diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..5e17dfa98 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 + +[Makefile] +indent_style = tab +indent_size = 4 diff --git a/.gitignore b/.gitignore index be86e88da..5188a2e6a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,25 @@ -/build/* -!/build/codegen/ - -/doc/* -!/doc/Theme.css - /node_modules/ /vendor/libgit2/ +/vendor/libssh2/ +/vendor/http_parser/ +/build/ +/test/coverage/ /test/repos/ +/test/test/repos/ +/src/ +/include/ +/lib/enums.js + + +/vendor/Release +/vendor/*.vcxproj +/vendor/*.filters +/vendor/*.sln + +/generate/idefs.json +/generate/missing-tests.json +/binding.gyp + + +*.log +.DS_STORE diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 000000000..ea2e2b7b1 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,26 @@ +{ + "evil": true, + "boss": true, + "immed": false, + "eqnull": true, + "maxlen": 80, + "node": true, + "proto": true, + "curly": true, + "quotmark": "double", + "trailing": true, + "unused": "vars", + "undef": true, + "validthis": true, + "globals": { + "global": true, + "define": true, + "it": true, + "describe": true, + "before": true, + "beforeEach": true, + "after": true, + "afterEach": true + }, + "predef": ["-Promise"] +} diff --git a/.travis.yml b/.travis.yml index 8be0a1110..8a78fce67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,37 @@ -language: node_js -node_js: - - "0.10" - - 0.11 +env: + matrix: + - export NODE_VERSION="0.10" + - export NODE_VERSION="0.11" +before_install: + - git clone https://github.com/creationix/nvm.git ./.nvm + - source ./.nvm/nvm.sh + - nvm install $NODE_VERSION + - nvm use $NODE_VERSION + - if [ $TRAVIS_OS_NAME == "linux" ]; then + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; + sudo apt-get -qq update; + sudo apt-get -qq install g++-4.8; + export CXX='g++-4.8'; + fi + - "export JOBS=4" + - BUILD_ONLY=true npm install +# This is a random private key used purely for testing. +before_script: + - echo -e "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + - echo -e "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDkTcgXnHuqR0gbwegnr9Zxz4hTkjjV/SpgJNPJz7mo/HKNbx0rqjj1P0yGR053R9GSFFim2ut4NK9DPPUkQdyucw+DoLkYRHJmlJ4BNa9NTCD0sl+eSXO2969kZojCYSOgbmkCJx8mdgTwhzdgE/jhBrsY0hPE6pRTlU+H68/zeNdJUAIJf0LLXOm3hpTKLA19VICltl/j9VvBJpgRHdBylXEyL8HokYpjkQQk1ZXj3m7Nlo8yDdg4VcljOJWC+Xh8kxRMfK5x/VRVsYKCQXN5QlzKeqf7USRDUS/7mFoPUBW+d4kwKtGxRsWuIL2yeqzifZUTOgsh9+ZWAWxWffQZ your_email@example.com" > ~/.ssh/id_rsa.pub + - echo -e "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA5E3IF5x7qkdIG8HoJ6/Wcc+IU5I41f0qYCTTyc+5qPxyjW8d\nK6o49T9MhkdOd0fRkhRYptrreDSvQzz1JEHcrnMPg6C5GERyZpSeATWvTUwg9LJf\nnklztvevZGaIwmEjoG5pAicfJnYE8Ic3YBP44Qa7GNITxOqUU5VPh+vP83jXSVAC\nCX9Cy1zpt4aUyiwNfVSApbZf4/VbwSaYER3QcpVxMi/B6JGKY5EEJNWV495uzZaP\nMg3YOFXJYziVgvl4fJMUTHyucf1UVbGCgkFzeUJcynqn+1EkQ1Ev+5haD1AVvneJ\nMCrRsUbFriC9snqs4n2VEzoLIffmVgFsVn30GQIDAQABAoIBAQDPQm2sQbti0mN8\nD4Uawl8D40v30n8WhUa7EbPTOmlqKAQ2sfDhex9KRbTLEmEBmImA/Eee8o9iCTIy\n8Fv8Fm6pUHt9G6Pti/XvemwW3Q3QNpSUkHqN0FDkgecQVqVBEb6uHo3mDm4RFINX\neOmkp30BjIK9/blEw1D0sFALLOEUPaDdPMwiXtFgqfrFSgpDET3TvQIwZ2LxxTm0\ncNmP3sCSlZHJNkZI4hBEWaaXR+V5/+C1qblDCo5blAWTcX3UzqrwUUJgFi6VnBuh\n7S9Q6+CEIU+4JRyWQNmY8YgZFaAp6IOr/kyfPxTP1+UEVVgcLn3WDYwfG9og0tmz\nfzlruAgBAoGBAPfz73Pey86tNZEanhJhbX8gVjzy2hvyhT0paHg0q/H6c1VWOtUH\nOwZ3Ns2xAZqJhlDqCHnQYSCZDly042U/theP4N8zo1APb4Yg4qdmXF9QE1+2M03r\nkS6138gU/CSCLf8pCYa6pA/GmsaXxloeJGLvT4fzOZRsVav80/92XHRhAoGBAOu2\nmKh4Gr1EjgN9QNbk9cQTSFDtlBEqO/0pTepvL73UvNp/BAn4iYZFU4WnklFVBSWc\nL84Sc732xU12TAbTTUsa6E7W29pS8u7zVTxlIdQIIU5pzDyU1pNNk2kpxzte5p3Y\nPDtniPFsoYLWoH0LpsKL93t2pLAj+IOkE6f3XBq5AoGAIKaYo5N1FxQr952frx/x\nQUpK0N/R5Ng8v18SiLG26rhmM5iVSrQXC7TrHI7wfR8a9tC6qP/NqnM9NuwC/bQ0\nEEo7/GhaWxKNRwZRkmWiSFLNGk9t1hbtGU+N1lUdFtmloPIQdRNiw0kN3JTj474Q\nYI7O1EItFORnK6yxZfR6HEECgYEA1CT7MGUoa8APsMRCXyaiq15Pb8bjxK8mXquW\nHLEFXuzhLCW1FORDoj0y9s/iuKC0iS0ROX8R/J7k5NrbgikbH8WP36UxKkYNr1IC\nHOFImPTYRSKjVsL+fIUNb1DSp3S6SsYbL7v3XJJQqtlQiDq8U8x1aQFXJ9C4EoLR\nzhKrKsECgYBtU/TSF/TATZY5XtrN9O+HX1Fbz70Ci8XgvioheVI2fezOcXPRzDcC\nOYPaCMNKA5E8gHdg4s0TN7uDvKTJ+KhSg2V7gZ39A28dHrJaRX7Nz4k6t2uEBjX9\na1JidpAIbJ+3w7+hj6L299tVZvS+Y/6Dz/uuEQGXfJg/l/5CCvQPsA==\n-----END RSA PRIVATE KEY-----" > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa* + - eval `ssh-agent -s` + - ssh-add ~/.ssh/id_rsa git: depth: 1 branches: only: - master -matrix: - fast_finish: true - allow_failures: - - node_js: 0.11 +os: + - linux + - osx +script: npm test +notifications: + slack: + secure: KglNSqZiid9YudCwkPFDh+sZfW5BwFlM70y67E4peHwwlbbV1sSBPHcs74ZHP/lqgEZ4hMv4N2NI58oYFD5/1a+tKIQP1TkdIMuq4j2LXheuirA2HDcydOVrsC8kRx5XFGKdVRg/uyX2dlRHcOWFhxrS6yc6IxtxYWlRTD2SmEc= diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..b8f6b7ce1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,81 @@ +Test Contribution Guidelines +---------------------------- + +This is a guide on how to contribute test cases to help with coverage testing for NodeGit. + +## Getting Started ## + +Currently there are a number of fields and functions in NodeGit that have no tests at all. A list of which files are missing and what fields and functions need tests can be generated by running + +``` bash +npm run missing-tests +``` + +This will make the file `generate/missing-tests.json` which will contain info for tests or files that are currently missing. + +From this file you can find fields and functions that don't have any tests yet and pick one to work on. + +## Adding a test ## + +After you find a test that's missing the next step is to find or add the file that you need to add it into. You can always use other tests in the directory as a guide for writing more. All new files will be automatically added during a test run. + +In the `missing-tests.json` file you'll see it formatted like so: + +```json +{ + "{className}":{ + "fields": [], + "functions": [] + } +} +``` + +In the file each `{className}` corresponds to a file found at `test/tests/{classname}`. Each entry in either `fields` or `functions` is a missing test for the respective field/function. + +In the file that your test is going in you can just append it to the file inside of the `describe` function block. + +It can be helpful to reference the [libgit2 API docs](https://libgit2.github.com/libgit2/#v0.21.2) to know what the field or function is doing inside of libgit2 and referencing the [NodeGit API docs](http://www.nodegit.org/) can also help. Looking at examples inside of `/example` can show you how we wrap the libgit2 library and how you can call into it from JavaScript. + +The idea is to test the basic functionality of the field/function and to confirm that it's returning or setting the value(s) correctly. Bugs inside of libgit2 will have to either have a work-around or be ignored. + +If a specific field or function is further wrapped via a file inside of `/lib` then as long as that wrapper is called and tested. + +You can mark something to be ignored inside of the `/generate/missing-tests-ignore.json` file. + +After you write your test make sure to run `npm run missing-tests` again to confirm that the field/function that a test was written for no longer shows up. + +## Test results ## + +### The test passes ### + +Excellent!! Make sure that the test is working correctly and testing what you're expecting it to test and then move onto the [next section](https://github.com/nodegit/nodegit/tree/master/test#making-a-pull-request). + +### The test fails ### + +This is also great! You just found something that wasn't properly covered in our generate scripts for wrapping libgit2. We'll have to further analyze what's going on and figure out how to fix it. + +For bonus points you could also include a fix in your pull request but that step is optional. + +## Making a pull request ## + +So you made your self a new test for NodeGit and now you want to add it to the main repo? That's great! We'll try and make the process as simple and easy as possible for you. + +So assuming that you have a fork of the repo make a new branch that's labeled `new-tests-{className}` where {className} is the name of the file you added the tests to. Also, make sure you check the [main repo's pull request list](https://github.com/nodegit/nodegit/pulls) and see if somebody else is editing that file before you make your PR. They might have added a test already that's waiting to get merged in. + +So after you have your branch and your change is ready to go make sure your subjects for your commits contain the {className} of the tests you added and then list each new field/function being tested inside of the subject of the commit message. + +Example: + +``` +Added tests for oid + +fromString +allocfmt +inspect +``` + +This will help us know what each commit contains at a glance and should expedite merging your pull request. + +If your test is failing, TravisCI should pick it up and note it on the PR. PR's that add failing tests will have to be handled on a case-by-case basis but please don't let that stop you from staring a PR. + +Please don't start a PR until you're finished (no WIP test PRs please!). diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 000000000..20061a36e --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,9 @@ +0.2.0 / 2014-11-24 +=================== + + * Shifted to promises; asynchronous methods now provide promises. + * Lots of new methods exposed for merging, pushing, blaming and more. + * SSH transport now works. + * Switched generation of native module code from ejsg to Combyne. + * Added continuous integration with Linux, OSX, and Windows. + * Many method and property names have changed. diff --git a/README.md b/README.md index c2e03d931..8cec4a48b 100644 --- a/README.md +++ b/README.md @@ -4,19 +4,16 @@ NodeGit > Node bindings to the [libgit2](http://libgit2.github.com/) project. [![Build -Status](https://travis-ci.org/tbranyen/nodegit.png)](https://travis-ci.org/nodegit/nodegit) +Status](https://travis-ci.org/nodegit/nodegit.png)](https://travis-ci.org/nodegit/nodegit) Build Status: Windows -**Stable: 0.1.4** +**Stable: 0.2.0** -Maintained by Tim Branyen [@tbranyen](http://twitter.com/tbranyen), Michael -Robinson [@codeofinterest](http://twitter.com/codeofinterest), and Nick Kallen -[@nk](http://twitter.com/nk), with help from [awesome -contributors](https://github.com/tbranyen/nodegit/contributors)! +Maintained by Tim Branyen [@tbranyen](http://twitter.com/tbranyen), Michael Robinson [@codeofinterest](http://twitter.com/codeofinterest), John Haley [@johnhaley81](http://twitter.com/johnhaley81), Max Korp [@maxkorp](http://twitter.com/MaximilianoKorp), and Nick Kallen [@nk](http://twitter.com/nk) with help from [awesome contributors](https://github.com/nodegit/nodegit/contributors)! ## API Documentation. ## -http://www.nodegit.org/nodegit/ +http://www.nodegit.org/ ## Getting started. ## @@ -27,8 +24,7 @@ dependencies. npm install nodegit ``` -If you encounter problems while installing, you should try the Building from -source instructions below. +If you encounter problems while installing, you should try the Building from source instructions below. ## Building from source. ## @@ -40,17 +36,16 @@ If you wish to help contribute to nodegit it is useful to build locally. ``` bash # Fetch this project. -git clone git://github.com/tbranyen/nodegit.git +git clone git://github.com/nodegit/nodegit.git # Enter the repository. cd nodegit -# Install the template engine, run the code generation script, and install. -npm install ejs && npm run codegen && npm install +# Installs the template engine, run the code generation script, and build. +npm install ``` -If you encounter errors, you most likely have not configured the dependencies -correctly. +If you encounter errors, you most likely have not configured the dependencies correctly. ### Installing dependencies: ### @@ -77,11 +72,9 @@ sudo pacman -S base-devel - [Download and install Python](https://www.python.org/download/windows). - [Download and install VS Express](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop). -You may have to add a build flag to the installation process to successfully -install. Try first without, if the build fails, try again with the flag. +You may have to add a build flag to the installation process to successfully install. Try first without, if the build fails, try again with the flag. -*Allegedly the order in which you install Visual Studio could trigger this -error.* +*Allegedly the order in which you install Visual Studio could trigger this error.* ``` bash npm install nodegit --msvs_version=2013 @@ -93,68 +86,57 @@ npm install nodegit --msvs_version=2013 ### Cloning a repository and reading a file: ### ``` javascript -var clone = require("nodegit").Repo.clone; +var clone = require("./").Clone.clone; // Clone a given repository into a specific folder. -clone("https://github.com/nodegit/nodegit", "tmp", null, function(err, repo) { - if (err) { - throw err; - } - - // Use a known commit sha from this repository. - var sha = "59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5"; - +clone("https://github.com/nodegit/nodegit", "tmp", null) // Look up this known commit. - repo.getCommit(sha, function(err, commit) { - if (err) { - throw err; - } - - // Look up a specific file within that commit. - commit.getEntry("README.md", function(err, entry) { - if (err) { - throw err; - } - - // Get the blob contents from the file. - entry.getBlob(function(err, blob) { - if (err) { - throw err; - } + .then(function(repo) { + // Use a known commit sha from this repository. + return repo.getCommit("59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5"); + }) + // Look up a specific file within that commit. + .then(function(commit) { + return commit.getEntry("README.md"); + }) + // Get the blob contents from the file. + .then(function(entry) { + // Patch the blob to contain a reference to the entry. + return entry.getBlob().then(function(blob) { + blob.entry = entry; + return blob; + }); + }) + // Display information about the blob. + .then(function(blob) { + // Show the name, sha, and filesize in byes. + console.log(blob.entry.name() + blob.entry.sha() + blob.size() + "b"); - // Show the name, sha, and filesize in byes. - console.log(entry.name() + entry.sha() + blob.size() + "b"); + // Show a spacer. + console.log(Array(72).join("=") + "\n\n"); - // Show a spacer. - console.log(Array(72).join("=") + "\n\n"); + // Show the entire file. + console.log(String(blob)); + }) + .catch(function(err) { console.log(err); }); - // Show the entire file. - console.log(String(blob)); - }); - }); - }); -}); ``` ### Emulating git log: ### ``` javascript -var open = require("nodegit").Repo.open; +var open = require("nodegit").Repository.open; // Open the repository directory. -open("tmp", function(err, repo) { - if (err) { - throw err; - } - +open("tmp") // Open the master branch. - repo.getMaster(function(err, branch) { - if (err) { - throw err; - } - + .then(function(repo) { + return repo.getMasterCommit(); + }) + // Display information about commits on master. + .then(function(firstCommitOnMaster) { // Create a new history event emitter. - var history = branch.history(); + var history = firstCommitOnMaster.history(); // Create a counter to only show up to 9 entries. var count = 0; @@ -185,7 +167,6 @@ open("tmp", function(err, repo) { // Start emitting events. history.start(); }); -}); ``` ## Unit tests. ## @@ -195,3 +176,12 @@ You will need to build locally before running the tests. See above. ``` bash npm test ``` + +## Migrating from old versions. ## + +The bump from 0.1.4 to 0.2.0 was a big one. Many things changed, see here: +https://github.com/nodegit/nodegit/compare/refs/tags/0.1.4...0.2.0 + +This update is wholly and entirely a breaking one, and older versions won't be +maintained. For the purpose of migration, perhaps the biggest point to make +is that async methods can now use promises, rather than just taking callbacks. Additionally, lots of method and property names have changed. diff --git a/appveyor.yml b/appveyor.yml index 8c99db391..47e35efe3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,9 +2,15 @@ # http://www.appveyor.com/docs/appveyor-yml project_id: "e5a5q75l9yfhnfv2" +# Try out "interactive-mode" +os: unstable + # build version format version: "{build}" +# Set a known clone folder +clone_folder: c:\projects\nodegit + # fix lineendings in Windows init: - git config --global core.autocrlf input @@ -15,15 +21,15 @@ environment: - nodejs_version: 0.11 - nodejs_version: 0.10 -matrix: - allow_failures: - - nodejs_version: 0.11 - # Get the latest stable version of Node 0.STABLE.latest install: - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) - cmd: SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH% - cmd: SET PATH=c:\python27;%PATH% + - cmd: SET JOBS=4 + - cmd: SET BUILD_ONLY=true + - cmd: SET GIT_SSH=c:\projects\nodegit\vendor\plink.exe + - ps: Start-Process c:\projects\nodegit\vendor\pageant.exe c:\projects\nodegit\vendor\private.ppk - cmd: npm install -g node-gyp - npm install --msvs_version=2013 diff --git a/binding.gyp b/binding.gyp deleted file mode 100644 index 104b7a9d3..000000000 --- a/binding.gyp +++ /dev/null @@ -1,423 +0,0 @@ -{ - "targets": [ - { - "target_name": "nodegit", - - "dependencies": [ - "libgit2" - ], - - "sources": [ - "src/base.cc", - "src/blob.cc", - "src/commit.cc", - "src/oid.cc", - "src/reference.cc", - "src/object.cc", - "src/repo.cc", - "src/index.cc", - "src/index_entry.cc", - "src/index_time.cc", - "src/tag.cc", - "src/revwalk.cc", - "src/signature.cc", - "src/time.cc", - "src/tree.cc", - "src/tree_builder.cc", - "src/tree_entry.cc", - "src/diff_find_options.cc", - "src/diff_options.cc", - "src/diff_list.cc", - "src/patch.cc", - "src/delta.cc", - "src/diff_file.cc", - "src/diff_range.cc", - "src/threads.cc", - "src/wrapper.cc", - "src/refdb.cc", - "src/odb_object.cc", - "src/odb.cc", - "src/submodule.cc", - "src/remote.cc", - "src/clone_options.cc", - "src/functions/copy.cc", - ], - - "include_dirs": [ - "vendor/libv8-convert", - "vendor/libgit2/include", - " - */ -NAN_METHOD(<%- cppClassName %>::<%- functionInfo.cppFunctionName %>) { - NanScope(); - <% var jsArg; -%> - <% include guardArguments.cc.ejs -%> - - if (args.Length() == <%- jsArg %> || !args[<%- jsArg %>]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - <%- functionInfo.cppFunctionName %>Baton* baton = new <%- functionInfo.cppFunctionName %>Baton; - baton->error_code = GIT_OK; - baton->error = NULL; -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; --%> -<% if (!arg.isReturn) { -%> -<% if (arg.isSelf) { -%> - baton-><%- arg.name %> = ObjectWrap::Unwrap<<%- cppClassName %>>(args.This())->GetValue(); -<% } else { -%> - <% include convertFromV8.cc.ejs -%> - <% if (!arg.isPayload) { -%> - baton-><%- arg.name %> = from_<%- arg.name %>; - <% } -%> -<% } -%> -<% if (!(arg.isReturn || arg.isSelf || arg.isPayload)) jsArg++; -%> -<% } else { -%> -<% if (arg.shouldAlloc) { -%> - baton-><%- arg.name %> = (<%- arg.cType %>)malloc(sizeof(<%- arg.cType.replace('*', '') %>)); -<% } -%> -<% } -%> -<% } -%> - - NanCallback *callback = new NanCallback(Local::Cast(args[<%- jsArg %>])); - <%- functionInfo.cppFunctionName %>Worker *worker = new <%- functionInfo.cppFunctionName %>Worker(baton, callback); -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; --%> -<% if (!arg.isReturn) { -%> -<% if (arg.isSelf) { -%> - worker->SaveToPersistent("<%- arg.name %>", args.This()); -<% } else { -%> - if (!args[<%- jsArg %>]->IsUndefined() && !args[<%- jsArg %>]->IsNull()) - worker->SaveToPersistent("<%- arg.name %>", args[<%- jsArg %>]->ToObject()); -<% } -%> -<% if (!(arg.isReturn || arg.isSelf || arg.isPayload)) jsArg++; -%> -<% } -%> -<% } -%> - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void <%- cppClassName %>::<%- functionInfo.cppFunctionName %>Worker::Execute() { - <% if (functionInfo.return.cType != "void" || functionInfo.return.isErrorCode) { %><%- functionInfo.return.cType %> result = <% } %><%- functionInfo.cFunctionName %>( -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> - <% if (arg.isReturn && /\*\*/.test(arg.cType)) { %>&<% } %>baton-><%- arg.name %><% if (i < functionInfo.args.length - 1) { %>, <% } %> -<% } -%> - ); -<% if (functionInfo.return.isErrorCode) { -%> - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -<% } else if (functionInfo.return.cType != "void") { -%> - baton->result = result; -<% } -%> -} - -void <%- cppClassName %>::<%- functionInfo.cppFunctionName %>Worker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { -<% if (!returns.length) { -%> - Handle result = NanUndefined(); -<% } else if (returns.length == 1) { -%> -<% var to = {}; to.__proto__ = returns[0]; to.name = "baton->" + to.name; -%> - Handle to; - <% include convertToV8.cc.ejs -%> - Handle result = to; -<% } else { -%> - Handle result = NanNew(); - Handle to; -<% - for (r in returns) { - var to = returns[r]; --%> - <% include convertToV8.cc.ejs -%> - result->Set(NanNew("<%- to.jsName || to.name %>"), to); -<% } -%> -<% } -%> - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - <% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (!arg.shouldAlloc) continue; - -%> - free(baton-><%= arg.name %>); - <% } -%> - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> -<% if (['String', 'Array'].indexOf(arg.cppClassName) > -1) { -%> -<% if (arg.freeFunctionName) { %> - <%- arg.freeFunctionName %>(baton-><%- arg.name %>); -<% } else { -%> - free((void *)baton-><%- arg.name %>); -<% } -%> -<% } -%> -<% } -%> - delete baton; -} diff --git a/build/codegen/templates/class.cc.ejs b/build/codegen/templates/class.cc.ejs deleted file mode 100644 index 5bae84441..000000000 --- a/build/codegen/templates/class.cc.ejs +++ /dev/null @@ -1,160 +0,0 @@ -<% - function isV8Value(cppClassName) { - return ["Boolean", "Number", "String", "Integer", "Int32", "Uint32", "Date", "Function"].indexOf(cppClassName) > -1; - } - - function cppClassName2v8ValueClassName(cppClassName) { - if (isV8Value(cppClassName)) - return cppClassName; - else - return 'Object'; - } - - function isPointer(cType) { - return /\s*\*\s*$/.test(cType); - } - - function unPointer(cType) { - return cType.replace(/\s*\*\s*$/,''); - } - - function defaultValue(cType) { - if (cType === 'git_otype') { return 'GIT_OBJ_ANY'; } - else { return '0'; } - } --%> -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/<%= filename %>" -<% if (typeof dependencies != 'undefined') { -%> -<% for (d in dependencies) { -%> -#include "<%- dependencies[d] %>" -<% } -%> -<% } -%> - -using namespace v8; -using namespace node; - -<% if (typeof cType != 'undefined') { -%> -<%- cppClassName %>::<%- cppClassName %>(<%- cType %> *raw) { - this->raw = raw; -} - -<%- cppClassName %>::~<%- cppClassName %>() { -<% if (typeof freeFunctionName != 'undefined') { -%> - <%- freeFunctionName %>(this->raw); -<% } -%> -} - -void <%- cppClassName %>::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("<%- jsClassName %>")); - -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; --%> -<% if (functionInfo.isPrototypeMethod) { -%> - NODE_SET_PROTOTYPE_METHOD(tpl, "<%- functionInfo.jsFunctionName %>", <%- functionInfo.cppFunctionName %>); -<% } else { -%> - NODE_SET_METHOD(tpl, "<%- functionInfo.jsFunctionName %>", <%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% } -%> - -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore) continue; --%> - NODE_SET_PROTOTYPE_METHOD(tpl, "<%- fieldInfo.jsFunctionName %>", <%- fieldInfo.cppFunctionName %>); -<% } -%> -<% } -%> - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("<%- jsClassName %>"), _constructor_template); -} - -NAN_METHOD(<%- cppClassName %>::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("<%= cType %> is required."); - } - <%- cppClassName %>* object = new <%- cppClassName %>(static_cast<<%= cType%> *>(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle <%- cppClassName %>::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(<%- cppClassName %>::constructor_template)->NewInstance(1, argv)); -} - -<%- cType %> *<%- cppClassName %>::GetValue() { - return this->raw; -} -<% } else { -%> -void <%- cppClassName %>::Initialize(Handle target) { - NanScope(); - - Local object = NanNew(); - -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; --%> - NODE_SET_METHOD(object, "<%- functionInfo.jsFunctionName %>", <%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> - - target->Set(NanNew("<%- jsClassName %>"), object); -} -<% } -%> - -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; - - var returns = []; - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isReturn) returns.push(arg); - } - if (!returns.length && !functionInfo.return.isErrorCode && functionInfo.return.cType != "void") returns.push(functionInfo.return); --%> - -<% if (functionInfo.isAsync) { -%> -<% include build/codegen/templates/asyncFunction.cc.ejs -%> -<% } else { -%> -<% include build/codegen/templates/syncFunction.cc.ejs -%> -<% } -%> -<% } -%> -<% } -%> -<% include build/codegen/templates/fields.cc.ejs -%> - -<% if (typeof cType != 'undefined') { -%> -Persistent <%- cppClassName %>::constructor_template; -<% } -%> diff --git a/build/codegen/templates/convertFromV8.cc.ejs b/build/codegen/templates/convertFromV8.cc.ejs deleted file mode 100644 index acc5d5044..000000000 --- a/build/codegen/templates/convertFromV8.cc.ejs +++ /dev/null @@ -1,31 +0,0 @@ -<% if (!arg.isPayload) { -%> - <%- arg.cType %> from_<%- arg.name %>; - <% if (arg.isOptional) { -%> - if (args[<%- jsArg %>]->Is<%- cppClassName2v8ValueClassName(arg.cppClassName) %>()) { - <% } -%> - <% if (arg.cppClassName == 'String') { -%> - String::Utf8Value <%- arg.name %>(args[<%- jsArg %>]->ToString()); - from_<%- arg.name %> = strdup(*<%- arg.name %>); - <% } else if (arg.cppClassName == 'Array') { -%> - Array *tmp_<%- arg.name %> = Array::Cast(*args[<%- jsArg %>]); - from_<%- arg.name %> = (<%- arg.cType %>)malloc(tmp_<%- arg.name %>->Length() * sizeof(<%- arg.cType.replace('**', '*') %>)); - for (unsigned int i = 0; i < tmp_<%- arg.name %>->Length(); i++) { - <% - // FIXME: should recursively call convertFromv8. - %> - from_<%- arg.name %>[i] = ObjectWrap::Unwrap<<%- arg.arrayElementCppClassName %>>(tmp_<%- arg.name %>->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); - } - <% } else if (arg.cppClassName == "Function") { -%> - <% } else if (arg.cppClassName == 'Buffer') { -%> - from_<%- arg.name %> = Buffer::Data(args[<%- jsArg %>]->ToObject()); - <% } else if (isV8Value(arg.cppClassName)) { -%> - from_<%- arg.name %> = (<%- arg.cType %>) <%- arg.additionalCast %> <%- arg.cast %> args[<%- jsArg %>]->To<%- arg.cppClassName %>()->Value(); - <% } else { -%> - from_<%- arg.name %> = ObjectWrap::Unwrap<<%- arg.cppClassName %>>(args[<%- jsArg %>]->ToObject())->GetValue(); - <% } -%> - <% if (arg.isOptional) { -%> - } else { - from_<%- arg.name %> = 0; - } - <% } -%> -<% } -%> diff --git a/build/codegen/templates/convertToV8.cc.ejs b/build/codegen/templates/convertToV8.cc.ejs deleted file mode 100644 index aefae8386..000000000 --- a/build/codegen/templates/convertToV8.cc.ejs +++ /dev/null @@ -1,40 +0,0 @@ -<% toName = to.name || 'result' -%> -<% if (to.cppClassName == "String") { -%> -<% if (typeof to.size != 'undefined') { -%> - to = NanNew(<%- toName %>, <%- to.size %>); -<% } else { -%> - to = NanNew(<%- toName %>); -<% } -%> -<% if (to.freeFunctionName) { -%> - <%- to.freeFunctionName %>(<%- toName %>); -<% } -%> -<% } else if (isV8Value(to.cppClassName)) { -%> -<% if (~['Uint32', 'Int32'].indexOf(to.cppClassName)) { -%> -<% var className = to.cppClassName.toLowerCase()+'_t' -%> - to = NanNew<<%- to.cppClassName %>>((<%- className %>)<%- toName %>); -<% } else { -%> - to = NanNew<<%- to.cppClassName %>>(<%- toName %>); -<% } -%> -<% } else if (to.cppClassName == "External") { -%> - to = NanNew((void *)<%- toName %>); -<% } else if (to.cppClassName == 'Array') { -%> -<% - // FIXME this is not general purpose enough. -%> - Local tmpArray = NanNew(<%- toName %>-><%- to.size %>); - for (unsigned int i = 0; i < <%- toName %>-><%- to.size %>; i++) { - tmpArray->Set(NanNew(i), NanNew(<%- toName %>-><%- to.key %>[i])); - } - to = tmpArray; -<% } else { -%> -<% if (to.copy) { -%> - if (<%- toName %> != NULL) { - <%- toName %> = (<%- to.cType.replace('**', '*') %> <% if (!/\*/.test(to.cType)) {%>*<% } %>)<%- to.copy %>(<%- toName %>); - } -<% } -%> - if (<%- toName %> != NULL) { - to = <%- to.cppClassName %>::New((void *)<%- toName %>); - } else { - to = NanNull(); - } -<% } -%> diff --git a/build/codegen/templates/doc.cc.ejs b/build/codegen/templates/doc.cc.ejs deleted file mode 100644 index 44ca0979a..000000000 --- a/build/codegen/templates/doc.cc.ejs +++ /dev/null @@ -1,14 +0,0 @@ -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isReturn || arg.isSelf) continue; --%> - * @param {<%- arg.jsClassName %>} <%- arg.name %> -<% } -%> -<% for (var r = 0; r < returns.length; r++) { -%> -<% if (functionInfo.isAsync) { -%> - * @param {<%- returns[r].jsClassName || returns[r].cppClassName %>} callback -<% } else { -%> - * @return {<%- returns[r].jsClassName || returns[r].cppClassName %>} <%- returns[r].name || 'result' %> -<% } -%> -<% } -%> diff --git a/build/codegen/templates/fields.cc.ejs b/build/codegen/templates/fields.cc.ejs deleted file mode 100644 index f7f684a99..000000000 --- a/build/codegen/templates/fields.cc.ejs +++ /dev/null @@ -1,20 +0,0 @@ -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore) continue; --%> - -NAN_METHOD(<%- cppClassName %>::<%- fieldInfo.cppFunctionName %>) { - NanScope(); - <% var to = fieldInfo; -%> - Handle to; - - <%- fieldInfo.cType %> <% if (!isV8Value(fieldInfo.cppClassName)) { %>*<% } %><%- fieldInfo.name %> = - <% if (!isV8Value(fieldInfo.cppClassName)) { %>&<% } %>ObjectWrap::Unwrap<<%- cppClassName %>>(args.This())->GetValue()-><%- fieldInfo.name %>; - - <% include convertToV8.cc.ejs -%> - NanReturnValue(to); -} -<% } -%> -<% } -%> diff --git a/build/codegen/templates/guardArguments.cc.ejs b/build/codegen/templates/guardArguments.cc.ejs deleted file mode 100644 index 99a99fb0f..000000000 --- a/build/codegen/templates/guardArguments.cc.ejs +++ /dev/null @@ -1,13 +0,0 @@ -<% - var cArg = 0; - for (cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; - if (arg.isReturn || arg.isSelf || arg.isPayload) continue; --%> -<% if (!arg.isOptional) { -%> - if (args.Length() == <%- jsArg %> || !args[<%- jsArg %>]->Is<%- cppClassName2v8ValueClassName(arg.cppClassName) %>()) { - return NanThrowError("<%- arg.jsClassName %> <%- arg.name %> is required."); - } -<% } -%> -<% jsArg++; -%> -<% } -%> diff --git a/build/codegen/templates/header.h.ejs b/build/codegen/templates/header.h.ejs deleted file mode 100644 index 1d7e373cb..000000000 --- a/build/codegen/templates/header.h.ejs +++ /dev/null @@ -1,90 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef <%- cppClassName.toUpperCase() %>_H -#define <%- cppClassName.toUpperCase() %>_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class <%- cppClassName %> : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - -<% if (typeof cType != 'undefined') { -%> - <%- cType %> *GetValue(); - - static Handle New(void *raw); -<% } -%> - - private: -<% if (typeof cType != 'undefined') { -%> - <%- cppClassName %>(<%- cType %> *raw); - ~<%- cppClassName %>(); -<% } -%> - - static NAN_METHOD(New); - -<% if (typeof fields != 'undefined') { -%> -<% - for (var i in fields) { - var fieldInfo = fields[i]; - if (fieldInfo.ignore) continue; --%> - static NAN_METHOD(<%- fieldInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% if (typeof functions != 'undefined') { -%> -<% - for (var i in functions) { - var functionInfo = functions[i]; - if (functionInfo.ignore) continue; --%> -<% if (functionInfo.isAsync) { -%> - - struct <%- functionInfo.cppFunctionName %>Baton { - int error_code; - const git_error* error; -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; --%> -<% if (arg.isReturn) { -%> - <%- arg.cType.replace('**', '*') %> <%- arg.name %>; -<% } else { -%> - <%- arg.cType %> <%- arg.name %>; -<% } -%> -<% } -%> - }; - class <%- functionInfo.cppFunctionName %>Worker : public NanAsyncWorker { - public: - <%- functionInfo.cppFunctionName %>Worker( - <%- functionInfo.cppFunctionName %>Baton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~<%- functionInfo.cppFunctionName %>Worker() {}; - void Execute(); - void HandleOKCallback(); - - private: - <%- functionInfo.cppFunctionName %>Baton *baton; - }; -<% } -%> - static NAN_METHOD(<%- functionInfo.cppFunctionName %>); -<% } -%> -<% } -%> -<% if (typeof cType != 'undefined') { -%> - <%- cType %> *raw; -<% } -%> -}; - -#endif diff --git a/build/codegen/templates/syncFunction.cc.ejs b/build/codegen/templates/syncFunction.cc.ejs deleted file mode 100644 index ad5349a35..000000000 --- a/build/codegen/templates/syncFunction.cc.ejs +++ /dev/null @@ -1,95 +0,0 @@ -/** -<% include doc.cc.ejs -%> - */ -NAN_METHOD(<%- cppClassName %>::<%- functionInfo.cppFunctionName %>) { - NanScope(); - <% include guardArguments.cc.ejs -%> - -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (!arg.isReturn) continue; --%> -<% if (arg.shouldAlloc) { -%> - <%- arg.cType %><%- arg.name %> = (<%- arg.cType %>)malloc(sizeof(<%- unPointer(arg.cType) %>)); -<% } else { -%> - <%- unPointer(arg.cType) %> <%- arg.name %> = <%- defaultValue(unPointer(arg.cType)) %>; -<% } -%> -<% } -%> -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; - if (arg.isSelf || arg.isReturn || arg.isPayload) continue; --%> -<% include convertFromV8.cc.ejs -%> -<% jsArg++; -%> -<% } %> - <% if (returns.length || functionInfo.return.isErrorCode) { %><%- functionInfo.return.cType %> result = <% } %><%- functionInfo.cFunctionName %>( -<% - for (var cArg = 0, jsArg = 0; cArg < functionInfo.args.length; cArg++) { - var arg = functionInfo.args[cArg]; --%> - <% if (cArg > 0) { %>, <% } -%><% if (arg.isReturn && !arg.shouldAlloc) { %>&<% } -%> -<% if (arg.isSelf) { -%> -ObjectWrap::Unwrap<<%- cppClassName %>>(args.This())->GetValue() -<% } else if (arg.isReturn) { -%> -<%- arg.name %> -<% } else { -%> -from_<%- arg.name %> -<% } -%> -<% - if (!(arg.isReturn || arg.isSelf)) jsArg++; - } --%> - ); -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (arg.isSelf || arg.isReturn) continue; --%> -<% if (['String', 'Array'].indexOf(arg.cppClassName) > -1) { -%> -<% if (arg.freeFunctionName) { %> - <%- arg.freeFunctionName %>(from_<%- arg.name %>); -<% } else { -%> - free((void *)from_<%- arg.name %>); -<% } -%> -<% } -%> -<% } -%> -<% if (functionInfo.return.isErrorCode) { -%> - if (result != GIT_OK) { -<% - for (var i = 0; i < functionInfo.args.length; i++) { - var arg = functionInfo.args[i]; - if (!arg.shouldAlloc) continue; --%> - free(<%= arg.name %>); -<% } -%> - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } -<% } -%> - -<% if (!returns.length) { -%> - NanReturnUndefined(); -<% } else if (returns.length == 1) { -%> -<% var to = returns[0]; -%> - Handle to; - <% include convertToV8.cc.ejs -%> - NanReturnValue(to); -<% } else { -%> - Handle toReturn = NanNew(); - Handle to; -<% - for (r in returns) { - var to = returns[r]; --%> - <% include convertToV8.cc.ejs -%> - toReturn->Set(NanNew("<%- to.jsName || to.name %>"), to); - -<% } -%> - NanReturnValue(toReturn); -<% } -%> -} diff --git a/build/codegen/v0.18.0.json b/build/codegen/v0.18.0.json deleted file mode 100644 index 1671d2a81..000000000 --- a/build/codegen/v0.18.0.json +++ /dev/null @@ -1,17420 +0,0 @@ -[ - { - "filename": "attr.h", - "ignore": true, - "jsClassName": "Attr", - "cppClassName": "Attr", - "cType": "git_attr", - "functions": [ - { - "cFunctionName": "git_attr_get", - "args": [ - { - "name": "value_out", - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Output of the value of the attribute. Use the GIT_ATTR_... macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just use the string value for attributes set to a value. You should NOT modify or free this value." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository containing the path." - }, - { - "name": "flags", - "cType": "uint32_t", - "cppClassName": "Uint32", - "jsClassName": "Uint32", - "comment": "A combination of GIT_ATTR_CHECK... flags." - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The path to check for attributes. Relative paths are interpreted relative to the repo root. The file does not have to exist, but if it does not, then it will be treated as a plain file (not a directory)." - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The name of the attribute to look up." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "get", - "cppFunctionName": "Get", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Look up the value of one git attribute for path.

\n" - }, - { - "cFunctionName": "git_attr_get_many", - "args": [ - { - "name": "values_out", - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "comment": "An array of num_attr entries that will have string pointers written into it for the values of the attributes. You should not modify or free the values that are written into this array (although of course, you should free the array itself if you allocated it)." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository containing the path." - }, - { - "name": "flags", - "cType": "uint32_t", - "cppClassName": "Uint32", - "jsClassName": "Uint32", - "comment": "A combination of GIT_ATTR_CHECK... flags." - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The path inside the repo to check attributes. This does not have to exist, but if it does not, then it will be treated as a plain file (i.e. not a directory)." - }, - { - "name": "num_attr", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "The number of attributes being looked up" - }, - { - "name": "names", - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "comment": "An array of num_attr strings containing attribute names." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getMany", - "cppFunctionName": "GetMany", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Look up a list of git attributes for path.

\n" - }, - { - "cFunctionName": "git_attr_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository containing the path." - }, - { - "name": "flags", - "cType": "uint32_t", - "cppClassName": "Uint32", - "jsClassName": "Uint32", - "comment": "A combination of GIT_ATTR_CHECK... flags." - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Path inside the repo to check attributes. This does not have to exist, but if it does not, then it will be treated as a plain file (i.e. not a directory)." - }, - { - "name": "callback", - "cType": "git_attr_foreach_cb", - "cppClassName": "AttrForeachCb", - "jsClassName": "AttrForeachCb", - "comment": "Function to invoke on each attribute name and value. The value may be NULL is the attribute is explicitly set to UNSPECIFIED using the '!' sign. Callback will be invoked only once per attribute name, even if there are multiple rules for a given file. The highest priority rule will be used. Return a non-zero value from this to stop looping." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Passed on as extra parameter to callback function." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Loop over all the git attributes for a path.

\n" - }, - { - "cFunctionName": "git_attr_cache_flush", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "cacheFlush", - "cppFunctionName": "CacheFlush", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Flush the gitattributes cache.

\n" - }, - { - "cFunctionName": "git_attr_add_macro", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "name": "values", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "addMacro", - "cppFunctionName": "AddMacro", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Add a macro definition.

\n" - } - ] - }, - { - "filename": "blob.h", - "dependencies": [ - "../include/repo.h", - "../include/oid.h", - "../include/wrapper.h", - "node_buffer.h" - ], - "jsClassName": "Blob", - "cppClassName": "GitBlob", - "cType": "git_blob", - "freeFunctionName": "git_blob_free", - "functions": [ - { - "cFunctionName": "git_blob_free", - "args": [ - { - "name": "blob", - "cType": "git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "comment": "the blob to close" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open blob

\n" - }, - { - "cFunctionName": "git_blob_id", - "args": [ - { - "name": "blob", - "cType": "const git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "isSelf": true, - "comment": "a previously loaded blob." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "SHA1 hash for this blob.", - "jsClassName": "Oid" - }, - "description": "

Get the id of a blob.

\n" - }, - { - "cFunctionName": "git_blob_rawcontent", - "args": [ - { - "name": "blob", - "cType": "const git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "isSelf": true, - "comment": "pointer to the blob" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "content", - "cppFunctionName": "Content", - "return": { - "cType": "const void *", - "cppClassName": "Wrapper", - "comment": "the pointer; NULL if the blob has no contents" - }, - "description": "

Get a read-only buffer with the raw content of a blob.

\n" - }, - { - "cFunctionName": "git_blob_rawsize", - "args": [ - { - "name": "blob", - "cType": "const git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "isSelf": true, - "comment": "pointer to the blob" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "git_off_t", - "cppClassName": "Number", - "comment": "size on bytes", - "jsClassName": "Number" - }, - "description": "

Get the size in bytes of the contents of a blob

\n" - }, - { - "cFunctionName": "git_blob_is_binary", - "args": [ - { - "name": "blob", - "cType": "git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "isSelf": true, - "comment": "The blob which content should be analyzed" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "isBinary", - "cppFunctionName": "IsBinary", - "return": { - "cType": "int", - "cppClassName": "Boolean", - "comment": "1 if the content of the blob is detected as binary; 0 otherwise.", - "jsClassName": "Boolean" - }, - "description": "

Determine if the blob content is most certainly binary or not.

\n" - } - ] - }, - { - "filename": "branch.h", - "jsClassName": "Branch", - "cppClassName": "Branch", - "cType": "git_branch", - "freeFunctionName": "git_branch_free", - "functions": [ - { - "cFunctionName": "git_branch_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer where to store the underlying reference." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository" - }, - { - "name": "branch_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Name for the branch; this name is validated for consistency. It should also not conflict with an already existing branch name." - }, - { - "name": "target", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "comment": "Commit to which this branch should point. This object must belong to the given `repo`." - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing branch." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "create", - "cppFunctionName": "Create", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_EINVALIDSPEC or an error code. A proper reference is written in the refs/heads namespace pointing to the provided target commit.", - "jsClassName": "Number" - }, - "description": "

Create a new branch pointing at a target commit

\n" - }, - { - "cFunctionName": "git_branch_delete", - "args": [ - { - "name": "branch", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "A valid reference representing a branch" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "delete", - "cppFunctionName": "Delete", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, or an error code.", - "jsClassName": "Number" - }, - "description": "

Delete an existing branch reference.

\n" - }, - { - "cFunctionName": "git_branch_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to find the branches." - }, - { - "name": "list_flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Filtering flags for the branch listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE or a combination of the two." - }, - { - "name": "branch_cb", - "cType": "git_branch_foreach_cb", - "cppClassName": "BranchForeachCb", - "jsClassName": "BranchForeachCb", - "comment": "Callback to invoke per found branch." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Extra parameter to callback function." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Loop over all the branches and issue a callback for each one.

\n" - }, - { - "cFunctionName": "git_branch_move", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference" - }, - { - "name": "branch", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Current underlying reference of the branch." - }, - { - "name": "new_branch_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Target name of the branch once the move is performed; this name is validated for consistency." - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing branch." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "move", - "cppFunctionName": "Move", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EINVALIDSPEC or an error code.", - "jsClassName": "Number" - }, - "description": "

Move/rename an existing local branch reference.

\n" - }, - { - "cFunctionName": "git_branch_lookup", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "pointer to the looked-up branch reference" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository to look up the branch" - }, - { - "name": "branch_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Name of the branch to be looked-up; this name is validated for consistency." - }, - { - "name": "branch_type", - "cType": "git_branch_t", - "cppClassName": "BranchT", - "jsClassName": "BranchT", - "comment": "Type of the considered branch. This should be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "lookup", - "cppFunctionName": "Lookup", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; GIT_ENOTFOUND when no matching branch exists, GIT_EINVALIDSPEC, otherwise an error code.", - "jsClassName": "Number" - }, - "description": "

Lookup a branch by its name in a repository.

\n" - }, - { - "cFunctionName": "git_branch_name", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "comment": "where the pointer of branch name is stored; this is valid as long as the ref is not freed." - }, - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "the reference ideally pointing to a branch" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "name", - "cppFunctionName": "Name", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; otherwise an error code (e.g., if the ref is no local or remote branch).", - "jsClassName": "Number" - }, - "description": "

Return the name of the given local or remote branch.

\n" - }, - { - "cFunctionName": "git_branch_upstream", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer where to store the retrieved reference." - }, - { - "name": "branch", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Current underlying reference of the branch." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "upstream", - "cppFunctionName": "Upstream", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; GIT_ENOTFOUND when no remote tracking reference exists, otherwise an error code.", - "jsClassName": "Number" - }, - "description": "

Return the reference supporting the remote tracking branch,\ngiven a local branch reference.

\n" - }, - { - "cFunctionName": "git_branch_set_upstream", - "args": [ - { - "name": "branch", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "the branch to configure" - }, - { - "name": "upstream_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "remote-tracking or local branch to set as upstream. Pass NULL to unset." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "setUpstream", - "cppFunctionName": "SetUpstream", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Set the upstream configuration for a given local branch

\n" - }, - { - "cFunctionName": "git_branch_upstream_name", - "args": [ - { - "name": "tracking_branch_name_out", - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The user-allocated buffer which will be filled with the name of the reference. Pass NULL if you just want to get the needed size of the name of the reference as the output value." - }, - { - "name": "buffer_size", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Size of the `out` buffer in bytes." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository where the branches live" - }, - { - "name": "canonical_branch_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name of the local branch." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "upstreamName", - "cppFunctionName": "UpstreamName", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "number of characters in the reference name including the trailing NUL byte; GIT_ENOTFOUND when no remote tracking reference exists, otherwise an error code.", - "jsClassName": "Number" - }, - "description": "

Return the name of the reference supporting the remote tracking branch,\ngiven the name of a local branch reference.

\n" - }, - { - "cFunctionName": "git_branch_is_head", - "args": [ - { - "name": "branch", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Current underlying reference of the branch." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "isHead", - "cppFunctionName": "IsHead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if HEAD points at the branch, 0 if it isn't, error code otherwise.", - "jsClassName": "Number" - }, - "description": "

Determine if the current local branch is pointed at by HEAD.

\n" - }, - { - "cFunctionName": "git_branch_remote_name", - "args": [ - { - "name": "remote_name_out", - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The user-allocated buffer which will be filled with the name of the remote. Pass NULL if you just want to get the needed size of the name of the remote as the output value." - }, - { - "name": "buffer_size", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Size of the `out` buffer in bytes." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository where the branch lives." - }, - { - "name": "canonical_branch_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name of the remote tracking branch." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "remoteName", - "cppFunctionName": "RemoteName", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "Number of characters in the reference name including the trailing NUL byte; GIT_ENOTFOUND when no remote matching remote was found, GIT_EAMBIGUOUS when the branch maps to several remotes, otherwise an error code.", - "jsClassName": "Number" - }, - "description": "

Return the name of remote that the remote tracking branch belongs to.

\n" - } - ] - }, - { - "filename": "checkout.h", - "ignore": true, - "jsClassName": "Checkout", - "cppClassName": "Checkout", - "cType": "git_checkout", - "freeFunctionName": "git_checkout_free", - "functions": [ - { - "cFunctionName": "git_checkout_head", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository to check out (must be non-bare)" - }, - { - "name": "opts", - "cType": "git_checkout_opts *", - "cppClassName": "CheckoutOpts", - "jsClassName": "CheckoutOpts", - "comment": "specifies checkout options (may be NULL)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "head", - "cppFunctionName": "Head", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing branch, GIT_ERROR otherwise (use giterr_last for information about the error)", - "jsClassName": "Number" - }, - "description": "

Updates files in the index and the working tree to match the content of\nthe commit pointed at by HEAD.

\n" - }, - { - "cFunctionName": "git_checkout_index", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository into which to check out (must be non-bare)" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "index to be checked out (or NULL to use repository index)" - }, - { - "name": "opts", - "cType": "git_checkout_opts *", - "cppClassName": "CheckoutOpts", - "jsClassName": "CheckoutOpts", - "comment": "specifies checkout options (may be NULL)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "index", - "cppFunctionName": "Index", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)", - "jsClassName": "Number" - }, - "description": "

Updates files in the working tree to match the content of the index.

\n" - }, - { - "cFunctionName": "git_checkout_tree", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository to check out (must be non-bare)" - }, - { - "name": "treeish", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "a commit, tag or tree which content will be used to update the working directory" - }, - { - "name": "opts", - "cType": "git_checkout_opts *", - "cppClassName": "CheckoutOpts", - "jsClassName": "CheckoutOpts", - "comment": "specifies checkout options (may be NULL)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "tree", - "cppFunctionName": "Tree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)", - "jsClassName": "Number" - }, - "description": "

Updates files in the index and working tree to match the content of the\ntree pointed at by the treeish.

\n" - } - ] - }, - { - "filename": "commit.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h", - "../include/signature.h", - "../include/tree.h" - ], - "jsClassName": "Commit", - "cppClassName": "GitCommit", - "cType": "git_commit", - "freeFunctionName": "git_commit_free", - "functions": [ - { - "cFunctionName": "git_commit_lookup_prefix", - "args": [ - { - "name": "commit", - "cType": "git_commit **", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isReturn": true, - "comment": "pointer to the looked up commit" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repo to use when locating the commit." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the commit to locate. If the object is an annotated tag it will be peeled back to the commit." - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the length of the short identifier" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "lookupPrefix", - "cppFunctionName": "LookupPrefix", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a commit object from a repository,\ngiven a prefix of its identifier (short id).

\n" - }, - { - "cFunctionName": "git_commit_free", - "args": [ - { - "name": "commit", - "cType": "git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "the commit to close" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open commit

\n" - }, - { - "cFunctionName": "git_commit_id", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "object identity for the commit.", - "jsClassName": "Oid" - }, - "description": "

Get the id of a commit.

\n" - }, - { - "cFunctionName": "git_commit_message_encoding", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "messageEncoding", - "cppFunctionName": "MessageEncoding", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "NULL, or the encoding", - "jsClassName": "String" - }, - "description": "

Get the encoding for the message of a commit,\nas a string representing a standard encoding name.

\n" - }, - { - "cFunctionName": "git_commit_message", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "message", - "cppFunctionName": "Message", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the message of a commit", - "jsClassName": "String" - }, - "description": "

Get the full message of a commit.

\n" - }, - { - "cFunctionName": "git_commit_time", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "time", - "cppFunctionName": "Time", - "return": { - "cType": "git_time_t", - "cppClassName": "Number", - "comment": "the time of a commit", - "jsClassName": "Number" - }, - "description": "

Get the commit time (i.e. committer time) of a commit.

\n" - }, - { - "cFunctionName": "git_commit_time_offset", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "offset", - "cppFunctionName": "Offset", - "return": { - "cType": "int", - "cppClassName": "Integer", - "comment": "positive or negative timezone offset, in minutes from UTC", - "jsClassName": "Number" - }, - "description": "

Get the commit timezone offset (i.e. committer's preferred timezone) of a commit.

\n" - }, - { - "cFunctionName": "git_commit_committer", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "committer", - "cppFunctionName": "Committer", - "return": { - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "copy": "git_signature_dup", - "comment": "the committer of a commit", - "jsClassName": "Signature" - }, - "description": "

Get the committer of a commit.

\n" - }, - { - "cFunctionName": "git_commit_author", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "author", - "cppFunctionName": "Author", - "return": { - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "copy": "git_signature_dup", - "comment": "the author of a commit", - "jsClassName": "Signature" - }, - "description": "

Get the author of a commit.

\n" - }, - { - "cFunctionName": "git_commit_tree", - "args": [ - { - "name": "tree_out", - "cType": "git_tree **", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isReturn": true, - "comment": "pointer where to store the tree object" - }, - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getTree", - "cppFunctionName": "GetTree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the tree pointed to by a commit.

\n" - }, - { - "cFunctionName": "git_commit_tree_id", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "treeId", - "cppFunctionName": "TreeId", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the id of tree pointed to by commit.", - "jsClassName": "Oid" - }, - "description": "

Get the id of the tree pointed to by a commit. This differs from\ngit_commit_tree in that no attempts are made to fetch an object\nfrom the ODB.

\n" - }, - { - "cFunctionName": "git_commit_parentcount", - "args": [ - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "parentCount", - "cppFunctionName": "ParentCount", - "return": { - "cType": "unsigned int", - "cppClassName": "Uint32", - "comment": "integer of count of parents", - "jsClassName": "Number" - }, - "description": "

Get the number of parents of this commit

\n" - }, - { - "cFunctionName": "git_commit_parent", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_commit **", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "comment": "Pointer where to store the parent commit" - }, - { - "name": "commit", - "cType": "git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - }, - { - "name": "n", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position of the parent (from 0 to `parentcount`)" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "parent", - "cppFunctionName": "Parent", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the specified parent of the commit.

\n" - }, - { - "cFunctionName": "git_commit_parent_id", - "args": [ - { - "name": "commit", - "cType": "git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - }, - { - "name": "n", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position of the parent (from 0 to `parentcount`)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "parentId", - "cppFunctionName": "ParentId", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the id of the parent, NULL on error.", - "jsClassName": "Oid" - }, - "description": "

Get the oid of a specified parent for a commit. This is different from\ngit_commit_parent, which will attempt to load the parent commit from\nthe ODB.

\n" - }, - { - "cFunctionName": "git_commit_nth_gen_ancestor", - "args": [ - { - "name": "ancestor", - "cType": "git_commit **", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isReturn": true, - "comment": "Pointer where to store the ancestor commit" - }, - { - "name": "commit", - "cType": "const git_commit *", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isSelf": true, - "comment": "a previously loaded commit." - }, - { - "name": "n", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the requested generation" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "nthGenAncestor", - "cppFunctionName": "NthGenAncestor", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; GIT_ENOTFOUND if no matching ancestor exists or an error code", - "jsClassName": "Number" - }, - "description": "

Get the commit object that is the th generation ancestor\nof the named commit object, following only the first parents.\nThe returned commit has to be freed by the caller.

\n" - }, - { - "cFunctionName": "git_commit_create_v", - "args": [ - { - "name": "id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "isReturn": true - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository" - }, - { - "name": "update_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "name": "author", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature" - }, - { - "name": "committer", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature" - }, - { - "name": "message_encoding", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "name": "message", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree" - }, - { - "name": "parent_count", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "createV", - "cppFunctionName": "CreateV", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create new commit in the repository using a variable argument list.

\n" - } - ] - }, - { - "filename": "common.h", - "ignore": true, - "jsClassName": "Common", - "cppClassName": "Common", - "cType": "git_common", - "functions": [ - { - "cFunctionName": "git_libgit2_version", - "args": [ - { - "name": "major", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Store the major version number" - }, - { - "name": "minor", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Store the minor version number" - }, - { - "name": "rev", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Store the revision (patch) number" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitLibgit2Version", - "cppFunctionName": "GitLibgit2Version", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Return the version of the libgit2 library\nbeing currently used.

\n" - }, - { - "cFunctionName": "git_libgit2_capabilities", - "args": [], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitLibgit2Capabilities", - "cppFunctionName": "GitLibgit2Capabilities", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "A combination of GIT_CAP_* values. - GIT_CAP_THREADS Libgit2 was compiled with thread support. Note that thread support is still to be seen as a 'work in progress' - basic object lookups are believed to be threadsafe, but other operations may not be. - GIT_CAP_HTTPS Libgit2 supports the https:// protocol. This requires the openssl library to be found when compiling libgit2.", - "jsClassName": "Number" - }, - "description": "

Query compile time options for libgit2.

\n" - }, - { - "cFunctionName": "git_libgit2_opts", - "args": [ - { - "name": "option", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Option key" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitLibgit2Opts", - "cppFunctionName": "GitLibgit2Opts", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure", - "jsClassName": "Number" - }, - "description": "

Set or query a library global option

\n" - } - ] - }, - { - "filename": "config.h", - "ignore": true, - "jsClassName": "Config", - "cppClassName": "Config", - "cType": "git_config", - "freeFunctionName": "git_config_free", - "functions": [ - { - "cFunctionName": "git_config_find_global", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Buffer to store the path in" - }, - { - "name": "length", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "size of the buffer in bytes" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "findGlobal", - "cppFunctionName": "FindGlobal", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if a global configuration file has been found. Its path will be stored in `buffer`.", - "jsClassName": "Number" - }, - "description": "

Locate the path to the global configuration file

\n" - }, - { - "cFunctionName": "git_config_find_xdg", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Buffer to store the path in" - }, - { - "name": "length", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "size of the buffer in bytes" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "findXdg", - "cppFunctionName": "FindXdg", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if a xdg compatible configuration file has been found. Its path will be stored in `buffer`.", - "jsClassName": "Number" - }, - "description": "

Locate the path to the global xdg compatible configuration file

\n" - }, - { - "cFunctionName": "git_config_find_system", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Buffer to store the path in" - }, - { - "name": "length", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "size of the buffer in bytes" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "findSystem", - "cppFunctionName": "FindSystem", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if a system configuration file has been found. Its path will be stored in `buffer`.", - "jsClassName": "Number" - }, - "description": "

Locate the path to the system configuration file

\n" - }, - { - "cFunctionName": "git_config_open_default", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_config **", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "Pointer to store the config instance" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "openDefault", - "cppFunctionName": "OpenDefault", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Open the global, XDG and system configuration files

\n" - }, - { - "cFunctionName": "git_config_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_config **", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "pointer to the new configuration" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "new", - "cppFunctionName": "New", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Allocate a new configuration object

\n" - }, - { - "cFunctionName": "git_config_add_backend", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "the configuration to add the file to" - }, - { - "name": "file", - "cType": "git_config_backend *", - "cppClassName": "ConfigBackend", - "jsClassName": "ConfigBackend", - "comment": "the configuration file (backend) to add" - }, - { - "name": "level", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the priority level of the backend" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "if a config file already exists for the given priority level, replace it" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addBackend", - "cppFunctionName": "AddBackend", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EEXISTS when adding more than one file for a given priority level (and force_replace set to 0), or error code", - "jsClassName": "Number" - }, - "description": "

Add a generic config file instance to an existing config

\n" - }, - { - "cFunctionName": "git_config_add_file_ondisk", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "the configuration to add the file to" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to the configuration file to add" - }, - { - "name": "level", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the priority level of the backend" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "replace config file at the given priority level" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addFileOndisk", - "cppFunctionName": "AddFileOndisk", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EEXISTS when adding more than one file for a given priority level (and force_replace set to 0), GIT_ENOTFOUND when the file doesn't exist or error code", - "jsClassName": "Number" - }, - "description": "

Add an on-disk config file instance to an existing config

\n" - }, - { - "cFunctionName": "git_config_open_ondisk", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_config **", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "The configuration instance to create" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Path to the on-disk file to open" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "openOndisk", - "cppFunctionName": "OpenOndisk", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND when the file doesn't exist or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new config instance containing a single on-disk file

\n" - }, - { - "cFunctionName": "git_config_open_level", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_config **", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "The configuration instance to create" - }, - { - "name": "parent", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "Multi-level config to search for the given level" - }, - { - "name": "level", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Configuration level to search for" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "openLevel", - "cppFunctionName": "OpenLevel", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_ENOTFOUND if the passed level cannot be found in the multi-level parent config, or an error code", - "jsClassName": "Number" - }, - "description": "

Build a single-level focused config object from a multi-level one.

\n" - }, - { - "cFunctionName": "git_config_refresh", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "The configuration to refresh" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "refresh", - "cppFunctionName": "Refresh", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Reload changed config files

\n" - }, - { - "cFunctionName": "git_config_free", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "the configuration to free" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the configuration and its associated memory and files

\n" - }, - { - "cFunctionName": "git_config_get_entry", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "const git_config_entry **", - "cppClassName": "ConfigEntry", - "jsClassName": "ConfigEntry", - "comment": "pointer to the variable git_config_entry" - }, - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getEntry", - "cppFunctionName": "GetEntry", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the git_config_entry of a config variable.

\n" - }, - { - "cFunctionName": "git_config_get_int32", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int32_t *", - "cppClassName": "int32_t", - "jsClassName": "int32_t", - "comment": "pointer to the variable where the value should be stored" - }, - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getInt32", - "cppFunctionName": "GetInt32", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the value of an integer config variable.

\n" - }, - { - "cFunctionName": "git_config_get_int64", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int64_t *", - "cppClassName": "int64_t", - "jsClassName": "int64_t", - "comment": "pointer to the variable where the value should be stored" - }, - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getInt64", - "cppFunctionName": "GetInt64", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the value of a long integer config variable.

\n" - }, - { - "cFunctionName": "git_config_get_bool", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "pointer to the variable where the value should be stored" - }, - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getBool", - "cppFunctionName": "GetBool", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the value of a boolean config variable.

\n" - }, - { - "cFunctionName": "git_config_get_string", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "comment": "pointer to the variable's value" - }, - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getString", - "cppFunctionName": "GetString", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the value of a string config variable.

\n" - }, - { - "cFunctionName": "git_config_get_multivar", - "args": [ - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - }, - { - "name": "regexp", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "regular expression to filter which variables we're interested in. Use NULL to indicate all" - }, - { - "name": "callback", - "cType": "git_config_foreach_cb", - "cppClassName": "ConfigForeachCb", - "jsClassName": "ConfigForeachCb", - "comment": "the function to be called on each value of the variable" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "opaque pointer to pass to the callback" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getMultivar", - "cppFunctionName": "GetMultivar", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Get each value of a multivar.

\n" - }, - { - "cFunctionName": "git_config_set_int32", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - }, - { - "name": "value", - "cType": "int32_t", - "cppClassName": "int32_t", - "jsClassName": "int32_t", - "comment": "Integer value for the variable" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setInt32", - "cppFunctionName": "SetInt32", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Set the value of an integer config variable in the config file\nwith the highest level (usually the local one).

\n" - }, - { - "cFunctionName": "git_config_set_int64", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - }, - { - "name": "value", - "cType": "int64_t", - "cppClassName": "int64_t", - "jsClassName": "int64_t", - "comment": "Long integer value for the variable" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setInt64", - "cppFunctionName": "SetInt64", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Set the value of a long integer config variable in the config file\nwith the highest level (usually the local one).

\n" - }, - { - "cFunctionName": "git_config_set_bool", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - }, - { - "name": "value", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "the value to store" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setBool", - "cppFunctionName": "SetBool", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Set the value of a boolean config variable in the config file\nwith the highest level (usually the local one).

\n" - }, - { - "cFunctionName": "git_config_set_string", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - }, - { - "name": "value", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the string to store." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setString", - "cppFunctionName": "SetString", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Set the value of a string config variable in the config file\nwith the highest level (usually the local one).

\n" - }, - { - "cFunctionName": "git_config_set_multivar", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to look for the variable" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable's name" - }, - { - "name": "regexp", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "a regular expression to indicate which values to replace" - }, - { - "name": "value", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the new value." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setMultivar", - "cppFunctionName": "SetMultivar", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Set a multivar in the local config file.

\n" - }, - { - "cFunctionName": "git_config_delete_entry", - "args": [ - { - "name": "cfg", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "the configuration" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the variable to delete" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "deleteEntry", - "cppFunctionName": "DeleteEntry", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Delete a config variable from the config file\nwith the highest level (usually the local one).

\n" - }, - { - "cFunctionName": "git_config_foreach", - "args": [ - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to get the variables from" - }, - { - "name": "callback", - "cType": "git_config_foreach_cb", - "cppClassName": "ConfigForeachCb", - "jsClassName": "ConfigForeachCb", - "comment": "the function to call on each variable" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "the data to pass to the callback" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Perform an operation on each config variable.

\n" - }, - { - "cFunctionName": "git_config_foreach_match", - "args": [ - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "isSelf": true, - "comment": "where to get the variables from" - }, - { - "name": "regexp", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "regular expression to match against config names" - }, - { - "name": "callback", - "cType": "git_config_foreach_cb", - "cppClassName": "ConfigForeachCb", - "jsClassName": "ConfigForeachCb", - "comment": "the function to call on each variable" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "the data to pass to the callback" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "foreachMatch", - "cppFunctionName": "ForeachMatch", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or the return value of the callback which didn't return 0", - "jsClassName": "Number" - }, - "description": "

Perform an operation on each config variable matching a regular expression.

\n" - }, - { - "cFunctionName": "git_config_get_mapped", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "place to store the result of the mapping" - }, - { - "name": "cfg", - "cType": "const git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "config file to get the variables from" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name of the config variable to lookup" - }, - { - "name": "maps", - "cType": "const git_cvar_map *", - "cppClassName": "CvarMap", - "jsClassName": "CvarMap", - "comment": "array of `git_cvar_map` objects specifying the possible mappings" - }, - { - "name": "map_n", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "number of mapping objects in `maps`" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "getMapped", - "cppFunctionName": "GetMapped", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, error code otherwise", - "jsClassName": "Number" - }, - "description": "

Query the value of a config variable and return it mapped to\nan integer constant.

\n" - }, - { - "cFunctionName": "git_config_lookup_map_value", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "place to store the result of the parsing" - }, - { - "name": "maps", - "cType": "const git_cvar_map *", - "cppClassName": "CvarMap", - "jsClassName": "CvarMap", - "comment": "array of `git_cvar_map` objects specifying the possible mappings" - }, - { - "name": "map_n", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "number of mapping objects in `maps`" - }, - { - "name": "value", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "value to parse" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "lookupMapValue", - "cppFunctionName": "LookupMapValue", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Maps a string value to an integer constant

\n" - }, - { - "cFunctionName": "git_config_parse_bool", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "place to store the result of the parsing" - }, - { - "name": "value", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "value to parse" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "parseBool", - "cppFunctionName": "ParseBool", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Parse a string value as a bool.

\n" - }, - { - "cFunctionName": "git_config_parse_int32", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int32_t *", - "cppClassName": "int32_t", - "jsClassName": "int32_t", - "comment": "place to store the result of the parsing" - }, - { - "name": "value", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "value to parse" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "parseInt32", - "cppFunctionName": "ParseInt32", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Parse a string value as an int32.

\n" - }, - { - "cFunctionName": "git_config_parse_int64", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "int64_t *", - "cppClassName": "int64_t", - "jsClassName": "int64_t", - "comment": "place to store the result of the parsing" - }, - { - "name": "value", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "value to parse" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "parseInt64", - "cppFunctionName": "ParseInt64", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Parse a string value as an int64.

\n" - } - ] - }, - { - "filename": "cred_helpers.h", - "ignore": true, - "jsClassName": "CredHelpers", - "cppClassName": "CredHelpers", - "cType": "git_cred_helpers", - "freeFunctionName": "git_cred_helpers_free", - "functions": [ - { - "cFunctionName": "git_cred_userpass", - "args": [ - { - "name": "cred", - "cType": "git_cred **", - "cppClassName": "Cred", - "jsClassName": "Cred", - "comment": "The newly created credential object." - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The resource for which we are demanding a credential." - }, - { - "name": "user_from_url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The username that was embedded in a \"user@host\" remote url, or NULL if not included." - }, - { - "name": "allowed_types", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "A bitmask stating which cred types are OK to return." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "The payload provided when specifying this callback. (This is interpreted as a `git_cred_userpass_payload*`.)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitCredUserpass", - "cppFunctionName": "GitCredUserpass", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Stock callback usable as a git_cred_acquire_cb. This calls\ngit_cred_userpass_plaintext_new unless the protocol has not specified\nGIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type.

\n" - } - ] - }, - { - "filename": "patch.h", - "dependencies": [ - "../include/delta.h", - "../include/diff_range.h" - ], - "jsClassName": "Patch", - "cppClassName": "GitPatch", - "cType": "git_diff_patch", - "freeFunctionName": "git_diff_patch_free", - "functions": [ - { - "cFunctionName": "git_diff_patch_free", - "args": [ - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "isFree": true, - "jsFunctionName": "patchFree", - "cppFunctionName": "PatchFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free a git_diff_patch object.

\n" - }, - { - "cFunctionName": "git_diff_patch_delta", - "args": [ - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "delta", - "cppFunctionName": "Delta", - "return": { - "cType": "const git_diff_delta *", - "cppClassName": "GitDelta", - "copy": "git_diff_delta_dup", - "jsClassName": "Delta" - }, - "description": "

Get the delta associated with a patch

\n" - }, - { - "cFunctionName": "git_diff_patch_num_hunks", - "args": [ - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - "description": "

Get the number of hunks in a patch

\n" - }, - { - "cFunctionName": "git_diff_patch_line_stats", - "args": [ - { - "name": "total_context", - "cType": "size_t *", - "cppClassName": "Integer", - "jsClassName": "Number", - "isReturn": true, - "comment": "Count of context lines in output, can be NULL." - }, - { - "name": "total_additions", - "cType": "size_t *", - "cppClassName": "Integer", - "jsClassName": "Number", - "isReturn": true, - "comment": "Count of addition lines in output, can be NULL." - }, - { - "name": "total_deletions", - "cType": "size_t *", - "cppClassName": "Integer", - "jsClassName": "Number", - "isReturn": true, - "comment": "Count of deletion lines in output, can be NULL." - }, - { - "name": "patch", - "cType": "const git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true, - "comment": "The git_diff_patch object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "stats", - "cppFunctionName": "Stats", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on error", - "jsClassName": "Number" - }, - "description": "

Get line counts of each type in a patch.

\n" - }, - { - "cFunctionName": "git_diff_patch_get_hunk", - "args": [ - { - "name": "range", - "jsName": "range", - "cType": "const git_diff_range **", - "cppClassName": "GitDiffRange", - "jsClassName": "DiffRange", - "isReturn": true, - "copy": "git_diff_range_dup", - "comment": "Output pointer to git_diff_range of hunk" - }, - { - "name": "header", - "jsName": "header", - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "isReturn": true, - "comment": "Output pointer to header string for hunk. Unlike the content pointer for each line, this will be NUL-terminated" - }, - { - "name": "header_len", - "jsName": "headerLength", - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "isReturn": true, - "comment": "Output value of characters in header string" - }, - { - "name": "lines_in_hunk", - "jsName": "lines", - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "isReturn": true, - "comment": "Output count of total lines in this hunk" - }, - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true, - "comment": "Input pointer to patch object" - }, - { - "name": "hunk_idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Input index of hunk to get information about" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hunk", - "cppFunctionName": "Hunk", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error", - "jsClassName": "Number" - }, - "description": "

Get the information about a hunk in a patch

\n" - }, - { - "cFunctionName": "git_diff_patch_num_lines_in_hunk", - "args": [ - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true, - "comment": "The git_diff_patch object" - }, - { - "name": "hunk_idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Index of the hunk" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "lines", - "cppFunctionName": "Lines", - "return": { - "cType": "int", - "cppClassName": "Int32", - "comment": "Number of lines in hunk or -1 if invalid hunk index", - "jsClassName": "Number" - }, - "description": "

Get the number of lines in a hunk.

\n" - }, - { - "cFunctionName": "git_diff_patch_get_line_in_hunk", - "args": [ - { - "name": "line_origin", - "jsName": "lineOrigin", - "cType": "char *", - "cppClassName": "Integer", - "jsClassName": "Number", - "isReturn": true, - "comment": "A GIT_DIFF_LINE constant from above" - }, - { - "name": "content", - "jsName": "content", - "size": "content_len", - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "isReturn": true, - "comment": "Pointer to content of diff line, not NUL-terminated" - }, - { - "name": "content_len", - "jsName": "length", - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "isReturn": true, - "comment": "Number of characters in content" - }, - { - "name": "old_lineno", - "jsName": "oldLineNumber", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "isReturn": true, - "comment": "Line number in old file or -1 if line is added" - }, - { - "name": "new_lineno", - "jsName": "newLineNumber", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "isReturn": true, - "comment": "Line number in new file or -1 if line is deleted" - }, - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true, - "comment": "The patch to look in" - }, - { - "name": "hunk_idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "The index of the hunk" - }, - { - "name": "line_of_hunk", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "The index of the line in the hunk" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "line", - "cppFunctionName": "Line", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure", - "jsClassName": "Number" - }, - "description": "

Get data about a line in a hunk of a patch.

\n" - }, - { - "cFunctionName": "git_diff_patch_print", - "args": [ - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true, - "comment": "A git_diff_patch representing changes to one file" - }, - { - "name": "print_cb", - "cType": "git_diff_data_cb", - "cppClassName": "DiffDataCb", - "jsClassName": "DiffDataCb", - "comment": "Callback function to output lines of the patch. Will be called for file headers, hunk headers, and diff lines." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Reference pointer that will be passed to your callbacks." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "patchPrint", - "cppFunctionName": "PatchPrint", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Serialize the patch to text via callback.

\n" - }, - { - "cFunctionName": "git_diff_patch_to_str", - "args": [ - { - "name": "string", - "cType": "char **", - "cppClassName": "String", - "jsClassName": "String", - "isReturn": true, - "comment": "Allocated string; caller must free.", - "freeFunctionName": "free" - }, - { - "name": "patch", - "cType": "git_diff_patch *", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isSelf": true, - "comment": "A git_diff_patch representing changes to one file" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "toString", - "cppFunctionName": "ToString", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure.", - "jsClassName": "Number" - }, - "description": "

Get the content of a patch as a single diff text.

\n" - } - ] - }, - { - "filename": "clone_options.h", - "dependencies": [], - "jsClassName": "CloneOptions", - "cppClassName": "GitCloneOptions", - "cType": "git_clone_options", - "freeFunctionName": "free", - "fields": [] - }, - { - "filename": "diff_options.h", - "dependencies": [], - "jsClassName": "DiffOptions", - "cppClassName": "GitDiffOptions", - "cType": "git_diff_options", - "freeFunctionName": "free", - "fields": [] - }, - { - "filename": "diff_find_options.h", - "dependencies": [], - "jsClassName": "DiffFindOptions", - "cppClassName": "GitDiffFindOptions", - "cType": "git_diff_find_options", - "freeFunctionName": "free", - "fields": [] - }, - { - "filename": "diff_range.h", - "dependencies": [], - "jsClassName": "DiffRange", - "cppClassName": "GitDiffRange", - "cType": "git_diff_range", - "freeFunctionName": "free", - "fields": [ - { - "jsFunctionName": "oldStart", - "cppFunctionName": "OldStart", - "name": "old_start", - "cType": "int", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "oldLines", - "cppFunctionName": "OldLines", - "name": "old_lines", - "cType": "int", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "newStart", - "cppFunctionName": "NewStart", - "name": "new_start", - "cType": "int", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "newLines", - "cppFunctionName": "NewLines", - "name": "new_lines", - "cType": "int", - "cppClassName": "Integer", - "jsClassName": "Number" - } - ] - }, - { - "filename": "diff_file.h", - "dependencies": [ - "../include/oid.h" - ], - "jsClassName": "DiffFile", - "cppClassName": "GitDiffFile", - "cType": "git_diff_file", - "freeFunctionName": "free", - "fields": [ - { - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "name": "oid", - "cType": "git_oid", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "copy": "git_oid_dup" - }, - { - "jsFunctionName": "path", - "cppFunctionName": "Path", - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "jsFunctionName": "size", - "cppFunctionName": "Size", - "name": "size", - "cType": "git_off_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "flags", - "cppFunctionName": "Flags", - "name": "flags", - "cType": "uint32_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "mode", - "cppFunctionName": "Mode", - "name": "mode", - "cType": "uint16_t", - "cppClassName": "Integer", - "jsClassName": "Number" - } - ] - }, - { - "filename": "delta.h", - "dependencies": [ - "../include/diff_file.h" - ], - "jsClassName": "Delta", - "cppClassName": "GitDelta", - "cType": "git_diff_delta", - "freeFunctionName": "free", - "fields": [ - { - "jsFunctionName": "oldFile", - "cppFunctionName": "OldFile", - "name": "old_file", - "cType": "git_diff_file", - "cppClassName": "GitDiffFile", - "jsClassName": "DiffFile", - "copy": "git_diff_file_dup" - }, - { - "jsFunctionName": "newFile", - "cppFunctionName": "NewFile", - "name": "new_file", - "cType": "git_diff_file", - "cppClassName": "GitDiffFile", - "jsClassName": "DiffFile", - "copy": "git_diff_file_dup" - }, - { - "jsFunctionName": "status", - "cppFunctionName": "Status", - "name": "status", - "cType": "git_delta_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "similarity", - "cppFunctionName": "Similarity", - "name": "similarity", - "cType": "uint32_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "flags", - "cppFunctionName": "Flags", - "name": "flags", - "cType": "uint32_t", - "cppClassName": "Integer", - "jsClassName": "Number" - } - ] - }, - { - "filename": "diff_list.h", - "dependencies": [ - "../include/diff_options.h", - "../include/diff_find_options.h", - "../include/repo.h", - "../include/tree.h", - "../include/index.h", - "../include/patch.h", - "../include/delta.h" - ], - "jsClassName": "DiffList", - "cppClassName": "GitDiffList", - "cType": "git_diff_list", - "freeFunctionName": "git_diff_list_free", - "functions": [ - { - "cFunctionName": "git_diff_list_free", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "comment": "The previously created diff list; cannot be used after free." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "listFree", - "cppFunctionName": "ListFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Deallocate a diff list.

\n" - }, - { - "cFunctionName": "git_diff_merge", - "args": [ - { - "name": "onto", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isSelf": true, - "comment": "Diff to merge into." - }, - { - "name": "from", - "cType": "const git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "comment": "Diff to merge." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "merge", - "cppFunctionName": "Merge", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Merge one diff list into another.

\n" - }, - { - "cFunctionName": "git_diff_find_similar", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isSelf": true, - "comment": "Diff list to run detection algorithms on" - }, - { - "name": "options", - "cType": "git_diff_find_options *", - "cppClassName": "GitDiffFindOptions", - "jsClassName": "DiffFindOptions", - "comment": "Control how detection should be run, NULL for defaults" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "findSimilar", - "cppFunctionName": "FindSimilar", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, -1 on failure", - "jsClassName": "Number" - }, - "description": "

Transform a diff list marking file renames, copies, etc.

\n" - }, - { - "cFunctionName": "git_diff_foreach", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "comment": "A git_diff_list generated by one of the above functions." - }, - { - "name": "file_cb", - "cType": "git_diff_file_cb", - "cppClassName": "DiffFileCb", - "jsClassName": "DiffFileCb", - "comment": "Callback function to make per file in the diff." - }, - { - "name": "hunk_cb", - "cType": "git_diff_hunk_cb", - "cppClassName": "DiffHunkCb", - "jsClassName": "DiffHunkCb", - "comment": "Optional callback to make per hunk of text diff. This callback is called to describe a range of lines in the diff. It will not be issued for binary files." - }, - { - "name": "line_cb", - "cType": "git_diff_data_cb", - "cppClassName": "DiffDataCb", - "jsClassName": "DiffDataCb", - "comment": "Optional callback to make per line of diff text. This same callback will be made for context lines, added, and removed lines, and even for a deleted trailing newline." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Reference pointer that will be passed to your callbacks." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Loop over all deltas in a diff list issuing callbacks.

\n" - }, - { - "cFunctionName": "git_diff_print_compact", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "comment": "A git_diff_list generated by one of the above functions." - }, - { - "name": "print_cb", - "cType": "git_diff_data_cb", - "cppClassName": "DiffDataCb", - "jsClassName": "DiffDataCb", - "comment": "Callback to make per line of diff text." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Reference pointer that will be passed to your callback." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "printCompact", - "cppFunctionName": "PrintCompact", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Iterate over a diff generating text output like "git diff --name-status".

\n" - }, - { - "cFunctionName": "git_diff_status_char", - "args": [ - { - "name": "status", - "cType": "git_delta_t", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "The git_delta_t value to look up" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "statusChar", - "cppFunctionName": "StatusChar", - "return": { - "cType": "char", - "cppClassName": "String", - "comment": "The single character label for that code", - "jsClassName": "String" - }, - "description": "

Look up the single character abbreviation for a delta status code.

\n" - }, - { - "cFunctionName": "git_diff_print_patch", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isSelf": true, - "comment": "A git_diff_list generated by one of the above functions." - }, - { - "name": "print_cb", - "cType": "git_diff_data_cb", - "cppClassName": "DiffDataCb", - "jsClassName": "DiffDataCb", - "comment": "Callback function to output lines of the diff. This same function will be called for file headers, hunk headers, and diff lines. Fortunately, you can probably use various GIT_DIFF_LINE constants to determine what text you are given." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Reference pointer that will be passed to your callbacks." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "printPatch", - "cppFunctionName": "PrintPatch", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Iterate over a diff generating text output like "git diff".

\n" - }, - { - "cFunctionName": "git_diff_num_deltas", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isSelf": true, - "comment": "A git_diff_list generated by one of the above functions" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "Count of number of deltas in the list", - "jsClassName": "Number" - }, - "description": "

Query how many diff records are there in a diff list.

\n" - }, - { - "cFunctionName": "git_diff_num_deltas_of_type", - "args": [ - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "comment": "A git_diff_list generated by one of the above functions" - }, - { - "name": "type", - "cType": "git_delta_t", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "A git_delta_t value to filter the count" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "numDeltasOfType", - "cppFunctionName": "NumDeltasOfType", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "Count of number of deltas matching delta_t type", - "jsClassName": "Number" - }, - "description": "

Query how many diff deltas are there in a diff list filtered by type.

\n" - }, - { - "cFunctionName": "git_diff_get_patch", - "args": [ - { - "name": "patch_out", - "jsName": "patch", - "cType": "git_diff_patch **", - "cppClassName": "GitPatch", - "jsClassName": "Patch", - "isReturn": true, - "comment": "Output parameter for the delta patch object" - }, - { - "name": "delta_out", - "jsName": "delta", - "cType": "const git_diff_delta **", - "copy": "git_diff_delta_dup", - "cppClassName": "GitDelta", - "jsClassName": "Delta", - "isReturn": true, - "comment": "Output parameter for the delta object" - }, - { - "name": "diff", - "cType": "git_diff_list *", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isSelf": true, - "comment": "Diff list object" - }, - { - "name": "idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Index into diff list" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "patch", - "cppFunctionName": "Patch", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, other value < 0 on error", - "jsClassName": "Number" - }, - "description": "

Return the diff delta and patch for an entry in the diff list.

\n" - }, - { - "cFunctionName": "git_diff_blobs", - "args": [ - { - "name": "old_blob", - "cType": "const git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "comment": "Blob for old side of diff, or NULL for empty blob" - }, - { - "name": "new_blob", - "cType": "const git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob" - }, - { - "name": "options", - "cType": "const git_diff_options *", - "cppClassName": "GitDiffOptions", - "jsClassName": "DiffOptions" - }, - { - "name": "file_cb", - "cType": "git_diff_file_cb", - "cppClassName": "DiffFileCb", - "jsClassName": "DiffFileCb" - }, - { - "name": "hunk_cb", - "cType": "git_diff_hunk_cb", - "cppClassName": "DiffHunkCb", - "jsClassName": "DiffHunkCb" - }, - { - "name": "line_cb", - "cType": "git_diff_data_cb", - "cppClassName": "DiffDataCb", - "jsClassName": "DiffDataCb" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "blobs", - "cppFunctionName": "Blobs", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback return, or error code", - "jsClassName": "Number" - }, - "description": "

Directly run a diff on two blobs.

\n" - }, - { - "cFunctionName": "git_diff_blob_to_buffer", - "args": [ - { - "name": "old_blob", - "cType": "const git_blob *", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "comment": "Blob for old side of diff, or NULL for empty blob" - }, - { - "name": "buffer", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "name": "buffer_len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "name": "options", - "cType": "const git_diff_options *", - "cppClassName": "GitDiffOptions", - "jsClassName": "DiffOptions" - }, - { - "name": "file_cb", - "cType": "git_diff_file_cb", - "cppClassName": "DiffFileCb", - "jsClassName": "DiffFileCb" - }, - { - "name": "hunk_cb", - "cType": "git_diff_hunk_cb", - "cppClassName": "DiffHunkCb", - "jsClassName": "DiffHunkCb" - }, - { - "name": "data_cb", - "cType": "git_diff_data_cb", - "cppClassName": "DiffDataCb", - "jsClassName": "DiffDataCb" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "blobToBuffer", - "cppFunctionName": "BlobToBuffer", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback return, or error code", - "jsClassName": "Number" - }, - "description": "

Directly run a diff between a blob and a buffer.

\n" - } - ] - }, - { - "filename": "error.h", - "ignore": true, - "jsClassName": "Error", - "cppClassName": "GitError", - "cType": "git_error", - "freeFunctionName": "git_errors_free", - "functions": [ - { - "cFunctionName": "giterr_last", - "args": [], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "lastError", - "cppFunctionName": "LastError", - "return": { - "cType": "const git_error *", - "cppClassName": "Error", - "copy": "fixme", - "comment": "A git_error object." - }, - "description": "

Return the last git_error object that was generated for the\ncurrent thread or NULL if no error has occurred.

\n" - }, - { - "cFunctionName": "giterr_clear", - "args": [], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "clear", - "cppFunctionName": "Clear", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Clear the last library error that occurred for this thread.

\n" - }, - { - "cFunctionName": "giterr_set_str", - "args": [ - { - "name": "error_class", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "One of the `git_error_t` enum above describing the general subsystem that is responsible for the error." - }, - { - "name": "string", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The formatted error message to keep" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "setString", - "cppFunctionName": "SetString", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the error message string for this thread.

\n" - }, - { - "cFunctionName": "giterr_set_oom", - "args": [], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "setOOM", - "cppFunctionName": "SetOOM", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the error message to a special value for memory allocation failure.

\n" - } - ] - }, - { - "filename": "graph.h", - "ignore": true, - "jsClassName": "Graph", - "cppClassName": "Graph", - "cType": "git_graph", - "freeFunctionName": "git_graph_free", - "functions": [ - { - "cFunctionName": "git_graph_ahead_behind", - "args": [ - { - "name": "ahead", - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "number of unique from commits in `upstream`" - }, - { - "name": "behind", - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "number of unique from commits in `local`" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository where the commits exist" - }, - { - "name": "local", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the commit for local" - }, - { - "name": "upstream", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the commit for upstream" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "aheadBehind", - "cppFunctionName": "AheadBehind", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Count the number of unique commits between two commit objects

\n" - } - ] - }, - { - "filename": "ignore.h", - "ignore": true, - "jsClassName": "Ignore", - "cppClassName": "Ignore", - "cType": "git_ignore", - "freeFunctionName": "git_ignore_free", - "functions": [ - { - "cFunctionName": "git_ignore_add_rule", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository to add ignore rules to." - }, - { - "name": "rules", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Text of rules, a la the contents of a .gitignore file. It is okay to have multiple rules in the text; if so, each rule should be terminated with a newline." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "addRule", - "cppFunctionName": "AddRule", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success", - "jsClassName": "Number" - }, - "description": "

Add ignore rules for a repository.

\n" - }, - { - "cFunctionName": "git_ignore_clear_internal_rules", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository to remove ignore rules from." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "clearInternalRules", - "cppFunctionName": "ClearInternalRules", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success", - "jsClassName": "Number" - }, - "description": "

Clear ignore rules that were explicitly added.

\n" - }, - { - "cFunctionName": "git_ignore_path_is_ignored", - "args": [ - { - "name": "ignored", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "boolean returning 0 if the file is not ignored, 1 if it is" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "a repository object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the file to check ignores for, relative to the repo's workdir." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "pathIsIgnored", - "cppFunctionName": "PathIsIgnored", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if ignore rules could be processed for the file (regardless of whether it exists or not), or an error < 0 if they could not.", - "jsClassName": "Number" - }, - "description": "

Test if the ignore rules apply to a given path.

\n" - } - ] - }, - { - "filename": "index_time.h", - "jsClassName": "IndexTime", - "cppClassName": "GitIndexTime", - "cType": "git_index_time", - "freeFunctionName": "free", - "fields": [ - { - "jsFunctionName": "seconds", - "cppFunctionName": "Seconds", - "name": "seconds", - "cType": "git_time_t", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "jsFunctionName": "nanoseconds", - "cppFunctionName": "Nanoseconds", - "name": "nanoseconds", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - } - ] - }, - { - "filename": "index_entry.h", - "dependencies": [ - "../include/index_time.h", - "../include/oid.h" - ], - "jsClassName": "IndexEntry", - "cppClassName": "GitIndexEntry", - "cType": "git_index_entry", - "freeFunctionName": "free", - "fields": [ - { - "jsFunctionName": "ctime", - "cppFunctionName": "Ctime", - "name": "ctime", - "cType": "git_index_time", - "cppClassName": "GitIndexTime", - "jsClassName": "IndexTime", - "copy": "git_index_time_dup" - }, - { - "jsFunctionName": "mtime", - "cppFunctionName": "Mtime", - "name": "mtime", - "cType": "git_index_time", - "cppClassName": "GitIndexTime", - "jsClassName": "IndexTime", - "copy": "git_index_time_dup" - }, - { - "jsFunctionName": "dev", - "cppFunctionName": "Dev", - "name": "dev", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "jsFunctionName": "ino", - "cppFunctionName": "Ino", - "name": "ino", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "jsFunctionName": "mode", - "cppFunctionName": "Mode", - "name": "mode", - "cType": "uint16_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "uid", - "cppFunctionName": "Uid", - "name": "uid", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "jsFunctionName": "gid", - "cppFunctionName": "gid", - "name": "gid", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "jsFunctionName": "file_size", - "cppFunctionName": "FileSize", - "name": "file_size", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "name": "oid", - "cType": "git_oid", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "copy": "git_oid_dup" - }, - { - "jsFunctionName": "flags", - "cppFunctionName": "Flags", - "name": "flags", - "cType": "uint16_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "flags_extended", - "cppFunctionName": "FlagsExtended", - "name": "flags_extended", - "cType": "uint16_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "path", - "cppFunctionName": "Path", - "name": "path", - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String" - } - ] - }, - { - "filename": "index.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h", - "../include/tree.h", - "../include/diff_list.h", - "../include/diff_options.h", - "../include/index_entry.h" - ], - "jsClassName": "Index", - "cppClassName": "GitIndex", - "cType": "git_index", - "freeFunctionName": "git_index_free", - "functions": [ - { - "cFunctionName": "git_index_open", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_index **", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "the pointer for the new index" - }, - { - "name": "index_path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the path to the index file in disk" - } - ], - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "open", - "cppFunctionName": "Open", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new bare Git index object as a memory representation\nof the Git index file in 'index_path', without a repository\nto back it.

\n" - }, - { - "cFunctionName": "git_index_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_index **", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "the pointer for the new index" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "new", - "cppFunctionName": "New", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create an in-memory index object.

\n" - }, - { - "cFunctionName": "git_index_free", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "an existing index object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free an existing index object.

\n" - }, - { - "cFunctionName": "git_index_owner", - "args": [ - { - "name": "index", - "cType": "const git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "The index" - } - ], - "ignore": "Never make public for memory allocation reasons", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "owner", - "cppFunctionName": "Owner", - "return": { - "cType": "git_repository *", - "cppClassName": "GitRepo", - "comment": "A pointer to the repository", - "jsClassName": "Repository" - }, - "description": "

Get the repository this index relates to

\n" - }, - { - "cFunctionName": "git_index_caps", - "args": [ - { - "name": "index", - "cType": "const git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "An existing index object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "caps", - "cppFunctionName": "Caps", - "return": { - "cType": "unsigned int", - "cppClassName": "Uint32", - "comment": "A combination of GIT_INDEXCAP values", - "jsClassName": "Number" - }, - "description": "

Read index capabilities flags.

\n" - }, - { - "cFunctionName": "git_index_set_caps", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "An existing index object" - }, - { - "name": "caps", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "A combination of GIT_INDEXCAP values" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setCaps", - "cppFunctionName": "SetCaps", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, -1 on failure", - "jsClassName": "Number" - }, - "description": "

Set index capabilities flags.

\n" - }, - { - "cFunctionName": "git_index_read", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "read", - "cppFunctionName": "Read", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Update the contents of an existing index object in memory\nby reading from the hard disk.

\n" - }, - { - "cFunctionName": "git_index_write", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "write", - "cppFunctionName": "Write", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Write an existing index object from memory back to disk\nusing an atomic file lock.

\n" - }, - { - "cFunctionName": "git_index_read_tree", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "comment": "tree to read" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "readTree", - "cppFunctionName": "ReadTree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Read a tree into the index file with stats

\n" - }, - { - "cFunctionName": "git_index_write_tree", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "Pointer where to store the OID of the written tree" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "Index to write" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "writeTree", - "cppFunctionName": "WriteTree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUNMERGED when the index is not clean or an error code", - "jsClassName": "Number" - }, - "description": "

Write the index as a tree

\n" - }, - { - "cFunctionName": "git_index_write_tree_to", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "Pointer where to store OID of the the written tree" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "Index to write" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to write the tree" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "writeTreeTo", - "cppFunctionName": "WriteTreeTo", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUNMERGED when the index is not clean or an error code", - "jsClassName": "Number" - }, - "description": "

Write the index as a tree to the given repository

\n" - }, - { - "cFunctionName": "git_index_entrycount", - "args": [ - { - "name": "index", - "cType": "const git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "integer of count of current entries", - "jsClassName": "Number" - }, - "description": "

Get the count of entries currently in the index

\n" - }, - { - "cFunctionName": "git_index_clear", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "clear", - "cppFunctionName": "Clear", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Clear the contents (all the entries) of an index object.\nThis clears the index object in memory; changes must be manually\nwritten to disk for them to take effect.

\n" - }, - { - "cFunctionName": "git_index_get_byindex", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "n", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position of the entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "entry", - "cppFunctionName": "Entry", - "return": { - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "copy": "git_index_entry_dup", - "comment": "a pointer to the entry; NULL if out of bounds", - "jsClassName": "IndexEntry" - }, - "description": "

Get a pointer to one of the entries in the index

\n" - }, - { - "cFunctionName": "git_index_get_bypath", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to search" - }, - { - "name": "stage", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "stage to search" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getEntry", - "cppFunctionName": "GetEntry", - "return": { - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "copy": "git_index_entry_dup", - "comment": "a pointer to the entry; NULL if it was not found", - "jsClassName": "IndexEntry" - }, - "description": "

Get a pointer to one of the entries in the index

\n" - }, - { - "cFunctionName": "git_index_remove", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to search" - }, - { - "name": "stage", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "stage to search" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "remove", - "cppFunctionName": "Remove", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Remove an entry from the index

\n" - }, - { - "cFunctionName": "git_index_remove_directory", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "dir", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "container directory path" - }, - { - "name": "stage", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "stage to search" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "removeDirectory", - "cppFunctionName": "RemoveDirectory", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Remove all entries from the index under a given directory

\n" - }, - { - "cFunctionName": "git_index_add", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "source_entry", - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "new entry object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "add", - "cppFunctionName": "Add", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add or update an index entry from an in-memory struct

\n" - }, - { - "cFunctionName": "git_index_entry_stage", - "args": [ - { - "name": "entry", - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "The entry" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "entryStage", - "cppFunctionName": "EntryStage", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Return the stage number from a git index entry

\n" - }, - { - "cFunctionName": "git_index_add_bypath", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "filename to add" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addByPath", - "cppFunctionName": "AddBypath", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add or update an index entry from a file on disk

\n" - }, - { - "cFunctionName": "git_index_remove_bypath", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "filename to remove" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "removeByPath", - "cppFunctionName": "RemoveBypath", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Remove an index entry corresponding to a file on disk

\n" - }, - { - "cFunctionName": "git_index_find", - "args": [ - { - "name": "at_pos", - "isReturn": true, - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the address to which the position of the index entry is written (optional)" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to search" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "find", - "cppFunctionName": "Find", - "return": { - "cType": "int", - "cppClassName": "Int32", - "comment": "a zero-based position in the index if found; GIT_ENOTFOUND otherwise", - "jsClassName": "Number" - }, - "description": "

Find the first position of any entries which point to given\npath in the Git index.

\n" - }, - { - "cFunctionName": "git_index_conflict_add", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "ancestor_entry", - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "the entry data for the ancestor of the conflict" - }, - { - "name": "our_entry", - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "the entry data for our side of the merge conflict" - }, - { - "name": "their_entry", - "cType": "const git_index_entry *", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "the entry data for their side of the merge conflict" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "conflictAdd", - "cppFunctionName": "ConflictAdd", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add or update index entries to represent a conflict

\n" - }, - { - "cFunctionName": "git_index_conflict_get", - "args": [ - { - "name": "ancestor_out", - "cType": "git_index_entry **", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "Pointer to store the ancestor entry" - }, - { - "name": "our_out", - "cType": "git_index_entry **", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "Pointer to store the our entry" - }, - { - "name": "their_out", - "cType": "git_index_entry **", - "cppClassName": "GitIndexEntry", - "jsClassName": "IndexEntry", - "comment": "Pointer to store the their entry" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to search" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "conflictGet", - "cppFunctionName": "ConflictGet", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Get the index entries that represent a conflict of a single file.

\n" - }, - { - "cFunctionName": "git_index_conflict_remove", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "to search" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "conflictRemove", - "cppFunctionName": "ConflictRemove", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Removes the index entries that represent a conflict of a single file.

\n" - }, - { - "cFunctionName": "git_index_conflict_cleanup", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "conflictCleanup", - "cppFunctionName": "ConflictCleanup", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Remove all conflicts in the index (entries with a stage greater than 0.)

\n" - }, - { - "cFunctionName": "git_index_has_conflicts", - "args": [ - { - "name": "index", - "cType": "const git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hasConflicts", - "cppFunctionName": "HasConflicts", - "return": { - "cType": "int", - "cppClassName": "Int32", - "comment": "1 if at least one conflict is found, 0 otherwise.", - "jsClassName": "Number" - }, - "description": "

Determine if the index contains entries representing file conflicts.

\n" - }, - { - "cFunctionName": "git_index_reuc_entrycount", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reucEntrycount", - "cppFunctionName": "ReucEntrycount", - "return": { - "cType": "unsigned int", - "cppClassName": "Uint32", - "comment": "integer of count of current resolve undo entries", - "jsClassName": "Number" - }, - "description": "

Get the count of resolve undo entries currently in the index.

\n" - }, - { - "cFunctionName": "git_index_reuc_find", - "args": [ - { - "name": "at_pos", - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the address to which the position of the reuc entry is written (optional)" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to search" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "reucFind", - "cppFunctionName": "ReucFind", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if found, < 0 otherwise (GIT_ENOTFOUND)", - "jsClassName": "Number" - }, - "description": "

Finds the resolve undo entry that points to the given path in the Git\nindex.

\n" - }, - { - "cFunctionName": "git_index_reuc_get_bypath", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to search" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reucGetBypath", - "cppFunctionName": "ReucGetBypath", - "return": { - "cType": "const git_index_reuc_entry *", - "cppClassName": "IndexReucEntry", - "copy": "fixme", - "comment": "the resolve undo entry; NULL if not found" - }, - "description": "

Get a resolve undo entry from the index.

\n" - }, - { - "cFunctionName": "git_index_reuc_get_byindex", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "n", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position of the entry" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reucGetByindex", - "cppFunctionName": "ReucGetByindex", - "return": { - "cType": "const git_index_reuc_entry *", - "cppClassName": "IndexReucEntry", - "copy": "fixme", - "comment": "a pointer to the resolve undo entry; NULL if out of bounds" - }, - "description": "

Get a resolve undo entry from the index.

\n" - }, - { - "cFunctionName": "git_index_reuc_add", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "filename to add" - }, - { - "name": "ancestor_mode", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "mode of the ancestor file" - }, - { - "name": "ancestor_id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid of the ancestor file" - }, - { - "name": "our_mode", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "mode of our file" - }, - { - "name": "our_id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid of our file" - }, - { - "name": "their_mode", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "mode of their file" - }, - { - "name": "their_id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid of their file" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reucAdd", - "cppFunctionName": "ReucAdd", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Adds a resolve undo entry for a file based on the given parameters.

\n" - }, - { - "cFunctionName": "git_index_reuc_remove", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - }, - { - "name": "n", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "position of the resolve undo entry to remove" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reucRemove", - "cppFunctionName": "ReucRemove", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Remove an resolve undo entry from the index

\n" - }, - { - "cFunctionName": "git_index_reuc_clear", - "args": [ - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isSelf": true, - "comment": "an existing index object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reucClear", - "cppFunctionName": "ReucClear", - "return": { - "cType": "void", - "cppClassName": "void", - "comment": "0 or an error code", - "jsClassName": "void" - }, - "description": "

Remove all resolve undo entries from the index

\n" - }, - { - "cFunctionName": "git_diff_index_to_workdir", - "args": [ - { - "name": "diff", - "cType": "git_diff_list **", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isReturn": true, - "comment": "Output pointer to a git_diff_list pointer to be allocated." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository." - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isOptional": true, - "comment": "The index to diff from; repo index used if NULL." - }, - { - "name": "opts", - "cType": "const git_diff_options *", - "cppClassName": "GitDiffOptions", - "jsClassName": "DiffOptions", - "isOptional": true, - "comment": "Structure with options to influence diff or NULL for defaults." - } - ], - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "indexToWorkdir", - "cppFunctionName": "IndexToWorkdir", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create a diff list between the repository index and the workdir directory.

\n" - } - ] - }, - { - "filename": "indexer.h", - "ignore": true, - "jsClassName": "Indexer", - "cppClassName": "Indexer", - "cType": "git_indexer", - "freeFunctionName": "git_indexer_free", - "functions": [ - { - "cFunctionName": "git_indexer_stream_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_indexer_stream **", - "cppClassName": "IndexerStream", - "jsClassName": "IndexerStream", - "comment": "where to store the indexer instance" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "to the directory where the packfile should be stored" - }, - { - "name": "progress_cb", - "cType": "git_transfer_progress_callback", - "cppClassName": "TransferProgressCallback", - "jsClassName": "TransferProgressCallback", - "comment": "function to call with progress information" - }, - { - "name": "progress_cb_payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "payload for the progress callback" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "streamNew", - "cppFunctionName": "StreamNew", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create a new streaming indexer instance

\n" - }, - { - "cFunctionName": "git_indexer_stream_add", - "args": [ - { - "name": "idx", - "cType": "git_indexer_stream *", - "cppClassName": "IndexerStream", - "jsClassName": "IndexerStream", - "comment": "the indexer" - }, - { - "name": "data", - "cType": "const void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "the data to add" - }, - { - "name": "size", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the size of the data in bytes" - }, - { - "name": "stats", - "cType": "git_transfer_progress *", - "cppClassName": "TransferProgress", - "jsClassName": "TransferProgress", - "comment": "stat storage" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "streamAdd", - "cppFunctionName": "StreamAdd", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Add data to the indexer

\n" - }, - { - "cFunctionName": "git_indexer_stream_finalize", - "args": [ - { - "name": "idx", - "cType": "git_indexer_stream *", - "cppClassName": "IndexerStream", - "jsClassName": "IndexerStream", - "comment": "the indexer" - }, - { - "name": "stats", - "cType": "git_transfer_progress *", - "cppClassName": "TransferProgress", - "jsClassName": "TransferProgress" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "streamFinalize", - "cppFunctionName": "StreamFinalize", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Finalize the pack and index

\n" - }, - { - "cFunctionName": "git_indexer_stream_hash", - "args": [ - { - "name": "idx", - "cType": "const git_indexer_stream *", - "cppClassName": "IndexerStream", - "jsClassName": "IndexerStream", - "comment": "the indexer instance" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "streamHash", - "cppFunctionName": "StreamHash", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "jsClassName": "Oid" - }, - "description": "

Get the packfile's hash

\n" - }, - { - "cFunctionName": "git_indexer_stream_free", - "args": [ - { - "name": "idx", - "cType": "git_indexer_stream *", - "cppClassName": "IndexerStream", - "jsClassName": "IndexerStream", - "comment": "the indexer to free" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "streamFree", - "cppFunctionName": "StreamFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the indexer and its resources

\n" - } - ] - }, - { - "filename": "inttypes.h", - "ignore": true, - "jsClassName": "Inttypes", - "cppClassName": "Inttypes", - "cType": "git_inttypes", - "freeFunctionName": "git_inttypes_free", - "functions": [] - }, - { - "filename": "merge.h", - "ignore": true, - "jsClassName": "Merge", - "cppClassName": "Merge", - "cType": "git_merge", - "freeFunctionName": "git_merge_free", - "functions": [ - { - "cFunctionName": "git_merge_base", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "the OID of a merge base between 'one' and 'two'" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository where the commits exist" - }, - { - "name": "one", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "one of the commits" - }, - { - "name": "two", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the other commit" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "base", - "cppFunctionName": "Base", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "Zero on success; GIT_ENOTFOUND or -1 on failure.", - "jsClassName": "Number" - }, - "description": "

Find a merge base between two commits

\n" - }, - { - "cFunctionName": "git_merge_base_many", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "the OID of a merge base considering all the commits" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository where the commits exist" - }, - { - "name": "length", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "The number of commits in the provided `input_array`" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "baseMany", - "cppFunctionName": "BaseMany", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "Zero on success; GIT_ENOTFOUND or -1 on failure.", - "jsClassName": "Number" - }, - "description": "

Find a merge base given a list of commits

\n" - } - ] - }, - { - "filename": "message.h", - "ignore": true, - "jsClassName": "Message", - "cppClassName": "Message", - "cType": "git_message", - "freeFunctionName": "git_message_free", - "functions": [ - { - "cFunctionName": "git_message_prettify", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The user-allocated buffer which will be filled with the cleaned up message. Pass NULL if you just want to get the needed size of the prettified message as the output value." - }, - { - "name": "out_size", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Size of the `out` buffer in bytes." - }, - { - "name": "message", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The message to be prettified." - }, - { - "name": "strip_comments", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Non-zero to remove lines starting with \"#\", 0 to leave them in." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "prettify", - "cppFunctionName": "Prettify", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "-1 on error, else number of characters in prettified message including the trailing NUL byte", - "jsClassName": "Number" - }, - "description": "

Clean up message from excess whitespace and make sure that the last line\nends with a '\\n'.

\n" - } - ] - }, - { - "filename": "net.h", - "ignore": true, - "jsClassName": "Net", - "cppClassName": "Net", - "cType": "git_net", - "freeFunctionName": "git_net_free", - "functions": [] - }, - { - "filename": "notes.h", - "ignore": true, - "jsClassName": "Notes", - "cppClassName": "Notes", - "cType": "git_notes", - "freeFunctionName": "git_notes_free", - "functions": [ - { - "cFunctionName": "git_note_iterator_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_note_iterator **", - "cppClassName": "NoteIterator", - "jsClassName": "NoteIterator", - "comment": "pointer to the iterator" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository where to look up the note" - }, - { - "name": "notes_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "canonical name of the reference to use (optional); defaults to \"refs/notes/commits\"" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteIteratorNew", - "cppFunctionName": "GitNoteIteratorNew", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Creates a new iterator for notes

\n" - }, - { - "cFunctionName": "git_note_iterator_free", - "args": [ - { - "name": "it", - "cType": "git_note_iterator *", - "cppClassName": "NoteIterator", - "jsClassName": "NoteIterator", - "comment": "pointer to the iterator" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "gitNoteIteratorFree", - "cppFunctionName": "GitNoteIteratorFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Frees an git_note_iterator

\n" - }, - { - "cFunctionName": "git_note_next", - "args": [ - { - "name": "note_id", - "cType": "git_oid*", - "cppClassName": "Oid*", - "jsClassName": "Oid*", - "comment": "id of blob containing the message" - }, - { - "name": "annotated_id", - "cType": "git_oid*", - "cppClassName": "Oid*", - "jsClassName": "Oid*", - "comment": "id of the git object being annotated" - }, - { - "name": "it", - "cType": "git_note_iterator *", - "cppClassName": "NoteIterator", - "jsClassName": "NoteIterator", - "comment": "pointer to the iterator" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteNext", - "cppFunctionName": "GitNoteNext", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 (no error), GIT_ITEROVER (iteration is done) or an error code (negative value)", - "jsClassName": "Number" - }, - "description": "

Returns the current item (note_id and annotated_id) and advance the iterator\ninternally to the next value

\n" - }, - { - "cFunctionName": "git_note_read", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_note **", - "cppClassName": "Note", - "jsClassName": "Note", - "comment": "pointer to the read note; NULL in case of error" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository where to look up the note" - }, - { - "name": "notes_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "canonical name of the reference to use (optional); defaults to \"refs/notes/commits\"" - }, - { - "name": "oid", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "OID of the git object to read the note from" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteRead", - "cppFunctionName": "GitNoteRead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Read the note for an object

\n" - }, - { - "cFunctionName": "git_note_message", - "args": [ - { - "name": "note", - "cType": "const git_note *", - "cppClassName": "Note", - "jsClassName": "Note", - "comment": "" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteMessage", - "cppFunctionName": "GitNoteMessage", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the note message", - "jsClassName": "String" - }, - "description": "

Get the note message

\n" - }, - { - "cFunctionName": "git_note_oid", - "args": [ - { - "name": "note", - "cType": "const git_note *", - "cppClassName": "Note", - "jsClassName": "Note", - "comment": "" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteOid", - "cppFunctionName": "GitNoteOid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the note object OID", - "jsClassName": "Oid" - }, - "description": "

Get the note object OID

\n" - }, - { - "cFunctionName": "git_note_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "pointer to store the OID (optional); NULL in case of error" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository where to store the note" - }, - { - "name": "author", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "signature of the notes commit author" - }, - { - "name": "committer", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "signature of the notes commit committer" - }, - { - "name": "notes_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "canonical name of the reference to use (optional); defaults to \"refs/notes/commits\"" - }, - { - "name": "oid", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "OID of the git object to decorate" - }, - { - "name": "note", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "s_ref canonical name of the reference to use (optional); defaults to \"refs/notes/commits\"" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing note" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteCreate", - "cppFunctionName": "GitNoteCreate", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add a note for an object

\n" - }, - { - "cFunctionName": "git_note_remove", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository where the note lives" - }, - { - "name": "notes_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "canonical name of the reference to use (optional); defaults to \"refs/notes/commits\"" - }, - { - "name": "author", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "signature of the notes commit author" - }, - { - "name": "committer", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "signature of the notes commit committer" - }, - { - "name": "oid", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "OID of the git object to remove the note from" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteRemove", - "cppFunctionName": "GitNoteRemove", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Remove the note for an object

\n" - }, - { - "cFunctionName": "git_note_free", - "args": [ - { - "name": "note", - "cType": "git_note *", - "cppClassName": "Note", - "jsClassName": "Note", - "comment": "git_note object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "gitNoteFree", - "cppFunctionName": "GitNoteFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free a git_note object

\n" - }, - { - "cFunctionName": "git_note_default_ref", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "const char **", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Pointer to the default notes reference" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The Git repository" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteDefaultRef", - "cppFunctionName": "GitNoteDefaultRef", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the default notes reference for a repository

\n" - }, - { - "cFunctionName": "git_note_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to find the notes." - }, - { - "name": "notes_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Reference to read from (optional); defaults to \"refs/notes/commits\"." - }, - { - "name": "note_cb", - "cType": "git_note_foreach_cb", - "cppClassName": "NoteForeachCb", - "jsClassName": "NoteForeachCb", - "comment": "Callback to invoke per found annotation. Return non-zero to stop looping." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Extra parameter to callback function." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitNoteForeach", - "cppFunctionName": "GitNoteForeach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Loop over all the notes within a specified namespace\nand issue a callback for each one.

\n" - } - ] - }, - { - "filename": "object.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h" - ], - "jsClassName": "Object", - "cppClassName": "GitObject", - "cType": "git_object", - "freeFunctionName": "git_object_free", - "functions": [ - { - "cFunctionName": "git_object_id", - "args": [ - { - "name": "obj", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isSelf": true, - "comment": "the repository object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the SHA1 id", - "jsClassName": "Oid" - }, - "description": "

Get the id (SHA1) of a repository object

\n" - }, - { - "cFunctionName": "git_object_type", - "args": [ - { - "name": "obj", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isSelf": true, - "comment": "the repository object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "type", - "cppFunctionName": "Type", - "return": { - "cType": "git_otype", - "cppClassName": "Number", - "comment": "the object's type", - "jsClassName": "Number" - }, - "description": "

Get the object type of an object

\n" - }, - { - "cFunctionName": "git_object_owner", - "args": [ - { - "name": "obj", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isSelf": true, - "comment": "the object" - } - ], - "ignore": "Never make public for memory allocation reasons", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "owner", - "cppFunctionName": "Owner", - "return": { - "cType": "git_repository *", - "cppClassName": "GitRepo", - "comment": "the repository who owns this object", - "jsClassName": "Repository" - }, - "description": "

Get the repository that owns this object

\n" - }, - { - "cFunctionName": "git_object_free", - "args": [ - { - "name": "object", - "cType": "git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "the object to close" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open object

\n" - }, - { - "cFunctionName": "git_object_type2string", - "args": [ - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Number", - "jsClassName": "Number", - "comment": "object type to convert." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "type2string", - "cppFunctionName": "Type2string", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the corresponding string representation.", - "jsClassName": "String" - }, - "description": "

Convert an object type to it's string representation.

\n" - }, - { - "cFunctionName": "git_object_string2type", - "args": [ - { - "name": "str", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the string to convert." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "string2type", - "cppFunctionName": "String2type", - "return": { - "cType": "git_otype", - "cppClassName": "Number", - "comment": "the corresponding git_otype.", - "jsClassName": "Number" - }, - "description": "

Convert a string object type representation to it's git_otype.

\n" - }, - { - "cFunctionName": "git_object_typeisloose", - "args": [ - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Number", - "jsClassName": "Number", - "comment": "object type to test." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "typeisloose", - "cppFunctionName": "Typeisloose", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "true if the type represents a valid loose object type, false otherwise.", - "jsClassName": "Number" - }, - "description": "

Determine if the given git_otype is a valid loose object type.

\n" - }, - { - "cFunctionName": "git_object__size", - "args": [ - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "object type to get its size" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "Size", - "cppFunctionName": "Size", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "size in bytes of the object", - "jsClassName": "Number" - }, - "description": "

Get the size in bytes for the structure which\nacts as an in-memory representation of any given\nobject type.

\n" - }, - { - "cFunctionName": "git_object_peel", - "args": [ - { - "name": "peeled", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "Pointer to the peeled git_object" - }, - { - "name": "object", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isSelf": true, - "comment": "The object to be processed" - }, - { - "name": "target_type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "The type of the requested object (GIT_OBJ_COMMIT, GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY)." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "peel", - "cppFunctionName": "Peel", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code", - "jsClassName": "Number" - }, - "description": "

Recursively peel an object until an object of the specified type is met.

\n" - }, - { - "cFunctionName": "git_object_dup", - "args": [ - { - "name": "dest", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "Pointer to store the copy of the object" - }, - { - "name": "source", - "cType": "git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "ignore": true, - "isSelf": true, - "comment": "Original object to copy" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "dup", - "cppFunctionName": "Dup", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create an in-memory copy of a Git object. The copy must be\nexplicitly free'd or it will leak.

\n" - } - ] - }, - { - "filename": "odb.h", - "dependencies": [ - "../include/oid.h", - "../include/odb_object.h", - "node_buffer.h" - ], - "jsClassName": "Odb", - "cppClassName": "GitOdb", - "cType": "git_odb", - "freeFunctionName": "git_odb_free", - "functions": [ - { - "cFunctionName": "git_odb_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb **", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "location to store the database pointer, if opened. Set to NULL if the open failed." - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "create()", - "cppFunctionName": "Create", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new object database with no backends.

\n" - }, - { - "cFunctionName": "git_odb_open", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb **", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "location to store the database pointer, if opened. Set to NULL if the open failed." - }, - { - "name": "objects_dir", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path of the backends' \"objects\" directory." - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "open", - "cppFunctionName": "Open", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new object database and automatically add\nthe two default backends:

\n" - }, - { - "cFunctionName": "git_odb_add_backend", - "args": [ - { - "name": "odb", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to add the backend to" - }, - { - "name": "backend", - "cType": "git_odb_backend *", - "cppClassName": "OdbBackend", - "jsClassName": "OdbBackend", - "comment": "pointer to a git_odb_backend instance" - }, - { - "name": "priority", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Value for ordering the backends queue" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addBackend", - "cppFunctionName": "AddBackend", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Add a custom backend to an existing Object DB

\n" - }, - { - "cFunctionName": "git_odb_add_alternate", - "args": [ - { - "name": "odb", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to add the backend to" - }, - { - "name": "backend", - "cType": "git_odb_backend *", - "cppClassName": "OdbBackend", - "jsClassName": "OdbBackend", - "comment": "pointer to a git_odb_backend instance" - }, - { - "name": "priority", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Value for ordering the backends queue" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addAlternate", - "cppFunctionName": "AddAlternate", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Add a custom backend to an existing Object DB; this\nbackend will work as an alternate.

\n" - }, - { - "cFunctionName": "git_odb_add_disk_alternate", - "args": [ - { - "name": "odb", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to add the backend to" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "path to the objects folder for the alternate" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addDiskAlternate", - "cppFunctionName": "AddDiskAlternate", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Add an on-disk alternate to an existing Object DB.

\n" - }, - { - "cFunctionName": "git_odb_free", - "args": [ - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "database pointer to close. If NULL no action is taken." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open object database.

\n" - }, - { - "cFunctionName": "git_odb_read", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb_object **", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "comment": "pointer where to store the read object" - }, - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to search for the object in." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the object to read." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "read", - "cppFunctionName": "Read", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "- 0 if the object was read; - GIT_ENOTFOUND if the object is not in the database.", - "jsClassName": "Number" - }, - "description": "

Read an object from the database.

\n" - }, - { - "cFunctionName": "git_odb_read_prefix", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb_object **", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "comment": "pointer where to store the read object" - }, - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "database to search for the object in." - }, - { - "name": "short_id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "a prefix of the id of the object to read." - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the length of the prefix" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "readPrefix", - "cppFunctionName": "ReadPrefix", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "- 0 if the object was read; - GIT_ENOTFOUND if the object is not in the database. - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)", - "jsClassName": "Number" - }, - "description": "

Read an object from the database, given a prefix\nof its identifier.

\n" - }, - { - "cFunctionName": "git_odb_read_header", - "args": [ - { - "name": "len_out", - "isReturn": true, - "cType": "size_t *", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "pointer where to store the length" - }, - { - "name": "type_out", - "isReturn": true, - "cType": "git_otype *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "pointer where to store the type" - }, - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "database to search for the object in." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the object to read." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "readHeader", - "cppFunctionName": "ReadHeader", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "- 0 if the object was read; - GIT_ENOTFOUND if the object is not in the database.", - "jsClassName": "Number" - }, - "description": "

Read the header of an object from the database, without\nreading its full contents.

\n" - }, - { - "cFunctionName": "git_odb_exists", - "args": [ - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to be searched for the given object." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the object to search for." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "exists", - "cppFunctionName": "Exists", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "- 1, if the object was found - 0, otherwise", - "jsClassName": "Number" - }, - "description": "

Determine if the given object can be found in the object database.

\n" - }, - { - "cFunctionName": "git_odb_refresh", - "args": [ - { - "name": "db", - "cType": "struct git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to refresh" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "refresh", - "cppFunctionName": "Refresh", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, error code otherwise", - "jsClassName": "Number" - }, - "description": "

Refresh the object database to load newly added files.

\n" - }, - { - "cFunctionName": "git_odb_foreach", - "args": [ - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "database to use" - }, - { - "name": "cb", - "cType": "git_odb_foreach_cb", - "cppClassName": "OdbForeachCb", - "jsClassName": "OdbForeachCb", - "comment": "the callback to call for each object" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "data to pass to the callback" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

List all objects available in the database

\n" - }, - { - "cFunctionName": "git_odb_write", - "args": [ - { - "name": "out", - "isReturn": true, - "shouldAlloc": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "pointer to store the OID result of the write" - }, - { - "name": "odb", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "isSelf": true, - "comment": "object database where to store the object" - }, - { - "name": "data", - "cType": "const void *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "buffer with the data to store" - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "size of the buffer" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "type of the data to store" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "write", - "cppFunctionName": "Write", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Write an object directly into the ODB

\n" - }, - { - "cFunctionName": "git_odb_open_wstream", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb_stream **", - "cppClassName": "GitOdbStream", - "jsClassName": "OdbStream", - "comment": "pointer where to store the stream" - }, - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "object database where the stream will write" - }, - { - "name": "size", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "final size of the object that will be written" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "type of the object that will be written" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "openWstream", - "cppFunctionName": "OpenWstream", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if the stream was created; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Open a stream to write an object into the ODB

\n" - }, - { - "cFunctionName": "git_odb_open_rstream", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb_stream **", - "cppClassName": "GitOdbStream", - "jsClassName": "OdbStream", - "comment": "pointer where to store the stream" - }, - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "object database where the stream will read from" - }, - { - "name": "oid", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid of the object the stream will read from" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "openRstream", - "cppFunctionName": "OpenRstream", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if the stream was created; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Open a stream to read an object from the ODB

\n" - }, - { - "cFunctionName": "git_odb_write_pack", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb_writepack **", - "cppClassName": "OdbWritepack", - "jsClassName": "OdbWritepack", - "comment": "pointer to the writepack functions" - }, - { - "name": "db", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "object database where the stream will read from" - }, - { - "name": "progress_cb", - "cType": "git_transfer_progress_callback", - "cppClassName": "TransferProgressCallback", - "jsClassName": "TransferProgressCallback", - "comment": "function to call with progress information. Be aware that this is called inline with network and indexing operations, so performance may be affected." - }, - { - "name": "progress_payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "payload for the progress callback" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "writePack", - "cppFunctionName": "WritePack", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Open a stream for writing a pack file to the ODB.

\n" - }, - { - "cFunctionName": "git_odb_hash", - "args": [ - { - "name": "out", - "isReturn": true, - "shouldAlloc": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the resulting object-ID." - }, - { - "name": "data", - "cType": "const void *", - "cppClassName": "Buffer", - "jsClassName": "Buffer", - "comment": "data to hash" - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "size of the data" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "of the data to hash" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "hash", - "cppFunctionName": "Hash", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Determine the object-ID (sha1 hash) of a data buffer

\n" - }, - { - "cFunctionName": "git_odb_hashfile", - "args": [ - { - "name": "out", - "isReturn": true, - "shouldAlloc": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid structure the result is written into." - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "file to read and determine object id for" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "the type of the object that will be hashed" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "hashfile", - "cppFunctionName": "Hashfile", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Read a file from disk and fill a git_oid with the object id\nthat the file would have if it were written to the Object\nDatabase as an object of the given type (w/o applying filters).\nSimilar functionality to git.git's git hash-object without\nthe -w flag, however, with the --no-filters flag.\nIf you need filters, see git_repository_hashfile.

\n" - } - ] - }, - { - "filename": "odb_object.h", - "dependencies": [ - "../include/wrapper.h", - "../include/oid.h" - ], - "jsClassName": "OdbObject", - "cppClassName": "GitOdbObject", - "cType": "git_odb_object", - "freeFunctionName": "git_odb_object_free", - "functions": [ - { - "cFunctionName": "git_odb_object_data", - "args": [ - { - "name": "object", - "cType": "git_odb_object *", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "isSelf": true, - "comment": "the object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "data", - "cppFunctionName": "Data", - "return": { - "cType": "const void *", - "cppClassName": "Wrapper", - "comment": "a pointer to the data" - }, - "description": "

Return the data of an ODB object

\n" - }, - { - "cFunctionName": "git_odb_object_size", - "args": [ - { - "name": "object", - "cType": "git_odb_object *", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "isSelf": true, - "comment": "the object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "the size", - "jsClassName": "Number" - }, - "description": "

Return the size of an ODB object

\n" - }, - { - "cFunctionName": "git_odb_object_type", - "args": [ - { - "name": "object", - "cType": "git_odb_object *", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "isSelf": true, - "comment": "the object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "type", - "cppFunctionName": "Type", - "return": { - "cType": "git_otype", - "cppClassName": "Int32", - "comment": "the type", - "jsClassName": "Number" - }, - "description": "

Return the type of an ODB object

\n" - }, - { - "cFunctionName": "git_odb_object_free", - "args": [ - { - "name": "object", - "cType": "git_odb_object *", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "isSelf": true, - "comment": "object to close" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an ODB object

\n" - }, - { - "cFunctionName": "git_odb_object_id", - "args": [ - { - "name": "object", - "cType": "git_odb_object *", - "cppClassName": "GitOdbObject", - "jsClassName": "OdbObject", - "isSelf": true, - "comment": "the object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "a pointer to the OID", - "jsClassName": "Oid" - }, - "description": "

Return the OID of an ODB object

\n" - } - ] - }, - { - "filename": "odb_backend.h", - "ignore": true, - "jsClassName": "OdbBackend", - "cppClassName": "OdbBackend", - "cType": "git_odb_backend", - "freeFunctionName": "git_odb_backend_free", - "functions": [ - { - "cFunctionName": "git_odb_backend_pack", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb_backend **", - "cppClassName": "OdbBackend", - "jsClassName": "OdbBackend", - "comment": "location to store the odb backend pointer" - }, - { - "name": "objects_dir", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the Git repository's objects directory" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "pack", - "cppFunctionName": "Pack", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a backend for the packfiles.

\n" - } - ] - }, - { - "filename": "oid.h", - "dependencies": [], - "jsClassName": "Oid", - "cppClassName": "GitOid", - "cType": "git_oid", - "freeFunctionName": "free", - "functions": [ - { - "cFunctionName": "git_oid_fromstr", - "args": [ - { - "name": "out", - "isReturn": true, - "shouldAlloc": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid structure the result is written into." - }, - { - "name": "str", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "input hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes)." - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "fromString", - "cppFunctionName": "FromString", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Parse a hex formatted object id into a git_oid.

\n" - }, - { - "cFunctionName": "git_oid_fromstrp", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "oid structure the result is written into." - }, - { - "name": "str", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "input hex string; must be at least 4 characters long and null-terminated." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "fromstrp", - "cppFunctionName": "Fromstrp", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Parse a hex formatted null-terminated string into a git_oid.

\n" - }, - { - "cFunctionName": "git_oid_fromstrn", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "oid structure the result is written into." - }, - { - "name": "str", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "input hex string of at least size `length`" - }, - { - "name": "length", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "length of the input string" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "fromstrn", - "cppFunctionName": "Fromstrn", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Parse N characters of a hex formatted object id into a git_oid

\n" - }, - { - "cFunctionName": "git_oid_fromraw", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "oid structure the result is written into." - }, - { - "name": "raw", - "cType": "const unsigned char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the raw input bytes to be copied." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "fromraw", - "cppFunctionName": "Fromraw", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Copy an already raw oid into a git_oid structure.

\n" - }, - { - "cFunctionName": "git_oid_fmt", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "output hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes). Only the oid digits are written; a '\\\\0' terminator must be added by the caller if it is required." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "oid structure to format." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "fmt", - "cppFunctionName": "Fmt", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Format a git_oid into a hex string.

\n" - }, - { - "cFunctionName": "git_oid_pathfmt", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "output hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (41 bytes). Only the oid digits are written; a '\\\\0' terminator must be added by the caller if it is required." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "oid structure to format." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "pathfmt", - "cppFunctionName": "Pathfmt", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Format a git_oid into a loose-object path string.

\n" - }, - { - "cFunctionName": "git_oid_allocfmt", - "args": [ - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "the oid structure to format" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "sha", - "cppFunctionName": "Sha", - "return": { - "cType": "char *", - "cppClassName": "String", - "comment": "the c-string; NULL if memory is exhausted. Caller must deallocate the string with git__free().", - "jsClassName": "String", - "freeFunctionName": "free" - }, - "description": "

Format a git_oid into a newly allocated c-string.

\n" - }, - { - "cFunctionName": "git_oid_tostr", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the buffer into which the oid string is output." - }, - { - "name": "n", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the size of the out buffer." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the oid structure to format." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "sha", - "cppFunctionName": "Sha", - "return": { - "cType": "char *", - "cppClassName": "String", - "comment": "the out buffer pointer, assuming no input parameter errors, otherwise a pointer to an empty string.", - "jsClassName": "String" - }, - "description": "

Format a git_oid into a buffer as a hex format c-string.

\n" - }, - { - "cFunctionName": "git_oid_cpy", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "oid structure the result is written into." - }, - { - "name": "src", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "oid structure to copy from." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "cpy", - "cppFunctionName": "Cpy", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Copy an oid from one structure to another.

\n" - }, - { - "cFunctionName": "git_oid_cmp", - "args": [ - { - "name": "a", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "first oid structure." - }, - { - "name": "b", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "second oid structure." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "cmp", - "cppFunctionName": "Cmp", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "<0, 0, >0 if a < b, a == b, a > b.", - "jsClassName": "Number" - }, - "description": "

Compare two oid structures.

\n" - }, - { - "cFunctionName": "git_oid_equal", - "args": [ - { - "name": "a", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "first oid structure." - }, - { - "name": "b", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "second oid structure." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "equal", - "cppFunctionName": "Equal", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "true if equal, false otherwise", - "jsClassName": "Number" - }, - "description": "

Compare two oid structures for equality

\n" - }, - { - "cFunctionName": "git_oid_ncmp", - "args": [ - { - "name": "a", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "first oid structure." - }, - { - "name": "b", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "second oid structure." - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the number of hex chars to compare" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "ncmp", - "cppFunctionName": "Ncmp", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 in case of a match", - "jsClassName": "Number" - }, - "description": "

Compare the first 'len' hexadecimal characters (packets of 4 bits)\nof two oid structures.

\n" - }, - { - "cFunctionName": "git_oid_streq", - "args": [ - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true, - "comment": "oid structure." - }, - { - "name": "str", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "input hex string of an object id." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "streq", - "cppFunctionName": "Streq", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "GIT_ENOTOID if str is not a valid hex string, 0 in case of a match, GIT_ERROR otherwise.", - "jsClassName": "Number" - }, - "description": "

Check if an oid equals an hex formatted object id.

\n" - }, - { - "cFunctionName": "git_oid_iszero", - "args": [ - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "iszero", - "cppFunctionName": "Iszero", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if all zeros, 0 otherwise.", - "jsClassName": "Number" - }, - "description": "

Check is an oid is all zeros.

\n" - }, - { - "cFunctionName": "git_oid_shorten_new", - "args": [ - { - "name": "min_length", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "The minimal length for all identifiers, which will be used even if shorter OIDs would still be unique." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "shortenNew", - "cppFunctionName": "ShortenNew", - "return": { - "cType": "git_oid_shorten *", - "cppClassName": "OidShorten", - "copy": "fixme", - "comment": "a `git_oid_shorten` instance, NULL if OOM", - "jsClassName": "OidShorten" - }, - "description": "

Create a new OID shortener.

\n" - }, - { - "cFunctionName": "git_oid_shorten_add", - "args": [ - { - "name": "os", - "cType": "git_oid_shorten *", - "cppClassName": "OidShorten", - "jsClassName": "OidShorten", - "comment": "a `git_oid_shorten` instance" - }, - { - "name": "text_id", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "an OID in text form" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "shortenAdd", - "cppFunctionName": "ShortenAdd", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "the minimal length to uniquely identify all OIDs added so far to the set; or an error code (<0) if an error occurs.", - "jsClassName": "Number" - }, - "description": "

Add a new OID to set of shortened OIDs and calculate\nthe minimal length to uniquely identify all the OIDs in\nthe set.

\n" - }, - { - "cFunctionName": "git_oid_shorten_free", - "args": [ - { - "name": "os", - "cType": "git_oid_shorten *", - "cppClassName": "OidShorten", - "jsClassName": "OidShorten", - "comment": "a `git_oid_shorten` instance" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "shortenFree", - "cppFunctionName": "ShortenFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free an OID shortener instance

\n" - } - ] - }, - { - "filename": "pack.h", - "ignore": true, - "jsClassName": "Pack", - "cppClassName": "Pack", - "cType": "git_pack", - "freeFunctionName": "git_pack_free", - "functions": [ - { - "cFunctionName": "git_packbuilder_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_packbuilder **", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "The new packbuilder object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderNew", - "cppFunctionName": "GitPackbuilderNew", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Initialize a new packbuilder

\n" - }, - { - "cFunctionName": "git_packbuilder_set_threads", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "The packbuilder" - }, - { - "name": "n", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Number of threads to spawn" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderSetThreads", - "cppFunctionName": "GitPackbuilderSetThreads", - "return": { - "cType": "unsigned int", - "cppClassName": "Uint32", - "comment": "number of actual threads to be used", - "jsClassName": "Number" - }, - "description": "

Set number of threads to spawn

\n" - }, - { - "cFunctionName": "git_packbuilder_insert", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "The packbuilder" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "The oid of the commit" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The name; might be NULL" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderInsert", - "cppFunctionName": "GitPackbuilderInsert", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Insert a single object

\n" - }, - { - "cFunctionName": "git_packbuilder_insert_tree", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "The packbuilder" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "The oid of the root tree" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderInsertTree", - "cppFunctionName": "GitPackbuilderInsertTree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Insert a root tree object

\n" - }, - { - "cFunctionName": "git_packbuilder_write", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "The packbuilder" - }, - { - "name": "file", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderWrite", - "cppFunctionName": "GitPackbuilderWrite", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Write the new pack and corresponding index file to path.

\n" - }, - { - "cFunctionName": "git_packbuilder_foreach", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "the packbuilder" - }, - { - "name": "cb", - "cType": "git_packbuilder_foreach_cb", - "cppClassName": "PackbuilderForeachCb", - "jsClassName": "PackbuilderForeachCb", - "comment": "the callback to call with each packed object's buffer" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "the callback's data" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderForeach", - "cppFunctionName": "GitPackbuilderForeach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create the new pack and pass each object to the callback

\n" - }, - { - "cFunctionName": "git_packbuilder_object_count", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "the packbuilder" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderObjectCount", - "cppFunctionName": "GitPackbuilderObjectCount", - "return": { - "cType": "uint32_t", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - "description": "

Get the total number of objects the packbuilder will write out

\n" - }, - { - "cFunctionName": "git_packbuilder_written", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "the packbuilder" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitPackbuilderWritten", - "cppFunctionName": "GitPackbuilderWritten", - "return": { - "cType": "uint32_t", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - "description": "

Get the number of objects the packbuilder has already written out

\n" - }, - { - "cFunctionName": "git_packbuilder_free", - "args": [ - { - "name": "pb", - "cType": "git_packbuilder *", - "cppClassName": "Packbuilder", - "jsClassName": "Packbuilder", - "comment": "The packbuilder" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "gitPackbuilderFree", - "cppFunctionName": "GitPackbuilderFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the packbuilder and all associated data

\n" - } - ] - }, - { - "filename": "push.h", - "ignore": true, - "jsClassName": "Push", - "cppClassName": "Push", - "cType": "git_push", - "freeFunctionName": "git_push_free", - "functions": [ - { - "cFunctionName": "git_push_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_push **", - "cppClassName": "Push", - "jsClassName": "Push", - "comment": "New push object" - }, - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "Remote instance" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "new", - "cppFunctionName": "New", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new push object

\n" - }, - { - "cFunctionName": "git_push_set_options", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "isSelf": true, - "comment": "The push object" - }, - { - "name": "opts", - "cType": "const git_push_options *", - "cppClassName": "PushOptions", - "jsClassName": "PushOptions", - "comment": "The options to set on the push object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setOptions", - "cppFunctionName": "SetOptions", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Set options on a push object

\n" - }, - { - "cFunctionName": "git_push_add_refspec", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "isSelf": true, - "comment": "The push object" - }, - { - "name": "refspec", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Refspec string" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addRefspec", - "cppFunctionName": "AddRefspec", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add a refspec to be pushed

\n" - }, - { - "cFunctionName": "git_push_update_tips", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "isSelf": true, - "comment": "The push object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "updateTips", - "cppFunctionName": "UpdateTips", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Update remote tips after a push

\n" - }, - { - "cFunctionName": "git_push_finish", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "isSelf": true, - "comment": "The push object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "finish", - "cppFunctionName": "Finish", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Actually push all given refspecs

\n" - }, - { - "cFunctionName": "git_push_unpack_ok", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "isSelf": true, - "comment": "The push object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "unpackOk", - "cppFunctionName": "UnpackOk", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "true if equal, false otherwise", - "jsClassName": "Number" - }, - "description": "

Check if remote side successfully unpacked

\n" - }, - { - "cFunctionName": "git_push_status_foreach", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "isSelf": true, - "comment": "The push object" - }, - { - "name": "cb", - "cType": "int (*)(const char *ref, const char *msg, void *data)", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "The callback to call on each object" - }, - { - "name": "data", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "statusForeach", - "cppFunctionName": "StatusForeach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Call callback `cb' on each status

\n" - }, - { - "cFunctionName": "git_push_free", - "args": [ - { - "name": "push", - "cType": "git_push *", - "cppClassName": "Push", - "jsClassName": "Push", - "comment": "The push object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the given push object

\n" - } - ] - }, - { - "filename": "refdb.h", - "jsClassName": "RefDb", - "cppClassName": "GitRefDb", - "cType": "git_refdb", - "note": "this should be git_refdb_free, but it's not available", - "freeFunctionName": "free", - "functions": [ - { - "cFunctionName": "git_reference__alloc", - "args": [ - { - "name": "refdb", - "cType": "git_refdb *", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "isSelf": true - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "name": "oid", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid" - }, - { - "name": "symbolic", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "gitReference_Alloc", - "cppFunctionName": "GitReference_Alloc", - "return": { - "cType": "git_reference *", - "cppClassName": "GitReference", - "copy": "fixme", - "comment": "the created git_reference or NULL on error", - "jsClassName": "Reference" - }, - "description": "

Create a new direct reference from an OID.

\n" - }, - { - "cFunctionName": "git_refdb_compress", - "args": [ - { - "name": "refdb", - "cType": "git_refdb *", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "isSelf": true - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "compress", - "cppFunctionName": "Compress", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Suggests that the given refdb compress or optimize its references.\nThis mechanism is implementation specific. For on-disk reference\ndatabases, for example, this may pack all loose references.

\n" - }, - { - "cFunctionName": "git_refdb_free", - "args": [ - { - "name": "refdb", - "cType": "git_refdb *", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "comment": "reference database pointer or NULL" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open reference database.

\n" - }, - { - "cFunctionName": "git_refdb_set_backend", - "args": [ - { - "name": "refdb", - "cType": "git_refdb *", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "isSelf": true, - "comment": "database to add the backend to" - }, - { - "name": "backend", - "cType": "git_refdb_backend *", - "cppClassName": "RefdbBackend", - "jsClassName": "RefdbBackend", - "comment": "pointer to a git_refdb_backend instance" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setBackend", - "cppFunctionName": "SetBackend", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Sets the custom backend to an existing reference DB

\n" - } - ] - }, - { - "filename": "refdb_backend.h", - "ignore": true, - "jsClassName": "RefdbBackend", - "cppClassName": "RefdbBackend", - "cType": "git_refdb_backend", - "freeFunctionName": "git_refdb_backend_free", - "functions": [] - }, - { - "filename": "reflog.h", - "ignore": true, - "jsClassName": "Reflog", - "cppClassName": "Reflog", - "cType": "git_reflog", - "freeFunctionName": "git_reflog_free", - "functions": [ - { - "cFunctionName": "git_reflog_read", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reflog **", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "comment": "pointer to reflog" - }, - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "reference to read the reflog for" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "read", - "cppFunctionName": "Read", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Read the reflog for the given reference

\n" - }, - { - "cFunctionName": "git_reflog_write", - "args": [ - { - "name": "reflog", - "cType": "git_reflog *", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "isSelf": true, - "comment": "an existing reflog object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "write", - "cppFunctionName": "Write", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Write an existing in-memory reflog object back to disk\nusing an atomic file lock.

\n" - }, - { - "cFunctionName": "git_reflog_append", - "args": [ - { - "name": "reflog", - "cType": "git_reflog *", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "isSelf": true, - "comment": "an existing reflog object" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the OID the reference is now pointing to" - }, - { - "name": "committer", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "the signature of the committer" - }, - { - "name": "msg", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the reflog message" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "append", - "cppFunctionName": "Append", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add a new entry to the reflog.

\n" - }, - { - "cFunctionName": "git_reflog_rename", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "the reference" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the new name of the reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "rename", - "cppFunctionName": "Rename", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Rename the reflog for the given reference

\n" - }, - { - "cFunctionName": "git_reflog_delete", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "the reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "delete", - "cppFunctionName": "Delete", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Delete the reflog for the given reference

\n" - }, - { - "cFunctionName": "git_reflog_entrycount", - "args": [ - { - "name": "reflog", - "cType": "git_reflog *", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "isSelf": true, - "comment": "the previously loaded reflog" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "entrycount", - "cppFunctionName": "Entrycount", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "the number of log entries", - "jsClassName": "Number" - }, - "description": "

Get the number of log entries in a reflog

\n" - }, - { - "cFunctionName": "git_reflog_entry_byindex", - "args": [ - { - "name": "reflog", - "cType": "git_reflog *", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "isSelf": true, - "comment": "a previously loaded reflog" - }, - { - "name": "idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position of the entry to lookup. Should be greater than or equal to 0 (zero) and less than `git_reflog_entrycount()`." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "entryByindex", - "cppFunctionName": "EntryByindex", - "return": { - "cType": "const git_reflog_entry *", - "cppClassName": "ReflogEntry", - "copy": "fixme", - "comment": "the entry; NULL if not found", - "jsClassName": "ReflogEntry" - }, - "description": "

Lookup an entry by its index

\n" - }, - { - "cFunctionName": "git_reflog_drop", - "args": [ - { - "name": "reflog", - "cType": "git_reflog *", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "isSelf": true, - "comment": "a previously loaded reflog." - }, - { - "name": "idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position of the entry to remove. Should be greater than or equal to 0 (zero) and less than `git_reflog_entrycount()`." - }, - { - "name": "rewrite_previous_entry", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "1 to rewrite the history; 0 otherwise." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "drop", - "cppFunctionName": "Drop", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND if the entry doesn't exist or an error code.", - "jsClassName": "Number" - }, - "description": "

Remove an entry from the reflog by its index

\n" - }, - { - "cFunctionName": "git_reflog_entry_id_old", - "args": [ - { - "name": "entry", - "cType": "const git_reflog_entry *", - "cppClassName": "ReflogEntry", - "jsClassName": "ReflogEntry", - "comment": "a reflog entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "entryIdOld", - "cppFunctionName": "EntryIdOld", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the old oid", - "jsClassName": "Oid" - }, - "description": "

Get the old oid

\n" - }, - { - "cFunctionName": "git_reflog_entry_id_new", - "args": [ - { - "name": "entry", - "cType": "const git_reflog_entry *", - "cppClassName": "ReflogEntry", - "jsClassName": "ReflogEntry", - "comment": "a reflog entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "entryIdNew", - "cppFunctionName": "EntryIdNew", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the new oid at this time", - "jsClassName": "Oid" - }, - "description": "

Get the new oid

\n" - }, - { - "cFunctionName": "git_reflog_entry_committer", - "args": [ - { - "name": "entry", - "cType": "const git_reflog_entry *", - "cppClassName": "ReflogEntry", - "jsClassName": "ReflogEntry", - "comment": "a reflog entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "entryCommitter", - "cppFunctionName": "EntryCommitter", - "return": { - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "copy": "git_signature_dup", - "comment": "the committer", - "jsClassName": "Signature" - }, - "description": "

Get the committer of this entry

\n" - }, - { - "cFunctionName": "git_reflog_entry_message", - "args": [ - { - "name": "entry", - "cType": "const git_reflog_entry *", - "cppClassName": "ReflogEntry", - "jsClassName": "ReflogEntry", - "comment": "a reflog entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "entryMessage", - "cppFunctionName": "EntryMessage", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the log msg", - "jsClassName": "String" - }, - "description": "

Get the log message

\n" - }, - { - "cFunctionName": "git_reflog_free", - "args": [ - { - "name": "reflog", - "cType": "git_reflog *", - "cppClassName": "Reflog", - "jsClassName": "Reflog", - "comment": "reflog to free" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the reflog

\n" - } - ] - }, - { - "filename": "reference.h", - "dependencies": [ - "../include/repo.h", - "../include/oid.h", - "../include/object.h" - ], - "jsClassName": "Reference", - "cppClassName": "GitReference", - "cType": "git_reference", - "freeFunctionName": "git_reference_free", - "functions": [ - { - "cFunctionName": "git_reference_name_to_id", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "Pointer to oid to be filled in" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository in which to look up the reference" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "oidForName", - "cppFunctionName": "OidForName", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, ENOTFOUND, EINVALIDSPEC or an error code.", - "jsClassName": "Number" - }, - "description": "

Lookup a reference by name and resolve immediately to OID.

\n" - }, - { - "cFunctionName": "git_reference_target", - "args": [ - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "target", - "cppFunctionName": "Target", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "a pointer to the oid if available, NULL otherwise", - "jsClassName": "Oid" - }, - "description": "

Get the OID pointed to by a direct reference.

\n" - }, - { - "cFunctionName": "git_reference_symbolic_target", - "args": [ - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "symbolicTarget", - "cppFunctionName": "SymbolicTarget", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "a pointer to the name if available, NULL otherwise", - "jsClassName": "String" - }, - "description": "

Get full name to the reference pointed to by a symbolic reference.

\n" - }, - { - "cFunctionName": "git_reference_type", - "args": [ - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "type", - "cppFunctionName": "Type", - "return": { - "cType": "git_ref_t", - "cppClassName": "Number", - "comment": "the type", - "jsClassName": "Number" - }, - "description": "

Get the type of a reference.

\n" - }, - { - "cFunctionName": "git_reference_name", - "args": [ - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "name", - "cppFunctionName": "Name", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the full name for the ref", - "jsClassName": "String" - }, - "description": "

Get the full name of a reference.

\n" - }, - { - "cFunctionName": "git_reference_resolve", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer to the peeled reference" - }, - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "resolve", - "cppFunctionName": "Resolve", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Resolve a symbolic reference to a direct reference.

\n" - }, - { - "cFunctionName": "git_reference_owner", - "args": [ - { - "name": "ref", - "cType": "const git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - } - ], - "ignore": "Never make public for memory allocation reasons", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "owner", - "cppFunctionName": "owner", - "return": { - "cType": "git_repository *", - "cppClassName": "GitRepo", - "comment": "a pointer to the repo", - "jsClassName": "Repository" - }, - "description": "

Get the repository where a reference resides.

\n" - }, - { - "cFunctionName": "git_reference_symbolic_set_target", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer to the newly created reference" - }, - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - }, - { - "name": "target", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The new target for the reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setSymbolicTarget", - "cppFunctionName": "SetSymbolicTarget", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new reference with the same name as the given reference but a\ndifferent symbolic target. The reference must be a symbolic reference,\notherwise this will fail.

\n" - }, - { - "cFunctionName": "git_reference_set_target", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer to the newly created reference" - }, - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "The new target OID for the reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setTarget", - "cppFunctionName": "setTarget", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new reference with the same name as the given reference but a\ndifferent OID target. The reference must be a direct reference, otherwise\nthis will fail.

\n" - }, - { - "cFunctionName": "git_reference_rename", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference" - }, - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference to rename" - }, - { - "name": "new_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The new name for the reference" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite an existing reference" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "rename", - "cppFunctionName": "Rename", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, EINVALIDSPEC, EEXISTS or an error code", - "jsClassName": "Number" - }, - "description": "

Rename an existing reference.

\n" - }, - { - "cFunctionName": "git_reference_delete", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference to remove" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "delete", - "cppFunctionName": "Delete", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Delete an existing reference.

\n" - }, - { - "cFunctionName": "git_reference_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to find the refs" - }, - { - "name": "list_flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "name": "callback", - "cType": "git_reference_foreach_cb", - "cppClassName": "ReferenceForeachCb", - "jsClassName": "ReferenceForeachCb" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Perform a callback on each reference in the repository.

\n" - }, - { - "cFunctionName": "git_reference_free", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "git_reference" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "gitReferenceFree", - "cppFunctionName": "GitReferenceFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the given reference.

\n" - }, - { - "cFunctionName": "git_reference_cmp", - "args": [ - { - "name": "ref1", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The first git_reference" - }, - { - "name": "ref2", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "The second git_reference" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "compare", - "cppFunctionName": "Compare", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if the same, else a stable but meaningless ordering.", - "jsClassName": "Number" - }, - "description": "

Compare two references.

\n" - }, - { - "cFunctionName": "git_reference_foreach_glob", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to find the refs" - }, - { - "name": "glob", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Pattern to match (fnmatch-style) against reference name." - }, - { - "name": "list_flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number" - }, - { - "name": "callback", - "cType": "git_reference_foreach_cb", - "cppClassName": "ReferenceForeachCb", - "jsClassName": "ReferenceForeachCb" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreachGlob", - "cppFunctionName": "ForeachGlob", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Perform a callback on each reference in the repository whose name\nmatches the given pattern.

\n" - }, - { - "cFunctionName": "git_reference_has_log", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "A git reference" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hasLog", - "cppFunctionName": "HasLog", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 when no reflog can be found, 1 when it exists; otherwise an error code.", - "jsClassName": "Number" - }, - "description": "

Check if a reflog exists for the specified reference.

\n" - }, - { - "cFunctionName": "git_reference_is_branch", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "A git reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "isBranch", - "cppFunctionName": "IsBranch", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 when the reference lives in the refs/heads namespace; 0 otherwise.", - "jsClassName": "Number" - }, - "description": "

Check if a reference is a local branch.

\n" - }, - { - "cFunctionName": "git_reference_is_remote", - "args": [ - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "A git reference" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "isRemote", - "cppFunctionName": "IsRemote", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 when the reference lives in the refs/remotes namespace; 0 otherwise.", - "jsClassName": "Number" - }, - "description": "

Check if a reference is a remote tracking branch

\n" - }, - { - "cFunctionName": "git_reference_normalize_name", - "args": [ - { - "name": "buffer_out", - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "isSelf": true, - "comment": "User allocated buffer to store normalized name" - }, - { - "name": "buffer_size", - "cType": "size_t", - "cppClassName": "Integer", - "jsClassName": "Number", - "comment": "Size of buffer_out" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Reference name to be checked." - }, - { - "name": "flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Flags to constrain name validation rules - see the GIT_REF_FORMAT constants above." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "normalizeName", - "cppFunctionName": "NormalizeName", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EBUFS if buffer is too small, EINVALIDSPEC or an error code.", - "jsClassName": "Number" - }, - "description": "

Normalize reference name and check validity.

\n" - }, - { - "cFunctionName": "git_reference_peel", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "Pointer to the peeled git_object" - }, - { - "name": "ref", - "cType": "git_reference *", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "isSelf": true, - "comment": "The reference to be processed" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "The type of the requested object (GIT_OBJ_COMMIT, GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY)." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "peel", - "cppFunctionName": "Peel", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code", - "jsClassName": "Number" - }, - "description": "

Recursively peel reference until object of the specified type is found.

\n" - }, - { - "cFunctionName": "git_reference_is_valid_name", - "args": [ - { - "name": "refname", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name to be checked." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "isValidName", - "cppFunctionName": "IsValidName", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if the reference name is acceptable; 0 if it isn't", - "jsClassName": "Number" - }, - "description": "

Ensure the reference name is well-formed.

\n" - } - ] - }, - { - "filename": "refspec.h", - "ignore": true, - "jsClassName": "Refspec", - "cppClassName": "Refspec", - "cType": "git_refspec", - "freeFunctionName": "git_refspec_free", - "functions": [ - { - "cFunctionName": "git_refspec_src", - "args": [ - { - "name": "refspec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "isSelf": true, - "comment": "the refspec" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "src", - "cppFunctionName": "Src", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the refspec's source specifier", - "jsClassName": "String" - }, - "description": "

Get the source specifier

\n" - }, - { - "cFunctionName": "git_refspec_dst", - "args": [ - { - "name": "refspec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "isSelf": true, - "comment": "the refspec" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "dst", - "cppFunctionName": "Dst", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the refspec's destination specifier", - "jsClassName": "String" - }, - "description": "

Get the destination specifier

\n" - }, - { - "cFunctionName": "git_refspec_force", - "args": [ - { - "name": "refspec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "isSelf": true, - "comment": "the refspec" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "force", - "cppFunctionName": "Force", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if force update has been set, 0 otherwise", - "jsClassName": "Number" - }, - "description": "

Get the force update setting

\n" - }, - { - "cFunctionName": "git_refspec_src_matches", - "args": [ - { - "name": "refspec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "isSelf": true, - "comment": "the refspec" - }, - { - "name": "refname", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the name of the reference to check" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "srcMatches", - "cppFunctionName": "SrcMatches", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if the refspec matches, 0 otherwise", - "jsClassName": "Number" - }, - "description": "

Check if a refspec's source descriptor matches a reference

\n" - }, - { - "cFunctionName": "git_refspec_dst_matches", - "args": [ - { - "name": "refspec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "isSelf": true, - "comment": "the refspec" - }, - { - "name": "refname", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the name of the reference to check" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "dstMatches", - "cppFunctionName": "DstMatches", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if the refspec matches, 0 otherwise", - "jsClassName": "Number" - }, - "description": "

Check if a refspec's destination descriptor matches a reference

\n" - }, - { - "cFunctionName": "git_refspec_transform", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "where to store the target name" - }, - { - "name": "outlen", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the size of the `out` buffer" - }, - { - "name": "spec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "comment": "the refspec" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the name of the reference to transform" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "transform", - "cppFunctionName": "Transform", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_EBUFS or another error", - "jsClassName": "Number" - }, - "description": "

Transform a reference to its target following the refspec's rules

\n" - }, - { - "cFunctionName": "git_refspec_rtransform", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "where to store the source reference name" - }, - { - "name": "outlen", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the size of the `out` buffer" - }, - { - "name": "spec", - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "jsClassName": "Refspec", - "comment": "the refspec" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the name of the reference to transform" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "rtransform", - "cppFunctionName": "Rtransform", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_EBUFS or another error", - "jsClassName": "Number" - }, - "description": "

Transform a target reference to its source reference following the refspec's rules

\n" - } - ] - }, - { - "filename": "remote.h", - "dependencies": [ - "git2/net.h" - ], - "jsClassName": "Remote", - "cppClassName": "GitRemote", - "cType": "git_remote", - "freeFunctionName": "git_remote_free", - "functions": [ - { - "cFunctionName": "git_remote_save", - "args": [ - { - "name": "remote", - "cType": "const git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to save to config" - } - ], - "ignore": "called automatically by git_remote_create", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "save", - "cppFunctionName": "Save", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Save a remote to its repository's configuration

\n" - }, - { - "cFunctionName": "git_remote_name", - "args": [ - { - "name": "remote", - "cType": "const git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "name", - "cppFunctionName": "Name", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "a pointer to the name or NULL for in-memory remotes", - "jsClassName": "String" - }, - "description": "

Get the remote's name

\n" - }, - { - "cFunctionName": "git_remote_url", - "args": [ - { - "name": "remote", - "cType": "const git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "url", - "cppFunctionName": "Url", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "a pointer to the url", - "jsClassName": "String" - }, - "description": "

Get the remote's url

\n" - }, - { - "cFunctionName": "git_remote_pushurl", - "args": [ - { - "name": "remote", - "cType": "const git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "pushUrl", - "cppFunctionName": "PushUrl", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "a pointer to the url or NULL if no special url for pushing is set", - "jsClassName": "String" - }, - "description": "

Get the remote's url for pushing

\n" - }, - { - "cFunctionName": "git_remote_set_url", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - }, - { - "name": "url", - "cType": "const char*", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the url to set" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setUrl", - "cppFunctionName": "SetUrl", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error value", - "jsClassName": "Number" - }, - "description": "

Set the remote's url

\n" - }, - { - "cFunctionName": "git_remote_set_pushurl", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - }, - { - "name": "url", - "cType": "const char*", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the url to set or NULL to clear the pushurl" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setPushUrl", - "cppFunctionName": "SetPushUrl", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error value", - "jsClassName": "Number" - }, - "description": "

Set the remote's url for pushing

\n" - }, - { - "cFunctionName": "git_remote_set_fetchspec", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true - }, - { - "name": "spec", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setFetchspec", - "cppFunctionName": "SetFetchspec", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - } - }, - { - "cFunctionName": "git_remote_fetchspec", - "args": [ - { - "name": "remote", - "cType": "const git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "fetchspec", - "cppFunctionName": "Fetchspec", - "return": { - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "copy": "fixme", - "jsClassName": "Refspec" - } - }, - { - "cFunctionName": "git_remote_set_pushspec", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true - }, - { - "name": "spec", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setPushspec", - "cppFunctionName": "SetPushspec", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - } - }, - { - "cFunctionName": "git_remote_pushspec", - "args": [ - { - "name": "remote", - "cType": "const git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "pushspec", - "cppFunctionName": "Pushspec", - "return": { - "cType": "const git_refspec *", - "cppClassName": "Refspec", - "copy": "fixme", - "jsClassName": "Refspec" - } - }, - { - "cFunctionName": "git_remote_connect", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to connect to" - }, - { - "name": "direction", - "cType": "git_direction", - "cppClassName": "Number", - "jsClassName": "Number", - "comment": "GIT_DIRECTION_FETCH if you want to fetch or GIT_DIRECTION_PUSH if you want to push", - "additionalCast": "(int)" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "connect", - "cppFunctionName": "Connect", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Open a connection to a remote

\n" - }, - { - "cFunctionName": "git_remote_ls", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - }, - { - "name": "list_cb", - "cType": "git_headlist_cb", - "cppClassName": "HeadlistCb", - "jsClassName": "HeadlistCb", - "comment": "function to call with each ref discovered at the remote" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "additional data to pass to the callback" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "ls", - "cppFunctionName": "Ls", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Get a list of refs at the remote

\n" - }, - { - "cFunctionName": "git_remote_download", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to download from" - }, - { - "name": "progress_cb", - "cType": "git_transfer_progress_callback", - "cppClassName": "Function", - "jsClassName": "Function", - "isOptional": true, - "comment": "function to call with progress information. Be aware that this is called inline with network and indexing operations, so performance may be affected." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "isPayload": true, - "comment": "payload for the progress callback" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "download", - "cppFunctionName": "Download", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Download the packfile

\n" - }, - { - "cFunctionName": "git_remote_connected", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "connected", - "cppFunctionName": "Connected", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Check whether the remote is connected

\n" - }, - { - "cFunctionName": "git_remote_stop", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "stop", - "cppFunctionName": "Stop", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Cancel the operation

\n" - }, - { - "cFunctionName": "git_remote_disconnect", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to disconnect from" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "disconnect", - "cppFunctionName": "Disconnect", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Disconnect from the remote

\n" - }, - { - "cFunctionName": "git_remote_free", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "the remote to free" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free the memory associated with a remote

\n" - }, - { - "cFunctionName": "git_remote_update_tips", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to update" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "updateTips", - "cppFunctionName": "UpdateTips", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Update the tips to the new state

\n" - }, - { - "cFunctionName": "git_remote_valid_url", - "args": [ - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the url to check" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "validUrl", - "cppFunctionName": "ValidUrl", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Return whether a string is a valid remote URL

\n" - }, - { - "cFunctionName": "git_remote_supported_url", - "args": [ - { - "name": "url", - "cType": "const char*", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the url to check" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "supportedUrl", - "cppFunctionName": "SupportedUrl", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Return whether the passed URL is supported by this version of the library.

\n" - }, - { - "cFunctionName": "git_remote_check_cert", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to configure" - }, - { - "name": "check", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "whether to check the server's certificate (defaults to yes)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "checkCert", - "cppFunctionName": "CheckCert", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Choose whether to check the server's certificate (applies to HTTPS only)

\n" - }, - { - "cFunctionName": "git_remote_set_cred_acquire_cb", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to configure" - }, - { - "name": "cred_acquire_cb", - "cType": "git_cred_acquire_cb", - "cppClassName": "CredAcquireCb", - "jsClassName": "CredAcquireCb", - "comment": "The credentials acquisition callback to use (defaults to NULL)" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setCredAcquireCb", - "cppFunctionName": "SetCredAcquireCb", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set a credentials acquisition callback for this remote. If the remote is\nnot available for anonymous access, then you must set this callback in order\nto provide credentials to the transport at the time of authentication\nfailure so that retry can be performed.

\n" - }, - { - "cFunctionName": "git_remote_set_transport", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to configure" - }, - { - "name": "transport", - "cType": "git_transport *", - "cppClassName": "Transport", - "jsClassName": "Transport", - "comment": "the transport object for the remote to use" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setTransport", - "cppFunctionName": "SetTransport", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Sets a custom transport for the remote. The caller can use this function\nto bypass the automatic discovery of a transport by URL scheme (i.e.\nhttp://, https://, git://) and supply their own transport to be used\ninstead. After providing the transport to a remote using this function,\nthe transport object belongs exclusively to that remote, and the remote will\nfree it when it is freed with git_remote_free.

\n" - }, - { - "cFunctionName": "git_remote_set_callbacks", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to configure" - }, - { - "name": "callbacks", - "cType": "git_remote_callbacks *", - "cppClassName": "RemoteCallbacks", - "jsClassName": "RemoteCallbacks", - "comment": "a pointer to the user's callback settings" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setCallbacks", - "cppFunctionName": "SetCallbacks", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Set the callbacks for a remote

\n" - }, - { - "cFunctionName": "git_remote_stats", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "stats", - "cppFunctionName": "Stats", - "return": { - "cType": "const git_transfer_progress *", - "cppClassName": "TransferProgress", - "jsClassName": "TransferProgress" - }, - "description": "

Get the statistics structure that is filled in by the fetch operation.

\n" - }, - { - "cFunctionName": "git_remote_autotag", - "args": [], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "autotag", - "cppFunctionName": "Autotag", - "return": { - "cType": "GIT_EXTERN(", - "cppClassName": "GIT_EXTERN(" - }, - "description": "

Retrieve the tag auto-follow setting

\n" - }, - { - "cFunctionName": "git_remote_set_autotag", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to configure" - }, - { - "name": "value", - "cType": "git_remote_autotag_option_t", - "cppClassName": "RemoteAutotagOptionT", - "jsClassName": "RemoteAutotagOptionT", - "comment": "a GIT_REMOTE_DOWNLOAD_TAGS value" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setAutotag", - "cppFunctionName": "SetAutotag", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the tag auto-follow setting

\n" - }, - { - "cFunctionName": "git_remote_rename", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to rename" - }, - { - "name": "new_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the new name the remote should bear" - }, - { - "name": "callback", - "cType": "git_remote_rename_problem_cb", - "cppClassName": "RemoteRenameProblemCb", - "jsClassName": "RemoteRenameProblemCb", - "comment": "Optional callback to notify the consumer of fetch refspecs that haven't been automatically updated and need potential manual tweaking." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Additional data to pass to the callback" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "rename", - "cppFunctionName": "Rename", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Give the remote a new name

\n" - }, - { - "cFunctionName": "git_remote_update_fetchhead", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to query" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "updateFetchhead", - "cppFunctionName": "UpdateFetchhead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Retrieve the update FETCH_HEAD setting.

\n" - }, - { - "cFunctionName": "git_remote_set_update_fetchhead", - "args": [ - { - "name": "remote", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "isSelf": true, - "comment": "the remote to configure" - }, - { - "name": "value", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "0 to disable updating FETCH_HEAD" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setUpdateFetchhead", - "cppFunctionName": "SetUpdateFetchhead", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be\nupdated on every fetch. Set to 0 to disable.

\n" - }, - { - "cFunctionName": "git_remote_is_valid_name", - "args": [ - { - "name": "remote_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name to be checked." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "isValidName", - "cppFunctionName": "IsValidName", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Ensure the remote name is well-formed.

\n" - } - ] - }, - { - "filename": "repo.h", - "dependencies": [ - "../include/oid.h", - "../include/commit.h", - "../include/blob.h", - "../include/object.h", - "../include/reference.h", - "../include/submodule.h", - "../include/refdb.h", - "../include/revwalk.h", - "../include/tag.h", - "../include/signature.h", - "../include/tree.h", - "../include/odb.h", - "../include/index.h", - "../include/remote.h", - "../include/clone_options.h", - "node_buffer.h" - ], - "jsClassName": "Repo", - "cppClassName": "GitRepo", - "cType": "git_repository", - "freeFunctionName": "git_repository_free", - "functions": [ - { - "cFunctionName": "git_repository_open", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "pointer to the repo which will be opened" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the path to the repository" - } - ], - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "open", - "cppFunctionName": "Open", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Open a git repository.

\n" - }, - { - "cFunctionName": "git_repository_wrap_odb", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "pointer to the repo" - }, - { - "name": "odb", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "the object database to wrap" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "wrapOdb", - "cppFunctionName": "WrapOdb", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a "fake" repository to wrap an object database

\n" - }, - { - "cFunctionName": "git_repository_discover", - "args": [ - { - "name": "path_out", - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The user allocated buffer which will contain the found path." - }, - { - "name": "path_size", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "repository_path size" - }, - { - "name": "start_path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The base path where the lookup starts." - }, - { - "name": "across_fs", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "If true, then the lookup will not stop when a filesystem device change is detected while exploring parent directories." - }, - { - "name": "ceiling_dirs", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "A GIT_PATH_LIST_SEPARATOR separated list of absolute symbolic link free paths. The lookup will stop when any of this paths is reached. Note that the lookup always performs on start_path no matter start_path appears in ceiling_dirs ceiling_dirs might be NULL (which is equivalent to an empty string)" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "discover", - "cppFunctionName": "Discover", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Look for a git repository and copy its path in the given buffer.\nThe lookup start from base_path and walk across parent directories\nif nothing has been found. The lookup ends when the first repository\nis found, or when reaching a directory referenced in ceiling_dirs\nor when the filesystem changes (in case across_fs is true).

\n" - }, - { - "cFunctionName": "git_repository_open_ext", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Pointer to the repo which will be opened. This can actually be NULL if you only want to use the error code to see if a repo at this path could be opened." - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Path to open as git repository. If the flags permit \"searching\", then this can be a path to a subdirectory inside the working directory of the repository." - }, - { - "name": "flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "A combination of the GIT_REPOSITORY_OPEN flags above." - }, - { - "name": "ceiling_dirs", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "A GIT_PATH_LIST_SEPARATOR delimited list of path prefixes at which the search for a containing repository should terminate." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "openExt", - "cppFunctionName": "OpenExt", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND if no repository could be found, or -1 if there was a repository but open failed for some reason (such as repo corruption or system errors).", - "jsClassName": "Number" - }, - "description": "

Find and open a repository with extended controls.

\n" - }, - { - "cFunctionName": "git_repository_free", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository handle to close. If NULL nothing occurs." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free a previously allocated repository

\n" - }, - { - "cFunctionName": "git_repository_init", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "pointer to the repo which will be created or reinitialized" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the path to the repository" - }, - { - "name": "is_bare", - "cType": "unsigned", - "cppClassName": "Boolean", - "jsClassName": "Boolean", - "comment": "if true, a Git repository without a working directory is created at the pointed path. If false, provided path will be considered as the working directory into which the .git directory will be created." - } - ], - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "init", - "cppFunctionName": "Init", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Creates a new Git repository in the given folder.

\n" - }, - { - "cFunctionName": "git_repository_init_ext", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Pointer to the repo which will be created or reinitialized." - }, - { - "name": "repo_path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The path to the repository." - }, - { - "name": "opts", - "cType": "git_repository_init_options *", - "cppClassName": "RepositoryInitOptions", - "jsClassName": "RepositoryInitOptions", - "comment": "Pointer to git_repository_init_options struct." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "initExt", - "cppFunctionName": "InitExt", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code on failure.", - "jsClassName": "Number" - }, - "description": "

Create a new Git repository in the given folder with extended controls.

\n" - }, - { - "cFunctionName": "git_repository_head", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "pointer to the reference which will be retrieved" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "a repository object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "head", - "cppFunctionName": "Head", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise", - "jsClassName": "Number" - }, - "description": "

Retrieve and resolve the reference pointed at by HEAD.

\n" - }, - { - "cFunctionName": "git_repository_head_detached", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repo to test" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "headDetached", - "cppFunctionName": "HeadDetached", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if HEAD is detached, 0 if it's not; error code if there was an error.", - "jsClassName": "Number" - }, - "description": "

Check if a repository's HEAD is detached

\n" - }, - { - "cFunctionName": "git_repository_head_orphan", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repo to test" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "headOrphan", - "cppFunctionName": "HeadOrphan", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if the current branch is an orphan, 0 if it's not; error code if there was an error", - "jsClassName": "Number" - }, - "description": "

Check if the current branch is an orphan

\n" - }, - { - "cFunctionName": "git_repository_is_empty", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repo to test" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "isEmpty", - "cppFunctionName": "IsEmpty", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if the repository is empty, 0 if it isn't, error code if the repository is corrupted", - "jsClassName": "Number" - }, - "description": "

Check if a repository is empty

\n" - }, - { - "cFunctionName": "git_repository_path", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "path", - "cppFunctionName": "Path", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the path to the repository", - "jsClassName": "String" - }, - "description": "

Get the path of this repository

\n" - }, - { - "cFunctionName": "git_repository_workdir", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "workdir", - "cppFunctionName": "Workdir", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the path to the working dir, if it exists", - "jsClassName": "String" - }, - "description": "

Get the path of the working directory for this repository

\n" - }, - { - "cFunctionName": "git_repository_set_workdir", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "workdir", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The path to a working directory" - }, - { - "name": "update_gitlink", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Create/update gitlink in workdir and set config \"core.worktree\" (if workdir is not the parent of the .git directory)" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setWorkdir", - "cppFunctionName": "SetWorkdir", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, or an error code", - "jsClassName": "Number" - }, - "description": "

Set the path to the working directory for this repository

\n" - }, - { - "cFunctionName": "git_repository_is_bare", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repo to test" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "isBare", - "cppFunctionName": "IsBare", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "1 if the repository is bare, 0 otherwise.", - "jsClassName": "Number" - }, - "description": "

Check if a repository is bare

\n" - }, - { - "cFunctionName": "git_repository_config", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_config **", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "Pointer to store the loaded config file" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "A repository object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "config", - "cppFunctionName": "Config", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, or an error code", - "jsClassName": "Number" - }, - "description": "

Get the configuration file for this repository.

\n" - }, - { - "cFunctionName": "git_repository_set_config", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "config", - "cType": "git_config *", - "cppClassName": "Config", - "jsClassName": "Config", - "comment": "A Config object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setConfig", - "cppFunctionName": "SetConfig", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the configuration file for this repository

\n" - }, - { - "cFunctionName": "git_repository_odb", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_odb **", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "Pointer to store the loaded ODB" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "odb", - "cppFunctionName": "Odb", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, or an error code", - "jsClassName": "Number" - }, - "description": "

Get the Object Database for this repository.

\n" - }, - { - "cFunctionName": "git_repository_set_odb", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "odb", - "cType": "git_odb *", - "cppClassName": "GitOdb", - "jsClassName": "Odb", - "comment": "An ODB object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setOdb", - "cppFunctionName": "SetOdb", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the Object Database for this repository

\n" - }, - { - "cFunctionName": "git_repository_refdb", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_refdb **", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "comment": "Pointer to store the loaded refdb" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "A repository object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "refdb", - "cppFunctionName": "Refdb", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, or an error code", - "jsClassName": "Number" - }, - "description": "

Get the Reference Database Backend for this repository.

\n" - }, - { - "cFunctionName": "git_repository_set_refdb", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "refdb", - "cType": "git_refdb *", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "comment": "An refdb object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setRefdb", - "cppFunctionName": "SetRefdb", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the Reference Database Backend for this repository

\n" - }, - { - "cFunctionName": "git_repository_index", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_index **", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "Pointer to store the loaded index" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "openIndex", - "cppFunctionName": "openIndex", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, or an error code", - "jsClassName": "Number" - }, - "description": "

Get the Index file for this repository.

\n" - }, - { - "cFunctionName": "git_repository_set_index", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "comment": "An index object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setIndex", - "cppFunctionName": "SetIndex", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Set the index file for this repository

\n" - }, - { - "cFunctionName": "git_repository_message", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Buffer to write data into or NULL to just read required size" - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Length of `out` buffer in bytes" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository to read prepared message from" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "message", - "cppFunctionName": "Message", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "GIT_ENOUTFOUND if no message exists, other value < 0 for other errors, or total bytes in message (may be > `len`) on success", - "jsClassName": "Number" - }, - "description": "

Retrieve git's prepared message

\n" - }, - { - "cFunctionName": "git_repository_message_remove", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "messageRemove", - "cppFunctionName": "MessageRemove", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Remove git's prepared message.

\n" - }, - { - "cFunctionName": "git_repository_merge_cleanup", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "mergeCleanup", - "cppFunctionName": "MergeCleanup", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, or error", - "jsClassName": "Number" - }, - "description": "

Remove all the metadata associated with an ongoing git merge, including\nMERGE_HEAD, MERGE_MSG, etc.

\n" - }, - { - "cFunctionName": "git_repository_fetchhead_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "callback", - "cType": "git_repository_fetchhead_foreach_cb", - "cppClassName": "RepositoryFetchheadForeachCb", - "jsClassName": "RepositoryFetchheadForeachCb", - "comment": "Callback function" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Pointer to callback data (optional)" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "fetchheadForeach", - "cppFunctionName": "FetchheadForeach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND, GIT_EUSER or error", - "jsClassName": "Number" - }, - "description": "

Call callback 'callback' for each entry in the given FETCH_HEAD file.

\n" - }, - { - "cFunctionName": "git_repository_mergehead_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "A repository object" - }, - { - "name": "callback", - "cType": "git_repository_mergehead_foreach_cb", - "cppClassName": "RepositoryMergeheadForeachCb", - "jsClassName": "RepositoryMergeheadForeachCb", - "comment": "Callback function" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Pointer to callback data (optional)" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "mergeheadForeach", - "cppFunctionName": "MergeheadForeach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND, GIT_EUSER or error", - "jsClassName": "Number" - }, - "description": "

If a merge is in progress, call callback 'cb' for each commit ID in the\nMERGE_HEAD file.

\n" - }, - { - "cFunctionName": "git_repository_hashfile", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "Output value of calculated SHA" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository pointer" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Path to file on disk whose contents should be hashed. If the repository is not NULL, this can be a relative path." - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Otype", - "comment": "The object type to hash as (e.g. GIT_OBJ_BLOB)" - }, - { - "name": "as_path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The path to use to look up filtering rules. If this is NULL, then the `path` parameter will be used instead. If this is passed as the empty string, then no filters will be applied when calculating the hash." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "hashfile", - "cppFunctionName": "Hashfile", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Calculate hash of file using repository filtering rules.

\n" - }, - { - "cFunctionName": "git_repository_set_head", - "args": [ - { - "name": "repo", - "cType": "git_repository*", - "cppClassName": "Repository*", - "jsClassName": "Repository*", - "comment": "Repository pointer" - }, - { - "name": "refname", - "cType": "const char*", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Canonical name of the reference the HEAD should point at" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "setHead", - "cppFunctionName": "SetHead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, or an error code", - "jsClassName": "Number" - }, - "description": "

Make the repository HEAD point to the specified reference.

\n" - }, - { - "cFunctionName": "git_repository_set_head_detached", - "args": [ - { - "name": "repo", - "cType": "git_repository*", - "cppClassName": "Repository*", - "jsClassName": "Repository*", - "comment": "Repository pointer" - }, - { - "name": "commitish", - "cType": "const git_oid*", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Object id of the Commit the HEAD should point to" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "setHeadDetached", - "cppFunctionName": "SetHeadDetached", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, or an error code", - "jsClassName": "Number" - }, - "description": "

Make the repository HEAD directly point to the Commit.

\n" - }, - { - "cFunctionName": "git_repository_detach_head", - "args": [ - { - "name": "repo", - "cType": "git_repository*", - "cppClassName": "Repository*", - "jsClassName": "Repository*", - "comment": "Repository pointer" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "detachHead", - "cppFunctionName": "DetachHead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing branch or an error code", - "jsClassName": "Number" - }, - "description": "

Detach the HEAD.

\n" - }, - { - "cFunctionName": "git_repository_state", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository pointer" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "state", - "cppFunctionName": "State", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "The state of the repository", - "jsClassName": "Number" - }, - "description": "

Determines the status of a git repository - ie, whether an operation\n(merge, cherry-pick, etc) is in progress.

\n" - }, - { - "cFunctionName": "git_blob_lookup", - "args": [ - { - "name": "blob", - "cType": "git_blob **", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "isReturn": true, - "comment": "pointer to the looked up blob" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to use when locating the blob." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the blob to locate." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getBlob", - "cppFunctionName": "GetBlob", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a blob object from a repository.

\n" - }, - { - "cFunctionName": "git_blob_lookup_prefix", - "args": [ - { - "name": "blob", - "cType": "git_blob **", - "cppClassName": "GitBlob", - "jsClassName": "Blob", - "isReturn": true, - "comment": "pointer to the looked up blob" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to use when locating the blob." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the blob to locate." - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the length of the short identifier" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getBlobByPrefix", - "cppFunctionName": "GetBlobByPrefix", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a blob object from a repository,\ngiven a prefix of its identifier (short id).

\n" - }, - { - "cFunctionName": "git_commit_lookup", - "args": [ - { - "name": "commit", - "cType": "git_commit **", - "cppClassName": "GitCommit", - "jsClassName": "Commit", - "isReturn": true, - "comment": "pointer to the looked up commit" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to use when locating the commit." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the commit to locate. If the object is an annotated tag it will be peeled back to the commit." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getCommit", - "cppFunctionName": "GetCommit", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a commit object from a repository.

\n" - }, - { - "cFunctionName": "git_commit_create", - "args": [ - { - "name": "id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isReturn": true, - "shouldAlloc": true, - "comment": "Pointer in which to store the OID of the newly created commit" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where to store the commit" - }, - { - "name": "update_ref", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "isOptional": true, - "comment": "If not NULL, name of the reference that will be updated to point to this commit. If the reference is not direct, it will be resolved to a direct reference. Use \"HEAD\" to update the HEAD of the current branch and make it point to this commit. If the reference doesn't exist yet, it will be created." - }, - { - "name": "author", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "Signature with author and author time of commit" - }, - { - "name": "committer", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "Signature with committer and * commit time of commit" - }, - { - "name": "message_encoding", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "isOptional": true, - "comment": "The encoding for the message in the commit, represented with a standard encoding name. E.g. \"UTF-8\". If NULL, no encoding header is written and UTF-8 is assumed." - }, - { - "name": "message", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "_encoding The encoding for the message in the commit, represented with a standard encoding name. E.g. \"UTF-8\". If NULL, no encoding header is written and UTF-8 is assumed." - }, - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "comment": "An instance of a `git_tree` object that will be used as the tree for the commit. This tree object must also be owned by the given `repo`." - }, - { - "name": "parent_count", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Number of parents for this commit" - }, - { - "name": "parents", - "cType": "const git_commit **", - "cppClassName": "Array", - "arrayElementCppClassName": "GitCommit", - "jsClassName": "Array" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createCommit", - "cppFunctionName": "CreateCommit", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code The created commit will be written to the Object Database and the given reference will be updated to point to it", - "jsClassName": "Number" - }, - "description": "

Create new commit in the repository from a list of git_object pointers

\n" - }, - { - "cFunctionName": "git_object_lookup", - "args": [ - { - "name": "object", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "pointer to the looked-up object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository to look up the object" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the unique identifier for the object" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "the type of the object" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getObject", - "cppFunctionName": "GetObject", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "a reference to the object", - "jsClassName": "Number" - }, - "description": "

Lookup a reference to one of the objects in a repository.

\n" - }, - { - "cFunctionName": "git_object_lookup_prefix", - "args": [ - { - "name": "object_out", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "pointer where to store the looked-up object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository to look up the object" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "a short identifier for the object" - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the length of the short identifier" - }, - { - "name": "type", - "cType": "git_otype", - "cppClassName": "Number", - "jsClassName": "Number", - "comment": "the type of the object" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getObjectByPrefix", - "cppFunctionName": "GetObjectByPrefix", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a reference to one of the objects in a repository,\ngiven a prefix of its identifier (short id).

\n" - }, - { - "cFunctionName": "git_refdb_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_refdb **", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "comment": "location to store the database pointer, if opened. Set to NULL if the open failed." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "newRefDbWithoutBackends", - "cppFunctionName": "NewRefDbWithoutBackends", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new reference database with no backends.

\n" - }, - { - "cFunctionName": "git_refdb_open", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_refdb **", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb", - "comment": "location to store the database pointer, if opened. Set to NULL if the open failed." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "openRefDb", - "cppFunctionName": "OpenRefDb", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new reference database and automatically add\nthe default backends:

\n" - }, - { - "cFunctionName": "git_refdb_backend_fs", - "args": [ - { - "name": "backend_out", - "cType": "struct git_refdb_backend **", - "cppClassName": "RefdbBackend", - "jsClassName": "RefdbBackend", - "isReturn": true, - "comment": "Output pointer to the git_refdb_backend object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Git repository to access" - }, - { - "name": "refdb", - "cType": "git_refdb *", - "cppClassName": "GitRefDb", - "jsClassName": "RefDb" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "openRefDbBackend", - "cppFunctionName": "OpenRefDbBackend", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 error code on failure", - "jsClassName": "Number" - }, - "description": "

Constructors for default filesystem-based refdb backend

\n" - }, - { - "cFunctionName": "git_reference_lookup", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "pointer to the looked-up reference" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository to look up the reference" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getReference", - "cppFunctionName": "GetReference", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, ENOTFOUND, EINVALIDSPEC or an error code.", - "jsClassName": "Number" - }, - "description": "

Lookup a reference by name in a repository.

\n" - }, - { - "cFunctionName": "git_reference_symbolic_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer to the newly created reference" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where that reference will live" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The name of the reference" - }, - { - "name": "target", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The target of the reference" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing references" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createSymbolicReference", - "cppFunctionName": "CreateSymbolicReference", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, EEXISTS, EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new symbolic reference.

\n" - }, - { - "cFunctionName": "git_reference_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_reference **", - "cppClassName": "GitReference", - "jsClassName": "Reference", - "comment": "Pointer to the newly created reference" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where that reference will live" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The name of the reference" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "The object id pointed to by the reference." - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing references" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createReference", - "cppFunctionName": "CreateReference", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, EEXISTS, EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new direct reference.

\n" - }, - { - "cFunctionName": "git_remote_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_remote **", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "the resulting remote" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository in which to create the remote" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the remote's name" - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the remote's url" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addRemote", - "cppFunctionName": "AddRemote", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code", - "jsClassName": "Number" - }, - "description": "

Add a remote with the default fetch refspec to the repository's configuration. This\ncalls git_remote_save before returning.

\n" - }, - { - "cFunctionName": "git_remote_create_inmemory", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_remote **", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "pointer to the new remote object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the associated repository" - }, - { - "name": "fetch", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the fetch refspec to use for this remote. May be NULL for defaults." - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the remote repository's URL" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addRemoteInMemory", - "cppFunctionName": "AddRemoteInMemory", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a remote in memory

\n" - }, - { - "cFunctionName": "git_revwalk_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_revwalk **", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "comment": "pointer to the new revision walker" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to walk through" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createRevWalk", - "cppFunctionName": "CreateRevWalk", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Allocate a new revision walker to iterate through a repo.

\n" - }, - { - "cFunctionName": "git_submodule_lookup", - "args": [ - { - "name": "submodule", - "cType": "git_submodule **", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isReturn": true, - "comment": "Pointer to submodule description object pointer.." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "The repository." - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The name of the submodule. Trailing slashes will be ignored." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getSubmodule", - "cppFunctionName": "GetSubmodule", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND if submodule does not exist, GIT_EEXISTS if submodule exists in working directory only, -1 on other errors.", - "jsClassName": "Number" - }, - "description": "

Lookup submodule information by name or path.

\n" - }, - { - "cFunctionName": "git_submodule_add_setup", - "args": [ - { - "name": "submodule", - "cType": "git_submodule **", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isReturn": true, - "comment": "The newly created submodule ready to open for clone" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Superproject repository to contain the new submodule" - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "URL for the submodules remote" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Path at which the submodule should be created" - }, - { - "name": "use_gitlink", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Should workdir contain a gitlink to the repo in .git/modules vs. repo directly in workdir." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addSubmodule", - "cppFunctionName": "AddSubmodule", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EEXISTS if submodule already exists, -1 on other errors.", - "jsClassName": "Number" - }, - "description": "

Set up a new git submodule for checkout.

\n" - }, - { - "cFunctionName": "git_tag_lookup", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_tag **", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "comment": "pointer to the looked up tag" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to use when locating the tag." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the tag to locate." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getTag", - "cppFunctionName": "GetTag", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a tag object from the repository.

\n" - }, - { - "cFunctionName": "git_tag_lookup_prefix", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_tag **", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "comment": "pointer to the looked up tag" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to use when locating the tag." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the tag to locate." - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the length of the short identifier" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getTagByPrefix", - "cppFunctionName": "GetTagByPrefix", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a tag object from the repository,\ngiven a prefix of its identifier (short id).

\n" - }, - { - "cFunctionName": "git_tag_create", - "args": [ - { - "name": "oid", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isReturn": true, - "shouldAlloc": true, - "comment": "Pointer where to store the OID of the newly created tag. If the tag already exists, this parameter will be the oid of the existing tag, and the function will return a GIT_EEXISTS error code." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where to store the tag" - }, - { - "name": "tag_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Name for the tag; this name is validated for consistency. It should also not conflict with an already existing tag name" - }, - { - "name": "target", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "Object to which this tag points. This object must belong to the given `repo`." - }, - { - "name": "tagger", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "Signature of the tagger for this tag, and of the tagging time" - }, - { - "name": "message", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Full message for this tag" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing references" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createTag", - "cppFunctionName": "CreateTag", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EINVALIDSPEC or an error code A tag object is written to the ODB, and a proper reference is written in the /refs/tags folder, pointing to it", - "jsClassName": "Number" - }, - "description": "

Create a new tag in the repository from an object

\n" - }, - { - "cFunctionName": "git_tag_create_lightweight", - "args": [ - { - "name": "oid", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "isReturn": true, - "shouldAlloc": true, - "comment": "Pointer where to store the OID of the provided target object. If the tag already exists, this parameter will be filled with the oid of the existing pointed object and the function will return a GIT_EEXISTS error code." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where to store the lightweight tag" - }, - { - "name": "tag_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Name for the tag; this name is validated for consistency. It should also not conflict with an already existing tag name" - }, - { - "name": "target", - "cType": "const git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "Object to which this tag points. This object must belong to the given `repo`." - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing references" - } - ], - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "createLightweightTag", - "cppFunctionName": "CreateLightweightTag", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EINVALIDSPEC or an error code A proper reference is written in the /refs/tags folder, pointing to the provided target object", - "jsClassName": "Number" - }, - "description": "

Create a new lightweight tag pointing at a target object

\n" - }, - { - "cFunctionName": "git_tree_lookup", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_tree **", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "comment": "Pointer to the looked up tree" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "The repo to use when locating the tree." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "Identity of the tree to locate." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getTree", - "cppFunctionName": "GetTree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a tree object from the repository.

\n" - }, - { - "cFunctionName": "git_tree_lookup_prefix", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_tree **", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "comment": "pointer to the looked up tree" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repo to use when locating the tree." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "identity of the tree to locate." - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the length of the short identifier" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getTreeByPrefix", - "cppFunctionName": "GetTreeByPrefix", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Lookup a tree object from the repository,\ngiven a prefix of its identifier (short id).

\n" - }, - { - "cFunctionName": "git_submodule_reload_all", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "reloadSubmodules", - "cppFunctionName": "ReloadSubmodules", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Reread all submodule info.

\n" - }, - { - "cFunctionName": "git_tag_delete", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where lives the tag" - }, - { - "name": "tag_name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Name of the tag to be deleted; this name is validated for consistency." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "delete", - "cppFunctionName": "Delete", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Delete an existing tag reference.

\n" - }, - { - "cFunctionName": "git_tag_list", - "args": [ - { - "name": "tag_names", - "cType": "git_strarray *", - "cppClassName": "Array", - "jsClassName": "Array", - "isReturn": true, - "comment": "Pointer to a git_strarray structure where the tag names will be stored" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where to find the tags" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "listTags", - "cppFunctionName": "ListTags", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Fill a list with all the tags in the Repository

\n" - }, - { - "cFunctionName": "git_tag_list_match", - "args": [ - { - "name": "tag_names", - "cType": "git_strarray *", - "cppClassName": "Strarray", - "jsClassName": "Strarray", - "isReturn": true, - "comment": "Pointer to a git_strarray structure where the tag names will be stored" - }, - { - "name": "pattern", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Standard fnmatch pattern" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where to find the tags" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "listMatch", - "cppFunctionName": "ListMatch", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Fill a list with all the tags in the Repository\nwhich name match a defined pattern

\n" - }, - { - "cFunctionName": "git_tag_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository" - }, - { - "name": "callback", - "cType": "git_tag_foreach_cb", - "cppClassName": "TagForeachCb", - "jsClassName": "TagForeachCb", - "comment": "Callback function" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Pointer to callback data (optional)" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Call callback `cb' for each tag in the repository

\n" - }, - { - "cFunctionName": "git_reference_list", - "args": [ - { - "name": "array", - "cType": "git_strarray *", - "cppClassName": "Array", - "jsClassName": "Array", - "freeFunctionName": "git_strarray_free", - "size": "count", - "key": "strings", - "shouldAlloc": true, - "isReturn": true, - "comment": "Pointer to a git_strarray structure where the reference names will be stored" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "Repository where to find the refs" - }, - { - "name": "list_flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "isOptional": true - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getReferences", - "cppFunctionName": "GetReferences", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Fill a list with all the references that can be found in a repository.

\n" - }, - { - "cFunctionName": "git_blob_create_frombuffer", - "args": [ - { - "name": "oid", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "isReturn": true, - "comment": "return the oid of the written blob" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "repository where to blob will be written" - }, - { - "name": "buffer", - "cType": "const void *", - "cppClassName": "Buffer", - "jsClassName": "Buffer", - "comment": "data to be written into the blob" - }, - { - "name": "len", - "cType": "size_t", - "cppClassName": "Number", - "jsClassName": "Number", - "comment": "length of the data" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createBlobFromBuffer", - "cppFunctionName": "CreateBlobFromBuffer", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Write an in-memory buffer to the ODB as a blob

\n" - }, - { - "cFunctionName": "git_blob_create_fromworkdir", - "args": [ - { - "name": "id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "isReturn": true, - "comment": "return the id of the written blob" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "repository where the blob will be written. this repository cannot be bare" - }, - { - "name": "relative_path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "file from which the blob will be created, relative to the repository's working dir" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createBlobFromWorkdir", - "cppFunctionName": "CreateBlobFromWorkdir", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Read a file from the working folder of a repository\nand write it to the Object Database as a loose blob

\n" - }, - { - "cFunctionName": "git_blob_create_fromdisk", - "args": [ - { - "name": "id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "isReturn": true, - "comment": "return the id of the written blob" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "repository where the blob will be written. this repository can be bare or not" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "file from which the blob will be created" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createBlobFromFile", - "cppFunctionName": "CreateBlobFromFile", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Read a file from the filesystem and write its content\nto the Object Database as a loose blob

\n" - }, - { - "cFunctionName": "git_blob_create_fromchunks", - "args": [ - { - "name": "id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "isReturn": true, - "comment": "Return the id of the written blob" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "repository where the blob will be written. This repository can be bare or not." - }, - { - "name": "hintpath", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "if not NULL, will help selecting the filters to apply onto the content of the blob to be created." - }, - { - "name": "callback", - "cType": "git_blob_chunk_cb", - "cppClassName": "BlobChunkCb", - "jsClassName": "BlobChunkCb" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "createBlobFromChunks", - "cppFunctionName": "CreateBlobFromChunks", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Write a loose blob to the Object Database from a\nprovider of chunks of data.

\n" - }, - { - "cFunctionName": "git_remote_list", - "args": [ - { - "name": "out", - "cType": "git_strarray *", - "cppClassName": "Array", - "jsClassName": "Array", - "freeFunctionName": "git_strarray_free", - "size": "count", - "key": "strings", - "shouldAlloc": true, - "isReturn": true, - "comment": "a string array which receives the names of the remotes" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the repository to query" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getRemotes", - "cppFunctionName": "GetRemotes", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get a list of the configured remotes for a repo

\n" - }, - { - "cFunctionName": "git_clone", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "pointer that will receive the resulting repository object" - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the remote repository to clone" - }, - { - "name": "local_path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "local directory to clone to" - }, - { - "name": "options", - "cType": "const git_clone_options *", - "cppClassName": "GitCloneOptions", - "jsClassName": "CloneOptions", - "isOptional": true, - "comment": "configuration options for the clone. If NULL, the function works as though GIT_OPTIONS_INIT were passed." - } - ], - "isAsync": true, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "clone", - "cppFunctionName": "Clone", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)", - "jsClassName": "Number" - }, - "description": "

Clone a remote repository, and checkout the branch pointed to by the remote\nHEAD.

\n" - }, - { - "cFunctionName": "git_remote_load", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_remote **", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "pointer to the new remote object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isSelf": true, - "comment": "the associated repository" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the remote's name" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getRemote", - "cppFunctionName": "GetRemote", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Get the information for a particular remote

\n" - } - ] - }, - { - "filename": "reset.h", - "ignore": true, - "jsClassName": "Reset", - "cppClassName": "Reset", - "cType": "git_reset", - "freeFunctionName": "git_reset_free", - "functions": [ - { - "cFunctionName": "git_reset", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to perform the reset operation." - }, - { - "name": "target", - "cType": "git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "Committish to which the Head should be moved to. This object must belong to the given `repo` and can either be a git_commit or a git_tag. When a git_tag is being passed, it should be dereferencable to a git_commit which oid will be used as the target of the branch." - }, - { - "name": "reset_type", - "cType": "git_reset_t", - "cppClassName": "ResetT", - "jsClassName": "ResetT", - "comment": "Kind of reset operation to perform." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitReset", - "cppFunctionName": "GitReset", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success or an error code", - "jsClassName": "Number" - }, - "description": "

Sets the current head to the specified commit oid and optionally\nresets the index and working tree to match.

\n" - }, - { - "cFunctionName": "git_reset_default", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to perform the reset operation." - }, - { - "name": "target", - "cType": "git_object *", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "The committish which content will be used to reset the content of the index." - }, - { - "name": "pathspecs", - "cType": "git_strarray*", - "cppClassName": "Strarray*", - "jsClassName": "Strarray*", - "comment": "List of pathspecs to operate on." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "default", - "cppFunctionName": "Default", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success or an error code < 0", - "jsClassName": "Number" - }, - "description": "

Updates some entries in the index from the target commit tree.

\n" - } - ] - }, - { - "filename": "revparse.h", - "ignore": true, - "jsClassName": "Revparse", - "cppClassName": "Revparse", - "cType": "git_revparse", - "freeFunctionName": "git_revparse_free", - "functions": [ - { - "cFunctionName": "git_revparse_single", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "comment": "pointer to output object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository to search in" - }, - { - "name": "spec", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the textual specification for an object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "single", - "cppFunctionName": "Single", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC or an error code", - "jsClassName": "Number" - }, - "description": "

Find a single object, as specified by a revision string. See man gitrevisions,\nor http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for\ninformation on the syntax accepted.

\n" - }, - { - "cFunctionName": "git_revparse", - "args": [ - { - "name": "revspec", - "cType": "git_revspec *", - "cppClassName": "Revspec", - "jsClassName": "Revspec", - "comment": "Pointer to an user-allocated git_revspec struct where the result of the rev-parse will be stored" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "the repository to search in" - }, - { - "name": "spec", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the rev-parse spec to parse" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitRevparse", - "cppFunctionName": "GitRevparse", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code", - "jsClassName": "Number" - }, - "description": "

Parse a revision string for from, to, and intent. See man gitrevisions or\nhttp://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for information\non the syntax accepted.

\n" - } - ] - }, - { - "filename": "revwalk.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h" - ], - "jsClassName": "RevWalk", - "cppClassName": "GitRevWalk", - "cType": "git_revwalk", - "freeFunctionName": "git_revwalk_free", - "functions": [ - { - "cFunctionName": "git_revwalk_reset", - "args": [ - { - "name": "walker", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "handle to reset." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reset", - "cppFunctionName": "Reset", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Reset the revision walker for reuse.

\n" - }, - { - "cFunctionName": "git_revwalk_push", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal." - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the oid of the commit to start from." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "push", - "cppFunctionName": "Push", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Mark a commit to start traversal from.

\n" - }, - { - "cFunctionName": "git_revwalk_push_glob", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - }, - { - "name": "glob", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the glob pattern references should match" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "pushGlob", - "cppFunctionName": "PushGlob", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Push matching references

\n" - }, - { - "cFunctionName": "git_revwalk_push_head", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "pushHead", - "cppFunctionName": "PushHead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Push the repository's HEAD

\n" - }, - { - "cFunctionName": "git_revwalk_hide", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal." - }, - { - "name": "commit_id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the oid of commit that will be ignored during the traversal" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hide", - "cppFunctionName": "Hide", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Mark a commit (and its ancestors) uninteresting for the output.

\n" - }, - { - "cFunctionName": "git_revwalk_hide_glob", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - }, - { - "name": "glob", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the glob pattern references should match" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hideGlob", - "cppFunctionName": "HideGlob", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Hide matching references.

\n" - }, - { - "cFunctionName": "git_revwalk_hide_head", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hideHead", - "cppFunctionName": "HideHead", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Hide the repository's HEAD

\n" - }, - { - "cFunctionName": "git_revwalk_push_ref", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - }, - { - "name": "refname", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the reference to push" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "pushRef", - "cppFunctionName": "PushRef", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Push the OID pointed to by a reference

\n" - }, - { - "cFunctionName": "git_revwalk_hide_ref", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - }, - { - "name": "refname", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the reference to hide" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "hideRef", - "cppFunctionName": "HideRef", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Hide the OID pointed to by a reference

\n" - }, - { - "cFunctionName": "git_revwalk_next", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "shouldAlloc": true, - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "Pointer where to store the oid of the next commit" - }, - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker to pop the commit from." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "next", - "cppFunctionName": "Next", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if the next commit was found; GIT_ITEROVER if there are no commits left to iterate", - "jsClassName": "Number" - }, - "description": "

Get the next commit from the revision walk.

\n" - }, - { - "cFunctionName": "git_revwalk_sorting", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal." - }, - { - "name": "sort_mode", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "combination of GIT_SORT_XXX flags" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "sorting", - "cppFunctionName": "Sorting", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Change the sorting mode when iterating through the\nrepository's contents.

\n" - }, - { - "cFunctionName": "git_revwalk_push_range", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the walker being used for the traversal" - }, - { - "name": "range", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the range" - } - ], - "ignore": "This is in the documentation, but doesn't seem to exist!", - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "pushRange", - "cppFunctionName": "PushRange", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Push and hide the respective endpoints of the given range.

\n" - }, - { - "cFunctionName": "git_revwalk_free", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "comment": "traversal handle to close. If NULL nothing occurs." - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free a revision walker previously allocated.

\n" - }, - { - "cFunctionName": "git_revwalk_repository", - "args": [ - { - "name": "walk", - "cType": "git_revwalk *", - "cppClassName": "GitRevWalk", - "jsClassName": "RevWalk", - "isSelf": true, - "comment": "the revision walker" - } - ], - "ignore": "Never make public for memory allocation reasons", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "repository", - "cppFunctionName": "Repository", - "return": { - "cType": "git_repository *", - "cppClassName": "GitRepo", - "comment": "the repository being walked", - "jsClassName": "Repository" - }, - "description": "

Return the repository on which this walker\nis operating.

\n" - } - ] - }, - { - "filename": "time.h", - "dependencies": [], - "jsClassName": "Time", - "cppClassName": "GitTime", - "cType": "git_time", - "freeFunctionName": "free", - "fields": [ - { - "jsFunctionName": "time", - "cppFunctionName": "Time", - "name": "time", - "cType": "git_time_t", - "cppClassName": "Integer", - "jsClassName": "Number" - }, - { - "jsFunctionName": "offset", - "cppFunctionName": "Offset", - "name": "offset", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number" - } - ] - }, - { - "filename": "signature.h", - "dependencies": [ - "../include/time.h" - ], - "jsClassName": "Signature", - "cppClassName": "GitSignature", - "cType": "git_signature", - "freeFunctionName": "git_signature_free", - "fields": [ - { - "jsFunctionName": "name", - "cppFunctionName": "Name", - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "jsFunctionName": "email", - "cppFunctionName": "Email", - "name": "email", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String" - }, - { - "jsFunctionName": "time", - "cppFunctionName": "Time", - "name": "when", - "cType": "git_time", - "cppClassName": "GitTime", - "jsClassName": "Time", - "copy": "git_time_dup" - } - ], - "functions": [ - { - "cFunctionName": "git_signature_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_signature **", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "new signature, in case of error NULL" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name of the person" - }, - { - "name": "email", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "email of the person" - }, - { - "name": "time", - "cType": "git_time_t", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "time when the action happened" - }, - { - "name": "offset", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "timezone offset in minutes for the time" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "create", - "cppFunctionName": "Create", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new action signature.

\n" - }, - { - "cFunctionName": "git_signature_now", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_signature **", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "new signature, in case of error NULL" - }, - { - "name": "name", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "name of the person" - }, - { - "name": "email", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "email of the person" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "now", - "cppFunctionName": "Now", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create a new action signature with a timestamp of 'now'.

\n" - }, - { - "cFunctionName": "git_signature_dup", - "args": [ - { - "name": "sig", - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "isSelf": true, - "comment": "signature to duplicated" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "dup", - "cppFunctionName": "Dup", - "return": { - "cType": "git_signature *", - "cppClassName": "GitSignature", - "comment": "a copy of sig, NULL on out of memory", - "jsClassName": "Signature" - }, - "description": "

Create a copy of an existing signature. All internal strings are also\nduplicated.

\n" - }, - { - "cFunctionName": "git_signature_free", - "args": [ - { - "name": "sig", - "cType": "git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "signature to free" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free an existing signature.

\n" - } - ] - }, - { - "filename": "stash.h", - "ignore": true, - "jsClassName": "Stash", - "cppClassName": "Stash", - "cType": "git_stash", - "freeFunctionName": "git_stash_free", - "functions": [ - { - "cFunctionName": "git_stash_save", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "comment": "Object id of the commit containing the stashed state. This commit is also the target of the direct reference refs/stash." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The owning repository." - }, - { - "name": "stasher", - "cType": "git_signature *", - "cppClassName": "GitSignature", - "jsClassName": "Signature", - "comment": "The identity of the person performing the stashing." - }, - { - "name": "message", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Optional description along with the stashed state." - }, - { - "name": "flags", - "cType": "unsigned int", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "Flags to control the stashing process. (see GIT_STASH_* above)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "save", - "cppFunctionName": "Save", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND where there's nothing to stash, or error code.", - "jsClassName": "Number" - }, - "description": "

Save the local modifications to a new stash.

\n" - }, - { - "cFunctionName": "git_stash_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to find the stash." - }, - { - "name": "callback", - "cType": "git_stash_cb", - "cppClassName": "StashCb", - "jsClassName": "StashCb", - "comment": "Callback to invoke per found stashed state. The most recent stash state will be enumerated first." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Extra parameter to callback function." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Loop over all the stashed states and issue a callback for each one.

\n" - }, - { - "cFunctionName": "git_stash_drop", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The owning repository." - }, - { - "name": "index", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "The position within the stash list. 0 points to the most recent stashed state." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "drop", - "cppFunctionName": "Drop", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, or error code", - "jsClassName": "Number" - }, - "description": "

Remove a single stashed state from the stash list.

\n" - } - ] - }, - { - "filename": "status.h", - "ignore": true, - "jsClassName": "Status", - "cppClassName": "Status", - "cType": "git_status", - "freeFunctionName": "git_status_free", - "functions": [ - { - "cFunctionName": "git_status_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "A repository object" - }, - { - "name": "callback", - "cType": "git_status_cb", - "cppClassName": "StatusCb", - "jsClassName": "StatusCb", - "comment": "The function to call on each file" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Pointer to pass through to callback function" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Gather file statuses and run a callback for each one.

\n" - }, - { - "cFunctionName": "git_status_foreach_ext", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository object" - }, - { - "name": "opts", - "cType": "const git_status_options *", - "cppClassName": "StatusOptions", - "jsClassName": "StatusOptions", - "comment": "Status options structure" - }, - { - "name": "callback", - "cType": "git_status_cb", - "cppClassName": "StatusCb", - "jsClassName": "StatusCb", - "comment": "The function to call on each file" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Pointer to pass through to callback function" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreachExt", - "cppFunctionName": "ForeachExt", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_EUSER on non-zero callback, or error code", - "jsClassName": "Number" - }, - "description": "

Gather file status information and run callbacks as requested.

\n" - }, - { - "cFunctionName": "git_status_file", - "args": [ - { - "name": "status_flags", - "cType": "unsigned int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "The status value for the file" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "A repository object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The file to retrieve status for, rooted at the repo's workdir" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "file", - "cppFunctionName": "File", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, GIT_ENOTFOUND if the file is not found in the HEAD, index, and work tree, GIT_EINVALIDPATH if `path` points at a folder, GIT_EAMBIGUOUS if \"path\" matches multiple files, -1 on other error.", - "jsClassName": "Number" - }, - "description": "

Get file status for a single file.

\n" - }, - { - "cFunctionName": "git_status_should_ignore", - "args": [ - { - "name": "ignored", - "cType": "int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Boolean returning 0 if the file is not ignored, 1 if it is" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "A repository object" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The file to check ignores for, rooted at the repo's workdir." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "shouldIgnore", - "cppFunctionName": "ShouldIgnore", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if ignore rules could be processed for the file (regardless of whether it exists or not), or an error < 0 if they could not.", - "jsClassName": "Number" - }, - "description": "

Test if the ignore rules apply to a given file.

\n" - } - ] - }, - { - "filename": "stdint.h", - "ignore": true, - "jsClassName": "Stdint", - "cppClassName": "Stdint", - "cType": "git_stdint", - "freeFunctionName": "git_stdint_free", - "functions": [] - }, - { - "filename": "strarray.h", - "ignore": true, - "jsClassName": "Strarray", - "cppClassName": "Strarray", - "cType": "git_strarray", - "freeFunctionName": "git_strarray_free", - "functions": [ - { - "cFunctionName": "git_strarray_free", - "args": [ - { - "name": "array", - "cType": "git_strarray *", - "cppClassName": "Strarray", - "jsClassName": "Strarray", - "comment": "git_strarray from which to free string data" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close a string array object

\n" - }, - { - "cFunctionName": "git_strarray_copy", - "args": [ - { - "name": "tgt", - "cType": "git_strarray *", - "cppClassName": "Strarray", - "jsClassName": "Strarray", - "isSelf": true, - "comment": "target" - }, - { - "name": "src", - "cType": "const git_strarray *", - "cppClassName": "Strarray", - "jsClassName": "Strarray", - "comment": "source" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "copy", - "cppFunctionName": "Copy", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, < 0 on allocation failure", - "jsClassName": "Number" - }, - "description": "

Copy a string array object from source to target.

\n" - } - ] - }, - { - "filename": "submodule.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h" - ], - "jsClassName": "Submodule", - "cppClassName": "GitSubmodule", - "cType": "git_submodule", - "freeFunctionName": "free", - "functions": [ - { - "cFunctionName": "git_submodule_foreach", - "args": [ - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository" - }, - { - "name": "callback", - "cType": "int (*)(git_submodule *sm, const char *name, void *payload)", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Function to be called with the name of each submodule. Return a non-zero value to terminate the iteration." - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Extra data to pass to callback" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "foreach", - "cppFunctionName": "Foreach", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, -1 on error, or non-zero return value of callback", - "jsClassName": "Number" - }, - "description": "

Iterate over all tracked submodules of a repository.

\n" - }, - { - "cFunctionName": "git_submodule_add_finalize", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "The submodule to finish adding." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addFinalize", - "cppFunctionName": "AddFinalize", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Resolve the setup of a new git submodule.

\n" - }, - { - "cFunctionName": "git_submodule_add_to_index", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "The submodule to add to the index" - }, - { - "name": "write_index", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Boolean if this should immediately write the index file. If you pass this as false, you will have to get the git_index and explicitly call `git_index_write()` on it to save the change." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "addToIndex", - "cppFunctionName": "AddToIndex", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure", - "jsClassName": "Number" - }, - "description": "

Add current submodule HEAD commit to index of superproject.

\n" - }, - { - "cFunctionName": "git_submodule_save", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "The submodule to write." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "save", - "cppFunctionName": "Save", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure.", - "jsClassName": "Number" - }, - "description": "

Write submodule settings to .gitmodules file.

\n" - }, - { - "cFunctionName": "git_submodule_owner", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "ignore": "Never make public for memory allocation reasons", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "owner", - "cppFunctionName": "Owner", - "return": { - "cType": "git_repository *", - "cppClassName": "GitRepo", - "comment": "Pointer to `git_repository`", - "jsClassName": "Repository" - }, - "description": "

Get the containing repository for a submodule.

\n" - }, - { - "cFunctionName": "git_submodule_name", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "name", - "cppFunctionName": "Name", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "Pointer to the submodule name", - "jsClassName": "String" - }, - "description": "

Get the name of submodule.

\n" - }, - { - "cFunctionName": "git_submodule_path", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "path", - "cppFunctionName": "Path", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "Pointer to the submodule path", - "jsClassName": "String" - }, - "description": "

Get the path to the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_url", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "url", - "cppFunctionName": "Url", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "Pointer to the submodule url", - "jsClassName": "String" - }, - "description": "

Get the URL for the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_set_url", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to the submodule object" - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "URL that should be used for the submodule" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setUrl", - "cppFunctionName": "SetUrl", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure", - "jsClassName": "Number" - }, - "description": "

Set the URL for the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_index_id", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "indexId", - "cppFunctionName": "IndexId", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "Pointer to git_oid or NULL if submodule is not in index.", - "jsClassName": "Oid" - }, - "description": "

Get the OID for the submodule in the index.

\n" - }, - { - "cFunctionName": "git_submodule_head_id", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "headId", - "cppFunctionName": "HeadId", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "Pointer to git_oid or NULL if submodule is not in the HEAD.", - "jsClassName": "Oid" - }, - "description": "

Get the OID for the submodule in the current HEAD tree.

\n" - }, - { - "cFunctionName": "git_submodule_wd_id", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Pointer to submodule object" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "wdId", - "cppFunctionName": "WdId", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "Pointer to git_oid or NULL if submodule is not checked out.", - "jsClassName": "Oid" - }, - "description": "

Get the OID for the submodule in the current working directory.

\n" - }, - { - "cFunctionName": "git_submodule_ignore", - "args": [], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "ignore", - "cppFunctionName": "Ignore", - "return": { - "cType": "GIT_EXTERN(", - "cppClassName": "GIT_EXTERN(" - }, - "description": "

Get the ignore rule for the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_set_ignore", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true - }, - { - "name": "ignore", - "cType": "git_submodule_ignore_t", - "cppClassName": "Uint32", - "jsClassName": "Uint32" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setIgnore", - "cppFunctionName": "SetIgnore", - "return": { - "cType": "git_submodule_ignore_t", - "cppClassName": "Uint32", - "comment": "old value for ignore", - "jsClassName": "Number" - }, - "description": "

Set the ignore rule for the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_update", - "ignore": true, - "args": [], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "update", - "cppFunctionName": "Update", - "return": { - "cType": "GIT_EXTERN(", - "cppClassName": "GIT_EXTERN(" - }, - "description": "

Get the update rule for the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_set_update", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true - }, - { - "name": "update", - "cType": "git_submodule_update_t", - "cppClassName": "Uint32", - "jsClassName": "Uint32" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setUpdate", - "cppFunctionName": "SetUpdate", - "return": { - "cType": "git_submodule_update_t", - "cppClassName": "SubmoduleUpdateT", - "comment": "old value for update" - }, - "description": "

Set the update rule for the submodule.

\n" - }, - { - "cFunctionName": "git_submodule_fetch_recurse_submodules", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "fetchRecurseSubmodules", - "cppFunctionName": "FetchRecurseSubmodules", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 if fetchRecurseSubmodules is false, 1 if true", - "jsClassName": "Number" - }, - "description": "

Read the fetchRecurseSubmodules rule for a submodule.

\n" - }, - { - "cFunctionName": "git_submodule_set_fetch_recurse_submodules", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "The submodule to modify" - }, - { - "name": "fetch_recurse_submodules", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Boolean value" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "setFetchRecurseSubmodules", - "cppFunctionName": "SetFetchRecurseSubmodules", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "old value for fetchRecurseSubmodules", - "jsClassName": "Number" - }, - "description": "

Set the fetchRecurseSubmodules rule for a submodule.

\n" - }, - { - "cFunctionName": "git_submodule_init", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "The submodule to write into the superproject config" - }, - { - "name": "overwrite", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "By default, existing entries will not be overwritten, but setting this to true forces them to be updated." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "init", - "cppFunctionName": "Init", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on failure.", - "jsClassName": "Number" - }, - "description": "

Copy submodule info into ".git/config" file.

\n" - }, - { - "cFunctionName": "git_submodule_sync", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "sync", - "cppFunctionName": "Sync", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Copy submodule remote info into submodule repo.

\n" - }, - { - "cFunctionName": "git_submodule_open", - "args": [ - { - "name": "repo", - "cType": "git_repository **", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "isReturn": true, - "comment": "Pointer to the submodule repo which was opened" - }, - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Submodule to be opened" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "open", - "cppFunctionName": "Open", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 if submodule repo could not be opened.", - "jsClassName": "Number" - }, - "description": "

Open the repository for a submodule.

\n" - }, - { - "cFunctionName": "git_submodule_reload", - "args": [ - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "reload", - "cppFunctionName": "Reload", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Reread submodule info from config, index, and HEAD.

\n" - }, - { - "cFunctionName": "git_submodule_status", - "args": [ - { - "name": "status", - "cType": "unsigned int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Combination of `GIT_SUBMODULE_STATUS` flags" - }, - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "isSelf": true, - "comment": "Submodule for which to get status" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "status", - "cppFunctionName": "Status", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on error", - "jsClassName": "Number" - }, - "description": "

Get the status for a submodule.

\n" - }, - { - "cFunctionName": "git_submodule_location", - "args": [ - { - "name": "location_status", - "cType": "unsigned int *", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Combination of first four `GIT_SUBMODULE_STATUS` flags" - }, - { - "name": "submodule", - "cType": "git_submodule *", - "cppClassName": "GitSubmodule", - "jsClassName": "Submodule", - "comment": "Submodule for which to get status" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "location", - "cppFunctionName": "Location", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success, <0 on error", - "jsClassName": "Number" - }, - "description": "

Get the locations of submodule information.

\n" - } - ] - }, - { - "filename": "tag.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h", - "../include/object.h", - "../include/signature.h" - ], - "jsClassName": "Tag", - "cppClassName": "GitTag", - "cType": "git_tag", - "freeFunctionName": "git_tag_free", - "functions": [ - { - "cFunctionName": "git_tag_free", - "args": [ - { - "name": "tag", - "cType": "git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "comment": "the tag to close" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open tag

\n" - }, - { - "cFunctionName": "git_tag_id", - "args": [ - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "object identity for the tag.", - "jsClassName": "Oid" - }, - "description": "

Get the id of a tag.

\n" - }, - { - "cFunctionName": "git_tag_target", - "args": [ - { - "name": "target_out", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "pointer where to store the target" - }, - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getTarget", - "cppFunctionName": "GetTarget", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Get the tagged object of a tag

\n" - }, - { - "cFunctionName": "git_tag_target_id", - "args": [ - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "targetId", - "cppFunctionName": "TargetId", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "pointer to the OID", - "jsClassName": "Oid" - }, - "description": "

Get the OID of the tagged object of a tag

\n" - }, - { - "cFunctionName": "git_tag_target_type", - "args": [ - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "targetType", - "cppFunctionName": "TargetType", - "return": { - "cType": "git_otype", - "cppClassName": "Int32", - "comment": "type of the tagged object", - "jsClassName": "Number" - }, - "description": "

Get the type of a tag's tagged object

\n" - }, - { - "cFunctionName": "git_tag_name", - "args": [ - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "name", - "cppFunctionName": "Name", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "name of the tag", - "jsClassName": "String" - }, - "description": "

Get the name of a tag

\n" - }, - { - "cFunctionName": "git_tag_tagger", - "args": [ - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "tagger", - "cppFunctionName": "Tagger", - "return": { - "cType": "const git_signature *", - "cppClassName": "GitSignature", - "copy": "git_signature_dup", - "comment": "reference to the tag's author or NULL when unspecified", - "jsClassName": "Signature" - }, - "description": "

Get the tagger (author) of a tag

\n" - }, - { - "cFunctionName": "git_tag_message", - "args": [ - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "isSelf": true, - "comment": "a previously loaded tag." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "message", - "cppFunctionName": "Message", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "message of the tag or NULL when unspecified", - "jsClassName": "String" - }, - "description": "

Get the message of a tag

\n" - }, - { - "cFunctionName": "git_tag_create_frombuffer", - "args": [ - { - "name": "oid", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "Pointer where to store the OID of the newly created tag" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository where to store the tag" - }, - { - "name": "buffer", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Raw tag data" - }, - { - "name": "force", - "cType": "int", - "cppClassName": "Int32", - "jsClassName": "Number", - "comment": "Overwrite existing tags" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "createFrombuffer", - "cppFunctionName": "CreateFrombuffer", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Create a new tag in the repository from a buffer

\n" - }, - { - "cFunctionName": "git_tag_peel", - "args": [ - { - "name": "tag_target_out", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "Pointer to the peeled git_object" - }, - { - "name": "tag", - "cType": "const git_tag *", - "cppClassName": "GitTag", - "jsClassName": "Tag", - "comment": "_target_out Pointer to the peeled git_object" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "peel", - "cppFunctionName": "Peel", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Recursively peel a tag until a non tag git_object is found

\n" - } - ] - }, - { - "filename": "threads.h", - "dependencies": [], - "jsClassName": "Threads", - "cppClassName": "GitThreads", - "functions": [ - { - "cFunctionName": "git_threads_init", - "args": [], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "init", - "cppFunctionName": "Init", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Init the threading system.

\n" - }, - { - "cFunctionName": "git_threads_shutdown", - "args": [], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "shutdown", - "cppFunctionName": "Shutdown", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Shutdown the threading system.

\n" - } - ] - }, - { - "filename": "trace.h", - "ignore": true, - "jsClassName": "Trace", - "cppClassName": "Trace", - "cType": "git_trace", - "freeFunctionName": "git_trace_free", - "functions": [ - { - "cFunctionName": "git_trace_set", - "args": [ - { - "name": "level", - "cType": "git_trace_level_t", - "cppClassName": "TraceLevelT", - "jsClassName": "TraceLevelT", - "comment": "Level to set tracing to" - }, - { - "name": "cb", - "cType": "git_trace_callback", - "cppClassName": "TraceCallback", - "jsClassName": "TraceCallback", - "comment": "Function to call with trace data" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "set", - "cppFunctionName": "Set", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Sets the system tracing configuration to the specified level with the\nspecified callback. When system events occur at a level equal to, or\nlower than, the given level they will be reported to the given callback.

\n" - } - ] - }, - { - "filename": "transport.h", - "ignore": true, - "jsClassName": "Transport", - "cppClassName": "Transport", - "cType": "git_transport", - "freeFunctionName": "git_transport_free", - "functions": [ - { - "cFunctionName": "git_cred_userpass_plaintext_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_cred **", - "cppClassName": "Cred", - "jsClassName": "Cred", - "comment": "The newly created credential object." - }, - { - "name": "username", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The username of the credential." - }, - { - "name": "password", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The password of the credential." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitCredUserpassPlaintextNew", - "cppFunctionName": "GitCredUserpassPlaintextNew", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 for success or an error code for failure", - "jsClassName": "Number" - }, - "description": "

Creates a new plain-text username and password credential object.\nThe supplied credential parameter will be internally duplicated.

\n" - }, - { - "cFunctionName": "git_transport_new", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_transport **", - "cppClassName": "Transport", - "jsClassName": "Transport", - "comment": "The newly created transport (out)" - }, - { - "name": "owner", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "The git_remote which will own this transport" - }, - { - "name": "url", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "The URL to connect to" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "new", - "cppFunctionName": "New", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Function to use to create a transport from a URL. The transport database\nis scanned to find a transport that implements the scheme of the URI (i.e.\ngit:// or http://) and a transport object is returned to the caller.

\n" - }, - { - "cFunctionName": "git_transport_dummy", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_transport **", - "cppClassName": "Transport", - "jsClassName": "Transport", - "comment": "The newly created transport (out)" - }, - { - "name": "owner", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "The git_remote which will own this transport" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "You must pass NULL for this parameter." - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "dummy", - "cppFunctionName": "Dummy", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create an instance of the dummy transport.

\n" - }, - { - "cFunctionName": "git_transport_local", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_transport **", - "cppClassName": "Transport", - "jsClassName": "Transport", - "comment": "The newly created transport (out)" - }, - { - "name": "owner", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "The git_remote which will own this transport" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "You must pass NULL for this parameter." - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "local", - "cppFunctionName": "Local", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create an instance of the local transport.

\n" - }, - { - "cFunctionName": "git_transport_smart", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_transport **", - "cppClassName": "Transport", - "jsClassName": "Transport", - "comment": "The newly created transport (out)" - }, - { - "name": "owner", - "cType": "git_remote *", - "cppClassName": "GitRemote", - "jsClassName": "Remote", - "comment": "The git_remote which will own this transport" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "A pointer to a git_smart_subtransport_definition" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "smart", - "cppFunctionName": "Smart", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create an instance of the smart transport.

\n" - }, - { - "cFunctionName": "git_smart_subtransport_http", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_smart_subtransport **", - "cppClassName": "SmartSubtransport", - "jsClassName": "SmartSubtransport", - "comment": "The newly created subtransport" - }, - { - "name": "owner", - "cType": "git_transport*", - "cppClassName": "Transport*", - "jsClassName": "Transport*", - "comment": "The smart transport to own this subtransport" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitSmartSubtransportHttp", - "cppFunctionName": "GitSmartSubtransportHttp", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create an instance of the http subtransport. This subtransport\nalso supports https. On Win32, this subtransport may be implemented\nusing the WinHTTP library.

\n" - }, - { - "cFunctionName": "git_smart_subtransport_git", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_smart_subtransport **", - "cppClassName": "SmartSubtransport", - "jsClassName": "SmartSubtransport", - "comment": "The newly created subtransport" - }, - { - "name": "owner", - "cType": "git_transport*", - "cppClassName": "Transport*", - "jsClassName": "Transport*", - "comment": "The smart transport to own this subtransport" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "gitSmartSubtransportGit", - "cppFunctionName": "GitSmartSubtransportGit", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Create an instance of the git subtransport.

\n" - } - ] - }, - { - "filename": "tree_entry.h", - "dependencies": [ - "../include/oid.h", - "../include/repo.h", - "../include/object.h" - ], - "jsClassName": "TreeEntry", - "cppClassName": "GitTreeEntry", - "cType": "git_tree_entry", - "freeFunctionName": "git_tree_entry_free", - "functions": [ - { - "cFunctionName": "git_tree_entry_dup", - "args": [ - { - "name": "entry", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "A tree entry to duplicate" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "dup", - "cppFunctionName": "Dup", - "return": { - "cType": "git_tree_entry *", - "cppClassName": "GitTreeEntry", - "comment": "a copy of the original entry or NULL on error (alloc failure)", - "jsClassName": "TreeEntry" - }, - "description": "

Duplicate a tree entry

\n" - }, - { - "cFunctionName": "git_tree_entry_free", - "args": [ - { - "name": "entry", - "cType": "git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "The entry to free" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free a user-owned tree entry

\n" - }, - { - "cFunctionName": "git_tree_entry_name", - "args": [ - { - "name": "entry", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "a tree entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "name", - "cppFunctionName": "Name", - "return": { - "cType": "const char *", - "cppClassName": "String", - "comment": "the name of the file", - "jsClassName": "String" - }, - "description": "

Get the filename of a tree entry

\n" - }, - { - "cFunctionName": "git_tree_entry_id", - "args": [ - { - "name": "entry", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "a tree entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "the oid of the object", - "jsClassName": "Oid" - }, - "description": "

Get the id of the object pointed by the entry

\n" - }, - { - "cFunctionName": "git_tree_entry_type", - "args": [ - { - "name": "entry", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "a tree entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "type", - "cppFunctionName": "Type", - "return": { - "cType": "git_otype", - "cppClassName": "Number", - "comment": "the type of the pointed object", - "jsClassName": "Number" - }, - "description": "

Get the type of the object pointed by the entry

\n" - }, - { - "cFunctionName": "git_tree_entry_filemode", - "args": [ - { - "name": "entry", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "a tree entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "filemode", - "cppFunctionName": "filemode", - "return": { - "cType": "git_filemode_t", - "cppClassName": "Number", - "comment": "filemode as an integer", - "jsClassName": "Number" - }, - "description": "

Get the UNIX file attributes of a tree entry

\n" - }, - { - "cFunctionName": "git_tree_entry_cmp", - "args": [ - { - "name": "e1", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "first tree entry" - }, - { - "name": "e2", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "comment": "second tree entry" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "compare", - "cppFunctionName": "Compare", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "<0 if e1 is before e2, 0 if e1 == e2, >0 if e1 is after e2", - "jsClassName": "Number" - }, - "description": "

Compare two tree entries

\n" - }, - { - "cFunctionName": "git_tree_entry_to_object", - "args": [ - { - "name": "object_out", - "cType": "git_object **", - "cppClassName": "GitObject", - "jsClassName": "Object", - "isReturn": true, - "comment": "pointer to the converted object" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "repository where to lookup the pointed object" - }, - { - "name": "entry", - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "isSelf": true, - "comment": "a tree entry" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getObject", - "cppFunctionName": "GetObject", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Convert a tree entry to the git_object it points too.

\n" - } - ] - }, - { - "filename": "tree.h", - "dependencies": [ - "../include/repo.h", - "../include/oid.h", - "../include/tree_entry.h", - "../include/diff_list.h", - "../include/diff_options.h", - "../include/tree_builder.h", - "../include/index.h" - ], - "jsClassName": "Tree", - "cppClassName": "GitTree", - "cType": "git_tree", - "freeFunctionName": "git_tree_free", - "functions": [ - { - "cFunctionName": "git_tree_free", - "args": [ - { - "name": "tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "comment": "The tree to close" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "free", - "cppFunctionName": "Free", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Close an open tree

\n" - }, - { - "cFunctionName": "git_tree_id", - "args": [ - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "a previously loaded tree." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "oid", - "cppFunctionName": "Oid", - "return": { - "cType": "const git_oid *", - "cppClassName": "GitOid", - "copy": "git_oid_dup", - "comment": "object identity for the tree.", - "jsClassName": "Oid" - }, - "description": "

Get the id of a tree.

\n" - }, - { - "cFunctionName": "git_tree_owner", - "args": [ - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "A previously loaded tree." - } - ], - "ignore": "Never make public for memory allocation reasons", - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "owner", - "cppFunctionName": "Owner", - "return": { - "cType": "git_repository *", - "cppClassName": "GitRepo", - "comment": "Repository that contains this tree.", - "jsClassName": "Repository" - }, - "description": "

Get the repository that contains the tree.

\n" - }, - { - "cFunctionName": "git_tree_entrycount", - "args": [ - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "a previously loaded tree." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "size_t", - "cppClassName": "Uint32", - "comment": "the number of entries in the tree", - "jsClassName": "Number" - }, - "description": "

Get the number of entries listed in a tree

\n" - }, - { - "cFunctionName": "git_tree_entry_byname", - "args": [ - { - "name": "tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "a previously loaded tree." - }, - { - "name": "filename", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "the filename of the desired entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "entryByName", - "cppFunctionName": "EntryByName", - "return": { - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "copy": "git_tree_entry_dup", - "comment": "the tree entry; NULL if not found", - "jsClassName": "TreeEntry" - }, - "description": "

Lookup a tree entry by its filename

\n" - }, - { - "cFunctionName": "git_tree_entry_byindex", - "args": [ - { - "name": "tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "a previously loaded tree." - }, - { - "name": "idx", - "cType": "size_t", - "cppClassName": "Uint32", - "jsClassName": "Number", - "comment": "the position in the entry list" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "entryByIndex", - "cppFunctionName": "EntryByIndex", - "return": { - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "copy": "git_tree_entry_dup", - "comment": "the tree entry; NULL if not found", - "jsClassName": "TreeEntry" - }, - "description": "

Lookup a tree entry by its position in the tree

\n" - }, - { - "cFunctionName": "git_tree_entry_byoid", - "args": [ - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "a previously loaded tree." - }, - { - "name": "oid", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "the sha being looked for" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "entryByOid", - "cppFunctionName": "EntryByOid", - "return": { - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "copy": "git_tree_entry_dup", - "comment": "the tree entry; NULL if not found", - "jsClassName": "TreeEntry" - }, - "description": "

Lookup a tree entry by SHA value.

\n" - }, - { - "cFunctionName": "git_tree_entry_bypath", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_tree_entry **", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "comment": "Pointer where to store the tree entry" - }, - { - "name": "root", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "Previously loaded tree which is the root of the relative path" - }, - { - "name": "path", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Path to the contained entry" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "getEntry", - "cppFunctionName": "GetEntry", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; GIT_ENOTFOUND if the path does not exist", - "jsClassName": "Number" - }, - "description": "

Retrieve a tree entry contained in a tree or in any of its subtrees,\ngiven its relative path.

\n" - }, - { - "cFunctionName": "git_treebuilder_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_treebuilder **", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "comment": "Pointer where to store the tree builder" - }, - { - "name": "source", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "Source tree to initialize the builder (optional)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "builder", - "cppFunctionName": "Builder", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Create a new tree builder.

\n" - }, - { - "cFunctionName": "git_tree_walk", - "args": [ - { - "name": "tree", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "The tree to walk" - }, - { - "name": "mode", - "cType": "git_treewalk_mode", - "cppClassName": "TreewalkMode", - "jsClassName": "TreewalkMode", - "comment": "Traversal mode (pre or post-order)" - }, - { - "name": "callback", - "cType": "git_treewalk_cb", - "cppClassName": "TreewalkCb", - "jsClassName": "TreewalkCb", - "comment": "Function to call on each tree entry" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Opaque pointer to be passed on each callback" - } - ], - "ignore": true, - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "walk", - "cppFunctionName": "Walk", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Traverse the entries in a tree and its subtrees in post or pre order.

\n" - }, - { - "cFunctionName": "git_diff_tree_to_tree", - "args": [ - { - "name": "diff", - "cType": "git_diff_list **", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isReturn": true, - "comment": "Output pointer to a git_diff_list pointer to be allocated." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository containing the trees." - }, - { - "name": "old_tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "A git_tree object to diff from, or NULL for empty tree." - }, - { - "name": "new_tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "comment": "A git_tree object to diff to, or NULL for empty tree." - }, - { - "name": "opts", - "cType": "const git_diff_options *", - "cppClassName": "GitDiffOptions", - "jsClassName": "DiffOptions", - "isOptional": true, - "comment": "Structure with options to influence diff or NULL for defaults." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "diffTree", - "cppFunctionName": "DiffTree", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create a diff list with the difference between two tree objects.

\n" - }, - { - "cFunctionName": "git_diff_tree_to_index", - "args": [ - { - "name": "diff", - "cType": "git_diff_list **", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isReturn": true, - "comment": "Output pointer to a git_diff_list pointer to be allocated." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository containing the tree and index." - }, - { - "name": "old_tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "A git_tree object to diff from, or NULL for empty tree." - }, - { - "name": "index", - "cType": "git_index *", - "cppClassName": "GitIndex", - "jsClassName": "Index", - "isOptional": true, - "comment": "The index to diff with; repo index used if NULL." - }, - { - "name": "opts", - "cType": "const git_diff_options *", - "cppClassName": "GitDiffOptions", - "jsClassName": "DiffOptions", - "isOptional": true, - "comment": "Structure with options to influence diff or NULL for defaults." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "diffIndex", - "cppFunctionName": "DiffIndex", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create a diff list between a tree and repository index.

\n" - }, - { - "cFunctionName": "git_diff_tree_to_workdir", - "args": [ - { - "name": "diff", - "cType": "git_diff_list **", - "cppClassName": "GitDiffList", - "jsClassName": "DiffList", - "isReturn": true, - "comment": "A pointer to a git_diff_list pointer that will be allocated." - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "The repository containing the tree." - }, - { - "name": "old_tree", - "cType": "git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isSelf": true, - "comment": "A git_tree object to diff from, or NULL for empty tree." - }, - { - "name": "opts", - "cType": "const git_diff_options *", - "cppClassName": "GitDiffOptions", - "jsClassName": "DiffOptions", - "isOptional": true, - "comment": "Structure with options to influence diff or NULL for defaults." - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "diffWorkDir", - "cppFunctionName": "DiffWorkDir", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Create a diff list between a tree and the working directory.

\n" - } - ] - }, - { - "filename": "tree_builder.h", - "dependencies": [ - "../include/repo.h", - "../include/oid.h", - "../include/tree_entry.h", - "../include/tree.h", - "../include/diff_list.h", - "../include/diff_options.h", - "../include/index.h" - ], - "jsClassName": "TreeBuilder", - "cppClassName": "GitTreeBuilder", - "cType": "git_treebuilder", - "freeFunctionName": "git_treebuilder_free", - "functions": [ - { - "cFunctionName": "git_treebuilder_create", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "git_treebuilder **", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "comment": "Pointer where to store the tree builder" - }, - { - "name": "source", - "cType": "const git_tree *", - "cppClassName": "GitTree", - "jsClassName": "Tree", - "isOptional": true, - "comment": "Source tree to initialize the builder (optional)" - } - ], - "isAsync": false, - "isConstructorMethod": true, - "isPrototypeMethod": false, - "jsFunctionName": "create", - "cppFunctionName": "Create", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 on success; error code otherwise", - "jsClassName": "Number" - }, - "description": "

Create a new tree builder.

\n" - }, - { - "cFunctionName": "git_treebuilder_clear", - "args": [ - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "comment": "Builder to clear" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "clear", - "cppFunctionName": "Clear", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Clear all the entires in the builder

\n" - }, - { - "cFunctionName": "git_treebuilder_entrycount", - "args": [ - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "isSelf": true, - "comment": "a previously loaded treebuilder." - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "size", - "cppFunctionName": "Size", - "return": { - "cType": "unsigned int", - "cppClassName": "Uint32", - "comment": "the number of entries in the treebuilder", - "jsClassName": "Number" - }, - "description": "

Get the number of entries listed in a treebuilder

\n" - }, - { - "cFunctionName": "git_treebuilder_free", - "args": [ - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "comment": "Builder to free" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "isFree": true, - "jsFunctionName": "treebuilderFree", - "cppFunctionName": "GitTreebuilderFree", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Free a tree builder

\n" - }, - { - "cFunctionName": "git_treebuilder_get", - "args": [ - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "isSelf": true, - "comment": "Tree builder" - }, - { - "name": "filename", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Name of the entry" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "get", - "cppFunctionName": "Get", - "return": { - "cType": "const git_tree_entry *", - "cppClassName": "GitTreeEntry", - "copy": "git_tree_entry_dup", - "comment": "pointer to the entry; NULL if not found", - "jsClassName": "TreeEntry" - }, - "description": "

Get an entry from the builder from its filename

\n" - }, - { - "cFunctionName": "git_treebuilder_insert", - "args": [ - { - "name": "out", - "isReturn": true, - "cType": "const git_tree_entry **", - "cppClassName": "GitTreeEntry", - "jsClassName": "TreeEntry", - "copy": "git_tree_entry_dup", - "comment": "Pointer to store the entry (optional)" - }, - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "isSelf": true, - "comment": "Tree builder" - }, - { - "name": "filename", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Filename of the entry" - }, - { - "name": "id", - "cType": "const git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "comment": "SHA1 oid of the entry" - }, - { - "name": "filemode", - "cType": "git_filemode_t", - "cppClassName": "Number", - "jsClassName": "Number", - "comment": "Folder attributes of the entry. This parameter must be valued with one of the following entries: 0040000, 0100644, 0100755, 0120000 or 0160000.", - "additionalCast": "(int)" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "insert", - "cppFunctionName": "Insert", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "comment": "0 or an error code", - "jsClassName": "Number" - }, - "description": "

Add or update an entry to the builder

\n" - }, - { - "cFunctionName": "git_treebuilder_remove", - "args": [ - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "isSelf": true, - "comment": "Tree builder" - }, - { - "name": "filename", - "cType": "const char *", - "cppClassName": "String", - "jsClassName": "String", - "comment": "Filename of the entry to remove" - } - ], - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "gitTreebuilderRemove", - "cppFunctionName": "GitTreebuilderRemove", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number" - }, - "description": "

Remove an entry from the builder by its filename

\n" - }, - { - "cFunctionName": "git_treebuilder_filter", - "args": [ - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "isSelf": true, - "comment": "Tree builder" - }, - { - "name": "filter", - "cType": "git_treebuilder_filter_cb", - "cppClassName": "TreebuilderFilterCb", - "jsClassName": "TreebuilderFilterCb", - "comment": "Callback to filter entries" - }, - { - "name": "payload", - "cType": "void *", - "cppClassName": "void", - "jsClassName": "void", - "comment": "Extra data to pass to filter" - } - ], - "ignore": true, - "isAsync": false, - "isConstructorMethod": false, - "isPrototypeMethod": false, - "jsFunctionName": "filter", - "cppFunctionName": "Filter", - "return": { - "cType": "void", - "cppClassName": "void", - "jsClassName": "void" - }, - "description": "

Filter the entries in the tree

\n" - }, - { - "cFunctionName": "git_treebuilder_write", - "args": [ - { - "name": "id", - "cType": "git_oid *", - "cppClassName": "GitOid", - "jsClassName": "Oid", - "shouldAlloc": true, - "isReturn": true, - "comment": "Pointer to store the OID of the newly written tree" - }, - { - "name": "repo", - "cType": "git_repository *", - "cppClassName": "GitRepo", - "jsClassName": "Repository", - "comment": "Repository in which to store the object" - }, - { - "name": "bld", - "cType": "git_treebuilder *", - "cppClassName": "GitTreeBuilder", - "jsClassName": "TreeBuilder", - "isSelf": true, - "comment": "Tree builder to write" - } - ], - "isAsync": true, - "isConstructorMethod": false, - "isPrototypeMethod": true, - "jsFunctionName": "write", - "cppFunctionName": "Write", - "return": { - "cType": "int", - "cppClassName": "Int32", - "isErrorCode": true, - "jsClassName": "Number", - "comment": "0 or an error code" - }, - "description": "

Write the contents of the tree builder as a tree object

\n" - } - ] - } -] diff --git a/doc/Theme.css b/doc/Theme.css deleted file mode 100644 index 111dd6573..000000000 --- a/doc/Theme.css +++ /dev/null @@ -1,796 +0,0 @@ -@import('http://fonts.googleapis.com/css?family=EB+Garamond'); - -body { - background-color: #FFFFFF; - font-family: Georgia, sans-serif; - font-size: 14px; - margin: 40px; -} - -a:link, -a:visited { color: #900000; text-decoration: none } -a:hover { color: #900000; text-decoration: underline } -a:active { color: #FF0000; text-decoration: underline } - -td { - vertical-align: top } - -img { border: 0; } - - -/* - Comment out this line to use web-style paragraphs (blank line between - paragraphs, no indent) instead of print-style paragraphs (no blank line, - indented.) -*/ -p { - text-indent: 5ex; margin: 0 } - - -/* Opera doesn't break with just wbr, but will if you add this. */ -.Opera wbr:after { - content: "\00200B"; - } - - -/* Blockquotes are used as containers for things that may need to scroll. */ -blockquote { - padding: 0; - margin: 0; - overflow: auto; - } - - -.Firefox1 blockquote { - padding-bottom: .5em; - } - -/* Turn off scrolling when printing. */ -@media print { - blockquote { - overflow: visible; - } - .IE blockquote { - width: auto; - } - } - - - -#Menu { - padding: 10px 0 0 0; - } -.ContentPage #Menu, -.IndexPage #Menu { - position: absolute; - top: 0; - left: 0; - width: 31ex; - overflow: hidden; - } -.ContentPage .Firefox #Menu, -.IndexPage .Firefox #Menu { - width: 27ex; - } - - - .MTitle { - font-size: 16pt; font-weight: bold; font-variant: small-caps; - text-align: center; - padding: 5px 10px 15px 10px; - border-bottom: 1px dotted #000000; - margin-bottom: 15px } - - .MSubTitle { - font-size: 9pt; font-weight: normal; font-variant: normal; - margin-top: 1ex; margin-bottom: 5px } - - - .MEntry a:link, - .MEntry a:hover, - .MEntry a:visited { color: #606060; margin-right: 0 } - .MEntry a:active { color: #A00000; margin-right: 0 } - - - .MGroup { - font-variant: small-caps; font-weight: bold; - margin: 1em 0 1em 10px; - } - - .MGroupContent { - font-variant: normal; font-weight: normal } - - .MGroup a:link, - .MGroup a:hover, - .MGroup a:visited { color: #545454; margin-right: 10px } - .MGroup a:active { color: #A00000; margin-right: 10px } - - - .MFile, - .MText, - .MLink, - .MIndex { - padding: 1px 17px 2px 10px; - margin: .25em 0 .25em 0; - } - - .MText { - font-size: 8pt; font-style: italic } - - .MLink { - font-style: italic } - - #MSelected { - color: #000000; background-color: #FFFFFF; - /* Replace padding with border. */ - padding: 0 10px 0 10px; - border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000; - margin-right: 5px; - } - - /* Close off the left side when its in a group. */ - .MGroup #MSelected { - padding-left: 9px; border-left-width: 1px } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Firefox #MSelected { - -moz-border-radius-topright: 10px; - -moz-border-radius-bottomright: 10px } - .Firefox .MGroup #MSelected { - -moz-border-radius-topleft: 10px; - -moz-border-radius-bottomleft: 10px } - - - #MSearchPanel { - padding: 0px 6px; - margin: .25em 0; - } - - - #MSearchField { - font: italic 9pt Verdana, sans-serif; - color: #606060; - background-color: #E8E8E8; - border: none; - padding: 2px 4px; - width: 100%; - } - /* Only Opera gets it right. */ - .Firefox #MSearchField, - .IE #MSearchField, - .Safari #MSearchField { - width: 94%; - } - .Opera9 #MSearchField, - .Konqueror #MSearchField { - width: 97%; - } - .FramedMenuPage .Firefox #MSearchField, - .FramedMenuPage .Safari #MSearchField, - .FramedMenuPage .Konqueror #MSearchField { - width: 98%; - } - - /* Firefox doesn't do this right in frames without #MSearchPanel added on. - It's presence doesn't hurt anything other browsers. */ - #MSearchPanel.MSearchPanelInactive:hover #MSearchField { - background-color: #FFFFFF; - border: 1px solid #C0C0C0; - padding: 1px 3px; - } - .MSearchPanelActive #MSearchField { - background-color: #FFFFFF; - border: 1px solid #C0C0C0; - font-style: normal; - padding: 1px 3px; - } - - #MSearchType { - visibility: hidden; - font: 8pt Verdana, sans-serif; - width: 98%; - padding: 0; - border: 1px solid #C0C0C0; - } - .MSearchPanelActive #MSearchType, - /* As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */ - #MSearchPanel.MSearchPanelInactive:hover #MSearchType, - #MSearchType:focus { - visibility: visible; - color: #606060; - } - #MSearchType option#MSearchEverything { - font-weight: bold; - } - - .Opera8 .MSearchPanelInactive:hover, - .Opera8 .MSearchPanelActive { - margin-left: -1px; - } - - - iframe#MSearchResults { - width: 60ex; - height: 15em; - } - #MSearchResultsWindow { - display: none; - position: absolute; - left: 0; top: 0; - border: 1px solid #000000; - background-color: #E8E8E8; - } - #MSearchResultsWindowClose { - font-weight: bold; - font-size: 8pt; - display: block; - padding: 2px 5px; - } - #MSearchResultsWindowClose:link, - #MSearchResultsWindowClose:visited { - color: #000000; - text-decoration: none; - } - #MSearchResultsWindowClose:active, - #MSearchResultsWindowClose:hover { - color: #800000; - text-decoration: none; - background-color: #F4F4F4; - } - - - - -#Content { - padding-bottom: 15px; - } - -.ContentPage #Content { - border-width: 0 0 1px 1px; - border-style: solid; - border-color: #000000; - background-color: #FFFFFF; - font-size: 9pt; /* To make 31ex match the menu's 31ex. */ - margin-left: 31ex; - } -.ContentPage .Firefox #Content { - margin-left: 27ex; - } - - - - .CTopic { - font-size: 10pt; - margin-bottom: 3em; - } - - - .CTitle { - font-size: 12pt; font-weight: bold; - border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0; - margin: 0 15px .5em 15px } - - .CGroup .CTitle { - font-size: 16pt; font-variant: small-caps; - padding-left: 15px; padding-right: 15px; - border-width: 0 0 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CClass .CTitle, - .CInterface .CTitle, - .CDatabase .CTitle, - .CDatabaseTable .CTitle, - .CSection .CTitle { - font-size: 18pt; - color: #FFFFFF; background-color: #A0A0A0; - padding: 10px 15px 10px 15px; - border-width: 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - #MainTopic .CTitle { - font-size: 20pt; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CBody { - margin-left: 15px; margin-right: 15px } - - - .CToolTip { - position: absolute; visibility: hidden; - left: 0; top: 0; - background-color: #FFFFE0; - padding: 5px; - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000; - font-size: 8pt; - } - - .Opera .CToolTip { - max-width: 98%; - } - - /* Scrollbars would be useless. */ - .CToolTip blockquote { - overflow: hidden; - } - .IE6 .CToolTip blockquote { - overflow: visible; - } - - .CHeading { - font-weight: bold; font-size: 10pt; - margin: 1.5em 0 .5em 0; - } - - .CBody pre { - font: 10pt "Courier New", Courier, monospace; - background-color: #FCFCFC; - margin: 1em 35px; - padding: 10px 15px 10px 10px; - border-color: #E0E0E0 #E0E0E0 #E0E0E0 #E4E4E4; - border-width: 1px 1px 1px 6px; - border-style: dashed dashed dashed solid; - } - - .CBody ul { - /* I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever. - Reapply it here as padding. */ - padding-left: 15px; padding-right: 15px; - margin: .5em 5ex .5em 5ex; - } - - .CDescriptionList { - margin: .5em 5ex 0 5ex } - - .CDLEntry { - font: 10pt "Courier New", Courier, monospace; color: #808080; - padding-bottom: .25em; - white-space: nowrap } - - .CDLDescription { - font-size: 10pt; /* For browsers that don't inherit correctly, like Opera 5. */ - padding-bottom: .5em; padding-left: 5ex } - - - .CTopic img { - text-align: center; - display: block; - margin: 1em auto; - } - .CImageCaption { - font-variant: small-caps; - font-size: 8pt; - color: #808080; - text-align: center; - position: relative; - top: 1em; - } - - .CImageLink { - color: #808080; - font-style: italic; - } - a.CImageLink:link, - a.CImageLink:visited, - a.CImageLink:hover { color: #808080 } - - - - - -.Prototype { - font: 10pt "Courier New", Courier, monospace; - padding: 5px 3ex; - border-width: 1px; border-style: solid; - margin: 0 5ex 1.5em 5ex; - } - - .Prototype td { - font-size: 10pt; - } - - .PDefaultValue, - .PDefaultValuePrefix, - .PTypePrefix { - color: #8F8F8F; - } - .PTypePrefix { - text-align: right; - } - .PAfterParameters { - vertical-align: bottom; - } - - .IE .Prototype table { - padding: 0; - } - - .CFunction .Prototype { - background-color: #F4F4F4; border-color: #D0D0D0 } - .CProperty .Prototype { - background-color: #F4F4FF; border-color: #C0C0E8 } - .CVariable .Prototype { - background-color: #FFFFF0; border-color: #E0E0A0 } - - .CClass .Prototype { - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0; - background-color: #F4F4F4; - } - .CInterface .Prototype { - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0; - background-color: #F4F4FF; - } - - .CDatabaseIndex .Prototype, - .CConstant .Prototype { - background-color: #D0D0D0; border-color: #000000 } - .CType .Prototype, - .CEnumeration .Prototype { - background-color: #FAF0F0; border-color: #E0B0B0; - } - .CDatabaseTrigger .Prototype, - .CEvent .Prototype, - .CDelegate .Prototype { - background-color: #F0FCF0; border-color: #B8E4B8 } - - .CToolTip .Prototype { - margin: 0 0 .5em 0; - white-space: nowrap; - } - - - - - -.Summary { - margin: 1.5em 5ex 0 5ex } - - .STitle { - font-size: 12pt; font-weight: bold; - margin-bottom: .5em } - - - .SBorder { - background-color: #FFFFF0; - padding: 15px; - border: 1px solid #C0C060 } - - /* In a frame IE 6 will make them too long unless you set the width to 100%. Without frames it will be correct without a width - or slightly too long (but not enough to scroll) with a width. This arbitrary weirdness simply astounds me. IE 7 has the same - problem with frames, haven't tested it without. */ - .FramedContentPage .IE .SBorder { - width: 100% } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Firefox .SBorder { - -moz-border-radius: 20px } - - - .STable { - font-size: 9pt; width: 100% } - - .SEntry { - width: 30% } - .SDescription { - width: 70% } - - - .SMarked { - background-color: #F8F8D8 } - - .SDescription { padding-left: 2ex } - .SIndent1 .SEntry { padding-left: 1.5ex } .SIndent1 .SDescription { padding-left: 3.5ex } - .SIndent2 .SEntry { padding-left: 3.0ex } .SIndent2 .SDescription { padding-left: 5.0ex } - .SIndent3 .SEntry { padding-left: 4.5ex } .SIndent3 .SDescription { padding-left: 6.5ex } - .SIndent4 .SEntry { padding-left: 6.0ex } .SIndent4 .SDescription { padding-left: 8.0ex } - .SIndent5 .SEntry { padding-left: 7.5ex } .SIndent5 .SDescription { padding-left: 9.5ex } - - .SDescription a { color: #800000} - .SDescription a:active { color: #A00000 } - - .SGroup td { - padding-top: .5em; padding-bottom: .25em } - - .SGroup .SEntry { - font-weight: bold; font-variant: small-caps } - - .SGroup .SEntry a { color: #800000 } - .SGroup .SEntry a:active { color: #F00000 } - - - .SMain td, - .SClass td, - .SDatabase td, - .SDatabaseTable td, - .SSection td { - font-size: 10pt; - padding-bottom: .25em } - - .SClass td, - .SDatabase td, - .SDatabaseTable td, - .SSection td { - padding-top: 1em } - - .SMain .SEntry, - .SClass .SEntry, - .SDatabase .SEntry, - .SDatabaseTable .SEntry, - .SSection .SEntry { - font-weight: bold; - } - - .SMain .SEntry a, - .SClass .SEntry a, - .SDatabase .SEntry a, - .SDatabaseTable .SEntry a, - .SSection .SEntry a { color: #000000 } - - .SMain .SEntry a:active, - .SClass .SEntry a:active, - .SDatabase .SEntry a:active, - .SDatabaseTable .SEntry a:active, - .SSection .SEntry a:active { color: #A00000 } - - - - - -.ClassHierarchy { - margin: 0 15px 1em 15px } - - .CHEntry { - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0; - margin-bottom: 3px; - padding: 2px 2ex; - font-size: 10pt; - background-color: #F4F4F4; color: #606060; - } - - .Firefox .CHEntry { - -moz-border-radius: 4px; - } - - .CHCurrent .CHEntry { - font-weight: bold; - border-color: #000000; - color: #000000; - } - - .CHChildNote .CHEntry { - font-style: italic; - font-size: 8pt; - } - - .CHIndent { - margin-left: 3ex; - } - - .CHEntry a:link, - .CHEntry a:visited, - .CHEntry a:hover { - color: #606060; - } - .CHEntry a:active { - color: #800000; - } - - - - - -#Index { - background-color: #FFFFFF; - } - -/* As opposed to .PopupSearchResultsPage #Index */ -.IndexPage #Index, -.FramedIndexPage #Index, -.FramedSearchResultsPage #Index { - padding: 15px; - } - -.IndexPage #Index { - border-width: 0 0 1px 1px; - border-style: solid; - border-color: #000000; - font-size: 9pt; /* To make 27ex match the menu's 27ex. */ - margin-left: 27ex; - } - - - .IPageTitle { - font-size: 20pt; font-weight: bold; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; border-style: solid; - margin: -15px -15px 0 -15px } - - .FramedSearchResultsPage .IPageTitle { - margin-bottom: 15px; - } - - .INavigationBar { - font-size: 10pt; - text-align: center; - background-color: #FFFFF0; - padding: 5px; - border-bottom: solid 1px black; - margin: 0 -15px 15px -15px; - } - - .INavigationBar a { - font-weight: bold } - - .IHeading { - font-size: 16pt; font-weight: bold; - padding: 2.5em 0 .5em 0; - text-align: center; - width: 3.5ex; - } - #IFirstHeading { - padding-top: 0; - } - - .IEntry { - font-size: 10pt; - padding-left: 1ex; - } - .PopupSearchResultsPage .IEntry { - font-size: 8pt; - padding: 1px 5px; - } - .PopupSearchResultsPage .Opera9 .IEntry, - .FramedSearchResultsPage .Opera9 .IEntry { - text-align: left; - } - .FramedSearchResultsPage .IEntry { - padding: 0; - } - - .ISubIndex { - padding-left: 3ex; padding-bottom: .5em } - .PopupSearchResultsPage .ISubIndex { - display: none; - } - - /* While it may cause some entries to look like links when they aren't, I found it's much easier to read the - index if everything's the same color. */ - .ISymbol { - font-weight: bold; color: #900000 } - - .IndexPage .ISymbolPrefix, - .FramedIndexPage .ISymbolPrefix { - font-size: 10pt; - text-align: right; - color: #C47C7C; - background-color: #F8F8F8; - border-right: 3px solid #E0E0E0; - border-left: 1px solid #E0E0E0; - padding: 0 1px 0 2px; - } - .PopupSearchResultsPage .ISymbolPrefix, - .FramedSearchResultsPage .ISymbolPrefix { - color: #900000; - } - .PopupSearchResultsPage .ISymbolPrefix { - font-size: 8pt; - } - - .IndexPage #IFirstSymbolPrefix, - .FramedIndexPage #IFirstSymbolPrefix { - border-top: 1px solid #E0E0E0; - } - .IndexPage #ILastSymbolPrefix, - .FramedIndexPage #ILastSymbolPrefix { - border-bottom: 1px solid #E0E0E0; - } - .IndexPage #IOnlySymbolPrefix, - .FramedIndexPage #IOnlySymbolPrefix { - border-top: 1px solid #E0E0E0; - border-bottom: 1px solid #E0E0E0; - } - - a.IParent, - a.IFile { - display: block; - } - - .PopupSearchResultsPage .SRStatus { - padding: 2px 5px; - font-size: 8pt; - font-style: italic; - } - .FramedSearchResultsPage .SRStatus { - font-size: 10pt; - font-style: italic; - } - - .SRResult { - display: none; - } - - - -#Footer { - font-size: 8pt; - color: #989898; - text-align: right; - } - -#Footer p { - text-indent: 0; - margin-bottom: .5em; - } - -.ContentPage #Footer, -.IndexPage #Footer { - text-align: right; - margin: 2px; - } - -.FramedMenuPage #Footer { - text-align: center; - margin: 5em 10px 10px 10px; - padding-top: 1em; - border-top: 1px solid #C8C8C8; - } - - #Footer a:link, - #Footer a:hover, - #Footer a:visited { color: #989898 } - #Footer a:active { color: #A00000 } - - - -.prettyprint .kwd { color: #800000; } /* keywords */ - - .prettyprint.PDefaultValue .kwd, - .prettyprint.PDefaultValuePrefix .kwd, - .prettyprint.PTypePrefix .kwd { - color: #C88F8F; - } - -.prettyprint .com { color: #008000; } /* comments */ - - .prettyprint.PDefaultValue .com, - .prettyprint.PDefaultValuePrefix .com, - .prettyprint.PTypePrefix .com { - color: #8FC88F; - } - -.prettyprint .str { color: #0000B0; } /* strings */ -.prettyprint .lit { color: #0000B0; } /* literals */ - - .prettyprint.PDefaultValue .str, - .prettyprint.PDefaultValuePrefix .str, - .prettyprint.PTypePrefix .str, - .prettyprint.PDefaultValue .lit, - .prettyprint.PDefaultValuePrefix .lit, - .prettyprint.PTypePrefix .lit { - color: #8F8FC0; - } - -.prettyprint .typ { color: #000000; } /* types */ -.prettyprint .pun { color: #000000; } /* punctuation */ -.prettyprint .pln { color: #000000; } /* punctuation */ - - .prettyprint.PDefaultValue .typ, - .prettyprint.PDefaultValuePrefix .typ, - .prettyprint.PTypePrefix .typ, - .prettyprint.PDefaultValue .pun, - .prettyprint.PDefaultValuePrefix .pun, - .prettyprint.PTypePrefix .pun, - .prettyprint.PDefaultValue .pln, - .prettyprint.PDefaultValuePrefix .pln, - .prettyprint.PTypePrefix .pln { - color: #8F8F8F; - } - -.prettyprint .tag { color: #008; } -.prettyprint .atn { color: #606; } -.prettyprint .atv { color: #080; } -.prettyprint .dec { color: #606; } - diff --git a/example/add-and-commit.js b/example/add-and-commit.js index d9c5da2b7..b1d4e31cd 100644 --- a/example/add-and-commit.js +++ b/example/add-and-commit.js @@ -1,59 +1,68 @@ -var git = require('../'), - path = require('path'), - fs = require('fs'), - fileName = 'newfile.txt', - fileContent = 'hello world' - ; +var nodegit = require('../'); +var path = require('path'); +var Promise = require('nodegit-promise'); +var promisify = require('promisify-node'); +var fse = promisify(require('fs-extra')); +var fileName = 'newfile.txt'; +var fileContent = 'hello world'; +var directoryName = 'salad/toast/strangerinastrangeland/theresnowaythisexists'; +// ensureDir is an alias to mkdirp, which has the callback with a weird name +// and in the 3rd position of 4 (the 4th being used for recursion). We have to force +// promisify it, because promisify-node won't detect it on its own and assumes sync +fse.ensureDir = promisify(fse.ensureDir); /** - * This example creates a certain file `newfile.txt`, adds it to the git index and + * This example creates a certain file `newfile.txt`, adds it to the git index and * commits it to head. Similar to a `git add newfile.txt` followed by a `git commit` **/ -//open a git repo -git.Repo.open(path.resolve(__dirname, '../.git'), function(openReporError, repo) { - if (openReporError) throw openReporError; +var repo; +var index; +var oid; +var parent; - //create the file in the repo's workdir - fs.writeFile(path.join(repo.workdir(), fileName), fileContent, function(writeError) { - if (writeError) throw writeError; +nodegit.Repository.open(path.resolve(__dirname, '../.git')) +.then(function(repoResult) { + repo = repoResult; + return fse.ensureDir(path.join(repo.workdir(), directoryName)); +}).then(function(){ + return fse.writeFile(path.join(repo.workdir(), fileName), fileContent); +}) +.then(function() { + return fse.writeFile(path.join(repo.workdir(), directoryName, fileName), fileContent); +}) +.then(function() { + return repo.openIndex(); +}) +.then(function(indexResult) { + index = indexResult; + return index.read(1); +}) +.then(function() { + return index.addByPath(fileName); +}) +.then(function() { + return index.addByPath(path.join(directoryName, fileName)); +}) +.then(function() { + return index.write(); +}) +.then(function() { + return index.writeTree(); +}) +.then(function(oidResult) { + oid = oidResult; + return nodegit.Reference.nameToId(repo, 'HEAD'); +}) +.then(function(head) { + return repo.getCommit(head); +}) +.then(function(parent) { + var author = nodegit.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); + var committer = nodegit.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); - //add the file to the index... - repo.openIndex(function(openIndexError, index) { - if (openIndexError) throw openIndexError; - - index.read(function(readError) { - if (readError) throw readError; - - index.addByPath(fileName, function(addByPathError) { - if (addByPathError) throw addByPathError; - - index.write(function(writeError) { - if (writeError) throw writeError; - - index.writeTree(function(writeTreeError, oid) { - if (writeTreeError) throw writeTreeError; - - //get HEAD - git.Reference.oidForName(repo, 'HEAD', function(oidForName, head) { - if (oidForName) throw oidForName; - - //get latest commit (will be the parent commit) - repo.getCommit(head, function(getCommitError, parent) { - if (getCommitError) throw getCommitError; - var author = git.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); - var committer = git.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); - - //commit - repo.createCommit('HEAD', author, committer, 'message', oid, [parent], function(error, commitId) { - console.log("New Commit:", commitId.sha()); - }); - }); - }); - }); - }); - }); - }); - }); - }); -}); \ No newline at end of file + return repo.createCommit('HEAD', author, committer, 'message', oid, [parent]); +}) +.done(function(commitId) { + console.log('New Commit: ', commitId); +}); diff --git a/example/apps/git_profanity_check.js b/example/apps/git_profanity_check.js index 7f0674849..ab38eb919 100644 --- a/example/apps/git_profanity_check.js +++ b/example/apps/git_profanity_check.js @@ -35,32 +35,25 @@ else { } // Open repository. -git.Repo.open(path, function(err, repo) { - if (err) { - throw new Error(err); - } - +git.Repo.open(path) +.then(function(repo) { // Open branch, default to master. - repo.getBranch(branch, function(err, branch) { - if (err) { - throw new Error(err); + return repo.getBranchCommit(branch); +}).then(function(firstCommit) { + // Iterate history + var history = firstCommit.history(); + + // Iterate over every commit message and test for words. + history.on('commit', function(commit) { + var message = commit.message(); + + if (reCurse.test(message)) { + console.log('Curse detected in commit', commit.sha()); + console.log('=> ', message); + return; } - - // Iterate history - var history = branch.history(); - - // Iterate over every commit message and test for words. - history.on('commit', function(commit) { - var message = commit.message(); - - if (reCurse.test(message)) { - console.log('Curse detected in commit', commit.sha()); - console.log('=> ', message); - return; - } - }); - - // Start history iteration. - history.start(); }); + + // Start history iteration. + history.start(); }); diff --git a/example/clone.js b/example/clone.js index 75f8b3603..d6ba9c2b6 100644 --- a/example/clone.js +++ b/example/clone.js @@ -1,27 +1,29 @@ -var git = require('../'), - rimraf = require('rimraf'), - path = "/tmp/nodegit-clone-demo"; +var nodegit = require('../'); +var rimraf = require('rimraf'); +var path = "/tmp/nodegit-clone-demo"; rimraf(path, function() { - git.Repo.clone("https://github.com/nodegit/nodegit.git", path, null, function(error, repo) { - if (error) throw error; + var entry; - repo.getCommit('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5', function(error, commit) { - if (error) throw error; - - commit.getEntry('README.md', function(error, entry) { - if (error) throw error; - - entry.getBlob(function(error, blob) { - if (error) throw error; - - console.log(entry.name(), entry.sha(), blob.size() + 'b'); - console.log('========================================================\n\n'); - var firstTenLines = blob.toString().split('\n').slice(0, 10).join('\n'); - console.log(firstTenLines); - console.log('...'); - }); - }); - }); + nodegit.Clone.clone( + "https://github.com/nodegit/nodegit.git", + path, + { ignoreCertErrors: 1}) + .then(function(repo) { + return repo.getCommit('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5'); + }) + .then(function(commit) { + return commit.getEntry('README.md') + }) + .then(function(entryResult) { + entry = entryResult; + return entry.getBlob(); + }) + .done(function(blob) { + console.log(entry.filename(), entry.sha(), blob.rawsize() + 'b'); + console.log('========================================================\n\n'); + var firstTenLines = blob.toString().split('\n').slice(0, 10).join('\n'); + console.log(firstTenLines); + console.log('...'); }); -}); \ No newline at end of file +}); diff --git a/example/create-new-repo.js b/example/create-new-repo.js new file mode 100644 index 000000000..c934476d9 --- /dev/null +++ b/example/create-new-repo.js @@ -0,0 +1,57 @@ +var nodegit = require('../'); +var path = require('path'); +var Promise = require('nodegit-promise'); +var promisify = require('promisify-node'); +var fse = promisify(require('fs-extra')); +var fileName = 'newfile.txt'; +var fileContent = 'hello world'; +var repoDir = '../../newRepo'; + +fse.ensureDir = promisify(fse.ensureDir); + +var repository; +var index; + +fse.ensureDir(path.resolve(__dirname, repoDir)) +.then(function() { + console.log('a'); + return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0); +}) +.then(function(repo) { + console.log('b'); + repository = repo; + return fse.writeFile(path.join(repository.workdir(), fileName), fileContent); +}) +.then(function(){ + console.log('c'); + return repository.openIndex(); +}) +.then(function(idx) { + console.log('d'); + index = idx; + return index.read(1); +}) +.then(function() { + console.log('e'); + return index.addByPath(fileName); +}) +.then(function() { + console.log('f'); + return index.write(); +}) +.then(function() { + console.log('g'); + return index.writeTree(); +}) +.then(function(oid) { + console.log('j'); + var author = nodegit.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); + var committer = nodegit.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); + + // Since we're creating an inital commit, it has no parents. Note that unlike + // normal we don't get the head either, because there isn't one yet. + return repository.createCommit('HEAD', author, committer, 'message', oid, []); +}) +.done(function(commitId) { + console.log('New Commit: ', commitId); +}); diff --git a/example/details-for-tree-entry.js b/example/details-for-tree-entry.js new file mode 100644 index 000000000..c17c6d065 --- /dev/null +++ b/example/details-for-tree-entry.js @@ -0,0 +1,29 @@ +var nodegit = require('../'); +var path = require('path'); + +/** + * This shows how to get details from a tree entry or a blob +**/ + +nodegit.Repository.open(path.resolve(__dirname, '../.git')) +.then(function(repo) { + return repo.getTree( + nodegit.Oid.fromString("e1b0c7ea57bfc5e30ec279402a98168a27838ac9")) + .then(function(tree) { + var treeEntry = tree.entryByIndex(0); + + // Tree entry doesn't have any data associated with the actual entry + // To get that we need to get the index entry that this points to + return repo.openIndex().then(function(index) { + var indexEntry = index.getByPath(treeEntry.path()); + + // With the index entry we can now view the details for the tree entry + console.log("Entry path: " + indexEntry.path()); + console.log("Entry time in seconds: " + indexEntry.mtime().seconds()); + console.log("Entry oid: " + indexEntry.id().toString()); + console.log("Entry size: " + indexEntry.fileSize()); + }); + }) +}).done(function() { + console.log("Done!"); +}); diff --git a/example/diff-commits.js b/example/diff-commits.js index edd05b3eb..d6b2bd4c4 100644 --- a/example/diff-commits.js +++ b/example/diff-commits.js @@ -1,33 +1,30 @@ -var git = require('../'), - path = require('path'); +var nodegit = require('../'); +var path = require('path'); // This code examines the diffs between a particular commit and all of its // parents. Since this commit is not a merge, it only has one parent. This is // similar to doing `git show`. -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - if (error) throw error; +nodegit.Repository.open(path.resolve(__dirname, '../.git')) +.then(function(repo) { + return repo.getCommit('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5'); +}) +.then(function(commit) { + console.log('commit ' + commit.sha()); + console.log('Author:', commit.author().name() + ' <' + commit.author().email() + '>'); + console.log('Date:', commit.date()); + console.log('\n ' + commit.message()); - repo.getCommit('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5', function(error, commit) { - if (error) throw error; - - console.log('commit ' + commit.sha()); - console.log('Author:', commit.author().name() + ' <' + commit.author().email() + '>'); - console.log('Date:', commit.date()); - console.log('\n ' + commit.message()); - - commit.getDiff(function(error, diffList) { - if (error) throw error; - - diffList.forEach(function(diff) { - diff.patches().forEach(function(patch) { - console.log("diff", patch.oldFile().path(), patch.newFile().path()); - patch.hunks().forEach(function(hunk) { - console.log(hunk.header().trim()); - hunk.lines().forEach(function(line) { - console.log(String.fromCharCode(line.lineOrigin) + line.content.trim()); - }); - }); + return commit.getDiff(); +}) +.done(function(diffList) { + diffList.forEach(function(diff) { + diff.patches().forEach(function(patch) { + console.log("diff", patch.oldFile().path(), patch.newFile().path()); + patch.hunks().forEach(function(hunk) { + console.log(hunk.header().trim()); + hunk.lines().forEach(function(line) { + console.log(String.fromCharCode(line.origin()) + line.content().trim()); }); }); }); diff --git a/example/fetch.js b/example/fetch.js index 2eeffe327..927a2b8db 100644 --- a/example/fetch.js +++ b/example/fetch.js @@ -1,17 +1,12 @@ -var git = require('../'), - path = require('path'); - -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - if (error) throw error; - - var remote = repo.getRemote("origin"); - remote.connect(0, function(error) { - if (error) throw error; - - remote.download(null, function(error) { - if (error) throw error; - - console.log("It worked!"); - }) - }); +var nodegit = require('../'); +var path = require('path'); + +nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { + return nodegit.Remote.load(repo, "origin"); +}).then(function(remote) { + remote.connect(0); + return remote.download(); +}) +.done(function() { + console.log("It worked!"); }); diff --git a/example/general.js b/example/general.js index 559a42861..94d60dd6e 100644 --- a/example/general.js +++ b/example/general.js @@ -1,5 +1,9 @@ -var git = require('../'), - path = require('path'); +var nodegit = require('../'); +var path = require('path'); +var Promise = require('nodegit-promise'); +var oid; +var odb; +var repo; // **nodegit** is a javascript library for node.js that wraps libgit2, a // pure C implementation of the Git core. It provides an asynchronous @@ -16,10 +20,9 @@ var git = require('../'), // Nearly, all git operations in the context of a repository. // To open a repository, -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - // For all of the following examples, error-handling will be performed in - // this naive way: - if (error) throw error; +nodegit.Repository.open(path.resolve(__dirname, '../.git')) +.then(function(repoResult) { + repo = repoResult; console.log("Opened repository."); // ### SHA-1 Value Conversions @@ -28,7 +31,7 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // **nodegit** uses a simple wrapper around hash values called an `Oid`. // The oid validates that the SHA is well-formed. - var oid = git.Oid.fromString('c27d9c35e3715539d941254f2ce57042b978c49c'); + oid = nodegit.Oid.fromString('c27d9c35e3715539d941254f2ce57042b978c49c'); // Most functions in in **nodegit** that take an oid will also take a // string, so for example, you can look up a commit by a string SHA or @@ -36,7 +39,7 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // an Oid. // If you have a oid, you can easily get the hex value of the SHA again. - console.log("Sha hex string:", oid.sha()); + console.log("Sha hex string:", oid.toString()); // ### Working with the Object Database @@ -44,39 +47,38 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // object database is where the actual objects are stored in Git. For // working with raw objects, we'll need to get this structure from the // repository. - var odb = repo.odb(); + return repo.odb(); +}).then(function(odbResult) { + odb = odbResult; // We can read raw objects directly from the object database if we have // the oid (SHA) of the object. This allows us to access objects without // knowing thier type and inspect the raw bytes unparsed. - odb.read(oid, function(error, object) { - if (error) throw error; - - // A raw object only has three properties - the type (commit, blob, tree - // or tag), the size of the raw data and the raw, unparsed data itself. - // For a commit or tag, that raw data is human readable plain ASCII - // text. For a blob it is just file contents, so it could be text or - // binary data. For a tree it is a special binary format, so it's unlikely - // to be hugely helpful as a raw object. - var data = object.data(), - type = object.type(); - - console.log("Object size and type:", object.size(), object.type()); - }); - + return odb.read(oid); +}).then(function(object) { + // A raw object only has three properties - the type (commit, blob, tree + // or tag), the size of the raw data and the raw, unparsed data itself. + // For a commit or tag, that raw data is human readable plain ASCII + // text. For a blob it is just file contents, so it could be text or + // binary data. For a tree it is a special binary format, so it's unlikely + // to be hugely helpful as a raw object. + var data = object.data(); + var type = object.type(); + var size = object.size(); + + console.log("Object size and type:", size, type); +}).then(function() { // You can also write raw object data to Git. This is pretty cool because // it gives you direct access to the key/value properties of Git. Here // we'll write a new blob object that just contains a simple string. // Notice that we have to specify the object type. - odb.write("test data", "test data".length, git.Object.Type.Blob, function(error, oid) { - if (error) throw error; - - // Now that we've written the object, we can check out what SHA1 was - // generated when the object was written to our database. - console.log("Written Object: ", oid.sha()); - }); - + return odb.write("test data", "test data".length, nodegit.Object.TYPE.BLOB); +}).then(function(oid) { + // Now that we've written the object, we can check out what SHA1 was + // generated when the object was written to our database. + console.log("Written Object: ", oid.toString()); +}).then(function() { // ### Object Parsing // libgit2 has methods to parse every object type in Git so you don't have @@ -89,93 +91,80 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // data in the commit - the author (name, email, datetime), committer // (same), tree, message, encoding and parent(s). - oid = git.Oid.fromString("698c74e817243efe441a5d1f3cbaf3998282ca86"); + oid = nodegit.Oid.fromString("698c74e817243efe441a5d1f3cbaf3998282ca86"); // Many methods in **nodegit** are asynchronous, because they do file // or network I/O. By convention, all asynchronous methods are named // imperatively, like `getCommit`, `open`, `read`, `write`, etc., whereas // synchronous methods are named nominatively, like `type`, `size`, `name`. - repo.getCommit(oid, function(error, commit) { - if (error) throw error; - - // Each of the properties of the commit object are accessible via methods, - // including commonly needed variations, such as `git_commit_time` which - // returns the author time and `git_commit_message` which gives you the - // commit message. - console.log("Commit:", commit.message(), commit.author().name(), commit.date()); - - // Commits can have zero or more parents. The first (root) commit will - // have no parents, most commits will have one (i.e. the commit it was - // based on) and merge commits will have two or more. Commits can - // technically have any number, though it's rare to have more than two. - commit.getParents(function(error, parents) { - parents.forEach(function(parent) { - console.log("Parent:", parent.oid().sha()); - }); - }); + return repo.getCommit(oid); +}).then(function(commit) { + // Each of the properties of the commit object are accessible via methods, + // including commonly needed variations, such as `git_commit_time` which + // returns the author time and `git_commit_message` which gives you the + // commit message. + console.log("Commit:", commit.message(), commit.author().name(), commit.date()); + + // Commits can have zero or more parents. The first (root) commit will + // have no parents, most commits will have one (i.e. the commit it was + // based on) and merge commits will have two or more. Commits can + // technically have any number, though it's rare to have more than two. + return commit.getParents(); +}).then(function(parents) { + parents.forEach(function(parent) { + console.log("Parent:", parent.toString()); }); - +}).then(function() { // #### Writing Commits // nodegit provides a couple of methods to create commit objects easily as // well. - - var author = git.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); - var committer = git.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); + var author = nodegit.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); + var committer = nodegit.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); // Commit objects need a tree to point to and optionally one or more // parents. Here we're creating oid objects to create the commit with, // but you can also use existing ones: + var treeId = nodegit.Oid.fromString("4170d10f19600b9cb086504e8e05fe7d863358a2"); + var parentId = nodegit.Oid.fromString("eebd0ead15d62eaf0ba276da53af43bbc3ce43ab"); - var treeId = git.Oid.fromString("4170d10f19600b9cb086504e8e05fe7d863358a2"); - var parentId = git.Oid.fromString("eebd0ead15d62eaf0ba276da53af43bbc3ce43ab"); - - repo.getTree(treeId, function(error, tree) { - if (error) throw error; - - repo.getCommit(parentId, function(error, parent) { - if (error) throw error; + return repo.getTree(treeId).then(function(tree) { + return repo.getCommit(parentId).then(function(parent) { // Here we actually create the commit object with a single call with all // the values we need to create the commit. The SHA key is written to the // `commit_id` variable here. - repo.createCommit( + return repo.createCommit( null /* do not update the HEAD */, author, committer, "example commit", tree, - [parent], - function (error, oid) { - console.log("New Commit:", oid.sha()); - }); + [parent]); + }).then(function(oid) { + console.log("New Commit:", oid.toString()); }); }); - +}).then(function() { // #### Tag Parsing // You can parse and create tags with the [tag management API][tm], which // functions very similarly to the commit lookup, parsing and creation // methods, since the objects themselves are very similar. - oid = git.Oid.fromString("43f0ac7359e30b769f6b1714e0adbaf51bedbb65"); - repo.getTag(oid, function(error, tag) { - if (error) throw error; - - // Now that we have the tag object, we can extract the information it - // generally contains: the target (usually a commit object), the type of - // the target object (usually 'commit'), the name ('v1.0'), the tagger (a - // git_signature - name, email, timestamp), and the tag message. - console.log(tag.name(), tag.targetType(), tag.message()); - - tag.getTarget(function (error, target) { - if (error) throw error; - - console.log("Target is commit:", target.isCommit()); - }); - }); - - + oid = nodegit.Oid.fromString("dcc4aa9fcdaced037434cb149ed3b6eab4d0709d"); + return repo.getTag(oid); +}).then(function(tag) { + // Now that we have the tag object, we can extract the information it + // generally contains: the target (usually a commit object), the type of + // the target object (usually 'commit'), the name ('v1.0'), the tagger (a + // git_signature - name, email, timestamp), and the tag message. + console.log(tag.name(), tag.targetType(), tag.message()); + + return tag.target(); +}).then(function (target) { + console.log("Target is commit:", target.isCommit()); +}).then(function() { // #### Tree Parsing // A Tree is how Git represents the state of the filesystem @@ -187,34 +176,36 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // object type in Git, but a useful structure for parsing and traversing // tree entries. - oid = git.Oid.fromString("e1b0c7ea57bfc5e30ec279402a98168a27838ac9"); - repo.getTree(oid, function(error, tree) { - if (error) throw error; - - console.log("Tree Size:", tree.size()); - function dfs(error, tree) { - tree.entries().forEach(function(entry) { - if (entry.isDirectory()) { - entry.getTree(dfs); - } else if (entry.isFile()) { - console.log("Tree Entry:", entry.name()); - } - }); - } - dfs(null, tree); + oid = nodegit.Oid.fromString("e1b0c7ea57bfc5e30ec279402a98168a27838ac9"); + return repo.getTree(oid); +}).then(function(tree) { + console.log("Tree Size:", tree.entryCount()); + + function dfs(tree) { + var promises = []; + + tree.entries().forEach(function(entry) { + if (entry.isDirectory()) { + promises.push(entry.getTree().then(dfs)); + } else if (entry.isFile()) { + console.log("Tree Entry:", entry.filename()); + } + }); + + return Promise.all(promises); + } + return dfs(tree).then(function() { // You can also access tree entries by path if you know the path of the // entry you're looking for. - tree.getEntry("example/general.js", function(error, entry) { - if (error) throw error; - + return tree.getEntry("example/general.js").then(function(entry) { // Entries which are files have blobs associated with them: entry.getBlob(function(error, blob) { console.log("Blob size:", blob.size()); }); }); }); - +}).then(function() { // #### Blob Parsing // The last object type is the simplest and requires the least parsing @@ -225,19 +216,17 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // from disk and writing it to the db and getting the oid back so you // don't have to do all those steps yourself. - oid = git.Oid.fromString("991c06b7b1ec6f939488427e4b41a4fa3e1edd5f"); - repo.getBlob(oid, function(error, blob) { - if (error) throw error; - - // You can access a node.js Buffer with the raw contents of the blob directly. - // Note that this buffer may not be contain ASCII data for certain blobs - // (e.g. binary files). - var buffer = blob.content(); - - // If you know that the blob is UTF-8, however, - console.log("Blob contents:", blob.toString().slice(0, 38)); - }); - + oid = nodegit.Oid.fromString("991c06b7b1ec6f939488427e4b41a4fa3e1edd5f"); + return repo.getBlob(oid); +}).then(function(blob) { + // You can access a node.js Buffer with the raw contents of the blob directly. + // Note that this buffer may not be contain ASCII data for certain blobs + // (e.g. binary files). + var buffer = blob.content(); + + // If you know that the blob is UTF-8, however, + console.log("Blob contents:", blob.toString().slice(0, 38)); +}).then(function() { // ### Revwalking // The libgit2 [revision walking api][rw] provides methods to traverse the @@ -247,7 +236,7 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // that were ancestors of (reachable from) a given starting point. This // can allow you to create `git log` type functionality. - oid = git.Oid.fromString("698c74e817243efe441a5d1f3cbaf3998282ca86"); + oid = nodegit.Oid.fromString("698c74e817243efe441a5d1f3cbaf3998282ca86"); // To use the revwalker, create a new walker, tell it how you want to sort // the output and then push one or more starting points onto the walker. @@ -258,72 +247,68 @@ git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { // branch1..branch2`, you would push the oid of `branch2` and hide the oid // of `branch1`. var revWalk = repo.createRevWalk(); - revWalk.sorting(git.RevWalk.Sort.Topological, git.RevWalk.Sort.Reverse); - revWalk.push(oid, function(error) { - if (error) throw error; - - // Now that we have the starting point pushed onto the walker, we start - // asking for ancestors. It will return them in the sorting order we asked - // for as commit oids. We can then lookup and parse the commited pointed - // at by the returned OID; note that this operation is specially fast - // since the raw contents of the commit object will be cached in memory - - function walk() { - revWalk.next(function(error, oid) { - if (error) throw error; - if (!oid) return; - - repo.getCommit(oid, function(error, commit) { - if (error) throw error; - - console.log("Commit:", commit.sha()); - walk(); - }); + + revWalk.sorting(nodegit.Revwalk.SORT.TOPOLOGICAL, nodegit.Revwalk.SORT.REVERSE); + + revWalk.push(oid); + + // Now that we have the starting point pushed onto the walker, we start + // asking for ancestors. It will return them in the sorting order we asked + // for as commit oids. We can then lookup and parse the commited pointed + // at by the returned OID; note that this operation is specially fast + // since the raw contents of the commit object will be cached in memory + + function walk() { + return revWalk.next().then(function(oid) { + if (!oid) return; + + return repo.getCommit(oid).then(function(commit) { + console.log("Commit:", commit.toString()); + return walk(); }); - } - walk(); - }); + }); + } + return walk(); +}).then(function() { // ### Index File Manipulation // The [index file API][gi] allows you to read, traverse, update and write // the Git index file (sometimes thought of as the staging area). - repo.openIndex(function(error, index) { - if (error) throw error; - - // For each entry in the index, you can get a bunch of information - // including the SHA (oid), path and mode which map to the tree objects - // that are written out. It also has filesystem properties to help - // determine what to inspect for changes (ctime, mtime, dev, ino, uid, - // gid, file_size and flags) All these properties are exported publicly in - // the `IndexEntry` class - - index.entries().forEach(function(entry) { - console.log("Index Entry:", entry.path(), entry.mtime().seconds()); - }); + return repo.openIndex(); +}).then(function(index) { + // For each entry in the index, you can get a bunch of information + // including the SHA (oid), path and mode which map to the tree objects + // that are written out. It also has filesystem properties to help + // determine what to inspect for changes (ctime, mtime, dev, ino, uid, + // gid, file_size and flags) All these properties are exported publicly in + // the `IndexEntry` class + + index.entries().forEach(function(entry) { + console.log("Index Entry:", entry.path(), entry.mtime().seconds()); }); - +}).then(function() { // ### References // The [reference API][ref] allows you to list, resolve, create and update // references such as branches, tags and remote references (everything in // the .git/refs directory). - repo.getReferences(git.Reference.Type.All, function(error, referenceNames) { - if (error) throw error; - - referenceNames.forEach(function(referenceName) { - repo.getReference(referenceName, function(error, reference) { - if (error) throw error; - - if (reference.isConcrete()) { - console.log("Reference:", referenceName, reference.target()); - } else if (reference.isSymbolic()) { - console.log("Reference:", referenceName, reference.symbolicTarget()); - } - }); - }); + return repo.getReferenceNames(nodegit.Reference.TYPE.ALL); +}).then(function(referenceNames) { + var promises = []; + + referenceNames.forEach(function(referenceName) { + promises.push(repo.getReference(referenceName).then(function(reference) { + if (reference.isConcrete()) { + console.log("Reference:", referenceName, reference.target()); + } else if (reference.isSymbolic()) { + console.log("Reference:", referenceName, reference.symbolicTarget()); + } + })); }); -}); - + return Promise.all(promises); +}).done(function() { + console.log("Done!"); +}); diff --git a/example/merge-cleanly.js b/example/merge-cleanly.js new file mode 100644 index 000000000..6fabc672d --- /dev/null +++ b/example/merge-cleanly.js @@ -0,0 +1,118 @@ +var nodegit = require('../'); +var path = require('path'); +var Promise = require('nodegit-promise'); +var promisify = require('promisify-node'); +var fse = promisify(require('fs-extra')); +fse.ensureDir = promisify(fse.ensureDir); + +var ourFileName = 'ourNewFile.txt'; +var ourFileContent = 'I like Toll Roads. I have an EZ-Pass!'; +var ourBranchName = "ours"; + +var theirFileName = 'theirNewFile.txt'; +var theirFileContent = "I'm skeptical about Toll Roads"; +var theirBranchName = "theirs"; + +var repoDir = '../../newRepo'; + +var repository; +var ourCommit; +var theirCommit; +var ourBranch; +var theirBranch; + +var ourSignature = nodegit.Signature.create("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60); +var theirSignature = nodegit.Signature.create("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60); + +// Create a new repository in a clean directory, and add our first file +fse.remove(path.resolve(__dirname, repoDir)) +.then(function() { + return fse.ensureDir(path.resolve(__dirname, repoDir)); +}) +.then(function() { + return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0); +}) +.then(function(repo) { + repository = repo; + return fse.writeFile(path.join(repository.workdir(), ourFileName), ourFileContent); +}) + +// Load up the repository index and make our initial commit to HEAD +.then(function() { + return repository.openIndex(); +}) +.then(function(index) { + index.read(1); + index.addByPath(ourFileName); + index.write() + + return index.writeTree(); +}) +.then(function(oid) { + return repository.createCommit('HEAD', ourSignature, ourSignature, 'we made a commit', oid, []); +}) + +// Get commit object from the oid, and create our new branches at that position +.then(function(commitOid) { + return repository.getCommit(commitOid).then(function(commit) { + ourCommit = commit; + }).then(function() { + return repository.createBranch(ourBranchName, commitOid).then(function(branch) { + ourBranch = branch; + return repository.createBranch(theirBranchName, commitOid); + }); + }); +}) + +// Create a new file, stage it and commit it to our second branch +.then(function(branch) { + theirBranch = branch; + return fse.writeFile(path.join(repository.workdir(), theirFileName), theirFileContent); +}) +.then(function() { + return repository.openIndex(); +}) +.then(function(index) { + index.read(1); + index.addByPath(theirFileName); + index.write() + + return index.writeTree(); +}) +.then(function(oid) { + // You don't have to change head to make a commit to a different branch. + return repository.createCommit(theirBranch.name(), theirSignature, theirSignature, 'they made a commit', oid, [ourCommit]); +}) +.then(function(commitOid) { + return repository.getCommit(commitOid).then(function(commit) { + theirCommit = commit; + }); +}) + + +// Merge the two commits +.then(function() { + return nodegit.Merge.commits(repository, ourCommit, theirCommit); +}) + + +// Merging returns an index that isn't backed by the repository. +// You have to manually check for merge conflicts. If there are none +// you just have to write the index. You do have to write it to +// the repository instead of just writing it. +.then(function(index) { + if (!index.hasConflicts()) { + index.write() + return index.writeTreeTo(repository); + } +}) + + +// Create our merge commit back on our branch +.then(function(oid) { + return repository.createCommit(ourBranch.name(), ourSignature, ourSignature, 'we merged their commit', oid, [ourCommit, theirCommit]); +}) +.done(function(commitId) { + // We never changed the HEAD after the initial commit; it should still be the same as master. + console.log('New Commit: ', commitId); +}); diff --git a/example/merge-with-conflicts.js b/example/merge-with-conflicts.js new file mode 100644 index 000000000..652198b77 --- /dev/null +++ b/example/merge-with-conflicts.js @@ -0,0 +1,169 @@ +var nodegit = require('../'); +var path = require('path'); +var Promise = require('nodegit-promise'); +var promisify = require('promisify-node'); +var fse = promisify(require('fs-extra')); +fse.ensureDir = promisify(fse.ensureDir); + +var repoDir = '../../newRepo'; +var fileName = 'newFile.txt'; + +var baseFileContent = 'All Bobs are created equal. ish.\n'; +var ourFileContent = "Big Bobs are best, IMHO.\n"; +var theirFileContent = "Nobody expects the small Bobquisition!\n"; +var finalFileContent = "Big Bobs are beautiful, and the small are unexpected!\n"; + +var baseSignature = nodegit.Signature.create("Peaceful Bob", "justchill@bob.net", 123456789, 60); +var ourSignature = nodegit.Signature.create("Big Bob", "impressive@bob.net", 123456789, 60); +var theirSignature = nodegit.Signature.create("Small Bob", "underestimated@bob.net", 123456789, 60); + +var ourBranchName = "ours"; +var theirBranchName = "theirs"; + +var repository; +var baseCommit; +var baseCommitOid; +var ourCommit; +var theirCommit; +var ourBranch; +var theirBranch; + +// Create a new repository in a clean directory, and add our first file +fse.remove(path.resolve(__dirname, repoDir)) +.then(function() { + return fse.ensureDir(path.resolve(__dirname, repoDir)); +}) +.then(function() { + return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0); +}) +.then(function(repo) { + repository = repo; + return fse.writeFile(path.join(repository.workdir(), fileName), baseFileContent); +}) + + +// Load up the repository index and make our initial commit to HEAD +.then(function() { + return repository.openIndex(); +}) +.then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write() + + return index.writeTree(); +}) +.then(function(oid) { + return repository.createCommit('HEAD', baseSignature, baseSignature, 'bobs are all ok', oid, []); +}) +.then(function(commitOid) { + baseCommitOid = commitOid; + return repository.getCommit(commitOid).then(function(commit) { + baseCommit = commit; + }); +}) + + +// create our branches +.then(function() { + return repository.createBranch(ourBranchName, baseCommitOid).then(function(branch) { + ourBranch = branch; + }); +}) +.then(function() { + return repository.createBranch(theirBranchName, baseCommitOid).then(function(branch) { + theirBranch = branch; + }); +}) + + +// Write and commit our version of the file +.then(function() { + return fse.writeFile(path.join(repository.workdir(), fileName), ourFileContent); +}) +.then(function() { + return repository.openIndex().then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write() + + return index.writeTree(); + }); +}) +.then(function(oid) { + return repository.createCommit(ourBranch.name(), ourSignature, ourSignature, 'lol big bobs :yesway:', oid, [baseCommit]); +}) +.then(function(commitOid) { + return repository.getCommit(commitOid).then(function(commit) { + ourCommit = commit; + }); +}) + + +// Write and commit their version of the file +.then(function() { + return fse.writeFile(path.join(repository.workdir(), fileName), theirFileContent); +}) +.then(function() { + return repository.openIndex().then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write() + + return index.writeTree(); + }); +}) +.then(function(oid) { + return repository.createCommit(theirBranch.name(), theirSignature, theirSignature, 'lol big bobs :poop:', oid, [baseCommit]); +}) +.then(function(commitOid) { + return repository.getCommit(commitOid).then(function(commit) { + theirCommit = commit; + }); +}) + + +// move the head to our branch, just to keep things tidy +.then(function() { + return nodegit.Reference.lookup(repository, 'HEAD').then(function(head) { + return head.symbolicSetTarget(ourBranch.name(), ourSignature, ""); + }) +}) + + +// Merge their branch into our branch +.then(function() { + return nodegit.Merge.commits(repository, ourCommit, theirCommit, null); +}) + +// Merging returns an index that isn't backed by the repository. +// You have to write it to the repository instead of just writing it. +.then(function(index) { + if (index.hasConflicts()) { + console.log('Conflict time!'); + + // if the merge had comflicts, solve them + // (in this case, we simply overwrite the file) + fse.writeFileSync(path.join(repository.workdir(), fileName), finalFileContent); + } +}) + +// we need to get a new index as the other one isnt backed to +// the repository in the usual fashion, and just behaves weirdly +.then(function() { + return repository.openIndex().then(function(index) { + + index.read(1); + index.addByPath(fileName); + index.write(); + + return index.writeTree(); + }); +}) +.then(function(oid) { + // create the new merge commit on our branch + return repository.createCommit(ourBranch.name(), baseSignature, baseSignature, 'Stop this bob sized fued', oid, [ourCommit, theirCommit]); +}) +.done(function(commitId) { + console.log('New Commit: ', commitId); +}); diff --git a/example/new-commit.js b/example/new-commit.js deleted file mode 100755 index 4bf733c53..000000000 --- a/example/new-commit.js +++ /dev/null @@ -1,32 +0,0 @@ -var git = require('../'), - path = require('path'); - -// This example opens a certain file, `README.md`, at a particular commit, -// and prints the first 10 lines as well as some metadata. - -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - if (error) throw error; - - repo.getCommit('eebd0ead15d62eaf0ba276da53af43bbc3ce43ab', function(error, commit) { - if (error) throw error; - - commit.getTree(function(error, tree) { - if (error) throw error; - - var builder = tree.builder(), - buffer = new Buffer("this is a file\n"); - - builder.insertBlob("/lib/baz.txt", buffer, false) - builder.write(function(error, treeId) { - if (error) throw error; - - var author = git.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); - var committer = git.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); - - repo.createCommit(null, author, committer, "message", treeId, [commit], function(error, commitId) { - console.log("New Commit:", commitId.sha()); - }); - }); - }); - }); -}); diff --git a/example/push.js b/example/push.js new file mode 100644 index 000000000..b902ffdbe --- /dev/null +++ b/example/push.js @@ -0,0 +1,77 @@ +var nodegit = require('../'); +var path = require('path'); +var Promise = require('nodegit-promise'); +var promisify = require('promisify-node'); +var fse = promisify(require('fs-extra')); +fse.ensureDir = promisify(fse.ensureDir); + +var fileName = 'newFile.txt'; +var fileContent = 'hello world'; + +var repoDir = '../../newRepo'; + +var repository; + +var signature = nodegit.Signature.create("Foo bar", "foo@bar.com", 123456789, 60); + +// Create a new repository in a clean directory, and add our first file +fse.remove(path.resolve(__dirname, repoDir)) +.then(function() { + return fse.ensureDir(path.resolve(__dirname, repoDir)); +}) +.then(function() { + return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0); +}) +.then(function(repo) { + repository = repo; + return fse.writeFile(path.join(repository.workdir(), fileName), fileContent); +}) + +// Load up the repository index and make our initial commit to HEAD +.then(function() { + return repository.openIndex(); +}) +.then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write() + + return index.writeTree(); +}) +.then(function(oid) { + return repository.createCommit('HEAD', signature, signature, 'initial commit', oid, []); +}) + +// Add a new remote +.then(function() { + return nodegit.Remote.create(repository, "origin", "git@github.com:nodegit/push-example.git") + .then(function(remote) { + remote.connect(nodegit.Enums.DIRECTION.PUSH); + + var push; + + // We need to set the auth on the remote, not the push object + remote.setCallbacks({ + credentials: function(url, userName) { + return nodegit.Cred.sshKeyFromAgent(userName); + } + }); + + // Create the push object for this remote + return nodegit.Push.create(remote) + .then(function(pushResult) { + push = pushResult; + + // This just says what branch we're pushing onto what branch in the remote + return push.addRefspec("refs/heads/master:refs/heads/master"); + }).then(function() { + // This is the call that performs the actual push + return push.finish(); + }).then(function() { + // Check to see if the remote accepted our push request. + return push.unpackOk(); + }); + }); +}).done(function() { + console.log("Done!"); +}) diff --git a/example/read-file.js b/example/read-file.js index fc698b03d..9d2746670 100644 --- a/example/read-file.js +++ b/example/read-file.js @@ -1,27 +1,20 @@ -var git = require('../'), +var nodegit = require('../'), path = require('path'); // This example opens a certain file, `README.md`, at a particular commit, // and prints the first 10 lines as well as some metadata. - -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - if (error) throw error; - - repo.getCommit('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5', function(error, commit) { - if (error) throw error; - - commit.getEntry('README.md', function(error, entry) { - if (error) throw error; - - entry.getBlob(function(error, blob) { - if (error) throw error; - - console.log(entry.name(), entry.sha(), blob.size() + 'b'); - console.log('========================================================\n\n'); - var firstTenLines = blob.toString().split('\n').slice(0, 10).join('\n'); - console.log(firstTenLines); - console.log('...'); - }); - }); - }); -}); +var _entry; +nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { + return repo.getCommit('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5'); +}).then(function(commit) { + return commit.getEntry('README.md'); +}).then(function(entry) { + _entry = entry; + return _entry.getBlob(); +}).then(function(blob) { + console.log(_entry.filename(), _entry.sha(), blob.rawsize() + 'b'); + console.log('========================================================\n\n'); + var firstTenLines = blob.toString().split('\n').slice(0, 10).join('\n'); + console.log(firstTenLines); + console.log('...'); +}).done(); diff --git a/example/remove-and-commit.js b/example/remove-and-commit.js index 5a4c17684..0bbf8273b 100644 --- a/example/remove-and-commit.js +++ b/example/remove-and-commit.js @@ -1,53 +1,42 @@ -var git = require('../'), +var nodegit = require('../'), path = require('path'), - fileName = 'newfile.txt' - ; + fileName = 'newfile.txt'; /** - * This example deletes a certain file `newfile.txt`, removes it from the git index and + * This example deletes a certain file `newfile.txt`, removes it from the git index and * commits it to head. Similar to a `git rm newfile.txt` followed by a `git commit` * Use add-and-commit.js to create the file first. **/ -//open a git repo -git.Repo.open(path.resolve(__dirname, '../.git'), function(openReporError, repo) { - if (openReporError) throw openReporError; +var _repository; +var _index; +var _oid; +//open a git repo +nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { + _repository = repo; + return repo.openIndex(); +}).then(function(index){ + _index = index; + return _index.read(); +}).then(function() { //remove the file from the index... - repo.openIndex(function(openIndexError, index) { - if (openIndexError) throw openIndexError; - - index.read(function(readError) { - if (readError) throw readError; - - index.removeByPath(fileName); - - index.write(function(writeError) { - if (writeError) throw writeError; - - index.writeTree(function(writeTreeError, oid) { - if (writeTreeError) throw writeTreeError; - - //get HEAD - git.Reference.oidForName(repo, 'HEAD', function(oidForName, head) { - if (oidForName) throw oidForName; - - //get latest commit (will be the parent commit) - repo.getCommit(head, function(getCommitError, parent) { - if (getCommitError) throw getCommitError; - var author = git.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); - var committer = git.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); - - //commit - repo.createCommit('HEAD', author, committer, 'message', oid, [parent], function(error, commitId) { - console.log("New Commit:", commitId.sha()); - // the file is removed from the git repo, use fs.unlink now to remove it - // from the filesystem. - }); - }); - }); - }); - }); - }); - }); -}); \ No newline at end of file + _index.removeByPath(fileName); + return _index.write(); +}).then(function() { + return _index.writeTree(); +}).then(function(oid) { + _oid = oid; + return nodegit.Reference.nameToId(_repository, "HEAD"); +}).then(function(head) { + return _repository.getCommit(head); +}).then(function(parent) { + var author = nodegit.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60); + var committer = nodegit.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); + + return _repository.createCommit('HEAD', author, committer, "message", _oid, [parent]); +}).then(function(commitId) { + // the file is removed from the git repo, use fs.unlink now to remove it + // from the filesystem. + console.log("New Commit:", commitId.allocfmt()); +}).done(); diff --git a/example/walk-history.js b/example/walk-history.js index 4a31f806b..42d3ccb44 100644 --- a/example/walk-history.js +++ b/example/walk-history.js @@ -1,28 +1,23 @@ -var git = require('../'), - path = require('path'), - sort = git.RevWalk.Sort; +var nodegit = require('../'), + path = require('path'); // This code walks the history of the master branch and prints results // that look very similar to calling `git log` from the command line -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - if (error) throw error; +nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { + return repo.getMasterCommit(); +}).then(function(firstCommitOnMaster){ + // History returns an event. + var history = firstCommitOnMaster.history(nodegit.Revwalk.SORT.Time); - repo.getMaster(function(error, branch) { - if (error) throw error; - - // History returns an event. - var history = branch.history(sort.Time); - - // History emits 'commit' event for each commit in the branch's history - history.on('commit', function(commit) { - console.log('commit ' + commit.sha()); - console.log('Author:', commit.author().name() + ' <' + commit.author().email() + '>'); - console.log('Date:', commit.date()); - console.log('\n ' + commit.message()); - }); - - // Don't forget to call `start()`! - history.start(); + // History emits 'commit' event for each commit in the branch's history + history.on('commit', function(commit) { + console.log('commit ' + commit.sha()); + console.log('Author:', commit.author().name() + ' <' + commit.author().email() + '>'); + console.log('Date:', commit.date()); + console.log('\n ' + commit.message()); }); -}); + + // Don't forget to call `start()`! + history.start(); +}).done(); diff --git a/example/walk-tree.js b/example/walk-tree.js index c5c5f98a8..9278eb345 100644 --- a/example/walk-tree.js +++ b/example/walk-tree.js @@ -1,27 +1,21 @@ -var git = require('../'), +var nodegit = require('../'), path = require('path'); // A `tree` in git is typically a representation of the filesystem at // a revision. A tree has a set of entries, each entry being either a // tree (directory), or a file. -git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) { - if (error) throw error; - - repo.getMaster(function(error, branch) { - if (error) throw error; - - branch.getTree(function(error, tree) { - if (error) throw error; - - // `walk()` returns an event. - var walker = tree.walk(); - walker.on('entry', function(entry) { - console.log(entry.path()); - }); - - // Don't forget to call `start()`! - walker.start(); - }); +nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { + return repo.getMasterCommit(); +}).then(function(firstCommitOnMaster) { + return firstCommitOnMaster.getTree(); +}).then(function(tree) { + // `walk()` returns an event. + var walker = tree.walk(); + walker.on('entry', function(entry) { + console.log(entry.path()); }); -}); + + // Don't forget to call `start()`! + walker.start(); +}).done(); diff --git a/generate/callbacks.json b/generate/callbacks.json new file mode 100644 index 000000000..3ca35e475 --- /dev/null +++ b/generate/callbacks.json @@ -0,0 +1,131 @@ +{ + "git_checkout_notify_cb": { + "args": [ + { + "name": "why", + "cType": "git_checkout_notify_t" + }, + { + "name": "path", + "cType": "const char *" + }, + { + "name": "baseline", + "cType": "const git_diff_file *" + }, + { + "name": "target", + "cType": "const git_diff_file *" + }, + { + "name": "workdir", + "cType": "const git_diff_file *" + }, + { + "name": "payload", + "cType": "void *" + } + ], + "returnType": "int", + "returnNoResults": 1, + "returnSuccess": 0, + "returnError": -1 + }, + "git_checkout_progress_cb": { + "args": [ + { + "name": "path", + "cType": "const char *" + }, + { + "name": "completed_steps", + "cType": "size_t" + }, + { + "name": "total_steps", + "cType": "size_t" + }, + { + "name": "payload", + "cType": "void *" + } + ], + "returnType": "int", + "returnNoResults": 1, + "returnSuccess": 0, + "returnError": -1 + }, + "git_cred_acquire_cb": { + "args": [ + { + "name": "cred", + "cType": "git_cred **", + "isReturn": true + }, + { + "name": "url", + "cType": "const char *" + }, + { + "name": "username_from_url", + "cType": "const char *" + }, + { + "name": "allowed_types", + "cType": "unsigned int" + }, + { + "name": "payload", + "cType": "void *" + } + ], + "returnType": "int", + "returnNoResults": 1, + "returnSuccess": 0, + "returnError": -1 + }, + "git_diff_notify_cb": { + "args": [ + { + "name": "diff_so_far", + "cType": "const git_diff *" + }, + { + "name": "delta_to_add", + "cType": "git_diff_delta *" + }, + { + "name": "matched_pathspec", + "cType": "const char *" + }, + { + "name": "payload", + "cType": "void *" + } + ], + "returnType": "int", + "returnNoResults": 1, + "returnSuccess": 0, + "returnError": -1 + }, + "git_diff_file_cb": { + "args": [ + { + "name": "delta", + "cType": "const git_diff_delta *" + }, + { + "name": "progress", + "cType": "float" + }, + { + "name": "payload", + "cType": "void *" + } + ], + "returnType": "int", + "returnNoResults": 1, + "returnSuccess": 0, + "returnError": -1 + } +} diff --git a/generate/descriptor.json b/generate/descriptor.json new file mode 100644 index 000000000..dd767bf55 --- /dev/null +++ b/generate/descriptor.json @@ -0,0 +1,1281 @@ +{ + "enums": { + "branch": { + "JsName": "BRANCH", + "isMask": false + }, + "clone_local": { + "isMask": false, + "values": { + "GIT_CLONE_LOCAL": { + "JsName": "LOCAL" + } + } + }, + "delta": { + "owner": "Diff" + }, + "error": { + "JsName": "ERROR", + "isMask": false + }, + "error_code": { + "values": { + "GIT_ERROR": { + "JsName": "ERROR" + } + } + }, + "filemode": { + "owner": "TreeEntry", + "values": { + "GIT_FILEMODE_BLOB_EXECUTABLE": { + "JsName": "EXECUTABLE" + } + } + }, + "repository_init_flag": { + "removeString": "INIT_" + }, + "otype": { + "JsName": "TYPE", + "owner": "Object", + "removeString": "OBJ_" + }, + "ref": { + "owner": "Reference", + "JsName": "TYPE" + }, + "sort": { + "owner": "Revwalk" + }, + "status": { + "JsName": "STATUS", + "isMask": false + } + }, + "types": + { + "attr": { + "functions": { + "git_attr_foreach": { + "ignore": true + }, + "git_attr_get": { + "isAsync": true, + "args": { + "value_out": { + "isReturn": true + } + } + } + } + }, + "blame": { + "cType": "git_blame" + }, + "blame_hunk": { + "fields": { + "boundary": { + "ignore": true + } + } + }, + "blob": { + "functions": { + "git_blob_create_frombuffer": { + "args": { + "buffer": { + "cppClassName": "Buffer", + "jsClassName": "Buffer" + } + } + }, + "git_blob_create_fromchunks": { + "ignore": true + }, + "git_blob_filtered_content": { + "ignore": true + }, + "git_blob_rawcontent": { + "return": { + "cppClassName": "Wrapper", + "jsClassName": "Buffer" + } + } + }, + "dependencies": [ + "../include/wrapper.h", + "node_buffer.h" + ] + }, + "branch": { + "functions": { + "git_branch_create": { + "args": { + "force": { + "isOptional": true + }, + "signature": { + "isOptional": true + }, + "log_message": { + "isOptional": true + } + } + }, + "git_branch_next": { + "ignore": true + }, + "git_branch_set_upstream": { + "isAsync": false, + "args": { + "upstream_name": { + "isOptional": true + } + } + }, + "git_branch_upstream": { + "isAsync": false + } + } + }, + "buf": { + "functions": { + "git_buf_grow": { + "cppFunctionName": "Grow", + "jsFunctionName": "grow", + "args": { + "buffer": { + "isReturn": true, + "isSelf": false, + "shouldAlloc": true + } + }, + "return": { + "cppClassName": "Number", + "jsClassName": "Number", + "isErrorCode": true + }, + "isAsync": true + }, + "git_buf_set": { + "cppFunctionName": "Set", + "jsFunctionName": "set", + "args": { + "buffer": { + "isReturn": true, + "isSelf": false, + "shouldAlloc": true + }, + "data": { + "cppClassName": "Buffer", + "jsClassName": "Buffer" + } + }, + "return": { + "cppClassName": "Number", + "jsClassName": "Number", + "isErrorCode": true + }, + "isAsync": true + } + } + }, + "clone": { + "functions": { + "git_clone": { + "args": { + "options": { + "isOptional": true + } + } + } + } + }, + "commit": { + "functions": { + "git_commit_create": { + "args": { + "id": { + "isReturn": true + }, + "message_encoding": { + "isOptional": true + }, + "parents": { + "cType": "const git_commit **", + "cppClassName": "Array", + "jsClassName": "Array", + "arrayElementCppClassName": "GitCommit" + }, + "update_ref": { + "isOptional": true + } + } + }, + "git_commit_create_from_callback": { + "ignore": true + }, + "git_commit_create_from_ids": { + "ignore": true + } + } + }, + "config": { + "functions": { + "git_config_add_backend": { + "ignore": true + }, + "git_config_add_file_ondisk": { + "ignore": true + }, + "git_config_backend_foreach_match": { + "ignore": true + }, + "git_config_delete_entry": { + "ignore": true + }, + "git_config_delete_multivar": { + "ignore": true + }, + "git_config_find_global": { + "ignore": true + }, + "git_config_find_system": { + "ignore": true + }, + "git_config_find_xdg": { + "ignore": true + }, + "git_config_foreach": { + "ignore": true + }, + "git_config_foreach_match": { + "ignore": true + }, + "git_config_free": { + "ignore": true + }, + "git_config_get_bool": { + "ignore": true + }, + "git_config_get_entry": { + "ignore": true + }, + "git_config_get_int32": { + "ignore": true + }, + "git_config_get_int64": { + "ignore": true + }, + "git_config_get_mapped": { + "ignore": true + }, + "git_config_get_multivar_foreach": { + "ignore": true + }, + "git_config_get_string": { + "ignore": true + }, + "git_config_iterator_free": { + "ignore": true + }, + "git_config_iterator_glob_new": { + "ignore": true + }, + "git_config_iterator_new": { + "ignore": true + }, + "git_config_init_backend": { + "ignore": true + }, + "git_config_lookup_map_value": { + "ignore": true + }, + "git_config_multivar_iterator_new": { + "ignore": true + }, + "git_config_new": { + "ignore": true + }, + "git_config_next": { + "ignore": true + }, + "git_config_open_default": { + "ignore": true + }, + "git_config_open_global": { + "ignore": true + }, + "git_config_open_level": { + "ignore": true + }, + "git_config_open_ondisk": { + "ignore": true + }, + "git_config_parse_bool": { + "ignore": true + }, + "git_config_parse_int32": { + "ignore": true + }, + "git_config_parse_int64": { + "ignore": true + }, + "git_config_refresh": { + "ignore": true + }, + "git_config_set_bool": { + "ignore": true + }, + "git_config_set_int32": { + "ignore": true + } + } + }, + "config_backend": { + "ignore": true + }, + "config_iterator": { + "ignore": true + }, + "cred": { + "cType": "git_cred", + "functions": { + "git_cred_ssh_custom_new": { + "ignore": true + }, + "git_cred_ssh_interactive_new": { + "ignore": true + }, + "git_cred_ssh_key_from_agent":{ + "isAsync": false + }, + "git_cred_userpass": { + "ignore": true + } + } + }, + "cred_ssh_custom": { + "ignore": true + }, + "cred_ssh_interactive": { + "ignore": true + }, + "cred_ssh_key": { + "ignore": true + }, + "cred_userpass_payload": { + "cDependencies": [ + "git2/cred_helpers.h" + ] + }, + "cred_userpass_plaintext": { + "ignore": true + }, + "diff": { + "cDependencies": [ + "git2/sys/diff.h" + ], + "functions": { + "git_diff_blob_to_buffer": { + "ignore": true + }, + "git_diff_blobs": { + "ignore": true + }, + "git_diff_buffers": { + "ignore": true + }, + "git_diff_commit_as_email": { + "ignore": true + }, + "git_diff_find_init_options": { + "ignore": true + }, + "git_diff_find_similar": { + "ignore": true + }, + "git_diff_foreach": { + "ignore": true + }, + "git_diff_format_email": { + "ignore": true + }, + "git_diff_format_email_init_options": { + "ignore": true + }, + "git_diff_free": { + "ignore": true + }, + "git_diff_get_stats": { + "ignore": true + }, + "git_diff_index_to_workdir": { + "ignore": true + }, + "git_diff_init_options": { + "ignore": true + }, + "git_diff_is_sorted_icase": { + "ignore": true + }, + "git_diff_merge": { + "ignore": true + }, + "git_diff_num_deltas_of_type": { + "ignore": true + }, + "git_diff_print": { + "ignore": true + }, + "git_diff_print_callback__to_buf": { + "ignore": true + }, + "git_diff_print_callback__to_file_handle": { + "ignore": true + }, + "git_diff_stats_deletions": { + "ignore": true + }, + "git_diff_stats_files_changed": { + "ignore": true + }, + "git_diff_stats_free": { + "ignore": true + }, + "git_diff_stats_insertions": { + "ignore": true + }, + "git_diff_stats_to_buf": { + "ignore": true + }, + "git_diff_status_char": { + "ignore": true + }, + "git_diff_tree_to_index": { + "ignore": true + }, + "git_diff_tree_to_tree": { + "args": { + "opts": { + "isOptional": true + } + } + }, + "git_diff_tree_to_workdir": { + "ignore": true + }, + "git_diff_tree_to_workdir_with_index": { + "ignore": true + } + } + }, + "diff_find_options": { + "fields": { + "git_diff_similarity_metric": { + "ignore": true + } + }, + "ignore": true + }, + "diff_format_email_options": { + "ignore": true + }, + "diff_perfdata": { + "cDependencies": [ + "git2/sys/diff.h" + ] + }, + "diff_similarity_metric": { + "ignore": true + }, + "error_code": { + "values": { + "GIT_ERROR": { + "JsName": "ERROR" + } + } + }, + "filter": { + "functions": { + "git_filter_list_apply_to_blob": { + "ignore": true + }, + "git_filter_list_apply_to_data": { + "ignore": true + }, + "git_filter_list_apply_to_file": { + "ignore": true + }, + "git_filter_list_free": { + "ignore": true + }, + "git_filter_list_load": { + "ignore": true + }, + "git_filter_list_push": { + "ignore": true + }, + "git_filter_source_filemode": { + "ignore": true + }, + "git_filter_source_id": { + "ignore": true + }, + "git_filter_source_mode": { + "ignore": true + }, + "git_filter_source_options": { + "ignore": true + }, + "git_filter_source_path": { + "ignore": true + }, + "git_filter_source_repo": { + "ignore": true + } + }, + "fields": { + "initialize": { + "ignore": true + }, + "shutdown": { + "ignore": true + }, + "check": { + "ignore": true + }, + "apply": { + "ignore": true + }, + "cleanup": { + "ignore": true + } + }, + "cDependencies": [ + "git2/sys/filter.h" + ] + }, + "filter_source": { + "ignore": true + }, + "graph": { + "functions": { + "git_graph_ahead_behind": { + "ignore": true + } + } + }, + "ignore": { + "functions": { + "git_ignore_path_is_ignored": { + "ignore": true + } + } + }, + "index": { + "functions": { + "git_index_add_all": { + "ignore": true + }, + "git_index_conflict_get": { + "ignore": true + }, + "git_index_conflict_iterator_free": { + "ignore": true + }, + "git_index_conflict_iterator_new": { + "ignore": true + }, + "git_index_conflict_next": { + "ignore": true + }, + "git_index_entrycount": { + "jsFunctionName": "entryCount" + }, + "git_index_find": { + "ignore": true + }, + "git_index_free": { + "ignore": true + }, + "git_index_get_bypath": { + "args": { + "stage": { + "isOptional": true + } + } + }, + "git_index_new": { + "ignore": true + }, + "git_index_read": { + "args": { + "force": { + "isOptional": true + } + } + }, + "git_index_remove_all": { + "ignore": true + }, + "git_index_update_all": { + "ignore": true + }, + "git_index_write": { + "args": { + "force": { + "isOptional": true + } + } + } + } + }, + "index_entry": { + "ignore": false + }, + "indexer": { + "cType": "git_indexer", + "functions": { + "git_indexer_append": { + "ignore": true + }, + "git_indexer_new": { + "ignore": true + } + } + }, + "mempack": { + "functions": { + "git_mempack_new": { + "ignore": true + }, + "git_mempack_reset": { + "ignore": true + } + } + }, + "merge": { + "functions": { + "git_merge": { + "ignore": true + }, + "git_merge_analysis": { + "ignore": true + }, + "git_merge_base_many": { + "ignore": true + }, + "git_merge_base_octopus": { + "ignore": true + }, + "git_merge_commits": { + "args": { + "opts": { + "isOptional": true + } + } + }, + "git_merge_file": { + "ignore": true + }, + "git_merge_file_from_index": { + "ignore": true + }, + "git_merge_file_init_options": { + "ignore": true + }, + "git_merge_file_result_free": { + "ignore": true + } + } + }, + "message": { + "functions": { + "git_message_prettify": { + "ignore": true + } + } + }, + "note": { + "functions": { + "git_note_create": { + "args": { + "out": { + "shouldAlloc": true + } + } + }, + "git_note_foreach": { + "ignore": true + } + } + }, + "object": { + "functions": { + "git_object_short_id": { + "args": { + "out": { + "shouldAlloc": true + } + } + } + } + }, + "odb": { + "functions": { + "git_odb_add_alternate": { + "ignore": true + }, + "git_odb_add_backend": { + "ignore": true + }, + "git_odb_backend_loose": { + "ignore": true + }, + "git_odb_backend_one_pack": { + "ignore": true + }, + "git_odb_backend_pack": { + "ignore": true + }, + "git_odb_exists": { + "ignore": true + }, + "git_odb_exists_prefix": { + "ignore": true + }, + "git_odb_foreach": { + "ignore": true + }, + "git_odb_get_backend": { + "ignore": true + }, + "git_odb_hash": { + "ignore": true + }, + "git_odb_hashfile": { + "ignore": true + }, + "git_odb_init_backend": { + "ignore": true + }, + "git_odb_new": { + "ignore": true + }, + "git_odb_num_backends": { + "ignore": true + }, + "git_odb_open_rstream": { + "ignore": true + }, + "git_odb_open_wstream": { + "ignore": true + }, + "git_odb_read_header": { + "ignore": true + }, + "git_odb_read_prefix": { + "ignore": true + }, + "git_odb_refresh": { + "ignore": true + }, + "git_odb_stream_finalize_write": { + "ignore": true + }, + "git_odb_stream_free": { + "ignore": true + }, + "git_odb_stream_read": { + "ignore": true + }, + "git_odb_stream_write": { + "ignore": true + }, + "git_odb_write": { + "args": { + "data": { + "cppClassName": "Wrapper", + "jsClassName": "Buffer" + } + } + }, + "git_odb_write_pack": { + "ignore": true + } + } + }, + "odb_backend": { + "fields": { + "foreach": { + "ignore": true + }, + "writepack": { + "ignore": true + } + }, + "ignore": true + }, + "odb_object": { + "functions": { + "git_odb_object_data": { + "return": { + "cppClassName": "Wrapper", + "jsClassName": "Buffer" + } + } + }, + "dependencies": [ + "../include/wrapper.h", + "node_buffer.h" + ] + }, + "odb_stream": { + "ignore": true + }, + "odb_writepack": { + "ignore": true + }, + "oid": { + "shouldAlloc": true, + "functions": { + "git_oid_cpy": { + "ignore": true + }, + "git_oid_fmt": { + "ignore": true + }, + "git_oid_fromraw": { + "ignore": true + }, + "git_oid_fromstr": { + "isAsync": false + }, + "git_oid_fromstrn": { + "ignore": true + }, + "git_oid_fromstrp": { + "ignore": true + }, + "git_oid_nfmt": { + "ignore": true + }, + "git_oid_pathfmt": { + "ignore": true + }, + "git_oid_shorten_add": { + "ignore": true + }, + "git_oid_shorten_free": { + "ignore": true + }, + "git_oid_shorten_new": { + "ignore": true + }, + "git_oid_tostr": { + "ignore": true + } + }, + "fields": { + "id": { + "ignore": true + } + } + }, + "packbuilder": { + "functions": { + "git_packbuilder_foreach": { + "ignore": true + }, + "git_packbuilder_new": { + "ignore": true + }, + "git_packbuilder_set_callbacks": { + "ignore": true + }, + "git_packbuilder_write": { + "ignore": true + } + } + }, + "patch": { + "functions": { + "git_patch_free": { + "ignore": true + }, + "git_patch_from_buffers": { + "ignore": true + }, + "git_patch_from_diff": { + "isAsync": false + }, + "git_patch_get_hunk": { + "args": { + "out": { + "returnName": "hunk" + }, + "lines_in_hunk": { + "isReturn": true + } + }, + "isAsync": false + }, + "git_patch_get_line_in_hunk": { + "isAsync": false + }, + "git_patch_line_stats": { + "ignore": true + }, + "git_patch_print": { + "ignore": true + }, + "git_patch_to_buf": { + "ignore": true + } + } + }, + "pathspec": { + "functions": { + "git_pathspec_new": { + "ignore": true + } + } + }, + "push": { + "cType": "git_push", + "functions": { + "git_push_finish": { + "isAsync": true, + "return": { + "isErrorCode": true + } + }, + "git_push_set_callbacks": { + "ignore": true + }, + "git_push_status_foreach": { + "ignore": true + } + } + }, + "refdb": { + "functions": { + "git_refdb_backend_fs": { + "ignore": true + }, + "git_refdb_init_backend": { + "ignore": true + }, + "git_refdb_set_backend": { + "ignore": true + }, + "git_refdb_new": { + "ignore": true + } + } + }, + "refdb_backend": { + "ignore": true + }, + "reference": { + "cppClassName": "GitRefs", + "functions": { + "git_reference__alloc": { + "ignore": true + }, + "git_reference__alloc_symbolic": { + "ignore": true + }, + "git_reference_foreach": { + "ignore": true + }, + "git_reference_foreach_glob": { + "ignore": true + }, + "git_reference_foreach_name": { + "ignore": true + }, + "git_reference_free": { + "ignore": true + }, + "git_reference_iterator_free": { + "ignore": true + }, + "git_reference_iterator_glob_new": { + "ignore": true + }, + "git_reference_iterator_new": { + "ignore": true + }, + "git_reference_list": { + "args": { + "array": { + "isReturn": true, + "shouldAlloc": true, + "cppClassName": "Array", + "jsClassName": "Array", + "size": "count", + "key": "strings" + } + }, + "isAsync": true + }, + "git_reference_next": { + "ignore": true + }, + "git_reference_next_name": { + "ignore": true + }, + "git_reference_symbolic_set_target": { + "args": { + "signature": { + "isOptional": true + }, + "log_message": { + "isOptional": true + } + } + } + } + }, + "reference_iterator": { + "cDependencies": [ + "git2/sys/refdb_backend.h" + ], + "needsForwardDeclaration": false, + "ignore": true + }, + "refspec": { + "cType": "git_refspec", + "functions": { + "git_refspec_rtransform": { + "ignore": true + }, + "git_refspec_string": { + "ignore": true + }, + "git_refspec_transform": { + "ignore": true + } + } + }, + "remote": { + "cType": "git_remote", + "functions": { + "git_remote_default_branch": { + "ignore": true + }, + "git_remote_get_fetch_refspecs": { + "ignore": true + }, + "git_remote_get_push_refspecs": { + "ignore": true + }, + "git_remote_list": { + "args": { + "out": { + "shouldAlloc": true + } + } + }, + "git_remote_ls": { + "ignore": true + }, + "git_remote_rename": { + "ignore": true + } + } + }, + "remote_callbacks": { + "fields": { + "completion": { + "ignore": true + }, + "sideband_progress": { + "ignore": true + }, + "transfer_progress": { + "ignore": true + }, + "update_tips": { + "ignore": true + } + } + }, + "remote_head": { + "ignore": true + }, + "repository": { + "functions": { + "git_repository_discover": { + "ignore": true + }, + "git_repository_fetchhead_foreach": { + "ignore": true + }, + "git_repository_free": { + "ignore": true + }, + "git_repository_hashfile": { + "ignore": true + }, + "git_repository_mergehead_foreach": { + "ignore": true + }, + "git_repository_message": { + "ignore": true + } + } + }, + "revparse": { + "functions": { + "git_revparse": { + "ignore": true + } + } + }, + "revspec": { + "ignore": true + }, + "revwalk": { + "functions": { + "git_revwalk_add_hide_cb": { + "ignore": true + }, + "git_revwalk_free": { + "ignore": true + }, + "git_revwalk_new": { + "isAsync": false + } + } + + }, + "signature": { + "functions": { + "git_signature_new": { + "isAsync": false + } + } + }, + "smart": { + "functions": { + "git_smart_subtransport_git": { + "ignore": true + }, + "git_smart_subtransport_http": { + "ignore": true + }, + "git_smart_subtransport_ssh": { + "ignore": true + } + } + }, + "stash": { + "functions": { + "git_stash_foreach": { + "ignore": true + } + } + }, + "status": { + "cDependencies": [ + "git2/sys/diff.h" + ], + "functions": { + "git_status_byindex": { + "ignore": true + }, + "git_status_foreach": { + "ignore": true + }, + "git_status_foreach_ext": { + "ignore": true + }, + "git_status_init_options": { + "ignore": true + }, + "git_status_list_new": { + "ignore": true + } + } + }, + "submodule": { + "functions": { + "git_submodule_foreach": { + "ignore": true + }, + "git_submodule_location": { + "ignore": true + }, + "git_submodule_status": { + "ignore": true + } + } + }, + "tag": { + "functions": { + "git_tag_foreach": { + "ignore": true + }, + "git_tag_target": { + "args": { + "target_out": { + "isReturn": true + } + } + } + } + }, + "trace": { + "functions": { + "git_trace_set": { + "ignore": true + } + } + }, + "transport": { + "cType": "git_transport", + "functions": { + "git_transport_dummy": { + "ignore": true + }, + "git_transport_local": { + "ignore": true + }, + "git_transport_new": { + "ignore": true + }, + "git_transport_register": { + "ignore": true + }, + "git_transport_smart": { + "ignore": true + } + } + }, + "tree": { + "functions": { + "git_tree_entry_byindex": { + "jsFunctionName": "_entryByIndex" + }, + "git_tree_entrycount": { + "jsFunctionName": "entryCount" + }, + "git_tree_walk": { + "ignore": true + } + } + }, + "treebuilder": { + "functions": { + "git_treebuilder_filter": { + "ignore": true + } + } + } + } +} diff --git a/generate/filters/and.js b/generate/filters/and.js new file mode 100644 index 000000000..042631623 --- /dev/null +++ b/generate/filters/and.js @@ -0,0 +1,3 @@ +module.exports = function(value, other) { + return value && other; +}; diff --git a/generate/filters/args_info.js b/generate/filters/args_info.js new file mode 100644 index 000000000..b2fb1aa5b --- /dev/null +++ b/generate/filters/args_info.js @@ -0,0 +1,30 @@ +module.exports = function(args) { + var result = [], + cArg, + jsArg; + + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { + var arg = args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + arg.isJsArg = true; + arg.jsArg = jsArg; + + jsArg++; + } + + if (cArg === args.length -1) { + arg.lastArg = true; + } + else { + arg.lastArg = false; + } + + arg.cArg = cArg; + arg.isCppClassStringOrArray = ~["String", "Array"].indexOf(arg.cppClassName); + + result.push(arg); + } + + return result; +}; diff --git a/generate/filters/cpp_to_v8.js b/generate/filters/cpp_to_v8.js new file mode 100644 index 000000000..96b2b0ba6 --- /dev/null +++ b/generate/filters/cpp_to_v8.js @@ -0,0 +1,11 @@ +var isV8Value = require("./is_v8_value"); + +module.exports = function(cppClassName) { + if (cppClassName === "Integer") { + cppClassName = "Number"; + } else if (cppClassName === "Wrapper"){ + cppClassName = "String"; + } + + return isV8Value(cppClassName) ? cppClassName : "Object"; +}; diff --git a/generate/filters/default_value.js b/generate/filters/default_value.js new file mode 100644 index 000000000..42682549e --- /dev/null +++ b/generate/filters/default_value.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return cType === "git_otype" ? "GIT_OBJ_ANY" : "0"; +}; diff --git a/generate/filters/fields_info.js b/generate/filters/fields_info.js new file mode 100644 index 000000000..8ec8a930b --- /dev/null +++ b/generate/filters/fields_info.js @@ -0,0 +1,17 @@ +module.exports = function(fields) { + var result = []; + + fields.forEach(function (field){ + var fieldInfo = {}; + + fieldInfo.__proto__ = field; + + fieldInfo.parsedName = field.name || "result"; + fieldInfo.isCppClassIntType = ~["Uint32", "Int32"].indexOf(field.cppClassName); + fieldInfo.parsedClassName = (field.cppClassName || '').toLowerCase() + "_t"; + + result.push(fieldInfo); + }); + + return result; +}; diff --git a/generate/filters/has_return_type.js b/generate/filters/has_return_type.js new file mode 100644 index 000000000..2d21a0e66 --- /dev/null +++ b/generate/filters/has_return_type.js @@ -0,0 +1,7 @@ +module.exports = function(functionInfo) { + if (functionInfo.return) { + return functionInfo.return.cType != "void" || functionInfo.return.isErrorCode; + } + + return false; +}; diff --git a/generate/filters/has_returns.js b/generate/filters/has_returns.js new file mode 100644 index 000000000..733bfe6a3 --- /dev/null +++ b/generate/filters/has_returns.js @@ -0,0 +1,15 @@ +module.exports = function(fn) { + var args = fn.args || []; + var result = args.some(function (arg) { + return arg.isReturn; + }); + + if (!result + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + result = true; + } + + return result || (fn.return && fn.return.isErrorCode); +}; diff --git a/generate/filters/is_double_pointer.js b/generate/filters/is_double_pointer.js new file mode 100644 index 000000000..9d1246ab4 --- /dev/null +++ b/generate/filters/is_double_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return /\s*\*\*\s*/.test(cType); +}; diff --git a/generate/filters/is_pointer.js b/generate/filters/is_pointer.js new file mode 100644 index 000000000..a5dbb053e --- /dev/null +++ b/generate/filters/is_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return /\s*\*\s*/.test(cType); +}; diff --git a/generate/filters/is_v8_value.js b/generate/filters/is_v8_value.js new file mode 100644 index 000000000..f773ff6a2 --- /dev/null +++ b/generate/filters/is_v8_value.js @@ -0,0 +1,14 @@ +var v8 = [ + "Boolean", + "Number", + "String", + "Integer", + "Int32", + "Uint32", + "Date", + "Function" +]; + +module.exports = function(cppClassName) { + return v8.indexOf(cppClassName) > -1; +}; diff --git a/generate/filters/js_args_count.js b/generate/filters/js_args_count.js new file mode 100644 index 000000000..5be437f41 --- /dev/null +++ b/generate/filters/js_args_count.js @@ -0,0 +1,18 @@ +module.exports = function(args) { + var cArg, + jsArg; + + if (!args) { + return 0; + } + + for(cArg = 0, jsArg = 0; cArg < args.length; cArg++) { + var arg = args[cArg]; + + if (!arg.isReturn && !arg.isSelf && !arg.isPayload) { + jsArg++; + } + } + + return jsArg; +}; diff --git a/generate/filters/or.js b/generate/filters/or.js new file mode 100644 index 000000000..fe02c2a87 --- /dev/null +++ b/generate/filters/or.js @@ -0,0 +1,3 @@ +module.exports = function(value, other) { + return value || other; +}; diff --git a/generate/filters/payload_for.js b/generate/filters/payload_for.js new file mode 100644 index 000000000..412cf6123 --- /dev/null +++ b/generate/filters/payload_for.js @@ -0,0 +1,14 @@ +module.exports = function(fields, payloadForField) { + fields = fields || []; + + var result = fields.filter(function (field) { + return field.payloadFor && (field.payloadFor === payloadForField || field.payloadFor === "*"); + }); + + if (result.length > 0) { + return result[0].name; + } + else { + return ""; + } +}; diff --git a/generate/filters/replace.js b/generate/filters/replace.js new file mode 100644 index 000000000..15ed9c71f --- /dev/null +++ b/generate/filters/replace.js @@ -0,0 +1,3 @@ +module.exports = function(value, find, replace) { + return value.replace(find, replace); +}; diff --git a/generate/filters/returns_count.js b/generate/filters/returns_count.js new file mode 100644 index 000000000..9ba92aec4 --- /dev/null +++ b/generate/filters/returns_count.js @@ -0,0 +1,15 @@ +module.exports = function(fn) { + var args = fn.args || []; + var result = args.reduce(function (currentValue, arg) { + return currentValue + (arg.isReturn ? 1 : 0); + }, 0); + + if (!result + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + result = 1; + } + + return result; +}; diff --git a/generate/filters/returns_info.js b/generate/filters/returns_info.js new file mode 100644 index 000000000..1c2856901 --- /dev/null +++ b/generate/filters/returns_info.js @@ -0,0 +1,40 @@ +module.exports = function(fn, argReturnsOnly, isAsync) { + var result = []; + var args = fn.args || []; + + args.forEach(function (arg) { + if (!arg.isReturn) return; + + var return_info = {}; + + return_info.__proto__ = arg; + + return_info.parsedName = isAsync ? "baton->" + return_info.name : return_info.name; + return_info.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(return_info.cppClassName); + return_info.parsedClassName = (return_info.cppClassName || '').toLowerCase() + "_t"; + return_info.returnNameOrName = return_info.returnName || return_info.name; + return_info.jsOrCppClassName = return_info.jsClassName || return_info.cppClassName; + + result.push(return_info); + }); + + if (!result.length + && !argReturnsOnly + && fn.return + && !fn.return.isErrorCode + && fn.return.cType != "void") { + var return_info = {}; + + return_info.__proto__ = fn.return; + return_info.parsedName = return_info.name && isAsync ? "baton->" + return_info.name : "result"; + return_info.isCppClassIntType = ~['Uint32', 'Int32'].indexOf(return_info.cppClassName); + return_info.parsedClassName = (return_info.cppClassName || '').toLowerCase() + "_t"; + return_info.returnNameOrName = return_info.returnName || return_info.name; + return_info.jsOrCppClassName = return_info.jsClassName || return_info.cppClassName; + + result.push(return_info); + } + + + return result; +}; diff --git a/generate/filters/title_case.js b/generate/filters/title_case.js new file mode 100644 index 000000000..8c22b32bb --- /dev/null +++ b/generate/filters/title_case.js @@ -0,0 +1,9 @@ +module.exports = function(str) { + return str.split(/_|\//).map(function(val, index) { + if (val.length) { + return val[0].toUpperCase() + val.slice(1); + } + + return val; + }).join(""); +}; diff --git a/generate/filters/un_pointer.js b/generate/filters/un_pointer.js new file mode 100644 index 000000000..99382f36f --- /dev/null +++ b/generate/filters/un_pointer.js @@ -0,0 +1,3 @@ +module.exports = function(cType) { + return cType.replace(/\s*\*\s*$/, ""); +}; diff --git a/generate/filters/upper.js b/generate/filters/upper.js new file mode 100644 index 000000000..bf0aa534b --- /dev/null +++ b/generate/filters/upper.js @@ -0,0 +1,3 @@ +module.exports = function(value) { + return value.toUpperCase(); +}; diff --git a/generate/index.js b/generate/index.js new file mode 100644 index 000000000..23e36792e --- /dev/null +++ b/generate/index.js @@ -0,0 +1,110 @@ +const path = require("path"); +const combyne = require("combyne"); +const file = require("./util/file"); +const idefs = require("./idefs"); +const promisify = require("promisify-node"); +const fse = promisify(require("fs-extra")); + +// Customize the delimiters so as to not process `{{{` or `}}}`. +combyne.settings.delimiters = { + START_RAW: "{{=", + END_RAW: "=}}" +}; + +var partials = { + asyncFunction: file.read("partials/async_function.cc"), + convertFromV8: file.read("partials/convert_from_v8.cc"), + convertToV8: file.read("partials/convert_to_v8.cc"), + doc: file.read("partials/doc.cc"), + fields: file.read("partials/fields.cc"), + guardArguments: file.read("partials/guard_arguments.cc"), + syncFunction: file.read("partials/sync_function.cc"), + fieldAccessors: file.read("partials/field_accessors.cc") +}; + +var templates = { + class_content: file.read("templates/class_content.cc"), + struct_content: file.read("templates/struct_content.cc"), + class_header: file.read("templates/class_header.h"), + struct_header: file.read("templates/struct_header.h"), + binding: file.read("templates/binding.gyp"), + nodegit: file.read("templates/nodegit.cc"), + enums: file.read("templates/enums.js") +}; + +var filters = { + upper: require("./filters/upper"), + replace: require("./filters/replace"), + titleCase: require("./filters/title_case"), + or: require("./filters/or"), + and: require("./filters/and"), + defaultValue: require("./filters/default_value"), + argsInfo: require("./filters/args_info"), + cppToV8: require("./filters/cpp_to_v8"), + jsArgsCount: require("./filters/js_args_count"), + isV8Value: require("./filters/is_v8_value"), + isPointer: require("./filters/is_pointer"), + isDoublePointer: require("./filters/is_double_pointer"), + unPointer: require("./filters/un_pointer"), + payloadFor: require("./filters/payload_for"), + hasReturnType: require("./filters/has_return_type"), + hasReturns: require("./filters/has_returns"), + returnsCount: require("./filters/returns_count"), + returnsInfo: require("./filters/returns_info"), + fieldsInfo: require("./filters/fields_info") +}; + +// Convert Buffers to Combyne templates. +Object.keys(templates).forEach(function(template) { + templates[template] = combyne(templates[template]); + + // Attach all filters to all templates. + Object.keys(filters).forEach(function(filter) { + templates[template].registerFilter(filter, filters[filter]); + }); +}); + +// Attach all partials to select templates. +Object.keys(partials).forEach(function(partial) { + templates.class_content.registerPartial(partial, combyne(partials[partial])); + templates.struct_content.registerPartial(partial, combyne(partials[partial])); +}); + + +// Determine which definitions to actually include in the source code. +// This might not be needed anymore but to be frank I'm not totally positive +var enabled = idefs.filter(function(idef) { + return !idef.ignore; +}); + +fse.remove(path.resolve(__dirname, "../src")).then(function() { + return fse.remove(path.resolve(__dirname, "../include")); +}).then(function() { + return fse.copy(path.resolve(__dirname, "./manual/"), path.resolve(__dirname, "../")); +}).then(function() { + // Write out single purpose templates. + file.write("../binding.gyp", templates.binding.render(enabled)); + file.write("../src/nodegit.cc", templates.nodegit.render(enabled)); + + + // Write out all the classes. + enabled.forEach(function(idef) { + try { + if (idef.type == "struct") { + file.write("../src/" + idef.filename + ".cc", templates.struct_content.render(idef)); + file.write("../include/" + idef.filename + ".h", templates.struct_header.render(idef)); + } + else if (idef.type == "class") { + file.write("../src/" + idef.filename + ".cc", templates.class_content.render(idef)); + file.write("../include/" + idef.filename + ".h", templates.class_header.render(idef)); + } + } + catch (e) { + if (process.env.BUILD_ONLY) { + console.log(e); + } + } + }); + + file.write("../lib/enums.js", templates.enums.render(enabled)); +}); diff --git a/generate/libgit2-supplement.json b/generate/libgit2-supplement.json new file mode 100644 index 000000000..693b2d865 --- /dev/null +++ b/generate/libgit2-supplement.json @@ -0,0 +1,298 @@ +{ + "types": { + "git_cred_default": { + "decl": "git_cred" + }, + "git_diff_hunk": { + "decl": [ + "int old_start", + "int old_lines", + "int new_start", + "int new_lines", + "size_t header_len", + "char header[128]" + ], + "fields": [ + { + "name": "old_start", + "type": "int" + }, + { + "name": "old_lines", + "type": "int" + }, + { + "name": "new_start", + "type": "int" + }, + { + "name": "new_lines", + "type": "int" + }, + { + "name": "header_len", + "type": "size_t" + }, + { + "name": "header", + "type": "char *" + } + ] + }, + "git_diff_line": { + "decl": [ + "int origin", + "int old_lineno", + "int new_lineno", + "int num_lines", + "size_t, content_len", + "git_off_t content_offset", + "const char * content" + ], + "fields": [ + { + "name": "origin", + "type": "int" + }, + { + "name": "old_lineno", + "type": "int" + }, + { + "name": "new_lineno", + "type": "int" + }, + { + "name": "num_lines", + "type": "int" + }, + { + "name": "content_len", + "type": "size_t" + }, + { + "name": "content_offset", + "type": "git_off_t" + }, + { + "name": "content", + "type": "const char *" + } + ] + }, + "git_note_iterator": { + "decl": "git_iterator" + }, + "git_tree_entry": { + "fields": [ + { + "name": "removed", + "type": "uint16_t" + }, + { + "name": "attr", + "type": "uint16_t" + }, + { + "name": "oid", + "type": "git_oid" + }, + { + "name": "filename_len", + "type": "size_t" + }, + { + "name": "filename", + "structType": "char", + "structName": "filename[1]", + "type": "char *" + } + ] + } + }, + "new" : { + "types": [ + [ + "git_direction", + { + "type": "enum", + "description": "Enum to indicate the direction that a remote connection is going to go", + "fields": [ + { + "type": "int", + "name": "GIT_DIRECTION_FETCH", + "comments": "Fetching from the remote repository", + "value": 0 + }, + { + "type": "int", + "name": "GIT_DIRECTION_PUSH", + "comments": "Pushing to a remote repository", + "value": 1 + } + ] + } + ], + [ + "git_diff_perfdata", + { + "type": "struct", + "fields": [ + { + "type": "unsigned int", + "name": "version" + }, + { + "type": "size_t", + "name": "stat_calls" + }, + { + "type": "size_t", + "name": "oid_calculations" + } + ] + } + ], + [ + "git_merge_options", + { + "type": "struct", + "fields": [ + { + "type": "unsigned int", + "name": "version" + }, + { + "type": "git_merge_tree_flag_t", + "name": "flags" + }, + { + "type": "unsigned int", + "name": "rename_threshold" + }, + { + "type": "unsigned int", + "name": "target_limit" + }, + { + "type": "git_diff_similarity_metric *", + "name": "metric", + "ignore": true + }, + { + "type": "git_merge_file_favor_t", + "name": "file_favor" + } + ], + "used": { + "needs": [ + "git_merge_init_options" + ] + } + } + ], + [ + "git_off_t", + { + "type": "enum" + } + ], + [ + "git_remote_autotag_option_t", + { + "type": "enum" + } + ], + [ + "git_sort_t", + { + "type": "enum", + "description": "Flags to specify the sorting which a revwalk should perform.", + "fields": [ + { + "type": "int", + "name": "GIT_SORT_NONE", + "comments": "Sort the repository contents in no particular ordering; this sorting is arbitrary, implementation-specific and subject to change at any time. This is the default sorting for new walkers.", + "value": 0 + }, + { + "type": "int", + "name": "GIT_SORT_TOPOLOGICAL", + "comments": "Sort the repository contents in topological order (parents before children); this sorting mode can be combined with time sorting.", + "value": 1 + }, + { + "type": "int", + "name": "GIT_SORT_TIME", + "comments": "Sort the repository contents by commit time; this sorting mode can be combined with topological sorting.", + "value": 2 + }, + { + "type": "int", + "name": "GIT_SORT_REVERSE", + "comments": "Iterate through the repository contents in reverse order; this sorting mode can be combined with any of the above.", + "value": 4 + } + ], + "comments": "" + } + ], + [ + "git_time_t", + { + "type": "enum" + } + ], + [ + "git_trace_level_t", + { + "type": "enum" + } + ] + ], + "groups": [ + [ + "odb_object", + [ + "git_odb_object_data", + "git_odb_object_dup", + "git_odb_object_free", + "git_odb_object_id", + "git_odb_object_size", + "git_odb_object_type" + ] + ], + [ + "merge_head", + [ + "git_merge_head_free", + "git_merge_head_from_fetchhead", + "git_merge_head_from_id", + "git_merge_head_from_ref", + "git_merge_head_id" + ] + ] + ] + }, + "remove": { + "odb": { + "functions": [ + "git_odb_object_data", + "git_odb_object_dup", + "git_odb_object_free", + "git_odb_object_id", + "git_odb_object_size", + "git_odb_object_type" + ] + }, + "merge": { + "functions": [ + "git_merge_head_free", + "git_merge_head_from_fetchhead", + "git_merge_head_from_id", + "git_merge_head_from_ref", + "git_merge_head_id" + ] + } + } +} diff --git a/include/functions/copy.h b/generate/manual/include/functions/copy.h similarity index 88% rename from include/functions/copy.h rename to generate/manual/include/functions/copy.h index 9cc8659ef..299d07fea 100644 --- a/include/functions/copy.h +++ b/generate/manual/include/functions/copy.h @@ -14,6 +14,5 @@ const git_index_time *git_index_time_dup(const git_index_time *arg); const git_time *git_time_dup(const git_time *arg); const git_diff_delta *git_diff_delta_dup(const git_diff_delta *arg); const git_diff_file *git_diff_file_dup(const git_diff_file *arg); -const git_diff_range *git_diff_range_dup(const git_diff_range *arg); #endif diff --git a/generate/manual/include/macros.h b/generate/manual/include/macros.h new file mode 100644 index 000000000..80e63ab04 --- /dev/null +++ b/generate/manual/include/macros.h @@ -0,0 +1,12 @@ +#ifndef NODEGIT_PSUEDONAN_H_ +#if (NODE_MODULE_VERSION > 0x000B) +// Node 0.11+ (0.11.3 and below won't compile with these) +# define NodeGitPsueodoNanReturnEscapingValue(val) NanReturnValue(NanEscapeScope(val)) + +#else +// Node 0.8 and 0.10 +# define NodeGitPsueodoNanReturnEscapingValue(val) NanReturnValue(val) + +#endif + +#endif //NODEGIT_PSUEDONAN_H_ diff --git a/include/wrapper.h b/generate/manual/include/wrapper.h similarity index 88% rename from include/wrapper.h rename to generate/manual/include/wrapper.h index 5cb98063e..32b07ce26 100644 --- a/include/wrapper.h +++ b/generate/manual/include/wrapper.h @@ -17,7 +17,7 @@ class Wrapper : public ObjectWrap { public: static Persistent constructor_template; - static void Initialize (Handle target); + static void InitializeComponent (Handle target); void *GetValue(); static Handle New(void *raw); diff --git a/src/functions/copy.cc b/generate/manual/src/functions/copy.cc similarity index 87% rename from src/functions/copy.cc rename to generate/manual/src/functions/copy.cc index d534c3da0..0effadb2c 100644 --- a/src/functions/copy.cc +++ b/generate/manual/src/functions/copy.cc @@ -45,9 +45,3 @@ const git_diff_file *git_diff_file_dup(const git_diff_file *arg) { *result = *arg; return result; } - -const git_diff_range *git_diff_range_dup(const git_diff_range *arg) { - git_diff_range *result = (git_diff_range *)malloc(sizeof(git_diff_range)); - *result = *arg; - return result; -} diff --git a/src/wrapper.cc b/generate/manual/src/wrapper.cc similarity index 96% rename from src/wrapper.cc rename to generate/manual/src/wrapper.cc index ac719d464..4b32340ff 100644 --- a/src/wrapper.cc +++ b/generate/manual/src/wrapper.cc @@ -15,14 +15,14 @@ Wrapper::Wrapper(void *raw) { this->raw = raw; } -void Wrapper::Initialize(Handle target) { +void Wrapper::InitializeComponent(Handle target) { NanScope(); Local tpl = NanNew(New); tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->SetClassName(NanNew("Wrapper")); - + NODE_SET_PROTOTYPE_METHOD(tpl, "toBuffer", ToBuffer); NanAssignPersistent(constructor_template, tpl); @@ -44,12 +44,12 @@ NAN_METHOD(Wrapper::New) { Handle Wrapper::New(void *raw) { NanEscapableScope(); - + Handle argv[1] = { NanNew((void *)raw) }; Local instance; Local constructorHandle = NanNew(constructor_template); instance = constructorHandle->GetFunction()->NewInstance(1, argv); - + return NanEscapeScope(instance); } @@ -67,7 +67,7 @@ NAN_METHOD(Wrapper::ToBuffer) { int len = args[0]->ToNumber()->Value(); Local bufferConstructor = Local::Cast( - NanGetCurrentContext()->Global()->Get(NanNew("Buffer"))); + NanGetCurrentContext()->Global()->Get(NanNew("Buffer"))); Handle constructorArgs[1] = { NanNew(len) }; Local nodeBuffer = bufferConstructor->NewInstance(1, constructorArgs); diff --git a/generate/missing-tests-ignore.json b/generate/missing-tests-ignore.json new file mode 100644 index 000000000..eac03aba8 --- /dev/null +++ b/generate/missing-tests-ignore.json @@ -0,0 +1,34 @@ +{ + "blob": { + "functions": [ + "createFrombuffer", + "isBinary", + "lookup", + "rawcontent", + "rawsize" + ] + }, + "clone": { + "functions": [ + "initOptions" + ] + }, + "commit": { + "functions": [ + "parentCount", + "parentId", + "treeId" + ] + }, + "diff": { + "functions": [ + "getDelta", + "numDeltas" + ] + }, + "object": { + "functions": [ + "type" + ] + } +} diff --git a/generate/missing-tests.js b/generate/missing-tests.js new file mode 100644 index 000000000..339f1a217 --- /dev/null +++ b/generate/missing-tests.js @@ -0,0 +1,64 @@ +const path = require("path"); +const idefs = require("./idefs"); +const Promise = require("nodegit-promise"); +const promisify = require("promisify-node"); +const fse = promisify(require("fs-extra")); +const testFilesPath = path.resolve(__dirname, "../test/tests"); +const missingFileIgnores = require("./missing-tests-ignore"); + +var output = {}; + +function findMissingTest(idef) { + var testFilePath = path.join(testFilesPath, idef.filename + ".js"); + var result = {}; + + return fse.readFile(testFilePath, "utf8") + .then(function(file) { + var fieldsResult = []; + var functionsResult = []; + var fieldIgnores = (missingFileIgnores[idef.filename] || {}).fields; + var functionIgnores = (missingFileIgnores[idef.filename] || {}).functions; + + fieldIgnores = fieldIgnores || []; + functionIgnores = functionIgnores || []; + file = file || ""; + + idef.fields.forEach(function(field) { + if (file.indexOf(field.jsFunctionName) < 0 + && fieldIgnores.indexOf(field.jsFunctionName < 0)) { + fieldsResult.push(field.jsFunctionName); + } + }); + + result.fields = fieldsResult; + + idef.functions.forEach(function(fn) { + if (file.indexOf(fn.jsFunctionName) < 0 + && functionIgnores.indexOf(fn.jsFunctionName) < 0) { + functionsResult.push(fn.jsFunctionName); + } + }); + + result.functions = functionsResult; + }, + function() { + result.testFileMissing = false; + result.testFilePath = testFilePath; + }).then(function() { + output[idef.filename] = result; + }); +}; + +var promises = []; + +idefs.forEach(function(idef) { + promises.push(findMissingTest(idef)); +}); + +Promise.all(promises) +.then(function() { + fse.writeFileSync(path.join(__dirname, "missing-tests.json"), + JSON.stringify(output, null, 2)); +}, function(fail) { + console.log(fail); +}); diff --git a/generate/partials/async_function.cc b/generate/partials/async_function.cc new file mode 100644 index 000000000..cf6dd38b3 --- /dev/null +++ b/generate/partials/async_function.cc @@ -0,0 +1,136 @@ + +{%partial doc .%} +NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { + NanScope(); + {%partial guardArguments .%} + if (args.Length() == {{args|jsArgsCount}} || !args[{{args|jsArgsCount}}]->IsFunction()) { + return NanThrowError("Callback is required and must be a Function."); + } + + {{ cppFunctionName }}Baton* baton = new {{ cppFunctionName }}Baton; + + baton->error_code = GIT_OK; + baton->error = NULL; + + {%each args|argsInfo as arg %} + {%if not arg.isReturn %} + {%if arg.isSelf %} + baton->{{ arg.name }} = ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue(); + {%elsif arg.name %} + {%partial convertFromV8 arg%} + {%if not arg.isPayload %} + baton->{{ arg.name }} = from_{{ arg.name }}; + {%endif%} + {%endif%} + {%elsif arg.shouldAlloc %} + baton->{{ arg.name }} = ({{ arg.cType }})malloc(sizeof({{ arg.cType|replace '*' '' }})); + {%endif%} + {%endeach%} + + NanCallback *callback = new NanCallback(Local::Cast(args[{{args|jsArgsCount}}])); + {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback); + {%each args|argsInfo as arg %} + {%if not arg.isReturn %} + {%if arg.isSelf %} + worker->SaveToPersistent("{{ arg.name }}", args.This()); + {%else%} + if (!args[{{ arg.jsArg }}]->IsUndefined() && !args[{{ arg.jsArg }}]->IsNull()) + worker->SaveToPersistent("{{ arg.name }}", args[{{ arg.jsArg }}]->ToObject()); + {%endif%} + {%endif%} + {%endeach%} + + NanAsyncQueueWorker(worker); + NanReturnUndefined(); +} + +void {{ cppClassName }}::{{ cppFunctionName }}Worker::Execute() { + {%if .|hasReturnType %} + {{ return.cType }} result = {{ cFunctionName }}( + {%else%} + {{ cFunctionName }}( + {%endif%} + {%-- Insert Function Arguments --%} + {%each args|argsInfo as arg %} + {%-- turn the pointer into a ref --%} + {%if arg.isReturn|and arg.cType|isDoublePointer %}&{%endif%}baton->{{ arg.name }}{%if not arg.lastArg %},{%endif%} + + {%endeach%} + ); + + {%if return.isErrorCode %} + baton->error_code = result; + + if (result != GIT_OK && giterr_last() != NULL) { + baton->error = git_error_dup(giterr_last()); + } + + {%elsif not return.cType == 'void' %} + + baton->result = result; + + {%endif%} +} + +void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { + TryCatch try_catch; + + if (baton->error_code == GIT_OK) { + {%if not .|returnsCount %} + Handle result = NanUndefined(); + {%else%} + Handle to; + {%if .|returnsCount > 1 %} + Handle result = NanNew(); + {%endif%} + {%each .|returnsInfo 0 1 as _return %} + {%partial convertToV8 _return %} + {%if .|returnsCount > 1 %} + result->Set(NanNew("{{ _return.returnNameOrName }}"), to); + {%endif%} + {%endeach%} + {%if .|returnsCount == 1 %} + Handle result = to; + {%endif%} + {%endif%} + Handle argv[2] = { + NanNull(), + result + }; + callback->Call(2, argv); + } else { + if (baton->error) { + Handle argv[1] = { + NanError(baton->error->message) + }; + callback->Call(1, argv); + if (baton->error->message) + free((void *)baton->error->message); + free((void *)baton->error); + } else { + callback->Call(0, NULL); + } + + {%each args as arg %} + {%if arg.shouldAlloc %} + free((void*)baton->{{ arg.name }}); + {%endif%} + {%endeach%} + } + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + + {%each args|argsInfo as arg %} + {%if arg.isCppClassStringOrArray %} + {%if arg.freeFunctionName %} + {{ arg.freeFunctionName }}(baton->{{ arg.name }}); + {%else%} + free((void *)baton->{{ arg.name }}); + {%endif%} + {%endif%} + {%endeach%} + + delete baton; +} diff --git a/generate/partials/convert_from_v8.cc b/generate/partials/convert_from_v8.cc new file mode 100644 index 000000000..788f24e27 --- /dev/null +++ b/generate/partials/convert_from_v8.cc @@ -0,0 +1,51 @@ +{%if not isPayload %} + {{ cType }} from_{{ name }}; + {%if isOptional %} + + if (args[{{ jsArg }}]->Is{{ cppClassName|cppToV8 }}()) { + {%endif%} + {%if cppClassName == 'String'%} + + String::Utf8Value {{ name }}(args[{{ jsArg }}]->ToString()); + from_{{ name }} = ({{ cType }}) strdup(*{{ name }}); + {%elsif cppClassName == 'Wrapper'%} + + String::Utf8Value {{ name }}(args[{{ jsArg }}]->ToString()); + from_{{ name }} = ({{ cType }}) strdup(*{{ name }}); + {%elsif cppClassName == 'Array'%} + + Array *tmp_{{ name }} = Array::Cast(*args[{{ jsArg }}]); + from_{{ name }} = ({{ cType }})malloc(tmp_{{ name }}->Length() * sizeof({{ cType|replace '**' '*' }})); + for (unsigned int i = 0; i < tmp_{{ name }}->Length(); i++) { + {%-- + // FIXME: should recursively call convertFromv8. + --%} + from_{{ name }}[i] = ObjectWrap::Unwrap<{{ arrayElementCppClassName }}>(tmp_{{ name }}->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); + } + {%elsif cppClassName == 'Function'%} + {%elsif cppClassName == 'Buffer'%} + + from_{{ name }} = Buffer::Data(args[{{ jsArg }}]->ToObject()); + {%elsif cppClassName|isV8Value %} + + {%if cType|isPointer %} + *from_{{ name }} = ({{ cType|unPointer }}) {{ cast }} {%if isEnum %}(int){%endif%} args[{{ jsArg }}]->To{{ cppClassName }}()->Value(); + {%else%} + from_{{ name }} = ({{ cType }}) {{ cast }} {%if isEnum %}(int){%endif%} args[{{ jsArg }}]->To{{ cppClassName }}()->Value(); + {%endif%} + {%else%} + {%if cType|isDoublePointer %} + from_{{ name }} = ObjectWrap::Unwrap<{{ cppClassName }}>(args[{{ jsArg }}]->ToObject())->GetRefValue(); + {%else%} + from_{{ name }} = ObjectWrap::Unwrap<{{ cppClassName }}>(args[{{ jsArg }}]->ToObject())->GetValue(); + {%endif%} + {%endif%} + + {%if isOptional %} + } + else { + from_{{ name }} = 0; + } + + {%endif%} +{%endif%} diff --git a/generate/partials/convert_to_v8.cc b/generate/partials/convert_to_v8.cc new file mode 100644 index 000000000..fd2802a0d --- /dev/null +++ b/generate/partials/convert_to_v8.cc @@ -0,0 +1,60 @@ +// start convert_to_v8 block +{%if cppClassName == 'String' %} + if ({{= parsedName =}}){ + {%if size %} + to = NanNew({{= parsedName =}}, {{ size }}); + {%elsif cType == 'char **' %} + + to = NanNew(*{{= parsedName =}}); + {%else%} + to = NanNew({{= parsedName =}}); + {%endif%} + } + else { + to = NanNull(); + } + + {%if freeFunctionName %} +{{ freeFunctionName }}({{= parsedName =}}); + {%endif%} +{%elsif cppClassName|isV8Value %} + {%if isCppClassIntType %} +to = NanNew<{{ cppClassName }}>(({{ parsedClassName }}){{= parsedName =}}); + {%else%} + to = NanNew<{{ cppClassName }}>({{= parsedName =}}); + {%endif%} +{%elsif cppClassName == 'External' %} +to = NanNew((void *){{= parsedName =}}); +{%elsif cppClassName == 'Array' %} +{%-- + // FIXME this is not general purpose enough. +--%} +{%if size%} +Local tmpArray = NanNew({{= parsedName =}}->{{ size }}); +for (unsigned int i = 0; i < {{= parsedName =}}->{{ size }}; i++) { + tmpArray->Set(NanNew(i), NanNew({{= parsedName =}}->{{ key }}[i])); +} +{%else%} +Local tmpArray = NanNew({{= parsedName =}}); +{%endif%} +to = tmpArray; +{%else%} + {%if copy %} + if ({{= parsedName =}} != NULL) { + {{= parsedName =}} = ({{ cType|replace '**' '*' }} {%if not cType|isPointer %}*{%endif%}){{ copy }}({{= parsedName =}}); + } + {%endif%} + + if ({{= parsedName =}} != NULL) { + // {{= cppClassName }} {{= parsedName }} + {%if cppClassName == 'Wrapper' %} + to = {{ cppClassName }}::New((void *){{= parsedName =}}); + {%else%} + to = {{ cppClassName }}::New((void *){{= parsedName =}}, false); + {%endif%} + } else { + to = NanNull(); + } + +{%endif%} +// end convert_to_v8 block diff --git a/generate/partials/doc.cc b/generate/partials/doc.cc new file mode 100644 index 000000000..158a48113 --- /dev/null +++ b/generate/partials/doc.cc @@ -0,0 +1,15 @@ +/** +{%each args as arg %} + {%if not arg.isReturn %} + {%if not arg.isSelf %} + * @param {{ arg.jsClassName }} {{ arg.name }} + {%endif%} + {%endif%} +{%endeach%}{%each .|returnsInfo as returnInfo %} + {%if isAsync %} + * @param {{ returnInfo.jsOrCppClassName }} callback + {%else%} + * @return {{ returnInfo.jsOrCppClassName }} {%if returnInfo.name %}{{ returnInfo.name }}{%else%}result{%endif%} + {%endif%} +{%endeach%} + */ diff --git a/generate/partials/field_accessors.cc b/generate/partials/field_accessors.cc new file mode 100644 index 000000000..a5b629026 --- /dev/null +++ b/generate/partials/field_accessors.cc @@ -0,0 +1,217 @@ +{%each fields|fieldsInfo as field %} + {%if not field.ignore %} + +NAN_GETTER({{ cppClassName }}::Get{{ field.cppFunctionName }}) { + NanScope(); + + {{ cppClassName }} *wrapper = ObjectWrap::Unwrap<{{ cppClassName }}>(args.This()); + + {%if field.isEnum %} + NanReturnValue(NanNew((int)wrapper->GetValue()->{{ field.name }})); + {%elsif field.isLibgitType | or field.payloadFor %} + NanReturnValue(wrapper->{{ field.name }}); + {%elsif field.isCallbackFunction %} + NanReturnValue(wrapper->{{ field.name }}->GetFunction()); + {%elsif field.cppClassName == 'String' %} + if (wrapper->GetValue()->{{ field.name }}) { + NanReturnValue(NanNew(wrapper->GetValue()->{{ field.name }})); + } + else { + NanReturnUndefined(); + } + {%elsif field.cppClassName|isV8Value %} + NanReturnValue(NanNew<{{ field.cppClassName }}>(wrapper->GetValue()->{{ field.name }})); + {%endif%} +} + +NAN_SETTER({{ cppClassName }}::Set{{ field.cppFunctionName }}) { + NanScope(); + + {{ cppClassName }} *wrapper = ObjectWrap::Unwrap<{{ cppClassName }}>(args.This()); + + {%if field.isEnum %} + if (value->IsNumber()) { + wrapper->GetValue()->{{ field.name }} = ({{ field.cType }}) value->Int32Value(); + } + + {%elsif field.isLibgitType %} + NanDisposePersistent(wrapper->{{ field.name }}); + + wrapper->raw->{{ field.name }} = {%if not field.cType | isPointer %}*{%endif%}ObjectWrap::Unwrap<{{ field.cppClassName }}>(value->ToObject())->GetValue(); + {%elsif field.isCallbackFunction %} + if (value->IsFunction()) { + wrapper->{{ field.name }} = new NanCallback(value.As()); + } + {%elsif field.payloadFor %} + NanAssignPersistent(wrapper->{{ field.name }}, value); + {%elsif field.cppClassName == 'String' %} + if (wrapper->GetValue()->{{ field.name }}) { + //free(wrapper->{{ field.name }}); + } + + String::Utf8Value str(value); + wrapper->GetValue()->{{ field.name }} = strdup(*str); + {%elsif field.isCppClassIntType%} + if (value->IsNumber()) { + wrapper->GetValue()->{{ field.name }} = value->{{field.cppClassName}}Value(); + } + {%else%} + if (value->IsNumber()) { + wrapper->GetValue()->{{ field.name }} = ({{ field.cType }}) value->Int32Value(); + } + {%endif%} +} + + {%if field.isCallbackFunction %} +{{ field.returnType }} {{ cppClassName }}::{{ field.name }}_cppCallback ( + {%each field.args|argsInfo as arg%} + {{ arg.cType }} {{ arg.name}}{%if not arg.lastArg %},{%endif%} + + {%endeach%} + ) { + {{ field.name|titleCase }}Baton* baton = new {{ field.name|titleCase }}Baton(); + + {%each field.args|argsInfo as arg %} + baton->{{ arg.name }} = {{ arg.name }}; + {%endeach%} + baton->req.data = baton; + baton->done = false; + + uv_queue_work(uv_default_loop(), &baton->req, {{ field.name }}_asyncWork, {{ field.name }}_asyncAfter); + + while(!baton->done) { + this_thread::sleep_for(chrono::milliseconds(1)); + } + + {%each field|returnsInfo true false as _return %} + *{{ _return.name }} = *baton->{{ _return.name }}; + {%endeach%} + + return baton->result; +} + +void {{ cppClassName }}::{{ field.name }}_asyncWork(uv_work_t* req) { + // We aren't doing any work on a seperate thread, just need to + // access the main node thread in the async after method. + // However, this worker method is still needed +} + +void {{ cppClassName }}::{{ field.name }}_asyncAfter(uv_work_t* req, int status) { + NanScope(); + + {{ field.name|titleCase }}Baton* baton = static_cast<{{ field.name|titleCase }}Baton*>(req->data); + {{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->payload); + + if (instance->{{ field.name }}->IsEmpty()) { + {%if field.returnType == "int" %} + baton->result = {{ field.returnNoResults }}; // no results acquired + {%endif%} + baton->done = true; + return; + } + + Local argv[{{ field.args|jsArgsCount }}] = { + {%each field.args|argsInfo as arg %} + {%if arg.name == "payload" %} + {%-- payload is always the last arg --%} + NanNew(instance->{{ fields|payloadFor field.name }}) + {%elsif arg.isJsArg %} + {%if arg.isEnum %} + NanNew((int)baton->{{ arg.name }}), + {%elsif arg.isLibgitType %} + NanNew({{ arg.cppClassName }}::New(&baton->{{ arg.name }}, false)), + {%elsif arg.cType == "size_t" %} + // HACK: NAN should really have an overload for NanNew to support size_t + NanNew((unsigned int)baton->{{ arg.name }}), + {%else%} + NanNew(baton->{{ arg.name }}), + {%endif%} + {%endif%} + {%endeach%} + }; + + TryCatch tryCatch; + Handle result = instance->{{ field.name }}->Call({{ field.args|jsArgsCount }}, argv); + + if (result->IsObject() && result->ToObject()->Has(NanNew("then"))) { + Handle thenProp = result->ToObject()->Get(NanNew("then")); + + if (thenProp->IsFunction()) { + // we can be reasonbly certain that the result is a promise + Local promise = result->ToObject(); + + NanAssignPersistent(baton->promise, promise); + + uv_queue_work(uv_default_loop(), &baton->req, {{ field.name }}_asyncWork, {{ field.name }}_asyncPromisePolling); + return; + } + } + + {{ field.returnType }} resultStatus; + + {%each field|returnsInfo true false as _return%} + if (result.IsEmpty() || result->IsNativeError()) { + baton->result = {{ field.returnError }}; + } + else if (!result->IsNull() && !result->IsUndefined()) { + {{ _return.cppClassName }}* wrapper = ObjectWrap::Unwrap<{{ _return.cppClassName }}>(result->ToObject()); + wrapper->selfFreeing = false; + + baton->{{ _return.name }} = wrapper->GetRefValue(); + baton->result = {{ field.returnSuccess }}; + } + else { + baton->result = {{ field.returnNoResults }}; + } + {%endeach%} + baton->done = true; +} + +void {{ cppClassName }}::{{ field.name }}_asyncPromisePolling(uv_work_t* req, int status) { + NanScope(); + + {{ field.name|titleCase }}Baton* baton = static_cast<{{ field.name|titleCase }}Baton*>(req->data); + Local promise = NanNew(baton->promise); + NanCallback* isPendingFn = new NanCallback(promise->Get(NanNew("isPending")).As()); + Local argv[1]; // MSBUILD won't assign an array of length 0 + Local isPending = isPendingFn->Call(0, argv)->ToBoolean(); + + if (isPending->Value()) { + uv_queue_work(uv_default_loop(), &baton->req, {{ field.name }}_asyncWork, {{ field.name }}_asyncPromisePolling); + return; + } + + NanCallback* isFulfilledFn = new NanCallback(promise->Get(NanNew("isFulfilled")).As()); + Local isFulfilled = isFulfilledFn->Call(0, argv)->ToBoolean(); + + if (isFulfilled->Value()) { + NanCallback* resultFn = new NanCallback(promise->Get(NanNew("value")).As()); + Handle result = resultFn->Call(0, argv); + {{ field.returnType }} resultStatus; + + {%each field|returnsInfo true false as _return%} + if (result.IsEmpty() || result->IsNativeError()) { + baton->result = {{ field.returnError }}; + } + else if (!result->IsNull() && !result->IsUndefined()) { + {{ _return.cppClassName }}* wrapper = ObjectWrap::Unwrap<{{ _return.cppClassName }}>(result->ToObject()); + wrapper->selfFreeing = false; + + baton->{{ _return.name }} = wrapper->GetRefValue(); + baton->result = {{ field.returnSuccess }}; + } + else { + baton->result = {{ field.returnNoResults }}; + } + {%endeach%} + baton->done = true; + } + else { + // promise was rejected + baton->result = {{ field.returnError }}; + baton->done = false; + } +} + {%endif%} + {%endif%} +{%endeach%} diff --git a/generate/partials/fields.cc b/generate/partials/fields.cc new file mode 100644 index 000000000..45e17503c --- /dev/null +++ b/generate/partials/fields.cc @@ -0,0 +1,15 @@ +{%each fields|fieldsInfo as field %} + {%if not field.ignore %} + +NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { + NanScope(); + Handle to; + + {{ field.cType }} {%if not field.cppClassName|isV8Value %}*{%endif%}{{ field.name }} = + {%if not field.cppClassName|isV8Value %}&{%endif%}ObjectWrap::Unwrap<{{ cppClassName }}>(args.This())->GetValue()->{{ field.name }}; + + {%partial convertToV8 field %} + NanReturnValue(to); +} + {%endif%} +{%endeach%} diff --git a/generate/partials/guard_arguments.cc b/generate/partials/guard_arguments.cc new file mode 100644 index 000000000..9bc969979 --- /dev/null +++ b/generate/partials/guard_arguments.cc @@ -0,0 +1,11 @@ + +{%each args|argsInfo as arg%} + {%if arg.isJsArg%} + {%if not arg.isOptional%} + if (args.Length() == {{arg.jsArg}} || !args[{{arg.jsArg}}]->Is{{arg.cppClassName|cppToV8}}()) { + return NanThrowError("{{arg.jsClassName}} {{arg.name}} is required."); + } + + {%endif%} + {%endif%} +{%endeach%} diff --git a/generate/partials/sync_function.cc b/generate/partials/sync_function.cc new file mode 100644 index 000000000..042a7d3a3 --- /dev/null +++ b/generate/partials/sync_function.cc @@ -0,0 +1,81 @@ + +{%partial doc .%} +NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { + NanEscapableScope(); + {%partial guardArguments .%} + + {%each .|returnsInfo 'true' as _return %} + {%if _return.shouldAlloc %} + {{ _return.cType }}{{ _return.name }} = ({{ _return.cType }})malloc(sizeof({{ _return.cType|unPointer }})); + {%else%} + {{ _return.cType|unPointer }} {{ _return.name }} = {{ _return.cType|unPointer|defaultValue }}; + {%endif%} + {%endeach%} + + {%each args|argsInfo as arg %} + {%if not arg.isSelf %} + {%if not arg.isReturn %} + {%partial convertFromV8 arg %} + {%endif%} + {%endif%} + {%endeach%} + +{%if .|hasReturns %} + {{ return.cType }} result = {%endif%}{{ cFunctionName }}( + {%each args|argsInfo as arg %} + {%if arg.isReturn %} + {%if not arg.shouldAlloc %}&{%endif%} + {%endif%} + {%if arg.isSelf %} +ObjectWrap::Unwrap<{{ arg.cppClassName }}>(args.This())->GetValue() + {%elsif arg.isReturn %} +{{ arg.name }} + {%else%} +from_{{ arg.name }} + {%endif%} + {%if not arg.lastArg %},{%endif%} + {%endeach%} + ); +{%if return.isErrorCode %} + if (result != GIT_OK) { + {%each args|argsInfo as arg %} + {%if arg.shouldAlloc %} + free({{ arg.name }}); + {%endif%} + {%endeach%} + + if (giterr_last()) { + return NanThrowError(giterr_last()->message); + } else { + return NanThrowError("Unknown Error"); + } + } +{%endif%} + +{%if not .|returnsCount %} + NanReturnUndefined(); +{%else%} + {%if return.cType | isPointer %} + // null checks on pointers + if (!result) { + NodeGitPsueodoNanReturnEscapingValue(NanUndefined()); + } + {%endif%} + + Handle to; + {%if .|returnsCount > 1 %} + Handle toReturn = NanNew(); + {%endif%} + {%each .|returnsInfo as _return %} + {%partial convertToV8 _return %} + {%if .|returnsCount > 1 %} + toReturn->Set(NanNew("{{ _return.returnNameOrName }}"), to); + {%endif%} + {%endeach%} + {%if .|returnsCount == 1 %} + NodeGitPsueodoNanReturnEscapingValue(to); + {%else%} + NodeGitPsueodoNanReturnEscapingValue(toReturn); + {%endif%} +{%endif%} +} diff --git a/generate/setup.js b/generate/setup.js new file mode 100644 index 000000000..98cb3617f --- /dev/null +++ b/generate/setup.js @@ -0,0 +1,218 @@ +const fs = require("fs"); +const path = require("path"); +const utils = require("./utils"); +const _ = require("lodash"); + +var version = require("../package.json").libgit2.version; +var descriptor = require("./descriptor.json"); +var libgit2 = require("./v" + version + ".json"); +var supplement = require("./libgit2-supplement.json"); + +libgit2.types.forEach(function(type) { + if (supplement.types[type[0]]){ + _.merge(type[1], supplement.types[type[0]]); + } +}); + +// libgit2's docs aren't complete so we'll add in what they're missing here +Array.prototype.push.apply(libgit2.types, supplement.new.types); +Array.prototype.push.apply(libgit2.groups, supplement.new.groups); + +var output = []; +var dependencyLookup = {}; +var types = []; +var enums = []; + +// reduce all of the groups into a hashmap and a name array for easy lookup +var groups = libgit2.groups.reduce(function(memo, group) { + var groupName = group[0]; + + // Some functions are in the wrong group so we can't just ignore them. + // We have to completely remove them from one group and manually add them + // into the other. + var functionNames = group[1].filter(function(fnName) { + return !supplement.remove[groupName] || + !supplement.remove[groupName].functions || + !~supplement.remove[groupName].functions.indexOf(fnName); + }); + + memo[groupName] = functionNames; + return memo; +}, {}); + + +// Split each type from the array into classes/structs and enums +// each entry is of type ['name', {definingobject}] +libgit2.types.forEach(function(current) { + current[1].typeName = current[0]; + + // just log these out to a file for fun + if (current[1].type === "enum") { + enums.push(current[1]); + } + else { + types.push(current[1]); + } +}); + +var previous = ""; +enums = _(enums).sortBy("name").reduce(function(enumMemo, enumerable) { + if (previous == enumerable.typeName) { + if (process.env.BUILD_ONLY) { + console.warn('Duplicate definition for enum ' + enumerable.typeName + + ". skipped."); + } + } + else if (!enumerable.fields) { + if (process.env.BUILD_ONLY) { + console.warn('Incomplete definition for enum ' + enumerable.typeName + + ". skipped."); + } + } + else { + enumMemo[enumerable.typeName] = { + typeName: enumerable.typeName.replace(/^git_/, "").replace(/_t$/, ""), + type: "enum", + cType: enumerable.typeName, + isMask: (/_t$/).test(enumerable.typeName), + values: enumerable.fields.map(function(field) { + return { + name: field.name, + value: field.value + } + }) + }; + } + + previous = enumerable.typeName; + return enumMemo; +}, {}).valueOf(); + +// decorate the definitions with required data to build the C++ files +types.forEach(function(typeDef) { + var typeName = typeDef.typeName; + typeDef.cType = typeName; + typeName = typeName.replace("git_", ""); + typeDef.typeName = typeName; + dependencyLookup[typeName] = typeName; + + typeDef.functions = groups[typeName] || []; + utils.decoratePrimaryType(typeDef, enums); + + groups[typeName] = false; + + typeDef.type = typeDef.hasConstructor ? "struct" : "class"; + + output.push(typeDef); +}); + +// Loop over the groups in case we missed anything (eg the types are missing in the docs); +for (var groupName in groups) { + var groupDef = groups[groupName]; + if (groupDef === false) { + continue; + } + + groupDef = { + functions: groupDef + }; + + groupDef.type = "class"; + groupDef.cType = (descriptor.types[groupName] || {}).cType || groupDef.cType; + + groupDef.typeName = groupName; + dependencyLookup[groupName] = groupName; + utils.decoratePrimaryType(groupDef, enums); + + output.push(groupDef); +} + +// Calculate dependencies +output.forEach(function (def) { + if (def.ignore) { + return; + } + + var dependencies = {}; + var addDependencies = function (prop) { + if (prop.ignore) { + return; + } + + var type = utils.normalizeCtype(prop.type || prop.cType).replace("git_", ""); + var dependencyFilename = dependencyLookup[type]; + + if (dependencyFilename) { + dependencies[dependencyFilename] = dependencyFilename; + } + + (prop.args || []).forEach(addDependencies); + + if (prop.return) { + addDependencies(prop.return); + } + }; + + def.fields.forEach(addDependencies); + def.functions.forEach(addDependencies); + + Object.keys(dependencies).forEach(function (dependencyFilename) { + def.dependencies.push("../include/" + dependencyFilename + ".h"); + }); + + // Additionally provide a friendly name to the actual filename. + def.name = path.basename(def.filename, ".h"); + + def.functions.forEach(function(fn) { + fn.cppClassName = def.cppClassName; + }); +}); + +// Process enums +_(enums).forEach(function(enumerable) { + output.some(function(obj) { + if (enumerable.typeName.indexOf(obj.typeName) == 0) { + enumerable.owner = obj.jsClassName; + } + else if (enumerable.owner) { + return true; + } + }); + + var override = descriptor.enums[enumerable.typeName] || {}; + + enumerable.owner = override.owner || enumerable.owner || "Enums"; + + enumerable.JsName = enumerable.typeName + .replace(new RegExp("^" + enumerable.owner.toLowerCase()), "") + .replace(/^_/, "") + .toUpperCase(); + + enumerable.values.forEach(function(value) { + value.JsName = value.name + .replace(/^GIT_/, "") + .replace(override.removeString || "", "") + .replace(new RegExp("^" + enumerable.owner.toUpperCase()), "") + .replace(/^_/, "") + .replace(new RegExp("^" + enumerable.JsName), "") + .replace(/^_/, "") + .toUpperCase(); + + if (override.values && override.values[value.name]) { + _.merge(value, override.values[value.name]); + } + }); + + _.merge(enumerable, _.omit(override, ["values"])); + + output.push(enumerable); +}); + +output = _.sortBy(output, "typeName"); + +if (process.argv[2] != "--documentation") { + utils.filterDocumentation(output); +} + +fs.writeFileSync(path.join(__dirname, "idefs.json"), + JSON.stringify(output, null, 2)); diff --git a/generate/templates/binding.gyp b/generate/templates/binding.gyp new file mode 100644 index 000000000..10f292de3 --- /dev/null +++ b/generate/templates/binding.gyp @@ -0,0 +1,57 @@ +# This is a generated file, modify: generate/templates/binding.gyp. +{ + "targets": [ + { + "target_name": "nodegit", + + "dependencies": [ + "<(module_root_dir)/vendor/libgit2.gyp:libgit2" + ], + + "sources": [ + "src/nodegit.cc", + "src/wrapper.cc", + "src/functions/copy.cc", + {%each%} + {% if type != "enum" %} + "src/{{ name }}.cc", + {% endif %} + {%endeach%} + ], + + "include_dirs": [ + "vendor/libv8-convert", + " +#include + +extern "C" { +#include +{%each cDependencies as dependency %} +#include <{{ dependency }}> +{%endeach%} +} + + +#include "../include/functions/copy.h" +#include "../include/macros.h" +#include "../include/{{ filename }}.h" + +{%each dependencies as dependency%} +#include "{{ dependency }}" +{%endeach%} + +#include + +using namespace std; +using namespace v8; +using namespace node; + +{%if cType%} +{{ cppClassName }}::{{ cppClassName }}({{ cType }} *raw, bool selfFreeing) { + this->raw = raw; + this->selfFreeing = selfFreeing; +} + +{{ cppClassName }}::~{{ cppClassName }}() { + {%if freeFunctionName%} + if (this->selfFreeing) { + {{ freeFunctionName }}(this->raw); + } + {%endif%} +} + +void {{ cppClassName }}::InitializeComponent(Handle target) { + NanScope(); + + Local tpl = NanNew(New); + + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(NanNew("{{ jsClassName }}")); + + {%each functions as function%} + {%if not function.ignore%} + {%if function.isPrototypeMethod%} + NODE_SET_PROTOTYPE_METHOD(tpl, "{{ function.jsFunctionName }}", {{ function.cppFunctionName }}); + {%else%} + NODE_SET_METHOD(tpl, "{{ function.jsFunctionName }}", {{ function.cppFunctionName }}); + {%endif%} + {%endif%} + {%endeach%} + + {%each fields as field%} + {%if not field.ignore%} + NODE_SET_PROTOTYPE_METHOD(tpl, "{{ field.jsFunctionName }}", {{ field.cppFunctionName }}); + {%endif%} + {%endeach%} + + Local _constructor_template = tpl->GetFunction(); + NanAssignPersistent(constructor_template, _constructor_template); + target->Set(NanNew("{{ jsClassName }}"), _constructor_template); +} + +NAN_METHOD({{ cppClassName }}::New) { + NanScope(); + + if (args.Length() == 0 || !args[0]->IsExternal()) { + {%if createFunctionName%} + return NanThrowError("A new {{ cppClassName }} cannot be instantiated. Use {{ jsCreateFunctionName }} instead."); + {%else%} + return NanThrowError("A new {{ cppClassName }} cannot be instantiated."); + {%endif%} + } + + {{ cppClassName }}* object = new {{ cppClassName }}(static_cast<{{ cType }} *>(Handle::Cast(args[0])->Value()), args[1]->BooleanValue()); + object->Wrap(args.This()); + + NanReturnValue(args.This()); +} + +Handle {{ cppClassName }}::New(void *raw, bool selfFreeing) { + NanEscapableScope(); + Handle argv[2] = { NanNew((void *)raw), NanNew(selfFreeing) }; + return NanEscapeScope(NanNew({{ cppClassName }}::constructor_template)->NewInstance(2, argv)); +} + +{{ cType }} *{{ cppClassName }}::GetValue() { + return this->raw; +} + +{{ cType }} **{{ cppClassName }}::GetRefValue() { + return &this->raw; +} +{%else%} +void {{ cppClassName }}::InitializeComponent(Handle target) { + NanScope(); + + Local object = NanNew(); + + {%each functions as function%} + {%if not function.ignore%} + NODE_SET_METHOD(object, "{{ function.jsFunctionName }}", {{ function.cppFunctionName }}); + {%endif%} + {%endeach%} + + target->Set(NanNew("{{ jsClassName }}"), object); +} +{%endif%} + +{%each functions as function %} + {%if not function.ignore%} + {%if function.isAsync%} + {%partial asyncFunction function %} + {%else%} + {%partial syncFunction function %} + {%endif%} + {%endif%} +{%endeach%} + +{%partial fields .%} + +{%if not cTypeIsUndefined %} +Persistent {{ cppClassName }}::constructor_template; +{%endif%} diff --git a/generate/templates/class_header.h b/generate/templates/class_header.h new file mode 100644 index 000000000..ab0615362 --- /dev/null +++ b/generate/templates/class_header.h @@ -0,0 +1,100 @@ +#ifndef {{ cppClassName|upper }}_H +#define {{ cppClassName|upper }}_H +// generated from class_header.h +#include +#include + +extern "C" { +#include +{%each cDependencies as dependency %} +#include <{{ dependency }}> +{%endeach%} +} + +{%each dependencies as dependency%} +#include "{{ dependency }}" +{%endeach%} + +{%if needsForwardDeclaration %} +// Forward declaration. +struct {{ cType }} { + {%each fields as field%} + {%if not field.ignore%} + {{ field.structType|or field.cType }} {{ field.structName|or field.name }}; + {%endif%} + {%endeach%} +}; +{%endif%} + +using namespace node; +using namespace v8; + +class {{ cppClassName }} : public ObjectWrap { + public: + + static Persistent constructor_template; + static void InitializeComponent (Handle target); + + {%if cType%} + {{ cType }} *GetValue(); + {{ cType }} **GetRefValue(); + + static Handle New(void *raw, bool selfFreeing); + {%endif%} + bool selfFreeing; + + private: + {%if cType%} + {{ cppClassName }}({{ cType }} *raw, bool selfFreeing); + ~{{ cppClassName }}(); + {%endif%} + + static NAN_METHOD(New); + + {%each fields as field%} + {%if not field.ignore%} + static NAN_METHOD({{ field.cppFunctionName }}); + {%endif%} + {%endeach%} + + {%each functions as function%} + {%if not function.ignore%} + {%if function.isAsync%} + + struct {{ function.cppFunctionName }}Baton { + int error_code; + const git_error* error; + {%each function.args as arg%} + {%if arg.isReturn%} + {{ arg.cType|replace "**" "*" }} {{ arg.name }}; + {%else%} + {{ arg.cType }} {{ arg.name }}; + {%endif%} + {%endeach%} + }; + class {{ function.cppFunctionName }}Worker : public NanAsyncWorker { + public: + {{ function.cppFunctionName }}Worker( + {{ function.cppFunctionName }}Baton *_baton, + NanCallback *callback + ) : NanAsyncWorker(callback) + , baton(_baton) {}; + ~{{ function.cppFunctionName }}Worker() {}; + void Execute(); + void HandleOKCallback(); + + private: + {{ function.cppFunctionName }}Baton *baton; + }; + {%endif%} + + static NAN_METHOD({{ function.cppFunctionName }}); + {%endif%} + {%endeach%} + + {%if cType%} + {{ cType }} *raw; + {%endif%} +}; + +#endif diff --git a/generate/templates/enums.js b/generate/templates/enums.js new file mode 100644 index 000000000..210ddcf91 --- /dev/null +++ b/generate/templates/enums.js @@ -0,0 +1,16 @@ +var NodeGit = require("../"); +NodeGit.Enums = {}; + +/* jshint ignore:start */ +{% each . as enumerable %} +{% if enumerable.type == "enum" %} +NodeGit.{{ enumerable.owner }}.{{ enumerable.JsName }} = { +{% each enumerable.values as value %} + {{ value.JsName }}: {{ value.value }}, +{% endeach %} +}; + +{% endif %} +{% endeach %} + +/* jshint ignore:end */ diff --git a/generate/templates/nodegit.cc b/generate/templates/nodegit.cc new file mode 100644 index 000000000..5431d753b --- /dev/null +++ b/generate/templates/nodegit.cc @@ -0,0 +1,25 @@ +// This is a generated file, modify: generate/templates/nodegit.cc. +#include +#include +#include + +#include "../include/wrapper.h" +#include "../include/functions/copy.h" +{% each %} + {% if type != "enum" %} +#include "../include/{{ filename }}.h" + {% endif %} +{% endeach %} + +extern "C" void init(Handle target) { + NanScope(); + + Wrapper::InitializeComponent(target); + {%each%} + {% if type != "enum" %} + {{ cppClassName }}::InitializeComponent(target); + {% endif %} + {%endeach%} +} + +NODE_MODULE(nodegit, init) diff --git a/generate/templates/struct_content.cc b/generate/templates/struct_content.cc new file mode 100644 index 000000000..fca6cad30 --- /dev/null +++ b/generate/templates/struct_content.cc @@ -0,0 +1,130 @@ +// This is a generated file, modify: generate/templates/struct_content.cc. +#include +#include +#include +#include + +extern "C" { +#include +{%each cDependencies as dependency %} +#include <{{ dependency }}> +{%endeach%} +} + +#include "../include/functions/copy.h" +#include "../include/{{ filename }}.h" + +{%each dependencies as dependency%} +#include "{{ dependency }}" +{%endeach%} +#include + +using namespace v8; +using namespace node; +using namespace std; +// generated from struct_content.cc +{{ cppClassName }}::{{ cppClassName }}() { + {{ cType }} wrappedValue = {{ cType|upper }}_INIT; + this->raw = ({{ cType }}*) malloc(sizeof({{ cType }})); + memcpy(this->raw, &wrappedValue, sizeof({{ cType }})); + + this->ConstructFields(); + this->selfFreeing = true; +} + +{{ cppClassName }}::{{ cppClassName }}({{ cType }}* raw, bool selfFreeing) { + this->raw = raw; + this->ConstructFields(); + this->selfFreeing = selfFreeing; +} + +{{ cppClassName }}::~{{ cppClassName }}() { + // This is going to cause memory leaks. We'll have to solve that later + // TODO: Clean up memory better + if (this->selfFreeing) { + free(this->raw); + } +} + +void {{ cppClassName }}::ConstructFields() { + {%each fields|fieldsInfo as field %} + {%if not field.ignore %} + {%if not field.isEnum %} + {%if field.hasConstructor %} + Local {{ field.name }}Temp = {{ field.cppClassName }}::New(&this->raw->{{ field.name }}, false)->ToObject(); + NanAssignPersistent(this->{{ field.name }}, {{ field.name }}Temp); + + {%elsif field.isLibgitType %} + Local {{ field.name }}Temp = {{ field.cppClassName }}::New(&this->raw->{{ field.name }}, false)->ToObject(); + NanAssignPersistent(this->{{ field.name }}, {{ field.name }}Temp); + + {%elsif field.isCallbackFunction %} + + // Set the static method call and set the payload for this function to be + // the current instance + this->raw->{{ field.name }} = ({{ field.cType }}){{ field.name }}_cppCallback; + this->raw->{{ fields|payloadFor field.name }} = (void *)this; + this->{{ field.name }} = new NanCallback(); + {%elsif field.payloadFor %} + + Local {{ field.name }} = NanUndefined(); + NanAssignPersistent(this->{{ field.name }}, {{ field.name }}); + {%endif%} + {%endif%} + {%endif%} + {%endeach%} +} + +void {{ cppClassName }}::InitializeComponent(Handle target) { + NanScope(); + + Local tpl = NanNew(New); + + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(NanNew("{{ jsClassName }}")); + + {%each fields as field%} + {%if not field.ignore%} + tpl->InstanceTemplate()->SetAccessor(NanNew("{{ field.jsFunctionName }}"), Get{{ field.cppFunctionName}}, Set{{ field.cppFunctionName}}); + {%endif%} + {%endeach%} + + Local _constructor_template = tpl->GetFunction(); + NanAssignPersistent(constructor_template, _constructor_template); + target->Set(NanNew("{{ jsClassName }}"), _constructor_template); +} + +NAN_METHOD({{ cppClassName }}::New) { + NanScope(); + {{ cppClassName }}* instance; + + if (args.Length() == 0 || !args[0]->IsExternal()) { + instance = new {{ cppClassName }}(); + } + else { + instance = new {{ cppClassName }}(static_cast<{{ cType }}*>(Handle::Cast(args[0])->Value()), args[1]->BooleanValue()); + } + + instance->Wrap(args.This()); + + NanReturnValue(args.This()); +} + +Handle {{ cppClassName }}::New(void* raw, bool selfFreeing) { + NanEscapableScope(); + + Handle argv[2] = { NanNew((void *)raw), NanNew(selfFreeing) }; + return NanEscapeScope(NanNew({{ cppClassName }}::constructor_template)->NewInstance(2, argv)); +} + +{{ cType }} *{{ cppClassName }}::GetValue() { + return this->raw; +} + +{{ cType }} **{{ cppClassName }}::GetRefValue() { + return &this->raw; +} + +{%partial fieldAccessors .%} + +Persistent {{ cppClassName }}::constructor_template; diff --git a/generate/templates/struct_header.h b/generate/templates/struct_header.h new file mode 100644 index 000000000..006dd96d7 --- /dev/null +++ b/generate/templates/struct_header.h @@ -0,0 +1,85 @@ +#ifndef {{ cppClassName|upper }}_H +#define {{ cppClassName|upper }}_H +// generated from struct_header.h +#include +#include + +extern "C" { +#include +{%each cDependencies as dependency %} +#include <{{ dependency }}> +{%endeach%} +} + +{%each dependencies as dependency%} +#include "{{ dependency }}" +{%endeach%} + +using namespace node; +using namespace v8; + +class {{ cppClassName }} : public ObjectWrap { + public: + {{ cppClassName }}({{ cType }}* raw, bool selfFreeing); + static Persistent constructor_template; + static void InitializeComponent (Handle target); + + {{ cType }} *GetValue(); + {{ cType }} **GetRefValue(); + + static Handle New(void *raw, bool selfFreeing); + + bool selfFreeing; + + {%each fields as field %} + {%if not field.ignore %} + {%if field.isCallbackFunction %} + static {{ field.returnType }} {{ field.name }}_cppCallback ( + {%each field.args|argsInfo as arg %} + {{ arg.cType }} {{ arg.name}}{%if not arg.lastArg %},{%endif%} + {%endeach%} + ); + static void {{ field.name }}_asyncWork(uv_work_t* req); + static void {{ field.name }}_asyncAfter(uv_work_t* req, int status); + static void {{ field.name }}_asyncPromisePolling(uv_work_t* req, int status); + struct {{ field.name|titleCase }}Baton { + {%each field.args|argsInfo as arg %} + {{ arg.cType }} {{ arg.name}}; + {%endeach%} + uv_work_t req; + {{ field.returnType }} result; + Persistent promise; + bool done; + }; + {%endif%} + {%endif%} + {%endeach%} + + private: + {{ cppClassName }}(); + ~{{ cppClassName }}(); + + void ConstructFields(); + + static NAN_METHOD(New); + + {%each fields as field%} + {%if not field.ignore%} + {%if not field.isEnum %} + {%if field.isLibgitType %} + Persistent {{ field.name }}; + {%elsif field.isCallbackFunction %} + NanCallback* {{ field.name }}; + {%elsif field.payloadFor %} + Persistent {{ field.name }}; + {%endif%} + {%endif%} + static NAN_GETTER(Get{{ field.cppFunctionName }}); + static NAN_SETTER(Set{{ field.cppFunctionName }}); + {%endif%} + {%endeach%} + + {{ cType }} *raw; +}; + +#endif diff --git a/generate/util/file.js b/generate/util/file.js new file mode 100644 index 000000000..c595a7687 --- /dev/null +++ b/generate/util/file.js @@ -0,0 +1,24 @@ +const fs = require("fs"); +const path = require("path"); + +// Make a locally bound path joiner. +var local = path.join.bind(null, __dirname, "../"); + +exports.read = function(file) { + try { + return fs.readFileSync(local(file)).toString(); + } + catch (unhandledException) { + return ""; + } +}; + +exports.write = function(file, contents) { + try { + fs.writeFileSync(local(file), contents); + return true; + } + catch (unhandledException) { + return false; + } +}; diff --git a/generate/utils.js b/generate/utils.js new file mode 100644 index 000000000..24f612d8b --- /dev/null +++ b/generate/utils.js @@ -0,0 +1,375 @@ +var pointerRegex = /\s*\*\s*/; +var doublePointerRegex = /\s*\*\*\s*/; +var callbackTypePattern = /\s*_cb/; +var _ = require("lodash"); + +// TODO: When libgit2's docs include callbacks we should be able to remove this +var callbackDefs = require("./callbacks.json"); +var descriptor = require("./descriptor.json"); +var version = require("../package.json").libgit2.version; +var libgit2 = require("./v" + version + ".json"); +var cTypes = libgit2.groups.map(function(group) { return group[0];}); + +var cTypeMappings = { + "char": "String", + "short": "Number", + "int": "Number", + "int16_t": "Number", + "int32_t": "Number", + "int64_t": "Number", + "size_t": "Number", + "uint16_t": "Number", + "uint32_t": "Number", + "uint64_t": "Number" +} + +var collisionMappings = { + "new": "create" +} + +var Utils = { + titleCase: function(str) { + return str.split(/_|\//).map(function(val, index) { + if (val.length) { + return val[0].toUpperCase() + val.slice(1); + } + + return val; + }).join(""); + }, + + camelCase: function(str) { + return str.split(/_|\//).map(function(val, index) { + return (index >= 1 + ? val[0].toUpperCase() + val.slice(1) + : val[0].toLowerCase() + val.slice(1)); + }).join(""); + }, + + isPointer: function(cType) { + return pointerRegex.test(cType) || doublePointerRegex.test(cType); + }, + + isDoublePointer: function(cType) { + return doublePointerRegex.test(cType); + }, + + normalizeCtype: function(cType) { + return (cType || "") + .toLowerCase() + .replace("const ", "") + .replace("unsigned ", "") + .replace("struct", "") + .replace(doublePointerRegex, "") + .replace(pointerRegex, "") + .trim(); + }, + + cTypeToCppName: function(cType, ownerType) { + var normalizedType = Utils.normalizeCtype(cType); + if (ownerType && normalizedType != ownerType) { + normalizedType = normalizedType.replace(ownerType, ""); + } + + return cTypeMappings[normalizedType] || Utils.titleCase(normalizedType); + }, + + cTypeToJsName: function(cType, ownerType) { + var output = Utils.camelCase(Utils.cTypeToCppName(cType, ownerType).replace(/^Git/, "")); + var mergedPrefixes = ["from", "by"]; + + mergedPrefixes.forEach(function(prefix) { + var reg = new RegExp("(^" + prefix + "|" + Utils.titleCase(prefix) + ")([a-z]+)$"); + output = output.replace(reg, function(all, prefixMatch, otherWord) { + return prefixMatch + Utils.titleCase(otherWord); + }); + }); + + output = output.replace(/([a-z])Str$/, "$1String") + return output; + }, + + isConstructorFunction: function(cType, fnName) { + var initFnName = cType.split('_'); + + initFnName.splice(-1, 0, "init"); + initFnName = initFnName.join('_'); + + return initFnName === fnName; + }, + + hasConstructor: function(type, normalizedType) { + return type.used + && type.used.needs + && type.used.needs.some(function (fnName) { + return Utils.isConstructorFunction(normalizedType, fnName); + }); + }, + + isCallbackFunction: function(cType) { + return callbackTypePattern.test(cType); + }, + + isPayloadFor: function(cbField, payloadName) { + return ~payloadName.indexOf("_payload") + && Utils.isCallbackFunction(cbField.cType) + && ~cbField.name.indexOf(payloadName.replace("_payload", "")); + }, + + getLibgitType: function(normalizedType, types) { + var libgitType; + + types.some(function (type) { + if (type[0] === normalizedType) { + libgitType = type[1]; + return true; + } + }); + + return libgitType; + }, + + processCallback: function(field) { + field.isCallbackFunction = true; + + if (callbackDefs[field.type]) { + _.merge(field, callbackDefs[field.type]); + } + else { + if (process.env.BUILD_ONLY) { + console.warn("Couldn't find callback definition for " + field.type); + } + } + }, + + processPayload: function(field, allFields) { + if (field.name === "payload") { + field.payloadFor = "*"; + } + else { + var cbFieldName; + + allFields.some(function (cbField) { + if (Utils.isPayloadFor(cbField, field.name)) { + cbFieldName = cbField.name; + return true; + } + }); + + if (cbFieldName) { + field.payloadFor = cbFieldName; + } + } + }, + + decorateLibgitType: function(type, types, enums) { + var normalizedType = Utils.normalizeCtype(type.cType); + var libgitType = Utils.getLibgitType(normalizedType, types); + + if (libgitType) { + type.isLibgitType = true; + type.isEnum = libgitType.type === "enum"; + type.hasConstructor = Utils.hasConstructor(type, normalizedType); + + // there are no enums at the struct level currently, but we still need to override function args + if (type.isEnum) { + type.cppClassName = "Number"; + type.jsClassName = "Number"; + if (enums[type.cType]) { + type.isMask = enums[type.cType].isMask || false + } + } + _.merge(type, descriptor.types[normalizedType.replace("git_", "")] || {}); + } + }, + + decoratePrimaryType: function(typeDef, enums) { + var typeDefOverrides = descriptor.types[typeDef.typeName] || {}; + var partialOverrides = _.omit(typeDefOverrides, ["fields", "functions"]); + + typeDef.cType = typeDef.cType || null; + typeDef.cppClassName = Utils.cTypeToCppName(typeDef.cType || "git_" + typeDef.typeName); + typeDef.jsClassName = Utils.titleCase(Utils.cTypeToJsName(typeDef.cType || "git_" + typeDef.typeName)); + typeDef.filename = typeDef.typeName; + typeDef.isLibgitType = true; + typeDef.dependencies = []; + + typeDef.fields = typeDef.fields || []; + typeDef.fields.forEach(function (field, index, allFields) { + var fieldOverrides = typeDefOverrides.fields || {}; + Utils.decorateField(field, allFields, fieldOverrides[field.name] || {}, enums); + }); + + typeDef.needsForwardDeclaration = typeDef.decl === typeDef.cType; + + var normalizedType = Utils.normalizeCtype(typeDef.cType); + typeDef.hasConstructor = Utils.hasConstructor(typeDef, normalizedType); + + typeDef.functions = (typeDef.functions).map(function(fn) { + var fnDef = libgit2.functions[fn]; + fnDef.cFunctionName = fn; + return fnDef; + }); + + var typeDefOverrides = descriptor.types[typeDef.typeName] || {}; + var functionOverrides = typeDefOverrides.functions || {}; + typeDef.functions.forEach(function(fnDef) { + Utils.decorateFunction(fnDef, typeDef, functionOverrides[fnDef.cFunctionName] || {}, enums); + }); + + _.merge(typeDef, partialOverrides); + }, + + decorateField: function(field, allFields, fieldOverrides, enums) { + var normalizeType = Utils.normalizeCtype(field.type); + + field.cType = field.type; + field.cppFunctionName = Utils.titleCase(field.name); + field.jsFunctionName = Utils.camelCase(field.name); + field.cppClassName = Utils.cTypeToCppName(field.type); + field.jsClassName = Utils.titleCase(Utils.cTypeToJsName(field.type)); + + if (Utils.isCallbackFunction(field.cType)) { + Utils.processCallback(field); + + var argOverrides = fieldOverrides.args || {}; + field.args = field.args || []; + field.args.forEach(function (arg) { + Utils.decorateArg(arg, null, null, argOverrides[arg.name] || {}, enums); + }); + } + else { + field.isCallbackFunction = false; + Utils.processPayload(field, allFields); + if (field.payloadFor) { + return; + } + } + + Utils.decorateLibgitType(field, libgit2.types, enums); + _.merge(field, fieldOverrides); + }, + + decorateArg: function(arg, typeDef, fnDef, argOverrides, enums) { + var type = arg.cType || arg.type; + var normalizedType = Utils.normalizeCtype(type); + + arg.cType = type; + arg.cppClassName = Utils.cTypeToCppName(arg.cType); + arg.jsClassName = Utils.titleCase(Utils.cTypeToJsName(arg.cType)); + + Utils.decorateLibgitType(arg, libgit2.types, enums); + + if (typeDef && fnDef) { + // Mark all of the args that are either returns or are the object + // itself and determine if this function goes on the prototype + // or is a constructor method. + arg.isReturn = arg.name === "out" || (Utils.isDoublePointer(arg.type) && normalizedType == typeDef.cType); + arg.isSelf = Utils.isPointer(arg.type) && normalizedType == typeDef.cType; + + if (arg.isReturn && fnDef.return && fnDef.return.type === "int") { + fnDef.return.isErrorCode = true; + fnDef.isAsync = true; + } + + if (arg.isReturn && arg.isSelf) { + arg.isSelf = false; + fnDef.isConstructorMethod = true; + } + else if (arg.isSelf) { + fnDef.isPrototypeMethod = true; + } + } + + _.merge(arg, argOverrides); + }, + + decorateFunction: function(fnDef, typeDef, fnOverrides, enums) { + var key = fnDef.cFunctionName; + + // if this is the free function for the class, make the ref on the class + // and then return since we don't want the free functions publicly + // available + if (key == typeDef.cType + "_free") { + typeDef.freeFunctionName = key; + fnDef.ignore = true; + return; + } + + fnDef.cppFunctionName = Utils.cTypeToCppName(key, "git_" + typeDef.typeName); + fnDef.jsFunctionName = Utils.cTypeToJsName(key, "git_" + typeDef.typeName); + //fnDef.isAsync = false; // until proven otherwise + + if (fnDef.cppFunctionName == typeDef.cppClassName) { + fnDef.cppFunctionName = fnDef.cppFunctionName.replace("Git", ""); + } + + var argOverrides = fnOverrides.args || {}; + fnDef.args.forEach(function(arg) { + Utils.decorateArg(arg, typeDef, fnDef, argOverrides[arg.name] || {}, enums); + }); + + if (fnDef.return) { + Utils.decorateArg(fnDef.return, typeDef, fnDef, fnOverrides.return || {}, enums); + } + + _(collisionMappings).forEach(function(newName, collidingName) { + if (fnDef.cppFunctionName == Utils.titleCase(collidingName)) { + fnDef.cppFunctionName = Utils.titleCase(newName); + } + + if (fnDef.jsFunctionName == Utils.camelCase(collidingName)) { + fnDef.jsFunctionName = Utils.camelCase(newName); + } + }); + + _.merge(fnDef, _.omit(fnOverrides, "args", "return")); + }, + + filterIgnored: function (arr, callback) { + if (!arr) { + return; + } + for (var i = arr.length - 1; i >= 0; i--) { + if (arr[i].ignore) { + arr.splice(i, 1); + } + else if (callback) { + callback(arr[i]); + } + } + }, + + deleteProperties: function(obj) { + delete obj.line; + delete obj.lineto; + delete obj.block; + delete obj.description; + delete obj.comments; + delete obj.tdef; + delete obj.decl; + delete obj.comments; + delete obj.argline; + delete obj.sig; + }, + + filterDocumentation: function(idefs) { + Utils.filterIgnored(idefs, function (idef) { + Utils.deleteProperties(idef); + + Utils.filterIgnored(idef.fields, Utils.deleteProperties); + + + Utils.filterIgnored(idef.functions, function (fn) { + Utils.deleteProperties(fn); + + Utils.filterIgnored(fn.args, function(arg) { + Utils.deleteProperties(arg); + delete arg.functions; + }); + }); + }); + } +}; + +module.exports = Utils; diff --git a/generate/v0.21.2.json b/generate/v0.21.2.json new file mode 100644 index 000000000..8bf582b01 --- /dev/null +++ b/generate/v0.21.2.json @@ -0,0 +1 @@ +{"files":[{"file":"attr.h","functions":["git_attr_get","git_attr_get_many","git_attr_foreach","git_attr_cache_flush","git_attr_add_macro"],"meta":{},"lines":237},{"file":"blame.h","functions":["git_blame_init_options","git_blame_get_hunk_count","git_blame_get_hunk_byindex","git_blame_get_hunk_byline","git_blame_file","git_blame_buffer","git_blame_free"],"meta":{},"lines":208},{"file":"blob.h","functions":["git_blob_lookup","git_blob_lookup_prefix","git_blob_free","git_blob_id","git_blob_owner","git_blob_rawcontent","git_blob_rawsize","git_blob_filtered_content","git_blob_create_fromworkdir","git_blob_create_fromdisk","git_blob_create_fromchunks","git_blob_create_frombuffer","git_blob_is_binary"],"meta":{},"lines":219},{"file":"branch.h","functions":["git_branch_create","git_branch_delete","git_branch_iterator_new","git_branch_next","git_branch_iterator_free","git_branch_move","git_branch_lookup","git_branch_name","git_branch_upstream","git_branch_set_upstream","git_branch_is_head"],"meta":{},"lines":242},{"file":"buffer.h","functions":["git_buf_free","git_buf_grow","git_buf_set"],"meta":{},"lines":106},{"file":"checkout.h","functions":["git_checkout_init_options","git_checkout_head","git_checkout_index","git_checkout_tree"],"meta":{},"lines":323},{"file":"cherrypick.h","functions":["git_cherry_pick_init_options","git_cherry_pick_commit","git_cherry_pick"],"meta":{},"lines":81},{"file":"clone.h","functions":["git_clone_init_options","git_clone","git_clone_into","git_clone_local_into"],"meta":{},"lines":203},{"file":"commit.h","functions":["git_commit_lookup","git_commit_lookup_prefix","git_commit_free","git_commit_id","git_commit_owner","git_commit_message_encoding","git_commit_message","git_commit_message_raw","git_commit_summary","git_commit_time","git_commit_time_offset","git_commit_committer","git_commit_author","git_commit_raw_header","git_commit_tree","git_commit_tree_id","git_commit_parentcount","git_commit_parent","git_commit_parent_id","git_commit_nth_gen_ancestor","git_commit_create","git_commit_create_v","git_commit_amend"],"meta":{},"lines":353},{"file":"common.h","functions":["git_libgit2_version","git_libgit2_features","git_libgit2_opts"],"meta":{},"lines":228},{"file":"config.h","functions":["git_config_find_global","git_config_find_xdg","git_config_find_system","git_config_open_default","git_config_new","git_config_add_file_ondisk","git_config_open_ondisk","git_config_open_level","git_config_open_global","git_config_snapshot","git_config_refresh","git_config_free","git_config_get_entry","git_config_get_int32","git_config_get_int64","git_config_get_bool","git_config_get_string","git_config_get_multivar_foreach","git_config_multivar_iterator_new","git_config_next","git_config_iterator_free","git_config_set_int32","git_config_set_int64","git_config_set_bool","git_config_set_string","git_config_set_multivar","git_config_delete_entry","git_config_delete_multivar","git_config_foreach","git_config_iterator_new","git_config_iterator_glob_new","git_config_foreach_match","git_config_get_mapped","git_config_lookup_map_value","git_config_parse_bool","git_config_parse_int32","git_config_parse_int64","git_config_backend_foreach_match"],"meta":{},"lines":640},{"file":"cred_helpers.h","functions":["git_cred_userpass"],"meta":{},"lines":48},{"file":"diff.h","functions":["git_diff_init_options","git_diff_find_init_options","git_diff_free","git_diff_tree_to_tree","git_diff_tree_to_index","git_diff_index_to_workdir","git_diff_tree_to_workdir","git_diff_tree_to_workdir_with_index","git_diff_merge","git_diff_find_similar","git_diff_num_deltas","git_diff_num_deltas_of_type","git_diff_get_delta","git_diff_is_sorted_icase","git_diff_foreach","git_diff_status_char","git_diff_print","git_diff_blobs","git_diff_blob_to_buffer","git_diff_buffers","git_diff_get_stats","git_diff_stats_files_changed","git_diff_stats_insertions","git_diff_stats_deletions","git_diff_stats_to_buf","git_diff_stats_free","git_diff_format_email","git_diff_commit_as_email","git_diff_format_email_init_options"],"meta":{},"lines":1234},{"file":"errors.h","functions":["giterr_last","giterr_clear","giterr_detach","giterr_set_str","giterr_set_oom"],"meta":{},"lines":149},{"file":"filter.h","functions":["git_filter_list_load","git_filter_list_apply_to_data","git_filter_list_apply_to_file","git_filter_list_apply_to_blob","git_filter_list_free"],"meta":{},"lines":142},{"file":"graph.h","functions":["git_graph_ahead_behind","git_graph_descendant_of"],"meta":{},"lines":51},{"file":"ignore.h","functions":["git_ignore_add_rule","git_ignore_clear_internal_rules","git_ignore_path_is_ignored"],"meta":{},"lines":74},{"file":"index.h","functions":["git_index_open","git_index_new","git_index_free","git_index_owner","git_index_caps","git_index_set_caps","git_index_read","git_index_write","git_index_path","git_index_read_tree","git_index_write_tree","git_index_write_tree_to","git_index_entrycount","git_index_clear","git_index_get_byindex","git_index_get_bypath","git_index_remove","git_index_remove_directory","git_index_add","git_index_entry_stage","git_index_add_bypath","git_index_remove_bypath","git_index_add_all","git_index_remove_all","git_index_update_all","git_index_find","git_index_conflict_add","git_index_conflict_get","git_index_conflict_remove","git_index_conflict_cleanup","git_index_has_conflicts","git_index_conflict_iterator_new","git_index_conflict_next","git_index_conflict_iterator_free"],"meta":{},"lines":693},{"file":"indexer.h","functions":["git_indexer_new","git_indexer_append","git_indexer_commit","git_indexer_hash","git_indexer_free"],"meta":{},"lines":72},{"file":"merge.h","functions":["git_merge_file_init_input","git_merge_file_init_options","git_merge_init_options","git_merge_analysis","git_merge_base","git_merge_base_many","git_merge_base_octopus","git_merge_head_from_ref","git_merge_head_from_fetchhead","git_merge_head_from_id","git_merge_head_id","git_merge_head_free","git_merge_file","git_merge_file_from_index","git_merge_file_result_free","git_merge_trees","git_merge_commits","git_merge"],"meta":{},"lines":532},{"file":"message.h","functions":["git_message_prettify"],"meta":{},"lines":39},{"file":"net.h","functions":[],"meta":{},"lines":54},{"file":"notes.h","functions":["git_note_iterator_new","git_note_iterator_free","git_note_next","git_note_read","git_note_message","git_note_id","git_note_create","git_note_remove","git_note_free","git_note_default_ref","git_note_foreach"],"meta":{},"lines":198},{"file":"object.h","functions":["git_object_lookup","git_object_lookup_prefix","git_object_lookup_bypath","git_object_id","git_object_short_id","git_object_type","git_object_owner","git_object_free","git_object_type2string","git_object_string2type","git_object_typeisloose","git_object__size","git_object_peel","git_object_dup"],"meta":{},"lines":230},{"file":"odb.h","functions":["git_odb_new","git_odb_open","git_odb_add_disk_alternate","git_odb_free","git_odb_read","git_odb_read_prefix","git_odb_read_header","git_odb_exists","git_odb_exists_prefix","git_odb_refresh","git_odb_foreach","git_odb_write","git_odb_open_wstream","git_odb_stream_write","git_odb_stream_finalize_write","git_odb_stream_read","git_odb_stream_free","git_odb_open_rstream","git_odb_write_pack","git_odb_hash","git_odb_hashfile","git_odb_object_dup","git_odb_object_free","git_odb_object_id","git_odb_object_data","git_odb_object_size","git_odb_object_type","git_odb_add_backend","git_odb_add_alternate","git_odb_num_backends","git_odb_get_backend"],"meta":{},"lines":491},{"file":"odb_backend.h","functions":["git_odb_backend_pack","git_odb_backend_loose","git_odb_backend_one_pack"],"meta":{},"lines":130},{"file":"oid.h","functions":["git_oid_fromstr","git_oid_fromstrp","git_oid_fromstrn","git_oid_fromraw","git_oid_fmt","git_oid_nfmt","git_oid_pathfmt","git_oid_allocfmt","git_oid_tostr","git_oid_cpy","git_oid_cmp","git_oid_equal","git_oid_ncmp","git_oid_streq","git_oid_strcmp","git_oid_iszero","git_oid_shorten_new","git_oid_shorten_add","git_oid_shorten_free"],"meta":{},"lines":261},{"file":"pack.h","functions":["git_packbuilder_new","git_packbuilder_set_threads","git_packbuilder_insert","git_packbuilder_insert_tree","git_packbuilder_insert_commit","git_packbuilder_write","git_packbuilder_hash","git_packbuilder_foreach","git_packbuilder_object_count","git_packbuilder_written","git_packbuilder_set_callbacks","git_packbuilder_free"],"meta":{},"lines":211},{"file":"patch.h","functions":["git_patch_from_diff","git_patch_from_blobs","git_patch_from_blob_and_buffer","git_patch_from_buffers","git_patch_free","git_patch_get_delta","git_patch_num_hunks","git_patch_line_stats","git_patch_get_hunk","git_patch_num_lines_in_hunk","git_patch_get_line_in_hunk","git_patch_size","git_patch_print","git_patch_to_buf"],"meta":{},"lines":271},{"file":"pathspec.h","functions":["git_pathspec_new","git_pathspec_free","git_pathspec_matches_path","git_pathspec_match_workdir","git_pathspec_match_index","git_pathspec_match_tree","git_pathspec_match_diff","git_pathspec_match_list_free","git_pathspec_match_list_entrycount","git_pathspec_match_list_entry","git_pathspec_match_list_diff_entry","git_pathspec_match_list_failed_entrycount","git_pathspec_match_list_failed_entry"],"meta":{},"lines":260},{"file":"push.h","functions":["git_push_init_options","git_push_new","git_push_set_options","git_push_set_callbacks","git_push_add_refspec","git_push_update_tips","git_push_finish","git_push_unpack_ok","git_push_status_foreach","git_push_free"],"meta":{},"lines":177},{"file":"refdb.h","functions":["git_refdb_new","git_refdb_open","git_refdb_compress","git_refdb_free"],"meta":{},"lines":63},{"file":"reflog.h","functions":["git_reflog_read","git_reflog_write","git_reflog_append","git_reflog_rename","git_reflog_delete","git_reflog_entrycount","git_reflog_entry_byindex","git_reflog_drop","git_reflog_entry_id_old","git_reflog_entry_id_new","git_reflog_entry_committer","git_reflog_entry_message","git_reflog_free"],"meta":{},"lines":166},{"file":"refs.h","functions":["git_reference_lookup","git_reference_name_to_id","git_reference_dwim","git_reference_symbolic_create_matching","git_reference_symbolic_create","git_reference_create","git_reference_create_matching","git_reference_target","git_reference_target_peel","git_reference_symbolic_target","git_reference_type","git_reference_name","git_reference_resolve","git_reference_owner","git_reference_symbolic_set_target","git_reference_set_target","git_reference_rename","git_reference_delete","git_reference_remove","git_reference_list","git_reference_foreach","git_reference_foreach_name","git_reference_free","git_reference_cmp","git_reference_iterator_new","git_reference_iterator_glob_new","git_reference_next","git_reference_next_name","git_reference_iterator_free","git_reference_foreach_glob","git_reference_has_log","git_reference_ensure_log","git_reference_is_branch","git_reference_is_remote","git_reference_is_tag","git_reference_is_note","git_reference_normalize_name","git_reference_peel","git_reference_is_valid_name","git_reference_shorthand"],"meta":{},"lines":734},{"file":"refspec.h","functions":["git_refspec_src","git_refspec_dst","git_refspec_string","git_refspec_force","git_refspec_direction","git_refspec_src_matches","git_refspec_dst_matches","git_refspec_transform","git_refspec_rtransform"],"meta":{},"lines":100},{"file":"remote.h","functions":["git_remote_create","git_remote_create_with_fetchspec","git_remote_create_anonymous","git_remote_load","git_remote_save","git_remote_dup","git_remote_owner","git_remote_name","git_remote_url","git_remote_pushurl","git_remote_set_url","git_remote_set_pushurl","git_remote_add_fetch","git_remote_get_fetch_refspecs","git_remote_set_fetch_refspecs","git_remote_add_push","git_remote_get_push_refspecs","git_remote_set_push_refspecs","git_remote_clear_refspecs","git_remote_refspec_count","git_remote_get_refspec","git_remote_connect","git_remote_ls","git_remote_download","git_remote_connected","git_remote_stop","git_remote_disconnect","git_remote_free","git_remote_update_tips","git_remote_fetch","git_remote_valid_url","git_remote_supported_url","git_remote_list","git_remote_check_cert","git_remote_set_transport","git_remote_init_callbacks","git_remote_set_callbacks","git_remote_get_callbacks","git_remote_stats","git_remote_autotag","git_remote_set_autotag","git_remote_rename","git_remote_update_fetchhead","git_remote_set_update_fetchhead","git_remote_is_valid_name","git_remote_delete","git_remote_default_branch"],"meta":{},"lines":639},{"file":"repository.h","functions":["git_repository_open","git_repository_wrap_odb","git_repository_discover","git_repository_open_ext","git_repository_open_bare","git_repository_free","git_repository_init","git_repository_init_init_options","git_repository_init_ext","git_repository_head","git_repository_head_detached","git_repository_head_unborn","git_repository_is_empty","git_repository_path","git_repository_workdir","git_repository_set_workdir","git_repository_is_bare","git_repository_config","git_repository_config_snapshot","git_repository_odb","git_repository_refdb","git_repository_index","git_repository_message","git_repository_message_remove","git_repository_state_cleanup","git_repository_fetchhead_foreach","git_repository_mergehead_foreach","git_repository_hashfile","git_repository_set_head","git_repository_set_head_detached","git_repository_detach_head","git_repository_state","git_repository_set_namespace","git_repository_get_namespace","git_repository_is_shallow"],"meta":{},"lines":712},{"file":"revert.h","functions":["git_revert_init_options","git_revert_commit","git_revert"],"meta":{},"lines":81},{"file":"revparse.h","functions":["git_revparse_single","git_revparse_ext","git_revparse"],"meta":{},"lines":108},{"file":"revwalk.h","functions":["git_revwalk_new","git_revwalk_reset","git_revwalk_push","git_revwalk_push_glob","git_revwalk_push_head","git_revwalk_hide","git_revwalk_hide_glob","git_revwalk_hide_head","git_revwalk_push_ref","git_revwalk_hide_ref","git_revwalk_next","git_revwalk_sorting","git_revwalk_push_range","git_revwalk_simplify_first_parent","git_revwalk_free","git_revwalk_repository","git_revwalk_add_hide_cb"],"meta":{},"lines":286},{"file":"signature.h","functions":["git_signature_new","git_signature_now","git_signature_default","git_signature_dup","git_signature_free"],"meta":{},"lines":86},{"file":"stash.h","functions":["git_stash_foreach","git_stash_drop"],"meta":{},"lines":113},{"file":"status.h","functions":["git_status_init_options","git_status_foreach","git_status_foreach_ext","git_status_file","git_status_list_new","git_status_list_entrycount","git_status_byindex","git_status_list_free","git_status_should_ignore"],"meta":{},"lines":361},{"file":"strarray.h","functions":["git_strarray_free","git_strarray_copy"],"meta":{},"lines":53},{"file":"submodule.h","functions":["git_submodule_lookup","git_submodule_free","git_submodule_foreach","git_submodule_add_setup","git_submodule_add_finalize","git_submodule_add_to_index","git_submodule_save","git_submodule_owner","git_submodule_name","git_submodule_path","git_submodule_url","git_submodule_branch","git_submodule_set_url","git_submodule_index_id","git_submodule_head_id","git_submodule_wd_id","git_submodule_ignore","git_submodule_set_ignore","git_submodule_update","git_submodule_set_update","git_submodule_fetch_recurse_submodules","git_submodule_set_fetch_recurse_submodules","git_submodule_init","git_submodule_sync","git_submodule_open","git_submodule_reload","git_submodule_reload_all","git_submodule_status","git_submodule_location"],"meta":{},"lines":555},{"file":"sys/commit.h","functions":["git_commit_create_from_ids","git_commit_create_from_callback"],"meta":{},"lines":76},{"file":"sys/config.h","functions":["git_config_init_backend","git_config_add_backend"],"meta":{},"lines":108},{"file":"sys/diff.h","functions":["git_diff_print_callback__to_buf","git_diff_print_callback__to_file_handle","git_diff_get_perfdata","git_status_list_get_perfdata"],"meta":{},"lines":87},{"file":"sys/filter.h","functions":["git_filter_lookup","git_filter_list_new","git_filter_list_push","git_filter_list_length","git_filter_source_repo","git_filter_source_path","git_filter_source_filemode","git_filter_source_id","git_filter_source_mode","git_filter_source_options","git_filter_register","git_filter_unregister"],"meta":{},"lines":297},{"file":"sys/mempack.h","functions":["git_mempack_new","git_mempack_reset"],"meta":{},"lines":81},{"file":"sys/odb_backend.h","functions":["git_odb_init_backend"],"meta":{},"lines":102},{"file":"sys/refdb_backend.h","functions":["git_refdb_init_backend","git_refdb_backend_fs","git_refdb_set_backend"],"meta":{},"lines":200},{"file":"sys/refs.h","functions":["git_reference__alloc","git_reference__alloc_symbolic"],"meta":{},"lines":36},{"file":"tag.h","functions":["git_tag_lookup","git_tag_lookup_prefix","git_tag_free","git_tag_id","git_tag_owner","git_tag_target","git_tag_target_id","git_tag_target_type","git_tag_name","git_tag_tagger","git_tag_message","git_tag_create","git_tag_annotation_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_delete","git_tag_list","git_tag_list_match","git_tag_foreach","git_tag_peel"],"meta":{},"lines":348},{"file":"threads.h","functions":["git_threads_init","git_threads_shutdown"],"meta":{},"lines":45},{"file":"trace.h","functions":["git_trace_set"],"meta":{},"lines":63},{"file":"transport.h","functions":["git_cred_has_username","git_cred_userpass_plaintext_new","git_cred_ssh_key_new","git_cred_ssh_interactive_new","git_cred_ssh_key_from_agent","git_cred_ssh_custom_new","git_cred_default_new","git_transport_init","git_transport_new","git_transport_register","git_transport_unregister","git_transport_dummy","git_transport_local","git_transport_smart","git_smart_subtransport_http","git_smart_subtransport_git","git_smart_subtransport_ssh"],"meta":{},"lines":537},{"file":"tree.h","functions":["git_tree_lookup","git_tree_lookup_prefix","git_tree_free","git_tree_id","git_tree_owner","git_tree_entrycount","git_tree_entry_byname","git_tree_entry_byindex","git_tree_entry_byid","git_tree_entry_bypath","git_tree_entry_dup","git_tree_entry_free","git_tree_entry_name","git_tree_entry_id","git_tree_entry_type","git_tree_entry_filemode","git_tree_entry_filemode_raw","git_tree_entry_cmp","git_tree_entry_to_object","git_treebuilder_create","git_treebuilder_clear","git_treebuilder_entrycount","git_treebuilder_free","git_treebuilder_get","git_treebuilder_insert","git_treebuilder_remove","git_treebuilder_filter","git_treebuilder_write","git_tree_walk"],"meta":{},"lines":408},{"file":"types.h","functions":[],"meta":{},"lines":344}],"functions":{"git_attr_get":{"type":"function","file":"attr.h","line":142,"lineto":147,"args":[{"name":"value_out","type":"const char **","comment":"Output of the value of the attribute. Use the GIT_ATTR_...\n macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just\n use the string value for attributes set to a value. You\n should NOT modify or free this value."},{"name":"repo","type":"git_repository *","comment":"The repository containing the path."},{"name":"flags","type":"uint32_t","comment":"A combination of GIT_ATTR_CHECK... flags."},{"name":"path","type":"const char *","comment":"The path to check for attributes. Relative paths are\n interpreted relative to the repo root. The file does\n not have to exist, but if it does not, then it will be\n treated as a plain file (not a directory)."},{"name":"name","type":"const char *","comment":"The name of the attribute to look up."}],"argline":"const char **value_out, git_repository *repo, uint32_t flags, const char *path, const char *name","sig":"const char **::git_repository *::uint32_t::const char *::const char *","return":{"type":"int","comment":null},"description":"

Look up the value of one git attribute for path.

\n","comments":"","group":"attr"},"git_attr_get_many":{"type":"function","file":"attr.h","line":178,"lineto":184,"args":[{"name":"values_out","type":"const char **","comment":"An array of num_attr entries that will have string\n pointers written into it for the values of the attributes.\n You should not modify or free the values that are written\n into this array (although of course, you should free the\n array itself if you allocated it)."},{"name":"repo","type":"git_repository *","comment":"The repository containing the path."},{"name":"flags","type":"uint32_t","comment":"A combination of GIT_ATTR_CHECK... flags."},{"name":"path","type":"const char *","comment":"The path inside the repo to check attributes. This\n does not have to exist, but if it does not, then\n it will be treated as a plain file (i.e. not a directory)."},{"name":"num_attr","type":"size_t","comment":"The number of attributes being looked up"},{"name":"names","type":"const char **","comment":"An array of num_attr strings containing attribute names."}],"argline":"const char **values_out, git_repository *repo, uint32_t flags, const char *path, size_t num_attr, const char **names","sig":"const char **::git_repository *::uint32_t::const char *::size_t::const char **","return":{"type":"int","comment":null},"description":"

Look up a list of git attributes for path.

\n","comments":"

Use this if you have a known list of attributes that you want to\n look up in a single call. This is somewhat more efficient than\n calling git_attr_get() multiple times.

\n\n

For example, you might write:

\n\n
 const char *attrs[] = { "crlf", "diff", "foo" };\n const char **values[3];\n git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs);\n
\n\n

Then you could loop through the 3 values to get the settings for\n the three attributes you asked about.

\n","group":"attr"},"git_attr_foreach":{"type":"function","file":"attr.h","line":206,"lineto":211,"args":[{"name":"repo","type":"git_repository *","comment":"The repository containing the path."},{"name":"flags","type":"uint32_t","comment":"A combination of GIT_ATTR_CHECK... flags."},{"name":"path","type":"const char *","comment":"Path inside the repo to check attributes. This does not have\n to exist, but if it does not, then it will be treated as a\n plain file (i.e. not a directory)."},{"name":"callback","type":"git_attr_foreach_cb","comment":"Function to invoke on each attribute name and value. The\n value may be NULL is the attribute is explicitly set to\n UNSPECIFIED using the '!' sign. Callback will be invoked\n only once per attribute name, even if there are multiple\n rules for a given file. The highest priority rule will be\n used. Return a non-zero value from this to stop looping.\n The value will be returned from `git_attr_foreach`."},{"name":"payload","type":"void *","comment":"Passed on as extra parameter to callback function."}],"argline":"git_repository *repo, uint32_t flags, const char *path, git_attr_foreach_cb callback, void *payload","sig":"git_repository *::uint32_t::const char *::git_attr_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Loop over all the git attributes for a path.

\n","comments":"","group":"attr"},"git_attr_cache_flush":{"type":"function","file":"attr.h","line":221,"lineto":222,"args":[{"name":"repo","type":"git_repository *","comment":null}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"void","comment":null},"description":"

Flush the gitattributes cache.

\n","comments":"

Call this if you have reason to believe that the attributes files on\n disk no longer match the cached contents of memory. This will cause\n the attributes files to be reloaded the next time that an attribute\n access function is called.

\n","group":"attr"},"git_attr_add_macro":{"type":"function","file":"attr.h","line":234,"lineto":237,"args":[{"name":"repo","type":"git_repository *","comment":null},{"name":"name","type":"const char *","comment":null},{"name":"values","type":"const char *","comment":null}],"argline":"git_repository *repo, const char *name, const char *values","sig":"git_repository *::const char *::const char *","return":{"type":"int","comment":null},"description":"

Add a macro definition.

\n","comments":"

Macros will automatically be loaded from the top level .gitattributes\n file of the repository (plus the build-in "binary" macro). This\n function allows you to add others. For example, to add the default\n macro, you would call:

\n\n
 git_attr_add_macro(repo, "binary", "-diff -crlf");\n
\n","group":"attr"},"git_blame_init_options":{"type":"function","file":"blame.h","line":93,"lineto":95,"args":[{"name":"opts","type":"git_blame_options *","comment":"The `git_blame_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_BLAME_OPTIONS_VERSION`"}],"argline":"git_blame_options *opts, unsigned int version","sig":"git_blame_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_blame_options with default values. Equivalent to\n creating an instance with GIT_BLAME_OPTIONS_INIT.

\n","comments":"","group":"blame"},"git_blame_get_hunk_count":{"type":"function","file":"blame.h","line":138,"lineto":138,"args":[{"name":"blame","type":"git_blame *","comment":null}],"argline":"git_blame *blame","sig":"git_blame *","return":{"type":"uint32_t","comment":null},"description":"

Gets the number of hunks that exist in the blame structure.

\n","comments":"","group":"blame"},"git_blame_get_hunk_byindex":{"type":"function","file":"blame.h","line":147,"lineto":149,"args":[{"name":"blame","type":"git_blame *","comment":"the blame structure to query"},{"name":"index","type":"uint32_t","comment":"index of the hunk to retrieve"}],"argline":"git_blame *blame, uint32_t index","sig":"git_blame *::uint32_t","return":{"type":"const git_blame_hunk *","comment":" the hunk at the given index, or NULL on error"},"description":"

Gets the blame hunk at the given index.

\n","comments":"","group":"blame"},"git_blame_get_hunk_byline":{"type":"function","file":"blame.h","line":158,"lineto":160,"args":[{"name":"blame","type":"git_blame *","comment":"the blame structure to query"},{"name":"lineno","type":"uint32_t","comment":"the (1-based) line number to find a hunk for"}],"argline":"git_blame *blame, uint32_t lineno","sig":"git_blame *::uint32_t","return":{"type":"const git_blame_hunk *","comment":" the hunk that contains the given line, or NULL on error"},"description":"

Gets the hunk that relates to the given line number in the newest commit.

\n","comments":"","group":"blame","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blame_get_hunk_byline-1"]}},"git_blame_file":{"type":"function","file":"blame.h","line":173,"lineto":177,"args":[{"name":"out","type":"git_blame **","comment":"pointer that will receive the blame object"},{"name":"repo","type":"git_repository *","comment":"repository whose history is to be walked"},{"name":"path","type":"const char *","comment":"path to file to consider"},{"name":"options","type":"git_blame_options *","comment":"options for the blame operation. If NULL, this is treated as\n though GIT_BLAME_OPTIONS_INIT were passed."}],"argline":"git_blame **out, git_repository *repo, const char *path, git_blame_options *options","sig":"git_blame **::git_repository *::const char *::git_blame_options *","return":{"type":"int","comment":" 0 on success, or an error code. (use giterr_last for information\n about the error.)"},"description":"

Get the blame for a single file.

\n","comments":"","group":"blame","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blame_file-2"]}},"git_blame_buffer":{"type":"function","file":"blame.h","line":197,"lineto":201,"args":[{"name":"out","type":"git_blame **","comment":"pointer that will receive the resulting blame data"},{"name":"reference","type":"git_blame *","comment":"cached blame from the history of the file (usually the output\n from git_blame_file)"},{"name":"buffer","type":"const char *","comment":"the (possibly) modified contents of the file"},{"name":"buffer_len","type":"size_t","comment":"number of valid bytes in the buffer"}],"argline":"git_blame **out, git_blame *reference, const char *buffer, size_t buffer_len","sig":"git_blame **::git_blame *::const char *::size_t","return":{"type":"int","comment":" 0 on success, or an error code. (use giterr_last for information\n about the error)"},"description":"

Get blame data for a file that has been modified in memory. The reference\n parameter is a pre-calculated blame for the in-odb history of the file. This\n means that once a file blame is completed (which can be expensive), updating\n the buffer blame is very fast.

\n","comments":"

Lines that differ between the buffer and the committed version are marked as\n having a zero OID for their final_commit_id.

\n","group":"blame"},"git_blame_free":{"type":"function","file":"blame.h","line":208,"lineto":208,"args":[{"name":"blame","type":"git_blame *","comment":"the blame structure to free"}],"argline":"git_blame *blame","sig":"git_blame *","return":{"type":"void","comment":null},"description":"

Free memory allocated by git_blame_file or git_blame_buffer.

\n","comments":"","group":"blame","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blame_free-3"]}},"git_blob_lookup":{"type":"function","file":"blob.h","line":33,"lineto":33,"args":[{"name":"blob","type":"git_blob **","comment":"pointer to the looked up blob"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the blob."},{"name":"id","type":"const git_oid *","comment":"identity of the blob to locate."}],"argline":"git_blob **blob, git_repository *repo, const git_oid *id","sig":"git_blob **::git_repository *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a blob object from a repository.

\n","comments":"","group":"blob","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blob_lookup-4"],"general.c":["ex/v0.21.2/general.html#git_blob_lookup-1"]}},"git_blob_lookup_prefix":{"type":"function","file":"blob.h","line":47,"lineto":47,"args":[{"name":"blob","type":"git_blob **","comment":"pointer to the looked up blob"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the blob."},{"name":"id","type":"const git_oid *","comment":"identity of the blob to locate."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_blob **blob, git_repository *repo, const git_oid *id, size_t len","sig":"git_blob **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a blob object from a repository,\n given a prefix of its identifier (short id).

\n","comments":"","group":"blob"},"git_blob_free":{"type":"function","file":"blob.h","line":60,"lineto":60,"args":[{"name":"blob","type":"git_blob *","comment":"the blob to close"}],"argline":"git_blob *blob","sig":"git_blob *","return":{"type":"void","comment":null},"description":"

Close an open blob

\n","comments":"

This is a wrapper around git_object_free()

\n\n

IMPORTANT:\n It is necessary to call this method when you stop\n using a blob. Failure to do so will cause a memory leak.

\n","group":"blob","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blob_free-5"]}},"git_blob_id":{"type":"function","file":"blob.h","line":68,"lineto":68,"args":[{"name":"blob","type":"const git_blob *","comment":"a previously loaded blob."}],"argline":"const git_blob *blob","sig":"const git_blob *","return":{"type":"const git_oid *","comment":" SHA1 hash for this blob."},"description":"

Get the id of a blob.

\n","comments":"","group":"blob"},"git_blob_owner":{"type":"function","file":"blob.h","line":76,"lineto":76,"args":[{"name":"blob","type":"const git_blob *","comment":"A previously loaded blob."}],"argline":"const git_blob *blob","sig":"const git_blob *","return":{"type":"git_repository *","comment":" Repository that contains this blob."},"description":"

Get the repository that contains the blob.

\n","comments":"","group":"blob"},"git_blob_rawcontent":{"type":"function","file":"blob.h","line":89,"lineto":89,"args":[{"name":"blob","type":"const git_blob *","comment":"pointer to the blob"}],"argline":"const git_blob *blob","sig":"const git_blob *","return":{"type":"const void *","comment":" the pointer"},"description":"

Get a read-only buffer with the raw content of a blob.

\n","comments":"

A pointer to the raw content of a blob is returned;\n this pointer is owned internally by the object and shall\n not be free'd. The pointer may be invalidated at a later\n time.

\n","group":"blob","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blob_rawcontent-6"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_blob_rawcontent-1"],"general.c":["ex/v0.21.2/general.html#git_blob_rawcontent-2"]}},"git_blob_rawsize":{"type":"function","file":"blob.h","line":97,"lineto":97,"args":[{"name":"blob","type":"const git_blob *","comment":"pointer to the blob"}],"argline":"const git_blob *blob","sig":"const git_blob *","return":{"type":"git_off_t","comment":" size on bytes"},"description":"

Get the size in bytes of the contents of a blob

\n","comments":"","group":"blob","examples":{"blame.c":["ex/v0.21.2/blame.html#git_blob_rawsize-7"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_blob_rawsize-2"],"general.c":["ex/v0.21.2/general.html#git_blob_rawsize-3","ex/v0.21.2/general.html#git_blob_rawsize-4"]}},"git_blob_filtered_content":{"type":"function","file":"blob.h","line":124,"lineto":128,"args":[{"name":"out","type":"git_buf *","comment":"The git_buf to be filled in"},{"name":"blob","type":"git_blob *","comment":"Pointer to the blob"},{"name":"as_path","type":"const char *","comment":"Path used for file attribute lookups, etc."},{"name":"check_for_binary_data","type":"int","comment":"Should this test if blob content contains\n NUL bytes / looks like binary data before applying filters?"}],"argline":"git_buf *out, git_blob *blob, const char *as_path, int check_for_binary_data","sig":"git_buf *::git_blob *::const char *::int","return":{"type":"int","comment":" 0 on success or an error code"},"description":"

Get a buffer with the filtered content of a blob.

\n","comments":"

This applies filters as if the blob was being checked out to the\n working directory under the specified filename. This may apply\n CRLF filtering or other types of changes depending on the file\n attributes set for the blob and the content detected in it.

\n\n

The output is written into a git_buf which the caller must free\n when done (via git_buf_free).

\n\n

If no filters need to be applied, then the out buffer will just be\n populated with a pointer to the raw content of the blob. In that case,\n be careful to not free the blob until done with the buffer. To keep\n the data detached from the blob, call git_buf_grow on the buffer\n with a want_size of 0 and the buffer will be reallocated to be\n detached from the blob.

\n","group":"blob"},"git_blob_create_fromworkdir":{"type":"function","file":"blob.h","line":141,"lineto":141,"args":[{"name":"id","type":"git_oid *","comment":"return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where the blob will be written.\n\tthis repository cannot be bare"},{"name":"relative_path","type":"const char *","comment":"file from which the blob will be created,\n\trelative to the repository's working dir"}],"argline":"git_oid *id, git_repository *repo, const char *relative_path","sig":"git_oid *::git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Read a file from the working folder of a repository\n and write it to the Object Database as a loose blob

\n","comments":"","group":"blob"},"git_blob_create_fromdisk":{"type":"function","file":"blob.h","line":153,"lineto":153,"args":[{"name":"id","type":"git_oid *","comment":"return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where the blob will be written.\n\tthis repository can be bare or not"},{"name":"path","type":"const char *","comment":"file from which the blob will be created"}],"argline":"git_oid *id, git_repository *repo, const char *path","sig":"git_oid *::git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Read a file from the filesystem and write its content\n to the Object Database as a loose blob

\n","comments":"","group":"blob"},"git_blob_create_fromchunks":{"type":"function","file":"blob.h","line":189,"lineto":194,"args":[{"name":"id","type":"git_oid *","comment":"Return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"Repository where the blob will be written.\n This repository can be bare or not."},{"name":"hintpath","type":"const char *","comment":"If not NULL, will be used to select data filters\n to apply onto the content of the blob to be created."},{"name":"callback","type":"git_blob_chunk_cb","comment":null},{"name":"payload","type":"void *","comment":null}],"argline":"git_oid *id, git_repository *repo, const char *hintpath, git_blob_chunk_cb callback, void *payload","sig":"git_oid *::git_repository *::const char *::git_blob_chunk_cb::void *","return":{"type":"int","comment":" 0 or error code (from either libgit2 or callback function)"},"description":"

Write a loose blob to the Object Database from a\n provider of chunks of data.

\n","comments":"

If the hintpath parameter is filled, it will be used to determine\n what git filters should be applied to the object before it is written\n to the object database.

\n\n

The implementation of the callback MUST respect the following rules:

\n\n
    \n
  • content must be filled by the callback. The maximum number of\nbytes that the buffer can accept per call is defined by the\nmax_length parameter. Allocation and freeing of the buffer will\nbe taken care of by libgit2.

  • \n
  • The callback must return the number of bytes that have been\nwritten to the content buffer.

  • \n
  • When there is no more data to stream, callback should return

    \n\n
      \n
    1. This will prevent it from being invoked anymore.
    2. \n
  • \n
  • If an error occurs, the callback should return a negative value.\nThis value will be returned to the caller.

  • \n
\n","group":"blob"},"git_blob_create_frombuffer":{"type":"function","file":"blob.h","line":205,"lineto":206,"args":[{"name":"id","type":"git_oid *","comment":"return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where to blob will be written"},{"name":"buffer","type":"const void *","comment":"data to be written into the blob"},{"name":"len","type":"size_t","comment":"length of the data"}],"argline":"git_oid *id, git_repository *repo, const void *buffer, size_t len","sig":"git_oid *::git_repository *::const void *::size_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Write an in-memory buffer to the ODB as a blob

\n","comments":"","group":"blob"},"git_blob_is_binary":{"type":"function","file":"blob.h","line":219,"lineto":219,"args":[{"name":"blob","type":"const git_blob *","comment":"The blob which content should be analyzed"}],"argline":"const git_blob *blob","sig":"const git_blob *","return":{"type":"int","comment":" 1 if the content of the blob is detected\n as binary; 0 otherwise."},"description":"

Determine if the blob content is most certainly binary or not.

\n","comments":"

The heuristic used to guess if a file is binary is taken from core git:\n Searching for NUL bytes and looking for a reasonable ratio of printable\n to non-printable characters among the first 8000 bytes.

\n","group":"blob"},"git_branch_create":{"type":"function","file":"branch.h","line":56,"lineto":63,"args":[{"name":"out","type":"git_reference **","comment":"Pointer where to store the underlying reference."},{"name":"repo","type":"git_repository *","comment":null},{"name":"branch_name","type":"const char *","comment":"Name for the branch; this name is\n validated for consistency. It should also not conflict with\n an already existing branch name."},{"name":"target","type":"const git_commit *","comment":"Commit to which this branch should point. This object\n must belong to the given `repo`."},{"name":"force","type":"int","comment":"Overwrite existing branch."},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog.\n If NULL, the default is \"Branch: created\"; if you want something more\n useful, provide a message."}],"argline":"git_reference **out, git_repository *repo, const char *branch_name, const git_commit *target, int force, const git_signature *signature, const char *log_message","sig":"git_reference **::git_repository *::const char *::const git_commit *::int::const git_signature *::const char *","return":{"type":"int","comment":" 0, GIT_EINVALIDSPEC or an error code.\n A proper reference is written in the refs/heads namespace\n pointing to the provided target commit."},"description":"

Create a new branch pointing at a target commit

\n","comments":"

A new direct reference will be created pointing to\n this target commit. If force is true and a reference\n already exists with the given name, it'll be replaced.

\n\n

The returned reference must be freed by the user.

\n\n

The branch name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"branch"},"git_branch_delete":{"type":"function","file":"branch.h","line":75,"lineto":75,"args":[{"name":"branch","type":"git_reference *","comment":"A valid reference representing a branch"}],"argline":"git_reference *branch","sig":"git_reference *","return":{"type":"int","comment":" 0 on success, or an error code."},"description":"

Delete an existing branch reference.

\n","comments":"

If the branch is successfully deleted, the passed reference\n object will be invalidated. The reference must be freed manually\n by the user.

\n","group":"branch"},"git_branch_iterator_new":{"type":"function","file":"branch.h","line":91,"lineto":94,"args":[{"name":"out","type":"git_branch_iterator **","comment":"the iterator"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the branches."},{"name":"list_flags","type":"git_branch_t","comment":"Filtering flags for the branch\n listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE\n or GIT_BRANCH_ALL."}],"argline":"git_branch_iterator **out, git_repository *repo, git_branch_t list_flags","sig":"git_branch_iterator **::git_repository *::git_branch_t","return":{"type":"int","comment":" 0 on success or an error code"},"description":"

Create an iterator which loops over the requested branches.

\n","comments":"","group":"branch"},"git_branch_next":{"type":"function","file":"branch.h","line":104,"lineto":104,"args":[{"name":"out","type":"git_reference **","comment":"the reference"},{"name":"out_type","type":"git_branch_t *","comment":"the type of branch (local or remote-tracking)"},{"name":"iter","type":"git_branch_iterator *","comment":"the branch iterator"}],"argline":"git_reference **out, git_branch_t *out_type, git_branch_iterator *iter","sig":"git_reference **::git_branch_t *::git_branch_iterator *","return":{"type":"int","comment":" 0 on success, GIT_ITEROVER if there are no more branches or an error code."},"description":"

Retrieve the next branch from the iterator

\n","comments":"","group":"branch"},"git_branch_iterator_free":{"type":"function","file":"branch.h","line":111,"lineto":111,"args":[{"name":"iter","type":"git_branch_iterator *","comment":"the iterator to free"}],"argline":"git_branch_iterator *iter","sig":"git_branch_iterator *","return":{"type":"void","comment":null},"description":"

Free a branch iterator

\n","comments":"","group":"branch"},"git_branch_move":{"type":"function","file":"branch.h","line":132,"lineto":138,"args":[{"name":"out","type":"git_reference **","comment":null},{"name":"branch","type":"git_reference *","comment":"Current underlying reference of the branch."},{"name":"new_branch_name","type":"const char *","comment":"Target name of the branch once the move\n is performed; this name is validated for consistency."},{"name":"force","type":"int","comment":"Overwrite existing branch."},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_reference *branch, const char *new_branch_name, int force, const git_signature *signature, const char *log_message","sig":"git_reference **::git_reference *::const char *::int::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC or an error code."},"description":"

Move/rename an existing local branch reference.

\n","comments":"

The new branch name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"branch"},"git_branch_lookup":{"type":"function","file":"branch.h","line":161,"lineto":165,"args":[{"name":"out","type":"git_reference **","comment":"pointer to the looked-up branch reference"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the branch"},{"name":"branch_name","type":"const char *","comment":"Name of the branch to be looked-up;\n this name is validated for consistency."},{"name":"branch_type","type":"git_branch_t","comment":"Type of the considered branch. This should\n be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE."}],"argline":"git_reference **out, git_repository *repo, const char *branch_name, git_branch_t branch_type","sig":"git_reference **::git_repository *::const char *::git_branch_t","return":{"type":"int","comment":" 0 on success; GIT_ENOTFOUND when no matching branch\n exists, GIT_EINVALIDSPEC, otherwise an error code."},"description":"

Lookup a branch by its name in a repository.

\n","comments":"

The generated reference must be freed by the user.

\n\n

The branch name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"branch"},"git_branch_name":{"type":"function","file":"branch.h","line":182,"lineto":184,"args":[{"name":"out","type":"const char **","comment":"where the pointer of branch name is stored;\n this is valid as long as the ref is not freed."},{"name":"ref","type":"const git_reference *","comment":"the reference ideally pointing to a branch"}],"argline":"const char **out, const git_reference *ref","sig":"const char **::const git_reference *","return":{"type":"int","comment":" 0 on success; otherwise an error code (e.g., if the\n ref is no local or remote branch)."},"description":"

Return the name of the given local or remote branch.

\n","comments":"

The name of the branch matches the definition of the name\n for git_branch_lookup. That is, if the returned name is given\n to git_branch_lookup() then the reference is returned that\n was given to this function.

\n","group":"branch"},"git_branch_upstream":{"type":"function","file":"branch.h","line":198,"lineto":200,"args":[{"name":"out","type":"git_reference **","comment":"Pointer where to store the retrieved\n reference."},{"name":"branch","type":"const git_reference *","comment":"Current underlying reference of the branch."}],"argline":"git_reference **out, const git_reference *branch","sig":"git_reference **::const git_reference *","return":{"type":"int","comment":" 0 on success; GIT_ENOTFOUND when no remote tracking\n reference exists, otherwise an error code."},"description":"

Return the reference supporting the remote tracking branch,\n given a local branch reference.

\n","comments":"","group":"branch"},"git_branch_set_upstream":{"type":"function","file":"branch.h","line":212,"lineto":212,"args":[{"name":"branch","type":"git_reference *","comment":"the branch to configure"},{"name":"upstream_name","type":"const char *","comment":"remote-tracking or local branch to set as\n upstream. Pass NULL to unset."}],"argline":"git_reference *branch, const char *upstream_name","sig":"git_reference *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the upstream configuration for a given local branch

\n","comments":"","group":"branch"},"git_branch_is_head":{"type":"function","file":"branch.h","line":241,"lineto":242,"args":[{"name":"branch","type":"const git_reference *","comment":"Current underlying reference of the branch."}],"argline":"const git_reference *branch","sig":"const git_reference *","return":{"type":"int","comment":" 1 if HEAD points at the branch, 0 if it isn't,\n error code otherwise."},"description":"

Determine if the current local branch is pointed at by HEAD.

\n","comments":"","group":"branch"},"git_buf_free":{"type":"function","file":"buffer.h","line":72,"lineto":72,"args":[{"name":"buffer","type":"git_buf *","comment":"The buffer to deallocate"}],"argline":"git_buf *buffer","sig":"git_buf *","return":{"type":"void","comment":null},"description":"

Free the memory referred to by the git_buf.

\n","comments":"

Note that this does not free the git_buf itself, just the memory\n pointed to by buffer->ptr. This will not free the memory if it looks\n like it was not allocated internally, but it will clear the buffer back\n to the empty state.

\n","group":"buf","examples":{"diff.c":["ex/v0.21.2/diff.html#git_buf_free-1"],"tag.c":["ex/v0.21.2/tag.html#git_buf_free-1"]}},"git_buf_grow":{"type":"function","file":"buffer.h","line":95,"lineto":95,"args":[{"name":"buffer","type":"git_buf *","comment":"The buffer to be resized; may or may not be allocated yet"},{"name":"target_size","type":"size_t","comment":"The desired available size"}],"argline":"git_buf *buffer, size_t target_size","sig":"git_buf *::size_t","return":{"type":"int","comment":" 0 on success, -1 on allocation failure"},"description":"

Resize the buffer allocation to make more space.

\n","comments":"

This will attempt to grow the buffer to accomodate the target size.

\n\n

If the buffer refers to memory that was not allocated by libgit2 (i.e.\n the asize field is zero), then ptr will be replaced with a newly\n allocated block of data. Be careful so that memory allocated by the\n caller is not lost. As a special variant, if you pass target_size as\n 0 and the memory is not allocated by libgit2, this will allocate a new\n buffer of size size and copy the external data into it.

\n\n

Currently, this will never shrink a buffer, only expand it.

\n\n

If the allocation fails, this will return an error and the buffer will be\n marked as invalid for future operations, invaliding the contents.

\n","group":"buf"},"git_buf_set":{"type":"function","file":"buffer.h","line":105,"lineto":106,"args":[{"name":"buffer","type":"git_buf *","comment":"The buffer to set"},{"name":"data","type":"const void *","comment":"The data to copy into the buffer"},{"name":"datalen","type":"size_t","comment":"The length of the data to copy into the buffer"}],"argline":"git_buf *buffer, const void *data, size_t datalen","sig":"git_buf *::const void *::size_t","return":{"type":"int","comment":" 0 on success, -1 on allocation failure"},"description":"

Set buffer to a copy of some raw data.

\n","comments":"","group":"buf"},"git_checkout_init_options":{"type":"function","file":"checkout.h","line":277,"lineto":279,"args":[{"name":"opts","type":"git_checkout_options *","comment":"the `git_checkout_options` struct to initialize."},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_CHECKOUT_OPTIONS_VERSION`"}],"argline":"git_checkout_options *opts, unsigned int version","sig":"git_checkout_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_checkout_options with default values. Equivalent to\n creating an instance with GIT_CHECKOUT_OPTIONS_INIT.

\n","comments":"","group":"checkout"},"git_checkout_head":{"type":"function","file":"checkout.h","line":291,"lineto":293,"args":[{"name":"repo","type":"git_repository *","comment":"repository to check out (must be non-bare)"},{"name":"opts","type":"const git_checkout_options *","comment":"specifies checkout options (may be NULL)"}],"argline":"git_repository *repo, const git_checkout_options *opts","sig":"git_repository *::const git_checkout_options *","return":{"type":"int","comment":" 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non\n existing branch, non-zero value returned by `notify_cb`, or\n other error code \n<\n 0 (use giterr_last for error details)"},"description":"

Updates files in the index and the working tree to match the content of\n the commit pointed at by HEAD.

\n","comments":"","group":"checkout"},"git_checkout_index":{"type":"function","file":"checkout.h","line":304,"lineto":307,"args":[{"name":"repo","type":"git_repository *","comment":"repository into which to check out (must be non-bare)"},{"name":"index","type":"git_index *","comment":"index to be checked out (or NULL to use repository index)"},{"name":"opts","type":"const git_checkout_options *","comment":"specifies checkout options (may be NULL)"}],"argline":"git_repository *repo, git_index *index, const git_checkout_options *opts","sig":"git_repository *::git_index *::const git_checkout_options *","return":{"type":"int","comment":" 0 on success, non-zero return value from `notify_cb`, or error\n code \n<\n 0 (use giterr_last for error details)"},"description":"

Updates files in the working tree to match the content of the index.

\n","comments":"","group":"checkout"},"git_checkout_tree":{"type":"function","file":"checkout.h","line":320,"lineto":323,"args":[{"name":"repo","type":"git_repository *","comment":"repository to check out (must be non-bare)"},{"name":"treeish","type":"const git_object *","comment":"a commit, tag or tree which content will be used to update\n the working directory (or NULL to use HEAD)"},{"name":"opts","type":"const git_checkout_options *","comment":"specifies checkout options (may be NULL)"}],"argline":"git_repository *repo, const git_object *treeish, const git_checkout_options *opts","sig":"git_repository *::const git_object *::const git_checkout_options *","return":{"type":"int","comment":" 0 on success, non-zero return value from `notify_cb`, or error\n code \n<\n 0 (use giterr_last for error details)"},"description":"

Updates files in the index and working tree to match the content of the\n tree pointed at by the treeish.

\n","comments":"","group":"checkout"},"git_cherry_pick_init_options":{"type":"function","file":"cherrypick.h","line":44,"lineto":46,"args":[{"name":"opts","type":"git_cherry_pick_options *","comment":"the `git_cherry_pick_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_CHERRY_PICK_OPTIONS_VERSION`"}],"argline":"git_cherry_pick_options *opts, unsigned int version","sig":"git_cherry_pick_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_cherry_pick_options with default values. Equivalent to\n creating an instance with GIT_CHERRY_PICK_OPTIONS_INIT.

\n","comments":"","group":"cherry"},"git_cherry_pick_commit":{"type":"function","file":"cherrypick.h","line":62,"lineto":68,"args":[{"name":"out","type":"git_index **","comment":"pointer to store the index result in"},{"name":"repo","type":"git_repository *","comment":"the repository that contains the given commits"},{"name":"cherry_pick_commit","type":"git_commit *","comment":"the commit to cherry-pick"},{"name":"our_commit","type":"git_commit *","comment":"the commit to revert against (eg, HEAD)"},{"name":"mainline","type":"unsigned int","comment":"the parent of the revert commit, if it is a merge"},{"name":"merge_options","type":"const git_merge_options *","comment":"the merge options (or null for defaults)"}],"argline":"git_index **out, git_repository *repo, git_commit *cherry_pick_commit, git_commit *our_commit, unsigned int mainline, const git_merge_options *merge_options","sig":"git_index **::git_repository *::git_commit *::git_commit *::unsigned int::const git_merge_options *","return":{"type":"int","comment":" zero on success, -1 on failure."},"description":"

Cherry-picks the given commit against the given "our" commit, producing an\n index that reflects the result of the cherry-pick.

\n","comments":"

The returned index must be freed explicitly with git_index_free.

\n","group":"cherry"},"git_cherry_pick":{"type":"function","file":"cherrypick.h","line":78,"lineto":81,"args":[{"name":"repo","type":"git_repository *","comment":"the repository to cherry-pick"},{"name":"commit","type":"git_commit *","comment":"the commit to cherry-pick"},{"name":"cherry_pick_options","type":"const git_cherry_pick_options *","comment":"the cherry-pick options (or null for defaults)"}],"argline":"git_repository *repo, git_commit *commit, const git_cherry_pick_options *cherry_pick_options","sig":"git_repository *::git_commit *::const git_cherry_pick_options *","return":{"type":"int","comment":" zero on success, -1 on failure."},"description":"

Cherry-pick the given commit, producing changes in the index and working directory.

\n","comments":"","group":"cherry"},"git_clone_init_options":{"type":"function","file":"clone.h","line":126,"lineto":128,"args":[{"name":"opts","type":"git_clone_options *","comment":"The `git_clone_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_CLONE_OPTIONS_VERSION`"}],"argline":"git_clone_options *opts, unsigned int version","sig":"git_clone_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_clone_options with default values. Equivalent to\n creating an instance with GIT_CLONE_OPTIONS_INIT.

\n","comments":"","group":"clone"},"git_clone":{"type":"function","file":"clone.h","line":146,"lineto":150,"args":[{"name":"out","type":"git_repository **","comment":"pointer that will receive the resulting repository object"},{"name":"url","type":"const char *","comment":"the remote repository to clone"},{"name":"local_path","type":"const char *","comment":"local directory to clone to"},{"name":"options","type":"const git_clone_options *","comment":"configuration options for the clone. If NULL, the\n function works as though GIT_OPTIONS_INIT were passed."}],"argline":"git_repository **out, const char *url, const char *local_path, const git_clone_options *options","sig":"git_repository **::const char *::const char *::const git_clone_options *","return":{"type":"int","comment":" 0 on success, any non-zero return value from a callback\n function, or a negative value to indicate an error (use\n `giterr_last` for a detailed error message)"},"description":"

Clone a remote repository.

\n","comments":"

This version handles the simple case. If you'd like to create the\n repository or remote with non-default settings, you can create and\n configure them and then use git_clone_into().

\n","group":"clone","examples":{"network/clone.c":["ex/v0.21.2/network/clone.html#git_clone-1"]}},"git_clone_into":{"type":"function","file":"clone.h","line":169,"lineto":174,"args":[{"name":"repo","type":"git_repository *","comment":"the repository to use"},{"name":"remote","type":"git_remote *","comment":"the remote repository to clone from"},{"name":"co_opts","type":"const git_checkout_options *","comment":"options to use during checkout"},{"name":"branch","type":"const char *","comment":"the branch to checkout after the clone, pass NULL for the\n remote's default branch"},{"name":"signature","type":"const git_signature *","comment":"The identity used when updating the reflog."}],"argline":"git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature","sig":"git_repository *::git_remote *::const git_checkout_options *::const char *::const git_signature *","return":{"type":"int","comment":" 0 on success, any non-zero return value from a callback\n function, or a negative value to indicate an error (use\n `giterr_last` for a detailed error message)"},"description":"

Clone into a repository

\n","comments":"

After creating the repository and remote and configuring them for\n paths and callbacks respectively, you can call this function to\n perform the clone operation and optionally checkout files.

\n","group":"clone"},"git_clone_local_into":{"type":"function","file":"clone.h","line":197,"lineto":203,"args":[{"name":"repo","type":"git_repository *","comment":"the repository to use"},{"name":"remote","type":"git_remote *","comment":"the remote repository to clone from"},{"name":"co_opts","type":"const git_checkout_options *","comment":"options to use during checkout"},{"name":"branch","type":"const char *","comment":"the branch to checkout after the clone, pass NULL for the\n remote's default branch"},{"name":"link","type":"int","comment":"wether to use hardlinks instead of copying\n objects. This is only possible if both repositories are on the same\n filesystem."},{"name":"signature","type":"const git_signature *","comment":"the identity used when updating the reflog"}],"argline":"git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature","sig":"git_repository *::git_remote *::const git_checkout_options *::const char *::int::const git_signature *","return":{"type":"int","comment":" 0 on success, any non-zero return value from a callback\n function, or a negative value to indicate an error (use\n `giterr_last` for a detailed error message)"},"description":"

Perform a local clone into a repository

\n","comments":"

A "local clone" bypasses any git-aware protocols and simply copies\n over the object database from the source repository. It is often\n faster than a git-aware clone, but no verification of the data is\n performed, and can copy over too much data.

\n","group":"clone"},"git_commit_lookup":{"type":"function","file":"commit.h","line":36,"lineto":37,"args":[{"name":"commit","type":"git_commit **","comment":"pointer to the looked up commit"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the commit."},{"name":"id","type":"const git_oid *","comment":"identity of the commit to locate. If the object is\n\t\tan annotated tag it will be peeled back to the commit."}],"argline":"git_commit **commit, git_repository *repo, const git_oid *id","sig":"git_commit **::git_repository *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a commit object from a repository.

\n","comments":"

The returned object should be released with git_commit_free when no\n longer needed.

\n","group":"commit","examples":{"general.c":["ex/v0.21.2/general.html#git_commit_lookup-5","ex/v0.21.2/general.html#git_commit_lookup-6","ex/v0.21.2/general.html#git_commit_lookup-7"],"log.c":["ex/v0.21.2/log.html#git_commit_lookup-1"]}},"git_commit_lookup_prefix":{"type":"function","file":"commit.h","line":55,"lineto":56,"args":[{"name":"commit","type":"git_commit **","comment":"pointer to the looked up commit"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the commit."},{"name":"id","type":"const git_oid *","comment":"identity of the commit to locate. If the object is\n\t\tan annotated tag it will be peeled back to the commit."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_commit **commit, git_repository *repo, const git_oid *id, size_t len","sig":"git_commit **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a commit object from a repository, given a prefix of its\n identifier (short id).

\n","comments":"

The returned object should be released with git_commit_free when no\n longer needed.

\n","group":"commit"},"git_commit_free":{"type":"function","file":"commit.h","line":70,"lineto":70,"args":[{"name":"commit","type":"git_commit *","comment":"the commit to close"}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"void","comment":null},"description":"

Close an open commit

\n","comments":"

This is a wrapper around git_object_free()

\n\n

IMPORTANT:\n It is necessary to call this method when you stop\n using a commit. Failure to do so will cause a memory leak.

\n","group":"commit","examples":{"general.c":["ex/v0.21.2/general.html#git_commit_free-8","ex/v0.21.2/general.html#git_commit_free-9","ex/v0.21.2/general.html#git_commit_free-10","ex/v0.21.2/general.html#git_commit_free-11"],"log.c":["ex/v0.21.2/log.html#git_commit_free-2","ex/v0.21.2/log.html#git_commit_free-3","ex/v0.21.2/log.html#git_commit_free-4","ex/v0.21.2/log.html#git_commit_free-5"]}},"git_commit_id":{"type":"function","file":"commit.h","line":78,"lineto":78,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const git_oid *","comment":" object identity for the commit."},"description":"

Get the id of a commit.

\n","comments":"","group":"commit","examples":{"general.c":["ex/v0.21.2/general.html#git_commit_id-12"],"log.c":["ex/v0.21.2/log.html#git_commit_id-6"]}},"git_commit_owner":{"type":"function","file":"commit.h","line":86,"lineto":86,"args":[{"name":"commit","type":"const git_commit *","comment":"A previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"git_repository *","comment":" Repository that contains this commit."},"description":"

Get the repository that contains the commit.

\n","comments":"","group":"commit","examples":{"log.c":["ex/v0.21.2/log.html#git_commit_owner-7","ex/v0.21.2/log.html#git_commit_owner-8"]}},"git_commit_message_encoding":{"type":"function","file":"commit.h","line":98,"lineto":98,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const char *","comment":" NULL, or the encoding"},"description":"

Get the encoding for the message of a commit,\n as a string representing a standard encoding name.

\n","comments":"

The encoding may be NULL if the encoding header\n in the commit is missing; in that case UTF-8 is assumed.

\n","group":"commit"},"git_commit_message":{"type":"function","file":"commit.h","line":109,"lineto":109,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const char *","comment":" the message of a commit"},"description":"

Get the full message of a commit.

\n","comments":"

The returned message will be slightly prettified by removing any\n potential leading newlines.

\n","group":"commit","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_commit_message-3","ex/v0.21.2/cat-file.html#git_commit_message-4"],"general.c":["ex/v0.21.2/general.html#git_commit_message-13","ex/v0.21.2/general.html#git_commit_message-14","ex/v0.21.2/general.html#git_commit_message-15"],"log.c":["ex/v0.21.2/log.html#git_commit_message-9","ex/v0.21.2/log.html#git_commit_message-10"],"tag.c":["ex/v0.21.2/tag.html#git_commit_message-2"]}},"git_commit_message_raw":{"type":"function","file":"commit.h","line":117,"lineto":117,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const char *","comment":" the raw message of a commit"},"description":"

Get the full raw message of a commit.

\n","comments":"","group":"commit"},"git_commit_summary":{"type":"function","file":"commit.h","line":128,"lineto":128,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const char *","comment":" the summary of a commit or NULL on error"},"description":"

Get the short "summary" of the git commit message.

\n","comments":"

The returned message is the summary of the commit, comprising the\n first paragraph of the message with whitespace trimmed and squashed.

\n","group":"commit"},"git_commit_time":{"type":"function","file":"commit.h","line":136,"lineto":136,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"git_time_t","comment":" the time of a commit"},"description":"

Get the commit time (i.e. committer time) of a commit.

\n","comments":"","group":"commit","examples":{"general.c":["ex/v0.21.2/general.html#git_commit_time-16","ex/v0.21.2/general.html#git_commit_time-17"]}},"git_commit_time_offset":{"type":"function","file":"commit.h","line":144,"lineto":144,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"int","comment":" positive or negative timezone offset, in minutes from UTC"},"description":"

Get the commit timezone offset (i.e. committer's preferred timezone) of a commit.

\n","comments":"","group":"commit"},"git_commit_committer":{"type":"function","file":"commit.h","line":152,"lineto":152,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const git_signature *","comment":" the committer of a commit"},"description":"

Get the committer of a commit.

\n","comments":"","group":"commit","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_commit_committer-5"],"general.c":["ex/v0.21.2/general.html#git_commit_committer-18"],"log.c":["ex/v0.21.2/log.html#git_commit_committer-11"]}},"git_commit_author":{"type":"function","file":"commit.h","line":160,"lineto":160,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const git_signature *","comment":" the author of a commit"},"description":"

Get the author of a commit.

\n","comments":"","group":"commit","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_commit_author-6"],"general.c":["ex/v0.21.2/general.html#git_commit_author-19","ex/v0.21.2/general.html#git_commit_author-20"],"log.c":["ex/v0.21.2/log.html#git_commit_author-12","ex/v0.21.2/log.html#git_commit_author-13"]}},"git_commit_raw_header":{"type":"function","file":"commit.h","line":168,"lineto":168,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit"}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const char *","comment":" the header text of the commit"},"description":"

Get the full raw text of the commit header.

\n","comments":"","group":"commit"},"git_commit_tree":{"type":"function","file":"commit.h","line":177,"lineto":177,"args":[{"name":"tree_out","type":"git_tree **","comment":"pointer where to store the tree object"},{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"git_tree **tree_out, const git_commit *commit","sig":"git_tree **::const git_commit *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the tree pointed to by a commit.

\n","comments":"","group":"commit","examples":{"log.c":["ex/v0.21.2/log.html#git_commit_tree-14","ex/v0.21.2/log.html#git_commit_tree-15","ex/v0.21.2/log.html#git_commit_tree-16","ex/v0.21.2/log.html#git_commit_tree-17","ex/v0.21.2/log.html#git_commit_tree-18"]}},"git_commit_tree_id":{"type":"function","file":"commit.h","line":187,"lineto":187,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"const git_oid *","comment":" the id of tree pointed to by commit."},"description":"

Get the id of the tree pointed to by a commit. This differs from\n git_commit_tree in that no attempts are made to fetch an object\n from the ODB.

\n","comments":"","group":"commit","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_commit_tree_id-7"]}},"git_commit_parentcount":{"type":"function","file":"commit.h","line":195,"lineto":195,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."}],"argline":"const git_commit *commit","sig":"const git_commit *","return":{"type":"unsigned int","comment":" integer of count of parents"},"description":"

Get the number of parents of this commit

\n","comments":"","group":"commit","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_commit_parentcount-8"],"general.c":["ex/v0.21.2/general.html#git_commit_parentcount-21"],"log.c":["ex/v0.21.2/log.html#git_commit_parentcount-19","ex/v0.21.2/log.html#git_commit_parentcount-20"]}},"git_commit_parent":{"type":"function","file":"commit.h","line":205,"lineto":208,"args":[{"name":"out","type":"git_commit **","comment":"Pointer where to store the parent commit"},{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."},{"name":"n","type":"unsigned int","comment":"the position of the parent (from 0 to `parentcount`)"}],"argline":"git_commit **out, const git_commit *commit, unsigned int n","sig":"git_commit **::const git_commit *::unsigned int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the specified parent of the commit.

\n","comments":"","group":"commit","examples":{"general.c":["ex/v0.21.2/general.html#git_commit_parent-22"],"log.c":["ex/v0.21.2/log.html#git_commit_parent-21","ex/v0.21.2/log.html#git_commit_parent-22"]}},"git_commit_parent_id":{"type":"function","file":"commit.h","line":219,"lineto":221,"args":[{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."},{"name":"n","type":"unsigned int","comment":"the position of the parent (from 0 to `parentcount`)"}],"argline":"const git_commit *commit, unsigned int n","sig":"const git_commit *::unsigned int","return":{"type":"const git_oid *","comment":" the id of the parent, NULL on error."},"description":"

Get the oid of a specified parent for a commit. This is different from\n git_commit_parent, which will attempt to load the parent commit from\n the ODB.

\n","comments":"","group":"commit","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_commit_parent_id-9"],"log.c":["ex/v0.21.2/log.html#git_commit_parent_id-23"]}},"git_commit_nth_gen_ancestor":{"type":"function","file":"commit.h","line":237,"lineto":240,"args":[{"name":"ancestor","type":"git_commit **","comment":"Pointer where to store the ancestor commit"},{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."},{"name":"n","type":"unsigned int","comment":"the requested generation"}],"argline":"git_commit **ancestor, const git_commit *commit, unsigned int n","sig":"git_commit **::const git_commit *::unsigned int","return":{"type":"int","comment":" 0 on success; GIT_ENOTFOUND if no matching ancestor exists\n or an error code"},"description":"

Get the commit object that is the \n<n

\n\n
\n

th generation ancestor\n of the named commit object, following only the first parents.\n The returned commit has to be freed by the caller.

\n
\n","comments":"

Passing 0 as the generation number returns another instance of the\n base commit itself.

\n","group":"commit"},"git_commit_create":{"type":"function","file":"commit.h","line":286,"lineto":296,"args":[{"name":"id","type":"git_oid *","comment":"Pointer in which to store the OID of the newly created commit"},{"name":"repo","type":"git_repository *","comment":"Repository where to store the commit"},{"name":"update_ref","type":"const char *","comment":"If not NULL, name of the reference that\n\twill be updated to point to this commit. If the reference\n\tis not direct, it will be resolved to a direct reference.\n\tUse \"HEAD\" to update the HEAD of the current branch and\n\tmake it point to this commit. If the reference doesn't\n\texist yet, it will be created. If it does exist, the first\n\tparent must be the tip of this branch."},{"name":"author","type":"const git_signature *","comment":"Signature with author and author time of commit"},{"name":"committer","type":"const git_signature *","comment":"Signature with committer and * commit time of commit"},{"name":"message_encoding","type":"const char *","comment":"The encoding for the message in the\n commit, represented with a standard encoding name.\n E.g. \"UTF-8\". If NULL, no encoding header is written and\n UTF-8 is assumed."},{"name":"message","type":"const char *","comment":"Full message for this commit"},{"name":"tree","type":"const git_tree *","comment":"An instance of a `git_tree` object that will\n be used as the tree for the commit. This tree object must\n also be owned by the given `repo`."},{"name":"parent_count","type":"size_t","comment":"Number of parents for this commit"},{"name":"parents","type":"const git_commit *[]","comment":"Array of `parent_count` pointers to `git_commit`\n objects that will be used as the parents for this commit. This\n array may be NULL if `parent_count` is 0 (root commit). All the\n given commits must be owned by the `repo`."}],"argline":"git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree, size_t parent_count, const git_commit *[] parents","sig":"git_oid *::git_repository *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_tree *::size_t::const git_commit *[]","return":{"type":"int","comment":" 0 or an error code\n\tThe created commit will be written to the Object Database and\n\tthe given reference will be updated to point to it"},"description":"

Create new commit in the repository from a list of git_object pointers

\n","comments":"

The message will not be cleaned up automatically. You can do that\n with the git_message_prettify() function.

\n","group":"commit"},"git_commit_create_v":{"type":"function","file":"commit.h","line":312,"lineto":322,"args":[{"name":"id","type":"git_oid *","comment":null},{"name":"repo","type":"git_repository *","comment":null},{"name":"update_ref","type":"const char *","comment":null},{"name":"author","type":"const git_signature *","comment":null},{"name":"committer","type":"const git_signature *","comment":null},{"name":"message_encoding","type":"const char *","comment":null},{"name":"message","type":"const char *","comment":null},{"name":"tree","type":"const git_tree *","comment":null},{"name":"parent_count","type":"size_t","comment":null}],"argline":"git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree, size_t parent_count","sig":"git_oid *::git_repository *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_tree *::size_t","return":{"type":"int","comment":null},"description":"

Create new commit in the repository using a variable argument list.

\n","comments":"

The message will not be cleaned up automatically. You can do that\n with the git_message_prettify() function.

\n\n

The parents for the commit are specified as a variable list of pointers\n to const git_commit *. Note that this is a convenience method which may\n not be safe to export for certain languages or compilers

\n\n

All other parameters remain the same as git_commit_create().

\n","group":"commit","examples":{"general.c":["ex/v0.21.2/general.html#git_commit_create_v-23"],"init.c":["ex/v0.21.2/init.html#git_commit_create_v-1"]}},"git_commit_amend":{"type":"function","file":"commit.h","line":345,"lineto":353,"args":[{"name":"id","type":"git_oid *","comment":null},{"name":"commit_to_amend","type":"const git_commit *","comment":null},{"name":"update_ref","type":"const char *","comment":null},{"name":"author","type":"const git_signature *","comment":null},{"name":"committer","type":"const git_signature *","comment":null},{"name":"message_encoding","type":"const char *","comment":null},{"name":"message","type":"const char *","comment":null},{"name":"tree","type":"const git_tree *","comment":null}],"argline":"git_oid *id, const git_commit *commit_to_amend, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree","sig":"git_oid *::const git_commit *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_tree *","return":{"type":"int","comment":null},"description":"

Amend an existing commit by replacing only non-NULL values.

\n","comments":"

This creates a new commit that is exactly the same as the old commit,\n except that any non-NULL values will be updated. The new commit has\n the same parents as the old commit.

\n\n

The update_ref value works as in the regular git_commit_create(),\n updating the ref to point to the newly rewritten commit. If you want\n to amend a commit that is not currently the tip of the branch and then\n rewrite the following commits to reach a ref, pass this as NULL and\n update the rest of the commit chain and ref separately.

\n\n

Unlike git_commit_create(), the author, committer, message,\n message_encoding, and tree parameters can be NULL in which case this\n will use the values from the original commit_to_amend.

\n\n

All parameters have the same meanings as in git_commit_create().

\n","group":"commit"},"git_libgit2_version":{"type":"function","file":"common.h","line":94,"lineto":94,"args":[{"name":"major","type":"int *","comment":"Store the major version number"},{"name":"minor","type":"int *","comment":"Store the minor version number"},{"name":"rev","type":"int *","comment":"Store the revision (patch) number"}],"argline":"int *major, int *minor, int *rev","sig":"int *::int *::int *","return":{"type":"void","comment":null},"description":"

Return the version of the libgit2 library\n being currently used.

\n","comments":"","group":"libgit2"},"git_libgit2_features":{"type":"function","file":"common.h","line":124,"lineto":124,"args":[],"argline":"","sig":"","return":{"type":"int","comment":" A combination of GIT_FEATURE_* values."},"description":"

Query compile time options for libgit2.

\n","comments":"
    \n
  • GIT_FEATURE_THREADS\nLibgit2 was compiled with thread support. Note that thread support is\nstill to be seen as a 'work in progress' - basic object lookups are\nbelieved to be threadsafe, but other operations may not be.

  • \n
  • GIT_FEATURE_HTTPS\nLibgit2 supports the https:// protocol. This requires the openssl\nlibrary to be found when compiling libgit2.

  • \n
  • GIT_FEATURE_SSH\nLibgit2 supports the SSH protocol for network operations. This requires\nthe libssh2 library to be found when compiling libgit2

  • \n
\n","group":"libgit2"},"git_libgit2_opts":{"type":"function","file":"common.h","line":228,"lineto":228,"args":[{"name":"option","type":"int","comment":"Option key"}],"argline":"int option","sig":"int","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure"},"description":"

Set or query a library global option

\n","comments":"

Available options:

\n\n
* opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *):\n\n    > Get the maximum mmap window size\n\n* opts(GIT_OPT_SET_MWINDOW_SIZE, size_t):\n\n    > Set the maximum mmap window size\n\n* opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *):\n\n    > Get the maximum memory that will be mapped in total by the library\n\n* opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t):\n\n    >Set the maximum amount of memory that can be mapped at any time\n    by the library\n\n* opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)\n\n    > Get the search path for a given level of config data.  "level" must\n    > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, or\n    > `GIT_CONFIG_LEVEL_XDG`.  The search path is written to the `out`\n    > buffer.\n\n* opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)\n\n    > Set the search path for a level of config data.  The search path\n    > applied to shared attributes and ignore files, too.\n    >\n    > - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR.\n    >   Pass NULL to reset to the default (generally based on environment\n    >   variables).  Use magic path `$PATH` to include the old value\n    >   of the path (if you want to prepend or append, for instance).\n    >\n    > - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL,\n    >   or GIT_CONFIG_LEVEL_XDG.\n\n* opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_otype type, size_t size)\n\n    > Set the maximum data size for the given type of object to be\n    > considered eligible for caching in memory.  Setting to value to\n    > zero means that that type of object will not be cached.\n    > Defaults to 0 for GIT_OBJ_BLOB (i.e. won't cache blobs) and 4k\n    > for GIT_OBJ_COMMIT, GIT_OBJ_TREE, and GIT_OBJ_TAG.\n\n* opts(GIT_OPT_SET_CACHE_MAX_SIZE, ssize_t max_storage_bytes)\n\n    > Set the maximum total data size that will be cached in memory\n    > across all repositories before libgit2 starts evicting objects\n    > from the cache.  This is a soft limit, in that the library might\n    > briefly exceed it, but will start aggressively evicting objects\n    > from cache when that happens.  The default cache size is 256MB.\n\n* opts(GIT_OPT_ENABLE_CACHING, int enabled)\n\n    > Enable or disable caching completely.\n    >\n    > Because caches are repository-specific, disabling the cache\n    > cannot immediately clear all cached objects, but each cache will\n    > be cleared on the next attempt to update anything in it.\n\n* opts(GIT_OPT_GET_CACHED_MEMORY, ssize_t *current, ssize_t *allowed)\n\n    > Get the current bytes in cache and the maximum that would be\n    > allowed in the cache.\n\n* opts(GIT_OPT_GET_TEMPLATE_PATH, git_buf *out)\n\n    > Get the default template path.\n    > The path is written to the `out` buffer.\n\n* opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)\n\n    > Set the default template path.\n    >\n    > - `path` directory of template.\n
\n","group":"libgit2"},"git_config_find_global":{"type":"function","file":"config.h","line":97,"lineto":97,"args":[{"name":"out","type":"git_buf *","comment":"Pointer to a user-allocated git_buf in which to store the path"}],"argline":"git_buf *out","sig":"git_buf *","return":{"type":"int","comment":" 0 if a global configuration file has been found. Its path will be stored in `out`."},"description":"

Locate the path to the global configuration file

\n","comments":"

The user or global configuration file is usually\n located in $HOME/.gitconfig.

\n\n

This method will try to guess the full path to that\n file, if the file exists. The returned path\n may be used on any git_config call to load the\n global configuration file.

\n\n

This method will not guess the path to the xdg compatible\n config file (.config/git/config).

\n","group":"config"},"git_config_find_xdg":{"type":"function","file":"config.h","line":114,"lineto":114,"args":[{"name":"out","type":"git_buf *","comment":"Pointer to a user-allocated git_buf in which to store the path"}],"argline":"git_buf *out","sig":"git_buf *","return":{"type":"int","comment":" 0 if a xdg compatible configuration file has been\n\tfound. Its path will be stored in `out`."},"description":"

Locate the path to the global xdg compatible configuration file

\n","comments":"

The xdg compatible configuration file is usually\n located in $HOME/.config/git/config.

\n\n

This method will try to guess the full path to that\n file, if the file exists. The returned path\n may be used on any git_config call to load the\n xdg compatible configuration file.

\n","group":"config"},"git_config_find_system":{"type":"function","file":"config.h","line":126,"lineto":126,"args":[{"name":"out","type":"git_buf *","comment":"Pointer to a user-allocated git_buf in which to store the path"}],"argline":"git_buf *out","sig":"git_buf *","return":{"type":"int","comment":" 0 if a system configuration file has been\n\tfound. Its path will be stored in `out`."},"description":"

Locate the path to the system configuration file

\n","comments":"

If /etc/gitconfig doesn't exist, it will look for\n %PROGRAMFILES%

\n\n

.

\n","group":"config"},"git_config_open_default":{"type":"function","file":"config.h","line":138,"lineto":138,"args":[{"name":"out","type":"git_config **","comment":"Pointer to store the config instance"}],"argline":"git_config **out","sig":"git_config **","return":{"type":"int","comment":" 0 or an error code"},"description":"

Open the global, XDG and system configuration files

\n","comments":"

Utility wrapper that finds the global, XDG and system configuration files\n and opens them into a single prioritized config object that can be\n used when accessing default config data outside a repository.

\n","group":"config"},"git_config_new":{"type":"function","file":"config.h","line":149,"lineto":149,"args":[{"name":"out","type":"git_config **","comment":"pointer to the new configuration"}],"argline":"git_config **out","sig":"git_config **","return":{"type":"int","comment":" 0 or an error code"},"description":"

Allocate a new configuration object

\n","comments":"

This object is empty, so you have to add a file to it before you\n can do anything with it.

\n","group":"config"},"git_config_add_file_ondisk":{"type":"function","file":"config.h","line":173,"lineto":177,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration to add the file to"},{"name":"path","type":"const char *","comment":"path to the configuration file to add"},{"name":"level","type":"git_config_level_t","comment":"the priority level of the backend"},{"name":"force","type":"int","comment":"replace config file at the given priority level"}],"argline":"git_config *cfg, const char *path, git_config_level_t level, int force","sig":"git_config *::const char *::git_config_level_t::int","return":{"type":"int","comment":" 0 on success, GIT_EEXISTS when adding more than one file\n for a given priority level (and force_replace set to 0),\n GIT_ENOTFOUND when the file doesn't exist or error code"},"description":"

Add an on-disk config file instance to an existing config

\n","comments":"

The on-disk file pointed at by path will be opened and\n parsed; it's expected to be a native Git config file following\n the default Git config syntax (see man git-config).

\n\n

Note that the configuration object will free the file\n automatically.

\n\n

Further queries on this config object will access each\n of the config file instances in order (instances with\n a higher priority level will be accessed first).

\n","group":"config"},"git_config_open_ondisk":{"type":"function","file":"config.h","line":192,"lineto":192,"args":[{"name":"out","type":"git_config **","comment":"The configuration instance to create"},{"name":"path","type":"const char *","comment":"Path to the on-disk file to open"}],"argline":"git_config **out, const char *path","sig":"git_config **::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND when the file doesn't exist\n or an error code"},"description":"

Create a new config instance containing a single on-disk file

\n","comments":"

This method is a simple utility wrapper for the following sequence\n of calls:\n - git_config_new\n - git_config_add_file_ondisk

\n","group":"config","examples":{"general.c":["ex/v0.21.2/general.html#git_config_open_ondisk-24"]}},"git_config_open_level":{"type":"function","file":"config.h","line":210,"lineto":213,"args":[{"name":"out","type":"git_config **","comment":"The configuration instance to create"},{"name":"parent","type":"const git_config *","comment":"Multi-level config to search for the given level"},{"name":"level","type":"git_config_level_t","comment":"Configuration level to search for"}],"argline":"git_config **out, const git_config *parent, git_config_level_t level","sig":"git_config **::const git_config *::git_config_level_t","return":{"type":"int","comment":" 0, GIT_ENOTFOUND if the passed level cannot be found in the\n multi-level parent config, or an error code"},"description":"

Build a single-level focused config object from a multi-level one.

\n","comments":"

The returned config object can be used to perform get/set/delete operations\n on a single specific level.

\n\n

Getting several times the same level from the same parent multi-level config\n will return different config instances, but containing the same config_file\n instance.

\n","group":"config"},"git_config_open_global":{"type":"function","file":"config.h","line":227,"lineto":227,"args":[{"name":"out","type":"git_config **","comment":"pointer in which to store the config object"},{"name":"config","type":"git_config *","comment":"the config object in which to look"}],"argline":"git_config **out, git_config *config","sig":"git_config **::git_config *","return":{"type":"int","comment":null},"description":"

Open the global/XDG configuration file according to git's rules

\n","comments":"

Git allows you to store your global configuration at\n $HOME/.config or $XDG_CONFIG_HOME/git/config. For backwards\n compatability, the XDG file shouldn't be used unless the use has\n created it explicitly. With this function you'll open the correct\n one to write to.

\n","group":"config"},"git_config_snapshot":{"type":"function","file":"config.h","line":243,"lineto":243,"args":[{"name":"out","type":"git_config **","comment":"pointer in which to store the snapshot config object"},{"name":"config","type":"git_config *","comment":"configuration to snapshot"}],"argline":"git_config **out, git_config *config","sig":"git_config **::git_config *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a snapshot of the configuration

\n","comments":"

Create a snapshot of the current state of a configuration, which\n allows you to look into a consistent view of the configuration for\n looking up complex values (e.g. a remote, submodule).

\n\n

The string returned when querying such a config object is valid\n until it is freed.

\n","group":"config"},"git_config_refresh":{"type":"function","file":"config.h","line":257,"lineto":257,"args":[{"name":"cfg","type":"git_config *","comment":"The configuration to refresh"}],"argline":"git_config *cfg","sig":"git_config *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Reload changed config files

\n","comments":"

A config file may be changed on disk out from under the in-memory\n config object. This function causes us to look for files that have\n been modified since we last loaded them and refresh the config with\n the latest information.

\n","group":"config"},"git_config_free":{"type":"function","file":"config.h","line":264,"lineto":264,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration to free"}],"argline":"git_config *cfg","sig":"git_config *","return":{"type":"void","comment":null},"description":"

Free the configuration and its associated memory and files

\n","comments":"","group":"config"},"git_config_get_entry":{"type":"function","file":"config.h","line":277,"lineto":280,"args":[{"name":"out","type":"const git_config_entry **","comment":"pointer to the variable git_config_entry"},{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"const git_config_entry **out, const git_config *cfg, const char *name","sig":"const git_config_entry **::const git_config *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the git_config_entry of a config variable.

\n","comments":"

The git_config_entry is owned by the config and should not be freed by the\n user.

\n","group":"config"},"git_config_get_int32":{"type":"function","file":"config.h","line":294,"lineto":294,"args":[{"name":"out","type":"int32_t *","comment":"pointer to the variable where the value should be stored"},{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"int32_t *out, const git_config *cfg, const char *name","sig":"int32_t *::const git_config *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the value of an integer config variable.

\n","comments":"

All config files will be looked into, in the order of their\n defined level. A higher level means a higher priority. The\n first occurence of the variable will be returned here.

\n","group":"config","examples":{"general.c":["ex/v0.21.2/general.html#git_config_get_int32-25"]}},"git_config_get_int64":{"type":"function","file":"config.h","line":308,"lineto":308,"args":[{"name":"out","type":"int64_t *","comment":"pointer to the variable where the value should be stored"},{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"int64_t *out, const git_config *cfg, const char *name","sig":"int64_t *::const git_config *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the value of a long integer config variable.

\n","comments":"

All config files will be looked into, in the order of their\n defined level. A higher level means a higher priority. The\n first occurrence of the variable will be returned here.

\n","group":"config"},"git_config_get_bool":{"type":"function","file":"config.h","line":325,"lineto":325,"args":[{"name":"out","type":"int *","comment":"pointer to the variable where the value should be stored"},{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"int *out, const git_config *cfg, const char *name","sig":"int *::const git_config *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the value of a boolean config variable.

\n","comments":"

This function uses the usual C convention of 0 being false and\n anything else true.

\n\n

All config files will be looked into, in the order of their\n defined level. A higher level means a higher priority. The\n first occurrence of the variable will be returned here.

\n","group":"config"},"git_config_get_string":{"type":"function","file":"config.h","line":343,"lineto":343,"args":[{"name":"out","type":"const char **","comment":"pointer to the variable's value"},{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"const char **out, const git_config *cfg, const char *name","sig":"const char **::const git_config *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the value of a string config variable.

\n","comments":"

The string is owned by the variable and should not be freed by the\n user. The pointer will be valid until the next operation on this\n config object.

\n\n

All config files will be looked into, in the order of their\n defined level. A higher level means a higher priority. The\n first occurrence of the variable will be returned here.

\n","group":"config","examples":{"general.c":["ex/v0.21.2/general.html#git_config_get_string-26"]}},"git_config_get_multivar_foreach":{"type":"function","file":"config.h","line":357,"lineto":357,"args":[{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"regexp","type":"const char *","comment":"regular expression to filter which variables we're\n interested in. Use NULL to indicate all"},{"name":"callback","type":"git_config_foreach_cb","comment":"the function to be called on each value of the variable"},{"name":"payload","type":"void *","comment":"opaque pointer to pass to the callback"}],"argline":"const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload","sig":"const git_config *::const char *::const char *::git_config_foreach_cb::void *","return":{"type":"int","comment":null},"description":"

Get each value of a multivar in a foreach callback

\n","comments":"

The callback will be called on each variable found

\n","group":"config"},"git_config_multivar_iterator_new":{"type":"function","file":"config.h","line":368,"lineto":368,"args":[{"name":"out","type":"git_config_iterator **","comment":"pointer to store the iterator"},{"name":"cfg","type":"const git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"regexp","type":"const char *","comment":"regular expression to filter which variables we're\n interested in. Use NULL to indicate all"}],"argline":"git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp","sig":"git_config_iterator **::const git_config *::const char *::const char *","return":{"type":"int","comment":null},"description":"

Get each value of a multivar

\n","comments":"","group":"config"},"git_config_next":{"type":"function","file":"config.h","line":380,"lineto":380,"args":[{"name":"entry","type":"git_config_entry **","comment":"pointer to store the entry"},{"name":"iter","type":"git_config_iterator *","comment":"the iterator"}],"argline":"git_config_entry **entry, git_config_iterator *iter","sig":"git_config_entry **::git_config_iterator *","return":{"type":"int","comment":" 0 or an error code. GIT_ITEROVER if the iteration has completed"},"description":"

Return the current entry and advance the iterator

\n","comments":"

The pointers returned by this function are valid until the iterator\n is freed.

\n","group":"config"},"git_config_iterator_free":{"type":"function","file":"config.h","line":387,"lineto":387,"args":[{"name":"iter","type":"git_config_iterator *","comment":"the iterator to free"}],"argline":"git_config_iterator *iter","sig":"git_config_iterator *","return":{"type":"void","comment":null},"description":"

Free a config iterator

\n","comments":"","group":"config"},"git_config_set_int32":{"type":"function","file":"config.h","line":398,"lineto":398,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"int32_t","comment":"Integer value for the variable"}],"argline":"git_config *cfg, const char *name, int32_t value","sig":"git_config *::const char *::int32_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the value of an integer config variable in the config file\n with the highest level (usually the local one).

\n","comments":"","group":"config"},"git_config_set_int64":{"type":"function","file":"config.h","line":409,"lineto":409,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"int64_t","comment":"Long integer value for the variable"}],"argline":"git_config *cfg, const char *name, int64_t value","sig":"git_config *::const char *::int64_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the value of a long integer config variable in the config file\n with the highest level (usually the local one).

\n","comments":"","group":"config"},"git_config_set_bool":{"type":"function","file":"config.h","line":420,"lineto":420,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"int","comment":"the value to store"}],"argline":"git_config *cfg, const char *name, int value","sig":"git_config *::const char *::int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the value of a boolean config variable in the config file\n with the highest level (usually the local one).

\n","comments":"","group":"config"},"git_config_set_string":{"type":"function","file":"config.h","line":434,"lineto":434,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"const char *","comment":"the string to store."}],"argline":"git_config *cfg, const char *name, const char *value","sig":"git_config *::const char *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the value of a string config variable in the config file\n with the highest level (usually the local one).

\n","comments":"

A copy of the string is made and the user is free to use it\n afterwards.

\n","group":"config"},"git_config_set_multivar":{"type":"function","file":"config.h","line":444,"lineto":444,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"regexp","type":"const char *","comment":"a regular expression to indicate which values to replace"},{"name":"value","type":"const char *","comment":"the new value."}],"argline":"git_config *cfg, const char *name, const char *regexp, const char *value","sig":"git_config *::const char *::const char *::const char *","return":{"type":"int","comment":null},"description":"

Set a multivar in the local config file.

\n","comments":"","group":"config"},"git_config_delete_entry":{"type":"function","file":"config.h","line":453,"lineto":453,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration"},{"name":"name","type":"const char *","comment":"the variable to delete"}],"argline":"git_config *cfg, const char *name","sig":"git_config *::const char *","return":{"type":"int","comment":null},"description":"

Delete a config variable from the config file\n with the highest level (usually the local one).

\n","comments":"","group":"config"},"git_config_delete_multivar":{"type":"function","file":"config.h","line":464,"lineto":464,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variables"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"regexp","type":"const char *","comment":"a regular expression to indicate which values to delete"}],"argline":"git_config *cfg, const char *name, const char *regexp","sig":"git_config *::const char *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Deletes one or several entries from a multivar in the local config file.

\n","comments":"","group":"config"},"git_config_foreach":{"type":"function","file":"config.h","line":482,"lineto":485,"args":[{"name":"cfg","type":"const git_config *","comment":"where to get the variables from"},{"name":"callback","type":"git_config_foreach_cb","comment":"the function to call on each variable"},{"name":"payload","type":"void *","comment":"the data to pass to the callback"}],"argline":"const git_config *cfg, git_config_foreach_cb callback, void *payload","sig":"const git_config *::git_config_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Perform an operation on each config variable.

\n","comments":"

The callback receives the normalized name and value of each variable\n in the config backend, and the data pointer passed to this function.\n If the callback returns a non-zero value, the function stops iterating\n and returns that value to the caller.

\n\n

The pointers passed to the callback are only valid as long as the\n iteration is ongoing.

\n","group":"config"},"git_config_iterator_new":{"type":"function","file":"config.h","line":496,"lineto":496,"args":[{"name":"out","type":"git_config_iterator **","comment":"pointer to store the iterator"},{"name":"cfg","type":"const git_config *","comment":"where to ge the variables from"}],"argline":"git_config_iterator **out, const git_config *cfg","sig":"git_config_iterator **::const git_config *","return":{"type":"int","comment":null},"description":"

Iterate over all the config variables

\n","comments":"

Use git_config_next to advance the iteration and\n git_config_iterator_free when done.

\n","group":"config"},"git_config_iterator_glob_new":{"type":"function","file":"config.h","line":508,"lineto":508,"args":[{"name":"out","type":"git_config_iterator **","comment":"pointer to store the iterator"},{"name":"cfg","type":"const git_config *","comment":"where to ge the variables from"},{"name":"regexp","type":"const char *","comment":"regular expression to match the names"}],"argline":"git_config_iterator **out, const git_config *cfg, const char *regexp","sig":"git_config_iterator **::const git_config *::const char *","return":{"type":"int","comment":null},"description":"

Iterate over all the config variables whose name matches a pattern

\n","comments":"

Use git_config_next to advance the iteration and\n git_config_iterator_free when done.

\n","group":"config"},"git_config_foreach_match":{"type":"function","file":"config.h","line":526,"lineto":530,"args":[{"name":"cfg","type":"const git_config *","comment":"where to get the variables from"},{"name":"regexp","type":"const char *","comment":"regular expression to match against config names"},{"name":"callback","type":"git_config_foreach_cb","comment":"the function to call on each variable"},{"name":"payload","type":"void *","comment":"the data to pass to the callback"}],"argline":"const git_config *cfg, const char *regexp, git_config_foreach_cb callback, void *payload","sig":"const git_config *::const char *::git_config_foreach_cb::void *","return":{"type":"int","comment":" 0 or the return value of the callback which didn't return 0"},"description":"

Perform an operation on each config variable matching a regular expression.

\n","comments":"

This behaviors like git_config_foreach with an additional filter of a\n regular expression that filters which config keys are passed to the\n callback.

\n\n

The pointers passed to the callback are only valid as long as the\n iteration is ongoing.

\n","group":"config"},"git_config_get_mapped":{"type":"function","file":"config.h","line":566,"lineto":571,"args":[{"name":"out","type":"int *","comment":"place to store the result of the mapping"},{"name":"cfg","type":"const git_config *","comment":"config file to get the variables from"},{"name":"name","type":"const char *","comment":"name of the config variable to lookup"},{"name":"maps","type":"const git_cvar_map *","comment":"array of `git_cvar_map` objects specifying the possible mappings"},{"name":"map_n","type":"size_t","comment":"number of mapping objects in `maps`"}],"argline":"int *out, const git_config *cfg, const char *name, const git_cvar_map *maps, size_t map_n","sig":"int *::const git_config *::const char *::const git_cvar_map *::size_t","return":{"type":"int","comment":" 0 on success, error code otherwise"},"description":"

Query the value of a config variable and return it mapped to\n an integer constant.

\n","comments":"

This is a helper method to easily map different possible values\n to a variable to integer constants that easily identify them.

\n\n

A mapping array looks as follows:

\n\n
git_cvar_map autocrlf_mapping[] = {\n    {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},\n    {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},\n    {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT},\n    {GIT_CVAR_STRING, "default", GIT_AUTO_CRLF_DEFAULT}};\n
\n\n

On any "false" value for the variable (e.g. "false", "FALSE", "no"), the\n mapping will store GIT_AUTO_CRLF_FALSE in the out parameter.

\n\n

The same thing applies for any "true" value such as "true", "yes" or "1", storing\n the GIT_AUTO_CRLF_TRUE variable.

\n\n

Otherwise, if the value matches the string "input" (with case insensitive comparison),\n the given constant will be stored in out, and likewise for "default".

\n\n

If not a single match can be made to store in out, an error code will be\n returned.

\n","group":"config"},"git_config_lookup_map_value":{"type":"function","file":"config.h","line":581,"lineto":585,"args":[{"name":"out","type":"int *","comment":"place to store the result of the parsing"},{"name":"maps","type":"const git_cvar_map *","comment":"array of `git_cvar_map` objects specifying the possible mappings"},{"name":"map_n","type":"size_t","comment":"number of mapping objects in `maps`"},{"name":"value","type":"const char *","comment":"value to parse"}],"argline":"int *out, const git_cvar_map *maps, size_t map_n, const char *value","sig":"int *::const git_cvar_map *::size_t::const char *","return":{"type":"int","comment":null},"description":"

Maps a string value to an integer constant

\n","comments":"","group":"config"},"git_config_parse_bool":{"type":"function","file":"config.h","line":597,"lineto":597,"args":[{"name":"out","type":"int *","comment":"place to store the result of the parsing"},{"name":"value","type":"const char *","comment":"value to parse"}],"argline":"int *out, const char *value","sig":"int *::const char *","return":{"type":"int","comment":null},"description":"

Parse a string value as a bool.

\n","comments":"

Valid values for true are: 'true', 'yes', 'on', 1 or any\n number different from 0\n Valid values for false are: 'false', 'no', 'off', 0

\n","group":"config"},"git_config_parse_int32":{"type":"function","file":"config.h","line":609,"lineto":609,"args":[{"name":"out","type":"int32_t *","comment":"place to store the result of the parsing"},{"name":"value","type":"const char *","comment":"value to parse"}],"argline":"int32_t *out, const char *value","sig":"int32_t *::const char *","return":{"type":"int","comment":null},"description":"

Parse a string value as an int32.

\n","comments":"

An optional value suffix of 'k', 'm', or 'g' will\n cause the value to be multiplied by 1024, 1048576,\n or 1073741824 prior to output.

\n","group":"config"},"git_config_parse_int64":{"type":"function","file":"config.h","line":621,"lineto":621,"args":[{"name":"out","type":"int64_t *","comment":"place to store the result of the parsing"},{"name":"value","type":"const char *","comment":"value to parse"}],"argline":"int64_t *out, const char *value","sig":"int64_t *::const char *","return":{"type":"int","comment":null},"description":"

Parse a string value as an int64.

\n","comments":"

An optional value suffix of 'k', 'm', or 'g' will\n cause the value to be multiplied by 1024, 1048576,\n or 1073741824 prior to output.

\n","group":"config"},"git_config_backend_foreach_match":{"type":"function","file":"config.h","line":636,"lineto":640,"args":[{"name":"backend","type":"git_config_backend *","comment":"where to get the variables from"},{"name":"regexp","type":"const char *","comment":"regular expression to match against config names (can be NULL)"},{"name":"callback","type":"git_config_foreach_cb","comment":"the function to call on each variable"},{"name":"payload","type":"void *","comment":"the data to pass to the callback"}],"argline":"git_config_backend *backend, const char *regexp, git_config_foreach_cb callback, void *payload","sig":"git_config_backend *::const char *::git_config_foreach_cb::void *","return":{"type":"int","comment":null},"description":"

Perform an operation on each config variable in given config backend\n matching a regular expression.

\n","comments":"

This behaviors like git_config_foreach_match except instead of all config\n entries it just enumerates through the given backend entry.

\n","group":"config"},"git_cred_userpass":{"type":"function","file":"cred_helpers.h","line":43,"lineto":48,"args":[{"name":"cred","type":"git_cred **","comment":"The newly created credential object."},{"name":"url","type":"const char *","comment":"The resource for which we are demanding a credential."},{"name":"user_from_url","type":"const char *","comment":"The username that was embedded in a \"user"},{"name":"allowed_types","type":"unsigned int","comment":"A bitmask stating which cred types are OK to return."},{"name":"payload","type":"void *","comment":"The payload provided when specifying this callback. (This is\n interpreted as a `git_cred_userpass_payload*`.)"}],"argline":"git_cred **cred, const char *url, const char *user_from_url, unsigned int allowed_types, void *payload","sig":"git_cred **::const char *::const char *::unsigned int::void *","return":{"type":"int","comment":null},"description":"

Stock callback usable as a git_cred_acquire_cb. This calls\n git_cred_userpass_plaintext_new unless the protocol has not specified\n GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type.

\n","comments":"","group":"cred"},"git_diff_init_options":{"type":"function","file":"diff.h","line":398,"lineto":400,"args":[{"name":"opts","type":"git_diff_options *","comment":"The `git_diff_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_DIFF_OPTIONS_VERSION`"}],"argline":"git_diff_options *opts, unsigned int version","sig":"git_diff_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_diff_options with default values. Equivalent to\n creating an instance with GIT_DIFF_OPTIONS_INIT.

\n","comments":"","group":"diff"},"git_diff_find_init_options":{"type":"function","file":"diff.h","line":638,"lineto":640,"args":[{"name":"opts","type":"git_diff_find_options *","comment":"The `git_diff_find_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_DIFF_FIND_OPTIONS_VERSION`"}],"argline":"git_diff_find_options *opts, unsigned int version","sig":"git_diff_find_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_diff_find_options with default values. Equivalent to\n creating an instance with GIT_DIFF_FIND_OPTIONS_INIT.

\n","comments":"","group":"diff"},"git_diff_free":{"type":"function","file":"diff.h","line":654,"lineto":654,"args":[{"name":"diff","type":"git_diff *","comment":"The previously created diff; cannot be used after free."}],"argline":"git_diff *diff","sig":"git_diff *","return":{"type":"void","comment":null},"description":"

Deallocate a diff.

\n","comments":"","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_free-2"],"log.c":["ex/v0.21.2/log.html#git_diff_free-24","ex/v0.21.2/log.html#git_diff_free-25"]}},"git_diff_tree_to_tree":{"type":"function","file":"diff.h","line":672,"lineto":677,"args":[{"name":"diff","type":"git_diff **","comment":"Output pointer to a git_diff pointer to be allocated."},{"name":"repo","type":"git_repository *","comment":"The repository containing the trees."},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from, or NULL for empty tree."},{"name":"new_tree","type":"git_tree *","comment":"A git_tree object to diff to, or NULL for empty tree."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults."}],"argline":"git_diff **diff, git_repository *repo, git_tree *old_tree, git_tree *new_tree, const git_diff_options *opts","sig":"git_diff **::git_repository *::git_tree *::git_tree *::const git_diff_options *","return":{"type":"int","comment":null},"description":"

Create a diff with the difference between two tree objects.

\n","comments":"

This is equivalent to git diff \n<old\n-tree> \n<new\n-tree>

\n\n

The first tree will be used for the "old_file" side of the delta and the\n second tree will be used for the "new_file" side of the delta. You can\n pass NULL to indicate an empty tree, although it is an error to pass\n NULL for both the old_tree and new_tree.

\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_tree_to_tree-3"],"log.c":["ex/v0.21.2/log.html#git_diff_tree_to_tree-26","ex/v0.21.2/log.html#git_diff_tree_to_tree-27"]}},"git_diff_tree_to_index":{"type":"function","file":"diff.h","line":698,"lineto":703,"args":[{"name":"diff","type":"git_diff **","comment":"Output pointer to a git_diff pointer to be allocated."},{"name":"repo","type":"git_repository *","comment":"The repository containing the tree and index."},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from, or NULL for empty tree."},{"name":"index","type":"git_index *","comment":"The index to diff with; repo index used if NULL."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults."}],"argline":"git_diff **diff, git_repository *repo, git_tree *old_tree, git_index *index, const git_diff_options *opts","sig":"git_diff **::git_repository *::git_tree *::git_index *::const git_diff_options *","return":{"type":"int","comment":null},"description":"

Create a diff between a tree and repository index.

\n","comments":"

This is equivalent to `git diff --cached \n<treeish

\n\n
\n

or if you pass\n the HEAD tree, then likegit diff --cached`.

\n
\n\n

The tree you pass will be used for the "old_file" side of the delta, and\n the index will be used for the "new_file" side of the delta.

\n\n

If you pass NULL for the index, then the existing index of the repo\n will be used. In this case, the index will be refreshed from disk\n (if it has changed) before the diff is generated.

\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_tree_to_index-4"]}},"git_diff_index_to_workdir":{"type":"function","file":"diff.h","line":725,"lineto":729,"args":[{"name":"diff","type":"git_diff **","comment":"Output pointer to a git_diff pointer to be allocated."},{"name":"repo","type":"git_repository *","comment":"The repository."},{"name":"index","type":"git_index *","comment":"The index to diff from; repo index used if NULL."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults."}],"argline":"git_diff **diff, git_repository *repo, git_index *index, const git_diff_options *opts","sig":"git_diff **::git_repository *::git_index *::const git_diff_options *","return":{"type":"int","comment":null},"description":"

Create a diff between the repository index and the workdir directory.

\n","comments":"

This matches the git diff command. See the note below on\n git_diff_tree_to_workdir for a discussion of the difference between\n git diff and git diff HEAD and how to emulate a `git diff \n<treeish

\n\n
\n

`\n using libgit2.

\n
\n\n

The index will be used for the "old_file" side of the delta, and the\n working directory will be used for the "new_file" side of the delta.

\n\n

If you pass NULL for the index, then the existing index of the repo\n will be used. In this case, the index will be refreshed from disk\n (if it has changed) before the diff is generated.

\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_index_to_workdir-5"]}},"git_diff_tree_to_workdir":{"type":"function","file":"diff.h","line":754,"lineto":758,"args":[{"name":"diff","type":"git_diff **","comment":"A pointer to a git_diff pointer that will be allocated."},{"name":"repo","type":"git_repository *","comment":"The repository containing the tree."},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from, or NULL for empty tree."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults."}],"argline":"git_diff **diff, git_repository *repo, git_tree *old_tree, const git_diff_options *opts","sig":"git_diff **::git_repository *::git_tree *::const git_diff_options *","return":{"type":"int","comment":null},"description":"

Create a diff between a tree and the working directory.

\n","comments":"

The tree you provide will be used for the "old_file" side of the delta,\n and the working directory will be used for the "new_file" side.

\n\n

This is not the same as `git diff \n<treeish

\n\n
\n

orgit diff-index

\n
\n\n

<treeish

\n\n
\n

. Those commands use information from the index, whereas this\n function strictly returns the differences between the tree and the files\n in the working directory, regardless of the state of the index. Use\ngit_diff_tree_to_workdir_with_index` to emulate those commands.

\n
\n\n

To see difference between this and git_diff_tree_to_workdir_with_index,\n consider the example of a staged file deletion where the file has then\n been put back into the working dir and further modified. The\n tree-to-workdir diff for that file is 'modified', but git diff would\n show status 'deleted' since there is a staged delete.

\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_tree_to_workdir-6"]}},"git_diff_tree_to_workdir_with_index":{"type":"function","file":"diff.h","line":773,"lineto":777,"args":[{"name":"diff","type":"git_diff **","comment":"A pointer to a git_diff pointer that will be allocated."},{"name":"repo","type":"git_repository *","comment":"The repository containing the tree."},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from, or NULL for empty tree."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults."}],"argline":"git_diff **diff, git_repository *repo, git_tree *old_tree, const git_diff_options *opts","sig":"git_diff **::git_repository *::git_tree *::const git_diff_options *","return":{"type":"int","comment":null},"description":"

Create a diff between a tree and the working directory using index data\n to account for staged deletes, tracked files, etc.

\n","comments":"

This emulates `git diff \n<tree

\n\n
\n

` by diffing the tree to the index and\n the index to the working directory and blending the results into a\n single diff that includes staged deleted, etc.

\n
\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_tree_to_workdir_with_index-7"]}},"git_diff_merge":{"type":"function","file":"diff.h","line":792,"lineto":794,"args":[{"name":"onto","type":"git_diff *","comment":"Diff to merge into."},{"name":"from","type":"const git_diff *","comment":"Diff to merge."}],"argline":"git_diff *onto, const git_diff *from","sig":"git_diff *::const git_diff *","return":{"type":"int","comment":null},"description":"

Merge one diff into another.

\n","comments":"

This merges items from the "from" list into the "onto" list. The\n resulting diff will have all items that appear in either list.\n If an item appears in both lists, then it will be "merged" to appear\n as if the old version was from the "onto" list and the new version\n is from the "from" list (with the exception that if the item has a\n pending DELETE in the middle, then it will show as deleted).

\n","group":"diff"},"git_diff_find_similar":{"type":"function","file":"diff.h","line":808,"lineto":810,"args":[{"name":"diff","type":"git_diff *","comment":"diff to run detection algorithms on"},{"name":"options","type":"const git_diff_find_options *","comment":"Control how detection should be run, NULL for defaults"}],"argline":"git_diff *diff, const git_diff_find_options *options","sig":"git_diff *::const git_diff_find_options *","return":{"type":"int","comment":" 0 on success, -1 on failure"},"description":"

Transform a diff marking file renames, copies, etc.

\n","comments":"

This modifies a diff in place, replacing old entries that look\n like renames or copies with new entries reflecting those changes.\n This also will, if requested, break modified files into add/remove\n pairs if the amount of change is above a threshold.

\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_find_similar-8"]}},"git_diff_num_deltas":{"type":"function","file":"diff.h","line":828,"lineto":828,"args":[{"name":"diff","type":"const git_diff *","comment":"A git_diff generated by one of the above functions"}],"argline":"const git_diff *diff","sig":"const git_diff *","return":{"type":"size_t","comment":" Count of number of deltas in the list"},"description":"

Query how many diff records are there in a diff.

\n","comments":"","group":"diff","examples":{"log.c":["ex/v0.21.2/log.html#git_diff_num_deltas-28"]}},"git_diff_num_deltas_of_type":{"type":"function","file":"diff.h","line":841,"lineto":842,"args":[{"name":"diff","type":"const git_diff *","comment":"A git_diff generated by one of the above functions"},{"name":"type","type":"git_delta_t","comment":"A git_delta_t value to filter the count"}],"argline":"const git_diff *diff, git_delta_t type","sig":"const git_diff *::git_delta_t","return":{"type":"size_t","comment":" Count of number of deltas matching delta_t type"},"description":"

Query how many diff deltas are there in a diff filtered by type.

\n","comments":"

This works just like git_diff_entrycount() with an extra parameter\n that is a git_delta_t and returns just the count of how many deltas\n match that particular type.

\n","group":"diff"},"git_diff_get_delta":{"type":"function","file":"diff.h","line":861,"lineto":862,"args":[{"name":"diff","type":"const git_diff *","comment":"Diff list object"},{"name":"idx","type":"size_t","comment":"Index into diff list"}],"argline":"const git_diff *diff, size_t idx","sig":"const git_diff *::size_t","return":{"type":"const git_diff_delta *","comment":" Pointer to git_diff_delta (or NULL if `idx` out of range)"},"description":"

Return the diff delta for an entry in the diff list.

\n","comments":"

The git_delta pointer points to internal data and you do not have\n to release it when you are done with it. It will go away when the\n git_diff (or any associated git_patch) goes away.

\n\n

Note that the flags on the delta related to whether it has binary\n content or not may not be set if there are no attributes set for the\n file and there has been no reason to load the file data at this point.\n For now, if you need those flags to be up to date, your only option is\n to either use git_diff_foreach or create a git_patch.

\n","group":"diff"},"git_diff_is_sorted_icase":{"type":"function","file":"diff.h","line":870,"lineto":870,"args":[{"name":"diff","type":"const git_diff *","comment":"diff to check"}],"argline":"const git_diff *diff","sig":"const git_diff *","return":{"type":"int","comment":" 0 if case sensitive, 1 if case is ignored"},"description":"

Check if deltas are sorted case sensitively or insensitively.

\n","comments":"","group":"diff"},"git_diff_foreach":{"type":"function","file":"diff.h","line":897,"lineto":902,"args":[{"name":"diff","type":"git_diff *","comment":"A git_diff generated by one of the above functions."},{"name":"file_cb","type":"git_diff_file_cb","comment":"Callback function to make per file in the diff."},{"name":"hunk_cb","type":"git_diff_hunk_cb","comment":"Optional callback to make per hunk of text diff. This\n callback is called to describe a range of lines in the\n diff. It will not be issued for binary files."},{"name":"line_cb","type":"git_diff_line_cb","comment":"Optional callback to make per line of diff text. This\n same callback will be made for context lines, added, and\n removed lines, and even for a deleted trailing newline."},{"name":"payload","type":"void *","comment":"Reference pointer that will be passed to your callbacks."}],"argline":"git_diff *diff, git_diff_file_cb file_cb, git_diff_hunk_cb hunk_cb, git_diff_line_cb line_cb, void *payload","sig":"git_diff *::git_diff_file_cb::git_diff_hunk_cb::git_diff_line_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Loop over all deltas in a diff issuing callbacks.

\n","comments":"

This will iterate through all of the files described in a diff. You\n should provide a file callback to learn about each file.

\n\n

The "hunk" and "line" callbacks are optional, and the text diff of the\n files will only be calculated if they are not NULL. Of course, these\n callbacks will not be invoked for binary files on the diff or for\n files whose only changed is a file mode change.

\n\n

Returning a non-zero value from any of the callbacks will terminate\n the iteration and return the value to the user.

\n","group":"diff"},"git_diff_status_char":{"type":"function","file":"diff.h","line":915,"lineto":915,"args":[{"name":"status","type":"git_delta_t","comment":"The git_delta_t value to look up"}],"argline":"git_delta_t status","sig":"git_delta_t","return":{"type":"char","comment":" The single character label for that code"},"description":"

Look up the single character abbreviation for a delta status code.

\n","comments":"

When you run git diff --name-status it uses single letter codes in\n the output such as 'A' for added, 'D' for deleted, 'M' for modified,\n etc. This function converts a git_delta_t value into these letters for\n your own purposes. GIT_DELTA_UNTRACKED will return a space (i.e. ' ').

\n","group":"diff"},"git_diff_print":{"type":"function","file":"diff.h","line":940,"lineto":944,"args":[{"name":"diff","type":"git_diff *","comment":"A git_diff generated by one of the above functions."},{"name":"format","type":"git_diff_format_t","comment":"A git_diff_format_t value to pick the text format."},{"name":"print_cb","type":"git_diff_line_cb","comment":"Callback to make per line of diff text."},{"name":"payload","type":"void *","comment":"Reference pointer that will be passed to your callback."}],"argline":"git_diff *diff, git_diff_format_t format, git_diff_line_cb print_cb, void *payload","sig":"git_diff *::git_diff_format_t::git_diff_line_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Iterate over a diff generating formatted text output.

\n","comments":"

Returning a non-zero value from the callbacks will terminate the\n iteration and return the non-zero value to the caller.

\n","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_print-9"],"log.c":["ex/v0.21.2/log.html#git_diff_print-29"]}},"git_diff_blobs":{"type":"function","file":"diff.h","line":980,"lineto":989,"args":[{"name":"old_blob","type":"const git_blob *","comment":"Blob for old side of diff, or NULL for empty blob"},{"name":"old_as_path","type":"const char *","comment":"Treat old blob as if it had this filename; can be NULL"},{"name":"new_blob","type":"const git_blob *","comment":"Blob for new side of diff, or NULL for empty blob"},{"name":"new_as_path","type":"const char *","comment":"Treat new blob as if it had this filename; can be NULL"},{"name":"options","type":"const git_diff_options *","comment":"Options for diff, or NULL for default options"},{"name":"file_cb","type":"git_diff_file_cb","comment":"Callback for \"file\"; made once if there is a diff; can be NULL"},{"name":"hunk_cb","type":"git_diff_hunk_cb","comment":"Callback for each hunk in diff; can be NULL"},{"name":"line_cb","type":"git_diff_line_cb","comment":"Callback for each line in diff; can be NULL"},{"name":"payload","type":"void *","comment":"Payload passed to each callback function"}],"argline":"const git_blob *old_blob, const char *old_as_path, const git_blob *new_blob, const char *new_as_path, const git_diff_options *options, git_diff_file_cb file_cb, git_diff_hunk_cb hunk_cb, git_diff_line_cb line_cb, void *payload","sig":"const git_blob *::const char *::const git_blob *::const char *::const git_diff_options *::git_diff_file_cb::git_diff_hunk_cb::git_diff_line_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Directly run a diff on two blobs.

\n","comments":"

Compared to a file, a blob lacks some contextual information. As such,\n the git_diff_file given to the callback will have some fake data; i.e.\n mode will be 0 and path will be NULL.

\n\n

NULL is allowed for either old_blob or new_blob and will be treated\n as an empty blob, with the oid set to NULL in the git_diff_file data.\n Passing NULL for both blobs is a noop; no callbacks will be made at all.

\n\n

We do run a binary content check on the blob content and if either blob\n looks like binary data, the git_diff_delta binary attribute will be set\n to 1 and no call to the hunk_cb nor line_cb will be made (unless you pass\n GIT_DIFF_FORCE_TEXT of course).

\n","group":"diff"},"git_diff_blob_to_buffer":{"type":"function","file":"diff.h","line":1015,"lineto":1025,"args":[{"name":"old_blob","type":"const git_blob *","comment":"Blob for old side of diff, or NULL for empty blob"},{"name":"old_as_path","type":"const char *","comment":"Treat old blob as if it had this filename; can be NULL"},{"name":"buffer","type":"const char *","comment":"Raw data for new side of diff, or NULL for empty"},{"name":"buffer_len","type":"size_t","comment":"Length of raw data for new side of diff"},{"name":"buffer_as_path","type":"const char *","comment":"Treat buffer as if it had this filename; can be NULL"},{"name":"options","type":"const git_diff_options *","comment":"Options for diff, or NULL for default options"},{"name":"file_cb","type":"git_diff_file_cb","comment":"Callback for \"file\"; made once if there is a diff; can be NULL"},{"name":"hunk_cb","type":"git_diff_hunk_cb","comment":"Callback for each hunk in diff; can be NULL"},{"name":"line_cb","type":"git_diff_line_cb","comment":"Callback for each line in diff; can be NULL"},{"name":"payload","type":"void *","comment":"Payload passed to each callback function"}],"argline":"const git_blob *old_blob, const char *old_as_path, const char *buffer, size_t buffer_len, const char *buffer_as_path, const git_diff_options *options, git_diff_file_cb file_cb, git_diff_hunk_cb hunk_cb, git_diff_line_cb line_cb, void *payload","sig":"const git_blob *::const char *::const char *::size_t::const char *::const git_diff_options *::git_diff_file_cb::git_diff_hunk_cb::git_diff_line_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Directly run a diff between a blob and a buffer.

\n","comments":"

As with git_diff_blobs, comparing a blob and buffer lacks some context,\n so the git_diff_file parameters to the callbacks will be faked a la the\n rules for git_diff_blobs().

\n\n

Passing NULL for old_blob will be treated as an empty blob (i.e. the\n file_cb will be invoked with GIT_DELTA_ADDED and the diff will be the\n entire content of the buffer added). Passing NULL to the buffer will do\n the reverse, with GIT_DELTA_REMOVED and blob content removed.

\n","group":"diff"},"git_diff_buffers":{"type":"function","file":"diff.h","line":1047,"lineto":1058,"args":[{"name":"old_buffer","type":"const void *","comment":"Raw data for old side of diff, or NULL for empty"},{"name":"old_len","type":"size_t","comment":"Length of the raw data for old side of the diff"},{"name":"old_as_path","type":"const char *","comment":"Treat old buffer as if it had this filename; can be NULL"},{"name":"new_buffer","type":"const void *","comment":"Raw data for new side of diff, or NULL for empty"},{"name":"new_len","type":"size_t","comment":"Length of raw data for new side of diff"},{"name":"new_as_path","type":"const char *","comment":"Treat buffer as if it had this filename; can be NULL"},{"name":"options","type":"const git_diff_options *","comment":"Options for diff, or NULL for default options"},{"name":"file_cb","type":"git_diff_file_cb","comment":"Callback for \"file\"; made once if there is a diff; can be NULL"},{"name":"hunk_cb","type":"git_diff_hunk_cb","comment":"Callback for each hunk in diff; can be NULL"},{"name":"line_cb","type":"git_diff_line_cb","comment":"Callback for each line in diff; can be NULL"},{"name":"payload","type":"void *","comment":"Payload passed to each callback function"}],"argline":"const void *old_buffer, size_t old_len, const char *old_as_path, const void *new_buffer, size_t new_len, const char *new_as_path, const git_diff_options *options, git_diff_file_cb file_cb, git_diff_hunk_cb hunk_cb, git_diff_line_cb line_cb, void *payload","sig":"const void *::size_t::const char *::const void *::size_t::const char *::const git_diff_options *::git_diff_file_cb::git_diff_hunk_cb::git_diff_line_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Directly run a diff between two buffers.

\n","comments":"

Even more than with git_diff_blobs, comparing two buffer lacks\n context, so the git_diff_file parameters to the callbacks will be\n faked a la the rules for git_diff_blobs().

\n","group":"diff"},"git_diff_get_stats":{"type":"function","file":"diff.h","line":1094,"lineto":1096,"args":[{"name":"out","type":"git_diff_stats **","comment":"Structure containg the diff statistics."},{"name":"diff","type":"git_diff *","comment":"A git_diff generated by one of the above functions."}],"argline":"git_diff_stats **out, git_diff *diff","sig":"git_diff_stats **::git_diff *","return":{"type":"int","comment":" 0 on success; non-zero on error"},"description":"

Accumlate diff statistics for all patches.

\n","comments":"","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_get_stats-10"]}},"git_diff_stats_files_changed":{"type":"function","file":"diff.h","line":1104,"lineto":1105,"args":[{"name":"stats","type":"const git_diff_stats *","comment":"A `git_diff_stats` generated by one of the above functions."}],"argline":"const git_diff_stats *stats","sig":"const git_diff_stats *","return":{"type":"size_t","comment":" total number of files changed in the diff"},"description":"

Get the total number of files changed in a diff

\n","comments":"","group":"diff"},"git_diff_stats_insertions":{"type":"function","file":"diff.h","line":1113,"lineto":1114,"args":[{"name":"stats","type":"const git_diff_stats *","comment":"A `git_diff_stats` generated by one of the above functions."}],"argline":"const git_diff_stats *stats","sig":"const git_diff_stats *","return":{"type":"size_t","comment":" total number of insertions in the diff"},"description":"

Get the total number of insertions in a diff

\n","comments":"","group":"diff"},"git_diff_stats_deletions":{"type":"function","file":"diff.h","line":1122,"lineto":1123,"args":[{"name":"stats","type":"const git_diff_stats *","comment":"A `git_diff_stats` generated by one of the above functions."}],"argline":"const git_diff_stats *stats","sig":"const git_diff_stats *","return":{"type":"size_t","comment":" total number of deletions in the diff"},"description":"

Get the total number of deletions in a diff

\n","comments":"","group":"diff"},"git_diff_stats_to_buf":{"type":"function","file":"diff.h","line":1134,"lineto":1138,"args":[{"name":"out","type":"git_buf *","comment":"buffer to store the formatted diff statistics in."},{"name":"stats","type":"const git_diff_stats *","comment":"A `git_diff_stats` generated by one of the above functions."},{"name":"format","type":"git_diff_stats_format_t","comment":"Formatting option."},{"name":"width","type":"size_t","comment":"Target width for output (only affects GIT_DIFF_STATS_FULL)"}],"argline":"git_buf *out, const git_diff_stats *stats, git_diff_stats_format_t format, size_t width","sig":"git_buf *::const git_diff_stats *::git_diff_stats_format_t::size_t","return":{"type":"int","comment":" 0 on success; non-zero on error"},"description":"

Print diff statistics to a git_buf.

\n","comments":"","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_stats_to_buf-11"]}},"git_diff_stats_free":{"type":"function","file":"diff.h","line":1146,"lineto":1146,"args":[{"name":"stats","type":"git_diff_stats *","comment":"The previously created statistics object;\n cannot be used after free."}],"argline":"git_diff_stats *stats","sig":"git_diff_stats *","return":{"type":"void","comment":null},"description":"

Deallocate a git_diff_stats.

\n","comments":"","group":"diff","examples":{"diff.c":["ex/v0.21.2/diff.html#git_diff_stats_free-12"]}},"git_diff_format_email":{"type":"function","file":"diff.h","line":1195,"lineto":1198,"args":[{"name":"out","type":"git_buf *","comment":"buffer to store the e-mail patch in"},{"name":"diff","type":"git_diff *","comment":"containing the commit"},{"name":"opts","type":"const git_diff_format_email_options *","comment":"structure with options to influence content and formatting."}],"argline":"git_buf *out, git_diff *diff, const git_diff_format_email_options *opts","sig":"git_buf *::git_diff *::const git_diff_format_email_options *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an e-mail ready patch from a diff.

\n","comments":"","group":"diff"},"git_diff_commit_as_email":{"type":"function","file":"diff.h","line":1214,"lineto":1221,"args":[{"name":"out","type":"git_buf *","comment":"buffer to store the e-mail patch in"},{"name":"repo","type":"git_repository *","comment":"containing the commit"},{"name":"commit","type":"git_commit *","comment":"pointer to up commit"},{"name":"patch_no","type":"size_t","comment":"patch number of the commit"},{"name":"total_patches","type":"size_t","comment":"total number of patches in the patch set"},{"name":"flags","type":"git_diff_format_email_flags_t","comment":"determines the formatting of the e-mail"},{"name":"diff_opts","type":"const git_diff_options *","comment":"structure with options to influence diff or NULL for defaults."}],"argline":"git_buf *out, git_repository *repo, git_commit *commit, size_t patch_no, size_t total_patches, git_diff_format_email_flags_t flags, const git_diff_options *diff_opts","sig":"git_buf *::git_repository *::git_commit *::size_t::size_t::git_diff_format_email_flags_t::const git_diff_options *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an e-mail ready patch for a commit.

\n","comments":"

Does not support creating patches for merge commits (yet).

\n","group":"diff"},"git_diff_format_email_init_options":{"type":"function","file":"diff.h","line":1232,"lineto":1234,"args":[{"name":"opts","type":"git_diff_format_email_options *","comment":"The `git_diff_format_email_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`"}],"argline":"git_diff_format_email_options *opts, unsigned int version","sig":"git_diff_format_email_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_diff_format_email_options with default values.

\n","comments":"

Equivalent to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.

\n","group":"diff"},"giterr_last":{"type":"function","file":"errors.h","line":98,"lineto":98,"args":[],"argline":"","sig":"","return":{"type":"const git_error *","comment":" A git_error object."},"description":"

Return the last git_error object that was generated for the\n current thread or NULL if no error has occurred.

\n","comments":"","group":"giterr","examples":{"general.c":["ex/v0.21.2/general.html#giterr_last-27"],"network/clone.c":["ex/v0.21.2/network/clone.html#giterr_last-2"],"network/git2.c":["ex/v0.21.2/network/git2.html#giterr_last-1","ex/v0.21.2/network/git2.html#giterr_last-2"]}},"giterr_clear":{"type":"function","file":"errors.h","line":103,"lineto":103,"args":[],"argline":"","sig":"","return":{"type":"void","comment":null},"description":"

Clear the last library error that occurred for this thread.

\n","comments":"","group":"giterr"},"giterr_detach":{"type":"function","file":"errors.h","line":115,"lineto":115,"args":[{"name":"cpy","type":"git_error *","comment":null}],"argline":"git_error *cpy","sig":"git_error *","return":{"type":"int","comment":null},"description":"

Get the last error data and clear it.

\n","comments":"

This copies the last error into the given git_error struct\n and returns 0 if the copy was successful, leaving the error\n cleared as if giterr_clear had been called.

\n\n

If there was no existing error in the library, -1 will be returned\n and the contents of cpy will be left unmodified.

\n","group":"giterr"},"giterr_set_str":{"type":"function","file":"errors.h","line":138,"lineto":138,"args":[{"name":"error_class","type":"int","comment":"One of the `git_error_t` enum above describing the\n general subsystem that is responsible for the error."},{"name":"string","type":"const char *","comment":"The formatted error message to keep"}],"argline":"int error_class, const char *string","sig":"int::const char *","return":{"type":"void","comment":null},"description":"

Set the error message string for this thread.

\n","comments":"

This function is public so that custom ODB backends and the like can\n relay an error message through libgit2. Most regular users of libgit2\n will never need to call this function -- actually, calling it in most\n circumstances (for example, calling from within a callback function)\n will just end up having the value overwritten by libgit2 internals.

\n\n

This error message is stored in thread-local storage and only applies\n to the particular thread that this libgit2 call is made from.

\n\n

NOTE: Passing the error_class as GITERR_OS has a special behavior: we\n attempt to append the system default error message for the last OS error\n that occurred and then clear the last error. The specific implementation\n of looking up and clearing this last OS error will vary by platform.

\n","group":"giterr"},"giterr_set_oom":{"type":"function","file":"errors.h","line":149,"lineto":149,"args":[],"argline":"","sig":"","return":{"type":"void","comment":null},"description":"

Set the error message to a special value for memory allocation failure.

\n","comments":"

The normal giterr_set_str() function attempts to strdup() the string\n that is passed in. This is not a good idea when the error in question\n is a memory allocation failure. That circumstance has a special setter\n function that sets the error string to a known and statically allocated\n internal value.

\n","group":"giterr"},"git_filter_list_load":{"type":"function","file":"filter.h","line":87,"lineto":93,"args":[{"name":"filters","type":"git_filter_list **","comment":"Output newly created git_filter_list (or NULL)"},{"name":"repo","type":"git_repository *","comment":"Repository object that contains `path`"},{"name":"blob","type":"git_blob *","comment":"The blob to which the filter will be applied (if known)"},{"name":"path","type":"const char *","comment":"Relative path of the file to be filtered"},{"name":"mode","type":"git_filter_mode_t","comment":"Filtering direction (WT->ODB or ODB->WT)"},{"name":"options","type":"uint32_t","comment":"Combination of `git_filter_opt_t` flags"}],"argline":"git_filter_list **filters, git_repository *repo, git_blob *blob, const char *path, git_filter_mode_t mode, uint32_t options","sig":"git_filter_list **::git_repository *::git_blob *::const char *::git_filter_mode_t::uint32_t","return":{"type":"int","comment":" 0 on success (which could still return NULL if no filters are\n needed for the requested file), \n<\n0 on error"},"description":"

Load the filter list for a given path.

\n","comments":"

This will return 0 (success) but set the output git_filter_list to NULL\n if no filters are requested for the given file.

\n","group":"filter"},"git_filter_list_apply_to_data":{"type":"function","file":"filter.h","line":115,"lineto":118,"args":[{"name":"out","type":"git_buf *","comment":"Buffer to store the result of the filtering"},{"name":"filters","type":"git_filter_list *","comment":"A loaded git_filter_list (or NULL)"},{"name":"in","type":"git_buf *","comment":"Buffer containing the data to filter"}],"argline":"git_buf *out, git_filter_list *filters, git_buf *in","sig":"git_buf *::git_filter_list *::git_buf *","return":{"type":"int","comment":" 0 on success, an error code otherwise"},"description":"

Apply filter list to a data buffer.

\n","comments":"

See git2/buffer.h for background on git_buf objects.

\n\n

If the in buffer holds data allocated by libgit2 (i.e. in->asize is\n not zero), then it will be overwritten when applying the filters. If\n not, then it will be left untouched.

\n\n

If there are no filters to apply (or filters is NULL), then the out\n buffer will reference the in buffer data (with asize set to zero)\n instead of allocating data. This keeps allocations to a minimum, but\n it means you have to be careful about freeing the in data since out\n may be pointing to it!

\n","group":"filter"},"git_filter_list_apply_to_file":{"type":"function","file":"filter.h","line":123,"lineto":127,"args":[{"name":"out","type":"git_buf *","comment":null},{"name":"filters","type":"git_filter_list *","comment":null},{"name":"repo","type":"git_repository *","comment":null},{"name":"path","type":"const char *","comment":null}],"argline":"git_buf *out, git_filter_list *filters, git_repository *repo, const char *path","sig":"git_buf *::git_filter_list *::git_repository *::const char *","return":{"type":"int","comment":null},"description":"

Apply filter list to the contents of a file on disk

\n","comments":"","group":"filter"},"git_filter_list_apply_to_blob":{"type":"function","file":"filter.h","line":132,"lineto":135,"args":[{"name":"out","type":"git_buf *","comment":null},{"name":"filters","type":"git_filter_list *","comment":null},{"name":"blob","type":"git_blob *","comment":null}],"argline":"git_buf *out, git_filter_list *filters, git_blob *blob","sig":"git_buf *::git_filter_list *::git_blob *","return":{"type":"int","comment":null},"description":"

Apply filter list to the contents of a blob

\n","comments":"","group":"filter"},"git_filter_list_free":{"type":"function","file":"filter.h","line":142,"lineto":142,"args":[{"name":"filters","type":"git_filter_list *","comment":"A git_filter_list created by `git_filter_list_load`"}],"argline":"git_filter_list *filters","sig":"git_filter_list *","return":{"type":"void","comment":null},"description":"

Free a git_filter_list

\n","comments":"","group":"filter"},"git_graph_ahead_behind":{"type":"function","file":"graph.h","line":37,"lineto":37,"args":[{"name":"ahead","type":"size_t *","comment":"number of unique from commits in `upstream`"},{"name":"behind","type":"size_t *","comment":"number of unique from commits in `local`"},{"name":"repo","type":"git_repository *","comment":"the repository where the commits exist"},{"name":"local","type":"const git_oid *","comment":"the commit for local"},{"name":"upstream","type":"const git_oid *","comment":"the commit for upstream"}],"argline":"size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream","sig":"size_t *::size_t *::git_repository *::const git_oid *::const git_oid *","return":{"type":"int","comment":null},"description":"

Count the number of unique commits between two commit objects

\n","comments":"

There is no need for branches containing the commits to have any\n upstream relationship, but it helps to think of one as a branch and\n the other as its upstream, the ahead and behind values will be\n what git would report for the branches.

\n","group":"graph"},"git_graph_descendant_of":{"type":"function","file":"graph.h","line":48,"lineto":51,"args":[{"name":"repo","type":"git_repository *","comment":null},{"name":"commit","type":"const git_oid *","comment":"a previously loaded commit."},{"name":"ancestor","type":"const git_oid *","comment":"a potential ancestor commit."}],"argline":"git_repository *repo, const git_oid *commit, const git_oid *ancestor","sig":"git_repository *::const git_oid *::const git_oid *","return":{"type":"int","comment":" 1 if the given commit is a descendant of the potential ancestor,\n 0 if not, error code otherwise."},"description":"

Determine if a commit is the descendant of another commit.

\n","comments":"","group":"graph"},"git_ignore_add_rule":{"type":"function","file":"ignore.h","line":37,"lineto":39,"args":[{"name":"repo","type":"git_repository *","comment":"The repository to add ignore rules to."},{"name":"rules","type":"const char *","comment":"Text of rules, a la the contents of a .gitignore file.\n It is okay to have multiple rules in the text; if so,\n each rule should be terminated with a newline."}],"argline":"git_repository *repo, const char *rules","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 on success"},"description":"

Add ignore rules for a repository.

\n","comments":"

Excludesfile rules (i.e. .gitignore rules) are generally read from\n .gitignore files in the repository tree or from a shared system file\n only if a "core.excludesfile" config value is set. The library also\n keeps a set of per-repository internal ignores that can be configured\n in-memory and will not persist. This function allows you to add to\n that internal rules list.

\n\n

Example usage:

\n\n
 error = git_ignore_add_rule(myrepo, "*.c\n
\n\n

/

\n\n

with space

\n\n

");

\n\n

This would add three rules to the ignores.

\n","group":"ignore"},"git_ignore_clear_internal_rules":{"type":"function","file":"ignore.h","line":52,"lineto":53,"args":[{"name":"repo","type":"git_repository *","comment":"The repository to remove ignore rules from."}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 0 on success"},"description":"

Clear ignore rules that were explicitly added.

\n","comments":"

Resets to the default internal ignore rules. This will not turn off\n rules in .gitignore files that actually exist in the filesystem.

\n\n

The default internal ignores ignore ".", ".." and ".git" entries.

\n","group":"ignore"},"git_ignore_path_is_ignored":{"type":"function","file":"ignore.h","line":71,"lineto":74,"args":[{"name":"ignored","type":"int *","comment":"boolean returning 0 if the file is not ignored, 1 if it is"},{"name":"repo","type":"git_repository *","comment":"a repository object"},{"name":"path","type":"const char *","comment":"the file to check ignores for, relative to the repo's workdir."}],"argline":"int *ignored, git_repository *repo, const char *path","sig":"int *::git_repository *::const char *","return":{"type":"int","comment":" 0 if ignore rules could be processed for the file (regardless\n of whether it exists or not), or an error \n<\n 0 if they could not."},"description":"

Test if the ignore rules apply to a given path.

\n","comments":"

This function checks the ignore rules to see if they would apply to the\n given file. This indicates if the file would be ignored regardless of\n whether the file is already in the index or committed to the repository.

\n\n

One way to think of this is if you were to do "git add ." on the\n directory containing the file, would it be added or not?

\n","group":"ignore"},"git_index_open":{"type":"function","file":"index.h","line":181,"lineto":181,"args":[{"name":"out","type":"git_index **","comment":"the pointer for the new index"},{"name":"index_path","type":"const char *","comment":"the path to the index file in disk"}],"argline":"git_index **out, const char *index_path","sig":"git_index **::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new bare Git index object as a memory representation\n of the Git index file in 'index_path', without a repository\n to back it.

\n","comments":"

Since there is no ODB or working directory behind this index,\n any Index methods which rely on these (e.g. index_add_bypath)\n will fail with the GIT_ERROR error code.

\n\n

If you need to access the index of an actual repository,\n use the git_repository_index wrapper.

\n\n

The index must be freed once it's no longer in use.

\n","group":"index"},"git_index_new":{"type":"function","file":"index.h","line":194,"lineto":194,"args":[{"name":"out","type":"git_index **","comment":"the pointer for the new index"}],"argline":"git_index **out","sig":"git_index **","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an in-memory index object.

\n","comments":"

This index object cannot be read/written to the filesystem,\n but may be used to perform in-memory index operations.

\n\n

The index must be freed once it's no longer in use.

\n","group":"index"},"git_index_free":{"type":"function","file":"index.h","line":201,"lineto":201,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"void","comment":null},"description":"

Free an existing index object.

\n","comments":"","group":"index","examples":{"general.c":["ex/v0.21.2/general.html#git_index_free-28"],"init.c":["ex/v0.21.2/init.html#git_index_free-2"]}},"git_index_owner":{"type":"function","file":"index.h","line":209,"lineto":209,"args":[{"name":"index","type":"const git_index *","comment":"The index"}],"argline":"const git_index *index","sig":"const git_index *","return":{"type":"git_repository *","comment":" A pointer to the repository"},"description":"

Get the repository this index relates to

\n","comments":"","group":"index"},"git_index_caps":{"type":"function","file":"index.h","line":217,"lineto":217,"args":[{"name":"index","type":"const git_index *","comment":"An existing index object"}],"argline":"const git_index *index","sig":"const git_index *","return":{"type":"int","comment":" A combination of GIT_INDEXCAP values"},"description":"

Read index capabilities flags.

\n","comments":"","group":"index"},"git_index_set_caps":{"type":"function","file":"index.h","line":230,"lineto":230,"args":[{"name":"index","type":"git_index *","comment":"An existing index object"},{"name":"caps","type":"int","comment":"A combination of GIT_INDEXCAP values"}],"argline":"git_index *index, int caps","sig":"git_index *::int","return":{"type":"int","comment":" 0 on success, -1 on failure"},"description":"

Set index capabilities flags.

\n","comments":"

If you pass GIT_INDEXCAP_FROM_OWNER for the caps, then the\n capabilities will be read from the config of the owner object,\n looking at core.ignorecase, core.filemode, core.symlinks.

\n","group":"index"},"git_index_read":{"type":"function","file":"index.h","line":249,"lineto":249,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"force","type":"int","comment":"if true, always reload, vs. only read if file has changed"}],"argline":"git_index *index, int force","sig":"git_index *::int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Update the contents of an existing index object in memory by reading\n from the hard disk.

\n","comments":"

If force is true, this performs a "hard" read that discards in-memory\n changes and always reloads the on-disk index data. If there is no\n on-disk version, the index will be cleared.

\n\n

If force is false, this does a "soft" read that reloads the index\n data from disk only if it has changed since the last time it was\n loaded. Purely in-memory index data will be untouched. Be aware: if\n there are changes on disk, unwritten in-memory changes are discarded.

\n","group":"index"},"git_index_write":{"type":"function","file":"index.h","line":258,"lineto":258,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Write an existing index object from memory back to disk\n using an atomic file lock.

\n","comments":"","group":"index"},"git_index_path":{"type":"function","file":"index.h","line":266,"lineto":266,"args":[{"name":"index","type":"const git_index *","comment":"an existing index object"}],"argline":"const git_index *index","sig":"const git_index *","return":{"type":"const char *","comment":" path to index file or NULL for in-memory index"},"description":"

Get the full path to the index file on disk.

\n","comments":"","group":"index"},"git_index_read_tree":{"type":"function","file":"index.h","line":277,"lineto":277,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"tree","type":"const git_tree *","comment":"tree to read"}],"argline":"git_index *index, const git_tree *tree","sig":"git_index *::const git_tree *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Read a tree into the index file with stats

\n","comments":"

The current index contents will be replaced by the specified tree.

\n","group":"index"},"git_index_write_tree":{"type":"function","file":"index.h","line":298,"lineto":298,"args":[{"name":"out","type":"git_oid *","comment":"Pointer where to store the OID of the written tree"},{"name":"index","type":"git_index *","comment":"Index to write"}],"argline":"git_oid *out, git_index *index","sig":"git_oid *::git_index *","return":{"type":"int","comment":" 0 on success, GIT_EUNMERGED when the index is not clean\n or an error code"},"description":"

Write the index as a tree

\n","comments":"

This method will scan the index and write a representation\n of its current state back to disk; it recursively creates\n tree objects for each of the subtrees stored in the index,\n but only returns the OID of the root tree. This is the OID\n that can be used e.g. to create a commit.

\n\n

The index instance cannot be bare, and needs to be associated\n to an existing repository.

\n\n

The index must not contain any file in conflict.

\n","group":"index","examples":{"init.c":["ex/v0.21.2/init.html#git_index_write_tree-3"]}},"git_index_write_tree_to":{"type":"function","file":"index.h","line":315,"lineto":315,"args":[{"name":"out","type":"git_oid *","comment":"Pointer where to store OID of the the written tree"},{"name":"index","type":"git_index *","comment":"Index to write"},{"name":"repo","type":"git_repository *","comment":"Repository where to write the tree"}],"argline":"git_oid *out, git_index *index, git_repository *repo","sig":"git_oid *::git_index *::git_repository *","return":{"type":"int","comment":" 0 on success, GIT_EUNMERGED when the index is not clean\n or an error code"},"description":"

Write the index as a tree to the given repository

\n","comments":"

This method will do the same as git_index_write_tree, but\n letting the user choose the repository where the tree will\n be written.

\n\n

The index must not contain any file in conflict.

\n","group":"index"},"git_index_entrycount":{"type":"function","file":"index.h","line":334,"lineto":334,"args":[{"name":"index","type":"const git_index *","comment":"an existing index object"}],"argline":"const git_index *index","sig":"const git_index *","return":{"type":"size_t","comment":" integer of count of current entries"},"description":"

Get the count of entries currently in the index

\n","comments":"","group":"index","examples":{"general.c":["ex/v0.21.2/general.html#git_index_entrycount-29"]}},"git_index_clear":{"type":"function","file":"index.h","line":345,"lineto":345,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"int","comment":" 0 on success, error code \n<\n 0 on failure"},"description":"

Clear the contents (all the entries) of an index object.

\n","comments":"

This clears the index object in memory; changes must be explicitly\n written to disk for them to take effect persistently.

\n","group":"index"},"git_index_get_byindex":{"type":"function","file":"index.h","line":358,"lineto":359,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"n","type":"size_t","comment":"the position of the entry"}],"argline":"git_index *index, size_t n","sig":"git_index *::size_t","return":{"type":"const git_index_entry *","comment":" a pointer to the entry; NULL if out of bounds"},"description":"

Get a pointer to one of the entries in the index

\n","comments":"

The entry is not modifiable and should not be freed. Because the\n git_index_entry struct is a publicly defined struct, you should\n be able to make your own permanent copy of the data if necessary.

\n","group":"index","examples":{"general.c":["ex/v0.21.2/general.html#git_index_get_byindex-30"]}},"git_index_get_bypath":{"type":"function","file":"index.h","line":373,"lineto":374,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to search"},{"name":"stage","type":"int","comment":"stage to search"}],"argline":"git_index *index, const char *path, int stage","sig":"git_index *::const char *::int","return":{"type":"const git_index_entry *","comment":" a pointer to the entry; NULL if it was not found"},"description":"

Get a pointer to one of the entries in the index

\n","comments":"

The entry is not modifiable and should not be freed. Because the\n git_index_entry struct is a publicly defined struct, you should\n be able to make your own permanent copy of the data if necessary.

\n","group":"index"},"git_index_remove":{"type":"function","file":"index.h","line":384,"lineto":384,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to search"},{"name":"stage","type":"int","comment":"stage to search"}],"argline":"git_index *index, const char *path, int stage","sig":"git_index *::const char *::int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Remove an entry from the index

\n","comments":"","group":"index"},"git_index_remove_directory":{"type":"function","file":"index.h","line":394,"lineto":395,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"dir","type":"const char *","comment":"container directory path"},{"name":"stage","type":"int","comment":"stage to search"}],"argline":"git_index *index, const char *dir, int stage","sig":"git_index *::const char *::int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Remove all entries from the index under a given directory

\n","comments":"","group":"index"},"git_index_add":{"type":"function","file":"index.h","line":411,"lineto":411,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"source_entry","type":"const git_index_entry *","comment":"new entry object"}],"argline":"git_index *index, const git_index_entry *source_entry","sig":"git_index *::const git_index_entry *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add or update an index entry from an in-memory struct

\n","comments":"

If a previous index entry exists that has the same path and stage\n as the given 'source_entry', it will be replaced. Otherwise, the\n 'source_entry' will be added.

\n\n

A full copy (including the 'path' string) of the given\n 'source_entry' will be inserted on the index.

\n","group":"index"},"git_index_entry_stage":{"type":"function","file":"index.h","line":423,"lineto":423,"args":[{"name":"entry","type":"const git_index_entry *","comment":"The entry"}],"argline":"const git_index_entry *entry","sig":"const git_index_entry *","return":{"type":"int","comment":" the stage number"},"description":"

Return the stage number from a git index entry

\n","comments":"

This entry is calculated from the entry's flag attribute like this:

\n\n
(entry->flags \n
\n\n

&\n GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT

\n","group":"index"},"git_index_add_bypath":{"type":"function","file":"index.h","line":454,"lineto":454,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"filename to add"}],"argline":"git_index *index, const char *path","sig":"git_index *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add or update an index entry from a file on disk

\n","comments":"

The file path must be relative to the repository's\n working folder and must be readable.

\n\n

This method will fail in bare index instances.

\n\n

This forces the file to be added to the index, not looking\n at gitignore rules. Those rules can be evaluated through\n the git_status APIs (in status.h) before calling this.

\n\n

If this file currently is the result of a merge conflict, this\n file will no longer be marked as conflicting. The data about\n the conflict will be moved to the "resolve undo" (REUC) section.

\n","group":"index"},"git_index_remove_bypath":{"type":"function","file":"index.h","line":470,"lineto":470,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"filename to remove"}],"argline":"git_index *index, const char *path","sig":"git_index *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Remove an index entry corresponding to a file on disk

\n","comments":"

The file path must be relative to the repository's\n working folder. It may exist.

\n\n

If this file currently is the result of a merge conflict, this\n file will no longer be marked as conflicting. The data about\n the conflict will be moved to the "resolve undo" (REUC) section.

\n","group":"index"},"git_index_add_all":{"type":"function","file":"index.h","line":517,"lineto":522,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"pathspec","type":"const git_strarray *","comment":"array of path patterns"},{"name":"flags","type":"unsigned int","comment":"combination of git_index_add_option_t flags"},{"name":"callback","type":"git_index_matched_path_cb","comment":"notification callback for each added/updated path (also\n gets index of matching pathspec entry); can be NULL;\n return 0 to add, >0 to skip, \n<\n0 to abort scan."},{"name":"payload","type":"void *","comment":"payload passed through to callback function"}],"argline":"git_index *index, const git_strarray *pathspec, unsigned int flags, git_index_matched_path_cb callback, void *payload","sig":"git_index *::const git_strarray *::unsigned int::git_index_matched_path_cb::void *","return":{"type":"int","comment":" 0 on success, negative callback return value, or error code"},"description":"

Add or update index entries matching files in the working directory.

\n","comments":"

This method will fail in bare index instances.

\n\n

The pathspec is a list of file names or shell glob patterns that will\n matched against files in the repository's working directory. Each file\n that matches will be added to the index (either updating an existing\n entry or adding a new entry). You can disable glob expansion and force\n exact matching with the GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH flag.

\n\n

Files that are ignored will be skipped (unlike git_index_add_bypath).\n If a file is already tracked in the index, then it will be updated\n even if it is ignored. Pass the GIT_INDEX_ADD_FORCE flag to\n skip the checking of ignore rules.

\n\n

To emulate git add -A and generate an error if the pathspec contains\n the exact path of an ignored file (when not using FORCE), add the\n GIT_INDEX_ADD_CHECK_PATHSPEC flag. This checks that each entry\n in the pathspec that is an exact match to a filename on disk is\n either not ignored or already in the index. If this check fails, the\n function will return GIT_EINVALIDSPEC.

\n\n

To emulate git add -A with the "dry-run" option, just use a callback\n function that always returns a positive value. See below for details.

\n\n

If any files are currently the result of a merge conflict, those files\n will no longer be marked as conflicting. The data about the conflicts\n will be moved to the "resolve undo" (REUC) section.

\n\n

If you provide a callback function, it will be invoked on each matching\n item in the working directory immediately before it is added to /\n updated in the index. Returning zero will add the item to the index,\n greater than zero will skip the item, and less than zero will abort the\n scan and return that value to the caller.

\n","group":"index"},"git_index_remove_all":{"type":"function","file":"index.h","line":539,"lineto":543,"args":[{"name":"index","type":"git_index *","comment":"An existing index object"},{"name":"pathspec","type":"const git_strarray *","comment":"array of path patterns"},{"name":"callback","type":"git_index_matched_path_cb","comment":"notification callback for each removed path (also\n gets index of matching pathspec entry); can be NULL;\n return 0 to add, >0 to skip, \n<\n0 to abort scan."},{"name":"payload","type":"void *","comment":"payload passed through to callback function"}],"argline":"git_index *index, const git_strarray *pathspec, git_index_matched_path_cb callback, void *payload","sig":"git_index *::const git_strarray *::git_index_matched_path_cb::void *","return":{"type":"int","comment":" 0 on success, negative callback return value, or error code"},"description":"

Remove all matching index entries.

\n","comments":"

If you provide a callback function, it will be invoked on each matching\n item in the index immediately before it is removed. Return 0 to\n remove the item, > 0 to skip the item, and \n<\n 0 to abort the scan.

\n","group":"index"},"git_index_update_all":{"type":"function","file":"index.h","line":568,"lineto":572,"args":[{"name":"index","type":"git_index *","comment":"An existing index object"},{"name":"pathspec","type":"const git_strarray *","comment":"array of path patterns"},{"name":"callback","type":"git_index_matched_path_cb","comment":"notification callback for each updated path (also\n gets index of matching pathspec entry); can be NULL;\n return 0 to add, >0 to skip, \n<\n0 to abort scan."},{"name":"payload","type":"void *","comment":"payload passed through to callback function"}],"argline":"git_index *index, const git_strarray *pathspec, git_index_matched_path_cb callback, void *payload","sig":"git_index *::const git_strarray *::git_index_matched_path_cb::void *","return":{"type":"int","comment":" 0 on success, negative callback return value, or error code"},"description":"

Update all index entries to match the working directory

\n","comments":"

This method will fail in bare index instances.

\n\n

This scans the existing index entries and synchronizes them with the\n working directory, deleting them if the corresponding working directory\n file no longer exists otherwise updating the information (including\n adding the latest version of file to the ODB if needed).

\n\n

If you provide a callback function, it will be invoked on each matching\n item in the index immediately before it is updated (either refreshed\n or removed depending on working directory state). Return 0 to proceed\n with updating the item, > 0 to skip the item, and \n<\n 0 to abort the scan.

\n","group":"index"},"git_index_find":{"type":"function","file":"index.h","line":583,"lineto":583,"args":[{"name":"at_pos","type":"size_t *","comment":"the address to which the position of the index entry is written (optional)"},{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to search"}],"argline":"size_t *at_pos, git_index *index, const char *path","sig":"size_t *::git_index *::const char *","return":{"type":"int","comment":" a zero-based position in the index if found; GIT_ENOTFOUND otherwise"},"description":"

Find the first position of any entries which point to given\n path in the Git index.

\n","comments":"","group":"index"},"git_index_conflict_add":{"type":"function","file":"index.h","line":607,"lineto":611,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"ancestor_entry","type":"const git_index_entry *","comment":"the entry data for the ancestor of the conflict"},{"name":"our_entry","type":"const git_index_entry *","comment":"the entry data for our side of the merge conflict"},{"name":"their_entry","type":"const git_index_entry *","comment":"the entry data for their side of the merge conflict"}],"argline":"git_index *index, const git_index_entry *ancestor_entry, const git_index_entry *our_entry, const git_index_entry *their_entry","sig":"git_index *::const git_index_entry *::const git_index_entry *::const git_index_entry *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add or update index entries to represent a conflict

\n","comments":"

The entries are the entries from the tree included in the merge. Any\n entry may be null to indicate that that file was not present in the\n trees during the merge. For example, ancestor_entry may be NULL to\n indicate that a file was added in both branches and must be resolved.

\n","group":"index"},"git_index_conflict_get":{"type":"function","file":"index.h","line":627,"lineto":632,"args":[{"name":"ancestor_out","type":"const git_index_entry **","comment":"Pointer to store the ancestor entry"},{"name":"our_out","type":"const git_index_entry **","comment":"Pointer to store the our entry"},{"name":"their_out","type":"const git_index_entry **","comment":"Pointer to store the their entry"},{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to search"}],"argline":"const git_index_entry **ancestor_out, const git_index_entry **our_out, const git_index_entry **their_out, git_index *index, const char *path","sig":"const git_index_entry **::const git_index_entry **::const git_index_entry **::git_index *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the index entries that represent a conflict of a single file.

\n","comments":"

The entries are not modifiable and should not be freed. Because the\n git_index_entry struct is a publicly defined struct, you should\n be able to make your own permanent copy of the data if necessary.

\n","group":"index"},"git_index_conflict_remove":{"type":"function","file":"index.h","line":641,"lineto":641,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to remove conflicts for"}],"argline":"git_index *index, const char *path","sig":"git_index *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Removes the index entries that represent a conflict of a single file.

\n","comments":"","group":"index"},"git_index_conflict_cleanup":{"type":"function","file":"index.h","line":649,"lineto":649,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Remove all conflicts in the index (entries with a stage greater than 0).

\n","comments":"","group":"index"},"git_index_has_conflicts":{"type":"function","file":"index.h","line":656,"lineto":656,"args":[{"name":"index","type":"const git_index *","comment":null}],"argline":"const git_index *index","sig":"const git_index *","return":{"type":"int","comment":" 1 if at least one conflict is found, 0 otherwise."},"description":"

Determine if the index contains entries representing file conflicts.

\n","comments":"","group":"index"},"git_index_conflict_iterator_new":{"type":"function","file":"index.h","line":667,"lineto":669,"args":[{"name":"iterator_out","type":"git_index_conflict_iterator **","comment":"The newly created conflict iterator"},{"name":"index","type":"git_index *","comment":"The index to scan"}],"argline":"git_index_conflict_iterator **iterator_out, git_index *index","sig":"git_index_conflict_iterator **::git_index *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an iterator for the conflicts in the index.

\n","comments":"

The index must not be modified while iterating; the results are undefined.

\n","group":"index"},"git_index_conflict_next":{"type":"function","file":"index.h","line":681,"lineto":685,"args":[{"name":"ancestor_out","type":"const git_index_entry **","comment":"Pointer to store the ancestor side of the conflict"},{"name":"our_out","type":"const git_index_entry **","comment":"Pointer to store our side of the conflict"},{"name":"their_out","type":"const git_index_entry **","comment":"Pointer to store their side of the conflict"},{"name":"iterator","type":"git_index_conflict_iterator *","comment":null}],"argline":"const git_index_entry **ancestor_out, const git_index_entry **our_out, const git_index_entry **their_out, git_index_conflict_iterator *iterator","sig":"const git_index_entry **::const git_index_entry **::const git_index_entry **::git_index_conflict_iterator *","return":{"type":"int","comment":" 0 (no error), GIT_ITEROVER (iteration is done) or an error code\n (negative value)"},"description":"

Returns the current conflict (ancestor, ours and theirs entry) and\n advance the iterator internally to the next value.

\n","comments":"","group":"index"},"git_index_conflict_iterator_free":{"type":"function","file":"index.h","line":692,"lineto":693,"args":[{"name":"iterator","type":"git_index_conflict_iterator *","comment":"pointer to the iterator"}],"argline":"git_index_conflict_iterator *iterator","sig":"git_index_conflict_iterator *","return":{"type":"void","comment":null},"description":"

Frees a git_index_conflict_iterator.

\n","comments":"","group":"index"},"git_indexer_new":{"type":"function","file":"indexer.h","line":30,"lineto":36,"args":[{"name":"out","type":"git_indexer **","comment":"where to store the indexer instance"},{"name":"path","type":"const char *","comment":"to the directory where the packfile should be stored"},{"name":"mode","type":"unsigned int","comment":"permissions to use creating packfile or 0 for defaults"},{"name":"odb","type":"git_odb *","comment":"object database from which to read base objects when\n fixing thin packs. Pass NULL if no thin pack is expected (an error\n will be returned if there are bases missing)"},{"name":"progress_cb","type":"git_transfer_progress_cb","comment":"function to call with progress information"},{"name":"progress_cb_payload","type":"void *","comment":"payload for the progress callback"}],"argline":"git_indexer **out, const char *path, unsigned int mode, git_odb *odb, git_transfer_progress_cb progress_cb, void *progress_cb_payload","sig":"git_indexer **::const char *::unsigned int::git_odb *::git_transfer_progress_cb::void *","return":{"type":"int","comment":null},"description":"

Create a new indexer instance

\n","comments":"","group":"indexer","examples":{"network/index-pack.c":["ex/v0.21.2/network/index-pack.html#git_indexer_new-1"]}},"git_indexer_append":{"type":"function","file":"indexer.h","line":46,"lineto":46,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer"},{"name":"data","type":"const void *","comment":"the data to add"},{"name":"size","type":"size_t","comment":"the size of the data in bytes"},{"name":"stats","type":"git_transfer_progress *","comment":"stat storage"}],"argline":"git_indexer *idx, const void *data, size_t size, git_transfer_progress *stats","sig":"git_indexer *::const void *::size_t::git_transfer_progress *","return":{"type":"int","comment":null},"description":"

Add data to the indexer

\n","comments":"","group":"indexer","examples":{"network/index-pack.c":["ex/v0.21.2/network/index-pack.html#git_indexer_append-2"]}},"git_indexer_commit":{"type":"function","file":"indexer.h","line":55,"lineto":55,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer"},{"name":"stats","type":"git_transfer_progress *","comment":null}],"argline":"git_indexer *idx, git_transfer_progress *stats","sig":"git_indexer *::git_transfer_progress *","return":{"type":"int","comment":null},"description":"

Finalize the pack and index

\n","comments":"

Resolve any pending deltas and write out the index file

\n","group":"indexer","examples":{"network/index-pack.c":["ex/v0.21.2/network/index-pack.html#git_indexer_commit-3"]}},"git_indexer_hash":{"type":"function","file":"indexer.h","line":65,"lineto":65,"args":[{"name":"idx","type":"const git_indexer *","comment":"the indexer instance"}],"argline":"const git_indexer *idx","sig":"const git_indexer *","return":{"type":"const git_oid *","comment":null},"description":"

Get the packfile's hash

\n","comments":"

A packfile's name is derived from the sorted hashing of all object\n names. This is only correct after the index has been finalized.

\n","group":"indexer","examples":{"network/index-pack.c":["ex/v0.21.2/network/index-pack.html#git_indexer_hash-4"]}},"git_indexer_free":{"type":"function","file":"indexer.h","line":72,"lineto":72,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer to free"}],"argline":"git_indexer *idx","sig":"git_indexer *","return":{"type":"void","comment":null},"description":"

Free the indexer and its resources

\n","comments":"","group":"indexer","examples":{"network/index-pack.c":["ex/v0.21.2/network/index-pack.html#git_indexer_free-5"]}},"git_merge_file_init_input":{"type":"function","file":"merge.h","line":58,"lineto":60,"args":[{"name":"opts","type":"git_merge_file_input *","comment":"the `git_merge_file_input` instance to initialize."},{"name":"version","type":"unsigned int","comment":"the version of the struct; you should pass\n `GIT_MERGE_FILE_INPUT_VERSION` here."}],"argline":"git_merge_file_input *opts, unsigned int version","sig":"git_merge_file_input *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_merge_file_input with default values. Equivalent to\n creating an instance with GIT_MERGE_FILE_INPUT_INIT.

\n","comments":"","group":"merge"},"git_merge_file_init_options":{"type":"function","file":"merge.h","line":165,"lineto":167,"args":[{"name":"opts","type":"git_merge_file_options *","comment":"the `git_merge_file_options` instance to initialize."},{"name":"version","type":"unsigned int","comment":"the version of the struct; you should pass\n `GIT_MERGE_FILE_OPTIONS_VERSION` here."}],"argline":"git_merge_file_options *opts, unsigned int version","sig":"git_merge_file_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_merge_file_options with default values. Equivalent to\n creating an instance with GIT_MERGE_FILE_OPTIONS_INIT.

\n","comments":"","group":"merge"},"git_merge_init_options":{"type":"function","file":"merge.h","line":233,"lineto":235,"args":[{"name":"opts","type":"git_merge_options *","comment":"the `git_merge_options` instance to initialize."},{"name":"version","type":"unsigned int","comment":"the version of the struct; you should pass\n `GIT_MERGE_OPTIONS_VERSION` here."}],"argline":"git_merge_options *opts, unsigned int version","sig":"git_merge_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_merge_options with default values. Equivalent to\n creating an instance with GIT_MERGE_OPTIONS_INIT.

\n","comments":"","group":"merge"},"git_merge_analysis":{"type":"function","file":"merge.h","line":301,"lineto":306,"args":[{"name":"analysis_out","type":"git_merge_analysis_t *","comment":"analysis enumeration that the result is written into"},{"name":"preference_out","type":"git_merge_preference_t *","comment":null},{"name":"repo","type":"git_repository *","comment":"the repository to merge"},{"name":"their_heads","type":"const git_merge_head **","comment":"the heads to merge into"},{"name":"their_heads_len","type":"size_t","comment":"the number of heads to merge"}],"argline":"git_merge_analysis_t *analysis_out, git_merge_preference_t *preference_out, git_repository *repo, const git_merge_head **their_heads, size_t their_heads_len","sig":"git_merge_analysis_t *::git_merge_preference_t *::git_repository *::const git_merge_head **::size_t","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Analyzes the given branch(es) and determines the opportunities for\n merging them into the HEAD of the repository.

\n","comments":"","group":"merge"},"git_merge_base":{"type":"function","file":"merge.h","line":317,"lineto":321,"args":[{"name":"out","type":"git_oid *","comment":"the OID of a merge base between 'one' and 'two'"},{"name":"repo","type":"git_repository *","comment":"the repository where the commits exist"},{"name":"one","type":"const git_oid *","comment":"one of the commits"},{"name":"two","type":"const git_oid *","comment":"the other commit"}],"argline":"git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two","sig":"git_oid *::git_repository *::const git_oid *::const git_oid *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if not found or error code"},"description":"

Find a merge base between two commits

\n","comments":"","group":"merge","examples":{"log.c":["ex/v0.21.2/log.html#git_merge_base-30"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_merge_base-1"]}},"git_merge_base_many":{"type":"function","file":"merge.h","line":332,"lineto":336,"args":[{"name":"out","type":"git_oid *","comment":"the OID of a merge base considering all the commits"},{"name":"repo","type":"git_repository *","comment":"the repository where the commits exist"},{"name":"length","type":"size_t","comment":"The number of commits in the provided `input_array`"},{"name":"input_array","type":"const git_oid []","comment":"oids of the commits"}],"argline":"git_oid *out, git_repository *repo, size_t length, const git_oid [] input_array","sig":"git_oid *::git_repository *::size_t::const git_oid []","return":{"type":"int","comment":" Zero on success; GIT_ENOTFOUND or -1 on failure."},"description":"

Find a merge base given a list of commits

\n","comments":"","group":"merge"},"git_merge_base_octopus":{"type":"function","file":"merge.h","line":347,"lineto":351,"args":[{"name":"out","type":"git_oid *","comment":"the OID of a merge base considering all the commits"},{"name":"repo","type":"git_repository *","comment":"the repository where the commits exist"},{"name":"length","type":"size_t","comment":"The number of commits in the provided `input_array`"},{"name":"input_array","type":"const git_oid []","comment":"oids of the commits"}],"argline":"git_oid *out, git_repository *repo, size_t length, const git_oid [] input_array","sig":"git_oid *::git_repository *::size_t::const git_oid []","return":{"type":"int","comment":" Zero on success; GIT_ENOTFOUND or -1 on failure."},"description":"

Find a merge base in preparation for an octopus merge

\n","comments":"","group":"merge"},"git_merge_head_from_ref":{"type":"function","file":"merge.h","line":362,"lineto":365,"args":[{"name":"out","type":"git_merge_head **","comment":"pointer to store the git_merge_head result in"},{"name":"repo","type":"git_repository *","comment":"repository that contains the given reference"},{"name":"ref","type":"const git_reference *","comment":"reference to use as a merge input"}],"argline":"git_merge_head **out, git_repository *repo, const git_reference *ref","sig":"git_merge_head **::git_repository *::const git_reference *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Creates a git_merge_head from the given reference. The resulting\n git_merge_head must be freed with git_merge_head_free.

\n","comments":"","group":"merge"},"git_merge_head_from_fetchhead":{"type":"function","file":"merge.h","line":378,"lineto":383,"args":[{"name":"out","type":"git_merge_head **","comment":"pointer to store the git_merge_head result in"},{"name":"repo","type":"git_repository *","comment":"repository that contains the given commit"},{"name":"branch_name","type":"const char *","comment":"name of the (remote) branch"},{"name":"remote_url","type":"const char *","comment":"url of the remote"},{"name":"oid","type":"const git_oid *","comment":"the commit object id to use as a merge input"}],"argline":"git_merge_head **out, git_repository *repo, const char *branch_name, const char *remote_url, const git_oid *oid","sig":"git_merge_head **::git_repository *::const char *::const char *::const git_oid *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Creates a git_merge_head from the given fetch head data. The resulting\n git_merge_head must be freed with git_merge_head_free.

\n","comments":"","group":"merge"},"git_merge_head_from_id":{"type":"function","file":"merge.h","line":394,"lineto":397,"args":[{"name":"out","type":"git_merge_head **","comment":"pointer to store the git_merge_head result in"},{"name":"repo","type":"git_repository *","comment":"repository that contains the given commit"},{"name":"id","type":"const git_oid *","comment":"the commit object id to use as a merge input"}],"argline":"git_merge_head **out, git_repository *repo, const git_oid *id","sig":"git_merge_head **::git_repository *::const git_oid *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Creates a git_merge_head from the given commit id. The resulting\n git_merge_head must be freed with git_merge_head_free.

\n","comments":"","group":"merge"},"git_merge_head_id":{"type":"function","file":"merge.h","line":405,"lineto":406,"args":[{"name":"head","type":"const git_merge_head *","comment":"the given merge head"}],"argline":"const git_merge_head *head","sig":"const git_merge_head *","return":{"type":"const git_oid *","comment":" commit id"},"description":"

Gets the commit ID that the given git_merge_head refers to.

\n","comments":"","group":"merge"},"git_merge_head_free":{"type":"function","file":"merge.h","line":413,"lineto":414,"args":[{"name":"head","type":"git_merge_head *","comment":"merge head to free"}],"argline":"git_merge_head *head","sig":"git_merge_head *","return":{"type":"void","comment":null},"description":"

Frees a git_merge_head.

\n","comments":"","group":"merge"},"git_merge_file":{"type":"function","file":"merge.h","line":432,"lineto":437,"args":[{"name":"out","type":"git_merge_file_result *","comment":"The git_merge_file_result to be filled in"},{"name":"ancestor","type":"const git_merge_file_input *","comment":"The contents of the ancestor file"},{"name":"ours","type":"const git_merge_file_input *","comment":"The contents of the file in \"our\" side"},{"name":"theirs","type":"const git_merge_file_input *","comment":"The contents of the file in \"their\" side"},{"name":"opts","type":"const git_merge_file_options *","comment":"The merge file options or `NULL` for defaults"}],"argline":"git_merge_file_result *out, const git_merge_file_input *ancestor, const git_merge_file_input *ours, const git_merge_file_input *theirs, const git_merge_file_options *opts","sig":"git_merge_file_result *::const git_merge_file_input *::const git_merge_file_input *::const git_merge_file_input *::const git_merge_file_options *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Merge two files as they exist in the in-memory data structures, using\n the given common ancestor as the baseline, producing a\n git_merge_file_result that reflects the merge result. The\n git_merge_file_result must be freed with git_merge_file_result_free.

\n","comments":"

Note that this function does not reference a repository and any\n configuration must be passed as git_merge_file_options.

\n","group":"merge"},"git_merge_file_from_index":{"type":"function","file":"merge.h","line":453,"lineto":459,"args":[{"name":"out","type":"git_merge_file_result *","comment":"The git_merge_file_result to be filled in"},{"name":"repo","type":"git_repository *","comment":"The repository"},{"name":"ancestor","type":"const git_index_entry *","comment":"The index entry for the ancestor file (stage level 1)"},{"name":"ours","type":"const git_index_entry *","comment":"The index entry for our file (stage level 2)"},{"name":"theirs","type":"const git_index_entry *","comment":"The index entry for their file (stage level 3)"},{"name":"opts","type":"const git_merge_file_options *","comment":"The merge file options or NULL"}],"argline":"git_merge_file_result *out, git_repository *repo, const git_index_entry *ancestor, const git_index_entry *ours, const git_index_entry *theirs, const git_merge_file_options *opts","sig":"git_merge_file_result *::git_repository *::const git_index_entry *::const git_index_entry *::const git_index_entry *::const git_merge_file_options *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Merge two files as they exist in the index, using the given common\n ancestor as the baseline, producing a git_merge_file_result that\n reflects the merge result. The git_merge_file_result must be freed with\n git_merge_file_result_free.

\n","comments":"","group":"merge"},"git_merge_file_result_free":{"type":"function","file":"merge.h","line":466,"lineto":466,"args":[{"name":"result","type":"git_merge_file_result *","comment":"The result to free or `NULL`"}],"argline":"git_merge_file_result *result","sig":"git_merge_file_result *","return":{"type":"void","comment":null},"description":"

Frees a git_merge_file_result.

\n","comments":"","group":"merge"},"git_merge_trees":{"type":"function","file":"merge.h","line":484,"lineto":490,"args":[{"name":"out","type":"git_index **","comment":"pointer to store the index result in"},{"name":"repo","type":"git_repository *","comment":"repository that contains the given trees"},{"name":"ancestor_tree","type":"const git_tree *","comment":"the common ancestor between the trees (or null if none)"},{"name":"our_tree","type":"const git_tree *","comment":"the tree that reflects the destination tree"},{"name":"their_tree","type":"const git_tree *","comment":"the tree to merge in to `our_tree`"},{"name":"opts","type":"const git_merge_options *","comment":"the merge tree options (or null for defaults)"}],"argline":"git_index **out, git_repository *repo, const git_tree *ancestor_tree, const git_tree *our_tree, const git_tree *their_tree, const git_merge_options *opts","sig":"git_index **::git_repository *::const git_tree *::const git_tree *::const git_tree *::const git_merge_options *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Merge two trees, producing a git_index that reflects the result of\n the merge. The index may be written as-is to the working directory\n or checked out. If the index is to be converted to a tree, the caller\n should resolve any conflicts that arose as part of the merge.

\n","comments":"

The returned index must be freed explicitly with git_index_free.

\n","group":"merge"},"git_merge_commits":{"type":"function","file":"merge.h","line":507,"lineto":512,"args":[{"name":"out","type":"git_index **","comment":"pointer to store the index result in"},{"name":"repo","type":"git_repository *","comment":"repository that contains the given trees"},{"name":"our_commit","type":"const git_commit *","comment":"the commit that reflects the destination tree"},{"name":"their_commit","type":"const git_commit *","comment":"the commit to merge in to `our_commit`"},{"name":"opts","type":"const git_merge_options *","comment":"the merge tree options (or null for defaults)"}],"argline":"git_index **out, git_repository *repo, const git_commit *our_commit, const git_commit *their_commit, const git_merge_options *opts","sig":"git_index **::git_repository *::const git_commit *::const git_commit *::const git_merge_options *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Merge two commits, producing a git_index that reflects the result of\n the merge. The index may be written as-is to the working directory\n or checked out. If the index is to be converted to a tree, the caller\n should resolve any conflicts that arose as part of the merge.

\n","comments":"

The returned index must be freed explicitly with git_index_free.

\n","group":"merge"},"git_merge":{"type":"function","file":"merge.h","line":527,"lineto":532,"args":[{"name":"repo","type":"git_repository *","comment":"the repository to merge"},{"name":"their_heads","type":"const git_merge_head **","comment":"the heads to merge into"},{"name":"their_heads_len","type":"size_t","comment":"the number of heads to merge"},{"name":"merge_opts","type":"const git_merge_options *","comment":"merge options"},{"name":"checkout_opts","type":"const git_checkout_options *","comment":"checkout options"}],"argline":"git_repository *repo, const git_merge_head **their_heads, size_t their_heads_len, const git_merge_options *merge_opts, const git_checkout_options *checkout_opts","sig":"git_repository *::const git_merge_head **::size_t::const git_merge_options *::const git_checkout_options *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Merges the given commit(s) into HEAD, writing the results into the working\n directory. Any changes are staged for commit and any conflicts are written\n to the index. Callers should inspect the repository's index after this\n completes, resolve any conflicts and prepare a commit.

\n","comments":"","group":"merge"},"git_message_prettify":{"type":"function","file":"message.h","line":39,"lineto":39,"args":[{"name":"out","type":"git_buf *","comment":"The user-allocated git_buf which will be filled with the\n cleaned up message."},{"name":"message","type":"const char *","comment":"The message to be prettified."},{"name":"strip_comments","type":"int","comment":"Non-zero to remove comment lines, 0 to leave them in."},{"name":"comment_char","type":"char","comment":"Comment character. Lines starting with this character\n are considered to be comments and removed if `strip_comments` is non-zero."}],"argline":"git_buf *out, const char *message, int strip_comments, char comment_char","sig":"git_buf *::const char *::int::char","return":{"type":"int","comment":" 0 or an error code."},"description":"

Clean up message from excess whitespace and make sure that the last line\n ends with a '

\n\n

'.

\n","comments":"

Optionally, can remove lines starting with a "#".

\n","group":"message"},"git_note_iterator_new":{"type":"function","file":"notes.h","line":49,"lineto":52,"args":[{"name":"out","type":"git_note_iterator **","comment":"pointer to the iterator"},{"name":"repo","type":"git_repository *","comment":"repository where to look up the note"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional); defaults to\n \"refs/notes/commits\""}],"argline":"git_note_iterator **out, git_repository *repo, const char *notes_ref","sig":"git_note_iterator **::git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Creates a new iterator for notes

\n","comments":"

The iterator must be freed manually by the user.

\n","group":"note"},"git_note_iterator_free":{"type":"function","file":"notes.h","line":59,"lineto":59,"args":[{"name":"it","type":"git_note_iterator *","comment":"pointer to the iterator"}],"argline":"git_note_iterator *it","sig":"git_note_iterator *","return":{"type":"void","comment":null},"description":"

Frees an git_note_iterator

\n","comments":"","group":"note"},"git_note_next":{"type":"function","file":"notes.h","line":74,"lineto":77,"args":[{"name":"note_id","type":"git_oid *","comment":"id of blob containing the message"},{"name":"annotated_id","type":"git_oid *","comment":"id of the git object being annotated"},{"name":"it","type":"git_note_iterator *","comment":"pointer to the iterator"}],"argline":"git_oid *note_id, git_oid *annotated_id, git_note_iterator *it","sig":"git_oid *::git_oid *::git_note_iterator *","return":{"type":"int","comment":" 0 (no error), GIT_ITEROVER (iteration is done) or an error code\n (negative value)"},"description":"

Returns the current item (note_id and annotated_id) and advance the iterator\n internally to the next value

\n","comments":"

The notes must not be freed manually by the user.

\n","group":"note"},"git_note_read":{"type":"function","file":"notes.h","line":93,"lineto":97,"args":[{"name":"out","type":"git_note **","comment":"pointer to the read note; NULL in case of error"},{"name":"repo","type":"git_repository *","comment":"repository where to look up the note"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional); defaults to\n \"refs/notes/commits\""},{"name":"oid","type":"const git_oid *","comment":"OID of the git object to read the note from"}],"argline":"git_note **out, git_repository *repo, const char *notes_ref, const git_oid *oid","sig":"git_note **::git_repository *::const char *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Read the note for an object

\n","comments":"

The note must be freed manually by the user.

\n","group":"note"},"git_note_message":{"type":"function","file":"notes.h","line":105,"lineto":105,"args":[{"name":"note","type":"const git_note *","comment":"the note"}],"argline":"const git_note *note","sig":"const git_note *","return":{"type":"const char *","comment":" the note message"},"description":"

Get the note message

\n","comments":"","group":"note"},"git_note_id":{"type":"function","file":"notes.h","line":114,"lineto":114,"args":[{"name":"note","type":"const git_note *","comment":"the note"}],"argline":"const git_note *note","sig":"const git_note *","return":{"type":"const git_oid *","comment":" the note object's id"},"description":"

Get the note object's id

\n","comments":"","group":"note"},"git_note_create":{"type":"function","file":"notes.h","line":131,"lineto":139,"args":[{"name":"out","type":"git_oid *","comment":"pointer to store the OID (optional); NULL in case of error"},{"name":"repo","type":"git_repository *","comment":"repository where to store the note"},{"name":"author","type":"const git_signature *","comment":"signature of the notes commit author"},{"name":"committer","type":"const git_signature *","comment":"signature of the notes commit committer"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional);\n\t\t\t\t\tdefaults to \"refs/notes/commits\""},{"name":"oid","type":"const git_oid *","comment":"OID of the git object to decorate"},{"name":"note","type":"const char *","comment":"Content of the note to add for object oid"},{"name":"force","type":"int","comment":"Overwrite existing note"}],"argline":"git_oid *out, git_repository *repo, const git_signature *author, const git_signature *committer, const char *notes_ref, const git_oid *oid, const char *note, int force","sig":"git_oid *::git_repository *::const git_signature *::const git_signature *::const char *::const git_oid *::const char *::int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add a note for an object

\n","comments":"","group":"note"},"git_note_remove":{"type":"function","file":"notes.h","line":154,"lineto":159,"args":[{"name":"repo","type":"git_repository *","comment":"repository where the note lives"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional);\n\t\t\t\t\tdefaults to \"refs/notes/commits\""},{"name":"author","type":"const git_signature *","comment":"signature of the notes commit author"},{"name":"committer","type":"const git_signature *","comment":"signature of the notes commit committer"},{"name":"oid","type":"const git_oid *","comment":"OID of the git object to remove the note from"}],"argline":"git_repository *repo, const char *notes_ref, const git_signature *author, const git_signature *committer, const git_oid *oid","sig":"git_repository *::const char *::const git_signature *::const git_signature *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Remove the note for an object

\n","comments":"","group":"note"},"git_note_free":{"type":"function","file":"notes.h","line":166,"lineto":166,"args":[{"name":"note","type":"git_note *","comment":"git_note object"}],"argline":"git_note *note","sig":"git_note *","return":{"type":"void","comment":null},"description":"

Free a git_note object

\n","comments":"","group":"note"},"git_note_default_ref":{"type":"function","file":"notes.h","line":176,"lineto":176,"args":[{"name":"out","type":"const char **","comment":"Pointer to the default notes reference"},{"name":"repo","type":"git_repository *","comment":"The Git repository"}],"argline":"const char **out, git_repository *repo","sig":"const char **::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the default notes reference for a repository

\n","comments":"","group":"note"},"git_note_foreach":{"type":"function","file":"notes.h","line":194,"lineto":198,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the notes."},{"name":"notes_ref","type":"const char *","comment":"Reference to read from (optional); defaults to\n \"refs/notes/commits\"."},{"name":"note_cb","type":"git_note_foreach_cb","comment":"Callback to invoke per found annotation. Return non-zero\n to stop looping."},{"name":"payload","type":"void *","comment":"Extra parameter to callback function."}],"argline":"git_repository *repo, const char *notes_ref, git_note_foreach_cb note_cb, void *payload","sig":"git_repository *::const char *::git_note_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Loop over all the notes within a specified namespace\n and issue a callback for each one.

\n","comments":"","group":"note"},"git_object_lookup":{"type":"function","file":"object.h","line":42,"lineto":46,"args":[{"name":"object","type":"git_object **","comment":"pointer to the looked-up object"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the object"},{"name":"id","type":"const git_oid *","comment":"the unique identifier for the object"},{"name":"type","type":"git_otype","comment":"the type of the object"}],"argline":"git_object **object, git_repository *repo, const git_oid *id, git_otype type","sig":"git_object **::git_repository *::const git_oid *::git_otype","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a reference to one of the objects in a repository.

\n","comments":"

The generated reference is owned by the repository and\n should be closed with the git_object_free method\n instead of free'd manually.

\n\n

The 'type' parameter must match the type of the object\n in the odb; the method will fail otherwise.\n The special value 'GIT_OBJ_ANY' may be passed to let\n the method guess the object's type.

\n","group":"object","examples":{"log.c":["ex/v0.21.2/log.html#git_object_lookup-31"]}},"git_object_lookup_prefix":{"type":"function","file":"object.h","line":75,"lineto":80,"args":[{"name":"object_out","type":"git_object **","comment":"pointer where to store the looked-up object"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the object"},{"name":"id","type":"const git_oid *","comment":"a short identifier for the object"},{"name":"len","type":"size_t","comment":"the length of the short identifier"},{"name":"type","type":"git_otype","comment":"the type of the object"}],"argline":"git_object **object_out, git_repository *repo, const git_oid *id, size_t len, git_otype type","sig":"git_object **::git_repository *::const git_oid *::size_t::git_otype","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a reference to one of the objects in a repository,\n given a prefix of its identifier (short id).

\n","comments":"

The object obtained will be so that its identifier\n matches the first 'len' hexadecimal characters\n (packets of 4 bits) of the given 'id'.\n 'len' must be at least GIT_OID_MINPREFIXLEN, and\n long enough to identify a unique object matching\n the prefix; otherwise the method will fail.

\n\n

The generated reference is owned by the repository and\n should be closed with the git_object_free method\n instead of free'd manually.

\n\n

The 'type' parameter must match the type of the object\n in the odb; the method will fail otherwise.\n The special value 'GIT_OBJ_ANY' may be passed to let\n the method guess the object's type.

\n","group":"object"},"git_object_lookup_bypath":{"type":"function","file":"object.h","line":93,"lineto":97,"args":[{"name":"out","type":"git_object **","comment":"buffer that receives a pointer to the object (which must be freed\n by the caller)"},{"name":"treeish","type":"const git_object *","comment":"root object that can be peeled to a tree"},{"name":"path","type":"const char *","comment":"relative path from the root object to the desired object"},{"name":"type","type":"git_otype","comment":"type of object desired"}],"argline":"git_object **out, const git_object *treeish, const char *path, git_otype type","sig":"git_object **::const git_object *::const char *::git_otype","return":{"type":"int","comment":" 0 on success, or an error code"},"description":"

Lookup an object that represents a tree entry.

\n","comments":"","group":"object"},"git_object_id":{"type":"function","file":"object.h","line":105,"lineto":105,"args":[{"name":"obj","type":"const git_object *","comment":"the repository object"}],"argline":"const git_object *obj","sig":"const git_object *","return":{"type":"const git_oid *","comment":" the SHA1 id"},"description":"

Get the id (SHA1) of a repository object

\n","comments":"","group":"object","examples":{"blame.c":["ex/v0.21.2/blame.html#git_object_id-8","ex/v0.21.2/blame.html#git_object_id-9","ex/v0.21.2/blame.html#git_object_id-10","ex/v0.21.2/blame.html#git_object_id-11"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_object_id-10","ex/v0.21.2/cat-file.html#git_object_id-11"],"log.c":["ex/v0.21.2/log.html#git_object_id-32","ex/v0.21.2/log.html#git_object_id-33","ex/v0.21.2/log.html#git_object_id-34","ex/v0.21.2/log.html#git_object_id-35"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_object_id-2","ex/v0.21.2/rev-parse.html#git_object_id-3","ex/v0.21.2/rev-parse.html#git_object_id-4","ex/v0.21.2/rev-parse.html#git_object_id-5","ex/v0.21.2/rev-parse.html#git_object_id-6"]}},"git_object_short_id":{"type":"function","file":"object.h","line":119,"lineto":119,"args":[{"name":"out","type":"git_buf *","comment":"Buffer to write string into"},{"name":"obj","type":"const git_object *","comment":"The object to get an ID for"}],"argline":"git_buf *out, const git_object *obj","sig":"git_buf *::const git_object *","return":{"type":"int","comment":" 0 on success, \n<\n0 for error"},"description":"

Get a short abbreviated OID string for the object

\n","comments":"

This starts at the "core.abbrev" length (default 7 characters) and\n iteratively extends to a longer string if that length is ambiguous.\n The result will be unambiguous (at least until new objects are added to\n the repository).

\n","group":"object","examples":{"tag.c":["ex/v0.21.2/tag.html#git_object_short_id-3"]}},"git_object_type":{"type":"function","file":"object.h","line":127,"lineto":127,"args":[{"name":"obj","type":"const git_object *","comment":"the repository object"}],"argline":"const git_object *obj","sig":"const git_object *","return":{"type":"git_otype","comment":" the object's type"},"description":"

Get the object type of an object

\n","comments":"","group":"object","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_object_type-12","ex/v0.21.2/cat-file.html#git_object_type-13","ex/v0.21.2/cat-file.html#git_object_type-14"],"tag.c":["ex/v0.21.2/tag.html#git_object_type-4"]}},"git_object_owner":{"type":"function","file":"object.h","line":141,"lineto":141,"args":[{"name":"obj","type":"const git_object *","comment":"the object"}],"argline":"const git_object *obj","sig":"const git_object *","return":{"type":"git_repository *","comment":" the repository who owns this object"},"description":"

Get the repository that owns this object

\n","comments":"

Freeing or calling git_repository_close on the\n returned pointer will invalidate the actual object.

\n\n

Any other operation may be run on the repository without\n affecting the object.

\n","group":"object"},"git_object_free":{"type":"function","file":"object.h","line":158,"lineto":158,"args":[{"name":"object","type":"git_object *","comment":"the object to close"}],"argline":"git_object *object","sig":"git_object *","return":{"type":"void","comment":null},"description":"

Close an open object

\n","comments":"

This method instructs the library to close an existing\n object; note that git_objects are owned and cached by the repository\n so the object may or may not be freed after this library call,\n depending on how aggressive is the caching mechanism used\n by the repository.

\n\n

IMPORTANT:\n It is necessary to call this method when you stop using\n an object. Failure to do so will cause a memory leak.

\n","group":"object","examples":{"blame.c":["ex/v0.21.2/blame.html#git_object_free-12","ex/v0.21.2/blame.html#git_object_free-13","ex/v0.21.2/blame.html#git_object_free-14","ex/v0.21.2/blame.html#git_object_free-15"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_object_free-15"],"general.c":["ex/v0.21.2/general.html#git_object_free-31"],"log.c":["ex/v0.21.2/log.html#git_object_free-36"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_object_free-7","ex/v0.21.2/rev-parse.html#git_object_free-8","ex/v0.21.2/rev-parse.html#git_object_free-9"],"tag.c":["ex/v0.21.2/tag.html#git_object_free-5","ex/v0.21.2/tag.html#git_object_free-6","ex/v0.21.2/tag.html#git_object_free-7","ex/v0.21.2/tag.html#git_object_free-8"]}},"git_object_type2string":{"type":"function","file":"object.h","line":169,"lineto":169,"args":[{"name":"type","type":"git_otype","comment":"object type to convert."}],"argline":"git_otype type","sig":"git_otype","return":{"type":"const char *","comment":" the corresponding string representation."},"description":"

Convert an object type to its string representation.

\n","comments":"

The result is a pointer to a string in static memory and\n should not be free()'ed.

\n","group":"object","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_object_type2string-16","ex/v0.21.2/cat-file.html#git_object_type2string-17","ex/v0.21.2/cat-file.html#git_object_type2string-18","ex/v0.21.2/cat-file.html#git_object_type2string-19"],"general.c":["ex/v0.21.2/general.html#git_object_type2string-32"]}},"git_object_string2type":{"type":"function","file":"object.h","line":177,"lineto":177,"args":[{"name":"str","type":"const char *","comment":"the string to convert."}],"argline":"const char *str","sig":"const char *","return":{"type":"git_otype","comment":" the corresponding git_otype."},"description":"

Convert a string object type representation to it's git_otype.

\n","comments":"","group":"object"},"git_object_typeisloose":{"type":"function","file":"object.h","line":186,"lineto":186,"args":[{"name":"type","type":"git_otype","comment":"object type to test."}],"argline":"git_otype type","sig":"git_otype","return":{"type":"int","comment":" true if the type represents a valid loose object type,\n false otherwise."},"description":"

Determine if the given git_otype is a valid loose object type.

\n","comments":"","group":"object"},"git_object__size":{"type":"function","file":"object.h","line":200,"lineto":200,"args":[{"name":"type","type":"git_otype","comment":"object type to get its size"}],"argline":"git_otype type","sig":"git_otype","return":{"type":"size_t","comment":" size in bytes of the object"},"description":"

Get the size in bytes for the structure which\n acts as an in-memory representation of any given\n object type.

\n","comments":"

For all the core types, this would the equivalent\n of calling sizeof(git_commit) if the core types\n were not opaque on the external API.

\n","group":"object"},"git_object_peel":{"type":"function","file":"object.h","line":218,"lineto":221,"args":[{"name":"peeled","type":"git_object **","comment":"Pointer to the peeled git_object"},{"name":"object","type":"const git_object *","comment":"The object to be processed"},{"name":"target_type","type":"git_otype","comment":"The type of the requested object (GIT_OBJ_COMMIT,\n GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY)."}],"argline":"git_object **peeled, const git_object *object, git_otype target_type","sig":"git_object **::const git_object *::git_otype","return":{"type":"int","comment":" 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code"},"description":"

Recursively peel an object until an object of the specified type is met.

\n","comments":"

The retrieved peeled object is owned by the repository and should be\n closed with the git_object_free method.

\n\n

If you pass GIT_OBJ_ANY as the target type, then the object will be\n peeled until the type changes (e.g. a tag will be chased until the\n referenced object is no longer a tag).

\n","group":"object"},"git_object_dup":{"type":"function","file":"object.h","line":230,"lineto":230,"args":[{"name":"dest","type":"git_object **","comment":"Pointer to store the copy of the object"},{"name":"source","type":"git_object *","comment":"Original object to copy"}],"argline":"git_object **dest, git_object *source","sig":"git_object **::git_object *","return":{"type":"int","comment":null},"description":"

Create an in-memory copy of a Git object. The copy must be\n explicitly free'd or it will leak.

\n","comments":"","group":"object"},"git_odb_new":{"type":"function","file":"odb.h","line":38,"lineto":38,"args":[{"name":"out","type":"git_odb **","comment":"location to store the database pointer, if opened.\n\t\t\tSet to NULL if the open failed."}],"argline":"git_odb **out","sig":"git_odb **","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new object database with no backends.

\n","comments":"

Before the ODB can be used for read/writing, a custom database\n backend must be manually added using git_odb_add_backend()

\n","group":"odb"},"git_odb_open":{"type":"function","file":"odb.h","line":56,"lineto":56,"args":[{"name":"out","type":"git_odb **","comment":"location to store the database pointer, if opened.\n\t\t\tSet to NULL if the open failed."},{"name":"objects_dir","type":"const char *","comment":"path of the backends' \"objects\" directory."}],"argline":"git_odb **out, const char *objects_dir","sig":"git_odb **::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new object database and automatically add\n the two default backends:

\n","comments":"
- git_odb_backend_loose: read and write loose object files\n    from disk, assuming `objects_dir` as the Objects folder\n\n- git_odb_backend_pack: read objects from packfiles,\n    assuming `objects_dir` as the Objects folder which\n    contains a 'pack/' folder with the corresponding data\n
\n","group":"odb"},"git_odb_add_disk_alternate":{"type":"function","file":"odb.h","line":73,"lineto":73,"args":[{"name":"odb","type":"git_odb *","comment":"database to add the backend to"},{"name":"path","type":"const char *","comment":"path to the objects folder for the alternate"}],"argline":"git_odb *odb, const char *path","sig":"git_odb *::const char *","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"

Add an on-disk alternate to an existing Object DB.

\n","comments":"

Note that the added path must point to an objects, not\n to a full repository, to use it as an alternate store.

\n\n

Alternate backends are always checked for objects after\n all the main backends have been exhausted.

\n\n

Writing is disabled on alternate backends.

\n","group":"odb"},"git_odb_free":{"type":"function","file":"odb.h","line":80,"lineto":80,"args":[{"name":"db","type":"git_odb *","comment":"database pointer to close. If NULL no action is taken."}],"argline":"git_odb *db","sig":"git_odb *","return":{"type":"void","comment":null},"description":"

Close an open object database.

\n","comments":"","group":"odb","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_odb_free-20"]}},"git_odb_read":{"type":"function","file":"odb.h","line":99,"lineto":99,"args":[{"name":"out","type":"git_odb_object **","comment":"pointer where to store the read object"},{"name":"db","type":"git_odb *","comment":"database to search for the object in."},{"name":"id","type":"const git_oid *","comment":"identity of the object to read."}],"argline":"git_odb_object **out, git_odb *db, const git_oid *id","sig":"git_odb_object **::git_odb *::const git_oid *","return":{"type":"int","comment":" - 0 if the object was read;\n - GIT_ENOTFOUND if the object is not in the database."},"description":"

Read an object from the database.

\n","comments":"

This method queries all available ODB backends\n trying to read the given OID.

\n\n

The returned object is reference counted and\n internally cached, so it should be closed\n by the user once it's no longer in use.

\n","group":"odb","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_odb_read-21"],"general.c":["ex/v0.21.2/general.html#git_odb_read-33"]}},"git_odb_read_prefix":{"type":"function","file":"odb.h","line":128,"lineto":128,"args":[{"name":"out","type":"git_odb_object **","comment":"pointer where to store the read object"},{"name":"db","type":"git_odb *","comment":"database to search for the object in."},{"name":"short_id","type":"const git_oid *","comment":"a prefix of the id of the object to read."},{"name":"len","type":"size_t","comment":"the length of the prefix"}],"argline":"git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len","sig":"git_odb_object **::git_odb *::const git_oid *::size_t","return":{"type":"int","comment":" - 0 if the object was read;\n - GIT_ENOTFOUND if the object is not in the database.\n - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)"},"description":"

Read an object from the database, given a prefix\n of its identifier.

\n","comments":"

This method queries all available ODB backends\n trying to match the 'len' first hexadecimal\n characters of the 'short_id'.\n The remaining (GIT_OID_HEXSZ-len)*4 bits of\n 'short_id' must be 0s.\n 'len' must be at least GIT_OID_MINPREFIXLEN,\n and the prefix must be long enough to identify\n a unique object in all the backends; the\n method will fail otherwise.

\n\n

The returned object is reference counted and\n internally cached, so it should be closed\n by the user once it's no longer in use.

\n","group":"odb"},"git_odb_read_header":{"type":"function","file":"odb.h","line":148,"lineto":148,"args":[{"name":"len_out","type":"size_t *","comment":"pointer where to store the length"},{"name":"type_out","type":"git_otype *","comment":"pointer where to store the type"},{"name":"db","type":"git_odb *","comment":"database to search for the object in."},{"name":"id","type":"const git_oid *","comment":"identity of the object to read."}],"argline":"size_t *len_out, git_otype *type_out, git_odb *db, const git_oid *id","sig":"size_t *::git_otype *::git_odb *::const git_oid *","return":{"type":"int","comment":" - 0 if the object was read;\n - GIT_ENOTFOUND if the object is not in the database."},"description":"

Read the header of an object from the database, without\n reading its full contents.

\n","comments":"

The header includes the length and the type of an object.

\n\n

Note that most backends do not support reading only the header\n of an object, so the whole object will be read and then the\n header will be returned.

\n","group":"odb"},"git_odb_exists":{"type":"function","file":"odb.h","line":159,"lineto":159,"args":[{"name":"db","type":"git_odb *","comment":"database to be searched for the given object."},{"name":"id","type":"const git_oid *","comment":"the object to search for."}],"argline":"git_odb *db, const git_oid *id","sig":"git_odb *::const git_oid *","return":{"type":"int","comment":" - 1, if the object was found\n - 0, otherwise"},"description":"

Determine if the given object can be found in the object database.

\n","comments":"","group":"odb"},"git_odb_exists_prefix":{"type":"function","file":"odb.h","line":171,"lineto":172,"args":[{"name":"out","type":"git_oid *","comment":"The full OID of the found object if just one is found."},{"name":"db","type":"git_odb *","comment":"The database to be searched for the given object."},{"name":"short_id","type":"const git_oid *","comment":"A prefix of the id of the object to read."},{"name":"len","type":"size_t","comment":"The length of the prefix."}],"argline":"git_oid *out, git_odb *db, const git_oid *short_id, size_t len","sig":"git_oid *::git_odb *::const git_oid *::size_t","return":{"type":"int","comment":" 0 if found, GIT_ENOTFOUND if not found, GIT_EAMBIGUOUS if multiple\n matches were found, other value \n<\n 0 if there was a read error."},"description":"

Determine if objects can be found in the object database from a short OID.

\n","comments":"","group":"odb"},"git_odb_refresh":{"type":"function","file":"odb.h","line":192,"lineto":192,"args":[{"name":"db","type":"struct git_odb *","comment":"database to refresh"}],"argline":"struct git_odb *db","sig":"struct git_odb *","return":{"type":"int","comment":" 0 on success, error code otherwise"},"description":"

Refresh the object database to load newly added files.

\n","comments":"

If the object databases have changed on disk while the library\n is running, this function will force a reload of the underlying\n indexes.

\n\n

Use this function when you're confident that an external\n application has tampered with the ODB.

\n\n

NOTE that it is not necessary to call this function at all. The\n library will automatically attempt to refresh the ODB\n when a lookup fails, to see if the looked up object exists\n on disk but hasn't been loaded yet.

\n","group":"odb"},"git_odb_foreach":{"type":"function","file":"odb.h","line":207,"lineto":207,"args":[{"name":"db","type":"git_odb *","comment":"database to use"},{"name":"cb","type":"git_odb_foreach_cb","comment":"the callback to call for each object"},{"name":"payload","type":"void *","comment":"data to pass to the callback"}],"argline":"git_odb *db, git_odb_foreach_cb cb, void *payload","sig":"git_odb *::git_odb_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

List all objects available in the database

\n","comments":"

The callback will be called for each object available in the\n database. Note that the objects are likely to be returned in the index\n order, which would make accessing the objects in that order inefficient.\n Return a non-zero value from the callback to stop looping.

\n","group":"odb"},"git_odb_write":{"type":"function","file":"odb.h","line":227,"lineto":227,"args":[{"name":"out","type":"git_oid *","comment":"pointer to store the OID result of the write"},{"name":"odb","type":"git_odb *","comment":"object database where to store the object"},{"name":"data","type":"const void *","comment":"buffer with the data to store"},{"name":"len","type":"size_t","comment":"size of the buffer"},{"name":"type","type":"git_otype","comment":"type of the data to store"}],"argline":"git_oid *out, git_odb *odb, const void *data, size_t len, git_otype type","sig":"git_oid *::git_odb *::const void *::size_t::git_otype","return":{"type":"int","comment":" 0 or an error code"},"description":"

Write an object directly into the ODB

\n","comments":"

This method writes a full object straight into the ODB.\n For most cases, it is preferred to write objects through a write\n stream, which is both faster and less memory intensive, specially\n for big objects.

\n\n

This method is provided for compatibility with custom backends\n which are not able to support streaming writes

\n","group":"odb","examples":{"general.c":["ex/v0.21.2/general.html#git_odb_write-34"]}},"git_odb_open_wstream":{"type":"function","file":"odb.h","line":250,"lineto":250,"args":[{"name":"out","type":"git_odb_stream **","comment":"pointer where to store the stream"},{"name":"db","type":"git_odb *","comment":"object database where the stream will write"},{"name":"size","type":"size_t","comment":"final size of the object that will be written"},{"name":"type","type":"git_otype","comment":"type of the object that will be written"}],"argline":"git_odb_stream **out, git_odb *db, size_t size, git_otype type","sig":"git_odb_stream **::git_odb *::size_t::git_otype","return":{"type":"int","comment":" 0 if the stream was created; error code otherwise"},"description":"

Open a stream to write an object into the ODB

\n","comments":"

The type and final length of the object must be specified\n when opening the stream.

\n\n

The returned stream will be of type GIT_STREAM_WRONLY, and it\n won't be effective until git_odb_stream_finalize_write is called\n and returns without an error

\n\n

The stream must always be freed when done with git_odb_stream_free or\n will leak memory.

\n","group":"odb"},"git_odb_stream_write":{"type":"function","file":"odb.h","line":263,"lineto":263,"args":[{"name":"stream","type":"git_odb_stream *","comment":"the stream"},{"name":"buffer","type":"const char *","comment":"the data to write"},{"name":"len","type":"size_t","comment":"the buffer's length"}],"argline":"git_odb_stream *stream, const char *buffer, size_t len","sig":"git_odb_stream *::const char *::size_t","return":{"type":"int","comment":" 0 if the write succeeded; error code otherwise"},"description":"

Write to an odb stream

\n","comments":"

This method will fail if the total number of received bytes exceeds the\n size declared with git_odb_open_wstream()

\n","group":"odb"},"git_odb_stream_finalize_write":{"type":"function","file":"odb.h","line":278,"lineto":278,"args":[{"name":"out","type":"git_oid *","comment":"pointer to store the resulting object's id"},{"name":"stream","type":"git_odb_stream *","comment":"the stream"}],"argline":"git_oid *out, git_odb_stream *stream","sig":"git_oid *::git_odb_stream *","return":{"type":"int","comment":" 0 on success; an error code otherwise"},"description":"

Finish writing to an odb stream

\n","comments":"

The object will take its final name and will be available to the\n odb.

\n\n

This method will fail if the total number of received bytes\n differs from the size declared with git_odb_open_wstream()

\n","group":"odb"},"git_odb_stream_read":{"type":"function","file":"odb.h","line":285,"lineto":285,"args":[{"name":"stream","type":"git_odb_stream *","comment":null},{"name":"buffer","type":"char *","comment":null},{"name":"len","type":"size_t","comment":null}],"argline":"git_odb_stream *stream, char *buffer, size_t len","sig":"git_odb_stream *::char *::size_t","return":{"type":"int","comment":null},"description":"

Read from an odb stream

\n","comments":"

Most backends don't implement streaming reads

\n","group":"odb"},"git_odb_stream_free":{"type":"function","file":"odb.h","line":292,"lineto":292,"args":[{"name":"stream","type":"git_odb_stream *","comment":"the stream to free"}],"argline":"git_odb_stream *stream","sig":"git_odb_stream *","return":{"type":"void","comment":null},"description":"

Free an odb stream

\n","comments":"","group":"odb"},"git_odb_open_rstream":{"type":"function","file":"odb.h","line":318,"lineto":318,"args":[{"name":"out","type":"git_odb_stream **","comment":"pointer where to store the stream"},{"name":"db","type":"git_odb *","comment":"object database where the stream will read from"},{"name":"oid","type":"const git_oid *","comment":"oid of the object the stream will read from"}],"argline":"git_odb_stream **out, git_odb *db, const git_oid *oid","sig":"git_odb_stream **::git_odb *::const git_oid *","return":{"type":"int","comment":" 0 if the stream was created; error code otherwise"},"description":"

Open a stream to read an object from the ODB

\n","comments":"

Note that most backends do not support streaming reads\n because they store their objects as compressed/delta'ed blobs.

\n\n

It's recommended to use git_odb_read instead, which is\n assured to work on all backends.

\n\n

The returned stream will be of type GIT_STREAM_RDONLY and\n will have the following methods:

\n\n
    - stream->read: read `n` bytes from the stream\n    - stream->free: free the stream\n
\n\n

The stream must always be free'd or will leak memory.

\n","group":"odb"},"git_odb_write_pack":{"type":"function","file":"odb.h","line":338,"lineto":342,"args":[{"name":"out","type":"git_odb_writepack **","comment":"pointer to the writepack functions"},{"name":"db","type":"git_odb *","comment":"object database where the stream will read from"},{"name":"progress_cb","type":"git_transfer_progress_cb","comment":"function to call with progress information.\n Be aware that this is called inline with network and indexing operations,\n so performance may be affected."},{"name":"progress_payload","type":"void *","comment":"payload for the progress callback"}],"argline":"git_odb_writepack **out, git_odb *db, git_transfer_progress_cb progress_cb, void *progress_payload","sig":"git_odb_writepack **::git_odb *::git_transfer_progress_cb::void *","return":{"type":"int","comment":null},"description":"

Open a stream for writing a pack file to the ODB.

\n","comments":"

If the ODB layer understands pack files, then the given\n packfile will likely be streamed directly to disk (and a\n corresponding index created). If the ODB layer does not\n understand pack files, the objects will be stored in whatever\n format the ODB layer uses.

\n","group":"odb"},"git_odb_hash":{"type":"function","file":"odb.h","line":356,"lineto":356,"args":[{"name":"out","type":"git_oid *","comment":"the resulting object-ID."},{"name":"data","type":"const void *","comment":"data to hash"},{"name":"len","type":"size_t","comment":"size of the data"},{"name":"type","type":"git_otype","comment":"of the data to hash"}],"argline":"git_oid *out, const void *data, size_t len, git_otype type","sig":"git_oid *::const void *::size_t::git_otype","return":{"type":"int","comment":" 0 or an error code"},"description":"

Determine the object-ID (sha1 hash) of a data buffer

\n","comments":"

The resulting SHA-1 OID will be the identifier for the data\n buffer as if the data buffer it were to written to the ODB.

\n","group":"odb"},"git_odb_hashfile":{"type":"function","file":"odb.h","line":371,"lineto":371,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"path","type":"const char *","comment":"file to read and determine object id for"},{"name":"type","type":"git_otype","comment":"the type of the object that will be hashed"}],"argline":"git_oid *out, const char *path, git_otype type","sig":"git_oid *::const char *::git_otype","return":{"type":"int","comment":" 0 or an error code"},"description":"

Read a file from disk and fill a git_oid with the object id\n that the file would have if it were written to the Object\n Database as an object of the given type (w/o applying filters).\n Similar functionality to git.git's git hash-object without\n the -w flag, however, with the --no-filters flag.\n If you need filters, see git_repository_hashfile.

\n","comments":"","group":"odb"},"git_odb_object_dup":{"type":"function","file":"odb.h","line":385,"lineto":385,"args":[{"name":"dest","type":"git_odb_object **","comment":"pointer where to store the copy"},{"name":"source","type":"git_odb_object *","comment":"object to copy"}],"argline":"git_odb_object **dest, git_odb_object *source","sig":"git_odb_object **::git_odb_object *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a copy of an odb_object

\n","comments":"

The returned copy must be manually freed with git_odb_object_free.\n Note that because of an implementation detail, the returned copy will be\n the same pointer as source: the object is internally refcounted, so the\n copy still needs to be freed twice.

\n","group":"odb"},"git_odb_object_free":{"type":"function","file":"odb.h","line":395,"lineto":395,"args":[{"name":"object","type":"git_odb_object *","comment":"object to close"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"void","comment":null},"description":"

Close an ODB object

\n","comments":"

This method must always be called once a git_odb_object is no\n longer needed, otherwise memory will leak.

\n","group":"odb","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_odb_object_free-22"],"general.c":["ex/v0.21.2/general.html#git_odb_object_free-35"]}},"git_odb_object_id":{"type":"function","file":"odb.h","line":405,"lineto":405,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"const git_oid *","comment":" a pointer to the OID"},"description":"

Return the OID of an ODB object

\n","comments":"

This is the OID from which the object was read from

\n","group":"odb"},"git_odb_object_data":{"type":"function","file":"odb.h","line":418,"lineto":418,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"const void *","comment":" a pointer to the data"},"description":"

Return the data of an ODB object

\n","comments":"

This is the uncompressed, raw data as read from the ODB,\n without the leading header.

\n\n

This pointer is owned by the object and shall not be free'd.

\n","group":"odb","examples":{"general.c":["ex/v0.21.2/general.html#git_odb_object_data-36"]}},"git_odb_object_size":{"type":"function","file":"odb.h","line":429,"lineto":429,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"size_t","comment":" the size"},"description":"

Return the size of an ODB object

\n","comments":"

This is the real size of the data buffer, not the\n actual size of the object.

\n","group":"odb","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_odb_object_size-23"],"general.c":["ex/v0.21.2/general.html#git_odb_object_size-37"]}},"git_odb_object_type":{"type":"function","file":"odb.h","line":437,"lineto":437,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"git_otype","comment":" the type"},"description":"

Return the type of an ODB object

\n","comments":"","group":"odb","examples":{"general.c":["ex/v0.21.2/general.html#git_odb_object_type-38"]}},"git_odb_add_backend":{"type":"function","file":"odb.h","line":452,"lineto":452,"args":[{"name":"odb","type":"git_odb *","comment":"database to add the backend to"},{"name":"backend","type":"git_odb_backend *","comment":"pointer to a git_odb_backend instance"},{"name":"priority","type":"int","comment":"Value for ordering the backends queue"}],"argline":"git_odb *odb, git_odb_backend *backend, int priority","sig":"git_odb *::git_odb_backend *::int","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"

Add a custom backend to an existing Object DB

\n","comments":"

The backends are checked in relative ordering, based on the\n value of the priority parameter.

\n\n

Read \n for more information.

\n","group":"odb"},"git_odb_add_alternate":{"type":"function","file":"odb.h","line":473,"lineto":473,"args":[{"name":"odb","type":"git_odb *","comment":"database to add the backend to"},{"name":"backend","type":"git_odb_backend *","comment":"pointer to a git_odb_backend instance"},{"name":"priority","type":"int","comment":"Value for ordering the backends queue"}],"argline":"git_odb *odb, git_odb_backend *backend, int priority","sig":"git_odb *::git_odb_backend *::int","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"

Add a custom backend to an existing Object DB; this\n backend will work as an alternate.

\n","comments":"

Alternate backends are always checked for objects after\n all the main backends have been exhausted.

\n\n

The backends are checked in relative ordering, based on the\n value of the priority parameter.

\n\n

Writing is disabled on alternate backends.

\n\n

Read \n for more information.

\n","group":"odb"},"git_odb_num_backends":{"type":"function","file":"odb.h","line":481,"lineto":481,"args":[{"name":"odb","type":"git_odb *","comment":"object database"}],"argline":"git_odb *odb","sig":"git_odb *","return":{"type":"size_t","comment":" number of backends in the ODB"},"description":"

Get the number of ODB backend objects

\n","comments":"","group":"odb"},"git_odb_get_backend":{"type":"function","file":"odb.h","line":491,"lineto":491,"args":[{"name":"out","type":"git_odb_backend **","comment":"output pointer to ODB backend at pos"},{"name":"odb","type":"git_odb *","comment":"object database"},{"name":"pos","type":"size_t","comment":"index into object database backend list"}],"argline":"git_odb_backend **out, git_odb *odb, size_t pos","sig":"git_odb_backend **::git_odb *::size_t","return":{"type":"int","comment":" 0 on success; GIT_ENOTFOUND if pos is invalid; other errors \n<\n 0"},"description":"

Lookup an ODB backend object by index

\n","comments":"","group":"odb"},"git_odb_backend_pack":{"type":"function","file":"odb_backend.h","line":34,"lineto":34,"args":[{"name":"out","type":"git_odb_backend **","comment":"location to store the odb backend pointer"},{"name":"objects_dir","type":"const char *","comment":"the Git repository's objects directory"}],"argline":"git_odb_backend **out, const char *objects_dir","sig":"git_odb_backend **::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a backend for the packfiles.

\n","comments":"","group":"odb"},"git_odb_backend_loose":{"type":"function","file":"odb_backend.h","line":48,"lineto":54,"args":[{"name":"out","type":"git_odb_backend **","comment":"location to store the odb backend pointer"},{"name":"objects_dir","type":"const char *","comment":"the Git repository's objects directory"},{"name":"compression_level","type":"int","comment":"zlib compression level to use"},{"name":"do_fsync","type":"int","comment":"whether to do an fsync() after writing (currently ignored)"},{"name":"dir_mode","type":"unsigned int","comment":"permissions to use creating a directory or 0 for defaults"},{"name":"file_mode","type":"unsigned int","comment":"permissions to use creating a file or 0 for defaults"}],"argline":"git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync, unsigned int dir_mode, unsigned int file_mode","sig":"git_odb_backend **::const char *::int::int::unsigned int::unsigned int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a backend for loose objects

\n","comments":"","group":"odb"},"git_odb_backend_one_pack":{"type":"function","file":"odb_backend.h","line":67,"lineto":67,"args":[{"name":"out","type":"git_odb_backend **","comment":"location to store the odb backend pointer"},{"name":"index_file","type":"const char *","comment":"path to the packfile's .idx file"}],"argline":"git_odb_backend **out, const char *index_file","sig":"git_odb_backend **::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a backend out of a single packfile

\n","comments":"

This can be useful for inspecting the contents of a single\n packfile.

\n","group":"odb"},"git_oid_fromstr":{"type":"function","file":"oid.h","line":47,"lineto":47,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"str","type":"const char *","comment":"input hex string; must be pointing at the start of\n\t\tthe hex sequence and have at least the number of bytes\n\t\tneeded for an oid encoded in hex (40 bytes)."}],"argline":"git_oid *out, const char *str","sig":"git_oid *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Parse a hex formatted object id into a git_oid.

\n","comments":"","group":"oid","examples":{"general.c":["ex/v0.21.2/general.html#git_oid_fromstr-39","ex/v0.21.2/general.html#git_oid_fromstr-40","ex/v0.21.2/general.html#git_oid_fromstr-41","ex/v0.21.2/general.html#git_oid_fromstr-42","ex/v0.21.2/general.html#git_oid_fromstr-43","ex/v0.21.2/general.html#git_oid_fromstr-44","ex/v0.21.2/general.html#git_oid_fromstr-45","ex/v0.21.2/general.html#git_oid_fromstr-46"]}},"git_oid_fromstrp":{"type":"function","file":"oid.h","line":57,"lineto":57,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"str","type":"const char *","comment":"input hex string; must be at least 4 characters\n long and null-terminated."}],"argline":"git_oid *out, const char *str","sig":"git_oid *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Parse a hex formatted null-terminated string into a git_oid.

\n","comments":"","group":"oid"},"git_oid_fromstrn":{"type":"function","file":"oid.h","line":70,"lineto":70,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"str","type":"const char *","comment":"input hex string of at least size `length`"},{"name":"length","type":"size_t","comment":"length of the input string"}],"argline":"git_oid *out, const char *str, size_t length","sig":"git_oid *::const char *::size_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Parse N characters of a hex formatted object id into a git_oid

\n","comments":"

If N is odd, N-1 characters will be parsed instead.\n The remaining space in the git_oid will be set to zero.

\n","group":"oid"},"git_oid_fromraw":{"type":"function","file":"oid.h","line":78,"lineto":78,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"raw","type":"const unsigned char *","comment":"the raw input bytes to be copied."}],"argline":"git_oid *out, const unsigned char *raw","sig":"git_oid *::const unsigned char *","return":{"type":"void","comment":null},"description":"

Copy an already raw oid into a git_oid structure.

\n","comments":"","group":"oid"},"git_oid_fmt":{"type":"function","file":"oid.h","line":90,"lineto":90,"args":[{"name":"out","type":"char *","comment":"output hex string; must be pointing at the start of\n\t\tthe hex sequence and have at least the number of bytes\n\t\tneeded for an oid encoded in hex (40 bytes). Only the\n\t\toid digits are written; a '\n\\\n0' terminator must be added\n\t\tby the caller if it is required."},{"name":"id","type":"const git_oid *","comment":"oid structure to format."}],"argline":"char *out, const git_oid *id","sig":"char *::const git_oid *","return":{"type":"void","comment":null},"description":"

Format a git_oid into a hex string.

\n","comments":"","group":"oid","examples":{"general.c":["ex/v0.21.2/general.html#git_oid_fmt-47","ex/v0.21.2/general.html#git_oid_fmt-48","ex/v0.21.2/general.html#git_oid_fmt-49","ex/v0.21.2/general.html#git_oid_fmt-50","ex/v0.21.2/general.html#git_oid_fmt-51"],"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_oid_fmt-1","ex/v0.21.2/network/fetch.html#git_oid_fmt-2"],"network/index-pack.c":["ex/v0.21.2/network/index-pack.html#git_oid_fmt-6"],"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_oid_fmt-1"]}},"git_oid_nfmt":{"type":"function","file":"oid.h","line":101,"lineto":101,"args":[{"name":"out","type":"char *","comment":"output hex string; you say how many bytes to write.\n\t\tIf the number of bytes is > GIT_OID_HEXSZ, extra bytes\n\t\twill be zeroed; if not, a '\n\\\n0' terminator is NOT added."},{"name":"n","type":"size_t","comment":"number of characters to write into out string"},{"name":"id","type":"const git_oid *","comment":"oid structure to format."}],"argline":"char *out, size_t n, const git_oid *id","sig":"char *::size_t::const git_oid *","return":{"type":"void","comment":null},"description":"

Format a git_oid into a partial hex string.

\n","comments":"","group":"oid"},"git_oid_pathfmt":{"type":"function","file":"oid.h","line":116,"lineto":116,"args":[{"name":"out","type":"char *","comment":"output hex string; must be pointing at the start of\n\t\tthe hex sequence and have at least the number of bytes\n\t\tneeded for an oid encoded in hex (41 bytes). Only the\n\t\toid digits are written; a '\n\\\n0' terminator must be added\n\t\tby the caller if it is required."},{"name":"id","type":"const git_oid *","comment":"oid structure to format."}],"argline":"char *out, const git_oid *id","sig":"char *::const git_oid *","return":{"type":"void","comment":null},"description":"

Format a git_oid into a loose-object path string.

\n","comments":"

The resulting string is "aa/...", where "aa" is the first two\n hex digits of the oid and "..." is the remaining 38 digits.

\n","group":"oid"},"git_oid_allocfmt":{"type":"function","file":"oid.h","line":125,"lineto":125,"args":[{"name":"id","type":"const git_oid *","comment":"the oid structure to format"}],"argline":"const git_oid *id","sig":"const git_oid *","return":{"type":"char *","comment":" the c-string; NULL if memory is exhausted. Caller must\n\t\t\tdeallocate the string with git__free()."},"description":"

Format a git_oid into a newly allocated c-string.

\n","comments":"","group":"oid"},"git_oid_tostr":{"type":"function","file":"oid.h","line":144,"lineto":144,"args":[{"name":"out","type":"char *","comment":"the buffer into which the oid string is output."},{"name":"n","type":"size_t","comment":"the size of the out buffer."},{"name":"id","type":"const git_oid *","comment":"the oid structure to format."}],"argline":"char *out, size_t n, const git_oid *id","sig":"char *::size_t::const git_oid *","return":{"type":"char *","comment":" the out buffer pointer, assuming no input parameter\n\t\t\terrors, otherwise a pointer to an empty string."},"description":"

Format a git_oid into a buffer as a hex format c-string.

\n","comments":"

If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting\n oid c-string will be truncated to n-1 characters (but will still be\n NUL-byte terminated).

\n\n

If there are any input parameter errors (out == NULL, n == 0, oid ==\n NULL), then a pointer to an empty string is returned, so that the\n return value can always be printed.

\n","group":"oid","examples":{"blame.c":["ex/v0.21.2/blame.html#git_oid_tostr-16","ex/v0.21.2/blame.html#git_oid_tostr-17"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_oid_tostr-24","ex/v0.21.2/cat-file.html#git_oid_tostr-25","ex/v0.21.2/cat-file.html#git_oid_tostr-26","ex/v0.21.2/cat-file.html#git_oid_tostr-27","ex/v0.21.2/cat-file.html#git_oid_tostr-28"],"log.c":["ex/v0.21.2/log.html#git_oid_tostr-37","ex/v0.21.2/log.html#git_oid_tostr-38"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_oid_tostr-10","ex/v0.21.2/rev-parse.html#git_oid_tostr-11","ex/v0.21.2/rev-parse.html#git_oid_tostr-12","ex/v0.21.2/rev-parse.html#git_oid_tostr-13"]}},"git_oid_cpy":{"type":"function","file":"oid.h","line":152,"lineto":152,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"src","type":"const git_oid *","comment":"oid structure to copy from."}],"argline":"git_oid *out, const git_oid *src","sig":"git_oid *::const git_oid *","return":{"type":"void","comment":null},"description":"

Copy an oid from one structure to another.

\n","comments":"","group":"oid","examples":{"blame.c":["ex/v0.21.2/blame.html#git_oid_cpy-18","ex/v0.21.2/blame.html#git_oid_cpy-19","ex/v0.21.2/blame.html#git_oid_cpy-20"]}},"git_oid_cmp":{"type":"function","file":"oid.h","line":161,"lineto":161,"args":[{"name":"a","type":"const git_oid *","comment":"first oid structure."},{"name":"b","type":"const git_oid *","comment":"second oid structure."}],"argline":"const git_oid *a, const git_oid *b","sig":"const git_oid *::const git_oid *","return":{"type":"int","comment":" \n<\n0, 0, >0 if a \n<\n b, a == b, a > b."},"description":"

Compare two oid structures.

\n","comments":"","group":"oid"},"git_oid_equal":{"type":"function","file":"oid.h","line":170,"lineto":170,"args":[{"name":"a","type":"const git_oid *","comment":"first oid structure."},{"name":"b","type":"const git_oid *","comment":"second oid structure."}],"argline":"const git_oid *a, const git_oid *b","sig":"const git_oid *::const git_oid *","return":{"type":"int","comment":" true if equal, false otherwise"},"description":"

Compare two oid structures for equality

\n","comments":"","group":"oid"},"git_oid_ncmp":{"type":"function","file":"oid.h","line":181,"lineto":181,"args":[{"name":"a","type":"const git_oid *","comment":"first oid structure."},{"name":"b","type":"const git_oid *","comment":"second oid structure."},{"name":"len","type":"size_t","comment":"the number of hex chars to compare"}],"argline":"const git_oid *a, const git_oid *b, size_t len","sig":"const git_oid *::const git_oid *::size_t","return":{"type":"int","comment":" 0 in case of a match"},"description":"

Compare the first 'len' hexadecimal characters (packets of 4 bits)\n of two oid structures.

\n","comments":"","group":"oid"},"git_oid_streq":{"type":"function","file":"oid.h","line":190,"lineto":190,"args":[{"name":"id","type":"const git_oid *","comment":"oid structure."},{"name":"str","type":"const char *","comment":"input hex string of an object id."}],"argline":"const git_oid *id, const char *str","sig":"const git_oid *::const char *","return":{"type":"int","comment":" 0 in case of a match, -1 otherwise."},"description":"

Check if an oid equals an hex formatted object id.

\n","comments":"","group":"oid"},"git_oid_strcmp":{"type":"function","file":"oid.h","line":200,"lineto":200,"args":[{"name":"id","type":"const git_oid *","comment":"oid structure."},{"name":"str","type":"const char *","comment":"input hex string of an object id."}],"argline":"const git_oid *id, const char *str","sig":"const git_oid *::const char *","return":{"type":"int","comment":" -1 if str is not valid, \n<\n0 if id sorts before str,\n 0 if id matches str, >0 if id sorts after str."},"description":"

Compare an oid to an hex formatted object id.

\n","comments":"","group":"oid"},"git_oid_iszero":{"type":"function","file":"oid.h","line":207,"lineto":207,"args":[{"name":"id","type":"const git_oid *","comment":null}],"argline":"const git_oid *id","sig":"const git_oid *","return":{"type":"int","comment":" 1 if all zeros, 0 otherwise."},"description":"

Check is an oid is all zeros.

\n","comments":"","group":"oid","examples":{"blame.c":["ex/v0.21.2/blame.html#git_oid_iszero-21"],"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_oid_iszero-3"]}},"git_oid_shorten_new":{"type":"function","file":"oid.h","line":228,"lineto":228,"args":[{"name":"min_length","type":"size_t","comment":"The minimal length for all identifiers,\n\t\twhich will be used even if shorter OIDs would still\n\t\tbe unique."}],"argline":"size_t min_length","sig":"size_t","return":{"type":"git_oid_shorten *","comment":" a `git_oid_shorten` instance, NULL if OOM"},"description":"

Create a new OID shortener.

\n","comments":"

The OID shortener is used to process a list of OIDs\n in text form and return the shortest length that would\n uniquely identify all of them.

\n\n

E.g. look at the result of git log --abbrev.

\n","group":"oid"},"git_oid_shorten_add":{"type":"function","file":"oid.h","line":254,"lineto":254,"args":[{"name":"os","type":"git_oid_shorten *","comment":"a `git_oid_shorten` instance"},{"name":"text_id","type":"const char *","comment":"an OID in text form"}],"argline":"git_oid_shorten *os, const char *text_id","sig":"git_oid_shorten *::const char *","return":{"type":"int","comment":" the minimal length to uniquely identify all OIDs\n\t\tadded so far to the set; or an error code (\n<\n0) if an\n\t\terror occurs."},"description":"

Add a new OID to set of shortened OIDs and calculate\n the minimal length to uniquely identify all the OIDs in\n the set.

\n","comments":"

The OID is expected to be a 40-char hexadecimal string.\n The OID is owned by the user and will not be modified\n or freed.

\n\n

For performance reasons, there is a hard-limit of how many\n OIDs can be added to a single set (around ~32000, assuming\n a mostly randomized distribution), which should be enough\n for any kind of program, and keeps the algorithm fast and\n memory-efficient.

\n\n

Attempting to add more than those OIDs will result in a\n GITERR_INVALID error

\n","group":"oid"},"git_oid_shorten_free":{"type":"function","file":"oid.h","line":261,"lineto":261,"args":[{"name":"os","type":"git_oid_shorten *","comment":"a `git_oid_shorten` instance"}],"argline":"git_oid_shorten *os","sig":"git_oid_shorten *","return":{"type":"void","comment":null},"description":"

Free an OID shortener instance

\n","comments":"","group":"oid"},"git_packbuilder_new":{"type":"function","file":"pack.h","line":64,"lineto":64,"args":[{"name":"out","type":"git_packbuilder **","comment":"The new packbuilder object"},{"name":"repo","type":"git_repository *","comment":"The repository"}],"argline":"git_packbuilder **out, git_repository *repo","sig":"git_packbuilder **::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Initialize a new packbuilder

\n","comments":"","group":"packbuilder"},"git_packbuilder_set_threads":{"type":"function","file":"pack.h","line":77,"lineto":77,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder"},{"name":"n","type":"unsigned int","comment":"Number of threads to spawn"}],"argline":"git_packbuilder *pb, unsigned int n","sig":"git_packbuilder *::unsigned int","return":{"type":"unsigned int","comment":" number of actual threads to be used"},"description":"

Set number of threads to spawn

\n","comments":"

By default, libgit2 won't spawn any threads at all;\n when set to 0, libgit2 will autodetect the number of\n CPUs.

\n","group":"packbuilder"},"git_packbuilder_insert":{"type":"function","file":"pack.h","line":91,"lineto":91,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder"},{"name":"id","type":"const git_oid *","comment":"The oid of the commit"},{"name":"name","type":"const char *","comment":"The name; might be NULL"}],"argline":"git_packbuilder *pb, const git_oid *id, const char *name","sig":"git_packbuilder *::const git_oid *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Insert a single object

\n","comments":"

For an optimal pack it's mandatory to insert objects in recency order,\n commits followed by trees and blobs.

\n","group":"packbuilder"},"git_packbuilder_insert_tree":{"type":"function","file":"pack.h","line":103,"lineto":103,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder"},{"name":"id","type":"const git_oid *","comment":"The oid of the root tree"}],"argline":"git_packbuilder *pb, const git_oid *id","sig":"git_packbuilder *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Insert a root tree object

\n","comments":"

This will add the tree as well as all referenced trees and blobs.

\n","group":"packbuilder"},"git_packbuilder_insert_commit":{"type":"function","file":"pack.h","line":115,"lineto":115,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder"},{"name":"id","type":"const git_oid *","comment":"The oid of the commit"}],"argline":"git_packbuilder *pb, const git_oid *id","sig":"git_packbuilder *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Insert a commit object

\n","comments":"

This will add a commit as well as the completed referenced tree.

\n","group":"packbuilder"},"git_packbuilder_write":{"type":"function","file":"pack.h","line":139,"lineto":144,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder"},{"name":"path","type":"const char *","comment":"to the directory where the packfile and index should be stored"},{"name":"mode","type":"unsigned int","comment":"permissions to use creating a packfile or 0 for defaults"},{"name":"progress_cb","type":"git_transfer_progress_cb","comment":"function to call with progress information from the indexer (optional)"},{"name":"progress_cb_payload","type":"void *","comment":"payload for the progress callback (optional)"}],"argline":"git_packbuilder *pb, const char *path, unsigned int mode, git_transfer_progress_cb progress_cb, void *progress_cb_payload","sig":"git_packbuilder *::const char *::unsigned int::git_transfer_progress_cb::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Write the new pack and corresponding index file to path.

\n","comments":"","group":"packbuilder"},"git_packbuilder_hash":{"type":"function","file":"pack.h","line":154,"lineto":154,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder object"}],"argline":"git_packbuilder *pb","sig":"git_packbuilder *","return":{"type":"const git_oid *","comment":null},"description":"

Get the packfile's hash

\n","comments":"

A packfile's name is derived from the sorted hashing of all object\n names. This is only correct after the packfile has been written.

\n","group":"packbuilder"},"git_packbuilder_foreach":{"type":"function","file":"pack.h","line":166,"lineto":166,"args":[{"name":"pb","type":"git_packbuilder *","comment":"the packbuilder"},{"name":"cb","type":"git_packbuilder_foreach_cb","comment":"the callback to call with each packed object's buffer"},{"name":"payload","type":"void *","comment":"the callback's data"}],"argline":"git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload","sig":"git_packbuilder *::git_packbuilder_foreach_cb::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create the new pack and pass each object to the callback

\n","comments":"","group":"packbuilder"},"git_packbuilder_object_count":{"type":"function","file":"pack.h","line":174,"lineto":174,"args":[{"name":"pb","type":"git_packbuilder *","comment":"the packbuilder"}],"argline":"git_packbuilder *pb","sig":"git_packbuilder *","return":{"type":"uint32_t","comment":" the number of objects in the packfile"},"description":"

Get the total number of objects the packbuilder will write out

\n","comments":"","group":"packbuilder"},"git_packbuilder_written":{"type":"function","file":"pack.h","line":182,"lineto":182,"args":[{"name":"pb","type":"git_packbuilder *","comment":"the packbuilder"}],"argline":"git_packbuilder *pb","sig":"git_packbuilder *","return":{"type":"uint32_t","comment":" the number of objects which have already been written"},"description":"

Get the number of objects the packbuilder has already written out

\n","comments":"","group":"packbuilder"},"git_packbuilder_set_callbacks":{"type":"function","file":"pack.h","line":201,"lineto":204,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder object"},{"name":"progress_cb","type":"git_packbuilder_progress","comment":"Function to call with progress information during\n pack building. Be aware that this is called inline with pack building\n operations, so performance may be affected."},{"name":"progress_cb_payload","type":"void *","comment":"Payload for progress callback."}],"argline":"git_packbuilder *pb, git_packbuilder_progress progress_cb, void *progress_cb_payload","sig":"git_packbuilder *::git_packbuilder_progress::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the callbacks for a packbuilder

\n","comments":"","group":"packbuilder"},"git_packbuilder_free":{"type":"function","file":"pack.h","line":211,"lineto":211,"args":[{"name":"pb","type":"git_packbuilder *","comment":"The packbuilder"}],"argline":"git_packbuilder *pb","sig":"git_packbuilder *","return":{"type":"void","comment":null},"description":"

Free the packbuilder and all associated data

\n","comments":"","group":"packbuilder"},"git_patch_from_diff":{"type":"function","file":"patch.h","line":55,"lineto":56,"args":[{"name":"out","type":"git_patch **","comment":"Output parameter for the delta patch object"},{"name":"diff","type":"git_diff *","comment":"Diff list object"},{"name":"idx","type":"size_t","comment":"Index into diff list"}],"argline":"git_patch **out, git_diff *diff, size_t idx","sig":"git_patch **::git_diff *::size_t","return":{"type":"int","comment":" 0 on success, other value \n<\n 0 on error"},"description":"

Return the diff delta and patch for an entry in the diff list.

\n","comments":"

The git_patch is a newly created object contains the text diffs\n for the delta. You have to call git_patch_free() when you are\n done with it. You can use the patch object to loop over all the hunks\n and lines in the diff of the one delta.

\n\n

For an unchanged file or a binary file, no git_patch will be\n created, the output will be set to NULL, and the binary flag will be\n set true in the git_diff_delta structure.

\n\n

The git_diff_delta pointer points to internal data and you do not have\n to release it when you are done with it. It will go away when the\n git_diff and git_patch go away.

\n\n

It is okay to pass NULL for either of the output parameters; if you pass\n NULL for the git_patch, then the text diff will not be calculated.

\n","group":"patch"},"git_patch_from_blobs":{"type":"function","file":"patch.h","line":74,"lineto":80,"args":[{"name":"out","type":"git_patch **","comment":"The generated patch; NULL on error"},{"name":"old_blob","type":"const git_blob *","comment":"Blob for old side of diff, or NULL for empty blob"},{"name":"old_as_path","type":"const char *","comment":"Treat old blob as if it had this filename; can be NULL"},{"name":"new_blob","type":"const git_blob *","comment":"Blob for new side of diff, or NULL for empty blob"},{"name":"new_as_path","type":"const char *","comment":"Treat new blob as if it had this filename; can be NULL"},{"name":"opts","type":"const git_diff_options *","comment":"Options for diff, or NULL for default options"}],"argline":"git_patch **out, const git_blob *old_blob, const char *old_as_path, const git_blob *new_blob, const char *new_as_path, const git_diff_options *opts","sig":"git_patch **::const git_blob *::const char *::const git_blob *::const char *::const git_diff_options *","return":{"type":"int","comment":" 0 on success or error code \n<\n 0"},"description":"

Directly generate a patch from the difference between two blobs.

\n","comments":"

This is just like git_diff_blobs() except it generates a patch object\n for the difference instead of directly making callbacks. You can use the\n standard git_patch accessor functions to read the patch data, and\n you must call git_patch_free() on the patch when done.

\n","group":"patch"},"git_patch_from_blob_and_buffer":{"type":"function","file":"patch.h","line":99,"lineto":106,"args":[{"name":"out","type":"git_patch **","comment":"The generated patch; NULL on error"},{"name":"old_blob","type":"const git_blob *","comment":"Blob for old side of diff, or NULL for empty blob"},{"name":"old_as_path","type":"const char *","comment":"Treat old blob as if it had this filename; can be NULL"},{"name":"buffer","type":"const char *","comment":"Raw data for new side of diff, or NULL for empty"},{"name":"buffer_len","type":"size_t","comment":"Length of raw data for new side of diff"},{"name":"buffer_as_path","type":"const char *","comment":"Treat buffer as if it had this filename; can be NULL"},{"name":"opts","type":"const git_diff_options *","comment":"Options for diff, or NULL for default options"}],"argline":"git_patch **out, const git_blob *old_blob, const char *old_as_path, const char *buffer, size_t buffer_len, const char *buffer_as_path, const git_diff_options *opts","sig":"git_patch **::const git_blob *::const char *::const char *::size_t::const char *::const git_diff_options *","return":{"type":"int","comment":" 0 on success or error code \n<\n 0"},"description":"

Directly generate a patch from the difference between a blob and a buffer.

\n","comments":"

This is just like git_diff_blob_to_buffer() except it generates a patch\n object for the difference instead of directly making callbacks. You can\n use the standard git_patch accessor functions to read the patch\n data, and you must call git_patch_free() on the patch when done.

\n","group":"patch"},"git_patch_from_buffers":{"type":"function","file":"patch.h","line":126,"lineto":134,"args":[{"name":"out","type":"git_patch **","comment":"The generated patch; NULL on error"},{"name":"old_buffer","type":"const void *","comment":"Raw data for old side of diff, or NULL for empty"},{"name":"old_len","type":"size_t","comment":"Length of the raw data for old side of the diff"},{"name":"old_as_path","type":"const char *","comment":"Treat old buffer as if it had this filename; can be NULL"},{"name":"new_buffer","type":"const char *","comment":"Raw data for new side of diff, or NULL for empty"},{"name":"new_len","type":"size_t","comment":"Length of raw data for new side of diff"},{"name":"new_as_path","type":"const char *","comment":"Treat buffer as if it had this filename; can be NULL"},{"name":"opts","type":"const git_diff_options *","comment":"Options for diff, or NULL for default options"}],"argline":"git_patch **out, const void *old_buffer, size_t old_len, const char *old_as_path, const char *new_buffer, size_t new_len, const char *new_as_path, const git_diff_options *opts","sig":"git_patch **::const void *::size_t::const char *::const char *::size_t::const char *::const git_diff_options *","return":{"type":"int","comment":" 0 on success or error code \n<\n 0"},"description":"

Directly generate a patch from the difference between two buffers.

\n","comments":"

This is just like git_diff_buffers() except it generates a patch\n object for the difference instead of directly making callbacks. You can\n use the standard git_patch accessor functions to read the patch\n data, and you must call git_patch_free() on the patch when done.

\n","group":"patch"},"git_patch_free":{"type":"function","file":"patch.h","line":139,"lineto":139,"args":[{"name":"patch","type":"git_patch *","comment":null}],"argline":"git_patch *patch","sig":"git_patch *","return":{"type":"void","comment":null},"description":"

Free a git_patch object.

\n","comments":"","group":"patch"},"git_patch_get_delta":{"type":"function","file":"patch.h","line":144,"lineto":144,"args":[{"name":"patch","type":"const git_patch *","comment":null}],"argline":"const git_patch *patch","sig":"const git_patch *","return":{"type":"const git_diff_delta *","comment":null},"description":"

Get the delta associated with a patch

\n","comments":"","group":"patch"},"git_patch_num_hunks":{"type":"function","file":"patch.h","line":149,"lineto":149,"args":[{"name":"patch","type":"const git_patch *","comment":null}],"argline":"const git_patch *patch","sig":"const git_patch *","return":{"type":"size_t","comment":null},"description":"

Get the number of hunks in a patch

\n","comments":"","group":"patch"},"git_patch_line_stats":{"type":"function","file":"patch.h","line":167,"lineto":171,"args":[{"name":"total_context","type":"size_t *","comment":"Count of context lines in output, can be NULL."},{"name":"total_additions","type":"size_t *","comment":"Count of addition lines in output, can be NULL."},{"name":"total_deletions","type":"size_t *","comment":"Count of deletion lines in output, can be NULL."},{"name":"patch","type":"const git_patch *","comment":"The git_patch object"}],"argline":"size_t *total_context, size_t *total_additions, size_t *total_deletions, const git_patch *patch","sig":"size_t *::size_t *::size_t *::const git_patch *","return":{"type":"int","comment":" 0 on success, \n<\n0 on error"},"description":"

Get line counts of each type in a patch.

\n","comments":"

This helps imitate a diff --numstat type of output. For that purpose,\n you only need the total_additions and total_deletions values, but we\n include the total_context line count in case you want the total number\n of lines of diff output that will be generated.

\n\n

All outputs are optional. Pass NULL if you don't need a particular count.

\n","group":"patch"},"git_patch_get_hunk":{"type":"function","file":"patch.h","line":186,"lineto":190,"args":[{"name":"out","type":"const git_diff_hunk **","comment":"Output pointer to git_diff_hunk of hunk"},{"name":"lines_in_hunk","type":"size_t *","comment":"Output count of total lines in this hunk"},{"name":"patch","type":"git_patch *","comment":"Input pointer to patch object"},{"name":"hunk_idx","type":"size_t","comment":"Input index of hunk to get information about"}],"argline":"const git_diff_hunk **out, size_t *lines_in_hunk, git_patch *patch, size_t hunk_idx","sig":"const git_diff_hunk **::size_t *::git_patch *::size_t","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if hunk_idx out of range, \n<\n0 on error"},"description":"

Get the information about a hunk in a patch

\n","comments":"

Given a patch and a hunk index into the patch, this returns detailed\n information about that hunk. Any of the output pointers can be passed\n as NULL if you don't care about that particular piece of information.

\n","group":"patch"},"git_patch_num_lines_in_hunk":{"type":"function","file":"patch.h","line":199,"lineto":201,"args":[{"name":"patch","type":"const git_patch *","comment":"The git_patch object"},{"name":"hunk_idx","type":"size_t","comment":"Index of the hunk"}],"argline":"const git_patch *patch, size_t hunk_idx","sig":"const git_patch *::size_t","return":{"type":"int","comment":" Number of lines in hunk or -1 if invalid hunk index"},"description":"

Get the number of lines in a hunk.

\n","comments":"","group":"patch"},"git_patch_get_line_in_hunk":{"type":"function","file":"patch.h","line":217,"lineto":221,"args":[{"name":"out","type":"const git_diff_line **","comment":"The git_diff_line data for this line"},{"name":"patch","type":"git_patch *","comment":"The patch to look in"},{"name":"hunk_idx","type":"size_t","comment":"The index of the hunk"},{"name":"line_of_hunk","type":"size_t","comment":"The index of the line in the hunk"}],"argline":"const git_diff_line **out, git_patch *patch, size_t hunk_idx, size_t line_of_hunk","sig":"const git_diff_line **::git_patch *::size_t::size_t","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure"},"description":"

Get data about a line in a hunk of a patch.

\n","comments":"

Given a patch, a hunk index, and a line index in the hunk, this\n will return a lot of details about that line. If you pass a hunk\n index larger than the number of hunks or a line index larger than\n the number of lines in the hunk, this will return -1.

\n","group":"patch"},"git_patch_size":{"type":"function","file":"patch.h","line":239,"lineto":243,"args":[{"name":"patch","type":"git_patch *","comment":"A git_patch representing changes to one file"},{"name":"include_context","type":"int","comment":"Include context lines in size if non-zero"},{"name":"include_hunk_headers","type":"int","comment":"Include hunk header lines if non-zero"},{"name":"include_file_headers","type":"int","comment":"Include file header lines if non-zero"}],"argline":"git_patch *patch, int include_context, int include_hunk_headers, int include_file_headers","sig":"git_patch *::int::int::int","return":{"type":"size_t","comment":" The number of bytes of data"},"description":"

Look up size of patch diff data in bytes

\n","comments":"

This returns the raw size of the patch data. This only includes the\n actual data from the lines of the diff, not the file or hunk headers.

\n\n

If you pass include_context as true (non-zero), this will be the size\n of all of the diff output; if you pass it as false (zero), this will\n only include the actual changed lines (as if context_lines was 0).

\n","group":"patch"},"git_patch_print":{"type":"function","file":"patch.h","line":257,"lineto":260,"args":[{"name":"patch","type":"git_patch *","comment":"A git_patch representing changes to one file"},{"name":"print_cb","type":"git_diff_line_cb","comment":"Callback function to output lines of the patch. Will be\n called for file headers, hunk headers, and diff lines."},{"name":"payload","type":"void *","comment":"Reference pointer that will be passed to your callbacks."}],"argline":"git_patch *patch, git_diff_line_cb print_cb, void *payload","sig":"git_patch *::git_diff_line_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Serialize the patch to text via callback.

\n","comments":"

Returning a non-zero value from the callback will terminate the iteration\n and return that value to the caller.

\n","group":"patch"},"git_patch_to_buf":{"type":"function","file":"patch.h","line":269,"lineto":271,"args":[{"name":"out","type":"git_buf *","comment":"The git_buf to be filled in"},{"name":"patch","type":"git_patch *","comment":"A git_patch representing changes to one file"}],"argline":"git_buf *out, git_patch *patch","sig":"git_buf *::git_patch *","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure."},"description":"

Get the content of a patch as a single diff text.

\n","comments":"","group":"patch"},"git_pathspec_new":{"type":"function","file":"pathspec.h","line":65,"lineto":66,"args":[{"name":"out","type":"git_pathspec **","comment":"Output of the compiled pathspec"},{"name":"pathspec","type":"const git_strarray *","comment":"A git_strarray of the paths to match"}],"argline":"git_pathspec **out, const git_strarray *pathspec","sig":"git_pathspec **::const git_strarray *","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure"},"description":"

Compile a pathspec

\n","comments":"","group":"pathspec","examples":{"log.c":["ex/v0.21.2/log.html#git_pathspec_new-39"]}},"git_pathspec_free":{"type":"function","file":"pathspec.h","line":73,"lineto":73,"args":[{"name":"ps","type":"git_pathspec *","comment":"The compiled pathspec"}],"argline":"git_pathspec *ps","sig":"git_pathspec *","return":{"type":"void","comment":null},"description":"

Free a pathspec

\n","comments":"","group":"pathspec","examples":{"log.c":["ex/v0.21.2/log.html#git_pathspec_free-40"]}},"git_pathspec_matches_path":{"type":"function","file":"pathspec.h","line":88,"lineto":89,"args":[{"name":"ps","type":"const git_pathspec *","comment":"The compiled pathspec"},{"name":"flags","type":"uint32_t","comment":"Combination of git_pathspec_flag_t options to control match"},{"name":"path","type":"const char *","comment":"The pathname to attempt to match"}],"argline":"const git_pathspec *ps, uint32_t flags, const char *path","sig":"const git_pathspec *::uint32_t::const char *","return":{"type":"int","comment":" 1 is path matches spec, 0 if it does not"},"description":"

Try to match a path against a pathspec

\n","comments":"

Unlike most of the other pathspec matching functions, this will not\n fall back on the native case-sensitivity for your platform. You must\n explicitly pass flags to control case sensitivity or else this will\n fall back on being case sensitive.

\n","group":"pathspec"},"git_pathspec_match_workdir":{"type":"function","file":"pathspec.h","line":113,"lineto":117,"args":[{"name":"out","type":"git_pathspec_match_list **","comment":"Output list of matches; pass NULL to just get return value"},{"name":"repo","type":"git_repository *","comment":"The repository in which to match; bare repo is an error"},{"name":"flags","type":"uint32_t","comment":"Combination of git_pathspec_flag_t options to control match"},{"name":"ps","type":"git_pathspec *","comment":"Pathspec to be matched"}],"argline":"git_pathspec_match_list **out, git_repository *repo, uint32_t flags, git_pathspec *ps","sig":"git_pathspec_match_list **::git_repository *::uint32_t::git_pathspec *","return":{"type":"int","comment":" 0 on success, -1 on error, GIT_ENOTFOUND if no matches and\n the GIT_PATHSPEC_NO_MATCH_ERROR flag was given"},"description":"

Match a pathspec against the working directory of a repository.

\n","comments":"

This matches the pathspec against the current files in the working\n directory of the repository. It is an error to invoke this on a bare\n repo. This handles git ignores (i.e. ignored files will not be\n considered to match the pathspec unless the file is tracked in the\n index).

\n\n

If out is not NULL, this returns a git_patchspec_match_list. That\n contains the list of all matched filenames (unless you pass the\n GIT_PATHSPEC_FAILURES_ONLY flag) and may also contain the list of\n pathspecs with no match (if you used the GIT_PATHSPEC_FIND_FAILURES\n flag). You must call git_pathspec_match_list_free() on this object.

\n","group":"pathspec"},"git_pathspec_match_index":{"type":"function","file":"pathspec.h","line":142,"lineto":146,"args":[{"name":"out","type":"git_pathspec_match_list **","comment":"Output list of matches; pass NULL to just get return value"},{"name":"index","type":"git_index *","comment":"The index to match against"},{"name":"flags","type":"uint32_t","comment":"Combination of git_pathspec_flag_t options to control match"},{"name":"ps","type":"git_pathspec *","comment":"Pathspec to be matched"}],"argline":"git_pathspec_match_list **out, git_index *index, uint32_t flags, git_pathspec *ps","sig":"git_pathspec_match_list **::git_index *::uint32_t::git_pathspec *","return":{"type":"int","comment":" 0 on success, -1 on error, GIT_ENOTFOUND if no matches and\n the GIT_PATHSPEC_NO_MATCH_ERROR flag is used"},"description":"

Match a pathspec against entries in an index.

\n","comments":"

This matches the pathspec against the files in the repository index.

\n\n

NOTE: At the moment, the case sensitivity of this match is controlled\n by the current case-sensitivity of the index object itself and the\n USE_CASE and IGNORE_CASE flags will have no effect. This behavior will\n be corrected in a future release.

\n\n

If out is not NULL, this returns a git_patchspec_match_list. That\n contains the list of all matched filenames (unless you pass the\n GIT_PATHSPEC_FAILURES_ONLY flag) and may also contain the list of\n pathspecs with no match (if you used the GIT_PATHSPEC_FIND_FAILURES\n flag). You must call git_pathspec_match_list_free() on this object.

\n","group":"pathspec"},"git_pathspec_match_tree":{"type":"function","file":"pathspec.h","line":166,"lineto":170,"args":[{"name":"out","type":"git_pathspec_match_list **","comment":"Output list of matches; pass NULL to just get return value"},{"name":"tree","type":"git_tree *","comment":"The root-level tree to match against"},{"name":"flags","type":"uint32_t","comment":"Combination of git_pathspec_flag_t options to control match"},{"name":"ps","type":"git_pathspec *","comment":"Pathspec to be matched"}],"argline":"git_pathspec_match_list **out, git_tree *tree, uint32_t flags, git_pathspec *ps","sig":"git_pathspec_match_list **::git_tree *::uint32_t::git_pathspec *","return":{"type":"int","comment":" 0 on success, -1 on error, GIT_ENOTFOUND if no matches and\n the GIT_PATHSPEC_NO_MATCH_ERROR flag is used"},"description":"

Match a pathspec against files in a tree.

\n","comments":"

This matches the pathspec against the files in the given tree.

\n\n

If out is not NULL, this returns a git_patchspec_match_list. That\n contains the list of all matched filenames (unless you pass the\n GIT_PATHSPEC_FAILURES_ONLY flag) and may also contain the list of\n pathspecs with no match (if you used the GIT_PATHSPEC_FIND_FAILURES\n flag). You must call git_pathspec_match_list_free() on this object.

\n","group":"pathspec","examples":{"log.c":["ex/v0.21.2/log.html#git_pathspec_match_tree-41"]}},"git_pathspec_match_diff":{"type":"function","file":"pathspec.h","line":190,"lineto":194,"args":[{"name":"out","type":"git_pathspec_match_list **","comment":"Output list of matches; pass NULL to just get return value"},{"name":"diff","type":"git_diff *","comment":"A generated diff list"},{"name":"flags","type":"uint32_t","comment":"Combination of git_pathspec_flag_t options to control match"},{"name":"ps","type":"git_pathspec *","comment":"Pathspec to be matched"}],"argline":"git_pathspec_match_list **out, git_diff *diff, uint32_t flags, git_pathspec *ps","sig":"git_pathspec_match_list **::git_diff *::uint32_t::git_pathspec *","return":{"type":"int","comment":" 0 on success, -1 on error, GIT_ENOTFOUND if no matches and\n the GIT_PATHSPEC_NO_MATCH_ERROR flag is used"},"description":"

Match a pathspec against files in a diff list.

\n","comments":"

This matches the pathspec against the files in the given diff list.

\n\n

If out is not NULL, this returns a git_patchspec_match_list. That\n contains the list of all matched filenames (unless you pass the\n GIT_PATHSPEC_FAILURES_ONLY flag) and may also contain the list of\n pathspecs with no match (if you used the GIT_PATHSPEC_FIND_FAILURES\n flag). You must call git_pathspec_match_list_free() on this object.

\n","group":"pathspec"},"git_pathspec_match_list_free":{"type":"function","file":"pathspec.h","line":201,"lineto":201,"args":[{"name":"m","type":"git_pathspec_match_list *","comment":"The git_pathspec_match_list to be freed"}],"argline":"git_pathspec_match_list *m","sig":"git_pathspec_match_list *","return":{"type":"void","comment":null},"description":"

Free memory associates with a git_pathspec_match_list

\n","comments":"","group":"pathspec"},"git_pathspec_match_list_entrycount":{"type":"function","file":"pathspec.h","line":209,"lineto":210,"args":[{"name":"m","type":"const git_pathspec_match_list *","comment":"The git_pathspec_match_list object"}],"argline":"const git_pathspec_match_list *m","sig":"const git_pathspec_match_list *","return":{"type":"size_t","comment":" Number of items in match list"},"description":"

Get the number of items in a match list.

\n","comments":"","group":"pathspec"},"git_pathspec_match_list_entry":{"type":"function","file":"pathspec.h","line":222,"lineto":223,"args":[{"name":"m","type":"const git_pathspec_match_list *","comment":"The git_pathspec_match_list object"},{"name":"pos","type":"size_t","comment":"The index into the list"}],"argline":"const git_pathspec_match_list *m, size_t pos","sig":"const git_pathspec_match_list *::size_t","return":{"type":"const char *","comment":" The filename of the match"},"description":"

Get a matching filename by position.

\n","comments":"

This routine cannot be used if the match list was generated by\n git_pathspec_match_diff. If so, it will always return NULL.

\n","group":"pathspec"},"git_pathspec_match_list_diff_entry":{"type":"function","file":"pathspec.h","line":235,"lineto":236,"args":[{"name":"m","type":"const git_pathspec_match_list *","comment":"The git_pathspec_match_list object"},{"name":"pos","type":"size_t","comment":"The index into the list"}],"argline":"const git_pathspec_match_list *m, size_t pos","sig":"const git_pathspec_match_list *::size_t","return":{"type":"const git_diff_delta *","comment":" The filename of the match"},"description":"

Get a matching diff delta by position.

\n","comments":"

This routine can only be used if the match list was generated by\n git_pathspec_match_diff. Otherwise it will always return NULL.

\n","group":"pathspec"},"git_pathspec_match_list_failed_entrycount":{"type":"function","file":"pathspec.h","line":247,"lineto":248,"args":[{"name":"m","type":"const git_pathspec_match_list *","comment":"The git_pathspec_match_list object"}],"argline":"const git_pathspec_match_list *m","sig":"const git_pathspec_match_list *","return":{"type":"size_t","comment":" Number of items in original pathspec that had no matches"},"description":"

Get the number of pathspec items that did not match.

\n","comments":"

This will be zero unless you passed GIT_PATHSPEC_FIND_FAILURES when\n generating the git_pathspec_match_list.

\n","group":"pathspec"},"git_pathspec_match_list_failed_entry":{"type":"function","file":"pathspec.h","line":259,"lineto":260,"args":[{"name":"m","type":"const git_pathspec_match_list *","comment":"The git_pathspec_match_list object"},{"name":"pos","type":"size_t","comment":"The index into the failed items"}],"argline":"const git_pathspec_match_list *m, size_t pos","sig":"const git_pathspec_match_list *::size_t","return":{"type":"const char *","comment":" The pathspec pattern that didn't match anything"},"description":"

Get an original pathspec string that had no matches.

\n","comments":"

This will be return NULL for positions out of range.

\n","group":"pathspec"},"git_push_init_options":{"type":"function","file":"push.h","line":51,"lineto":53,"args":[{"name":"opts","type":"git_push_options *","comment":"the `git_push_options` instance to initialize."},{"name":"version","type":"unsigned int","comment":"the version of the struct; you should pass\n `GIT_PUSH_OPTIONS_VERSION` here."}],"argline":"git_push_options *opts, unsigned int version","sig":"git_push_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_push_options with default values. Equivalent to\n creating an instance with GIT_PUSH_OPTIONS_INIT.

\n","comments":"","group":"push"},"git_push_new":{"type":"function","file":"push.h","line":70,"lineto":70,"args":[{"name":"out","type":"git_push **","comment":"New push object"},{"name":"remote","type":"git_remote *","comment":"Remote instance"}],"argline":"git_push **out, git_remote *remote","sig":"git_push **::git_remote *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new push object

\n","comments":"","group":"push"},"git_push_set_options":{"type":"function","file":"push.h","line":80,"lineto":82,"args":[{"name":"push","type":"git_push *","comment":"The push object"},{"name":"opts","type":"const git_push_options *","comment":"The options to set on the push object"}],"argline":"git_push *push, const git_push_options *opts","sig":"git_push *::const git_push_options *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set options on a push object

\n","comments":"","group":"push"},"git_push_set_callbacks":{"type":"function","file":"push.h","line":98,"lineto":103,"args":[{"name":"push","type":"git_push *","comment":"The push object"},{"name":"pack_progress_cb","type":"git_packbuilder_progress","comment":"Function to call with progress information during\n pack building. Be aware that this is called inline with pack building\n operations, so performance may be affected."},{"name":"pack_progress_cb_payload","type":"void *","comment":"Payload for the pack progress callback."},{"name":"transfer_progress_cb","type":"git_push_transfer_progress","comment":"Function to call with progress information during\n the upload portion of a push. Be aware that this is called inline with\n pack building operations, so performance may be affected."},{"name":"transfer_progress_cb_payload","type":"void *","comment":"Payload for the network progress callback."}],"argline":"git_push *push, git_packbuilder_progress pack_progress_cb, void *pack_progress_cb_payload, git_push_transfer_progress transfer_progress_cb, void *transfer_progress_cb_payload","sig":"git_push *::git_packbuilder_progress::void *::git_push_transfer_progress::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the callbacks for a push

\n","comments":"","group":"push"},"git_push_add_refspec":{"type":"function","file":"push.h","line":113,"lineto":113,"args":[{"name":"push","type":"git_push *","comment":"The push object"},{"name":"refspec","type":"const char *","comment":"Refspec string"}],"argline":"git_push *push, const char *refspec","sig":"git_push *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add a refspec to be pushed

\n","comments":"","group":"push"},"git_push_update_tips":{"type":"function","file":"push.h","line":125,"lineto":128,"args":[{"name":"push","type":"git_push *","comment":"The push object"},{"name":"signature","type":"const git_signature *","comment":"The identity to use when updating reflogs"},{"name":"reflog_message","type":"const char *","comment":"The message to insert into the reflogs. If NULL, the\n default is \"update by push\"."}],"argline":"git_push *push, const git_signature *signature, const char *reflog_message","sig":"git_push *::const git_signature *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Update remote tips after a push

\n","comments":"","group":"push"},"git_push_finish":{"type":"function","file":"push.h","line":142,"lineto":142,"args":[{"name":"push","type":"git_push *","comment":"The push object"}],"argline":"git_push *push","sig":"git_push *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Actually push all given refspecs

\n","comments":"

Note: To check if the push was successful (i.e. all remote references\n have been updated as requested), you need to call both\n git_push_unpack_ok and git_push_status_foreach. The remote\n repository might have refused to update some or all of the references.

\n","group":"push"},"git_push_unpack_ok":{"type":"function","file":"push.h","line":151,"lineto":151,"args":[{"name":"push","type":"const git_push *","comment":"The push object"}],"argline":"const git_push *push","sig":"const git_push *","return":{"type":"int","comment":" true if remote side successfully unpacked, false otherwise"},"description":"

Check if remote side successfully unpacked

\n","comments":"","group":"push"},"git_push_status_foreach":{"type":"function","file":"push.h","line":168,"lineto":170,"args":[{"name":"push","type":"git_push *","comment":"The push object"},{"name":"cb","type":"int (*)(const char *, const char *, void *)","comment":"The callback to call on each object"},{"name":"data","type":"void *","comment":null}],"argline":"git_push *push, int (*)(const char *, const char *, void *) cb, void *data","sig":"git_push *::int (*)(const char *, const char *, void *)::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Invoke callback `cb' on each status entry

\n","comments":"

For each of the updated references, we receive a status report in the\n form of ok refs/heads/master or `ng refs/heads/master \n<msg

\n\n
\n

.\nmsg != NULL` means the reference has not been updated for the given\n reason.

\n
\n\n

Return a non-zero value from the callback to stop the loop.

\n","group":"push"},"git_push_free":{"type":"function","file":"push.h","line":177,"lineto":177,"args":[{"name":"push","type":"git_push *","comment":"The push object"}],"argline":"git_push *push","sig":"git_push *","return":{"type":"void","comment":null},"description":"

Free the given push object

\n","comments":"","group":"push"},"git_refdb_new":{"type":"function","file":"refdb.h","line":35,"lineto":35,"args":[{"name":"out","type":"git_refdb **","comment":"location to store the database pointer, if opened.\n\t\t\tSet to NULL if the open failed."},{"name":"repo","type":"git_repository *","comment":"the repository"}],"argline":"git_refdb **out, git_repository *repo","sig":"git_refdb **::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new reference database with no backends.

\n","comments":"

Before the Ref DB can be used for read/writing, a custom database\n backend must be manually set using git_refdb_set_backend()

\n","group":"refdb"},"git_refdb_open":{"type":"function","file":"refdb.h","line":49,"lineto":49,"args":[{"name":"out","type":"git_refdb **","comment":"location to store the database pointer, if opened.\n\t\t\tSet to NULL if the open failed."},{"name":"repo","type":"git_repository *","comment":"the repository"}],"argline":"git_refdb **out, git_repository *repo","sig":"git_refdb **::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new reference database and automatically add\n the default backends:

\n","comments":"
    \n
  • git_refdb_dir: read and write loose and packed refs\n from disk, assuming the repository dir as the folder
  • \n
\n","group":"refdb"},"git_refdb_compress":{"type":"function","file":"refdb.h","line":56,"lineto":56,"args":[{"name":"refdb","type":"git_refdb *","comment":null}],"argline":"git_refdb *refdb","sig":"git_refdb *","return":{"type":"int","comment":null},"description":"

Suggests that the given refdb compress or optimize its references.\n This mechanism is implementation specific. For on-disk reference\n databases, for example, this may pack all loose references.

\n","comments":"","group":"refdb"},"git_refdb_free":{"type":"function","file":"refdb.h","line":63,"lineto":63,"args":[{"name":"refdb","type":"git_refdb *","comment":"reference database pointer or NULL"}],"argline":"git_refdb *refdb","sig":"git_refdb *","return":{"type":"void","comment":null},"description":"

Close an open reference database.

\n","comments":"","group":"refdb"},"git_reflog_read":{"type":"function","file":"reflog.h","line":38,"lineto":38,"args":[{"name":"out","type":"git_reflog **","comment":"pointer to reflog"},{"name":"repo","type":"git_repository *","comment":"the repostiory"},{"name":"name","type":"const char *","comment":"reference to look up"}],"argline":"git_reflog **out, git_repository *repo, const char *name","sig":"git_reflog **::git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Read the reflog for the given reference

\n","comments":"

If there is no reflog file for the given\n reference yet, an empty reflog object will\n be returned.

\n\n

The reflog must be freed manually by using\n git_reflog_free().

\n","group":"reflog"},"git_reflog_write":{"type":"function","file":"reflog.h","line":47,"lineto":47,"args":[{"name":"reflog","type":"git_reflog *","comment":"an existing reflog object"}],"argline":"git_reflog *reflog","sig":"git_reflog *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Write an existing in-memory reflog object back to disk\n using an atomic file lock.

\n","comments":"","group":"reflog"},"git_reflog_append":{"type":"function","file":"reflog.h","line":60,"lineto":60,"args":[{"name":"reflog","type":"git_reflog *","comment":"an existing reflog object"},{"name":"id","type":"const git_oid *","comment":"the OID the reference is now pointing to"},{"name":"committer","type":"const git_signature *","comment":"the signature of the committer"},{"name":"msg","type":"const char *","comment":"the reflog message"}],"argline":"git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg","sig":"git_reflog *::const git_oid *::const git_signature *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add a new entry to the in-memory reflog.

\n","comments":"

msg is optional and can be NULL.

\n","group":"reflog"},"git_reflog_rename":{"type":"function","file":"reflog.h","line":75,"lineto":75,"args":[{"name":"repo","type":"git_repository *","comment":"the repository"},{"name":"old_name","type":"const char *","comment":"the old name of the reference"},{"name":"name","type":"const char *","comment":"the new name of the reference"}],"argline":"git_repository *repo, const char *old_name, const char *name","sig":"git_repository *::const char *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC or an error code"},"description":"

Rename a reflog

\n","comments":"

The reflog to be renamed is expected to already exist

\n\n

The new name will be checked for validity.\n See git_reference_create_symbolic() for rules about valid names.

\n","group":"reflog"},"git_reflog_delete":{"type":"function","file":"reflog.h","line":84,"lineto":84,"args":[{"name":"repo","type":"git_repository *","comment":"the repository"},{"name":"name","type":"const char *","comment":"the reflog to delete"}],"argline":"git_repository *repo, const char *name","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Delete the reflog for the given reference

\n","comments":"","group":"reflog"},"git_reflog_entrycount":{"type":"function","file":"reflog.h","line":92,"lineto":92,"args":[{"name":"reflog","type":"git_reflog *","comment":"the previously loaded reflog"}],"argline":"git_reflog *reflog","sig":"git_reflog *","return":{"type":"size_t","comment":" the number of log entries"},"description":"

Get the number of log entries in a reflog

\n","comments":"","group":"reflog"},"git_reflog_entry_byindex":{"type":"function","file":"reflog.h","line":105,"lineto":105,"args":[{"name":"reflog","type":"git_reflog *","comment":"a previously loaded reflog"},{"name":"idx","type":"size_t","comment":"the position of the entry to lookup. Should be greater than or\n equal to 0 (zero) and less than `git_reflog_entrycount()`."}],"argline":"git_reflog *reflog, size_t idx","sig":"git_reflog *::size_t","return":{"type":"const git_reflog_entry *","comment":" the entry; NULL if not found"},"description":"

Lookup an entry by its index

\n","comments":"

Requesting the reflog entry with an index of 0 (zero) will\n return the most recently created entry.

\n","group":"reflog"},"git_reflog_drop":{"type":"function","file":"reflog.h","line":124,"lineto":127,"args":[{"name":"reflog","type":"git_reflog *","comment":"a previously loaded reflog."},{"name":"idx","type":"size_t","comment":"the position of the entry to remove. Should be greater than or\n equal to 0 (zero) and less than `git_reflog_entrycount()`."},{"name":"rewrite_previous_entry","type":"int","comment":"1 to rewrite the history; 0 otherwise."}],"argline":"git_reflog *reflog, size_t idx, int rewrite_previous_entry","sig":"git_reflog *::size_t::int","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if the entry doesn't exist\n or an error code."},"description":"

Remove an entry from the reflog by its index

\n","comments":"

To ensure there's no gap in the log history, set rewrite_previous_entry\n param value to 1. When deleting entry n, member old_oid of entry n-1\n (if any) will be updated with the value of member new_oid of entry n+1.

\n","group":"reflog"},"git_reflog_entry_id_old":{"type":"function","file":"reflog.h","line":135,"lineto":135,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"const git_oid *","comment":" the old oid"},"description":"

Get the old oid

\n","comments":"","group":"reflog"},"git_reflog_entry_id_new":{"type":"function","file":"reflog.h","line":143,"lineto":143,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"const git_oid *","comment":" the new oid at this time"},"description":"

Get the new oid

\n","comments":"","group":"reflog"},"git_reflog_entry_committer":{"type":"function","file":"reflog.h","line":151,"lineto":151,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"const git_signature *","comment":" the committer"},"description":"

Get the committer of this entry

\n","comments":"","group":"reflog"},"git_reflog_entry_message":{"type":"function","file":"reflog.h","line":159,"lineto":159,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"const char *","comment":" the log msg"},"description":"

Get the log message

\n","comments":"","group":"reflog"},"git_reflog_free":{"type":"function","file":"reflog.h","line":166,"lineto":166,"args":[{"name":"reflog","type":"git_reflog *","comment":"reflog to free"}],"argline":"git_reflog *reflog","sig":"git_reflog *","return":{"type":"void","comment":null},"description":"

Free the reflog

\n","comments":"","group":"reflog"},"git_reference_lookup":{"type":"function","file":"refs.h","line":37,"lineto":37,"args":[{"name":"out","type":"git_reference **","comment":"pointer to the looked-up reference"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the reference"},{"name":"name","type":"const char *","comment":"the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)"}],"argline":"git_reference **out, git_repository *repo, const char *name","sig":"git_reference **::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code."},"description":"

Lookup a reference by name in a repository.

\n","comments":"

The returned reference must be freed by the user.

\n\n

The name will be checked for validity.\n See git_reference_symbolic_create() for rules about valid names.

\n","group":"reference","examples":{"general.c":["ex/v0.21.2/general.html#git_reference_lookup-52"]}},"git_reference_name_to_id":{"type":"function","file":"refs.h","line":54,"lineto":55,"args":[{"name":"out","type":"git_oid *","comment":"Pointer to oid to be filled in"},{"name":"repo","type":"git_repository *","comment":"The repository in which to look up the reference"},{"name":"name","type":"const char *","comment":"The long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)"}],"argline":"git_oid *out, git_repository *repo, const char *name","sig":"git_oid *::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code."},"description":"

Lookup a reference by name and resolve immediately to OID.

\n","comments":"

This function provides a quick way to resolve a reference name straight\n through to the object id that it refers to. This avoids having to\n allocate or free any git_reference objects for simple situations.

\n\n

The name will be checked for validity.\n See git_reference_symbolic_create() for rules about valid names.

\n","group":"reference"},"git_reference_dwim":{"type":"function","file":"refs.h","line":68,"lineto":68,"args":[{"name":"out","type":"git_reference **","comment":"pointer in which to store the reference"},{"name":"repo","type":"git_repository *","comment":"the repository in which to look"},{"name":"shorthand","type":"const char *","comment":"the short name for the reference"}],"argline":"git_reference **out, git_repository *repo, const char *shorthand","sig":"git_reference **::git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a reference by DWIMing its short name

\n","comments":"

Apply the git precendence rules to the given shorthand to determine\n which reference the user is refering to.

\n","group":"reference"},"git_reference_symbolic_create_matching":{"type":"function","file":"refs.h","line":110,"lineto":110,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"repo","type":"git_repository *","comment":"Repository where that reference will live"},{"name":"name","type":"const char *","comment":"The name of the reference"},{"name":"target","type":"const char *","comment":"The target of the reference"},{"name":"force","type":"int","comment":"Overwrite existing references"},{"name":"current_value","type":"const char *","comment":"The expected value of the reference when updating"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_repository *repo, const char *name, const char *target, int force, const char *current_value, const git_signature *signature, const char *log_message","sig":"git_reference **::git_repository *::const char *::const char *::int::const char *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC, GIT_EMODIFIED or an error code"},"description":"

Conditionally create a new symbolic reference.

\n","comments":"

A symbolic reference is a reference name that refers to another\n reference name. If the other name moves, the symbolic name will move,\n too. As a simple example, the "HEAD" reference might refer to\n "refs/heads/master" while on the "master" branch of a repository.

\n\n

The symbolic reference will be created in the repository and written to\n the disk. The generated reference object must be freed by the user.

\n\n

Valid reference names must follow one of two patterns:

\n\n
    \n
  1. Top-level names must contain only capital letters and underscores,\nand must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
  2. \n
  3. Names prefixed with "refs/" can be almost anything. You must avoid\nthe characters '~', '^', ':', '\n\\\n', '?', '[', and '*', and the\nsequences ".." and "\n@\n{" which have special meaning to revparse.
  4. \n
\n\n

This function will return an error if a reference already exists with the\n given name unless force is true, in which case it will be overwritten.

\n\n

The signature and message for the reflog will be ignored if the\n reference does not belong in the standard set (HEAD, branches and\n remote-tracking branches) and it does not have a reflog.

\n\n

It will return GIT_EMODIFIED if the reference's value at the time\n of updating does not match the one passed through current_value\n (i.e. if the ref has changed since the user read it).

\n","group":"reference"},"git_reference_symbolic_create":{"type":"function","file":"refs.h","line":147,"lineto":147,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"repo","type":"git_repository *","comment":"Repository where that reference will live"},{"name":"name","type":"const char *","comment":"The name of the reference"},{"name":"target","type":"const char *","comment":"The target of the reference"},{"name":"force","type":"int","comment":"Overwrite existing references"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_repository *repo, const char *name, const char *target, int force, const git_signature *signature, const char *log_message","sig":"git_reference **::git_repository *::const char *::const char *::int::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code"},"description":"

Create a new symbolic reference.

\n","comments":"

A symbolic reference is a reference name that refers to another\n reference name. If the other name moves, the symbolic name will move,\n too. As a simple example, the "HEAD" reference might refer to\n "refs/heads/master" while on the "master" branch of a repository.

\n\n

The symbolic reference will be created in the repository and written to\n the disk. The generated reference object must be freed by the user.

\n\n

Valid reference names must follow one of two patterns:

\n\n
    \n
  1. Top-level names must contain only capital letters and underscores,\nand must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
  2. \n
  3. Names prefixed with "refs/" can be almost anything. You must avoid\nthe characters '~', '^', ':', '\n\\\n', '?', '[', and '*', and the\nsequences ".." and "\n@\n{" which have special meaning to revparse.
  4. \n
\n\n

This function will return an error if a reference already exists with the\n given name unless force is true, in which case it will be overwritten.

\n\n

The signature and message for the reflog will be ignored if the\n reference does not belong in the standard set (HEAD, branches and\n remote-tracking branches) and it does not have a reflog.

\n","group":"reference"},"git_reference_create":{"type":"function","file":"refs.h","line":185,"lineto":185,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"repo","type":"git_repository *","comment":"Repository where that reference will live"},{"name":"name","type":"const char *","comment":"The name of the reference"},{"name":"id","type":"const git_oid *","comment":"The object id pointed to by the reference."},{"name":"force","type":"int","comment":"Overwrite existing references"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_signature *signature, const char *log_message","sig":"git_reference **::git_repository *::const char *::const git_oid *::int::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code"},"description":"

Create a new direct reference.

\n","comments":"

A direct reference (also called an object id reference) refers directly\n to a specific object id (a.k.a. OID or SHA) in the repository. The id\n permanently refers to the object (although the reference itself can be\n moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0"\n refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.

\n\n

The direct reference will be created in the repository and written to\n the disk. The generated reference object must be freed by the user.

\n\n

Valid reference names must follow one of two patterns:

\n\n
    \n
  1. Top-level names must contain only capital letters and underscores,\nand must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
  2. \n
  3. Names prefixed with "refs/" can be almost anything. You must avoid\nthe characters '~', '^', ':', '\n\\\n', '?', '[', and '*', and the\nsequences ".." and "\n@\n{" which have special meaning to revparse.
  4. \n
\n\n

This function will return an error if a reference already exists with the\n given name unless force is true, in which case it will be overwritten.

\n\n

The signature and message for the reflog will be ignored if the\n reference does not belong in the standard set (HEAD, branches and\n remote-tracking branches) and and it does not have a reflog.

\n","group":"reference"},"git_reference_create_matching":{"type":"function","file":"refs.h","line":229,"lineto":229,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"repo","type":"git_repository *","comment":"Repository where that reference will live"},{"name":"name","type":"const char *","comment":"The name of the reference"},{"name":"id","type":"const git_oid *","comment":"The object id pointed to by the reference."},{"name":"force","type":"int","comment":"Overwrite existing references"},{"name":"current_id","type":"const git_oid *","comment":"The expected value of the reference at the time of update"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_oid *current_id, const git_signature *signature, const char *log_message","sig":"git_reference **::git_repository *::const char *::const git_oid *::int::const git_oid *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EMODIFIED if the value of the reference\n has changed, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code"},"description":"

Conditionally create new direct reference

\n","comments":"

A direct reference (also called an object id reference) refers directly\n to a specific object id (a.k.a. OID or SHA) in the repository. The id\n permanently refers to the object (although the reference itself can be\n moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0"\n refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.

\n\n

The direct reference will be created in the repository and written to\n the disk. The generated reference object must be freed by the user.

\n\n

Valid reference names must follow one of two patterns:

\n\n
    \n
  1. Top-level names must contain only capital letters and underscores,\nand must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
  2. \n
  3. Names prefixed with "refs/" can be almost anything. You must avoid\nthe characters '~', '^', ':', '\n\\\n', '?', '[', and '*', and the\nsequences ".." and "\n@\n{" which have special meaning to revparse.
  4. \n
\n\n

This function will return an error if a reference already exists with the\n given name unless force is true, in which case it will be overwritten.

\n\n

The signature and message for the reflog will be ignored if the\n reference does not belong in the standard set (HEAD, branches and\n remote-tracking branches) and and it does not have a reflog.

\n\n

It will return GIT_EMODIFIED if the reference's value at the time\n of updating does not match the one passed through current_id\n (i.e. if the ref has changed since the user read it).

\n","group":"reference"},"git_reference_target":{"type":"function","file":"refs.h","line":244,"lineto":244,"args":[{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"const git_oid *","comment":" a pointer to the oid if available, NULL otherwise"},"description":"

Get the OID pointed to by a direct reference.

\n","comments":"

Only available if the reference is direct (i.e. an object id reference,\n not a symbolic one).

\n\n

To find the OID of a symbolic ref, call git_reference_resolve() and\n then this function (or maybe use git_reference_name_to_id() to\n directly resolve a reference name all the way through to an OID).

\n","group":"reference","examples":{"general.c":["ex/v0.21.2/general.html#git_reference_target-53"]}},"git_reference_target_peel":{"type":"function","file":"refs.h","line":255,"lineto":255,"args":[{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"const git_oid *","comment":" a pointer to the oid if available, NULL otherwise"},"description":"

Return the peeled OID target of this reference.

\n","comments":"

This peeled OID only applies to direct references that point to\n a hard Tag object: it is the result of peeling such Tag.

\n","group":"reference"},"git_reference_symbolic_target":{"type":"function","file":"refs.h","line":265,"lineto":265,"args":[{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"const char *","comment":" a pointer to the name if available, NULL otherwise"},"description":"

Get full name to the reference pointed to by a symbolic reference.

\n","comments":"

Only available if the reference is symbolic.

\n","group":"reference","examples":{"general.c":["ex/v0.21.2/general.html#git_reference_symbolic_target-54"]}},"git_reference_type":{"type":"function","file":"refs.h","line":275,"lineto":275,"args":[{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"git_ref_t","comment":" the type"},"description":"

Get the type of a reference.

\n","comments":"

Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC)

\n","group":"reference","examples":{"general.c":["ex/v0.21.2/general.html#git_reference_type-55"]}},"git_reference_name":{"type":"function","file":"refs.h","line":285,"lineto":285,"args":[{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"const char *","comment":" the full name for the ref"},"description":"

Get the full name of a reference.

\n","comments":"

See git_reference_symbolic_create() for rules about valid names.

\n","group":"reference"},"git_reference_resolve":{"type":"function","file":"refs.h","line":303,"lineto":303,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the peeled reference"},{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"git_reference **out, const git_reference *ref","sig":"git_reference **::const git_reference *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Resolve a symbolic reference to a direct reference.

\n","comments":"

This method iteratively peels a symbolic reference until it resolves to\n a direct reference to an OID.

\n\n

The peeled reference is returned in the resolved_ref argument, and\n must be freed manually once it's no longer needed.

\n\n

If a direct reference is passed as an argument, a copy of that\n reference is returned. This copy must be manually freed too.

\n","group":"reference"},"git_reference_owner":{"type":"function","file":"refs.h","line":311,"lineto":311,"args":[{"name":"ref","type":"const git_reference *","comment":"The reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"git_repository *","comment":" a pointer to the repo"},"description":"

Get the repository where a reference resides.

\n","comments":"","group":"reference"},"git_reference_symbolic_set_target":{"type":"function","file":"refs.h","line":334,"lineto":339,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"ref","type":"git_reference *","comment":"The reference"},{"name":"target","type":"const char *","comment":"The new target for the reference"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_reference *ref, const char *target, const git_signature *signature, const char *log_message","sig":"git_reference **::git_reference *::const char *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC or an error code"},"description":"

Create a new reference with the same name as the given reference but a\n different symbolic target. The reference must be a symbolic reference,\n otherwise this will fail.

\n","comments":"

The new reference will be written to disk, overwriting the given reference.

\n\n

The target name will be checked for validity.\n See git_reference_symbolic_create() for rules about valid names.

\n\n

The signature and message for the reflog will be ignored if the\n reference does not belong in the standard set (HEAD, branches and\n remote-tracking branches) and and it does not have a reflog.

\n","group":"reference"},"git_reference_set_target":{"type":"function","file":"refs.h","line":356,"lineto":361,"args":[{"name":"out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"ref","type":"git_reference *","comment":"The reference"},{"name":"id","type":"const git_oid *","comment":"The new target OID for the reference"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **out, git_reference *ref, const git_oid *id, const git_signature *signature, const char *log_message","sig":"git_reference **::git_reference *::const git_oid *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EMODIFIED if the value of the reference\n has changed since it was read, or an error code"},"description":"

Conditionally create a new reference with the same name as the given reference but a\n different OID target. The reference must be a direct reference, otherwise\n this will fail.

\n","comments":"

The new reference will be written to disk, overwriting the given reference.

\n","group":"reference"},"git_reference_rename":{"type":"function","file":"refs.h","line":387,"lineto":393,"args":[{"name":"new_ref","type":"git_reference **","comment":null},{"name":"ref","type":"git_reference *","comment":"The reference to rename"},{"name":"new_name","type":"const char *","comment":"The new name for the reference"},{"name":"force","type":"int","comment":"Overwrite an existing reference"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_reference **new_ref, git_reference *ref, const char *new_name, int force, const git_signature *signature, const char *log_message","sig":"git_reference **::git_reference *::const char *::int::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code"},"description":"

Rename an existing reference.

\n","comments":"

This method works for both direct and symbolic references.

\n\n

The new name will be checked for validity.\n See git_reference_symbolic_create() for rules about valid names.

\n\n

If the force flag is not enabled, and there's already\n a reference with the given name, the renaming will fail.

\n\n

IMPORTANT:\n The user needs to write a proper reflog entry if the\n reflog is enabled for the repository. We only rename\n the reflog if it exists.

\n","group":"reference"},"git_reference_delete":{"type":"function","file":"refs.h","line":408,"lineto":408,"args":[{"name":"ref","type":"git_reference *","comment":"The reference to remove"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":" 0, GIT_EMODIFIED or an error code"},"description":"

Delete an existing reference.

\n","comments":"

This method works for both direct and symbolic references. The reference\n will be immediately removed on disk but the memory will not be freed.\n Callers must call git_reference_free.

\n\n

This function will return an error if the reference has changed\n from the time it was looked up.

\n","group":"reference"},"git_reference_remove":{"type":"function","file":"refs.h","line":419,"lineto":419,"args":[{"name":"repo","type":"git_repository *","comment":null},{"name":"name","type":"const char *","comment":"The reference to remove"}],"argline":"git_repository *repo, const char *name","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Delete an existing reference by name

\n","comments":"

This method removes the named reference from the repository without\n looking at its old value.

\n","group":"reference"},"git_reference_list":{"type":"function","file":"refs.h","line":433,"lineto":433,"args":[{"name":"array","type":"git_strarray *","comment":"Pointer to a git_strarray structure where\n\t\tthe reference names will be stored"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the refs"}],"argline":"git_strarray *array, git_repository *repo","sig":"git_strarray *::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Fill a list with all the references that can be found in a repository.

\n","comments":"

The string array will be filled with the names of all references; these\n values are owned by the user and should be free'd manually when no\n longer needed, using git_strarray_free().

\n","group":"reference","examples":{"general.c":["ex/v0.21.2/general.html#git_reference_list-56"]}},"git_reference_foreach":{"type":"function","file":"refs.h","line":451,"lineto":454,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the refs"},{"name":"callback","type":"git_reference_foreach_cb","comment":"Function which will be called for every listed ref"},{"name":"payload","type":"void *","comment":"Additional data to pass to the callback"}],"argline":"git_repository *repo, git_reference_foreach_cb callback, void *payload","sig":"git_repository *::git_reference_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Perform a callback on each reference in the repository.

\n","comments":"

The callback function will be called for each reference in the\n repository, receiving the reference object and the payload value\n passed to this method. Returning a non-zero value from the callback\n will terminate the iteration.

\n","group":"reference"},"git_reference_foreach_name":{"type":"function","file":"refs.h","line":469,"lineto":472,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the refs"},{"name":"callback","type":"git_reference_foreach_name_cb","comment":"Function which will be called for every listed ref name"},{"name":"payload","type":"void *","comment":"Additional data to pass to the callback"}],"argline":"git_repository *repo, git_reference_foreach_name_cb callback, void *payload","sig":"git_repository *::git_reference_foreach_name_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Perform a callback on the fully-qualified name of each reference.

\n","comments":"

The callback function will be called for each reference in the\n repository, receiving the name of the reference and the payload value\n passed to this method. Returning a non-zero value from the callback\n will terminate the iteration.

\n","group":"reference"},"git_reference_free":{"type":"function","file":"refs.h","line":479,"lineto":479,"args":[{"name":"ref","type":"git_reference *","comment":"git_reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"void","comment":null},"description":"

Free the given reference.

\n","comments":"","group":"reference","examples":{"status.c":["ex/v0.21.2/status.html#git_reference_free-1"]}},"git_reference_cmp":{"type":"function","file":"refs.h","line":488,"lineto":490,"args":[{"name":"ref1","type":"const git_reference *","comment":"The first git_reference"},{"name":"ref2","type":"const git_reference *","comment":"The second git_reference"}],"argline":"const git_reference *ref1, const git_reference *ref2","sig":"const git_reference *::const git_reference *","return":{"type":"int","comment":" 0 if the same, else a stable but meaningless ordering."},"description":"

Compare two references.

\n","comments":"","group":"reference"},"git_reference_iterator_new":{"type":"function","file":"refs.h","line":499,"lineto":501,"args":[{"name":"out","type":"git_reference_iterator **","comment":"pointer in which to store the iterator"},{"name":"repo","type":"git_repository *","comment":"the repository"}],"argline":"git_reference_iterator **out, git_repository *repo","sig":"git_reference_iterator **::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an iterator for the repo's references

\n","comments":"","group":"reference"},"git_reference_iterator_glob_new":{"type":"function","file":"refs.h","line":512,"lineto":515,"args":[{"name":"out","type":"git_reference_iterator **","comment":"pointer in which to store the iterator"},{"name":"repo","type":"git_repository *","comment":"the repository"},{"name":"glob","type":"const char *","comment":"the glob to match against the reference names"}],"argline":"git_reference_iterator **out, git_repository *repo, const char *glob","sig":"git_reference_iterator **::git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an iterator for the repo's references that match the\n specified glob

\n","comments":"","group":"reference"},"git_reference_next":{"type":"function","file":"refs.h","line":524,"lineto":524,"args":[{"name":"out","type":"git_reference **","comment":"pointer in which to store the reference"},{"name":"iter","type":"git_reference_iterator *","comment":"the iterator"}],"argline":"git_reference **out, git_reference_iterator *iter","sig":"git_reference **::git_reference_iterator *","return":{"type":"int","comment":" 0, GIT_ITEROVER if there are no more; or an error code"},"description":"

Get the next reference

\n","comments":"","group":"reference"},"git_reference_next_name":{"type":"function","file":"refs.h","line":537,"lineto":537,"args":[{"name":"out","type":"const char **","comment":"pointer in which to store the string"},{"name":"iter","type":"git_reference_iterator *","comment":"the iterator"}],"argline":"const char **out, git_reference_iterator *iter","sig":"const char **::git_reference_iterator *","return":{"type":"int","comment":" 0, GIT_ITEROVER if there are no more; or an error code"},"description":"

Get the next reference's name

\n","comments":"

This function is provided for convenience in case only the names\n are interesting as it avoids the allocation of the git_reference\n object which git_reference_next() needs.

\n","group":"reference"},"git_reference_iterator_free":{"type":"function","file":"refs.h","line":544,"lineto":544,"args":[{"name":"iter","type":"git_reference_iterator *","comment":"the iterator to free"}],"argline":"git_reference_iterator *iter","sig":"git_reference_iterator *","return":{"type":"void","comment":null},"description":"

Free the iterator and its associated resources

\n","comments":"","group":"reference"},"git_reference_foreach_glob":{"type":"function","file":"refs.h","line":564,"lineto":568,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the refs"},{"name":"glob","type":"const char *","comment":"Pattern to match (fnmatch-style) against reference name."},{"name":"callback","type":"git_reference_foreach_name_cb","comment":"Function which will be called for every listed ref"},{"name":"payload","type":"void *","comment":"Additional data to pass to the callback"}],"argline":"git_repository *repo, const char *glob, git_reference_foreach_name_cb callback, void *payload","sig":"git_repository *::const char *::git_reference_foreach_name_cb::void *","return":{"type":"int","comment":" 0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"

Perform a callback on each reference in the repository whose name\n matches the given pattern.

\n","comments":"

This function acts like git_reference_foreach() with an additional\n pattern match being applied to the reference name before issuing the\n callback function. See that function for more information.

\n\n

The pattern is matched using fnmatch or "glob" style where a '*' matches\n any sequence of letters, a '?' matches any letter, and square brackets\n can be used to define character ranges (such as "[0-9]" for digits).

\n","group":"reference"},"git_reference_has_log":{"type":"function","file":"refs.h","line":578,"lineto":578,"args":[{"name":"repo","type":"git_repository *","comment":"the repository"},{"name":"refname","type":"const char *","comment":"the reference's name"}],"argline":"git_repository *repo, const char *refname","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 when no reflog can be found, 1 when it exists;\n otherwise an error code."},"description":"

Check if a reflog exists for the specified reference.

\n","comments":"","group":"reference"},"git_reference_ensure_log":{"type":"function","file":"refs.h","line":590,"lineto":590,"args":[{"name":"repo","type":"git_repository *","comment":"the repository"},{"name":"refname","type":"const char *","comment":"the reference's name"}],"argline":"git_repository *repo, const char *refname","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 or an error code."},"description":"

Ensure there is a reflog for a particular reference.

\n","comments":"

Make sure that successive updates to the reference will append to\n its log.

\n","group":"reference"},"git_reference_is_branch":{"type":"function","file":"refs.h","line":600,"lineto":600,"args":[{"name":"ref","type":"const git_reference *","comment":"A git reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"int","comment":" 1 when the reference lives in the refs/heads\n namespace; 0 otherwise."},"description":"

Check if a reference is a local branch.

\n","comments":"","group":"reference"},"git_reference_is_remote":{"type":"function","file":"refs.h","line":610,"lineto":610,"args":[{"name":"ref","type":"const git_reference *","comment":"A git reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"int","comment":" 1 when the reference lives in the refs/remotes\n namespace; 0 otherwise."},"description":"

Check if a reference is a remote tracking branch

\n","comments":"","group":"reference"},"git_reference_is_tag":{"type":"function","file":"refs.h","line":620,"lineto":620,"args":[{"name":"ref","type":"const git_reference *","comment":"A git reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"int","comment":" 1 when the reference lives in the refs/tags\n namespace; 0 otherwise."},"description":"

Check if a reference is a tag

\n","comments":"","group":"reference"},"git_reference_is_note":{"type":"function","file":"refs.h","line":630,"lineto":630,"args":[{"name":"ref","type":"const git_reference *","comment":"A git reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"int","comment":" 1 when the reference lives in the refs/notes\n namespace; 0 otherwise."},"description":"

Check if a reference is a note

\n","comments":"","group":"reference"},"git_reference_normalize_name":{"type":"function","file":"refs.h","line":680,"lineto":684,"args":[{"name":"buffer_out","type":"char *","comment":"User allocated buffer to store normalized name"},{"name":"buffer_size","type":"size_t","comment":"Size of buffer_out"},{"name":"name","type":"const char *","comment":"Reference name to be checked."},{"name":"flags","type":"unsigned int","comment":"Flags to constrain name validation rules - see the\n GIT_REF_FORMAT constants above."}],"argline":"char *buffer_out, size_t buffer_size, const char *name, unsigned int flags","sig":"char *::size_t::const char *::unsigned int","return":{"type":"int","comment":" 0 on success, GIT_EBUFS if buffer is too small, GIT_EINVALIDSPEC\n or an error code."},"description":"

Normalize reference name and check validity.

\n","comments":"

This will normalize the reference name by removing any leading slash\n '/' characters and collapsing runs of adjacent slashes between name\n components into a single slash.

\n\n

Once normalized, if the reference name is valid, it will be returned in\n the user allocated buffer.

\n\n

See git_reference_symbolic_create() for rules about valid names.

\n","group":"reference"},"git_reference_peel":{"type":"function","file":"refs.h","line":701,"lineto":704,"args":[{"name":"out","type":"git_object **","comment":"Pointer to the peeled git_object"},{"name":"ref","type":"git_reference *","comment":"The reference to be processed"},{"name":"type","type":"git_otype","comment":"The type of the requested object (GIT_OBJ_COMMIT,\n GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY)."}],"argline":"git_object **out, git_reference *ref, git_otype type","sig":"git_object **::git_reference *::git_otype","return":{"type":"int","comment":" 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code"},"description":"

Recursively peel reference until object of the specified type is found.

\n","comments":"

The retrieved peeled object is owned by the repository\n and should be closed with the git_object_free method.

\n\n

If you pass GIT_OBJ_ANY as the target type, then the object\n will be peeled until a non-tag object is met.

\n","group":"reference"},"git_reference_is_valid_name":{"type":"function","file":"refs.h","line":720,"lineto":720,"args":[{"name":"refname","type":"const char *","comment":"name to be checked."}],"argline":"const char *refname","sig":"const char *","return":{"type":"int","comment":" 1 if the reference name is acceptable; 0 if it isn't"},"description":"

Ensure the reference name is well-formed.

\n","comments":"

Valid reference names must follow one of two patterns:

\n\n
    \n
  1. Top-level names must contain only capital letters and underscores,\nand must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
  2. \n
  3. Names prefixed with "refs/" can be almost anything. You must avoid\nthe characters '~', '^', ':', '\n\\\n', '?', '[', and '*', and the\nsequences ".." and "\n@\n{" which have special meaning to revparse.
  4. \n
\n","group":"reference"},"git_reference_shorthand":{"type":"function","file":"refs.h","line":734,"lineto":734,"args":[{"name":"ref","type":"const git_reference *","comment":"a reference"}],"argline":"const git_reference *ref","sig":"const git_reference *","return":{"type":"const char *","comment":" the human-readable version of the name"},"description":"

Get the reference's short name

\n","comments":"

This will transform the reference name into a name "human-readable"\n version. If no shortname is appropriate, it will return the full\n name.

\n\n

The memory is owned by the reference and must not be freed.

\n","group":"reference","examples":{"status.c":["ex/v0.21.2/status.html#git_reference_shorthand-2"]}},"git_refspec_src":{"type":"function","file":"refspec.h","line":30,"lineto":30,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"const char *","comment":" the refspec's source specifier"},"description":"

Get the source specifier

\n","comments":"","group":"refspec"},"git_refspec_dst":{"type":"function","file":"refspec.h","line":38,"lineto":38,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"const char *","comment":" the refspec's destination specifier"},"description":"

Get the destination specifier

\n","comments":"","group":"refspec"},"git_refspec_string":{"type":"function","file":"refspec.h","line":46,"lineto":46,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"const char *","comment":null},"description":"

Get the refspec's string

\n","comments":"","group":"refspec"},"git_refspec_force":{"type":"function","file":"refspec.h","line":54,"lineto":54,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"int","comment":" 1 if force update has been set, 0 otherwise"},"description":"

Get the force update setting

\n","comments":"","group":"refspec"},"git_refspec_direction":{"type":"function","file":"refspec.h","line":62,"lineto":62,"args":[{"name":"spec","type":"const git_refspec *","comment":"refspec"}],"argline":"const git_refspec *spec","sig":"const git_refspec *","return":{"type":"git_direction","comment":" GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH"},"description":"

Get the refspec's direction.

\n","comments":"","group":"refspec"},"git_refspec_src_matches":{"type":"function","file":"refspec.h","line":71,"lineto":71,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"},{"name":"refname","type":"const char *","comment":"the name of the reference to check"}],"argline":"const git_refspec *refspec, const char *refname","sig":"const git_refspec *::const char *","return":{"type":"int","comment":" 1 if the refspec matches, 0 otherwise"},"description":"

Check if a refspec's source descriptor matches a reference

\n","comments":"","group":"refspec"},"git_refspec_dst_matches":{"type":"function","file":"refspec.h","line":80,"lineto":80,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"},{"name":"refname","type":"const char *","comment":"the name of the reference to check"}],"argline":"const git_refspec *refspec, const char *refname","sig":"const git_refspec *::const char *","return":{"type":"int","comment":" 1 if the refspec matches, 0 otherwise"},"description":"

Check if a refspec's destination descriptor matches a reference

\n","comments":"","group":"refspec"},"git_refspec_transform":{"type":"function","file":"refspec.h","line":90,"lineto":90,"args":[{"name":"out","type":"git_buf *","comment":"where to store the target name"},{"name":"spec","type":"const git_refspec *","comment":"the refspec"},{"name":"name","type":"const char *","comment":"the name of the reference to transform"}],"argline":"git_buf *out, const git_refspec *spec, const char *name","sig":"git_buf *::const git_refspec *::const char *","return":{"type":"int","comment":" 0, GIT_EBUFS or another error"},"description":"

Transform a reference to its target following the refspec's rules

\n","comments":"","group":"refspec"},"git_refspec_rtransform":{"type":"function","file":"refspec.h","line":100,"lineto":100,"args":[{"name":"out","type":"git_buf *","comment":"where to store the source reference name"},{"name":"spec","type":"const git_refspec *","comment":"the refspec"},{"name":"name","type":"const char *","comment":"the name of the reference to transform"}],"argline":"git_buf *out, const git_refspec *spec, const char *name","sig":"git_buf *::const git_refspec *::const char *","return":{"type":"int","comment":" 0, GIT_EBUFS or another error"},"description":"

Transform a target reference to its source reference following the refspec's rules

\n","comments":"","group":"refspec"},"git_remote_create":{"type":"function","file":"remote.h","line":39,"lineto":43,"args":[{"name":"out","type":"git_remote **","comment":"the resulting remote"},{"name":"repo","type":"git_repository *","comment":"the repository in which to create the remote"},{"name":"name","type":"const char *","comment":"the remote's name"},{"name":"url","type":"const char *","comment":"the remote's url"}],"argline":"git_remote **out, git_repository *repo, const char *name, const char *url","sig":"git_remote **::git_repository *::const char *::const char *","return":{"type":"int","comment":" 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code"},"description":"

Add a remote with the default fetch refspec to the repository's configuration. This\n calls git_remote_save before returning.

\n","comments":"","group":"remote"},"git_remote_create_with_fetchspec":{"type":"function","file":"remote.h","line":57,"lineto":62,"args":[{"name":"out","type":"git_remote **","comment":"the resulting remote"},{"name":"repo","type":"git_repository *","comment":"the repository in which to create the remote"},{"name":"name","type":"const char *","comment":"the remote's name"},{"name":"url","type":"const char *","comment":"the remote's url"},{"name":"fetch","type":"const char *","comment":"the remote fetch value"}],"argline":"git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch","sig":"git_remote **::git_repository *::const char *::const char *::const char *","return":{"type":"int","comment":" 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code"},"description":"

Add a remote with the provided fetch refspec (or default if NULL) to the repository's\n configuration. This\n calls git_remote_save before returning.

\n","comments":"","group":"remote"},"git_remote_create_anonymous":{"type":"function","file":"remote.h","line":80,"lineto":84,"args":[{"name":"out","type":"git_remote **","comment":"pointer to the new remote object"},{"name":"repo","type":"git_repository *","comment":"the associated repository"},{"name":"url","type":"const char *","comment":"the remote repository's URL"},{"name":"fetch","type":"const char *","comment":"the fetch refspec to use for this remote."}],"argline":"git_remote **out, git_repository *repo, const char *url, const char *fetch","sig":"git_remote **::git_repository *::const char *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an anonymous remote

\n","comments":"

Create a remote with the given url and refspec in memory. You can use\n this when you have a URL instead of a remote's name. Note that anonymous\n remotes cannot be converted to persisted remotes.

\n\n

The name, when provided, will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_create_anonymous-4"],"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_remote_create_anonymous-2"]}},"git_remote_load":{"type":"function","file":"remote.h","line":97,"lineto":97,"args":[{"name":"out","type":"git_remote **","comment":"pointer to the new remote object"},{"name":"repo","type":"git_repository *","comment":"the associated repository"},{"name":"name","type":"const char *","comment":"the remote's name"}],"argline":"git_remote **out, git_repository *repo, const char *name","sig":"git_remote **::git_repository *::const char *","return":{"type":"int","comment":" 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code"},"description":"

Get the information for a particular remote

\n","comments":"

The name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_load-5"],"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_remote_load-3"]}},"git_remote_save":{"type":"function","file":"remote.h","line":108,"lineto":108,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote to save to config"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"int","comment":" 0, GIT_EINVALIDSPEC or an error code"},"description":"

Save a remote to its repository's configuration

\n","comments":"

One can't save a in-memory remote. Doing so will\n result in a GIT_EINVALIDSPEC being returned.

\n","group":"remote"},"git_remote_dup":{"type":"function","file":"remote.h","line":120,"lineto":120,"args":[{"name":"dest","type":"git_remote **","comment":"pointer where to store the copy"},{"name":"source","type":"git_remote *","comment":"object to copy"}],"argline":"git_remote **dest, git_remote *source","sig":"git_remote **::git_remote *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a copy of an existing remote. All internal strings are also\n duplicated. Callbacks are not duplicated.

\n","comments":"

Call git_remote_free to free the data.

\n","group":"remote"},"git_remote_owner":{"type":"function","file":"remote.h","line":128,"lineto":128,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"git_repository *","comment":" a pointer to the repository"},"description":"

Get the remote's repository

\n","comments":"","group":"remote"},"git_remote_name":{"type":"function","file":"remote.h","line":136,"lineto":136,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"const char *","comment":" a pointer to the name or NULL for in-memory remotes"},"description":"

Get the remote's name

\n","comments":"","group":"remote"},"git_remote_url":{"type":"function","file":"remote.h","line":144,"lineto":144,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"const char *","comment":" a pointer to the url"},"description":"

Get the remote's url

\n","comments":"","group":"remote"},"git_remote_pushurl":{"type":"function","file":"remote.h","line":152,"lineto":152,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"const char *","comment":" a pointer to the url or NULL if no special url for pushing is set"},"description":"

Get the remote's url for pushing

\n","comments":"","group":"remote"},"git_remote_set_url":{"type":"function","file":"remote.h","line":163,"lineto":163,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"url","type":"const char *","comment":"the url to set"}],"argline":"git_remote *remote, const char *url","sig":"git_remote *::const char *","return":{"type":"int","comment":" 0 or an error value"},"description":"

Set the remote's url

\n","comments":"

Existing connections will not be updated.

\n","group":"remote"},"git_remote_set_pushurl":{"type":"function","file":"remote.h","line":174,"lineto":174,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"url","type":"const char *","comment":"the url to set or NULL to clear the pushurl"}],"argline":"git_remote *remote, const char *url","sig":"git_remote *::const char *","return":{"type":"int","comment":" 0 or an error value"},"description":"

Set the remote's url for pushing

\n","comments":"

Existing connections will not be updated.

\n","group":"remote"},"git_remote_add_fetch":{"type":"function","file":"remote.h","line":186,"lineto":186,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"refspec","type":"const char *","comment":"the new fetch refspec"}],"argline":"git_remote *remote, const char *refspec","sig":"git_remote *::const char *","return":{"type":"int","comment":" 0 or an error value"},"description":"

Add a fetch refspec to the remote

\n","comments":"

Convenience function for adding a single fetch refspec to the\n current list in the remote.

\n","group":"remote"},"git_remote_get_fetch_refspecs":{"type":"function","file":"remote.h","line":197,"lineto":197,"args":[{"name":"array","type":"git_strarray *","comment":"pointer to the array in which to store the strings"},{"name":"remote","type":"const git_remote *","comment":"the remote to query"}],"argline":"git_strarray *array, const git_remote *remote","sig":"git_strarray *::const git_remote *","return":{"type":"int","comment":null},"description":"

Get the remote's list of fetch refspecs

\n","comments":"

The memory is owned by the user and should be freed with\n git_strarray_free.

\n","group":"remote"},"git_remote_set_fetch_refspecs":{"type":"function","file":"remote.h","line":207,"lineto":207,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to modify"},{"name":"array","type":"git_strarray *","comment":"the new list of fetch resfpecs"}],"argline":"git_remote *remote, git_strarray *array","sig":"git_remote *::git_strarray *","return":{"type":"int","comment":null},"description":"

Set the remote's list of fetch refspecs

\n","comments":"

The contents of the string array are copied.

\n","group":"remote"},"git_remote_add_push":{"type":"function","file":"remote.h","line":219,"lineto":219,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"refspec","type":"const char *","comment":"the new push refspec"}],"argline":"git_remote *remote, const char *refspec","sig":"git_remote *::const char *","return":{"type":"int","comment":" 0 or an error value"},"description":"

Add a push refspec to the remote

\n","comments":"

Convenience function for adding a single push refspec to the\n current list in the remote.

\n","group":"remote"},"git_remote_get_push_refspecs":{"type":"function","file":"remote.h","line":230,"lineto":230,"args":[{"name":"array","type":"git_strarray *","comment":"pointer to the array in which to store the strings"},{"name":"remote","type":"const git_remote *","comment":"the remote to query"}],"argline":"git_strarray *array, const git_remote *remote","sig":"git_strarray *::const git_remote *","return":{"type":"int","comment":null},"description":"

Get the remote's list of push refspecs

\n","comments":"

The memory is owned by the user and should be freed with\n git_strarray_free.

\n","group":"remote"},"git_remote_set_push_refspecs":{"type":"function","file":"remote.h","line":240,"lineto":240,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to modify"},{"name":"array","type":"git_strarray *","comment":"the new list of push resfpecs"}],"argline":"git_remote *remote, git_strarray *array","sig":"git_remote *::git_strarray *","return":{"type":"int","comment":null},"description":"

Set the remote's list of push refspecs

\n","comments":"

The contents of the string array are copied.

\n","group":"remote"},"git_remote_clear_refspecs":{"type":"function","file":"remote.h","line":249,"lineto":249,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"void","comment":null},"description":"

Clear the refspecs

\n","comments":"

Remove all configured fetch and push refspecs from the remote.

\n","group":"remote"},"git_remote_refspec_count":{"type":"function","file":"remote.h","line":257,"lineto":257,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"size_t","comment":" the amount of refspecs configured in this remote"},"description":"

Get the number of refspecs for a remote

\n","comments":"","group":"remote"},"git_remote_get_refspec":{"type":"function","file":"remote.h","line":266,"lineto":266,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote to query"},{"name":"n","type":"size_t","comment":"the refspec to get"}],"argline":"const git_remote *remote, size_t n","sig":"const git_remote *::size_t","return":{"type":"const git_refspec *","comment":" the nth refspec"},"description":"

Get a refspec from the remote

\n","comments":"","group":"remote"},"git_remote_connect":{"type":"function","file":"remote.h","line":280,"lineto":280,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to connect to"},{"name":"direction","type":"git_direction","comment":"GIT_DIRECTION_FETCH if you want to fetch or\n GIT_DIRECTION_PUSH if you want to push"}],"argline":"git_remote *remote, git_direction direction","sig":"git_remote *::git_direction","return":{"type":"int","comment":" 0 or an error code"},"description":"

Open a connection to a remote

\n","comments":"

The transport is selected based on the URL. The direction argument\n is due to a limitation of the git protocol (over TCP or SSH) which\n starts up a specific binary which can only do the one or the other.

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_connect-6"],"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_remote_connect-4"]}},"git_remote_ls":{"type":"function","file":"remote.h","line":297,"lineto":297,"args":[{"name":"out","type":"const git_remote_head ***","comment":"pointer to the array"},{"name":"size","type":"size_t *","comment":"the number of remote heads"},{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"const git_remote_head ***out, size_t *size, git_remote *remote","sig":"const git_remote_head ***::size_t *::git_remote *","return":{"type":"int","comment":" 0 on success, or an error code"},"description":"

Get a list of refs at the remote

\n","comments":"

The remote (or more exactly its transport) must be connected. The\n memory belongs to the remote.

\n\n

The array will stay valid as long as the remote object exists and\n its transport isn't changed, but a copy is recommended for usage of\n the data.

\n","group":"remote","examples":{"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_remote_ls-5"]}},"git_remote_download":{"type":"function","file":"remote.h","line":311,"lineto":311,"args":[{"name":"remote","type":"git_remote *","comment":null}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Download and index the packfile

\n","comments":"

Connect to the remote if it hasn't been done yet, negotiate with\n the remote git which objects are missing, download and index the\n packfile.

\n\n

The .idx file will be created and both it and the packfile with be\n renamed to their final name.

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_download-7"]}},"git_remote_connected":{"type":"function","file":"remote.h","line":322,"lineto":322,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"int","comment":" 1 if it's connected, 0 otherwise."},"description":"

Check whether the remote is connected

\n","comments":"

Check whether the remote's underlying transport is connected to the\n remote host.

\n","group":"remote"},"git_remote_stop":{"type":"function","file":"remote.h","line":332,"lineto":332,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"void","comment":null},"description":"

Cancel the operation

\n","comments":"

At certain points in its operation, the network code checks whether\n the operation has been cancelled and if so stops the operation.

\n","group":"remote"},"git_remote_disconnect":{"type":"function","file":"remote.h","line":342,"lineto":342,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to disconnect from"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"void","comment":null},"description":"

Disconnect from the remote

\n","comments":"

Close the connection to the remote and free the underlying\n transport.

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_disconnect-8"]}},"git_remote_free":{"type":"function","file":"remote.h","line":352,"lineto":352,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to free"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"void","comment":null},"description":"

Free the memory associated with a remote

\n","comments":"

This also disconnects from the remote, if the connection\n has not been closed yet (using git_remote_disconnect).

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_free-9","ex/v0.21.2/network/fetch.html#git_remote_free-10"],"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_remote_free-6"]}},"git_remote_update_tips":{"type":"function","file":"remote.h","line":364,"lineto":367,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to update"},{"name":"signature","type":"const git_signature *","comment":"The identity to use when updating reflogs"},{"name":"reflog_message","type":"const char *","comment":"The message to insert into the reflogs. If NULL, the\n default is \"fetch \n\", where \n is the name of\n the remote (or its url, for in-memory remotes)."}],"argline":"git_remote *remote, const git_signature *signature, const char *reflog_message","sig":"git_remote *::const git_signature *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Update the tips to the new state

\n","comments":"","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_update_tips-11"]}},"git_remote_fetch":{"type":"function","file":"remote.h","line":381,"lineto":384,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to fetch from"},{"name":"signature","type":"const git_signature *","comment":"The identity to use when updating reflogs"},{"name":"reflog_message","type":"const char *","comment":"The message to insert into the reflogs. If NULL, the\n\t\t\t\t\t\t\t\t default is \"fetch\""}],"argline":"git_remote *remote, const git_signature *signature, const char *reflog_message","sig":"git_remote *::const git_signature *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Download new data and update tips

\n","comments":"

Convenience function to connect to a remote, download the data,\n disconnect and update the remote-tracking branches.

\n","group":"remote"},"git_remote_valid_url":{"type":"function","file":"remote.h","line":392,"lineto":392,"args":[{"name":"url","type":"const char *","comment":"the url to check"}],"argline":"const char *url","sig":"const char *","return":{"type":"int","comment":" 1 if the url is valid, 0 otherwise"},"description":"

Return whether a string is a valid remote URL

\n","comments":"","group":"remote"},"git_remote_supported_url":{"type":"function","file":"remote.h","line":400,"lineto":400,"args":[{"name":"url","type":"const char *","comment":"the url to check"}],"argline":"const char *url","sig":"const char *","return":{"type":"int","comment":" 1 if the url is supported, 0 otherwise"},"description":"

Return whether the passed URL is supported by this version of the library.

\n","comments":"","group":"remote"},"git_remote_list":{"type":"function","file":"remote.h","line":411,"lineto":411,"args":[{"name":"out","type":"git_strarray *","comment":"a string array which receives the names of the remotes"},{"name":"repo","type":"git_repository *","comment":"the repository to query"}],"argline":"git_strarray *out, git_repository *repo","sig":"git_strarray *::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get a list of the configured remotes for a repo

\n","comments":"

The string array must be freed by the user.

\n","group":"remote"},"git_remote_check_cert":{"type":"function","file":"remote.h","line":419,"lineto":419,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"check","type":"int","comment":"whether to check the server's certificate (defaults to yes)"}],"argline":"git_remote *remote, int check","sig":"git_remote *::int","return":{"type":"void","comment":null},"description":"

Choose whether to check the server's certificate (applies to HTTPS only)

\n","comments":"","group":"remote"},"git_remote_set_transport":{"type":"function","file":"remote.h","line":433,"lineto":435,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"transport","type":"git_transport *","comment":"the transport object for the remote to use"}],"argline":"git_remote *remote, git_transport *transport","sig":"git_remote *::git_transport *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Sets a custom transport for the remote. The caller can use this function\n to bypass the automatic discovery of a transport by URL scheme (i.e.\n http://, https://, git://) and supply their own transport to be used\n instead. After providing the transport to a remote using this function,\n the transport object belongs exclusively to that remote, and the remote will\n free it when it is freed with git_remote_free.

\n","comments":"","group":"remote"},"git_remote_init_callbacks":{"type":"function","file":"remote.h","line":508,"lineto":510,"args":[{"name":"opts","type":"git_remote_callbacks *","comment":"the `git_remote_callbacks` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_REMOTE_CALLBACKS_VERSION`"}],"argline":"git_remote_callbacks *opts, unsigned int version","sig":"git_remote_callbacks *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_remote_callbacks with default values. Equivalent to\n creating an instance with GIT_REMOTE_CALLBACKS_INIT.

\n","comments":"","group":"remote"},"git_remote_set_callbacks":{"type":"function","file":"remote.h","line":522,"lineto":522,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"callbacks","type":"const git_remote_callbacks *","comment":"a pointer to the user's callback settings"}],"argline":"git_remote *remote, const git_remote_callbacks *callbacks","sig":"git_remote *::const git_remote_callbacks *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Set the callbacks for a remote

\n","comments":"

Note that the remote keeps its own copy of the data and you need to\n call this function again if you want to change the callbacks.

\n","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_set_callbacks-12"],"network/ls-remote.c":["ex/v0.21.2/network/ls-remote.html#git_remote_set_callbacks-7"]}},"git_remote_get_callbacks":{"type":"function","file":"remote.h","line":533,"lineto":533,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to query"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const git_remote_callbacks *","comment":" a pointer to the callbacks structure"},"description":"

Retrieve the current callback structure

\n","comments":"

This provides read access to the callbacks structure as the remote\n sees it.

\n","group":"remote"},"git_remote_stats":{"type":"function","file":"remote.h","line":538,"lineto":538,"args":[{"name":"remote","type":"git_remote *","comment":null}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const git_transfer_progress *","comment":null},"description":"

Get the statistics structure that is filled in by the fetch operation.

\n","comments":"","group":"remote","examples":{"network/fetch.c":["ex/v0.21.2/network/fetch.html#git_remote_stats-13"]}},"git_remote_autotag":{"type":"function","file":"remote.h","line":552,"lineto":552,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote to query"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"git_remote_autotag_option_t","comment":" the auto-follow setting"},"description":"

Retrieve the tag auto-follow setting

\n","comments":"","group":"remote"},"git_remote_set_autotag":{"type":"function","file":"remote.h","line":560,"lineto":562,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"value","type":"git_remote_autotag_option_t","comment":"a GIT_REMOTE_DOWNLOAD_TAGS value"}],"argline":"git_remote *remote, git_remote_autotag_option_t value","sig":"git_remote *::git_remote_autotag_option_t","return":{"type":"void","comment":null},"description":"

Set the tag auto-follow setting

\n","comments":"","group":"remote"},"git_remote_rename":{"type":"function","file":"remote.h","line":582,"lineto":585,"args":[{"name":"problems","type":"git_strarray *","comment":"non-default refspecs cannot be renamed and will be\n stored here for further processing by the caller. Always free this\n strarray on succesful return."},{"name":"remote","type":"git_remote *","comment":"the remote to rename"},{"name":"new_name","type":"const char *","comment":"the new name the remote should bear"}],"argline":"git_strarray *problems, git_remote *remote, const char *new_name","sig":"git_strarray *::git_remote *::const char *","return":{"type":"int","comment":" 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code"},"description":"

Give the remote a new name

\n","comments":"

All remote-tracking branches and configuration settings\n for the remote are updated.

\n\n

The new name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n\n

A temporary in-memory remote cannot be given a name with this method.

\n","group":"remote"},"git_remote_update_fetchhead":{"type":"function","file":"remote.h","line":593,"lineto":593,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to query"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"int","comment":" the update FETCH_HEAD setting"},"description":"

Retrieve the update FETCH_HEAD setting.

\n","comments":"","group":"remote"},"git_remote_set_update_fetchhead":{"type":"function","file":"remote.h","line":602,"lineto":602,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"value","type":"int","comment":"0 to disable updating FETCH_HEAD"}],"argline":"git_remote *remote, int value","sig":"git_remote *::int","return":{"type":"void","comment":null},"description":"

Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be\n updated on every fetch. Set to 0 to disable.

\n","comments":"","group":"remote"},"git_remote_is_valid_name":{"type":"function","file":"remote.h","line":610,"lineto":610,"args":[{"name":"remote_name","type":"const char *","comment":"name to be checked."}],"argline":"const char *remote_name","sig":"const char *","return":{"type":"int","comment":" 1 if the reference name is acceptable; 0 if it isn't"},"description":"

Ensure the remote name is well-formed.

\n","comments":"","group":"remote"},"git_remote_delete":{"type":"function","file":"remote.h","line":621,"lineto":621,"args":[{"name":"remote","type":"git_remote *","comment":"A valid remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"int","comment":" 0 on success, or an error code."},"description":"

Delete an existing persisted remote.

\n","comments":"

All remote-tracking branches and configuration settings\n for the remote will be removed.

\n","group":"remote"},"git_remote_default_branch":{"type":"function","file":"remote.h","line":639,"lineto":639,"args":[{"name":"out","type":"git_buf *","comment":"the buffern in which to store the reference name"},{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_buf *out, git_remote *remote","sig":"git_buf *::git_remote *","return":{"type":"int","comment":" 0, GIT_ENOTFOUND if the remote does not have any references\n or none of them point to HEAD's commit, or an error message."},"description":"

Retrieve the name of the remote's default branch

\n","comments":"

The default branch of a repository is the branch which HEAD points\n to. If the remote does not support reporting this information\n directly, it performs the guess as git does; that is, if there are\n multiple branches which point to the same commit, the first one is\n chosen. If the master branch is a candidate, it wins.

\n\n

This function must only be called after connecting.

\n","group":"remote"},"git_repository_open":{"type":"function","file":"repository.h","line":37,"lineto":37,"args":[{"name":"out","type":"git_repository **","comment":"pointer to the repo which will be opened"},{"name":"path","type":"const char *","comment":"the path to the repository"}],"argline":"git_repository **out, const char *path","sig":"git_repository **::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Open a git repository.

\n","comments":"

The 'path' argument must point to either a git repository\n folder, or an existing work dir.

\n\n

The method will automatically detect if 'path' is a normal\n or bare repository or fail is 'path' is neither.

\n","group":"repository","examples":{"general.c":["ex/v0.21.2/general.html#git_repository_open-57"],"network/git2.c":["ex/v0.21.2/network/git2.html#git_repository_open-3"]}},"git_repository_wrap_odb":{"type":"function","file":"repository.h","line":50,"lineto":50,"args":[{"name":"out","type":"git_repository **","comment":"pointer to the repo"},{"name":"odb","type":"git_odb *","comment":"the object database to wrap"}],"argline":"git_repository **out, git_odb *odb","sig":"git_repository **::git_odb *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a "fake" repository to wrap an object database

\n","comments":"

Create a repository object to wrap an object database to be used\n with the API when all you have is an object database. This doesn't\n have any paths associated with it, so use with care.

\n","group":"repository"},"git_repository_discover":{"type":"function","file":"repository.h","line":78,"lineto":82,"args":[{"name":"out","type":"git_buf *","comment":"A pointer to a user-allocated git_buf which will contain\n the found path."},{"name":"start_path","type":"const char *","comment":"The base path where the lookup starts."},{"name":"across_fs","type":"int","comment":"If true, then the lookup will not stop when a\n filesystem device change is detected while exploring parent directories."},{"name":"ceiling_dirs","type":"const char *","comment":"A GIT_PATH_LIST_SEPARATOR separated list of\n absolute symbolic link free paths. The lookup will stop when any\n of this paths is reached. Note that the lookup always performs on\n start_path no matter start_path appears in ceiling_dirs ceiling_dirs\n might be NULL (which is equivalent to an empty string)"}],"argline":"git_buf *out, const char *start_path, int across_fs, const char *ceiling_dirs","sig":"git_buf *::const char *::int::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Look for a git repository and copy its path in the given buffer.\n The lookup start from base_path and walk across parent directories\n if nothing has been found. The lookup ends when the first repository\n is found, or when reaching a directory referenced in ceiling_dirs\n or when the filesystem changes (in case across_fs is true).

\n","comments":"

The method will automatically detect if the repository is bare\n (if there is a repository).

\n","group":"repository"},"git_repository_open_ext":{"type":"function","file":"repository.h","line":122,"lineto":126,"args":[{"name":"out","type":"git_repository **","comment":"Pointer to the repo which will be opened. This can\n actually be NULL if you only want to use the error code to\n see if a repo at this path could be opened."},{"name":"path","type":"const char *","comment":"Path to open as git repository. If the flags\n permit \"searching\", then this can be a path to a subdirectory\n inside the working directory of the repository."},{"name":"flags","type":"unsigned int","comment":"A combination of the GIT_REPOSITORY_OPEN flags above."},{"name":"ceiling_dirs","type":"const char *","comment":"A GIT_PATH_LIST_SEPARATOR delimited list of path\n prefixes at which the search for a containing repository should\n terminate."}],"argline":"git_repository **out, const char *path, unsigned int flags, const char *ceiling_dirs","sig":"git_repository **::const char *::unsigned int::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if no repository could be found,\n or -1 if there was a repository but open failed for some reason\n (such as repo corruption or system errors)."},"description":"

Find and open a repository with extended controls.

\n","comments":"","group":"repository","examples":{"blame.c":["ex/v0.21.2/blame.html#git_repository_open_ext-22"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_repository_open_ext-29"],"diff.c":["ex/v0.21.2/diff.html#git_repository_open_ext-13"],"log.c":["ex/v0.21.2/log.html#git_repository_open_ext-42","ex/v0.21.2/log.html#git_repository_open_ext-43"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_repository_open_ext-14"],"status.c":["ex/v0.21.2/status.html#git_repository_open_ext-3"],"tag.c":["ex/v0.21.2/tag.html#git_repository_open_ext-9"]}},"git_repository_open_bare":{"type":"function","file":"repository.h","line":139,"lineto":139,"args":[{"name":"out","type":"git_repository **","comment":"Pointer to the repo which will be opened."},{"name":"bare_path","type":"const char *","comment":"Direct path to the bare repository"}],"argline":"git_repository **out, const char *bare_path","sig":"git_repository **::const char *","return":{"type":"int","comment":" 0 on success, or an error code"},"description":"

Open a bare repository on the serverside.

\n","comments":"

This is a fast open for bare repositories that will come in handy\n if you're e.g. hosting git repositories and need to access them\n efficiently

\n","group":"repository"},"git_repository_free":{"type":"function","file":"repository.h","line":152,"lineto":152,"args":[{"name":"repo","type":"git_repository *","comment":"repository handle to close. If NULL nothing occurs."}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"void","comment":null},"description":"

Free a previously allocated repository

\n","comments":"

Note that after a repository is free'd, all the objects it has spawned\n will still exist until they are manually closed by the user\n with git_object_free, but accessing any of the attributes of\n an object without a backing repository will result in undefined\n behavior

\n","group":"repository","examples":{"blame.c":["ex/v0.21.2/blame.html#git_repository_free-23"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_repository_free-30"],"diff.c":["ex/v0.21.2/diff.html#git_repository_free-14"],"general.c":["ex/v0.21.2/general.html#git_repository_free-58"],"init.c":["ex/v0.21.2/init.html#git_repository_free-4"],"log.c":["ex/v0.21.2/log.html#git_repository_free-44"],"network/clone.c":["ex/v0.21.2/network/clone.html#git_repository_free-3"],"network/git2.c":["ex/v0.21.2/network/git2.html#git_repository_free-4"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_repository_free-15"],"status.c":["ex/v0.21.2/status.html#git_repository_free-4"],"tag.c":["ex/v0.21.2/tag.html#git_repository_free-10"]}},"git_repository_init":{"type":"function","file":"repository.h","line":169,"lineto":172,"args":[{"name":"out","type":"git_repository **","comment":"pointer to the repo which will be created or reinitialized"},{"name":"path","type":"const char *","comment":"the path to the repository"},{"name":"is_bare","type":"unsigned int","comment":"if true, a Git repository without a working directory is\n\t\tcreated at the pointed path. If false, provided path will be\n\t\tconsidered as the working directory into which the .git directory\n\t\twill be created."}],"argline":"git_repository **out, const char *path, unsigned int is_bare","sig":"git_repository **::const char *::unsigned int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Creates a new Git repository in the given folder.

\n","comments":"

TODO:\n - Reinit the repository

\n","group":"repository","examples":{"init.c":["ex/v0.21.2/init.html#git_repository_init-5"]}},"git_repository_init_init_options":{"type":"function","file":"repository.h","line":278,"lineto":280,"args":[{"name":"opts","type":"git_repository_init_options *","comment":"the `git_repository_init_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_REPOSITORY_INIT_OPTIONS_VERSION`"}],"argline":"git_repository_init_options *opts, unsigned int version","sig":"git_repository_init_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_repository_init_options with default values. Equivalent\n to creating an instance with GIT_REPOSITORY_INIT_OPTIONS_INIT.

\n","comments":"","group":"repository"},"git_repository_init_ext":{"type":"function","file":"repository.h","line":295,"lineto":298,"args":[{"name":"out","type":"git_repository **","comment":"Pointer to the repo which will be created or reinitialized."},{"name":"repo_path","type":"const char *","comment":"The path to the repository."},{"name":"opts","type":"git_repository_init_options *","comment":"Pointer to git_repository_init_options struct."}],"argline":"git_repository **out, const char *repo_path, git_repository_init_options *opts","sig":"git_repository **::const char *::git_repository_init_options *","return":{"type":"int","comment":" 0 or an error code on failure."},"description":"

Create a new Git repository in the given folder with extended controls.

\n","comments":"

This will initialize a new git repository (creating the repo_path\n if requested by flags) and working directory as needed. It will\n auto-detect the case sensitivity of the file system and if the\n file system supports file mode bits correctly.

\n","group":"repository","examples":{"init.c":["ex/v0.21.2/init.html#git_repository_init_ext-6"]}},"git_repository_head":{"type":"function","file":"repository.h","line":313,"lineto":313,"args":[{"name":"out","type":"git_reference **","comment":"pointer to the reference which will be retrieved"},{"name":"repo","type":"git_repository *","comment":"a repository object"}],"argline":"git_reference **out, git_repository *repo","sig":"git_reference **::git_repository *","return":{"type":"int","comment":" 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing\n branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise"},"description":"

Retrieve and resolve the reference pointed at by HEAD.

\n","comments":"

The returned git_reference will be owned by caller and\n git_reference_free() must be called when done with it to release the\n allocated memory and prevent a leak.

\n","group":"repository","examples":{"status.c":["ex/v0.21.2/status.html#git_repository_head-5"]}},"git_repository_head_detached":{"type":"function","file":"repository.h","line":325,"lineto":325,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 1 if HEAD is detached, 0 if it's not; error code if there\n was an error."},"description":"

Check if a repository's HEAD is detached

\n","comments":"

A repository's HEAD is detached when it points directly to a commit\n instead of a branch.

\n","group":"repository"},"git_repository_head_unborn":{"type":"function","file":"repository.h","line":337,"lineto":337,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 1 if the current branch is unborn, 0 if it's not; error\n code if there was an error"},"description":"

Check if the current branch is unborn

\n","comments":"

An unborn branch is one named from HEAD but which doesn't exist in\n the refs namespace, because it doesn't have any commit to point to.

\n","group":"repository"},"git_repository_is_empty":{"type":"function","file":"repository.h","line":349,"lineto":349,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 1 if the repository is empty, 0 if it isn't, error code\n if the repository is corrupted"},"description":"

Check if a repository is empty

\n","comments":"

An empty repository has just been initialized and contains\n no references.

\n","group":"repository"},"git_repository_path":{"type":"function","file":"repository.h","line":360,"lineto":360,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"const char *","comment":" the path to the repository"},"description":"

Get the path of this repository

\n","comments":"

This is the path of the .git folder for normal repositories,\n or of the repository itself for bare repositories.

\n","group":"repository","examples":{"init.c":["ex/v0.21.2/init.html#git_repository_path-7"],"status.c":["ex/v0.21.2/status.html#git_repository_path-6"]}},"git_repository_workdir":{"type":"function","file":"repository.h","line":371,"lineto":371,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"const char *","comment":" the path to the working dir, if it exists"},"description":"

Get the path of the working directory for this repository

\n","comments":"

If the repository is bare, this function will always return\n NULL.

\n","group":"repository","examples":{"init.c":["ex/v0.21.2/init.html#git_repository_workdir-8"]}},"git_repository_set_workdir":{"type":"function","file":"repository.h","line":390,"lineto":391,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"workdir","type":"const char *","comment":"The path to a working directory"},{"name":"update_gitlink","type":"int","comment":"Create/update gitlink in workdir and set config\n \"core.worktree\" (if workdir is not the parent of the .git directory)"}],"argline":"git_repository *repo, const char *workdir, int update_gitlink","sig":"git_repository *::const char *::int","return":{"type":"int","comment":" 0, or an error code"},"description":"

Set the path to the working directory for this repository

\n","comments":"

The working directory doesn't need to be the same one\n that contains the .git folder for this repository.

\n\n

If this repository is bare, setting its working directory\n will turn it into a normal repository, capable of performing\n all the common workdir operations (checkout, status, index\n manipulation, etc).

\n","group":"repository"},"git_repository_is_bare":{"type":"function","file":"repository.h","line":399,"lineto":399,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 1 if the repository is bare, 0 otherwise."},"description":"

Check if a repository is bare

\n","comments":"","group":"repository","examples":{"status.c":["ex/v0.21.2/status.html#git_repository_is_bare-7"]}},"git_repository_config":{"type":"function","file":"repository.h","line":415,"lineto":415,"args":[{"name":"out","type":"git_config **","comment":"Pointer to store the loaded configuration"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_config **out, git_repository *repo","sig":"git_config **::git_repository *","return":{"type":"int","comment":" 0, or an error code"},"description":"

Get the configuration file for this repository.

\n","comments":"

If a configuration file has not been set, the default\n config set for the repository will be returned, including\n global and system configurations (if they are available).

\n\n

The configuration file must be freed once it's no longer\n being used by the user.

\n","group":"repository"},"git_repository_config_snapshot":{"type":"function","file":"repository.h","line":431,"lineto":431,"args":[{"name":"out","type":"git_config **","comment":"Pointer to store the loaded configuration"},{"name":"repo","type":"git_repository *","comment":"the repository"}],"argline":"git_config **out, git_repository *repo","sig":"git_config **::git_repository *","return":{"type":"int","comment":" 0, or an error code"},"description":"

Get a snapshot of the repository's configuration

\n","comments":"

Convenience function to take a snapshot from the repository's\n configuration. The contents of this snapshot will not change,\n even if the underlying config files are modified.

\n\n

The configuration file must be freed once it's no longer\n being used by the user.

\n","group":"repository"},"git_repository_odb":{"type":"function","file":"repository.h","line":447,"lineto":447,"args":[{"name":"out","type":"git_odb **","comment":"Pointer to store the loaded ODB"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_odb **out, git_repository *repo","sig":"git_odb **::git_repository *","return":{"type":"int","comment":" 0, or an error code"},"description":"

Get the Object Database for this repository.

\n","comments":"

If a custom ODB has not been set, the default\n database for the repository will be returned (the one\n located in .git/objects).

\n\n

The ODB must be freed once it's no longer being used by\n the user.

\n","group":"repository","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_repository_odb-31"],"general.c":["ex/v0.21.2/general.html#git_repository_odb-59"]}},"git_repository_refdb":{"type":"function","file":"repository.h","line":463,"lineto":463,"args":[{"name":"out","type":"git_refdb **","comment":"Pointer to store the loaded refdb"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_refdb **out, git_repository *repo","sig":"git_refdb **::git_repository *","return":{"type":"int","comment":" 0, or an error code"},"description":"

Get the Reference Database Backend for this repository.

\n","comments":"

If a custom refsdb has not been set, the default database for\n the repository will be returned (the one that manipulates loose\n and packed references in the .git directory).

\n\n

The refdb must be freed once it's no longer being used by\n the user.

\n","group":"repository"},"git_repository_index":{"type":"function","file":"repository.h","line":479,"lineto":479,"args":[{"name":"out","type":"git_index **","comment":"Pointer to store the loaded index"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_index **out, git_repository *repo","sig":"git_index **::git_repository *","return":{"type":"int","comment":" 0, or an error code"},"description":"

Get the Index file for this repository.

\n","comments":"

If a custom index has not been set, the default\n index for the repository will be returned (the one\n located in .git/index).

\n\n

The index must be freed once it's no longer being used by\n the user.

\n","group":"repository","examples":{"general.c":["ex/v0.21.2/general.html#git_repository_index-60"],"init.c":["ex/v0.21.2/init.html#git_repository_index-9"]}},"git_repository_message":{"type":"function","file":"repository.h","line":497,"lineto":497,"args":[{"name":"out","type":"git_buf *","comment":"git_buf to write data into"},{"name":"repo","type":"git_repository *","comment":"Repository to read prepared message from"}],"argline":"git_buf *out, git_repository *repo","sig":"git_buf *::git_repository *","return":{"type":"int","comment":" 0, GIT_ENOTFOUND if no message exists or an error code"},"description":"

Retrieve git's prepared message

\n","comments":"

Operations such as git revert/cherry-pick/merge with the -n option\n stop just short of creating a commit with the changes and save\n their prepared message in .git/MERGE_MSG so the next git-commit\n execution can present it to the user for them to amend if they\n wish.

\n\n

Use this function to get the contents of this file. Don't forget to\n remove the file after you create the commit.

\n","group":"repository"},"git_repository_message_remove":{"type":"function","file":"repository.h","line":504,"lineto":504,"args":[{"name":"repo","type":"git_repository *","comment":null}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":null},"description":"

Remove git's prepared message.

\n","comments":"

Remove the message that git_repository_message retrieves.

\n","group":"repository"},"git_repository_state_cleanup":{"type":"function","file":"repository.h","line":513,"lineto":513,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 0 on success, or error"},"description":"

Remove all the metadata associated with an ongoing command like merge,\n revert, cherry-pick, etc. For example: MERGE_HEAD, MERGE_MSG, etc.

\n","comments":"","group":"repository"},"git_repository_fetchhead_foreach":{"type":"function","file":"repository.h","line":532,"lineto":535,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"callback","type":"git_repository_fetchhead_foreach_cb","comment":"Callback function"},{"name":"payload","type":"void *","comment":"Pointer to callback data (optional)"}],"argline":"git_repository *repo, git_repository_fetchhead_foreach_cb callback, void *payload","sig":"git_repository *::git_repository_fetchhead_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, GIT_ENOTFOUND if\n there is no FETCH_HEAD file, or other error code."},"description":"

Invoke 'callback' for each entry in the given FETCH_HEAD file.

\n","comments":"

Return a non-zero value from the callback to stop the loop.

\n","group":"repository"},"git_repository_mergehead_foreach":{"type":"function","file":"repository.h","line":552,"lineto":555,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"callback","type":"git_repository_mergehead_foreach_cb","comment":"Callback function"},{"name":"payload","type":"void *","comment":"Pointer to callback data (optional)"}],"argline":"git_repository *repo, git_repository_mergehead_foreach_cb callback, void *payload","sig":"git_repository *::git_repository_mergehead_foreach_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, GIT_ENOTFOUND if\n there is no MERGE_HEAD file, or other error code."},"description":"

If a merge is in progress, invoke 'callback' for each commit ID in the\n MERGE_HEAD file.

\n","comments":"

Return a non-zero value from the callback to stop the loop.

\n","group":"repository"},"git_repository_hashfile":{"type":"function","file":"repository.h","line":580,"lineto":585,"args":[{"name":"out","type":"git_oid *","comment":"Output value of calculated SHA"},{"name":"repo","type":"git_repository *","comment":"Repository pointer"},{"name":"path","type":"const char *","comment":"Path to file on disk whose contents should be hashed. If the\n repository is not NULL, this can be a relative path."},{"name":"type","type":"git_otype","comment":"The object type to hash as (e.g. GIT_OBJ_BLOB)"},{"name":"as_path","type":"const char *","comment":"The path to use to look up filtering rules. If this is\n NULL, then the `path` parameter will be used instead. If\n this is passed as the empty string, then no filters will be\n applied when calculating the hash."}],"argline":"git_oid *out, git_repository *repo, const char *path, git_otype type, const char *as_path","sig":"git_oid *::git_repository *::const char *::git_otype::const char *","return":{"type":"int","comment":" 0 on success, or an error code"},"description":"

Calculate hash of file using repository filtering rules.

\n","comments":"

If you simply want to calculate the hash of a file on disk with no filters,\n you can just use the git_odb_hashfile() API. However, if you want to\n hash a file in the repository and you want to apply filtering rules (e.g.\n crlf filters) before generating the SHA, then use this function.

\n\n

Note: if the repository has core.safecrlf set to fail and the\n filtering triggers that failure, then this function will return an\n error and not calculate the hash of the file.

\n","group":"repository"},"git_repository_set_head":{"type":"function","file":"repository.h","line":607,"lineto":611,"args":[{"name":"repo","type":"git_repository *","comment":"Repository pointer"},{"name":"refname","type":"const char *","comment":"Canonical name of the reference the HEAD should point at"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_repository *repo, const char *refname, const git_signature *signature, const char *log_message","sig":"git_repository *::const char *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, or an error code"},"description":"

Make the repository HEAD point to the specified reference.

\n","comments":"

If the provided reference points to a Tree or a Blob, the HEAD is\n unaltered and -1 is returned.

\n\n

If the provided reference points to a branch, the HEAD will point\n to that branch, staying attached, or become attached if it isn't yet.\n If the branch doesn't exist yet, no error will be return. The HEAD\n will then be attached to an unborn branch.

\n\n

Otherwise, the HEAD will be detached and will directly point to\n the Commit.

\n","group":"repository"},"git_repository_set_head_detached":{"type":"function","file":"repository.h","line":631,"lineto":635,"args":[{"name":"repo","type":"git_repository *","comment":"Repository pointer"},{"name":"commitish","type":"const git_oid *","comment":"Object id of the Commit the HEAD should point to"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"log_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_repository *repo, const git_oid *commitish, const git_signature *signature, const char *log_message","sig":"git_repository *::const git_oid *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, or an error code"},"description":"

Make the repository HEAD directly point to the Commit.

\n","comments":"

If the provided committish cannot be found in the repository, the HEAD\n is unaltered and GIT_ENOTFOUND is returned.

\n\n

If the provided commitish cannot be peeled into a commit, the HEAD\n is unaltered and -1 is returned.

\n\n

Otherwise, the HEAD will eventually be detached and will directly point to\n the peeled Commit.

\n","group":"repository"},"git_repository_detach_head":{"type":"function","file":"repository.h","line":656,"lineto":659,"args":[{"name":"repo","type":"git_repository *","comment":"Repository pointer"},{"name":"signature","type":"const git_signature *","comment":"The identity that will used to populate the reflog entry"},{"name":"reflog_message","type":"const char *","comment":"The one line long message to be appended to the reflog"}],"argline":"git_repository *repo, const git_signature *signature, const char *reflog_message","sig":"git_repository *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing\n branch or an error code"},"description":"

Detach the HEAD.

\n","comments":"

If the HEAD is already detached and points to a Commit, 0 is returned.

\n\n

If the HEAD is already detached and points to a Tag, the HEAD is\n updated into making it point to the peeled Commit, and 0 is returned.

\n\n

If the HEAD is already detached and points to a non commitish, the HEAD is\n unaltered, and -1 is returned.

\n\n

Otherwise, the HEAD will be detached and point to the peeled Commit.

\n","group":"repository"},"git_repository_state":{"type":"function","file":"repository.h","line":681,"lineto":681,"args":[{"name":"repo","type":"git_repository *","comment":"Repository pointer"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" The state of the repository"},"description":"

Determines the status of a git repository - ie, whether an operation\n (merge, cherry-pick, etc) is in progress.

\n","comments":"","group":"repository"},"git_repository_set_namespace":{"type":"function","file":"repository.h","line":695,"lineto":695,"args":[{"name":"repo","type":"git_repository *","comment":"The repo"},{"name":"nmspace","type":"const char *","comment":"The namespace. This should not include the refs\n\tfolder, e.g. to namespace all references under `refs/namespaces/foo/`,\n\tuse `foo` as the namespace."}],"argline":"git_repository *repo, const char *nmspace","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 on success, -1 on error"},"description":"

Sets the active namespace for this Git Repository

\n","comments":"

This namespace affects all reference operations for the repo.\n See man gitnamespaces

\n","group":"repository"},"git_repository_get_namespace":{"type":"function","file":"repository.h","line":703,"lineto":703,"args":[{"name":"repo","type":"git_repository *","comment":"The repo"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"const char *","comment":" the active namespace, or NULL if there isn't one"},"description":"

Get the currently active namespace for this repository

\n","comments":"","group":"repository"},"git_repository_is_shallow":{"type":"function","file":"repository.h","line":712,"lineto":712,"args":[{"name":"repo","type":"git_repository *","comment":"The repository"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":" 1 if shallow, zero if not"},"description":"

Determine if the repository was a shallow clone

\n","comments":"","group":"repository"},"git_revert_init_options":{"type":"function","file":"revert.h","line":44,"lineto":46,"args":[{"name":"opts","type":"git_revert_options *","comment":"the `git_revert_options` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_REVERT_OPTIONS_VERSION`"}],"argline":"git_revert_options *opts, unsigned int version","sig":"git_revert_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_revert_options with default values. Equivalent to\n creating an instance with GIT_REVERT_OPTIONS_INIT.

\n","comments":"","group":"revert"},"git_revert_commit":{"type":"function","file":"revert.h","line":62,"lineto":68,"args":[{"name":"out","type":"git_index **","comment":"pointer to store the index result in"},{"name":"repo","type":"git_repository *","comment":"the repository that contains the given commits"},{"name":"revert_commit","type":"git_commit *","comment":"the commit to revert"},{"name":"our_commit","type":"git_commit *","comment":"the commit to revert against (eg, HEAD)"},{"name":"mainline","type":"unsigned int","comment":"the parent of the revert commit, if it is a merge"},{"name":"merge_options","type":"const git_merge_options *","comment":"the merge options (or null for defaults)"}],"argline":"git_index **out, git_repository *repo, git_commit *revert_commit, git_commit *our_commit, unsigned int mainline, const git_merge_options *merge_options","sig":"git_index **::git_repository *::git_commit *::git_commit *::unsigned int::const git_merge_options *","return":{"type":"int","comment":" zero on success, -1 on failure."},"description":"

Reverts the given commit against the given "our" commit, producing an\n index that reflects the result of the revert.

\n","comments":"

The returned index must be freed explicitly with git_index_free.

\n","group":"revert"},"git_revert":{"type":"function","file":"revert.h","line":78,"lineto":81,"args":[{"name":"repo","type":"git_repository *","comment":"the repository to revert"},{"name":"commit","type":"git_commit *","comment":"the commit to revert"},{"name":"given_opts","type":"const git_revert_options *","comment":"merge flags"}],"argline":"git_repository *repo, git_commit *commit, const git_revert_options *given_opts","sig":"git_repository *::git_commit *::const git_revert_options *","return":{"type":"int","comment":" zero on success, -1 on failure."},"description":"

Reverts the given commit, producing changes in the working directory.

\n","comments":"","group":"revert"},"git_revparse_single":{"type":"function","file":"revparse.h","line":37,"lineto":38,"args":[{"name":"out","type":"git_object **","comment":"pointer to output object"},{"name":"repo","type":"git_repository *","comment":"the repository to search in"},{"name":"spec","type":"const char *","comment":"the textual specification for an object"}],"argline":"git_object **out, git_repository *repo, const char *spec","sig":"git_object **::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC or an error code"},"description":"

Find a single object, as specified by a revision string.

\n","comments":"

See man gitrevisions, or\n http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for\n information on the syntax accepted.

\n\n

The returned object should be released with git_object_free when no\n longer needed.

\n","group":"revparse","examples":{"blame.c":["ex/v0.21.2/blame.html#git_revparse_single-24"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_revparse_single-32"],"log.c":["ex/v0.21.2/log.html#git_revparse_single-45"],"tag.c":["ex/v0.21.2/tag.html#git_revparse_single-11","ex/v0.21.2/tag.html#git_revparse_single-12","ex/v0.21.2/tag.html#git_revparse_single-13","ex/v0.21.2/tag.html#git_revparse_single-14"]}},"git_revparse_ext":{"type":"function","file":"revparse.h","line":61,"lineto":65,"args":[{"name":"object_out","type":"git_object **","comment":"pointer to output object"},{"name":"reference_out","type":"git_reference **","comment":"pointer to output reference or NULL"},{"name":"repo","type":"git_repository *","comment":"the repository to search in"},{"name":"spec","type":"const char *","comment":"the textual specification for an object"}],"argline":"git_object **object_out, git_reference **reference_out, git_repository *repo, const char *spec","sig":"git_object **::git_reference **::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC\n or an error code"},"description":"

Find a single object and intermediate reference by a revision string.

\n","comments":"

See man gitrevisions, or\n http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for\n information on the syntax accepted.

\n\n

In some cases (\n@\n{\n<\n-n>} or `\n<branchname

\n\n
\n

@\n{upstream}), the expression may\n point to an intermediate reference. When such expressions are being passed\n in,reference_out` will be valued as well.

\n
\n\n

The returned object should be released with git_object_free and the\n returned reference with git_reference_free when no longer needed.

\n","group":"revparse"},"git_revparse":{"type":"function","file":"revparse.h","line":105,"lineto":108,"args":[{"name":"revspec","type":"git_revspec *","comment":"Pointer to an user-allocated git_revspec struct where\n\t the result of the rev-parse will be stored"},{"name":"repo","type":"git_repository *","comment":"the repository to search in"},{"name":"spec","type":"const char *","comment":"the rev-parse spec to parse"}],"argline":"git_revspec *revspec, git_repository *repo, const char *spec","sig":"git_revspec *::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code"},"description":"

Parse a revision string for from, to, and intent.

\n","comments":"

See man gitrevisions or\n http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for\n information on the syntax accepted.

\n","group":"revparse","examples":{"blame.c":["ex/v0.21.2/blame.html#git_revparse-25"],"log.c":["ex/v0.21.2/log.html#git_revparse-46"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_revparse-16","ex/v0.21.2/rev-parse.html#git_revparse-17"]}},"git_revwalk_new":{"type":"function","file":"revwalk.h","line":70,"lineto":70,"args":[{"name":"out","type":"git_revwalk **","comment":"pointer to the new revision walker"},{"name":"repo","type":"git_repository *","comment":"the repo to walk through"}],"argline":"git_revwalk **out, git_repository *repo","sig":"git_revwalk **::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Allocate a new revision walker to iterate through a repo.

\n","comments":"

This revision walker uses a custom memory pool and an internal\n commit cache, so it is relatively expensive to allocate.

\n\n

For maximum performance, this revision walker should be\n reused for different walks.

\n\n

This revision walker is not thread safe: it may only be\n used to walk a repository on a single thread; however,\n it is possible to have several revision walkers in\n several different threads walking the same repository.

\n","group":"revwalk","examples":{"general.c":["ex/v0.21.2/general.html#git_revwalk_new-61"],"log.c":["ex/v0.21.2/log.html#git_revwalk_new-47","ex/v0.21.2/log.html#git_revwalk_new-48"]}},"git_revwalk_reset":{"type":"function","file":"revwalk.h","line":85,"lineto":85,"args":[{"name":"walker","type":"git_revwalk *","comment":"handle to reset."}],"argline":"git_revwalk *walker","sig":"git_revwalk *","return":{"type":"void","comment":null},"description":"

Reset the revision walker for reuse.

\n","comments":"

This will clear all the pushed and hidden commits, and\n leave the walker in a blank state (just like at\n creation) ready to receive new commit pushes and\n start a new walk.

\n\n

The revision walk is automatically reset when a walk\n is over.

\n","group":"revwalk"},"git_revwalk_push":{"type":"function","file":"revwalk.h","line":102,"lineto":102,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal."},{"name":"id","type":"const git_oid *","comment":"the oid of the commit to start from."}],"argline":"git_revwalk *walk, const git_oid *id","sig":"git_revwalk *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Mark a commit to start traversal from.

\n","comments":"

The given OID must belong to a committish on the walked\n repository.

\n\n

The given commit will be used as one of the roots\n when starting the revision walk. At least one commit\n must be pushed onto the walker before a walk can\n be started.

\n","group":"revwalk","examples":{"general.c":["ex/v0.21.2/general.html#git_revwalk_push-62"],"log.c":["ex/v0.21.2/log.html#git_revwalk_push-49"]}},"git_revwalk_push_glob":{"type":"function","file":"revwalk.h","line":120,"lineto":120,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"glob","type":"const char *","comment":"the glob pattern references should match"}],"argline":"git_revwalk *walk, const char *glob","sig":"git_revwalk *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Push matching references

\n","comments":"

The OIDs pointed to by the references that match the given glob\n pattern will be pushed to the revision walker.

\n\n

A leading 'refs/' is implied if not present as well as a trailing\n '/\n\\\n*' if the glob lacks '?', '\n\\\n*' or '['.

\n\n

Any references matching this glob which do not point to a\n committish will be ignored.

\n","group":"revwalk"},"git_revwalk_push_head":{"type":"function","file":"revwalk.h","line":128,"lineto":128,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Push the repository's HEAD

\n","comments":"","group":"revwalk","examples":{"log.c":["ex/v0.21.2/log.html#git_revwalk_push_head-50"]}},"git_revwalk_hide":{"type":"function","file":"revwalk.h","line":143,"lineto":143,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal."},{"name":"commit_id","type":"const git_oid *","comment":"the oid of commit that will be ignored during the traversal"}],"argline":"git_revwalk *walk, const git_oid *commit_id","sig":"git_revwalk *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Mark a commit (and its ancestors) uninteresting for the output.

\n","comments":"

The given OID must belong to a committish on the walked\n repository.

\n\n

The resolved commit and all its parents will be hidden from the\n output on the revision walk.

\n","group":"revwalk","examples":{"log.c":["ex/v0.21.2/log.html#git_revwalk_hide-51"]}},"git_revwalk_hide_glob":{"type":"function","file":"revwalk.h","line":162,"lineto":162,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"glob","type":"const char *","comment":"the glob pattern references should match"}],"argline":"git_revwalk *walk, const char *glob","sig":"git_revwalk *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Hide matching references.

\n","comments":"

The OIDs pointed to by the references that match the given glob\n pattern and their ancestors will be hidden from the output on the\n revision walk.

\n\n

A leading 'refs/' is implied if not present as well as a trailing\n '/\n\\\n*' if the glob lacks '?', '\n\\\n*' or '['.

\n\n

Any references matching this glob which do not point to a\n committish will be ignored.

\n","group":"revwalk"},"git_revwalk_hide_head":{"type":"function","file":"revwalk.h","line":170,"lineto":170,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Hide the repository's HEAD

\n","comments":"","group":"revwalk"},"git_revwalk_push_ref":{"type":"function","file":"revwalk.h","line":181,"lineto":181,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"refname","type":"const char *","comment":"the reference to push"}],"argline":"git_revwalk *walk, const char *refname","sig":"git_revwalk *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Push the OID pointed to by a reference

\n","comments":"

The reference must point to a committish.

\n","group":"revwalk"},"git_revwalk_hide_ref":{"type":"function","file":"revwalk.h","line":192,"lineto":192,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"refname","type":"const char *","comment":"the reference to hide"}],"argline":"git_revwalk *walk, const char *refname","sig":"git_revwalk *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Hide the OID pointed to by a reference

\n","comments":"

The reference must point to a committish.

\n","group":"revwalk"},"git_revwalk_next":{"type":"function","file":"revwalk.h","line":212,"lineto":212,"args":[{"name":"out","type":"git_oid *","comment":"Pointer where to store the oid of the next commit"},{"name":"walk","type":"git_revwalk *","comment":"the walker to pop the commit from."}],"argline":"git_oid *out, git_revwalk *walk","sig":"git_oid *::git_revwalk *","return":{"type":"int","comment":" 0 if the next commit was found;\n\tGIT_ITEROVER if there are no commits left to iterate"},"description":"

Get the next commit from the revision walk.

\n","comments":"

The initial call to this method is not blocking when\n iterating through a repo with a time-sorting mode.

\n\n

Iterating with Topological or inverted modes makes the initial\n call blocking to preprocess the commit list, but this block should be\n mostly unnoticeable on most repositories (topological preprocessing\n times at 0.3s on the git.git repo).

\n\n

The revision walker is reset when the walk is over.

\n","group":"revwalk","examples":{"general.c":["ex/v0.21.2/general.html#git_revwalk_next-63"],"log.c":["ex/v0.21.2/log.html#git_revwalk_next-52"]}},"git_revwalk_sorting":{"type":"function","file":"revwalk.h","line":223,"lineto":223,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal."},{"name":"sort_mode","type":"unsigned int","comment":"combination of GIT_SORT_XXX flags"}],"argline":"git_revwalk *walk, unsigned int sort_mode","sig":"git_revwalk *::unsigned int","return":{"type":"void","comment":null},"description":"

Change the sorting mode when iterating through the\n repository's contents.

\n","comments":"

Changing the sorting mode resets the walker.

\n","group":"revwalk","examples":{"general.c":["ex/v0.21.2/general.html#git_revwalk_sorting-64"],"log.c":["ex/v0.21.2/log.html#git_revwalk_sorting-53","ex/v0.21.2/log.html#git_revwalk_sorting-54"]}},"git_revwalk_push_range":{"type":"function","file":"revwalk.h","line":238,"lineto":238,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"range","type":"const char *","comment":"the range"}],"argline":"git_revwalk *walk, const char *range","sig":"git_revwalk *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Push and hide the respective endpoints of the given range.

\n","comments":"

The range should be of the form

\n\n

<commit

\n\n
\n

..\n<commit

\n\n

where each \n<commit\nis in the form accepted by 'git_revparse_single'.\n The left-hand commit will be hidden and the right-hand commit pushed.

\n
\n","group":"revwalk"},"git_revwalk_simplify_first_parent":{"type":"function","file":"revwalk.h","line":245,"lineto":245,"args":[{"name":"walk","type":"git_revwalk *","comment":null}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"void","comment":null},"description":"

Simplify the history by first-parent

\n","comments":"

No parents other than the first for each commit will be enqueued.

\n","group":"revwalk"},"git_revwalk_free":{"type":"function","file":"revwalk.h","line":253,"lineto":253,"args":[{"name":"walk","type":"git_revwalk *","comment":"traversal handle to close. If NULL nothing occurs."}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"void","comment":null},"description":"

Free a revision walker previously allocated.

\n","comments":"","group":"revwalk","examples":{"general.c":["ex/v0.21.2/general.html#git_revwalk_free-65"],"log.c":["ex/v0.21.2/log.html#git_revwalk_free-55"]}},"git_revwalk_repository":{"type":"function","file":"revwalk.h","line":262,"lineto":262,"args":[{"name":"walk","type":"git_revwalk *","comment":"the revision walker"}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"git_repository *","comment":" the repository being walked"},"description":"

Return the repository on which this walker\n is operating.

\n","comments":"","group":"revwalk"},"git_revwalk_add_hide_cb":{"type":"function","file":"revwalk.h","line":283,"lineto":286,"args":[{"name":"walk","type":"git_revwalk *","comment":"the revision walker"},{"name":"hide_cb","type":"git_revwalk_hide_cb","comment":"callback function to hide a commit and its parents"},{"name":"payload","type":"void *","comment":"data payload to be passed to callback function"}],"argline":"git_revwalk *walk, git_revwalk_hide_cb hide_cb, void *payload","sig":"git_revwalk *::git_revwalk_hide_cb::void *","return":{"type":"int","comment":null},"description":"

Adds a callback function to hide a commit and its parents

\n","comments":"","group":"revwalk"},"git_signature_new":{"type":"function","file":"signature.h","line":37,"lineto":37,"args":[{"name":"out","type":"git_signature **","comment":"new signature, in case of error NULL"},{"name":"name","type":"const char *","comment":"name of the person"},{"name":"email","type":"const char *","comment":"email of the person"},{"name":"time","type":"git_time_t","comment":"time when the action happened"},{"name":"offset","type":"int","comment":"timezone offset in minutes for the time"}],"argline":"git_signature **out, const char *name, const char *email, git_time_t time, int offset","sig":"git_signature **::const char *::const char *::git_time_t::int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new action signature.

\n","comments":"

Call git_signature_free() to free the data.

\n\n

Note: angle brackets ('\n<\n' and '>') characters are not allowed\n to be used in either the name or the email parameter.

\n","group":"signature","examples":{"general.c":["ex/v0.21.2/general.html#git_signature_new-66","ex/v0.21.2/general.html#git_signature_new-67"]}},"git_signature_now":{"type":"function","file":"signature.h","line":49,"lineto":49,"args":[{"name":"out","type":"git_signature **","comment":"new signature, in case of error NULL"},{"name":"name","type":"const char *","comment":"name of the person"},{"name":"email","type":"const char *","comment":"email of the person"}],"argline":"git_signature **out, const char *name, const char *email","sig":"git_signature **::const char *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a new action signature with a timestamp of 'now'.

\n","comments":"

Call git_signature_free() to free the data.

\n","group":"signature"},"git_signature_default":{"type":"function","file":"signature.h","line":63,"lineto":63,"args":[{"name":"out","type":"git_signature **","comment":"new signature"},{"name":"repo","type":"git_repository *","comment":"repository pointer"}],"argline":"git_signature **out, git_repository *repo","sig":"git_signature **::git_repository *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if config is missing, or error code"},"description":"

Create a new action signature with default user and now timestamp.

\n","comments":"

This looks up the user.name and user.email from the configuration and\n uses the current time as the timestamp, and creates a new signature\n based on that information. It will return GIT_ENOTFOUND if either the\n user.name or user.email are not set.

\n","group":"signature","examples":{"init.c":["ex/v0.21.2/init.html#git_signature_default-10"],"tag.c":["ex/v0.21.2/tag.html#git_signature_default-15"]}},"git_signature_dup":{"type":"function","file":"signature.h","line":75,"lineto":75,"args":[{"name":"dest","type":"git_signature **","comment":"pointer where to store the copy"},{"name":"sig","type":"const git_signature *","comment":"signature to duplicate"}],"argline":"git_signature **dest, const git_signature *sig","sig":"git_signature **::const git_signature *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create a copy of an existing signature. All internal strings are also\n duplicated.

\n","comments":"

Call git_signature_free() to free the data.

\n","group":"signature"},"git_signature_free":{"type":"function","file":"signature.h","line":86,"lineto":86,"args":[{"name":"sig","type":"git_signature *","comment":"signature to free"}],"argline":"git_signature *sig","sig":"git_signature *","return":{"type":"void","comment":null},"description":"

Free an existing signature.

\n","comments":"

Because the signature is not an opaque structure, it is legal to free it\n manually, but be sure to free the "name" and "email" strings in addition\n to the structure itself.

\n","group":"signature","examples":{"init.c":["ex/v0.21.2/init.html#git_signature_free-11"],"tag.c":["ex/v0.21.2/tag.html#git_signature_free-16"]}},"git_stash_foreach":{"type":"function","file":"stash.h","line":95,"lineto":98,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the stash."},{"name":"callback","type":"git_stash_cb","comment":"Callback to invoke per found stashed state. The most\n recent stash state will be enumerated first."},{"name":"payload","type":"void *","comment":"Extra parameter to callback function."}],"argline":"git_repository *repo, git_stash_cb callback, void *payload","sig":"git_repository *::git_stash_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Loop over all the stashed states and issue a callback for each one.

\n","comments":"

If the callback returns a non-zero value, this will stop looping.

\n","group":"stash"},"git_stash_drop":{"type":"function","file":"stash.h","line":111,"lineto":113,"args":[{"name":"repo","type":"git_repository *","comment":"The owning repository."},{"name":"index","type":"size_t","comment":"The position within the stash list. 0 points to the\n most recent stashed state."}],"argline":"git_repository *repo, size_t index","sig":"git_repository *::size_t","return":{"type":"int","comment":" 0 on success, or error code"},"description":"

Remove a single stashed state from the stash list.

\n","comments":"","group":"stash"},"git_status_init_options":{"type":"function","file":"status.h","line":191,"lineto":193,"args":[{"name":"opts","type":"git_status_options *","comment":"The `git_status_options` instance to initialize."},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_STATUS_OPTIONS_VERSION`"}],"argline":"git_status_options *opts, unsigned int version","sig":"git_status_options *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_status_options with default values. Equivalent to\n creating an instance with GIT_STATUS_OPTIONS_INIT.

\n","comments":"","group":"status"},"git_status_foreach":{"type":"function","file":"status.h","line":231,"lineto":234,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"callback","type":"git_status_cb","comment":"The function to call on each file"},{"name":"payload","type":"void *","comment":"Pointer to pass through to callback function"}],"argline":"git_repository *repo, git_status_cb callback, void *payload","sig":"git_repository *::git_status_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Gather file statuses and run a callback for each one.

\n","comments":"

The callback is passed the path of the file, the status (a combination of\n the git_status_t values above) and the payload data pointer passed\n into this function.

\n\n

If the callback returns a non-zero value, this function will stop looping\n and return that value to caller.

\n","group":"status","examples":{"status.c":["ex/v0.21.2/status.html#git_status_foreach-8"]}},"git_status_foreach_ext":{"type":"function","file":"status.h","line":255,"lineto":259,"args":[{"name":"repo","type":"git_repository *","comment":"Repository object"},{"name":"opts","type":"const git_status_options *","comment":"Status options structure"},{"name":"callback","type":"git_status_cb","comment":"The function to call on each file"},{"name":"payload","type":"void *","comment":"Pointer to pass through to callback function"}],"argline":"git_repository *repo, const git_status_options *opts, git_status_cb callback, void *payload","sig":"git_repository *::const git_status_options *::git_status_cb::void *","return":{"type":"int","comment":" 0 on success, non-zero callback return value, or error code"},"description":"

Gather file status information and run callbacks as requested.

\n","comments":"

This is an extended version of the git_status_foreach() API that\n allows for more granular control over which paths will be processed and\n in what order. See the git_status_options structure for details\n about the additional controls that this makes available.

\n\n

Note that if a pathspec is given in the git_status_options to filter\n the status, then the results from rename detection (if you enable it) may\n not be accurate. To do rename detection properly, this must be called\n with no pathspec so that all files can be considered.

\n","group":"status","examples":{"status.c":["ex/v0.21.2/status.html#git_status_foreach_ext-9"]}},"git_status_file":{"type":"function","file":"status.h","line":286,"lineto":289,"args":[{"name":"status_flags","type":"unsigned int *","comment":"Output combination of git_status_t values for file"},{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"path","type":"const char *","comment":"The file to retrieve status for relative to the repo workdir"}],"argline":"unsigned int *status_flags, git_repository *repo, const char *path","sig":"unsigned int *::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD,\n index, and work tree, GIT_EAMBIGUOUS if `path` matches multiple files\n or if it refers to a folder, and -1 on other errors."},"description":"

Get file status for a single file.

\n","comments":"

This tries to get status for the filename that you give. If no files\n match that name (in either the HEAD, index, or working directory), this\n returns GIT_ENOTFOUND.

\n\n

If the name matches multiple files (for example, if the path names a\n directory or if running on a case- insensitive filesystem and yet the\n HEAD has two entries that both match the path), then this returns\n GIT_EAMBIGUOUS because it cannot give correct results.

\n\n

This does not do any sort of rename detection. Renames require a set of\n targets and because of the path filtering, there is not enough\n information to check renames correctly. To check file status with rename\n detection, there is no choice but to do a full git_status_list_new and\n scan through looking for the path that you are interested in.

\n","group":"status"},"git_status_list_new":{"type":"function","file":"status.h","line":304,"lineto":307,"args":[{"name":"out","type":"git_status_list **","comment":"Pointer to store the status results in"},{"name":"repo","type":"git_repository *","comment":"Repository object"},{"name":"opts","type":"const git_status_options *","comment":"Status options structure"}],"argline":"git_status_list **out, git_repository *repo, const git_status_options *opts","sig":"git_status_list **::git_repository *::const git_status_options *","return":{"type":"int","comment":" 0 on success or error code"},"description":"

Gather file status information and populate the git_status_list.

\n","comments":"

Note that if a pathspec is given in the git_status_options to filter\n the status, then the results from rename detection (if you enable it) may\n not be accurate. To do rename detection properly, this must be called\n with no pathspec so that all files can be considered.

\n","group":"status","examples":{"status.c":["ex/v0.21.2/status.html#git_status_list_new-10","ex/v0.21.2/status.html#git_status_list_new-11"]}},"git_status_list_entrycount":{"type":"function","file":"status.h","line":318,"lineto":319,"args":[{"name":"statuslist","type":"git_status_list *","comment":"Existing status list object"}],"argline":"git_status_list *statuslist","sig":"git_status_list *","return":{"type":"size_t","comment":" the number of status entries"},"description":"

Gets the count of status entries in this list.

\n","comments":"

If there are no changes in status (at least according the options given\n when the status list was created), this can return 0.

\n","group":"status","examples":{"status.c":["ex/v0.21.2/status.html#git_status_list_entrycount-12","ex/v0.21.2/status.html#git_status_list_entrycount-13"]}},"git_status_byindex":{"type":"function","file":"status.h","line":330,"lineto":332,"args":[{"name":"statuslist","type":"git_status_list *","comment":"Existing status list object"},{"name":"idx","type":"size_t","comment":"Position of the entry"}],"argline":"git_status_list *statuslist, size_t idx","sig":"git_status_list *::size_t","return":{"type":"const git_status_entry *","comment":" Pointer to the entry; NULL if out of bounds"},"description":"

Get a pointer to one of the entries in the status list.

\n","comments":"

The entry is not modifiable and should not be freed.

\n","group":"status","examples":{"status.c":["ex/v0.21.2/status.html#git_status_byindex-14","ex/v0.21.2/status.html#git_status_byindex-15","ex/v0.21.2/status.html#git_status_byindex-16","ex/v0.21.2/status.html#git_status_byindex-17","ex/v0.21.2/status.html#git_status_byindex-18","ex/v0.21.2/status.html#git_status_byindex-19"]}},"git_status_list_free":{"type":"function","file":"status.h","line":339,"lineto":340,"args":[{"name":"statuslist","type":"git_status_list *","comment":"Existing status list object"}],"argline":"git_status_list *statuslist","sig":"git_status_list *","return":{"type":"void","comment":null},"description":"

Free an existing status list

\n","comments":"","group":"status","examples":{"status.c":["ex/v0.21.2/status.html#git_status_list_free-20"]}},"git_status_should_ignore":{"type":"function","file":"status.h","line":358,"lineto":361,"args":[{"name":"ignored","type":"int *","comment":"Boolean returning 0 if the file is not ignored, 1 if it is"},{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"path","type":"const char *","comment":"The file to check ignores for, rooted at the repo's workdir."}],"argline":"int *ignored, git_repository *repo, const char *path","sig":"int *::git_repository *::const char *","return":{"type":"int","comment":" 0 if ignore rules could be processed for the file (regardless\n of whether it exists or not), or an error \n<\n 0 if they could not."},"description":"

Test if the ignore rules apply to a given file.

\n","comments":"

This function checks the ignore rules to see if they would apply to the\n given file. This indicates if the file would be ignored regardless of\n whether the file is already in the index or committed to the repository.

\n\n

One way to think of this is if you were to do "git add ." on the\n directory containing the file, would it be added or not?

\n","group":"status"},"git_strarray_free":{"type":"function","file":"strarray.h","line":41,"lineto":41,"args":[{"name":"array","type":"git_strarray *","comment":"git_strarray from which to free string data"}],"argline":"git_strarray *array","sig":"git_strarray *","return":{"type":"void","comment":null},"description":"

Close a string array object

\n","comments":"

This method should be called on git_strarray objects where the strings\n array is allocated and contains allocated strings, such as what you\n would get from git_strarray_copy(). Not doing so, will result in a\n memory leak.

\n\n

This does not free the git_strarray itself, since the library will\n never allocate that object directly itself (it is more commonly embedded\n inside another struct or created on the stack).

\n","group":"strarray","examples":{"general.c":["ex/v0.21.2/general.html#git_strarray_free-68"],"tag.c":["ex/v0.21.2/tag.html#git_strarray_free-17"]}},"git_strarray_copy":{"type":"function","file":"strarray.h","line":53,"lineto":53,"args":[{"name":"tgt","type":"git_strarray *","comment":"target"},{"name":"src","type":"const git_strarray *","comment":"source"}],"argline":"git_strarray *tgt, const git_strarray *src","sig":"git_strarray *::const git_strarray *","return":{"type":"int","comment":" 0 on success, \n<\n 0 on allocation failure"},"description":"

Copy a string array object from source to target.

\n","comments":"

Note: target is overwritten and hence should be empty, otherwise its\n contents are leaked. Call git_strarray_free() if necessary.

\n","group":"strarray"},"git_submodule_lookup":{"type":"function","file":"submodule.h","line":135,"lineto":138,"args":[{"name":"out","type":"git_submodule **","comment":"Output ptr to submodule; pass NULL to just get return code"},{"name":"repo","type":"git_repository *","comment":"The parent repository"},{"name":"name","type":"const char *","comment":"The name of or path to the submodule; trailing slashes okay"}],"argline":"git_submodule **out, git_repository *repo, const char *name","sig":"git_submodule **::git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_ENOTFOUND if submodule does not exist,\n GIT_EEXISTS if a repository is found in working directory only,\n -1 on other errors."},"description":"

Lookup submodule information by name or path.

\n","comments":"

Given either the submodule name or path (they are usually the same), this\n returns a structure describing the submodule.

\n\n

There are two expected error scenarios:

\n\n
    \n
  • The submodule is not mentioned in the HEAD, the index, and the config,\nbut does "exist" in the working directory (i.e. there is a subdirectory\nthat appears to be a Git repository). In this case, this function\nreturns GIT_EEXISTS to indicate a sub-repository exists but not in a\nstate where a git_submodule can be instantiated.
  • \n
  • The submodule is not mentioned in the HEAD, index, or config and the\nworking directory doesn't contain a value git repo at that path.\nThere may or may not be anything else at that path, but nothing that\nlooks like a submodule. In this case, this returns GIT_ENOTFOUND.
  • \n
\n\n

You must call git_submodule_free when done with the submodule.

\n","group":"submodule","examples":{"status.c":["ex/v0.21.2/status.html#git_submodule_lookup-21"]}},"git_submodule_free":{"type":"function","file":"submodule.h","line":145,"lineto":145,"args":[{"name":"submodule","type":"git_submodule *","comment":"Submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"void","comment":null},"description":"

Release a submodule

\n","comments":"","group":"submodule","examples":{"status.c":["ex/v0.21.2/status.html#git_submodule_free-22"]}},"git_submodule_foreach":{"type":"function","file":"submodule.h","line":165,"lineto":168,"args":[{"name":"repo","type":"git_repository *","comment":"The repository"},{"name":"callback","type":"int (*)(git_submodule *, const char *, void *)","comment":"Function to be called with the name of each submodule.\n Return a non-zero value to terminate the iteration."},{"name":"payload","type":"void *","comment":"Extra data to pass to callback"}],"argline":"git_repository *repo, int (*)(git_submodule *, const char *, void *) callback, void *payload","sig":"git_repository *::int (*)(git_submodule *, const char *, void *)::void *","return":{"type":"int","comment":" 0 on success, -1 on error, or non-zero return value of callback"},"description":"

Iterate over all tracked submodules of a repository.

\n","comments":"

See the note on git_submodule above. This iterates over the tracked\n submodules as decribed therein.

\n\n

If you are concerned about items in the working directory that look like\n submodules but are not tracked, the diff API will generate a diff record\n for workdir items that look like submodules but are not tracked, showing\n them as added in the workdir. Also, the status API will treat the entire\n subdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item.

\n","group":"submodule","examples":{"status.c":["ex/v0.21.2/status.html#git_submodule_foreach-23"]}},"git_submodule_add_setup":{"type":"function","file":"submodule.h","line":195,"lineto":200,"args":[{"name":"out","type":"git_submodule **","comment":"The newly created submodule ready to open for clone"},{"name":"repo","type":"git_repository *","comment":"The repository in which you want to create the submodule"},{"name":"url","type":"const char *","comment":"URL for the submodule's remote"},{"name":"path","type":"const char *","comment":"Path at which the submodule should be created"},{"name":"use_gitlink","type":"int","comment":"Should workdir contain a gitlink to the repo in\n .git/modules vs. repo directly in workdir."}],"argline":"git_submodule **out, git_repository *repo, const char *url, const char *path, int use_gitlink","sig":"git_submodule **::git_repository *::const char *::const char *::int","return":{"type":"int","comment":" 0 on success, GIT_EEXISTS if submodule already exists,\n -1 on other errors."},"description":"

Set up a new git submodule for checkout.

\n","comments":"

This does "git submodule add" up to the fetch and checkout of the\n submodule contents. It preps a new submodule, creates an entry in\n .gitmodules and creates an empty initialized repository either at the\n given path in the working directory or in .git/modules with a gitlink\n from the working directory to the new repo.

\n\n

To fully emulate "git submodule add" call this function, then open the\n submodule repo and perform the clone step as needed. Lastly, call\n git_submodule_add_finalize() to wrap up adding the new submodule and\n .gitmodules to the index to be ready to commit.

\n\n

You must call git_submodule_free on the submodule object when done.

\n","group":"submodule"},"git_submodule_add_finalize":{"type":"function","file":"submodule.h","line":212,"lineto":212,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to finish adding."}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int","comment":null},"description":"

Resolve the setup of a new git submodule.

\n","comments":"

This should be called on a submodule once you have called add setup\n and done the clone of the submodule. This adds the .gitmodules file\n and the newly cloned submodule to the index to be ready to be committed\n (but doesn't actually do the commit).

\n","group":"submodule"},"git_submodule_add_to_index":{"type":"function","file":"submodule.h","line":224,"lineto":226,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to add to the index"},{"name":"write_index","type":"int","comment":"Boolean if this should immediately write the index\n file. If you pass this as false, you will have to get the\n git_index and explicitly call `git_index_write()` on it to\n save the change."}],"argline":"git_submodule *submodule, int write_index","sig":"git_submodule *::int","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure"},"description":"

Add current submodule HEAD commit to index of superproject.

\n","comments":"","group":"submodule"},"git_submodule_save":{"type":"function","file":"submodule.h","line":240,"lineto":240,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to write."}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure."},"description":"

Write submodule settings to .gitmodules file.

\n","comments":"

This commits any in-memory changes to the submodule to the gitmodules\n file on disk. You may also be interested in git_submodule_init() which\n writes submodule info to ".git/config" (which is better for local changes\n to submodule settings) and/or git_submodule_sync() which writes\n settings about remotes to the actual submodule repository.

\n","group":"submodule"},"git_submodule_owner":{"type":"function","file":"submodule.h","line":253,"lineto":253,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"git_repository *","comment":" Pointer to `git_repository`"},"description":"

Get the containing repository for a submodule.

\n","comments":"

This returns a pointer to the repository that contains the submodule.\n This is a just a reference to the repository that was passed to the\n original git_submodule_lookup() call, so if that repository has been\n freed, then this may be a dangling reference.

\n","group":"submodule"},"git_submodule_name":{"type":"function","file":"submodule.h","line":261,"lineto":261,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":" Pointer to the submodule name"},"description":"

Get the name of submodule.

\n","comments":"","group":"submodule","examples":{"status.c":["ex/v0.21.2/status.html#git_submodule_name-24"]}},"git_submodule_path":{"type":"function","file":"submodule.h","line":272,"lineto":272,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":" Pointer to the submodule path"},"description":"

Get the path to the submodule.

\n","comments":"

The path is almost always the same as the submodule name, but the\n two are actually not required to match.

\n","group":"submodule","examples":{"status.c":["ex/v0.21.2/status.html#git_submodule_path-25"]}},"git_submodule_url":{"type":"function","file":"submodule.h","line":280,"lineto":280,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":" Pointer to the submodule url"},"description":"

Get the URL for the submodule.

\n","comments":"","group":"submodule"},"git_submodule_branch":{"type":"function","file":"submodule.h","line":298,"lineto":298,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":" Pointer to the submodule branch"},"description":"

Get the branch for the submodule.

\n","comments":"","group":"submodule"},"git_submodule_set_url":{"type":"function","file":"submodule.h","line":314,"lineto":314,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to the submodule object"},{"name":"url","type":"const char *","comment":"URL that should be used for the submodule"}],"argline":"git_submodule *submodule, const char *url","sig":"git_submodule *::const char *","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure"},"description":"

Set the URL for the submodule.

\n","comments":"

This sets the URL in memory for the submodule. This will be used for\n any following submodule actions while this submodule data is in memory.

\n\n

After calling this, you may wish to call git_submodule_save() to write\n the changes back to the ".gitmodules" file and git_submodule_sync() to\n write the changes to the checked out submodule repository.

\n","group":"submodule"},"git_submodule_index_id":{"type":"function","file":"submodule.h","line":322,"lineto":322,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const git_oid *","comment":" Pointer to git_oid or NULL if submodule is not in index."},"description":"

Get the OID for the submodule in the index.

\n","comments":"","group":"submodule"},"git_submodule_head_id":{"type":"function","file":"submodule.h","line":330,"lineto":330,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const git_oid *","comment":" Pointer to git_oid or NULL if submodule is not in the HEAD."},"description":"

Get the OID for the submodule in the current HEAD tree.

\n","comments":"","group":"submodule"},"git_submodule_wd_id":{"type":"function","file":"submodule.h","line":343,"lineto":343,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const git_oid *","comment":" Pointer to git_oid or NULL if submodule is not checked out."},"description":"

Get the OID for the submodule in the current working directory.

\n","comments":"

This returns the OID that corresponds to looking up 'HEAD' in the checked\n out submodule. If there are pending changes in the index or anything\n else, this won't notice that. You should call git_submodule_status()\n for a more complete picture about the state of the working directory.

\n","group":"submodule"},"git_submodule_ignore":{"type":"function","file":"submodule.h","line":371,"lineto":372,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to check"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"git_submodule_ignore_t","comment":" The current git_submodule_ignore_t valyue what will be used for\n this submodule."},"description":"

Get the ignore rule that will be used for the submodule.

\n","comments":"

These values control the behavior of git_submodule_status() for this\n submodule. There are four ignore values:

\n\n
    \n
  • GIT_SUBMODULE_IGNORE_NONE will consider any change to the contents\nof the submodule from a clean checkout to be dirty, including the\naddition of untracked files. This is the default if unspecified.
  • \n
  • GIT_SUBMODULE_IGNORE_UNTRACKED examines the contents of the\nworking tree (i.e. call git_status_foreach() on the submodule) but\nUNTRACKED files will not count as making the submodule dirty.
  • \n
  • GIT_SUBMODULE_IGNORE_DIRTY means to only check if the HEAD of the\nsubmodule has moved for status. This is fast since it does not need to\nscan the working tree of the submodule at all.
  • \n
  • GIT_SUBMODULE_IGNORE_ALL means not to open the submodule repo.\nThe working directory will be consider clean so long as there is a\nchecked out version present.
  • \n
\n\n

plus the special GIT_SUBMODULE_IGNORE_RESET which can be used with\n git_submodule_set_ignore() to revert to the on-disk setting.

\n","group":"submodule"},"git_submodule_set_ignore":{"type":"function","file":"submodule.h","line":390,"lineto":392,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to update"},{"name":"ignore","type":"git_submodule_ignore_t","comment":"The new value for the ignore rule"}],"argline":"git_submodule *submodule, git_submodule_ignore_t ignore","sig":"git_submodule *::git_submodule_ignore_t","return":{"type":"git_submodule_ignore_t","comment":" old value for ignore"},"description":"

Set the ignore rule for the submodule.

\n","comments":"

This sets the in-memory ignore rule for the submodule which will\n control the behavior of git_submodule_status().

\n\n

To make changes persistent, call git_submodule_save() to write the\n value to disk (in the ".gitmodules" and ".git/config" files).

\n\n

Call with GIT_SUBMODULE_IGNORE_RESET or call git_submodule_reload()\n to revert the in-memory rule to the value that is on disk.

\n","group":"submodule"},"git_submodule_update":{"type":"function","file":"submodule.h","line":406,"lineto":407,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to check"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"git_submodule_update_t","comment":" The current git_submodule_update_t value that will be used\n for this submodule."},"description":"

Get the update rule that will be used for the submodule.

\n","comments":"

This value controls the behavior of the git submodule update command.\n There are four useful values documented with git_submodule_update_t\n plus the GIT_SUBMODULE_UPDATE_RESET which can be used to revert to\n the on-disk setting.

\n","group":"submodule"},"git_submodule_set_update":{"type":"function","file":"submodule.h","line":425,"lineto":427,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to update"},{"name":"update","type":"git_submodule_update_t","comment":"The new value to use"}],"argline":"git_submodule *submodule, git_submodule_update_t update","sig":"git_submodule *::git_submodule_update_t","return":{"type":"git_submodule_update_t","comment":" old value for update"},"description":"

Set the update rule for the submodule.

\n","comments":"

The initial value comes from the ".git/config" setting of\n submodule.$name.update for this submodule (which is initialized from\n the ".gitmodules" file). Using this function sets the update rule in\n memory for the submodule. Call git_submodule_save() to write out the\n new update rule.

\n\n

Calling this again with GIT_SUBMODULE_UPDATE_RESET or calling\n git_submodule_reload() will revert the rule to the on disk value.

\n","group":"submodule"},"git_submodule_fetch_recurse_submodules":{"type":"function","file":"submodule.h","line":440,"lineto":441,"args":[{"name":"submodule","type":"git_submodule *","comment":null}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"git_submodule_recurse_t","comment":" 0 if fetchRecurseSubmodules is false, 1 if true"},"description":"

Read the fetchRecurseSubmodules rule for a submodule.

\n","comments":"

This accesses the submodule.\n<name

\n\n
\n

.fetchRecurseSubmodules value for\n the submodule that controls fetching behavior for the submodule.

\n
\n\n

Note that at this time, libgit2 does not honor this setting and the\n fetch functionality current ignores submodules.

\n","group":"submodule"},"git_submodule_set_fetch_recurse_submodules":{"type":"function","file":"submodule.h","line":454,"lineto":456,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to modify"},{"name":"fetch_recurse_submodules","type":"git_submodule_recurse_t","comment":"Boolean value"}],"argline":"git_submodule *submodule, git_submodule_recurse_t fetch_recurse_submodules","sig":"git_submodule *::git_submodule_recurse_t","return":{"type":"git_submodule_recurse_t","comment":" old value for fetchRecurseSubmodules"},"description":"

Set the fetchRecurseSubmodules rule for a submodule.

\n","comments":"

This sets the submodule.\n<name

\n\n
\n

.fetchRecurseSubmodules value for\n the submodule. You should call git_submodule_save() if you want\n to persist the new value.

\n
\n","group":"submodule"},"git_submodule_init":{"type":"function","file":"submodule.h","line":471,"lineto":471,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to write into the superproject config"},{"name":"overwrite","type":"int","comment":"By default, existing entries will not be overwritten,\n but setting this to true forces them to be updated."}],"argline":"git_submodule *submodule, int overwrite","sig":"git_submodule *::int","return":{"type":"int","comment":" 0 on success, \n<\n0 on failure."},"description":"

Copy submodule info into ".git/config" file.

\n","comments":"

Just like "git submodule init", this copies information about the\n submodule into ".git/config". You can use the accessor functions\n above to alter the in-memory git_submodule object and control what\n is written to the config, overriding what is in .gitmodules.

\n","group":"submodule"},"git_submodule_sync":{"type":"function","file":"submodule.h","line":481,"lineto":481,"args":[{"name":"submodule","type":"git_submodule *","comment":null}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int","comment":null},"description":"

Copy submodule remote info into submodule repo.

\n","comments":"

This copies the information about the submodules URL into the checked out\n submodule config, acting like "git submodule sync". This is useful if\n you have altered the URL for the submodule (or it has been altered by a\n fetch of upstream changes) and you need to update your local repo.

\n","group":"submodule"},"git_submodule_open":{"type":"function","file":"submodule.h","line":495,"lineto":497,"args":[{"name":"repo","type":"git_repository **","comment":"Pointer to the submodule repo which was opened"},{"name":"submodule","type":"git_submodule *","comment":"Submodule to be opened"}],"argline":"git_repository **repo, git_submodule *submodule","sig":"git_repository **::git_submodule *","return":{"type":"int","comment":" 0 on success, \n<\n0 if submodule repo could not be opened."},"description":"

Open the repository for a submodule.

\n","comments":"

This is a newly opened repository object. The caller is responsible for\n calling git_repository_free() on it when done. Multiple calls to this\n function will return distinct git_repository objects. This will only\n work if the submodule is checked out into the working directory.

\n","group":"submodule"},"git_submodule_reload":{"type":"function","file":"submodule.h","line":509,"lineto":509,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to reload"},{"name":"force","type":"int","comment":"Force reload even if the data doesn't seem out of date"}],"argline":"git_submodule *submodule, int force","sig":"git_submodule *::int","return":{"type":"int","comment":" 0 on success, \n<\n0 on error"},"description":"

Reread submodule info from config, index, and HEAD.

\n","comments":"

Call this to reread cached submodule information for this submodule if\n you have reason to believe that it has changed.

\n","group":"submodule"},"git_submodule_reload_all":{"type":"function","file":"submodule.h","line":520,"lineto":520,"args":[{"name":"repo","type":"git_repository *","comment":"The repository to reload submodule data for"},{"name":"force","type":"int","comment":"Force full reload even if the data doesn't seem out of date"}],"argline":"git_repository *repo, int force","sig":"git_repository *::int","return":{"type":"int","comment":" 0 on success, \n<\n0 on error"},"description":"

Reread all submodule info.

\n","comments":"

Call this to reload all cached submodule information for the repo.

\n","group":"submodule"},"git_submodule_status":{"type":"function","file":"submodule.h","line":535,"lineto":537,"args":[{"name":"status","type":"unsigned int *","comment":"Combination of `GIT_SUBMODULE_STATUS` flags"},{"name":"submodule","type":"git_submodule *","comment":"Submodule for which to get status"}],"argline":"unsigned int *status, git_submodule *submodule","sig":"unsigned int *::git_submodule *","return":{"type":"int","comment":" 0 on success, \n<\n0 on error"},"description":"

Get the status for a submodule.

\n","comments":"

This looks at a submodule and tries to determine the status. It\n will return a combination of the GIT_SUBMODULE_STATUS values above.\n How deeply it examines the working directory to do this will depend\n on the git_submodule_ignore_t value for the submodule - which can be\n set either temporarily or permanently with git_submodule_set_ignore().

\n","group":"submodule","examples":{"status.c":["ex/v0.21.2/status.html#git_submodule_status-26"]}},"git_submodule_location":{"type":"function","file":"submodule.h","line":553,"lineto":555,"args":[{"name":"location_status","type":"unsigned int *","comment":"Combination of first four `GIT_SUBMODULE_STATUS` flags"},{"name":"submodule","type":"git_submodule *","comment":"Submodule for which to get status"}],"argline":"unsigned int *location_status, git_submodule *submodule","sig":"unsigned int *::git_submodule *","return":{"type":"int","comment":" 0 on success, \n<\n0 on error"},"description":"

Get the locations of submodule information.

\n","comments":"

This is a bit like a very lightweight version of git_submodule_status.\n It just returns a made of the first four submodule status values (i.e.\n the ones like GIT_SUBMODULE_STATUS_IN_HEAD, etc) that tell you where the\n submodule data comes from (i.e. the HEAD commit, gitmodules file, etc.).\n This can be useful if you want to know if the submodule is present in the\n working directory at this point in time, etc.

\n","group":"submodule"},"git_commit_create_from_ids":{"type":"function","file":"sys/commit.h","line":34,"lineto":44,"args":[{"name":"id","type":"git_oid *","comment":null},{"name":"repo","type":"git_repository *","comment":null},{"name":"update_ref","type":"const char *","comment":null},{"name":"author","type":"const git_signature *","comment":null},{"name":"committer","type":"const git_signature *","comment":null},{"name":"message_encoding","type":"const char *","comment":null},{"name":"message","type":"const char *","comment":null},{"name":"tree","type":"const git_oid *","comment":null},{"name":"parent_count","type":"size_t","comment":null},{"name":"parents","type":"const git_oid *[]","comment":null}],"argline":"git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_oid *tree, size_t parent_count, const git_oid *[] parents","sig":"git_oid *::git_repository *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_oid *::size_t::const git_oid *[]","return":{"type":"int","comment":null},"description":"

Create new commit in the repository from a list of git_oid values.

\n","comments":"

See documentation for git_commit_create() for information about the\n parameters, as the meaning is identical excepting that tree and\n parents now take git_oid. This is a dangerous API in that nor\n the tree, neither the parents list of git_oids are checked for\n validity.

\n","group":"commit"},"git_commit_create_from_callback":{"type":"function","file":"sys/commit.h","line":66,"lineto":76,"args":[{"name":"id","type":"git_oid *","comment":null},{"name":"repo","type":"git_repository *","comment":null},{"name":"update_ref","type":"const char *","comment":null},{"name":"author","type":"const git_signature *","comment":null},{"name":"committer","type":"const git_signature *","comment":null},{"name":"message_encoding","type":"const char *","comment":null},{"name":"message","type":"const char *","comment":null},{"name":"tree","type":"const git_oid *","comment":null},{"name":"parent_cb","type":"git_commit_parent_callback","comment":null},{"name":"parent_payload","type":"void *","comment":null}],"argline":"git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_oid *tree, git_commit_parent_callback parent_cb, void *parent_payload","sig":"git_oid *::git_repository *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_oid *::git_commit_parent_callback::void *","return":{"type":"int","comment":null},"description":"

Create a new commit in the repository with an callback to supply parents.

\n","comments":"

See documentation for git_commit_create() for information about the\n parameters, as the meaning is identical excepting that tree takes a\n git_oid and doesn't check for validity, and parent_cb is invoked\n with parent_payload and should return git_oid values or NULL to\n indicate that all parents are accounted for.

\n","group":"commit"},"git_config_init_backend":{"type":"function","file":"sys/config.h","line":82,"lineto":84,"args":[{"name":"backend","type":"git_config_backend *","comment":null},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_CONFIG_BACKEND_VERSION`"}],"argline":"git_config_backend *backend, unsigned int version","sig":"git_config_backend *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_config_backend with default values. Equivalent to\n creating an instance with GIT_CONFIG_BACKEND_INIT.

\n","comments":"","group":"config"},"git_config_add_backend":{"type":"function","file":"sys/config.h","line":104,"lineto":108,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration to add the file to"},{"name":"file","type":"git_config_backend *","comment":"the configuration file (backend) to add"},{"name":"level","type":"git_config_level_t","comment":"the priority level of the backend"},{"name":"force","type":"int","comment":"if a config file already exists for the given\n priority level, replace it"}],"argline":"git_config *cfg, git_config_backend *file, git_config_level_t level, int force","sig":"git_config *::git_config_backend *::git_config_level_t::int","return":{"type":"int","comment":" 0 on success, GIT_EEXISTS when adding more than one file\n for a given priority level (and force_replace set to 0), or error code"},"description":"

Add a generic config file instance to an existing config

\n","comments":"

Note that the configuration object will free the file\n automatically.

\n\n

Further queries on this config object will access each\n of the config file instances in order (instances with\n a higher priority level will be accessed first).

\n","group":"config"},"git_diff_print_callback__to_buf":{"type":"function","file":"sys/diff.h","line":37,"lineto":41,"args":[{"name":"delta","type":"const git_diff_delta *","comment":null},{"name":"hunk","type":"const git_diff_hunk *","comment":null},{"name":"line","type":"const git_diff_line *","comment":null},{"name":"payload","type":"void *","comment":null}],"argline":"const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *payload","sig":"const git_diff_delta *::const git_diff_hunk *::const git_diff_line *::void *","return":{"type":"int","comment":null},"description":"

Diff print callback that writes to a git_buf.

\n","comments":"

This function is provided not for you to call it directly, but instead\n so you can use it as a function pointer to the git_diff_print or\n git_patch_print APIs. When using those APIs, you specify a callback\n to actually handle the diff and/or patch data.

\n\n

Use this callback to easily write that data to a git_buf buffer. You\n must pass a git_buf * value as the payload to the git_diff_print\n and/or git_patch_print function. The data will be appended to the\n buffer (after any existing content).

\n","group":"diff"},"git_diff_print_callback__to_file_handle":{"type":"function","file":"sys/diff.h","line":57,"lineto":61,"args":[{"name":"delta","type":"const git_diff_delta *","comment":null},{"name":"hunk","type":"const git_diff_hunk *","comment":null},{"name":"line","type":"const git_diff_line *","comment":null},{"name":"payload","type":"void *","comment":null}],"argline":"const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *payload","sig":"const git_diff_delta *::const git_diff_hunk *::const git_diff_line *::void *","return":{"type":"int","comment":null},"description":"

Diff print callback that writes to stdio FILE handle.

\n","comments":"

This function is provided not for you to call it directly, but instead\n so you can use it as a function pointer to the git_diff_print or\n git_patch_print APIs. When using those APIs, you specify a callback\n to actually handle the diff and/or patch data.

\n\n

Use this callback to easily write that data to a stdio FILE handle. You\n must pass a FILE * value (such as stdout or stderr or the return\n value from fopen()) as the payload to the git_diff_print\n and/or git_patch_print function. If you pass NULL, this will write\n data to stdout.

\n","group":"diff"},"git_diff_get_perfdata":{"type":"function","file":"sys/diff.h","line":80,"lineto":81,"args":[{"name":"out","type":"git_diff_perfdata *","comment":"Structure to be filled with diff performance data"},{"name":"diff","type":"const git_diff *","comment":"Diff to read performance data from"}],"argline":"git_diff_perfdata *out, const git_diff *diff","sig":"git_diff_perfdata *::const git_diff *","return":{"type":"int","comment":" 0 for success, \n<\n0 for error"},"description":"

Get performance data for a diff object.

\n","comments":"","group":"diff"},"git_status_list_get_perfdata":{"type":"function","file":"sys/diff.h","line":86,"lineto":87,"args":[{"name":"out","type":"git_diff_perfdata *","comment":null},{"name":"status","type":"const git_status_list *","comment":null}],"argline":"git_diff_perfdata *out, const git_status_list *status","sig":"git_diff_perfdata *::const git_status_list *","return":{"type":"int","comment":null},"description":"

Get performance data for diffs from a git_status_list

\n","comments":"","group":"status"},"git_filter_lookup":{"type":"function","file":"sys/filter.h","line":27,"lineto":27,"args":[{"name":"name","type":"const char *","comment":"The name of the filter"}],"argline":"const char *name","sig":"const char *","return":{"type":"git_filter *","comment":" Pointer to the filter object or NULL if not found"},"description":"

Look up a filter by name

\n","comments":"","group":"filter"},"git_filter_list_new":{"type":"function","file":"sys/filter.h","line":57,"lineto":61,"args":[{"name":"out","type":"git_filter_list **","comment":null},{"name":"repo","type":"git_repository *","comment":null},{"name":"mode","type":"git_filter_mode_t","comment":null},{"name":"options","type":"uint32_t","comment":null}],"argline":"git_filter_list **out, git_repository *repo, git_filter_mode_t mode, uint32_t options","sig":"git_filter_list **::git_repository *::git_filter_mode_t::uint32_t","return":{"type":"int","comment":null},"description":"

Create a new empty filter list

\n","comments":"

Normally you won't use this because git_filter_list_load will create\n the filter list for you, but you can use this in combination with the\n git_filter_lookup and git_filter_list_push functions to assemble\n your own chains of filters.

\n","group":"filter"},"git_filter_list_push":{"type":"function","file":"sys/filter.h","line":76,"lineto":77,"args":[{"name":"fl","type":"git_filter_list *","comment":null},{"name":"filter","type":"git_filter *","comment":null},{"name":"payload","type":"void *","comment":null}],"argline":"git_filter_list *fl, git_filter *filter, void *payload","sig":"git_filter_list *::git_filter *::void *","return":{"type":"int","comment":null},"description":"

Add a filter to a filter list with the given payload.

\n","comments":"

Normally you won't have to do this because the filter list is created\n by calling the "check" function on registered filters when the filter\n attributes are set, but this does allow more direct manipulation of\n filter lists when desired.

\n\n

Note that normally the "check" function can set up a payload for the\n filter. Using this function, you can either pass in a payload if you\n know the expected payload format, or you can pass NULL. Some filters\n may fail with a NULL payload. Good luck!

\n","group":"filter"},"git_filter_list_length":{"type":"function","file":"sys/filter.h","line":90,"lineto":90,"args":[{"name":"fl","type":"const git_filter_list *","comment":"A filter list"}],"argline":"const git_filter_list *fl","sig":"const git_filter_list *","return":{"type":"size_t","comment":" The number of filters in the list"},"description":"

Look up how many filters are in the list

\n","comments":"

We will attempt to apply all of these filters to any data passed in,\n but note that the filter apply action still has the option of skipping\n data that is passed in (for example, the CRLF filter will skip data\n that appears to be binary).

\n","group":"filter"},"git_filter_source_repo":{"type":"function","file":"sys/filter.h","line":100,"lineto":100,"args":[{"name":"src","type":"const git_filter_source *","comment":null}],"argline":"const git_filter_source *src","sig":"const git_filter_source *","return":{"type":"git_repository *","comment":null},"description":"

Get the repository that the source data is coming from.

\n","comments":"","group":"filter"},"git_filter_source_path":{"type":"function","file":"sys/filter.h","line":105,"lineto":105,"args":[{"name":"src","type":"const git_filter_source *","comment":null}],"argline":"const git_filter_source *src","sig":"const git_filter_source *","return":{"type":"const char *","comment":null},"description":"

Get the path that the source data is coming from.

\n","comments":"","group":"filter"},"git_filter_source_filemode":{"type":"function","file":"sys/filter.h","line":111,"lineto":111,"args":[{"name":"src","type":"const git_filter_source *","comment":null}],"argline":"const git_filter_source *src","sig":"const git_filter_source *","return":{"type":"uint16_t","comment":null},"description":"

Get the file mode of the source file\n If the mode is unknown, this will return 0

\n","comments":"","group":"filter"},"git_filter_source_id":{"type":"function","file":"sys/filter.h","line":118,"lineto":118,"args":[{"name":"src","type":"const git_filter_source *","comment":null}],"argline":"const git_filter_source *src","sig":"const git_filter_source *","return":{"type":"const git_oid *","comment":null},"description":"

Get the OID of the source\n If the OID is unknown (often the case with GIT_FILTER_CLEAN) then\n this will return NULL.

\n","comments":"","group":"filter"},"git_filter_source_mode":{"type":"function","file":"sys/filter.h","line":123,"lineto":123,"args":[{"name":"src","type":"const git_filter_source *","comment":null}],"argline":"const git_filter_source *src","sig":"const git_filter_source *","return":{"type":"git_filter_mode_t","comment":null},"description":"

Get the git_filter_mode_t to be used

\n","comments":"","group":"filter"},"git_filter_source_options":{"type":"function","file":"sys/filter.h","line":128,"lineto":128,"args":[{"name":"src","type":"const git_filter_source *","comment":null}],"argline":"const git_filter_source *src","sig":"const git_filter_source *","return":{"type":"uint32_t","comment":null},"description":"

Get the combination git_filter_opt_t options to be applied

\n","comments":"","group":"filter"},"git_filter_register":{"type":"function","file":"sys/filter.h","line":281,"lineto":282,"args":[{"name":"name","type":"const char *","comment":"A name by which the filter can be referenced. Attempting\n \t\t\tto register with an in-use name will return GIT_EEXISTS."},{"name":"filter","type":"git_filter *","comment":"The filter definition. This pointer will be stored as is\n \t\t\tby libgit2 so it must be a durable allocation (either static\n \t\t\tor on the heap)."},{"name":"priority","type":"int","comment":"The priority for filter application"}],"argline":"const char *name, git_filter *filter, int priority","sig":"const char *::git_filter *::int","return":{"type":"int","comment":" 0 on successful registry, error code \n<\n0 on failure"},"description":"

Register a filter under a given name with a given priority.

\n","comments":"

As mentioned elsewhere, the initialize callback will not be invoked\n immediately. It is deferred until the filter is used in some way.

\n\n

A filter's attribute checks and check and apply callbacks will be\n issued in order of priority on smudge (to workdir), and in reverse\n order of priority on clean (to odb).

\n\n

Two filters are preregistered with libgit2:\n - GIT_FILTER_CRLF with priority 0\n - GIT_FILTER_IDENT with priority 100

\n\n

Currently the filter registry is not thread safe, so any registering or\n deregistering of filters must be done outside of any possible usage of\n the filters (i.e. during application setup or shutdown).

\n","group":"filter"},"git_filter_unregister":{"type":"function","file":"sys/filter.h","line":297,"lineto":297,"args":[{"name":"name","type":"const char *","comment":"The name under which the filter was registered"}],"argline":"const char *name","sig":"const char *","return":{"type":"int","comment":" 0 on success, error code \n<\n0 on failure"},"description":"

Remove the filter with the given name

\n","comments":"

Attempting to remove the builtin libgit2 filters is not permitted and\n will return an error.

\n\n

Currently the filter registry is not thread safe, so any registering or\n deregistering of filters must be done outside of any possible usage of\n the filters (i.e. during application setup or shutdown).

\n","group":"filter"},"git_mempack_new":{"type":"function","file":"sys/mempack.h","line":44,"lineto":44,"args":[{"name":"out","type":"git_odb_backend **","comment":"Poiter where to store the ODB backend"}],"argline":"git_odb_backend **out","sig":"git_odb_backend **","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"
Instantiate a new mempack backend.\n
\n","comments":"
The backend must be added to an existing ODB with the highest\npriority.\n\n    git_mempack_new(\n
\n\n

&mempacker\n);\n git_repository_odb(\n&odb\n, repository);\n git_odb_add_backend(odb, mempacker, 999);

\n\n
Once the backend has been loaded, all writes to the ODB will\ninstead be queued in memory, and can be finalized with\n`git_mempack_dump`.\n\nSubsequent reads will also be served from the in-memory store\nto ensure consistency, until the memory store is dumped.\n
\n","group":"mempack"},"git_mempack_reset":{"type":"function","file":"sys/mempack.h","line":81,"lineto":81,"args":[{"name":"backend","type":"git_odb_backend *","comment":"The mempack backend"}],"argline":"git_odb_backend *backend","sig":"git_odb_backend *","return":{"type":"void","comment":null},"description":"
Reset the memory packer by clearing all the queued objects.\n
\n","comments":"
This assumes that `git_mempack_dump` has been called before to\nstore all the queued objects into a single packfile.\n\nAlternatively, call `reset` without a previous dump to "undo"\nall the recently written objects, giving transaction-like\nsemantics to the Git repository.\n
\n","group":"mempack"},"git_odb_init_backend":{"type":"function","file":"sys/odb_backend.h","line":100,"lineto":102,"args":[{"name":"backend","type":"git_odb_backend *","comment":null},{"name":"version","type":"unsigned int","comment":"Version the struct; pass `GIT_ODB_BACKEND_VERSION`"}],"argline":"git_odb_backend *backend, unsigned int version","sig":"git_odb_backend *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_odb_backend with default values. Equivalent to\n creating an instance with GIT_ODB_BACKEND_INIT.

\n","comments":"","group":"odb"},"git_refdb_init_backend":{"type":"function","file":"sys/refdb_backend.h","line":169,"lineto":171,"args":[{"name":"backend","type":"git_refdb_backend *","comment":null},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_REFDB_BACKEND_VERSION`"}],"argline":"git_refdb_backend *backend, unsigned int version","sig":"git_refdb_backend *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_refdb_backend with default values. Equivalent to\n creating an instance with GIT_REFDB_BACKEND_INIT.

\n","comments":"","group":"refdb"},"git_refdb_backend_fs":{"type":"function","file":"sys/refdb_backend.h","line":184,"lineto":186,"args":[{"name":"backend_out","type":"git_refdb_backend **","comment":"Output pointer to the git_refdb_backend object"},{"name":"repo","type":"git_repository *","comment":"Git repository to access"}],"argline":"git_refdb_backend **backend_out, git_repository *repo","sig":"git_refdb_backend **::git_repository *","return":{"type":"int","comment":" 0 on success, \n<\n0 error code on failure"},"description":"

Constructors for default filesystem-based refdb backend

\n","comments":"

Under normal usage, this is called for you when the repository is\n opened / created, but you can use this to explicitly construct a\n filesystem refdb backend for a repository.

\n","group":"refdb"},"git_refdb_set_backend":{"type":"function","file":"sys/refdb_backend.h","line":198,"lineto":200,"args":[{"name":"refdb","type":"git_refdb *","comment":"database to add the backend to"},{"name":"backend","type":"git_refdb_backend *","comment":"pointer to a git_refdb_backend instance"}],"argline":"git_refdb *refdb, git_refdb_backend *backend","sig":"git_refdb *::git_refdb_backend *","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"

Sets the custom backend to an existing reference DB

\n","comments":"

The git_refdb will take ownership of the git_refdb_backend so you\n should NOT free it after calling this function.

\n","group":"refdb"},"git_reference__alloc":{"type":"function","file":"sys/refs.h","line":22,"lineto":25,"args":[{"name":"name","type":"const char *","comment":"the reference name"},{"name":"oid","type":"const git_oid *","comment":"the object id for a direct reference"},{"name":"peel","type":"const git_oid *","comment":"the first non-tag object's OID, or NULL"}],"argline":"const char *name, const git_oid *oid, const git_oid *peel","sig":"const char *::const git_oid *::const git_oid *","return":{"type":"git_reference *","comment":" the created git_reference or NULL on error"},"description":"

Create a new direct reference from an OID.

\n","comments":"","group":"reference"},"git_reference__alloc_symbolic":{"type":"function","file":"sys/refs.h","line":34,"lineto":36,"args":[{"name":"name","type":"const char *","comment":"the reference name"},{"name":"target","type":"const char *","comment":"the target for a symbolic reference"}],"argline":"const char *name, const char *target","sig":"const char *::const char *","return":{"type":"git_reference *","comment":" the created git_reference or NULL on error"},"description":"

Create a new symbolic reference.

\n","comments":"","group":"reference"},"git_tag_lookup":{"type":"function","file":"tag.h","line":33,"lineto":34,"args":[{"name":"out","type":"git_tag **","comment":"pointer to the looked up tag"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tag."},{"name":"id","type":"const git_oid *","comment":"identity of the tag to locate."}],"argline":"git_tag **out, git_repository *repo, const git_oid *id","sig":"git_tag **::git_repository *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a tag object from the repository.

\n","comments":"","group":"tag","examples":{"general.c":["ex/v0.21.2/general.html#git_tag_lookup-69"]}},"git_tag_lookup_prefix":{"type":"function","file":"tag.h","line":48,"lineto":49,"args":[{"name":"out","type":"git_tag **","comment":"pointer to the looked up tag"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tag."},{"name":"id","type":"const git_oid *","comment":"identity of the tag to locate."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_tag **out, git_repository *repo, const git_oid *id, size_t len","sig":"git_tag **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a tag object from the repository,\n given a prefix of its identifier (short id).

\n","comments":"","group":"tag"},"git_tag_free":{"type":"function","file":"tag.h","line":61,"lineto":61,"args":[{"name":"tag","type":"git_tag *","comment":"the tag to close"}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"void","comment":null},"description":"

Close an open tag

\n","comments":"

You can no longer use the git_tag pointer after this call.

\n\n

IMPORTANT: You MUST call this method when you are through with a tag to\n release memory. Failure to do so will cause a memory leak.

\n","group":"tag"},"git_tag_id":{"type":"function","file":"tag.h","line":69,"lineto":69,"args":[{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"const git_oid *","comment":" object identity for the tag."},"description":"

Get the id of a tag.

\n","comments":"","group":"tag"},"git_tag_owner":{"type":"function","file":"tag.h","line":77,"lineto":77,"args":[{"name":"tag","type":"const git_tag *","comment":"A previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"git_repository *","comment":" Repository that contains this tag."},"description":"

Get the repository that contains the tag.

\n","comments":"","group":"tag"},"git_tag_target":{"type":"function","file":"tag.h","line":89,"lineto":89,"args":[{"name":"target_out","type":"git_object **","comment":"pointer where to store the target"},{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"git_object **target_out, const git_tag *tag","sig":"git_object **::const git_tag *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Get the tagged object of a tag

\n","comments":"

This method performs a repository lookup for the\n given object and returns it

\n","group":"tag","examples":{"general.c":["ex/v0.21.2/general.html#git_tag_target-70"]}},"git_tag_target_id":{"type":"function","file":"tag.h","line":97,"lineto":97,"args":[{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"const git_oid *","comment":" pointer to the OID"},"description":"

Get the OID of the tagged object of a tag

\n","comments":"","group":"tag","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tag_target_id-33"]}},"git_tag_target_type":{"type":"function","file":"tag.h","line":105,"lineto":105,"args":[{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"git_otype","comment":" type of the tagged object"},"description":"

Get the type of a tag's tagged object

\n","comments":"","group":"tag","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tag_target_type-34"],"general.c":["ex/v0.21.2/general.html#git_tag_target_type-71"]}},"git_tag_name":{"type":"function","file":"tag.h","line":113,"lineto":113,"args":[{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"const char *","comment":" name of the tag"},"description":"

Get the name of a tag

\n","comments":"","group":"tag","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tag_name-35"],"general.c":["ex/v0.21.2/general.html#git_tag_name-72"],"tag.c":["ex/v0.21.2/tag.html#git_tag_name-18"]}},"git_tag_tagger":{"type":"function","file":"tag.h","line":121,"lineto":121,"args":[{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"const git_signature *","comment":" reference to the tag's author or NULL when unspecified"},"description":"

Get the tagger (author) of a tag

\n","comments":"","group":"tag","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tag_tagger-36"]}},"git_tag_message":{"type":"function","file":"tag.h","line":129,"lineto":129,"args":[{"name":"tag","type":"const git_tag *","comment":"a previously loaded tag."}],"argline":"const git_tag *tag","sig":"const git_tag *","return":{"type":"const char *","comment":" message of the tag or NULL when unspecified"},"description":"

Get the message of a tag

\n","comments":"","group":"tag","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tag_message-37","ex/v0.21.2/cat-file.html#git_tag_message-38"],"general.c":["ex/v0.21.2/general.html#git_tag_message-73"],"tag.c":["ex/v0.21.2/tag.html#git_tag_message-19"]}},"git_tag_create":{"type":"function","file":"tag.h","line":171,"lineto":178,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the\n newly created tag. If the tag already exists, this parameter\n will be the oid of the existing tag, and the function will\n return a GIT_EEXISTS error code."},{"name":"repo","type":"git_repository *","comment":"Repository where to store the tag"},{"name":"tag_name","type":"const char *","comment":"Name for the tag; this name is validated\n for consistency. It should also not conflict with an\n already existing tag name"},{"name":"target","type":"const git_object *","comment":"Object to which this tag points. This object\n must belong to the given `repo`."},{"name":"tagger","type":"const git_signature *","comment":"Signature of the tagger for this tag, and\n of the tagging time"},{"name":"message","type":"const char *","comment":"Full message for this tag"},{"name":"force","type":"int","comment":"Overwrite existing references"}],"argline":"git_oid *oid, git_repository *repo, const char *tag_name, const git_object *target, const git_signature *tagger, const char *message, int force","sig":"git_oid *::git_repository *::const char *::const git_object *::const git_signature *::const char *::int","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC or an error code\n\tA tag object is written to the ODB, and a proper reference\n\tis written in the /refs/tags folder, pointing to it"},"description":"

Create a new tag in the repository from an object

\n","comments":"

A new reference will also be created pointing to\n this tag object. If force is true and a reference\n already exists with the given name, it'll be replaced.

\n\n

The message will not be cleaned up. This can be achieved\n through git_message_prettify().

\n\n

The tag name will be checked for validity. You must avoid\n the characters '~', '^', ':', '\n\\\n', '?', '[', and '*', and the\n sequences ".." and "\n@\n{" which have special meaning to revparse.

\n","group":"tag","examples":{"tag.c":["ex/v0.21.2/tag.html#git_tag_create-20"]}},"git_tag_annotation_create":{"type":"function","file":"tag.h","line":203,"lineto":209,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the\n newly created tag"},{"name":"repo","type":"git_repository *","comment":"Repository where to store the tag"},{"name":"tag_name","type":"const char *","comment":"Name for the tag"},{"name":"target","type":"const git_object *","comment":"Object to which this tag points. This object\n must belong to the given `repo`."},{"name":"tagger","type":"const git_signature *","comment":"Signature of the tagger for this tag, and\n of the tagging time"},{"name":"message","type":"const char *","comment":"Full message for this tag"}],"argline":"git_oid *oid, git_repository *repo, const char *tag_name, const git_object *target, const git_signature *tagger, const char *message","sig":"git_oid *::git_repository *::const char *::const git_object *::const git_signature *::const char *","return":{"type":"int","comment":" 0 on success or an error code"},"description":"

Create a new tag in the object database pointing to a git_object

\n","comments":"

The message will not be cleaned up. This can be achieved\n through git_message_prettify().

\n","group":"tag"},"git_tag_create_frombuffer":{"type":"function","file":"tag.h","line":220,"lineto":224,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the newly created tag"},{"name":"repo","type":"git_repository *","comment":"Repository where to store the tag"},{"name":"buffer","type":"const char *","comment":"Raw tag data"},{"name":"force","type":"int","comment":"Overwrite existing tags"}],"argline":"git_oid *oid, git_repository *repo, const char *buffer, int force","sig":"git_oid *::git_repository *::const char *::int","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"

Create a new tag in the repository from a buffer

\n","comments":"","group":"tag"},"git_tag_create_lightweight":{"type":"function","file":"tag.h","line":256,"lineto":261,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the provided\n target object. If the tag already exists, this parameter\n will be filled with the oid of the existing pointed object\n and the function will return a GIT_EEXISTS error code."},{"name":"repo","type":"git_repository *","comment":"Repository where to store the lightweight tag"},{"name":"tag_name","type":"const char *","comment":"Name for the tag; this name is validated\n for consistency. It should also not conflict with an\n already existing tag name"},{"name":"target","type":"const git_object *","comment":"Object to which this tag points. This object\n must belong to the given `repo`."},{"name":"force","type":"int","comment":"Overwrite existing references"}],"argline":"git_oid *oid, git_repository *repo, const char *tag_name, const git_object *target, int force","sig":"git_oid *::git_repository *::const char *::const git_object *::int","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC or an error code\n\tA proper reference is written in the /refs/tags folder,\n pointing to the provided target object"},"description":"

Create a new lightweight tag pointing at a target object

\n","comments":"

A new direct reference will be created pointing to\n this target object. If force is true and a reference\n already exists with the given name, it'll be replaced.

\n\n

The tag name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"tag","examples":{"tag.c":["ex/v0.21.2/tag.html#git_tag_create_lightweight-21"]}},"git_tag_delete":{"type":"function","file":"tag.h","line":276,"lineto":278,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where lives the tag"},{"name":"tag_name","type":"const char *","comment":"Name of the tag to be deleted;\n this name is validated for consistency."}],"argline":"git_repository *repo, const char *tag_name","sig":"git_repository *::const char *","return":{"type":"int","comment":" 0 on success, GIT_EINVALIDSPEC or an error code"},"description":"

Delete an existing tag reference.

\n","comments":"

The tag name will be checked for validity.\n See git_tag_create() for rules about valid names.

\n","group":"tag","examples":{"tag.c":["ex/v0.21.2/tag.html#git_tag_delete-22"]}},"git_tag_list":{"type":"function","file":"tag.h","line":293,"lineto":295,"args":[{"name":"tag_names","type":"git_strarray *","comment":"Pointer to a git_strarray structure where\n\t\tthe tag names will be stored"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the tags"}],"argline":"git_strarray *tag_names, git_repository *repo","sig":"git_strarray *::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Fill a list with all the tags in the Repository

\n","comments":"

The string array will be filled with the names of the\n matching tags; these values are owned by the user and\n should be free'd manually when no longer needed, using\n git_strarray_free.

\n","group":"tag"},"git_tag_list_match":{"type":"function","file":"tag.h","line":315,"lineto":318,"args":[{"name":"tag_names","type":"git_strarray *","comment":"Pointer to a git_strarray structure where\n\t\tthe tag names will be stored"},{"name":"pattern","type":"const char *","comment":"Standard fnmatch pattern"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the tags"}],"argline":"git_strarray *tag_names, const char *pattern, git_repository *repo","sig":"git_strarray *::const char *::git_repository *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Fill a list with all the tags in the Repository\n which name match a defined pattern

\n","comments":"

If an empty pattern is provided, all the tags\n will be returned.

\n\n

The string array will be filled with the names of the\n matching tags; these values are owned by the user and\n should be free'd manually when no longer needed, using\n git_strarray_free.

\n","group":"tag","examples":{"tag.c":["ex/v0.21.2/tag.html#git_tag_list_match-23"]}},"git_tag_foreach":{"type":"function","file":"tag.h","line":330,"lineto":333,"args":[{"name":"repo","type":"git_repository *","comment":"Repository"},{"name":"callback","type":"git_tag_foreach_cb","comment":"Callback function"},{"name":"payload","type":"void *","comment":"Pointer to callback data (optional)"}],"argline":"git_repository *repo, git_tag_foreach_cb callback, void *payload","sig":"git_repository *::git_tag_foreach_cb::void *","return":{"type":"int","comment":null},"description":"

Call callback `cb' for each tag in the repository

\n","comments":"","group":"tag"},"git_tag_peel":{"type":"function","file":"tag.h","line":346,"lineto":348,"args":[{"name":"tag_target_out","type":"git_object **","comment":"Pointer to the peeled git_object"},{"name":"tag","type":"const git_tag *","comment":"The tag to be processed"}],"argline":"git_object **tag_target_out, const git_tag *tag","sig":"git_object **::const git_tag *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Recursively peel a tag until a non tag git_object is found

\n","comments":"

The retrieved tag_target object is owned by the repository\n and should be closed with the git_object_free method.

\n","group":"tag"},"git_threads_init":{"type":"function","file":"threads.h","line":33,"lineto":33,"args":[],"argline":"","sig":"","return":{"type":"int","comment":" 0 or an error code"},"description":"

Init the threading system.

\n","comments":"

If libgit2 has been built with GIT_THREADS\n on, this function must be called once before\n any other library functions.

\n\n

If libgit2 has been built without GIT_THREADS\n support, this function is a no-op.

\n","group":"threads","examples":{"blame.c":["ex/v0.21.2/blame.html#git_threads_init-26"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_threads_init-39"],"diff.c":["ex/v0.21.2/diff.html#git_threads_init-15"],"init.c":["ex/v0.21.2/init.html#git_threads_init-12"],"log.c":["ex/v0.21.2/log.html#git_threads_init-56"],"network/git2.c":["ex/v0.21.2/network/git2.html#git_threads_init-5"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_threads_init-18"],"status.c":["ex/v0.21.2/status.html#git_threads_init-27"],"tag.c":["ex/v0.21.2/tag.html#git_threads_init-24"]}},"git_threads_shutdown":{"type":"function","file":"threads.h","line":45,"lineto":45,"args":[],"argline":"","sig":"","return":{"type":"void","comment":null},"description":"

Shutdown the threading system.

\n","comments":"

If libgit2 has been built with GIT_THREADS\n on, this function must be called before shutting\n down the library.

\n\n

If libgit2 has been built without GIT_THREADS\n support, this function is a no-op.

\n","group":"threads","examples":{"blame.c":["ex/v0.21.2/blame.html#git_threads_shutdown-27"],"cat-file.c":["ex/v0.21.2/cat-file.html#git_threads_shutdown-40"],"diff.c":["ex/v0.21.2/diff.html#git_threads_shutdown-16"],"init.c":["ex/v0.21.2/init.html#git_threads_shutdown-13"],"log.c":["ex/v0.21.2/log.html#git_threads_shutdown-57"],"rev-parse.c":["ex/v0.21.2/rev-parse.html#git_threads_shutdown-19"],"status.c":["ex/v0.21.2/status.html#git_threads_shutdown-28"],"tag.c":["ex/v0.21.2/tag.html#git_threads_shutdown-25"]}},"git_trace_set":{"type":"function","file":"trace.h","line":63,"lineto":63,"args":[{"name":"level","type":"git_trace_level_t","comment":"Level to set tracing to"},{"name":"cb","type":"git_trace_callback","comment":"Function to call with trace data"}],"argline":"git_trace_level_t level, git_trace_callback cb","sig":"git_trace_level_t::git_trace_callback","return":{"type":"int","comment":" 0 or an error code"},"description":"

Sets the system tracing configuration to the specified level with the\n specified callback. When system events occur at a level equal to, or\n lower than, the given level they will be reported to the given callback.

\n","comments":"","group":"trace"},"git_cred_has_username":{"type":"function","file":"transport.h","line":116,"lineto":116,"args":[{"name":"cred","type":"git_cred *","comment":"object to check"}],"argline":"git_cred *cred","sig":"git_cred *","return":{"type":"int","comment":" 1 if the credential object has non-NULL username, 0 otherwise"},"description":"

Check whether a credential object contains username information.

\n","comments":"","group":"cred"},"git_cred_userpass_plaintext_new":{"type":"function","file":"transport.h","line":127,"lineto":130,"args":[{"name":"out","type":"git_cred **","comment":"The newly created credential object."},{"name":"username","type":"const char *","comment":"The username of the credential."},{"name":"password","type":"const char *","comment":"The password of the credential."}],"argline":"git_cred **out, const char *username, const char *password","sig":"git_cred **::const char *::const char *","return":{"type":"int","comment":" 0 for success or an error code for failure"},"description":"

Create a new plain-text username and password credential object.\n The supplied credential parameter will be internally duplicated.

\n","comments":"","group":"cred"},"git_cred_ssh_key_new":{"type":"function","file":"transport.h","line":143,"lineto":148,"args":[{"name":"out","type":"git_cred **","comment":"The newly created credential object."},{"name":"username","type":"const char *","comment":"username to use to authenticate"},{"name":"publickey","type":"const char *","comment":"The path to the public key of the credential."},{"name":"privatekey","type":"const char *","comment":"The path to the private key of the credential."},{"name":"passphrase","type":"const char *","comment":"The passphrase of the credential."}],"argline":"git_cred **out, const char *username, const char *publickey, const char *privatekey, const char *passphrase","sig":"git_cred **::const char *::const char *::const char *::const char *","return":{"type":"int","comment":" 0 for success or an error code for failure"},"description":"

Create a new passphrase-protected ssh key credential object.\n The supplied credential parameter will be internally duplicated.

\n","comments":"","group":"cred"},"git_cred_ssh_interactive_new":{"type":"function","file":"transport.h","line":159,"lineto":163,"args":[{"name":"out","type":"git_cred **","comment":null},{"name":"username","type":"const char *","comment":"Username to use to authenticate."},{"name":"prompt_callback","type":"git_cred_ssh_interactive_callback","comment":"The callback method used for prompts."},{"name":"payload","type":"void *","comment":"Additional data to pass to the callback."}],"argline":"git_cred **out, const char *username, git_cred_ssh_interactive_callback prompt_callback, void *payload","sig":"git_cred **::const char *::git_cred_ssh_interactive_callback::void *","return":{"type":"int","comment":" 0 for success or an error code for failure."},"description":"

Create a new ssh keyboard-interactive based credential object.\n The supplied credential parameter will be internally duplicated.

\n","comments":"","group":"cred"},"git_cred_ssh_key_from_agent":{"type":"function","file":"transport.h","line":173,"lineto":175,"args":[{"name":"out","type":"git_cred **","comment":"The newly created credential object."},{"name":"username","type":"const char *","comment":"username to use to authenticate"}],"argline":"git_cred **out, const char *username","sig":"git_cred **::const char *","return":{"type":"int","comment":" 0 for success or an error code for failure"},"description":"

Create a new ssh key credential object used for querying an ssh-agent.\n The supplied credential parameter will be internally duplicated.

\n","comments":"","group":"cred"},"git_cred_ssh_custom_new":{"type":"function","file":"transport.h","line":195,"lineto":201,"args":[{"name":"out","type":"git_cred **","comment":"The newly created credential object."},{"name":"username","type":"const char *","comment":"username to use to authenticate"},{"name":"publickey","type":"const char *","comment":"The bytes of the public key."},{"name":"publickey_len","type":"size_t","comment":"The length of the public key in bytes."},{"name":"sign_callback","type":"git_cred_sign_callback","comment":"The callback method to sign the data during the challenge."},{"name":"payload","type":"void *","comment":"Additional data to pass to the callback."}],"argline":"git_cred **out, const char *username, const char *publickey, size_t publickey_len, git_cred_sign_callback sign_callback, void *payload","sig":"git_cred **::const char *::const char *::size_t::git_cred_sign_callback::void *","return":{"type":"int","comment":" 0 for success or an error code for failure"},"description":"

Create an ssh key credential with a custom signing function.

\n","comments":"

This lets you use your own function to sign the challenge.

\n\n

This function and its credential type is provided for completeness\n and wraps libssh2_userauth_publickey(), which is undocumented.

\n\n

The supplied credential parameter will be internally duplicated.

\n","group":"cred"},"git_cred_default_new":{"type":"function","file":"transport.h","line":209,"lineto":209,"args":[{"name":"out","type":"git_cred **","comment":null}],"argline":"git_cred **out","sig":"git_cred **","return":{"type":"int","comment":" 0 for success or an error code for failure"},"description":"

Create a "default" credential usable for Negotiate mechanisms like NTLM\n or Kerberos authentication.

\n","comments":"","group":"cred"},"git_transport_init":{"type":"function","file":"transport.h","line":323,"lineto":325,"args":[{"name":"opts","type":"git_transport *","comment":"the `git_transport` struct to initialize"},{"name":"version","type":"unsigned int","comment":"Version of struct; pass `GIT_TRANSPORT_VERSION`"}],"argline":"git_transport *opts, unsigned int version","sig":"git_transport *::unsigned int","return":{"type":"int","comment":" Zero on success; -1 on failure."},"description":"

Initializes a git_transport with default values. Equivalent to\n creating an instance with GIT_TRANSPORT_INIT.

\n","comments":"","group":"transport"},"git_transport_new":{"type":"function","file":"transport.h","line":337,"lineto":337,"args":[{"name":"out","type":"git_transport **","comment":"The newly created transport (out)"},{"name":"owner","type":"git_remote *","comment":"The git_remote which will own this transport"},{"name":"url","type":"const char *","comment":"The URL to connect to"}],"argline":"git_transport **out, git_remote *owner, const char *url","sig":"git_transport **::git_remote *::const char *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Function to use to create a transport from a URL. The transport database\n is scanned to find a transport that implements the scheme of the URI (i.e.\n git:// or http://) and a transport object is returned to the caller.

\n","comments":"","group":"transport"},"git_transport_register":{"type":"function","file":"transport.h","line":357,"lineto":361,"args":[{"name":"prefix","type":"const char *","comment":"The scheme (ending in \"://\") to match, i.e. \"git://\""},{"name":"priority","type":"unsigned int","comment":"The priority of this transport relative to others with\n\t\tthe same prefix. Built-in transports have a priority of 1."},{"name":"cb","type":"git_transport_cb","comment":"The callback used to create an instance of the transport"},{"name":"param","type":"void *","comment":"A fixed parameter to pass to cb at creation time"}],"argline":"const char *prefix, unsigned int priority, git_transport_cb cb, void *param","sig":"const char *::unsigned int::git_transport_cb::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add a custom transport definition, to be used in addition to the built-in\n set of transports that come with libgit2.

\n","comments":"

The caller is responsible for synchronizing calls to git_transport_register\n and git_transport_unregister with other calls to the library that\n instantiate transports.

\n","group":"transport"},"git_transport_unregister":{"type":"function","file":"transport.h","line":372,"lineto":374,"args":[{"name":"prefix","type":"const char *","comment":"From the previous call to git_transport_register"},{"name":"priority","type":"unsigned int","comment":"From the previous call to git_transport_register"}],"argline":"const char *prefix, unsigned int priority","sig":"const char *::unsigned int","return":{"type":"int","comment":" 0 or an error code"},"description":"

Unregister a custom transport definition which was previously registered\n with git_transport_register.

\n","comments":"","group":"transport"},"git_transport_dummy":{"type":"function","file":"transport.h","line":387,"lineto":390,"args":[{"name":"out","type":"git_transport **","comment":"The newly created transport (out)"},{"name":"owner","type":"git_remote *","comment":"The git_remote which will own this transport"},{"name":"payload","type":"void *","comment":"You must pass NULL for this parameter."}],"argline":"git_transport **out, git_remote *owner, void *payload","sig":"git_transport **::git_remote *::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an instance of the dummy transport.

\n","comments":"","group":"transport"},"git_transport_local":{"type":"function","file":"transport.h","line":400,"lineto":403,"args":[{"name":"out","type":"git_transport **","comment":"The newly created transport (out)"},{"name":"owner","type":"git_remote *","comment":"The git_remote which will own this transport"},{"name":"payload","type":"void *","comment":"You must pass NULL for this parameter."}],"argline":"git_transport **out, git_remote *owner, void *payload","sig":"git_transport **::git_remote *::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an instance of the local transport.

\n","comments":"","group":"transport"},"git_transport_smart":{"type":"function","file":"transport.h","line":413,"lineto":416,"args":[{"name":"out","type":"git_transport **","comment":"The newly created transport (out)"},{"name":"owner","type":"git_remote *","comment":"The git_remote which will own this transport"},{"name":"payload","type":"void *","comment":"A pointer to a git_smart_subtransport_definition"}],"argline":"git_transport **out, git_remote *owner, void *payload","sig":"git_transport **::git_remote *::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an instance of the smart transport.

\n","comments":"","group":"transport"},"git_smart_subtransport_http":{"type":"function","file":"transport.h","line":513,"lineto":515,"args":[{"name":"out","type":"git_smart_subtransport **","comment":"The newly created subtransport"},{"name":"owner","type":"git_transport *","comment":"The smart transport to own this subtransport"}],"argline":"git_smart_subtransport **out, git_transport *owner","sig":"git_smart_subtransport **::git_transport *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an instance of the http subtransport. This subtransport\n also supports https. On Win32, this subtransport may be implemented\n using the WinHTTP library.

\n","comments":"","group":"smart"},"git_smart_subtransport_git":{"type":"function","file":"transport.h","line":524,"lineto":526,"args":[{"name":"out","type":"git_smart_subtransport **","comment":"The newly created subtransport"},{"name":"owner","type":"git_transport *","comment":"The smart transport to own this subtransport"}],"argline":"git_smart_subtransport **out, git_transport *owner","sig":"git_smart_subtransport **::git_transport *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an instance of the git subtransport.

\n","comments":"","group":"smart"},"git_smart_subtransport_ssh":{"type":"function","file":"transport.h","line":535,"lineto":537,"args":[{"name":"out","type":"git_smart_subtransport **","comment":"The newly created subtransport"},{"name":"owner","type":"git_transport *","comment":"The smart transport to own this subtransport"}],"argline":"git_smart_subtransport **out, git_transport *owner","sig":"git_smart_subtransport **::git_transport *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Create an instance of the ssh subtransport.

\n","comments":"","group":"smart"},"git_tree_lookup":{"type":"function","file":"tree.h","line":32,"lineto":33,"args":[{"name":"out","type":"git_tree **","comment":"Pointer to the looked up tree"},{"name":"repo","type":"git_repository *","comment":"The repo to use when locating the tree."},{"name":"id","type":"const git_oid *","comment":"Identity of the tree to locate."}],"argline":"git_tree **out, git_repository *repo, const git_oid *id","sig":"git_tree **::git_repository *::const git_oid *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a tree object from the repository.

\n","comments":"","group":"tree","examples":{"general.c":["ex/v0.21.2/general.html#git_tree_lookup-74","ex/v0.21.2/general.html#git_tree_lookup-75"],"init.c":["ex/v0.21.2/init.html#git_tree_lookup-14"]}},"git_tree_lookup_prefix":{"type":"function","file":"tree.h","line":47,"lineto":51,"args":[{"name":"out","type":"git_tree **","comment":"pointer to the looked up tree"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tree."},{"name":"id","type":"const git_oid *","comment":"identity of the tree to locate."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_tree **out, git_repository *repo, const git_oid *id, size_t len","sig":"git_tree **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Lookup a tree object from the repository,\n given a prefix of its identifier (short id).

\n","comments":"","group":"tree"},"git_tree_free":{"type":"function","file":"tree.h","line":63,"lineto":63,"args":[{"name":"tree","type":"git_tree *","comment":"The tree to close"}],"argline":"git_tree *tree","sig":"git_tree *","return":{"type":"void","comment":null},"description":"

Close an open tree

\n","comments":"

You can no longer use the git_tree pointer after this call.

\n\n

IMPORTANT: You MUST call this method when you stop using a tree to\n release memory. Failure to do so will cause a memory leak.

\n","group":"tree","examples":{"diff.c":["ex/v0.21.2/diff.html#git_tree_free-17","ex/v0.21.2/diff.html#git_tree_free-18"],"init.c":["ex/v0.21.2/init.html#git_tree_free-15"],"log.c":["ex/v0.21.2/log.html#git_tree_free-58","ex/v0.21.2/log.html#git_tree_free-59","ex/v0.21.2/log.html#git_tree_free-60","ex/v0.21.2/log.html#git_tree_free-61","ex/v0.21.2/log.html#git_tree_free-62"]}},"git_tree_id":{"type":"function","file":"tree.h","line":71,"lineto":71,"args":[{"name":"tree","type":"const git_tree *","comment":"a previously loaded tree."}],"argline":"const git_tree *tree","sig":"const git_tree *","return":{"type":"const git_oid *","comment":" object identity for the tree."},"description":"

Get the id of a tree.

\n","comments":"","group":"tree"},"git_tree_owner":{"type":"function","file":"tree.h","line":79,"lineto":79,"args":[{"name":"tree","type":"const git_tree *","comment":"A previously loaded tree."}],"argline":"const git_tree *tree","sig":"const git_tree *","return":{"type":"git_repository *","comment":" Repository that contains this tree."},"description":"

Get the repository that contains the tree.

\n","comments":"","group":"tree"},"git_tree_entrycount":{"type":"function","file":"tree.h","line":87,"lineto":87,"args":[{"name":"tree","type":"const git_tree *","comment":"a previously loaded tree."}],"argline":"const git_tree *tree","sig":"const git_tree *","return":{"type":"size_t","comment":" the number of entries in the tree"},"description":"

Get the number of entries listed in a tree

\n","comments":"","group":"tree","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tree_entrycount-41"],"general.c":["ex/v0.21.2/general.html#git_tree_entrycount-76"]}},"git_tree_entry_byname":{"type":"function","file":"tree.h","line":99,"lineto":100,"args":[{"name":"tree","type":"const git_tree *","comment":"a previously loaded tree."},{"name":"filename","type":"const char *","comment":"the filename of the desired entry"}],"argline":"const git_tree *tree, const char *filename","sig":"const git_tree *::const char *","return":{"type":"const git_tree_entry *","comment":" the tree entry; NULL if not found"},"description":"

Lookup a tree entry by its filename

\n","comments":"

This returns a git_tree_entry that is owned by the git_tree. You don't\n have to free it, but you must not use it after the git_tree is released.

\n","group":"tree","examples":{"general.c":["ex/v0.21.2/general.html#git_tree_entry_byname-77"]}},"git_tree_entry_byindex":{"type":"function","file":"tree.h","line":112,"lineto":113,"args":[{"name":"tree","type":"const git_tree *","comment":"a previously loaded tree."},{"name":"idx","type":"size_t","comment":"the position in the entry list"}],"argline":"const git_tree *tree, size_t idx","sig":"const git_tree *::size_t","return":{"type":"const git_tree_entry *","comment":" the tree entry; NULL if not found"},"description":"

Lookup a tree entry by its position in the tree

\n","comments":"

This returns a git_tree_entry that is owned by the git_tree. You don't\n have to free it, but you must not use it after the git_tree is released.

\n","group":"tree","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tree_entry_byindex-42"],"general.c":["ex/v0.21.2/general.html#git_tree_entry_byindex-78"]}},"git_tree_entry_byid":{"type":"function","file":"tree.h","line":127,"lineto":128,"args":[{"name":"tree","type":"const git_tree *","comment":"a previously loaded tree."},{"name":"id","type":"const git_oid *","comment":"the sha being looked for"}],"argline":"const git_tree *tree, const git_oid *id","sig":"const git_tree *::const git_oid *","return":{"type":"const git_tree_entry *","comment":" the tree entry; NULL if not found"},"description":"

Lookup a tree entry by SHA value.

\n","comments":"

This returns a git_tree_entry that is owned by the git_tree. You don't\n have to free it, but you must not use it after the git_tree is released.

\n\n

Warning: this must examine every entry in the tree, so it is not fast.

\n","group":"tree"},"git_tree_entry_bypath":{"type":"function","file":"tree.h","line":142,"lineto":145,"args":[{"name":"out","type":"git_tree_entry **","comment":"Pointer where to store the tree entry"},{"name":"root","type":"const git_tree *","comment":"Previously loaded tree which is the root of the relative path"},{"name":"path","type":"const char *","comment":"Path to the contained entry"}],"argline":"git_tree_entry **out, const git_tree *root, const char *path","sig":"git_tree_entry **::const git_tree *::const char *","return":{"type":"int","comment":" 0 on success; GIT_ENOTFOUND if the path does not exist"},"description":"

Retrieve a tree entry contained in a tree or in any of its subtrees,\n given its relative path.

\n","comments":"

Unlike the other lookup functions, the returned tree entry is owned by\n the user and must be freed explicitly with git_tree_entry_free().

\n","group":"tree"},"git_tree_entry_dup":{"type":"function","file":"tree.h","line":157,"lineto":157,"args":[{"name":"dest","type":"git_tree_entry **","comment":"pointer where to store the copy"},{"name":"source","type":"const git_tree_entry *","comment":"tree entry to duplicate"}],"argline":"git_tree_entry **dest, const git_tree_entry *source","sig":"git_tree_entry **::const git_tree_entry *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Duplicate a tree entry

\n","comments":"

Create a copy of a tree entry. The returned copy is owned by the user,\n and must be freed explicitly with git_tree_entry_free().

\n","group":"tree"},"git_tree_entry_free":{"type":"function","file":"tree.h","line":168,"lineto":168,"args":[{"name":"entry","type":"git_tree_entry *","comment":"The entry to free"}],"argline":"git_tree_entry *entry","sig":"git_tree_entry *","return":{"type":"void","comment":null},"description":"

Free a user-owned tree entry

\n","comments":"

IMPORTANT: This function is only needed for tree entries owned by the\n user, such as the ones returned by git_tree_entry_dup() or\n git_tree_entry_bypath().

\n","group":"tree"},"git_tree_entry_name":{"type":"function","file":"tree.h","line":176,"lineto":176,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"const char *","comment":" the name of the file"},"description":"

Get the filename of a tree entry

\n","comments":"","group":"tree","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tree_entry_name-43"],"general.c":["ex/v0.21.2/general.html#git_tree_entry_name-79","ex/v0.21.2/general.html#git_tree_entry_name-80"]}},"git_tree_entry_id":{"type":"function","file":"tree.h","line":184,"lineto":184,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"const git_oid *","comment":" the oid of the object"},"description":"

Get the id of the object pointed by the entry

\n","comments":"","group":"tree","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tree_entry_id-44"]}},"git_tree_entry_type":{"type":"function","file":"tree.h","line":192,"lineto":192,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"git_otype","comment":" the type of the pointed object"},"description":"

Get the type of the object pointed by the entry

\n","comments":"","group":"tree","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tree_entry_type-45"]}},"git_tree_entry_filemode":{"type":"function","file":"tree.h","line":200,"lineto":200,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"git_filemode_t","comment":" filemode as an integer"},"description":"

Get the UNIX file attributes of a tree entry

\n","comments":"","group":"tree","examples":{"cat-file.c":["ex/v0.21.2/cat-file.html#git_tree_entry_filemode-46"]}},"git_tree_entry_filemode_raw":{"type":"function","file":"tree.h","line":212,"lineto":212,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"git_filemode_t","comment":" filemode as an integer"},"description":"

Get the raw UNIX file attributes of a tree entry

\n","comments":"

This function does not perform any normalization and is only useful\n if you need to be able to recreate the original tree object.

\n","group":"tree"},"git_tree_entry_cmp":{"type":"function","file":"tree.h","line":220,"lineto":220,"args":[{"name":"e1","type":"const git_tree_entry *","comment":"first tree entry"},{"name":"e2","type":"const git_tree_entry *","comment":"second tree entry"}],"argline":"const git_tree_entry *e1, const git_tree_entry *e2","sig":"const git_tree_entry *::const git_tree_entry *","return":{"type":"int","comment":" \n<\n0 if e1 is before e2, 0 if e1 == e2, >0 if e1 is after e2"},"description":"

Compare two tree entries

\n","comments":"","group":"tree"},"git_tree_entry_to_object":{"type":"function","file":"tree.h","line":232,"lineto":235,"args":[{"name":"object_out","type":"git_object **","comment":"pointer to the converted object"},{"name":"repo","type":"git_repository *","comment":"repository where to lookup the pointed object"},{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"git_object **object_out, git_repository *repo, const git_tree_entry *entry","sig":"git_object **::git_repository *::const git_tree_entry *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Convert a tree entry to the git_object it points to.

\n","comments":"

You must call git_object_free() on the object when you are done with it.

\n","group":"tree","examples":{"general.c":["ex/v0.21.2/general.html#git_tree_entry_to_object-81"]}},"git_treebuilder_create":{"type":"function","file":"tree.h","line":253,"lineto":254,"args":[{"name":"out","type":"git_treebuilder **","comment":"Pointer where to store the tree builder"},{"name":"source","type":"const git_tree *","comment":"Source tree to initialize the builder (optional)"}],"argline":"git_treebuilder **out, const git_tree *source","sig":"git_treebuilder **::const git_tree *","return":{"type":"int","comment":" 0 on success; error code otherwise"},"description":"

Create a new tree builder.

\n","comments":"

The tree builder can be used to create or modify trees in memory and\n write them as tree objects to the database.

\n\n

If the source parameter is not NULL, the tree builder will be\n initialized with the entries of the given tree.

\n\n

If the source parameter is NULL, the tree builder will start with no\n entries and will have to be filled manually.

\n","group":"treebuilder"},"git_treebuilder_clear":{"type":"function","file":"tree.h","line":261,"lineto":261,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Builder to clear"}],"argline":"git_treebuilder *bld","sig":"git_treebuilder *","return":{"type":"void","comment":null},"description":"

Clear all the entires in the builder

\n","comments":"","group":"treebuilder"},"git_treebuilder_entrycount":{"type":"function","file":"tree.h","line":269,"lineto":269,"args":[{"name":"bld","type":"git_treebuilder *","comment":"a previously loaded treebuilder."}],"argline":"git_treebuilder *bld","sig":"git_treebuilder *","return":{"type":"unsigned int","comment":" the number of entries in the treebuilder"},"description":"

Get the number of entries listed in a treebuilder

\n","comments":"","group":"treebuilder"},"git_treebuilder_free":{"type":"function","file":"tree.h","line":280,"lineto":280,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Builder to free"}],"argline":"git_treebuilder *bld","sig":"git_treebuilder *","return":{"type":"void","comment":null},"description":"

Free a tree builder

\n","comments":"

This will clear all the entries and free to builder.\n Failing to free the builder after you're done using it\n will result in a memory leak

\n","group":"treebuilder"},"git_treebuilder_get":{"type":"function","file":"tree.h","line":292,"lineto":293,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filename","type":"const char *","comment":"Name of the entry"}],"argline":"git_treebuilder *bld, const char *filename","sig":"git_treebuilder *::const char *","return":{"type":"const git_tree_entry *","comment":" pointer to the entry; NULL if not found"},"description":"

Get an entry from the builder from its filename

\n","comments":"

The returned entry is owned by the builder and should\n not be freed manually.

\n","group":"treebuilder"},"git_treebuilder_insert":{"type":"function","file":"tree.h","line":320,"lineto":325,"args":[{"name":"out","type":"const git_tree_entry **","comment":"Pointer to store the entry (optional)"},{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filename","type":"const char *","comment":"Filename of the entry"},{"name":"id","type":"const git_oid *","comment":"SHA1 oid of the entry"},{"name":"filemode","type":"git_filemode_t","comment":"Folder attributes of the entry. This parameter must\n\t\t\tbe valued with one of the following entries: 0040000, 0100644,\n\t\t\t0100755, 0120000 or 0160000."}],"argline":"const git_tree_entry **out, git_treebuilder *bld, const char *filename, const git_oid *id, git_filemode_t filemode","sig":"const git_tree_entry **::git_treebuilder *::const char *::const git_oid *::git_filemode_t","return":{"type":"int","comment":" 0 or an error code"},"description":"

Add or update an entry to the builder

\n","comments":"

Insert a new entry for filename in the builder with the\n given attributes.

\n\n

If an entry named filename already exists, its attributes\n will be updated with the given ones.

\n\n

The optional pointer out can be used to retrieve a pointer to\n the newly created/updated entry. Pass NULL if you do not need it.

\n\n

No attempt is being made to ensure that the provided oid points\n to an existing git object in the object database, nor that the\n attributes make sense regarding the type of the pointed at object.

\n","group":"treebuilder"},"git_treebuilder_remove":{"type":"function","file":"tree.h","line":333,"lineto":334,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filename","type":"const char *","comment":"Filename of the entry to remove"}],"argline":"git_treebuilder *bld, const char *filename","sig":"git_treebuilder *::const char *","return":{"type":"int","comment":null},"description":"

Remove an entry from the builder by its filename

\n","comments":"","group":"treebuilder"},"git_treebuilder_filter":{"type":"function","file":"tree.h","line":357,"lineto":360,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filter","type":"git_treebuilder_filter_cb","comment":"Callback to filter entries"},{"name":"payload","type":"void *","comment":"Extra data to pass to filter callback"}],"argline":"git_treebuilder *bld, git_treebuilder_filter_cb filter, void *payload","sig":"git_treebuilder *::git_treebuilder_filter_cb::void *","return":{"type":"void","comment":null},"description":"

Selectively remove entries in the tree

\n","comments":"

The filter callback will be called for each entry in the tree with a\n pointer to the entry and the provided payload; if the callback returns\n non-zero, the entry will be filtered (removed from the builder).

\n","group":"treebuilder"},"git_treebuilder_write":{"type":"function","file":"tree.h","line":373,"lineto":374,"args":[{"name":"id","type":"git_oid *","comment":"Pointer to store the OID of the newly written tree"},{"name":"repo","type":"git_repository *","comment":"Repository in which to store the object"},{"name":"bld","type":"git_treebuilder *","comment":"Tree builder to write"}],"argline":"git_oid *id, git_repository *repo, git_treebuilder *bld","sig":"git_oid *::git_repository *::git_treebuilder *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Write the contents of the tree builder as a tree object

\n","comments":"

The tree builder will be written to the given repo, and its\n identifying SHA1 hash will be stored in the id pointer.

\n","group":"treebuilder"},"git_tree_walk":{"type":"function","file":"tree.h","line":404,"lineto":408,"args":[{"name":"tree","type":"const git_tree *","comment":"The tree to walk"},{"name":"mode","type":"git_treewalk_mode","comment":"Traversal mode (pre or post-order)"},{"name":"callback","type":"git_treewalk_cb","comment":"Function to call on each tree entry"},{"name":"payload","type":"void *","comment":"Opaque pointer to be passed on each callback"}],"argline":"const git_tree *tree, git_treewalk_mode mode, git_treewalk_cb callback, void *payload","sig":"const git_tree *::git_treewalk_mode::git_treewalk_cb::void *","return":{"type":"int","comment":" 0 or an error code"},"description":"

Traverse the entries in a tree and its subtrees in post or pre order.

\n","comments":"

The entries will be traversed in the specified order, children subtrees\n will be automatically loaded as required, and the callback will be\n called once per entry with the current (relative) root for the entry and\n the entry data itself.

\n\n

If the callback returns a positive value, the passed entry will be\n skipped on the traversal (in pre mode). A negative value stops the walk.

\n","group":"tree"}},"globals":{},"types":[["git_blame_flag_t",{"decl":["GIT_BLAME_NORMAL","GIT_BLAME_TRACK_COPIES_SAME_FILE","GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES","GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES","GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES","GIT_BLAME_FIRST_PARENT"],"type":"enum","file":"blame.h","line":26,"lineto":46,"block":"GIT_BLAME_NORMAL\nGIT_BLAME_TRACK_COPIES_SAME_FILE\nGIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES\nGIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES\nGIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES\nGIT_BLAME_FIRST_PARENT","tdef":"typedef","description":" Flags for indicating option behavior for git_blame APIs.","comments":"","fields":[{"type":"int","name":"GIT_BLAME_NORMAL","comments":"

Normal blame, the default

\n","value":0},{"type":"int","name":"GIT_BLAME_TRACK_COPIES_SAME_FILE","comments":"

Track lines that have moved within a file (like git blame -M).\n NOT IMPLEMENTED.

\n","value":1},{"type":"int","name":"GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES","comments":"

Track lines that have moved across files in the same commit (like git blame -C).\n NOT IMPLEMENTED.

\n","value":2},{"type":"int","name":"GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES","comments":"

Track lines that have been copied from another file that exists in the\n same commit (like git blame -CC). Implies SAME_FILE.\n NOT IMPLEMENTED.

\n","value":4},{"type":"int","name":"GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES","comments":"

Track lines that have been copied from another file that exists in any\n commit (like git blame -CCC). Implies SAME_COMMIT_COPIES.\n NOT IMPLEMENTED.

\n","value":8},{"type":"int","name":"GIT_BLAME_FIRST_PARENT","comments":"

Restrict the search of commits to those reachable following only the\n first parents.

\n","value":16}],"used":{"returns":[],"needs":[]}}],["git_blame_hunk",{"decl":["uint16_t lines_in_hunk","git_oid final_commit_id","uint16_t final_start_line_number","git_signature * final_signature","git_oid orig_commit_id","const char * orig_path","uint16_t orig_start_line_number","git_signature * orig_signature","char boundary"],"type":"struct","value":"git_blame_hunk","file":"blame.h","line":116,"lineto":129,"block":"uint16_t lines_in_hunk\ngit_oid final_commit_id\nuint16_t final_start_line_number\ngit_signature * final_signature\ngit_oid orig_commit_id\nconst char * orig_path\nuint16_t orig_start_line_number\ngit_signature * orig_signature\nchar boundary","tdef":"typedef","description":" Structure that represents a blame hunk.","comments":"
    \n
  • lines_in_hunk is the number of lines in this hunk
  • \n
  • final_commit_id is the OID of the commit where this line was last\nchanged.
  • \n
  • final_start_line_number is the 1-based line number where this hunk\nbegins, in the final version of the file
  • \n
  • orig_commit_id is the OID of the commit where this hunk was found. This\nwill usually be the same as final_commit_id, except when\nGIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES has been specified.
  • \n
  • orig_path is the path to the file where this hunk originated, as of the\ncommit specified by orig_commit_id.
  • \n
  • orig_start_line_number is the 1-based line number where this hunk begins\nin the file named by orig_path in the commit specified by\norig_commit_id.
  • \n
  • boundary is 1 iff the hunk has been tracked to a boundary commit (the\nroot, or the commit specified in git_blame_options.oldest_commit)
  • \n
\n","fields":[{"type":"uint16_t","name":"lines_in_hunk","comments":""},{"type":"git_oid","name":"final_commit_id","comments":""},{"type":"uint16_t","name":"final_start_line_number","comments":""},{"type":"git_signature *","name":"final_signature","comments":""},{"type":"git_oid","name":"orig_commit_id","comments":""},{"type":"const char *","name":"orig_path","comments":""},{"type":"uint16_t","name":"orig_start_line_number","comments":""},{"type":"git_signature *","name":"orig_signature","comments":""},{"type":"char","name":"boundary","comments":""}],"used":{"returns":["git_blame_get_hunk_byindex","git_blame_get_hunk_byline"],"needs":[]}}],["git_blame_options",{"decl":["unsigned int version","uint32_t flags","uint16_t min_match_characters","git_oid newest_commit","git_oid oldest_commit","uint32_t min_line","uint32_t max_line"],"type":"struct","value":"git_blame_options","file":"blame.h","line":71,"lineto":80,"block":"unsigned int version\nuint32_t flags\nuint16_t min_match_characters\ngit_oid newest_commit\ngit_oid oldest_commit\nuint32_t min_line\nuint32_t max_line","tdef":"typedef","description":" Blame options structure","comments":"

Use zeros to indicate default settings. It's easiest to use the\n GIT_BLAME_OPTIONS_INIT macro:\n git_blame_options opts = GIT_BLAME_OPTIONS_INIT;

\n\n
    \n
  • flags is a combination of the git_blame_flag_t values above.
  • \n
  • min_match_characters is the lower bound on the number of alphanumeric\ncharacters that must be detected as moving/copying within a file for it to\nassociate those lines with the parent commit. The default value is 20.\nThis value only takes effect if any of the GIT_BLAME_TRACK_COPIES_*\nflags are specified.
  • \n
  • newest_commit is the id of the newest commit to consider. The default\n is HEAD.
  • \n
  • oldest_commit is the id of the oldest commit to consider. The default\n is the first commit encountered with a NULL parent.\n\n
      \n
    • min_line is the first line in the file to blame. The default is 1 (line\n numbers start with 1).
    • \n
    • max_line is the last line in the file to blame. The default is the last\n line of the file.
    • \n
  • \n
\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"uint32_t","name":"flags","comments":""},{"type":"uint16_t","name":"min_match_characters","comments":""},{"type":"git_oid","name":"newest_commit","comments":""},{"type":"git_oid","name":"oldest_commit","comments":""},{"type":"uint32_t","name":"min_line","comments":""},{"type":"uint32_t","name":"max_line","comments":""}],"used":{"returns":[],"needs":["git_blame_file","git_blame_init_options"]}}],["git_blob",{"decl":"git_blob","type":"struct","value":"git_blob","file":"types.h","line":117,"lineto":117,"tdef":"typedef","description":" In-memory representation of a blob object. ","comments":"","used":{"returns":[],"needs":["git_blob_filtered_content","git_blob_free","git_blob_id","git_blob_is_binary","git_blob_lookup","git_blob_lookup_prefix","git_blob_owner","git_blob_rawcontent","git_blob_rawsize","git_diff_blob_to_buffer","git_diff_blobs","git_filter_list_apply_to_blob","git_filter_list_load","git_patch_from_blob_and_buffer","git_patch_from_blobs"]}}],["git_branch_iterator",{"decl":"git_branch_iterator","type":"struct","value":"git_branch_iterator","file":"branch.h","line":78,"lineto":78,"tdef":"typedef","description":" Iterator type for branches ","comments":"","used":{"returns":[],"needs":["git_branch_iterator_free","git_branch_iterator_new","git_branch_next"]}}],["git_branch_t",{"decl":["GIT_BRANCH_LOCAL","GIT_BRANCH_REMOTE","GIT_BRANCH_ALL"],"type":"enum","file":"types.h","line":193,"lineto":197,"block":"GIT_BRANCH_LOCAL\nGIT_BRANCH_REMOTE\nGIT_BRANCH_ALL","tdef":"typedef","description":" Basic type of any Git branch. ","comments":"","fields":[{"type":"int","name":"GIT_BRANCH_LOCAL","comments":"","value":1},{"type":"int","name":"GIT_BRANCH_REMOTE","comments":"","value":2},{"type":"int","name":"GIT_BRANCH_ALL","comments":"","value":3}],"used":{"returns":[],"needs":["git_branch_iterator_new","git_branch_lookup","git_branch_next"]}}],["git_buf",{"decl":["char * ptr","size_t asize","size_t size"],"type":"struct","value":"git_buf","file":"buffer.h","line":52,"lineto":55,"block":"char * ptr\nsize_t asize\nsize_t size","tdef":"typedef","description":" A data buffer for exporting data from libgit2","comments":"

Sometimes libgit2 wants to return an allocated data buffer to the\n caller and have the caller take responsibility for freeing that memory.\n This can be awkward if the caller does not have easy access to the same\n allocation functions that libgit2 is using. In those cases, libgit2\n will fill in a git_buf and the caller can use git_buf_free() to\n release it when they are done.

\n\n

A git_buf may also be used for the caller to pass in a reference to\n a block of memory they hold. In this case, libgit2 will not resize or\n free the memory, but will read from it as needed.

\n\n

A git_buf is a public structure with three fields:

\n\n
    \n
  • ptr points to the start of the allocated memory. If it is NULL,\nthen the git_buf is considered empty and libgit2 will feel free\nto overwrite it with new data.

  • \n
  • size holds the size (in bytes) of the data that is actually used.

  • \n
  • asize holds the known total amount of allocated memory if the ptr\nwas allocated by libgit2. It may be larger than size. If ptr\nwas not allocated by libgit2 and should not be resized and/or freed,\nthen asize will be set to zero.

  • \n
\n\n

Some APIs may occasionally do something slightly unusual with a buffer,\n such as setting ptr to a value that was passed in by the user. In\n those cases, the behavior will be clearly documented by the API.

\n","fields":[{"type":"char *","name":"ptr","comments":""},{"type":"size_t","name":"asize","comments":""},{"type":"size_t","name":"size","comments":""}],"used":{"returns":[],"needs":["git_blob_filtered_content","git_buf_free","git_buf_grow","git_buf_set","git_config_find_global","git_config_find_system","git_config_find_xdg","git_diff_commit_as_email","git_diff_format_email","git_diff_stats_to_buf","git_filter_list_apply_to_blob","git_filter_list_apply_to_data","git_filter_list_apply_to_file","git_message_prettify","git_object_short_id","git_patch_to_buf","git_refspec_rtransform","git_refspec_transform","git_remote_default_branch","git_repository_discover","git_repository_message"]}}],["git_checkout_notify_t",{"decl":["GIT_CHECKOUT_NOTIFY_NONE","GIT_CHECKOUT_NOTIFY_CONFLICT","GIT_CHECKOUT_NOTIFY_DIRTY","GIT_CHECKOUT_NOTIFY_UPDATED","GIT_CHECKOUT_NOTIFY_UNTRACKED","GIT_CHECKOUT_NOTIFY_IGNORED","GIT_CHECKOUT_NOTIFY_ALL"],"type":"enum","file":"checkout.h","line":198,"lineto":207,"block":"GIT_CHECKOUT_NOTIFY_NONE\nGIT_CHECKOUT_NOTIFY_CONFLICT\nGIT_CHECKOUT_NOTIFY_DIRTY\nGIT_CHECKOUT_NOTIFY_UPDATED\nGIT_CHECKOUT_NOTIFY_UNTRACKED\nGIT_CHECKOUT_NOTIFY_IGNORED\nGIT_CHECKOUT_NOTIFY_ALL","tdef":"typedef","description":" Checkout notification flags","comments":"

Checkout will invoke an options notification callback (notify_cb) for\n certain cases - you pick which ones via notify_flags:

\n\n
    \n
  • GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths.

  • \n
  • GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that\ndo not need an update but no longer match the baseline. Core git\ndisplays these files when checkout runs, but won't stop the checkout.

  • \n
  • GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed.

  • \n
  • GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files.

  • \n
  • GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files.

  • \n
\n\n

Returning a non-zero value from this callback will cancel the checkout.\n The non-zero return value will be propagated back and returned by the\n git_checkout_... call.

\n\n

Notification callbacks are made prior to modifying any files on disk,\n so canceling on any notification will still happen prior to any files\n being modified.

\n","fields":[{"type":"int","name":"GIT_CHECKOUT_NOTIFY_NONE","comments":"","value":0},{"type":"int","name":"GIT_CHECKOUT_NOTIFY_CONFLICT","comments":"","value":1},{"type":"int","name":"GIT_CHECKOUT_NOTIFY_DIRTY","comments":"","value":2},{"type":"int","name":"GIT_CHECKOUT_NOTIFY_UPDATED","comments":"","value":4},{"type":"int","name":"GIT_CHECKOUT_NOTIFY_UNTRACKED","comments":"","value":8},{"type":"int","name":"GIT_CHECKOUT_NOTIFY_IGNORED","comments":"","value":16},{"type":"int","name":"GIT_CHECKOUT_NOTIFY_ALL","comments":"","value":65535}],"used":{"returns":[],"needs":[]}}],["git_checkout_options",{"decl":["unsigned int version","unsigned int checkout_strategy","int disable_filters","unsigned int dir_mode","unsigned int file_mode","int file_open_flags","unsigned int notify_flags","git_checkout_notify_cb notify_cb","void * notify_payload","git_checkout_progress_cb progress_cb","void * progress_payload","git_strarray paths","git_tree * baseline","const char * target_directory","const char * ancestor_label","const char * our_label","const char * their_label"],"type":"struct","value":"git_checkout_options","file":"checkout.h","line":233,"lineto":264,"block":"unsigned int version\nunsigned int checkout_strategy\nint disable_filters\nunsigned int dir_mode\nunsigned int file_mode\nint file_open_flags\nunsigned int notify_flags\ngit_checkout_notify_cb notify_cb\nvoid * notify_payload\ngit_checkout_progress_cb progress_cb\nvoid * progress_payload\ngit_strarray paths\ngit_tree * baseline\nconst char * target_directory\nconst char * ancestor_label\nconst char * our_label\nconst char * their_label","tdef":"typedef","description":" Checkout options structure","comments":"

Zero out for defaults. Initialize with GIT_CHECKOUT_OPTIONS_INIT macro to\n correctly set the version field. E.g.

\n\n
    git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;\n
\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"unsigned int","name":"checkout_strategy","comments":""},{"type":"int","name":"disable_filters","comments":" default will be a dry run "},{"type":"unsigned int","name":"dir_mode","comments":" don't apply filters like CRLF conversion "},{"type":"unsigned int","name":"file_mode","comments":" default is 0755 "},{"type":"int","name":"file_open_flags","comments":" default is 0644 or 0755 as dictated by blob "},{"type":"unsigned int","name":"notify_flags","comments":" default is O_CREAT | O_TRUNC | O_WRONLY "},{"type":"git_checkout_notify_cb","name":"notify_cb","comments":" see `git_checkout_notify_t` above "},{"type":"void *","name":"notify_payload","comments":""},{"type":"git_checkout_progress_cb","name":"progress_cb","comments":""},{"type":"void *","name":"progress_payload","comments":""},{"type":"git_strarray","name":"paths","comments":" When not zeroed out, array of fnmatch patterns specifying which\n paths should be taken into account, otherwise all files. Use\n GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as simple list."},{"type":"git_tree *","name":"baseline","comments":""},{"type":"const char *","name":"target_directory","comments":" expected content of workdir, defaults to HEAD "},{"type":"const char *","name":"ancestor_label","comments":" alternative checkout path to workdir "},{"type":"const char *","name":"our_label","comments":" the name of the common ancestor side of conflicts "},{"type":"const char *","name":"their_label","comments":" the name of the \"our\" side of conflicts "}],"used":{"returns":[],"needs":["git_checkout_head","git_checkout_index","git_checkout_init_options","git_checkout_tree","git_clone_into","git_clone_local_into","git_merge"]}}],["git_checkout_strategy_t",{"decl":["GIT_CHECKOUT_NONE","GIT_CHECKOUT_SAFE","GIT_CHECKOUT_SAFE_CREATE","GIT_CHECKOUT_FORCE","GIT_CHECKOUT_ALLOW_CONFLICTS","GIT_CHECKOUT_REMOVE_UNTRACKED","GIT_CHECKOUT_REMOVE_IGNORED","GIT_CHECKOUT_UPDATE_ONLY","GIT_CHECKOUT_DONT_UPDATE_INDEX","GIT_CHECKOUT_NO_REFRESH","GIT_CHECKOUT_SKIP_UNMERGED","GIT_CHECKOUT_USE_OURS","GIT_CHECKOUT_USE_THEIRS","GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH","GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES","GIT_CHECKOUT_DONT_OVERWRITE_IGNORED","GIT_CHECKOUT_CONFLICT_STYLE_MERGE","GIT_CHECKOUT_CONFLICT_STYLE_DIFF3","GIT_CHECKOUT_UPDATE_SUBMODULES","GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED"],"type":"enum","file":"checkout.h","line":108,"lineto":170,"block":"GIT_CHECKOUT_NONE\nGIT_CHECKOUT_SAFE\nGIT_CHECKOUT_SAFE_CREATE\nGIT_CHECKOUT_FORCE\nGIT_CHECKOUT_ALLOW_CONFLICTS\nGIT_CHECKOUT_REMOVE_UNTRACKED\nGIT_CHECKOUT_REMOVE_IGNORED\nGIT_CHECKOUT_UPDATE_ONLY\nGIT_CHECKOUT_DONT_UPDATE_INDEX\nGIT_CHECKOUT_NO_REFRESH\nGIT_CHECKOUT_SKIP_UNMERGED\nGIT_CHECKOUT_USE_OURS\nGIT_CHECKOUT_USE_THEIRS\nGIT_CHECKOUT_DISABLE_PATHSPEC_MATCH\nGIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES\nGIT_CHECKOUT_DONT_OVERWRITE_IGNORED\nGIT_CHECKOUT_CONFLICT_STYLE_MERGE\nGIT_CHECKOUT_CONFLICT_STYLE_DIFF3\nGIT_CHECKOUT_UPDATE_SUBMODULES\nGIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED","tdef":"typedef","description":" Checkout behavior flags","comments":"

In libgit2, checkout is used to update the working directory and index\n to match a target tree. Unlike git checkout, it does not move the HEAD\n commit for you - use git_repository_set_head or the like to do that.

\n\n

Checkout looks at (up to) four things: the "target" tree you want to\n check out, the "baseline" tree of what was checked out previously, the\n working directory for actual files, and the index for staged changes.

\n\n

You give checkout one of four strategies for update:

\n\n
    \n
  • GIT_CHECKOUT_NONE is a dry-run strategy that checks for conflicts,\netc., but doesn't make any actual changes.

  • \n
  • GIT_CHECKOUT_FORCE is at the opposite extreme, taking any action to\nmake the working directory match the target (including potentially\ndiscarding modified files).

  • \n
\n\n

In between those are GIT_CHECKOUT_SAFE and GIT_CHECKOUT_SAFE_CREATE\n both of which only make modifications that will not lose changes.

\n\n
                     |  target == baseline   |  target != baseline  |\n---------------------|-----------------------|----------------------|\n workdir == baseline |       no action       |  create, update, or  |\n                     |                       |     delete file      |\n---------------------|-----------------------|----------------------|\n workdir exists and  |       no action       |   conflict (notify   |\n   is != baseline    | notify dirty MODIFIED | and cancel checkout) |\n---------------------|-----------------------|----------------------|\n  workdir missing,   | create if SAFE_CREATE |     create file      |\n  baseline present   | notify dirty DELETED  |                      |\n---------------------|-----------------------|----------------------|\n
\n\n

The only difference between SAFE and SAFE_CREATE is that SAFE_CREATE\n will cause a file to be checked out if it is missing from the working\n directory even if it is not modified between the target and baseline.

\n\n

To emulate git checkout, use GIT_CHECKOUT_SAFE with a checkout\n notification callback (see below) that displays information about dirty\n files. The default behavior will cancel checkout on conflicts.

\n\n

To emulate git checkout-index, use GIT_CHECKOUT_SAFE_CREATE with a\n notification callback that cancels the operation if a dirty-but-existing\n file is found in the working directory. This core git command isn't\n quite "force" but is sensitive about some types of changes.

\n\n

To emulate git checkout -f, use GIT_CHECKOUT_FORCE.

\n\n

To emulate git clone use GIT_CHECKOUT_SAFE_CREATE in the options.

\n\n

There are some additional flags to modified the behavior of checkout:

\n\n
    \n
  • GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates\neven if there are conflicts (instead of cancelling the checkout).

  • \n
  • GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not\nin target, baseline, or index, and not ignored) from the working dir.

  • \n
  • GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also\nuntracked) from the working directory as well.

  • \n
  • GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that\nalready exist. Files will not be created nor deleted. This just skips\napplying adds, deletes, and typechanges.

  • \n
  • GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the\nupdated files' information to the index.

  • \n
  • Normally, checkout will reload the index and git attributes from disk\nbefore any operations. GIT_CHECKOUT_NO_REFRESH prevents this reload.

  • \n
  • Unmerged index entries are conflicts. GIT_CHECKOUT_SKIP_UNMERGED skips\nfiles with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and\nGIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the\nstage 2 ("ours") or stage 3 ("theirs") version of files in the index.

  • \n
  • GIT_CHECKOUT_DONT_OVERWRITE_IGNORED prevents ignored files from being\noverwritten. Normally, files that are ignored in the working directory\nare not considered "precious" and may be overwritten if the checkout\ntarget contains that file.

  • \n
\n","fields":[{"type":"int","name":"GIT_CHECKOUT_NONE","comments":"

default is a dry run, no actual updates

\n","value":0},{"type":"int","name":"GIT_CHECKOUT_SAFE","comments":"

Allow safe updates that cannot overwrite uncommitted data

\n","value":1},{"type":"int","name":"GIT_CHECKOUT_SAFE_CREATE","comments":"

Allow safe updates plus creation of missing files

\n","value":2},{"type":"int","name":"GIT_CHECKOUT_FORCE","comments":"

Allow all updates to force working directory to look like index

\n","value":4},{"type":"int","name":"GIT_CHECKOUT_ALLOW_CONFLICTS","comments":"

Allow checkout to make safe updates even if conflicts are found

\n","value":16},{"type":"int","name":"GIT_CHECKOUT_REMOVE_UNTRACKED","comments":"

Remove untracked files not in index (that are not ignored)

\n","value":32},{"type":"int","name":"GIT_CHECKOUT_REMOVE_IGNORED","comments":"

Remove ignored files not in index

\n","value":64},{"type":"int","name":"GIT_CHECKOUT_UPDATE_ONLY","comments":"

Only update existing files, don't create new ones

\n","value":128},{"type":"int","name":"GIT_CHECKOUT_DONT_UPDATE_INDEX","comments":"

Normally checkout updates index entries as it goes; this stops that

\n","value":256},{"type":"int","name":"GIT_CHECKOUT_NO_REFRESH","comments":"

Don't refresh index/config/etc before doing checkout

\n","value":512},{"type":"int","name":"GIT_CHECKOUT_SKIP_UNMERGED","comments":"

Allow checkout to skip unmerged files

\n","value":1024},{"type":"int","name":"GIT_CHECKOUT_USE_OURS","comments":"

For unmerged files, checkout stage 2 from index

\n","value":2048},{"type":"int","name":"GIT_CHECKOUT_USE_THEIRS","comments":"

For unmerged files, checkout stage 3 from index

\n","value":4096},{"type":"int","name":"GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH","comments":"

Treat pathspec as simple list of exact match file paths

\n","value":8192},{"type":"int","name":"GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES","comments":"

Ignore directories in use, they will be left empty

\n","value":262144},{"type":"int","name":"GIT_CHECKOUT_DONT_OVERWRITE_IGNORED","comments":"

Don't overwrite ignored files that exist in the checkout target

\n","value":524288},{"type":"int","name":"GIT_CHECKOUT_CONFLICT_STYLE_MERGE","comments":"

Write normal merge files for conflicts

\n","value":1048576},{"type":"int","name":"GIT_CHECKOUT_CONFLICT_STYLE_DIFF3","comments":"

Include common ancestor data in diff3 format files for conflicts

\n","value":2097152},{"type":"int","name":"GIT_CHECKOUT_UPDATE_SUBMODULES","comments":"

Recursively checkout submodules with same options (NOT IMPLEMENTED)

\n","value":65536},{"type":"int","name":"GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED","comments":"

Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED)

\n","value":131072}],"used":{"returns":[],"needs":[]}}],["git_cherry_pick_options",{"decl":["unsigned int version","unsigned int mainline","git_merge_options merge_opts","git_checkout_options checkout_opts"],"type":"struct","value":"git_cherry_pick_options","file":"cherrypick.h","line":23,"lineto":31,"block":"unsigned int version\nunsigned int mainline\ngit_merge_options merge_opts\ngit_checkout_options checkout_opts","tdef":"typedef","description":" \n\n git2/cherrypick.h\n ","comments":"

@\n{

\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"unsigned int","name":"mainline","comments":" For merge commits, the \"mainline\" is treated as the parent. "},{"type":"git_merge_options","name":"merge_opts","comments":""},{"type":"git_checkout_options","name":"checkout_opts","comments":""}],"used":{"returns":[],"needs":["git_cherry_pick","git_cherry_pick_init_options"]}}],["git_clone_local_t",{"decl":["GIT_CLONE_LOCAL_AUTO","GIT_CLONE_LOCAL","GIT_CLONE_NO_LOCAL","GIT_CLONE_LOCAL_NO_LINKS"],"type":"enum","file":"clone.h","line":32,"lineto":52,"block":"GIT_CLONE_LOCAL_AUTO\nGIT_CLONE_LOCAL\nGIT_CLONE_NO_LOCAL\nGIT_CLONE_LOCAL_NO_LINKS","tdef":"typedef","description":" Options for bypassing the git-aware transport on clone. Bypassing\n it means that instead of a fetch, libgit2 will copy the object\n database directory instead of figuring out what it needs, which is\n faster. If possible, it will hardlink the files to save space.","comments":"","fields":[{"type":"int","name":"GIT_CLONE_LOCAL_AUTO","comments":"

Auto-detect (default), libgit2 will bypass the git-aware\n transport for local paths, but use a normal fetch for\n file:// urls.

\n","value":0},{"type":"int","name":"GIT_CLONE_LOCAL","comments":"

Bypass the git-aware transport even for a file:// url.

\n","value":1},{"type":"int","name":"GIT_CLONE_NO_LOCAL","comments":"

Do no bypass the git-aware transport

\n","value":2},{"type":"int","name":"GIT_CLONE_LOCAL_NO_LINKS","comments":"

Bypass the git-aware transport, but do not try to use\n hardlinks.

\n","value":3}],"used":{"returns":[],"needs":[]}}],["git_clone_options",{"decl":["unsigned int version","git_checkout_options checkout_opts","git_remote_callbacks remote_callbacks","int bare","int ignore_cert_errors","git_clone_local_t local","const char * remote_name","const char * checkout_branch","git_signature * signature"],"type":"struct","value":"git_clone_options","file":"clone.h","line":62,"lineto":113,"block":"unsigned int version\ngit_checkout_options checkout_opts\ngit_remote_callbacks remote_callbacks\nint bare\nint ignore_cert_errors\ngit_clone_local_t local\nconst char * remote_name\nconst char * checkout_branch\ngit_signature * signature","tdef":"typedef","description":" Clone options structure","comments":"

Use the GIT_CLONE_OPTIONS_INIT to get the default settings, like this:

\n\n
    git_clone_options opts = GIT_CLONE_OPTIONS_INIT;\n
\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"git_checkout_options","name":"checkout_opts","comments":" These options are passed to the checkout step. To disable\n checkout, set the `checkout_strategy` to\n `GIT_CHECKOUT_NONE`. Generally you will want the use\n GIT_CHECKOUT_SAFE_CREATE to create all files in the working\n directory for the newly cloned repository."},{"type":"git_remote_callbacks","name":"remote_callbacks","comments":" Callbacks to use for reporting fetch progress."},{"type":"int","name":"bare","comments":" Set to zero (false) to create a standard repo, or non-zero\n for a bare repo"},{"type":"int","name":"ignore_cert_errors","comments":" Set to 1 if errors validating the remote host's certificate\n should be ignored."},{"type":"git_clone_local_t","name":"local","comments":" Whether to use a fetch or copy the object database."},{"type":"const char *","name":"remote_name","comments":" The name to be given to the remote that will be\n created. The default is \"origin\"."},{"type":"const char *","name":"checkout_branch","comments":" The name of the branch to checkout. NULL means use the\n remote's default branch."},{"type":"git_signature *","name":"signature","comments":" The identity used when updating the reflog. NULL means to\n use the default signature using the config."}],"used":{"returns":[],"needs":["git_clone","git_clone_init_options"]}}],["git_commit",{"decl":"git_commit","type":"struct","value":"git_commit","file":"types.h","line":120,"lineto":120,"tdef":"typedef","description":" Parsed representation of a commit object. ","comments":"","used":{"returns":[],"needs":["git_branch_create","git_cherry_pick","git_cherry_pick_commit","git_commit_amend","git_commit_author","git_commit_committer","git_commit_create","git_commit_free","git_commit_id","git_commit_lookup","git_commit_lookup_prefix","git_commit_message","git_commit_message_encoding","git_commit_message_raw","git_commit_nth_gen_ancestor","git_commit_owner","git_commit_parent","git_commit_parent_id","git_commit_parentcount","git_commit_raw_header","git_commit_summary","git_commit_time","git_commit_time_offset","git_commit_tree","git_commit_tree_id","git_diff_commit_as_email","git_merge_commits","git_revert","git_revert_commit"]}}],["git_config",{"decl":"git_config","type":"struct","value":"git_config","file":"types.h","line":138,"lineto":138,"tdef":"typedef","description":" Memory representation of a set of config files ","comments":"","used":{"returns":[],"needs":["git_config_add_backend","git_config_add_file_ondisk","git_config_delete_entry","git_config_delete_multivar","git_config_foreach","git_config_foreach_match","git_config_free","git_config_get_bool","git_config_get_entry","git_config_get_int32","git_config_get_int64","git_config_get_mapped","git_config_get_multivar_foreach","git_config_get_string","git_config_iterator_glob_new","git_config_iterator_new","git_config_multivar_iterator_new","git_config_new","git_config_open_default","git_config_open_global","git_config_open_level","git_config_open_ondisk","git_config_refresh","git_config_set_bool","git_config_set_int32","git_config_set_int64","git_config_set_multivar","git_config_set_string","git_config_snapshot","git_repository_config","git_repository_config_snapshot"]}}],["git_config_backend",{"decl":"git_config_backend","type":"struct","value":"git_config_backend","file":"types.h","line":141,"lineto":141,"block":"unsigned int version\nstruct git_config * cfg\nint (*)(struct git_config_backend *, git_config_level_t) open\nint (*)(struct git_config_backend *, const char *, const git_config_entry **) get\nint (*)(struct git_config_backend *, const char *, const char *) set\nint (*)(git_config_backend *, const char *, const char *, const char *) set_multivar\nint (*)(struct git_config_backend *, const char *) del\nint (*)(struct git_config_backend *, const char *, const char *) del_multivar\nint (*)(git_config_iterator **, struct git_config_backend *) iterator\nint (*)(struct git_config_backend *) refresh\nint (*)(struct git_config_backend **, struct git_config_backend *) snapshot\nvoid (*)(struct git_config_backend *) free","tdef":"typedef","description":" Interface to access a configuration file ","comments":"","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"struct git_config *","name":"cfg","comments":""},{"type":"int (*)(struct git_config_backend *, git_config_level_t)","name":"open","comments":""},{"type":"int (*)(struct git_config_backend *, const char *, const git_config_entry **)","name":"get","comments":""},{"type":"int (*)(struct git_config_backend *, const char *, const char *)","name":"set","comments":""},{"type":"int (*)(git_config_backend *, const char *, const char *, const char *)","name":"set_multivar","comments":""},{"type":"int (*)(struct git_config_backend *, const char *)","name":"del","comments":""},{"type":"int (*)(struct git_config_backend *, const char *, const char *)","name":"del_multivar","comments":""},{"type":"int (*)(git_config_iterator **, struct git_config_backend *)","name":"iterator","comments":""},{"type":"int (*)(struct git_config_backend *)","name":"refresh","comments":""},{"type":"int (*)(struct git_config_backend **, struct git_config_backend *)","name":"snapshot","comments":" Produce a read-only version of this backend "},{"type":"void (*)(struct git_config_backend *)","name":"free","comments":""}],"used":{"returns":[],"needs":["git_config_add_backend","git_config_backend_foreach_match","git_config_init_backend"]}}],["git_config_iterator",{"decl":["git_config_backend * backend","unsigned int flags","int (*)(git_config_entry **, git_config_iterator *) next","void (*)(git_config_iterator *) free"],"type":"struct","value":"git_config_iterator","file":"sys/config.h","line":34,"lineto":48,"block":"git_config_backend * backend\nunsigned int flags\nint (*)(git_config_entry **, git_config_iterator *) next\nvoid (*)(git_config_iterator *) free","tdef":null,"description":" Every iterator must have this struct as its first element, so the\n API can talk to it. You'd define your iterator as","comments":"
 struct my_iterator {\n         git_config_iterator parent;\n         ...\n }\n
\n\n

and assign iter->parent.backend to your git_config_backend.

\n","fields":[{"type":"git_config_backend *","name":"backend","comments":""},{"type":"unsigned int","name":"flags","comments":""},{"type":"int (*)(git_config_entry **, git_config_iterator *)","name":"next","comments":" Return the current entry and advance the iterator. The\n memory belongs to the library."},{"type":"void (*)(git_config_iterator *)","name":"free","comments":" Free the iterator"}],"used":{"returns":[],"needs":["git_config_iterator_free","git_config_iterator_glob_new","git_config_iterator_new","git_config_multivar_iterator_new","git_config_next"]}}],["git_config_level_t",{"decl":["GIT_CONFIG_LEVEL_SYSTEM","GIT_CONFIG_LEVEL_XDG","GIT_CONFIG_LEVEL_GLOBAL","GIT_CONFIG_LEVEL_LOCAL","GIT_CONFIG_LEVEL_APP","GIT_CONFIG_HIGHEST_LEVEL"],"type":"enum","file":"config.h","line":31,"lineto":56,"block":"GIT_CONFIG_LEVEL_SYSTEM\nGIT_CONFIG_LEVEL_XDG\nGIT_CONFIG_LEVEL_GLOBAL\nGIT_CONFIG_LEVEL_LOCAL\nGIT_CONFIG_LEVEL_APP\nGIT_CONFIG_HIGHEST_LEVEL","tdef":"typedef","description":" Priority level of a config file.\n These priority levels correspond to the natural escalation logic\n (from higher to lower) when searching for config entries in git.git.","comments":"

git_config_open_default() and git_repository_config() honor those\n priority levels as well.

\n","fields":[{"type":"int","name":"GIT_CONFIG_LEVEL_SYSTEM","comments":"

System-wide configuration file; /etc/gitconfig on Linux systems

\n","value":1},{"type":"int","name":"GIT_CONFIG_LEVEL_XDG","comments":"

XDG compatible configuration file; typically ~/.config/git/config

\n","value":2},{"type":"int","name":"GIT_CONFIG_LEVEL_GLOBAL","comments":"

User-specific configuration file (also called Global configuration\n file); typically ~/.gitconfig

\n","value":3},{"type":"int","name":"GIT_CONFIG_LEVEL_LOCAL","comments":"

Repository specific configuration file; $WORK_DIR/.git/config on\n non-bare repos

\n","value":4},{"type":"int","name":"GIT_CONFIG_LEVEL_APP","comments":"

Application specific configuration file; freely defined by applications

\n","value":5},{"type":"int","name":"GIT_CONFIG_HIGHEST_LEVEL","comments":"

Represents the highest level available config file (i.e. the most\n specific config file available that actually is loaded)

\n","value":-1}],"used":{"returns":[],"needs":["git_config_add_backend","git_config_add_file_ondisk","git_config_open_level"]}}],["git_cred_default",{"decl":"git_cred_default","type":"struct","value":"git_cred_default","file":"transport.h","line":108,"lineto":108,"tdef":"typedef","description":" A key for NTLM/Kerberos \"default\" credentials ","comments":"","used":{"returns":[],"needs":[]}}],["git_cred_ssh_custom",{"decl":["git_cred parent","char * username","char * publickey","size_t publickey_len","git_cred_sign_callback sign_callback","void * payload"],"type":"struct","value":"git_cred_ssh_custom","file":"transport.h","line":98,"lineto":105,"block":"git_cred parent\nchar * username\nchar * publickey\nsize_t publickey_len\ngit_cred_sign_callback sign_callback\nvoid * payload","tdef":"typedef","description":" A key with a custom signature function","comments":"","fields":[{"type":"git_cred","name":"parent","comments":""},{"type":"char *","name":"username","comments":""},{"type":"char *","name":"publickey","comments":""},{"type":"size_t","name":"publickey_len","comments":""},{"type":"git_cred_sign_callback","name":"sign_callback","comments":""},{"type":"void *","name":"payload","comments":""}],"used":{"returns":[],"needs":[]}}],["git_cred_ssh_interactive",{"decl":["git_cred parent","char * username","git_cred_ssh_interactive_callback prompt_callback","void * payload"],"type":"struct","value":"git_cred_ssh_interactive","file":"transport.h","line":88,"lineto":93,"block":"git_cred parent\nchar * username\ngit_cred_ssh_interactive_callback prompt_callback\nvoid * payload","tdef":"typedef","description":" Keyboard-interactive based ssh authentication","comments":"","fields":[{"type":"git_cred","name":"parent","comments":""},{"type":"char *","name":"username","comments":""},{"type":"git_cred_ssh_interactive_callback","name":"prompt_callback","comments":""},{"type":"void *","name":"payload","comments":""}],"used":{"returns":[],"needs":[]}}],["git_cred_ssh_key",{"decl":["git_cred parent","char * username","char * publickey","char * privatekey","char * passphrase"],"type":"struct","value":"git_cred_ssh_key","file":"transport.h","line":77,"lineto":83,"block":"git_cred parent\nchar * username\nchar * publickey\nchar * privatekey\nchar * passphrase","tdef":"typedef","description":" A ssh key from disk","comments":"","fields":[{"type":"git_cred","name":"parent","comments":""},{"type":"char *","name":"username","comments":""},{"type":"char *","name":"publickey","comments":""},{"type":"char *","name":"privatekey","comments":""},{"type":"char *","name":"passphrase","comments":""}],"used":{"returns":[],"needs":[]}}],["git_cred_userpass_payload",{"decl":["char * username","char * password"],"type":"struct","value":"git_cred_userpass_payload","file":"cred_helpers.h","line":24,"lineto":27,"block":"char * username\nchar * password","tdef":"typedef","description":" Payload for git_cred_stock_userpass_plaintext.","comments":"","fields":[{"type":"char *","name":"username","comments":""},{"type":"char *","name":"password","comments":""}],"used":{"returns":[],"needs":[]}}],["git_cred_userpass_plaintext",{"decl":["git_cred parent","char * username","char * password"],"type":"struct","value":"git_cred_userpass_plaintext","file":"transport.h","line":54,"lineto":58,"block":"git_cred parent\nchar * username\nchar * password","tdef":"typedef","description":" A plaintext username and password ","comments":"","fields":[{"type":"git_cred","name":"parent","comments":""},{"type":"char *","name":"username","comments":""},{"type":"char *","name":"password","comments":""}],"used":{"returns":[],"needs":[]}}],["git_credtype_t",{"decl":["GIT_CREDTYPE_USERPASS_PLAINTEXT","GIT_CREDTYPE_SSH_KEY","GIT_CREDTYPE_SSH_CUSTOM","GIT_CREDTYPE_DEFAULT","GIT_CREDTYPE_SSH_INTERACTIVE"],"type":"enum","file":"transport.h","line":28,"lineto":43,"block":"GIT_CREDTYPE_USERPASS_PLAINTEXT\nGIT_CREDTYPE_SSH_KEY\nGIT_CREDTYPE_SSH_CUSTOM\nGIT_CREDTYPE_DEFAULT\nGIT_CREDTYPE_SSH_INTERACTIVE","tdef":"typedef","description":" Authentication type requested ","comments":"","fields":[{"type":"int","name":"GIT_CREDTYPE_USERPASS_PLAINTEXT","comments":"","value":1},{"type":"int","name":"GIT_CREDTYPE_SSH_KEY","comments":"","value":2},{"type":"int","name":"GIT_CREDTYPE_SSH_CUSTOM","comments":"","value":4},{"type":"int","name":"GIT_CREDTYPE_DEFAULT","comments":"","value":8},{"type":"int","name":"GIT_CREDTYPE_SSH_INTERACTIVE","comments":"","value":16}],"used":{"returns":[],"needs":[]}}],["git_delta_t",{"decl":["GIT_DELTA_UNMODIFIED","GIT_DELTA_ADDED","GIT_DELTA_DELETED","GIT_DELTA_MODIFIED","GIT_DELTA_RENAMED","GIT_DELTA_COPIED","GIT_DELTA_IGNORED","GIT_DELTA_UNTRACKED","GIT_DELTA_TYPECHANGE"],"type":"enum","file":"diff.h","line":230,"lineto":240,"block":"GIT_DELTA_UNMODIFIED\nGIT_DELTA_ADDED\nGIT_DELTA_DELETED\nGIT_DELTA_MODIFIED\nGIT_DELTA_RENAMED\nGIT_DELTA_COPIED\nGIT_DELTA_IGNORED\nGIT_DELTA_UNTRACKED\nGIT_DELTA_TYPECHANGE","tdef":"typedef","description":" What type of change is described by a git_diff_delta?","comments":"

GIT_DELTA_RENAMED and GIT_DELTA_COPIED will only show up if you run\n git_diff_find_similar() on the diff object.

\n\n

GIT_DELTA_TYPECHANGE only shows up given GIT_DIFF_INCLUDE_TYPECHANGE\n in the option flags (otherwise type changes will be split into ADDED /\n DELETED pairs).

\n","fields":[{"type":"int","name":"GIT_DELTA_UNMODIFIED","comments":"

no changes

\n","value":0},{"type":"int","name":"GIT_DELTA_ADDED","comments":"

entry does not exist in old version

\n","value":1},{"type":"int","name":"GIT_DELTA_DELETED","comments":"

entry does not exist in new version

\n","value":2},{"type":"int","name":"GIT_DELTA_MODIFIED","comments":"

entry content changed between old and new

\n","value":3},{"type":"int","name":"GIT_DELTA_RENAMED","comments":"

entry was renamed between old and new

\n","value":4},{"type":"int","name":"GIT_DELTA_COPIED","comments":"

entry was copied from another old entry

\n","value":5},{"type":"int","name":"GIT_DELTA_IGNORED","comments":"

entry is ignored item in workdir

\n","value":6},{"type":"int","name":"GIT_DELTA_UNTRACKED","comments":"

entry is untracked item in workdir

\n","value":7},{"type":"int","name":"GIT_DELTA_TYPECHANGE","comments":"

type of entry changed between old and new

\n","value":8}],"used":{"returns":[],"needs":["git_diff_num_deltas_of_type","git_diff_status_char"]}}],["git_diff",{"decl":"git_diff","type":"struct","value":"git_diff","file":"diff.h","line":204,"lineto":204,"tdef":"typedef","description":" The diff object that contains all individual file deltas.","comments":"

This is an opaque structure which will be allocated by one of the diff\n generator functions below (such as git_diff_tree_to_tree). You are\n responsible for releasing the object memory when done, using the\n git_diff_free() function.

\n","used":{"returns":[],"needs":["git_diff_find_similar","git_diff_foreach","git_diff_format_email","git_diff_free","git_diff_get_delta","git_diff_get_perfdata","git_diff_get_stats","git_diff_index_to_workdir","git_diff_is_sorted_icase","git_diff_merge","git_diff_num_deltas","git_diff_num_deltas_of_type","git_diff_print","git_diff_tree_to_index","git_diff_tree_to_tree","git_diff_tree_to_workdir","git_diff_tree_to_workdir_with_index","git_patch_from_diff","git_pathspec_match_diff"]}}],["git_diff_delta",{"decl":["git_delta_t status","uint32_t flags","uint16_t similarity","uint16_t nfiles","git_diff_file old_file","git_diff_file new_file"],"type":"struct","value":"git_diff_delta","file":"diff.h","line":307,"lineto":314,"block":"git_delta_t status\nuint32_t flags\nuint16_t similarity\nuint16_t nfiles\ngit_diff_file old_file\ngit_diff_file new_file","tdef":"typedef","description":" Description of changes to one entry.","comments":"

When iterating over a diff, this will be passed to most callbacks and\n you can use the contents to understand exactly what has changed.

\n\n

The old_file represents the "from" side of the diff and the new_file\n represents to "to" side of the diff. What those means depend on the\n function that was used to generate the diff and will be documented below.\n You can also use the GIT_DIFF_REVERSE flag to flip it around.

\n\n

Although the two sides of the delta are named "old_file" and "new_file",\n they actually may correspond to entries that represent a file, a symbolic\n link, a submodule commit id, or even a tree (if you are tracking type\n changes or ignored/untracked directories).

\n\n

Under some circumstances, in the name of efficiency, not all fields will\n be filled in, but we generally try to fill in as much as possible. One\n example is that the "flags" field may not have either the BINARY or the\n NOT_BINARY flag set to avoid examining file contents if you do not pass\n in hunk and/or line callbacks to the diff foreach iteration function. It\n will just use the git attributes for those files.

\n\n

The similarity score is zero unless you call git_diff_find_similar()\n which does a similarity analysis of files in the diff. Use that\n function to do rename and copy detection, and to split heavily modified\n files in add/delete pairs. After that call, deltas with a status of\n GIT_DELTA_RENAMED or GIT_DELTA_COPIED will have a similarity score\n between 0 and 100 indicating how similar the old and new sides are.

\n\n

If you ask git_diff_find_similar to find heavily modified files to\n break, but to not actually break the records, then GIT_DELTA_MODIFIED\n records may have a non-zero similarity score if the self-similarity is\n below the split threshold. To display this value like core Git, invert\n the score (a la printf("M%03d", 100 - delta->similarity)).

\n","fields":[{"type":"git_delta_t","name":"status","comments":""},{"type":"uint32_t","name":"flags","comments":" git_diff_flag_t values "},{"type":"uint16_t","name":"similarity","comments":" for RENAMED and COPIED, value 0-100 "},{"type":"uint16_t","name":"nfiles","comments":" number of files in this delta "},{"type":"git_diff_file","name":"old_file","comments":""},{"type":"git_diff_file","name":"new_file","comments":""}],"used":{"returns":["git_diff_get_delta","git_patch_get_delta","git_pathspec_match_list_diff_entry"],"needs":["git_diff_print_callback__to_buf","git_diff_print_callback__to_file_handle"]}}],["git_diff_file",{"decl":["git_oid id","const char * path","git_off_t size","uint32_t flags","uint16_t mode"],"type":"struct","value":"git_diff_file","file":"diff.h","line":263,"lineto":269,"block":"git_oid id\nconst char * path\ngit_off_t size\nuint32_t flags\nuint16_t mode","tdef":"typedef","description":" Description of one side of a delta.","comments":"

Although this is called a "file", it could represent a file, a symbolic\n link, a submodule commit id, or even a tree (although that only if you\n are tracking type changes or ignored/untracked directories).

\n\n

The oid is the git_oid of the item. If the entry represents an\n absent side of a diff (e.g. the old_file of a GIT_DELTA_ADDED delta),\n then the oid will be zeroes.

\n\n

path is the NUL-terminated path to the entry relative to the working\n directory of the repository.

\n\n

size is the size of the entry in bytes.

\n\n

flags is a combination of the git_diff_flag_t types

\n\n

mode is, roughly, the stat() st_mode value for the item. This will\n be restricted to one of the git_filemode_t values.

\n","fields":[{"type":"git_oid","name":"id","comments":""},{"type":"const char *","name":"path","comments":""},{"type":"git_off_t","name":"size","comments":""},{"type":"uint32_t","name":"flags","comments":""},{"type":"uint16_t","name":"mode","comments":""}],"used":{"returns":[],"needs":[]}}],["git_diff_find_options",{"decl":["unsigned int version","uint32_t flags","uint16_t rename_threshold","uint16_t rename_from_rewrite_threshold","uint16_t copy_threshold","uint16_t break_rewrite_threshold","size_t rename_limit","git_diff_similarity_metric * metric"],"type":"struct","value":"git_diff_find_options","file":"diff.h","line":599,"lineto":625,"block":"unsigned int version\nuint32_t flags\nuint16_t rename_threshold\nuint16_t rename_from_rewrite_threshold\nuint16_t copy_threshold\nuint16_t break_rewrite_threshold\nsize_t rename_limit\ngit_diff_similarity_metric * metric","tdef":"typedef","description":" Control behavior of rename and copy detection","comments":"

These options mostly mimic parameters that can be passed to git-diff.

\n\n
    \n
  • rename_threshold is the same as the -M option with a value
  • \n
  • copy_threshold is the same as the -C option with a value
  • \n
  • rename_from_rewrite_threshold matches the top of the -B option
  • \n
  • break_rewrite_threshold matches the bottom of the -B option
  • \n
  • rename_limit is the maximum number of matches to consider for\na particular file. This is a little different from the -l option\nto regular Git because we will still process up to this many matches\nbefore abandoning the search.
  • \n
\n\n

The metric option allows you to plug in a custom similarity metric.\n Set it to NULL for the default internal metric which is based on sampling\n hashes of ranges of data in the file. The default metric is a pretty\n good similarity approximation that should work fairly well for both text\n and binary data, and is pretty fast with fixed memory overhead.

\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"uint32_t","name":"flags","comments":" Combination of git_diff_find_t values (default GIT_DIFF_FIND_BY_CONFIG).\n NOTE: if you don't explicitly set this, `diff.renames` could be set\n to false, resulting in `git_diff_find_similar` doing nothing."},{"type":"uint16_t","name":"rename_threshold","comments":" Similarity to consider a file renamed (default 50) "},{"type":"uint16_t","name":"rename_from_rewrite_threshold","comments":" Similarity of modified to be eligible rename source (default 50) "},{"type":"uint16_t","name":"copy_threshold","comments":" Similarity to consider a file a copy (default 50) "},{"type":"uint16_t","name":"break_rewrite_threshold","comments":" Similarity to split modify into delete/add pair (default 60) "},{"type":"size_t","name":"rename_limit","comments":" Maximum similarity sources to examine for a file (somewhat like\n git-diff's `-l` option or `diff.renameLimit` config) (default 200)"},{"type":"git_diff_similarity_metric *","name":"metric","comments":" Pluggable similarity metric; pass NULL to use internal metric "}],"used":{"returns":[],"needs":["git_diff_find_init_options","git_diff_find_similar"]}}],["git_diff_find_t",{"decl":["GIT_DIFF_FIND_BY_CONFIG","GIT_DIFF_FIND_RENAMES","GIT_DIFF_FIND_RENAMES_FROM_REWRITES","GIT_DIFF_FIND_COPIES","GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED","GIT_DIFF_FIND_REWRITES","GIT_DIFF_BREAK_REWRITES","GIT_DIFF_FIND_AND_BREAK_REWRITES","GIT_DIFF_FIND_FOR_UNTRACKED","GIT_DIFF_FIND_ALL","GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE","GIT_DIFF_FIND_IGNORE_WHITESPACE","GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE","GIT_DIFF_FIND_EXACT_MATCH_ONLY","GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY","GIT_DIFF_FIND_REMOVE_UNMODIFIED"],"type":"enum","file":"diff.h","line":493,"lineto":562,"block":"GIT_DIFF_FIND_BY_CONFIG\nGIT_DIFF_FIND_RENAMES\nGIT_DIFF_FIND_RENAMES_FROM_REWRITES\nGIT_DIFF_FIND_COPIES\nGIT_DIFF_FIND_COPIES_FROM_UNMODIFIED\nGIT_DIFF_FIND_REWRITES\nGIT_DIFF_BREAK_REWRITES\nGIT_DIFF_FIND_AND_BREAK_REWRITES\nGIT_DIFF_FIND_FOR_UNTRACKED\nGIT_DIFF_FIND_ALL\nGIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE\nGIT_DIFF_FIND_IGNORE_WHITESPACE\nGIT_DIFF_FIND_DONT_IGNORE_WHITESPACE\nGIT_DIFF_FIND_EXACT_MATCH_ONLY\nGIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY\nGIT_DIFF_FIND_REMOVE_UNMODIFIED","tdef":"typedef","description":" Flags to control the behavior of diff rename/copy detection.","comments":"","fields":[{"type":"int","name":"GIT_DIFF_FIND_BY_CONFIG","comments":"

Obey diff.renames. Overridden by any other GIT_DIFF_FIND_... flag.

\n","value":0},{"type":"int","name":"GIT_DIFF_FIND_RENAMES","comments":"

Look for renames? (--find-renames)

\n","value":1},{"type":"int","name":"GIT_DIFF_FIND_RENAMES_FROM_REWRITES","comments":"

Consider old side of MODIFIED for renames? (--break-rewrites=N)

\n","value":2},{"type":"int","name":"GIT_DIFF_FIND_COPIES","comments":"

Look for copies? (a la --find-copies).

\n","value":4},{"type":"int","name":"GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED","comments":"

Consider UNMODIFIED as copy sources? (--find-copies-harder).

\n\n

For this to work correctly, use GIT_DIFF_INCLUDE_UNMODIFIED when\n the initial git_diff is being generated.

\n","value":8},{"type":"int","name":"GIT_DIFF_FIND_REWRITES","comments":"

Mark significant rewrites for split (--break-rewrites=/M)

\n","value":16},{"type":"int","name":"GIT_DIFF_BREAK_REWRITES","comments":"

Actually split large rewrites into delete/add pairs

\n","value":32},{"type":"int","name":"GIT_DIFF_FIND_AND_BREAK_REWRITES","comments":"

Mark rewrites for split and break into delete/add pairs

\n","value":48},{"type":"int","name":"GIT_DIFF_FIND_FOR_UNTRACKED","comments":"

Find renames/copies for UNTRACKED items in working directory.

\n\n

For this to work correctly, use GIT_DIFF_INCLUDE_UNTRACKED when the\n initial git_diff is being generated (and obviously the diff must\n be against the working directory for this to make sense).

\n","value":64},{"type":"int","name":"GIT_DIFF_FIND_ALL","comments":"

Turn on all finding features.

\n","value":255},{"type":"int","name":"GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE","comments":"

Measure similarity ignoring leading whitespace (default)

\n","value":0},{"type":"int","name":"GIT_DIFF_FIND_IGNORE_WHITESPACE","comments":"

Measure similarity ignoring all whitespace

\n","value":4096},{"type":"int","name":"GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE","comments":"

Measure similarity including all data

\n","value":8192},{"type":"int","name":"GIT_DIFF_FIND_EXACT_MATCH_ONLY","comments":"

Measure similarity only by comparing SHAs (fast and cheap)

\n","value":16384},{"type":"int","name":"GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY","comments":"

Do not break rewrites unless they contribute to a rename.

\n\n

Normally, GIT_DIFF_FIND_AND_BREAK_REWRITES will measure the self-\n similarity of modified files and split the ones that have changed a\n lot into a DELETE / ADD pair. Then the sides of that pair will be\n considered candidates for rename and copy detection.

\n\n

If you add this flag in and the split pair is not used for an\n actual rename or copy, then the modified record will be restored to\n a regular MODIFIED record instead of being split.

\n","value":32768},{"type":"int","name":"GIT_DIFF_FIND_REMOVE_UNMODIFIED","comments":"

Remove any UNMODIFIED deltas after find_similar is done.

\n\n

Using GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED to emulate the\n --find-copies-harder behavior requires building a diff with the\n GIT_DIFF_INCLUDE_UNMODIFIED flag. If you do not want UNMODIFIED\n records in the final result, pass this flag to have them removed.

\n","value":65536}],"used":{"returns":[],"needs":[]}}],["git_diff_flag_t",{"decl":["GIT_DIFF_FLAG_BINARY","GIT_DIFF_FLAG_NOT_BINARY","GIT_DIFF_FLAG_VALID_ID"],"type":"enum","file":"diff.h","line":214,"lineto":218,"block":"GIT_DIFF_FLAG_BINARY\nGIT_DIFF_FLAG_NOT_BINARY\nGIT_DIFF_FLAG_VALID_ID","tdef":"typedef","description":" Flags for the delta object and the file objects on each side.","comments":"

These flags are used for both the flags value of the git_diff_delta\n and the flags for the git_diff_file objects representing the old and\n new sides of the delta. Values outside of this public range should be\n considered reserved for internal or future use.

\n","fields":[{"type":"int","name":"GIT_DIFF_FLAG_BINARY","comments":"

file(s) treated as binary data

\n","value":1},{"type":"int","name":"GIT_DIFF_FLAG_NOT_BINARY","comments":"

file(s) treated as text data

\n","value":2},{"type":"int","name":"GIT_DIFF_FLAG_VALID_ID","comments":"

id value is known correct

\n","value":4}],"used":{"returns":[],"needs":[]}}],["git_diff_format_email_flags_t",{"decl":["GIT_DIFF_FORMAT_EMAIL_NONE","GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER"],"type":"enum","file":"diff.h","line":1151,"lineto":1158,"block":"GIT_DIFF_FORMAT_EMAIL_NONE\nGIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER","tdef":"typedef","description":" Formatting options for diff e-mail generation","comments":"","fields":[{"type":"int","name":"GIT_DIFF_FORMAT_EMAIL_NONE","comments":"

Normal patch, the default

\n","value":0},{"type":"int","name":"GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER","comments":"

Don't insert "[PATCH]" in the subject header

\n","value":1}],"used":{"returns":[],"needs":["git_diff_commit_as_email"]}}],["git_diff_format_email_options",{"decl":["unsigned int version","git_diff_format_email_flags_t flags","size_t patch_no","size_t total_patches","const git_oid * id","const char * summary","const git_signature * author"],"type":"struct","value":"git_diff_format_email_options","file":"diff.h","line":1163,"lineto":1182,"block":"unsigned int version\ngit_diff_format_email_flags_t flags\nsize_t patch_no\nsize_t total_patches\nconst git_oid * id\nconst char * summary\nconst git_signature * author","tdef":"typedef","description":" Options for controlling the formatting of the generated e-mail.","comments":"","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"git_diff_format_email_flags_t","name":"flags","comments":""},{"type":"size_t","name":"patch_no","comments":" This patch number "},{"type":"size_t","name":"total_patches","comments":" Total number of patches in this series "},{"type":"const git_oid *","name":"id","comments":" id to use for the commit "},{"type":"const char *","name":"summary","comments":" Summary of the change "},{"type":"const git_signature *","name":"author","comments":" Author of the change "}],"used":{"returns":[],"needs":["git_diff_format_email","git_diff_format_email_init_options"]}}],["git_diff_format_t",{"decl":["GIT_DIFF_FORMAT_PATCH","GIT_DIFF_FORMAT_PATCH_HEADER","GIT_DIFF_FORMAT_RAW","GIT_DIFF_FORMAT_NAME_ONLY","GIT_DIFF_FORMAT_NAME_STATUS"],"type":"enum","file":"diff.h","line":920,"lineto":926,"block":"GIT_DIFF_FORMAT_PATCH\nGIT_DIFF_FORMAT_PATCH_HEADER\nGIT_DIFF_FORMAT_RAW\nGIT_DIFF_FORMAT_NAME_ONLY\nGIT_DIFF_FORMAT_NAME_STATUS","tdef":"typedef","description":" Possible output formats for diff data","comments":"","fields":[{"type":"int","name":"GIT_DIFF_FORMAT_PATCH","comments":"

full git diff

\n","value":1},{"type":"int","name":"GIT_DIFF_FORMAT_PATCH_HEADER","comments":"

just the file headers of patch

\n","value":2},{"type":"int","name":"GIT_DIFF_FORMAT_RAW","comments":"

like git diff --raw

\n","value":3},{"type":"int","name":"GIT_DIFF_FORMAT_NAME_ONLY","comments":"

like git diff --name-only

\n","value":4},{"type":"int","name":"GIT_DIFF_FORMAT_NAME_STATUS","comments":"

like git diff --name-status

\n","value":5}],"used":{"returns":[],"needs":["git_diff_print"]}}],["git_diff_hunk",{"decl":"git_diff_hunk","type":"struct","value":"git_diff_hunk","file":"diff.h","line":417,"lineto":417,"tdef":"typedef","description":" Structure describing a hunk of a diff.","comments":"","used":{"returns":[],"needs":["git_diff_print_callback__to_buf","git_diff_print_callback__to_file_handle","git_patch_get_hunk"]}}],["git_diff_line",{"decl":"git_diff_line","type":"struct","value":"git_diff_line","file":"diff.h","line":465,"lineto":465,"tdef":"typedef","description":" Structure describing a line (or data span) of a diff.","comments":"","used":{"returns":[],"needs":["git_diff_print_callback__to_buf","git_diff_print_callback__to_file_handle","git_patch_get_line_in_hunk"]}}],["git_diff_line_t",{"decl":["GIT_DIFF_LINE_CONTEXT","GIT_DIFF_LINE_ADDITION","GIT_DIFF_LINE_DELETION","GIT_DIFF_LINE_CONTEXT_EOFNL","GIT_DIFF_LINE_ADD_EOFNL","GIT_DIFF_LINE_DEL_EOFNL","GIT_DIFF_LINE_FILE_HDR","GIT_DIFF_LINE_HUNK_HDR","GIT_DIFF_LINE_BINARY"],"type":"enum","file":"diff.h","line":444,"lineto":460,"block":"GIT_DIFF_LINE_CONTEXT\nGIT_DIFF_LINE_ADDITION\nGIT_DIFF_LINE_DELETION\nGIT_DIFF_LINE_CONTEXT_EOFNL\nGIT_DIFF_LINE_ADD_EOFNL\nGIT_DIFF_LINE_DEL_EOFNL\nGIT_DIFF_LINE_FILE_HDR\nGIT_DIFF_LINE_HUNK_HDR\nGIT_DIFF_LINE_BINARY","tdef":"typedef","description":" Line origin constants.","comments":"

These values describe where a line came from and will be passed to\n the git_diff_line_cb when iterating over a diff. There are some\n special origin constants at the end that are used for the text\n output callbacks to demarcate lines that are actually part of\n the file or hunk headers.

\n","fields":[{"type":"int","name":"GIT_DIFF_LINE_CONTEXT","comments":"","value":32},{"type":"int","name":"GIT_DIFF_LINE_ADDITION","comments":"","value":43},{"type":"int","name":"GIT_DIFF_LINE_DELETION","comments":"","value":45},{"type":"int","name":"GIT_DIFF_LINE_CONTEXT_EOFNL","comments":"

Both files have no LF at end

\n","value":61},{"type":"int","name":"GIT_DIFF_LINE_ADD_EOFNL","comments":"

Old has no LF at end, new does

\n","value":62},{"type":"int","name":"GIT_DIFF_LINE_DEL_EOFNL","comments":"

Old has LF at end, new does not

\n","value":60},{"type":"int","name":"GIT_DIFF_LINE_FILE_HDR","comments":"","value":70},{"type":"int","name":"GIT_DIFF_LINE_HUNK_HDR","comments":"","value":72},{"type":"int","name":"GIT_DIFF_LINE_BINARY","comments":"

For "Binary files x and y differ"

\n","value":66}],"used":{"returns":[],"needs":[]}}],["git_diff_option_t",{"decl":["GIT_DIFF_NORMAL","GIT_DIFF_REVERSE","GIT_DIFF_INCLUDE_IGNORED","GIT_DIFF_RECURSE_IGNORED_DIRS","GIT_DIFF_INCLUDE_UNTRACKED","GIT_DIFF_RECURSE_UNTRACKED_DIRS","GIT_DIFF_INCLUDE_UNMODIFIED","GIT_DIFF_INCLUDE_TYPECHANGE","GIT_DIFF_INCLUDE_TYPECHANGE_TREES","GIT_DIFF_IGNORE_FILEMODE","GIT_DIFF_IGNORE_SUBMODULES","GIT_DIFF_IGNORE_CASE","GIT_DIFF_DISABLE_PATHSPEC_MATCH","GIT_DIFF_SKIP_BINARY_CHECK","GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS","GIT_DIFF_UPDATE_INDEX","GIT_DIFF_FORCE_TEXT","GIT_DIFF_FORCE_BINARY","GIT_DIFF_IGNORE_WHITESPACE","GIT_DIFF_IGNORE_WHITESPACE_CHANGE","GIT_DIFF_IGNORE_WHITESPACE_EOL","GIT_DIFF_SHOW_UNTRACKED_CONTENT","GIT_DIFF_SHOW_UNMODIFIED","GIT_DIFF_PATIENCE","GIT_DIFF_MINIMAL","GIT_DIFF_SHOW_BINARY"],"type":"enum","file":"diff.h","line":72,"lineto":194,"block":"GIT_DIFF_NORMAL\nGIT_DIFF_REVERSE\nGIT_DIFF_INCLUDE_IGNORED\nGIT_DIFF_RECURSE_IGNORED_DIRS\nGIT_DIFF_INCLUDE_UNTRACKED\nGIT_DIFF_RECURSE_UNTRACKED_DIRS\nGIT_DIFF_INCLUDE_UNMODIFIED\nGIT_DIFF_INCLUDE_TYPECHANGE\nGIT_DIFF_INCLUDE_TYPECHANGE_TREES\nGIT_DIFF_IGNORE_FILEMODE\nGIT_DIFF_IGNORE_SUBMODULES\nGIT_DIFF_IGNORE_CASE\nGIT_DIFF_DISABLE_PATHSPEC_MATCH\nGIT_DIFF_SKIP_BINARY_CHECK\nGIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS\nGIT_DIFF_UPDATE_INDEX\nGIT_DIFF_FORCE_TEXT\nGIT_DIFF_FORCE_BINARY\nGIT_DIFF_IGNORE_WHITESPACE\nGIT_DIFF_IGNORE_WHITESPACE_CHANGE\nGIT_DIFF_IGNORE_WHITESPACE_EOL\nGIT_DIFF_SHOW_UNTRACKED_CONTENT\nGIT_DIFF_SHOW_UNMODIFIED\nGIT_DIFF_PATIENCE\nGIT_DIFF_MINIMAL\nGIT_DIFF_SHOW_BINARY","tdef":"typedef","description":" Flags for diff options. A combination of these flags can be passed\n in via the `flags` value in the `git_diff_options`.","comments":"","fields":[{"type":"int","name":"GIT_DIFF_NORMAL","comments":"

Normal diff, the default

\n","value":0},{"type":"int","name":"GIT_DIFF_REVERSE","comments":"

Reverse the sides of the diff

\n","value":1},{"type":"int","name":"GIT_DIFF_INCLUDE_IGNORED","comments":"

Include ignored files in the diff

\n","value":2},{"type":"int","name":"GIT_DIFF_RECURSE_IGNORED_DIRS","comments":"

Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory\n will be marked with only a single entry in the diff; this flag\n adds all files under the directory as IGNORED entries, too.

\n","value":4},{"type":"int","name":"GIT_DIFF_INCLUDE_UNTRACKED","comments":"

Include untracked files in the diff

\n","value":8},{"type":"int","name":"GIT_DIFF_RECURSE_UNTRACKED_DIRS","comments":"

Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked\n directory will be marked with only a single entry in the diff\n (a la what core Git does in git status); this flag adds all\n files under untracked directories as UNTRACKED entries, too.

\n","value":16},{"type":"int","name":"GIT_DIFF_INCLUDE_UNMODIFIED","comments":"

Include unmodified files in the diff

\n","value":32},{"type":"int","name":"GIT_DIFF_INCLUDE_TYPECHANGE","comments":"

Normally, a type change between files will be converted into a\n DELETED record for the old and an ADDED record for the new; this\n options enabled the generation of TYPECHANGE delta records.

\n","value":64},{"type":"int","name":"GIT_DIFF_INCLUDE_TYPECHANGE_TREES","comments":"

Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still\n generally show as a DELETED blob. This flag tries to correctly\n label blob->tree transitions as TYPECHANGE records with new_file's\n mode set to tree. Note: the tree SHA will not be available.

\n","value":128},{"type":"int","name":"GIT_DIFF_IGNORE_FILEMODE","comments":"

Ignore file mode changes

\n","value":256},{"type":"int","name":"GIT_DIFF_IGNORE_SUBMODULES","comments":"

Treat all submodules as unmodified

\n","value":512},{"type":"int","name":"GIT_DIFF_IGNORE_CASE","comments":"

Use case insensitive filename comparisons

\n","value":1024},{"type":"int","name":"GIT_DIFF_DISABLE_PATHSPEC_MATCH","comments":"

If the pathspec is set in the diff options, this flags means to\n apply it as an exact match instead of as an fnmatch pattern.

\n","value":4096},{"type":"int","name":"GIT_DIFF_SKIP_BINARY_CHECK","comments":"

Disable updating of the binary flag in delta records. This is\n useful when iterating over a diff if you don't need hunk and data\n callbacks and want to avoid having to load file completely.

\n","value":8192},{"type":"int","name":"GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS","comments":"

When diff finds an untracked directory, to match the behavior of\n core Git, it scans the contents for IGNORED and UNTRACKED files.\n If all contents are IGNORED, then the directory is IGNORED; if\n any contents are not IGNORED, then the directory is UNTRACKED.\n This is extra work that may not matter in many cases. This flag\n turns off that scan and immediately labels an untracked directory\n as UNTRACKED (changing the behavior to not match core Git).

\n","value":16384},{"type":"int","name":"GIT_DIFF_UPDATE_INDEX","comments":"

When diff finds a file in the working directory with stat\n information different from the index, but the OID ends up being the\n same, write the correct stat information into the index. Note:\n without this flag, diff will always leave the index untouched.

\n","value":32768},{"type":"int","name":"GIT_DIFF_FORCE_TEXT","comments":"

Treat all files as text, disabling binary attributes \n&\n detection

\n","value":1048576},{"type":"int","name":"GIT_DIFF_FORCE_BINARY","comments":"

Treat all files as binary, disabling text diffs

\n","value":2097152},{"type":"int","name":"GIT_DIFF_IGNORE_WHITESPACE","comments":"

Ignore all whitespace

\n","value":4194304},{"type":"int","name":"GIT_DIFF_IGNORE_WHITESPACE_CHANGE","comments":"

Ignore changes in amount of whitespace

\n","value":8388608},{"type":"int","name":"GIT_DIFF_IGNORE_WHITESPACE_EOL","comments":"

Ignore whitespace at end of line

\n","value":16777216},{"type":"int","name":"GIT_DIFF_SHOW_UNTRACKED_CONTENT","comments":"

When generating patch text, include the content of untracked\n files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but\n it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that\n flag if you want the content of every single UNTRACKED file.

\n","value":33554432},{"type":"int","name":"GIT_DIFF_SHOW_UNMODIFIED","comments":"

When generating output, include the names of unmodified files if\n they are included in the git_diff. Normally these are skipped in\n the formats that list files (e.g. name-only, name-status, raw).\n Even with this, these will not be included in patch format.

\n","value":67108864},{"type":"int","name":"GIT_DIFF_PATIENCE","comments":"

Use the "patience diff" algorithm

\n","value":268435456},{"type":"int","name":"GIT_DIFF_MINIMAL","comments":"

Take extra time to find minimal diff

\n","value":536870912},{"type":"int","name":"GIT_DIFF_SHOW_BINARY","comments":"

Include the necessary deflate / delta information so that git-apply\n can apply given diff information to binary files.

\n","value":1073741824}],"used":{"returns":[],"needs":[]}}],["git_diff_options",{"decl":["unsigned int version","uint32_t flags","git_submodule_ignore_t ignore_submodules","git_strarray pathspec","git_diff_notify_cb notify_cb","void * notify_payload","uint16_t context_lines","uint16_t interhunk_lines","uint16_t id_abbrev","git_off_t max_size","const char * old_prefix","const char * new_prefix"],"type":"struct","value":"git_diff_options","file":"diff.h","line":360,"lineto":379,"block":"unsigned int version\nuint32_t flags\ngit_submodule_ignore_t ignore_submodules\ngit_strarray pathspec\ngit_diff_notify_cb notify_cb\nvoid * notify_payload\nuint16_t context_lines\nuint16_t interhunk_lines\nuint16_t id_abbrev\ngit_off_t max_size\nconst char * old_prefix\nconst char * new_prefix","tdef":"typedef","description":" Structure describing options about how the diff should be executed.","comments":"

Setting all values of the structure to zero will yield the default\n values. Similarly, passing NULL for the options structure will\n give the defaults. The default values are marked below.

\n\n
    \n
  • flags is a combination of the git_diff_option_t values above
  • \n
  • context_lines is the number of unchanged lines that define the\nboundary of a hunk (and to display before and after)
  • \n
  • interhunk_lines is the maximum number of unchanged lines between\nhunk boundaries before the hunks will be merged into a one.
  • \n
  • old_prefix is the virtual "directory" to prefix to old file names\nin hunk headers (default "a")
  • \n
  • new_prefix is the virtual "directory" to prefix to new file names\nin hunk headers (default "b")
  • \n
  • pathspec is an array of paths / fnmatch patterns to constrain diff
  • \n
  • max_size is a file size (in bytes) above which a blob will be marked\nas binary automatically; pass a negative value to disable.
  • \n
  • notify_cb is an optional callback function, notifying the consumer of\nwhich files are being examined as the diff is generated
  • \n
  • notify_payload is the payload data to pass to the notify_cb function
  • \n
  • ignore_submodules overrides the submodule ignore setting for all\nsubmodules in the diff.
  • \n
\n","fields":[{"type":"unsigned int","name":"version","comments":" version for the struct "},{"type":"uint32_t","name":"flags","comments":" defaults to GIT_DIFF_NORMAL "},{"type":"git_submodule_ignore_t","name":"ignore_submodules","comments":" submodule ignore rule "},{"type":"git_strarray","name":"pathspec","comments":" defaults to include all paths "},{"type":"git_diff_notify_cb","name":"notify_cb","comments":""},{"type":"void *","name":"notify_payload","comments":""},{"type":"uint16_t","name":"context_lines","comments":" defaults to 3 "},{"type":"uint16_t","name":"interhunk_lines","comments":" defaults to 0 "},{"type":"uint16_t","name":"id_abbrev","comments":" default 'core.abbrev' or 7 if unset "},{"type":"git_off_t","name":"max_size","comments":" defaults to 512MB "},{"type":"const char *","name":"old_prefix","comments":" defaults to \"a\" "},{"type":"const char *","name":"new_prefix","comments":" defaults to \"b\" "}],"used":{"returns":[],"needs":["git_diff_blob_to_buffer","git_diff_blobs","git_diff_buffers","git_diff_commit_as_email","git_diff_index_to_workdir","git_diff_init_options","git_diff_tree_to_index","git_diff_tree_to_tree","git_diff_tree_to_workdir","git_diff_tree_to_workdir_with_index","git_patch_from_blob_and_buffer","git_patch_from_blobs","git_patch_from_buffers"]}}],["git_diff_similarity_metric",{"decl":["int (*)(void **, const git_diff_file *, const char *, void *) file_signature","int (*)(void **, const git_diff_file *, const char *, size_t, void *) buffer_signature","void (*)(void *, void *) free_signature","int (*)(int *, void *, void *, void *) similarity","void * payload"],"type":"struct","value":"git_diff_similarity_metric","file":"diff.h","line":567,"lineto":577,"block":"int (*)(void **, const git_diff_file *, const char *, void *) file_signature\nint (*)(void **, const git_diff_file *, const char *, size_t, void *) buffer_signature\nvoid (*)(void *, void *) free_signature\nint (*)(int *, void *, void *, void *) similarity\nvoid * payload","tdef":"typedef","description":" Pluggable similarity metric","comments":"","fields":[{"type":"int (*)(void **, const git_diff_file *, const char *, void *)","name":"file_signature","comments":""},{"type":"int (*)(void **, const git_diff_file *, const char *, size_t, void *)","name":"buffer_signature","comments":""},{"type":"void (*)(void *, void *)","name":"free_signature","comments":""},{"type":"int (*)(int *, void *, void *, void *)","name":"similarity","comments":""},{"type":"void *","name":"payload","comments":""}],"used":{"returns":[],"needs":[]}}],["git_diff_stats",{"decl":"git_diff_stats","type":"struct","value":"git_diff_stats","file":"diff.h","line":1065,"lineto":1065,"tdef":"typedef","description":" This is an opaque structure which is allocated by `git_diff_get_stats`.\n You are responsible for releasing the object memory when done, using the\n `git_diff_stats_free()` function.","comments":"","used":{"returns":[],"needs":["git_diff_get_stats","git_diff_stats_deletions","git_diff_stats_files_changed","git_diff_stats_free","git_diff_stats_insertions","git_diff_stats_to_buf"]}}],["git_diff_stats_format_t",{"decl":["GIT_DIFF_STATS_NONE","GIT_DIFF_STATS_FULL","GIT_DIFF_STATS_SHORT","GIT_DIFF_STATS_NUMBER","GIT_DIFF_STATS_INCLUDE_SUMMARY"],"type":"enum","file":"diff.h","line":1070,"lineto":1085,"block":"GIT_DIFF_STATS_NONE\nGIT_DIFF_STATS_FULL\nGIT_DIFF_STATS_SHORT\nGIT_DIFF_STATS_NUMBER\nGIT_DIFF_STATS_INCLUDE_SUMMARY","tdef":"typedef","description":" Formatting options for diff stats","comments":"","fields":[{"type":"int","name":"GIT_DIFF_STATS_NONE","comments":"

No stats

\n","value":0},{"type":"int","name":"GIT_DIFF_STATS_FULL","comments":"

Full statistics, equivalent of --stat

\n","value":1},{"type":"int","name":"GIT_DIFF_STATS_SHORT","comments":"

Short statistics, equivalent of --shortstat

\n","value":2},{"type":"int","name":"GIT_DIFF_STATS_NUMBER","comments":"

Number statistics, equivalent of --numstat

\n","value":4},{"type":"int","name":"GIT_DIFF_STATS_INCLUDE_SUMMARY","comments":"

Extended header information such as creations, renames and mode changes, equivalent of --summary

\n","value":8}],"used":{"returns":[],"needs":["git_diff_stats_to_buf"]}}],["git_error",{"decl":["char * message","int klass"],"type":"struct","value":"git_error","file":"errors.h","line":55,"lineto":58,"block":"char * message\nint klass","tdef":"typedef","description":" Structure to store extra details of the last error that occurred.","comments":"

This is kept on a per-thread basis if GIT_THREADS was defined when the\n library was build, otherwise one is kept globally for the library

\n","fields":[{"type":"char *","name":"message","comments":""},{"type":"int","name":"klass","comments":""}],"used":{"returns":["giterr_last"],"needs":["giterr_detach"]}}],["git_error_code",{"decl":["GIT_OK","GIT_ERROR","GIT_ENOTFOUND","GIT_EEXISTS","GIT_EAMBIGUOUS","GIT_EBUFS","GIT_EUSER","GIT_EBAREREPO","GIT_EUNBORNBRANCH","GIT_EUNMERGED","GIT_ENONFASTFORWARD","GIT_EINVALIDSPEC","GIT_EMERGECONFLICT","GIT_ELOCKED","GIT_EMODIFIED","GIT_PASSTHROUGH","GIT_ITEROVER"],"type":"enum","file":"errors.h","line":21,"lineto":47,"block":"GIT_OK\nGIT_ERROR\nGIT_ENOTFOUND\nGIT_EEXISTS\nGIT_EAMBIGUOUS\nGIT_EBUFS\nGIT_EUSER\nGIT_EBAREREPO\nGIT_EUNBORNBRANCH\nGIT_EUNMERGED\nGIT_ENONFASTFORWARD\nGIT_EINVALIDSPEC\nGIT_EMERGECONFLICT\nGIT_ELOCKED\nGIT_EMODIFIED\nGIT_PASSTHROUGH\nGIT_ITEROVER","tdef":"typedef","description":" Generic return codes ","comments":"","fields":[{"type":"int","name":"GIT_OK","comments":"

No error

\n","value":0},{"type":"int","name":"GIT_ERROR","comments":"

Generic error

\n","value":-1},{"type":"int","name":"GIT_ENOTFOUND","comments":"

Requested object could not be found

\n","value":-3},{"type":"int","name":"GIT_EEXISTS","comments":"

Object exists preventing operation

\n","value":-4},{"type":"int","name":"GIT_EAMBIGUOUS","comments":"

More than one object matches

\n","value":-5},{"type":"int","name":"GIT_EBUFS","comments":"

Output buffer too short to hold data

\n","value":-6},{"type":"int","name":"GIT_EUSER","comments":"","value":-7},{"type":"int","name":"GIT_EBAREREPO","comments":"

Operation not allowed on bare repository

\n","value":-8},{"type":"int","name":"GIT_EUNBORNBRANCH","comments":"

HEAD refers to branch with no commits

\n","value":-9},{"type":"int","name":"GIT_EUNMERGED","comments":"

Merge in progress prevented operation

\n","value":-10},{"type":"int","name":"GIT_ENONFASTFORWARD","comments":"

Reference was not fast-forwardable

\n","value":-11},{"type":"int","name":"GIT_EINVALIDSPEC","comments":"

Name/ref spec was not in a valid format

\n","value":-12},{"type":"int","name":"GIT_EMERGECONFLICT","comments":"

Merge conflicts prevented operation

\n","value":-13},{"type":"int","name":"GIT_ELOCKED","comments":"

Lock file prevented operation

\n","value":-14},{"type":"int","name":"GIT_EMODIFIED","comments":"

Reference value does not match expected

\n","value":-15},{"type":"int","name":"GIT_PASSTHROUGH","comments":"

Internal only

\n","value":-30},{"type":"int","name":"GIT_ITEROVER","comments":"

Signals end of iteration with iterator

\n","value":-31}],"used":{"returns":[],"needs":[]}}],["git_error_t",{"decl":["GITERR_NONE","GITERR_NOMEMORY","GITERR_OS","GITERR_INVALID","GITERR_REFERENCE","GITERR_ZLIB","GITERR_REPOSITORY","GITERR_CONFIG","GITERR_REGEX","GITERR_ODB","GITERR_INDEX","GITERR_OBJECT","GITERR_NET","GITERR_TAG","GITERR_TREE","GITERR_INDEXER","GITERR_SSL","GITERR_SUBMODULE","GITERR_THREAD","GITERR_STASH","GITERR_CHECKOUT","GITERR_FETCHHEAD","GITERR_MERGE","GITERR_SSH","GITERR_FILTER","GITERR_REVERT","GITERR_CALLBACK","GITERR_CHERRYPICK"],"type":"enum","file":"errors.h","line":61,"lineto":90,"block":"GITERR_NONE\nGITERR_NOMEMORY\nGITERR_OS\nGITERR_INVALID\nGITERR_REFERENCE\nGITERR_ZLIB\nGITERR_REPOSITORY\nGITERR_CONFIG\nGITERR_REGEX\nGITERR_ODB\nGITERR_INDEX\nGITERR_OBJECT\nGITERR_NET\nGITERR_TAG\nGITERR_TREE\nGITERR_INDEXER\nGITERR_SSL\nGITERR_SUBMODULE\nGITERR_THREAD\nGITERR_STASH\nGITERR_CHECKOUT\nGITERR_FETCHHEAD\nGITERR_MERGE\nGITERR_SSH\nGITERR_FILTER\nGITERR_REVERT\nGITERR_CALLBACK\nGITERR_CHERRYPICK","tdef":"typedef","description":" Error classes ","comments":"","fields":[{"type":"int","name":"GITERR_NONE","comments":"","value":0},{"type":"int","name":"GITERR_NOMEMORY","comments":"","value":1},{"type":"int","name":"GITERR_OS","comments":"","value":2},{"type":"int","name":"GITERR_INVALID","comments":"","value":3},{"type":"int","name":"GITERR_REFERENCE","comments":"","value":4},{"type":"int","name":"GITERR_ZLIB","comments":"","value":5},{"type":"int","name":"GITERR_REPOSITORY","comments":"","value":6},{"type":"int","name":"GITERR_CONFIG","comments":"","value":7},{"type":"int","name":"GITERR_REGEX","comments":"","value":8},{"type":"int","name":"GITERR_ODB","comments":"","value":9},{"type":"int","name":"GITERR_INDEX","comments":"","value":10},{"type":"int","name":"GITERR_OBJECT","comments":"","value":11},{"type":"int","name":"GITERR_NET","comments":"","value":12},{"type":"int","name":"GITERR_TAG","comments":"","value":13},{"type":"int","name":"GITERR_TREE","comments":"","value":14},{"type":"int","name":"GITERR_INDEXER","comments":"","value":15},{"type":"int","name":"GITERR_SSL","comments":"","value":16},{"type":"int","name":"GITERR_SUBMODULE","comments":"","value":17},{"type":"int","name":"GITERR_THREAD","comments":"","value":18},{"type":"int","name":"GITERR_STASH","comments":"","value":19},{"type":"int","name":"GITERR_CHECKOUT","comments":"","value":20},{"type":"int","name":"GITERR_FETCHHEAD","comments":"","value":21},{"type":"int","name":"GITERR_MERGE","comments":"","value":22},{"type":"int","name":"GITERR_SSH","comments":"","value":23},{"type":"int","name":"GITERR_FILTER","comments":"","value":24},{"type":"int","name":"GITERR_REVERT","comments":"","value":25},{"type":"int","name":"GITERR_CALLBACK","comments":"","value":26},{"type":"int","name":"GITERR_CHERRYPICK","comments":"","value":27}],"used":{"returns":[],"needs":[]}}],["git_feature_t",{"decl":["GIT_FEATURE_THREADS","GIT_FEATURE_HTTPS","GIT_FEATURE_SSH"],"type":"enum","file":"common.h","line":100,"lineto":104,"block":"GIT_FEATURE_THREADS\nGIT_FEATURE_HTTPS\nGIT_FEATURE_SSH","tdef":"typedef","description":" Combinations of these values describe the features with which libgit2\n was compiled","comments":"","fields":[{"type":"int","name":"GIT_FEATURE_THREADS","comments":"","value":1},{"type":"int","name":"GIT_FEATURE_HTTPS","comments":"","value":2},{"type":"int","name":"GIT_FEATURE_SSH","comments":"","value":4}],"used":{"returns":[],"needs":[]}}],["git_filemode_t",{"decl":["GIT_FILEMODE_NEW","GIT_FILEMODE_TREE","GIT_FILEMODE_BLOB","GIT_FILEMODE_BLOB_EXECUTABLE","GIT_FILEMODE_LINK","GIT_FILEMODE_COMMIT"],"type":"enum","file":"types.h","line":200,"lineto":207,"block":"GIT_FILEMODE_NEW\nGIT_FILEMODE_TREE\nGIT_FILEMODE_BLOB\nGIT_FILEMODE_BLOB_EXECUTABLE\nGIT_FILEMODE_LINK\nGIT_FILEMODE_COMMIT","tdef":"typedef","description":" Valid modes for index and tree entries. ","comments":"","fields":[{"type":"int","name":"GIT_FILEMODE_NEW","comments":"","value":0},{"type":"int","name":"GIT_FILEMODE_TREE","comments":"","value":16384},{"type":"int","name":"GIT_FILEMODE_BLOB","comments":"","value":33188},{"type":"int","name":"GIT_FILEMODE_BLOB_EXECUTABLE","comments":"","value":33261},{"type":"int","name":"GIT_FILEMODE_LINK","comments":"","value":40960},{"type":"int","name":"GIT_FILEMODE_COMMIT","comments":"","value":57344}],"used":{"returns":[],"needs":["git_treebuilder_insert"]}}],["git_filter",{"decl":["unsigned int version","const char * attributes","git_filter_init_fn initialize","git_filter_shutdown_fn shutdown","git_filter_check_fn check","git_filter_apply_fn apply","git_filter_cleanup_fn cleanup"],"type":"struct","value":"git_filter","file":"sys/filter.h","line":241,"lineto":251,"tdef":null,"description":" Filter structure used to register custom filters.","comments":"

To associate extra data with a filter, allocate extra data and put the\n git_filter struct at the start of your data buffer, then cast the\n self pointer to your larger structure when your callback is invoked.

\n\n

version should be set to GIT_FILTER_VERSION

\n\n

attributes is a whitespace-separated list of attribute names to check\n for this filter (e.g. "eol crlf text"). If the attribute name is bare,\n it will be simply loaded and passed to the check callback. If it has\n a value (i.e. "name=value"), the attribute must match that value for\n the filter to be applied.

\n\n

The initialize, shutdown, check, apply, and cleanup callbacks\n are all documented above with the respective function pointer typedefs.

\n","block":"unsigned int version\nconst char * attributes\ngit_filter_init_fn initialize\ngit_filter_shutdown_fn shutdown\ngit_filter_check_fn check\ngit_filter_apply_fn apply\ngit_filter_cleanup_fn cleanup","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"const char *","name":"attributes","comments":""},{"type":"git_filter_init_fn","name":"initialize","comments":""},{"type":"git_filter_shutdown_fn","name":"shutdown","comments":""},{"type":"git_filter_check_fn","name":"check","comments":""},{"type":"git_filter_apply_fn","name":"apply","comments":""},{"type":"git_filter_cleanup_fn","name":"cleanup","comments":""}],"used":{"returns":["git_filter_lookup"],"needs":["git_filter_list_push","git_filter_register"]}}],["git_filter_list",{"decl":"git_filter_list","type":"struct","value":"git_filter_list","file":"filter.h","line":70,"lineto":70,"tdef":"typedef","description":" List of filters to be applied","comments":"

This represents a list of filters to be applied to a file / blob. You\n can build the list with one call, apply it with another, and dispose it\n with a third. In typical usage, there are not many occasions where a\n git_filter_list is needed directly since the library will generally\n handle conversions for you, but it can be convenient to be able to\n build and apply the list sometimes.

\n","used":{"returns":[],"needs":["git_filter_list_apply_to_blob","git_filter_list_apply_to_data","git_filter_list_apply_to_file","git_filter_list_free","git_filter_list_length","git_filter_list_load","git_filter_list_new","git_filter_list_push"]}}],["git_filter_mode_t",{"decl":["GIT_FILTER_TO_WORKTREE","GIT_FILTER_SMUDGE","GIT_FILTER_TO_ODB","GIT_FILTER_CLEAN"],"type":"enum","file":"filter.h","line":31,"lineto":36,"block":"GIT_FILTER_TO_WORKTREE\nGIT_FILTER_SMUDGE\nGIT_FILTER_TO_ODB\nGIT_FILTER_CLEAN","tdef":"typedef","description":" Filters are applied in one of two directions: smudging - which is\n exporting a file from the Git object database to the working directory,\n and cleaning - which is importing a file from the working directory to\n the Git object database. These values control which direction of\n change is being applied.","comments":"","fields":[{"type":"int","name":"GIT_FILTER_TO_WORKTREE","comments":"","value":0},{"type":"int","name":"GIT_FILTER_SMUDGE","comments":"","value":0},{"type":"int","name":"GIT_FILTER_TO_ODB","comments":"","value":1},{"type":"int","name":"GIT_FILTER_CLEAN","comments":"","value":1}],"used":{"returns":[],"needs":["git_filter_list_load","git_filter_list_new"]}}],["git_filter_source",{"decl":"git_filter_source","type":"struct","value":"git_filter_source","file":"sys/filter.h","line":95,"lineto":95,"tdef":"typedef","description":" A filter source represents a file/blob to be processed","comments":"","used":{"returns":[],"needs":["git_filter_source_filemode","git_filter_source_id","git_filter_source_mode","git_filter_source_options","git_filter_source_path","git_filter_source_repo"]}}],["git_idxentry_extended_flag_t",{"decl":["GIT_IDXENTRY_INTENT_TO_ADD","GIT_IDXENTRY_SKIP_WORKTREE","GIT_IDXENTRY_EXTENDED2","GIT_IDXENTRY_EXTENDED_FLAGS","GIT_IDXENTRY_UPDATE","GIT_IDXENTRY_REMOVE","GIT_IDXENTRY_UPTODATE","GIT_IDXENTRY_ADDED","GIT_IDXENTRY_HASHED","GIT_IDXENTRY_UNHASHED","GIT_IDXENTRY_WT_REMOVE","GIT_IDXENTRY_CONFLICTED","GIT_IDXENTRY_UNPACKED","GIT_IDXENTRY_NEW_SKIP_WORKTREE"],"type":"enum","file":"index.h","line":107,"lineto":127,"block":"GIT_IDXENTRY_INTENT_TO_ADD\nGIT_IDXENTRY_SKIP_WORKTREE\nGIT_IDXENTRY_EXTENDED2\nGIT_IDXENTRY_EXTENDED_FLAGS\nGIT_IDXENTRY_UPDATE\nGIT_IDXENTRY_REMOVE\nGIT_IDXENTRY_UPTODATE\nGIT_IDXENTRY_ADDED\nGIT_IDXENTRY_HASHED\nGIT_IDXENTRY_UNHASHED\nGIT_IDXENTRY_WT_REMOVE\nGIT_IDXENTRY_CONFLICTED\nGIT_IDXENTRY_UNPACKED\nGIT_IDXENTRY_NEW_SKIP_WORKTREE","tdef":"typedef","description":" Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended`","comments":"

In memory, the flags_extended fields are divided into two parts: the\n fields that are read from and written to disk, and other fields that\n in-memory only and used by libgit2. Only the flags in\n GIT_IDXENTRY_EXTENDED_FLAGS will get saved on-disk.

\n\n

Thee first three bitmasks match the three fields in the\n git_index_entry flags_extended value that belong on disk. You\n can use them to interpret the data in the flags_extended.

\n\n

The rest of the bitmasks match the other fields in the git_index_entry\n flags_extended value that are only used in-memory by libgit2.\n You can use them to interpret the data in the flags_extended.

\n","fields":[{"type":"int","name":"GIT_IDXENTRY_INTENT_TO_ADD","comments":"","value":8192},{"type":"int","name":"GIT_IDXENTRY_SKIP_WORKTREE","comments":"","value":16384},{"type":"int","name":"GIT_IDXENTRY_EXTENDED2","comments":"

Reserved for future extension

\n","value":32768},{"type":"int","name":"GIT_IDXENTRY_EXTENDED_FLAGS","comments":"

Reserved for future extension

\n","value":24576},{"type":"int","name":"GIT_IDXENTRY_UPDATE","comments":"

Reserved for future extension

\n","value":1},{"type":"int","name":"GIT_IDXENTRY_REMOVE","comments":"

Reserved for future extension

\n","value":2},{"type":"int","name":"GIT_IDXENTRY_UPTODATE","comments":"

Reserved for future extension

\n","value":4},{"type":"int","name":"GIT_IDXENTRY_ADDED","comments":"

Reserved for future extension

\n","value":8},{"type":"int","name":"GIT_IDXENTRY_HASHED","comments":"

Reserved for future extension

\n","value":16},{"type":"int","name":"GIT_IDXENTRY_UNHASHED","comments":"

Reserved for future extension

\n","value":32},{"type":"int","name":"GIT_IDXENTRY_WT_REMOVE","comments":"

remove in work directory

\n","value":64},{"type":"int","name":"GIT_IDXENTRY_CONFLICTED","comments":"","value":128},{"type":"int","name":"GIT_IDXENTRY_UNPACKED","comments":"","value":256},{"type":"int","name":"GIT_IDXENTRY_NEW_SKIP_WORKTREE","comments":"","value":512}],"used":{"returns":[],"needs":[]}}],["git_index",{"decl":"git_index","type":"struct","value":"git_index","file":"types.h","line":132,"lineto":132,"tdef":"typedef","description":" Memory representation of an index file. ","comments":"","used":{"returns":[],"needs":["git_checkout_index","git_cherry_pick_commit","git_diff_index_to_workdir","git_diff_tree_to_index","git_index_add","git_index_add_all","git_index_add_bypath","git_index_caps","git_index_clear","git_index_conflict_add","git_index_conflict_cleanup","git_index_conflict_get","git_index_conflict_iterator_new","git_index_conflict_remove","git_index_entrycount","git_index_find","git_index_free","git_index_get_byindex","git_index_get_bypath","git_index_has_conflicts","git_index_new","git_index_open","git_index_owner","git_index_path","git_index_read","git_index_read_tree","git_index_remove","git_index_remove_all","git_index_remove_bypath","git_index_remove_directory","git_index_set_caps","git_index_update_all","git_index_write","git_index_write_tree","git_index_write_tree_to","git_merge_commits","git_merge_trees","git_pathspec_match_index","git_repository_index","git_revert_commit"]}}],["git_index_add_option_t",{"decl":["GIT_INDEX_ADD_DEFAULT","GIT_INDEX_ADD_FORCE","GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH","GIT_INDEX_ADD_CHECK_PATHSPEC"],"type":"enum","file":"index.h","line":142,"lineto":147,"block":"GIT_INDEX_ADD_DEFAULT\nGIT_INDEX_ADD_FORCE\nGIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH\nGIT_INDEX_ADD_CHECK_PATHSPEC","tdef":"typedef","description":" Flags for APIs that add files matching pathspec ","comments":"","fields":[{"type":"int","name":"GIT_INDEX_ADD_DEFAULT","comments":"","value":0},{"type":"int","name":"GIT_INDEX_ADD_FORCE","comments":"","value":1},{"type":"int","name":"GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH","comments":"","value":2},{"type":"int","name":"GIT_INDEX_ADD_CHECK_PATHSPEC","comments":"","value":4}],"used":{"returns":[],"needs":[]}}],["git_index_conflict_iterator",{"decl":"git_index_conflict_iterator","type":"struct","value":"git_index_conflict_iterator","file":"types.h","line":135,"lineto":135,"tdef":"typedef","description":" An iterator for conflicts in the index. ","comments":"","used":{"returns":[],"needs":["git_index_conflict_iterator_free","git_index_conflict_iterator_new","git_index_conflict_next"]}}],["git_index_entry",{"decl":["git_index_time ctime","git_index_time mtime","unsigned int dev","unsigned int ino","unsigned int mode","unsigned int uid","unsigned int gid","git_off_t file_size","git_oid id","unsigned short flags","unsigned short flags_extended","const char * path"],"type":"struct","value":"git_index_entry","file":"index.h","line":48,"lineto":65,"block":"git_index_time ctime\ngit_index_time mtime\nunsigned int dev\nunsigned int ino\nunsigned int mode\nunsigned int uid\nunsigned int gid\ngit_off_t file_size\ngit_oid id\nunsigned short flags\nunsigned short flags_extended\nconst char * path","tdef":"typedef","description":" In-memory representation of a file entry in the index.","comments":"

This is a public structure that represents a file entry in the index.\n The meaning of the fields corresponds to core Git's documentation (in\n "Documentation/technical/index-format.txt").

\n\n

The flags field consists of a number of bit fields which can be\n accessed via the first set of GIT_IDXENTRY_... bitmasks below. These\n flags are all read from and persisted to disk.

\n\n

The flags_extended field also has a number of bit fields which can be\n accessed via the later GIT_IDXENTRY_... bitmasks below. Some of\n these flags are read from and written to disk, but some are set aside\n for in-memory only reference.

\n","fields":[{"type":"git_index_time","name":"ctime","comments":""},{"type":"git_index_time","name":"mtime","comments":""},{"type":"unsigned int","name":"dev","comments":""},{"type":"unsigned int","name":"ino","comments":""},{"type":"unsigned int","name":"mode","comments":""},{"type":"unsigned int","name":"uid","comments":""},{"type":"unsigned int","name":"gid","comments":""},{"type":"git_off_t","name":"file_size","comments":""},{"type":"git_oid","name":"id","comments":""},{"type":"unsigned short","name":"flags","comments":""},{"type":"unsigned short","name":"flags_extended","comments":""},{"type":"const char *","name":"path","comments":""}],"used":{"returns":["git_index_get_byindex","git_index_get_bypath"],"needs":["git_index_add","git_index_conflict_add","git_index_conflict_get","git_index_conflict_next","git_index_entry_stage","git_merge_file_from_index"]}}],["git_index_time",{"decl":["git_time_t seconds","unsigned int nanoseconds"],"type":"struct","value":"git_index_time","file":"index.h","line":26,"lineto":30,"block":"git_time_t seconds\nunsigned int nanoseconds","tdef":"typedef","description":" Time structure used in a git index entry ","comments":"","fields":[{"type":"git_time_t","name":"seconds","comments":""},{"type":"unsigned int","name":"nanoseconds","comments":""}],"used":{"returns":[],"needs":[]}}],["git_indexcap_t",{"decl":["GIT_INDEXCAP_IGNORE_CASE","GIT_INDEXCAP_NO_FILEMODE","GIT_INDEXCAP_NO_SYMLINKS","GIT_INDEXCAP_FROM_OWNER"],"type":"enum","file":"index.h","line":130,"lineto":135,"block":"GIT_INDEXCAP_IGNORE_CASE\nGIT_INDEXCAP_NO_FILEMODE\nGIT_INDEXCAP_NO_SYMLINKS\nGIT_INDEXCAP_FROM_OWNER","tdef":"typedef","description":" Capabilities of system that affect index actions. ","comments":"","fields":[{"type":"int","name":"GIT_INDEXCAP_IGNORE_CASE","comments":"","value":1},{"type":"int","name":"GIT_INDEXCAP_NO_FILEMODE","comments":"","value":2},{"type":"int","name":"GIT_INDEXCAP_NO_SYMLINKS","comments":"","value":4},{"type":"int","name":"GIT_INDEXCAP_FROM_OWNER","comments":"","value":-1}],"used":{"returns":[],"needs":[]}}],["git_merge_analysis_t",{"decl":["GIT_MERGE_ANALYSIS_NONE","GIT_MERGE_ANALYSIS_NORMAL","GIT_MERGE_ANALYSIS_UP_TO_DATE","GIT_MERGE_ANALYSIS_FASTFORWARD","GIT_MERGE_ANALYSIS_UNBORN"],"type":"enum","file":"merge.h","line":240,"lineto":269,"block":"GIT_MERGE_ANALYSIS_NONE\nGIT_MERGE_ANALYSIS_NORMAL\nGIT_MERGE_ANALYSIS_UP_TO_DATE\nGIT_MERGE_ANALYSIS_FASTFORWARD\nGIT_MERGE_ANALYSIS_UNBORN","tdef":"typedef","description":" The results of `git_merge_analysis` indicate the merge opportunities.","comments":"","fields":[{"type":"int","name":"GIT_MERGE_ANALYSIS_NONE","comments":"

No merge is possible. (Unused.)

\n","value":0},{"type":"int","name":"GIT_MERGE_ANALYSIS_NORMAL","comments":"

A "normal" merge; both HEAD and the given merge input have diverged\n from their common ancestor. The divergent commits must be merged.

\n","value":1},{"type":"int","name":"GIT_MERGE_ANALYSIS_UP_TO_DATE","comments":"

All given merge inputs are reachable from HEAD, meaning the\n repository is up-to-date and no merge needs to be performed.

\n","value":2},{"type":"int","name":"GIT_MERGE_ANALYSIS_FASTFORWARD","comments":"

The given merge input is a fast-forward from HEAD and no merge\n needs to be performed. Instead, the client can check out the\n given merge input.

\n","value":4},{"type":"int","name":"GIT_MERGE_ANALYSIS_UNBORN","comments":"

The HEAD of the current repository is "unborn" and does not point to\n a valid commit. No merge can be performed, but the caller may wish\n to simply set HEAD to the target commit(s).

\n","value":8}],"used":{"returns":[],"needs":["git_merge_analysis"]}}],["git_merge_file_favor_t",{"decl":["GIT_MERGE_FILE_FAVOR_NORMAL","GIT_MERGE_FILE_FAVOR_OURS","GIT_MERGE_FILE_FAVOR_THEIRS","GIT_MERGE_FILE_FAVOR_UNION"],"type":"enum","file":"merge.h","line":79,"lineto":109,"block":"GIT_MERGE_FILE_FAVOR_NORMAL\nGIT_MERGE_FILE_FAVOR_OURS\nGIT_MERGE_FILE_FAVOR_THEIRS\nGIT_MERGE_FILE_FAVOR_UNION","tdef":"typedef","description":" Merge file favor options for `git_merge_options` instruct the file-level\n merging functionality how to deal with conflicting regions of the files.","comments":"","fields":[{"type":"int","name":"GIT_MERGE_FILE_FAVOR_NORMAL","comments":"

When a region of a file is changed in both branches, a conflict\n will be recorded in the index so that git_checkout can produce\n a merge file with conflict markers in the working directory.\n This is the default.

\n","value":0},{"type":"int","name":"GIT_MERGE_FILE_FAVOR_OURS","comments":"

When a region of a file is changed in both branches, the file\n created in the index will contain the "ours" side of any conflicting\n region. The index will not record a conflict.

\n","value":1},{"type":"int","name":"GIT_MERGE_FILE_FAVOR_THEIRS","comments":"

When a region of a file is changed in both branches, the file\n created in the index will contain the "theirs" side of any conflicting\n region. The index will not record a conflict.

\n","value":2},{"type":"int","name":"GIT_MERGE_FILE_FAVOR_UNION","comments":"

When a region of a file is changed in both branches, the file\n created in the index will contain each unique line from each side,\n which has the result of combining both files. The index will not\n record a conflict.

\n","value":3}],"used":{"returns":[],"needs":[]}}],["git_merge_file_input",{"decl":["unsigned int version","const char * ptr","size_t size","const char * path","unsigned int mode"],"type":"struct","value":"git_merge_file_input","file":"merge.h","line":30,"lineto":44,"block":"unsigned int version\nconst char * ptr\nsize_t size\nconst char * path\nunsigned int mode","tdef":"typedef","description":" The file inputs to `git_merge_file`. Callers should populate the\n `git_merge_file_input` structure with descriptions of the files in\n each side of the conflict for use in producing the merge file.","comments":"","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"const char *","name":"ptr","comments":" Pointer to the contents of the file. "},{"type":"size_t","name":"size","comments":" Size of the contents pointed to in `ptr`. "},{"type":"const char *","name":"path","comments":" File name of the conflicted file, or `NULL` to not merge the path. "},{"type":"unsigned int","name":"mode","comments":" File mode of the conflicted file, or `0` to not merge the mode. "}],"used":{"returns":[],"needs":["git_merge_file","git_merge_file_init_input"]}}],["git_merge_head",{"decl":"git_merge_head","type":"struct","value":"git_merge_head","file":"types.h","line":175,"lineto":175,"tdef":"typedef","description":" Merge heads, the input to merge ","comments":"","used":{"returns":[],"needs":["git_merge","git_merge_analysis","git_merge_head_free","git_merge_head_from_fetchhead","git_merge_head_from_id","git_merge_head_from_ref","git_merge_head_id"]}}],["git_merge_result",{"decl":"git_merge_result","type":"struct","value":"git_merge_result","file":"types.h","line":178,"lineto":178,"tdef":"typedef","description":" Merge result ","comments":"","used":{"returns":[],"needs":[]}}],["git_merge_tree_flag_t",{"decl":["GIT_MERGE_TREE_FIND_RENAMES"],"type":"enum","file":"merge.h","line":66,"lineto":73,"block":"GIT_MERGE_TREE_FIND_RENAMES","tdef":"typedef","description":" Flags for `git_merge_tree` options. A combination of these flags can be\n passed in via the `flags` value in the `git_merge_options`.","comments":"","fields":[{"type":"int","name":"GIT_MERGE_TREE_FIND_RENAMES","comments":"

Detect renames that occur between the common ancestor and the "ours"\n side or the common ancestor and the "theirs" side. This will enable\n the ability to merge between a modified and renamed file.

\n","value":1}],"used":{"returns":[],"needs":[]}}],["git_note",{"decl":"git_note","type":"struct","value":"git_note","file":"types.h","line":150,"lineto":150,"tdef":"typedef","description":" Representation of a git note ","comments":"","used":{"returns":[],"needs":["git_note_free","git_note_id","git_note_message","git_note_read"]}}],["git_note_iterator",{"decl":"git_note_iterator","type":"struct","value":"git_note_iterator","file":"notes.h","line":35,"lineto":35,"tdef":"typedef","description":" note iterator","comments":"","used":{"returns":[],"needs":["git_note_iterator_free","git_note_iterator_new","git_note_next"]}}],["git_object",{"decl":"git_object","type":"struct","value":"git_object","file":"types.h","line":108,"lineto":108,"tdef":"typedef","description":" Representation of a generic object in a repository ","comments":"","used":{"returns":[],"needs":["git_checkout_tree","git_object_dup","git_object_free","git_object_id","git_object_lookup","git_object_lookup_bypath","git_object_lookup_prefix","git_object_owner","git_object_peel","git_object_short_id","git_object_type","git_reference_peel","git_revparse_ext","git_revparse_single","git_tag_annotation_create","git_tag_create","git_tag_create_lightweight","git_tag_peel","git_tag_target","git_tree_entry_to_object"]}}],["git_odb",{"decl":"git_odb","type":"struct","value":"git_odb","file":"types.h","line":81,"lineto":81,"tdef":"typedef","description":" An open object database handle. ","comments":"","used":{"returns":[],"needs":["git_indexer_new","git_odb_add_alternate","git_odb_add_backend","git_odb_add_disk_alternate","git_odb_exists","git_odb_exists_prefix","git_odb_foreach","git_odb_free","git_odb_get_backend","git_odb_new","git_odb_num_backends","git_odb_open","git_odb_open_rstream","git_odb_open_wstream","git_odb_read","git_odb_read_header","git_odb_read_prefix","git_odb_refresh","git_odb_write","git_odb_write_pack","git_repository_odb","git_repository_wrap_odb"]}}],["git_odb_backend",{"decl":"git_odb_backend","type":"struct","value":"git_odb_backend","file":"types.h","line":84,"lineto":84,"block":"unsigned int version\ngit_odb * odb\nint (*)(void **, size_t *, git_otype *, git_odb_backend *, const git_oid *) read\nint (*)(git_oid *, void **, size_t *, git_otype *, git_odb_backend *, const git_oid *, size_t) read_prefix\nint (*)(size_t *, git_otype *, git_odb_backend *, const git_oid *) read_header\nint (*)(git_odb_backend *, const git_oid *, const void *, size_t, git_otype) write\nint (*)(git_odb_stream **, git_odb_backend *, size_t, git_otype) writestream\nint (*)(git_odb_stream **, git_odb_backend *, const git_oid *) readstream\nint (*)(git_odb_backend *, const git_oid *) exists\nint (*)(git_oid *, git_odb_backend *, const git_oid *, size_t) exists_prefix\nint (*)(git_odb_backend *) refresh\nint (*)(git_odb_backend *, git_odb_foreach_cb, void *) foreach\nint (*)(git_odb_writepack **, git_odb_backend *, git_odb *, git_transfer_progress_cb, void *) writepack\nvoid (*)(git_odb_backend *) free","tdef":"typedef","description":" A custom backend in an ODB ","comments":"","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"git_odb *","name":"odb","comments":""},{"type":"int (*)(void **, size_t *, git_otype *, git_odb_backend *, const git_oid *)","name":"read","comments":""},{"type":"int (*)(git_oid *, void **, size_t *, git_otype *, git_odb_backend *, const git_oid *, size_t)","name":"read_prefix","comments":""},{"type":"int (*)(size_t *, git_otype *, git_odb_backend *, const git_oid *)","name":"read_header","comments":""},{"type":"int (*)(git_odb_backend *, const git_oid *, const void *, size_t, git_otype)","name":"write","comments":" Write an object into the backend. The id of the object has\n already been calculated and is passed in."},{"type":"int (*)(git_odb_stream **, git_odb_backend *, size_t, git_otype)","name":"writestream","comments":""},{"type":"int (*)(git_odb_stream **, git_odb_backend *, const git_oid *)","name":"readstream","comments":""},{"type":"int (*)(git_odb_backend *, const git_oid *)","name":"exists","comments":""},{"type":"int (*)(git_oid *, git_odb_backend *, const git_oid *, size_t)","name":"exists_prefix","comments":""},{"type":"int (*)(git_odb_backend *)","name":"refresh","comments":" If the backend implements a refreshing mechanism, it should be exposed\n through this endpoint. Each call to `git_odb_refresh()` will invoke it.\n\n However, the backend implementation should try to stay up-to-date as much\n as possible by itself as libgit2 will not automatically invoke\n `git_odb_refresh()`. For instance, a potential strategy for the backend\n implementation to achieve this could be to internally invoke this\n endpoint on failed lookups (ie. `exists()`, `read()`, `read_header()`)."},{"type":"int (*)(git_odb_backend *, git_odb_foreach_cb, void *)","name":"foreach","comments":""},{"type":"int (*)(git_odb_writepack **, git_odb_backend *, git_odb *, git_transfer_progress_cb, void *)","name":"writepack","comments":""},{"type":"void (*)(git_odb_backend *)","name":"free","comments":""}],"used":{"returns":[],"needs":["git_mempack_new","git_mempack_reset","git_odb_add_alternate","git_odb_add_backend","git_odb_backend_loose","git_odb_backend_one_pack","git_odb_backend_pack","git_odb_get_backend","git_odb_init_backend"]}}],["git_odb_object",{"decl":"git_odb_object","type":"struct","value":"git_odb_object","file":"types.h","line":87,"lineto":87,"tdef":"typedef","description":" An object read from the ODB ","comments":"","used":{"returns":[],"needs":["git_odb_object_data","git_odb_object_dup","git_odb_object_free","git_odb_object_id","git_odb_object_size","git_odb_object_type","git_odb_read","git_odb_read_prefix"]}}],["git_odb_stream",{"decl":"git_odb_stream","type":"struct","value":"git_odb_stream","file":"types.h","line":90,"lineto":90,"block":"git_odb_backend * backend\nunsigned int mode\nvoid * hash_ctx\nsize_t declared_size\nsize_t received_bytes\nint (*)(git_odb_stream *, char *, size_t) read\nint (*)(git_odb_stream *, const char *, size_t) write\nint (*)(git_odb_stream *, const int *) finalize_write\nvoid (*)(git_odb_stream *) free","tdef":"typedef","description":" A stream to read/write from the ODB ","comments":"","fields":[{"type":"git_odb_backend *","name":"backend","comments":""},{"type":"unsigned int","name":"mode","comments":""},{"type":"void *","name":"hash_ctx","comments":""},{"type":"size_t","name":"declared_size","comments":""},{"type":"size_t","name":"received_bytes","comments":""},{"type":"int (*)(git_odb_stream *, char *, size_t)","name":"read","comments":" Write at most `len` bytes into `buffer` and advance the stream."},{"type":"int (*)(git_odb_stream *, const char *, size_t)","name":"write","comments":" Write `len` bytes from `buffer` into the stream."},{"type":"int (*)(git_odb_stream *, const int *)","name":"finalize_write","comments":" Store the contents of the stream as an object with the id\n specified in `oid`.\n\n This method might not be invoked if:\n - an error occurs earlier with the `write` callback,\n - the object referred to by `oid` already exists in any backend, or\n - the final number of received bytes differs from the size declared\n with `git_odb_open_wstream()`"},{"type":"void (*)(git_odb_stream *)","name":"free","comments":" Free the stream's memory.\n\n This method might be called without a call to `finalize_write` if\n an error occurs or if the object is already present in the ODB."}],"used":{"returns":[],"needs":["git_odb_open_rstream","git_odb_open_wstream","git_odb_stream_finalize_write","git_odb_stream_free","git_odb_stream_read","git_odb_stream_write"]}}],["git_odb_stream_t",{"decl":["GIT_STREAM_RDONLY","GIT_STREAM_WRONLY","GIT_STREAM_RW"],"type":"enum","file":"odb_backend.h","line":70,"lineto":74,"block":"GIT_STREAM_RDONLY\nGIT_STREAM_WRONLY\nGIT_STREAM_RW","tdef":"typedef","description":" Streaming mode ","comments":"","fields":[{"type":"int","name":"GIT_STREAM_RDONLY","comments":"","value":2},{"type":"int","name":"GIT_STREAM_WRONLY","comments":"","value":4},{"type":"int","name":"GIT_STREAM_RW","comments":"","value":6}],"used":{"returns":[],"needs":[]}}],["git_odb_writepack",{"decl":"git_odb_writepack","type":"struct","value":"git_odb_writepack","file":"types.h","line":93,"lineto":93,"block":"git_odb_backend * backend\nint (*)(git_odb_writepack *, const void *, size_t, git_transfer_progress *) append\nint (*)(git_odb_writepack *, git_transfer_progress *) commit\nvoid (*)(git_odb_writepack *) free","tdef":"typedef","description":" A stream to write a packfile to the ODB ","comments":"","fields":[{"type":"git_odb_backend *","name":"backend","comments":""},{"type":"int (*)(git_odb_writepack *, const void *, size_t, git_transfer_progress *)","name":"append","comments":""},{"type":"int (*)(git_odb_writepack *, git_transfer_progress *)","name":"commit","comments":""},{"type":"void (*)(git_odb_writepack *)","name":"free","comments":""}],"used":{"returns":[],"needs":["git_odb_write_pack"]}}],["git_oid",{"decl":["unsigned char [20] id"],"type":"struct","value":"git_oid","file":"oid.h","line":33,"lineto":36,"block":"unsigned char [20] id","tdef":"typedef","description":" Unique identity of any object (commit, tree, blob, tag). ","comments":"","fields":[{"type":"unsigned char [20]","name":"id","comments":" raw binary formatted id "}],"used":{"returns":["git_blob_id","git_commit_id","git_commit_parent_id","git_commit_tree_id","git_filter_source_id","git_indexer_hash","git_merge_head_id","git_note_id","git_object_id","git_odb_object_id","git_packbuilder_hash","git_reference_target","git_reference_target_peel","git_reflog_entry_id_new","git_reflog_entry_id_old","git_submodule_head_id","git_submodule_index_id","git_submodule_wd_id","git_tag_id","git_tag_target_id","git_tree_entry_id","git_tree_id"],"needs":["git_blob_create_frombuffer","git_blob_create_fromchunks","git_blob_create_fromdisk","git_blob_create_fromworkdir","git_blob_lookup","git_blob_lookup_prefix","git_commit_amend","git_commit_create","git_commit_create_from_callback","git_commit_create_from_ids","git_commit_create_v","git_commit_lookup","git_commit_lookup_prefix","git_graph_ahead_behind","git_graph_descendant_of","git_index_write_tree","git_index_write_tree_to","git_merge_base","git_merge_base_many","git_merge_base_octopus","git_merge_head_from_fetchhead","git_merge_head_from_id","git_note_create","git_note_next","git_note_read","git_note_remove","git_object_lookup","git_object_lookup_prefix","git_odb_exists","git_odb_exists_prefix","git_odb_hash","git_odb_hashfile","git_odb_open_rstream","git_odb_read","git_odb_read_header","git_odb_read_prefix","git_odb_stream_finalize_write","git_odb_write","git_oid_allocfmt","git_oid_cmp","git_oid_cpy","git_oid_equal","git_oid_fmt","git_oid_fromraw","git_oid_fromstr","git_oid_fromstrn","git_oid_fromstrp","git_oid_iszero","git_oid_ncmp","git_oid_nfmt","git_oid_pathfmt","git_oid_strcmp","git_oid_streq","git_oid_tostr","git_packbuilder_insert","git_packbuilder_insert_commit","git_packbuilder_insert_tree","git_reference__alloc","git_reference_create","git_reference_create_matching","git_reference_name_to_id","git_reference_set_target","git_reflog_append","git_repository_hashfile","git_repository_set_head_detached","git_revwalk_hide","git_revwalk_next","git_revwalk_push","git_tag_annotation_create","git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_lookup","git_tag_lookup_prefix","git_tree_entry_byid","git_tree_lookup","git_tree_lookup_prefix","git_treebuilder_insert","git_treebuilder_write"]}}],["git_oid_shorten",{"decl":"git_oid_shorten","type":"struct","value":"git_oid_shorten","file":"oid.h","line":212,"lineto":212,"tdef":"typedef","description":" OID Shortener object","comments":"","used":{"returns":["git_oid_shorten_new"],"needs":["git_oid_shorten_add","git_oid_shorten_free"]}}],["git_otype",{"decl":["GIT_OBJ_ANY","GIT_OBJ_BAD","GIT_OBJ__EXT1","GIT_OBJ_COMMIT","GIT_OBJ_TREE","GIT_OBJ_BLOB","GIT_OBJ_TAG","GIT_OBJ__EXT2","GIT_OBJ_OFS_DELTA","GIT_OBJ_REF_DELTA"],"type":"enum","file":"types.h","line":67,"lineto":78,"block":"GIT_OBJ_ANY\nGIT_OBJ_BAD\nGIT_OBJ__EXT1\nGIT_OBJ_COMMIT\nGIT_OBJ_TREE\nGIT_OBJ_BLOB\nGIT_OBJ_TAG\nGIT_OBJ__EXT2\nGIT_OBJ_OFS_DELTA\nGIT_OBJ_REF_DELTA","tdef":"typedef","description":" Basic type (loose or packed) of any Git object. ","comments":"","fields":[{"type":"int","name":"GIT_OBJ_ANY","comments":"

Object can be any of the following

\n","value":-2},{"type":"int","name":"GIT_OBJ_BAD","comments":"

Object is invalid.

\n","value":-1},{"type":"int","name":"GIT_OBJ__EXT1","comments":"

Reserved for future use.

\n","value":0},{"type":"int","name":"GIT_OBJ_COMMIT","comments":"

A commit object.

\n","value":1},{"type":"int","name":"GIT_OBJ_TREE","comments":"

A tree (directory listing) object.

\n","value":2},{"type":"int","name":"GIT_OBJ_BLOB","comments":"

A file revision object.

\n","value":3},{"type":"int","name":"GIT_OBJ_TAG","comments":"

An annotated tag object.

\n","value":4},{"type":"int","name":"GIT_OBJ__EXT2","comments":"

Reserved for future use.

\n","value":5},{"type":"int","name":"GIT_OBJ_OFS_DELTA","comments":"

A delta, base is given by an offset.

\n","value":6},{"type":"int","name":"GIT_OBJ_REF_DELTA","comments":"

A delta, base is given by object id.

\n","value":7}],"used":{"returns":[],"needs":["git_object__size","git_object_lookup","git_object_lookup_bypath","git_object_lookup_prefix","git_object_peel","git_object_type2string","git_object_typeisloose","git_odb_hash","git_odb_hashfile","git_odb_open_wstream","git_odb_read_header","git_odb_write","git_reference_peel","git_repository_hashfile"]}}],["git_packbuilder",{"decl":"git_packbuilder","type":"struct","value":"git_packbuilder","file":"types.h","line":153,"lineto":153,"tdef":"typedef","description":" Representation of a git packbuilder ","comments":"","used":{"returns":[],"needs":["git_packbuilder_foreach","git_packbuilder_free","git_packbuilder_hash","git_packbuilder_insert","git_packbuilder_insert_commit","git_packbuilder_insert_tree","git_packbuilder_new","git_packbuilder_object_count","git_packbuilder_set_callbacks","git_packbuilder_set_threads","git_packbuilder_write","git_packbuilder_written"]}}],["git_packbuilder_stage_t",{"decl":["GIT_PACKBUILDER_ADDING_OBJECTS","GIT_PACKBUILDER_DELTAFICATION"],"type":"enum","file":"pack.h","line":51,"lineto":54,"block":"GIT_PACKBUILDER_ADDING_OBJECTS\nGIT_PACKBUILDER_DELTAFICATION","tdef":"typedef","description":" Stages that are reported by the packbuilder progress callback.","comments":"","fields":[{"type":"int","name":"GIT_PACKBUILDER_ADDING_OBJECTS","comments":"","value":0},{"type":"int","name":"GIT_PACKBUILDER_DELTAFICATION","comments":"","value":1}],"used":{"returns":[],"needs":[]}}],["git_patch",{"decl":"git_patch","type":"struct","value":"git_patch","file":"patch.h","line":29,"lineto":29,"tdef":"typedef","description":" The diff patch is used to store all the text diffs for a delta.","comments":"

You can easily loop over the content of patches and get information about\n them.

\n","used":{"returns":[],"needs":["git_patch_free","git_patch_from_blob_and_buffer","git_patch_from_blobs","git_patch_from_buffers","git_patch_from_diff","git_patch_get_delta","git_patch_get_hunk","git_patch_get_line_in_hunk","git_patch_line_stats","git_patch_num_hunks","git_patch_num_lines_in_hunk","git_patch_print","git_patch_size","git_patch_to_buf"]}}],["git_pathspec",{"decl":"git_pathspec","type":"struct","value":"git_pathspec","file":"pathspec.h","line":20,"lineto":20,"tdef":"typedef","description":" Compiled pathspec","comments":"","used":{"returns":[],"needs":["git_pathspec_free","git_pathspec_match_diff","git_pathspec_match_index","git_pathspec_match_tree","git_pathspec_match_workdir","git_pathspec_matches_path","git_pathspec_new"]}}],["git_pathspec_flag_t",{"decl":["GIT_PATHSPEC_DEFAULT","GIT_PATHSPEC_IGNORE_CASE","GIT_PATHSPEC_USE_CASE","GIT_PATHSPEC_NO_GLOB","GIT_PATHSPEC_NO_MATCH_ERROR","GIT_PATHSPEC_FIND_FAILURES","GIT_PATHSPEC_FAILURES_ONLY"],"type":"enum","file":"pathspec.h","line":48,"lineto":56,"block":"GIT_PATHSPEC_DEFAULT\nGIT_PATHSPEC_IGNORE_CASE\nGIT_PATHSPEC_USE_CASE\nGIT_PATHSPEC_NO_GLOB\nGIT_PATHSPEC_NO_MATCH_ERROR\nGIT_PATHSPEC_FIND_FAILURES\nGIT_PATHSPEC_FAILURES_ONLY","tdef":"typedef","description":" Options controlling how pathspec match should be executed","comments":"
    \n
  • GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise\nmatch will use native case sensitivity of platform filesystem
  • \n
  • GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise\nmatch will use native case sensitivity of platform filesystem
  • \n
  • GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple\nstring comparison for matching
  • \n
  • GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error\ncode GIT_ENOTFOUND if no matches are found; otherwise no matches is\nstill success (return 0) but git_pathspec_match_list_entrycount\nwill indicate 0 matches.
  • \n
  • GIT_PATHSPEC_FIND_FAILURES means that the git_pathspec_match_list\nshould track which patterns matched which files so that at the end of\nthe match we can identify patterns that did not match any files.
  • \n
  • GIT_PATHSPEC_FAILURES_ONLY means that the git_pathspec_match_list\ndoes not need to keep the actual matching filenames. Use this to\njust test if there were any matches at all or in combination with\nGIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
  • \n
\n","fields":[{"type":"int","name":"GIT_PATHSPEC_DEFAULT","comments":"","value":0},{"type":"int","name":"GIT_PATHSPEC_IGNORE_CASE","comments":"","value":1},{"type":"int","name":"GIT_PATHSPEC_USE_CASE","comments":"","value":2},{"type":"int","name":"GIT_PATHSPEC_NO_GLOB","comments":"","value":4},{"type":"int","name":"GIT_PATHSPEC_NO_MATCH_ERROR","comments":"","value":8},{"type":"int","name":"GIT_PATHSPEC_FIND_FAILURES","comments":"","value":16},{"type":"int","name":"GIT_PATHSPEC_FAILURES_ONLY","comments":"","value":32}],"used":{"returns":[],"needs":[]}}],["git_pathspec_match_list",{"decl":"git_pathspec_match_list","type":"struct","value":"git_pathspec_match_list","file":"pathspec.h","line":25,"lineto":25,"tdef":"typedef","description":" List of filenames matching a pathspec","comments":"","used":{"returns":[],"needs":["git_pathspec_match_diff","git_pathspec_match_index","git_pathspec_match_list_diff_entry","git_pathspec_match_list_entry","git_pathspec_match_list_entrycount","git_pathspec_match_list_failed_entry","git_pathspec_match_list_failed_entrycount","git_pathspec_match_list_free","git_pathspec_match_tree","git_pathspec_match_workdir"]}}],["git_push_options",{"decl":["unsigned int version","unsigned int pb_parallelism"],"type":"struct","value":"git_push_options","file":"push.h","line":25,"lineto":37,"block":"unsigned int version\nunsigned int pb_parallelism","tdef":"typedef","description":" Controls the behavior of a git_push object.","comments":"","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"unsigned int","name":"pb_parallelism","comments":" If the transport being used to push to the remote requires the creation\n of a pack file, this controls the number of worker threads used by\n the packbuilder when creating that pack file to be sent to the remote.\n\n If set to 0, the packbuilder will auto-detect the number of threads\n to create. The default value is 1."}],"used":{"returns":[],"needs":["git_push_init_options","git_push_set_options"]}}],["git_ref_t",{"decl":["GIT_REF_INVALID","GIT_REF_OID","GIT_REF_SYMBOLIC","GIT_REF_LISTALL"],"type":"enum","file":"types.h","line":185,"lineto":190,"block":"GIT_REF_INVALID\nGIT_REF_OID\nGIT_REF_SYMBOLIC\nGIT_REF_LISTALL","tdef":"typedef","description":" Basic type of any Git reference. ","comments":"","fields":[{"type":"int","name":"GIT_REF_INVALID","comments":"

Invalid reference

\n","value":0},{"type":"int","name":"GIT_REF_OID","comments":"

A reference which points at an object id

\n","value":1},{"type":"int","name":"GIT_REF_SYMBOLIC","comments":"

A reference which points at another reference

\n","value":2},{"type":"int","name":"GIT_REF_LISTALL","comments":"","value":3}],"used":{"returns":[],"needs":[]}}],["git_refdb",{"decl":"git_refdb","type":"struct","value":"git_refdb","file":"types.h","line":96,"lineto":96,"tdef":"typedef","description":" An open refs database handle. ","comments":"","used":{"returns":[],"needs":["git_refdb_compress","git_refdb_free","git_refdb_new","git_refdb_open","git_refdb_set_backend","git_repository_refdb"]}}],["git_refdb_backend",{"decl":"git_refdb_backend","type":"struct","value":"git_refdb_backend","file":"types.h","line":99,"lineto":99,"block":"unsigned int version\nint (*)(int *, git_refdb_backend *, const char *) exists\nint (*)(git_reference **, git_refdb_backend *, const char *) lookup\nint (*)(git_reference_iterator **, struct git_refdb_backend *, const char *) iterator\nint (*)(git_refdb_backend *, const git_reference *, int, const git_signature *, const char *, const git_oid *, const char *) write\nint (*)(git_reference **, git_refdb_backend *, const char *, const char *, int, const git_signature *, const char *) rename\nint (*)(git_refdb_backend *, const char *, const git_oid *, const char *) del\nint (*)(git_refdb_backend *) compress\nint (*)(git_refdb_backend *, const char *) has_log\nint (*)(git_refdb_backend *, const char *) ensure_log\nvoid (*)(git_refdb_backend *) free\nint (*)(git_reflog **, git_refdb_backend *, const char *) reflog_read\nint (*)(git_refdb_backend *, git_reflog *) reflog_write\nint (*)(git_refdb_backend *, const char *, const char *) reflog_rename\nint (*)(git_refdb_backend *, const char *) reflog_delete","tdef":"typedef","description":" A custom backend for refs ","comments":"","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"int (*)(int *, git_refdb_backend *, const char *)","name":"exists","comments":" Queries the refdb backend to determine if the given ref_name\n exists. A refdb implementation must provide this function."},{"type":"int (*)(git_reference **, git_refdb_backend *, const char *)","name":"lookup","comments":" Queries the refdb backend for a given reference. A refdb\n implementation must provide this function."},{"type":"int (*)(git_reference_iterator **, struct git_refdb_backend *, const char *)","name":"iterator","comments":" Allocate an iterator object for the backend.\n\n A refdb implementation must provide this function."},{"type":"int (*)(git_refdb_backend *, const git_reference *, int, const git_signature *, const char *, const git_oid *, const char *)","name":"write","comments":""},{"type":"int (*)(git_reference **, git_refdb_backend *, const char *, const char *, int, const git_signature *, const char *)","name":"rename","comments":""},{"type":"int (*)(git_refdb_backend *, const char *, const git_oid *, const char *)","name":"del","comments":" Deletes the given reference from the refdb. A refdb implementation\n must provide this function."},{"type":"int (*)(git_refdb_backend *)","name":"compress","comments":" Suggests that the given refdb compress or optimize its references.\n This mechanism is implementation specific. (For on-disk reference\n databases, this may pack all loose references.) A refdb\n implementation may provide this function; if it is not provided,\n nothing will be done."},{"type":"int (*)(git_refdb_backend *, const char *)","name":"has_log","comments":" Query whether a particular reference has a log (may be empty)"},{"type":"int (*)(git_refdb_backend *, const char *)","name":"ensure_log","comments":" Make sure a particular reference will have a reflog which\n will be appended to on writes."},{"type":"void (*)(git_refdb_backend *)","name":"free","comments":" Frees any resources held by the refdb. A refdb implementation may\n provide this function; if it is not provided, nothing will be done."},{"type":"int (*)(git_reflog **, git_refdb_backend *, const char *)","name":"reflog_read","comments":" Read the reflog for the given reference name."},{"type":"int (*)(git_refdb_backend *, git_reflog *)","name":"reflog_write","comments":" Write a reflog to disk."},{"type":"int (*)(git_refdb_backend *, const char *, const char *)","name":"reflog_rename","comments":" Rename a reflog"},{"type":"int (*)(git_refdb_backend *, const char *)","name":"reflog_delete","comments":" Remove a reflog."}],"used":{"returns":[],"needs":["git_refdb_backend_fs","git_refdb_init_backend","git_refdb_set_backend"]}}],["git_reference",{"decl":"git_reference","type":"struct","value":"git_reference","file":"types.h","line":169,"lineto":169,"tdef":"typedef","description":" In-memory representation of a reference. ","comments":"","used":{"returns":["git_reference__alloc","git_reference__alloc_symbolic"],"needs":["git_branch_create","git_branch_delete","git_branch_is_head","git_branch_lookup","git_branch_move","git_branch_name","git_branch_next","git_branch_set_upstream","git_branch_upstream","git_merge_head_from_ref","git_reference_cmp","git_reference_create","git_reference_create_matching","git_reference_delete","git_reference_dwim","git_reference_free","git_reference_is_branch","git_reference_is_note","git_reference_is_remote","git_reference_is_tag","git_reference_lookup","git_reference_name","git_reference_next","git_reference_owner","git_reference_peel","git_reference_rename","git_reference_resolve","git_reference_set_target","git_reference_shorthand","git_reference_symbolic_create","git_reference_symbolic_create_matching","git_reference_symbolic_set_target","git_reference_symbolic_target","git_reference_target","git_reference_target_peel","git_reference_type","git_repository_head","git_revparse_ext"]}}],["git_reference_iterator",{"decl":"git_reference_iterator","type":"struct","value":"git_reference_iterator","file":"types.h","line":172,"lineto":172,"block":"git_refdb * db\nint (*)(git_reference **, git_reference_iterator *) next\nint (*)(const char **, git_reference_iterator *) next_name\nvoid (*)(git_reference_iterator *) free","tdef":"typedef","description":" Iterator for references ","comments":"","fields":[{"type":"git_refdb *","name":"db","comments":""},{"type":"int (*)(git_reference **, git_reference_iterator *)","name":"next","comments":" Return the current reference and advance the iterator."},{"type":"int (*)(const char **, git_reference_iterator *)","name":"next_name","comments":" Return the name of the current reference and advance the iterator"},{"type":"void (*)(git_reference_iterator *)","name":"free","comments":" Free the iterator"}],"used":{"returns":[],"needs":["git_reference_iterator_free","git_reference_iterator_glob_new","git_reference_iterator_new","git_reference_next","git_reference_next_name"]}}],["git_reflog",{"decl":"git_reflog","type":"struct","value":"git_reflog","file":"types.h","line":147,"lineto":147,"tdef":"typedef","description":" Representation of a reference log ","comments":"","used":{"returns":[],"needs":["git_reflog_append","git_reflog_drop","git_reflog_entry_byindex","git_reflog_entrycount","git_reflog_free","git_reflog_read","git_reflog_write"]}}],["git_reflog_entry",{"decl":"git_reflog_entry","type":"struct","value":"git_reflog_entry","file":"types.h","line":144,"lineto":144,"tdef":"typedef","description":" Representation of a reference log entry ","comments":"","used":{"returns":["git_reflog_entry_byindex"],"needs":["git_reflog_entry_committer","git_reflog_entry_id_new","git_reflog_entry_id_old","git_reflog_entry_message"]}}],["git_remote_callbacks",{"decl":["unsigned int version","git_transport_message_cb sideband_progress","int (*)(git_remote_completion_type, void *) completion","git_cred_acquire_cb credentials","git_transfer_progress_cb transfer_progress","int (*)(const char *, const git_oid *, const git_oid *, void *) update_tips","void * payload"],"type":"struct","value":"git_remote_callbacks","file":"remote.h","line":453,"lineto":495,"block":"unsigned int version\ngit_transport_message_cb sideband_progress\nint (*)(git_remote_completion_type, void *) completion\ngit_cred_acquire_cb credentials\ngit_transfer_progress_cb transfer_progress\nint (*)(const char *, const git_oid *, const git_oid *, void *) update_tips\nvoid * payload","tdef":null,"description":" The callback settings structure","comments":"

Set the callbacks to be called by the remote when informing the user\n about the progress of the network operations.

\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"git_transport_message_cb","name":"sideband_progress","comments":" Textual progress from the remote. Text send over the\n progress side-band will be passed to this function (this is\n the 'counting objects' output."},{"type":"int (*)(git_remote_completion_type, void *)","name":"completion","comments":" Completion is called when different parts of the download\n process are done (currently unused)."},{"type":"git_cred_acquire_cb","name":"credentials","comments":" This will be called if the remote host requires\n authentication in order to connect to it.\n\n Returning GIT_PASSTHROUGH will make libgit2 behave as\n though this field isn't set."},{"type":"git_transfer_progress_cb","name":"transfer_progress","comments":" During the download of new data, this will be regularly\n called with the current count of progress done by the\n indexer."},{"type":"int (*)(const char *, const git_oid *, const git_oid *, void *)","name":"update_tips","comments":" Each time a reference is updated locally, this function\n will be called with information about it."},{"type":"void *","name":"payload","comments":" This will be passed to each of the callbacks in this struct\n as the last parameter."}],"used":{"returns":["git_remote_get_callbacks"],"needs":["git_remote_init_callbacks","git_remote_set_callbacks"]}}],["git_remote_completion_type",{"decl":["GIT_REMOTE_COMPLETION_DOWNLOAD","GIT_REMOTE_COMPLETION_INDEXING","GIT_REMOTE_COMPLETION_ERROR"],"type":"enum","file":"remote.h","line":441,"lineto":445,"block":"GIT_REMOTE_COMPLETION_DOWNLOAD\nGIT_REMOTE_COMPLETION_INDEXING\nGIT_REMOTE_COMPLETION_ERROR\nGIT_REMOTE_COMPLETION_DOWNLOAD\nGIT_REMOTE_COMPLETION_INDEXING\nGIT_REMOTE_COMPLETION_ERROR","tdef":"typedef","description":" Argument to the completion callback which tells it which operation\n finished.","comments":"","fields":[{"type":"int","name":"GIT_REMOTE_COMPLETION_DOWNLOAD","comments":"","value":0},{"type":"int","name":"GIT_REMOTE_COMPLETION_INDEXING","comments":"","value":1},{"type":"int","name":"GIT_REMOTE_COMPLETION_ERROR","comments":"","value":2}],"used":{"returns":[],"needs":[]}}],["git_remote_head",{"decl":["int local","git_oid oid","git_oid loid","char * name","char * symref_target"],"type":"struct","value":"git_remote_head","file":"net.h","line":39,"lineto":49,"block":"int local\ngit_oid oid\ngit_oid loid\nchar * name\nchar * symref_target","tdef":null,"description":" Remote head description, given out on `ls` calls.","comments":"","fields":[{"type":"int","name":"local","comments":""},{"type":"git_oid","name":"oid","comments":""},{"type":"git_oid","name":"loid","comments":""},{"type":"char *","name":"name","comments":""},{"type":"char *","name":"symref_target","comments":" If the server send a symref mapping for this ref, this will\n point to the target."}],"used":{"returns":[],"needs":["git_remote_ls"]}}],["git_repository",{"decl":"git_repository","type":"struct","value":"git_repository","file":"types.h","line":105,"lineto":105,"tdef":"typedef","description":" Representation of an existing git repository,\n including all its object contents","comments":"","used":{"returns":["git_blob_owner","git_commit_owner","git_filter_source_repo","git_index_owner","git_object_owner","git_reference_owner","git_remote_owner","git_revwalk_repository","git_submodule_owner","git_tag_owner","git_tree_owner"],"needs":["git_attr_add_macro","git_attr_cache_flush","git_attr_foreach","git_attr_get","git_attr_get_many","git_blame_file","git_blob_create_frombuffer","git_blob_create_fromchunks","git_blob_create_fromdisk","git_blob_create_fromworkdir","git_blob_lookup","git_blob_lookup_prefix","git_branch_create","git_branch_iterator_new","git_branch_lookup","git_checkout_head","git_checkout_index","git_checkout_tree","git_cherry_pick","git_cherry_pick_commit","git_clone","git_clone_into","git_clone_local_into","git_commit_create","git_commit_create_from_callback","git_commit_create_from_ids","git_commit_create_v","git_commit_lookup","git_commit_lookup_prefix","git_diff_commit_as_email","git_diff_index_to_workdir","git_diff_tree_to_index","git_diff_tree_to_tree","git_diff_tree_to_workdir","git_diff_tree_to_workdir_with_index","git_filter_list_apply_to_file","git_filter_list_load","git_filter_list_new","git_graph_ahead_behind","git_graph_descendant_of","git_ignore_add_rule","git_ignore_clear_internal_rules","git_ignore_path_is_ignored","git_index_write_tree_to","git_merge","git_merge_analysis","git_merge_base","git_merge_base_many","git_merge_base_octopus","git_merge_commits","git_merge_file_from_index","git_merge_head_from_fetchhead","git_merge_head_from_id","git_merge_head_from_ref","git_merge_trees","git_note_create","git_note_default_ref","git_note_foreach","git_note_iterator_new","git_note_read","git_note_remove","git_object_lookup","git_object_lookup_prefix","git_packbuilder_new","git_pathspec_match_workdir","git_refdb_backend_fs","git_refdb_new","git_refdb_open","git_reference_create","git_reference_create_matching","git_reference_dwim","git_reference_ensure_log","git_reference_foreach","git_reference_foreach_glob","git_reference_foreach_name","git_reference_has_log","git_reference_iterator_glob_new","git_reference_iterator_new","git_reference_list","git_reference_lookup","git_reference_name_to_id","git_reference_remove","git_reference_symbolic_create","git_reference_symbolic_create_matching","git_reflog_delete","git_reflog_read","git_reflog_rename","git_remote_create","git_remote_create_anonymous","git_remote_create_with_fetchspec","git_remote_list","git_remote_load","git_repository_config","git_repository_config_snapshot","git_repository_detach_head","git_repository_fetchhead_foreach","git_repository_free","git_repository_get_namespace","git_repository_hashfile","git_repository_head","git_repository_head_detached","git_repository_head_unborn","git_repository_index","git_repository_init","git_repository_init_ext","git_repository_is_bare","git_repository_is_empty","git_repository_is_shallow","git_repository_mergehead_foreach","git_repository_message","git_repository_message_remove","git_repository_odb","git_repository_open","git_repository_open_bare","git_repository_open_ext","git_repository_path","git_repository_refdb","git_repository_set_head","git_repository_set_head_detached","git_repository_set_namespace","git_repository_set_workdir","git_repository_state","git_repository_state_cleanup","git_repository_workdir","git_repository_wrap_odb","git_revert","git_revert_commit","git_revparse","git_revparse_ext","git_revparse_single","git_revwalk_new","git_signature_default","git_stash_drop","git_stash_foreach","git_status_file","git_status_foreach","git_status_foreach_ext","git_status_list_new","git_status_should_ignore","git_submodule_add_setup","git_submodule_foreach","git_submodule_lookup","git_submodule_open","git_submodule_reload_all","git_tag_annotation_create","git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_delete","git_tag_foreach","git_tag_list","git_tag_list_match","git_tag_lookup","git_tag_lookup_prefix","git_tree_entry_to_object","git_tree_lookup","git_tree_lookup_prefix","git_treebuilder_write"]}}],["git_repository_init_flag_t",{"decl":["GIT_REPOSITORY_INIT_BARE","GIT_REPOSITORY_INIT_NO_REINIT","GIT_REPOSITORY_INIT_NO_DOTGIT_DIR","GIT_REPOSITORY_INIT_MKDIR","GIT_REPOSITORY_INIT_MKPATH","GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE"],"type":"enum","file":"repository.h","line":200,"lineto":207,"block":"GIT_REPOSITORY_INIT_BARE\nGIT_REPOSITORY_INIT_NO_REINIT\nGIT_REPOSITORY_INIT_NO_DOTGIT_DIR\nGIT_REPOSITORY_INIT_MKDIR\nGIT_REPOSITORY_INIT_MKPATH\nGIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE","tdef":"typedef","description":" Option flags for `git_repository_init_ext`.","comments":"

These flags configure extra behaviors to git_repository_init_ext.\n In every case, the default behavior is the zero value (i.e. flag is\n not set). Just OR the flag values together for the flags parameter\n when initializing a new repo. Details of individual values are:

\n\n
    \n
  • BARE - Create a bare repository with no working directory.
  • \n
  • NO_REINIT - Return an GIT_EEXISTS error if the repo_path appears to\n already be an git repository.
  • \n
  • NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo\n path for non-bare repos (if it is not already there), but\n passing this flag prevents that behavior.
  • \n
  • MKDIR - Make the repo_path (and workdir_path) as needed. Init is\n always willing to create the ".git" directory even without this\n flag. This flag tells init to create the trailing component of\n the repo and workdir paths as needed.
  • \n
  • MKPATH - Recursively make all components of the repo and workdir\n paths as necessary.
  • \n
  • EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to\n initialize a new repo. This flags enables external templates,\n looking the "template_path" from the options if set, or the\n init.templatedir global config if not, or falling back on\n "/usr/share/git-core/templates" if it exists.
  • \n
\n","fields":[{"type":"int","name":"GIT_REPOSITORY_INIT_BARE","comments":"","value":1},{"type":"int","name":"GIT_REPOSITORY_INIT_NO_REINIT","comments":"","value":2},{"type":"int","name":"GIT_REPOSITORY_INIT_NO_DOTGIT_DIR","comments":"","value":4},{"type":"int","name":"GIT_REPOSITORY_INIT_MKDIR","comments":"","value":8},{"type":"int","name":"GIT_REPOSITORY_INIT_MKPATH","comments":"","value":16},{"type":"int","name":"GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE","comments":"","value":32}],"used":{"returns":[],"needs":[]}}],["git_repository_init_mode_t",{"decl":["GIT_REPOSITORY_INIT_SHARED_UMASK","GIT_REPOSITORY_INIT_SHARED_GROUP","GIT_REPOSITORY_INIT_SHARED_ALL"],"type":"enum","file":"repository.h","line":222,"lineto":226,"block":"GIT_REPOSITORY_INIT_SHARED_UMASK\nGIT_REPOSITORY_INIT_SHARED_GROUP\nGIT_REPOSITORY_INIT_SHARED_ALL","tdef":"typedef","description":" Mode options for `git_repository_init_ext`.","comments":"

Set the mode field of the git_repository_init_options structure\n either to the custom mode that you would like, or to one of the\n following modes:

\n\n
    \n
  • SHARED_UMASK - Use permissions configured by umask - the default.
  • \n
  • SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo\n to be group writable and "g+sx" for sticky group assignment.
  • \n
  • SHARED_ALL - Use "--shared=all" behavior, adding world readability.
  • \n
  • Anything else - Set to custom value.
  • \n
\n","fields":[{"type":"int","name":"GIT_REPOSITORY_INIT_SHARED_UMASK","comments":"","value":0},{"type":"int","name":"GIT_REPOSITORY_INIT_SHARED_GROUP","comments":"","value":1533},{"type":"int","name":"GIT_REPOSITORY_INIT_SHARED_ALL","comments":"","value":1535}],"used":{"returns":[],"needs":[]}}],["git_repository_init_options",{"decl":["unsigned int version","uint32_t flags","uint32_t mode","const char * workdir_path","const char * description","const char * template_path","const char * initial_head","const char * origin_url"],"type":"struct","value":"git_repository_init_options","file":"repository.h","line":256,"lineto":265,"block":"unsigned int version\nuint32_t flags\nuint32_t mode\nconst char * workdir_path\nconst char * description\nconst char * template_path\nconst char * initial_head\nconst char * origin_url","tdef":"typedef","description":" Extended options structure for `git_repository_init_ext`.","comments":"

This contains extra options for git_repository_init_ext that enable\n additional initialization features. The fields are:

\n\n
    \n
  • flags - Combination of GIT_REPOSITORY_INIT flags above.
  • \n
  • mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_...\n constants above, or to a custom value that you would like.
  • \n
  • workdir_path - The path to the working dir or NULL for default (i.e.\n repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH,\n IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not\n the "natural" working directory, a .git gitlink file will be\n created here linking to the repo_path.
  • \n
  • description - If set, this will be used to initialize the "description"\n file in the repository, instead of using the template content.
  • \n
  • template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set,\n this contains the path to use for the template directory. If\n this is NULL, the config or default directory options will be\n used instead.
  • \n
  • initial_head - The name of the head to point HEAD at. If NULL, then\n this will be treated as "master" and the HEAD ref will be set\n to "refs/heads/master". If this begins with "refs/" it will be\n used verbatim; otherwise "refs/heads/" will be prefixed.
  • \n
  • origin_url - If this is non-NULL, then after the rest of the\n repository initialization is completed, an "origin" remote\n will be added pointing to this URL.
  • \n
\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"uint32_t","name":"flags","comments":""},{"type":"uint32_t","name":"mode","comments":""},{"type":"const char *","name":"workdir_path","comments":""},{"type":"const char *","name":"description","comments":""},{"type":"const char *","name":"template_path","comments":""},{"type":"const char *","name":"initial_head","comments":""},{"type":"const char *","name":"origin_url","comments":""}],"used":{"returns":[],"needs":["git_repository_init_ext","git_repository_init_init_options"]}}],["git_repository_open_flag_t",{"decl":["GIT_REPOSITORY_OPEN_NO_SEARCH","GIT_REPOSITORY_OPEN_CROSS_FS","GIT_REPOSITORY_OPEN_BARE"],"type":"enum","file":"repository.h","line":99,"lineto":103,"block":"GIT_REPOSITORY_OPEN_NO_SEARCH\nGIT_REPOSITORY_OPEN_CROSS_FS\nGIT_REPOSITORY_OPEN_BARE","tdef":"typedef","description":" Option flags for `git_repository_open_ext`.","comments":"
    \n
  • GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be\nimmediately found in the start_path. Do not walk up from the\nstart_path looking at parent directories.
  • \n
  • GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not\ncontinue searching across filesystem boundaries (i.e. when st_dev\nchanges from the stat system call). (E.g. Searching in a user's home\ndirectory "/home/user/source/" will not return "/.git/" as the found\nrepo if "/" is a different filesystem than "/home".)
  • \n
  • GIT_REPOSITORY_OPEN_BARE - Open repository as a bare repo regardless\nof core.bare config, and defer loading config file for faster setup.\nUnlike git_repository_open_bare, this can follow gitlinks.
  • \n
\n","fields":[{"type":"int","name":"GIT_REPOSITORY_OPEN_NO_SEARCH","comments":"","value":1},{"type":"int","name":"GIT_REPOSITORY_OPEN_CROSS_FS","comments":"","value":2},{"type":"int","name":"GIT_REPOSITORY_OPEN_BARE","comments":"","value":4}],"used":{"returns":[],"needs":[]}}],["git_revert_options",{"decl":["unsigned int version","unsigned int mainline","git_merge_options merge_opts","git_checkout_options checkout_opts"],"type":"struct","value":"git_revert_options","file":"revert.h","line":23,"lineto":31,"block":"unsigned int version\nunsigned int mainline\ngit_merge_options merge_opts\ngit_checkout_options checkout_opts","tdef":"typedef","description":" \n\n git2/revert.h\n ","comments":"

@\n{

\n","fields":[{"type":"unsigned int","name":"version","comments":""},{"type":"unsigned int","name":"mainline","comments":" For merge commits, the \"mainline\" is treated as the parent. "},{"type":"git_merge_options","name":"merge_opts","comments":""},{"type":"git_checkout_options","name":"checkout_opts","comments":""}],"used":{"returns":[],"needs":["git_revert","git_revert_init_options"]}}],["git_revparse_mode_t",{"decl":["GIT_REVPARSE_SINGLE","GIT_REVPARSE_RANGE","GIT_REVPARSE_MERGE_BASE"],"type":"enum","file":"revparse.h","line":71,"lineto":78,"block":"GIT_REVPARSE_SINGLE\nGIT_REVPARSE_RANGE\nGIT_REVPARSE_MERGE_BASE","tdef":"typedef","description":" Revparse flags. These indicate the intended behavior of the spec passed to\n git_revparse.","comments":"","fields":[{"type":"int","name":"GIT_REVPARSE_SINGLE","comments":"

The spec targeted a single object.

\n","value":1},{"type":"int","name":"GIT_REVPARSE_RANGE","comments":"

The spec targeted a range of commits.

\n","value":2},{"type":"int","name":"GIT_REVPARSE_MERGE_BASE","comments":"

The spec used the '...' operator, which invokes special semantics.

\n","value":4}],"used":{"returns":[],"needs":[]}}],["git_revspec",{"decl":["git_object * from","git_object * to","unsigned int flags"],"type":"struct","value":"git_revspec","file":"revparse.h","line":83,"lineto":90,"block":"git_object * from\ngit_object * to\nunsigned int flags","tdef":"typedef","description":" Git Revision Spec: output of a `git_revparse` operation","comments":"","fields":[{"type":"git_object *","name":"from","comments":" The left element of the revspec; must be freed by the user "},{"type":"git_object *","name":"to","comments":" The right element of the revspec; must be freed by the user "},{"type":"unsigned int","name":"flags","comments":" The intent of the revspec (i.e. `git_revparse_mode_t` flags) "}],"used":{"returns":[],"needs":["git_revparse"]}}],["git_revwalk",{"decl":"git_revwalk","type":"struct","value":"git_revwalk","file":"types.h","line":111,"lineto":111,"tdef":"typedef","description":" Representation of an in-progress walk through the commits in a repo ","comments":"","used":{"returns":[],"needs":["git_revwalk_add_hide_cb","git_revwalk_free","git_revwalk_hide","git_revwalk_hide_glob","git_revwalk_hide_head","git_revwalk_hide_ref","git_revwalk_new","git_revwalk_next","git_revwalk_push","git_revwalk_push_glob","git_revwalk_push_head","git_revwalk_push_range","git_revwalk_push_ref","git_revwalk_repository","git_revwalk_reset","git_revwalk_simplify_first_parent","git_revwalk_sorting"]}}],["git_signature",{"decl":["char * name","char * email","git_time when"],"type":"struct","value":"git_signature","file":"types.h","line":162,"lineto":166,"block":"char * name\nchar * email\ngit_time when","tdef":"typedef","description":" An action signature (e.g. for committers, taggers, etc) ","comments":"","fields":[{"type":"char *","name":"name","comments":" full name of the author "},{"type":"char *","name":"email","comments":" email of the author "},{"type":"git_time","name":"when","comments":" time when the action happened "}],"used":{"returns":["git_commit_author","git_commit_committer","git_reflog_entry_committer","git_tag_tagger"],"needs":["git_branch_create","git_branch_move","git_clone_into","git_clone_local_into","git_commit_amend","git_commit_create","git_commit_create_from_callback","git_commit_create_from_ids","git_commit_create_v","git_note_create","git_note_remove","git_push_update_tips","git_reference_create","git_reference_create_matching","git_reference_rename","git_reference_set_target","git_reference_symbolic_create","git_reference_symbolic_create_matching","git_reference_symbolic_set_target","git_reflog_append","git_remote_fetch","git_remote_update_tips","git_repository_detach_head","git_repository_set_head","git_repository_set_head_detached","git_signature_default","git_signature_dup","git_signature_free","git_signature_new","git_signature_now","git_tag_annotation_create","git_tag_create"]}}],["git_stash_flags",{"decl":["GIT_STASH_DEFAULT","GIT_STASH_KEEP_INDEX","GIT_STASH_INCLUDE_UNTRACKED","GIT_STASH_INCLUDE_IGNORED"],"type":"enum","file":"stash.h","line":21,"lineto":38,"block":"GIT_STASH_DEFAULT\nGIT_STASH_KEEP_INDEX\nGIT_STASH_INCLUDE_UNTRACKED\nGIT_STASH_INCLUDE_IGNORED","tdef":"typedef","description":" \n\n git2/stash.h\n ","comments":"

@\n{

\n","fields":[{"type":"int","name":"GIT_STASH_DEFAULT","comments":"","value":0},{"type":"int","name":"GIT_STASH_KEEP_INDEX","comments":"","value":1},{"type":"int","name":"GIT_STASH_INCLUDE_UNTRACKED","comments":"","value":2},{"type":"int","name":"GIT_STASH_INCLUDE_IGNORED","comments":"","value":4}],"used":{"returns":[],"needs":[]}}],["git_status_list",{"decl":"git_status_list","type":"struct","value":"git_status_list","file":"types.h","line":181,"lineto":181,"tdef":"typedef","description":" Representation of a status collection ","comments":"","used":{"returns":[],"needs":["git_status_byindex","git_status_list_entrycount","git_status_list_free","git_status_list_get_perfdata","git_status_list_new"]}}],["git_status_opt_t",{"decl":["GIT_STATUS_OPT_INCLUDE_UNTRACKED","GIT_STATUS_OPT_INCLUDE_IGNORED","GIT_STATUS_OPT_INCLUDE_UNMODIFIED","GIT_STATUS_OPT_EXCLUDE_SUBMODULES","GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS","GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH","GIT_STATUS_OPT_RECURSE_IGNORED_DIRS","GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX","GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR","GIT_STATUS_OPT_SORT_CASE_SENSITIVELY","GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY","GIT_STATUS_OPT_RENAMES_FROM_REWRITES","GIT_STATUS_OPT_NO_REFRESH","GIT_STATUS_OPT_UPDATE_INDEX"],"type":"enum","file":"status.h","line":135,"lineto":150,"block":"GIT_STATUS_OPT_INCLUDE_UNTRACKED\nGIT_STATUS_OPT_INCLUDE_IGNORED\nGIT_STATUS_OPT_INCLUDE_UNMODIFIED\nGIT_STATUS_OPT_EXCLUDE_SUBMODULES\nGIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS\nGIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH\nGIT_STATUS_OPT_RECURSE_IGNORED_DIRS\nGIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX\nGIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR\nGIT_STATUS_OPT_SORT_CASE_SENSITIVELY\nGIT_STATUS_OPT_SORT_CASE_INSENSITIVELY\nGIT_STATUS_OPT_RENAMES_FROM_REWRITES\nGIT_STATUS_OPT_NO_REFRESH\nGIT_STATUS_OPT_UPDATE_INDEX","tdef":"typedef","description":" Flags to control status callbacks","comments":"
    \n
  • GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made\non untracked files. These will only be made if the workdir files are\nincluded in the status "show" option.
  • \n
  • GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files get callbacks.\nAgain, these callbacks will only be made if the workdir files are\nincluded in the status "show" option.
  • \n
  • GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be\nmade even on unmodified files.
  • \n
  • GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that submodules should be\nskipped. This only applies if there are no pending typechanges to\nthe submodule (either from or to another type).
  • \n
  • GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that all files in\nuntracked directories should be included. Normally if an entire\ndirectory is new, then just the top-level directory is included (with\na trailing slash on the entry name). This flag says to include all\nof the individual files in the directory instead.
  • \n
  • GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path\nshould be treated as a literal path, and not as a pathspec pattern.
  • \n
  • GIT_STATUS_OPT_RECURSE_IGNORED_DIRS indicates that the contents of\nignored directories should be included in the status. This is like\ndoing git ls-files -o -i --exclude-standard with core git.
  • \n
  • GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX indicates that rename detection\nshould be processed between the head and the index and enables\nthe GIT_STATUS_INDEX_RENAMED as a possible status flag.
  • \n
  • GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates that rename\ndetection should be run between the index and the working directory\nand enabled GIT_STATUS_WT_RENAMED as a possible status flag.
  • \n
  • GIT_STATUS_OPT_SORT_CASE_SENSITIVELY overrides the native case\nsensitivity for the file system and forces the output to be in\ncase-sensitive order
  • \n
  • GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY overrides the native case\nsensitivity for the file system and forces the output to be in\ncase-insensitive order
  • \n
  • GIT_STATUS_OPT_RENAMES_FROM_REWRITES indicates that rename detection\nshould include rewritten files
  • \n
  • GIT_STATUS_OPT_NO_REFRESH bypasses the default status behavior of\ndoing a "soft" index reload (i.e. reloading the index data if the\nfile on disk has been modified outside libgit2).
  • \n
  • GIT_STATUS_OPT_UPDATE_INDEX tells libgit2 to refresh the stat cache\nin the index for files that are unchanged but have out of date stat\ninformation in the index. It will result in less work being done on\nsubsequent calls to get status. This is mutually exclusive with the\nNO_REFRESH option.
  • \n
\n\n

Calling git_status_foreach() is like calling the extended version\n with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,\n and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. Those options are bundled\n together as GIT_STATUS_OPT_DEFAULTS if you want them as a baseline.

\n","fields":[{"type":"int","name":"GIT_STATUS_OPT_INCLUDE_UNTRACKED","comments":"","value":1},{"type":"int","name":"GIT_STATUS_OPT_INCLUDE_IGNORED","comments":"","value":2},{"type":"int","name":"GIT_STATUS_OPT_INCLUDE_UNMODIFIED","comments":"","value":4},{"type":"int","name":"GIT_STATUS_OPT_EXCLUDE_SUBMODULES","comments":"","value":8},{"type":"int","name":"GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS","comments":"","value":16},{"type":"int","name":"GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH","comments":"","value":32},{"type":"int","name":"GIT_STATUS_OPT_RECURSE_IGNORED_DIRS","comments":"","value":64},{"type":"int","name":"GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX","comments":"","value":128},{"type":"int","name":"GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR","comments":"","value":256},{"type":"int","name":"GIT_STATUS_OPT_SORT_CASE_SENSITIVELY","comments":"","value":512},{"type":"int","name":"GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY","comments":"","value":1024},{"type":"int","name":"GIT_STATUS_OPT_RENAMES_FROM_REWRITES","comments":"","value":2048},{"type":"int","name":"GIT_STATUS_OPT_NO_REFRESH","comments":"","value":4096},{"type":"int","name":"GIT_STATUS_OPT_UPDATE_INDEX","comments":"","value":8192}],"used":{"returns":[],"needs":[]}}],["git_status_show_t",{"decl":["GIT_STATUS_SHOW_INDEX_AND_WORKDIR","GIT_STATUS_SHOW_INDEX_ONLY","GIT_STATUS_SHOW_WORKDIR_ONLY"],"type":"enum","file":"status.h","line":77,"lineto":81,"block":"GIT_STATUS_SHOW_INDEX_AND_WORKDIR\nGIT_STATUS_SHOW_INDEX_ONLY\nGIT_STATUS_SHOW_WORKDIR_ONLY","tdef":"typedef","description":" Select the files on which to report status.","comments":"

With git_status_foreach_ext, this will control which changes get\n callbacks. With git_status_list_new, these will control which\n changes are included in the list.

\n\n
    \n
  • GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This roughly\nmatches git status --porcelain regarding which files are\nincluded and in what order.
  • \n
  • GIT_STATUS_SHOW_INDEX_ONLY only gives status based on HEAD to index\ncomparison, not looking at working directory changes.
  • \n
  • GIT_STATUS_SHOW_WORKDIR_ONLY only gives status based on index to\nworking directory comparison, not comparing the index to the HEAD.
  • \n
\n","fields":[{"type":"int","name":"GIT_STATUS_SHOW_INDEX_AND_WORKDIR","comments":"","value":0},{"type":"int","name":"GIT_STATUS_SHOW_INDEX_ONLY","comments":"","value":1},{"type":"int","name":"GIT_STATUS_SHOW_WORKDIR_ONLY","comments":"","value":2}],"used":{"returns":[],"needs":[]}}],["git_status_t",{"decl":["GIT_STATUS_CURRENT","GIT_STATUS_INDEX_NEW","GIT_STATUS_INDEX_MODIFIED","GIT_STATUS_INDEX_DELETED","GIT_STATUS_INDEX_RENAMED","GIT_STATUS_INDEX_TYPECHANGE","GIT_STATUS_WT_NEW","GIT_STATUS_WT_MODIFIED","GIT_STATUS_WT_DELETED","GIT_STATUS_WT_TYPECHANGE","GIT_STATUS_WT_RENAMED","GIT_STATUS_IGNORED"],"type":"enum","file":"status.h","line":32,"lineto":48,"block":"GIT_STATUS_CURRENT\nGIT_STATUS_INDEX_NEW\nGIT_STATUS_INDEX_MODIFIED\nGIT_STATUS_INDEX_DELETED\nGIT_STATUS_INDEX_RENAMED\nGIT_STATUS_INDEX_TYPECHANGE\nGIT_STATUS_WT_NEW\nGIT_STATUS_WT_MODIFIED\nGIT_STATUS_WT_DELETED\nGIT_STATUS_WT_TYPECHANGE\nGIT_STATUS_WT_RENAMED\nGIT_STATUS_IGNORED","tdef":"typedef","description":" Status flags for a single file.","comments":"

A combination of these values will be returned to indicate the status of\n a file. Status compares the working directory, the index, and the\n current HEAD of the repository. The GIT_STATUS_INDEX set of flags\n represents the status of file in the index relative to the HEAD, and the\n GIT_STATUS_WT set of flags represent the status of the file in the\n working directory relative to the index.

\n","fields":[{"type":"int","name":"GIT_STATUS_CURRENT","comments":"","value":0},{"type":"int","name":"GIT_STATUS_INDEX_NEW","comments":"","value":1},{"type":"int","name":"GIT_STATUS_INDEX_MODIFIED","comments":"","value":2},{"type":"int","name":"GIT_STATUS_INDEX_DELETED","comments":"","value":4},{"type":"int","name":"GIT_STATUS_INDEX_RENAMED","comments":"","value":8},{"type":"int","name":"GIT_STATUS_INDEX_TYPECHANGE","comments":"","value":16},{"type":"int","name":"GIT_STATUS_WT_NEW","comments":"","value":128},{"type":"int","name":"GIT_STATUS_WT_MODIFIED","comments":"","value":256},{"type":"int","name":"GIT_STATUS_WT_DELETED","comments":"","value":512},{"type":"int","name":"GIT_STATUS_WT_TYPECHANGE","comments":"","value":1024},{"type":"int","name":"GIT_STATUS_WT_RENAMED","comments":"","value":2048},{"type":"int","name":"GIT_STATUS_IGNORED","comments":"","value":16384}],"used":{"returns":[],"needs":[]}}],["git_strarray",{"decl":["char ** strings","size_t count"],"type":"struct","value":"git_strarray","file":"strarray.h","line":22,"lineto":25,"block":"char ** strings\nsize_t count","tdef":"typedef","description":" Array of strings ","comments":"","fields":[{"type":"char **","name":"strings","comments":""},{"type":"size_t","name":"count","comments":""}],"used":{"returns":[],"needs":["git_index_add_all","git_index_remove_all","git_index_update_all","git_pathspec_new","git_reference_list","git_remote_get_fetch_refspecs","git_remote_get_push_refspecs","git_remote_list","git_remote_rename","git_remote_set_fetch_refspecs","git_remote_set_push_refspecs","git_strarray_copy","git_strarray_free","git_tag_list","git_tag_list_match"]}}],["git_submodule",{"decl":"git_submodule","type":"struct","value":"git_submodule","file":"types.h","line":249,"lineto":249,"tdef":"typedef","description":" Opaque structure representing a submodule.","comments":"","used":{"returns":[],"needs":["git_submodule_add_finalize","git_submodule_add_setup","git_submodule_add_to_index","git_submodule_branch","git_submodule_fetch_recurse_submodules","git_submodule_foreach","git_submodule_free","git_submodule_head_id","git_submodule_ignore","git_submodule_index_id","git_submodule_init","git_submodule_location","git_submodule_lookup","git_submodule_name","git_submodule_open","git_submodule_owner","git_submodule_path","git_submodule_reload","git_submodule_save","git_submodule_set_fetch_recurse_submodules","git_submodule_set_ignore","git_submodule_set_update","git_submodule_set_url","git_submodule_status","git_submodule_sync","git_submodule_update","git_submodule_url","git_submodule_wd_id"]}}],["git_submodule_ignore_t",{"decl":["GIT_SUBMODULE_IGNORE_RESET","GIT_SUBMODULE_IGNORE_NONE","GIT_SUBMODULE_IGNORE_UNTRACKED","GIT_SUBMODULE_IGNORE_DIRTY","GIT_SUBMODULE_IGNORE_ALL","GIT_SUBMODULE_IGNORE_DEFAULT"],"type":"enum","file":"types.h","line":316,"lineto":325,"block":"GIT_SUBMODULE_IGNORE_RESET\nGIT_SUBMODULE_IGNORE_NONE\nGIT_SUBMODULE_IGNORE_UNTRACKED\nGIT_SUBMODULE_IGNORE_DIRTY\nGIT_SUBMODULE_IGNORE_ALL\nGIT_SUBMODULE_IGNORE_DEFAULT","tdef":"typedef","description":" Submodule ignore values","comments":"

These values represent settings for the submodule.$name.ignore\n configuration value which says how deeply to look at the working\n directory when getting submodule status.

\n\n

You can override this value in memory on a per-submodule basis with\n git_submodule_set_ignore() and can write the changed value to disk\n with git_submodule_save(). If you have overwritten the value, you\n can revert to the on disk value by using GIT_SUBMODULE_IGNORE_RESET.

\n\n

The values are:

\n\n
    \n
  • GIT_SUBMODULE_IGNORE_RESET: reset to the on-disk value.
  • \n
  • GIT_SUBMODULE_IGNORE_NONE: don't ignore any change - i.e. even an\nuntracked file, will mark the submodule as dirty. Ignored files are\nstill ignored, of course.
  • \n
  • GIT_SUBMODULE_IGNORE_UNTRACKED: ignore untracked files; only changes\nto tracked files, or the index or the HEAD commit will matter.
  • \n
  • GIT_SUBMODULE_IGNORE_DIRTY: ignore changes in the working directory,\nonly considering changes if the HEAD of submodule has moved from the\nvalue in the superproject.
  • \n
  • GIT_SUBMODULE_IGNORE_ALL: never check if the submodule is dirty
  • \n
  • GIT_SUBMODULE_IGNORE_DEFAULT: not used except as static initializer\nwhen we don't want any particular ignore rule to be specified.
  • \n
\n","fields":[{"type":"int","name":"GIT_SUBMODULE_IGNORE_RESET","comments":"

reset to on-disk value

\n","value":-1},{"type":"int","name":"GIT_SUBMODULE_IGNORE_NONE","comments":"

any change or untracked == dirty

\n","value":1},{"type":"int","name":"GIT_SUBMODULE_IGNORE_UNTRACKED","comments":"

dirty if tracked files change

\n","value":2},{"type":"int","name":"GIT_SUBMODULE_IGNORE_DIRTY","comments":"

only dirty if HEAD moved

\n","value":3},{"type":"int","name":"GIT_SUBMODULE_IGNORE_ALL","comments":"

never dirty

\n","value":4},{"type":"int","name":"GIT_SUBMODULE_IGNORE_DEFAULT","comments":"","value":0}],"used":{"returns":[],"needs":["git_submodule_set_ignore"]}}],["git_submodule_recurse_t",{"decl":["GIT_SUBMODULE_RECURSE_RESET","GIT_SUBMODULE_RECURSE_NO","GIT_SUBMODULE_RECURSE_YES","GIT_SUBMODULE_RECURSE_ONDEMAND"],"type":"enum","file":"types.h","line":338,"lineto":344,"block":"GIT_SUBMODULE_RECURSE_RESET\nGIT_SUBMODULE_RECURSE_NO\nGIT_SUBMODULE_RECURSE_YES\nGIT_SUBMODULE_RECURSE_ONDEMAND","tdef":"typedef","description":" Options for submodule recurse.","comments":"

Represent the value of submodule.$name.fetchRecurseSubmodules

\n\n
    \n
  • GIT_SUBMODULE_RECURSE_RESET - reset to the on-disk value
  • \n
  • GIT_SUBMODULE_RECURSE_NO - do no recurse into submodules
  • \n
  • GIT_SUBMODULE_RECURSE_YES - recurse into submodules
  • \n
  • GIT_SUBMODULE_RECURSE_ONDEMAND - recurse into submodules only when\n commit not already in local clone
  • \n
\n","fields":[{"type":"int","name":"GIT_SUBMODULE_RECURSE_RESET","comments":"","value":-1},{"type":"int","name":"GIT_SUBMODULE_RECURSE_NO","comments":"","value":0},{"type":"int","name":"GIT_SUBMODULE_RECURSE_YES","comments":"","value":1},{"type":"int","name":"GIT_SUBMODULE_RECURSE_ONDEMAND","comments":"","value":2}],"used":{"returns":[],"needs":["git_submodule_set_fetch_recurse_submodules"]}}],["git_submodule_status_t",{"decl":["GIT_SUBMODULE_STATUS_IN_HEAD","GIT_SUBMODULE_STATUS_IN_INDEX","GIT_SUBMODULE_STATUS_IN_CONFIG","GIT_SUBMODULE_STATUS_IN_WD","GIT_SUBMODULE_STATUS_INDEX_ADDED","GIT_SUBMODULE_STATUS_INDEX_DELETED","GIT_SUBMODULE_STATUS_INDEX_MODIFIED","GIT_SUBMODULE_STATUS_WD_UNINITIALIZED","GIT_SUBMODULE_STATUS_WD_ADDED","GIT_SUBMODULE_STATUS_WD_DELETED","GIT_SUBMODULE_STATUS_WD_MODIFIED","GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED","GIT_SUBMODULE_STATUS_WD_WD_MODIFIED","GIT_SUBMODULE_STATUS_WD_UNTRACKED"],"type":"enum","file":"submodule.h","line":72,"lineto":87,"block":"GIT_SUBMODULE_STATUS_IN_HEAD\nGIT_SUBMODULE_STATUS_IN_INDEX\nGIT_SUBMODULE_STATUS_IN_CONFIG\nGIT_SUBMODULE_STATUS_IN_WD\nGIT_SUBMODULE_STATUS_INDEX_ADDED\nGIT_SUBMODULE_STATUS_INDEX_DELETED\nGIT_SUBMODULE_STATUS_INDEX_MODIFIED\nGIT_SUBMODULE_STATUS_WD_UNINITIALIZED\nGIT_SUBMODULE_STATUS_WD_ADDED\nGIT_SUBMODULE_STATUS_WD_DELETED\nGIT_SUBMODULE_STATUS_WD_MODIFIED\nGIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED\nGIT_SUBMODULE_STATUS_WD_WD_MODIFIED\nGIT_SUBMODULE_STATUS_WD_UNTRACKED","tdef":"typedef","description":" Return codes for submodule status.","comments":"

A combination of these flags will be returned to describe the status of a\n submodule. Depending on the "ignore" property of the submodule, some of\n the flags may never be returned because they indicate changes that are\n supposed to be ignored.

\n\n

Submodule info is contained in 4 places: the HEAD tree, the index, config\n files (both .git/config and .gitmodules), and the working directory. Any\n or all of those places might be missing information about the submodule\n depending on what state the repo is in. We consider all four places to\n build the combination of status flags.

\n\n

There are four values that are not really status, but give basic info\n about what sources of submodule data are available. These will be\n returned even if ignore is set to "ALL".

\n\n
    \n
  • IN_HEAD - superproject head contains submodule
  • \n
  • IN_INDEX - superproject index contains submodule
  • \n
  • IN_CONFIG - superproject gitmodules has submodule
  • \n
  • IN_WD - superproject workdir has submodule
  • \n
\n\n

The following values will be returned so long as ignore is not "ALL".

\n\n
    \n
  • INDEX_ADDED - in index, not in head
  • \n
  • INDEX_DELETED - in head, not in index
  • \n
  • INDEX_MODIFIED - index and head don't match
  • \n
  • WD_UNINITIALIZED - workdir contains empty directory
  • \n
  • WD_ADDED - in workdir, not index
  • \n
  • WD_DELETED - in index, not workdir
  • \n
  • WD_MODIFIED - index and workdir head don't match
  • \n
\n\n

The following can only be returned if ignore is "NONE" or "UNTRACKED".

\n\n
    \n
  • WD_INDEX_MODIFIED - submodule workdir index is dirty
  • \n
  • WD_WD_MODIFIED - submodule workdir has modified files
  • \n
\n\n

Lastly, the following will only be returned for ignore "NONE".

\n\n
    \n
  • WD_UNTRACKED - wd contains untracked files
  • \n
\n","fields":[{"type":"int","name":"GIT_SUBMODULE_STATUS_IN_HEAD","comments":"","value":1},{"type":"int","name":"GIT_SUBMODULE_STATUS_IN_INDEX","comments":"","value":2},{"type":"int","name":"GIT_SUBMODULE_STATUS_IN_CONFIG","comments":"","value":4},{"type":"int","name":"GIT_SUBMODULE_STATUS_IN_WD","comments":"","value":8},{"type":"int","name":"GIT_SUBMODULE_STATUS_INDEX_ADDED","comments":"","value":16},{"type":"int","name":"GIT_SUBMODULE_STATUS_INDEX_DELETED","comments":"","value":32},{"type":"int","name":"GIT_SUBMODULE_STATUS_INDEX_MODIFIED","comments":"","value":64},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_UNINITIALIZED","comments":"","value":128},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_ADDED","comments":"","value":256},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_DELETED","comments":"","value":512},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_MODIFIED","comments":"","value":1024},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED","comments":"","value":2048},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_WD_MODIFIED","comments":"","value":4096},{"type":"int","name":"GIT_SUBMODULE_STATUS_WD_UNTRACKED","comments":"","value":8192}],"used":{"returns":[],"needs":[]}}],["git_submodule_update_t",{"decl":["GIT_SUBMODULE_UPDATE_RESET","GIT_SUBMODULE_UPDATE_CHECKOUT","GIT_SUBMODULE_UPDATE_REBASE","GIT_SUBMODULE_UPDATE_MERGE","GIT_SUBMODULE_UPDATE_NONE","GIT_SUBMODULE_UPDATE_DEFAULT"],"type":"enum","file":"types.h","line":278,"lineto":287,"block":"GIT_SUBMODULE_UPDATE_RESET\nGIT_SUBMODULE_UPDATE_CHECKOUT\nGIT_SUBMODULE_UPDATE_REBASE\nGIT_SUBMODULE_UPDATE_MERGE\nGIT_SUBMODULE_UPDATE_NONE\nGIT_SUBMODULE_UPDATE_DEFAULT","tdef":"typedef","description":" Submodule update values","comments":"

These values represent settings for the submodule.$name.update\n configuration value which says how to handle git submodule update for\n this submodule. The value is usually set in the ".gitmodules" file and\n copied to ".git/config" when the submodule is initialized.

\n\n

You can override this setting on a per-submodule basis with\n git_submodule_set_update() and write the changed value to disk using\n git_submodule_save(). If you have overwritten the value, you can\n revert it by passing GIT_SUBMODULE_UPDATE_RESET to the set function.

\n\n

The values are:

\n\n
    \n
  • GIT_SUBMODULE_UPDATE_RESET: reset to the on-disk value.
  • \n
  • GIT_SUBMODULE_UPDATE_CHECKOUT: the default; when a submodule is\nupdated, checkout the new detached HEAD to the submodule directory.
  • \n
  • GIT_SUBMODULE_UPDATE_REBASE: update by rebasing the current checked\nout branch onto the commit from the superproject.
  • \n
  • GIT_SUBMODULE_UPDATE_MERGE: update by merging the commit in the\nsuperproject into the current checkout out branch of the submodule.
  • \n
  • GIT_SUBMODULE_UPDATE_NONE: do not update this submodule even when\nthe commit in the superproject is updated.
  • \n
  • GIT_SUBMODULE_UPDATE_DEFAULT: not used except as static initializer\nwhen we don't want any particular update rule to be specified.
  • \n
\n","fields":[{"type":"int","name":"GIT_SUBMODULE_UPDATE_RESET","comments":"","value":-1},{"type":"int","name":"GIT_SUBMODULE_UPDATE_CHECKOUT","comments":"","value":1},{"type":"int","name":"GIT_SUBMODULE_UPDATE_REBASE","comments":"","value":2},{"type":"int","name":"GIT_SUBMODULE_UPDATE_MERGE","comments":"","value":3},{"type":"int","name":"GIT_SUBMODULE_UPDATE_NONE","comments":"","value":4},{"type":"int","name":"GIT_SUBMODULE_UPDATE_DEFAULT","comments":"","value":0}],"used":{"returns":[],"needs":["git_submodule_set_update"]}}],["git_tag",{"decl":"git_tag","type":"struct","value":"git_tag","file":"types.h","line":114,"lineto":114,"tdef":"typedef","description":" Parsed representation of a tag object. ","comments":"","used":{"returns":[],"needs":["git_tag_free","git_tag_id","git_tag_lookup","git_tag_lookup_prefix","git_tag_message","git_tag_name","git_tag_owner","git_tag_peel","git_tag_tagger","git_tag_target","git_tag_target_id","git_tag_target_type"]}}],["git_time",{"decl":["git_time_t time","int offset"],"type":"struct","value":"git_time","file":"types.h","line":156,"lineto":159,"block":"git_time_t time\nint offset","tdef":"typedef","description":" Time in a signature ","comments":"","fields":[{"type":"git_time_t","name":"time","comments":" time in seconds from epoch "},{"type":"int","name":"offset","comments":" timezone offset, in minutes "}],"used":{"returns":[],"needs":[]}}],["git_trace_level_t",{"decl":["GIT_TRACE_NONE","GIT_TRACE_FATAL","GIT_TRACE_ERROR","GIT_TRACE_WARN","GIT_TRACE_INFO","GIT_TRACE_DEBUG","GIT_TRACE_TRACE"],"type":"enum","file":"trace.h","line":26,"lineto":47,"block":"GIT_TRACE_NONE\nGIT_TRACE_FATAL\nGIT_TRACE_ERROR\nGIT_TRACE_WARN\nGIT_TRACE_INFO\nGIT_TRACE_DEBUG\nGIT_TRACE_TRACE","tdef":"typedef","description":" Available tracing levels. When tracing is set to a particular level,\n callers will be provided tracing at the given level and all lower levels.","comments":"","fields":[{"type":"int","name":"GIT_TRACE_NONE","comments":"

No tracing will be performed.

\n","value":0},{"type":"int","name":"GIT_TRACE_FATAL","comments":"

Severe errors that may impact the program's execution

\n","value":1},{"type":"int","name":"GIT_TRACE_ERROR","comments":"

Errors that do not impact the program's execution

\n","value":2},{"type":"int","name":"GIT_TRACE_WARN","comments":"

Warnings that suggest abnormal data

\n","value":3},{"type":"int","name":"GIT_TRACE_INFO","comments":"

Informational messages about program execution

\n","value":4},{"type":"int","name":"GIT_TRACE_DEBUG","comments":"

Detailed data that allows for debugging

\n","value":5},{"type":"int","name":"GIT_TRACE_TRACE","comments":"

Exceptionally detailed debugging data

\n","value":6}],"used":{"returns":[],"needs":["git_trace_set"]}}],["git_transfer_progress",{"decl":["unsigned int total_objects","unsigned int indexed_objects","unsigned int received_objects","unsigned int local_objects","unsigned int total_deltas","unsigned int indexed_deltas","size_t received_bytes"],"type":"struct","value":"git_transfer_progress","file":"types.h","line":227,"lineto":235,"block":"unsigned int total_objects\nunsigned int indexed_objects\nunsigned int received_objects\nunsigned int local_objects\nunsigned int total_deltas\nunsigned int indexed_deltas\nsize_t received_bytes","tdef":"typedef","description":" This is passed as the first argument to the callback to allow the\n user to see the progress.","comments":"
    \n
  • total_objects: number of objects in the packfile being downloaded
  • \n
  • indexed_objects: received objects that have been hashed
  • \n
  • received_objects: objects which have been downloaded
  • \n
  • local_objects: locally-available objects that have been injected\nin order to fix a thin pack.
  • \n
  • received-bytes: size of the packfile received up to now
  • \n
\n","fields":[{"type":"unsigned int","name":"total_objects","comments":""},{"type":"unsigned int","name":"indexed_objects","comments":""},{"type":"unsigned int","name":"received_objects","comments":""},{"type":"unsigned int","name":"local_objects","comments":""},{"type":"unsigned int","name":"total_deltas","comments":""},{"type":"unsigned int","name":"indexed_deltas","comments":""},{"type":"size_t","name":"received_bytes","comments":""}],"used":{"returns":["git_remote_stats"],"needs":["git_indexer_append","git_indexer_commit"]}}],["git_tree",{"decl":"git_tree","type":"struct","value":"git_tree","file":"types.h","line":126,"lineto":126,"tdef":"typedef","description":" Representation of a tree object. ","comments":"","used":{"returns":[],"needs":["git_commit_amend","git_commit_create","git_commit_create_v","git_commit_tree","git_diff_tree_to_index","git_diff_tree_to_tree","git_diff_tree_to_workdir","git_diff_tree_to_workdir_with_index","git_index_read_tree","git_merge_trees","git_pathspec_match_tree","git_tree_entry_byid","git_tree_entry_byindex","git_tree_entry_byname","git_tree_entry_bypath","git_tree_entrycount","git_tree_free","git_tree_id","git_tree_lookup","git_tree_lookup_prefix","git_tree_owner","git_tree_walk","git_treebuilder_create"]}}],["git_tree_entry",{"decl":"git_tree_entry","type":"struct","value":"git_tree_entry","file":"types.h","line":123,"lineto":123,"tdef":"typedef","description":" Representation of each one of the entries in a tree object. ","comments":"","used":{"returns":["git_tree_entry_byid","git_tree_entry_byindex","git_tree_entry_byname","git_treebuilder_get"],"needs":["git_tree_entry_bypath","git_tree_entry_cmp","git_tree_entry_dup","git_tree_entry_filemode","git_tree_entry_filemode_raw","git_tree_entry_free","git_tree_entry_id","git_tree_entry_name","git_tree_entry_to_object","git_tree_entry_type","git_treebuilder_insert"]}}],["git_treebuilder",{"decl":"git_treebuilder","type":"struct","value":"git_treebuilder","file":"types.h","line":129,"lineto":129,"tdef":"typedef","description":" Constructor for in-memory trees ","comments":"","used":{"returns":[],"needs":["git_treebuilder_clear","git_treebuilder_create","git_treebuilder_entrycount","git_treebuilder_filter","git_treebuilder_free","git_treebuilder_get","git_treebuilder_insert","git_treebuilder_remove","git_treebuilder_write"]}}],["git_treewalk_mode",{"decl":["GIT_TREEWALK_PRE","GIT_TREEWALK_POST"],"type":"enum","file":"tree.h","line":382,"lineto":385,"block":"GIT_TREEWALK_PRE\nGIT_TREEWALK_POST","tdef":"typedef","description":" Tree traversal modes ","comments":"","fields":[{"type":"int","name":"GIT_TREEWALK_PRE","comments":"","value":0},{"type":"int","name":"GIT_TREEWALK_POST","comments":"","value":1}],"used":{"returns":[],"needs":["git_tree_walk"]}}]],"prefix":"include/git2","groups":[["attr",["git_attr_add_macro","git_attr_cache_flush","git_attr_foreach","git_attr_get","git_attr_get_many"]],["blame",["git_blame_buffer","git_blame_file","git_blame_free","git_blame_get_hunk_byindex","git_blame_get_hunk_byline","git_blame_get_hunk_count","git_blame_init_options"]],["blob",["git_blob_create_frombuffer","git_blob_create_fromchunks","git_blob_create_fromdisk","git_blob_create_fromworkdir","git_blob_filtered_content","git_blob_free","git_blob_id","git_blob_is_binary","git_blob_lookup","git_blob_lookup_prefix","git_blob_owner","git_blob_rawcontent","git_blob_rawsize"]],["branch",["git_branch_create","git_branch_delete","git_branch_is_head","git_branch_iterator_free","git_branch_iterator_new","git_branch_lookup","git_branch_move","git_branch_name","git_branch_next","git_branch_set_upstream","git_branch_upstream"]],["buf",["git_buf_free","git_buf_grow","git_buf_set"]],["checkout",["git_checkout_head","git_checkout_index","git_checkout_init_options","git_checkout_tree"]],["cherry",["git_cherry_pick","git_cherry_pick_commit","git_cherry_pick_init_options"]],["clone",["git_clone","git_clone_init_options","git_clone_into","git_clone_local_into"]],["commit",["git_commit_amend","git_commit_author","git_commit_committer","git_commit_create","git_commit_create_from_callback","git_commit_create_from_ids","git_commit_create_v","git_commit_free","git_commit_id","git_commit_lookup","git_commit_lookup_prefix","git_commit_message","git_commit_message_encoding","git_commit_message_raw","git_commit_nth_gen_ancestor","git_commit_owner","git_commit_parent","git_commit_parent_id","git_commit_parentcount","git_commit_raw_header","git_commit_summary","git_commit_time","git_commit_time_offset","git_commit_tree","git_commit_tree_id"]],["config",["git_config_add_backend","git_config_add_file_ondisk","git_config_backend_foreach_match","git_config_delete_entry","git_config_delete_multivar","git_config_find_global","git_config_find_system","git_config_find_xdg","git_config_foreach","git_config_foreach_match","git_config_free","git_config_get_bool","git_config_get_entry","git_config_get_int32","git_config_get_int64","git_config_get_mapped","git_config_get_multivar_foreach","git_config_get_string","git_config_init_backend","git_config_iterator_free","git_config_iterator_glob_new","git_config_iterator_new","git_config_lookup_map_value","git_config_multivar_iterator_new","git_config_new","git_config_next","git_config_open_default","git_config_open_global","git_config_open_level","git_config_open_ondisk","git_config_parse_bool","git_config_parse_int32","git_config_parse_int64","git_config_refresh","git_config_set_bool","git_config_set_int32","git_config_set_int64","git_config_set_multivar","git_config_set_string","git_config_snapshot"]],["cred",["git_cred_default_new","git_cred_has_username","git_cred_ssh_custom_new","git_cred_ssh_interactive_new","git_cred_ssh_key_from_agent","git_cred_ssh_key_new","git_cred_userpass","git_cred_userpass_plaintext_new"]],["diff",["git_diff_blob_to_buffer","git_diff_blobs","git_diff_buffers","git_diff_commit_as_email","git_diff_find_init_options","git_diff_find_similar","git_diff_foreach","git_diff_format_email","git_diff_format_email_init_options","git_diff_free","git_diff_get_delta","git_diff_get_perfdata","git_diff_get_stats","git_diff_index_to_workdir","git_diff_init_options","git_diff_is_sorted_icase","git_diff_merge","git_diff_num_deltas","git_diff_num_deltas_of_type","git_diff_print","git_diff_print_callback__to_buf","git_diff_print_callback__to_file_handle","git_diff_stats_deletions","git_diff_stats_files_changed","git_diff_stats_free","git_diff_stats_insertions","git_diff_stats_to_buf","git_diff_status_char","git_diff_tree_to_index","git_diff_tree_to_tree","git_diff_tree_to_workdir","git_diff_tree_to_workdir_with_index"]],["filter",["git_filter_list_apply_to_blob","git_filter_list_apply_to_data","git_filter_list_apply_to_file","git_filter_list_free","git_filter_list_length","git_filter_list_load","git_filter_list_new","git_filter_list_push","git_filter_lookup","git_filter_register","git_filter_source_filemode","git_filter_source_id","git_filter_source_mode","git_filter_source_options","git_filter_source_path","git_filter_source_repo","git_filter_unregister"]],["giterr",["giterr_clear","giterr_detach","giterr_last","giterr_set_oom","giterr_set_str"]],["graph",["git_graph_ahead_behind","git_graph_descendant_of"]],["ignore",["git_ignore_add_rule","git_ignore_clear_internal_rules","git_ignore_path_is_ignored"]],["index",["git_index_add","git_index_add_all","git_index_add_bypath","git_index_caps","git_index_clear","git_index_conflict_add","git_index_conflict_cleanup","git_index_conflict_get","git_index_conflict_iterator_free","git_index_conflict_iterator_new","git_index_conflict_next","git_index_conflict_remove","git_index_entry_stage","git_index_entrycount","git_index_find","git_index_free","git_index_get_byindex","git_index_get_bypath","git_index_has_conflicts","git_index_new","git_index_open","git_index_owner","git_index_path","git_index_read","git_index_read_tree","git_index_remove","git_index_remove_all","git_index_remove_bypath","git_index_remove_directory","git_index_set_caps","git_index_update_all","git_index_write","git_index_write_tree","git_index_write_tree_to"]],["indexer",["git_indexer_append","git_indexer_commit","git_indexer_free","git_indexer_hash","git_indexer_new"]],["libgit2",["git_libgit2_features","git_libgit2_opts","git_libgit2_version"]],["mempack",["git_mempack_new","git_mempack_reset"]],["merge",["git_merge","git_merge_analysis","git_merge_base","git_merge_base_many","git_merge_base_octopus","git_merge_commits","git_merge_file","git_merge_file_from_index","git_merge_file_init_input","git_merge_file_init_options","git_merge_file_result_free","git_merge_head_free","git_merge_head_from_fetchhead","git_merge_head_from_id","git_merge_head_from_ref","git_merge_head_id","git_merge_init_options","git_merge_trees"]],["message",["git_message_prettify"]],["note",["git_note_create","git_note_default_ref","git_note_foreach","git_note_free","git_note_id","git_note_iterator_free","git_note_iterator_new","git_note_message","git_note_next","git_note_read","git_note_remove"]],["object",["git_object__size","git_object_dup","git_object_free","git_object_id","git_object_lookup","git_object_lookup_bypath","git_object_lookup_prefix","git_object_owner","git_object_peel","git_object_short_id","git_object_string2type","git_object_type","git_object_type2string","git_object_typeisloose"]],["odb",["git_odb_add_alternate","git_odb_add_backend","git_odb_add_disk_alternate","git_odb_backend_loose","git_odb_backend_one_pack","git_odb_backend_pack","git_odb_exists","git_odb_exists_prefix","git_odb_foreach","git_odb_free","git_odb_get_backend","git_odb_hash","git_odb_hashfile","git_odb_init_backend","git_odb_new","git_odb_num_backends","git_odb_object_data","git_odb_object_dup","git_odb_object_free","git_odb_object_id","git_odb_object_size","git_odb_object_type","git_odb_open","git_odb_open_rstream","git_odb_open_wstream","git_odb_read","git_odb_read_header","git_odb_read_prefix","git_odb_refresh","git_odb_stream_finalize_write","git_odb_stream_free","git_odb_stream_read","git_odb_stream_write","git_odb_write","git_odb_write_pack"]],["oid",["git_oid_allocfmt","git_oid_cmp","git_oid_cpy","git_oid_equal","git_oid_fmt","git_oid_fromraw","git_oid_fromstr","git_oid_fromstrn","git_oid_fromstrp","git_oid_iszero","git_oid_ncmp","git_oid_nfmt","git_oid_pathfmt","git_oid_shorten_add","git_oid_shorten_free","git_oid_shorten_new","git_oid_strcmp","git_oid_streq","git_oid_tostr"]],["packbuilder",["git_packbuilder_foreach","git_packbuilder_free","git_packbuilder_hash","git_packbuilder_insert","git_packbuilder_insert_commit","git_packbuilder_insert_tree","git_packbuilder_new","git_packbuilder_object_count","git_packbuilder_set_callbacks","git_packbuilder_set_threads","git_packbuilder_write","git_packbuilder_written"]],["patch",["git_patch_free","git_patch_from_blob_and_buffer","git_patch_from_blobs","git_patch_from_buffers","git_patch_from_diff","git_patch_get_delta","git_patch_get_hunk","git_patch_get_line_in_hunk","git_patch_line_stats","git_patch_num_hunks","git_patch_num_lines_in_hunk","git_patch_print","git_patch_size","git_patch_to_buf"]],["pathspec",["git_pathspec_free","git_pathspec_match_diff","git_pathspec_match_index","git_pathspec_match_list_diff_entry","git_pathspec_match_list_entry","git_pathspec_match_list_entrycount","git_pathspec_match_list_failed_entry","git_pathspec_match_list_failed_entrycount","git_pathspec_match_list_free","git_pathspec_match_tree","git_pathspec_match_workdir","git_pathspec_matches_path","git_pathspec_new"]],["push",["git_push_add_refspec","git_push_finish","git_push_free","git_push_init_options","git_push_new","git_push_set_callbacks","git_push_set_options","git_push_status_foreach","git_push_unpack_ok","git_push_update_tips"]],["refdb",["git_refdb_backend_fs","git_refdb_compress","git_refdb_free","git_refdb_init_backend","git_refdb_new","git_refdb_open","git_refdb_set_backend"]],["reference",["git_reference__alloc","git_reference__alloc_symbolic","git_reference_cmp","git_reference_create","git_reference_create_matching","git_reference_delete","git_reference_dwim","git_reference_ensure_log","git_reference_foreach","git_reference_foreach_glob","git_reference_foreach_name","git_reference_free","git_reference_has_log","git_reference_is_branch","git_reference_is_note","git_reference_is_remote","git_reference_is_tag","git_reference_is_valid_name","git_reference_iterator_free","git_reference_iterator_glob_new","git_reference_iterator_new","git_reference_list","git_reference_lookup","git_reference_name","git_reference_name_to_id","git_reference_next","git_reference_next_name","git_reference_normalize_name","git_reference_owner","git_reference_peel","git_reference_remove","git_reference_rename","git_reference_resolve","git_reference_set_target","git_reference_shorthand","git_reference_symbolic_create","git_reference_symbolic_create_matching","git_reference_symbolic_set_target","git_reference_symbolic_target","git_reference_target","git_reference_target_peel","git_reference_type"]],["reflog",["git_reflog_append","git_reflog_delete","git_reflog_drop","git_reflog_entry_byindex","git_reflog_entry_committer","git_reflog_entry_id_new","git_reflog_entry_id_old","git_reflog_entry_message","git_reflog_entrycount","git_reflog_free","git_reflog_read","git_reflog_rename","git_reflog_write"]],["refspec",["git_refspec_direction","git_refspec_dst","git_refspec_dst_matches","git_refspec_force","git_refspec_rtransform","git_refspec_src","git_refspec_src_matches","git_refspec_string","git_refspec_transform"]],["remote",["git_remote_add_fetch","git_remote_add_push","git_remote_autotag","git_remote_check_cert","git_remote_clear_refspecs","git_remote_connect","git_remote_connected","git_remote_create","git_remote_create_anonymous","git_remote_create_with_fetchspec","git_remote_default_branch","git_remote_delete","git_remote_disconnect","git_remote_download","git_remote_dup","git_remote_fetch","git_remote_free","git_remote_get_callbacks","git_remote_get_fetch_refspecs","git_remote_get_push_refspecs","git_remote_get_refspec","git_remote_init_callbacks","git_remote_is_valid_name","git_remote_list","git_remote_load","git_remote_ls","git_remote_name","git_remote_owner","git_remote_pushurl","git_remote_refspec_count","git_remote_rename","git_remote_save","git_remote_set_autotag","git_remote_set_callbacks","git_remote_set_fetch_refspecs","git_remote_set_push_refspecs","git_remote_set_pushurl","git_remote_set_transport","git_remote_set_update_fetchhead","git_remote_set_url","git_remote_stats","git_remote_stop","git_remote_supported_url","git_remote_update_fetchhead","git_remote_update_tips","git_remote_url","git_remote_valid_url"]],["repository",["git_repository_config","git_repository_config_snapshot","git_repository_detach_head","git_repository_discover","git_repository_fetchhead_foreach","git_repository_free","git_repository_get_namespace","git_repository_hashfile","git_repository_head","git_repository_head_detached","git_repository_head_unborn","git_repository_index","git_repository_init","git_repository_init_ext","git_repository_init_init_options","git_repository_is_bare","git_repository_is_empty","git_repository_is_shallow","git_repository_mergehead_foreach","git_repository_message","git_repository_message_remove","git_repository_odb","git_repository_open","git_repository_open_bare","git_repository_open_ext","git_repository_path","git_repository_refdb","git_repository_set_head","git_repository_set_head_detached","git_repository_set_namespace","git_repository_set_workdir","git_repository_state","git_repository_state_cleanup","git_repository_workdir","git_repository_wrap_odb"]],["revert",["git_revert","git_revert_commit","git_revert_init_options"]],["revparse",["git_revparse","git_revparse_ext","git_revparse_single"]],["revwalk",["git_revwalk_add_hide_cb","git_revwalk_free","git_revwalk_hide","git_revwalk_hide_glob","git_revwalk_hide_head","git_revwalk_hide_ref","git_revwalk_new","git_revwalk_next","git_revwalk_push","git_revwalk_push_glob","git_revwalk_push_head","git_revwalk_push_range","git_revwalk_push_ref","git_revwalk_repository","git_revwalk_reset","git_revwalk_simplify_first_parent","git_revwalk_sorting"]],["signature",["git_signature_default","git_signature_dup","git_signature_free","git_signature_new","git_signature_now"]],["smart",["git_smart_subtransport_git","git_smart_subtransport_http","git_smart_subtransport_ssh"]],["stash",["git_stash_drop","git_stash_foreach"]],["status",["git_status_byindex","git_status_file","git_status_foreach","git_status_foreach_ext","git_status_init_options","git_status_list_entrycount","git_status_list_free","git_status_list_get_perfdata","git_status_list_new","git_status_should_ignore"]],["strarray",["git_strarray_copy","git_strarray_free"]],["submodule",["git_submodule_add_finalize","git_submodule_add_setup","git_submodule_add_to_index","git_submodule_branch","git_submodule_fetch_recurse_submodules","git_submodule_foreach","git_submodule_free","git_submodule_head_id","git_submodule_ignore","git_submodule_index_id","git_submodule_init","git_submodule_location","git_submodule_lookup","git_submodule_name","git_submodule_open","git_submodule_owner","git_submodule_path","git_submodule_reload","git_submodule_reload_all","git_submodule_save","git_submodule_set_fetch_recurse_submodules","git_submodule_set_ignore","git_submodule_set_update","git_submodule_set_url","git_submodule_status","git_submodule_sync","git_submodule_update","git_submodule_url","git_submodule_wd_id"]],["tag",["git_tag_annotation_create","git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_delete","git_tag_foreach","git_tag_free","git_tag_id","git_tag_list","git_tag_list_match","git_tag_lookup","git_tag_lookup_prefix","git_tag_message","git_tag_name","git_tag_owner","git_tag_peel","git_tag_tagger","git_tag_target","git_tag_target_id","git_tag_target_type"]],["threads",["git_threads_init","git_threads_shutdown"]],["trace",["git_trace_set"]],["transport",["git_transport_dummy","git_transport_init","git_transport_local","git_transport_new","git_transport_register","git_transport_smart","git_transport_unregister"]],["tree",["git_tree_entry_byid","git_tree_entry_byindex","git_tree_entry_byname","git_tree_entry_bypath","git_tree_entry_cmp","git_tree_entry_dup","git_tree_entry_filemode","git_tree_entry_filemode_raw","git_tree_entry_free","git_tree_entry_id","git_tree_entry_name","git_tree_entry_to_object","git_tree_entry_type","git_tree_entrycount","git_tree_free","git_tree_id","git_tree_lookup","git_tree_lookup_prefix","git_tree_owner","git_tree_walk"]],["treebuilder",["git_treebuilder_clear","git_treebuilder_create","git_treebuilder_entrycount","git_treebuilder_filter","git_treebuilder_free","git_treebuilder_get","git_treebuilder_insert","git_treebuilder_remove","git_treebuilder_write"]]],"examples":[["add.c","ex/v0.21.2/add.html"],["blame.c","ex/v0.21.2/blame.html"],["cat-file.c","ex/v0.21.2/cat-file.html"],["common.c","ex/v0.21.2/common.html"],["diff.c","ex/v0.21.2/diff.html"],["for-each-ref.c","ex/v0.21.2/for-each-ref.html"],["general.c","ex/v0.21.2/general.html"],["init.c","ex/v0.21.2/init.html"],["log.c","ex/v0.21.2/log.html"],["network/clone.c","ex/v0.21.2/network/clone.html"],["network/common.c","ex/v0.21.2/network/common.html"],["network/fetch.c","ex/v0.21.2/network/fetch.html"],["network/git2.c","ex/v0.21.2/network/git2.html"],["network/index-pack.c","ex/v0.21.2/network/index-pack.html"],["network/ls-remote.c","ex/v0.21.2/network/ls-remote.html"],["rev-list.c","ex/v0.21.2/rev-list.html"],["rev-parse.c","ex/v0.21.2/rev-parse.html"],["showindex.c","ex/v0.21.2/showindex.html"],["status.c","ex/v0.21.2/status.html"],["tag.c","ex/v0.21.2/tag.html"]]} \ No newline at end of file diff --git a/include/blob.h b/include/blob.h deleted file mode 100755 index 14c503678..000000000 --- a/include/blob.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITBLOB_H -#define GITBLOB_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitBlob : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_blob *GetValue(); - - static Handle New(void *raw); - - private: - GitBlob(git_blob *raw); - ~GitBlob(); - - static NAN_METHOD(New); - - static NAN_METHOD(Oid); - static NAN_METHOD(Content); - static NAN_METHOD(Size); - static NAN_METHOD(IsBinary); - git_blob *raw; -}; - -#endif diff --git a/include/branch.h b/include/branch.h deleted file mode 100644 index 02a1a71dd..000000000 --- a/include/branch.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef BRANCH_H -#define BRANCH_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class Branch : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_branch *GetValue(); - - static Handle New(void *raw); - - private: - Branch(git_branch *raw); - ~Branch(); - - static NAN_METHOD(New); - - static NAN_METHOD(Create); - static NAN_METHOD(Delete); - static NAN_METHOD(Foreach); - static NAN_METHOD(Move); - static NAN_METHOD(Lookup); - static NAN_METHOD(Name); - static NAN_METHOD(Upstream); - static NAN_METHOD(SetUpstream); - static NAN_METHOD(UpstreamName); - static NAN_METHOD(IsHead); - static NAN_METHOD(RemoteName); - git_branch *raw; -}; - -#endif diff --git a/include/clone_options.h b/include/clone_options.h deleted file mode 100644 index 6ba6b027c..000000000 --- a/include/clone_options.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITCLONEOPTIONS_H -#define GITCLONEOPTIONS_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitCloneOptions : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_clone_options *GetValue(); - - static Handle New(void *raw); - - private: - GitCloneOptions(git_clone_options *raw); - ~GitCloneOptions(); - - static NAN_METHOD(New); - - git_clone_options *raw; -}; - -#endif diff --git a/include/commit.h b/include/commit.h deleted file mode 100755 index efccd66dd..000000000 --- a/include/commit.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITCOMMIT_H -#define GITCOMMIT_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitCommit : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_commit *GetValue(); - - static Handle New(void *raw); - - private: - GitCommit(git_commit *raw); - ~GitCommit(); - - static NAN_METHOD(New); - - static NAN_METHOD(Oid); - static NAN_METHOD(MessageEncoding); - static NAN_METHOD(Message); - static NAN_METHOD(Time); - static NAN_METHOD(Offset); - static NAN_METHOD(Committer); - static NAN_METHOD(Author); - static NAN_METHOD(TreeId); - static NAN_METHOD(ParentCount); - static NAN_METHOD(ParentId); - static NAN_METHOD(NthGenAncestor); - git_commit *raw; -}; - -#endif diff --git a/include/delta.h b/include/delta.h deleted file mode 100644 index 5c8b7315b..000000000 --- a/include/delta.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDELTA_H -#define GITDELTA_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDelta : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_delta *GetValue(); - - static Handle New(void *raw); - - private: - GitDelta(git_diff_delta *raw); - ~GitDelta(); - - static NAN_METHOD(New); - - static NAN_METHOD(OldFile); - static NAN_METHOD(NewFile); - static NAN_METHOD(Status); - static NAN_METHOD(Similarity); - static NAN_METHOD(Flags); - git_diff_delta *raw; -}; - -#endif diff --git a/include/diff.h b/include/diff.h deleted file mode 100644 index fa88badfa..000000000 --- a/include/diff.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDIFF_H -#define GITDIFF_H - -#include -#include -#include - -#include "nan.h" - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDiff : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_list *GetValue(); - - private: - GitDiff(git_diff_list *raw); - ~GitDiff(); - - static NAN_METHOD(New); - - static NAN_METHOD(TreeToTree); - - static void TreeToTreeWork(uv_work_t* req); - static void TreeToTreeAfterWork(uv_work_t* req); - - struct TreeToTreeBaton { - uv_work_t request; - const git_error* error; - git_diff_list * diff; - Persistent repoReference; - git_repository * repo; - Persistent old_treeReference; - git_tree * old_tree; - Persistent new_treeReference; - git_tree * new_tree; - Persistent optsReference; - const git_diff_options * opts; - Persistent callback; - }; - static NAN_METHOD(TreeToIndex); - static void TreeToIndexWork(uv_work_t* req); - static void TreeToIndexAfterWork(uv_work_t* req); - - struct TreeToIndexBaton { - uv_work_t request; - const git_error* error; - git_diff_list * diff; - Persistent repoReference; - git_repository * repo; - Persistent old_treeReference; - git_tree * old_tree; - Persistent indexReference; - git_index * index; - Persistent optsReference; - const git_diff_options * opts; - Persistent callback; - }; - static NAN_METHOD(IndexToWorkdir); - static void IndexToWorkdirWork(uv_work_t* req); - static void IndexToWorkdirAfterWork(uv_work_t* req); - - struct IndexToWorkdirBaton { - uv_work_t request; - const git_error* error; - git_diff_list * diff; - Persistent repoReference; - git_repository * repo; - Persistent indexReference; - git_index * index; - Persistent optsReference; - const git_diff_options * opts; - Persistent callback; - }; - static NAN_METHOD(TreeToWorkdir); - static void TreeToWorkdirWork(uv_work_t* req); - static void TreeToWorkdirAfterWork(uv_work_t* req); - - struct TreeToWorkdirBaton { - uv_work_t request; - const git_error* error; - git_diff_list * diff; - Persistent repoReference; - git_repository * repo; - Persistent old_treeReference; - git_tree * old_tree; - Persistent optsReference; - const git_diff_options * opts; - Persistent callback; - }; - static NAN_METHOD(Merge); - static NAN_METHOD(FindSimilar); - static NAN_METHOD(StatusChar); - static NAN_METHOD(NumDeltas); - static NAN_METHOD(NumDeltasOfType); - static NAN_METHOD(GetPatch); - git_diff_list *raw; -}; - -#endif diff --git a/include/diff_file.h b/include/diff_file.h deleted file mode 100644 index e00eb5a6b..000000000 --- a/include/diff_file.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDIFFFILE_H -#define GITDIFFFILE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDiffFile : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_file *GetValue(); - - static Handle New(void *raw); - - private: - GitDiffFile(git_diff_file *raw); - ~GitDiffFile(); - - static NAN_METHOD(New); - - static NAN_METHOD(Oid); - static NAN_METHOD(Path); - static NAN_METHOD(Size); - static NAN_METHOD(Flags); - static NAN_METHOD(Mode); - git_diff_file *raw; -}; - -#endif diff --git a/include/diff_find_options.h b/include/diff_find_options.h deleted file mode 100644 index e5897cf82..000000000 --- a/include/diff_find_options.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDIFFFINDOPTIONS_H -#define GITDIFFFINDOPTIONS_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDiffFindOptions : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_find_options *GetValue(); - - static Handle New(void *raw); - - private: - GitDiffFindOptions(git_diff_find_options *raw); - ~GitDiffFindOptions(); - - static NAN_METHOD(New); - - git_diff_find_options *raw; -}; - -#endif diff --git a/include/diff_list.h b/include/diff_list.h deleted file mode 100644 index d8b4996bb..000000000 --- a/include/diff_list.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDIFFLIST_H -#define GITDIFFLIST_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDiffList : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_list *GetValue(); - - static Handle New(void *raw); - - private: - GitDiffList(git_diff_list *raw); - ~GitDiffList(); - - static NAN_METHOD(New); - - static NAN_METHOD(Merge); - static NAN_METHOD(FindSimilar); - static NAN_METHOD(Size); - static NAN_METHOD(NumDeltasOfType); - static NAN_METHOD(Patch); - git_diff_list *raw; -}; - -#endif diff --git a/include/diff_options.h b/include/diff_options.h deleted file mode 100644 index 79f1580be..000000000 --- a/include/diff_options.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDIFFOPTIONS_H -#define GITDIFFOPTIONS_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDiffOptions : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_options *GetValue(); - - static Handle New(void *raw); - - private: - GitDiffOptions(git_diff_options *raw); - ~GitDiffOptions(); - - static NAN_METHOD(New); - - git_diff_options *raw; -}; - -#endif diff --git a/include/diff_range.h b/include/diff_range.h deleted file mode 100644 index 3d8942288..000000000 --- a/include/diff_range.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITDIFFRANGE_H -#define GITDIFFRANGE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitDiffRange : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_range *GetValue(); - - static Handle New(void *raw); - - private: - GitDiffRange(git_diff_range *raw); - ~GitDiffRange(); - - static NAN_METHOD(New); - - static NAN_METHOD(OldStart); - static NAN_METHOD(OldLines); - static NAN_METHOD(NewStart); - static NAN_METHOD(NewLines); - git_diff_range *raw; -}; - -#endif diff --git a/include/index.h b/include/index.h deleted file mode 100755 index 1346136c2..000000000 --- a/include/index.h +++ /dev/null @@ -1,199 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITINDEX_H -#define GITINDEX_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitIndex : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_index *GetValue(); - - static Handle New(void *raw); - - private: - GitIndex(git_index *raw); - ~GitIndex(); - - static NAN_METHOD(New); - - - struct OpenBaton { - int error_code; - const git_error* error; - git_index * out; - const char * index_path; - }; - class OpenWorker : public NanAsyncWorker { - public: - OpenWorker( - OpenBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~OpenWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - OpenBaton *baton; - }; - static NAN_METHOD(Open); - - struct ReadBaton { - int error_code; - const git_error* error; - git_index * index; - }; - class ReadWorker : public NanAsyncWorker { - public: - ReadWorker( - ReadBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ReadWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ReadBaton *baton; - }; - static NAN_METHOD(Read); - - struct WriteBaton { - int error_code; - const git_error* error; - git_index * index; - }; - class WriteWorker : public NanAsyncWorker { - public: - WriteWorker( - WriteBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~WriteWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - WriteBaton *baton; - }; - static NAN_METHOD(Write); - - struct ReadTreeBaton { - int error_code; - const git_error* error; - git_index * index; - const git_tree * tree; - }; - class ReadTreeWorker : public NanAsyncWorker { - public: - ReadTreeWorker( - ReadTreeBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ReadTreeWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ReadTreeBaton *baton; - }; - static NAN_METHOD(ReadTree); - - struct WriteTreeBaton { - int error_code; - const git_error* error; - git_oid * out; - git_index * index; - }; - class WriteTreeWorker : public NanAsyncWorker { - public: - WriteTreeWorker( - WriteTreeBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~WriteTreeWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - WriteTreeBaton *baton; - }; - static NAN_METHOD(WriteTree); - static NAN_METHOD(Size); - static NAN_METHOD(Clear); - static NAN_METHOD(Entry); - static NAN_METHOD(Remove); - static NAN_METHOD(RemoveDirectory); - - struct AddBypathBaton { - int error_code; - const git_error* error; - git_index * index; - const char * path; - }; - class AddBypathWorker : public NanAsyncWorker { - public: - AddBypathWorker( - AddBypathBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~AddBypathWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - AddBypathBaton *baton; - }; - static NAN_METHOD(AddBypath); - static NAN_METHOD(RemoveBypath); - static NAN_METHOD(Find); - static NAN_METHOD(ConflictRemove); - static NAN_METHOD(ConflictCleanup); - static NAN_METHOD(HasConflicts); - - struct IndexToWorkdirBaton { - int error_code; - const git_error* error; - git_diff_list * diff; - git_repository * repo; - git_index * index; - const git_diff_options * opts; - }; - class IndexToWorkdirWorker : public NanAsyncWorker { - public: - IndexToWorkdirWorker( - IndexToWorkdirBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~IndexToWorkdirWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - IndexToWorkdirBaton *baton; - }; - static NAN_METHOD(IndexToWorkdir); - git_index *raw; -}; - -#endif diff --git a/include/index_entry.h b/include/index_entry.h deleted file mode 100644 index 47f6ef156..000000000 --- a/include/index_entry.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITINDEXENTRY_H -#define GITINDEXENTRY_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitIndexEntry : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_index_entry *GetValue(); - - static Handle New(void *raw); - - private: - GitIndexEntry(git_index_entry *raw); - ~GitIndexEntry(); - - static NAN_METHOD(New); - - static NAN_METHOD(Ctime); - static NAN_METHOD(Mtime); - static NAN_METHOD(Dev); - static NAN_METHOD(Ino); - static NAN_METHOD(Mode); - static NAN_METHOD(Uid); - static NAN_METHOD(gid); - static NAN_METHOD(FileSize); - static NAN_METHOD(Oid); - static NAN_METHOD(Flags); - static NAN_METHOD(FlagsExtended); - static NAN_METHOD(Path); - git_index_entry *raw; -}; - -#endif diff --git a/include/index_time.h b/include/index_time.h deleted file mode 100644 index d60a7fce3..000000000 --- a/include/index_time.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITINDEXTIME_H -#define GITINDEXTIME_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitIndexTime : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_index_time *GetValue(); - - static Handle New(void *raw); - - private: - GitIndexTime(git_index_time *raw); - ~GitIndexTime(); - - static NAN_METHOD(New); - - static NAN_METHOD(Seconds); - static NAN_METHOD(Nanoseconds); - git_index_time *raw; -}; - -#endif diff --git a/include/object.h b/include/object.h deleted file mode 100644 index 69b4c1ecb..000000000 --- a/include/object.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITOBJECT_H -#define GITOBJECT_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitObject : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_object *GetValue(); - - static Handle New(void *raw); - - private: - GitObject(git_object *raw); - ~GitObject(); - - static NAN_METHOD(New); - - static NAN_METHOD(Oid); - static NAN_METHOD(Type); - - struct PeelBaton { - int error_code; - const git_error* error; - git_object * peeled; - const git_object * object; - git_otype target_type; - }; - class PeelWorker : public NanAsyncWorker { - public: - PeelWorker( - PeelBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~PeelWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - PeelBaton *baton; - }; - static NAN_METHOD(Peel); - git_object *raw; -}; - -#endif diff --git a/include/odb.h b/include/odb.h deleted file mode 100644 index 7fb77bbba..000000000 --- a/include/odb.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITODB_H -#define GITODB_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitOdb : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_odb *GetValue(); - - static Handle New(void *raw); - - private: - GitOdb(git_odb *raw); - ~GitOdb(); - - static NAN_METHOD(New); - - static NAN_METHOD(Create); - static NAN_METHOD(Open); - static NAN_METHOD(AddDiskAlternate); - - struct ReadBaton { - int error_code; - const git_error* error; - git_odb_object * out; - git_odb * db; - const git_oid * id; - }; - class ReadWorker : public NanAsyncWorker { - public: - ReadWorker( - ReadBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ReadWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ReadBaton *baton; - }; - static NAN_METHOD(Read); - static NAN_METHOD(ReadPrefix); - static NAN_METHOD(ReadHeader); - static NAN_METHOD(Exists); - static NAN_METHOD(Refresh); - - struct WriteBaton { - int error_code; - const git_error* error; - git_oid * out; - git_odb * odb; - const void * data; - size_t len; - git_otype type; - }; - class WriteWorker : public NanAsyncWorker { - public: - WriteWorker( - WriteBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~WriteWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - WriteBaton *baton; - }; - static NAN_METHOD(Write); - static NAN_METHOD(Hash); - static NAN_METHOD(Hashfile); - git_odb *raw; -}; - -#endif diff --git a/include/odb_object.h b/include/odb_object.h deleted file mode 100644 index f32508592..000000000 --- a/include/odb_object.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITODBOBJECT_H -#define GITODBOBJECT_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitOdbObject : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_odb_object *GetValue(); - - static Handle New(void *raw); - - private: - GitOdbObject(git_odb_object *raw); - ~GitOdbObject(); - - static NAN_METHOD(New); - - static NAN_METHOD(Data); - static NAN_METHOD(Size); - static NAN_METHOD(Type); - static NAN_METHOD(Oid); - git_odb_object *raw; -}; - -#endif diff --git a/include/oid.h b/include/oid.h deleted file mode 100755 index 4c0e0986e..000000000 --- a/include/oid.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITOID_H -#define GITOID_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitOid : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_oid *GetValue(); - - static Handle New(void *raw); - - private: - GitOid(git_oid *raw); - ~GitOid(); - - static NAN_METHOD(New); - - static NAN_METHOD(FromString); - static NAN_METHOD(Sha); - git_oid *raw; -}; - -#endif diff --git a/include/patch.h b/include/patch.h deleted file mode 100644 index ddd6de050..000000000 --- a/include/patch.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITPATCH_H -#define GITPATCH_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitPatch : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_diff_patch *GetValue(); - - static Handle New(void *raw); - - private: - GitPatch(git_diff_patch *raw); - ~GitPatch(); - - static NAN_METHOD(New); - - static NAN_METHOD(Delta); - static NAN_METHOD(Size); - static NAN_METHOD(Stats); - static NAN_METHOD(Hunk); - static NAN_METHOD(Lines); - static NAN_METHOD(Line); - static NAN_METHOD(ToString); - git_diff_patch *raw; -}; - -#endif diff --git a/include/refdb.h b/include/refdb.h deleted file mode 100644 index 8f928e208..000000000 --- a/include/refdb.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITREFDB_H -#define GITREFDB_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitRefDb : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_refdb *GetValue(); - - static Handle New(void *raw); - - private: - GitRefDb(git_refdb *raw); - ~GitRefDb(); - - static NAN_METHOD(New); - - git_refdb *raw; -}; - -#endif diff --git a/include/reference.h b/include/reference.h deleted file mode 100644 index 13eaa5107..000000000 --- a/include/reference.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITREFERENCE_H -#define GITREFERENCE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitReference : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_reference *GetValue(); - - static Handle New(void *raw); - - private: - GitReference(git_reference *raw); - ~GitReference(); - - static NAN_METHOD(New); - - - struct OidForNameBaton { - int error_code; - const git_error* error; - git_oid * out; - git_repository * repo; - const char * name; - }; - class OidForNameWorker : public NanAsyncWorker { - public: - OidForNameWorker( - OidForNameBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~OidForNameWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - OidForNameBaton *baton; - }; - static NAN_METHOD(OidForName); - static NAN_METHOD(Target); - static NAN_METHOD(SymbolicTarget); - static NAN_METHOD(Type); - static NAN_METHOD(Name); - - struct ResolveBaton { - int error_code; - const git_error* error; - git_reference * out; - const git_reference * ref; - }; - class ResolveWorker : public NanAsyncWorker { - public: - ResolveWorker( - ResolveBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ResolveWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ResolveBaton *baton; - }; - static NAN_METHOD(Resolve); - static NAN_METHOD(SetSymbolicTarget); - static NAN_METHOD(setTarget); - - struct RenameBaton { - int error_code; - const git_error* error; - git_reference * out; - git_reference * ref; - const char * new_name; - int force; - }; - class RenameWorker : public NanAsyncWorker { - public: - RenameWorker( - RenameBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~RenameWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - RenameBaton *baton; - }; - static NAN_METHOD(Rename); - - struct DeleteBaton { - int error_code; - const git_error* error; - git_reference * ref; - }; - class DeleteWorker : public NanAsyncWorker { - public: - DeleteWorker( - DeleteBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DeleteWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DeleteBaton *baton; - }; - static NAN_METHOD(Delete); - static NAN_METHOD(IsBranch); - static NAN_METHOD(IsRemote); - static NAN_METHOD(Peel); - static NAN_METHOD(IsValidName); - git_reference *raw; -}; - -#endif diff --git a/include/remote.h b/include/remote.h deleted file mode 100644 index 73af9487c..000000000 --- a/include/remote.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITREMOTE_H -#define GITREMOTE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitRemote : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_remote *GetValue(); - - static Handle New(void *raw); - - private: - GitRemote(git_remote *raw); - ~GitRemote(); - - static NAN_METHOD(New); - - static NAN_METHOD(Name); - static NAN_METHOD(Url); - static NAN_METHOD(PushUrl); - static NAN_METHOD(SetUrl); - static NAN_METHOD(SetPushUrl); - - struct ConnectBaton { - int error_code; - const git_error* error; - git_remote * remote; - git_direction direction; - }; - class ConnectWorker : public NanAsyncWorker { - public: - ConnectWorker( - ConnectBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ConnectWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ConnectBaton *baton; - }; - static NAN_METHOD(Connect); - - struct DownloadBaton { - int error_code; - const git_error* error; - git_remote * remote; - git_transfer_progress_callback progress_cb; - void * payload; - }; - class DownloadWorker : public NanAsyncWorker { - public: - DownloadWorker( - DownloadBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DownloadWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DownloadBaton *baton; - }; - static NAN_METHOD(Download); - static NAN_METHOD(Connected); - static NAN_METHOD(Stop); - - struct DisconnectBaton { - int error_code; - const git_error* error; - git_remote * remote; - }; - class DisconnectWorker : public NanAsyncWorker { - public: - DisconnectWorker( - DisconnectBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DisconnectWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DisconnectBaton *baton; - }; - static NAN_METHOD(Disconnect); - static NAN_METHOD(UpdateTips); - static NAN_METHOD(ValidUrl); - static NAN_METHOD(SupportedUrl); - static NAN_METHOD(CheckCert); - static NAN_METHOD(UpdateFetchhead); - static NAN_METHOD(SetUpdateFetchhead); - static NAN_METHOD(IsValidName); - git_remote *raw; -}; - -#endif diff --git a/include/repo.h b/include/repo.h deleted file mode 100755 index a5a71e400..000000000 --- a/include/repo.h +++ /dev/null @@ -1,515 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITREPO_H -#define GITREPO_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitRepo : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_repository *GetValue(); - - static Handle New(void *raw); - - private: - GitRepo(git_repository *raw); - ~GitRepo(); - - static NAN_METHOD(New); - - - struct OpenBaton { - int error_code; - const git_error* error; - git_repository * out; - const char * path; - }; - class OpenWorker : public NanAsyncWorker { - public: - OpenWorker( - OpenBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~OpenWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - OpenBaton *baton; - }; - static NAN_METHOD(Open); - - struct InitBaton { - int error_code; - const git_error* error; - git_repository * out; - const char * path; - unsigned is_bare; - }; - class InitWorker : public NanAsyncWorker { - public: - InitWorker( - InitBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~InitWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - InitBaton *baton; - }; - static NAN_METHOD(Init); - static NAN_METHOD(Path); - static NAN_METHOD(Workdir); - static NAN_METHOD(Odb); - - struct openIndexBaton { - int error_code; - const git_error* error; - git_index * out; - git_repository * repo; - }; - class openIndexWorker : public NanAsyncWorker { - public: - openIndexWorker( - openIndexBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~openIndexWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - openIndexBaton *baton; - }; - static NAN_METHOD(openIndex); - - struct GetBlobBaton { - int error_code; - const git_error* error; - git_blob * blob; - git_repository * repo; - const git_oid * id; - }; - class GetBlobWorker : public NanAsyncWorker { - public: - GetBlobWorker( - GetBlobBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetBlobWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetBlobBaton *baton; - }; - static NAN_METHOD(GetBlob); - - struct GetCommitBaton { - int error_code; - const git_error* error; - git_commit * commit; - git_repository * repo; - const git_oid * id; - }; - class GetCommitWorker : public NanAsyncWorker { - public: - GetCommitWorker( - GetCommitBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetCommitWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetCommitBaton *baton; - }; - static NAN_METHOD(GetCommit); - - struct CreateCommitBaton { - int error_code; - const git_error* error; - git_oid * id; - git_repository * repo; - const char * update_ref; - const git_signature * author; - const git_signature * committer; - const char * message_encoding; - const char * message; - const git_tree * tree; - int parent_count; - const git_commit ** parents; - }; - class CreateCommitWorker : public NanAsyncWorker { - public: - CreateCommitWorker( - CreateCommitBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~CreateCommitWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - CreateCommitBaton *baton; - }; - static NAN_METHOD(CreateCommit); - - struct GetObjectBaton { - int error_code; - const git_error* error; - git_object * object; - git_repository * repo; - const git_oid * id; - git_otype type; - }; - class GetObjectWorker : public NanAsyncWorker { - public: - GetObjectWorker( - GetObjectBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetObjectWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetObjectBaton *baton; - }; - static NAN_METHOD(GetObject); - - struct GetReferenceBaton { - int error_code; - const git_error* error; - git_reference * out; - git_repository * repo; - const char * name; - }; - class GetReferenceWorker : public NanAsyncWorker { - public: - GetReferenceWorker( - GetReferenceBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetReferenceWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetReferenceBaton *baton; - }; - static NAN_METHOD(GetReference); - static NAN_METHOD(CreateSymbolicReference); - static NAN_METHOD(CreateReference); - - struct AddRemoteBaton { - int error_code; - const git_error* error; - git_remote * out; - git_repository * repo; - const char * name; - const char * url; - }; - class AddRemoteWorker : public NanAsyncWorker { - public: - AddRemoteWorker( - AddRemoteBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~AddRemoteWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - AddRemoteBaton *baton; - }; - static NAN_METHOD(AddRemote); - static NAN_METHOD(CreateRevWalk); - static NAN_METHOD(GetSubmodule); - static NAN_METHOD(AddSubmodule); - - struct GetTagBaton { - int error_code; - const git_error* error; - git_tag * out; - git_repository * repo; - const git_oid * id; - }; - class GetTagWorker : public NanAsyncWorker { - public: - GetTagWorker( - GetTagBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetTagWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetTagBaton *baton; - }; - static NAN_METHOD(GetTag); - - struct CreateTagBaton { - int error_code; - const git_error* error; - git_oid * oid; - git_repository * repo; - const char * tag_name; - const git_object * target; - const git_signature * tagger; - const char * message; - int force; - }; - class CreateTagWorker : public NanAsyncWorker { - public: - CreateTagWorker( - CreateTagBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~CreateTagWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - CreateTagBaton *baton; - }; - static NAN_METHOD(CreateTag); - - struct CreateLightweightTagBaton { - int error_code; - const git_error* error; - git_oid * oid; - git_repository * repo; - const char * tag_name; - const git_object * target; - int force; - }; - class CreateLightweightTagWorker : public NanAsyncWorker { - public: - CreateLightweightTagWorker( - CreateLightweightTagBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~CreateLightweightTagWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - CreateLightweightTagBaton *baton; - }; - static NAN_METHOD(CreateLightweightTag); - - struct GetTreeBaton { - int error_code; - const git_error* error; - git_tree * out; - git_repository * repo; - const git_oid * id; - }; - class GetTreeWorker : public NanAsyncWorker { - public: - GetTreeWorker( - GetTreeBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetTreeWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetTreeBaton *baton; - }; - static NAN_METHOD(GetTree); - - struct ReloadSubmodulesBaton { - int error_code; - const git_error* error; - git_repository * repo; - }; - class ReloadSubmodulesWorker : public NanAsyncWorker { - public: - ReloadSubmodulesWorker( - ReloadSubmodulesBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ReloadSubmodulesWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ReloadSubmodulesBaton *baton; - }; - static NAN_METHOD(ReloadSubmodules); - - struct DeleteBaton { - int error_code; - const git_error* error; - git_repository * repo; - const char * tag_name; - }; - class DeleteWorker : public NanAsyncWorker { - public: - DeleteWorker( - DeleteBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DeleteWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DeleteBaton *baton; - }; - static NAN_METHOD(Delete); - - struct GetReferencesBaton { - int error_code; - const git_error* error; - git_strarray * array; - git_repository * repo; - unsigned int list_flags; - }; - class GetReferencesWorker : public NanAsyncWorker { - public: - GetReferencesWorker( - GetReferencesBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetReferencesWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetReferencesBaton *baton; - }; - static NAN_METHOD(GetReferences); - - struct CreateBlobFromBufferBaton { - int error_code; - const git_error* error; - git_oid * oid; - git_repository * repo; - const void * buffer; - size_t len; - }; - class CreateBlobFromBufferWorker : public NanAsyncWorker { - public: - CreateBlobFromBufferWorker( - CreateBlobFromBufferBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~CreateBlobFromBufferWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - CreateBlobFromBufferBaton *baton; - }; - static NAN_METHOD(CreateBlobFromBuffer); - - struct CreateBlobFromFileBaton { - int error_code; - const git_error* error; - git_oid * id; - git_repository * repo; - const char * path; - }; - class CreateBlobFromFileWorker : public NanAsyncWorker { - public: - CreateBlobFromFileWorker( - CreateBlobFromFileBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~CreateBlobFromFileWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - CreateBlobFromFileBaton *baton; - }; - static NAN_METHOD(CreateBlobFromFile); - - struct GetRemotesBaton { - int error_code; - const git_error* error; - git_strarray * out; - git_repository * repo; - }; - class GetRemotesWorker : public NanAsyncWorker { - public: - GetRemotesWorker( - GetRemotesBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetRemotesWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetRemotesBaton *baton; - }; - static NAN_METHOD(GetRemotes); - - struct CloneBaton { - int error_code; - const git_error* error; - git_repository * out; - const char * url; - const char * local_path; - const git_clone_options * options; - }; - class CloneWorker : public NanAsyncWorker { - public: - CloneWorker( - CloneBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~CloneWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - CloneBaton *baton; - }; - static NAN_METHOD(Clone); - static NAN_METHOD(GetRemote); - git_repository *raw; -}; - -#endif diff --git a/include/revwalk.h b/include/revwalk.h deleted file mode 100755 index 29866e43f..000000000 --- a/include/revwalk.h +++ /dev/null @@ -1,233 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITREVWALK_H -#define GITREVWALK_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitRevWalk : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_revwalk *GetValue(); - - static Handle New(void *raw); - - private: - GitRevWalk(git_revwalk *raw); - ~GitRevWalk(); - - static NAN_METHOD(New); - - static NAN_METHOD(Reset); - - struct PushBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - const git_oid * id; - }; - class PushWorker : public NanAsyncWorker { - public: - PushWorker( - PushBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~PushWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - PushBaton *baton; - }; - static NAN_METHOD(Push); - - struct PushGlobBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - const char * glob; - }; - class PushGlobWorker : public NanAsyncWorker { - public: - PushGlobWorker( - PushGlobBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~PushGlobWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - PushGlobBaton *baton; - }; - static NAN_METHOD(PushGlob); - - struct PushHeadBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - }; - class PushHeadWorker : public NanAsyncWorker { - public: - PushHeadWorker( - PushHeadBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~PushHeadWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - PushHeadBaton *baton; - }; - static NAN_METHOD(PushHead); - - struct HideBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - const git_oid * commit_id; - }; - class HideWorker : public NanAsyncWorker { - public: - HideWorker( - HideBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~HideWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - HideBaton *baton; - }; - static NAN_METHOD(Hide); - - struct HideGlobBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - const char * glob; - }; - class HideGlobWorker : public NanAsyncWorker { - public: - HideGlobWorker( - HideGlobBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~HideGlobWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - HideGlobBaton *baton; - }; - static NAN_METHOD(HideGlob); - - struct HideHeadBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - }; - class HideHeadWorker : public NanAsyncWorker { - public: - HideHeadWorker( - HideHeadBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~HideHeadWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - HideHeadBaton *baton; - }; - static NAN_METHOD(HideHead); - - struct PushRefBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - const char * refname; - }; - class PushRefWorker : public NanAsyncWorker { - public: - PushRefWorker( - PushRefBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~PushRefWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - PushRefBaton *baton; - }; - static NAN_METHOD(PushRef); - - struct HideRefBaton { - int error_code; - const git_error* error; - git_revwalk * walk; - const char * refname; - }; - class HideRefWorker : public NanAsyncWorker { - public: - HideRefWorker( - HideRefBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~HideRefWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - HideRefBaton *baton; - }; - static NAN_METHOD(HideRef); - - struct NextBaton { - int error_code; - const git_error* error; - git_oid * out; - git_revwalk * walk; - }; - class NextWorker : public NanAsyncWorker { - public: - NextWorker( - NextBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~NextWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - NextBaton *baton; - }; - static NAN_METHOD(Next); - static NAN_METHOD(Sorting); - git_revwalk *raw; -}; - -#endif diff --git a/include/signature.h b/include/signature.h deleted file mode 100755 index e6e3c58c7..000000000 --- a/include/signature.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITSIGNATURE_H -#define GITSIGNATURE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitSignature : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_signature *GetValue(); - - static Handle New(void *raw); - - private: - GitSignature(git_signature *raw); - ~GitSignature(); - - static NAN_METHOD(New); - - static NAN_METHOD(Name); - static NAN_METHOD(Email); - static NAN_METHOD(Time); - static NAN_METHOD(Create); - static NAN_METHOD(Now); - git_signature *raw; -}; - -#endif diff --git a/include/submodule.h b/include/submodule.h deleted file mode 100644 index dfd25ed3e..000000000 --- a/include/submodule.h +++ /dev/null @@ -1,213 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITSUBMODULE_H -#define GITSUBMODULE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitSubmodule : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_submodule *GetValue(); - - static Handle New(void *raw); - - private: - GitSubmodule(git_submodule *raw); - ~GitSubmodule(); - - static NAN_METHOD(New); - - - struct AddFinalizeBaton { - int error_code; - const git_error* error; - git_submodule * submodule; - }; - class AddFinalizeWorker : public NanAsyncWorker { - public: - AddFinalizeWorker( - AddFinalizeBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~AddFinalizeWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - AddFinalizeBaton *baton; - }; - static NAN_METHOD(AddFinalize); - - struct AddToIndexBaton { - int error_code; - const git_error* error; - git_submodule * submodule; - int write_index; - }; - class AddToIndexWorker : public NanAsyncWorker { - public: - AddToIndexWorker( - AddToIndexBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~AddToIndexWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - AddToIndexBaton *baton; - }; - static NAN_METHOD(AddToIndex); - - struct SaveBaton { - int error_code; - const git_error* error; - git_submodule * submodule; - }; - class SaveWorker : public NanAsyncWorker { - public: - SaveWorker( - SaveBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~SaveWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - SaveBaton *baton; - }; - static NAN_METHOD(Save); - static NAN_METHOD(Name); - static NAN_METHOD(Path); - static NAN_METHOD(Url); - static NAN_METHOD(SetUrl); - static NAN_METHOD(IndexId); - static NAN_METHOD(HeadId); - - struct InitBaton { - int error_code; - const git_error* error; - git_submodule * submodule; - int overwrite; - }; - class InitWorker : public NanAsyncWorker { - public: - InitWorker( - InitBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~InitWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - InitBaton *baton; - }; - static NAN_METHOD(Init); - - struct SyncBaton { - int error_code; - const git_error* error; - git_submodule * submodule; - }; - class SyncWorker : public NanAsyncWorker { - public: - SyncWorker( - SyncBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~SyncWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - SyncBaton *baton; - }; - static NAN_METHOD(Sync); - - struct OpenBaton { - int error_code; - const git_error* error; - git_repository * repo; - git_submodule * submodule; - }; - class OpenWorker : public NanAsyncWorker { - public: - OpenWorker( - OpenBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~OpenWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - OpenBaton *baton; - }; - static NAN_METHOD(Open); - - struct ReloadBaton { - int error_code; - const git_error* error; - git_submodule * submodule; - }; - class ReloadWorker : public NanAsyncWorker { - public: - ReloadWorker( - ReloadBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~ReloadWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - ReloadBaton *baton; - }; - static NAN_METHOD(Reload); - - struct StatusBaton { - int error_code; - const git_error* error; - unsigned int * status; - git_submodule * submodule; - }; - class StatusWorker : public NanAsyncWorker { - public: - StatusWorker( - StatusBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~StatusWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - StatusBaton *baton; - }; - static NAN_METHOD(Status); - git_submodule *raw; -}; - -#endif diff --git a/include/tag.h b/include/tag.h deleted file mode 100755 index abbada0ed..000000000 --- a/include/tag.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITTAG_H -#define GITTAG_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitTag : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_tag *GetValue(); - - static Handle New(void *raw); - - private: - GitTag(git_tag *raw); - ~GitTag(); - - static NAN_METHOD(New); - - static NAN_METHOD(Oid); - - struct GetTargetBaton { - int error_code; - const git_error* error; - git_object * target_out; - const git_tag * tag; - }; - class GetTargetWorker : public NanAsyncWorker { - public: - GetTargetWorker( - GetTargetBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetTargetWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetTargetBaton *baton; - }; - static NAN_METHOD(GetTarget); - static NAN_METHOD(TargetId); - static NAN_METHOD(TargetType); - static NAN_METHOD(Name); - static NAN_METHOD(Tagger); - static NAN_METHOD(Message); - static NAN_METHOD(Peel); - git_tag *raw; -}; - -#endif diff --git a/include/threads.h b/include/threads.h deleted file mode 100755 index e66c9d06c..000000000 --- a/include/threads.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITTHREADS_H -#define GITTHREADS_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitThreads : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - - private: - - static NAN_METHOD(New); - - static NAN_METHOD(Init); - static NAN_METHOD(Shutdown); -}; - -#endif diff --git a/include/time.h b/include/time.h deleted file mode 100644 index 743c13ee7..000000000 --- a/include/time.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITTIME_H -#define GITTIME_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitTime : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_time *GetValue(); - - static Handle New(void *raw); - - private: - GitTime(git_time *raw); - ~GitTime(); - - static NAN_METHOD(New); - - static NAN_METHOD(Time); - static NAN_METHOD(Offset); - git_time *raw; -}; - -#endif diff --git a/include/tree.h b/include/tree.h deleted file mode 100755 index b926406e2..000000000 --- a/include/tree.h +++ /dev/null @@ -1,138 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITTREE_H -#define GITTREE_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitTree : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_tree *GetValue(); - - static Handle New(void *raw); - - private: - GitTree(git_tree *raw); - ~GitTree(); - - static NAN_METHOD(New); - - static NAN_METHOD(Oid); - static NAN_METHOD(Size); - static NAN_METHOD(EntryByName); - static NAN_METHOD(EntryByIndex); - static NAN_METHOD(EntryByOid); - - struct GetEntryBaton { - int error_code; - const git_error* error; - git_tree_entry * out; - git_tree * root; - const char * path; - }; - class GetEntryWorker : public NanAsyncWorker { - public: - GetEntryWorker( - GetEntryBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetEntryWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetEntryBaton *baton; - }; - static NAN_METHOD(GetEntry); - static NAN_METHOD(Builder); - - struct DiffTreeBaton { - int error_code; - const git_error* error; - git_diff_list * diff; - git_repository * repo; - git_tree * old_tree; - git_tree * new_tree; - const git_diff_options * opts; - }; - class DiffTreeWorker : public NanAsyncWorker { - public: - DiffTreeWorker( - DiffTreeBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DiffTreeWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DiffTreeBaton *baton; - }; - static NAN_METHOD(DiffTree); - - struct DiffIndexBaton { - int error_code; - const git_error* error; - git_diff_list * diff; - git_repository * repo; - git_tree * old_tree; - git_index * index; - const git_diff_options * opts; - }; - class DiffIndexWorker : public NanAsyncWorker { - public: - DiffIndexWorker( - DiffIndexBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DiffIndexWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DiffIndexBaton *baton; - }; - static NAN_METHOD(DiffIndex); - - struct DiffWorkDirBaton { - int error_code; - const git_error* error; - git_diff_list * diff; - git_repository * repo; - git_tree * old_tree; - const git_diff_options * opts; - }; - class DiffWorkDirWorker : public NanAsyncWorker { - public: - DiffWorkDirWorker( - DiffWorkDirBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~DiffWorkDirWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - DiffWorkDirBaton *baton; - }; - static NAN_METHOD(DiffWorkDir); - git_tree *raw; -}; - -#endif diff --git a/include/tree_builder.h b/include/tree_builder.h deleted file mode 100644 index 093365171..000000000 --- a/include/tree_builder.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITTREEBUILDER_H -#define GITTREEBUILDER_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitTreeBuilder : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_treebuilder *GetValue(); - - static Handle New(void *raw); - - private: - GitTreeBuilder(git_treebuilder *raw); - ~GitTreeBuilder(); - - static NAN_METHOD(New); - - static NAN_METHOD(Create); - static NAN_METHOD(Clear); - static NAN_METHOD(Size); - static NAN_METHOD(Get); - static NAN_METHOD(Insert); - static NAN_METHOD(GitTreebuilderRemove); - - struct WriteBaton { - int error_code; - const git_error* error; - git_oid * id; - git_repository * repo; - git_treebuilder * bld; - }; - class WriteWorker : public NanAsyncWorker { - public: - WriteWorker( - WriteBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~WriteWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - WriteBaton *baton; - }; - static NAN_METHOD(Write); - git_treebuilder *raw; -}; - -#endif diff --git a/include/tree_entry.h b/include/tree_entry.h deleted file mode 100755 index 126409453..000000000 --- a/include/tree_entry.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ - -#ifndef GITTREEENTRY_H -#define GITTREEENTRY_H - -#include -#include - -#include "git2.h" - -using namespace node; -using namespace v8; - -class GitTreeEntry : public ObjectWrap { - public: - - static Persistent constructor_template; - static void Initialize (Handle target); - - git_tree_entry *GetValue(); - - static Handle New(void *raw); - - private: - GitTreeEntry(git_tree_entry *raw); - ~GitTreeEntry(); - - static NAN_METHOD(New); - - static NAN_METHOD(Name); - static NAN_METHOD(Oid); - static NAN_METHOD(Type); - static NAN_METHOD(filemode); - - struct GetObjectBaton { - int error_code; - const git_error* error; - git_object * object_out; - git_repository * repo; - const git_tree_entry * entry; - }; - class GetObjectWorker : public NanAsyncWorker { - public: - GetObjectWorker( - GetObjectBaton *_baton, - NanCallback *callback - ) : NanAsyncWorker(callback) - , baton(_baton) {}; - ~GetObjectWorker() {}; - void Execute(); - void HandleOKCallback(); - - private: - GetObjectBaton *baton; - }; - static NAN_METHOD(GetObject); - git_tree_entry *raw; -}; - -#endif diff --git a/index.js b/index.js deleted file mode 100755 index df3fe4611..000000000 --- a/index.js +++ /dev/null @@ -1,35 +0,0 @@ -var rawApi; - -// Attempt to load the production release first, if it fails fall back to the -// debug release. -try { - rawApi = require('./build/Release/nodegit'); -} -catch (e) { - rawApi = require('./build/Debug/nodegit'); -} - -// Set the exports prototype to the raw API. -exports.__proto__ = rawApi; - -// Import extensions -require('./lib/commit.js'); -require('./lib/blob.js'); -require('./lib/object.js'); -require('./lib/signature.js'); -require('./lib/odb.js'); -require('./lib/oid.js'); -require('./lib/index.js'); -require('./lib/repo.js'); -require('./lib/reference.js'); -require('./lib/revwalk.js'); -require('./lib/tree.js'); -require('./lib/diff_list.js'); -require('./lib/tree_entry.js'); -require('./lib/tree_builder.js'); - -// Set version -exports.version = require('./package').version; - -// Initialize threads -exports.Threads.init(); diff --git a/install.js b/install.js index 4818e8242..bc1d876fb 100644 --- a/install.js +++ b/install.js @@ -1,16 +1,17 @@ -// Core Node.js modules. -var os = require('os'); -var fs = require('fs'); -var path = require('path'); -var zlib = require('zlib'); -var exec = require('child_process').exec; - -// Third-party modules. -var Q = require('q'); -var request = require('request'); -var tar = require('tar'); -var which = require('which'); -var rimraf = require('rimraf'); +var os = require("os"); +var fs = require("fs"); +var path = require("path"); +var zlib = require("zlib"); +var exec = require("child_process").exec; +var Q = require("q"); +var request = require("request"); +var tar = require("tar"); +var which = require("which"); +var rimraf = require("rimraf"); +var NODE_VERSION = Number(process.version.match(/^v(\d+\.\d+)/)[1]); + +// If the build only flag is set. +var buildOnly = process.env.BUILD_ONLY; // This will take in an object and find any matching keys in the environment // to use as overrides. @@ -18,7 +19,7 @@ var rimraf = require('rimraf'); // ENV variables: // // PKG: Location of `package.json` sans `.json`. -// LIBGIT2: Location of libgit2 source. +// LIBGIT2: Location of libgit2 source. // BUILD: Location of nodegit build directory. function envOverride(obj) { // Look through all keys. @@ -40,60 +41,102 @@ function systemPath(parts) { } // Will be used near the end to configure `node-gyp`. -var python, cmake; +var python; + +var local = path.join.bind(path, __dirname); // Common reusable paths that can be overwritten by environment variables. var paths = envOverride({ - pkg: __dirname + '/package', - libgit2: __dirname + '/vendor/libgit2/', - build: __dirname + '/vendor/libgit2/build/', - release: __dirname + '/build/Release' + pkg: local("package"), + libgit2: local("vendor/libgit2/"), + libssh2: local("vendor/libssh2/"), + http_parser: local("vendor/http_parser/"), + sys: { + include: local("include/sys/"), + src: local("src/sys/"), + build: local("build/Release/obj.target/src/sys/") + }, + release: local("build/Release/") }); // Load the package.json. var pkg = require(paths.pkg); -// Ensure all dependencies are available. -var dependencies = Q.allSettled([ - // This will prioritize `python2` over `python`, because we always want to - // work with Python 2.* if it's available. - Q.nfcall(which, 'python2'), - Q.nfcall(which, 'python'), +if (NODE_VERSION === 0.1) { + pkg.http_parser = pkg.http_parser["0.10"]; +} + +// Attempt to fallback on a prebuilt binary. +function fetchPrebuilt() { + if (!buildOnly) { + console.info("[nodegit] Fetching binary from S3."); + + // Using the node-pre-gyp module, attempt to fetch a compatible build. + return Q.nfcall(exec, "node-pre-gyp install"); + } + + throw new Error("Build only"); +} + +// Attempt to fetch prebuilt binary. +Q.ninvoke(fs, "mkdir", paths.release).then(fetchPrebuilt, fetchPrebuilt) + +.fail(function() { + if (!buildOnly) { + console.info("[nodegit] Failed to install prebuilt, attempting compile."); + } - // Check for any version of CMake. - Q.nfcall(which, 'cmake'), -]) + // Ensure all dependencies are available. + return Q.allSettled([ + // This will prioritize `python2` over `python`, because we always want to + // work with Python 2.* if it"s available. + Q.nfcall(which, "python2"), + Q.nfcall(which, "python") + ]) +}) // Determine if all the dependency requirements are met. .then(function(results) { - console.info('[nodegit] Determining dependencies.'); + console.info("[nodegit] Determining dependencies."); // Assign to reusable variables. python = results[0].value || results[1].value; - cmake = results[2].value; - - // Now lets check the Python version to ensure it's < 3. - return Q.nfcall(exec, python + ' --version').then(function(version) { - if (version[1].indexOf('Python 3') === 0) { - throw new Error('Incorrect version of Python, gyp requires < 3.'); + + // Missing Python. + if (!python) { + throw new Error("Python is required to build libgit2."); + } + + // Now lets check the Python version to ensure it"s < 3. + return Q.nfcall(exec, python + " --version").then(function(version) { + if (version[1].indexOf("Python 3") === 0) { + throw new Error("Incorrect version of Python, gyp requires < 3."); } }); }) -// Successfully found all dependencies. First step is to clean the vendor +// Successfully found all dependencies. First step is to detect the vendor // directory. .then(function() { - console.info('[nodegit] Removing vendor/libgit2.'); + console.info("[nodegit] Detecting vendor/libgit2."); + + return Q.ninvoke(fs, "stat", paths.libgit2).then(function() { + return Q.ninvoke(fs, "stat", paths.libgit2 + pkg.libgit2.sha); + }).fail(function() { + console.info("[nodegit] Removing outdated vendor/libgit2."); - return Q.ninvoke(rimraf, null, paths.libgit2); + // This directory is outdated, remove. + throw Q.ninvoke(rimraf, null, paths.libgit2); + }); }) -// Now fetch the libgit2 source from GitHub. -.then(function() { - console.info('[nodegit] Fetching vendor/libgit2.'); +// If the directory already exists, no need to refetch. +.fail(function() { + // Otherwise fetch the libgit2 source from GitHub. + console.info("[nodegit] Fetching vendor/libgit2."); + + var url = "https://github.com/libgit2/libgit2/tarball/" + pkg.libgit2.sha; - var url = 'https://github.com/libgit2/libgit2/tarball/' + pkg.libgit2; - var extract = tar.Extract({ path: paths.libgit2, strip: true @@ -102,64 +145,118 @@ var dependencies = Q.allSettled([ // First extract from Zlib and then extract from Tar. var expand = request.get(url).pipe(zlib.createUnzip()).pipe(extract); - return Q.ninvoke(expand, 'on', 'end'); + return Q.ninvoke(expand, "on", "end").then(function() { + // Write out a sha file for testing in the future. + return Q.ninvoke(fs, "writeFile", paths.libgit2 + pkg.libgit2.sha, ""); + }); }) -// Configure the native module using node-gyp. +// Grab libssh2 if needed. .then(function() { - console.info('[nodegit] Configuring native node module.'); + console.info("[nodegit] Detecting vendor/libssh2."); - return Q.nfcall(exec, systemPath([ - '.', 'node_modules', '.bin', 'node-gyp configure --python ' + python - ]), { - cwd: '.' + return Q.ninvoke(fs, "stat", paths.libssh2).then(function() { + return Q.ninvoke(fs, "stat", paths.libssh2 + pkg.libssh2.version); + }).fail(function() { + console.info("[nodegit] Removing outdated vendor/libssh2."); + + // This directory is outdated, remove. + throw Q.ninvoke(rimraf, null, paths.libssh2); }); }) -// Build the native module using node-gyp. +// If the directory already exists, no need to refetch. +.fail(function() { + // Otherwise fetch the libssh2 source. + console.info("[nodegit] Fetching vendor/libssh2."); + + var url = pkg.libssh2.url; + + var extract = tar.Extract({ + path: paths.libssh2, + strip: true + }); + + // First extract from Zlib and then extract from Tar. + var expand = request.get(url).pipe(zlib.createUnzip()).pipe(extract); + + return Q.ninvoke(expand, "on", "end").then(function() { + // Write out a sha file for testing in the future. + return Q.ninvoke(fs, "writeFile", paths.libssh2 + pkg.libssh2.version, ""); + }).then(function() { + // Only run the configuration script in a BSD-like environment. + if (process.platform !== "win32") { + return Q.nfcall(exec, "cd " + paths.libssh2 + " ; " + paths.libssh2 + + "configure"); + } + }); +}) + +// Grab http-parser if needed. .then(function() { - console.info('[nodegit] Building native node module.'); + console.info("[nodegit] Detecting vendor/http_parser."); - return Q.nfcall(exec, systemPath([ - '.', 'node_modules', '.bin', 'node-gyp build' - ]), { - cwd: '.', - maxBuffer: Number.MAX_VALUE + return Q.ninvoke(fs, "stat", paths.http_parser).then(function() { + return Q.ninvoke(fs, "stat", paths.http_parser + pkg.http_parser.version); + }).fail(function() { + console.info("[nodegit] Removing outdated vendor/http_parser."); + + // This directory is outdated, remove. + throw Q.ninvoke(rimraf, null, paths.http_parser); }); }) -// Attempt to fallback on a prebuilt binary. -.fail(function(message) { - console.info('[nodegit] Failed to build nodegit.'); - console.info('[nodegit] Attempting to fallback on a prebuilt binary.'); +// If the directory already exists, no need to refetch. +.fail(function() { + // Otherwise fetch the http_parser source. + console.info("[nodegit] Fetching vendor/http_parser."); - function fetchPrebuilt() { - console.info('[nodegit] Fetching binary from S3.'); + var url = pkg.http_parser.url; - // Using the node-pre-gyp module, attempt to fetch a compatible build. - return Q.nfcall(exec, 'node-pre-gyp install'); - } + var extract = tar.Extract({ + path: paths.http_parser, + strip: true + }); + + // First extract from Zlib and then extract from Tar. + var expand = request.get(url).pipe(zlib.createUnzip()).pipe(extract); + + return Q.ninvoke(expand, "on", "end").then(function() { + // Write out a sha file for testing in the future. + return Q.ninvoke(fs, "writeFile", paths.http_parser + + pkg.http_parser.version, ""); + }); +}) - // Attempt to fetch prebuilt binary. - return Q.ninvoke(fs, 'mkdir', paths.release) - .then(fetchPrebuilt, fetchPrebuilt); + +// Build the native module using node-gyp. +.then(function() { + console.info("[nodegit] Building native node module."); + var pythonFlag = " --python \"" + python + "\""; + + return Q.nfcall(exec, systemPath([ + ".", "node_modules", ".bin", "node-gyp clean configure build" + pythonFlag + ]), { + cwd: ".", + maxBuffer: Number.MAX_VALUE + }); }) // Display a warning message about failing to build native node module. .fail(function(message) { - console.info('[nodegit] Failed to build and install nodegit.'); + console.info("[nodegit] Failed to build and install nodegit."); console.info(message.message); console.info(message.stack); }) // Display a success message. .then(function() { - console.info('[nodegit] Completed installation successfully.'); + console.info("[nodegit] Completed installation successfully."); }) // Display a warning message about failing to build native node module. .fail(function(message) { - console.info('[nodegit] Failed to build nodegit.'); + console.info("[nodegit] Failed to build nodegit."); console.info(message.message); console.info(message.stack); }); diff --git a/lib/attr.js b/lib/attr.js new file mode 100644 index 000000000..f84ddaa29 --- /dev/null +++ b/lib/attr.js @@ -0,0 +1,5 @@ +var NodeGit = require("../"); + +var Attr = NodeGit.Attr; + +module.exports = Attr; diff --git a/lib/blob.js b/lib/blob.js index 341eef637..4f8527273 100644 --- a/lib/blob.js +++ b/lib/blob.js @@ -1,27 +1,35 @@ -var git = require('../'), - TreeEntry = git.TreeEntry, - Blob = git.Blob; +var NodeGit = require("../"); +var TreeEntry = require("./tree_entry"); -var oldContent = Blob.prototype.content; +var Blob = NodeGit.Blob; /** - * Retrieve the content of the blob. - * @return {Buffer} content + * Retrieve the content of the Blob. + * + * @return {Buffer} Contents. */ Blob.prototype.content = function() { - return oldContent.call(this).toBuffer(this.size()); + return this.rawcontent().toBuffer(this.rawsize()); }; /** - * Retrieve the blob's content as String. + * Retrieve the Blob's content as String. + * + * @return {string} Contents. */ Blob.prototype.toString = function() { return this.content().toString(); }; /** - * Retrieve the blob's type. + * Retrieve the Blob's type. + * + * @return {number} The filemode. */ Blob.prototype.filemode = function() { - return this.isBinary() ? TreeEntry.FileMode.Executable : TreeEntry.FileMode.Blob; + var FileMode = TreeEntry.FILEMODE; + + return this.isBinary() ? FileMode.EXECUTABLE : FileMode.BLOB; }; + +module.exports = Blob; diff --git a/lib/branch.js b/lib/branch.js new file mode 100644 index 000000000..a437f1de6 --- /dev/null +++ b/lib/branch.js @@ -0,0 +1,5 @@ +var NodeGit = require("../"); + +var Branch = NodeGit.Branch; + +module.exports = Branch; diff --git a/lib/checkout.js b/lib/checkout.js new file mode 100644 index 000000000..82c02e317 --- /dev/null +++ b/lib/checkout.js @@ -0,0 +1,5 @@ +var NodeGit = require("../"); + +var Checkout = NodeGit.Checkout; + +module.exports = Checkout; diff --git a/lib/clone.js b/lib/clone.js new file mode 100644 index 000000000..500a455e2 --- /dev/null +++ b/lib/clone.js @@ -0,0 +1,32 @@ +var NodeGit = require("../"); +var normalizeOptions = require("./util/normalize_options"); + +var Clone = NodeGit.Clone; +var clone = Clone.clone; + +/** + * Patch repository cloning to automatically coerce objects. + * + * @param url + * @param local_path + * @param options + */ +Clone.clone = function(url, local_path, options) { + var remoteCallbacks; + + if (options) { + remoteCallbacks = options.remoteCallbacks; + delete options.remoteCallbacks; + } + + options = normalizeOptions(options, NodeGit.CloneOptions); + + if (remoteCallbacks) { + options.remoteCallbacks = + normalizeOptions(remoteCallbacks, NodeGit.RemoteCallbacks); + } + + return clone.call(this, url, local_path, options); +}; + +module.exports = Clone; diff --git a/lib/commit.js b/lib/commit.js index 8dc0851f6..710902bc8 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -1,13 +1,15 @@ -var git = require('../'), - Commit = git.Commit, - events = require('events'); +var events = require("events"); +var Promise = require("promise"); +var NodeGit = require("../"); + +var Commit = NodeGit.Commit; /** * Retrieve the SHA. * @return {String} */ Commit.prototype.sha = function() { - return this.oid().sha(); + return this.id().toString(); }; /** @@ -28,10 +30,12 @@ Commit.prototype.date = function() { /** * Get the tree associated with this commit. + * + * @param {Function} callback * @return {Tree} */ Commit.prototype.getTree = function(callback) { - this.repo.getTree(this.treeId(), callback); + return this.repo.getTree(this.treeId(), callback); }; /** @@ -43,18 +47,22 @@ Commit.prototype.getTree = function(callback) { * @return {TreeEntry} */ Commit.prototype.getEntry = function(path, callback) { - this.getTree(function(error, tree) { - if (error) return callback(error); + return this.getTree().then(function(tree) { + return tree.getEntry(path).then(function(entry) { + if (typeof callback === "function") { + callback(null, entry); + } - tree.getEntry(path, callback); - }); + return entry; + }); + }, callback); }; /** * Walk the history from this commit backwards. - * An EventEmitter is returned that will emit a 'commit' event for each - * commit in the history, and one 'end' event when the walk is completed. - * Don't forget to call `start()` on the returned event. + * An EventEmitter is returned that will emit a "commit" event for each + * commit in the history, and one "end" event when the walk is completed. + * Don"t forget to call `start()` on the returned event. * * @fires Commit#commit * @fires Commit#end @@ -63,93 +71,127 @@ Commit.prototype.getEntry = function(path, callback) { */ Commit.prototype.history = function() { var event = new events.EventEmitter(); - - var oid = this.oid(); + var oid = this.id(); var revwalk = this.repo.createRevWalk(); + revwalk.sorting.apply(revwalk, arguments); var commits = []; + event.start = function() { revwalk.walk(oid, function commitRevWalk(error, commit) { - if (error) return event.emit('error', error); + if (error) { + return event.emit("error", error); + } if (!commit) { - event.emit('end', commits); + event.emit("end", commits); return; } - event.emit('commit', commit); + + event.emit("commit", commit); commits.push(commit); }); }; + return event; }; /** - * Retrieve the commit's parents -- as commit objects. + * Retrieve the commit"s parents -- as commit objects. * + * @param {number} limit - Optional amount of parents to return. * @param {Function} callback * @return {[Commit]} array of commits */ -Commit.prototype.getParents = function(callback) { - var self = this; - function processParents(commit, n, acc, callback) { - if (n < 0) return callback(null, acc); - - self.repo.getCommit(self.parentId(n), function nextParent(error, parent) { - if (error) return callback(error); - processParents(parent, n-1, acc.concat([parent]), callback); +Commit.prototype.getParents = function(limit, callback) { + var parents = []; + var i = 0; + + // Shift arguments. + if (typeof limit === "function") { + callback = limit; + } + + // If no limit was set, default to the maximum parents. + limit = typeof limit === "number" ? limit : this.parentcount(); + + function processParents(commit, callback) { + var oid = commit.parentId(i); + + var parent = commit.repo.getCommit(oid).then(function(parent) { + if (--limit) { + i = i + 1; + return processParents(parent, callback); + } + + return parent; }); + + // Add this parent to the list. + parents.push(parent); + + return parent; + } + + // Process all the parents. + if (limit) { + processParents(this, callback); } - processParents(this, this.parentCount() - 1, [], callback); + // Wait for all parents to complete, before returning. + return Promise.all(parents).then(function(parents) { + if (typeof callback === "function") { + callback(null, parents); + } + + return parents; + }, callback); }; /** - * Retrieve the commit's parent shas. + * Retrieve the commit"s parent shas. * * @param {Function} callback * @return {[Oid]} array of oids */ Commit.prototype.parents = function() { var result = []; - for (var i = 0; i < this.parentCount(); i++) { + + for (var i = 0; i < this.parentcount(); i++) { result.push(this.parentId(i)); } + return result; -} +}; /** - * Generate an array of diff trees showing changes between this commit + * Generate an array of diff trees showing changes between this commit * and its parent(s). * * @param {Function} callback - * @return {[DiffList]} an array of difflists + * @return {[Diff]} an array of diffs */ Commit.prototype.getDiff = function(callback) { - var self = this; - self.getParents(function commitParents(error, parents) { - if (error) return callback(error); - - var parentDiffLists = []; - parents.forEach(function commitEachParent(parent) { - parent.getTree(function(error, parentTree) { - if (error) return callback(error); - - self.getTree(function(error, thisTree) { - if (error) return callback(error); - - parentTree.diff(thisTree, function walkDiffList(error, diffList) { - if (error) return callback(error); - - parentDiffLists.push(diffList); - if (parentDiffLists.length === parents.length) { - callback(null, parentDiffLists); - } - }); + var commit = this; + + return commit.getParents().then(function(parents) { + var diffs = parents.map(function(parent) { + return parent.getTree().then(function(parentTree) { + return commit.getTree().then(function(thisTree) { + return parentTree.diff(thisTree); }); }); }); - }); + + return Promise.all(diffs); + }).then(function(diffs) { + if (typeof callback === "function") { + callback(null, diffs); + } + + return diffs; + }, callback); }; /** @@ -159,3 +201,5 @@ Commit.prototype.getDiff = function(callback) { Commit.prototype.toString = function() { return this.sha(); }; + +module.exports = Commit; diff --git a/lib/convenient_hunk.js b/lib/convenient_hunk.js index 9f032a6a5..d61fd8df3 100644 --- a/lib/convenient_hunk.js +++ b/lib/convenient_hunk.js @@ -9,7 +9,7 @@ function ConvenientHunk(raw, i) { * @return {String} */ ConvenientHunk.prototype.header = function() { - return this.raw.hunk(this.i).header; + return this.raw.getHunk(this.i).hunk.header(); }; /** @@ -17,7 +17,7 @@ ConvenientHunk.prototype.header = function() { * @return {Number} */ ConvenientHunk.prototype.size = function() { - return this.raw.hunk(this.i).lines; + return this.raw.numLinesInHunk(this.i); }; /** @@ -26,9 +26,10 @@ ConvenientHunk.prototype.size = function() { */ ConvenientHunk.prototype.lines = function() { var result = []; - for (var i = 0; i < this.size(); i++) - result.push(this.raw.line(this.i, i)); + for (var i = 0; i < this.size(); i++) { + result.push(this.raw.getLineInHunk(this.i, i)); + } return result; }; -exports.ConvenientHunk = ConvenientHunk; +module.exports = ConvenientHunk; diff --git a/lib/convenient_patch.js b/lib/convenient_patch.js index ed34735cb..b6f915114 100644 --- a/lib/convenient_patch.js +++ b/lib/convenient_patch.js @@ -1,17 +1,19 @@ -var git = require('../'), - DiffList = git.DiffList, - ConvenientHunk = require('./convenient_hunk').ConvenientHunk; +var git = require("../"); +var Diff = git.Diff; +var ConvenientHunk = require("./convenient_hunk"); -function ConvenientPatch(raw) { - this.raw = raw; +function ConvenientPatch(delta, patch) { + this.delta = delta; + this.patch = patch; } + /** * Old name of the file * @return {String} */ ConvenientPatch.prototype.oldFile = function() { - return this.raw.delta.oldFile(); + return this.delta.oldFile(); }; /** @@ -19,7 +21,7 @@ ConvenientPatch.prototype.oldFile = function() { * @return {String} */ ConvenientPatch.prototype.newFile = function() { - return this.raw.delta.newFile(); + return this.delta.newFile(); }; /** @@ -27,7 +29,7 @@ ConvenientPatch.prototype.newFile = function() { * @return {Number} */ ConvenientPatch.prototype.size = function() { - return this.raw.patch.size(); + return this.patch.numHunks(); }; /** @@ -36,8 +38,11 @@ ConvenientPatch.prototype.size = function() { */ ConvenientPatch.prototype.hunks = function() { var result = []; - for (var i = 0; i < this.size(); i++) - result.push(new ConvenientHunk(this.raw.patch, i)); + + for (var i = 0; i < this.size(); i++) { + result.push(new ConvenientHunk(this.patch, i)); + } + return result; }; @@ -46,7 +51,7 @@ ConvenientPatch.prototype.hunks = function() { * @return {Number} */ ConvenientPatch.prototype.status = function() { - return this.raw.delta.status(); + return this.delta.status(); }; /** @@ -54,7 +59,7 @@ ConvenientPatch.prototype.status = function() { * @return {Boolean} */ ConvenientPatch.prototype.isUnmodified = function() { - return this.status() == DiffList.Delta.Unmodified; + return this.status() == Diff.DELTA.UNMODIFIED; }; /** @@ -62,7 +67,7 @@ ConvenientPatch.prototype.isUnmodified = function() { * @return {Boolean} */ ConvenientPatch.prototype.isAdded = function() { - return this.status() == DiffList.Delta.Added; + return this.status() == Diff.DELTA.ADDED; }; /** @@ -70,7 +75,7 @@ ConvenientPatch.prototype.isAdded = function() { * @return {Boolean} */ ConvenientPatch.prototype.isDeleted = function() { - return this.status() == DiffList.Delta.Deleted; + return this.status() == Diff.DELTA.DELETED; }; /** @@ -78,7 +83,7 @@ ConvenientPatch.prototype.isDeleted = function() { * @return {Boolean} */ ConvenientPatch.prototype.isModified = function() { - return this.status() == DiffList.Delta.Modified; + return this.status() == Diff.DELTA.MODIFIED; }; /** @@ -86,7 +91,7 @@ ConvenientPatch.prototype.isModified = function() { * @return {Boolean} */ ConvenientPatch.prototype.isRenamed = function() { - return this.status() == DiffList.Delta.Renamed; + return this.status() == Diff.DELTA.RENAMED; }; /** @@ -94,7 +99,7 @@ ConvenientPatch.prototype.isRenamed = function() { * @return {Boolean} */ ConvenientPatch.prototype.isCopied = function() { - return this.status() == DiffList.Delta.Copied; + return this.status() == Diff.DELTA.COPIED; }; /** @@ -102,7 +107,7 @@ ConvenientPatch.prototype.isCopied = function() { * @return {Boolean} */ ConvenientPatch.prototype.isIgnored = function() { - return this.status() == DiffList.Delta.Ignored; + return this.status() == Diff.DELTA.IGNORED; }; /** @@ -110,7 +115,7 @@ ConvenientPatch.prototype.isIgnored = function() { * @return {Boolean} */ ConvenientPatch.prototype.isUntracked = function() { - return this.status() == DiffList.Delta.Untracked; + return this.status() == Diff.DELTA.UNTRACKED; }; /** @@ -118,7 +123,7 @@ ConvenientPatch.prototype.isUntracked = function() { * @return {Boolean} */ ConvenientPatch.prototype.isTypeChange = function() { - return this.status() == DiffList.Delta.TypeChange; + return this.status() == Diff.DELTA.TYPECHANGE; }; -exports.ConvenientPatch = ConvenientPatch; +module.exports = ConvenientPatch; diff --git a/lib/diff.js b/lib/diff.js new file mode 100644 index 000000000..d46f24207 --- /dev/null +++ b/lib/diff.js @@ -0,0 +1,23 @@ +var NodeGit = require("../"); +var Patch = require("./patch"); +var ConvenientPatch = require("./convenient_patch"); + +var Diff = NodeGit.Diff; + +/** + * Retrieve patches in this difflist + * + * @return {[ConvenientPatch]} an array of ConvenientPatches + */ +Diff.prototype.patches = function() { + var size = this.numDeltas(); + var result = []; + + for (var i = 0; i < size; i++) { + result.push(new ConvenientPatch(this.getDelta(i), Patch.fromDiff(this, i))); + } + + return result; +}; + +module.exports = Diff; diff --git a/lib/diff_list.js b/lib/diff_list.js deleted file mode 100644 index 5cc125085..000000000 --- a/lib/diff_list.js +++ /dev/null @@ -1,53 +0,0 @@ -var git = require('../'), - DiffList = git.DiffList, - ConvenientPatch = require('./convenient_patch').ConvenientPatch, - events = require('events'); - -/** - * Refer to vendor/libgit2/include/git2/diff.h for delta type definitions. - * - * @readonly - * @enum {Integer} - */ -DiffList.Delta = { - /** 0 */ Unmodified: 0, - /** 1 */ Added: 1, - /** 2 */ Deleted: 2, - /** 3 */ Modified: 3, - /** 4 */ Renamed: 4, - /** 5 */ Copied: 5, - /** 6 */ Ignored: 6, - /** 7 */ Untracked: 7, - /** 8 */ TypeChange: 8 -}; - -/** - * Refer to vendor/libgit2/include/git2/diff.h for line origin type definitions. - * - * @readOnly - * @enum {String} - */ -DiffList.LineOrigin = { - /** ' ' */ Context: 32, - /** '+' */ Addition: 43, - /** '-' */ Deletion: 45, - /** '\n' */ AddEofNl: 13, - /** '' */ DelEofNl: 0, - /** 'F' */ FileHdr: 106, - /** 'H' */ HunkHdr: 110, - /** 'B' */ Binary: 102 -}; - -/** - * Retrieve patches in this difflist - * - * @return {[ConvenientPatch]} an array of ConvenientPatches - */ -DiffList.prototype.patches = function() { - var size = this.size(); - result = []; - for (var i = 0; i < size; i++) { - result.push(new ConvenientPatch(this.patch(i))); - } - return result; -}; diff --git a/lib/index.js b/lib/index.js index 6dd690e54..a5ed5b344 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,15 +1,20 @@ -var git = require('../'), - Index = git.Index; +var NodeGit = require("../"); + +var Index = NodeGit.Index; /** * Return an array of the entries in this index. * @return {[IndexEntry]} an array of IndexEntrys */ Index.prototype.entries = function() { - var size = this.size(), - result = []; + var size = this.entryCount(); + var result = []; + for (var i = 0; i < size; i++) { - result.push(this.entry(i)); + result.push(this.getByIndex(i)); } + return result; }; + +module.exports = Index; diff --git a/lib/merge.js b/lib/merge.js new file mode 100644 index 000000000..cd96c88ce --- /dev/null +++ b/lib/merge.js @@ -0,0 +1,22 @@ +var NodeGit = require("../"); +var normalizeOptions = require("./util/normalize_options"); + +var Merge = NodeGit.Merge; +var mergeCommits = Merge.commits; + +/** + * Merge 2 commits together and create an new index that can + * be used to create a merge commit. + * + * @param repo Repository that contains the given commits + * @param ourCommit The commit that reflects the destination tree + * @oaram theirCommit The commit to merge into ourCommit + * @param options The merge tree options (null for default) + */ +Merge.commits = function(repo, ourCommit, theirCommit, options) { + options = normalizeOptions(options, NodeGit.MergeOptions); + + return mergeCommits.call(this, repo, ourCommit, theirCommit, options); +}; + +module.exports = Merge; diff --git a/lib/nodegit.js b/lib/nodegit.js new file mode 100644 index 000000000..43760522c --- /dev/null +++ b/lib/nodegit.js @@ -0,0 +1,82 @@ +var Promise = require("nodegit-promise"); +var promisify = require("promisify-node"); +var descriptors = require("../generate/idefs.json"); +var rawApi; + +// Attempt to load the production release first, if it fails fall back to the +// debug release. +try { + rawApi = require("../build/Release/nodegit"); +} +catch (e) { + /* istanbul ignore next */ + rawApi = require("../build/Debug/nodegit"); +} + +// Native methods do not return an identifiable function, so this function will +// filter down the function identity to match the libgit2 descriptor. +descriptors.forEach(function(descriptor) { + if (descriptor.type == "enum") { + return; + } + var Ctor = rawApi[descriptor.jsClassName]; + + // Iterate over each function in the file. + descriptor.functions.filter(function(func) { + return func.isAsync; + }).forEach(function(asyncFunc) { + var original = null; + + // Special case when you have a prototype method. + if (asyncFunc.isPrototypeMethod && Ctor.prototype) { + original = Ctor.prototype[asyncFunc.jsFunctionName]; + Ctor.prototype[asyncFunc.jsFunctionName] = promisify(original); + } + else { + original = Ctor[asyncFunc.jsFunctionName]; + Ctor[asyncFunc.jsFunctionName] = promisify(original); + } + }); +}); + +// Set the exports prototype to the raw API. +exports.__proto__ = rawApi; + +// Import extensions +require("./attr"); +require("./blob"); +require("./clone"); +require("./checkout"); +require("./commit"); +require("./diff"); +require("./index"); +require("./merge"); +require("./object"); +require("./odb"); +require("./odb_object"); +require("./oid"); +require("./patch"); +require("./reference"); +require("./remote"); +require("./revwalk"); +require("./repository"); +require("./revwalk"); +require("./signature"); +require("./status"); +require("./tree"); +require("./tree_entry"); + +//must go last! +require("./enums"); + +// Wrap asynchronous methods to return promises. +promisify(exports); + +// Set version. +exports.version = require("../package").version; + +// Expose Promise implementation. +exports.Promise = Promise; + +// Initialize threads. +exports.Threads.init(); diff --git a/lib/object.js b/lib/object.js index 64c774f84..2ae11b3c2 100644 --- a/lib/object.js +++ b/lib/object.js @@ -1,46 +1,37 @@ -var git = require('../'); +var NodeGit = require("../"); -git.Object.Type = { - Any: -2, /**< Object can be any of the following */ - Bad: -1, /**< Object is invalid. */ - Ext1: 0, /**< Reserved for future use. */ - Commit: 1, /**< A commit object. */ - Tree: 2, /**< A tree (directory listing) object. */ - Blob: 3, /**< A file revision object. */ - Tag: 4, /**< An annotated tag object. */ - Ext2: 5, /**< Reserved for future use. */ - OffsetDelta: 6, /**< A delta, base is given by an offset. */ - OidDelta: 7 /**< A delta, base is given by object id. */ -}; +var Obj = NodeGit.Object; /** * Is this object a commit? * @return {Boolean} */ -git.Object.prototype.isCommit = function() { - return this.type() == git.Object.Type.Commit; +Obj.prototype.isCommit = function() { + return this.type() == Obj.TYPE.COMMIT; }; /** * Is this object a tree? * @return {Boolean} */ -git.Object.prototype.isTree = function() { - return this.type() == git.Object.Type.Tree; +Obj.prototype.isTree = function() { + return this.type() == Obj.TYPE.TREE; }; /** * Is this object a blob? * @return {Boolean} */ -git.Object.prototype.isBlob = function() { - return this.type() == git.Object.Type.Blob; +Obj.prototype.isBlob = function() { + return this.type() == Obj.TYPE.BLOB; }; /** * Is this object a tag? * @return {Boolean} */ -git.Object.prototype.isTag = function() { - return this.type() == git.Object.Type.Tag; +Obj.prototype.isTag = function() { + return this.type() == Obj.TYPE.TAG; }; + +module.exports = Obj; diff --git a/lib/odb.js b/lib/odb.js index 28213903d..12e7c82c1 100644 --- a/lib/odb.js +++ b/lib/odb.js @@ -1,13 +1,19 @@ -var git = require('../'), - util = require('./util.js'), - Odb = git.Odb; - -/** - * Retrieve the object identified by oid. - * - * @param {String|Oid} String sha or Oid - * @param {Function} callback - * @return {git.Object} a git odb object - */ -util.normalizeOid(Odb.prototype, 'read'); -util.makeSafe(Odb.prototype, 'read'); +var git = require("../"); +var normalizeOid = require("./util/normalize_oid"); + +var Odb = git.Odb; +var read = Odb.prototype.read; + +Odb.prototype.read = function(oid, callback) { + oid = normalizeOid(oid); + + return read.call(this, oid).then(function(odbObject) { + if (typeof callback === "function") { + callback(null, odbObject); + } + + return odbObject; + }, callback); +}; + +module.exports = Odb; diff --git a/lib/odb_object.js b/lib/odb_object.js new file mode 100644 index 000000000..31ed33eff --- /dev/null +++ b/lib/odb_object.js @@ -0,0 +1,11 @@ +var NodeGit = require("../"); + +var OdbObject = NodeGit.OdbObject; + +OdbObject.prototype.toString = function(size) { + size = size || this.size(); + + return this.data().toBuffer(size).toString(); +}; + +module.exports = OdbObject; diff --git a/lib/oid.js b/lib/oid.js index cb531d7d8..1fabcf64c 100644 --- a/lib/oid.js +++ b/lib/oid.js @@ -1,14 +1,17 @@ -var git = require('../'), - Oid = git.Oid; - -/** - * The hex representation of the SHA - * @return {String} - */ -Oid.prototype.toString = function() { - return this.sha(); -}; +var NodeGit = require("../"); + +var Oid = NodeGit.Oid; + +// Backwards compatibility. +Object.defineProperties(Oid.prototype, { + "toString": { + value: Oid.prototype.allocfmt, + enumerable: false + } +}); Oid.prototype.inspect = function() { - return "[Oid " + this.sha() + "]"; + return "[Oid " + this.allocfmt() + "]"; }; + +module.exports = Oid; diff --git a/lib/patch.js b/lib/patch.js new file mode 100644 index 000000000..1d486dca3 --- /dev/null +++ b/lib/patch.js @@ -0,0 +1,5 @@ +var NodeGit = require("../"); + +var Patch = NodeGit.Patch; + +module.exports = Patch; diff --git a/lib/reference.js b/lib/reference.js index ce909cc0a..eab158eb0 100644 --- a/lib/reference.js +++ b/lib/reference.js @@ -1,13 +1,14 @@ -var git = require('../'), - Reference = git.Reference; +var NodeGit = require("../"); -var oldSymbolicTarget = Reference.prototype.symbolicTarget, - oldTarget = Reference.prototype.target; +var Reference = NodeGit.Reference; +var Branch = NodeGit.Branch; -Reference.Type = { - Oid: 1, - Symbolic: 2, - All: 3 +/** + * Returns true if this reference is valid + * @return {Boolean} + */ +Reference.prototype.isValid = function() { + return this.type() != Reference.TYPE.INVALID; }; /** @@ -15,7 +16,7 @@ Reference.Type = { * @return {Boolean} */ Reference.prototype.isConcrete = function() { - return this.type() == Reference.Type.Oid; + return this.type() == Reference.TYPE.OID; }; /** @@ -23,35 +24,23 @@ Reference.prototype.isConcrete = function() { * @return {Boolean} */ Reference.prototype.isSymbolic = function() { - return this.type() == Reference.Type.Symbolic; + return this.type() == Reference.TYPE.SYMBOLIC; }; /** - * Returns the target of this symbolic reference. - * @return {Reference} - * @throws if the target is not symbolic. + * Returns the name of the reference. + * @return {String} */ -Reference.prototype.symbolicTarget = function() { - if (!this.isSymbolic()) throw this.name() + " is not symbolic"; - - return oldSymbolicTarget.call(this); +Reference.prototype.toString = function() { + return this.name(); }; /** - * Returns the oid of this non-symbolic reference. - * @return {Oid} - * @throws if the target is symbolic. + * Returns if the ref is pointed at by HEAD + * @return {bool} */ -Reference.prototype.target = function() { - if (!this.isConcrete()) throw this.name() + " is symbolic"; - - return oldTarget.call(this); +Reference.prototype.isHead = function() { + return Branch.isHead(this); }; -/** - * Returns the name of the reference. - * @return {String} - */ -Reference.prototype.toString = function() { - return this.name(); -} \ No newline at end of file +module.exports = Reference; diff --git a/lib/remote.js b/lib/remote.js new file mode 100644 index 000000000..f2515caaa --- /dev/null +++ b/lib/remote.js @@ -0,0 +1,13 @@ +var NodeGit = require("../"); +var normalizeOptions = require("./util/normalize_options"); + +var Remote = NodeGit.Remote; +var setCallbacks = Remote.prototype.setCallbacks; + +Remote.prototype.setCallbacks = function(callbacks) { + callbacks = normalizeOptions(callbacks, NodeGit.RemoteCallbacks); + + return setCallbacks.call(this, callbacks); +}; + +module.exports = Remote; diff --git a/lib/repo.js b/lib/repo.js deleted file mode 100644 index 199d95fff..000000000 --- a/lib/repo.js +++ /dev/null @@ -1,220 +0,0 @@ -var git = require('../'), - util = require('./util.js'), - Repo = git.Repo, - Tree = git.Tree, - TreeBuilder = git.TreeBuilder, - Reference = git.Reference; - -var oldGetReference = Repo.prototype.getReference, - oldGetCommit = Repo.prototype.getCommit, - oldBlob = Repo.prototype.getBlob, - oldGetTree = Repo.prototype.getTree, - oldGetTag = Repo.prototype.getTag, - oldCreateRevWalk = Repo.prototype.createRevWalk, - oldCreateCommit = Repo.prototype.createCommit, - oldCreateBlobFromBuffer = Repo.prototype.createBlobFromBuffer; - -/** - * Look up a branch's most recent commit. - * - * @param {String} name Branch name, e.g. 'master' - * @param {Function} callback - * @return {Branch} - */ -Repo.prototype.getBranch = function(name, callback) { - var self = this; - this.getReference('refs/heads/' + name, function referenceLookupCallback(error, reference) { - if (error) return callback(error); - - self.getCommit(reference.target(), function commitLookupCallback(error, commit) { - if (error) return callback(error); - - callback(null, commit); - }); - }); -}; -util.makeSafe(Repo.prototype, 'getBranch'); - -/** - * Lookup the reference with the given name. - * - * @param {String} name - * @param {Function} callback - * @return {Reference} - */ -Repo.prototype.getReference = function(name, callback) { - var self = this; - oldGetReference.call(this, name, function(error, reference) { - if (error) return callback(error); - - if (reference.type() == Reference.Type.Symbolic) { - reference.resolve(function (error, reference) { - if (error) return callback(error); - reference.repo = self; - callback(null, reference); - }); - } else { - reference.repo = self; - callback(null, reference); - } - }); -}; -util.makeSafe(Repo.prototype, 'getReference'); - -/** - * Retrieve the commit identified by oid. - * - * @param {String|Oid} String sha or Oid - * @param {Function} callback - * @return {Commit} - */ -Repo.prototype.getCommit = function(oid, callback) { - var self = this; - oldGetCommit.call(this, oid, function(error, commit) { - if (error) return callback(error); - commit.repo = self; - callback(null, commit); - }); -}; -util.normalizeOid(Repo.prototype, 'getCommit'); -util.makeSafe(Repo.prototype, 'getCommit'); - -/** - * Retrieve the blob represented by the oid. - * - * @param {String|Oid} String sha or Oid - * @param {Function} callback - * @return {Blob} - */ -Repo.prototype.getBlob = function(oid, callback) { - var self = this; - oldBlob.call(this, oid, function(error, blob) { - if (error) return callback(error); - blob.repo = self; - callback(null, blob); - }); -}; -util.normalizeOid(Repo.prototype, 'getBlob'); -util.makeSafe(Repo.prototype, 'getBlob'); - -/** - * Retrieve the tree represented by the oid. - * - * @param {String|Oid} String sha or Oid - * @param {Function} callback - * @return {Tree} - */ -Repo.prototype.getTree = function(oid, callback) { - var self = this; - oldGetTree.call(this, oid, function(error, tree) { - if (error) return callback(error); - tree.repo = self; - callback(null, tree); - }); -}; -util.normalizeOid(Repo.prototype, 'getTree'); -util.makeSafe(Repo.prototype, 'getTree'); - -/** - * Retrieve the tag represented by the oid. - * - * @param {String|Oid} String sha or Oid - * @param {Function} callback - * @return {Tag} - */ -Repo.prototype.getTag = function(oid, callback) { - var self = this; - oldGetTag.call(this, oid, callback); -}; -util.normalizeOid(Repo.prototype, 'getTag'); -util.makeSafe(Repo.prototype, 'getTag'); - -/** - * Instantiate a new revision walker for browsing the Repo's history. - * See also `Commit.prototype.history()` - * - * @param {String|Oid} String sha or Oid - * @param {Function} callback - * @return {RevWalk} - */ -Repo.prototype.createRevWalk = function() { - var revWalk = oldCreateRevWalk.call(this); - revWalk.repo = this; - return revWalk; -}; - -/** - * Retrieve the master branch. - * - * @param {Function} callback - * @return {Branch} - */ -Repo.prototype.getMaster = function(callback) { - this.getBranch('master', callback); -}; - -/** - * Create a commit - * - * @param {String} updateRef - * @param {Signature} author - * @param {Signature} commiter - * @param {String} message - * @param {Tree|Oid|String} Tree - * @param {Array} parents - * @param {Function} callback - * @return {Oid} The oid of the commit - */ -Repo.prototype.createCommit = function(updateRef, author, committer, message, tree, parents, callback) { - if (tree instanceof Tree) { - oldCreateCommit.call( - this, - updateRef, - author, - committer, - null /* use default message encoding */, - message, - tree, - parents.length, parents, - callback); - } else { - var self = this; - this.getTree(tree, function(error, tree) { - if (error) return callback(error); - oldCreateCommit.call( - self, - updateRef, - author, - committer, - null /* use default message encoding */, - message, - tree, - parents.length, parents, - callback); - }); - } -}; - -/** - * Create a blob from a buffer - * - * @param {Buffer} buffer - * @param {Function} callback - * @return {Blob} - */ -Repo.prototype.createBlobFromBuffer = function(buffer, callback) { - oldCreateBlobFromBuffer.call(this, buffer, buffer.length, callback); -}; - -/** - * Create a new tree builder. - * - * @param {Tree} tree - * @param {Function} callback - */ -Repo.prototype.treeBuilder = function(callback) { - var builder = TreeBuilder.create(null); - builder.root = builder; - builder.repo = this; - return builder; -}; \ No newline at end of file diff --git a/lib/repository.js b/lib/repository.js new file mode 100644 index 000000000..f42314724 --- /dev/null +++ b/lib/repository.js @@ -0,0 +1,411 @@ +var NodeGit = require("../"); +var normalizeOid = require("./util/normalize_oid"); +var Blob = require("./blob"); +var Tree = require("./tree"); +var Tag = require("./tag"); +var Reference = require("./reference"); +var Revwalk = require("./revwalk"); +var Commit = require("./commit"); +var Remote = require("./remote"); +var Promise = require("nodegit-promise"); + +var TreeBuilder = NodeGit.Treebuilder; +var Repository = NodeGit.Repository; + +Object.defineProperty(Repository.prototype, "openIndex", { + enumerable: false, + value: Repository.prototype.index +}); + +/** + * Creates a branch with the passed in name pointing to the commit + * + * @param {String} name Branch name, e.g. "master" + * @param {Commit|String|Oid} commit The commit the branch will point to + * @param {bool} force Overwrite branch if it exists + * @param {Signature} signature Identity to use to populate reflog + * @param {String} logMessage One line message to be appended to the reflog + * @return {Ref} + */ +Repository.prototype.createBranch = +function(name, commit, force, signature, logMessage) { + var repo = this; + + if (commit instanceof Commit) { + return NodeGit.Branch.create( + repo, + name, + commit, + force ? 1 : 0, + signature, + logMessage); + } + else { + return repo.getCommit(commit).then(function(commit) { + return NodeGit.Branch.create( + repo, + name, + commit, + force ? 1 : 0, + signature, + logMessage); + }); + } +}; + +/** + * Look up a branch + * + * @param {String} name Branch name, e.g. "master" + * @param {Function} callback + * @return {Ref} + */ +Repository.prototype.getBranch = function(name, callback) { + name = ~name.indexOf("refs/heads/") ? name : "refs/heads/" + name; + + return this.getReference(name).then(function(reference) { + if (typeof callback === "function") { + callback(null, reference); + } + + return reference; + }, callback); +}; + +/** + * Look up a branch's most recent commit. + * + * @param {String} name Branch name, e.g. "master" + * @param {Function} callback + * @return {Commit} + */ +Repository.prototype.getBranchCommit = function(name, callback) { + var repository = this; + + return this.getBranch(name).then(function(reference) { + return repository.getCommit(reference.target()).then(function(commit) { + if (typeof callback === "function") { + callback(null, commit); + } + + return commit; + }); + }, callback); +}; + +/** + * Lists out the remotes in the given repository. + * + * @param {Function} Optional callback + * @return {Object} Promise object. + */ +Repository.prototype.getRemotes = function(callback) { + return Remote.list(this).then(function(remotes) { + if (typeof callback === "function") { + callback(null, remotes); + } + + return remotes; + }, callback); +}; + +/** + * Lookup the reference with the given name. + * + * @param {String} name + * @param {Function} callback + * @return {Reference} + */ +Repository.prototype.getReference = function(name, callback) { + var repository = this; + + return Reference.lookup(this, name).then(function(reference) { + if (reference.isSymbolic()) { + return reference.resolve(function (error, reference) { + reference.repo = repository; + + if (typeof callback === "function") { + callback(null, reference); + } + + return reference; + }); + } else { + reference.repo = repository; + if (typeof callback === "function") { + callback(null, reference); + } + return reference; + } + }, callback); +}; + +Repository.getReferences = function(repo, type, refNamesOnly, callback) { + return Reference.list(repo).then(function(refList) { + var refFilterPromises = []; + var filteredRefs = []; + + refList.forEach(function(refName) { + refFilterPromises.push(Reference.lookup(repo, refName) + .then(function(ref) { + if (type == Reference.TYPE.ALL || ref.type() == type) { + if (refNamesOnly) { + filteredRefs.push(refName); + return; + } + + if (ref.isSymbolic()) { + return ref.resolve().then(function(resolvedRef) { + resolvedRef.repo = repo; + + filteredRefs.push(resolvedRef); + }); + } + else { + filteredRefs.push(ref); + } + } + }) + ); + }); + + return Promise.all(refFilterPromises).then(function() { + if (typeof callback === "function") { + callback(null, filteredRefs); + } + return filteredRefs; + }, callback); + }); +}; + +Repository.prototype.getReferences = function(type, callback) { + return Repository.getReferences(this, type, false, callback); +}; + +Repository.prototype.getReferenceNames = function(type, callback) { + return Repository.getReferences(this, type, true, callback); +}; + +/** + * Retrieve the commit identified by oid. + * + * @param {String|Oid} String sha or Oid + * @param {Function} callback + * @return {Commit} + */ +Repository.prototype.getCommit = function(oid, callback) { + oid = normalizeOid(oid); + + var repository = this; + + return Commit.lookup(repository, oid).then(function(commit) { + commit.repo = repository; + + if (typeof callback === "function") { + callback(null, commit); + } + + return commit; + }, callback); +}; + +/** + * Retrieve the blob represented by the oid. + * + * @param {String|Oid} String sha or Oid + * @param {Function} callback + * @return {Blob} + */ +Repository.prototype.getBlob = function(oid, callback) { + oid = normalizeOid(oid); + var repository = this; + + return Blob.lookup(repository, oid).then(function(blob) { + blob.repo = repository; + + if (typeof callback === "function") { + callback(null, blob); + } + + return blob; + }, callback); +}; + +/** + * Retrieve the tree represented by the oid. + * + * @param {String|Oid} String sha or Oid + * @param {Function} callback + * @return {Tree} + */ +Repository.prototype.getTree = function(oid, callback) { + oid = normalizeOid(oid); + + var repository = this; + + return Tree.lookup(repository, oid).then(function(tree) { + tree.repo = repository; + + if (typeof callback === "function") { + callback(null, tree); + } + + return tree; + }, callback); +}; + +/** + * Retrieve the tag represented by the oid. + * + * @param {String|Oid} String sha or Oid + * @param {Function} callback + * @return {Tag} + */ +Repository.prototype.getTag = function(oid, callback) { + oid = normalizeOid(oid); + + var repository = this; + + return Tag.lookup(repository, oid).then(function(reference) { + reference.repo = repository; + + if (typeof callback === "function") { + callback(null, reference); + } + + return reference; + }, callback); +}; + +/** + * Retrieve the tag represented by the tag name. + * + * @param {String} Short or full tag name + * @param {Function} callback + * @return {Tag} + */ +Repository.prototype.getTagByName = function(name, callback) { + var repo = this; + + name = ~name.indexOf("refs/tags/") ? name : "refs/tags/" + name; + + return Reference.nameToId(repo, name).then(function(oid) { + return Tag.lookup(repo, oid).then(function(reference) { + reference.repo = repo; + + if (typeof callback === "function") { + callback(null, reference); + } + + return reference; + }); + }, callback); +}; + +/** + * Instantiate a new revision walker for browsing the Repository"s history. + * See also `Commit.prototype.history()` + * + * @param {String|Oid} String sha or Oid + * @param {Function} callback + * @return {RevWalk} + */ +Repository.prototype.createRevWalk = function() { + var revWalk = Revwalk.create(this); + revWalk.repo = this; + return revWalk; +}; + +/** + * Retrieve the master branch commit. + * + * @param {Function} callback + * @return {Commit} + */ +Repository.prototype.getMasterCommit = function(callback) { + return this.getBranchCommit("master", callback); +}; + +/** + * Create a commit + * + * @param {String} updateRef + * @param {Signature} author + * @param {Signature} committer + * @param {String} message + * @param {Tree|Oid|String} Tree + * @param {Array} parents + * @param {Function} callback + * @return {Oid} The oid of the commit + */ +Repository.prototype.createCommit = function( + updateRef, author, committer, message, tree, parents, callback) { + + var createCommit = null; + var repo = this; + + if (tree instanceof Tree) { + createCommit = Promise.all([ + Commit.create( + repo, + updateRef, + author, + committer, + null /* use default message encoding */, + message, + tree, + parents.length, + parents + ) + ]); + } else { + createCommit = this.getTree(tree).then(function(tree) { + return Commit.create( + repo, + updateRef, + author, + committer, + null /* use default message encoding */, + message, + tree, + parents.length, + parents + ); + }); + } + + return createCommit.then(function(commit) { + if (typeof callback === "function") { + callback(null, commit); + } + + return commit; + }, callback); +}; + +/** + * Create a blob from a buffer + * + * @param {Buffer} buffer + * @param {Function} callback + * @return {Blob} + */ +Repository.prototype.createBlobFromBuffer = function(buffer, callback) { + return Blob.createFrombuffer.call(this, buffer, buffer.length, callback); +}; + +/** + * Create a new tree builder. + * + * @param {Tree} tree + */ +Repository.prototype.treeBuilder = function() { + var builder = TreeBuilder.create(null); + + builder.root = builder; + builder.repo = this; + + return builder; +}; + +module.exports = Repository; diff --git a/lib/revwalk.js b/lib/revwalk.js index bd48b7481..cf4875bc4 100644 --- a/lib/revwalk.js +++ b/lib/revwalk.js @@ -1,28 +1,23 @@ -var git = require('../'), - RevWalk = git.RevWalk; +var NodeGit = require("../"); +var normalizeOid = require("./util/normalize_oid"); -var oldSorting = RevWalk.prototype.sorting; +var Revwalk = NodeGit.Revwalk; -/** - * Refer to vendor/libgit2/include/git2/revwalk.h for sort definitions. - */ -RevWalk.Sort = { - None: 0, - Topological: 1, - Time: 2, - Reverse: 4 -}; +var oldSorting = Revwalk.prototype.sorting; /** * Set the sort order for the revwalk. This function takes variable arguments - * like `revwalk.sorting(git.RevWalk.Topological, git.RevWalk.Reverse).` + * like `revwalk.sorting(NodeGit.RevWalk.Topological, NodeGit.RevWalk.Reverse).` * * @param {Number} sort */ -RevWalk.prototype.sorting = function() { +Revwalk.prototype.sorting = function() { var sort = 0; - for (var i = 0; i < arguments.length; i++) + + for (var i = 0; i < arguments.length; i++) { sort |= arguments[i]; + } + oldSorting.call(this, sort); }; @@ -34,24 +29,34 @@ RevWalk.prototype.sorting = function() { * @param {Function} callback * @return {Commit} */ -RevWalk.prototype.walk = function(oid, callback) { - var self = this; - this.push(oid, function revWalkPush(error) { - if (error) return callback(error); +Revwalk.prototype.walk = function(oid, callback) { + oid = normalizeOid(oid); - function walk() { - self.next(function revWalkNext(error, oid) { - if (error) return callback(error); - if (!oid) return callback(); + var revwalk = this; - self.repo.getCommit(oid, function revWalkCommitLookup(error, commit) { - if (error) return callback(error); + this.push(oid); + function walk() { + revwalk.next().then(function(oid) { + if (!oid) { + if (typeof callback === "function") { + return callback(); + } + + return; + } + + revwalk.repo.getCommit(oid).then(function(commit) { + if (typeof callback === "function") { callback(null, commit); - walk(); - }); + } + + walk(); }); - } - walk(); - }); + }, callback); + } + + walk(); }; + +module.exports = Revwalk; diff --git a/lib/signature.js b/lib/signature.js index 652793a07..ed530322a 100644 --- a/lib/signature.js +++ b/lib/signature.js @@ -1,10 +1,13 @@ -var git = require('../'), - Signature = git.Signature; +var NodeGit = require("../"); +var Signature = NodeGit.Signature; /** * Standard string representation of an author. - * @return {String} + * + * @return {string} Representation of the author. */ Signature.prototype.toString = function() { return this.name().toString() + " <" + this.email().toString() + ">"; }; + +module.exports = Signature; diff --git a/lib/status.js b/lib/status.js new file mode 100644 index 000000000..a6f930a13 --- /dev/null +++ b/lib/status.js @@ -0,0 +1,5 @@ +var NodeGit = require("../"); + +var Status = NodeGit.Status; + +module.exports = Status; diff --git a/lib/tag.js b/lib/tag.js new file mode 100644 index 000000000..ebbe71af6 --- /dev/null +++ b/lib/tag.js @@ -0,0 +1,5 @@ +var git = require("../"); + +var Tag = git.Tag; + +module.exports = Tag; diff --git a/lib/tree.js b/lib/tree.js index eada1462f..9abb4662d 100644 --- a/lib/tree.js +++ b/lib/tree.js @@ -1,11 +1,8 @@ -var git = require('../'), - Tree = git.Tree, - events = require('events'), - path = require('path'); - -var oldEntryByIndex = Tree.prototype.entryByIndex, - oldEntryByName = Tree.prototype.entryByName, - oldGetEntry = Tree.prototype.getEntry; +var git = require("../"); +var Tree = git.Tree; +var Treebuilder = git.Treebuilder; +var Diff = git.Diff; +var events = require("events"); /** * Diff two trees @@ -13,8 +10,14 @@ var oldEntryByIndex = Tree.prototype.entryByIndex, * @param {Function} callback * @return {DiffList} */ -Tree.prototype.diff = function(that, callback) { - this.diffTree(this.repo, that, null, callback); +Tree.prototype.diff = function(tree, callback) { + return Diff.treeToTree(this.repo, tree, this, null).then(function(diff) { + if (typeof callback === "function") { + callback(null, diff); + } + + return diff; + }, callback); }; /** @@ -24,7 +27,7 @@ Tree.prototype.diff = function(that, callback) { * @return {TreeEntry} */ Tree.prototype.entryByIndex = function(i) { - var entry = oldEntryByIndex.call(this, i); + var entry = this._entryByIndex(i); entry.parent = this; return entry; }; @@ -36,7 +39,7 @@ Tree.prototype.entryByIndex = function(i) { * @return {TreeEntry} */ Tree.prototype.entryByName = function(name) { - var entry = oldEntryByName.call(this, name); + var entry = this.entryByname(name); entry.parent = this; return entry; }; @@ -49,15 +52,16 @@ Tree.prototype.entryByName = function(name) { * @return {TreeEntry} */ Tree.prototype.getEntry = function(path, callback) { - // FIXME: this method ought to implement the recursion directly, rather than - // rely on oldGetEntry, in order to ensure that `parent` pointers are direct. - var self = this; - oldGetEntry.call(this, path, function(error, entry) { - if (error) return callback(error); + var tree = this; + + return this.entryByPath(path).then(function(entry) { + entry.parent = tree; - entry.parent = self; - entry.path = function() { return path }; - callback(null, entry); + if (typeof callback === "function") { + callback(null, entry); + } + + return entry; }); }; @@ -66,31 +70,33 @@ Tree.prototype.getEntry = function(path, callback) { * @return {[TreeEntry]} an array of TreeEntrys */ Tree.prototype.entries = function() { - var size = this.size(), - result = []; + var size = this.entryCount(); + var result = []; + for (var i = 0; i < size; i++) { result.push(this.entryByIndex(i)); } + return result; }; /** - * Recursively walk the tree in breadth-first order. Fires an event for each entry. + * Recursively walk the tree in breadth-first order. Fires an event for each + * entry. * * @fires Tree#entry * @fires Tree#end * - * @param {Boolean} [blobsOnly = true] True to emit only blob & blob executable entries. + * @param {Boolean} [blobsOnly = true] True to emit only blob & blob executable + * entries. * * @return {EventEmitter} */ Tree.prototype.walk = function(blobsOnly) { - if (typeof blobsOnly == 'undefined') blobsOnly = true; + blobsOnly = typeof blobsOnly === "boolean" ? blobsOnly : true; - var self = this, - event = new events.EventEmitter(), - entries = [], - errors = []; + var self = this; + var event = new events.EventEmitter(); var total = 1; @@ -98,11 +104,14 @@ Tree.prototype.walk = function(blobsOnly) { // the recursive call to `entry.getTree(bfs)` function bfs(error, tree) { total--; - if (error) return errors.push(error); - tree.entries().forEach(function (entry) { + if (error) { + return event.emit("error", error); + } + var entries = tree.entries(); + entries.forEach(function (entry, entryIndex) { if (!blobsOnly || entry.isFile()) { - event.emit('entry', entry); + event.emit("entry", entry); entries.push(entry); } @@ -111,8 +120,10 @@ Tree.prototype.walk = function(blobsOnly) { entry.getTree(bfs); } }); - if (total === 0) - event.emit('end', errors.length ? errors : null, entries); + + if (total === 0) { + event.emit("end", entries); + } } event.start = function() { @@ -127,17 +138,20 @@ Tree.prototype.walk = function(blobsOnly) { * @return {String} */ Tree.prototype.path = function(blobsOnly) { - return this.entry ? this.entry.path() : ''; + return this.entry ? this.entry.path() : ""; }; /** * Make builder. This is helpful for modifying trees. - * @return {TreeBuilder} + * @return {Treebuilder} */ -var oldBuilder = Tree.prototype.builder; Tree.prototype.builder = function() { - var builder = oldBuilder.call(this); + var builder = Treebuilder.create(this); + builder.root = builder; builder.repo = this.repo; + return builder; }; + +module.exports = Tree; diff --git a/lib/tree_builder.js b/lib/tree_builder.js deleted file mode 100644 index c3570c14c..000000000 --- a/lib/tree_builder.js +++ /dev/null @@ -1,144 +0,0 @@ -var git = require('../'), - TreeBuilder = git.TreeBuilder, - TreeEntry = git.TreeEntry, - path = require('path'); - -var oldInsert = TreeBuilder.prototype.insert; - -/** - * Insert an object into this tree by oid - * - * @param {String} filename - * @param {Oid} oid - * @param {Number} filemode - */ -TreeBuilder.prototype.insert = function(filename, oid, filemode) { - if (!this.insertions) this.insertions = []; - - this.insertions.push([filename, oid, filemode]); -}; - -/** - * Insert a blob into this tree - * - * @param {String} filename - * @param {Blob} blob - * @param {Boolean} isExecutable - */ -TreeBuilder.prototype.insertBlob = function(filename, blob, isExecutable) { - if (!this.blobs) this.blobs = []; - - this.blobs.push([filename, blob, isExecutable ? TreeEntry.FileMode.Executable : TreeEntry.FileMode.Blob]); -}; - -var oldWrite = TreeBuilder.prototype.write; - -/** - * Write this tree to the repo. - * - * @param {Function} callback - */ -TreeBuilder.prototype.write = function(callback) { - var self = this; - this.doInsertions(function(error) { - if (error) return callback(error); - - if (self.builders && self.builders.length) { - writeNextLevel(self.repo, self.builders, function(error, previousName, previousTreeId) { - if (previousName && previousTreeId) { - oldInsert.call(self, previousName, previousTreeId, TreeEntry.FileMode.Tree); - } - oldWrite.call(self, self.repo, callback); - }); - } else { - oldWrite.call(self, self.repo, callback); - } - }) -}; - -TreeBuilder.prototype.doInsertions = function(callback) { - var self = this; - - this.createBlobs(function(error) { - if (error) return callback(error); - - self.doOidInsertions(callback); - }) -}; - -TreeBuilder.prototype.createBlobs = function(callback) { - if (!this.blobs || !this.blobs.length) return callback(); - - var self = this, - data = this.blobs.pop(), - path = data[0], buffer = data[1], filemode = data[2]; - - this.repo.createBlobFromBuffer(buffer, function(error, blobId) { - if (error) return callback(error); - - self.insert(path, blobId, filemode); - self.createBlobs(callback); - }); -} - -TreeBuilder.prototype.doOidInsertions = function(callback) { - if (!this.insertions || !this.insertions.length) return callback(); - - var self = this, - data = this.insertions.pop(), - filename = data[0], oid = data[1], filemode = data[2], - parts = filename.split(path.sep), - pathParts = parts.slice(0, parts.length - 1), - filename = parts[parts.length - 1]; - - insertOneLevel(this, pathParts, function(error, builder) { - if (error) return callback(error); - oldInsert.call(builder, filename, oid, filemode); - self.doOidInsertions(callback); - }); -}; - -function writeNextLevel(repo, builders, callback, previousName, previousTreeId) { - var builder = builders.pop(); - if (!builder) return callback(null, previousName, previousTreeId); - - if (previousName && previousTreeId) { - oldInsert.call(builder, previousName, previousTreeId, TreeEntry.FileMode.Tree); - } - oldWrite.call(builder, repo, function(error, previousTreeId) { - if (error) return callback(error); - - previousName = builder.name; - writeNextLevel(repo, builders, callback, previousName, previousTreeId); - }); -} - -function insertOneLevel(builder, parts, callback) { - if (!parts.length) return callback(null, builder); - - var part = parts[0], rest = parts.slice(1, parts.length); - if (!part) return insertOneLevel(builder, rest, callback); - - if (!builder.root.builders) builder.root.builders = []; - var entry = builder.get(part); - if (entry) { - if (!entry.isTree()) return callback("Invalid path part " + part); - entry.parent = builder; - - entry.getTree(function(error, tree) { - if (error) return callback(error); - - var next = tree.builder(); - next.name = part; - next.root = builder.root; - builder.root.builders.push(next); - insertOneLevel(next, rest, callback); - }); - } else { - var next = TreeBuilder.create(); - next.name = part; - next.root = builder.root; - builder.root.builders.push(next); - insertOneLevel(next, rest, callback); - } -} \ No newline at end of file diff --git a/lib/tree_entry.js b/lib/tree_entry.js index 02f29b315..0d926c4db 100644 --- a/lib/tree_entry.js +++ b/lib/tree_entry.js @@ -1,29 +1,16 @@ -var git = require('../'), - TreeEntry = git.TreeEntry, - path = require('path'); +var path = require("path"); +var NodeGit = require("../"); -/** - * Refer to vendor/libgit2/include/git2/types.h for filemode definitions. - * - * @readonly - * @enum {Integer} - */ -TreeEntry.FileMode = { - /** 0000000 */ New: 0, - /** 0040000 */ Tree: 16384, - /** 0100644 */ Blob: 33188, - /** 0100755 */ Executable: 33261, - /** 0120000 */ Link: 40960, - /** 0160000 */ Commit: 57344 -}; +var Tree = NodeGit.Tree; +var TreeEntry = NodeGit.TreeEntry; /** * Is this TreeEntry a blob? (i.e., a file) * @return {Boolean} */ TreeEntry.prototype.isFile = function() { - return this.filemode() === TreeEntry.FileMode.Blob || - this.filemode() === TreeEntry.FileMode.Executable; + return this.attr() === TreeEntry.FILEMODE.BLOB || + this.attr() === TreeEntry.FILEMODE.EXECUTABLE; }; /** @@ -31,7 +18,7 @@ TreeEntry.prototype.isFile = function() { * @return {Boolean} */ TreeEntry.prototype.isTree = function() { - return this.filemode() === TreeEntry.FileMode.Tree; + return this.attr() === TreeEntry.FILEMODE.TREE; }; /** @@ -51,7 +38,7 @@ TreeEntry.prototype.isBlob = TreeEntry.prototype.isFile; * @return {String} */ TreeEntry.prototype.sha = function() { - return this.oid().sha(); + return this.oid().toString(); }; /** @@ -59,21 +46,25 @@ TreeEntry.prototype.sha = function() { * @return {Tree} */ TreeEntry.prototype.getTree = function(callback) { - var self = this; - this.parent.repo.getTree(this.oid(), function(error, tree) { - if (error) return callback(error); + var entry = this; + + return this.parent.repo.getTree(this.oid()).then(function(tree) { + tree.entry = entry; - tree.entry = self; - callback(null, tree); - }); + if (typeof callback === "function") { + callback(null, tree); + } + + return tree; + }, callback); }; /** * Retrieve the tree for this entry. Make sure to call `isTree` first! * @return {Blob} */ -TreeEntry.prototype.getBlob = function(callback) { - this.parent.repo.getBlob(this.oid(), callback); +TreeEntry.prototype.getBlob = function() { + return this.parent.repo.getBlob(this.oid()); }; /** @@ -81,7 +72,7 @@ TreeEntry.prototype.getBlob = function(callback) { * @return {String} */ TreeEntry.prototype.path = function(callback) { - return path.join(this.parent.path(), this.name()); + return path.join(this.parent.path(), this.filename()); }; /** @@ -90,3 +81,9 @@ TreeEntry.prototype.path = function(callback) { TreeEntry.prototype.toString = function() { return this.path(); }; + +TreeEntry.prototype.oid = function() { + return Tree.entryId(this).toString(); +}; + +module.exports = TreeEntry; diff --git a/lib/util.js b/lib/util.js deleted file mode 100644 index 096a34291..000000000 --- a/lib/util.js +++ /dev/null @@ -1,25 +0,0 @@ -var git = require('../'); - -exports.makeSafe = function(object, key) { - var oldFn = object[key]; - object[key] = function() { - try { - oldFn.apply(this, arguments); - } catch (e) { - var callback = arguments[arguments.length - 1]; - callback(e); - } - }; -}; - -exports.normalizeOid = function(object, key) { - var oldFn = object[key]; - object[key] = function() { - var oid = arguments[0]; - if (typeof oid === 'string') oid = git.Oid.fromString(oid); - var newArguments = [oid]; - for (var i = 1; i < arguments.length; i++) - newArguments[i] = arguments[i]; - oldFn.apply(this, newArguments); - }; -}; diff --git a/lib/util/normalize_oid.js b/lib/util/normalize_oid.js new file mode 100644 index 000000000..f08efcc07 --- /dev/null +++ b/lib/util/normalize_oid.js @@ -0,0 +1,18 @@ +var NodeGit = require("../../"); + +/** + * Normalize an identifier to always be an OID instance. + * + * @param {String, Object} oid - The oid string or instance. + * @return {Object} An Oid instance. + */ +function normalizeOid(oid) { + try { + return typeof oid === "string" ? NodeGit.Oid.fromString(oid) : oid; + } + catch (ex) { + return null; + } +} + +module.exports = normalizeOid; diff --git a/lib/util/normalize_options.js b/lib/util/normalize_options.js new file mode 100644 index 000000000..c0c4a0718 --- /dev/null +++ b/lib/util/normalize_options.js @@ -0,0 +1,21 @@ +/** + * Normalize an object to match a struct. + * + * @param {String, Object} oid - The oid string or instance. + * @return {Object} An Oid instance. + */ +function normalizeOptions(options, Ctor) { + var instance = options instanceof Ctor ? options : new Ctor(); + + if (!options) { + return null; + } + + Object.keys(options).forEach(function(key) { + instance[key] = options[key]; + }); + + return instance; +} + +module.exports = normalizeOptions; diff --git a/package.json b/package.json index 3853877f5..c92d421f2 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,24 @@ { "name": "nodegit", "description": "Node.js libgit2 asynchronous native bindings", - "version": "0.1.4", - "libgit2": "a50086d174658914d4d6462afbc83b02825b1f5b", - "homepage": "https://github.com/tbranyen/nodegit", + "version": "0.2.0", + "libgit2": { + "sha": "4af08d9f69f151f6362df51d7d7f41527e2af05c", + "version": "0.21.2" + }, + "libssh2": { + "url": "http://www.libssh2.org/download/libssh2-1.4.3.tar.gz", + "version": "1.4.3" + }, + "http_parser": { + "url": "https://github.com/joyent/http-parser/archive/v2.3.tar.gz", + "version": "2.3.0", + "0.10": { + "url": "https://github.com/joyent/http-parser/archive/v2.0.tar.gz", + "version": "2.0.0" + } + }, + "homepage": "http://nodegit.org", "keywords": [ "libgit2", "git2", @@ -11,17 +26,27 @@ "native" ], "license": "MIT", - "author": "Tim Branyen (http://twitter.com/tbranyen)", + "author": "Tim Branyen (@tbranyen)", "contributors": [ { "name": "Michael Robinson", "email": "mike@pagesofinterest.net" + }, + { + "name": "Nick Kallen" + }, + { + "name": "John Haley", + "email": "johnhaley81@gmail.com" + }, + { + "name": "Max Korp" } ], - "main": "index.js", + "main": "lib/nodegit.js", "repository": { "type": "git", - "url": "git://github.com/tbranyen/nodegit.git" + "url": "git://github.com/nodegit/nodegit.git" }, "directories": { "build": "./build", @@ -34,21 +59,27 @@ "node-pre-gyp" ], "dependencies": { - "fs-extra": "~0.9.1", - "nan": "~1.2.0", - "node-gyp": "~0.13.1", - "node-pre-gyp": "~0.5.16", + "combyne": "~0.6.2", + "fs-extra": "^0.12.0", + "lodash": "^2.4.1", + "nan": "~1.3.0", + "node-gyp": "~1.0.2", + "node-pre-gyp": "~0.5.27", + "nodegit-promise": "~1.0.0", + "promise": "~6.0.0", + "promisify-node": "~0.1.2", "q": "~1.0.1", - "request": "~2.36.0", + "request": "~2.45.0", "rimraf": "~2.2.8", - "tar": "~0.1.19", + "tar": "~1.0.1", "which": "~1.0.5" }, "devDependencies": { "async": "~0.9.0", - "aws-sdk": "~2.0.0-rc.20", - "ejs": "~1.0.0", - "jshint": "~2.5.1", + "aws-sdk": "~2.0.18", + "istanbul": "~0.3.2", + "jshint": "~2.5.6", + "mocha": "~1.21.4", "nodeunit": "~0.9.0" }, "binary": { @@ -57,10 +88,14 @@ "host": "https://s3.amazonaws.com/nodegit/nodegit/" }, "scripts": { - "lint": "jshint src", - "install": "node install.js", - "test": "cd test && nodeunit nodegit.js", - "codegen": "node build/codegen/generate.js", - "publish": "node-pre-gyp package && node-pre-gyp publish" + "lint": "jshint lib test/tests", + "cov": "node test", + "mocha": "mocha test/runner test/tests", + "test": "npm run lint && npm run cov", + "missing-tests": "node generate/missing-tests", + "publish": "node-pre-gyp package && node-pre-gyp publish", + "generate": "node generate/setup && node generate", + "install": "npm run generate && node install", + "rebuild": "BUILD_ONLY=true npm run generate && node-gyp configure build" } -} \ No newline at end of file +} diff --git a/src/base.cc b/src/base.cc deleted file mode 100755 index 940be289f..000000000 --- a/src/base.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013, Tim Branyen @tbranyen - * @author Michael Robinson @codeofinterest - * - * Dual licensed under the MIT and GPL licenses. - */ - -#include -#include - -#include "git2.h" - -#include "../include/wrapper.h" -#include "../include/reference.h" -#include "../include/signature.h" -#include "../include/time.h" -#include "../include/blob.h" -#include "../include/repo.h" -#include "../include/oid.h" -#include "../include/object.h" -#include "../include/commit.h" -#include "../include/revwalk.h" -#include "../include/tree.h" -#include "../include/tree_entry.h" -#include "../include/diff_find_options.h" -#include "../include/diff_options.h" -#include "../include/diff_list.h" -#include "../include/diff_range.h" -#include "../include/diff_file.h" -#include "../include/patch.h" -#include "../include/delta.h" -#include "../include/threads.h" -#include "../include/index.h" -#include "../include/index_entry.h" -#include "../include/index_time.h" -#include "../include/tag.h" -#include "../include/refdb.h" -#include "../include/odb_object.h" -#include "../include/odb.h" -#include "../include/submodule.h" -#include "../include/tree_builder.h" -#include "../include/remote.h" -#include "../include/clone_options.h" - -extern "C" void init(Handle target) { - NanScope(); - - Wrapper::Initialize(target); - - GitReference::Initialize(target); - GitIndex::Initialize(target); - GitIndexEntry::Initialize(target); - GitIndexTime::Initialize(target); - GitTag::Initialize(target); - GitSignature::Initialize(target); - GitTime::Initialize(target); - GitBlob::Initialize(target); - GitOid::Initialize(target); - GitObject::Initialize(target); - GitRepo::Initialize(target); - GitCommit::Initialize(target); - GitRevWalk::Initialize(target); - GitRefDb::Initialize(target); - GitOdb::Initialize(target); - GitOdbObject::Initialize(target); - GitSubmodule::Initialize(target); - - GitTree::Initialize(target); - GitTreeEntry::Initialize(target); - GitTreeBuilder::Initialize(target); - - GitDiffRange::Initialize(target); - GitDiffFindOptions::Initialize(target); - GitDiffOptions::Initialize(target); - GitDiffList::Initialize(target); - GitPatch::Initialize(target); - GitDiffFile::Initialize(target); - GitDelta::Initialize(target); - - GitRemote::Initialize(target); - GitCloneOptions::Initialize(target); - - GitThreads::Initialize(target); - -} - -NODE_MODULE(nodegit, init) diff --git a/src/blob.cc b/src/blob.cc deleted file mode 100755 index 3ffbbb9ce..000000000 --- a/src/blob.cc +++ /dev/null @@ -1,145 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/blob.h" -#include "../include/repo.h" -#include "../include/oid.h" -#include "../include/wrapper.h" -#include "node_buffer.h" - -using namespace v8; -using namespace node; - -GitBlob::GitBlob(git_blob *raw) { - this->raw = raw; -} - -GitBlob::~GitBlob() { - git_blob_free(this->raw); -} - -void GitBlob::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Blob")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "content", Content); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "isBinary", IsBinary); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Blob"), _constructor_template); -} - -NAN_METHOD(GitBlob::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_blob is required."); - } - GitBlob* object = new GitBlob(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitBlob::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitBlob::constructor_template)->NewInstance(1, argv)); -} - -git_blob *GitBlob::GetValue() { - return this->raw; -} - - -/** - * @return {Oid} result - */ -NAN_METHOD(GitBlob::Oid) { - NanScope(); - - - const git_oid * result = git_blob_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Wrapper} result - */ -NAN_METHOD(GitBlob::Content) { - NanScope(); - - - const void * result = git_blob_rawcontent( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - to = Wrapper::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitBlob::Size) { - NanScope(); - - - git_off_t result = git_blob_rawsize( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Boolean} result - */ -NAN_METHOD(GitBlob::IsBinary) { - NanScope(); - - - int result = git_blob_is_binary( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -Persistent GitBlob::constructor_template; diff --git a/src/branch.cc b/src/branch.cc deleted file mode 100644 index 5e9a3b340..000000000 --- a/src/branch.cc +++ /dev/null @@ -1,535 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/branch.h" - -using namespace v8; -using namespace node; - -Branch::Branch(git_branch *raw) { - this->raw = raw; -} - -Branch::~Branch() { - git_branch_free(this->raw); -} - -void Branch::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Branch")); - - NODE_SET_METHOD(tpl, "create", Create); - NODE_SET_METHOD(tpl, "delete", Delete); - NODE_SET_METHOD(tpl, "foreach", Foreach); - NODE_SET_METHOD(tpl, "move", Move); - NODE_SET_METHOD(tpl, "lookup", Lookup); - NODE_SET_METHOD(tpl, "name", Name); - NODE_SET_METHOD(tpl, "upstream", Upstream); - NODE_SET_METHOD(tpl, "setUpstream", SetUpstream); - NODE_SET_METHOD(tpl, "upstreamName", UpstreamName); - NODE_SET_METHOD(tpl, "isHead", IsHead); - NODE_SET_METHOD(tpl, "remoteName", RemoteName); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Branch"), _constructor_template); -} - -NAN_METHOD(Branch::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_branch is required."); - } - Branch* object = new Branch(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle Branch::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(Branch::constructor_template)->NewInstance(1, argv)); -} - -git_branch *Branch::GetValue() { - return this->raw; -} - - -/** - * @param {Repository} repo - * @param {String} branch_name - * @param {Commit} target - * @param {Number} force - * @return {Reference} out - */ -NAN_METHOD(Branch::Create) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String branch_name is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("Commit target is required."); - } - if (args.Length() == 3 || !args[3]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - git_reference * out = 0; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - const char * from_branch_name; - String::Utf8Value branch_name(args[1]->ToString()); - from_branch_name = strdup(*branch_name); - const git_commit * from_target; - from_target = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - int from_force; - from_force = (int) args[3]->ToInt32()->Value(); - - int result = git_branch_create( - &out - , from_repo - , from_branch_name - , from_target - , from_force - ); - free((void *)from_branch_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Reference} branch - */ -NAN_METHOD(Branch::Delete) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Reference branch is required."); - } - - git_reference * from_branch; - from_branch = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_branch_delete( - from_branch - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {Repository} repo - * @param {Number} list_flags - * @param {BranchForeachCb} branch_cb - * @param {void} payload - */ -NAN_METHOD(Branch::Foreach) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 1 || !args[1]->IsUint32()) { - return NanThrowError("Number list_flags is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("BranchForeachCb branch_cb is required."); - } - if (args.Length() == 3 || !args[3]->IsObject()) { - return NanThrowError("void payload is required."); - } - - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - unsigned int from_list_flags; - from_list_flags = (unsigned int) args[1]->ToUint32()->Value(); - git_branch_foreach_cb from_branch_cb; - from_branch_cb = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - void * from_payload; - from_payload = ObjectWrap::Unwrap(args[3]->ToObject())->GetValue(); - - int result = git_branch_foreach( - from_repo - , from_list_flags - , from_branch_cb - , from_payload - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {Reference} branch - * @param {String} new_branch_name - * @param {Number} force - * @return {Reference} out - */ -NAN_METHOD(Branch::Move) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Reference branch is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String new_branch_name is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - git_reference * out = 0; - git_reference * from_branch; - from_branch = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - const char * from_new_branch_name; - String::Utf8Value new_branch_name(args[1]->ToString()); - from_new_branch_name = strdup(*new_branch_name); - int from_force; - from_force = (int) args[2]->ToInt32()->Value(); - - int result = git_branch_move( - &out - , from_branch - , from_new_branch_name - , from_force - ); - free((void *)from_new_branch_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Repository} repo - * @param {String} branch_name - * @param {BranchT} branch_type - * @return {Reference} out - */ -NAN_METHOD(Branch::Lookup) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String branch_name is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("BranchT branch_type is required."); - } - - git_reference * out = 0; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - const char * from_branch_name; - String::Utf8Value branch_name(args[1]->ToString()); - from_branch_name = strdup(*branch_name); - git_branch_t from_branch_type; - from_branch_type = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - - int result = git_branch_lookup( - &out - , from_repo - , from_branch_name - , from_branch_type - ); - free((void *)from_branch_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Reference} ref - * @return {String} out - */ -NAN_METHOD(Branch::Name) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Reference ref is required."); - } - - const char * out = 0; - git_reference * from_ref; - from_ref = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_branch_name( - &out - , from_ref - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - to = NanNew(out); - NanReturnValue(to); -} - -/** - * @param {Reference} branch - * @return {Reference} out - */ -NAN_METHOD(Branch::Upstream) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Reference branch is required."); - } - - git_reference * out = 0; - git_reference * from_branch; - from_branch = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_branch_upstream( - &out - , from_branch - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Reference} branch - * @param {String} upstream_name - */ -NAN_METHOD(Branch::SetUpstream) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Reference branch is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String upstream_name is required."); - } - - git_reference * from_branch; - from_branch = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - const char * from_upstream_name; - String::Utf8Value upstream_name(args[1]->ToString()); - from_upstream_name = strdup(*upstream_name); - - int result = git_branch_set_upstream( - from_branch - , from_upstream_name - ); - free((void *)from_upstream_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} tracking_branch_name_out - * @param {Number} buffer_size - * @param {Repository} repo - * @param {String} canonical_branch_name - */ -NAN_METHOD(Branch::UpstreamName) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String tracking_branch_name_out is required."); - } - if (args.Length() == 1 || !args[1]->IsUint32()) { - return NanThrowError("Number buffer_size is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 3 || !args[3]->IsString()) { - return NanThrowError("String canonical_branch_name is required."); - } - - char * from_tracking_branch_name_out; - String::Utf8Value tracking_branch_name_out(args[0]->ToString()); - from_tracking_branch_name_out = strdup(*tracking_branch_name_out); - size_t from_buffer_size; - from_buffer_size = (size_t) args[1]->ToUint32()->Value(); - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - const char * from_canonical_branch_name; - String::Utf8Value canonical_branch_name(args[3]->ToString()); - from_canonical_branch_name = strdup(*canonical_branch_name); - - int result = git_branch_upstream_name( - from_tracking_branch_name_out - , from_buffer_size - , from_repo - , from_canonical_branch_name - ); - free((void *)from_tracking_branch_name_out); - free((void *)from_canonical_branch_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {Reference} branch - */ -NAN_METHOD(Branch::IsHead) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Reference branch is required."); - } - - git_reference * from_branch; - from_branch = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_branch_is_head( - from_branch - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} remote_name_out - * @param {Number} buffer_size - * @param {Repository} repo - * @param {String} canonical_branch_name - */ -NAN_METHOD(Branch::RemoteName) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String remote_name_out is required."); - } - if (args.Length() == 1 || !args[1]->IsUint32()) { - return NanThrowError("Number buffer_size is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 3 || !args[3]->IsString()) { - return NanThrowError("String canonical_branch_name is required."); - } - - char * from_remote_name_out; - String::Utf8Value remote_name_out(args[0]->ToString()); - from_remote_name_out = strdup(*remote_name_out); - size_t from_buffer_size; - from_buffer_size = (size_t) args[1]->ToUint32()->Value(); - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - const char * from_canonical_branch_name; - String::Utf8Value canonical_branch_name(args[3]->ToString()); - from_canonical_branch_name = strdup(*canonical_branch_name); - - int result = git_branch_remote_name( - from_remote_name_out - , from_buffer_size - , from_repo - , from_canonical_branch_name - ); - free((void *)from_remote_name_out); - free((void *)from_canonical_branch_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -Persistent Branch::constructor_template; diff --git a/src/clone_options.cc b/src/clone_options.cc deleted file mode 100644 index c6812d369..000000000 --- a/src/clone_options.cc +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/clone_options.h" - -using namespace v8; -using namespace node; - -GitCloneOptions::GitCloneOptions(git_clone_options *raw) { - this->raw = raw; -} - -GitCloneOptions::~GitCloneOptions() { - free(this->raw); -} - -void GitCloneOptions::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("CloneOptions")); - - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("CloneOptions"), _constructor_template); -} - -NAN_METHOD(GitCloneOptions::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_clone_options is required."); - } - GitCloneOptions* object = new GitCloneOptions(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitCloneOptions::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitCloneOptions::constructor_template)->NewInstance(1, argv)); -} - -git_clone_options *GitCloneOptions::GetValue() { - return this->raw; -} - - -Persistent GitCloneOptions::constructor_template; diff --git a/src/commit.cc b/src/commit.cc deleted file mode 100755 index 0ccd639b3..000000000 --- a/src/commit.cc +++ /dev/null @@ -1,315 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/commit.h" -#include "../include/oid.h" -#include "../include/repo.h" -#include "../include/signature.h" -#include "../include/tree.h" - -using namespace v8; -using namespace node; - -GitCommit::GitCommit(git_commit *raw) { - this->raw = raw; -} - -GitCommit::~GitCommit() { - git_commit_free(this->raw); -} - -void GitCommit::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Commit")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "messageEncoding", MessageEncoding); - NODE_SET_PROTOTYPE_METHOD(tpl, "message", Message); - NODE_SET_PROTOTYPE_METHOD(tpl, "time", Time); - NODE_SET_PROTOTYPE_METHOD(tpl, "offset", Offset); - NODE_SET_PROTOTYPE_METHOD(tpl, "committer", Committer); - NODE_SET_PROTOTYPE_METHOD(tpl, "author", Author); - NODE_SET_PROTOTYPE_METHOD(tpl, "treeId", TreeId); - NODE_SET_PROTOTYPE_METHOD(tpl, "parentCount", ParentCount); - NODE_SET_PROTOTYPE_METHOD(tpl, "parentId", ParentId); - NODE_SET_PROTOTYPE_METHOD(tpl, "nthGenAncestor", NthGenAncestor); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Commit"), _constructor_template); -} - -NAN_METHOD(GitCommit::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_commit is required."); - } - GitCommit* object = new GitCommit(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitCommit::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitCommit::constructor_template)->NewInstance(1, argv)); -} - -git_commit *GitCommit::GetValue() { - return this->raw; -} - - -/** - * @return {Oid} result - */ -NAN_METHOD(GitCommit::Oid) { - NanScope(); - - - const git_oid * result = git_commit_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitCommit::MessageEncoding) { - NanScope(); - - - const char * result = git_commit_message_encoding( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitCommit::Message) { - NanScope(); - - - const char * result = git_commit_message( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitCommit::Time) { - NanScope(); - - - git_time_t result = git_commit_time( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitCommit::Offset) { - NanScope(); - - - int result = git_commit_time_offset( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Signature} result - */ -NAN_METHOD(GitCommit::Committer) { - NanScope(); - - - const git_signature * result = git_commit_committer( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_signature * )git_signature_dup(result); - } - if (result != NULL) { - to = GitSignature::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Signature} result - */ -NAN_METHOD(GitCommit::Author) { - NanScope(); - - - const git_signature * result = git_commit_author( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_signature * )git_signature_dup(result); - } - if (result != NULL) { - to = GitSignature::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitCommit::TreeId) { - NanScope(); - - - const git_oid * result = git_commit_tree_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitCommit::ParentCount) { - NanScope(); - - - unsigned int result = git_commit_parentcount( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @param {Number} n - * @return {Oid} result - */ -NAN_METHOD(GitCommit::ParentId) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number n is required."); - } - - unsigned int from_n; - from_n = (unsigned int) args[0]->ToUint32()->Value(); - - const git_oid * result = git_commit_parent_id( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_n - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Number} n - * @return {Commit} ancestor - */ -NAN_METHOD(GitCommit::NthGenAncestor) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number n is required."); - } - - git_commit * ancestor = 0; - unsigned int from_n; - from_n = (unsigned int) args[0]->ToUint32()->Value(); - - int result = git_commit_nth_gen_ancestor( - &ancestor - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_n - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (ancestor != NULL) { - to = GitCommit::New((void *)ancestor); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -Persistent GitCommit::constructor_template; diff --git a/src/delta.cc b/src/delta.cc deleted file mode 100644 index 1428032c2..000000000 --- a/src/delta.cc +++ /dev/null @@ -1,137 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/delta.h" -#include "../include/diff_file.h" - -using namespace v8; -using namespace node; - -GitDelta::GitDelta(git_diff_delta *raw) { - this->raw = raw; -} - -GitDelta::~GitDelta() { - free(this->raw); -} - -void GitDelta::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Delta")); - - - NODE_SET_PROTOTYPE_METHOD(tpl, "oldFile", OldFile); - NODE_SET_PROTOTYPE_METHOD(tpl, "newFile", NewFile); - NODE_SET_PROTOTYPE_METHOD(tpl, "status", Status); - NODE_SET_PROTOTYPE_METHOD(tpl, "similarity", Similarity); - NODE_SET_PROTOTYPE_METHOD(tpl, "flags", Flags); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Delta"), _constructor_template); -} - -NAN_METHOD(GitDelta::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_delta is required."); - } - GitDelta* object = new GitDelta(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitDelta::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitDelta::constructor_template)->NewInstance(1, argv)); -} - -git_diff_delta *GitDelta::GetValue() { - return this->raw; -} - - -NAN_METHOD(GitDelta::OldFile) { - NanScope(); - Handle to; - - git_diff_file *old_file = - &ObjectWrap::Unwrap(args.This())->GetValue()->old_file; - - if (old_file != NULL) { - old_file = (git_diff_file *)git_diff_file_dup(old_file); - } - if (old_file != NULL) { - to = GitDiffFile::New((void *)old_file); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitDelta::NewFile) { - NanScope(); - Handle to; - - git_diff_file *new_file = - &ObjectWrap::Unwrap(args.This())->GetValue()->new_file; - - if (new_file != NULL) { - new_file = (git_diff_file *)git_diff_file_dup(new_file); - } - if (new_file != NULL) { - to = GitDiffFile::New((void *)new_file); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitDelta::Status) { - NanScope(); - Handle to; - - git_delta_t status = - ObjectWrap::Unwrap(args.This())->GetValue()->status; - - to = NanNew(status); - NanReturnValue(to); -} - -NAN_METHOD(GitDelta::Similarity) { - NanScope(); - Handle to; - - uint32_t similarity = - ObjectWrap::Unwrap(args.This())->GetValue()->similarity; - - to = NanNew(similarity); - NanReturnValue(to); -} - -NAN_METHOD(GitDelta::Flags) { - NanScope(); - Handle to; - - uint32_t flags = - ObjectWrap::Unwrap(args.This())->GetValue()->flags; - - to = NanNew(flags); - NanReturnValue(to); -} - -Persistent GitDelta::constructor_template; diff --git a/src/diff.cc b/src/diff.cc deleted file mode 100644 index 70fad85b6..000000000 --- a/src/diff.cc +++ /dev/null @@ -1,518 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include -#include - -#include "git2.h" - -#include "../include/diff.h" - -#include "../include/functions/utilities.h" -#include "../include/functions/string.h" - -using namespace v8; -using namespace node; - -GitDiff::GitDiff(git_diff_list *raw) { - this->raw = raw; -} - -GitDiff::~GitDiff() { - git_diff_list_free(this->raw); -} - -void GitDiff::Initialize(Handle target) { - NanScope(); - - Local tpl = FunctionTemplate::New(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanSymbol("Diff")); - - NODE_SET_METHOD(tpl, "treeToTree", TreeToTree); - NODE_SET_METHOD(tpl, "treeToIndex", TreeToIndex); - NODE_SET_METHOD(tpl, "indexToWorkdir", IndexToWorkdir); - NODE_SET_METHOD(tpl, "treeToWorkdir", TreeToWorkdir); - NODE_SET_PROTOTYPE_METHOD(tpl, "merge", Merge); - NODE_SET_PROTOTYPE_METHOD(tpl, "findSimilar", FindSimilar); - NODE_SET_METHOD(tpl, "statusChar", StatusChar); - NODE_SET_PROTOTYPE_METHOD(tpl, "numDeltas", NumDeltas); - NODE_SET_METHOD(tpl, "numDeltasOfType", NumDeltasOfType); - NODE_SET_PROTOTYPE_METHOD(tpl, "getPatch", GetPatch); - - NanAssignPersistent(FunctionTemplate, constructor_template, tpl); - target->Set(String::NewSymbol("Diff"), tpl->GetFunction()); -} - -Handle GitDiff::New(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return ThrowException(Exception::Error(String::New("git_diff_list is required."))); - } - - GitDiff* object = new GitDiff((git_diff_list *) External::Unwrap(args[0])); - object->Wrap(args.This()); - - return scope.Close(args.This()); -} - -git_diff_list *GitDiff::GetValue() { - return this->raw; -} - - -Handle GitDiff::TreeToTree(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Repository repo is required."))); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return ThrowException(Exception::Error(String::New("Tree old_tree is required."))); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return ThrowException(Exception::Error(String::New("Tree new_tree is required."))); - } - if (args.Length() == 3 || !args[3]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffOptions opts is required."))); - } - if (args.Length() == 4 || !args[4]->IsFunction()) { - return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); - } - - TreeToTreeBaton* baton = new TreeToTreeBaton; - baton->error = NULL; - baton->request.data = baton; - baton->repoReference = Persistent::New(args[0]); - baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->old_treeReference = Persistent::New(args[1]); - baton->old_tree = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->new_treeReference = Persistent::New(args[2]); - baton->new_tree = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - baton->optsReference = Persistent::New(args[3]); - baton->opts = ObjectWrap::Unwrap(args[3]->ToObject())->GetValue(); - baton->callback = Persistent::New(Local::Cast(args[4])); - - uv_queue_work(uv_default_loop(), &baton->request, TreeToTreeWork, (uv_after_work_cb)TreeToTreeAfterWork); - - return Undefined(); -} - -void GitDiff::TreeToTreeWork(uv_work_t *req) { - TreeToTreeBaton *baton = static_cast(req->data); - int diff = git_diff_tree_to_tree( - &baton->diff, - baton->repo, - baton->old_tree, - baton->new_tree, - baton->opts - ); - if (diff != GIT_OK) { - baton->error = giterr_last(); - } -} - -void GitDiff::TreeToTreeAfterWork(uv_work_t *req) { - HandleScope scope; - TreeToTreeBaton *baton = static_cast(req->data); - - TryCatch try_catch; - if (!baton->error) { - Handle argv[1] = { External::New(baton->diff) }; - Handle diff = GitDiffList::constructor_template->NewInstance(1, argv); - Handle argv2[2] = { - Local::New(Null()), - diff - }; - baton->callback->Call(Context::GetCurrent()->Global(), 2, argv2); - } else { - Handle argv2[1] = { - GitError::WrapError(baton->error) - }; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv2); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - baton->repoReference.Dispose(); - baton->old_treeReference.Dispose(); - baton->new_treeReference.Dispose(); - baton->optsReference.Dispose(); - baton->callback.Dispose(); - delete baton; -} - -Handle GitDiff::TreeToIndex(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Repository repo is required."))); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return ThrowException(Exception::Error(String::New("Tree old_tree is required."))); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return ThrowException(Exception::Error(String::New("Index index is required."))); - } - if (args.Length() == 3 || !args[3]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffOptions opts is required."))); - } - if (args.Length() == 4 || !args[4]->IsFunction()) { - return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); - } - - TreeToIndexBaton* baton = new TreeToIndexBaton; - baton->error = NULL; - baton->request.data = baton; - baton->repoReference = Persistent::New(args[0]); - baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->old_treeReference = Persistent::New(args[1]); - baton->old_tree = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->indexReference = Persistent::New(args[2]); - baton->index = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - baton->optsReference = Persistent::New(args[3]); - baton->opts = ObjectWrap::Unwrap(args[3]->ToObject())->GetValue(); - baton->callback = Persistent::New(Local::Cast(args[4])); - - uv_queue_work(uv_default_loop(), &baton->request, TreeToIndexWork, (uv_after_work_cb)TreeToIndexAfterWork); - - return Undefined(); -} - -void GitDiff::TreeToIndexWork(uv_work_t *req) { - TreeToIndexBaton *baton = static_cast(req->data); - int diff = git_diff_tree_to_index( - &baton->diff, - baton->repo, - baton->old_tree, - baton->index, - baton->opts - ); - if (diff != GIT_OK) { - baton->error = giterr_last(); - } -} - -void GitDiff::TreeToIndexAfterWork(uv_work_t *req) { - HandleScope scope; - TreeToIndexBaton *baton = static_cast(req->data); - - TryCatch try_catch; - if (!baton->error) { - Handle argv[1] = { External::New(baton->diff) }; - Handle diff = GitDiffList::constructor_template->NewInstance(1, argv); - Handle argv2[2] = { - Local::New(Null()), - diff - }; - baton->callback->Call(Context::GetCurrent()->Global(), 2, argv2); - } else { - Handle argv2[1] = { - GitError::WrapError(baton->error) - }; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv2); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - baton->repoReference.Dispose(); - baton->old_treeReference.Dispose(); - baton->indexReference.Dispose(); - baton->optsReference.Dispose(); - baton->callback.Dispose(); - delete baton; -} - -Handle GitDiff::IndexToWorkdir(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Repository repo is required."))); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return ThrowException(Exception::Error(String::New("Index index is required."))); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffOptions opts is required."))); - } - if (args.Length() == 3 || !args[3]->IsFunction()) { - return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); - } - - IndexToWorkdirBaton* baton = new IndexToWorkdirBaton; - baton->error = NULL; - baton->request.data = baton; - baton->repoReference = Persistent::New(args[0]); - baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->indexReference = Persistent::New(args[1]); - baton->index = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->optsReference = Persistent::New(args[2]); - baton->opts = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - baton->callback = Persistent::New(Local::Cast(args[3])); - - uv_queue_work(uv_default_loop(), &baton->request, IndexToWorkdirWork, (uv_after_work_cb)IndexToWorkdirAfterWork); - - return Undefined(); -} - -void GitDiff::IndexToWorkdirWork(uv_work_t *req) { - IndexToWorkdirBaton *baton = static_cast(req->data); - int diff = git_diff_index_to_workdir( - &baton->diff, - baton->repo, - baton->index, - baton->opts - ); - if (diff != GIT_OK) { - baton->error = giterr_last(); - } -} - -void GitDiff::IndexToWorkdirAfterWork(uv_work_t *req) { - HandleScope scope; - IndexToWorkdirBaton *baton = static_cast(req->data); - - TryCatch try_catch; - if (!baton->error) { - Handle argv[1] = { External::New(baton->diff) }; - Handle diff = GitDiffList::constructor_template->NewInstance(1, argv); - Handle argv2[2] = { - Local::New(Null()), - diff - }; - baton->callback->Call(Context::GetCurrent()->Global(), 2, argv2); - } else { - Handle argv2[1] = { - GitError::WrapError(baton->error) - }; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv2); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - baton->repoReference.Dispose(); - baton->indexReference.Dispose(); - baton->optsReference.Dispose(); - baton->callback.Dispose(); - delete baton; -} - -Handle GitDiff::TreeToWorkdir(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Repository repo is required."))); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return ThrowException(Exception::Error(String::New("Tree old_tree is required."))); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffOptions opts is required."))); - } - if (args.Length() == 3 || !args[3]->IsFunction()) { - return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); - } - - TreeToWorkdirBaton* baton = new TreeToWorkdirBaton; - baton->error = NULL; - baton->request.data = baton; - baton->repoReference = Persistent::New(args[0]); - baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->old_treeReference = Persistent::New(args[1]); - baton->old_tree = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->optsReference = Persistent::New(args[2]); - baton->opts = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - baton->callback = Persistent::New(Local::Cast(args[3])); - - uv_queue_work(uv_default_loop(), &baton->request, TreeToWorkdirWork, (uv_after_work_cb)TreeToWorkdirAfterWork); - - return Undefined(); -} - -void GitDiff::TreeToWorkdirWork(uv_work_t *req) { - TreeToWorkdirBaton *baton = static_cast(req->data); - int diff = git_diff_tree_to_workdir( - &baton->diff, - baton->repo, - baton->old_tree, - baton->opts - ); - if (diff != GIT_OK) { - baton->error = giterr_last(); - } -} - -void GitDiff::TreeToWorkdirAfterWork(uv_work_t *req) { - HandleScope scope; - TreeToWorkdirBaton *baton = static_cast(req->data); - - TryCatch try_catch; - if (!baton->error) { - Handle argv[1] = { External::New(baton->diff) }; - Handle diff = GitDiffList::constructor_template->NewInstance(1, argv); - Handle argv2[2] = { - Local::New(Null()), - diff - }; - baton->callback->Call(Context::GetCurrent()->Global(), 2, argv2); - } else { - Handle argv2[1] = { - GitError::WrapError(baton->error) - }; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv2); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - baton->repoReference.Dispose(); - baton->old_treeReference.Dispose(); - baton->optsReference.Dispose(); - baton->callback.Dispose(); - delete baton; -} - -Handle GitDiff::Merge(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffList from is required."))); - } - - int result = git_diff_merge( - - - ObjectWrap::Unwrap(args.This())->GetValue() -, - - ObjectWrap::Unwrap(args[0]->ToObject())->GetValue() - ); - - if (result != GIT_OK) { - return ThrowException(GitError::WrapError(giterr_last())); - } - - return scope.Close(Int32::New(result)); -} - -Handle GitDiff::FindSimilar(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffFindOptions options is required."))); - } - - int result = git_diff_find_similar( - - - ObjectWrap::Unwrap(args.This())->GetValue() -, - - ObjectWrap::Unwrap(args[0]->ToObject())->GetValue() - ); - - if (result != GIT_OK) { - return ThrowException(GitError::WrapError(giterr_last())); - } - - return scope.Close(Int32::New(result)); -} - -Handle GitDiff::StatusChar(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsInt32()) { - return ThrowException(Exception::Error(String::New("Number status is required."))); - } - - char result = git_diff_status_char( - - - (git_delta_t) args[0]->ToInt32()->Value() - ); - - - return scope.Close(String::New(result)); -} - -Handle GitDiff::NumDeltas(const Arguments& args) { - HandleScope scope; - - size_t result = git_diff_num_deltas( - - - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - - return scope.Close(Uint32::New(result)); -} - -Handle GitDiff::NumDeltasOfType(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffList diff is required."))); - } - - if (args.Length() == 1 || !args[1]->IsInt32()) { - return ThrowException(Exception::Error(String::New("Number type is required."))); - } - - size_t result = git_diff_num_deltas_of_type( - - - ObjectWrap::Unwrap(args[0]->ToObject())->GetValue() -, - - (git_delta_t) args[1]->ToInt32()->Value() - ); - - - return scope.Close(Uint32::New(result)); -} - -Handle GitDiff::GetPatch(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("DiffDelta delta_out is required."))); - } - - if (args.Length() == 1 || !args[1]->IsUint32()) { - return ThrowException(Exception::Error(String::New("Number idx is required."))); - } - git_diff_patch * patch_out; - - int result = git_diff_get_patch( - -& - patch_out -, -& - ObjectWrap::Unwrap(args[0]->ToObject())->GetValue() -, - - ObjectWrap::Unwrap(args.This())->GetValue() -, - - (size_t) args[1]->ToUint32()->Value() - ); - - if (result != GIT_OK) { - return ThrowException(GitError::WrapError(giterr_last())); - } - - // XXX need to copy object? - Handle argv[1] = { External::New((void *)patch_out) }; - return scope.Close(DiffPatch::constructor_template->NewInstance(1, argv)); -} - - -Persistent GitDiff::constructor_template; diff --git a/src/diff_file.cc b/src/diff_file.cc deleted file mode 100644 index b19711520..000000000 --- a/src/diff_file.cc +++ /dev/null @@ -1,130 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/diff_file.h" -#include "../include/oid.h" - -using namespace v8; -using namespace node; - -GitDiffFile::GitDiffFile(git_diff_file *raw) { - this->raw = raw; -} - -GitDiffFile::~GitDiffFile() { - free(this->raw); -} - -void GitDiffFile::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("DiffFile")); - - - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "path", Path); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "flags", Flags); - NODE_SET_PROTOTYPE_METHOD(tpl, "mode", Mode); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("DiffFile"), _constructor_template); -} - -NAN_METHOD(GitDiffFile::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_file is required."); - } - GitDiffFile* object = new GitDiffFile(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitDiffFile::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitDiffFile::constructor_template)->NewInstance(1, argv)); -} - -git_diff_file *GitDiffFile::GetValue() { - return this->raw; -} - - -NAN_METHOD(GitDiffFile::Oid) { - NanScope(); - Handle to; - - git_oid *oid = - &ObjectWrap::Unwrap(args.This())->GetValue()->oid; - - if (oid != NULL) { - oid = (git_oid *)git_oid_dup(oid); - } - if (oid != NULL) { - to = GitOid::New((void *)oid); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitDiffFile::Path) { - NanScope(); - Handle to; - - const char * path = - ObjectWrap::Unwrap(args.This())->GetValue()->path; - - to = NanNew(path); - NanReturnValue(to); -} - -NAN_METHOD(GitDiffFile::Size) { - NanScope(); - Handle to; - - git_off_t size = - ObjectWrap::Unwrap(args.This())->GetValue()->size; - - to = NanNew(size); - NanReturnValue(to); -} - -NAN_METHOD(GitDiffFile::Flags) { - NanScope(); - Handle to; - - uint32_t flags = - ObjectWrap::Unwrap(args.This())->GetValue()->flags; - - to = NanNew(flags); - NanReturnValue(to); -} - -NAN_METHOD(GitDiffFile::Mode) { - NanScope(); - Handle to; - - uint16_t mode = - ObjectWrap::Unwrap(args.This())->GetValue()->mode; - - to = NanNew(mode); - NanReturnValue(to); -} - -Persistent GitDiffFile::constructor_template; diff --git a/src/diff_find_options.cc b/src/diff_find_options.cc deleted file mode 100644 index 20421c3f1..000000000 --- a/src/diff_find_options.cc +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/diff_find_options.h" - -using namespace v8; -using namespace node; - -GitDiffFindOptions::GitDiffFindOptions(git_diff_find_options *raw) { - this->raw = raw; -} - -GitDiffFindOptions::~GitDiffFindOptions() { - free(this->raw); -} - -void GitDiffFindOptions::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("DiffFindOptions")); - - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("DiffFindOptions"), _constructor_template); -} - -NAN_METHOD(GitDiffFindOptions::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_find_options is required."); - } - GitDiffFindOptions* object = new GitDiffFindOptions(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitDiffFindOptions::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitDiffFindOptions::constructor_template)->NewInstance(1, argv)); -} - -git_diff_find_options *GitDiffFindOptions::GetValue() { - return this->raw; -} - - -Persistent GitDiffFindOptions::constructor_template; diff --git a/src/diff_list.cc b/src/diff_list.cc deleted file mode 100755 index 3a0985400..000000000 --- a/src/diff_list.cc +++ /dev/null @@ -1,225 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/diff_list.h" -#include "../include/diff_options.h" -#include "../include/diff_find_options.h" -#include "../include/repo.h" -#include "../include/tree.h" -#include "../include/index.h" -#include "../include/patch.h" -#include "../include/delta.h" - -using namespace v8; -using namespace node; - -GitDiffList::GitDiffList(git_diff_list *raw) { - this->raw = raw; -} - -GitDiffList::~GitDiffList() { - git_diff_list_free(this->raw); -} - -void GitDiffList::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("DiffList")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "merge", Merge); - NODE_SET_PROTOTYPE_METHOD(tpl, "findSimilar", FindSimilar); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_METHOD(tpl, "numDeltasOfType", NumDeltasOfType); - NODE_SET_PROTOTYPE_METHOD(tpl, "patch", Patch); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("DiffList"), _constructor_template); -} - -NAN_METHOD(GitDiffList::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_list is required."); - } - GitDiffList* object = new GitDiffList(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitDiffList::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitDiffList::constructor_template)->NewInstance(1, argv)); -} - -git_diff_list *GitDiffList::GetValue() { - return this->raw; -} - - -/** - * @param {DiffList} from - */ -NAN_METHOD(GitDiffList::Merge) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("DiffList from is required."); - } - - const git_diff_list * from_from; - from_from = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_diff_merge( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_from - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {DiffFindOptions} options - */ -NAN_METHOD(GitDiffList::FindSimilar) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("DiffFindOptions options is required."); - } - - git_diff_find_options * from_options; - from_options = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_diff_find_similar( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_options - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitDiffList::Size) { - NanScope(); - - - size_t result = git_diff_num_deltas( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @param {DiffList} diff - * @param {Number} type - * @return {Number} result - */ -NAN_METHOD(GitDiffList::NumDeltasOfType) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("DiffList diff is required."); - } - if (args.Length() == 1 || !args[1]->IsInt32()) { - return NanThrowError("Number type is required."); - } - - git_diff_list * from_diff; - from_diff = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - git_delta_t from_type; - from_type = (git_delta_t) args[1]->ToInt32()->Value(); - - size_t result = git_diff_num_deltas_of_type( - from_diff - , from_type - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @param {Number} idx - * @return {Patch} patch_out - * @return {Delta} delta_out - */ -NAN_METHOD(GitDiffList::Patch) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number idx is required."); - } - - git_diff_patch * patch_out = 0; - const git_diff_delta * delta_out = 0; - size_t from_idx; - from_idx = (size_t) args[0]->ToUint32()->Value(); - - int result = git_diff_get_patch( - &patch_out - , &delta_out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_idx - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle toReturn = NanNew(); - Handle to; - if (patch_out != NULL) { - to = GitPatch::New((void *)patch_out); - } else { - to = NanNull(); - } - toReturn->Set(NanNew("patch"), to); - - if (delta_out != NULL) { - delta_out = (const git_diff_delta * )git_diff_delta_dup(delta_out); - } - if (delta_out != NULL) { - to = GitDelta::New((void *)delta_out); - } else { - to = NanNull(); - } - toReturn->Set(NanNew("delta"), to); - - NanReturnValue(toReturn); -} - -Persistent GitDiffList::constructor_template; diff --git a/src/diff_options.cc b/src/diff_options.cc deleted file mode 100644 index 75a3bc129..000000000 --- a/src/diff_options.cc +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/diff_options.h" - -using namespace v8; -using namespace node; - -GitDiffOptions::GitDiffOptions(git_diff_options *raw) { - this->raw = raw; -} - -GitDiffOptions::~GitDiffOptions() { - free(this->raw); -} - -void GitDiffOptions::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("DiffOptions")); - - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("DiffOptions"), _constructor_template); -} - -NAN_METHOD(GitDiffOptions::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_options is required."); - } - GitDiffOptions* object = new GitDiffOptions(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitDiffOptions::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitDiffOptions::constructor_template)->NewInstance(1, argv)); -} - -git_diff_options *GitDiffOptions::GetValue() { - return this->raw; -} - - -Persistent GitDiffOptions::constructor_template; diff --git a/src/diff_range.cc b/src/diff_range.cc deleted file mode 100644 index 82c2b5fc4..000000000 --- a/src/diff_range.cc +++ /dev/null @@ -1,110 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/diff_range.h" - -using namespace v8; -using namespace node; - -GitDiffRange::GitDiffRange(git_diff_range *raw) { - this->raw = raw; -} - -GitDiffRange::~GitDiffRange() { - free(this->raw); -} - -void GitDiffRange::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("DiffRange")); - - - NODE_SET_PROTOTYPE_METHOD(tpl, "oldStart", OldStart); - NODE_SET_PROTOTYPE_METHOD(tpl, "oldLines", OldLines); - NODE_SET_PROTOTYPE_METHOD(tpl, "newStart", NewStart); - NODE_SET_PROTOTYPE_METHOD(tpl, "newLines", NewLines); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("DiffRange"), _constructor_template); -} - -NAN_METHOD(GitDiffRange::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_range is required."); - } - GitDiffRange* object = new GitDiffRange(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitDiffRange::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitDiffRange::constructor_template)->NewInstance(1, argv)); -} - -git_diff_range *GitDiffRange::GetValue() { - return this->raw; -} - - -NAN_METHOD(GitDiffRange::OldStart) { - NanScope(); - Handle to; - - int old_start = - ObjectWrap::Unwrap(args.This())->GetValue()->old_start; - - to = NanNew(old_start); - NanReturnValue(to); -} - -NAN_METHOD(GitDiffRange::OldLines) { - NanScope(); - Handle to; - - int old_lines = - ObjectWrap::Unwrap(args.This())->GetValue()->old_lines; - - to = NanNew(old_lines); - NanReturnValue(to); -} - -NAN_METHOD(GitDiffRange::NewStart) { - NanScope(); - Handle to; - - int new_start = - ObjectWrap::Unwrap(args.This())->GetValue()->new_start; - - to = NanNew(new_start); - NanReturnValue(to); -} - -NAN_METHOD(GitDiffRange::NewLines) { - NanScope(); - Handle to; - - int new_lines = - ObjectWrap::Unwrap(args.This())->GetValue()->new_lines; - - to = NanNew(new_lines); - NanReturnValue(to); -} - -Persistent GitDiffRange::constructor_template; diff --git a/src/index.cc b/src/index.cc deleted file mode 100644 index fc0e7a0c3..000000000 --- a/src/index.cc +++ /dev/null @@ -1,857 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/index.h" -#include "../include/oid.h" -#include "../include/repo.h" -#include "../include/tree.h" -#include "../include/diff_list.h" -#include "../include/diff_options.h" -#include "../include/index_entry.h" - -using namespace v8; -using namespace node; - -GitIndex::GitIndex(git_index *raw) { - this->raw = raw; -} - -GitIndex::~GitIndex() { - git_index_free(this->raw); -} - -void GitIndex::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Index")); - - NODE_SET_METHOD(tpl, "open", Open); - NODE_SET_PROTOTYPE_METHOD(tpl, "read", Read); - NODE_SET_PROTOTYPE_METHOD(tpl, "write", Write); - NODE_SET_PROTOTYPE_METHOD(tpl, "readTree", ReadTree); - NODE_SET_PROTOTYPE_METHOD(tpl, "writeTree", WriteTree); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "clear", Clear); - NODE_SET_PROTOTYPE_METHOD(tpl, "entry", Entry); - NODE_SET_PROTOTYPE_METHOD(tpl, "remove", Remove); - NODE_SET_PROTOTYPE_METHOD(tpl, "removeDirectory", RemoveDirectory); - NODE_SET_PROTOTYPE_METHOD(tpl, "addByPath", AddBypath); - NODE_SET_PROTOTYPE_METHOD(tpl, "removeByPath", RemoveBypath); - NODE_SET_PROTOTYPE_METHOD(tpl, "find", Find); - NODE_SET_PROTOTYPE_METHOD(tpl, "conflictRemove", ConflictRemove); - NODE_SET_PROTOTYPE_METHOD(tpl, "conflictCleanup", ConflictCleanup); - NODE_SET_PROTOTYPE_METHOD(tpl, "hasConflicts", HasConflicts); - NODE_SET_METHOD(tpl, "indexToWorkdir", IndexToWorkdir); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Index"), _constructor_template); -} - -NAN_METHOD(GitIndex::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_index is required."); - } - GitIndex* object = new GitIndex(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitIndex::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitIndex::constructor_template)->NewInstance(1, argv)); -} - -git_index *GitIndex::GetValue() { - return this->raw; -} - - -#include "../include/functions/copy.h" - -/** - * @param {String} index_path - * @param {Index} callback - */ -NAN_METHOD(GitIndex::Open) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String index_path is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - OpenBaton* baton = new OpenBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - const char * from_index_path; - String::Utf8Value index_path(args[0]->ToString()); - from_index_path = strdup(*index_path); - baton->index_path = from_index_path; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - OpenWorker *worker = new OpenWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("index_path", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::OpenWorker::Execute() { - int result = git_index_open( - &baton->out, - baton->index_path - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::OpenWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitIndex::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->index_path); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitIndex::Read) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ReadBaton* baton = new ReadBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->index = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - ReadWorker *worker = new ReadWorker(baton, callback); - worker->SaveToPersistent("index", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::ReadWorker::Execute() { - int result = git_index_read( - baton->index - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::ReadWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitIndex::Write) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - WriteBaton* baton = new WriteBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->index = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - WriteWorker *worker = new WriteWorker(baton, callback); - worker->SaveToPersistent("index", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::WriteWorker::Execute() { - int result = git_index_write( - baton->index - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::WriteWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Tree} tree - */ -NAN_METHOD(GitIndex::ReadTree) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Tree tree is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ReadTreeBaton* baton = new ReadTreeBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->index = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_tree * from_tree; - from_tree = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->tree = from_tree; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - ReadTreeWorker *worker = new ReadTreeWorker(baton, callback); - worker->SaveToPersistent("index", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("tree", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::ReadTreeWorker::Execute() { - int result = git_index_read_tree( - baton->index, - baton->tree - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::ReadTreeWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} callback - */ -NAN_METHOD(GitIndex::WriteTree) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - WriteTreeBaton* baton = new WriteTreeBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->out = (git_oid *)malloc(sizeof(git_oid )); - baton->index = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - WriteTreeWorker *worker = new WriteTreeWorker(baton, callback); - worker->SaveToPersistent("index", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::WriteTreeWorker::Execute() { - int result = git_index_write_tree( - baton->out, - baton->index - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::WriteTreeWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitOid::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->out); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitIndex::Size) { - NanScope(); - - - size_t result = git_index_entrycount( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - */ -NAN_METHOD(GitIndex::Clear) { - NanScope(); - - - git_index_clear( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - NanReturnUndefined(); -} - -/** - * @param {Number} n - * @return {IndexEntry} result - */ -NAN_METHOD(GitIndex::Entry) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number n is required."); - } - - size_t from_n; - from_n = (size_t) args[0]->ToUint32()->Value(); - - const git_index_entry * result = git_index_get_byindex( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_n - ); - - Handle to; - if (result != NULL) { - result = (const git_index_entry * )git_index_entry_dup(result); - } - if (result != NULL) { - to = GitIndexEntry::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} path - * @param {Number} stage - */ -NAN_METHOD(GitIndex::Remove) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - if (args.Length() == 1 || !args[1]->IsInt32()) { - return NanThrowError("Number stage is required."); - } - - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - int from_stage; - from_stage = (int) args[1]->ToInt32()->Value(); - - int result = git_index_remove( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_path - , from_stage - ); - free((void *)from_path); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} dir - * @param {Number} stage - */ -NAN_METHOD(GitIndex::RemoveDirectory) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String dir is required."); - } - if (args.Length() == 1 || !args[1]->IsInt32()) { - return NanThrowError("Number stage is required."); - } - - const char * from_dir; - String::Utf8Value dir(args[0]->ToString()); - from_dir = strdup(*dir); - int from_stage; - from_stage = (int) args[1]->ToInt32()->Value(); - - int result = git_index_remove_directory( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_dir - , from_stage - ); - free((void *)from_dir); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - * @param {String} path - */ -NAN_METHOD(GitIndex::AddBypath) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - AddBypathBaton* baton = new AddBypathBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->index = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - baton->path = from_path; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - AddBypathWorker *worker = new AddBypathWorker(baton, callback); - worker->SaveToPersistent("index", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("path", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::AddBypathWorker::Execute() { - int result = git_index_add_bypath( - baton->index, - baton->path - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::AddBypathWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->path); - delete baton; -} - -/** - * @param {String} path - */ -NAN_METHOD(GitIndex::RemoveBypath) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - - int result = git_index_remove_bypath( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_path - ); - free((void *)from_path); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} path - * @return {Number} at_pos - */ -NAN_METHOD(GitIndex::Find) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - size_t at_pos = 0; - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - - int result = git_index_find( - &at_pos - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_path - ); - free((void *)from_path); - - Handle to; - to = NanNew((uint32_t)at_pos); - NanReturnValue(to); -} - -/** - * @param {String} path - */ -NAN_METHOD(GitIndex::ConflictRemove) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - - int result = git_index_conflict_remove( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_path - ); - free((void *)from_path); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - */ -NAN_METHOD(GitIndex::ConflictCleanup) { - NanScope(); - - - git_index_conflict_cleanup( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - NanReturnUndefined(); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitIndex::HasConflicts) { - NanScope(); - - - int result = git_index_has_conflicts( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((int32_t)result); - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {Index} index - * @param {DiffOptions} opts - * @param {DiffList} callback - */ -NAN_METHOD(GitIndex::IndexToWorkdir) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - - if (args.Length() == 3 || !args[3]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - IndexToWorkdirBaton* baton = new IndexToWorkdirBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - git_index * from_index; - if (args[1]->IsObject()) { - from_index = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - } else { - from_index = 0; - } - baton->index = from_index; - const git_diff_options * from_opts; - if (args[2]->IsObject()) { - from_opts = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - } else { - from_opts = 0; - } - baton->opts = from_opts; - - NanCallback *callback = new NanCallback(Local::Cast(args[3])); - IndexToWorkdirWorker *worker = new IndexToWorkdirWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("index", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("opts", args[2]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitIndex::IndexToWorkdirWorker::Execute() { - int result = git_diff_index_to_workdir( - &baton->diff, - baton->repo, - baton->index, - baton->opts - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitIndex::IndexToWorkdirWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->diff != NULL) { - to = GitDiffList::New((void *)baton->diff); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -Persistent GitIndex::constructor_template; diff --git a/src/index_entry.cc b/src/index_entry.cc deleted file mode 100644 index 0fef443c1..000000000 --- a/src/index_entry.cc +++ /dev/null @@ -1,229 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/index_entry.h" -#include "../include/index_time.h" -#include "../include/oid.h" - -using namespace v8; -using namespace node; - -GitIndexEntry::GitIndexEntry(git_index_entry *raw) { - this->raw = raw; -} - -GitIndexEntry::~GitIndexEntry() { - free(this->raw); -} - -void GitIndexEntry::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("IndexEntry")); - - - NODE_SET_PROTOTYPE_METHOD(tpl, "ctime", Ctime); - NODE_SET_PROTOTYPE_METHOD(tpl, "mtime", Mtime); - NODE_SET_PROTOTYPE_METHOD(tpl, "dev", Dev); - NODE_SET_PROTOTYPE_METHOD(tpl, "ino", Ino); - NODE_SET_PROTOTYPE_METHOD(tpl, "mode", Mode); - NODE_SET_PROTOTYPE_METHOD(tpl, "uid", Uid); - NODE_SET_PROTOTYPE_METHOD(tpl, "gid", gid); - NODE_SET_PROTOTYPE_METHOD(tpl, "file_size", FileSize); - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "flags", Flags); - NODE_SET_PROTOTYPE_METHOD(tpl, "flags_extended", FlagsExtended); - NODE_SET_PROTOTYPE_METHOD(tpl, "path", Path); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("IndexEntry"), _constructor_template); -} - -NAN_METHOD(GitIndexEntry::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_index_entry is required."); - } - GitIndexEntry* object = new GitIndexEntry(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitIndexEntry::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitIndexEntry::constructor_template)->NewInstance(1, argv)); -} - -git_index_entry *GitIndexEntry::GetValue() { - return this->raw; -} - - -NAN_METHOD(GitIndexEntry::Ctime) { - NanScope(); - Handle to; - - git_index_time *ctime = - &ObjectWrap::Unwrap(args.This())->GetValue()->ctime; - - if (ctime != NULL) { - ctime = (git_index_time *)git_index_time_dup(ctime); - } - if (ctime != NULL) { - to = GitIndexTime::New((void *)ctime); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Mtime) { - NanScope(); - Handle to; - - git_index_time *mtime = - &ObjectWrap::Unwrap(args.This())->GetValue()->mtime; - - if (mtime != NULL) { - mtime = (git_index_time *)git_index_time_dup(mtime); - } - if (mtime != NULL) { - to = GitIndexTime::New((void *)mtime); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Dev) { - NanScope(); - Handle to; - - unsigned int dev = - ObjectWrap::Unwrap(args.This())->GetValue()->dev; - - to = NanNew((uint32_t)dev); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Ino) { - NanScope(); - Handle to; - - unsigned int ino = - ObjectWrap::Unwrap(args.This())->GetValue()->ino; - - to = NanNew((uint32_t)ino); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Mode) { - NanScope(); - Handle to; - - uint16_t mode = - ObjectWrap::Unwrap(args.This())->GetValue()->mode; - - to = NanNew(mode); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Uid) { - NanScope(); - Handle to; - - unsigned int uid = - ObjectWrap::Unwrap(args.This())->GetValue()->uid; - - to = NanNew((uint32_t)uid); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::gid) { - NanScope(); - Handle to; - - unsigned int gid = - ObjectWrap::Unwrap(args.This())->GetValue()->gid; - - to = NanNew((uint32_t)gid); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::FileSize) { - NanScope(); - Handle to; - - unsigned int file_size = - ObjectWrap::Unwrap(args.This())->GetValue()->file_size; - - to = NanNew((uint32_t)file_size); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Oid) { - NanScope(); - Handle to; - - git_oid *oid = - &ObjectWrap::Unwrap(args.This())->GetValue()->oid; - - if (oid != NULL) { - oid = (git_oid *)git_oid_dup(oid); - } - if (oid != NULL) { - to = GitOid::New((void *)oid); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Flags) { - NanScope(); - Handle to; - - uint16_t flags = - ObjectWrap::Unwrap(args.This())->GetValue()->flags; - - to = NanNew(flags); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::FlagsExtended) { - NanScope(); - Handle to; - - uint16_t flags_extended = - ObjectWrap::Unwrap(args.This())->GetValue()->flags_extended; - - to = NanNew(flags_extended); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexEntry::Path) { - NanScope(); - Handle to; - - char * path = - ObjectWrap::Unwrap(args.This())->GetValue()->path; - - to = NanNew(path); - NanReturnValue(to); -} - -Persistent GitIndexEntry::constructor_template; diff --git a/src/index_time.cc b/src/index_time.cc deleted file mode 100644 index 2da28c951..000000000 --- a/src/index_time.cc +++ /dev/null @@ -1,86 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/index_time.h" - -using namespace v8; -using namespace node; - -GitIndexTime::GitIndexTime(git_index_time *raw) { - this->raw = raw; -} - -GitIndexTime::~GitIndexTime() { - free(this->raw); -} - -void GitIndexTime::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("IndexTime")); - - - NODE_SET_PROTOTYPE_METHOD(tpl, "seconds", Seconds); - NODE_SET_PROTOTYPE_METHOD(tpl, "nanoseconds", Nanoseconds); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("IndexTime"), _constructor_template); -} - -NAN_METHOD(GitIndexTime::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_index_time is required."); - } - GitIndexTime* object = new GitIndexTime(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitIndexTime::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitIndexTime::constructor_template)->NewInstance(1, argv)); -} - -git_index_time *GitIndexTime::GetValue() { - return this->raw; -} - - -NAN_METHOD(GitIndexTime::Seconds) { - NanScope(); - Handle to; - - git_time_t seconds = - ObjectWrap::Unwrap(args.This())->GetValue()->seconds; - - to = NanNew((uint32_t)seconds); - NanReturnValue(to); -} - -NAN_METHOD(GitIndexTime::Nanoseconds) { - NanScope(); - Handle to; - - unsigned int nanoseconds = - ObjectWrap::Unwrap(args.This())->GetValue()->nanoseconds; - - to = NanNew((uint32_t)nanoseconds); - NanReturnValue(to); -} - -Persistent GitIndexTime::constructor_template; diff --git a/src/object.cc b/src/object.cc deleted file mode 100644 index 8a62b1300..000000000 --- a/src/object.cc +++ /dev/null @@ -1,187 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/object.h" -#include "../include/oid.h" -#include "../include/repo.h" - -using namespace v8; -using namespace node; - -GitObject::GitObject(git_object *raw) { - this->raw = raw; -} - -GitObject::~GitObject() { - git_object_free(this->raw); -} - -void GitObject::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Object")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "type", Type); - NODE_SET_PROTOTYPE_METHOD(tpl, "peel", Peel); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Object"), _constructor_template); -} - -NAN_METHOD(GitObject::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_object is required."); - } - GitObject* object = new GitObject(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitObject::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitObject::constructor_template)->NewInstance(1, argv)); -} - -git_object *GitObject::GetValue() { - return this->raw; -} - - -/** - * @return {Oid} result - */ -NAN_METHOD(GitObject::Oid) { - NanScope(); - - - const git_oid * result = git_object_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitObject::Type) { - NanScope(); - - - git_otype result = git_object_type( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Number} target_type - * @param {Object} callback - */ -NAN_METHOD(GitObject::Peel) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number target_type is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - PeelBaton* baton = new PeelBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->object = ObjectWrap::Unwrap(args.This())->GetValue(); - git_otype from_target_type; - from_target_type = (git_otype) args[0]->ToInt32()->Value(); - baton->target_type = from_target_type; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - PeelWorker *worker = new PeelWorker(baton, callback); - worker->SaveToPersistent("object", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("target_type", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitObject::PeelWorker::Execute() { - int result = git_object_peel( - &baton->peeled, - baton->object, - baton->target_type - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitObject::PeelWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->peeled != NULL) { - to = GitObject::New((void *)baton->peeled); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -Persistent GitObject::constructor_template; diff --git a/src/odb.cc b/src/odb.cc deleted file mode 100644 index c45ce17c8..000000000 --- a/src/odb.cc +++ /dev/null @@ -1,594 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/odb.h" -#include "../include/oid.h" -#include "../include/odb_object.h" -#include "node_buffer.h" - -using namespace v8; -using namespace node; - -GitOdb::GitOdb(git_odb *raw) { - this->raw = raw; -} - -GitOdb::~GitOdb() { - git_odb_free(this->raw); -} - -void GitOdb::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Odb")); - - NODE_SET_METHOD(tpl, "create()", Create); - NODE_SET_METHOD(tpl, "open", Open); - NODE_SET_PROTOTYPE_METHOD(tpl, "addDiskAlternate", AddDiskAlternate); - NODE_SET_PROTOTYPE_METHOD(tpl, "read", Read); - NODE_SET_METHOD(tpl, "readPrefix", ReadPrefix); - NODE_SET_METHOD(tpl, "readHeader", ReadHeader); - NODE_SET_PROTOTYPE_METHOD(tpl, "exists", Exists); - NODE_SET_PROTOTYPE_METHOD(tpl, "refresh", Refresh); - NODE_SET_PROTOTYPE_METHOD(tpl, "write", Write); - NODE_SET_METHOD(tpl, "hash", Hash); - NODE_SET_METHOD(tpl, "hashfile", Hashfile); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Odb"), _constructor_template); -} - -NAN_METHOD(GitOdb::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_odb is required."); - } - GitOdb* object = new GitOdb(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitOdb::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitOdb::constructor_template)->NewInstance(1, argv)); -} - -git_odb *GitOdb::GetValue() { - return this->raw; -} - - -/** - * @return {Odb} out - */ -NAN_METHOD(GitOdb::Create) { - NanScope(); - - git_odb * out = 0; - - int result = git_odb_new( - &out - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOdb::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} objects_dir - * @return {Odb} out - */ -NAN_METHOD(GitOdb::Open) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String objects_dir is required."); - } - - git_odb * out = 0; - const char * from_objects_dir; - String::Utf8Value objects_dir(args[0]->ToString()); - from_objects_dir = strdup(*objects_dir); - - int result = git_odb_open( - &out - , from_objects_dir - ); - free((void *)from_objects_dir); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOdb::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} path - */ -NAN_METHOD(GitOdb::AddDiskAlternate) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - - int result = git_odb_add_disk_alternate( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_path - ); - free((void *)from_path); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - * @param {OdbObject} callback - */ -NAN_METHOD(GitOdb::Read) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ReadBaton* baton = new ReadBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->db = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - ReadWorker *worker = new ReadWorker(baton, callback); - worker->SaveToPersistent("db", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitOdb::ReadWorker::Execute() { - int result = git_odb_read( - &baton->out, - baton->db, - baton->id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitOdb::ReadWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitOdbObject::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - * @param {Odb} db - * @param {Oid} short_id - * @param {Number} len - * @return {OdbObject} out - */ -NAN_METHOD(GitOdb::ReadPrefix) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Odb db is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Oid short_id is required."); - } - if (args.Length() == 2 || !args[2]->IsUint32()) { - return NanThrowError("Number len is required."); - } - - git_odb_object * out = 0; - git_odb * from_db; - from_db = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - const git_oid * from_short_id; - from_short_id = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - size_t from_len; - from_len = (size_t) args[2]->ToUint32()->Value(); - - int result = git_odb_read_prefix( - &out - , from_db - , from_short_id - , from_len - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOdbObject::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Odb} db - * @param {Oid} id - * @return {Number} len_out - * @return {Number} type_out - */ -NAN_METHOD(GitOdb::ReadHeader) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Odb db is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - size_t len_out = 0; - git_otype type_out = GIT_OBJ_ANY; - git_odb * from_db; - from_db = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - - int result = git_odb_read_header( - &len_out - , &type_out - , from_db - , from_id - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle toReturn = NanNew(); - Handle to; - to = NanNew((uint32_t)len_out); - toReturn->Set(NanNew("len_out"), to); - - to = NanNew((int32_t)type_out); - toReturn->Set(NanNew("type_out"), to); - - NanReturnValue(toReturn); -} - -/** - * @param {Oid} id - */ -NAN_METHOD(GitOdb::Exists) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_odb_exists( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_id - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - */ -NAN_METHOD(GitOdb::Refresh) { - NanScope(); - - - int result = git_odb_refresh( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - * @param {String} data - * @param {Number} len - * @param {Number} type - * @param {Oid} callback - */ -NAN_METHOD(GitOdb::Write) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String data is required."); - } - if (args.Length() == 1 || !args[1]->IsUint32()) { - return NanThrowError("Number len is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number type is required."); - } - - if (args.Length() == 3 || !args[3]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - WriteBaton* baton = new WriteBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->out = (git_oid *)malloc(sizeof(git_oid )); - baton->odb = ObjectWrap::Unwrap(args.This())->GetValue(); - const void * from_data; - String::Utf8Value data(args[0]->ToString()); - from_data = strdup(*data); - baton->data = from_data; - size_t from_len; - from_len = (size_t) args[1]->ToUint32()->Value(); - baton->len = from_len; - git_otype from_type; - from_type = (git_otype) args[2]->ToInt32()->Value(); - baton->type = from_type; - - NanCallback *callback = new NanCallback(Local::Cast(args[3])); - WriteWorker *worker = new WriteWorker(baton, callback); - worker->SaveToPersistent("odb", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("data", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("len", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("type", args[2]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitOdb::WriteWorker::Execute() { - int result = git_odb_write( - baton->out, - baton->odb, - baton->data, - baton->len, - baton->type - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitOdb::WriteWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitOid::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->out); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->data); - delete baton; -} - -/** - * @param {Buffer} data - * @param {Number} len - * @param {Number} type - * @return {Oid} out - */ -NAN_METHOD(GitOdb::Hash) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Buffer data is required."); - } - if (args.Length() == 1 || !args[1]->IsUint32()) { - return NanThrowError("Number len is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number type is required."); - } - - git_oid *out = (git_oid *)malloc(sizeof(git_oid)); - const void * from_data; - from_data = Buffer::Data(args[0]->ToObject()); - size_t from_len; - from_len = (size_t) args[1]->ToUint32()->Value(); - git_otype from_type; - from_type = (git_otype) args[2]->ToInt32()->Value(); - - int result = git_odb_hash( - out - , from_data - , from_len - , from_type - ); - if (result != GIT_OK) { - free(out); - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOid::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} path - * @param {Number} type - * @return {Oid} out - */ -NAN_METHOD(GitOdb::Hashfile) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - if (args.Length() == 1 || !args[1]->IsInt32()) { - return NanThrowError("Number type is required."); - } - - git_oid *out = (git_oid *)malloc(sizeof(git_oid)); - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - git_otype from_type; - from_type = (git_otype) args[1]->ToInt32()->Value(); - - int result = git_odb_hashfile( - out - , from_path - , from_type - ); - free((void *)from_path); - if (result != GIT_OK) { - free(out); - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOid::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -Persistent GitOdb::constructor_template; diff --git a/src/odb_object.cc b/src/odb_object.cc deleted file mode 100644 index 2316738fe..000000000 --- a/src/odb_object.cc +++ /dev/null @@ -1,143 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/odb_object.h" -#include "../include/wrapper.h" -#include "../include/oid.h" - -using namespace v8; -using namespace node; - -GitOdbObject::GitOdbObject(git_odb_object *raw) { - this->raw = raw; -} - -GitOdbObject::~GitOdbObject() { - git_odb_object_free(this->raw); -} - -void GitOdbObject::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("OdbObject")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "data", Data); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "type", Type); - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("OdbObject"), _constructor_template); -} - -NAN_METHOD(GitOdbObject::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_odb_object is required."); - } - GitOdbObject* object = new GitOdbObject(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitOdbObject::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitOdbObject::constructor_template)->NewInstance(1, argv)); -} - -git_odb_object *GitOdbObject::GetValue() { - return this->raw; -} - - -/** - * @return {Wrapper} result - */ -NAN_METHOD(GitOdbObject::Data) { - NanScope(); - - - const void * result = git_odb_object_data( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - to = Wrapper::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitOdbObject::Size) { - NanScope(); - - - size_t result = git_odb_object_size( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitOdbObject::Type) { - NanScope(); - - - git_otype result = git_odb_object_type( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((int32_t)result); - NanReturnValue(to); -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitOdbObject::Oid) { - NanScope(); - - - const git_oid * result = git_odb_object_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -Persistent GitOdbObject::constructor_template; diff --git a/src/oid.cc b/src/oid.cc deleted file mode 100755 index e05f9400b..000000000 --- a/src/oid.cc +++ /dev/null @@ -1,119 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/oid.h" - -using namespace v8; -using namespace node; - -GitOid::GitOid(git_oid *raw) { - this->raw = raw; -} - -GitOid::~GitOid() { - free(this->raw); -} - -void GitOid::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Oid")); - - NODE_SET_METHOD(tpl, "fromString", FromString); - NODE_SET_PROTOTYPE_METHOD(tpl, "sha", Sha); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Oid"), _constructor_template); -} - -NAN_METHOD(GitOid::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_oid is required."); - } - GitOid* object = new GitOid(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitOid::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitOid::constructor_template)->NewInstance(1, argv)); -} - -git_oid *GitOid::GetValue() { - return this->raw; -} - - -/** - * @param {String} str - * @return {Oid} out - */ -NAN_METHOD(GitOid::FromString) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String str is required."); - } - - git_oid *out = (git_oid *)malloc(sizeof(git_oid)); - const char * from_str; - String::Utf8Value str(args[0]->ToString()); - from_str = strdup(*str); - - int result = git_oid_fromstr( - out - , from_str - ); - free((void *)from_str); - if (result != GIT_OK) { - free(out); - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOid::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitOid::Sha) { - NanScope(); - - - char * result = git_oid_allocfmt( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - free(result); - NanReturnValue(to); -} - -Persistent GitOid::constructor_template; diff --git a/src/patch.cc b/src/patch.cc deleted file mode 100644 index 936f2d3e6..000000000 --- a/src/patch.cc +++ /dev/null @@ -1,325 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/patch.h" -#include "../include/delta.h" -#include "../include/diff_range.h" - -using namespace v8; -using namespace node; - -GitPatch::GitPatch(git_diff_patch *raw) { - this->raw = raw; -} - -GitPatch::~GitPatch() { - git_diff_patch_free(this->raw); -} - -void GitPatch::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Patch")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "delta", Delta); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "stats", Stats); - NODE_SET_PROTOTYPE_METHOD(tpl, "hunk", Hunk); - NODE_SET_PROTOTYPE_METHOD(tpl, "lines", Lines); - NODE_SET_PROTOTYPE_METHOD(tpl, "line", Line); - NODE_SET_METHOD(tpl, "toString", ToString); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Patch"), _constructor_template); -} - -NAN_METHOD(GitPatch::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_diff_patch is required."); - } - GitPatch* object = new GitPatch(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitPatch::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitPatch::constructor_template)->NewInstance(1, argv)); -} - -git_diff_patch *GitPatch::GetValue() { - return this->raw; -} - - -/** - * @return {Delta} result - */ -NAN_METHOD(GitPatch::Delta) { - NanScope(); - - - const git_diff_delta * result = git_diff_patch_delta( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_diff_delta * )git_diff_delta_dup(result); - } - if (result != NULL) { - to = GitDelta::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitPatch::Size) { - NanScope(); - - - size_t result = git_diff_patch_num_hunks( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @return {Number} total_context - * @return {Number} total_additions - * @return {Number} total_deletions - */ -NAN_METHOD(GitPatch::Stats) { - NanScope(); - - size_t total_context = 0; - size_t total_additions = 0; - size_t total_deletions = 0; - - int result = git_diff_patch_line_stats( - &total_context - , &total_additions - , &total_deletions - , ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle toReturn = NanNew(); - Handle to; - to = NanNew(total_context); - toReturn->Set(NanNew("total_context"), to); - - to = NanNew(total_additions); - toReturn->Set(NanNew("total_additions"), to); - - to = NanNew(total_deletions); - toReturn->Set(NanNew("total_deletions"), to); - - NanReturnValue(toReturn); -} - -/** - * @param {Number} hunk_idx - * @return {DiffRange} range - * @return {String} header - * @return {Number} header_len - * @return {Number} lines_in_hunk - */ -NAN_METHOD(GitPatch::Hunk) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number hunk_idx is required."); - } - - const git_diff_range * range = 0; - const char * header = 0; - size_t header_len = 0; - size_t lines_in_hunk = 0; - size_t from_hunk_idx; - from_hunk_idx = (size_t) args[0]->ToUint32()->Value(); - - int result = git_diff_patch_get_hunk( - &range - , &header - , &header_len - , &lines_in_hunk - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_hunk_idx - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle toReturn = NanNew(); - Handle to; - if (range != NULL) { - range = (const git_diff_range * )git_diff_range_dup(range); - } - if (range != NULL) { - to = GitDiffRange::New((void *)range); - } else { - to = NanNull(); - } - toReturn->Set(NanNew("range"), to); - - to = NanNew(header); - toReturn->Set(NanNew("header"), to); - - to = NanNew((uint32_t)header_len); - toReturn->Set(NanNew("headerLength"), to); - - to = NanNew((uint32_t)lines_in_hunk); - toReturn->Set(NanNew("lines"), to); - - NanReturnValue(toReturn); -} - -/** - * @param {Number} hunk_idx - * @return {Number} result - */ -NAN_METHOD(GitPatch::Lines) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number hunk_idx is required."); - } - - size_t from_hunk_idx; - from_hunk_idx = (size_t) args[0]->ToUint32()->Value(); - - int result = git_diff_patch_num_lines_in_hunk( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_hunk_idx - ); - - Handle to; - to = NanNew((int32_t)result); - NanReturnValue(to); -} - -/** - * @param {Number} hunk_idx - * @param {Number} line_of_hunk - * @return {Number} line_origin - * @return {String} content - * @return {Number} content_len - * @return {Number} old_lineno - * @return {Number} new_lineno - */ -NAN_METHOD(GitPatch::Line) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number hunk_idx is required."); - } - if (args.Length() == 1 || !args[1]->IsUint32()) { - return NanThrowError("Number line_of_hunk is required."); - } - - char line_origin = 0; - const char * content = 0; - size_t content_len = 0; - int old_lineno = 0; - int new_lineno = 0; - size_t from_hunk_idx; - from_hunk_idx = (size_t) args[0]->ToUint32()->Value(); - size_t from_line_of_hunk; - from_line_of_hunk = (size_t) args[1]->ToUint32()->Value(); - - int result = git_diff_patch_get_line_in_hunk( - &line_origin - , &content - , &content_len - , &old_lineno - , &new_lineno - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_hunk_idx - , from_line_of_hunk - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle toReturn = NanNew(); - Handle to; - to = NanNew(line_origin); - toReturn->Set(NanNew("lineOrigin"), to); - - to = NanNew(content, content_len); - toReturn->Set(NanNew("content"), to); - - to = NanNew((uint32_t)content_len); - toReturn->Set(NanNew("length"), to); - - to = NanNew((int32_t)old_lineno); - toReturn->Set(NanNew("oldLineNumber"), to); - - to = NanNew((int32_t)new_lineno); - toReturn->Set(NanNew("newLineNumber"), to); - - NanReturnValue(toReturn); -} - -/** - * @return {String} string - */ -NAN_METHOD(GitPatch::ToString) { - NanScope(); - - char * string = 0; - - int result = git_diff_patch_to_str( - &string - , ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - to = NanNew(string); - free(string); - NanReturnValue(to); -} - -Persistent GitPatch::constructor_template; diff --git a/src/refdb.cc b/src/refdb.cc deleted file mode 100644 index b9279d17f..000000000 --- a/src/refdb.cc +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/refdb.h" - -using namespace v8; -using namespace node; - -GitRefDb::GitRefDb(git_refdb *raw) { - this->raw = raw; -} - -GitRefDb::~GitRefDb() { - free(this->raw); -} - -void GitRefDb::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("RefDb")); - - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("RefDb"), _constructor_template); -} - -NAN_METHOD(GitRefDb::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_refdb is required."); - } - GitRefDb* object = new GitRefDb(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitRefDb::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitRefDb::constructor_template)->NewInstance(1, argv)); -} - -git_refdb *GitRefDb::GetValue() { - return this->raw; -} - - -Persistent GitRefDb::constructor_template; diff --git a/src/reference.cc b/src/reference.cc deleted file mode 100755 index 131df574a..000000000 --- a/src/reference.cc +++ /dev/null @@ -1,647 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/reference.h" -#include "../include/repo.h" -#include "../include/oid.h" -#include "../include/object.h" - -using namespace v8; -using namespace node; - -GitReference::GitReference(git_reference *raw) { - this->raw = raw; -} - -GitReference::~GitReference() { - git_reference_free(this->raw); -} - -void GitReference::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Reference")); - - NODE_SET_METHOD(tpl, "oidForName", OidForName); - NODE_SET_PROTOTYPE_METHOD(tpl, "target", Target); - NODE_SET_PROTOTYPE_METHOD(tpl, "symbolicTarget", SymbolicTarget); - NODE_SET_PROTOTYPE_METHOD(tpl, "type", Type); - NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); - NODE_SET_PROTOTYPE_METHOD(tpl, "resolve", Resolve); - NODE_SET_PROTOTYPE_METHOD(tpl, "setSymbolicTarget", SetSymbolicTarget); - NODE_SET_PROTOTYPE_METHOD(tpl, "setTarget", setTarget); - NODE_SET_PROTOTYPE_METHOD(tpl, "rename", Rename); - NODE_SET_PROTOTYPE_METHOD(tpl, "delete", Delete); - NODE_SET_PROTOTYPE_METHOD(tpl, "isBranch", IsBranch); - NODE_SET_PROTOTYPE_METHOD(tpl, "isRemote", IsRemote); - NODE_SET_PROTOTYPE_METHOD(tpl, "peel", Peel); - NODE_SET_METHOD(tpl, "isValidName", IsValidName); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Reference"), _constructor_template); -} - -NAN_METHOD(GitReference::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_reference is required."); - } - GitReference* object = new GitReference(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitReference::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitReference::constructor_template)->NewInstance(1, argv)); -} - -git_reference *GitReference::GetValue() { - return this->raw; -} - - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {String} name - * @param {Oid} callback - */ -NAN_METHOD(GitReference::OidForName) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String name is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - OidForNameBaton* baton = new OidForNameBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->out = (git_oid *)malloc(sizeof(git_oid )); - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - const char * from_name; - String::Utf8Value name(args[1]->ToString()); - from_name = strdup(*name); - baton->name = from_name; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - OidForNameWorker *worker = new OidForNameWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("name", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitReference::OidForNameWorker::Execute() { - int result = git_reference_name_to_id( - baton->out, - baton->repo, - baton->name - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitReference::OidForNameWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitOid::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->out); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->name); - delete baton; -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitReference::Target) { - NanScope(); - - - const git_oid * result = git_reference_target( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitReference::SymbolicTarget) { - NanScope(); - - - const char * result = git_reference_symbolic_target( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitReference::Type) { - NanScope(); - - - git_ref_t result = git_reference_type( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitReference::Name) { - NanScope(); - - - const char * result = git_reference_name( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Reference} callback - */ -NAN_METHOD(GitReference::Resolve) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ResolveBaton* baton = new ResolveBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->ref = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - ResolveWorker *worker = new ResolveWorker(baton, callback); - worker->SaveToPersistent("ref", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitReference::ResolveWorker::Execute() { - int result = git_reference_resolve( - &baton->out, - baton->ref - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitReference::ResolveWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitReference::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - * @param {String} target - * @return {Reference} out - */ -NAN_METHOD(GitReference::SetSymbolicTarget) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String target is required."); - } - - git_reference * out = 0; - const char * from_target; - String::Utf8Value target(args[0]->ToString()); - from_target = strdup(*target); - - int result = git_reference_symbolic_set_target( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_target - ); - free((void *)from_target); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Oid} id - * @return {Reference} out - */ -NAN_METHOD(GitReference::setTarget) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - git_reference * out = 0; - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_reference_set_target( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_id - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {String} new_name - * @param {Number} force - * @param {Reference} callback - */ -NAN_METHOD(GitReference::Rename) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String new_name is required."); - } - if (args.Length() == 1 || !args[1]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - RenameBaton* baton = new RenameBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->ref = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_new_name; - String::Utf8Value new_name(args[0]->ToString()); - from_new_name = strdup(*new_name); - baton->new_name = from_new_name; - int from_force; - from_force = (int) args[1]->ToInt32()->Value(); - baton->force = from_force; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - RenameWorker *worker = new RenameWorker(baton, callback); - worker->SaveToPersistent("ref", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("new_name", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("force", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitReference::RenameWorker::Execute() { - int result = git_reference_rename( - &baton->out, - baton->ref, - baton->new_name, - baton->force - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitReference::RenameWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitReference::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->new_name); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitReference::Delete) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DeleteBaton* baton = new DeleteBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->ref = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - DeleteWorker *worker = new DeleteWorker(baton, callback); - worker->SaveToPersistent("ref", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitReference::DeleteWorker::Execute() { - int result = git_reference_delete( - baton->ref - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitReference::DeleteWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - */ -NAN_METHOD(GitReference::IsBranch) { - NanScope(); - - - int result = git_reference_is_branch( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - */ -NAN_METHOD(GitReference::IsRemote) { - NanScope(); - - - int result = git_reference_is_remote( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {Number} type - * @return {Object} out - */ -NAN_METHOD(GitReference::Peel) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number type is required."); - } - - git_object * out = 0; - git_otype from_type; - from_type = (git_otype) args[0]->ToInt32()->Value(); - - int result = git_reference_peel( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_type - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitObject::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} refname - */ -NAN_METHOD(GitReference::IsValidName) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String refname is required."); - } - - const char * from_refname; - String::Utf8Value refname(args[0]->ToString()); - from_refname = strdup(*refname); - - int result = git_reference_is_valid_name( - from_refname - ); - free((void *)from_refname); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -Persistent GitReference::constructor_template; diff --git a/src/remote.cc b/src/remote.cc deleted file mode 100644 index 4f6c33b1b..000000000 --- a/src/remote.cc +++ /dev/null @@ -1,592 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/remote.h" -#include "git2/net.h" - -using namespace v8; -using namespace node; - -GitRemote::GitRemote(git_remote *raw) { - this->raw = raw; -} - -GitRemote::~GitRemote() { - git_remote_free(this->raw); -} - -void GitRemote::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Remote")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); - NODE_SET_PROTOTYPE_METHOD(tpl, "url", Url); - NODE_SET_PROTOTYPE_METHOD(tpl, "pushUrl", PushUrl); - NODE_SET_PROTOTYPE_METHOD(tpl, "setUrl", SetUrl); - NODE_SET_PROTOTYPE_METHOD(tpl, "setPushUrl", SetPushUrl); - NODE_SET_PROTOTYPE_METHOD(tpl, "connect", Connect); - NODE_SET_PROTOTYPE_METHOD(tpl, "download", Download); - NODE_SET_PROTOTYPE_METHOD(tpl, "connected", Connected); - NODE_SET_PROTOTYPE_METHOD(tpl, "stop", Stop); - NODE_SET_PROTOTYPE_METHOD(tpl, "disconnect", Disconnect); - NODE_SET_PROTOTYPE_METHOD(tpl, "updateTips", UpdateTips); - NODE_SET_METHOD(tpl, "validUrl", ValidUrl); - NODE_SET_METHOD(tpl, "supportedUrl", SupportedUrl); - NODE_SET_PROTOTYPE_METHOD(tpl, "checkCert", CheckCert); - NODE_SET_PROTOTYPE_METHOD(tpl, "updateFetchhead", UpdateFetchhead); - NODE_SET_PROTOTYPE_METHOD(tpl, "setUpdateFetchhead", SetUpdateFetchhead); - NODE_SET_METHOD(tpl, "isValidName", IsValidName); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Remote"), _constructor_template); -} - -NAN_METHOD(GitRemote::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_remote is required."); - } - GitRemote* object = new GitRemote(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitRemote::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitRemote::constructor_template)->NewInstance(1, argv)); -} - -git_remote *GitRemote::GetValue() { - return this->raw; -} - - -/** - * @return {String} result - */ -NAN_METHOD(GitRemote::Name) { - NanScope(); - - - const char * result = git_remote_name( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitRemote::Url) { - NanScope(); - - - const char * result = git_remote_url( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitRemote::PushUrl) { - NanScope(); - - - const char * result = git_remote_pushurl( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @param {String} url - */ -NAN_METHOD(GitRemote::SetUrl) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - - const char* from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - - int result = git_remote_set_url( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_url - ); - free((void *)from_url); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} url - */ -NAN_METHOD(GitRemote::SetPushUrl) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - - const char* from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - - int result = git_remote_set_pushurl( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_url - ); - free((void *)from_url); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - * @param {Number} direction - */ -NAN_METHOD(GitRemote::Connect) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsNumber()) { - return NanThrowError("Number direction is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ConnectBaton* baton = new ConnectBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->remote = ObjectWrap::Unwrap(args.This())->GetValue(); - git_direction from_direction; - from_direction = (git_direction) (int) args[0]->ToNumber()->Value(); - baton->direction = from_direction; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - ConnectWorker *worker = new ConnectWorker(baton, callback); - worker->SaveToPersistent("remote", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("direction", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRemote::ConnectWorker::Execute() { - int result = git_remote_connect( - baton->remote, - baton->direction - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRemote::ConnectWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Function} progress_cb - * @param {void} payload - */ -NAN_METHOD(GitRemote::Download) { - NanScope(); - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DownloadBaton* baton = new DownloadBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->remote = ObjectWrap::Unwrap(args.This())->GetValue(); - git_transfer_progress_callback from_progress_cb; - if (args[0]->IsFunction()) { - } else { - from_progress_cb = 0; - } - baton->progress_cb = from_progress_cb; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - DownloadWorker *worker = new DownloadWorker(baton, callback); - worker->SaveToPersistent("remote", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("progress_cb", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("payload", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRemote::DownloadWorker::Execute() { - int result = git_remote_download( - baton->remote, - baton->progress_cb, - baton->payload - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRemote::DownloadWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - */ -NAN_METHOD(GitRemote::Connected) { - NanScope(); - - - int result = git_remote_connected( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - */ -NAN_METHOD(GitRemote::Stop) { - NanScope(); - - - git_remote_stop( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitRemote::Disconnect) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DisconnectBaton* baton = new DisconnectBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->remote = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - DisconnectWorker *worker = new DisconnectWorker(baton, callback); - worker->SaveToPersistent("remote", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRemote::DisconnectWorker::Execute() { - git_remote_disconnect( - baton->remote - ); -} - -void GitRemote::DisconnectWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - */ -NAN_METHOD(GitRemote::UpdateTips) { - NanScope(); - - - int result = git_remote_update_tips( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} url - */ -NAN_METHOD(GitRemote::ValidUrl) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - - const char * from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - - int result = git_remote_valid_url( - from_url - ); - free((void *)from_url); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {String} url - */ -NAN_METHOD(GitRemote::SupportedUrl) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - - const char* from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - - int result = git_remote_supported_url( - from_url - ); - free((void *)from_url); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {Number} check - */ -NAN_METHOD(GitRemote::CheckCert) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number check is required."); - } - - int from_check; - from_check = (int) args[0]->ToInt32()->Value(); - - git_remote_check_cert( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_check - ); - - NanReturnUndefined(); -} - -/** - */ -NAN_METHOD(GitRemote::UpdateFetchhead) { - NanScope(); - - - int result = git_remote_update_fetchhead( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @param {Number} value - */ -NAN_METHOD(GitRemote::SetUpdateFetchhead) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number value is required."); - } - - int from_value; - from_value = (int) args[0]->ToInt32()->Value(); - - git_remote_set_update_fetchhead( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_value - ); - - NanReturnUndefined(); -} - -/** - * @param {String} remote_name - */ -NAN_METHOD(GitRemote::IsValidName) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String remote_name is required."); - } - - const char * from_remote_name; - String::Utf8Value remote_name(args[0]->ToString()); - from_remote_name = strdup(*remote_name); - - int result = git_remote_is_valid_name( - from_remote_name - ); - free((void *)from_remote_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -Persistent GitRemote::constructor_template; diff --git a/src/repo.cc b/src/repo.cc deleted file mode 100755 index 0e46f91d2..000000000 --- a/src/repo.cc +++ /dev/null @@ -1,2248 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/repo.h" -#include "../include/oid.h" -#include "../include/commit.h" -#include "../include/blob.h" -#include "../include/object.h" -#include "../include/reference.h" -#include "../include/submodule.h" -#include "../include/refdb.h" -#include "../include/revwalk.h" -#include "../include/tag.h" -#include "../include/signature.h" -#include "../include/tree.h" -#include "../include/odb.h" -#include "../include/index.h" -#include "../include/remote.h" -#include "../include/clone_options.h" -#include "node_buffer.h" - -using namespace v8; -using namespace node; - -GitRepo::GitRepo(git_repository *raw) { - this->raw = raw; -} - -GitRepo::~GitRepo() { - git_repository_free(this->raw); -} - -void GitRepo::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Repo")); - - NODE_SET_METHOD(tpl, "open", Open); - NODE_SET_METHOD(tpl, "init", Init); - NODE_SET_PROTOTYPE_METHOD(tpl, "path", Path); - NODE_SET_PROTOTYPE_METHOD(tpl, "workdir", Workdir); - NODE_SET_PROTOTYPE_METHOD(tpl, "odb", Odb); - NODE_SET_PROTOTYPE_METHOD(tpl, "openIndex", openIndex); - NODE_SET_PROTOTYPE_METHOD(tpl, "getBlob", GetBlob); - NODE_SET_PROTOTYPE_METHOD(tpl, "getCommit", GetCommit); - NODE_SET_PROTOTYPE_METHOD(tpl, "createCommit", CreateCommit); - NODE_SET_PROTOTYPE_METHOD(tpl, "getObject", GetObject); - NODE_SET_PROTOTYPE_METHOD(tpl, "getReference", GetReference); - NODE_SET_PROTOTYPE_METHOD(tpl, "createSymbolicReference", CreateSymbolicReference); - NODE_SET_PROTOTYPE_METHOD(tpl, "createReference", CreateReference); - NODE_SET_PROTOTYPE_METHOD(tpl, "addRemote", AddRemote); - NODE_SET_PROTOTYPE_METHOD(tpl, "createRevWalk", CreateRevWalk); - NODE_SET_PROTOTYPE_METHOD(tpl, "getSubmodule", GetSubmodule); - NODE_SET_PROTOTYPE_METHOD(tpl, "addSubmodule", AddSubmodule); - NODE_SET_PROTOTYPE_METHOD(tpl, "getTag", GetTag); - NODE_SET_PROTOTYPE_METHOD(tpl, "createTag", CreateTag); - NODE_SET_METHOD(tpl, "createLightweightTag", CreateLightweightTag); - NODE_SET_PROTOTYPE_METHOD(tpl, "getTree", GetTree); - NODE_SET_METHOD(tpl, "reloadSubmodules", ReloadSubmodules); - NODE_SET_PROTOTYPE_METHOD(tpl, "delete", Delete); - NODE_SET_PROTOTYPE_METHOD(tpl, "getReferences", GetReferences); - NODE_SET_PROTOTYPE_METHOD(tpl, "createBlobFromBuffer", CreateBlobFromBuffer); - NODE_SET_PROTOTYPE_METHOD(tpl, "createBlobFromFile", CreateBlobFromFile); - NODE_SET_PROTOTYPE_METHOD(tpl, "getRemotes", GetRemotes); - NODE_SET_METHOD(tpl, "clone", Clone); - NODE_SET_PROTOTYPE_METHOD(tpl, "getRemote", GetRemote); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Repo"), _constructor_template); -} - -NAN_METHOD(GitRepo::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_repository is required."); - } - GitRepo* object = new GitRepo(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitRepo::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitRepo::constructor_template)->NewInstance(1, argv)); -} - -git_repository *GitRepo::GetValue() { - return this->raw; -} - - -#include "../include/functions/copy.h" - -/** - * @param {String} path - * @param {Repository} callback - */ -NAN_METHOD(GitRepo::Open) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - OpenBaton* baton = new OpenBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - baton->path = from_path; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - OpenWorker *worker = new OpenWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("path", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::OpenWorker::Execute() { - int result = git_repository_open( - &baton->out, - baton->path - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::OpenWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitRepo::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->path); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} path - * @param {Boolean} is_bare - * @param {Repository} callback - */ -NAN_METHOD(GitRepo::Init) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - if (args.Length() == 1 || !args[1]->IsBoolean()) { - return NanThrowError("Boolean is_bare is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - InitBaton* baton = new InitBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - baton->path = from_path; - unsigned from_is_bare; - from_is_bare = (unsigned) args[1]->ToBoolean()->Value(); - baton->is_bare = from_is_bare; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - InitWorker *worker = new InitWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("path", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("is_bare", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::InitWorker::Execute() { - int result = git_repository_init( - &baton->out, - baton->path, - baton->is_bare - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::InitWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitRepo::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->path); - delete baton; -} - -/** - * @return {String} result - */ -NAN_METHOD(GitRepo::Path) { - NanScope(); - - - const char * result = git_repository_path( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitRepo::Workdir) { - NanScope(); - - - const char * result = git_repository_workdir( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Odb} out - */ -NAN_METHOD(GitRepo::Odb) { - NanScope(); - - git_odb * out = 0; - - int result = git_repository_odb( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitOdb::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Index} callback - */ -NAN_METHOD(GitRepo::openIndex) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - openIndexBaton* baton = new openIndexBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - openIndexWorker *worker = new openIndexWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::openIndexWorker::Execute() { - int result = git_repository_index( - &baton->out, - baton->repo - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::openIndexWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitIndex::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - * @param {Blob} callback - */ -NAN_METHOD(GitRepo::GetBlob) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetBlobBaton* baton = new GetBlobBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetBlobWorker *worker = new GetBlobWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetBlobWorker::Execute() { - int result = git_blob_lookup( - &baton->blob, - baton->repo, - baton->id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetBlobWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->blob != NULL) { - to = GitBlob::New((void *)baton->blob); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - * @param {Commit} callback - */ -NAN_METHOD(GitRepo::GetCommit) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetCommitBaton* baton = new GetCommitBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetCommitWorker *worker = new GetCommitWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetCommitWorker::Execute() { - int result = git_commit_lookup( - &baton->commit, - baton->repo, - baton->id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetCommitWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->commit != NULL) { - to = GitCommit::New((void *)baton->commit); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} update_ref - * @param {Signature} author - * @param {Signature} committer - * @param {String} message_encoding - * @param {String} message - * @param {Tree} tree - * @param {Number} parent_count - * @param {Array} parents - * @param {Oid} callback - */ -NAN_METHOD(GitRepo::CreateCommit) { - NanScope(); - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Signature author is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("Signature committer is required."); - } - if (args.Length() == 4 || !args[4]->IsString()) { - return NanThrowError("String message is required."); - } - if (args.Length() == 5 || !args[5]->IsObject()) { - return NanThrowError("Tree tree is required."); - } - if (args.Length() == 6 || !args[6]->IsInt32()) { - return NanThrowError("Number parent_count is required."); - } - if (args.Length() == 7 || !args[7]->IsObject()) { - return NanThrowError("Array parents is required."); - } - - if (args.Length() == 8 || !args[8]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - CreateCommitBaton* baton = new CreateCommitBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->id = (git_oid *)malloc(sizeof(git_oid )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_update_ref; - if (args[0]->IsString()) { - String::Utf8Value update_ref(args[0]->ToString()); - from_update_ref = strdup(*update_ref); - } else { - from_update_ref = 0; - } - baton->update_ref = from_update_ref; - const git_signature * from_author; - from_author = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->author = from_author; - const git_signature * from_committer; - from_committer = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - baton->committer = from_committer; - const char * from_message_encoding; - if (args[3]->IsString()) { - String::Utf8Value message_encoding(args[3]->ToString()); - from_message_encoding = strdup(*message_encoding); - } else { - from_message_encoding = 0; - } - baton->message_encoding = from_message_encoding; - const char * from_message; - String::Utf8Value message(args[4]->ToString()); - from_message = strdup(*message); - baton->message = from_message; - const git_tree * from_tree; - from_tree = ObjectWrap::Unwrap(args[5]->ToObject())->GetValue(); - baton->tree = from_tree; - int from_parent_count; - from_parent_count = (int) args[6]->ToInt32()->Value(); - baton->parent_count = from_parent_count; - const git_commit ** from_parents; - Array *tmp_parents = Array::Cast(*args[7]); - from_parents = (const git_commit **)malloc(tmp_parents->Length() * sizeof(const git_commit *)); - for (unsigned int i = 0; i < tmp_parents->Length(); i++) { - - from_parents[i] = ObjectWrap::Unwrap(tmp_parents->Get(NanNew(static_cast(i)))->ToObject())->GetValue(); - } - baton->parents = from_parents; - - NanCallback *callback = new NanCallback(Local::Cast(args[8])); - CreateCommitWorker *worker = new CreateCommitWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("update_ref", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("author", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("committer", args[2]->ToObject()); - if (!args[3]->IsUndefined() && !args[3]->IsNull()) - worker->SaveToPersistent("message_encoding", args[3]->ToObject()); - if (!args[4]->IsUndefined() && !args[4]->IsNull()) - worker->SaveToPersistent("message", args[4]->ToObject()); - if (!args[5]->IsUndefined() && !args[5]->IsNull()) - worker->SaveToPersistent("tree", args[5]->ToObject()); - if (!args[6]->IsUndefined() && !args[6]->IsNull()) - worker->SaveToPersistent("parent_count", args[6]->ToObject()); - if (!args[7]->IsUndefined() && !args[7]->IsNull()) - worker->SaveToPersistent("parents", args[7]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::CreateCommitWorker::Execute() { - int result = git_commit_create( - baton->id, - baton->repo, - baton->update_ref, - baton->author, - baton->committer, - baton->message_encoding, - baton->message, - baton->tree, - baton->parent_count, - baton->parents - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::CreateCommitWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->id != NULL) { - to = GitOid::New((void *)baton->id); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->id); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->update_ref); - free((void *)baton->message_encoding); - free((void *)baton->message); - free((void *)baton->parents); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - * @param {Number} type - * @param {Object} callback - */ -NAN_METHOD(GitRepo::GetObject) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - if (args.Length() == 1 || !args[1]->IsInt32()) { - return NanThrowError("Number type is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetObjectBaton* baton = new GetObjectBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - git_otype from_type; - from_type = (git_otype) args[1]->ToInt32()->Value(); - baton->type = from_type; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - GetObjectWorker *worker = new GetObjectWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("type", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetObjectWorker::Execute() { - int result = git_object_lookup( - &baton->object, - baton->repo, - baton->id, - baton->type - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetObjectWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->object != NULL) { - to = GitObject::New((void *)baton->object); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} name - * @param {Reference} callback - */ -NAN_METHOD(GitRepo::GetReference) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetReferenceBaton* baton = new GetReferenceBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - baton->name = from_name; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetReferenceWorker *worker = new GetReferenceWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("name", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetReferenceWorker::Execute() { - int result = git_reference_lookup( - &baton->out, - baton->repo, - baton->name - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetReferenceWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitReference::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->name); - delete baton; -} - -/** - * @param {String} name - * @param {String} target - * @param {Number} force - * @return {Reference} out - */ -NAN_METHOD(GitRepo::CreateSymbolicReference) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String target is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - git_reference * out = 0; - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - const char * from_target; - String::Utf8Value target(args[1]->ToString()); - from_target = strdup(*target); - int from_force; - from_force = (int) args[2]->ToInt32()->Value(); - - int result = git_reference_symbolic_create( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_name - , from_target - , from_force - ); - free((void *)from_name); - free((void *)from_target); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} name - * @param {Oid} id - * @param {Number} force - * @return {Reference} out - */ -NAN_METHOD(GitRepo::CreateReference) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Oid id is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - git_reference * out = 0; - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - int from_force; - from_force = (int) args[2]->ToInt32()->Value(); - - int result = git_reference_create( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_name - , from_id - , from_force - ); - free((void *)from_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitReference::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {String} name - * @param {String} url - * @param {Remote} callback - */ -NAN_METHOD(GitRepo::AddRemote) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String url is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - AddRemoteBaton* baton = new AddRemoteBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - baton->name = from_name; - const char * from_url; - String::Utf8Value url(args[1]->ToString()); - from_url = strdup(*url); - baton->url = from_url; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - AddRemoteWorker *worker = new AddRemoteWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("name", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("url", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::AddRemoteWorker::Execute() { - int result = git_remote_create( - &baton->out, - baton->repo, - baton->name, - baton->url - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::AddRemoteWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitRemote::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->name); - free((void *)baton->url); - delete baton; -} - -/** - * @return {RevWalk} out - */ -NAN_METHOD(GitRepo::CreateRevWalk) { - NanScope(); - - git_revwalk * out = 0; - - int result = git_revwalk_new( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitRevWalk::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} name - * @return {Submodule} submodule - */ -NAN_METHOD(GitRepo::GetSubmodule) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - - git_submodule * submodule = 0; - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - - int result = git_submodule_lookup( - &submodule - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_name - ); - free((void *)from_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (submodule != NULL) { - to = GitSubmodule::New((void *)submodule); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} url - * @param {String} path - * @param {Number} use_gitlink - * @return {Submodule} submodule - */ -NAN_METHOD(GitRepo::AddSubmodule) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String path is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number use_gitlink is required."); - } - - git_submodule * submodule = 0; - const char * from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - const char * from_path; - String::Utf8Value path(args[1]->ToString()); - from_path = strdup(*path); - int from_use_gitlink; - from_use_gitlink = (int) args[2]->ToInt32()->Value(); - - int result = git_submodule_add_setup( - &submodule - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_url - , from_path - , from_use_gitlink - ); - free((void *)from_url); - free((void *)from_path); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (submodule != NULL) { - to = GitSubmodule::New((void *)submodule); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - * @param {Tag} callback - */ -NAN_METHOD(GitRepo::GetTag) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetTagBaton* baton = new GetTagBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetTagWorker *worker = new GetTagWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetTagWorker::Execute() { - int result = git_tag_lookup( - &baton->out, - baton->repo, - baton->id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetTagWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitTag::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} tag_name - * @param {Object} target - * @param {Signature} tagger - * @param {String} message - * @param {Number} force - * @param {Oid} callback - */ -NAN_METHOD(GitRepo::CreateTag) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String tag_name is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Object target is required."); - } - if (args.Length() == 2 || !args[2]->IsObject()) { - return NanThrowError("Signature tagger is required."); - } - if (args.Length() == 3 || !args[3]->IsString()) { - return NanThrowError("String message is required."); - } - if (args.Length() == 4 || !args[4]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - if (args.Length() == 5 || !args[5]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - CreateTagBaton* baton = new CreateTagBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->oid = (git_oid *)malloc(sizeof(git_oid )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_tag_name; - String::Utf8Value tag_name(args[0]->ToString()); - from_tag_name = strdup(*tag_name); - baton->tag_name = from_tag_name; - const git_object * from_target; - from_target = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->target = from_target; - const git_signature * from_tagger; - from_tagger = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - baton->tagger = from_tagger; - const char * from_message; - String::Utf8Value message(args[3]->ToString()); - from_message = strdup(*message); - baton->message = from_message; - int from_force; - from_force = (int) args[4]->ToInt32()->Value(); - baton->force = from_force; - - NanCallback *callback = new NanCallback(Local::Cast(args[5])); - CreateTagWorker *worker = new CreateTagWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("tag_name", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("target", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("tagger", args[2]->ToObject()); - if (!args[3]->IsUndefined() && !args[3]->IsNull()) - worker->SaveToPersistent("message", args[3]->ToObject()); - if (!args[4]->IsUndefined() && !args[4]->IsNull()) - worker->SaveToPersistent("force", args[4]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::CreateTagWorker::Execute() { - int result = git_tag_create( - baton->oid, - baton->repo, - baton->tag_name, - baton->target, - baton->tagger, - baton->message, - baton->force - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::CreateTagWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->oid != NULL) { - to = GitOid::New((void *)baton->oid); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->oid); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->tag_name); - free((void *)baton->message); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} tag_name - * @param {Object} target - * @param {Number} force - * @param {Oid} callback - */ -NAN_METHOD(GitRepo::CreateLightweightTag) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String tag_name is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Object target is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number force is required."); - } - - if (args.Length() == 3 || !args[3]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - CreateLightweightTagBaton* baton = new CreateLightweightTagBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->oid = (git_oid *)malloc(sizeof(git_oid )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_tag_name; - String::Utf8Value tag_name(args[0]->ToString()); - from_tag_name = strdup(*tag_name); - baton->tag_name = from_tag_name; - const git_object * from_target; - from_target = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->target = from_target; - int from_force; - from_force = (int) args[2]->ToInt32()->Value(); - baton->force = from_force; - - NanCallback *callback = new NanCallback(Local::Cast(args[3])); - CreateLightweightTagWorker *worker = new CreateLightweightTagWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("tag_name", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("target", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("force", args[2]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::CreateLightweightTagWorker::Execute() { - int result = git_tag_create_lightweight( - baton->oid, - baton->repo, - baton->tag_name, - baton->target, - baton->force - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::CreateLightweightTagWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->oid != NULL) { - to = GitOid::New((void *)baton->oid); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->oid); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->tag_name); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - * @param {Tree} callback - */ -NAN_METHOD(GitRepo::GetTree) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetTreeBaton* baton = new GetTreeBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetTreeWorker *worker = new GetTreeWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetTreeWorker::Execute() { - int result = git_tree_lookup( - &baton->out, - baton->repo, - baton->id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetTreeWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitTree::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitRepo::ReloadSubmodules) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ReloadSubmodulesBaton* baton = new ReloadSubmodulesBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - ReloadSubmodulesWorker *worker = new ReloadSubmodulesWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::ReloadSubmodulesWorker::Execute() { - int result = git_submodule_reload_all( - baton->repo - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::ReloadSubmodulesWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} tag_name - */ -NAN_METHOD(GitRepo::Delete) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String tag_name is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DeleteBaton* baton = new DeleteBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_tag_name; - String::Utf8Value tag_name(args[0]->ToString()); - from_tag_name = strdup(*tag_name); - baton->tag_name = from_tag_name; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - DeleteWorker *worker = new DeleteWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("tag_name", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::DeleteWorker::Execute() { - int result = git_tag_delete( - baton->repo, - baton->tag_name - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::DeleteWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->tag_name); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Number} list_flags - * @param {Array} callback - */ -NAN_METHOD(GitRepo::GetReferences) { - NanScope(); - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetReferencesBaton* baton = new GetReferencesBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->array = (git_strarray *)malloc(sizeof(git_strarray )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - unsigned int from_list_flags; - if (args[0]->IsUint32()) { - from_list_flags = (unsigned int) args[0]->ToUint32()->Value(); - } else { - from_list_flags = 0; - } - baton->list_flags = from_list_flags; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetReferencesWorker *worker = new GetReferencesWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("list_flags", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetReferencesWorker::Execute() { - int result = git_reference_list( - baton->array, - baton->repo, - baton->list_flags - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetReferencesWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - - Local tmpArray = NanNew(baton->array->count); - for (unsigned int i = 0; i < baton->array->count; i++) { - tmpArray->Set(NanNew(i), NanNew(baton->array->strings[i])); - } - to = tmpArray; - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->array); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - - git_strarray_free(baton->array); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Buffer} buffer - * @param {Number} len - * @param {Oid} callback - */ -NAN_METHOD(GitRepo::CreateBlobFromBuffer) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Buffer buffer is required."); - } - if (args.Length() == 1 || !args[1]->IsNumber()) { - return NanThrowError("Number len is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - CreateBlobFromBufferBaton* baton = new CreateBlobFromBufferBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->oid = (git_oid *)malloc(sizeof(git_oid )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const void * from_buffer; - from_buffer = Buffer::Data(args[0]->ToObject()); - baton->buffer = from_buffer; - size_t from_len; - from_len = (size_t) args[1]->ToNumber()->Value(); - baton->len = from_len; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - CreateBlobFromBufferWorker *worker = new CreateBlobFromBufferWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("buffer", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("len", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::CreateBlobFromBufferWorker::Execute() { - int result = git_blob_create_frombuffer( - baton->oid, - baton->repo, - baton->buffer, - baton->len - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::CreateBlobFromBufferWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->oid != NULL) { - to = GitOid::New((void *)baton->oid); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->oid); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} path - * @param {Oid} callback - */ -NAN_METHOD(GitRepo::CreateBlobFromFile) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - CreateBlobFromFileBaton* baton = new CreateBlobFromFileBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->id = (git_oid *)malloc(sizeof(git_oid )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - baton->path = from_path; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - CreateBlobFromFileWorker *worker = new CreateBlobFromFileWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("path", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::CreateBlobFromFileWorker::Execute() { - int result = git_blob_create_fromdisk( - baton->id, - baton->repo, - baton->path - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::CreateBlobFromFileWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->id != NULL) { - to = GitOid::New((void *)baton->id); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->id); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->path); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Array} callback - */ -NAN_METHOD(GitRepo::GetRemotes) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetRemotesBaton* baton = new GetRemotesBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->out = (git_strarray *)malloc(sizeof(git_strarray )); - baton->repo = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - GetRemotesWorker *worker = new GetRemotesWorker(baton, callback); - worker->SaveToPersistent("repo", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::GetRemotesWorker::Execute() { - int result = git_remote_list( - baton->out, - baton->repo - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::GetRemotesWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - - Local tmpArray = NanNew(baton->out->count); - for (unsigned int i = 0; i < baton->out->count; i++) { - tmpArray->Set(NanNew(i), NanNew(baton->out->strings[i])); - } - to = tmpArray; - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->out); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - - git_strarray_free(baton->out); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} url - * @param {String} local_path - * @param {CloneOptions} options - * @param {Repository} callback - */ -NAN_METHOD(GitRepo::Clone) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String local_path is required."); - } - - if (args.Length() == 3 || !args[3]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - CloneBaton* baton = new CloneBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - const char * from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - baton->url = from_url; - const char * from_local_path; - String::Utf8Value local_path(args[1]->ToString()); - from_local_path = strdup(*local_path); - baton->local_path = from_local_path; - const git_clone_options * from_options; - if (args[2]->IsObject()) { - from_options = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - } else { - from_options = 0; - } - baton->options = from_options; - - NanCallback *callback = new NanCallback(Local::Cast(args[3])); - CloneWorker *worker = new CloneWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("url", args[0]->ToObject()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("local_path", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("options", args[2]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRepo::CloneWorker::Execute() { - int result = git_clone( - &baton->out, - baton->url, - baton->local_path, - baton->options - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRepo::CloneWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitRepo::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->url); - free((void *)baton->local_path); - delete baton; -} - -/** - * @param {String} name - * @return {Remote} out - */ -NAN_METHOD(GitRepo::GetRemote) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - - git_remote * out = 0; - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - - int result = git_remote_load( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_name - ); - free((void *)from_name); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitRemote::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -Persistent GitRepo::constructor_template; diff --git a/src/revwalk.cc b/src/revwalk.cc deleted file mode 100755 index 61430026f..000000000 --- a/src/revwalk.cc +++ /dev/null @@ -1,753 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/revwalk.h" -#include "../include/oid.h" -#include "../include/repo.h" - -using namespace v8; -using namespace node; - -GitRevWalk::GitRevWalk(git_revwalk *raw) { - this->raw = raw; -} - -GitRevWalk::~GitRevWalk() { - git_revwalk_free(this->raw); -} - -void GitRevWalk::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("RevWalk")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "reset", Reset); - NODE_SET_PROTOTYPE_METHOD(tpl, "push", Push); - NODE_SET_PROTOTYPE_METHOD(tpl, "pushGlob", PushGlob); - NODE_SET_PROTOTYPE_METHOD(tpl, "pushHead", PushHead); - NODE_SET_PROTOTYPE_METHOD(tpl, "hide", Hide); - NODE_SET_PROTOTYPE_METHOD(tpl, "hideGlob", HideGlob); - NODE_SET_PROTOTYPE_METHOD(tpl, "hideHead", HideHead); - NODE_SET_PROTOTYPE_METHOD(tpl, "pushRef", PushRef); - NODE_SET_PROTOTYPE_METHOD(tpl, "hideRef", HideRef); - NODE_SET_PROTOTYPE_METHOD(tpl, "next", Next); - NODE_SET_PROTOTYPE_METHOD(tpl, "sorting", Sorting); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("RevWalk"), _constructor_template); -} - -NAN_METHOD(GitRevWalk::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_revwalk is required."); - } - GitRevWalk* object = new GitRevWalk(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitRevWalk::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitRevWalk::constructor_template)->NewInstance(1, argv)); -} - -git_revwalk *GitRevWalk::GetValue() { - return this->raw; -} - - -/** - */ -NAN_METHOD(GitRevWalk::Reset) { - NanScope(); - - - git_revwalk_reset( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} id - */ -NAN_METHOD(GitRevWalk::Push) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - PushBaton* baton = new PushBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->id = from_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - PushWorker *worker = new PushWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::PushWorker::Execute() { - int result = git_revwalk_push( - baton->walk, - baton->id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::PushWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} glob - */ -NAN_METHOD(GitRevWalk::PushGlob) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String glob is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - PushGlobBaton* baton = new PushGlobBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_glob; - String::Utf8Value glob(args[0]->ToString()); - from_glob = strdup(*glob); - baton->glob = from_glob; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - PushGlobWorker *worker = new PushGlobWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("glob", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::PushGlobWorker::Execute() { - int result = git_revwalk_push_glob( - baton->walk, - baton->glob - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::PushGlobWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->glob); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitRevWalk::PushHead) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - PushHeadBaton* baton = new PushHeadBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - PushHeadWorker *worker = new PushHeadWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::PushHeadWorker::Execute() { - int result = git_revwalk_push_head( - baton->walk - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::PushHeadWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} commit_id - */ -NAN_METHOD(GitRevWalk::Hide) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid commit_id is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - HideBaton* baton = new HideBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_oid * from_commit_id; - from_commit_id = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->commit_id = from_commit_id; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - HideWorker *worker = new HideWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("commit_id", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::HideWorker::Execute() { - int result = git_revwalk_hide( - baton->walk, - baton->commit_id - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::HideWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} glob - */ -NAN_METHOD(GitRevWalk::HideGlob) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String glob is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - HideGlobBaton* baton = new HideGlobBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_glob; - String::Utf8Value glob(args[0]->ToString()); - from_glob = strdup(*glob); - baton->glob = from_glob; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - HideGlobWorker *worker = new HideGlobWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("glob", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::HideGlobWorker::Execute() { - int result = git_revwalk_hide_glob( - baton->walk, - baton->glob - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::HideGlobWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->glob); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitRevWalk::HideHead) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - HideHeadBaton* baton = new HideHeadBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - HideHeadWorker *worker = new HideHeadWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::HideHeadWorker::Execute() { - int result = git_revwalk_hide_head( - baton->walk - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::HideHeadWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} refname - */ -NAN_METHOD(GitRevWalk::PushRef) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String refname is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - PushRefBaton* baton = new PushRefBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_refname; - String::Utf8Value refname(args[0]->ToString()); - from_refname = strdup(*refname); - baton->refname = from_refname; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - PushRefWorker *worker = new PushRefWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("refname", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::PushRefWorker::Execute() { - int result = git_revwalk_push_ref( - baton->walk, - baton->refname - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::PushRefWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->refname); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {String} refname - */ -NAN_METHOD(GitRevWalk::HideRef) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String refname is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - HideRefBaton* baton = new HideRefBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_refname; - String::Utf8Value refname(args[0]->ToString()); - from_refname = strdup(*refname); - baton->refname = from_refname; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - HideRefWorker *worker = new HideRefWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("refname", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::HideRefWorker::Execute() { - int result = git_revwalk_hide_ref( - baton->walk, - baton->refname - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::HideRefWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->refname); - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Oid} callback - */ -NAN_METHOD(GitRevWalk::Next) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - NextBaton* baton = new NextBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->out = (git_oid *)malloc(sizeof(git_oid )); - baton->walk = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - NextWorker *worker = new NextWorker(baton, callback); - worker->SaveToPersistent("walk", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitRevWalk::NextWorker::Execute() { - int result = git_revwalk_next( - baton->out, - baton->walk - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitRevWalk::NextWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitOid::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->out); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - * @param {Number} sort_mode - */ -NAN_METHOD(GitRevWalk::Sorting) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number sort_mode is required."); - } - - unsigned int from_sort_mode; - from_sort_mode = (unsigned int) args[0]->ToUint32()->Value(); - - git_revwalk_sorting( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_sort_mode - ); - - NanReturnUndefined(); -} - -Persistent GitRevWalk::constructor_template; diff --git a/src/signature.cc b/src/signature.cc deleted file mode 100755 index 26d181901..000000000 --- a/src/signature.cc +++ /dev/null @@ -1,214 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/signature.h" -#include "../include/time.h" - -using namespace v8; -using namespace node; - -GitSignature::GitSignature(git_signature *raw) { - this->raw = raw; -} - -GitSignature::~GitSignature() { - git_signature_free(this->raw); -} - -void GitSignature::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Signature")); - - NODE_SET_METHOD(tpl, "create", Create); - NODE_SET_METHOD(tpl, "now", Now); - - NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); - NODE_SET_PROTOTYPE_METHOD(tpl, "email", Email); - NODE_SET_PROTOTYPE_METHOD(tpl, "time", Time); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Signature"), _constructor_template); -} - -NAN_METHOD(GitSignature::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_signature is required."); - } - GitSignature* object = new GitSignature(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitSignature::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitSignature::constructor_template)->NewInstance(1, argv)); -} - -git_signature *GitSignature::GetValue() { - return this->raw; -} - - -/** - * @param {String} name - * @param {String} email - * @param {Number} time - * @param {Number} offset - * @return {Signature} out - */ -NAN_METHOD(GitSignature::Create) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String email is required."); - } - if (args.Length() == 2 || !args[2]->IsInt32()) { - return NanThrowError("Number time is required."); - } - if (args.Length() == 3 || !args[3]->IsInt32()) { - return NanThrowError("Number offset is required."); - } - - git_signature * out = 0; - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - const char * from_email; - String::Utf8Value email(args[1]->ToString()); - from_email = strdup(*email); - git_time_t from_time; - from_time = (git_time_t) args[2]->ToInt32()->Value(); - int from_offset; - from_offset = (int) args[3]->ToInt32()->Value(); - - int result = git_signature_new( - &out - , from_name - , from_email - , from_time - , from_offset - ); - free((void *)from_name); - free((void *)from_email); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitSignature::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} name - * @param {String} email - * @return {Signature} out - */ -NAN_METHOD(GitSignature::Now) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String name is required."); - } - if (args.Length() == 1 || !args[1]->IsString()) { - return NanThrowError("String email is required."); - } - - git_signature * out = 0; - const char * from_name; - String::Utf8Value name(args[0]->ToString()); - from_name = strdup(*name); - const char * from_email; - String::Utf8Value email(args[1]->ToString()); - from_email = strdup(*email); - - int result = git_signature_now( - &out - , from_name - , from_email - ); - free((void *)from_name); - free((void *)from_email); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitSignature::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -NAN_METHOD(GitSignature::Name) { - NanScope(); - Handle to; - - const char * name = - ObjectWrap::Unwrap(args.This())->GetValue()->name; - - to = NanNew(name); - NanReturnValue(to); -} - -NAN_METHOD(GitSignature::Email) { - NanScope(); - Handle to; - - const char * email = - ObjectWrap::Unwrap(args.This())->GetValue()->email; - - to = NanNew(email); - NanReturnValue(to); -} - -NAN_METHOD(GitSignature::Time) { - NanScope(); - Handle to; - - git_time *when = - &ObjectWrap::Unwrap(args.This())->GetValue()->when; - - if (when != NULL) { - when = (git_time *)git_time_dup(when); - } - if (when != NULL) { - to = GitTime::New((void *)when); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -Persistent GitSignature::constructor_template; diff --git a/src/submodule.cc b/src/submodule.cc deleted file mode 100644 index 22a9c5806..000000000 --- a/src/submodule.cc +++ /dev/null @@ -1,743 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/submodule.h" -#include "../include/oid.h" -#include "../include/repo.h" - -using namespace v8; -using namespace node; - -GitSubmodule::GitSubmodule(git_submodule *raw) { - this->raw = raw; -} - -GitSubmodule::~GitSubmodule() { - free(this->raw); -} - -void GitSubmodule::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Submodule")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "addFinalize", AddFinalize); - NODE_SET_PROTOTYPE_METHOD(tpl, "addToIndex", AddToIndex); - NODE_SET_PROTOTYPE_METHOD(tpl, "save", Save); - NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); - NODE_SET_PROTOTYPE_METHOD(tpl, "path", Path); - NODE_SET_PROTOTYPE_METHOD(tpl, "url", Url); - NODE_SET_PROTOTYPE_METHOD(tpl, "setUrl", SetUrl); - NODE_SET_PROTOTYPE_METHOD(tpl, "indexId", IndexId); - NODE_SET_PROTOTYPE_METHOD(tpl, "headId", HeadId); - NODE_SET_PROTOTYPE_METHOD(tpl, "init", Init); - NODE_SET_PROTOTYPE_METHOD(tpl, "sync", Sync); - NODE_SET_PROTOTYPE_METHOD(tpl, "open", Open); - NODE_SET_PROTOTYPE_METHOD(tpl, "reload", Reload); - NODE_SET_PROTOTYPE_METHOD(tpl, "status", Status); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Submodule"), _constructor_template); -} - -NAN_METHOD(GitSubmodule::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_submodule is required."); - } - GitSubmodule* object = new GitSubmodule(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitSubmodule::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitSubmodule::constructor_template)->NewInstance(1, argv)); -} - -git_submodule *GitSubmodule::GetValue() { - return this->raw; -} - - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitSubmodule::AddFinalize) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - AddFinalizeBaton* baton = new AddFinalizeBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - AddFinalizeWorker *worker = new AddFinalizeWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::AddFinalizeWorker::Execute() { - int result = git_submodule_add_finalize( - baton->submodule - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::AddFinalizeWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Number} write_index - */ -NAN_METHOD(GitSubmodule::AddToIndex) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number write_index is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - AddToIndexBaton* baton = new AddToIndexBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - int from_write_index; - from_write_index = (int) args[0]->ToInt32()->Value(); - baton->write_index = from_write_index; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - AddToIndexWorker *worker = new AddToIndexWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("write_index", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::AddToIndexWorker::Execute() { - int result = git_submodule_add_to_index( - baton->submodule, - baton->write_index - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::AddToIndexWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitSubmodule::Save) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - SaveBaton* baton = new SaveBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - SaveWorker *worker = new SaveWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::SaveWorker::Execute() { - int result = git_submodule_save( - baton->submodule - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::SaveWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - * @return {String} result - */ -NAN_METHOD(GitSubmodule::Name) { - NanScope(); - - - const char * result = git_submodule_name( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitSubmodule::Path) { - NanScope(); - - - const char * result = git_submodule_path( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitSubmodule::Url) { - NanScope(); - - - const char * result = git_submodule_url( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @param {String} url - */ -NAN_METHOD(GitSubmodule::SetUrl) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String url is required."); - } - - const char * from_url; - String::Utf8Value url(args[0]->ToString()); - from_url = strdup(*url); - - int result = git_submodule_set_url( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_url - ); - free((void *)from_url); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitSubmodule::IndexId) { - NanScope(); - - - const git_oid * result = git_submodule_index_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitSubmodule::HeadId) { - NanScope(); - - - const git_oid * result = git_submodule_head_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Number} overwrite - */ -NAN_METHOD(GitSubmodule::Init) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number overwrite is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - InitBaton* baton = new InitBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - int from_overwrite; - from_overwrite = (int) args[0]->ToInt32()->Value(); - baton->overwrite = from_overwrite; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - InitWorker *worker = new InitWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("overwrite", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::InitWorker::Execute() { - int result = git_submodule_init( - baton->submodule, - baton->overwrite - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::InitWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitSubmodule::Sync) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - SyncBaton* baton = new SyncBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - SyncWorker *worker = new SyncWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::SyncWorker::Execute() { - int result = git_submodule_sync( - baton->submodule - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::SyncWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} callback - */ -NAN_METHOD(GitSubmodule::Open) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - OpenBaton* baton = new OpenBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - OpenWorker *worker = new OpenWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::OpenWorker::Execute() { - int result = git_submodule_open( - &baton->repo, - baton->submodule - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::OpenWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->repo != NULL) { - to = GitRepo::New((void *)baton->repo); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - */ -NAN_METHOD(GitSubmodule::Reload) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - ReloadBaton* baton = new ReloadBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - ReloadWorker *worker = new ReloadWorker(baton, callback); - worker->SaveToPersistent("submodule", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::ReloadWorker::Execute() { - int result = git_submodule_reload( - baton->submodule - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::ReloadWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Number} status - */ -NAN_METHOD(GitSubmodule::Status) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsInt32()) { - return NanThrowError("Number status is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - StatusBaton* baton = new StatusBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - unsigned int * from_status; - from_status = (unsigned int *) args[0]->ToInt32()->Value(); - baton->status = from_status; - baton->submodule = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - StatusWorker *worker = new StatusWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("status", args[0]->ToObject()); - worker->SaveToPersistent("submodule", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitSubmodule::StatusWorker::Execute() { - int result = git_submodule_status( - baton->status, - baton->submodule - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitSubmodule::StatusWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle result = NanUndefined(); - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -Persistent GitSubmodule::constructor_template; diff --git a/src/tag.cc b/src/tag.cc deleted file mode 100644 index 0717ab100..000000000 --- a/src/tag.cc +++ /dev/null @@ -1,297 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/tag.h" -#include "../include/oid.h" -#include "../include/repo.h" -#include "../include/object.h" -#include "../include/signature.h" - -using namespace v8; -using namespace node; - -GitTag::GitTag(git_tag *raw) { - this->raw = raw; -} - -GitTag::~GitTag() { - git_tag_free(this->raw); -} - -void GitTag::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Tag")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "getTarget", GetTarget); - NODE_SET_PROTOTYPE_METHOD(tpl, "targetId", TargetId); - NODE_SET_PROTOTYPE_METHOD(tpl, "targetType", TargetType); - NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); - NODE_SET_PROTOTYPE_METHOD(tpl, "tagger", Tagger); - NODE_SET_PROTOTYPE_METHOD(tpl, "message", Message); - NODE_SET_PROTOTYPE_METHOD(tpl, "peel", Peel); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Tag"), _constructor_template); -} - -NAN_METHOD(GitTag::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_tag is required."); - } - GitTag* object = new GitTag(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitTag::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitTag::constructor_template)->NewInstance(1, argv)); -} - -git_tag *GitTag::GetValue() { - return this->raw; -} - - -/** - * @return {Oid} result - */ -NAN_METHOD(GitTag::Oid) { - NanScope(); - - - const git_oid * result = git_tag_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Object} callback - */ -NAN_METHOD(GitTag::GetTarget) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetTargetBaton* baton = new GetTargetBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->tag = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[0])); - GetTargetWorker *worker = new GetTargetWorker(baton, callback); - worker->SaveToPersistent("tag", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTag::GetTargetWorker::Execute() { - int result = git_tag_target( - &baton->target_out, - baton->tag - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTag::GetTargetWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->target_out != NULL) { - to = GitObject::New((void *)baton->target_out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitTag::TargetId) { - NanScope(); - - - const git_oid * result = git_tag_target_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitTag::TargetType) { - NanScope(); - - - git_otype result = git_tag_target_type( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((int32_t)result); - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitTag::Name) { - NanScope(); - - - const char * result = git_tag_name( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Signature} result - */ -NAN_METHOD(GitTag::Tagger) { - NanScope(); - - - const git_signature * result = git_tag_tagger( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_signature * )git_signature_dup(result); - } - if (result != NULL) { - to = GitSignature::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {String} result - */ -NAN_METHOD(GitTag::Message) { - NanScope(); - - - const char * result = git_tag_message( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @param {Tag} tag - * @return {Object} tag_target_out - */ -NAN_METHOD(GitTag::Peel) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Tag tag is required."); - } - - git_object * tag_target_out = 0; - const git_tag * from_tag; - from_tag = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - int result = git_tag_peel( - &tag_target_out - , from_tag - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (tag_target_out != NULL) { - to = GitObject::New((void *)tag_target_out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -Persistent GitTag::constructor_template; diff --git a/src/threads.cc b/src/threads.cc deleted file mode 100755 index 5e36ef1cd..000000000 --- a/src/threads.cc +++ /dev/null @@ -1,58 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/threads.h" - -using namespace v8; -using namespace node; - -void GitThreads::Initialize(Handle target) { - NanScope(); - - Local object = NanNew(); - - NODE_SET_METHOD(object, "init", Init); - NODE_SET_METHOD(object, "shutdown", Shutdown); - - target->Set(NanNew("Threads"), object); -} - - -/** - */ -NAN_METHOD(GitThreads::Init) { - NanScope(); - - - int result = git_threads_init( - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -/** - */ -NAN_METHOD(GitThreads::Shutdown) { - NanScope(); - - - git_threads_shutdown( - ); - - NanReturnUndefined(); -} - diff --git a/src/time.cc b/src/time.cc deleted file mode 100644 index dd495947b..000000000 --- a/src/time.cc +++ /dev/null @@ -1,86 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/time.h" - -using namespace v8; -using namespace node; - -GitTime::GitTime(git_time *raw) { - this->raw = raw; -} - -GitTime::~GitTime() { - free(this->raw); -} - -void GitTime::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Time")); - - - NODE_SET_PROTOTYPE_METHOD(tpl, "time", Time); - NODE_SET_PROTOTYPE_METHOD(tpl, "offset", Offset); - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Time"), _constructor_template); -} - -NAN_METHOD(GitTime::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_time is required."); - } - GitTime* object = new GitTime(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitTime::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitTime::constructor_template)->NewInstance(1, argv)); -} - -git_time *GitTime::GetValue() { - return this->raw; -} - - -NAN_METHOD(GitTime::Time) { - NanScope(); - Handle to; - - git_time_t time = - ObjectWrap::Unwrap(args.This())->GetValue()->time; - - to = NanNew(time); - NanReturnValue(to); -} - -NAN_METHOD(GitTime::Offset) { - NanScope(); - Handle to; - - int offset = - ObjectWrap::Unwrap(args.This())->GetValue()->offset; - - to = NanNew((int32_t)offset); - NanReturnValue(to); -} - -Persistent GitTime::constructor_template; diff --git a/src/tree.cc b/src/tree.cc deleted file mode 100755 index 3686e35da..000000000 --- a/src/tree.cc +++ /dev/null @@ -1,619 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/tree.h" -#include "../include/repo.h" -#include "../include/oid.h" -#include "../include/tree_entry.h" -#include "../include/diff_list.h" -#include "../include/diff_options.h" -#include "../include/tree_builder.h" -#include "../include/index.h" - -using namespace v8; -using namespace node; - -GitTree::GitTree(git_tree *raw) { - this->raw = raw; -} - -GitTree::~GitTree() { - git_tree_free(this->raw); -} - -void GitTree::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("Tree")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "entryByName", EntryByName); - NODE_SET_PROTOTYPE_METHOD(tpl, "entryByIndex", EntryByIndex); - NODE_SET_PROTOTYPE_METHOD(tpl, "entryByOid", EntryByOid); - NODE_SET_PROTOTYPE_METHOD(tpl, "getEntry", GetEntry); - NODE_SET_PROTOTYPE_METHOD(tpl, "builder", Builder); - NODE_SET_PROTOTYPE_METHOD(tpl, "diffTree", DiffTree); - NODE_SET_PROTOTYPE_METHOD(tpl, "diffIndex", DiffIndex); - NODE_SET_PROTOTYPE_METHOD(tpl, "diffWorkDir", DiffWorkDir); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("Tree"), _constructor_template); -} - -NAN_METHOD(GitTree::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_tree is required."); - } - GitTree* object = new GitTree(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitTree::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitTree::constructor_template)->NewInstance(1, argv)); -} - -git_tree *GitTree::GetValue() { - return this->raw; -} - - -/** - * @return {Oid} result - */ -NAN_METHOD(GitTree::Oid) { - NanScope(); - - - const git_oid * result = git_tree_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitTree::Size) { - NanScope(); - - - size_t result = git_tree_entrycount( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @param {String} filename - * @return {TreeEntry} result - */ -NAN_METHOD(GitTree::EntryByName) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String filename is required."); - } - - const char * from_filename; - String::Utf8Value filename(args[0]->ToString()); - from_filename = strdup(*filename); - - const git_tree_entry * result = git_tree_entry_byname( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_filename - ); - free((void *)from_filename); - - Handle to; - if (result != NULL) { - result = (const git_tree_entry * )git_tree_entry_dup(result); - } - if (result != NULL) { - to = GitTreeEntry::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Number} idx - * @return {TreeEntry} result - */ -NAN_METHOD(GitTree::EntryByIndex) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsUint32()) { - return NanThrowError("Number idx is required."); - } - - size_t from_idx; - from_idx = (size_t) args[0]->ToUint32()->Value(); - - const git_tree_entry * result = git_tree_entry_byindex( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_idx - ); - - Handle to; - if (result != NULL) { - result = (const git_tree_entry * )git_tree_entry_dup(result); - } - if (result != NULL) { - to = GitTreeEntry::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {Oid} oid - * @return {TreeEntry} result - */ -NAN_METHOD(GitTree::EntryByOid) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Oid oid is required."); - } - - const git_oid * from_oid; - from_oid = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - const git_tree_entry * result = git_tree_entry_byoid( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_oid - ); - - Handle to; - if (result != NULL) { - result = (const git_tree_entry * )git_tree_entry_dup(result); - } - if (result != NULL) { - to = GitTreeEntry::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {String} path - * @param {TreeEntry} callback - */ -NAN_METHOD(GitTree::GetEntry) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String path is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetEntryBaton* baton = new GetEntryBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->root = ObjectWrap::Unwrap(args.This())->GetValue(); - const char * from_path; - String::Utf8Value path(args[0]->ToString()); - from_path = strdup(*path); - baton->path = from_path; - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetEntryWorker *worker = new GetEntryWorker(baton, callback); - worker->SaveToPersistent("root", args.This()); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("path", args[0]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTree::GetEntryWorker::Execute() { - int result = git_tree_entry_bypath( - &baton->out, - baton->root, - baton->path - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTree::GetEntryWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->out != NULL) { - to = GitTreeEntry::New((void *)baton->out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - free((void *)baton->path); - delete baton; -} - -/** - * @return {TreeBuilder} out - */ -NAN_METHOD(GitTree::Builder) { - NanScope(); - - git_treebuilder * out = 0; - - int result = git_treebuilder_create( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitTreeBuilder::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {Tree} new_tree - * @param {DiffOptions} opts - * @param {DiffList} callback - */ -NAN_METHOD(GitTree::DiffTree) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Tree new_tree is required."); - } - - if (args.Length() == 3 || !args[3]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DiffTreeBaton* baton = new DiffTreeBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - baton->old_tree = ObjectWrap::Unwrap(args.This())->GetValue(); - git_tree * from_new_tree; - from_new_tree = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->new_tree = from_new_tree; - const git_diff_options * from_opts; - if (args[2]->IsObject()) { - from_opts = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - } else { - from_opts = 0; - } - baton->opts = from_opts; - - NanCallback *callback = new NanCallback(Local::Cast(args[3])); - DiffTreeWorker *worker = new DiffTreeWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - worker->SaveToPersistent("old_tree", args.This()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("new_tree", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("opts", args[2]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTree::DiffTreeWorker::Execute() { - int result = git_diff_tree_to_tree( - &baton->diff, - baton->repo, - baton->old_tree, - baton->new_tree, - baton->opts - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTree::DiffTreeWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->diff != NULL) { - to = GitDiffList::New((void *)baton->diff); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {Index} index - * @param {DiffOptions} opts - * @param {DiffList} callback - */ -NAN_METHOD(GitTree::DiffIndex) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - - if (args.Length() == 3 || !args[3]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DiffIndexBaton* baton = new DiffIndexBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - baton->old_tree = ObjectWrap::Unwrap(args.This())->GetValue(); - git_index * from_index; - if (args[1]->IsObject()) { - from_index = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - } else { - from_index = 0; - } - baton->index = from_index; - const git_diff_options * from_opts; - if (args[2]->IsObject()) { - from_opts = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); - } else { - from_opts = 0; - } - baton->opts = from_opts; - - NanCallback *callback = new NanCallback(Local::Cast(args[3])); - DiffIndexWorker *worker = new DiffIndexWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - worker->SaveToPersistent("old_tree", args.This()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("index", args[1]->ToObject()); - if (!args[2]->IsUndefined() && !args[2]->IsNull()) - worker->SaveToPersistent("opts", args[2]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTree::DiffIndexWorker::Execute() { - int result = git_diff_tree_to_index( - &baton->diff, - baton->repo, - baton->old_tree, - baton->index, - baton->opts - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTree::DiffIndexWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->diff != NULL) { - to = GitDiffList::New((void *)baton->diff); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {DiffOptions} opts - * @param {DiffList} callback - */ -NAN_METHOD(GitTree::DiffWorkDir) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - - if (args.Length() == 2 || !args[2]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - DiffWorkDirBaton* baton = new DiffWorkDirBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - baton->old_tree = ObjectWrap::Unwrap(args.This())->GetValue(); - const git_diff_options * from_opts; - if (args[1]->IsObject()) { - from_opts = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - } else { - from_opts = 0; - } - baton->opts = from_opts; - - NanCallback *callback = new NanCallback(Local::Cast(args[2])); - DiffWorkDirWorker *worker = new DiffWorkDirWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - worker->SaveToPersistent("old_tree", args.This()); - if (!args[1]->IsUndefined() && !args[1]->IsNull()) - worker->SaveToPersistent("opts", args[1]->ToObject()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTree::DiffWorkDirWorker::Execute() { - int result = git_diff_tree_to_workdir( - &baton->diff, - baton->repo, - baton->old_tree, - baton->opts - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTree::DiffWorkDirWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->diff != NULL) { - to = GitDiffList::New((void *)baton->diff); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -Persistent GitTree::constructor_template; diff --git a/src/tree_builder.cc b/src/tree_builder.cc deleted file mode 100644 index fd08dda9d..000000000 --- a/src/tree_builder.cc +++ /dev/null @@ -1,346 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/tree_builder.h" -#include "../include/repo.h" -#include "../include/oid.h" -#include "../include/tree_entry.h" -#include "../include/tree.h" -#include "../include/diff_list.h" -#include "../include/diff_options.h" -#include "../include/index.h" - -using namespace v8; -using namespace node; - -GitTreeBuilder::GitTreeBuilder(git_treebuilder *raw) { - this->raw = raw; -} - -GitTreeBuilder::~GitTreeBuilder() { - git_treebuilder_free(this->raw); -} - -void GitTreeBuilder::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("TreeBuilder")); - - NODE_SET_METHOD(tpl, "create", Create); - NODE_SET_PROTOTYPE_METHOD(tpl, "clear", Clear); - NODE_SET_METHOD(tpl, "size", Size); - NODE_SET_PROTOTYPE_METHOD(tpl, "get", Get); - NODE_SET_PROTOTYPE_METHOD(tpl, "insert", Insert); - NODE_SET_PROTOTYPE_METHOD(tpl, "gitTreebuilderRemove", GitTreebuilderRemove); - NODE_SET_PROTOTYPE_METHOD(tpl, "write", Write); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("TreeBuilder"), _constructor_template); -} - -NAN_METHOD(GitTreeBuilder::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_treebuilder is required."); - } - GitTreeBuilder* object = new GitTreeBuilder(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitTreeBuilder::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitTreeBuilder::constructor_template)->NewInstance(1, argv)); -} - -git_treebuilder *GitTreeBuilder::GetValue() { - return this->raw; -} - - -/** - * @param {Tree} source - * @return {TreeBuilder} out - */ -NAN_METHOD(GitTreeBuilder::Create) { - NanScope(); - - git_treebuilder * out = 0; - const git_tree * from_source; - if (args[0]->IsObject()) { - from_source = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - } else { - from_source = 0; - } - - int result = git_treebuilder_create( - &out - , from_source - ); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - to = GitTreeBuilder::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {TreeBuilder} bld - */ -NAN_METHOD(GitTreeBuilder::Clear) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("TreeBuilder bld is required."); - } - - git_treebuilder * from_bld; - from_bld = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - - git_treebuilder_clear( - from_bld - ); - - NanReturnUndefined(); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitTreeBuilder::Size) { - NanScope(); - - - unsigned int result = git_treebuilder_entrycount( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew((uint32_t)result); - NanReturnValue(to); -} - -/** - * @param {String} filename - * @return {TreeEntry} result - */ -NAN_METHOD(GitTreeBuilder::Get) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String filename is required."); - } - - const char * from_filename; - String::Utf8Value filename(args[0]->ToString()); - from_filename = strdup(*filename); - - const git_tree_entry * result = git_treebuilder_get( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_filename - ); - free((void *)from_filename); - - Handle to; - if (result != NULL) { - result = (const git_tree_entry * )git_tree_entry_dup(result); - } - if (result != NULL) { - to = GitTreeEntry::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} filename - * @param {Oid} id - * @param {Number} filemode - * @return {TreeEntry} out - */ -NAN_METHOD(GitTreeBuilder::Insert) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String filename is required."); - } - if (args.Length() == 1 || !args[1]->IsObject()) { - return NanThrowError("Oid id is required."); - } - if (args.Length() == 2 || !args[2]->IsNumber()) { - return NanThrowError("Number filemode is required."); - } - - const git_tree_entry * out = 0; - const char * from_filename; - String::Utf8Value filename(args[0]->ToString()); - from_filename = strdup(*filename); - const git_oid * from_id; - from_id = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - git_filemode_t from_filemode; - from_filemode = (git_filemode_t) (int) args[2]->ToNumber()->Value(); - - int result = git_treebuilder_insert( - &out - , ObjectWrap::Unwrap(args.This())->GetValue() - , from_filename - , from_id - , from_filemode - ); - free((void *)from_filename); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - Handle to; - if (out != NULL) { - out = (const git_tree_entry * )git_tree_entry_dup(out); - } - if (out != NULL) { - to = GitTreeEntry::New((void *)out); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @param {String} filename - */ -NAN_METHOD(GitTreeBuilder::GitTreebuilderRemove) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsString()) { - return NanThrowError("String filename is required."); - } - - const char * from_filename; - String::Utf8Value filename(args[0]->ToString()); - from_filename = strdup(*filename); - - int result = git_treebuilder_remove( - ObjectWrap::Unwrap(args.This())->GetValue() - , from_filename - ); - free((void *)from_filename); - if (result != GIT_OK) { - if (giterr_last()) { - return NanThrowError(giterr_last()->message); - } else { - return NanThrowError("Unknown Error"); - } - } - - NanReturnUndefined(); -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {Oid} callback - */ -NAN_METHOD(GitTreeBuilder::Write) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - WriteBaton* baton = new WriteBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - baton->id = (git_oid *)malloc(sizeof(git_oid )); - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - baton->bld = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - WriteWorker *worker = new WriteWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - worker->SaveToPersistent("bld", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTreeBuilder::WriteWorker::Execute() { - int result = git_treebuilder_write( - baton->id, - baton->repo, - baton->bld - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTreeBuilder::WriteWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->id != NULL) { - to = GitOid::New((void *)baton->id); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - free(baton->id); - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -Persistent GitTreeBuilder::constructor_template; diff --git a/src/tree_entry.cc b/src/tree_entry.cc deleted file mode 100755 index 10fe341fc..000000000 --- a/src/tree_entry.cc +++ /dev/null @@ -1,222 +0,0 @@ -/** - * This code is auto-generated; unless you know what you're doing, do not modify! - **/ -#include -#include - -#include "git2.h" - -#include "../include/functions/copy.h" - -#include "../include/tree_entry.h" -#include "../include/oid.h" -#include "../include/repo.h" -#include "../include/object.h" - -using namespace v8; -using namespace node; - -GitTreeEntry::GitTreeEntry(git_tree_entry *raw) { - this->raw = raw; -} - -GitTreeEntry::~GitTreeEntry() { - git_tree_entry_free(this->raw); -} - -void GitTreeEntry::Initialize(Handle target) { - NanScope(); - - Local tpl = NanNew(New); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); - tpl->SetClassName(NanNew("TreeEntry")); - - NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); - NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid); - NODE_SET_PROTOTYPE_METHOD(tpl, "type", Type); - NODE_SET_PROTOTYPE_METHOD(tpl, "filemode", filemode); - NODE_SET_PROTOTYPE_METHOD(tpl, "getObject", GetObject); - - - Local _constructor_template = tpl->GetFunction(); - NanAssignPersistent(constructor_template, _constructor_template); - target->Set(NanNew("TreeEntry"), _constructor_template); -} - -NAN_METHOD(GitTreeEntry::New) { - NanScope(); - - if (args.Length() == 0 || !args[0]->IsExternal()) { - return NanThrowError("git_tree_entry is required."); - } - GitTreeEntry* object = new GitTreeEntry(static_cast(Handle::Cast(args[0])->Value())); - object->Wrap(args.This()); - - NanReturnValue(args.This()); -} - -Handle GitTreeEntry::New(void *raw) { - NanEscapableScope(); - Handle argv[1] = { NanNew((void *)raw) }; - return NanEscapeScope(NanNew(GitTreeEntry::constructor_template)->NewInstance(1, argv)); -} - -git_tree_entry *GitTreeEntry::GetValue() { - return this->raw; -} - - -/** - * @return {String} result - */ -NAN_METHOD(GitTreeEntry::Name) { - NanScope(); - - - const char * result = git_tree_entry_name( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Oid} result - */ -NAN_METHOD(GitTreeEntry::Oid) { - NanScope(); - - - const git_oid * result = git_tree_entry_id( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - if (result != NULL) { - result = (const git_oid * )git_oid_dup(result); - } - if (result != NULL) { - to = GitOid::New((void *)result); - } else { - to = NanNull(); - } - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitTreeEntry::Type) { - NanScope(); - - - git_otype result = git_tree_entry_type( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -/** - * @return {Number} result - */ -NAN_METHOD(GitTreeEntry::filemode) { - NanScope(); - - - git_filemode_t result = git_tree_entry_filemode( - ObjectWrap::Unwrap(args.This())->GetValue() - ); - - Handle to; - to = NanNew(result); - NanReturnValue(to); -} - -#include "../include/functions/copy.h" - -/** - * @param {Repository} repo - * @param {Object} callback - */ -NAN_METHOD(GitTreeEntry::GetObject) { - NanScope(); - if (args.Length() == 0 || !args[0]->IsObject()) { - return NanThrowError("Repository repo is required."); - } - - if (args.Length() == 1 || !args[1]->IsFunction()) { - return NanThrowError("Callback is required and must be a Function."); - } - - GetObjectBaton* baton = new GetObjectBaton; - baton->error_code = GIT_OK; - baton->error = NULL; - git_repository * from_repo; - from_repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - baton->repo = from_repo; - baton->entry = ObjectWrap::Unwrap(args.This())->GetValue(); - - NanCallback *callback = new NanCallback(Local::Cast(args[1])); - GetObjectWorker *worker = new GetObjectWorker(baton, callback); - if (!args[0]->IsUndefined() && !args[0]->IsNull()) - worker->SaveToPersistent("repo", args[0]->ToObject()); - worker->SaveToPersistent("entry", args.This()); - - NanAsyncQueueWorker(worker); - NanReturnUndefined(); -} - -void GitTreeEntry::GetObjectWorker::Execute() { - int result = git_tree_entry_to_object( - &baton->object_out, - baton->repo, - baton->entry - ); - baton->error_code = result; - if (result != GIT_OK && giterr_last() != NULL) { - baton->error = git_error_dup(giterr_last()); - } -} - -void GitTreeEntry::GetObjectWorker::HandleOKCallback() { - TryCatch try_catch; - if (baton->error_code == GIT_OK) { - Handle to; - if (baton->object_out != NULL) { - to = GitObject::New((void *)baton->object_out); - } else { - to = NanNull(); - } - Handle result = to; - Handle argv[2] = { - NanNull(), - result - }; - callback->Call(2, argv); - } else { - if (baton->error) { - Handle argv[1] = { - NanError(baton->error->message) - }; - callback->Call(1, argv); - if (baton->error->message) - free((void *)baton->error->message); - free((void *)baton->error); - } else { - callback->Call(0, NULL); - } - } - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - delete baton; -} - -Persistent GitTreeEntry::constructor_template; diff --git a/test/blob.js b/test/blob.js deleted file mode 100644 index c3e9363c7..000000000 --- a/test/blob.js +++ /dev/null @@ -1,13 +0,0 @@ -var git = require('../'), - path = require('path'); - -exports.content = function(test) { - var testOid = git.Oid.fromString('111dd657329797f6165f52f5085f61ac976dcf04'); - test.expect(1); - git.Repo.open(path.resolve('repos/workdir/.git'), function(err, repo) { - repo.getBlob(testOid, function(err, blob) { - test.equals(blob.toString().slice(0, 7), "@import"); - test.done(); - }); - }); -}; diff --git a/test/commit.js b/test/commit.js deleted file mode 100644 index ef0b51e8e..000000000 --- a/test/commit.js +++ /dev/null @@ -1,242 +0,0 @@ -var git = require('../'), - rimraf = require('rimraf'), - fs = require( 'fs' ); - -var historyCountKnownSHA = 'fce88902e66c72b5b93e75bdb5ae717038b221f6'; - -exports.message = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var message = commit.message(); - test.equals(error, null, 'There should be no error'); - test.equals(message, 'Update README.md', 'Message should match expected value'); - test.done(); - }); - }); -}; - -exports.sha = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var sha = commit.sha(); - test.equals(error, null, 'There should be no error'); - test.equals(sha, historyCountKnownSHA, 'SHA should match expected value'); - test.done(); - }); - }); -}; - -exports.time = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var time = commit.timeMs(); - test.equals(error, null, 'There should be no error'); - test.equals(time, 1362012884000, 'Time should match expected value'); - test.done(); - }); - }); -}; - -exports.date = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var date = commit.date(); - test.equals(error, null, 'There should be no error'); - test.equals(date.getTime(), 1362012884000, 'Date should match expected value'); - test.done(); - }); - }); -}; - -exports.offset = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var offset = commit.offset(); - test.equals(error, null, 'There should be no error'); - test.equals(offset, 780, 'Offset should match expected value'); - test.done(); - }); - }); -}; - -exports.author = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var author = commit.author(); - test.equals(error, null, 'There should be no error'); - test.notEqual(author, null, 'Author should not be null'); - test.done(); - }); - }); -}; - -exports.authorName = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var author = commit.author(); - var name = author.name(); - test.equals(name, 'Michael Robinson', 'The author name should match expected value'); - test.done(); - }); - }); -}; - -exports.authorEmail = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var author = commit.author(); - var email = author.email(); - test.equals(email, 'mike@panmedia.co.nz', 'The author email should match expected value'); - test.done(); - }); - }); -}; - -exports.committerName = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var committer = commit.committer(); - var name = committer.name(); - test.equals(name, 'Michael Robinson', 'The author name should match expected value'); - test.done(); - }); - }); -}; - -exports.committerEmail = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - var committer = commit.committer(); - var email = committer.email(); - test.equals(email, 'mike@panmedia.co.nz', 'The committer email should match expected value'); - test.done(); - }); - }); -}; - -/** - * Test that improper commit ID's result in an error message - */ -exports.improperCommitId = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit('not a proper commit sha', function(error, commit) { - test.notEqual(error, null, 'Error should occur'); - test.done(); - }); - }); -}; - -/** - * Test that retreiving walking a given commit's history works as expected. - */ -exports.history = function(test) { - test.expect(4); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - test.equals(null, error, 'Getting latest branch commit should not error'); - var historyCount = 0; - var expectedHistoryCount = 364; - commit.history().on('commit', function(commit) { - historyCount++; - }).on('end', function(commits) { - test.equals(null, error, 'There should be no errors'); - test.equals(historyCount, expectedHistoryCount); - test.equals(commits.length, expectedHistoryCount); - test.done(); - }).on('error', function(error) { - test.equals(null, error, 'There should be no errors'); - test.ok(false, 'There should be no errors'); - }).start(); - }); - }); -}; - -/** - * Test that retreiving master branch's HEAD commit works as expected. - */ -exports.masterHead = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getBranch('master', function(error, branch) { - var sha = branch.sha(); - repository.getCommit(sha, function(error, commit) { - test.equals(error, null, 'Getting latest branch commit should not error'); - test.done(); - }); - }); - }); -}; - -/** - * Test that retreiving parent works as expected. - * - * @param {Object} test - */ -exports.parents = function(test) { - test.expect(3); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - commit.getParents(function(error, parents) { - test.equals(parents.length, 1, 'Commit should have exactly one parent'); - var sha = parents[0].sha(); - test.equals(error, null, 'Getting parent SHA should not error'); - test.equals(sha, 'ecfd36c80a3e9081f200dfda2391acadb56dac27', 'Parent SHA should match expected value'); - test.done(); - }); - }); - }); -}; - -/** - * Test that retrieving and walking a commit's tree works as expected. - */ -exports.tree = function(test) { - test.expect(2); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - test.equals(error, null, 'Getting latest branch commit should not error'); - - var commitTreeEntryCount = 0; - var expectedCommitTreeEntryCount = 198; - commit.getTree(function(error, tree) { - tree.walk().on('entry', function(entry) { - commitTreeEntryCount++; - }).on('end', function(error, entries) { - test.equals(commitTreeEntryCount, expectedCommitTreeEntryCount, 'Commit tree entry count does not match expected'); - test.done(); - }).start(); - }); - }); - }); -}; - -/** - * Test that getDiff works as expected. - */ -exports.getDiff = function(test) { - test.expect(1); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - commit.getDiff(function(error, diff) { - test.equals(diff.length, 1, 'Should be one item in parents diff trees'); - test.done(); - }); - }); - }); -}; - -process.on('uncaughtException', function(err) { - console.log(err.stack); -}); - diff --git a/test/difflist.js b/test/difflist.js deleted file mode 100644 index 3c9e0f919..000000000 --- a/test/difflist.js +++ /dev/null @@ -1,49 +0,0 @@ -var git = require('../'), - rimraf = require('rimraf'), - fs = require( 'fs' ); - -var historyCountKnownSHA = 'fce88902e66c72b5b93e75bdb5ae717038b221f6'; - -/** - * Test that retreiving parent works as expected. - * - * @param {Object} test - */ -exports.walkingDiffs = function(test) { - test.expect(16); - git.Repo.open('repos/workdir/.git', function(error, repository) { - repository.getCommit(historyCountKnownSHA, function(error, commit) { - commit.getDiff(function(error, diffList) { - test.equal(null, error, 'Should not error'); - - diffList[0].patches().forEach(function(patch) { - test.equal(null, error, 'Should not error'); - - test.equal(patch.oldFile().path(), 'README.md', 'Old file path should match expected'); - test.equal(patch.newFile().path(), 'README.md', 'New file path should match expected'); - test.equal(patch.size(), 1, 'Content array should be of known length'); - test.ok(patch.isModified(), 'Status should be known type'); - - var hunk = patch.hunks()[0]; - test.equal(hunk.size(), 5, 'Content array should be of known length'); - var lines = hunk.lines(); - - test.equal(lines[0].lineOrigin, git.DiffList.LineOrigin.Context, 'First content item should be context'); - test.equal(lines[1].lineOrigin, git.DiffList.LineOrigin.Context, 'Second content item should be context'); - test.equal(lines[2].lineOrigin, git.DiffList.LineOrigin.Context, 'Third content item should be context'); - - var oldContent = '__Before submitting a pull request, please ensure both unit tests and lint checks pass.__\n'; - test.equal(lines[3].content, oldContent, 'Old content should match known value'); - test.equal(lines[3].lineOrigin, git.DiffList.LineOrigin.Deletion, 'Fourth content item should be deletion'); - test.equal(lines[3].length, 90, 'Fourth content length should match known value'); - - var newContent = '__Before submitting a pull request, please ensure both that you\'ve added unit tests to cover your shiny new code, and that all unit tests and lint checks pass.__\n'; - test.equal(lines[4].content, newContent, 'New content should match known value'); - test.equal(lines[4].lineOrigin, git.DiffList.LineOrigin.Addition, 'Fifth content item should be addition'); - test.equal(lines[4].length, 162, 'Fifth content length should match known value'); - test.done(); - }); - }); - }); - }); -}; diff --git a/test/index.js b/test/index.js new file mode 100644 index 000000000..288e7a720 --- /dev/null +++ b/test/index.js @@ -0,0 +1,13 @@ +var args = [ + "cover", + process.platform != "win32" ? "_mocha" : "../node_modules/mocha/bin/_mocha", + "--", + "runner", + "tests", + "--report=lcov", + "--expose-gc" + ]; + +require("child_process").fork("../node_modules/istanbul/lib/cli.js", args, { + cwd: __dirname +}); diff --git a/test/nodegit.js b/test/nodegit.js deleted file mode 100644 index b603e7ae5..000000000 --- a/test/nodegit.js +++ /dev/null @@ -1,40 +0,0 @@ -var fs = require('fs'); -var rimraf = require('rimraf'); -var exec = require('child_process').exec; -var path = require('path'); -var async = require('async'); - -var testFiles = ['blob','difflist','oid','repo','tree_entry','commit','reference','revwalk','tree']; - -function setupReposCache(cb) { - fs.mkdir('repos',function() { - async.series([ - function empty(cb) { exec('git init repos/empty',function() { cb(); }); }, - function workdir(cb) { exec('git clone https://github.com/nodegit/nodegit.git repos/workdir',function() { cb(); }); }, - function nonrepo(cb) { - fs.mkdir('repos/nonrepo',function() { - fs.writeFile('repos/nonrepo/file.txt','This is a bogus file',function() { - cb(); - }); - }); - } - ],function() { - cb(); - }); - }); -} - -exports.setUp = function(cb) { - fs.exists('.reposCache', function(exists) { - if (!exists) { - setupReposCache(function(err) { - cb(); - }); - } - }); -}; - -Object.keys(testFiles).forEach(function(fileName) { - var testFile = testFiles[fileName] - exports[testFile] = require('./' + testFile); -}); diff --git a/test/oid.js b/test/oid.js deleted file mode 100644 index 3ce3d48d1..000000000 --- a/test/oid.js +++ /dev/null @@ -1,10 +0,0 @@ -var git = require('../'); - -var knownSha = 'fce88902e66c72b5b93e75bdb5ae717038b221f6'; - -exports.fromStringAndSha = function(test) { - test.expect(1); - var oid = git.Oid.fromString(knownSha); - test.equal(oid.sha(), knownSha, 'SHA should match known value'); - test.done(); -}; diff --git a/test/reference.js b/test/reference.js deleted file mode 100644 index e608a622f..000000000 --- a/test/reference.js +++ /dev/null @@ -1,14 +0,0 @@ -var git = require('../'), - rimraf = require('rimraf'); - -// Ref::Lookup -exports.lookup = function(test) { - test.expect(1); - - git.Repo.open('repos/workdir/.git', function(error, repo) { - repo.getReference('refs/heads/master', function(error, reference) { - test.ok(reference instanceof git.Reference); - test.done(); - }); - }); -}; diff --git a/test/repo.js b/test/repo.js deleted file mode 100644 index 70f3128dd..000000000 --- a/test/repo.js +++ /dev/null @@ -1,57 +0,0 @@ -var git = require('../'), - rimraf = require('rimraf'), - fs = require( 'fs' ); - -/** - * Repo - * Ensure the repo method can handle opening repositories with async/sync - * signatures properly. - */ -exports.openInvalidRepo = function(test){ - test.expect(1); - - // Test invalid repository - git.Repo.open('repos/nonrepo', function(error, repository) { - test.ok(error instanceof Error); - test.done(); - }); -}; - -exports.openValidRepo = function(test){ - test.expect(1); - - // Test valid repository - git.Repo.open('repos/workdir/.git', function(error, repository) { - test.equals(null, error, 'Valid repository error code'); - test.done(); - }); -}; - -/** - * Ensure repo doesn't attempt to open missing directories - */ -exports.nonexistentDirectory = function(test) { - test.expect(2); - git.Repo.open('/surely/this/directory/does/not/exist/on/this/machine', function(error, repository) { - test.notEqual(error, null, 'Attempting to open a nonexistent directory should error'); - test.equals(repository, null, 'Non existent directory should result in null repository'); - test.done(); - }); -}; - -/** - * Ensure the init method can create repositories at the destination path and - * can create either bare/non-bare. - */ -exports.init = function(test) { - test.expect(2); - // Create bare repo and test for creation - git.Repo.init('repos/newrepo', true, function(error, path, isBare) { - test.equals(null, error, 'Successfully created bare repository'); - // Verify repo exists - git.Repo.open('repos/newrepo', function(error, path, repo) { - test.equals(null, error, 'Valid repository created'); - test.done(); - }); - }); -}; diff --git a/test/revwalk.js b/test/revwalk.js deleted file mode 100644 index 469f18b51..000000000 --- a/test/revwalk.js +++ /dev/null @@ -1,24 +0,0 @@ -var git = require('../').raw, - path = require('path'), - rimraf = require('rimraf'); - -// Helper functions -var helper = { - // Test if obj is a true function - testFunction: function(test, obj, label) { - // The object reports itself as a function - test(typeof obj, 'function', label +' reports as a function.'); - // This ensures the repo is actually a derivative of the Function [[Class]] - test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); - }, - // Test code and handle exception thrown - testException: function(test, fun, label) { - try { - fun(); - test(false, label); - } - catch (ex) { - test(true, label); - } - } -}; diff --git a/test/runner.js b/test/runner.js new file mode 100644 index 000000000..8b2d0052e --- /dev/null +++ b/test/runner.js @@ -0,0 +1,37 @@ +var promisify = require("promisify-node"); +var fse = promisify("fs-extra"); + +// Have to wrap exec, since it has a weird callback signature. +var exec = promisify(function(command, opts, callback) { + return require("child_process").exec(command, opts, callback); +}); + +before(function(done) { + this.timeout(350000); + + var url = "https://github.com/nodegit/test"; + var done = done.bind(null, null); + + function initEmpty() { + return exec("git init test/repos/empty"); + } + + fse.removeSync("test/repos") + + fse.mkdir("test/repos").then(initEmpty, initEmpty) + .then(function() { + return exec("git clone " + url + " test/repos/workdir"); + }).then(function() { + return exec("git checkout rev-walk", {cwd: "test/repos/workdir"}) + }).then(function() { + return exec("git checkout master", {cwd: "test/repos/workdir"}) + }).then(function() { + var nonrepo = "test/repos/nonrepo"; + + function writeBogus() { + return fse.writeFile(nonrepo + "/file.txt", "This is a bogus file"); + } + + return fse.mkdir(nonrepo).then(writeBogus, writeBogus); + }).then(done, done); +}); diff --git a/test/tests/attr.js b/test/tests/attr.js new file mode 100644 index 000000000..c5b7690f1 --- /dev/null +++ b/test/tests/attr.js @@ -0,0 +1,33 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Attr", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Attr = require("../../lib/attr"); + var Status = require("../../lib/status"); + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + }); + }); + + it("can add a macro definition", function() { + var error = Attr.addMacro(this.repository, "binary", "-diff -crlf"); + + assert.equal(error, 0); + }); + + it("can flush the attr cache", function() { + Attr.cacheFlush(this.repository); + }); + + it("can lookup the value of a git attribute", function() { + var flags = Status.SHOW.INDEX_AND_WORKDIR; + return Attr.get(this.repository, flags, ".gitattributes", "test"); + }); +}); diff --git a/test/tests/blob.js b/test/tests/blob.js new file mode 100644 index 000000000..06856cc03 --- /dev/null +++ b/test/tests/blob.js @@ -0,0 +1,39 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Blob", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + var oid = "111dd657329797f6165f52f5085f61ac976dcf04"; + + var Repository = require("../../lib/repository"); + var FileMode = require("../../lib/tree_entry").FILEMODE; + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + + return repository.getBlob(oid).then(function(blob) { + test.blob = blob; + }); + }); + }); + + it("can provide content as a buffer", function() { + var contents = this.blob.content(); + + assert.ok(Buffer.isBuffer(contents)); + }); + + it("can provide content as a string", function() { + var contents = this.blob.toString(); + + assert.equal(typeof contents, "string"); + assert.equal(contents.slice(0, 7), "@import"); + }); + + it("can determine if a blob is not a binary", function() { + assert.equal(this.blob.filemode(), FileMode.BLOB); + }); +}); diff --git a/test/tests/branch.js b/test/tests/branch.js new file mode 100644 index 000000000..6b717e476 --- /dev/null +++ b/test/tests/branch.js @@ -0,0 +1,63 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Branch", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Branch = require("../../lib/branch"); + var branchName = "test-branch"; + var fullBranchName = "refs/heads/" + branchName; + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repo = repository; + }); + }); + + beforeEach(function() { + var test = this; + var repo = test.repo; + + return repo.getMasterCommit().then(function(masterCommit) { + test.masterCommit = masterCommit; + + return repo.createBranch(branchName, masterCommit, true) + .then(function(branch) { + test.branch = branch; + }); + }); + }); + + it("can create a branch", function() { + var branch = this.branch; + var masterCommit = this.masterCommit; + + assert.equal(branch.name(), fullBranchName); + assert.equal(branch.target().toString(), masterCommit.sha()); + }); + + it("can delete a branch", function() { + var repo = this.repo; + + Branch.delete(this.branch); + + return repo.getBranch(branchName).then(function() { + // branch wasn't deleted + assert.ok(false); + }, function() { + // branch was deleted! + assert.ok(true); + }); + }); + + it("can see if the branch is pointed to by head", function() { + var repo = this.repo; + + return repo.getBranch("master").then(function(branch) { + assert.ok(branch.isHead()); + }); + }); +}); diff --git a/test/tests/checkout.js b/test/tests/checkout.js new file mode 100644 index 000000000..327c7d399 --- /dev/null +++ b/test/tests/checkout.js @@ -0,0 +1,15 @@ +var path = require("path"); + +describe("Checkout", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + }); + }); +}); diff --git a/test/tests/clone.js b/test/tests/clone.js new file mode 100644 index 000000000..26971dea8 --- /dev/null +++ b/test/tests/clone.js @@ -0,0 +1,82 @@ +var assert = require("assert"); +var path = require("path"); +var Promise = require("promise"); +var promisify = require("promisify-node"); +var rimraf = promisify("rimraf"); + +describe("Clone", function() { + var http = path.resolve("test/repos/http"); + var https = path.resolve("test/repos/https"); + var ssh = path.resolve("test/repos/ssh"); + var git = path.resolve("test/repos/git"); + var file = path.resolve("test/repos/file"); + + var Repository = require("../../lib/repository"); + var Clone = require("../../lib/clone"); + var NodeGit = require("../../"); + + // Set a reasonable timeout here now that our repository has grown. + this.timeout(15000); + + before(function() { + return Promise.all([ + rimraf(http), + rimraf(https), + rimraf(ssh), + rimraf(git), + rimraf(file), + ]); + }); + + it("can clone with http", function() { + var url = "http://github.com/nodegit/test.git"; + var opts = { ignoreCertErrors: 1 }; + + return Clone.clone(url, http, opts).then(function(repository) { + assert.ok(repository instanceof Repository); + }); + }); + + it("can clone with https", function() { + var url = "https://github.com/nodegit/test.git"; + var opts = { ignoreCertErrors: 1 }; + + return Clone.clone(url, https, opts).then(function(repository) { + assert.ok(repository instanceof Repository); + }); + }); + + it("can clone with ssh", function() { + var url = "git@github.com:nodegit/test.git"; + var opts = { + ignoreCertErrors: 1, + remoteCallbacks: { + credentials: function(url, userName) { + return NodeGit.Cred.sshKeyFromAgent(userName); + } + } + }; + + return Clone.clone(url, ssh, opts).then(function(repository) { + assert.ok(repository instanceof Repository); + }); + }); + + it("can clone with git", function() { + var url = "git://github.com/nodegit/test.git"; + var opts = { ignoreCertErrors: 1 }; + + return Clone.clone(url, git, opts).then(function(repository) { + assert.ok(repository instanceof Repository); + }); + }); + + it("can clone with filesystem", function() { + var prefix = process.platform === "win32" ? "" : "file://"; + var url = prefix + path.resolve("test/repos/empty"); + + return Clone.clone(url, file).then(function(repository) { + assert.ok(repository instanceof Repository); + }); + }); +}); diff --git a/test/tests/commit.js b/test/tests/commit.js new file mode 100644 index 000000000..dee52dfc7 --- /dev/null +++ b/test/tests/commit.js @@ -0,0 +1,259 @@ +var assert = require("assert"); +var path = require("path"); +var Promise = require("nodegit-promise"); +var promisify = require("promisify-node"); +var fse = promisify(require("fs-extra")); + +var NodeGit = require("../../"); +var Repository = NodeGit.Repository; + +describe("Commit", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + var oid = "fce88902e66c72b5b93e75bdb5ae717038b221f6"; + + beforeEach(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + + return repository.getCommit(oid).then(function(commit) { + test.commit = commit; + }); + }); + }); + + it("will fail with an invalid sha", function() { + return this.repository.getCommit("invalid").then(null, function(err) { + assert.ok(err instanceof Error); + }); + }); + + it("has a message", function() { + assert.equal(this.commit.message(), "Update README.md"); + }); + + it("has a raw message", function() { + assert.equal(this.commit.messageRaw(), "Update README.md"); + }); + + it("has a message encoding", function() { + var encoding = this.commit.messageEncoding(); + assert.ok(encoding === "UTF-8" || encoding === undefined); + }); + + it("has a summary", function() { + assert.equal(this.commit.summary(), "Update README.md"); + }); + + it("has a sha", function() { + assert.equal(this.commit.sha(), oid); + }); + + it("has a time", function() { + assert.equal(this.commit.timeMs(), 1362012884000); + }); + + it("has a date", function() { + assert.equal(this.commit.date().getTime(), 1362012884000); + }); + + it("has a time offset", function() { + assert.equal(this.commit.timeOffset(), 780); + }); + + it("can create a commit", function() { + var expectedCommitId = "315e77328ef596f3bc065d8ac6dd2c72c09de8a5"; + var fileName = "newfile.txt"; + var fileContent = "hello world"; + + var repo; + var index; + var treeOid; + var parent; + + return NodeGit.Repository.open(reposPath) + .then(function(repoResult) { + repo = repoResult; + return fse.writeFile(path.join(repo.workdir(), fileName), fileContent); + }) + .then(function() { + return repo.openIndex(); + }) + .then(function(indexResult) { + index = indexResult; + return index.read(1); + }) + .then(function() { + return index.addByPath(fileName); + }) + .then(function() { + return index.write(); + }) + .then(function() { + return index.writeTree(); + }) + .then(function(oidResult) { + treeOid = oidResult; + return NodeGit.Reference.nameToId(repo, "HEAD"); + }) + .then(function(head) { + return repo.getCommit(head); + }) + .then(function(parentResult) { + parent = parentResult; + + return Promise.all([ + NodeGit.Signature.create("Foo Bar", "foo@bar.com", 123456789, 60), + NodeGit.Signature.create("Foo A Bar", "foo@bar.com", 987654321, 90) + ]); + }) + .then(function(signatures){ + var author = signatures[0]; + var committer = signatures[1]; + + return repo.createCommit( + "HEAD", + author, + committer, + "message", + treeOid, + [parent]); + }) + .then(function(commitId) { + assert.equal(expectedCommitId, commitId); + }, function(rejected) { + assert.fail(); + }); + }); + + describe("author", function() { + before(function() { + this.author = this.commit.author(); + }); + + it("is available", function() { + assert.ok(this.author instanceof NodeGit.Signature); + }); + + it("has a name", function() { + assert.equal(this.author.name(), "Michael Robinson"); + }); + + it("has an email", function() { + assert.equal(this.author.email(), "mike@panmedia.co.nz"); + }); + }); + + describe("committer", function() { + before(function() { + this.author = this.commit.committer(); + }); + + it("is available", function() { + assert.ok(this.author instanceof NodeGit.Signature); + }); + + it("has a name", function() { + assert.equal(this.author.name(), "Michael Robinson"); + }); + + it("has an email", function() { + assert.equal(this.author.email(), "mike@panmedia.co.nz"); + }); + }); + + it("has owner", function() { + var owner = this.commit.owner(); + assert.ok(owner instanceof Repository); + }); + + it("can walk its repository's history", function(done) { + var historyCount = 0; + var expectedHistoryCount = 364; + + var history = this.commit.history(); + + history.on("commit", function(commit) { + historyCount++; + }); + + history.on("end", function(commits) { + assert.equal(historyCount, expectedHistoryCount); + assert.equal(commits.length, expectedHistoryCount); + + done(); + }); + + history.on("error", function(err) { + assert.ok(false); + }); + + history.start(); + }); + + it("can fetch the master branch HEAD", function() { + var repository = this.repository; + + return repository.getBranchCommit("master").then(function(commit) { + return repository.getCommit(commit.sha()); + }); + }); + + it("can fetch all its parents", function() { + return this.commit.getParents().then(function(parents) { + assert.equal(parents.length, 1); + + var sha = parents[0].sha(); + assert.equal(sha, "ecfd36c80a3e9081f200dfda2391acadb56dac27"); + }); + }); + + it("can specify a parents limit", function() { + return this.commit.getParents(0).then(function(parents) { + assert.equal(parents.length, 0); + }); + }); + + it("has a parent count", function() { + assert.equal(1, this.commit.parentcount()); + }); + + it("can retrieve and walk a commit tree", function() { + var commitTreeEntryCount = 0; + var expectedCommitTreeEntryCount = 198; + + return this.commit.getTree().then(function(tree) { + return new Promise(function(resolve, fail) { + + var treeWalker = tree.walk(); + + treeWalker.on("entry", function(entry) { + commitTreeEntryCount++; + }); + + treeWalker.on("error", function(error) { + fail(error); + }); + + treeWalker.on("end", function(entries) { + try { + assert.equal(commitTreeEntryCount, expectedCommitTreeEntryCount); + resolve(); + } + catch (e) { + fail(e); + } + }); + + treeWalker.start(); + }); + }); + }); + + it("can get the commit diff", function() { + return this.commit.getDiff().then(function(diff) { + assert.equal(diff.length, 1); + }); + }); +}); diff --git a/test/tests/cred.js b/test/tests/cred.js new file mode 100644 index 000000000..3cda288f8 --- /dev/null +++ b/test/tests/cred.js @@ -0,0 +1,29 @@ +var assert = require("assert"); + +describe("Cred", function() { + var NodeGit = require("../../"); + + it("can create default credentials", function() { + NodeGit.Cred.defaultNew().then(function (defaultCreds) { + assert(defaultCreds instanceof NodeGit.Cred); + }); + }); + + it("can create ssh credentials using passed keys", function() { + NodeGit.Cred.sshKeyNew( + "username", + "public key", + "private key", + "passphrase") + .then(function (sshCreds) { + assert(sshCreds instanceof NodeGit.Cred); + }); + }); + + it("can create credentials using plaintext", function() { + NodeGit.Cred.userpassPlaintextNew("username", "password") + .then(function (plaintextCreds) { + assert(plaintextCreds instanceof NodeGit.Cred); + }); + }); +}); diff --git a/test/tests/diff.js b/test/tests/diff.js new file mode 100644 index 000000000..23800e6ff --- /dev/null +++ b/test/tests/diff.js @@ -0,0 +1,56 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Diff", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + var oid = "fce88902e66c72b5b93e75bdb5ae717038b221f6"; + + var Repository = require("../../lib/repository"); + var Diff = require("../../lib/diff"); + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + + return repository.getCommit(oid).then(function(commit) { + test.commit = commit; + + return commit.getDiff().then(function(diff) { + test.diff = diff; + }); + }); + }); + }); + + it("can walk a DiffList", function() { + var patch = this.diff[0].patches()[0]; + + assert.equal(patch.oldFile().path(), "README.md"); + assert.equal(patch.newFile().path(), "README.md"); + assert.equal(patch.size(), 1); + assert.ok(patch.isModified()); + + var hunk = patch.hunks()[0]; + assert.equal(hunk.size(), 5); + + var lines = hunk.lines(); + assert.equal(lines[0].origin(), Diff.LINE.CONTEXT); + assert.equal(lines[1].origin(), Diff.LINE.CONTEXT); + assert.equal(lines[2].origin(), Diff.LINE.CONTEXT); + + var oldContent = "\n__Before submitting a pull request, please ensure " + + "both unit tests and lint checks pass.__\n"; + assert.equal(lines[2].content(), oldContent); + assert.equal(lines[3].origin(), Diff.LINE.DELETION); + assert.equal(lines[4].contentLen(), 90); + + var newContent = "__Before submitting a pull request, please ensure " + + "both that you've added unit tests to cover your shiny new code, " + + "and that all unit tests and lint checks pass.__\n"; + assert.equal(lines[3].content(), newContent); + assert.equal(lines[4].origin(), Diff.LINE.ADDITION); + assert.equal(lines[3].contentLen(), 162); + }); +}); diff --git a/test/tests/index.js b/test/tests/index.js new file mode 100644 index 000000000..0fde90161 --- /dev/null +++ b/test/tests/index.js @@ -0,0 +1,28 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Index", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repo) { + test.repo = repo; + + return repo.openIndex().then(function(index) { + test.index = index; + + return index; + }); + }); + }); + + it("can get the index of a repo and examine entries", function() { + var entries = this.index.entries(); + + assert.equal(entries[0].path(), ".gitignore"); + }); +}); diff --git a/test/tests/merge.js b/test/tests/merge.js new file mode 100644 index 000000000..72b3d9c74 --- /dev/null +++ b/test/tests/merge.js @@ -0,0 +1,287 @@ +var assert = require("assert"); +var path = require("path"); +var promisify = require("promisify-node"); +var fse = promisify(require("fs-extra")); +fse.ensureDir = promisify(fse.ensureDir); + +describe("Merge", function() { + var nodegit = require("../../"); + + var repoDir = path.resolve("test/repos/merge"); + var ourBranchName = "ours"; + var theirBranchName = "theirs"; + + beforeEach(function() { + var test = this; + return fse.remove(path.resolve(__dirname, repoDir)) + .then(function() { + return fse.ensureDir(path.resolve(__dirname, repoDir)); + }) + .then(function() { + return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0); + }) + .then(function(repo) { + test.repository = repo; + }); + }); + + it("can cleanly merge 2 files", function() { + var ourFileName = "ourNewFile.txt"; + var theirFileName = "theirNewFile.txt"; + + var ourFileContent = "I like Toll Roads. I have an EZ-Pass!"; + var theirFileContent = "I'm skeptical about Toll Roads"; + + var ourSignature = nodegit.Signature.create + ("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60); + var theirSignature = nodegit.Signature.create + ("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60); + + var repository = this.repository; + var ourCommit; + var theirCommit; + var ourBranch; + var theirBranch; + + return fse.writeFile(path.join(repository.workdir(), ourFileName), + ourFileContent) + // Load up the repository index and make our initial commit to HEAD + .then(function() { + return repository.openIndex() + .then(function(index) { + index.read(1); + index.addByPath(ourFileName); + index.write(); + + return index.writeTree(); + }); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "11ead82b1135b8e240fb5d61e703312fb9cc3d6a"); + + return repository.createCommit("HEAD", ourSignature, + ourSignature, "we made a commit", oid, []); + }) + .then(function(commitOid) { + assert.equal(commitOid.toString(), + "91a183f87842ebb7a9b08dad8bc2473985796844"); + + return repository.getCommit(commitOid).then(function(commit) { + ourCommit = commit; + }).then(function() { + return repository.createBranch(ourBranchName, commitOid) + .then(function(branch) { + ourBranch = branch; + return repository.createBranch(theirBranchName, commitOid); + }); + }); + }) + .then(function(branch) { + theirBranch = branch; + return fse.writeFile(path.join(repository.workdir(), theirFileName), + theirFileContent); + }) + .then(function() { + return repository.openIndex() + .then(function(index) { + index.read(1); + index.addByPath(theirFileName); + index.write(); + + return index.writeTree(); + }); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "76631cb5a290dafe2959152626bb90f2a6d8ec94"); + + return repository.createCommit(theirBranch.name(), theirSignature, + theirSignature, "they made a commit", oid, [ourCommit]); + }) + .then(function(commitOid) { + assert.equal(commitOid.toString(), + "0e9231d489b3f4303635fc4b0397830da095e7e7"); + + return repository.getCommit(commitOid).then(function(commit) { + theirCommit = commit; + }); + }) + .then(function() { + return nodegit.Merge.commits(repository, ourCommit, theirCommit); + }) + .then(function(index) { + assert(!index.hasConflicts()); + index.write(); + return index.writeTreeTo(repository); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "76631cb5a290dafe2959152626bb90f2a6d8ec94"); + + return repository.createCommit(ourBranch.name(), ourSignature, + ourSignature, "we merged their commit", oid, + [ourCommit, theirCommit]); + }) + .then(function(commitId) { + assert.equal(commitId.toString(), + "eedee554af34dd4001d8abc799cb55bb7e56a58b"); + }); + }); + + it("can merge 2 branchs with conflicts on a single file", function () { + var baseFileContent = "All Bobs are created equal. ish.\n"; + var ourFileContent = "Big Bobs are best, IMHO.\n"; + var theirFileContent = "Nobody expects the small Bobquisition!\n"; + var finalFileContent = + "Big Bobs are beautiful, and the small are unexpected!\n"; + + var baseSignature = nodegit.Signature.create + ("Peaceful Bob", "justchill@bob.net", 123456789, 60); + var ourSignature = nodegit.Signature.create + ("Big Bob", "impressive@bob.net", 123456789, 60); + var theirSignature = nodegit.Signature.create + ("Small Bob", "underestimated@bob.net", 123456789, 60); + + var repository = this.repository; + var baseCommit; + var baseCommitOid; + var ourCommit; + var theirCommit; + var ourBranch; + var theirBranch; + var fileName = "newFile.txt"; + + return fse.writeFile(path.join(repository.workdir(), fileName), + baseFileContent) + .then(function() { + return repository.openIndex() + .then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write(); + + return index.writeTree(); + }); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "ea2f6521fb8097a881f43796946ac1603e1f4d75"); + + return repository.createCommit("HEAD", baseSignature, + baseSignature, "bobs are all ok", oid, []); + }) + .then(function(commitOid) { + assert.equal(commitOid.toString(), + "a9b202f7612273fb3a68f718304298704eaeb735"); + baseCommitOid = commitOid; + + return repository.getCommit(commitOid).then(function(commit) { + baseCommit = commit; + }); + }) + .then(function() { + return repository.createBranch(ourBranchName, baseCommitOid) + .then(function(branch) { + ourBranch = branch; + }); + }) + .then(function() { + return repository.createBranch(theirBranchName, baseCommitOid) + .then(function(branch) { + theirBranch = branch; + }); + }) + .then(function() { + return fse.writeFile(path.join(repository.workdir(), fileName), + ourFileContent); + }) + .then(function() { + return repository.openIndex().then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write(); + + return index.writeTree(); + }); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "c39b1e38b09085856cec7e7ff33e90f5a537d8a5"); + + return repository.createCommit(ourBranch.name(), ourSignature, + ourSignature, "lol big bobs :yesway:", oid, [baseCommit]); + }) + .then(function(commitOid) { + assert.equal(commitOid.toString(), + "935a89c09ad757a9dde2c0257f6f1e379f71816f"); + + return repository.getCommit(commitOid).then(function(commit) { + ourCommit = commit; + }); + }) + .then(function() { + return fse.writeFile(path.join(repository.workdir(), fileName), + theirFileContent); + }) + .then(function() { + return repository.openIndex().then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write(); + + return index.writeTree(); + }); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "d1a894a9a4a8c820eb66c82cdd7e6b76c8f713cb"); + + return repository.createCommit(theirBranch.name(), theirSignature, + theirSignature, "lol big bobs :poop:", oid, [baseCommit]); + }) + .then(function(commitOid) { + assert.equal(commitOid.toString(), + "bebb9ec2e0684c7cb7c1e1601c7d5a8f52b8b123"); + + return repository.getCommit(commitOid).then(function(commit) { + theirCommit = commit; + }); + }) + .then(function() { + return nodegit.Reference.lookup(repository, "HEAD") + .then(function(head) { + return head.symbolicSetTarget(ourBranch.name(), ourSignature, ""); + }); + }) + .then(function() { + return nodegit.Merge.commits(repository, ourCommit, theirCommit, null); + }) + .then(function(index) { + assert(index.hasConflicts()); + fse.writeFileSync(path.join(repository.workdir(), fileName), + finalFileContent); + }) + .then(function() { + return repository.openIndex().then(function(index) { + index.read(1); + index.addByPath(fileName); + index.write(); + + return index.writeTree(); + }); + }) + .then(function(oid) { + assert.equal(oid.toString(), + "b1cd49a27cd33b99ab6dad2fb82b3174812a8b47"); + + return repository.createCommit(ourBranch.name(), baseSignature, + baseSignature, "Stop this bob sized fued", oid, + [ourCommit, theirCommit]); + }) + .then(function(commitId) { + assert.equal(commitId.toString(), + "49014ccabf5125f9b69316acde36f891dfdb8b5c"); + }); + }); +}); diff --git a/test/tests/nodegit.js b/test/tests/nodegit.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/tests/object.js b/test/tests/object.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/tests/odb.js b/test/tests/odb.js new file mode 100644 index 000000000..2c24c2b3a --- /dev/null +++ b/test/tests/odb.js @@ -0,0 +1,56 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Odb", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Oid = require("../../lib/oid"); + var Obj = require("../../lib/object"); + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repo) { + test.repo = repo; + + return repo; + }).then(function(repo) { + return repo.odb(); + }).then(function(odb) { + test.odb = odb; + + return odb; + }); + }); + + it("can read raw objects directly from the odb using an OID", function() { + var oid = Oid.fromString("32789a79e71fbc9e04d3eff7425e1771eb595150"); + + return this.odb.read(oid).then(function (object) { + assert.equal(object.type(), Obj.TYPE.COMMIT); + }); + }); + + it("can read objects directly from the odb using a string", function() { + return this.odb.read("32789a79e71fbc9e04d3eff7425e1771eb595150") + .then(function (object) { + assert.equal(object.type(), Obj.TYPE.COMMIT); + }); + }); + + it("can write raw objects to git", function() { + var obj = "test data"; + var odb = this.odb; + + return odb.write(obj, obj.length, Obj.TYPE.BLOB).then(function(oid) { + assert.ok(oid instanceof Oid); + + return odb.read(oid); + }).then(function(object) { + assert.equal(object.type(), Obj.TYPE.BLOB); + assert.equal(object.toString(), obj); + assert.equal(object.size(), obj.length); + }); + }); +}); diff --git a/test/tests/oid.js b/test/tests/oid.js new file mode 100644 index 000000000..452148294 --- /dev/null +++ b/test/tests/oid.js @@ -0,0 +1,30 @@ +var assert = require("assert"); + +var NodeGit = require("../../"); + +describe("Oid", function() { + var oid = "fce88902e66c72b5b93e75bdb5ae717038b221f6"; + + var Oid = require("../../lib/oid"); + + before(function() { + this.oid = Oid.fromString(oid); + }); + + it("can convert a string to an oid", function() { + assert.ok(this.oid instanceof NodeGit.Oid); + }); + + it("can convert an oid to a string", function() { + var string = this.oid.allocfmt(); + + assert.equal(string, oid); + assert.equal(this.oid.toString(), oid); + }); + + it("provides a custom inspect method to improve debugging", function() { + var inspect = this.oid.inspect(); + + assert.equal(inspect, "[Oid " + oid + "]"); + }); +}); diff --git a/test/tests/patch.js b/test/tests/patch.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/tests/refs.js b/test/tests/refs.js new file mode 100644 index 000000000..674797724 --- /dev/null +++ b/test/tests/refs.js @@ -0,0 +1,53 @@ +var assert = require("assert"); +var path = require("path"); +var promisify = require("promisify-node"); + +// Have to wrap exec, since it has a weird callback signature. +var exec = promisify(function(command, opts, callback) { + return require("child_process").exec(command, opts, callback); +}); + +describe("Reference", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Reference = require("../../lib/reference"); + + before(function() { + var test = this; + + return exec("git reset --hard origin/master", {cwd: "test/repos/workdir"}) + .then(function() { + return Repository.open(reposPath); + }) + .then(function(repository) { + test.repository = repository; + + return repository.getReference("refs/heads/master"); + }) + .then(function(reference) { + test.reference = reference; + }); + }); + + it("can look up a reference", function() { + assert.ok(this.reference instanceof Reference); + }); + + it("can determine if the reference is symbolic", function() { + assert.equal(this.reference.isSymbolic(), false); + }); + + it("will return undefined looking up the symbolic target if not symbolic", + function() { + var reference = this.reference; + assert(reference.symbolicTarget() === undefined); + }); + + it("can look up the HEAD sha", function() { + return Reference.nameToId(this.repository, "HEAD").then(function(oid) { + var sha = oid.allocfmt(); + assert.equal(sha, "32789a79e71fbc9e04d3eff7425e1771eb595150"); + }); + }); +}); diff --git a/test/tests/remote.js b/test/tests/remote.js new file mode 100644 index 000000000..1142fd192 --- /dev/null +++ b/test/tests/remote.js @@ -0,0 +1,105 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Remote", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var NodeGit = require("../../"); + var Repository = require("../../lib/repository"); + var Remote = require("../../lib/remote"); + + function removeOrigins(repository) { + return Remote.load(repository, "origin1").then(function(remote) { + remote.delete(); + + return Remote.load(repository, "origin2").then(function(remote) { + remote.delete(); + }); + }).catch(function() {}); + } + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + + + return Remote.load(repository, "origin").then(function(remote) { + test.remote = remote; + + return removeOrigins(repository); + }); + }); + }); + + after(function() { + return removeOrigins(this.repository); + }); + + it("can load a remote", function() { + assert.ok(this.remote instanceof Remote); + }); + + it("can read the remote url", function() { + assert.equal( + this.remote.url().replace(".git", ""), + "https://github.com/nodegit/test"); + }); + + it("can push a remote", function() { + assert.equal(this.remote.pushurl(), undefined); + }); + + it("can set a remote", function() { + var repository = this.repository; + var url = "https://github.com/nodegit/nodegit"; + + return Remote.create(repository, "origin1", url).then(function(remote) { + return remote.setPushurl("https://google.com/", function() { + assert(remote.pushurl(), "https://google.com/"); + }); + }); + }); + + it("can read the remote name", function() { + assert.equal(this.remote.name(), "origin"); + }); + + it("can create a new remote", function() { + var repository = this.repository; + var url = "https://github.com/nodegit/test"; + + return Remote.create(repository, "origin2", url).then(function() { + return Remote.load(repository, "origin2").then(function(remote) { + assert(remote.url(), "https://github.com/nodegit/test"); + }); + }); + }); + + it("can delete a remote", function() { + var repository = this.repository; + var url = "https://github.com/nodegit/test"; + + return Remote.create(repository, "origin3", url).then(function() { + return Remote.load(repository, "origin3").then(function(remote) { + remote.delete(); + }); + }); + }); + + it("can fetch from a remote", function() { + var repo = this.repository; + + return Remote.load(repo, "origin") + .then(function(remote) { + remote.connect(NodeGit.Enums.DIRECTION.FETCH); + return remote.download(); + }) + .then(function() { + assert(true); + }, function() { + assert(false); + }); + }); +}); diff --git a/test/tests/repository.js b/test/tests/repository.js new file mode 100644 index 000000000..3d1de0fe8 --- /dev/null +++ b/test/tests/repository.js @@ -0,0 +1,55 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Repository", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + var newRepo = path.resolve("test/repos/newrepo"); + + var Repository = require("../../lib/repository"); + var Index = require("../../lib/index"); + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + }); + }); + + it("can open a valid repository", function() { + assert.ok(this.repository instanceof Repository); + }); + + it("cannot open an invalid repository", function() { + return Repository.open("repos/nonrepo").then(null, function(err) { + assert.ok(err instanceof Error); + }); + }); + + it("does not try to open paths that don't exist", function() { + var missingPath = "/surely/this/directory/does/not/exist/on/this/machine"; + + return Repository.open(missingPath).then(null, function(err) { + assert.ok(err instanceof Error); + }); + }); + + it("can initialize a repository into a folder", function() { + return Repository.init(newRepo, 1).then(function(path, isBare) { + return Repository.open(newRepo); + }); + }); + + it("can read the index", function() { + return this.repository.index().then(function(index) { + assert.ok(index instanceof Index); + }); + }); + + it("can list remotes", function() { + return this.repository.getRemotes().then(function(remotes) { + assert.equal(remotes.count(), 1); + assert.equal(remotes.strings(), "origin"); + }); + }); +}); diff --git a/test/tests/revwalk.js b/test/tests/revwalk.js new file mode 100644 index 000000000..9f42536d6 --- /dev/null +++ b/test/tests/revwalk.js @@ -0,0 +1,114 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Revwalk", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Revwalk = require("../../lib/revwalk"); + var Oid = require("../../lib/oid"); + + // Set a reasonable timeout here now that our repository has grown. + this.timeout(60000); + + before(function(done) { + var test = this; + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + return test.repository.getBranchCommit("rev-walk").then(function(commit) { + test.commit = commit; + done(); + }); + }); + }); + + beforeEach(function() { + this.walker = this.repository.createRevWalk(); + this.walker.push(this.commit.id()); + }); + + it("can create a walker", function() { + assert.ok(this.walker instanceof Revwalk); + }); + + it("can push an object", function() { + var sha = this.commit.sha(); + + return this.walker.next().then(function(commit) { + assert.equal(sha, commit); + }); + }); + + it("can hide an object", function() { + var test = this; + + return test.walker.next().then(function(commit) { + return test.walker.next(); + }).then(function() { + return test.walker.next(); + }).then(function() { + return test.walker.next(); + }).then(function(commit) { + assert.equal(commit.toString(), + "b8a94aefb22d0534cc0e5acf533989c13d8725dc"); + test.walker = test.repository.createRevWalk(); + test.walker.push(test.commit.id()); + test.walker.hide( + Oid.fromString("b8a94aefb22d0534cc0e5acf533989c13d8725dc")); + + return test.walker.next(); + }).then(function() { + return test.walker.next(); + }).then(function() { + return test.walker.next(); + }).then(function(commit) { + assert.equal(commit.toString(), + "95f695136203a372751c19b6353aeb5ae32ea40e"); + return test.walker.next(); + }).then(function(commit) { + assert.equal(commit, undefined); + }); + }); + + it("can simplify to first parent", function() { + var test = this; + + test.walker.simplifyFirstParent(); + return test.walker.next().then(function() { + return test.walker.next(); + }).then(function() { + return test.walker.next(); + }).then(function(commit) { + assert.equal(commit.toString(), + "b8a94aefb22d0534cc0e5acf533989c13d8725dc"); + }); + }); + + // This test requires forcing garbage collection, so mocha needs to be run + // via node rather than npm, with a la `node --expose-gc [pathtohmoca] + // [testglob]` + var testGC = global.gc ? it : it.skip; + + testGC("doesnt segfault when accessing .author() twice", function(done) { + Repository.open(reposPath).then(function(repository) { + var walker = repository.createRevWalk(); + + repository.getMasterCommit().then(function(firstCommitOnMaster) { + walker.walk(firstCommitOnMaster, function(err, commit) { + if (!err && !commit) { + return done(); + } + + for (var i = 0; i < 500; i++) { + commit.author().name(); + commit.author().email(); + + if ( i % 250 === 0) { + global.gc(); + } + } + }); + }); + }); + }); +}); diff --git a/test/tests/tag.js b/test/tests/tag.js new file mode 100644 index 000000000..7a8ba14d5 --- /dev/null +++ b/test/tests/tag.js @@ -0,0 +1,63 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Tag", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Obj = require("../../lib/object"); + var Oid = require("../../lib/oid"); + + var tagName = "annotated-tag"; + var tagFullName = "refs/tags/" + tagName; + var tagOid = "dc800017566123ff3c746b37284a24a66546667e"; + var commitPointedTo = "32789a79e71fbc9e04d3eff7425e1771eb595150"; + var tagMessage = "This is an annotated tag\n"; + + function testTag(tag) { + assert.equal(tag.name(), tagName); + assert.equal(tag.targetType(), Obj.TYPE.COMMIT); + assert.equal(tag.message(), tagMessage); + + var target = tag.target(); + + assert.ok(target.isCommit()); + assert.equal(target.id().toString(), commitPointedTo); + } + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repo) { + test.repo = repo; + + return repo; + }); + }); + + it("can get a tag from a repo via the tag name", function() { + return this.repo.getTagByName(tagName).then(function(tag) { + testTag(tag); + }); + }); + + it("can get a tag from a repo via the long tag name", function() { + return this.repo.getTagByName(tagFullName).then(function(tag) { + testTag(tag); + }); + }); + + it("can get a tag from a repo via the tag's OID as a string", function() { + return this.repo.getTag(tagOid).then(function(tag) { + testTag(tag); + }); + }); + + it("can get a tag from a repo via the tag's OID object", function() { + var oid = Oid.fromString(tagOid); + + return this.repo.getTag(oid).then(function(tag) { + testTag(tag); + }); + }); +}); diff --git a/test/tests/tree_entry.js b/test/tests/tree_entry.js new file mode 100644 index 000000000..f00ae38c5 --- /dev/null +++ b/test/tests/tree_entry.js @@ -0,0 +1,78 @@ +var assert = require("assert"); +var path = require("path"); + +describe("TreeEntry", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + var oid = "5716e9757886eaf38d51c86b192258c960d9cfea"; + + var Repository = require("../../lib/repository"); + var Tree = require("../../lib/tree"); + + beforeEach(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repository = repository; + + return repository.getCommit(oid).then(function(commit) { + test.commit = commit; + }); + }); + }); + + it("will fail on a missing file", function() { + return this.commit.getEntry("test/-entry.js").then(null, function(err) { + assert.ok(err instanceof Error); + }); + }); + + it("provides the correct sha for a file", function() { + return this.commit.getEntry("README.md").then(function(entry) { + var sha = entry.sha(); + + assert.equal(sha, "6cb45ba5d32532bf0d1310dc31ca4f20f59964bc"); + }); + }); + + it("provides the filename", function() { + return this.commit.getEntry("test/raw-commit.js").then(function(entry) { + var name = entry.filename(); + + assert.equal(name, "raw-commit.js"); + }); + }); + + it("provides the blob representation of the entry", function() { + return this.commit.getEntry("test/raw-commit.js").then(function(entry) { + return entry.getBlob().then(function(blob) { + var size = blob.rawsize(); + + assert.equal(size, 2736); + }); + }); + }); + + it("provides the tree the entry is part of", function() { + return this.commit.getEntry("test").then(function(entry) { + return entry.getTree().then(function(tree) { + assert.ok(tree instanceof Tree); + }); + }); + }); + + it("can determine if an entry is a file", function() { + return this.commit.getEntry("README.md").then(function(entry) { + var isFile = entry.isFile(); + + assert.equal(isFile, true); + }); + }); + + it("can determine if an entry is a directory", function() { + return this.commit.getEntry("example").then(function(entry) { + var isFile = entry.isFile(); + + assert.equal(isFile, false); + }); + }); +}); diff --git a/test/tree.js b/test/tree.js deleted file mode 100644 index a7c55fef0..000000000 --- a/test/tree.js +++ /dev/null @@ -1,63 +0,0 @@ -var git = require('../'), - rimraf = require('rimraf'), - fs = require('fs'), - path = require('path'); - -var sha = '5716e9757886eaf38d51c86b192258c960d9cfea'; -var fileCount = 512; // Number of blob & blob executabless - -exports.walk = function(test) { - test.expect(515); - - git.Repo.open('repos/workdir/.git', function(error, repo) { - repo.getCommit(sha, function(error, commit) { - var entryCount = 0; - commit.getTree(function(error, tree) { - tree.walk().on('entry', function(index, entry) { - test.equals(error, null, 'There should be no error'); - entryCount++; - }).on('end', function(errors, entries) { - test.equals(errors, null, 'There should be no error'); - test.equals(entryCount, fileCount, 'The manual tree entry count and the "end" tree entry count do not match'); - test.equals(entries.length, fileCount, 'The end entries count and the manual entry count do not match'); - test.done(); - }).start(); - }); - }); - }); -}; - -exports.insert = function(test) { - test.expect(1); - - git.Repo.open('repos/workdir/.git', function(error, repo) { - repo.getCommit(sha, function(error, commit) { - commit.getTree(function(error, tree) { - var text = "this is a file\n", - buffer = new Buffer(text); - repo.createBlobFromBuffer(buffer, function(error, blobId) { - var builder = tree.builder(); - builder.insert(path.join("lib", "baz", "bar.txt"), blobId, git.TreeEntry.FileMode.Blob); - builder.write(function(error, treeId) { - repo.getTree(treeId, function(error, tree) { - var author = git.Signature.create("Scott Chacon", "schacon@gmail.com", 123456789, 60), - committer = git.Signature.create("Scott A Chacon", "scott@github.com", 987654321, 90); - repo.createCommit(null, author, committer, "message", tree, [commit], function(error, commitId) { - repo.getCommit(commitId, function(error, commit) { - commit.getTree(function(error, tree) { - tree.getEntry('lib/baz/bar.txt', function(error, entry) { - entry.getBlob(function(error, blob) { - test.equals(blob.toString(), text); - test.done(); - }); - }); - }); - }); - }); - }); - }); - }); - }); - }); - }); -}; diff --git a/test/tree_entry.js b/test/tree_entry.js deleted file mode 100644 index eb00f9c93..000000000 --- a/test/tree_entry.js +++ /dev/null @@ -1,83 +0,0 @@ -var git = require('../'); - -var sha = '5716e9757886eaf38d51c86b192258c960d9cfea'; - -var getEntry = function(path, callback) { - git.Repo.open('repos/workdir/.git', function(error, repo) { - repo.getCommit(sha, function(error, commit) { - commit.getEntry(path, callback); - }); - }); -}; - -exports.missingFile = function(test) { - test.expect(1); - - getEntry('test/convenience-entry.js', function(error, entry) { - test.notEqual(error, null, 'Missing file should error'); - test.done(); - }); -}; - -exports.sha = function(test) { - test.expect(1); - getEntry('README.md', function(error, entry) { - var sha = entry.sha(); - test.equal(sha, '6cb45ba5d32532bf0d1310dc31ca4f20f59964bc', 'Entry SHA should match expected value'); - test.done(); - }); -}; - -exports.isFile = function(test) { - test.expect(2); - getEntry('README.md', function(error, entry) { - var isFile = entry.isFile(); - test.equal(isFile, true, 'Entry is a file'); - getEntry('example', function(error, entry) { - var isFile = entry.isFile(); - test.equal(isFile, false, 'Entry is a directory'); - test.done(); - }); - }); -}; - -exports.isDirectory = function(test) { - test.expect(2); - getEntry('example', function(error, entry) { - test.equal(entry.isFile(), false, 'Entry is a directory'); - getEntry('README.md', function(error, entry) { - test.equal(entry.isFile(), true, 'Entry is a file'); - test.done(); - }); - }); -}; - -exports.name = function(test) { - test.expect(2); - getEntry('test/raw-commit.js', function(error, entry) { - test.equal(error, null, 'Should not error'); - var name = entry.name(); - test.equal(name, 'raw-commit.js', 'Name should match expected value'); - test.done(); - }); -}; - -exports.getBlob = function(test) { - test.expect(1); - getEntry('test/raw-commit.js', function(error, entry) { - entry.getBlob(function(error, blob) { - test.equal(blob.size(), 2736, 'Content length should match expected value'); - test.done(); - }); - }); -}; - -exports.getTree = function(test) { - test.expect(1); - getEntry('test', function(error, entry) { - entry.getTree(function(error, tree) { - test.equal(tree instanceof git.Tree, true, 'Expected instance of Tree'); - test.done(); - }); - }); -}; diff --git a/vendor/README.md b/vendor/README.md new file mode 100644 index 000000000..916269d39 --- /dev/null +++ b/vendor/README.md @@ -0,0 +1,4 @@ +# Openssl + +I do not have the time to maintain working gyp metadata for openssl, +i've taken the easy way out and stolen it from [node.js](http://github.com/joyent/node.git). diff --git a/vendor/libgit2.gyp b/vendor/libgit2.gyp new file mode 100644 index 000000000..13a8b2d4a --- /dev/null +++ b/vendor/libgit2.gyp @@ -0,0 +1,1394 @@ +{ + # Copyright (c) 2012 The Chromium Authors. All rights reserved. + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + "variables": { + "target_arch%": "x86", + "library%": "static_library", + "openssl_enable_asm%": 0, # only supported with the Visual Studio 2012 (VC11) toolchain. + "gcc_version%": 0, + "is_clang%": 0, + }, + "targets": [ + { + "target_name": "libgit2", + "type": "static_library", + "defines": [ + "GIT_THREADS", + "GIT_SSH", + # Node's util.h may be accidentally included so use this to guard + # against compilation error. + "SRC_UTIL_H_", + ], + "dependencies": [ + "zlib", + "<(module_root_dir)/vendor/http_parser/http_parser.gyp:http_parser", + "libssh2", + "openssl" + ], + "sources": [ + "libgit2/src/array.h", + "libgit2/src/attr.c", + "libgit2/src/attr.h", + "libgit2/src/attr_file.c", + "libgit2/src/attr_file.h", + "libgit2/src/attrcache.c", + "libgit2/src/attrcache.h", + "libgit2/src/bitvec.h", + "libgit2/src/blame.c", + "libgit2/src/blame.h", + "libgit2/src/blame_git.c", + "libgit2/src/blame_git.h", + "libgit2/src/blob.c", + "libgit2/src/blob.h", + "libgit2/src/branch.c", + "libgit2/src/branch.h", + "libgit2/src/bswap.h", + "libgit2/src/buf_text.c", + "libgit2/src/buf_text.h", + "libgit2/src/buffer.c", + "libgit2/src/buffer.h", + "libgit2/src/cache.c", + "libgit2/src/cache.h", + "libgit2/src/cc-compat.h", + "libgit2/src/checkout.c", + "libgit2/src/checkout.h", + "libgit2/src/cherrypick.c", + "libgit2/src/clone.c", + "libgit2/src/clone.h", + "libgit2/src/commit.c", + "libgit2/src/commit.h", + "libgit2/src/commit_list.c", + "libgit2/src/commit_list.h", + "libgit2/src/common.h", + "libgit2/src/config.c", + "libgit2/src/config.h", + "libgit2/src/config_cache.c", + "libgit2/src/config_file.c", + "libgit2/src/config_file.h", + "libgit2/src/crlf.c", + "libgit2/src/date.c", + "libgit2/src/delta-apply.c", + "libgit2/src/delta-apply.h", + "libgit2/src/delta.c", + "libgit2/src/delta.h", + "libgit2/src/diff.c", + "libgit2/src/diff.h", + "libgit2/src/diff_driver.c", + "libgit2/src/diff_driver.h", + "libgit2/src/diff_file.c", + "libgit2/src/diff_file.h", + "libgit2/src/diff_patch.c", + "libgit2/src/diff_patch.h", + "libgit2/src/diff_print.c", + "libgit2/src/diff_stats.c", + "libgit2/src/diff_tform.c", + "libgit2/src/diff_xdiff.c", + "libgit2/src/diff_xdiff.h", + "libgit2/src/errors.c", + "libgit2/src/fetch.c", + "libgit2/src/fetch.h", + "libgit2/src/fetchhead.c", + "libgit2/src/fetchhead.h", + "libgit2/src/filebuf.c", + "libgit2/src/filebuf.h", + "libgit2/src/fileops.c", + "libgit2/src/fileops.h", + "libgit2/src/filter.c", + "libgit2/src/filter.h", + "libgit2/src/fnmatch.c", + "libgit2/src/fnmatch.h", + "libgit2/src/global.c", + "libgit2/src/global.h", + "libgit2/src/graph.c", + "libgit2/src/hash.c", + "libgit2/src/hash.h", + "libgit2/src/hashsig.c", + "libgit2/src/hashsig.h", + "libgit2/src/ident.c", + "libgit2/src/ignore.c", + "libgit2/src/ignore.h", + "libgit2/src/index.c", + "libgit2/src/index.h", + "libgit2/src/indexer.c", + "libgit2/src/iterator.c", + "libgit2/src/iterator.h", + "libgit2/src/khash.h", + "libgit2/src/map.h", + "libgit2/src/merge.c", + "libgit2/src/merge.h", + "libgit2/src/merge_file.c", + "libgit2/src/merge_file.h", + "libgit2/src/message.c", + "libgit2/src/message.h", + "libgit2/src/mwindow.c", + "libgit2/src/mwindow.h", + "libgit2/src/netops.c", + "libgit2/src/netops.h", + "libgit2/src/notes.c", + "libgit2/src/notes.h", + "libgit2/src/object.c", + "libgit2/src/object.h", + "libgit2/src/object_api.c", + "libgit2/src/odb.c", + "libgit2/src/odb.h", + "libgit2/src/odb_loose.c", + "libgit2/src/odb_mempack.c", + "libgit2/src/odb_pack.c", + "libgit2/src/offmap.h", + "libgit2/src/oid.c", + "libgit2/src/oid.h", + "libgit2/src/oidmap.h", + "libgit2/src/pack-objects.c", + "libgit2/src/pack-objects.h", + "libgit2/src/pack.c", + "libgit2/src/pack.h", + "libgit2/src/path.c", + "libgit2/src/path.h", + "libgit2/src/pathspec.c", + "libgit2/src/pathspec.h", + "libgit2/src/pool.c", + "libgit2/src/pool.h", + "libgit2/src/posix.c", + "libgit2/src/posix.h", + "libgit2/src/pqueue.c", + "libgit2/src/pqueue.h", + "libgit2/src/push.c", + "libgit2/src/push.h", + "libgit2/src/refdb.c", + "libgit2/src/refdb.h", + "libgit2/src/refdb_fs.c", + "libgit2/src/refdb_fs.h", + "libgit2/src/reflog.c", + "libgit2/src/reflog.h", + "libgit2/src/refs.c", + "libgit2/src/refs.h", + "libgit2/src/refspec.c", + "libgit2/src/refspec.h", + "libgit2/src/remote.c", + "libgit2/src/remote.h", + "libgit2/src/repo_template.h", + "libgit2/src/repository.c", + "libgit2/src/repository.h", + "libgit2/src/reset.c", + "libgit2/src/revert.c", + "libgit2/src/revparse.c", + "libgit2/src/revwalk.c", + "libgit2/src/revwalk.h", + "libgit2/src/settings.c", + "libgit2/src/sha1_lookup.c", + "libgit2/src/sha1_lookup.h", + "libgit2/src/signature.c", + "libgit2/src/signature.h", + "libgit2/src/sortedcache.c", + "libgit2/src/sortedcache.h", + "libgit2/src/stash.c", + "libgit2/src/status.c", + "libgit2/src/status.h", + "libgit2/src/strmap.c", + "libgit2/src/strmap.h", + "libgit2/src/strnlen.h", + "libgit2/src/submodule.c", + "libgit2/src/submodule.h", + "libgit2/src/sysdir.c", + "libgit2/src/sysdir.h", + "libgit2/src/tag.c", + "libgit2/src/tag.h", + "libgit2/src/thread-utils.c", + "libgit2/src/thread-utils.h", + "libgit2/src/trace.c", + "libgit2/src/trace.h", + "libgit2/src/transport.c", + "libgit2/src/tree-cache.c", + "libgit2/src/tree-cache.h", + "libgit2/src/tree.c", + "libgit2/src/tree.h", + "libgit2/src/tsort.c", + "libgit2/src/userdiff.h", + "libgit2/src/util.c", + "libgit2/src/util.h", + "libgit2/src/vector.c", + "libgit2/src/vector.h", + "libgit2/src/zstream.c", + "libgit2/src/zstream.h", + "libgit2/src/hash/hash_generic.c", + "libgit2/src/hash/hash_generic.h", + "libgit2/src/hash/hash_openssl.h", + "libgit2/src/transports/cred.c", + "libgit2/src/transports/cred_helpers.c", + "libgit2/src/transports/git.c", + "libgit2/src/transports/http.c", + "libgit2/src/transports/local.c", + "libgit2/src/transports/smart.c", + "libgit2/src/transports/smart.h", + "libgit2/src/transports/smart_pkt.c", + "libgit2/src/transports/smart_protocol.c", + "libgit2/src/transports/ssh.c", + "libgit2/src/xdiff/xdiff.h", + "libgit2/src/xdiff/xdiffi.c", + "libgit2/src/xdiff/xdiffi.h", + "libgit2/src/xdiff/xemit.c", + "libgit2/src/xdiff/xemit.h", + "libgit2/src/xdiff/xhistogram.c", + "libgit2/src/xdiff/xinclude.h", + "libgit2/src/xdiff/xmacros.h", + "libgit2/src/xdiff/xmerge.c", + "libgit2/src/xdiff/xpatience.c", + "libgit2/src/xdiff/xprepare.c", + "libgit2/src/xdiff/xprepare.h", + "libgit2/src/xdiff/xtypes.h", + "libgit2/src/xdiff/xutils.c", + "libgit2/src/xdiff/xutils.h", + ], + "conditions": [ + ["OS!='win'", { + "defines": [ + "GIT_SSL" + ], + }], + ["OS=='win'", {}, { + "sources": [ + "libgit2/src/unix/map.c", + "libgit2/src/unix/posix.h", + "libgit2/src/unix/realpath.c", + ] + }], + ["OS=='linux'", { + "cflags": [ + "-DGIT_SSH", + "-DGIT_SSL", + "-w", + ], + }], + ["OS=='win'", { + "defines": [ + "GIT_WINHTTP", + ], + "msvs_settings": { + "VCLinkerTool": { + "AdditionalDependencies": [ + "ws2_32.lib", + ], + }, + # Workaround of a strange bug: + # TargetMachine + static_library + x64 = nothing. + "conditions": [ + ["target_arch=='x64'", { + "VCLibrarianTool": { + "AdditionalOptions": [ + "/MACHINE:X64", + ], + }, + }, { + "VCLibrarianTool": { + "AdditionalOptions": [ + "/MACHINE:x86", + ], + }, + }], + ], + }, + "msvs_disabled_warnings": [ + # Conversion from 'ssize_t' to 'int32_t', possible loss of data. + 4244, + # Conversion from 'size_t' to 'int', possible loss of data. + 4267, + # Different 'volatile' qualifiers. + 4090, + # 'volatile void *' differs in levels of indirection from 'int'. + 4047, + # 'InterlockedDecrement' undefined; assuming extern returning int. + 4013, + ], + "sources": [ + "libgit2/src/win32/dir.c", + "libgit2/src/win32/dir.h", + "libgit2/src/win32/error.c", + "libgit2/src/win32/error.h", + "libgit2/src/win32/findfile.c", + "libgit2/src/win32/findfile.h", + "libgit2/src/win32/git2.rc", + "libgit2/src/win32/map.c", + "libgit2/src/win32/mingw-compat.h", + "libgit2/src/win32/msvc-compat.h", + "libgit2/src/win32/posix.h", + "libgit2/src/win32/posix_w32.c", + "libgit2/src/win32/precompiled.c", + "libgit2/src/win32/precompiled.h", + "libgit2/src/win32/pthread.c", + "libgit2/src/win32/pthread.h", + "libgit2/src/win32/reparse.h", + "libgit2/src/win32/utf-conv.c", + "libgit2/src/win32/utf-conv.h", + "libgit2/src/win32/version.h", + "libgit2/src/win32/w32_util.c", + "libgit2/src/win32/w32_util.h", + "libgit2/src/transports/winhttp.c", + "libgit2/deps/regex/regex.c", + ], + }, { + "libraries": [ + "-lpthread", + ], + "sources": [ + "libgit2/src/unix/map.c", + "libgit2/src/unix/posix.h", + "libgit2/src/unix/realpath.c", + ], + "cflags": [ + "-Wno-missing-field-initializers", + "-Wno-unused-variable", + "-Wno-deprecated-declarations", + ], + "xcode_settings": { + "WARNING_CFLAGS": [ + "-Wno-missing-field-initializers", + "-Wno-unused-variable", + "-Wno-deprecated-declarations", + "-Wno-uninitialized", + ], + }, + }, + ] + ], + "include_dirs": [ + "libgit2/include", + "libgit2/src", + "libgit2/deps/regex" + ], + "direct_dependent_settings": { + "include_dirs": [ + "libgit2/include", + ], + }, + }, + { + "target_name": "zlib", + "type": "static_library", + "sources": [ + "libgit2/deps/zlib/adler32.c", + "libgit2/deps/zlib/crc32.c", + "libgit2/deps/zlib/crc32.h", + "libgit2/deps/zlib/deflate.c", + "libgit2/deps/zlib/deflate.h", + "libgit2/deps/zlib/inffast.c", + "libgit2/deps/zlib/inffast.h", + "libgit2/deps/zlib/inffixed.h", + "libgit2/deps/zlib/inflate.c", + "libgit2/deps/zlib/inflate.h", + "libgit2/deps/zlib/inftrees.c", + "libgit2/deps/zlib/inftrees.h", + "libgit2/deps/zlib/trees.c", + "libgit2/deps/zlib/trees.h", + "libgit2/deps/zlib/zconf.h", + "libgit2/deps/zlib/zlib.h", + "libgit2/deps/zlib/zutil.c", + "libgit2/deps/zlib/zutil.h", + ], + "defines": [ + "NO_VIZ", + "STDC", + "NO_GZIP", + ], + "include_dirs": [ + "libgit2/include", + "libgit2/deps/regex", + ], + "direct_dependent_settings": { + "include_dirs": [ + "libgit2/deps/zlib", + ], + }, + }, + { + "target_name": "libssh2", + "type": "static_library", + "defines": [ + "NETSNMP_ENABLE_IPV6" + ], + "sources": [ + "libssh2/src/agent.c", + "libssh2/src/crypt.c", + "libssh2/src/keepalive.c", + "libssh2/src/libgcrypt.c", + "libssh2/src/openssl.c", + "libssh2/src/publickey.c", + "libssh2/src/sftp.c", + "libssh2/src/version.c", + "libssh2/src/channel.c", + "libssh2/src/global.c", + "libssh2/src/kex.c", + "libssh2/src/mac.c", + "libssh2/src/packet.c", + "libssh2/src/scp.c", + "libssh2/src/transport.c", + "libssh2/src/comp.c", + "libssh2/src/hostkey.c", + "libssh2/src/knownhost.c", + "libssh2/src/misc.c", + "libssh2/src/pem.c", + "libssh2/src/session.c", + "libssh2/src/userauth.c", + ], + "include_dirs": [ + ".", + "libssh2/include", + ], + "dependencies": [ + "openssl" + ], + "direct_dependent_settings": { + "include_dirs": [ + "libssh2/include" + ] + }, + "conditions": [ + ["OS=='win'", { + "include_dirs": [ + "libssh2/src", + "libssh2/win32", + "libssh2/include" + ], + "direct_dependent_settings": { + "include_dirs": [ + "libssh2/src", + "libssh2/win32", + "libssh2/include" + ] + } + }], + ] + }, + { + "target_name": "openssl", + "type": "static_library", + "defines": [ + #No clue what these are for. + "L_ENDIAN", + "PURIFY", + "_REENTRANT", + "NO_WINDOWS_BRAINDEATH", + ], + "include_dirs": [ + ".", + "openssl/openssl", + "openssl/openssl/crypto", + "openssl/openssl/crypto/asn1", + "openssl/openssl/crypto/evp", + "openssl/openssl/crypto/md2", + "openssl/openssl/crypto/modes", + "openssl/openssl/crypto/store", + "openssl/openssl/include", + ], + "direct_dependent_settings": { + "include_dirs": [ + "openssl/openssl/include", + "openssl/openssl/include/openssl", + ] + }, + "sources": [ + "openssl/openssl/ssl/bio_ssl.c", + "openssl/openssl/ssl/d1_both.c", + "openssl/openssl/ssl/d1_clnt.c", + "openssl/openssl/ssl/d1_enc.c", + "openssl/openssl/ssl/d1_lib.c", + "openssl/openssl/ssl/d1_meth.c", + "openssl/openssl/ssl/d1_pkt.c", + "openssl/openssl/ssl/d1_srtp.c", + "openssl/openssl/ssl/d1_srvr.c", + "openssl/openssl/ssl/kssl.c", + "openssl/openssl/ssl/s23_clnt.c", + "openssl/openssl/ssl/s23_lib.c", + "openssl/openssl/ssl/s23_meth.c", + "openssl/openssl/ssl/s23_pkt.c", + "openssl/openssl/ssl/s23_srvr.c", + "openssl/openssl/ssl/s2_clnt.c", + "openssl/openssl/ssl/s2_enc.c", + "openssl/openssl/ssl/s2_lib.c", + "openssl/openssl/ssl/s2_meth.c", + "openssl/openssl/ssl/s2_pkt.c", + "openssl/openssl/ssl/s2_srvr.c", + "openssl/openssl/ssl/s3_both.c", + "openssl/openssl/ssl/s3_clnt.c", + "openssl/openssl/ssl/s3_enc.c", + "openssl/openssl/ssl/s3_lib.c", + "openssl/openssl/ssl/s3_meth.c", + "openssl/openssl/ssl/s3_pkt.c", + "openssl/openssl/ssl/s3_srvr.c", + "openssl/openssl/ssl/s3_cbc.c", + "openssl/openssl/ssl/ssl_algs.c", + "openssl/openssl/ssl/ssl_asn1.c", + "openssl/openssl/ssl/ssl_cert.c", + "openssl/openssl/ssl/ssl_ciph.c", + "openssl/openssl/ssl/ssl_err.c", + "openssl/openssl/ssl/ssl_err2.c", + "openssl/openssl/ssl/ssl_lib.c", + "openssl/openssl/ssl/ssl_rsa.c", + "openssl/openssl/ssl/ssl_sess.c", + "openssl/openssl/ssl/ssl_stat.c", + "openssl/openssl/ssl/ssl_txt.c", + "openssl/openssl/ssl/t1_clnt.c", + "openssl/openssl/ssl/t1_enc.c", + "openssl/openssl/ssl/t1_lib.c", + "openssl/openssl/ssl/t1_meth.c", + "openssl/openssl/ssl/t1_reneg.c", + "openssl/openssl/ssl/t1_srvr.c", + "openssl/openssl/ssl/tls_srp.c", + "openssl/openssl/crypto/aes/aes_cfb.c", + "openssl/openssl/crypto/aes/aes_ctr.c", + "openssl/openssl/crypto/aes/aes_ecb.c", + "openssl/openssl/crypto/aes/aes_ige.c", + "openssl/openssl/crypto/aes/aes_misc.c", + "openssl/openssl/crypto/aes/aes_ofb.c", + "openssl/openssl/crypto/aes/aes_wrap.c", + "openssl/openssl/crypto/asn1/a_bitstr.c", + "openssl/openssl/crypto/asn1/a_bool.c", + "openssl/openssl/crypto/asn1/a_bytes.c", + "openssl/openssl/crypto/asn1/a_d2i_fp.c", + "openssl/openssl/crypto/asn1/a_digest.c", + "openssl/openssl/crypto/asn1/a_dup.c", + "openssl/openssl/crypto/asn1/a_enum.c", + "openssl/openssl/crypto/asn1/a_gentm.c", + "openssl/openssl/crypto/asn1/a_i2d_fp.c", + "openssl/openssl/crypto/asn1/a_int.c", + "openssl/openssl/crypto/asn1/a_mbstr.c", + "openssl/openssl/crypto/asn1/a_object.c", + "openssl/openssl/crypto/asn1/a_octet.c", + "openssl/openssl/crypto/asn1/a_print.c", + "openssl/openssl/crypto/asn1/a_set.c", + "openssl/openssl/crypto/asn1/a_sign.c", + "openssl/openssl/crypto/asn1/a_strex.c", + "openssl/openssl/crypto/asn1/a_strnid.c", + "openssl/openssl/crypto/asn1/a_time.c", + "openssl/openssl/crypto/asn1/a_type.c", + "openssl/openssl/crypto/asn1/a_utctm.c", + "openssl/openssl/crypto/asn1/a_utf8.c", + "openssl/openssl/crypto/asn1/a_verify.c", + "openssl/openssl/crypto/asn1/ameth_lib.c", + "openssl/openssl/crypto/asn1/asn1_err.c", + "openssl/openssl/crypto/asn1/asn1_gen.c", + "openssl/openssl/crypto/asn1/asn1_lib.c", + "openssl/openssl/crypto/asn1/asn1_par.c", + "openssl/openssl/crypto/asn1/asn_mime.c", + "openssl/openssl/crypto/asn1/asn_moid.c", + "openssl/openssl/crypto/asn1/asn_pack.c", + "openssl/openssl/crypto/asn1/bio_asn1.c", + "openssl/openssl/crypto/asn1/bio_ndef.c", + "openssl/openssl/crypto/asn1/d2i_pr.c", + "openssl/openssl/crypto/asn1/d2i_pu.c", + "openssl/openssl/crypto/asn1/evp_asn1.c", + "openssl/openssl/crypto/asn1/f_enum.c", + "openssl/openssl/crypto/asn1/f_int.c", + "openssl/openssl/crypto/asn1/f_string.c", + "openssl/openssl/crypto/asn1/i2d_pr.c", + "openssl/openssl/crypto/asn1/i2d_pu.c", + "openssl/openssl/crypto/asn1/n_pkey.c", + "openssl/openssl/crypto/asn1/nsseq.c", + "openssl/openssl/crypto/asn1/p5_pbe.c", + "openssl/openssl/crypto/asn1/p5_pbev2.c", + "openssl/openssl/crypto/asn1/p8_pkey.c", + "openssl/openssl/crypto/asn1/t_bitst.c", + "openssl/openssl/crypto/asn1/t_crl.c", + "openssl/openssl/crypto/asn1/t_pkey.c", + "openssl/openssl/crypto/asn1/t_req.c", + "openssl/openssl/crypto/asn1/t_spki.c", + "openssl/openssl/crypto/asn1/t_x509.c", + "openssl/openssl/crypto/asn1/t_x509a.c", + "openssl/openssl/crypto/asn1/tasn_dec.c", + "openssl/openssl/crypto/asn1/tasn_enc.c", + "openssl/openssl/crypto/asn1/tasn_fre.c", + "openssl/openssl/crypto/asn1/tasn_new.c", + "openssl/openssl/crypto/asn1/tasn_prn.c", + "openssl/openssl/crypto/asn1/tasn_typ.c", + "openssl/openssl/crypto/asn1/tasn_utl.c", + "openssl/openssl/crypto/asn1/x_algor.c", + "openssl/openssl/crypto/asn1/x_attrib.c", + "openssl/openssl/crypto/asn1/x_bignum.c", + "openssl/openssl/crypto/asn1/x_crl.c", + "openssl/openssl/crypto/asn1/x_exten.c", + "openssl/openssl/crypto/asn1/x_info.c", + "openssl/openssl/crypto/asn1/x_long.c", + "openssl/openssl/crypto/asn1/x_name.c", + "openssl/openssl/crypto/asn1/x_nx509.c", + "openssl/openssl/crypto/asn1/x_pkey.c", + "openssl/openssl/crypto/asn1/x_pubkey.c", + "openssl/openssl/crypto/asn1/x_req.c", + "openssl/openssl/crypto/asn1/x_sig.c", + "openssl/openssl/crypto/asn1/x_spki.c", + "openssl/openssl/crypto/asn1/x_val.c", + "openssl/openssl/crypto/asn1/x_x509.c", + "openssl/openssl/crypto/asn1/x_x509a.c", + "openssl/openssl/crypto/bf/bf_cfb64.c", + "openssl/openssl/crypto/bf/bf_ecb.c", + "openssl/openssl/crypto/bf/bf_ofb64.c", + "openssl/openssl/crypto/bf/bf_skey.c", + "openssl/openssl/crypto/bio/b_dump.c", + "openssl/openssl/crypto/bio/b_print.c", + "openssl/openssl/crypto/bio/b_sock.c", + "openssl/openssl/crypto/bio/bf_buff.c", + "openssl/openssl/crypto/bio/bf_nbio.c", + "openssl/openssl/crypto/bio/bf_null.c", + "openssl/openssl/crypto/bio/bio_cb.c", + "openssl/openssl/crypto/bio/bio_err.c", + "openssl/openssl/crypto/bio/bio_lib.c", + "openssl/openssl/crypto/bio/bss_acpt.c", + "openssl/openssl/crypto/bio/bss_bio.c", + "openssl/openssl/crypto/bio/bss_conn.c", + "openssl/openssl/crypto/bio/bss_dgram.c", + "openssl/openssl/crypto/bio/bss_fd.c", + "openssl/openssl/crypto/bio/bss_file.c", + "openssl/openssl/crypto/bio/bss_log.c", + "openssl/openssl/crypto/bio/bss_mem.c", + "openssl/openssl/crypto/bio/bss_null.c", + "openssl/openssl/crypto/bio/bss_sock.c", + "openssl/openssl/crypto/bn/bn_add.c", + "openssl/openssl/crypto/bn/bn_blind.c", + "openssl/openssl/crypto/bn/bn_const.c", + "openssl/openssl/crypto/bn/bn_ctx.c", + "openssl/openssl/crypto/bn/bn_depr.c", + "openssl/openssl/crypto/bn/bn_div.c", + "openssl/openssl/crypto/bn/bn_err.c", + "openssl/openssl/crypto/bn/bn_exp.c", + "openssl/openssl/crypto/bn/bn_exp2.c", + "openssl/openssl/crypto/bn/bn_gcd.c", + "openssl/openssl/crypto/bn/bn_gf2m.c", + "openssl/openssl/crypto/bn/bn_kron.c", + "openssl/openssl/crypto/bn/bn_lib.c", + "openssl/openssl/crypto/bn/bn_mod.c", + "openssl/openssl/crypto/bn/bn_mont.c", + "openssl/openssl/crypto/bn/bn_mpi.c", + "openssl/openssl/crypto/bn/bn_mul.c", + "openssl/openssl/crypto/bn/bn_nist.c", + "openssl/openssl/crypto/bn/bn_prime.c", + "openssl/openssl/crypto/bn/bn_print.c", + "openssl/openssl/crypto/bn/bn_rand.c", + "openssl/openssl/crypto/bn/bn_recp.c", + "openssl/openssl/crypto/bn/bn_shift.c", + "openssl/openssl/crypto/bn/bn_sqr.c", + "openssl/openssl/crypto/bn/bn_sqrt.c", + "openssl/openssl/crypto/bn/bn_word.c", + "openssl/openssl/crypto/bn/bn_x931p.c", + "openssl/openssl/crypto/buffer/buf_err.c", + "openssl/openssl/crypto/buffer/buf_str.c", + "openssl/openssl/crypto/buffer/buffer.c", + "openssl/openssl/crypto/camellia/cmll_cfb.c", + "openssl/openssl/crypto/camellia/cmll_ctr.c", + "openssl/openssl/crypto/camellia/cmll_ecb.c", + "openssl/openssl/crypto/camellia/cmll_ofb.c", + "openssl/openssl/crypto/camellia/cmll_utl.c", + "openssl/openssl/crypto/cast/c_cfb64.c", + "openssl/openssl/crypto/cast/c_ecb.c", + "openssl/openssl/crypto/cast/c_ofb64.c", + "openssl/openssl/crypto/cast/c_skey.c", + "openssl/openssl/crypto/cmac/cm_ameth.c", + "openssl/openssl/crypto/cmac/cm_pmeth.c", + "openssl/openssl/crypto/cmac/cmac.c", + "openssl/openssl/crypto/cms/cms_asn1.c", + "openssl/openssl/crypto/cms/cms_att.c", + "openssl/openssl/crypto/cms/cms_cd.c", + "openssl/openssl/crypto/cms/cms_dd.c", + "openssl/openssl/crypto/cms/cms_enc.c", + "openssl/openssl/crypto/cms/cms_env.c", + "openssl/openssl/crypto/cms/cms_err.c", + "openssl/openssl/crypto/cms/cms_ess.c", + "openssl/openssl/crypto/cms/cms_io.c", + "openssl/openssl/crypto/cms/cms_lib.c", + "openssl/openssl/crypto/cms/cms_pwri.c", + "openssl/openssl/crypto/cms/cms_sd.c", + "openssl/openssl/crypto/cms/cms_smime.c", + "openssl/openssl/crypto/comp/c_rle.c", + "openssl/openssl/crypto/comp/c_zlib.c", + "openssl/openssl/crypto/comp/comp_err.c", + "openssl/openssl/crypto/comp/comp_lib.c", + "openssl/openssl/crypto/conf/conf_api.c", + "openssl/openssl/crypto/conf/conf_def.c", + "openssl/openssl/crypto/conf/conf_err.c", + "openssl/openssl/crypto/conf/conf_lib.c", + "openssl/openssl/crypto/conf/conf_mall.c", + "openssl/openssl/crypto/conf/conf_mod.c", + "openssl/openssl/crypto/conf/conf_sap.c", + "openssl/openssl/crypto/cpt_err.c", + "openssl/openssl/crypto/cryptlib.c", + "openssl/openssl/crypto/cversion.c", + "openssl/openssl/crypto/des/cbc_cksm.c", + "openssl/openssl/crypto/des/cbc_enc.c", + "openssl/openssl/crypto/des/cfb64ede.c", + "openssl/openssl/crypto/des/cfb64enc.c", + "openssl/openssl/crypto/des/cfb_enc.c", + "openssl/openssl/crypto/des/des_old.c", + "openssl/openssl/crypto/des/des_old2.c", + "openssl/openssl/crypto/des/ecb3_enc.c", + "openssl/openssl/crypto/des/ecb_enc.c", + "openssl/openssl/crypto/des/ede_cbcm_enc.c", + "openssl/openssl/crypto/des/enc_read.c", + "openssl/openssl/crypto/des/enc_writ.c", + "openssl/openssl/crypto/des/fcrypt.c", + "openssl/openssl/crypto/des/ofb64ede.c", + "openssl/openssl/crypto/des/ofb64enc.c", + "openssl/openssl/crypto/des/ofb_enc.c", + "openssl/openssl/crypto/des/pcbc_enc.c", + "openssl/openssl/crypto/des/qud_cksm.c", + "openssl/openssl/crypto/des/rand_key.c", + "openssl/openssl/crypto/des/read2pwd.c", + "openssl/openssl/crypto/des/rpc_enc.c", + "openssl/openssl/crypto/des/set_key.c", + "openssl/openssl/crypto/des/str2key.c", + "openssl/openssl/crypto/des/xcbc_enc.c", + "openssl/openssl/crypto/dh/dh_ameth.c", + "openssl/openssl/crypto/dh/dh_asn1.c", + "openssl/openssl/crypto/dh/dh_check.c", + "openssl/openssl/crypto/dh/dh_depr.c", + "openssl/openssl/crypto/dh/dh_err.c", + "openssl/openssl/crypto/dh/dh_gen.c", + "openssl/openssl/crypto/dh/dh_key.c", + "openssl/openssl/crypto/dh/dh_lib.c", + "openssl/openssl/crypto/dh/dh_pmeth.c", + "openssl/openssl/crypto/dh/dh_prn.c", + "openssl/openssl/crypto/dsa/dsa_ameth.c", + "openssl/openssl/crypto/dsa/dsa_asn1.c", + "openssl/openssl/crypto/dsa/dsa_depr.c", + "openssl/openssl/crypto/dsa/dsa_err.c", + "openssl/openssl/crypto/dsa/dsa_gen.c", + "openssl/openssl/crypto/dsa/dsa_key.c", + "openssl/openssl/crypto/dsa/dsa_lib.c", + "openssl/openssl/crypto/dsa/dsa_ossl.c", + "openssl/openssl/crypto/dsa/dsa_pmeth.c", + "openssl/openssl/crypto/dsa/dsa_prn.c", + "openssl/openssl/crypto/dsa/dsa_sign.c", + "openssl/openssl/crypto/dsa/dsa_vrf.c", + "openssl/openssl/crypto/dso/dso_beos.c", + "openssl/openssl/crypto/dso/dso_dl.c", + "openssl/openssl/crypto/dso/dso_dlfcn.c", + "openssl/openssl/crypto/dso/dso_err.c", + "openssl/openssl/crypto/dso/dso_lib.c", + "openssl/openssl/crypto/dso/dso_null.c", + "openssl/openssl/crypto/dso/dso_openssl.c", + "openssl/openssl/crypto/dso/dso_vms.c", + "openssl/openssl/crypto/dso/dso_win32.c", + "openssl/openssl/crypto/ebcdic.c", + "openssl/openssl/crypto/ec/ec2_mult.c", + "openssl/openssl/crypto/ec/ec2_oct.c", + "openssl/openssl/crypto/ec/ec2_smpl.c", + "openssl/openssl/crypto/ec/ec_ameth.c", + "openssl/openssl/crypto/ec/ec_asn1.c", + "openssl/openssl/crypto/ec/ec_check.c", + "openssl/openssl/crypto/ec/ec_curve.c", + "openssl/openssl/crypto/ec/ec_cvt.c", + "openssl/openssl/crypto/ec/ec_err.c", + "openssl/openssl/crypto/ec/ec_key.c", + "openssl/openssl/crypto/ec/ec_lib.c", + "openssl/openssl/crypto/ec/ec_mult.c", + "openssl/openssl/crypto/ec/ec_oct.c", + "openssl/openssl/crypto/ec/ec_pmeth.c", + "openssl/openssl/crypto/ec/ec_print.c", + "openssl/openssl/crypto/ec/eck_prn.c", + "openssl/openssl/crypto/ec/ecp_mont.c", + "openssl/openssl/crypto/ec/ecp_nist.c", + "openssl/openssl/crypto/ec/ecp_nistp224.c", + "openssl/openssl/crypto/ec/ecp_nistp256.c", + "openssl/openssl/crypto/ec/ecp_nistp521.c", + "openssl/openssl/crypto/ec/ecp_nistputil.c", + "openssl/openssl/crypto/ec/ecp_oct.c", + "openssl/openssl/crypto/ec/ecp_smpl.c", + "openssl/openssl/crypto/ecdh/ech_err.c", + "openssl/openssl/crypto/ecdh/ech_key.c", + "openssl/openssl/crypto/ecdh/ech_lib.c", + "openssl/openssl/crypto/ecdh/ech_ossl.c", + "openssl/openssl/crypto/ecdsa/ecs_asn1.c", + "openssl/openssl/crypto/ecdsa/ecs_err.c", + "openssl/openssl/crypto/ecdsa/ecs_lib.c", + "openssl/openssl/crypto/ecdsa/ecs_ossl.c", + "openssl/openssl/crypto/ecdsa/ecs_sign.c", + "openssl/openssl/crypto/ecdsa/ecs_vrf.c", + "openssl/openssl/crypto/engine/eng_all.c", + "openssl/openssl/crypto/engine/eng_cnf.c", + "openssl/openssl/crypto/engine/eng_cryptodev.c", + "openssl/openssl/crypto/engine/eng_ctrl.c", + "openssl/openssl/crypto/engine/eng_dyn.c", + "openssl/openssl/crypto/engine/eng_err.c", + "openssl/openssl/crypto/engine/eng_fat.c", + "openssl/openssl/crypto/engine/eng_init.c", + "openssl/openssl/crypto/engine/eng_lib.c", + "openssl/openssl/crypto/engine/eng_list.c", + "openssl/openssl/crypto/engine/eng_openssl.c", + "openssl/openssl/crypto/engine/eng_pkey.c", + "openssl/openssl/crypto/engine/eng_rdrand.c", + "openssl/openssl/crypto/engine/eng_rsax.c", + "openssl/openssl/crypto/engine/eng_table.c", + "openssl/openssl/crypto/engine/tb_asnmth.c", + "openssl/openssl/crypto/engine/tb_cipher.c", + "openssl/openssl/crypto/engine/tb_dh.c", + "openssl/openssl/crypto/engine/tb_digest.c", + "openssl/openssl/crypto/engine/tb_dsa.c", + "openssl/openssl/crypto/engine/tb_ecdh.c", + "openssl/openssl/crypto/engine/tb_ecdsa.c", + "openssl/openssl/crypto/engine/tb_pkmeth.c", + "openssl/openssl/crypto/engine/tb_rand.c", + "openssl/openssl/crypto/engine/tb_rsa.c", + "openssl/openssl/crypto/engine/tb_store.c", + "openssl/openssl/crypto/err/err.c", + "openssl/openssl/crypto/err/err_all.c", + "openssl/openssl/crypto/err/err_prn.c", + "openssl/openssl/crypto/evp/bio_b64.c", + "openssl/openssl/crypto/evp/bio_enc.c", + "openssl/openssl/crypto/evp/bio_md.c", + "openssl/openssl/crypto/evp/bio_ok.c", + "openssl/openssl/crypto/evp/c_all.c", + "openssl/openssl/crypto/evp/c_allc.c", + "openssl/openssl/crypto/evp/c_alld.c", + "openssl/openssl/crypto/evp/digest.c", + "openssl/openssl/crypto/evp/e_aes.c", + "openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c", + "openssl/openssl/crypto/evp/e_bf.c", + "openssl/openssl/crypto/evp/e_camellia.c", + "openssl/openssl/crypto/evp/e_cast.c", + "openssl/openssl/crypto/evp/e_des.c", + "openssl/openssl/crypto/evp/e_des3.c", + "openssl/openssl/crypto/evp/e_idea.c", + "openssl/openssl/crypto/evp/e_null.c", + "openssl/openssl/crypto/evp/e_old.c", + "openssl/openssl/crypto/evp/e_rc2.c", + "openssl/openssl/crypto/evp/e_rc4.c", + "openssl/openssl/crypto/evp/e_rc4_hmac_md5.c", + "openssl/openssl/crypto/evp/e_rc5.c", + "openssl/openssl/crypto/evp/e_seed.c", + "openssl/openssl/crypto/evp/e_xcbc_d.c", + "openssl/openssl/crypto/evp/encode.c", + "openssl/openssl/crypto/evp/evp_acnf.c", + "openssl/openssl/crypto/evp/evp_cnf.c", + "openssl/openssl/crypto/evp/evp_enc.c", + "openssl/openssl/crypto/evp/evp_err.c", + "openssl/openssl/crypto/evp/evp_fips.c", + "openssl/openssl/crypto/evp/evp_key.c", + "openssl/openssl/crypto/evp/evp_lib.c", + "openssl/openssl/crypto/evp/evp_pbe.c", + "openssl/openssl/crypto/evp/evp_pkey.c", + "openssl/openssl/crypto/evp/m_dss.c", + "openssl/openssl/crypto/evp/m_dss1.c", + "openssl/openssl/crypto/evp/m_ecdsa.c", + "openssl/openssl/crypto/evp/m_md2.c", + "openssl/openssl/crypto/evp/m_md4.c", + "openssl/openssl/crypto/evp/m_md5.c", + "openssl/openssl/crypto/evp/m_mdc2.c", + "openssl/openssl/crypto/evp/m_null.c", + "openssl/openssl/crypto/evp/m_ripemd.c", + "openssl/openssl/crypto/evp/m_sha.c", + "openssl/openssl/crypto/evp/m_sha1.c", + "openssl/openssl/crypto/evp/m_sigver.c", + "openssl/openssl/crypto/evp/m_wp.c", + "openssl/openssl/crypto/evp/names.c", + "openssl/openssl/crypto/evp/p5_crpt.c", + "openssl/openssl/crypto/evp/p5_crpt2.c", + "openssl/openssl/crypto/evp/p_dec.c", + "openssl/openssl/crypto/evp/p_enc.c", + "openssl/openssl/crypto/evp/p_lib.c", + "openssl/openssl/crypto/evp/p_open.c", + "openssl/openssl/crypto/evp/p_seal.c", + "openssl/openssl/crypto/evp/p_sign.c", + "openssl/openssl/crypto/evp/p_verify.c", + "openssl/openssl/crypto/evp/pmeth_fn.c", + "openssl/openssl/crypto/evp/pmeth_gn.c", + "openssl/openssl/crypto/evp/pmeth_lib.c", + "openssl/openssl/crypto/ex_data.c", + "openssl/openssl/crypto/fips_ers.c", + "openssl/openssl/crypto/hmac/hm_ameth.c", + "openssl/openssl/crypto/hmac/hm_pmeth.c", + "openssl/openssl/crypto/hmac/hmac.c", + "openssl/openssl/crypto/idea/i_cbc.c", + "openssl/openssl/crypto/idea/i_cfb64.c", + "openssl/openssl/crypto/idea/i_ecb.c", + "openssl/openssl/crypto/idea/i_ofb64.c", + "openssl/openssl/crypto/idea/i_skey.c", + "openssl/openssl/crypto/krb5/krb5_asn.c", + "openssl/openssl/crypto/lhash/lh_stats.c", + "openssl/openssl/crypto/lhash/lhash.c", + "openssl/openssl/crypto/md2/md2_dgst.c", + "openssl/openssl/crypto/md2/md2_one.c", + "openssl/openssl/crypto/md4/md4_dgst.c", + "openssl/openssl/crypto/md4/md4_one.c", + "openssl/openssl/crypto/md5/md5_dgst.c", + "openssl/openssl/crypto/md5/md5_one.c", + "openssl/openssl/crypto/mdc2/mdc2_one.c", + "openssl/openssl/crypto/mdc2/mdc2dgst.c", + "openssl/openssl/crypto/mem.c", + "openssl/openssl/crypto/mem_dbg.c", + "openssl/openssl/crypto/modes/cbc128.c", + "openssl/openssl/crypto/modes/ccm128.c", + "openssl/openssl/crypto/modes/cfb128.c", + "openssl/openssl/crypto/modes/ctr128.c", + "openssl/openssl/crypto/modes/cts128.c", + "openssl/openssl/crypto/modes/gcm128.c", + "openssl/openssl/crypto/modes/ofb128.c", + "openssl/openssl/crypto/modes/xts128.c", + "openssl/openssl/crypto/o_dir.c", + "openssl/openssl/crypto/o_fips.c", + "openssl/openssl/crypto/o_init.c", + "openssl/openssl/crypto/o_str.c", + "openssl/openssl/crypto/o_time.c", + "openssl/openssl/crypto/objects/o_names.c", + "openssl/openssl/crypto/objects/obj_dat.c", + "openssl/openssl/crypto/objects/obj_err.c", + "openssl/openssl/crypto/objects/obj_lib.c", + "openssl/openssl/crypto/objects/obj_xref.c", + "openssl/openssl/crypto/ocsp/ocsp_asn.c", + "openssl/openssl/crypto/ocsp/ocsp_cl.c", + "openssl/openssl/crypto/ocsp/ocsp_err.c", + "openssl/openssl/crypto/ocsp/ocsp_ext.c", + "openssl/openssl/crypto/ocsp/ocsp_ht.c", + "openssl/openssl/crypto/ocsp/ocsp_lib.c", + "openssl/openssl/crypto/ocsp/ocsp_prn.c", + "openssl/openssl/crypto/ocsp/ocsp_srv.c", + "openssl/openssl/crypto/ocsp/ocsp_vfy.c", + "openssl/openssl/crypto/pem/pem_all.c", + "openssl/openssl/crypto/pem/pem_err.c", + "openssl/openssl/crypto/pem/pem_info.c", + "openssl/openssl/crypto/pem/pem_lib.c", + "openssl/openssl/crypto/pem/pem_oth.c", + "openssl/openssl/crypto/pem/pem_pk8.c", + "openssl/openssl/crypto/pem/pem_pkey.c", + "openssl/openssl/crypto/pem/pem_seal.c", + "openssl/openssl/crypto/pem/pem_sign.c", + "openssl/openssl/crypto/pem/pem_x509.c", + "openssl/openssl/crypto/pem/pem_xaux.c", + "openssl/openssl/crypto/pem/pvkfmt.c", + "openssl/openssl/crypto/pkcs12/p12_add.c", + "openssl/openssl/crypto/pkcs12/p12_asn.c", + "openssl/openssl/crypto/pkcs12/p12_attr.c", + "openssl/openssl/crypto/pkcs12/p12_crpt.c", + "openssl/openssl/crypto/pkcs12/p12_crt.c", + "openssl/openssl/crypto/pkcs12/p12_decr.c", + "openssl/openssl/crypto/pkcs12/p12_init.c", + "openssl/openssl/crypto/pkcs12/p12_key.c", + "openssl/openssl/crypto/pkcs12/p12_kiss.c", + "openssl/openssl/crypto/pkcs12/p12_mutl.c", + "openssl/openssl/crypto/pkcs12/p12_npas.c", + "openssl/openssl/crypto/pkcs12/p12_p8d.c", + "openssl/openssl/crypto/pkcs12/p12_p8e.c", + "openssl/openssl/crypto/pkcs12/p12_utl.c", + "openssl/openssl/crypto/pkcs12/pk12err.c", + "openssl/openssl/crypto/pkcs7/bio_pk7.c", + "openssl/openssl/crypto/pkcs7/pk7_asn1.c", + "openssl/openssl/crypto/pkcs7/pk7_attr.c", + "openssl/openssl/crypto/pkcs7/pk7_doit.c", + "openssl/openssl/crypto/pkcs7/pk7_lib.c", + "openssl/openssl/crypto/pkcs7/pk7_mime.c", + "openssl/openssl/crypto/pkcs7/pk7_smime.c", + "openssl/openssl/crypto/pkcs7/pkcs7err.c", + "openssl/openssl/crypto/pqueue/pqueue.c", + "openssl/openssl/crypto/rand/md_rand.c", + "openssl/openssl/crypto/rand/rand_egd.c", + "openssl/openssl/crypto/rand/rand_err.c", + "openssl/openssl/crypto/rand/rand_lib.c", + "openssl/openssl/crypto/rand/rand_nw.c", + "openssl/openssl/crypto/rand/rand_os2.c", + "openssl/openssl/crypto/rand/rand_unix.c", + "openssl/openssl/crypto/rand/rand_win.c", + "openssl/openssl/crypto/rand/randfile.c", + "openssl/openssl/crypto/rc2/rc2_cbc.c", + "openssl/openssl/crypto/rc2/rc2_ecb.c", + "openssl/openssl/crypto/rc2/rc2_skey.c", + "openssl/openssl/crypto/rc2/rc2cfb64.c", + "openssl/openssl/crypto/rc2/rc2ofb64.c", + "openssl/openssl/crypto/rc4/rc4_utl.c", + "openssl/openssl/crypto/ripemd/rmd_dgst.c", + "openssl/openssl/crypto/ripemd/rmd_one.c", + "openssl/openssl/crypto/rsa/rsa_ameth.c", + "openssl/openssl/crypto/rsa/rsa_asn1.c", + "openssl/openssl/crypto/rsa/rsa_chk.c", + "openssl/openssl/crypto/rsa/rsa_crpt.c", + "openssl/openssl/crypto/rsa/rsa_depr.c", + "openssl/openssl/crypto/rsa/rsa_eay.c", + "openssl/openssl/crypto/rsa/rsa_err.c", + "openssl/openssl/crypto/rsa/rsa_gen.c", + "openssl/openssl/crypto/rsa/rsa_lib.c", + "openssl/openssl/crypto/rsa/rsa_none.c", + "openssl/openssl/crypto/rsa/rsa_null.c", + "openssl/openssl/crypto/rsa/rsa_oaep.c", + "openssl/openssl/crypto/rsa/rsa_pk1.c", + "openssl/openssl/crypto/rsa/rsa_pmeth.c", + "openssl/openssl/crypto/rsa/rsa_prn.c", + "openssl/openssl/crypto/rsa/rsa_pss.c", + "openssl/openssl/crypto/rsa/rsa_saos.c", + "openssl/openssl/crypto/rsa/rsa_sign.c", + "openssl/openssl/crypto/rsa/rsa_ssl.c", + "openssl/openssl/crypto/rsa/rsa_x931.c", + "openssl/openssl/crypto/seed/seed.c", + "openssl/openssl/crypto/seed/seed_cbc.c", + "openssl/openssl/crypto/seed/seed_cfb.c", + "openssl/openssl/crypto/seed/seed_ecb.c", + "openssl/openssl/crypto/seed/seed_ofb.c", + "openssl/openssl/crypto/sha/sha1_one.c", + "openssl/openssl/crypto/sha/sha1dgst.c", + "openssl/openssl/crypto/sha/sha256.c", + "openssl/openssl/crypto/sha/sha512.c", + "openssl/openssl/crypto/sha/sha_dgst.c", + "openssl/openssl/crypto/sha/sha_one.c", + "openssl/openssl/crypto/srp/srp_lib.c", + "openssl/openssl/crypto/srp/srp_vfy.c", + "openssl/openssl/crypto/stack/stack.c", + "openssl/openssl/crypto/store/str_err.c", + "openssl/openssl/crypto/store/str_lib.c", + "openssl/openssl/crypto/store/str_mem.c", + "openssl/openssl/crypto/store/str_meth.c", + "openssl/openssl/crypto/ts/ts_asn1.c", + "openssl/openssl/crypto/ts/ts_conf.c", + "openssl/openssl/crypto/ts/ts_err.c", + "openssl/openssl/crypto/ts/ts_lib.c", + "openssl/openssl/crypto/ts/ts_req_print.c", + "openssl/openssl/crypto/ts/ts_req_utils.c", + "openssl/openssl/crypto/ts/ts_rsp_print.c", + "openssl/openssl/crypto/ts/ts_rsp_sign.c", + "openssl/openssl/crypto/ts/ts_rsp_utils.c", + "openssl/openssl/crypto/ts/ts_rsp_verify.c", + "openssl/openssl/crypto/ts/ts_verify_ctx.c", + "openssl/openssl/crypto/txt_db/txt_db.c", + "openssl/openssl/crypto/ui/ui_compat.c", + "openssl/openssl/crypto/ui/ui_err.c", + "openssl/openssl/crypto/ui/ui_lib.c", + "openssl/openssl/crypto/ui/ui_openssl.c", + "openssl/openssl/crypto/ui/ui_util.c", + "openssl/openssl/crypto/uid.c", + "openssl/openssl/crypto/whrlpool/wp_dgst.c", + "openssl/openssl/crypto/x509/by_dir.c", + "openssl/openssl/crypto/x509/by_file.c", + "openssl/openssl/crypto/x509/x509_att.c", + "openssl/openssl/crypto/x509/x509_cmp.c", + "openssl/openssl/crypto/x509/x509_d2.c", + "openssl/openssl/crypto/x509/x509_def.c", + "openssl/openssl/crypto/x509/x509_err.c", + "openssl/openssl/crypto/x509/x509_ext.c", + "openssl/openssl/crypto/x509/x509_lu.c", + "openssl/openssl/crypto/x509/x509_obj.c", + "openssl/openssl/crypto/x509/x509_r2x.c", + "openssl/openssl/crypto/x509/x509_req.c", + "openssl/openssl/crypto/x509/x509_set.c", + "openssl/openssl/crypto/x509/x509_trs.c", + "openssl/openssl/crypto/x509/x509_txt.c", + "openssl/openssl/crypto/x509/x509_v3.c", + "openssl/openssl/crypto/x509/x509_vfy.c", + "openssl/openssl/crypto/x509/x509_vpm.c", + "openssl/openssl/crypto/x509/x509cset.c", + "openssl/openssl/crypto/x509/x509name.c", + "openssl/openssl/crypto/x509/x509rset.c", + "openssl/openssl/crypto/x509/x509spki.c", + "openssl/openssl/crypto/x509/x509type.c", + "openssl/openssl/crypto/x509/x_all.c", + "openssl/openssl/crypto/x509v3/pcy_cache.c", + "openssl/openssl/crypto/x509v3/pcy_data.c", + "openssl/openssl/crypto/x509v3/pcy_lib.c", + "openssl/openssl/crypto/x509v3/pcy_map.c", + "openssl/openssl/crypto/x509v3/pcy_node.c", + "openssl/openssl/crypto/x509v3/pcy_tree.c", + "openssl/openssl/crypto/x509v3/v3_addr.c", + "openssl/openssl/crypto/x509v3/v3_akey.c", + "openssl/openssl/crypto/x509v3/v3_akeya.c", + "openssl/openssl/crypto/x509v3/v3_alt.c", + "openssl/openssl/crypto/x509v3/v3_asid.c", + "openssl/openssl/crypto/x509v3/v3_bcons.c", + "openssl/openssl/crypto/x509v3/v3_bitst.c", + "openssl/openssl/crypto/x509v3/v3_conf.c", + "openssl/openssl/crypto/x509v3/v3_cpols.c", + "openssl/openssl/crypto/x509v3/v3_crld.c", + "openssl/openssl/crypto/x509v3/v3_enum.c", + "openssl/openssl/crypto/x509v3/v3_extku.c", + "openssl/openssl/crypto/x509v3/v3_genn.c", + "openssl/openssl/crypto/x509v3/v3_ia5.c", + "openssl/openssl/crypto/x509v3/v3_info.c", + "openssl/openssl/crypto/x509v3/v3_int.c", + "openssl/openssl/crypto/x509v3/v3_lib.c", + "openssl/openssl/crypto/x509v3/v3_ncons.c", + "openssl/openssl/crypto/x509v3/v3_ocsp.c", + "openssl/openssl/crypto/x509v3/v3_pci.c", + "openssl/openssl/crypto/x509v3/v3_pcia.c", + "openssl/openssl/crypto/x509v3/v3_pcons.c", + "openssl/openssl/crypto/x509v3/v3_pku.c", + "openssl/openssl/crypto/x509v3/v3_pmaps.c", + "openssl/openssl/crypto/x509v3/v3_prn.c", + "openssl/openssl/crypto/x509v3/v3_purp.c", + "openssl/openssl/crypto/x509v3/v3_skey.c", + "openssl/openssl/crypto/x509v3/v3_sxnet.c", + "openssl/openssl/crypto/x509v3/v3_utl.c", + "openssl/openssl/crypto/x509v3/v3err.c", + "openssl/openssl/engines/e_4758cca.c", + "openssl/openssl/engines/e_aep.c", + "openssl/openssl/engines/e_atalla.c", + "openssl/openssl/engines/e_capi.c", + "openssl/openssl/engines/e_chil.c", + "openssl/openssl/engines/e_cswift.c", + "openssl/openssl/engines/e_gmp.c", + "openssl/openssl/engines/e_nuron.c", + "openssl/openssl/engines/e_sureware.c", + "openssl/openssl/engines/e_ubsec.c" + ], + "sources/": [ + ["exclude", "md2/.*$"], + ["exclude", "store/.*$"] + ], + "conditions": [ + ["openssl_enable_asm!=1", { + "defines": [ + "OPENSSL_NO_ASM" + ], + "sources": [ + "openssl/openssl/crypto/aes/aes_cbc.c", + "openssl/openssl/crypto/aes/aes_core.c", + "openssl/openssl/crypto/bf/bf_enc.c", + "openssl/openssl/crypto/bn/bn_asm.c", + "openssl/openssl/crypto/cast/c_enc.c", + "openssl/openssl/crypto/camellia/camellia.c", + "openssl/openssl/crypto/camellia/cmll_cbc.c", + "openssl/openssl/crypto/camellia/cmll_misc.c", + "openssl/openssl/crypto/des/des_enc.c", + "openssl/openssl/crypto/des/fcrypt_b.c", + "openssl/openssl/crypto/mem_clr.c", + "openssl/openssl/crypto/rc4/rc4_enc.c", + "openssl/openssl/crypto/rc4/rc4_skey.c", + "openssl/openssl/crypto/whrlpool/wp_block.c" + ] + }, { + "defines": [ + "AES_ASM", + "BF_ASM", + "BNCO_ASM", + "BN_ASM", + "CPUID_ASM", + "DES_ASM", + "LIB_BN_ASM", + "OPENSSL_BN_ASM", + "OPENSSL_CPUID_OBJ", + "RIP_ASM", + "WHIRLPOOL_ASM", + "WP_ASM" + ], + "conditions": [ + ["OS!='win' and OS!='mac' and target_arch=='ia32'", { + "sources": [ + "asm/x86-elf-gas/aes/aes-586.s", + "asm/x86-elf-gas/aes/aesni-x86.s", + "asm/x86-elf-gas/bf/bf-686.s", + "asm/x86-elf-gas/bn/x86-mont.s", + "asm/x86-elf-gas/bn/x86.s", + "asm/x86-elf-gas/camellia/cmll-x86.s", + "asm/x86-elf-gas/cast/cast-586.s", + "asm/x86-elf-gas/des/crypt586.s", + "asm/x86-elf-gas/des/des-586.s", + "asm/x86-elf-gas/md5/md5-586.s", + "asm/x86-elf-gas/rc4/rc4-586.s", + "asm/x86-elf-gas/rc5/rc5-586.s", + "asm/x86-elf-gas/ripemd/rmd-586.s", + "asm/x86-elf-gas/sha/sha1-586.s", + "asm/x86-elf-gas/sha/sha256-586.s", + "asm/x86-elf-gas/sha/sha512-586.s", + "asm/x86-elf-gas/whrlpool/wp-mmx.s", + "asm/x86-elf-gas/x86cpuid.s", + "openssl/openssl/crypto/whrlpool/wp_block.c" + ] + }], + ["OS!='win' and OS!='mac' and target_arch=='x64'", + { + "sources": [ + "asm/x64-elf-gas/aes/aes-x86_64.s", + "asm/x64-elf-gas/aes/aesni-x86_64.s", + "asm/x64-elf-gas/aes/aesni-sha1-x86_64.s", + "asm/x64-elf-gas/bn/modexp512-x86_64.s", + "asm/x64-elf-gas/bn/x86_64-mont.s", + "asm/x64-elf-gas/camellia/cmll-x86_64.s", + "asm/x64-elf-gas/md5/md5-x86_64.s", + "asm/x64-elf-gas/rc4/rc4-x86_64.s", + "asm/x64-elf-gas/rc4/rc4-md5-x86_64.s", + "asm/x64-elf-gas/sha/sha1-x86_64.s", + "asm/x64-elf-gas/sha/sha512-x86_64.s", + "asm/x64-elf-gas/whrlpool/wp-x86_64.s", + "asm/x64-elf-gas/x86_64cpuid.s", + #Non - generated asm + "openssl/openssl/crypto/bn/asm/x86_64-gcc.c", + #No asm available + "openssl/openssl/crypto/bf/bf_enc.c", + "openssl/openssl/crypto/cast/c_enc.c", + "openssl/openssl/crypto/camellia/cmll_misc.c", + "openssl/openssl/crypto/des/des_enc.c", + "openssl/openssl/crypto/des/fcrypt_b.c" + ] + }], + ["OS=='mac' and target_arch=='ia32'", { + "sources": [ + "asm/x86-macosx-gas/aes/aes-586.s", + "asm/x86-macosx-gas/aes/aesni-x86.s", + "asm/x86-macosx-gas/bf/bf-686.s", + "asm/x86-macosx-gas/bn/x86-mont.s", + "asm/x86-macosx-gas/bn/x86.s", + "asm/x86-macosx-gas/camellia/cmll-x86.s", + "asm/x86-macosx-gas/cast/cast-586.s", + "asm/x86-macosx-gas/des/crypt586.s", + "asm/x86-macosx-gas/des/des-586.s", + "asm/x86-macosx-gas/md5/md5-586.s", + "asm/x86-macosx-gas/rc4/rc4-586.s", + "asm/x86-macosx-gas/rc5/rc5-586.s", + "asm/x86-macosx-gas/ripemd/rmd-586.s", + "asm/x86-macosx-gas/sha/sha1-586.s", + "asm/x86-macosx-gas/sha/sha256-586.s", + "asm/x86-macosx-gas/sha/sha512-586.s", + "asm/x86-macosx-gas/whrlpool/wp-mmx.s", + "asm/x86-macosx-gas/x86cpuid.s", + "openssl/openssl/crypto/whrlpool/wp_block.c" + ] + }], + ["OS=='mac' and target_arch=='x64'", { + "sources": [ + "asm/x64-macosx-gas/aes/aes-x86_64.s", + "asm/x64-macosx-gas/aes/aesni-x86_64.s", + "asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s", + "asm/x64-macosx-gas/bn/modexp512-x86_64.s", + "asm/x64-macosx-gas/bn/x86_64-mont.s", + "asm/x64-macosx-gas/camellia/cmll-x86_64.s", + "asm/x64-macosx-gas/md5/md5-x86_64.s", + "asm/x64-macosx-gas/rc4/rc4-x86_64.s", + "asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s", + "asm/x64-macosx-gas/sha/sha1-x86_64.s", + "asm/x64-macosx-gas/sha/sha512-x86_64.s", + "asm/x64-macosx-gas/whrlpool/wp-x86_64.s", + "asm/x64-macosx-gas/x86_64cpuid.s", + #Non - generated asm + "openssl/openssl/crypto/bn/asm/x86_64-gcc.c", + #No asm available + "openssl/openssl/crypto/bf/bf_enc.c", + "openssl/openssl/crypto/cast/c_enc.c", + "openssl/openssl/crypto/camellia/cmll_misc.c", + "openssl/openssl/crypto/des/des_enc.c", + "openssl/openssl/crypto/des/fcrypt_b.c" + ] + }], + ["OS=='win' and target_arch=='ia32'", { + "sources": [ + "asm/x86-win32-masm/aes/aes-586.asm", + "asm/x86-win32-masm/aes/aesni-x86.asm", + "asm/x86-win32-masm/bf/bf-686.asm", + "asm/x86-win32-masm/bn/x86-mont.asm", + "asm/x86-win32-masm/bn/x86.asm", + "asm/x86-win32-masm/camellia/cmll-x86.asm", + "asm/x86-win32-masm/cast/cast-586.asm", + "asm/x86-win32-masm/des/crypt586.asm", + "asm/x86-win32-masm/des/des-586.asm", + "asm/x86-win32-masm/md5/md5-586.asm", + "asm/x86-win32-masm/rc4/rc4-586.asm", + "asm/x86-win32-masm/rc5/rc5-586.asm", + "asm/x86-win32-masm/ripemd/rmd-586.asm", + "asm/x86-win32-masm/sha/sha1-586.asm", + "asm/x86-win32-masm/sha/sha256-586.asm", + "asm/x86-win32-masm/sha/sha512-586.asm", + "asm/x86-win32-masm/whrlpool/wp-mmx.asm", + "asm/x86-win32-masm/x86cpuid.asm", + "openssl/openssl/crypto/whrlpool/wp_block.c" + ], + "rules": [ + { + "rule_name": "Assemble", + "extension": "asm", + "inputs": [], + "outputs": [ + "<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj", + ], + "action": [ + "ml.exe", + "/Zi", + "/safeseh", + "/Fo", "<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj", + "/c", "<(RULE_INPUT_PATH)", + ], + "process_outputs_as_sources": 0, + "message": "Assembling <(RULE_INPUT_PATH) to <(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj.", + } + ] + }], + ["OS=='win' and target_arch=='x64'", + { + "sources": [ + "asm/x64-win32-masm/aes/aes-x86_64.asm", + "asm/x64-win32-masm/aes/aesni-x86_64.asm", + "asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm", + "asm/x64-win32-masm/bn/modexp512-x86_64.asm", + "asm/x64-win32-masm/bn/x86_64-mont.asm", + "asm/x64-win32-masm/camellia/cmll-x86_64.asm", + "asm/x64-win32-masm/md5/md5-x86_64.asm", + "asm/x64-win32-masm/rc4/rc4-x86_64.asm", + "asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm", + "asm/x64-win32-masm/sha/sha1-x86_64.asm", + "asm/x64-win32-masm/sha/sha512-x86_64.asm", + "asm/x64-win32-masm/whrlpool/wp-x86_64.asm", + "asm/x64-win32-masm/x86_64cpuid.asm", + #Non - generated asm + "openssl/openssl/crypto/bn/asm/x86_64-win32-masm.asm", + #No asm available + "openssl/openssl/crypto/bf/bf_enc.c", + "openssl/openssl/crypto/cast/c_enc.c", + "openssl/openssl/crypto/camellia/cmll_misc.c", + "openssl/openssl/crypto/des/des_enc.c", + "openssl/openssl/crypto/des/fcrypt_b.c" + ], + "rules": [ + { + "rule_name": "Assemble", + "extension": "asm", + "inputs": [], + "outputs": [ + "<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj", + ], + "action": [ + "ml64.exe", + "/Zi", + "/Fo", "<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj", + "/c", "<(RULE_INPUT_PATH)", + ], + "process_outputs_as_sources": 0, + "message": "Assembling <(RULE_INPUT_PATH) to <(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).obj.", + } + ] + }] + ] + }], + ["OS=='win'", { + "defines": [ + "MK1MF_BUILD", + "WIN32_LEAN_AND_MEAN" + ], + "link_settings": { + "libraries": [ + "-lgdi32.lib", + "-luser32.lib", + "-lwsock32.lib", + ], + "conditions": [ + ["_type=='shared_library'", { + "libraries": [ + "-ladvapi32.lib" + ] + }] + ] + } + }, { + "defines": [ + "TERMIOS", + ], + "cflags": [ + "-Wno-missing-field-initializers" + ], + }], + ["is_clang==1 or gcc_version>=43", { + "cflags": [ + "-Wno-old-style-declaration" + ], + }], + ["OS=='solaris'", { + "defines": [ + "__EXTENSIONS__" + ], + }], + ["target_arch=='arm'", { + "sources": [ + "openssl/openssl/crypto/armcap.c" + ], + }], + ], + }, + ] +} diff --git a/vendor/libv8-convert/cvv8/ClassCreator.hpp b/vendor/libv8-convert/cvv8/ClassCreator.hpp deleted file mode 100644 index 4a8b6d7d9..000000000 --- a/vendor/libv8-convert/cvv8/ClassCreator.hpp +++ /dev/null @@ -1,1286 +0,0 @@ -#if !defined(CODE_GOOGLE_COM_P_V8_CONVERT_CLASS_CREATOR_HPP_INCLUDED) -#define CODE_GOOGLE_COM_P_V8_CONVERT_CLASS_CREATOR_HPP_INCLUDED 1 -/** LICENSE - - This software's source code, including accompanying documentation and - demonstration applications, are licensed under the following - conditions... - - The author (Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) - explicitly disclaims copyright in all jurisdictions which recognize - such a disclaimer. In such jurisdictions, this software is released - into the Public Domain. - - In jurisdictions which do not recognize Public Domain property - (e.g. Germany as of 2011), this software is Copyright (c) 2011 - by Stephan G. Beal, and is released under the terms of the MIT License - (see below). - - In jurisdictions which recognize Public Domain property, the user of - this software may choose to accept it either as 1) Public Domain, 2) - under the conditions of the MIT License (see below), or 3) under the - terms of dual Public Domain/MIT License conditions described here, as - they choose. - - The MIT License is about as close to Public Domain as a license can - get, and is described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - -- - Copyright (c) 2011 Stephan G. Beal (http://wanderinghorse.net/home/stephan/) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - --END OF MIT LICENSE-- - - For purposes of the above license, the term "Software" includes - documentation and demonstration source code which accompanies - this software. ("Accompanies" = is contained in the Software's - primary public source code repository.) - -*/ - -#include -#include -#include "convert.hpp" -//#include // only for debuggering -#include "NativeToJSMap.hpp" -namespace cvv8 { - - /** - Policy template used by ClassCreator for - instantiating T objects. - */ - template - class ClassCreator_Factory - { - public: - typedef T * ReturnType; - /** - Must instantiate a new T object based on the given - arguments. On error it should throw an exception (which the - binding framework will convert to a JS-side exception). It - may also return NULL on error, but the error message - probably won't be as clear for the user. - - Ownership of the object is passed to the caller (the - binding API internals), and eventually given to v8. - - jsSelf will be the newly-created JS-side 'this' object. It - is not normally required by this function but it is - sometimes useful when we need to bind supplementary - properties in the ctor, especially when binding a "pure - C++" class which has no native place to store such - properties. - - At the time this is called, jsSelf is not connected to the - native (because it hasn't yet been created). - Implementations must not perform the actual binding of the - returned native to jsSelf - ClassCreator will do that - immediately after Create() returns the new object. - - The default implementation simply return (new T). - */ - static ReturnType Create( v8::Persistent & jsSelf, v8::Arguments const & argv ) - { - return new T; - } - - /** - Must destroy obj using a mechanism complementary to its - construction via a prior call to Create(). - - The default implementation simply calls (delete obj). - */ - static void Delete( T * obj ) - { - delete obj; - } - }; - - /** - Base class for static ClassCreator options. - */ - template - struct Opt_ConstVal - { - typedef ValT Type; - const static Type Value = Val; - }; - - /** - Base class for static integer ClassCreator options. - */ - template - struct Opt_Int : Opt_ConstVal - {}; - - /** - Base class for static boolean ClassCreator options. - */ - template - struct Opt_Bool : Opt_ConstVal - {}; - - /** - A ClassCreator policy/option class responsible specifying whether - or not a ClassCreator-bound class should allow "Foo()" and "new - Foo()" to behave the same or not. If the Value member is false - (the default) then "Foo()" is not allowed to behave as a - constructor call (it will generate an error), otherwise it will - be treated exactly as if "new Foo()" had been called. - */ - template - struct ClassCreator_AllowCtorWithoutNew : Opt_Bool - {}; - - /** - ClassCreator policy which determines whether lookups for native - types in JS objects should walk through the prototype - chain. This can decrease the speed of JS-to-this operations and - is necessary only if bound types will be subclassed (either from - other bound native types or from JS classes). - - The default value is true for the sake of usability. If JS-side - subclassing will never be used, you can potentially optimize out a - few lookup operations by creating the specialization by subclassing - Opt_Bool. - */ - template - struct ClassCreator_SearchPrototypeForThis : Opt_Bool - {}; - - /** - ClassCreator policy type which defines a "type ID" value - for a type wrapped using ClassCreator. This is used - together with JSToNative_ObjectWithInternalFieldsTypeSafe - (type THAT 10 times fast) to provide a lightweight - (but highly effective) type check when extracting - natives from v8 (as void pointers). The default - implementation is fine for all cases i can think of, but i can - concieve of one or two uses for specializations (e.g. storing the - JS-side name of the class as the type ID). - - The type id must be unique per type except that subtypes may - (depending on various other binding options) may need use the same - value as the parent type. If multiple types share the same type ID, - the type-safety check can be bypassed, _potentially_ leading to an - illegal static_cast() and subsequent mis-use of the pointer. i - stress the word "potentially" because to get that condition one - would have to (A) abuse the object via the C++ API (which doesn't - happen via the binding process, and you're probably also not going - to do it) or (B) write some script code to confuse two bound native - types about who is really who when a particular member is called. - - In the case of subclassed bound types, the - ClassCreator_TypeID impl should subclass - ClassCreator_TypeID. Whether or not this is _required_ - for proper functionality depends at least in part on whether - (ClassCreator_InternalFields::TypeIDIndex>=0). If it is - negative, subclasses do not need to explicitly define this policy - because the type ID won't be used for purposes of validating a JS-held - pointer's native type. - - TODO: see if we can consolidate this type with TypeName<>. The problem - at the moment is that JSToNative_ObjectWithInternalFieldsTypeSafe - takes a (void const * &) and TypeName::Value is a (char const *), which - won't convert to (void const *) in the context of template parameters. - */ - template - struct ClassCreator_TypeID - { - const static void * Value; - }; - template - const void * ClassCreator_TypeID::Value = TypeName::Value; - - /** - Convenience base type for ClassCreator_InternalFields - implementations. - - See the member documentation for the meaning of - HowMany and Index. - - If any of the following conditions are met then - a compile-time assertion is triggered: - - - (ObjectIndex<0) - - - (ObjectIndex>=HowMany) - - - (TypeIndex>=HowMany). - - - (TypeIndex == ObjectIndex) - - TypeIndex may be negative, which indicates to ClassCreator that the - binding should not store type ID information. However, if it is - negative then T must not be used together with - JSToNative_ObjectWithInternalFieldsTypeSafe - doing so will trigger - a compile-time assertion. - */ - template - struct ClassCreator_InternalFields_Base - { - /** - Total number of internal fields assigned to JS-side T - objects. - */ - static const int Count = HowMany; - - /** - The internal field index at which ClassCreator policies should - expect the native object to be found in any given JS object. - It must be 0 or greater, and must be less than Value. - */ - static const int NativeIndex = ObjectIndex; - - /** - The internal field index at which ClassCreator policies - should expect a type identifier tag to be stored. - This can be used in conjunction with - JSToNative_ObjectWithInternalFieldsTypeSafe (or similar) - to provide an extra level of type safety at JS runtime. - - */ - static const int TypeIDIndex = TypeIndex; - private: - typedef char AssertFields[ - (HowMany > TypeIndex) - && (HowMany > ObjectIndex) - && (TypeIndex != ObjectIndex) - && (ObjectIndex >= 0) - ? 1 : -1]; - }; - - /** - The ClassCreator policy which sets the number of internal - fields reserved for JS objects and the internal field index - (0-based) at which the native object is stored . The Count - value must be greater than 0 and greater than the NativeIndex - member. Failing to meet these prerequisites will cause a - compile-time assertion to be triggered. - - ACHTUNG SUBCLASSERS: - - When using a heirarchy of native types, more than one of which - is compatible with CastFromJS(), conversions from subtype to - base type will fail unless all subtypes use the same internal - field placement as the parent type. If this code can detect a - mismatch then it will fail gracefully (e.g. a JS-side - exception), and if not then it might mis-cast an object and - cause Undefined Behaviour. - - If a given parent type uses a custom ClassCreator_InternalFields - specialization then to ensure that subclasses always have the - same placement, they "should" define their own policy like - this: - - @code - template <> - struct ClassCreator_InternalFields< SubType > - : ClassCreator_InternalFields< ParentType > - {}; - @endcode - - That prohibits special internal field handling in the subtypes, - but experience hasn't shown that subclasses need their own - internal fields. Normaly a single internal field is all we need - when binding native data. And when i say "normally", i mean - "almost always." - - This must-match requirement is partially a side-effect of the library - internally using the field count as a santiy check before trying to - extract data from internal fields. It also exists so that the - optional (but recommended) type-safety-check support (added in late - June 2011: see JSToNative_ObjectWithInternalFieldsTypeSafe) will - treat the subclasses as instances of the base class. - */ - template - struct ClassCreator_InternalFields : ClassCreator_InternalFields_Base - { - }; - - - /** - This policy is used by ClassCreator::SetupBindings() as the generic - interface for plugging in a bound class. Clients are not required to - specialise this, but see this class' Initialize() for what might - happen if they don't. - */ - template - struct ClassCreator_SetupBindings - { - /** - Specializations should perform any class/function-related binding - here, adding their functionality to the given object (which is - normally the logical global object but need not be). (Note that the - handle refererence is const but that object itself can be modified. - - The default implementation throws an exception deriving from - std::exception, so it must be specialized to be useful. A default - specialization exists because there are probably a few cases - out there which don't really need this. But most (if not all) - need a setup function, and this is the official one for - ClassCreator-wrapped types. Implementations may of course simply - forward the call to another, client-provided function. - - On error the binding should throw a NATIVE exception (ideally - deriving from std::exception because (A) it's portable practice - and (B) parts of the cvv8 API handles those explicitly). - - Several years of experience have shown that this function (or - similar implementations) should take some care to make sure - not to set up their bindings twice. We can do that by using the - following pattern: - - @code - typedef ClassCreator CC; - CC & cc( CC::Instance() ); - if( cc.IsSealed() ) { - cc.AddClassTo( "T", dest ); - return; - } - - // ... do your bindings here... - - // As the final step: - cc.AddClassTo( "T", dest ); - return; - @endcode - - If you do not actually want to add the class to the dest object, - you should call Seal() instead of AddClassTo() (or pass a different - destination object to AddClassTo(). - */ - static void Initialize( v8::Handle const & target ) - { - throw std::runtime_error("ClassCreator_SetupBindings MUST be specialized " - "in order to be useful!"); - } - }; - - /** - A concrete ClassCreator_SetupBindings implementation which forwards - the call to a user-defined function. - */ - template const &) > - struct ClassCreator_SetupBindings_ClientFunc - { - /** - Calls Func(target). - */ - static void Initialize( v8::Handle const & target ) - { - Func(target); - } - }; - - /** - The ClassCreator policy class responsible for doing optional - class-specific binding-related work as part of the JS/Native - object construction process. - - The default specialization does nothing (which is okay for the - general case) but defines the interface which specializations - must implement. - - Reminder to self: we could arguably benefit by splitting this policy - into 3 classes, but experience has shown that the metadata used by - the 3 functions are typically shared amongst the 3 implementations - (or 2 of them in most cases). - */ - template - struct ClassCreator_WeakWrap - { - typedef typename TypeInfo::NativeHandle NativeHandle; - - /** - Similar to Wrap(), but this is called before the native constructor is called. - It is rarely needed, but is necessary if one needs to manipulate the JS - "this" object before the native object is constructed, so that the native ctor - can access information stored in the JS-side internal fields. - - If this throws a native exception, construction of the - object will fail and Unwrap() is called, passed - (jsSelf,NULL), to clean up any data which this function might have - stored in jsSelf. - - The argv object is the arguments passed to the constructor. - - The default implementation does nothing. - */ - static void PreWrap( v8::Persistent const &, v8::Arguments const & ) - { - return; - } - - - /** - This operation is called one time from ClassCreator for each - new object, directly after the native has been connected to - a Persistent handle. - - Note that the ClassCreator code which calls this has already - taken care of connecting nativeSelf to jsSelf. Client - specializations of this policy may opt to add their own - binding mechanisms, e.g. to allow CastToJS() to work. - - Clients should do any bindings-related cleanup in - Factory::Destruct() or Unwrap(), as appropriate for their - case. - - Ownership of the objects is unchanged by calling this. - - On error, this function may throw a native exception. If - that happens, ClassCreator will call - Unwrap(jsSelf,nativeHandle) and - Factory::Destruct(nativeSelf) to clean up, and will then - propagate the exception. - - The default implementation does nothing. - */ - static void Wrap( v8::Persistent const &, NativeHandle ) - { - return; - } - - /** - This is called from the ClassCreator-generated destructor, - just before the native destructor is called. If nativeSelf - is NULL then it means that native construction failed, - but implementations must (if necessary) clean up any data - stored in jsSelf by the PreWrap() function. - - Specializations may use this to clean up data stored in - other internal fields of the object (_not_ the field used - to hold the native itself - that is removed by the - framework). Optionally, such cleanup may be done in the - corresponding Factory::Destruct() routine, and must be done - there if the dtor will need access to such data. - - Note that when this is called, jsSelf and nativeSelf are - about to be destroyed, so do not do anything crazy with the - contents of jsSelf and DO NOT destroy nativeSelf (that is - the job of the ClassCreator_Factory policy). - - Ownership of the objects is unchanged by calling this. - - Unwrap() is called during destruction or when construction - fails (via a native exception), so any cleanup required for - the jsSelf object can be delegated to this function, as - opposed to being performed (and possibly duplicated) in - PreWrap() and/or Wrap(). - - The default implementation does nothing. - */ - static void Unwrap( v8::Handle const &, NativeHandle ) - { - return; - } - }; - - -#if 0 - namespace Detail - { - template - struct SharedType : public Context - { - private: - SharedType(){} - public: - static SharedType & Instance() - { - static SharedType bob; - return bob; - } - }; - } -#endif - /** - A basic Native-to-JS class binding mechanism. This class does - not aim to be a monster framework, just something simple, - mainly for purposes of showing (and testing) what the core - cvv8 can do. - - The framework must know how to convert JS objects to T objects, - and for this to work client code must define a JSToNative - specialization in this manner: - - @code - template <> - struct JSToNative - : JSToNative_ClassCreator - {}; - @endcode - - If the internal field configuration must be customized then the - client must define the number of fields by - specializing/customizing the ClassCreator_InternalFields - policy class. Additionally, if the client does NOT use the - above JSToNative implementation then he should create his - implementation by subclassing - JSToNative_ObjectWithInternalFields, where (N,M) are the - number of internals fields and the index of the field where the - native object is to be stored. See JSToNative_ClassCreator - for an example. - - TODOs: - - - Certain operations may not work properly when inheriting - bound classes from JS space, and possibly not even when - inheriting bound natives from one another. That depends on - several factors too complex to summarize here. - - - See how much of the v8::juice::cw::ClassWrap - inheritance-related code we can salvage for re-use here. - - - There are known problems when trying to bind inherited methods - when the parent class has no bound them to JS. i'm not sure how - i can fix the templates to get this working. - */ - template - class ClassCreator - { - private: - typedef ClassCreator_InternalFields InternalFields; - typedef ClassCreator_WeakWrap WeakWrap; - typedef ClassCreator_TypeID TypeID; - v8::Persistent ctorTmpl; - v8::Handle protoTmpl; - bool isSealed; - typedef ClassCreator_Factory Factory; - - - /** - A utility function primarily intended to support various - ClassCreator policy implementations. - - This function tries to extract a native handle from jo by - looking in the internal field defined by - ClassCreator_InternalFields::NativeIndex. If a native is - found in that field and it is the same as nh, then jo is - returned. If none is found, jo's prototype object is searched, - recursively, until either nh is found in the prototype chain or - the end of the chain is reached. If a match is found, the JS - object in which the native was found is returned. This does no - casting - it only compares by address. - - If nh is not found anywhere in the chain, an empty handle is - returned. - - Note that T must be non-cv qualified, so it is generally - undesirable to allow the compiler to deduce its type from the - parameter. Thus the T template parameter should not be omitted - from calls to this function. - */ - static v8::Handle FindHolder( v8::Handle const & jo, - T const * nh ) - { - if( !nh || jo.IsEmpty() ) return v8::Handle(); - v8::Handle proto(jo); - void const * ext = NULL; - typedef ClassCreator_SearchPrototypeForThis SPFT; - while( !ext && !proto.IsEmpty() && proto->IsObject() ) - { - v8::Local const & obj( v8::Object::Cast( *proto ) ); - ext = (obj->InternalFieldCount() != InternalFields::Count) - ? NULL - : obj->GetPointerFromInternalField( InternalFields::NativeIndex ); - // FIXME: if InternalFields::TypeIDIndex>=0 then also do a check on that one. - /* - If !ext, there is no bound pointer. If (ext && - (ext!=nh)) then there is one, but it's not the droid - we're looking for. In either case, (possibly) check the - prototype... - */ - if( ext == nh ) return obj; - else if( !SPFT::Value ) break; - else proto = obj->GetPrototype(); - } - return v8::Handle(); - } - - static void weak_dtor( v8::Persistent< v8::Value > pv, void *nobj ) - { - using namespace v8; - //std::cerr << "Entering weak_dtor<>(native="<<(void const *)nobj<<")\n"; - Local jobj( Object::Cast(*pv) ); - typedef typename JSToNative::ResultType NT; - NT native = CastFromJS( pv ); - if( !native ) - { - /* see: http://code.google.com/p/v8-juice/issues/detail?id=27 - - When i call pv.Dispose(), this function is getting called twice, - and the second time won't work. i'm going to igore (return w/o - side-effects) this for now for the sake of avoiding a crash - which i'm seeing only on 64-bit platforms. - - However, even if i return here, v8 is crashing with a - !NEAR_DEATH assertion right after the second call is made. - - The extra pair of Dispose()/Clear() calls seems to eliminate that - crash, but the fact that this code block is hit AT ALL is a - sign of a problem - the dtor shouldn't be called twice! - */ - pv.Dispose(); - pv.Clear(); -#if 1 /* i believe this problem was fixed. If you are reading this b/c - you followed an assert() message, please report this as a bug. - */ - assert( 0 && "weak_dtor() got no native object!"); -#endif - return; - } - else - { - /** - Reminder: the FindHolder() bits are here to - assist when the bound native exists somewhere in the - prototype chain other than jobj itself. In that case, - jobj is valid but we cannot clear out the native handle - internal field on it because it has no internal fields - (or none that belong to us). - - To fix this properly we have to be able to know - _exactly_ which JS object in the prototype chain nh is - bound to. - */ - v8::Handle nholder = FindHolder( jobj, native ); -#if 1 /* reminder: i've never actually seen this error happen, i'm just pedantic about checking... */ - assert( ! nholder.IsEmpty() ); - WeakWrap::Unwrap( nholder /*jobj? subtle difference!*/, native ); - if( nholder.IsEmpty() || (nholder->InternalFieldCount() != InternalFields::Count) ) - { - StringBuffer msg; - msg << "SERIOUS INTERNAL ERROR:\n" - << "ClassCreator::weak_dtor() " - << "validated that the JS/Native belong together, but " - << "FindHolder() returned an " - << (nholder.IsEmpty() ? "empty" : "invalid") - << " handle!\n" - << "From JS=@"<<(void const *)nobj - << ", Converted to Native=@"<<(void const *)native - << ", nholder field count="<InternalFieldCount() - << ", jobj field count="<InternalFieldCount() - << "\nTHIS MAY LEAD TO A CRASH IF THIS JS HANDLE IS USED AGAIN!!!\n" - ; - Factory::Delete(native); - pv.Dispose(); pv.Clear(); /* see comments below!*/ - v8::ThrowException(msg.toError()); - return; - } - else - { - nholder->SetInternalField( InternalFields::NativeIndex, Null() ); - if( 0 <= InternalFields::TypeIDIndex ) - { - nholder->SetInternalField( InternalFields::TypeIDIndex, Null() ); - } - Factory::Delete(native); - } -#else - WeakWrap::Unwrap( nholder, native ); - nholder->SetInternalField( InternalFields::NativeIndex, Null() ); - if( 0 <= InternalFields::TypeIDIndex ) - { - nholder->SetInternalField( InternalFields::TypeIDIndex, Null() ); - } - Factory::Delete(native); -#endif - } - /* - According to the v8 gurus i need to call pv.Dispose() - instead of pv.Clear(), but if i do then this dtor is - being called twice. If i don't call it, v8 is crashing - sometime after this function with a !NEAR_DEATH - assertion. - */ - pv.Dispose(); - pv.Clear(); - } - - /** - Gets installed as the NewInstance() handler for T. - */ - static v8::Handle ctor_proxy( v8::Arguments const & argv ) - { - using namespace v8; - if(ClassCreator_AllowCtorWithoutNew::Value) - { - /** - Allow construction without 'new' by forcing this - function to be called in a ctor context... - */ - if (!argv.IsConstructCall()) - { - const int argc = argv.Length(); - Handle ctor( Function::Cast(*argv.Callee())); - std::vector< Handle > av(static_cast(argc),Undefined()); - for( int i = 0; i < argc; ++i ) av[i] = argv[i]; - return ctor->NewInstance( argc, &av[0] ); - } - } - else - { - /** - Why have this limitation? If we don't, v8 pukes - when the ctor is called, with - "v8::Object::SetInternalField() Writing internal - field out of bounds". - */ - if (!argv.IsConstructCall()) - { - return Toss("This constructor cannot be called as function!"); - } - } - Local const & jobj( argv.This() - /*CastToJS(*nobj) - - We are not yet far enough - along in the binding that - CastToJS() can work. And it - can't work for the generic - case, anyway. - */); - if( jobj.IsEmpty() ) return jobj /* assume exception*/; - Persistent self( Persistent::New(jobj) ); - T * nobj = NULL; - try - { - WeakWrap::PreWrap( self, argv ); - nobj = Factory::Create( self, argv ); - if( ! nobj ) - { - return CastToJS(std::runtime_error("Native constructor failed.")); - } - WeakWrap::Wrap( self, nobj ); - self.MakeWeak( nobj, weak_dtor ); - if( 0 <= InternalFields::TypeIDIndex ) - { - self->SetPointerInInternalField( InternalFields::TypeIDIndex, (void *)TypeID::Value ); - } - self->SetPointerInInternalField( InternalFields::NativeIndex, nobj ) - /* We do this after the call to Wrap() just in case the Wrap() impl - accidentally writes to this field. In that case we end up - losing the data they stored there. So this is just as evil as - adding the internal field before Wrap(), but only when the - client mis-uses the internal fields. - */ - ; - } - catch(std::exception const &ex) - { - WeakWrap::Unwrap( self, nobj ); - if( nobj ) Factory::Delete( nobj ); - self.Clear(); - return Toss(CastToJS(ex)); - } - catch(...) - { - WeakWrap::Unwrap( self, nobj ); - if( nobj ) Factory::Delete( nobj ); - self.Clear(); - return Toss("Native constructor threw an unknown exception!"); - } - return self; - } - - ClassCreator() - : ctorTmpl(v8::Persistent::New( v8::FunctionTemplate::New(ctor_proxy) )), - protoTmpl(v8::Persistent::New( ctorTmpl->PrototypeTemplate() )), - isSealed(false) - { - ctorTmpl->InstanceTemplate()->SetInternalFieldCount(InternalFields::Count); - } - public: - /** - The native type being bound to JS. - */ - typedef typename tmp::PlainType::Type Type; - - /** - Returns the shared instance of this class. - */ - static ClassCreator & Instance() - { - static ClassCreator bob; - return bob; - } - - /** - Returns this class' prototype object. - */ - inline v8::Handle Prototype() - { - return this->protoTmpl; - } - - /** - Returns this class' constructor template object. - */ - inline v8::Handle CtorTemplate() - { - return this->ctorTmpl; - } - - /** - Returns this class' constructor template. - - ACHTUNG: after this is called, changes made to the Prototype() - object might not have any effect. Thus this should only be - called after the prototype object has been fully set up. - (i have no idea why v8 behaves this way.) - - After calling this, IsSealed() will return true. - */ - inline v8::Handle CtorFunction() - { - // In my experience, if GetFunction() is called BEFORE setting up - // the Prototype object, v8 gets very unhappy (class member lookups don't work?). - this->isSealed = true; - return this->ctorTmpl->GetFunction(); - } - - /** - Returns true if CtorFunction() has been called. See that - function for why. - */ - inline bool IsSealed() const - { - return this->isSealed; - } - - /** - Creates a new instanced of the object via the JS API. It calls - ClassCreator_Factory::Create(), passing it argv, to - instantiate the object. On success a JS handle to the object is - returned (it is owned by v8), and the caller can get the native - pointer with: - - @code - T * t = CastFromJS(theHandle); - @endcode - */ - inline v8::Handle NewInstance( int argc, v8::Handle argv[] ) - { - return this->CtorFunction()->NewInstance(argc, argv); - } - - /** - A convenience form of NewInstance() which returns the JS version - of the object and assigns tgt to the native pointer (which will - be NULL on error). - - If tgt is NULL when this function returns, or - returnedObj.IsEmpty(), then we assume that a v8 exception is - propagating, and the caller should return to v8 as soon as - possible so the exception can be triggered JS-side (it is not - actually triggered until we return to v8). - - The returned object is owned by v8. - */ - v8::Handle NewInstance( int argc, v8::Handle argv[], T * & tgt ) - { - v8::Handle const & obj( this->CtorFunction()->NewInstance(argc, argv) ); - if( obj.IsEmpty() ) return obj /* assume exception is propagating. */; - else - { - tgt = CastFromJS(obj); - if( !tgt ) { - Toss(StringBuffer()<<"Internal error: NewInstance() returned a non-empty " - << "Handle but CastFromJS<"<::Value<<">() failed. " - << "This is either a serious cvv8 bug or the JSToNative specialization " - << "is not working properly."); - return v8::Handle(); - } - else return obj; - } - } - - /** - Convenience method to add the given property to the - prototype. Returns this object, for call chaining. - - CastToJS(val) must be valid or a compile-time - error will be triggered. - */ - template - inline ClassCreator & Set( char const * name, ValueT val ) - { - this->protoTmpl->Set(v8::String::New(name), CastToJS(val)); - return *this; - } - //! Not quite sure why i need this overload, but i do. - inline ClassCreator & Set( char const * name, v8::InvocationCallback val ) - { - this->protoTmpl->Set(v8::String::New(name), CastToJS(val)); - return *this; - } - /** - Equivalent to Set(). - */ - template - inline ClassCreator & operator()( char const * name, ValueT val ) - { - return this->Set(name, val); - } - /** - Overload to avoid an ambiguity. - */ - inline ClassCreator & operator()( char const * name, v8::InvocationCallback val ) - { - return this->Set(name, val); - } - - /** - Adds CtorFunction() to dest using the given property name. - This implicitly "seals" the class (see CtorFunction() for - details). - */ - inline void AddClassTo( char const * thisClassName, v8::Handle const & dest ) - { - dest->Set(v8::String::New(thisClassName), - this->CtorFunction()); - } - - /** - Destroys the given object by disconnecting its associated - native object and calling the native destructor function - for it. - - If jo cannot be converted to a T then false is - returned. Otherwise the true is returned and the native - object referenced by jo is no longer valid (it should not - be used by JS code). - - Native functions bound to that object should take care to - bail out with an exception once the native pointer is gone, - as opposed to blindly stepping on its null/dangling pointer - (which _might_ have been re-allocated to a different - object, even of a different type, in the mean time). - */ - static bool DestroyObject( v8::Handle const & jo ) - { - T * t = CastFromJS(jo); - if( ! t ) return false; - else - { - v8::Persistent p( v8::Persistent::New( jo ) ); - p.ClearWeak(); // avoid a second call to weak_dtor() via gc! - weak_dtor( p, t ); - return true; - } - } - /** - If jv is empty or !jv->IsObject() then false is returned, - otherwise it returns the result of - DestroyObject(Handle). - */ - static bool DestroyObject( v8::Handle const & jv ) - { - return (jv.IsEmpty() || !jv->IsObject()) - ? false - : DestroyObject( v8::Handle( v8::Object::Cast(*jv) ) ); - } - - /** - A v8::InvocationCallback implementation which calls - DestroyObject( argv.This() ). - - It is intended to be used as a "manual destructor" for - classes which need it. The canonical examples are - Stream.close() and Database.close(). - - This function is not called DestroyObject to avoid name - collisions during binding using Set(...,DestroyObjectCallback). - */ - static v8::Handle DestroyObjectCallback( v8::Arguments const & argv ) - { - return DestroyObject(argv.This()) ? v8::True() : v8::False(); - } - - /** - Tells v8 that this bound type inherits ParentType. - ParentType _must_ be a class wrapped by ClassCreator. - This function throws if - ClassCreator::Instance().IsSealed() returns - false). We require that the parent class be sealed to - avoid accidental mis-use caused by registering a - subclass of a class which has not yet been bound (and may - may never be bound). - */ - template - void Inherit() - { - typedef ClassCreator PT; - PT & p(PT::Instance()); - if( ! p.IsSealed() ) - { - throw std::runtime_error("ClassCreator has not been sealed yet!"); - } - this->CtorTemplate()->Inherit( p.CtorTemplate() ); - } - - /** - Simply runs ClassCreator_SetupBindings::Initialize( target ). - It is provided here to simplify the client-side interface. - */ - static void SetupBindings( v8::Handle const & target ) - { - ClassCreator_SetupBindings::Initialize( target ); - } - - }; - - /** - Intended to be the base class for JSToNative specializations - when T is JS-bound using ClassCreator. - - This particular implementation must be defined _after_ - any of the following policies are customized for T: - - - ClassCreator_InternalFields - - ClassCreator_SearchPrototypeForThis - - ClassCreator_TypeID (only if TypeSafe is true!) - - If the client will not specialize those types type then the order is - irrelevant, but when specializing any of them, they must come before - this JSToNative implementation is instantiated. - - If TypeSafe is true then this type is a proxy for - JSToNative_ObjectWithInternalFieldsTypeSafe, else it is a proxy for - JSToNative_ObjectWithInternalFields. Note that ClassCreator is - hard-wired to implant/deplant type id information if - ClassCreator_InternalFields::TypeIDIndex is not negative, with the - _hope_ that JSToNative will use it, but it does not enforce that - the type ID is used. For types where the internal fields' TypeIDIndex - is negative, ClassCreator will not set up bits for the type check, - which means a slightly smaller runtime memory footprint. - */ - template ::TypeIDIndex >= 0 > - struct JSToNative_ClassCreator : - tmp::IfElse< TypeSafe, - JSToNative_ObjectWithInternalFieldsTypeSafe::Value, - ClassCreator_InternalFields::Count, - ClassCreator_InternalFields::TypeIDIndex, - ClassCreator_InternalFields::NativeIndex, - ClassCreator_SearchPrototypeForThis::Value - >, - JSToNative_ObjectWithInternalFields::Count, - ClassCreator_InternalFields::NativeIndex, - ClassCreator_SearchPrototypeForThis::Value - > - >::Type - { - }; - -#if 0 - //! Experimental. - template - struct JSToNative_ClassCreator_Subclass - { - typedef typename TypeInfo::NativeHandle ResultType; - ResultType operator()( v8::Handle const & h ) const - { - typedef typename TypeInfo::NativeHandle PTP; - PTP typeCheck; typeCheck = (ResultType)NULL - /* If compiler errors led you here then SubT probably does not - publicly subclass ParentT. */ - ; - PTP p = CastFromJS(h); - //std::cerr << "dyncast="<(p)<<"\n"; - return p ? dynamic_cast(p) : NULL; - } - }; -#endif - -#if !defined(DOXYGEN) - namespace Detail - { - /** - A base class for ClassCreator_Factory_CtorArityDispatcher. - We don't really need this level of indirection, i think. - */ - template - struct Factory_CtorForwarder_Base - { - typedef typename TypeInfo::Type Type; - typedef typename TypeInfo::NativeHandle NativeHandle; - static void Delete( NativeHandle nself ) - { - delete nself; - } - protected: - /** - If argv.Length() >= Arity then this function ignores errmsg and - returns true, otherwise it writes a descriptive error message - to errmsg and return false. - */ - static bool argv_check( v8::Arguments const & argv, int Arity ) - { - if( argv.Length() >= Arity ) return true; - else - { - StringBuffer msg; - msg << "constructor requires " << Arity << " arguments!"; - throw std::range_error(msg.Content().c_str()); - return false; - } - } - }; - } -#endif // !DOXYGEN - - /** - Can be used as a concrete ClassCreator_Factor - specialization to forward JS ctor calls directly to native - ctors. - - T must be the ClassCreator'd type to construct. CtorProxy must - be a type having this interface: - - @code - TypeInfo::NativeHandle Call( v8::Arguments const & ); - @endcode - - Normally CtorProxy would be CtorForwarder or CtorArityDispatcher, - but any interface-compatible type will do. - - It must return a new object instance on success. On error it - may return NULL and "should" throw a native exception explaining - the problem. The exception will be caught by ClassCreator and - transformed into a JS-side exception. - - If CtorProxy::Call() succeeds (returns non-NULL and does not throw) - then NativeToJSMap is used to create a native-to-JS mapping. - To make use of this, the client should do the following: - - @code - // in the cvv8 namespace: - template <> - struct NativeToJS : NativeToJSMap::NativeToJSImpl {}; - @endcode - - After that, CastToJS( theNativeObject ) can work. - - The mapping is cleaned up when (if!) the object is sent through - the JS garbage collector or the client somehow triggers its - JS-aware destruction (e.g. via ClassCreator::DestroyObject(), - assuming the type was wrapped using ClassCreator). - */ - template - struct ClassCreator_Factory_NativeToJSMap : Detail::Factory_CtorForwarder_Base - { - public: - typedef NativeToJSMap N2JMap; - typedef typename TypeInfo::Type Type; - typedef typename TypeInfo::NativeHandle NativeHandle; - - /** - If CtorProxy::Call(argv) succeeds, N2JMap::Insert(jself, theNative) - is called. The result of CtorProxy::Call() is returned. - */ - static NativeHandle Create( v8::Persistent jself, v8::Arguments const & argv ) - { - NativeHandle n = CtorProxy::Call( argv ); - if( n ) N2JMap::Insert( jself, n ); - return n; - } - /** - Calls N2JMap::Remove( nself ) then (delete nself). - */ - static void Delete( NativeHandle nself ) - { - N2JMap::Remove( nself ); - delete nself; - } - }; - - /** @deprecated Use ClassCreator_Factory_Dispatcher instead (same interface). - */ - template - struct ClassCreator_Factory_CtorArityDispatcher : Detail::Factory_CtorForwarder_Base - { - public: - typedef typename TypeInfo::Type Type; - typedef typename TypeInfo::NativeHandle NativeHandle; - static NativeHandle Create( v8::Persistent , v8::Arguments const & argv ) - { - typedef CtorArityDispatcher Proxy; - return Proxy::Call( argv ); - } - }; - - /** - A ClassCreator_Factory implementation which forwards its Create() - member to CtorT::Call() (the interface used by CtorForwarder and friends). - - T must (or is assumed to) be a ClassCreator-wrapped class. - CtorForwarderList must be a Signature typelist of CtorForwarder - types and its "return type" must be T (optionally pointer-qualified). - - Example: - - @code - typedef CtorForwarder C0; - typedef CtorForwarder C1; - typedef CtorForwarder C2; - typedef Signature< CFT (C0, C1, C2) > CtorList; - - // Then create Factory specialization based on those: - template <> - struct ClassCreator_Factory : - ClassCreator_Factory_Dispatcher > {}; - @endcode - - Or: - - @code - template <> - struct ClassCreator_Factory : - ClassCreator_Factory_Dispatcher< MyType, CtorForwarder > - {}; - @endcode - */ - template - struct ClassCreator_Factory_Dispatcher : Detail::Factory_CtorForwarder_Base - { - public: - typedef typename TypeInfo::Type Type; - typedef typename TypeInfo::NativeHandle NativeHandle; - static NativeHandle Create( v8::Persistent jself, v8::Arguments const & argv ) - { - return CtorT::Call( argv ); - } - }; - - -}// namespaces - -#endif /* CODE_GOOGLE_COM_P_V8_CONVERT_CLASS_CREATOR_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/Makefile b/vendor/libv8-convert/cvv8/Makefile deleted file mode 100644 index 552c1ebd4..000000000 --- a/vendor/libv8-convert/cvv8/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: - -EXAMPLE_DIR := ../../examples -ifneq (,$(wildcard $(EXAMPLE_DIR)/Makefile)) -$(sort all $(MAKECMDGOALS)): - $(MAKE) -C ../../examples $@ -endif - diff --git a/vendor/libv8-convert/cvv8/NativeToJSMap.hpp b/vendor/libv8-convert/cvv8/NativeToJSMap.hpp deleted file mode 100644 index 1e09da7bd..000000000 --- a/vendor/libv8-convert/cvv8/NativeToJSMap.hpp +++ /dev/null @@ -1,183 +0,0 @@ -#if ! defined(V8_CONVERT_NATIVE_JS_MAPPER_HPP_INCLUDED) -#define V8_CONVERT_NATIVE_JS_MAPPER_HPP_INCLUDED - -#include "detail/convert_core.hpp" -namespace cvv8 { - /** - A helper class to assist in the "two-way-binding" of - natives to JS objects. This class holds native-to-JS - binding information. - - In the general case, a native-to-JS conversion is only - needed at the framework-level if bound/converted - functions/methods will _return_ bound native - pointers/references. If they only return "core" types (numbers - and strings, basically), or explicitly return v8-supported - types (e.g. v8::Handle) then no native-to-JS - conversion is typically needed. - - Known limitations: - - This type does not fully support subclass conversions. - e.g. the following function binding: - - @code - virtual MyType * (MyType::*)(); - @endcode - - _should_ be able to return a MySubType from derived implementations - but it currently cannot. Handling this requires that a parent class - be told each of its subclasses, and that we add internal handlers - which try lookups on those classes if a conversion to MyType fails. - - Reminder to self: the v8::juice tree has an example of that which we - can probably plunder. - */ - template - struct NativeToJSMap - { - private: - typedef TypeInfo TI; - typedef typename TI::Type Type; - /** - The native type to bind to. - */ - typedef typename TI::NativeHandle NativeHandle; - /** The type for holding the JS 'this' object. */ - typedef v8::Persistent JSObjHandle; - //typedef v8::Handle JSObjHandle; // Hmmm. - typedef std::pair ObjBindT; - typedef std::map OneOfUsT; - /** Maps (void const *) to ObjBindT. - - Reminder to self: we might need to make this map a static - non-function member to work around linking problems (at - least on Windows) which lead to multiple instances of - the returned map being created when the types being - bound are loaded from multiple DLLs. The out-of-class - initialization of the member is going to require a really - ugly set of template parameters, though. - */ - static OneOfUsT & Map() - { - static OneOfUsT bob; - return bob; - } - public: - /** Maps obj as a lookup key for jself. Returns false if !obj, - else true. */ - static bool Insert( JSObjHandle const & jself, - NativeHandle obj ) - { - return obj - ? (Map().insert( std::make_pair( obj, std::make_pair( obj, jself ) ) ),true) - : 0; - } - - /** - Removes any mapping of the given key. Returns the - mapped native, or 0 if none is found. - */ - static NativeHandle Remove( void const * key ) - { - typedef typename OneOfUsT::iterator Iterator; - OneOfUsT & map( Map() ); - Iterator it = map.find( key ); - if( map.end() == it ) - { - return 0; - } - else - { - NativeHandle victim = (*it).second.first; - map.erase(it); - return victim; - } - } - - /** - Returns the native associated (via Insert()) - with key, or 0 if none is found. - */ - static NativeHandle GetNative( void const * key ) - { - if( ! key ) return 0; - else - { - typename OneOfUsT::iterator it = Map().find(key); - return (Map().end() == it) - ? 0 - : (*it).second.first; - } - } - - /** - Returns the JS object associated with key, or - an empty handle if !key or no object is found. - */ - static v8::Handle GetJSObject( void const * key ) - { - if( ! key ) return v8::Handle(); - typename OneOfUsT::const_iterator it = Map().find(key); - if( Map().end() == it ) return v8::Handle(); - else return (*it).second.second; - } - - /** - A base NativeToJS implementation for classes which use NativeToJSMap - to hold their native-to-JS bindings. To be used like this: - - @code - // must be in the v8::convert namespace! - template <> - struct NativeToJS : NativeToJSMap::NativeToJSImpl {}; - @endcode - */ - struct NativeToJSImpl - { - v8::Handle operator()( Type const * n ) const - { - typedef NativeToJSMap BM; - v8::Handle const & rc( BM::GetJSObject(n) ); - if( rc.IsEmpty() ) return v8::Null(); - else return rc; - } - v8::Handle operator()( Type const & n ) const - { - return this->operator()( &n ); - } - }; - -#if 0 - //! Experimental - template - struct NativeToJSImpl_Subclass - { - v8::Handle operator()( Type const * n ) const - { - typedef NativeToJSMap BM; - v8::Handle const & rc( BM::GetJSObject(n) ); - if( rc.IsEmpty() ) - { - typedef typename NativeToJSMap::NativeToJSImpl PI; - return PI()(n); -#if 0 - typedef typename TypeInfo::NativeHandle PH; - rc = CastToJS(n); - if( rc.IsEmpty() ) return v8::Null(); - else return rc; -#endif - } - else return rc; - } - v8::Handle operator()( Type const & n ) const - { - return this->operator()( &n ); - } - }; -#endif - }; - -} // namespaces - -#endif /* include guard */ diff --git a/vendor/libv8-convert/cvv8/V8Shell.hpp b/vendor/libv8-convert/cvv8/V8Shell.hpp deleted file mode 100644 index ecfb9aa3a..000000000 --- a/vendor/libv8-convert/cvv8/V8Shell.hpp +++ /dev/null @@ -1,650 +0,0 @@ -#if !defined(V8_CONVERT_V8Shell_HPP_INCLUDED) -#define V8_CONVERT_V8Shell_HPP_INCLUDED -/** @file V8Shell.hpp - - This file contains the v8::convert::V8Shell class, a convenience - wrapper for bootstrapping integration of v8 into arbitrary - client applications. - - Dependencies: v8 and the STL. - - License: released into the Public Domain by its author, - Stephan Beal (http://wanderinghorse.net/home/stephan/). -*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace cvv8 { - namespace Detail { - template - struct V8MaybeLocker - { - private: - v8::Locker lock; - public: - V8MaybeLocker() : lock() {} - }; - template <> - struct V8MaybeLocker - { - }; - } - /** - This class implements a very basic shell for v8. - - - These objects are basically thin wrappers around the - bootstrap code necessary for getting v8 running in an - application. They are intended to be stack-created in main() - (or equivalent) and used as a front-end for passing JS code - into v8 for execution. - - Because library-level JS code activated via this class - _might_ use v8::Unlocker to unlock the VM while C-level - routines are running, each instance of this class includes a - v8::Locker instance if UseLocker is true. (If it did not, - clients would be required to add one or accept crashes when - called code uses v8::Unlocker.) Only set UseLocker to false - if you _know_ that _no_ JS code run through this API will - end up trying to unlock v8. (If you're using this class - together with the v8::convert function binding API then you - are almost certainly using v8::Unlocker without realizing it.) - - Maintenance reminder: keep this class free of dependencies - on other library-level code so that we can re-use it - in arbitrary v8 clients. - - FIXME: the way this class uses v8::TryCatch is "all wrong", and any - functions using it need to be revisited. - */ - template - class V8Shell - { - public: - /** - A callback function signature for reporing JS-side - exception messages to the native world. - - TODO: consider passing a v8::Handle argument - instead of a (char const *) and possibly a (void *) State - handle for use by the client. - */ - typedef void (*ErrorMessageReporter)( char const * msg ); - private: - // The declaration order of the v8-related objects is important! - Detail::V8MaybeLocker locker; - v8::HandleScope hscope; - //v8::Handle globt; - v8::Handle context; - v8::Context::Scope cxscope; - v8::Handle global; - /** - tryCatch is only here until i can track down a post-main() - v8 assertion which happens when V8Shell-executed JS code - exits with an exception. It is just a workaround. - */ - v8::TryCatch tryCatch; - ErrorMessageReporter reporter; - static void DefaultErrorMessageReporter( char const * msg ) - { - if( msg && *msg ) std::cerr - //<< "[V8Shell default exception reporter says:]\n" - << msg << std::endl; - } - - /** - An v8::InvocationCallback implementation which implements a - JS-conventional print() routine. OS must be a pointer to - an ostream, e.g. std::cout or std::cerr. - - Each argument is converted to a string (using - v8::String::Utf8Value) and is output, separated by a - space. For compatibility with other toolkits' print() - implementations (some of which only accept one - argument), it is recommended that client script code - only rely on the first argument being output. - - Always returns v8::Undefined(). - - It is a little-known fact that one can replace the output - buffer used by std::cout (and other std::ostreams) with a - custom one, such that calling print() from JS code will - redirect the output to a different destination. This can - be used, e.g., to redirect std::cout to a libcurses window. - */ - template - static v8::Handle PrintToStdOstream( v8::Arguments const & argv ) - { - v8::HandleScope hscope; - int const argc = argv.Length(); - const char * cstr = NULL; - for (int i = 0; i < argc; i++) - { - if( 0 != i ) *OS << ' '; - v8::String::Utf8Value const str(argv[i]); - cstr = *str; - if( cstr ) *OS << cstr; - } - *OS << '\n'; - OS->flush(); - return v8::Undefined(); - } - - void init( char const * globalObjectName, - int argc, char const * const * argv, - unsigned short argOffset ) - { - if( globalObjectName && *globalObjectName ) - { - this->global->Set( v8::String::New(globalObjectName), this->global ); - } - if( (0 < argc) && (NULL != argv) ) - { - this->ProcessMainArgv( argc, argv, argOffset ); - } - } - - static void SetupTryCatch( v8::TryCatch & tc ) - { - tc.SetVerbose(true); - tc.SetCaptureMessage(true); - } - public: - /** - Initialize a v8 context and global object belonging to this object. - - If globalObjectName is not null and not empty then the global object - is given a refernce to itself using the given name, such that client - JS code can then refer to it. - - If argc is greater than 0 and argv is not NULL then argv is - assumed to be an arguments list in the format conventional - for main() and ProcessMainArgv(argc,argv,argOffset) is called. - */ - V8Shell( char const * globalObjectName = NULL, - int argc = 0, char const * const * argv = NULL, - unsigned short argOffset = 1 ) : - locker(), - hscope(), - //globt( v8::ObjectTemplate::New() ), - context( v8::Context::New(NULL, v8::ObjectTemplate::New()) ), - cxscope(context), - global( context->Global() ), - reporter( DefaultErrorMessageReporter ) - { - this->init( globalObjectName, argc, argv, argOffset ); - } - - /** - Destructs all v8 resources used by this object, e.g. the JS context. - */ - ~V8Shell() - { - if( ! v8::V8::IsDead() ) { - tryCatch.Reset(); - } - } - - /** - Sets the error reporter function used by - ExecuteString(). Passing 0 will disable exception - reporting. The default reporter sends its output to - std::cerr. - */ - void SetExecuteErrorReporter( ErrorMessageReporter r ) - { - this->reporter = r; - } - - /** - Outputs an exception message using the current - error reporter function. - - If try_catch or the current error reporter are - null then nothing is done. - - @see SetExecuteErrorReporter(). - */ - - void ReportException(v8::TryCatch* try_catch) - { - if( !try_catch || ! this->reporter ) return; - v8::HandleScope hsc; - v8::String::Utf8Value const excUtf(try_catch->Exception()); -#define TOCSTR(X) (*X ? *X : "") - const char* excCstr = TOCSTR(excUtf); - v8::Handle const & message( try_catch->Message() ); - std::ostringstream os; - os << "V8Shell Exception Reporter: "; - if (message.IsEmpty()) - { - // V8 didn't provide any extra information about this error; just - // print the exception. - os << excCstr << '\n'; - } - else - { - // output (filename):(line number): (message)... - int linenum = message->GetLineNumber(); - os << *v8::String::Utf8Value(message->GetScriptResourceName()) << ':' - << std::dec << linenum << ": " - << excCstr << '\n'; - // output source code line... - os << *v8::String::AsciiValue(message->GetSourceLine()) << '\n'; - // output decoration pointing to error location... - int start = message->GetStartColumn(); - for (int i = 0; i < start; i++) { - os << '-'; - } - int end = message->GetEndColumn(); - for (int i = start; i < end; i++) { - os << '^'; - } - os << '\n'; - } - std::string const & str( os.str() ); - this->reporter( str.c_str() ); -#undef TOCSTR - } - - /** - Adds the given function to the global object. - - Returns this object. - */ - V8Shell & operator()( char const * name, v8::Handle const & f ) - { - this->global->Set( v8::String::New(name), f ); - return *this; - } - - /** - Adds the given function to the global object. - - Returns this object. - */ - V8Shell & operator()( char const * name, v8::Handle const & f ) - { - return this->operator()( name, f->GetFunction() ); - } - - /** - Adds the given function to the global object. - - Returns this object. - */ - V8Shell & operator()( char const * name, v8::InvocationCallback const f ) - { - return this->operator()( name, v8::FunctionTemplate::New(f) ); - } - - /** - Returns the global object for this shell. - */ - v8::Handle Global() - { - return this->global; - } - - /** - Returns the context object for this shell. - */ - v8::Handle Context() - { - return this->context; - } - -#if 0 // changes made to global ObjectTemplate have no effect after cx is set up. - v8::Handle GlobalTemplate() - { - return this->globt; - } -#endif - - /** - Intended to be called from main() and passed the argc/argv - which are passed to main. offset is the number of arguments - to skip, and defaults to one to skip the argv[0] argument, - which is conventionally the application name. - - It skips all arguments up to "--". For each argument after - "--", it adds the argument to a list. At the end of the - list, the global object is assigned a property named - "arguments" which contains that list. - - If the argument list has no arguments after a "--" entry - then the "arguments" global value will be an empty array, - as opposed to null or undefined. - - This function does no interpretation of the arguments. - */ - V8Shell & ProcessMainArgv( int argc, char const * const * _argv, unsigned short offset = 1 ) - { - if( (argc<1) || !_argv ) return *this; - char const * endofargs = "--"; - v8::Handle argv( v8::Array::New() ); - int i = (int)offset; - for( ; i < argc; ++i ) - { - if( 0 == strcmp(_argv[i],endofargs) ) - { - ++i; - break; - } - } - int ndx = 0; - for( ; i < argc; ++i ) - { - char const * arg = _argv[i]; - if( arg ) - { // String::New() calls strlen(), which hates NULL - argv->Set( ndx++, v8::String::New(arg) ); - } - } - this->global->Set( v8::String::New("arguments"), argv ); - return *this; - } - - /** - Executes the given source string in the current - context. - - If the script throws an exception then a TryCatch object is used - to build an error string, which is passed to this object's error - reporter function. The default sends the output to std::cerr. - - If resultGoesTo is not null and the result a valid handle, then - the result is converted to a string and sent to that stream. - - Returns the result of the last expression evaluated in the script, - or an empty handle on error. - */ - v8::Handle ExecuteString(v8::Handle const & source, - v8::Handle name, - std::ostream * out = NULL ) - { - //this->executeThrew = false; - v8::HandleScope scope; - v8::TryCatch tc; - SetupTryCatch(tc); - v8::Handle script = v8::Script::Compile(source, name); - if( script.IsEmpty())//tc.HasCaught()) - { - // Report errors that happened during compilation. - //this->executeThrew = true; - this->ReportException(&tc); - return scope.Close(tc.ReThrow()); - //return v8::Handle(); - } - else - { - v8::Handle const & result( script->Run() ); - if( tc.HasCaught())//(result.IsEmpty()) - { - //this->executeThrew = true; - this->ReportException(&tc); - //return v8::Handle(); - return scope.Close(tc.ReThrow()); - } - else - { - if (out && !result.IsEmpty()) - { - (*out) << *v8::String::Utf8Value(result) << '\n'; - } - return scope.Close(result); - } - } - } - -#if 0 - bool ExecThrewException() const - { - return this->executeThrew; - } -#endif - - /** - Convenience form of ExecuteString(source,"some default name", reportExceptions, 0). - */ - v8::Handle ExecuteString(std::string const & source, - std::string const & name, - std::ostream * resultGoesTo ) - { - v8::HandleScope scope; - v8::Local const & s( v8::String::New( source.c_str(), static_cast(source.size()) ) ); - v8::Local const & n( v8::String::New( name.c_str(), static_cast(name.size()) ) ); - return scope.Close(this->ExecuteString( s, n, resultGoesTo )); - } - - /** - Convenience overload taking input from a native string. - */ - v8::Handle ExecuteString(std::string const & source ) - { - return this->ExecuteString(source, "ExecuteString()", 0); - } - - /** - Convenience form of ExecuteString(source,"some default name", 0, reportExceptions). - */ - v8::Handle ExecuteString(v8::Handle source ) - { - return this->ExecuteString(source, v8::String::New("ExecuteString()"), 0); - } - - /** - Convenience form of ExecuteString() reading from an opened input stream. - - Throws a std::exception if reading fails or the input is empty. - - An empty input is not necessarily an error. Todo: re-think this decision. - */ - v8::Handle ExecuteStream( std::istream & is, std::string const & name, - std::ostream * resultGoesTo = NULL ) - { - std::ostringstream os; - is >> std::noskipws; - std::copy( std::istream_iterator(is), std::istream_iterator(), std::ostream_iterator(os) ); - std::string const & str( os.str() ); - if( str.empty() ) - { - std::ostringstream msg; - msg << "Input stream ["<ExecuteString( str, name, resultGoesTo ); - } - - /** - Convenience form of ExecuteString() reading from a local file. - */ - v8::Handle ExecuteFile( char const * filename, - std::ostream * resultGoesTo = NULL ) - { - if( ! filename || !*filename ) - { - throw std::runtime_error("filename argument must not be NULL/empty."); - } - std::ifstream inf(filename); - if( ! inf.good() ) - { - // FIXME: throw a v8 exception and report it via our reporter. - // Nevermind: the result is useless b/c the exception has no proper vm stack/state info here... - std::ostringstream msg; - msg << "Could not open file ["<ExecuteStream( inf, filename, resultGoesTo ); - } - - /** - An v8::InvocationCallback implementation which implements - a JS-conventional print() routine, sending its output to - std::cout. See PrintToStdOstream() for the exact semantics - argument/return. - */ - static v8::Handle PrintToCout( v8::Arguments const & argv ) - { - return PrintToStdOstream<&std::cout>( argv ); - } - - /** - Identical to PrintToCout(), but sends its output to - std::cerr instead. - */ - static v8::Handle PrintToCerr( v8::Arguments const & argv ) - { - return PrintToStdOstream<&std::cerr>( argv ); - } - - private: - static v8::Handle Include( v8::Arguments const & argv ) - { - int const argc = argv.Length(); - if( argc < 1 ) return v8::Undefined(); - v8::HandleScope hsc; - v8::Local const jvself(argv.Data()); - if( jvself.IsEmpty() || !jvself->IsExternal() ) - { - return v8::ThrowException(v8::Exception::Error(v8::String::New("Include() callback is missing its native V8Shell object."))); - } - V8Shell * self = static_cast( v8::External::Cast(*jvself)->Value() ); - v8::String::Utf8Value fn(argv[0]); - try - { - return hsc.Close(self->ExecuteFile( *fn )); - } - catch( std::exception const & ex ) - { - char const * msg = ex.what(); - return v8::ThrowException(v8::Exception::Error(v8::String::New(msg ? msg : "Unspecified native exception."))); - } - } - - public: - /** - Returns a Function object implementing conventional - include(filename) functionality (called load() in some JS - shells). This function must be created dynamically - because the generated function internally refers back to - this object (so that we can re-use ExecuteString() for the - implementation). - - The return value of the Function is the value of the last - expression evaluated in the given JS code. - - Results are undefined, and almost certainly fatal, if - the generated function is ever called after this native - object has been destructed. For best results, to avoid - potential lifetime issues, never install the returned - function in any object other than this object's Global(). - */ - v8::Handle CreateIncludeFunction() - { - return v8::FunctionTemplate::New(Include, v8::External::New(this))->GetFunction(); - } - - /** - Implements the v8::InvocationCallback interface and has the - following JS interface: - - @code - Array getStracktrace([unsigned int limit = some reasonable default]) - @endcode - - Each element in the returned array represents a stack frame and - is a plain object with the following properties: - - column = 1-based column number (note that this is - different from most editors, but this is how v8 returns - this value). - - line = 1-based line number - - scriptName = name of the script - - functionName = name of the function - - isConstructor = true if this is a constructor call - - isEval = true if this is part of an eval() - - TODO: - - - Add a toString() member to the returned array which creates a - conventional-looking stacktrace string. - */ - static v8::Handle GetStackTrace( v8::Arguments const & argv ) - { - using namespace v8; - int32_t limitSigned = (argv.Length() > 0) ? argv[0]->Int32Value() : 0; - if( limitSigned <= 0 ) limitSigned = 8; - else if( limitSigned > 100 ) limitSigned = 100; - uint32_t limit = static_cast(limitSigned); - HandleScope hsc; - Local const st = StackTrace::CurrentStackTrace( limit, StackTrace::kDetailed ); - int const fcountI = st->GetFrameCount(); - // Who the hell designed the StackTrace API to return an int in GetFrameCount() but take - // an unsigned int in GetFrame()??? - uint32_t const fcount = static_cast(fcountI); - Local jst = Array::New(fcount); -#define STR(X) v8::String::New(X) - for( uint32_t i = 0; (i < fcount) && (i const & sf( st->GetFrame(i) ); - Local jsf = Object::New(); - jsf->Set(STR("column"), v8::Integer::New(sf->GetColumn())); - jsf->Set(STR("functionName"), sf->GetFunctionName()); - jsf->Set(STR("line"), v8::Integer::New(sf->GetLineNumber())); - jsf->Set(STR("scriptName"), sf->GetScriptName()); - jsf->Set(STR("isConstructor"), sf->IsConstructor() ? v8::True() : v8::False() ); - jsf->Set(STR("isEval"), sf->IsEval() ? v8::True() : v8::False() ); - jst->Set(i,jsf); - } - return hsc.Close(jst); -#undef STR - } - - /** - Can optionally be called to include the following functionality - in this shell's Global() object: - - JS Functions: - - print(...) (see PrintToCout()) - - getStacktrace([int limit]) (see GetStackTrace()) - - load(filename) (see CreateIncludeFunction()) - - Returns this object, for use in chaining. - */ - V8Shell & SetupDefaultBindings() - { - (*this)( "print", PrintToCout ) - ("getStacktrace", GetStackTrace) - ("load", this->CreateIncludeFunction()) - ; - return *this; - } - }; - - /** - Convenience typedef for V8Shell<>. - */ - typedef V8Shell<> Shell; - -} -#endif /* V8_CONVERT_V8Shell_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/XTo.hpp b/vendor/libv8-convert/cvv8/XTo.hpp deleted file mode 100644 index f3502063e..000000000 --- a/vendor/libv8-convert/cvv8/XTo.hpp +++ /dev/null @@ -1,281 +0,0 @@ -#if !defined (CVV8_TO_X_HPP_INCLUDED) -#define CVV8_TO_X_HPP_INCLUDED -#include "invocable.hpp" -#include "properties.hpp" -/** @file XTo.hpp - - This file provides an alternate approach to the function - conversion API. It covers: - - - Converting functions and methods to to v8::InvocationCallback, - v8::AccessorGetter, and v8::AccessorSetter. - - - Converting variables to v8::AccessorGetter and v8::AccessorSetter. - - All conversions of a given category, e.g. FunctionToXYZ or MethodToXYZ - have a common template, e.g. FunctionTo or MethodTo. The first type - passed to that template is a "tag" type which tells us what conversion - to perform. e.g. a function can be used as an v8::InvocationCallback, - v8::AccessorGetter, or v8::AccessorSetter. - - An example probably explains it best: - - @code - int aBoundInt = 3; - void test_to_bindings() - { - v8::InvocationCallback cb; - v8::AccessorGetter g; - v8::AccessorSetter s; - - using namespace cvv8; - - typedef FunctionTo< InCa, int(char const *), ::puts> FPuts; - typedef FunctionTo< Getter, int(void), ::getchar> GetChar; - typedef FunctionTo< Setter, int(int), ::putchar> SetChar; - cb = FPuts::Call; - g = GetChar::Get; - s = SetChar::Set; - - typedef VarTo< Getter, int, &aBoundInt > VarGet; - typedef VarTo< Setter, int, &aBoundInt > VarSet; - g = VarGet::Get; - s = VarSet::Set; - typedef VarTo< Accessors, int, &aBoundInt > VarGetSet; - g = VarGetSet::Get; - s = VarGetSet::Set; - - typedef BoundNative T; - typedef MethodTo< InCa, const T, int (), &T::getInt > MemInCa; - typedef MethodTo< Getter, const T, int (), &T::getInt > MemGet; - typedef MethodTo< Setter, T, void (int), &T::setInt > MemSet; - cb = MemInCa::Call; - g = MemGet::Get; - s = MemSet::Set; - } - @endcode - - This unconventional, but nonetheless interesting and arguably - very readable/writable approach was first proposed by Coen - Campman. -*/ - - -namespace cvv8 { - - /** - Base (unimplemented) FunctionTo interface. - - Specializations act as proxies for FunctionToInCa, - FunctionToGetter and FunctionToSetter. Tag must be one of - (InCa, InCaVoid, Getter, Setter). The other args are as - documented for the aforementioned proxied types. - - See FunctionToInCa for more information about the parameters. - */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< FunctionSignature >::Value > - struct FunctionTo DOXYGEN_FWD_DECL_KLUDGE; - - //! Behaves like FunctionToInCa. - template ::FunctionType Func, bool UnlockV8> - struct FunctionTo< InCa, Sig, Func, UnlockV8 > : FunctionToInCa - {}; - - //! Behaves like FunctionToInCaVoid. - template ::FunctionType Func, bool UnlockV8> - struct FunctionTo< InCaVoid, Sig, Func, UnlockV8 > : FunctionToInCaVoid - {}; - - //! Behaves like FunctionToGetter. - template ::FunctionType Func, bool UnlockV8> - struct FunctionTo< Getter, Sig, Func, UnlockV8 > : FunctionToGetter - {}; - - //! Behaves like FunctionToSetter. - template ::FunctionType Func, bool UnlockV8> - struct FunctionTo< Setter, Sig, Func, UnlockV8 > : FunctionToSetter - {}; - - /** @class VarTo - - Base (unimplemented) VarTo interface. - - Acts as a proxy for VarToGetter and VarToSetter. Tag must be - one of (Getter, Setter, Accessors). The other args are as - documented for VarToGetter and VarToSetter. - */ - template - struct VarTo DOXYGEN_FWD_DECL_KLUDGE; - - //! Behaves like VarToGetter. - template - struct VarTo< Getter, PropertyType,SharedVar> : VarToGetter - {}; - - //! Behaves like VarToSetter. - template - struct VarTo< Setter, PropertyType,SharedVar> : VarToSetter - {}; - - //! Behaves like VarToAccessors. - template - struct VarTo< Accessors, PropertyType,SharedVar> : VarToAccessors - {}; - - /** - Base (unimplemented) type for MemberTo-xxx conversions. - - Acts as a proxy for MemberToGetter, MemberToSetter and - MemberToAccessors. Tag must be one of (Getter, Setter, Accessors). - The other args are as documented for MemberToGetter and - MemberToSetter. - */ - template - struct MemberTo DOXYGEN_FWD_DECL_KLUDGE; - - //! Behaves like MemberToGetter. - template - struct MemberTo : MemberToGetter< T, PropertyType, MemVar > {}; - - //! Behaves like MemberToSetter. - template - struct MemberTo : MemberToSetter< T, PropertyType, MemVar > {}; - - //! Behaves like MemberToAccessors. - template - struct MemberTo : MemberToAccessors< T, PropertyType, MemVar > {}; - - /** - Base (unimplemented) MethodTo interface. - - Acts as a proxy for MethodToInCa, MethodToGetter and - MethodToSetter (or their const cousins if T is - const-qualified). Tag must be one of (InCa, InCaVoid, - Getter, Setter). The other args are as documented for the - aforementioned proxied types. - - See MethodToInCa for more information about the parameters. - */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< MethodSignature >::Value> - struct MethodTo DOXYGEN_FWD_DECL_KLUDGE; - - //! Behaves like MethodToInCa. For const methods, const-qualify T. - template ::FunctionType Func, bool UnlockV8> - struct MethodTo< InCa, T, Sig, Func, UnlockV8 > : MethodToInCa - {}; - - //! Behaves like MethodToInCaVoid. For const methods, const-qualify T. - template ::FunctionType Func, bool UnlockV8> - struct MethodTo< InCaVoid, T, Sig, Func, UnlockV8 > : MethodToInCaVoid - {}; - - //! Behaves like MethodToGetter. For const methods, const-qualify T. - template ::FunctionType Func, bool UnlockV8> - struct MethodTo< Getter, T, Sig, Func, UnlockV8 > : MethodToGetter - {}; - - //! Behaves like MethodToSetter. For const methods, const-qualify T. - template ::FunctionType Func, bool UnlockV8> - struct MethodTo< Setter, T, Sig, Func, UnlockV8 > : MethodToSetter - {}; - - /** - Base (unimplemented) FunctorTo interface. - - Behaves like one of the following, depending on the Tag type: - - FunctorToInCa (Tag=InCa), FunctorToInCaVoid (Tag=InCaVoid), - FunctorToGetter (Tag=Getter), FunctorToSetter (Tag=Setter) - - See FunctorToInCa for more information about the parameters. - */ - template >::Value - > - struct FunctorTo DOXYGEN_FWD_DECL_KLUDGE; - - //! Behaves like FunctorToInCa. - template - struct FunctorTo< InCa, FtorT, Sig, UnlockV8 > : FunctorToInCa - {}; - - //! Behaves like FunctorToInCaVoid. - template - struct FunctorTo< InCaVoid, FtorT, Sig, UnlockV8 > : FunctorToInCaVoid - {}; - - //! Behaves like FunctorToGetter. - template - struct FunctorTo< Getter, FtorT, Sig, UnlockV8 > : FunctorToGetter - {}; - - //! Behaves like FunctorToSetter. - template - struct FunctorTo< Setter, FtorT, Sig, UnlockV8 > : FunctorToSetter - {}; -} -/** LICENSE - - This software's source code, including accompanying documentation and - demonstration applications, are licensed under the following - conditions... - - The author (Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) - explicitly disclaims copyright in all jurisdictions which recognize - such a disclaimer. In such jurisdictions, this software is released - into the Public Domain. - - In jurisdictions which do not recognize Public Domain property - (e.g. Germany as of 2011), this software is Copyright (c) 2011 - by Stephan G. Beal, and is released under the terms of the MIT License - (see below). - - In jurisdictions which recognize Public Domain property, the user of - this software may choose to accept it either as 1) Public Domain, 2) - under the conditions of the MIT License (see below), or 3) under the - terms of dual Public Domain/MIT License conditions described here, as - they choose. - - The MIT License is about as close to Public Domain as a license can - get, and is described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - -- - Copyright (c) 2011 Stephan G. Beal (http://wanderinghorse.net/home/stephan/) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - --END OF MIT LICENSE-- - - For purposes of the above license, the term "Software" includes - documentation and demonstration source code which accompanies - this software. ("Accompanies" = is contained in the Software's - primary public source code repository.) - -*/ - -#endif /* CVV8_TO_X_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/arguments.hpp b/vendor/libv8-convert/cvv8/arguments.hpp deleted file mode 100644 index 307db2cae..000000000 --- a/vendor/libv8-convert/cvv8/arguments.hpp +++ /dev/null @@ -1,817 +0,0 @@ -#if !defined(V8_CONVERT_ARGUMENTS_HPP_INCLUDED) -#define V8_CONVERT_ARGUMENTS_HPP_INCLUDED -#include "convert.hpp" -#include - -namespace cvv8 { - - /** - A functor which fetches an argument by index. - - I = the argument index to fetch. - - The class is intended mainly to be invoked via code paths - selected by template metaprograms, thus the hard-coding of - the argument parameter index at compile-time. - */ - template - struct ArgAt - { - typedef char AssertIndex[ (I>=0) ? 1 : -1]; - /** - Returns argv[I] if argv.Length() is <= I, else v8::Undefined() - is returned. - */ - inline v8::Handle operator()( v8::Arguments const & argv ) const - { - return (argv.Length() > I) ? argv[I] : v8::Undefined(); - } - }; - - /** - Functor to fetch an argument and return its result - as a native value. - - I = the argument index to fetch. - - T = the native type to convert to. CastFromJS() must be legal. - */ - template - struct ArgAtCast - { - typedef JSToNative J2N; - typedef typename J2N::ReturnType ReturnType; - typedef char AssertIndex[ (I>=0) ? 1 : -1]; - /** - Returns CastFromJS( ArtAt(argv) ). - */ - inline ReturnType operator()( v8::Arguments const & argv ) const - { - typedef ArgAt Proxy; - return CastFromJS( Proxy()(argv) ); - } - }; - - /** - Marker class, for documentation purposes. - */ - struct ValuePredicate - { - /** - Must evaluate the handle and return true or false. - The framework cannot guaranty that h.IsEmpty() is false, - so implementations should be in the habit of checking it. - */ - bool operator()( v8::Handle const & h ) const; - }; - - /** - A functor interface for determining if a JS value - "is-a" value of a particular native type. The default - implementation is useable for any type for which the - following is legal: - - @code - T const * t = CastFromJS( aV8Handle ); - @endcode - - Specializations are used for most data types, but this - one is fine for client-bound types conformant with - CastFromJS(). - - Note that the default specializations treat T as a plain type, - discarding const/pointer/reference qualifiers. Certain types may - require that ValIs (and similar) be specialized in order - to behave properly. - */ - template - struct ValIs : ValuePredicate - { - typedef T Type; - /** - Returns true if v appears to contain a (T*). - */ - inline bool operator()( v8::Handle const & v ) const - { - return NULL != CastFromJS(v); - } - }; - - //! Specialization to treat (T const) as T. - template struct ValIs : ValIs {}; - //! Specialization to treat (T const &) as T. - template struct ValIs : ValIs {}; - //! Specialization to treat (T *) as T. - template struct ValIs : ValIs {}; - //! Specialization to treat (T const *) as T. - template struct ValIs : ValIs {}; - - /** - Specialization which treats void as the v8::Undefined() value. - */ - template <> - struct ValIs - { - typedef void Type; - /** - Returns true only if h is not empty and h->IsUndefined(). Note - that an empty handle evaluates to false in this context because - Undefined is a legal value whereas an empty handle is not. - (Though Undefined might not be _semantically_ legal in any given - use case, it is legal to dereference such a handle.) - */ - inline bool operator()( v8::Handle const & h ) const - { - return h.IsEmpty() ? false : h->IsUndefined(); - } - }; - -#if !defined(DOXYGEN) - namespace Detail { - /** - ValuePredicate impl which returns retrue if - Getter returns true for the given value. - - Getter must be a pointer to one of the v8::Value::IsXXX() - functions. This functor returns true if the passed-in handle is - not empty and its IsXXX() function returns true. - */ - template - struct ValIs_X : ValuePredicate - { - inline bool operator()( v8::Handle const & v ) const - { - return v.IsEmpty() ? false : ((*v)->*Getter)(); - } - }; - - /** - A ValuePredicate impl which returns true only if - the given handle is-a number and the number is in the - inclusive range (std::numeric_limits::min .. - max()). - */ - template - struct ValIs_NumberStrictRange : ValuePredicate - { - typedef NumT Type; - inline bool operator()( v8::Handle const & h ) const - { - if( h.IsEmpty() || ! h->IsNumber() ) return false; - else - { - double const dv( h->NumberValue() ); - return (dv >= std::numeric_limits::min()) - && (dv <= std::numeric_limits::max()); - } - } - }; - /** Special-case specialization which returns true if the given - handle is-a Number (without checking the range, which is - not necessary for this specific type in this context). - */ - template <> - struct ValIs_NumberStrictRange : ValuePredicate - { - typedef double Type; - inline bool operator()( v8::Handle const & h ) const - { - return !h.IsEmpty() && h->IsNumber(); - } - }; - } -#endif // DOXYGEN - - /** A Value predicate which returns true if its argument is-a Array. */ - struct ValIs_Array : Detail::ValIs_X<&v8::Value::IsArray> {}; - /** A Value predicate which returns true if its argument is-a Object. */ - struct ValIs_Object : Detail::ValIs_X<&v8::Value::IsObject> {}; - /** A Value predicate which returns true if its argument is-a Boolean. */ - struct ValIs_Boolean : Detail::ValIs_X<&v8::Value::IsBoolean> {}; - /** A Value predicate which returns true if its argument is-a Date. */ - struct ValIs_Date : Detail::ValIs_X<&v8::Value::IsDate> {}; - /** A Value predicate which returns true if its argument is-a External. */ - struct ValIs_External : Detail::ValIs_X<&v8::Value::IsExternal> {}; - /** A Value predicate which returns true if its argument has a false value. */ - struct ValIs_False : Detail::ValIs_X<&v8::Value::IsFalse> {}; - /** A Value predicate which returns true if its argument is-a Function. */ - struct ValIs_Function : Detail::ValIs_X<&v8::Value::IsFunction> {}; - /** A Value predicate which returns true if its argument is-a In32. */ - struct ValIs_Int32 : Detail::ValIs_X<&v8::Value::IsInt32> {}; - /** A Value predicate which returns true if its argument is-a UInt32. */ - struct ValIs_UInt32 : Detail::ValIs_X<&v8::Value::IsUint32 /* Note the "UInt" vs "Uint" descrepancy. i consider Uint to be wrong.*/ > {}; - /** A Value predicate which returns true if its argument is Null (JS null, not C++ NULL). */ - struct ValIs_Null : Detail::ValIs_X<&v8::Value::IsNull> {}; - /** A Value predicate which returns true if its argument has the special Undefined value. */ - struct ValIs_Undefined : Detail::ValIs_X<&v8::Value::IsUndefined> {}; - /** A Value predicate which returns true if its argument is-a Number. */ - struct ValIs_Number : Detail::ValIs_X<&v8::Value::IsNumber> {}; - /** A Value predicate which returns true if its argument is-a RegExp. */ - struct ValIs_RegExp : Detail::ValIs_X<&v8::Value::IsRegExp> {}; - /** A Value predicate which returns true if its argument is-a String. */ - struct ValIs_String : Detail::ValIs_X<&v8::Value::IsString> {}; - /** A Value predicate which returns true if its argument has a true value. */ - struct ValIs_True : Detail::ValIs_X<&v8::Value::IsTrue> {}; - - // FIXME: reverse the parent relationships between e.g. ValIs and ValIs_Array. - /** A Value predicate which returns true if its argument is a number capable - of fitting in an int8_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an uint8_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an int16_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an uint16_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an int32_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an uint32_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an int64_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is a number capable - of fitting in an uint64_t. */ - template <> struct ValIs : Detail::ValIs_NumberStrictRange {}; - /** A Value predicate which returns true if its argument is-a Number value. */ - template <> struct ValIs : ValIs_Number {}; - //! Special-case specialization to treat C strings as JS strings. - template <> struct ValIs : ValIs_String {}; - //! Special-case specialization to treat v8 strings as JS strings. - template <> struct ValIs : ValIs_String {}; - //! A Value predicate which returns true if its argument is-a Array. */ - template <> struct ValIs : ValIs_Array {}; - //! A Value predicate which returns true if its argument is-a Object. */ - template <> struct ValIs : ValIs_Object {}; - //! A Value predicate which returns true if its argument is-a Boolean. */ - template <> struct ValIs : ValIs_Boolean {}; - //! A Value predicate which returns true if its argument is-a Date. */ - template <> struct ValIs : ValIs_Date {}; - //! A Value predicate which returns true if its argument is-a External. */ - template <> struct ValIs : ValIs_External {}; - //! A Value predicate which returns true if its argument is-a Function. */ - template <> struct ValIs : ValIs_Function {}; - //! A Value predicate which returns true if its argument is-a Int32. */ - template <> struct ValIs : ValIs_Int32 {}; - //! A Value predicate which returns true if its argument is-a UInt32. */ - template <> struct ValIs : ValIs_UInt32 {}; - //! A Value predicate which returns true if its argument is-a Number. */ - template <> struct ValIs : ValIs_Number {}; - //! A Value predicate which returns true if its argument is-a RegExp. */ - template <> struct ValIs : ValIs_RegExp {}; - //! A Value predicate which returns true if its argument is-a String. */ - template <> struct ValIs : ValIs_String {}; - //! Specialization to treat Handle as T. */ - template struct ValIs< v8::Handle > : ValIs< T > {}; - //! Specialization to treat Local as T. */ - template struct ValIs< v8::Local > : ValIs< T > {}; - //! Specialization to treat Persistent as T. */ - template struct ValIs< v8::Persistent > : ValIs< T > {}; - - /** - Marker class, mainly for documentation purposes. - - Classes matching this concept "evaluate" a v8::Arguments - object for validity without actually performing any - "application logic." These are intended to be used as - functors, primarily triggered via code paths selected by - template metaprograms. - - They must be default-construcable and should have no - private state. Their public API consists of only operator(). - - This Concept's operator() is intended only to be used for - decision-making purposes ("are there enough arguments?" or - "are the arguments of the proper types?"), and not - higher-level application logic. - */ - struct ArgumentsPredicate - { - /** - Must "evaluate" the arguments and return true or false. - */ - bool operator()( v8::Arguments const & ) const; - }; - - /** - Functor to evaluate whether an Arguments list - has a certain range of argument count. - - Min is the minimum number. Max is the maximum. The range is - inclusive. Use (Max - struct Argv_Length : ArgumentsPredicate - { - private: - typedef char AssertMinIsPositive[ (Min_>=0) ? 1 : -1 ]; - enum { Min = Min_, Max = Max_ }; - public: - /** - Returns true if av meets the argument count - requirements defined by the Min and Max - values. - */ - bool operator()( v8::Arguments const & av ) const - { - - int const argc = av.Length(); - return (Max < Min) - ? argc >= Min - : (argc>=Min) && (argc<=Max); - } - }; - - /** - Arguments predicate functor. - - Index = arg index to check. - - ValIsType must match the ValuePredicate interface. - */ - template - struct ArgAt_Is : ArgumentsPredicate - { - /** - Returns true if ValType()( av[Index] ) is true. - */ - inline bool operator()( v8::Arguments const & av ) const - { - return (Index >= av.Length()) - ? false - : ValIsType()( av[Index] ); - } - }; - - /** - Arguments predicate functor. - - Index = arg index to check. - - T is a type for which ValIs is legal. The functor - returns true if ValIs returns true the argument - at the given index. - */ - template - struct ArgAt_IsA : ArgAt_Is< Index, ValIs > {}; - - namespace Detail { - /** - Functor which proxies the v8::Value "is-a" functions. - - Index is the argument index to check. Getter is the - member to be used to perform the is-a evaluation. - */ - template - struct ArgAt_IsX : ArgumentsPredicate - { - /** - Returns true only if (Index < av.Length()) - and av->Getter() returns true. - */ - inline bool operator()( v8::Arguments const & av ) const - { - return ( av.Length() <= Index ) - ? false - : ((*av[Index])->*Getter)(); - } - }; - } - - //! ArgumentsPredicate which returns true if the argument at Index is-a Array. */ - template - struct ArgAt_IsArray : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a Object. */ - template - struct ArgAt_IsObject : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a Boolean. */ - template - struct ArgAt_IsBoolean : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a Date. */ - template - struct ArgAt_IsDate : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a External. */ - template - struct ArgAt_IsExternal : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index has a false value. */ - template - struct ArgAt_IsFalse : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a Function. */ - template - struct ArgAt_IsFunction : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a Int32Boolean. */ - template - struct ArgAt_IsInt32 : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a UInt32. */ - template - struct ArgAt_IsUInt32 : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index has the special Null value. */ - template - struct ArgAt_IsNull : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index has the special Undefined value. */ - template - struct ArgAt_IsUndefined : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a Number. */ - template - struct ArgAt_IsNumber : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a RegExp. */ - template - struct ArgAt_IsRegExp : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index is-a String. */ - template - struct ArgAt_IsString : Detail::ArgAt_IsX {}; - - //! ArgumentsPredicate which returns true if the argument at Index has a True value. */ - template - struct ArgAt_IsTrue : Detail::ArgAt_IsX {}; - - - /** - ArgumentsPredicate functor which always returns true. - - This currently has only one obscure use: as the predicate given to a - PredicatedInCa in conjunction with an N-arity callback, used as a - catch-all fallback as the last item in a list of PredicatedInCas - passed to PredicatedInCaDispatcher. (Got that?) - */ - struct Argv_True : ArgumentsPredicate - { - inline bool operator()( v8::Arguments const & ) const - { - return true; - } - }; - /** ArgumentsPredicate which always returns false. - - This predicate has only one known, rather obscure use in combination - with type lists. - */ - struct Argv_False : ArgumentsPredicate - { - inline bool operator()( v8::Arguments const & ) const - { - return false; - } - }; - - /** - An ArgumentsPredicate implementation which takes - two ArgumentsPredicate functors as template parameters - and combines them using an AND operation. - - See Argv_AndN if you just want to combine more than two functors. - (Argv_AndN can also be used for two functors but is more verbose - than this form for that case.) - */ - template - struct Argv_And : ArgumentsPredicate - { - /** - Returns true only if ArgPred1()(args) and - ArgPred2()(args) both return true. - */ - inline bool operator()( v8::Arguments const & args ) const - { - return ArgPred1()( args ) && ArgPred2()( args ); - } - }; - - /** - The "or" equivalent of Argv_And. - - Use Argv_OrN for chaining more than two predicates. - */ - template - struct Argv_Or : ArgumentsPredicate - { - /** - Returns true only if one of ArgPred1()(args) or - ArgPred2()(args) return true. - */ - inline bool operator()( v8::Arguments const & args ) const - { - return ArgPred1()( args ) || ArgPred2()( args ); - } - }; - - /** - This ArgumentsPredicate implementation combines a list of - other ArgumentsPredicates using an AND operation on the combined - results of each functor. - - PredList must be a type-list containing ArgumentsPredicate types. - This functor is a predicate which performs an AND operation on all - of the predicates in the type list. - - Note that an empty typelist evaluates to True in this context, for - deeply arcane reasons. - - See Argv_And if you just want to combine two functors - (it is more succinct for that case). - - Example: - - @code - // Predicate matching (function, ANYTHING, function) signature: - typedef Argv_AndN< CVV8_TYPELIST(( - Argv_Length<3>, - ArgAt_IsFunction<0>, - ArgAt_IsFunction<2> - )) > PredFuncXFunc; - @endcode - */ - template - struct Argv_AndN : ArgumentsPredicate - { - /** - Returns true only if all predicates in PredList - return true when passed the args object. - */ - inline bool operator()( v8::Arguments const & args ) const - { - typedef typename PredList::Head Head; - typedef typename tmp::IfElse< tmp::SameType::Value, - Argv_True, - Head>::Type P1; - typedef typename PredList::Tail Tail; - typedef Argv_AndN P2; - return P1()( args ) && P2()(args); - } - }; - - //! End-of-list specialization. - template <> - struct Argv_AndN : Argv_True {}; - - /** - The "or" equivalent of Argv_AndN. - - When chaining only two predicates Argv_Or offers - a more succinct equivalent to this type. - - Note that an empty typelist evaluates to False in this context, for - deeply arcane reasons. - */ - template - struct Argv_OrN : ArgumentsPredicate - { - /** - Returns true only if one of the predicates in PredList - returns true when passed the args object. - */ - inline bool operator()( v8::Arguments const & args ) const - { - typedef typename PredList::Head P1; - typedef typename PredList::Tail Tail; - typedef Argv_OrN P2; - return P1()( args ) || P2()(args); - } - }; - - //! End-of-list specialization. - template <> - struct Argv_OrN : ArgumentsPredicate - { - /** - Always returns false. - */ - inline bool operator()( v8::Arguments const & ) const - { - return false; - } - }; - - /** - Intended as a base class for a couple other - PredicatedXyz types. - - This type combines ArgumentsPredicate ArgPred and - CallT::Call() into one type, for template-based dispatching - purposes. - - ArgPred must be-a ArgumentsPredicate. CallT must - be a type having a static Call() function taking one - (v8::Arguments const &) and returning any type. - - This type uses subclassing instead of composition - to avoid having to specify the CallT::Call() return - type as an additional template parameter. i don't seem to - be able to template-calculate it from here. We can't use - CallT::ReturnType because for most bindings that value - is different from its Call() return type. We will possibly - eventually run into a problem with the lack of a way - to get Call()'s return type. - - @see PredicatedInCaDispatcher - */ - template - struct PredicatedInCaLike : ArgPred, CallT {}; - - /** - PredicatedInCa combines an ArgumentsPredicate functor - (ArgPred) with an InCa type, such that we can create lists - of functor/callback pairs for use in dispatching callbacks - based on the results of ArgumentPredicates. - - InCaT must implement the InCa interface. - - This type is primarily intended to be used together with - PredicatedInCaDispatcher. - - @see PredicatedInCaLike - - Reminder to self: this class is only in arguments.hpp, as opposed to - invocable_core.hpp, because i want (for pedantic - documentation-related reasons) this class to inherit - ArgumentsPredicate, which invocable*.hpp does not know about. - We might want to move ArgumentsPredicate and - ValuePredicate into convert_core.hpp and move this class back - into invocable_core.hpp. - - @see PredicatedInCaDispatcher - */ - template - struct PredicatedInCa : PredicatedInCaLike {}; - - /** - This class creates an InvocationCallback which dispatches to one of an - arbitrarily large set of other InvocationCallbacks, as determined by - predicate rules. - - PredList must be a type-list (e.g. Signature) of PredicatedInCa - implementations. See Call() for more details. - - Basic example: - - @code - // Overloads for 1-3 arguments: - typedef PredicatedInCa< Argv_Length<1>, ToInCa<...> > Cb1; - typedef PredicatedInCa< Argv_Length<2>, ToInCa<...> > Cb2; - typedef PredicatedInCa< Argv_Length<3>, ToInCa<...> > Cb3; - // Fallback impl for 0 or 4+ args: - typedef PredicatedInCa< Argv_True, InCaToInCa > CbN; - // Side note: this ^^^^^^^^^^^^^^ is the only known use for the - // Argv_True predicate. - - // Combine them into one InvocationCallback: - typedef PredicatedInCaDispatcher< CVV8_TYPELIST(( - Cb1, Cb2, Cb3, CbN - ))> AllOverloads; - v8::InvocationCallback cb = AllOverloads::Call; - @endcode - */ - template - struct PredicatedInCaDispatcher - : InCa - { - /** - For each PredicatedInCa (P) in PredList, if P()(argv) - returns true then P::Call(argv) is returned, else the next - predicate in the list is tried. - - If no predicates match then a JS-side exception will be triggered. - */ - static inline v8::Handle Call( v8::Arguments const & argv ) - { - typedef typename PredList::Head Head; - typedef typename tmp::IfElse< tmp::SameType::Value, - Argv_False, - Head>::Type Ftor; - typedef typename PredList::Tail Tail; - typedef char AssertEndOfListCheck[ tmp::SameType::Value - ? (tmp::SameType::Value ? 1 : -1) - : 1 - /* ensures that the Argv_False kludge does not call - any specialization other than the NilType one. - */ - ]; - return ( Ftor()( argv ) ) - ? Detail::OverloadCallHelper::Call( argv ) - : PredicatedInCaDispatcher::Call(argv); - } - }; - - //! End-of-list specialization. - template <> - struct PredicatedInCaDispatcher< tmp::NilType > : InCa - { - /** - Triggers a JS-side exception explaining (in English text) that no - overloads could be matched to the given arguments. - */ - static inline v8::Handle Call( v8::Arguments const & argv ) - { - return Toss(StringBuffer()<<"No predicates in the " - << "argument dispatcher matched the given " - << "arguments (arg count="< - struct PredicatedCtorForwarder - : PredicatedInCaLike {}; - - /** - The constructor counterpart of PredicatedInCaDispatcher. - PredList must be a typelist of PredicatedCtorForwarder (or - interface-compatible) types. The ReturnType part of the - typelist must be the base type the constructors in the list - can return (they must all share a common base). Clients must - not pass the ContextT parameter - it is required internally - for handling the end-of-typelist case. - - This template instantiates TypeName, so - if that template is to be specialized by client code, it should - be specialized before this template used. - */ - template - struct PredicatedCtorDispatcher - { - /** - Force the ContextT into a native handle type. - */ - typedef typename TypeInfo::NativeHandle ReturnType; - /** - For each PredicatedCtorForwarder (P) in PredList, if P()(argv) - returns true then P::Call(argv) is returned, else the next - predicate in the list is tried. - - If no predicates match then a JS-side exception will be triggered. - */ - static ReturnType Call( v8::Arguments const & argv ) - { - typedef typename PredList::Head Head; - typedef typename tmp::IfElse< tmp::SameType::Value, - Argv_False, - Head>::Type Ftor; - typedef typename PredList::Tail Tail; - return ( Ftor()( argv ) ) - ? Detail::CtorFwdDispatch::Call( argv ) - : PredicatedCtorDispatcher::Call(argv); - } - }; - - //! End-of-list specialization. - template - struct PredicatedCtorDispatcher< tmp::NilType, ContextT > : Signature< ContextT * () > - { - typedef typename TypeInfo::NativeHandle ReturnType; - /** - Triggers a native exception explaining (in English text) that no - overloads could be matched to the given arguments. It's kinda - cryptic, but we can't be more specific at this level of - the API. - */ - static ReturnType Call( v8::Arguments const & argv ) - { - StringBuffer os; - os << "No predicates in the " - << TypeName::Value - << " ctor argument dispatcher matched the given " - << "arguments (arg count="< // arg! Requires C++0x! -#include -#include // hope the client's platform is recent! -#include -#include -#include -#include -#include -#include -#include - -#if !defined(CVV8_CONFIG_HAS_LONG_LONG) -/* long long in C++ requires C++0x or compiler extensions. */ -# define CVV8_CONFIG_HAS_LONG_LONG 0 -#endif - -#include "signature_core.hpp" /* only needed for the Signature used by the generated code. */ -#include "tmp.hpp" - -namespace cvv8 { - - - /** - A convenience base type for TypeInfo specializations. - */ - template - struct TypeInfoBase - { - /** - The unqualified type T. In some special cases, Type _may_ - differ from T. - */ - typedef T Type; - /** - The "handle" type used to pass around native objects - between the JS and Native worlds. - - In _theory_ we can also use shared/smart pointers with - this typedef, but that requires custom handling in other - template code (mainly because we cannot store a - full-fledged shared pointer object directly inside a JS - object). - */ - typedef NHT NativeHandle; - - // MAYBE to do: add a function to get a pointer to the object, e.g. - // for dereferencing smart pointers. So far it's not been necessary. - // static NativeHandle Pointer( NativeHandle x ) { return x; } - }; - - /** - This may optionally be specialized for client-defined types - to define the type name used by some error reporting - code. - - The default implementation is usable but not all that useful. - */ - template - struct TypeName - { - /** Specializations must have a non-NULL value, and any number - of specializations may legally have the same value. - */ - static char const * Value; - }; -#if 0 - /** - This default implementation is unfortunate, but quite a bit - of error-reporting code uses this, with the assumption that - if it was worth binding to JS then it's worth having a - useful type name in error strings. - - FIXME: remove the default specialization if we can, as it will - cause us problems with some planned/potential uses which cross - DLL boundaries (there may be multiple definitions with different - addresses). - */ - template - char const * TypeName::Value = "T"; -#endif - - /** @def CVV8_TypeName_DECL - - A convenience macro for declaring a TypeName specialization. X must - be a type name with extra wrapping parenthesis, e.g.: - - @code - CVV8_TypeName_DECL((MyType)); - @endcode - - They are required so that we can also support template types with commas - in the names, e.g. (std::map). - - It must be called from inside the cvv8 namespace. - */ -#define CVV8_TypeName_DECL(X) template <> struct TypeName< cvv8::sl::At<0,CVV8_TYPELIST(X) >::Type > \ - { const static char * Value; } - - /** @def CVV8_TypeName_IMPL - - The counterpart of CVV8_TypeName_DECL, this must be called from the - cvv8 namespace. The X argument is as documented for CVV8_TypeName_DECL - and the NAME argument must be a C string. - - Example: - - @code - CVV8_TypeName_IMPL((MyType),"MyType"); - @endcode - */ -#define CVV8_TypeName_IMPL(X,NAME) char const * TypeName< cvv8::sl::At<0,CVV8_TYPELIST(X) >::Type >::Value = NAME - /** @def CVV8_TypeName_IMPL2 - - Almost identical to CVV8_TypeName_IMPL(), but can be used without - having first explicitly specializing TypeName. - */ -#define CVV8_TypeName_IMPL2(X,NAME) template <> CVV8_TypeName_IMPL(X,NAME) - - -#if 1 - template - struct TypeName : TypeName {}; - template - struct TypeName : TypeName {}; - template - struct TypeName : TypeName {}; -#endif - - /** - Describes basic type information regarding a type, for purposes - of static typing during JS-to/from-Native conversions. - - The default instantiation is suitable for most - cases. Specializations may be required in certain JS/Native - binding cases. - */ - template - struct TypeInfo : TypeInfoBase - { - }; - - template - struct TypeInfo : TypeInfo {}; - - template - struct TypeInfo : TypeInfo {}; - - template - struct TypeInfo : TypeInfo {}; - - template - struct TypeInfo : TypeInfo {}; - - template - struct TypeInfo : TypeInfo {}; - -#if 1 // this will only theoretically do what i want. Never actually tried to use a non-pointer NativeHandle type... - template - struct TypeInfo< v8::Handle > - { - typedef v8::Handle Type; - typedef v8::Handle NativeHandle; - }; -#endif - - /** - Base instantiation for T-to-v8::Handle conversion functor. - Must be specialized or it will not compile. - */ - template - struct NativeToJS - { - /** - Must be specialized. The argument type may be pointer-qualified. - Implementations for non-pod types are encouraged to have two - overloads, one taking (NT const &) and one taking (NT const *), - as this gives the underlying CastToJS() calls more leeway. - **/ - template - v8::Handle operator()( X const & ) const; - private: - typedef tmp::Assertion NativeToJSMustBeSpecialized; - }; - - /** - Specialization to treat (NT*) as (NT). - - NativeToJS must have an operator() taking - (NT const *). - */ - template - struct NativeToJS : NativeToJS -#if 1 - {}; -#else - { - v8::Handle operator()( NT const * v ) const - { - typedef NativeToJS Proxy; - if( v ) return Proxy()(v); - else return v8::Null() - ; - } - }; -#endif - /** - Specialization to treat (NT const *) as (NT). - */ - template - struct NativeToJS : NativeToJS {}; - // { - // typedef typename TypeInfo::Type const * ArgType; - // v8::Handle operator()( ArgType n ) const - // { - // typedef NativeToJS Proxy; - // return Proxy()( n ); - // } - // }; - - /** - Specialization to treat (NT const &) as (NT). - */ - template - struct NativeToJS : NativeToJS {}; - template - struct NativeToJS : NativeToJS {}; - -#if 0 - /** - Specialization to treat (NT &) as (NT). - */ - template - struct NativeToJS : NativeToJS {}; -#else - /** - A specialization to convert from (T&) to JS. - - Be very careful with this, and make sure that - NativeToJS has its own specialization, - as this implementation uses that one as its - basis. - */ - template - struct NativeToJS - { - typedef typename TypeInfo::Type & ArgType; - v8::Handle operator()( ArgType n ) const - { - typedef NativeToJS< typename TypeInfo::NativeHandle > Cast; - return Cast()( &n ); - } - }; -#endif - -#if 0 - template <> - struct NativeToJS - { - /** - Returns v8::Undefined(). - */ - template - v8::Handle operator()(Ignored const &) const - { - return ::v8::Undefined(); - } - }; -#endif - -#if !defined(DOXYGEN) - namespace Detail { - /** - Base implementation for "small" integer conversions (<=32 - bits). - */ - template - struct NativeToJS_int_small - { - v8::Handle operator()( IntegerT v ) const - { - return v8::Integer::New( static_cast(v) ); - } - }; - /** - Base implementation for "small" unsigned integer conversions - (<=32 bits). - */ - template - struct NativeToJS_uint_small - { - v8::Handle operator()( IntegerT v ) const - { - return v8::Integer::NewFromUnsigned( static_cast(v) ); - } - }; - } -#endif // if !defined(DOXYGEN) - - template <> - struct NativeToJS : Detail::NativeToJS_int_small {}; - - template <> - struct NativeToJS : Detail::NativeToJS_uint_small {}; - - template <> - struct NativeToJS : Detail::NativeToJS_int_small {}; - - template <> - struct NativeToJS : Detail::NativeToJS_uint_small {}; - -#if !defined(DOXYGEN) - namespace Detail { - /** - Base implementation for "big" numeric conversions (>32 bits). - */ - template - struct NativeToJS_int_big - { - /** Returns v as a double value. */ - v8::Handle operator()( IntegerT v ) const - { - return v8::Number::New( static_cast(v) ); - } - }; - } -#endif // if !defined(DOXYGEN) - - template <> - struct NativeToJS : Detail::NativeToJS_int_big {}; - - template <> - struct NativeToJS : Detail::NativeToJS_int_big {}; - - template <> - struct NativeToJS - { - v8::Handle operator()( double v ) const - { - return v8::Number::New( v ); - } - }; - - template <> - struct NativeToJS - { - v8::Handle operator()( bool v ) const - { - return v8::Boolean::New( v ); - } - }; - - template - struct NativeToJS< ::v8::Handle > - { - typedef ::v8::Handle handle_type; - v8::Handle operator()( handle_type const & li ) const - { - return li; - } - }; - - template - struct NativeToJS< ::v8::Local > - { - typedef ::v8::Local handle_type; - v8::Handle operator()( handle_type const & li ) const - { - return li; - } - }; - - template - struct NativeToJS< ::v8::Persistent > - { - typedef ::v8::Persistent handle_type; - v8::Handle operator()( handle_type const & li ) const - { - return li; - } - }; - - template <> - struct NativeToJS< ::v8::InvocationCallback > - { - v8::Handle operator()( ::v8::InvocationCallback const f ) const - { - return ::v8::FunctionTemplate::New(f)->GetFunction(); - } - }; - - - template <> - struct NativeToJS - { - v8::Handle operator()( std::string const & v ) const - { - /** This use of v.data() instead of v.c_str() is highly arguable. */ - char const * const cstr = v.data(); - return cstr ? v8::String::New( cstr, static_cast( v.size() ) ) : v8::String::New("",0); - } - }; - - template <> - struct NativeToJS - { - v8::Handle operator()( char const * v ) const - { - if( ! v ) return v8::Null(); - else return v8::String::New( v ); - } - }; - - /** - "Casts" v to a JS value using NativeToJS. - */ - template - inline v8::Handle CastToJS( T const & v ) - { - typedef NativeToJS F; - return F()( v ); - } - - /** - Overload to avoid ambiguity in certain calls. - */ - static inline v8::Handle CastToJS( char const * v ) - { - typedef NativeToJS F; - return F()( v ); - } - - /** - Overload to avoid mis-selection of templates. - */ - static inline v8::Handle CastToJS( v8::InvocationCallback v ) - { - typedef NativeToJS F; - return F()( v ); - } - - /** - Overload to avoid ambiguity in certain calls. - */ - static inline v8::Handle CastToJS( char * v ) - { - typedef NativeToJS F; - return F()( v ); - } - - /** Convenience instance of NativeToJS. */ - static const NativeToJS Int16ToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS UInt16ToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS Int32ToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS UInt32ToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS Int64ToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS UInt64ToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS DoubleToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS BoolToJS = NativeToJS(); - /** Convenience instance of NativeToJS. */ - static const NativeToJS StdStringToJS = NativeToJS(); - - /** - Converts a native std::exception to a JS exception and throws - that exception via v8::ThrowException(). - */ - template <> - struct NativeToJS - { - /** Returns v8::Exception::Error(ex.what()). - - ACHTUNG: on 20110717 this function was changed to NOT trigger a - JS exception. Prior versions triggered a JS exception, but that - was done due to a misunderstanding on my part (i didn't know v8 - provided a way to create Error objects without throwing). This - change is semantically incompatible with older code which uses - this conversion. - - OLD way of doing it (don't do this!): - - @code - catch( std::exception const & ex ) { return CastToJS(ex); } - @endcode - - The equivalent is now: - - @code - catch( std::exception const & ex ) { return Toss(CastToJS(ex)); } - @endcode - */ - v8::Handle operator()( std::exception const & ex ) const - { - char const * msg = ex.what(); - return v8::Exception::Error(v8::String::New( msg ? msg : "unspecified std::exception" )); - /** ^^^ String::New() internally calls strlen(), which hates it when string==0. */ - } - }; - template <> - struct NativeToJS : NativeToJS {}; - template <> - struct NativeToJS : NativeToJS {}; - template <> - struct NativeToJS : NativeToJS {}; - - - /** - Base interface for converting from native objects to JS - objects. There is no default implementation, and it must be - specialized to be useful. - - When creating custom implementations, remember that in - practice, all custom client-bound types are passed around - internally by non-const pointer. This is in contrast to - conversions of POD- and POD-like types (numbers and strings), - which are passed around by value. - - It is theoretically possible to use smart pointers (with value - semantics) via this API, but it is untested. - */ - template - struct JSToNative - { - typedef typename TypeInfo::NativeHandle ResultType; - //! Must be specialized to be useful. - ResultType operator()( v8::Handle const & h ) const; - }; - - /** Specialization to treat (JST*) as JST. */ - template - struct JSToNative : JSToNative {}; - - /** Specialization to treat (JST*) as JST. */ - template - struct JSToNative : JSToNative {}; - - /** Specialization to treat (JST const *) as (JST *). */ - template - struct JSToNative : JSToNative {}; - - /** - A specialization to convert from JS to (T&). - */ - template - struct JSToNative - { - /** - Uses JSTNative() to try to convert a JS object to a - pointer, and then dereferences that pointer to form - (T&). Beware, however, that this operation throws a native - exeception (deriving from std::exception) if it fails, - because the only other other option is has is to - dereference null and crash your app. - */ - typedef typename TypeInfo::Type & ResultType; - ResultType operator()( v8::Handle const & h ) const - { - typedef JSToNative Cast; - typedef typename Cast::ResultType NH; - NH n = Cast()( h ); - if( ! n ) - { - throw std::runtime_error("JSToNative could not get native pointer. Throwing to avoid dereferencing null!"); - } - else return *n; - } - }; - - /** Specialization to treat (JST const &) as (JST). */ - template - struct JSToNative - { - typedef typename TypeInfo::Type const & ResultType; - ResultType operator()( v8::Handle const & h ) const - { - typedef JSToNative Cast; - typedef typename Cast::ResultType NH; -#if 0 - NH n = Cast()( h ); - if( ! n ) - { - throw std::runtime_error("JSToNative could not get native pointer. Throwing to avoid dereferencing null!"); - } - else return *n; -#else - return Cast()(h); -#endif - } - }; - - - - /** Specialization which passes on v8 Handles as-is. */ - template - struct JSToNative > - { - typedef v8::Handle ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h; - } - }; - template - struct JSToNative const &> : JSToNative< v8::Handle > {}; - template - struct JSToNative &> : JSToNative< v8::Handle > {}; - - /** Specialization which passes on v8 local Handles as-is. */ - template - struct JSToNative > - { - typedef v8::Local ResultType; - ResultType operator()( v8::Local const & h ) const - { - return h; - } - }; - template - struct JSToNative const &> : JSToNative< v8::Local > {}; - template - struct JSToNative &> : JSToNative< v8::Local > {}; - -#if !defined(DOXYGEN) - namespace Detail - { - template - struct JSToNative_V8Type - { - /** - If h is not empty and is of the correct type - then its converted handle is returned, else - an empty handle is returned. - */ - typedef v8::Handle ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return (h.IsEmpty() || !((*h)->*IsA)()/*man, what a construct!*/) - ? v8::Handle() - : v8::Handle(V8Type::Cast(*h)); - } - }; - } -#endif - template <> - struct JSToNative > : Detail::JSToNative_V8Type< v8::Object, &v8::Value::IsObject> - {}; - template <> - struct JSToNative< v8::Handle &> : JSToNative< v8::Handle > {}; - template <> - struct JSToNative< v8::Handle const &> : JSToNative< v8::Handle > {}; - - - template <> - struct JSToNative > : Detail::JSToNative_V8Type< v8::Array, &v8::Value::IsArray> - {}; - template <> - struct JSToNative< v8::Handle &> : JSToNative< v8::Handle > {}; - template <> - struct JSToNative< v8::Handle const &> : JSToNative< v8::Handle > {}; - - template <> - struct JSToNative > : Detail::JSToNative_V8Type< v8::Function, &v8::Value::IsFunction> - {}; - template <> - struct JSToNative< v8::Handle &> : JSToNative< v8::Handle > {}; - template <> - struct JSToNative< v8::Handle const &> : JSToNative< v8::Handle > {}; - - /** - An X-to-void specialization which we cannot use in the generic - case due to the syntactic limitations of void. - */ - template <> - struct JSToNative - { - typedef void ResultType; - ResultType operator()( ... ) const - { - return; - } - }; - - /** - A very arguable specialization which tries to convert a JS - value to native (void*) via v8::External. - */ - template <> - struct JSToNative - { - typedef void * ResultType; - /** - If h is-a External then this return its value, else it - return 0. - - We could arguably check if it is an object and has - internal fields, and return the first one, but i think - that would be going too far considering how arguably the - v8-to-(void *) conversion is in the first place. - */ - ResultType operator()( v8::Handle const & h ) const - { - if( h.IsEmpty() || ! h->IsExternal() ) return 0; - return v8::External::Cast(*h)->Value(); - } - }; - /** - A very arguable specialization which tries to convert a JS - value to native (void*) via v8::External. - */ - template <> - struct JSToNative - { - typedef void const * ResultType; - /** - If h is-a External then this return its value, else it - return 0. - - We could arguably check if it is an object and has - internal fields, and return the first one, but i think - that would be going to far considering how arguably the - v8-to-(void *) conversion is in the first place. - */ - ResultType operator()( v8::Handle const & h ) const - { - if( h.IsEmpty() || ! h->IsExternal() ) return 0; - return v8::External::Cast(*h)->Value(); - } - }; - - /** - A concrete JSToNative implementation intended to be used as the - base class for JSToNative implementations where T is "bound - to JS" in JS objects, and those JS objects meet the following - requirements: - - - They have exactly InternalFieldCount internal fields. - - - They have a C/C++-native object of type (T*) (or convertible - to type (T*)) stored as a v8::External value in the JS-object - internal field number InternalFieldIndex. - - Note that the InternalFieldCount check is only a quick - sanity-checking mechanism, and is by far not foolproof because - the majority of JS-bound native types only use 1 internal - field. - - It is illegal for InternalFieldCount to be equal to or smaller - than InternalFieldIndex, or for either value to be - negative. Violating these invariants results in a compile-time - assertion. - - If an object to convert matches the field specification but - is not a T (or publically derived from T) then results are - undefined (this could lead to a crash at runtime). - - There are cases where very-misbehaving JS code can force this - particular conversion algorithm to mis-cast the native. While - they have never been seen "in the wild", they can - theoretically happen. If that bothers you, and you want to be - able to sleep soundly at night, use - JSToNative_ObjectWithInternalFieldsTypeSafe instead of this - class. - - @see JSToNative_ObjectWithInternalFieldsTypeSafe - - */ - template - struct JSToNative_ObjectWithInternalFields - { - private: - typedef char AssertIndexRanges - [tmp::Assertion< - (InternalFieldIndex>=0) - && (InternalFieldCount>0) - && (InternalFieldIndex < InternalFieldCount) - >::Value - ? 1 : -1]; - public: - typedef typename TypeInfo::NativeHandle ResultType; - /** - If h is-a Object and it meets the requirements described - in this class' documentation, then this function returns - the result of static_cast(void*), using the (void*) - extracted from the Object. If the requirements are not met - then NULL is returned. - - See the class docs for more details on the requirements - of the passed-in handle. - - If SearchPrototypeChain is true and this object does not - contain a native then the prototype chain is searched. - This is generally only required when bound types are - subclassed. - */ - ResultType operator()( v8::Handle const & h ) const - { - if( h.IsEmpty() || ! h->IsObject() ) return NULL; - else - { - void * ext = NULL; - v8::Handle proto(h); - while( !ext && !proto.IsEmpty() && proto->IsObject() ) - { - v8::Local const & obj( v8::Object::Cast( *proto ) ); - ext = (obj->InternalFieldCount() != InternalFieldCount) - ? NULL - : obj->GetPointerFromInternalField( InternalFieldIndex ); - if( ! ext ) - { - if( !SearchPrototypeChain ) break; - else proto = obj->GetPrototype(); - } - } - return ext ? static_cast(ext) : NULL; - } - } - }; - - /** - A concrete JSToNative implementation (to be used as a base class) - which does a type-safe conversion from JS to (T*). - - T is the bound native type. A pointer of this type is expected - in the object-internal field specified by ObjectFieldIndex. - - Each value to be converted is checked for an internal field - (of type v8::External) at the index specified by - TypeIdFieldIndex. If (and only if) that field contains a - v8::External which holds the value TypeID is the conversion - considered legal. If they match but the native value stored - in field ObjectFieldIndex is NOT-a-T then results are - undefined. Note that the TypeID value is compared by pointer - address, not by its byte contents (which may legally be - NULL). - - If SearchPrototypeChain is true and the passed-in object - contains no native T then the prototype chain is checked - recursively. This is normally only necessary if the native - type is allowed to be subclasses from JS code (at which point - the JS 'this' is not the same exact object as the one - holding the native 'this' pointer, and we need to search the - prototype chain). - - For this all to work: the class-binding mechanism being used - by the client must store the TypeID value in all new - JS-created instances of T by calling SetInternalField( - TypeIdFieldIndex, theTypeID ) and store the native object - pointer in the field internal field ObjectFieldIndex. And - then they should do: - - @code - // in the cvv8 namespace: - template <> - struct JSToNative : - JSToNative_ObjectWithInternalFieldsTypeSafe - {}; - @endcode - - At which point CastFromJS() will take advantage of this - type check. - - - The real docs end here. What follows is pseudorandom blather... - - Theoretically (i haven't tried this but i know how the - underlying code works), it is possible for script code to - create a condition which will lead to an invalid cast if the - check performed by this class (or something equivalent) is - _not_ performed: - - @code - var x = new Native1(); - var y = new Native2(); - // assume y.someFunc and x.otherFunc are both bound to native functions - y.someFunc = x.otherFunc; - y.someFunc( ... ); // here is where it will likely end badly - @endcode - - When y.someFunc() is called, JS will look for a 'this' object of - type Native1, not Native2, because the type information related to - the conversion is "stored" in the callback function itself, not in - the native object. (This is a side-effect of us using templates to - create InvocationCallback implementations.) It will not find a - Native1, but it might (depending on how both classes are bound to - JS) find a Native2 pointer and _think_ it is a Native1. And by - "think it is" i mean "it will try to cast it to," but the cast is - illegal in that case. In any case it would be bad news. - - The check performed by this class can catch that condition - (and similar ones) and fail gracefully (i.e. returning a - NULL instead of performing an illegal cast). - */ - template - struct JSToNative_ObjectWithInternalFieldsTypeSafe - { - private: - typedef char AssertIndexRanges - [(InternalFieldCount>=2) - && (TypeIdFieldIndex != ObjectFieldIndex) - && (TypeIdFieldIndex >= 0) - && (TypeIdFieldIndex < InternalFieldCount) - && (ObjectFieldIndex >= 0) - && (ObjectFieldIndex < InternalFieldCount) - ? 1 : -1]; - public: - typedef typename TypeInfo::NativeHandle ResultType; - /** - If h is-a Object and it meets the requirements described - in this class' documentation, then this function returns - the result of static_cast(void*), using the (void*) - extracted from the Object. If the requirements are not met - then NULL is returned. - - See the class docs for more details on the requirements - of the passed-in handle. - - If SearchPrototypeChain is true and the object does not - contain a native then the prototype chain is searched - recursively. This is generally only required when bound - types are subclassed from JS code. - */ - ResultType operator()( v8::Handle const & h ) const - { - if( h.IsEmpty() || ! h->IsObject() ) return NULL; - else - { - void const * tid = NULL; - void * ext = NULL; - v8::Handle proto(h); - while( !ext && !proto.IsEmpty() && proto->IsObject() ) - { - v8::Local const & obj( v8::Object::Cast( *proto ) ); - tid = (obj->InternalFieldCount() != InternalFieldCount) - ? NULL - : obj->GetPointerFromInternalField( TypeIdFieldIndex ); - ext = (tid == TypeID) - ? obj->GetPointerFromInternalField( ObjectFieldIndex ) - : NULL; - if( ! ext ) - { - if( ! SearchPrototypeChain ) break; - else proto = obj->GetPrototype(); - } - } - return ext ? static_cast(ext) : NULL; - } - } - }; - - /** Specialization to convert JS values to int16_t. */ - template <> - struct JSToNative - { - typedef int16_t ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? static_cast(h->Int32Value()) - : 0; - } - }; - - /** Specialization to convert JS values to uint16_t. */ - template <> - struct JSToNative - { - typedef uint16_t ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? static_cast(h->Int32Value()) - : 0; - } - }; - - /** Specialization to convert JS values to int32_t. */ - template <> - struct JSToNative - { - typedef int32_t ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? h->Int32Value() - : 0; - } - }; - - /** Specialization to convert JS values to uint32_t. */ - template <> - struct JSToNative - { - typedef uint32_t ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? static_cast(h->Uint32Value()) - : 0; - } - }; - - - /** Specialization to convert JS values to int64_t. */ - template <> - struct JSToNative - { - typedef int64_t ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? static_cast(h->IntegerValue()) - : 0; - } - }; - - /** Specialization to convert JS values to uint64_t. */ - template <> - struct JSToNative - { - typedef uint64_t ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? static_cast(h->IntegerValue()) - : 0; - } - }; - - /** Specialization to convert JS values to double. */ - template <> - struct JSToNative - { - typedef double ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->IsNumber() - ? h->NumberValue() - : 0; - } - }; - - /** Specialization to convert JS values to bool. */ - template <> - struct JSToNative - { - typedef bool ResultType; - ResultType operator()( v8::Handle const & h ) const - { - return h->BooleanValue(); - } - }; - - /** Specialization to convert JS values to std::string. */ - template <> - struct JSToNative - { - typedef std::string ResultType; - ResultType operator()( v8::Handle const & h ) const - { - static const std::string emptyString; - v8::String::Utf8Value const utf8String( h ); - const char* s = *utf8String; - return s - ? std::string(s, utf8String.length()) - : emptyString; - } - }; - - /** - Specialization necessary to avoid incorrect default behaviour - for this special case. - - Reminder to self: we'll need a specialization like this any - time we want to use a type which is returned by VALUE from - JSToNative() and might be passed as a const reference as a - function argument type. The vast majority of bound native - types are bound internally as pointers (and don't need a - specialization like this one), whereas the std::string - conversion uses value semantics to simplify usage. - */ - template <> - struct JSToNative : public JSToNative {}; - -#if 0 // leave this unused code here for the sake of the next guy who tries to re-add it - /** - Nonono! This will Cause Grief when used together with CastFromJS() - because the returned pointer's lifetime cannot be guaranteed. - See ArgCaster for more details on the problem. - */ - template <> - struct JSToNative - { - public: - typedef char const * ResultType; - ResultType operator()( v8::Handle const & h ); - }; -#else -#if 0 // it turns out no current (20110627) code uses this. -// We might want to leave it in b/c that will cause compile errors -// in some use cases rather than link errors ("undefined ref..."). - /** Not great, but a happy medium. */ - template <> - struct JSToNative : JSToNative {}; -#endif -#endif - - namespace Detail - { - /** A kludge placeholder type for a ulong-is-not-uint64 - condition on some platforms. - - T is ignored, but is required to avoid class-redefinition - errors for the templates using this class. - */ - template - struct UselessConversionType - { - }; - } - - /** - This specialization is a kludge/workaround for use in cases - where (unsigned long int) is: - - 1) The same type as the platform's pointer type. - 2) Somehow NOT the same as one of the standard uintNN_t types. - 3) Used in CastToJS() or CastFromJS() calls. - - If ulong and uint64 are the same type then this specialization - is a no-op (it generates a converter for a type which will - never be converted), otherwords it performs a numeric conversion. - */ - template <> - struct NativeToJS< tmp::IfElse< tmp::SameType::Value, - Detail::UselessConversionType, - unsigned long >::Type > - : Detail::NativeToJS_int_big - { - }; - - /** - This is a kludge/workaround for use in cases where (unsigned - long int) is: - - 1) The same type as the platform's pointer type. - 2) Somehow NOT the same as one of the standard uintNN_t types. - 3) Used in CastToJS() or CastFromJS() calls. - - If ulong and uint64 are the same type then this specialization - is a no-op (it generates a converter for a type which will - never be converted), otherwords it performs a numeric - conversion. - */ - template <> - struct JSToNative< tmp::IfElse< - tmp::SameType::Value, - Detail::UselessConversionType, - unsigned long >::Type > - : JSToNative - { - }; - - /** - See the equivalent NativeToJS kludge for unsigned long. - */ - template <> - struct NativeToJS< tmp::IfElse< tmp::SameType::Value, - Detail::UselessConversionType, - long >::Type > - : Detail::NativeToJS_int_big - { - }; - - /** - See the equivalent JSToNative kludge for unsigned long. - */ - template <> - struct JSToNative< tmp::IfElse< - tmp::SameType::Value, - Detail::UselessConversionType, - long >::Type > : JSToNative - { - }; - -#if CVV8_CONFIG_HAS_LONG_LONG - /** - See the equivalent JSToNative kludge for unsigned long. - - Added 20100606 to please the sqlite3 plugin, where sqlite3_int64 - collides with (long long) on some platforms and causes an invalid - conversion compile-time error. - */ - template <> - struct JSToNative< tmp::IfElse< - tmp::SameType::Value, - Detail::UselessConversionType, - long long int >::Type > : JSToNative - { - }; - /** - See the equivalent JSToNative kludge for unsigned long. - - Added 20101126 to please the sqlite3 plugin, where - sqlite3_int64 collides with (long long) on some platforms and - causes a link-time error. - */ - template <> - struct NativeToJS< tmp::IfElse< tmp::SameType::Value, - Detail::UselessConversionType, - long long int >::Type > - : Detail::NativeToJS_int_big - { - }; -#endif - - - /** - Converts h to an object of type NT, using JSToNative to do - the conversion. - */ - template - typename JSToNative::ResultType CastFromJS( v8::Handle const & h ) - { - typedef JSToNative F; - return F()( h ); - } - - /** Convenience instance of JSToNative. */ - static const JSToNative JSToInt16 = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToUInt16 = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToInt32 = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToUInt32 = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToInt64 = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToUInt64 = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToDouble = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToBool = JSToNative(); - /** Convenience instance of JSToNative. */ - static const JSToNative JSToStdString = JSToNative(); - - /** - A utility to add properties to a JS v8::Object or v8::ObjectTemplate. - ObjectType must be either v8::Object or v8::ObjectTemplate. It - _might_ work in limited context with v8::Array, but that is untested. - ObjectType is intended to be v8::Object or v8::ObjectTemplate, - but Object subclasses, e.g. v8::Array and v8::Function, "should" work - as well. - - It is intended to be used like this: - - \code - v8::Handle obj = ...; - ObjectPropSetter set(obj); - set("propOne", CastToJS(32) ) - ("propTwo", ... ) - (32, ... ) - ("func1", anInvocationCallback ) - ; - \endcode - */ - template ::Value, - v8::Handle, - v8::Handle - >::Type - > - class ObjectPropSetter - { - private: - v8::Handle const target; - public: - /** - Initializes this object to use the given array - as its append target. Results are undefined if - target is not a valid Object. - */ - explicit ObjectPropSetter( v8::Handle< ObjectType > const & obj ) :target(obj) - {} - ~ObjectPropSetter(){} - - - /** - Adds an arbtirary property to the target object. - */ - inline ObjectPropSetter & Set( KeyType const & key, v8::Handle const & v ) - { - this->target->Set(key->ToString(), CastToJS(v)); - return *this; - } - /** - Adds an arbtirary property to the target object. - */ - inline ObjectPropSetter & Set( char const * key, v8::Handle const & v ) - { - this->target->Set( v8::String::New(key), CastToJS(v)); - return *this; - } - - /** - Adds an arbitrary property to the target object using - CastToJS(v). - */ - template - inline ObjectPropSetter & operator()( KeyType const & key, T const & v ) - { - this->target->Set(key, CastToJS(v)); - return *this; - } - - /** - Adds a numeric property to the target object. - */ - template - inline ObjectPropSetter & operator()( int32_t ndx, T const & v ) - { - return this->Set( v8::Integer::New(ndx), CastToJS(v) ); - } - - /** - Adds a string-keyed property to the target object. - Note that if key is NULL, the v8::String constructor - will crash your app. (Good luck with that!) - */ - template - inline ObjectPropSetter & operator()( char const * key, T const & v ) - { - return this->Set( v8::String::New(key), CastToJS(v) ); - } - - - /** - Adds the given function as a member of the target object. - */ - inline ObjectPropSetter & operator()( char const * name, v8::InvocationCallback pf ) - { - return this->Set( name, v8::FunctionTemplate::New(pf)->GetFunction() ); - } - - /** - Returns this object's JS object. - */ - v8::Handle< v8::Object > Object() const - { - return this->target; - } - }; - - /** - NativeToJS classes which act on list types compatible with the - STL can subclass this to get an implementation. - */ - template - struct NativeToJS_list - { - v8::Handle operator()( ListT const & li ) const - { - typedef typename ListT::const_iterator IT; - IT it = li.begin(); - const size_t sz = li.size(); -#if 1 - v8::Handle rv( v8::Array::New( static_cast(sz) ) ); - for( int i = 0; li.end() != it; ++it, ++i ) - { - rv->Set( v8::Integer::New(i), CastToJS( *it ) ); - } - return rv; -#else - ObjectPropSetter app(Array::New( static_cast(sz) )); - for( int32_t i = 0; li.end() != it; ++it, ++i ) - { - app( i, CastToJS( *it ) ); - } - return app.Object(); -#endif - } - }; - - /** Partial specialization for std::list<>. */ - template - struct NativeToJS< std::list > : NativeToJS_list< std::list > {}; - /** Partial specialization for std::vector<>. */ - template - struct NativeToJS< std::vector > : NativeToJS_list< std::vector > {}; - - /** - NativeToJS classes which act on map types compatible with the - STL can subclass this to get an implementation. - - Both the key and mapped types of the given Map Type must be - converitible to v8 types using CastToJS(). - */ - template - struct NativeToJS_map - { - v8::Handle operator()( MapT const & li ) const - { - typedef typename MapT::const_iterator IT; - IT it( li.begin() ); - v8::Handle rv( v8::Object::New() ); - for( int i = 0; li.end() != it; ++it, ++i ) - { - rv->Set( CastToJS( (*it).first ), CastToJS( (*it).second ) ); - } - return rv; - } - }; - - /** Partial specialization for std::map<>. */ - template - struct NativeToJS< std::map > : NativeToJS_map< std::map > {}; - - /** - A base class for JSToNative - specializations. ListT must be compatible with std::list and - std::vector, namely: - - - Must support push_back( ListT::value_type ). - - - Must define value_type typedef or the second template - argument must be specified for this template. - - It is technically legal for ValueType to differ from - ListT::value_type if - ListT::push_back(JSToNative::ResultType) is - legal. e.g. if ListT is std::vector and we want to - truncate the values we could use, e.g. int32_t as the - ValueType. - */ - template - struct JSToNative_list - { - typedef ListT ResultType; - /** - Converts jv to a ListT object. - - If jv->IsArray() then the returned object is populated from - jv, otherwise the returned object is empty. Since it is - legal for an array to be empty, it is not generically - possible to know if this routine got an empty Array object - or a non-Array object. - */ - ResultType operator()( v8::Handle jv ) const - { - //typedef typename ListT::value_type VALT; - typedef ValueType VALT; - ListT li; - if( jv.IsEmpty() || ! jv->IsArray() ) return li; - v8::Handle ar( v8::Array::Cast(*jv) ); - uint32_t ndx = 0; - for( ; ar->Has(ndx); ++ndx ) - { - li.push_back( CastFromJS( ar->Get(v8::Integer::New(ndx)) ) ); - } - return li; - } - }; - - /** Partial specialization for std::list<>. */ - template - struct JSToNative< std::list > : JSToNative_list< std::list > {}; - - /** Partial specialization for std::vector<>. */ - template - struct JSToNative< std::vector > : JSToNative_list< std::vector > {}; - -#if 0 // untested code - /** - UNTESTED! - - Intended as a base class for JSToNative specializations - which proxy a std::map-like map. - */ - template - struct JSToNative_map - { - typedef MapT ResultType; - /** - Converts jv to a MapT object. - - If jv->IsObject() then the returned object is populated from - jv, otherwise the returned object is empty. Since it is - legal for an object to be empty, it is not generically - possible to know if this routine got an empty Object - or a non-Object handle. - */ - ResultType operator()( v8::Handle jv ) const - { - typedef ValueType VALT; - MapT map; - if( jv.IsEmpty() || ! jv->IsObject() ) return map; - Local obj( Object::Cast(*jv) ); - Local ar( obj->GetPropertyNames() ); - uint32_t ndx = 0; - for( ; ar->Has(ndx); ++ndx ) - { - Local const & k = ar->Get(Integer::New(ndx)); - if( ! obj->HasRealNamedProperty(k) ) continue; - map[CastFromJS(k)] = CastFromJS(obj->Get(k)); - } - return map; - } - }; -#endif - /** - A utility class for building up message strings, most notably - exception messages, using a mixture of native and JS message - data. - - It is used like a std::ostream: - - @code - StringBuffer msg; - msg << "Could not set property " - << "'" << propName - <<"' on object " << myJSObject << '!'; - return v8::ThrowException(msg.toError()); - // or: - return Toss(msg); - @endcode - */ - class StringBuffer - { - private: - std::ostringstream os; - public: - /** - Initializes the message stream. - */ - StringBuffer() : os() - { - } - StringBuffer(StringBuffer const & other) : os(other.os.str()) - { - } - StringBuffer & operator=(StringBuffer const & other) - { - this->os.str(other.os.str()); - return *this; - } - - /** - Empties out the message buffer. This invalidates any value - returned from previous calls to the (char const *) - operator. - */ - inline void Clear() - { - this->os.str(""); - } - - /** - Returns a copy of the current message content. - */ - inline std::string Content() const - { - return this->os.str(); - } - - /** - Converts the message state to a JS string. - */ - inline operator v8::Handle() const - { - return CastToJS( this->os.str() ); - } - - /** - Converts the message state to a v8::String (for use - with v8::Exception::Error() and friends). - */ - inline operator v8::Handle() const - { - std::string const & str(this->os.str()); - char const * cstr = str.c_str(); - return v8::String::New( cstr ? cstr : "", cstr ? str.size() : 0 ); - } - - /** - Appends to the message using CastFromJS(t) - */ - template - inline StringBuffer & operator<<( v8::Handle const & t ) - { - this->os << CastFromJS( t ); - return *this; - } - /** - Appends to the message using CastFromJS(t) - - Reminder to self: if this function is changed to take - a const reference instead of a copy, we get overload - ambiguity errors in some contexts. See: - - http://code.google.com/p/v8-juice/issues/detail?id=19 - - (And thanks to Feng Fillano for reporting and localizing - the problem.) - */ - template - inline StringBuffer & operator<<( v8::Local const t ) - { - this->os << CastFromJS( t ); - return *this; - } - - /** - Appends t to the message via std::ostream<<. - */ - template - inline StringBuffer & operator<<( T const t) - { - this->os << t; - return *this; - } - - /** - Returns this buffer's value wrapped in - a JS Error object. - */ - v8::Local toError() const - { - return v8::Exception::Error(*this); - } - }; - - /** Outputs sb.Content() to os and returns os. */ - inline std::ostream & operator<<( std::ostream & os, StringBuffer const & sb ) - { - return os << sb.Content(); - } - - - /** - Requi - "Lexically casts" msg to a string and throws a new JS-side - Error. ValT may be any type which can be sent to StringBuffer's - ostream operator. - - The return value is the result of calling - v8::ThrowException() (Undefined except in the face of a - serious internal error like OOM, i'm told by the v8 devs). - */ - template - inline v8::Handle Toss( ValT const & msg ) - { - return v8::ThrowException((StringBuffer() << msg).toError()); - } - - /** - Overload to avoid an ambiguity (and it's more efficient than - the default impl). - */ - inline v8::Handle Toss( char const * msg ) - { - return v8::ThrowException(v8::Exception::Error(v8::String::New( msg ? msg : "Unspecified error."))); - } - - /** - Eqivalent to v8::ThrowException(err). Note that if err is not an - Error object, the JS side will not get an Error object. e.g. if err - is-a String then the JS side will see the error as a string. - - The reason this does not convert err to an Error is because the v8 - API provides no way for us to know if err is already an Error object. - This function is primarily intended to be passed the results of - CastToJS(std::exception), which generates Error objects. - */ - inline v8::Handle Toss( v8::Handle const & err ) - { - return v8::ThrowException(err); - } - - /** - Efficiency overload. - */ - inline v8::Handle Toss( StringBuffer const & msg ) - { - return v8::ThrowException(msg.toError()); - } - /** - Like Toss(Handle), but converts err to a string and creates an - Error object, which is then thrown. - */ - inline v8::Handle TossAsError( v8::Handle const & err ) - { - return Toss(v8::Exception::Error(err->ToString())); - } - - /** - ArgCaster is a thin wrapper around CastFromJS(), and primarily - exists to give us a way to convert JS values to (char const *) - for purposes of passing them to native functions. The main - difference between this type and JSToNative is that this - interface explicitly allows for the conversion to be stored by - an instance of this type. That allows us to get more lifetime - out of converted values in certain cases (namely (char const*)). - - The default implementation is suitable for all cases which - JSToNative supports, but specializations can handle some of - the corner cases which JSToNative cannot (e.g. (char const *)). - - Added 20091121. - */ - template - struct ArgCaster - { - typedef typename JSToNative::ResultType ResultType; - /** - Default impl simply returns CastFromJS(v). - Specializations are allowed to store the result of the - conversion, as long as they release it when the destruct. - See ArgCaster for an example of that. - */ - inline ResultType ToNative( v8::Handle const & v ) const - { - return CastFromJS( v ); - } - /** - To eventually be used for some internal optimizations. - */ - enum { HasConstOp = 1 }; - }; - /** - Specialization for (char const *). The value returned from - ToNative() is guaranteed to be valid as long as the ArgCaster - object is alive or until ToNative() is called again (which will - almost certainly change the pointer). Holding a pointer to the - ToNative() return value after the ArgCaster is destroyed will - lead to undefined behaviour. Likewise, fetching a pointer, then - calling ToNative() a second time, will invalidate the first - pointer. - - BEWARE OF THESE LIMITATIONS: - - 1) This will only work properly for nul-terminated strings, - and not binary data! - - 2) Do not use this to pass (char const *) as a function - parameter if that function will hold a copy of the pointer - after it returns (as opposed to copying/consuming the - pointed-to-data before it returns) OR if it returns the - pointer passed to it. Returning is a specific corner-case - of "holding a copy" for which we cannot guaranty the lifetime - at the function-binding level. - - 3) Do not use the same ArgCaster object to convert multiple - arguments, as each call to ToNative() will invalidate the - pointer returned by previous calls. - - 4) The to-string conversion uses whatever encoding - JSToNative uses. - - Violating any of those leads to undefined behaviour, and - very possibly memory corruption for cases 2 or 3. - */ - template <> - struct ArgCaster - { - private: - /** - Reminder to self: we cannot use v8::String::Utf8Value - here because at the point the bindings call ToNative(), - v8 might have been unlocked, at which point dereferencing - the Utf8Value becomes illegal. - */ - std::string val; - typedef char Type; - public: - typedef Type const * ResultType; - /** - Returns the toString() value of v unless: - - - v.IsEmpty() - - v->IsNull() - - v->IsUndefined() - - In which cases it returns 0. - - The returned value is valid until: - - - ToNative() is called again. - - This object is destructed. - */ - ResultType ToNative( v8::Handle const & v ) - { - typedef JSToNative C; - if( v.IsEmpty() || v->IsNull() || v->IsUndefined() ) - { - return 0; - } - this->val = C()( v ); - return this->val.c_str(); - } - /** - To eventually be used for some internal optimizations. - */ - enum { HasConstOp = 0 }; - }; - -#if !defined(DOXYGEN) - namespace Detail { - /** - Default (unimplemented) CtorForwarderProxy impl. A helper - for the CtorForwarder class. All specializations except - the 0-arity one are generated from script code. - */ - template >::Value > - struct CtorForwarderProxy - { - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & ); - }; - - //! Specialization for 0-arity ctors. - template - struct CtorForwarderProxy - { - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & ) - { - typedef typename TypeInfo::Type RType; - return new RType; - } - }; - //! Specialization for ctors taking (v8::Arguments const &). - template - struct CtorForwarderProxy - { - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - typedef typename TypeInfo::Type T; - return new T(argv); - } - }; - - } -#endif - /** - A utility type to help forward v8::Arguments to native - constructors. This type is intended to assist in the creation - of ctor functions for JS-bound C++ classes. - - Requirements: - - - Sig is "almost" a function-signature-style type, but - because ctors don't have a return value in the conventional - sense, we have to use a tiny workaround: Sig should be passed - in like this from client code: - - @code - typedef CtorForwarder CF; - @endcode - - - (new T(...)) must be legal, taking a number of - arguments equal to Sig's Arity. - - - All arguments to the native ctor must be convertible - using CastFromJS(). - - Example: - - @code - typedef CtorForwarder CF0; - typedef CtorForwarder CF1; - typedef CtorForwarder CF2; - typedef CtorForwarder CFAny; - @endcode - - @see CtorArityDispatcher - */ - template - struct CtorForwarder : Signature - { - typedef Signature STL; - //typedef typename tmp::AddPointer::Type ReturnType; - typedef typename STL::ReturnType ReturnType; - /** - If (argv.Length()>=Arity) or Arity is less than 0, - then the constructor is called with Arity arguments - (if it >=0) or with 1 v8::Arguments parameter (for Arity<0). - - Returns the result of (new Type(...)), transfering ownership - to the caller. - - May propagate native exceptions. - */ - static ReturnType Call( v8::Arguments const & argv ) - { - enum { Arity = sl::Arity< STL >::Value }; - typedef Detail::CtorForwarderProxy Proxy; - return Proxy::Call( argv ); - } - }; - -#if !defined(DOXYGEN) - namespace Detail - { - - /** - Internal dispatch routine. CTOR _must_ be a CtorForwarder implementation - (or interface-compatible). - */ - template - struct CtorFwdDispatch - { - typedef typename TypeInfo::NativeHandle ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - return CTOR::Call( argv ); - } - }; - /** - Internal dispatch end-of-list routine. - */ - template - struct CtorFwdDispatch - { - typedef typename TypeInfo::NativeHandle ReturnType; - static ReturnType Call( v8::Arguments const & ) - { - return 0; - } - }; - /** - Internal type to dispatch a v8::Arguments list to one of - several a bound native constructors, depending on on the - argument count. - - List MUST be a Signature< ... > containing ONLY - CtorFowarder types (or compatible). - */ - template - struct CtorFwdDispatchList - { - typedef typename TypeInfo::NativeHandle ReturnType; - /** - Tries to dispatch Arguments to one of the constructors - in the List type, based on the argument count. - */ - static ReturnType Call( v8::Arguments const & argv ) - { - typedef typename List::Head CTOR; - typedef typename List::Tail Tail; - enum { Arity = (0==sl::Index::Value) - ? -1 : sl::Length::Value - }; - return ( (Arity < 0) || (Arity == argv.Length()) ) - ? CtorFwdDispatch< T, CTOR >::Call(argv ) - : CtorFwdDispatchList::Call(argv); - } - }; - /** - End-of-list specialization. - */ - template - struct CtorFwdDispatchList - { - typedef typename TypeInfo::NativeHandle ReturnType; - /** Writes an error message to errmsg and returns 0. */ - static ReturnType Call( v8::Arguments const & argv ) - { - StringBuffer msg; - msg << "No native constructor was defined for "<, - CtorForwarder, - CtorForwarder, - CtorForwarder - )> Ctors; - @endcode - - All entries in the typelist must be interface-compatible with - CtorForwarder. No two entries should have the same number - of arguments with one exception: an InvocationCallback-like - function taking (v8::Arguments const &) can be used as a - catch-all for any number of arguments. If used, it must be - the LAST entry because it will always match any argument - count (and will therefore trump any which (would) come after - it. - - The ctors are dispatched based solely on the argument count, - not their types. The first one with a matching arity - is called. - - IN THEORY (untested), the factories passed in the list may - legally return a type publically derived from - CtorList::ReturnType. - */ - template - struct CtorArityDispatcher - { - typedef typename CtorList::ReturnType RT; - typedef typename TypeInfo::NativeHandle NativeHandle; - static NativeHandle Call( v8::Arguments const & argv ) - { - typedef typename tmp::PlainType::Type Type; - typedef Detail::CtorFwdDispatchList Proxy; - return Proxy::Call( argv ); - } - }; - -} // namespaces - - -#endif /* CODE_GOOGLE_COM_P_V8_CONVERT_CORE_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/detail/doxygen_hack.hpp b/vendor/libv8-convert/cvv8/detail/doxygen_hack.hpp deleted file mode 100644 index 85778705d..000000000 --- a/vendor/libv8-convert/cvv8/detail/doxygen_hack.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/** @file doxygen_hack.hpp - - doxygen REFUSES to document class templates i forward-decl, even when - adding "@class" to the docs. Being the doc-pedant that i am, i felt - compelled to work around that. With gcc we can add an empty body to - those classes but MSVC doesn't like it. So we leave it out unless - doxygen is building, and then doxygen needs to be configured with: - - - ENABLE_PREPROCESSING = YES - - EXPAND_AS_DEFINED = DOXYGEN_FWD_DECL_KLUDGE - - and possibly: - - - MACRO_EXPANSION = YES - - and/or: - - - EXPAND_ONLY_PREDEF = YES -*/ -#if !defined(DOXYGEN) -# if !defined DOXYGEN_FWD_DECL_KLUDGE -# define DOXYGEN_FWD_DECL_KLUDGE -# endif -#else -# if !defined DOXYGEN_FWD_DECL_KLUDGE -# define DOXYGEN_FWD_DECL_KLUDGE {} -# endif -#endif diff --git a/vendor/libv8-convert/cvv8/detail/invocable_core.hpp b/vendor/libv8-convert/cvv8/detail/invocable_core.hpp deleted file mode 100644 index a47b3dcb8..000000000 --- a/vendor/libv8-convert/cvv8/detail/invocable_core.hpp +++ /dev/null @@ -1,2202 +0,0 @@ -#if !defined(CODE_GOOGLE_COM_V8_CONVERT_INVOCABLE_V8_HPP_INCLUDED) -#define CODE_GOOGLE_COM_V8_CONVERT_INVOCABLE_V8_HPP_INCLUDED 1 - -/** @file invocable_core.hpp - -This file houses the core-most "invocation-related" parts of the -v8-convert API. These types and functions are for converting -free and member functions to v8::InvocationCallback functions -so that they can be tied to JS objects. It relies on the -CastToJS() and CastFromJS() functions to do non-function type -conversion. - -*/ - -#include "convert_core.hpp" -#include "signature_core.hpp" - -namespace cvv8 { - -/** - A concept class, primarily for documentation and tag-type purposes. -*/ -struct InCa -{ - /** - Matches the v8::InvocationCallback interface. All function bindings - created by this framework use Call() as their class-level - InvocationCallback interface. Some bindings provide additional - overloads as well. - */ - static v8::Handle Call( v8::Arguments const & ); -}; - -/** - A tag type for use with FunctionTo and MethodTo. -*/ -struct InCaVoid : InCa {}; - - -/** - Partial specialization for v8::InvocationCallback-like functions - (differing only in their return type) with an Arity value of -1. -*/ -template -struct FunctionSignature< RV (v8::Arguments const &) > : Signature -{ - typedef RV (*FunctionType)(v8::Arguments const &); -}; - -/** - Partial specialization for v8::InvocationCallback-like non-const - member functions (differing only in their return type) with an - Arity value of -1. -*/ -template -struct MethodSignature< T, RV (v8::Arguments const &) > : Signature< RV (v8::Arguments const &) > -{ - typedef T Type; - typedef RV (T::*FunctionType)(v8::Arguments const &); -}; - -/** - Partial specialization for v8::InvocationCallback-like const member - functions (differing only in their return type) with an Arity value - of -1. -*/ -template -struct ConstMethodSignature< T, RV (v8::Arguments const &) > : Signature< RV (v8::Arguments const &) > -{ - typedef T Type; - typedef RV (T::*FunctionType)(v8::Arguments const &) const; -}; - -/** - Full specialization for InvocationCallback and - InvocationCallback-like functions (differing only by their return - type), which uses an Arity value of -1. -*/ -template -struct FunctionPtr - : FunctionSignature -{ - public: - typedef FunctionSignature SignatureType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename SignatureType::FunctionType FunctionType; - static FunctionType GetFunction() - { - return FuncPtr; - } -}; - -/** - Full specialization for InvocationCallback and - InvocationCallback-like functions (differing only by their return - type), which uses an Arity value of -1. -*/ -template -struct MethodPtr - : MethodSignature -{ - typedef MethodSignature SignatureType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename SignatureType::FunctionType FunctionType; - static FunctionType GetFunction() - { - return FuncPtr; - } -}; - -/** - Full specialization for InvocationCallback and - InvocationCallback-like functions (differing only by their return - type), which uses an Arity value of -1. -*/ -template -struct ConstMethodPtr - : ConstMethodSignature -{ - typedef ConstMethodSignature SignatureType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename SignatureType::FunctionType FunctionType; - static FunctionType GetFunction() - { - return FuncPtr; - } -}; - -#if !defined(DOXYGEN) -namespace Detail { - /** - A sentry class which instantiates a v8::Unlocker - if the boolean value is true or is a no-op if it is false. - */ - template struct V8Unlocker {}; - - /** - Equivalent to v8::Unlocker. - */ - template <> - struct V8Unlocker : v8::Unlocker - { - }; - - -} -#endif - -/** - A metatemplate which we can use to determine if a given type - is "safe" to use in conjunction with v8::Unlock. - - We optimistically assume that most types are safe and - add specializations for types we know are not safe, e.g. - v8::Handle and v8::Arguments. - - Specializations of this type basically make up a collective - "blacklist" of types which we know are not legal to use unless - v8 is locked by our current thread. As new problematic types are - discovered, they can be added to the blacklist by introducing a - specialization of this class. -*/ -template -struct IsUnlockable : tmp::BoolVal {}; -template -struct IsUnlockable : IsUnlockable {}; -template -struct IsUnlockable : IsUnlockable {}; -template -struct IsUnlockable : IsUnlockable {}; -template -struct IsUnlockable : IsUnlockable {}; - -/** - Explicit instantiation to make damned sure that nobody - re-sets this one. We rely on these semantics for - handling FunctionSignature like Const/MethodSignature - in some cases. -*/ -template <> -struct IsUnlockable : tmp::BoolVal {}; - -/* - Todo?: find a mechanism to cause certain highly illegal types to - always trigger an assertion... We could probably do it by - declaring but not definiting JSToNative/NativeToJS - specialializations. -*/ -template <> -struct IsUnlockable : tmp::BoolVal {}; - -template <> -struct IsUnlockable : tmp::BoolVal {}; - -template -struct IsUnlockable< v8::Handle > : tmp::BoolVal {}; - -template -struct IsUnlockable< v8::Persistent > : tmp::BoolVal {}; - -template -struct IsUnlockable< v8::Local > : tmp::BoolVal {}; - -template <> -struct IsUnlockable : tmp::BoolVal {}; - -/** - Given a tmp::TypeList-compatible type list, this metafunction's - Value member evalues to true if IsUnlockable::Value is - true for all types in TList, else Value evaluates to false. - As a special case, an empty list evaluates to true because in this - API an empty list will refer to a function taking no arguments. -*/ -template -struct TypeListIsUnlockable : tmp::BoolVal< - IsUnlockable::Value && TypeListIsUnlockable::Value - > -{ -}; - -//! End-of-typelist specialization. -template <> -struct TypeListIsUnlockable< tmp::NilType > : tmp::BoolVal -{}; -/** - Given a Signature, this metafunction's Value member - evaluates to true if: - - - IsUnlockable::Value is true and... - - - IsUnlockable::Value is true (only relavent - for Const/MethodSignature, not FunctionSignature) and... - - - TypeListIsUnlockable< SigTList >::Value is true. - - If the value is true, the function signature has passed the most - basic check for whether or not it is legal to use v8::Unlocker - to unlock v8 before calling a function with this signature. Note - that this is a best guess, but this code cannot know - app-specific conditions which might make this guess invalid. - e.g. if a bound function itself uses v8 and does not explicitly - acquire a lock then the results are undefined (and will very - possibly trigger an assertion in v8, killing the app). Such - things can and do happen. If you're lucky, you're building - against a debug version of libv8 and its assertion text will - point you directly to the JS code which caused the assertion, - then you can disable unlocking support for that binding. - - If you want to disable unlocking for all bound members of a given - class, create an IsUnlockable specialization whos Value - member evaluates to false. Then no functions/methods using that - class will cause this metafunction to evaluate to true. - - Note that FunctionToInCa, Const/MethodToInCa, etc., are all - Signature subclasses, and can be used directly with - this template. - - Example: - - @code - // This one can be unlocked: - typedef FunctionSignature< int (int) > F1; - // SignatureIsUnlockable::Value == true - - // This one cannot because it contains a v8 type in the arguments: - typedef FunctionSignature< int (v8::Handle) > F2; - // SignatureIsUnlockable::Value == false - @endcode - - For Const/MethodToInCa types, this check will also fail if - IsUnlockable< SigTList::Context >::Value is false. -*/ -template -struct SignatureIsUnlockable : tmp::BoolVal< - IsUnlockable::Value && - IsUnlockable::Value && - IsUnlockable::Value && - SignatureIsUnlockable::Value - > {}; -//! End-of-list specialization. -template <> -struct SignatureIsUnlockable : tmp::BoolVal {}; - -/** - Internal exception type to allow us to differentiate - "no native 'this' pointer found" errors from all other - exceptions. It is thrown by the CallNative() functions - of various JS-to-Native function forwarders. -*/ -struct MissingThisException -{ -protected: - StringBuffer msg; - template - void init() - { - this->msg << "CastFromJS<"<< TypeName::Value - << ">() returned NULL. Throwing to avoid " - << "dereferencing a NULL pointer!"; - } - MissingThisException() {} -public: - /** - Returns the exception message text, which does not change - after construction. - */ - StringBuffer const & Buffer() const { return msg; } -}; - - -/** - This special-case convenience form of Toss() triggers a JS-side - exception containing an English-language message explaining that - CastFromJS() failed, i.e. the native 'this' pointer for a bound - native T object could not be found. It uses TypeName::Value as the - class' name. - - This is primarily intended for use in two cases: - - - Internally in the cvv8 binding mechanisms. - - - In client code when binding non-member functions as JS-side methods of - native objects. - - Returns the result of v8::ThrowException(...). - - Example: - - @code - v8::Handle my_bound_func( v8::Arguments const & argv ) { - T * self = CastFromJS( argv.This() ); - if( ! self ) { - return TossMissingThis(); - } - ... - } - @endcode - - BUG: TypeName::Value is NOT used here because... If we instantiate - TypeName<> from here then we require a value for TypeName<>::Value or we - break FunctorTo and friends (because TypeName'ing functors isn't always - possible). The problem with that is that i want to use TypeName::Value's - address as a type key and that can't work cross-DLL on Windows (and - possibly other platforms) if we have a default value for TypeName::Value. - i hope to eventually find a solution which is both cross-platform and - allows us to invoke TypeName::Value from here. -*/ -template -v8::Handle TossMissingThis() -{ - return Toss(StringBuffer()<<"CastFromJS<" -#if 0 - <::Value -#else - <<'T' -#endif - <<">() returned NULL! Cannot find 'this' pointer!"); -} - -#if !defined(DOXYGEN) -namespace Detail { -/** Temporary internal macro. Undef'd at the end of this file. */ -#define HANDLE_PROPAGATE_EXCEPTION catch( MissingThisException const & ){ return TossMissingThis(); } \ - catch(...){ throw; } (void)0/* (void)0 is a hack to help emacs' indentation out!*/ - - /** - A MissingThisException type holding generic - message text which references TypeName::Value - as being the problematic class. - */ - template - struct MissingThisExceptionT : MissingThisException - { - MissingThisExceptionT() - { - this->init(); - } - }; - -/** - Temporary internal macro to trigger a static assertion if unlocking - support is requested but cannot be implemented for the given - wrapper due to constraints on our use of v8 when it is unlocked. - - This differs from ASSERT_UNLOCK_SANITY_CHECK in that this is intended - for use with functions which we _know_ (while coding, as opposed to - finding out at compile time) are not legally unlockable. -*/ -#define ASSERT_UNLOCKV8_IS_FALSE typedef char ThisSpecializationCannotUseV8Unlocker[!UnlockV8 ? 1 : -1] -/** - Temporary internal macro to trigger a static assertion if: - UnlockV8 is true and SignatureIsUnlockable::Value is false. - This is to prohibit that someone accidentally enables locking - when using a function type which we know (based on its - signature's types) cannot obey the (un)locking rules. -*/ -#define ASSERT_UNLOCK_SANITY_CHECK typedef char AssertCanEnableUnlock[ \ - !UnlockV8 ? 1 : (SignatureIsUnlockable< SignatureType >::Value ? 1 : -1) \ - ] - - template >::Value > - struct FunctionForwarder DOXYGEN_FWD_DECL_KLUDGE; - - template - struct FunctionForwarder - : FunctionSignature - { - public: - typedef FunctionSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - return (RV) func(argv); - } - - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - - ASSERT_UNLOCKV8_IS_FALSE; - typedef char AssertArity[ sl::Arity::Value == -1 ? 1 : -1]; - }; - - //! Reminder to self: we really do need this specialization for some cases. - template - struct FunctionForwarder - : FunctionForwarder - {}; - - template - struct FunctionForwarder<0,Sig, UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename SignatureType::FunctionType FunctionType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return func(); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - ASSERT_UNLOCK_SANITY_CHECK; - typedef char AssertArity[ sl::Arity::Value == 0 ? 1 : -1]; - }; - - template >::Value> - struct FunctionForwarderVoid DOXYGEN_FWD_DECL_KLUDGE; - - template - struct FunctionForwarderVoid<0,Sig, UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef typename SignatureType::ReturnType ReturnType; - typedef Sig FunctionType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)func() - /* the explicit cast there is a workaround for the RV==void - case. It is a no-op for other cases, since the return value - is already RV. Some compilers (MSVC) don't allow an explicit - return of a void expression without the cast. - */; - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - ASSERT_UNLOCK_SANITY_CHECK; - typedef char AssertArity[ sl::Arity::Value == 0 ? 1 : -1]; - }; - - template - struct FunctionForwarderVoid - : FunctionSignature - { - public: - typedef FunctionSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)func(argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - ASSERT_UNLOCKV8_IS_FALSE; - typedef char AssertArity[ sl::Arity::Value == -1 ? 1 : -1]; - }; - - /** - Internal impl for cvv8::ConstMethodForwarder. - */ - template >::Value - > - struct MethodForwarder DOXYGEN_FWD_DECL_KLUDGE; - - - template - struct MethodForwarder : MethodSignature - { - public: - typedef MethodSignature SignatureType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename TypeInfo::Type Type; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (self.*func)(); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative( self, func, argv ) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative( func, argv ) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - - ASSERT_UNLOCK_SANITY_CHECK; - }; - - template - struct MethodForwarder - : MethodSignature - { - public: - typedef MethodSignature SignatureType; - typedef char AssertArity[ sl::Arity::Value == -1 ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - return (self.*func)(argv); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative( self, func, argv ) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative(func, argv) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - ASSERT_UNLOCKV8_IS_FALSE; - }; - - template - struct MethodForwarder : - MethodForwarder - {}; - - template >::Value - > - struct MethodForwarderVoid DOXYGEN_FWD_DECL_KLUDGE; - - template - struct MethodForwarderVoid - : MethodSignature - { - public: - typedef MethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - typedef T Type; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( Type & self, FunctionType func, v8::Arguments const & ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)(); - } - static v8::Handle Call( Type & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid - : MethodSignature - { - public: - typedef MethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename TypeInfo::Type Type; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( Type & self, FunctionType func, v8::Arguments const & argv ) - { - return (ReturnType)(self.*func)(argv); - } - static v8::Handle Call( Type & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - ASSERT_UNLOCKV8_IS_FALSE; - }; - - template - struct MethodForwarderVoid - : MethodForwarderVoid - {}; - - /** - Internal impl for cvv8::ConstMethodForwarder. - */ - template >::Value - > - struct ConstMethodForwarder DOXYGEN_FWD_DECL_KLUDGE; - - template - struct ConstMethodForwarder : ConstMethodSignature - { - public: - typedef ConstMethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (self.*func)(); - } - - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative( self, func, argv ) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative(func, argv) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarder - : ConstMethodSignature - { - public: - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ sl::Arity::Value == -1 ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - return (ReturnType)(self.*func)(argv); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative( self, func, argv ) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative(func, argv) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - ASSERT_UNLOCKV8_IS_FALSE; - }; - - template - struct ConstMethodForwarder - : ConstMethodForwarder - {}; - - template >::Value - > - struct ConstMethodForwarderVoid DOXYGEN_FWD_DECL_KLUDGE; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - public: - typedef ConstMethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename TypeInfo::Type Type; - static ReturnType CallNative( Type const & self, FunctionType func, v8::Arguments const & ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)(); - } - - static v8::Handle Call( Type const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - ASSERT_UNLOCK_SANITY_CHECK; - }; - - template - struct ConstMethodForwarderVoid - : ConstMethodSignature - { - public: - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ sl::Arity::Value == -1 ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - typedef typename TypeInfo::Type Type; - static ReturnType CallNative( Type const & self, FunctionType func, v8::Arguments const & argv ) - { - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)(); - } - static v8::Handle Call( Type const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - return CastToJS( CallNative( func, argv ) ); - } - HANDLE_PROPAGATE_EXCEPTION; - } - ASSERT_UNLOCKV8_IS_FALSE; - }; - - template - struct ConstMethodForwarderVoid - : ConstMethodForwarderVoid - {}; - -} -#endif // DOXYGEN - -/** - A helper type for passing v8::Arguments lists to native non-member - functions. - - Sig must be a function-signature-like argument. e.g. , - and the members of this class expect functions matching that signature. - - If UnlockV8 is true then v8::Unlocker will be used to unlock v8 - for the duration of the call to Func(). HOWEVER... (the rest of - these docs are about the caveats)... - - A UnlockV8 value of SignatureIsUnlockable::Value uses a - reasonably sound heuristic but it cannot predict certain - app-dependent conditions which render its guess semantically - invalid. See SignatureIsUnlockable for more information. - - It is illegal for UnlockV8 to be true if ANY of the following - applies: - - - The callback itself will "use" v8 but does not explicitly use - v8::Locker. If it uses v8::Locker then it may safely enable - unlocking support. We cannot determine via templates whether - or not a function "uses" v8 except by guessing based on the - return and arguments types. - - - Any of the return or argument types for the function are v8 - types, e.g. v8::Handle or v8::Arguments. - SignatureIsUnlockable::Value will evaluate to false - if any of the "known bad" types is contained in the function's - signature. If this function is given a true value but - SignatureIsUnlockable::Value is false then - a compile-time assertion will be triggered. - - - Certain callback signatures cannot have unlocking support - enabled because if we unlock then we cannot legally access the data - we need to convert. These will cause a compile-time assertion - if UnlockV8 is true. All such bits are incidentally covered by - SignatureIsUnlockable's check, so this assertion can - only happen if the client explicitly sets UnlockV8 to true for - those few cases. - - - There might be other, as yet unknown/undocumented, corner cases - where unlocking v8 is semantically illegal at this level of the - API. - - Violating any of these leads to undefined behaviour. The library - tries to fail at compile time for invalid combinations when it - can, but (as described aboved) it can be fooled into thinking that - unlocking is safe. - - Reminder to self: we can implement this completely via inheritance of - the internal Proxy type, but i REALLY want the API docs out here at this - level instead of in the Detail namespace (which i filter out of doxygen - for the most part). -*/ -template >::Value -> -struct FunctionForwarder -{ -private: - typedef typename tmp::IfElse< tmp::SameType::ReturnType>::Value, - Detail::FunctionForwarderVoid< sl::Arity< Signature >::Value, Sig, UnlockV8 >, - Detail::FunctionForwarder< sl::Arity< Signature >::Value, Sig, UnlockV8 > - >::Type - Proxy; -public: - typedef typename Proxy::SignatureType SignatureType; - typedef typename Proxy::ReturnType ReturnType; - typedef typename Proxy::FunctionType FunctionType; - /** - Passes the given arguments to func(), converting them to the appropriate - types. If argv.Length() is less than sl::Arity< SignatureType >::Value then - a JS exception is thrown, with one exception: if the function has "-1 arity" - (i.e. it is InvocationCallback-like) then argv is passed on to it regardless - of the value of argv.Length(). - - The native return value of the call is returned to the caller. - */ - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - return Proxy::CallNative( func, argv ); - } - /** - Equivalent to CastToJS( CallNative(func,argv) ) unless ReturnType - is void, in which case CastToJS() is not invoked and v8::Undefined() - will be returned. - */ - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return Proxy::Call( func, argv ); - } -}; - -/** - CallForwarder basically does the opposite of FunctionForwarder: it - converts native arguments to JS and calls a JS function. - - The default implementation is useless - it must be specialized - for each arity. -*/ -template -struct CallForwarder -{ - /** - Implementations must be templates taking Arity arguments in addition - to the first two. All argument types must legal for use with - CastToJS(). - - If either self or func.IsEmpty() then a JS exception must be thrown, - else implementations must return func->Call(self, N, ARGS), where - ARGS is an array of v8::Handle and N is the number of - items in that array (and, not coincidentally, is the same value as - Arity). The ARGS array must be populated by calling CastToJS(ARG_N) - for each argument, where ARG_N is the Nth argument. - */ - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - ... ); - /** - Convenience form of Call() which must be equivalent to - Call(func,func,...). - */ - static v8::Handle Call( v8::Handle const & func, ... ); -}; - -//! Specialization for 0-arity calls. -template <> -struct CallForwarder<0> -{ - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func ) - { - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, 0, NULL); - } - static v8::Handle Call( v8::Handle const & func ) - { - return Call( func, func ); - } -}; - - -#if !defined(DOXYGEN) -namespace Detail { - - /** - Base internal implementation of cvv8::FunctionToInCa. - */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< FunctionSignature >::Value > - struct FunctionToInCa : FunctionPtr, InCa - { - - typedef FunctionSignature SignatureType; - typedef FunctionForwarder< sl::Arity::Value, Sig, UnlockV8 > Proxy; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( v8::Arguments const & argv ) - { - return (ReturnType)Proxy::CallNative( Func, argv ); - /** - The (ReturnType) cast is effectively a no-op for all types - except void, where it is used to get around a limitation in - some compilers which does not allow us to explicitly return - foo() when foo() returns void. - */ - } - static v8::Handle Call( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - ASSERT_UNLOCK_SANITY_CHECK; - }; - - /** Almost identical to FunctionToInCa, but expressly does not - instantiate NativeToJS< Signature::ReturnType >, meaning - that: - - a) it can proxy functions which have non-convertible return types. - - b) JS always gets the 'undefined' JS value as the return value. - */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< FunctionSignature >::Value > - struct FunctionToInCaVoid : FunctionPtr, InCa - { - typedef FunctionSignature SignatureType; - typedef FunctionForwarderVoid< sl::Arity::Value, Sig, UnlockV8 > Proxy; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( v8::Arguments const & argv ) - { - return (ReturnType)Proxy::CallNative( Func, argv ); - } - static v8::Handle Call( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - ASSERT_UNLOCK_SANITY_CHECK; - }; - - /** Method equivalent to FunctionToInCa. */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< MethodSignature >::Value - > - struct MethodToInCa : MethodPtr, InCa - { - typedef MethodPtr SignatureType; - enum { Arity = sl::Arity::Value }; - typedef MethodForwarder< T, Arity, Sig, UnlockV8 > Proxy; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, v8::Arguments const & argv ) - { - return Proxy::CallNative( self, Func, argv ); - } - static ReturnType CallNative( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( T & self, v8::Arguments const & argv ) - { - return Proxy::Call( self, Func, argv ); - } - ASSERT_UNLOCK_SANITY_CHECK; - }; - - /** Method equivalent to FunctionToInCaVoid. */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< MethodSignature >::Value - > - struct MethodToInCaVoid : MethodPtr, InCa - { - typedef MethodPtr SignatureType; - enum { Arity = sl::Arity::Value }; - typedef MethodForwarderVoid< T, Arity, Sig, UnlockV8 > Proxy; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, v8::Arguments const & argv ) - { - return Proxy::CallNative( self, Func, argv ); - } - static ReturnType CallNative( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( T & self, v8::Arguments const & argv ) - { - return Proxy::Call( self, Func, argv ); - } - ASSERT_UNLOCK_SANITY_CHECK; - }; - - /** Const method equivalent to MethodToInCa. */ - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< ConstMethodSignature >::Value - > - struct ConstMethodToInCa : ConstMethodPtr, InCa - { - typedef ConstMethodPtr SignatureType; - typedef ConstMethodForwarder< T, sl::Arity::Value, Sig, UnlockV8 > Proxy; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, v8::Arguments const & argv ) - { - return Proxy::CallNative( self, Func, argv ); - } - static ReturnType CallNative( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( T const & self, v8::Arguments const & argv ) - { - return Proxy::Call( self, Func, argv ); - } - }; - - template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< ConstMethodSignature >::Value - > - struct ConstMethodToInCaVoid : ConstMethodPtr, InCa - { - typedef ConstMethodPtr SignatureType; - typedef ConstMethodForwarderVoid< T, sl::Arity::Value, Sig, UnlockV8 > Proxy; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, v8::Arguments const & argv ) - { - return Proxy::CallNative( self, Func, argv ); - } - static ReturnType CallNative( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( v8::Arguments const & argv ) - { - return Proxy::Call( Func, argv ); - } - static v8::Handle Call( T const & self, v8::Arguments const & argv ) - { - return Proxy::Call( self, Func, argv ); - } - ASSERT_UNLOCK_SANITY_CHECK; - }; - -} // Detail namespace -#endif // DOXYGEN -#undef ASSERT_UNLOCK_SANITY_CHECK -#undef ASSERT_UNLOCKV8_IS_FALSE - - -/** - A template for converting free (non-member) function pointers - to v8::InvocationCallback. - - Sig must be a function signature. Func must be a pointer to a function - with that signature. - - If UnlockV8 is true then v8::Unlocker will be used to unlock v8 - for the duration of the call to Func(). HOWEVER... see - FunctionForwarder for the details/caveats regarding that - parameter. - - Example: - - @code - v8::InvocationCallback cb = - FunctionToInCa< int (int), ::putchar>::Call; - @endcode -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< Signature >::Value - > -struct FunctionToInCa - : tmp::IfElse< tmp::SameType::ReturnType>::Value, - Detail::FunctionToInCaVoid< Sig, Func, UnlockV8>, - Detail::FunctionToInCa< Sig, Func, UnlockV8> - >::Type -{}; - -/** - A variant of FunctionToInCa with the property of NOT invoking the - conversion of the function's return type from native to JS form. i.e. it - does not cause NativeToJS< Signature::ReturnType > to be - instantiated. This is useful when such a conversion is not legal because - CastToJS() won't work on it or, more generally, when you want the JS - interface to always get the undefined return value. - - Call() always returns v8::Undefined(). CallNative(), however, - returns the real return type specified by Sig (which may be void). - - Example: - - @code - v8::InvocationCallback cb = - FunctionToInCaVoid< int (int), ::putchar>::Call; - @endcode -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< Signature >::Value - > -struct FunctionToInCaVoid : Detail::FunctionToInCaVoid< Sig, Func, UnlockV8> -{}; - - -/** - A template for converting non-const member function pointers to - v8::InvocationCallback. If T is const qualified then this works - as for ConstMethodToInCaVoid. - - To convert JS objects to native 'this' pointers this API uses - CastFromJS(arguments.This()), where arguments is the - v8::Arguments instance passed to the generated InvocationCallback - implementation. If that conversion fails then the generated - functions will throw a JS-side exception when called. - - T must be some client-specified type which is presumably bound (or - at least bindable) to JS-side Objects. Sig must be a member - function signature for T. Func must be a pointer to a function with - that signature. - - See FunctionForwarder for details about the UnlockV8 parameter. - - Example: - - @code - v8::InvocationCallback cb = - MethodToInCa::Call; - // For const methods: - cb = MethodToInCa::Call; - @endcode -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< MethodSignature >::Value - > -struct MethodToInCa - : tmp::IfElse< tmp::SameType::ReturnType>::Value, - Detail::MethodToInCaVoid, - Detail::MethodToInCa - >::Type -{ -}; - -/** - See FunctionToInCaVoid - this is identical exception that it - works on member functions of T. If T is const qualified - then this works as for ConstMethodToInCaVoid. - - Example: - - @code - v8::InvocationCallback cb = - MethodToInCaVoid< T, int (int), &T::myFunc>::Call; - @endcode - -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< MethodSignature >::Value - > -struct MethodToInCaVoid - : Detail::MethodToInCaVoid -{ -}; - -#if !defined(DOXYGEN) -namespace Detail { - template - struct FunctorToInCaSelector : ConstMethodForwarder >::Value, Sig, UnlockV8> - { - }; - template - struct FunctorToInCaSelector : ConstMethodForwarderVoid >::Value, Sig, UnlockV8> - {}; -} -#endif - -/** - This class converts a functor to an InvocationCallback. Ftor must - be a functor type. Sig must be a signature unambiguously matching - a Ftor::operator() implementation and Ftor::operator() must be - const. UnlockV8 is as described for FunctionToInCa. -*/ -template >::Value - > -struct FunctorToInCa : InCa -{ - inline static v8::Handle Call( v8::Arguments const & argv ) - { - typedef Detail::FunctorToInCaSelector< - typename Signature::ReturnType, Ftor, Sig, UnlockV8 - > Proxy; - return Proxy::Call( Ftor(), &Ftor::operator(), argv ); - } -}; - -/** - The functor equivalent of FunctionToInCaVoid. See FunctorToInCa for - the requirements of the Ftor and Sig types. -*/ -template >::Value - > -struct FunctorToInCaVoid : InCa -{ - inline static v8::Handle Call( v8::Arguments const & argv ) - { - typedef Detail::FunctorToInCaSelector< - void, Ftor, Sig, UnlockV8 - > Proxy; - return Proxy::Call( Ftor(), &Ftor::operator(), argv ); - } -}; - -/** - Functionally identical to MethodToInCa, but for const member functions. - - See FunctionForwarder for details about the UnlockV8 parameter. - - Note that the Sig signature must be suffixed with a const qualifier! - - Example: - - @code - v8::InvocationCallback cb = - ConstMethodToInCa< T, int (int), &T::myFunc>::Call; - @endcode - -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< ConstMethodSignature >::Value - > -struct ConstMethodToInCa -#if 0 // not working due to an ambiguous Sig vs Sig. Kinda weird, since MethodToInCa works. - : MethodToInCa {}; -#else - : tmp::IfElse< tmp::SameType::ReturnType>::Value, - Detail::ConstMethodToInCaVoid, - Detail::ConstMethodToInCa - >::Type -{}; -#endif -/** - See FunctionToInCaVoid - this is identical exception that it - works on const member functions of T. - - Note that the Sig signature must be suffixed with a const qualifier! - - Example: - - @code - v8::InvocationCallback cb = - ConstMethodToInCaVoid< T, int (int), &T::myFunc>::Call; - @endcode - -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< ConstMethodSignature >::Value - > -struct ConstMethodToInCaVoid : Detail::ConstMethodToInCaVoid -{}; - -/** - Identicial to FunctionForwarder, but works on non-const - member methods of type T. - - Sig must be a function-signature-like argument. e.g. , and the members of this class expect T member - functions matching that signature. -*/ -template >::Value> -struct MethodForwarder -{ -private: - typedef typename - tmp::IfElse< tmp::SameType::ReturnType>::Value, - Detail::MethodForwarderVoid< T, sl::Arity< Signature >::Value, Sig, UnlockV8 >, - Detail::MethodForwarder< T, sl::Arity< Signature >::Value, Sig, UnlockV8 > - >::Type - Proxy; -public: - typedef typename Proxy::SignatureType SignatureType; - typedef typename Proxy::FunctionType FunctionType; - typedef typename Proxy::ReturnType ReturnType; - /** - Passes the given arguments to (self.*func)(), converting them - to the appropriate types. If argv.Length() is less than - sl::Arity::Value then a JS exception is - thrown, with one exception: if the function has "-1 arity" - (i.e. it is InvocationCallback-like) then argv is passed on - to it regardless of the value of argv.Length(). - */ - inline static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - return Proxy::Call( self, func, argv ); - } - - /** - Like the 3-arg overload, but tries to extract the (T*) object using - CastFromJS(argv.This()). - */ - inline static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return Proxy::Call( func, argv ); - } -}; - - -/** - Identical to MethodForwarder, but works on const member methods. -*/ -template >::Value - > -struct ConstMethodForwarder -#if 1 //?msvc Seems to work. -: MethodForwarder {}; -#else -{ -private: - typedef typename - tmp::IfElse< tmp::SameType::ReturnType>::Value, - Detail::ConstMethodForwarderVoid< T, sl::Arity< Signature >::Value, Sig, UnlockV8 >, - Detail::ConstMethodForwarder< T, sl::Arity< Signature >::Value, Sig, UnlockV8 > - >::Type - Proxy; -public: - typedef typename Proxy::SignatureType SignatureType; - typedef typename Proxy::FunctionType FunctionType; - - /** - Passes the given arguments to (self.*func)(), converting them - to the appropriate types. If argv.Length() is less than - sl::Arity< Signature >::Value then a JS exception is thrown, with one - exception: if the function has "-1 arity" (i.e. it is - InvocationCallback-like) then argv is passed on to it - regardless of the value of argv.Length(). - */ - inline static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - return Proxy::Call( self, func, argv ); - } - - /** - Like the 3-arg overload, but tries to extract the (T const *) - object using CastFromJS(argv.This()). - */ - inline static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return Proxy::Call( func, argv ); - } -}; -#endif - -/** - Tries to forward the given arguments to the given native - function. Will fail if argv.Lengt() is not at least - sl::Arity>::Value, throwing a JS exception in that - case _unless_ the function is InvocationCallback-like, in which - case argv is passed directly to it regardless of the value of - argv.Length(). -*/ -template -inline typename FunctionSignature::ReturnType -forwardFunction( Sig func, v8::Arguments const & argv ) -{ - typedef FunctionSignature MSIG; - typedef typename MSIG::ReturnType RV; - enum { Arity = sl::Arity< Signature >::Value }; - typedef typename - tmp::IfElse< tmp::SameType::Value, - Detail::FunctionForwarderVoid< Arity, Sig >, - Detail::FunctionForwarder< Arity, Sig > - >::Type Proxy; - return (RV)Proxy::CallNative( func, argv ); -} - -/** - Works like forwardFunction(), but forwards to the - given non-const member function and treats the given object - as the 'this' pointer. -*/ -template -inline typename MethodSignature::ReturnType -forwardMethod( T & self, - Sig func, - /* if i do: typename MethodSignature::FunctionType - then this template is never selected. */ - v8::Arguments const & argv ) -{ - typedef MethodSignature MSIG; - typedef typename MSIG::ReturnType RV; - enum { Arity = sl::Arity< MSIG >::Value }; - typedef typename - tmp::IfElse< tmp::SameType::Value, - Detail::MethodForwarderVoid< T, Arity, Sig >, - Detail::MethodForwarder< T, Arity, Sig > - >::Type Proxy; - return (RV)Proxy::CallNative( self, func, argv ); -} - -/** - Like the 3-arg forwardMethod() overload, but - extracts the native T 'this' object from argv.This(). - - Note that this function requires that the caller specify - the T template parameter - it cannot deduce it. -*/ -template -inline typename MethodSignature::ReturnType -forwardMethod(Sig func, v8::Arguments const & argv ) -{ - typedef MethodSignature MSIG; - typedef typename MSIG::ReturnType RV; - enum { Arity = sl::Arity< MSIG >::Value }; - typedef typename - tmp::IfElse< tmp::SameType::Value, - Detail::MethodForwarderVoid< T, Arity, Sig >, - Detail::MethodForwarder< T, Arity, Sig > - >::Type Proxy; - return (RV)Proxy::CallNative( func, argv ); -} - - -/** - Works like forwardMethod(), but forwards to the given const member - function and treats the given object as the 'this' pointer. - -*/ -template -inline typename ConstMethodSignature::ReturnType -forwardConstMethod( T const & self, - //typename ConstMethodSignature::FunctionType func, - Sig func, - v8::Arguments const & argv ) -{ - typedef ConstMethodSignature MSIG; - typedef typename MSIG::ReturnType RV; - enum { Arity = sl::Arity< MSIG >::Value }; - typedef typename - tmp::IfElse< tmp::SameType::Value, - Detail::ConstMethodForwarderVoid< T, Arity, Sig >, - Detail::ConstMethodForwarder< T, Arity, Sig > - >::Type Proxy; - return (RV)Proxy::CallNative( self, func, argv ); -} - -/** - Like the 3-arg forwardConstMethod() overload, but - extracts the native T 'this' object from argv.This(). - - Note that this function requires that the caller specify - the T template parameter - it cannot deduce it. -*/ -template -inline typename ConstMethodSignature::ReturnType -forwardConstMethod(Sig func, v8::Arguments const & argv ) -{ - typedef ConstMethodSignature MSIG; - typedef typename MSIG::ReturnType RV; - enum { Arity = sl::Arity< MSIG >::Value }; - typedef typename - tmp::IfElse< tmp::SameType::Value, - Detail::ConstMethodForwarderVoid< T, Arity, Sig >, - Detail::ConstMethodForwarder< T, Arity, Sig > - >::Type Proxy; - return (RV)Proxy::CallNative( func, argv ); -} - -/** - A structified/functorified form of v8::InvocationCallback. It is - sometimes convenient to be able to use a typedef to create an alias - for a given InvocationCallback. Since we cannot typedef function - templates this way, this class can fill that gap. -*/ -template -struct InCaToInCa : FunctionToInCa< v8::Handle (v8::Arguments const &), ICB> -{ -}; - - -#if 0 // YAGNI -/** - "Converts" an InCaToInCa instance to JS by treating it as an - InvocationCallback function. This is primarily useful in - conjunction with ClassCreator::Set() to add function bindings. -*/ -template -struct NativeToJS< InCaToInCa > -{ - /** - Returns a JS handle to InCaToInCa::Call(). - */ - v8::Handle operator()( InCaToInCa const & ) - { - return v8::FunctionTemplate::New(InCaToInCa::Call)->GetFunction(); - } -}; -#endif - -#if !defined(DOXYGEN) -namespace Detail { - /** Internal code duplication reducer. */ - template - v8::Handle TossArgCountError( v8::Arguments const & args ) - { - return Toss((StringBuffer() - <<"Incorrect argument count ("< > -> -struct ArityDispatch : InCa -{ - /** - When called, if (Artity==-1) or if (Arity==args.Length()) then - InCaT::Call(args) is returned, else Fallback::Call(args) is returned. - - Implements the InvocationCallback interface. - */ - inline static v8::Handle Call( v8::Arguments const & args ) - { - return ( (-1==Arity) || (Arity == args.Length()) ) - ? InCaT::Call(args) - : Fallback::Call(args); - } -}; - - -/** - InvocationCallback wrapper which calls another InvocationCallback - and translates any native ExceptionT exceptions thrown by that - function into JS exceptions. - - ExceptionT must be an exception type which is thrown by const - reference (e.g. STL-style) as opposed to by pointer (MFC-style). - - SigGetMsg must be a function-signature-style argument describing - a method within ExceptionT which can be used to fetch the message - reported by the exception. It must meet these requirements: - - a) Be const - b) Take no arguments - c) Return a type convertible to JS via CastToJS() - - Getter must be a pointer to a function matching that signature. - - InCaT must be a InCa type. When Call() is called by v8, it will pass - on the call to InCaT::Call() and catch exceptions as described below. - - Exceptions of type (ExceptionT const &) and (ExceptionT const *) which - are thrown by ICB get translated into a JS exception with an error - message fetched using ExceptionT::Getter(). - - If PropagateOtherExceptions is true then exception of types other - than ExceptionT are re-thrown (which can be fatal to v8, so be - careful). If it is false then they are not propagated but the error - message in the generated JS exception is unspecified (because we - have no generic way to get such a message). If a client needs to - catch multiple exception types, enable propagation and chain the - callbacks together. In such a case, the outer-most (last) callback - in the chain should not propagate unknown exceptions (to avoid - killing v8). - - This type can be used to implement "chaining" of exception - catching, such that we can use the InCaCatcher - to catch various distinct exception types in the context - of one v8::InvocationCallback call. - - Example: - - @code - // Here we want to catch MyExceptionType, std::runtime_error, and - // std::exception (the base class of std::runtime_error, by the - // way) separately: - - // When catching within an exception hierarchy, start with the most - // specific (most-derived) exceptions. - - // Client-specified exception type: - typedef InCaCatcher< - MyExceptionType, - std::string (), - &MyExceptionType::getMessage, - InCaToInCa, // the "real" InvocationCallback - true // make sure propagation is turned on so chaining can work! - > Catch_MyEx; - - // std::runtime_error: - typedef InCaCatcher_std< Catch_MyEx, std::runtime_error > Catch_RTE; - - // std::exception: - typedef InCaCatcher_std< Catch_RTE > MyCatcher; - - // Now MyCatcher::Call is-a InvocationCallback which will handle - // MyExceptionType, std::runtime_error, and std::exception via - // different catch blocks. Note, however, that the visible - // behaviour for runtime_error and std::exception (its base class) - // will be identical here, though they actually have different - // code. - @endcode -*/ -template < typename ExceptionT, - typename SigGetMsg, - typename ConstMethodSignature::FunctionType Getter, - typename InCaT, - bool PropagateOtherExceptions = false - > -struct InCaCatcher : InCa -{ - /** - Returns ICB(args), converting any exceptions of type (ExceptionT - const &) or (ExceptionT const *) to JS exceptions. Other exception - types are handled as described in the class-level documentation. - - See the class-level docs for full details. - */ - static v8::Handle Call( v8::Arguments const & args ) - { - try - { - return InCaT::Call( args ); - } - catch( ExceptionT const & e2 ) - { - /* reminder to self: we now have the unusual corner case that - if Getter() returns a v8::Handle it will be thrown - as-is instead of wrapped in an Error object. See the Toss() docs - for why that is so. We could use tmp::SameType to alternately - call TossAsError(), but i'm too tired and i honestly don't ever - expect any exception type to return v8 handles. - */ - return Toss((e2.*Getter)()); - } - catch( ExceptionT const * e2 ) - { - return Toss((e2->*Getter)()); - } - catch(...) - { - if( PropagateOtherExceptions ) throw; - else return Toss("Unknown native exception thrown!"); - } - } -}; - -/** - Convenience form of InCaCatcher which catches std::exception objects and - uses their what() method to fetch the error message. - - The ConcreteException parameter may be std::exception (the default) or - any publically derived subclass of std::exception. When using a - non-default value, one can chain exception catchers to catch most-derived - types first. - - PropagateOtherExceptions determines whether _other_ exception types are - propagated or not. It defaults to false if ConcreteException is - std::exception (exactly, not a subtype), else it defaults to true. The - reasoning is: when chaining these handlers we need to catch the - most-derived first. Those handlers need to propagate other exceptions so - that we can catch the lesser-derived ones (or those from completely - different hierarchies) in subsequent catchers. The final catcher "should" - (arguably) swallow unknown exceptions, converting them to JS exceptions - with an unspecified message string (propagating them is technically legal - but will most likely crash v8). - - Here is an example of chaining: - - @code - typedef InCaCatcher_std< InCaToInCa, std::logic_error > LECatch; - typedef InCaCatcher_std< LECatch, std::runtime_error > RECatch; - typedef InCaCatcher_std< RECatch, std::bad_cast > BCCatch; - typedef InCaCatcher_std< BCCatch > BaseCatch; - v8::InvocationCallback cb = BaseCatch::Call; - @endcode - - In the above example any exceptions would be processed in the order: - logic_error, runtime_error, bad_cast, std::exception, anything else. Notice - that we took advantage of the PropagateOtherExceptions default value for all - cases to get the propagation behaviour we want. -*/ -template < - typename InCaT, - typename ConcreteException = std::exception, - bool PropagateOtherExceptions = !tmp::SameType< std::exception, ConcreteException >::Value -> -struct InCaCatcher_std : - InCaCatcher -{}; - -namespace Detail { - /** - An internal level of indirection for overloading-related - dispatchers. - */ - template - struct OverloadCallHelper : InCa - { - inline static v8::Handle Call( v8::Arguments const & argv ) - { - return InCaT::Call(argv); - } - }; - //! End-of-list specialization. - template <> - struct OverloadCallHelper : InCa - { - inline static v8::Handle Call( v8::Arguments const & argv ) - { - return Toss( StringBuffer() - << "End of typelist reached. Argument count=" - < Call( v8::Arguments const & argv ); - - And a static const integer (or enum) value called Arity, - which must specify the expected number of arguments, or be - negative specify that the function accepts any number of - arguments. - - In other words, all entries in FwdList must implement the - interface used by most of the InCa-related API. - - Example: - - @code - // Overload 3 variants of a member function: - typedef CVV8_TYPELIST(( - MethodToInCa, - MethodToInCa, - MethodToInCa - // Note that "N-arity" callbacks MUST come last in the list - // because they will always match any arity count and therefore - // trump any overloads which follow them. - )) OverloadList; - typedef ArityDispatchList< OverloadList > MyOverloads; - v8::InvocationCallback cb = MyOverloads::Call; - @endcode - - Note that only one line of that code is evaluated at runtime - the rest - is all done at compile-time. -*/ -template -struct ArityDispatchList : InCa -{ - /** - Tries to dispatch argv to one of the bound functions defined - in FwdList, based on the number of arguments in argv and - the Arity - - Implements the v8::InvocationCallback interface. - */ - inline static v8::Handle Call( v8::Arguments const & argv ) - { - typedef typename FwdList::Head FWD; - typedef typename FwdList::Tail Tail; - enum { Arity = sl::Arity< FWD >::Value }; - return ( (-1 == Arity) || (Arity == argv.Length()) ) - ? Detail::OverloadCallHelper::Call(argv) - : ArityDispatchList::Call(argv); - } -}; - -/** - End-of-list specialization. -*/ -template <> -struct ArityDispatchList : Detail::OverloadCallHelper -{ -}; - -#if !defined(DOXYGEN) -namespace Detail { - //! Internal helper for ToInCa impl. - template - struct ToInCaSigSelector : MethodSignature - { - template < typename MethodSignature::FunctionType Func, bool UnlockV8 > - struct Base : cvv8::MethodToInCa - { - }; - }; - - //! Internal helper for ToInCa impl. - template - struct ToInCaSigSelector : FunctionSignature - { - template < typename FunctionSignature::FunctionType Func, bool UnlockV8 > - struct Base : cvv8::FunctionToInCa - { - }; - }; - - //! Internal helper for ToInCaVoid impl. - template - struct ToInCaSigSelectorVoid : MethodSignature - { - template < typename MethodSignature::FunctionType Func, bool UnlockV8 > - struct Base : cvv8::MethodToInCaVoid - { - }; - }; - - //! Internal helper for ToInCaVoid impl. - template - struct ToInCaSigSelectorVoid : FunctionSignature - { - template < typename FunctionSignature::FunctionType Func, bool UnlockV8 > - struct Base : cvv8::FunctionToInCaVoid - { - }; - }; - -} -#endif // DOXYGEN - -/** - A wrapper for MethodToInCa, ConstMethodToInCa, and - FunctionToInCa, which determines which one of those to use based - on the type of T and its constness. - - For non-member functions, T must be void. For non-const member - functions T must be non-cvp-qualified T. For const member functions - T must be const-qualified. - - See FunctionForwarder for the meaning of the UnlockV8 parameter. - - Examples: - - @code - typedef ToInCa NonConstMethod; - typedef ToInCa ConstMethod; - typedef ToInCa Func; - - v8::InvocationCallback cb; - cb = NonConstMethod::Call; - cb = ConstMethod::Call; - cb = Func::Call; - @endcode - - Note the extra 'const' qualification for const method. This is - neccessary to be able to portably distinguish the constness - (some compilers allow us to add the const as part of the - function signature). Also note that the 'void' 1st parameter for - non-member functions is a bit of a hack. -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< Detail::ToInCaSigSelector >::Value - > -struct ToInCa : Detail::ToInCaSigSelector::template Base -{ -}; - -/** - This works just like ToInCa but instead of behaving like - FunctionToInCa or Const/MethoToInCa it behaves like - FunctionToInCaVoid or Const/MethoToInCaVoid. -*/ -template ::FunctionType Func, - bool UnlockV8 = SignatureIsUnlockable< Detail::ToInCaSigSelector >::Value - > -struct ToInCaVoid : Detail::ToInCaSigSelectorVoid::template Base -{ -}; - - -/** - A slightly simplified form of FunctionToInCa which is only - useful for "InvocationCallback-like" functions and requires - only two arguments: - - @code - // int my_func( v8::Arguments const & ); - typedef InCaLikeFunction< int, my_func > F; - @endcode -*/ -template -struct InCaLikeFunction : FunctionToInCa< RV (v8::Arguments const &), Func> -{ -}; - -/** - A slightly simplified form of MethodToInCa which is only - useful for non-const "InvocationCallback-like" methods: - - @code - // Method: int MyType::func( v8::Arguments const & ) - typedef InCaLikeMethod F; - @endcode -*/ -template -struct InCaLikeMethod : MethodToInCa< T, RV (v8::Arguments const &), Func> -{}; - -/** - A slightly simplified form of ConstMethodToInCa which is only - useful for const "InvocationCallback-like" methods: - - @code - // Method: int MyType::func( v8::Arguments const & ) const - typedef InCaLikeConstMethod F; - @endcode -*/ -template -struct InCaLikeConstMethod : ConstMethodToInCa< T, RV (v8::Arguments const &), Func> -{}; - - -#if 0 -//! Don't use. Doesn't yet compile. Trying to consolidate Const/MethodXyz -template ::FunctionType Func> -struct SigToInCa : - tmp::IfElse< - sl::IsFunction< Signature >::Value, - FunctionToInCa< ASig, Func >, - typename tmp::IfElse< - sl::IsConstMethod< Signature >::Value, - ConstMethodToInCa< typename tmp::PlainType::Context>::Type, ASig, Func >, - MethodToInCa< typename Signature::Context, ASig, Func > - >::Type - >::Type -{}; -#endif - -/** - This class acts as a proxy for another InCa-compatible class, - running client-defined intialization code the _first_ time - its callback is called from JS. This could be used to run - library-dependent intialization routines such as lt_dlinit(). - - InCaT must conform to the InCa interface (i.e., have a static Call() - function which implements the v8::InvocationCallback interface). - - InitFunctor must be default-constructable and have an operator() - (preferably const) taking no args and returning any type which can be - ignored (i.e. not dynamically-allocated resources). -*/ -template -struct OneTimeInitInCa : InCa -{ - /** - The first time this function is called it runs - InitFunctor()() to execute any client-dependent setup. If - that throws a native exception it is propagated back to the - caller and initialization is considered NOT to have - occurred, meaning the next call to this function will also - run InitFunctor()(). - - If initialization does not throw, InCaT::Call(argv) is - called and its value is returned. Once initialization - succeeds, it is _not_ triggered on subsequent calls to this - function. - - Pedantic note: if this class is used in code which is linked - in from multiple DLLs, the init routine might be called - more than once, depending on the platform. - */ - static v8::Handle Call( v8::Arguments const & argv ) - { - static bool bob = false; - if( ! bob ) - { - InitFunctor()(); - /* Reminder: if it throws we do not set bob=true. - This is part of the interface, not an accident. - */ - bob = true; - } - return InCaT::Call( argv ); - } -}; - - -#if 0// i'm not yet decided on these bits... -struct NativeToJS_InCa_Base -{ - typedef v8::InvocationCallback ArgType; - template - inline v8::Handle operator()( SigT const & ) const - { - return v8::FunctionTemplate::New(SigT::Call)->GetFunction(); - } -}; - -template ::FunctionType Func> -struct NativeToJS< FunctionToInCa > : NativeToJS_InCa_Base {}; -template ::FunctionType Func> -struct NativeToJS< FunctionToInCaVoid > : NativeToJS_InCa_Base {}; - -template ::FunctionType Func> -struct NativeToJS< MethodToInCa > : NativeToJS_InCa_Base {}; -template ::FunctionType Func> -struct NativeToJS< MethodToInCaVoid > : NativeToJS_InCa_Base {}; - -template ::FunctionType Func> -struct NativeToJS< ConstMethodToInCa > : NativeToJS_InCa_Base {}; -template ::FunctionType Func> -struct NativeToJS< ConstMethodToInCaVoid > : NativeToJS_InCa_Base {}; - -template ::FunctionType Func> -struct NativeToJS< ToInCa > : NativeToJS_InCa_Base {}; -template ::FunctionType Func> -struct NativeToJS< ToInCaVoid > : NativeToJS_InCa_Base {}; -#endif - -#include "invocable_generated.hpp" -} // namespace - -#undef HANDLE_PROPAGATE_EXCEPTION -#undef ENABLE_TOINCA - -#endif /* CODE_GOOGLE_COM_V8_CONVERT_INVOCABLE_V8_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/detail/invocable_generated.hpp b/vendor/libv8-convert/cvv8/detail/invocable_generated.hpp deleted file mode 100644 index 6c7227f5f..000000000 --- a/vendor/libv8-convert/cvv8/detail/invocable_generated.hpp +++ /dev/null @@ -1,3588 +0,0 @@ -/* AUTO-GENERATED CODE! EDIT AT YOUR OWN RISK! */ -#if !defined(DOXYGEN) -namespace Detail { - template - struct FunctionForwarder<1,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (1 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<1,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (1 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (1 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (1 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (1 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (1 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 1-arity calls. -template <> -struct CallForwarder<1> -{ - template < typename A0> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0 - ) - { - v8::Handle args[] = { - CastToJS(a0) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0> - static v8::Handle Call( v8::Handle const & func, - A0 a0 - ) - { - return Call( func, func, a0 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 1 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 1 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - - typedef ArgCaster AC0; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<2,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (2 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<2,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (2 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (2 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (2 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (2 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (2 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 2-arity calls. -template <> -struct CallForwarder<2> -{ - template < typename A0, typename A1> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1 - ) - { - return Call( func, func, a0,a1 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 2 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 2 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<3,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (3 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<3,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (3 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (3 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (3 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (3 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (3 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 3-arity calls. -template <> -struct CallForwarder<3> -{ - template < typename A0, typename A1, typename A2> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2 - ) - { - return Call( func, func, a0,a1,a2 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 3 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 3 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<4,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (4 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<4,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (4 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (4 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (4 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (4 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (4 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 4-arity calls. -template <> -struct CallForwarder<4> -{ - template < typename A0, typename A1, typename A2, typename A3> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3 - ) - { - return Call( func, func, a0,a1,a2,a3 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 4 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 4 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<5,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (5 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<5,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (5 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (5 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (5 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (5 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (5 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 5-arity calls. -template <> -struct CallForwarder<5> -{ - template < typename A0, typename A1, typename A2, typename A3, typename A4> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3), CastToJS(a4) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3, typename A4> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4 - ) - { - return Call( func, func, a0,a1,a2,a3,a4 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 5 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 5 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3, arg4 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<6,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (6 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<6,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (6 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (6 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (6 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (6 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (6 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 6-arity calls. -template <> -struct CallForwarder<6> -{ - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3), CastToJS(a4), CastToJS(a5) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 - ) - { - return Call( func, func, a0,a1,a2,a3,a4,a5 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 6 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 6 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3, arg4, arg5 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<7,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (7 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<7,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (7 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (7 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (7 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (7 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (7 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 7-arity calls. -template <> -struct CallForwarder<7> -{ - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3), CastToJS(a4), CastToJS(a5), CastToJS(a6) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 - ) - { - return Call( func, func, a0,a1,a2,a3,a4,a5,a6 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 7 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 7 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3, arg4, arg5, arg6 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<8,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (8 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<8,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (8 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (8 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (8 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (8 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (8 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 8-arity calls. -template <> -struct CallForwarder<8> -{ - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3), CastToJS(a4), CastToJS(a5), CastToJS(a6), CastToJS(a7) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 - ) - { - return Call( func, func, a0,a1,a2,a3,a4,a5,a6,a7 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 8 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 8 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<9,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (9 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<9,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (9 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (9 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (9 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (9 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (9 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 9-arity calls. -template <> -struct CallForwarder<9> -{ - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3), CastToJS(a4), CastToJS(a5), CastToJS(a6), CastToJS(a7), CastToJS(a8) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 - ) - { - return Call( func, func, a0,a1,a2,a3,a4,a5,a6,a7,a8 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 9 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 9 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); - } - } -}; -} -namespace Detail { - template - struct FunctionForwarder<10,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (10 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - return CastToJS( CallNative( func, argv ) ); - } - }; - - template - struct FunctionForwarderVoid<10,Sig,UnlockV8> : FunctionSignature - { - typedef FunctionSignature SignatureType; - typedef char AssertArity[ (10 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - CallNative( func, argv ); - return v8::Undefined(); - } - }; -} -namespace Detail { - template - struct MethodForwarder : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (10 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct MethodForwarderVoid : MethodSignature - { - typedef MethodSignature SignatureType; - typedef char AssertArity[ (10 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - static v8::Handle Call( T & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -namespace Detail { - template - struct ConstMethodForwarder : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (10 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - V8Unlocker const & unlocker = ( V8Unlocker() ); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative( self, func, argv ) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try { return CastToJS( CallNative(func, argv) ); } - HANDLE_PROPAGATE_EXCEPTION; - } - }; - - template - struct ConstMethodForwarderVoid : ConstMethodSignature - { - typedef ConstMethodSignature SignatureType; - typedef char AssertArity[ (10 == sl::Arity::Value) ? 1 : -1]; - typedef typename SignatureType::FunctionType FunctionType; - typedef typename SignatureType::ReturnType ReturnType; - static ReturnType CallNative( T const & self, FunctionType func, v8::Arguments const & argv ) - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - V8Unlocker const & unlocker = V8Unlocker(); - return (ReturnType)(self.*func)( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - static v8::Handle Call( T const & self, FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative( self, func, argv ); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - static ReturnType CallNative( FunctionType func, v8::Arguments const & argv ) - { - T const * self = CastFromJS(argv.This()); - if( ! self ) throw MissingThisExceptionT(); - return (ReturnType)CallNative(*self, func, argv); - } - static v8::Handle Call( FunctionType func, v8::Arguments const & argv ) - { - try - { - CallNative(func, argv); - return v8::Undefined(); - } - HANDLE_PROPAGATE_EXCEPTION; - } - }; -} -//! Specialization for 10-arity calls. -template <> -struct CallForwarder<10> -{ - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> - static v8::Handle Call( v8::Handle const & self, - v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 - ) - { - v8::Handle args[] = { - CastToJS(a0), CastToJS(a1), CastToJS(a2), CastToJS(a3), CastToJS(a4), CastToJS(a5), CastToJS(a6), CastToJS(a7), CastToJS(a8), CastToJS(a9) - }; - return (self.IsEmpty() || func.IsEmpty()) - ? Toss("Illegal argument: empty v8::Handle<>.") - : func->Call(self, sizeof(args)/sizeof(args[0]), args); - } - template < typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> - static v8::Handle Call( v8::Handle const & func, - A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 - ) - { - return Call( func, func, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9 ); - } - -}; -namespace Detail { -template -struct CtorForwarderProxy -{ - enum { Arity = 10 }; - typedef typename Signature::ReturnType ReturnType; - static ReturnType Call( v8::Arguments const & argv ) - { - if( argv.Length() < Arity ) - { - throw std::range_error("CtorForwarder::Ctor() expects at least 10 JS arguments!"); - } - else - { - typedef typename sl::At< 0, Signature >::Type A0; - typedef typename sl::At< 1, Signature >::Type A1; - typedef typename sl::At< 2, Signature >::Type A2; - typedef typename sl::At< 3, Signature >::Type A3; - typedef typename sl::At< 4, Signature >::Type A4; - typedef typename sl::At< 5, Signature >::Type A5; - typedef typename sl::At< 6, Signature >::Type A6; - typedef typename sl::At< 7, Signature >::Type A7; - typedef typename sl::At< 8, Signature >::Type A8; - typedef typename sl::At< 9, Signature >::Type A9; - - typedef ArgCaster AC0; - typedef ArgCaster AC1; - typedef ArgCaster AC2; - typedef ArgCaster AC3; - typedef ArgCaster AC4; - typedef ArgCaster AC5; - typedef ArgCaster AC6; - typedef ArgCaster AC7; - typedef ArgCaster AC8; - typedef ArgCaster AC9; - - AC0 ac0; A0 arg0(ac0.ToNative(argv[0])); - AC1 ac1; A1 arg1(ac1.ToNative(argv[1])); - AC2 ac2; A2 arg2(ac2.ToNative(argv[2])); - AC3 ac3; A3 arg3(ac3.ToNative(argv[3])); - AC4 ac4; A4 arg4(ac4.ToNative(argv[4])); - AC5 ac5; A5 arg5(ac5.ToNative(argv[5])); - AC6 ac6; A6 arg6(ac6.ToNative(argv[6])); - AC7 ac7; A7 arg7(ac7.ToNative(argv[7])); - AC8 ac8; A8 arg8(ac8.ToNative(argv[8])); - AC9 ac9; A9 arg9(ac9.ToNative(argv[9])); - - typedef typename TypeInfo::Type Type; - return new Type( arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); - } - } -}; -} -#endif // if !defined(DOXYGEN) diff --git a/vendor/libv8-convert/cvv8/detail/signature_core.hpp b/vendor/libv8-convert/cvv8/detail/signature_core.hpp deleted file mode 100644 index b4ff3fe6d..000000000 --- a/vendor/libv8-convert/cvv8/detail/signature_core.hpp +++ /dev/null @@ -1,498 +0,0 @@ -#if !defined(CODE_GOOGLE_COM_V8_CONVERT_SIGNATURE_CORE_HPP_INCLUDED) -#define CODE_GOOGLE_COM_V8_CONVERT_SIGNATURE_CORE_HPP_INCLUDED 1 -#include "tmp.hpp" -#include "doxygen_hack.hpp" - -namespace cvv8 { -/** @file signature_core.hpp - -This file houses the core-most templates related to handling -function/method signatures as full-fleged types. -*/ - - - -/** @class Signature - - Base (unimplemented) template for holding function-signature-style - argument lists in a type-rich manner. Most implementations are - script-generated and accept up to some library-build-time-defined number - of types in their argument list (the interface guarantees at least 10 - unless the client builds a custom copy with a smaller limit). - - All specializations implement a "type list" interface. The sl namespace - contains several different compile-time algorithms (sometimes called - template metafunctions) for querying the arity and types in a signature. - - Sig must be a function-signature-style parameter list, e.g.: - - @code - Signature< void (int, double) > - Signature< void (MyType::*)( int double ) > - Signature< void (MyType::*)( char const * ) const > - @endcode - - This interface treates the "function parameter part" of its arguments as - a "type list", and several algorithms in the sl namespace are available - for fetching type information from a Signature type. This is an - "extended" typelist, however, because it also remembers the return type - and optionally the class containing a member function described by the - signature (neither of those are counted as part of the list, but are - accessible separately). - - Required interface for specializations: - - @code - typedef functionSignature FunctionType; // e.g. void () or void (T::*)() const. - typedef functionReturnType ReturnType; - typedef T Context; // void for non-member functions, non-vp-qualified T - // for all T members. const-qualified T for const members. - typedef firstArgType Head; // head type of type-list. - typedef Signature< RV (...)> Tail; // tail of type-list. (...)==arg types 2..N. - // When Arity==0, Head and Tail must both be tmp::NilType. For Arity==1 - // Tail is Signature but one could argue that it should be tmp::NilType. - - @endcode - - It is intended to be used like this: - - @code - typedef Signature< int (char const *, double) > Sig; - assert( 2 == sl::Arity::Value ); - assert( 2 == sl::Length::Value ) - assert( (tmp::SameType< char const *, sl::At<0,Sig>::Type >::Value) ); - assert( (tmp::SameType< double, sl::At<1,Sig>::Type >::Value) ); - assert( 1 == sl::Index< double, Sig >::Value) ); - assert( !sl::Contains< int, Sig >::Value) ); // Sig::ReturnType doesn't count here! - assert( sl::IsConstMethod< Signature< void (MyType::*)() const > >::Value ); - assert( sl::IsMethod< Signature< void (MyType::*)() const > >::Value ); - assert( !sl::IsConstMethod< Signature< void (MyType::*)() > >::Value ); - // Those can all be made into static assertions, by the way. - @endcode - - Note that the length of the typelist does not include the return value - type nor (for member methods) the containing class (the Context typedef). - - Functions taking one (v8::Arguments const &) argument and - returning any type are considered to be - "InvocationCallback-like" and are treated specially. They have - an Arity value of -1, which is used as a hint by binding code - that the function can accept any number of arguments when called - from JS code (there is no way to create Arguments objects - directly from C++, only indirectly via Call()ing or Apply()ing a - v8::Function). -*/ -template struct Signature DOXYGEN_FWD_DECL_KLUDGE; - -/** @def CVV8_TYPELIST - - CVV8_TYPELIST is a (slightly) convenience form of - Signature for creating typelists where we do not care about the - "return type" or "context" parts of the list. - - It is used like this: - - @code - typedef CVV8_TYPELIST(( int, double, char )) MyList; - @endcode - - NOTE the doubled parenthesis! - - Many members of the API which take a type-list require a - Signature-compatible typelist because they need the ReturnValue and/or - Context parts. CVV8_TYPELIST is intended for cases where niether the - ReturnValue nor Context are evaluated (both are void for CVV8_TYPELIST). - - The maximum number of types the typelist can hold is limited - to some build-time configuration option. -*/ -#define CVV8_TYPELIST(X) ::cvv8::Signature< void (*)X > - -/** \namespace cvv8::sl - - The sl namespace exclusively holds template metafunctions for working - with Signature-style typelists. -*/ -namespace sl { - - /** - Metafunction whose Value member evaluates to the length of the - given Signature. - */ - template < typename ListT > - struct Length : tmp::IntVal< - tmp::IsNil::Value ? 0 : (1 + Length::Value) - > {}; - - //! End-of-list specialization. - template <> - struct Length : tmp::IntVal<0> {}; - /** - Metafunction whose Type member evaluates to the type of the - I'th argument type in the given Signature. Fails to compile - if I is out of range. - */ - template < unsigned short I, typename ListT > - struct At : At - { - typedef char AssertIndex[ (I >= Length::Value) ? -1 : 1 ]; - }; - - //! Beginning-of-list specialization. - template < typename ListT > - struct At<0, ListT> - { - typedef typename ListT::Head Type; - }; - /** - End-of-list specialization. i don't think we need this, actually. - */ - template - struct At : tmp::Identity - {}; - - /** - Metafunction whose Type Value member evaluates to the 0-based - index of the first occurrance of the the type T in the - given Signature's argument list. Evaluates to -1 if T is not - contained in the argument list. Signature::ReturnType and - Signature::Context are not evaluated. - - Clients _must not_ pass a value for the 3rd template parameter. - */ - template < typename T, typename ListT, unsigned short Internal = 0 > - struct Index : tmp::IntVal< tmp::SameType::Value - ? Internal - : Index::Value> - { - }; - - //! End-of-list specialization. - template < typename T, unsigned short Internal > - struct Index : tmp::IntVal<-1> {}; - - /** - Convenience form of Index which evaluates to true - if Index returns a non-negative value, else it evaluates - to false. - */ - template < typename T, typename ListT> - struct Contains : tmp::BoolVal< Index::Value >= 0 > {}; - - - /** - A metatype which calculates the number of arguments in the given - typelist, but evaluates to -1 if SigT's only argument is - (v8::Arguments const &), as such function signatures are considered - to be n-arity. - */ - template - struct Arity - { - enum { - Value = ((1==Length::Value) - && (0==Index::Value)) - ? -1 - : Length::Value - }; - }; - - /** - This metafunction evaluates to true if SigT appears to be - "InvocationCallback-like" (returns any type and takes one - (v8::Arguments const &) parameter). - - We could implement this a number of different ways. The - current impl simply checks if the arity is -1. - */ - template - struct IsInCaLike : tmp::BoolVal< -1 == Arity::Value > {}; - - /** - A metafunction which has a true Value if the Signature type SigT - represents a non-member function. - */ - template - struct IsFunction : tmp::BoolVal< tmp::SameType::Value > {}; - - /** - A metafunction which has a true Value if the Signature type SigT - represents a member function (const or not). - */ - template - struct IsMethod : tmp::BoolVal< !tmp::SameType::Value > {}; - - /** - A metafunction which has a true Value if the Signature type SigT - represents a non-const member function. - */ - template - struct IsNonConstMethod : tmp::BoolVal< !tmp::IsConst< typename SigT::Context >::Value && IsMethod::Value > {}; - - /** - A metafunction which has a true Value if the Signature type SigT - represents a const member function. - */ - template - struct IsConstMethod : - tmp::BoolVal< tmp::IsConst< typename SigT::Context >::Value && IsMethod::Value > {}; - //tmp::BoolVal< SigT::IsConst && IsMethod::Value > {}; - -} - -namespace tmp { - /** - A metatemplate who's Type member resolves to IF if Cond is - true, or ELSE if Cond is false. Its Value member evaluates - to 1 or 0, accordingly. - */ - template - struct IfElse : sl::At< Cond ? 0 : 1, Signature > - { - }; -} - -#if 0 -//! Highly arguably specialization. -template struct Signature< Signature > : Signature {}; -#endif - -/** - Specialization to give "InvacationCallback-like" functions - an Arity value of -1. - - Reminder: we can get rid of this if we factory out the Arity definition - and use sl::Arity instead. -*/ -template -struct Signature -{ - typedef RV ReturnType; - typedef RV (*FunctionType)(v8::Arguments const &); - typedef void Context; - typedef v8::Arguments const & Head; - typedef Signature Tail; -}; - -template -struct Signature : Signature -{}; - -template -struct Signature : Signature -{ - typedef T Context; - typedef RV (Context::*FunctionType)(v8::Arguments const &); -}; - - -template -struct Signature : Signature -{ - typedef T const Context; - typedef RV (Context::*FunctionType)(v8::Arguments const &) const; -}; - - - -/** @class FunctionSignature - Base (unimplemented) signature for FunctionSignature - specializations. The type passed to it must be a function - signature. - - All implementations must define the interface described for - Signature and its Context typedef must be void for this type. - - Examples: - - @code - // void func_foo(): - typedef FunctionSignature< void () > NoArgsReturnsVoid; - - // int func_foo(double): - typedef FunctionSignature< int (double) > OneArgReturnsInt; - - // double func_foo(int,int): - typedef FunctionSignature< double (int,int) > TwoArgsReturnsDouble; - @endcode - -*/ -template -struct FunctionSignature : Signature< FunctionSig > {}; - -/** @class MethodSignature - Base (unimplemented) signature for MethodSignature - specializations. The Sig type passed to it must match a member method - signature of a function from the class T. - e.g. (void (T::*)(int)) or its equivalent (void (int)). - - All implementations must have the interface called for by Signature - and the Context typedef must be non-cvp-qualified T. - - Examples: - - @code - // void MyType::func(): - typedef MethodSignature< MyType, void () > NoArgsReturnsVoid; - - // int MyType::func(double): - typedef MethodSignature< MyType, int (double) > OneArgReturnsInt; - - // double MyType::func(int,int): - typedef MethodSignature< MyType, double (int,int) > TwoArgsReturnsDouble; - @endcode - - As of r2019 (20110723), MethodSignature and - ConstMethodSignature are equivalent. - - Reminders to self: - - i would really like this class to simply subclass Signature and we - would add in a couple typedefs we need. This would cut the specializations - we generate. However, i don't know how to make this work. The problems - include: - - - i can't "refactor" Signature::FunctionType to the proper type - at this level. -*/ -template -struct MethodSignature DOXYGEN_FWD_DECL_KLUDGE; - -/** @class ConstMethodSignature - Base (unimplemented) signature for ConstMethodSignature - specializations. The Sig type passed to it must be a member - method signature of a const function from the class T. - e.g. (void (T::*)(int) const) - - All implementations must have the interface called for by Signature - and the Context typedef must be non-cvp-qualified T. The IsConst - member (enum or static/const boolean) must be a true value. - - Examples: - - @code - // void MyType::func() const: - typedef ConstMethodSignature< MyType, void () > NoArgsReturnsVoid; - - // int MyType::func(double) const: - typedef ConstMethodSignature< MyType, int (double) > OneArgReturnsInt; - - // double MyType::func(int,int) const: - typedef ConstMethodSignature< MyType, double (int,int) > TwoArgsReturnsDouble; - @endcode - - As of r2019 (20110723), MethodSignature and - ConstMethodSignature are equivalent. -*/ -template -struct ConstMethodSignature DOXYGEN_FWD_DECL_KLUDGE; -//template -//struct ConstMethodSignature : ConstMethodSignature {}; - -template -struct MethodSignature< T, RV () > : Signature< RV () > -{ - typedef T Context; - typedef RV (Context::*FunctionType)(); -}; - - -template -struct MethodSignature< T, RV (T::*)() > : MethodSignature -{ -}; - -template -struct MethodSignature< T const, RV () > : ConstMethodSignature< T, RV () > -{}; - -template -struct MethodSignature< T const, RV (T::*)() > : MethodSignature -{ -}; -#if 1 //msvc? -template -struct MethodSignature< T const, RV (T::*)() const > : MethodSignature -{ -}; -#endif - -template -struct ConstMethodSignature< T, RV () > : Signature< RV (T::*)() const > -{ - typedef T const Context; - typedef RV (Context::*FunctionType)() const; -}; -template -struct ConstMethodSignature< T, RV (T::*)() const > : ConstMethodSignature -{ -}; - - -/** - A "type-rich" function pointer. - - Sig must be a function signature type usable in the construct - FunctionSignature. FuncPtr must be a function of that type. -*/ -template ::FunctionType FuncPtr> -struct FunctionPtr : FunctionSignature -{ - /** - This type's full "signature" type. - */ - typedef FunctionSignature SignatureType; - /** - The data type of FuncPtr. - */ - typedef typename SignatureType::FunctionType FunctionType; - - /** The function specifies in the template arguments. */ - static const FunctionType Function; -}; -template ::FunctionType FuncPtr> -typename FunctionPtr::FunctionType const FunctionPtr::Function = FuncPtr; - -/** - Used like FunctionPtr, but in conjunction with non-const - member functions ("methods") of the T class. See FunctionPtr - for the requirements of the Sig type. -*/ -template ::FunctionType FuncPtr> -struct MethodPtr : MethodSignature -{ - typedef MethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - static const FunctionType Function; -}; -template ::FunctionType FuncPtr> -typename MethodPtr::FunctionType const MethodPtr::Function = FuncPtr; -/** - Used like MethodPtr, but in conjunction with const methods of the T - class. -*/ -template ::FunctionType FuncPtr> -struct ConstMethodPtr : ConstMethodSignature -{ - typedef ConstMethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - static const FunctionType Function; -}; -template ::FunctionType FuncPtr> -typename ConstMethodPtr::FunctionType const ConstMethodPtr::Function = FuncPtr; - -#if 0 //!msvc -//! Specialization to treat (const T) as ConstMethodPtr. -template ::FunctionType FuncPtr> -struct MethodPtr : ConstMethodPtr -{ - typedef MethodSignature SignatureType; - typedef typename SignatureType::FunctionType FunctionType; - static const FunctionType Function; -}; -#endif - -#include "signature_generated.hpp" -} // namespaces - -#endif /* CODE_GOOGLE_COM_V8_CONVERT_SIGNATURE_CORE_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/detail/signature_generated.hpp b/vendor/libv8-convert/cvv8/detail/signature_generated.hpp deleted file mode 100644 index 30102c1f2..000000000 --- a/vendor/libv8-convert/cvv8/detail/signature_generated.hpp +++ /dev/null @@ -1,911 +0,0 @@ -/* AUTO-GENERATED CODE! EDIT AT YOUR OWN RISK! */ -#if !defined(DOXYGEN) - -template -struct Signature< RV () > -{ - typedef RV ReturnType; - enum { IsConst = 0 }; - typedef void Context; - typedef RV (*FunctionType)(); - typedef tmp::NilType Head; - typedef Head Tail; -}; -template -struct Signature< RV (*)() > : Signature -{}; - -template -struct Signature< RV (T::*)() > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(); -}; -template -struct Signature< RV (T::*)() const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)() const; - enum { IsConst = 1 }; -}; -//! Specialization for 1 arg(s). -template -struct Signature< RV (A1) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1); - typedef A1 Head; - typedef Signature< RV () > Tail; -}; - -//! Specialization for 1 arg(s). -template -struct Signature< RV (*)(A1) > : Signature -{}; - -//! Specialization for T non-const methods taking 1 arg(s). -template -struct Signature< RV (T::*)(A1) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1); -}; - -//! Specialization for T const methods taking 1 arg(s). -template -struct Signature< RV (T::*)(A1) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1) const; -}; - -//! Specialization for 2 arg(s). -template -struct Signature< RV (A1, A2) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 2 arg(s). -template -struct Signature< RV (*)(A1, A2) > : Signature -{}; - -//! Specialization for T non-const methods taking 2 arg(s). -template -struct Signature< RV (T::*)(A1, A2) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2); -}; - -//! Specialization for T const methods taking 2 arg(s). -template -struct Signature< RV (T::*)(A1, A2) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2) const; -}; - -//! Specialization for 3 arg(s). -template -struct Signature< RV (A1, A2, A3) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 3 arg(s). -template -struct Signature< RV (*)(A1, A2, A3) > : Signature -{}; - -//! Specialization for T non-const methods taking 3 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3); -}; - -//! Specialization for T const methods taking 3 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3) const; -}; - -//! Specialization for 4 arg(s). -template -struct Signature< RV (A1, A2, A3, A4) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 4 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4) > : Signature -{}; - -//! Specialization for T non-const methods taking 4 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4); -}; - -//! Specialization for T const methods taking 4 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4) const; -}; - -//! Specialization for 5 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 5 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5) > : Signature -{}; - -//! Specialization for T non-const methods taking 5 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5); -}; - -//! Specialization for T const methods taking 5 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5) const; -}; - -//! Specialization for 6 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 6 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6) > : Signature -{}; - -//! Specialization for T non-const methods taking 6 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6); -}; - -//! Specialization for T const methods taking 6 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6) const; -}; - -//! Specialization for 7 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 7 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7) > : Signature -{}; - -//! Specialization for T non-const methods taking 7 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7); -}; - -//! Specialization for T const methods taking 7 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7) const; -}; - -//! Specialization for 8 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 8 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8) > : Signature -{}; - -//! Specialization for T non-const methods taking 8 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8); -}; - -//! Specialization for T const methods taking 8 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8) const; -}; - -//! Specialization for 9 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 9 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) > : Signature -{}; - -//! Specialization for T non-const methods taking 9 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9); -}; - -//! Specialization for T const methods taking 9 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const; -}; - -//! Specialization for 10 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 10 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) > : Signature -{}; - -//! Specialization for T non-const methods taking 10 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); -}; - -//! Specialization for T const methods taking 10 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const; -}; - -//! Specialization for 11 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 11 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) > : Signature -{}; - -//! Specialization for T non-const methods taking 11 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); -}; - -//! Specialization for T const methods taking 11 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const; -}; - -//! Specialization for 12 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 12 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) > : Signature -{}; - -//! Specialization for T non-const methods taking 12 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); -}; - -//! Specialization for T const methods taking 12 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const; -}; - -//! Specialization for 13 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 13 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) > : Signature -{}; - -//! Specialization for T non-const methods taking 13 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); -}; - -//! Specialization for T const methods taking 13 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const; -}; - -//! Specialization for 14 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 14 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) > : Signature -{}; - -//! Specialization for T non-const methods taking 14 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); -}; - -//! Specialization for T const methods taking 14 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const; -}; - -//! Specialization for 15 arg(s). -template -struct Signature< RV (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) > -{ - typedef RV ReturnType; - typedef void Context; - typedef RV (*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15); - typedef A1 Head; - typedef Signature Tail; -}; - -//! Specialization for 15 arg(s). -template -struct Signature< RV (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) > : Signature -{}; - -//! Specialization for T non-const methods taking 15 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) > : Signature -{ - typedef T Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15); -}; - -//! Specialization for T const methods taking 15 arg(s). -template -struct Signature< RV (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) const > : Signature -{ - typedef T const Context; - typedef RV (T::*FunctionType)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) const; -}; - -template -struct MethodSignature< T, RV ( A0) > : Signature< RV (T::*)( A0) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0) > : MethodSignature< T, RV ( A0) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0) > : - MethodSignature< T, RV ( A0) > -{}; - -template -struct MethodSignature< T const, RV ( A0) > : - ConstMethodSignature< T, RV ( A0) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0) > : - MethodSignature< T const, RV ( A0) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0) const > : - MethodSignature< T const, RV ( A0) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0) > : Signature< RV (T::*)( A0) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0) const > : - ConstMethodSignature< T, RV ( A0) > -{}; -template -struct MethodSignature< T, RV ( A0, A1) > : Signature< RV (T::*)( A0, A1) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1) > : MethodSignature< T, RV ( A0, A1) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1) > : - MethodSignature< T, RV ( A0, A1) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1) > : - ConstMethodSignature< T, RV ( A0, A1) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1) > : - MethodSignature< T const, RV ( A0, A1) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1) const > : - MethodSignature< T const, RV ( A0, A1) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1) > : Signature< RV (T::*)( A0, A1) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1) const > : - ConstMethodSignature< T, RV ( A0, A1) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2) > : Signature< RV (T::*)( A0, A1, A2) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2) > : MethodSignature< T, RV ( A0, A1, A2) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2) > : - MethodSignature< T, RV ( A0, A1, A2) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2) > : - ConstMethodSignature< T, RV ( A0, A1, A2) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2) > : - MethodSignature< T const, RV ( A0, A1, A2) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2) const > : - MethodSignature< T const, RV ( A0, A1, A2) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2) > : Signature< RV (T::*)( A0, A1, A2) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2) const > : - ConstMethodSignature< T, RV ( A0, A1, A2) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3) > : Signature< RV (T::*)( A0, A1, A2, A3) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3) > : MethodSignature< T, RV ( A0, A1, A2, A3) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3) > : - MethodSignature< T, RV ( A0, A1, A2, A3) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3) > : - MethodSignature< T const, RV ( A0, A1, A2, A3) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3) > : Signature< RV (T::*)( A0, A1, A2, A3) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3, A4) > : Signature< RV (T::*)( A0, A1, A2, A3, A4) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3, A4) > : MethodSignature< T, RV ( A0, A1, A2, A3, A4) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4) > : - MethodSignature< T, RV ( A0, A1, A2, A3, A4) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3, A4) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4) > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4) > : Signature< RV (T::*)( A0, A1, A2, A3, A4) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3, A4, A5) > : MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5) > : - MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5) > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3, A4, A5, A6) > : MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6) > : - MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6) > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3, A4, A5, A6, A7) > : MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7) > : - MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7) > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) > : MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) > : - MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8) > -{}; -template -struct MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{ -}; -template -struct MethodSignature< T, RV (*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > : MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{ -}; - -template -struct MethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > : - MethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{}; - -template -struct MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{}; - -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{}; - -#if 1 // msvc? Apparently this works. -template -struct MethodSignature< T const, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) const > : - MethodSignature< T const, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{}; -#endif - - -template -struct ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > : Signature< RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) const > -{ -}; -template -struct ConstMethodSignature< T, RV (T::*)( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) const > : - ConstMethodSignature< T, RV ( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) > -{}; -#endif // if !defined(DOXYGEN) diff --git a/vendor/libv8-convert/cvv8/detail/tmp.hpp b/vendor/libv8-convert/cvv8/detail/tmp.hpp deleted file mode 100644 index aff069f6c..000000000 --- a/vendor/libv8-convert/cvv8/detail/tmp.hpp +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef CODE_GOOGLE_COM_P_V8_CONVERT_TMP_HPP_INCLUDED -#define CODE_GOOGLE_COM_P_V8_CONVERT_TMP_HPP_INCLUDED - -namespace cvv8 { -/** - The tmp namespace contains code related to template - metaprogramming, a-la Alexandrescu's Loki library or Boost MPL. - - All of it is independent of the core library. - - This is not a complete/full-featured TMP library - it only - contains the functions needed by our library-level code. -*/ -namespace tmp { - - struct NilType {}; - typedef NilType nil; - - - /** - An utmost most-basic compile-time assertion template. - If Condition is false, an incomplete specialization of - this type is invoked, causing a compile-time error. - */ - template - struct Assertion - { - enum { Value = 1 }; - }; - /** Unimplemented - causes a compile-time error if used. */ - template <> - struct Assertion; - - - /** A convenience base type for metafunctions holding a constant value. */ - template - struct ConstVal - { - static const ValType Value = Val; - }; - /** A metafunction holding an integer constant. */ - template - struct IntVal : ConstVal {}; - /** A metafunction holding an unsigned short constant. */ - template - struct UShortVal : ConstVal {}; - /** A metafunction holding a bool constant. */ - template - struct BoolVal : ConstVal {}; - - /** A metatype whos Value member is true if X and Y are the same type. */ - template - struct SameType : BoolVal {}; - /** Specialization for X==Y. */ - template - struct SameType : BoolVal {}; - - template - struct Identity - { - typedef T Type; - }; - - template - struct PlainType - { - typedef T Type; - }; - template - struct PlainType : PlainType {}; - template - struct PlainType : PlainType {}; - template - struct PlainType : PlainType {}; - -#if 0 - /** Metatemplate whose Type evaluates to (T*). */ - template - struct AddPointer - { - typedef T * Type; - }; - /** Specialization whose Type evaluates to (T *). */ - template - struct AddPointer - { - typedef T * Type; - }; - /** Specialization whose Type evaluates to (T const *). */ - template - struct AddPointer - { - typedef T const * Type; - }; - - //! Unimplemented. How to handle this? - template - struct AddPointer; - //! Unimplemented. How to handle this? - template - struct AddPointer; -#endif - - template - struct IsConst : BoolVal {}; - template - struct IsConst : BoolVal {}; - template - struct IsConst : IsConst {}; - template - struct IsConst : IsConst {}; - - - template - struct IsNil : SameType {}; - - - -}} // namespaces -#endif // CODE_GOOGLE_COM_P_V8_CONVERT_TMP_HPP_INCLUDED diff --git a/vendor/libv8-convert/cvv8/generator/Signature.hpp b/vendor/libv8-convert/cvv8/generator/Signature.hpp deleted file mode 100644 index 969a5e54b..000000000 --- a/vendor/libv8-convert/cvv8/generator/Signature.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) -# include -# include -# include -# include -# include -# if !defined(CVV8_PP_ITER_MAX) -# error "Define CVV8_PP_ITER_MAX before including this file." -# endif -# if !defined(CVV8_SIGNATURE_GENERATED_HPP_INCLUDED) -# define BOOST_PP_ITERATION_LIMITS (0, CVV8_PP_ITER_MAX) -# define BOOST_PP_FILENAME_1 "Signature.hpp" -# include BOOST_PP_ITERATE() -# endif /* include guard */ -#else -#define n BOOST_PP_ITERATION() - -template -struct Signature< RV (BOOST_PP_ENUM_PARAMS(n, A)) > -{ - typedef RV ReturnType; - static const bool IsConst = false; - typedef void Context; - typedef RV (*FunctionType)(BOOST_PP_ENUM_PARAMS(n, A)); -#if n > 0 - typedef A0 Head; - typedef Signature< RV (BOOST_PP_ENUM_SHIFTED_PARAMS(n, A)) > Tail; -#else - typedef tmp::NilType Head; - typedef Head Tail; -#endif -}; - -template -struct Signature< RV (*)(BOOST_PP_ENUM_PARAMS(n, A)) > - : Signature< RV (BOOST_PP_ENUM_PARAMS(n, A)) > -{}; - -//! Non-const method. -template -struct Signature< RV (T::*)(BOOST_PP_ENUM_PARAMS(n, A)) > - : Signature< RV (BOOST_PP_ENUM_PARAMS(n, A))> -{ - typedef T Context; - typedef RV (Context::*FunctionType)(BOOST_PP_ENUM_PARAMS(n, A)); -#if n > 0 - typedef A0 Head; - typedef Signature< RV (T::*)(BOOST_PP_ENUM_SHIFTED_PARAMS(n, A)) > Tail; -#else - typedef tmp::NilType Head; - typedef Head Tail; -#endif -}; - -//! Const method. -template -struct Signature< RV (T::*)(BOOST_PP_ENUM_PARAMS(n, A)) const > - : Signature< RV (BOOST_PP_ENUM_PARAMS(n, A))> -{ - typedef T const Context; - typedef RV (Context::*FunctionType)(BOOST_PP_ENUM_PARAMS(n, A)) const; - static const bool IsConst = true; -#if n > 0 - typedef A0 Head; - typedef Signature< RV (T::*)(BOOST_PP_ENUM_SHIFTED_PARAMS(n, A)) const > Tail; -#else - typedef tmp::NilType Head; - typedef Head Tail; -#endif -}; - -#endif /* BOOST_PP_IS_ITERATING */ diff --git a/vendor/libv8-convert/cvv8/invocable.hpp b/vendor/libv8-convert/cvv8/invocable.hpp deleted file mode 100644 index dac513380..000000000 --- a/vendor/libv8-convert/cvv8/invocable.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#if !defined(CODE_GOOGLE_COM_P_V8_CONVERT_INVOKE_HPP_INCLUDED) -#define CODE_GOOGLE_COM_P_V8_CONVERT_INVOKE_HPP_INCLUDED 1 - -#include "convert.hpp" -#include "detail/invocable_core.hpp" -/** LICENSE - - This software's source code, including accompanying documentation and - demonstration applications, are licensed under the following - conditions... - - The author (Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) - explicitly disclaims copyright in all jurisdictions which recognize - such a disclaimer. In such jurisdictions, this software is released - into the Public Domain. - - In jurisdictions which do not recognize Public Domain property - (e.g. Germany as of 2011), this software is Copyright (c) 2011 - by Stephan G. Beal, and is released under the terms of the MIT License - (see below). - - In jurisdictions which recognize Public Domain property, the user of - this software may choose to accept it either as 1) Public Domain, 2) - under the conditions of the MIT License (see below), or 3) under the - terms of dual Public Domain/MIT License conditions described here, as - they choose. - - The MIT License is about as close to Public Domain as a license can - get, and is described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - -- - Copyright (c) 2011 Stephan G. Beal (http://wanderinghorse.net/home/stephan/) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - --END OF MIT LICENSE-- - - For purposes of the above license, the term "Software" includes - documentation and demonstration source code which accompanies - this software. ("Accompanies" = is contained in the Software's - primary public source code repository.) - -*/ -#endif /* CODE_GOOGLE_COM_P_V8_CONVERT_INVOKE_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/properties.hpp b/vendor/libv8-convert/cvv8/properties.hpp deleted file mode 100644 index 1b4b936ad..000000000 --- a/vendor/libv8-convert/cvv8/properties.hpp +++ /dev/null @@ -1,730 +0,0 @@ -#if !defined(CODE_GOOGLE_COM_P_V8_CONVERT_PROPERTIES_HPP_INCLUDED) -#define CODE_GOOGLE_COM_P_V8_CONVERT_PROPERTIES_HPP_INCLUDED 1 - -#include "invocable.hpp" - -namespace cvv8 { - - /** - Marker class, primarily for documentation purposes. - - This class models the v8::AccessorGetter interface, and - XyzToGetter classes inherit this type as a sign that they - implement this interface. - - This class has no implemention - it only exists for - documentation purposes. - */ - struct AccessorGetterType - { - /** - The v8::AccessorGetter() interface. - */ - static v8::Handle Get(v8::Local property, const v8::AccessorInfo &info); - //{ return Toss(StringBuffer()<<"Property '"< property, v8::Local value, const v8::AccessorInfo& info); - }; - - /** @typedef AccessorGetterType Getter - - Convenience typedef, primarily to simplify usage of - FunctionTo and friends. - */ - typedef AccessorGetterType Getter; - - /** @typedef AccessorSetterType Setter - - Convenience typedef, primarily to simplify usage of - FunctionTo and friends. - */ - typedef AccessorSetterType Setter; - - /** - A tag type for use with VarTo, MemberTo, MethodTo, and FunctionTo. - */ - struct Accessors : AccessorGetterType, AccessorSetterType {}; - - /** - This template create an v8::AccessorGetter from a static/shared - variable. - - SharedVar must be pointer to a static variable and must not - be NULL. - - CastToJS(*SharedVar) must be legal. - */ - template - struct VarToGetter : AccessorGetterType - { - /** Implements the v8::AccessorGetter() interface. */ - inline static v8::Handle Get(v8::Local property, const v8::AccessorInfo &info) - { - return CastToJS( *SharedVar ); - } - }; - - /** - The setter counterpart of StaticVarToGetter(). - - SharedVar must be pointer to a static variable and must not - be NULL. - - (*SharedVar = CastFromJS()) must be legal. - - Reminder: this is not included in the StaticVarToGetter - template so that we can avoid either the Get or Set - conversion for cases where it is not legal (or not desired). - If they were both in one class, both Get and Set would _have_ - to be legal. - */ - template - struct VarToSetter : AccessorSetterType - { - /** Implements the v8::AccessorSetter() interface. */ - inline static void Set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) - { - *SharedVar = CastFromJS( value ); - } - }; - - /** - A proxy for both VarToGetter and VarToSetter, providing both - Get() and Set() functions. - */ - template - struct VarToAccessors : VarToGetter, - VarToSetter - {}; - - /** - This template creates a v8::AcessorGetter which binds directly to - a non-const native class member variable. - - Requirements: - - - T must be convertible to (T*) via CastFromJS(). - - MemVar must be an accessible member of T. - - PropertyType must be convertible via CastToJS(). - - If the underlying native 'this' object cannot be found (that - is, if CastFromJS() fails) then this routine will - trigger a JS exception. - */ - template - struct MemberToGetter : AccessorGetterType - { - /** Implements the v8::AccessorGetter() interface. */ - inline static v8::Handle Get(v8::Local property, const v8::AccessorInfo &info) - { - typedef typename TypeInfo::Type Type; - typedef typename JSToNative::ResultType NativeHandle; - NativeHandle self = CastFromJS( info.This() ); - return ( ! self ) - ? Toss( StringBuffer() << "Native member property getter '" - << property << "' could not access native 'this' object!" ) - : CastToJS( (self->*MemVar) ); - } - }; - - /** - This is the Setter counterpart of MemberToGetter. - - Requirements: - - - T must be convertible to (T*) via CastFromJS(). - - PropertyType must be convertible via CastToJS(). - - MemVar must be an accessible member of T. - - If the underlying native This object cannot be found then this - routine will trigger a JS exception. - */ - template - struct MemberToSetter : AccessorSetterType - { - /** Implements the v8::AccessorSetter() interface. */ - inline static void Set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) - { - typedef typename TypeInfo::Type Type; - typedef typename JSToNative::ResultType NativeHandle; - NativeHandle self = CastFromJS( info.This() ); - if( self ) self->*MemVar = CastFromJS( value ); - else Toss( StringBuffer() << "Native member property setter '" - << property << "' could not access native 'this'his object!" ); - } - }; - - /** - A proxy for both MemberToGetter and MemberToSetter, providing both - Get() and Set() functions. - - This should be called MembersToAccessors (plural Members). - */ - template - struct MemberToAccessors : MemberToGetter, - MemberToSetter - {}; - - /** - An AccessorSetter() implementation which always triggers a JS exception. - Can be used to enforce "pedantically read-only" variables. Note that - JS does not allow us to assign an AccessorSetter _without_ assigning - an AccessorGetter. Also note that there is no AccessorGetterThrow, - because a write-only var doesn't make all that much sense (use - methods for those use cases). - */ - struct ThrowingSetter : AccessorSetterType - { - inline static void Set(v8::Local property, v8::Local, const v8::AccessorInfo &) - { - Toss(StringBuffer() << - "Native member property setter '" - << property - << "' is configured to throw an exception when modifying " - << "this read-only member!"); - } - }; - - /** - Implements the v8::AccessorGetter interface to bind a JS - member property to a native getter function. This function - can be used as the getter parameter to - v8::ObjectTemplate::SetAccessor(). - - Sig must be a function-signature-style type and Getter must - capable of being called with no arguments and returning a - value which can be CastToJS() to a JS value. - - If Getter() throws a native exception it is converted to a JS - exception. - */ - template ::FunctionType Getter> - struct FunctionToGetter : AccessorGetterType - { - inline static v8::Handle Get( v8::Local< v8::String > property, const v8::AccessorInfo & info ) - { - return CastToJS( (*Getter)() ); - } - }; - - /** - Implements the v8::AccessorSetter interface to bind a JS - member property to a native getter function. This function - can be used as the getter parameter to - v8::ObjectTemplate::SetAccessor(). - - SigSet must be function-signature-style pattern - for the setter function. The native - function must follow conventional mutator signature: - - ReturnType ( PropertyType ) - - PropertyType may differ from the return type. PropertyType - may not be void but the ReturnType may be. Any return value - from the setter is ignored by the JS engine. - - Note that the v8 API appears to not allow us to just set - a setter, but not a getter. We have to set a getter without - a setter, a getter with a setter, or neither. At least that's - been my experience. - - If Setter() throws a native exception it is converted to a JS - exception. - */ - template ::FunctionType Func> - struct FunctionToSetter : AccessorSetterType - { - inline static void Set( v8::Local< v8::String > property, v8::Local< v8::Value > value, const v8::AccessorInfo &info) - { - typedef FunctionSignature FT; - (*Func)( CastFromJS::Type>( value ) ); - } - }; - - - /** - Implements the v8::AccessorGetter interface to bind a JS - member property to a native getter function. This function - can be used as the getter parameter to - v8::ObjectTemplate::SetAccessor(). - - Sig must be a function-pointer-style argument with a - non-void return type convertible to v8 via CastToJS(), and - Getter must be function capable of being called with 0 - arguments (either because it has none or they have - defaults). - */ - template ::FunctionType Getter> - struct MethodToGetter : AccessorGetterType - { - inline static v8::Handle Get( v8::Local< v8::String > property, const v8::AccessorInfo & info ) - { - typedef typename TypeInfo::Type Type; - typedef typename JSToNative::ResultType NativeHandle; - NativeHandle self = CastFromJS( info.This() ); - return self - ? CastToJS( (self->*Getter)() ) - : Toss( StringBuffer() << "Native member property getter '" - << property << "' could not access native This object!" ); - } - }; - - /** - Overload for const native getter functions. - */ - template ::FunctionType Getter> - struct ConstMethodToGetter : AccessorGetterType - { - inline static v8::Handle Get( v8::Local< v8::String > property, const v8::AccessorInfo & info ) - { - typedef typename TypeInfo::Type Type; - typedef typename JSToNative::ResultType NativeHandle; - NativeHandle const self = CastFromJS( info.This() ); - return self - ? CastToJS( (self->*Getter)() ) - : Toss( (StringBuffer() << "Native member property getter '" - << property << "' could not access native This object!").toError() ) - ; - } - }; - - /** - Implements v8::AccessorSetter interface to proxy a JS - member property through a native member setter function. - - This function can be used as the setter parameter to - v8::ObjectTemplate::SetAccessor(). - - Sig must be a function-pointer-style type and Getter must - be a T member function of that type. The function must be - capable of being called with only 1 argument (either - because it only accepts 1 or has defaults for the others), - and its return value is discarded (not converted to v8) - because that's how v8's native setters work. - - Exceptions thrown by the underlying function are - translated to JS exceptions. - - FIXME: code is 100% identical to ConstMethodToSetter except - for FunctionType typedef. Consolidate them in a base class. - */ - template ::FunctionType Setter> - struct MethodToSetter : AccessorSetterType - { - static void Set(v8::Local< v8::String > property, v8::Local< v8::Value > value, const v8::AccessorInfo &info) - { - typedef typename TypeInfo::Type Type; - typedef typename JSToNative::ResultType NativeHandle; - NativeHandle self = CastFromJS( info.This() ); - if( ! self ) - { - Toss( StringBuffer() << "Native member property setter '" - << property << "' could not access native This object!" ); - } - else - { - - typedef typename sl::At< 0, Signature >::Type ArgT; - (self->*Setter)( CastFromJS( value ) ); - } - return; - } - }; - - /** - Const-method equivalent of MethodToSetter. - - FIXME: code is 100% identical to ConstMethodToSetter except - for FunctionType typedef. Consolidate them in a base class. - */ - template ::FunctionType Setter> - struct ConstMethodToSetter : AccessorSetterType - { - static void Set(v8::Local< v8::String > property, v8::Local< v8::Value > value, const v8::AccessorInfo &info) - { - typedef typename TypeInfo::Type Type; - typedef typename JSToNative::ResultType NativeHandle; - NativeHandle self = CastFromJS( info.This() ); - if( ! self ) - { - Toss( StringBuffer() << "Native member property setter '" - << property << "' could not access native This object!" ); - } - else - { - typedef typename sl::At< 0, Signature >::Type ArgT; - (self->*Setter)( CastFromJS( value ) ); - } - } - }; - - - /** - Similar to FunctionToGetter but uses a functor as a getter. - This is rarely useful, since the functor has no direct access - to any application state (unless that is static/shared within - the Ftor class). - - Ftor must be a functor. Sig must be a signature matching a const - Ftor::operator() implementation. CastToJS(Signature::ReturnType) - must be legal. - - The signature's return type may not be void (this is a getter, - and getters don't return void). - */ - template - struct FunctorToGetter - { - inline static v8::Handle Get( v8::Local< v8::String > property, const v8::AccessorInfo & info ) - { - //const static Ftor f(); - return CastToJS(Ftor()()); - } - }; - - /** - The setter counterpart of FunctorToGetter. - - Ftor must be a functor which accepts 1 arguments. - Sig must be a signature matching a Ftor::operator() - implementation. - - The return value of Ftor::operator() is not evaluated, so it may be - void or any non-convertible type. It is semantically illegal to bind - a setter which return resources allocated by the setter, if those - resources are passed to the caller. In such a case, each access - _will_ leak memory. But nobody returns allocated memory from a - setter, right? - - CastFromJS() must be legal, where ArgType1 - is sl::At<0, Signature >::Type. - */ - template - struct FunctorToSetter - { - inline static void Set(v8::Local< v8::String > property, v8::Local< v8::Value > value, const v8::AccessorInfo &info) - { - typedef typename sl::At< 0, Signature >::Type ArgT; - Ftor()( CastFromJS( value ) ); - } - }; - - /** - SetterCatcher is the AccessorSetter equivalent of InCaCatcher, and - is functionality identical except that its 4th template parameter - must be-a AccessorSetterType instead of an InCa type. - */ - template < typename ExceptionT, - typename SigGetMsg, - typename ConstMethodSignature::FunctionType Getter, - typename SetterT, - bool PropagateOtherExceptions = false - > - struct SetterCatcher : AccessorSetterType - { - static void Set(v8::Local< v8::String > property, v8::Local< v8::Value > value, const v8::AccessorInfo &info) - { - try - { - SetterT::Set( property, value, info ); - } - catch( ExceptionT const & e2 ) - { - Toss((e2.*Getter)()); - } - catch( ExceptionT const * e2 ) - { - Toss((e2->*Getter)()); - } - catch(...) - { - if( PropagateOtherExceptions ) throw; - else Toss("Unknown native exception thrown!"); - } - } - }; - - /** - A convenience form of SetterCatcher which catches std::exception - and subtyes. See InCaCatcher_std for full details - this type is - identical except that its first template parameter must be-a - AccessorSetterType instead of InCa type. - */ - template < - typename SetterT, - typename ConcreteException = std::exception, - bool PropagateOtherExceptions = !tmp::SameType< std::exception, ConcreteException >::Value - > - struct SetterCatcher_std : - SetterCatcher - {}; - - /** - GetterCatcher is the AccessorSetter equivalent of InCaCatcher, and - is functionality identical except that its 4th template parameter - must be-a AccessorGetterType instead of an InCa type. - */ - template < typename ExceptionT, - typename SigGetMsg, - typename ConstMethodSignature::FunctionType Getter, - typename GetterT, - bool PropagateOtherExceptions = false - > - struct GetterCatcher : AccessorGetterType - { - static v8::Handle Get( v8::Local< v8::String > property, const v8::AccessorInfo & info ) - { - try - { - return GetterT::Get( property, info ); - } - catch( ExceptionT const & e2 ) - { - return Toss(CastToJS((e2.*Getter)())); - } - catch( ExceptionT const * e2 ) - { - return Toss(CastToJS((e2->*Getter)())); - } - catch(...) - { - if( PropagateOtherExceptions ) throw; - else return Toss("Unknown native exception thrown!"); - } - } - }; - - /** - A convenience form of GetterCatcher which catches std::exception - and subtyes. See InCaCatcher_std for full details - this type is - identical except that its first template parameter must be-a - AccessorGetterType instead of InCa type. - */ - template < - typename GetterT, - typename ConcreteException = std::exception, - bool PropagateOtherExceptions = !tmp::SameType< std::exception, ConcreteException >::Value - > - struct GetterCatcher_std : - GetterCatcher - {}; - - - /** - AccessAdder is a convenience class for use when applying several - (or more) accessor bindings to a prototype object. - - Example: - - @code - AccessorAdder acc(myPrototype); - acc("foo", MemberToGetter(), - MemberToSetter()) - ("bar", ConstMethodToGetter(), - MethodToSetter()) - ... - ; - @endcode - */ - class AccessorAdder - { - private: - v8::Handle const & proto; - - /** A "null" setter which does nothing. Used only as default - argument to operator(). Its Set() is not actually used - but this type is used as a placeholder for a NULL - v8::AccessorSetter. - */ - struct NullSetter - { - /** The v8::AccessorSetter() interface. */ - static void Set(v8::Local< v8::String > property, v8::Local< v8::Value > value, const v8::AccessorInfo &info) - { - } - }; - public: - /** - Initializes this object so that calls to operator() will - apply to p. p must out-live this object. More specifically, - operator() must not be called after p has been destroyed. - */ - explicit AccessorAdder( v8::Handle const & p ) - : proto(p) - {} - AccessorAdder const & operator()( char const * name, - v8::AccessorGetter g, - v8::AccessorSetter s = NULL, - v8::Handle< v8::Value > data=v8::Handle< v8::Value >(), - v8::AccessControl settings=v8::DEFAULT, - v8::PropertyAttribute attribute=v8::None) const - { - proto->SetAccessor(v8::String::New(name), g, s, data, settings, attribute); - return *this; - } - /** - Adds GetterT::Get and SetterT::Set as accessors for the - given property in the prototype object. - - GetterT must be-a AccessorGetterType. SetterT must be-a - AccessorSetterType. Note that their values are not used, - but GetterT::Get and SetterT::Set are used - directly. The objects are only passed in to keep the - client from having to specify them as template - parameters (which is clumsy for operator()), as their - types can be deduced. - - The 3rd and higher arguments are as documented (or not!) - for v8::ObjectTemplate::SetAccessor(). - - Returns this object, for chaining calls. - */ - template - AccessorAdder const & operator()( char const * name, - GetterT const &, - SetterT const & = NullSetter(), - v8::Handle< v8::Value > data=v8::Handle< v8::Value >(), - v8::AccessControl settings=v8::DEFAULT, - v8::PropertyAttribute attribute=v8::None) const - { - // jump through a small hoop to ensure identical semantics vis-a-vis - // the other overload. - return this->operator()( name, GetterT::Get, - tmp::SameType::Value ? NULL : SetterT::Set, - data, settings, attribute); - } - }; - -#if 0 /* i'm still undecided on the in-class naming conventions here... */ - /** - ClassAccessor provides a slight simplification for cases - where several different members/methods of a given bound - class (T) need to be bound to v8. It wraps the following - classes so that clients can use them one fewer template - parameters: - - MemberToGetter, MemberToSetter, MethodToGetter, MethodToSetter, - ConstMethodToGetter, ConstMethodToSetter - - Example: - - @code - typedef ClassAccessor CA; - v8::AccessorGetter get; - - get = MemberToGetter::Get - // is equivalent to: - get = CA::MemGet::Set - @endcode - - Its only real benefit is saving a bit of typing when several T - member/method bindings are made and T's real type name is longer - than 'T'. e.g. it gets tedious to repeatedly type - MyExceedinglyLongClassName in method/member-binding templates. - (Function-local typedefs help.) - */ - template - struct ClassAccessor - { - template - struct MemGet : MemberToGetter {}; - template - struct MemSet : MemberToSetter {}; - template ::FunctionType Getter> - struct MethGet : MethodToGetter {}; - template ::FunctionType Getter> - struct CMethGet : ConstMethodToGetter {}; - template ::FunctionType Setter> - struct MethSet : MethodToSetter {}; - template ::FunctionType Setter> - struct CMethSet : ConstMethodToSetter {}; - }; -#endif /* ClassAccessor */ - -} // namespaces -/** LICENSE - - This software's source code, including accompanying documentation and - demonstration applications, are licensed under the following - conditions... - - The author (Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) - explicitly disclaims copyright in all jurisdictions which recognize - such a disclaimer. In such jurisdictions, this software is released - into the Public Domain. - - In jurisdictions which do not recognize Public Domain property - (e.g. Germany as of 2011), this software is Copyright (c) 2011 - by Stephan G. Beal, and is released under the terms of the MIT License - (see below). - - In jurisdictions which recognize Public Domain property, the user of - this software may choose to accept it either as 1) Public Domain, 2) - under the conditions of the MIT License (see below), or 3) under the - terms of dual Public Domain/MIT License conditions described here, as - they choose. - - The MIT License is about as close to Public Domain as a license can - get, and is described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - -- - Copyright (c) 2011 Stephan G. Beal (http://wanderinghorse.net/home/stephan/) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - --END OF MIT LICENSE-- - - For purposes of the above license, the term "Software" includes - documentation and demonstration source code which accompanies - this software. ("Accompanies" = is contained in the Software's - primary public source code repository.) - -*/ -#endif /* CODE_GOOGLE_COM_P_V8_CONVERT_PROPERTIES_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/signature.hpp b/vendor/libv8-convert/cvv8/signature.hpp deleted file mode 100644 index 4961d7039..000000000 --- a/vendor/libv8-convert/cvv8/signature.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#if !defined(WANDERINGHORSE_NET_SIGNATURE_HPP_INCLUDED) -#define WANDERINGHORSE_NET_SIGNATURE_HPP_INCLUDED 1 - - -namespace cvv8 { -#include "detail/signature_core.hpp" -#include "detail/signature_generated.hpp" -} -/** LICENSE - - This software's source code, including accompanying documentation and - demonstration applications, are licensed under the following - conditions... - - The author (Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) - explicitly disclaims copyright in all jurisdictions which recognize - such a disclaimer. In such jurisdictions, this software is released - into the Public Domain. - - In jurisdictions which do not recognize Public Domain property - (e.g. Germany as of 2011), this software is Copyright (c) 2011 - by Stephan G. Beal, and is released under the terms of the MIT License - (see below). - - In jurisdictions which recognize Public Domain property, the user of - this software may choose to accept it either as 1) Public Domain, 2) - under the conditions of the MIT License (see below), or 3) under the - terms of dual Public Domain/MIT License conditions described here, as - they choose. - - The MIT License is about as close to Public Domain as a license can - get, and is described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - -- - Copyright (c) 2011 Stephan G. Beal (http://wanderinghorse.net/home/stephan/) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - --END OF MIT LICENSE-- - - For purposes of the above license, the term "Software" includes - documentation and demonstration source code which accompanies - this software. ("Accompanies" = is contained in the Software's - primary public source code repository.) - -*/ -#endif /* WANDERINGHORSE_NET_SIGNATURE_HPP_INCLUDED */ diff --git a/vendor/libv8-convert/cvv8/v8-convert.hpp b/vendor/libv8-convert/cvv8/v8-convert.hpp deleted file mode 100644 index 1ee91d73e..000000000 --- a/vendor/libv8-convert/cvv8/v8-convert.hpp +++ /dev/null @@ -1,169 +0,0 @@ -#if !defined(CODE_GOOGLE_COM_P_V8_CONVERT_V8_CONVERT_HPP_INCLUDED) -#define CODE_GOOGLE_COM_P_V8_CONVERT_V8_CONVERT_HPP_INCLUDED 1 - -// Doxygen REFUSES to use this block as namespace docs: @namespace cvv8 -/** @mainpage libv8-convert (cvv8) - -The cvv8 namespace (formerly v8::convert) houses APIs for handling the -following: - -- Converting between v8 Value handles and "native types" using generic -interface. This allows us to write generic algorithms which convert -between JS/C++ without having to know the exact types we're dealing -with. The basic POD types and some STL types are supported out of the -box and plugging in one's own types is normally quite simple. - -- Converting free- and member functions into v8::InvocationCallback -functions. These generated functions convert the JavaScript-originated -function arguments into native counterparts, forward the data to the -original native function, and convert the return values back to -something JS can use. - -Those two core features give us all we need in order to be able to -bind near-arbitrary C/C++ functions with JavaScript (where calling -conventions and type conversions allow us to do so). For cases where -the "automatic" function-to-InvocationCallback conversions are not -suitable, the type-conversion API can simplify the implementation of -custom v8::InvocationCallback functions. - -All of the conversions are compile-time typesafe where possible and -fail gracefully when such a determination can only be made at runtime. - -This code originated as the core-most component of the v8-juice -library (http://code.google.com/p/v8-juice). After a couple years -i felt compelled to refactor it into a toolkit usable by arbitrary -v8-using clients, doing a bit of cleanup along the way. The eventuall -intention is that this code will replace the v8::juice::convert -code. - -Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) - -License: Dual MIT/Public Domain - -Project home page: http://code.google.com/p/v8-juice/wiki/V8Convert - -The most important functions and types, from a user's perspective, -include: - -Converting types: - -- cvv8::CastToJS() -- cvv8::CastFromJS() - -Implementing custom conversions: - -- cvv8::NativeToJS -- cvv8::JSToNative - -Converting functions to v8::InvocationCallback: - -- cvv8::FunctionToInCa -- cvv8::MethodToInCa -- cvv8::ConstMethodToInCa -- cvv8::ToInCa -- cvv8::FunctorToInCa -- cvv8::PredicatedInCa and cvv8::PredicatedInCaDispatcher - -Binding JS properties to native properties, functions, methods, or -functors: - -- cvv8::FunctionToGetter, cvv8::FunctionToSetter -- cvv8::MethodToGetter, cvv8::MethodToSetter -- cvv8::ConstMethodToGetter, cvv8::ConstMethodToSetter -- cvv8::FunctorToGetter, cvv8::FunctorToSetter - -Other utilities: - -- cvv8::CtorForwarder and cvv8::CtorArityDispatcher -- cvv8::ClassCreator simplifies binding of C++ classes with v8. -- cvv8::FunctionTo converts functions to ... -- cvv8::MethodTo converts methods to ... -- cvv8::FunctorTo converts functors to ... -- cvv8::VarTo converts variables to ... -- cvv8::CallForwarder forwards native arguments to JS functions. -- The tmp and sl namespaces hold various template metaprogramming bits. -- ... there's more ... - -Most of the code in this library are internal template specializations -which take care of the dirty work. Typical clients won't typically need -more than what's listed above. - -A core rule of this library is "if it ain't documented, don't use -it." All public API members which are intended for client-side use -are documented. Some one-line proxies whose purpose is either very -obvious, exist only for template type resolution reasons, or -are strictly internal are not necessarily documented. - -*/ -namespace cvv8 { -} - -#include "convert.hpp" -#include "invocable.hpp" -#include "arguments.hpp" -#include "ClassCreator.hpp" -#include "properties.hpp" -#include "XTo.hpp" -/** LICENSE - - This software's source code, including accompanying documentation and - demonstration applications, are licensed under the following - conditions... - - The author (Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) - explicitly disclaims copyright in all jurisdictions which recognize - such a disclaimer. In such jurisdictions, this software is released - into the Public Domain. - - In jurisdictions which do not recognize Public Domain property - (e.g. Germany as of 2011), this software is Copyright (c) 2011 - by Stephan G. Beal, and is released under the terms of the MIT License - (see below). - - In jurisdictions which recognize Public Domain property, the user of - this software may choose to accept it either as 1) Public Domain, 2) - under the conditions of the MIT License (see below), or 3) under the - terms of dual Public Domain/MIT License conditions described here, as - they choose. - - The MIT License is about as close to Public Domain as a license can - get, and is described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - - The full text of the MIT License follows: - - -- - Copyright (c) 2011 Stephan G. Beal (http://wanderinghorse.net/home/stephan/) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - --END OF MIT LICENSE-- - - For purposes of the above license, the term "Software" includes - documentation and demonstration source code which accompanies - this software. ("Accompanies" = is contained in the Software's - primary public source code repository.) - -*/ - -#endif /* CODE_GOOGLE_COM_P_V8_CONVERT_V8_CONVERT_HPP_INCLUDED */ diff --git a/vendor/naturaldocs/Config/Languages.txt b/vendor/naturaldocs/Config/Languages.txt deleted file mode 100644 index 28adf6186..000000000 --- a/vendor/naturaldocs/Config/Languages.txt +++ /dev/null @@ -1,286 +0,0 @@ -Format: 1.51 - -# This is the main Natural Docs languages file. If you change anything here, -# it will apply to EVERY PROJECT you use Natural Docs on. If you'd like to -# change something for just one project, edit the Languages.txt in its project -# directory instead. - - -#------------------------------------------------------------------------------- -# SYNTAX: -# -# Unlike other Natural Docs configuration files, in this file all comments -# MUST be alone on a line. Some languages deal with the # character, so you -# cannot put comments on the same line as content. -# -# Also, all lists are separated with spaces, not commas, again because some -# languages may need to use them. -# -# Language: [name] -# Defines a new language. Its name can use any characters. -# -# The language Shebang Script is special. It's entry is only used for -# extensions, and files with those extensions have their shebang (#!) lines -# read to determine the real language of the file. Extensionless files are -# always treated this way. -# -# The language Text File is also special. It's treated as one big comment -# so you can put Natural Docs content in them without special symbols. Also, -# if you don't specify a package separator, ignored prefixes, or enum value -# behavior, it will copy those settings from the language that is used most -# in the source tree. -# -# Extensions: [extension] [extension] ... -# Defines the file extensions of the language's source files. You can use * -# to mean any undefined extension. -# -# Shebang Strings: [string] [string] ... -# Defines a list of strings that can appear in the shebang (#!) line to -# designate that it's part of the language. -# -# Ignore Prefixes in Index: [prefix] [prefix] ... -# Ignore [Topic Type] Prefixes in Index: [prefix] [prefix] ... -# Specifies prefixes that should be ignored when sorting symbols in an -# index. Can be specified in general or for a specific topic type. -# -#------------------------------------------------------------------------------ -# For basic language support only: -# -# Line Comments: [symbol] [symbol] ... -# Defines a space-separated list of symbols that are used for line comments, -# if any. -# -# Block Comments: [opening sym] [closing sym] [opening sym] [closing sym] ... -# Defines a space-separated list of symbol pairs that are used for block -# comments, if any. -# -# Package Separator: [symbol] -# Defines the default package separator symbol. The default is a dot. -# -# [Topic Type] Prototype Enders: [symbol] [symbol] ... -# When defined, Natural Docs will attempt to get a prototype from the code -# immediately following the topic type. It stops when it reaches one of -# these symbols. Use \n for line breaks. -# -# Line Extender: [symbol] -# Defines the symbol that allows a prototype to span multiple lines if -# normally a line break would end it. -# -# Enum Values: [global|under type|under parent] -# Defines how enum values are referenced. The default is global. -# global - Values are always global, referenced as 'value'. -# under type - Values are under the enum type, referenced as -# 'package.enum.value'. -# under parent - Values are under the enum's parent, referenced as -# 'package.value'. -# -# Perl Package: [perl package] -# Specifies the Perl package used to fine-tune the language behavior in ways -# too complex to do in this file. -# -#------------------------------------------------------------------------------ -# For full language support only: -# -# Full Language Support: [perl package] -# Specifies the Perl package that has the parsing routines necessary for full -# language support. -# -#------------------------------------------------------------------------------- - -# The following languages MUST be defined in this file: -# -# Text File, Shebang Script - -# If you add a language that you think would be useful to other developers -# and should be included in Natural Docs by default, please e-mail it to -# languages [at] naturaldocs [dot] org. - - -Language: Text File - - Extension: txt - - -Language: Shebang Script - - Extension: cgi - - -Language: C/C++ - - Extensions: c cpp h hpp cxx hxx - Ignore Function Prefix in Index: ~ - Line Comment: // - Block Comment: /* */ - Package Separator: :: - Enum Values: Under parent - Class Prototype Enders: ; { - Function Prototype Enders: ; { - Variable Prototype Enders: ; = - - -Language: C# - - Extension: cs - Ignore Prefix in Index: @ - Full Language Support: NaturalDocs::Languages::CSharp - - -Language: Java - - Extension: java - Line Comment: // - Block Comment: /* */ - Enum Values: Under type - Function Prototype Ender: { - Variable Prototype Enders: ; = - - -Language: JavaScript - - Extension: js - Line Comment: // - Block Comment: /* */ - Enum Values: Under type - Function Prototype Ender: { - Variable Prototype Enders: ; = , } - - -Language: Perl - - Extensions: pl pm - Shebang String: perl - Ignore Variable Prefixes in Index: $ @ % * - Full Language Support: NaturalDocs::Languages::Perl - - -Language: Python - - Extension: py - Shebang String: python - Line Comment: # - Function Prototype Ender: : - Variable Prototype Ender: = - Line Extender: \ - - -Language: PHP - - Extensions: inc php php3 php4 phtml - Shebang String: php - Ignore Variable Prefix in Index: $ - Line Comments: // # - Block Comment: /* */ - Function Prototype Enders: ; { - Variable Prototype Enders: ; = - - -Language: SQL - - Extension: sql - Line Comment: -- - Block Comment: /* */ - Enum Values: Global - Function Prototype Enders: , ; ) as As AS is Is IS - Variable Prototype Enders: , ; ) := default Default DEFAULT - Database Index Prototype Enders: , ; ) - Database Trigger Prototype Enders: begin Begin BEGIN as As AS - Perl Package: NaturalDocs::Languages::PLSQL - - -Language: Visual Basic - - Extensions: vb vbs bas cls frm - Line Comment: ' - Enum Values: Under type - Function Prototype Ender: \n - Variable Prototype Enders: \n = - Line Extender: _ - - -Language: Pascal - - Extension: pas - Line Comment: // - Block Comments: { } (* *) - Function Prototype Ender: ; - Variable Prototype Enders: ; = - Perl Package: NaturalDocs::Languages::Pascal - - -Language: Assembly - - Extension: asm - Line Comment: ; - Variable Prototype Ender: \n - Line Extender: \ - - -Language: Ada - - Extensions: ada ads adb - Line Comment: -- - Function Prototype Enders: ; is Is IS - Variable Prototype Enders: ; := - Perl Package: NaturalDocs::Languages::Ada - - -Language: Tcl - - Extensions: tcl exp - Shebang Strings: tclsh wish expect - Line Comment: # - Package Separator: :: - Function Prototype Enders: ; { - Variable Prototype Enders: ; \n - Line Extender: \ - Perl Package: NaturalDocs::Languages::Tcl - - -Language: Ruby - - Extension: rb - Shebang String: ruby - Ignore Variable Prefixes in Index: $ @ @@ - Line Comment: # - Enum Values: Under parent - Function Prototype Enders: ; \n - Variable Prototype Enders: ; \n = - Line Extender: \ - - -Language: Makefile - - Extensions: mk mak make - Line Comment: # - - -Language: ActionScript - - Extensions: as mxml - Full Language Support: NaturalDocs::Languages::ActionScript - - -Language: ColdFusion - - Extensions: cfm cfml cfc - Line Comment: // - Block Comments: /* */ - Function Prototype Enders: { < - - -Language: R - - Extension: r - Line Comment: # - Function Prototype Enders: { ; - Variable Prototype Enders: <- = ; \n - - -Language: Fortran - - Extensions: f90 f95 f03 - Line Comment: ! - Function Prototype Ender: \n - Variable Prototype Enders: \n = => - Line Extender: & diff --git a/vendor/naturaldocs/Config/Topics.txt b/vendor/naturaldocs/Config/Topics.txt deleted file mode 100644 index 9a10469b6..000000000 --- a/vendor/naturaldocs/Config/Topics.txt +++ /dev/null @@ -1,382 +0,0 @@ -Format: 1.51 - -# This is the main Natural Docs topics file. If you change anything here, it -# will apply to EVERY PROJECT you use Natural Docs on. If you'd like to -# change something for just one project, edit the Topics.txt in its project -# directory instead. - - -#------------------------------------------------------------------------------- -# SYNTAX: -# -# Topic Type: [name] -# Creates a new topic type. Each type gets its own index and behavior -# settings. Its name can have letters, numbers, spaces, and these -# charaters: - / . ' -# -# The Enumeration type is special. It's indexed with Types but its members -# are indexed with Constants according to the rules in Languages.txt. -# -# Plural: [name] -# Sets the plural name of the topic type, if different. -# -# Keywords: -# [keyword] -# [keyword], [plural keyword] -# ... -# Defines a list of keywords for the topic type. They may only contain -# letters, numbers, and spaces and are not case sensitive. Plural keywords -# are used for list topics. -# -# Index: [yes|no] -# Whether the topics get their own index. Defaults to yes. Everything is -# included in the general index regardless of this setting. -# -# Scope: [normal|start|end|always global] -# How the topics affects scope. Defaults to normal. -# normal - Topics stay within the current scope. -# start - Topics start a new scope for all the topics beneath it, -# like class topics. -# end - Topics reset the scope back to global for all the topics -# beneath it. -# always global - Topics are defined as global, but do not change the scope -# for any other topics. -# -# Class Hierarchy: [yes|no] -# Whether the topics are part of the class hierarchy. Defaults to no. -# -# Page Title If First: [yes|no] -# Whether the topic's title becomes the page title if it's the first one in -# a file. Defaults to no. -# -# Break Lists: [yes|no] -# Whether list topics should be broken into individual topics in the output. -# Defaults to no. -# -# Can Group With: [type], [type], ... -# Defines a list of topic types that this one can possibly be grouped with. -# Defaults to none. -#------------------------------------------------------------------------------- - -# The following topics MUST be defined in this file: -# -# Generic, Class, Interface, Section, File, Group, Function, Variable, -# Property, Type, Constant, Enumeration, Event, Delegate - -# If you add something that you think would be useful to other developers -# and should be included in Natural Docs by default, please e-mail it to -# topics [at] naturaldocs [dot] org. - - -Topic Type: Generic - - Index: No - Keywords: - topic, topics - about, list - - -Topic Type: Class - - Plural: Classes - Scope: Start - Class Hierarchy: Yes - Page Title If First: Yes - Can Group With: Interfaces - - Keywords: - class, classes - structure, structures - struct, structs - package, packages - namespace, namespaces - - -Topic Type: Interface - - Plural: Interfaces - Scope: Start - Class Hierarchy: Yes - Page Title If First: Yes - Can Group With: Classes - - Keywords: - interface, interfaces - - -Topic Type: Section - - Plural: Sections - Index: No - Scope: End - Page Title If First: Yes - - Keywords: - section - title - - -Topic Type: File - - Plural: Files - Scope: Always global - Page Title If First: Yes - - Keywords: - file, files - program, programs - script, scripts - document, documents - doc, docs - header, headers - - -Topic Type: Group - - Plural: Groups - Index: No - - Keywords: - group - - -Topic Type: Function - - Plural: Functions - Break Lists: Yes - Can Group With: Properties - - Keywords: - function, functions - func, funcs - procedure, procedures - proc, procs - routine, routines - subroutine, subroutines - sub, subs - method, methods - callback, callbacks - constructor, constructors - destructor, destructors - operator, operators - - -Topic Type: Variable - - Plural: Variables - Can Group With: Types, Constants, Macros, Enumerations - - Keywords: - variable, variables - var, vars - integer, integers - int, ints - uint, uints - long, longs - ulong, ulongs - short, shorts - ushort, ushorts - byte, bytes - ubyte, ubytes - sbyte, sbytes - float, floats - double, doubles - real, reals - decimal, decimals - scalar, scalars - array, arrays - arrayref, arrayrefs - hash, hashes - hashref, hashrefs - bool, bools - boolean, booleans - flag, flags - bit, bits - bitfield, bitfields - field, fields - pointer, pointers - ptr, ptrs - reference, references - ref, refs - object, objects - obj, objs - character, characters - wcharacter, wcharacters - char, chars - wchar, wchars - string, strings - wstring, wstrings - str, strs - wstr, wstrs - handle, handles - - -Topic Type: Property - - Plural: Properties - Can Group With: Functions - - Keywords: - property, properties - prop, props - - -Topic Type: Type - - Plural: Types - Can Group With: Variables, Constants, Macros, Enumerations - - Keywords: - type, types - typedef, typedefs - - -Topic Type: Constant - - Plural: Constants - Can Group With: Variables, Types, Macros, Enumerations - - Keywords: - constant, constants - const, consts - - -Topic Type: Enumeration - - Plural: Enumerations - Index: No - Can Group With: Variables, Types, Macros, Constants - - Keywords: - enum, enums - enumeration, enumerations - - -Topic Type: Event - - Plural: Events - Keywords: - event, events - - -Topic Type: Delegate - - Plural: Delegates - Keywords: - delegate, delegates - - -Topic Type: Macro - - Plural: Macros - Can Group With: Variables, Types, Constants - - Keywords: - define, defines - def, defs - macro, macros - - -Topic Type: Database - - Plural: Databases - Page Title If First: Yes - - Keywords: - database, databases - db, dbs - - -Topic Type: Database Table - - Plural: Database Tables - Scope: Start - Page Title If First: Yes - - Keywords: - table, tables - database table, database tables - databasetable, databasetables - db table, db tables - dbtable, dbtables - - -Topic Type: Database View - - Plural: Database Views - Scope: Start - Page Title If First: Yes - - Keywords: - view, views - database view, database views - databaseview, databaseviews - db view, db views - dbview, dbviews - - -Topic Type: Database Index - - Plural: Database Indexes - Keywords: - index, indexes - index, indices - database index, database indexes - database index, database indices - databaseindex, databaseindexes - databaseindex, databaseindices - db index, db indexes - db index, db indices - dbindex, dbindexes - dbindex, dbindices - key, keys - database key, database keys - databasekey, databasekeys - db key, db keys - dbkey, dbkeys - primary key, primary keys - primarykey, primarykeys - database primary key, database primary keys - databaseprimarykey, databaseprimarykeys - db primary key, db primary keys - dbprimarykey, dbprimarykeys - - -Topic Type: Database Cursor - - Plural: Database Cursors - Keywords: - cursor, cursors - database cursor, database cursors - databasecursor, databasecursors - db cursor, db cursors - dbcursor, dbcursors - - -Topic Type: Database Trigger - - Plural: Database Triggers - Keywords: - trigger, triggers - database trigger, database triggers - databasetrigger, databasetriggers - db trigger, db triggers - dbtrigger, dbtriggers - - -Topic Type: Cookie - - Plural: Cookies - Scope: Always global - - Keywords: - cookie, cookies - - -Topic Type: Build Target - - Plural: Build Targets - Keywords: - target, targets - build target, build targets - buildtarget, buildtargets diff --git a/vendor/naturaldocs/Help/customizinglanguages.html b/vendor/naturaldocs/Help/customizinglanguages.html deleted file mode 100644 index 0b579d96c..000000000 --- a/vendor/naturaldocs/Help/customizinglanguages.html +++ /dev/null @@ -1,52 +0,0 @@ - - -Customizing Natural Docs Languages - - - -
Natural Docs
Customizing
Organizing the MenuCSS StylesTopics and KeywordsLanguages, Indexes,
and Prototypes
Customizing Languages
Languages.txt

Natural Docs has two files called Languages.txt: one in its Config directory, and one in your project directory.  These control the language, index prefix, and prototype features of Natural Docs.

You should edit the one in your project directory whenever possible.  It keeps your changes separate and easier to manage, plus you don’t have to reapply them whenever you upgrade.  Editing the one in Natural Docs’ Config directory would be better only if you’re using Natural Docs with a lot of projects and would like the changes to apply everywhere.

Note that unlike other Natural Docs configuration files, comments can only appear on their own lines.  They cannot appear after something else on a line because settings may need to use the # symbol.  Also, all lists are space-separated instead of comma-separated, again because some settings may need to use the comma symbol.

File Extensions

If Natural Docs doesn’t recognize a file extension you use for your code, it’s not a problem.  You can alter the language definition from your project file to add them.

Alter Language: [your language]
-   Add Extensions: cxx hxx

On the other hand, if it’s scanning some files you don’t want it to scan, you can exclude extensions as well.  Just add this to the top of your file:

Ignore Extensions: c cpp

In this example, Natural Docs will ignore C++ source files, thus only scanning the headers.

Adding Languages

You can add basic language support for any programming language just by editing these configuration files.  Here are the most important settings:

Language: Fictional
-
-   Extensions: fsrc fhdr
-   Shebang Strings: fictional
-   Line Comment: //
-   Block Comment: /* */
-   Package Separator: ::

This tells Natural Docs that any files with the .fsrc or .fhdr extensions are part of our fictional programming language.  Also, any .cgi or extensionless files that have “fictional” in the shebang (#!) line are part of it as well.  Line comments start with // and block comments appear between /* and */.  The default package separator is ::.  Not too hard, huh?

You can also add settings to ignore prefixes in the index and detect prototypes, but those are dealt with in their own sections on this page.

Prototypes

So you’ve added a new language and want to detect prototypes.  Or perhaps you added a custom topic type and want to detect prototypes for that as well.  Here’s an example of the properties you need:

Function Prototype Enders: ; {
-Variable Prototype Enders: ; =

The algorithm for finding prototypes is very simple, yet it works really well in practice.  All the code following the comment is grabbed until it reaches an ender symbol or another comment.  Ender symbols appearing inside parenthesis, brackets, braces, or angle brackets don’t count.  If it reaches an ender symbol and somewhere in that code is the topic title, the code is accepted as the prototype.

So in the example above, variables end at semicolons (the end of the declaration) or equal signs (the default value expression, which we don’t want to include.)  Since the Natural Docs comment for the variable should have appeared right before the definition, that leaves us with the name and type.  Functions are handled similarly: they end at a semicolon (the end of a predeclaration) or an opening brace (the beginning of the body) leaving us with the name, parameters, and return type.

You can do this with any topic type, including custom ones.  Any prototypes that look like they have parameters will be formatted as such automatically.

Line Breaks

For some languages, line breaks are significant.  To have them end a prototype, use \n.  If it has an extender symbol that allows the code to continue on the next line, you can specify that as well.

Function Prototype Ender: \n
-Variable Prototype Ender: \n =
-Line Extender: _
Colors

If you’re collecting prototypes for a custom topic type, they will not automatically get their own background color like the other types have.  You have to define it via CSS.

Index Prefixes

Natural Docs has the ability to ignore prefixes in the indexes.  This is necessary because in certain languages, variables are prefixed with $ or other symbols and we don’t want them to get all grouped together under the symbols heading.  Instead, they appear in the sidebar and are sorted as if they’re not there.

A
 AddProperty, SomeClass
$amount
 Average

However, we can take advantage of this simply to get around coding conventions.  Suppose you prefix all your class names with C.  They’d all form one gigantic group under C in the index.  If you want, you can have it ignored so CCat, CDog, and CMouse get filed under C, D, and M instead.  Just add this to your languages file:

Alter Language: [your language]
-   Add Ignored Class Prefix in Index: C

Now C is ignored in your indexes:

A
CAccount
CAccountHolder
 AddProperty, SomeClass
$amount
 Average

You can include any number of prefixes and can do this for any topic type.  So if you have a bunch of functions that start with COM_ and DB_, you can ignore them too:

Alter Language: [your language]
-   Add Ignored Class Prefix in Index: C
-   Add Ignored Function Prefixes in Index: COM_ DB_
Special Languages

There are two languages with special properties: Shebang Script and Text File.

Shebang Script allows you to define the file extensions where the language is really determined by the shebang (#!) line within it.  For example, .cgi files.  If Natural Docs finds a .cgi file, it sees that it’s a Shebang Script so it opens it up to parse it’s shebang line.  It then searches it for substrings defined by other languages’ Shebang String settings to find out what language it really is.  Files with no extension are always treated this way.

With Text File, the entire file is treated like a comment.  There are no comment symbols required, you can just put Natural Docs content there in plain text.  The most important setting is Extensions.

However, since it is possible to document classes, functions, etc. in text files, they also have their own Package Separator and Ignored [type] Prefixes in Index settings.  To make things easier on you, by default it copies these settings from whichever language has the most source files in your project.  You can override this by manually setting them, but you shouldn’t need to.

Syntax Reference

Unlike other Natural Docs configuration files, comments can only appear on their own lines.  They cannot appear after something else on a line because settings may need to use the # symbol.  Likewise, lists are separated with spaces instead of commas because commas themselves may need to appear on the list.

Singular and plural forms are generally both supported, so you can write Extension or Extensions.  It doesn’t matter if they match how many items are set.  Also, you can use either Ignore or Ignored.

Ignore Extensions: [extension] [extension] ...

Causes the listed file extensions to be ignored, even if they were previously defined to be part of a language.  The list is space-separated.  ex. “Ignore Extensions: cvs txt

Language: [name]
-Alter Language: [name]

Creates a new language or alters an existing one.  Names can use any characters.  Note the special behavior for languages named Shebang Script and Text File.

If you’re altering an existing language and a property has an [Add/Replace] form, you have to specify whether you’re adding to or replacing the list if that property has already been defined.

General Language Properties
Extensions: [extension] [extension] ...
-[Add/Replace] Extensions: [extension] [extension] ...

Defines file extensions for the language’s source files.  The list is space-separated.  ex. “Extensions: c cpp”.  You can use extensions that were previously used by another language to redefine them.  You can use * to specify all undefined extensions.

Shebang Strings: [string] [string] ...
-[Add/Replace] Shebang Strings: [string] [string] ...

Defines a list of strings that can appear in the shebang (#!) line to designate that it’s part of this language.  They can appear anywhere in the line, so php will work for “#!/user/bin/php4”.  You can use strings that were previously used by another language to redefine them.

Ignore Prefixes in Index: [prefix] [prefix] ...
-Ignore [type] Prefixes in Index: [prefix] [prefix] ...
-
-[Add/Replace] Ignored Prefixes in Index: [prefix] [prefix] ...
-[Add/Replace] Ignored [type] Prefixes in Index: [prefix] [prefix] ...

Specifies prefixes that should be ignored when sorting symbols for an index.  Can be specified in general or for a specific topic type.  The prefixes will still appear, the symbols will just be sorted as if they’re not there.  For example, specifying ADO_ for functions will mean that ADO_DoSomething will appear under D instead of A.

Basic Language Support Properties

These attributes are only available for languages with basic language support.

Line Comments: [symbol] [symbol] ...

Defines a space-separated list of symbols that are used for line comments, if any.  ex. “Line Comment: //”.

Block Comments: [opening symbol] [closing symbol] [o.s.] [c.s.] ...

Defines a space-separated list of symbol pairs that are used for block comments, if any.  ex. “Block Comment: /* */”.

Enum Values: [global|under type|under parent]

Defines the behavior of enum values.  The default is global.

GlobalEnum values are always global and will be referenced as “Value”.
Under TypeEnum values appear under the type and will be referenced as “Package.Enum.Value”.
Under ParentEnum values appear under the parent and will be referenced as “Package.Value”
[type] Prototype Enders: [symbol] [symbol] ...

When defined, Natural Docs will attempt to collect prototypes from the code following the specified topic type.  It grabs code until the first ender symbol or the next Natural Docs comment, and if it contains the topic name, it serves as its prototype.  Use \n to specify a line break.  ex. “Function Prototype Enders: { ;”, “Variable Prototype Enders: = ;”.

Line Extender: [symbol]

Defines the symbol that allows a prototype to span multiple lines if normally a line break would end it.

Perl Package: [perl package]

Specifies the Perl package used to fine-tune the language behavior in ways too complex to do in this file.

Full Language Support Properties

These attributes are only available for languages with full language support.

Full Language Support: [perl package]

Specifies the Perl package that has the parsing routines necessary for full language support.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/customizingtopics.html b/vendor/naturaldocs/Help/customizingtopics.html deleted file mode 100644 index 92a17f293..000000000 --- a/vendor/naturaldocs/Help/customizingtopics.html +++ /dev/null @@ -1,74 +0,0 @@ - - -Customizing Natural Docs Topics - - - -
Natural Docs
Customizing Topics
Topics.txt

Natural Docs has two files called Topics.txt: one in its Config directory, and one in your project directory.  These control the topic behavior and keywords Natural Docs uses.

You should edit the one in your project directory whenever possible.  It keeps your changes separate and easier to manage, plus you don’t have to reapply them whenever you upgrade.  Editing the one in Natural Docs’ Config directory would be better only if you’re using Natural Docs with a lot of projects and would like the changes to apply everywhere.

Topic Types vs. Keywords

It’s important to understand the difference between topic types and keywords.  Topic types have their own indexes and behavior settings.  You’ll reference them by name when dealing with indexes in the menu file or prototype detection in the language file, but not when documenting your code unless you make their names keywords as well.

You use keywords when documenting your code.  There can be many keywords per topic type, and they are completely interchangable.

Suppose you document a class with the Class keyword and a struct with Struct.  They are both keywords for the Class topic type by default, so they will appear in the same index.  If you wanted structs to have their own index, you would add a topic type for structs and change the Struct keyword to point to it.

Adding Topic Types

If you want to be able to document something in Natural Docs doesn’t handle by default, you want to create your own topic type for it.  Let’s say you’re working on a video game and you want to document all the sound effects because you want to keep track of what each one is for and have an index of them.  You’d add this to your topics file:

Topic Type: Sound Effect
-   Plural: Sound Effects
-   Keywords:
-      sound
-      sound effect
-

Sound effects can now be documented with the sound or sound effect keywords, and they’ll get their own index.  The Plural line just specifies the plural name of the topic type.  It isn’t required, but Natural Docs will use it in some places where the plural would sound more natural, like when grouping topics or naming indexes on the menu.

Here are a couple of other things you may want to add:

Topic Type: Sound Effect
-   Plural: Sound Effects
-   Scope: Always Global
-   Keywords:
-      sound, sounds
-      sound effect, sound effects
-

You can set the scope behavior of the topic type.  Your options are:

NormalTopics stay within the current scope.
StartTopics start a new scope for all the topics beneath it, like class topics.
EndTopics reset the scope back to global for all the topics beneath it.
Always GlobalTopics are defined as global, but do not change the scope for any other topics.

Here we set it to Always Global so that if we document one as part of a class, it will still be global yet will not break the class’ scope.  In other words, we can always link to it with just its name instead of needing something like <Class.Sound>.

The other thing we did was add plural keywords, which you do by using a comma after an existing keyword.  These keywords are used for list topics so we don’t have to document each one individually with the full syntax.

There are more options, these are just the most important ones.  See the full syntax reference for the rest.

Prototypes

If you’d like to collect prototypes for your new topic type, you have to do that by editing Languages.txt.

Changing Keywords
Adding and Changing

If you’re defining your own topic type or editing the main topics file, you simply add to the keywords list:

Topic Type: Sound Effect
-   Keywords:
-      sound, sounds
-      sound effect, sound effects
-

It doesn’t matter if the keyword was previously defined for a different topic type.  Just define it again and the definition will change.

If you want to add keywords to one of the main topic types from the project file, use Alter Topic Type instead:

Alter Topic Type: General
-   Keywords:
-      note
-      notes
-

Natural Docs will keep a list of the main file’s topic types in your project file so that you can do this easily.

Ignoring

Sometimes a keyword just gets in the way.  It’s too common in your comments and Natural Docs keeps accidentally picking them up as topics when that isn’t what you wanted.  You can get rid of keywords completely by either deleting them from the main file or putting this in your project file:

Ignore Keywords:
-   about
-   title
-

If you only have a few, you can use this syntax as well:

Ignore Keywords: note, notes, title
-
Altering Behavior

You can change the behavior of any topic type defined in the main file via your project file.  Just use Alter Topic Type and redefine any property.

Alter Topic Type: Constant
-   Scope: Always Global
-

Natural Docs will keep a list of the main file’s topic types in your project file so you can do this easily.  See the syntax reference below for a full list of your options.

Syntax Reference
Ignore Keywords: [keyword], [keyword] ...
-   [keyword]
-   [keyword], [keyword]
-   ...
-

Ignores the keywords so that they’re not recognized as Natural Docs topics anymore.  Can be specified as a list on the same line and/or following like a normal Keywords section.

Topic Type: [name]
-Alter Topic Type: [name]
-

Creates a new topic type or alters an existing one.  The name can only contain letters, numbers, spaces, and these characters: . - ‘ /.  It isn’t case sensitive, although the original case is remembered for presentation.

There are a number of default types that must be defined in the main file, but they will be listed there since it may change between versions.  The default types can have their keywords or behaviors changed, though, either by editing the default file or by overriding them in the user file.

Properties
Plural: [name]
-

Specifies the plural name of the topic type.  Defaults to the singular name.  Has the same restrictions as the topic type name.

Index: [yes|no]
-

Whether the topic type gets an index.  Defaults to yes.

Scope: [normal|start|end|always global]
-

How the topic affects scope.  Defaults to normal.

NormalTopics stay within the current scope.
StartTopics start a new scope for all the topics beneath it, like class topics.
EndTopics reset the scope back to global for all the topics beneath it.
Always GlobalTopics are defined as global, but do not change the scope for any other topics.
Class Hierarchy: [yes|no]
-

Whether the topic is part of the class hierarchy.  Defaults to no.

Page Title if First: [yes|no]
-

Whether the title of this topic becomes the page title if it is the first topic in a file.  Defaults to no.

Break Lists: [yes|no]
-

Whether list topics should be broken into individual topics in the output.  Defaults to no.

Can Group With: [topic type], [topic type], ...
-

Lists the topic types that can be grouped with this one in the output.  If two or more topic types often appear together, like Functions and Properties, this will allow them to be grouped together under one heading if it would cause too many groups otherwise.

Keywords:
-   [keyword]
-   [keyword], [plural keyword]
-   ...
-

A list of the topic type’s keywords.  Each line after the heading is the keyword and optionally its plural form.  This continues until the next line in “keyword: value” format.

  • Keywords can only have letters, numbers, and spaces.  No punctuation or symbols are allowed.
  • Keywords are not case sensitive.
  • Subsequent keyword sections add to the list.  They don’t replace it.
  • Keywords can be redefined by appearing in later keyword sections.
Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/documenting.html b/vendor/naturaldocs/Help/documenting.html deleted file mode 100644 index 465ca9538..000000000 --- a/vendor/naturaldocs/Help/documenting.html +++ /dev/null @@ -1,58 +0,0 @@ - - -Documenting Your Code - Natural Docs - - - -
Natural Docs
Using
Documenting
Your Code
KeywordsRunningTroubleshooting
Documenting Your Code

Here’s a quick example of how to document your code for Natural Docs.  If you’re a new user, we have a walkthrough to get you started.  Otherwise, visit the reference for the full details.

/*
-   Function: Multiply
-
-   Multiplies two integers.
-
-   Parameters:
-
-      x - The first integer.
-      y - The second integer.
-
-   Returns:
-
-      The two integers multiplied together.
-
-   See Also:
-
-      <Divide>
-*/
-int Multiply (int x, int y)
-   {  return x * y;  };
Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/documenting/reference.html b/vendor/naturaldocs/Help/documenting/reference.html deleted file mode 100644 index 3a6b5f34d..000000000 --- a/vendor/naturaldocs/Help/documenting/reference.html +++ /dev/null @@ -1,147 +0,0 @@ - - -Documenting Your Code: Reference - Natural Docs - - - -
Natural Docs
Documenting Your Code
int Add (int x,
int y)
Adds two integers.
int Subtract (int x,
int y)
Subtracts two integers.
int Multiply (int x,
int y)
Multiplies two integers.
int Divide (int x,
int y)
Divides two integers.
bool IsEqual (int x,
int y)
Returns whether two integers are equal.
Comments

There is no special comment style for Natural Docs.  You just embed Natural Docs topics into regular comments, and it’s pretty tolerant as far as style goes.  You can use block comments or string together line comments.  The only requirement is that the comments are not on the same line as code.

/* Function: Multiply
-   Multiplies two integers and returns the result. */
-
-// Function: Multiply
-// Multiplies two integers and returns the result.
-

Note that when stringing line comments together, blank lines that you want to include in the documentation must start with the comment symbol as well.  If a line is completely blank, it’s considered the end of the comment and thus the end of the Natural Docs topic.

Boxes and Horizontal Lines

Natural Docs can also handle comment boxes and horizontal lines.  It doesn’t matter what symbols they use.  The boxes don’t need to be closed on the right side, and they can have different symbols for the edges and corners.

/*
- * Function: Multiply
- * Multiplies two integers and returns the result.
- */
-
-/* +-------------------------------------------------+
-   | Function: Multiply                              |
-   | Multiplies two integers and returns the result. |
-   +-------------------------------------------------+ */
-
-//////////////////////////////////////////////////////////////
-//
-//  Function: Multiply
-//  ------------------
-//
-//  Multiplies two integers together and returns the result.
-//
-//////////////////////////////////////////////////////////////
-
Javadoc Style

If you have full language support, you can also use Javadoc-style comments to write Natural Docs documentation.  To do this you repeat the last symbol on the first line of the comment once.  The comment must appear directly above what it’s documenting, and you can omit the topic line if you want (the “Function: Multiply” part.)

/**
- * Multiplies two integers and returns the result.
- */
-
-///
-// Multiplies two integers together and returns the result.
-

If you omit the topic line and include any Javadoc tags in the comment, like @param, the entire comment will be treated as Javadoc and can only use Javadoc formatting.  Otherwise it’s treated as a Natural Docs comment and you can use all the formatting options described on this page.  You can have both styles in the same source file, but not in the same comment.

Perl POD

Perl users can also use POD to do block comments.

=begin nd
-
-Function: Multiply
-Multiplies two integers and returns the result.
-
-=cut
-

You can also use NaturalDocs or Natural Docs in place of ND.  None of them are case sensitive.  If for some reason you want to go back to POD documentation instead of using =cut, you can write =end nd.

There’s a second form of just =nd which is offered as a convenience.  However, it is not valid POD.  Perl will skip over it and execute fine, but POD parsers will give errors and possibly include the unformatted text in the output.  Use the longer, valid form unless you know for certain that no one will ever try to run POD on your code.

=nd
-
-Function: Multiply
-Multiplies two integers and returns the result.
-
-=cut
-
Text Files

Documentation can also be included in text files.  Any file with a .txt extension appearing in the source tree and starting with a topic line will included in the documentation.  It will be treated the same as a source file, meaning it will appear in the menu, its topics will be in the indexes, and its topics can be linked to from anywhere in the documentation.  The only difference is you don’t need comment symbols.

Remember that the topic line is required to be the first line of content.  If the first non-blank line is not in the “Function: Multiply” format the file will be ignored.  An easy way to do this is to use the Title keyword, although all of the other ones will work as well.

Title: License
-
-This project is licensed under the GPL.
-

This method is convenient for documenting file formats, configuration settings, the general program architecture, or anything else that isn’t directly tied to a source file.

Keywords, Topics, and Scope

A topic in Natural Docs starts with a topic line in the format “keyword: name”.  You can have multiple topics per comment as long as you separate them with a blank line.  The keywords aren’t case sensitive.

The list of keywords is pretty predictable: Function, Class, Variable, etc.  Just use what you’re documenting.  There are many synonyms as well, so you can use keywords like Func, Procedure, Proc, Method and Constructor.  Look at the full list of keywords to see everything that’s available.

The list of keywords is separated into topic types.  Each type gets its own index, and which specific keyword you use doesn’t matter.  Some also have scoping rules or other behavior as noted.

Scope

Like the code it’s documenting, Natural Docs topics have scope.  This mostly has to do with linking: if you’re in a class you can link to its members by their name alone, but if you’re not, you have to use a notation like class.member or class::member.

If you have full language support and are documenting something that appears in the code, the scope will be handled automatically.  If you’re using text files, have basic language support, or are including a topic that doesn’t correspond to something in the code, scoping follows these rules:

List Topics

If you looked at the list, you saw that most of the keywords have plural forms.  That’s for list topics, which let you document many small things without using the full syntax.  Anything that appears in definition lists within that topic will be treated as if it had its own topic.  It will appear in the indexes and be linkable, just like normal topics.

Function list topics will automatically break apart in the output as well, so it will look the same as if you documented each one individually.

Linking

Linking is the one place where Natural Docs has some negative effect on the readability of the comments.  The alternative would be to automatically guess where links should be, but systems that do that can sometimes pepper your sentences with unintentional links to functions called “is” or “on”.  However, the Natural Docs syntax is still as minimal as possible.  Simply surround any topic you want to link to with angle brackets.  Natural Docs will keep track off all the topics and where they are defined, so you don’t need to use HTML-like syntax or remember what file anything is in.  Also, if the link can’t be resolved to anything, Natural Docs leaves the angle brackets in the output so if something wasn’t intended to be a link (such as #include <somefile.h>) it won’t be mangled.

Let's link to function <Multiply>.
-

Let’s link to function Multiply.

Links and topic names are case sensitive, regardless of whether the language is or not.

When linking to functions, it doesn’t matter if you include empty parenthesis or not.  Both <Function> and <Function()> will work.  However, if you documented the function with parameters as part of the name, you will need to include those parameters whenever linking to it.  It is recommended that you only include parameters in the topic name if you need to distinguish between two functions with the same name.

If the topic has a summary sentence, hovering over the link will give it to you as a tooltip.  If the topic has a prototype, that will be included as well.  You can try it above.

Scope

If a topic is considered part of a class, they can be linked to using any of the three most common class/member notations:  class.member, class::member, and class->member.  Natural Docs will not be confused by <class->member>.  Like in the language itself, if the topic you’re writing is in that class’ scope you can link to it simply as <member>.

If you have multi-level classes and packages, links can be relative as well.  So if you’re in Project::UI::Window::Base and you want to link to Project::UI::Button::Base, just using <Button::Base> will work.

Plurals and Possessives

To make the documentation easier to write and easier to read in the source file, you can include plurals and possessives inside the angle brackets.  In other words, you don’t have to use awkward syntax like <Object>s, although that’s supported as well.  You can simply write <Objects> and it will link to the symbol Object just fine.  It can handle any plural and/or possessive form you can throw at it.  I’m not kidding: Foxes, Fox’s, Foxes’, Children, Mice, Alumni, Indices, Amoebae, Teeth, just try to trip it up.

URLs and E-Mail

You can also link to URLs and e-mail addresses.  It will detect them automatically, but you can also put them in angle brackets if you like.

Visit <http://www.website.com> or send messages to
-email@address.com.
-

E-mail addresses are protected in a way that should avoid spam crawlers.  Although the link above looks and acts like a regular link (try it) the HTML code actually looks like this:

<a href="#"
- onClick="location.href='mai' + 'lto:' + 'em' + 'ail' + '@'
-          + 'addre' + 'ss.com'; return false;">
-    em<span style="display: none">.nosp@m.</span>ail
-    <span>@</span>
-    addre<span style="display: none">.nosp@m.</span>ss.com
-</a>
-

You can create named links by putting the text, “at”, and then the address in the angle brackets.  This format lets it read naturally in a sentence.

Visit <the website at http://www.website.com> or <e-mail me at email@address.com>.
-
Formatting and Layout

You can apply additional formatting and layout to your Natural Docs content, all in ways that will appear very natural in the source code.

Paragraphs

You can break paragraphs by leaving blank lines between them.  So we have this in our content:

The first paragraph blah blah blah blah blah blah blah blah
-blah blah blah blah blah blah blah blah blah blah blah blah
-blah blah blah blah.
-
-The second paragraph blah blah blah blah blah blah blah
-blah blah blah blah blah blah blah blah blah blah blah blah
-blah blah blah blah.
-

and we get this in our output:

The first paragraph blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah.

The second paragraph blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah.

Bold and Underline

You can apply bold to a stretch of text by surrounding it with asterisks.  You can apply underlining by surrounding it with underscores instead.  With underlining, it doesn’t matter if you use an underscore for every space between words or not; they’ll be converted to spaces if you do.

Some *bold text* and some _underlined text_
-and yet _more_underlined_text_.
-

Some bold text and some underlined text and yet more underlined text.

Headings

You can add headings to your output just by ending a line with a colon and having a blank line above it.

Some text before the heading.
-
-Heading:
-Some text under the heading.
-

Some text before the heading.

Heading

Some text under the heading.

You must have a blank line above the heading or it will not work.  You can skip the blank after it but not before.

Bullet Lists

You can add bullet lists by starting a line with a dash, an asterisk, an o, or a plus.  Bullets can have blank lines between them if you want, and subsequent lines don’t have to be indented.  You end a list by skipping a line and doing something else.

- Bullet one.
-- Bullet two.
-  Bullet two continued.
-- Bullet three.
-
-Some text after the bullet list.
-
-o Spaced bullet one.
-
-o Spaced bullet two.
-Spaced bullet two continued.
-
-o Spaced bullet three.
-
-Some text after the spaced bullet list.
-
  • Bullet one.
  • Bullet two.  Bullet two continued.
  • Bullet three.

Some text after the bullet list.

  • Spaced bullet one.
  • Spaced bullet two.  Spaced bullet two continued.
  • Spaced bullet three.

Some text after the spaced bullet list.

Definition Lists

You can add a definition list by using the format below, specifically “text space dash space text”.  Like bullet lists, you can have blank lines between them if you want, subsequent lines don’t have to be indented, and you end the list by skipping a line and doing something else.

First  - This is the first item.
-Second - This is the second item.
-         This is more of the second item.
-Third  - This is the third item.
-This is more of the third item.
-
-Some text after the definition list.
-
FirstThis is the first item.
SecondThis is the second item.  This is more of the second item.
ThirdThis is the third item.  This is more of the third item.

Some text after the definition list.

Remember that with definition lists, if you’re using the plural form of the keywords each entry can be linked to as if it had its own topic.

Code and Text Diagrams

You can add example code or text diagrams by starting each line with >, |, or :.  If you have a vertical line or text box with the comment, you must separate these symbols from it with a space.

: a = b + c;
-
->   +-----+     +-----+
->   |  A  | --> |  B  |
->   +-----+     +-----+
->                  |
->               +-----+
->               |  C  |
->               +-----+
-
a = b + c;
+-----+     +-----+
| A | --> | B |
+-----+ +-----+
|
+-----+
| C |
+-----+

For long stretches, this may be too tedious.  You can start a code section by placing (start code) or just (code) alone on a line.  You end it with either (end code) or just (end).  You can’t put any other content on these lines.

(start code)
-
-if (x == 0) {
-   DoSomething();
-}
-
-return x;
-
-(end)
-
if (x == 0) {
DoSomething();
}

return x;

You can also use example, diagram, or table instead of code.  Just use whatever’s appropriate.  Always flexible, it will accept begin for start and it will accept finish or done for end so you don’t have to remember the exact word.

Syntax highlighting will be applied to (start code) sections by default.  If you’d like to also apply it to >, :, and | lines or turn it off completely, use the -hl command line option.

Images

You can include images in your documentation by writing “(see filename)”.  If you put it alone on a line it will be embedded in place.

This is the first paragraph.
-
-(see logo.gif)
-
-This is the second paragraph.
-

This is the first paragraph.

This is the second paragraph.

If it’s not alone on a line the image will appear after the end of the paragraph, the text will become a link to it, and the file name will be used as a caption.

This is the first paragraph (see logo.gif)  This is
-more of the first paragraph.
-

This is the first paragraph (see logo)  This is more of the first paragraph.

logo

The image file names are relative to the source file the comment appears in or any directories specified with the -img command line option.  You can use relative paths like (see images/logo.gif) and (see ../images/logo.gif), but you cannot use absolute paths, URLs, or specify a file that’s not in a folder included by -i or -img.

Natural Docs supports gif, jpg, jpeg, png, and bmp files.

Page Titles

Natural Docs automatically determines the page title as follows:

  • If there’s only one topic in the file, that topic’s title becomes the page title.
  • Otherwise, if the first topic in the file is a class, section, or file, that topic’s title becomes the page title.
  • Otherwise, the file name becomes the page title.

This should be enough for most people.  However, if you don’t like the page title Natural Docs has chosen for you, add a “Title: [name]” comment to the top of the file to override it.  Title is a synonym of Section, so that will satisfy the second rule and make it the page title.

Summaries

Summaries are automatically generated for every file, class, and section.  You don’t have to do anything special to get them.

There are two things you may want to keep in mind when documenting your code so that the summaries are nicer.  The first is that they use the first sentence in the topic as the description, so long as it’s plain text and not something like a bullet list.  It will also appear in the tooltip whenever that topic is linked to.

The second is that you may want to manually add group topics to divide long lists and make the summaries easier to navigate.  Natural Docs will automatically group them by type if you do not, but sometimes you want to be more specific.  You don’t need to provide a description, just adding a “Group: [name]” comment is sufficient.  Note that once you manually add a group automatic grouping is completely turned off for that class.

Here’s an example summary.  Note that as before, when you hover over a link, you’ll get the prototype and summary line as a tooltip.

Summary
A example class that does arithmetic with functions for people scared of operators.
Adds two integers.
Subtracts two integers.
Multiplies two integers.
Divides two integers.
Returns whether two integers are equal.
Javadoc Compatibility

If you have full language support Natural Docs will also extract documentation from actual Javadoc comments, not just Natural Docs comments written with the Javadoc comment symbols.  This provides you with a good method of migrating to Natural Docs as you don’t have to convert all of your existing documentation.

/**
- * Multiplies two integers.
- *
- * @param x The first integer.
- * @param y The second integer.
- * @return The two integers multiplied together.
- * @see Divide
- */
-

Multiply

int Multiply (int x,
int y)

Multiplies two integers.

Parameters

xThe first integer.
yThe second integer.

Returns

The two integers multiplied together.

See Also

Divide

While most Javadoc tags and simple HTML formatting are supported, Natural Docs is not a full Javadoc parser and may not support some advanced tags and HTML.  See this page for a list of what’s supported and what isn’t.

A source file can contain both Natural Docs and Javadoc comments.  However, you cannot mix the two within a single comment.  For example, you can’t use asterisks for bold in a @param line.  If a comment is written with the Javadoc comment symbols (repeat the last symbol of the first line once) doesn’t have a topic line (like “Function: Multiply”) and uses Javadoc tags (like @param) the comment is treated as Javadoc.  If any of those conditions aren’t true it’s treated as a Natural Docs comment.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/documenting/walkthrough.html b/vendor/naturaldocs/Help/documenting/walkthrough.html deleted file mode 100644 index 055d0b82a..000000000 --- a/vendor/naturaldocs/Help/documenting/walkthrough.html +++ /dev/null @@ -1,181 +0,0 @@ - - -Documenting Your Code - Walkthrough - Natural Docs - - - -
Natural Docs
Documenting Your Code
Our First Function

So you downloaded Natural Docs, you figured out the command line, and now it’s time to start documenting your code.  Natural Docs tries to make this very straightforward and painless, so let’s just dive right in:

/*
-   Function: Multiply
-   Multiplies two integers and returns the result.
-*/
-int Multiply (int x, int y)
-   {  return x * y;  };
-

That’s all you need.  Run Natural Docs and here’s what appears in your output:

Multiply

int Multiply (int x,
int y)

Multiplies two integers and returns the result.

Okay, so that’s all you need, but probably not all you want.  After all, you’ve got some real functions to document, not little one-liners.  Here’s something more elaborate:

/*
-   Function: Multiply
-
-   Multiplies two integers.
-
-   Parameters:
-
-      x - The first integer.
-      y - The second integer.
-
-   Returns:
-
-      The two integers multiplied together.
-
-   See Also:
-
-      <Divide>
-*/
-int Multiply (int x, int y)
-   {  return x * y;  };
-

Multiply

int Multiply (int x,
int y)

Multiplies two integers.

Parameters

xThe first integer.
yThe second integer.

Returns

The two integers multiplied together.

See Also

Divide

int Add (int x,
int y)
Adds two integers.
int Subtract (int x,
int y)
Subtracts two integers.
int Multiply (int x,
int y)
Multiplies two integers.
int Divide (int x,
int y)
Divides two integers.
bool IsEqual (int x,
int y)
Returns whether two integers are equal.

Still not too scary, huh?  Notice the comments are just as readable as the output.  No tags littered about, and the structure is very natural.  You probably get it just by looking at it, but let’s go through the details anyway.

Function: Multiply
-

Every one of these comments you write (called topics) are going to start with a topic line in the format “keyword: title”.  There are a lot of keywords, but they’re exactly what you’d expect: Function, Class, Variable, etc.  There are also a lot of synonyms so instead of Function you could use Func, Procedure, Proc, Method, Constructor, etc.  It’s designed so you can just use whatever it is you’re describing without memorizing anything.  You can glance over the keyword list but you shouldn’t have to consult it very often.

The other part of the topic line is the title.  It should match whatever it is you’re documenting, in this case the function name Multiply.  Natural Docs is case sensitive even if your programming language isn’t, so make sure you match it closely or you might not get the prototype in your output, which is the little gray box.  You don’t need to include the parameters in the title.  In fact, it’s better if you don’t.

Parameters:
-
-Returns:
-
-See Also:
-

You can also define headings by skipping a line and ending the text with a colon.  If you’re used to other documentation systems you may think there’s only a handful of headings to choose from, but any text formatted this way will become one.  If you want a heading called Dependencies you can go right ahead and add it.

x - The first integer.
-y - The second integer.
-

This is what’s called a definition list.  You can use more than one line to finish the definition, as it won’t stop until you skip a line.

x - The first integer.
-y - The second integer with a long description.
-    This is still part of the description.
-
-This is a new paragraph because we skipped a line.
-

Indentation doesn’t matter either, so even if the second description line wasn’t indented to match the first, it would still be considered part of it.

<Divide>
-

This is how we link in Natural Docs, with angle brackets.  There will be a lot more to say about this later, but for now I’ll just show you something cool.  Hover over it in the output below:

You get that everywhere in your generated documentation.

Classes and Scope

So that’s good for our one function of questionable usefulness, but what if we have a whole class of questionable usefulness?  We can document the class and it’s members the same way we documented the individual function, with a Natural Docs comment right above each element.  We’ll go back to short descriptions to keep the example manageable.

/*
-   Class: Counter
-   A class that manages an incrementing counter.
-*/
-class Counter
-   {
-   public:
-
-      /*
-         Constructor: Counter
-         Initializes the object.
-      */
-      Counter()
-         {  value = 0;  };
-
-      /*
-         Function: Value
-         Returns the value of the counter.
-      */
-      int Value()
-         {  return value;  };
-
-      /*
-         Function: Increment
-         Adds one to the counter.
-      */
-      void Increment()
-         {  value++;  };
-
-   protected:
-
-      /*
-         Variable: value
-         The counter's value.
-      */
-      int value;
-   };
-

Everything’s the same, we just substituted Class and Variable for the Function keyword when it was appropriate.  We also used Constructor, but we could have just as easily used Function there too.  They’re both keywords for the same thing so it doesn’t matter.

Scope

Like the source code itself, Natural Docs topics have scope.  Value and Increment are seen as part of class Counter, just like they are in the code.  Why is this important?  Linking.  Linking from one topic to another has similar rules to how one function can call another.  Since Value is in the same class as Increment, it’s topic can link to it with just <Increment>.  However, linking to Increment from a different class would require <Counter.Increment> instead.  You can actually use any of the three most common class/member notations: <Counter.Increment>, <Counter::Increment>, and <Counter->Increment>.

If your programming language has full language support, the scope is determined by the code and applied automatically.  However, if you only have basic language support it follows these rules:

  • Any topic that appears under a Class topic (or anything that says Starts Scope) is part of that class.
  • Any topic that appears under a Section topic (or anything that says Ends Scope) is global again.
  • Any File topic (or anything that says Always Global) is global no matter what and doesn’t affect any other topics.

Chances are you would have written the same thing even if you didn’t know this and it would have just worked.  You usually won’t need to think about them at all.  However, it’s still good to be aware of them in case something doesn’t behave the way you expected it to.

You actually know enough to go start documenting now.  I know Mr. ScrollBar says there’s more on this page you can learn, but if you want to skip out early, you can.  Really.  I don’t mind.

More Formatting

Okay then.  On we go.

Paragraphs, Bold, and Underline

The syntax for these three is exactly what you would expect it to be.

*Bold text*
-
-_Underlined text_
-
-Paragraphs are broken by skipping lines.  So the two
-lines above each have their own paragraph, but these
-three lines are all part of the same one.
-

Bold text

Underlined text

Paragraphs are broken by skipping lines.  So the two lines above each have their own paragraph, but these three lines are all part of the same one.

When underlining multiple words, you can use an underscore for each space or only put them at the edges like we did above.  Both ways will work.

Bullet Lists

You can add bullet lists by starting a line with a dash, an asterisk, an o, or a plus.  Like definition lists, bullets can span multiple lines and indentation doesn’t matter.  To end a bullet you have to skip a line before doing something else.

- Bullet one.
-- Bullet two.
-  Bullet two continued.
-- Bullet three.
-
-Some text after the bullet list.
-
  • Bullet one.
  • Bullet two.  Bullet two continued.
  • Bullet three.

Some text after the bullet list.

Code and Text Diagrams

You can add example code or text diagrams by starting each line with >, |, or :.

> a = b + c;
-> b++;
-
a = b + c;
b++;

If you have a long stretch, you can use (start code) and (end) instead.

(start code)
-
-if (x == 0) {
-   DoSomething();
-}
-
-return x;
-
-(end)
-
if (x == 0) {
DoSomething();
}

return x;

You can also use example, diagram, or table instead of code.  Just use whatever’s appropriate.

As I mentioned before, we don’t want you to worry about memorizing minor details, so in that spirit it will also accept begin for start and finish or done for end.  You can also write (end code) instead of just (end).

Syntax highlighting will be applied to (start code) sections by default.  If you’d like to also apply it to >, :, and | lines or turn it off completely, use the -hl command line option.

Images

You can include images in your documentation by writing “(see filename)”.  If you put it alone on a line it will be embedded in place, or if you put it in a paragraph it will appear after it using the file name as a caption.

This is the first paragraph.
-
-(see logo.gif)
-
-This is the second paragraph (see logo.gif)  This
-is more of the second paragraph.
-

This is the first paragraph.

This is the second paragraph (see logo)  This is more of the second paragraph.

logo

The image file names are relative to the source file the comment appears in, so if your file is C:\Project\SourceFile.cpp and your image is C:\Project\Images\Logo.gif, you would write (see Images/Logo.gif).  However, you can also specify image directories in the command line with -img, so if all your source files are in C:\Project\Source and all your images are in C:\Project\Images, you can put “-img C:\Project\Images” on the command line and just use (see logo.gif) again.

More on Linking

Yes, there’s still more to linking.  You can link to URLs and e-mail addresses, but in this case the angle brackets are optional.

Visit <http://www.website.com> or send messages to
-email@address.com.
-

You can create named links by putting the text, “at”, and then the address in the angle brackets.  This format lets it read naturally in a sentence.

Visit <the website at http://www.website.com> or <e-mail me at email@address.com>.
-

E-mail addresses are protected from spam crawlers.  They look and act like regular links (try it above) but you can see the actual HTML that’s generated for them here.

As for regular links, to help them fit into sentences easily you can actually include plurals and possessives inside the angle brackets.  In other words, you don’t have to use awkward syntax like <Object>s, although that’s supported as well.  You can simply write <Objects> and it will link to the symbol Object just fine.  It can handle any plural and/or possessive form you can throw at it.  I’m not kidding: Foxes, Fox’s, Foxes’, Children, Mice, Alumni, Indices, Amoebae, Teeth, just try to trip it up.

Extra Documentation

Sometimes you want to include documentation that doesn’t correspond directly to a code element.  Maybe you want to include license information or architecture notes.  There are two ways to do this.

Freestanding Topics

Just because most of the things you write will directly correspond to an element of your source code doesn’t mean they have to.  You can pick any of the available keywords and create a freestanding comment with it.  For example:

/*
-   Class: Counter
-   A class that manages an incrementing counter.
-*/
-class Counter
-   {
-   public:
-
-      /*
-         About: License
-         This file is licensed under the GPL.
-      */
-
-      /*
-         Constructor: Counter
-         Initializes the object.
-      */
-      Counter()
-         {  value = 0;  };
-   ...
-

The extra license topic will be added to the output just like the functions.

License

This file is licensed under the GPL.

Remember that because of scope, the License topic will actually be considered part of Counter the way it’s listed above.  You’d link to it from outside Counter with <Counter.License>.  That idea may take some getting used to, but if an extra topic only applies to one class that’s actually the most appropriate way to do it.  In this case it’s a license, so if it applies to the entire project instead you could put the comment above the class to make it global, just like moving a function there would.

Text Files

You can also add additional documentation with text files.  If you put a file with a .txt extension in your source tree and start it with a topic line, it’s contents will be treated the same as if it were in a comment in your source code.  That means you can define multiple topics within it, you can link between them and topics in your source code, and you can use all available formatting options.

Title: License
-
-This file is licensed under the GPL.
-
-I can link to <Counter> and <Counter.Increment>, and
-the documentation in that class can even link back
-with <License>.
-
-
-About: Second Topic
-
-I can create a *second* topic in here too, complete
-with formatting.
-

The thing some people forget though is that you must start it with a topic line, like “Title: License” above.  This is how Natural Docs tells it apart from regular text files.

Abbreviated Syntax

Here’s another useful thing you may want to know about.  Suppose you have a lot of little things to document, like constants.  Writing a separate topic for each one can be very tedious, no matter how much you compress it:

// Constant: COUNTER_NORMAL
-// Causes the counter to increment normally.
-#define COUNTER_NORMAL 0
-
-// Constant: COUNTER_ODD
-// Causes the counter to only increment in odd numbers.
-#define COUNTER_ODD 1
-
-// Constant: COUNTER_EVEN
-// Causes the counter to only increment in even numbers.
-#define COUNTER_EVEN 2
-

One thing you may have noticed in the keyword list is that they almost all have plural forms.  These are used to create what are called list topics.  You define a topic using a plural keyword, and then anything appearing in a definition list within it creates a linkable symbol as if they each had their own topic.  For example:

/*
-   Constants: Counter Modes
-
-   COUNTER_NORMAL - Causes the counter to increment normally.
-   COUNTER_ODD    - Causes the counter to only increment in odd numbers.
-   COUNTER_EVEN   - Causes the counter to only increment in even numbers.
-*/
-#define COUNTER_NORMAL 0
-#define COUNTER_ODD 1
-#define COUNTER_EVEN 2
-

I would now be able to write <COUNTER_ODD> and have it work the same as it would with the first example.

Using the enum or enumeration keyword is special because it automatically behaves in a similar manner.  This allows both the enum and its values to be documented in the same place.

/*
-   Enum: CounterMode
-
-   NORMAL - Causes the counter to increment normally.
-   ODD    - Causes the counter to only increment in odd numbers.
-   EVEN   - Causes the counter to only increment in even numbers.
-*/
-enum CounterMode { NORMAL, ODD, EVEN };
-

That’s it, you’re done with this walkthrough.  You should know enough now to make very good use of Natural Docs.  If you still want to know more, you can look in the reference for some of the smaller details we may have skipped over.  Also, look at the Customizing pages on this web site for even more you can do.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/example/Default.css b/vendor/naturaldocs/Help/example/Default.css deleted file mode 100644 index 7318fdcd9..000000000 --- a/vendor/naturaldocs/Help/example/Default.css +++ /dev/null @@ -1,528 +0,0 @@ -/* - IMPORTANT: If you're editing this file in the output directory of one of - your projects, your changes will be overwritten the next time you run - Natural Docs. Instead, copy this file to your project directory, make your - changes, and you can use it with -s. Even better would be to make a CSS - file in your project directory with only your changes, which you can then - use with -s [original style] [your changes]. - - On the other hand, if you're editing this file in the Natural Docs styles - directory, the changes will automatically be applied to all your projects - that use this style the next time Natural Docs is run on them. - - This file is part of Natural Docs, which is Copyright © 2003-2004 Greg Valure - Natural Docs is licensed under the GPL -*/ - -body { - font-family: Verdana, Arial, sans-serif; - color: #000000; - margin: 0px; padding: 0px } - -body.UnframedPage { - background-color: #E8E8E8 } - - -a:link, -a:visited { color: #900000; text-decoration: none } -a:hover { color: #900000; text-decoration: underline } -a:active { color: #FF0000; text-decoration: underline } - -td { - vertical-align: top } - -/* - Comment out this line to use web-style paragraphs (blank line between - paragraphs, no indent) instead of print-style paragraphs (no blank line, - indented.) -*/ -p { - text-indent: 5ex; margin: 0 } - - -/* Can't use something like display: none or it won't break. */ -.HB { - font-size: 1px } - - - - -body.FramedMenuPage, -.MenuSection { - font-size: 9pt; - background-color: #E8E8E8; - padding: 10px 0 0 0 } - -.MenuSection { - width: 27ex } - - - .MTitle { - font-size: 16pt; font-weight: bold; font-variant: small-caps; - text-align: center; - padding: 5px 10px 15px 10px; - border-bottom: 1px dotted #000000; - margin-bottom: 15px } - - .MSubTitle { - font-size: 9pt; font-weight: normal; font-variant: normal; - margin-top: 1ex; margin-bottom: 5px } - - - .MEntry a:link, - .MEntry a:hover, - .MEntry a:visited { color: #606060; margin-right: 0 } - .MEntry a:active { color: #A00000; margin-right: 0 } - - - .MGroup { - font-variant: small-caps; font-weight: bold; - margin: 1em 0 1em 10px } - - /* Konqueror just can't do margins. */ - .KHTML .MGroup { - margin-bottom: 0; padding-bottom: 1em } - - .MGroupContent { - font-variant: normal; font-weight: normal } - - .MGroup a:link, - .MGroup a:hover, - .MGroup a:visited { color: #545454; margin-right: 10px } - .MGroup a:active { color: #A00000; margin-right: 10px } - - - .MFile, - .MText, - .MLink, - .MIndex { - padding: 1px 17px 2px 10px; - margin: .25em 0 .25em 0 } - - .MText { - font-size: 8pt; font-style: italic } - - .MLink { - font-style: italic } - - #MSelected { - color: #000000; background-color: #FFFFFF; - /* Replace padding with border. */ - padding: 0 10px 0 10px; - border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000; - margin-right: 5px } - - /* Close off the left side when its in a group. */ - .MGroup #MSelected { - padding-left: 9px; border-left-width: 1px } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Gecko #MSelected { - -moz-border-radius-topright: 10px; - -moz-border-radius-bottomright: 10px } - .Gecko .MGroup #MSelected { - -moz-border-radius-topleft: 10px; - -moz-border-radius-bottomleft: 10px } - - - - -body.FramedContentPage, -.ContentSection { - background-color: #FFFFFF; - padding-bottom: 15px } - -.ContentSection { - border-width: 0 0 1px 1px; border-style: solid; border-color: #000000 } - - - .CTopic { - font-size: 10pt; - /* This should be a margin but Konq 3.1.1 sucks. */ - padding-bottom: 3em } - - - .CTitle { - font-size: 12pt; font-weight: bold; - border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0; - margin: 0 15px .5em 15px } - - .CGroup .CTitle { - font-size: 16pt; font-variant: small-caps; - padding-left: 15px; padding-right: 15px; - border-width: 0 0 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CClass .CTitle, - .CInterface .CTitle, - .CDatabase .CTitle, - .CDatabaseTable .CTitle, - .CSection .CTitle { - font-size: 18pt; - color: #FFFFFF; background-color: #A0A0A0; - padding: 10px 15px 10px 15px; - border-width: 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - #MainTopic .CTitle { - font-size: 20pt; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CBody { - margin-left: 15px; margin-right: 15px } - - - .CToolTip { - position: absolute; visibility: hidden; - left: 0; top: 0; max-width: 50%; - background-color: #FFFFE0; - padding: 5px; - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000; - font-size: 8pt } - - /* Opera 6 gives it a huge height otherwise. */ - .Opera6 .CTooltip, .Opera5 .CTooltip { - max-width: 100% } - - .CHeading { - font-weight: bold; font-size: 10pt; - margin-top: 1.5em; margin-bottom: .5em } - - .CCode { - font: 10pt "Courier New", Courier, monospace; - overflow: auto; - } - - .CBulletList { - /* I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever. - Reapply it here as padding. */ - padding-left: 15px; padding-right: 15px; - margin: .5em 5ex .5em 5ex; - } - - .CDescriptionList { - margin: .5em 5ex 0 5ex } - - /* IE 4 and Konqueror always makes it too long. */ - .IE4 .CDescriptionList, - .KHTML .CDescriptionList { - width: 85% } - - .CDLEntry { - font: 10pt "Courier New", Courier, monospace; color: #808080; - padding-bottom: .25em; - white-space: nowrap } - - .CDLDescription { - font-size: 10pt; /* For browsers that don't inherit correctly, like Opera 5. */ - padding-bottom: .5em; padding-left: 5ex } - - .CTopic img { - text-align: center; - display: block; - margin: 1em auto; - } - .CImageCaption { - font-variant: small-caps; - font-size: 8pt; - color: #808080; - text-align: center; - position: relative; - top: 1em; - } - - .CImageLink { - color: #808080; - font-style: italic; - } - a.CImageLink:link, - a.CImageLink:visited, - a.CImageLink:hover { color: #808080 } - - - -.Prototype { - font: 10pt "Courier New", Courier, monospace; - padding: 5px 3ex; - border-width: 1px; border-style: solid; - margin: 0 5ex 1.5em 5ex; - } - - .Prototype td { - font-size: 10pt; - } - - .PDefaultValue, - .PTypePrefix { - color: #8F8F8F; - } - .PTypePrefix { - text-align: right; - } - - .IE .Prototype table { - padding: 0; - } - - .CFunction .Prototype { - background-color: #F4F4F4; border-color: #D0D0D0 } - .CProperty .Prototype { - background-color: #F4F4FF; border-color: #C0C0E8 } - .CVariable .Prototype { - background-color: #FFFFF0; border-color: #E0E0A0 } - - .CDatabaseIndex .Prototype, - .CConstant .Prototype { - background-color: #D0D0D0; border-color: #000000 } - .CType .Prototype { - background-color: #FFF8F8; border-color: #E8C8C8 } - .CDatabaseTrigger .Prototype, - .CEvent .Prototype, - .CDelegate .Prototype { - background-color: #F0FCF0; border-color: #B8E4B8 } - - .CToolTip .Prototype { - margin: 0 0 .5em 0; - white-space: nowrap; - } - - - - - -.Summary { - margin: 1.5em 5ex 0 5ex } - - .STitle { - font-size: 12pt; font-weight: bold; - margin-bottom: .5em } - - - .SBorder { - background-color: #FFFFF0; - padding: 15px; - border: 1px solid #C0C060 } - - /* Let's observe the evolution of IE's brokeness, shall we? - IE 4 always makes them too long, there's no way around it. */ - .IE4 .SBorder { - width: 85% } - /* IE 5 will make them too long unless you set the width to 100%. Isn't this implied for a div? */ - .IE5 .SBorder { - width: 100% } - /* IE 6 behaves like 5 when it's in a frame, but without frames it will be correct without a width or slightly too long - (but not enough to scroll) with a width. This arbitrary weirdness simply astounds me. */ - body.FramedContentPage .IE6 .SBorder { - width: 100% } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Gecko .SBorder { - -moz-border-radius: 20px } - - - .STable { - font-size: 9pt; width: 100% } - - .SEntrySize { - width: 30% } - .SDescriptionSize { - width: 70% } - - - .SMarked { - background-color: #F8F8D8 } - - - .SEntry .SIndent1 { - margin-left: 1.5ex } - .SEntry .SIndent2 { - margin-left: 3ex } - .SEntry .SIndent3 { - margin-left: 4.5ex } - .SEntry .SIndent4 { - margin-left: 6ex } - .SEntry .SIndent5 { - margin-left: 7.5ex } - - .SDescription { - padding-left: 3ex } - - .SDescription a { color: #800000} - .SDescription a:active { color: #A00000 } - - - .SGroup { - margin-top: .5em; margin-bottom: .25em } - - .SGroup .SEntry { - font-weight: bold; font-variant: small-caps } - - .SGroup .SEntry a { color: #800000 } - .SGroup .SEntry a:active { color: #F00000 } - - - .SMain .SEntry, - .SClass .SEntry, - .SDatabase .SEntry, - .SDatabaseTable .SEntry, - .SSection .SEntry { - font-weight: bold; font-size: 10pt; - margin-bottom: .25em } - - .SClass, - .SDatabase, - .SDatabaseTable, - .SSection { - margin-top: 1em } - - .SMain .SEntry a, - .SClass .SEntry a, - .SDatabase .SEntry a, - .SDatabaseTable .SEntry a, - .SSection .SEntry a { color: #000000 } - - .SMain .SEntry a:active, - .SClass .SEntry a:active, - .SDatabase .SEntry a:active, - .SDatabaseTable .SEntry a:active, - .SSection .SEntry a:active { color: #A00000 } - - - - - -.ClassHierarchy { - margin: 0 15px 1em 15px } - - .CHEntry { - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0; - margin-bottom: 3px; - padding: 2px 2ex; - font-size: 10pt; - background-color: #F4F4F4; color: #606060; - } - - .Gecko .CHEntry { - -moz-border-radius: 4px; - } - - .CHCurrent .CHEntry { - font-weight: bold; - border-color: #000000; - color: #000000; - } - - .CHChildNote .CHEntry { - font-style: italic; - font-size: 8pt; - } - - .CHIndent { - margin-left: 3ex; - } - - .CHEntry a:link, - .CHEntry a:visited, - .CHEntry a:hover { - color: #606060; - } - .CHEntry a:active { - color: #800000; - } - - - - - -body.FramedIndexPage, -.IndexSection { - background-color: #FFFFFF; - font-size: 10pt; - padding: 15px } - -.IndexSection { - border-width: 0 0 1px 1px; border-style: solid; border-color: #000000 } - - .IPageTitle { - font-size: 20pt; font-weight: bold; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; border-style: solid; - margin: -15px -15px 0 -15px } - - .INavigationBar { - text-align: center; - background-color: #FFFFF0; - padding: 5px; - border-bottom: solid 1px black; - margin: 0 -15px 15px -15px } - - .INavigationBar a { - font-weight: bold } - - .IHeading { - font-size: 16pt; font-weight: bold; - padding: 2.5em 0 .5em 0; - text-align: center; - width: 3.5ex; - } - #IFirstHeading { - padding-top: 0; - } - - .IEntry { - padding-left: 1ex; } - - .ISubIndex { - padding-left: 3ex; padding-bottom: .5em } - - /* While it may cause some entries to look like links when they aren't, I found it's much easier to read the - index if everything's the same color. */ - .ISymbol { - font-weight: bold; color: #900000 } - - .ISymbolPrefix { - text-align: right; - color: #C47C7C; - background-color: #F8F8F8; - border-right: 3px solid #E0E0E0; - border-left: 1px solid #E0E0E0; - padding: 0 1px 0 2px; - } - #IFirstSymbolPrefix { - border-top: 1px solid #E0E0E0; - } - #ILastSymbolPrefix { - border-bottom: 1px solid #E0E0E0; - } - #IOnlySymbolPrefix { - border-top: 1px solid #E0E0E0; - border-bottom: 1px solid #E0E0E0; - } - - a.IParent, - a.IFile { - display: block; - } - - - - -.Footer { - font-size: 8pt; color: #909090 } - -body.UnframedPage .Footer { - text-align: right; - margin: 2px } - -body.FramedMenuPage .Footer { - text-align: center; - margin: 5em 10px 0 10px} - - .Footer a:link, - .Footer a:hover, - .Footer a:visited { color: #909090 } - .Footer a:active { color: #A00000 } diff --git a/vendor/naturaldocs/Help/example/NaturalDocs.js b/vendor/naturaldocs/Help/example/NaturalDocs.js deleted file mode 100644 index 2af84cf54..000000000 --- a/vendor/naturaldocs/Help/example/NaturalDocs.js +++ /dev/null @@ -1,204 +0,0 @@ - -// -// Browser Styles -// ____________________________________________________________________________ - -var agt=navigator.userAgent.toLowerCase(); -var browserType; -var browserVer; - -if (agt.indexOf("opera") != -1) - { - browserType = "Opera"; - - if (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1) - { browserVer = "Opera5"; } - else if (agt.indexOf("opera 6") != -1 || agt.indexOf("opera/6") != -1) - { browserVer = "Opera6"; } - else if (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1) - { browserVer = "Opera7"; } - } - -else if (agt.indexOf("khtml") != -1 || agt.indexOf("konq") != -1 || agt.indexOf("safari") != -1) - { - browserType = "KHTML"; - } - -else if (agt.indexOf("msie") != -1) - { - browserType = "IE"; - - if (agt.indexOf("msie 4") != -1) - { browserVer = "IE4"; } - else if (agt.indexOf("msie 5") != -1) - { browserVer = "IE5"; } - else if (agt.indexOf("msie 6") != -1) - { browserVer = "IE6"; } - } - -else if (agt.indexOf("gecko") != -1) - { - browserType = "Gecko"; - } - -// Opera already taken care of. -else if (agt.indexOf("mozilla") != -1 && agt.indexOf("compatible") == -1 && agt.indexOf("spoofer") == -1 && - agt.indexOf("webtv") == -1 && agt.indexOf("hotjava") == -1) - { - browserType = "Netscape"; - - if (agt.indexOf("mozilla/4") != -1) - { browserVer = "Netscape4"; } - } - - -// -// Menu -// ____________________________________________________________________________ - - -function ToggleMenu(id) - { - if (!window.document.getElementById) - { return; }; - - var display = window.document.getElementById(id).style.display; - - if (display == "none") - { display = "block"; } - else - { display = "none"; } - - window.document.getElementById(id).style.display = display; - } - - -// -// Tooltips -// ____________________________________________________________________________ - - -var tooltipTimer = 0; - -function ShowTip(event, tooltipID, linkID) - { - if (tooltipTimer) - { clearTimeout(tooltipTimer); }; - - var docX = event.clientX + window.pageXOffset; - var docY = event.clientY + window.pageYOffset; - - var showCommand = "ReallyShowTip('" + tooltipID + "', '" + linkID + "', " + docX + ", " + docY + ")"; - - // KHTML cant handle showing on a timer right now. - - if (browserType != "KHTML") - { tooltipTimer = setTimeout(showCommand, 1000); } - else - { eval(showCommand); }; - } - -function ReallyShowTip(tooltipID, linkID, docX, docY) - { - tooltipTimer = 0; - - var tooltip; - var link; - - if (document.getElementById) - { - tooltip = document.getElementById(tooltipID); - link = document.getElementById(linkID); - } - else if (document.all) - { - tooltip = eval("document.all['" + tooltipID + "']"); - link = eval("document.all['" + linkID + "']"); - } - - if (tooltip) - { - var left = 0; - var top = 0; - - // Not everything supports offsetTop/Left/Width, and some, like Konqueror and Opera 5, think they do but do it badly. - - if (link && link.offsetWidth != null && browserType != "KHTML" && browserVer != "Opera5") - { - var item = link; - while (item != document.body) - { - left += item.offsetLeft; - item = item.offsetParent; - } - - item = link; - while (item != document.body) - { - top += item.offsetTop; - item = item.offsetParent; - } - top += link.offsetHeight; - } - - // The fallback method is to use the mouse X and Y relative to the document. We use a separate if and test if its a number - // in case some browser snuck through the above if statement but didn't support everything. - - if (!isFinite(top) || top == 0) - { - left = docX; - top = docY; - } - - // Some spacing to get it out from under the cursor. - - top += 10; - - // Make sure the tooltip doesnt get smushed by being too close to the edge, or in some browsers, go off the edge of the - // page. We do it here because Konqueror does get offsetWidth right even if it doesnt get the positioning right. - - if (tooltip.offsetWidth != null) - { - var width = tooltip.offsetWidth; - var docWidth = document.body.clientWidth; - - if (left + width > docWidth) - { left = docWidth - width - 1; } - } - - // Opera 5 chokes on the px extension, so it can use the Microsoft one instead. - - if (tooltip.style.left != null && browserVer != "Opera5") - { - tooltip.style.left = left + "px"; - tooltip.style.top = top + "px"; - } - else if (tooltip.style.pixelLeft != null) - { - tooltip.style.pixelLeft = left; - tooltip.style.pixelTop = top; - } - - tooltip.style.visibility = "visible"; - } - } - -function HideTip(tooltipID) - { - if (tooltipTimer) - { - clearTimeout(tooltipTimer); - tooltipTimer = 0; - } - - var tooltip; - - if (document.getElementById) - { tooltip = document.getElementById(tooltipID); } - else if (document.all) - { tooltip = eval("document.all['" + tooltipID + "']"); } - - if (tooltip) - { tooltip.style.visibility = "hidden"; } - } - diff --git a/vendor/naturaldocs/Help/example/Roman.css b/vendor/naturaldocs/Help/example/Roman.css deleted file mode 100644 index 54acc6e31..000000000 --- a/vendor/naturaldocs/Help/example/Roman.css +++ /dev/null @@ -1,507 +0,0 @@ -/* - IMPORTANT: If you're editing this file in the output directory of one of - your projects, your changes will be overwritten the next time you run - Natural Docs. Instead, copy this file to your project directory, make your - changes, and you can use it with -s. Even better would be to make a CSS - file in your project directory with only your changes, which you can then - use with -s [original style] [your changes]. - - On the other hand, if you're editing this file in the Natural Docs styles - directory, the changes will automatically be applied to all your projects - that use this style the next time Natural Docs is run on them. - - This file is part of Natural Docs, which is Copyright © 2003-2004 Greg Valure - Natural Docs is licensed under the GPL -*/ - -body { - font-family: "Times New Roman", Roman, serif; - color: #000000; - margin: 0px; padding: 0px } - -body.UnframedPage { - background-color: #E8E8E8 } - - -a:link, -a:visited { color: #900000; text-decoration: none } -a:hover { color: #900000; text-decoration: underline } -a:active { color: #FF0000; text-decoration: underline } - -td { - vertical-align: top } - -/* - Comment out this line to use web-style paragraphs (blank line between - paragraphs, no indent) instead of print-style paragraphs (no blank line, - indented.) -*/ -p { - text-indent: 5ex; margin: 0 } - - -/* Can't use something like display: none or it won't break. */ -.HB { - font-size: 1px } - - - - -body.FramedMenuPage, -.MenuSection { - font-size: 10pt; - background-color: #E8E8E8; - padding: 10px 0 0 0 } - -.MenuSection { - width: 27ex } - - - .MTitle { - font-size: 18pt; font-weight: bold; font-variant: small-caps; - text-align: center; - padding: 5px 10px 15px 10px; - border-bottom: 1px dotted #000000; - margin-bottom: 15px } - - .MSubTitle { - font-size: 10pt; font-weight: normal; font-variant: normal; - margin-top: 1ex; margin-bottom: 5px } - - - .MEntry a:link, - .MEntry a:hover, - .MEntry a:visited { color: #606060; margin-right: 0 } - .MEntry a:active { color: #A00000; margin-right: 0 } - - - .MGroup { - font-variant: small-caps; font-weight: bold; - margin: 1em 0 1em 10px } - - /* Konqueror just can't do margins. */ - .KHTML .MGroup { - margin-bottom: 0; padding-bottom: 1em } - - .MGroupContent { - font-variant: normal; font-weight: normal } - - .MGroup a:link, - .MGroup a:hover, - .MGroup a:visited { color: #545454; margin-right: 10px } - .MGroup a:active { color: #A00000; margin-right: 10px } - - - .MFile, - .MText, - .MLink, - .MIndex { - padding: 1px 17px 2px 10px; - margin: .25em 0 .25em 0 } - - .MText { - font-size: 8pt; font-style: italic } - - .MLink { - font-style: italic } - - #MSelected { - color: #000000; background-color: #FFFFFF; - /* Replace padding with border. */ - padding: 0 10px 0 10px; - border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000; - margin-right: 5px } - - /* Close off the left side when its in a group. */ - .MGroup #MSelected { - padding-left: 9px; border-left-width: 1px } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Gecko #MSelected { - -moz-border-radius-topright: 10px; - -moz-border-radius-bottomright: 10px } - .Gecko .MGroup #MSelected { - -moz-border-radius-topleft: 10px; - -moz-border-radius-bottomleft: 10px } - - - - -body.FramedContentPage, -.ContentSection { - background-color: #FFFFFF; - padding-bottom: 15px } - -.ContentSection { - border-width: 0 0 1px 1px; border-style: solid; border-color: #000000 } - - - .CTopic { - font-size: 12pt; - /* This should be a margin but Konq 3.1.1 sucks. */ - padding-bottom: 3em } - - - .CTitle { - font-size: 16pt; font-weight: bold; - border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0; - margin: 0 15px .5em 15px } - - .CGroup .CTitle { - font-size: 18pt; font-variant: small-caps; - padding-left: 15px; padding-right: 15px; - border-width: 0 0 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CClass .CTitle, - .CInterface .CTitle, - .CDatabase .CTitle, - .CDatabaseTable .CTitle, - .CSection .CTitle { - font-size: 20pt; - color: #FFFFFF; background-color: #A0A0A0; - padding: 10px 15px 10px 15px; - border-width: 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - #MainTopic .CTitle { - font-size: 24pt; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CBody { - margin-left: 15px; margin-right: 15px } - - - .CToolTip { - position: absolute; visibility: hidden; - left: 0; top: 0; max-width: 50%; - background-color: #FFFFE0; - padding: 5px; - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000; - font-size: 10pt } - - /* Opera 6 gives it a huge height otherwise. */ - .Opera6 .CTooltip, .Opera5 .CTooltip { - max-width: 100% } - - .CHeading { - font-weight: bold; - margin-top: 1.5em; margin-bottom: .5em } - - .CCode { - font: 10pt "Courier New", Courier, monospace; - overflow: auto; - } - - .CBulletList { - /* I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever. - Reapply it here as padding. */ - padding-left: 15px; padding-right: 15px; - margin: .5em 5ex .5em 5ex; - } - - .CDescriptionList { - margin: .5em 5ex 0 5ex } - - /* IE 4 and Konqueror always makes it too long. */ - .IE4 .CDescriptionList, - .KHTML .CDescriptionList { - width: 85% } - - .CDLEntry { - font: 10pt "Courier New", Courier, monospace; color: #808080; - padding-bottom: .25em; - white-space: nowrap } - - .CDLDescription { - font-size: 12pt; /* For browsers that don't inherit correctly, like Opera 5. */ - padding-bottom: .5em; padding-left: 5ex } - - - - - -.Prototype { - font: 10pt "Courier New", Courier, monospace; - padding: 5px 3ex; - border-width: 1px; border-style: solid; - margin: 0 5ex 1.5em 5ex; - } - - .Prototype td { - font-size: 10pt; - } - - .PDefaultValue, - .PTypePrefix { - color: #8F8F8F; - } - .PTypePrefix { - text-align: right; - } - - .IE .Prototype table { - padding: 0; - } - - .CFunction .Prototype { - background-color: #F4F4F4; border-color: #D0D0D0 } - .CProperty .Prototype { - background-color: #F4F4FF; border-color: #C0C0E8 } - .CVariable .Prototype { - background-color: #FFFFF0; border-color: #E0E0A0 } - - .CDatabaseIndex .Prototype, - .CConstant .Prototype { - background-color: #D0D0D0; border-color: #000000 } - .CType .Prototype { - background-color: #FFF8F8; border-color: #E8C8C8 } - .CDatabaseTrigger .Prototype, - .CEvent .Prototype, - .CDelegate .Prototype { - background-color: #F0FCF0; border-color: #B8E4B8 } - - .CToolTip .Prototype { - margin: 0 0 .5em 0; - white-space: nowrap; - } - - - - - -.Summary { - margin: 1.5em 5ex 0 5ex } - - .STitle { - font-size: 14pt; font-weight: bold; - margin-bottom: .5em } - - - .SBorder { - background-color: #FFFFF0; - padding: 15px; - border: 1px solid #C0C060 } - - /* Let's observe the evolution of IE's brokeness, shall we? - IE 4 always makes them too long, there's no way around it. */ - .IE4 .SBorder { - width: 85% } - /* IE 5 will make them too long unless you set the width to 100%. Isn't this implied for a div? */ - .IE5 .SBorder { - width: 100% } - /* IE 6 behaves like 5 when it's in a frame, but without frames it will be correct without a width or slightly too long - (but not enough to scroll) with a width. This arbitrary weirdness simply astounds me. */ - body.FramedContentPage .IE6 .SBorder { - width: 100% } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Gecko .SBorder { - -moz-border-radius: 20px } - - - .STable { - font-size: 10pt; width: 100% } - - .SEntrySize { - width: 30% } - .SDescriptionSize { - width: 70% } - - - .SMarked { - background-color: #F8F8D8 } - - - .SEntry .SIndent1 { - margin-left: 1.5ex } - .SEntry .SIndent2 { - margin-left: 3ex } - .SEntry .SIndent3 { - margin-left: 4.5ex } - .SEntry .SIndent4 { - margin-left: 6ex } - .SEntry .SIndent5 { - margin-left: 7.5ex } - - .SDescription { - padding-left: 3ex } - - .SDescription a { color: #800000} - .SDescription a:active { color: #A00000 } - - - .SGroup { - margin-top: .5em; margin-bottom: .25em } - - .SGroup .SEntry { - font-weight: bold; font-variant: small-caps } - - .SGroup .SEntry a { color: #800000 } - .SGroup .SEntry a:active { color: #F00000 } - - - .SMain .SEntry, - .SClass .SEntry, - .SDatabase .SEntry, - .SDatabaseTable .SEntry, - .SSection .SEntry { - font-weight: bold; font-size: 12pt; - margin-bottom: .25em } - - .SClass, - .SDatabase, - .SDatabaseTable, - .SSection { - margin-top: 1em } - - .SMain .SEntry a, - .SClass .SEntry a, - .SDatabase .SEntry a, - .SDatabaseTable .SEntry a, - .SSection .SEntry a { color: #000000 } - - .SMain .SEntry a:active, - .SClass .SEntry a:active, - .SDatabase .SEntry a:active, - .SDatabaseTable .SEntry a:active, - .SSection .SEntry a:active { color: #A00000 } - - - - - -.ClassHierarchy { - margin: 0 15px 1em 15px } - - .CHEntry { - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0; - margin-bottom: 3px; - padding: 2px 2ex; - font-size: 12pt; - background-color: #F4F4F4; color: #606060; - } - - .Gecko .CHEntry { - -moz-border-radius: 4px; - } - - .CHCurrent .CHEntry { - font-weight: bold; - border-color: #000000; - color: #000000; - } - - .CHChildNote .CHEntry { - font-style: italic; - font-size: 8pt; - } - - .CHIndent { - margin-left: 3ex; - } - - .CHEntry a:link, - .CHEntry a:visited, - .CHEntry a:hover { - color: #606060; - } - .CHEntry a:active { - color: #800000; - } - - - - - -body.FramedIndexPage, -.IndexSection { - background-color: #FFFFFF; - font: 12pt "Times New Roman", serif; - padding: 15px } - -.IndexSection { - border-width: 0 0 1px 1px; border-style: solid; border-color: #000000 } - - .IPageTitle { - font-size: 24pt; font-weight: bold; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; border-style: solid; - margin: -15px -15px 0 -15px } - - .INavigationBar { - text-align: center; - background-color: #FFFFF0; - padding: 5px; - border-bottom: solid 1px black; - margin: 0 -15px 15px -15px } - - .INavigationBar a { - font-weight: bold } - - .IHeading { - font-size: 20pt; font-weight: bold; - padding: 2.5em 0 .5em 0; - text-align: center; - width: 3.5ex; - } - #IFirstHeading { - padding-top: 0; - } - - .IEntry { - padding-left: 1ex; } - - .ISubIndex { - padding-left: 3ex; padding-bottom: .5em } - - /* While it may cause some entries to look like links when they aren't, I found it's much easier to read the - index if everything's the same color. */ - .ISymbol { - font-weight: bold; color: #900000 } - - .ISymbolPrefix { - text-align: right; - color: #C47C7C; - background-color: #F8F8F8; - border-right: 3px solid #E0E0E0; - border-left: 1px solid #E0E0E0; - padding: 0 1px 0 2px; - } - #IFirstSymbolPrefix { - border-top: 1px solid #E0E0E0; - } - #ILastSymbolPrefix { - border-bottom: 1px solid #E0E0E0; - } - #IOnlySymbolPrefix { - border-top: 1px solid #E0E0E0; - border-bottom: 1px solid #E0E0E0; - } - - a.IParent, - a.IFile { - display: block; - } - - - -.Footer { - font-size: 8pt; color: #909090 } - -body.UnframedPage .Footer { - text-align: right; - margin: 2px } - -body.FramedMenuPage .Footer { - text-align: center; - margin: 5em 10px 0 10px} - - .Footer a:link, - .Footer a:hover, - .Footer a:visited { color: #909090 } - .Footer a:active { color: #A00000 } diff --git a/vendor/naturaldocs/Help/example/Small.css b/vendor/naturaldocs/Help/example/Small.css deleted file mode 100644 index 0cb7be1c9..000000000 --- a/vendor/naturaldocs/Help/example/Small.css +++ /dev/null @@ -1,507 +0,0 @@ -/* - IMPORTANT: If you're editing this file in the output directory of one of - your projects, your changes will be overwritten the next time you run - Natural Docs. Instead, copy this file to your project directory, make your - changes, and you can use it with -s. Even better would be to make a CSS - file in your project directory with only your changes, which you can then - use with -s [original style] [your changes]. - - On the other hand, if you're editing this file in the Natural Docs styles - directory, the changes will automatically be applied to all your projects - that use this style the next time Natural Docs is run on them. - - This file is part of Natural Docs, which is Copyright © 2003-2004 Greg Valure - Natural Docs is licensed under the GPL -*/ - -body { - font-family: Verdana, Arial, sans-serif; - color: #000000; - margin: 0px; padding: 0px } - -body.UnframedPage { - background-color: #E8E8E8 } - - -a:link, -a:visited { color: #900000; text-decoration: none } -a:hover { color: #900000; text-decoration: underline } -a:active { color: #FF0000; text-decoration: underline } - -td { - vertical-align: top } - -/* - Comment out this line to use web-style paragraphs (blank line between - paragraphs, no indent) instead of print-style paragraphs (no blank line, - indented.) -*/ -p { - text-indent: 5ex; margin: 0 } - - -/* Can't use something like display: none or it won't break. */ -.HB { - font-size: 1px } - - - - -body.FramedMenuPage, -.MenuSection { - font-size: 8pt; - background-color: #E8E8E8; - padding: 10px 0 0 0 } - -.MenuSection { - width: 27ex } - - - .MTitle { - font-size: 16pt; font-weight: bold; font-variant: small-caps; - text-align: center; - padding: 5px 10px 15px 10px; - border-bottom: 1px dotted #000000; - margin-bottom: 15px } - - .MSubTitle { - font-size: 9pt; font-weight: normal; font-variant: normal; - margin-top: 1ex; margin-bottom: 5px } - - - .MEntry a:link, - .MEntry a:hover, - .MEntry a:visited { color: #606060; margin-right: 0 } - .MEntry a:active { color: #A00000; margin-right: 0 } - - - .MGroup { - font-variant: small-caps; font-weight: bold; - margin: 1em 0 1em 10px } - - /* Konqueror just can't do margins. */ - .KHTML .MGroup { - margin-bottom: 0; padding-bottom: 1em } - - .MGroupContent { - font-variant: normal; font-weight: normal } - - .MGroup a:link, - .MGroup a:hover, - .MGroup a:visited { color: #545454; margin-right: 10px } - .MGroup a:active { color: #A00000; margin-right: 10px } - - - .MFile, - .MText, - .MLink, - .MIndex { - padding: 1px 17px 2px 10px; - margin: .25em 0 .25em 0 } - - .MText { - font-size: 8pt; font-style: italic } - - .MLink { - font-style: italic } - - #MSelected { - color: #000000; background-color: #FFFFFF; - /* Replace padding with border. */ - padding: 0 10px 0 10px; - border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000; - margin-right: 5px } - - /* Close off the left side when its in a group. */ - .MGroup #MSelected { - padding-left: 9px; border-left-width: 1px } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Gecko #MSelected { - -moz-border-radius-topright: 10px; - -moz-border-radius-bottomright: 10px } - .Gecko .MGroup #MSelected { - -moz-border-radius-topleft: 10px; - -moz-border-radius-bottomleft: 10px } - - - - -body.FramedContentPage, -.ContentSection { - background-color: #FFFFFF; - padding-bottom: 15px } - -.ContentSection { - border-width: 0 0 1px 1px; border-style: solid; border-color: #000000 } - - - .CTopic { - font-size: 8pt; - /* This should be a margin but Konq 3.1.1 sucks. */ - padding-bottom: 3em } - - - .CTitle { - font-size: 11pt; font-weight: bold; - border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0; - margin: 0 15px .5em 15px } - - .CGroup .CTitle { - font-size: 16pt; font-variant: small-caps; - padding-left: 15px; padding-right: 15px; - border-width: 0 0 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CClass .CTitle, - .CInterface .CTitle, - .CDatabase .CTitle, - .CDatabaseTable .CTitle, - .CSection .CTitle { - font-size: 18pt; - color: #FFFFFF; background-color: #A0A0A0; - padding: 10px 15px 10px 15px; - border-width: 2px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - #MainTopic .CTitle { - font-size: 20pt; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; - margin-left: 0; margin-right: 0 } - - .CBody { - margin-left: 15px; margin-right: 15px } - - - .CToolTip { - position: absolute; visibility: hidden; - left: 0; top: 0; max-width: 50%; - background-color: #FFFFE0; - padding: 5px; - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000; - font-size: 8pt } - - /* Opera 6 gives it a huge height otherwise. */ - .Opera6 .CTooltip, .Opera5 .CTooltip { - max-width: 100% } - - .CHeading { - font-weight: bold; font-size: 9pt; - margin-top: 1.5em; margin-bottom: .5em } - - .CCode { - font: 8pt "Courier New", Courier, monospace; - overflow: auto; - } - - .CBulletList { - /* I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever. - Reapply it here as padding. */ - padding-left: 15px; padding-right: 15px; - margin: .5em 5ex .5em 5ex; - } - - .CDescriptionList { - margin: .5em 5ex 0 5ex } - - /* IE 4 and Konqueror always makes it too long. */ - .IE4 .CDescriptionList, - .KHTML .CDescriptionList { - width: 85% } - - .CDLEntry { - font: 8pt "Courier New", Courier, monospace; color: #808080; - padding-bottom: .25em; - white-space: nowrap } - - .CDLDescription { - font-size: 8pt; /* For browsers that don't inherit correctly, like Opera 5. */ - padding-bottom: .5em; padding-left: 5ex } - - - - - -.Prototype { - font: 8pt "Courier New", Courier, monospace; - padding: 5px 3ex; - border-width: 1px; border-style: solid; - margin: 0 5ex 1.5em 5ex; - } - - .Prototype td { - font-size: 8pt; - } - - .PDefaultValue, - .PTypePrefix { - color: #8F8F8F; - } - .PTypePrefix { - text-align: right; - } - - .IE .Prototype table { - padding: 0; - } - - .CFunction .Prototype { - background-color: #F4F4F4; border-color: #D0D0D0 } - .CProperty .Prototype { - background-color: #F4F4FF; border-color: #C0C0E8 } - .CVariable .Prototype { - background-color: #FFFFF0; border-color: #E0E0A0 } - - .CDatabaseIndex .Prototype, - .CConstant .Prototype { - background-color: #D0D0D0; border-color: #000000 } - .CType .Prototype { - background-color: #FFF8F8; border-color: #E8C8C8 } - .CDatabaseTrigger .Prototype, - .CEvent .Prototype, - .CDelegate .Prototype { - background-color: #F0FCF0; border-color: #B8E4B8 } - - .CToolTip .Prototype { - margin: 0 0 .5em 0; - white-space: nowrap; - } - - - - - -.Summary { - margin: 1.5em 5ex 0 5ex } - - .STitle { - font-size: 11pt; font-weight: bold; - margin-bottom: .5em } - - - .SBorder { - background-color: #FFFFF0; - padding: 15px; - border: 1px solid #C0C060 } - - /* Let's observe the evolution of IE's brokeness, shall we? - IE 4 always makes them too long, there's no way around it. */ - .IE4 .SBorder { - width: 85% } - /* IE 5 will make them too long unless you set the width to 100%. Isn't this implied for a div? */ - .IE5 .SBorder { - width: 100% } - /* IE 6 behaves like 5 when it's in a frame, but without frames it will be correct without a width or slightly too long - (but not enough to scroll) with a width. This arbitrary weirdness simply astounds me. */ - body.FramedContentPage .IE6 .SBorder { - width: 100% } - - /* A treat for Mozilla users. Blatantly non-standard. Will be replaced with CSS 3 attributes when finalized/supported. */ - .Gecko .SBorder { - -moz-border-radius: 20px } - - - .STable { - font-size: 8pt; width: 100% } - - .SEntrySize { - width: 30% } - .SDescriptionSize { - width: 70% } - - - .SMarked { - background-color: #F8F8D8 } - - - .SEntry .SIndent1 { - margin-left: 1.5ex } - .SEntry .SIndent2 { - margin-left: 3ex } - .SEntry .SIndent3 { - margin-left: 4.5ex } - .SEntry .SIndent4 { - margin-left: 6ex } - .SEntry .SIndent5 { - margin-left: 7.5ex } - - .SDescription { - padding-left: 3ex } - - .SDescription a { color: #800000} - .SDescription a:active { color: #A00000 } - - - .SGroup { - margin-top: .5em; margin-bottom: .25em } - - .SGroup .SEntry { - font-weight: bold; font-variant: small-caps } - - .SGroup .SEntry a { color: #800000 } - .SGroup .SEntry a:active { color: #F00000 } - - - .SMain .SEntry, - .SClass .SEntry, - .SDatabase .SEntry, - .SDatabaseTable .SEntry, - .SSection .SEntry { - font-weight: bold; font-size: 9pt; - margin-bottom: .25em } - - .SClass, - .SDatabase, - .SDatabaseTable, - .SSection { - margin-top: 1em } - - .SMain .SEntry a, - .SClass .SEntry a, - .SDatabase .SEntry a, - .SDatabaseTable .SEntry a, - .SSection .SEntry a { color: #000000 } - - .SMain .SEntry a:active, - .SClass .SEntry a:active, - .SDatabase .SEntry a:active, - .SDatabaseTable .SEntry a:active, - .SSection .SEntry a:active { color: #A00000 } - - - - - -.ClassHierarchy { - margin: 0 15px 1em 15px } - - .CHEntry { - border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0; - margin-bottom: 3px; - padding: 2px 2ex; - font-size: 8pt; - background-color: #F4F4F4; color: #606060; - } - - .Gecko .CHEntry { - -moz-border-radius: 4px; - } - - .CHCurrent .CHEntry { - font-weight: bold; - border-color: #000000; - color: #000000; - } - - .CHChildNote .CHEntry { - font-style: italic; - font-size: 8pt; - } - - .CHIndent { - margin-left: 3ex; - } - - .CHEntry a:link, - .CHEntry a:visited, - .CHEntry a:hover { - color: #606060; - } - .CHEntry a:active { - color: #800000; - } - - - - - -body.FramedIndexPage, -.IndexSection { - background-color: #FFFFFF; - font-size: 8pt; - padding: 15px } - -.IndexSection { - border-width: 0 0 1px 1px; border-style: solid; border-color: #000000 } - - .IPageTitle { - font-size: 20pt; font-weight: bold; - color: #FFFFFF; background-color: #7070C0; - padding: 10px 15px 10px 15px; - border-width: 0 0 3px 0; border-color: #000000; border-style: solid; - margin: -15px -15px 0 -15px } - - .INavigationBar { - text-align: center; - background-color: #FFFFF0; - padding: 5px; - border-bottom: solid 1px black; - margin: 0 -15px 15px -15px } - - .INavigationBar a { - font-weight: bold } - - .IHeading { - font-size: 14pt; font-weight: bold; - padding: 2.5em 0 .5em 0; - text-align: center; - width: 3.5ex; - } - #IFirstHeading { - padding-top: 0; - } - - .IEntry { - padding-left: 1ex; } - - .ISubIndex { - padding-left: 3ex; padding-bottom: .5em } - - /* While it may cause some entries to look like links when they aren't, I found it's much easier to read the - index if everything's the same color. */ - .ISymbol { - font-weight: bold; color: #900000 } - - .ISymbolPrefix { - text-align: right; - color: #C47C7C; - background-color: #F8F8F8; - border-right: 3px solid #E0E0E0; - border-left: 1px solid #E0E0E0; - padding: 0 1px 0 2px; - } - #IFirstSymbolPrefix { - border-top: 1px solid #E0E0E0; - } - #ILastSymbolPrefix { - border-bottom: 1px solid #E0E0E0; - } - #IOnlySymbolPrefix { - border-top: 1px solid #E0E0E0; - border-bottom: 1px solid #E0E0E0; - } - - a.IParent, - a.IFile { - display: block; - } - - - -.Footer { - font-size: 8pt; color: #909090 } - -body.UnframedPage .Footer { - text-align: right; - margin: 2px } - -body.FramedMenuPage .Footer { - text-align: center; - margin: 5em 10px 0 10px} - - .Footer a:link, - .Footer a:hover, - .Footer a:visited { color: #909090 } - .Footer a:active { color: #A00000 } diff --git a/vendor/naturaldocs/Help/example/showstyle.html b/vendor/naturaldocs/Help/example/showstyle.html deleted file mode 100644 index e71b8b9cd..000000000 --- a/vendor/naturaldocs/Help/example/showstyle.html +++ /dev/null @@ -1,43 +0,0 @@ - - -CSS Sample - Project - - - - - - - - - - - - - - -
This is the style.  Back
- - - - - - -

CSS Sample

Here’s what the output would look like with the currently selected CSS style.  The CSS structure is well-documented so you can easily alter it or make your own.

Here’s a paragraph break.  Natural Docs defaults to print-style paragraphs, where each one is indented rather than separated with a blank line.  If you open the CSS file it will tell you which line to remove to go back to web-style paragraphs.

Header

There’s a header, just so you know what one looks like in this style.  As you can tell, the quality of the text here is going to go downhill fast as I’m really just blathering on to fill up the page.  If you’re actually reading this, you can safely stop now.  No, really.  I’m not going to say anything important from here on down.  Reading it will be just as boring as writing it was.

  • Here’s a bullet.  Thought you should see that.
  • Here’s another one.  Well look at that.
  • And a third.  Looks just like all the others, but I’m going to give it some more text.  So there you go.

Now lets look at a text diagram, shall we?  Are you still reading this?  What’s wrong with you?

+------+     +------+
-| Moby | --> | Dick |
-+------+     +------+
-   |
-   V
-+----------+
-| Musician |
-+----------+
Summary
Here’s what the output would look like with the currently selected CSS style.
Ah, here’s our first function.
This is another function, much like DoSomething(), but different, in that it does something else.
This is my variable.

DoSomething

int DoSomething(int one,
int two,
float four)

Ah, here’s our first function.  I have nothing to say about it just like I had nothing to say about anything else.  Typing, typing, typing to fill up space.  Just a random stream-of-consciousness about nothing.

Parameters

oneThis is the first parameter, aptly named one.
twoBet you can’t guess what the next one is called?
fourHah!  Did that just to screw you up.

Returns

Sometimes it returns, sometimes it doesn’t.  It’s moody that way.

DoSomethingElse

bool DoSomethingElse()

This is another function, much like DoSomething(), but different, in that it does something else.  Hover over DoSomething(), will ya?  See the nice DHTML tooltip goodness.  Here, here’s a link to myVariable too.  Hover over that.

Variables

myVariable

int myVariable

This is my variable.  See how the prototype is colored differently on the default styles?  I thought that was cool too, since you can tell where you are in the documentation easier.  Or maybe you didn’t think it was cool.  I shouldn’t make assumptions like that.  See, now you went and hurt my feelings.  Shame on you.

Um, why are you still reading this?  Didn’t you learn by now?

int DoSomething(int one,
int two,
float four)
Ah, here’s our first function.
bool DoSomethingElse()
This is another function, much like DoSomething(), but different, in that it does something else.
int myVariable
This is my variable.
diff --git a/vendor/naturaldocs/Help/examples.css b/vendor/naturaldocs/Help/examples.css deleted file mode 100644 index f61d06b6d..000000000 --- a/vendor/naturaldocs/Help/examples.css +++ /dev/null @@ -1,90 +0,0 @@ -@import URL(example/Default.css); - - -.NDContent { - color: #000000; background-color: #FFFFFF; - padding: 15px 0; - border-style: solid; - border-width: 1px 3px 3px 1px; - border-color: #c0c0c0 #808080 #808080 #c0c0c0; - margin: 1em 5ex; - -moz-border-radius: 12px; - } - - .NDContent p, - .NDContent li, - .NDContent td, - .NDMenu td, - .NDSummary td, - .NDIndex td { - font-size: 10pt; - line-height: normal; - } - .NDContent .CTopic { - padding-bottom: 0; - } - .Prototype td { - font: 10pt Courier New, monospace; - } - .NDIndex .IHeading { - font-size: 16pt; - } - - -.NDMenu { - font: 9pt Verdana, Arial, sans-serif; - color: #000000; background-color: #E8E8E8; - width: 27ex; - padding: 10px 0; - border-style: solid; - border-width: 1px 3px 3px 1px; - border-color: #808080 #606060 #606060 #808080; - margin: 1em 0 1em 5ex; - -moz-border-radius: 12px; - } - - -.NDFooter { - font: 8pt Verdana, Arial, sans-serif; - color: #909090; background-color: #E8E8E8; - border-style: solid; - border-width: 1px 3px 3px 1px; - border-color: #808080 #606060 #606060 #808080; - margin: 1em 0 1em 5ex; - -moz-border-radius: 12px; - } -.NDFooter td { - font-size: 8pt; - padding: 0 2ex; - } - - .NDFooter a:link, - .NDFooter a:hover, - .NDFooter a:visited { color: #909090 } - .NDFooter a:active { color: #A00000 } - - -.NDSummary { - padding: 15px; - border-style: solid; - border-width: 1px 3px 3px 1px; - border-color: #c0c0c0 #808080 #808080 #c0c0c0; - margin: 1em 5ex; - -moz-border-radius: 12px; - } - - .NDSummary .Summary { - margin-top: 0; - } - - -.NDIndex { - color: #000000; background-color: #FFFFFF; - padding: 15px; - border-style: solid; - border-width: 1px 3px 3px 1px; - border-color: #c0c0c0 #808080 #808080 #c0c0c0; - margin: 1em 5ex; - -moz-border-radius: 12px; - } - diff --git a/vendor/naturaldocs/Help/images/header/background.png b/vendor/naturaldocs/Help/images/header/background.png deleted file mode 100644 index 09a2ea465..000000000 Binary files a/vendor/naturaldocs/Help/images/header/background.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/leftside.png b/vendor/naturaldocs/Help/images/header/leftside.png deleted file mode 100644 index 7d0938657..000000000 Binary files a/vendor/naturaldocs/Help/images/header/leftside.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/logo.png b/vendor/naturaldocs/Help/images/header/logo.png deleted file mode 100644 index 9317a1b69..000000000 Binary files a/vendor/naturaldocs/Help/images/header/logo.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/overbody.png b/vendor/naturaldocs/Help/images/header/overbody.png deleted file mode 100644 index 6b86af15f..000000000 Binary files a/vendor/naturaldocs/Help/images/header/overbody.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/overbodybg.png b/vendor/naturaldocs/Help/images/header/overbodybg.png deleted file mode 100644 index b4284ec19..000000000 Binary files a/vendor/naturaldocs/Help/images/header/overbodybg.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/overleftmargin.png b/vendor/naturaldocs/Help/images/header/overleftmargin.png deleted file mode 100644 index 3d02af7fa..000000000 Binary files a/vendor/naturaldocs/Help/images/header/overleftmargin.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/overmenu.png b/vendor/naturaldocs/Help/images/header/overmenu.png deleted file mode 100644 index d720d9860..000000000 Binary files a/vendor/naturaldocs/Help/images/header/overmenu.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/overmenubg.png b/vendor/naturaldocs/Help/images/header/overmenubg.png deleted file mode 100644 index 69339d8cb..000000000 Binary files a/vendor/naturaldocs/Help/images/header/overmenubg.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/header/rightside.png b/vendor/naturaldocs/Help/images/header/rightside.png deleted file mode 100644 index f8ef976a4..000000000 Binary files a/vendor/naturaldocs/Help/images/header/rightside.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/about.png b/vendor/naturaldocs/Help/images/menu/about.png deleted file mode 100644 index ca65ea4e7..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/about.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/background.png b/vendor/naturaldocs/Help/images/menu/background.png deleted file mode 100644 index db8b557bb..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/background.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/bottomleft.png b/vendor/naturaldocs/Help/images/menu/bottomleft.png deleted file mode 100644 index 0f608c8b9..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/bottomleft.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/bottomright.png b/vendor/naturaldocs/Help/images/menu/bottomright.png deleted file mode 100644 index 10c9e0291..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/bottomright.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/community.png b/vendor/naturaldocs/Help/images/menu/community.png deleted file mode 100644 index 0021013ac..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/community.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/customizing.png b/vendor/naturaldocs/Help/images/menu/customizing.png deleted file mode 100644 index d56d25b3f..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/customizing.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/images/menu/using.png b/vendor/naturaldocs/Help/images/menu/using.png deleted file mode 100644 index 1de988d2c..000000000 Binary files a/vendor/naturaldocs/Help/images/menu/using.png and /dev/null differ diff --git a/vendor/naturaldocs/Help/index.html b/vendor/naturaldocs/Help/index.html deleted file mode 100644 index 84a7b633b..000000000 --- a/vendor/naturaldocs/Help/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - -Natural Docs - - - -
Natural Docs
Version 1.51

This is the Natural Docs help file, a subset of the documentation available at the web site.  Everything you need is on the menu to the left.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/javascript/BrowserStyles.js b/vendor/naturaldocs/Help/javascript/BrowserStyles.js deleted file mode 100644 index 71666418d..000000000 --- a/vendor/naturaldocs/Help/javascript/BrowserStyles.js +++ /dev/null @@ -1,77 +0,0 @@ - -// -// Browser Styles -// ____________________________________________________________________________ - -var agt=navigator.userAgent.toLowerCase(); -var browserType; -var browserVer; - -if (agt.indexOf("opera") != -1) - { - browserType = "Opera"; - - if (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1) - { browserVer = "Opera5"; } - else if (agt.indexOf("opera 6") != -1 || agt.indexOf("opera/6") != -1) - { browserVer = "Opera6"; } - else if (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1) - { browserVer = "Opera7"; } - } - -else if (agt.indexOf("khtml") != -1 || agt.indexOf("konq") != -1 || agt.indexOf("safari") != -1) - { - browserType = "KHTML"; - } - -else if (agt.indexOf("msie") != -1) - { - browserType = "IE"; - - if (agt.indexOf("msie 4") != -1) - { browserVer = "IE4"; } - else if (agt.indexOf("msie 5") != -1) - { browserVer = "IE5"; } - else if (agt.indexOf("msie 6") != -1) - { browserVer = "IE6"; } - else if (agt.indexOf("msie 7") != -1) - { browserVer = "IE7"; } - } - -else if (agt.indexOf("gecko") != -1) - { - browserType = "Gecko"; - } - -// Opera already taken care of. -else if (agt.indexOf("mozilla") != -1 && agt.indexOf("compatible") == -1 && agt.indexOf("spoofer") == -1 && - agt.indexOf("webtv") == -1 && agt.indexOf("hotjava") == -1) - { - browserType = "Netscape"; - - if (agt.indexOf("mozilla/4") != -1) - { browserVer = "Netscape4"; } - } - - -function OpeningBrowserTags() - { - if (browserType) - { - document.write('
'); - - if (browserVer) - { document.write('
'); } - } - }; - -function ClosingBrowserTags() - { - if (browserType) - { - document.write('
'); - - if (browserVer) - { document.write('
'); } - } - }; diff --git a/vendor/naturaldocs/Help/javascript/PNGHandling.js b/vendor/naturaldocs/Help/javascript/PNGHandling.js deleted file mode 100644 index ab47a538e..000000000 --- a/vendor/naturaldocs/Help/javascript/PNGHandling.js +++ /dev/null @@ -1,72 +0,0 @@ -// Parts derived from: -// Opacity Displayer, Version 1.0 -// Copyright Michael Lovitt, 6/2002. -// Distribute freely, but please leave this notice intact. -// http://www.alistapart.com/articles/pngopacity/ - -// Parts derived from: -// Natural Docs -// Copyright (C) 2003-2004 Greg Valure -// http://www.naturaldocs.org/ - - -var pngTransform; -var pngNormal; - -var agt=navigator.userAgent.toLowerCase(); - -if (agt.indexOf("opera") != -1) - { - if ( (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1) && - agt.indexOf("mac") != -1) - { - pngNormal = 1; - } - else if (agt.indexOf("opera 6") != -1 || agt.indexOf("opera/6") != -1 || - agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1) - { - pngNormal = 1; - } - } - -else if (agt.indexOf("msie") != -1) - { - if (agt.indexOf("msie 5.5") != -1 || agt.indexOf("msie 6") != -1) - { - if (agt.indexOf("mac") != -1) - { pngNormal = 1; } - else if (agt.indexOf("win") != -1) - { pngTransform = 1; }; - } - - else if (agt.indexOf("msie 5") != -1) - { - if (agt.indexOf("mac") != -1) - { pngNormal = 1; }; - } - - else if (agt.indexOf("msie 7") != -1) - { pngNormal = 1; } - } - -else if (agt.indexOf("gecko") != -1) - { - pngNormal = 1; - } - - -function PNGGIF(strPath, intWidth, intHeight, strAlt, strID) - { - if (pngTransform) - { - document.write('
'); - } - else if (pngNormal) - { - document.write(''+strAlt+''); - } - else - { - document.write(''+strAlt+''); - } - }; diff --git a/vendor/naturaldocs/Help/keywords.html b/vendor/naturaldocs/Help/keywords.html deleted file mode 100644 index 648250325..000000000 --- a/vendor/naturaldocs/Help/keywords.html +++ /dev/null @@ -1,38 +0,0 @@ - - -Natural Docs Topics and Keywords - - - -
Natural Docs
Topics and Keywords

Keywords are not case sensitive and are interchangable within their topic type.  The plural forms denote list topics where every item in its definition lists are treated like they have their own topic.

General Topics
Generic
topictopics
aboutlist
Section
Ends Scope
section
title
Group
group
File
Always Global
filefiles
programprograms
scriptscripts
documentdocuments
docdocs
headerheaders
Code Topics
Class
Starts Scope
classclasses
structurestructures
structstructs
packagepackages
namespacenamespaces
Interface
Starts Scope
interfaceinterfaces
Type
typetypes
typedeftypedefs
Constant
constantconstants
constconsts
Enumeration
Topic indexed under Types
Members indexed under Constants
enumerationenumerations
enumenums
Function
List topics break apart
functionfunctions
funcfuncs
procedureprocedures
procprocs
routineroutines
subroutinesubroutines
subsubs
methodmethods
callbackcallbacks
constructorconstructors
destructordestructors
operatoroperators
Property
propertyproperties
propprops
Event
eventevents
Delegate
delegatedelegates
Macro
macromacros
definedefines
defdefs
Variable
variablevariables
varvars
integerintegers
intints
uintuints
longlongs
ulongulongs
shortshorts
ushortushorts
bytebytes
ubyteubytes
sbytesbytes
floatfloats
doubledoubles
realreals
decimaldecimals
scalarscalars
arrayarrays
arrayrefarrayrefs
hashhashes
hashrefhashrefs
boolbools
booleanbooleans
flagflags
bitbits
bitfieldbitfields
fieldfields
pointerpointers
ptrptrs
referencereferences
refrefs
objectobjects
objobjs
charactercharacters
wcharacterwcharacters
charchars
wcharwchars
stringstrings
wstringwstrings
strstrs
wstrwstrs
handlehandles
Database Topics
Database
databasedatabases
dbdbs
Database Table
Starts Scope
tabletables
database tabledatabase tables
db tabledb tables
Database View
Starts Scope
viewviews
database viewdatabase views
db viewdb views
Database Cursor
cursorcursors
database cursordatabase cursors
db cursordb cursors
Database Index
indexindexes
indices
database indexdatabase indexes
database indices
db indexdb indexes
db indices
keykeys
database keydatabase keys
db keydb keys
primary keyprimary keys
database primary keydatabase primary keys
db primary keydb primary keys
Database Trigger
triggertriggers
database triggerdatabase triggers
db triggerdb triggers
Miscellaneous Topics
Cookie
Always global
cookiecookies
Build Target
targettargets
build targetbuild targets
Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/languages.html b/vendor/naturaldocs/Help/languages.html deleted file mode 100644 index 02f21a09a..000000000 --- a/vendor/naturaldocs/Help/languages.html +++ /dev/null @@ -1,32 +0,0 @@ - - -Natural Docs Language Support - - - -
Natural Docs
About
Language SupportOutput Formats
Language Support
Full Language Support

The following languages have full language support, which means you get:

Full code documentation.  All functions, variables, and classes will appear in the output regardless of whether you wrote anything for them.  This can be turned off with the -do command line option.

Inheritance diagrams.  They will appear in the output wherever appropriate.

Javadoc compatibility.  Natural Docs can read most Javadoc comments and include them in the output.  You can also write Natural Docs documentation without topic lines by using the Javadoc comment symbols.

Auto-scoping.  The class a topic is part of is determined by the source code rather than class and section topics.

  • C# (1.1, some 2.0)
  • Perl
  • ActionScript (2 and 3)
Basic Language Support

The following languages have basic language support, which means you have:

Explicit documentation only.  Only things you write Natural Docs documentation for will appear in the output.

No inheritance diagrams.

Natural Docs comments only.  They also need to include a topic line.

Topic scoping.  The class a topic is part of is determined by the topic scoping rules.

  • C/C++
  • Java
  • PHP
  • Python
  • PL/SQL
  • Visual Basic
  • Pascal/Delphi
  • Ada
  • JavaScript
  • Ruby
  • Tcl
  • ColdFusion
  • Assembly
  • Fortran (free-format only)
  • R
  • Makefiles
  • Plain Text
  • Custom Languages
Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/menu.html b/vendor/naturaldocs/Help/menu.html deleted file mode 100644 index ef087d23a..000000000 --- a/vendor/naturaldocs/Help/menu.html +++ /dev/null @@ -1,79 +0,0 @@ - - -Organizing the Menu - Natural Docs - - - -
Natural Docs
Organizing the Menu

Natural Docs creates a file called Menu.txt in your project directory that you can edit to organize the menu.  It normally takes care of this on its own, but you have the option of improving it manually if you want to.

Order and Titles

If you’ve never looked in it before, the menu file will have some comments explaining its syntax and a list like you see below.

File: ClassA  (ClassA.h)
-File: ClassB  (ClassB.h)
-File: Globals  (Globals.h)
-

The list gets turned into a menu that looks like this:

The lines are in the format “File: [title] ([filename])”.  When Natural Docs made the menu, it decided on its own what the title of each file should be and then put them in alphabetical order.  However, suppose we don’t want this.  We want Globals above the classes and we want spaces in the menu titles.  So we edit the file.

File: Globals  (Globals.h)
-File: Class A  (ClassA.h)
-File: Class B  (ClassB.h)
-

Run Natural Docs again and the menu is updated.

However, open the menu file again and you’ll see something interesting.

File: Globals  (Globals.h)
-File: Class A  (no auto-title, ClassA.h)
-File: Class B  (no auto-title, ClassB.h)
-

Natural Docs noticed that you changed a couple of the titles and added a no auto-title attribute to each one.  This tells it to never change them on it’s own in the future, so your changes won’t be lost.  You don’t have to worry about adding this, Natural Docs will always do it automatically.  However, to go back to automatic titles you’d have to manually remove it.

Grouping

This menu is good for our example, but in the real world they get much, much longer.  We can add groups to organize it further.  Natural Docs will create them automatically based on the each file’s directory, but once again you can improve it manually if that’s not good enough.

You can add groups as shown below.

File: Globals  (Globals.h)
-Group: Classes {
-   File: Class A  (no auto-title, ClassA.h)
-   File: Class B  (no auto-title, ClassB.h) }
-

You can also nest them inside each other.

File: Globals  (Globals.h)
-Group: Classes {
-   File: Class A  (no auto-title, ClassA.h)
-   Group: Nested Group {
-      File: Class B  (no auto-title, ClassB.h)  }
-   }
-

We’ll get rid of the nested group because it doesn’t make sense for our example.  Run Natural Docs, open up the menu file again and take a look.

File: Globals  (Globals.h)
-
-Group: Classes  {
-
-   File: Class A  (no auto-title, ClassA.h)
-   File: Class B  (no auto-title, ClassB.h)
-   }  # Group: Classes
-

Natural Docs reformatted it.  When you’re organizing the menu, you don’t have to worry about the indentation or otherwise keeping it neat.  The file is reformatted every time it changes, so you can make quick and dirty edits and Natural Docs will keep it readable.

Besides breaking up long lists, groups also serve another purpose.  Clicking on them will make it expand and collapse.  Go ahead and try it in the examples above.  When the menu gets too long its groups will start being collapsed by default, allowing easier navigation on large projects where it would just be impractical to show everything at once.

Indexes and Search

Natural Docs will automatically determine what indexes your project needs and add them to the menu.  Anything indexed will also be used for the search feature.  The entries will look like this:

Group: Index {
-
-   Index: Everything
-   Class Index: Classes
-   Function Index: Functions
-   }  # Group: Index
-

Like the file entries we saw before, you can rename them by editing the title and reorder them by cutting and pasting.  However, if you decide you don’t want a particular index to be generated, just delete its entry and it will go away.  Just like before, Natural Docs will detect this and add something new:

Don't Index: Functions
-

As with no auto-title, Natural Docs adds this automatically to make sure it doesn’t later undo your changes.

Automatic Changes

Natural Docs tries to manage the menu on its own as much as possible so you don’t have to worry about it.  This is just a peek into some of the things it does so you know what to expect.

You already saw that by default Natural Docs tries to guess what title should be for each file.  If you leave it this way, Natural Docs will always update the menu for you if the file’s content changes significantly enough to change its guess, such as if you rename the first class defined in it.  If you’d like to take advantage of this to define the menu title in each source file instead of in the menu itself, add a “Title: [title]” comment to the top of the file.

When you add and delete source files, Natural Docs will automatically add and remove them from the menu file.  When adding one it will look for the best group to put it in by directory.  If your grouping mirrors the source tree somewhat, this will be a lot more accurate.  Also, if the group it’s putting it in is alphabetized, Natural Docs will put it in the correct place to maintain that alphabetization.  In fact, even if an existing file’s automatic title changes, it will change it’s position to make sure a previously alphabetized group stays that way.

There are exceptions in alphabetization for the indexes.  If a group only contains indexes, it can be the last item on the menu or in its parent group without making it count as unsorted.  Also, within groups that only contain indexes, the general index can be first, also without making the group count as unsorted.

Finally, if Natural Docs adds some files to a group that causes it to become too long, it will attempt to sub-group it based on directory.  However, it will only do this when its adding files on its own, so you don’t have to worry about it constantly messing up your groups.  Since new files aren’t added to a project that often, if you change the menu manually it should stay that way for quite some time.

Extras

There’s more you can do with the menu than just renaming and reorganizing its entries.  Natural Docs has a few extras you can add to it as well.

Title and Subtitle

You can add a title and subtitle to your menu.

Title: My Project
-SubTitle: Something That Does Something
-
-File: Globals  (Globals.h)
-Group: Classes
-   File: Class A  (no auto-title, ClassA.h)
-   File: Class B  (no auto-title, ClassB.h)
-
My Project
Something That Does Something

In addition to adding the title to the menu, the Title tag will also change the HTML page titles from “Class A” to “Class A - My Project”, making bookmarks clearer.

Text and Web Links

You can also add arbitrary text and web links to your menu.

File: Globals  (Globals.h)
-Group: Classes  {
-   Text: I couldn't think of good names for these classes.
-   File: Class A  (no auto-title, ClassA.h)
-   File: Class B  (no auto-title, ClassB.h)
-   }
-Link: Built with Natural Docs  (http://www.naturaldocs.org)
-
Classes

Even though comments use the # character, adding an anchor to a link (such as “http://www.website.com/page.html#anchor”) will still work.

Footers

Finally, you can add a footer to all your pages, such as a copyright notice.  Natural Docs will change any (c)’s it finds into real copyright symbols.

Footer: Copyright (C) 2010 Me
-
Copyright © 2010 Me  ·  Generated by Natural Docs

You can also add a timestamp in any format you want.  The tokens you can use in building it are:

mOne or two digit month.January is “1”
mmAlways two digit month.January is “01”
monShort month word.January is “Jan”
monthLong month word.January is “January”
dOne or two digit day.1 is “1”
ddAlways two digit day.1 is “01”
dayDay with letter extension.1 is “1st”
yyTwo digit year.2010 is “10”
yyyyFour digit year.2010 is “2010”
yearFour digit year.2010 is “2010”

Everything else appears literally, so we can add:

Timestamp: Updated month day, year
-

and get:

Copyright © 2010 Me  ·  Updated January 1st, 2010  ·  Generated by Natural Docs
Errors

If there’s ever an error in the menu file, Natural Docs will tell you when it’s run.  It also adds a comment for each one in the menu file itself so that you can search for them in a text editor.

# There is an error in this file.  Search for ERROR to find it.
-
-File: Globals  (Globals.h)
-Group: Classes  {
-# ERROR: Txet is not a valid keyword.
-   Txet: I couldn't think of good names for these classes.
-   File: Class A  (no auto-title, ClassA.h)
-   File: Class B  (no auto-title, ClassB.h)
-   }
-

Remember that Natural Docs reformats the menu file whenever it’s run, so you only need to correct the error.  Natural Docs will remove the error comments on its own.

Portability and Versioning Systems

If you only use one input directory, all the files in the menu will have relative paths.  However, if you have more Natural Docs will use the absolute path instead.

This is not a problem.  The menu file can still be shared between machines even if they don’t keep the source tree in the exact same location.  As long as you have the same layout within the source tree and point to the same base directories in the command line, Natural Docs will be able to convert the paths automatically for the new machine.

However, if you’re putting the menu file in a versioning system like Subversion or SourceSafe, it might be very desirable to only have relative paths so anybody can check it in and only the real changes show.  In that case, instead of using multiple input directories, see if it’s possible to only have one input directory and use the -xi command line option to exclude the subdirectories you don’t want scanned.

That’s It!

And we’re done.  The syntax to do all of this is included in the menu file itself, so you don’t need to memorize everything.  You shouldn’t need to organize the menu very often, just after a lot of new files have been added and if you don’t like the default.

Note that if you’re using the non-framed HTML output format, changing the menu does require every output file to be updated.  However, Natural Docs has a special process just for this so it won’t take nearly as long as if it were rebuilding them all from scratch.  Still, if you’re working on a large project, it may be worth considering the framed HTML output format.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/output.html b/vendor/naturaldocs/Help/output.html deleted file mode 100644 index 7d1bcda9b..000000000 --- a/vendor/naturaldocs/Help/output.html +++ /dev/null @@ -1,84 +0,0 @@ - - -Output Formats - Natural Docs - - - -
Natural Docs
About
Language SupportOutput Formats
Output Formats

These are the output formats that are currently implemented in Natural Docs.

HTMLHTML output.  Each page is self-contained.  Linking to specific pages is easy, but every file has to be updated whenever the menu changes.
FramedHTMLHTML output based on frames.  The menu is updated quickly, but linking to individual pages is difficult and some people just plain hate frames.
HTML Compatibility

These are the browsers Natural Docs’ HTML output has been tested with.  All browsers will be able to view and navigate it, some of the older ones just may not be able to use advanced features like search correctly.

FireFoxTested with 1.0, 1.5, and 2.0.
Internet ExplorerTested with 6 and 7.
SafariTested with 2 and 3.  Search doesn’t work with unframed HTML in 2.
OperaTested with 7.0, 7.5, 8.0, 8.5, and 9.0.  Search doesn’t work with 7.0, and sometimes tooltips.
KonquerorTested with 3.5.5.  Search doesn’t work.
Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/running.html b/vendor/naturaldocs/Help/running.html deleted file mode 100644 index df186563c..000000000 --- a/vendor/naturaldocs/Help/running.html +++ /dev/null @@ -1,40 +0,0 @@ - - -Running Natural Docs - - - -
Natural Docs
Running Natural Docs
 
How and When

Probably the best way to run Natural Docs is as part of the build process.  This way every time you compile your code, your documentation is updated as well and you always have a current reference.  Natural Docs has a differential build process so it will not rebuild the entire set of documentation every time it’s run.

If you’d like to run it manually instead, you should determine the command line you need and save it as a shortcut, batch file, or script since you should be running it often and will rarely need to fiddle with the parameters.

Command Line
NaturalDocs -i [input (source) directory]
-            -o [output format] [output directory]
-            -p [project directory]
-            [options]
Required Parameters:
-i [dir]
--input [dir]
--source [dir]

The input (source) directory.  Natural Docs will build the documentation from the files in this directory and all its subdirectories.  You can specify it multiple times to include multiple directories.  See the list of supported programming languages.

-o [fmt] [dir]
--output [fmt] [dir]

The output format and directory.  This can also be specified multiple times, so you can build the documentation in multiple formats in a single run.  The supported formats are HTML and FramedHTML.

-p [dir]
--project [dir]

The project directory.  Natural Docs needs a place to store configuration and data files for each project it’s run on, so this is where it will put them.  No two projects should share the same directory.

Optional Parameters:
-xi [dir]
--exclude-input [dir]
--exclude-source [dir]

Excludes a subdirectory from being scanned.  The output and project directories are automatically excluded.

-img [dir]
--images [dir]

Adds a directory to search for image files when using (see [file]).

-s [style] ([style] ...)
--style [style] ([style] ...)

Selects the CSS style for HTML output.  The default styles are Default, Small, and Roman.

You can use any CSS file in your project directory or Natural Docs’ Styles directory just by using its name without the .css extension.  If you include more than one, they will all be included in the HTML that order.

-r
--rebuild

Rebuilds everything from scratch.  All source files will be rescanned and all output files will be rebuilt

-ro
--rebuild-output

Rebuilds all output files from scratch.

-t [len]
--tab-length [len]

Sets the number of spaces tabs should be expanded to.  This only needs to be set if you use tabs in example code or text diagrams.  The default is 4.

-hl [opt]
--highlight [opt]

Sets the syntax highlighting option used in the output.  Off turns off all syntax highlighting.  Code applies it to prototypes and (start code) segmentsAll applies it to prototypes, (start code) segments, and lines prefixed with >, |, or :.  The default is Code.

-do
--documented-only

Tells Natural Docs to only include what you explicitly document in the output, and not to find undocumented classes, functions, and variables.  This option is only relevant if you have full language support.

-oft
--only-file-titles

Tells Natural Docs to only use the file name for its menu and page titles.  It won’t try to determine one from the contents of the file.

-nag
--no-auto-group

Tells Natural Docs to not automatically create group topics if you don’t add them yourself.

-q
--quiet

Suppresses all non-error output.

-?
-h
--help

Prints the syntax reference.

No Longer Supported:
These parameters were part of previous Natural Docs releases, but are no longer supported.
-ho
--headers-only

This used to check only the headers and not the source files in C and C++.  Edit Languages.txt instead and add the line “Ignore Extensions: c cpp cxx”.

-s Custom
--style Custom

This used to tell Natural Docs not to alter the CSS file in the output directory.  Copy your custom CSS file to your project directory and use it with -s instead.

-ag [level]
--auto-group [level]

This used to set the level of auto-grouping between Full, Basic, and None.  The algorithm was improved so there’s no need for separate levels anymore.  You can use -nag if you want to turn it off completely.

-cs [charset]
--charset [charset]
--character-set [charset]

This used to set the character set property of the generated HTML.  Natural Docs now always uses UTF-8.

Examples
NaturalDocs -i C:\My Project\Source
-            -o FramedHTML C:\My Project\Docs
-            -p C:\My Project\Natural Docs
-
-NaturalDocs -i /project/src1
-            -i /project/src2
-            -o HTML /project/doc
-            -p /project/nd
-            -s Small -t 3
Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/styles.css b/vendor/naturaldocs/Help/styles.css deleted file mode 100644 index 905f0140a..000000000 --- a/vendor/naturaldocs/Help/styles.css +++ /dev/null @@ -1,292 +0,0 @@ - -body { - background: #FFFFFF; - margin: 18px 15px 25px 15px !important; - } - -body, -td, -li { - font: 9pt Verdana, sans-serif; - } -p, -td, -li { - line-height: 150%; - } - -p { - text-indent: 4ex; - margin: 0; - } - -td { - vertical-align: top; - } - -a:link, -a:visited { color: #900000; text-decoration: none } -a:hover { color: #900000; text-decoration: underline } -a:active { color: #FF0000; text-decoration: underline } - -.Opera wbr:after { - content: "\00200B"; - } - -.NoIndent p - { text-indent: 0; } - -img { - border: none; - } - -.First { - margin-top: 0 !important; - padding-top: 0 !important; - } -.Last { - margin-bottom: 0 !important; - padding-bottom: 0 !important; - } - -.PageTable { - max-width: 950px; - margin-left: auto; - margin-right: auto; - } - -.Header { - background-image: URL("images/header/background.png"); - background-color: #7070C0; - } -.SideMenuTop { - background: URL("images/header/overmenubg.png"); - } -.SideMenuBottom { - vertical-align: bottom; - } -.BodyTop { - background: URL("images/header/overbodybg.png"); - text-align: right; - } -.BodyBottom { - vertical-align: bottom; - text-align: right; - font: italic 8pt Georgia, serif; - color: #C0C0C0; - padding-right: 10px; - } - -.Body { - padding: 15px 20px 0 25px; - } - - - - -pre, code, .Example { - font: 10pt Courier New, Courier, monospace; - color: #606060; - } -a code { - color: #C06060; - } -.Example { - overflow: auto; - } - -.PageTitle { - font: bold italic 21pt Trebuchet MS, sans-serif; letter-spacing: .5ex; text-transform: uppercase; - margin-bottom: .5em } -.IE .PageTitle { - letter-spacing: 1.25ex; - } - - -.Topic { - margin-bottom: 2em } - - -.TopicTitle { - font: 18pt Georgia, serif; - border-width: 0 0 1px 0; border-style: solid; border-color: #C0C0C0; - margin-bottom: .5em - } -#SubscribeTopicTitle { - margin-bottom: 0; - } -.Subscribe { - font-size: 8pt; - margin-bottom: 2em; - color: #909090; - } - -.Subscribe a:link, -.Subscribe a:hover, -.Subscribe a:visited { - color: #909090 } - - -.SubTopic { - font-weight: bold; font-size: 10pt; - padding-top: 1.5em; padding-bottom: .5em; - } - -.MiniTopic { - font-weight: bold; - padding-top: 1em; padding-bottom: 0em; - } - - -.TOC { - text-align: center; - font: 8pt Verdana, sans-serif; - text-transform: uppercase; - background-color: #F8F8F8; - border-width: 1px; border-style: solid; border-color: #C0C0C0; - margin-bottom: 1.5em; - padding: 2px 0; - -moz-border-radius: 14px; - } - - .TOC a { - margin: 0 0.75ex; } - - .TOC a:link, - .TOC a:hover, - .TOC a:visited { - color: #404040 } - - -.Example { - background-color: #FDFDFD; - padding: 15px; - border: 1px solid #C0C0C0; - border-width: 1px 1px 1px 6px; - border-style: dashed dashed dashed solid; - color: #707070; - margin: 15px 5ex; - } - - -.LastUpdated { - font: italic 10pt Georgia, serif; - color: #A0A0A0; - margin: 1em 0; - } - - - -.FAQSummary { - margin-bottom: 3em; - } -.FAQSummaryGroup { - font: bold 12pt Georgia, serif; - margin: 1em 0 .25em 0; - } -.FAQGroup { - font: 18pt Georgia, serif; - border-bottom: 1px solid #C0C0C0; - margin-bottom: .5em; - margin-top: 1.5em; - } -.FAQSummaryEntry:link, -.FAQSummaryEntry:visited, -.FAQSummaryEntry:hover, -.FAQSummaryEntry:active { - } - -.FAQEntry { - margin-bottom: 3em; - } -.FAQEntryTitle { - font: bold 12pt Georgia, serif; - margin-bottom: .5em; - } -.FAQEntry .SubTopic { - font: italic 9pt Verdana, sans-serif; - } - - - -.SideMenu { - width: 175px; /* 195 minus padding */ - text-align: center; - padding-top: 15px; - background-color: #F0F0F0; - } -.SideMenuBottom { - background-color: #F0F0F0; - } -.SideMenuBottomRight { - text-align: right; - } - -.SideMenuSection { - margin-bottom: 3em; - } - -.SideMenuTitle { - padding-bottom: 3px; - border-bottom: 1px solid #D0D0D0; - } - -.SideMenuBody { - padding-top: 1em; - background: URL("images/menu/background.png") repeat-x; - } - -.SideMenuEntry { - font: 8pt Verdana, sans-serif; - margin: 0 10px 1em 10px; - display: block; - } - -a.SideMenuEntry:link, -a.SideMenuEntry:visited { - color: #000000; - padding: 1px 10px 2px 9px; - } -a.SideMenuEntry:hover, -a.SideMenuEntry:active, -#SelectedSideMenuEntry { - border-style: solid; - border-width: 1px 2px 2px 1px; - padding: 0 8px; - text-decoration: none; - -moz-border-radius: 10px; - } -a.SideMenuEntry:hover, -a.SideMenuEntry:active { - color: #000000; - border-color: #C8C8C8; - background-color: #F8F8F8; - } -#SelectedSideMenuEntry { - color: #000000; - border-color: #606060; - background-color: #FFFFFF; - } - -.SideMenuSourceForge { - padding-top: 2.5em; - } - - - -/* Needed by the release notes for 1.3 */ - -.ExPrototype { - font: 10pt Courier New, Courier, monospace; - padding: 5px 3ex; - background-color: #F4F4F4; - border: 1px solid #D0D0D0; - margin: 1em 0; - } -.ExPrototype td { - font: 10pt Courier New, Courier, monospace; - } -.ExPrototype .Fade { - color: #8F8F8F; - } - diff --git a/vendor/naturaldocs/Help/styles.html b/vendor/naturaldocs/Help/styles.html deleted file mode 100644 index 808341d1c..000000000 --- a/vendor/naturaldocs/Help/styles.html +++ /dev/null @@ -1,52 +0,0 @@ - - -CSS Styles - Natural Docs - - - -
Natural Docs
CSS Styles
Default Styles

These are the styles that come with Natural Docs.  They all follow the same color scheme and general layout; the choices are more so that you can choose the style of text you want.

You choose which style you want for your project by adding “-s [style name]” to the command line.

DefaultThis is the default style that Natural Docs uses.  Most of the text is 10pt Verdana.
SmallSmaller fonts than Default with most of the text using 8pt Verdana.  Some people like the small fonts because you can fit more on the screen at once.  However, some people hate them and find them hard to read.
RomanSerif fonts with most of the text using 12pt Roman.  Some people prefer Roman fonts, usually those that have decent anti-aliasing displays like Mac OS X or Windows XP with ClearType.
Customizing

There are two ways to customize the CSS files.  One is to build your own file from scratch, and the other is to make a touch-up file that gets applied after one of the default styles.  Either way you want to create your own CSS file in your project directory (the one you use with -p) or if you plan on sharing it between many projects, in Natural Docs’ Styles directory.

To use a custom file, no matter where you put it, you just use it with -s without the CSS extension.  So if you made Red.css, you use “-s Red”.  If you made a touch-up file instead, you use it after one of the default styles, such as with “-s Default Red”.  If you’re so inclined, you can string as many touch-up files together as you want or use one of your own as a base.

The CSS Guide documents the page structure and CSS styles of Natural Docs’ output.  Always remember to check its revisions section every time you upgrade Natural Docs because it may change between releases.

Common Customizations
Web-Style Paragraphs

Natural Docs defaults to print-style paragraphs like the one you are reading.  Each one is indented and there are no blank lines between them.  To switch to web-style paragraphs, which have blank lines and no indents, add this to your custom CSS file:

p {
-   text-indent: 0;
-   margin-bottom: 1em;
-   }
-
Prototype Colors

If you’ve added a custom topic type and have it finding prototypes for you, you may want to have them appear in a different color than the default black and white.  Add this to your custom CSS file:

.C[type] .Prototype {
-   background-color: [color];
-   border-color: [color];
-   }
-

Replace [type] with the name of your topic type, minus any symbols and spaces.  So if you added a type “Sound Effect”, you would apply the style to “.CSoundEffect .Prototype”.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Help/troubleshooting.html b/vendor/naturaldocs/Help/troubleshooting.html deleted file mode 100644 index 3cc089e80..000000000 --- a/vendor/naturaldocs/Help/troubleshooting.html +++ /dev/null @@ -1,18 +0,0 @@ - - -Troubleshooting - Natural Docs - - - -
Natural Docs
Troubleshooting
Natural Docs Issues
I don’t get any documentation
Is it recognizing your source files?

If Natural Docs has never said “Parsing n files...” when you run it, or n was way too low a number, it is not finding your source files.

If it has, try this test.  Run Natural Docs once.  Edit one of your source files and save it.  Run Natural Docs again.  If it doesn’t say “Parsing 1 file...” it is not recognizing your file.

No, it’s not recognizing them

The most likely scenario is that Natural Docs doesn’t associate the file extension you’re using with your programming language.  Open Languages.txt in Natural Docs’ Config directory and find your language.  Underneath it you should see a line that says something like “Extensions: c cpp cxx h hpp hxx”.  Add the file extensions you use and try again.

If you use extensionless or .cgi files, do the same thing but instead look for a line that says something like “Shebang Strings: tclsh wish expect”.  If it is not there, you may need to add it yourself.  Edit it to include whatever appears in your shebang (#!) line that would say this file belongs to your language.

Otherwise just make sure you included the directory or one of its parents with -i on the command line.

Yes, it’s recognizing them

First note that unless you have full language support, Natural Docs will only include what you write for it.  It will not be able to scan your code and pick out all the classes and functions on its own.

If the problem is with text files, the most likely scenario is that you’re not including topic lines.  Like in comments, only things that appear under “keyword: name” lines count as Natural Docs content.

If it’s still not working, note that Natural Docs can only read ASCII or UTF-8 encoded files that use Windows (CR+LF) or Unix (LF) line endings.  If you use UTF-16 encoded files and/or classic Mac (CR) line endings you need to convert the files.  These are due to limitations in Perl.  Natural Docs 2.0 won’t have these problems.

Some of my topics don’t show up
  • Check the list of keywords to see if the one you’re using is there and you spelled it correctly.  Note that the web page only has the default set of keywords.  You may need to check Topics.txt in Natural Docs’ Config directory and your project directory if you’ve edited them
  • If the topics appear in code, make sure that the comments are alone on a line.  You cannot put Natural Docs content on the same line as code.  This includes having anything appear after a closing block comment symbol.
  • Make sure that if you have more than one topic in a comment, there is a blank line above the topic line.
  • If you have text boxes or lines, make sure they are completely unbroken.  You can also try removing them completely.
  • If the topics appear in a text file, make sure you included topic lines.  Like in comments, only things that appear after “keyword: name” lines count as Natural Docs content.  You could just add a Title: line to the top of the file to fix this.
Some of my topics aren’t formatting correctly
  • Headings must have a blank line above them.
  • Lines directly after bullet or definition lines are part of the previous bullet or definition, even if it’s not indented.  Skip a line first to do something else
  • If you’re getting symbols scattered throughout your text, make sure any text boxes or lines are completely unbroken.  You can also try removing them altogether.
  • If your example source code is getting mangled, remember to use the example code syntax.
  • If a line’s becoming a heading but shouldn’t, either get rid of the colon at the end or break it into two lines so the colon appears on the second line
  • If a line’s becoming a definition but shouldn’t, either get rid of the space-dash-space (use two dashes or remove one of the spaces) or break it into two lines so that the space-dash-space is on the second line.

I realize the last two aren’t great.  If you have any ideas as to how to reliably detect these kinds of false positives, e-mail me.

I’m not getting prototypes
  • The topic must appear directly above the thing it’s documenting.
  • Topics documented in lists will not get prototypes, even if the list break apart in the output.
  • The topic name must be present in the prototype somewhere.  Make sure the topic title has the same case as in the prototype and that it’s not misspelled.  This applies even if your language isn’t case sensitive.
  • If you’re documenting something with a new topic type you added to Topics.txt, you must also edit Languages.txt to tell it how to detect prototypes for that type.
My links aren’t working

If your links appear in the output as “<text>” instead of being converted to links, do the following:

  • Make sure the target appears in the output.  The easiest way is to see if it appears in the Everything index.
  • Make sure the link is spelled correctly and has the same case as what you’re linking to.  This applies even if your language isn’t case sensitive.
  • If the topic your link appears in and the link target are not in the same class (or are not both global) make sure you include the class in the link with class.target, class::target, or class->target.  You can check which classes topics appear in with the Everything index.  If your topics are appearing in the wrong classes, fix the documentation remembering the topic scoping rules.
Windows Issues
I get the message “Bad command or file name” or “perl is not recognized”

What’s happening is that NaturalDocs.bat can’t find Perl.  You need Perl installed to run Natural Docs, so if you haven’t done so already, you can download and install ActiveState’s ActivePerl for free.

If you already have Perl, it’s bin directory is either not in your path or the path isn’t being used by whatever you’re running it from, which happens on some IDEs.  Edit NaturalDocs.bat and on the line that says “perl NaturalDocs %NaturalDocsParams%”, change perl to be the full path to perl.exe, such as “C:\perl\bin\perl.exe”.  You need to include the quotes if there are spaces in the path.

I get the message “Can’t open perl script NaturalDocs”

What’s happening is that Perl can’t find the Natural Docs script file.  This happens when the working directory or “start in” folder isn’t the directory Natural Docs was installed to.  If changing that doesn’t work, or if you don’t have the option to set that, edit NaturalDocs.bat and find the line that says “perl NaturalDocs %NaturalDocsParams%”.  Change NaturalDocs to include the full path Natural Docs was installed to, such as “C:\Program Files\Natural Docs\NaturalDocs”.  You need to include the quotes if there are spaces in the path.

Copyright © 2003-2010 Greg Valure
\ No newline at end of file diff --git a/vendor/naturaldocs/Info/CSSGuide.txt b/vendor/naturaldocs/Info/CSSGuide.txt deleted file mode 100644 index 2496b0bfc..000000000 --- a/vendor/naturaldocs/Info/CSSGuide.txt +++ /dev/null @@ -1,947 +0,0 @@ - - Architecture: CSS Structure -_______________________________________________________________________________ - -It's important to understand the internal HTML file structure and styles in order to design your own CSS style for Natural Docs. If -you're content with the default styles, there's no need to read this document. - -Topic: Diagram Conventions - - The diagrams are designed for clarity. In the actual HTML, you'd obviously see "
" - instead of "
". - - - A tag with just a style, for example "CTitle", means an unspecified element with that class. Style with .CTitle. - - A tag that includes a #, for example "#Menu", means an unspecified element with that ID. Style with #Menu. - - A tag that includes a HTML element as well, for example "table CDescriptionList", means it will always be that element. You - can style with either .CDescriptionList or table.CDescriptionList. - - A tag that has multiple classes or has an "and" in it, for example "CType and CTopic", means that both styles will apply to the - same element. You can style it with .CType.CTopic, noting that the space between them must be omitted. - - A tag that has an "or" in it, for example "#Content or #Index", is just shorthand for either of those elements. The diagram - applies to both of them but only one will actually appear at a time in the output. - - A tag or style with a question mark means that tag or style will only be there in certain situations. - - -Topic: Page Structure -_______________________________________________________________________________ - - The body tag is used to distinguish between the types of pages. - - Unframed Content/Index Page: - - (start diagram) - - - [browser styles] - - <#Content or #Index> - Content or Index - - - <#Menu> - Menu - - - <#Footer> - Footer - - - [/browser styles] - - - (end diagram) - - - Unframed Search Results Popup Page: - - (start diagram) - - - [browser styles] - - <#Index> - Index - - - [browser styles] - - - (end diagram) - - - Framed Menu Page: - - (start diagram) - - - [browser styles] - - <#Menu> - Menu - - - <#Footer> - Footer - - - [browser styles] - - - (end diagram) - - - Framed Content/Index/SearchResults Page: - - (start diagram) - - - [browser styles] - - <#Content or #Index> - Content or Index - - - [browser styles] - - - (end diagram) - - -Styles: Page Styles - - ContentPage - An unframed content page. - IndexPage - An unframed index page. - PopupSearchResultsPage - A search results page for use in a popup iframe. - - FramedContentPage - A framed content page. - FramedIndexPage - A framed index page. - FramedSearchResultsPage - A framed search results page. - - #Footer - The page footer. Will be in a framed menu page or on its own in a non-framed page. - - See Also: - - - <#Content> - - <#Menu> - - <#Index> - - <#Footer> - - - - -Styles: Browser Styles -_______________________________________________________________________________ - - - Natural Docs pages include JavaScript to detect which browser the user is running and apply styles so that you can work - around browser quirks right in the CSS file. - - The browser type and version styles will be applied immediately after the body tag. However, neither are guaranteed to be - there; the user may have JavaScript turned off or be using a browser that isn't detected. These styles should only be used to - correct minor flaws and should not be heavily relied on. - - > - > ? - > ? - > - > Page Content - > - > ? - > ? - > - - For example, if a 's style is giving you problems in Internet Explorer 6, override it with .IE6 .CTopic. If a 's - style gives you a problem in Opera 7 but only in frames, override it with .Framed.Opera7 .MTitle. - - Browser Types: - - If the browser is not one of the types below, neither this nor the browser version will be present. There's the possibility that - some obscure browser will appear as one of the others by spoofing, but the most prominent of these, Opera, Konqueror, and - Safari, are taken care of. - - IE - Internet Explorer - Firefox - Firefox and anything else based on the Gecko rendering engine. - Opera - Opera - Safari - Safari - Konqueror - Konqueror and anything else based on the KHTML rendering engine except Safari. - - Browser Versions: - - If the browser is not one of the versions below, this style will not be present. The browser type still may be. - - IE6 - Internet Explorer 6.x. - IE7 - Internet Explorer 7.x. - - Firefox1 - Firefox 1.0.x and anything else based on Gecko 1.7.x. - Firefox15 - Firefox 1.5.x and anything else based on Gecko 1.8.0.x. - Firefox2 - Firefox 2.0.x and anything else based on Gecko 1.8.1.x. - - Opera7 - Opera 7.x. - Opera8 - Opera 8.x. - Opera9 - Opera 9.x. - - Safari2 - Safari 2.x. - Safari3 - Safari 3.x. - - Notes: - - Why not apply them to the body tag itself? The JavaScript is easy enough and everything supports multiple classes, right? - Because IE 6 doesn't support multiple selectors so I wouldn't be able to combine browser and page styles. - .Opera.ContentPage will apply to all ContentPages in IE because it treats it as if only the last class is there. - - - - -Topic: Content Structure -_______________________________________________________________________________ - - - All the topics of a given file is contained in a <#Content>. All other content styles are prefixed with a C. - - Surrounding each piece of content is a and its type; for example, CFunction for a function. Inside that are the - and if necessary, . Inside are analogues to all the top-level tags:

,

, etc. - - In addition to the top-level tags, you also have prototypes, class hierarchies, and summaries which are - described in their own sections. - - (start diagram) - - <#Content> - - - - - - Topic title - - - - - [Class Hierarchy] - - [Prototype] - - - Heading - - -

- Paragraph -

- -
-                        Code or text diagram
-                    
- -
    -
  • - Bullet item -
  • -
- - ? - Caption - ? - - - - text - - - - - - - -
- Entry - - Description -
- - [Summary] - - - - - - - - - (end diagram) - - Take advantange of the CSS inheritance model. For example, you can style all titles via .CTitle, and you can style - specific titles with .CType .CTitle. - - -Styles: Content Styles - - #Content - Parent element containing all topics. - - CTopic - An individual topic. - - CTitle - The title of a topic. - CBody - The body of a topic. May not exist. - CHeading - Surrounds a heading. - CImageCaption - Surrounds an image caption. - CImageLink - Surrounds a link to an image. - - CDescriptionList - A description list, which is the type of list you're reading right now. Is implemented with a table. - CDLEntry - A description list entry, which is the left side. - CDLDescription - A description list description, which is the right side. - - #MainTopic - The ID given to the main topic, which is the first in the file. It is applied to the . - - CType - A placeholder for all type-specific styles. The actual styles will be C followed by the alphanumeric-only topic type name. - So the CType of a "PL/SQL Function" topic will actually be CPLSQLFunction. - - - - -Topic: Menu Structure -_______________________________________________________________________________ - - - Everything is enclosed in a <#Menu>. All other menu styles are prefixed with an M. - - The title is an and will always be at the beginning of the menu if it exists. If a subtitle exists as well, it will appear - as an inside . Subtitles aren't allowed without titles. Most other entries in the menu are contained in - . Here's the diagram: - - (start diagram) - - <#Menu> - - - Menu title - - - Menu sub title - - - - - - - File - - - - - - File - - - - - - Text - - - - - - Link - - - - - - Group - - - (MEntries) - - - - - - <#MSearchPanel and MSearchPanelActive/Inactive> - - - - - - - (if in unframed HTML) - <#MSearchResultsWindow> - - - - - - - - (end) - - The or entry that's currently selected will have the <#MSelected> ID, so you can reference it in CSS via - .MFile#MSelected. - - The search panel is has its own ID, <#MSearchPanel>, but also has one of the classes or - depending on whether any of the controls are selected or the results window is open. - <#MSearchResultsWindow> is separate because it may be floating. - - -Styles: Menu Styles - - #Menu - Parent element containing the entire menu. - - MTitle - The title of the menu. - MSubTitle - The subtitle of the menu. Will appear within . - - MFile - A file entry. - MGroup - A group entry. - MGroupContent - A container for a content. - MText - A plain text entry. - MLink - An external link entry. - MIndex - An index entry. - - #MSelected - The ID of the currently selected or . - - MType - , , , , or . - - #MSearchPanel - Contains all the search controls. - MSearchPanelActive - Applied to <#MSearchPanel> when any of the controls are selected or the results window is open. - MSearchPanelInactive - Applied to <#MSearchPanel> when not in use. - - #MSearchField - The text input field of the search panel. - #MSearchType - The drop down type selector of the search panel. - #MSearchEverything - The <#MSearchType> option for the Everything index. - - #MSearchResultsWindow - Contains all the search results elements. - #MSearchResults - Contains the iframe that will hold the results. - #MSearchRseultsWindowClose - The link to manually close the search results window. - - - - -Topic: Class Hierarchy Structure -_______________________________________________________________________________ - - - Everything is contained in a single . Each entry is surrounded by its type, such as , and the - generic . Depending on the context, entries may be surrounded by one or more . - - (start diagram) - - - - ? - - - - - ? - Entry - - - - - - ? - - - - (end diagram) - - -Styles: Class Hierarchy Styles - - ClassHierarchy - The topmost style containing everything. - - CHEntry - A generic class entry. - - CHParent - The style for a parent class. - CHCurrent - The style for the current class, which is the one the hierarchy is generated for. - CHChild - The style for a child class. - CHChildNote - The style for when a child is added that just shows how many other children were omitted. - - CHIndent - A style used to indent a level. - - CHType - , , , or . - - - - -Topic: Summary Structure -_______________________________________________________________________________ - - - Everything is enclosed in a single . All the other summary styles are prefixed with an S. - - holds the actual word "Summary" and and hold the content. exists because different - browsers apply table padding attributes in different ways. exists as a class to separate the main table from any other - tables that may be necessary. Here's a diagram: - - > - > - > - > Title - > - > - > - > - > ... - >
- >
- > - >
- - On to the table content. - - > - > - > - > Entry - > - > - > - > - > Description - > - > - > - - exist to allow indenting. They're necessary because implementing it as nested tables, while structurally cleaner, - won't allow the desciptions to line up on the right throughout the entire summary. will be applied on almost every - other row to allow for tinting to improve readability. - - Use the power of CSS's inheritance rules to specify styles. For example, to set the style of a group entry, apply it to - .SGroup .SEntry. However, you could also apply a style to both the group's entry and description by applying the - style to .SGroup td. Or, you could apply a style to all the entries by applying it to .SEntry. And so on. - - -Styles: Summary Styles - - Summary - The topmost style containing the entire summary. - - STitle - Contains the summary title, which is the part that actually says "Summary". - - SBorder - Surrounds , since some browsers can't do table padding right. A hack, I know. - STable - The actual summary table. This class separates it from other layout tables that may appear. - - SMarked - A class applied to rows that should have a slightly different color than the rest of the rows to make them easier to - read. - - SEntry - The entry (left) side of the table. - SDescription - The description (right) side of the table. - - SIndent# - Surrounding entries and descriptions that are part of a group and need to be indented. Actual styles will be - SIndent1, SIndent2, etc. - - SType - A placeholder for all topic-specific styles. The actual styles will be S followed by the alphanumeric-only topic type name. - So the SType of a "PL/SQL Function" topic will actually be SPLSQLFunction. - - - - -Topic: Prototype Structure -_______________________________________________________________________________ - - - Everything is enclosed in a . All other styles are prefixed with a P. - - Parameter Type First Style: - - For prototypes such as - > void Function (unsigned int* a, int b = 0) - where the types come first. - - (start diagram) - - - - - - - - - - - - - - - - - - (repeated as necessary) - - - -
- "void Function (" - - "unsigned" - - "int" - - "*" - - "a", "b" - - "=" - - "0" - - ")" -
- - (end diagram) - - - Parameter Name First Style: - - For prototypes such as - > function Function (a, b: int; c: int := 0) - where the parameters come first. - - (start diagram) - - - - - - - - - - - - - - (repeated as necessary) - - - -
- "function Function (" - - "a,", "b:", "c:" - - "int" - - ":=" - - "0" - - ")" -
- - (end diagram) - - - Note that any section may not exist. For example, there will be no cells generated if none of the parameters - have it. - - -Styles: Prototype Styles - - Prototype - The style encompassing the entire prototype. - - PBeforeParameters - The part of the prototype that comes before the parameters. - PAfterParameters - The part of the prototype that comes after the parameters. - - PType - The parameter type. - PTypePrefix - The prefix of a parameter type. - PParameter - The parameter name. - PParameterPrefix - The prefix of a parameter name. - PDefaultValue - The default value expression for a parameter. - PDefaultValuePrefix - The prefix of the default value expression. - - - - -Topic: Link Structure -_______________________________________________________________________________ - - - All links to symbols have a type style prefixed with L. The only exceptions are summary entries; summary descriptions use - them as well. - - > - > Link - > - - You can use this to make links to different symbols appear in different styles. For example, making .LClass bold will make all - links to classes bold, except when appearing in summary entries. You can combine this with other styles to be even more - specific. For example, you can apply a style to function links appearing in summary descriptions with .SDescription .LFunction. - -Styles: Link Styles - - LType - A placeholder for all topic-specific styles. The actual styles will be L followed by the alphanumeric-only topic type name. - So the LType of a "PL/SQL Function" topic will actually be LPLSQLFunction. - - - -Topic: Index Structure -_______________________________________________________________________________ - - - Everything is enclosed in an <#Index>. Combine with and to distinguish between output formats. All - other index styles are prefixed with an I. - - (start diagram) - - <#Index> - - - Page Title - - - - A - B - C ... - - - - - - Heading (A, B, etc.) - - - - - - - ... - -
- Prefix, if any - - Entry -
- - - - (end diagram) - - Every index entry, including headings, are rows in a table. The first column of a non-heading are so that - the non-prefix portions align correctly. The other column are , of which there are multiple formats, described below. - - (start diagram) - - - Symbol - , - - Class - - - - Symbol - - - - Class - - ... - - - - Symbol - - - - Class - - - - File - - ... - - ... - - - (end diagram) - - Each part of the entry is surrounded by its type, which may or may not be a link. If an entry has more than one defining class - or file, they're broken out into . - - It's called instead of because class entries are . are only used when the symbol - has a class. If the symbol _is_ a class, the symbol is global. - - -Styles: Index Styles - - #Index - Parent element for the entire index. - - IPageTitle - The page title. - INavigationBar - The navigation bar. - - IHeading - An index heading, such as the letter for the group. - - IEntry - An entry in the index. - ISymbolPrefix - The stripped prefix of the entry. - ISymbol - The entry symbol. - IParent - The entry parent class. If the entry _is_ a class, this isn't defined because classes are global and don't have parent - classes. This is why it's called IParent instead of IClass; hopefully it's less confusing. - IFile - The file the entry is defined in. - - ISubIndex - The surrounding block if an entry needs to be broken out into a sub-index. - - #IFirstHeading - The ID of the first to appear in the file. - - #IFirstSymbolPrefix - The ID for the first to appear under an . - #ILastSymbolPrefix - The ID for the last to appear under an . - #IOnlySymbolPrefix - The ID if there is only one for an . - - - -Topic: Search Results Structure -_______________________________________________________________________________ - - - The search results use virtually the same structure and styles as the indexes, except that <#SearchResults> replaces - <#Index>, there's a new style, and there are a few additional blocks. - - Visibility: - - Visibility is *very* important to making the search work correctly. JavaScript will handle most of it, but your CSS needs to - abide by these rules. - - - sections are visible by default. - - sections are *not* visible by default. They must use display: none. - - should be display: none when under <#SearchResults>. - - -Styles: Search Results Styles - - #SearchResults - Parent element for the entire page. - SRStatus - Status message. Must be visible by default. - SRResult - A result. All you need to do for this class is set it to display: none. Nothing else should be set on it. - - - - -Topic: Tool Tip Structure -_______________________________________________________________________________ - - - Tool tips may appear anywhere in the page, mainly because it's assumed that they will use position: absolute and - visibility: hidden. - - The entire tool tip is found in a style, with a CType style inside it. CTypes are normally outside their elements, but - that would cause it to be partially visible in this case. We need to be the outermost style so its visibility and - position can be manipulated in JavaScript. - - Inside there's a and/or the description text. The description text has no special surrounding tags. - - > - > - > - > Prototype - > - > - > Summary text - > - > - -Styles: Tool Tip Styles - - CToolTip - Surrounds the entire tool tip. This *must* have position: absolute and visibility: hidden for the tool tip mechanism - to work. - - See also . - - -Styles: Miscellaneous Styles - - blockquote - This HTML element should surround anything that needs to be scrolled if it's too wide, like prototypes and text - diagrams. It's not a style because this makes it much easier to do the JavaScript necessary to get this working - in IE. - - -Group: History - -Topic: Revisions -_______________________________________________________________________________ - - - How the page structure has changed throughout the various releases. - - 1.4: - - - Replaced UnframedPage with and . - - Added <#Menu>, <#Content>, <#Footer>, and <#Index>. They were previously shown in the diagrams as classes but did - not actually appear in the generated output. - - Removed MenuSection, ContentSection, and IndexSection. Use things like ".ContentPage #Menu" instead. - - Removed tables from the unframed . Use CSS to position the elements instead. - - <#MainTopic> is applied to instead of . - - IE4, IE5, Opera5, Opera6, Netscape, and Netscape4 browser styles have been removed. , , - and have been added. Gecko has been replaced by , , , and . - KHTML has been replaced by , , , and . - - Removed redundant CParagraph, CCode, and CBulletList classes. Use with p, pre, and ul instead. - - Added and . - - Added <#MSearchPanel>, <#MSearchResultsWindow>, and all related styles. - - Added , , and . - - Removed SEntrySize. Apply the width to and instead. - - , , and were moved from the td and divs into the tr. - - Removed HB style. Now using wbr tag. - - 1.33: - - - Added . - - 1.32: - - - now surround elements that should scroll if they're too wide for the page. - - 1.3: - - - Removed CPrototype. See the replacement and . - - Removed SInGroup, SInClass, and SInSection in favor of more general . - - , , and are now completely determined by configuration files. - - , , and no longer have separate list types. A CFunctionList is now just a CFunction. - - Indexes are now done with tables. - - ISection was removed. - - are only used for the entry cell, not for each entry in an . - - Added , related IDs, and <#IFirstHeading>. - - Merged and into the same element. Must now be styled with .CType.CTopic (no space) while all - sub-elements will still be .CType .CElement (with space.) - - 1.21: - - - Added and TOPIC_PROPERTY_LIST styles, so they get corresponding , , and - . - - 1.2: - - - Added since 1.2 added class hierarchies. - - 1.16: - - - Changed the first topic from having a CMain type to having a normal type with a <#MainTopic> ID. - - 1.1: - - - Added . - - Renamed HiddenBreak to . - - Added , TOPIC_CONSTANT_LIST, , and TOPIC_TYPE_LIST types, so they get - corresponding , , and . - - 1.0: - - - The tags now appear arround the tags instead of vice versa. - - Added a tag to surround non- elements. - - now appears in tr's instead of td's, where it belonged in the first place. - - 0.95: - - - Added . - - Redid , replacing generic styles like Menu with page type styles like UnframedPage/MenuSection and - FramedMenuPage. - - 0.91: - - - Added and link styles, since 0.91 added URL and e-mail links. - - Added style, which is better than floating on its own. - - 0.9: - - - Added , since 0.9 added indexes. - diff --git a/vendor/naturaldocs/Info/File Parsing.txt b/vendor/naturaldocs/Info/File Parsing.txt deleted file mode 100644 index 10bd0e91b..000000000 --- a/vendor/naturaldocs/Info/File Parsing.txt +++ /dev/null @@ -1,83 +0,0 @@ - - Architecture: File Parsing - -#################################################################################### - - This is the architecture and code path for general file parsing. We pick it up at Parse()> because we're not interested in how the files are gathered and their languages determined for the purposes of this document. We are just interested in the process each individual file goes through when it's decided that it should be parsed. - - - - Stage: Preparation and Differentiation - _______________________________________________________________________________________________________ - - Parse()> can be called from one of two places, ParseForInformation()> and ParseForBuild()>, which correspond to the parsing and building phases of Natural Docs. There is no noteworthy work done in either of them before they call Parse(). - - - Stage: Basic File Processing - _______________________________________________________________________________________________________ - - The nitty-gritty file handling is no longer done in itself due to the introduction of full language support in 1.3, as it required two completely different code paths for full and basic language support. Instead it's handled in NaturalDocs::Languages::Base->ParseFile(), which is really a virtual function that leads to ParseFile()> for basic language support or a version appearing in a package derived from for full language support. - - The mechinations of how these functions work is for another document, but their responsibility is to feed all comments Natural Docs should be interested in back to the parser via OnComment()>. - - - Stage: Comment Processing - _______________________________________________________________________________________________________ - - OnComment()> receives the comment sans comment symbols, since that's language specific. All comment symbols are replaced by spaces in the text instead of removed so any indentation is properly preserved. Also passed is whether it's a JavaDoc styled comment, as that varies by language as well. - - OnComment() runs what it receives through CleanComment()> which normalizes the text by removing comment boxes and horizontal lines, expanding tabs, etc. - - - Stage: Comment Type Determination - _______________________________________________________________________________________________________ - - OnComment() sends the comment to IsMine()> to test if it's definitely Natural Docs content, such as by starting with a recognized header line. If so, it sends it to ParseComment()>. - - If not, OnComment() sends the comment to IsMine()> to test if it's definitely JavaDoc content, such as by having JavaDoc tags. If so, it sends it to ParseComment()>. - - If not, the content is ambiguous. If it's a JavaDoc-styled comment it goes to ParseComment()> to be treated as a headerless Natural Docs comment. It is ignored otherwise, which lets normal comments slip through. Note that it's only ambiguous if neither parser claims it; there's no test to see if they both do. Instead Natural Docs always wins. - - We will not go into the JavaDoc code path for the purposes of this document. It simply converts the JavaDoc comment into as best it can, which will never be perfectly, and adds a to the list for that file. Each of those ParsedTopics will be headerless as indicated by having an undefined Title()>. - - - Stage: Native Comment Parsing - _______________________________________________________________________________________________________ - - At this point, parsing is handed off to ParseComment()>. It searches for header lines within the comment and divides the content into individual topics. It also detects (start code) and (end) sections so that anything that would normally be interpreted as a header line can appear there without breaking the topic. - - The content between the header lines is sent to FormatBody()> which handles all the block level formatting such as paragraphs, bullet lists, and code sections. That function in turn calls RichFormatTextBlock()> on certain snippets of the text to handle all inline formatting, such as bold, underline, and links, both explicit and automatic. - - ParseComment()> then has the body in so it makes a to add to the list. It keeps track of the scoping via topic scoping, regardless of whether we're using full or basic language support. Headerless topics are given normal scope regardless of whether they might be classes or other scoped types. - - - Group: Post Processing - _______________________________________________________________________________________________________ - - After all the comments have been parsed into ParsedTopics and execution has been returned to Parse()>, it's time for some after the fact cleanup. Some things are done like breaking topic lists, determining the menu title, and adding automatic group headings that we won't get into here. There are two processes that are very relevant though. - - - Stage: Repairing Packages - _______________________________________________________________________________________________________ - - If the file we parsed had full language support, the parser would have done more than just generate various OnComment() calls. It would also return a scope record, as represented by objects, and a second set of ParsedTopics it extracted purely from the code, which we'll refer to as autotopics. The scope record shows, purely from the source, what scope each line of code appears in. This is then combined with the topic scoping to update ParsedTopics that come from the comments in the function RepairPackages()>. - - If a comment topic changes the scope, that's honored until the next autotopic or scope change from the code. This allows someone to document a class that doesn't appear in the code purely with topic scoping without throwing off anything else. Any other comment topics have their scope changed to the current scope no matter how it's arrived at. This allows someone to manually document a function without manually documenting the class and still have it appear under that class. The scope record will change the scope to part of that class even if topic scoping did not. Essentially the previous topic scoping is thrown out, which I guess is something that can be improved. - - None of this affects the autotopics, as they are known to have the correct scoping since they are gleaned from the code with a dedicated parser. Wouldn't there be duplication of manually documented code elements, which would appear both in the autotopics and in the comment topics? Yes. That brings us to our next stage, which is... - - - Stage: Merging Auto Topics - _______________________________________________________________________________________________________ - - As mentioned above, ParseFile() also returns a set of ParsedTopics gleaned from the code called autotopics. The function MergeAutoTopics()> merges this list with the comment topics. - - The list is basically merged by line number. Since named topics should appear directly above the thing that they're documenting, topics are tested that way and combined into one if they match. The description and title of the comment topic is merged with the prototype of the autotopic. JavaDoc styled comments are also merged in this function, as they should appear directly above the code element they're documenting. Any headerless topics that don't, either by appearing past the last autotopic or above another comment topic, are discarded. - - - Stage: Conclusion - _______________________________________________________________________________________________________ - - Thus ends all processing by Parse()>. The file is now a single list of with all the body content in . If we were using ParseForBuild()>, that's pretty much it and it's ready to be converted into the output format. If we were using ParseForInformation()> though, the resulting file is scanned for all relevant information to feed into other packages such as . - - Note that no prototype processing was done in this process, only the possible tranferring of prototypes from one ParsedTopic to another when merging autotopics with comment topics. Obtaining prototypes and formatting them is handled by and derived packages. diff --git a/vendor/naturaldocs/Info/HTMLTestCases.pm b/vendor/naturaldocs/Info/HTMLTestCases.pm deleted file mode 100644 index ea434a4a6..000000000 --- a/vendor/naturaldocs/Info/HTMLTestCases.pm +++ /dev/null @@ -1,270 +0,0 @@ -############################################################################### -# -# File: Browser Testing -# -############################################################################### -# -# This file tests Natural Docs' generated output. Particularly useful when testing various browsers. -# -############################################################################### - -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL) -# Refer to License.txt for the complete details - -use strict; -use integer; - - -# -# About: Browsers -# -# The specific browser versions tested are below. Everything is tested on Windows Vista unless otherwise noted. -# -# Firefox 2.0.0.10 - 2.0 released October 2006. -# Firefox 1.5.0.8 - 1.5 released Novemer 2005. -# Firefox 1.0.8 - 1.0 released November 2004. Not critical to support. -# -# IE 7.0 - 7.0 released October 2006. -# IE 6.0 - 6.0 released August 2001. Tested on Windows XP SP2 via Virtual PC. -# -# Safari 3.0.4 - 3.0 released June 2007. Tested Windows version. -# Safari 2.0.4 - 2.0 released April 2005. Tested on Mac OS X 10.4 Tiger. -# -# Opera 9.02 - 9.0 released June 2006. -# Opera 8.54 - 8.5 released September 2005. -# Opera 8.02 - 8.0 released April 2005. -# Opera 7.51 - 7.5 released around August 2004 I think. Not critical to support. -# Opera 7.02 - 7.0 released January 2003. Not critical to support. -# -# Konqueror 3.5.5 - Tested on openSUSE 10.2 via VMware Player. -# - - -############################################################################### -# Group: Search - -# -# Topic: Unframed HTML Search -# -# Tests: -# -# - Make sure the search box appears and disappears correctly on hover. -# - Type to bring up results. Type further to narrow them. Narrow until there's no results. -# - Backspace to bring the results back. Backspacing to empty closes the results. -# - Type to bring up results with a different first letter. (Tests iframe content switch.) -# - Type *Z* to bring up empty page when there's nothing with that first letter. (Tests generic no results page.) -# - Type *Name* in Everything search to test expanding and collapsing, especially between two that differ only by case. -# - Change filter to *Functions* to test changing filter while results are open. Change to *Types* to switch to one with -# no results. -# - Test Close button on results. Should deactivate panel as well. -# - Clicking away should deactivate panel if the box is empty, not have an effect if there are results open. -# - Text should always change back to "Search" when deactivating. -# -# Results: -# -# Firefox 2.0 - OK -# Firefox 1.5 - OK -# Firefox 1.0 - OK -# -# IE 7.0 - OK -# IE 6.0 - Functionally OK. Search panel doesn't activate on hover. Works fine when clicked. -# -# Safari 3.0 - OK -# Safari 2.0 - *Broken.* Results panel doesn't show up. Border around deactivated search box. -# -# Opera 9.0 - OK -# Opera 8.5 - OK -# Opera 8.0 - OK -# Opera 7.5 - Functionally OK. Search panel has sunken border when deactivated, minor pixel shifting. -# Opera 7.0 - *Broken.* Completely. -# -# Konqueror 3.5 - *Broken.* Results panel doesn't show up. Seems to fail on "resultsFrame = window.frames.MSearchResults;" -# - -# -# Topic: Framed HTML Search -# -# Tests: -# -# - Make sure the search box appears and disappears correctly on hover. -# - Type to bring up results on right. Type further to narrow them. Narrow until there's no results. -# - Backspace to bring the results back. -# - Type to bring up results with a different first letter. (Tests frame content switch.) -# - Type *Z* to bring up empty page when there's nothing with that first letter. (Tests generic no results page.) -# - Type *Name* in Everything search to see that there's no collapsing in this mode. -# - Change filter to *Functions* to test changing filter while results are open. Change to *Types* to switch to one with -# no results. -# - Clicking away should deactivate panel. -# - Clicking a result should deactivate panel and show up in correct frame. -# - Text should always change back to "Search" when deactivating. -# -# Results: -# -# Firefox 2.0 - OK -# Firefox 1.5 - OK -# Firefox 1.0 - OK -# -# IE 7.0 - OK -# IE 6.0 - Functionally OK. Search panel doesn't activate on hover, is a little wide. Works fine when clicked. -# -# Safari 3.0 - OK -# Safari 2.0 - Functionally OK. Has a sunken border around the deactivated seach field. -# -# Opera 9.0 - OK -# Opera 8.5 - OK -# Opera 8.0 - OK -# Opera 7.5 - Functionally OK. Search panel has sunken border when deactivated, minor pixel shifting. -# Opera 7.0 - *Broken.* -# -# Konqueror 3.5 - Functionally OK. Panel doesn't reset and deactivate when clicking a result link. -# - - -############################################################################### -# Group: Other - -# -# Topic: Images -# -# Tests: -# -# - Here is an embedded image on its own line. -# -# (see images/logo.png) -# -# - Here is a reference in the middle of a sentence, in the middle of a bullet list: (see images/logo.png) It should have been -# converted to a link with the image appearing below the bullet list and the file name used as a caption. Make sure the -# caption positions correctly. -# - Here's a link to a non-existent image, which should appear literally: (see images/doesntexist.jpg) -# - Here is an embedded image that doesn't exist on it's own line. -# -# (see images/doesntexist.png) -# -# - Here is a link using the "(see)" syntax which shouldn't be interpreted as an image link because it doesn't end with an -# acceptable extension. Also, links should still resolve because of that. (see ) -# -# Results: -# -# Firefox 2.0 - OK -# Firefox 1.5 - OK -# Firefox 1.0 - OK -# -# IE 7.0 - OK -# IE 6.0 - OK -# -# Safari 3.0 - OK -# Safari 2.0 - OK -# -# Opera 9.0 - OK -# Opera 8.5 - OK -# Opera 8.0 - OK -# Opera 7.5 - OK -# Opera 7.0 - OK -# -# Konqueror 3.5 - OK - - -# -# Topic: Prototypes and Tooltips -# -# Hover over ParseComment()> and IsMine()> -# -# Tests: -# -# - A tooltip should appear about a second after you hover over the link above. -# - It should go away when you move the cursor away. -# - It shoud be positioned directly underneath with a slight gap. -# - The prototype should be formatted cleanly with each parameter on its own line and aligned in columns. -# - The asterisk should be in a separate column. -# - Test it with the link too close to the edge of the window so the pop-up has to shift left to fit. -# -# Results: -# -# Firefox 2.0 - OK -# Firefox 1.5 - OK -# Firefox 1.0 - OK -# -# IE 7.0 - OK -# IE 6.0 - OK -# -# Safari 3.0 - OK -# Safari 2.0 - OK -# -# Opera 9.0 - OK. Has its own tooltips turned on by default which can cover it up though. -# Opera 8.5 - OK. Has its own tooltips turned on by default which can cover it up though. -# Opera 8.0 - OK. Has its own tooltips turned on by default which can cover it up though. -# Opera 7.5 - OK. Has its own tooltips turned on by default which can cover it up though. -# Opera 7.0 - *Broken.* Usually works, if the window is too narrow may collapse completely. -# -# Konqueror 3.5 - OK -# - - -# -# Topic: Long code block scrolling -# -# Go to . -# -# Tests: -# -# - Shrink the browser window so that a line extends past the end of it. Only the line should have a scrollbar, not the -# entire page. -# - Expand the browser window. The scrollbar should disappear. -# -# Results: -# -# Firefox 2.0 - OK -# Firefox 1.5 - OK -# Firefox 1.0 - OK -# -# IE 7.0 - OK -# IE 6.0 - OK -# -# Safari 3.0 - OK -# Safari 2.0 - OK -# -# Opera 9.0 - OK -# Opera 8.5 - OK -# Opera 8.0 - OK -# Opera 7.5 - OK -# Opera 7.0 - OK -# -# Konqueror 3.5 - OK -# - - -# -# Topic: Menu and Class Hierarchies -# -# Go to . -# -# Tests: -# -# - Class hierarchy should look okay. -# - Make sure the menu hierarchy opens up on its own when the page is loaded. -# - You should be able to click on groups to open and close them. -# -# Results: -# -# Firefox 2.0 - OK -# Firefox 1.5 - OK -# Firefox 1.0 - OK -# -# IE 7.0 - OK -# IE 6.0 - OK -# -# Safari 3.0 - OK -# Safari 2.0 - OK -# -# Opera 9.0 - OK -# Opera 8.5 - OK -# Opera 8.0 - OK -# Opera 7.5 - OK -# Opera 7.0 - OK -# -# Konqueror 3.5 - OK -# - - -1; diff --git a/vendor/naturaldocs/Info/Languages.txt b/vendor/naturaldocs/Info/Languages.txt deleted file mode 100644 index c564eb582..000000000 --- a/vendor/naturaldocs/Info/Languages.txt +++ /dev/null @@ -1,107 +0,0 @@ - - Title: Language Notes -_______________________________________________________________________________ - - This is more for my personal reference than anything else. - - - ___________________________________________________________________________ - - Topic: Prototype Parameter Styles - ___________________________________________________________________________ - - Parameters via Commas, Typed via Spaces: - - > FunctionName ( type indentifier, type identifier = value, modifier type identifier ) - > FunctionName ( indentifier, identifier = value ) - - The general idea is that parameters are separated by commas. Identifiers cannot contain spaces. Types and modifiers, - if available, are separated from the identifiers with spaces. There may be an equals sign to set the default value. - - So parsing means splitting by commas, stripping everything past an equals sign for the default value, stripping everything - after the last space for the identifier, and the rest is the type. If there are no internal spaces after the default value is - stripped, it's all identifier. - - Note that internal parenthesis, brackets, braces, and angle brackets should be parsed out. They may be present in default - values or types and any commas and equal signs in them should not be included. - - Applies to C++, Java, C#, JavaScript, Python, PHP, Ruby. - - Applies to Perl as well, even though it doesn't have any real parameter declaration structure. Just adding it with comments - is fine. - - Parameters via Semicolons and Commas, Typed via Colons: - - > FunctionName ( identifier: type; identifier, identifier: type; identifier: type := value ) - - Parameters via semicolons, types via colons. However, there can be more than one parameter per type via commas. - Default values via colon-equals. - - Applies to Pascal, Ada. - - - SQL: - - > FunctionName ( identifier type, identifier modifier type, identifier type := value ) - - Parameters separated by commas. Identifiers come before the types and are separated by a space. Default values are - specified with colon-equals. - - > FunctionName @identifier type, @dentifier modifier type, @identifier type = value - - Microsoft's SQL uses equals instead of colon-equals, doesn't need parenthesis, and starts its parameter names with an @ - symbol. - - - Visual Basic: - - > FunctionName ( modifiers identifier as type, identifier = value ) - - Parameters separated by commas. Default values via equals. However, any number of modifiers may appear before the - identifier. Those modifiers are ByVal, ByRef, Optional, and ParamArray. - - - Tcl: - - > FunctionName { identifier identifier { whatever } } { code } - - Identifiers are specified in the first set of braces and have no commas. However, they can be broken out into sub-braces. - - - ___________________________________________________________________________ - - Topic: Syntax References - ___________________________________________________________________________ - - C++ - http://www.csci.csusb.edu/dick/c++std/syntax.html - - C# - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/CSharpSpecStart.asp. Open in IE. - - Java - http://cui.unige.ch/db-research/Enseignement/analyseinfo/ - Ada - http://cui.unige.ch/db-research/Enseignement/analyseinfo/ - - SQL - http://cui.unige.ch/db-research/Enseignement/analyseinfo/, - , or - (open in IE). - - JavaScript - http://academ.hvcc.edu/~kantopet/javascript/index.php - - Python - http://www.python.org/doc/2.3.4/ref/ref.html - - PHP - http://www.php.net/manual/en/langref.php - - Visual Basic - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/html/vbspecstart.asp. Open in IE. - - Pascal - . Open in IE. - - Ruby - http://www.rubycentral.com/book/ - - ActionScript 2 - - ActionScript 3 - - E2X - http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-357.pdf - - R - Somewhere on http://www.r-project.org. - - ColdFusion - - - Eiffel - http://www.gobosoft.com/eiffel/syntax/ diff --git a/vendor/naturaldocs/Info/NDMarkup.txt b/vendor/naturaldocs/Info/NDMarkup.txt deleted file mode 100644 index 23051722e..000000000 --- a/vendor/naturaldocs/Info/NDMarkup.txt +++ /dev/null @@ -1,92 +0,0 @@ - - Architecture: NDMarkup -_______________________________________________________________________________ - -A markup format used by the parser, both internally and in objects. Text formatted in -NDMarkup will only have the tags documented below. - - -About: Top-Level Tags - - All content will be surrounded by one of the top-level tags. These tags will not appear within each other. - -

- Surrounds a paragraph. Paragraph breaks will replace double line breaks, and single line breaks will - be removed completely. - - - Surrounds code or text diagrams that should appear literally in the output. The type can - be code, text, or anonymous, in which case it's not specified whether it's code or text. - - - Surrounds a heading. - -
    - Surrounds a bulleted (unordered) list. -
    - Surrounds a description list, which is what you are reading. - - - An inline image. Target contains the image target, and original contains the - original text in case it doesn't resolve. - - -About: List Item Tags - - These tags will only appear within their respective lists. - -
  • - Surrounds a bulleted list item. - - Surrounds a description list entry, which is the left side. It will always be followed by a description list - description. - - Surrounds a description list symbol. This is the same as a description list entry, except that the content - is also a referenceable symbol. This occurs when inside a list topic. This tag will always - be followed by a description list description. -
    - Surrounds a description list description, which is the right side. It will always be preceded by a description - list entry or symbol. - -About: Text Tags - - These tags will only appear in paragraphs, headings, or description list descriptions. - - - Bold - - Italics - - Underline - - - Surrounds a potential link to a symbol; potential because the target is not guaranteed to - exist. This tag merely designates an attempted link. Target is what is attempting to be - linked to, name is the text that should appear for a successful link, and original is the - original text in case the link doesn't resolve. - - - An external link. There's no need for an original attribute because it will always be - turned into an actual link. - - A link to an e-mail address. - - - An image link. Target contains the image target, and original contains the original - text in case it doesn't resolve. - - -About: Amp Chars - - These are the only amp chars supported, and will appear everywhere. Every other character will appear as is. - - & - The ampersand &. - " - The double quote ". - < - The less than sign <. - > - The greater than sign >. - -About: Tabs - - NDMarkup will not contain tab characters, only spaces. Any tab characters appearing in the source files will be - expanded/replaced as necessary. - - -About: General Tag Properties - - Since the tags are generated, they will always have the following properties, which will make pattern matching much - easier. - - - Tags and amp chars will always be in all lowercase. - - Properties will appear exactly as documented here. They will be in all lowercase, in the documented order, and will have no - extraneous whitespace. Anything appearing in the properties will have amp chars. - - All code is valid, meaning tags will always be closed,
  • s will only appear within
      s, etc. - - So, for example, you can match description list entries with /(.+?)<\/de>/ and $1 will be the text. No surprises or - gotchas. No need for sophisticated parsing routines. - - Remember that for symbol definitions, the text should appear as is, but internally (such as for the anchor) they need to - be passed through Defines()> so that the output file is just as tolerant as - . diff --git a/vendor/naturaldocs/Info/Symbol Management.txt b/vendor/naturaldocs/Info/Symbol Management.txt deleted file mode 100644 index fb2bad233..000000000 --- a/vendor/naturaldocs/Info/Symbol Management.txt +++ /dev/null @@ -1,59 +0,0 @@ - - Architecture: Symbol Management - -#################################################################################### - - This is the architecture and code path for symbol management. This is almost exclusively managed by , but it's complicated enough that I want a plain-English walk through of the code paths anyway. - - An important thing to remember is that each section below is simplified initially and then expanded upon in later sections as more facets of the code are introduced. You will not get the whole story of what a function does by reading just one section. - - - - Topic: Symbol Storage - _______________________________________________________________________________________________________ - - Symbols are indexed primarily by their , which is the normalized, pre-parsed series of identifiers that make it up. A symbol can have any number of definitions, including none, but can only have one definition per file. If a symbol is defined more than once in a file, only the first definition is counted. Stored for each definition is the , summary, and prototype. - - Each symbol that has a definition has one designated as the global definition. This is the one linked to by other files, unless that file happens to have its own definition which then takes precedence. Which definition is chosen is rather arbitrary at this point; probably the first one that got defined. Similarly, if the global definition is deleted, which one is chosen to replace it is completely arbitrary. - - Each symbol also stores a list of references to it. Note that references can be interpreted as multiple symbols, and each of those symbols will store a link back to the reference. In other words, every reference a symbol stores is one that _can_ be interpreted as that symbol, but that is not necessarily the interpretation the reference actually uses. A reference could have a better interpretation it uses instead. - - For example, suppose there are two functions, MyFunction() and MyClass.MyFunction(). The reference text "MyFunction()" appearing in MyClass can be interpreted as either MyClass.MyFunction(), or if that doesn't exist, the global MyFunction(). Both the symbols for MyFunction() and MyClass.MyFunction() will store that it's referenced by the link, even though the class scoped one serves as the actual definition. - - This is also the reason a symbol can exist that has no definitions: it has references. We want symbols to be created in the table for each reference interpretation, even if it doesn't exist. These are called potential symbols. The reason is so we know whether a new symbol definition fulfills an existing reference, since it may be a better interpretation for the reference than what is currently used. - - - - Topic: Reference Storage - _______________________________________________________________________________________________________ - - References are indexed primarily by their , which is actually an elaborate data structure packed into a string. It includes a of the text that appears in the link and a bunch of other data that determines the rules by which the link can be resolved. For example, it includes the scope it appears in and any "using" statements in effect, which are alternate possible scopes. It includes the type of link it is (text links, the ones you explicitly put in comments, aren't the only kind) and resolving flags which encode the language-specific rules of non-text links. But the bottom line is the encodes everything that influences how it may be resolved, so if two links come up with the same rules, they're considered two definitions of the same reference. This is the understanding of the word "reference" that will used in this document. - - Like symbols, each reference stores a list of definitions. However, it only stores the name as all the other relevant information is encoded in the itself. Unlike a symbol, which can be linked to the same no matter what kind of definitions it has, references that are in any way different might be interpreted differently and so need their own distinct entries in the symbol table. - - References also store a list of interpretations. Every possible interpretation of the reference is stored and given a numeric score. The higher the score, the better it suits the reference. In the MyFunction() example from before, MyClass.MyFunction() would have a higher score than just MyFunction() because the local scope should win. Each interpretation has a unique score, there are no duplicates. - - So the symbol and reference data structures are complimentary. Each symbol has a list of every reference that might be interpreted as it, and every reference has a list of each symbol that it could be interpreted as. Again, objects are created for potential symbols (those with references but no definitions) so that this structure always remains intact. - - The interpretation with the highest score which actually exists is deemed the current interpretation of the reference. Unlike symbols where the next global definition is arbitrary, the succession of reference interpretations is very controlled and predictable. - - - Topic: Change Detection - _______________________________________________________________________________________________________ - - Change management is handled a couple of ways. First, there is a secondary file index in that stores which symbols and references are stored in each file. It doesn't have any information other than a list of and since they can be used in the main structures to look up the details. If a file is deleted, the symbol table can then prune any definitions that should no longer be in the table. - - Another way deals with how the information parsing stage works. Files parsed for information just have their symbols and references added to the table regardless of whether this was the first time it was ever parsed or if it had been parsed before. If it had been parsed before, all the information from the previous parse should be in the symbol table and file indexes already. If a new symbol or reference is defined, that's fine, it's added to the table normally. However, if a symbol is redefined it's ignored because only the first definition matters. Also, this won't detect things that disappear. - - Enter watched files. tells to designate a file as watched before it starts parsing it, and then says to analyze the changes when it's done. The watched file is a second index of all the symbols and references that were defined since the watch started, including the specific details on the symbol definitions. When the analysis is done, it compares the list of symbols and references to the one in the main file index. Any that appear in the main file index but not the watched one are deleted because they didn't show up the second time around. Any symbol definitions that are different in the watched file than the main file are changed to the former, since the first definition that appeared the second time around was different than the original. - - - Topic: Change Management - _______________________________________________________________________________________________________ - - When a symbol's global definition changes, either because it switches to another file or because the details of the current file's definition changed (prototype, summary, etc.) it goes through all the references that can be interpreted as that symbol, finds the ones that use it as their current definition, and marks all the files that define them for rebuilding. The links in their output files have to be changed to the new definition or at least have their tooltips updated. - - When a symbol's last definition is deleted, it goes through all the references that can be interpreted as that symbol, finds the ones that use it as their current definition, and has them reinterpreted to the definition with the next highest score. The files that define them are also marked for rebuilding. - - When a potential symbol's first definition is found, it goes through all the references that can be interpreted as it and sees if it can serve as a higher scored interpretation than the current one. If so, the interpretations are changed and all the files that define them are marked for rebuilding. - diff --git a/vendor/naturaldocs/Info/images/Logo.png b/vendor/naturaldocs/Info/images/Logo.png deleted file mode 100644 index 87395ec5e..000000000 Binary files a/vendor/naturaldocs/Info/images/Logo.png and /dev/null differ diff --git a/vendor/naturaldocs/JavaScript/GooglePrettify.js b/vendor/naturaldocs/JavaScript/GooglePrettify.js deleted file mode 100644 index fda4bf1ed..000000000 --- a/vendor/naturaldocs/JavaScript/GooglePrettify.js +++ /dev/null @@ -1,1526 +0,0 @@ - -// This code comes from the December 2009 release of Google Prettify, which is Copyright © 2006 Google Inc. -// Minor modifications are marked with "ND Change" comments. -// As part of Natural Docs, this code is licensed under version 3 of the GNU Affero General Public License (AGPL.) -// However, it may also be obtained separately under version 2.0 of the Apache License. -// Refer to License.txt for the complete details - - -// Main code -// ____________________________________________________________________________ - -// Copyright (C) 2006 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/** - * @fileoverview - * some functions for browser-side pretty printing of code contained in html. - *

      - * - * For a fairly comprehensive set of languages see the - * README - * file that came with this source. At a minimum, the lexer should work on a - * number of languages including C and friends, Java, Python, Bash, SQL, HTML, - * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk - * and a subset of Perl, but, because of commenting conventions, doesn't work on - * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. - *

      - * Usage:

        - *
      1. include this source file in an html page via - * {@code } - *
      2. define style rules. See the example page for examples. - *
      3. mark the {@code
        } and {@code } tags in your source with
        - *    {@code class=prettyprint.}
        - *    You can also use the (html deprecated) {@code } tag, but the pretty
        - *    printer needs to do more substantial DOM manipulations to support that, so
        - *    some css styles may not be preserved.
        - * </ol>
        - * That's it.  I wanted to keep the API as simple as possible, so there's no
        - * need to specify which language the code is in, but if you wish, you can add
        - * another class to the {@code <pre>} or {@code <code>} element to specify the
        - * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
        - * starts with "lang-" followed by a file extension, specifies the file type.
        - * See the "lang-*.js" files in this directory for code that implements
        - * per-language file handlers.
        - * <p>
        - * Change log:<br>
        - * cbeust, 2006/08/22
        - * <blockquote>
        - *   Java annotations (start with "@") are now captured as literals ("lit")
        - * </blockquote>
        - * @requires console
        - * @overrides window
        - */
        -
        -// JSLint declarations
        -/*global console, document, navigator, setTimeout, window */
        -
        -/**
        - * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
        - * UI events.
        - * If set to {@code false}, {@code prettyPrint()} is synchronous.
        - */
        -window['PR_SHOULD_USE_CONTINUATION'] = true;
        -
        -/** the number of characters between tab columns */
        -window['PR_TAB_WIDTH'] = 8;
        -
        -/** Walks the DOM returning a properly escaped version of innerHTML.
        -  * @param {Node} node
        -  * @param {Array.<string>} out output buffer that receives chunks of HTML.
        -  */
        -window['PR_normalizedHtml']
        -
        -/** Contains functions for creating and registering new language handlers.
        -  * @type {Object}
        -  */
        -  = window['PR']
        -
        -/** Pretty print a chunk of code.
        -  *
        -  * @param {string} sourceCodeHtml code as html
        -  * @return {string} code as html, but prettier
        -  */
        -  = window['prettyPrintOne']
        -/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with
        -  * {@code class=prettyprint} and prettify them.
        -  * @param {Function?} opt_whenDone if specified, called when the last entry
        -  *     has been finished.
        -  */
        -  = window['prettyPrint'] = void 0;
        -
        -/** browser detection. @extern @returns false if not IE, otherwise the major version. */
        -window['_pr_isIE6'] = function () {
        -  var ieVersion = navigator && navigator.userAgent &&
        -      navigator.userAgent.match(/\bMSIE ([678])\./);
        -  ieVersion = ieVersion ? +ieVersion[1] : false;
        -  window['_pr_isIE6'] = function () { return ieVersion; };
        -  return ieVersion;
        -};
        -
        -
        -(function () {
        -  // Keyword lists for various languages.
        -  var FLOW_CONTROL_KEYWORDS =
        -      "break continue do else for if return while ";
        -  var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
        -      "double enum extern float goto int long register short signed sizeof " +
        -      "static struct switch typedef union unsigned void volatile ";
        -  var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
        -      "new operator private protected public this throw true try typeof ";
        -  var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
        -      "concept concept_map const_cast constexpr decltype " +
        -      "dynamic_cast explicit export friend inline late_check " +
        -      "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
        -      "template typeid typename using virtual wchar_t where ";
        -  var JAVA_KEYWORDS = COMMON_KEYWORDS +
        -      "abstract boolean byte extends final finally implements import " +
        -      "instanceof null native package strictfp super synchronized throws " +
        -      "transient ";
        -  var CSHARP_KEYWORDS = JAVA_KEYWORDS +
        -      "as base by checked decimal delegate descending event " +
        -      "fixed foreach from group implicit in interface internal into is lock " +
        -      "object out override orderby params partial readonly ref sbyte sealed " +
        -      "stackalloc string select uint ulong unchecked unsafe ushort var ";
        -  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
        -      "debugger eval export function get null set undefined var with " +
        -      "Infinity NaN ";
        -  var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
        -      "goto if import last local my next no our print package redo require " +
        -      "sub undef unless until use wantarray while BEGIN END ";
        -  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
        -      "elif except exec finally from global import in is lambda " +
        -      "nonlocal not or pass print raise try with yield " +
        -      "False True None ";
        -  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
        -      " defined elsif end ensure false in module next nil not or redo rescue " +
        -      "retry self super then true undef unless until when yield BEGIN END ";
        -  var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
        -      "function in local set then until ";
        -  var ALL_KEYWORDS = (
        -      CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
        -      PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
        -
        -  // token style names.  correspond to css classes
        -  /** token style for a string literal */
        -  var PR_STRING = 'str';
        -  /** token style for a keyword */
        -  var PR_KEYWORD = 'kwd';
        -  /** token style for a comment */
        -  var PR_COMMENT = 'com';
        -  /** token style for a type */
        -  var PR_TYPE = 'typ';
        -  /** token style for a literal value.  e.g. 1, null, true. */
        -  var PR_LITERAL = 'lit';
        -  /** token style for a punctuation string. */
        -  var PR_PUNCTUATION = 'pun';
        -  /** token style for a punctuation string. */
        -  var PR_PLAIN = 'pln';
        -
        -  /** token style for an sgml tag. */
        -  var PR_TAG = 'tag';
        -  /** token style for a markup declaration such as a DOCTYPE. */
        -  var PR_DECLARATION = 'dec';
        -  /** token style for embedded source. */
        -  var PR_SOURCE = 'src';
        -  /** token style for an sgml attribute name. */
        -  var PR_ATTRIB_NAME = 'atn';
        -  /** token style for an sgml attribute value. */
        -  var PR_ATTRIB_VALUE = 'atv';
        -
        -  /**
        -   * A class that indicates a section of markup that is not code, e.g. to allow
        -   * embedding of line numbers within code listings.
        -   */
        -  var PR_NOCODE = 'nocode';
        -
        -  /** A set of tokens that can precede a regular expression literal in
        -    * javascript.
        -    * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
        -    * list, but I've removed ones that might be problematic when seen in
        -    * languages that don't support regular expression literals.
        -    *
        -    * <p>Specifically, I've removed any keywords that can't precede a regexp
        -    * literal in a syntactically legal javascript program, and I've removed the
        -    * "in" keyword since it's not a keyword in many languages, and might be used
        -    * as a count of inches.
        -    *
        -    * <p>The link a above does not accurately describe EcmaScript rules since
        -    * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
        -    * very well in practice.
        -    *
        -    * @private
        -    */
        -  var REGEXP_PRECEDER_PATTERN = function () {
        -      var preceders = [
        -          "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
        -          "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
        -          "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
        -          "<", "<<", "<<=", "<=", "=", "==", "===", ">",
        -          ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
        -          "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
        -          "||=", "~" /* handles =~ and !~ */,
        -          "break", "case", "continue", "delete",
        -          "do", "else", "finally", "instanceof",
        -          "return", "throw", "try", "typeof"
        -          ];
        -      var pattern = '(?:^^|[+-]';
        -      for (var i = 0; i < preceders.length; ++i) {
        -        pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
        -      }
        -      pattern += ')\\s*';  // matches at end, and matches empty string
        -      return pattern;
        -      // CAVEAT: this does not properly handle the case where a regular
        -      // expression immediately follows another since a regular expression may
        -      // have flags for case-sensitivity and the like.  Having regexp tokens
        -      // adjacent is not valid in any language I'm aware of, so I'm punting.
        -      // TODO: maybe style special characters inside a regexp as punctuation.
        -    }();
        -
        -  // Define regexps here so that the interpreter doesn't have to create an
        -  // object each time the function containing them is called.
        -  // The language spec requires a new object created even if you don't access
        -  // the $1 members.
        -  var pr_amp = /&/g;
        -  var pr_lt = /</g;
        -  var pr_gt = />/g;
        -  var pr_quot = /\"/g;
        -  /** like textToHtml but escapes double quotes to be attribute safe. */
        -  function attribToHtml(str) {
        -    return str.replace(pr_amp, '&amp;')
        -        .replace(pr_lt, '&lt;')
        -        .replace(pr_gt, '&gt;')
        -        .replace(pr_quot, '&quot;');
        -  }
        -
        -  /** escapest html special characters to html. */
        -  function textToHtml(str) {
        -    return str.replace(pr_amp, '&amp;')
        -        .replace(pr_lt, '&lt;')
        -        .replace(pr_gt, '&gt;');
        -  }
        -
        -
        -  var pr_ltEnt = /&lt;/g;
        -  var pr_gtEnt = /&gt;/g;
        -  var pr_aposEnt = /&apos;/g;
        -  var pr_quotEnt = /&quot;/g;
        -  var pr_ampEnt = /&amp;/g;
        -  var pr_nbspEnt = /&nbsp;/g;
        -  /** unescapes html to plain text. */
        -  function htmlToText(html) {
        -    var pos = html.indexOf('&');
        -    if (pos < 0) { return html; }
        -    // Handle numeric entities specially.  We can't use functional substitution
        -    // since that doesn't work in older versions of Safari.
        -    // These should be rare since most browsers convert them to normal chars.
        -    for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {
        -      var end = html.indexOf(';', pos);
        -      if (end >= 0) {
        -        var num = html.substring(pos + 3, end);
        -        var radix = 10;
        -        if (num && num.charAt(0) === 'x') {
        -          num = num.substring(1);
        -          radix = 16;
        -        }
        -        var codePoint = parseInt(num, radix);
        -        if (!isNaN(codePoint)) {
        -          html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
        -                  html.substring(end + 1));
        -        }
        -      }
        -    }
        -
        -    return html.replace(pr_ltEnt, '<')
        -        .replace(pr_gtEnt, '>')
        -        .replace(pr_aposEnt, "'")
        -        .replace(pr_quotEnt, '"')
        -        .replace(pr_nbspEnt, ' ')
        -        .replace(pr_ampEnt, '&');
        -  }
        -
        -  /** is the given node's innerHTML normally unescaped? */
        -  function isRawContent(node) {
        -    return 'XMP' === node.tagName;
        -  }
        -
        -  var newlineRe = /[\r\n]/g;
        -  /**
        -   * Are newlines and adjacent spaces significant in the given node's innerHTML?
        -   */
        -  function isPreformatted(node, content) {
        -    // PRE means preformatted, and is a very common case, so don't create
        -    // unnecessary computed style objects.
        -    if ('PRE' === node.tagName) { return true; }
        -    if (!newlineRe.test(content)) { return true; }  // Don't care
        -    var whitespace = '';
        -    // For disconnected nodes, IE has no currentStyle.
        -    if (node.currentStyle) {
        -      whitespace = node.currentStyle.whiteSpace;
        -    } else if (window.getComputedStyle) {
        -      // Firefox makes a best guess if node is disconnected whereas Safari
        -      // returns the empty string.
        -      whitespace = window.getComputedStyle(node, null).whiteSpace;
        -    }
        -    return !whitespace || whitespace === 'pre';
        -  }
        -
        -  function normalizedHtml(node, out) {
        -    switch (node.nodeType) {
        -      case 1:  // an element
        -        var name = node.tagName.toLowerCase();
        -        out.push('<', name);
        -        for (var i = 0; i < node.attributes.length; ++i) {
        -          var attr = node.attributes[i];
        -          if (!attr.specified) { continue; }
        -          out.push(' ');
        -          normalizedHtml(attr, out);
        -        }
        -        out.push('>');
        -        for (var child = node.firstChild; child; child = child.nextSibling) {
        -          normalizedHtml(child, out);
        -        }
        -        if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
        -          out.push('<\/', name, '>');
        -        }
        -        break;
        -      case 2: // an attribute
        -        out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"');
        -        break;
        -      case 3: case 4: // text
        -        out.push(textToHtml(node.nodeValue));
        -        break;
        -    }
        -  }
        -
        -  /**
        -   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
        -   * matches the union o the sets o strings matched d by the input RegExp.
        -   * Since it matches globally, if the input strings have a start-of-input
        -   * anchor (/^.../), it is ignored for the purposes of unioning.
        -   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
        -   * @return {RegExp} a global regex.
        -   */
        -  function combinePrefixPatterns(regexs) {
        -    var capturedGroupIndex = 0;
        -
        -    var needToFoldCase = false;
        -    var ignoreCase = false;
        -    for (var i = 0, n = regexs.length; i < n; ++i) {
        -      var regex = regexs[i];
        -      if (regex.ignoreCase) {
        -        ignoreCase = true;
        -      } else if (/[a-z]/i.test(regex.source.replace(
        -                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
        -        needToFoldCase = true;
        -        ignoreCase = false;
        -        break;
        -      }
        -    }
        -
        -    function decodeEscape(charsetPart) {
        -      if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
        -      switch (charsetPart.charAt(1)) {
        -        case 'b': return 8;
        -        case 't': return 9;
        -        case 'n': return 0xa;
        -        case 'v': return 0xb;
        -        case 'f': return 0xc;
        -        case 'r': return 0xd;
        -        case 'u': case 'x':
        -          return parseInt(charsetPart.substring(2), 16)
        -              || charsetPart.charCodeAt(1);
        -        case '0': case '1': case '2': case '3': case '4':
        -        case '5': case '6': case '7':
        -          return parseInt(charsetPart.substring(1), 8);
        -        default: return charsetPart.charCodeAt(1);
        -      }
        -    }
        -
        -    function encodeEscape(charCode) {
        -      if (charCode < 0x20) {
        -        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
        -      }
        -      var ch = String.fromCharCode(charCode);
        -      if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
        -        ch = '\\' + ch;
        -      }
        -      return ch;
        -    }
        -
        -    function caseFoldCharset(charSet) {
        -      var charsetParts = charSet.substring(1, charSet.length - 1).match(
        -          new RegExp(
        -              '\\\\u[0-9A-Fa-f]{4}'
        -              + '|\\\\x[0-9A-Fa-f]{2}'
        -              + '|\\\\[0-3][0-7]{0,2}'
        -              + '|\\\\[0-7]{1,2}'
        -              + '|\\\\[\\s\\S]'
        -              + '|-'
        -              + '|[^-\\\\]',
        -              'g'));
        -      var groups = [];
        -      var ranges = [];
        -      var inverse = charsetParts[0] === '^';
        -      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
        -        var p = charsetParts[i];
        -        switch (p) {
        -          case '\\B': case '\\b':
        -          case '\\D': case '\\d':
        -          case '\\S': case '\\s':
        -          case '\\W': case '\\w':
        -            groups.push(p);
        -            continue;
        -        }
        -        var start = decodeEscape(p);
        -        var end;
        -        if (i + 2 < n && '-' === charsetParts[i + 1]) {
        -          end = decodeEscape(charsetParts[i + 2]);
        -          i += 2;
        -        } else {
        -          end = start;
        -        }
        -        ranges.push([start, end]);
        -        // If the range might intersect letters, then expand it.
        -        if (!(end < 65 || start > 122)) {
        -          if (!(end < 65 || start > 90)) {
        -            ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
        -          }
        -          if (!(end < 97 || start > 122)) {
        -            ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
        -          }
        -        }
        -      }
        -
        -      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
        -      // -> [[1, 12], [14, 14], [16, 17]]
        -      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
        -      var consolidatedRanges = [];
        -      var lastRange = [NaN, NaN];
        -      for (var i = 0; i < ranges.length; ++i) {
        -        var range = ranges[i];
        -        if (range[0] <= lastRange[1] + 1) {
        -          lastRange[1] = Math.max(lastRange[1], range[1]);
        -        } else {
        -          consolidatedRanges.push(lastRange = range);
        -        }
        -      }
        -
        -      var out = ['['];
        -      if (inverse) { out.push('^'); }
        -      out.push.apply(out, groups);
        -      for (var i = 0; i < consolidatedRanges.length; ++i) {
        -        var range = consolidatedRanges[i];
        -        out.push(encodeEscape(range[0]));
        -        if (range[1] > range[0]) {
        -          if (range[1] + 1 > range[0]) { out.push('-'); }
        -          out.push(encodeEscape(range[1]));
        -        }
        -      }
        -      out.push(']');
        -      return out.join('');
        -    }
        -
        -    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
        -      // Split into character sets, escape sequences, punctuation strings
        -      // like ('(', '(?:', ')', '^'), and runs of characters that do not
        -      // include any of the above.
        -      var parts = regex.source.match(
        -          new RegExp(
        -              '(?:'
        -              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
        -              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
        -              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
        -              + '|\\\\[0-9]+'  // a back-reference or octal escape
        -              + '|\\\\[^ux0-9]'  // other escape sequence
        -              + '|\\(\\?[:!=]'  // start of a non-capturing group
        -              + '|[\\(\\)\\^]'  // start/emd of a group, or line start
        -              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
        -              + ')',
        -              'g'));
        -      var n = parts.length;
        -
        -      // Maps captured group numbers to the number they will occupy in
        -      // the output or to -1 if that has not been determined, or to
        -      // undefined if they need not be capturing in the output.
        -      var capturedGroups = [];
        -
        -      // Walk over and identify back references to build the capturedGroups
        -      // mapping.
        -      for (var i = 0, groupIndex = 0; i < n; ++i) {
        -        var p = parts[i];
        -        if (p === '(') {
        -          // groups are 1-indexed, so max group index is count of '('
        -          ++groupIndex;
        -        } else if ('\\' === p.charAt(0)) {
        -          var decimalValue = +p.substring(1);
        -          if (decimalValue && decimalValue <= groupIndex) {
        -            capturedGroups[decimalValue] = -1;
        -          }
        -        }
        -      }
        -
        -      // Renumber groups and reduce capturing groups to non-capturing groups
        -      // where possible.
        -      for (var i = 1; i < capturedGroups.length; ++i) {
        -        if (-1 === capturedGroups[i]) {
        -          capturedGroups[i] = ++capturedGroupIndex;
        -        }
        -      }
        -      for (var i = 0, groupIndex = 0; i < n; ++i) {
        -        var p = parts[i];
        -        if (p === '(') {
        -          ++groupIndex;
        -          if (capturedGroups[groupIndex] === undefined) {
        -            parts[i] = '(?:';
        -          }
        -        } else if ('\\' === p.charAt(0)) {
        -          var decimalValue = +p.substring(1);
        -          if (decimalValue && decimalValue <= groupIndex) {
        -            parts[i] = '\\' + capturedGroups[groupIndex];
        -          }
        -        }
        -      }
        -
        -      // Remove any prefix anchors so that the output will match anywhere.
        -      // ^^ really does mean an anchored match though.
        -      for (var i = 0, groupIndex = 0; i < n; ++i) {
        -        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
        -      }
        -
        -      // Expand letters to groupts to handle mixing of case-sensitive and
        -      // case-insensitive patterns if necessary.
        -      if (regex.ignoreCase && needToFoldCase) {
        -        for (var i = 0; i < n; ++i) {
        -          var p = parts[i];
        -          var ch0 = p.charAt(0);
        -          if (p.length >= 2 && ch0 === '[') {
        -            parts[i] = caseFoldCharset(p);
        -          } else if (ch0 !== '\\') {
        -            // TODO: handle letters in numeric escapes.
        -            parts[i] = p.replace(
        -                /[a-zA-Z]/g,
        -                function (ch) {
        -                  var cc = ch.charCodeAt(0);
        -                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
        -                });
        -          }
        -        }
        -      }
        -
        -      return parts.join('');
        -    }
        -
        -    var rewritten = [];
        -    for (var i = 0, n = regexs.length; i < n; ++i) {
        -      var regex = regexs[i];
        -      if (regex.global || regex.multiline) { throw new Error('' + regex); }
        -      rewritten.push(
        -          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
        -    }
        -
        -    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
        -  }
        -
        -  var PR_innerHtmlWorks = null;
        -  function getInnerHtml(node) {
        -    // inner html is hopelessly broken in Safari 2.0.4 when the content is
        -    // an html description of well formed XML and the containing tag is a PRE
        -    // tag, so we detect that case and emulate innerHTML.
        -    if (null === PR_innerHtmlWorks) {
        -      var testNode = document.createElement('PRE');
        -      testNode.appendChild(
        -          document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));
        -      PR_innerHtmlWorks = !/</.test(testNode.innerHTML);
        -    }
        -
        -    if (PR_innerHtmlWorks) {
        -      var content = node.innerHTML;
        -      // XMP tags contain unescaped entities so require special handling.
        -      if (isRawContent(node)) {
        -        content = textToHtml(content);
        -      } else if (!isPreformatted(node, content)) {
        -        content = content.replace(/(<br\s*\/?>)[\r\n]+/g, '$1')
        -            .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
        -      }
        -      return content;
        -    }
        -
        -    var out = [];
        -    for (var child = node.firstChild; child; child = child.nextSibling) {
        -      normalizedHtml(child, out);
        -    }
        -    return out.join('');
        -  }
        -
        -  /** returns a function that expand tabs to spaces.  This function can be fed
        -    * successive chunks of text, and will maintain its own internal state to
        -    * keep track of how tabs are expanded.
        -    * @return {function (string) : string} a function that takes
        -    *   plain text and return the text with tabs expanded.
        -    * @private
        -    */
        -  function makeTabExpander(tabWidth) {
        -    var SPACES = '                ';
        -    var charInLine = 0;
        -
        -    return function (plainText) {
        -      // walk over each character looking for tabs and newlines.
        -      // On tabs, expand them.  On newlines, reset charInLine.
        -      // Otherwise increment charInLine
        -      var out = null;
        -      var pos = 0;
        -      for (var i = 0, n = plainText.length; i < n; ++i) {
        -        var ch = plainText.charAt(i);
        -
        -        switch (ch) {
        -          case '\t':
        -            if (!out) { out = []; }
        -            out.push(plainText.substring(pos, i));
        -            // calculate how much space we need in front of this part
        -            // nSpaces is the amount of padding -- the number of spaces needed
        -            // to move us to the next column, where columns occur at factors of
        -            // tabWidth.
        -            var nSpaces = tabWidth - (charInLine % tabWidth);
        -            charInLine += nSpaces;
        -            for (; nSpaces >= 0; nSpaces -= SPACES.length) {
        -              out.push(SPACES.substring(0, nSpaces));
        -            }
        -            pos = i + 1;
        -            break;
        -          case '\n':
        -            charInLine = 0;
        -            break;
        -          default:
        -            ++charInLine;
        -        }
        -      }
        -      if (!out) { return plainText; }
        -      out.push(plainText.substring(pos));
        -      return out.join('');
        -    };
        -  }
        -
        -  var pr_chunkPattern = new RegExp(
        -      '[^<]+'  // A run of characters other than '<'
        -      + '|<\!--[\\s\\S]*?--\>'  // an HTML comment
        -      + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>'  // a CDATA section
        -      // a probable tag that should not be highlighted
        -      + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
        -      + '|<',  // A '<' that does not begin a larger chunk
        -      'g');
        -  var pr_commentPrefix = /^<\!--/;
        -  var pr_cdataPrefix = /^<!\[CDATA\[/;
        -  var pr_brPrefix = /^<br\b/i;
        -  var pr_tagNameRe = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;
        -
        -  /** split markup into chunks of html tags (style null) and
        -    * plain text (style {@link #PR_PLAIN}), converting tags which are
        -    * significant for tokenization (<br>) into their textual equivalent.
        -    *
        -    * @param {string} s html where whitespace is considered significant.
        -    * @return {Object} source code and extracted tags.
        -    * @private
        -    */
        -  function extractTags(s) {
        -    // since the pattern has the 'g' modifier and defines no capturing groups,
        -    // this will return a list of all chunks which we then classify and wrap as
        -    // PR_Tokens
        -    var matches = s.match(pr_chunkPattern);
        -    var sourceBuf = [];
        -    var sourceBufLen = 0;
        -    var extractedTags = [];
        -    if (matches) {
        -      for (var i = 0, n = matches.length; i < n; ++i) {
        -        var match = matches[i];
        -        if (match.length > 1 && match.charAt(0) === '<') {
        -          if (pr_commentPrefix.test(match)) { continue; }
        -          if (pr_cdataPrefix.test(match)) {
        -            // strip CDATA prefix and suffix.  Don't unescape since it's CDATA
        -            sourceBuf.push(match.substring(9, match.length - 3));
        -            sourceBufLen += match.length - 12;
        -          } else if (pr_brPrefix.test(match)) {
        -            // <br> tags are lexically significant so convert them to text.
        -            // This is undone later.
        -            sourceBuf.push('\n');
        -            ++sourceBufLen;
        -          } else {
        -            if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
        -              // A <span class="nocode"> will start a section that should be
        -              // ignored.  Continue walking the list until we see a matching end
        -              // tag.
        -              var name = match.match(pr_tagNameRe)[2];
        -              var depth = 1;
        -              var j;
        -              end_tag_loop:
        -              for (j = i + 1; j < n; ++j) {
        -                var name2 = matches[j].match(pr_tagNameRe);
        -                if (name2 && name2[2] === name) {
        -                  if (name2[1] === '/') {
        -                    if (--depth === 0) { break end_tag_loop; }
        -                  } else {
        -                    ++depth;
        -                  }
        -                }
        -              }
        -              if (j < n) {
        -                extractedTags.push(
        -                    sourceBufLen, matches.slice(i, j + 1).join(''));
        -                i = j;
        -              } else {  // Ignore unclosed sections.
        -                extractedTags.push(sourceBufLen, match);
        -              }
        -            } else {
        -              extractedTags.push(sourceBufLen, match);
        -            }
        -          }
        -        } else {
        -          var literalText = htmlToText(match);
        -          sourceBuf.push(literalText);
        -          sourceBufLen += literalText.length;
        -        }
        -      }
        -    }
        -    return { source: sourceBuf.join(''), tags: extractedTags };
        -  }
        -
        -  /** True if the given tag contains a class attribute with the nocode class. */
        -  function isNoCodeTag(tag) {
        -    return !!tag
        -        // First canonicalize the representation of attributes
        -        .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
        -                 ' $1="$2$3$4"')
        -        // Then look for the attribute we want.
        -        .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
        -  }
        -
        -  /**
        -   * Apply the given language handler to sourceCode and add the resulting
        -   * decorations to out.
        -   * @param {number} basePos the index of sourceCode within the chunk of source
        -   *    whose decorations are already present on out.
        -   */
        -  function appendDecorations(basePos, sourceCode, langHandler, out) {
        -    if (!sourceCode) { return; }
        -    var job = {
        -      source: sourceCode,
        -      basePos: basePos
        -    };
        -    langHandler(job);
        -    out.push.apply(out, job.decorations);
        -  }
        -
        -  /** Given triples of [style, pattern, context] returns a lexing function,
        -    * The lexing function interprets the patterns to find token boundaries and
        -    * returns a decoration list of the form
        -    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
        -    * where index_n is an index into the sourceCode, and style_n is a style
        -    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
        -    * all characters in sourceCode[index_n-1:index_n].
        -    *
        -    * The stylePatterns is a list whose elements have the form
        -    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
        -    *
        -    * Style is a style constant like PR_PLAIN, or can be a string of the
        -    * form 'lang-FOO', where FOO is a language extension describing the
        -    * language of the portion of the token in $1 after pattern executes.
        -    * E.g., if style is 'lang-lisp', and group 1 contains the text
        -    * '(hello (world))', then that portion of the token will be passed to the
        -    * registered lisp handler for formatting.
        -    * The text before and after group 1 will be restyled using this decorator
        -    * so decorators should take care that this doesn't result in infinite
        -    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
        -    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
        -    * '<script>foo()<\/script>', which would cause the current decorator to
        -    * be called with '<script>' which would not match the same rule since
        -    * group 1 must not be empty, so it would be instead styled as PR_TAG by
        -    * the generic tag rule.  The handler registered for the 'js' extension would
        -    * then be called with 'foo()', and finally, the current decorator would
        -    * be called with '<\/script>' which would not match the original rule and
        -    * so the generic tag rule would identify it as a tag.
        -    *
        -    * Pattern must only match prefixes, and if it matches a prefix, then that
        -    * match is considered a token with the same style.
        -    *
        -    * Context is applied to the last non-whitespace, non-comment token
        -    * recognized.
        -    *
        -    * Shortcut is an optional string of characters, any of which, if the first
        -    * character, gurantee that this pattern and only this pattern matches.
        -    *
        -    * @param {Array} shortcutStylePatterns patterns that always start with
        -    *   a known character.  Must have a shortcut string.
        -    * @param {Array} fallthroughStylePatterns patterns that will be tried in
        -    *   order if the shortcut ones fail.  May have shortcuts.
        -    *
        -    * @return {function (Object)} a
        -    *   function that takes source code and returns a list of decorations.
        -    */
        -  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
        -    var shortcuts = {};
        -    var tokenizer;
        -    (function () {
        -      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
        -      var allRegexs = [];
        -      var regexKeys = {};
        -      for (var i = 0, n = allPatterns.length; i < n; ++i) {
        -        var patternParts = allPatterns[i];
        -        var shortcutChars = patternParts[3];
        -        if (shortcutChars) {
        -          for (var c = shortcutChars.length; --c >= 0;) {
        -            shortcuts[shortcutChars.charAt(c)] = patternParts;
        -          }
        -        }
        -        var regex = patternParts[1];
        -        var k = '' + regex;
        -        if (!regexKeys.hasOwnProperty(k)) {
        -          allRegexs.push(regex);
        -          regexKeys[k] = null;
        -        }
        -      }
        -      allRegexs.push(/[\0-\uffff]/);
        -      tokenizer = combinePrefixPatterns(allRegexs);
        -    })();
        -
        -    var nPatterns = fallthroughStylePatterns.length;
        -    var notWs = /\S/;
        -
        -    /**
        -     * Lexes job.source and produces an output array job.decorations of style
        -     * classes preceded by the position at which they start in job.source in
        -     * order.
        -     *
        -     * @param {Object} job an object like {@code
        -     *    source: {string} sourceText plain text,
        -     *    basePos: {int} position of job.source in the larger chunk of
        -     *        sourceCode.
        -     * }
        -     */
        -    var decorate = function (job) {
        -      var sourceCode = job.source, basePos = job.basePos;
        -      /** Even entries are positions in source in ascending order.  Odd enties
        -        * are style markers (e.g., PR_COMMENT) that run from that position until
        -        * the end.
        -        * @type {Array.<number|string>}
        -        */
        -      var decorations = [basePos, PR_PLAIN];
        -      var pos = 0;  // index into sourceCode
        -      var tokens = sourceCode.match(tokenizer) || [];
        -      var styleCache = {};
        -
        -      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
        -        var token = tokens[ti];
        -        var style = styleCache[token];
        -        var match = void 0;
        -
        -        var isEmbedded;
        -        if (typeof style === 'string') {
        -          isEmbedded = false;
        -        } else {
        -          var patternParts = shortcuts[token.charAt(0)];
        -          if (patternParts) {
        -            match = token.match(patternParts[1]);
        -            style = patternParts[0];
        -          } else {
        -            for (var i = 0; i < nPatterns; ++i) {
        -              patternParts = fallthroughStylePatterns[i];
        -              match = token.match(patternParts[1]);
        -              if (match) {
        -                style = patternParts[0];
        -                break;
        -              }
        -            }
        -
        -            if (!match) {  // make sure that we make progress
        -              style = PR_PLAIN;
        -            }
        -          }
        -
        -          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
        -          if (isEmbedded && !(match && typeof match[1] === 'string')) {
        -            isEmbedded = false;
        -            style = PR_SOURCE;
        -          }
        -
        -          if (!isEmbedded) { styleCache[token] = style; }
        -        }
        -
        -        var tokenStart = pos;
        -        pos += token.length;
        -
        -        if (!isEmbedded) {
        -          decorations.push(basePos + tokenStart, style);
        -        } else {  // Treat group 1 as an embedded block of source code.
        -          var embeddedSource = match[1];
        -          var embeddedSourceStart = token.indexOf(embeddedSource);
        -          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
        -          if (match[2]) {
        -            // If embeddedSource can be blank, then it would match at the
        -            // beginning which would cause us to infinitely recurse on the
        -            // entire token, so we catch the right context in match[2].
        -            embeddedSourceEnd = token.length - match[2].length;
        -            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
        -          }
        -          var lang = style.substring(5);
        -          // Decorate the left of the embedded source
        -          appendDecorations(
        -              basePos + tokenStart,
        -              token.substring(0, embeddedSourceStart),
        -              decorate, decorations);
        -          // Decorate the embedded source
        -          appendDecorations(
        -              basePos + tokenStart + embeddedSourceStart,
        -              embeddedSource,
        -              langHandlerForExtension(lang, embeddedSource),
        -              decorations);
        -          // Decorate the right of the embedded section
        -          appendDecorations(
        -              basePos + tokenStart + embeddedSourceEnd,
        -              token.substring(embeddedSourceEnd),
        -              decorate, decorations);
        -        }
        -      }
        -      job.decorations = decorations;
        -    };
        -    return decorate;
        -  }
        -
        -  /** returns a function that produces a list of decorations from source text.
        -    *
        -    * This code treats ", ', and ` as string delimiters, and \ as a string
        -    * escape.  It does not recognize perl's qq() style strings.
        -    * It has no special handling for double delimiter escapes as in basic, or
        -    * the tripled delimiters used in python, but should work on those regardless
        -    * although in those cases a single string literal may be broken up into
        -    * multiple adjacent string literals.
        -    *
        -    * It recognizes C, C++, and shell style comments.
        -    *
        -    * @param {Object} options a set of optional parameters.
        -    * @return {function (Object)} a function that examines the source code
        -    *     in the input job and builds the decoration list.
        -    */
        -  function sourceDecorator(options) {
        -    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
        -    if (options['tripleQuotedStrings']) {
        -      // '''multi-line-string''', 'single-line-string', and double-quoted
        -      shortcutStylePatterns.push(
        -          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
        -           null, '\'"']);
        -    } else if (options['multiLineStrings']) {
        -      // 'multi-line-string', "multi-line-string"
        -      shortcutStylePatterns.push(
        -          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
        -           null, '\'"`']);
        -    } else {
        -      // 'single-line-string', "single-line-string"
        -      shortcutStylePatterns.push(
        -          [PR_STRING,
        -           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
        -           null, '"\'']);
        -    }
        -    if (options['verbatimStrings']) {
        -      // verbatim-string-literal production from the C# grammar.  See issue 93.
        -      fallthroughStylePatterns.push(
        -          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
        -    }
        -    if (options['hashComments']) {
        -      if (options['cStyleComments']) {
        -        // Stop C preprocessor declarations at an unclosed open comment
        -        shortcutStylePatterns.push(
        -            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
        -             null, '#']);
        -        fallthroughStylePatterns.push(
        -            [PR_STRING,
        -             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
        -             null]);
        -      } else {
        -        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
        -      }
        -    }
        -    if (options['cStyleComments']) {
        -      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
        -      fallthroughStylePatterns.push(
        -          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
        -    }
        -    if (options['regexLiterals']) {
        -      var REGEX_LITERAL = (
        -          // A regular expression literal starts with a slash that is
        -          // not followed by * or / so that it is not confused with
        -          // comments.
        -          '/(?=[^/*])'
        -          // and then contains any number of raw characters,
        -          + '(?:[^/\\x5B\\x5C]'
        -          // escape sequences (\x5C),
        -          +    '|\\x5C[\\s\\S]'
        -          // or non-nesting character sets (\x5B\x5D);
        -          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
        -          // finally closed by a /.
        -          + '/');
        -      fallthroughStylePatterns.push(
        -          ['lang-regex',
        -           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
        -           ]);
        -    }
        -
        -    var keywords = options['keywords'].replace(/^\s+|\s+$/g, '');
        -    if (keywords.length) {
        -      fallthroughStylePatterns.push(
        -          [PR_KEYWORD,
        -           new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]);
        -    }
        -
        -    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
        -    fallthroughStylePatterns.push(
        -        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
        -        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
        -        [PR_TYPE,        /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],
        -        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
        -        [PR_LITERAL,
        -         new RegExp(
        -             '^(?:'
        -             // A hex number
        -             + '0x[a-f0-9]+'
        -             // or an octal or decimal number,
        -             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
        -             // possibly in scientific notation
        -             + '(?:e[+\\-]?\\d+)?'
        -             + ')'
        -             // with an optional modifier like UL for unsigned long
        -             + '[a-z]*', 'i'),
        -         null, '0123456789'],
        -        [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]);
        -
        -    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
        -  }
        -
        -  var decorateSource = sourceDecorator({
        -        'keywords': ALL_KEYWORDS,
        -        'hashComments': true,
        -        'cStyleComments': true,
        -        'multiLineStrings': true,
        -        'regexLiterals': true
        -      });
        -
        -  /** Breaks {@code job.source} around style boundaries in
        -    * {@code job.decorations} while re-interleaving {@code job.extractedTags},
        -    * and leaves the result in {@code job.prettyPrintedHtml}.
        -    * @param {Object} job like {
        -    *    source: {string} source as plain text,
        -    *    extractedTags: {Array.<number|string>} extractedTags chunks of raw
        -    *                   html preceded by their position in {@code job.source}
        -    *                   in order
        -    *    decorations: {Array.<number|string} an array of style classes preceded
        -    *                 by the position at which they start in job.source in order
        -    * }
        -    * @private
        -    */
        -  function recombineTagsAndDecorations(job) {
        -    var sourceText = job.source;
        -    var extractedTags = job.extractedTags;
        -    var decorations = job.decorations;
        -
        -    var html = [];
        -    // index past the last char in sourceText written to html
        -    var outputIdx = 0;
        -
        -    var openDecoration = null;
        -    var currentDecoration = null;
        -    var tagPos = 0;  // index into extractedTags
        -    var decPos = 0;  // index into decorations
        -    var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);
        -
        -    var adjacentSpaceRe = /([\r\n ]) /g;
        -    var startOrSpaceRe = /(^| ) /gm;
        -    var newlineRe = /\r\n?|\n/g;
        -    var trailingSpaceRe = /[ \r\n]$/;
        -    var lastWasSpace = true;  // the last text chunk emitted ended with a space.
        -
        -    // A helper function that is responsible for opening sections of decoration
        -    // and outputing properly escaped chunks of source
        -    function emitTextUpTo(sourceIdx) {
        -      if (sourceIdx > outputIdx) {
        -        if (openDecoration && openDecoration !== currentDecoration) {
        -          // Close the current decoration
        -          html.push('</span>');
        -          openDecoration = null;
        -        }
        -        if (!openDecoration && currentDecoration) {
        -          openDecoration = currentDecoration;
        -          html.push('<span class="', openDecoration, '">');
        -        }
        -        // This interacts badly with some wikis which introduces paragraph tags
        -        // into pre blocks for some strange reason.
        -        // It's necessary for IE though which seems to lose the preformattedness
        -        // of <pre> tags when their innerHTML is assigned.
        -        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
        -        // and it serves to undo the conversion of <br>s to newlines done in
        -        // chunkify.
        -        var htmlChunk = textToHtml(
        -            tabExpander(sourceText.substring(outputIdx, sourceIdx)))
        -            .replace(lastWasSpace
        -                     ? startOrSpaceRe
        -                     : adjacentSpaceRe, '$1&nbsp;');
        -        // Keep track of whether we need to escape space at the beginning of the
        -        // next chunk.
        -        lastWasSpace = trailingSpaceRe.test(htmlChunk);
        -        // IE collapses multiple adjacient <br>s into 1 line break.
        -        // Prefix every <br> with '&nbsp;' can prevent such IE's behavior.
        -        var lineBreakHtml = window['_pr_isIE6']() ? '&nbsp;<br />' : '<br />';
        -        html.push(htmlChunk.replace(newlineRe, lineBreakHtml));
        -        outputIdx = sourceIdx;
        -      }
        -    }
        -
        -    while (true) {
        -      // Determine if we're going to consume a tag this time around.  Otherwise
        -      // we consume a decoration or exit.
        -      var outputTag;
        -      if (tagPos < extractedTags.length) {
        -        if (decPos < decorations.length) {
        -          // Pick one giving preference to extractedTags since we shouldn't open
        -          // a new style that we're going to have to immediately close in order
        -          // to output a tag.
        -          outputTag = extractedTags[tagPos] <= decorations[decPos];
        -        } else {
        -          outputTag = true;
        -        }
        -      } else {
        -        outputTag = false;
        -      }
        -      // Consume either a decoration or a tag or exit.
        -      if (outputTag) {
        -        emitTextUpTo(extractedTags[tagPos]);
        -        if (openDecoration) {
        -          // Close the current decoration
        -          html.push('</span>');
        -          openDecoration = null;
        -        }
        -        html.push(extractedTags[tagPos + 1]);
        -        tagPos += 2;
        -      } else if (decPos < decorations.length) {
        -        emitTextUpTo(decorations[decPos]);
        -        currentDecoration = decorations[decPos + 1];
        -        decPos += 2;
        -      } else {
        -        break;
        -      }
        -    }
        -    emitTextUpTo(sourceText.length);
        -    if (openDecoration) {
        -      html.push('</span>');
        -    }
        -    job.prettyPrintedHtml = html.join('');
        -  }
        -
        -  /** Maps language-specific file extensions to handlers. */
        -  var langHandlerRegistry = {};
        -  /** Register a language handler for the given file extensions.
        -    * @param {function (Object)} handler a function from source code to a list
        -    *      of decorations.  Takes a single argument job which describes the
        -    *      state of the computation.   The single parameter has the form
        -    *      {@code {
        -    *        source: {string} as plain text.
        -    *        decorations: {Array.<number|string>} an array of style classes
        -    *                     preceded by the position at which they start in
        -    *                     job.source in order.
        -    *                     The language handler should assigned this field.
        -    *        basePos: {int} the position of source in the larger source chunk.
        -    *                 All positions in the output decorations array are relative
        -    *                 to the larger source chunk.
        -    *      } }
        -    * @param {Array.<string>} fileExtensions
        -    */
        -  function registerLangHandler(handler, fileExtensions) {
        -    for (var i = fileExtensions.length; --i >= 0;) {
        -      var ext = fileExtensions[i];
        -      if (!langHandlerRegistry.hasOwnProperty(ext)) {
        -        langHandlerRegistry[ext] = handler;
        -      } else if ('console' in window) {
        -        console.warn('cannot override language handler %s', ext);
        -      }
        -    }
        -  }
        -  function langHandlerForExtension(extension, source) {
        -    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
        -      // Treat it as markup if the first non whitespace character is a < and
        -      // the last non-whitespace character is a >.
        -      extension = /^\s*</.test(source)
        -          ? 'default-markup'
        -          : 'default-code';
        -    }
        -    return langHandlerRegistry[extension];
        -  }
        -  registerLangHandler(decorateSource, ['default-code']);
        -  registerLangHandler(
        -      createSimpleLexer(
        -          [],
        -          [
        -           [PR_PLAIN,       /^[^<?]+/],
        -           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
        -           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
        -           // Unescaped content in an unknown language
        -           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
        -           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
        -           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
        -           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
        -           // Unescaped content in javascript.  (Or possibly vbscript).
        -           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
        -           // Contains unescaped stylesheet content
        -           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
        -           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
        -          ]),
        -      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
        -  registerLangHandler(
        -      createSimpleLexer(
        -          [
        -           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
        -           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
        -           ],
        -          [
        -           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
        -           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
        -           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
        -           [PR_PUNCTUATION,  /^[=<>\/]+/],
        -           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
        -           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
        -           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
        -           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
        -           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
        -           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
        -           ]),
        -      ['in.tag']);
        -  registerLangHandler(
        -      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': CPP_KEYWORDS,
        -          'hashComments': true,
        -          'cStyleComments': true
        -        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': 'null true false'
        -        }), ['json']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': CSHARP_KEYWORDS,
        -          'hashComments': true,
        -          'cStyleComments': true,
        -          'verbatimStrings': true
        -        }), ['cs']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': JAVA_KEYWORDS,
        -          'cStyleComments': true
        -        }), ['java']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': SH_KEYWORDS,
        -          'hashComments': true,
        -          'multiLineStrings': true
        -        }), ['bsh', 'csh', 'sh']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': PYTHON_KEYWORDS,
        -          'hashComments': true,
        -          'multiLineStrings': true,
        -          'tripleQuotedStrings': true
        -        }), ['cv', 'py']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': PERL_KEYWORDS,
        -          'hashComments': true,
        -          'multiLineStrings': true,
        -          'regexLiterals': true
        -        }), ['perl', 'pl', 'pm']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': RUBY_KEYWORDS,
        -          'hashComments': true,
        -          'multiLineStrings': true,
        -          'regexLiterals': true
        -        }), ['rb']);
        -  registerLangHandler(sourceDecorator({
        -          'keywords': JSCRIPT_KEYWORDS,
        -          'cStyleComments': true,
        -          'regexLiterals': true
        -        }), ['js']);
        -  registerLangHandler(
        -      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
        -
        -  function applyDecorator(job) {
        -    var sourceCodeHtml = job.sourceCodeHtml;
        -    var opt_langExtension = job.langExtension;
        -
        -    // Prepopulate output in case processing fails with an exception.
        -    job.prettyPrintedHtml = sourceCodeHtml;
        -
        -    try {
        -      // Extract tags, and convert the source code to plain text.
        -      var sourceAndExtractedTags = extractTags(sourceCodeHtml);
        -      /** Plain text. @type {string} */
        -      var source = sourceAndExtractedTags.source;
        -      job.source = source;
        -      job.basePos = 0;
        -
        -      /** Even entries are positions in source in ascending order.  Odd entries
        -        * are tags that were extracted at that position.
        -        * @type {Array.<number|string>}
        -        */
        -      job.extractedTags = sourceAndExtractedTags.tags;
        -
        -      // Apply the appropriate language handler
        -      langHandlerForExtension(opt_langExtension, source)(job);
        -      // Integrate the decorations and tags back into the source code to produce
        -      // a decorated html string which is left in job.prettyPrintedHtml.
        -      recombineTagsAndDecorations(job);
        -    } catch (e) {
        -      if ('console' in window) {
        -        console.log(e);
        -        console.trace();
        -      }
        -    }
        -  }
        -
        -  function prettyPrintOne(sourceCodeHtml, opt_langExtension) {
        -    var job = {
        -      sourceCodeHtml: sourceCodeHtml,
        -      langExtension: opt_langExtension
        -    };
        -    applyDecorator(job);
        -    return job.prettyPrintedHtml;
        -  }
        -
        -  function prettyPrint(opt_whenDone) {
        -    var isIE678 = window['_pr_isIE6']();
        -    var ieNewline = isIE678 === 6 ? '\r\n' : '\r';
        -    // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-
        -
        -    // fetch a list of nodes to rewrite
        -    var codeSegments = [
        -        document.getElementsByTagName('pre'),
        -        document.getElementsByTagName('code'),
        -        document.getElementsByTagName('td'),  /* ND Change: Add tables to support prototypes. */
        -        document.getElementsByTagName('xmp') ];
        -    var elements = [];
        -    for (var i = 0; i < codeSegments.length; ++i) {
        -      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
        -        elements.push(codeSegments[i][j]);
        -      }
        -    }
        -    codeSegments = null;
        -
        -    var clock = Date;
        -    if (!clock['now']) {
        -      clock = { 'now': function () { return (new Date).getTime(); } };
        -    }
        -
        -    // The loop is broken into a series of continuations to make sure that we
        -    // don't make the browser unresponsive when rewriting a large page.
        -    var k = 0;
        -    var prettyPrintingJob;
        -
        -    function doWork() {
        -      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
        -                     clock.now() + 250 /* ms */ :
        -                     Infinity);
        -      for (; k < elements.length && clock.now() < endTime; k++) {
        -        var cs = elements[k];
        -        if (cs.className && cs.className.indexOf('prettyprint') >= 0) {
        -          // If the classes includes a language extensions, use it.
        -          // Language extensions can be specified like
        -          //     <pre class="prettyprint lang-cpp">
        -          // the language extension "cpp" is used to find a language handler as
        -          // passed to PR_registerLangHandler.
        -          var langExtension = cs.className.match(/\blang-(\w+)\b/);
        -          if (langExtension) { langExtension = langExtension[1]; }
        -
        -          // make sure this is not nested in an already prettified element
        -          var nested = false;
        -          for (var p = cs.parentNode; p; p = p.parentNode) {
        -            if ((p.tagName === 'pre' || p.tagName === 'code' ||
        -                 p.tagName === 'xmp' || p.tagName === 'td') &&  /* ND Change: Add tables to support prototypes */
        -                p.className && p.className.indexOf('prettyprint') >= 0) {
        -              nested = true;
        -              break;
        -            }
        -          }
        -          if (!nested) {
        -            // fetch the content as a snippet of properly escaped HTML.
        -            // Firefox adds newlines at the end.
        -            var content = getInnerHtml(cs);
        -            content = content.replace(/(?:\r\n?|\n)$/, '');
        -
        -	  		/* ND Change: we need to preserve &nbsp;s so change them to a special character instead of a space. */
        -			content = content.replace(/&nbsp;/g, '\x11');
        -
        -            // do the pretty printing
        -            prettyPrintingJob = {
        -              sourceCodeHtml: content,
        -              langExtension: langExtension,
        -              sourceNode: cs
        -            };
        -            applyDecorator(prettyPrintingJob);
        -            replaceWithPrettyPrintedHtml();
        -          }
        -        }
        -      }
        -      if (k < elements.length) {
        -        // finish up in a continuation
        -        setTimeout(doWork, 250);
        -      } else if (opt_whenDone) {
        -        opt_whenDone();
        -      }
        -    }
        -
        -    function replaceWithPrettyPrintedHtml() {
        -      var newContent = prettyPrintingJob.prettyPrintedHtml;
        -      if (!newContent) { return; }
        -
        -      /* ND Change: Restore the preserved &nbsp;s.  */
        -	  newContent = newContent.replace(/\x11/g, '&nbsp;');
        -
        -      var cs = prettyPrintingJob.sourceNode;
        -
        -      // push the prettified html back into the tag.
        -      if (!isRawContent(cs)) {
        -        // just replace the old html with the new
        -        cs.innerHTML = newContent;
        -      } else {
        -        // we need to change the tag to a <pre> since <xmp>s do not allow
        -        // embedded tags such as the span tags used to attach styles to
        -        // sections of source code.
        -        var pre = document.createElement('PRE');
        -        for (var i = 0; i < cs.attributes.length; ++i) {
        -          var a = cs.attributes[i];
        -          if (a.specified) {
        -            var aname = a.name.toLowerCase();
        -            if (aname === 'class') {
        -              pre.className = a.value;  // For IE 6
        -            } else {
        -              pre.setAttribute(a.name, a.value);
        -            }
        -          }
        -        }
        -        pre.innerHTML = newContent;
        -
        -        // remove the old
        -        cs.parentNode.replaceChild(pre, cs);
        -        cs = pre;
        -      }
        -
        -      // Replace <br>s with line-feeds so that copying and pasting works
        -      // on IE 6.
        -      // Doing this on other browsers breaks lots of stuff since \r\n is
        -      // treated as two newlines on Firefox, and doing this also slows
        -      // down rendering.
        -      if (isIE678 && cs.tagName === 'PRE') {
        -        var lineBreaks = cs.getElementsByTagName('br');
        -        for (var j = lineBreaks.length; --j >= 0;) {
        -          var lineBreak = lineBreaks[j];
        -          lineBreak.parentNode.replaceChild(
        -              document.createTextNode(ieNewline), lineBreak);
        -        }
        -      }
        -    }
        -
        -    doWork();
        -  }
        -
        -  window['PR_normalizedHtml'] = normalizedHtml;
        -  window['prettyPrintOne'] = prettyPrintOne;
        -  window['prettyPrint'] = prettyPrint;
        -  window['PR'] = {
        -        'combinePrefixPatterns': combinePrefixPatterns,
        -        'createSimpleLexer': createSimpleLexer,
        -        'registerLangHandler': registerLangHandler,
        -        'sourceDecorator': sourceDecorator,
        -        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
        -        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
        -        'PR_COMMENT': PR_COMMENT,
        -        'PR_DECLARATION': PR_DECLARATION,
        -        'PR_KEYWORD': PR_KEYWORD,
        -        'PR_LITERAL': PR_LITERAL,
        -        'PR_NOCODE': PR_NOCODE,
        -        'PR_PLAIN': PR_PLAIN,
        -        'PR_PUNCTUATION': PR_PUNCTUATION,
        -        'PR_SOURCE': PR_SOURCE,
        -        'PR_STRING': PR_STRING,
        -        'PR_TAG': PR_TAG,
        -        'PR_TYPE': PR_TYPE
        -      };
        -})();
        -
        -
        -// ____________________________________________________________________________
        -
        -
        -
        -// Lua extension
        -
        -PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],[PR.PR_STRING,/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],[PR.PR_KEYWORD,/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_]\w*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),['lua'])
        -
        -
        -// Haskell extension
        -
        -PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\x0B\x0C\r ]+/,null,'	\n\r '],[PR.PR_STRING,/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'\"'],[PR.PR_STRING,/^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,null,'\''],[PR.PR_LITERAL,/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,'0123456789']],[[PR.PR_COMMENT,/^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],[PR.PR_KEYWORD,/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/,null],[PR.PR_PLAIN,/^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],[PR.PR_PUNCTUATION,/^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]]),['hs'])
        -
        -
        -// ML extension
        -
        -PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_COMMENT,/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,'#'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],[PR.PR_KEYWORD,/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],[PR.PR_LITERAL,/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^(?:[a-z_]\w*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],[PR.PR_PUNCTUATION,/^[^\t\n\r \xA0\"\'\w]+/]]),['fs','ml'])
        -
        -
        -// SQL extension
        -
        -PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_STRING,/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],[PR.PR_KEYWORD,/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_][\w-]*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),['sql'])
        -
        -
        -// VB extension
        -
        -PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0\u2028\u2029]+/,null,'	\n\r \xa0\u2028\u2029'],[PR.PR_STRING,/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'\"\u201c\u201d'],[PR.PR_COMMENT,/^[\'\u2018\u2019][^\r\n\u2028\u2029]*/,null,'\'\u2018\u2019']],[[PR.PR_KEYWORD,/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,null],[PR.PR_COMMENT,/^REM[^\r\n\u2028\u2029]*/i],[PR.PR_LITERAL,/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],[PR.PR_PLAIN,/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],[PR.PR_PUNCTUATION,/^(?:\[|\])/]]),['vb','vbs'])
        diff --git a/vendor/naturaldocs/JavaScript/NaturalDocs.js b/vendor/naturaldocs/JavaScript/NaturalDocs.js
        deleted file mode 100644
        index 3f42acde6..000000000
        --- a/vendor/naturaldocs/JavaScript/NaturalDocs.js
        +++ /dev/null
        @@ -1,841 +0,0 @@
        -// This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -// Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -// Refer to License.txt for the complete details
        -
        -// This file may be distributed with documentation files generated by Natural Docs.
        -// Such documentation is not covered by Natural Docs' copyright and licensing,
        -// and may have its own copyright and distribution terms as decided by its author.
        -
        -
        -//
        -//  Browser Styles
        -// ____________________________________________________________________________
        -
        -var agt=navigator.userAgent.toLowerCase();
        -var browserType;
        -var browserVer;
        -
        -if (agt.indexOf("opera") != -1)
        -    {
        -    browserType = "Opera";
        -
        -    if (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1)
        -        {  browserVer = "Opera7";  }
        -    else if (agt.indexOf("opera 8") != -1 || agt.indexOf("opera/8") != -1)
        -        {  browserVer = "Opera8";  }
        -    else if (agt.indexOf("opera 9") != -1 || agt.indexOf("opera/9") != -1)
        -        {  browserVer = "Opera9";  }
        -    }
        -
        -else if (agt.indexOf("applewebkit") != -1)
        -    {
        -    browserType = "Safari";
        -
        -    if (agt.indexOf("version/3") != -1)
        -        {  browserVer = "Safari3";  }
        -    else if (agt.indexOf("safari/4") != -1)
        -        {  browserVer = "Safari2";  }
        -    }
        -
        -else if (agt.indexOf("khtml") != -1)
        -    {
        -    browserType = "Konqueror";
        -    }
        -
        -else if (agt.indexOf("msie") != -1)
        -    {
        -    browserType = "IE";
        -
        -    if (agt.indexOf("msie 6") != -1)
        -        {  browserVer = "IE6";  }
        -    else if (agt.indexOf("msie 7") != -1)
        -        {  browserVer = "IE7";  }
        -    }
        -
        -else if (agt.indexOf("gecko") != -1)
        -    {
        -    browserType = "Firefox";
        -
        -    if (agt.indexOf("rv:1.7") != -1)
        -        {  browserVer = "Firefox1";  }
        -    else if (agt.indexOf("rv:1.8)") != -1 || agt.indexOf("rv:1.8.0") != -1)
        -        {  browserVer = "Firefox15";  }
        -    else if (agt.indexOf("rv:1.8.1") != -1)
        -        {  browserVer = "Firefox2";  }
        -    }
        -
        -
        -//
        -//  Support Functions
        -// ____________________________________________________________________________
        -
        -
        -function GetXPosition(item)
        -    {
        -    var position = 0;
        -
        -    if (item.offsetWidth != null)
        -        {
        -        while (item != document.body && item != null)
        -            {
        -            position += item.offsetLeft;
        -            item = item.offsetParent;
        -            };
        -        };
        -
        -    return position;
        -    };
        -
        -
        -function GetYPosition(item)
        -    {
        -    var position = 0;
        -
        -    if (item.offsetWidth != null)
        -        {
        -        while (item != document.body && item != null)
        -            {
        -            position += item.offsetTop;
        -            item = item.offsetParent;
        -            };
        -        };
        -
        -    return position;
        -    };
        -
        -
        -function MoveToPosition(item, x, y)
        -    {
        -    // Opera 5 chokes on the px extension, so it can use the Microsoft one instead.
        -
        -    if (item.style.left != null)
        -        {
        -        item.style.left = x + "px";
        -        item.style.top = y + "px";
        -        }
        -    else if (item.style.pixelLeft != null)
        -        {
        -        item.style.pixelLeft = x;
        -        item.style.pixelTop = y;
        -        };
        -    };
        -
        -
        -//
        -//  Menu
        -// ____________________________________________________________________________
        -
        -
        -function ToggleMenu(id)
        -    {
        -    if (!window.document.getElementById)
        -        {  return;  };
        -
        -    var display = window.document.getElementById(id).style.display;
        -
        -    if (display == "none")
        -        {  display = "block";  }
        -    else
        -        {  display = "none";  }
        -
        -    window.document.getElementById(id).style.display = display;
        -    }
        -
        -function HideAllBut(ids, max)
        -    {
        -    if (document.getElementById)
        -        {
        -        ids.sort( function(a,b) { return a - b; } );
        -        var number = 1;
        -
        -        while (number < max)
        -            {
        -            if (ids.length > 0 && number == ids[0])
        -                {  ids.shift();  }
        -            else
        -                {
        -                document.getElementById("MGroupContent" + number).style.display = "none";
        -                };
        -
        -            number++;
        -            };
        -        };
        -    }
        -
        -
        -//
        -//  Tooltips
        -// ____________________________________________________________________________
        -
        -
        -var tooltipTimer = 0;
        -
        -function ShowTip(event, tooltipID, linkID)
        -    {
        -    if (tooltipTimer)
        -        {  clearTimeout(tooltipTimer);  };
        -
        -    var docX = event.clientX + window.pageXOffset;
        -    var docY = event.clientY + window.pageYOffset;
        -
        -    var showCommand = "ReallyShowTip('" + tooltipID + "', '" + linkID + "', " + docX + ", " + docY + ")";
        -
        -    tooltipTimer = setTimeout(showCommand, 1000);
        -    }
        -
        -function ReallyShowTip(tooltipID, linkID, docX, docY)
        -    {
        -    tooltipTimer = 0;
        -
        -    var tooltip;
        -    var link;
        -
        -    if (document.getElementById)
        -        {
        -        tooltip = document.getElementById(tooltipID);
        -        link = document.getElementById(linkID);
        -        }
        -/*    else if (document.all)
        -        {
        -        tooltip = eval("document.all['" + tooltipID + "']");
        -        link = eval("document.all['" + linkID + "']");
        -        }
        -*/
        -    if (tooltip)
        -        {
        -        var left = GetXPosition(link);
        -        var top = GetYPosition(link);
        -        top += link.offsetHeight;
        -
        -
        -        // The fallback method is to use the mouse X and Y relative to the document.  We use a separate if and test if its a number
        -        // in case some browser snuck through the above if statement but didn't support everything.
        -
        -        if (!isFinite(top) || top == 0)
        -            {
        -            left = docX;
        -            top = docY;
        -            }
        -
        -        // Some spacing to get it out from under the cursor.
        -
        -        top += 10;
        -
        -        // Make sure the tooltip doesnt get smushed by being too close to the edge, or in some browsers, go off the edge of the
        -        // page.  We do it here because Konqueror does get offsetWidth right even if it doesnt get the positioning right.
        -
        -        if (tooltip.offsetWidth != null)
        -            {
        -            var width = tooltip.offsetWidth;
        -            var docWidth = document.body.clientWidth;
        -
        -            if (left + width > docWidth)
        -                {  left = docWidth - width - 1;  }
        -
        -            // If there's a horizontal scroll bar we could go past zero because it's using the page width, not the window width.
        -            if (left < 0)
        -                {  left = 0;  };
        -            }
        -
        -        MoveToPosition(tooltip, left, top);
        -        tooltip.style.visibility = "visible";
        -        }
        -    }
        -
        -function HideTip(tooltipID)
        -    {
        -    if (tooltipTimer)
        -        {
        -        clearTimeout(tooltipTimer);
        -        tooltipTimer = 0;
        -        }
        -
        -    var tooltip;
        -
        -    if (document.getElementById)
        -        {  tooltip = document.getElementById(tooltipID); }
        -    else if (document.all)
        -        {  tooltip = eval("document.all['" + tooltipID + "']");  }
        -
        -    if (tooltip)
        -        {  tooltip.style.visibility = "hidden";  }
        -    }
        -
        -
        -//
        -//  Blockquote fix for IE
        -// ____________________________________________________________________________
        -
        -
        -function NDOnLoad()
        -    {
        -    if (browserVer == "IE6")
        -        {
        -        var scrollboxes = document.getElementsByTagName('blockquote');
        -
        -        if (scrollboxes.item(0))
        -            {
        -            NDDoResize();
        -            window.onresize=NDOnResize;
        -            };
        -        };
        -    };
        -
        -
        -var resizeTimer = 0;
        -
        -function NDOnResize()
        -    {
        -    if (resizeTimer != 0)
        -        {  clearTimeout(resizeTimer);  };
        -
        -    resizeTimer = setTimeout(NDDoResize, 250);
        -    };
        -
        -
        -function NDDoResize()
        -    {
        -    var scrollboxes = document.getElementsByTagName('blockquote');
        -
        -    var i;
        -    var item;
        -
        -    i = 0;
        -    while (item = scrollboxes.item(i))
        -        {
        -        item.style.width = 100;
        -        i++;
        -        };
        -
        -    i = 0;
        -    while (item = scrollboxes.item(i))
        -        {
        -        item.style.width = item.parentNode.offsetWidth;
        -        i++;
        -        };
        -
        -    clearTimeout(resizeTimer);
        -    resizeTimer = 0;
        -    }
        -
        -
        -
        -/* ________________________________________________________________________________________________________
        -
        -    Class: SearchPanel
        -    ________________________________________________________________________________________________________
        -
        -    A class handling everything associated with the search panel.
        -
        -    Parameters:
        -
        -        name - The name of the global variable that will be storing this instance.  Is needed to be able to set timeouts.
        -        mode - The mode the search is going to work in.  Pass <NaturalDocs::Builder::Base->CommandLineOption()>, so the
        -                   value will be something like "HTML" or "FramedHTML".
        -
        -    ________________________________________________________________________________________________________
        -*/
        -
        -
        -function SearchPanel(name, mode, resultsPath)
        -    {
        -    if (!name || !mode || !resultsPath)
        -        {  alert("Incorrect parameters to SearchPanel.");  };
        -
        -
        -    // Group: Variables
        -    // ________________________________________________________________________
        -
        -    /*
        -        var: name
        -        The name of the global variable that will be storing this instance of the class.
        -    */
        -    this.name = name;
        -
        -    /*
        -        var: mode
        -        The mode the search is going to work in, such as "HTML" or "FramedHTML".
        -    */
        -    this.mode = mode;
        -
        -    /*
        -        var: resultsPath
        -        The relative path from the current HTML page to the results page directory.
        -    */
        -    this.resultsPath = resultsPath;
        -
        -    /*
        -        var: keyTimeout
        -        The timeout used between a keystroke and when a search is performed.
        -    */
        -    this.keyTimeout = 0;
        -
        -    /*
        -        var: keyTimeoutLength
        -        The length of <keyTimeout> in thousandths of a second.
        -    */
        -    this.keyTimeoutLength = 500;
        -
        -    /*
        -        var: lastSearchValue
        -        The last search string executed, or an empty string if none.
        -    */
        -    this.lastSearchValue = "";
        -
        -    /*
        -        var: lastResultsPage
        -        The last results page.  The value is only relevant if <lastSearchValue> is set.
        -    */
        -    this.lastResultsPage = "";
        -
        -    /*
        -        var: deactivateTimeout
        -
        -        The timeout used between when a control is deactivated and when the entire panel is deactivated.  Is necessary
        -        because a control may be deactivated in favor of another control in the same panel, in which case it should stay
        -        active.
        -    */
        -    this.deactivateTimout = 0;
        -
        -    /*
        -        var: deactivateTimeoutLength
        -        The length of <deactivateTimeout> in thousandths of a second.
        -    */
        -    this.deactivateTimeoutLength = 200;
        -
        -
        -
        -
        -    // Group: DOM Elements
        -    // ________________________________________________________________________
        -
        -
        -    // Function: DOMSearchField
        -    this.DOMSearchField = function()
        -        {  return document.getElementById("MSearchField");  };
        -
        -    // Function: DOMSearchType
        -    this.DOMSearchType = function()
        -        {  return document.getElementById("MSearchType");  };
        -
        -    // Function: DOMPopupSearchResults
        -    this.DOMPopupSearchResults = function()
        -        {  return document.getElementById("MSearchResults");  };
        -
        -    // Function: DOMPopupSearchResultsWindow
        -    this.DOMPopupSearchResultsWindow = function()
        -        {  return document.getElementById("MSearchResultsWindow");  };
        -
        -    // Function: DOMSearchPanel
        -    this.DOMSearchPanel = function()
        -        {  return document.getElementById("MSearchPanel");  };
        -
        -
        -
        -
        -    // Group: Event Handlers
        -    // ________________________________________________________________________
        -
        -
        -    /*
        -        Function: OnSearchFieldFocus
        -        Called when focus is added or removed from the search field.
        -    */
        -    this.OnSearchFieldFocus = function(isActive)
        -        {
        -        this.Activate(isActive);
        -        };
        -
        -
        -    /*
        -        Function: OnSearchFieldChange
        -        Called when the content of the search field is changed.
        -    */
        -    this.OnSearchFieldChange = function()
        -        {
        -        if (this.keyTimeout)
        -            {
        -            clearTimeout(this.keyTimeout);
        -            this.keyTimeout = 0;
        -            };
        -
        -        var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
        -
        -        if (searchValue != this.lastSearchValue)
        -            {
        -            if (searchValue != "")
        -                {
        -                this.keyTimeout = setTimeout(this.name + ".Search()", this.keyTimeoutLength);
        -                }
        -            else
        -                {
        -                if (this.mode == "HTML")
        -                    {  this.DOMPopupSearchResultsWindow().style.display = "none";  };
        -                this.lastSearchValue = "";
        -                };
        -            };
        -        };
        -
        -
        -    /*
        -        Function: OnSearchTypeFocus
        -        Called when focus is added or removed from the search type.
        -    */
        -    this.OnSearchTypeFocus = function(isActive)
        -        {
        -        this.Activate(isActive);
        -        };
        -
        -
        -    /*
        -        Function: OnSearchTypeChange
        -        Called when the search type is changed.
        -    */
        -    this.OnSearchTypeChange = function()
        -        {
        -        var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
        -
        -        if (searchValue != "")
        -            {
        -            this.Search();
        -            };
        -        };
        -
        -
        -
        -    // Group: Action Functions
        -    // ________________________________________________________________________
        -
        -
        -    /*
        -        Function: CloseResultsWindow
        -        Closes the results window.
        -    */
        -    this.CloseResultsWindow = function()
        -        {
        -        this.DOMPopupSearchResultsWindow().style.display = "none";
        -        this.Activate(false, true);
        -        };
        -
        -
        -    /*
        -        Function: Search
        -        Performs a search.
        -    */
        -    this.Search = function()
        -        {
        -        this.keyTimeout = 0;
        -
        -        var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
        -        var searchTopic = this.DOMSearchType().value;
        -
        -        var pageExtension = searchValue.substr(0,1);
        -
        -        if (pageExtension.match(/^[a-z]/i))
        -            {  pageExtension = pageExtension.toUpperCase();  }
        -        else if (pageExtension.match(/^[0-9]/))
        -            {  pageExtension = 'Numbers';  }
        -        else
        -            {  pageExtension = "Symbols";  };
        -
        -        var resultsPage;
        -        var resultsPageWithSearch;
        -        var hasResultsPage;
        -
        -        // indexSectionsWithContent is defined in searchdata.js
        -        if (indexSectionsWithContent[searchTopic][pageExtension] == true)
        -            {
        -            resultsPage = this.resultsPath + '/' + searchTopic + pageExtension + '.html';
        -            resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
        -            hasResultsPage = true;
        -            }
        -        else
        -            {
        -            resultsPage = this.resultsPath + '/NoResults.html';
        -            resultsPageWithSearch = resultsPage;
        -            hasResultsPage = false;
        -            };
        -
        -        var resultsFrame;
        -        if (this.mode == "HTML")
        -            {  resultsFrame = window.frames.MSearchResults;  }
        -        else if (this.mode == "FramedHTML")
        -            {  resultsFrame = window.top.frames['Content'];  };
        -
        -
        -        if (resultsPage != this.lastResultsPage ||
        -
        -            // Bug in IE.  If everything becomes hidden in a run, none of them will be able to be reshown in the next for some
        -            // reason.  It counts the right number of results, and you can even read the display as "block" after setting it, but it
        -            // just doesn't work in IE 6 or IE 7.  So if we're on the right page but the previous search had no results, reload the
        -            // page anyway to get around the bug.
        -            (browserType == "IE" && hasResultsPage &&
        -            	(!resultsFrame.searchResults || resultsFrame.searchResults.lastMatchCount == 0)) )
        -
        -            {
        -            resultsFrame.location.href = resultsPageWithSearch;
        -            }
        -
        -        // So if the results page is right and there's no IE bug, reperform the search on the existing page.  We have to check if there
        -        // are results because NoResults.html doesn't have any JavaScript, and it would be useless to do anything on that page even
        -        // if it did.
        -        else if (hasResultsPage)
        -            {
        -            // We need to check if this exists in case the frame is present but didn't finish loading.
        -            if (resultsFrame.searchResults)
        -                {  resultsFrame.searchResults.Search(searchValue);  }
        -
        -            // Otherwise just reload instead of waiting.
        -            else
        -                {  resultsFrame.location.href = resultsPageWithSearch;  };
        -            };
        -
        -
        -        var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
        -
        -        if (this.mode == "HTML" && domPopupSearchResultsWindow.style.display != "block")
        -            {
        -            var domSearchType = this.DOMSearchType();
        -
        -            var left = GetXPosition(domSearchType);
        -            var top = GetYPosition(domSearchType) + domSearchType.offsetHeight;
        -
        -            MoveToPosition(domPopupSearchResultsWindow, left, top);
        -            domPopupSearchResultsWindow.style.display = 'block';
        -            };
        -
        -
        -        this.lastSearchValue = searchValue;
        -        this.lastResultsPage = resultsPage;
        -        };
        -
        -
        -
        -    // Group: Activation Functions
        -    // Functions that handle whether the entire panel is active or not.
        -    // ________________________________________________________________________
        -
        -
        -    /*
        -        Function: Activate
        -
        -        Activates or deactivates the search panel, resetting things to their default values if necessary.  You can call this on every
        -        control's OnBlur() and it will handle not deactivating the entire panel when focus is just switching between them transparently.
        -
        -        Parameters:
        -
        -            isActive - Whether you're activating or deactivating the panel.
        -            ignoreDeactivateDelay - Set if you're positive the action will deactivate the panel and thus want to skip the delay.
        -    */
        -    this.Activate = function(isActive, ignoreDeactivateDelay)
        -        {
        -        // We want to ignore isActive being false while the results window is open.
        -        if (isActive || (this.mode == "HTML" && this.DOMPopupSearchResultsWindow().style.display == "block"))
        -            {
        -            if (this.inactivateTimeout)
        -                {
        -                clearTimeout(this.inactivateTimeout);
        -                this.inactivateTimeout = 0;
        -                };
        -
        -            this.DOMSearchPanel().className = 'MSearchPanelActive';
        -
        -            var searchField = this.DOMSearchField();
        -
        -            if (searchField.value == 'Search')
        -                 {  searchField.value = "";  }
        -            }
        -        else if (!ignoreDeactivateDelay)
        -            {
        -            this.inactivateTimeout = setTimeout(this.name + ".InactivateAfterTimeout()", this.inactivateTimeoutLength);
        -            }
        -        else
        -            {
        -            this.InactivateAfterTimeout();
        -            };
        -        };
        -
        -
        -    /*
        -        Function: InactivateAfterTimeout
        -
        -        Called by <inactivateTimeout>, which is set by <Activate()>.  Inactivation occurs on a timeout because a control may
        -        receive OnBlur() when focus is really transferring to another control in the search panel.  In this case we don't want to
        -        actually deactivate the panel because not only would that cause a visible flicker but it could also reset the search value.
        -        So by doing it on a timeout instead, there's a short period where the second control's OnFocus() can cancel the deactivation.
        -    */
        -    this.InactivateAfterTimeout = function()
        -        {
        -        this.inactivateTimeout = 0;
        -
        -        this.DOMSearchPanel().className = 'MSearchPanelInactive';
        -        this.DOMSearchField().value = "Search";
        -
        -	    this.lastSearchValue = "";
        -	    this.lastResultsPage = "";
        -        };
        -    };
        -
        -
        -
        -
        -/* ________________________________________________________________________________________________________
        -
        -   Class: SearchResults
        -   _________________________________________________________________________________________________________
        -
        -   The class that handles everything on the search results page.
        -   _________________________________________________________________________________________________________
        -*/
        -
        -
        -function SearchResults(name, mode)
        -    {
        -    /*
        -        var: mode
        -        The mode the search is going to work in, such as "HTML" or "FramedHTML".
        -    */
        -    this.mode = mode;
        -
        -    /*
        -        var: lastMatchCount
        -        The number of matches from the last run of <Search()>.
        -    */
        -    this.lastMatchCount = 0;
        -
        -
        -    /*
        -        Function: Toggle
        -        Toggles the visibility of the passed element ID.
        -    */
        -    this.Toggle = function(id)
        -        {
        -        if (this.mode == "FramedHTML")
        -            {  return;  };
        -
        -        var parentElement = document.getElementById(id);
        -
        -        var element = parentElement.firstChild;
        -
        -        while (element && element != parentElement)
        -            {
        -            if (element.nodeName == 'DIV' && element.className == 'ISubIndex')
        -                {
        -                if (element.style.display == 'block')
        -                    {  element.style.display = "none";  }
        -                else
        -                    {  element.style.display = 'block';  }
        -                };
        -
        -            if (element.nodeName == 'DIV' && element.hasChildNodes())
        -                {  element = element.firstChild;  }
        -            else if (element.nextSibling)
        -                {  element = element.nextSibling;  }
        -            else
        -                {
        -                do
        -                    {
        -                    element = element.parentNode;
        -                    }
        -                while (element && element != parentElement && !element.nextSibling);
        -
        -                if (element && element != parentElement)
        -                    {  element = element.nextSibling;  };
        -                };
        -            };
        -        };
        -
        -
        -    /*
        -        Function: Search
        -
        -        Searches for the passed string.  If there is no parameter, it takes it from the URL query.
        -
        -        Always returns true, since other documents may try to call it and that may or may not be possible.
        -    */
        -    this.Search = function(search)
        -        {
        -        if (!search)
        -            {
        -            search = window.location.search;
        -            search = search.substring(1);  // Remove the leading ?
        -            search = unescape(search);
        -            };
        -
        -        search = search.replace(/^ +/, "");
        -        search = search.replace(/ +$/, "");
        -        search = search.toLowerCase();
        -
        -        if (search.match(/[^a-z0-9]/)) // Just a little speedup so it doesn't have to go through the below unnecessarily.
        -            {
        -            search = search.replace(/\_/g, "_und");
        -            search = search.replace(/\ +/gi, "_spc");
        -            search = search.replace(/\~/g, "_til");
        -            search = search.replace(/\!/g, "_exc");
        -            search = search.replace(/\@/g, "_att");
        -            search = search.replace(/\#/g, "_num");
        -            search = search.replace(/\$/g, "_dol");
        -            search = search.replace(/\%/g, "_pct");
        -            search = search.replace(/\^/g, "_car");
        -            search = search.replace(/\&/g, "_amp");
        -            search = search.replace(/\*/g, "_ast");
        -            search = search.replace(/\(/g, "_lpa");
        -            search = search.replace(/\)/g, "_rpa");
        -            search = search.replace(/\-/g, "_min");
        -            search = search.replace(/\+/g, "_plu");
        -            search = search.replace(/\=/g, "_equ");
        -            search = search.replace(/\{/g, "_lbc");
        -            search = search.replace(/\}/g, "_rbc");
        -            search = search.replace(/\[/g, "_lbk");
        -            search = search.replace(/\]/g, "_rbk");
        -            search = search.replace(/\:/g, "_col");
        -            search = search.replace(/\;/g, "_sco");
        -            search = search.replace(/\"/g, "_quo");
        -            search = search.replace(/\'/g, "_apo");
        -            search = search.replace(/\</g, "_lan");
        -            search = search.replace(/\>/g, "_ran");
        -            search = search.replace(/\,/g, "_com");
        -            search = search.replace(/\./g, "_per");
        -            search = search.replace(/\?/g, "_que");
        -            search = search.replace(/\//g, "_sla");
        -            search = search.replace(/[^a-z0-9\_]i/gi, "_zzz");
        -            };
        -
        -        var resultRows = document.getElementsByTagName("div");
        -        var matches = 0;
        -
        -        var i = 0;
        -        while (i < resultRows.length)
        -            {
        -            var row = resultRows.item(i);
        -
        -            if (row.className == "SRResult")
        -                {
        -                var rowMatchName = row.id.toLowerCase();
        -                rowMatchName = rowMatchName.replace(/^sr\d*_/, '');
        -
        -                if (search.length <= rowMatchName.length && rowMatchName.substr(0, search.length) == search)
        -                    {
        -                    row.style.display = "block";
        -                    matches++;
        -                    }
        -                else
        -                    {  row.style.display = "none";  };
        -                };
        -
        -            i++;
        -            };
        -
        -        document.getElementById("Searching").style.display="none";
        -
        -        if (matches == 0)
        -            {  document.getElementById("NoMatches").style.display="block";  }
        -        else
        -            {  document.getElementById("NoMatches").style.display="none";  }
        -
        -        this.lastMatchCount = matches;
        -
        -        return true;
        -        };
        -    };
        -
        diff --git a/vendor/naturaldocs/License.txt b/vendor/naturaldocs/License.txt
        deleted file mode 100644
        index 70aabbed8..000000000
        --- a/vendor/naturaldocs/License.txt
        +++ /dev/null
        @@ -1,275 +0,0 @@
        -Title: License
        -
        -Natural Docs is Copyright © 2003-2010 Greg Valure.  Natural Docs is licensed under version 3 of the GNU
        -Affero General Public License (AGPL).
        -
        -Natural Docs incorporates code from Google Prettify, which is Copyright © 2006 Google Inc.  Google Prettify
        -may be obtained separately under version 2.0 of the Apache License.  However, this combined product is still
        -licensed under the terms of the AGPLv3.
        -
        -Portions of Natural Docs may be distributed with generated documentation files in order to help them function,
        -such as JavaScript and CSS files.  These individual files retain their copyright and licensing terms, but they do
        -not apply to the remainder of the generated documentation.  All other generated documentation files remain
        -under the copyright and distribution terms decided by its author(s).
        -
        -
        -Topic: GNU Affero General Public License
        -
        -	Version 3, 19 November 2007
        -
        -	Copyright © 2007 Free Software Foundation, Inc.  <http://fsf.org/>
        -
        -	Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
        -
        -
        -	Preamble:
        -
        -	The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software.
        -
        -	The licenses for most software and other practical works are designed to take away your freedom to share and change the works.  By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.
        -
        -	When we speak of free software, we are referring to freedom, not price.  Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
        -
        -	Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software.
        -
        -	A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate.  Many developers of free software are heartened and encouraged by the resulting cooperation.  However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public.
        -
        -	The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community.  It requires the operator of a network server to provide the source code of the modified version running there to the users of that server.  Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version.
        -
        -	An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals.  This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license.
        -
        -	The precise terms and conditions for copying, distribution and modification follow.
        -
        -
        -	TERMS AND CONDITIONS:
        -
        -	0. Definitions:
        -
        -	"This License" refers to version 3 of the GNU Affero General Public License.
        -
        -	"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
        -
        -	"The Program" refers to any copyrightable work licensed under this License.  Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations
        -
        -	To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy.  The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.
        -
        -	A "covered work" means either the unmodified Program or a work based on the Program.
        -
        -	To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy.  Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
        -
        -	To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
        -
        -	An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this
        -	License, and how to view a copy of this License.  If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
        -
        -
        -	1. Source Code:
        -
        -	The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work.
        -
        -	A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
        -
        -	The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
        -
        -	The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
        -
        -	The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
        -
        -	The Corresponding Source for a work in source code form is that same work.
        -
        -
        -	2. Basic Permissions:
        -
        -	All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
        -
        -	You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
        -
        -	Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
        -
        -
        -	3. Protecting Users' Legal Rights From Anti-Circumvention Law:
        -
        -	No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
        -
        -	When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
        -
        -
        -	4. Conveying Verbatim Copies:
        -
        -	You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
        -
        -	You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
        -
        -
        -	5. Conveying Modified Source Versions:
        -
        -	You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code
        -under the terms of section 4, provided that you also meet all of these conditions:
        -
        -	    * a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
        -	    * b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices".
        -	    * c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
        -	    * d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
        -
        -	A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
        -
        -
        -	6. Conveying Non-Source Forms:
        -
        -	You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the
        -machine-readable Corresponding Source under the terms of this License, in one of these ways:
        -
        -	    * a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
        -	    * b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
        -	    * c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
        -	    * d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
        -	    * e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
        -
        -	A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
        -
        -	A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
        -
        -	"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
        -
        -	If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
        -
        -	The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
        -
        -	Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
        -
        -
        -	7. Additional Terms:
        -
        -	"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
        -
        -	When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
        -
        -	Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the
        -copyright holders of that material) supplement the terms of this License with terms:
        -
        -	    * a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
        -	    * b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
        -	    * c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
        -	    * d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
        -	    * e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
        -	    * f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
        -
        -	All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
        -
        -	If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
        -
        -	Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
        -
        -
        -	8. Termination:
        -
        -	You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
        -
        -	However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
        -
        -	Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
        -
        -	Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
        -
        -
        -	9. Acceptance Not Required for Having Copies:
        -
        -	You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
        -
        -
        -	10. Automatic Licensing of Downstream Recipients:
        -
        -	Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
        -
        -	An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
        -
        -	You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
        -
        -
        -	11. Patents:
        -
        -	A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version".
        -
        -	A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
        -
        -	Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
        -
        -	In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
        -
        -	If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
        -
        -	If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
        -
        -	A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
        -
        -	Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
        -
        -
        -	12. No Surrender of Others' Freedom:
        -
        -	If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
        -
        -
        -	13. Remote Network Interaction; Use with the GNU General Public License:
        -
        -	Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph.
        -
        -	Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License.
        -
        -
        -	14. Revised Versions of this License:
        -
        -	The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
        -
        -	Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation.
        -
        -	If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
        -
        -	Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
        -
        -
        -	15. Disclaimer of Warranty:
        -
        -	THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
        -
        -
        -	16. Limitation of Liability:
        -
        -	IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
        -
        -
        -	17. Interpretation of Sections 15 and 16:
        -
        -	If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
        -
        -	END OF TERMS AND CONDITIONS
        -
        -
        -How to Apply These Terms to Your New Programs:
        -
        -If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
        -
        -To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
        -
        -    <one line to give the program's name and a brief idea of what it does.>
        -    Copyright (C) <year>  <name of author>
        -
        -    This program is free software: you can redistribute it and/or modify
        -    it under the terms of the GNU Affero General Public License as
        -    published by the Free Software Foundation, either version 3 of the
        -    License, or (at your option) any later version.
        -
        -    This program 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.  See the
        -    GNU Affero General Public License for more details.
        -
        -    You should have received a copy of the GNU Affero General Public License
        -    along with this program.  If not, see <http://www.gnu.org/licenses/>.
        -
        -Also add information on how to contact you by electronic and paper mail.
        -
        -If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements.
        -
        -You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see <http://www.gnu.org/licenses/>.
        -
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/BinaryFile.pm b/vendor/naturaldocs/Modules/NaturalDocs/BinaryFile.pm
        deleted file mode 100644
        index ff9a444b1..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/BinaryFile.pm
        +++ /dev/null
        @@ -1,295 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::BinaryFile
        -#
        -###############################################################################
        -#
        -#   A package to manage Natural Docs' binary data files.
        -#
        -#   Usage:
        -#
        -#       - Only one data file can be managed with this package at a time.  You must close the file before opening another
        -#         one.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::BinaryFile;
        -
        -use vars qw(@EXPORT @ISA);
        -require Exporter;
        -@ISA = qw(Exporter);
        -
        -@EXPORT = ('BINARY_FORMAT');
        -
        -
        -###############################################################################
        -# Group: Format
        -
        -#
        -#   Topic: Standard Header
        -#
        -#   > [UInt8: BINARY_FORMAT]
        -#   > [VersionInt: app version]
        -#
        -#   The first byte is <BINARY_FORMAT>, which distinguishes binary configuration files from text ones, since Natural Docs
        -#   used to use text data files with the same name.
        -#
        -#   The next section is the version of Natural Docs that wrote the file, as defined by <NaturalDocs::Settings->AppVersion>
        -#   and written by <NaturalDocs::Version->ToBinaryFile()>.
        -#
        -
        -#
        -#   Topic: Data Types
        -#
        -#   All the integer data types are written most significant byte first, aka big endian.
        -#
        -#   An AString16 is a UInt16 followed by that many 8-bit ASCII characters.  It doesn't include a null character at the end.  Undef
        -#   strings are represented by a zero for the UInt16 and nothing following it.
        -#
        -
        -#
        -#   Constant: BINARY_FORMAT
        -#
        -#   An 8-bit constant that's used as the first byte of binary data files.  This is used so that you can easily distinguish between
        -#   binary and old-style text data files.  It's not a character that would appear in plain text files.
        -#
        -use constant BINARY_FORMAT => pack('C', 0x06);
        -# Which is ACK or acknowledge in ASCII.  Is the cool spade character in DOS displays.
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -#
        -#   handle: FH_BINARYDATAFILE
        -#
        -#   The file handle used for the data file.
        -#
        -
        -
        -#
        -#   string: currentFile
        -#
        -#   The <FileName> for the current configuration file being parsed.
        -#
        -my $currentFile;
        -
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: OpenForReading
        -#
        -#   Opens a binary file for reading.
        -#
        -#   Parameters:
        -#
        -#       minimumVersion - The minimum version of the file format that is acceptible.  May be undef.
        -#
        -#   Returns:
        -#
        -#       The format <VersionInt> or undef if it failed.  It could fail for any of the following reasons.
        -#
        -#       - The file doesn't exist.
        -#       - The file couldn't be opened.
        -#       - The file didn't have the proper header.
        -#       - Either the application or the file was from a development release, and they're not the exact same development release.
        -#       - The file's format was less than the minimum version, if one was defined.
        -#       - The file was from a later application version than the current.
        -#
        -sub OpenForReading #(FileName file, optional VersionInt minimumVersion) => VersionInt
        -    {
        -    my ($self, $file, $minimumVersion) = @_;
        -
        -    if (defined $currentFile)
        -        {  die "Tried to open binary file " . $file . " for reading when " . $currentFile . " was already open.";  };
        -
        -    $currentFile = $file;
        -
        -    if (open(FH_BINARYDATAFILE, '<' . $currentFile))
        -        {
        -        # See if it's binary.
        -        binmode(FH_BINARYDATAFILE);
        -
        -        my $firstChar;
        -        read(FH_BINARYDATAFILE, $firstChar, 1);
        -
        -        if ($firstChar == ::BINARY_FORMAT())
        -            {
        -            my $version = NaturalDocs::Version->FromBinaryFile(\*FH_BINARYDATAFILE);
        -
        -            if (NaturalDocs::Version->CheckFileFormat($version, $minimumVersion))
        -                {  return $version;  };
        -            };
        -
        -        close(FH_BINARYDATAFILE);
        -        };
        -
        -    $currentFile = undef;
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: OpenForWriting
        -#
        -#   Opens a binary file for writing and writes the standard header.  Dies if the file cannot be opened.
        -#
        -sub OpenForWriting #(FileName file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (defined $currentFile)
        -        {  die "Tried to open binary file " . $file . " for writing when " . $currentFile . " was already open.";  };
        -
        -    $currentFile = $file;
        -
        -    open (FH_BINARYDATAFILE, '>' . $currentFile)
        -        or die "Couldn't save " . $file . ".\n";
        -
        -    binmode(FH_BINARYDATAFILE);
        -
        -    print FH_BINARYDATAFILE '' . ::BINARY_FORMAT();
        -    NaturalDocs::Version->ToBinaryFile(\*FH_BINARYDATAFILE, NaturalDocs::Settings->AppVersion());
        -    };
        -
        -
        -#
        -#   Function: Close
        -#
        -#   Closes the current configuration file.
        -#
        -sub Close
        -    {
        -    my $self = shift;
        -
        -    if (!$currentFile)
        -        {  die "Tried to close a binary file when one wasn't open.";  };
        -
        -    close(FH_BINARYDATAFILE);
        -    $currentFile = undef;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Reading Functions
        -
        -
        -#
        -#   Function: GetUInt8
        -#   Reads and returns a UInt8 from the open file.
        -#
        -sub GetUInt8 # => UInt8
        -    {
        -    my $raw;
        -    read(FH_BINARYDATAFILE, $raw, 1);
        -
        -    return unpack('C', $raw);
        -    };
        -
        -#
        -#   Function: GetUInt16
        -#   Reads and returns a UInt16 from the open file.
        -#
        -sub GetUInt16 # => UInt16
        -    {
        -    my $raw;
        -    read(FH_BINARYDATAFILE, $raw, 2);
        -
        -    return unpack('n', $raw);
        -    };
        -
        -#
        -#   Function: GetUInt32
        -#   Reads and returns a UInt32 from the open file.
        -#
        -sub GetUInt32 # => UInt32
        -    {
        -    my $raw;
        -    read(FH_BINARYDATAFILE, $raw, 4);
        -
        -    return unpack('N', $raw);
        -    };
        -
        -#
        -#   Function: GetAString16
        -#   Reads and returns an AString16 from the open file.  Supports undef strings.
        -#
        -sub GetAString16 # => string
        -    {
        -    my $rawLength;
        -    read(FH_BINARYDATAFILE, $rawLength, 2);
        -    my $length = unpack('n', $rawLength);
        -
        -    if (!$length)
        -        {  return undef;  };
        -
        -    my $string;
        -    read(FH_BINARYDATAFILE, $string, $length);
        -
        -    return $string;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Writing Functions
        -
        -
        -#
        -#   Function: WriteUInt8
        -#   Writes a UInt8 to the open file.
        -#
        -sub WriteUInt8 #(UInt8 value)
        -    {
        -    my ($self, $value) = @_;
        -    print FH_BINARYDATAFILE pack('C', $value);
        -    };
        -
        -#
        -#   Function: WriteUInt16
        -#   Writes a UInt32 to the open file.
        -#
        -sub WriteUInt16 #(UInt16 value)
        -    {
        -    my ($self, $value) = @_;
        -    print FH_BINARYDATAFILE pack('n', $value);
        -    };
        -
        -#
        -#   Function: WriteUInt32
        -#   Writes a UInt32 to the open file.
        -#
        -sub WriteUInt32 #(UInt32 value)
        -    {
        -    my ($self, $value) = @_;
        -    print FH_BINARYDATAFILE pack('N', $value);
        -    };
        -
        -#
        -#   Function: WriteAString16
        -#   Writes an AString16 to the open file.  Supports undef strings.
        -#
        -sub WriteAString16 #(string value)
        -    {
        -    my ($self, $string) = @_;
        -
        -    if (length($string))
        -        {  print FH_BINARYDATAFILE pack('nA*', length($string), $string);  }
        -    else
        -        {  print FH_BINARYDATAFILE pack('n', 0);  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Builder.pm b/vendor/naturaldocs/Modules/NaturalDocs/Builder.pm
        deleted file mode 100644
        index e8b1cd37a..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Builder.pm
        +++ /dev/null
        @@ -1,281 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Builder
        -#
        -###############################################################################
        -#
        -#   A package that takes parsed source file and builds the output for it.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - <Add()> can be called immediately.
        -#       - <OutputPackages()> and <OutputPackageOf()> can be called once all sub-packages have been registered via <Add()>.
        -#         Since this is normally done in their INIT functions, they should be available to all normal functions immediately.
        -#
        -#       - Prior to calling <Run()>, <NaturalDocs::Settings>, <NaturalDocs::Project>, <NaturalDocs::Menu>, and
        -#         <NaturalDocs::Parser> must be initialized.  <NaturalDocs::Settings->GenerateDirectoryNames()> must be called.
        -#         <NaturalDocs::SymbolTable> and <NaturalDocs::ClassHierarchy> must be initialized and fully resolved.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use strict;
        -use integer;
        -
        -use NaturalDocs::Builder::Base;
        -use NaturalDocs::Builder::HTML;
        -use NaturalDocs::Builder::FramedHTML;
        -
        -package NaturalDocs::Builder;
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -#
        -#   Array: outputPackages
        -#
        -#   An array of the output packages available for use.
        -#
        -my @outputPackages;
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: OutputPackages
        -#
        -#   Returns an arrayref of the output packages available for use.  The arrayref is not a copy of the data, so don't change it.
        -#
        -#   Add output packages to this list with the <Add()> function.
        -#
        -sub OutputPackages
        -    {  return \@outputPackages;  };
        -
        -
        -#
        -#   Function: OutputPackageOf
        -#
        -#   Returns the output package corresponding to the passed command line option, or undef if none.
        -#
        -sub OutputPackageOf #(commandLineOption)
        -    {
        -    my ($self, $commandLineOption) = @_;
        -
        -    $commandLineOption = lc($commandLineOption);
        -
        -    foreach my $package (@outputPackages)
        -        {
        -        if (lc($package->CommandLineOption()) eq $commandLineOption)
        -            {  return $package;  };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -
        -#
        -#   Function: Add
        -#
        -#   Adds an output package to those available for use.  All output packages must call this function in order to be recognized.
        -#
        -#   Parameters:
        -#
        -#       package - The package name.
        -#
        -sub Add #(package)
        -    {
        -    my ($self, $package) = @_;
        -
        -    # Output packages shouldn't register themselves more than once, so we don't need to check for it.
        -    push @outputPackages, $package;
        -    };
        -
        -
        -#
        -#   Function: Run
        -#
        -#   Runs the build process.  This must be called *every time* Natural Docs is run, regardless of whether any source files changed
        -#   or not.  Some output packages have dependencies on files outside of the source tree that need to be checked.
        -#
        -#   Since there are multiple stages to the build process, this function will handle its own status messages.  There's no need to print
        -#   "Building files..." or something similar beforehand.
        -#
        -sub Run
        -    {
        -    my ($self) = @_;
        -
        -
        -    # Determine what we're doing.
        -
        -    my $buildTargets = NaturalDocs::Settings->BuildTargets();
        -
        -    my $filesToBuild = NaturalDocs::Project->FilesToBuild();
        -    my $numberOfFilesToBuild = (scalar keys %$filesToBuild) * (scalar @$buildTargets);
        -
        -    my $filesToPurge = NaturalDocs::Project->FilesToPurge();
        -    my $numberOfFilesToPurge = (scalar keys %$filesToPurge) * (scalar @$buildTargets);
        -
        -    my $imagesToUpdate = NaturalDocs::Project->ImageFilesToUpdate();
        -    my $numberOfImagesToUpdate = (scalar keys %$imagesToUpdate) * (scalar @$buildTargets);
        -
        -    my $imagesToPurge = NaturalDocs::Project->ImageFilesToPurge();
        -    my $numberOfImagesToPurge = (scalar keys %$imagesToPurge) * (scalar @$buildTargets);
        -
        -    my %indexesToBuild;
        -    my %indexesToPurge;
        -
        -    my $currentIndexes = NaturalDocs::Menu->Indexes();
        -    my $previousIndexes = NaturalDocs::Menu->PreviousIndexes();
        -
        -    foreach my $index (keys %$currentIndexes)
        -        {
        -        if (NaturalDocs::SymbolTable->IndexChanged($index) || !exists $previousIndexes->{$index})
        -            {
        -            $indexesToBuild{$index} = 1;
        -            };
        -        };
        -
        -    # All indexes that still exist should have been deleted.
        -    foreach my $index (keys %$previousIndexes)
        -        {
        -        if (!exists $currentIndexes->{$index})
        -            {
        -            $indexesToPurge{$index} = 1;
        -            };
        -        };
        -
        -    my $numberOfIndexesToBuild = (scalar keys %indexesToBuild) * (scalar @$buildTargets);
        -    my $numberOfIndexesToPurge = (scalar keys %indexesToPurge) * (scalar @$buildTargets);
        -
        -
        -    # Start the build process
        -
        -    foreach my $buildTarget (@$buildTargets)
        -        {
        -        $buildTarget->Builder()->BeginBuild( $numberOfFilesToBuild || $numberOfFilesToPurge ||
        -                                                               $numberOfImagesToUpdate || $numberOfImagesToPurge ||
        -                                                               $numberOfIndexesToBuild || $numberOfIndexesToPurge ||
        -                                                               NaturalDocs::Menu->HasChanged() );
        -        };
        -
        -    if ($numberOfFilesToPurge)
        -        {
        -        NaturalDocs::StatusMessage->Start('Purging ' . $numberOfFilesToPurge
        -                                                          . ' file' . ($numberOfFilesToPurge > 1 ? 's' : '') . '...',
        -                                                             scalar @$buildTargets);
        -
        -        foreach my $buildTarget (@$buildTargets)
        -            {
        -            $buildTarget->Builder()->PurgeFiles($filesToPurge);
        -            NaturalDocs::StatusMessage->CompletedItem();
        -            };
        -        };
        -
        -    if ($numberOfIndexesToPurge)
        -        {
        -        NaturalDocs::StatusMessage->Start('Purging ' . $numberOfIndexesToPurge
        -                                                           . ' index' . ($numberOfIndexesToPurge > 1 ? 'es' : '') . '...',
        -                                                             scalar @$buildTargets);
        -
        -        foreach my $buildTarget (@$buildTargets)
        -            {
        -            $buildTarget->Builder()->PurgeIndexes(\%indexesToPurge);
        -            NaturalDocs::StatusMessage->CompletedItem();
        -            };
        -        };
        -
        -    if ($numberOfImagesToPurge)
        -        {
        -        NaturalDocs::StatusMessage->Start('Purging ' . $numberOfImagesToPurge
        -                                                          . ' image' . ($numberOfImagesToPurge > 1 ? 's' : '') . '...',
        -                                                             scalar @$buildTargets);
        -
        -        foreach my $buildTarget (@$buildTargets)
        -            {
        -            $buildTarget->Builder()->PurgeImages($imagesToPurge);
        -            NaturalDocs::StatusMessage->CompletedItem();
        -            };
        -        };
        -
        -    if ($numberOfFilesToBuild)
        -        {
        -        NaturalDocs::StatusMessage->Start('Building ' . $numberOfFilesToBuild
        -                                                           . ' file' . ($numberOfFilesToBuild > 1 ? 's' : '') . '...',
        -                                                             $numberOfFilesToBuild);
        -
        -        foreach my $file (keys %$filesToBuild)
        -            {
        -            my $parsedFile = NaturalDocs::Parser->ParseForBuild($file);
        -
        -            NaturalDocs::Error->OnStartBuilding($file);
        -
        -            foreach my $buildTarget (@$buildTargets)
        -                {
        -                $buildTarget->Builder()->BuildFile($file, $parsedFile);
        -                NaturalDocs::StatusMessage->CompletedItem();
        -                };
        -
        -            NaturalDocs::Error->OnEndBuilding($file);
        -            };
        -        };
        -
        -    if ($numberOfIndexesToBuild)
        -        {
        -        NaturalDocs::StatusMessage->Start('Building ' . $numberOfIndexesToBuild
        -                                                          . ' index' . ($numberOfIndexesToBuild > 1 ? 'es' : '') . '...',
        -                                                             $numberOfIndexesToBuild);
        -
        -        foreach my $index (keys %indexesToBuild)
        -            {
        -            foreach my $buildTarget (@$buildTargets)
        -                {
        -                $buildTarget->Builder()->BuildIndex($index);
        -                NaturalDocs::StatusMessage->CompletedItem();
        -                };
        -            };
        -        };
        -
        -    if ($numberOfImagesToUpdate)
        -        {
        -        NaturalDocs::StatusMessage->Start('Updating ' . $numberOfImagesToUpdate
        -                                                          . ' image' . ($numberOfImagesToUpdate > 1 ? 's' : '') . '...',
        -                                                             $numberOfImagesToUpdate);
        -
        -        foreach my $image (keys %$imagesToUpdate)
        -            {
        -            foreach my $buildTarget (@$buildTargets)
        -                {
        -                $buildTarget->Builder()->UpdateImage($image);
        -                NaturalDocs::StatusMessage->CompletedItem();
        -                };
        -            };
        -        };
        -
        -    if (NaturalDocs::Menu->HasChanged())
        -        {
        -        if (!NaturalDocs::Settings->IsQuiet())
        -            {  print "Updating menu...\n";  };
        -
        -        foreach my $buildTarget (@$buildTargets)
        -            {  $buildTarget->Builder()->UpdateMenu();  };
        -        };
        -
        -    foreach my $buildTarget (@$buildTargets)
        -        {
        -        $buildTarget->Builder()->EndBuild($numberOfFilesToBuild || $numberOfFilesToPurge ||
        -                                                           $numberOfIndexesToBuild || $numberOfIndexesToPurge ||
        -                                                           $numberOfImagesToUpdate || $numberOfImagesToPurge ||
        -                                                           NaturalDocs::Menu->HasChanged());
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Builder/Base.pm b/vendor/naturaldocs/Modules/NaturalDocs/Builder/Base.pm
        deleted file mode 100644
        index 75b3fd310..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Builder/Base.pm
        +++ /dev/null
        @@ -1,349 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Builder::Base
        -#
        -###############################################################################
        -#
        -#   A base class for all Builder output formats.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Builder::Base;
        -
        -
        -###############################################################################
        -# Group: Notes
        -
        -
        -#
        -#   Topic: Implementation
        -#
        -#   Builder packages are implemented as blessed arrayrefs, not hashrefs.  This is done for all objects in Natural Docs for
        -#   efficiency reasons.  You create members by defining constants via <NaturalDocs::DefineMembers> and using them as
        -#   indexes into the array.
        -#
        -
        -#
        -#   Topic: Function Order
        -#
        -#   The functions in the build process will always be called in the following order.
        -#
        -#   - <BeginBuild()> will always be called.
        -#   - <PurgeFiles()> will be called next only if there's files that need to be purged.
        -#   - <PurgeIndexes()> will be called next only if there's indexes that need to be purged.
        -#   - <PurgeImages()> will e called next only if there's images that need to be purged.
        -#   - <BuildFile()> will be called once for each file that needs to be built, if any.
        -#   - <BuildIndex()> will be called once for each index that changed and is part of the menu, if any.
        -#   - <UpdateImage()> will be called once for each image that needs to be updated, if any.
        -#   - <UpdateMenu()> will be called next only if the menu changed.
        -#   - <EndBuild()> will always be called.
        -#
        -
        -#
        -#   Topic: How to Approach
        -#
        -#   Here's an idea of how to approach making packages for different output types.
        -#
        -#
        -#   Multiple Output Files, Embedded Menu:
        -#
        -#       This example is for when you want to build one output file per source file, each with its own copy of the menu within it.
        -#       This is how <NaturalDocs::Builder::HTML> works.
        -#
        -#       Make sure you create a function that generates just the menu for a particular source file.  We'll need to generate menus for
        -#       both building a file from scratch and for updating the menu on an existing output file, so it's better to give it its own function.
        -#       You may want to surround it with something that can be easily detected in the output file to make replacing easier.
        -#
        -#       <BeginBuild()> isn't important.  You don't need to implement it.
        -#
        -#       Implement <PurgeFiles()> to delete the output files associated with the purged files.
        -#
        -#       Implement <PurgeIndexes()> to delete the output files associated with the purged indexes.
        -#
        -#       Implement <BuildFile()> to create an output file for the parsed source file.  Use the menu function described earlier.
        -#
        -#       Implement <BuildIndex()> to create an output file for each index.  Use the menu function described earlier for each page.
        -#
        -#       Implement <UpdateMenu()> to go through the list of unbuilt files and update their menus.  You can get the list from
        -#       <NaturalDocs::Project->UnbuiltFilesWithContent()>.  You need to open their output files, replace the menu, and save it back
        -#       to disk.  Yes, it would be simpler from a programmer's point of view to just rebuild the file completely, but that would be
        -#       _very_ inefficient since there could potentially be a _lot_ of files in this group.
        -#
        -#       Also make sure <UpdateMenu()> goes through the unchanged indexes and updates them as well.
        -#
        -#       <EndBuild()> isn't important.  You don't need to implement it.
        -#
        -#
        -#   Multiple Output Files, Menu in File:
        -#
        -#       This example is for when you want to build one output file per source file, but keep the menu in its own separate file.  This
        -#       is how <NaturalDocs::Builder::FramedHTML> works.
        -#
        -#       <BeginBuild()> isn't important.  You don't need to implement it.
        -#
        -#       Implement <PurgeFiles()> to delete the output files associated with the purged files.
        -#
        -#       Implement <PurgeIndexes()> to delete the output files associated with the purged indexes.
        -#
        -#       Implement <BuildFile()> to generate an output file from the parsed source file.
        -#
        -#       Implement <BuildIndex()> to generate an output file for each index.
        -#
        -#       Implement <UpdateMenu()> to rebuild the menu file.
        -#
        -#       <EndBuild()> isn't important.  You don't need to implement it.
        -#
        -#
        -#   Single Output File using Intermediate Files:
        -#
        -#       This example is for when you want to build one output file, such as a PDF file, but use intermediate files to handle differential
        -#       building.  This would be much like how a compiler compiles each source file into a object file, and then a linker stitches them
        -#       all together into the final executable file.
        -#
        -#       <BeginBuild()> isn't important.  You don't need to implement it.
        -#
        -#       Implement <PurgeFiles()> to delete the intermediate files associated with the purged files.
        -#
        -#       Implement <PurgeIndexes()> to delete the intermediate files associated with the purged indexes.
        -#
        -#       Implement <BuildFile()> to generate an intermediate file from the parsed source file.
        -#
        -#       Implement <BuildIndex()> to generate an intermediate file for the specified index.
        -#
        -#       Implement <UpdateMenu()> to generate the intermediate file for the menu.
        -#
        -#       Implement <EndBuild()> so that if the project changed, it stitches the intermediate files together into the final
        -#       output file.  Make sure you check the parameter because the function will be called when nothing changes too.
        -#
        -#
        -#   Single Output File using Direct Changes:
        -#
        -#       This example is for when you want to build one output file, such as a PDF file, but engineering it in such a way that you don't
        -#       need to use intermediate files.  In other words, you're able to add, delete, and modify entries directly in the output file.
        -#
        -#       Implement <BeginBuild()> so that if the project changed, it opens the output file and does anything it needs to do
        -#       to get ready for editing.
        -#
        -#       Implement <PurgeFiles()> to remove the entries associated with the purged files.
        -#
        -#       Implement <PurgeIndexes()> to remove the entries associated with the purged indexes.
        -#
        -#       Implement <BuildFile()> to add or replace a section of the output file with a new one generated from the parsed file.
        -#
        -#       Implement <BuildIndex()> to add or replace an index in the output file with a new one generated from the specified index.
        -#
        -#       Implement <EndBuild()> so that if the project changed, it saves the output file to disk.
        -#
        -#       How you handle the menu depends on how the output file references other sections of itself.  If it can do so by name, then
        -#       you can implement <UpdateMenu()> to update the menu section of the file and you're done.  If it has to reference itself
        -#       by address or offset, it gets trickier.  You should skip <UpdateMenu()> and instead rebuild the menu in <EndBuild()> if
        -#       the parameter is true.  This lets you do it whenever anything changes in a file, rather than just when the menu
        -#       visibly changes.  How you keep track of the locations and how they change is your problem.
        -#
        -
        -
        -###############################################################################
        -#
        -#   Group: Required Interface Functions
        -#
        -#   All Builder classes *must* define these functions.
        -#
        -
        -
        -#
        -#   Function: INIT
        -#
        -#   Define this function to call <NaturalDocs::Builder->Add()> so that <NaturalDocs::Builder> knows about this package.
        -#   Packages are defined this way so that new ones can be added without messing around in other code.
        -#
        -
        -
        -#
        -#   Function: CommandLineOption
        -#
        -#   Define this function to return the text that should be put in the command line after -o to use this package.  It cannot have
        -#   spaces and is not case sensitive.
        -#
        -#   For example, <NaturalDocs::Builder::HTML> returns 'html' so someone could use -o html [directory] to use that package.
        -#
        -sub CommandLineOption
        -    {
        -    NaturalDocs::Error->SoftDeath($_[0] . " didn't define CommandLineOption().");
        -    };
        -
        -
        -#
        -#   Function: BuildFile
        -#
        -#   Define this function to convert a parsed file to this package's output format.  This function will be called once for every source
        -#   file that needs to be rebuilt.  However, if a file hasn't changed since the last time Natural Docs was run, it will not be sent to
        -#   this function.  All packages must support differential build.
        -#
        -#   Parameters:
        -#
        -#       sourceFile  - The name of the source file.
        -#       parsedFile  - The parsed source file, as an arrayref of <NaturalDocs::Parser::ParsedTopic> objects.
        -#
        -sub BuildFile #(sourceFile, parsedFile)
        -    {
        -    NaturalDocs::Error->SoftDeath($_[0] . " didn't define BuildFile().");
        -    };
        -
        -
        -###############################################################################
        -#
        -#   Group: Optional Interface Functions
        -#
        -#   These functions can be implemented but packages are not required to do so.
        -#
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Note that this is the only function where the first parameter will be the package name, not the object itself.
        -#
        -sub New
        -    {
        -    my $package = shift;
        -
        -    my $object = [ ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: BeginBuild
        -#
        -#   Define this function if the package needs to do anything at the beginning of the build process.  This function will be called
        -#   every time Natural Docs is run, even if the project hasn't changed.  This allows you to manage dependencies specific
        -#   to the output format that may change independently from the source tree and menu.  For example,
        -#   <NaturalDocs::Builder::HTML> needs to keep the CSS files in sync regardless of whether the source tree changed or not.
        -#
        -#   Parameters:
        -#
        -#       hasChanged - Whether the project has changed, such as source files or the menu file.  If false, nothing else is going to be
        -#                            called except <EndBuild()>.
        -#
        -sub BeginBuild #(hasChanged)
        -    {
        -    };
        -
        -
        -#
        -#   Function: EndBuild
        -#
        -#   Define this function if the package needs to do anything at the end of the build process.  This function will be called every time
        -#   Natural Docs is run, even if the project hasn't changed.  This allows you to manage dependencies specific to the output
        -#   format that may change independently from the source tree.  For example, <NaturalDocs::Builder::HTML> needs to keep the
        -#   CSS files in sync regardless of whether the source tree changed or not.
        -#
        -#   Parameters:
        -#
        -#       hasChanged - Whether the project has changed, such as source files or the menu file.  If false, the only other function that
        -#                            was called was <BeginBuild()>.
        -#
        -sub EndBuild #(hasChanged)
        -    {
        -    };
        -
        -
        -#
        -#   Function: BuildIndex
        -#
        -#   Define this function to create an index for the passed topic.  You can get the index from
        -#   <NaturalDocs::SymbolTable->Index()>.
        -#
        -#   The reason it's not passed directly to this function is because indexes may be time-consuming to create.  As such, they're
        -#   generated on demand because some output packages may choose not to implement them.
        -#
        -#   Parameters:
        -#
        -#       topic  - The <TopicType> to limit the index by.
        -#
        -sub BuildIndex #(topic)
        -    {
        -    };
        -
        -
        -#
        -#   Function: UpdateImage
        -#
        -#   Define this function to add or update the passed image in the output.
        -#
        -#   Parameters:
        -#
        -#       file - The image <FileName>
        -#
        -sub UpdateImage #(file)
        -    {
        -    };
        -
        -
        -#
        -#   Function: PurgeFiles
        -#
        -#   Define this function to make the package remove all output related to the passed files.  These files no longer have Natural Docs
        -#   content.
        -#
        -#   Parameters:
        -#
        -#       files - An existence hashref of the files to purge.
        -#
        -sub PurgeFiles #(files)
        -    {
        -    };
        -
        -
        -#
        -#   Function: PurgeIndexes
        -#
        -#   Define this function to make the package remove all output related to the passed indexes.  These indexes are no longer part
        -#   of the menu.
        -#
        -#   Parameters:
        -#
        -#       indexes  - An existence hashref of the <TopicTypes> of the indexes to purge.
        -#
        -sub PurgeIndexes #(indexes)
        -    {
        -    };
        -
        -
        -#
        -#   Function: PurgeImages
        -#
        -#   Define this function to make the package remove all output related to the passed image files.  These files are no longer used
        -#   by the documentation.
        -#
        -#   Parameters:
        -#
        -#       files - An existence hashref of the image <FileNames> to purge.
        -#
        -sub PurgeImages #(files)
        -    {
        -    };
        -
        -
        -#
        -#   Function: UpdateMenu
        -#
        -#   Define this function to make the package update the menu.  It will only be called if the menu changed.
        -#
        -sub UpdateMenu
        -    {
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Builder/FramedHTML.pm b/vendor/naturaldocs/Modules/NaturalDocs/Builder/FramedHTML.pm
        deleted file mode 100644
        index c29528a39..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Builder/FramedHTML.pm
        +++ /dev/null
        @@ -1,354 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Builder::FramedHTML
        -#
        -###############################################################################
        -#
        -#   A package that generates output in HTML with frames.
        -#
        -#   All functions are called with Package->Function() notation.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Builder::FramedHTML;
        -
        -use base 'NaturalDocs::Builder::HTMLBase';
        -
        -
        -###############################################################################
        -# Group: Implemented Interface Functions
        -
        -
        -#
        -#   Function: INIT
        -#
        -#   Registers the package with <NaturalDocs::Builder>.
        -#
        -sub INIT
        -    {
        -    NaturalDocs::Builder->Add(__PACKAGE__);
        -    };
        -
        -
        -#
        -#   Function: CommandLineOption
        -#
        -#   Returns the option to follow -o to use this package.  In this case, "html".
        -#
        -sub CommandLineOption
        -    {
        -    return 'FramedHTML';
        -    };
        -
        -
        -#
        -#   Function: BuildFile
        -#
        -#   Builds the output file from the parsed source file.
        -#
        -#   Parameters:
        -#
        -#       sourcefile       - The <FileName> of the source file.
        -#       parsedFile      - An arrayref of the source file as <NaturalDocs::Parser::ParsedTopic> objects.
        -#
        -sub BuildFile #(sourceFile, parsedFile)
        -    {
        -    my ($self, $sourceFile, $parsedFile) = @_;
        -
        -    my $outputFile = $self->OutputFileOf($sourceFile);
        -
        -
        -    # 99.99% of the time the output directory will already exist, so this will actually be more efficient.  It only won't exist
        -    # if a new file was added in a new subdirectory and this is the first time that file was ever parsed.
        -    if (!open(OUTPUTFILEHANDLE, '>' . $outputFile))
        -        {
        -        NaturalDocs::File->CreatePath( NaturalDocs::File->NoFileName($outputFile) );
        -
        -        open(OUTPUTFILEHANDLE, '>' . $outputFile)
        -            or die "Couldn't create output file " . $outputFile . "\n";
        -        };
        -
        -    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -    my $usePrettify = (NaturalDocs::Settings->HighlightCode() || NaturalDocs::Settings->HighlightAnonymous());
        -
        -
        -    print OUTPUTFILEHANDLE
        -
        -        # IE 6 doesn't like any doctype here at all.  Add one (strict or transitional doesn't matter) and it makes the page slightly too
        -        # wide for the frame.  Mozilla and Opera handle it like champs either way because they Don't Suck(tm).
        -
        -        # '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
        -        # . '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
        -
        -        '<html><head>'
        -
        -        	. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<title>'
        -                . $self->BuildTitle($sourceFile)
        -            . '</title>'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($outputFile, $self->MainCSSFile(), 1) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->MainJavaScriptFile(), 1) . '"></script>';
        -
        -            if ($usePrettify)
        -            	{
        -            	print OUTPUTFILEHANDLE
        -	            '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->PrettifyJavaScriptFile(), 1) . '">'
        -	            . '</script>';
        -            	}
        -
        -        print OUTPUTFILEHANDLE
        -        '</head><body class="FramedContentPage" onLoad="NDOnLoad();' . ($usePrettify ? 'prettyPrint();' : '') . '">'
        -            . $self->OpeningBrowserStyles()
        -
        -            . $self->StandardComments()
        -
        -            . "\n\n\n"
        -                . $self->BuildContent($sourceFile, $parsedFile)
        -            . "\n\n\n"
        -
        -            . $self->BuildToolTips()
        -
        -            . $self->ClosingBrowserStyles()
        -        . '</body></html>';
        -
        -
        -    close(OUTPUTFILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: BuildIndex
        -#
        -#   Builds an index for the passed type.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> to limit the index to, or undef if none.
        -#
        -sub BuildIndex #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    my $indexTitle = $self->IndexTitleOf($type);
        -    my $indexFile = $self->IndexFileOf($type);
        -
        -    my $startIndexPage =
        -
        -        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
        -            . '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
        -
        -        . '<html><head>'
        -
        -        	. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<title>';
        -
        -            if (defined NaturalDocs::Menu->Title())
        -                {  $startIndexPage .= $self->StringToHTML(NaturalDocs::Menu->Title()) . ' - ';  };
        -
        -                $startIndexPage .=
        -                $indexTitle
        -            . '</title>'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($indexFile, $self->MainCSSFile(), 1) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($indexFile, $self->MainJavaScriptFile(), 1) . '"></script>'
        -
        -        . '</head><body class="FramedIndexPage" onLoad="NDOnLoad()">'
        -            . $self->OpeningBrowserStyles()
        -
        -            . "\n\n\n"
        -                . $self->StandardComments()
        -            . "\n\n\n"
        -                . '<div id=Index>'
        -                    . '<div class=IPageTitle>'
        -                        . $indexTitle
        -                    . '</div>';
        -
        -
        -    my $endIndexPage =
        -
        -                    '</div><!--Index-->'
        -                . "\n\n\n"
        -
        -                . $self->ClosingBrowserStyles()
        -
        -       . '</body></html>';
        -
        -    my $startSearchResultsPage =
        -
        -        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
        -            . '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
        -
        -        . '<html><head>'
        -
        -            . '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($indexFile, $self->MainCSSFile(), 1) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($indexFile, $self->MainJavaScriptFile(), 1) . '"></script>'
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($indexFile, $self->SearchDataJavaScriptFile(), 1) . '">'
        -                . '</script>'
        -
        -        . '</head><body class="FramedSearchResultsPage" onLoad="NDOnLoad()">'
        -            . $self->OpeningBrowserStyles()
        -
        -            . "\n\n\n"
        -                . $self->StandardComments()
        -            . "\n\n\n"
        -
        -                . '<div id=Index>'
        -                    . '<div class=IPageTitle>'
        -                        . 'Search Results'
        -                    . '</div>';
        -
        -    my $endSearchResultsPage =
        -
        -                    '</div><!--Index-->'
        -                . "\n\n\n"
        -
        -                . $self->ClosingBrowserStyles()
        -
        -       . '</body></html>';
        -
        -    my $indexContent = NaturalDocs::SymbolTable->Index($type);
        -    my $pageCount = $self->BuildIndexPages($type, $indexContent, $startIndexPage, $endIndexPage,
        -                                                                  $startSearchResultsPage, $endSearchResultsPage);
        -    $self->PurgeIndexFiles($type, $indexContent, $pageCount + 1);
        -    };
        -
        -
        -#
        -#   Function: UpdateMenu
        -#
        -#   Builds the menu file.  Also generates index.html.
        -#
        -sub UpdateMenu
        -    {
        -    my $self = shift;
        -
        -    my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);
        -    my $outputFile = NaturalDocs::File->JoinPaths($outputDirectory, 'menu.html');
        -
        -
        -    open(OUTPUTFILEHANDLE, '>' . $outputFile)
        -        or die "Couldn't create output file " . $outputFile . "\n";
        -
        -    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -
        -    my $title = 'Menu';
        -    if (defined $title)
        -        {  $title .= ' - ' . NaturalDocs::Menu->Title();  };
        -
        -    $title = $self->StringToHTML($title);
        -
        -
        -    print OUTPUTFILEHANDLE
        -
        -        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
        -            . '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
        -
        -        . '<html><head>'
        -
        -          	. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<title>'
        -                . $title
        -            . '</title>'
        -
        -            . '<base target="Content">'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($outputFile, $self->MainCSSFile(), 1) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->MainJavaScriptFile(), 1) . '"></script>'
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->SearchDataJavaScriptFile(), 1) . '">'
        -                . '</script>'
        -
        -        . '</head><body class="FramedMenuPage" onLoad="NDOnLoad()">'
        -            . $self->OpeningBrowserStyles()
        -
        -            . $self->StandardComments()
        -
        -            . "\n\n\n"
        -                . $self->BuildMenu(undef, undef)
        -            . "\n\n\n"
        -                . $self->BuildFooter(1)
        -            . "\n\n\n"
        -
        -            . $self->ClosingBrowserStyles()
        -        . '</body></html>';
        -
        -
        -    close(OUTPUTFILEHANDLE);
        -
        -
        -    # Update index.html
        -
        -    my $firstMenuEntry = $self->FindFirstFile();
        -    my $indexFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html' );
        -
        -    # We have to check because it's possible that there may be no files with Natural Docs content and thus no files on the menu.
        -    if (defined $firstMenuEntry)
        -        {
        -        open(INDEXFILEHANDLE, '>' . $indexFile)
        -            or die "Couldn't create output file " . $indexFile . ".\n";
        -
        -	    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -
        -        print INDEXFILEHANDLE
        -
        -            '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" '
        -                . '"http://www.w3.org/TR/REC-html40/frameset.dtd">'
        -
        -            . '<html>'
        -
        -                . '<head>'
        -
        -                    . '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -                    . '<title>'
        -                        . $self->StringToHTML(NaturalDocs::Menu->Title())
        -                    . '</title>'
        -
        -                . '</head>'
        -
        -                . $self->StandardComments()
        -
        -                . '<frameset cols="185,*">'
        -                    . '<frame name=Menu src="menu.html">'
        -                    . '<frame name=Content src="'
        -                        . $self->MakeRelativeURL($indexFile, $self->OutputFileOf($firstMenuEntry->Target()), 1) . '">'
        -                . '</frameset>'
        -
        -                . '<noframes>'
        -                    . 'This documentation was designed for use with frames.  However, you can still use it by '
        -                    . '<a href="menu.html">starting from the menu page</a>.'
        -                    . "<script language=JavaScript><!--\n"
        -                        . 'location.href="menu.html";'
        -                    . "\n// --></script>"
        -                . '</noframes>'
        -
        -            . '</html>';
        -
        -        close INDEXFILEHANDLE;
        -        }
        -
        -    elsif (-e $indexFile)
        -        {
        -        unlink($indexFile);
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Builder/HTML.pm b/vendor/naturaldocs/Modules/NaturalDocs/Builder/HTML.pm
        deleted file mode 100644
        index 86bd8bf90..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Builder/HTML.pm
        +++ /dev/null
        @@ -1,414 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Builder::HTML
        -#
        -###############################################################################
        -#
        -#   A package that generates output in HTML.
        -#
        -#   All functions are called with Package->Function() notation.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Builder::HTML;
        -
        -use base 'NaturalDocs::Builder::HTMLBase';
        -
        -
        -###############################################################################
        -# Group: Implemented Interface Functions
        -
        -
        -#
        -#   Function: INIT
        -#
        -#   Registers the package with <NaturalDocs::Builder>.
        -#
        -sub INIT
        -    {
        -    NaturalDocs::Builder->Add(__PACKAGE__);
        -    };
        -
        -
        -#
        -#   Function: CommandLineOption
        -#
        -#   Returns the option to follow -o to use this package.  In this case, "html".
        -#
        -sub CommandLineOption
        -    {
        -    return 'HTML';
        -    };
        -
        -
        -#
        -#   Function: BuildFile
        -#
        -#   Builds the output file from the parsed source file.
        -#
        -#   Parameters:
        -#
        -#       sourcefile       - The <FileName> of the source file.
        -#       parsedFile      - An arrayref of the source file as <NaturalDocs::Parser::ParsedTopic> objects.
        -#
        -sub BuildFile #(sourceFile, parsedFile)
        -    {
        -    my ($self, $sourceFile, $parsedFile) = @_;
        -
        -    my $outputFile = $self->OutputFileOf($sourceFile);
        -
        -
        -    # 99.99% of the time the output directory will already exist, so this will actually be more efficient.  It only won't exist
        -    # if a new file was added in a new subdirectory and this is the first time that file was ever parsed.
        -    if (!open(OUTPUTFILEHANDLE, '>' . $outputFile))
        -        {
        -        NaturalDocs::File->CreatePath( NaturalDocs::File->NoFileName($outputFile) );
        -
        -        open(OUTPUTFILEHANDLE, '>' . $outputFile)
        -            or die "Couldn't create output file " . $outputFile . "\n";
        -        };
        -
        -    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -    my $usePrettify = (NaturalDocs::Settings->HighlightCode() || NaturalDocs::Settings->HighlightAnonymous());
        -
        -
        -    print OUTPUTFILEHANDLE
        -
        -        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" '
        -            . '"http://www.w3.org/TR/REC-html40/strict.dtd">' . "\n\n"
        -
        -        . '<html><head>'
        -
        -            . '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<title>'
        -                . $self->BuildTitle($sourceFile)
        -            . '</title>'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($outputFile, $self->MainCSSFile(), 1) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->MainJavaScriptFile(), 1) . '">'
        -                . '</script>';
        -
        -			if ($usePrettify)
        -				{
        -				print OUTPUTFILEHANDLE
        -	            '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->PrettifyJavaScriptFile(), 1) . '">'
        -	                . '</script>';
        -                }
        -
        -            print OUTPUTFILEHANDLE
        -            '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->SearchDataJavaScriptFile(), 1) . '">'
        -                . '</script>'
        -
        -	        . '</head><body class="ContentPage" onLoad="NDOnLoad();' . ($usePrettify ? 'prettyPrint();' : '') . '">'
        -            . $self->OpeningBrowserStyles()
        -
        -            . $self->StandardComments()
        -
        -            . "\n\n\n"
        -                . $self->BuildContent($sourceFile, $parsedFile)
        -            . "\n\n\n"
        -                . $self->BuildFooter()
        -            . "\n\n\n"
        -                . $self->BuildMenu($sourceFile, undef)
        -            . "\n\n\n"
        -                . $self->BuildToolTips()
        -            . "\n\n\n"
        -                . '<div id=MSearchResultsWindow>'
        -                    . '<iframe src="" frameborder=0 name=MSearchResults id=MSearchResults></iframe>'
        -                    . '<a href="javascript:searchPanel.CloseResultsWindow()" id=MSearchResultsWindowClose>Close</a>'
        -                . '</div>'
        -            . "\n\n\n"
        -
        -            . $self->ClosingBrowserStyles()
        -        . '</body></html>';
        -
        -
        -    close(OUTPUTFILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: BuildIndex
        -#
        -#   Builds an index for the passed type.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> to limit the index to, or undef if none.
        -#
        -sub BuildIndex #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    my $indexTitle = $self->IndexTitleOf($type);
        -
        -    my $startIndexPage =
        -
        -        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" '
        -            . '"http://www.w3.org/TR/REC-html40/strict.dtd">' . "\n\n"
        -
        -        . '<html><head>'
        -
        -            . '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<title>'
        -                . $indexTitle;
        -
        -                if (defined NaturalDocs::Menu->Title())
        -                    {  $startIndexPage .= ' - ' . $self->StringToHTML(NaturalDocs::Menu->Title());  };
        -
        -            $startIndexPage .=
        -            '</title>'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($self->IndexDirectory(),
        -                                                                                                                       $self->MainCSSFile()) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($self->IndexDirectory(),
        -                                                                                                        $self->MainJavaScriptFile()) . '"></script>'
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($self->IndexDirectory(),
        -                                                                                                        $self->SearchDataJavaScriptFile()) . '">'
        -                . '</script>'
        -
        -        . '</head><body class="IndexPage" onLoad="NDOnLoad()">'
        -            . $self->OpeningBrowserStyles()
        -
        -        . $self->StandardComments()
        -
        -        . "\n\n\n"
        -
        -        . '<div id=Index>'
        -            . '<div class=IPageTitle>'
        -                . $indexTitle
        -            . '</div>';
        -
        -    my $endIndexPage =
        -            '</div><!--Index-->'
        -
        -            . "\n\n\n"
        -                . $self->BuildFooter()
        -            . "\n\n\n"
        -                . $self->BuildMenu(undef, $type)
        -            . "\n\n\n"
        -                . '<div id=MSearchResultsWindow>'
        -                    . '<iframe src="" frameborder=0 name=MSearchResults id=MSearchResults></iframe>'
        -                    . '<a href="javascript:searchPanel.CloseResultsWindow()" id=MSearchResultsWindowClose>Close</a>'
        -                . '</div>'
        -            . "\n\n\n"
        -
        -            . $self->ClosingBrowserStyles()
        -        . '</body></html>';
        -
        -
        -    my $startSearchResultsPage =
        -
        -        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" '
        -            . '"http://www.w3.org/TR/REC-html40/strict.dtd">' . "\n\n"
        -
        -        . '<html><head>'
        -
        -            . '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        -
        -            . '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($self->SearchResultsDirectory(),
        -                                                                                                                       $self->MainCSSFile()) . '">'
        -
        -            . '<script language=JavaScript src="' . $self->MakeRelativeURL($self->SearchResultsDirectory(),
        -                                                                                                        $self->MainJavaScriptFile()) . '"></script>'
        -
        -        . '</head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()">'
        -            . $self->OpeningBrowserStyles()
        -
        -        . $self->StandardComments()
        -
        -        . "\n\n\n"
        -
        -        . '<div id=Index>';
        -
        -
        -    my $endSearchResultsPage =
        -        '</div>'
        -        . $self->ClosingBrowserStyles()
        -   . '</body></html>';
        -
        -    my $indexContent = NaturalDocs::SymbolTable->Index($type);
        -    my $pageCount = $self->BuildIndexPages($type, $indexContent, $startIndexPage, $endIndexPage,
        -                                                                  $startSearchResultsPage, $endSearchResultsPage);
        -    $self->PurgeIndexFiles($type, $indexContent, $pageCount + 1);
        -    };
        -
        -
        -#
        -#   Function: UpdateMenu
        -#
        -#   Updates the menu in all the output files that weren't rebuilt.  Also generates index.html.
        -#
        -sub UpdateMenu
        -    {
        -    my $self = shift;
        -
        -
        -    # Update the menu on unbuilt files.
        -
        -    my $filesToUpdate = NaturalDocs::Project->UnbuiltFilesWithContent();
        -
        -    foreach my $sourceFile (keys %$filesToUpdate)
        -        {
        -        $self->UpdateFile($sourceFile);
        -        };
        -
        -
        -    # Update the menu on unchanged index files.
        -
        -    my $indexes = NaturalDocs::Menu->Indexes();
        -
        -    foreach my $index (keys %$indexes)
        -        {
        -        if (!NaturalDocs::SymbolTable->IndexChanged($index))
        -            {
        -            $self->UpdateIndex($index);
        -            };
        -        };
        -
        -
        -    # Update index.html
        -
        -    my $firstMenuEntry = $self->FindFirstFile();
        -    my $indexFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html' );
        -
        -    # We have to check because it's possible that there may be no files with Natural Docs content and thus no files on the menu.
        -    if (defined $firstMenuEntry)
        -        {
        -        open(INDEXFILEHANDLE, '>' . $indexFile)
        -            or die "Couldn't create output file " . $indexFile . ".\n";
        -
        -	    binmode(INDEXFILEHANDLE, ':encoding(UTF-8)');
        -
        -        print INDEXFILEHANDLE
        -        '<html><head>'
        -             . '<meta http-equiv="Refresh" CONTENT="0; URL='
        -                 . $self->MakeRelativeURL( NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html'),
        -                                                        $self->OutputFileOf($firstMenuEntry->Target()), 1 ) . '">'
        -        . '</head></html>';
        -
        -        close INDEXFILEHANDLE;
        -        }
        -
        -    elsif (-e $indexFile)
        -        {
        -        unlink($indexFile);
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: UpdateFile
        -#
        -#   Updates an output file.  Replaces the menu, HTML title, and footer.  It opens the output file, makes the changes, and saves it
        -#   back to disk, which is much quicker than rebuilding the file from scratch if these were the only things that changed.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName>.
        -#
        -#   Dependencies:
        -#
        -#       - Requires <Builder::BuildMenu()> to surround its content with the exact strings "<div id=Menu>" and "</div><!--Menu-->".
        -#       - Requires <Builder::BuildFooter()> to surround its content with the exact strings "<div id=Footer>" and
        -#         "</div><!--Footer-->".
        -#
        -sub UpdateFile #(sourceFile)
        -    {
        -    my ($self, $sourceFile) = @_;
        -
        -    my $outputFile = $self->OutputFileOf($sourceFile);
        -
        -    if (open(OUTPUTFILEHANDLE, '<' . $outputFile))
        -        {
        -        my $content;
        -
        -	    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -        read(OUTPUTFILEHANDLE, $content, -s OUTPUTFILEHANDLE);
        -        close(OUTPUTFILEHANDLE);
        -
        -
        -        $content =~ s{<title>[^<]*<\/title>}{'<title>' . $self->BuildTitle($sourceFile) . '</title>'}e;
        -
        -        $content =~ s/<div id=Menu>.*?<\/div><!--Menu-->/$self->BuildMenu($sourceFile, undef)/es;
        -
        -        $content =~ s/<div id=Footer>.*?<\/div><!--Footer-->/$self->BuildFooter()/e;
        -
        -
        -        open(OUTPUTFILEHANDLE, '>' . $outputFile);
        -	    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -        print OUTPUTFILEHANDLE $content;
        -        close(OUTPUTFILEHANDLE);
        -        };
        -    };
        -
        -
        -#
        -#   Function: UpdateIndex
        -#
        -#   Updates an index's output file.  Replaces the menu and footer.  It opens the output file, makes the changes, and saves it
        -#   back to disk, which is much quicker than rebuilding the file from scratch if these were the only things that changed.
        -#
        -#   Parameters:
        -#
        -#       type - The index <TopicType>, or undef if none.
        -#
        -sub UpdateIndex #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    my $page = 1;
        -
        -    my $outputFile = $self->IndexFileOf($type, $page);
        -
        -    my $newMenu = $self->BuildMenu(undef, $type);
        -    my $newFooter = $self->BuildFooter();
        -
        -    while (-e $outputFile)
        -        {
        -        open(OUTPUTFILEHANDLE, '<' . $outputFile)
        -            or die "Couldn't open output file " . $outputFile . ".\n";
        -
        -        my $content;
        -
        -	    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -        read(OUTPUTFILEHANDLE, $content, -s OUTPUTFILEHANDLE);
        -        close(OUTPUTFILEHANDLE);
        -
        -
        -        $content =~ s/<div id=Menu>.*?<\/div><!--Menu-->/$newMenu/es;
        -
        -        $content =~ s/<div id=Footer>.*<\/div><!--Footer-->/$newFooter/e;
        -
        -
        -        open(OUTPUTFILEHANDLE, '>' . $outputFile)
        -            or die "Couldn't save output file " . $outputFile . ".\n";
        -
        -	    binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
        -        print OUTPUTFILEHANDLE $content;
        -        close(OUTPUTFILEHANDLE);
        -
        -        $page++;
        -        $outputFile = $self->IndexFileOf($type, $page);
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Builder/HTMLBase.pm b/vendor/naturaldocs/Modules/NaturalDocs/Builder/HTMLBase.pm
        deleted file mode 100644
        index 9d7dab0b0..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Builder/HTMLBase.pm
        +++ /dev/null
        @@ -1,3745 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Builder::HTMLBase
        -#
        -###############################################################################
        -#
        -#   A base package for all the shared functionality in <NaturalDocs::Builder::HTML> and
        -#   <NaturalDocs::Builder::FramedHTML>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use Tie::RefHash;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Builder::HTMLBase;
        -
        -use base 'NaturalDocs::Builder::Base';
        -
        -use NaturalDocs::DefineMembers 'MADE_EMPTY_SEARCH_RESULTS_PAGE', 'MadeEmptySearchResultsPage()',
        -                                                 'SetMadeEmptySearchResultsPage()';
        -
        -
        -
        -###############################################################################
        -# Group: Object Variables
        -
        -
        -#
        -#   Constants: Members
        -#
        -#   The object is implemented as a blessed arrayref, with the follow constants as indexes.
        -#
        -#   MADE_EMPTY_SEARCH_RESULTS_PAGE - Whether the search results page for searches with no results was generated.
        -#
        -
        -#
        -#   Constants: NDMarkupToHTML Styles
        -#
        -#   These are the styles used with <NDMarkupToHTML()>.
        -#
        -#   NDMARKUPTOHTML_GENERAL - General style.
        -#   NDMARKUPTOHTML_SUMMARY - For summaries.
        -#   NDMARKUPTOHTML_TOOLTIP - For tooltips.
        -#
        -use constant NDMARKUPTOHTML_GENERAL => undef;
        -use constant NDMARKUPTOHTML_SUMMARY => 1;
        -use constant NDMARKUPTOHTML_TOOLTIP => 2;
        -
        -
        -
        -###############################################################################
        -# Group: Package Variables
        -# These variables are shared by all instances of the package so don't change them.
        -
        -
        -#
        -#   handle: FH_CSS_FILE
        -#
        -#   The file handle to use when updating CSS files.
        -#
        -
        -
        -#
        -#   Hash: abbreviations
        -#
        -#   An existence hash of acceptable abbreviations.  These are words that <AddDoubleSpaces()> won't put a second space
        -#   after when followed by period-whitespace-capital letter.  Yes, this is seriously over-engineered.
        -#
        -my %abbreviations = ( mr => 1, mrs => 1, ms => 1, dr => 1,
        -                                  rev => 1, fr => 1, 'i.e' => 1,
        -                                  maj => 1, gen => 1, pres => 1, sen => 1, rep => 1,
        -                                  n => 1, s => 1, e => 1, w => 1, ne => 1, se => 1, nw => 1, sw => 1 );
        -
        -#
        -#   array: indexHeadings
        -#
        -#   An array of the headings of all the index sections.  First is for symbols, second for numbers, and the rest for each letter.
        -#
        -my @indexHeadings = ( '$#!', '0-9', 'A' .. 'Z' );
        -
        -#
        -#   array: indexAnchors
        -#
        -#   An array of the HTML anchors of all the index sections.  First is for symbols, second for numbers, and the rest for each letter.
        -#
        -my @indexAnchors = ( 'Symbols', 'Numbers', 'A' .. 'Z' );
        -
        -#
        -#   array: searchExtensions
        -#
        -#   An array of the search file name extensions for all the index sections.  First is for symbols, second for numbers, and the rest
        -#   for each letter.
        -#
        -my @searchExtensions = ( 'Symbols', 'Numbers', 'A' .. 'Z' );
        -
        -#
        -#   bool: saidUpdatingCSSFile
        -#
        -#   Whether the status message "Updating CSS file..." has been displayed.  We only want to print it once, no matter how many
        -#   HTML-based targets we are building.
        -#
        -my $saidUpdatingCSSFile;
        -
        -#
        -#   constant: ADD_HIDDEN_BREAKS
        -#
        -#   Just a synonym for "1" so that setting the flag on <StringToHTML()> is clearer in the calling code.
        -#
        -use constant ADD_HIDDEN_BREAKS => 1;
        -
        -
        -###############################################################################
        -# Group: ToolTip Package Variables
        -#
        -#   These variables are for the tooltip generation functions only.  Since they're reset on every call to <BuildContent()> and
        -#   <BuildIndexSections()>, and are only used by them and their support functions, they can be shared by all instances of the
        -#   package.
        -
        -#
        -#   int: tooltipLinkNumber
        -#
        -#   A number used as part of the ID for each link that has a tooltip.  Should be incremented whenever one is made.
        -#
        -my $tooltipLinkNumber;
        -
        -#
        -#   int: tooltipNumber
        -#
        -#   A number used as part of the ID for each tooltip.  Should be incremented whenever one is made.
        -#
        -my $tooltipNumber;
        -
        -#
        -#   hash: tooltipSymbolsToNumbers
        -#
        -#   A hash that maps the tooltip symbols to their assigned numbers.
        -#
        -my %tooltipSymbolsToNumbers;
        -
        -#
        -#   string: tooltipHTML
        -#
        -#   The generated tooltip HTML.
        -#
        -my $tooltipHTML;
        -
        -
        -###############################################################################
        -# Group: Menu Package Variables
        -#
        -#   These variables are for the menu generation functions only.  Since they're reset on every call to <BuildMenu()> and are
        -#   only used by it and its support functions, they can be shared by all instances of the package.
        -#
        -
        -
        -#
        -#   hash: prebuiltMenus
        -#
        -#   A hash that maps output directonies to menu HTML already built for it.  There will be no selection or JavaScript in the menus.
        -#
        -my %prebuiltMenus;
        -
        -
        -#
        -#   bool: menuNumbersAndLengthsDone
        -#
        -#   Set when the variables that only need to be calculated for the menu once are done.  This includes <menuGroupNumber>,
        -#   <menuLength>, <menuGroupLengths>, and <menuGroupNumbers>, and <menuRootLength>.
        -#
        -my $menuNumbersAndLengthsDone;
        -
        -
        -#
        -#   int: menuGroupNumber
        -#
        -#   The current menu group number.  Each time a group is created, this is incremented so that each one will be unique.
        -#
        -my $menuGroupNumber;
        -
        -
        -#
        -#   int: menuLength
        -#
        -#   The length of the entire menu, fully expanded.  The value is computed from the <Menu Length Constants>.
        -#
        -my $menuLength;
        -
        -
        -#
        -#   hash: menuGroupLengths
        -#
        -#   A hash of the length of each group, *not* including any subgroup contents.  The keys are references to each groups'
        -#   <NaturalDocs::Menu::Entry> object, and the values are their lengths computed from the <Menu Length Constants>.
        -#
        -my %menuGroupLengths;
        -tie %menuGroupLengths, 'Tie::RefHash';
        -
        -
        -#
        -#   hash: menuGroupNumbers
        -#
        -#   A hash of the number of each group, as managed by <menuGroupNumber>.  The keys are references to each groups'
        -#   <NaturalDocs::Menu::Entry> object, and the values are the number.
        -#
        -my %menuGroupNumbers;
        -tie %menuGroupNumbers, 'Tie::RefHash';
        -
        -
        -#
        -#   int: menuRootLength
        -#
        -#   The length of the top-level menu entries without expansion.  The value is computed from the <Menu Length Constants>.
        -#
        -my $menuRootLength;
        -
        -
        -#
        -#   constants: Menu Length Constants
        -#
        -#   Constants used to approximate the lengths of the menu or its groups.
        -#
        -#   MENU_TITLE_LENGTH       - The length of the title.
        -#   MENU_SUBTITLE_LENGTH - The length of the subtitle.
        -#   MENU_FILE_LENGTH         - The length of one file entry.
        -#   MENU_GROUP_LENGTH     - The length of one group entry.
        -#   MENU_TEXT_LENGTH        - The length of one text entry.
        -#   MENU_LINK_LENGTH        - The length of one link entry.
        -#
        -#   MENU_LENGTH_LIMIT    - The limit of the menu's length.  If the total length surpasses this limit, groups that aren't required
        -#                                       to be open to show the selection will default to closed on browsers that support it.
        -#
        -use constant MENU_TITLE_LENGTH => 3;
        -use constant MENU_SUBTITLE_LENGTH => 1;
        -use constant MENU_FILE_LENGTH => 1;
        -use constant MENU_GROUP_LENGTH => 2; # because it's a line and a blank space
        -use constant MENU_TEXT_LENGTH => 1;
        -use constant MENU_LINK_LENGTH => 1;
        -use constant MENU_INDEX_LENGTH => 1;
        -
        -use constant MENU_LENGTH_LIMIT => 35;
        -
        -
        -###############################################################################
        -# Group: Image Package Variables
        -#
        -#   These variables are for the image generation functions only.  Since they're reset on every call to <BuildContent()>,
        -#   and are only used by it and its support functions, they can be shared by all instances of thepackage.
        -
        -
        -#
        -#   var: imageAnchorNumber
        -#   Incremented for each image link in the file that requires an anchor.
        -#
        -my $imageAnchorNumber;
        -
        -
        -#
        -#   var: imageContent
        -#
        -#   The actual embedded image HTML for all image links.  When generating an image link, the link HTML is returned and
        -#   the HTML for the target image is added here.  Periodically, such as after the end of the paragraph, this content should
        -#   be added to the page and the variable set to undef.
        -#
        -my $imageContent;
        -
        -
        -
        -###############################################################################
        -# Group: Search Package Variables
        -#
        -#   These variables are for the search generation functions only.  Since they're reset on every call to <BuildIndexSections()> and
        -#   are only used by them and their support functions, they can be shared by all instances of the package.
        -
        -
        -#
        -#   hash: searchResultIDs
        -#
        -#   A hash mapping lowercase-only search result IDs to the number of times they've been used.  This is to work around an IE
        -#   bug where it won't correctly reference IDs if they differ only in case.
        -#
        -my %searchResultIDs;
        -
        -
        -
        -###############################################################################
        -# Group: Object Functions
        -
        -
        -#
        -#   Function: New
        -#   Creates and returns a new object.
        -#
        -sub New
        -    {
        -    my $class = shift;
        -
        -    my $object = $class->SUPER::New();
        -    $object->SetMadeEmptySearchResultsPage(0);
        -
        -    return $object;
        -    };
        -
        -
        -# Function: MadeEmptySearchResultsPage
        -# Returns whether the empty search results page was created or not.
        -
        -# Function: SetMadeEmptySearchResultsPage
        -# Sets whether the empty search results page was created or not.
        -
        -
        -
        -###############################################################################
        -# Group: Implemented Interface Functions
        -#
        -#   The behavior of these functions is shared between HTML output formats.
        -#
        -
        -
        -#
        -#   Function: UpdateImage
        -#
        -#   Define this function to add or update the passed image in the output.
        -#
        -#   Parameters:
        -#
        -#       file - The image <FileName>
        -#
        -sub UpdateImage #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    my $outputFile = $self->OutputImageOf($file);
        -    my $outputDirectory = NaturalDocs::File->NoFileName($outputFile);
        -
        -    if (!-d $outputDirectory)
        -        {  NaturalDocs::File->CreatePath($outputDirectory);  };
        -
        -    NaturalDocs::File->Copy($file, $outputFile);
        -    };
        -
        -
        -#
        -#   Function: PurgeFiles
        -#
        -#   Deletes the output files associated with the purged source files.
        -#
        -sub PurgeFiles #(filesToPurge)
        -    {
        -    my ($self, $filesToPurge) = @_;
        -
        -    # Combine directories into a hash to remove duplicate work.
        -    my %directoriesToPurge;
        -
        -    foreach my $file (keys %$filesToPurge)
        -        {
        -        # It's possible that there may be files there that aren't in a valid input directory anymore.  They won't generate an output
        -        # file name so we need to check for undef.
        -        my $outputFile = $self->OutputFileOf($file);
        -        if (defined $outputFile)
        -            {
        -            unlink($outputFile);
        -            $directoriesToPurge{ NaturalDocs::File->NoFileName($outputFile) } = 1;
        -            };
        -        };
        -
        -    foreach my $directory (keys %directoriesToPurge)
        -        {
        -        NaturalDocs::File->RemoveEmptyTree($directory, NaturalDocs::Settings->OutputDirectoryOf($self));
        -        };
        -    };
        -
        -
        -#
        -#   Function: PurgeIndexes
        -#
        -#   Deletes the output files associated with the purged source files.
        -#
        -#   Parameters:
        -#
        -#       indexes  - An existence hashref of the index types to purge.  The keys are the <TopicTypes> or * for the general index.
        -#
        -sub PurgeIndexes #(indexes)
        -    {
        -    my ($self, $indexes) = @_;
        -
        -    foreach my $index (keys %$indexes)
        -        {
        -        $self->PurgeIndexFiles($index, undef, undef);
        -        };
        -    };
        -
        -
        -#
        -#   Function: PurgeImages
        -#
        -#   Define this function to make the package remove all output related to the passed image files.  These files are no longer used
        -#   by the documentation.
        -#
        -#   Parameters:
        -#
        -#       files - An existence hashref of the image <FileNames> to purge.
        -#
        -sub PurgeImages #(files)
        -    {
        -    my ($self, $filesToPurge) = @_;
        -
        -    # Combine directories into a hash to remove duplicate work.
        -    my %directoriesToPurge;
        -
        -    foreach my $file (keys %$filesToPurge)
        -        {
        -        # It's possible that there may be files there that aren't in a valid input directory anymore.  They won't generate an output
        -        # file name so we need to check for undef.
        -        my $outputFile = $self->OutputImageOf($file);
        -        if (defined $outputFile)
        -            {
        -            unlink($outputFile);
        -            $directoriesToPurge{ NaturalDocs::File->NoFileName($outputFile) } = 1;
        -            };
        -        };
        -
        -    foreach my $directory (keys %directoriesToPurge)
        -        {
        -        NaturalDocs::File->RemoveEmptyTree($directory, NaturalDocs::Settings->OutputDirectoryOf($self));
        -        };
        -    };
        -
        -
        -#
        -#   Function: BeginBuild
        -#
        -#   Creates the necessary subdirectories in the output directory.
        -#
        -sub BeginBuild #(hasChanged)
        -    {
        -    my ($self, $hasChanged) = @_;
        -
        -    foreach my $directory ( $self->JavaScriptDirectory(), $self->CSSDirectory(), $self->IndexDirectory(),
        -                                       $self->SearchResultsDirectory() )
        -        {
        -        if (!-d $directory)
        -            {  NaturalDocs::File->CreatePath($directory);  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: EndBuild
        -#
        -#   Synchronizes the projects CSS and JavaScript files.  Also generates the search data JavaScript file.
        -#
        -sub EndBuild #(hasChanged)
        -    {
        -    my ($self, $hasChanged) = @_;
        -
        -
        -    # Update the style sheets.
        -
        -    my $styles = NaturalDocs::Settings->Styles();
        -    my $changed;
        -
        -    my $cssDirectory = $self->CSSDirectory();
        -    my $mainCSSFile = $self->MainCSSFile();
        -
        -    for (my $i = 0; $i < scalar @$styles; $i++)
        -        {
        -        my $outputCSSFile;
        -
        -        if (scalar @$styles == 1)
        -            {  $outputCSSFile = $mainCSSFile;  }
        -        else
        -            {  $outputCSSFile = NaturalDocs::File->JoinPaths($cssDirectory, ($i + 1) . '.css');  };
        -
        -
        -        my $masterCSSFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), $styles->[$i] . '.css' );
        -
        -        if (! -e $masterCSSFile)
        -            {  $masterCSSFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->StyleDirectory(), $styles->[$i] . '.css' );  };
        -
        -        # We check both the date and the size in case the user switches between two styles which just happen to have the same
        -        # date.  Should rarely happen, but it might.
        -        if (! -e $outputCSSFile ||
        -            (stat($masterCSSFile))[9] != (stat($outputCSSFile))[9] ||
        -             -s $masterCSSFile != -s $outputCSSFile)
        -            {
        -            if (!NaturalDocs::Settings->IsQuiet() && !$saidUpdatingCSSFile)
        -                {
        -                print "Updating CSS file...\n";
        -                $saidUpdatingCSSFile = 1;
        -                };
        -
        -            NaturalDocs::File->Copy($masterCSSFile, $outputCSSFile);
        -
        -            $changed = 1;
        -            };
        -        };
        -
        -
        -    my $deleteFrom;
        -
        -    if (scalar @$styles == 1)
        -        {  $deleteFrom = 1;  }
        -    else
        -        {  $deleteFrom = scalar @$styles + 1;  };
        -
        -    for (;;)
        -        {
        -        my $file = NaturalDocs::File->JoinPaths($cssDirectory, $deleteFrom . '.css');
        -
        -        if (! -e $file)
        -            {  last;  };
        -
        -        unlink ($file);
        -        $deleteFrom++;
        -
        -        $changed = 1;
        -        };
        -
        -
        -    if ($changed)
        -        {
        -        if (scalar @$styles > 1)
        -            {
        -            open(FH_CSS_FILE, '>' . $mainCSSFile);
        -		    binmode(FH_CSS_FILE, ':encoding(UTF-8)');
        -
        -            for (my $i = 0; $i < scalar @$styles; $i++)
        -                {
        -                print FH_CSS_FILE '@import URL("' . ($i + 1) . '.css");' . "\n";
        -                };
        -
        -            close(FH_CSS_FILE);
        -            };
        -        };
        -
        -
        -
        -    # Update the JavaScript files
        -
        -    my $jsMaster = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->JavaScriptDirectory(), 'NaturalDocs.js' );
        -    my $jsOutput = $self->MainJavaScriptFile();
        -
        -    # We check both the date and the size in case the user switches between two styles which just happen to have the same
        -    # date.  Should rarely happen, but it might.
        -    if (! -e $jsOutput ||
        -        (stat($jsMaster))[9] != (stat($jsOutput))[9] ||
        -         -s $jsMaster != -s $jsOutput)
        -        {
        -        NaturalDocs::File->Copy($jsMaster, $jsOutput);
        -        };
        -
        -
        -    my $prettifyOutput = $self->PrettifyJavaScriptFile();
        -
        -    if (NaturalDocs::Settings->HighlightCode() || NaturalDocs::Settings->HighlightAnonymous())
        -    	{
        -	    my $prettifyMaster = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->JavaScriptDirectory(), 'GooglePrettify.js' );
        -
        -	    # We check both the date and the size in case the user switches between two styles which just happen to have the same
        -	    # date.  Should rarely happen, but it might.
        -	    if (! -e $prettifyOutput ||
        -	        (stat($prettifyMaster))[9] != (stat($prettifyOutput))[9] ||
        -	         -s $prettifyMaster != -s $prettifyOutput)
        -	        {
        -	        NaturalDocs::File->Copy($prettifyMaster, $prettifyOutput);
        -	        };
        -	    }
        -	elsif (-e $prettifyOutput)
        -		{
        -		unlink $prettifyOutput;
        -		}
        -
        -
        -    my @indexes = keys %{NaturalDocs::Menu->Indexes()};
        -
        -    open(FH_INDEXINFOJS, '>' . NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'searchdata.js'));
        -    binmode(FH_INDEXINFOJS, ':encoding(UTF-8)');
        -
        -    print FH_INDEXINFOJS
        -    "var indexSectionsWithContent = {\n";
        -
        -    for (my $i = 0; $i < scalar @indexes; $i++)
        -        {
        -        if ($i != 0)
        -            {  print FH_INDEXINFOJS ",\n";  };
        -
        -        print FH_INDEXINFOJS '   "' . NaturalDocs::Topics->NameOfType($indexes[$i], 1, 1) . "\": {\n";
        -
        -        my $content = NaturalDocs::SymbolTable->IndexSectionsWithContent($indexes[$i]);
        -        for (my $contentIndex = 0; $contentIndex < 28; $contentIndex++)
        -            {
        -            if ($contentIndex != 0)
        -                {  print FH_INDEXINFOJS ",\n";  };
        -
        -            print FH_INDEXINFOJS '      "' . $searchExtensions[$contentIndex] . '": ' . ($content->[$contentIndex] ? 'true' : 'false');
        -            };
        -
        -        print FH_INDEXINFOJS "\n      }";
        -        };
        -
        -    print FH_INDEXINFOJS
        -    "\n   }";
        -
        -    close(FH_INDEXINFOJS);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Section Functions
        -
        -
        -#
        -#   Function: BuildTitle
        -#
        -#   Builds and returns the HTML page title of a file.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to build the title of.
        -#
        -#   Returns:
        -#
        -#       The source file's title in HTML.
        -#
        -sub BuildTitle #(sourceFile)
        -    {
        -    my ($self, $sourceFile) = @_;
        -
        -    # If we have a menu title, the page title is [menu title] - [file title].  Otherwise it is just [file title].
        -
        -    my $title = NaturalDocs::Project->DefaultMenuTitleOf($sourceFile);
        -
        -    my $menuTitle = NaturalDocs::Menu->Title();
        -    if (defined $menuTitle && $menuTitle ne $title)
        -        {  $title .= ' - ' . $menuTitle;  };
        -
        -    $title = $self->StringToHTML($title);
        -
        -    return $title;
        -    };
        -
        -#
        -#   Function: BuildMenu
        -#
        -#   Builds and returns the side menu of a file.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to use if you're looking for a source file.
        -#       indexType - The index <TopicType> to use if you're looking for an index.
        -#
        -#       Both sourceFile and indexType may be undef.
        -#
        -#   Returns:
        -#
        -#       The side menu in HTML.
        -#
        -#   Dependencies:
        -#
        -#       - <Builder::HTML::UpdateFile()> and <Builder::HTML::UpdateIndex()> require this section to be surrounded with the exact
        -#         strings "<div id=Menu>" and "</div><!--Menu-->".
        -#       - This function depends on the way <BuildMenuSegment()> formats file and index entries.
        -#
        -sub BuildMenu #(FileName sourceFile, TopicType indexType) -> string htmlMenu
        -    {
        -    my ($self, $sourceFile, $indexType) = @_;
        -
        -    if (!$menuNumbersAndLengthsDone)
        -        {
        -        $menuGroupNumber = 1;
        -        $menuLength = 0;
        -        %menuGroupLengths = ( );
        -        %menuGroupNumbers = ( );
        -        $menuRootLength = 0;
        -        };
        -
        -    my $outputDirectory;
        -
        -    if ($sourceFile)
        -        {  $outputDirectory = NaturalDocs::File->NoFileName( $self->OutputFileOf($sourceFile) );  }
        -    elsif ($indexType)
        -        {  $outputDirectory = NaturalDocs::File->NoFileName( $self->IndexFileOf($indexType) );  }
        -    else
        -        {  $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);  };
        -
        -
        -    # Comment needed for UpdateFile().
        -    my $output = '<div id=Menu>';
        -
        -
        -    if (!exists $prebuiltMenus{$outputDirectory})
        -        {
        -        my $segmentOutput;
        -
        -        ($segmentOutput, $menuRootLength) =
        -            $self->BuildMenuSegment($outputDirectory, NaturalDocs::Menu->Content(), 1);
        -
        -        my $titleOutput;
        -
        -        my $menuTitle = NaturalDocs::Menu->Title();
        -        if (defined $menuTitle)
        -            {
        -            if (!$menuNumbersAndLengthsDone)
        -                {  $menuLength += MENU_TITLE_LENGTH;  };
        -
        -            $menuRootLength += MENU_TITLE_LENGTH;
        -
        -            $titleOutput .=
        -            '<div class=MTitle>'
        -                . $self->StringToHTML($menuTitle);
        -
        -            my $menuSubTitle = NaturalDocs::Menu->SubTitle();
        -            if (defined $menuSubTitle)
        -                {
        -                if (!$menuNumbersAndLengthsDone)
        -                    {  $menuLength += MENU_SUBTITLE_LENGTH;  };
        -
        -                $menuRootLength += MENU_SUBTITLE_LENGTH;
        -
        -                $titleOutput .=
        -                '<div class=MSubTitle>'
        -                    . $self->StringToHTML($menuSubTitle)
        -                . '</div>';
        -                };
        -
        -            $titleOutput .=
        -            '</div>';
        -            };
        -
        -        my $searchOutput;
        -
        -        if (scalar keys %{NaturalDocs::Menu->Indexes()})
        -            {
        -            $searchOutput =
        -            '<script type="text/javascript"><!--' . "\n"
        -                . 'var searchPanel = new SearchPanel("searchPanel", "' . $self->CommandLineOption() . '", '
        -                    . '"' . $self->MakeRelativeURL($outputDirectory, $self->SearchResultsDirectory()) . '");' . "\n"
        -            . '--></script>'
        -
        -            . '<div id=MSearchPanel class=MSearchPanelInactive>'
        -                . '<input type=text id=MSearchField value=Search '
        -                    . 'onFocus="searchPanel.OnSearchFieldFocus(true)" onBlur="searchPanel.OnSearchFieldFocus(false)" '
        -                    . 'onKeyUp="searchPanel.OnSearchFieldChange()">'
        -                . '<select id=MSearchType '
        -                    . 'onFocus="searchPanel.OnSearchTypeFocus(true)" onBlur="searchPanel.OnSearchTypeFocus(false)" '
        -                    . 'onChange="searchPanel.OnSearchTypeChange()">';
        -
        -                my @indexes = keys %{NaturalDocs::Menu->Indexes()};
        -                @indexes = sort
        -                    {
        -                    if ($a eq ::TOPIC_GENERAL())  {  return -1;  }
        -                    elsif ($b eq ::TOPIC_GENERAL())  {  return 1;  }
        -                    else  {  return (NaturalDocs::Topics->NameOfType($a, 1) cmp NaturalDocs::Topics->NameOfType($b, 1))  };
        -                    }  @indexes;
        -
        -                foreach my $index (@indexes)
        -                    {
        -                    my ($name, $extra);
        -                    if ($index eq ::TOPIC_GENERAL())
        -                        {
        -                        $name = 'Everything';
        -                        $extra = ' id=MSearchEverything selected ';
        -                        }
        -                    else
        -                        {  $name = $self->ConvertAmpChars(NaturalDocs::Topics->NameOfType($index, 1));  }
        -
        -                    $searchOutput .=
        -                    '<option ' . $extra . 'value="' . NaturalDocs::Topics->NameOfType($index, 1, 1) . '">'
        -                        . $name
        -                    . '</option>';
        -                    };
        -
        -                $searchOutput .=
        -                '</select>'
        -            . '</div>';
        -            };
        -
        -        $prebuiltMenus{$outputDirectory} = $titleOutput . $segmentOutput . $searchOutput;
        -        $output .= $titleOutput . $segmentOutput . $searchOutput;
        -        }
        -    else
        -        {  $output .= $prebuiltMenus{$outputDirectory};  };
        -
        -
        -    # Highlight the menu selection.
        -
        -    if ($sourceFile)
        -        {
        -        # Dependency: This depends on how BuildMenuSegment() formats file entries.
        -        my $outputFile = $self->OutputFileOf($sourceFile);
        -        my $tag = '<div class=MFile><a href="' . $self->MakeRelativeURL($outputDirectory, $outputFile) . '">';
        -        my $tagIndex = index($output, $tag);
        -
        -        if ($tagIndex != -1)
        -            {
        -            my $endIndex = index($output, '</a>', $tagIndex);
        -
        -            substr($output, $endIndex, 4, '');
        -            substr($output, $tagIndex, length($tag), '<div class=MFile id=MSelected>');
        -            };
        -        }
        -    elsif ($indexType)
        -        {
        -        # Dependency: This depends on how BuildMenuSegment() formats index entries.
        -        my $outputFile = $self->IndexFileOf($indexType);
        -        my $tag = '<div class=MIndex><a href="' . $self->MakeRelativeURL($outputDirectory, $outputFile) . '">';
        -        my $tagIndex = index($output, $tag);
        -
        -        if ($tagIndex != -1)
        -            {
        -            my $endIndex = index($output, '</a>', $tagIndex);
        -
        -            substr($output, $endIndex, 4, '');
        -            substr($output, $tagIndex, length($tag), '<div class=MIndex id=MSelected>');
        -            };
        -        };
        -
        -
        -    # If the completely expanded menu is too long, collapse all the groups that aren't in the selection hierarchy or near the
        -    # selection.  By doing this instead of having them default to closed via CSS, any browser that doesn't support changing this at
        -    # runtime will keep the menu entirely open so that its still usable.
        -
        -    if ($menuLength > MENU_LENGTH_LIMIT())
        -        {
        -        my $menuSelectionHierarchy = $self->GetMenuSelectionHierarchy($sourceFile, $indexType);
        -
        -        my $toExpand = $self->ExpandMenu($sourceFile, $indexType, $menuSelectionHierarchy, $menuRootLength);
        -
        -        $output .=
        -
        -        '<script language=JavaScript><!--' . "\n"
        -
        -        . 'HideAllBut([' . join(', ', @$toExpand) . '], ' . $menuGroupNumber . ');'
        -
        -        . '// --></script>';
        -        };
        -
        -    $output .= '</div><!--Menu-->';
        -
        -    $menuNumbersAndLengthsDone = 1;
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildMenuSegment
        -#
        -#   A recursive function to build a segment of the menu.  *Remember to reset the <Menu Package Variables> before calling this
        -#   for the first time.*
        -#
        -#   Parameters:
        -#
        -#       outputDirectory - The output directory the menu is being built for.
        -#       menuSegment - An arrayref specifying the segment of the menu to build.  Either pass the menu itself or the contents
        -#                               of a group.
        -#       topLevel - Whether the passed segment is the top level segment or not.
        -#
        -#   Returns:
        -#
        -#       The array ( menuHTML, length ).
        -#
        -#       menuHTML - The menu segment in HTML.
        -#       groupLength - The length of the group, *not* including the contents of any subgroups, as computed from the
        -#                            <Menu Length Constants>.
        -#
        -#   Dependencies:
        -#
        -#       - <BuildMenu()> depends on the way this function formats file and index entries.
        -#
        -sub BuildMenuSegment #(outputDirectory, menuSegment, topLevel)
        -    {
        -    my ($self, $outputDirectory, $menuSegment, $topLevel) = @_;
        -
        -    my $output;
        -    my $groupLength = 0;
        -
        -    foreach my $entry (@$menuSegment)
        -        {
        -        if ($entry->Type() == ::MENU_GROUP())
        -            {
        -            my ($entryOutput, $entryLength) =
        -                $self->BuildMenuSegment($outputDirectory, $entry->GroupContent());
        -
        -            my $entryNumber;
        -
        -            if (!$menuNumbersAndLengthsDone)
        -                {
        -                $entryNumber = $menuGroupNumber;
        -                $menuGroupNumber++;
        -
        -                $menuGroupLengths{$entry} = $entryLength;
        -                $menuGroupNumbers{$entry} = $entryNumber;
        -                }
        -            else
        -                {  $entryNumber = $menuGroupNumbers{$entry};  };
        -
        -            $output .=
        -            '<div class=MEntry>'
        -                . '<div class=MGroup>'
        -
        -                    . '<a href="javascript:ToggleMenu(\'MGroupContent' . $entryNumber . '\')"'
        -                         . ($self->CommandLineOption() eq 'FramedHTML' ? ' target="_self"' : '') . '>'
        -                        . $self->StringToHTML($entry->Title())
        -                    . '</a>'
        -
        -                    . '<div class=MGroupContent id=MGroupContent' . $entryNumber . '>'
        -                        . $entryOutput
        -                    . '</div>'
        -
        -                . '</div>'
        -            . '</div>';
        -
        -            $groupLength += MENU_GROUP_LENGTH;
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_FILE())
        -            {
        -            my $targetOutputFile = $self->OutputFileOf($entry->Target());
        -
        -        # Dependency: BuildMenu() depends on how this formats file entries.
        -            $output .=
        -            '<div class=MEntry>'
        -                . '<div class=MFile>'
        -                    . '<a href="' . $self->MakeRelativeURL($outputDirectory, $targetOutputFile) . '">'
        -                        . $self->StringToHTML( $entry->Title(), ADD_HIDDEN_BREAKS)
        -                    . '</a>'
        -                . '</div>'
        -            . '</div>';
        -
        -            $groupLength += MENU_FILE_LENGTH;
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_TEXT())
        -            {
        -            $output .=
        -            '<div class=MEntry>'
        -                . '<div class=MText>'
        -                    . $self->StringToHTML( $entry->Title() )
        -                . '</div>'
        -            . '</div>';
        -
        -            $groupLength += MENU_TEXT_LENGTH;
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_LINK())
        -            {
        -            $output .=
        -            '<div class=MEntry>'
        -                . '<div class=MLink>'
        -                    . '<a href="' . $entry->Target() . '"' . ($self->CommandLineOption() eq 'FramedHTML' ? ' target="_top"' : '') . '>'
        -                        . $self->StringToHTML( $entry->Title() )
        -                    . '</a>'
        -                . '</div>'
        -            . '</div>';
        -
        -            $groupLength += MENU_LINK_LENGTH;
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_INDEX())
        -            {
        -            my $indexFile = $self->IndexFileOf($entry->Target);
        -
        -        # Dependency: BuildMenu() depends on how this formats index entries.
        -            $output .=
        -            '<div class=MEntry>'
        -                . '<div class=MIndex>'
        -                    . '<a href="' . $self->MakeRelativeURL( $outputDirectory, $self->IndexFileOf($entry->Target()) ) . '">'
        -                        . $self->StringToHTML( $entry->Title() )
        -                    . '</a>'
        -                . '</div>'
        -            . '</div>';
        -
        -            $groupLength += MENU_INDEX_LENGTH;
        -            };
        -        };
        -
        -
        -    if (!$menuNumbersAndLengthsDone)
        -        {  $menuLength += $groupLength;  };
        -
        -    return ($output, $groupLength);
        -    };
        -
        -
        -#
        -#   Function: BuildContent
        -#
        -#   Builds and returns the main page content.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName>.
        -#       parsedFile - The parsed source file as an arrayref of <NaturalDocs::Parser::ParsedTopic> objects.
        -#
        -#   Returns:
        -#
        -#       The page content in HTML.
        -#
        -sub BuildContent #(sourceFile, parsedFile)
        -    {
        -    my ($self, $sourceFile, $parsedFile) = @_;
        -
        -    $self->ResetToolTips();
        -    $imageAnchorNumber = 1;
        -    $imageContent = undef;
        -
        -    my $output = '<div id=Content>';
        -    my $i = 0;
        -
        -    while ($i < scalar @$parsedFile)
        -        {
        -        my $anchor = $self->SymbolToHTMLSymbol($parsedFile->[$i]->Symbol());
        -
        -        my $scope = NaturalDocs::Topics->TypeInfo($parsedFile->[$i]->Type())->Scope();
        -
        -
        -        # The anchors are closed, but not around the text, so the :hover CSS style won't accidentally kick in.
        -
        -        my $headerType;
        -
        -        if ($i == 0)
        -            {  $headerType = 'h1';  }
        -        elsif ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -            {  $headerType = 'h2';  }
        -        else
        -            {  $headerType = 'h3';  };
        -
        -        $output .=
        -
        -        '<div class="C' . NaturalDocs::Topics->NameOfType($parsedFile->[$i]->Type(), 0, 1) . '">'
        -            . '<div class=CTopic' . ($i == 0 ? ' id=MainTopic' : '') . '>'
        -
        -                . '<' . $headerType . ' class=CTitle>'
        -                    . '<a name="' . $anchor . '"></a>'
        -                    . $self->StringToHTML( $parsedFile->[$i]->Title(), ADD_HIDDEN_BREAKS)
        -                . '</' . $headerType . '>';
        -
        -
        -        my $hierarchy;
        -        if (NaturalDocs::Topics->TypeInfo( $parsedFile->[$i]->Type() )->ClassHierarchy())
        -            {
        -            $hierarchy = $self->BuildClassHierarchy($sourceFile, $parsedFile->[$i]->Symbol());
        -            };
        -
        -        my $summary;
        -        if ($i == 0 || $scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -            {
        -            $summary .= $self->BuildSummary($sourceFile, $parsedFile, $i);
        -            };
        -
        -        my $hasBody;
        -        if (defined $hierarchy || defined $summary ||
        -            defined $parsedFile->[$i]->Prototype() || defined $parsedFile->[$i]->Body())
        -            {
        -            $output .= '<div class=CBody>';
        -            $hasBody = 1;
        -            };
        -
        -        $output .= $hierarchy;
        -
        -        if (defined $parsedFile->[$i]->Prototype())
        -            {
        -            $output .= $self->BuildPrototype($parsedFile->[$i]->Type(), $parsedFile->[$i]->Prototype(), $sourceFile);
        -            };
        -
        -        if (defined $parsedFile->[$i]->Body())
        -            {
        -            $output .= $self->NDMarkupToHTML( $sourceFile, $parsedFile->[$i]->Body(), $parsedFile->[$i]->Symbol(),
        -                                                                  $parsedFile->[$i]->Package(), $parsedFile->[$i]->Type(),
        -                                                                  $parsedFile->[$i]->Using() );
        -            };
        -
        -        $output .= $summary;
        -
        -
        -        if ($hasBody)
        -            {  $output .= '</div>';  };
        -
        -        $output .=
        -            '</div>' # CTopic
        -        . '</div>' # CType
        -        . "\n\n";
        -
        -        $i++;
        -        };
        -
        -    $output .= '</div><!--Content-->';
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildSummary
        -#
        -#   Builds a summary, either for the entire file or the current class/section.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> the summary appears in.
        -#
        -#       parsedFile - A reference to the parsed source file.
        -#
        -#       index   - The index into the parsed file to start at.  If undef or zero, it builds a summary for the entire file.  If it's the
        -#                    index of a <TopicType> that starts or ends a scope, it builds a summary for that scope
        -#
        -#   Returns:
        -#
        -#       The summary in HTML.
        -#
        -sub BuildSummary #(sourceFile, parsedFile, index)
        -    {
        -    my ($self, $sourceFile, $parsedFile, $index) = @_;
        -    my $completeSummary;
        -
        -    if (!defined $index || $index == 0)
        -        {
        -        $index = 0;
        -        $completeSummary = 1;
        -        }
        -    else
        -        {
        -        # Skip the scope entry.
        -        $index++;
        -        };
        -
        -    if ($index + 1 >= scalar @$parsedFile)
        -        {  return undef;  };
        -
        -
        -    my $scope = NaturalDocs::Topics->TypeInfo($parsedFile->[$index]->Type())->Scope();
        -
        -    # Return nothing if there's only one entry.
        -    if (!$completeSummary && ($scope == ::SCOPE_START() || $scope == ::SCOPE_END()) )
        -        {  return undef;  };
        -
        -
        -    my $indent = 0;
        -    my $inGroup;
        -
        -    my $isMarked = 0;
        -
        -    my $output =
        -    '<!--START_ND_SUMMARY-->'
        -    . '<div class=Summary><div class=STitle>Summary</div>'
        -
        -        # Not all browsers get table padding right, so we need a div to apply the border.
        -        . '<div class=SBorder>'
        -        . '<table border=0 cellspacing=0 cellpadding=0 class=STable>';
        -
        -        while ($index < scalar @$parsedFile)
        -            {
        -            my $topic = $parsedFile->[$index];
        -            my $scope = NaturalDocs::Topics->TypeInfo($topic->Type())->Scope();
        -
        -            if (!$completeSummary && ($scope == ::SCOPE_START() || $scope == ::SCOPE_END()) )
        -                {  last;  };
        -
        -
        -            # Remove modifiers as appropriate for the current entry.
        -
        -            if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -                {
        -                $indent = 0;
        -                $inGroup = 0;
        -                $isMarked = 0;
        -                }
        -            elsif ($topic->Type() eq ::TOPIC_GROUP())
        -                {
        -                if ($inGroup)
        -                    {  $indent--;  };
        -
        -                $inGroup = 0;
        -                $isMarked = 0;
        -                };
        -
        -
        -            $output .=
        -             '<tr class="S' . ($index == 0 ? 'Main' : NaturalDocs::Topics->NameOfType($topic->Type(), 0, 1))
        -                . ($indent ? ' SIndent' . $indent : '') . ($isMarked ? ' SMarked' : '') .'">'
        -                . '<td class=SEntry>';
        -
        -           # Add the entry itself.
        -
        -            my $toolTipProperties;
        -
        -            # We only want a tooltip here if there's a protoype.  Otherwise it's redundant.
        -
        -            if (defined $topic->Prototype())
        -                {
        -                my $tooltipID = $self->BuildToolTip($topic->Symbol(), $sourceFile, $topic->Type(),
        -                                                                     $topic->Prototype(), $topic->Summary());
        -                $toolTipProperties = $self->BuildToolTipLinkProperties($tooltipID);
        -                };
        -
        -            $output .=
        -            '<a href="#' . $self->SymbolToHTMLSymbol($parsedFile->[$index]->Symbol()) . '" ' . $toolTipProperties . '>'
        -                . $self->StringToHTML( $parsedFile->[$index]->Title(), ADD_HIDDEN_BREAKS)
        -            . '</a>';
        -
        -
        -            $output .=
        -            '</td><td class=SDescription>';
        -
        -            if (defined $parsedFile->[$index]->Body())
        -                {
        -                $output .= $self->NDMarkupToHTML($sourceFile, $parsedFile->[$index]->Summary(),
        -                                                                     $parsedFile->[$index]->Symbol(), $parsedFile->[$index]->Package(),
        -                                                                     $parsedFile->[$index]->Type(), $parsedFile->[$index]->Using(),
        -                                                                     NDMARKUPTOHTML_SUMMARY);
        -                };
        -
        -
        -            $output .=
        -            '</td></tr>';
        -
        -
        -            # Prepare the modifiers for the next entry.
        -
        -            if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -                {
        -                $indent = 1;
        -                $inGroup = 0;
        -                }
        -            elsif ($topic->Type() eq ::TOPIC_GROUP())
        -                {
        -                if (!$inGroup)
        -                    {
        -                    $indent++;
        -                    $inGroup = 1;
        -                    };
        -                };
        -
        -            $isMarked ^= 1;
        -            $index++;
        -            };
        -
        -        $output .=
        -        '</table>'
        -    . '</div>' # Body
        -    . '</div>' # Summary
        -    . "<!--END_ND_SUMMARY-->";
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildPrototype
        -#
        -#   Builds and returns the prototype as HTML.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> the prototype is from.
        -#       prototype - The prototype to format.
        -#       file - The <FileName> the prototype was defined in.
        -#
        -#   Returns:
        -#
        -#       The prototype in HTML.
        -#
        -sub BuildPrototype #(type, prototype, file)
        -    {
        -    my ($self, $type, $prototype, $file) = @_;
        -
        -    my $language = NaturalDocs::Languages->LanguageOf($file);
        -    my $prototypeObject = $language->ParsePrototype($type, $prototype);
        -
        -    my $output;
        -
        -    if ($prototypeObject->OnlyBeforeParameters())
        -        {
        -        $output =
        -        # A blockquote to scroll it if it's too long.
        -        '<blockquote>'
        -            # A surrounding table as a hack to make the div form-fit.
        -            . '<table border=0 cellspacing=0 cellpadding=0 class="Prototype"><tr>'
        -            	. '<td' . (NaturalDocs::Settings->HighlightCode() ? ' class="prettyprint"' : '') . '>'
        -	                . $self->ConvertAmpChars($prototypeObject->BeforeParameters())
        -	            . '</td>'
        -	        . '</tr></table>'
        -        . '</blockquote>';
        -        }
        -
        -    else
        -        {
        -        my $params = $prototypeObject->Parameters();
        -        my $beforeParams = $prototypeObject->BeforeParameters();
        -        my $afterParams = $prototypeObject->AfterParameters();
        -
        -	    my $highlightClass = (NaturalDocs::Settings->HighlightCode() ? ' prettyprint ' : '');
        -
        -        # Determine what features the prototype has and its length.
        -
        -        my ($hasType, $hasTypePrefix, $hasNamePrefix, $hasDefaultValue, $hasDefaultValuePrefix);
        -        my $maxParamLength = 0;
        -
        -        foreach my $param (@$params)
        -            {
        -            my $paramLength = length($param->Name());
        -
        -            if ($param->Type())
        -                {
        -                $hasType = 1;
        -                $paramLength += length($param->Type()) + 1;
        -                };
        -            if ($param->TypePrefix())
        -                {
        -                $hasTypePrefix = 1;
        -                $paramLength += length($param->TypePrefix()) + 1;
        -                };
        -            if ($param->NamePrefix())
        -                {
        -                $hasNamePrefix = 1;
        -                $paramLength += length($param->NamePrefix());
        -                };
        -            if ($param->DefaultValue())
        -                {
        -                $hasDefaultValue = 1;
        -
        -                # The length of the default value part is either the longest word, or 1/3 the total, whichever is longer.  We do this
        -                # because we don't want parameter lines wrapping to more than three lines, and there's no guarantee that the line will
        -                # wrap at all.  There's a small possibility that it could still wrap to four lines with this code, but we don't need to go
        -                # crazy(er) here.
        -
        -                my $thirdLength = length($param->DefaultValue()) / 3;
        -
        -                my @words = split(/ +/, $param->DefaultValue());
        -                my $maxWordLength = 0;
        -
        -                foreach my $word (@words)
        -                    {
        -                    if (length($word) > $maxWordLength)
        -                        {  $maxWordLength = length($word);  };
        -                    };
        -
        -                $paramLength += ($maxWordLength > $thirdLength ? $maxWordLength : $thirdLength) + 1;
        -                };
        -            if ($param->DefaultValuePrefix())
        -                {
        -                $hasDefaultValuePrefix = 1;
        -                $paramLength += length($param->DefaultValuePrefix()) + 1;
        -                };
        -
        -            if ($paramLength > $maxParamLength)
        -                {  $maxParamLength = $paramLength;  };
        -            };
        -
        -        my $useCondensed = (length($beforeParams) + $maxParamLength + length($afterParams) > 80 ? 1 : 0);
        -        my $parameterColumns = 1 + $hasType + $hasTypePrefix + $hasNamePrefix +
        -                                               $hasDefaultValue + $hasDefaultValuePrefix + $useCondensed;
        -
        -        $output =
        -        '<blockquote><table border=0 cellspacing=0 cellpadding=0 class="Prototype"><tr><td>'
        -
        -            # Stupid hack to get it to work right in IE.
        -            . '<table border=0 cellspacing=0 cellpadding=0><tr>'
        -
        -            . '<td class="PBeforeParameters ' . $highlightClass . '"' . ($useCondensed ? 'colspan=' . $parameterColumns : 'nowrap') . '>'
        -                . $self->ConvertAmpChars($beforeParams);
        -
        -                if ($beforeParams && $beforeParams !~ /[\(\[\{\<]$/)
        -                    {  $output .= '&nbsp;';  };
        -
        -            $output .=
        -            '</td>';
        -
        -            for (my $i = 0; $i < scalar @$params; $i++)
        -                {
        -                if ($useCondensed)
        -                    {
        -                    $output .= '</tr><tr><td>&nbsp;&nbsp;&nbsp;</td>';
        -                    }
        -                elsif ($i > 0)
        -                    {
        -                    # Go to the next row and and skip the BeforeParameters cell.
        -                    $output .= '</tr><tr><td></td>';
        -                    };
        -
        -                if ($language->TypeBeforeParameter())
        -                    {
        -                    if ($hasTypePrefix)
        -                        {
        -                        my $htmlTypePrefix = $self->ConvertAmpChars($params->[$i]->TypePrefix());
        -                        $htmlTypePrefix =~ s/ $/&nbsp;/;
        -
        -                        $output .=
        -                        '<td class="PTypePrefix ' . $highlightClass . '" nowrap>'
        -                            . $htmlTypePrefix
        -                        . '</td>';
        -                        };
        -
        -                    if ($hasType)
        -                        {
        -                        $output .=
        -                        '<td class="PType ' . $highlightClass . '" nowrap>'
        -                            . $self->ConvertAmpChars($params->[$i]->Type()) . '&nbsp;'
        -                        . '</td>';
        -                        };
        -
        -                    if ($hasNamePrefix)
        -                        {
        -                        $output .=
        -                        '<td class="PParameterPrefix ' . $highlightClass . '" nowrap>'
        -                            . $self->ConvertAmpChars($params->[$i]->NamePrefix())
        -                        . '</td>';
        -                        };
        -
        -                    $output .=
        -                    '<td class="PParameter ' . $highlightClass . '" nowrap' . ($useCondensed && !$hasDefaultValue ? ' width=100%' : '') . '>'
        -                        . $self->ConvertAmpChars($params->[$i]->Name())
        -                    . '</td>';
        -                    }
        -
        -                else # !$language->TypeBeforeParameter()
        -                    {
        -                    $output .=
        -                    '<td class="PParameter ' . $highlightClass . '" nowrap>'
        -                        . $self->ConvertAmpChars( $params->[$i]->NamePrefix() . $params->[$i]->Name() )
        -                    . '</td>';
        -
        -                    if ($hasType || $hasTypePrefix)
        -                        {
        -                        my $typePrefix = $params->[$i]->TypePrefix();
        -                        if ($typePrefix)
        -                            {  $typePrefix .= ' ';  };
        -
        -                        $output .=
        -                        '<td class="PType ' . $highlightClass . '" nowrap' . ($useCondensed && !$hasDefaultValue ? ' width=100%' : '') . '>'
        -                            . '&nbsp;' . $self->ConvertAmpChars( $typePrefix . $params->[$i]->Type() )
        -                        . '</td>';
        -                        };
        -                    };
        -
        -                if ($hasDefaultValuePrefix)
        -                    {
        -                    $output .=
        -                    '<td class="PDefaultValuePrefix ' . $highlightClass . '">'
        -
        -                       . '&nbsp;' . $self->ConvertAmpChars( $params->[$i]->DefaultValuePrefix() ) . '&nbsp;'
        -                    . '</td>';
        -                    };
        -
        -                if ($hasDefaultValue)
        -                    {
        -                    $output .=
        -                    '<td class="PDefaultValue ' . $highlightClass . '" width=100%>'
        -                        . ($hasDefaultValuePrefix ? '' : '&nbsp;') . $self->ConvertAmpChars( $params->[$i]->DefaultValue() )
        -                    . '</td>';
        -                    };
        -                };
        -
        -            if ($useCondensed)
        -                {  $output .= '</tr><tr>';  };
        -
        -            $output .=
        -            '<td class="PAfterParameters ' . $highlightClass . '"' . ($useCondensed ? 'colspan=' . $parameterColumns : 'nowrap') . '>'
        -                 . $self->ConvertAmpChars($afterParams);
        -
        -                if ($afterParams && $afterParams !~ /^[\)\]\}\>]/)
        -                    {  $output .= '&nbsp;';  };
        -
        -            $output .=
        -            '</td>'
        -        . '</tr></table>'
        -
        -        # Hack.
        -        . '</td></tr></table></blockquote>';
        -       };
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildFooter
        -#
        -#   Builds and returns the HTML footer for the page.
        -#
        -#   Parameters:
        -#
        -#       multiline - Whether it should be formatted on multiple lines or not.
        -#
        -#   Dependencies:
        -#
        -#       <Builder::HTML::UpdateFile()> and <Builder::HTML::UpdateIndex()> require this section to be surrounded with the exact
        -#       strings "<div id=Footer>" and "</div><!--Footer-->".
        -#
        -sub BuildFooter #(bool multiline)
        -    {
        -    my ($self, $multiline) = @_;
        -
        -    my $footer = NaturalDocs::Menu->Footer();
        -    my $timestamp = NaturalDocs::Menu->TimeStamp();
        -    my $divider;
        -
        -    if ($multiline)
        -        {  $divider = '</p><p>';  }
        -    else
        -        {  $divider = '&nbsp; &middot;&nbsp; ';  };
        -
        -
        -    my $output = '<div id=Footer>';
        -    if ($multiline)
        -        {  $output .= '<p>';  };
        -
        -    if (defined $footer)
        -        {
        -        $footer =~ s/\(c\)/&copy;/gi;
        -        $footer =~ s/\(tm\)/&trade;/gi;
        -        $footer =~ s/\(r\)/&reg;/gi;
        -
        -        $output .= $footer . $divider;
        -        };
        -
        -    if (defined $timestamp)
        -        {
        -        $output .= $timestamp . $divider;
        -        };
        -
        -    $output .=
        -    '<a href="' . NaturalDocs::Settings->AppURL() . '">'
        -        . 'Generated by Natural Docs'
        -    . '</a>';
        -
        -    if ($multiline)
        -        {  $output .= '</p>';  };
        -
        -    $output .=
        -    '</div><!--Footer-->';
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildToolTip
        -#
        -#   Builds the HTML for a symbol's tooltip and stores it in <tooltipHTML>.
        -#
        -#   Parameters:
        -#
        -#       symbol - The target <SymbolString>.
        -#       file - The <FileName> the target's defined in.
        -#       type - The symbol <TopicType>.
        -#       prototype - The target prototype, or undef for none.
        -#       summary - The target summary, or undef for none.
        -#
        -#   Returns:
        -#
        -#       If a tooltip is necessary for the link, returns the tooltip ID.  If not, returns undef.
        -#
        -sub BuildToolTip #(symbol, file, type, prototype, summary)
        -    {
        -    my ($self, $symbol, $file, $type, $prototype, $summary) = @_;
        -
        -    if (defined $prototype || defined $summary)
        -        {
        -        my $htmlSymbol = $self->SymbolToHTMLSymbol($symbol);
        -        my $number = $tooltipSymbolsToNumbers{$htmlSymbol};
        -
        -        if (!defined $number)
        -            {
        -            $number = $tooltipNumber;
        -            $tooltipNumber++;
        -
        -            $tooltipSymbolsToNumbers{$htmlSymbol} = $number;
        -
        -            $tooltipHTML .=
        -            '<div class=CToolTip id="tt' . $number . '">'
        -                . '<div class=C' . NaturalDocs::Topics->NameOfType($type, 0, 1) . '>';
        -
        -            if (defined $prototype)
        -                {
        -                $tooltipHTML .= $self->BuildPrototype($type, $prototype, $file);
        -                };
        -
        -            if (defined $summary)
        -                {
        -                # The fact that we don't have scope or using shouldn't matter because links shouldn't be included in the style anyway.
        -                $summary = $self->NDMarkupToHTML($file, $summary, undef, undef, $type, undef, NDMARKUPTOHTML_TOOLTIP);
        -                $tooltipHTML .= $summary;
        -                };
        -
        -            $tooltipHTML .=
        -                '</div>'
        -            . '</div>';
        -            };
        -
        -        return 'tt' . $number;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -#
        -#   Function: BuildToolTips
        -#
        -#   Builds and returns the tooltips for the page in HTML.
        -#
        -sub BuildToolTips
        -    {
        -    my $self = shift;
        -    return "\n<!--START_ND_TOOLTIPS-->\n" . $tooltipHTML . "<!--END_ND_TOOLTIPS-->\n\n";
        -    };
        -
        -#
        -#   Function: BuildClassHierarchy
        -#
        -#   Builds and returns a class hierarchy diagram for the passed class, if applicable.
        -#
        -#   Parameters:
        -#
        -#       file - The source <FileName>.
        -#       class - The class <SymbolString> to build the hierarchy of.
        -#
        -sub BuildClassHierarchy #(file, symbol)
        -    {
        -    my ($self, $file, $symbol) = @_;
        -
        -    my @parents = NaturalDocs::ClassHierarchy->ParentsOf($symbol);
        -    @parents = sort { ::StringCompare($a, $b) } @parents;
        -
        -    my @children = NaturalDocs::ClassHierarchy->ChildrenOf($symbol);
        -    @children = sort { ::StringCompare($a, $b) } @children;
        -
        -    if (!scalar @parents && !scalar @children)
        -        {  return undef;  };
        -
        -    my $output =
        -    '<div class=ClassHierarchy>';
        -
        -    if (scalar @parents)
        -        {
        -        $output .='<table border=0 cellspacing=0 cellpadding=0><tr><td>';
        -
        -        foreach my $parent (@parents)
        -            {
        -            $output .= $self->BuildClassHierarchyEntry($file, $parent, 'CHParent', 1);
        -            };
        -
        -        $output .= '</td></tr></table><div class=CHIndent>';
        -        };
        -
        -    $output .=
        -    '<table border=0 cellspacing=0 cellpadding=0><tr><td>'
        -        . $self->BuildClassHierarchyEntry($file, $symbol, 'CHCurrent', undef)
        -    . '</td></tr></table>';
        -
        -    if (scalar @children)
        -        {
        -        $output .=
        -        '<div class=CHIndent>'
        -            . '<table border=0 cellspacing=0 cellpadding=0><tr><td>';
        -
        -        if (scalar @children <= 5)
        -            {
        -            for (my $i = 0; $i < scalar @children; $i++)
        -                {  $output .= $self->BuildClassHierarchyEntry($file, $children[$i], 'CHChild', 1);  };
        -            }
        -        else
        -            {
        -            for (my $i = 0; $i < 4; $i++)
        -                {  $output .= $self->BuildClassHierarchyEntry($file, $children[$i], 'CHChild', 1);  };
        -
        -           $output .= '<div class=CHChildNote><div class=CHEntry>' . (scalar @children - 4) . ' other children</div></div>';
        -            };
        -
        -        $output .=
        -        '</td></tr></table>'
        -        . '</div>';
        -        };
        -
        -    if (scalar @parents)
        -        {  $output .= '</div>';  };
        -
        -    $output .=
        -    '</div>';
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildClassHierarchyEntry
        -#
        -#   Builds and returns a single class hierarchy entry.
        -#
        -#   Parameters:
        -#
        -#       file - The source <FileName>.
        -#       symbol - The class <SymbolString> whose entry is getting built.
        -#       style - The style to apply to the entry, such as <CHParent>.
        -#       link - Whether to build a link for this class or not.  When building the selected class' entry, this should be false.  It will
        -#               automatically handle whether the symbol is defined or not.
        -#
        -sub BuildClassHierarchyEntry #(file, symbol, style, link)
        -    {
        -    my ($self, $file, $symbol, $style, $link) = @_;
        -
        -    my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
        -    my $name = join(NaturalDocs::Languages->LanguageOf($file)->PackageSeparator(), @identifiers);
        -    $name = $self->StringToHTML($name);
        -
        -    my $output = '<div class=' . $style . '><div class=CHEntry>';
        -
        -    if ($link)
        -        {
        -        my $target = NaturalDocs::SymbolTable->Lookup($symbol, $file);
        -
        -        if (defined $target)
        -            {
        -            my $targetFile;
        -
        -            if ($target->File() ne $file)
        -                {  $targetFile = $self->MakeRelativeURL( $self->OutputFileOf($file), $self->OutputFileOf($target->File()), 1 );  };
        -            # else leave it undef
        -
        -            my $targetTooltipID = $self->BuildToolTip($symbol, $target->File(), $target->Type(),
        -                                                                          $target->Prototype(), $target->Summary());
        -
        -            my $toolTipProperties = $self->BuildToolTipLinkProperties($targetTooltipID);
        -
        -            $output .= '<a href="' . $targetFile . '#' . $self->SymbolToHTMLSymbol($symbol) . '" '
        -                            . 'class=L' . NaturalDocs::Topics->NameOfType($target->Type(), 0, 1) . ' ' . $toolTipProperties . '>'
        -                            . $name . '</a>';
        -            }
        -        else
        -            {  $output .= $name;  };
        -        }
        -    else
        -        {  $output .= $name;  };
        -
        -    $output .= '</div></div>';
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: OpeningBrowserStyles
        -#
        -#   Returns the JavaScript that will add opening browser styles if necessary.
        -#
        -sub OpeningBrowserStyles
        -    {
        -    my $self = shift;
        -
        -    return
        -
        -    '<script language=JavaScript><!--' . "\n"
        -
        -        # IE 4 and 5 don't understand 'undefined', so you can't say '!= undefined'.
        -        . 'if (browserType) {'
        -            . 'document.write("<div class=" + browserType + ">");'
        -            . 'if (browserVer) {'
        -                . 'document.write("<div class=" + browserVer + ">"); }'
        -            . '}'
        -
        -    . '// --></script>';
        -    };
        -
        -
        -#
        -#   Function: ClosingBrowserStyles
        -#
        -#   Returns the JavaScript that will close browser styles if necessary.
        -#
        -sub ClosingBrowserStyles
        -    {
        -    my $self = shift;
        -
        -    return
        -
        -    '<script language=JavaScript><!--' . "\n"
        -
        -        . 'if (browserType) {'
        -            . 'if (browserVer) {'
        -                . 'document.write("</div>"); }'
        -            . 'document.write("</div>");'
        -            . '}'
        -
        -    . '// --></script>';
        -    };
        -
        -
        -#
        -#   Function: StandardComments
        -#
        -#   Returns the standard HTML comments that should be included in every generated file.  This includes <IEWebMark()>, so this
        -#   really is required for proper functionality.
        -#
        -sub StandardComments
        -    {
        -    my $self = shift;
        -
        -    return "\n\n"
        -
        -        . '<!--  Generated by Natural Docs, version ' . NaturalDocs::Settings->TextAppVersion() . ' -->' . "\n"
        -        . '<!--  ' . NaturalDocs::Settings->AppURL() . '  -->' . "\n\n"
        -        . $self->IEWebMark() . "\n\n";
        -    };
        -
        -
        -#
        -#   Function: IEWebMark
        -#
        -#   Returns the HTML comment necessary to get around the security warnings in IE starting with Windows XP Service Pack 2.
        -#
        -#   With this mark, the HTML page is treated as if it were in the Internet security zone instead of the Local Machine zone.  This
        -#   prevents the lockdown on scripting that causes an error message to appear with each page.
        -#
        -#   More Information:
        -#
        -#       - http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx#EHAA
        -#       - http://www.phdcc.com/xpsp2.htm#markoftheweb
        -#
        -sub IEWebMark
        -    {
        -    my $self = shift;
        -
        -    return '<!-- saved from url=(0026)http://www.naturaldocs.org -->';
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Index Functions
        -
        -
        -#
        -#   Function: BuildIndexPages
        -#
        -#   Builds an index file or files.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> the index is limited to, or undef for none.
        -#       indexSections  - An arrayref of sections, each section being an arrayref <NaturalDocs::SymbolTable::IndexElement>
        -#                               objects.  The first section is for symbols, the second for numbers, and the rest for A through Z.
        -#       beginIndexPage - All the content of the HTML page up to where the index content should appear.
        -#       endIndexPage - All the content of the HTML page past where the index should appear.
        -#       beginSearchResultsPage - All the content of the HTML page up to where the search results content should appear.
        -#       endSearchResultsPage - All the content of the HTML page past where the search results content should appear.
        -#
        -#   Returns:
        -#
        -#       The number of pages in the index.
        -#
        -sub BuildIndexPages #(TopicType type, NaturalDocs::SymbolTable::IndexElement[] indexSections, string beginIndexPage, string endIndexPage, string beginSearchResultsPage, string endSearchResultsPage) => int
        -    {
        -    my ($self, $type, $indexSections, $beginIndexPage, $endIndexPage, $beginSearchResultsPage, $endSearchResultsPage) = @_;
        -
        -
        -    # Build the content.
        -
        -    my ($indexHTMLSections, $tooltipHTMLSections, $searchResultsHTMLSections) = $self->BuildIndexSections($indexSections);
        -
        -
        -    # Generate the search result pages.
        -
        -   for (my $i = 0; $i < 28; $i++)
        -        {
        -        if ($searchResultsHTMLSections->[$i])
        -            {
        -            my $searchResultsFileName = $self->SearchResultsFileOf($type, $searchExtensions[$i]);
        -
        -            open(INDEXFILEHANDLE, '>' . $searchResultsFileName)
        -                or die "Couldn't create output file " . $searchResultsFileName . ".\n";
        -
        -		    binmode(INDEXFILEHANDLE, ':encoding(UTF-8)');
        -
        -            print INDEXFILEHANDLE
        -
        -            $beginSearchResultsPage
        -
        -            . '<div class=SRStatus id=Loading>Loading...</div>'
        -
        -            . '<table border=0 cellspacing=0 cellpadding=0>'
        -                . $searchResultsHTMLSections->[$i]
        -            . '</table>'
        -
        -            . '<div class=SRStatus id=Searching>Searching...</div>'
        -            . '<div class=SRStatus id=NoMatches>No Matches</div>'
        -
        -            . '<script type="text/javascript"><!--' . "\n"
        -                . 'document.getElementById("Loading").style.display="none";' . "\n"
        -                . 'document.getElementById("NoMatches").style.display="none";' . "\n"
        -
        -                . 'var searchResults = new SearchResults("searchResults", "' . $self->CommandLineOption() . '");' . "\n"
        -                . 'searchResults.Search();' . "\n"
        -            . '--></script>'
        -
        -            . $endSearchResultsPage;
        -
        -            close(INDEXFILEHANDLE);
        -            };
        -        };
        -
        -    if (!$self->MadeEmptySearchResultsPage())
        -        {
        -        my $emptySearchResultsFileName = NaturalDocs::File->JoinPaths( $self->SearchResultsDirectory(), 'NoResults.html' );
        -
        -        open(INDEXFILEHANDLE, '>' . $emptySearchResultsFileName)
        -            or die "Couldn't create output file " . $emptySearchResultsFileName . ".\n";
        -
        -	    binmode(INDEXFILEHANDLE, ':encoding(UTF-8)');
        -
        -        print INDEXFILEHANDLE
        -
        -        $beginSearchResultsPage
        -        . '<div class=SRStatus id=NoMatches>No Matches</div>'
        -        . $endSearchResultsPage;
        -
        -        close(INDEXFILEHANDLE);
        -
        -        $self->SetMadeEmptySearchResultsPage(1);
        -        };
        -
        -
        -    # Generate the index pages.
        -
        -    my $page = 1;
        -    my $pageSize = 0;
        -    my @pageLocations;
        -
        -    # The maximum page size acceptable before starting a new page.  Note that this doesn't include beginPage and endPage,
        -    # because we don't want something like a large menu screwing up the calculations.
        -    use constant PAGESIZE_LIMIT => 50000;
        -
        -
        -    # File the pages.
        -
        -    for (my $i = 0; $i < scalar @$indexHTMLSections; $i++)
        -        {
        -        if (!defined $indexHTMLSections->[$i])
        -            {  next;  };
        -
        -        $pageSize += length($indexHTMLSections->[$i]) + length($tooltipHTMLSections->[$i]);
        -        $pageLocations[$i] = $page;
        -
        -        if ($pageSize + length($indexHTMLSections->[$i+1]) + length($tooltipHTMLSections->[$i+1]) > PAGESIZE_LIMIT)
        -            {
        -            $page++;
        -            $pageSize = 0;
        -            };
        -        };
        -
        -
        -    # Build the pages.
        -
        -    my $indexFileName;
        -    $page = -1;
        -    my $oldPage = -1;
        -    my $tooltips;
        -    my $firstHeading;
        -
        -    for (my $i = 0; $i < scalar @$indexHTMLSections; $i++)
        -        {
        -        if (!defined $indexHTMLSections->[$i])
        -            {  next;  };
        -
        -        $page = $pageLocations[$i];
        -
        -        # Switch files if we need to.
        -
        -        if ($page != $oldPage)
        -            {
        -            if ($oldPage != -1)
        -                {
        -                print INDEXFILEHANDLE '</table>' . $tooltips . $endIndexPage;
        -                close(INDEXFILEHANDLE);
        -                $tooltips = undef;
        -                };
        -
        -            $indexFileName = $self->IndexFileOf($type, $page);
        -
        -            open(INDEXFILEHANDLE, '>' . $indexFileName)
        -                or die "Couldn't create output file " . $indexFileName . ".\n";
        -
        -		    binmode(INDEXFILEHANDLE, ':encoding(UTF-8)');
        -
        -            print INDEXFILEHANDLE $beginIndexPage . $self->BuildIndexNavigationBar($type, $page, \@pageLocations)
        -                                              . '<table border=0 cellspacing=0 cellpadding=0>';
        -
        -            $oldPage = $page;
        -            $firstHeading = 1;
        -            };
        -
        -        print INDEXFILEHANDLE
        -        '<tr>'
        -            . '<td class=IHeading' . ($firstHeading ? ' id=IFirstHeading' : '') . '>'
        -                . '<a name="' . $indexAnchors[$i] . '"></a>'
        -                 . $indexHeadings[$i]
        -            . '</td>'
        -            . '<td></td>'
        -        . '</tr>'
        -
        -        . $indexHTMLSections->[$i];
        -
        -        $firstHeading = 0;
        -        $tooltips .= $tooltipHTMLSections->[$i];
        -        };
        -
        -    if ($page != -1)
        -        {
        -        print INDEXFILEHANDLE '</table>' . $tooltips . $endIndexPage;
        -        close(INDEXFILEHANDLE);
        -        }
        -
        -    # Build a dummy page so there's something at least.
        -    else
        -        {
        -        $indexFileName = $self->IndexFileOf($type, 1);
        -
        -        open(INDEXFILEHANDLE, '>' . $indexFileName)
        -            or die "Couldn't create output file " . $indexFileName . ".\n";
        -
        -    	binmode(INDEXFILEHANDLE, ':encoding(UTF-8)');
        -
        -        print INDEXFILEHANDLE
        -            $beginIndexPage
        -            . $self->BuildIndexNavigationBar($type, 1, \@pageLocations)
        -            . 'There are no entries in the ' . lc( NaturalDocs::Topics->NameOfType($type) ) . ' index.'
        -            . $endIndexPage;
        -
        -        close(INDEXFILEHANDLE);
        -        };
        -
        -
        -    return $page;
        -    };
        -
        -
        -#
        -#   Function: BuildIndexSections
        -#
        -#   Builds and returns the index and search results sections in HTML.
        -#
        -#   Parameters:
        -#
        -#       index  - An arrayref of sections, each section being an arrayref <NaturalDocs::SymbolTable::IndexElement> objects.
        -#                   The first section is for symbols, the second for numbers, and the rest for A through Z.
        -#
        -#   Returns:
        -#
        -#       The arrayref ( indexSections, tooltipSections, searchResultsSections ).
        -#
        -#       Index 0 is the symbols, index 1 is the numbers, and each following index is A through Z.  The content of each section
        -#       is its HTML, or undef if there is nothing for that section.
        -#
        -sub BuildIndexSections #(NaturalDocs::SymbolTable::IndexElement[] index) => ( string[], string[], string[] )
        -    {
        -    my ($self, $indexSections) = @_;
        -
        -    $self->ResetToolTips();
        -    %searchResultIDs = ( );
        -
        -    my $contentSections = [ ];
        -    my $tooltipSections = [ ];
        -    my $searchResultsSections = [ ];
        -
        -    for (my $section = 0; $section < scalar @$indexSections; $section++)
        -        {
        -        if (defined $indexSections->[$section])
        -            {
        -            my $total = scalar @{$indexSections->[$section]};
        -
        -            for (my $i = 0; $i < $total; $i++)
        -                {
        -                my $id;
        -
        -                if ($i == 0)
        -                    {
        -                    if ($total == 1)
        -                        {  $id = 'IOnlySymbolPrefix';  }
        -                    else
        -                        {  $id = 'IFirstSymbolPrefix';  };
        -                    }
        -                elsif ($i == $total - 1)
        -                    {  $id = 'ILastSymbolPrefix';  };
        -
        -                my ($content, $searchResult) = $self->BuildIndexElement($indexSections->[$section]->[$i], $id);
        -                $contentSections->[$section] .= $content;
        -                $searchResultsSections->[$section] .= $searchResult;
        -                };
        -
        -            $tooltipSections->[$section] .= $self->BuildToolTips();
        -            $self->ResetToolTips(1);
        -            };
        -        };
        -
        -
        -    return ( $contentSections, $tooltipSections, $searchResultsSections );
        -    };
        -
        -
        -#
        -#   Function: BuildIndexElement
        -#
        -#   Converts a <NaturalDocs::SymbolTable::IndexElement> to HTML and returns it.  It will handle all sub-elements automatically.
        -#
        -#   Parameters:
        -#
        -#       element - The <NaturalDocs::SymbolTable::IndexElement> to build.
        -#       cssID - The CSS ID to apply to the prefix.
        -#
        -#   Recursion-Only Parameters:
        -#
        -#       These parameters are used internally for recursion, and should not be set.
        -#
        -#       symbol - If the element is below symbol level, the <SymbolString> to use.
        -#       package - If the element is below package level, the package <SymbolString> to use.
        -#       hasPackage - Whether the element is below package level.  Is necessary because package may need to be undef.
        -#
        -#   Returns:
        -#
        -#       The array ( indexHTML, searchResultHTML ) which is the element in the respective HTML forms.
        -#
        -sub BuildIndexElement #(NaturalDocs::SymbolTable::IndexElement element, string cssID, SymbolString symbol, SymbolString package, bool hasPackage) => ( string, string )
        -    {
        -    my ($self, $element, $cssID, $symbol, $package, $hasPackage) = @_;
        -
        -
        -    # If we're doing a file sub-index entry...
        -
        -    if ($hasPackage)
        -        {
        -        my ($inputDirectory, $relativePath) = NaturalDocs::Settings->SplitFromInputDirectory($element->File());
        -
        -        return $self->BuildIndexLink($self->StringToHTML($relativePath, ADD_HIDDEN_BREAKS), $symbol,
        -                                                                                 $package, $element->File(), $element->Type(),
        -                                                                                 $element->Prototype(), $element->Summary(), 'IFile');
        -        }
        -
        -
        -    # If we're doing a package sub-index entry...
        -
        -    elsif (defined $symbol)
        -
        -        {
        -        my $text;
        -
        -        if ($element->Package())
        -            {
        -            $text = NaturalDocs::SymbolString->ToText($element->Package(), $element->PackageSeparator());
        -            $text = $self->StringToHTML($text, ADD_HIDDEN_BREAKS);
        -            }
        -        else
        -            {  $text = 'Global';  };
        -
        -        if (!$element->HasMultipleFiles())
        -            {
        -            return $self->BuildIndexLink($text, $symbol, $element->Package(), $element->File(), $element->Type(),
        -                                                      $element->Prototype(), $element->Summary(), 'IParent');
        -            }
        -
        -        else
        -            {
        -            my $indexHTML =
        -            '<span class=IParent>'
        -                . $text
        -            . '</span>'
        -            . '<div class=ISubIndex>';
        -
        -            my $searchResultHTML = $indexHTML;
        -
        -            my $fileElements = $element->File();
        -            foreach my $fileElement (@$fileElements)
        -                {
        -                my ($i, $s) = $self->BuildIndexElement($fileElement, $cssID, $symbol, $element->Package(), 1);
        -                $indexHTML .= $i;
        -                $searchResultHTML .= $s;
        -                };
        -
        -            $indexHTML .= '</div>';
        -            $searchResultHTML .= '</div>';
        -
        -            return ($indexHTML, $searchResultHTML);
        -            };
        -        }
        -
        -
        -    # If we're doing a top-level symbol entry...
        -
        -    else
        -        {
        -        my $symbolText = $self->StringToHTML($element->SortableSymbol(), ADD_HIDDEN_BREAKS);
        -        my $symbolPrefix = $self->StringToHTML($element->IgnoredPrefix());
        -        my $searchResultID = $self->StringToSearchResultID($element->SortableSymbol());
        -
        -        my $indexHTML =
        -        '<tr>'
        -            . '<td class=ISymbolPrefix' . ($cssID ? ' id=' . $cssID : '') . '>'
        -                . ($symbolPrefix || '&nbsp;')
        -            . '</td><td class=IEntry>';
        -
        -        my $searchResultsHTML =
        -        '<div class=SRResult id=' . $searchResultID . '><div class=IEntry>';
        -
        -            if ($symbolPrefix)
        -                {  $searchResultsHTML .= '<span class=ISymbolPrefix>' . $symbolPrefix . '</span>';  };
        -
        -        if (!$element->HasMultiplePackages())
        -            {
        -            my $packageText;
        -
        -            if (defined $element->Package())
        -                {
        -                $packageText = NaturalDocs::SymbolString->ToText($element->Package(), $element->PackageSeparator());
        -                $packageText = $self->StringToHTML($packageText, ADD_HIDDEN_BREAKS);
        -                };
        -
        -            if (!$element->HasMultipleFiles())
        -                {
        -                my ($i, $s) =
        -                    $self->BuildIndexLink($symbolText, $element->Symbol(), $element->Package(), $element->File(),
        -                                                     $element->Type(), $element->Prototype(), $element->Summary(), 'ISymbol');
        -                $indexHTML .= $i;
        -                $searchResultsHTML .= $s;
        -
        -                if (defined $packageText)
        -                    {
        -                    $indexHTML .=
        -                    ', <span class=IParent>'
        -                        . $packageText
        -                    . '</span>';
        -
        -                    $searchResultsHTML .=
        -                    ', <span class=IParent>'
        -                        . $packageText
        -                    . '</span>';
        -                    };
        -                }
        -            else # hasMultipleFiles but not multiplePackages
        -                {
        -                $indexHTML .=
        -                '<span class=ISymbol>'
        -                    . $symbolText
        -                . '</span>';
        -
        -                $searchResultsHTML .=
        -                q{<a href="javascript:searchResults.Toggle('} . $searchResultID . q{')" class=ISymbol>}
        -                    . $symbolText
        -                . '</a>';
        -
        -                my $output;
        -
        -                if (defined $packageText)
        -                    {
        -                    $output .=
        -                    ', <span class=IParent>'
        -                        . $packageText
        -                    . '</span>';
        -                    };
        -
        -                $output .=
        -                '<div class=ISubIndex>';
        -
        -                $indexHTML .= $output;
        -                $searchResultsHTML .= $output;
        -
        -                my $fileElements = $element->File();
        -                foreach my $fileElement (@$fileElements)
        -                    {
        -                    my ($i, $s) = $self->BuildIndexElement($fileElement, $cssID, $element->Symbol(), $element->Package(), 1);
        -                    $indexHTML .= $i;
        -                    $searchResultsHTML .= $s;
        -                    };
        -
        -                $indexHTML .= '</div>';
        -                $searchResultsHTML .= '</div>';
        -                };
        -            }
        -
        -        else # hasMultiplePackages
        -            {
        -            $indexHTML .=
        -            '<span class=ISymbol>'
        -                . $symbolText
        -            . '</span>'
        -            . '<div class=ISubIndex>';
        -
        -            $searchResultsHTML .=
        -            q{<a href="javascript:searchResults.Toggle('} . $searchResultID . q{')" class=ISymbol>}
        -                . $symbolText
        -            . '</a>'
        -            . '<div class=ISubIndex>';
        -
        -            my $packageElements = $element->Package();
        -            foreach my $packageElement (@$packageElements)
        -                {
        -                my ($i, $s) = $self->BuildIndexElement($packageElement, $cssID, $element->Symbol());
        -                $indexHTML .= $i;
        -                $searchResultsHTML .= $s;
        -                };
        -
        -            $indexHTML .= '</div>';
        -            $searchResultsHTML .= '</div>';
        -            };
        -
        -        $indexHTML .= '</td></tr>';
        -        $searchResultsHTML .= '</div></div>';
        -
        -        return ($indexHTML, $searchResultsHTML);
        -        };
        -    };
        -
        -
        -#
        -#   Function: BuildIndexLink
        -#
        -#   Builds and returns the HTML associated with an index link.  The HTML will be the a href tag, the text, and the closing tag.
        -#
        -#   Parameters:
        -#
        -#       text - The text of the link *in HTML*.  Use <IndexSymbolToHTML()> if necessary.
        -#       symbol - The partial <SymbolString> to link to.
        -#       package - The package <SymbolString> of the symbol.
        -#       file - The <FileName> the symbol is defined in.
        -#       type - The <TopicType> of the symbol.
        -#       prototype - The prototype of the symbol, or undef if none.
        -#       summary - The summary of the symbol, or undef if none.
        -#       style - The CSS style to apply to the link.
        -#
        -#   Returns:
        -#
        -#       The array ( indexHTML, searchResultHTML ) which is the link in the respective forms.
        -#
        -sub BuildIndexLink #(string text, SymbolString symbol, SymbolString package, FileName file, TopicType type, string prototype, string summary, string style) => ( string, string )
        -    {
        -    my ($self, $text, $symbol, $package, $file, $type, $prototype, $summary, $style) = @_;
        -
        -    $symbol = NaturalDocs::SymbolString->Join($package, $symbol);
        -
        -    my $targetTooltipID = $self->BuildToolTip($symbol, $file, $type, $prototype, $summary);
        -    my $toolTipProperties = $self->BuildToolTipLinkProperties($targetTooltipID);
        -
        -    my $indexHTML = '<a href="' . $self->MakeRelativeURL( $self->IndexDirectory(), $self->OutputFileOf($file) )
        -                                         . '#' . $self->SymbolToHTMLSymbol($symbol) . '" ' . $toolTipProperties . ' '
        -                                . 'class=' . $style . '>' . $text . '</a>';
        -    my $searchResultHTML = '<a href="' . $self->MakeRelativeURL( $self->SearchResultsDirectory(), $self->OutputFileOf($file) )
        -                                         . '#' . $self->SymbolToHTMLSymbol($symbol) . '" '
        -                                         . ($self->CommandLineOption eq 'HTML' ? 'target=_parent ' : '')
        -                                . 'class=' . $style . '>' . $text . '</a>';
        -
        -    return ($indexHTML, $searchResultHTML);
        -    };
        -
        -
        -#
        -#   Function: BuildIndexNavigationBar
        -#
        -#   Builds a navigation bar for a page of the index.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> of the index, or undef for general.
        -#       page - The page of the index the navigation bar is for.
        -#       locations - An arrayref of the locations of each section.  Index 0 is for the symbols, index 1 for the numbers, and the rest
        -#                       for each letter.  The values are the page numbers where the sections are located.
        -#
        -sub BuildIndexNavigationBar #(type, page, locations)
        -    {
        -    my ($self, $type, $page, $locations) = @_;
        -
        -    my $output = '<div class=INavigationBar>';
        -
        -    for (my $i = 0; $i < scalar @indexHeadings; $i++)
        -        {
        -        if ($i != 0)
        -            {  $output .= ' &middot; ';  };
        -
        -        if (defined $locations->[$i])
        -            {
        -            $output .= '<a href="';
        -
        -            if ($locations->[$i] != $page)
        -                {  $output .= $self->RelativeIndexFileOf($type, $locations->[$i]);  };
        -
        -            $output .= '#' . $indexAnchors[$i] . '">' . $indexHeadings[$i] . '</a>';
        -            }
        -        else
        -            {
        -            $output .= $indexHeadings[$i];
        -            };
        -        };
        -
        -    $output .= '</div>';
        -
        -    return $output;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: PurgeIndexFiles
        -#
        -#   Removes all or some of the output files for an index.
        -#
        -#   Parameters:
        -#
        -#       type  - The index <TopicType>.
        -#       indexSections  - An arrayref of sections, each section being an arrayref <NaturalDocs::SymbolTable::IndexElement>
        -#                               objects.  The first section is for symbols, the second for numbers, and the rest for A through Z.  May be
        -#                               undef.
        -#       startingPage - If defined, only pages starting with this number will be removed.  Otherwise all pages will be removed.
        -#
        -sub PurgeIndexFiles #(TopicType type, optional NaturalDocs::SymbolTable::IndexElement[] indexSections, optional int startingPage)
        -    {
        -    my ($self, $type, $indexSections, $page) = @_;
        -
        -    # First the regular index pages.
        -
        -    if (!defined $page)
        -        {  $page = 1;  };
        -
        -    for (;;)
        -        {
        -        my $file = $self->IndexFileOf($type, $page);
        -
        -        if (-e $file)
        -            {
        -            unlink($file);
        -            $page++;
        -            }
        -        else
        -            {
        -            last;
        -            };
        -        };
        -
        -
        -    # Next the search results.
        -
        -    for (my $i = 0; $i < 28; $i++)
        -        {
        -        if (!$indexSections || !$indexSections->[$i])
        -            {
        -            my $file = $self->SearchResultsFileOf($type, $searchExtensions[$i]);
        -
        -            if (-e $file)
        -                {  unlink($file);  };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: OutputFileOf
        -#
        -#   Returns the output file name of the source file.  Will be undef if it is not a file from a valid input directory.
        -#
        -sub OutputFileOf #(sourceFile)
        -    {
        -    my ($self, $sourceFile) = @_;
        -
        -    my ($inputDirectory, $relativeSourceFile) = NaturalDocs::Settings->SplitFromInputDirectory($sourceFile);
        -    if (!defined $inputDirectory)
        -        {  return undef;  };
        -
        -    my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);
        -    my $inputDirectoryName = NaturalDocs::Settings->InputDirectoryNameOf($inputDirectory);
        -
        -    $outputDirectory = NaturalDocs::File->JoinPaths( $outputDirectory,
        -                                                                            'files' . ($inputDirectoryName != 1 ? $inputDirectoryName : ''), 1 );
        -
        -    # We need to change any extensions to dashes because Apache will think file.pl.html is a script.
        -    # We also need to add a dash if the file doesn't have an extension so there'd be no conflicts with index.html,
        -    # FunctionIndex.html, etc.
        -
        -    if (!($relativeSourceFile =~ tr/./-/))
        -        {  $relativeSourceFile .= '-';  };
        -
        -    $relativeSourceFile =~ tr/ &?(){};#/_/;
        -    $relativeSourceFile .= '.html';
        -
        -    return NaturalDocs::File->JoinPaths($outputDirectory, $relativeSourceFile);
        -    };
        -
        -
        -#
        -#   Function: OutputImageOf
        -#
        -#   Returns the output image file name of the source image file.  Will be undef if it is not a file from a valid input directory.
        -#
        -sub OutputImageOf #(sourceImageFile)
        -    {
        -    my ($self, $sourceImageFile) = @_;
        -
        -    my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);
        -    my $topLevelDirectory;
        -
        -    my ($inputDirectory, $relativeImageFile) = NaturalDocs::Settings->SplitFromInputDirectory($sourceImageFile);
        -
        -    if (defined $inputDirectory)
        -        {
        -        my $inputDirectoryName = NaturalDocs::Settings->InputDirectoryNameOf($inputDirectory);
        -        $topLevelDirectory = 'files' . ($inputDirectoryName != 1 ? $inputDirectoryName : '');
        -        }
        -    else
        -        {
        -        ($inputDirectory, $relativeImageFile) = NaturalDocs::Settings->SplitFromImageDirectory($sourceImageFile);
        -
        -        if (!defined $inputDirectory)
        -            {  return undef;  };
        -
        -        my $inputDirectoryName = NaturalDocs::Settings->ImageDirectoryNameOf($inputDirectory);
        -        $topLevelDirectory = 'images' . ($inputDirectoryName != 1 ? $inputDirectoryName : '');
        -        }
        -
        -
        -    $outputDirectory = NaturalDocs::File->JoinPaths($outputDirectory, $topLevelDirectory, 1);
        -
        -    $relativeImageFile =~ tr/ /_/;
        -
        -    return NaturalDocs::File->JoinPaths($outputDirectory, $relativeImageFile);
        -    };
        -
        -
        -#
        -#   Function: IndexDirectory
        -#
        -#   Returns the directory of the index files.
        -#
        -sub IndexDirectory
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index', 1);
        -    };
        -
        -
        -#
        -#   Function: IndexFileOf
        -#
        -#   Returns the output file name of the index file.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> of the index.
        -#       page  - The page number.  Undef is the same as one.
        -#
        -sub IndexFileOf #(type, page)
        -    {
        -    my ($self, $type, $page) = @_;
        -    return NaturalDocs::File->JoinPaths( $self->IndexDirectory(), $self->RelativeIndexFileOf($type, $page) );
        -    };
        -
        -
        -#
        -#   Function: RelativeIndexFileOf
        -#
        -#   Returns the output file name of the index file, relative to other index files.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> of the index.
        -#       page  - The page number.  Undef is the same as one.
        -#
        -sub RelativeIndexFileOf #(type, page)
        -    {
        -    my ($self, $type, $page) = @_;
        -    return NaturalDocs::Topics->NameOfType($type, 1, 1) . (defined $page && $page != 1 ? $page : '') . '.html';
        -    };
        -
        -
        -#
        -#   Function: SearchResultsDirectory
        -#
        -#   Returns the directory of the search results files.
        -#
        -sub SearchResultsDirectory
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'search', 1);
        -    };
        -
        -
        -#
        -#   Function: SearchResultsFileOf
        -#
        -#   Returns the output file name of the search result file.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> of the index.
        -#       extra - The string to add to the end of the file name, such as "A" or "Symbols".
        -#
        -sub SearchResultsFileOf #(TopicType type, string extra)
        -    {
        -    my ($self, $type, $extra) = @_;
        -
        -    my $fileName = NaturalDocs::Topics->NameOfType($type, 1, 1) . $extra . '.html';
        -
        -    return NaturalDocs::File->JoinPaths( $self->SearchResultsDirectory(), $fileName );
        -    };
        -
        -
        -#
        -#   Function: CSSDirectory
        -#
        -#   Returns the directory of the CSS files.
        -#
        -sub CSSDirectory
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'styles', 1);
        -    };
        -
        -
        -#
        -#   Function: MainCSSFile
        -#
        -#   Returns the location of the main CSS file.
        -#
        -sub MainCSSFile
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( $self->CSSDirectory(), 'main.css' );
        -    };
        -
        -
        -#
        -#   Function: JavaScriptDirectory
        -#
        -#   Returns the directory of the JavaScript files.
        -#
        -sub JavaScriptDirectory
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'javascript', 1);
        -    };
        -
        -
        -#
        -#   Function: MainJavaScriptFile
        -#
        -#   Returns the location of the main JavaScript file.
        -#
        -sub MainJavaScriptFile
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'main.js' );
        -    };
        -
        -
        -#
        -#   Function: PrettifyJavaScriptFile
        -#
        -#   Returns the location of the Google Prettify JavaScript file.
        -#
        -sub PrettifyJavaScriptFile
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'prettify.js' );
        -    };
        -
        -
        -#
        -#   Function: SearchDataJavaScriptFile
        -#
        -#   Returns the location of the search data JavaScript file.
        -#
        -sub SearchDataJavaScriptFile
        -    {
        -    my $self = shift;
        -    return NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'searchdata.js' );
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: IndexTitleOf
        -#
        -#   Returns the page title of the index file.
        -#
        -#   Parameters:
        -#
        -#       type  - The type of index.
        -#
        -sub IndexTitleOf #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    return ($type eq ::TOPIC_GENERAL() ? '' : NaturalDocs::Topics->NameOfType($type) . ' ') . 'Index';
        -    };
        -
        -#
        -#   Function: MakeRelativeURL
        -#
        -#   Returns a relative path between two files in the output tree and returns it in URL format.
        -#
        -#   Parameters:
        -#
        -#       baseFile    - The base <FileName> in local format, *not* in URL format.
        -#       targetFile  - The target <FileName> of the link in local format, *not* in URL format.
        -#       baseHasFileName - Whether baseFile has a file name attached or is just a path.
        -#
        -#   Returns:
        -#
        -#       The relative URL to the target.
        -#
        -sub MakeRelativeURL #(FileName baseFile, FileName targetFile, bool baseHasFileName) -> string relativeURL
        -    {
        -    my ($self, $baseFile, $targetFile, $baseHasFileName) = @_;
        -
        -    if ($baseHasFileName)
        -        {  $baseFile = NaturalDocs::File->NoFileName($baseFile)  };
        -
        -    my $relativePath = NaturalDocs::File->MakeRelativePath($baseFile, $targetFile);
        -
        -    return $self->ConvertAmpChars( NaturalDocs::File->ConvertToURL($relativePath) );
        -    };
        -
        -#
        -#   Function: StringToHTML
        -#
        -#   Converts a text string to HTML.  Does not apply paragraph tags or accept formatting tags.
        -#
        -#   Parameters:
        -#
        -#       string - The string to convert.
        -#       addHiddenBreaks - Whether to add hidden breaks to the string.  You can use <ADD_HIDDEN_BREAKS> for this parameter
        -#                                   if you want to make the calling code clearer.
        -#
        -#   Returns:
        -#
        -#       The string in HTML.
        -#
        -sub StringToHTML #(string, addHiddenBreaks)
        -    {
        -    my ($self, $string, $addHiddenBreaks) = @_;
        -
        -    $string =~ s/&/&amp;/g;
        -    $string =~ s/</&lt;/g;
        -    $string =~ s/>/&gt;/g;
        -
        -    # Me likey the fancy quotes.  They work in IE 4+, Mozilla, and Opera 5+.  We've already abandoned NS4 with the CSS
        -    # styles, so might as well.
        -    $string =~ s/^\'/&lsquo;/gm;
        -    $string =~ s/([\ \(\[\{])\'/$1&lsquo;/g;
        -    $string =~ s/\'/&rsquo;/g;
        -
        -    $string =~ s/^\"/&ldquo;/gm;
        -    $string =~ s/([\ \(\[\{])\"/$1&ldquo;/g;
        -    $string =~ s/\"/&rdquo;/g;
        -
        -    # Me likey the double spaces too.  As you can probably tell, I like print-formatting better than web-formatting.  The indented
        -    # paragraphs without blank lines in between them do become readable when you have fancy quotes and double spaces too.
        -    $string = $self->AddDoubleSpaces($string);
        -
        -    if ($addHiddenBreaks)
        -        {  $string = $self->AddHiddenBreaks($string);  };
        -
        -    return $string;
        -    };
        -
        -
        -#
        -#   Function: SymbolToHTMLSymbol
        -#
        -#   Converts a <SymbolString> to a HTML symbol, meaning one that is safe to include in anchor and link tags.  You don't need
        -#   to pass the result to <ConvertAmpChars()>.
        -#
        -sub SymbolToHTMLSymbol #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -
        -    my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
        -    my $htmlSymbol = join('.', @identifiers);
        -
        -    # If only Mozilla was nice about putting special characters in URLs like IE and Opera are, I could leave spaces in and replace
        -    # "<>& with their amp chars.  But alas, Mozilla shows them as %20, etc. instead.  It would have made for nice looking URLs.
        -    $htmlSymbol =~ tr/ \"<>\?&%/_/d;
        -
        -    return $htmlSymbol;
        -    };
        -
        -
        -#
        -#   Function: StringToSearchResultID
        -#
        -#   Takes a text string and translates it into something that can be used as a CSS ID.
        -#
        -#   Parameters:
        -#
        -#       string - The string to convert
        -#       dontIncrement - If set, it reuses the last generated ID.  Otherwise it generates a new one if it matches a previously
        -#                               generated one in a case-insensitive way.
        -#
        -sub StringToSearchResultID #(string string, bool dontIncrement = 0) => string
        -    {
        -    my ($self, $string, $dontIncrement) = @_;
        -
        -    $string =~ s/\_/_und/g;
        -    $string =~ s/ +/_spc/g;
        -
        -    my %translation = ( '~' => '_til', '!' => '_exc', '@' => '_att', '#' => '_num', '$' => '_dol', '%' => '_pct', '^' => '_car',
        -                                  '&' => '_amp', '*' => '_ast', '(' => '_lpa', ')' => '_rpa', '-' => '_min', '+' => '_plu', '=' => '_equ',
        -                                  '{' => '_lbc', '}' => '_rbc', '[' => '_lbk', ']' => '_rbk', ':' => '_col', ';' => '_sco', '"' => '_quo',
        -                                  '\'' => '_apo', '<' => '_lan', '>' => '_ran', ',' => '_com', '.' => '_per', '?' => '_que', '/' => '_sla' );
        -
        -    $string =~ s/([\~\!\@\#\$\%\^\&\*\(\)\-\+\=\{\}\[\]\:\;\"\'\<\>\,\.\?\/])/$translation{$1}/ge;
        -    $string =~ s/[^a-z0-9_]/_zzz/gi;
        -
        -    my $number = $searchResultIDs{lc($string)};
        -
        -    if (!$number)
        -        {  $number = 1;  }
        -    elsif (!$dontIncrement)
        -        {  $number++;  };
        -
        -    $searchResultIDs{lc($string)} = $number;
        -
        -    return 'SR' . ($number == 1 ? '' : $number) . '_' . $string;
        -    };
        -
        -
        -#
        -#   Function: NDMarkupToHTML
        -#
        -#   Converts a block of <NDMarkup> to HTML.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> the <NDMarkup> appears in.
        -#       text    - The <NDMarkup> text to convert.
        -#       symbol - The topic <SymbolString> the <NDMarkup> appears in.
        -#       package  - The package <SymbolString> the <NDMarkup> appears in.
        -#       type - The <TopicType> the <NDMarkup> appears in.
        -#       using - An arrayref of scope <SymbolStrings> the <NDMarkup> also has access to, or undef if none.
        -#       style - Set to one of the <NDMarkupToHTML Styles> or leave undef for general.
        -#
        -#   Returns:
        -#
        -#       The text in HTML.
        -#
        -sub NDMarkupToHTML #(sourceFile, text, symbol, package, type, using, style)
        -    {
        -    my ($self, $sourceFile, $text, $symbol, $package, $type, $using, $style) = @_;
        -
        -    my $dlSymbolBehavior;
        -
        -    if ($type eq ::TOPIC_ENUMERATION())
        -        {  $dlSymbolBehavior = NaturalDocs::Languages->LanguageOf($sourceFile)->EnumValues();  }
        -   elsif (NaturalDocs::Topics->TypeInfo($type)->Scope() == ::SCOPE_ALWAYS_GLOBAL())
        -        {  $dlSymbolBehavior = ::ENUM_GLOBAL();  }
        -    else
        -        {  $dlSymbolBehavior = ::ENUM_UNDER_PARENT();  };
        -
        -    my $output;
        -    my $inCode;
        -
        -    my @splitText = split(/(<\/?code(?: type="[^"]+")?>)/, $text);
        -
        -    while (scalar @splitText)
        -        {
        -        $text = shift @splitText;
        -
        -        if ($text =~ /<code type="([^"]+)">/)
        -            {
        -            my $codeType = $1;
        -
        -            my $highlight = ( ($codeType eq "code" && NaturalDocs::Settings->HighlightCode()) ||
        -            						  ($codeType eq "anonymous" && NaturalDocs::Settings->HighlightAnonymous()) );
        -
        -            $output .= '<blockquote><pre' . ($highlight ? ' class="prettyprint"' : '') . '>';
        -            $inCode = 1;
        -            }
        -        elsif ($text eq '</code>')
        -            {
        -            $output .= '</pre></blockquote>';
        -            $inCode = undef;
        -            }
        -        elsif ($inCode)
        -            {
        -            # Leave line breaks in.
        -            $output .= $text;
        -            }
        -        else
        -            {
        -            # Format non-code text.
        -
        -            # Convert linked images.
        -            if ($text =~ /<img mode=\"link\"/)
        -                {
        -                if ($style == NDMARKUPTOHTML_GENERAL)
        -                    {
        -                    # Split by tags we would want to see the linked images appear after.  For example, an image link appearing in
        -                    # the middle of a paragraph would appear after the end of that paragraph.
        -                    my @imageBlocks = split(/(<p>.*?<\/p>|<dl>.*?<\/dl>|<ul>.*?<\/ul>)/, $text);
        -                    $text = undef;
        -
        -                    foreach my $imageBlock (@imageBlocks)
        -                        {
        -                        $imageBlock =~ s{<img mode=\"link\" target=\"([^\"]*)\" original=\"([^\"]*)\">}
        -                                                {$self->BuildImage($sourceFile, 'link', $1, $2)}ge;
        -
        -                        $text .= $imageBlock . $imageContent;
        -                        $imageContent = undef;
        -                        };
        -                    }
        -
        -                # Use only the text for tooltips and summaries.
        -                else
        -                    {
        -                    $text =~ s{<img mode=\"link\" target=\"[^\"]*\" original=\"([^\"]*)\">}{$1}g;
        -                    };
        -                };
        -
        -            # Convert quotes to fancy quotes.  This has to be done before links because some of them may have JavaScript
        -            # attributes that use the apostrophe character.
        -            $text =~ s/^\'/&lsquo;/gm;
        -            $text =~ s/([\ \(\[\{])\'/$1&lsquo;/g;
        -            $text =~ s/\'/&rsquo;/g;
        -
        -            $text =~ s/^&quot;/&ldquo;/gm;
        -            $text =~ s/([\ \(\[\{])&quot;/$1&ldquo;/g;
        -            $text =~ s/&quot;/&rdquo;/g;
        -
        -            # Resolve and convert links, except for tooltips.
        -            if ($style != NDMARKUPTOHTML_TOOLTIP)
        -                {
        -                $text =~ s{<link target=\"([^\"]*)\" name=\"([^\"]*)\" original=\"([^\"]*)\">}
        -                               {$self->BuildTextLink($1, $2, $3, $package, $using, $sourceFile)}ge;
        -                $text =~ s/<url target=\"([^\"]*)\" name=\"([^\"]*)\">/$self->BuildURLLink($1, $2)/ge;
        -                }
        -            else
        -                {
        -                $text =~ s{<link target=\"[^\"]*\" name=\"([^\"]*)\" original=\"[^\"]*\">}{$1}g;
        -                $text =~ s{<url target=\"[^\"]*\" name=\"([^\"]*)\">}{$1}g;
        -                };
        -
        -            # We do full e-mail links anyway just so the obfuscation remains.
        -            $text =~ s/<email target=\"([^\"]*)\" name=\"([^\"]*)\">/$self->BuildEMailLink($1, $2)/ge;
        -
        -
        -            # Convert inline images, but only for the general style.
        -            if ($style == NDMARKUPTOHTML_GENERAL)
        -                {
        -                $text =~ s{<img mode=\"inline\" target=\"([^\"]*)\" original=\"([^\"]*)\">}
        -                               {$self->BuildImage($sourceFile, 'inline', $1, $2)}ge;
        -                }
        -            else
        -                {
        -                $text =~ s{<img mode=\"inline\" target=\"[^\"]*\" original=\"([^\"]*)\">}{$1}g;
        -                };
        -
        -            # Copyright symbols.  Prevent conversion when part of (a), (b), (c) lists.
        -            if ($text !~ /\(a\)/i)
        -                {  $text =~ s/\(c\)/&copy;/gi;  };
        -
        -            # Trademark symbols.
        -            $text =~ s/\(tm\)/&trade;/gi;
        -            $text =~ s/\(r\)/&reg;/gi;
        -
        -            # Add double spaces too.
        -            $text = $self->AddDoubleSpaces($text);
        -
        -            # Headings
        -            $text =~ s/<h>/<h4 class=CHeading>/g;
        -            $text =~ s/<\/h>/<\/h4>/g;
        -
        -            # Description Lists
        -            $text =~ s/<dl>/<table border=0 cellspacing=0 cellpadding=0 class=CDescriptionList>/g;
        -            $text =~ s/<\/dl>/<\/table>/g;
        -
        -            $text =~ s/<de>/<tr><td class=CDLEntry>/g;
        -            $text =~ s/<\/de>/<\/td>/g;
        -
        -            if ($dlSymbolBehavior == ::ENUM_GLOBAL())
        -                {  $text =~ s/<ds>([^<]+)<\/ds>/$self->MakeDescriptionListSymbol(undef, $1)/ge;  }
        -            elsif ($dlSymbolBehavior == ::ENUM_UNDER_PARENT())
        -                {  $text =~ s/<ds>([^<]+)<\/ds>/$self->MakeDescriptionListSymbol($package, $1)/ge;  }
        -            else # ($dlSymbolBehavior == ::ENUM_UNDER_TYPE())
        -                {  $text =~ s/<ds>([^<]+)<\/ds>/$self->MakeDescriptionListSymbol($symbol, $1)/ge;  }
        -
        -            sub MakeDescriptionListSymbol #(package, text)
        -                {
        -                my ($self, $package, $text) = @_;
        -
        -                $text = NaturalDocs::NDMarkup->RestoreAmpChars($text);
        -                my $symbol = NaturalDocs::SymbolString->FromText($text);
        -
        -                if (defined $package)
        -                    {  $symbol = NaturalDocs::SymbolString->Join($package, $symbol);  };
        -
        -                return
        -                '<tr>'
        -                    . '<td class=CDLEntry>'
        -                        # The anchors are closed, but not around the text, to prevent the :hover CSS style from kicking in.
        -                        . '<a name="' . $self->SymbolToHTMLSymbol($symbol) . '"></a>'
        -                        . $text
        -                    . '</td>';
        -                };
        -
        -            $text =~ s/<dd>/<td class=CDLDescription>/g;
        -            $text =~ s/<\/dd>/<\/td><\/tr>/g;
        -
        -            $output .= $text;
        -            };
        -        };
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildTextLink
        -#
        -#   Creates a HTML link to a symbol, if it exists.
        -#
        -#   Parameters:
        -#
        -#       target  - The link text.
        -#       name - The link name.
        -#       original - The original text as it appears in the source.
        -#       package  - The package <SymbolString> the link appears in, or undef if none.
        -#       using - An arrayref of additional scope <SymbolStrings> the link has access to, or undef if none.
        -#       sourceFile  - The <FileName> the link appears in.
        -#
        -#       Target, name, and original are assumed to still have <NDMarkup> amp chars.
        -#
        -#   Returns:
        -#
        -#       The link in HTML, including tags.  If the link doesn't resolve to anything, returns the HTML that should be substituted for it.
        -#
        -sub BuildTextLink #(target, name, original, package, using, sourceFile)
        -    {
        -    my ($self, $target, $name, $original, $package, $using, $sourceFile) = @_;
        -
        -    my $plainTarget = $self->RestoreAmpChars($target);
        -
        -    my $symbol = NaturalDocs::SymbolString->FromText($plainTarget);
        -    my $symbolTarget = NaturalDocs::SymbolTable->References(::REFERENCE_TEXT(), $symbol, $package, $using, $sourceFile);
        -
        -    if (defined $symbolTarget)
        -        {
        -        my $symbolTargetFile;
        -
        -        if ($symbolTarget->File() ne $sourceFile)
        -            {
        -            $symbolTargetFile = $self->MakeRelativeURL( $self->OutputFileOf($sourceFile),
        -                                                                               $self->OutputFileOf($symbolTarget->File()), 1 );
        -            };
        -        # else leave it undef
        -
        -        my $symbolTargetTooltipID = $self->BuildToolTip($symbolTarget->Symbol(), $sourceFile, $symbolTarget->Type(),
        -                                                                                 $symbolTarget->Prototype(), $symbolTarget->Summary());
        -
        -        my $toolTipProperties = $self->BuildToolTipLinkProperties($symbolTargetTooltipID);
        -
        -        return '<a href="' . $symbolTargetFile . '#' . $self->SymbolToHTMLSymbol($symbolTarget->Symbol()) . '" '
        -                    . 'class=L' . NaturalDocs::Topics->NameOfType($symbolTarget->Type(), 0, 1) . ' ' . $toolTipProperties . '>'
        -                        . $name
        -                    . '</a>';
        -        }
        -    else
        -        {
        -        return $original;
        -        };
        -    };
        -
        -
        -#
        -#   Function: BuildURLLink
        -#
        -#   Creates a HTML link to an external URL.  Long URLs will have hidden breaks to allow them to wrap.
        -#
        -#   Parameters:
        -#
        -#       target - The URL to link to.
        -#       name - The label of the link.
        -#
        -#       Both are assumed to still have <NDMarkup> amp chars.
        -#
        -#   Returns:
        -#
        -#       The HTML link, complete with tags.
        -#
        -sub BuildURLLink #(target, name)
        -    {
        -    my ($self, $target, $name) = @_;
        -
        -    # Don't restore amp chars on the target.
        -
        -    if (length $name < 50 || $name ne $target)
        -        {  return '<a href="' . $target . '" class=LURL target=_top>' . $name . '</a>';  };
        -
        -    my @segments = split(/([\,\/]|&amp;)/, $target);
        -    my $output = '<a href="' . $target . '" class=LURL target=_top>';
        -
        -    # Get past the first batch of slashes, since we don't want to break on things like http://.
        -
        -    $output .= $segments[0];
        -
        -    my $i = 1;
        -    while ($i < scalar @segments && ($segments[$i] eq '/' || !$segments[$i]))
        -        {
        -        $output .= $segments[$i];
        -        $i++;
        -        };
        -
        -    # Now break on each one of those symbols.
        -
        -    while ($i < scalar @segments)
        -        {
        -        if ($segments[$i] eq ',' || $segments[$i] eq '/' || $segments[$i] eq '&amp;')
        -            {  $output .= '<wbr>';  };
        -
        -        $output .= $segments[$i];
        -        $i++;
        -        };
        -
        -    $output .= '</a>';
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildEMailLink
        -#
        -#   Creates a HTML link to an e-mail address.  The address will be transparently munged to protect it (hopefully) from spambots.
        -#
        -#   Parameters:
        -#
        -#       target  - The e-mail address.
        -#       name - The label of the link.
        -#
        -#       Both are assumed to still have <NDMarkup> amp chars.
        -#
        -#   Returns:
        -#
        -#       The HTML e-mail link, complete with tags.
        -#
        -sub BuildEMailLink #(target, name)
        -    {
        -    my ($self, $target, $name) = @_;
        -    my @splitAddress;
        -
        -
        -    # Hack the address up.  We want two user pieces and two host pieces.
        -
        -    my ($user, $host) = split(/\@/, $self->RestoreAmpChars($target));
        -
        -    my $userSplit = length($user) / 2;
        -
        -    push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($user, 0, $userSplit) );
        -    push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($user, $userSplit) );
        -
        -    push @splitAddress, '@';
        -
        -    my $hostSplit = length($host) / 2;
        -
        -    push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($host, 0, $hostSplit) );
        -    push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($host, $hostSplit) );
        -
        -
        -    # Now put it back together again.  We'll use spans to split the text transparently and JavaScript to split and join the link.
        -
        -    my $output =
        -    "<a href=\"#\" onClick=\"location.href='mai' + 'lto:' + '" . join("' + '", @splitAddress) . "'; return false;\" class=LEMail>";
        -
        -    if ($name eq $target)
        -        {
        -        $output .=
        -        $splitAddress[0] . '<span style="display: none">.nosp@m.</span>' . $splitAddress[1]
        -        . '<span>@</span>'
        -        . $splitAddress[3] . '<span style="display: none">.nosp@m.</span>' . $splitAddress[4];
        -        }
        -    else
        -        {  $output .= $name;  };
        -
        -    $output .= '</a>';
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: BuildImage
        -#
        -#   Builds the HTML for an image.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> this image appears in.
        -#       mode - Either "inline" or "link".
        -#       target - The target.
        -#       original - The original text.
        -#
        -#       All are assumed to still have <NDMarkup> amp chars.
        -#
        -#   Returns:
        -#
        -#       The result in HTML.  If the mode was "link", the target image's HTML is added to <imageContent>.
        -#
        -sub BuildImage #(sourceFile, mode, target, original)
        -    {
        -    my ($self, $sourceFile, $mode, $target, $original) = @_;
        -
        -    my $targetNoAmp = $self->RestoreAmpChars($target);
        -
        -    my $image = NaturalDocs::ImageReferenceTable->GetReferenceTarget($sourceFile, $targetNoAmp);
        -
        -    if ($image)
        -        {
        -        my ($width, $height) = NaturalDocs::Project->ImageFileDimensions($image);
        -
        -        if ($mode eq 'inline')
        -            {
        -            return
        -            '<img src="' . $self->MakeRelativeURL($self->OutputFileOf($sourceFile),
        -                                                                       $self->OutputImageOf($image), 1) . '"'
        -
        -            . ($width && $height ? ' width="' . $width . '" height="' . $height . '"' : '')
        -            . '>';
        -            }
        -        else # link
        -            {
        -            # Make the text a little more friendly in the output by removing any folders and file extensions.
        -            # (see images/Table1.gif) will be turned into (see Table1).
        -            my $originalNoAmp = $self->RestoreAmpChars($original);
        -            my $targetIndex = index($originalNoAmp, $targetNoAmp);
        -            my ($shortTarget, $shortTargetNoAmp, $shortOriginal);
        -
        -            if ($targetIndex != -1)
        -                {
        -                $shortTargetNoAmp = (NaturalDocs::File->SplitPath($targetNoAmp))[2];
        -                $shortTargetNoAmp = NaturalDocs::File->NoExtension($shortTargetNoAmp);
        -
        -                substr($originalNoAmp, $targetIndex, length($targetNoAmp), $shortTargetNoAmp);
        -
        -                $shortOriginal = NaturalDocs::NDMarkup->ConvertAmpChars($originalNoAmp);
        -                $shortTarget = NaturalDocs::NDMarkup->ConvertAmpChars($shortTargetNoAmp);
        -                };
        -
        -            my $output =
        -            '<a href="#Image' . $imageAnchorNumber . '" class=CImageLink>'
        -                . ($shortOriginal || $original)
        -            . '</a>';
        -
        -            $imageContent .=
        -            '<blockquote>'
        -            . '<div class=CImage>'
        -                . '<a name="Image' . $imageAnchorNumber . '"></a>'
        -                . '<div class=CImageCaption>' . ($shortTarget || $target) . '</div>'
        -                . '<img src="' . $self->MakeRelativeURL($self->OutputFileOf($sourceFile),
        -                                                                           $self->OutputImageOf($image), 1) . '"'
        -
        -                . ($width && $height ? ' width="' . $width . '" height="' . $height . '"' : '')
        -                . '>'
        -
        -            . '</div></blockquote>';
        -
        -            $imageAnchorNumber++;
        -            return $output;
        -            };
        -        }
        -    else # !$image
        -        {
        -        if ($mode eq 'inline')
        -            {  return '<p>' . $original . '</p>';  }
        -        else #($mode eq 'link')
        -            {  return $original;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: BuildToolTipLinkProperties
        -#
        -#   Returns the properties that should go in the link tag to add a tooltip to it.  Because the function accepts undef, you can
        -#   call it without checking if <BuildToolTip()> returned undef or not.
        -#
        -#   Parameters:
        -#
        -#       toolTipID - The ID of the tooltip.  If undef, the function will return undef.
        -#
        -#   Returns:
        -#
        -#       The properties that should be put in the link tag, or undef if toolTipID wasn't specified.
        -#
        -sub BuildToolTipLinkProperties #(toolTipID)
        -    {
        -    my ($self, $toolTipID) = @_;
        -
        -    if (defined $toolTipID)
        -        {
        -        my $currentNumber = $tooltipLinkNumber;
        -        $tooltipLinkNumber++;
        -
        -        return 'id=link' . $currentNumber . ' '
        -                . 'onMouseOver="ShowTip(event, \'' . $toolTipID . '\', \'link' . $currentNumber . '\')" '
        -                . 'onMouseOut="HideTip(\'' . $toolTipID . '\')"';
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: AddDoubleSpaces
        -#
        -#   Adds second spaces after the appropriate punctuation with &nbsp; so they show up in HTML.  They don't occur if there isn't at
        -#   least one space after the punctuation, so things like class.member notation won't be affected.
        -#
        -#   Parameters:
        -#
        -#       text - The text to convert.
        -#
        -#   Returns:
        -#
        -#       The text with double spaces as necessary.
        -#
        -sub AddDoubleSpaces #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    # Question marks and exclamation points get double spaces unless followed by a lowercase letter.
        -
        -    $text =~ s/  ([^\ \t\r\n] [\!\?])  # Must appear after a non-whitespace character to apply.
        -
        -                      (&quot;|&[lr][sd]quo;|[\'\"\]\}\)]?)  # Tolerate closing quotes, parenthesis, etc.
        -                      ((?:<[^>]+>)*)  # Tolerate tags
        -
        -                      \   # The space
        -                      (?![a-z])  # Not followed by a lowercase character.
        -
        -                   /$1$2$3&nbsp;\ /gx;
        -
        -
        -    # Periods get double spaces if it's not followed by a lowercase letter.  However, if it's followed by a capital letter and the
        -    # preceding word is in the list of acceptable abbreviations, it won't get the double space.  Yes, I do realize I am seriously
        -    # over-engineering this.
        -
        -    $text =~ s/  ([^\ \t\r\n]+)  # The word prior to the period.
        -
        -                      \.
        -
        -                      (&quot;|&[lr][sd]quo;|[\'\"\]\}\)]?)  # Tolerate closing quotes, parenthesis, etc.
        -                      ((?:<[^>]+>)*)  # Tolerate tags
        -
        -                      \   # The space
        -                      ([^a-z])   # The next character, if it's not a lowercase letter.
        -
        -                  /$1 . '.' . $2 . $3 . MaybeExpand($1, $4) . $4/gex;
        -
        -    sub MaybeExpand #(leadWord, nextLetter)
        -        {
        -        my ($leadWord, $nextLetter) = @_;
        -
        -        if ($nextLetter =~ /^[A-Z]$/ && exists $abbreviations{ lc($leadWord) } )
        -            { return ' '; }
        -        else
        -            { return '&nbsp; '; };
        -        };
        -
        -    return $text;
        -    };
        -
        -
        -#
        -#   Function: ConvertAmpChars
        -#
        -#   Converts certain characters to their HTML amp char equivalents.
        -#
        -#   Parameters:
        -#
        -#       text - The text to convert.
        -#
        -#   Returns:
        -#
        -#       The converted text.
        -#
        -sub ConvertAmpChars #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ s/&/&amp;/g;
        -    $text =~ s/\"/&quot;/g;
        -    $text =~ s/</&lt;/g;
        -    $text =~ s/>/&gt;/g;
        -
        -    return $text;
        -    };
        -
        -
        -#
        -#   Function: RestoreAmpChars
        -#
        -#   Restores all amp characters to their original state.  This works with both <NDMarkup> amp chars and fancy quotes.
        -#
        -#   Parameters:
        -#
        -#       text - The text to convert.
        -#
        -#   Returns:
        -#
        -#       The converted text.
        -#
        -sub RestoreAmpChars #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text = NaturalDocs::NDMarkup->RestoreAmpChars($text);
        -    $text =~ s/&[lr]squo;/\'/g;
        -    $text =~ s/&[lr]dquo;/\"/g;
        -
        -    return $text;
        -    };
        -
        -
        -#
        -#   Function: AddHiddenBreaks
        -#
        -#   Adds hidden breaks to symbols.  Puts them after symbol and directory separators so long names won't screw up the layout.
        -#
        -#   Parameters:
        -#
        -#       string - The string to break.
        -#
        -#   Returns:
        -#
        -#       The string with hidden breaks.
        -#
        -sub AddHiddenBreaks #(string)
        -    {
        -    my ($self, $string) = @_;
        -
        -    # \.(?=.{5,}) instead of \. so file extensions don't get breaks.
        -    # :+ instead of :: because Mac paths are separated by a : and we want to get those too.
        -
        -    $string =~ s/(\w(?:\.(?=.{5,})|:+|->|\\|\/))(\w)/$1 . '<wbr>' . $2/ge;
        -
        -    return $string;
        -    };
        -
        -
        -#
        -#   Function: FindFirstFile
        -#
        -#   A function that finds and returns the first file entry in the menu, or undef if none.
        -#
        -sub FindFirstFile
        -    {
        -    # Hidden parameter: arrayref
        -    # Used for recursion only.
        -
        -    my ($self, $arrayref) = @_;
        -
        -    if (!defined $arrayref)
        -        {  $arrayref = NaturalDocs::Menu->Content();  };
        -
        -    foreach my $entry (@$arrayref)
        -        {
        -        if ($entry->Type() == ::MENU_FILE())
        -            {
        -            return $entry;
        -            }
        -        elsif ($entry->Type() == ::MENU_GROUP())
        -            {
        -            my $result = $self->FindFirstFile($entry->GroupContent());
        -            if (defined $result)
        -                {  return $result;  };
        -            };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: ExpandMenu
        -#
        -#   Determines which groups should be expanded.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to use if you're looking for a source file.
        -#       indexType - The index <TopicType> to use if you're looking for an index.
        -#       selectionHierarchy - The <FileName> the menu is being built for.  Does not have to be on the menu itself.
        -#       rootLength - The length of the menu's root group, *not* including the contents of subgroups.
        -#
        -#   Returns:
        -#
        -#       An arrayref of all the group numbers that should be expanded.  At minimum, it will contain the numbers of the groups
        -#       present in <menuSelectionHierarchy>, though it may contain more.
        -#
        -sub ExpandMenu #(FileName sourceFile, TopicType indexType, NaturalDocs::Menu::Entry[] selectionHierarchy, int rootLength) -> int[] groupsToExpand
        -    {
        -    my ($self, $sourceFile, $indexType, $menuSelectionHierarchy, $rootLength) = @_;
        -
        -    my $toExpand = [ ];
        -
        -
        -    # First expand everything in the selection hierarchy.
        -
        -    my $length = $rootLength;
        -
        -    foreach my $entry (@$menuSelectionHierarchy)
        -        {
        -        $length += $menuGroupLengths{$entry};
        -        push @$toExpand, $menuGroupNumbers{$entry};
        -        };
        -
        -
        -    # Now do multiple passes of group expansion as necessary.  We start from bottomIndex and expand outwards.  We stop going
        -    # in a direction if a group there is too long -- we do not skip over it and check later groups as well.  However, if one direction
        -    # stops, the other can keep going.
        -
        -    my $pass = 1;
        -    my $hasSubGroups;
        -
        -    while ($length < MENU_LENGTH_LIMIT)
        -        {
        -        my $content;
        -        my $topIndex;
        -        my $bottomIndex;
        -
        -
        -        if ($pass == 1)
        -            {
        -            # First pass, we expand the selection's siblings.
        -
        -            if (scalar @$menuSelectionHierarchy)
        -                {  $content = $menuSelectionHierarchy->[0]->GroupContent();  }
        -            else
        -                {  $content = NaturalDocs::Menu->Content();  };
        -
        -            $bottomIndex = 0;
        -
        -            while ($bottomIndex < scalar @$content &&
        -                     !($content->[$bottomIndex]->Type() == ::MENU_FILE() &&
        -                       $content->[$bottomIndex]->Target() eq $sourceFile) &&
        -                     !($content->[$bottomIndex]->Type() != ::MENU_INDEX() &&
        -                       $content->[$bottomIndex]->Target() eq $indexType) )
        -                {  $bottomIndex++;  };
        -
        -            if ($bottomIndex == scalar @$content)
        -                {  $bottomIndex = 0;  };
        -            $topIndex = $bottomIndex - 1;
        -            }
        -
        -        elsif ($pass == 2)
        -            {
        -            # If the section we just expanded had no sub-groups, do another pass trying to expand the parent's sub-groups.  The
        -            # net effect is that groups won't collapse as much unnecessarily.  Someone can click on a file in a sub-group and the
        -            # groups in the parent will stay open.
        -
        -            if (!$hasSubGroups && scalar @$menuSelectionHierarchy)
        -                {
        -                if (scalar @$menuSelectionHierarchy > 1)
        -                    {  $content = $menuSelectionHierarchy->[1]->GroupContent();  }
        -                else
        -                    {  $content = NaturalDocs::Menu->Content();  };
        -
        -                $bottomIndex = 0;
        -
        -                while ($bottomIndex < scalar @$content &&
        -                         $content->[$bottomIndex] != $menuSelectionHierarchy->[0])
        -                    {  $bottomIndex++;  };
        -
        -                $topIndex = $bottomIndex - 1;
        -                $bottomIndex++;  # Increment past our own group.
        -                $hasSubGroups = undef;
        -                }
        -            else
        -                {  last;  };
        -            }
        -
        -        # No more passes.
        -        else
        -            {  last;  };
        -
        -
        -        while ( ($topIndex >= 0 || $bottomIndex < scalar @$content) && $length < MENU_LENGTH_LIMIT)
        -            {
        -            # We do the bottom first.
        -
        -            while ($bottomIndex < scalar @$content && $content->[$bottomIndex]->Type() != ::MENU_GROUP())
        -                {  $bottomIndex++;  };
        -
        -            if ($bottomIndex < scalar @$content)
        -                {
        -                my $bottomEntry = $content->[$bottomIndex];
        -                $hasSubGroups = 1;
        -
        -                if ($length + $menuGroupLengths{$bottomEntry} <= MENU_LENGTH_LIMIT)
        -                    {
        -                    $length += $menuGroupLengths{$bottomEntry};
        -                    push @$toExpand, $menuGroupNumbers{$bottomEntry};
        -                    $bottomIndex++;
        -                    }
        -                else
        -                    {  $bottomIndex = scalar @$content;  };
        -                };
        -
        -            # Top next.
        -
        -            while ($topIndex >= 0 && $content->[$topIndex]->Type() != ::MENU_GROUP())
        -                {  $topIndex--;  };
        -
        -            if ($topIndex >= 0)
        -                {
        -                my $topEntry = $content->[$topIndex];
        -                $hasSubGroups = 1;
        -
        -                if ($length + $menuGroupLengths{$topEntry} <= MENU_LENGTH_LIMIT)
        -                    {
        -                    $length += $menuGroupLengths{$topEntry};
        -                    push @$toExpand, $menuGroupNumbers{$topEntry};
        -                    $topIndex--;
        -                    }
        -                else
        -                    {  $topIndex = -1;  };
        -                };
        -            };
        -
        -
        -        $pass++;
        -        };
        -
        -    return $toExpand;
        -    };
        -
        -
        -#
        -#   Function: GetMenuSelectionHierarchy
        -#
        -#   Finds the sequence of menu groups that contain the current selection.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to use if you're looking for a source file.
        -#       indexType - The index <TopicType> to use if you're looking for an index.
        -#
        -#   Returns:
        -#
        -#       An arrayref of the <NaturalDocs::Menu::Entry> objects of each group surrounding the selected menu item.  First entry is the
        -#       group immediately encompassing it, and each subsequent entry works its way towards the outermost group.
        -#
        -sub GetMenuSelectionHierarchy #(FileName sourceFile, TopicType indexType) -> NaturalDocs::Menu::Entry[] selectionHierarchy
        -    {
        -    my ($self, $sourceFile, $indexType) = @_;
        -
        -    my $hierarchy = [ ];
        -
        -    $self->FindMenuSelection($sourceFile, $indexType, $hierarchy, NaturalDocs::Menu->Content());
        -
        -    return $hierarchy;
        -    };
        -
        -
        -#
        -#   Function: FindMenuSelection
        -#
        -#   A recursive function that deterimes if it or any of its sub-groups has the menu selection.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to use if you're looking for a source file.
        -#       indexType - The index <TopicType> to use if you're looking for an index.
        -#       hierarchyRef - A reference to the menu selection hierarchy.
        -#       entries - An arrayref of <NaturalDocs::Menu::Entries> to search.
        -#
        -#   Returns:
        -#
        -#       Whether this group or any of its subgroups had the selection.  If true, it will add any subgroups to the menu selection
        -#       hierarchy but not itself.  This prevents the topmost entry from being added.
        -#
        -sub FindMenuSelection #(FileName sourceFile, TopicType indexType, NaturalDocs::Menu::Entry[] hierarchyRef, NaturalDocs::Menu::Entry[] entries) -> bool hasSelection
        -    {
        -    my ($self, $sourceFile, $indexType, $hierarchyRef, $entries) = @_;
        -
        -    foreach my $entry (@$entries)
        -        {
        -        if ($entry->Type() == ::MENU_GROUP())
        -            {
        -            # If the subgroup has the selection...
        -            if ( $self->FindMenuSelection($sourceFile, $indexType, $hierarchyRef, $entry->GroupContent()) )
        -                {
        -                push @$hierarchyRef, $entry;
        -                return 1;
        -                };
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_FILE())
        -            {
        -            if ($sourceFile eq $entry->Target())
        -                {  return 1;  };
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_INDEX())
        -            {
        -            if ($indexType eq $entry->Target)
        -                {  return 1;  };
        -            };
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -#
        -#   Function: ResetToolTips
        -#
        -#   Resets the <ToolTip Package Variables> for a new page.
        -#
        -#   Parameters:
        -#
        -#       samePage  - Set this flag if there's the possibility that the next batch of tooltips may be on the same page as the last.
        -#
        -sub ResetToolTips #(samePage)
        -    {
        -    my ($self, $samePage) = @_;
        -
        -    if (!$samePage)
        -        {
        -        $tooltipLinkNumber = 1;
        -        $tooltipNumber = 1;
        -        };
        -
        -    $tooltipHTML = undef;
        -    %tooltipSymbolsToNumbers = ( );
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy.pm b/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy.pm
        deleted file mode 100644
        index 4b01b9a02..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy.pm
        +++ /dev/null
        @@ -1,861 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::ClassHierarchy
        -#
        -###############################################################################
        -#
        -#   A package that handles all the gory details of managing the class hierarchy.  It handles the hierarchy itself, which files define
        -#   them, rebuilding the files that are affected by changes, and loading and saving them to a file.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - <NaturalDocs::Settings> and <NaturalDocs::Project> must be initialized before use.
        -#
        -#       - <NaturalDocs::SymbolTable> must be initialized before <Load()> is called.  It must reflect the state as of the last time
        -#          Natural Docs was run.
        -#
        -#       - <Load()> must be called to initialize the package.  At this point, the <Information Functions> will return the state as
        -#         of the last time Natural Docs was run.  You are free to resolve <NaturalDocs::SymbolTable()> afterwards.
        -#
        -#       - <Purge()> must be called, and then <NaturalDocs::Parser->ParseForInformation()> must be called on all files that
        -#         have changed so it can fully resolve the hierarchy via the <Modification Functions()>.  Afterwards the
        -#         <Information Functions> will reflect the current state of the code.
        -#
        -#       - <Save()> must be called to commit any changes to the symbol table back to disk.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use strict;
        -use integer;
        -
        -use NaturalDocs::ClassHierarchy::Class;
        -use NaturalDocs::ClassHierarchy::File;
        -
        -package NaturalDocs::ClassHierarchy;
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -#
        -#   handle: CLASS_HIERARCHY_FILEHANDLE
        -#   The file handle used with <ClassHierarchy.nd>.
        -#
        -
        -#
        -#   hash: classes
        -#
        -#   A hash of all the classes.  The keys are the class <SymbolStrings> and the values are <NaturalDocs::ClassHierarchy::Classes>.
        -#
        -my %classes;
        -
        -#
        -#   hash: files
        -#
        -#   A hash of the hierarchy information referenced by file.  The keys are the <FileNames>, and the values are
        -#   <NaturalDocs::ClassHierarchy::File>s.
        -#
        -my %files;
        -
        -#
        -#   hash: parentReferences
        -#
        -#   A hash of all the parent reference strings and what they resolve to.  The keys are the <ReferenceStrings> and the values are
        -#   the class <SymbolStrings> that they resolve to.
        -#
        -my %parentReferences;
        -
        -#
        -#   object: watchedFile
        -#
        -#   A <NaturalDocs::ClassHierarchy::File> object of the file being watched for changes.  This is compared to the version in <files>
        -#   to see if anything was changed since the last parse.
        -#
        -my $watchedFile;
        -
        -#
        -#   string: watchedFileName
        -#
        -#   The <FileName> of the watched file, if any.  If there is no watched file, this will be undef.
        -#
        -my $watchedFileName;
        -
        -#
        -#   bool: dontRebuildFiles
        -#
        -#   A bool to set if you don't want changes in the hierarchy to cause files to be rebuilt.
        -#
        -my $dontRebuildFiles;
        -
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: ClassHierarchy.nd
        -#
        -#   Stores the class hierarchy on disk.
        -#
        -#   Format:
        -#
        -#       > [BINARY_FORMAT]
        -#       > [VersionInt: app version]
        -#
        -#       The standard <BINARY_FORMAT> and <VersionInt> header.
        -#
        -#       > [SymbolString: class or undef to end]
        -#
        -#       Next we begin a class segment with its <SymbolString>.  These continue until the end of the file.  Only defined classes are
        -#       included.
        -#
        -#       > [UInt32: number of files]
        -#       > [AString16: file] [AString16: file] ...
        -#
        -#       Next there is the number of files that define that class.  It's a UInt32, which seems like overkill, but I could imagine every
        -#       file in a huge C++ project being under the same namespace, and thus contributing its own definition.  It's theoretically
        -#       possible.
        -#
        -#       Following the number is that many file names.  You must remember the index of each file, as they will be important later.
        -#       Indexes start at one because zero has a special meaning.
        -#
        -#       > [UInt8: number of parents]
        -#       > ( [ReferenceString (no type): parent]
        -#       >   [UInt32: file index] [UInt32: file index] ... [UInt32: 0] ) ...
        -#
        -#       Next there is the number of parents defined for this class.  For each one, we define a parent segment, which consists of
        -#       its <ReferenceString>, and then a zero-terminated string of indexes of the files that define that parent as part of that class.
        -#       The indexes start at one, and are into the list of files we saw previously.
        -#
        -#       Note that we do store class segments for classes without parents, but not for undefined classes.
        -#
        -#       This concludes a class segment.  These segments continue until an undef <SymbolString>.
        -#
        -#   See Also:
        -#
        -#       <File Format Conventions>
        -#
        -#   Revisions:
        -#
        -#       1.22:
        -#
        -#           - Classes and parents switched from AString16s to <SymbolStrings> and <ReferenceStrings>.
        -#           - A ending undef <SymbolString> was added to the end.  Previously it stopped when the file ran out.
        -#
        -#       1.2:
        -#
        -#           - This file was introduced in 1.2.
        -#
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Loads the class hierarchy from disk.
        -#
        -sub Load
        -    {
        -    my ($self) = @_;
        -
        -    $dontRebuildFiles = 1;
        -
        -    my $fileIsOkay;
        -    my $fileName = NaturalDocs::Project->DataFile('ClassHierarchy.nd');
        -
        -    if (!NaturalDocs::Settings->RebuildData() && open(CLASS_HIERARCHY_FILEHANDLE, '<' . $fileName))
        -        {
        -        # See if it's binary.
        -        binmode(CLASS_HIERARCHY_FILEHANDLE);
        -
        -        my $firstChar;
        -        read(CLASS_HIERARCHY_FILEHANDLE, $firstChar, 1);
        -
        -        if ($firstChar != ::BINARY_FORMAT())
        -            {
        -            close(CLASS_HIERARCHY_FILEHANDLE);
        -            }
        -        else
        -            {
        -            my $version = NaturalDocs::Version->FromBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE);
        -
        -            # Minor bugs were fixed in 1.33 that may affect the stored data.
        -
        -            if (NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.33') ))
        -                {  $fileIsOkay = 1;  }
        -            else
        -                {  close(CLASS_HIERARCHY_FILEHANDLE);  };
        -            };
        -        };
        -
        -
        -    if (!$fileIsOkay)
        -        {
        -        NaturalDocs::Project->ReparseEverything();
        -        }
        -    else
        -        {
        -        my $raw;
        -
        -        for (;;)
        -            {
        -            # [SymbolString: class or undef to end]
        -
        -            my $class = NaturalDocs::SymbolString->FromBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE);
        -
        -            if (!defined $class)
        -                {  last;  };
        -
        -            # [UInt32: number of files]
        -
        -            read(CLASS_HIERARCHY_FILEHANDLE, $raw, 4);
        -            my $numberOfFiles = unpack('N', $raw);
        -
        -            my @files;
        -
        -            while ($numberOfFiles)
        -                {
        -                # [AString16: file]
        -
        -                read(CLASS_HIERARCHY_FILEHANDLE, $raw, 2);
        -                my $fileLength = unpack('n', $raw);
        -
        -                my $file;
        -                read(CLASS_HIERARCHY_FILEHANDLE, $file, $fileLength);
        -
        -                push @files, $file;
        -                $self->AddClass($file, $class, NaturalDocs::Languages->LanguageOf($file)->Name());
        -
        -                $numberOfFiles--;
        -                };
        -
        -            # [UInt8: number of parents]
        -
        -            read(CLASS_HIERARCHY_FILEHANDLE, $raw, 1);
        -            my $numberOfParents = unpack('C', $raw);
        -
        -            while ($numberOfParents)
        -                {
        -                # [ReferenceString (no type): parent]
        -
        -                my $parent = NaturalDocs::ReferenceString->FromBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE,
        -                                                                                                         ::BINARYREF_NOTYPE(),
        -                                                                                                         ::REFERENCE_CH_PARENT());
        -
        -                for (;;)
        -                    {
        -                    # [UInt32: file index or 0]
        -
        -                    read(CLASS_HIERARCHY_FILEHANDLE, $raw, 4);
        -                    my $fileIndex = unpack('N', $raw);
        -
        -                    if ($fileIndex == 0)
        -                        {  last;  }
        -
        -                    $self->AddParentReference( $files[$fileIndex - 1], $class, $parent );
        -                    };
        -
        -                $numberOfParents--;
        -                };
        -            };
        -
        -        close(CLASS_HIERARCHY_FILEHANDLE);
        -        };
        -
        -    $dontRebuildFiles = undef;
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves the class hierarchy to disk.
        -#
        -sub Save
        -    {
        -    my ($self) = @_;
        -
        -    open (CLASS_HIERARCHY_FILEHANDLE, '>' . NaturalDocs::Project->DataFile('ClassHierarchy.nd'))
        -        or die "Couldn't save " . NaturalDocs::Project->DataFile('ClassHierarchy.nd') . ".\n";
        -
        -    binmode(CLASS_HIERARCHY_FILEHANDLE);
        -
        -    print CLASS_HIERARCHY_FILEHANDLE '' . ::BINARY_FORMAT();
        -    NaturalDocs::Version->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, NaturalDocs::Settings->AppVersion());
        -
        -    while (my ($class, $classObject) = each %classes)
        -        {
        -        if ($classObject->IsDefined())
        -            {
        -            # [SymbolString: class or undef to end]
        -
        -            NaturalDocs::SymbolString->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, $class);
        -
        -            # [UInt32: number of files]
        -
        -            my @definitions = $classObject->Definitions();
        -            my %definitionIndexes;
        -
        -            print CLASS_HIERARCHY_FILEHANDLE pack('N', scalar @definitions);
        -
        -            for (my $i = 0; $i < scalar @definitions; $i++)
        -                {
        -                # [AString16: file]
        -                print CLASS_HIERARCHY_FILEHANDLE pack('nA*', length($definitions[$i]), $definitions[$i]);
        -                $definitionIndexes{$definitions[$i]} = $i + 1;
        -                };
        -
        -            # [UInt8: number of parents]
        -
        -            my @parents = $classObject->ParentReferences();
        -            print CLASS_HIERARCHY_FILEHANDLE pack('C', scalar @parents);
        -
        -            foreach my $parent (@parents)
        -                {
        -                # [ReferenceString (no type): parent]
        -
        -                NaturalDocs::ReferenceString->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, $parent, ::BINARYREF_NOTYPE());
        -
        -                # [UInt32: file index]
        -
        -                my @parentDefinitions = $classObject->ParentReferenceDefinitions($parent);
        -
        -                foreach my $parentDefinition (@parentDefinitions)
        -                    {
        -                    print CLASS_HIERARCHY_FILEHANDLE pack('N', $definitionIndexes{$parentDefinition});
        -                    };
        -
        -                # [UInt32: 0]
        -                print CLASS_HIERARCHY_FILEHANDLE pack('N', 0);
        -                };
        -            };
        -        };
        -
        -    # [SymbolString: class or undef to end]
        -
        -    NaturalDocs::SymbolString->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, undef);
        -
        -    close(CLASS_HIERARCHY_FILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: Purge
        -#
        -#   Purges the hierarchy of files that no longer have Natural Docs content.
        -#
        -sub Purge
        -    {
        -    my ($self) = @_;
        -
        -    my $filesToPurge = NaturalDocs::Project->FilesToPurge();
        -
        -    foreach my $file (keys %$filesToPurge)
        -        {
        -        $self->DeleteFile($file);
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Interface Functions
        -
        -
        -#
        -#   Function: OnInterpretationChange
        -#
        -#   Called by <NaturalDocs::SymbolTable> whenever a class hierarchy reference's intepretation changes, meaning it switched
        -#   from one symbol to another.
        -#
        -#       reference - The <ReferenceString> whose current interpretation changed.
        -#
        -sub OnInterpretationChange #(reference)
        -    {
        -    my ($self, $reference) = @_;
        -
        -    if (NaturalDocs::ReferenceString->TypeOf($reference) == ::REFERENCE_CH_PARENT())
        -        {
        -        # The approach here is simply to completely delete the reference and readd it.  This is less than optimal efficiency, since it's
        -        # being removed and added from %files too, even though that isn't required.  However, the simpler code is worth it
        -        # considering this will only happen when a parent reference becomes defined or undefined, or on the rare languages (like C#)
        -        # that allow relative parent references.
        -
        -        my $oldTargetSymbol = $parentReferences{$reference};
        -        my $oldTargetObject = $classes{$oldTargetSymbol};
        -
        -        my @classesWithReferenceParent = $oldTargetObject->Children();
        -
        -        # Each entry is an arrayref of file names.  Indexes are the same as classesWithReferenceParent's.
        -        my @filesDefiningReferenceParent;
        -
        -        foreach my $classWithReferenceParent (@classesWithReferenceParent)
        -            {
        -            my $fileList = [ $classes{$classWithReferenceParent}->ParentReferenceDefinitions($reference) ];
        -            push @filesDefiningReferenceParent, $fileList;
        -
        -            foreach my $fileDefiningReferenceParent (@$fileList)
        -                {
        -                $self->DeleteParentReference($fileDefiningReferenceParent, $classWithReferenceParent, $reference);
        -                };
        -            };
        -
        -
        -        # This will force the reference to be reinterpreted on the next add.
        -
        -        delete $parentReferences{$reference};
        -
        -
        -        # Now we can just readd it.
        -
        -        for (my $i = 0; $i < scalar @classesWithReferenceParent; $i++)
        -            {
        -            foreach my $file (@{$filesDefiningReferenceParent[$i]})
        -                {
        -                $self->AddParentReference($file, $classesWithReferenceParent[$i], $reference);
        -                };
        -            };
        -        };
        -
        -    # The only way for a REFERENCE_CH_CLASS reference to change is if the symbol is deleted.  That will be handled by
        -    # <AnalyzeChanges()>, so we don't need to do anything here.
        -    };
        -
        -
        -#
        -#   Function: OnTargetSymbolChange
        -#
        -#   Called by <NaturalDocs::SymbolTable> whenever a class hierarchy reference's target symbol changes, but the reference
        -#   still resolves to the same symbol.
        -#
        -#   Parameters:
        -#
        -#       reference - The <ReferenceString> that was affected by the change.
        -#
        -sub OnTargetSymbolChange #(reference)
        -    {
        -    my ($self, $reference) = @_;
        -
        -    my $type = NaturalDocs::ReferenceString->TypeOf($reference);
        -    my $class;
        -
        -    if ($type == ::REFERENCE_CH_PARENT())
        -        {  $class = $parentReferences{$reference};  }
        -    else # ($type == ::REFERENCE_CH_CLASS())
        -        {
        -        # Class references are global absolute, so we can just yank the symbol.
        -        (undef, $class, undef, undef, undef, undef) = NaturalDocs::ReferenceString->InformationOf($reference);
        -        };
        -
        -    $self->RebuildFilesFor($class, 1, 0, 1);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -
        -#
        -#   Function: AddClass
        -#
        -#   Adds a class to the hierarchy.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> the class was defined in.
        -#       class - The class <SymbolString>.
        -#       languageName - The name of the language this applies to.
        -#
        -#   Note:
        -#
        -#       The file parameter must be defined when using this function externally.  It may be undef for internal use only.
        -#
        -sub AddClass #(file, class, languageName)
        -    {
        -    my ($self, $file, $class, $languageName) = @_;
        -
        -    if (!exists $classes{$class})
        -        {
        -        $classes{$class} = NaturalDocs::ClassHierarchy::Class->New();
        -        NaturalDocs::SymbolTable->AddReference($self->ClassReferenceOf($class, $languageName), $file)
        -        };
        -
        -    if (defined $file)
        -        {
        -        # If this was the first definition for this class...
        -        if ($classes{$class}->AddDefinition($file))
        -            {  $self->RebuildFilesFor($class, 1, 1, 1);  };
        -
        -        if (!exists $files{$file})
        -            {  $files{$file} = NaturalDocs::ClassHierarchy::File->New();  };
        -
        -        $files{$file}->AddClass($class);
        -
        -        if (defined $watchedFileName)
        -            {  $watchedFile->AddClass($class);  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: AddParentReference
        -#
        -#   Adds a class-parent relationship to the hierarchy.  The classes will be created if they don't already exist.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> the reference was defined in.
        -#       class - The class <SymbolString>.
        -#       symbol - The parent class <SymbolString>.
        -#       scope - The package <SymbolString> that the reference appeared in.
        -#       using - An arrayref of package <SymbolStrings> that the reference has access to via "using" statements.
        -#       resolvingFlags - Any <Resolving Flags> to be used when resolving the reference.
        -#
        -#   Alternate Parameters:
        -#
        -#       file - The <FileName> the reference was defined in.
        -#       class - The class <SymbolString>.
        -#       reference - The parent <ReferenceString>.
        -#
        -sub AddParentReference #(file, class, symbol, scope, using, resolvingFlags) or (file, class, reference)
        -    {
        -    my ($self, $file, $class, $symbol, $parentReference);
        -
        -    if (scalar @_ == 7)
        -        {
        -        my ($scope, $using, $resolvingFlags);
        -        ($self, $file, $class, $symbol, $scope, $using, $resolvingFlags) = @_;
        -
        -        $parentReference = NaturalDocs::ReferenceString->MakeFrom(::REFERENCE_CH_PARENT(), $symbol,
        -                                                                                                    NaturalDocs::Languages->LanguageOf($file)->Name(),
        -                                                                                                    $scope, $using, $resolvingFlags);
        -        }
        -    else
        -        {
        -        ($self, $file, $class, $parentReference) = @_;
        -        $symbol = (NaturalDocs::ReferenceString->InformationOf($parentReference))[1];
        -        };
        -
        -
        -    # In case it doesn't already exist.
        -    $self->AddClass($file, $class);
        -
        -    my $parent;
        -    if (exists $parentReferences{$parentReference})
        -        {
        -        $parent = $parentReferences{$parentReference};
        -        }
        -    else
        -        {
        -        NaturalDocs::SymbolTable->AddReference($parentReference, $file);
        -        my $parentTarget = NaturalDocs::SymbolTable->References($parentReference);
        -
        -        if (defined $parentTarget)
        -            {  $parent = $parentTarget->Symbol();  }
        -        else
        -            {  $parent = $symbol;  };
        -
        -        # In case it doesn't already exist.
        -        $self->AddClass(undef, $parent);
        -
        -        $parentReferences{$parentReference} = $parent;
        -        };
        -
        -
        -    # If this defined a new parent...
        -    if ($classes{$class}->AddParentReference($parentReference, $file, \%parentReferences))
        -        {
        -        $classes{$parent}->AddChild($class);
        -
        -        $self->RebuildFilesFor($class, 0, 1, 0);
        -        $self->RebuildFilesFor($parent, 0, 1, 0);
        -        };
        -
        -    $files{$file}->AddParentReference($class, $parentReference);
        -
        -    if (defined $watchedFileName)
        -        {  $watchedFile->AddParentReference($class, $parentReference);  };
        -    };
        -
        -
        -#
        -#   Function: WatchFileForChanges
        -#
        -#   Watches a file for changes, which can then be applied by <AnalyzeChanges()>.  Definitions are not deleted via a DeleteClass()
        -#   function.  Instead, a file is watched for changes, reparsed, and then a comparison is made to look for definitions that
        -#   disappeared and any other relevant changes.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> to watch.
        -#
        -sub WatchFileForChanges #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    $watchedFile = NaturalDocs::ClassHierarchy::File->New();
        -    $watchedFileName = $file;
        -    };
        -
        -
        -#
        -#   Function: AnalyzeChanges
        -#
        -#   Checks the watched file for any changes that occured since the last time is was parsed, and updates the hierarchy as
        -#   necessary.  Also sends any files that are affected to <NaturalDocs::Project->RebuildFile()>.
        -#
        -sub AnalyzeChanges
        -    {
        -    my ($self) = @_;
        -
        -    # If the file didn't have any classes before, and it still doesn't, it wont be in %files.
        -    if (exists $files{$watchedFileName})
        -        {
        -        my @originalClasses = $files{$watchedFileName}->Classes();
        -
        -        foreach my $originalClass (@originalClasses)
        -            {
        -            # If the class isn't there the second time around...
        -            if (!$watchedFile->HasClass($originalClass))
        -                {  $self->DeleteClass($watchedFileName, $originalClass);  }
        -
        -            else
        -                {
        -                my @originalParents = $files{$watchedFileName}->ParentReferencesOf($originalClass);
        -
        -                foreach my $originalParent (@originalParents)
        -                    {
        -                    # If the parent reference wasn't there the second time around...
        -                    if (!$watchedFile->HasParentReference($originalClass, $originalParent))
        -                        {  $self->DeleteParentReference($watchedFileName, $originalClass, $originalParent);  };
        -                    };
        -                };
        -            };
        -        };
        -
        -
        -    $watchedFile = undef;
        -    $watchedFileName = undef;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -
        -#
        -#   Function: ParentsOf
        -#   Returns a <SymbolString> array of the passed class' parents, or an empty array if none.  Note that not all of them may be
        -#   defined.
        -#
        -sub ParentsOf #(class)
        -    {
        -    my ($self, $class) = @_;
        -
        -    if (exists $classes{$class})
        -        {  return $classes{$class}->Parents();  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -#
        -#   Function: ChildrenOf
        -#   Returns a <SymbolString> array of the passed class' children, or an empty array if none.  Note that not all of them may be
        -#   defined.
        -#
        -sub ChildrenOf #(class)
        -    {
        -    my ($self, $class) = @_;
        -
        -    if (exists $classes{$class})
        -        {  return $classes{$class}->Children();  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: DeleteFile
        -#
        -#   Deletes a file and everything defined in it.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName>.
        -#
        -sub DeleteFile #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (!exists $files{$file})
        -        {  return;  };
        -
        -    my @classes = $files{$file}->Classes();
        -    foreach my $class (@classes)
        -        {
        -        $self->DeleteClass($file, $class);
        -        };
        -
        -    delete $files{$file};
        -    };
        -
        -#
        -#   Function: DeleteClass
        -#
        -#   Deletes a class definition from a file.  Will also delete any parent references from this class and file.  Will rebuild any file
        -#   affected unless <dontRebuildFiles> is set.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> that defines the class.
        -#       class - The class <SymbolString>.
        -#
        -sub DeleteClass #(file, class)
        -    {
        -    my ($self, $file, $class) = @_;
        -
        -    my @parents = $files{$file}->ParentReferencesOf($class);
        -    foreach my $parent (@parents)
        -        {
        -        $self->DeleteParentReference($file, $class, $parent);
        -        };
        -
        -    $files{$file}->DeleteClass($class);
        -
        -    # If we're deleting the last definition of this class.
        -    if ($classes{$class}->DeleteDefinition($file))
        -        {
        -        if (!$classes{$class}->HasChildren())
        -            {
        -            delete $classes{$class};
        -
        -            if (!$dontRebuildFiles)
        -                {  NaturalDocs::Project->RebuildFile($file);  };
        -            }
        -        else
        -            {  $self->RebuildFilesFor($class, 0, 1, 1);  };
        -
        -        };
        -    };
        -
        -
        -#
        -#   Function: DeleteParentReference
        -#
        -#   Deletes a class' parent reference and returns whether it resulted in the loss of a parent class.  Will rebuild any file affected
        -#   unless <dontRebuildFiles> is set.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> that defines the reference.
        -#       class - The class <SymbolString>.
        -#       reference - The parent <ReferenceString>.
        -#
        -#   Returns:
        -#
        -#       If the class lost a parent as a result of this, it will return its <SymbolString>.  It will return undef otherwise.
        -#
        -sub DeleteParentReference #(file, class, reference)
        -    {
        -    my ($self, $file, $class, $reference) = @_;
        -
        -    if (!exists $classes{$class})
        -        {  return;  };
        -
        -    $files{$file}->DeleteParentReference($class, $reference);
        -
        -    my $deletedParent = $classes{$class}->DeleteParentReference($reference, $file, \%parentReferences);
        -
        -    if (defined $deletedParent)
        -        {
        -        my $deletedParentObject = $classes{$deletedParent};
        -
        -        $deletedParentObject->DeleteChild($class);
        -
        -        $self->RebuildFilesFor($deletedParent, 0, 1, 0);
        -        $self->RebuildFilesFor($class, 0, 1, 0);
        -
        -        if (!$deletedParentObject->HasChildren() && !$deletedParentObject->IsDefined())
        -            {
        -            delete $classes{$deletedParent};
        -            NaturalDocs::SymbolTable->DeleteReference(
        -                $self->ClassReferenceOf($class, NaturalDocs::Languages->LanguageOf($file)->Name()) );
        -            };
        -
        -        return $deletedParent;
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: ClassReferenceOf
        -#
        -#   Returns the <REFERENCE_CH_CLASS> <ReferenceString> of the passed class <SymbolString>.
        -#
        -sub ClassReferenceOf #(class, languageName)
        -    {
        -    my ($self, $class, $languageName) = @_;
        -
        -    return NaturalDocs::ReferenceString->MakeFrom(::REFERENCE_CH_CLASS(), $class, $languageName, undef, undef,
        -                                                                            ::RESOLVE_ABSOLUTE() | ::RESOLVE_NOPLURAL());
        -    };
        -
        -
        -#
        -#   Function: RebuildFilesFor
        -#
        -#   Calls <NaturalDocs::Project->RebuildFile()> for every file defining the passed class, its parents, and/or its children.
        -#   Returns without doing anything if <dontRebuildFiles> is set.
        -#
        -#   Parameters:
        -#
        -#       class - The class <SymbolString>.
        -#       rebuildParents - Whether to rebuild the class' parents.
        -#       rebuildSelf - Whether to rebuild the class.
        -#       rebuildChildren - Whether to rebuild the class' children.
        -#
        -sub RebuildFilesFor #(class, rebuildParents, rebuildSelf, rebuildChildren)
        -    {
        -    my ($self, $class, $rebuildParents, $rebuildSelf, $rebuildChildren) = @_;
        -
        -    if ($dontRebuildFiles)
        -        {  return;  };
        -
        -    my @classesToBuild;
        -
        -    if ($rebuildParents)
        -        {  @classesToBuild = $classes{$class}->Parents();  };
        -    if ($rebuildSelf)
        -        {  push @classesToBuild, $class;  };
        -    if ($rebuildChildren)
        -        {  push @classesToBuild, $classes{$class}->Children();  };
        -
        -    foreach my $classToBuild (@classesToBuild)
        -        {
        -        my @definitions = $classes{$classToBuild}->Definitions();
        -
        -        foreach my $definition (@definitions)
        -            {  NaturalDocs::Project->RebuildFile($definition);  };
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy/Class.pm b/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy/Class.pm
        deleted file mode 100644
        index 48ed6e28e..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy/Class.pm
        +++ /dev/null
        @@ -1,413 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::ClassHierarchy::Class
        -#
        -###############################################################################
        -#
        -#   An object that stores information about a class in the hierarchy.  It does not store its <SymbolString>; it assumes that it will
        -#   be stored in a hashref where the key is the <SymbolString>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::ClassHierarchy::Class;
        -
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The keys are the constants below.
        -#
        -#   DEFINITIONS - An existence hashref of all the <FileNames> which define this class.  Undef if none.
        -#   PARENTS - An existence hashref of the <SymbolStrings> of all the parents this class has.
        -#   CHILDREN - An existence hashref of the <SymbolStrings> of all the children this class has.
        -#   PARENT_REFERENCES - A hashref of the parent <ReferenceStrings> this class has.  The keys are the <ReferenceStrings>,
        -#                                      and the values are existence hashrefs of all the <FileNames> that define them.  Undef if none.
        -#
        -use NaturalDocs::DefineMembers 'DEFINITIONS', 'PARENTS', 'CHILDREN', 'PARENT_REFERENCES';
        -# Dependency: New() depends on the order of these constants, as well as the class not being derived from any other.
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new class.
        -#
        -sub New
        -    {
        -    # Dependency: This function depends on the order of the constants, as well as the class not being derived from any other.
        -    my ($package, $definitionFile) = @_;
        -
        -    my $object = [ undef, undef, undef, undef ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: AddDefinition
        -#
        -#   Adds a rew definition of this class and returns if that was the first definition.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> the definition appears in.
        -#
        -#   Returns:
        -#
        -#       Whether this was the first definition of this class.
        -#
        -sub AddDefinition #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    my $wasFirst;
        -
        -    if (!defined $self->[DEFINITIONS])
        -        {
        -        $self->[DEFINITIONS] = { };
        -        $wasFirst = 1;
        -        };
        -
        -    $self->[DEFINITIONS]->{$file} = 1;
        -
        -    return $wasFirst;
        -    };
        -
        -
        -#
        -#   Function: DeleteDefinition
        -#
        -#   Removes the definition of this class and returns if there are no more definitions.  Note that if there are no more
        -#   definitions, you may still want to keep the object around if <HasChildren()> returns true.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> the definition appears in.
        -#
        -#   Returns:
        -#
        -#       Whether this deleted the last definition of this class.
        -#
        -sub DeleteDefinition #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (defined $self->[DEFINITIONS])
        -        {
        -        delete $self->[DEFINITIONS]->{$file};
        -
        -        if (!scalar keys %{$self->[DEFINITIONS]})
        -            {
        -            $self->[DEFINITIONS] = undef;
        -            return 1;
        -            };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: AddParentReference
        -#
        -#   Adds a parent reference to the class and return whether it resulted in a new parent class.
        -#
        -#   Parameters:
        -#
        -#       reference - The <ReferenceString> used to determine the parent.
        -#       file - The <FileName> the parent reference is in.
        -#       referenceTranslations - A hashref of what each reference currently resolves to.  The keys are the
        -#                                         <ReferenceStrings> and the values are class <SymbolStrings>.  It should include an entry for
        -#                                         the reference parameter above.
        -#
        -#   Returns:
        -#
        -#       If the reference adds a new parent, it will return that parent's <SymbolString>.  Otherwise it will return undef.
        -#
        -sub AddParentReference #(reference, file, referenceTranslations)
        -    {
        -    my ($self, $reference, $file, $referenceTranslations) = @_;
        -
        -    if (!defined $self->[PARENT_REFERENCES])
        -        {  $self->[PARENT_REFERENCES] = { };  };
        -    if (!defined $self->[PARENTS])
        -        {  $self->[PARENTS] = { };  };
        -
        -
        -    if (!exists $self->[PARENT_REFERENCES]->{$reference})
        -        {
        -        $self->[PARENT_REFERENCES]->{$reference} = { $file => 1 };
        -
        -        my $symbol = $referenceTranslations->{$reference};
        -
        -        if (!exists $self->[PARENTS]->{$symbol})
        -            {
        -            $self->[PARENTS]->{$symbol} = 1;
        -            return $symbol;
        -            }
        -        else
        -            {  return undef;  };
        -        }
        -    else
        -        {
        -        $self->[PARENT_REFERENCES]->{$reference}->{$file} = 1;
        -        return undef;
        -        };
        -    };
        -
        -#
        -#   Function: DeleteParentReference
        -#
        -#   Deletes a parent reference from the class and return whether it resulted in a loss of a parent class.
        -#
        -#   Parameters:
        -#
        -#       reference - The <ReferenceString> used to determine the parent.
        -#       file - The <FileName> the parent declaration is in.
        -#       referenceTranslations - A hashref of what each reference currently resolves to.  The keys are the
        -#                                         <ReferenceStrings> and the values are class <SymbolStrings>.  It should include an entry for
        -#                                         the reference parameter above.
        -#
        -#   Returns:
        -#
        -#       If this causes a parent class to be lost, it will return that parent's <SymbolString>.  Otherwise it will return undef.
        -#
        -sub DeleteParentReference #(reference, file, referenceTranslations)
        -    {
        -    my ($self, $reference, $file, $referenceTranslations) = @_;
        -
        -    if (defined $self->[PARENT_REFERENCES] && exists $self->[PARENT_REFERENCES]->{$reference} &&
        -        exists $self->[PARENT_REFERENCES]->{$reference}->{$file})
        -        {
        -        delete $self->[PARENT_REFERENCES]->{$reference}->{$file};
        -
        -        # Quit if there are other definitions of this reference.
        -        if (scalar keys %{$self->[PARENT_REFERENCES]->{$reference}})
        -            {  return undef;  };
        -
        -        delete $self->[PARENT_REFERENCES]->{$reference};
        -
        -        if (!scalar keys %{$self->[PARENT_REFERENCES]})
        -            {  $self->[PARENT_REFERENCES] = undef;  };
        -
        -        my $parent = $referenceTranslations->{$reference};
        -
        -        # Check if any other references resolve to the same parent.
        -        if (defined $self->[PARENT_REFERENCES])
        -            {
        -            foreach my $parentReference (keys %{$self->[PARENT_REFERENCES]})
        -                {
        -                if ($referenceTranslations->{$parentReference} eq $parent)
        -                    {  return undef;  };
        -                };
        -            };
        -
        -        # If we got this far, no other parent references resolve to this symbol.
        -
        -        delete $self->[PARENTS]->{$parent};
        -
        -        if (!scalar keys %{$self->[PARENTS]})
        -            {  $self->[PARENTS] = undef;  };
        -
        -        return $parent;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: AddChild
        -#   Adds a child <SymbolString> to the class.  Unlike <AddParentReference()>, this does not keep track of anything other than
        -#   whether it has it or not.
        -#
        -#   Parameters:
        -#
        -#       child - The <SymbolString> to add.
        -#
        -sub AddChild #(child)
        -    {
        -    my ($self, $child) = @_;
        -
        -    if (!defined $self->[CHILDREN])
        -        {  $self->[CHILDREN] = { };  };
        -
        -    $self->[CHILDREN]->{$child} = 1;
        -    };
        -
        -#
        -#   Function: DeleteChild
        -#   Deletes a child <SymbolString> from the class.  Unlike <DeleteParentReference()>, this does not keep track of anything other
        -#   than whether it has it or not.
        -#
        -#   Parameters:
        -#
        -#       child - The <SymbolString> to delete.
        -#
        -sub DeleteChild #(child)
        -    {
        -    my ($self, $child) = @_;
        -
        -    if (defined $self->[CHILDREN])
        -        {
        -        delete $self->[CHILDREN]->{$child};
        -
        -        if (!scalar keys %{$self->[CHILDREN]})
        -            {  $self->[CHILDREN] = undef;  };
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -#
        -#   Function: Definitions
        -#   Returns an array of the <FileNames> that define this class, or an empty array if none.
        -#
        -sub Definitions
        -    {
        -    my ($self) = @_;
        -
        -    if (defined $self->[DEFINITIONS])
        -        {  return keys %{$self->[DEFINITIONS]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -#
        -#   Function: IsDefinedIn
        -#   Returns whether the class is defined in the passed <FileName>.
        -#
        -sub IsDefinedIn #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (defined $self->[DEFINITIONS])
        -        {  return exists $self->[DEFINITIONS]->{$file};  }
        -    else
        -        {  return 0;  };
        -    };
        -
        -#
        -#   Function: IsDefined
        -#   Returns whether the class is defined in any files.
        -#
        -sub IsDefined
        -    {
        -    my ($self) = @_;
        -    return defined $self->[DEFINITIONS];
        -    };
        -
        -#
        -#   Function: ParentReferences
        -#   Returns an array of the parent <ReferenceStrings>, or an empty array if none.
        -#
        -sub ParentReferences
        -    {
        -    my ($self) = @_;
        -
        -    if (defined $self->[PARENT_REFERENCES])
        -        {  return keys %{$self->[PARENT_REFERENCES]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -#
        -#   Function: HasParentReference
        -#   Returns whether the class has the passed parent <ReferenceString>.
        -#
        -sub HasParentReference #(reference)
        -    {
        -    my ($self, $reference) = @_;
        -    return (defined $self->[PARENT_REFERENCES] && exists $self->[PARENT_REFERENCES]->{$reference});
        -    };
        -
        -#
        -#   Function: HasParentReferences
        -#   Returns whether the class has any parent <ReferenceStrings>.
        -#
        -sub HasParentReferences
        -    {
        -    my ($self) = @_;
        -    return defined $self->[PARENT_REFERENCES];
        -    };
        -
        -#
        -#   Function: Parents
        -#   Returns an array of the parent <SymbolStrings>, or an empty array if none.
        -#
        -sub Parents
        -    {
        -    my ($self) = @_;
        -
        -    if (defined $self->[PARENTS])
        -        {  return keys %{$self->[PARENTS]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -#
        -#   Function: HasParents
        -#   Returns whether the class has any parent <SymbolStrings> defined.
        -#
        -sub HasParents
        -    {
        -    my ($self) = @_;
        -    return defined $self->[PARENTS];
        -    };
        -
        -#
        -#   Function: Children
        -#   Returns an array of the child <SymbolStrings>, or an empty array if none.
        -#
        -sub Children
        -    {
        -    my ($self) = @_;
        -
        -    if (defined $self->[CHILDREN])
        -        {  return keys %{$self->[CHILDREN]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -#
        -#   Function: HasChildren
        -#   Returns whether any child <SymbolStrings> are defined.
        -#
        -sub HasChildren
        -    {
        -    my ($self) = @_;
        -    return defined $self->[CHILDREN];
        -    };
        -
        -
        -#
        -#   Function: ParentReferenceDefinitions
        -#   Returns an array of the <FileNames> which define the passed parent <ReferenceString>, or an empty array if none.
        -#
        -sub ParentReferenceDefinitions #(reference)
        -    {
        -    my ($self, $reference) = @_;
        -
        -    if (defined $self->[PARENT_REFERENCES] && exists $self->[PARENT_REFERENCES]->{$reference})
        -        {  return keys %{$self->[PARENT_REFERENCES]->{$reference}};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy/File.pm b/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy/File.pm
        deleted file mode 100644
        index 0f7b3226a..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ClassHierarchy/File.pm
        +++ /dev/null
        @@ -1,158 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::ClassHierarchy::File
        -#
        -###############################################################################
        -#
        -#   An object that stores information about what hierarchy information is present in a file.  It does not store its <FileName>; it
        -#   assumes that it will be stored in a hashref where the key is the <FileName>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::ClassHierarchy::File;
        -
        -
        -#
        -#   Topic: Implementation
        -#
        -#   Since there's only one member in the class, and it's a hashref, the class is simply the hashref itself blessed as a class.
        -#   The keys are the class <SymbolStrings> that are defined in the file, and the values are existence hashrefs of each class'
        -#   parent <ReferenceStrings>, or undef if none.
        -#
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new class.
        -#
        -sub New
        -    {
        -    my ($package) = @_;
        -
        -    my $object = { };
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -#
        -#   Function: AddClass
        -#   Adds a rew class <SymbolString> to the file.
        -#
        -sub AddClass #(class)
        -    {
        -    my ($self, $class) = @_;
        -
        -    if (!exists $self->{$class})
        -        {  $self->{$class} = undef;  };
        -    };
        -
        -#
        -#   Function: DeleteClass
        -#   Deletes a class <SymbolString> from the file.
        -#
        -sub DeleteClass #(class)
        -    {
        -    my ($self, $class) = @_;
        -    delete $self->{$class};
        -    };
        -
        -#
        -#   Function: AddParentReference
        -#   Adds a parent <ReferenceString> to a class <SymbolString>.
        -#
        -sub AddParentReference #(class, parentReference)
        -    {
        -    my ($self, $class, $parent) = @_;
        -
        -    if (!exists $self->{$class} || !defined $self->{$class})
        -        {  $self->{$class} = { };  };
        -
        -    $self->{$class}->{$parent} = 1;
        -    };
        -
        -#
        -#   Function: DeleteParentReference
        -#   Deletes a parent <ReferenceString> from a class <SymbolString>.
        -#
        -sub DeleteParentReference #(class, parent)
        -    {
        -    my ($self, $class, $parent) = @_;
        -
        -    if (exists $self->{$class})
        -        {
        -        delete $self->{$class}->{$parent};
        -
        -        if (!scalar keys %{$self->{$class}})
        -            {  $self->{$class} = undef;  };
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -
        -#
        -#   Function: Classes
        -#   Returns an array of the class <SymbolStrings> that are defined by this file, or an empty array if none.
        -#
        -sub Classes
        -    {
        -    my ($self) = @_;
        -    return keys %{$self};
        -    };
        -
        -#
        -#   Function: HasClass
        -#   Returns whether the file defines the passed class <SymbolString>.
        -#
        -sub HasClass #(class)
        -    {
        -    my ($self, $class) = @_;
        -    return exists $self->{$class};
        -    };
        -
        -#
        -#   Function: ParentReferencesOf
        -#   Returns an array of the parent <ReferenceStrings> that are defined by the class, or an empty array if none.
        -#
        -sub ParentReferencesOf #(class)
        -    {
        -    my ($self, $class) = @_;
        -
        -    if (!exists $self->{$class} || !defined $self->{$class})
        -        {  return ( );  }
        -    else
        -        {  return keys %{$self->{$class}};  };
        -    };
        -
        -#
        -#   Function: HasParentReference
        -#   Returns whether the file defines the passed class <SymbolString> and parent <ReferenceString>.
        -#
        -sub HasParentReference #(class, parent)
        -    {
        -    my ($self, $class, $parent) = @_;
        -
        -    if (!$self->HasClass($class))
        -        {  return undef;  };
        -
        -    return exists $self->{$class}->{$parent};
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ConfigFile.pm b/vendor/naturaldocs/Modules/NaturalDocs/ConfigFile.pm
        deleted file mode 100644
        index e9fd7cc46..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ConfigFile.pm
        +++ /dev/null
        @@ -1,508 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::ConfigFile
        -#
        -###############################################################################
        -#
        -#   A package to manage Natural Docs' configuration files.
        -#
        -#   Usage:
        -#
        -#       - Only one configuration file can be managed with this package at a time.  You must close the file before opening another
        -#         one.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::ConfigFile;
        -
        -
        -
        -#
        -#   Topic: Format
        -#
        -#   All configuration files are text files.
        -#
        -#   > # [comment]
        -#
        -#   Comments start with the # character.
        -#
        -#   > Format: [version]
        -#
        -#   All configuration files *must* have a format line as its first line containing content.  Whitespace and comments are permitted
        -#   ahead of it.
        -#
        -#   > [keyword]: [value]
        -#
        -#   Keywords can only contain <CFChars>.  Keywords are not case sensitive.  Values can be anything and run until the end of
        -#   the line or a comment.
        -#
        -#   > [value]
        -#
        -#   Lines that don't start with a valid keyword format are considered to be all value.
        -#
        -#   > [line] { [line] } [line]
        -#
        -#   Files supporting brace groups (specified in <Open()>) may also have braces that can appear anywhere.  It allows more than
        -#   one thing to appear per line, which isn't supported otherwise.  Consequently, values may not have braces.
        -#
        -
        -
        -#
        -#   Type: CFChars
        -#
        -#   The characters that can appear in configuration file keywords and user-defined element names: letters, numbers, spaces,
        -#   dashes, slashes, apostrophes, and periods.
        -#
        -#   Although the list above is exhaustive, it should be noted that you especially can *not* use colons (messes up keyword: value
        -#   sequences) commas (messes up item, item, item list sequences) and hashes (messes up comment detection.)
        -#
        -#   You can search the source code for [CFChars] to find all the instances where this definition is used.
        -#
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -#
        -#   handle: CONFIG_FILEHANDLE
        -#
        -#   The file handle used for the configuration file.
        -#
        -
        -
        -#
        -#   string: file
        -#
        -#   The <FileName> for the current configuration file being parsed.
        -#
        -my $file;
        -
        -
        -#
        -#	var: lineReader
        -#
        -#	The <LineReader> used to read the configuration file.
        -#
        -my $lineReader;
        -
        -
        -#
        -#   array: errors
        -#
        -#   An array of errors added by <AddError()>.  Every odd entry is the line number, and every even entry following is the
        -#   error message.
        -#
        -my @errors;
        -
        -
        -#
        -#   var: lineNumber
        -#
        -#   The current line number for the configuration file.
        -#
        -my $lineNumber;
        -
        -
        -#
        -#   bool: hasBraceGroups
        -#
        -#   Whether the file has brace groups or not.
        -#
        -my $hasBraceGroups;
        -
        -
        -#
        -#   array: virtualLines
        -#
        -#   An array of virtual lines if a line from the file contained more than one.
        -#
        -#   Files with brace groups may have more than one virtual line per actual file line, such as "Group: A { Group: B".  When that
        -#   happens, any extra virtual lines are put into here so they can be returned on the next call.
        -#
        -my @virtualLines;
        -
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: Open
        -#
        -#   Opens a configuration file for parsing and returns the format <VersionInt>.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> to parse.
        -#       hasBraceGroups - Whether the file supports brace groups or not.  If so, lines with braces will be split apart behind the
        -#                                  scenes.
        -#
        -#   Returns:
        -#
        -#       The <VersionInt> of the file, or undef if the file doesn't exist.
        -#
        -sub Open #(file, hasBraceGroups)
        -    {
        -    my $self;
        -    ($self, $file, $hasBraceGroups) = @_;
        -
        -    @errors = ( );
        -
        -    # It will be incremented to one when the first line is read from the file.
        -    $lineNumber = 0;
        -
        -    open(CONFIG_FILEHANDLE, '<' . $file) or return undef;
        -    $lineReader = NaturalDocs::LineReader->New(\*CONFIG_FILEHANDLE);
        -
        -
        -    # Get the format line.
        -
        -    my ($keyword, $value, $comment) = $self->GetLine();
        -
        -    if ($keyword eq 'format')
        -        {  return NaturalDocs::Version->FromString($value);  }
        -    else
        -        {  die "The first content line in " . $file . " must be the Format: line.\n";  };
        -    };
        -
        -
        -#
        -#   Function: Close
        -#
        -#   Closes the current configuration file.
        -#
        -sub Close
        -    {
        -    my $self = shift;
        -    close(CONFIG_FILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: GetLine
        -#
        -#   Returns the next line containing content, or an empty array if none.
        -#
        -#   Returns:
        -#
        -#       Returns the array ( keyword, value, comment ), or an empty array if none.  All tabs will be converted to spaces, and all
        -#       whitespace will be condensed into a single space.
        -#
        -#       keyword - The keyword part of the line, if any.  Is converted to lowercase and doesn't include the colon.  If the file supports
        -#                       brace groups, opening and closing braces will be returned as keywords.
        -#       value - The value part of the line, minus any whitespace.  Keeps its original case.
        -#       comment - The comment following the line, if any.  This includes the # symbol and a leading space if there was
        -#                       any whitespace, since it may be significant.  Otherwise undef.  Used for lines where the # character needs to be
        -#                       accepted as part of the value.
        -#
        -sub GetLine
        -    {
        -    my $self = shift;
        -
        -    my ($line, $comment);
        -
        -
        -    # Get the next line with content.
        -
        -    do
        -        {
        -        # Get the next line.
        -
        -        my $isFileLine;
        -
        -        if (scalar @virtualLines)
        -            {
        -            $line = shift @virtualLines;
        -            $isFileLine = 0;
        -            }
        -        else
        -            {
        -            $line = $lineReader->Get();
        -            $lineNumber++;
        -
        -            if (!defined $line)
        -                {  return ( );  };
        -
        -            # Condense spaces and tabs into a single space.
        -            $line =~ tr/\t /  /s;
        -            $isFileLine = 1;
        -            };
        -
        -
        -        # Split off the comment.
        -
        -        if ($line =~ /^(.*?)( ?#.*)$/)
        -            {  ($line, $comment) = ($1, $2);  }
        -        else
        -            {  $comment = undef;  };
        -
        -
        -        # Split any brace groups.
        -
        -        if ($isFileLine && $hasBraceGroups && $line =~ /[\{\}]/)
        -            {
        -            ($line, @virtualLines) = split(/([\{\}])/, $line);
        -
        -            $virtualLines[-1] .= $comment;
        -            $comment = undef;
        -            };
        -
        -
        -        # Remove whitespace.
        -
        -        $line =~ s/^ //;
        -        $line =~ s/ $//;
        -        $comment =~ s/ $//;
        -        # We want to keep the leading space on a comment.
        -        }
        -    while (!$line);
        -
        -
        -    # Process the line.
        -
        -    if ($hasBraceGroups && ($line eq '{' || $line eq '}'))
        -        {
        -        return ($line, undef, undef);
        -        };
        -
        -
        -    if ($line =~ /^([a-z0-9\ \'\/\.\-]+?) ?: ?(.*)$/i) # [CFChars]
        -        {
        -        my ($keyword, $value) = ($1, $2);
        -        return (lc($keyword), $value, $comment);
        -        }
        -
        -    else
        -        {
        -        return (undef, $line, $comment);
        -        };
        -    };
        -
        -
        -#
        -#   Function: LineNumber
        -#
        -#   Returns the line number for the line last returned by <GetLine()>.
        -#
        -sub LineNumber
        -    {  return $lineNumber;  };
        -
        -
        -
        -###############################################################################
        -# Group: Error Functions
        -
        -
        -#
        -#   Function: AddError
        -#
        -#   Stores an error for the current configuration file.  Will be attached to the last line read by <GetLine()>.
        -#
        -#   Parameters:
        -#
        -#       message - The error message.
        -#       lineNumber - The line number to use.  If not specified, it will use the line number from the last call to <GetLine()>.
        -#
        -sub AddError #(message, lineNumber)
        -    {
        -    my ($self, $message, $messageLineNumber) = @_;
        -
        -    if (!defined $messageLineNumber)
        -        {  $messageLineNumber = $lineNumber;  };
        -
        -    push @errors, $messageLineNumber, $message;
        -    };
        -
        -
        -#
        -#   Function: ErrorCount
        -#
        -#   Returns how many errors the configuration file has.
        -#
        -sub ErrorCount
        -    {
        -    return (scalar @errors) / 2;
        -    };
        -
        -
        -#
        -#   Function: PrintErrorsAndAnnotateFile
        -#
        -#   Prints the errors to STDERR in the standard GNU format and annotates the configuration file with them.  It does *not* end
        -#   execution.  <Close()> *must* be called before this function.
        -#
        -sub PrintErrorsAndAnnotateFile
        -    {
        -    my ($self) = @_;
        -
        -    if (scalar @errors)
        -        {
        -        open(CONFIG_FILEHANDLE, '<' . $file);
        -
        -        my $lineReader = NaturalDocs::LineReader->New(\*CONFIG_FILEHANDLE);
        -        my @lines = $lineReader->GetAll();
        -
        -        close(CONFIG_FILEHANDLE);
        -
        -        # We need to keep track of both the real and the original line numbers.  The original line numbers are for matching errors in
        -        # the errors array, and don't include any comment lines added or deleted.  Line number is the current line number including
        -        # those comment lines for sending to the display.
        -        my $lineNumber = 1;
        -        my $originalLineNumber = 1;
        -
        -        open(CONFIG_FILEHANDLE, '>' . $file);
        -
        -        # We don't want to keep the old error header, if present.
        -        if ($lines[0] =~ /^\# There (?:is an error|are \d+ errors) in this file\./)
        -            {
        -            shift @lines;
        -            $originalLineNumber++;
        -
        -            # We want to drop the blank line after it as well.
        -            if ($lines[0] eq "\n")
        -                {
        -                shift @lines;
        -                $originalLineNumber++;
        -                };
        -            };
        -
        -        if ($self->ErrorCount() == 1)
        -            {
        -            print CONFIG_FILEHANDLE
        -            "# There is an error in this file.  Search for ERROR to find it.\n\n";
        -            }
        -        else
        -            {
        -            print CONFIG_FILEHANDLE
        -            "# There are " . $self->ErrorCount() . " errors in this file.  Search for ERROR to find them.\n\n";
        -            };
        -
        -        $lineNumber += 2;
        -
        -
        -        foreach my $line (@lines)
        -            {
        -            while (scalar @errors && $originalLineNumber == $errors[0])
        -                {
        -                my $errorLine = shift @errors;
        -                my $errorMessage = shift @errors;
        -
        -                print CONFIG_FILEHANDLE "# ERROR: " . $errorMessage . "\n";
        -
        -                # Use the GNU error format, which should make it easier to handle errors when Natural Docs is part of a build process.
        -                # See http://www.gnu.org/prep/standards_15.html
        -
        -                $errorMessage = lcfirst($errorMessage);
        -                $errorMessage =~ s/\.$//;
        -
        -                print STDERR 'NaturalDocs:' . $file . ':' . $lineNumber . ': ' . $errorMessage . "\n";
        -
        -                $lineNumber++;
        -                };
        -
        -            # We want to remove error lines from previous runs.
        -            if (substr($line, 0, 9) ne '# ERROR: ')
        -                {
        -                print CONFIG_FILEHANDLE $line;
        -                $lineNumber++;
        -                };
        -
        -            $originalLineNumber++;
        -            };
        -
        -        # Clean up any remaining errors.
        -        while (scalar @errors)
        -            {
        -            my $errorLine = shift @errors;
        -            my $errorMessage = shift @errors;
        -
        -            print CONFIG_FILEHANDLE "# ERROR: " . $errorMessage . "\n";
        -
        -            # Use the GNU error format, which should make it easier to handle errors when Natural Docs is part of a build process.
        -            # See http://www.gnu.org/prep/standards_15.html
        -
        -            $errorMessage = lcfirst($errorMessage);
        -            $errorMessage =~ s/\.$//;
        -
        -            print STDERR 'NaturalDocs:' . $file . ':' . $lineNumber . ': ' . $errorMessage . "\n";
        -            };
        -
        -        close(CONFIG_FILEHANDLE);
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Misc Functions
        -
        -
        -#
        -#   Function: HasOnlyCFChars
        -#
        -#   Returns whether the passed string contains only <CFChars>.
        -#
        -sub HasOnlyCFChars #(string)
        -    {
        -    my ($self, $string) = @_;
        -    return ($string =~ /^[a-z0-9\ \.\-\/\']*$/i);  # [CFChars]
        -    };
        -
        -
        -#
        -#   Function: CFCharNames
        -#
        -#   Returns a plain-english list of <CFChars> which can be embedded in a sentence.  For example, "You can only use
        -#   [CFCharsList()] in the name.
        -#
        -sub CFCharNames
        -    {
        -    # [CFChars]
        -    return 'letters, numbers, spaces, periods, dashes, slashes, and apostrophes';
        -    };
        -
        -
        -#
        -#   Function: Obscure
        -#
        -#   Obscures the passed text so that it is not user editable and returns it.  The encoding method is not secure; it is just designed
        -#   to be fast and to discourage user editing.
        -#
        -sub Obscure #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    # ` is specifically chosen to encode to space because of its rarity.  We don't want a trailing one to get cut off before decoding.
        -    $text =~ tr{a-zA-Z0-9\ \\\/\.\:\_\-\`}
        -                    {pY9fGc\`R8lAoE\\uIdH6tN\/7sQjKx0B5mW\.vZ41PyFg\:CrLaO\_eUi2DhT\-nSqJkXb3MwVz\ };
        -
        -    return $text;
        -    };
        -
        -
        -#
        -#   Function: Unobscure
        -#
        -#   Restores text encoded with <Obscure()> and returns it.
        -#
        -sub Unobscure #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ tr{pY9fGc\`R8lAoE\\uIdH6tN\/7sQjKx0B5mW\.vZ41PyFg\:CrLaO\_eUi2DhT\-nSqJkXb3MwVz\ }
        -                    {a-zA-Z0-9\ \\\/\.\:\_\-\`};
        -
        -    return $text;
        -    };
        -
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Constants.pm b/vendor/naturaldocs/Modules/NaturalDocs/Constants.pm
        deleted file mode 100644
        index 66d934c29..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Constants.pm
        +++ /dev/null
        @@ -1,166 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Constants
        -#
        -###############################################################################
        -#
        -#   Constants that are used throughout the script.  All are exported by default.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Constants;
        -
        -use vars qw(@EXPORT @ISA);
        -require Exporter;
        -@ISA = qw(Exporter);
        -
        -@EXPORT = ('MENU_TITLE', 'MENU_SUBTITLE', 'MENU_FILE', 'MENU_GROUP', 'MENU_TEXT', 'MENU_LINK', 'MENU_FOOTER',
        -                   'MENU_INDEX', 'MENU_FORMAT', 'MENU_ENDOFORIGINAL', 'MENU_DATA',
        -
        -                   'MENU_FILE_NOAUTOTITLE', 'MENU_GROUP_UPDATETITLES', 'MENU_GROUP_UPDATESTRUCTURE',
        -                   'MENU_GROUP_UPDATEORDER', 'MENU_GROUP_HASENDOFORIGINAL',
        -                   'MENU_GROUP_UNSORTED', 'MENU_GROUP_FILESSORTED',
        -                   'MENU_GROUP_FILESANDGROUPSSORTED', 'MENU_GROUP_EVERYTHINGSORTED',
        -                   'MENU_GROUP_ISINDEXGROUP',
        -
        -                   'FILE_NEW', 'FILE_CHANGED', 'FILE_SAME', 'FILE_DOESNTEXIST');
        -
        -#
        -#   Topic: Assumptions
        -#
        -#   - No constant here will ever be zero.
        -#   - All constants are exported by default.
        -#
        -
        -
        -###############################################################################
        -# Group: Virtual Types
        -# These are only groups of constants, but should be treated like typedefs or enums.  Each one represents a distinct type and
        -# their values should only be one of their constants or undef.
        -
        -
        -#
        -#   Constants: MenuEntryType
        -#
        -#   The types of entries that can appear in the menu.
        -#
        -#       MENU_TITLE         - The title of the menu.
        -#       MENU_SUBTITLE   - The sub-title of the menu.
        -#       MENU_FILE           - A source file, relative to the source directory.
        -#       MENU_GROUP       - A group.
        -#       MENU_TEXT          - Arbitrary text.
        -#       MENU_LINK           - A web link.
        -#       MENU_FOOTER      - Footer text.
        -#       MENU_INDEX        - An index.
        -#       MENU_FORMAT     - The version of Natural Docs the menu file was generated with.
        -#       MENU_ENDOFORIGINAL - A dummy entry that marks where the original group content ends.  This is used when automatically
        -#                                           changing the groups so that the alphabetization or lack thereof can be detected without being
        -#                                           affected by new entries tacked on to the end.
        -#       MENU_DATA - Data not meant for user editing.
        -#
        -#   Dependency:
        -#
        -#       <PreviousMenuState.nd> depends on these values all being able to fit into a UInt8, i.e. <= 255.
        -#
        -use constant MENU_TITLE => 1;
        -use constant MENU_SUBTITLE => 2;
        -use constant MENU_FILE => 3;
        -use constant MENU_GROUP => 4;
        -use constant MENU_TEXT => 5;
        -use constant MENU_LINK => 6;
        -use constant MENU_FOOTER => 7;
        -use constant MENU_INDEX => 8;
        -use constant MENU_FORMAT => 9;
        -use constant MENU_ENDOFORIGINAL => 10;
        -use constant MENU_DATA => 11;
        -
        -
        -#
        -#   Constants: FileStatus
        -#
        -#   What happened to a file since Natural Docs' last execution.
        -#
        -#       FILE_NEW                - The file has been added since the last run.
        -#       FILE_CHANGED        - The file has been modified since the last run.
        -#       FILE_SAME               - The file hasn't been modified since the last run.
        -#       FILE_DOESNTEXIST  - The file doesn't exist, or was deleted.
        -#
        -use constant FILE_NEW => 1;
        -use constant FILE_CHANGED => 2;
        -use constant FILE_SAME => 3;
        -use constant FILE_DOESNTEXIST => 4;
        -
        -
        -
        -###############################################################################
        -# Group: Flags
        -# These constants can be combined with each other.
        -
        -
        -#
        -#   Constants: Menu Entry Flags
        -#
        -#   The various flags that can apply to a menu entry.  You cannot mix flags of different types, since they may overlap.
        -#
        -#   File Flags:
        -#
        -#       MENU_FILE_NOAUTOTITLE - Whether the file is auto-titled or not.
        -#
        -#   Group Flags:
        -#
        -#       MENU_GROUP_UPDATETITLES - The group should have its auto-titles regenerated.
        -#       MENU_GROUP_UPDATESTRUCTURE - The group should be checked for structural changes, such as being removed or being
        -#                                                             split into subgroups.
        -#       MENU_GROUP_UPDATEORDER - The group should be resorted.
        -#
        -#       MENU_GROUP_HASENDOFORIGINAL - Whether the group contains a dummy <MENU_ENDOFORIGINAL> entry.
        -#       MENU_GROUP_ISINDEXGROUP - Whether the group is used primarily for <MENU_INDEX> entries.  <MENU_TEXT> entries
        -#                                                       are tolerated.
        -#
        -#       MENU_GROUP_UNSORTED - The group's contents are not sorted.
        -#       MENU_GROUP_FILESSORTED - The group's files are sorted alphabetically.
        -#       MENU_GROUP_FILESANDGROUPSSORTED - The group's files and sub-groups are sorted alphabetically.
        -#       MENU_GROUP_EVERYTHINGSORTED - All entries in the group are sorted alphabetically.
        -#
        -use constant MENU_FILE_NOAUTOTITLE => 0x0001;
        -
        -use constant MENU_GROUP_UPDATETITLES => 0x0001;
        -use constant MENU_GROUP_UPDATESTRUCTURE => 0x0002;
        -use constant MENU_GROUP_UPDATEORDER => 0x0004;
        -use constant MENU_GROUP_HASENDOFORIGINAL => 0x0008;
        -
        -# This could really be a two-bit field instead of four flags, but it's not worth the effort since it's only used internally.
        -use constant MENU_GROUP_UNSORTED => 0x0010;
        -use constant MENU_GROUP_FILESSORTED => 0x0020;
        -use constant MENU_GROUP_FILESANDGROUPSSORTED => 0x0040;
        -use constant MENU_GROUP_EVERYTHINGSORTED => 0x0080;
        -
        -use constant MENU_GROUP_ISINDEXGROUP => 0x0100;
        -
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: IsClassHierarchyReference
        -#   Returns whether the passed <ReferenceType> belongs to <NaturalDocs::ClassHierarchy>.
        -#
        -sub IsClassHierarchyReference #(reference)
        -    {
        -    my ($self, $reference) = @_;
        -    return ($reference == ::REFERENCE_CH_CLASS() || $reference == ::REFERENCE_CH_PARENT());
        -    };
        -
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/DefineMembers.pm b/vendor/naturaldocs/Modules/NaturalDocs/DefineMembers.pm
        deleted file mode 100644
        index 8e04d3ddd..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/DefineMembers.pm
        +++ /dev/null
        @@ -1,101 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::DefineMembers
        -#
        -###############################################################################
        -#
        -#   A custom Perl pragma to define member constants and accessors for use in Natural Docs objects while supporting inheritance.
        -#
        -#   Each member will be defined as a numeric constant which should be used as that variable's index into the object arrayref.
        -#   They will be assigned sequentially from zero, and take into account any members defined this way in parent classes.  Note
        -#   that you can *not* use multiple inheritance with this method.
        -#
        -#   If a parameter ends in parenthesis, it will be generated as an accessor for the previous member.  If it also starts with "Set",
        -#   the accessor will accept a single parameter to replace the value with.  If it's followed with "duparrayref", it will assume the
        -#   parameter is either an arrayref or undef, and if the former, will duplicate it to set the value.
        -#
        -#   Example:
        -#
        -#   > package MyPackage;
        -#   >
        -#   > use NaturalDocs::DefineMembers 'VAR_A', 'VarA()', 'SetVarA()',
        -#   >                                'VAR_B', 'VarB()',
        -#   >                                'VAR_C',
        -#   >                                'VAR_D', 'VarD()', 'SetVarD() duparrayref';
        -#   >
        -#   > sub SetC #(C)
        -#   >    {
        -#   >    my ($self, $c) = @_;
        -#   >    $self->[VAR_C] = $c;
        -#   >    };
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -package NaturalDocs::DefineMembers;
        -
        -sub import #(member, member, ...)
        -    {
        -    my ($self, @parameters) = @_;
        -    my $package = caller();
        -
        -    no strict 'refs';
        -    my $parent = ${$package . '::ISA'}[0];
        -    use strict 'refs';
        -
        -    my $memberConstant = 0;
        -    my $lastMemberName;
        -
        -    if (defined $parent && $parent->can('END_OF_MEMBERS'))
        -        {  $memberConstant = $parent->END_OF_MEMBERS();  };
        -
        -    my $code = '{ package ' . $package . ";\n";
        -
        -    foreach my $parameter (@parameters)
        -        {
        -        if ($parameter =~ /^(.+)\(\) *(duparrayref)?$/i)
        -            {
        -            my ($functionName, $pragma) = ($1, lc($2));
        -
        -            if ($functionName =~ /^Set/)
        -                {
        -                if ($pragma eq 'duparrayref')
        -                    {
        -                    $code .=
        -                    'sub ' . $functionName . '
        -                        {
        -                        if (defined $_[1])
        -                            {  $_[0]->[' . $lastMemberName . '] = [ @{$_[1]} ];  }
        -                        else
        -                            {  $_[0]->[' . $lastMemberName . '] = undef;  };
        -                        };' . "\n";
        -                    }
        -                else
        -                    {
        -                    $code .= 'sub ' . $functionName . ' { $_[0]->[' . $lastMemberName . '] = $_[1];  };' . "\n";
        -                    };
        -                }
        -            else
        -                {
        -                $code .= 'sub ' . $functionName . ' { return $_[0]->[' . $lastMemberName . '];  };' . "\n";
        -                };
        -            }
        -        else
        -            {
        -            $code .= 'use constant ' . $parameter . ' => ' . $memberConstant . ";\n";
        -            $memberConstant++;
        -            $lastMemberName = $parameter;
        -            };
        -        };
        -
        -    $code .= 'use constant END_OF_MEMBERS => ' . $memberConstant . ";\n";
        -    $code .= '};';
        -
        -    eval $code;
        -    };
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Error.pm b/vendor/naturaldocs/Modules/NaturalDocs/Error.pm
        deleted file mode 100644
        index 5b300607b..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Error.pm
        +++ /dev/null
        @@ -1,306 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Error
        -#
        -###############################################################################
        -#
        -#   Manages all aspects of error handling in Natural Docs.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -$SIG{'__DIE__'} = \&NaturalDocs::Error::CatchDeath;
        -
        -
        -package NaturalDocs::Error;
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   handle: FH_CRASHREPORT
        -#   The filehandle used for generating crash reports.
        -#
        -
        -
        -#
        -#   var: stackTrace
        -#   The stack trace generated by <CatchDeath()>.
        -#
        -my $stackTrace;
        -
        -
        -#
        -#   var: softDeath
        -#   Whether the program exited using <SoftDeath()>.
        -#
        -my $softDeath;
        -
        -
        -#
        -#   var: currentAction
        -#   What Natural Docs was doing when it crashed.  This stores strings generated by functions like <OnStartParsing()>.
        -#
        -my $currentAction;
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: SoftDeath
        -#
        -#   Generates a "soft" death, which means the program exits like with Perl's die(), but no crash report will be generated.
        -#
        -#   Parameter:
        -#
        -#       message - The error message to die with.
        -#
        -sub SoftDeath #(message)
        -    {
        -    my ($self, $message) = @_;
        -
        -    $softDeath = 1;
        -    if ($message !~ /\n$/)
        -        {  $message .= "\n";  };
        -
        -    die $message;
        -    };
        -
        -
        -#
        -#   Function: OnStartParsing
        -#
        -#   Called whenever <NaturalDocs::Parser> starts parsing a source file.
        -#
        -sub OnStartParsing #(FileName file)
        -    {
        -    my ($self, $file) = @_;
        -    $currentAction = 'Parsing ' . $file;
        -    };
        -
        -
        -#
        -#   Function: OnEndParsing
        -#
        -#   Called whenever <NaturalDocs::Parser> is done parsing a source file.
        -#
        -sub OnEndParsing #(FileName file)
        -    {
        -    my ($self, $file) = @_;
        -    $currentAction = undef;
        -    };
        -
        -
        -#
        -#   Function: OnStartBuilding
        -#
        -#   Called whenever <NaturalDocs::Builder> starts building a source file.
        -#
        -sub OnStartBuilding #(FileName file)
        -    {
        -    my ($self, $file) = @_;
        -    $currentAction = 'Building ' . $file;
        -    };
        -
        -
        -#
        -#   Function: OnEndBuilding
        -#
        -#   Called whenever <NaturalDocs::Builder> is done building a source file.
        -#
        -sub OnEndBuilding #(FileName file)
        -    {
        -    my ($self, $file) = @_;
        -    $currentAction = undef;
        -    };
        -
        -
        -#
        -#   Function: HandleDeath
        -#
        -#   Should be called whenever Natural Docs dies out of execution.
        -#
        -sub HandleDeath
        -    {
        -    my $self = shift;
        -
        -    my $reason = $::EVAL_ERROR;
        -    $reason =~ s/[\n\r]+$//;
        -
        -    my $errorMessage =
        -         "\n"
        -         . "Natural Docs encountered the following error and was stopped:\n"
        -         . "\n"
        -         . "   " . $reason . "\n"
        -         . "\n"
        -
        -         . "You can get help at the following web site:\n"
        -         . "\n"
        -         . "   " . NaturalDocs::Settings->AppURL() . "\n"
        -         . "\n";
        -
        -    if (!$softDeath)
        -        {
        -        my $crashReport = $self->GenerateCrashReport();
        -
        -        if ($crashReport)
        -            {
        -            $errorMessage .=
        -             "If sending an error report, please include the information found in the\n"
        -             . "following file:\n"
        -             . "\n"
        -             . "   " . $crashReport . "\n"
        -             . "\n";
        -            }
        -        else
        -            {
        -            $errorMessage .=
        -             "If sending an error report, please include the following information:\n"
        -             . "\n"
        -             . "   Natural Docs version: " . NaturalDocs::Settings->TextAppVersion() . "\n"
        -             . "   Perl version: " . $self->PerlVersion() . " on " . $::OSNAME . "\n"
        -             . "\n";
        -             };
        -        };
        -
        -    die $errorMessage;
        -    };
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: PerlVersion
        -#   Returns the current Perl version as a string.
        -#
        -sub PerlVersion
        -    {
        -    my $self = shift;
        -
        -    my $perlVersion;
        -
        -    if ($^V)
        -        {  $perlVersion = sprintf('%vd', $^V);  }
        -    if (!$perlVersion || substr($perlVersion, 0, 1) eq '%')
        -        {  $perlVersion = $];  };
        -
        -    return $perlVersion;
        -    };
        -
        -
        -#
        -#   Function: GenerateCrashReport
        -#
        -#   Generates a report and returns the <FileName> it's located at.  Returns undef if it could not generate one.
        -#
        -sub GenerateCrashReport
        -    {
        -    my $self = shift;
        -
        -    my $errorMessage = $::EVAL_ERROR;
        -    $errorMessage =~ s/[\r\n]+$//;
        -
        -    my $reportDirectory = NaturalDocs::Settings->ProjectDirectory();
        -
        -    if (!$reportDirectory || !-d $reportDirectory)
        -        {  return undef;  };
        -
        -    my $file = NaturalDocs::File->JoinPaths($reportDirectory, 'LastCrash.txt');
        -
        -    open(FH_CRASHREPORT, '>' . $file) or return undef;
        -
        -    print FH_CRASHREPORT
        -    'Crash Message:' . "\n\n"
        -    . '   ' . $errorMessage . "\n\n";
        -
        -    if ($currentAction)
        -        {
        -        print FH_CRASHREPORT
        -        'Current Action:' . "\n\n"
        -        . '   ' . $currentAction . "\n\n";
        -        };
        -
        -    print FH_CRASHREPORT
        -    'Natural Docs version ' . NaturalDocs::Settings->TextAppVersion() . "\n"
        -    . 'Perl version ' . $self->PerlVersion . ' on ' . $::OSNAME . "\n\n"
        -    . 'Command Line:' . "\n\n"
        -    . '   ' . join(' ', @ARGV) . "\n\n";
        -
        -    if ($stackTrace)
        -        {
        -        print FH_CRASHREPORT
        -        'Stack Trace:' . "\n\n"
        -        . $stackTrace;
        -        }
        -    else
        -        {
        -        print FH_CRASHREPORT
        -        'Stack Trace not available.' . "\n\n";
        -        };
        -
        -    close(FH_CRASHREPORT);
        -    return $file;
        -    };
        -
        -
        -###############################################################################
        -# Group: Signal Handlers
        -
        -
        -#
        -#   Function: CatchDeath
        -#
        -#   Catches Perl die calls.
        -#
        -#   *IMPORTANT:* This function is a signal handler and should not be called manually.  Also, because of this, it does not have
        -#   a $self parameter.
        -#
        -#   Parameters:
        -#
        -#       message - The error message to die with.
        -#
        -sub CatchDeath #(message)
        -    {
        -    # No $self because it's a signal handler.
        -    my $message = shift;
        -
        -    if (!$NaturalDocs::Error::softDeath)
        -        {
        -        my $i = 0;
        -        my ($lastPackage, $lastFile, $lastLine, $lastFunction);
        -
        -        while (my ($package, $file, $line, $function) = caller($i))
        -            {
        -            if ($i != 0)
        -                {  $stackTrace .= ', called from' . "\n";  };
        -
        -            $stackTrace .= '   ' . $function;
        -
        -            if (defined $lastLine)
        -                {
        -                $stackTrace .= ', line ' . $lastLine;
        -
        -                if ($function !~ /^NaturalDocs::/)
        -                    {  $stackTrace .= ' of ' . $lastFile;  };
        -                };
        -
        -            ($lastPackage, $lastFile, $lastLine, $lastFunction) = ($package, $file, $line, $function);
        -            $i++;
        -            };
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/File.pm b/vendor/naturaldocs/Modules/NaturalDocs/File.pm
        deleted file mode 100644
        index 9a13c99a2..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/File.pm
        +++ /dev/null
        @@ -1,541 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::File
        -#
        -###############################################################################
        -#
        -#   A package to manage file access across platforms.  Incorporates functions from various standard File:: packages, but more
        -#   importantly, works around the glorious suckage present in File::Spec, at least in version 0.82 and earlier.  Read the "Why oh
        -#   why?" sections for why this package was necessary.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - The package doesn't depend on any other Natural Docs packages and is ready to use immediately.
        -#
        -#       - All functions except <CanonizePath()> assume that all parameters are canonized.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use File::Spec ();
        -use File::Path ();
        -use File::Copy ();
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::File;
        -
        -
        -#
        -#   Function: CheckCompatibility
        -#
        -#   Checks if the standard packages required by this one are up to snuff and dies if they aren't.  This is done because I can't
        -#   tell which versions of File::Spec have splitpath just by the version numbers.
        -#
        -sub CheckCompatibility
        -    {
        -    my ($self) = @_;
        -
        -    eval {
        -        File::Spec->splitpath('');
        -    };
        -
        -    if ($@)
        -        {
        -        NaturalDocs::Error->SoftDeath("Natural Docs requires a newer version of File::Spec than you have.  "
        -                                                    . "You must either upgrade it or upgrade Perl.");
        -        };
        -    };
        -
        -
        -###############################################################################
        -# Group: Path String Functions
        -
        -
        -#
        -#   Function: CanonizePath
        -#
        -#   Takes a path and returns a logically simplified version of it.
        -#
        -#   Why oh why?:
        -#
        -#       Because File::Spec->canonpath doesn't strip quotes on Windows.  So if you pass in "a b\c" or "a b"\c, they still end up as
        -#       different strings even though they're logically the same.
        -#
        -#       It also doesn't remove things like "..", so "a/b/../c" doesn't simplify to "a/c" like it should.
        -#
        -sub CanonizePath #(path)
        -    {
        -    my ($self, $path) = @_;
        -
        -    if ($::OSNAME eq 'MSWin32')
        -        {
        -        # We don't have to use a smarter algorithm for dropping quotes because they're invalid characters for actual file and
        -        # directory names.
        -        $path =~ s/\"//g;
        -        };
        -
        -    $path = File::Spec->canonpath($path);
        -
        -    # Condense a/b/../c into a/c.
        -
        -    my $upDir = File::Spec->updir();
        -    if (index($path, $upDir) != -1)
        -        {
        -        my ($volume, $directoryString, $file) = $self->SplitPath($path);
        -        my @directories = $self->SplitDirectories($directoryString);
        -
        -        my $i = 1;
        -        while ($i < scalar @directories)
        -            {
        -            if ($i > 0 && $directories[$i] eq $upDir && $directories[$i - 1] ne $upDir)
        -                {
        -                splice(@directories, $i - 1, 2);
        -                $i--;
        -                }
        -            else
        -                {  $i++;  };
        -            };
        -
        -        $directoryString = $self->JoinDirectories(@directories);
        -        $path = $self->JoinPath($volume, $directoryString, $file);
        -        };
        -
        -    return $path;
        -    };
        -
        -
        -#
        -#   Function: PathIsAbsolute
        -#
        -#   Returns whether the passed path is absolute.
        -#
        -sub PathIsAbsolute #(path)
        -    {
        -    my ($self, $path) = @_;
        -    return File::Spec->file_name_is_absolute($path);
        -    };
        -
        -
        -#
        -#   Function: JoinPath
        -#
        -#   Creates a path from its elements.
        -#
        -#   Parameters:
        -#
        -#       volume - The volume, such as the drive letter on Windows.  Undef if none.
        -#       dirString - The directory string.  Create with <JoinDirectories()> if necessary.
        -#       file - The file name, or undef if none.
        -#
        -#   Returns:
        -#
        -#       The joined path.
        -#
        -sub JoinPath #(volume, dirString, $file)
        -    {
        -    my ($self, $volume, $dirString, $file) = @_;
        -    return File::Spec->catpath($volume, $dirString, $file);
        -    };
        -
        -
        -#
        -#   Function: JoinPaths
        -#
        -#   Joins two paths.
        -#
        -#   Parameters:
        -#
        -#       basePath       - May be a relative path, an absolute path, or undef.
        -#       extraPath      - May be a relative path, a file, a relative path and file together, or undef.
        -#       noFileInExtra - Set this to true if extraPath is a relative path only, and doesn't have a file.
        -#
        -#   Returns:
        -#
        -#       The joined path.
        -#
        -#   Why oh why?:
        -#
        -#       Because nothing in File::Spec will simply slap two paths together.  They have to be split up for catpath/file, and rel2abs
        -#       requires the base to be absolute.
        -#
        -sub JoinPaths #(basePath, extraPath, noFileInExtra)
        -    {
        -    my ($self, $basePath, $extraPath, $noFileInExtra) = @_;
        -
        -    # If both are undef, it will return undef, which is what we want.
        -    if (!defined $basePath)
        -        {  return $extraPath;  }
        -    elsif (!defined $extraPath)
        -        {  return $basePath;  };
        -
        -    my ($baseVolume, $baseDirString, $baseFile) = File::Spec->splitpath($basePath, 1);
        -    my ($extraVolume, $extraDirString, $extraFile) = File::Spec->splitpath($extraPath, $noFileInExtra);
        -
        -    my @baseDirectories = $self->SplitDirectories($baseDirString);
        -    my @extraDirectories = $self->SplitDirectories($extraDirString);
        -
        -    my $fullDirString = $self->JoinDirectories(@baseDirectories, @extraDirectories);
        -
        -    my $fullPath = File::Spec->catpath($baseVolume, $fullDirString, $extraFile);
        -
        -    return $self->CanonizePath($fullPath);
        -    };
        -
        -
        -#
        -#   Function: SplitPath
        -#
        -#   Takes a path and returns its elements.
        -#
        -#   Parameters:
        -#
        -#       path - The path to split.
        -#       noFile - Set to true if the path doesn't have a file at the end.
        -#
        -#   Returns:
        -#
        -#       The array ( volume, directoryString, file ).  If any don't apply, they will be undef.  Use <SplitDirectories()> to split the
        -#       directory string if desired.
        -#
        -#   Why oh Why?:
        -#
        -#       Because File::Spec->splitpath may leave a trailing slash/backslash/whatever on the directory string, which makes
        -#       it a bit hard to match it with results from File::Spec->catdir.
        -#
        -sub SplitPath #(path, noFile)
        -    {
        -    my ($self, $path, $noFile) = @_;
        -
        -    my @segments = File::Spec->splitpath($path, $noFile);
        -
        -    if (!length $segments[0])
        -        {  $segments[0] = undef;  };
        -    if (!length $segments[2])
        -        {  $segments[2] = undef;  };
        -
        -    $segments[1] = File::Spec->catdir( File::Spec->splitdir($segments[1]) );
        -
        -    return @segments;
        -    };
        -
        -
        -#
        -#   Function: JoinDirectories
        -#
        -#   Creates a directory string from an array of directory names.
        -#
        -#   Parameters:
        -#
        -#       directory - A directory name.  There may be as many of these as desired.
        -#
        -sub JoinDirectories #(directory, directory, ...)
        -    {
        -    my ($self, @directories) = @_;
        -    return File::Spec->catdir(@directories);
        -    };
        -
        -
        -#
        -#   Function: SplitDirectories
        -#
        -#   Takes a string of directories and returns an array of its elements.
        -#
        -#   Why oh why?:
        -#
        -#       Because File::Spec->splitdir might leave an empty element at the end of the array, which screws up both joining in
        -#       <ConvertToURL> and navigation in <MakeRelativePath>.
        -#
        -sub SplitDirectories #(directoryString)
        -    {
        -    my ($self, $directoryString) = @_;
        -
        -    my @directories = File::Spec->splitdir($directoryString);
        -
        -    if (!length $directories[-1])
        -        {  pop @directories;  };
        -
        -    return @directories;
        -    };
        -
        -
        -#
        -#   Function: MakeRelativePath
        -#
        -#   Takes two paths and returns a relative path between them.
        -#
        -#   Parameters:
        -#
        -#       basePath    - The starting path.  May be relative or absolute, so long as the target path is as well.
        -#       targetPath  - The target path.  May be relative or absolute, so long as the base path is as well.
        -#
        -#       If both paths are relative, they are assumed to be relative to the same base.
        -#
        -#   Returns:
        -#
        -#       The target path relative to base.
        -#
        -#   Why oh why?:
        -#
        -#       First, there's nothing that gives a relative path between two relative paths.
        -#
        -#       Second, if target and base are absolute but on different volumes, File::Spec->abs2rel creates a totally non-functional
        -#       relative path.  It should return the target as is, since there is no relative path.
        -#
        -#       Third, File::Spec->abs2rel between absolute paths on the same volume, at least on Windows, leaves the drive letter
        -#       on.  So abs2rel('a:\b\c\d', 'a:\b') returns 'a:c\d' instead of the expected 'c\d'.  That makes no sense whatsoever.  It's
        -#       not like it was designed to handle only directory names, either; the documentation says 'path' and the code seems to
        -#       explicitly handle it.  There's just an 'unless' in there that tacks on the volume, defeating the purpose of a *relative* path
        -#       and making the function worthless.
        -#
        -sub MakeRelativePath #(basePath, targetPath)
        -    {
        -    my ($self, $basePath, $targetPath) = @_;
        -
        -    my ($baseVolume, $baseDirString, $baseFile) = $self->SplitPath($basePath, 1);
        -    my ($targetVolume, $targetDirString, $targetFile) = $self->SplitPath($targetPath);
        -
        -    # If the volumes are different, there is no possible relative path.
        -    if ($targetVolume ne $baseVolume)
        -        {  return $targetPath;  };
        -
        -    my @baseDirectories = $self->SplitDirectories($baseDirString);
        -    my @targetDirectories = $self->SplitDirectories($targetDirString);
        -
        -    # Skip the parts of the path that are the same.
        -    while (scalar @baseDirectories && @targetDirectories && $baseDirectories[0] eq $targetDirectories[0])
        -        {
        -        shift @baseDirectories;
        -        shift @targetDirectories;
        -        };
        -
        -    # Back out of the base path until it reaches where they were similar.
        -    for (my $i = 0; $i < scalar @baseDirectories; $i++)
        -        {
        -        unshift @targetDirectories, File::Spec->updir();
        -        };
        -
        -    $targetDirString = $self->JoinDirectories(@targetDirectories);
        -
        -    return File::Spec->catpath(undef, $targetDirString, $targetFile);
        -    };
        -
        -
        -#
        -#   Function: IsSubPathOf
        -#
        -#   Returns whether the path is a descendant of another path.
        -#
        -#   Parameters:
        -#
        -#       base - The base path to test against.
        -#       path - The possible subpath to test.
        -#
        -#   Returns:
        -#
        -#       Whether path is a descendant of base.
        -#
        -sub IsSubPathOf #(base, path)
        -    {
        -    my ($self, $base, $path) = @_;
        -
        -    # This is a quick test that should find a false quickly.
        -    if ($base eq substr($path, 0, length($base)))
        -        {
        -        # This doesn't guarantee true, because it could be "C:\A B" and "C:\A B C\File".  So we test for it by seeing if the last
        -        # directory in base is the same as the equivalent directory in path.
        -
        -        my ($baseVolume, $baseDirString, $baseFile) = NaturalDocs::File->SplitPath($base, 1);
        -        my @baseDirectories = NaturalDocs::File->SplitDirectories($baseDirString);
        -
        -        my ($pathVolume, $pathDirString, $pathFile) = NaturalDocs::File->SplitPath($path);
        -        my @pathDirectories = NaturalDocs::File->SplitDirectories($pathDirString);
        -
        -        return ( $baseDirectories[-1] eq $pathDirectories[ scalar @baseDirectories - 1 ] );
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: ConvertToURL
        -#
        -#   Takes a relative path and converts it from the native format to a relative URL.  Note that it _doesn't_ convert special characters
        -#   to amp chars.
        -#
        -sub ConvertToURL #(path)
        -    {
        -    my ($self, $path) = @_;
        -
        -    my ($pathVolume, $pathDirString, $pathFile) = $self->SplitPath($path);
        -    my @pathDirectories = $self->SplitDirectories($pathDirString);
        -
        -    my $i = 0;
        -    while ($i < scalar @pathDirectories && $pathDirectories[$i] eq File::Spec->updir())
        -        {
        -        $pathDirectories[$i] = '..';
        -        $i++;
        -        };
        -
        -    return join('/', @pathDirectories, $pathFile);
        -    };
        -
        -
        -#
        -#   Function: NoUpwards
        -#
        -#   Takes an array of directory entries and returns one without all the entries that refer to the parent directory, such as '.' and '..'.
        -#
        -sub NoUpwards #(array)
        -    {
        -    my ($self, @array) = @_;
        -    return File::Spec->no_upwards(@array);
        -    };
        -
        -
        -#
        -#   Function: NoFileName
        -#
        -#   Takes a path and returns a version without the file name.  Useful for sending paths to <CreatePath()>.
        -#
        -sub NoFileName #(path)
        -    {
        -    my ($self, $path) = @_;
        -
        -    my ($pathVolume, $pathDirString, $pathFile) = File::Spec->splitpath($path);
        -
        -    return File::Spec->catpath($pathVolume, $pathDirString, undef);
        -    };
        -
        -
        -#
        -#   Function: NoExtension
        -#
        -#   Returns the path without an extension.
        -#
        -sub NoExtension #(path)
        -    {
        -    my ($self, $path) = @_;
        -
        -    my $extension = $self->ExtensionOf($path);
        -
        -    if ($extension)
        -        {  $path = substr($path, 0, length($path) - length($extension) - 1);  };
        -
        -    return $path;
        -    };
        -
        -
        -#
        -#   Function: ExtensionOf
        -#
        -#   Returns the extension of the passed path, or undef if none.
        -#
        -sub ExtensionOf #(path)
        -    {
        -    my ($self, $path) = @_;
        -
        -    my ($pathVolume, $pathDirString, $pathFile) = File::Spec->splitpath($path);
        -
        -    # We need the leading dot in the regex so files that start with a dot but don't have an extension count as extensionless files.
        -    if ($pathFile =~ /.\.([^\.]+)$/)
        -        {  return $1;  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: IsCaseSensitive
        -#
        -#   Returns whether the current platform has case-sensitive paths.
        -#
        -sub IsCaseSensitive
        -    {
        -    return !(File::Spec->case_tolerant());
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Disk Functions
        -
        -
        -#
        -#   Function: CreatePath
        -#
        -#   Creates a directory tree corresponding to the passed path, regardless of how many directories do or do not already exist.
        -#   Do _not_ include a file name in the path.  Use <NoFileName()> first if you need to.
        -#
        -sub CreatePath #(path)
        -    {
        -    my ($self, $path) = @_;
        -    File::Path::mkpath($path);
        -    };
        -
        -
        -#
        -#   Function: RemoveEmptyTree
        -#
        -#   Removes an empty directory tree.  The passed directory will be removed if it's empty, and it will keep removing its parents
        -#   until it reaches one that's not empty or a set limit.
        -#
        -#   Parameters:
        -#
        -#       path - The path to start from.  It will try to remove this directory and work it's way down.
        -#       limit - The path to stop at if it doesn't find any non-empty directories first.  This path will *not* be removed.
        -#
        -sub RemoveEmptyTree #(path, limit)
        -    {
        -    my ($self, $path, $limit) = @_;
        -
        -    my ($volume, $directoryString) = $self->SplitPath($path, 1);
        -    my @directories = $self->SplitDirectories($directoryString);
        -
        -    my $directory = $path;
        -
        -    while (-d $directory && $directory ne $limit)
        -        {
        -        opendir FH_ND_FILE, $directory;
        -        my @entries = readdir FH_ND_FILE;
        -        closedir FH_ND_FILE;
        -
        -        @entries = $self->NoUpwards(@entries);
        -
        -        if (scalar @entries || !rmdir($directory))
        -            {  last;  };
        -
        -        pop @directories;
        -        $directoryString = $self->JoinDirectories(@directories);
        -        $directory = $self->JoinPath($volume, $directoryString);
        -        };
        -    };
        -
        -
        -#
        -#   Function: Copy
        -#
        -#   Copies a file from one path to another.  If the destination file exists, it is overwritten.
        -#
        -#   Parameters:
        -#
        -#       source       - The file to copy.
        -#       destination - The destination to copy to.
        -#
        -#   Returns:
        -#
        -#       Whether it succeeded
        -#
        -sub Copy #(source, destination) => bool
        -    {
        -    my ($self, $source, $destination) = @_;
        -    return File::Copy::copy($source, $destination);
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable.pm b/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable.pm
        deleted file mode 100644
        index df803e4b5..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable.pm
        +++ /dev/null
        @@ -1,384 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::ImageReferenceTable
        -#
        -###############################################################################
        -#
        -#   A <NaturalDocs::SourceDB>-based package that manages all the image references appearing in source files.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -use NaturalDocs::ImageReferenceTable::String;
        -use NaturalDocs::ImageReferenceTable::Reference;
        -
        -
        -package NaturalDocs::ImageReferenceTable;
        -
        -use base 'NaturalDocs::SourceDB::Extension';
        -
        -
        -###############################################################################
        -# Group: Information
        -
        -#
        -#   Topic: Usage
        -#
        -#       - <NaturalDocs::Project> and <NaturalDocs::SourceDB> must be initialized before this package can be used.
        -#
        -#       - Call <Register()> before using.
        -#
        -#
        -#   Topic: Programming Notes
        -#
        -#       When working on this code, remember that there are three things it has to juggle.
        -#
        -#       - The information in <NaturalDocs::SourceDB>.
        -#       - Image file references in <NaturalDocs::Project>.
        -#       - Source file rebuilding on changes.
        -#
        -#       Managing the actual image files will be handled between <NaturalDocs::Project> and the <NaturalDocs::Builder>
        -#       sub-packages.
        -#
        -#
        -#   Topic: Implementation
        -#
        -#       Managing image references is simpler than managing the references in <NaturalDocs::SymbolTable>.  In SymbolTable,
        -#       you have to worry about reference targets popping into and out of existence.  A link may go to a file that hasn't been
        -#       reparsed yet and the target may no longer exist.  We have to deal with that when we know it, which may be after the
        -#       reference's file was parsed.  Also, a new definition may appear that serves as a better interpretation of a link than its
        -#       current target, and again we may only know that after the reference's file has been parsed already.  So we have to deal
        -#       with scores and potential symbols and each symbol knowing exactly what links to it and so forth.
        -#
        -#       Not so with image references.  All possible targets (all possible image files) are known by <NaturalDocs::Project> early
        -#       on and will remain consistent throughout execution.  So because of that, we can get away with only storing reference
        -#       counts with each image and determining exactly where a reference points to as we find them.
        -#
        -#       Reference counts are stored with the image file information in <NaturalDocs::Project>.  However, it is not loaded and
        -#       saved to disk by it.  Rather, it is regenerated by this package when it loads <ImageReferenceTable.nd>.
        -#       NaturalDocs::Project only stores the last modification time (so it can add files to the build list if they've changed) and
        -#       whether it had any references at all on the last run (so it knows whether it should care if they've changed.)
        -#       ImageReferenceTable.nd stores each reference's target, width, and height.  Whether their interpretations have changed is
        -#       dealt with in the <Load()> function, again since the list of targets (image files) is constant.
        -#
        -#       The package is based on <NaturalDocs::SourceDB>, so read it's documentation for more information on how it works.
        -#
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   var: extensionID
        -#   The <ExtensionID> granted by <NaturalDocs::SourceDB>.
        -#
        -my $extensionID;
        -
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: ImageReferenceTable.nd
        -#
        -#   The data file which stores all the image references from the last run of Natural Docs.
        -#
        -#   Format:
        -#
        -#       > [Standard Binary Header]
        -#
        -#       It starts with the standard binary header from <NaturalDocs::BinaryFile>.
        -#
        -#       > [Image Reference String or undef]
        -#       > [AString16: target file]
        -#       > [UInt16: target width or 0]
        -#       > [UInt16: target height or 0]
        -#
        -#       For each <ImageReferenceString>, it's target, width, and height are stored.  The target is needed so we can tell if it
        -#       changed from the last run, and the dimensions are needed because if the target hasn't changed but the file's dimensions
        -#       have, the source files need to be rebuilt.
        -#
        -#       <ImageReferenceStrings> are encoded by <NaturalDocs::ImageReferenceTable::String>.
        -#
        -#       > [AString16: definition file or undef] ...
        -#
        -#       Then comes a series of AString16s for all the files that define the reference until it hits an undef.
        -#
        -#       This whole series is repeated for each <ImageReferenceString> until it hits an undef.
        -#
        -#	Revisions:
        -#
        -#		1.4:
        -#
        -#			- The file was added to Natural Docs.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: Register
        -#   Registers the package with <NaturalDocs::SourceDB>.
        -#
        -sub Register
        -    {
        -    my $self = shift;
        -    $extensionID = NaturalDocs::SourceDB->RegisterExtension($self, 0);
        -    };
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Loads the data from <ImageReferenceTable.nd>.  Returns whether it was successful.
        -#
        -sub Load # => bool
        -    {
        -    my $self = shift;
        -
        -    if (NaturalDocs::Settings->RebuildData())
        -        {  return 0;  };
        -
        -    # The file format hasn't changed since it was introduced.
        -    if (!NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('ImageReferenceTable.nd') ))
        -        {  return 0;  };
        -
        -
        -    # [Image Reference String or undef]
        -    while (my $referenceString = NaturalDocs::ImageReferenceTable::String->FromBinaryFile())
        -        {
        -        NaturalDocs::SourceDB->AddItem($extensionID, $referenceString,
        -                                                           NaturalDocs::ImageReferenceTable::Reference->New());
        -
        -        # [AString16: target file]
        -        # [UInt16: target width or 0]
        -        # [UInt16: target height or 0]
        -
        -        my $targetFile = NaturalDocs::BinaryFile->GetAString16();
        -        my $width = NaturalDocs::BinaryFile->GetUInt16();
        -        my $height = NaturalDocs::BinaryFile->GetUInt16();
        -
        -        my $newTargetFile = $self->SetReferenceTarget($referenceString);
        -        my $newWidth;
        -        my $newHeight;
        -
        -        if ($newTargetFile)
        -            {
        -            NaturalDocs::Project->AddImageFileReference($newTargetFile);
        -            ($newWidth, $newHeight) = NaturalDocs::Project->ImageFileDimensions($newTargetFile);
        -            };
        -
        -        my $rebuildDefinitions = ($newTargetFile ne $targetFile || $newWidth != $width || $newHeight != $height);
        -
        -
        -        # [AString16: definition file or undef] ...
        -        while (my $definitionFile = NaturalDocs::BinaryFile->GetAString16())
        -            {
        -            NaturalDocs::SourceDB->AddDefinition($extensionID, $referenceString, $definitionFile);
        -
        -            if ($rebuildDefinitions)
        -                {  NaturalDocs::Project->RebuildFile($definitionFile);  };
        -            };
        -        };
        -
        -
        -    NaturalDocs::BinaryFile->Close();
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves the data to <ImageReferenceTable.nd>.
        -#
        -sub Save
        -    {
        -    my $self = shift;
        -
        -    my $references = NaturalDocs::SourceDB->GetAllItemsHashRef($extensionID);
        -
        -    NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('ImageReferenceTable.nd') );
        -
        -    while (my ($referenceString, $referenceObject) = each %$references)
        -        {
        -        # [Image Reference String or undef]
        -        # [AString16: target file]
        -        # [UInt16: target width or 0]
        -        # [UInt16: target height or 0]
        -
        -        NaturalDocs::ImageReferenceTable::String->ToBinaryFile($referenceString);
        -
        -        my $target = $referenceObject->Target();
        -        my ($width, $height);
        -
        -        if ($target)
        -            {  ($width, $height) = NaturalDocs::Project->ImageFileDimensions($target);  };
        -
        -        NaturalDocs::BinaryFile->WriteAString16( $referenceObject->Target() );
        -        NaturalDocs::BinaryFile->WriteUInt16( ($width || 0) );
        -        NaturalDocs::BinaryFile->WriteUInt16( ($height || 0) );
        -
        -        # [AString16: definition file or undef] ...
        -
        -        my $definitions = $referenceObject->GetAllDefinitionsHashRef();
        -
        -        foreach my $definition (keys %$definitions)
        -            {  NaturalDocs::BinaryFile->WriteAString16($definition);  };
        -
        -        NaturalDocs::BinaryFile->WriteAString16(undef);
        -        };
        -
        -    NaturalDocs::ImageReferenceTable::String->ToBinaryFile(undef);
        -
        -    NaturalDocs::BinaryFile->Close();
        -    };
        -
        -
        -#
        -#   Function: AddReference
        -#
        -#   Adds a new image reference.
        -#
        -sub AddReference #(FileName file, string referenceText)
        -    {
        -    my ($self, $file, $referenceText) = @_;
        -
        -    my $referenceString = NaturalDocs::ImageReferenceTable::String->Make($file, $referenceText);
        -
        -    if (!NaturalDocs::SourceDB->HasItem($extensionID, $referenceString))
        -        {
        -        my $referenceObject = NaturalDocs::ImageReferenceTable::Reference->New();
        -        NaturalDocs::SourceDB->AddItem($extensionID, $referenceString, $referenceObject);
        -
        -        my $target = $self->SetReferenceTarget($referenceString);
        -        if ($target)
        -            {  NaturalDocs::Project->AddImageFileReference($target);  };
        -        };
        -
        -    NaturalDocs::SourceDB->AddDefinition($extensionID, $referenceString, $file);
        -    };
        -
        -
        -#
        -#   Function: OnDeletedDefinition
        -#
        -#   Called for each definition deleted by <NaturalDocs::SourceDB>.  This is called *after* the definition has been deleted from
        -#   the database, so don't expect to be able to read it.
        -#
        -sub OnDeletedDefinition #(ImageReferenceString referenceString, FileName file, bool wasLastDefinition)
        -    {
        -    my ($self, $referenceString, $file, $wasLastDefinition) = @_;
        -
        -    if ($wasLastDefinition)
        -        {
        -        my $referenceObject = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString);
        -        my $target = $referenceObject->Target();
        -
        -        if ($target)
        -            {  NaturalDocs::Project->DeleteImageFileReference($target);  };
        -
        -        NaturalDocs::SourceDB->DeleteItem($extensionID, $referenceString);
        -        };
        -    };
        -
        -
        -#
        -#   Function: GetReferenceTarget
        -#
        -#   Returns the image file the reference resolves to, or undef if none.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> the reference appears in.
        -#       text - The reference text.
        -#
        -sub GetReferenceTarget #(FileName sourceFile, string text) => FileName
        -    {
        -    my ($self, $sourceFile, $text) = @_;
        -
        -    my $referenceString = NaturalDocs::ImageReferenceTable::String->Make($sourceFile, $text);
        -    my $reference = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString);
        -
        -    if (!defined $reference)
        -        {  return undef;  }
        -    else
        -        {  return $reference->Target();  };
        -    };
        -
        -
        -#
        -#   Function: SetReferenceTarget
        -#
        -#   Determines the best target for the passed <ImageReferenceString> and sets it on the
        -#   <NaturalDocs::ImageReferenceTable::Reference> object.  Returns the new target <FileName>.  Does *not* add any source
        -#   files to the bulid list.
        -#
        -sub SetReferenceTarget #(ImageReferenceString referenceString) => FileName
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    my $referenceObject = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString);
        -    my ($sourcePath, $text) = NaturalDocs::ImageReferenceTable::String->InformationOf($referenceString);
        -
        -
        -    # Try the path relative to the source file first.
        -
        -    my $target;
        -
        -    my $imageFile = NaturalDocs::File->JoinPaths($sourcePath, $text);
        -    my $exists = NaturalDocs::Project->ImageFileExists($imageFile);
        -
        -
        -    # Then try relative image directories.
        -
        -    if (!$exists)
        -        {
        -        my $relativeImageDirectories = NaturalDocs::Settings->RelativeImageDirectories();
        -
        -        for (my $i = 0; $i < scalar @$relativeImageDirectories && !$exists; $i++)
        -            {
        -            $imageFile = NaturalDocs::File->JoinPaths($sourcePath, $relativeImageDirectories->[$i], 1);
        -            $imageFile = NaturalDocs::File->JoinPaths($imageFile, $text);
        -
        -            $exists = NaturalDocs::Project->ImageFileExists($imageFile);
        -            };
        -        };
        -
        -
        -    # Then try absolute image directories.
        -
        -    if (!$exists)
        -        {
        -        my $imageDirectories = NaturalDocs::Settings->ImageDirectories();
        -
        -        for (my $i = 0; $i < scalar @$imageDirectories && !$exists; $i++)
        -            {
        -            $imageFile = NaturalDocs::File->JoinPaths($imageDirectories->[$i], $text);
        -            $exists = NaturalDocs::Project->ImageFileExists($imageFile);
        -            };
        -        };
        -
        -
        -    if ($exists)
        -        {  $target = NaturalDocs::Project->ImageFileCapitalization($imageFile);  };
        -    #else leave it as undef.
        -
        -    $referenceObject->SetTarget($target);
        -    return $target;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm b/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm
        deleted file mode 100644
        index 3477435af..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm
        +++ /dev/null
        @@ -1,45 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::ImageReferenceTable::Reference
        -#
        -###############################################################################
        -#
        -#   A class for references being tracked in <NaturalDocs::SourceDB>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::ImageReferenceTable::Reference;
        -
        -use base 'NaturalDocs::SourceDB::Item';
        -
        -
        -use NaturalDocs::DefineMembers 'TARGET', 'Target()', 'SetTarget()',
        -                                                 'NEEDS_REBUILD', 'NeedsRebuild()', 'SetNeedsRebuild()';
        -
        -
        -#
        -#   Variables: Members
        -#
        -#   The following constants are indexes into the object array.
        -#
        -#   TARGET - The image <FileName> this reference resolves to, or undef if none.
        -#
        -
        -
        -#
        -#   Functions: Member Functions
        -#
        -#   Target - Returns the image <FileName> this reference resolves to, or undef if none.
        -#   SetTarget - Replaces the image <FileName> this reference resolves to, or undef if none.
        -#
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable/String.pm b/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable/String.pm
        deleted file mode 100644
        index 27fbf7797..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ImageReferenceTable/String.pm
        +++ /dev/null
        @@ -1,111 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::ImageReferenceTable::String
        -#
        -###############################################################################
        -#
        -#   A package for creating and managing <ImageReferenceStrings>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::ImageReferenceTable::String;
        -
        -
        -#
        -#   Type: ImageReferenceString
        -#
        -#   A string representing a unique image reference.  It's composed of the reference text and the directory of the source file.
        -#   The source file name itself isn't included because two files in the same directory with the same reference text will always go
        -#   to the same targets.
        -#
        -
        -
        -#
        -#   Function: Make
        -#
        -#   Converts a source <FileName> and the reference text to an <ImageReferenceString>.
        -#
        -sub Make #(FileName sourceFile, string text) => ImageReferenceString
        -    {
        -    my ($self, $sourceFile, $text) = @_;
        -
        -    my $path = NaturalDocs::File->NoFileName($sourceFile);
        -
        -    # Condense whitespace and remove any separator characters.
        -    $path =~ tr/ \t\r\n\x1C/ /s;
        -    $text =~ tr/ \t\r\n\x1C/ /s;
        -
        -    return $path . "\x1C" . $text;
        -    };
        -
        -
        -#
        -#   Function: InformationOf
        -#
        -#   Returns the information contained in the <ImageReferenceString> as the array ( path, text ).
        -#
        -sub InformationOf #(ImageReferenceString referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -    return split(/\x1C/, $referenceString);
        -    };
        -
        -
        -#
        -#   Function: ToBinaryFile
        -#
        -#   Writes an <ImageReferenceString> to <NaturalDocs::BinaryFile>.  Can also encode an undef.
        -#
        -#   Format:
        -#
        -#       > [AString16: path] [AString16: reference text] ...
        -#
        -#       Undef is represented by the first AString16 being undef.
        -#
        -sub ToBinaryFile #(ImageReferenceString referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    if (defined $referenceString)
        -        {
        -        my ($path, $text) = split(/\x1C/, $referenceString);
        -
        -        NaturalDocs::BinaryFile->WriteAString16($path);
        -        NaturalDocs::BinaryFile->WriteAString16($text);
        -        }
        -    else
        -        {
        -        NaturalDocs::BinaryFile->WriteAString16(undef);
        -        };
        -    };
        -
        -
        -#
        -#   Function: FromBinaryFile
        -#
        -#   Loads an <ImageReferenceString> or undef from <NaturalDocs::BinaryFile> and returns it.
        -#
        -sub FromBinaryFile
        -    {
        -    my $self = shift;
        -
        -    my $path = NaturalDocs::BinaryFile->GetAString16();
        -
        -    if (!defined $path)
        -        {  return undef;  };
        -
        -    my $text = NaturalDocs::BinaryFile->GetAString16();
        -
        -    return $path . "\x1C" . $text;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages.pm
        deleted file mode 100644
        index a85f749f4..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages.pm
        +++ /dev/null
        @@ -1,1476 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Languages
        -#
        -###############################################################################
        -#
        -#   A package to manage all the programming languages Natural Docs supports.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - Prior to use, <NaturalDocs::Settings> must be initialized and <Load()> must be called.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use Text::Wrap();
        -
        -use NaturalDocs::Languages::Prototype;
        -
        -use NaturalDocs::Languages::Base;
        -use NaturalDocs::Languages::Simple;
        -use NaturalDocs::Languages::Advanced;
        -
        -use NaturalDocs::Languages::Perl;
        -use NaturalDocs::Languages::CSharp;
        -use NaturalDocs::Languages::ActionScript;
        -
        -use NaturalDocs::Languages::Ada;
        -use NaturalDocs::Languages::PLSQL;
        -use NaturalDocs::Languages::Pascal;
        -use NaturalDocs::Languages::Tcl;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages;
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   handle: FH_LANGUAGES
        -#
        -#   The file handle used for writing to <Languages.txt>.
        -#
        -
        -
        -#
        -#   hash: languages
        -#
        -#   A hash of all the defined languages.  The keys are the all-lowercase language names, and the values are
        -#   <NaturalDocs::Languages::Base>-derived objects.
        -#
        -my %languages;
        -
        -#
        -#   hash: extensions
        -#
        -#   A hash of all the defined languages' extensions.  The keys are the all-lowercase extensions, and the values are the
        -#   all-lowercase names of the languages that defined them.
        -#
        -my %extensions;
        -
        -#
        -#   hash: shebangStrings
        -#
        -#   A hash of all the defined languages' strings to search for in the shebang (#!) line.  The keys are the all-lowercase strings, and
        -#   the values are the all-lowercase names of the languages that defined them.
        -#
        -my %shebangStrings;
        -
        -#
        -#   hash: shebangFiles
        -#
        -#   A hash of all the defined languages for files where it needs to be found via shebang strings.  The keys are the file names,
        -#   and the values are language names, or undef if the file isn't supported.  These values should be filled in the first time
        -#   each file is parsed for a shebang string so that it doesn't have to be done multiple times.
        -#
        -my %shebangFiles;
        -
        -#
        -#   array: mainLanguageNames
        -#
        -#   An array of the language names that are defined in the main <Languages.txt>.
        -#
        -my @mainLanguageNames;
        -
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: Languages.txt
        -#
        -#   The configuration file that defines or overrides the language definitions for Natural Docs.  One version sits in Natural Docs'
        -#   configuration directory, and another can be in a project directory to add to or override them.
        -#
        -#   > # [comments]
        -#
        -#   Everything after a # symbol is ignored.  However, for this particular file, comments can only appear on their own lines.
        -#   They cannot appear after content on the same line.
        -#
        -#   > Format: [version]
        -#
        -#   Specifies the file format version of the file.
        -#
        -#
        -#   Sections:
        -#
        -#       > Ignore[d] Extension[s]: [extension] [extension] ...
        -#
        -#       Causes the listed file extensions to be ignored, even if they were previously defined to be part of a language.  The list is
        -#       space-separated.  ex. "Ignore Extensions: cvs txt"
        -#
        -#
        -#       > Language: [name]
        -#
        -#       Creates a new language.  Everything underneath applies to this language until the next one.  Names can use any
        -#       characters.
        -#
        -#       The languages "Text File" and "Shebang Script" have special meanings.  Text files are considered all comment and don't
        -#       have comment symbols.  Shebang scripts have their language determined by the shebang string and automatically
        -#       include files with no extension in addition to the extensions defined.
        -#
        -#       If "Text File" doesn't define ignored prefixes, a package separator, or enum value behavior, those settings will be copied
        -#       from the language with the most files in the source tree.
        -#
        -#
        -#       > Alter Language: [name]
        -#
        -#       Alters an existing language.  Everything underneath it overrides the previous settings until the next one.  Note that if a
        -#       property has an [Add/Replace] form and that property has already been defined, you have to specify whether you're adding
        -#       to or replacing the defined list.
        -#
        -#
        -#   Language Properties:
        -#
        -#       > Extension[s]: [extension] [extension] ...
        -#       > [Add/Replace] Extension[s]: ...
        -#
        -#       Defines file extensions for the language's source files.  The list is space-separated.  ex. "Extensions: c cpp".  You can use
        -#       extensions that were previously used by another language to redefine them.
        -#
        -#
        -#       > Shebang String[s]: [string] [string] ...
        -#       > [Add/Replace] Shebang String[s]: ...
        -#
        -#       Defines a list of strings that can appear in the shebang (#!) line to designate that it's part of this language.  They can
        -#       appear anywhere in the line, so "php" will work for "#!/user/bin/php4".  You can use strings that were previously used by
        -#       another language to redefine them.
        -#
        -#
        -#       > Ignore[d] Prefix[es] in Index: [prefix] [prefix] ...
        -#       > Ignore[d] [Topic Type] Prefix[es] in Index: [prefix] [prefix] ...
        -#       > [Add/Replace] Ignore[d] Prefix[es] in Index: ...
        -#       > [Add/Replace] Ignore[d] [Topic Type] Prefix[es] in Index: ...
        -#
        -#       Specifies prefixes that should be ignored when sorting symbols for an index.  Can be specified in general or for a specific
        -#       <TopicType>.  The prefixes will still appear, the symbols will just be sorted as if they're not there.  For example, specifying
        -#       "ADO_" for functions will mean that "ADO_DoSomething" will appear under D instead of A.
        -#
        -#
        -#   Basic Language Support Properties:
        -#
        -#       These attributes are only available for languages with basic language support.
        -#
        -#
        -#       > Line Comment[s]: [symbol] [symbol] ...
        -#
        -#       Defines a space-separated list of symbols that are used for line comments, if any.  ex. "Line Comment: //".
        -#
        -#
        -#       > Block Comment[s]: [opening symbol] [closing symbol] [opening symbol] [closing symbol] ...
        -#
        -#       Defines a space-separated list of symbol pairs that are used for block comments, if any.  ex. "Block Comment: /* */".
        -#
        -#
        -#       > Package Separator: [symbol]
        -#
        -#       Defines the default package separator symbol, such as . or ::.  This is for presentation only and will not affect how
        -#       Natural Docs links are parsed.  The default is a dot.
        -#
        -#
        -#       > [Topic Type] Prototype Ender[s]: [symbol] [symbol] ...
        -#
        -#       When defined, Natural Docs will attempt to collect prototypes from the code following the specified <TopicType>.  It grabs
        -#       code until the first ender symbol or the next Natural Docs comment, and if it contains the topic name, it serves as its
        -#       prototype.  Use \n to specify a line break.  ex. "Function Prototype Enders: { ;", "Variable Prototype Enders: = ;".
        -#
        -#
        -#       > Line Extender: [symbol]
        -#
        -#       Defines the symbol that allows a prototype to span multiple lines if normally a line break would end it.
        -#
        -#
        -#       > Enum Values: [global|under type|under parent]
        -#
        -#       Defines how enum values are referenced.  The default is global.
        -#
        -#       global - Values are always global, referenced as 'value'.
        -#       under type - Values are under the enum type, referenced as 'package.enum.value'.
        -#       under parent - Values are under the enum's parent, referenced as 'package.value'.
        -#
        -#
        -#       > Perl Package: [perl package]
        -#
        -#       Specifies the Perl package used to fine-tune the language behavior in ways too complex to do in this file.
        -#
        -#
        -#   Full Language Support Properties:
        -#
        -#       These attributes are only available for languages with full language support.
        -#
        -#
        -#       > Full Language Support: [perl package]
        -#
        -#       Specifies the Perl package that has the parsing routines necessary for full language support.
        -#
        -#
        -#   Revisions:
        -#
        -#       1.32:
        -#
        -#           - Package Separator is now a basic language support only property.
        -#           - Added Enum Values setting.
        -#
        -#       1.3:
        -#
        -#           - The file was introduced.
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Loads both the master and the project version of <Languages.txt>.
        -#
        -sub Load
        -    {
        -    my $self = shift;
        -
        -    # Hashrefs where the keys are all-lowercase extensions/shebang strings, and the values are arrayrefs of the languages
        -    # that defined them, earliest first, all lowercase.
        -    my %tempExtensions;
        -    my %tempShebangStrings;
        -
        -    $self->LoadFile(1, \%tempExtensions, \%tempShebangStrings);  # Main
        -
        -    if (!exists $languages{'shebang script'})
        -        {  NaturalDocs::ConfigFile->AddError('You must define "Shebang Script" in the main languages file.');  };
        -    if (!exists $languages{'text file'})
        -        {  NaturalDocs::ConfigFile->AddError('You must define "Text File" in the main languages file.');  };
        -
        -    my $errorCount = NaturalDocs::ConfigFile->ErrorCount();
        -
        -    if ($errorCount)
        -        {
        -        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
        -        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
        -                                                    . ' in ' . NaturalDocs::Project->MainConfigFile('Languages.txt'));
        -        }
        -
        -
        -    $self->LoadFile(0, \%tempExtensions, \%tempShebangStrings);  # User
        -
        -    $errorCount = NaturalDocs::ConfigFile->ErrorCount();
        -
        -    if ($errorCount)
        -        {
        -        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
        -        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
        -                                                    . ' in ' . NaturalDocs::Project->UserConfigFile('Languages.txt'));
        -        };
        -
        -
        -    # Convert the temp hashes into the real ones.
        -
        -    while (my ($extension, $languages) = each %tempExtensions)
        -        {
        -        $extensions{$extension} = $languages->[-1];
        -        };
        -    while (my ($shebangString, $languages) = each %tempShebangStrings)
        -        {
        -        $shebangStrings{$shebangString} = $languages->[-1];
        -        };
        -    };
        -
        -
        -#
        -#   Function: LoadFile
        -#
        -#   Loads a particular version of <Languages.txt>.
        -#
        -#   Parameters:
        -#
        -#       isMain - Whether the file is the main file or not.
        -#       tempExtensions - A hashref where the keys are all-lowercase extensions, and the values are arrayrefs of the all-lowercase
        -#                                 names of the languages that defined them, earliest first.  It will be changed by this function.
        -#       tempShebangStrings - A hashref where the keys are all-lowercase shebang strings, and the values are arrayrefs of the
        -#                                        all-lowercase names of the languages that defined them, earliest first.  It will be changed by this
        -#                                        function.
        -#
        -sub LoadFile #(isMain, tempExtensions, tempShebangStrings)
        -    {
        -    my ($self, $isMain, $tempExtensions, $tempShebangStrings) = @_;
        -
        -    my ($file, $status);
        -
        -    if ($isMain)
        -        {
        -        $file = NaturalDocs::Project->MainConfigFile('Languages.txt');
        -        $status = NaturalDocs::Project->MainConfigFileStatus('Languages.txt');
        -        }
        -    else
        -        {
        -        $file = NaturalDocs::Project->UserConfigFile('Languages.txt');
        -        $status = NaturalDocs::Project->UserConfigFileStatus('Languages.txt');
        -        };
        -
        -
        -    my $version;
        -
        -    # An array of properties for the current language.  Each entry is the three consecutive values ( lineNumber, keyword, value ).
        -    my @properties;
        -
        -    if ($version = NaturalDocs::ConfigFile->Open($file))
        -        {
        -        # The format hasn't changed significantly since the file was introduced.
        -
        -        if ($status == ::FILE_CHANGED())
        -            {
        -            NaturalDocs::Project->ReparseEverything();
        -            NaturalDocs::SymbolTable->RebuildAllIndexes();  # Because the ignored prefixes could change.
        -            };
        -
        -        my ($keyword, $value, $comment);
        -
        -        while (($keyword, $value, $comment) = NaturalDocs::ConfigFile->GetLine())
        -            {
        -            $value .= $comment;
        -            $value =~ s/^ //;
        -
        -            # Process previous properties.
        -            if (($keyword eq 'language' || $keyword eq 'alter language') && scalar @properties)
        -                {
        -                if ($isMain && $properties[1] eq 'language')
        -                    {  push @mainLanguageNames, $properties[2];  };
        -
        -                $self->ProcessProperties(\@properties, $version, $tempExtensions, $tempShebangStrings);
        -                @properties = ( );
        -                };
        -
        -            if ($keyword =~ /^ignored? extensions?$/)
        -                {
        -                $value =~ tr/.*//d;
        -                my @extensions = split(/ /, lc($value));
        -
        -                foreach my $extension (@extensions)
        -                    {  delete $tempExtensions->{$extension};  };
        -                }
        -            else
        -                {
        -                push @properties, NaturalDocs::ConfigFile->LineNumber(), $keyword, $value;
        -                };
        -            };
        -
        -        if (scalar @properties)
        -            {
        -            if ($isMain && $properties[1] eq 'language')
        -                {  push @mainLanguageNames, $properties[2];  };
        -
        -            $self->ProcessProperties(\@properties, $version, $tempExtensions, $tempShebangStrings);
        -            };
        -        }
        -
        -    else # couldn't open file
        -        {
        -        if ($isMain)
        -            {  die "Couldn't open languages file " . $file . "\n";  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: ProcessProperties
        -#
        -#   Processes an array of language properties from <Languages.txt>.
        -#
        -#   Parameters:
        -#
        -#       properties - An arrayref of properties where each entry is the three consecutive values ( lineNumber, keyword, value ).
        -#                         It must start with the Language or Alter Language property.
        -#       version - The <VersionInt> of the file.
        -#       tempExtensions - A hashref where the keys are all-lowercase extensions, and the values are arrayrefs of the all-lowercase
        -#                                 names of the languages that defined them, earliest first.  It will be changed by this function.
        -#       tempShebangStrings - A hashref where the keys are all-lowercase shebang strings, and the values are arrayrefs of the
        -#                                        all-lowercase names of the languages that defined them, earliest first.  It will be changed by this
        -#                                        function.
        -#
        -sub ProcessProperties #(properties, version, tempExtensions, tempShebangStrings)
        -    {
        -    my ($self, $properties, $version, $tempExtensions, $tempShebangStrings) = @_;
        -
        -
        -    # First validate the name and check whether the language has full support.
        -
        -    my $language;
        -    my $fullLanguageSupport;
        -    my ($lineNumber, $languageKeyword, $languageName) = @$properties[0..2];
        -    my $lcLanguageName = lc($languageName);
        -    my ($keyword, $value);
        -
        -    if ($languageKeyword eq 'alter language')
        -        {
        -        $language = $languages{$lcLanguageName};
        -
        -        if (!defined $language)
        -            {
        -            NaturalDocs::ConfigFile->AddError('The language ' . $languageName . ' is not defined.', $lineNumber);
        -            return;
        -            }
        -        else
        -            {
        -            $fullLanguageSupport = (!$language->isa('NaturalDocs::Languages::Simple'));
        -            };
        -        }
        -
        -    elsif ($languageKeyword eq 'language')
        -        {
        -        if (exists $languages{$lcLanguageName})
        -            {
        -            NaturalDocs::ConfigFile->AddError('The language ' . $value . ' is already defined.  Use "Alter Language" if you want '
        -                                                             . 'to override its settings.', $lineNumber);
        -            return;
        -            };
        -
        -        # Case is important with these two.
        -        if ($lcLanguageName eq 'shebang script')
        -            {  $languageName = 'Shebang Script';  }
        -        elsif ($lcLanguageName eq 'text file')
        -            {  $languageName = 'Text File';  };
        -
        -
        -        # Go through the properties looking for whether the language has basic or full support and which package to use to create
        -        # it.
        -
        -        for (my $i = 3; $i < scalar @$properties; $i += 3)
        -            {
        -            ($lineNumber, $keyword, $value) = @$properties[$i..$i+2];
        -
        -            if ($keyword eq 'full language support')
        -                {
        -                $fullLanguageSupport = 1;
        -
        -                eval
        -                    {
        -                    $language = $value->New($languageName);
        -                    };
        -                if ($::EVAL_ERROR)
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Could not create ' . $value . ' object.', $lineNumber);
        -                    return;
        -                    };
        -
        -                last;
        -                }
        -
        -            elsif ($keyword eq 'perl package')
        -                {
        -                eval
        -                    {
        -                    $language = $value->New($languageName);
        -                    };
        -                if ($::EVAL_ERROR)
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Could not create ' . $value . ' object.', $lineNumber);
        -                    return;
        -                    };
        -                };
        -            };
        -
        -        # If $language was not created by now, it's a generic basic support language.
        -        if (!defined $language)
        -            {  $language = NaturalDocs::Languages::Simple->New($languageName);  };
        -
        -        $languages{$lcLanguageName} = $language;
        -        }
        -
        -    else # not language or alter language
        -        {
        -        NaturalDocs::ConfigFile->AddError('You must start this line with "Language", "Alter Language", or "Ignore Extensions".',
        -                                                           $lineNumber);
        -        return;
        -        };
        -
        -
        -    # Decode the properties.
        -
        -    for (my $i = 3; $i < scalar @$properties; $i += 3)
        -        {
        -        ($lineNumber, $keyword, $value) = @$properties[$i..$i+2];
        -
        -        if ($keyword =~ /^(?:(add|replace) )?extensions?$/)
        -            {
        -            my $command = $1;
        -
        -
        -            # Remove old extensions.
        -
        -            if (defined $language->Extensions() && $command eq 'replace')
        -                {
        -                foreach my $extension (@{$language->Extensions()})
        -                    {
        -                    if (exists $tempExtensions->{$extension})
        -                        {
        -                        my $languages = $tempExtensions->{$extension};
        -                        my $i = 0;
        -
        -                        while ($i < scalar @$languages)
        -                            {
        -                            if ($languages->[$i] eq $lcLanguageName)
        -                                {  splice(@$languages, $i, 1);  }
        -                            else
        -                                {  $i++;  };
        -                            };
        -
        -                        if (!scalar @$languages)
        -                            {  delete $tempExtensions->{$extension};  };
        -                        };
        -                    };
        -                };
        -
        -
        -            # Add new extensions.
        -
        -            # Ignore stars and dots so people could use .ext or *.ext.
        -            $value =~ s/\*\.|\.//g;
        -
        -            my @extensions = split(/ /, lc($value));
        -
        -            foreach my $extension (@extensions)
        -                {
        -                if (!exists $tempExtensions->{$extension})
        -                    {  $tempExtensions->{$extension} = [ ];  };
        -
        -                push @{$tempExtensions->{$extension}}, $lcLanguageName;
        -                };
        -
        -
        -            # Set the extensions for the language object.
        -
        -            if (defined $language->Extensions())
        -                {
        -                if ($command eq 'add')
        -                    {  push @extensions, @{$language->Extensions()};  }
        -                elsif (!$command)
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('You need to specify whether you are adding to or replacing the list of extensions.',
        -                                                                       $lineNumber);
        -                    };
        -                };
        -
        -            $language->SetExtensions(\@extensions);
        -            }
        -
        -        elsif ($keyword =~ /^(?:(add|replace) )?shebang strings?$/)
        -            {
        -            my $command = $1;
        -
        -
        -            # Remove old strings.
        -
        -            if (defined $language->ShebangStrings() && $command eq 'replace')
        -                {
        -                foreach my $shebangString (@{$language->ShebangStrings()})
        -                    {
        -                    if (exists $tempShebangStrings->{$shebangString})
        -                        {
        -                        my $languages = $tempShebangStrings->{$shebangString};
        -                        my $i = 0;
        -
        -                        while ($i < scalar @$languages)
        -                            {
        -                            if ($languages->[$i] eq $lcLanguageName)
        -                                {  splice(@$languages, $i, 1);  }
        -                            else
        -                                {  $i++;  };
        -                            };
        -
        -                        if (!scalar @$languages)
        -                            {  delete $tempShebangStrings->{$shebangString};  };
        -                        };
        -                    };
        -                };
        -
        -
        -            # Add new strings.
        -
        -            my @shebangStrings = split(/ /, lc($value));
        -
        -            foreach my $shebangString (@shebangStrings)
        -                {
        -                if (!exists $tempShebangStrings->{$shebangString})
        -                    {  $tempShebangStrings->{$shebangString} = [ ];  };
        -
        -                push @{$tempShebangStrings->{$shebangString}}, $lcLanguageName;
        -                };
        -
        -
        -            # Set the strings for the language object.
        -
        -            if (defined $language->ShebangStrings())
        -                {
        -                if ($command eq 'add')
        -                    {  push @shebangStrings, @{$language->ShebangStrings()};  }
        -                elsif (!$command)
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('You need to specify whether you are adding to or replacing the list of shebang '
        -                                                                     . 'strings.', $lineNumber);
        -                    };
        -                };
        -
        -            $language->SetShebangStrings(\@shebangStrings);
        -            }
        -
        -        elsif ($keyword eq 'package separator')
        -            {
        -            if ($fullLanguageSupport)
        -                {
        -                # Prior to 1.32, package separator was used with full language support too.  Accept it without complaining, even though
        -                # we ignore it.
        -                if ($version >= NaturalDocs::Version->FromString('1.32'))
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
        -                    };
        -                }
        -            else
        -                {  $language->SetPackageSeparator($value);  };
        -            }
        -
        -        elsif ($keyword =~ /^(?:(add|replace) )?ignored? (?:(.+) )?prefix(?:es)? in index$/)
        -            {
        -            my ($command, $topicName) = ($1, $2);
        -            my $topicType;
        -
        -            if ($topicName)
        -                {
        -                if (!( ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName) ))
        -                    {
        -                    NaturalDocs::ConfigFile->AddError($topicName . ' is not a defined topic type.', $lineNumber);
        -                    };
        -                }
        -            else
        -                {  $topicType = ::TOPIC_GENERAL();  };
        -
        -            if ($topicType)
        -                {
        -                my @prefixes;
        -
        -                if (defined $language->IgnoredPrefixesFor($topicType))
        -                    {
        -                    if ($command eq 'add')
        -                        {  @prefixes = @{$language->IgnoredPrefixesFor($topicType)};  }
        -                    elsif (!$command)
        -                        {
        -                        NaturalDocs::ConfigFile->AddError('You need to specify whether you are adding to or replacing the list of '
        -                                                                         . 'ignored prefixes.', $lineNumber);
        -                        };
        -                    };
        -
        -                push @prefixes, split(/ /, $value);
        -                $language->SetIgnoredPrefixesFor($topicType, \@prefixes);
        -                };
        -            }
        -
        -        elsif ($keyword eq 'full language support' || $keyword eq 'perl package')
        -            {
        -            if ($languageKeyword eq 'alter language')
        -                {
        -                NaturalDocs::ConfigFile->AddError('You cannot use ' . $keyword . ' with Alter Language.', $lineNumber);
        -                };
        -            # else ignore it.
        -            }
        -
        -        elsif ($keyword =~ /^line comments?$/)
        -            {
        -            if ($fullLanguageSupport)
        -                {
        -                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
        -                }
        -            else
        -                {
        -                my @symbols = split(/ /, $value);
        -                $language->SetLineCommentSymbols(\@symbols);
        -                };
        -            }
        -
        -        elsif ($keyword =~ /^block comments?$/)
        -            {
        -            if ($fullLanguageSupport)
        -                {
        -                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
        -                }
        -            else
        -                {
        -                my @symbols = split(/ /, $value);
        -
        -                if ((scalar @symbols) % 2 == 0)
        -                    {  $language->SetBlockCommentSymbols(\@symbols);  }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Block comment symbols must appear in pairs.', $lineNumber);  };
        -                };
        -            }
        -
        -        elsif ($keyword =~ /^(?:(.+) )?prototype enders?$/)
        -            {
        -            if ($fullLanguageSupport)
        -                {
        -                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
        -                }
        -            else
        -                {
        -                my $topicName = $1;
        -                my $topicType;
        -
        -                if ($topicName)
        -                    {
        -                    if (!( ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName) ))
        -                        {
        -                        NaturalDocs::ConfigFile->AddError($topicName . ' is not a defined topic type.', $lineNumber);
        -                        };
        -                    }
        -                else
        -                    {  $topicType = ::TOPIC_GENERAL();  };
        -
        -                if ($topicType)
        -                    {
        -                    $value =~ s/\\n/\n/g;
        -                    my @symbols = split(/ /, $value);
        -                    $language->SetPrototypeEndersFor($topicType, \@symbols);
        -                    };
        -                };
        -            }
        -
        -        elsif ($keyword eq 'line extender')
        -            {
        -            if ($fullLanguageSupport)
        -                {
        -                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
        -                }
        -            else
        -                {
        -                $language->SetLineExtender($value);
        -                };
        -            }
        -
        -        elsif ($keyword eq 'enum values')
        -            {
        -            if ($fullLanguageSupport)
        -                {
        -                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
        -                }
        -            else
        -                {
        -                $value = lc($value);
        -                my $constant;
        -
        -                if ($value eq 'global')
        -                    {  $constant = ::ENUM_GLOBAL();  }
        -                elsif ($value eq 'under type')
        -                    {  $constant = ::ENUM_UNDER_TYPE();  }
        -                elsif ($value eq 'under parent')
        -                    {  $constant = ::ENUM_UNDER_PARENT();  };
        -
        -                if (defined $constant)
        -                    {  $language->SetEnumValues($constant);  }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Enum Values must be "Global", "Under Type", or "Under Parent".', $lineNumber);
        -                    };
        -                };
        -            }
        -
        -        else
        -            {
        -            NaturalDocs::ConfigFile->AddError($keyword . ' is not a valid keyword.', $lineNumber);
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves the main and user versions of <Languages.txt>.
        -#
        -sub Save
        -    {
        -    my $self = shift;
        -
        -    $self->SaveFile(1); # Main
        -    $self->SaveFile(0); # User
        -    };
        -
        -
        -#
        -#   Function: SaveFile
        -#
        -#   Saves a particular version of <Topics.txt>.
        -#
        -#   Parameters:
        -#
        -#       isMain - Whether the file is the main file or not.
        -#
        -sub SaveFile #(isMain)
        -    {
        -    my ($self, $isMain) = @_;
        -
        -    my $file;
        -
        -    if ($isMain)
        -        {
        -        if (NaturalDocs::Project->MainConfigFileStatus('Languages.txt') == ::FILE_SAME())
        -            {  return;  };
        -        $file = NaturalDocs::Project->MainConfigFile('Languages.txt');
        -        }
        -    else
        -        {
        -        # Have to check the main too because this file lists the languages defined there.
        -        if (NaturalDocs::Project->UserConfigFileStatus('Languages.txt') == ::FILE_SAME() &&
        -            NaturalDocs::Project->MainConfigFileStatus('Languages.txt') == ::FILE_SAME())
        -            {  return;  };
        -        $file = NaturalDocs::Project->UserConfigFile('Languages.txt');
        -        };
        -
        -
        -    # Array of segments, with each being groups of three consecutive entries.  The first is the keyword ('language' or
        -    # 'alter language'), the second is the value, and the third is a hashref of all the properties.
        -    # - For properties that can accept a topic type, the property values are hashrefs mapping topic types to the values.
        -    # - For properties that can accept 'add' or 'replace', there is an additional property ending in 'command' that stores it.
        -    # - For properties that can accept both, the 'command' thing is applied to the topic types rather than the properties.
        -    my @segments;
        -
        -    my @ignoredExtensions;
        -
        -    my $currentProperties;
        -    my $version;
        -
        -    if ($version = NaturalDocs::ConfigFile->Open($file))
        -        {
        -        # We can assume the file is valid.
        -
        -        while (my ($keyword, $value, $comment) = NaturalDocs::ConfigFile->GetLine())
        -            {
        -            $value .= $comment;
        -            $value =~ s/^ //;
        -
        -            if ($keyword eq 'language')
        -                {
        -                $currentProperties = { };
        -
        -                # Case is important with these two.
        -                if (lc($value) eq 'shebang script')
        -                    {  $value = 'Shebang Script';  }
        -                elsif (lc($value) eq 'text file')
        -                    {  $value = 'Text File';  };
        -
        -                push @segments, 'language', $value, $currentProperties;
        -                }
        -
        -            elsif ($keyword eq 'alter language')
        -                {
        -                $currentProperties = { };
        -                push @segments, 'alter language', $languages{lc($value)}->Name(), $currentProperties;
        -                }
        -
        -            elsif ($keyword =~ /^ignored? extensions?$/)
        -                {
        -                $value =~ tr/*.//d;
        -                push @ignoredExtensions, split(/ /, $value);
        -                }
        -
        -            elsif ($keyword eq 'package separator' || $keyword eq 'full language support' || $keyword eq 'perl package' ||
        -                    $keyword eq 'line extender' || $keyword eq 'enum values')
        -                {
        -                $currentProperties->{$keyword} = $value;
        -                }
        -
        -            elsif ($keyword =~ /^line comments?$/)
        -                {
        -                $currentProperties->{'line comments'} = $value;
        -                }
        -            elsif ($keyword =~ /^block comments?$/)
        -                {
        -                $currentProperties->{'block comments'} = $value;
        -                }
        -
        -            elsif ($keyword =~ /^(?:(add|replace) )?extensions?$/)
        -                {
        -                my $command = $1;
        -
        -                if ($command eq 'add' && exists $currentProperties->{'extensions'})
        -                    {  $currentProperties->{'extensions'} .= ' ' . $value;  }
        -                else
        -                    {
        -                    $currentProperties->{'extensions'} = $value;
        -                    $currentProperties->{'extensions command'} = $command;
        -                    };
        -                }
        -
        -            elsif ($keyword =~ /^(?:(add|replace) )?shebang strings?$/)
        -                {
        -                my $command = $1;
        -
        -                if ($command eq 'add' && exists $currentProperties->{'shebang strings'})
        -                    {  $currentProperties->{'shebang strings'} .= ' ' . $value;  }
        -                else
        -                    {
        -                    $currentProperties->{'shebang strings'} = $value;
        -                    $currentProperties->{'shebang strings command'} = $command;
        -                    };
        -                }
        -
        -            elsif ($keyword =~ /^(?:(.+) )?prototype enders?$/)
        -                {
        -                my $topicName = $1;
        -                my $topicType;
        -
        -                if ($topicName)
        -                    {  ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName);  }
        -                else
        -                    {  $topicType = ::TOPIC_GENERAL();  };
        -
        -                my $currentTypeProperties = $currentProperties->{'prototype enders'};
        -
        -                if (!defined $currentTypeProperties)
        -                    {
        -                    $currentTypeProperties = { };
        -                    $currentProperties->{'prototype enders'} = $currentTypeProperties;
        -                    };
        -
        -                $currentTypeProperties->{$topicType} = $value;
        -                }
        -
        -            elsif ($keyword =~ /^(?:(add|replace) )?ignored? (?:(.+) )?prefix(?:es)? in index$/)
        -                {
        -                my ($command, $topicName) = ($1, $2);
        -                my $topicType;
        -
        -                if ($topicName)
        -                    {  ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName);  }
        -                else
        -                    {  $topicType = ::TOPIC_GENERAL();  };
        -
        -                my $currentTypeProperties = $currentProperties->{'ignored prefixes in index'};
        -
        -                if (!defined $currentTypeProperties)
        -                    {
        -                    $currentTypeProperties = { };
        -                    $currentProperties->{'ignored prefixes in index'} = $currentTypeProperties;
        -                    };
        -
        -                if ($command eq 'add' && exists $currentTypeProperties->{$topicType})
        -                    {  $currentTypeProperties->{$topicType} .= ' ' . $value;  }
        -                else
        -                    {
        -                    $currentTypeProperties->{$topicType} = $value;
        -                    $currentTypeProperties->{$topicType . ' command'} = $command;
        -                    };
        -                };
        -            };
        -
        -        NaturalDocs::ConfigFile->Close();
        -        };
        -
        -
        -    if (!open(FH_LANGUAGES, '>' . $file))
        -        {
        -        # The main file may be on a shared volume or some other place the user doesn't have write access to.  Since this is only to
        -        # reformat the file, we can ignore the failure.
        -        if ($isMain)
        -            {  return;  }
        -        else
        -            {  die "Couldn't save " . $file;  };
        -        };
        -
        -    print FH_LANGUAGES 'Format: ' . NaturalDocs::Settings->TextAppVersion() . "\n\n";
        -
        -    # Remember the 80 character limit.
        -
        -    if ($isMain)
        -        {
        -        print FH_LANGUAGES
        -        "# This is the main Natural Docs languages file.  If you change anything here,\n"
        -        . "# it will apply to EVERY PROJECT you use Natural Docs on.  If you'd like to\n"
        -        . "# change something for just one project, edit the Languages.txt in its project\n"
        -        . "# directory instead.\n";
        -        }
        -    else
        -        {
        -        print FH_LANGUAGES
        -        "# This is the Natural Docs languages file for this project.  If you change\n"
        -        . "# anything here, it will apply to THIS PROJECT ONLY.  If you'd like to change\n"
        -        . "# something for all your projects, edit the Languages.txt in Natural Docs'\n"
        -        . "# Config directory instead.\n\n\n";
        -
        -        if (scalar @ignoredExtensions == 1)
        -            {
        -            print FH_LANGUAGES
        -            'Ignore Extension: ' . $ignoredExtensions[0] . "\n";
        -            }
        -        elsif (scalar @ignoredExtensions)
        -            {
        -            print FH_LANGUAGES
        -            'Ignore Extensions: ' . join(' ', @ignoredExtensions) . "\n";
        -            }
        -        else
        -            {
        -            print FH_LANGUAGES
        -            "# You can prevent certain file extensions from being scanned like this:\n"
        -            . "# Ignore Extensions: [extension] [extension] ...\n"
        -            };
        -        };
        -
        -    print FH_LANGUAGES
        -    "\n\n"
        -    . "#-------------------------------------------------------------------------------\n"
        -    . "# SYNTAX:\n"
        -    . "#\n"
        -    . "# Unlike other Natural Docs configuration files, in this file all comments\n"
        -    . "# MUST be alone on a line.  Some languages deal with the # character, so you\n"
        -    . "# cannot put comments on the same line as content.\n"
        -    . "#\n"
        -    . "# Also, all lists are separated with spaces, not commas, again because some\n"
        -    . "# languages may need to use them.\n"
        -    . "#\n";
        -
        -    if ($isMain)
        -        {
        -        print FH_LANGUAGES
        -        "# Language: [name]\n"
        -        . "#    Defines a new language.  Its name can use any characters.\n"
        -        . "#\n";
        -        }
        -    else
        -        {
        -        print FH_LANGUAGES
        -        "# Language: [name]\n"
        -        . "# Alter Language: [name]\n"
        -        . "#    Defines a new language or alters an existing one.  Its name can use any\n"
        -        . "#    characters.  If any of the properties below have an add/replace form, you\n"
        -        . "#    must use that when using Alter Language.\n"
        -        . "#\n";
        -        };
        -
        -    print FH_LANGUAGES
        -    "#    The language Shebang Script is special.  It's entry is only used for\n"
        -    . "#    extensions, and files with those extensions have their shebang (#!) lines\n"
        -    . "#    read to determine the real language of the file.  Extensionless files are\n"
        -    . "#    always treated this way.\n"
        -    . "#\n"
        -    . "#    The language Text File is also special.  It's treated as one big comment\n"
        -    . "#    so you can put Natural Docs content in them without special symbols.  Also,\n"
        -    . "#    if you don't specify a package separator, ignored prefixes, or enum value\n"
        -    . "#    behavior, it will copy those settings from the language that is used most\n"
        -    . "#    in the source tree.\n"
        -    . "#\n"
        -    . "# Extensions: [extension] [extension] ...\n";
        -
        -    if ($isMain)
        -        {
        -        print FH_LANGUAGES
        -        "#    Defines the file extensions of the language's source files.  You can use *\n"
        -        . "#    to mean any undefined extension.\n"
        -        . "#\n"
        -        . "# Shebang Strings: [string] [string] ...\n"
        -        . "#    Defines a list of strings that can appear in the shebang (#!) line to\n"
        -        . "#    designate that it's part of the language.\n"
        -        . "#\n";
        -        }
        -    else
        -        {
        -        print FH_LANGUAGES
        -        "# [Add/Replace] Extensions: [extension] [extension] ...\n"
        -        . "#    Defines the file extensions of the language's source files.  You can\n"
        -        . "#    redefine extensions found in the main languages file.  You can use * to\n"
        -        . "#    mean any undefined extension.\n"
        -        . "#\n"
        -        . "# Shebang Strings: [string] [string] ...\n"
        -        . "# [Add/Replace] Shebang Strings: [string] [string] ...\n"
        -        . "#    Defines a list of strings that can appear in the shebang (#!) line to\n"
        -        . "#    designate that it's part of the language.  You can redefine strings found\n"
        -        . "#    in the main languages file.\n"
        -        . "#\n";
        -        };
        -
        -    print FH_LANGUAGES
        -    "# Ignore Prefixes in Index: [prefix] [prefix] ...\n"
        -    . (!$isMain ? "# [Add/Replace] Ignored Prefixes in Index: [prefix] [prefix] ...\n#\n" : '')
        -    . "# Ignore [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n"
        -    . (!$isMain ? "# [Add/Replace] Ignored [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n" : '')
        -    . "#    Specifies prefixes that should be ignored when sorting symbols in an\n"
        -    . "#    index.  Can be specified in general or for a specific topic type.\n"
        -    . "#\n"
        -    . "#------------------------------------------------------------------------------\n"
        -    . "# For basic language support only:\n"
        -    . "#\n"
        -    . "# Line Comments: [symbol] [symbol] ...\n"
        -    . "#    Defines a space-separated list of symbols that are used for line comments,\n"
        -    . "#    if any.\n"
        -    . "#\n"
        -    . "# Block Comments: [opening sym] [closing sym] [opening sym] [closing sym] ...\n"
        -    . "#    Defines a space-separated list of symbol pairs that are used for block\n"
        -    . "#    comments, if any.\n"
        -    . "#\n"
        -    . "# Package Separator: [symbol]\n"
        -    . "#    Defines the default package separator symbol.  The default is a dot.\n"
        -    . "#\n"
        -    . "# [Topic Type] Prototype Enders: [symbol] [symbol] ...\n"
        -    . "#    When defined, Natural Docs will attempt to get a prototype from the code\n"
        -    . "#    immediately following the topic type.  It stops when it reaches one of\n"
        -    . "#    these symbols.  Use \\n for line breaks.\n"
        -    . "#\n"
        -    . "# Line Extender: [symbol]\n"
        -    . "#    Defines the symbol that allows a prototype to span multiple lines if\n"
        -    . "#    normally a line break would end it.\n"
        -    . "#\n"
        -    . "# Enum Values: [global|under type|under parent]\n"
        -    . "#    Defines how enum values are referenced.  The default is global.\n"
        -    . "#    global       - Values are always global, referenced as 'value'.\n"
        -    . "#    under type   - Values are under the enum type, referenced as\n"
        -    . "#               'package.enum.value'.\n"
        -    . "#    under parent - Values are under the enum's parent, referenced as\n"
        -    . "#               'package.value'.\n"
        -    . "#\n"
        -    . "# Perl Package: [perl package]\n"
        -    . "#    Specifies the Perl package used to fine-tune the language behavior in ways\n"
        -    . "#    too complex to do in this file.\n"
        -    . "#\n"
        -    . "#------------------------------------------------------------------------------\n"
        -    . "# For full language support only:\n"
        -    . "#\n"
        -    . "# Full Language Support: [perl package]\n"
        -    . "#    Specifies the Perl package that has the parsing routines necessary for full\n"
        -    . "#    language support.\n"
        -    . "#\n"
        -    . "#-------------------------------------------------------------------------------\n\n";
        -
        -    if ($isMain)
        -        {
        -        print FH_LANGUAGES
        -        "# The following languages MUST be defined in this file:\n"
        -        . "#\n"
        -        . "#    Text File, Shebang Script\n";
        -        }
        -    else
        -        {
        -        print FH_LANGUAGES
        -        "# The following languages are defined in the main file, if you'd like to alter\n"
        -        . "# them:\n"
        -        . "#\n"
        -        . Text::Wrap::wrap('#    ', '#    ', join(', ', @mainLanguageNames)) . "\n";
        -        };
        -
        -    print FH_LANGUAGES "\n"
        -    . "# If you add a language that you think would be useful to other developers\n"
        -    . "# and should be included in Natural Docs by default, please e-mail it to\n"
        -    . "# languages [at] naturaldocs [dot] org.\n";
        -
        -    my @topicTypeOrder = ( ::TOPIC_GENERAL(), ::TOPIC_CLASS(), ::TOPIC_FUNCTION(), ::TOPIC_VARIABLE(),
        -                                         ::TOPIC_PROPERTY(), ::TOPIC_TYPE(), ::TOPIC_CONSTANT() );
        -
        -    for (my $i = 0; $i < scalar @segments; $i += 3)
        -        {
        -        my ($keyword, $name, $properties) = @segments[$i..$i+2];
        -
        -        print FH_LANGUAGES "\n\n";
        -
        -        if ($keyword eq 'language')
        -            {  print FH_LANGUAGES 'Language: ' . $name . "\n\n";  }
        -        else
        -            {  print FH_LANGUAGES 'Alter Language: ' . $name . "\n\n";  };
        -
        -        if (exists $properties->{'extensions'})
        -            {
        -            print FH_LANGUAGES '   ';
        -
        -            if ($properties->{'extensions command'})
        -                {  print FH_LANGUAGES ucfirst($properties->{'extensions command'}) . ' ';  };
        -
        -            my @extensions = split(/ /, $properties->{'extensions'}, 2);
        -
        -            if (scalar @extensions == 1)
        -                {  print FH_LANGUAGES 'Extension: ';  }
        -            else
        -                {  print FH_LANGUAGES 'Extensions: ';  };
        -
        -            print FH_LANGUAGES lc($properties->{'extensions'}) . "\n";
        -            };
        -
        -        if (exists $properties->{'shebang strings'})
        -            {
        -            print FH_LANGUAGES '   ';
        -
        -            if ($properties->{'shebang strings command'})
        -                {  print FH_LANGUAGES ucfirst($properties->{'shebang strings command'}) . ' ';  };
        -
        -            my @shebangStrings = split(/ /, $properties->{'shebang strings'}, 2);
        -
        -            if (scalar @shebangStrings == 1)
        -                {  print FH_LANGUAGES 'Shebang String: ';  }
        -            else
        -                {  print FH_LANGUAGES 'Shebang Strings: ';  };
        -
        -            print FH_LANGUAGES lc($properties->{'shebang strings'}) . "\n";
        -            };
        -
        -        if (exists $properties->{'ignored prefixes in index'})
        -            {
        -            my $topicTypePrefixes = $properties->{'ignored prefixes in index'};
        -
        -            my %usedTopicTypes;
        -            my @topicTypes = ( @topicTypeOrder, keys %$topicTypePrefixes );
        -
        -            foreach my $topicType (@topicTypes)
        -                {
        -                if ($topicType !~ / command$/ &&
        -                    exists $topicTypePrefixes->{$topicType} &&
        -                    !exists $usedTopicTypes{$topicType})
        -                    {
        -                    print FH_LANGUAGES '   ';
        -
        -                    if ($topicTypePrefixes->{$topicType . ' command'})
        -                        {  print FH_LANGUAGES ucfirst($topicTypePrefixes->{$topicType . ' command'}) . ' Ignored ';  }
        -                    else
        -                        {  print FH_LANGUAGES 'Ignore ';  };
        -
        -                    if ($topicType ne ::TOPIC_GENERAL())
        -                        {  print FH_LANGUAGES NaturalDocs::Topics->TypeInfo($topicType)->Name() . ' ';  };
        -
        -                    my @prefixes = split(/ /, $topicTypePrefixes->{$topicType}, 2);
        -
        -                    if (scalar @prefixes == 1)
        -                        {  print FH_LANGUAGES 'Prefix in Index: ';  }
        -                    else
        -                        {  print FH_LANGUAGES 'Prefixes in Index: ';  };
        -
        -                    print FH_LANGUAGES $topicTypePrefixes->{$topicType} . "\n";
        -
        -                    $usedTopicTypes{$topicType} = 1;
        -                    };
        -                };
        -            };
        -
        -        if (exists $properties->{'line comments'})
        -            {
        -            my @comments = split(/ /, $properties->{'line comments'}, 2);
        -
        -            if (scalar @comments == 1)
        -                {  print FH_LANGUAGES '   Line Comment: ';  }
        -            else
        -                {  print FH_LANGUAGES '   Line Comments: ';  };
        -
        -            print FH_LANGUAGES $properties->{'line comments'} . "\n";
        -            };
        -
        -        if (exists $properties->{'block comments'})
        -            {
        -            my @comments = split(/ /, $properties->{'block comments'}, 3);
        -
        -            if (scalar @comments == 2)
        -                {  print FH_LANGUAGES '   Block Comment: ';  }
        -            else
        -                {  print FH_LANGUAGES '   Block Comments: ';  };
        -
        -            print FH_LANGUAGES $properties->{'block comments'} . "\n";
        -            };
        -
        -        if (exists $properties->{'package separator'})
        -            {
        -            # Prior to 1.32, Package Separator was allowed for full language support.  Ignore it when reformatting.
        -            if ($version >= NaturalDocs::Version->FromString('1.32') || !exists $properties->{'full language support'})
        -                {  print FH_LANGUAGES '   Package Separator: ' . $properties->{'package separator'} . "\n";  };
        -            };
        -
        -        if (exists $properties->{'enum values'})
        -            {
        -            print FH_LANGUAGES '   Enum Values: ' . ucfirst(lc($properties->{'enum values'})) . "\n";
        -            };
        -
        -        if (exists $properties->{'prototype enders'})
        -            {
        -            my $topicTypeEnders = $properties->{'prototype enders'};
        -
        -            my %usedTopicTypes;
        -            my @topicTypes = ( @topicTypeOrder, keys %$topicTypeEnders );
        -
        -            foreach my $topicType (@topicTypes)
        -                {
        -                if ($topicType !~ / command$/ &&
        -                    exists $topicTypeEnders->{$topicType} &&
        -                    !exists $usedTopicTypes{$topicType})
        -                    {
        -                    print FH_LANGUAGES '   ';
        -
        -                    if ($topicType ne ::TOPIC_GENERAL())
        -                        {  print FH_LANGUAGES NaturalDocs::Topics->TypeInfo($topicType)->Name() . ' ';  };
        -
        -                    my @enders = split(/ /, $topicTypeEnders->{$topicType}, 2);
        -
        -                    if (scalar @enders == 1)
        -                        {  print FH_LANGUAGES 'Prototype Ender: ';  }
        -                    else
        -                        {  print FH_LANGUAGES 'Prototype Enders: ';  };
        -
        -                    print FH_LANGUAGES $topicTypeEnders->{$topicType} . "\n";
        -
        -                    $usedTopicTypes{$topicType} = 1;
        -                    };
        -                };
        -            };
        -
        -        if (exists $properties->{'line extender'})
        -            {
        -            print FH_LANGUAGES '   Line Extender: ' . $properties->{'line extender'} . "\n";
        -            };
        -
        -        if (exists $properties->{'perl package'})
        -            {
        -            print FH_LANGUAGES '   Perl Package: ' . $properties->{'perl package'} . "\n";
        -            };
        -
        -        if (exists $properties->{'full language support'})
        -            {
        -            print FH_LANGUAGES '   Full Language Support: ' . $properties->{'full language support'} . "\n";
        -            };
        -        };
        -
        -    close(FH_LANGUAGES);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: LanguageOf
        -#
        -#   Returns the language of the passed source file.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to get the language of.
        -#
        -#   Returns:
        -#
        -#       A <NaturalDocs::Languages::Base>-derived object for the passed file, or undef if the file is not a recognized language.
        -#
        -sub LanguageOf #(sourceFile)
        -    {
        -    my ($self, $sourceFile) = @_;
        -
        -    my $extension = NaturalDocs::File->ExtensionOf($sourceFile);
        -    if (defined $extension)
        -        {  $extension = lc($extension);  };
        -
        -    my $languageName;
        -
        -    if (!defined $extension)
        -        {  $languageName = 'shebang script';  }
        -    else
        -        {  $languageName = $extensions{$extension};  };
        -
        -    if (!defined $languageName)
        -        {  $languageName = $extensions{'*'};  };
        -
        -    if (defined $languageName)
        -        {
        -        if ($languageName eq 'shebang script')
        -            {
        -            if (exists $shebangFiles{$sourceFile})
        -                {
        -                if (defined $shebangFiles{$sourceFile})
        -                    {  return $languages{$shebangFiles{$sourceFile}};  }
        -                else
        -                    {  return undef;  };
        -                }
        -
        -            else # (!exists $shebangFiles{$sourceFile})
        -                {
        -                my $shebangLine;
        -
        -                if (open(SOURCEFILEHANDLE, '<' . $sourceFile))
        -                	{
        -                    my $lineReader = NaturalDocs::LineReader->New(\*SOURCEFILEHANDLE);
        -                    $shebangLine = $lineReader->Get();
        -
        -	                if (substr($shebangLine, 0, 2) ne '#!')
        -	                    {  $shebangLine = undef;  };
        -
        -	                close (SOURCEFILEHANDLE);
        -	                }
        -	            elsif (defined $extension)
        -	            	{  die 'Could not open ' . $sourceFile;  }
        -	            # Ignore extensionless files that can't be opened.  They may be system files.
        -
        -                if (!defined $shebangLine)
        -                    {
        -                    $shebangFiles{$sourceFile} = undef;
        -                    return undef;
        -                    }
        -                else
        -                    {
        -                    $shebangLine = lc($shebangLine);
        -
        -                    foreach my $shebangString (keys %shebangStrings)
        -                        {
        -                        if (index($shebangLine, $shebangString) != -1)
        -                            {
        -                            $shebangFiles{$sourceFile} = $shebangStrings{$shebangString};
        -                            return $languages{$shebangStrings{$shebangString}};
        -                            };
        -                        };
        -
        -                    $shebangFiles{$sourceFile} = undef;
        -                    return undef;
        -                    };
        -                };
        -            }
        -
        -        else # language name ne 'shebang script'
        -            {  return $languages{$languageName};  };
        -        }
        -    else # !defined $language
        -        {
        -        return undef;
        -        };
        -    };
        -
        -
        -#
        -#   Function: OnMostUsedLanguageKnown
        -#
        -#   Called when the most used language is known.
        -#
        -sub OnMostUsedLanguageKnown
        -    {
        -    my $self = shift;
        -
        -    my $language = $languages{lc( NaturalDocs::Project->MostUsedLanguage() )};
        -
        -    if ($language)
        -        {
        -        if (!$languages{'text file'}->HasIgnoredPrefixes())
        -            {  $languages{'text file'}->CopyIgnoredPrefixesOf($language);  };
        -        if (!$languages{'text file'}->PackageSeparatorWasSet())
        -            {  $languages{'text file'}->SetPackageSeparator($language->PackageSeparator());  };
        -        if (!$languages{'text file'}->EnumValuesWasSet())
        -            {  $languages{'text file'}->SetEnumValues($language->EnumValues());  };
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/ActionScript.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/ActionScript.pm
        deleted file mode 100644
        index b24ba9d6e..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/ActionScript.pm
        +++ /dev/null
        @@ -1,1487 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::ActionScript
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of Flash ActionScript.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::ActionScript;
        -
        -use base 'NaturalDocs::Languages::Advanced';
        -
        -
        -################################################################################
        -# Group: Constants and Types
        -
        -
        -#
        -#   Constants: XML Tag Type
        -#
        -#   XML_OPENING_TAG - The tag is an opening one, such as <tag>.
        -#   XML_CLOSING_TAG - The tag is a closing one, such as </tag>.
        -#   XML_SELF_CONTAINED_TAG - The tag is self contained, such as <tag />.
        -#
        -use constant XML_OPENING_TAG => 1;
        -use constant XML_CLOSING_TAG => 2;
        -use constant XML_SELF_CONTAINED_TAG => 3;
        -
        -
        -################################################################################
        -# Group: Package Variables
        -
        -#
        -#   hash: classModifiers
        -#   An existence hash of all the acceptable class modifiers.  The keys are in all lowercase.
        -#
        -my %classModifiers = ( 'dynamic' => 1,
        -                                   'intrinsic' => 1,
        -                                   'final' => 1,
        -                                   'internal' => 1,
        -                                   'public' => 1 );
        -
        -#
        -#   hash: memberModifiers
        -#   An existence hash of all the acceptable class member modifiers.  The keys are in all lowercase.
        -#
        -my %memberModifiers = ( 'public' => 1,
        -                                        'private' => 1,
        -                                        'protected' => 1,
        -                                        'static' => 1,
        -                                        'internal' => 1,
        -                                        'override' => 1 );
        -
        -
        -#
        -#   hash: declarationEnders
        -#   An existence hash of all the tokens that can end a declaration.  This is important because statements don't require a semicolon
        -#   to end.  The keys are in all lowercase.
        -#
        -my %declarationEnders = ( ';' => 1,
        -                                        '}' => 1,
        -                                        '{' => 1,
        -                                        'public' => 1,
        -                                        'private' => 1,
        -                                        'protected' => 1,
        -                                        'static' => 1,
        -                                        'internal' => 1,
        -                                        'dynamic' => 1,
        -                                        'intrinsic' => 1,
        -                                        'final' => 1,
        -                                        'override' => 1,
        -                                        'class' => 1,
        -                                        'interface' => 1,
        -                                        'var' => 1,
        -                                        'function' => 1,
        -                                        'const' => 1,
        -                                        'namespace' => 1,
        -                                        'import' => 1 );
        -
        -
        -#
        -#   var: isEscaped
        -#   Whether the current file being parsed uses escapement.
        -#
        -my $isEscaped;
        -
        -
        -
        -################################################################################
        -# Group: Interface Functions
        -
        -
        -#
        -#   Function: PackageSeparator
        -#   Returns the package separator symbol.
        -#
        -sub PackageSeparator
        -    {  return '.';  };
        -
        -
        -#
        -#   Function: EnumValues
        -#   Returns the <EnumValuesType> that describes how the language handles enums.
        -#
        -sub EnumValues
        -    {  return ::ENUM_GLOBAL();  };
        -
        -
        -#
        -#   Function: ParseParameterLine
        -#   Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
        -#
        -sub ParseParameterLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -
        -    if ($line =~ /^ ?\.\.\.\ (.+)$/)
        -        {
        -        # This puts them in the wrong fields as $1 should be the name and ... should be the type.  However, this is necessary
        -        # because the order in the source is reversed from other parameter declarations and it's more important for the output
        -        # to match the source.
        -        return NaturalDocs::Languages::Prototype::Parameter->New($1, undef, '...', undef, undef, undef);
        -        }
        -    else
        -        {  return $self->ParsePascalParameterLine($line);  };
        -    };
        -
        -
        -#
        -#   Function: TypeBeforeParameter
        -#   Returns whether the type appears before the parameter in prototypes.
        -#
        -sub TypeBeforeParameter
        -    {  return 0;  };
        -
        -
        -#
        -#   Function: PreprocessFile
        -#
        -#   If the file is escaped, strips out all unescaped code.  Will translate any unescaped comments into comments surrounded by
        -#   "\x1C\x1D\x1E\x1F" and "\x1F\x1E\x1D" characters, so chosen because they are the same character lengths as <!-- and -->
        -#   and will not appear in normal code.
        -#
        -sub PreprocessFile
        -    {
        -    my ($self, $lines) = @_;
        -
        -    if (!$isEscaped)
        -        {  return;  };
        -
        -    use constant MODE_UNESCAPED_REGULAR => 1;
        -    use constant MODE_UNESCAPED_PI => 2;
        -    use constant MODE_UNESCAPED_CDATA => 3;
        -    use constant MODE_UNESCAPED_COMMENT => 4;
        -    use constant MODE_ESCAPED_UNKNOWN_CDATA => 5;
        -    use constant MODE_ESCAPED_CDATA => 6;
        -    use constant MODE_ESCAPED_NO_CDATA => 7;
        -
        -    my $mode = MODE_UNESCAPED_REGULAR;
        -
        -    for (my $i = 0; $i < scalar @$lines; $i++)
        -        {
        -        my @tokens = split(/(<[ \t]*\/?[ \t]*mx:Script[^>]*>|<\?|\?>|<\!--|-->|<\!\[CDATA\[|\]\]\>)/, $lines->[$i]);
        -        my $newLine;
        -
        -        foreach my $token (@tokens)
        -            {
        -            if ($mode == MODE_UNESCAPED_REGULAR)
        -                {
        -                if ($token eq '<?')
        -                    {  $mode = MODE_UNESCAPED_PI;  }
        -                elsif ($token eq '<![CDATA[')
        -                    {  $mode = MODE_UNESCAPED_CDATA;  }
        -                elsif ($token eq '<!--')
        -                    {
        -                    $mode = MODE_UNESCAPED_COMMENT;
        -                    $newLine .= "\x1C\x1D\x1E\x1F";
        -                    }
        -                elsif ($token =~ /^<[ \t]*mx:Script/)
        -                    {  $mode = MODE_ESCAPED_UNKNOWN_CDATA;  };
        -                }
        -
        -            elsif ($mode == MODE_UNESCAPED_PI)
        -                {
        -                if ($token eq '?>')
        -                    {  $mode = MODE_UNESCAPED_REGULAR;  };
        -                }
        -
        -            elsif ($mode == MODE_UNESCAPED_CDATA)
        -                {
        -                if ($token eq ']]>')
        -                    {  $mode = MODE_UNESCAPED_REGULAR;  };
        -                }
        -
        -            elsif ($mode == MODE_UNESCAPED_COMMENT)
        -                {
        -                if ($token eq '-->')
        -                    {
        -                    $mode = MODE_UNESCAPED_REGULAR;
        -                    $newLine .= "\x1F\x1E\x1D";
        -                    }
        -                else
        -                    {  $newLine .= $token;  };
        -                }
        -
        -            elsif ($mode == MODE_ESCAPED_UNKNOWN_CDATA)
        -                {
        -                if ($token eq '<![CDATA[')
        -                    {  $mode = MODE_ESCAPED_CDATA;  }
        -                elsif ($token =~ /^<[ \t]*\/[ \t]*mx:Script/)
        -                    {
        -                    $mode = MODE_UNESCAPED_REGULAR;
        -                    $newLine .= '; ';
        -                    }
        -                elsif ($token !~ /^[ \t]*$/)
        -                    {
        -                    $mode = MODE_ESCAPED_NO_CDATA;
        -                    $newLine .= $token;
        -                    };
        -                }
        -
        -            elsif ($mode == MODE_ESCAPED_CDATA)
        -                {
        -                if ($token eq ']]>')
        -                    {
        -                    $mode = MODE_UNESCAPED_REGULAR;
        -                    $newLine .= '; ';
        -                    }
        -                else
        -                    {  $newLine .= $token;  };
        -                }
        -
        -            else #($mode == MODE_ESCAPED_NO_CDATA)
        -                {
        -                if ($token =~ /^<[ \t]*\/[ \t]*mx:Script/)
        -                    {
        -                    $mode = MODE_UNESCAPED_REGULAR;
        -                    $newLine .= '; ';
        -                    }
        -                else
        -                    {  $newLine .= $token;  };
        -                };
        -
        -            };
        -
        -        $lines->[$i] = $newLine;
        -        };
        -    };
        -
        -
        -#
        -#   Function: ParseFile
        -#
        -#   Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The <FileName> to parse.
        -#       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
        -#
        -#   Returns:
        -#
        -#       The array ( autoTopics, scopeRecord ).
        -#
        -#       autoTopics - An arrayref of automatically generated topics from the file, or undef if none.
        -#       scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
        -#
        -sub ParseFile #(sourceFile, topicsList)
        -    {
        -    my ($self, $sourceFile, $topicsList) = @_;
        -
        -    # The \x1# comment symbols are inserted by PreprocessFile() to stand in for XML comments in escaped files.
        -    my @parseParameters = ( [ '//' ], [ '/*', '*/', "\x1C\x1D\x1E\x1F", "\x1F\x1E\x1D" ], [ '///' ], [ '/**', '*/' ] );
        -
        -    my $extension = lc(NaturalDocs::File->ExtensionOf($sourceFile));
        -    $isEscaped = ($extension eq 'mxml');
        -
        -    $self->ParseForCommentsAndTokens($sourceFile, @parseParameters);
        -
        -    my $tokens = $self->Tokens();
        -    my $index = 0;
        -    my $lineNumber = 1;
        -
        -    while ($index < scalar @$tokens)
        -        {
        -        if ($self->TryToSkipWhitespace(\$index, \$lineNumber) ||
        -            $self->TryToGetImport(\$index, \$lineNumber) ||
        -            $self->TryToGetClass(\$index, \$lineNumber) ||
        -            $self->TryToGetFunction(\$index, \$lineNumber) ||
        -            $self->TryToGetVariable(\$index, \$lineNumber) )
        -            {
        -            # The functions above will handle everything.
        -            }
        -
        -        elsif ($tokens->[$index] eq '{')
        -            {
        -            $self->StartScope('}', $lineNumber, undef, undef, undef);
        -            $index++;
        -            }
        -
        -        elsif ($tokens->[$index] eq '}')
        -            {
        -            if ($self->ClosingScopeSymbol() eq '}')
        -                {  $self->EndScope($lineNumber);  };
        -
        -            $index++;
        -            }
        -
        -        else
        -            {
        -            $self->SkipToNextStatement(\$index, \$lineNumber);
        -            };
        -        };
        -
        -
        -    # Don't need to keep these around.
        -    $self->ClearTokens();
        -
        -
        -    my $autoTopics = $self->AutoTopics();
        -
        -    my $scopeRecord = $self->ScopeRecord();
        -    if (defined $scopeRecord && !scalar @$scopeRecord)
        -        {  $scopeRecord = undef;  };
        -
        -    return ( $autoTopics, $scopeRecord );
        -    };
        -
        -
        -
        -################################################################################
        -# Group: Statement Parsing Functions
        -# All functions here assume that the current position is at the beginning of a statement.
        -#
        -# Note for developers: I am well aware that the code in these functions do not check if we're past the end of the tokens as
        -# often as it should.  We're making use of the fact that Perl will always return undef in these cases to keep the code simpler.
        -
        -
        -#
        -#   Function: TryToGetIdentifier
        -#
        -#   Determines whether the position is at an identifier, and if so, skips it and returns the complete identifier as a string.  Returns
        -#   undef otherwise.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the current token index.
        -#       lineNumberRef - A reference to the current line number.
        -#       allowStar - If set, allows the last identifier to be a star.
        -#
        -sub TryToGetIdentifier #(indexRef, lineNumberRef, allowStar)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $allowStar) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -
        -    use constant MODE_IDENTIFIER_START => 1;
        -    use constant MODE_IN_IDENTIFIER => 2;
        -    use constant MODE_AFTER_STAR => 3;
        -
        -    my $identifier;
        -    my $mode = MODE_IDENTIFIER_START;
        -
        -    while ($index < scalar @$tokens)
        -        {
        -        if ($mode == MODE_IDENTIFIER_START)
        -            {
        -            if ($tokens->[$index] =~ /^[a-z\$\_]/i)
        -                {
        -                $identifier .= $tokens->[$index];
        -                $index++;
        -
        -                $mode = MODE_IN_IDENTIFIER;
        -                }
        -            elsif ($allowStar && $tokens->[$index] eq '*')
        -                {
        -                $identifier .= '*';
        -                $index++;
        -
        -                $mode = MODE_AFTER_STAR;
        -                }
        -            else
        -                {  return undef;  };
        -            }
        -
        -        elsif ($mode == MODE_IN_IDENTIFIER)
        -            {
        -            if ($tokens->[$index] eq '.')
        -                {
        -                $identifier .= '.';
        -                $index++;
        -
        -                $mode = MODE_IDENTIFIER_START;
        -                }
        -            elsif ($tokens->[$index] =~ /^[a-z0-9\$\_]/i)
        -                {
        -                $identifier .= $tokens->[$index];
        -                $index++;
        -                }
        -            else
        -                {  last;  };
        -            }
        -
        -        else #($mode == MODE_AFTER_STAR)
        -            {
        -            if ($tokens->[$index] =~ /^[a-z0-9\$\_\.]/i)
        -                {  return undef;  }
        -            else
        -                {  last;  };
        -            };
        -        };
        -
        -    # We need to check again because we may have run out of tokens after a dot.
        -    if ($mode != MODE_IDENTIFIER_START)
        -        {
        -        $$indexRef = $index;
        -        return $identifier;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToGetImport
        -#
        -#   Determines whether the position is at a import statement, and if so, adds it as a Using statement to the current scope, skips
        -#   it, and returns true.
        -#
        -sub TryToGetImport #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if ($tokens->[$index] ne 'import')
        -        {  return undef;  };
        -
        -    $index++;
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my $identifier = $self->TryToGetIdentifier(\$index, \$lineNumber, 1);
        -    if (!$identifier)
        -        {  return undef;  };
        -
        -
        -    # Currently we implement importing by stripping the last package level and treating it as a using.  So "import p1.p2.p3" makes
        -    # p1.p2 the using path, which is over-tolerant but that's okay.  "import p1.p2.*" is treated the same way, but in this case it's
        -    # not over-tolerant.  If there's no dot, there's no point to including it.
        -
        -    if (index($identifier, '.') != -1)
        -        {
        -        $identifier =~ s/\.[^\.]+$//;
        -        $self->AddUsing( NaturalDocs::SymbolString->FromText($identifier) );
        -        };
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetClass
        -#
        -#   Determines whether the position is at a class declaration statement, and if so, generates a topic for it, skips it, and
        -#   returns true.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Classes
        -#       - Interfaces
        -#       - Classes and interfaces with _global
        -#
        -sub TryToGetClass #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    my @modifiers;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i &&
        -              exists $classModifiers{lc($tokens->[$index])} )
        -        {
        -        push @modifiers, lc($tokens->[$index]);
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -    my $type;
        -
        -    if ($tokens->[$index] eq 'class' || $tokens->[$index] eq 'interface')
        -        {
        -        $type = $tokens->[$index];
        -
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        }
        -    else
        -        {  return undef;  };
        -
        -    my $className = $self->TryToGetIdentifier(\$index, \$lineNumber);
        -
        -    if (!$className)
        -        {  return undef;  };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my @parents;
        -
        -    if ($tokens->[$index] eq 'extends')
        -        {
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        # Interfaces can extend multiple other interfaces, which is NOT clearly mentioned in the docs.
        -
        -        for (;;)
        -        	{
        -	        my $parent = $self->TryToGetIdentifier(\$index, \$lineNumber);
        -	        if (!$parent)
        -	            {  return undef;  };
        -
        -	        push @parents, $parent;
        -
        -	        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -            if ($tokens->[$index] ne ',')
        -                {  last;  }
        -            else
        -                {
        -                $index++;
        -                $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -                };
        -	        }
        -        };
        -
        -    if ($type eq 'class' && $tokens->[$index] eq 'implements')
        -        {
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        for (;;)
        -            {
        -            my $parent = $self->TryToGetIdentifier(\$index, \$lineNumber);
        -            if (!$parent)
        -                {  return undef;  };
        -
        -            push @parents, $parent;
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -            if ($tokens->[$index] ne ',')
        -                {  last;  }
        -            else
        -                {
        -                $index++;
        -                $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -                };
        -            };
        -        };
        -
        -    if ($tokens->[$index] ne '{')
        -        {  return undef;  };
        -
        -    $index++;
        -
        -
        -    # If we made it this far, we have a valid class declaration.
        -
        -    my $topicType;
        -
        -    if ($type eq 'interface')
        -        {  $topicType = ::TOPIC_INTERFACE();  }
        -    else
        -        {  $topicType = ::TOPIC_CLASS();  };
        -
        -    $className =~ s/^_global.//;
        -
        -    my $autoTopic = NaturalDocs::Parser::ParsedTopic->New($topicType, $className,
        -                                                                                         undef, $self->CurrentUsing(),
        -                                                                                         undef,
        -                                                                                         undef, undef, $$lineNumberRef);
        -
        -    $self->AddAutoTopic($autoTopic);
        -    NaturalDocs::Parser->OnClass($autoTopic->Package());
        -
        -    foreach my $parent (@parents)
        -        {
        -        NaturalDocs::Parser->OnClassParent($autoTopic->Package(), NaturalDocs::SymbolString->FromText($parent),
        -                                                               undef, $self->CurrentUsing(), ::RESOLVE_ABSOLUTE());
        -        };
        -
        -    $self->StartScope('}', $lineNumber, $autoTopic->Package());
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetFunction
        -#
        -#   Determines if the position is on a function declaration, and if so, generates a topic for it, skips it, and returns true.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Functions
        -#       - Constructors
        -#       - Properties
        -#       - Functions with _global
        -#       - Functions with namespaces
        -#
        -sub TryToGetFunction #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -
        -    my @modifiers;
        -    my $namespace;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i)
        -        {
        -        if ($tokens->[$index] eq 'function')
        -            {  last;  }
        -
        -        elsif (exists $memberModifiers{lc($tokens->[$index])})
        -            {
        -            push @modifiers, lc($tokens->[$index]);
        -            $index++;
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            }
        -
        -        elsif (!$namespace)
        -            {
        -            do
        -                {
        -                $namespace .= $tokens->[$index];
        -                $index++;
        -                }
        -            while ($tokens->[$index] =~ /^[a-z0-9_]/i);
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            }
        -
        -        else
        -            {  last;  };
        -        };
        -
        -    if ($tokens->[$index] ne 'function')
        -        {  return undef;  };
        -    $index++;
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my $type;
        -
        -    if ($tokens->[$index] eq 'get' || $tokens->[$index] eq 'set')
        -        {
        -        # This can either be a property ("function get Something()") or a function name ("function get()").
        -
        -        my $nextIndex = $index;
        -        my $nextLineNumber = $lineNumber;
        -
        -        $nextIndex++;
        -        $self->TryToSkipWhitespace(\$nextIndex, \$nextLineNumber);
        -
        -        if ($tokens->[$nextIndex] eq '(')
        -            {
        -            $type = ::TOPIC_FUNCTION();
        -            # Ignore the movement and let the code ahead pick it up as the name.
        -            }
        -        else
        -            {
        -            $type = ::TOPIC_PROPERTY();
        -            $index = $nextIndex;
        -            $lineNumber = $nextLineNumber;
        -            };
        -        }
        -    else
        -        {  $type = ::TOPIC_FUNCTION();  };
        -
        -    my $name = $self->TryToGetIdentifier(\$index, \$lineNumber);
        -    if (!$name)
        -        {  return undef;  };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    if ($tokens->[$index] ne '(')
        -        {  return undef;  };
        -
        -    $index++;
        -    $self->GenericSkipUntilAfter(\$index, \$lineNumber, ')');
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    if ($tokens->[$index] eq ':')
        -        {
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        $self->TryToGetIdentifier(\$index, \$lineNumber, 1);
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -
        -    my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
        -
        -    if ($tokens->[$index] eq '{')
        -        {  $self->GenericSkip(\$index, \$lineNumber);  }
        -    elsif (!exists $declarationEnders{$tokens->[$index]})
        -        {  return undef;  };
        -
        -
        -    my $scope = $self->CurrentScope();
        -
        -    if ($name =~ s/^_global.//)
        -        {  $scope = undef;  };
        -    if ($namespace)
        -        {  $scope = NaturalDocs::SymbolString->Join($scope, $namespace);  };
        -
        -    $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($type, $name,
        -                                                                                              $scope, $self->CurrentUsing(),
        -                                                                                              $prototype,
        -                                                                                              undef, undef, $startLine));
        -
        -
        -    # We succeeded if we got this far.
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetVariable
        -#
        -#   Determines if the position is on a variable declaration statement, and if so, generates a topic for each variable, skips the
        -#   statement, and returns true.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Variables
        -#       - Variables with _global
        -#       - Variables with type * (untyped)
        -#       - Constants
        -#       - Variables and constants with namespaces
        -#
        -sub TryToGetVariable #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -
        -    my @modifiers;
        -    my $namespace;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i)
        -        {
        -        if ($tokens->[$index] eq 'var' || $tokens->[$index] eq 'const')
        -            {  last;  }
        -
        -        elsif (exists $memberModifiers{lc($tokens->[$index])})
        -            {
        -            push @modifiers, lc($tokens->[$index]);
        -            $index++;
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            }
        -
        -        elsif (!$namespace)
        -            {
        -            do
        -                {
        -                $namespace .= $tokens->[$index];
        -                $index++;
        -                }
        -            while ($tokens->[$index] =~ /^[a-z0-9_]/i);
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            }
        -
        -        else
        -            {  last;  };
        -        };
        -
        -    my $type;
        -
        -    if ($tokens->[$index] eq 'var')
        -        {  $type = ::TOPIC_VARIABLE();  }
        -    elsif ($tokens->[$index] eq 'const')
        -        {  $type = ::TOPIC_CONSTANT();  }
        -    else
        -        {  return undef;  };
        -    $index++;
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my $endTypeIndex = $index;
        -    my @names;
        -    my @types;
        -
        -    for (;;)
        -        {
        -        my $name = $self->TryToGetIdentifier(\$index, \$lineNumber);
        -        if (!$name)
        -            {  return undef;  };
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        my $type;
        -
        -        if ($tokens->[$index] eq ':')
        -            {
        -            $index++;
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -            $type = ': ' . $self->TryToGetIdentifier(\$index, \$lineNumber, 1);
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            };
        -
        -        if ($tokens->[$index] eq '=')
        -            {
        -            do
        -                {
        -                $self->GenericSkip(\$index, \$lineNumber);
        -                }
        -            while ($tokens->[$index] ne ',' && !exists $declarationEnders{$tokens->[$index]} && $index < scalar @$tokens);
        -            };
        -
        -        push @names, $name;
        -        push @types, $type;
        -
        -        if ($tokens->[$index] eq ',')
        -            {
        -            $index++;
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            }
        -        elsif (exists $declarationEnders{$tokens->[$index]})
        -            {  last;  }
        -        else
        -            {  return undef;  };
        -        };
        -
        -
        -    # We succeeded if we got this far.
        -
        -    my $prototypePrefix = $self->CreateString($startIndex, $endTypeIndex);
        -
        -    for (my $i = 0; $i < scalar @names; $i++)
        -        {
        -        my $prototype = $self->NormalizePrototype( $prototypePrefix . ' ' . $names[$i] . $types[$i]);
        -        my $scope = $self->CurrentScope();
        -
        -        if ($names[$i] =~ s/^_global.//)
        -            {  $scope = undef;  };
        -        if ($namespace)
        -            {  $scope = NaturalDocs::SymbolString->Join($scope, $namespace);  };
        -
        -        $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($type, $names[$i],
        -                                                                                                  $scope, $self->CurrentUsing(),
        -                                                                                                  $prototype,
        -                                                                                                  undef, undef, $startLine));
        -        };
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -
        -################################################################################
        -# Group: Low Level Parsing Functions
        -
        -
        -#
        -#   Function: GenericSkip
        -#
        -#   Advances the position one place through general code.
        -#
        -#   - If the position is on a string, it will skip it completely.
        -#   - If the position is on an opening symbol, it will skip until the past the closing symbol.
        -#   - If the position is on whitespace (including comments), it will skip it completely.
        -#   - Otherwise it skips one token.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the current index.
        -#       lineNumberRef - A reference to the current line number.
        -#
        -sub GenericSkip #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # We can ignore the scope stack because we're just skipping everything without parsing, and we need recursion anyway.
        -    if ($tokens->[$$indexRef] eq '{')
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
        -        }
        -    elsif ($tokens->[$$indexRef] eq '(')
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ')');
        -        }
        -    elsif ($tokens->[$$indexRef] eq '[')
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
        -        }
        -
        -    elsif ($self->TryToSkipWhitespace($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipString($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipRegExp($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipXML($indexRef, $lineNumberRef) )
        -        {
        -        }
        -
        -    else
        -        {  $$indexRef++;  };
        -    };
        -
        -
        -#
        -#   Function: GenericSkipUntilAfter
        -#
        -#   Advances the position via <GenericSkip()> until a specific token is reached and passed.
        -#
        -sub GenericSkipUntilAfter #(indexRef, lineNumberRef, token)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $token) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne $token)
        -        {  $self->GenericSkip($indexRef, $lineNumberRef);  };
        -
        -    if ($tokens->[$$indexRef] eq "\n")
        -        {  $$lineNumberRef++;  };
        -    $$indexRef++;
        -    };
        -
        -
        -#
        -#   Function: IndiscriminateSkipUntilAfterSequence
        -#
        -#   Advances the position indiscriminately until a specific token sequence is reached and passed.
        -#
        -sub IndiscriminateSkipUntilAfterSequence #(indexRef, lineNumberRef, token, token, ...)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, @sequence) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens && !$self->IsAtSequence($$indexRef, @sequence))
        -        {
        -        if ($tokens->[$$indexRef] eq "\n")
        -            {  $$lineNumberRef++;  };
        -        $$indexRef++;
        -        };
        -
        -    if ($self->IsAtSequence($$indexRef, @sequence))
        -        {
        -        $$indexRef += scalar @sequence;
        -        foreach my $token (@sequence)
        -            {
        -            if ($token eq "\n")
        -                {  $$lineNumberRef++;  };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: SkipToNextStatement
        -#
        -#   Advances the position via <GenericSkip()> until the next statement, which is defined as anything in <declarationEnders> not
        -#   appearing in brackets or strings.  It will always advance at least one token.
        -#
        -sub SkipToNextStatement #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq ';')
        -        {  $$indexRef++;  }
        -
        -    else
        -        {
        -        do
        -            {
        -            $self->GenericSkip($indexRef, $lineNumberRef);
        -            }
        -        while ( $$indexRef < scalar @$tokens &&
        -                  !exists $declarationEnders{$tokens->[$$indexRef]} );
        -        };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipRegExp
        -#   If the current position is on a regular expression, skip past it and return true.
        -#
        -sub TryToSkipRegExp #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '/')
        -        {
        -        # A slash can either start a regular expression or be a divide symbol.  Skip backwards to see what the previous symbol is.
        -        my $index = $$indexRef - 1;
        -
        -        while ($index >= 0 && $tokens->[$index] =~ /^(?: |\t|\n)/)
        -            {  $index--;  };
        -
        -        if ($index < 0 || $tokens->[$index] !~ /^[\:\=\(\[\,]/)
        -            {  return 0;  };
        -
        -        $$indexRef++;
        -
        -        while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne '/')
        -            {
        -            if ($tokens->[$$indexRef] eq '\\')
        -                {  $$indexRef += 2;  }
        -            elsif ($tokens->[$$indexRef] eq "\n")
        -                {
        -                $$indexRef++;
        -                $$lineNumberRef++;
        -                }
        -            else
        -                {  $$indexRef++;  }
        -            };
        -
        -        if ($$indexRef < scalar @$tokens)
        -            {
        -            $$indexRef++;
        -
        -            if ($tokens->[$$indexRef] =~ /^[gimsx]+$/i)
        -                {  $$indexRef++;  };
        -            };
        -
        -        return 1;
        -        }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipXML
        -#   If the current position is on an XML literal, skip past it and return true.
        -#
        -sub TryToSkipXML #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '<')
        -        {
        -        # A < can either start an XML literal or be a comparison or shift operator.  First check the next character for << or <=.
        -
        -        my $index = $$indexRef + 1;
        -
        -        while ($index < scalar @$tokens && $tokens->[$index] =~ /^[\=\<]$/)
        -            {  return 0;  };
        -
        -
        -        # Next try the previous character.
        -
        -        $index = $$indexRef - 1;
        -
        -        while ($index >= 0 && $tokens->[$index] =~ /^[ |\t|\n]/)
        -            {  $index--;  };
        -
        -        if ($index < 0 || $tokens->[$index] !~ /^[\=\(\[\,\>]/)
        -            {  return 0;  };
        -        }
        -    else
        -        {  return 0;  };
        -
        -
        -    # Only handle the tag here if it's not an irregular XML section.
        -    if (!$self->TryToSkipIrregularXML($indexRef, $lineNumberRef))
        -        {
        -        my @tagStack;
        -
        -        my ($tagType, $tagIdentifier) = $self->GetAndSkipXMLTag($indexRef, $lineNumberRef);
        -        if ($tagType == XML_OPENING_TAG)
        -            {  push @tagStack, $tagIdentifier;  };
        -
        -        while (scalar @tagStack && $$indexRef < scalar @$tokens)
        -            {
        -            $self->SkipToNextXMLTag($indexRef, $lineNumberRef);
        -            ($tagType, $tagIdentifier) = $self->GetAndSkipXMLTag($indexRef, $lineNumberRef);
        -
        -            if ($tagType == XML_OPENING_TAG)
        -                {  push @tagStack, $tagIdentifier;  }
        -            elsif ($tagType == XML_CLOSING_TAG && $tagIdentifier eq $tagStack[-1])
        -                {  pop @tagStack;  };
        -            };
        -        };
        -
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToSkipIrregularXML
        -#
        -#   If the current position is on an irregular XML tag, skip past it and return true.  Irregular XML tags are defined as
        -#
        -#       CDATA - <![CDATA[ ... ]]>
        -#       Comments - <!-- ... -->
        -#       PI - <? ... ?>
        -#
        -sub TryToSkipIrregularXML #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -
        -    if ($self->IsAtSequence($$indexRef, '<', '!', '[', 'CDATA', '['))
        -        {
        -        $$indexRef += 5;
        -        $self->IndiscriminateSkipUntilAfterSequence($indexRef, $lineNumberRef, ']', ']', '>');
        -        return 1;
        -        }
        -
        -    elsif ($self->IsAtSequence($$indexRef, '<', '!', '-', '-'))
        -        {
        -        $$indexRef += 4;
        -        $self->IndiscriminateSkipUntilAfterSequence($indexRef, $lineNumberRef, '-', '-', '>');
        -        return 1;
        -        }
        -
        -    elsif ($self->IsAtSequence($$indexRef, '<', '?'))
        -        {
        -        $$indexRef += 2;
        -        $self->IndiscriminateSkipUntilAfterSequence($indexRef, $lineNumberRef, '?', '>');
        -        return 1;
        -        }
        -
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: GetAndSkipXMLTag
        -#
        -#   Processes the XML tag at the current position, moves beyond it, and returns information about it.  Assumes the position is on
        -#   the opening angle bracket of the tag and the tag is a normal XML tag, not one of the ones handled by
        -#   <TryToSkipIrregularXML()>.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the index of the position of the opening angle bracket.
        -#       lineNumberRef - A reference to the line number of the position of the opening angle bracket.
        -#
        -#   Returns:
        -#
        -#       The array ( tagType, name ).
        -#
        -#       tagType - One of the <XML Tag Type> constants.
        -#       identifier - The identifier of the tag.  If it's an empty tag (<> or </>), this will be "(anonymous)".
        -#
        -sub GetAndSkipXMLTag #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne '<')
        -        {  die "Tried to call GetXMLTag when the position isn't on an opening bracket.";  };
        -
        -    # Get the anonymous ones out of the way so we don't have to worry about them below, since they're rather exceptional.
        -
        -    if ($self->IsAtSequence($$indexRef, '<', '>'))
        -        {
        -        $$indexRef += 2;
        -        return ( XML_OPENING_TAG, '(anonymous)' );
        -        }
        -    elsif ($self->IsAtSequence($$indexRef, '<', '/', '>'))
        -        {
        -        $$indexRef += 3;
        -        return ( XML_CLOSING_TAG, '(anonymous)' );
        -        };
        -
        -
        -    # Grab the identifier.
        -
        -    my $tagType = XML_OPENING_TAG;
        -    my $identifier;
        -
        -    $$indexRef++;
        -
        -    if ($tokens->[$$indexRef] eq '/')
        -        {
        -        $$indexRef++;
        -        $tagType = XML_CLOSING_TAG;
        -        };
        -
        -    $self->TryToSkipXMLWhitespace($indexRef, $lineNumberRef);
        -
        -
        -    # The identifier could be a native expression in braces.
        -
        -    if ($tokens->[$$indexRef] eq '{')
        -        {
        -        my $startOfIdentifier = $$indexRef;
        -
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
        -
        -        $identifier = $self->CreateString($startOfIdentifier, $$indexRef);
        -        }
        -
        -
        -    # Otherwise just grab content until whitespace or the end of the tag.
        -
        -    else
        -        {
        -        while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] !~ /^[\/\>\ \t]$/)
        -            {
        -            $identifier .= $tokens->[$$indexRef];
        -            $$indexRef++;
        -            };
        -        };
        -
        -
        -    # Skip to the end of the tag.
        -
        -    while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] !~ /^[\/\>]$/)
        -        {
        -        if ($tokens->[$$indexRef] eq '{')
        -            {
        -            $$indexRef++;
        -            $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
        -            }
        -
        -        elsif ($self->TryToSkipXMLWhitespace($indexRef, $lineNumberRef))
        -            {  }
        -
        -        # We don't need to do special handling for attribute quotes or anything like that because there's no backslashing in
        -        # XML.  It's all handled with entity characters.
        -        else
        -            {  $$indexRef++;  };
        -        };
        -
        -
        -    if ($tokens->[$$indexRef] eq '/')
        -        {
        -        if ($tagType == XML_OPENING_TAG)
        -            {  $tagType = XML_SELF_CONTAINED_TAG;  };
        -
        -        $$indexRef++;
        -        };
        -
        -    if ($tokens->[$$indexRef] eq '>')
        -        {  $$indexRef++;  };
        -
        -    if (!$identifier)
        -        {  $identifier = '(anonymous)';  };
        -
        -
        -    return ( $tagType, $identifier );
        -    };
        -
        -
        -#
        -#   Function: SkipToNextXMLTag
        -#   Skips to the next normal XML tag.  It will not stop at elements handled by <TryToSkipIrregularXML()>.  Note that if the
        -#   position is already at an XML tag, it will not move.
        -#
        -sub SkipToNextXMLTag #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens)
        -        {
        -        if ($tokens->[$$indexRef] eq '{')
        -            {
        -            $$indexRef++;
        -            $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
        -            }
        -
        -        elsif ($self->TryToSkipIrregularXML($indexRef, $lineNumberRef))
        -            {  }
        -
        -        elsif ($tokens->[$$indexRef] eq '<')
        -            {  last;  }
        -
        -        else
        -            {
        -            if ($tokens->[$$indexRef] eq "\n")
        -                {  $$lineNumberRef++;  };
        -
        -            $$indexRef++;
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipXMLWhitespace
        -#   If the current position is on XML whitespace, skip past it and return true.
        -#
        -sub TryToSkipXMLWhitespace #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $result;
        -
        -    while ($$indexRef < scalar @$tokens)
        -        {
        -        if ($tokens->[$$indexRef] =~ /^[ \t]/)
        -            {
        -            $$indexRef++;
        -            $result = 1;
        -            }
        -        elsif ($tokens->[$$indexRef] eq "\n")
        -            {
        -            $$indexRef++;
        -            $$lineNumberRef++;
        -            $result = 1;
        -            }
        -        else
        -            {  last;  };
        -        };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: TryToSkipString
        -#   If the current position is on a string delimiter, skip past the string and return true.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the index of the position to start at.
        -#       lineNumberRef - A reference to the line number of the position.
        -#
        -#   Returns:
        -#
        -#       Whether the position was at a string.
        -#
        -#   Syntax Support:
        -#
        -#       - Supports quotes and apostrophes.
        -#
        -sub TryToSkipString #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -
        -    return ($self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '\'') ||
        -               $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '"') );
        -    };
        -
        -
        -#
        -#   Function: TryToSkipWhitespace
        -#   If the current position is on a whitespace token, a line break token, or a comment, it skips them and returns true.  If there are
        -#   a number of these in a row, it skips them all.
        -#
        -sub TryToSkipWhitespace #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $result;
        -
        -    while ($$indexRef < scalar @$tokens)
        -        {
        -        if ($tokens->[$$indexRef] =~ /^[ \t]/)
        -            {
        -            $$indexRef++;
        -            $result = 1;
        -            }
        -        elsif ($tokens->[$$indexRef] eq "\n")
        -            {
        -            $$indexRef++;
        -            $$lineNumberRef++;
        -            $result = 1;
        -            }
        -        elsif ($self->TryToSkipComment($indexRef, $lineNumberRef))
        -            {
        -            $result = 1;
        -            }
        -        else
        -            {  last;  };
        -        };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: TryToSkipComment
        -#   If the current position is on a comment, skip past it and return true.
        -#
        -sub TryToSkipComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -
        -    return ( $self->TryToSkipLineComment($indexRef, $lineNumberRef) ||
        -                $self->TryToSkipMultilineComment($indexRef, $lineNumberRef) );
        -    };
        -
        -
        -#
        -#   Function: TryToSkipLineComment
        -#   If the current position is on a line comment symbol, skip past it and return true.
        -#
        -sub TryToSkipLineComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '/')
        -        {
        -        $self->SkipRestOfLine($indexRef, $lineNumberRef);
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipMultilineComment
        -#   If the current position is on an opening comment symbol, skip past it and return true.
        -#
        -sub TryToSkipMultilineComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '*')
        -        {
        -        $self->SkipUntilAfter($indexRef, $lineNumberRef, '*', '/');
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Ada.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Ada.pm
        deleted file mode 100644
        index 062c5ae97..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Ada.pm
        +++ /dev/null
        @@ -1,39 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Ada
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of Ada
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Ada;
        -
        -use base 'NaturalDocs::Languages::Simple';
        -
        -
        -#
        -#   Function: ParseParameterLine
        -#   Overridden because Ada uses Pascal-style parameters
        -#
        -sub ParseParameterLine #(...)
        -    {
        -    my ($self, @params) = @_;
        -    return $self->SUPER::ParsePascalParameterLine(@params);
        -    };
        -
        -sub TypeBeforeParameter
        -    {
        -    return 0;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced.pm
        deleted file mode 100644
        index d6cafa7eb..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced.pm
        +++ /dev/null
        @@ -1,817 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Advanced
        -#
        -###############################################################################
        -#
        -#   The base class for all languages that have full support in Natural Docs.  Each one will have a custom parser capable
        -#   of documenting undocumented aspects of the code.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -use NaturalDocs::Languages::Advanced::Scope;
        -use NaturalDocs::Languages::Advanced::ScopeChange;
        -
        -package NaturalDocs::Languages::Advanced;
        -
        -use base 'NaturalDocs::Languages::Base';
        -
        -
        -#############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are used as indexes.
        -#
        -#   TOKENS - An arrayref of tokens used in all the <Parsing Functions>.
        -#   SCOPE_STACK - An arrayref of <NaturalDocs::Languages::Advanced::Scope> objects serving as a scope stack for parsing.
        -#                            There will always be one available, with a symbol of undef, for the top level.
        -#   SCOPE_RECORD - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChange> objects, as generated by the scope
        -#                              stack.  If there is more than one change per line, only the last is stored.
        -#   AUTO_TOPICS - An arrayref of <NaturalDocs::Parser::ParsedTopics> generated automatically from the code.
        -#
        -use NaturalDocs::DefineMembers 'TOKENS', 'SCOPE_STACK', 'SCOPE_RECORD', 'AUTO_TOPICS';
        -
        -
        -#############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       name - The name of the language.
        -#
        -sub New #(name)
        -    {
        -    my ($package, @parameters) = @_;
        -
        -    my $object = $package->SUPER::New(@parameters);
        -    $object->[TOKENS] = undef;
        -    $object->[SCOPE_STACK] = undef;
        -    $object->[SCOPE_RECORD] = undef;
        -
        -    return $object;
        -    };
        -
        -
        -# Function: Tokens
        -# Returns the tokens found by <ParseForCommentsAndTokens()>.
        -sub Tokens
        -    {  return $_[0]->[TOKENS];  };
        -
        -# Function: SetTokens
        -# Replaces the tokens.
        -sub SetTokens #(tokens)
        -    {  $_[0]->[TOKENS] = $_[1];  };
        -
        -# Function: ClearTokens
        -#  Resets the token list.  You may want to do this after parsing is over to save memory.
        -sub ClearTokens
        -    {  $_[0]->[TOKENS] = undef;  };
        -
        -# Function: AutoTopics
        -# Returns the arrayref of automatically generated topics, or undef if none.
        -sub AutoTopics
        -    {  return $_[0]->[AUTO_TOPICS];  };
        -
        -# Function: AddAutoTopic
        -# Adds a <NaturalDocs::Parser::ParsedTopic> to <AutoTopics()>.
        -sub AddAutoTopic #(topic)
        -    {
        -    my ($self, $topic) = @_;
        -    if (!defined $self->[AUTO_TOPICS])
        -        {  $self->[AUTO_TOPICS] = [ ];  };
        -    push @{$self->[AUTO_TOPICS]}, $topic;
        -    };
        -
        -# Function: ClearAutoTopics
        -# Resets the automatic topic list.  Not necessary if you call <ParseForCommentsAndTokens()>.
        -sub ClearAutoTopics
        -    {  $_[0]->[AUTO_TOPICS] = undef;  };
        -
        -# Function: ScopeRecord
        -# Returns an arrayref of <NaturalDocs::Languages::Advanced::ScopeChange> objects describing how and when the scope
        -# changed thoughout the file.  There will always be at least one entry, which will be for line 1 and undef as the scope.
        -sub ScopeRecord
        -    {  return $_[0]->[SCOPE_RECORD];  };
        -
        -
        -
        -###############################################################################
        -#
        -#   Group: Parsing Functions
        -#
        -#   These functions are good general language building blocks.  Use them to create your language-specific parser.
        -#
        -#   All functions work on <Tokens()> and assume it is set by <ParseForCommentsAndTokens()>.
        -#
        -
        -
        -#
        -#   Function: ParseForCommentsAndTokens
        -#
        -#   Loads the passed file, sends all appropriate comments to <NaturalDocs::Parser->OnComment()>, and breaks the rest into
        -#   an arrayref of tokens.  Tokens are defined as
        -#
        -#   - All consecutive alphanumeric and underscore characters.
        -#   - All consecutive whitespace.
        -#   - A single line break.  It will always be "\n"; you don't have to worry about platform differences.
        -#   - A single character not included above, which is usually a symbol.  Multiple consecutive ones each get their own token.
        -#
        -#   The result will be placed in <Tokens()>.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The source <FileName> to load and parse.
        -#       lineCommentSymbols - An arrayref of symbols that designate line comments, or undef if none.
        -#       blockCommentSymbols - An arrayref of symbol pairs that designate multiline comments, or undef if none.  Symbol pairs are
        -#                                            designated as two consecutive array entries, the opening symbol appearing first.
        -#       javadocLineCommentSymbols - An arrayref of symbols that designate the start of a JavaDoc comment, or undef if none.
        -#       javadocBlockCommentSymbols - An arrayref of symbol pairs that designate multiline JavaDoc comments, or undef if none.
        -#
        -#   Notes:
        -#
        -#       - This function automatically calls <ClearAutoTopics()> and <ClearScopeStack()>.  You only need to call those functions
        -#         manually if you override this one.
        -#       - To save parsing time, all comment lines sent to <NaturalDocs::Parser->OnComment()> will be replaced with blank lines
        -#         in <Tokens()>.  It's all the same to most languages.
        -#
        -sub ParseForCommentsAndTokens #(FileName sourceFile, string[] lineCommentSymbols, string[] blockCommentSymbols, string[] javadocLineCommentSymbols, string[] javadocBlockCommentSymbols)
        -    {
        -    my ($self, $sourceFile, $lineCommentSymbols, $blockCommentSymbols,
        -           $javadocLineCommentSymbols, $javadocBlockCommentSymbols) = @_;
        -
        -    open(SOURCEFILEHANDLE, '<' . $sourceFile)
        -        or die "Couldn't open input file " . $sourceFile . "\n";
        -
        -    my $lineReader = NaturalDocs::LineReader->New(\*SOURCEFILEHANDLE);
        -
        -    my $tokens = [ ];
        -    $self->SetTokens($tokens);
        -
        -    # For convenience.
        -    $self->ClearAutoTopics();
        -    $self->ClearScopeStack();
        -
        -
        -    # Load and preprocess the file
        -
        -    my @lines = $lineReader->GetAll();
        -    close(SOURCEFILEHANDLE);
        -
        -    $self->PreprocessFile(\@lines);
        -
        -
        -    # Go through the file
        -
        -    my $lineIndex = 0;
        -
        -    while ($lineIndex < scalar @lines)
        -        {
        -        my $line = $lines[$lineIndex];
        -
        -        my @commentLines;
        -        my $commentLineNumber;
        -        my $isJavaDoc;
        -        my $closingSymbol;
        -
        -
        -        # Retrieve single line comments.  This leaves $lineIndex at the next line.
        -
        -        if ( ($isJavaDoc = $self->StripOpeningJavaDocSymbols(\$line, $javadocLineCommentSymbols)) ||
        -              $self->StripOpeningSymbols(\$line, $lineCommentSymbols))
        -            {
        -            $commentLineNumber = $lineIndex + 1;
        -
        -            do
        -                {
        -                push @commentLines, $line;
        -                push @$tokens, "\n";
        -
        -                $lineIndex++;
        -
        -                if ($lineIndex >= scalar @lines)
        -                    {  goto EndDo;  };
        -
        -                $line = $lines[$lineIndex];
        -                }
        -            while ($self->StripOpeningSymbols(\$line, $lineCommentSymbols));
        -
        -            EndDo:  # I hate Perl sometimes.
        -            }
        -
        -
        -        # Retrieve multiline comments.  This leaves $lineIndex at the next line.
        -
        -        elsif ( ($isJavaDoc = $self->StripOpeningJavaDocBlockSymbols(\$line, $javadocBlockCommentSymbols)) ||
        -                 ($closingSymbol = $self->StripOpeningBlockSymbols(\$line, $blockCommentSymbols)) )
        -            {
        -            $commentLineNumber = $lineIndex + 1;
        -
        -            if ($isJavaDoc)
        -                {  $closingSymbol = $isJavaDoc;  };
        -
        -            # Note that it is possible for a multiline comment to start correctly but not end so.  We want those comments to stay in
        -            # the code.  For example, look at this prototype with this splint annotation:
        -            #
        -            # int get_array(integer_t id,
        -            #                    /*@out@*/ array_t array);
        -            #
        -            # The annotation starts correctly but doesn't end so because it is followed by code on the same line.
        -
        -            my ($lineRemainder, $isMultiLine);
        -
        -            for (;;)
        -                {
        -                $lineRemainder = $self->StripClosingSymbol(\$line, $closingSymbol);
        -
        -                push @commentLines, $line;
        -
        -                #  If we found an end comment symbol...
        -                if (defined $lineRemainder)
        -                    {  last;  };
        -
        -                push @$tokens, "\n";
        -                $lineIndex++;
        -                $isMultiLine = 1;
        -
        -                if ($lineIndex >= scalar @lines)
        -                    {  last;  };
        -
        -                $line = $lines[$lineIndex];
        -                };
        -
        -            if ($lineRemainder !~ /^[ \t]*$/)
        -                {
        -                # If there was something past the closing symbol this wasn't an acceptable comment.
        -
        -                if ($isMultiLine)
        -                    {  $self->TokenizeLine($lineRemainder);  }
        -                else
        -                    {
        -                    # We go back to the original line if it wasn't a multiline comment because we want the comment to stay in the
        -                    # code.  Otherwise the /*@out@*/ from the example would be removed.
        -                    $self->TokenizeLine($lines[$lineIndex]);
        -                    };
        -
        -                @commentLines = ( );
        -                }
        -            else
        -                {
        -                push @$tokens, "\n";
        -                };
        -
        -            $lineIndex++;
        -            }
        -
        -
        -        # Otherwise just add it to the code.
        -
        -        else
        -            {
        -            $self->TokenizeLine($line);
        -            $lineIndex++;
        -            };
        -
        -
        -        # If there were comments, send them to Parser->OnComment().
        -
        -        if (scalar @commentLines)
        -            {
        -            NaturalDocs::Parser->OnComment(\@commentLines, $commentLineNumber, $isJavaDoc);
        -            @commentLines = ( );
        -            $isJavaDoc = undef;
        -            };
        -
        -        # $lineIndex was incremented by the individual code paths above.
        -
        -        };  # while ($lineIndex < scalar @lines)
        -    };
        -
        -
        -#
        -#   Function: PreprocessFile
        -#
        -#   An overridable function if you'd like to preprocess the file before it goes into <ParseForCommentsAndTokens()>.
        -#
        -#   Parameters:
        -#
        -#       lines - An arrayref to the file's lines.  Each line has its line break stripped off, but is otherwise untouched.
        -#
        -sub PreprocessFile #(lines)
        -    {
        -    };
        -
        -
        -#
        -#   Function: TokenizeLine
        -#
        -#   Converts the passed line to tokens as described in <ParseForCommentsAndTokens> and adds them to <Tokens()>.  Also
        -#   adds a line break token after it.
        -#
        -sub TokenizeLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -    push @{$self->Tokens()}, $line =~ /(\w+|[ \t]+|.)/g, "\n";
        -    };
        -
        -
        -#
        -#   Function: TryToSkipString
        -#
        -#   If the position is on a string delimiter, moves the position to the token following the closing delimiter, or past the end of the
        -#   tokens if there is none.  Assumes all other characters are allowed in the string, the delimiter itself is allowed if it's preceded by
        -#   a backslash, and line breaks are allowed in the string.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the position's index into <Tokens()>.
        -#       lineNumberRef - A reference to the position's line number.
        -#       openingDelimiter - The opening string delimiter, such as a quote or an apostrophe.
        -#       closingDelimiter - The closing string delimiter, if different.  If not defined, assumes the same as openingDelimiter.
        -#       startContentIndexRef - A reference to a variable in which to store the index of the first token of the string's content.
        -#                                         May be undef.
        -#       endContentIndexRef - A reference to a variable in which to store the index of the end of the string's content, which is one
        -#                                        past the last index of content.  May be undef.
        -#
        -#   Returns:
        -#
        -#       Whether the position was on the passed delimiter or not.  The index, line number, and content index ref variables will be
        -#       updated only if true.
        -#
        -sub TryToSkipString #(indexRef, lineNumberRef, openingDelimiter, closingDelimiter, startContentIndexRef, endContentIndexRef)
        -    {
        -    my ($self, $index, $lineNumber, $openingDelimiter, $closingDelimiter, $startContentIndexRef, $endContentIndexRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if (!defined $closingDelimiter)
        -        {  $closingDelimiter = $openingDelimiter;  };
        -
        -    if ($tokens->[$$index] ne $openingDelimiter)
        -        {  return undef;  };
        -
        -
        -    $$index++;
        -    if (defined $startContentIndexRef)
        -        {  $$startContentIndexRef = $$index;  };
        -
        -    while ($$index < scalar @$tokens)
        -        {
        -        if ($tokens->[$$index] eq "\\")
        -            {
        -            # Skip the token after it.
        -            $$index += 2;
        -            }
        -        elsif ($tokens->[$$index] eq "\n")
        -            {
        -            $$lineNumber++;
        -            $$index++;
        -            }
        -        elsif ($tokens->[$$index] eq $closingDelimiter)
        -            {
        -            if (defined $endContentIndexRef)
        -                {  $$endContentIndexRef = $$index;  };
        -
        -            $$index++;
        -            last;
        -            }
        -        else
        -            {
        -            $$index++;
        -            };
        -        };
        -
        -    if ($$index >= scalar @$tokens && defined $endContentIndexRef)
        -        {  $$endContentIndexRef = scalar @$tokens;  };
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: SkipRestOfLine
        -#
        -#   Moves the position to the token following the next line break, or past the end of the tokens array if there is none.  Useful for
        -#   line comments.
        -#
        -#   Note that it skips blindly.  It assumes there cannot be anything of interest, such as a string delimiter, between the position
        -#   and the end of the line.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the position's index into <Tokens()>.
        -#       lineNumberRef - A reference to the position's line number.
        -
        -sub SkipRestOfLine #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $index, $lineNumber) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$index < scalar @$tokens)
        -        {
        -        if ($tokens->[$$index] eq "\n")
        -            {
        -            $$lineNumber++;
        -            $$index++;
        -            last;
        -            }
        -        else
        -            {
        -            $$index++;
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: SkipUntilAfter
        -#
        -#   Moves the position to the token following the next occurance of a particular token sequence, or past the end of the tokens
        -#   array if it never occurs.  Useful for multiline comments.
        -#
        -#   Note that it skips blindly.  It assumes there cannot be anything of interest, such as a string delimiter, between the position
        -#   and the end of the line.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the position's index.
        -#       lineNumberRef - A reference to the position's line number.
        -#       token - A token that must be matched.  Can be specified multiple times to match a sequence of tokens.
        -#
        -sub SkipUntilAfter #(indexRef, lineNumberRef, token, token, ...)
        -    {
        -    my ($self, $index, $lineNumber, @target) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$index < scalar @$tokens)
        -        {
        -        if ($tokens->[$$index] eq $target[0] && ($$index + scalar @target) <= scalar @$tokens)
        -            {
        -            my $match = 1;
        -
        -            for (my $i = 1; $i < scalar @target; $i++)
        -                {
        -                if ($tokens->[$$index+$i] ne $target[$i])
        -                    {
        -                    $match = 0;
        -                    last;
        -                    };
        -                };
        -
        -            if ($match)
        -                {
        -                $$index += scalar @target;
        -                return;
        -                };
        -            };
        -
        -        if ($tokens->[$$index] eq "\n")
        -            {
        -            $$lineNumber++;
        -            $$index++;
        -            }
        -        else
        -            {
        -            $$index++;
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: IsFirstLineToken
        -#
        -#   Returns whether the position is at the first token of a line, not including whitespace.
        -#
        -#   Parameters:
        -#
        -#       index - The index of the position.
        -#
        -sub IsFirstLineToken #(index)
        -    {
        -    my ($self, $index) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($index == 0)
        -        {  return 1;  };
        -
        -    $index--;
        -
        -    if ($tokens->[$index] =~ /^[ \t]/)
        -        {  $index--;  };
        -
        -    if ($index <= 0 || $tokens->[$index] eq "\n")
        -        {  return 1;  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: IsLastLineToken
        -#
        -#   Returns whether the position is at the last token of a line, not including whitespace.
        -#
        -#   Parameters:
        -#
        -#       index - The index of the position.
        -#
        -sub IsLastLineToken #(index)
        -    {
        -    my ($self, $index) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    do
        -        {  $index++;  }
        -    while ($index < scalar @$tokens && $tokens->[$index] =~ /^[ \t]/);
        -
        -    if ($index >= scalar @$tokens || $tokens->[$index] eq "\n")
        -        {  return 1;  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: IsAtSequence
        -#
        -#   Returns whether the position is at a sequence of tokens.
        -#
        -#   Parameters:
        -#
        -#       index - The index of the position.
        -#       token - A token to match.  Specify multiple times to specify the sequence.
        -#
        -sub IsAtSequence #(index, token, token, token ...)
        -    {
        -    my ($self, $index, @target) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($index + scalar @target > scalar @$tokens)
        -        {  return undef;  };
        -
        -    for (my $i = 0; $i < scalar @target; $i++)
        -        {
        -        if ($tokens->[$index + $i] ne $target[$i])
        -            {  return undef;  };
        -        };
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: IsBackslashed
        -#
        -#   Returns whether the position is after a backslash.
        -#
        -#   Parameters:
        -#
        -#       index - The index of the postition.
        -#
        -sub IsBackslashed #(index)
        -    {
        -    my ($self, $index) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($index > 0 && $tokens->[$index - 1] eq "\\")
        -        {  return 1;  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -
        -###############################################################################
        -#
        -#   Group: Scope Functions
        -#
        -#   These functions provide a nice scope stack implementation for language-specific parsers to use.  The default implementation
        -#   makes the following assumptions.
        -#
        -#   - Packages completely replace one another, rather than concatenating.  You need to concatenate manually if that's the
        -#     behavior.
        -#
        -#   - Packages inherit, so if a scope level doesn't set its own, the package is the same as the parent scope's.
        -#
        -
        -
        -#
        -#   Function: ClearScopeStack
        -#
        -#   Clears the scope stack for a new file.  Not necessary if you call <ParseForCommentsAndTokens()>.
        -#
        -sub ClearScopeStack
        -    {
        -    my ($self) = @_;
        -    $self->[SCOPE_STACK] = [ NaturalDocs::Languages::Advanced::Scope->New(undef, undef) ];
        -    $self->[SCOPE_RECORD] = [ NaturalDocs::Languages::Advanced::ScopeChange->New(undef, 1) ];
        -    };
        -
        -
        -#
        -#   Function: StartScope
        -#
        -#   Records a new scope level.
        -#
        -#   Parameters:
        -#
        -#       closingSymbol - The closing symbol of the scope.
        -#       lineNumber - The line number where the scope begins.
        -#       package - The package <SymbolString> of the scope.  Undef means no change.
        -#
        -sub StartScope #(closingSymbol, lineNumber, package)
        -    {
        -    my ($self, $closingSymbol, $lineNumber, $package) = @_;
        -
        -    push @{$self->[SCOPE_STACK]},
        -            NaturalDocs::Languages::Advanced::Scope->New($closingSymbol, $package, $self->CurrentUsing());
        -
        -    $self->AddToScopeRecord($self->CurrentScope(), $lineNumber);
        -    };
        -
        -
        -#
        -#   Function: EndScope
        -#
        -#   Records the end of the current scope level.  Note that this is blind; you need to manually check <ClosingScopeSymbol()> if
        -#   you need to determine if it is correct to do so.
        -#
        -#   Parameters:
        -#
        -#       lineNumber - The line number where the scope ends.
        -#
        -sub EndScope #(lineNumber)
        -    {
        -    my ($self, $lineNumber) = @_;
        -
        -    if (scalar @{$self->[SCOPE_STACK]} > 1)
        -        {  pop @{$self->[SCOPE_STACK]};  };
        -
        -    $self->AddToScopeRecord($self->CurrentScope(), $lineNumber);
        -    };
        -
        -
        -#
        -#   Function: ClosingScopeSymbol
        -#
        -#   Returns the symbol that ends the current scope level, or undef if we are at the top level.
        -#
        -sub ClosingScopeSymbol
        -    {
        -    my ($self) = @_;
        -    return $self->[SCOPE_STACK]->[-1]->ClosingSymbol();
        -    };
        -
        -
        -#
        -#   Function: CurrentScope
        -#
        -#   Returns the current calculated scope, or undef if global.  The default implementation just returns <CurrentPackage()>.  This
        -#   is a separate function because C++ may need to track namespaces and classes separately, and so the current scope would
        -#   be a concatenation of them.
        -#
        -sub CurrentScope
        -    {
        -    return $_[0]->CurrentPackage();
        -    };
        -
        -
        -#
        -#   Function: CurrentPackage
        -#
        -#   Returns the current calculated package or class, or undef if none.
        -#
        -sub CurrentPackage
        -    {
        -    my ($self) = @_;
        -
        -    my $package;
        -
        -    for (my $index = scalar @{$self->[SCOPE_STACK]} - 1; $index >= 0 && !defined $package; $index--)
        -        {
        -        $package = $self->[SCOPE_STACK]->[$index]->Package();
        -        };
        -
        -    return $package;
        -    };
        -
        -
        -#
        -#   Function: SetPackage
        -#
        -#   Sets the package for the current scope level.
        -#
        -#   Parameters:
        -#
        -#       package - The new package <SymbolString>.
        -#       lineNumber - The line number the new package starts on.
        -#
        -sub SetPackage #(package, lineNumber)
        -    {
        -    my ($self, $package, $lineNumber) = @_;
        -    $self->[SCOPE_STACK]->[-1]->SetPackage($package);
        -
        -    $self->AddToScopeRecord($self->CurrentScope(), $lineNumber);
        -    };
        -
        -
        -#
        -#   Function: CurrentUsing
        -#
        -#   Returns the current calculated arrayref of <SymbolStrings> from Using statements, or undef if none.
        -#
        -sub CurrentUsing
        -    {
        -    my ($self) = @_;
        -    return $self->[SCOPE_STACK]->[-1]->Using();
        -    };
        -
        -
        -#
        -#   Function: AddUsing
        -#
        -#   Adds a Using <SymbolString> to the current scope.
        -#
        -sub AddUsing #(using)
        -    {
        -    my ($self, $using) = @_;
        -    $self->[SCOPE_STACK]->[-1]->AddUsing($using);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: AddToScopeRecord
        -#
        -#   Adds a change to the scope record, condensing unnecessary entries.
        -#
        -#   Parameters:
        -#
        -#       newScope - What the scope <SymbolString> changed to.
        -#       lineNumber - Where the scope changed.
        -#
        -sub AddToScopeRecord #(newScope, lineNumber)
        -    {
        -    my ($self, $scope, $lineNumber) = @_;
        -    my $scopeRecord = $self->ScopeRecord();
        -
        -    if ($scope ne $scopeRecord->[-1]->Scope())
        -        {
        -        if ($scopeRecord->[-1]->LineNumber() == $lineNumber)
        -            {  $scopeRecord->[-1]->SetScope($scope);  }
        -        else
        -            {  push @$scopeRecord, NaturalDocs::Languages::Advanced::ScopeChange->New($scope, $lineNumber);  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: CreateString
        -#
        -#   Converts the specified tokens into a string and returns it.
        -#
        -#   Parameters:
        -#
        -#       startIndex - The starting index to convert.
        -#       endIndex - The ending index, which is *not inclusive*.
        -#
        -#   Returns:
        -#
        -#       The string.
        -#
        -sub CreateString #(startIndex, endIndex)
        -    {
        -    my ($self, $startIndex, $endIndex) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $string;
        -
        -    while ($startIndex < $endIndex && $startIndex < scalar @$tokens)
        -        {
        -        $string .= $tokens->[$startIndex];
        -        $startIndex++;
        -        };
        -
        -    return $string;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm
        deleted file mode 100644
        index 39218107b..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm
        +++ /dev/null
        @@ -1,96 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Advanced::Scope
        -#
        -###############################################################################
        -#
        -#   A class used to store a scope level.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Advanced::Scope;
        -
        -#
        -#   Constants: Implementation
        -#
        -#   The object is implemented as a blessed arrayref.  The constants below are used as indexes.
        -#
        -#   CLOSING_SYMBOL - The closing symbol character of the scope.
        -#   PACKAGE - The package <SymbolString> of the scope.
        -#   USING - An arrayref of <SymbolStrings> for using statements, or undef if none.
        -#
        -use NaturalDocs::DefineMembers 'CLOSING_SYMBOL', 'PACKAGE', 'USING';
        -# Dependency: New() depends on the order of these constants as well as that there is no inherited members.
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       closingSymbol - The closing symbol character of the scope.
        -#       package - The package <SymbolString> of the scope.
        -#       using - An arrayref of using <SymbolStrings>, or undef if none.  The contents of the array will be duplicated.
        -#
        -#       If package is set to undef, it is assumed that it inherits the value of the previous scope on the stack.
        -#
        -sub New #(closingSymbol, package, using)
        -    {
        -    # Dependency: This depends on the order of the parameters matching the constants, and that there are no inherited
        -    # members.
        -    my $package = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $package;
        -
        -    if (defined $object->[USING])
        -        {  $object->[USING] = [ @{$object->[USING]} ];  };
        -
        -    return $object;
        -    };
        -
        -
        -# Function: ClosingSymbol
        -# Returns the closing symbol character of the scope.
        -sub ClosingSymbol
        -    {  return $_[0]->[CLOSING_SYMBOL];  };
        -
        -# Function: Package
        -# Returns the package <SymbolString> of the scope, or undef if none.
        -sub Package
        -    {  return $_[0]->[PACKAGE];  };
        -
        -# Function: SetPackage
        -# Sets the package <SymbolString> of the scope.
        -sub SetPackage #(package)
        -    {  $_[0]->[PACKAGE] = $_[1];  };
        -
        -# Function: Using
        -# Returns an arrayref of <SymbolStrings> for using statements, or undef if none
        -sub Using
        -    {  return $_[0]->[USING];  };
        -
        -# Function: AddUsing
        -# Adds a <SymbolString> to the <Using()> array.
        -sub AddUsing #(using)
        -    {
        -    my ($self, $using) = @_;
        -
        -    if (!defined $self->[USING])
        -        {  $self->[USING] = [ ];  };
        -
        -    push @{$self->[USING]}, $using;
        -    };
        -
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm
        deleted file mode 100644
        index 8774d5b59..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm
        +++ /dev/null
        @@ -1,71 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Advanced::ScopeChange
        -#
        -###############################################################################
        -#
        -#   A class used to store a scope change.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Advanced::ScopeChange;
        -
        -#
        -#   Constants: Implementation
        -#
        -#   The object is implemented as a blessed arrayref.  The constants below are used as indexes.
        -#
        -#   SCOPE - The new scope <SymbolString>.
        -#   LINE_NUMBER - The line number of the change.
        -#
        -use NaturalDocs::DefineMembers 'SCOPE', 'LINE_NUMBER';
        -# Dependency: New() depends on the order of these constants as well as that there is no inherited members.
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       scope - The <SymbolString> the scope was changed to.
        -#       lineNumber - What line it occurred on.
        -#
        -sub New #(scope, lineNumber)
        -    {
        -    # Dependency: This depends on the order of the parameters matching the constants, and that there are no inherited
        -    # members.
        -    my $self = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $self;
        -
        -    return $object;
        -    };
        -
        -
        -# Function: Scope
        -# Returns the <SymbolString> the scope was changed to.
        -sub Scope
        -    {  return $_[0]->[SCOPE];  };
        -
        -# Function: SetScope
        -# Replaces the <SymbolString> the scope was changed to.
        -sub SetScope #(scope)
        -    {  $_[0]->[SCOPE] = $_[1];  };
        -
        -# Function: LineNumber
        -# Returns the line number of the change.
        -sub LineNumber
        -    {  return $_[0]->[LINE_NUMBER];  };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Base.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Base.pm
        deleted file mode 100644
        index 15880c437..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Base.pm
        +++ /dev/null
        @@ -1,833 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Base
        -#
        -###############################################################################
        -#
        -#   A base class for all programming language parsers.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Base;
        -
        -use NaturalDocs::DefineMembers 'NAME', 'Name()',
        -                                                 'EXTENSIONS', 'Extensions()', 'SetExtensions() duparrayref',
        -                                                 'SHEBANG_STRINGS', 'ShebangStrings()', 'SetShebangStrings() duparrayref',
        -                                                 'IGNORED_PREFIXES',
        -                                                 'ENUM_VALUES';
        -
        -use base 'Exporter';
        -our @EXPORT = ('ENUM_GLOBAL', 'ENUM_UNDER_TYPE', 'ENUM_UNDER_PARENT');
        -
        -
        -#
        -#   Constants: EnumValuesType
        -#
        -#   How enum values are handled in the language.
        -#
        -#   ENUM_GLOBAL - Values are always global and thus 'value'.
        -#   ENUM_UNDER_TYPE - Values are under the type in the hierarchy, and thus 'package.enum.value'.
        -#   ENUM_UNDER_PARENT - Values are under the parent in the hierarchy, putting them on the same level as the enum itself.  Thus
        -#                                       'package.value'.
        -#
        -use constant ENUM_GLOBAL => 1;
        -use constant ENUM_UNDER_TYPE => 2;
        -use constant ENUM_UNDER_PARENT => 3;
        -
        -
        -#
        -#   Handle: SOURCEFILEHANDLE
        -#
        -#   The handle of the source file currently being parsed.
        -#
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       name - The name of the language.
        -#
        -sub New #(name)
        -    {
        -    my ($selfPackage, $name) = @_;
        -
        -    my $object = [ ];
        -
        -    $object->[NAME] = $name;
        -
        -    bless $object, $selfPackage;
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Members
        -#
        -#   Name - Returns the language's name.
        -#   Extensions - Returns an arrayref of the language's file extensions, or undef if none.
        -#   SetExtensions - Replaces the arrayref of the language's file extensions.
        -#   ShebangStrings - Returns an arrayref of the language's shebang strings, or undef if none.
        -#   SetShebangStrings - Replaces the arrayref of the language's shebang strings.
        -#
        -
        -#
        -#   Function: PackageSeparator
        -#   Returns the language's package separator string.
        -#
        -sub PackageSeparator
        -    {  return '.';  };
        -
        -#
        -#   Function: PackageSeparatorWasSet
        -#   Returns whether the language's package separator string was ever changed from the default.
        -#
        -sub PackageSeparatorWasSet
        -    {  return 0;  };
        -
        -
        -#
        -#   Function: EnumValues
        -#   Returns the <EnumValuesType> that describes how the language handles enums.
        -#
        -sub EnumValues
        -    {  return ENUM_GLOBAL;  };
        -
        -
        -#
        -#   Function: IgnoredPrefixesFor
        -#
        -#   Returns an arrayref of ignored prefixes for the passed <TopicType>, or undef if none.  The array is sorted so that the longest
        -#   prefixes are first.
        -#
        -sub IgnoredPrefixesFor #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    if (defined $self->[IGNORED_PREFIXES])
        -        {  return $self->[IGNORED_PREFIXES]->{$type};  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: SetIgnoredPrefixesFor
        -#
        -#   Replaces the arrayref of ignored prefixes for the passed <TopicType>.
        -#
        -sub SetIgnoredPrefixesFor #(type, prefixes)
        -    {
        -    my ($self, $type, $prefixesRef) = @_;
        -
        -    if (!defined $self->[IGNORED_PREFIXES])
        -        {  $self->[IGNORED_PREFIXES] = { };  };
        -
        -    if (!defined $prefixesRef)
        -        {  delete $self->[IGNORED_PREFIXES]->{$type};  }
        -    else
        -        {
        -        my $prefixes = [ @$prefixesRef ];
        -
        -        # Sort prefixes to be longest to shortest.
        -        @$prefixes = sort { length $b <=> length $a } @$prefixes;
        -
        -        $self->[IGNORED_PREFIXES]->{$type} = $prefixes;
        -        };
        -    };
        -
        -
        -#
        -#   Function: HasIgnoredPrefixes
        -#
        -#   Returns whether the language has any ignored prefixes at all.
        -#
        -sub HasIgnoredPrefixes
        -    {  return defined $_[0]->[IGNORED_PREFIXES];  };
        -
        -
        -#
        -#   Function: CopyIgnoredPrefixesOf
        -#
        -#   Copies all the ignored prefix settings of the passed <NaturalDocs::Languages::Base> object.
        -#
        -sub CopyIgnoredPrefixesOf #(language)
        -    {
        -    my ($self, $language) = @_;
        -
        -    if ($language->HasIgnoredPrefixes())
        -        {
        -        $self->[IGNORED_PREFIXES] = { };
        -
        -        while (my ($topicType, $prefixes) = each %{$language->[IGNORED_PREFIXES]})
        -            {
        -            $self->[IGNORED_PREFIXES]->{$topicType} = [ @$prefixes ];
        -            };
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Parsing Functions
        -
        -
        -#
        -#   Function: ParseFile
        -#
        -#   Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
        -#   This *must* be defined by a subclass.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The <FileName> of the source file to parse.
        -#       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
        -#
        -#   Returns:
        -#
        -#       The array ( autoTopics, scopeRecord ).
        -#
        -#       autoTopics - An arrayref of automatically generated <NaturalDocs::Parser::ParsedTopics> from the file, or undef if none.
        -#       scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
        -#
        -
        -
        -#
        -#   Function: ParsePrototype
        -#
        -#   Parses the prototype and returns it as a <NaturalDocs::Languages::Prototype> object.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType>.
        -#       prototype - The text prototype.
        -#
        -#   Returns:
        -#
        -#       A <NaturalDocs::Languages::Prototype> object.
        -#
        -sub ParsePrototype #(type, prototype)
        -    {
        -    my ($self, $type, $prototype) = @_;
        -
        -    my $isClass = NaturalDocs::Topics->TypeInfo($type)->ClassHierarchy();
        -
        -    if ($prototype !~ /\(.*[^ ].*\)/ && (!$isClass || $prototype !~ /\{.*[^ ].*\}/))
        -        {
        -        my $object = NaturalDocs::Languages::Prototype->New($prototype);
        -        return $object;
        -        };
        -
        -
        -    # Parse the parameters out of the prototype.
        -
        -    my @tokens = $prototype =~ /([^\(\)\[\]\{\}\<\>\'\"\,\;]+|.)/g;
        -
        -    my $parameter;
        -    my @parameterLines;
        -
        -    my @symbolStack;
        -    my $finishedParameters;
        -
        -    my ($beforeParameters, $afterParameters);
        -
        -    foreach my $token (@tokens)
        -        {
        -        if ($finishedParameters)
        -            {  $afterParameters .= $token;  }
        -
        -        elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
        -            {
        -            if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
        -                {  $parameter .= $token;  }
        -            else
        -                {  $beforeParameters .= $token;  };
        -
        -            if ($token eq $symbolStack[-1])
        -                {  pop @symbolStack;  };
        -            }
        -
        -        elsif ($token =~ /^[\(\[\{\<\'\"]$/)
        -            {
        -            if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
        -                {  $parameter .= $token;   }
        -            else
        -                {  $beforeParameters .= $token;  };
        -
        -            push @symbolStack, $token;
        -            }
        -
        -        elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
        -                 ($token eq ']' && $symbolStack[-1] eq '[') ||
        -                 ($token eq '}' && $symbolStack[-1] eq '{') ||
        -                 ($token eq '>' && $symbolStack[-1] eq '<') )
        -            {
        -            if ($symbolStack[0] eq '(')
        -                {
        -                if ($token eq ')' && scalar @symbolStack == 1)
        -                    {
        -                    if ($parameter ne ' ')
        -                        {  push @parameterLines, $parameter;  };
        -
        -                    $finishedParameters = 1;
        -                    $afterParameters .= $token;
        -                    }
        -                else
        -                    {  $parameter .= $token;  };
        -                }
        -            elsif ($isClass && $symbolStack[0] eq '{')
        -                {
        -                if ($token eq '}' && scalar @symbolStack == 1)
        -                    {
        -                    if ($parameter ne ' ')
        -                        {  push @parameterLines, $parameter;  };
        -
        -                    $finishedParameters = 1;
        -                    $afterParameters .= $token;
        -                    }
        -                else
        -                    {  $parameter .= $token;  };
        -                }
        -            else
        -                {
        -                $beforeParameters .= $token;
        -                };
        -
        -            pop @symbolStack;
        -            }
        -
        -        elsif ($token eq ',' || $token eq ';')
        -            {
        -            if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
        -                {
        -                if (scalar @symbolStack == 1)
        -                    {
        -                    push @parameterLines, $parameter . $token;
        -                    $parameter = undef;
        -                    }
        -                else
        -                    {
        -                    $parameter .= $token;
        -                    };
        -                }
        -            else
        -                {
        -                $beforeParameters .= $token;
        -                };
        -            }
        -
        -        else
        -            {
        -            if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
        -                {  $parameter .= $token;  }
        -            else
        -                {  $beforeParameters .= $token;  };
        -            };
        -        };
        -
        -    foreach my $part (\$beforeParameters, \$afterParameters)
        -        {
        -        $$part =~ s/^ //;
        -        $$part =~ s/ $//;
        -        };
        -
        -    my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
        -
        -
        -    # Parse the actual parameters.
        -
        -    foreach my $parameterLine (@parameterLines)
        -        {
        -        $prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
        -        };
        -
        -    return $prototypeObject;
        -    };
        -
        -
        -#
        -#   Function: ParseParameterLine
        -#
        -#   Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
        -#
        -#   This vesion assumes a C++ style line.  If you need a Pascal style line, override this function to forward to
        -#   <ParsePascalParameterLine()>.
        -#
        -#   > Function(parameter, type parameter, type parameter = value);
        -#
        -sub ParseParameterLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -
        -    $line =~ s/^ //;
        -    $line =~ s/ $//;
        -
        -    my @tokens = $line =~ /([^ \(\)\{\}\[\]\<\>\'\"\=]+|.)/g;
        -
        -    my @symbolStack;
        -    my @parameterWords = ( undef );
        -    my ($defaultValue, $defaultValuePrefix, $inDefaultValue);
        -
        -    foreach my $token (@tokens)
        -        {
        -        if ($inDefaultValue)
        -            {  $defaultValue .= $token;  }
        -
        -        elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
        -            {
        -            $parameterWords[-1] .= $token;
        -
        -            if ($token eq $symbolStack[-1])
        -                {  pop @symbolStack;  };
        -            }
        -
        -        elsif ($token =~ /^[\(\[\{\<\'\"]$/)
        -            {
        -            push @symbolStack, $token;
        -            $parameterWords[-1] .= $token;
        -            }
        -
        -        elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
        -                 ($token eq ']' && $symbolStack[-1] eq '[') ||
        -                 ($token eq '}' && $symbolStack[-1] eq '{') ||
        -                 ($token eq '>' && $symbolStack[-1] eq '<') )
        -            {
        -            pop @symbolStack;
        -            $parameterWords[-1] .= $token;
        -            }
        -
        -        elsif ($token eq ' ')
        -            {
        -            if (!scalar @symbolStack)
        -                {  push @parameterWords, undef;  }
        -            else
        -                {  $parameterWords[-1] .= $token;  };
        -            }
        -
        -        elsif ($token eq '=')
        -            {
        -            if (!scalar @symbolStack)
        -                {
        -                $defaultValuePrefix = $token;
        -                $inDefaultValue = 1;
        -                }
        -            else
        -                {  $parameterWords[-1] .= $token;  };
        -            }
        -
        -        else
        -            {
        -            $parameterWords[-1] .= $token;
        -            };
        -        };
        -
        -    my ($name, $namePrefix, $type, $typePrefix);
        -
        -    if (!$parameterWords[-1])
        -        {  pop @parameterWords;  };
        -
        -    $name = pop @parameterWords;
        -
        -    if ($parameterWords[-1]=~ /([\*\&]+)$/)
        -        {
        -        $namePrefix = $1;
        -        $parameterWords[-1] = substr($parameterWords[-1], 0, 0 - length($namePrefix));
        -        $parameterWords[-1] =~ s/ $//;
        -
        -        if (!$parameterWords[-1])
        -            {  pop @parameterWords;  };
        -        }
        -    elsif ($name =~ /^([\*\&]+)/)
        -        {
        -        $namePrefix = $1;
        -        $name = substr($name, length($namePrefix));
        -        $name =~ s/^ //;
        -        };
        -
        -    $type = pop @parameterWords;
        -    $typePrefix = join(' ', @parameterWords);
        -
        -    if ($typePrefix)
        -        {  $typePrefix .= ' ';  };
        -
        -    if ($type =~ /^([a-z0-9_\:\.]+(?:\.|\:\:))[a-z0-9_]/i)
        -        {
        -        my $attachedTypePrefix = $1;
        -
        -        $typePrefix .= $attachedTypePrefix;
        -        $type = substr($type, length($attachedTypePrefix));
        -        };
        -
        -    $defaultValue =~ s/ $//;
        -
        -    return NaturalDocs::Languages::Prototype::Parameter->New($type, $typePrefix, $name, $namePrefix,
        -                                                                                             $defaultValue, $defaultValuePrefix);
        -    };
        -
        -
        -#
        -#   Function: ParsePascalParameterLine
        -#
        -#   Parses a Pascal-like prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
        -#   Pascal lines are as follows:
        -#
        -#   > Function (name: type; name, name: type := value)
        -#
        -#   Also supports ActionScript lines
        -#
        -#   > Function (name: type, name, name: type = value)
        -#
        -sub ParsePascalParameterLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -
        -    $line =~ s/^ //;
        -    $line =~ s/ $//;
        -
        -    my @tokens = $line =~ /([^\(\)\{\}\[\]\<\>\'\"\=\:]+|\:\=|.)/g;
        -    my ($type, $name, $defaultValue, $defaultValuePrefix, $afterName, $afterDefaultValue);
        -    my @symbolStack;
        -
        -    foreach my $token (@tokens)
        -        {
        -        if ($afterDefaultValue)
        -            {  $defaultValue .= $token;  }
        -
        -        elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
        -            {
        -            if ($afterName)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -
        -            if ($token eq $symbolStack[-1])
        -                {  pop @symbolStack;  };
        -            }
        -
        -        elsif ($token =~ /^[\(\[\{\<\'\"]$/)
        -            {
        -            push @symbolStack, $token;
        -
        -            if ($afterName)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -            }
        -
        -        elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
        -                 ($token eq ']' && $symbolStack[-1] eq '[') ||
        -                 ($token eq '}' && $symbolStack[-1] eq '{') ||
        -                 ($token eq '>' && $symbolStack[-1] eq '<') )
        -            {
        -            pop @symbolStack;
        -
        -            if ($afterName)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -            }
        -
        -        elsif ($afterName)
        -            {
        -            if (($token eq ':=' || $token eq '=') && !scalar @symbolStack)
        -                {
        -                $defaultValuePrefix = $token;
        -                $afterDefaultValue = 1;
        -                }
        -            else
        -                {  $type .= $token;  };
        -            }
        -
        -        elsif ($token eq ':' && !scalar @symbolStack)
        -            {
        -            $name .= $token;
        -            $afterName = 1;
        -            }
        -
        -        else
        -            {  $name .= $token;  };
        -        };
        -
        -    foreach my $part (\$type, \$name, \$defaultValue)
        -        {
        -        $$part =~ s/^ //;
        -        $$part =~ s/ $//;
        -        };
        -
        -    return NaturalDocs::Languages::Prototype::Parameter->New($type, undef, $name, undef, $defaultValue, $defaultValuePrefix);
        -    };
        -
        -
        -#
        -#   Function: TypeBeforeParameter
        -#
        -#   Returns whether the type appears before the parameter in prototypes.
        -#
        -#   For example, it does in C++
        -#   > void Function (int a, int b)
        -#
        -#   but does not in Pascal
        -#   > function Function (a: int; b, c: int)
        -#
        -sub TypeBeforeParameter
        -    {
        -    return 1;
        -    };
        -
        -
        -
        -#
        -#   Function: IgnoredPrefixLength
        -#
        -#   Returns the length of the prefix that should be ignored in the index, or zero if none.
        -#
        -#   Parameters:
        -#
        -#       name - The name of the symbol.
        -#       type  - The symbol's <TopicType>.
        -#
        -#   Returns:
        -#
        -#       The length of the prefix to ignore, or zero if none.
        -#
        -sub IgnoredPrefixLength #(name, type)
        -    {
        -    my ($self, $name, $type) = @_;
        -
        -    foreach my $prefixes ($self->IgnoredPrefixesFor($type), $self->IgnoredPrefixesFor(::TOPIC_GENERAL()))
        -        {
        -        if (defined $prefixes)
        -            {
        -            foreach my $prefix (@$prefixes)
        -                {
        -                if (substr($name, 0, length($prefix)) eq $prefix)
        -                    {  return length($prefix);  };
        -                };
        -            };
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: StripOpeningSymbols
        -#
        -#   Determines if the line starts with any of the passed symbols, and if so, replaces it with spaces.  This only happens
        -#   if the only thing before it on the line is whitespace.
        -#
        -#   Parameters:
        -#
        -#       lineRef - A reference to the line to check.
        -#       symbols - An arrayref of the symbols to check for.
        -#
        -#   Returns:
        -#
        -#       If the line starts with any of the passed comment symbols, it will replace it in the line with spaces and return the symbol.
        -#       If the line doesn't, it will leave the line alone and return undef.
        -#
        -sub StripOpeningSymbols #(lineRef, symbols)
        -    {
        -    my ($self, $lineRef, $symbols) = @_;
        -
        -    if (!defined $symbols)
        -        {  return undef;  };
        -
        -    my ($index, $symbol) = ::FindFirstSymbol($$lineRef, $symbols);
        -
        -    if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/)
        -        {
        -        return substr($$lineRef, $index, length($symbol), ' ' x length($symbol));
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: StripOpeningJavaDocSymbols
        -#
        -#   Determines if the line starts with any of the passed symbols, and if so, replaces it with spaces.  This only happens
        -#   if the only thing before it on the line is whitespace and the next character after it is whitespace or the end of the line.
        -#
        -#   Parameters:
        -#
        -#       lineRef - A reference to the line to check.
        -#       symbols - An arrayref of the symbols to check for.
        -#
        -#   Returns:
        -#
        -#       If the line starts with any of the passed comment symbols, it will replace it in the line with spaces and return the symbol.
        -#       If the line doesn't, it will leave the line alone and return undef.
        -#
        -sub StripOpeningJavaDocSymbols #(lineRef, symbols)
        -    {
        -    my ($self, $lineRef, $symbols) = @_;
        -
        -    if (!defined $symbols)
        -        {  return undef;  };
        -
        -    my ($index, $symbol) = ::FindFirstSymbol($$lineRef, $symbols);
        -
        -    if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/ && substr($$lineRef, $index + length($symbol), 1) =~ /^[ \t]?$/)
        -        {
        -        return substr($$lineRef, $index, length($symbol), ' ' x length($symbol));
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: StripOpeningBlockSymbols
        -#
        -#   Determines if the line starts with any of the opening symbols in the passed symbol pairs, and if so, replaces it with spaces.
        -#   This only happens if the only thing before it on the line is whitespace.
        -#
        -#   Parameters:
        -#
        -#       lineRef - A reference to the line to check.
        -#       symbolPairs - An arrayref of the symbol pairs to check for.  Pairs are specified as two consecutive array entries, with the
        -#                            opening symbol first.
        -#
        -#   Returns:
        -#
        -#       If the line starts with any of the opening symbols, it will replace it in the line with spaces and return the closing symbol.
        -#       If the line doesn't, it will leave the line alone and return undef.
        -#
        -sub StripOpeningBlockSymbols #(lineRef, symbolPairs)
        -    {
        -    my ($self, $lineRef, $symbolPairs) = @_;
        -
        -    if (!defined $symbolPairs)
        -        {  return undef;  };
        -
        -    for (my $i = 0; $i < scalar @$symbolPairs; $i += 2)
        -        {
        -        my $index = index($$lineRef, $symbolPairs->[$i]);
        -
        -        if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/)
        -            {
        -            substr($$lineRef, $index, length($symbolPairs->[$i]), ' ' x length($symbolPairs->[$i]));
        -            return $symbolPairs->[$i + 1];
        -            };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: StripOpeningJavaDocBlockSymbols
        -#
        -#   Determines if the line starts with any of the opening symbols in the passed symbol pairs, and if so, replaces it with spaces.
        -#   This only happens if the only thing before it on the line is whitespace and the next character is whitespace or the end of the line.
        -#
        -#   Parameters:
        -#
        -#       lineRef - A reference to the line to check.
        -#       symbolPairs - An arrayref of the symbol pairs to check for.  Pairs are specified as two consecutive array entries, with the
        -#                            opening symbol first.
        -#
        -#   Returns:
        -#
        -#       If the line starts with any of the opening symbols, it will replace it in the line with spaces and return the closing symbol.
        -#       If the line doesn't, it will leave the line alone and return undef.
        -#
        -sub StripOpeningJavaDocBlockSymbols #(lineRef, symbolPairs)
        -    {
        -    my ($self, $lineRef, $symbolPairs) = @_;
        -
        -    if (!defined $symbolPairs)
        -        {  return undef;  };
        -
        -    for (my $i = 0; $i < scalar @$symbolPairs; $i += 2)
        -        {
        -        my $index = index($$lineRef, $symbolPairs->[$i]);
        -
        -        if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/ &&
        -            substr($$lineRef, $index + length($symbolPairs->[$i]), 1) =~ /^[ \t]?$/)
        -            {
        -            substr($$lineRef, $index, length($symbolPairs->[$i]), ' ' x length($symbolPairs->[$i]));
        -            return $symbolPairs->[$i + 1];
        -            };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: StripClosingSymbol
        -#
        -#   Determines if the line contains a symbol, and if so, truncates it just before the symbol.
        -#
        -#   Parameters:
        -#
        -#       lineRef - A reference to the line to check.
        -#       symbol - The symbol to check for.
        -#
        -#   Returns:
        -#
        -#       The remainder of the line, or undef if the symbol was not found.
        -#
        -sub StripClosingSymbol #(lineRef, symbol)
        -    {
        -    my ($self, $lineRef, $symbol) = @_;
        -
        -    my $index = index($$lineRef, $symbol);
        -
        -    if ($index != -1)
        -        {
        -        my $lineRemainder = substr($$lineRef, $index + length($symbol));
        -        $$lineRef = substr($$lineRef, 0, $index);
        -
        -        return $lineRemainder;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: NormalizePrototype
        -#
        -#   Normalizes a prototype.  Specifically, condenses spaces, tabs, and line breaks into single spaces and removes leading and
        -#   trailing ones.
        -#
        -#   Parameters:
        -#
        -#       prototype - The original prototype string.
        -#
        -#   Returns:
        -#
        -#       The normalized prototype.
        -#
        -sub NormalizePrototype #(prototype)
        -    {
        -    my ($self, $prototype) = @_;
        -
        -    $prototype =~ tr/ \t\r\n/ /s;
        -    $prototype =~ s/^ //;
        -    $prototype =~ s/ $//;
        -
        -    return $prototype;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/CSharp.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/CSharp.pm
        deleted file mode 100644
        index 13a0c94fb..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/CSharp.pm
        +++ /dev/null
        @@ -1,1552 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::CSharp
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of C#.
        -#
        -#
        -#   Topic: Language Support
        -#
        -#       Supported:
        -#
        -#       - Classes
        -#       - Namespaces (no topic generated)
        -#       - Functions
        -#       - Constructors and Destructors
        -#       - Properties
        -#       - Indexers
        -#       - Operators
        -#       - Delegates
        -#       - Variables
        -#       - Constants
        -#       - Events
        -#       - Enums
        -#
        -#       Not supported yet:
        -#
        -#       - Autodocumenting enum members
        -#       - Using alias
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::CSharp;
        -
        -use base 'NaturalDocs::Languages::Advanced';
        -
        -
        -###############################################################################
        -# Group: Package Variables
        -
        -#
        -#   hash: classKeywords
        -#   An existence hash of all the acceptable class keywords.  The keys are in all lowercase.
        -#
        -my %classKeywords = ( 'class' => 1,
        -                                    'struct' => 1,
        -                                    'interface' => 1 );
        -
        -#
        -#   hash: classModifiers
        -#   An existence hash of all the acceptable class modifiers.  The keys are in all lowercase.
        -#
        -my %classModifiers = ( 'new' => 1,
        -                                   'public' => 1,
        -                                   'protected' => 1,
        -                                   'internal' => 1,
        -                                   'private' => 1,
        -                                   'abstract' => 1,
        -                                   'sealed' => 1,
        -                                   'unsafe' => 1,
        -                                   'static' => 1,
        -                                   'partial' => 1 );
        -
        -#
        -#   hash: functionModifiers
        -#   An existence hash of all the acceptable function modifiers.  Also applies to properties.  Also encompasses those for operators
        -#   and indexers, but have more than are valid for them.  The keys are in all lowercase.
        -#
        -my %functionModifiers = ( 'new' => 1,
        -                                       'public' => 1,
        -                                       'protected' => 1,
        -                                       'internal' => 1,
        -                                       'private' => 1,
        -                                       'static' => 1,
        -                                       'virtual' => 1,
        -                                       'sealed' => 1,
        -                                       'override' => 1,
        -                                       'abstract' => 1,
        -                                       'extern' => 1,
        -                                       'unsafe' => 1 );
        -
        -#
        -#   hash: variableModifiers
        -#   An existence hash of all the acceptable variable modifiers.  The keys are in all lowercase.
        -#
        -my %variableModifiers = ( 'new' => 1,
        -                                       'public' => 1,
        -                                       'protected' => 1,
        -                                       'internal' => 1,
        -                                       'private' => 1,
        -                                       'static' => 1,
        -                                       'readonly' => 1,
        -                                       'volatile' => 1,
        -                                       'unsafe' => 1 );
        -
        -#
        -#   hash: enumTypes
        -#   An existence hash of all the possible enum types.  The keys are in all lowercase.
        -#
        -my %enumTypes = ( 'sbyte' => 1,
        -                             'byte' => 1,
        -                             'short' => 1,
        -                             'ushort' => 1,
        -                             'int' => 1,
        -                             'uint' => 1,
        -                             'long' => 1,
        -                             'ulong' => 1 );
        -
        -#
        -#   hash: impossibleTypeWords
        -#   An existence hash of all the reserved words that cannot be in a type.  This includes 'enum' and all modifiers.  The keys are in
        -#   all lowercase.
        -#
        -my %impossibleTypeWords = ( 'abstract' => 1, 'as' => 1, 'base' => 1, 'break' => 1, 'case' => 1, 'catch' => 1,
        -                                              'checked' => 1, 'class' => 1, 'const' => 1, 'continue' => 1, 'default' => 1, 'delegate' => 1,
        -                                              'do' => 1, 'else' => 1, 'enum' => 1, 'event' => 1, 'explicit' => 1, 'extern' => 1,
        -                                              'false' => 1, 'finally' => 1, 'fixed' => 1, 'for' => 1, 'foreach' => 1, 'goto' => 1, 'if' => 1,
        -                                              'implicit' => 1, 'in' => 1, 'interface' => 1, 'internal' => 1, 'is' => 1, 'lock' => 1,
        -                                              'namespace' => 1, 'new' => 1, 'null' => 1, 'operator' => 1, 'out' => 1, 'override' => 1,
        -                                              'params' => 1, 'private' => 1, 'protected' => 1, 'public' => 1, 'readonly' => 1, 'ref' => 1,
        -                                              'return' => 1, 'sealed' => 1, 'sizeof' => 1, 'stackalloc' => 1, 'static' => 1,
        -                                              'struct' => 1, 'switch' => 1, 'this' => 1, 'throw' => 1, 'true' => 1, 'try' => 1, 'typeof' => 1,
        -                                              'unchecked' => 1, 'unsafe' => 1, 'using' => 1, 'virtual' => 1, 'volatile' => 1, 'while' => 1 );
        -# Deleted from the list: object, string, bool, decimal, sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, void
        -
        -
        -
        -###############################################################################
        -# Group: Interface Functions
        -
        -
        -#
        -#   Function: PackageSeparator
        -#   Returns the package separator symbol.
        -#
        -sub PackageSeparator
        -    {  return '.';  };
        -
        -
        -#
        -#   Function: EnumValues
        -#   Returns the <EnumValuesType> that describes how the language handles enums.
        -#
        -sub EnumValues
        -    {  return ::ENUM_UNDER_TYPE();  };
        -
        -
        -#
        -#   Function: ParseFile
        -#
        -#   Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The <FileName> to parse.
        -#       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
        -#
        -#   Returns:
        -#
        -#       The array ( autoTopics, scopeRecord ).
        -#
        -#       autoTopics - An arrayref of automatically generated topics from the file, or undef if none.
        -#       scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
        -#
        -sub ParseFile #(sourceFile, topicsList)
        -    {
        -    my ($self, $sourceFile, $topicsList) = @_;
        -
        -    $self->ParseForCommentsAndTokens($sourceFile, [ '//' ], [ '/*', '*/' ], [ '///' ], [ '/**', '*/' ] );
        -
        -    my $tokens = $self->Tokens();
        -    my $index = 0;
        -    my $lineNumber = 1;
        -
        -    while ($index < scalar @$tokens)
        -        {
        -        if ($self->TryToSkipWhitespace(\$index, \$lineNumber) ||
        -            $self->TryToGetNamespace(\$index, \$lineNumber) ||
        -            $self->TryToGetUsing(\$index, \$lineNumber) ||
        -            $self->TryToGetClass(\$index, \$lineNumber) ||
        -            $self->TryToGetFunction(\$index, \$lineNumber) ||
        -            $self->TryToGetOverloadedOperator(\$index, \$lineNumber) ||
        -            $self->TryToGetVariable(\$index, \$lineNumber) ||
        -            $self->TryToGetEnum(\$index, \$lineNumber) )
        -            {
        -            # The functions above will handle everything.
        -            }
        -
        -        elsif ($tokens->[$index] eq '{')
        -            {
        -            $self->StartScope('}', $lineNumber, undef, undef, undef);
        -            $index++;
        -            }
        -
        -        elsif ($tokens->[$index] eq '}')
        -            {
        -            if ($self->ClosingScopeSymbol() eq '}')
        -                {  $self->EndScope($lineNumber);  };
        -
        -            $index++;
        -            }
        -
        -        else
        -            {
        -            $self->SkipRestOfStatement(\$index, \$lineNumber);
        -            };
        -        };
        -
        -
        -    # Don't need to keep these around.
        -    $self->ClearTokens();
        -
        -
        -    my $autoTopics = $self->AutoTopics();
        -
        -    my $scopeRecord = $self->ScopeRecord();
        -    if (defined $scopeRecord && !scalar @$scopeRecord)
        -        {  $scopeRecord = undef;  };
        -
        -    return ( $autoTopics, $scopeRecord );
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Statement Parsing Functions
        -# All functions here assume that the current position is at the beginning of a statement.
        -#
        -# Note for developers: I am well aware that the code in these functions do not check if we're past the end of the tokens as
        -# often as it should.  We're making use of the fact that Perl will always return undef in these cases to keep the code simpler.
        -
        -
        -#
        -#   Function: TryToGetNamespace
        -#
        -#   Determines whether the position is at a namespace declaration statement, and if so, adjusts the scope, skips it, and returns
        -#   true.
        -#
        -#   Why no topic?:
        -#
        -#       The main reason we don't create a Natural Docs topic for a namespace is because in order to declare class A.B.C in C#,
        -#       you must do this:
        -#
        -#       > namespace A.B
        -#       >    {
        -#       >    class C
        -#       >        { ... }
        -#       >    }
        -#
        -#       That would result in a namespace topic whose only purpose is really to qualify C.  It would take the default page title, and
        -#       thus the default menu title.  So if you have files for A.B.X, A.B.Y, and A.B.Z, they all will appear as A.B on the menu.
        -#
        -#       If something actually appears in the namespace besides a class, it will be handled by
        -#       <NaturalDocs::Parser->AddPackageDelineators()>.  That function will add a package topic to correct the scope.
        -#
        -#       If the user actually documented it, it will still appear because of the manual topic.
        -#
        -sub TryToGetNamespace #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if (lc($tokens->[$$indexRef]) ne 'namespace')
        -        {  return undef;  };
        -
        -    my $index = $$indexRef + 1;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
        -        {  return undef;  };
        -
        -    my $name;
        -
        -    while ($tokens->[$index] =~ /^[a-z_\.\@]/i)
        -        {
        -        $name .= $tokens->[$index];
        -        $index++;
        -        };
        -
        -    if (!defined $name)
        -        {  return undef;  };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    if ($tokens->[$index] ne '{')
        -        {  return undef;  };
        -
        -    $index++;
        -
        -
        -    # We found a valid one if we made it this far.
        -
        -    my $autoTopic = NaturalDocs::Parser::ParsedTopic->New(::TOPIC_CLASS(), $name,
        -                                                                                         $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                         undef,
        -                                                                                         undef, undef, $$lineNumberRef);
        -
        -    # We don't add an auto-topic for namespaces.  See the function documentation above.
        -
        -    NaturalDocs::Parser->OnClass($autoTopic->Package());
        -
        -    $self->StartScope('}', $lineNumber, $autoTopic->Package());
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetClass
        -#
        -#   Determines whether the position is at a class declaration statement, and if so, generates a topic for it, skips it, and
        -#   returns true.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Classes
        -#       - Structs
        -#       - Interfaces
        -#
        -sub TryToGetClass #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -    my $needsPrototype = 0;
        -
        -    if ($self->TryToSkipAttributes(\$index, \$lineNumber))
        -        {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
        -
        -    my @modifiers;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i &&
        -              !exists $classKeywords{lc($tokens->[$index])} &&
        -              exists $classModifiers{lc($tokens->[$index])} )
        -        {
        -        push @modifiers, lc($tokens->[$index]);
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -    if (!exists $classKeywords{lc($tokens->[$index])})
        -        {  return undef;  };
        -
        -    my $lcClassKeyword = lc($tokens->[$index]);
        -
        -    $index++;
        -
        -    if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
        -        {  return undef;  };
        -
        -    my $name;
        -
        -    while ($tokens->[$index] =~ /^[a-z_\@]/i)
        -        {
        -        $name .= $tokens->[$index];
        -        $index++;
        -        };
        -
        -    if (!defined $name)
        -        {  return undef;  };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -	if ($self->TryToSkipTemplateSpec(\$index, \$lineNumber))
        -		{
        -		$needsPrototype = 1;
        -		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -		if ($self->TryToSkipWhereClauses(\$index, \$lineNumber))
        -			{  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
        -		}
        -
        -    my @parents;
        -
        -    if ($tokens->[$index] eq ':')
        -        {
        -        my $inheritsTemplates;
        -
        -        do
        -            {
        -            $index++;
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -            my $parentName;
        -
        -            while ($tokens->[$index] =~ /^[a-z_\.\@]/i)
        -                {
        -                $parentName .= $tokens->[$index];
        -                $index++;
        -                };
        -
        -            if (!defined $parentName)
        -                {  return undef;  };
        -
        -            push @parents, NaturalDocs::SymbolString->FromText($parentName);
        -
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -            if ($self->TryToSkipTemplateSpec(\$index, \$lineNumber))
        -            	{
        -            	$inheritsTemplates = 1;
        -            	$needsPrototype = 1;
        -            	$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            	}
        -            }
        -        while ($tokens->[$index] eq ',');
        -
        -        if ($inheritsTemplates)
        -        	{
        -        	if ($self->TryToSkipWhereClauses(\$index, \$lineNumber))
        -        		{  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
        -        	}
        -        };
        -
        -    if ($tokens->[$index] ne '{')
        -        {  return undef;  };
        -
        -
        -    # If we made it this far, we have a valid class declaration.
        -
        -    my @scopeIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($self->CurrentScope());
        -    $name = join('.', @scopeIdentifiers, $name);
        -
        -    my $topicType;
        -
        -    if ($lcClassKeyword eq 'interface')
        -        {  $topicType = ::TOPIC_INTERFACE();  }
        -    else
        -        {  $topicType = ::TOPIC_CLASS();  };
        -
        -    my $prototype;
        -
        -    if ($needsPrototype)
        -            {
        -            $prototype = $self->CreateString($startIndex, $index);
        -            }
        -
        -    my $autoTopic = NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
        -                                                                                         undef, $self->CurrentUsing(),
        -                                                                                         $prototype,
        -                                                                                         undef, undef, $$lineNumberRef);
        -
        -    $self->AddAutoTopic($autoTopic);
        -    NaturalDocs::Parser->OnClass($autoTopic->Package());
        -
        -    foreach my $parent (@parents)
        -        {
        -        NaturalDocs::Parser->OnClassParent($autoTopic->Package(), $parent, $self->CurrentScope(), undef,
        -                                                               ::RESOLVE_RELATIVE());
        -        };
        -
        -    $self->StartScope('}', $lineNumber, $autoTopic->Package());
        -
        -    $index++;
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetUsing
        -#
        -#   Determines whether the position is at a using statement, and if so, adds it to the current scope, skips it, and returns
        -#        true.
        -#
        -#        Supported:
        -#
        -#       - Using
        -#
        -#        Unsupported:
        -#
        -#                - Using with alias
        -#
        -sub TryToGetUsing #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if (lc($tokens->[$index]) ne 'using')
        -        {  return undef;  };
        -
        -    $index++;
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my $name;
        -
        -    while ($tokens->[$index] =~ /^[a-z_\@\.]/i)
        -        {
        -        $name .= $tokens->[$index];
        -        $index++;
        -        };
        -
        -    if ($tokens->[$index] ne ';' ||
        -                !defined $name)
        -        {  return undef;  };
        -
        -    $index++;
        -
        -
        -    $self->AddUsing( NaturalDocs::SymbolString->FromText($name) );
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -
        -#
        -#   Function: TryToGetFunction
        -#
        -#   Determines if the position is on a function declaration, and if so, generates a topic for it, skips it, and returns true.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Functions
        -#       - Constructors
        -#       - Destructors
        -#       - Properties
        -#       - Indexers
        -#       - Delegates
        -#       - Events
        -#
        -sub TryToGetFunction #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if ($self->TryToSkipAttributes(\$index, \$lineNumber))
        -        {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -
        -    my @modifiers;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i &&
        -              exists $functionModifiers{lc($tokens->[$index])} )
        -        {
        -        push @modifiers, lc($tokens->[$index]);
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -    my $isDelegate;
        -    my $isEvent;
        -
        -    if (lc($tokens->[$index]) eq 'delegate')
        -        {
        -        $isDelegate = 1;
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        }
        -    elsif (lc($tokens->[$index]) eq 'event')
        -        {
        -        $isEvent = 1;
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -    my $returnType = $self->TryToGetType(\$index, \$lineNumber);
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my $name;
        -    my $lastNameWord;
        -    my $hasTemplates;
        -
        -    while ($tokens->[$index] =~ /^[a-z\_\@\.\~]/i)
        -        {
        -        $name .= $tokens->[$index];
        -        $lastNameWord = $tokens->[$index];
        -        $index++;
        -
        -        # For explicit generic interface definitions, such as
        -        # IDObjectType System.Collections.Generic.IEnumerator<IDObjectType>.Current
        -        # or templated functions.
        -
        -        if ($self->TryToSkipTemplateSpec(\$index, \$lineNumber))
        -        	{
        -        	$hasTemplates = 1;
        -        	$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        	}
        -        };
        -
        -    if (!defined $name)
        -        {
        -        # Constructors and destructors don't have return types.  It's possible their names were mistaken for the return type.
        -        if (defined $returnType)
        -            {
        -            $name = $returnType;
        -            $returnType = undef;
        -
        -            $name =~ /([a-z0-9_]+)$/i;
        -            $lastNameWord = $1;
        -            }
        -        else
        -            {  return undef;  };
        -        };
        -
        -    # If there's no return type, make sure it's a constructor or destructor.
        -    if (!defined $returnType)
        -        {
        -        my @identifiers = NaturalDocs::SymbolString->IdentifiersOf( $self->CurrentScope() );
        -
        -        if ($lastNameWord ne $identifiers[-1])
        -            {  return undef;  };
        -        };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -
        -    # Skip the brackets on indexers.
        -    if ($tokens->[$index] eq '[' && lc($lastNameWord) eq 'this')
        -        {
        -        # This should jump the brackets completely.
        -        $self->GenericSkip(\$index, \$lineNumber);
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        $name .= '[]';
        -        };
        -
        -
        -    # Properties, indexers, events with braces
        -
        -    if ($tokens->[$index] eq '{')
        -        {
        -        my $prototype = $self->CreateString($startIndex, $index);
        -
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        my ($aWord, $bWord, $hasA, $hasB);
        -
        -        if ($isEvent)
        -            {
        -            $aWord = 'add';
        -            $bWord = 'remove';
        -            }
        -        else
        -            {
        -            $aWord = 'get';
        -            $bWord = 'set';
        -            };
        -
        -        while ($index < scalar @$tokens)
        -            {
        -            if ($self->TryToSkipAttributes(\$index, \$lineNumber))
        -                {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
        -
        -            if (lc($tokens->[$index]) eq $aWord)
        -                {  $hasA = 1;  }
        -            elsif (lc($tokens->[$index]) eq $bWord)
        -                {  $hasB = 1;  }
        -            elsif ($tokens->[$index] eq '}')
        -                {
        -                $index++;
        -                last;
        -                };
        -
        -            $self->SkipRestOfStatement(\$index, \$lineNumber);
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            };
        -
        -        if ($hasA && $hasB)
        -            {  $prototype .= ' { ' . $aWord . ', ' . $bWord . ' }';  }
        -        elsif ($hasA)
        -            {  $prototype .= ' { ' . $aWord . ' }';  }
        -        elsif ($hasB)
        -            {  $prototype .= ' { ' . $bWord . ' }';  };
        -
        -        $prototype = $self->NormalizePrototype($prototype);
        -
        -        my $topicType = ( $isEvent ? ::TOPIC_EVENT() : ::TOPIC_PROPERTY() );
        -
        -        $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
        -                                                                                                  $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                                  $prototype,
        -                                                                                                  undef, undef, $startLine));
        -        }
        -
        -
        -    # Functions, constructors, destructors, delegates.
        -
        -    elsif ($tokens->[$index] eq '(')
        -        {
        -        # This should jump the parenthesis completely.
        -        $self->GenericSkip(\$index, \$lineNumber);
        -		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if ($hasTemplates && $self->TryToSkipWhereClauses(\$index, \$lineNumber))
        -        	{  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
        -
        -        my $topicType = ( $isDelegate ? ::TOPIC_DELEGATE() : ::TOPIC_FUNCTION() );
        -        my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
        -
        -        $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
        -                                                                                                  $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                                  $prototype,
        -                                                                                                  undef, undef, $startLine));
        -
        -        $self->SkipRestOfStatement(\$index, \$lineNumber);
        -        }
        -
        -
        -    # Events without braces
        -
        -    elsif ($isEvent && $tokens->[$index] eq ';')
        -        {
        -        my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
        -
        -        $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_EVENT(), $name,
        -                                                                                                  $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                                  $prototype,
        -                                                                                                  undef, undef, $startLine));
        -        $index++;
        -        }
        -
        -    else
        -        {  return undef;  };
        -
        -
        -    # We succeeded if we got this far.
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetOverloadedOperator
        -#
        -#   Determines if the position is on an operator overload declaration, and if so, generates a topic for it, skips it, and returns true.
        -#
        -sub TryToGetOverloadedOperator #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if ($self->TryToSkipAttributes(\$index, \$lineNumber))
        -        {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -
        -    my @modifiers;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i &&
        -              exists $functionModifiers{lc($tokens->[$index])} )
        -        {
        -        push @modifiers, lc($tokens->[$index]);
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -
        -    my $name;
        -
        -
        -    # Casting operators.
        -
        -    if (lc($tokens->[$index]) eq 'implicit' || lc($tokens->[$index]) eq 'explicit')
        -        {
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if (lc($tokens->[$index]) ne 'operator')
        -            {  return undef;  };
        -
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        $name = $self->TryToGetType(\$index, \$lineNumber);
        -
        -        if (!defined $name)
        -            {  return undef;  };
        -        }
        -
        -
        -    # Symbol operators.
        -
        -    else
        -        {
        -        if (!$self->TryToGetType(\$index, \$lineNumber))
        -            {  return undef;  };
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if (lc($tokens->[$index]) ne 'operator')
        -            {  return undef;  };
        -
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if (lc($tokens->[$index]) eq 'true' || lc($tokens->[$index]) eq 'false')
        -            {
        -            $name = $tokens->[$index];
        -            $index++;
        -            }
        -        else
        -            {
        -            while ($tokens->[$index] =~ /^[\+\-\!\~\*\/\%\&\|\^\<\>\=]$/)
        -                {
        -                $name .= $tokens->[$index];
        -                $index++;
        -                };
        -            };
        -        };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    if ($tokens->[$index] ne '(')
        -        {  return undef;  };
        -
        -    # This should skip the parenthesis completely.
        -    $self->GenericSkip(\$index, \$lineNumber);
        -
        -    my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
        -
        -    $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_FUNCTION(), 'operator ' . $name,
        -                                                                                              $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                              $prototype,
        -                                                                                              undef, undef, $startLine));
        -
        -    $self->SkipRestOfStatement(\$index, \$lineNumber);
        -
        -
        -    # We succeeded if we got this far.
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetVariable
        -#
        -#   Determines if the position is on a variable declaration statement, and if so, generates a topic for each variable, skips the
        -#   statement, and returns true.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Variables
        -#       - Constants
        -#
        -sub TryToGetVariable #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if ($self->TryToSkipAttributes(\$index, \$lineNumber))
        -        {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -
        -    my @modifiers;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i &&
        -              exists $variableModifiers{lc($tokens->[$index])} )
        -        {
        -        push @modifiers, lc($tokens->[$index]);
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -    my $type;
        -    if (lc($tokens->[$index]) eq 'const')
        -        {
        -        $type = ::TOPIC_CONSTANT();
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        }
        -    else
        -        {
        -        $type = ::TOPIC_VARIABLE();
        -        };
        -
        -    if (!$self->TryToGetType(\$index, \$lineNumber))
        -        {  return undef;  };
        -
        -    my $endTypeIndex = $index;
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my @names;
        -
        -    for (;;)
        -        {
        -        my $name;
        -
        -        while ($tokens->[$index] =~ /^[a-z\@\_]/i)
        -            {
        -            $name .= $tokens->[$index];
        -            $index++;
        -            };
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if ($tokens->[$index] eq '=')
        -            {
        -            do
        -                {
        -                $self->GenericSkip(\$index, \$lineNumber);
        -                }
        -            while ($tokens->[$index] ne ',' && $tokens->[$index] ne ';');
        -            };
        -
        -        push @names, $name;
        -
        -        if ($tokens->[$index] eq ';')
        -            {
        -            $index++;
        -            last;
        -            }
        -        elsif ($tokens->[$index] eq ',')
        -            {
        -            $index++;
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            }
        -        else
        -            {  return undef;  };
        -        };
        -
        -
        -    # We succeeded if we got this far.
        -
        -    my $prototypePrefix = $self->CreateString($startIndex, $endTypeIndex);
        -
        -    foreach my $name (@names)
        -        {
        -        my $prototype = $self->NormalizePrototype( $prototypePrefix . ' ' . $name );
        -
        -        $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($type, $name,
        -                                                                                                  $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                                  $prototype,
        -                                                                                                  undef, undef, $startLine));
        -        };
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetEnum
        -#
        -#   Determines if the position is on an enum declaration statement, and if so, generates a topic for it.
        -#
        -#   Supported Syntaxes:
        -#
        -#       - Enums
        -#       - Enums with declared types
        -#
        -#   Unsupported:
        -#
        -#       - Documenting the members automatically
        -#
        -sub TryToGetEnum #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if ($self->TryToSkipAttributes(\$index, \$lineNumber))
        -        {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
        -
        -    my $startIndex = $index;
        -    my $startLine = $lineNumber;
        -
        -    my @modifiers;
        -
        -    while ($tokens->[$index] =~ /^[a-z]/i &&
        -              exists $variableModifiers{lc($tokens->[$index])} )
        -        {
        -        push @modifiers, lc($tokens->[$index]);
        -        $index++;
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        };
        -
        -    if (lc($tokens->[$index]) ne 'enum')
        -        {  return undef;  }
        -
        -    $index++;
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    my $name;
        -
        -    while ($tokens->[$index] =~ /^[a-z\@\_]/i)
        -        {
        -        $name .= $tokens->[$index];
        -        $index++;
        -        };
        -
        -    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -    if ($tokens->[$index] eq ':')
        -        {
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if (!exists $enumTypes{ lc($tokens->[$index]) })
        -            {  return undef;  }
        -
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        }
        -
        -    if ($tokens->[$index] ne '{')
        -        {  return undef;  }
        -
        -    # We succeeded if we got this far.
        -
        -    my $prototype = $self->CreateString($startIndex, $index);
        -    $prototype = $self->NormalizePrototype( $prototype );
        -
        -    $self->SkipRestOfStatement(\$index, \$lineNumber);
        -
        -    $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_ENUMERATION(), $name,
        -                                                                                              $self->CurrentScope(), $self->CurrentUsing(),
        -                                                                                              $prototype,
        -                                                                                              undef, undef, $startLine));
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: TryToGetType
        -#
        -#   Determines if the position is on a type identifier, and if so, skips it and returns it as a string.  This function does _not_ allow
        -#   modifiers.  You must take care of those beforehand.
        -#
        -sub TryToGetType #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $name;
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    while ($tokens->[$index] =~ /^[a-z\@\.\_]/i)
        -        {
        -		# Case sensitive since you can declare a class Lock even though lock is a keyword.
        -        if (exists $impossibleTypeWords{ $tokens->[$index] } && $name !~ /\@$/)
        -            {  return undef;  };
        -
        -        $name .= $tokens->[$index];
        -        $index++;
        -        };
        -
        -    if (!defined $name)
        -        {  return undef;  };
        -
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if ($tokens->[$index] eq '?')
        -                {
        -                $name .= '?';
        -                $index++;
        -
        -                $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -                }
        -
        -    if ($self->TryToSkipTemplateSpec(\$index, \$lineNumber))
        -    	{  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
        -
        -    while ($tokens->[$index] eq '[')
        -        {
        -        $name .= '[';
        -        $index++;
        -
        -        while ($tokens->[$index] eq ',')
        -            {
        -            $name .= ',';
        -            $index++;
        -            };
        -
        -        if ($tokens->[$index] eq ']')
        -            {
        -            $name .= ']';
        -            $index++;
        -            }
        -        else
        -            {  return undef;  }
        -        };
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return $name;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Low Level Parsing Functions
        -
        -
        -#
        -#   Function: GenericSkip
        -#
        -#   Advances the position one place through general code.
        -#
        -#   - If the position is on a string, it will skip it completely.
        -#   - If the position is on an opening symbol, it will skip until the past the closing symbol.
        -#   - If the position is on whitespace (including comments and preprocessing directives), it will skip it completely.
        -#   - Otherwise it skips one token.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the current index.
        -#       lineNumberRef - A reference to the current line number.
        -#
        -sub GenericSkip #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # We can ignore the scope stack because we're just skipping everything without parsing, and we need recursion anyway.
        -    if ($tokens->[$$indexRef] eq '{')
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
        -        }
        -    elsif ($tokens->[$$indexRef] eq '(')
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ')');
        -        }
        -    elsif ($tokens->[$$indexRef] eq '[')
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
        -        }
        -
        -    elsif ($self->TryToSkipWhitespace($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipString($indexRef, $lineNumberRef))
        -        {
        -        }
        -
        -    else
        -        {  $$indexRef++;  };
        -    };
        -
        -
        -#
        -#   Function: GenericSkipUntilAfter
        -#
        -#   Advances the position via <GenericSkip()> until a specific token is reached and passed.
        -#
        -sub GenericSkipUntilAfter #(indexRef, lineNumberRef, token)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $token) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne $token)
        -        {  $self->GenericSkip($indexRef, $lineNumberRef);  };
        -
        -    if ($tokens->[$$indexRef] eq "\n")
        -        {  $$lineNumberRef++;  };
        -    $$indexRef++;
        -    };
        -
        -
        -#
        -#   Function: SkipRestOfStatement
        -#
        -#   Advances the position via <GenericSkip()> until after the end of the current statement, which is defined as a semicolon or
        -#   a brace group.  Of course, either of those appearing inside parenthesis, a nested brace group, etc. don't count.
        -#
        -sub SkipRestOfStatement #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens &&
        -             $tokens->[$$indexRef] ne ';' &&
        -             $tokens->[$$indexRef] ne '{')
        -        {
        -        $self->GenericSkip($indexRef, $lineNumberRef);
        -        };
        -
        -    if ($tokens->[$$indexRef] eq ';')
        -        {  $$indexRef++;  }
        -    elsif ($tokens->[$$indexRef] eq '{')
        -        {  $self->GenericSkip($indexRef, $lineNumberRef);  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipString
        -#   If the current position is on a string delimiter, skip past the string and return true.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the index of the position to start at.
        -#       lineNumberRef - A reference to the line number of the position.
        -#
        -#   Returns:
        -#
        -#       Whether the position was at a string.
        -#
        -#   Syntax Support:
        -#
        -#       - Supports quotes, apostrophes, and at-quotes.
        -#
        -sub TryToSkipString #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # The three string delimiters.  All three are Perl variables when preceded by a dollar sign.
        -    if ($self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '\'') ||
        -        $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '"') )
        -        {
        -        return 1;
        -        }
        -    elsif ($tokens->[$$indexRef] eq '@' && $tokens->[$$indexRef+1] eq '"')
        -        {
        -        $$indexRef += 2;
        -
        -        # We need to do at-strings manually because backslash characters are accepted as regular characters, and two consecutive
        -        # quotes are accepted as well.
        -
        -        while ($$indexRef < scalar @$tokens && !($tokens->[$$indexRef] eq '"' && $tokens->[$$indexRef+1] ne '"') )
        -            {
        -            if ($tokens->[$$indexRef] eq '"')
        -                {
        -                # This is safe because the while condition will only let through quote pairs.
        -                $$indexRef += 2;
        -                }
        -            elsif ($tokens->[$$indexRef] eq "\n")
        -                {
        -                $$indexRef++;
        -                $$lineNumberRef++;
        -                }
        -            else
        -                {
        -                $$indexRef++;
        -                };
        -            };
        -
        -        # Skip the closing quote.
        -        if ($$indexRef < scalar @$tokens)
        -            {  $$indexRef++;  };
        -
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipAttributes
        -#   If the current position is on an attribute section, skip it and return true.  Skips multiple attribute sections if they appear
        -#   consecutively.
        -#
        -sub TryToSkipAttributes #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $success;
        -
        -    while ($tokens->[$$indexRef] eq '[')
        -        {
        -        $success = 1;
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
        -        $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -        };
        -
        -    return $success;
        -    };
        -
        -
        -#
        -#	Function: TryToSkipTemplateSpec
        -#	If the current position is on a template spec (the part in angle brackets) skip it and return true.  Can handle nested
        -#	templates.
        -#
        -sub TryToSkipTemplateSpec #(indexRef, lineNumberRef)
        -	{
        -	my ($self, $indexRef, $lineNumberRef) = @_;
        -	my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '<')
        -        {
        -        my $nestingLevel = 1;
        -        $$indexRef++;
        -        $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -
        -        while ($$indexRef < scalar @$tokens && $nestingLevel > 0)
        -        	{
        -        	if ($tokens->[$$indexRef] eq '<')
        -        		{  $nestingLevel++;  }
        -        	elsif ($tokens->[$$indexRef] eq '>')
        -        		{  $nestingLevel--;  }
        -
        -            $$indexRef++;
        -        	$self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -			}
        -
        -		return 1;
        -        }
        -    else
        -    	{  return undef;  }
        -	}
        -
        -
        -#
        -#	Function: TryToSkipWhereClauses
        -#	If the current position is on a "where" clause, skips it and returns true.  Can handle multiple wheres in a row.
        -#
        -sub TryToSkipWhereClauses #(indexRef, lineNumberRef)
        -	{
        -	my ($self, $indexRef, $lineNumberRef) = @_;
        -	my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] ne 'where')
        -    	{  return undef;  }
        -
        -	my $index = $$indexRef;
        -	my $lineNumber = $$lineNumberRef;
        -
        -    do
        -        {
        -        $index++;  # Skip the where
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        $index++;  # Skip the variable name
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        if ($tokens->[$index] ne ':')
        -        	{  return undef;  }
        -
        -        $index++;  # Skip the colon
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        for (;;)
        -        	{
        -        	if ($index >= scalar @$tokens)
        -        		{  return undef;  }
        -        	elsif ($tokens->[$index] eq 'new')
        -        		{
        -        		$index++;
        -        		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        		if ($tokens->[$index] ne '(')
        -        			{  return undef;  }
        -
        -                $index++;
        -        		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        		if ($tokens->[$index] ne ')')
        -        			{  return undef;  }
        -
        -        		$index++;
        -        		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        		}
        -        	else
        -        		{
        -        		while ($index < scalar @$tokens && $tokens->[$index] =~ /^[a-z0-9_\.\@]+$/i)
        -        			{  $index++;  }
        -
        -        		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        		if ($self->TryToSkipTemplateSpec(\$index, \$lineNumber))
        -        			{  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
        -        		}
        -
        -        	if ($tokens->[$index] eq ',')
        -        		{
        -        		$index++;
        -        		$self->TryToSkipWhitespace(\$index, \$lineNumber);
        -        		}
        -        	else
        -        		{  last;  }
        -        	}
        -        }
        -    while ($tokens->[$index] eq 'where');
        -
        -    $$indexRef = $index;
        -    $$lineNumberRef = $lineNumber;
        -
        -    return 1;
        -	}
        -
        -
        -#
        -#   Function: TryToSkipWhitespace
        -#   If the current position is on a whitespace token, a line break token, a comment, or a preprocessing directive, it skips them
        -#   and returns true.  If there are a number of these in a row, it skips them all.
        -#
        -sub TryToSkipWhitespace #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $result;
        -
        -    while ($$indexRef < scalar @$tokens)
        -        {
        -        if ($tokens->[$$indexRef] =~ /^[ \t]/)
        -            {
        -            $$indexRef++;
        -            $result = 1;
        -            }
        -        elsif ($tokens->[$$indexRef] eq "\n")
        -            {
        -            $$indexRef++;
        -            $$lineNumberRef++;
        -            $result = 1;
        -            }
        -        elsif ($self->TryToSkipComment($indexRef, $lineNumberRef) ||
        -                $self->TryToSkipPreprocessingDirective($indexRef, $lineNumberRef))
        -            {
        -            $result = 1;
        -            }
        -        else
        -            {  last;  };
        -        };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: TryToSkipComment
        -#   If the current position is on a comment, skip past it and return true.
        -#
        -sub TryToSkipComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -
        -    return ( $self->TryToSkipLineComment($indexRef, $lineNumberRef) ||
        -                $self->TryToSkipMultilineComment($indexRef, $lineNumberRef) );
        -    };
        -
        -
        -#
        -#   Function: TryToSkipLineComment
        -#   If the current position is on a line comment symbol, skip past it and return true.
        -#
        -sub TryToSkipLineComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '/')
        -        {
        -        $self->SkipRestOfLine($indexRef, $lineNumberRef);
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipMultilineComment
        -#   If the current position is on an opening comment symbol, skip past it and return true.
        -#
        -sub TryToSkipMultilineComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '*')
        -        {
        -        $self->SkipUntilAfter($indexRef, $lineNumberRef, '*', '/');
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipPreprocessingDirective
        -#   If the current position is on a preprocessing directive, skip past it and return true.
        -#
        -sub TryToSkipPreprocessingDirective #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq '#' && $self->IsFirstLineToken($$indexRef))
        -        {
        -        $self->SkipRestOfLine($indexRef, $lineNumberRef);
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/PLSQL.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/PLSQL.pm
        deleted file mode 100644
        index c72db78cb..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/PLSQL.pm
        +++ /dev/null
        @@ -1,320 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::PLSQL
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of PL/SQL.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::PLSQL;
        -
        -use base 'NaturalDocs::Languages::Simple';
        -
        -
        -#
        -#   Function: OnPrototypeEnd
        -#
        -#   Microsoft's SQL specifies parameters as shown below.
        -#
        -#   > CREATE PROCEDURE Test @as int, @foo int AS ...
        -#
        -#   Having a parameter @is or @as is perfectly valid even though those words are also used to end the prototype.  We need to
        -#   ignore text-based enders preceded by an at sign.  Also note that it does not have parenthesis for parameter lists.  We need to
        -#   skip all commas if the prototype doesn't have parenthesis but does have @ characters.
        -#
        -#	Identifiers such as function names may contain the characters $, #, and _, so if "as" or "is" appears directly after one of them
        -#	we need to ignore the ender there as well.
        -#
        -#	> FUNCTION Something_is_something ...
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> of the prototype.
        -#       prototypeRef - A reference to the prototype so far, minus the ender in dispute.
        -#       ender - The ender symbol.
        -#
        -#   Returns:
        -#
        -#       ENDER_ACCEPT - The ender is accepted and the prototype is finished.
        -#       ENDER_IGNORE - The ender is rejected and parsing should continue.  Note that the prototype will be rejected as a whole
        -#                                  if all enders are ignored before reaching the end of the code.
        -#       ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is.  However, the prototype might
        -#                                                          also continue on so continue parsing.  If there is no accepted ender between here and
        -#                                                          the end of the code this version will be accepted instead.
        -#       ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed.  Use the last accepted
        -#                                                        version and end parsing.
        -#
        -sub OnPrototypeEnd #(type, prototypeRef, ender)
        -    {
        -    my ($self, $type, $prototypeRef, $ender) = @_;
        -
        -    # _ should be handled already.
        -    if ($ender =~ /^[a-z]+$/i && substr($$prototypeRef, -1) =~ /^[\@\$\#]$/)
        -        {  return ::ENDER_IGNORE();  }
        -
        -    elsif ($type eq ::TOPIC_FUNCTION() && $ender eq ',')
        -        {
        -        if ($$prototypeRef =~ /^[^\(]*\@/)
        -            {  return ::ENDER_IGNORE();  }
        -        else
        -            {  return ::ENDER_ACCEPT();  };
        -        }
        -
        -    else
        -        {  return ::ENDER_ACCEPT();  };
        -    };
        -
        -
        -#
        -#   Function: ParsePrototype
        -#
        -#   Overridden to handle Microsoft's parenthesisless version.  Otherwise just throws to the parent.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType>.
        -#       prototype - The text prototype.
        -#
        -#   Returns:
        -#
        -#       A <NaturalDocs::Languages::Prototype> object.
        -#
        -sub ParsePrototype #(type, prototype)
        -    {
        -    my ($self, $type, $prototype) = @_;
        -
        -    my $noParenthesisParameters = ($type eq ::TOPIC_FUNCTION() && $prototype =~ /^[^\(]*\@/);
        -
        -    if ($prototype !~ /\(.*[^ ].*\)/ && !$noParenthesisParameters)
        -        {  return $self->SUPER::ParsePrototype($type, $prototype);  };
        -
        -
        -
        -    my ($beforeParameters, $afterParameters, $isAfterParameters);
        -
        -    if ($noParenthesisParameters)
        -        {
        -        ($beforeParameters, $prototype) = split(/\@/, $prototype, 2);
        -        $prototype = '@' . $prototype;
        -        };
        -
        -    my @tokens = $prototype =~ /([^\(\)\[\]\{\}\<\>\'\"\,]+|.)/g;
        -
        -    my $parameter;
        -    my @parameterLines;
        -
        -    my @symbolStack;
        -
        -    foreach my $token (@tokens)
        -        {
        -        if ($isAfterParameters)
        -            {  $afterParameters .= $token;  }
        -
        -        elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
        -            {
        -            if ($noParenthesisParameters || $symbolStack[0] eq '(')
        -                {  $parameter .= $token;  }
        -            else
        -                {  $beforeParameters .= $token;  };
        -
        -            if ($token eq $symbolStack[-1])
        -                {  pop @symbolStack;  };
        -            }
        -
        -        elsif ($token =~ /^[\(\[\{\<\'\"]$/)
        -            {
        -            if ($noParenthesisParameters || $symbolStack[0] eq '(')
        -                {  $parameter .= $token;  }
        -            else
        -                {  $beforeParameters .= $token;  };
        -
        -            push @symbolStack, $token;
        -            }
        -
        -        elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
        -                 ($token eq ']' && $symbolStack[-1] eq '[') ||
        -                 ($token eq '}' && $symbolStack[-1] eq '{') ||
        -                 ($token eq '>' && $symbolStack[-1] eq '<') )
        -            {
        -            if (!$noParenthesisParameters && $token eq ')' && scalar @symbolStack == 1 && $symbolStack[0] eq '(')
        -                {
        -                $afterParameters .= $token;
        -                $isAfterParameters = 1;
        -                }
        -            else
        -                {  $parameter .= $token;  };
        -
        -            pop @symbolStack;
        -            }
        -
        -        elsif ($token eq ',')
        -            {
        -            if (!scalar @symbolStack)
        -                {
        -                if ($noParenthesisParameters)
        -                    {
        -                    push @parameterLines, $parameter . $token;
        -                    $parameter = undef;
        -                    }
        -                else
        -                    {
        -                    $beforeParameters .= $token;
        -                    };
        -                }
        -            else
        -                {
        -                if (scalar @symbolStack == 1 && $symbolStack[0] eq '(' && !$noParenthesisParameters)
        -                    {
        -                    push @parameterLines, $parameter . $token;
        -                    $parameter = undef;
        -                    }
        -                else
        -                    {
        -                    $parameter .= $token;
        -                    };
        -                };
        -            }
        -
        -        else
        -            {
        -            if ($noParenthesisParameters || $symbolStack[0] eq '(')
        -                {  $parameter .= $token;  }
        -            else
        -                {  $beforeParameters .= $token;  };
        -            };
        -        };
        -
        -    push @parameterLines, $parameter;
        -
        -    foreach my $item (\$beforeParameters, \$afterParameters)
        -        {
        -        $$item =~ s/^ //;
        -        $$item =~ s/ $//;
        -        }
        -
        -    my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
        -
        -
        -    # Parse the actual parameters.
        -
        -    foreach my $parameterLine (@parameterLines)
        -        {
        -        $prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
        -        };
        -
        -    return $prototypeObject;
        -    };
        -
        -
        -#
        -#   Function: ParseParameterLine
        -#
        -#   Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
        -#
        -sub ParseParameterLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -
        -    $line =~ s/^ //;
        -    $line =~ s/ $//;
        -
        -    my @tokens = $line =~ /([^\(\)\[\]\{\}\<\>\'\"\:\=\ ]+|\:\=|.)/g;
        -
        -    my ($name, $type, $defaultValue, $defaultValuePrefix, $inType, $inDefaultValue);
        -
        -
        -    my @symbolStack;
        -
        -    foreach my $token (@tokens)
        -        {
        -        if ($inDefaultValue)
        -            {  $defaultValue .= $token;  }
        -
        -        elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
        -            {
        -            if ($inType)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -
        -            if ($token eq $symbolStack[-1])
        -                {  pop @symbolStack;  };
        -            }
        -
        -        elsif ($token =~ /^[\(\[\{\<\'\"]$/)
        -            {
        -            if ($inType)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -
        -            push @symbolStack, $token;
        -            }
        -
        -        elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
        -                 ($token eq ']' && $symbolStack[-1] eq '[') ||
        -                 ($token eq '}' && $symbolStack[-1] eq '{') ||
        -                 ($token eq '>' && $symbolStack[-1] eq '<') )
        -            {
        -            if ($inType)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -
        -            pop @symbolStack;
        -            }
        -
        -        elsif ($token eq ' ')
        -            {
        -            if ($inType)
        -                {  $type .= $token;  }
        -            elsif (!scalar @symbolStack)
        -                {  $inType = 1;  }
        -            else
        -                {  $name .= $token;  };
        -            }
        -
        -        elsif ($token eq ':=' || $token eq '=')
        -            {
        -            if (!scalar @symbolStack)
        -                {
        -                $defaultValuePrefix = $token;
        -                $inDefaultValue = 1;
        -                }
        -            elsif ($inType)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -            }
        -
        -        else
        -            {
        -            if ($inType)
        -                {  $type .= $token;  }
        -            else
        -                {  $name .= $token;  };
        -            };
        -        };
        -
        -    foreach my $part (\$type, \$defaultValue)
        -        {
        -        $$part =~ s/ $//;
        -        };
        -
        -    return NaturalDocs::Languages::Prototype::Parameter->New($type, undef, $name, undef, $defaultValue, $defaultValuePrefix);
        -    };
        -
        -
        -sub TypeBeforeParameter
        -    {  return 0;  };
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Pascal.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Pascal.pm
        deleted file mode 100644
        index 69cf56784..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Pascal.pm
        +++ /dev/null
        @@ -1,144 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Pascal
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of Pascal and Delphi.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Pascal;
        -
        -use base 'NaturalDocs::Languages::Simple';
        -
        -
        -#
        -#   hash: prototypeDirectives
        -#
        -#   An existence hash of all the directives that can appear after a function prototype and will be included.  The keys are the all
        -#   lowercase keywords.
        -#
        -my %prototypeDirectives = ( 'overload' => 1,
        -                                           'override' => 1,
        -                                           'virtual' => 1,
        -                                           'abstract' => 1,
        -                                           'reintroduce' => 1,
        -                                           'export' => 1,
        -                                           'public' => 1,
        -                                           'interrupt' => 1,
        -                                           'register' => 1,
        -                                           'pascal' => 1,
        -                                           'cdecl' => 1,
        -                                           'stdcall' => 1,
        -                                           'popstack' => 1,
        -                                           'saveregisters' => 1,
        -                                           'inline' => 1,
        -                                           'safecall' => 1 );
        -
        -#
        -#   hash: longPrototypeDirectives
        -#
        -#   An existence hash of all the directives with parameters that can appear after a function prototype and will be included.  The
        -#   keys are the all lowercase keywords.
        -#
        -my %longPrototypeDirectives = ( 'alias' => 1,
        -                                                 'external' => 1 );
        -
        -#
        -#   bool: checkingForDirectives
        -#
        -#   Set after the first function semicolon, which means we're in directives mode.
        -#
        -my $checkingForDirectives;
        -
        -
        -#
        -#   Function: OnCode
        -#
        -#   Just overridden to reset <checkingForDirectives>.
        -#
        -sub OnCode #(...)
        -    {
        -    my ($self, @parameters) = @_;
        -
        -    $checkingForDirectives = 0;
        -
        -    return $self->SUPER::OnCode(@parameters);
        -    };
        -
        -
        -#
        -#   Function: OnPrototypeEnd
        -#
        -#   Pascal's syntax has directives after the prototype that should be included.
        -#
        -#   > function MyFunction ( param1: type ); virtual; abstract;
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> of the prototype.
        -#       prototypeRef - A reference to the prototype so far, minus the ender in dispute.
        -#       ender - The ender symbol.
        -#
        -#   Returns:
        -#
        -#       ENDER_ACCEPT - The ender is accepted and the prototype is finished.
        -#       ENDER_IGNORE - The ender is rejected and parsing should continue.  Note that the prototype will be rejected as a whole
        -#                                  if all enders are ignored before reaching the end of the code.
        -#       ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is.  However, the prototype might
        -#                                                          also continue on so continue parsing.  If there is no accepted ender between here and
        -#                                                          the end of the code this version will be accepted instead.
        -#       ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed.  Use the last accepted
        -#                                                        version and end parsing.
        -#
        -sub OnPrototypeEnd #(type, prototypeRef, ender)
        -    {
        -    my ($self, $type, $prototypeRef, $ender) = @_;
        -
        -    if ($type eq ::TOPIC_FUNCTION() && $ender eq ';')
        -        {
        -        if (!$checkingForDirectives)
        -            {
        -            $checkingForDirectives = 1;
        -            return ::ENDER_ACCEPT_AND_CONTINUE();
        -            }
        -        elsif ($$prototypeRef =~ /;[ \t]*([a-z]+)([^;]*)$/i)
        -            {
        -            my ($lastDirective, $extra) = (lc($1), $2);
        -
        -            if (exists $prototypeDirectives{$lastDirective} && $extra =~ /^[ \t]*$/)
        -                {  return ::ENDER_ACCEPT_AND_CONTINUE();  }
        -            elsif (exists $longPrototypeDirectives{$lastDirective})
        -                {  return ::ENDER_ACCEPT_AND_CONTINUE();  }
        -            else
        -                {  return ::ENDER_REVERT_TO_ACCEPTED();  };
        -            }
        -        else
        -            {  return ::ENDER_REVERT_TO_ACCEPTED();  };
        -        }
        -    else
        -        {  return ::ENDER_ACCEPT();  };
        -    };
        -
        -
        -sub ParseParameterLine #(...)
        -    {
        -    my ($self, @params) = @_;
        -    return $self->SUPER::ParsePascalParameterLine(@params);
        -    };
        -
        -sub TypeBeforeParameter
        -    {
        -    return 0;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Perl.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Perl.pm
        deleted file mode 100644
        index 5d971b8d5..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Perl.pm
        +++ /dev/null
        @@ -1,1371 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Perl
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of Perl.
        -#
        -#
        -#   Topic: Language Support
        -#
        -#       Supported:
        -#
        -#       - Packages
        -#       - Inheritance via "use base" and "@ISA =".
        -#       - Functions
        -#       - Variables
        -#
        -#       Not supported yet:
        -#
        -#       - Constants
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Perl;
        -
        -use base 'NaturalDocs::Languages::Advanced';
        -
        -
        -#
        -#   array: hereDocTerminators
        -#   An array of active Here Doc terminators, or an empty array if not active.  Each entry is an arrayref of tokens.  The entries
        -#   must appear in the order they must appear in the source.
        -#
        -my @hereDocTerminators;
        -
        -
        -
        -###############################################################################
        -# Group: Interface Functions
        -
        -
        -#
        -#   Function: PackageSeparator
        -#   Returns the package separator symbol.
        -#
        -sub PackageSeparator
        -    {  return '::';  };
        -
        -#
        -#   Function: EnumValues
        -#   Returns the <EnumValuesType> that describes how the language handles enums.
        -#
        -sub EnumValues
        -    {  return ::ENUM_GLOBAL();  };
        -
        -
        -#
        -#   Function: ParseFile
        -#
        -#   Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The name of the source file to parse.
        -#       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
        -#
        -#   Returns:
        -#
        -#       The array ( autoTopics, scopeRecord ).
        -#
        -#       autoTopics - An arrayref of automatically generated topics from the file, or undef if none.
        -#       scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
        -#
        -sub ParseFile #(sourceFile, topicsList)
        -    {
        -    my ($self, $sourceFile, $topicsList) = @_;
        -
        -    @hereDocTerminators = ( );
        -
        -    # The regular block comment symbols are undef because they're all potentially JavaDoc comments.  PreprocessFile() will
        -    # handle translating things like =begin naturaldocs and =begin javadoc to =begin nd.
        -    $self->ParseForCommentsAndTokens($sourceFile, [ '#' ], undef, [ '##' ], [ '=begin nd', '=end nd' ]);
        -
        -    my $tokens = $self->Tokens();
        -    my $index = 0;
        -    my $lineNumber = 1;
        -
        -    while ($index < scalar @$tokens)
        -        {
        -        if ($self->TryToSkipWhitespace(\$index, \$lineNumber) ||
        -            $self->TryToGetPackage(\$index, \$lineNumber) ||
        -            $self->TryToGetBase(\$index, \$lineNumber) ||
        -            $self->TryToGetFunction(\$index, \$lineNumber) ||
        -            $self->TryToGetVariable(\$index, \$lineNumber) )
        -            {
        -            # The functions above will handle everything.
        -            }
        -
        -        elsif ($tokens->[$index] eq '{')
        -            {
        -            $self->StartScope('}', $lineNumber, undef);
        -            $index++;
        -            }
        -
        -        elsif ($tokens->[$index] eq '}')
        -            {
        -            if ($self->ClosingScopeSymbol() eq '}')
        -                {  $self->EndScope($lineNumber);  };
        -
        -            $index++;
        -            }
        -
        -        elsif (lc($tokens->[$index]) eq 'eval')
        -            {
        -            # We want to skip the token in this case instead of letting it fall to SkipRestOfStatement.  This allows evals with braces
        -            # to be treated like normal floating braces.
        -            $index++;
        -            }
        -
        -        else
        -            {
        -            $self->SkipRestOfStatement(\$index, \$lineNumber);
        -            };
        -        };
        -
        -
        -    # Don't need to keep these around.
        -    $self->ClearTokens();
        -
        -    return ( $self->AutoTopics(), $self->ScopeRecord() );
        -    };
        -
        -
        -#
        -#   Function: PreprocessFile
        -#
        -#   Overridden to support "=begin nd" and similar.
        -#
        -#   - "=begin [nd|naturaldocs|natural docs|jd|javadoc|java doc]" all translate to "=begin nd".
        -#   - "=[nd|naturaldocs|natural docs]" also translate to "=begin nd".
        -#   - "=end [nd|naturaldocs|natural docs|jd|javadoc]" all translate to "=end nd".
        -#   - "=cut" from a ND block translates into "=end nd", but the next line will be altered to begin with "(NDPODBREAK)".  This is
        -#     so if there is POD leading into ND which ends with a cut, the parser can still end the original POD because the end ND line
        -#     would have been removed.  Remember, <NaturalDocs::Languages::Advanced->ParseForCommentsAndTokens()> removes
        -#     Natural Docs-worthy comments to save parsing time.
        -#   - "=pod begin nd" and "=pod end nd" are supported for compatibility with ND 1.32 and earlier, even though the syntax is a
        -#     mistake.
        -#   - It also supports the wrong plural forms, so naturaldoc/natural doc/javadocs/java docs will work.
        -#
        -sub PreprocessFile #(lines)
        -    {
        -    my ($self, $lines) = @_;
        -
        -    my $inNDPOD = 0;
        -    my $mustBreakPOD = 0;
        -
        -    for (my $i = 0; $i < scalar @$lines; $i++)
        -        {
        -        if ($lines->[$i] =~ /^\=(?:(?:pod[ \t]+)?begin[ \t]+)?(?:nd|natural[ \t]*docs?|jd|java[ \t]*docs?)[ \t]*$/i)
        -            {
        -            $lines->[$i] = '=begin nd';
        -            $inNDPOD = 1;
        -            $mustBreakPOD = 0;
        -            }
        -        elsif ($lines->[$i] =~ /^\=(?:pod[ \t]+)end[ \t]+(?:nd|natural[ \t]*docs?|jd|javadocs?)[ \t]*$/i)
        -            {
        -            $lines->[$i] = '=end nd';
        -            $inNDPOD = 0;
        -            $mustBreakPOD = 0;
        -            }
        -        elsif ($lines->[$i] =~ /^\=cut[ \t]*$/i)
        -            {
        -            if ($inNDPOD)
        -                {
        -                $lines->[$i] = '=end nd';
        -                $inNDPOD = 0;
        -                $mustBreakPOD = 1;
        -                };
        -            }
        -        elsif ($mustBreakPOD)
        -            {
        -            $lines->[$i] = '(NDPODBREAK)' . $lines->[$i];
        -            $mustBreakPOD = 0;
        -            };
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Statement Parsing Functions
        -# All functions here assume that the current position is at the beginning of a statement.
        -#
        -# Note for developers: I am well aware that the code in these functions do not check if we're past the end of the tokens as
        -# often as it should.  We're making use of the fact that Perl will always return undef in these cases to keep the code simpler.
        -
        -
        -#
        -#   Function: TryToGetPackage
        -#
        -#   Determines whether the position is at a package declaration statement, and if so, generates a topic for it, skips it, and
        -#   returns true.
        -#
        -sub TryToGetPackage #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if (lc($tokens->[$$indexRef]) eq 'package')
        -        {
        -        my $index = $$indexRef + 1;
        -        my $lineNumber = $$lineNumberRef;
        -
        -        if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
        -            {  return undef;  };
        -
        -        my $name;
        -
        -        while ($tokens->[$index] =~ /^[a-z_\:]/i)
        -            {
        -            $name .= $tokens->[$index];
        -            $index++;
        -            };
        -
        -        if (!defined $name)
        -            {  return undef;  };
        -
        -        my $autoTopic = NaturalDocs::Parser::ParsedTopic->New(::TOPIC_CLASS(), $name,
        -                                                                                             undef, undef,
        -                                                                                             undef,
        -                                                                                             undef, undef, $$lineNumberRef);
        -        $self->AddAutoTopic($autoTopic);
        -
        -        NaturalDocs::Parser->OnClass($autoTopic->Symbol());
        -
        -        $self->SetPackage($autoTopic->Symbol(), $$lineNumberRef);
        -
        -        $$indexRef = $index;
        -        $$lineNumberRef = $lineNumber;
        -        $self->SkipRestOfStatement($indexRef, $lineNumberRef);
        -
        -        return 1;
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: TryToGetBase
        -#
        -#   Determines whether the position is at a package base declaration statement, and if so, calls
        -#   <NaturalDocs::Parser->OnClassParent()>.
        -#
        -#   Supported Syntaxes:
        -#
        -#   > use base [list of strings]
        -#   > @ISA = [list of strings]
        -#   > @[package]::ISA = [list of strings]
        -#   > our @ISA = [list of strings]
        -#
        -sub TryToGetBase #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my ($index, $lineNumber, $class, $parents);
        -
        -    if (lc($tokens->[$$indexRef]) eq 'use')
        -        {
        -        $index = $$indexRef + 1;
        -        $lineNumber = $$lineNumberRef;
        -
        -        if (!$self->TryToSkipWhitespace(\$index, \$lineNumber) ||
        -           lc($tokens->[$index]) ne 'base')
        -            {  return undef;  }
        -
        -        $index++;
        -        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -        $parents = $self->TryToGetListOfStrings(\$index, \$lineNumber);
        -        }
        -
        -    else
        -        {
        -        $index = $$indexRef;
        -        $lineNumber = $$lineNumberRef;
        -
        -        if (lc($tokens->[$index]) eq 'our')
        -            {
        -            $index++;
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -            };
        -
        -        if ($tokens->[$index] eq '@')
        -            {
        -            $index++;
        -
        -            while ($index < scalar @$tokens)
        -                {
        -                if ($tokens->[$index] eq 'ISA')
        -                    {
        -                    $index++;
        -                    $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -                    if ($tokens->[$index] eq '=')
        -                        {
        -                        $index++;
        -                        $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -                        $parents = $self->TryToGetListOfStrings(\$index, \$lineNumber);
        -                        }
        -                    else
        -                        {  last;  };
        -                    }
        -
        -                # If token isn't ISA...
        -                elsif ($tokens->[$index] =~ /^[a-z0-9_:]/i)
        -                    {
        -                    $class .= $tokens->[$index];
        -                    $index++;
        -                    }
        -                else
        -                    {  last;  };
        -                };
        -            };
        -        };
        -
        -    if (defined $parents)
        -        {
        -        if (defined $class)
        -            {
        -            $class =~ s/::$//;
        -            my @classIdentifiers = split(/::/, $class);
        -            $class = NaturalDocs::SymbolString->Join(@classIdentifiers);
        -            }
        -        else
        -            {  $class = $self->CurrentScope();  };
        -
        -        foreach my $parent (@$parents)
        -            {
        -            my @parentIdentifiers = split(/::/, $parent);
        -            my $parentSymbol = NaturalDocs::SymbolString->Join(@parentIdentifiers);
        -
        -            NaturalDocs::Parser->OnClassParent($class, $parentSymbol, undef, undef, ::RESOLVE_ABSOLUTE());
        -            };
        -
        -        $$indexRef = $index;
        -        $$lineNumberRef = $lineNumber;
        -        $self->SkipRestOfStatement($indexRef, $lineNumberRef);
        -
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToGetFunction
        -#
        -#   Determines whether the position is at a function declaration statement, and if so, generates a topic for it, skips it, and
        -#   returns true.
        -#
        -sub TryToGetFunction #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ( lc($tokens->[$$indexRef]) eq 'sub')
        -        {
        -        my $prototypeStart = $$indexRef;
        -        my $prototypeStartLine = $$lineNumberRef;
        -        my $prototypeEnd = $$indexRef + 1;
        -        my $prototypeEndLine = $$lineNumberRef;
        -
        -        if ( !$self->TryToSkipWhitespace(\$prototypeEnd, \$prototypeEndLine) ||
        -             $tokens->[$prototypeEnd] !~ /^[a-z_]/i )
        -            {  return undef;  };
        -
        -        my $name = $tokens->[$prototypeEnd];
        -        $prototypeEnd++;
        -
        -        # We parsed 'sub [name]'.  Now keep going until we find a semicolon or a brace.
        -
        -        for (;;)
        -            {
        -            if ($prototypeEnd >= scalar @$tokens)
        -                {  return undef;  }
        -
        -            # End if we find a semicolon, since it means we found a predeclaration rather than an actual function.
        -            elsif ($tokens->[$prototypeEnd] eq ';')
        -                {  return undef;  }
        -
        -            elsif ($tokens->[$prototypeEnd] eq '{')
        -                {
        -                # Found it!
        -
        -                my $prototype = $self->NormalizePrototype( $self->CreateString($prototypeStart, $prototypeEnd) );
        -
        -                $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_FUNCTION(), $name,
        -                                                                                                          $self->CurrentScope(), undef,
        -                                                                                                          $prototype,
        -                                                                                                          undef, undef, $prototypeStartLine));
        -
        -                $$indexRef = $prototypeEnd;
        -                $$lineNumberRef = $prototypeEndLine;
        -
        -                $self->SkipRestOfStatement($indexRef, $lineNumberRef);
        -
        -                return 1;
        -                }
        -
        -            else
        -                {  $self->GenericSkip(\$prototypeEnd, \$prototypeEndLine, 0, 1);  };
        -            };
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToGetVariable
        -#
        -#   Determines if the position is at a variable declaration statement, and if so, generates a topic for it, skips it, and returns
        -#   true.
        -#
        -#   Supported Syntaxes:
        -#
        -#   - Supports variables declared with "my", "our", and "local".
        -#   - Supports multiple declarations in one statement, such as "my ($x, $y);".
        -#   - Supports types and attributes.
        -#
        -sub TryToGetVariable #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $firstToken = lc( $tokens->[$$indexRef] );
        -
        -    if ($firstToken eq 'my' || $firstToken eq 'our' || $firstToken eq 'local')
        -        {
        -        my $prototypeStart = $$indexRef;
        -        my $prototypeStartLine = $$lineNumberRef;
        -        my $prototypeEnd = $$indexRef + 1;
        -        my $prototypeEndLine = $$lineNumberRef;
        -
        -        $self->TryToSkipWhitespace(\$prototypeEnd, \$prototypeEndLine);
        -
        -
        -        # Get the type if present.
        -
        -        my $type;
        -
        -        if ($tokens->[$prototypeEnd] =~ /^[a-z\:]/i)
        -            {
        -            do
        -                {
        -                $type .= $tokens->[$prototypeEnd];
        -                $prototypeEnd++;
        -                }
        -            while ($tokens->[$prototypeEnd] =~ /^[a-z\:]/i);
        -
        -            if (!$self->TryToSkipWhitespace(\$prototypeEnd, \$prototypeEndLine))
        -                {  return undef;  };
        -            };
        -
        -
        -        # Get the name, or possibly names.
        -
        -        if ($tokens->[$prototypeEnd] eq '(')
        -            {
        -            # If there's multiple variables, we'll need to build a custom prototype for each one.  $firstToken already has the
        -            # declaring word.  We're going to store each name in @names, and we're going to use $prototypeStart and
        -            # $prototypeEnd to capture any properties appearing after the list.
        -
        -            my $name;
        -            my @names;
        -            my $hasComma = 0;
        -
        -            $prototypeStart = $prototypeEnd + 1;
        -            $prototypeStartLine = $prototypeEndLine;
        -
        -            for (;;)
        -                {
        -                $self->TryToSkipWhitespace(\$prototypeStart, \$prototypeStartLine);
        -
        -                $name = $self->TryToGetVariableName(\$prototypeStart, \$prototypeStartLine);
        -
        -                if (!defined $name)
        -                    {  return undef;  };
        -
        -                push @names, $name;
        -
        -                $self->TryToSkipWhitespace(\$prototypeStart, \$prototypeStartLine);
        -
        -                # We can have multiple commas in a row.  We can also have trailing commas.  However, the parenthesis must
        -                # not start with a comma or be empty, hence this logic does not appear earlier.
        -                while ($tokens->[$prototypeStart] eq ',')
        -                    {
        -                    $prototypeStart++;
        -                    $self->TryToSkipWhitespace(\$prototypeStart, \$prototypeStartLine);
        -
        -                    $hasComma = 1;
        -                    }
        -
        -                if ($tokens->[$prototypeStart] eq ')')
        -                    {
        -                    $prototypeStart++;
        -                    last;
        -                    }
        -                elsif (!$hasComma)
        -                    {  return undef;  };
        -                };
        -
        -
        -            # Now find the end of the prototype.
        -
        -            $prototypeEnd = $prototypeStart;
        -            $prototypeEndLine = $prototypeStartLine;
        -
        -            while ($prototypeEnd < scalar @$tokens &&
        -                     $tokens->[$prototypeEnd] !~ /^[\;\=]/)
        -                {
        -                $prototypeEnd++;
        -                };
        -
        -
        -            my $prototypePrefix = $firstToken . ' ';
        -            if (defined $type)
        -                {  $prototypePrefix .= $type . ' ';  };
        -
        -            my $prototypeSuffix = ' ' . $self->CreateString($prototypeStart, $prototypeEnd);
        -
        -            foreach $name (@names)
        -                {
        -                my $prototype = $self->NormalizePrototype( $prototypePrefix . $name . $prototypeSuffix );
        -
        -                $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_VARIABLE(), $name,
        -                                                                                                           $self->CurrentScope(), undef,
        -                                                                                                           $prototype,
        -                                                                                                           undef, undef, $prototypeStartLine));
        -                };
        -
        -            $self->SkipRestOfStatement(\$prototypeEnd, \$prototypeEndLine);
        -
        -            $$indexRef = $prototypeEnd;
        -            $$lineNumberRef = $prototypeEndLine;
        -            }
        -
        -        else # no parenthesis
        -            {
        -            my $name = $self->TryToGetVariableName(\$prototypeEnd, \$prototypeEndLine);
        -
        -            if (!defined $name)
        -                {  return undef;  };
        -
        -            while ($prototypeEnd < scalar @$tokens &&
        -                     $tokens->[$prototypeEnd] !~ /^[\;\=]/)
        -                {
        -                $prototypeEnd++;
        -                };
        -
        -            my $prototype = $self->NormalizePrototype( $self->CreateString($prototypeStart, $prototypeEnd) );
        -
        -            $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_VARIABLE(), $name,
        -                                                                                                       $self->CurrentScope(), undef,
        -                                                                                                       $prototype,
        -                                                                                                       undef, undef, $prototypeStartLine));
        -
        -            $self->SkipRestOfStatement(\$prototypeEnd, \$prototypeEndLine);
        -
        -            $$indexRef = $prototypeEnd;
        -            $$lineNumberRef = $prototypeEndLine;
        -            };
        -
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToGetVariableName
        -#
        -#   Determines if the position is at a variable name, and if so, skips it and returns the name.
        -#
        -sub TryToGetVariableName #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $name;
        -
        -    if ($tokens->[$$indexRef] =~ /^[\$\@\%\*]/)
        -        {
        -        $name .= $tokens->[$$indexRef];
        -        $$indexRef++;
        -
        -        $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -
        -        if ($tokens->[$$indexRef] =~ /^[a-z_]/i)
        -            {
        -            $name .= $tokens->[$$indexRef];
        -            $$indexRef++;
        -            }
        -        else
        -            {  return undef;  };
        -        };
        -
        -    return $name;
        -    };
        -
        -
        -#
        -#   Function: TryToGetListOfStrings
        -#
        -#   Attempts to retrieve a list of strings from the current position.  Returns an arrayref of them if any are found, or undef if none.
        -#   It stops the moment it reaches a non-string, so "string1, variable, string2" will only return string1.
        -#
        -#   Supported Syntaxes:
        -#
        -#   - Supports parenthesis.
        -#   - Supports all string forms supported by <TryToSkipString()>.
        -#   - Supports qw() string arrays.
        -#
        -sub TryToGetListOfStrings #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $parenthesis = 0;
        -    my $strings;
        -
        -    while ($$indexRef < scalar @$tokens)
        -        {
        -        # We'll tolerate parenthesis.
        -        if ($tokens->[$$indexRef] eq '(')
        -            {
        -            $$indexRef++;
        -            $parenthesis++;
        -            }
        -        elsif ($tokens->[$$indexRef] eq ')')
        -            {
        -            if ($parenthesis == 0)
        -                {  last;  };
        -
        -            $$indexRef++;
        -            $parenthesis--;
        -            }
        -        elsif ($tokens->[$$indexRef] eq ',')
        -            {
        -            $$indexRef++;
        -            }
        -        else
        -            {
        -            my ($startContent, $endContent);
        -            my $symbolIndex = $$indexRef;
        -
        -            if ($self->TryToSkipString($indexRef, $lineNumberRef, \$startContent, \$endContent))
        -                {
        -                my $content = $self->CreateString($startContent, $endContent);
        -
        -                if (!defined $strings)
        -                    {  $strings = [ ];  };
        -
        -                if (lc($tokens->[$symbolIndex]) eq 'qw')
        -                    {
        -                    $content =~ tr/ \t\n/ /s;
        -                    $content =~ s/^ //;
        -
        -                    my @qwStrings = split(/ /, $content);
        -
        -                    push @$strings, @qwStrings;
        -                    }
        -                else
        -                    {
        -                    push @$strings, $content;
        -                    };
        -                }
        -            else
        -                {  last;  };
        -            };
        -
        -        $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -        };
        -
        -    return $strings;
        -    };
        -
        -
        -###############################################################################
        -# Group: Low Level Parsing Functions
        -
        -
        -#
        -#   Function: GenericSkip
        -#
        -#   Advances the position one place through general code.
        -#
        -#   - If the position is on a comment or string, it will skip it completely.
        -#   - If the position is on an opening symbol, it will skip until the past the closing symbol.
        -#   - If the position is on a regexp or quote-like operator, it will skip it completely.
        -#   - If the position is on a backslash, it will skip it and the following token.
        -#   - If the position is on whitespace (including comments), it will skip it completely.
        -#   - Otherwise it skips one token.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the current index.
        -#       lineNumberRef - A reference to the current line number.
        -#       noRegExps - If set, does not test for regular expressions.
        -#
        -sub GenericSkip #(indexRef, lineNumberRef, noRegExps)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $noRegExps, $allowStringedClosingParens) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq "\\" && $$indexRef + 1 < scalar @$tokens && $tokens->[$$indexRef+1] ne "\n")
        -        {  $$indexRef += 2;  }
        -
        -    # Note that we don't want to count backslashed ()[]{} since they could be in regexps.  Also, ()[] are valid variable names
        -    # when preceded by a string.
        -
        -    # We can ignore the scope stack because we're just skipping everything without parsing, and we need recursion anyway.
        -    elsif ($tokens->[$$indexRef] eq '{' && !$self->IsBackslashed($$indexRef))
        -        {
        -        $$indexRef++;
        -        $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}', $noRegExps, $allowStringedClosingParens);
        -        }
        -    elsif ($tokens->[$$indexRef] eq '(' && !$self->IsBackslashed($$indexRef) && !$self->IsStringed($$indexRef))
        -        {
        -        # Temporarily allow stringed closing parenthesis if it looks like we're in an anonymous function declaration with Perl's
        -        # cheap version of prototypes, such as "my $_declare = sub($) {}".
        -        my $tempAllowStringedClosingParens = $allowStringedClosingParens;
        -        if (!$allowStringedClosingParens)
        -        	{
        -        	my $tempIndex = $$indexRef - 1;
        -        	if ($tempIndex >= 0 && $tokens->[$tempIndex] =~ /^[ \t]/)
        -        		{  $tempIndex--;  }
        -        	if ($tempIndex >= 0 && $tokens->[$tempIndex] eq 'sub')
        -        		{  $tempAllowStringedClosingParens = 1;  }
        -        	}
        -
        -        $$indexRef++;
        -
        -        do
        -            {  $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ')', $noRegExps, $tempAllowStringedClosingParens);  }
        -        while ($$indexRef < scalar @$tokens && $self->IsStringed($$indexRef - 1) && !$tempAllowStringedClosingParens);
        -        }
        -    elsif ($tokens->[$$indexRef] eq '[' && !$self->IsBackslashed($$indexRef) && !$self->IsStringed($$indexRef))
        -        {
        -        $$indexRef++;
        -
        -        do
        -            {  $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']', $noRegExps, $allowStringedClosingParens);  }
        -        while ($$indexRef < scalar @$tokens && $self->IsStringed($$indexRef - 1));
        -        }
        -
        -    elsif ($self->TryToSkipWhitespace($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipString($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipHereDocDeclaration($indexRef, $lineNumberRef) ||
        -            (!$noRegExps && $self->TryToSkipRegexp($indexRef, $lineNumberRef) ) )
        -        {
        -        }
        -
        -    else
        -        {  $$indexRef++;  };
        -    };
        -
        -
        -#
        -#   Function: GenericSkipUntilAfter
        -#
        -#   Advances the position via <GenericSkip()> until a specific token is reached and passed.
        -#
        -sub GenericSkipUntilAfter #(indexRef, lineNumberRef, token, noRegExps, allowStringedClosingParens)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $token, $noRegExps, $allowStringedClosingParens) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne $token)
        -        {  $self->GenericSkip($indexRef, $lineNumberRef, $noRegExps, $allowStringedClosingParens);  };
        -
        -    if ($tokens->[$$indexRef] eq "\n")
        -        {  $$lineNumberRef++;  };
        -    $$indexRef++;
        -    };
        -
        -
        -#
        -#   Function: GenericRegexpSkip
        -#
        -#   Advances the position one place through regexp code.
        -#
        -#   - If the position is on an opening symbol, it will skip until the past the closing symbol.
        -#   - If the position is on a backslash, it will skip it and the following token.
        -#   - If the position is on whitespace (not including comments), it will skip it completely.
        -#   - Otherwise it skips one token.
        -#
        -#   Also differs from <GenericSkip()> in that the parenthesis in $( and $) do count against the scope, where they wouldn't
        -#   normally.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the current index.
        -#       lineNumberRef - A reference to the current line number.
        -#       inBrackets - Whether we're in brackets or not.  If true, we don't care about matching braces and parenthesis.
        -#
        -sub GenericRegexpSkip #(indexRef, lineNumberRef, inBrackets)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $inBrackets) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($tokens->[$$indexRef] eq "\\" && $$indexRef + 1 < scalar @$tokens && $tokens->[$$indexRef+1] ne "\n")
        -        {  $$indexRef += 2;  }
        -
        -    # We can ignore the scope stack because we're just skipping everything without parsing, and we need recursion anyway.
        -    elsif ($tokens->[$$indexRef] eq '{' && !$self->IsBackslashed($$indexRef) && !$inBrackets)
        -        {
        -        $$indexRef++;
        -        $self->GenericRegexpSkipUntilAfter($indexRef, $lineNumberRef, '}');
        -        }
        -    elsif ($tokens->[$$indexRef] eq '(' && !$self->IsBackslashed($$indexRef) && !$inBrackets)
        -        {
        -        $$indexRef++;
        -        $self->GenericRegexpSkipUntilAfter($indexRef, $lineNumberRef, ')');
        -        }
        -    elsif ($tokens->[$$indexRef] eq '[' && !$self->IsBackslashed($$indexRef) && !$self->IsStringed($$indexRef))
        -        {
        -        $$indexRef++;
        -
        -        do
        -            {  $self->GenericRegexpSkipUntilAfter($indexRef, $lineNumberRef, ']');  }
        -        while ($$indexRef < scalar @$tokens && $self->IsStringed($$indexRef - 1));
        -        }
        -
        -    elsif ($tokens->[$$indexRef] eq "\n")
        -        {
        -        $$lineNumberRef++;
        -        $$indexRef++;
        -        }
        -
        -    else
        -        {  $$indexRef++;  };
        -    };
        -
        -
        -#
        -#   Function: GenericRegexpSkipUntilAfter
        -#
        -#   Advances the position via <GenericRegexpSkip()> until a specific token is reached and passed.
        -#
        -sub GenericRegexpSkipUntilAfter #(indexRef, lineNumberRef, token)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $token) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $inBrackets = ( $token eq ']' );
        -
        -    while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne $token)
        -        {  $self->GenericRegexpSkip($indexRef, $lineNumberRef, $inBrackets);  };
        -
        -    if ($tokens->[$$indexRef] eq "\n")
        -        {  $$lineNumberRef++;  };
        -    $$indexRef++;
        -    };
        -
        -
        -#
        -#   Function: SkipRestOfStatement
        -#
        -#   Advances the position via <GenericSkip()> until after the end of the current statement, which is defined as a semicolon or
        -#   a brace group.  Of course, either of those appearing inside parenthesis, a nested brace group, etc. don't count.
        -#
        -sub SkipRestOfStatement #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    while ($$indexRef < scalar @$tokens &&
        -             $tokens->[$$indexRef] ne ';' &&
        -             !($tokens->[$$indexRef] eq '{' && !$self->IsStringed($$indexRef)) )
        -        {
        -        $self->GenericSkip($indexRef, $lineNumberRef);
        -        };
        -
        -    if ($tokens->[$$indexRef] eq ';')
        -        {  $$indexRef++;  }
        -    elsif ($tokens->[$$indexRef] eq '{')
        -        {  $self->GenericSkip($indexRef, $lineNumberRef);  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipWhitespace
        -#
        -#   If the current position is on whitespace it skips them and returns true.  If there are a number of these in a row, it skips them
        -#   all.
        -#
        -#   Supported Syntax:
        -#
        -#       - Whitespace
        -#       - Line break
        -#       - All comment forms supported by <TryToSkipComment()>
        -#       - Here Doc content
        -#
        -sub TryToSkipWhitespace #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $result;
        -
        -    while ($$indexRef < scalar @$tokens)
        -        {
        -        if ($self->TryToSkipHereDocContent($indexRef, $lineNumberRef) ||
        -            $self->TryToSkipComment($indexRef, $lineNumberRef))
        -            {
        -            $result = 1;
        -            }
        -        elsif ($tokens->[$$indexRef] =~ /^[ \t]/)
        -            {
        -            $$indexRef++;
        -            $result = 1;
        -            }
        -        elsif ($tokens->[$$indexRef] eq "\n")
        -            {
        -            $$indexRef++;
        -            $$lineNumberRef++;
        -            $result = 1;
        -            }
        -        else
        -            {  last;  };
        -        };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: TryToSkipComment
        -#   If the current position is on a comment, skip past it and return true.
        -#
        -sub TryToSkipComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -
        -    return ( $self->TryToSkipLineComment($indexRef, $lineNumberRef) ||
        -                $self->TryToSkipPODComment($indexRef, $lineNumberRef) );
        -    };
        -
        -
        -#
        -#   Function: TryToSkipLineComment
        -#   If the current position is on a line comment symbol, skip past it and return true.
        -#
        -sub TryToSkipLineComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # Note that $#var is not a comment.
        -    if ($tokens->[$$indexRef] eq '#' && !$self->IsStringed($$indexRef))
        -        {
        -        $self->SkipRestOfLine($indexRef, $lineNumberRef);
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipPODComment
        -#   If the current position is on a POD comment symbol, skip past it and return true.
        -#
        -sub TryToSkipPODComment #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # Note that whitespace is not allowed before the equals sign.  It must directly start a line.
        -    if ($tokens->[$$indexRef] eq '=' &&
        -        ( $$indexRef == 0 || $tokens->[$$indexRef - 1] eq "\n" ) &&
        -        $tokens->[$$indexRef + 1] =~ /^[a-z]/i )
        -        {
        -        # Skip until =cut or (NDPODBREAK).  Note that it's theoretically possible for =cut to appear without a prior POD directive.
        -
        -        do
        -            {
        -            if ($tokens->[$$indexRef] eq '=' && lc( $tokens->[$$indexRef + 1] ) eq 'cut')
        -                {
        -                $self->SkipRestOfLine($indexRef, $lineNumberRef);
        -                last;
        -                }
        -            elsif ($tokens->[$$indexRef] eq '(' && $$indexRef + 2 < scalar @$tokens &&
        -                    $tokens->[$$indexRef+1] eq 'NDPODBREAK' && $tokens->[$$indexRef+2] eq ')')
        -                {
        -                $$indexRef += 3;
        -                last;
        -                }
        -            else
        -                {
        -                $self->SkipRestOfLine($indexRef, $lineNumberRef);
        -                };
        -            }
        -        while ($$indexRef < scalar @$tokens);
        -
        -        return 1;
        -        }
        -
        -    # It's also possible that (NDPODBREAK) will appear without any opening pod statement because "=begin nd" and "=cut" will
        -    # still result in one.  We need to pick off the stray (NDPODBREAK).
        -    elsif ($tokens->[$$indexRef] eq '(' && $$indexRef + 2 < scalar @$tokens &&
        -            $tokens->[$$indexRef+1] eq 'NDPODBREAK' && $tokens->[$$indexRef+2] eq ')')
        -        {
        -        $$indexRef += 3;
        -        return 1;
        -        }
        -
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipString
        -#   If the current position is on a string delimiter, skip past the string and return true.
        -#
        -#   Parameters:
        -#
        -#       indexRef - A reference to the index of the position to start at.
        -#       lineNumberRef - A reference to the line number of the position.
        -#       startContentIndexRef - A reference to the variable in which to store the index of the first content token.  May be undef.
        -#       endContentIndexRef - A reference to the variable in which to store the index of the end of the content, which is one past
        -#                                        the last content token.  may be undef.
        -#
        -#   Returns:
        -#
        -#       Whether the position was at a string.  The index, line number, and content index variabls will only be changed if true.
        -#
        -#   Syntax Support:
        -#
        -#       - Supports quotes, apostrophes, backticks, q(), qq(), qx(), and qw().
        -#       - All symbols are supported for the letter forms.
        -#
        -sub TryToSkipString #(indexRef, lineNumberRef, startContentIndexRef, endContentIndexRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef, $startContentIndexRef, $endContentIndexRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # The three string delimiters.  All three are Perl variables when preceded by a dollar sign.
        -    if (!$self->IsStringed($$indexRef) &&
        -        ( $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '\'', '\'', $startContentIndexRef, $endContentIndexRef) ||
        -          $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '"', '"', $startContentIndexRef, $endContentIndexRef) ||
        -          $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '`', '`', $startContentIndexRef, $endContentIndexRef) ) )
        -        {
        -        return 1;
        -        }
        -    elsif ($tokens->[$$indexRef] =~ /^(?:q|qq|qx|qw)$/i &&
        -            ($$indexRef == 0 || $tokens->[$$indexRef - 1] !~ /^[\$\%\@\*]$/))
        -        {
        -        $$indexRef++;
        -
        -        $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -
        -        my $openingSymbol = $tokens->[$$indexRef];
        -        my $closingSymbol;
        -
        -        if ($openingSymbol eq '{')
        -            {  $closingSymbol = '}';  }
        -        elsif ($openingSymbol eq '(')
        -            {  $closingSymbol = ')';  }
        -        elsif ($openingSymbol eq '[')
        -            {  $closingSymbol = ']';  }
        -        elsif ($openingSymbol eq '<')
        -            {  $closingSymbol = '>';  }
        -        else
        -            {  $closingSymbol = $openingSymbol;  };
        -
        -        $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, $openingSymbol, $closingSymbol,
        -                                                      $startContentIndexRef, $endContentIndexRef);
        -
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipHereDocDeclaration
        -#
        -#   If the current position is on a Here Doc declaration, add its terminators to <hereDocTerminators> and skip it.
        -#
        -#   Syntax Support:
        -#
        -#       - Supports <<EOF
        -#       - Supports << "String" with all string forms supported by <TryToSkipString()>.
        -#
        -sub TryToSkipHereDocDeclaration #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $index = $$indexRef;
        -    my $lineNumber = $$lineNumberRef;
        -
        -    if ($tokens->[$index] eq '<' && $tokens->[$index + 1] eq '<')
        -        {
        -        $index += 2;
        -        my $success;
        -
        -        # No whitespace allowed with the bare word.
        -        if ($tokens->[$index] =~ /^[a-z0-9_]/i)
        -            {
        -            push @hereDocTerminators, [ $tokens->[$index] ];
        -            $index++;
        -            $success = 1;
        -            }
        -        else
        -            {
        -            $self->TryToSkipWhitespace(\$index, \$lineNumber);
        -
        -            my ($contentStart, $contentEnd);
        -            if ($self->TryToSkipString(\$index, \$lineNumber, \$contentStart, \$contentEnd))
        -                {
        -                push @hereDocTerminators, [ @{$tokens}[$contentStart..$contentEnd - 1] ];
        -                $success = 1;
        -                };
        -            };
        -
        -        if ($success)
        -            {
        -            $$indexRef = $index;
        -            $$lineNumberRef = $lineNumber;
        -
        -            return 1;
        -            };
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -#
        -#   Function: TryToSkipHereDocContent
        -#
        -#   If the current position is at the beginning of a line and there are entries in <hereDocTerminators>, skips lines until all the
        -#   terminators are exhausted or we reach the end of the file.
        -#
        -#   Returns:
        -#
        -#       Whether the position was on Here Doc content.
        -#
        -sub TryToSkipHereDocContent #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    # We don't use IsFirstLineToken() because it really needs to be the first line token.  Whitespace is not allowed.
        -    if ($$indexRef > 0 && $tokens->[$$indexRef - 1] eq "\n")
        -        {
        -        my $success = (scalar @hereDocTerminators > 0);
        -
        -        while (scalar @hereDocTerminators && $$indexRef < scalar @$tokens)
        -            {
        -            my $terminatorIndex = 0;
        -
        -            while ($hereDocTerminators[0]->[$terminatorIndex] eq $tokens->[$$indexRef])
        -                {
        -                $terminatorIndex++;
        -                $$indexRef++;
        -                };
        -
        -            if ($terminatorIndex == scalar @{$hereDocTerminators[0]} &&
        -                ($tokens->[$$indexRef] eq "\n" || ($tokens->[$$indexRef] =~ /^[ \t]/ && $tokens->[$$indexRef + 1] eq "\n")) )
        -                {
        -                shift @hereDocTerminators;
        -                $$indexRef++;
        -                $$lineNumberRef++;
        -                }
        -            else
        -                {  $self->SkipRestOfLine($indexRef, $lineNumberRef);  };
        -            };
        -
        -        return $success;
        -        }
        -
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: TryToSkipRegexp
        -#   If the current position is on a regular expression or a quote-like operator, skip past it and return true.
        -#
        -#   Syntax Support:
        -#
        -#       - Supports //, ??, m//, qr//, s///, tr///, and y///.
        -#       - All symbols are supported for the letter forms.
        -#       - ?? is *not* supported because it could cause problems with ?: statements.  The generic parser has a good chance of
        -#         successfully stumbling through a regex, whereas the regex code will almost certainly see the rest of the file as part of it.
        -#
        -sub TryToSkipRegexp #(indexRef, lineNumberRef)
        -    {
        -    my ($self, $indexRef, $lineNumberRef) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    my $isRegexp;
        -
        -    # If it's a supported character sequence that's not a variable (ex $qr) or package (ex a::tr)...
        -    if ($tokens->[$$indexRef] =~ /^(?:m|qr|s|tr|y)$/i &&
        -         ($$indexRef == 0 || $tokens->[$$indexRef - 1] !~ /^[\$\%\@\*\-\>\:]$/) )
        -        {  $isRegexp = 1;  }
        -
        -    elsif ($tokens->[$$indexRef] eq '/' && !$self->IsStringed($$indexRef))
        -        {
        -        # This is a bit of a hack.  If we find a random slash, it could be a divide operator or a bare regexp.  Find the first previous
        -        # non-whitespace token and if it's text, a closing brace, or a string, assume it's a divide operator.  (Strings don't make
        -        # much pratical sense there but a regexp would be impossible.)  Otherwise assume it's a regexp.
        -
        -        # We make a special consideration for split() appearing without parenthesis.  If the previous token is split and it's not a
        -        # variable, assume it is a regexp even though it fails the above test.
        -
        -        my $index = $$indexRef - 1;
        -
        -        while ($index >= 0 && $tokens->[$index] =~ /^(?: |\t|\n)/)
        -            {  $index--;  };
        -
        -        if ($index < 0 || $tokens->[$index] !~ /^[a-zA-Z0-9_\)\]\}\'\"\`]/ ||
        -            ($tokens->[$index] =~ /^split|grep$/ && $index > 0 && $tokens->[$index-1] !~ /^[\$\%\@\*]$/) )
        -            {  $isRegexp = 1;  };
        -        };
        -
        -    if ($isRegexp)
        -        {
        -        my $operator = lc($tokens->[$$indexRef]);
        -        my $index = $$indexRef;
        -        my $lineNumber = $$lineNumberRef;
        -
        -        if ($operator =~ /^[\?\/]/)
        -            {  $operator = 'm';  }
        -        else
        -            {
        -            $index++;
        -
        -            # Believe it or not, s#...# is allowed.  We can't pass over number signs here.
        -            if ($tokens->[$index] ne '#')
        -                {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
        -            };
        -
        -        if ($tokens->[$index] =~ /^\w/)
        -            {  return undef;  };
        -        if ($tokens->[$index] eq '=' && $tokens->[$index+1] eq '>')
        -        	{  return undef;  };
        -
        -        my $openingSymbol = $tokens->[$index];
        -        my $closingSymbol;
        -
        -        if ($openingSymbol eq '{')
        -            {  $closingSymbol = '}';  }
        -        elsif ($openingSymbol eq '(')
        -            {  $closingSymbol = ')';  }
        -        elsif ($openingSymbol eq '[')
        -            {  $closingSymbol = ']';  }
        -        elsif ($openingSymbol eq '<')
        -            {  $closingSymbol = '>';  }
        -        else
        -            {  $closingSymbol = $openingSymbol;  };
        -
        -        $index++;
        -
        -        $self->GenericRegexpSkipUntilAfter(\$index, \$lineNumber, $closingSymbol);
        -
        -        $$indexRef = $index;
        -        $$lineNumberRef = $lineNumber;
        -
        -        if ($operator =~ /^(?:s|tr|y)$/)
        -            {
        -            if ($openingSymbol ne $closingSymbol)
        -                {
        -                $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
        -
        -                $openingSymbol = $tokens->[$index];
        -
        -                if ($openingSymbol eq '{')
        -                    {  $closingSymbol = '}';  }
        -                elsif ($openingSymbol eq '(')
        -                    {  $closingSymbol = ')';  }
        -                elsif ($openingSymbol eq '[')
        -                    {  $closingSymbol = ']';  }
        -                elsif ($openingSymbol eq '<')
        -                    {  $closingSymbol = '>';  }
        -                else
        -                    {  $closingSymbol = $openingSymbol;  };
        -
        -                $$indexRef++;
        -                };
        -
        -            if ($operator eq 's')
        -                {
        -                $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, $closingSymbol, 1);
        -                }
        -            else # ($operator eq 'tr' || $operator eq 'y')
        -                {
        -                while ($$indexRef < scalar @$tokens &&
        -                          ($tokens->[$$indexRef] ne $closingSymbol || $self->IsBackslashed($$indexRef)) )
        -                    {
        -                    if ($tokens->[$$indexRef] eq "\n")
        -                        {  $$lineNumberRef++;  };
        -                    $$indexRef++;
        -                    };
        -
        -                $$indexRef++;
        -                };
        -            };
        -
        -        # We want to skip any letters after the regexp.  Otherwise something like tr/a/b/s; could have the trailing s; interpreted
        -        # as another regexp.  Whitespace is not allowed between the closing symbol and the letters.
        -
        -        if ($tokens->[$$indexRef] =~ /^[a-z]/i)
        -            {  $$indexRef++;  };
        -
        -        return 1;
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: IsStringed
        -#
        -#   Returns whether the position is after a string (dollar sign) character.  Returns false if it's preceded by two dollar signs so
        -#   "if ($x == $$)" doesn't skip the closing parenthesis as stringed.
        -#
        -#   Parameters:
        -#
        -#       index - The index of the postition.
        -#
        -sub IsStringed #(index)
        -    {
        -    my ($self, $index) = @_;
        -    my $tokens = $self->Tokens();
        -
        -    if ($index > 0 && $tokens->[$index - 1] eq '$' && !($index > 1 && $tokens->[$index - 2] eq '$'))
        -        {  return 1;  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Prototype.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Prototype.pm
        deleted file mode 100644
        index b4d5fc86f..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Prototype.pm
        +++ /dev/null
        @@ -1,93 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Prototype
        -#
        -###############################################################################
        -#
        -#   A data class for storing parsed prototypes.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -use NaturalDocs::Languages::Prototype::Parameter;
        -
        -
        -package NaturalDocs::Languages::Prototype;
        -
        -use NaturalDocs::DefineMembers 'BEFORE_PARAMETERS', 'BeforeParameters()', 'SetBeforeParameters()',
        -                                                 'AFTER_PARAMETERS', 'AfterParameters()', 'SetAfterParameters()',
        -                                                 'PARAMETERS', 'Parameters()';
        -# Dependency: New(), constant order, no parents.
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new prototype object.
        -#
        -#   Parameters:
        -#
        -#       beforeParameters - The part of the prototype before the parameter list.
        -#       afterParameters - The part of the prototype after the parameter list.
        -#
        -#   You cannot set the parameters from here.  Use <AddParameter()>.
        -#
        -sub New #(beforeParameters, afterParameters)
        -    {
        -    my ($package, @params) = @_;
        -
        -    # Dependency: Constant order, no parents.
        -
        -    my $object = [ @params ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Members
        -#
        -#   BeforeParameters - Returns the part of the prototype before the parameter list.  If there is no parameter list, this will be the
        -#                                only thing that returns content.
        -#   SetBeforeParameters - Replaces the part of the prototype before the parameter list.
        -#   AfterParameters - Returns the part of the prototype after the parameter list, if any.
        -#   SetAfterParameters - Replaces the part of the prototype after the parameter list.
        -#   Parameters - Returns the parameter list as an arrayref of <NaturalDocs::Languages::Prototype::Parameters>, or undef if none.
        -#
        -
        -#
        -#   Function: AddParameter
        -#
        -#   Adds a <NaturalDocs::Languages::Prototype::Parameter> to the list.
        -#
        -sub AddParameter #(parameter)
        -    {
        -    my ($self, $parameter) = @_;
        -
        -    if (!defined $self->[PARAMETERS])
        -        {  $self->[PARAMETERS] = [ ];  };
        -
        -    push @{$self->[PARAMETERS]}, $parameter;
        -    };
        -
        -
        -#
        -#   Function: OnlyBeforeParameters
        -#
        -#   Returns whether <BeforeParameters()> is the only thing set.
        -#
        -sub OnlyBeforeParameters
        -    {
        -    my $self = shift;
        -    return (!defined $self->[PARAMETERS] && !defined $self->[AFTER_PARAMETERS]);
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm
        deleted file mode 100644
        index 41b5bce54..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm
        +++ /dev/null
        @@ -1,88 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Prototype::Parameter
        -#
        -###############################################################################
        -#
        -#   A data class for storing parsed prototype parameters.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Prototype::Parameter;
        -
        -use NaturalDocs::DefineMembers 'TYPE', 'Type()', 'SetType()',
        -                                                 'TYPE_PREFIX', 'TypePrefix()', 'SetTypePrefix()',
        -                                                 'NAME', 'Name()', 'SetName()',
        -                                                 'NAME_PREFIX', 'NamePrefix()', 'SetNamePrefix()',
        -                                                 'DEFAULT_VALUE', 'DefaultValue()', 'SetDefaultValue()',
        -                                                 'DEFAULT_VALUE_PREFIX', 'DefaultValuePrefix()', 'SetDefaultValuePrefix()';
        -# Dependency: New() depends on the order of these constants and that they don't inherit from another class.
        -
        -
        -#
        -#   Constants: Members
        -#
        -#   The object is implemented as a blessed arrayref, with the following constants as its indexes.
        -#
        -#       TYPE - The parameter type, if any.
        -#       TYPE_PREFIX - The parameter type prefix which should be aligned separately, if any.
        -#       NAME - The parameter name.
        -#       NAME_PREFIX - The parameter name prefix which should be aligned separately, if any.
        -#       DEFAULT_VALUE - The default value expression, if any.
        -#       DEFAULT_VALUE_PREFIX - The default value prefix which should be aligned separately, if any.
        -#
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new prototype object.
        -#
        -#   Parameters:
        -#
        -#       type - The parameter type, if any.
        -#       typePrefix - The parameter type prefix which should be aligned separately, if any.
        -#       name - The parameter name.
        -#       namePrefix - The parameter name prefix which should be aligned separately, if any.
        -#       defaultValue - The default value expression, if any.
        -#       defaultValuePrefix - The default value prefix which should be aligned separately, if any.
        -#
        -sub New #(type, typePrefix, name, namePrefix, defaultValue, defaultValuePrefix)
        -    {
        -    my ($package, @params) = @_;
        -
        -    # Dependency: This depends on the order of the parameters being the same as the order of the constants, and that the
        -    # constants don't inherit from another class.
        -
        -    my $object = [ @params ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Members
        -#
        -#   Type - The parameter type, if any.
        -#   SetType - Replaces the parameter type.
        -#   TypePrefix - The parameter type prefix, which should be aligned separately, if any.
        -#   SetTypePrefix - Replaces the parameter type prefix.
        -#   Name - The parameter name.
        -#   SetName - Replaces the parameter name.
        -#   NamePrefix - The parameter name prefix, which should be aligned separately, if any.
        -#   SetNamePrefix - Replaces the parameter name prefix.
        -#   DefaultValue - The default value expression, if any.
        -#   SetDefaultValue - Replaces the default value expression.
        -#   DefaultValuePrefix - The default value prefix, which should be aligned separately, if any.
        -#   SetDefaultValuePrefix - Replaces the default value prefix.
        -#
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Simple.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Simple.pm
        deleted file mode 100644
        index 6dfacd86a..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Simple.pm
        +++ /dev/null
        @@ -1,487 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Simple
        -#
        -###############################################################################
        -#
        -#   A class containing the characteristics of a particular programming language for basic support within Natural Docs.
        -#   Also serves as a base class for languages that break from general conventions, such as not having parameter lists use
        -#   parenthesis and commas.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Simple;
        -
        -use base 'NaturalDocs::Languages::Base';
        -use base 'Exporter';
        -
        -our @EXPORT = ( 'ENDER_ACCEPT', 'ENDER_IGNORE', 'ENDER_ACCEPT_AND_CONTINUE', 'ENDER_REVERT_TO_ACCEPTED' );
        -
        -
        -use NaturalDocs::DefineMembers 'LINE_COMMENT_SYMBOLS', 'LineCommentSymbols()', 'SetLineCommentSymbols() duparrayref',
        -                                                 'BLOCK_COMMENT_SYMBOLS', 'BlockCommentSymbols()',
        -                                                                                              'SetBlockCommentSymbols() duparrayref',
        -                                                 'PROTOTYPE_ENDERS',
        -                                                 'LINE_EXTENDER', 'LineExtender()', 'SetLineExtender()',
        -                                                 'PACKAGE_SEPARATOR', 'PackageSeparator()',
        -                                                 'PACKAGE_SEPARATOR_WAS_SET', 'PackageSeparatorWasSet()',
        -                                                 'ENUM_VALUES', 'EnumValues()',
        -                                                 'ENUM_VALUES_WAS_SET', 'EnumValuesWasSet()';
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       name - The name of the language.
        -#
        -sub New #(name)
        -    {
        -    my ($selfPackage, $name) = @_;
        -
        -    my $object = $selfPackage->SUPER::New($name);
        -
        -    $object->[ENUM_VALUES] = ::ENUM_GLOBAL();
        -    $object->[PACKAGE_SEPARATOR] = '.';
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Members
        -#
        -#   LineCommentSymbols - Returns an arrayref of symbols that start a line comment, or undef if none.
        -#   SetLineCommentSymbols - Replaces the arrayref of symbols that start a line comment.
        -#   BlockCommentSymbols - Returns an arrayref of start/end symbol pairs that specify a block comment, or undef if none.  Pairs
        -#                                        are specified with two consecutive array entries.
        -#   SetBlockCommentSymbols - Replaces the arrayref of start/end symbol pairs that specify a block comment.  Pairs are
        -#                                             specified with two consecutive array entries.
        -#   LineExtender - Returns the symbol to ignore a line break in languages where line breaks are significant.
        -#   SetLineExtender - Replaces the symbol to ignore a line break in languages where line breaks are significant.
        -#   PackageSeparator - Returns the package separator symbol.
        -#   PackageSeparatorWasSet - Returns whether the package separator symbol was ever changed from the default.
        -#
        -
        -#
        -#   Function: SetPackageSeparator
        -#   Replaces the language's package separator string.
        -#
        -sub SetPackageSeparator #(separator)
        -    {
        -    my ($self, $separator) = @_;
        -    $self->[PACKAGE_SEPARATOR] = $separator;
        -    $self->[PACKAGE_SEPARATOR_WAS_SET] = 1;
        -    };
        -
        -
        -#
        -#   Functions: Members
        -#
        -#   EnumValues - Returns the <EnumValuesType> that describes how the language handles enums.
        -#   EnumValuesWasSet - Returns whether <EnumValues> was ever changed from the default.
        -
        -
        -#
        -#   Function: SetEnumValues
        -#   Replaces the <EnumValuesType> that describes how the language handles enums.
        -#
        -sub SetEnumValues #(EnumValuesType newBehavior)
        -    {
        -    my ($self, $behavior) = @_;
        -    $self->[ENUM_VALUES] = $behavior;
        -    $self->[ENUM_VALUES_WAS_SET] = 1;
        -    };
        -
        -
        -#
        -#   Function: PrototypeEndersFor
        -#
        -#   Returns an arrayref of prototype ender symbols for the passed <TopicType>, or undef if none.
        -#
        -sub PrototypeEndersFor #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    if (defined $self->[PROTOTYPE_ENDERS])
        -        {  return $self->[PROTOTYPE_ENDERS]->{$type};  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: SetPrototypeEndersFor
        -#
        -#   Replaces the arrayref of prototype ender symbols for the passed <TopicType>.
        -#
        -sub SetPrototypeEndersFor #(type, enders)
        -    {
        -    my ($self, $type, $enders) = @_;
        -
        -    if (!defined $self->[PROTOTYPE_ENDERS])
        -        {  $self->[PROTOTYPE_ENDERS] = { };  };
        -
        -    if (!defined $enders)
        -        {  delete $self->[PROTOTYPE_ENDERS]->{$type};  }
        -    else
        -        {
        -        $self->[PROTOTYPE_ENDERS]->{$type} = [ @$enders ];
        -        };
        -    };
        -
        -
        -
        -
        -###############################################################################
        -# Group: Parsing Functions
        -
        -
        -#
        -#   Function: ParseFile
        -#
        -#   Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>
        -#   and all other sections to <OnCode()>.
        -#
        -#   Parameters:
        -#
        -#       sourceFile - The <FileName> of the source file to parse.
        -#       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
        -#
        -#   Returns:
        -#
        -#       Since this class cannot automatically document the code or generate a scope record, it always returns ( undef, undef ).
        -#
        -sub ParseFile #(sourceFile, topicsList)
        -    {
        -    my ($self, $sourceFile, $topicsList) = @_;
        -
        -    open(SOURCEFILEHANDLE, '<' . $sourceFile)
        -        or die "Couldn't open input file " . $sourceFile . "\n";
        -
        -    my $lineReader = NaturalDocs::LineReader->New(\*SOURCEFILEHANDLE);
        -
        -    my @commentLines;
        -    my @codeLines;
        -    my $lastCommentTopicCount = 0;
        -
        -    if ($self->Name() eq 'Text File')
        -        {
        -        @commentLines = $lineReader->GetAll();
        -        NaturalDocs::Parser->OnComment(\@commentLines, 1);
        -        }
        -
        -    else
        -        {
        -        my $line = $lineReader->Get();
        -        my $lineNumber = 1;
        -
        -        while (defined $line)
        -            {
        -            my $originalLine = $line;
        -
        -
        -            # Retrieve multiline comments.  This leaves $line at the next line.
        -            # We check for multiline comments before single line comments because in Lua the symbols are --[[ and --.
        -
        -            if (my $closingSymbol = $self->StripOpeningBlockSymbols(\$line, $self->BlockCommentSymbols()))
        -                {
        -                # Note that it is possible for a multiline comment to start correctly but not end so.  We want those comments to stay in
        -                # the code.  For example, look at this prototype with this splint annotation:
        -                #
        -                # int get_array(integer_t id,
        -                #                    /*@out@*/ array_t array);
        -                #
        -                # The annotation starts correctly but doesn't end so because it is followed by code on the same line.
        -
        -                my $lineRemainder;
        -
        -                for (;;)
        -                    {
        -                    $lineRemainder = $self->StripClosingSymbol(\$line, $closingSymbol);
        -
        -                    push @commentLines, $line;
        -
        -                    #  If we found an end comment symbol...
        -                    if (defined $lineRemainder)
        -                        {  last;  };
        -
        -                    $line = $lineReader->Get();
        -
        -                    if (!defined $line)
        -                        {  last;  };
        -                    };
        -
        -                if ($lineRemainder !~ /^[ \t]*$/)
        -                    {
        -                    # If there was something past the closing symbol this wasn't an acceptable comment, so move the lines to code.
        -                    push @codeLines, @commentLines;
        -                    @commentLines = ( );
        -                    };
        -
        -                $line = $lineReader->Get();
        -                }
        -
        -
        -            # Retrieve single line comments.  This leaves $line at the next line.
        -
        -            elsif ($self->StripOpeningSymbols(\$line, $self->LineCommentSymbols()))
        -                {
        -                do
        -                    {
        -                    push @commentLines, $line;
        -                    $line = $lineReader->Get();
        -
        -                    if (!defined $line)
        -                        {  goto EndDo;  };
        -                    }
        -                while ($self->StripOpeningSymbols(\$line, $self->LineCommentSymbols()));
        -
        -                EndDo:  # I hate Perl sometimes.
        -                }
        -
        -
        -            # Otherwise just add it to the code.
        -
        -            else
        -                {
        -                push @codeLines, $line;
        -                $line = $lineReader->Get();
        -                };
        -
        -
        -            # If there were comments, send them to Parser->OnComment().
        -
        -            if (scalar @commentLines)
        -                {
        -                # First process any code lines before the comment.
        -                if (scalar @codeLines)
        -                    {
        -                    $self->OnCode(\@codeLines, $lineNumber, $topicsList, $lastCommentTopicCount);
        -                    $lineNumber += scalar @codeLines;
        -                    @codeLines = ( );
        -                    };
        -
        -                $lastCommentTopicCount = NaturalDocs::Parser->OnComment(\@commentLines, $lineNumber);
        -                $lineNumber += scalar @commentLines;
        -                @commentLines = ( );
        -                };
        -
        -            };  # while (defined $line)
        -
        -
        -        # Clean up any remaining code.
        -        if (scalar @codeLines)
        -            {
        -            $self->OnCode(\@codeLines, $lineNumber, $topicsList, $lastCommentTopicCount);
        -            @codeLines = ( );
        -            };
        -
        -        };
        -
        -    close(SOURCEFILEHANDLE);
        -
        -    return ( undef, undef );
        -    };
        -
        -
        -#
        -#   Function: OnCode
        -#
        -#   Called whenever a section of code is encountered by the parser.  Is used to find the prototype of the last topic created.
        -#
        -#   Parameters:
        -#
        -#       codeLines - The source code as an arrayref of lines.
        -#       codeLineNumber - The line number of the first line of code.
        -#       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
        -#       lastCommentTopicCount - The number of Natural Docs topics that were created by the last comment.
        -#
        -sub OnCode #(codeLines, codeLineNumber, topicList, lastCommentTopicCount)
        -    {
        -    my ($self, $codeLines, $codeLineNumber, $topicList, $lastCommentTopicCount) = @_;
        -
        -    if ($lastCommentTopicCount && defined $self->PrototypeEndersFor($topicList->[-1]->Type()))
        -        {
        -        my $lineIndex = 0;
        -        my $prototype;
        -
        -        # Skip all blank lines before a prototype.
        -        while ($lineIndex < scalar @$codeLines && $codeLines->[$lineIndex] =~ /^[ \t]*$/)
        -            {  $lineIndex++;  };
        -
        -        my @tokens;
        -        my $tokenIndex = 0;
        -
        -        my @brackets;
        -        my $enders = $self->PrototypeEndersFor($topicList->[-1]->Type());
        -
        -        # Add prototype lines until we reach the end of the prototype or the end of the code lines.
        -        while ($lineIndex < scalar @$codeLines)
        -            {
        -            my $line = $self->RemoveLineExtender($codeLines->[$lineIndex] . "\n");
        -
        -            push @tokens, $line =~ /([^\(\)\[\]\{\}\<\>]+|.)/g;
        -
        -            while ($tokenIndex < scalar @tokens)
        -                {
        -                # If we're not inside brackets, check for ender symbols.
        -                if (!scalar @brackets)
        -                    {
        -                    my $startingIndex = 0;
        -                    my $testPrototype;
        -
        -                    for (;;)
        -                        {
        -                        my ($enderIndex, $ender) = ::FindFirstSymbol($tokens[$tokenIndex], $enders, $startingIndex);
        -
        -                        if ($enderIndex == -1)
        -                            {  last;  }
        -                        else
        -                            {
        -                            # We do this here so we don't duplicate prototype for every single token.  Just the first time an ender symbol
        -                            # is found in one.
        -                            if (!defined $testPrototype)
        -                                {  $testPrototype = $prototype;  };
        -
        -                            $testPrototype .= substr($tokens[$tokenIndex], $startingIndex, $enderIndex - $startingIndex);
        -
        -                            my $enderResult;
        -
        -                            # If the ender is all text and the character preceding or following it is as well, ignore it.
        -                            if ($ender =~ /^[a-z0-9]+$/i &&
        -                                ( ($enderIndex > 0 && substr($tokens[$tokenIndex], $enderIndex - 1, 1) =~ /^[a-z0-9_]$/i) ||
        -                                   substr($tokens[$tokenIndex], $enderIndex + length($ender), 1) =~ /^[a-z0-9_]$/i ) )
        -                                {  $enderResult = ENDER_IGNORE();  }
        -                            else
        -                                {  $enderResult = $self->OnPrototypeEnd($topicList->[-1]->Type(), \$testPrototype, $ender);  }
        -
        -                            if ($enderResult == ENDER_IGNORE())
        -                                {
        -                                $testPrototype .= $ender;
        -                                $startingIndex = $enderIndex + length($ender);
        -                                }
        -                            elsif ($enderResult == ENDER_REVERT_TO_ACCEPTED())
        -                                {
        -                                return;
        -                                }
        -                            else # ENDER_ACCEPT || ENDER_ACCEPT_AND_CONTINUE
        -                                {
        -                                my $titleInPrototype = $topicList->[-1]->Title();
        -
        -                                # Strip parenthesis so Function(2) and Function(int, int) will still match Function(anything).
        -                                $titleInPrototype =~ s/[\t ]*\([^\(]*$//;
        -
        -                                if (index($testPrototype, $titleInPrototype) != -1)
        -                                    {
        -                                    $topicList->[-1]->SetPrototype( $self->NormalizePrototype($testPrototype) );
        -                                    };
        -
        -                                if ($enderResult == ENDER_ACCEPT())
        -                                    {  return;  }
        -                                else # ENDER_ACCEPT_AND_CONTINUE
        -                                    {
        -                                    $testPrototype .= $ender;
        -                                    $startingIndex = $enderIndex + length($ender);
        -                                    };
        -                                };
        -                            };
        -                        };
        -                    }
        -
        -                # If we are inside brackets, check for closing symbols.
        -                elsif ( ($tokens[$tokenIndex] eq ')' && $brackets[-1] eq '(') ||
        -                         ($tokens[$tokenIndex] eq ']' && $brackets[-1] eq '[') ||
        -                         ($tokens[$tokenIndex] eq '}' && $brackets[-1] eq '{') ||
        -                         ($tokens[$tokenIndex] eq '>' && $brackets[-1] eq '<') )
        -                    {
        -                    pop @brackets;
        -                    };
        -
        -                # Check for opening brackets.
        -				if ($tokens[$tokenIndex] =~ /^[\(\[\{]$/ ||
        -				    ($tokens[$tokenIndex] eq "<" && $tokens[$tokenIndex-1] !~ /operator[ \t]*$/) )
        -	                {
        -                    push @brackets, $tokens[$tokenIndex];
        -                    };
        -
        -                $prototype .= $tokens[$tokenIndex];
        -                $tokenIndex++;
        -                };
        -
        -            $lineIndex++;
        -            };
        -
        -        # If we got out of that while loop by running out of lines, there was no prototype.
        -        };
        -    };
        -
        -
        -use constant ENDER_ACCEPT => 1;
        -use constant ENDER_IGNORE => 2;
        -use constant ENDER_ACCEPT_AND_CONTINUE => 3;
        -use constant ENDER_REVERT_TO_ACCEPTED => 4;
        -
        -#
        -#   Function: OnPrototypeEnd
        -#
        -#   Called whenever the end of a prototype is found so that there's a chance for derived classes to mark false positives.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> of the prototype.
        -#       prototypeRef - A reference to the prototype so far, minus the ender in dispute.
        -#       ender - The ender symbol.
        -#
        -#   Returns:
        -#
        -#       ENDER_ACCEPT - The ender is accepted and the prototype is finished.
        -#       ENDER_IGNORE - The ender is rejected and parsing should continue.  Note that the prototype will be rejected as a whole
        -#                                  if all enders are ignored before reaching the end of the code.
        -#       ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is.  However, the prototype might
        -#                                                          also continue on so continue parsing.  If there is no accepted ender between here and
        -#                                                          the end of the code this version will be accepted instead.
        -#       ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed.  Use the last accepted
        -#                                                        version and end parsing.
        -#
        -sub OnPrototypeEnd #(type, prototypeRef, ender)
        -    {
        -    return ENDER_ACCEPT();
        -    };
        -
        -
        -#
        -#   Function: RemoveLineExtender
        -#
        -#   If the passed line has a line extender, returns it without the extender or the line break that follows.  If it doesn't, or there are
        -#   no line extenders defined, returns the passed line unchanged.
        -#
        -sub RemoveLineExtender #(line)
        -    {
        -    my ($self, $line) = @_;
        -
        -    if (defined $self->LineExtender())
        -        {
        -        my $lineExtenderIndex = rindex($line, $self->LineExtender());
        -
        -        if ($lineExtenderIndex != -1 &&
        -            substr($line, $lineExtenderIndex + length($self->LineExtender())) =~ /^[ \t]*\n$/)
        -            {
        -            $line = substr($line, 0, $lineExtenderIndex) . ' ';
        -            };
        -        };
        -
        -    return $line;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Tcl.pm b/vendor/naturaldocs/Modules/NaturalDocs/Languages/Tcl.pm
        deleted file mode 100644
        index fde2a190a..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Languages/Tcl.pm
        +++ /dev/null
        @@ -1,220 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Languages::Tcl
        -#
        -###############################################################################
        -#
        -#   A subclass to handle the language variations of Tcl.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Languages::Tcl;
        -
        -use base 'NaturalDocs::Languages::Simple';
        -
        -
        -#
        -#   bool: pastFirstBrace
        -#
        -#   Whether we've past the first brace in a function prototype or not.
        -#
        -my $pastFirstBrace;
        -
        -
        -#
        -#   Function: OnCode
        -#
        -#   This is just overridden to reset <pastFirstBrace>.
        -#
        -sub OnCode #(...)
        -    {
        -    my ($self, @params) = @_;
        -
        -    $pastFirstBrace = 0;
        -
        -    return $self->SUPER::OnCode(@params);
        -    };
        -
        -
        -#
        -#   Function: OnPrototypeEnd
        -#
        -#   Tcl's function syntax is shown below.
        -#
        -#   > proc [name] { [params] } { [code] }
        -#
        -#   The opening brace is one of the prototype enders.  We need to allow the first opening brace because it contains the
        -#   parameters.
        -#
        -#   Also, the parameters may have braces within them.  I've seen one that used { seconds 20 } as a parameter.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> of the prototype.
        -#       prototypeRef - A reference to the prototype so far, minus the ender in dispute.
        -#       ender - The ender symbol.
        -#
        -#   Returns:
        -#
        -#       ENDER_ACCEPT - The ender is accepted and the prototype is finished.
        -#       ENDER_IGNORE - The ender is rejected and parsing should continue.  Note that the prototype will be rejected as a whole
        -#                                  if all enders are ignored before reaching the end of the code.
        -#       ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is.  However, the prototype might
        -#                                                          also continue on so continue parsing.  If there is no accepted ender between here and
        -#                                                          the end of the code this version will be accepted instead.
        -#       ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed.  Use the last accepted
        -#                                                        version and end parsing.
        -#
        -sub OnPrototypeEnd #(type, prototypeRef, ender)
        -    {
        -    my ($self, $type, $prototypeRef, $ender) = @_;
        -
        -    if ($type eq ::TOPIC_FUNCTION() && $ender eq '{' && !$pastFirstBrace)
        -        {
        -        $pastFirstBrace = 1;
        -        return ::ENDER_IGNORE();
        -        }
        -    else
        -        {  return ::ENDER_ACCEPT();  };
        -    };
        -
        -
        -#
        -#   Function: ParsePrototype
        -#
        -#   Parses the prototype and returns it as a <NaturalDocs::Languages::Prototype> object.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType>.
        -#       prototype - The text prototype.
        -#
        -#   Returns:
        -#
        -#       A <NaturalDocs::Languages::Prototype> object.
        -#
        -sub ParsePrototype #(type, prototype)
        -    {
        -    my ($self, $type, $prototype) = @_;
        -
        -    if ($type ne ::TOPIC_FUNCTION())
        -        {
        -        my $object = NaturalDocs::Languages::Prototype->New($prototype);
        -        return $object;
        -        };
        -
        -
        -    # Parse the parameters out of the prototype.
        -
        -    my @tokens = $prototype =~ /([^\{\}\ ]+|.)/g;
        -
        -    my $parameter;
        -    my @parameterLines;
        -
        -    my $braceLevel = 0;
        -
        -    my ($beforeParameters, $afterParameters, $finishedParameters);
        -
        -    foreach my $token (@tokens)
        -        {
        -        if ($finishedParameters)
        -            {  $afterParameters .= $token;  }
        -
        -        elsif ($token eq '{')
        -            {
        -            if ($braceLevel == 0)
        -                {  $beforeParameters .= $token;  }
        -
        -            else # braceLevel > 0
        -                {  $parameter .= $token;   };
        -
        -            $braceLevel++;
        -            }
        -
        -        elsif ($token eq '}')
        -            {
        -            if ($braceLevel == 1)
        -                {
        -                if ($parameter && $parameter ne ' ')
        -                    {  push @parameterLines, $parameter;  };
        -
        -                $finishedParameters = 1;
        -                $afterParameters .= $token;
        -
        -                $braceLevel--;
        -                }
        -            elsif ($braceLevel > 1)
        -                {
        -                $parameter .= $token;
        -                $braceLevel--;
        -                };
        -            }
        -
        -        elsif ($token eq ' ')
        -            {
        -            if ($braceLevel == 1)
        -                {
        -                if ($parameter)
        -                    {  push @parameterLines, $parameter;  };
        -
        -                $parameter = undef;
        -                }
        -            elsif ($braceLevel > 1)
        -                {
        -                $parameter .= $token;
        -                }
        -            else
        -                {
        -                $beforeParameters .= $token;
        -                };
        -            }
        -
        -        else
        -            {
        -            if ($braceLevel > 0)
        -                {  $parameter .= $token;  }
        -            else
        -                {  $beforeParameters .= $token;  };
        -            };
        -        };
        -
        -    foreach my $part (\$beforeParameters, \$afterParameters)
        -        {
        -        $$part =~ s/^ //;
        -        $$part =~ s/ $//;
        -        };
        -
        -    my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
        -
        -
        -    # Parse the actual parameters.
        -
        -    foreach my $parameterLine (@parameterLines)
        -        {
        -        $prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
        -        };
        -
        -    return $prototypeObject;
        -    };
        -
        -
        -#
        -#   Function: ParseParameterLine
        -#
        -#   Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
        -#
        -sub ParseParameterLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -    return NaturalDocs::Languages::Prototype::Parameter->New(undef, undef, $line, undef, undef, undef);
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/LineReader.pm b/vendor/naturaldocs/Modules/NaturalDocs/LineReader.pm
        deleted file mode 100644
        index c732afbd2..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/LineReader.pm
        +++ /dev/null
        @@ -1,166 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::LineReader
        -#
        -###############################################################################
        -#
        -#   An object to handle reading text files line by line in a cross platform manner.  Using this class instead of the standard
        -#	angle brackets approach has the following benefits:
        -#
        -#	- It strips all three types of line breaks automatically: CR/LF (Windows) LF (Unix) and CR (Classic Mac).  You do not need to
        -#	  call chomp().  Perl's chomp() fails when parsing Windows-format line breaks on a Unix platform anyway.  It leaves the /r on,
        -#	  which screws everything up.
        -#	- It reads Classic Mac files line by line correctly, whereas the Perl version returns it all as one line.
        -#	- It abstracts away ignoring the Unicode BOM on the first line, if present.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::LineReader;
        -
        -#
        -#	Constants: Members
        -#
        -#	LINEREADER_FILEHANDLE - The file handle being used to read the file.  Has the LINEREADER_ prefix to make sure it doesn't
        -#											 conflict with any actual filehandles named FILEHANDLE in the program.
        -#	CACHED_LINES - An arrayref of lines already read into memory.
        -#
        -use NaturalDocs::DefineMembers 'LINEREADER_FILEHANDLE',
        -                                                 'CACHED_LINES';
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       filehandle - The file handle being used to read the file.
        -#
        -sub New #(filehandle)
        -    {
        -    my ($selfPackage, $filehandle) = @_;
        -
        -    my $object = [ ];
        -
        -    $object->[LINEREADER_FILEHANDLE] = $filehandle;
        -    $object->[CACHED_LINES] = [ ];
        -
        -    binmode($filehandle, ':raw');
        -
        -    my $possibleBOM = undef;
        -    read($filehandle, $possibleBOM, 2);
        -
        -    if ($possibleBOM eq "\xEF\xBB")
        -        {
        -        read($filehandle, $possibleBOM, 1);
        -        if ($possibleBOM eq "\xBF")
        -            {
        -            seek($filehandle, 3, 0);
        -            binmode($filehandle, ':crlf:encoding(UTF-8)');  # Strict UTF-8, not Perl's lax version.
        -            }
        -        else
        -            {
        -            seek($filehandle, 0, 0);
        -            binmode($filehandle, ':crlf');
        -            }
        -        }
        -    elsif ($possibleBOM eq "\xFE\xFF")
        -        {
        -        seek($filehandle, 2, 0);
        -        binmode($filehandle, ':crlf:encoding(UTF-16BE)');
        -        }
        -    elsif ($possibleBOM eq "\xFF\xFE")
        -        {
        -        seek($filehandle, 2, 0);
        -        binmode($filehandle, ':crlf:encoding(UTF-16LE)');
        -        }
        -    else
        -        {
        -        seek($filehandle, 0, 0);
        -        binmode($filehandle, ':crlf');
        -        }
        -
        -    bless $object, $selfPackage;
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: Chomp
        -#
        -#   Removes any line breaks from the end of a value.  It does not remove any that are in the middle of it.
        -#
        -#   Parameters:
        -#
        -#       lineRef - A *reference* to the line to chomp.
        -#
        -sub Chomp #(lineRef)
        -    {
        -    my ($self, $lineRef) = @_;
        -    $$lineRef =~ s/(?:\r\n|\r|\n)$//;
        -    };
        -
        -
        -#
        -#	Function: Get
        -#
        -#	Returns the next line of text from the file, or undef if there are no more.  The line break will be removed automatically.  If
        -#	the first line contains a Unicode BOM, that will also be removed automatically.
        -#
        -sub Get
        -	{
        -	my $self = shift;
        -	my $line = undef;
        -
        -	if (scalar @{$self->[CACHED_LINES]} == 0)
        -		{
        -		my $filehandle = $self->[LINEREADER_FILEHANDLE];
        -		my $rawLine = <$filehandle>;
        -
        -		if (!defined $rawLine)
        -			{  return undef;  }
        -
        -		$self->Chomp(\$rawLine);
        -
        -        if ($rawLine =~ /\r/)
        -        	{
        -	  		push @{$self->[CACHED_LINES]}, split(/\r/, $rawLine);  # Split for Classic Mac
        -			$line = shift @{$self->[CACHED_LINES]};
        -          	}
        -        else
        -        	{  $line = $rawLine;  }
        -		}
        -	else
        -		{  $line = shift @{$self->[CACHED_LINES]};  }
        -
        -	return $line;
        -	}
        -
        -
        -#
        -#	Function: GetAll
        -#
        -#	Returns an array of all the lines from the file.  The line breaks will be removed automatically.  If the first line contains a
        -#	Unicode BOM, that will also be removed automatically.
        -#
        -sub GetAll
        -	{
        -	my $self = shift;
        -
        -	my $filehandle = $self->[LINEREADER_FILEHANDLE];
        -	my $rawContent;
        -
        -    read($filehandle, $rawContent, -s $filehandle);
        -
        -    return split(/\r\n|\n|\r/, $rawContent);
        -	}
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Menu.pm b/vendor/naturaldocs/Modules/NaturalDocs/Menu.pm
        deleted file mode 100644
        index f0502d9a0..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Menu.pm
        +++ /dev/null
        @@ -1,3405 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Menu
        -#
        -###############################################################################
        -#
        -#   A package handling the menu's contents and state.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - The <Event Handlers> can be called by <NaturalDocs::Project> immediately.
        -#
        -#       - Prior to initialization, <NaturalDocs::Project> must be initialized, and all files that have been changed must be run
        -#         through <NaturalDocs::Parser->ParseForInformation()>.
        -#
        -#       - To initialize, call <LoadAndUpdate()>.  Afterwards, all other functions are available.  Also, <LoadAndUpdate()> will
        -#         call <NaturalDocs::Settings->GenerateDirectoryNames()>.
        -#
        -#       - To save the changes back to disk, call <Save()>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use Tie::RefHash;
        -
        -use NaturalDocs::Menu::Entry;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Menu;
        -
        -
        -#
        -#   Constants: Constants
        -#
        -#   MAXFILESINGROUP - The maximum number of file entries that can be present in a group before it becomes a candidate for
        -#                                  sub-grouping.
        -#   MINFILESINNEWGROUP - The minimum number of file entries that must be present in a group before it will be automatically
        -#                                        created.  This is *not* the number of files that must be in a group before it's deleted.
        -#
        -use constant MAXFILESINGROUP => 6;
        -use constant MINFILESINNEWGROUP => 3;
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   bool: hasChanged
        -#
        -#   Whether the menu changed or not, regardless of why.
        -#
        -my $hasChanged;
        -
        -
        -#
        -#   Object: menu
        -#
        -#   The parsed menu file.  Is stored as a <MENU_GROUP> <NaturalDocs::Menu::Entry> object, with the top-level entries being
        -#   stored as the group's content.  This is done because it makes a number of functions simpler to implement, plus it allows group
        -#   flags to be set on the top-level.  However, it is exposed externally via <Content()> as an arrayref.
        -#
        -#   This structure will only contain objects for <MENU_FILE>, <MENU_GROUP>, <MENU_TEXT>, <MENU_LINK>, and
        -#   <MENU_INDEX> entries.  Other types, such as <MENU_TITLE>, are stored in variables such as <title>.
        -#
        -my $menu;
        -
        -#
        -#   hash: defaultTitlesChanged
        -#
        -#   An existence hash of default titles that have changed, since <OnDefaultTitleChange()> will be called before
        -#   <LoadAndUpdate()>.  Collects them to be applied later.  The keys are the <FileNames>.
        -#
        -my %defaultTitlesChanged;
        -
        -#
        -#   String: title
        -#
        -#   The title of the menu.
        -#
        -my $title;
        -
        -#
        -#   String: subTitle
        -#
        -#   The sub-title of the menu.
        -#
        -my $subTitle;
        -
        -#
        -#   String: footer
        -#
        -#   The footer for the documentation.
        -#
        -my $footer;
        -
        -#
        -#   String: timestampText
        -#
        -#   The timestamp for the documentation, stored as the final output text.
        -#
        -my $timestampText;
        -
        -#
        -#   String: timestampCode
        -#
        -#   The timestamp for the documentation, storted as the symbolic code.
        -#
        -my $timestampCode;
        -
        -#
        -#   hash: indexes
        -#
        -#   An existence hash of all the defined index <TopicTypes> appearing in the menu.
        -#
        -my %indexes;
        -
        -#
        -#   hash: previousIndexes
        -#
        -#   An existence hash of all the index <TopicTypes> that appeared in the menu last time.
        -#
        -my %previousIndexes;
        -
        -#
        -#   hash: bannedIndexes
        -#
        -#   An existence hash of all the index <TopicTypes> that the user has manually deleted, and thus should not be added back to
        -#   the menu automatically.
        -#
        -my %bannedIndexes;
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -#
        -#   File: Menu.txt
        -#
        -#   The file used to generate the menu.
        -#
        -#   Format:
        -#
        -#       The file is plain text.  Blank lines can appear anywhere and are ignored.  Tags and their content must be completely
        -#       contained on one line with the exception of Group's braces.  All values in brackets below are encoded with entity characters.
        -#
        -#       > # [comment]
        -#
        -#       The file supports single-line comments via #.  They can appear alone on a line or after content.
        -#
        -#       > Format: [version]
        -#       > Title: [title]
        -#       > SubTitle: [subtitle]
        -#       > Footer: [footer]
        -#       > Timestamp: [timestamp code]
        -#
        -#       The file format version, menu title, subtitle, footer, and timestamp are specified as above.  Each can only be specified once,
        -#       with subsequent ones being ignored.  Subtitle is ignored if Title is not present.  Format must be the first entry in the file.  If
        -#       it's not present, it's assumed the menu is from version 0.95 or earlier, since it was added with 1.0.
        -#
        -#       The timestamp code is as follows.
        -#
        -#           m - Single digit month, where applicable.  January is "1".
        -#           mm - Always double digit month.  January is "01".
        -#           mon - Short month word.  January is "Jan".
        -#           month - Long month word.  January is "January".
        -#           d - Single digit day, where applicable.  1 is "1".
        -#           dd - Always double digit day.  1 is "01".
        -#           day - Day with text extension.  1 is "1st".
        -#           yy - Double digit year.  2006 is "06".
        -#           yyyy - Four digit year.  2006 is "2006".
        -#           year - Four digit year.  2006 is "2006".
        -#
        -#       Anything else is left literal in the output.
        -#
        -#       > File: [title] ([file name])
        -#       > File: [title] (auto-title, [file name])
        -#       > File: [title] (no auto-title, [file name])
        -#
        -#       Files are specified as above.  If there is only one input directory, file names are relative.  Otherwise they are absolute.
        -#       If "no auto-title" is specified, the title on the line is used.  If not, the title is ignored and the
        -#       default file title is used instead.  Auto-title defaults to on, so specifying "auto-title" is for compatibility only.
        -#
        -#       > Group: [title]
        -#       > Group: [title] { ... }
        -#
        -#       Groups are specified as above.  If no braces are specified, the group's content is everything that follows until the end of the
        -#       file, the next group (braced or unbraced), or the closing brace of a parent group.  Group braces are the only things in this
        -#       file that can span multiple lines.
        -#
        -#       There is no limitations on where the braces can appear.  The opening brace can appear after the group tag, on its own line,
        -#       or preceding another tag on a line.  Similarly, the closing brace can appear after another tag or on its own line.  Being
        -#       bitchy here would just get in the way of quick and dirty editing; the package will clean it up automatically when it writes it
        -#       back to disk.
        -#
        -#       > Text: [text]
        -#
        -#       Arbitrary text is specified as above.  As with other tags, everything must be contained on the same line.
        -#
        -#       > Link: [URL]
        -#       > Link: [title] ([URL])
        -#
        -#       External links can be specified as above.  If the titled form is not used, the URL is used as the title.
        -#
        -#       > Index: [name]
        -#       > [topic type name] Index: [name]
        -#
        -#       Indexes are specified as above.  The topic type names can be either singular or plural.  General is assumed if not specified.
        -#
        -#       > Don't Index: [topic type name]
        -#       > Don't Index: [topic type name], [topic type name], ...
        -#
        -#       The option above prevents indexes that exist but are not on the menu from being automatically added.
        -#
        -#       > Data: [number]([obscured data])
        -#
        -#       Used to store non-user editable data.
        -#
        -#       > Data: 1([obscured: [directory name]///[input directory]])
        -#
        -#       When there is more than one directory, these lines store the input directories used in the last run and their names.  This
        -#       allows menu files to be shared across machines since the names will be consistent and the directories can be used to convert
        -#       filenames to the local machine's paths.  We don't want this user-editable because they may think changing it changes the
        -#       input directories, when it doesn't.  Also, changing it without changing all the paths screws up resolving.
        -#
        -#       > Data: 2([obscured: [directory name])
        -#
        -#       When there is only one directory and its name is not "default", this stores the name.
        -#
        -#
        -#   Entities:
        -#
        -#       &amp; - Ampersand.
        -#       &lparen; - Left parenthesis.
        -#       &rparen; - Right parenthesis.
        -#       &lbrace; - Left brace.
        -#       &rbrace; - Right brace.
        -#
        -#
        -#   Revisions:
        -#
        -#       1.4:
        -#
        -#           - Added Timestamp property.
        -#           - Values are now encoded with entity characters.
        -#
        -#       1.3:
        -#
        -#           - File names are now relative again if there is only one input directory.
        -#           - Data: 2(...) added.
        -#           - Can't use synonyms like "copyright" for "footer" or "sub-title" for "subtitle".
        -#           - "Don't Index" line now requires commas to separate them, whereas it tolerated just spaces before.
        -#
        -#       1.16:
        -#
        -#           - File names are now absolute instead of relative.  Prior to 1.16 only one input directory was allowed, so they could be
        -#             relative.
        -#           - Data keywords introduced to store input directories and their names.
        -#
        -#       1.14:
        -#
        -#           - Renamed this file from NaturalDocs_Menu.txt to Menu.txt.
        -#
        -#       1.1:
        -#
        -#           - Added the "don't index" line.
        -#
        -#           This is also the point where indexes were automatically added and removed, so all index entries from prior revisions
        -#           were manually added and are not guaranteed to contain anything.
        -#
        -#       1.0:
        -#
        -#           - Added the format line.
        -#           - Added the "no auto-title" attribute.
        -#           - Changed the file entry default to auto-title.
        -#
        -#           This is also the point where auto-organization and better auto-titles were introduced.  All groups in prior revisions were
        -#           manually added, with the exception of a top-level Other group where new files were automatically added if there were
        -#           groups defined.
        -#
        -#       Break in support:
        -#
        -#           Releases prior to 1.0 are no longer supported.  Why?
        -#
        -#           - They don't have a Format: line, which is required by <NaturalDocs::ConfigFile>, although I could work around this
        -#             if I needed to.
        -#           - No significant number of downloads for pre-1.0 releases.
        -#           - Code simplification.  I don't have to bridge the conversion from manual-only menu organization to automatic.
        -#
        -#       0.9:
        -#
        -#           - Added index entries.
        -#
        -
        -#
        -#   File: PreviousMenuState.nd
        -#
        -#   The file used to store the previous state of the menu so as to detect changes.
        -#
        -#
        -#   Format:
        -#
        -#   > [BINARY_FORMAT]
        -#   > [VersionInt: app version]
        -#
        -#   First is the standard <BINARY_FORMAT> <VersionInt> header.
        -#
        -#   > [UInt8: 0 (end group)]
        -#   > [UInt8: MENU_FILE] [UInt8: noAutoTitle] [AString16: title] [AString16: target]
        -#   > [UInt8: MENU_GROUP] [AString16: title]
        -#   > [UInt8: MENU_INDEX] [AString16: title] [AString16: topic type]
        -#   > [UInt8: MENU_LINK] [AString16: title] [AString16: url]
        -#   > [UInt8: MENU_TEXT] [AString16: text]
        -#
        -#   The first UInt8 of each following line is either zero or one of the <Menu Entry Types>.  What follows is contextual.
        -#
        -#   There are no entries for title, subtitle, or footer.  Only the entries present in <menu>.
        -#
        -#   See Also:
        -#
        -#       <File Format Conventions>
        -#
        -#   Dependencies:
        -#
        -#       - Because the type is represented by a UInt8, the <Menu Entry Types> must all be <= 255.
        -#
        -#   Revisions:
        -#
        -#       1.3:
        -#
        -#           - The topic type following the <MENU_INDEX> entries were changed from UInt8s to AString16s, since <TopicTypes>
        -#             were switched from integer constants to strings.  You can still convert the old to the new via
        -#             <NaturalDocs::Topics->TypeFromLegacy()>.
        -#
        -#       1.16:
        -#
        -#           - The file targets are now absolute.  Prior to 1.16, they were relative to the input directory since only one was allowed.
        -#
        -#       1.14:
        -#
        -#           - The file was renamed from NaturalDocs.m to PreviousMenuState.nd and moved into the Data subdirectory.
        -#
        -#       1.0:
        -#
        -#           - The file's format was completely redone.  Prior to 1.0, the file was a text file consisting of the app version and a line
        -#             which was a tab-separated list of the indexes present in the menu.  * meant the general index.
        -#
        -#       Break in support:
        -#
        -#           Pre-1.0 files are no longer supported.  There was no significant number of downloads for pre-1.0 releases, and this
        -#           eliminates a separate code path for them.
        -#
        -#       0.95:
        -#
        -#           - Change the file version to match the app version.  Prior to 0.95, the version line was 1.  Test for "1" instead of "1.0" to
        -#             distinguish.
        -#
        -#       0.9:
        -#
        -#           - The file was added to the project.  Prior to 0.9, it didn't exist.
        -#
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -#
        -#   Function: LoadAndUpdate
        -#
        -#   Loads the menu file from disk and updates it.  Will add, remove, rearrange, and remove auto-titling from entries as
        -#   necessary.  Will also call <NaturalDocs::Settings->GenerateDirectoryNames()>.
        -#
        -sub LoadAndUpdate
        -    {
        -    my ($self) = @_;
        -
        -    my ($inputDirectoryNames, $relativeFiles, $onlyDirectoryName) = $self->LoadMenuFile();
        -
        -    my $errorCount = NaturalDocs::ConfigFile->ErrorCount();
        -    if ($errorCount)
        -        {
        -        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
        -        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
        -                                                    . ' in ' . NaturalDocs::Project->UserConfigFile('Menu.txt'));
        -        };
        -
        -    # If the menu has a timestamp and today is a different day than the last time Natural Docs was run, we have to count it as the
        -    # menu changing.
        -    if (defined $timestampCode)
        -        {
        -        my (undef, undef, undef, $currentDay, $currentMonth, $currentYear) = localtime();
        -        my (undef, undef, undef, $lastDay, $lastMonth, $lastYear) =
        -            localtime( (stat( NaturalDocs::Project->DataFile('PreviousMenuState.nd') ))[9] );
        -            # This should be okay if the previous menu state file doesn't exist.
        -
        -        if ($currentDay != $lastDay || $currentMonth != $lastMonth || $currentYear != $lastYear)
        -            {  $hasChanged = 1;  };
        -        };
        -
        -
        -    if ($relativeFiles)
        -        {
        -        my $inputDirectory = $self->ResolveRelativeInputDirectories($onlyDirectoryName);
        -
        -        if ($onlyDirectoryName)
        -            {  $inputDirectoryNames = { $inputDirectory => $onlyDirectoryName };  };
        -        }
        -    else
        -        {  $self->ResolveInputDirectories($inputDirectoryNames);  };
        -
        -    NaturalDocs::Settings->GenerateDirectoryNames($inputDirectoryNames);
        -
        -    my $filesInMenu = $self->FilesInMenu();
        -
        -    my ($previousMenu, $previousIndexes, $previousFiles) = $self->LoadPreviousMenuStateFile();
        -
        -    if (defined $previousIndexes)
        -        {  %previousIndexes = %$previousIndexes;  };
        -
        -    if (defined $previousFiles)
        -        {  $self->LockUserTitleChanges($previousFiles);  };
        -
        -    # Don't need these anymore.  We keep this level of detail because it may be used more in the future.
        -    $previousMenu = undef;
        -    $previousFiles = undef;
        -    $previousIndexes = undef;
        -
        -    # We flag title changes instead of actually performing them at this point for two reasons.  First, contents of groups are still
        -    # subject to change, which would affect the generated titles.  Second, we haven't detected the sort order yet.  Changing titles
        -    # could make groups appear unalphabetized when they were beforehand.
        -
        -    my $updateAllTitles;
        -
        -    # If the menu file changed, we can't be sure which groups changed and which didn't without a comparison, which really isn't
        -    # worth the trouble.  So we regenerate all the titles instead.
        -    if (NaturalDocs::Project->UserConfigFileStatus('Menu.txt') == ::FILE_CHANGED())
        -        {  $updateAllTitles = 1;  }
        -    else
        -        {  $self->FlagAutoTitleChanges();  };
        -
        -    # We add new files before deleting old files so their presence still affects the grouping.  If we deleted old files first, it could
        -    # throw off where to place the new ones.
        -
        -    $self->AutoPlaceNewFiles($filesInMenu);
        -
        -    my $numberRemoved = $self->RemoveDeadFiles();
        -
        -    $self->CheckForTrashedMenu(scalar keys %$filesInMenu, $numberRemoved);
        -
        -    # Don't ban indexes if they deleted Menu.txt.  They may have not deleted PreviousMenuState.nd and we don't want everything
        -    # to be banned because of it.
        -    if (NaturalDocs::Project->UserConfigFileStatus('Menu.txt') != ::FILE_DOESNTEXIST())
        -        {  $self->BanAndUnbanIndexes();  };
        -
        -    # Index groups need to be detected before adding new ones.
        -
        -    $self->DetectIndexGroups();
        -
        -    $self->AddAndRemoveIndexes();
        -
        -   # We wait until after new files are placed to remove dead groups because a new file may save a group.
        -
        -    $self->RemoveDeadGroups();
        -
        -    $self->CreateDirectorySubGroups();
        -
        -    # We detect the sort before regenerating the titles so it doesn't get thrown off by changes.  However, we do it after deleting
        -    # dead entries and moving things into subgroups because their removal may bump it into a stronger sort category (i.e.
        -    # SORTFILESANDGROUPS instead of just SORTFILES.)  New additions don't factor into the sort.
        -
        -    $self->DetectOrder($updateAllTitles);
        -
        -    $self->GenerateAutoFileTitles($updateAllTitles);
        -
        -    $self->ResortGroups($updateAllTitles);
        -
        -
        -    # Don't need this anymore.
        -    %defaultTitlesChanged = ( );
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Writes the changes to the menu files.
        -#
        -sub Save
        -    {
        -    my ($self) = @_;
        -
        -    if ($hasChanged)
        -        {
        -        $self->SaveMenuFile();
        -        $self->SavePreviousMenuStateFile();
        -        };
        -    };
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -#
        -#   Function: HasChanged
        -#
        -#   Returns whether the menu has changed or not.
        -#
        -sub HasChanged
        -    {  return $hasChanged;  };
        -
        -#
        -#   Function: Content
        -#
        -#   Returns the parsed menu as an arrayref of <NaturalDocs::Menu::Entry> objects.  Do not change the arrayref.
        -#
        -#   The arrayref will only contain <MENU_FILE>, <MENU_GROUP>, <MENU_INDEX>, <MENU_TEXT>, and <MENU_LINK>
        -#   entries.  Entries such as <MENU_TITLE> are parsed out and are only accessible via functions such as <Title()>.
        -#
        -sub Content
        -    {  return $menu->GroupContent();  };
        -
        -#
        -#   Function: Title
        -#
        -#   Returns the title of the menu, or undef if none.
        -#
        -sub Title
        -    {  return $title;  };
        -
        -#
        -#   Function: SubTitle
        -#
        -#   Returns the sub-title of the menu, or undef if none.
        -#
        -sub SubTitle
        -    {  return $subTitle;  };
        -
        -#
        -#   Function: Footer
        -#
        -#   Returns the footer of the documentation, or undef if none.
        -#
        -sub Footer
        -    {  return $footer;  };
        -
        -#
        -#   Function: TimeStamp
        -#
        -#   Returns the timestamp text of the documentation, or undef if none.
        -#
        -sub TimeStamp
        -    {  return $timestampText;  };
        -
        -#
        -#   Function: Indexes
        -#
        -#   Returns an existence hashref of all the index <TopicTypes> appearing in the menu.  Do not change the hashref.
        -#
        -sub Indexes
        -    {  return \%indexes;  };
        -
        -#
        -#   Function: PreviousIndexes
        -#
        -#   Returns an existence hashref of all the index <TopicTypes> that previously appeared in the menu.  Do not change the
        -#   hashref.
        -#
        -sub PreviousIndexes
        -    {  return \%previousIndexes;  };
        -
        -
        -#
        -#   Function: FilesInMenu
        -#
        -#   Returns a hashref of all the files present in the menu.  The keys are the <FileNames>, and the values are references to their
        -#   <NaturalDocs::Menu::Entry> objects.
        -#
        -sub FilesInMenu
        -    {
        -    my ($self) = @_;
        -
        -    my @groupStack = ( $menu );
        -    my $filesInMenu = { };
        -
        -    while (scalar @groupStack)
        -        {
        -        my $currentGroup = pop @groupStack;
        -        my $currentGroupContent = $currentGroup->GroupContent();
        -
        -        foreach my $entry (@$currentGroupContent)
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {  push @groupStack, $entry;  }
        -            elsif ($entry->Type() == ::MENU_FILE())
        -                {  $filesInMenu->{ $entry->Target() } = $entry;  };
        -            };
        -        };
        -
        -    return $filesInMenu;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Event Handlers
        -#
        -#   These functions are called by <NaturalDocs::Project> only.  You don't need to worry about calling them.  For example, when
        -#   changing the default menu title of a file, you only need to call <NaturalDocs::Project->SetDefaultMenuTitle()>.  That function
        -#   will handle calling <OnDefaultTitleChange()>.
        -
        -
        -#
        -#   Function: OnDefaultTitleChange
        -#
        -#   Called by <NaturalDocs::Project> if the default menu title of a source file has changed.
        -#
        -#   Parameters:
        -#
        -#       file    - The source <FileName> that had its default menu title changed.
        -#
        -sub OnDefaultTitleChange #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    # Collect them for later.  We'll deal with them in LoadAndUpdate().
        -
        -    $defaultTitlesChanged{$file} = 1;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: LoadMenuFile
        -#
        -#   Loads and parses the menu file <Menu.txt>.  This will fill <menu>, <title>, <subTitle>, <footer>, <timestampText>,
        -#   <timestampCode>, <indexes>, and <bannedIndexes>.  If there are any errors in the file, they will be recorded with
        -#   <NaturalDocs::ConfigFile->AddError()>.
        -#
        -#   Returns:
        -#
        -#       The array ( inputDirectories, relativeFiles, onlyDirectoryName ) or an empty array if the file doesn't exist.
        -#
        -#       inputDirectories - A hashref of all the input directories and their names stored in the menu file.  The keys are the
        -#                                 directories and the values are their names.  Undef if none.
        -#       relativeFiles - Whether the menu uses relative file names.
        -#       onlyDirectoryName - The name of the input directory if there is only one.
        -#
        -sub LoadMenuFile
        -    {
        -    my ($self) = @_;
        -
        -    my $inputDirectories = { };
        -    my $relativeFiles;
        -    my $onlyDirectoryName;
        -
        -    # A stack of Menu::Entry object references as we move through the groups.
        -    my @groupStack;
        -
        -    $menu = NaturalDocs::Menu::Entry->New(::MENU_GROUP(), undef, undef, undef);
        -    my $currentGroup = $menu;
        -
        -    # Whether we're currently in a braceless group, since we'd have to find the implied end rather than an explicit one.
        -    my $inBracelessGroup;
        -
        -    # Whether we're right after a group token, which is the only place there can be an opening brace.
        -    my $afterGroupToken;
        -
        -    my $version;
        -
        -    if ($version = NaturalDocs::ConfigFile->Open(NaturalDocs::Project->UserConfigFile('Menu.txt'), 1))
        -        {
        -        # We don't check if the menu file is from a future version because we can't just throw it out and regenerate it like we can
        -        # with other data files.  So we just keep going regardless.  Any syntactic differences will show up as errors.
        -
        -        while (my ($keyword, $value, $comment) = NaturalDocs::ConfigFile->GetLine())
        -            {
        -            # Check for an opening brace after a group token.  This has to be separate from the rest of the code because the flag
        -            # needs to be reset after every line.
        -            if ($afterGroupToken)
        -                {
        -                $afterGroupToken = undef;
        -
        -                if ($keyword eq '{')
        -                    {
        -                    $inBracelessGroup = undef;
        -                    next;
        -                    }
        -                else
        -                    {  $inBracelessGroup = 1;  };
        -                };
        -
        -
        -            # Now on to the real code.
        -
        -            if ($keyword eq 'file')
        -                {
        -                my $flags = 0;
        -
        -                if ($value =~ /^(.+)\(([^\(]+)\)$/)
        -                    {
        -                    my ($title, $file) = ($1, $2);
        -
        -                    $title =~ s/ +$//;
        -
        -                    # Check for auto-title modifier.
        -                    if ($file =~ /^((?:no )?auto-title, ?)(.+)$/i)
        -                        {
        -                        my $modifier;
        -                        ($modifier, $file) = ($1, $2);
        -
        -                        if ($modifier =~ /^no/i)
        -                            {  $flags |= ::MENU_FILE_NOAUTOTITLE();  };
        -                        };
        -
        -                    my $entry = NaturalDocs::Menu::Entry->New(::MENU_FILE(), $self->RestoreAmpChars($title),
        -                                                                                       $self->RestoreAmpChars($file), $flags);
        -
        -                    $currentGroup->PushToGroup($entry);
        -                    }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('File lines must be in the format "File: [title] ([location])"');  };
        -                }
        -
        -            elsif ($keyword eq 'group')
        -                {
        -                # End a braceless group, if we were in one.
        -                if ($inBracelessGroup)
        -                    {
        -                    $currentGroup = pop @groupStack;
        -                    $inBracelessGroup = undef;
        -                    };
        -
        -                my $entry = NaturalDocs::Menu::Entry->New(::MENU_GROUP(), $self->RestoreAmpChars($value), undef, undef);
        -
        -                $currentGroup->PushToGroup($entry);
        -
        -                push @groupStack, $currentGroup;
        -                $currentGroup = $entry;
        -
        -                $afterGroupToken = 1;
        -                }
        -
        -
        -            elsif ($keyword eq '{')
        -                {
        -                NaturalDocs::ConfigFile->AddError('Opening braces are only allowed after Group tags.');
        -                }
        -
        -
        -            elsif ($keyword eq '}')
        -                {
        -                # End a braceless group, if we were in one.
        -                if ($inBracelessGroup)
        -                    {
        -                    $currentGroup = pop @groupStack;
        -                    $inBracelessGroup = undef;
        -                    };
        -
        -                # End a braced group too.
        -                if (scalar @groupStack)
        -                    {  $currentGroup = pop @groupStack;  }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Unmatched closing brace.');  };
        -                }
        -
        -
        -            elsif ($keyword eq 'title')
        -                {
        -                if (!defined $title)
        -                    {  $title = $self->RestoreAmpChars($value);  }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Title can only be defined once.');  };
        -                }
        -
        -
        -            elsif ($keyword eq 'subtitle')
        -                {
        -                if (defined $title)
        -                    {
        -                    if (!defined $subTitle)
        -                        {  $subTitle = $self->RestoreAmpChars($value);  }
        -                    else
        -                        {  NaturalDocs::ConfigFile->AddError('SubTitle can only be defined once.');  };
        -                    }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Title must be defined before SubTitle.');  };
        -                }
        -
        -
        -            elsif ($keyword eq 'footer')
        -                {
        -                if (!defined $footer)
        -                    {  $footer = $self->RestoreAmpChars($value);  }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Footer can only be defined once.');  };
        -                }
        -
        -
        -            elsif ($keyword eq 'timestamp')
        -                {
        -                if (!defined $timestampCode)
        -                    {
        -                    $timestampCode = $self->RestoreAmpChars($value);
        -                    $self->GenerateTimestampText();
        -                    }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Timestamp can only be defined once.');  };
        -                }
        -
        -
        -            elsif ($keyword eq 'text')
        -                {
        -                $currentGroup->PushToGroup( NaturalDocs::Menu::Entry->New(::MENU_TEXT(), $self->RestoreAmpChars($value),
        -                                                                                                              undef, undef) );
        -                }
        -
        -
        -            elsif ($keyword eq 'link')
        -                {
        -                my ($title, $url);
        -
        -                if ($value =~ /^([^\(\)]+?) ?\(([^\)]+)\)$/)
        -                    {
        -                    ($title, $url) = ($1, $2);
        -                    }
        -                elsif (defined $comment)
        -                    {
        -                    $value .= $comment;
        -
        -                    if ($value =~ /^([^\(\)]+?) ?\(([^\)]+)\) ?(?:#.*)?$/)
        -                        {
        -                        ($title, $url) = ($1, $2);
        -                        };
        -                    };
        -
        -                if ($title)
        -                    {
        -                    $currentGroup->PushToGroup( NaturalDocs::Menu::Entry->New(::MENU_LINK(), $self->RestoreAmpChars($title),
        -                                                                 $self->RestoreAmpChars($url), undef) );
        -                    }
        -                else
        -                    {  NaturalDocs::ConfigFile->AddError('Link lines must be in the format "Link: [title] ([url])"');  };
        -                }
        -
        -
        -            elsif ($keyword eq 'data')
        -                {
        -                $value =~ /^(\d)\((.*)\)$/;
        -                my ($number, $data) = ($1, $2);
        -
        -                $data = NaturalDocs::ConfigFile->Unobscure($data);
        -
        -                # The input directory naming convention changed with version 1.32, but NaturalDocs::Settings will handle that
        -                # automatically.
        -
        -                if ($number == 1)
        -                    {
        -                    my ($dirName, $inputDir) = split(/\/\/\//, $data, 2);
        -                    $inputDirectories->{$inputDir} = $dirName;
        -                    }
        -                elsif ($number == 2)
        -                    {  $onlyDirectoryName = $data;  };
        -                # Ignore other numbers because it may be from a future format and we don't want to make the user delete it
        -                # manually.
        -                }
        -
        -            elsif ($keyword eq "don't index")
        -                {
        -                my @indexes = split(/, ?/, $value);
        -
        -                foreach my $index (@indexes)
        -                    {
        -                    my $indexType = NaturalDocs::Topics->TypeFromName( $self->RestoreAmpChars($index) );
        -
        -                    if (defined $indexType)
        -                        {  $bannedIndexes{$indexType} = 1;  };
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'index')
        -                {
        -                my $entry = NaturalDocs::Menu::Entry->New(::MENU_INDEX(), $self->RestoreAmpChars($value),
        -                                                                                   ::TOPIC_GENERAL(), undef);
        -                $currentGroup->PushToGroup($entry);
        -
        -                $indexes{::TOPIC_GENERAL()} = 1;
        -                }
        -
        -            elsif (substr($keyword, -6) eq ' index')
        -                {
        -                my $index = substr($keyword, 0, -6);
        -                my ($indexType, $indexInfo) = NaturalDocs::Topics->NameInfo( $self->RestoreAmpChars($index) );
        -
        -                if (defined $indexType)
        -                    {
        -                    if ($indexInfo->Index())
        -                        {
        -                        $indexes{$indexType} = 1;
        -                        $currentGroup->PushToGroup(
        -                            NaturalDocs::Menu::Entry->New(::MENU_INDEX(), $self->RestoreAmpChars($value), $indexType, undef) );
        -                        }
        -                    else
        -                        {
        -                        # If it's on the menu but isn't indexable, the topic setting may have changed out from under it.
        -                        $hasChanged = 1;
        -                        };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError($index . ' is not a valid index type.');
        -                    };
        -                }
        -
        -            else
        -                {
        -                NaturalDocs::ConfigFile->AddError(ucfirst($keyword) . ' is not a valid keyword.');
        -                };
        -            };
        -
        -
        -        # End a braceless group, if we were in one.
        -        if ($inBracelessGroup)
        -            {
        -            $currentGroup = pop @groupStack;
        -            $inBracelessGroup = undef;
        -            };
        -
        -        # Close up all open groups.
        -        my $openGroups = 0;
        -        while (scalar @groupStack)
        -            {
        -            $currentGroup = pop @groupStack;
        -            $openGroups++;
        -            };
        -
        -        if ($openGroups == 1)
        -            {  NaturalDocs::ConfigFile->AddError('There is an unclosed group.');  }
        -        elsif ($openGroups > 1)
        -            {  NaturalDocs::ConfigFile->AddError('There are ' . $openGroups . ' unclosed groups.');  };
        -
        -
        -        if (!scalar keys %$inputDirectories)
        -            {
        -            $inputDirectories = undef;
        -            $relativeFiles = 1;
        -            };
        -
        -        NaturalDocs::ConfigFile->Close();
        -
        -        return ($inputDirectories, $relativeFiles, $onlyDirectoryName);
        -        }
        -
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -#
        -#   Function: SaveMenuFile
        -#
        -#   Saves the current menu to <Menu.txt>.
        -#
        -sub SaveMenuFile
        -    {
        -    my ($self) = @_;
        -
        -    open(MENUFILEHANDLE, '>' . NaturalDocs::Project->UserConfigFile('Menu.txt'))
        -        or die "Couldn't save menu file " . NaturalDocs::Project->UserConfigFile('Menu.txt') . "\n";
        -
        -
        -    print MENUFILEHANDLE
        -    "Format: " . NaturalDocs::Settings->TextAppVersion() . "\n\n\n";
        -
        -    my $inputDirs = NaturalDocs::Settings->InputDirectories();
        -
        -
        -    if (defined $title)
        -        {
        -        print MENUFILEHANDLE 'Title: ' . $self->ConvertAmpChars($title) . "\n";
        -
        -        if (defined $subTitle)
        -            {
        -            print MENUFILEHANDLE 'SubTitle: ' . $self->ConvertAmpChars($subTitle) . "\n";
        -            }
        -        else
        -            {
        -            print MENUFILEHANDLE
        -            "\n"
        -            . "# You can also add a sub-title to your menu like this:\n"
        -            . "# SubTitle: [subtitle]\n";
        -            };
        -        }
        -    else
        -        {
        -        print MENUFILEHANDLE
        -        "# You can add a title and sub-title to your menu like this:\n"
        -        . "# Title: [project name]\n"
        -        . "# SubTitle: [subtitle]\n";
        -        };
        -
        -    print MENUFILEHANDLE "\n";
        -
        -    if (defined $footer)
        -        {
        -        print MENUFILEHANDLE 'Footer: ' . $self->ConvertAmpChars($footer) . "\n";
        -        }
        -    else
        -        {
        -        print MENUFILEHANDLE
        -        "# You can add a footer to your documentation like this:\n"
        -        . "# Footer: [text]\n"
        -        . "# If you want to add a copyright notice, this would be the place to do it.\n";
        -        };
        -
        -    if (defined $timestampCode)
        -        {
        -        print MENUFILEHANDLE 'Timestamp: ' . $self->ConvertAmpChars($timestampCode) . "\n";
        -        }
        -    else
        -        {
        -        print MENUFILEHANDLE
        -        "\n"
        -        . "# You can add a timestamp to your documentation like one of these:\n"
        -        . "# Timestamp: Generated on month day, year\n"
        -        . "# Timestamp: Updated mm/dd/yyyy\n"
        -        . "# Timestamp: Last updated mon day\n"
        -        . "#\n";
        -        };
        -
        -    print MENUFILEHANDLE
        -        qq{#   m     - One or two digit month.  January is "1"\n}
        -        . qq{#   mm    - Always two digit month.  January is "01"\n}
        -        . qq{#   mon   - Short month word.  January is "Jan"\n}
        -        . qq{#   month - Long month word.  January is "January"\n}
        -        . qq{#   d     - One or two digit day.  1 is "1"\n}
        -        . qq{#   dd    - Always two digit day.  1 is "01"\n}
        -        . qq{#   day   - Day with letter extension.  1 is "1st"\n}
        -        . qq{#   yy    - Two digit year.  2006 is "06"\n}
        -        . qq{#   yyyy  - Four digit year.  2006 is "2006"\n}
        -        . qq{#   year  - Four digit year.  2006 is "2006"\n}
        -
        -        . "\n";
        -
        -    if (scalar keys %bannedIndexes)
        -        {
        -        print MENUFILEHANDLE
        -
        -        "# These are indexes you deleted, so Natural Docs will not add them again\n"
        -        . "# unless you remove them from this line.\n"
        -        . "\n"
        -        . "Don't Index: ";
        -
        -        my $first = 1;
        -
        -        foreach my $index (keys %bannedIndexes)
        -            {
        -            if (!$first)
        -                {  print MENUFILEHANDLE ', ';  }
        -            else
        -                {  $first = undef;  };
        -
        -            print MENUFILEHANDLE $self->ConvertAmpChars( NaturalDocs::Topics->NameOfType($index, 1), CONVERT_COMMAS() );
        -            };
        -
        -        print MENUFILEHANDLE "\n\n";
        -        };
        -
        -
        -    # Remember to keep lines below eighty characters.
        -
        -    print MENUFILEHANDLE
        -    "\n"
        -    . "# --------------------------------------------------------------------------\n"
        -    . "# \n"
        -    . "# Cut and paste the lines below to change the order in which your files\n"
        -    . "# appear on the menu.  Don't worry about adding or removing files, Natural\n"
        -    . "# Docs will take care of that.\n"
        -    . "# \n"
        -    . "# You can further organize the menu by grouping the entries.  Add a\n"
        -    . "# \"Group: [name] {\" line to start a group, and add a \"}\" to end it.\n"
        -    . "# \n"
        -    . "# You can add text and web links to the menu by adding \"Text: [text]\" and\n"
        -    . "# \"Link: [name] ([URL])\" lines, respectively.\n"
        -    . "# \n"
        -    . "# The formatting and comments are auto-generated, so don't worry about\n"
        -    . "# neatness when editing the file.  Natural Docs will clean it up the next\n"
        -    . "# time it is run.  When working with groups, just deal with the braces and\n"
        -    . "# forget about the indentation and comments.\n"
        -    . "# \n";
        -
        -    if (scalar @$inputDirs > 1)
        -        {
        -        print MENUFILEHANDLE
        -        "# You can use this file on other computers even if they use different\n"
        -        . "# directories.  As long as the command line points to the same source files,\n"
        -        . "# Natural Docs will be able to correct the locations automatically.\n"
        -        . "# \n";
        -        };
        -
        -    print MENUFILEHANDLE
        -    "# --------------------------------------------------------------------------\n"
        -
        -    . "\n\n";
        -
        -
        -    $self->WriteMenuEntries($menu->GroupContent(), \*MENUFILEHANDLE, undef, (scalar @$inputDirs == 1));
        -
        -
        -    if (scalar @$inputDirs > 1)
        -        {
        -        print MENUFILEHANDLE
        -        "\n\n##### Do not change or remove these lines. #####\n";
        -
        -        foreach my $inputDir (@$inputDirs)
        -            {
        -            print MENUFILEHANDLE
        -            'Data: 1(' . NaturalDocs::ConfigFile->Obscure( NaturalDocs::Settings->InputDirectoryNameOf($inputDir)
        -                                                                              . '///' . $inputDir ) . ")\n";
        -            };
        -        }
        -    elsif (lc(NaturalDocs::Settings->InputDirectoryNameOf($inputDirs->[0])) != 1)
        -        {
        -        print MENUFILEHANDLE
        -        "\n\n##### Do not change or remove this line. #####\n"
        -        . 'Data: 2(' . NaturalDocs::ConfigFile->Obscure( NaturalDocs::Settings->InputDirectoryNameOf($inputDirs->[0]) ) . ")\n";
        -        }
        -
        -    close(MENUFILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: WriteMenuEntries
        -#
        -#   A recursive function to write the contents of an arrayref of <NaturalDocs::Menu::Entry> objects to disk.
        -#
        -#   Parameters:
        -#
        -#       entries          - The arrayref of menu entries to write.
        -#       fileHandle      - The handle to the output file.
        -#       indentChars   - The indentation _characters_ to add before each line.  It is not the number of characters, it is the characters
        -#                              themselves.  Use undef for none.
        -#       relativeFiles - Whether to use relative file names.
        -#
        -sub WriteMenuEntries #(entries, fileHandle, indentChars, relativeFiles)
        -    {
        -    my ($self, $entries, $fileHandle, $indentChars, $relativeFiles) = @_;
        -    my $lastEntryType;
        -
        -    foreach my $entry (@$entries)
        -        {
        -        if ($entry->Type() == ::MENU_FILE())
        -            {
        -            my $fileName;
        -
        -            if ($relativeFiles)
        -                {  $fileName = (NaturalDocs::Settings->SplitFromInputDirectory($entry->Target()))[1];  }
        -            else
        -                {  $fileName = $entry->Target();  };
        -
        -            print $fileHandle $indentChars . 'File: ' . $self->ConvertAmpChars( $entry->Title(), CONVERT_PARENTHESIS() )
        -                                  . '  (' . ($entry->Flags() & ::MENU_FILE_NOAUTOTITLE() ? 'no auto-title, ' : '')
        -                                  . $self->ConvertAmpChars($fileName) . ")\n";
        -            }
        -        elsif ($entry->Type() == ::MENU_GROUP())
        -            {
        -            if (defined $lastEntryType && $lastEntryType != ::MENU_GROUP())
        -                {  print $fileHandle "\n";  };
        -
        -            print $fileHandle $indentChars . 'Group: ' . $self->ConvertAmpChars( $entry->Title() ) . "  {\n\n";
        -            $self->WriteMenuEntries($entry->GroupContent(), $fileHandle, '   ' . $indentChars, $relativeFiles);
        -            print $fileHandle '   ' . $indentChars . '}  # Group: ' . $self->ConvertAmpChars( $entry->Title() ) . "\n\n";
        -            }
        -        elsif ($entry->Type() == ::MENU_TEXT())
        -            {
        -            print $fileHandle $indentChars . 'Text: ' . $self->ConvertAmpChars( $entry->Title() ) . "\n";
        -            }
        -        elsif ($entry->Type() == ::MENU_LINK())
        -            {
        -            print $fileHandle $indentChars . 'Link: ' . $self->ConvertAmpChars( $entry->Title() ) . '  '
        -                                                        . '(' . $self->ConvertAmpChars( $entry->Target(), CONVERT_PARENTHESIS() ) . ')' . "\n";
        -            }
        -        elsif ($entry->Type() == ::MENU_INDEX())
        -            {
        -            my $type;
        -            if ($entry->Target() ne ::TOPIC_GENERAL())
        -                {
        -                $type = NaturalDocs::Topics->NameOfType($entry->Target()) . ' ';
        -                };
        -
        -            print $fileHandle $indentChars . $self->ConvertAmpChars($type, CONVERT_COLONS()) . 'Index: '
        -                                                        . $self->ConvertAmpChars( $entry->Title() ) . "\n";
        -            };
        -
        -        $lastEntryType = $entry->Type();
        -        };
        -    };
        -
        -
        -#
        -#   Function: LoadPreviousMenuStateFile
        -#
        -#   Loads and parses the previous menu state file.
        -#
        -#   Returns:
        -#
        -#       The array ( previousMenu, previousIndexes, previousFiles ) or an empty array if there was a problem with the file.
        -#
        -#       previousMenu - A <MENU_GROUP> <NaturalDocs::Menu::Entry> object, similar to <menu>, which contains the entire
        -#                              previous menu.
        -#       previousIndexes - An existence hashref of the index <TopicTypes> present in the previous menu.
        -#       previousFiles - A hashref of the files present in the previous menu.  The keys are the <FileNames>, and the entries are
        -#                             references to its object in previousMenu.
        -#
        -sub LoadPreviousMenuStateFile
        -    {
        -    my ($self) = @_;
        -
        -    my $fileIsOkay;
        -    my $version;
        -    my $previousStateFileName = NaturalDocs::Project->DataFile('PreviousMenuState.nd');
        -
        -    if (open(PREVIOUSSTATEFILEHANDLE, '<' . $previousStateFileName))
        -        {
        -        # See if it's binary.
        -        binmode(PREVIOUSSTATEFILEHANDLE);
        -
        -        my $firstChar;
        -        read(PREVIOUSSTATEFILEHANDLE, $firstChar, 1);
        -
        -        if ($firstChar == ::BINARY_FORMAT())
        -            {
        -            $version = NaturalDocs::Version->FromBinaryFile(\*PREVIOUSSTATEFILEHANDLE);
        -
        -            # Only the topic type format has changed since switching to binary, and we support both methods.
        -
        -            if (NaturalDocs::Version->CheckFileFormat($version))
        -                {  $fileIsOkay = 1;  }
        -            else
        -                {  close(PREVIOUSSTATEFILEHANDLE);  };
        -            }
        -
        -        else # it's not in binary
        -            {  close(PREVIOUSSTATEFILEHANDLE);  };
        -        };
        -
        -    if ($fileIsOkay)
        -        {
        -        if (NaturalDocs::Project->UserConfigFileStatus('Menu.txt') == ::FILE_CHANGED())
        -            {  $hasChanged = 1;  };
        -
        -
        -        my $menu = NaturalDocs::Menu::Entry->New(::MENU_GROUP(), undef, undef, undef);
        -        my $indexes = { };
        -        my $files = { };
        -
        -        my @groupStack;
        -        my $currentGroup = $menu;
        -        my $raw;
        -
        -        # [UInt8: type or 0 for end group]
        -
        -        while (read(PREVIOUSSTATEFILEHANDLE, $raw, 1))
        -            {
        -            my ($type, $flags, $title, $titleLength, $target, $targetLength);
        -            $type = unpack('C', $raw);
        -
        -            if ($type == 0)
        -                {  $currentGroup = pop @groupStack;  }
        -
        -            elsif ($type == ::MENU_FILE())
        -                {
        -                # [UInt8: noAutoTitle] [AString16: title] [AString16: target]
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 3);
        -                (my $noAutoTitle, $titleLength) = unpack('Cn', $raw);
        -
        -                if ($noAutoTitle)
        -                    {  $flags = ::MENU_FILE_NOAUTOTITLE();  };
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $title, $titleLength);
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -
        -                $targetLength = unpack('n', $raw);
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $target, $targetLength);
        -                }
        -
        -            elsif ($type == ::MENU_GROUP())
        -                {
        -                # [AString16: title]
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -                $titleLength = unpack('n', $raw);
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $title, $titleLength);
        -                }
        -
        -            elsif ($type == ::MENU_INDEX())
        -                {
        -                # [AString16: title]
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -                $titleLength = unpack('n', $raw);
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $title, $titleLength);
        -
        -                if ($version >= NaturalDocs::Version->FromString('1.3'))
        -                    {
        -                    # [AString16: topic type]
        -                    read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -                    $targetLength = unpack('n', $raw);
        -
        -                    read(PREVIOUSSTATEFILEHANDLE, $target, $targetLength);
        -                    }
        -                else
        -                    {
        -                    # [UInt8: topic type (0 for general)]
        -                    read(PREVIOUSSTATEFILEHANDLE, $raw, 1);
        -                    $target = unpack('C', $raw);
        -
        -                    $target = NaturalDocs::Topics->TypeFromLegacy($target);
        -                    };
        -                }
        -
        -            elsif ($type == ::MENU_LINK())
        -                {
        -                # [AString16: title] [AString16: url]
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -                $titleLength = unpack('n', $raw);
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $title, $titleLength);
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -                $targetLength = unpack('n', $raw);
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $target, $targetLength);
        -                }
        -
        -            elsif ($type == ::MENU_TEXT())
        -                {
        -                # [AString16: text]
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $raw, 2);
        -                $titleLength = unpack('n', $raw);
        -
        -                read(PREVIOUSSTATEFILEHANDLE, $title, $titleLength);
        -                };
        -
        -
        -            # The topic type of the index may have been removed.
        -
        -            if ( !($type == ::MENU_INDEX() && !NaturalDocs::Topics->IsValidType($target)) )
        -                {
        -                my $entry = NaturalDocs::Menu::Entry->New($type, $title, $target, ($flags || 0));
        -                $currentGroup->PushToGroup($entry);
        -
        -                if ($type == ::MENU_FILE())
        -                    {
        -                    $files->{$target} = $entry;
        -                    }
        -                elsif ($type == ::MENU_GROUP())
        -                    {
        -                    push @groupStack, $currentGroup;
        -                    $currentGroup = $entry;
        -                    }
        -                elsif ($type == ::MENU_INDEX())
        -                    {
        -                    $indexes->{$target} = 1;
        -                    };
        -                };
        -
        -            };
        -
        -        close(PREVIOUSSTATEFILEHANDLE);
        -
        -        return ($menu, $indexes, $files);
        -        }
        -    else
        -        {
        -        $hasChanged = 1;
        -        return ( );
        -        };
        -    };
        -
        -
        -#
        -#   Function: SavePreviousMenuStateFile
        -#
        -#   Saves changes to <PreviousMenuState.nd>.
        -#
        -sub SavePreviousMenuStateFile
        -    {
        -    my ($self) = @_;
        -
        -    open (PREVIOUSSTATEFILEHANDLE, '>' . NaturalDocs::Project->DataFile('PreviousMenuState.nd'))
        -        or die "Couldn't save " . NaturalDocs::Project->DataFile('PreviousMenuState.nd') . ".\n";
        -
        -    binmode(PREVIOUSSTATEFILEHANDLE);
        -
        -    print PREVIOUSSTATEFILEHANDLE '' . ::BINARY_FORMAT();
        -
        -    NaturalDocs::Version->ToBinaryFile(\*PREVIOUSSTATEFILEHANDLE, NaturalDocs::Settings->AppVersion());
        -
        -    $self->WritePreviousMenuStateEntries($menu->GroupContent(), \*PREVIOUSSTATEFILEHANDLE);
        -
        -    close(PREVIOUSSTATEFILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: WritePreviousMenuStateEntries
        -#
        -#   A recursive function to write the contents of an arrayref of <NaturalDocs::Menu::Entry> objects to disk.
        -#
        -#   Parameters:
        -#
        -#       entries          - The arrayref of menu entries to write.
        -#       fileHandle      - The handle to the output file.
        -#
        -sub WritePreviousMenuStateEntries #(entries, fileHandle)
        -    {
        -    my ($self, $entries, $fileHandle) = @_;
        -
        -    foreach my $entry (@$entries)
        -        {
        -        if ($entry->Type() == ::MENU_FILE())
        -            {
        -            # We need to do length manually instead of using n/A in the template because it's not supported in earlier versions
        -            # of Perl.
        -
        -            # [UInt8: MENU_FILE] [UInt8: noAutoTitle] [AString16: title] [AString16: target]
        -            print $fileHandle pack('CCnA*nA*', ::MENU_FILE(), ($entry->Flags() & ::MENU_FILE_NOAUTOTITLE() ? 1 : 0),
        -                                                                length($entry->Title()), $entry->Title(),
        -                                                                length($entry->Target()), $entry->Target());
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_GROUP())
        -            {
        -            # [UInt8: MENU_GROUP] [AString16: title]
        -            print $fileHandle pack('CnA*', ::MENU_GROUP(), length($entry->Title()), $entry->Title());
        -            $self->WritePreviousMenuStateEntries($entry->GroupContent(), $fileHandle);
        -            print $fileHandle pack('C', 0);
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_INDEX())
        -            {
        -            # [UInt8: MENU_INDEX] [AString16: title] [AString16: topic type]
        -            print $fileHandle pack('CnA*nA*', ::MENU_INDEX(), length($entry->Title()), $entry->Title(),
        -                                                                                       length($entry->Target()), $entry->Target());
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_LINK())
        -            {
        -            # [UInt8: MENU_LINK] [AString16: title] [AString16: url]
        -            print $fileHandle pack('CnA*nA*', ::MENU_LINK(), length($entry->Title()), $entry->Title(),
        -                                                             length($entry->Target()), $entry->Target());
        -            }
        -
        -        elsif ($entry->Type() == ::MENU_TEXT())
        -            {
        -            # [UInt8: MENU_TEXT] [AString16: hext]
        -            print $fileHandle pack('CnA*', ::MENU_TEXT(), length($entry->Title()), $entry->Title());
        -            };
        -        };
        -
        -    };
        -
        -
        -#
        -#   Function: CheckForTrashedMenu
        -#
        -#   Checks the menu to see if a significant number of file entries didn't resolve to actual files, and if so, saves a backup of the
        -#   menu and issues a warning.
        -#
        -#   Parameters:
        -#
        -#       numberOriginallyInMenu - A count of how many file entries were in the menu orignally.
        -#       numberRemoved - A count of how many file entries were removed from the menu.
        -#
        -sub CheckForTrashedMenu #(numberOriginallyInMenu, numberRemoved)
        -    {
        -    my ($self, $numberOriginallyInMenu, $numberRemoved) = @_;
        -
        -    no integer;
        -
        -    if ( ($numberOriginallyInMenu >= 6 && $numberRemoved == $numberOriginallyInMenu) ||
        -         ($numberOriginallyInMenu >= 12 && ($numberRemoved / $numberOriginallyInMenu) >= 0.4) ||
        -         ($numberRemoved >= 15) )
        -        {
        -        my $backupFile = NaturalDocs::Project->UserConfigFile('Menu_Backup.txt');
        -        my $backupFileNumber = 1;
        -
        -        while (-e $backupFile)
        -            {
        -            $backupFileNumber++;
        -            $backupFile = NaturalDocs::Project->UserConfigFile('Menu_Backup_' . $backupFileNumber . '.txt');
        -            };
        -
        -        NaturalDocs::File->Copy( NaturalDocs::Project->UserConfigFile('Menu.txt'), $backupFile );
        -
        -        print STDERR
        -        "\n"
        -        # GNU format.  See http://www.gnu.org/prep/standards_15.html
        -        . "NaturalDocs: warning: possible trashed menu\n"
        -        . "\n"
        -        . "   Natural Docs has detected that a significant number file entries in the\n"
        -        . "   menu did not resolve to actual files.  A backup of your original menu file\n"
        -        . "   has been saved as\n"
        -        . "\n"
        -        . "   " . $backupFile . "\n"
        -        . "\n"
        -        . "   - If you recently deleted a lot of files from your project, you can safely\n"
        -        . "     ignore this message.  They have been deleted from the menu as well.\n"
        -        . "   - If you recently rearranged your source tree, you may want to restore your\n"
        -        . "     menu from the backup and do a search and replace to preserve your layout.\n"
        -        . "     Otherwise the position of any moved files will be reset.\n"
        -        . "   - If neither of these is the case, you may have gotten the -i parameter\n"
        -        . "     wrong in the command line.  You should definitely restore the backup and\n"
        -        . "     try again, because otherwise every file in your menu will be reset.\n"
        -        . "\n";
        -        };
        -
        -    use integer;
        -    };
        -
        -
        -#
        -#   Function: GenerateTimestampText
        -#
        -#   Generates <timestampText> from <timestampCode> with the current date.
        -#
        -sub GenerateTimestampText
        -    {
        -    my $self = shift;
        -
        -    my @longMonths = ( 'January', 'February', 'March', 'April', 'May', 'June',
        -                                   'July', 'August', 'September', 'October', 'November', 'December' );
        -    my @shortMonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec' );
        -
        -    my (undef, undef, undef, $day, $month, $year) = localtime();
        -    $year += 1900;
        -
        -    my $longDay;
        -    if ($day % 10 == 1 && $day != 11)
        -        {  $longDay = $day . 'st';  }
        -    elsif ($day % 10 == 2 && $day != 12)
        -        {  $longDay = $day . 'nd';  }
        -    elsif ($day % 10 == 3 && $day != 13)
        -        {  $longDay = $day . 'rd';  }
        -    else
        -        {  $longDay = $day . 'th';  };
        -
        -
        -    $timestampText = $timestampCode;
        -
        -    $timestampText =~ s/(?<![a-z])month(?![a-z])/$longMonths[$month]/i;
        -    $timestampText =~ s/(?<![a-z])mon(?![a-z])/$shortMonths[$month]/i;
        -    $timestampText =~ s/(?<![a-z])mm(?![a-z])/sprintf('%02d', $month + 1)/ie;
        -    $timestampText =~ s/(?<![a-z])m(?![a-z])/$month + 1/ie;
        -
        -    $timestampText =~ s/(?<![a-z])day(?![a-z])/$longDay/i;
        -    $timestampText =~ s/(?<![a-z])dd(?![a-z])/sprintf('%02d', $day)/ie;
        -    $timestampText =~ s/(?<![a-z])d(?![a-z])/$day/i;
        -
        -    $timestampText =~ s/(?<![a-z])(?:year|yyyy)(?![a-z])/$year/i;
        -    $timestampText =~ s/(?<![a-z])yy(?![a-z])/sprintf('%02d', $year % 100)/ie;
        -    };
        -
        -
        -use constant CONVERT_PARENTHESIS => 0x01;
        -use constant CONVERT_COMMAS => 0x02;
        -use constant CONVERT_COLONS => 0x04;
        -
        -#
        -#   Function: ConvertAmpChars
        -#   Replaces certain characters in the string with their entities and returns it.
        -#
        -#   Parameters:
        -#
        -#       text - The text to convert.
        -#       flags - The flags of any additional characters to convert.
        -#
        -#   Flags:
        -#
        -#       - CONVERT_PARENTHESIS
        -#       - CONVERT_COMMAS
        -#       - CONVERT_COLONS
        -#
        -#   Returns:
        -#
        -#       The string with the amp chars converted.
        -#
        -sub ConvertAmpChars #(string text, int flags) => string
        -    {
        -    my ($self, $text, $flags) = @_;
        -
        -    $text =~ s/&/&amp;/g;
        -    $text =~ s/\{/&lbrace;/g;
        -    $text =~ s/\}/&rbrace;/g;
        -
        -    if ($flags & CONVERT_PARENTHESIS())
        -        {
        -        $text =~ s/\(/&lparen;/g;
        -        $text =~ s/\)/&rparen;/g;
        -        };
        -    if ($flags & CONVERT_COMMAS())
        -        {
        -        $text =~ s/\,/&comma;/g;
        -        };
        -    if ($flags & CONVERT_COLONS())
        -        {
        -        $text =~ s/\:/&colon;/g;
        -        };
        -
        -    return $text;
        -    };
        -
        -
        -#
        -#   Function: RestoreAmpChars
        -#   Replaces entity characters in the string with their original characters and returns it.  This will restore all amp chars regardless
        -#   of the flags passed to <ConvertAmpChars()>.
        -#
        -sub RestoreAmpChars #(string text) => string
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ s/&lparen;/(/gi;
        -    $text =~ s/&rparen;/)/gi;
        -    $text =~ s/&lbrace;/{/gi;
        -    $text =~ s/&rbrace;/}/gi;
        -    $text =~ s/&comma;/,/gi;
        -    $text =~ s/&amp;/&/gi;
        -    $text =~ s/&colon;/:/gi;
        -
        -    return $text;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Auto-Adjustment Functions
        -
        -
        -#
        -#   Function: ResolveInputDirectories
        -#
        -#   Detects if the input directories in the menu file match those in the command line, and if not, tries to resolve them.  This allows
        -#   menu files to work across machines, since the absolute paths won't be the same but the relative ones should be.
        -#
        -#   Parameters:
        -#
        -#       inputDirectoryNames - A hashref of the input directories appearing in the menu file, or undef if none.  The keys are the
        -#                                        directories, and the values are their names.  May be undef.
        -#
        -sub ResolveInputDirectories #(inputDirectoryNames)
        -    {
        -    my ($self, $menuDirectoryNames) = @_;
        -
        -
        -    # Determine which directories don't match the command line, if any.
        -
        -    my $inputDirectories = NaturalDocs::Settings->InputDirectories();
        -    my @unresolvedMenuDirectories;
        -
        -    foreach my $menuDirectory (keys %$menuDirectoryNames)
        -        {
        -        my $found;
        -
        -        foreach my $inputDirectory (@$inputDirectories)
        -            {
        -            if ($menuDirectory eq $inputDirectory)
        -                {
        -                $found = 1;
        -                last;
        -                };
        -            };
        -
        -        if (!$found)
        -            {  push @unresolvedMenuDirectories, $menuDirectory;  };
        -        };
        -
        -    # Quit if everything matches up, which should be the most common case.
        -    if (!scalar @unresolvedMenuDirectories)
        -        {  return;  };
        -
        -    # Poop.  See which input directories are still available.
        -
        -    my @unresolvedInputDirectories;
        -
        -    foreach my $inputDirectory (@$inputDirectories)
        -        {
        -        if (!exists $menuDirectoryNames->{$inputDirectory})
        -            {  push @unresolvedInputDirectories, $inputDirectory;  };
        -        };
        -
        -    # Quit if there are none.  This means an input directory is in the menu that isn't in the command line.  Natural Docs should
        -    # proceed normally and let the files be deleted.
        -    if (!scalar @unresolvedInputDirectories)
        -        {
        -        $hasChanged = 1;
        -        return;
        -        };
        -
        -    # The index into menuDirectoryScores is the same as in unresolvedMenuDirectories.  The index into each arrayref within it is
        -    # the same as in unresolvedInputDirectories.
        -    my @menuDirectoryScores;
        -    for (my $i = 0; $i < scalar @unresolvedMenuDirectories; $i++)
        -        {  push @menuDirectoryScores, [ ];  };
        -
        -
        -    # Now plow through the menu, looking for files that have an unresolved base.
        -
        -    my @menuGroups = ( $menu );
        -
        -    while (scalar @menuGroups)
        -        {
        -        my $currentGroup = pop @menuGroups;
        -        my $currentGroupContent = $currentGroup->GroupContent();
        -
        -        foreach my $entry (@$currentGroupContent)
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {
        -                push @menuGroups, $entry;
        -                }
        -            elsif ($entry->Type() == ::MENU_FILE())
        -                {
        -                # Check if it uses an unresolved base.
        -                for (my $i = 0; $i < scalar @unresolvedMenuDirectories; $i++)
        -                    {
        -                    if (NaturalDocs::File->IsSubPathOf($unresolvedMenuDirectories[$i], $entry->Target()))
        -                        {
        -                        my $relativePath = NaturalDocs::File->MakeRelativePath($unresolvedMenuDirectories[$i], $entry->Target());
        -                        $self->ResolveFile($relativePath, \@unresolvedInputDirectories, $menuDirectoryScores[$i]);
        -                        last;
        -                        };
        -                    };
        -                };
        -            };
        -        };
        -
        -
        -    # Now, create an array of score objects.  Each score object is the three value arrayref [ from, to, score ].  From and To are the
        -    # conversion options and are the indexes into unresolvedInput/MenuDirectories.  We'll sort this array by score to get the best
        -    # possible conversions.  Yes, really.
        -    my @scores;
        -
        -    for (my $menuIndex = 0; $menuIndex < scalar @unresolvedMenuDirectories; $menuIndex++)
        -        {
        -        for (my $inputIndex = 0; $inputIndex < scalar @unresolvedInputDirectories; $inputIndex++)
        -            {
        -            if ($menuDirectoryScores[$menuIndex]->[$inputIndex])
        -                {
        -                push @scores, [ $menuIndex, $inputIndex, $menuDirectoryScores[$menuIndex]->[$inputIndex] ];
        -                };
        -            };
        -        };
        -
        -    @scores = sort { $b->[2] <=> $a->[2] } @scores;
        -
        -
        -    # Now we determine what goes where.
        -    my @menuDirectoryConversions;
        -
        -    foreach my $scoreObject (@scores)
        -        {
        -        if (!defined $menuDirectoryConversions[ $scoreObject->[0] ])
        -            {
        -            $menuDirectoryConversions[ $scoreObject->[0] ] = $unresolvedInputDirectories[ $scoreObject->[1] ];
        -            };
        -        };
        -
        -
        -    # Now, FINALLY, we do the conversion.  Note that not every menu directory may have a conversion defined.
        -
        -    @menuGroups = ( $menu );
        -
        -    while (scalar @menuGroups)
        -        {
        -        my $currentGroup = pop @menuGroups;
        -        my $currentGroupContent = $currentGroup->GroupContent();
        -
        -        foreach my $entry (@$currentGroupContent)
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {
        -                push @menuGroups, $entry;
        -                }
        -            elsif ($entry->Type() == ::MENU_FILE())
        -                {
        -                # Check if it uses an unresolved base.
        -                for (my $i = 0; $i < scalar @unresolvedMenuDirectories; $i++)
        -                    {
        -                    if (NaturalDocs::File->IsSubPathOf($unresolvedMenuDirectories[$i], $entry->Target()) &&
        -                        defined $menuDirectoryConversions[$i])
        -                        {
        -                        my $relativePath = NaturalDocs::File->MakeRelativePath($unresolvedMenuDirectories[$i], $entry->Target());
        -                        $entry->SetTarget( NaturalDocs::File->JoinPaths($menuDirectoryConversions[$i], $relativePath) );
        -                        last;
        -                        };
        -                    };
        -                };
        -            };
        -        };
        -
        -
        -    # Whew.
        -
        -    $hasChanged = 1;
        -    };
        -
        -
        -#
        -#   Function: ResolveRelativeInputDirectories
        -#
        -#   Resolves relative input directories to the input directories available.
        -#
        -sub ResolveRelativeInputDirectories
        -    {
        -    my ($self) = @_;
        -
        -    my $inputDirectories = NaturalDocs::Settings->InputDirectories();
        -    my $resolvedInputDirectory;
        -
        -    if (scalar @$inputDirectories == 1)
        -        {  $resolvedInputDirectory = $inputDirectories->[0];  }
        -    else
        -        {
        -        my @score;
        -
        -        # Plow through the menu, looking for files and scoring them.
        -
        -        my @menuGroups = ( $menu );
        -
        -        while (scalar @menuGroups)
        -            {
        -            my $currentGroup = pop @menuGroups;
        -            my $currentGroupContent = $currentGroup->GroupContent();
        -
        -            foreach my $entry (@$currentGroupContent)
        -                {
        -                if ($entry->Type() == ::MENU_GROUP())
        -                    {
        -                    push @menuGroups, $entry;
        -                    }
        -                elsif ($entry->Type() == ::MENU_FILE())
        -                    {
        -                    $self->ResolveFile($entry->Target(), $inputDirectories, \@score);
        -                    };
        -                };
        -            };
        -
        -        # Determine the best match.
        -
        -        my $bestScore = 0;
        -        my $bestIndex = 0;
        -
        -        for (my $i = 0; $i < scalar @$inputDirectories; $i++)
        -            {
        -            if ($score[$i] > $bestScore)
        -                {
        -                $bestScore = $score[$i];
        -                $bestIndex = $i;
        -                };
        -            };
        -
        -        $resolvedInputDirectory = $inputDirectories->[$bestIndex];
        -        };
        -
        -
        -    # Okay, now that we have our resolved directory, update everything.
        -
        -    my @menuGroups = ( $menu );
        -
        -    while (scalar @menuGroups)
        -        {
        -        my $currentGroup = pop @menuGroups;
        -        my $currentGroupContent = $currentGroup->GroupContent();
        -
        -        foreach my $entry (@$currentGroupContent)
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {  push @menuGroups, $entry;  }
        -            elsif ($entry->Type() == ::MENU_FILE())
        -                {
        -                $entry->SetTarget( NaturalDocs::File->JoinPaths($resolvedInputDirectory, $entry->Target()) );
        -                };
        -            };
        -        };
        -
        -    if (scalar @$inputDirectories > 1)
        -        {  $hasChanged = 1;  };
        -
        -    return $resolvedInputDirectory;
        -    };
        -
        -
        -#
        -#   Function: ResolveFile
        -#
        -#   Tests a relative path against a list of directories.  Adds one to the score of each base where there is a match.
        -#
        -#   Parameters:
        -#
        -#       relativePath - The relative file name to test.
        -#       possibleBases - An arrayref of bases to test it against.
        -#       possibleBaseScores - An arrayref of scores to adjust.  The score indexes should correspond to the base indexes.
        -#
        -sub ResolveFile #(relativePath, possibleBases, possibleBaseScores)
        -    {
        -    my ($self, $relativePath, $possibleBases, $possibleBaseScores) = @_;
        -
        -    for (my $i = 0; $i < scalar @$possibleBases; $i++)
        -        {
        -        if (-e NaturalDocs::File->JoinPaths($possibleBases->[$i], $relativePath))
        -            {  $possibleBaseScores->[$i]++;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: LockUserTitleChanges
        -#
        -#   Detects if the user manually changed any file titles, and if so, automatically locks them with <MENU_FILE_NOAUTOTITLE>.
        -#
        -#   Parameters:
        -#
        -#       previousMenuFiles - A hashref of the files from the previous menu state.  The keys are the <FileNames>, and the values are
        -#                                    references to their <NaturalDocs::Menu::Entry> objects.
        -#
        -sub LockUserTitleChanges #(previousMenuFiles)
        -    {
        -    my ($self, $previousMenuFiles) = @_;
        -
        -    my @groupStack = ( $menu );
        -    my $groupEntry;
        -
        -    while (scalar @groupStack)
        -        {
        -        $groupEntry = pop @groupStack;
        -
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -
        -            # If it's an unlocked file entry
        -            if ($entry->Type() == ::MENU_FILE() && ($entry->Flags() & ::MENU_FILE_NOAUTOTITLE()) == 0)
        -                {
        -                my $previousEntry = $previousMenuFiles->{$entry->Target()};
        -
        -                # If the previous entry was also unlocked and the titles are different, the user changed the title.  Automatically lock it.
        -                if (defined $previousEntry && ($previousEntry->Flags() & ::MENU_FILE_NOAUTOTITLE()) == 0 &&
        -                    $entry->Title() ne $previousEntry->Title())
        -                    {
        -                    $entry->SetFlags($entry->Flags() | ::MENU_FILE_NOAUTOTITLE());
        -                    $hasChanged = 1;
        -                    };
        -                }
        -
        -            elsif ($entry->Type() == ::MENU_GROUP())
        -                {
        -                push @groupStack, $entry;
        -                };
        -
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: FlagAutoTitleChanges
        -#
        -#   Finds which files have auto-titles that changed and flags their groups for updating with <MENU_GROUP_UPDATETITLES> and
        -#   <MENU_GROUP_UPDATEORDER>.
        -#
        -sub FlagAutoTitleChanges
        -    {
        -    my ($self) = @_;
        -
        -    my @groupStack = ( $menu );
        -    my $groupEntry;
        -
        -    while (scalar @groupStack)
        -        {
        -        $groupEntry = pop @groupStack;
        -
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -            if ($entry->Type() == ::MENU_FILE() && ($entry->Flags() & ::MENU_FILE_NOAUTOTITLE()) == 0 &&
        -                exists $defaultTitlesChanged{$entry->Target()})
        -                {
        -                $groupEntry->SetFlags($groupEntry->Flags() | ::MENU_GROUP_UPDATETITLES() | ::MENU_GROUP_UPDATEORDER());
        -                $hasChanged = 1;
        -                }
        -            elsif ($entry->Type() == ::MENU_GROUP())
        -                {
        -                push @groupStack, $entry;
        -                };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: AutoPlaceNewFiles
        -#
        -#   Adds files to the menu that aren't already on it, attempting to guess where they belong.
        -#
        -#   New files are placed after a dummy <MENU_ENDOFORIGINAL> entry so that they don't affect the detected order.  Also, the
        -#   groups they're placed in get <MENU_GROUP_UPDATETITLES>, <MENU_GROUP_UPDATESTRUCTURE>, and
        -#   <MENU_GROUP_UPDATEORDER> flags.
        -#
        -#   Parameters:
        -#
        -#       filesInMenu - An existence hash of all the <FileNames> present in the menu.
        -#
        -sub AutoPlaceNewFiles #(fileInMenu)
        -    {
        -    my ($self, $filesInMenu) = @_;
        -
        -    my $files = NaturalDocs::Project->FilesWithContent();
        -
        -    my $directories;
        -
        -    foreach my $file (keys %$files)
        -        {
        -        if (!exists $filesInMenu->{$file})
        -            {
        -            # This is done on demand because new files shouldn't be added very often, so this will save time.
        -            if (!defined $directories)
        -                {  $directories = $self->MatchDirectoriesAndGroups();  };
        -
        -            my $targetGroup;
        -            my $fileDirectoryString = (NaturalDocs::File->SplitPath($file))[1];
        -
        -            $targetGroup = $directories->{$fileDirectoryString};
        -
        -            if (!defined $targetGroup)
        -                {
        -                # Okay, if there's no exact match, work our way down.
        -
        -                my @fileDirectories = NaturalDocs::File->SplitDirectories($fileDirectoryString);
        -
        -                do
        -                    {
        -                    pop @fileDirectories;
        -                    $targetGroup = $directories->{ NaturalDocs::File->JoinDirectories(@fileDirectories) };
        -                    }
        -                while (!defined $targetGroup && scalar @fileDirectories);
        -
        -                if (!defined $targetGroup)
        -                    {  $targetGroup = $menu;  };
        -                };
        -
        -            $targetGroup->MarkEndOfOriginal();
        -            $targetGroup->PushToGroup( NaturalDocs::Menu::Entry->New(::MENU_FILE(), undef, $file, undef) );
        -
        -            $targetGroup->SetFlags( $targetGroup->Flags() | ::MENU_GROUP_UPDATETITLES() |
        -                                                 ::MENU_GROUP_UPDATESTRUCTURE() | ::MENU_GROUP_UPDATEORDER() );
        -
        -            $hasChanged = 1;
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: MatchDirectoriesAndGroups
        -#
        -#   Determines which groups files in certain directories should be placed in.
        -#
        -#   Returns:
        -#
        -#       A hashref.  The keys are the directory names, and the values are references to the group objects they should be placed in.
        -#
        -#       This only repreesents directories that currently have files on the menu, so it shouldn't be assumed that every possible
        -#       directory will exist.  To match, you should first try to match the directory, and then strip the deepest directories one by
        -#       one until there's a match or there's none left.  If there's none left, use the root group <menu>.
        -#
        -sub MatchDirectoriesAndGroups
        -    {
        -    my ($self) = @_;
        -
        -    # The keys are the directory names, and the values are hashrefs.  For the hashrefs, the keys are the group objects, and the
        -    # values are the number of files in them from that directory.  In other words,
        -    # $directories{$directory}->{$groupEntry} = $count;
        -    my %directories;
        -    # Note that we need to use Tie::RefHash to use references as keys.  Won't work otherwise.  Also, not every Perl distro comes
        -    # with Tie::RefHash::Nestable, so we can't rely on that.
        -
        -    # We're using an index instead of pushing and popping because we want to save a list of the groups in the order they appear
        -    # to break ties.
        -    my @groups = ( $menu );
        -    my $groupIndex = 0;
        -
        -
        -    # Count the number of files in each group that appear in each directory.
        -
        -    while ($groupIndex < scalar @groups)
        -        {
        -        my $groupEntry = $groups[$groupIndex];
        -
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {
        -                push @groups, $entry;
        -                }
        -            elsif ($entry->Type() == ::MENU_FILE())
        -                {
        -                my $directory = (NaturalDocs::File->SplitPath($entry->Target()))[1];
        -
        -                if (!exists $directories{$directory})
        -                    {
        -                    my $subHash = { };
        -                    tie %$subHash, 'Tie::RefHash';
        -                    $directories{$directory} = $subHash;
        -                    };
        -
        -                if (!exists $directories{$directory}->{$groupEntry})
        -                    {  $directories{$directory}->{$groupEntry} = 1;  }
        -                else
        -                    {  $directories{$directory}->{$groupEntry}++;  };
        -                };
        -            };
        -
        -        $groupIndex++;
        -        };
        -
        -
        -    # Determine which group goes with which directory, breaking ties by using whichever group appears first.
        -
        -    my $finalDirectories = { };
        -
        -    while (my ($directory, $directoryGroups) = each %directories)
        -        {
        -        my $bestGroup;
        -        my $bestCount = 0;
        -        my %tiedGroups;  # Existence hash
        -
        -        while (my ($group, $count) = each %$directoryGroups)
        -            {
        -            if ($count > $bestCount)
        -                {
        -                $bestGroup = $group;
        -                $bestCount = $count;
        -                %tiedGroups = ( );
        -                }
        -            elsif ($count == $bestCount)
        -                {
        -                $tiedGroups{$group} = 1;
        -                };
        -            };
        -
        -        # Break ties.
        -        if (scalar keys %tiedGroups)
        -            {
        -            $tiedGroups{$bestGroup} = 1;
        -
        -            foreach my $group (@groups)
        -                {
        -                if (exists $tiedGroups{$group})
        -                    {
        -                    $bestGroup = $group;
        -                    last;
        -                    };
        -                };
        -            };
        -
        -
        -        $finalDirectories->{$directory} = $bestGroup;
        -        };
        -
        -
        -    return $finalDirectories;
        -    };
        -
        -
        -#
        -#   Function: RemoveDeadFiles
        -#
        -#   Removes files from the menu that no longer exist or no longer have Natural Docs content.
        -#
        -#   Returns:
        -#
        -#       The number of file entries removed.
        -#
        -sub RemoveDeadFiles
        -    {
        -    my ($self) = @_;
        -
        -    my @groupStack = ( $menu );
        -    my $numberRemoved = 0;
        -
        -    my $filesWithContent = NaturalDocs::Project->FilesWithContent();
        -
        -    while (scalar @groupStack)
        -        {
        -        my $groupEntry = pop @groupStack;
        -        my $groupContent = $groupEntry->GroupContent();
        -
        -        my $index = 0;
        -        while ($index < scalar @$groupContent)
        -            {
        -            if ($groupContent->[$index]->Type() == ::MENU_FILE() &&
        -                !exists $filesWithContent->{ $groupContent->[$index]->Target() } )
        -                {
        -                $groupEntry->DeleteFromGroup($index);
        -
        -                $groupEntry->SetFlags( $groupEntry->Flags() | ::MENU_GROUP_UPDATETITLES() |
        -                                                   ::MENU_GROUP_UPDATESTRUCTURE() );
        -                $numberRemoved++;
        -                $hasChanged = 1;
        -                }
        -
        -            elsif ($groupContent->[$index]->Type() == ::MENU_GROUP())
        -                {
        -                push @groupStack, $groupContent->[$index];
        -                $index++;
        -                }
        -
        -            else
        -                {  $index++;  };
        -            };
        -        };
        -
        -    return $numberRemoved;
        -    };
        -
        -
        -#
        -#   Function: BanAndUnbanIndexes
        -#
        -#   Adjusts the indexes that are banned depending on if the user added or deleted any.
        -#
        -sub BanAndUnbanIndexes
        -    {
        -    my ($self) = @_;
        -
        -    # Unban any indexes that are present, meaning the user added them back manually without deleting the ban.
        -    foreach my $index (keys %indexes)
        -        {  delete $bannedIndexes{$index};  };
        -
        -    # Ban any indexes that were in the previous menu but not the current, meaning the user manually deleted them.  However,
        -    # don't do this if the topic isn't indexable, meaning they changed the topic type rather than the menu.
        -    foreach my $index (keys %previousIndexes)
        -        {
        -        if (!exists $indexes{$index} && NaturalDocs::Topics->TypeInfo($index)->Index())
        -            {  $bannedIndexes{$index} = 1;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: AddAndRemoveIndexes
        -#
        -#   Automatically adds and removes index entries on the menu as necessary.  <DetectIndexGroups()> should be called
        -#   beforehand.
        -#
        -sub AddAndRemoveIndexes
        -    {
        -    my ($self) = @_;
        -
        -    my %validIndexes;
        -    my @allIndexes = NaturalDocs::Topics->AllIndexableTypes();
        -
        -    foreach my $index (@allIndexes)
        -        {
        -        # Strip the banned indexes first so it's potentially less work for SymbolTable.
        -        if (!exists $bannedIndexes{$index})
        -            {  $validIndexes{$index} = 1;  };
        -        };
        -
        -    %validIndexes = %{NaturalDocs::SymbolTable->HasIndexes(\%validIndexes)};
        -
        -
        -    # Delete dead indexes and find the best index group.
        -
        -    my @groupStack = ( $menu );
        -
        -    my $bestIndexGroup;
        -    my $bestIndexCount = 0;
        -
        -    while (scalar @groupStack)
        -        {
        -        my $currentGroup = pop @groupStack;
        -        my $index = 0;
        -
        -        my $currentIndexCount = 0;
        -
        -        while ($index < scalar @{$currentGroup->GroupContent()})
        -            {
        -            my $entry = $currentGroup->GroupContent()->[$index];
        -
        -            if ($entry->Type() == ::MENU_INDEX())
        -                {
        -                $currentIndexCount++;
        -
        -                if ($currentIndexCount > $bestIndexCount)
        -                    {
        -                    $bestIndexCount = $currentIndexCount;
        -                    $bestIndexGroup = $currentGroup;
        -                    };
        -
        -                # Remove it if it's dead.
        -
        -                if (!exists $validIndexes{ $entry->Target() })
        -                    {
        -                    $currentGroup->DeleteFromGroup($index);
        -                    delete $indexes{ $entry->Target() };
        -                    $hasChanged = 1;
        -                    }
        -                else
        -                    {  $index++;  };
        -                }
        -
        -            else
        -                {
        -                if ($entry->Type() == ::MENU_GROUP())
        -                    {  push @groupStack, $entry;  };
        -
        -                $index++;
        -                };
        -            };
        -        };
        -
        -
        -    # Now add the new indexes.
        -
        -    foreach my $index (keys %indexes)
        -        {  delete $validIndexes{$index};  };
        -
        -    if (scalar keys %validIndexes)
        -        {
        -        # Add a group if there are no indexes at all.
        -
        -        if ($bestIndexCount == 0)
        -            {
        -            $menu->MarkEndOfOriginal();
        -
        -            my $newIndexGroup = NaturalDocs::Menu::Entry->New(::MENU_GROUP(), 'Index', undef,
        -                                                                                              ::MENU_GROUP_ISINDEXGROUP());
        -            $menu->PushToGroup($newIndexGroup);
        -
        -            $bestIndexGroup = $newIndexGroup;
        -            $menu->SetFlags( $menu->Flags() | ::MENU_GROUP_UPDATEORDER() | ::MENU_GROUP_UPDATESTRUCTURE() );
        -            };
        -
        -        # Add the new indexes.
        -
        -        $bestIndexGroup->MarkEndOfOriginal();
        -        my $isIndexGroup = $bestIndexGroup->Flags() & ::MENU_GROUP_ISINDEXGROUP();
        -
        -        foreach my $index (keys %validIndexes)
        -            {
        -            my $title;
        -
        -            if ($isIndexGroup)
        -                {
        -                if ($index eq ::TOPIC_GENERAL())
        -                    {  $title = 'Everything';  }
        -                else
        -                    {  $title = NaturalDocs::Topics->NameOfType($index, 1);  };
        -                }
        -            else
        -                {
        -                $title = NaturalDocs::Topics->NameOfType($index) . ' Index';
        -                };
        -
        -            my $newEntry = NaturalDocs::Menu::Entry->New(::MENU_INDEX(), $title, $index, undef);
        -            $bestIndexGroup->PushToGroup($newEntry);
        -
        -            $indexes{$index} = 1;
        -            };
        -
        -        $bestIndexGroup->SetFlags( $bestIndexGroup->Flags() |
        -                                                   ::MENU_GROUP_UPDATEORDER() | ::MENU_GROUP_UPDATESTRUCTURE() );
        -        $hasChanged = 1;
        -        };
        -    };
        -
        -
        -#
        -#   Function: RemoveDeadGroups
        -#
        -#   Removes groups with less than two entries.  It will always remove empty groups, and it will remove groups with one entry if it
        -#   has the <MENU_GROUP_UPDATESTRUCTURE> flag.
        -#
        -sub RemoveDeadGroups
        -    {
        -    my ($self) = @_;
        -
        -    my $index = 0;
        -
        -    while ($index < scalar @{$menu->GroupContent()})
        -        {
        -        my $entry = $menu->GroupContent()->[$index];
        -
        -        if ($entry->Type() == ::MENU_GROUP())
        -            {
        -            my $removed = $self->RemoveIfDead($entry, $menu, $index);
        -
        -            if (!$removed)
        -                {  $index++;  };
        -            }
        -        else
        -            {  $index++;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: RemoveIfDead
        -#
        -#   Checks a group and all its sub-groups for life and remove any that are dead.  Empty groups are removed, and groups with one
        -#   entry and the <MENU_GROUP_UPDATESTRUCTURE> flag have their entry moved to the parent group.
        -#
        -#   Parameters:
        -#
        -#       groupEntry - The group to check for possible deletion.
        -#       parentGroupEntry - The parent group to move the single entry to if necessary.
        -#       parentGroupIndex - The index of the group in its parent.
        -#
        -#   Returns:
        -#
        -#       Whether the group was removed or not.
        -#
        -sub RemoveIfDead #(groupEntry, parentGroupEntry, parentGroupIndex)
        -    {
        -    my ($self, $groupEntry, $parentGroupEntry, $parentGroupIndex) = @_;
        -
        -
        -    # Do all sub-groups first, since their deletions will affect our UPDATESTRUCTURE flag and content count.
        -
        -    my $index = 0;
        -    while ($index < scalar @{$groupEntry->GroupContent()})
        -        {
        -        my $entry = $groupEntry->GroupContent()->[$index];
        -
        -        if ($entry->Type() == ::MENU_GROUP())
        -            {
        -            my $removed = $self->RemoveIfDead($entry, $groupEntry, $index);
        -
        -            if (!$removed)
        -                {  $index++;  };
        -            }
        -        else
        -            {  $index++;  };
        -        };
        -
        -
        -    # Now check ourself.
        -
        -    my $count = scalar @{$groupEntry->GroupContent()};
        -    if ($groupEntry->Flags() & ::MENU_GROUP_HASENDOFORIGINAL())
        -        {  $count--;  };
        -
        -    if ($count == 0)
        -        {
        -        $parentGroupEntry->DeleteFromGroup($parentGroupIndex);
        -
        -        $parentGroupEntry->SetFlags( $parentGroupEntry->Flags() | ::MENU_GROUP_UPDATESTRUCTURE() );
        -
        -        $hasChanged = 1;
        -        return 1;
        -        }
        -    elsif ($count == 1 && ($groupEntry->Flags() & ::MENU_GROUP_UPDATESTRUCTURE()) )
        -        {
        -        my $onlyEntry = $groupEntry->GroupContent()->[0];
        -        if ($onlyEntry->Type() == ::MENU_ENDOFORIGINAL())
        -            {  $onlyEntry = $groupEntry->GroupContent()->[1];  };
        -
        -        $parentGroupEntry->DeleteFromGroup($parentGroupIndex);
        -
        -        $parentGroupEntry->MarkEndOfOriginal();
        -        $parentGroupEntry->PushToGroup($onlyEntry);
        -
        -        $parentGroupEntry->SetFlags( $parentGroupEntry->Flags() | ::MENU_GROUP_UPDATETITLES() |
        -                                                     ::MENU_GROUP_UPDATEORDER() | ::MENU_GROUP_UPDATESTRUCTURE() );
        -
        -        $hasChanged = 1;
        -        return 1;
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: DetectIndexGroups
        -#
        -#   Finds groups that are primarily used for indexes and gives them the <MENU_GROUP_ISINDEXGROUP> flag.
        -#
        -sub DetectIndexGroups
        -    {
        -    my ($self) = @_;
        -
        -    my @groupStack = ( $menu );
        -
        -    while (scalar @groupStack)
        -        {
        -        my $groupEntry = pop @groupStack;
        -
        -        my $isIndexGroup = -1;  # -1: Can't tell yet.  0: Can't be an index group.  1: Is an index group so far.
        -
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -            if ($entry->Type() == ::MENU_INDEX())
        -                {
        -                if ($isIndexGroup == -1)
        -                    {  $isIndexGroup = 1;  };
        -                }
        -
        -            # Text is tolerated, but it still needs at least one index entry.
        -            elsif ($entry->Type() != ::MENU_TEXT())
        -                {
        -                $isIndexGroup = 0;
        -
        -                if ($entry->Type() == ::MENU_GROUP())
        -                    {  push @groupStack, $entry;  };
        -                };
        -            };
        -
        -        if ($isIndexGroup == 1)
        -            {
        -            $groupEntry->SetFlags( $groupEntry->Flags() | ::MENU_GROUP_ISINDEXGROUP() );
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: CreateDirectorySubGroups
        -#
        -#   Where possible, creates sub-groups based on directories for any long groups that have <MENU_GROUP_UPDATESTRUCTURE>
        -#   set.  Clears the flag afterwards on groups that are short enough to not need any more sub-groups, but leaves it for the rest.
        -#
        -sub CreateDirectorySubGroups
        -    {
        -    my ($self) = @_;
        -
        -    my @groupStack = ( $menu );
        -
        -    foreach my $groupEntry (@groupStack)
        -        {
        -        if ($groupEntry->Flags() & ::MENU_GROUP_UPDATESTRUCTURE())
        -            {
        -            # Count the number of files.
        -
        -            my $fileCount = 0;
        -
        -            foreach my $entry (@{$groupEntry->GroupContent()})
        -                {
        -                if ($entry->Type() == ::MENU_FILE())
        -                    {  $fileCount++;  };
        -                };
        -
        -
        -            if ($fileCount > MAXFILESINGROUP)
        -                {
        -                my @sharedDirectories = $self->SharedDirectoriesOf($groupEntry);
        -                my $unsharedIndex = scalar @sharedDirectories;
        -
        -                # The keys are the first directory entries after the shared ones, and the values are the number of files that are in
        -                # that directory.  Files that don't have subdirectories after the shared directories aren't included because they shouldn't
        -                # be put in a subgroup.
        -                my %directoryCounts;
        -
        -                foreach my $entry (@{$groupEntry->GroupContent()})
        -                    {
        -                    if ($entry->Type() == ::MENU_FILE())
        -                        {
        -                        my @entryDirectories = NaturalDocs::File->SplitDirectories( (NaturalDocs::File->SplitPath($entry->Target()))[1] );
        -
        -                        if (scalar @entryDirectories > $unsharedIndex)
        -                            {
        -                            my $unsharedDirectory = $entryDirectories[$unsharedIndex];
        -
        -                            if (!exists $directoryCounts{$unsharedDirectory})
        -                                {  $directoryCounts{$unsharedDirectory} = 1;  }
        -                            else
        -                                {  $directoryCounts{$unsharedDirectory}++;  };
        -                            };
        -                        };
        -                    };
        -
        -
        -                # Now create the subgroups.
        -
        -                # The keys are the first directory entries after the shared ones, and the values are the groups for those files to be
        -                # put in.  There will only be entries for the groups with at least MINFILESINNEWGROUP files.
        -                my %directoryGroups;
        -
        -                while (my ($directory, $count) = each %directoryCounts)
        -                    {
        -                    if ($count >= MINFILESINNEWGROUP)
        -                        {
        -                        my $newGroup = NaturalDocs::Menu::Entry->New( ::MENU_GROUP(), ucfirst($directory), undef,
        -                                                                                                   ::MENU_GROUP_UPDATETITLES() |
        -                                                                                                   ::MENU_GROUP_UPDATEORDER() );
        -
        -                        if ($count > MAXFILESINGROUP)
        -                            {  $newGroup->SetFlags( $newGroup->Flags() | ::MENU_GROUP_UPDATESTRUCTURE());  };
        -
        -                        $groupEntry->MarkEndOfOriginal();
        -                        push @{$groupEntry->GroupContent()}, $newGroup;
        -
        -                        $directoryGroups{$directory} = $newGroup;
        -                        $fileCount -= $count;
        -                        };
        -                    };
        -
        -
        -                # Now fill the subgroups.
        -
        -                if (scalar keys %directoryGroups)
        -                    {
        -                    my $afterOriginal;
        -                    my $index = 0;
        -
        -                    while ($index < scalar @{$groupEntry->GroupContent()})
        -                        {
        -                        my $entry = $groupEntry->GroupContent()->[$index];
        -
        -                        if ($entry->Type() == ::MENU_FILE())
        -                            {
        -                            my @entryDirectories =
        -                                NaturalDocs::File->SplitDirectories( (NaturalDocs::File->SplitPath($entry->Target()))[1] );
        -
        -                            my $unsharedDirectory = $entryDirectories[$unsharedIndex];
        -
        -                            if (exists $directoryGroups{$unsharedDirectory})
        -                                {
        -                                my $targetGroup = $directoryGroups{$unsharedDirectory};
        -
        -                                if ($afterOriginal)
        -                                    {  $targetGroup->MarkEndOfOriginal();  };
        -                                $targetGroup->PushToGroup($entry);
        -
        -                                $groupEntry->DeleteFromGroup($index);
        -                                }
        -                            else
        -                                {  $index++;  };
        -                            }
        -
        -                        elsif ($entry->Type() == ::MENU_ENDOFORIGINAL())
        -                            {
        -                            $afterOriginal = 1;
        -                            $index++;
        -                            }
        -
        -                        elsif ($entry->Type() == ::MENU_GROUP())
        -                            {
        -                            # See if we need to relocate this group.
        -
        -                            my @groupDirectories = $self->SharedDirectoriesOf($entry);
        -
        -                            # The group's shared directories must be at least two levels deeper than the current.  If the first level deeper
        -                            # is a new group, move it there because it's a subdirectory of that one.
        -                            if (scalar @groupDirectories - scalar @sharedDirectories >= 2)
        -                                {
        -                                my $unsharedDirectory = $groupDirectories[$unsharedIndex];
        -
        -                                if (exists $directoryGroups{$unsharedDirectory} &&
        -                                    $directoryGroups{$unsharedDirectory} != $entry)
        -                                    {
        -                                    my $targetGroup = $directoryGroups{$unsharedDirectory};
        -
        -                                    if ($afterOriginal)
        -                                        {  $targetGroup->MarkEndOfOriginal();  };
        -                                    $targetGroup->PushToGroup($entry);
        -
        -                                    $groupEntry->DeleteFromGroup($index);
        -
        -                                    # We need to retitle the group if it has the name of the unshared directory.
        -
        -                                    my $oldTitle = $entry->Title();
        -                                    $oldTitle =~ s/ +//g;
        -                                    $unsharedDirectory =~ s/ +//g;
        -
        -                                    if (lc($oldTitle) eq lc($unsharedDirectory))
        -                                        {
        -                                        $entry->SetTitle($groupDirectories[$unsharedIndex + 1]);
        -                                        };
        -                                    }
        -                                else
        -                                    {  $index++;  };
        -                                }
        -                            else
        -                                {  $index++;  };
        -                            }
        -
        -                        else
        -                            {  $index++;  };
        -                        };
        -
        -                    $hasChanged = 1;
        -
        -                    if ($fileCount <= MAXFILESINGROUP)
        -                        {  $groupEntry->SetFlags( $groupEntry->Flags() & ~::MENU_GROUP_UPDATESTRUCTURE() );  };
        -
        -                    $groupEntry->SetFlags( $groupEntry->Flags() | ::MENU_GROUP_UPDATETITLES() |
        -                                                                                         ::MENU_GROUP_UPDATEORDER() );
        -                    };
        -
        -                };  # If group has >MAXFILESINGROUP files
        -            };  # If group has UPDATESTRUCTURE
        -
        -
        -        # Okay, now go through all the subgroups.  We do this after the above so that newly created groups can get subgrouped
        -        # further.
        -
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {  push @groupStack, $entry;  };
        -            };
        -
        -        };  # For each group entry
        -    };
        -
        -
        -#
        -#   Function: DetectOrder
        -#
        -#   Detects the order of the entries in all groups that have the <MENU_GROUP_UPDATEORDER> flag set.  Will set one of the
        -#   <MENU_GROUP_FILESSORTED>, <MENU_GROUP_FILESANDGROUPSSORTED>, <MENU_GROUP_EVERYTHINGSORTED>, or
        -#   <MENU_GROUP_UNSORTED> flags.  It will always go for the most comprehensive sort possible, so if a group only has one
        -#   entry, it will be flagged as <MENU_GROUP_EVERYTHINGSORTED>.
        -#
        -#   <DetectIndexGroups()> should be called beforehand, as the <MENU_GROUP_ISINDEXGROUP> flag affects how the order is
        -#   detected.
        -#
        -#   The sort detection stops if it reaches a <MENU_ENDOFORIGINAL> entry, so new entries can be added to the end while still
        -#   allowing the original sort to be detected.
        -#
        -#   Parameters:
        -#
        -#       forceAll - If set, the order will be detected for all groups regardless of whether <MENU_GROUP_UPDATEORDER> is set.
        -#
        -sub DetectOrder #(forceAll)
        -    {
        -    my ($self, $forceAll) = @_;
        -    my @groupStack = ( $menu );
        -
        -    while (scalar @groupStack)
        -        {
        -        my $groupEntry = pop @groupStack;
        -        my $index = 0;
        -
        -
        -        # First detect the sort.
        -
        -        if ($forceAll || ($groupEntry->Flags() & ::MENU_GROUP_UPDATEORDER()) )
        -            {
        -            my $order = ::MENU_GROUP_EVERYTHINGSORTED();
        -
        -            my $lastFile;
        -            my $lastFileOrGroup;
        -
        -            while ($index < scalar @{$groupEntry->GroupContent()} &&
        -                     $groupEntry->GroupContent()->[$index]->Type() != ::MENU_ENDOFORIGINAL() &&
        -                     $order != ::MENU_GROUP_UNSORTED())
        -                {
        -                my $entry = $groupEntry->GroupContent()->[$index];
        -
        -
        -                # Ignore the last entry if it's an index group.  We don't want it to affect the sort.
        -
        -                if ($index + 1 == scalar @{$groupEntry->GroupContent()} &&
        -                    $entry->Type() == ::MENU_GROUP() && ($entry->Flags() & ::MENU_GROUP_ISINDEXGROUP()) )
        -                    {
        -                    # Ignore.
        -
        -                    # This is an awkward code construct, basically working towards an else instead of using an if, but the code just gets
        -                    # too hard to read otherwise.  The compiled code should work out to roughly the same thing anyway.
        -                    }
        -
        -
        -                # Ignore the first entry if it's the general index in an index group.  We don't want it to affect the sort.
        -
        -                elsif ($index == 0 && ($groupEntry->Flags() & ::MENU_GROUP_ISINDEXGROUP()) &&
        -                        $entry->Type() == ::MENU_INDEX() && $entry->Target() eq ::TOPIC_GENERAL() )
        -                    {
        -                    # Ignore.
        -                    }
        -
        -
        -                # Degenerate the sort.
        -
        -                else
        -                    {
        -
        -                    if ($order == ::MENU_GROUP_EVERYTHINGSORTED() && $index > 0 &&
        -                        ::StringCompare($entry->Title(), $groupEntry->GroupContent()->[$index - 1]->Title()) < 0)
        -                        {  $order = ::MENU_GROUP_FILESANDGROUPSSORTED();  };
        -
        -                    if ($order == ::MENU_GROUP_FILESANDGROUPSSORTED() &&
        -                        ($entry->Type() == ::MENU_FILE() || $entry->Type() == ::MENU_GROUP()) &&
        -                        defined $lastFileOrGroup && ::StringCompare($entry->Title(), $lastFileOrGroup->Title()) < 0)
        -                        {  $order = ::MENU_GROUP_FILESSORTED();  };
        -
        -                    if ($order == ::MENU_GROUP_FILESSORTED() &&
        -                        $entry->Type() == ::MENU_FILE() && defined $lastFile &&
        -                        ::StringCompare($entry->Title(), $lastFile->Title()) < 0)
        -                        {  $order = ::MENU_GROUP_UNSORTED();  };
        -
        -                    };
        -
        -
        -                # Set the lastX parameters for comparison and add sub-groups to the stack.
        -
        -                if ($entry->Type() == ::MENU_FILE())
        -                    {
        -                    $lastFile = $entry;
        -                    $lastFileOrGroup = $entry;
        -                    }
        -                elsif ($entry->Type() == ::MENU_GROUP())
        -                    {
        -                    $lastFileOrGroup = $entry;
        -                    push @groupStack, $entry;
        -                    };
        -
        -                $index++;
        -                };
        -
        -            $groupEntry->SetFlags($groupEntry->Flags() | $order);
        -            };
        -
        -
        -        # Find any subgroups in the remaining entries.
        -
        -        while ($index < scalar @{$groupEntry->GroupContent()})
        -            {
        -            my $entry = $groupEntry->GroupContent()->[$index];
        -
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {  push @groupStack, $entry;  };
        -
        -            $index++;
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: GenerateAutoFileTitles
        -#
        -#   Creates titles for the unlocked file entries in all groups that have the <MENU_GROUP_UPDATETITLES> flag set.  It clears the
        -#   flag afterwards so it can be used efficiently for multiple sweeps.
        -#
        -#   Parameters:
        -#
        -#       forceAll - If set, forces all the unlocked file titles to update regardless of whether the group has the
        -#                     <MENU_GROUP_UPDATETITLES> flag set.
        -#
        -sub GenerateAutoFileTitles #(forceAll)
        -    {
        -    my ($self, $forceAll) = @_;
        -
        -    my @groupStack = ( $menu );
        -
        -    while (scalar @groupStack)
        -        {
        -        my $groupEntry = pop @groupStack;
        -
        -        if ($forceAll || ($groupEntry->Flags() & ::MENU_GROUP_UPDATETITLES()) )
        -            {
        -            # Find common prefixes and paths to strip from the default menu titles.
        -
        -            my @sharedDirectories = $self->SharedDirectoriesOf($groupEntry);
        -            my $noSharedDirectories = (scalar @sharedDirectories == 0);
        -
        -            my @sharedPrefixes;
        -            my $noSharedPrefixes;
        -
        -            foreach my $entry (@{$groupEntry->GroupContent()})
        -                {
        -                if ($entry->Type() == ::MENU_FILE())
        -                    {
        -                    # Find the common prefixes among all file entries that are unlocked and don't use the file name as their default title.
        -
        -                    my $defaultTitle = NaturalDocs::Project->DefaultMenuTitleOf($entry->Target());
        -
        -                    if (!$noSharedPrefixes && ($entry->Flags() & ::MENU_FILE_NOAUTOTITLE()) == 0 &&
        -                        $defaultTitle ne $entry->Target())
        -                        {
        -                        # If the filename is part of the title, separate it off so no part of it gets included as a common prefix.  This would
        -                        # happen if there's a group with only one file in it (Project.h => h) or only files that differ by extension
        -                        # (Project.h, Project.cpp => h, cpp) and people labeled them manually (// File: Project.h).
        -                        my $filename = (NaturalDocs::File->SplitPath($entry->Target()))[2];
        -                        my $filenamePart;
        -
        -                        if ( length $defaultTitle >= length $filename &&
        -                             lc(substr($defaultTitle, 0 - length($filename))) eq lc($filename) )
        -                            {
        -                            $filenamePart = substr($defaultTitle, 0 - length($filename));
        -                            $defaultTitle = substr($defaultTitle, 0, 0 - length($filename));
        -                            };
        -
        -
        -                        my @entryPrefixes = split(/(\.|::|->)/, $defaultTitle);
        -
        -                        # Remove potential leading undef/empty string.
        -                        if (!length $entryPrefixes[0])
        -                            {  shift @entryPrefixes;  };
        -
        -                        # Remove last entry.  Something has to exist for the title.  If we already separated off the filename, that will be
        -                        # it instead.
        -                        if (!$filenamePart)
        -                            {  pop @entryPrefixes;  };
        -
        -                        if (!scalar @entryPrefixes)
        -                            {  $noSharedPrefixes = 1;  }
        -                        elsif (!scalar @sharedPrefixes)
        -                            {  @sharedPrefixes = @entryPrefixes;  }
        -                        elsif ($entryPrefixes[0] ne $sharedPrefixes[0])
        -                            {  $noSharedPrefixes = 1;  }
        -
        -                        # If both arrays have entries, and the first is shared...
        -                        else
        -                            {
        -                            my $index = 1;
        -
        -                            while ($index < scalar @sharedPrefixes && $entryPrefixes[$index] eq $sharedPrefixes[$index])
        -                                {  $index++;  };
        -
        -                            if ($index < scalar @sharedPrefixes)
        -                                {  splice(@sharedPrefixes, $index);  };
        -                            };
        -                        };
        -
        -                    };  # if entry is MENU_FILE
        -                };  # foreach entry in group content.
        -
        -
        -            if (!scalar @sharedPrefixes)
        -                {  $noSharedPrefixes = 1;  };
        -
        -
        -            # Update all the menu titles of unlocked file entries.
        -
        -            foreach my $entry (@{$groupEntry->GroupContent()})
        -                {
        -                if ($entry->Type() == ::MENU_FILE() && ($entry->Flags() & ::MENU_FILE_NOAUTOTITLE()) == 0)
        -                    {
        -                    my $title = NaturalDocs::Project->DefaultMenuTitleOf($entry->Target());
        -
        -                    if ($title eq $entry->Target())
        -                        {
        -                        my ($volume, $directoryString, $file) = NaturalDocs::File->SplitPath($entry->Target());
        -                        my @directories = NaturalDocs::File->SplitDirectories($directoryString);
        -
        -                        if (!$noSharedDirectories)
        -                            {  splice(@directories, 0, scalar @sharedDirectories);  };
        -
        -                        # directory\...\directory\file.ext
        -
        -                        if (scalar @directories > 2)
        -                            {  @directories = ( $directories[0], '...', $directories[-1] );  };
        -
        -                        $directoryString = NaturalDocs::File->JoinDirectories(@directories);
        -                        $title = NaturalDocs::File->JoinPaths($directoryString, $file);
        -                        }
        -
        -                    else
        -                        {
        -                        my $filename = (NaturalDocs::File->SplitPath($entry->Target()))[2];
        -                        my $filenamePart;
        -
        -                        if ( length $title >= length $filename &&
        -                             lc(substr($title, 0 - length($filename))) eq lc($filename) )
        -                            {
        -                            $filenamePart = substr($title, 0 - length($filename));
        -                            $title = substr($title, 0, 0 - length($filename));
        -                            };
        -
        -                        my @segments = split(/(::|\.|->)/, $title);
        -                        if (!length $segments[0])
        -                            {  shift @segments;  };
        -
        -                        if ($filenamePart)
        -                            {  push @segments, $filenamePart;  };
        -
        -                        if (!$noSharedPrefixes)
        -                            {  splice(@segments, 0, scalar @sharedPrefixes);  };
        -
        -                        # package...package::target
        -
        -                        if (scalar @segments > 5)
        -                            {  splice(@segments, 1, scalar @segments - 4, '...');  };
        -
        -                        $title = join('', @segments);
        -                        };
        -
        -                    $entry->SetTitle($title);
        -                    };  # If entry is an unlocked file
        -                };  # Foreach entry
        -
        -            $groupEntry->SetFlags( $groupEntry->Flags() & ~::MENU_GROUP_UPDATETITLES() );
        -
        -            };  # If updating group titles
        -
        -        # Now find any subgroups.
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {  push @groupStack, $entry;  };
        -            };
        -        };
        -
        -    };
        -
        -
        -#
        -#   Function: ResortGroups
        -#
        -#   Resorts all groups that have <MENU_GROUP_UPDATEORDER> set.  Assumes <DetectOrder()> and <GenerateAutoFileTitles()>
        -#   have already been called.  Will clear the flag and any <MENU_ENDOFORIGINAL> entries on reordered groups.
        -#
        -#   Parameters:
        -#
        -#       forceAll - If set, resorts all groups regardless of whether <MENU_GROUP_UPDATEORDER> is set.
        -#
        -sub ResortGroups #(forceAll)
        -    {
        -    my ($self, $forceAll) = @_;
        -    my @groupStack = ( $menu );
        -
        -    while (scalar @groupStack)
        -        {
        -        my $groupEntry = pop @groupStack;
        -
        -        if ($forceAll || ($groupEntry->Flags() & ::MENU_GROUP_UPDATEORDER()) )
        -            {
        -            my $newEntriesIndex;
        -
        -
        -            # Strip the ENDOFORIGINAL.
        -
        -            if ($groupEntry->Flags() & ::MENU_GROUP_HASENDOFORIGINAL())
        -                {
        -                $newEntriesIndex = 0;
        -
        -                while ($newEntriesIndex < scalar @{$groupEntry->GroupContent()} &&
        -                         $groupEntry->GroupContent()->[$newEntriesIndex]->Type() != ::MENU_ENDOFORIGINAL() )
        -                    {  $newEntriesIndex++;  };
        -
        -                $groupEntry->DeleteFromGroup($newEntriesIndex);
        -
        -                $groupEntry->SetFlags( $groupEntry->Flags() & ~::MENU_GROUP_HASENDOFORIGINAL() );
        -                }
        -            else
        -                {  $newEntriesIndex = -1;  };
        -
        -
        -            # Strip the exceptions.
        -
        -            my $trailingIndexGroup;
        -            my $leadingGeneralIndex;
        -
        -            if ( ($groupEntry->Flags() & ::MENU_GROUP_ISINDEXGROUP()) &&
        -                 $groupEntry->GroupContent()->[0]->Type() == ::MENU_INDEX() &&
        -                 $groupEntry->GroupContent()->[0]->Target() eq ::TOPIC_GENERAL() )
        -                {
        -                $leadingGeneralIndex = shift @{$groupEntry->GroupContent()};
        -                if ($newEntriesIndex != -1)
        -                    {  $newEntriesIndex--;  };
        -                }
        -
        -            elsif (scalar @{$groupEntry->GroupContent()} && $newEntriesIndex != 0)
        -                {
        -                my $lastIndex;
        -
        -                if ($newEntriesIndex != -1)
        -                    {  $lastIndex = $newEntriesIndex - 1;  }
        -                else
        -                    {  $lastIndex = scalar @{$groupEntry->GroupContent()} - 1;  };
        -
        -                if ($groupEntry->GroupContent()->[$lastIndex]->Type() == ::MENU_GROUP() &&
        -                    ( $groupEntry->GroupContent()->[$lastIndex]->Flags() & ::MENU_GROUP_ISINDEXGROUP() ) )
        -                    {
        -                    $trailingIndexGroup = $groupEntry->GroupContent()->[$lastIndex];
        -                    $groupEntry->DeleteFromGroup($lastIndex);
        -
        -                    if ($newEntriesIndex != -1)
        -                        {  $newEntriesIndex++;  };
        -                    };
        -                };
        -
        -
        -            # If there weren't already exceptions, strip them from the new entries.
        -
        -            if ( (!defined $trailingIndexGroup || !defined $leadingGeneralIndex) && $newEntriesIndex != -1)
        -                {
        -                my $index = $newEntriesIndex;
        -
        -                while ($index < scalar @{$groupEntry->GroupContent()})
        -                    {
        -                    my $entry = $groupEntry->GroupContent()->[$index];
        -
        -                    if (!defined $trailingIndexGroup &&
        -                        $entry->Type() == ::MENU_GROUP() && ($entry->Flags() & ::MENU_GROUP_ISINDEXGROUP()) )
        -                        {
        -                        $trailingIndexGroup = $entry;
        -                        $groupEntry->DeleteFromGroup($index);
        -                        }
        -                    elsif (!defined $leadingGeneralIndex && ($groupEntry->Flags() & ::MENU_GROUP_ISINDEXGROUP()) &&
        -                            $entry->Type() == ::MENU_INDEX() && !defined $entry->Target())
        -                        {
        -                        $leadingGeneralIndex = $entry;
        -                        $groupEntry->DeleteFromGroup($index);
        -                        }
        -                    else
        -                        {  $index++;  };
        -                    };
        -                };
        -
        -
        -            # If there's no order, we still want to sort the new additions.
        -
        -            if ($groupEntry->Flags() & ::MENU_GROUP_UNSORTED())
        -                {
        -                if ($newEntriesIndex != -1)
        -                    {
        -                    my @newEntries =
        -                        @{$groupEntry->GroupContent()}[$newEntriesIndex..scalar @{$groupEntry->GroupContent()} - 1];
        -
        -                    @newEntries = sort { $self->CompareEntries($a, $b) } @newEntries;
        -
        -                    foreach my $newEntry (@newEntries)
        -                        {
        -                        $groupEntry->GroupContent()->[$newEntriesIndex] = $newEntry;
        -                        $newEntriesIndex++;
        -                        };
        -                    };
        -                }
        -
        -            elsif ($groupEntry->Flags() & ::MENU_GROUP_EVERYTHINGSORTED())
        -                {
        -                @{$groupEntry->GroupContent()} = sort { $self->CompareEntries($a, $b) } @{$groupEntry->GroupContent()};
        -                }
        -
        -            elsif ( ($groupEntry->Flags() & ::MENU_GROUP_FILESSORTED()) ||
        -                     ($groupEntry->Flags() & ::MENU_GROUP_FILESANDGROUPSSORTED()) )
        -                {
        -                my $groupContent = $groupEntry->GroupContent();
        -                my @newEntries;
        -
        -                if ($newEntriesIndex != -1)
        -                    {  @newEntries = splice( @$groupContent, $newEntriesIndex );  };
        -
        -
        -                # First resort the existing entries.
        -
        -                # A couple of support functions.  They're defined here instead of spun off into their own functions because they're only
        -                # used here and to make them general we would need to add support for the other sort options.
        -
        -                sub IsIncludedInSort #(groupEntry, entry)
        -                    {
        -                    my ($self, $groupEntry, $entry) = @_;
        -
        -                    return ($entry->Type() == ::MENU_FILE() ||
        -                                ( $entry->Type() == ::MENU_GROUP() &&
        -                                    ($groupEntry->Flags() & ::MENU_GROUP_FILESANDGROUPSSORTED()) ) );
        -                    };
        -
        -                sub IsSorted #(groupEntry)
        -                    {
        -                    my ($self, $groupEntry) = @_;
        -                    my $lastApplicable;
        -
        -                    foreach my $entry (@{$groupEntry->GroupContent()})
        -                        {
        -                        # If the entry is applicable to the sort order...
        -                        if ($self->IsIncludedInSort($groupEntry, $entry))
        -                            {
        -                            if (defined $lastApplicable)
        -                                {
        -                                if ($self->CompareEntries($entry, $lastApplicable) < 0)
        -                                    {  return undef;  };
        -                                };
        -
        -                            $lastApplicable = $entry;
        -                            };
        -                        };
        -
        -                    return 1;
        -                    };
        -
        -
        -                # There's a good chance it's still sorted.  They should only become unsorted if an auto-title changes.
        -                if (!$self->IsSorted($groupEntry))
        -                    {
        -                    # Crap.  Okay, method one is to sort each group of continuous sortable elements.  There's a possibility that doing
        -                    # this will cause the whole to become sorted again.  We try this first, even though it isn't guaranteed to succeed,
        -                    # because it will restore the sort without moving any unsortable entries.
        -
        -                    # Copy it because we'll need the original if this fails.
        -                    my @originalGroupContent = @$groupContent;
        -
        -                    my $index = 0;
        -                    my $startSortable = 0;
        -
        -                    while (1)
        -                        {
        -                        # If index is on an unsortable entry or the end of the array...
        -                        if ($index == scalar @$groupContent || !$self->IsIncludedInSort($groupEntry, $groupContent->[$index]))
        -                            {
        -                            # If we have at least two sortable entries...
        -                            if ($index - $startSortable >= 2)
        -                                {
        -                                # Sort them.
        -                                my @sortableEntries = @{$groupContent}[$startSortable .. $index - 1];
        -                                @sortableEntries = sort { $self->CompareEntries($a, $b) } @sortableEntries;
        -                                foreach my $sortableEntry (@sortableEntries)
        -                                    {
        -                                    $groupContent->[$startSortable] = $sortableEntry;
        -                                    $startSortable++;
        -                                    };
        -                                };
        -
        -                            if ($index == scalar @$groupContent)
        -                                {  last;  };
        -
        -                            $startSortable = $index + 1;
        -                            };
        -
        -                        $index++;
        -                        };
        -
        -                    if (!$self->IsSorted($groupEntry))
        -                        {
        -                        # Crap crap.  Okay, now we do a full sort but with potential damage to the original structure.  Each unsortable
        -                        # element is locked to the next sortable element.  We sort the sortable elements, bringing all the unsortable
        -                        # pieces with them.
        -
        -                        my @pieces = ( [ ] );
        -                        my $currentPiece = $pieces[0];
        -
        -                        foreach my $entry (@originalGroupContent)
        -                            {
        -                            push @$currentPiece, $entry;
        -
        -                            # If the entry is sortable...
        -                            if ($self->IsIncludedInSort($groupEntry, $entry))
        -                                {
        -                                $currentPiece = [ ];
        -                                push @pieces, $currentPiece;
        -                                };
        -                            };
        -
        -                        my $lastUnsortablePiece;
        -
        -                        # If the last entry was sortable, we'll have an empty piece at the end.  Drop it.
        -                        if (scalar @{$pieces[-1]} == 0)
        -                            {  pop @pieces;  }
        -
        -                        # If the last entry wasn't sortable, the last piece won't end with a sortable element.  Save it, but remove it
        -                        # from the list.
        -                        else
        -                            {  $lastUnsortablePiece = pop @pieces;  };
        -
        -                        # Sort the list.
        -                        @pieces = sort { $self->CompareEntries( $a->[-1], $b->[-1] ) } @pieces;
        -
        -                        # Copy it back to the original.
        -                        if (defined $lastUnsortablePiece)
        -                            {  push @pieces, $lastUnsortablePiece;  };
        -
        -                        my $index = 0;
        -
        -                        foreach my $piece (@pieces)
        -                            {
        -                            foreach my $entry (@{$piece})
        -                                {
        -                                $groupEntry->GroupContent()->[$index] = $entry;
        -                                $index++;
        -                                };
        -                            };
        -                        };
        -                    };
        -
        -
        -                # Okay, the orginal entries are sorted now.  Sort the new entries and apply.
        -
        -                if (scalar @newEntries)
        -                    {
        -                    @newEntries = sort { $self->CompareEntries($a, $b) } @newEntries;
        -                    my @originalEntries = @$groupContent;
        -                    @$groupContent = ( );
        -
        -                    while (1)
        -                        {
        -                        while (scalar @originalEntries && !$self->IsIncludedInSort($groupEntry, $originalEntries[0]))
        -                            {  push @$groupContent, (shift @originalEntries);  };
        -
        -                        if (!scalar @originalEntries || !scalar @newEntries)
        -                            {  last;  };
        -
        -                        while (scalar @newEntries && $self->CompareEntries($newEntries[0], $originalEntries[0]) < 0)
        -                            {  push @$groupContent, (shift @newEntries);  };
        -
        -                        push @$groupContent, (shift @originalEntries);
        -
        -                        if (!scalar @originalEntries || !scalar @newEntries)
        -                            {  last;  };
        -                        };
        -
        -                    if (scalar @originalEntries)
        -                        {  push @$groupContent, @originalEntries;  }
        -                    elsif (scalar @newEntries)
        -                        {  push @$groupContent, @newEntries;  };
        -                    };
        -                };
        -
        -
        -            # Now re-add the exceptions.
        -
        -            if (defined $leadingGeneralIndex)
        -                {
        -                unshift @{$groupEntry->GroupContent()}, $leadingGeneralIndex;
        -                };
        -
        -            if (defined $trailingIndexGroup)
        -                {
        -                $groupEntry->PushToGroup($trailingIndexGroup);
        -                };
        -
        -            };
        -
        -        foreach my $entry (@{$groupEntry->GroupContent()})
        -            {
        -            if ($entry->Type() == ::MENU_GROUP())
        -                {  push @groupStack, $entry;  };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: CompareEntries
        -#
        -#   A comparison function for use in sorting.  Compares the two entries by their titles with <StringCompare()>, but in the case
        -#   of a tie, puts <MENU_FILE> entries above <MENU_GROUP> entries.
        -#
        -sub CompareEntries #(a, b)
        -    {
        -    my ($self, $a, $b) = @_;
        -
        -    my $result = ::StringCompare($a->Title(), $b->Title());
        -
        -    if ($result == 0)
        -        {
        -        if ($a->Type() == ::MENU_FILE() && $b->Type() == ::MENU_GROUP())
        -            {  $result = -1;  }
        -        elsif ($a->Type() == ::MENU_GROUP() && $b->Type() == ::MENU_FILE())
        -            {  $result = 1;  };
        -        };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: SharedDirectoriesOf
        -#
        -#   Returns an array of all the directories shared by the files in the group.  If none, returns an empty array.
        -#
        -sub SharedDirectoriesOf #(group)
        -    {
        -    my ($self, $groupEntry) = @_;
        -    my @sharedDirectories;
        -
        -    foreach my $entry (@{$groupEntry->GroupContent()})
        -        {
        -        if ($entry->Type() == ::MENU_FILE())
        -            {
        -            my @entryDirectories = NaturalDocs::File->SplitDirectories( (NaturalDocs::File->SplitPath($entry->Target()))[1] );
        -
        -            if (!scalar @sharedDirectories)
        -                {  @sharedDirectories = @entryDirectories;  }
        -            else
        -                {  ::ShortenToMatchStrings(\@sharedDirectories, \@entryDirectories);  };
        -
        -            if (!scalar @sharedDirectories)
        -                {  last;  };
        -            };
        -        };
        -
        -    return @sharedDirectories;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Menu/Entry.pm b/vendor/naturaldocs/Modules/NaturalDocs/Menu/Entry.pm
        deleted file mode 100644
        index 00bdd4e29..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Menu/Entry.pm
        +++ /dev/null
        @@ -1,202 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Menu::Entry
        -#
        -###############################################################################
        -#
        -#   A class representing an entry in the menu.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Menu::Entry;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The object is implemented as a blessed arrayref with the indexes below.
        -#
        -#       TYPE      - The <MenuEntryType>
        -#       TITLE     - The title of the entry.
        -#       TARGET  - The target of the entry.  If the type is <MENU_FILE>, it will be the source <FileName>.  If the type is
        -#                       <MENU_LINK>, it will be the URL.  If the type is <MENU_GROUP>, it will be an arrayref of
        -#                       <NaturalDocs::Menu::Entry> objects representing the group's content.  If the type is <MENU_INDEX>, it will be
        -#                       a <TopicType>.
        -#       FLAGS    - Any <Menu Entry Flags> that apply.
        -#
        -use constant TYPE => 0;
        -use constant TITLE => 1;
        -use constant TARGET => 2;
        -use constant FLAGS => 3;
        -# DEPENDENCY: New() depends on the order of these constants.
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       type     - The <MenuEntryType>.
        -#       title      - The title of the entry.
        -#       target   - The target of the entry, if applicable.  If the type is <MENU_FILE>, use the source <FileName>.  If the type is
        -#                     <MENU_LINK>, use the URL.  If the type is <MENU_INDEX>, use the <TopicType>.  Otherwise set it to undef.
        -#       flags     - Any <Menu Entry Flags> that apply.
        -#
        -sub New #(type, title, target, flags)
        -    {
        -    # DEPENDENCY: This gode depends on the order of the constants.
        -
        -    my $package = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $package;
        -
        -    if ($object->[TYPE] == ::MENU_GROUP())
        -        {  $object->[TARGET] = [ ];  };
        -    if (!defined $object->[FLAGS])
        -        {  $object->[FLAGS] = 0;  };
        -
        -    return $object;
        -    };
        -
        -
        -#   Function: Type
        -#   Returns the <MenuEntryType>.
        -sub Type
        -    {  return $_[0]->[TYPE];  };
        -
        -#   Function: Title
        -#   Returns the title of the entry.
        -sub Title
        -    {  return $_[0]->[TITLE];  };
        -
        -# Function: SetTitle
        -# Replaces the entry's title.
        -sub SetTitle #(title)
        -    {  $_[0]->[TITLE] = $_[1];  };
        -
        -#
        -#   Function: Target
        -#
        -#   Returns the target of the entry, if applicable.  If the type is <MENU_FILE>, it returns the source <FileName>.  If the type is
        -#   <MENU_LINK>, it returns the URL.  If the type is <MENU_INDEX>, it returns the <TopicType>.  Otherwise it returns undef.
        -#
        -sub Target
        -    {
        -    my $self = shift;
        -
        -    # Group entries are the only time when target won't be undef when it should be.
        -    if ($self->Type() == ::MENU_GROUP())
        -        {  return undef;  }
        -    else
        -        {  return $self->[TARGET];  };
        -    };
        -
        -# Function: SetTarget
        -# Replaces the entry's target.
        -sub SetTarget #(target)
        -    {  $_[0]->[TARGET] = $_[1];  };
        -
        -#   Function: Flags
        -#   Returns the <Menu Entry Flags>.
        -sub Flags
        -    {  return $_[0]->[FLAGS];  };
        -
        -# Function: SetFlags
        -# Replaces the <Menu Entry Flags>.
        -sub SetFlags #(flags)
        -    {  $_[0]->[FLAGS] = $_[1];  };
        -
        -
        -
        -###############################################################################
        -# Group: Group Functions
        -#
        -#   All of these functions assume the type is <MENU_GROUP>.  Do *not* call any of these without checking <Type()> first.
        -
        -
        -#
        -#   Function: GroupContent
        -#
        -#   Returns an arrayref of <NaturalDocs::Menu::Entry> objects representing the contents of the
        -#   group, or undef otherwise.  This arrayref will always exist for <MENU_GROUP>'s and can be changed.
        -#
        -sub GroupContent
        -    {
        -    return $_[0]->[TARGET];
        -    };
        -
        -
        -#
        -#   Function: GroupIsEmpty
        -#
        -#   If the type is <MENU_GROUP>, returns whether the group is empty.
        -#
        -sub GroupIsEmpty
        -    {
        -    my $self = shift;
        -    return (scalar @{$self->GroupContent()} > 0);
        -    };
        -
        -
        -#
        -#   Function: PushToGroup
        -#
        -#   Pushes the entry to the end of the group content.
        -#
        -sub PushToGroup #(entry)
        -    {
        -    my ($self, $entry) = @_;
        -    push @{$self->GroupContent()}, $entry;
        -    };
        -
        -
        -#
        -#   Function: DeleteFromGroup
        -#
        -#   Deletes an entry from the group content by index.
        -#
        -sub DeleteFromGroup #(index)
        -    {
        -    my ($self, $index) = @_;
        -
        -    my $groupContent = $self->GroupContent();
        -
        -    splice( @$groupContent, $index, 1 );
        -    };
        -
        -
        -#
        -#   Function: MarkEndOfOriginal
        -#
        -#   If the group doesn't already have one, adds a <MENU_ENDOFORIGINAL> entry to the end and sets the
        -#   <MENU_GROUP_HASENDOFORIGINAL> flag.
        -#
        -sub MarkEndOfOriginal
        -    {
        -    my $self = shift;
        -
        -    if (($self->Flags() & ::MENU_GROUP_HASENDOFORIGINAL()) == 0)
        -        {
        -        $self->PushToGroup( NaturalDocs::Menu::Entry->New(::MENU_ENDOFORIGINAL(), undef, undef, undef) );
        -        $self->SetFlags( $self->Flags() | ::MENU_GROUP_HASENDOFORIGINAL() );
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/NDMarkup.pm b/vendor/naturaldocs/Modules/NaturalDocs/NDMarkup.pm
        deleted file mode 100644
        index 46adc0211..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/NDMarkup.pm
        +++ /dev/null
        @@ -1,77 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::NDMarkup
        -#
        -###############################################################################
        -#
        -#   A package of support functions for dealing with <NDMarkup>.
        -#
        -#   Usage and Dependencies:
        -#
        -#       The package doesn't depend on any Natural Docs packages and is ready to use right away.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::NDMarkup;
        -
        -#
        -#   Function: ConvertAmpChars
        -#
        -#   Substitutes certain characters with their <NDMarkup> amp chars.
        -#
        -#   Parameters:
        -#
        -#       text - The block of text to convert.
        -#
        -#   Returns:
        -#
        -#       The converted text block.
        -#
        -sub ConvertAmpChars #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ s/&/&amp;/g;
        -    $text =~ s/</&lt;/g;
        -    $text =~ s/>/&gt;/g;
        -    $text =~ s/\"/&quot;/g;
        -
        -    return $text;
        -    };
        -
        -
        -#
        -#   Function: RestoreAmpChars
        -#
        -#   Replaces <NDMarkup> amp chars with their original symbols.
        -#
        -#   Parameters:
        -#
        -#       text - The text to restore.
        -#
        -#   Returns:
        -#
        -#       The restored text.
        -#
        -sub RestoreAmpChars #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ s/&quot;/\"/g;
        -    $text =~ s/&gt;/>/g;
        -    $text =~ s/&lt;/</g;
        -    $text =~ s/&amp;/&/g;
        -
        -    return $text;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Parser.pm b/vendor/naturaldocs/Modules/NaturalDocs/Parser.pm
        deleted file mode 100644
        index 24c415feb..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Parser.pm
        +++ /dev/null
        @@ -1,1335 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Parser
        -#
        -###############################################################################
        -#
        -#   A package that coordinates source file parsing between the <NaturalDocs::Languages::Base>-derived objects and its own
        -#   sub-packages such as <NaturalDocs::Parser::Native>.  Also handles sending symbols to <NaturalDocs::SymbolTable> and
        -#   other generic topic processing.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - Prior to use, <NaturalDocs::Settings>, <NaturalDocs::Languages>, <NaturalDocs::Project>, <NaturalDocs::SymbolTable>,
        -#         and <NaturalDocs::ClassHierarchy> must be initialized.  <NaturalDocs::SymbolTable> and <NaturalDocs::ClassHierarchy>
        -#         do not have to be fully resolved.
        -#
        -#       - Aside from that, the package is ready to use right away.  It does not have its own initialization function.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use NaturalDocs::Parser::ParsedTopic;
        -use NaturalDocs::Parser::Native;
        -use NaturalDocs::Parser::JavaDoc;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Parser;
        -
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   var: sourceFile
        -#
        -#   The source <FileName> currently being parsed.
        -#
        -my $sourceFile;
        -
        -#
        -#   var: language
        -#
        -#   The language object for the file, derived from <NaturalDocs::Languages::Base>.
        -#
        -my $language;
        -
        -#
        -#   Array: parsedFile
        -#
        -#   An array of <NaturalDocs::Parser::ParsedTopic> objects.
        -#
        -my @parsedFile;
        -
        -
        -#
        -#   bool: parsingForInformation
        -#   Whether <ParseForInformation()> was called.  If false, then <ParseForBuild()> was called.
        -#
        -my $parsingForInformation;
        -
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: ParseForInformation
        -#
        -#   Parses the input file for information.  Will update the information about the file in <NaturalDocs::SymbolTable> and
        -#   <NaturalDocs::Project>.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> to parse.
        -#
        -sub ParseForInformation #(file)
        -    {
        -    my ($self, $file) = @_;
        -    $sourceFile = $file;
        -
        -    $parsingForInformation = 1;
        -
        -    # Watch this parse so we detect any changes.
        -    NaturalDocs::SymbolTable->WatchFileForChanges($sourceFile);
        -    NaturalDocs::ClassHierarchy->WatchFileForChanges($sourceFile);
        -    NaturalDocs::SourceDB->WatchFileForChanges($sourceFile);
        -
        -    my $defaultMenuTitle = $self->Parse();
        -
        -    foreach my $topic (@parsedFile)
        -        {
        -        # Add a symbol for the topic.
        -
        -        my $type = $topic->Type();
        -        if ($type eq ::TOPIC_ENUMERATION())
        -            {  $type = ::TOPIC_TYPE();  };
        -
        -        NaturalDocs::SymbolTable->AddSymbol($topic->Symbol(), $sourceFile, $type,
        -                                                                   $topic->Prototype(), $topic->Summary());
        -
        -
        -        # You can't put the function call directly in a while with a regex.  It has to sit in a variable to work.
        -        my $body = $topic->Body();
        -
        -
        -        # If it's a list or enum topic, add a symbol for each description list entry.
        -
        -        if ($topic->IsList() || $topic->Type() eq ::TOPIC_ENUMERATION())
        -            {
        -            # We'll hijack the enum constants to apply to non-enum behavior too.
        -            my $behavior;
        -
        -            if ($topic->Type() eq ::TOPIC_ENUMERATION())
        -                {
        -                $type = ::TOPIC_CONSTANT();
        -                $behavior = $language->EnumValues();
        -                }
        -            elsif (NaturalDocs::Topics->TypeInfo($topic->Type())->Scope() == ::SCOPE_ALWAYS_GLOBAL())
        -                {
        -                $behavior = ::ENUM_GLOBAL();
        -                }
        -            else
        -                {
        -                $behavior = ::ENUM_UNDER_PARENT();
        -                };
        -
        -            while ($body =~ /<ds>([^<]+)<\/ds><dd>(.*?)<\/dd>/g)
        -                {
        -                my ($listTextSymbol, $listSummary) = ($1, $2);
        -
        -                $listTextSymbol = NaturalDocs::NDMarkup->RestoreAmpChars($listTextSymbol);
        -                my $listSymbol = NaturalDocs::SymbolString->FromText($listTextSymbol);
        -
        -                if ($behavior == ::ENUM_UNDER_PARENT())
        -                    {  $listSymbol = NaturalDocs::SymbolString->Join($topic->Package(), $listSymbol);  }
        -                elsif ($behavior == ::ENUM_UNDER_TYPE())
        -                    {  $listSymbol = NaturalDocs::SymbolString->Join($topic->Symbol(), $listSymbol);  };
        -
        -                NaturalDocs::SymbolTable->AddSymbol($listSymbol, $sourceFile, $type, undef,
        -                                                                           $self->GetSummaryFromDescriptionList($listSummary));
        -                };
        -            };
        -
        -
        -        # Add references in the topic.
        -
        -        while ($body =~ /<link target=\"([^\"]*)\" name=\"[^\"]*\" original=\"[^\"]*\">/g)
        -            {
        -            my $linkText = NaturalDocs::NDMarkup->RestoreAmpChars($1);
        -            my $linkSymbol = NaturalDocs::SymbolString->FromText($linkText);
        -
        -            NaturalDocs::SymbolTable->AddReference(::REFERENCE_TEXT(), $linkSymbol,
        -                                                                           $topic->Package(), $topic->Using(), $sourceFile);
        -            };
        -
        -
        -        # Add images in the topic.
        -
        -        while ($body =~ /<img mode=\"[^\"]*\" target=\"([^\"]+)\" original=\"[^\"]*\">/g)
        -            {
        -            my $target = NaturalDocs::NDMarkup->RestoreAmpChars($1);
        -            NaturalDocs::ImageReferenceTable->AddReference($sourceFile, $target);
        -            };
        -        };
        -
        -    # Handle any changes to the file.
        -    NaturalDocs::ClassHierarchy->AnalyzeChanges();
        -    NaturalDocs::SymbolTable->AnalyzeChanges();
        -    NaturalDocs::SourceDB->AnalyzeWatchedFileChanges();
        -
        -    # Update project on the file's characteristics.
        -    my $hasContent = (scalar @parsedFile > 0);
        -
        -    NaturalDocs::Project->SetHasContent($sourceFile, $hasContent);
        -    if ($hasContent)
        -        {  NaturalDocs::Project->SetDefaultMenuTitle($sourceFile, $defaultMenuTitle);  };
        -
        -    # We don't need to keep this around.
        -    @parsedFile = ( );
        -    };
        -
        -
        -#
        -#   Function: ParseForBuild
        -#
        -#   Parses the input file for building, returning it as a <NaturalDocs::Parser::ParsedTopic> arrayref.
        -#
        -#   Note that all new and changed files should be parsed for symbols via <ParseForInformation()> before calling this function on
        -#   *any* file.  The reason is that <NaturalDocs::SymbolTable> needs to know about all the symbol definitions and references to
        -#   resolve them properly.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> to parse for building.
        -#
        -#   Returns:
        -#
        -#       An arrayref of the source file as <NaturalDocs::Parser::ParsedTopic> objects.
        -#
        -sub ParseForBuild #(file)
        -    {
        -    my ($self, $file) = @_;
        -    $sourceFile = $file;
        -
        -    $parsingForInformation = undef;
        -
        -    $self->Parse();
        -
        -    return \@parsedFile;
        -    };
        -
        -
        -
        -
        -###############################################################################
        -# Group: Interface Functions
        -
        -
        -#
        -#   Function: OnComment
        -#
        -#   The function called by <NaturalDocs::Languages::Base>-derived objects when their parsers encounter a comment
        -#   suitable for documentation.
        -#
        -#   Parameters:
        -#
        -#       commentLines - An arrayref of the comment's lines.  The language's comment symbols should be converted to spaces,
        -#                               and there should be no line break characters at the end of each line.  *The original memory will be
        -#                               changed.*
        -#       lineNumber - The line number of the first of the comment lines.
        -#       isJavaDoc - Whether the comment is in JavaDoc format.
        -#
        -#   Returns:
        -#
        -#       The number of topics created by this comment, or zero if none.
        -#
        -sub OnComment #(string[] commentLines, int lineNumber, bool isJavaDoc)
        -    {
        -    my ($self, $commentLines, $lineNumber, $isJavaDoc) = @_;
        -
        -    $self->CleanComment($commentLines);
        -
        -    # We check if it's definitely Natural Docs content first.  This overrides all else, since it's possible that a comment could start
        -    # with a topic line yet have something that looks like a JavaDoc tag.  Natural Docs wins in this case.
        -    if (NaturalDocs::Parser::Native->IsMine($commentLines, $isJavaDoc))
        -        {  return NaturalDocs::Parser::Native->ParseComment($commentLines, $isJavaDoc, $lineNumber, \@parsedFile);  }
        -
        -    elsif (NaturalDocs::Parser::JavaDoc->IsMine($commentLines, $isJavaDoc))
        -        {  return NaturalDocs::Parser::JavaDoc->ParseComment($commentLines, $isJavaDoc, $lineNumber, \@parsedFile);  }
        -
        -    # If the content is ambiguous and it's a JavaDoc-styled comment, treat it as Natural Docs content.
        -    elsif ($isJavaDoc)
        -        {  return NaturalDocs::Parser::Native->ParseComment($commentLines, $isJavaDoc, $lineNumber, \@parsedFile);  }
        -    };
        -
        -
        -#
        -#   Function: OnClass
        -#
        -#   A function called by <NaturalDocs::Languages::Base>-derived objects when their parsers encounter a class declaration.
        -#
        -#   Parameters:
        -#
        -#       class - The <SymbolString> of the class encountered.
        -#
        -sub OnClass #(class)
        -    {
        -    my ($self, $class) = @_;
        -
        -    if ($parsingForInformation)
        -        {  NaturalDocs::ClassHierarchy->AddClass($sourceFile, $class);  };
        -    };
        -
        -
        -#
        -#   Function: OnClassParent
        -#
        -#   A function called by <NaturalDocs::Languages::Base>-derived objects when their parsers encounter a declaration of
        -#   inheritance.
        -#
        -#   Parameters:
        -#
        -#       class - The <SymbolString> of the class we're in.
        -#       parent - The <SymbolString> of the class it inherits.
        -#       scope - The package <SymbolString> that the reference appeared in.
        -#       using - An arrayref of package <SymbolStrings> that the reference has access to via "using" statements.
        -#       resolvingFlags - Any <Resolving Flags> to be used when resolving the reference.  <RESOLVE_NOPLURAL> is added
        -#                              automatically since that would never apply to source code.
        -#
        -sub OnClassParent #(class, parent, scope, using, resolvingFlags)
        -    {
        -    my ($self, $class, $parent, $scope, $using, $resolvingFlags) = @_;
        -
        -    if ($parsingForInformation)
        -        {
        -        NaturalDocs::ClassHierarchy->AddParentReference($sourceFile, $class, $parent, $scope, $using,
        -                                                                                   $resolvingFlags | ::RESOLVE_NOPLURAL());
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#   Function: Parse
        -#
        -#   Opens the source file and parses process.  Most of the actual parsing is done in <NaturalDocs::Languages::Base->ParseFile()>
        -#   and <OnComment()>, though.
        -#
        -#   *Do not call externally.*  Rather, call <ParseForInformation()> or <ParseForBuild()>.
        -#
        -#   Returns:
        -#
        -#       The default menu title of the file.  Will be the <FileName> if nothing better is found.
        -#
        -sub Parse
        -    {
        -    my ($self) = @_;
        -
        -    NaturalDocs::Error->OnStartParsing($sourceFile);
        -
        -    $language = NaturalDocs::Languages->LanguageOf($sourceFile);
        -    NaturalDocs::Parser::Native->Start();
        -    @parsedFile = ( );
        -
        -    my ($autoTopics, $scopeRecord) = $language->ParseFile($sourceFile, \@parsedFile);
        -
        -
        -    $self->AddToClassHierarchy();
        -
        -    $self->BreakLists();
        -
        -    if (defined $autoTopics)
        -        {
        -        if (defined $scopeRecord)
        -            {  $self->RepairPackages($autoTopics, $scopeRecord);  };
        -
        -        $self->MergeAutoTopics($language, $autoTopics);
        -        };
        -
        -    $self->RemoveRemainingHeaderlessTopics();
        -
        -
        -    # We don't need to do this if there aren't any auto-topics because the only package changes would be implied by the comments.
        -    if (defined $autoTopics)
        -        {  $self->AddPackageDelineators();  };
        -
        -    if (!NaturalDocs::Settings->NoAutoGroup())
        -        {  $self->MakeAutoGroups($autoTopics);  };
        -
        -
        -    # Set the menu title.
        -
        -    my $defaultMenuTitle = $sourceFile;
        -
        -    if (scalar @parsedFile)
        -        {
        -        my $addFileTitle;
        -
        -        if (NaturalDocs::Settings->OnlyFileTitles())
        -            {
        -            # We still want to use the title from the topics if the first one is a file.
        -            if ($parsedFile[0]->Type() eq ::TOPIC_FILE())
        -                {  $addFileTitle = 0;  }
        -            else
        -                {  $addFileTitle = 1;  };
        -            }
        -        elsif (scalar @parsedFile == 1 || NaturalDocs::Topics->TypeInfo( $parsedFile[0]->Type() )->PageTitleIfFirst())
        -            {  $addFileTitle = 0;  }
        -        else
        -            {  $addFileTitle = 1;  };
        -
        -        if (!$addFileTitle)
        -            {
        -            $defaultMenuTitle = $parsedFile[0]->Title();
        -            }
        -        else
        -            {
        -            # If the title ended up being the file name, add a leading section for it.
        -
        -            unshift @parsedFile,
        -                       NaturalDocs::Parser::ParsedTopic->New(::TOPIC_FILE(), (NaturalDocs::File->SplitPath($sourceFile))[2],
        -                                                                                  undef, undef, undef, undef, undef, 1, undef);
        -            };
        -        };
        -
        -    NaturalDocs::Error->OnEndParsing($sourceFile);
        -
        -    return $defaultMenuTitle;
        -    };
        -
        -
        -#
        -#   Function: CleanComment
        -#
        -#   Removes any extraneous formatting and whitespace from the comment.  Eliminates comment boxes, horizontal lines, trailing
        -#   whitespace from lines, and expands all tab characters.  It keeps leading whitespace, though, since it may be needed for
        -#   example code, and blank lines, since the original line numbers are needed.
        -#
        -#   Parameters:
        -#
        -#       commentLines  - An arrayref of the comment lines to clean.  *The original memory will be changed.*  Lines should have the
        -#                                language's comment symbols replaced by spaces and not have a trailing line break.
        -#
        -sub CleanComment #(commentLines)
        -    {
        -    my ($self, $commentLines) = @_;
        -
        -    use constant DONT_KNOW => 0;
        -    use constant IS_UNIFORM => 1;
        -    use constant IS_UNIFORM_IF_AT_END => 2;
        -    use constant IS_NOT_UNIFORM => 3;
        -
        -    my $leftSide = DONT_KNOW;
        -    my $rightSide = DONT_KNOW;
        -    my $leftSideChar;
        -    my $rightSideChar;
        -
        -    my $index = 0;
        -    my $tabLength = NaturalDocs::Settings->TabLength();
        -
        -    while ($index < scalar @$commentLines)
        -        {
        -        # Strip trailing whitespace from the original.
        -
        -        $commentLines->[$index] =~ s/[ \t]+$//;
        -
        -
        -        # Expand tabs in the original.  This method is almost six times faster than Text::Tabs' method.
        -
        -        my $tabIndex = index($commentLines->[$index], "\t");
        -
        -        while ($tabIndex != -1)
        -            {
        -            substr( $commentLines->[$index], $tabIndex, 1, ' ' x ($tabLength - ($tabIndex % $tabLength)) );
        -            $tabIndex = index($commentLines->[$index], "\t", $tabIndex);
        -            };
        -
        -
        -        # Make a working copy and strip leading whitespace as well.  This has to be done after tabs are expanded because
        -        # stripping indentation could change how far tabs are expanded.
        -
        -        my $line = $commentLines->[$index];
        -        $line =~ s/^ +//;
        -
        -        # If the line is blank...
        -        if (!length $line)
        -            {
        -            # If we have a potential vertical line, this only acceptable if it's at the end of the comment.
        -            if ($leftSide == IS_UNIFORM)
        -                {  $leftSide = IS_UNIFORM_IF_AT_END;  };
        -            if ($rightSide == IS_UNIFORM)
        -                {  $rightSide = IS_UNIFORM_IF_AT_END;  };
        -            }
        -
        -        # If there's at least four symbols in a row, it's a horizontal line.  The second regex supports differing edge characters.  It
        -        # doesn't matter if any of this matches the left and right side symbols.  The length < 256 is a sanity check, because that
        -        # regexp has caused the perl regexp engine to choke on an insane line someone sent me from an automatically generated
        -        # file.  It had over 10k characters on the first line, and most of them were 0x00.
        -        elsif ($line =~ /^([^a-zA-Z0-9 ])\1{3,}$/ ||
        -                (length $line < 256 && $line =~ /^([^a-zA-Z0-9 ])\1*([^a-zA-Z0-9 ])\2{3,}([^a-zA-Z0-9 ])\3*$/) )
        -            {
        -            # Ignore it.  This has no effect on the vertical line detection.  We want to keep it in the output though in case it was
        -            # in a code section.
        -            }
        -
        -        # If the line is not blank or a horizontal line...
        -        else
        -            {
        -            # More content means any previous blank lines are no longer tolerated in vertical line detection.  They are only
        -            # acceptable at the end of the comment.
        -
        -            if ($leftSide == IS_UNIFORM_IF_AT_END)
        -                {  $leftSide = IS_NOT_UNIFORM;  };
        -            if ($rightSide == IS_UNIFORM_IF_AT_END)
        -                {  $rightSide = IS_NOT_UNIFORM;  };
        -
        -
        -            # Detect vertical lines.  Lines are only lines if they are followed by whitespace or a connected horizontal line.
        -            # Otherwise we may accidentally detect lines from short comments that just happen to have every first or last
        -            # character the same.
        -
        -            if ($leftSide != IS_NOT_UNIFORM)
        -                {
        -                if ($line =~ /^([^a-zA-Z0-9])\1*(?: |$)/)
        -                    {
        -                    if ($leftSide == DONT_KNOW)
        -                        {
        -                        $leftSide = IS_UNIFORM;
        -                        $leftSideChar = $1;
        -                        }
        -                    else # ($leftSide == IS_UNIFORM)  Other choices already ruled out.
        -                        {
        -                        if ($leftSideChar ne $1)
        -                            {  $leftSide = IS_NOT_UNIFORM;  };
        -                        };
        -                    }
        -                # We'll tolerate the lack of symbols on the left on the first line, because it may be a
        -                # /* Function: Whatever
        -                #  * Description.
        -                #  */
        -                # comment which would have the leading /* blanked out.
        -                elsif ($index != 0)
        -                    {
        -                    $leftSide = IS_NOT_UNIFORM;
        -                    };
        -                };
        -
        -            if ($rightSide != IS_NOT_UNIFORM)
        -                {
        -                if ($line =~ / ([^a-zA-Z0-9])\1*$/)
        -                    {
        -                    if ($rightSide == DONT_KNOW)
        -                        {
        -                        $rightSide = IS_UNIFORM;
        -                        $rightSideChar = $1;
        -                        }
        -                    else # ($rightSide == IS_UNIFORM)  Other choices already ruled out.
        -                        {
        -                        if ($rightSideChar ne $1)
        -                            {  $rightSide = IS_NOT_UNIFORM;  };
        -                        };
        -                    }
        -                else
        -                    {
        -                    $rightSide = IS_NOT_UNIFORM;
        -                    };
        -                };
        -
        -            # We'll remove vertical lines later if they're uniform throughout the entire comment.
        -            };
        -
        -        $index++;
        -        };
        -
        -
        -    if ($leftSide == IS_UNIFORM_IF_AT_END)
        -        {  $leftSide = IS_UNIFORM;  };
        -    if ($rightSide == IS_UNIFORM_IF_AT_END)
        -        {  $rightSide = IS_UNIFORM;  };
        -
        -
        -    $index = 0;
        -    my $inCodeSection = 0;
        -
        -    while ($index < scalar @$commentLines)
        -        {
        -        # Clear horizontal lines only if we're not in a code section.
        -        if ($commentLines->[$index] =~ /^ *([^a-zA-Z0-9 ])\1{3,}$/ ||
        -            ( length $commentLines->[$index] < 256 &&
        -              $commentLines->[$index] =~ /^ *([^a-zA-Z0-9 ])\1*([^a-zA-Z0-9 ])\2{3,}([^a-zA-Z0-9 ])\3*$/ ) )
        -        	{
        -        	if (!$inCodeSection)
        -        		{  $commentLines->[$index] = '';  }
        -        	}
        -
        -        else
        -        	{
        -	        # Clear vertical lines.
        -
        -	        if ($leftSide == IS_UNIFORM)
        -	            {
        -	            # This works because every line should either start this way, be blank, or be the first line that doesn't start with a
        -	            # symbol.
        -	            $commentLines->[$index] =~ s/^ *([^a-zA-Z0-9 ])\1*//;
        -	            };
        -
        -	        if ($rightSide == IS_UNIFORM)
        -	            {
        -	            $commentLines->[$index] =~ s/ *([^a-zA-Z0-9 ])\1*$//;
        -	            };
        -
        -
        -	        # Clear horizontal lines again if there were vertical lines.  This catches lines that were separated from the verticals by
        -	        # whitespace.
        -
        -	        if (($leftSide == IS_UNIFORM || $rightSide == IS_UNIFORM) && !$inCodeSection)
        -	            {
        -	            $commentLines->[$index] =~ s/^ *([^a-zA-Z0-9 ])\1{3,}$//;
        -	            $commentLines->[$index] =~ s/^ *([^a-zA-Z0-9 ])\1*([^a-zA-Z0-9 ])\2{3,}([^a-zA-Z0-9 ])\3*$//;
        -	            };
        -
        -
        -	        # Check for the start and end of code sections.  Note that this doesn't affect vertical line removal.
        -
        -	        if (!$inCodeSection &&
        -	        	$commentLines->[$index] =~ /^ *\( *(?:(?:start|begin)? +)?(?:table|code|example|diagram) *\)$/i )
        -	        	{
        -	        	$inCodeSection = 1;
        -	        	}
        -	        elsif ($inCodeSection &&
        -	        	    $commentLines->[$index] =~ /^ *\( *(?:end|finish|done)(?: +(?:table|code|example|diagram))? *\)$/i)
        -	        	 {
        -	        	 $inCodeSection = 0;
        -	        	 }
        -	        }
        -
        -
        -        $index++;
        -        };
        -
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Processing Functions
        -
        -
        -#
        -#   Function: RepairPackages
        -#
        -#   Recalculates the packages for all comment topics using the auto-topics and the scope record.  Call this *before* calling
        -#   <MergeAutoTopics()>.
        -#
        -#   Parameters:
        -#
        -#       autoTopics - A reference to the list of automatically generated <NaturalDocs::Parser::ParsedTopics>.
        -#       scopeRecord - A reference to an array of <NaturalDocs::Languages::Advanced::ScopeChanges>.
        -#
        -sub RepairPackages #(autoTopics, scopeRecord)
        -    {
        -    my ($self, $autoTopics, $scopeRecord) = @_;
        -
        -    my $topicIndex = 0;
        -    my $autoTopicIndex = 0;
        -    my $scopeIndex = 0;
        -
        -    my $topic = $parsedFile[0];
        -    my $autoTopic = $autoTopics->[0];
        -    my $scopeChange = $scopeRecord->[0];
        -
        -    my $currentPackage;
        -    my $inFakePackage;
        -
        -    while (defined $topic)
        -        {
        -        # First update the scope via the record if its defined and has the lowest line number.
        -        if (defined $scopeChange &&
        -            $scopeChange->LineNumber() <= $topic->LineNumber() &&
        -            (!defined $autoTopic || $scopeChange->LineNumber() <= $autoTopic->LineNumber()) )
        -            {
        -            $currentPackage = $scopeChange->Scope();
        -            $scopeIndex++;
        -            $scopeChange = $scopeRecord->[$scopeIndex];  # Will be undef when past end.
        -            $inFakePackage = undef;
        -            }
        -
        -        # Next try to end a fake scope with an auto topic if its defined and has the lowest line number.
        -        elsif (defined $autoTopic &&
        -                $autoTopic->LineNumber() <= $topic->LineNumber())
        -            {
        -            if ($inFakePackage)
        -                {
        -                $currentPackage = $autoTopic->Package();
        -                $inFakePackage = undef;
        -                };
        -
        -            $autoTopicIndex++;
        -            $autoTopic = $autoTopics->[$autoTopicIndex];  # Will be undef when past end.
        -            }
        -
        -
        -        # Finally try to handle the topic, since it has the lowest line number.  Check for Type() because headerless topics won't have
        -        # one.
        -        else
        -            {
        -            my $scope;
        -            if ($topic->Type())
        -                {  $scope = NaturalDocs::Topics->TypeInfo($topic->Type())->Scope();  }
        -            else
        -                {  $scope = ::SCOPE_NORMAL();  };
        -
        -            if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -                {
        -                # They should already have the correct class and scope.
        -                $currentPackage = $topic->Package();
        -                $inFakePackage = 1;
        -                }
        -           else
        -                {
        -                # Fix the package of everything else.
        -
        -                # Note that the first function or variable topic to appear in a fake package will assume that package even if it turns out
        -                # to be incorrect in the actual code, since the topic will come before the auto-topic.  This will be corrected in
        -                # MergeAutoTopics().
        -
        -                $topic->SetPackage($currentPackage);
        -                };
        -
        -            $topicIndex++;
        -            $topic = $parsedFile[$topicIndex];  # Will be undef when past end.
        -            };
        -        };
        -
        -    };
        -
        -
        -#
        -#   Function: MergeAutoTopics
        -#
        -#   Merges the automatically generated topics into the file.  If an auto-topic matches an existing topic, it will have it's prototype
        -#   and package transferred.  If it doesn't, the auto-topic will be inserted into the list unless
        -#   <NaturalDocs::Settings->DocumentedOnly()> is set.  If an existing topic doesn't have a title, it's assumed to be a headerless
        -#   comment and will be merged with the next auto-topic or discarded.
        -#
        -#   Parameters:
        -#
        -#       language - The <NaturalDocs::Languages::Base>-derived class for the file.
        -#       autoTopics - A reference to the list of automatically generated topics.
        -#
        -sub MergeAutoTopics #(language, autoTopics)
        -    {
        -    my ($self, $language, $autoTopics) = @_;
        -
        -    my $topicIndex = 0;
        -    my $autoTopicIndex = 0;
        -
        -    # Keys are topic types, values are existence hashrefs of titles.
        -    my %topicsInLists;
        -
        -    while ($topicIndex < scalar @parsedFile && $autoTopicIndex < scalar @$autoTopics)
        -        {
        -        my $topic = $parsedFile[$topicIndex];
        -        my $autoTopic = $autoTopics->[$autoTopicIndex];
        -
        -        my $cleanTitle = $topic->Title();
        -        $cleanTitle =~ s/[\t ]*\([^\(]*$//;
        -
        -        # Add the auto-topic if it's higher in the file than the current topic.
        -        if ($autoTopic->LineNumber() < $topic->LineNumber())
        -            {
        -            if (exists $topicsInLists{$autoTopic->Type()} &&
        -                exists $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()})
        -                {
        -                # Remove it from the list so a second one with the same name will be added.
        -                delete $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()};
        -                }
        -            elsif (!NaturalDocs::Settings->DocumentedOnly())
        -                {
        -                splice(@parsedFile, $topicIndex, 0, $autoTopic);
        -                $topicIndex++;
        -                };
        -
        -            $autoTopicIndex++;
        -            }
        -
        -        # Remove a headerless topic if there's another topic between it and the next auto-topic.
        -        elsif (!$topic->Title() && $topicIndex + 1 < scalar @parsedFile &&
        -                $parsedFile[$topicIndex+1]->LineNumber() < $autoTopic->LineNumber())
        -            {
        -            splice(@parsedFile, $topicIndex, 1);
        -            }
        -
        -        # Transfer information if we have a match or a headerless topic.
        -        elsif ( !$topic->Title() ||
        -        		  $topic->Symbol() eq $autoTopic->Symbol() ||
        -        		  ( $topic->Type() == $autoTopic->Type() &&
        -        			( index($autoTopic->Title(), $cleanTitle) != -1 || index($cleanTitle, $autoTopic->Title()) != -1 ) ) )
        -            {
        -            $topic->SetType($autoTopic->Type());
        -            $topic->SetPrototype($autoTopic->Prototype());
        -            $topic->SetUsing($autoTopic->Using());
        -
        -            if (!$topic->Title())
        -                {  $topic->SetTitle($autoTopic->Title());  };
        -
        -            if (NaturalDocs::Topics->TypeInfo($topic->Type())->Scope() != ::SCOPE_START())
        -                {  $topic->SetPackage($autoTopic->Package());  }
        -            elsif ($autoTopic->Package() ne $topic->Package())
        -                {
        -                my @autoPackageIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($autoTopic->Package());
        -                my @packageIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($topic->Package());
        -
        -                while (scalar @autoPackageIdentifiers && $autoPackageIdentifiers[-1] eq $packageIdentifiers[-1])
        -                    {
        -                    pop @autoPackageIdentifiers;
        -                    pop @packageIdentifiers;
        -                    };
        -
        -                if (scalar @autoPackageIdentifiers)
        -                    {  $topic->SetPackage( NaturalDocs::SymbolString->Join(@autoPackageIdentifiers) );  };
        -                };
        -
        -            $topicIndex++;
        -            $autoTopicIndex++;
        -            }
        -
        -        # Extract topics in lists.
        -        elsif ($topic->IsList())
        -            {
        -            if (!exists $topicsInLists{$topic->Type()})
        -                {  $topicsInLists{$topic->Type()} = { };  };
        -
        -            my $body = $topic->Body();
        -
        -            while ($body =~ /<ds>([^<]+)<\/ds>/g)
        -                {  $topicsInLists{$topic->Type()}->{NaturalDocs::NDMarkup->RestoreAmpChars($1)} = 1;  };
        -
        -            $topicIndex++;
        -            }
        -
        -        # Otherwise there's no match.  Skip the topic.  The auto-topic will be added later.
        -        else
        -            {
        -            $topicIndex++;
        -            }
        -        };
        -
        -    # Add any auto-topics remaining.
        -    if (!NaturalDocs::Settings->DocumentedOnly())
        -    	{
        -	    while ($autoTopicIndex < scalar @$autoTopics)
        -	        {
        -	        my $autoTopic = $autoTopics->[$autoTopicIndex];
        -
        -	        if (exists $topicsInLists{$autoTopic->Type()} &&
        -	            exists $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()})
        -	            {
        -	            # Remove it from the list so a second one with the same name will be added.
        -	            delete $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()};
        -	            }
        -	        else
        -	            {
        -	            push(@parsedFile, $autoTopic);
        -	            };
        -
        -	        $autoTopicIndex++;
        -	        };
        -        };
        -   };
        -
        -
        -#
        -#   Function: RemoveRemainingHeaderlessTopics
        -#
        -#   After <MergeAutoTopics()> is done, this function removes any remaining headerless topics from the file.  If they don't merge
        -#   into anything, they're not valid topics.
        -#
        -sub RemoveRemainingHeaderlessTopics
        -    {
        -    my ($self) = @_;
        -
        -    my $index = 0;
        -    while ($index < scalar @parsedFile)
        -        {
        -        if ($parsedFile[$index]->Title())
        -            {  $index++;  }
        -        else
        -            {  splice(@parsedFile, $index, 1);  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: MakeAutoGroups
        -#
        -#   Creates group topics for files that do not have them.
        -#
        -sub MakeAutoGroups
        -    {
        -    my ($self) = @_;
        -
        -    # No groups only one topic.
        -    if (scalar @parsedFile < 2)
        -        {  return;  };
        -
        -    my $index = 0;
        -    my $startStretch = 0;
        -
        -    # Skip the first entry if its the page title.
        -    if (NaturalDocs::Topics->TypeInfo( $parsedFile[0]->Type() )->PageTitleIfFirst())
        -        {
        -        $index = 1;
        -        $startStretch = 1;
        -        };
        -
        -    # Make auto-groups for each stretch between scope-altering topics.
        -    while ($index < scalar @parsedFile)
        -        {
        -        my $scope = NaturalDocs::Topics->TypeInfo($parsedFile[$index]->Type())->Scope();
        -
        -        if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -            {
        -            if ($index > $startStretch)
        -                {  $index += $self->MakeAutoGroupsFor($startStretch, $index);  };
        -
        -            $startStretch = $index + 1;
        -            };
        -
        -        $index++;
        -        };
        -
        -    if ($index > $startStretch)
        -        {  $self->MakeAutoGroupsFor($startStretch, $index);  };
        -    };
        -
        -
        -#
        -#   Function: MakeAutoGroupsFor
        -#
        -#   Creates group topics for sections of files that do not have them.  A support function for <MakeAutoGroups()>.
        -#
        -#   Parameters:
        -#
        -#       startIndex - The index to start at.
        -#       endIndex - The index to end at.  Not inclusive.
        -#
        -#   Returns:
        -#
        -#       The number of group topics added.
        -#
        -sub MakeAutoGroupsFor #(startIndex, endIndex)
        -    {
        -    my ($self, $startIndex, $endIndex) = @_;
        -
        -    # No groups if any are defined already.
        -    for (my $i = $startIndex; $i < $endIndex; $i++)
        -        {
        -        if ($parsedFile[$i]->Type() eq ::TOPIC_GROUP())
        -            {  return 0;  };
        -        };
        -
        -
        -    use constant COUNT => 0;
        -    use constant TYPE => 1;
        -    use constant SECOND_TYPE => 2;
        -    use constant SIZE => 3;
        -
        -    # This is an array of ( count, type, secondType ) triples.  Count and Type will always be filled in; count is the number of
        -    # consecutive topics of type.  On the second pass, if small groups are combined secondType will be filled in.  There will not be
        -    # more than two types per group.
        -    my @groups;
        -    my $groupIndex = 0;
        -
        -
        -    # First pass: Determine all the groups.
        -
        -    my $i = $startIndex;
        -    my $currentType;
        -
        -    while ($i < $endIndex)
        -        {
        -        if (!defined $currentType || ($parsedFile[$i]->Type() ne $currentType && $parsedFile[$i]->Type() ne ::TOPIC_GENERIC()) )
        -            {
        -            if (defined $currentType)
        -                {  $groupIndex += SIZE;  };
        -
        -            $currentType = $parsedFile[$i]->Type();
        -
        -            $groups[$groupIndex + COUNT] = 1;
        -            $groups[$groupIndex + TYPE] = $currentType;
        -            }
        -        else
        -            {  $groups[$groupIndex + COUNT]++;  };
        -
        -        $i++;
        -        };
        -
        -
        -    # Second pass: Combine groups based on "noise".  Noise means types go from A to B to A at least once, and there are at least
        -    # two groups in a row with three or less, and at least one of those groups is two or less.  So 3, 3, 3 doesn't count as noise, but
        -    # 3, 2, 3 does.
        -
        -    $groupIndex = 0;
        -
        -    # While there are at least three groups left...
        -    while ($groupIndex < scalar @groups - (2 * SIZE))
        -        {
        -        # If the group two places in front of this one has the same type...
        -        if ($groups[$groupIndex + (2 * SIZE) + TYPE] eq $groups[$groupIndex + TYPE])
        -            {
        -            # It means we went from A to B to A, which partially qualifies as noise.
        -
        -            my $firstType = $groups[$groupIndex + TYPE];
        -            my $secondType = $groups[$groupIndex + SIZE + TYPE];
        -
        -            if (NaturalDocs::Topics->TypeInfo($firstType)->CanGroupWith($secondType) ||
        -                NaturalDocs::Topics->TypeInfo($secondType)->CanGroupWith($firstType))
        -                {
        -                my $hasNoise;
        -
        -                my $hasThrees;
        -                my $hasTwosOrOnes;
        -
        -                my $endIndex = $groupIndex;
        -
        -                while ($endIndex < scalar @groups &&
        -                         ($groups[$endIndex + TYPE] eq $firstType || $groups[$endIndex + TYPE] eq $secondType))
        -                    {
        -                    if ($groups[$endIndex + COUNT] > 3)
        -                        {
        -                        # They must be consecutive to count.
        -                        $hasThrees = 0;
        -                        $hasTwosOrOnes = 0;
        -                        }
        -                    elsif ($groups[$endIndex + COUNT] == 3)
        -                        {
        -                        $hasThrees = 1;
        -
        -                        if ($hasTwosOrOnes)
        -                            {  $hasNoise = 1;  };
        -                        }
        -                    else # < 3
        -                        {
        -                        if ($hasThrees || $hasTwosOrOnes)
        -                            {  $hasNoise = 1;  };
        -
        -                        $hasTwosOrOnes = 1;
        -                        };
        -
        -                    $endIndex += SIZE;
        -                    };
        -
        -                if (!$hasNoise)
        -                    {
        -                    $groupIndex = $endIndex - SIZE;
        -                    }
        -                else # hasNoise
        -                    {
        -                    $groups[$groupIndex + SECOND_TYPE] = $secondType;
        -
        -                    for (my $noiseIndex = $groupIndex + SIZE; $noiseIndex < $endIndex; $noiseIndex += SIZE)
        -                        {
        -                        $groups[$groupIndex + COUNT] += $groups[$noiseIndex + COUNT];
        -                        };
        -
        -                    splice(@groups, $groupIndex + SIZE, $endIndex - $groupIndex - SIZE);
        -
        -                    $groupIndex += SIZE;
        -                    };
        -                }
        -
        -            else # They can't group together
        -                {
        -                $groupIndex += SIZE;
        -                };
        -            }
        -
        -        else
        -            {  $groupIndex += SIZE;  };
        -        };
        -
        -
        -    # Finally, create group topics for the parsed file.
        -
        -    $groupIndex = 0;
        -    $i = $startIndex;
        -
        -    while ($groupIndex < scalar @groups)
        -        {
        -        if ($groups[$groupIndex + TYPE] ne ::TOPIC_GENERIC())
        -            {
        -            my $topic = $parsedFile[$i];
        -            my $title = NaturalDocs::Topics->NameOfType($groups[$groupIndex + TYPE], 1);
        -
        -            if (defined $groups[$groupIndex + SECOND_TYPE])
        -                {  $title .= ' and ' . NaturalDocs::Topics->NameOfType($groups[$groupIndex + SECOND_TYPE], 1);  };
        -
        -            splice(@parsedFile, $i, 0, NaturalDocs::Parser::ParsedTopic->New(::TOPIC_GROUP(),
        -                                                                                                            $title,
        -                                                                                                            $topic->Package(), $topic->Using(),
        -                                                                                                            undef, undef, undef,
        -                                                                                                            $topic->LineNumber()) );
        -            $i++;
        -            };
        -
        -        $i += $groups[$groupIndex + COUNT];
        -        $groupIndex += SIZE;
        -        };
        -
        -    return (scalar @groups / SIZE);
        -    };
        -
        -
        -#
        -#   Function: AddToClassHierarchy
        -#
        -#   Adds any class topics to the class hierarchy, since they may not have been called with <OnClass()> if they didn't match up to
        -#   an auto-topic.
        -#
        -sub AddToClassHierarchy
        -    {
        -    my ($self) = @_;
        -
        -    foreach my $topic (@parsedFile)
        -        {
        -        if ($topic->Type() && NaturalDocs::Topics->TypeInfo( $topic->Type() )->ClassHierarchy())
        -            {
        -            if ($topic->IsList())
        -                {
        -                my $body = $topic->Body();
        -
        -                while ($body =~ /<ds>([^<]+)<\/ds>/g)
        -                    {
        -                    $self->OnClass( NaturalDocs::SymbolString->FromText( NaturalDocs::NDMarkup->RestoreAmpChars($1) ) );
        -                    };
        -                }
        -            else
        -                {
        -                $self->OnClass($topic->Package());
        -                };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: AddPackageDelineators
        -#
        -#   Adds section and class topics to make sure the package is correctly represented in the documentation.  Should be called last in
        -#   this process.
        -#
        -sub AddPackageDelineators
        -    {
        -    my ($self) = @_;
        -
        -    my $index = 0;
        -    my $currentPackage;
        -
        -    # Values are the arrayref [ title, type ];
        -    my %usedPackages;
        -
        -    while ($index < scalar @parsedFile)
        -        {
        -        my $topic = $parsedFile[$index];
        -
        -        if ($topic->Package() ne $currentPackage)
        -            {
        -            $currentPackage = $topic->Package();
        -            my $scopeType = NaturalDocs::Topics->TypeInfo($topic->Type())->Scope();
        -
        -            if ($scopeType == ::SCOPE_START())
        -                {
        -                $usedPackages{$currentPackage} = [ $topic->Title(), $topic->Type() ];
        -                }
        -            elsif ($scopeType == ::SCOPE_END())
        -                {
        -                my $newTopic;
        -
        -                if (!defined $currentPackage)
        -                    {
        -                    $newTopic = NaturalDocs::Parser::ParsedTopic->New(::TOPIC_SECTION(), 'Global',
        -                                                                                                   undef, undef,
        -                                                                                                   undef, undef, undef,
        -                                                                                                   $topic->LineNumber(), undef);
        -                    }
        -                else
        -                    {
        -                    my ($title, $body, $summary, $type);
        -                    my @packageIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($currentPackage);
        -
        -                    if (exists $usedPackages{$currentPackage})
        -                        {
        -                        $title = $usedPackages{$currentPackage}->[0];
        -                        $type = $usedPackages{$currentPackage}->[1];
        -                        $body = '<p>(continued)</p>';
        -                        $summary = '(continued)';
        -                        }
        -                    else
        -                        {
        -                        $title = join($language->PackageSeparator(), @packageIdentifiers);
        -                        $type = ::TOPIC_CLASS();
        -
        -                        # Body and summary stay undef.
        -
        -                        $usedPackages{$currentPackage} = $title;
        -                        };
        -
        -                    my @titleIdentifiers = NaturalDocs::SymbolString->IdentifiersOf( NaturalDocs::SymbolString->FromText($title) );
        -                    for (my $i = 0; $i < scalar @titleIdentifiers; $i++)
        -                        {  pop @packageIdentifiers;  };
        -
        -                    $newTopic = NaturalDocs::Parser::ParsedTopic->New($type, $title,
        -                                                                                                   NaturalDocs::SymbolString->Join(@packageIdentifiers), undef,
        -                                                                                                   undef, $summary, $body,
        -                                                                                                   $topic->LineNumber(), undef);
        -                    }
        -
        -                splice(@parsedFile, $index, 0, $newTopic);
        -                $index++;
        -                }
        -            };
        -
        -        $index++;
        -        };
        -    };
        -
        -
        -#
        -#   Function: BreakLists
        -#
        -#   Breaks list topics into individual topics.
        -#
        -sub BreakLists
        -    {
        -    my $self = shift;
        -
        -    my $index = 0;
        -
        -    while ($index < scalar @parsedFile)
        -        {
        -        my $topic = $parsedFile[$index];
        -
        -        if ($topic->IsList() && NaturalDocs::Topics->TypeInfo( $topic->Type() )->BreakLists())
        -            {
        -            my $body = $topic->Body();
        -
        -            my @newTopics;
        -            my $newBody;
        -
        -            my $bodyIndex = 0;
        -
        -            for (;;)
        -                {
        -                my $startList = index($body, '<dl>', $bodyIndex);
        -
        -                if ($startList == -1)
        -                    {  last;  };
        -
        -                $newBody .= substr($body, $bodyIndex, $startList - $bodyIndex);
        -
        -                my $endList = index($body, '</dl>', $startList);
        -                my $listBody = substr($body, $startList, $endList - $startList);
        -
        -                while ($listBody =~ /<ds>([^<]+)<\/ds><dd>(.*?)<\/dd>/g)
        -                    {
        -                    my ($symbol, $description) = ($1, $2);
        -
        -                    push @newTopics, NaturalDocs::Parser::ParsedTopic->New( $topic->Type(), $symbol, $topic->Package(),
        -                                                                                                            $topic->Using(), undef,
        -                                                                                                            $self->GetSummaryFromDescriptionList($description),
        -                                                                                                            '<p>' . $description .  '</p>', $topic->LineNumber(),
        -                                                                                                            undef );
        -                    };
        -
        -                $bodyIndex = $endList + 5;
        -                };
        -
        -            $newBody .= substr($body, $bodyIndex);
        -
        -            # Remove trailing headings.
        -            $newBody =~ s/(?:<h>[^<]+<\/h>)+$//;
        -
        -            # Remove empty headings.
        -            $newBody =~ s/(?:<h>[^<]+<\/h>)+(<h>[^<]+<\/h>)/$1/g;
        -
        -            if ($newBody)
        -                {
        -                unshift @newTopics, NaturalDocs::Parser::ParsedTopic->New( ::TOPIC_GROUP(), $topic->Title(), $topic->Package(),
        -                                                                                                          $topic->Using(), undef,
        -                                                                                                          $self->GetSummaryFromBody($newBody), $newBody,
        -                                                                                                          $topic->LineNumber(), undef );
        -                };
        -
        -            splice(@parsedFile, $index, 1, @newTopics);
        -
        -            $index += scalar @newTopics;
        -            }
        -
        -        else # not a list
        -            {  $index++;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: GetSummaryFromBody
        -#
        -#   Returns the summary text from the topic body.
        -#
        -#   Parameters:
        -#
        -#       body - The complete topic body, in <NDMarkup>.
        -#
        -#   Returns:
        -#
        -#       The topic summary, or undef if none.
        -#
        -sub GetSummaryFromBody #(body)
        -    {
        -    my ($self, $body) = @_;
        -
        -    my $summary;
        -
        -    # Extract the first sentence from the leading paragraph, if any.  We'll tolerate a single header beforehand, but nothing else.
        -
        -    if ($body =~ /^(?:<h>[^<]*<\/h>)?<p>(.*?)(<\/p>|[\.\!\?](?:[\)\}\'\ ]|&quot;|&gt;))/x)
        -        {
        -        $summary = $1;
        -
        -        if ($2 ne '</p>')
        -            {  $summary .= $2;  };
        -        };
        -
        -    return $summary;
        -    };
        -
        -
        -#
        -#   Function: GetSummaryFromDescriptionList
        -#
        -#   Returns the summary text from a description list entry.
        -#
        -#   Parameters:
        -#
        -#       description - The description in <NDMarkup>.  Should be the content between the <dd></dd> tags only.
        -#
        -#   Returns:
        -#
        -#       The description summary, or undef if none.
        -#
        -sub GetSummaryFromDescriptionList #(description)
        -    {
        -    my ($self, $description) = @_;
        -
        -    my $summary;
        -
        -    if ($description =~ /^(.*?)($|[\.\!\?](?:[\)\}\'\ ]|&quot;|&gt;))/)
        -        {  $summary = $1 . $2;  };
        -
        -    return $summary;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Parser/JavaDoc.pm b/vendor/naturaldocs/Modules/NaturalDocs/Parser/JavaDoc.pm
        deleted file mode 100644
        index 0e8bd4bd0..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Parser/JavaDoc.pm
        +++ /dev/null
        @@ -1,465 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Parser::JavaDoc
        -#
        -###############################################################################
        -#
        -#   A package for translating JavaDoc topics into Natural Docs.
        -#
        -#   Supported tags:
        -#
        -#       - @param
        -#       - @author
        -#       - @deprecated
        -#       - @code, @literal (doesn't change font)
        -#       - @exception, @throws (doesn't link to class)
        -#       - @link, @linkplain (doesn't change font)
        -#       - @return, @returns
        -#       - @see
        -#       - @since
        -#       - @value (shown as link instead of replacement)
        -#       - @version
        -#
        -#   Stripped tags:
        -#
        -#       - @inheritDoc
        -#       - @serial, @serialField, @serialData
        -#       - All other block level tags.
        -#
        -#   Unsupported tags:
        -#
        -#       These will appear literally in the output because I cannot handle them easily.
        -#
        -#       - @docRoot
        -#       - Any other tags not mentioned
        -#
        -#   Supported HTML:
        -#
        -#       - p
        -#       - b, i, u
        -#       - pre
        -#       - a href
        -#       - ol, ul, li (ol gets converted to ul)
        -#       - gt, lt, amp, quot, nbsp entities
        -#
        -#   Stripped HTML:
        -#
        -#       - code
        -#       - HTML comments
        -#
        -#   Unsupported HTML:
        -#
        -#       These will appear literally in the output because I cannot handle them easily.
        -#
        -#       - Any tags with additional properties other than a href.  (ex. <p class=Something>)
        -#       - Any other tags not mentioned
        -#
        -#   Reference:
        -#
        -#       http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Parser::JavaDoc;
        -
        -
        -#
        -#   hash: blockTags
        -#   An existence hash of the all-lowercase JavaDoc block tags, not including the @.
        -#
        -my %blockTags = ( 'param' => 1, 'author' => 1, 'deprecated' => 1, 'exception' => 1, 'return' => 1, 'see' => 1,
        -                             'serial' => 1, 'serialfield' => 1, 'serialdata' => 1, 'since' => 1, 'throws' => 1, 'version' => 1,
        -                             'returns' => 1 );
        -
        -#
        -#   hash: inlineTags
        -#   An existence hash of the all-lowercase JavaDoc inline tags, not including the @.
        -#
        -my %inlineTags = ( 'inheritdoc' => 1, 'docroot' => 1, 'code' => 1, 'literal' => 1, 'link' => 1, 'linkplain' => 1, 'value' => 1 );
        -
        -
        -##
        -#   Examines the comment and returns whether it is *definitely* JavaDoc content, i.e. is owned by this package.
        -#
        -#   Parameters:
        -#
        -#       commentLines - An arrayref of the comment lines.  Must have been run through <NaturalDocs::Parser->CleanComment()>.
        -#       isJavaDoc - Whether the comment is JavaDoc styled.  This doesn't necessarily mean it has JavaDoc content.
        -#
        -#   Returns:
        -#
        -#       Whether the comment is *definitely* JavaDoc content.
        -#
        -sub IsMine #(string[] commentLines, bool isJavaDoc)
        -    {
        -    my ($self, $commentLines, $isJavaDoc) = @_;
        -
        -    if (!$isJavaDoc)
        -        {  return undef;  };
        -
        -    for (my $line = 0; $line < scalar @$commentLines; $line++)
        -        {
        -        if ($commentLines->[$line] =~ /^ *@([a-z]+) /i && exists $blockTags{$1} ||
        -            $commentLines->[$line] =~ /\{@([a-z]+) /i && exists $inlineTags{$1})
        -            {
        -            return 1;
        -            };
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -##
        -#   Parses the JavaDoc-syntax comment and adds it to the parsed topic list.
        -#
        -#   Parameters:
        -#
        -#       commentLines - An arrayref of the comment lines.  Must have been run through <NaturalDocs::Parser->CleanComment()>.
        -#                               *The original memory will be changed.*
        -#       isJavaDoc - Whether the comment is JavaDoc styled.  This doesn't necessarily mean it has JavaDoc content.
        -#       lineNumber - The line number of the first of the comment lines.
        -#       parsedTopics - A reference to the array where any new <NaturalDocs::Parser::ParsedTopics> should be placed.
        -#
        -#   Returns:
        -#
        -#       The number of parsed topics added to the array, which in this case will always be one.
        -#
        -sub ParseComment #(string[] commentLines, bool isJavaDoc, int lineNumber, ParsedTopics[]* parsedTopics)
        -    {
        -    my ($self, $commentLines, $isJavaDoc, $lineNumber, $parsedTopics) = @_;
        -
        -
        -    # Stage one: Before block level tags.
        -
        -    my $i = 0;
        -    my $output;
        -    my $unformattedText;
        -    my $inCode;
        -    my $sharedCodeIndent;
        -
        -    while ($i < scalar @$commentLines &&
        -              !($commentLines->[$i] =~ /^ *@([a-z]+) /i && exists $blockTags{$1}) )
        -        {
        -        my $line = $self->ConvertAmpChars($commentLines->[$i]);
        -        my @tokens = split(/(&lt;\/?pre&gt;)/, $line);
        -
        -        foreach my $token (@tokens)
        -            {
        -            if ($token =~ /^&lt;pre&gt;$/i)
        -                {
        -                if (!$inCode && $unformattedText)
        -                    {
        -                    $output .= '<p>' . $self->FormatText($unformattedText, 1) . '</p>';
        -                    };
        -
        -                $inCode = 1;
        -                $unformattedText = undef;
        -                }
        -            elsif ($token =~ /^&lt;\/pre&gt;$/i)
        -                {
        -                if ($inCode && $unformattedText)
        -                    {
        -                    $unformattedText =~ s/^ {$sharedCodeIndent}//mg;
        -                    $unformattedText =~ s/\n{3,}/\n\n/g;
        -                    $unformattedText =~ s/\n+$//;
        -                    $output .= '<code type="anonymous">' . $unformattedText . '</code>';
        -
        -                    $sharedCodeIndent = undef;
        -                    };
        -
        -                $inCode = 0;
        -                $unformattedText = undef;
        -                }
        -            elsif (length($token))
        -                {
        -                if (!$inCode)
        -                    {
        -                    $token =~ s/^ +//;
        -                    if ($unformattedText)
        -                        {  $unformattedText .= ' ';  };
        -                    }
        -                else
        -                    {
        -                    $token =~ /^( *)/;
        -                    my $indent = length($1);
        -
        -                    if (!defined $sharedCodeIndent || $indent < $sharedCodeIndent)
        -                        {  $sharedCodeIndent = $indent;  };
        -                    };
        -
        -                $unformattedText .= $token;
        -                };
        -            };
        -
        -        if ($inCode && $unformattedText)
        -            {  $unformattedText .= "\n";  };
        -
        -        $i++;
        -        };
        -
        -    if ($unformattedText)
        -        {
        -        if ($inCode)
        -            {
        -            $unformattedText =~ s/^ {$sharedCodeIndent}//mg;
        -            $unformattedText =~ s/\n{3,}/\n\n/g;
        -            $unformattedText =~ s/\n+$//;
        -            $output .= '<code type="anonymous">' . $unformattedText . '</code>';
        -            }
        -        else
        -            {  $output .= '<p>' . $self->FormatText($unformattedText, 1) . '</p>';  };
        -
        -        $unformattedText = undef;
        -        };
        -
        -
        -    # Stage two: Block level tags.
        -
        -    my ($keyword, $value, $unformattedTextPtr, $unformattedTextCloser);
        -    my ($params, $authors, $deprecation, $throws, $returns, $seeAlso, $since, $version);
        -
        -
        -    while ($i < scalar @$commentLines)
        -        {
        -        my $line = $self->ConvertAmpChars($commentLines->[$i]);
        -        $line =~ s/^ +//;
        -
        -        if ($line =~ /^@([a-z]+) ?(.*)$/i)
        -            {
        -            ($keyword, $value) = (lc($1), $2);
        -
        -            # Process the previous one, if any.
        -            if ($unformattedText)
        -                {
        -                $$unformattedTextPtr .= $self->FormatText($unformattedText) . $unformattedTextCloser;
        -                $unformattedText = undef;
        -                };
        -
        -            if ($keyword eq 'param')
        -                {
        -                $value =~ /^([a-z0-9_]+) *(.*)$/i;
        -
        -                $params .= '<de>' . $1 . '</de><dd>';
        -                $unformattedText = $2;
        -
        -                $unformattedTextPtr = \$params;
        -                $unformattedTextCloser = '</dd>';
        -                }
        -            elsif ($keyword eq 'exception' || $keyword eq 'throws')
        -                {
        -                $value =~ /^([a-z0-9_]+) *(.*)$/i;
        -
        -                $throws .= '<de>' . $1 . '</de><dd>';
        -                $unformattedText = $2;
        -
        -                $unformattedTextPtr = \$throws;
        -                $unformattedTextCloser = '</dd>';
        -                }
        -            elsif ($keyword eq 'return' || $keyword eq 'returns')
        -                {
        -                if ($returns)
        -                    {  $returns .= ' ';  };
        -
        -                $unformattedText = $value;
        -                $unformattedTextPtr = \$returns;
        -                $unformattedTextCloser = undef;
        -                }
        -            elsif ($keyword eq 'author')
        -                {
        -                if ($authors)
        -                    {  $authors .= ', ';  };
        -
        -                $unformattedText = $value;
        -                $unformattedTextPtr = \$authors;
        -                $unformattedTextCloser = undef;
        -                }
        -            elsif ($keyword eq 'deprecated')
        -                {
        -                if ($deprecation)
        -                    {  $deprecation .= ' ';  };
        -
        -                $unformattedText = $value;
        -                $unformattedTextPtr = \$deprecation;
        -                $unformattedTextCloser = undef;
        -                }
        -            elsif ($keyword eq 'since')
        -                {
        -                if ($since)
        -                    {  $since .= ', ';  };
        -
        -                $unformattedText = $value;
        -                $unformattedTextPtr = \$since;
        -                $unformattedTextCloser = undef;
        -                }
        -            elsif ($keyword eq 'version')
        -                {
        -                if ($version)
        -                    {  $version .= ', ';  };
        -
        -                $unformattedText = $value;
        -                $unformattedTextPtr = \$version;
        -                $unformattedTextCloser = undef;
        -                }
        -            elsif ($keyword eq 'see')
        -                {
        -                if ($seeAlso)
        -                    {  $seeAlso .= ', ';  };
        -
        -                $unformattedText = undef;
        -
        -                if ($value =~ /^&(?:quot|lt);/i)
        -                    {  $seeAlso .= $self->FormatText($value);  }
        -                else
        -                    {  $seeAlso .= $self->ConvertLink($value);  };
        -                };
        -
        -            # Everything else will be skipped.
        -            }
        -        elsif ($unformattedText)
        -            {
        -            $unformattedText .= ' ' . $line;
        -            };
        -
        -        $i++;
        -        };
        -
        -    if ($unformattedText)
        -        {
        -        $$unformattedTextPtr .= $self->FormatText($unformattedText) . $unformattedTextCloser;
        -        $unformattedText = undef;
        -        };
        -
        -    if ($params)
        -        {  $output .= '<h>Parameters</h><dl>' . $params . '</dl>';  };
        -    if ($returns)
        -        {  $output .= '<h>Returns</h><p>' . $returns . '</p>';  };
        -    if ($throws)
        -        {  $output .= '<h>Throws</h><dl>' . $throws . '</dl>';  };
        -    if ($since)
        -        {  $output .= '<h>Since</h><p>' . $since . '</p>';  };
        -    if ($version)
        -        {  $output .= '<h>Version</h><p>' . $version . '</p>';  };
        -    if ($deprecation)
        -        {  $output .= '<h>Deprecated</h><p>' . $deprecation . '</p>';  };
        -    if ($authors)
        -        {  $output .= '<h>Author</h><p>' . $authors . '</p>';  };
        -    if ($seeAlso)
        -        {  $output .= '<h>See Also</h><p>' . $seeAlso . '</p>';  };
        -
        -
        -    # Stage three: Build the parsed topic.
        -
        -    my $summary = NaturalDocs::Parser->GetSummaryFromBody($output);
        -
        -    push @$parsedTopics, NaturalDocs::Parser::ParsedTopic->New(undef, undef, undef, undef, undef, $summary,
        -                                                                                                $output, $lineNumber, undef);
        -    return 1;
        -    };
        -
        -
        -##
        -#   Translates any inline tags or HTML codes to <NDMarkup> and returns it.
        -#
        -sub FormatText #(string text, bool inParagraph)
        -    {
        -    my ($self, $text, $inParagraph) = @_;
        -
        -    # JavaDoc Literal
        -
        -    $text =~ s/\{\@(?:code|literal) ([^\}]*)\}/$self->ConvertAmpChars($1)/gie;
        -
        -
        -    # HTML
        -
        -    $text =~ s/&lt;b&gt;(.*?)&lt;\/b&gt;/<b>$1<\/b>/gi;
        -    $text =~ s/&lt;i&gt;(.*?)&lt;\/i&gt;/<i>$1<\/i>/gi;
        -    $text =~ s/&lt;u&gt;(.*?)&lt;\/u&gt;/<u>$1<\/u>/gi;
        -
        -    $text =~ s/&lt;code&gt;(.*?)&lt;\/code&gt;/$1/gi;
        -
        -    $text =~ s/&lt;ul.*?&gt;(.*?)&lt;\/ul&gt;/<ul>$1<\/ul>/gi;
        -    $text =~ s/&lt;ol.*?&gt;(.*?)&lt;\/ol&gt;/<ul>$1<\/ul>/gi;
        -    $text =~ s/&lt;li.*?&gt;(.*?)&lt;\/li&gt;/<li>$1<\/li>/gi;
        -
        -    $text =~ s/&lt;!--.*?--&gt;//gi;
        -
        -    $text =~ s/&lt;\/p&gt;//gi;
        -    $text =~ s/^&lt;p&gt;//i;
        -    if ($inParagraph)
        -        {  $text =~ s/&lt;p&gt;/<\/p><p>/gi;  }
        -    else
        -        {  $text =~ s/&lt;p&gt;//gi;  };
        -
        -    $text =~ s/&lt;a href=&quot;mailto:(.*?)&quot;.*?&gt;(.*?)&lt;\/a&gt;/$self->MakeEMailLink($1, $2)/gie;
        -    $text =~ s/&lt;a href=&quot;(.*?)&quot;.*?&gt;(.*?)&lt;\/a&gt;/$self->MakeURLLink($1, $2)/gie;
        -
        -    $text =~ s/&amp;nbsp;/ /gi;
        -    $text =~ s/&amp;amp;/&amp;/gi;
        -    $text =~ s/&amp;gt;/&gt;/gi;
        -    $text =~ s/&amp;lt;/&lt;/gi;
        -    $text =~ s/&amp;quot;/&quot;/gi;
        -
        -
        -
        -    # JavaDoc
        -
        -    $text =~ s/\{\@inheritdoc\}//gi;
        -    $text =~ s/\{\@(?:linkplain|link|value) ([^\}]*)\}/$self->ConvertLink($1)/gie;
        -
        -    return $text;
        -    };
        -
        -
        -sub ConvertAmpChars #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ s/&/&amp;/g;
        -    $text =~ s/</&lt;/g;
        -    $text =~ s/>/&gt;/g;
        -    $text =~ s/"/&quot;/g;
        -
        -    return $text;
        -    };
        -
        -sub ConvertLink #(text)
        -    {
        -    my ($self, $text) = @_;
        -
        -    $text =~ /^ *([a-z0-9\_\.\:\#]+(?:\([^\)]*\))?) *(.*)$/i;
        -    my ($target, $label) = ($1, $2);
        -
        -    # Convert the anchor to part of the link, but remove it altogether if it's the beginning of the link.
        -    $target =~ s/^\#//;
        -    $target =~ s/\#/\./;
        -
        -    $label =~ s/ +$//;
        -
        -    if (!length $label)
        -        {  return '<link target="' . $target . '" name="' . $target . '" original="' . $target . '">';  }
        -    else
        -        {  return '<link target="' . $target . '" name="' . $label . '" original="' . $label . ' (' . $target . ')">';  };
        -    };
        -
        -sub MakeURLLink #(target, text)
        -    {
        -    my ($self, $target, $text) = @_;
        -    return '<url target="' . $target . '" name="' . $text . '">';
        -    };
        -
        -sub MakeEMailLink #(target, text)
        -    {
        -    my ($self, $target, $text) = @_;
        -    return '<email target="' . $target . '" name="' . $text . '">';
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Parser/Native.pm b/vendor/naturaldocs/Modules/NaturalDocs/Parser/Native.pm
        deleted file mode 100644
        index 39d8663b0..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Parser/Native.pm
        +++ /dev/null
        @@ -1,1073 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Parser::Native
        -#
        -###############################################################################
        -#
        -#   A package that converts comments from Natural Docs' native format into <NaturalDocs::Parser::ParsedTopic> objects.
        -#   Unlike most second-level packages, these are packages and not object classes.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Parser::Native;
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -# Return values of TagType().  Not documented here.
        -use constant POSSIBLE_OPENING_TAG => 1;
        -use constant POSSIBLE_CLOSING_TAG => 2;
        -use constant NOT_A_TAG => 3;
        -
        -
        -#
        -#   var: package
        -#
        -#   A <SymbolString> representing the package normal topics will be a part of at the current point in the file.  This is a package variable
        -#   because it needs to be reserved between function calls.
        -#
        -my $package;
        -
        -#
        -#   hash: functionListIgnoredHeadings
        -#
        -#   An existence hash of all the headings that prevent the parser from creating function list symbols.  Whenever one of
        -#   these headings are used in a function list topic, symbols are not created from definition lists until the next heading.  The keys
        -#   are in all lowercase.
        -#
        -my %functionListIgnoredHeadings = ( 'parameters' => 1,
        -                                                       'parameter' => 1,
        -                                                       'params' => 1,
        -                                                       'param' => 1,
        -                                                       'arguments' => 1,
        -                                                       'argument' => 1,
        -                                                       'args' => 1,
        -                                                       'arg' => 1 );
        -
        -
        -###############################################################################
        -# Group: Interface Functions
        -
        -
        -#
        -#   Function: Start
        -#
        -#   This will be called whenever a file is about to be parsed.  It allows the package to reset its internal state.
        -#
        -sub Start
        -    {
        -    my ($self) = @_;
        -    $package = undef;
        -    };
        -
        -
        -#
        -#   Function: IsMine
        -#
        -#   Examines the comment and returns whether it is *definitely* Natural Docs content, i.e. it is owned by this package.  Note
        -#   that a comment can fail this function and still be interpreted as a Natural Docs content, for example a JavaDoc-styled comment
        -#   that doesn't have header lines but no JavaDoc tags either.
        -#
        -#   Parameters:
        -#
        -#       commentLines - An arrayref of the comment lines.  Must have been run through <NaturalDocs::Parser->CleanComment()>.
        -#       isJavaDoc - Whether the comment was JavaDoc-styled.
        -#
        -#   Returns:
        -#
        -#       Whether the comment is *definitely* Natural Docs content.
        -#
        -sub IsMine #(string[] commentLines, bool isJavaDoc)
        -    {
        -    my ($self, $commentLines, $isJavaDoc) = @_;
        -
        -    # Skip to the first line with content.
        -    my $line = 0;
        -
        -    while ($line < scalar @$commentLines && !length $commentLines->[$line])
        -        {  $line++;  };
        -
        -    return $self->ParseHeaderLine($commentLines->[$line]);
        -    };
        -
        -
        -
        -#
        -#   Function: ParseComment
        -#
        -#   This will be called whenever a comment capable of containing Natural Docs content is found.
        -#
        -#   Parameters:
        -#
        -#       commentLines - An arrayref of the comment lines.  Must have been run through <NaturalDocs::Parser->CleanComment()>.
        -#                               *The original memory will be changed.*
        -#       isJavaDoc - Whether the comment is JavaDoc styled.
        -#       lineNumber - The line number of the first of the comment lines.
        -#       parsedTopics - A reference to the array where any new <NaturalDocs::Parser::ParsedTopics> should be placed.
        -#
        -#   Returns:
        -#
        -#       The number of parsed topics added to the array, or zero if none.
        -#
        -sub ParseComment #(commentLines, isJavaDoc, lineNumber, parsedTopics)
        -    {
        -    my ($self, $commentLines, $isJavaDoc, $lineNumber, $parsedTopics) = @_;
        -
        -    my $topicCount = 0;
        -    my $prevLineBlank = 1;
        -    my $inCodeSection = 0;
        -
        -    my ($type, $scope, $isPlural, $title, $symbol);
        -    #my $package;  # package variable.
        -    my ($newKeyword, $newTitle);
        -
        -    my $index = 0;
        -
        -    my $bodyStart = 0;
        -    my $bodyEnd = 0;  # Not inclusive.
        -
        -    while ($index < scalar @$commentLines)
        -        {
        -        # Everything but leading whitespace was removed beforehand.
        -
        -        # If we're in a code section...
        -        if ($inCodeSection)
        -            {
        -            if ($commentLines->[$index] =~ /^ *\( *(?:end|finish|done)(?: +(?:table|code|example|diagram))? *\)$/i)
        -                {  $inCodeSection = undef;  };
        -
        -            $prevLineBlank = 0;
        -            $bodyEnd++;
        -            }
        -
        -        # If the line is empty...
        -        elsif (!length($commentLines->[$index]))
        -            {
        -            $prevLineBlank = 1;
        -
        -            if ($topicCount)
        -                {  $bodyEnd++;  };
        -            }
        -
        -        # If the line has a recognized header and the previous line is blank...
        -        elsif ($prevLineBlank && (($newKeyword, $newTitle) = $self->ParseHeaderLine($commentLines->[$index])) )
        -            {
        -            # Process the previous one, if any.
        -
        -            if ($topicCount)
        -                {
        -                if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -                    {  $package = undef;  };
        -
        -                my $body = $self->FormatBody($commentLines, $bodyStart, $bodyEnd, $type, $isPlural);
        -                my $newTopic = $self->MakeParsedTopic($type, $title, $package, $body, $lineNumber + $bodyStart - 1, $isPlural);
        -                push @$parsedTopics, $newTopic;
        -
        -                $package = $newTopic->Package();
        -                };
        -
        -            $title = $newTitle;
        -
        -            my $typeInfo;
        -            ($type, $typeInfo, $isPlural) = NaturalDocs::Topics->KeywordInfo($newKeyword);
        -            $scope = $typeInfo->Scope();
        -
        -            $bodyStart = $index + 1;
        -            $bodyEnd = $index + 1;
        -
        -            $topicCount++;
        -
        -            $prevLineBlank = 0;
        -            }
        -
        -        # If we're on a non-empty, non-header line of a JavaDoc-styled comment and we haven't started a topic yet...
        -        elsif ($isJavaDoc && !$topicCount)
        -            {
        -            $type = undef;
        -            $scope = ::SCOPE_NORMAL();  # The scope repair and topic merging processes will handle if this is a class topic.
        -            $isPlural = undef;
        -            $title = undef;
        -            $symbol = undef;
        -
        -            $bodyStart = $index;
        -            $bodyEnd = $index + 1;
        -
        -            $topicCount++;
        -
        -            $prevLineBlank = undef;
        -            }
        -
        -        # If we're on a normal content line within a topic
        -        elsif ($topicCount)
        -            {
        -            $prevLineBlank = 0;
        -            $bodyEnd++;
        -
        -            if ($commentLines->[$index] =~ /^ *\( *(?:(?:start|begin)? +)?(?:table|code|example|diagram) *\)$/i)
        -                {  $inCodeSection = 1;  };
        -            };
        -
        -
        -        $index++;
        -        };
        -
        -
        -    # Last one, if any.  This is the only one that gets the prototypes.
        -    if ($topicCount)
        -        {
        -        if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
        -            {  $package = undef;  };
        -
        -        my $body = $self->FormatBody($commentLines, $bodyStart, $bodyEnd, $type, $isPlural);
        -        my $newTopic = $self->MakeParsedTopic($type, $title, $package, $body, $lineNumber + $bodyStart - 1, $isPlural);
        -        push @$parsedTopics, $newTopic;
        -        $topicCount++;
        -
        -        $package = $newTopic->Package();
        -        };
        -
        -    return $topicCount;
        -    };
        -
        -
        -#
        -#   Function: ParseHeaderLine
        -#
        -#   If the passed line is a topic header, returns the array ( keyword, title ).  Otherwise returns an empty array.
        -#
        -sub ParseHeaderLine #(line)
        -    {
        -    my ($self, $line) = @_;
        -
        -    if ($line =~ /^ *([a-z0-9 ]*[a-z0-9]): +(.*)$/i)
        -        {
        -        my ($keyword, $title) = ($1, $2);
        -
        -        # We need to do it this way because if you do "if (ND:T->KeywordInfo($keyword)" and the last element of the array it
        -        # returns is false, the statement is false.  That is really retarded, but there it is.
        -        my ($type, undef, undef) = NaturalDocs::Topics->KeywordInfo($keyword);
        -
        -        if ($type)
        -            {  return ($keyword, $title);  }
        -        else
        -            {  return ( );  };
        -        }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: MakeParsedTopic
        -#
        -#   Creates a <NaturalDocs::Parser::ParsedTopic> object for the passed parameters.  Scope is gotten from
        -#   the package variable <package> instead of from the parameters.  The summary is generated from the body.
        -#
        -#   Parameters:
        -#
        -#       type         - The <TopicType>.  May be undef for headerless topics.
        -#       title          - The title of the topic.  May be undef for headerless topics.
        -#       package    - The package <SymbolString> the topic appears in.
        -#       body        - The topic's body in <NDMarkup>.
        -#       lineNumber - The topic's line number.
        -#       isList         - Whether the topic is a list.
        -#
        -#   Returns:
        -#
        -#       The <NaturalDocs::Parser::ParsedTopic> object.
        -#
        -sub MakeParsedTopic #(type, title, package, body, lineNumber, isList)
        -    {
        -    my ($self, $type, $title, $package, $body, $lineNumber, $isList) = @_;
        -
        -    my $summary;
        -
        -    if (defined $body)
        -        {  $summary = NaturalDocs::Parser->GetSummaryFromBody($body);  };
        -
        -    return NaturalDocs::Parser::ParsedTopic->New($type, $title, $package, undef, undef, $summary,
        -                                                                         $body, $lineNumber, $isList);
        -    };
        -
        -
        -#
        -#    Function: FormatBody
        -#
        -#    Converts the section body to <NDMarkup>.
        -#
        -#    Parameters:
        -#
        -#       commentLines - The arrayref of comment lines.
        -#       startingIndex  - The starting index of the body to format.
        -#       endingIndex   - The ending index of the body to format, *not* inclusive.
        -#       type               - The type of the section.  May be undef for headerless comments.
        -#       isList              - Whether it's a list topic.
        -#
        -#    Returns:
        -#
        -#        The body formatted in <NDMarkup>.
        -#
        -sub FormatBody #(commentLines, startingIndex, endingIndex, type, isList)
        -    {
        -    my ($self, $commentLines, $startingIndex, $endingIndex, $type, $isList) = @_;
        -
        -    use constant TAG_NONE => 1;
        -    use constant TAG_PARAGRAPH => 2;
        -    use constant TAG_BULLETLIST => 3;
        -    use constant TAG_DESCRIPTIONLIST => 4;
        -    use constant TAG_HEADING => 5;
        -    use constant TAG_PREFIXCODE => 6;
        -    use constant TAG_TAGCODE => 7;
        -
        -    my %tagEnders = ( TAG_NONE() => '',
        -                                 TAG_PARAGRAPH() => '</p>',
        -                                 TAG_BULLETLIST() => '</li></ul>',
        -                                 TAG_DESCRIPTIONLIST() => '</dd></dl>',
        -                                 TAG_HEADING() => '</h>',
        -                                 TAG_PREFIXCODE() => '</code>',
        -                                 TAG_TAGCODE() => '</code>' );
        -
        -    my $topLevelTag = TAG_NONE;
        -
        -    my $output;
        -    my $textBlock;
        -    my $prevLineBlank = 1;
        -
        -    my $codeBlock;
        -    my $removedCodeSpaces;
        -
        -    my $ignoreListSymbols;
        -
        -    my $index = $startingIndex;
        -
        -    while ($index < $endingIndex)
        -        {
        -        # If we're in a tagged code section...
        -        if ($topLevelTag == TAG_TAGCODE)
        -            {
        -            if ($commentLines->[$index] =~ /^ *\( *(?:end|finish|done)(?: +(?:table|code|example|diagram))? *\)$/i)
        -                {
        -                $codeBlock =~ s/\n+$//;
        -                $output .= NaturalDocs::NDMarkup->ConvertAmpChars($codeBlock) . '</code>';
        -                $codeBlock = undef;
        -                $topLevelTag = TAG_NONE;
        -                $prevLineBlank = undef;
        -                }
        -            else
        -                {
        -                $self->AddToCodeBlock($commentLines->[$index], \$codeBlock, \$removedCodeSpaces);
        -                };
        -            }
        -
        -        # If the line starts with a code designator...
        -        elsif ($commentLines->[$index] =~ /^ *[>:|](.*)$/)
        -            {
        -            my $code = $1;
        -
        -            if ($topLevelTag == TAG_PREFIXCODE)
        -                {
        -                $self->AddToCodeBlock($code, \$codeBlock, \$removedCodeSpaces);
        -                }
        -            else # $topLevelTag != TAG_PREFIXCODE
        -                {
        -                if (defined $textBlock)
        -                    {
        -                    $output .= $self->RichFormatTextBlock($textBlock) . $tagEnders{$topLevelTag};
        -                    $textBlock = undef;
        -                    };
        -
        -                $topLevelTag = TAG_PREFIXCODE;
        -                $output .= '<code type="anonymous">';
        -                $self->AddToCodeBlock($code, \$codeBlock, \$removedCodeSpaces);
        -                };
        -            }
        -
        -        # If we're not in either code style...
        -        else
        -            {
        -            # Strip any leading whitespace.
        -            $commentLines->[$index] =~ s/^ +//;
        -
        -            # If we were in a prefixed code section...
        -            if ($topLevelTag == TAG_PREFIXCODE)
        -                {
        -                $codeBlock =~ s/\n+$//;
        -                $output .= NaturalDocs::NDMarkup->ConvertAmpChars($codeBlock) . '</code>';
        -                $codeBlock = undef;
        -                $topLevelTag = TAG_NONE;
        -                $prevLineBlank = undef;
        -                };
        -
        -
        -            # If the line is blank...
        -            if (!length($commentLines->[$index]))
        -                {
        -                # End a paragraph.  Everything else ignores it for now.
        -                if ($topLevelTag == TAG_PARAGRAPH)
        -                    {
        -                    $output .= $self->RichFormatTextBlock($textBlock) . '</p>';
        -                    $textBlock = undef;
        -                    $topLevelTag = TAG_NONE;
        -                    };
        -
        -                $prevLineBlank = 1;
        -                }
        -
        -            # If the line starts with a bullet...
        -            elsif ($commentLines->[$index] =~ /^[-\*o+] +([^ ].*)$/ &&
        -                    substr($1, 0, 2) ne '- ')  # Make sure "o - Something" is a definition, not a bullet.
        -                {
        -                my $bulletedText = $1;
        -
        -                if (defined $textBlock)
        -                    {  $output .= $self->RichFormatTextBlock($textBlock);  };
        -
        -                if ($topLevelTag == TAG_BULLETLIST)
        -                    {
        -                    $output .= '</li><li>';
        -                    }
        -                else #($topLevelTag != TAG_BULLETLIST)
        -                    {
        -                    $output .= $tagEnders{$topLevelTag} . '<ul><li>';
        -                    $topLevelTag = TAG_BULLETLIST;
        -                    };
        -
        -                $textBlock = $bulletedText;
        -
        -                $prevLineBlank = undef;
        -                }
        -
        -            # If the line looks like a description list entry...
        -            elsif ($commentLines->[$index] =~ /^(.+?) +- +([^ ].*)$/ && $topLevelTag != TAG_PARAGRAPH)
        -                {
        -                my $entry = $1;
        -                my $description = $2;
        -
        -                if (defined $textBlock)
        -                    {  $output .= $self->RichFormatTextBlock($textBlock);  };
        -
        -                if ($topLevelTag == TAG_DESCRIPTIONLIST)
        -                    {
        -                    $output .= '</dd>';
        -                    }
        -                else #($topLevelTag != TAG_DESCRIPTIONLIST)
        -                    {
        -                    $output .= $tagEnders{$topLevelTag} . '<dl>';
        -                    $topLevelTag = TAG_DESCRIPTIONLIST;
        -                    };
        -
        -                if (($isList && !$ignoreListSymbols) || $type eq ::TOPIC_ENUMERATION())
        -                    {
        -                    $output .= '<ds>' . NaturalDocs::NDMarkup->ConvertAmpChars($entry) . '</ds><dd>';
        -                    }
        -                else
        -                    {
        -                    $output .= '<de>' . NaturalDocs::NDMarkup->ConvertAmpChars($entry) . '</de><dd>';
        -                    };
        -
        -                $textBlock = $description;
        -
        -                $prevLineBlank = undef;
        -                }
        -
        -            # If the line could be a header...
        -            elsif ($prevLineBlank && $commentLines->[$index] =~ /^(.*)([^ ]):$/)
        -                {
        -                my $headerText = $1 . $2;
        -
        -                if (defined $textBlock)
        -                    {
        -                    $output .= $self->RichFormatTextBlock($textBlock);
        -                    $textBlock = undef;
        -                    }
        -
        -                $output .= $tagEnders{$topLevelTag};
        -                $topLevelTag = TAG_NONE;
        -
        -                $output .= '<h>' . $self->RichFormatTextBlock($headerText) . '</h>';
        -
        -                if ($type eq ::TOPIC_FUNCTION() && $isList)
        -                    {
        -                    $ignoreListSymbols = exists $functionListIgnoredHeadings{lc($headerText)};
        -                    };
        -
        -                $prevLineBlank = undef;
        -                }
        -
        -            # If the line looks like a code tag...
        -            elsif ($commentLines->[$index] =~ /^\( *(?:(?:start|begin)? +)?(table|code|example|diagram) *\)$/i)
        -                {
        -				my $codeType = lc($1);
        -
        -                if (defined $textBlock)
        -                    {
        -                    $output .= $self->RichFormatTextBlock($textBlock);
        -                    $textBlock = undef;
        -                    };
        -
        -                if ($codeType eq 'example')
        -                	{  $codeType = 'anonymous';  }
        -                elsif ($codeType eq 'table' || $codeType eq 'diagram')
        -                	{  $codeType = 'text';  }
        -                # else leave it 'code'
        -
        -                $output .= $tagEnders{$topLevelTag} . '<code type="' . $codeType . '">';
        -                $topLevelTag = TAG_TAGCODE;
        -                }
        -
        -            # If the line looks like an inline image...
        -            elsif ($commentLines->[$index] =~ /^(\( *see +)([^\)]+?)( *\))$/i)
        -                {
        -                if (defined $textBlock)
        -                    {
        -                    $output .= $self->RichFormatTextBlock($textBlock);
        -                    $textBlock = undef;
        -                    };
        -
        -                $output .= $tagEnders{$topLevelTag};
        -                $topLevelTag = TAG_NONE;
        -
        -                $output .= '<img mode="inline" target="' . NaturalDocs::NDMarkup->ConvertAmpChars($2) . '" '
        -                                . 'original="' . NaturalDocs::NDMarkup->ConvertAmpChars($1 . $2 . $3) . '">';
        -
        -                $prevLineBlank = undef;
        -                }
        -
        -            # If the line isn't any of those, we consider it normal text.
        -            else
        -                {
        -                # A blank line followed by normal text ends lists.  We don't handle this when we detect if the line's blank because
        -                # we don't want blank lines between list items to break the list.
        -                if ($prevLineBlank && ($topLevelTag == TAG_BULLETLIST || $topLevelTag == TAG_DESCRIPTIONLIST))
        -                    {
        -                    $output .= $self->RichFormatTextBlock($textBlock) . $tagEnders{$topLevelTag} . '<p>';
        -
        -                    $topLevelTag = TAG_PARAGRAPH;
        -                    $textBlock = undef;
        -                    }
        -
        -                elsif ($topLevelTag == TAG_NONE)
        -                    {
        -                    $output .= '<p>';
        -                    $topLevelTag = TAG_PARAGRAPH;
        -                    # textBlock will already be undef.
        -                    };
        -
        -                if (defined $textBlock)
        -                    {  $textBlock .= ' ';  };
        -
        -                $textBlock .= $commentLines->[$index];
        -
        -                $prevLineBlank = undef;
        -                };
        -            };
        -
        -        $index++;
        -        };
        -
        -    # Clean up anything left dangling.
        -    if (defined $textBlock)
        -        {
        -        $output .= $self->RichFormatTextBlock($textBlock) . $tagEnders{$topLevelTag};
        -        }
        -    elsif (defined $codeBlock)
        -        {
        -        $codeBlock =~ s/\n+$//;
        -        $output .= NaturalDocs::NDMarkup->ConvertAmpChars($codeBlock) . '</code>';
        -        };
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: AddToCodeBlock
        -#
        -#   Adds a line of text to a code block, handling all the indentation processing required.
        -#
        -#   Parameters:
        -#
        -#       line - The line of text to add.
        -#       codeBlockRef - A reference to the code block to add it to.
        -#       removedSpacesRef - A reference to a variable to hold the number of spaces removed.  It needs to be stored between calls.
        -#                                      It will reset itself automatically when the code block codeBlockRef points to is undef.
        -#
        -sub AddToCodeBlock #(line, codeBlockRef, removedSpacesRef)
        -    {
        -    my ($self, $line, $codeBlockRef, $removedSpacesRef) = @_;
        -
        -    $line =~ /^( *)(.*)$/;
        -    my ($spaces, $code) = ($1, $2);
        -
        -    if (!defined $$codeBlockRef)
        -        {
        -        if (length($code))
        -            {
        -            $$codeBlockRef = $code . "\n";
        -            $$removedSpacesRef = length($spaces);
        -            };
        -        # else ignore leading line breaks.
        -        }
        -
        -    elsif (length $code)
        -        {
        -        # Make sure we have the minimum amount of spaces to the left possible.
        -        if (length($spaces) != $$removedSpacesRef)
        -            {
        -            my $spaceDifference = abs( length($spaces) - $$removedSpacesRef );
        -            my $spacesToAdd = ' ' x $spaceDifference;
        -
        -            if (length($spaces) > $$removedSpacesRef)
        -                {
        -                $$codeBlockRef .= $spacesToAdd;
        -                }
        -            else
        -                {
        -                $$codeBlockRef =~ s/^(.)/$spacesToAdd . $1/gme;
        -                $$removedSpacesRef = length($spaces);
        -                };
        -            };
        -
        -        $$codeBlockRef .= $code . "\n";
        -        }
        -
        -    else # (!length $code)
        -        {
        -        $$codeBlockRef .= "\n";
        -        };
        -    };
        -
        -
        -#
        -#   Function: RichFormatTextBlock
        -#
        -#   Applies rich <NDMarkup> formatting to a chunk of text.  This includes both amp chars, formatting tags, and link tags.
        -#
        -#   Parameters:
        -#
        -#       text - The block of text to format.
        -#
        -#   Returns:
        -#
        -#       The formatted text block.
        -#
        -sub RichFormatTextBlock #(text)
        -    {
        -    my ($self, $text) = @_;
        -    my $output;
        -
        -
        -    # First find bare urls, e-mail addresses, and images.  We have to do this before the split because they may contain underscores
        -    # or asterisks.  We have to mark the tags with \x1E and \x1F so they don't get confused with angle brackets from the comment.
        -    # We can't convert the amp chars beforehand because we need lookbehinds in the regexps below and they need to be
        -    # constant length.  Sucks, huh?
        -
        -    $text =~ s{
        -                       # The previous character can't be an alphanumeric or an opening angle bracket.
        -                       (?<!  [a-z0-9<]  )
        -
        -                       # Optional mailto:.  Ignored in output.
        -                       (?:mailto\:)?
        -
        -                       # Begin capture
        -                       (
        -
        -                       # The user portion.  Alphanumeric and - _.  Dots can appear between, but not at the edges or more than
        -                       # one in a row.
        -                       (?:  [a-z0-9\-_]+  \.  )*   [a-z0-9\-_]+
        -
        -                       @
        -
        -                       # The domain.  Alphanumeric and -.  Dots same as above, however, there must be at least two sections
        -                       # and the last one must be two to four alphanumeric characters (.com, .uk, .info, .203 for IP addresses)
        -                       (?:  [a-z0-9\-]+  \.  )+  [a-z]{2,4}
        -
        -                       # End capture.
        -                       )
        -
        -                       # The next character can't be an alphanumeric, which should prevent .abcde from matching the two to
        -                       # four character requirement, or a closing angle bracket.
        -                       (?!  [a-z0-9>]  )
        -
        -                       }
        -
        -                       {"\x1E" . 'email target="' . NaturalDocs::NDMarkup->ConvertAmpChars($1) . '" '
        -                       . 'name="' . NaturalDocs::NDMarkup->ConvertAmpChars($1) . '"' . "\x1F"}igxe;
        -
        -    $text =~ s{
        -                       # The previous character can't be an alphanumeric or an opening angle bracket.
        -                       (?<!  [a-z0-9<]  )
        -
        -                       # Begin capture.
        -                       (
        -
        -                       # URL must start with one of the acceptable protocols.
        -                       (?:http|https|ftp|news|file)\:
        -
        -                       # The acceptable URL characters as far as I know.
        -                       [a-z0-9\-\=\~\@\#\%\&\_\+\/\;\:\?\*\.\,]*
        -
        -                       # The URL characters minus period and comma.  If it ends on them, they're probably intended as
        -                       # punctuation.
        -                       [a-z0-9\-\=\~\@\#\%\&\_\+\/\;\:\?\*]
        -
        -                       # End capture.
        -                       )
        -
        -                       # The next character must not be an acceptable character or a closing angle bracket.  It must also not be a
        -					   # dot and then an acceptable character.  These will prevent the URL from ending early just to get a match.
        -                       (?!  \.?[a-z0-9\-\=\~\@\#\%\&\_\+\/\;\:\?\*\>]  )
        -
        -                       }
        -
        -                       {"\x1E" . 'url target="' . NaturalDocs::NDMarkup->ConvertAmpChars($1) . '" '
        -                       . 'name="' . NaturalDocs::NDMarkup->ConvertAmpChars($1) . '"' . "\x1F"}igxe;
        -
        -
        -    # Find image links.  Inline images should already be pulled out by now.
        -
        -    $text =~ s{(\( *see +)([^\)\<\>]+?)( *\))}
        -                      {"\x1E" . 'img mode="link" target="' . NaturalDocs::NDMarkup->ConvertAmpChars($2) . '" '
        -                        . 'original="' . NaturalDocs::NDMarkup->ConvertAmpChars($1 . $2 . $3) . '"' . "\x1F"}gie;
        -
        -
        -
        -    # Split the text from the potential tags.
        -
        -    my @tempTextBlocks = split(/([\*_<>\x1E\x1F])/, $text);
        -
        -    # Since the symbols are considered dividers, empty strings could appear between two in a row or at the beginning/end of the
        -    # array.  This could seriously screw up TagType(), so we need to get rid of them.
        -    my @textBlocks;
        -
        -    while (scalar @tempTextBlocks)
        -        {
        -        my $tempTextBlock = shift @tempTextBlocks;
        -
        -        if (length $tempTextBlock)
        -            {  push @textBlocks, $tempTextBlock;  };
        -        };
        -
        -
        -    my $bold;
        -    my $underline;
        -    my $underlineHasWhitespace;
        -
        -    my $index = 0;
        -
        -    while ($index < scalar @textBlocks)
        -        {
        -        if ($textBlocks[$index] eq "\x1E")
        -            {
        -            $output .= '<';
        -            $index++;
        -
        -            while ($textBlocks[$index] ne "\x1F")
        -                {
        -                $output .= $textBlocks[$index];
        -                $index++;
        -                };
        -
        -            $output .= '>';
        -            }
        -
        -        elsif ($textBlocks[$index] eq '<' && $self->TagType(\@textBlocks, $index) == POSSIBLE_OPENING_TAG)
        -            {
        -            my $endingIndex = $self->ClosingTag(\@textBlocks, $index, undef);
        -
        -            if ($endingIndex != -1)
        -                {
        -                my $linkText;
        -                $index++;
        -
        -                while ($index < $endingIndex)
        -                    {
        -                    $linkText .= $textBlocks[$index];
        -                    $index++;
        -                    };
        -                # Index will be incremented again at the end of the loop.
        -
        -                $linkText = NaturalDocs::NDMarkup->ConvertAmpChars($linkText);
        -
        -                if ($linkText =~ /^(?:mailto\:)?((?:[a-z0-9\-_]+\.)*[a-z0-9\-_]+@(?:[a-z0-9\-]+\.)+[a-z]{2,4})$/i)
        -                    {  $output .= '<email target="' . $1 . '" name="' . $1 . '">';  }
        -                elsif ($linkText =~ /^(.+?) at (?:mailto\:)?((?:[a-z0-9\-_]+\.)*[a-z0-9\-_]+@(?:[a-z0-9\-]+\.)+[a-z]{2,4})$/i)
        -                    {  $output .= '<email target="' . $2 . '" name="' . $1 . '">';  }
        -                elsif ($linkText =~ /^(?:http|https|ftp|news|file)\:/i)
        -                    {  $output .= '<url target="' . $linkText . '" name="' . $linkText . '">';  }
        -                elsif ($linkText =~ /^(.+?) at ((?:http|https|ftp|news|file)\:.+)/i)
        -                    {  $output .= '<url target="' . $2 . '" name="' . $1 . '">';  }
        -                else
        -                    {  $output .= '<link target="' . $linkText . '" name="' . $linkText . '" original="&lt;' . $linkText . '&gt;">';  };
        -                }
        -
        -            else # it's not a link.
        -                {
        -                $output .= '&lt;';
        -                };
        -            }
        -
        -        elsif ($textBlocks[$index] eq '*')
        -            {
        -            my $tagType = $self->TagType(\@textBlocks, $index);
        -
        -            if ($tagType == POSSIBLE_OPENING_TAG && $self->ClosingTag(\@textBlocks, $index, undef) != -1)
        -                {
        -                # ClosingTag() makes sure tags aren't opened multiple times in a row.
        -                $bold = 1;
        -                $output .= '<b>';
        -                }
        -            elsif ($bold && $tagType == POSSIBLE_CLOSING_TAG)
        -                {
        -                $bold = undef;
        -                $output .= '</b>';
        -                }
        -            else
        -                {
        -                $output .= '*';
        -                };
        -            }
        -
        -        elsif ($textBlocks[$index] eq '_')
        -            {
        -            my $tagType = $self->TagType(\@textBlocks, $index);
        -
        -             if ($tagType == POSSIBLE_OPENING_TAG && $self->ClosingTag(\@textBlocks, $index, \$underlineHasWhitespace) != -1)
        -                {
        -                # ClosingTag() makes sure tags aren't opened multiple times in a row.
        -                $underline = 1;
        -                #underlineHasWhitespace is set by ClosingTag().
        -                $output .= '<u>';
        -                }
        -            elsif ($underline && $tagType == POSSIBLE_CLOSING_TAG)
        -                {
        -                $underline = undef;
        -                #underlineHasWhitespace will be reset by the next opening underline.
        -                $output .= '</u>';
        -                }
        -            elsif ($underline && !$underlineHasWhitespace)
        -                {
        -                # If there's no whitespace between underline tags, all underscores are replaced by spaces so
        -                # _some_underlined_text_ becomes <u>some underlined text</u>.  The standard _some underlined text_
        -                # will work too.
        -                $output .= ' ';
        -                }
        -            else
        -                {
        -                $output .= '_';
        -                };
        -            }
        -
        -        else # plain text or a > that isn't part of a link
        -            {
        -            $output .= NaturalDocs::NDMarkup->ConvertAmpChars($textBlocks[$index]);
        -           };
        -
        -        $index++;
        -        };
        -
        -    return $output;
        -    };
        -
        -
        -#
        -#   Function: TagType
        -#
        -#   Returns whether the tag is a possible opening or closing tag, or neither.  "Possible" because it doesn't check if an opening tag is
        -#   closed or a closing tag is opened, just whether the surrounding characters allow it to be a candidate for a tag.  For example, in
        -#   "A _B" the underscore is a possible opening underline tag, but in "A_B" it is not.  Support function for <RichFormatTextBlock()>.
        -#
        -#   Parameters:
        -#
        -#       textBlocks  - A reference to an array of text blocks.
        -#       index         - The index of the tag.
        -#
        -#   Returns:
        -#
        -#       POSSIBLE_OPENING_TAG, POSSIBLE_CLOSING_TAG, or NOT_A_TAG.
        -#
        -sub TagType #(textBlocks, index)
        -    {
        -    my ($self, $textBlocks, $index) = @_;
        -
        -
        -    # Possible opening tags
        -
        -    if ( ( $textBlocks->[$index] =~ /^[\*_<]$/ ) &&
        -
        -        # Before it must be whitespace, the beginning of the text, or ({["'-/*_.
        -        ( $index == 0 || $textBlocks->[$index-1] =~ /[\ \t\n\(\{\[\"\'\-\/\*\_]$/ ) &&
        -
        -        # Notes for 2.0: Include Spanish upside down ! and ? as well as opening quotes (66) and apostrophes (6).  Look into
        -        # Unicode character classes as well.
        -
        -        # After it must be non-whitespace.
        -        ( $index + 1 < scalar @$textBlocks && $textBlocks->[$index+1] !~ /^[\ \t\n]/) &&
        -
        -        # Make sure we don't accept <<, <=, <-, or *= as opening tags.
        -        ( $textBlocks->[$index] ne '<' || $textBlocks->[$index+1] !~ /^[<=-]/ ) &&
        -        ( $textBlocks->[$index] ne '*' || $textBlocks->[$index+1] !~ /^[\=\*]/ ) &&
        -
        -        # Make sure we don't accept * or _ before it unless it's <.
        -        ( $textBlocks->[$index] eq '<' || $index == 0 || $textBlocks->[$index-1] !~ /[\*\_]$/) )
        -        {
        -        return POSSIBLE_OPENING_TAG;
        -        }
        -
        -
        -    # Possible closing tags
        -
        -    elsif ( ( $textBlocks->[$index] =~ /^[\*_>]$/) &&
        -
        -            # After it must be whitespace, the end of the text, or )}].,!?"';:-/*_.
        -            ( $index + 1 == scalar @$textBlocks || $textBlocks->[$index+1] =~ /^[ \t\n\)\]\}\.\,\!\?\"\'\;\:\-\/\*\_]/ ||
        -              # Links also get plurals, like <link>s, <linx>es, <link>'s, and <links>'.
        -              ( $textBlocks->[$index] eq '>' && $textBlocks->[$index+1] =~ /^(?:es|s|\')/ ) ) &&
        -
        -            # Notes for 2.0: Include closing quotes (99) and apostrophes (9).  Look into Unicode character classes as well.
        -
        -            # Before it must be non-whitespace.
        -            ( $index != 0 && $textBlocks->[$index-1] !~ /[ \t\n]$/ ) &&
        -
        -            # Make sure we don't accept >>, ->, or => as closing tags.  >= is already taken care of.
        -            ( $textBlocks->[$index] ne '>' || $textBlocks->[$index-1] !~ /[>=-]$/ ) &&
        -
        -            # Make sure we don't accept * or _ after it unless it's >.
        -            ( $textBlocks->[$index] eq '>' || $textBlocks->[$index+1] !~ /[\*\_]$/) )
        -        {
        -        return POSSIBLE_CLOSING_TAG;
        -        }
        -
        -    else
        -        {
        -        return NOT_A_TAG;
        -        };
        -
        -    };
        -
        -
        -#
        -#   Function: ClosingTag
        -#
        -#   Returns whether a tag is closed or not, where it's closed if it is, and optionally whether there is any whitespace between the
        -#   tags.  Support function for <RichFormatTextBlock()>.
        -#
        -#   The results of this function are in full context, meaning that if it says a tag is closed, it can be interpreted as that tag in the
        -#   final output.  It takes into account any spoiling factors, like there being two opening tags in a row.
        -#
        -#   Parameters:
        -#
        -#       textBlocks             - A reference to an array of text blocks.
        -#       index                    - The index of the opening tag.
        -#       hasWhitespaceRef  - A reference to the variable that will hold whether there is whitespace between the tags or not.  If
        -#                                     undef, the function will not check.  If the tag is not closed, the variable will not be changed.
        -#
        -#   Returns:
        -#
        -#       If the tag is closed, it returns the index of the closing tag and puts whether there was whitespace between the tags in
        -#       hasWhitespaceRef if it was specified.  If the tag is not closed, it returns -1 and doesn't touch the variable pointed to by
        -#       hasWhitespaceRef.
        -#
        -sub ClosingTag #(textBlocks, index, hasWhitespace)
        -    {
        -    my ($self, $textBlocks, $index, $hasWhitespaceRef) = @_;
        -
        -    my $hasWhitespace;
        -    my $closingTag;
        -
        -    if ($textBlocks->[$index] eq '*' || $textBlocks->[$index] eq '_')
        -        {  $closingTag = $textBlocks->[$index];  }
        -    elsif ($textBlocks->[$index] eq '<')
        -        {  $closingTag = '>';  }
        -    else
        -        {  return -1;  };
        -
        -    my $beginningIndex = $index;
        -    $index++;
        -
        -    while ($index < scalar @$textBlocks)
        -        {
        -        if ($textBlocks->[$index] eq '<' && $self->TagType($textBlocks, $index) == POSSIBLE_OPENING_TAG)
        -            {
        -            # If we hit a < and we're checking whether a link is closed, it's not.  The first < becomes literal and the second one
        -            # becomes the new link opening.
        -            if ($closingTag eq '>')
        -                {
        -                return -1;
        -                }
        -
        -            # If we're not searching for the end of a link, we have to skip the link because formatting tags cannot appear within
        -            # them.  That's of course provided it's closed.
        -            else
        -                {
        -                my $linkHasWhitespace;
        -
        -                my $endIndex = $self->ClosingTag($textBlocks, $index,
        -                                                                    ($hasWhitespaceRef && !$hasWhitespace ? \$linkHasWhitespace : undef) );
        -
        -                if ($endIndex != -1)
        -                    {
        -                    if ($linkHasWhitespace)
        -                        {  $hasWhitespace = 1;  };
        -
        -                    # index will be incremented again at the end of the loop, which will bring us past the link's >.
        -                    $index = $endIndex;
        -                    };
        -                };
        -            }
        -
        -        elsif ($textBlocks->[$index] eq $closingTag)
        -            {
        -            my $tagType = $self->TagType($textBlocks, $index);
        -
        -            if ($tagType == POSSIBLE_CLOSING_TAG)
        -                {
        -                # There needs to be something between the tags for them to count.
        -                if ($index == $beginningIndex + 1)
        -                    {  return -1;  }
        -                else
        -                    {
        -                    # Success!
        -
        -                    if ($hasWhitespaceRef)
        -                        {  $$hasWhitespaceRef = $hasWhitespace;  };
        -
        -                    return $index;
        -                    };
        -                }
        -
        -            # If there are two opening tags of the same type, the first becomes literal and the next becomes part of a tag.
        -            elsif ($tagType == POSSIBLE_OPENING_TAG)
        -                {  return -1;  }
        -            }
        -
        -        elsif ($hasWhitespaceRef && !$hasWhitespace)
        -            {
        -            if ($textBlocks->[$index] =~ /[ \t\n]/)
        -                {  $hasWhitespace = 1;  };
        -            };
        -
        -        $index++;
        -        };
        -
        -    # Hit the end of the text blocks if we're here.
        -    return -1;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Parser/ParsedTopic.pm b/vendor/naturaldocs/Modules/NaturalDocs/Parser/ParsedTopic.pm
        deleted file mode 100644
        index c4c2afd80..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Parser/ParsedTopic.pm
        +++ /dev/null
        @@ -1,254 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Parser::ParsedTopic
        -#
        -###############################################################################
        -#
        -#   A class for parsed topics of source files.  Also encompasses some of the <TopicType>-specific behavior.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Parser::ParsedTopic;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The object is a blessed arrayref with the following indexes.
        -#
        -#       TYPE           - The <TopicType>.
        -#       TITLE          - The title of the topic.
        -#       PACKAGE    - The package <SymbolString> the topic appears in, or undef if none.
        -#       USING         - An arrayref of additional package <SymbolStrings> available to the topic via "using" statements, or undef if
        -#                           none.
        -#       PROTOTYPE - The prototype, if it exists and is applicable.
        -#       SUMMARY    - The summary, if it exists.
        -#       BODY          - The body of the topic, formatted in <NDMarkup>.  Some topics may not have bodies, and if not, this
        -#                           will be undef.
        -#       LINE_NUMBER  - The line number the topic appears at in the file.
        -#       IS_LIST - Whether the topic is a list.
        -#
        -use NaturalDocs::DefineMembers 'TYPE', 'TITLE', 'PACKAGE', 'USING', 'PROTOTYPE', 'SUMMARY', 'BODY',
        -                                                 'LINE_NUMBER', 'IS_LIST';
        -# DEPENDENCY: New() depends on the order of these constants, and that this class is not inheriting any members.
        -
        -
        -#
        -#   Architecture: Title, Package, and Symbol Behavior
        -#
        -#   Title, package, and symbol behavior is a little awkward so it deserves some explanation.  Basically you set them according to
        -#   certain rules, but you get computed values that try to hide all the different scoping situations.
        -#
        -#   Normal Topics:
        -#
        -#       Set them to the title and package as they appear.  "Function" and "PkgA.PkgB" will return "Function" for the title,
        -#       "PkgA.PkgB" for the package, and "PkgA.PkgB.Function" for the symbol.
        -#
        -#       In the rare case that a title has a separator symbol it's treated as inadvertant, so "A vs. B" in "PkgA.PkgB" still returns just
        -#       "PkgA.PkgB" for the package even though if you got it from the symbol it can be seen as "PkgA.PkgB.A vs".
        -#
        -#   Scope Topics:
        -#
        -#       Set the title normally and leave the package undef.  So "PkgA.PkgB" and undef will return "PkgA.PkgB" for the title as well
        -#       as for the package and symbol.
        -#
        -#       The only time you should set the package is when you have full language support and they only documented the class with
        -#       a partial title.  So if you documented "PkgA.PkgB" with just "PkgB", you want to set the package to "PkgA".  This
        -#       will return "PkgB" as the title for presentation and will return "PkgA.PkgB" for the package and symbol, which is correct.
        -#
        -#   Always Global Topics:
        -#
        -#       Set the title and package normally, do not set the package to undef.  So "Global" and "PkgA.PkgB" will return "Global" as
        -#       the title, "PkgA.PkgB" as the package, and "Global" as the symbol.
        -#
        -#   Um, yeah...:
        -#
        -#       So does this suck?  Yes, yes it does.  But the suckiness is centralized here instead of having to be handled everywhere these
        -#       issues come into play.  Just realize there are a certain set of rules to follow when you *set* these variables, and the results
        -#       you see when you *get* them are computed rather than literal.
        -#
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates a new object.
        -#
        -#   Parameters:
        -#
        -#       type          - The <TopicType>.
        -#       title           - The title of the topic.
        -#       package    - The package <SymbolString> the topic appears in, or undef if none.
        -#       using         - An arrayref of additional package <SymbolStrings> available to the topic via "using" statements, or undef if
        -#                          none.
        -#       prototype   - The prototype, if it exists and is applicable.  Otherwise set to undef.
        -#       summary   - The summary of the topic, if any.
        -#       body          - The body of the topic, formatted in <NDMarkup>.  May be undef, as some topics may not have bodies.
        -#       lineNumber - The line number the topic appears at in the file.
        -#       isList          - Whether the topic is a list topic or not.
        -#
        -#   Returns:
        -#
        -#       The new object.
        -#
        -sub New #(type, title, package, using, prototype, summary, body, lineNumber, isList)
        -    {
        -    # DEPENDENCY: This depends on the order of the parameter list being the same as the constants, and that there are no
        -    # members inherited from a base class.
        -
        -    my $package = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $package;
        -
        -    if (defined $object->[USING])
        -        {  $object->[USING] = [ @{$object->[USING]} ];  };
        -
        -    return $object;
        -    };
        -
        -
        -# Function: Type
        -# Returns the <TopicType>.
        -sub Type
        -    {  return $_[0]->[TYPE];  };
        -
        -# Function: SetType
        -# Replaces the <TopicType>.
        -sub SetType #(type)
        -    {  $_[0]->[TYPE] = $_[1];  };
        -
        -# Function: IsList
        -# Returns whether the topic is a list.
        -sub IsList
        -    {  return $_[0]->[IS_LIST];  };
        -
        -# Function: SetIsList
        -# Sets whether the topic is a list.
        -sub SetIsList
        -    {  $_[0]->[IS_LIST] = $_[1];  };
        -
        -# Function: Title
        -# Returns the title of the topic.
        -sub Title
        -    {  return $_[0]->[TITLE];  };
        -
        -# Function: SetTitle
        -# Replaces the topic title.
        -sub SetTitle #(title)
        -    {  $_[0]->[TITLE] = $_[1];  };
        -
        -#
        -#   Function: Symbol
        -#
        -#   Returns the <SymbolString> defined by the topic.  It is fully resolved and does _not_ need to be joined with <Package()>.
        -#
        -#   Type-Specific Behavior:
        -#
        -#       - If the <TopicType> is always global, the symbol will be generated from the title only.
        -#       - Everything else's symbols will be generated from the title and the package passed to <New()>.
        -#
        -sub Symbol
        -    {
        -    my ($self) = @_;
        -
        -    my $titleSymbol = NaturalDocs::SymbolString->FromText($self->[TITLE]);
        -
        -    if (NaturalDocs::Topics->TypeInfo($self->Type())->Scope() == ::SCOPE_ALWAYS_GLOBAL())
        -        {  return $titleSymbol;  }
        -    else
        -        {
        -        return NaturalDocs::SymbolString->Join( $self->[PACKAGE], $titleSymbol );
        -        };
        -    };
        -
        -
        -#
        -#   Function: Package
        -#
        -#   Returns the package <SymbolString> that the topic appears in.
        -#
        -#   Type-Specific Behavior:
        -#
        -#       - If the <TopicType> has scope, the package will be generated from both the title and the package passed to <New()>, not
        -#         just the package.
        -#       - If the <TopicType> is always global, the package will be the one passed to <New()>, even though it isn't part of it's
        -#         <Symbol()>.
        -#       - Everything else's package will be what was passed to <New()>, even if the title has separator symbols in it.
        -#
        -sub Package
        -    {
        -    my ($self) = @_;
        -
        -    # Headerless topics may not have a type yet.
        -    if ($self->Type() && NaturalDocs::Topics->TypeInfo($self->Type())->Scope() == ::SCOPE_START())
        -        {  return $self->Symbol();  }
        -    else
        -        {  return $self->[PACKAGE];  };
        -    };
        -
        -
        -# Function: SetPackage
        -# Replaces the package the topic appears in.  This will behave the same way as the package parameter in <New()>.  Later calls
        -# to <Package()> will still be generated according to its type-specific behavior.
        -sub SetPackage #(package)
        -    {  $_[0]->[PACKAGE] = $_[1];  };
        -
        -# Function: Using
        -# Returns an arrayref of additional scope <SymbolStrings> available to the topic via "using" statements, or undef if none.
        -sub Using
        -    {  return $_[0]->[USING];  };
        -
        -# Function: SetUsing
        -# Replaces the using arrayref of sope <SymbolStrings>.
        -sub SetUsing #(using)
        -    {  $_[0]->[USING] = $_[1];  };
        -
        -# Function: Prototype
        -# Returns the prototype if one is defined.  Will be undef otherwise.
        -sub Prototype
        -    {  return $_[0]->[PROTOTYPE];  };
        -
        -# Function: SetPrototype
        -# Replaces the function or variable prototype.
        -sub SetPrototype #(prototype)
        -    {  $_[0]->[PROTOTYPE] = $_[1];  };
        -
        -# Function: Summary
        -# Returns the topic summary, if it exists, formatted in <NDMarkup>.
        -sub Summary
        -    {  return $_[0]->[SUMMARY];  };
        -
        -# Function: Body
        -# Returns the topic's body, formatted in <NDMarkup>.  May be undef.
        -sub Body
        -    {  return $_[0]->[BODY];  };
        -
        -# Function: SetBody
        -# Replaces the topic's body, formatted in <NDMarkup>.  May be undef.
        -sub SetBody #(body)
        -    {
        -    my ($self, $body) = @_;
        -    $self->[BODY] = $body;
        -    };
        -
        -# Function: LineNumber
        -# Returns the line the topic appears at in the file.
        -sub LineNumber
        -    {  return $_[0]->[LINE_NUMBER];  };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Project.pm b/vendor/naturaldocs/Modules/NaturalDocs/Project.pm
        deleted file mode 100644
        index b62495fe1..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Project.pm
        +++ /dev/null
        @@ -1,1404 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Project
        -#
        -###############################################################################
        -#
        -#   A package that manages information about the files in the source tree, as well as the list of files that have to be parsed
        -#   and built.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - All the <Config and Data File Functions> are available immediately, except for the status functions.
        -#
        -#       - <ReparseEverything()> and <RebuildEverything()> are available immediately, because they may need to be called
        -#         after <LoadConfigFileInfo()> but before <LoadSourceFileInfo()>.
        -#
        -#       - Prior to <LoadConfigFileInfo()>, <NaturalDocs::Settings> must be initialized.
        -#
        -#       - After <LoadConfigFileInfo()>, the status <Config and Data File Functions> are available as well.
        -#
        -#       - Prior to <LoadSourceFileInfo()>, <NaturalDocs::Settings> and <NaturalDocs::Languages> must be initialized.
        -#
        -#       - After <LoadSourceFileInfo()>, the rest of the <Source File Functions> are available.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use NaturalDocs::Project::SourceFile;
        -use NaturalDocs::Project::ImageFile;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Project;
        -
        -
        -###############################################################################
        -# Group: File Handles
        -
        -#
        -#   handle: FH_FILEINFO
        -#
        -#   The file handle for the file information file, <FileInfo.nd>.
        -#
        -
        -#
        -#   handle: FH_CONFIGFILEINFO
        -#
        -#   The file handle for the config file information file, <ConfigFileInfo.nd>.
        -#
        -
        -#
        -#   handle: FH_IMAGEFILE
        -#
        -#   The file handle for determining the dimensions of image files.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: Source File Variables
        -
        -
        -#
        -#   hash: supportedFiles
        -#
        -#   A hash of all the supported files in the input directory.  The keys are the <FileNames>, and the values are
        -#   <NaturalDocs::Project::SourceFile> objects.
        -#
        -my %supportedFiles;
        -
        -#
        -#   hash: filesToParse
        -#
        -#   An existence hash of all the <FileNames> that need to be parsed.
        -#
        -my %filesToParse;
        -
        -#
        -#   hash: filesToBuild
        -#
        -#   An existence hash of all the <FileNames> that need to be built.
        -#
        -my %filesToBuild;
        -
        -#
        -#   hash: filesToPurge
        -#
        -#   An existence hash of the <FileNames> that had Natural Docs content last time, but now either don't exist or no longer have
        -#   content.
        -#
        -my %filesToPurge;
        -
        -#
        -#   hash: unbuiltFilesWithContent
        -#
        -#   An existence hash of all the <FileNames> that have Natural Docs content but are not part of <filesToBuild>.
        -#
        -my %unbuiltFilesWithContent;
        -
        -
        -# bool: reparseEverything
        -# Whether all the source files need to be reparsed.
        -my $reparseEverything;
        -
        -# bool: rebuildEverything
        -# Whether all the source files need to be rebuilt.
        -my $rebuildEverything;
        -
        -# hash: mostUsedLanguage
        -# The name of the most used language.  Doesn't include text files.
        -my $mostUsedLanguage;
        -
        -
        -
        -###############################################################################
        -# Group: Configuration File Variables
        -
        -
        -#
        -#   hash: mainConfigFile
        -#
        -#   A hash mapping all the main configuration file names without paths to their <FileStatus>.  Prior to <LoadConfigFileInfo()>,
        -#   it serves as an existence hashref of the file names.
        -#
        -my %mainConfigFiles = ( 'Topics.txt' => 1, 'Languages.txt' => 1 );
        -
        -#
        -#   hash: userConfigFiles
        -#
        -#   A hash mapping all the user configuration file names without paths to their <FileStatus>.  Prior to <LoadConfigFileInfo()>,
        -#   it serves as an existence hashref of the file names.
        -#
        -my %userConfigFiles = ( 'Topics.txt' => 1, 'Languages.txt' => 1, 'Menu.txt' => 1 );
        -
        -
        -
        -
        -###############################################################################
        -# Group: Image File Variables
        -
        -
        -#
        -#   hash: imageFileExtensions
        -#
        -#   An existence hash of all the file extensions for images.  Extensions are in all lowercase.
        -#
        -my %imageFileExtensions = ( 'jpg' => 1, 'jpeg' => 1, 'gif' => 1, 'png' => 1, 'bmp' => 1 );
        -
        -
        -#
        -#   hash: imageFiles
        -#
        -#   A hash of all the image files in the project.  The keys are the <FileNames> and the values are
        -#   <NaturalDocs::Project::ImageFiles>.
        -#
        -my %imageFiles;
        -
        -
        -#
        -#   hash: imageFilesToUpdate
        -#
        -#   An existence hash of all the image <FileNames> that need to be updated, either because they changed or they're new to the
        -#   project.
        -#
        -my %imageFilesToUpdate;
        -
        -
        -#
        -#   hash: imageFilesToPurge
        -#
        -#   An existence hash of all the image <FileNames> that need to be purged, either because the files no longer exist or because
        -#   they are no longer used.
        -#
        -my %imageFilesToPurge;
        -
        -
        -#
        -#   hash: insensitiveImageFiles
        -#
        -#   A hash that maps all lowercase image <FileNames> to their proper case as it would appear in <imageFiles>.  Used for
        -#   case insensitivity, obviously.
        -#
        -#   You can't just use all lowercase in <imageFiles> because both Linux and HTTP are case sensitive, so the original case must
        -#   be preserved.  We also want to allow separate entries for files that differ based only on case, so it goes to <imageFiles> first
        -#   where they can be distinguished and here only if there's no match.  Ties are broken by whichever is lower with cmp, because
        -#   it has to resolve consistently on all runs of the program.
        -#
        -my %insensitiveImageFiles;
        -
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: FileInfo.nd
        -#
        -#   An index of the state of the files as of the last parse.  Used to determine if files were added, deleted, or changed.
        -#
        -#   Format:
        -#
        -#       The format is a text file.
        -#
        -#       > [VersionInt: app version]
        -#
        -#       The beginning of the file is the <VersionInt> it was generated with.
        -#
        -#       > [most used language name]
        -#
        -#       Next is the name of the most used language in the source tree.  Does not include text files.
        -#
        -#       Each following line is
        -#
        -#       > [file name] tab [last modification time] tab [has ND content (0 or 1)] tab [default menu title] \n
        -#
        -#   Revisions:
        -#
        -#       1.3:
        -#
        -#           - The line following the <VersionInt>, which was previously the last modification time of <Menu.txt>, was changed to
        -#             the name of the most used language.
        -#
        -#       1.16:
        -#
        -#           - File names are now absolute.  Prior to 1.16, they were relative to the input directory since only one was allowed.
        -#
        -#       1.14:
        -#
        -#           - The file was renamed from NaturalDocs.files to FileInfo.nd and moved into the Data subdirectory.
        -#
        -#       0.95:
        -#
        -#           - The file version was changed to match the program version.  Prior to 0.95, the version line was 1.  Test for "1" instead
        -#             of "1.0" to distinguish.
        -#
        -
        -
        -#
        -#   File: ConfigFileInfo.nd
        -#
        -#   An index of the state of the config files as of the last parse.
        -#
        -#   Format:
        -#
        -#       > [BINARY_FORMAT]
        -#       > [VersionInt: app version]
        -#
        -#       First is the standard <BINARY_FORMAT> <VersionInt> header.
        -#
        -#       > [UInt32: last modification time of menu]
        -#       > [UInt32: last modification of main topics file]
        -#       > [UInt32: last modification of user topics file]
        -#       > [UInt32: last modification of main languages file]
        -#       > [UInt32: last modification of user languages file]
        -#
        -#       Next are the last modification times of various configuration files as UInt32s in the standard Unix format.
        -#
        -#
        -#   Revisions:
        -#
        -#       1.3:
        -#
        -#           - The file was added to Natural Docs.  Previously the last modification of <Menu.txt> was stored in <FileInfo.nd>, and
        -#             <Topics.txt> and <Languages.txt> didn't exist.
        -#
        -
        -
        -#
        -#   File: ImageFileInfo.nd
        -#
        -#   An index of the state of the image files as of the last parse.
        -#
        -#   Format:
        -#
        -#       > [Standard Binary Header]
        -#
        -#       First is the standard binary file header as defined by <NaturalDocs::BinaryFile>.
        -#
        -#       > [AString16: file name or undef]
        -#       > [UInt32: last modification time]
        -#       > [UInt8: was used]
        -#
        -#       This section is repeated until the file name is null.  The last modification times are UInt32s in the standard Unix format.
        -#
        -#
        -#   Revisions:
        -#
        -#       1.4:
        -#
        -#           - The file was added to Natural Docs.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -#
        -#   Function: LoadSourceFileInfo
        -#
        -#   Loads the project file from disk and compares it against the files in the input directory.  Project is loaded from
        -#   <FileInfo.nd>.  New and changed files will be added to <FilesToParse()>, and if they have content,
        -#   <FilesToBuild()>.
        -#
        -#   Will call <NaturalDocs::Languages->OnMostUsedLanguageKnown()> if <MostUsedLanguage()> changes.
        -#
        -#   Returns:
        -#
        -#       Returns whether the project was changed in any way.
        -#
        -sub LoadSourceFileInfo
        -    {
        -    my ($self) = @_;
        -
        -    $self->GetAllSupportedFiles();
        -    NaturalDocs::Languages->OnMostUsedLanguageKnown();
        -
        -    my $fileIsOkay;
        -    my $version;
        -    my $hasChanged;
        -    my $lineReader;
        -
        -    if (open(FH_FILEINFO, '<' . $self->DataFile('FileInfo.nd')))
        -        {
        -        $lineReader = NaturalDocs::LineReader->New(\*FH_FILEINFO);
        -
        -        # Check if the file is in the right format.
        -        $version = NaturalDocs::Version->FromString($lineReader->Get());
        -
        -        # The project file need to be rebuilt for 1.16.  The source files need to be reparsed and the output files rebuilt for 1.51.
        -        # We'll tolerate the difference between 1.16 and 1.3 in the loader.
        -
        -        if (NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.16') ))
        -            {
        -            $fileIsOkay = 1;
        -
        -            if (!NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.51') ))
        -                {
        -                $reparseEverything = 1;
        -                $rebuildEverything = 1;
        -                $hasChanged = 1;
        -                };
        -            }
        -        else
        -            {
        -            close(FH_FILEINFO);
        -            $hasChanged = 1;
        -            };
        -        };
        -
        -
        -    if ($fileIsOkay)
        -        {
        -        my %indexedFiles;
        -
        -
        -        my $line = $lineReader->Get();
        -
        -        # Prior to 1.3 it was the last modification time of Menu.txt, which we ignore and treat as though the most used language
        -        # changed.  Prior to 1.32 the settings didn't transfer over correctly to Menu.txt so we need to behave that way again.
        -        if ($version < NaturalDocs::Version->FromString('1.32') || lc($mostUsedLanguage) ne lc($line))
        -            {
        -            $reparseEverything = 1;
        -            NaturalDocs::SymbolTable->RebuildAllIndexes();
        -            };
        -
        -
        -        # Parse the rest of the file.
        -
        -        while ($line = $lineReader->Get())
        -            {
        -            my ($file, $modification, $hasContent, $menuTitle) = split(/\t/, $line, 4);
        -
        -            # If the file no longer exists...
        -            if (!exists $supportedFiles{$file})
        -                {
        -                if ($hasContent)
        -                    {  $filesToPurge{$file} = 1;  };
        -
        -                $hasChanged = 1;
        -                }
        -
        -            # If the file still exists...
        -            else
        -                {
        -                $indexedFiles{$file} = 1;
        -
        -                # If the file changed...
        -                if ($supportedFiles{$file}->LastModified() != $modification)
        -                    {
        -                    $supportedFiles{$file}->SetStatus(::FILE_CHANGED());
        -                    $filesToParse{$file} = 1;
        -
        -                    # If the file loses its content, this will be removed by SetHasContent().
        -                    if ($hasContent)
        -                        {  $filesToBuild{$file} = 1;  };
        -
        -                    $hasChanged = 1;
        -                    }
        -
        -                # If the file has not changed...
        -                else
        -                    {
        -                    my $status;
        -
        -                    if ($rebuildEverything && $hasContent)
        -                        {
        -                        $status = ::FILE_CHANGED();
        -
        -                        # If the file loses its content, this will be removed by SetHasContent().
        -                        $filesToBuild{$file} = 1;
        -                        $hasChanged = 1;
        -                        }
        -                    else
        -                        {
        -                        $status = ::FILE_SAME();
        -
        -                        if ($hasContent)
        -                            {  $unbuiltFilesWithContent{$file} = 1;  };
        -                        };
        -
        -                    if ($reparseEverything)
        -                        {
        -                        $status = ::FILE_CHANGED();
        -
        -                        $filesToParse{$file} = 1;
        -                        $hasChanged = 1;
        -                        };
        -
        -                    $supportedFiles{$file}->SetStatus($status);
        -                    };
        -
        -                $supportedFiles{$file}->SetHasContent($hasContent);
        -                $supportedFiles{$file}->SetDefaultMenuTitle($menuTitle);
        -                };
        -            };
        -
        -        close(FH_FILEINFO);
        -
        -
        -        # Check for added files.
        -
        -        if (scalar keys %supportedFiles > scalar keys %indexedFiles)
        -            {
        -            foreach my $file (keys %supportedFiles)
        -                {
        -                if (!exists $indexedFiles{$file})
        -                    {
        -                    $supportedFiles{$file}->SetStatus(::FILE_NEW());
        -                    $supportedFiles{$file}->SetDefaultMenuTitle($file);
        -                    $supportedFiles{$file}->SetHasContent(undef);
        -                    $filesToParse{$file} = 1;
        -                    # It will be added to filesToBuild if HasContent gets set to true when it's parsed.
        -                    $hasChanged = 1;
        -                    };
        -                };
        -            };
        -        }
        -
        -    # If something's wrong with FileInfo.nd, everything is new.
        -    else
        -        {
        -        foreach my $file (keys %supportedFiles)
        -            {
        -            $supportedFiles{$file}->SetStatus(::FILE_NEW());
        -            $supportedFiles{$file}->SetDefaultMenuTitle($file);
        -            $supportedFiles{$file}->SetHasContent(undef);
        -            $filesToParse{$file} = 1;
        -            # It will be added to filesToBuild if HasContent gets set to true when it's parsed.
        -            };
        -
        -        $hasChanged = 1;
        -        };
        -
        -
        -    # There are other side effects, so we need to call this.
        -    if ($rebuildEverything)
        -        {  $self->RebuildEverything();  };
        -
        -
        -    return $hasChanged;
        -    };
        -
        -
        -#
        -#   Function: SaveSourceFileInfo
        -#
        -#   Saves the source file info to disk.  Everything is saved in <FileInfo.nd>.
        -#
        -sub SaveSourceFileInfo
        -    {
        -    my ($self) = @_;
        -
        -    open(FH_FILEINFO, '>' . $self->DataFile('FileInfo.nd'))
        -        or die "Couldn't save project file " . $self->DataFile('FileInfo.nd') . "\n";
        -
        -    NaturalDocs::Version->ToTextFile(\*FH_FILEINFO, NaturalDocs::Settings->AppVersion());
        -
        -    print FH_FILEINFO $mostUsedLanguage . "\n";
        -
        -    while (my ($fileName, $file) = each %supportedFiles)
        -        {
        -        print FH_FILEINFO $fileName . "\t"
        -                              . $file->LastModified() . "\t"
        -                              . ($file->HasContent() || '0') . "\t"
        -                              . $file->DefaultMenuTitle() . "\n";
        -        };
        -
        -    close(FH_FILEINFO);
        -    };
        -
        -
        -#
        -#   Function: LoadConfigFileInfo
        -#
        -#   Loads the config file info from disk.
        -#
        -sub LoadConfigFileInfo
        -    {
        -    my ($self) = @_;
        -
        -    my $fileIsOkay;
        -    my $version;
        -    my $fileName = NaturalDocs::Project->DataFile('ConfigFileInfo.nd');
        -
        -    if (open(FH_CONFIGFILEINFO, '<' . $fileName))
        -        {
        -        # See if it's binary.
        -        binmode(FH_CONFIGFILEINFO);
        -
        -        my $firstChar;
        -        read(FH_CONFIGFILEINFO, $firstChar, 1);
        -
        -        if ($firstChar == ::BINARY_FORMAT())
        -            {
        -            $version = NaturalDocs::Version->FromBinaryFile(\*FH_CONFIGFILEINFO);
        -
        -            # It hasn't changed since being introduced.
        -
        -            if (NaturalDocs::Version->CheckFileFormat($version))
        -                {  $fileIsOkay = 1;  }
        -            else
        -                {  close(FH_CONFIGFILEINFO);  };
        -            }
        -
        -        else # it's not in binary
        -            {  close(FH_CONFIGFILEINFO);  };
        -        };
        -
        -    my @configFiles = ( $self->UserConfigFile('Menu.txt'), \$userConfigFiles{'Menu.txt'},
        -                                 $self->MainConfigFile('Topics.txt'), \$mainConfigFiles{'Topics.txt'},
        -                                 $self->UserConfigFile('Topics.txt'), \$userConfigFiles{'Topics.txt'},
        -                                 $self->MainConfigFile('Languages.txt'), \$mainConfigFiles{'Languages.txt'},
        -                                 $self->UserConfigFile('Languages.txt'), \$userConfigFiles{'Languages.txt'} );
        -
        -    if ($fileIsOkay)
        -        {
        -        my $raw;
        -
        -        read(FH_CONFIGFILEINFO, $raw, 20);
        -        my @configFileDates = unpack('NNNNN', $raw);
        -
        -        while (scalar @configFiles)
        -            {
        -            my $file = shift @configFiles;
        -            my $fileStatus = shift @configFiles;
        -            my $fileDate = shift @configFileDates;
        -
        -            if (-e $file)
        -                {
        -                if ($fileDate == (stat($file))[9])
        -                    {  $$fileStatus = ::FILE_SAME();  }
        -                else
        -                    {  $$fileStatus = ::FILE_CHANGED();  };
        -                }
        -            else
        -                {  $$fileStatus = ::FILE_DOESNTEXIST();  };
        -            };
        -
        -        close(FH_CONFIGFILEINFO);
        -        }
        -    else # !$fileIsOkay
        -        {
        -        while (scalar @configFiles)
        -            {
        -            my $file = shift @configFiles;
        -            my $fileStatus = shift @configFiles;
        -
        -            if (-e $file)
        -                {  $$fileStatus = ::FILE_CHANGED();  }
        -            else
        -                {  $$fileStatus = ::FILE_DOESNTEXIST();  };
        -            };
        -        };
        -
        -    if ($userConfigFiles{'Menu.txt'} == ::FILE_SAME() && $rebuildEverything)
        -        {  $userConfigFiles{'Menu.txt'} = ::FILE_CHANGED();  };
        -    };
        -
        -
        -#
        -#   Function: SaveConfigFileInfo
        -#
        -#   Saves the config file info to disk.  You *must* save all other config files first, such as <Menu.txt> and <Topics.txt>.
        -#
        -sub SaveConfigFileInfo
        -    {
        -    my ($self) = @_;
        -
        -    open (FH_CONFIGFILEINFO, '>' . NaturalDocs::Project->DataFile('ConfigFileInfo.nd'))
        -        or die "Couldn't save " . NaturalDocs::Project->DataFile('ConfigFileInfo.nd') . ".\n";
        -
        -    binmode(FH_CONFIGFILEINFO);
        -
        -    print FH_CONFIGFILEINFO '' . ::BINARY_FORMAT();
        -
        -    NaturalDocs::Version->ToBinaryFile(\*FH_CONFIGFILEINFO, NaturalDocs::Settings->AppVersion());
        -
        -    print FH_CONFIGFILEINFO pack('NNNNN', (stat($self->UserConfigFile('Menu.txt')))[9],
        -                                                                (stat($self->MainConfigFile('Topics.txt')))[9],
        -                                                                (stat($self->UserConfigFile('Topics.txt')))[9],
        -                                                                (stat($self->MainConfigFile('Languages.txt')))[9],
        -                                                                (stat($self->UserConfigFile('Languages.txt')))[9] );
        -
        -    close(FH_CONFIGFILEINFO);
        -    };
        -
        -
        -#
        -#   Function: LoadImageFileInfo
        -#
        -#   Loads the image file info from disk.
        -#
        -sub LoadImageFileInfo
        -    {
        -    my ($self) = @_;
        -
        -    my $version = NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('ImageFileInfo.nd') );
        -    my $fileIsOkay;
        -
        -    if (defined $version)
        -        {
        -        # It hasn't changed since being introduced.
        -
        -        if (NaturalDocs::Version->CheckFileFormat($version))
        -            {  $fileIsOkay = 1;  }
        -        else
        -            {  NaturalDocs::BinaryFile->Close();  };
        -        };
        -
        -    if ($fileIsOkay)
        -        {
        -        # [AString16: file name or undef]
        -
        -        while (my $imageFile = NaturalDocs::BinaryFile->GetAString16())
        -            {
        -            # [UInt32: last modified]
        -            # [UInt8: was used]
        -
        -            my $lastModified = NaturalDocs::BinaryFile->GetUInt32();
        -            my $wasUsed = NaturalDocs::BinaryFile->GetUInt8();
        -
        -            my $imageFileObject = $imageFiles{$imageFile};
        -
        -            # If there's an image file in ImageFileInfo.nd that no longer exists...
        -            if (!$imageFileObject)
        -                {
        -                $imageFileObject = NaturalDocs::Project::ImageFile->New($lastModified, ::FILE_DOESNTEXIST(), $wasUsed);
        -                $imageFiles{$imageFile} = $imageFileObject;
        -
        -                if ($wasUsed)
        -                    {  $imageFilesToPurge{$imageFile} = 1;  };
        -                }
        -            else
        -                {
        -                $imageFileObject->SetWasUsed($wasUsed);
        -
        -                # This will be removed if it gets any references.
        -                if ($wasUsed)
        -                    {  $imageFilesToPurge{$imageFile} = 1;  };
        -
        -                if ($imageFileObject->LastModified() == $lastModified && !$rebuildEverything)
        -                    {  $imageFileObject->SetStatus(::FILE_SAME());  }
        -                else
        -                    {  $imageFileObject->SetStatus(::FILE_CHANGED());  };
        -                };
        -            };
        -
        -        NaturalDocs::BinaryFile->Close();
        -        }
        -
        -    else # !$fileIsOkay
        -        {
        -        $self->RebuildEverything();
        -        };
        -    };
        -
        -
        -#
        -#   Function: SaveImageFileInfo
        -#
        -#   Saves the image file info to disk.
        -#
        -sub SaveImageFileInfo
        -    {
        -    my $self = shift;
        -
        -    NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('ImageFileInfo.nd') );
        -
        -    while (my ($imageFile, $imageFileInfo) = each %imageFiles)
        -        {
        -        if ($imageFileInfo->Status() != ::FILE_DOESNTEXIST())
        -            {
        -            # [AString16: file name or undef]
        -            # [UInt32: last modification time]
        -            # [UInt8: was used]
        -
        -            NaturalDocs::BinaryFile->WriteAString16($imageFile);
        -            NaturalDocs::BinaryFile->WriteUInt32($imageFileInfo->LastModified());
        -            NaturalDocs::BinaryFile->WriteUInt8( ($imageFileInfo->ReferenceCount() > 0 ? 1 : 0) );
        -            };
        -        };
        -
        -    NaturalDocs::BinaryFile->WriteAString16(undef);
        -    NaturalDocs::BinaryFile->Close();
        -    };
        -
        -
        -#
        -#   Function: MigrateOldFiles
        -#
        -#   If the project uses the old file names used prior to 1.14, it converts them to the new file names.
        -#
        -sub MigrateOldFiles
        -    {
        -    my ($self) = @_;
        -
        -    my $projectDirectory = NaturalDocs::Settings->ProjectDirectory();
        -
        -    # We use the menu file as a test to see if we're using the new format.
        -    if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs_Menu.txt'))
        -        {
        -        # The Data subdirectory would have been created by NaturalDocs::Settings.
        -
        -        rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs_Menu.txt'), $self->UserConfigFile('Menu.txt') );
        -
        -        if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.sym'))
        -            {  rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.sym'), $self->DataFile('SymbolTable.nd') );  };
        -
        -        if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.files'))
        -            {  rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.files'), $self->DataFile('FileInfo.nd') );  };
        -
        -        if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.m'))
        -            {  rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.m'), $self->DataFile('PreviousMenuState.nd') );  };
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Config and Data File Functions
        -
        -
        -#
        -#   Function: MainConfigFile
        -#
        -#   Returns the full path to the passed main configuration file.  Pass the file name only.
        -#
        -sub MainConfigFile #(string file)
        -    {
        -    my ($self, $file) = @_;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ConfigDirectory(), $file );
        -    };
        -
        -#
        -#   Function: MainConfigFileStatus
        -#
        -#   Returns the <FileStatus> of the passed main configuration file.  Pass the file name only.
        -#
        -sub MainConfigFileStatus #(string file)
        -    {
        -    my ($self, $file) = @_;
        -    return $mainConfigFiles{$file};
        -    };
        -
        -#
        -#   Function: UserConfigFile
        -#
        -#   Returns the full path to the passed user configuration file.  Pass the file name only.
        -#
        -sub UserConfigFile #(string file)
        -    {
        -    my ($self, $file) = @_;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), $file );
        -    };
        -
        -#
        -#   Function: UserConfigFileStatus
        -#
        -#   Returns the <FileStatus> of the passed user configuration file.  Pass the file name only.
        -#
        -sub UserConfigFileStatus #(string file)
        -    {
        -    my ($self, $file) = @_;
        -    return $userConfigFiles{$file};
        -    };
        -
        -#
        -#   Function: DataFile
        -#
        -#   Returns the full path to the passed data file.  Pass the file name only.
        -#
        -sub DataFile #(string file)
        -    {
        -    my ($self, $file) = @_;
        -    return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), $file );
        -    };
        -
        -
        -
        -
        -###############################################################################
        -# Group: Source File Functions
        -
        -
        -# Function: FilesToParse
        -# Returns an existence hashref of the <FileNames> to parse.  This is not a copy of the data, so don't change it.
        -sub FilesToParse
        -    {  return \%filesToParse;  };
        -
        -# Function: FilesToBuild
        -# Returns an existence hashref of the <FileNames> to build.  This is not a copy of the data, so don't change it.
        -sub FilesToBuild
        -    {  return \%filesToBuild;  };
        -
        -# Function: FilesToPurge
        -# Returns an existence hashref of the <FileNames> that had content last time, but now either don't anymore or were deleted.
        -# This is not a copy of the data, so don't change it.
        -sub FilesToPurge
        -    {  return \%filesToPurge;  };
        -
        -#
        -#   Function: RebuildFile
        -#
        -#   Adds the file to the list of files to build.  This function will automatically filter out files that don't have Natural Docs content and
        -#   files that are part of <FilesToPurge()>.  If this gets called on a file and that file later gets Natural Docs content, it will be added.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> to build or rebuild.
        -#
        -sub RebuildFile #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    # We don't want to add it to the build list if it doesn't exist, doesn't have Natural Docs content, or it's going to be purged.
        -    # If it wasn't parsed yet and will later be found to have ND content, it will be added by SetHasContent().
        -    if (exists $supportedFiles{$file} && !exists $filesToPurge{$file} && $supportedFiles{$file}->HasContent())
        -        {
        -        $filesToBuild{$file} = 1;
        -
        -        if (exists $unbuiltFilesWithContent{$file})
        -            {  delete $unbuiltFilesWithContent{$file};  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: ReparseEverything
        -#
        -#   Adds all supported files to the list of files to parse.  This does not necessarily mean these files are going to be rebuilt.
        -#
        -sub ReparseEverything
        -    {
        -    my ($self) = @_;
        -
        -    if (!$reparseEverything)
        -        {
        -        foreach my $file (keys %supportedFiles)
        -            {
        -            $filesToParse{$file} = 1;
        -            };
        -
        -        $reparseEverything = 1;
        -        };
        -    };
        -
        -
        -#
        -#   Function: RebuildEverything
        -#
        -#   Adds all supported files to the list of files to build.  This does not necessarily mean these files are going to be reparsed.
        -#
        -sub RebuildEverything
        -    {
        -    my ($self) = @_;
        -
        -    foreach my $file (keys %unbuiltFilesWithContent)
        -        {
        -        $filesToBuild{$file} = 1;
        -        };
        -
        -    %unbuiltFilesWithContent = ( );
        -    $rebuildEverything = 1;
        -
        -    NaturalDocs::SymbolTable->RebuildAllIndexes();
        -
        -    if ($userConfigFiles{'Menu.txt'} == ::FILE_SAME())
        -        {  $userConfigFiles{'Menu.txt'} = ::FILE_CHANGED();  };
        -
        -    while (my ($imageFile, $imageObject) = each %imageFiles)
        -        {
        -        if ($imageObject->ReferenceCount())
        -            {  $imageFilesToUpdate{$imageFile} = 1;  };
        -        };
        -    };
        -
        -
        -# Function: UnbuiltFilesWithContent
        -# Returns an existence hashref of the <FileNames> that have Natural Docs content but are not part of <FilesToBuild()>.  This is
        -# not a copy of the data so don't change it.
        -sub UnbuiltFilesWithContent
        -    {  return \%unbuiltFilesWithContent;  };
        -
        -# Function: FilesWithContent
        -# Returns and existence hashref of the <FileNames> that have Natural Docs content.
        -sub FilesWithContent
        -    {
        -    # Don't keep this one internally, but there's an easy way to make it.
        -    return { %filesToBuild, %unbuiltFilesWithContent };
        -    };
        -
        -
        -#
        -#   Function: HasContent
        -#
        -#   Returns whether the <FileName> contains Natural Docs content.
        -#
        -sub HasContent #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (exists $supportedFiles{$file})
        -        {  return $supportedFiles{$file}->HasContent();  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: SetHasContent
        -#
        -#   Sets whether the <FileName> has Natural Docs content or not.
        -#
        -sub SetHasContent #(file, hasContent)
        -    {
        -    my ($self, $file, $hasContent) = @_;
        -
        -    if (exists $supportedFiles{$file} && $supportedFiles{$file}->HasContent() != $hasContent)
        -        {
        -        # If the file now has content...
        -        if ($hasContent)
        -            {
        -            $filesToBuild{$file} = 1;
        -            }
        -
        -        # If the file's content has been removed...
        -        else
        -            {
        -            delete $filesToBuild{$file};  # may not be there
        -            $filesToPurge{$file} = 1;
        -            };
        -
        -        $supportedFiles{$file}->SetHasContent($hasContent);
        -        };
        -    };
        -
        -
        -#
        -#   Function: StatusOf
        -#
        -#   Returns the <FileStatus> of the passed <FileName>.
        -#
        -sub StatusOf #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (exists $supportedFiles{$file})
        -        {  return $supportedFiles{$file}->Status();  }
        -    else
        -        {  return ::FILE_DOESNTEXIST();  };
        -    };
        -
        -
        -#
        -#   Function: DefaultMenuTitleOf
        -#
        -#   Returns the default menu title of the <FileName>.  If one isn't specified, it returns the <FileName>.
        -#
        -sub DefaultMenuTitleOf #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (exists $supportedFiles{$file})
        -        {  return $supportedFiles{$file}->DefaultMenuTitle();  }
        -    else
        -        {  return $file;  };
        -    };
        -
        -
        -#
        -#   Function: SetDefaultMenuTitle
        -#
        -#   Sets the <FileName's> default menu title.
        -#
        -sub SetDefaultMenuTitle #(file, menuTitle)
        -    {
        -    my ($self, $file, $menuTitle) = @_;
        -
        -    if (exists $supportedFiles{$file} && $supportedFiles{$file}->DefaultMenuTitle() ne $menuTitle)
        -        {
        -        $supportedFiles{$file}->SetDefaultMenuTitle($menuTitle);
        -        NaturalDocs::Menu->OnDefaultTitleChange($file);
        -        };
        -    };
        -
        -
        -#
        -#   Function: MostUsedLanguage
        -#
        -#   Returns the name of the most used language in the source trees.  Does not include text files.
        -#
        -sub MostUsedLanguage
        -    {  return $mostUsedLanguage;  };
        -
        -
        -
        -
        -###############################################################################
        -# Group: Image File Functions
        -
        -
        -#
        -#   Function: ImageFileExists
        -#   Returns whether the passed image file exists.
        -#
        -sub ImageFileExists #(FileName file) => bool
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (!exists $imageFiles{$file})
        -        {  $file = $insensitiveImageFiles{lc($file)};  };
        -
        -    return (exists $imageFiles{$file} && $imageFiles{$file}->Status() != ::FILE_DOESNTEXIST());
        -    };
        -
        -
        -#
        -#   Function: ImageFileDimensions
        -#   Returns the dimensions of the passed image file as the array ( width, height ).  Returns them both as undef if it cannot be
        -#   determined.
        -#
        -sub ImageFileDimensions #(FileName file) => (int, int)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (!exists $imageFiles{$file})
        -        {  $file = $insensitiveImageFiles{lc($file)};  };
        -
        -    my $object = $imageFiles{$file};
        -    if (!$object)
        -        {  die "Tried to get the dimensions of an image that doesn't exist.";  };
        -
        -    if ($object->Width() == -1)
        -        {  $self->DetermineImageDimensions($file);  };
        -
        -    return ($object->Width(), $object->Height());
        -    };
        -
        -
        -#
        -#   Function: ImageFileCapitalization
        -#   Returns the properly capitalized version of the passed image <FileName>.  Image file paths are treated as case insensitive
        -#   regardless of whether the underlying operating system is or not, so we have to make sure the final version matches the
        -#   capitalization of the actual file.
        -#
        -sub ImageFileCapitalization #(FileName file) => FileName
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (exists $imageFiles{$file})
        -        {  return $file;  }
        -    elsif (exists $insensitiveImageFiles{lc($file)})
        -        {  return $insensitiveImageFiles{lc($file)};  }
        -    else
        -        {  die "Tried to get the capitalization of an image file that doesn't exist.";  };
        -    };
        -
        -
        -#
        -#   Function: AddImageFileReference
        -#   Adds a reference to the passed image <FileName>.
        -#
        -sub AddImageFileReference #(FileName imageFile)
        -    {
        -    my ($self, $imageFile) = @_;
        -
        -    if (!exists $imageFiles{$imageFile})
        -        {  $imageFile = $insensitiveImageFiles{lc($imageFile)};  };
        -
        -    my $imageFileInfo = $imageFiles{$imageFile};
        -
        -    if ($imageFileInfo == undef || $imageFileInfo->Status() == ::FILE_DOESNTEXIST())
        -        {  die "Tried to add a reference to a non-existant image file.";  };
        -
        -    if ($imageFileInfo->AddReference() == 1)
        -        {
        -        delete $imageFilesToPurge{$imageFile};
        -
        -        if (!$imageFileInfo->WasUsed() ||
        -            $imageFileInfo->Status() == ::FILE_NEW() ||
        -            $imageFileInfo->Status() == ::FILE_CHANGED())
        -            {  $imageFilesToUpdate{$imageFile} = 1;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: DeleteImageFileReference
        -#   Deletes a reference from the passed image <FileName>.
        -#
        -sub DeleteImageFileReference #(FileName imageFile)
        -    {
        -    my ($self, $imageFile) = @_;
        -
        -    if (!exists $imageFiles{$imageFile})
        -        {  $imageFile = $insensitiveImageFiles{lc($imageFile)};  };
        -
        -    if (!exists $imageFiles{$imageFile})
        -        {  die "Tried to delete a reference to a non-existant image file.";  };
        -
        -    if ($imageFiles{$imageFile}->DeleteReference() == 0)
        -        {
        -        delete $imageFilesToUpdate{$imageFile};
        -
        -        if ($imageFiles{$imageFile}->WasUsed())
        -            {  $imageFilesToPurge{$imageFile} = 1;  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: ImageFilesToUpdate
        -#   Returns an existence hashref of image <FileNames> that need to be updated.  *Do not change.*
        -#
        -sub ImageFilesToUpdate
        -    {  return \%imageFilesToUpdate;  };
        -
        -
        -#
        -#   Function: ImageFilesToPurge
        -#   Returns an existence hashref of image <FileNames> that need to be updated.  *Do not change.*
        -#
        -sub ImageFilesToPurge
        -    {  return \%imageFilesToPurge;  };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -#
        -#   Function: GetAllSupportedFiles
        -#
        -#   Gets all the supported files in the passed directory and its subdirectories and puts them into <supportedFiles>.  The only
        -#   attribute that will be set is <NaturalDocs::Project::SourceFile->LastModified()>.  Also sets <mostUsedLanguage>.
        -#
        -sub GetAllSupportedFiles
        -    {
        -    my ($self) = @_;
        -
        -    my @directories = @{NaturalDocs::Settings->InputDirectories()};
        -    my $isCaseSensitive = NaturalDocs::File->IsCaseSensitive();
        -
        -    # Keys are language names, values are counts.
        -    my %languageCounts;
        -
        -
        -    # Make an existence hash of excluded directories.
        -
        -    my %excludedDirectories;
        -    my $excludedDirectoryArrayRef = NaturalDocs::Settings->ExcludedInputDirectories();
        -
        -    foreach my $excludedDirectory (@$excludedDirectoryArrayRef)
        -        {
        -        if ($isCaseSensitive)
        -            {  $excludedDirectories{$excludedDirectory} = 1;  }
        -        else
        -            {  $excludedDirectories{lc($excludedDirectory)} = 1;  };
        -        };
        -
        -
        -    my $imagesOnly;
        -    my $language;
        -
        -    while (scalar @directories)
        -        {
        -        my $directory = pop @directories;
        -
        -        opendir DIRECTORYHANDLE, $directory;
        -        my @entries = readdir DIRECTORYHANDLE;
        -        closedir DIRECTORYHANDLE;
        -
        -        @entries = NaturalDocs::File->NoUpwards(@entries);
        -
        -        foreach my $entry (@entries)
        -            {
        -            my $fullEntry = NaturalDocs::File->JoinPaths($directory, $entry);
        -
        -            # If an entry is a directory, recurse.
        -            if (-d $fullEntry)
        -                {
        -                # Join again with the noFile flag set in case the platform handles them differently.
        -                $fullEntry = NaturalDocs::File->JoinPaths($directory, $entry, 1);
        -
        -                if ($isCaseSensitive)
        -                    {
        -                    if (!exists $excludedDirectories{$fullEntry})
        -                        {  push @directories, $fullEntry;  };
        -                    }
        -                else
        -                    {
        -                    if (!exists $excludedDirectories{lc($fullEntry)})
        -                        {  push @directories, $fullEntry;  };
        -                    };
        -                }
        -
        -            # Otherwise add it if it's a supported extension.
        -            else
        -                {
        -                my $extension = NaturalDocs::File->ExtensionOf($entry);
        -
        -                if (exists $imageFileExtensions{lc($extension)})
        -                    {
        -                    my $fileObject = NaturalDocs::Project::ImageFile->New( (stat($fullEntry))[9], ::FILE_NEW(), 0 );
        -                    $imageFiles{$fullEntry} = $fileObject;
        -
        -                    my $lcFullEntry = lc($fullEntry);
        -
        -                    if (!exists $insensitiveImageFiles{$lcFullEntry} ||
        -                        ($fullEntry cmp $insensitiveImageFiles{$lcFullEntry}) < 0)
        -                        {
        -                        $insensitiveImageFiles{$lcFullEntry} = $fullEntry;
        -                        };
        -                    }
        -                elsif (!$imagesOnly && ($language = NaturalDocs::Languages->LanguageOf($fullEntry)) )
        -                    {
        -                    my $fileObject = NaturalDocs::Project::SourceFile->New();
        -                    $fileObject->SetLastModified(( stat($fullEntry))[9] );
        -                    $supportedFiles{$fullEntry} = $fileObject;
        -
        -                    $languageCounts{$language->Name()}++;
        -                    };
        -                };
        -            };
        -
        -
        -        # After we run out of source directories, add the image directories.
        -
        -        if (scalar @directories == 0 && !$imagesOnly)
        -            {
        -            $imagesOnly = 1;
        -            @directories = @{NaturalDocs::Settings->ImageDirectories()};
        -            };
        -        };
        -
        -
        -    my $topCount = 0;
        -
        -    while (my ($language, $count) = each %languageCounts)
        -        {
        -        if ($count > $topCount && $language ne 'Text File')
        -            {
        -            $topCount = $count;
        -            $mostUsedLanguage = $language;
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: DetermineImageDimensions
        -#
        -#   Attempts to determine the dimensions of the passed image and apply them to their object in <imageFiles>.  Will set them to
        -#   undef if they can't be determined.
        -#
        -sub DetermineImageDimensions #(FileName imageFile)
        -    {
        -    my ($self, $imageFile) = @_;
        -
        -    my $imageFileObject = $imageFiles{$imageFile};
        -    if (!defined $imageFileObject)
        -        {  die "Tried to determine image dimensions of a file with no object.";  };
        -
        -    my $extension = lc( NaturalDocs::File->ExtensionOf($imageFile) );
        -    my ($width, $height);
        -
        -    if ($imageFileExtensions{$extension})
        -        {
        -        open(FH_IMAGEFILE, '<' . $imageFile)
        -            or die 'Could not open ' . $imageFile . "\n";
        -        binmode(FH_IMAGEFILE);
        -
        -        my $raw;
        -
        -        if ($extension eq 'gif')
        -            {
        -            read(FH_IMAGEFILE, $raw, 6);
        -
        -            if ($raw eq 'GIF87a' || $raw eq 'GIF89a')
        -                {
        -                read(FH_IMAGEFILE, $raw, 4);
        -                ($width, $height) = unpack('vv', $raw);
        -                };
        -            }
        -
        -        elsif ($extension eq 'png')
        -            {
        -            read(FH_IMAGEFILE, $raw, 8);
        -
        -            if ($raw eq "\x89PNG\x0D\x0A\x1A\x0A")
        -                {
        -                seek(FH_IMAGEFILE, 4, 1);
        -                read(FH_IMAGEFILE, $raw, 4);
        -
        -                if ($raw eq 'IHDR')
        -                    {
        -                    read(FH_IMAGEFILE, $raw, 8);
        -                    ($width, $height) = unpack('NN', $raw);
        -                    };
        -                };
        -            }
        -
        -        elsif ($extension eq 'bmp')
        -            {
        -            read(FH_IMAGEFILE, $raw, 2);
        -
        -            if ($raw eq 'BM')
        -                {
        -                seek(FH_IMAGEFILE, 16, 1);
        -                read(FH_IMAGEFILE, $raw, 8);
        -
        -                ($width, $height) = unpack('VV', $raw);
        -                };
        -            }
        -
        -        elsif ($extension eq 'jpg' || $extension eq 'jpeg')
        -            {
        -            read(FH_IMAGEFILE, $raw, 2);
        -            my $isOkay = ($raw eq "\xFF\xD8");
        -
        -            while ($isOkay)
        -                {
        -                read(FH_IMAGEFILE, $raw, 4);
        -                my ($marker, $code, $length) = unpack('CCn', $raw);
        -
        -                $isOkay = ($marker eq 0xFF);
        -
        -                if ($isOkay)
        -                    {
        -                    if ($code >= 0xC0 && $code <= 0xC3)
        -                        {
        -                        read(FH_IMAGEFILE, $raw, 5);
        -                        ($height, $width) = unpack('xnn', $raw);
        -                        last;
        -                        }
        -
        -                    else
        -                        {
        -                        $isOkay = seek(FH_IMAGEFILE, $length - 2, 1);
        -                        };
        -                    };
        -                };
        -            };
        -
        -        close(FH_IMAGEFILE);
        -        };
        -
        -
        -    # Sanity check the values.  Although images can theoretically be bigger than 5000, most won't.  The worst that happens in this
        -    # case is just that they don't get length and width values in the output anyway.
        -    if ($width > 0 && $width < 5000 && $height > 0 && $height < 5000)
        -        {  $imageFileObject->SetDimensions($width, $height);  }
        -    else
        -        {  $imageFileObject->SetDimensions(undef, undef);  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Project/ImageFile.pm b/vendor/naturaldocs/Modules/NaturalDocs/Project/ImageFile.pm
        deleted file mode 100644
        index f72adc44e..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Project/ImageFile.pm
        +++ /dev/null
        @@ -1,161 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Project::ImageFile
        -#
        -###############################################################################
        -#
        -#   A simple information class about project image files.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Project::ImageFile;
        -
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are used as indexes.
        -#
        -#       LAST_MODIFIED - The integer timestamp of when the file was last modified.
        -#       STATUS - <FileStatus> since the last build.
        -#       REFERENCE_COUNT - The number of references to the image from the source files.
        -#       WAS_USED - Whether the image was used the last time Natural Docs was run.
        -#       WIDTH - The image width.  Undef if can't be determined, -1 if haven't attempted to determine yet.
        -#       HEIGHT - The image height.  Undef if can't be determined, -1 if haven't attempted to determine yet.
        -#
        -
        -use NaturalDocs::DefineMembers 'LAST_MODIFIED', 'LastModified()', 'SetLastModified()',
        -                                                 'STATUS', 'Status()', 'SetStatus()',
        -                                                 'REFERENCE_COUNT', 'ReferenceCount()',
        -                                                 'WAS_USED', 'WasUsed()', 'SetWasUsed()',
        -                                                 'WIDTH', 'Width()',
        -                                                 'HEIGHT', 'Height()';
        -
        -
        -#
        -#   Topic: WasUsed versus References
        -#
        -#   <WasUsed()> is a simple true/false that notes whether this image file was used the last time Natural Docs was run.
        -#   <ReferenceCount()> is a counter for the number of times it's used *this* run.  As such, it starts at zero regardless of whether
        -#   <WasUsed()> is set or not.
        -#
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new file object.
        -#
        -#   Parameters:
        -#
        -#       lastModified - The image file's last modification timestamp
        -#       status - The <FileStatus>.
        -#       wasUsed - Whether this image file was used the *last* time Natural Docs was run.
        -#
        -sub New #(timestamp lastModified, FileStatus status, bool wasUsed)
        -    {
        -    my ($package, $lastModified, $status, $width, $height, $wasUsed) = @_;
        -
        -    my $object = [ ];
        -    $object->[LAST_MODIFIED] = $lastModified;
        -    $object->[STATUS] = $status;
        -    $object->[REFERENCE_COUNT] = 0;
        -    $object->[WAS_USED] = $wasUsed;
        -    $object->[WIDTH] = -1;
        -    $object->[HEIGHT] = -1;
        -
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Member Functions
        -#
        -#   LastModified - Returns the integer timestamp of when the file was last modified.
        -#   SetLastModified - Sets the file's last modification timestamp.
        -#   Status - Returns the <FileStatus> since the last build.
        -#   SetStatus - Sets the <FileStatus> since the last build.
        -#
        -
        -#
        -#   Function: ReferenceCount
        -#   Returns the current number of references to this image file during *this* Natural Docs execution.
        -#
        -
        -#
        -#   Function: AddReference
        -#   Increases the number of references to this image file by one.  Returns the new reference count.
        -#
        -sub AddReference
        -    {
        -    my $self = shift;
        -
        -    $self->[REFERENCE_COUNT]++;
        -    return $self->[REFERENCE_COUNT];
        -    };
        -
        -#
        -#   Function: DeleteReference
        -#   Decreases the number of references to this image file by one.  Returns the new reference count.
        -#
        -sub DeleteReference
        -    {
        -    my $self = shift;
        -    $self->[REFERENCE_COUNT]--;
        -
        -    if ($self->[REFERENCE_COUNT] < 0)
        -        {  die "Deleted more references to an image file than existed.";  };
        -
        -    return $self->[REFERENCE_COUNT];
        -    };
        -
        -
        -#
        -#   Functions: Member Functions
        -#
        -#   WasUsed - Returns whether this image file was used during the *last* Natural Docs execution.
        -#   SetWasUsed - Sets whether this image file was used during the *last* Natural Docs execution.
        -#   Width - Returns the width in pixels, undef if it can't be determined, and -1 if determination hasn't been attempted yet.
        -#   Height - Returns the width in pixels, undef if it can't be determined, and -1 if determination hasn't been attempted yet.
        -#
        -
        -
        -#
        -#   Function: SetDimensions
        -#   Sets the width and height of the image.  Set to undef if they can't be determined.
        -#
        -sub SetDimensions #(int width, int height)
        -    {
        -    my ($self, $width, $height) = @_;
        -
        -    # If either are undef, both should be undef.  This will also convert zeroes to undef.
        -    if (!$width || !$height)
        -        {
        -        $self->[WIDTH] = undef;
        -        $self->[HEIGHT] = undef;
        -        }
        -    else
        -        {
        -        $self->[WIDTH] = $width;
        -        $self->[HEIGHT] = $height;
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Project/SourceFile.pm b/vendor/naturaldocs/Modules/NaturalDocs/Project/SourceFile.pm
        deleted file mode 100644
        index aff05c7a5..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Project/SourceFile.pm
        +++ /dev/null
        @@ -1,114 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Project::SourceFile
        -#
        -###############################################################################
        -#
        -#   A simple information class about project files.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Project::SourceFile;
        -
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are used as indexes.
        -#
        -#       HAS_CONTENT             - Whether the file contains Natural Docs content or not.
        -#       LAST_MODIFIED           - The integer timestamp of when the file was last modified.
        -#       STATUS                       - <FileStatus> since the last build.
        -#       DEFAULT_MENU_TITLE  - The file's default title in the menu.
        -#
        -
        -# DEPENDENCY: New() depends on its parameter list being in the same order as these constants.  If the order changes, New()
        -# needs to be changed.
        -use NaturalDocs::DefineMembers 'HAS_CONTENT', 'LAST_MODIFIED', 'STATUS', 'DEFAULT_MENU_TITLE';
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new file object.
        -#
        -#   Parameters:
        -#
        -#       hasContent         - Whether the file contains Natural Docs content or not.
        -#       lastModified         - The integer timestamp of when the file was last modified.
        -#       status                 - The <FileStatus> since the last build.
        -#       defaultMenuTitle  - The file's title in the menu.
        -#
        -#   Returns:
        -#
        -#       A reference to the new object.
        -#
        -sub New #(hasContent, lastModified, status, defaultMenuTitle)
        -    {
        -    # DEPENDENCY: This function depends on its parameter list being in the same order as the member constants.  If either order
        -    # changes, this function needs to be changed.
        -
        -    my $package = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -# Function: HasContent
        -# Returns whether the file contains Natural Docs content or not.
        -sub HasContent
        -    {  return $_[0]->[HAS_CONTENT];  };
        -
        -# Function: SetHasContent
        -# Sets whether the file contains Natural Docs content or not.
        -sub SetHasContent #(hasContent)
        -    {  $_[0]->[HAS_CONTENT] = $_[1];  };
        -
        -# Function: LastModified
        -# Returns the integer timestamp of when the file was last modified.
        -sub LastModified
        -    {  return $_[0]->[LAST_MODIFIED];  };
        -
        -# Function: SetLastModified
        -# Sets the file's last modification timestamp.
        -sub SetLastModified #(lastModified)
        -    {  $_[0]->[LAST_MODIFIED] = $_[1];  };
        -
        -# Function: Status
        -# Returns the <FileStatus> since the last build.
        -sub Status
        -    {  return $_[0]->[STATUS];  };
        -
        -# Function: SetStatus
        -# Sets the <FileStatus> since the last build.
        -sub SetStatus #(status)
        -    {  $_[0]->[STATUS] = $_[1];  };
        -
        -# Function: DefaultMenuTitle
        -# Returns the file's default title on the menu.
        -sub DefaultMenuTitle
        -    {  return $_[0]->[DEFAULT_MENU_TITLE];  };
        -
        -# Function: SetDefaultMenuTitle
        -# Sets the file's default title on the menu.
        -sub SetDefaultMenuTitle #(menuTitle)
        -    {  $_[0]->[DEFAULT_MENU_TITLE] = $_[1];  };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/ReferenceString.pm b/vendor/naturaldocs/Modules/NaturalDocs/ReferenceString.pm
        deleted file mode 100644
        index 31fef757b..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/ReferenceString.pm
        +++ /dev/null
        @@ -1,335 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::ReferenceString
        -#
        -###############################################################################
        -#
        -#   A package to manage <ReferenceString> handling throughout the program.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::ReferenceString;
        -
        -use vars '@ISA', '@EXPORT';
        -@ISA = 'Exporter';
        -@EXPORT = ( 'BINARYREF_NOTYPE', 'BINARYREF_NORESOLVINGFLAGS',
        -
        -                     'REFERENCE_TEXT', 'REFERENCE_CH_CLASS', 'REFERENCE_CH_PARENT',
        -
        -                     'RESOLVE_RELATIVE', 'RESOLVE_ABSOLUTE', 'RESOLVE_NOPLURAL', 'RESOLVE_NOUSING' );
        -
        -
        -#
        -#   Constants: Binary Format Flags
        -#
        -#   These flags can be combined to specify the format when using <ToBinaryFile()> and <FromBinaryFile()>.  All are exported
        -#   by default.
        -#
        -#   BINARYREF_NOTYPE - Do not include the <ReferenceType>.
        -#   BINARYREF_NORESOLVEFLAGS - Do not include the <Resolving Flags>.
        -#
        -use constant BINARYREF_NOTYPE => 0x01;
        -use constant BINARYREF_NORESOLVINGFLAGS => 0x02;
        -
        -
        -#
        -#   Constants: ReferenceType
        -#
        -#   The type of a reference.
        -#
        -#       REFERENCE_TEXT - The reference appears in the text of the documentation.
        -#       REFERENCE_CH_CLASS - A class reference handled by <NaturalDocs::ClassHierarchy>.
        -#       REFERENCE_CH_PARENT - A parent class reference handled by <NaturalDocs::ClassHierarchy>.
        -#
        -#   Dependencies:
        -#
        -#       - <ToBinaryFile()> and <FromBinaryFile()> require that these values fit into a UInt8, i.e. are <= 255.
        -#
        -use constant REFERENCE_TEXT => 1;
        -use constant REFERENCE_CH_CLASS => 2;
        -use constant REFERENCE_CH_PARENT => 3;
        -
        -
        -#
        -#   Constants: Resolving Flags
        -#
        -#   Used to influence the method of resolving references in <NaturalDocs::SymbolTable>.
        -#
        -#       RESOLVE_RELATIVE - The reference text is truly relative, rather than Natural Docs' semi-relative.
        -#       RESOLVE_ABSOLUTE - The reference text is always absolute.  No local or relative references.
        -#       RESOLVE_NOPLURAL - The reference text may not be interpreted as a plural, and thus match singular forms as well.
        -#       RESOLVE_NOUSING - The reference text may not include "using" statements when being resolved.
        -#
        -#       If neither <RESOLVE_RELATIVE> or <RESOLVE_ABSOLUTE> is specified, Natural Docs' semi-relative kicks in instead,
        -#       which is where links are interpreted as local, then global, then relative.  <RESOLVE_RELATIVE> states that links are
        -#       local, then relative, then global.
        -#
        -#   Dependencies:
        -#
        -#       - <ToBinaryFile()> and <FromBinaryFile()> require that these values fit into a UInt8, i.e. are <= 255.
        -#
        -use constant RESOLVE_RELATIVE => 0x01;
        -use constant RESOLVE_ABSOLUTE => 0x02;
        -use constant RESOLVE_NOPLURAL => 0x04;
        -use constant RESOLVE_NOUSING => 0x08;
        -
        -
        -#
        -#
        -#   Function: MakeFrom
        -#
        -#   Encodes the passed information as a <ReferenceString>.  The format of the string should be treated as opaque.  However, the
        -#   characteristic you can rely on is that the same string will always be made from the same parameters, and thus it's suitable
        -#   for comparison and use as hash keys.
        -#
        -#   Parameters:
        -#
        -#       type - The <ReferenceType>.
        -#       symbol - The <SymbolString> of the reference.
        -#       language - The name of the language that defines the file this reference appears in.
        -#       scope - The scope <SymbolString> the reference appears in, or undef if none.
        -#       using - An arrayref of scope <SymbolStrings> that are also available for checking due to the equivalent a "using" statement,
        -#                  or undef if none.
        -#       resolvingFlags - The <Resolving Flags> to use with this reference.  They are ignored if the type is <REFERENCE_TEXT>.
        -#
        -#   Returns:
        -#
        -#       The encoded <ReferenceString>.
        -#
        -sub MakeFrom #(ReferenceType type, SymbolString symbol, string language, SymbolString scope, SymbolString[]* using, flags resolvingFlags)
        -    {
        -    my ($self, $type, $symbol, $language, $scope, $using, $resolvingFlags) = @_;
        -
        -    if ($type == ::REFERENCE_TEXT() || $resolvingFlags == 0)
        -       {  $resolvingFlags = undef;  };
        -
        -    # The format is [type] 0x1E [resolving flags] 0x1E [symbol] 0x1E [scope] ( 0x1E [using] )*
        -    # If there is no scope and/or using, the separator characters still remain.
        -
        -    # DEPENDENCY: SymbolString->FromText() removed all 0x1E characters.
        -    # DEPENDENCY: SymbolString->FromText() doesn't use 0x1E characters in its encoding.
        -
        -    my $string = $type . "\x1E" . $symbol . "\x1E" . $language . "\x1E" . $resolvingFlags . "\x1E";
        -
        -    if (defined $scope)
        -        {
        -        $string .= $scope;
        -        };
        -
        -    $string .= "\x1E";
        -
        -    if (defined $using)
        -        {
        -        $string .= join("\x1E", @$using);
        -        };
        -
        -    return $string;
        -    };
        -
        -
        -#
        -#   Function: ToBinaryFile
        -#
        -#   Writes a <ReferenceString> to the passed filehandle.  Can also encode an undef.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The filehandle to write to.
        -#       referenceString - The <ReferenceString> to write, or undef.
        -#       binaryFormatFlags - Any <Binary Format Flags> you want to use to influence encoding.
        -#
        -#   Format:
        -#
        -#       > [SymbolString: Symbol or undef for an undef reference]
        -#       > [AString16: language]
        -#       > [SymbolString: Scope or undef for none]
        -#       >
        -#       > [SymbolString: Using or undef for none]
        -#       > [SymbolString: Using or undef for no more]
        -#       > ...
        -#       >
        -#       > [UInt8: Type unless BINARYREF_NOTYPE is set]
        -#       > [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
        -#
        -#   Dependencies:
        -#
        -#       - <ReferenceTypes> must fit into a UInt8.  All values must be <= 255.
        -#       - All <Resolving Flags> must fit into a UInt8.  All values must be <= 255.
        -#
        -sub ToBinaryFile #(FileHandle fileHandle, ReferenceString referenceString, flags binaryFormatFlags)
        -    {
        -    my ($self, $fileHandle, $referenceString, $binaryFormatFlags) = @_;
        -
        -    my ($type, $symbol, $language, $scope, $using, $resolvingFlags) = $self->InformationOf($referenceString);
        -
        -    # [SymbolString: Symbol or undef for an undef reference]
        -
        -    NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $symbol);
        -
        -    # [AString16: language]
        -
        -    print $fileHandle pack('nA*', length $language, $language);
        -
        -    # [SymbolString: scope or undef if none]
        -
        -    NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $scope);
        -
        -    # [SymbolString: using or undef if none/no more] ...
        -
        -    if (defined $using)
        -        {
        -        foreach my $usingScope (@$using)
        -            {  NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $usingScope);  };
        -        };
        -
        -    NaturalDocs::SymbolString->ToBinaryFile($fileHandle, undef);
        -
        -    # [UInt8: Type unless BINARYREF_NOTYPE is set]
        -
        -    if (!($binaryFormatFlags & BINARYREF_NOTYPE))
        -        {  print $fileHandle pack('C', $type);  };
        -
        -    # [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
        -
        -    if (!($binaryFormatFlags & BINARYREF_NORESOLVINGFLAGS))
        -        {  print $fileHandle pack('C', $type);  };
        -    };
        -
        -
        -#
        -#   Function: FromBinaryFile
        -#
        -#   Reads a <ReferenceString> or undef from the passed filehandle.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The filehandle to read from.
        -#       binaryFormatFlags - Any <Binary Format Flags> you want to use to influence decoding.
        -#       type - The <ReferenceType> to use if <BINARYREF_NOTYPE> is set.
        -#       resolvingFlags - The <Resolving Flags> to use if <BINARYREF_NORESOLVINGFLAGS> is set.
        -#
        -#   Returns:
        -#
        -#       The <ReferenceString> or undef.
        -#
        -#   See Also:
        -#
        -#       See <ToBinaryFile()> for format and dependencies.
        -#
        -sub FromBinaryFile #(FileHandle fileHandle, flags binaryFormatFlags, ReferenceType type, flags resolvingFlags)
        -    {
        -    my ($self, $fileHandle, $binaryFormatFlags, $type, $resolvingFlags) = @_;
        -    my $raw;
        -
        -    # [SymbolString: Symbol or undef for an undef reference]
        -
        -    my $symbol = NaturalDocs::SymbolString->FromBinaryFile($fileHandle);
        -
        -    if (!defined $symbol)
        -        {  return undef;  };
        -
        -
        -    # [AString16: language]
        -
        -    read($fileHandle, $raw, 2);
        -    my $languageLength = unpack('n', $raw);
        -
        -    my $language;
        -    read($fileHandle, $language, $languageLength);
        -
        -
        -    # [SymbolString: scope or undef if none]
        -
        -    my $scope = NaturalDocs::SymbolString->FromBinaryFile($fileHandle);
        -
        -    # [SymbolString: using or undef if none/no more] ...
        -
        -    my $usingSymbol;
        -    my @using;
        -
        -    while ($usingSymbol = NaturalDocs::SymbolString->FromBinaryFile($fileHandle))
        -        {  push @using, $usingSymbol;  };
        -
        -    if (scalar @using)
        -        {  $usingSymbol = \@using;  }
        -    else
        -        {  $usingSymbol = undef;  };
        -
        -    # [UInt8: Type unless BINARYREF_NOTYPE is set]
        -
        -    if (!($binaryFormatFlags & BINARYREF_NOTYPE))
        -        {
        -        my $raw;
        -        read($fileHandle, $raw, 1);
        -        $type = unpack('C', $raw);
        -        };
        -
        -    # [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
        -
        -    if (!($binaryFormatFlags & BINARYREF_NORESOLVINGFLAGS))
        -        {
        -        my $raw;
        -        read($fileHandle, $raw, 1);
        -        $resolvingFlags = unpack('C', $raw);
        -        };
        -
        -    return $self->MakeFrom($type, $symbol, $language, $scope, $usingSymbol, $resolvingFlags);
        -    };
        -
        -
        -#
        -#   Function: InformationOf
        -#
        -#   Returns the information encoded in a <ReferenceString>.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> to decode.
        -#
        -#   Returns:
        -#
        -#       The array ( type, symbol, language, scope, using, resolvingFlags ).
        -#
        -#       type - The <ReferenceType>.
        -#       symbol - The <SymbolString>.
        -#       language - The name of the language that defined the file the reference was defined in.
        -#       scope - The scope <SymbolString>, or undef if none.
        -#       using - An arrayref of scope <SymbolStrings> that the reference also has access to via "using" statements, or undef if none.
        -#       resolvingFlags - The <Resolving Flags> of the reference.
        -#
        -sub InformationOf #(ReferenceString referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    my ($type, $symbolString, $language, $resolvingFlags, $scopeString, @usingStrings) = split(/\x1E/, $referenceString);
        -
        -    if (!length $resolvingFlags)
        -        {  $resolvingFlags = undef;  };
        -
        -    return ( $type, $symbolString, $language, $scopeString, [ @usingStrings ], $resolvingFlags );
        -    };
        -
        -
        -#
        -#   Function: TypeOf
        -#
        -#   Returns the <ReferenceType> encoded in the reference string.  This is faster than <InformationOf()> if this is
        -#   the only information you need.
        -#
        -sub TypeOf #(ReferenceString referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    $referenceString =~ /^([^\x1E]+)/;
        -    return $1;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Settings.pm b/vendor/naturaldocs/Modules/NaturalDocs/Settings.pm
        deleted file mode 100644
        index a9ed60c66..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Settings.pm
        +++ /dev/null
        @@ -1,1480 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Settings
        -#
        -###############################################################################
        -#
        -#   A package to handle the command line and various other program settings.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use Cwd ();
        -
        -use NaturalDocs::Settings::BuildTarget;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Settings;
        -
        -
        -###############################################################################
        -# Group: Information
        -
        -=pod begin nd
        -
        -    Topic: Usage and Dependencies
        -
        -        - The <Constant Functions> can be called immediately.
        -
        -        - Prior to initialization, <NaturalDocs::Builder> must have all its output packages registered.
        -
        -        - To initialize, call <Load()>.  All functions except <InputDirectoryNameOf()> will then be available.
        -
        -        - <GenerateDirectoryNames()> must be called before <InputDirectoryNameOf()> will work.  Currently it is called by
        -          <NaturalDocs::Menu->LoadAndUpdate()>.
        -
        -
        -    Architecture: Internal Overview
        -
        -        - <Load()> first parses the command line, gathering all the settings and checking for errors.  All <NaturalDocs::Builder>
        -          packages must be registered before this is called because it needs their command line options.
        -          <NaturalDocs::Project->ReparseEverything()> and <NaturalDocs::Project->RebuildEverything()> are called right away if -r
        -          or -ro are used.
        -
        -        - Output directories are *not* named at this point.  See <Named Directories>.
        -
        -        - The previous settings from the last time Natural Docs was run are loaded and compared to the current settings.
        -          <NaturalDocs::Project->ReparseEverything()> and <NaturalDocs::Project->RebuildEverything()> are called if there are
        -          any differences that warrant it.
        -
        -        - It then waits for <GenerateDirectoryNames()> to be called by <NaturalDocs::Menu>.  The reason for this is that the
        -          previous directory names are stored as hints in the menu file, for reasons explained in <Named Directories>.  Once that
        -          happens all the unnamed directories have names generated for them so everything is named.  The package is completely
        -          set up.
        -
        -        - The input directories are stored in an array instead of a hash because the order they were declared in matters.  If two
        -          people use multiple input directories on separate computers without sharing a menu file, they should at least get consistent
        -          directory names by declaring them in the same order.
        -
        -
        -    Architecture: Named Directories
        -
        -        Ever since Natural Docs introduced multiple input directories in 1.16, they've had to be named.  Since they don't necessarily
        -        extend from the same root anymore, they can't share an output directory without the risk of file name conflicts.  There was
        -        an early attempt at giving them actual names, but now they're just numbered from 1.
        -
        -        Directory names aren't generated right away.  It waits for <Menu.txt> to load because that holds the obfuscated names from
        -        the last run.  <NaturalDocs::Menu> then calls <GenerateDirectoryNames()> and passes those along as hints.
        -        <GenerateDirectoryNames()> then applies them to any matches and generates new ones for any remaining.  This is done so
        -        that output page locations can remain consistent when built on multiple computers, so long as the menu file is shared.  I tend
        -        to think the menu file is the most likely configuration file to be shared.
        -
        -
        -    Architecture: Removed Directories
        -
        -        Directories that were part of the previous run but aren't anymore are still stored in the package.  The primary reason, though
        -        there may be others, is file purging.  If an input directory is removed, all the output files that were generated from anything
        -        in it need to be removed.  To find out what the output file name was for a removed source file, it needs to be able to split it
        -        from it's original input directory and know what that directory was named.  If this didn't happen those output files would be
        -        orphaned, as was the case prior to 1.32.
        -
        -=cut
        -
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -# handle: PREVIOUS_SETTINGS_FILEHANDLE
        -# The file handle used with <PreviousSettings.nd>.
        -
        -# array: inputDirectories
        -# An array of input directories.
        -my @inputDirectories;
        -
        -# array: inputDirectoryNames
        -# An array of the input directory names.  Each name corresponds to the directory of the same index in <inputDirectories>.
        -my @inputDirectoryNames;
        -
        -# array: imageDirectories
        -# An array of image directories.
        -my @imageDirectories;
        -
        -# array: imageDirectoryNames
        -# An array of the image directory names.  Each name corresponds to the directory of the same index in <imageDirectories>.
        -my @imageDirectoryNames;
        -
        -# array: relativeImageDirectories
        -# An array of the relative paths for images.  The asterisks found in the command line are not present.
        -my @relativeImageDirectories;
        -
        -# array: excludedInputDirectories
        -# An array of input directories to exclude.
        -my @excludedInputDirectories;
        -
        -# array: removedInputDirectories
        -# An array of input directories that were once in the command line but are no longer.
        -my @removedInputDirectories;
        -
        -# array: removedInputDirectoryNames
        -# An array of the removed input directories' names.  Each name corresponds to the directory of the same index in
        -# <removedInputDirectories>.
        -my @removedInputDirectoryNames;
        -
        -# array: removedImageDirectories
        -# An array of image directories that were once in the command line but are no longer.
        -my @removedImageDirectories;
        -
        -# array: removedImageDirectoryNames
        -# An array of the removed image directories' names.  Each name corresponds to the directory of the same index in
        -# <removedImageDirectories>.
        -my @removedImageDirectoryNames;
        -
        -# var: projectDirectory
        -# The project directory.
        -my $projectDirectory;
        -
        -# array: buildTargets
        -# An array of <NaturalDocs::Settings::BuildTarget>s.
        -my @buildTargets;
        -
        -# var: documentedOnly
        -# Whether undocumented code aspects should be included in the output.
        -my $documentedOnly;
        -
        -# int: tabLength
        -# The number of spaces in tabs.
        -my $tabLength;
        -
        -# bool: noAutoGroup
        -# Whether auto-grouping is turned off.
        -my $noAutoGroup;
        -
        -# bool: onlyFileTitles
        -# Whether source files should always use the file name as the title.
        -my $onlyFileTitles;
        -
        -# bool: isQuiet
        -# Whether the script should be run in quiet mode or not.
        -my $isQuiet;
        -
        -# bool: rebuildData
        -# WHether most data files should be ignored and rebuilt.
        -my $rebuildData;
        -
        -# array: styles
        -# An array of style names to use, most important first.
        -my @styles;
        -
        -# var: highlightCode
        -# Whether syntax highlighting should be applied to code tags.
        -my $highlightCode;
        -
        -# var: highlightAnonymous
        -# Whether syntax highlighting should be applied to anonymous code tags.
        -my $highlightAnonymous;
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: PreviousSettings.nd
        -#
        -#   Stores the previous command line settings.
        -#
        -#   Format:
        -#
        -#       > [BINARY_FORMAT]
        -#       > [VersionInt: app version]
        -#
        -#       The file starts with the standard <BINARY_FORMAT> <VersionInt> header.
        -#
        -#       > [UInt8: tab length]
        -#       > [UInt8: documented only (0 or 1)]
        -#       > [UInt8: no auto-group (0 or 1)]
        -#       > [UInt8: only file titles (0 or 1)]
        -#		> [UInt8: highlight code (0 or 1)]
        -#		> [UInt8: highlight anonymous (0 or 1)]
        -#       >
        -#       > [UInt8: number of input directories]
        -#       > [AString16: input directory] [AString16: input directory name] ...
        -#
        -#       A count of input directories, then that number of directory/name pairs.
        -#
        -#       > [UInt8: number of output targets]
        -#       > [AString16: output directory] [AString16: output format command line option] ...
        -#
        -#       A count of output targets, then that number of directory/format pairs.
        -#
        -#
        -#   Revisions:
        -#
        -#		1.51:
        -#
        -#			- Removed charset.
        -#
        -#		1.5:
        -#
        -#			- Added highlight code and highlight anonymous.
        -#
        -#       1.4:
        -#
        -#           - Added only file titles.
        -#
        -#       1.33:
        -#
        -#           - Added charset.
        -#
        -#       1.3:
        -#
        -#           - Removed headers-only, which was a 0/1 UInt8 after tab length.
        -#           - Change auto-group level (1 = no, 2 = yes, 3 = full only) to no auto-group (0 or 1).
        -#
        -#       1.22:
        -#
        -#           - Added auto-group level.
        -#
        -#       1.2:
        -#
        -#           - File was added to the project.  Prior to 1.2, it didn't exist.
        -#
        -
        -
        -###############################################################################
        -# Group: Action Functions
        -
        -#
        -#   Function: Load
        -#
        -#   Loads and parses all settings from the command line and configuration files.  Will exit if the options are invalid or the syntax
        -#   reference was requested.
        -#
        -sub Load
        -    {
        -    my ($self) = @_;
        -
        -    $self->ParseCommandLine();
        -    $self->LoadAndComparePreviousSettings();
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves all settings in configuration files to disk.
        -#
        -sub Save
        -    {
        -    my ($self) = @_;
        -
        -    $self->SavePreviousSettings();
        -    };
        -
        -
        -#
        -#   Function: GenerateDirectoryNames
        -#
        -#   Generates names for each of the input and image directories, which can later be retrieved with <InputDirectoryNameOf()>
        -#   and <ImageDirectoryNameOf()>.
        -#
        -#   Parameters:
        -#
        -#       inputHints - A hashref of suggested input directory names, where the keys are the directories and the values are the names.
        -#                        These take precedence over anything generated.  You should include names for directories that are no longer in
        -#                        the command line.  This parameter may be undef.
        -#       imageHints - Same as inputHints, only for the image directories.
        -#
        -sub GenerateDirectoryNames #(hashref inputHints, hashref imageHints)
        -    {
        -    my ($self, $inputHints, $imageHints) = @_;
        -
        -    my %usedInputNames;
        -    my %usedImageNames;
        -
        -
        -    if (defined $inputHints)
        -        {
        -        # First, we have to convert all non-numeric names to numbers, since they may come from a pre-1.32 menu file.  We do it
        -        # here instead of in NaturalDocs::Menu to keep the naming scheme centralized.
        -
        -        my @names = values %$inputHints;
        -        my $hasNonNumeric;
        -
        -        foreach my $name (@names)
        -            {
        -            if ($name !~ /^[0-9]+$/)
        -                {
        -                $hasNonNumeric = 1;
        -                last;
        -                };
        -            };
        -
        -
        -        if ($hasNonNumeric)
        -            {
        -            # Hash mapping old names to new names.
        -            my %conversion;
        -
        -            # The sequential number to use.  Starts at two because we want 'default' to be one.
        -            my $currentNumber = 2;
        -
        -            # If there's only one name, we set it to one no matter what it was set to before.
        -            if (scalar @names == 1)
        -                {  $conversion{$names[0]} = 1;  }
        -            else
        -                {
        -                # We sort the list first because we want the end result to be predictable.  This conversion could be happening on many
        -                # machines, and they may not all specify the input directories in the same order.  They need to all come up with the
        -                # same result.
        -                @names = sort @names;
        -
        -                foreach my $name (@names)
        -                    {
        -                    if ($name eq 'default')
        -                        {  $conversion{$name} = 1;  }
        -                    else
        -                        {
        -                        $conversion{$name} = $currentNumber;
        -                        $currentNumber++;
        -                        };
        -                    };
        -                };
        -
        -            # Convert them to the new names.
        -            foreach my $directory (keys %$inputHints)
        -                {
        -                $inputHints->{$directory} = $conversion{ $inputHints->{$directory} };
        -                };
        -            };
        -
        -
        -        # Now we apply all the names from the hints, and save any unused ones as removed directories.
        -
        -        for (my $i = 0; $i < scalar @inputDirectories; $i++)
        -            {
        -            if (exists $inputHints->{$inputDirectories[$i]})
        -                {
        -                $inputDirectoryNames[$i] = $inputHints->{$inputDirectories[$i]};
        -                $usedInputNames{ $inputDirectoryNames[$i] } = 1;
        -                delete $inputHints->{$inputDirectories[$i]};
        -                };
        -            };
        -
        -
        -        # Any remaining hints are saved as removed directories.
        -
        -        while (my ($directory, $name) = each %$inputHints)
        -            {
        -            push @removedInputDirectories, $directory;
        -            push @removedInputDirectoryNames, $name;
        -            };
        -        };
        -
        -
        -    if (defined $imageHints)
        -        {
        -        # Image directory names were never non-numeric, so there is no conversion.  Apply all the names from the hints.
        -
        -        for (my $i = 0; $i < scalar @imageDirectories; $i++)
        -            {
        -            if (exists $imageHints->{$imageDirectories[$i]})
        -                {
        -                $imageDirectoryNames[$i] = $imageHints->{$imageDirectories[$i]};
        -                $usedImageNames{ $imageDirectoryNames[$i] } = 1;
        -                delete $imageHints->{$imageDirectories[$i]};
        -                };
        -            };
        -
        -
        -        # Any remaining hints are saved as removed directories.
        -
        -        while (my ($directory, $name) = each %$imageHints)
        -            {
        -            push @removedImageDirectories, $directory;
        -            push @removedImageDirectoryNames, $name;
        -            };
        -        };
        -
        -
        -    # Now we generate names for anything remaining.
        -
        -    my $inputCounter = 1;
        -
        -    for (my $i = 0; $i < scalar @inputDirectories; $i++)
        -        {
        -        if (!defined $inputDirectoryNames[$i])
        -            {
        -            while (exists $usedInputNames{$inputCounter})
        -                {  $inputCounter++;  };
        -
        -            $inputDirectoryNames[$i] = $inputCounter;
        -            $usedInputNames{$inputCounter} = 1;
        -
        -            $inputCounter++;
        -            };
        -        };
        -
        -
        -    my $imageCounter = 1;
        -
        -    for (my $i = 0; $i < scalar @imageDirectories; $i++)
        -        {
        -        if (!defined $imageDirectoryNames[$i])
        -            {
        -            while (exists $usedImageNames{$imageCounter})
        -                {  $imageCounter++;  };
        -
        -            $imageDirectoryNames[$i] = $imageCounter;
        -            $usedImageNames{$imageCounter} = 1;
        -
        -            $imageCounter++;
        -            };
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -
        -#
        -#   Function: InputDirectories
        -#
        -#   Returns an arrayref of input directories.  Do not change.
        -#
        -#   This will not return any removed input directories.
        -#
        -sub InputDirectories
        -    {  return \@inputDirectories;  };
        -
        -#
        -#   Function: InputDirectoryNameOf
        -#
        -#   Returns the generated name of the passed input directory.  <GenerateDirectoryNames()> must be called once before this
        -#   function is available.
        -#
        -#   If a name for a removed input directory is available, it will be returned as well.
        -#
        -sub InputDirectoryNameOf #(directory)
        -    {
        -    my ($self, $directory) = @_;
        -
        -    for (my $i = 0; $i < scalar @inputDirectories; $i++)
        -        {
        -        if ($directory eq $inputDirectories[$i])
        -            {  return $inputDirectoryNames[$i];  };
        -        };
        -
        -    for (my $i = 0; $i < scalar @removedInputDirectories; $i++)
        -        {
        -        if ($directory eq $removedInputDirectories[$i])
        -            {  return $removedInputDirectoryNames[$i];  };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: SplitFromInputDirectory
        -#
        -#   Takes an input file name and returns the array ( inputDirectory, relativePath ).
        -#
        -#   If the file cannot be split from an input directory, it will try to do it with the removed input directories.
        -#
        -sub SplitFromInputDirectory #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    foreach my $directory (@inputDirectories, @removedInputDirectories)
        -        {
        -        if (NaturalDocs::File->IsSubPathOf($directory, $file))
        -            {  return ( $directory, NaturalDocs::File->MakeRelativePath($directory, $file) );  };
        -        };
        -
        -    return ( );
        -    };
        -
        -
        -#
        -#   Function: ImageDirectories
        -#
        -#   Returns an arrayref of image directories.  Do not change.
        -#
        -#   This will not return any removed image directories.
        -#
        -sub ImageDirectories
        -    {  return \@imageDirectories;  };
        -
        -
        -#
        -#   Function: ImageDirectoryNameOf
        -#
        -#   Returns the generated name of the passed image or input directory.  <GenerateDirectoryNames()> must be called once before
        -#   this function is available.
        -#
        -#   If a name for a removed input or image directory is available, it will be returned as well.
        -#
        -sub ImageDirectoryNameOf #(directory)
        -    {
        -    my ($self, $directory) = @_;
        -
        -    for (my $i = 0; $i < scalar @imageDirectories; $i++)
        -        {
        -        if ($directory eq $imageDirectories[$i])
        -            {  return $imageDirectoryNames[$i];  };
        -        };
        -
        -    for (my $i = 0; $i < scalar @removedImageDirectories; $i++)
        -        {
        -        if ($directory eq $removedImageDirectories[$i])
        -            {  return $removedImageDirectoryNames[$i];  };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -#
        -#   Function: SplitFromImageDirectory
        -#
        -#   Takes an input image file name and returns the array ( imageDirectory, relativePath ).
        -#
        -#   If the file cannot be split from an image directory, it will try to do it with the removed image directories.
        -#
        -sub SplitFromImageDirectory #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    foreach my $directory (@imageDirectories, @removedImageDirectories)
        -        {
        -        if (NaturalDocs::File->IsSubPathOf($directory, $file))
        -            {  return ( $directory, NaturalDocs::File->MakeRelativePath($directory, $file) );  };
        -        };
        -
        -    return ( );
        -    };
        -
        -
        -#
        -#   Function: RelativeImageDirectories
        -#
        -#   Returns an arrayref of relative image directories.  Do not change.
        -#
        -sub RelativeImageDirectories
        -    {  return \@relativeImageDirectories;  };
        -
        -
        -# Function: ExcludedInputDirectories
        -# Returns an arrayref of input directories to exclude.  Do not change.
        -sub ExcludedInputDirectories
        -    {  return \@excludedInputDirectories;  };
        -
        -
        -# Function: BuildTargets
        -# Returns an arrayref of <NaturalDocs::Settings::BuildTarget>s.  Do not change.
        -sub BuildTargets
        -    {  return \@buildTargets;  };
        -
        -
        -#
        -#   Function: OutputDirectoryOf
        -#
        -#   Returns the output directory of a builder object.
        -#
        -#   Parameters:
        -#
        -#       object - The builder object, whose class is derived from <NaturalDocs::Builder::Base>.
        -#
        -#   Returns:
        -#
        -#       The builder directory, or undef if the object wasn't found..
        -#
        -sub OutputDirectoryOf #(object)
        -    {
        -    my ($self, $object) = @_;
        -
        -    foreach my $buildTarget (@buildTargets)
        -        {
        -        if ($buildTarget->Builder() == $object)
        -            {  return $buildTarget->Directory();  };
        -        };
        -
        -    return undef;
        -    };
        -
        -
        -# Function: Styles
        -# Returns an arrayref of the styles associated with the output.
        -sub Styles
        -    {  return \@styles;  };
        -
        -# Function: ProjectDirectory
        -# Returns the project directory.
        -sub ProjectDirectory
        -    {  return $projectDirectory;  };
        -
        -# Function: ProjectDataDirectory
        -# Returns the project data directory.
        -sub ProjectDataDirectory
        -    {  return NaturalDocs::File->JoinPaths($projectDirectory, 'Data', 1);  };
        -
        -# Function: StyleDirectory
        -# Returns the main style directory.
        -sub StyleDirectory
        -    {  return NaturalDocs::File->JoinPaths($FindBin::RealBin, 'Styles', 1);  };
        -
        -# Function: JavaScriptDirectory
        -# Returns the main JavaScript directory.
        -sub JavaScriptDirectory
        -    {  return NaturalDocs::File->JoinPaths($FindBin::RealBin, 'JavaScript', 1);  };
        -
        -# Function: ConfigDirectory
        -# Returns the main configuration directory.
        -sub ConfigDirectory
        -    {  return NaturalDocs::File->JoinPaths($FindBin::RealBin, 'Config', 1);  };
        -
        -# Function: DocumentedOnly
        -# Returns whether undocumented code aspects should be included in the output.
        -sub DocumentedOnly
        -    {  return $documentedOnly;  };
        -
        -# Function: TabLength
        -# Returns the number of spaces tabs should be expanded to.
        -sub TabLength
        -    {  return $tabLength;  };
        -
        -# Function: NoAutoGroup
        -# Returns whether auto-grouping is turned off.
        -sub NoAutoGroup
        -    {  return $noAutoGroup;  };
        -
        -# Function: OnlyFileTitles
        -# Returns whether source files should always use the file name as the title.
        -sub OnlyFileTitles
        -    {  return $onlyFileTitles;  };
        -
        -# Function: IsQuiet
        -# Returns whether the script should be run in quiet mode or not.
        -sub IsQuiet
        -    {  return $isQuiet;  };
        -
        -# Function: RebuildData
        -# Returns whether all data files should be ignored and rebuilt.
        -sub RebuildData
        -    {  return $rebuildData;  };
        -
        -# Function: HighlightCode
        -# Returns whether to apply syntax highlighting (start code) sections.
        -sub HighlightCode
        -	{  return $highlightCode;  }
        -
        -# Function: HighlightAnonymous
        -# Returns whether to apply syntax highlighting to anonymous code sections designated with :, >, or |.
        -sub HighlightAnonymous
        -	{  return $highlightAnonymous;  }
        -
        -
        -###############################################################################
        -# Group: Constant Functions
        -
        -#
        -#   Function: AppVersion
        -#
        -#   Returns Natural Docs' version number as an integer.  Use <TextAppVersion()> to get a printable version.
        -#
        -sub AppVersion
        -    {
        -    my ($self) = @_;
        -    return NaturalDocs::Version->FromString($self->TextAppVersion());
        -    };
        -
        -#
        -#   Function: TextAppVersion
        -#
        -#   Returns Natural Docs' version number as plain text.
        -#
        -sub TextAppVersion
        -    {
        -    return '1.51';
        -    };
        -
        -#
        -#   Function: AppURL
        -#
        -#   Returns a string of the project's current web address.
        -#
        -sub AppURL
        -    {  return 'http://www.naturaldocs.org';  };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: ParseCommandLine
        -#
        -#   Parses and validates the command line.  Will cause the script to exit if the options ask for the syntax reference or
        -#   are invalid.
        -#
        -sub ParseCommandLine
        -    {
        -    my ($self) = @_;
        -
        -    my %synonyms = ( 'input'    => '-i',
        -                                  'source' => '-i',
        -                                  'excludeinput' => '-xi',
        -                                  'excludesource' => '-xi',
        -                                  'images' => '-img',
        -                                  'output'  => '-o',
        -                                  'project' => '-p',
        -                                  'documentedonly' => '-do',
        -                                  'style'    => '-s',
        -                                  'rebuild' => '-r',
        -                                  'rebuildoutput' => '-ro',
        -                                  'tablength' => '-t',
        -                                  'quiet'    => '-q',
        -                                  'headersonly' => '-ho',
        -                                  'help'     => '-h',
        -                                  'autogroup' => '-ag',
        -                                  'noautogroup' => '-nag',
        -                                  'onlyfiletitles' => '-oft',
        -                                  'onlyfiletitle' => '-oft',
        -                                  'highlight' => '-hl',
        -                                  'highlighting' => '-hl' );
        -
        -
        -    my @errorMessages;
        -
        -    my $valueRef;
        -    my $option;
        -
        -    my @outputStrings;
        -    my @imageStrings;
        -    my $highlightString;
        -
        -
        -    # Sometimes $valueRef is set to $ignored instead of undef because we don't want certain errors to cause other,
        -    # unnecessary errors.  For example, if they set the input directory twice, we want to show that error and swallow the
        -    # specified directory without complaint.  Otherwise it would complain about the directory too as if it were random crap
        -    # inserted into the command line.
        -    my $ignored;
        -
        -    my $index = 0;
        -
        -    while ($index < scalar @ARGV)
        -        {
        -        my $arg = $ARGV[$index];
        -
        -        if (substr($arg, 0, 1) eq '-')
        -            {
        -            $option = lc($arg);
        -
        -            # Support options like -t2 as well as -t 2.
        -            if ($option =~ /^([^0-9]+)([0-9]+)$/)
        -                {
        -                $option = $1;
        -                splice(@ARGV, $index + 1, 0, $2);
        -                };
        -
        -            # Convert long forms to short.
        -            if (substr($option, 1, 1) eq '-')
        -                {
        -                # Strip all dashes.
        -                my $newOption = $option;
        -                $newOption =~ tr/-//d;
        -
        -                if (exists $synonyms{$newOption})
        -                    {  $option = $synonyms{$newOption};  }
        -                }
        -
        -            if ($option eq '-i')
        -                {
        -                push @inputDirectories, undef;
        -                $valueRef = \$inputDirectories[-1];
        -                }
        -            elsif ($option eq '-xi')
        -                {
        -                push @excludedInputDirectories, undef;
        -                $valueRef = \$excludedInputDirectories[-1];
        -                }
        -            elsif ($option eq '-img')
        -                {
        -                push @imageStrings, undef;
        -                $valueRef = \$imageStrings[-1];
        -                }
        -            elsif ($option eq '-p')
        -                {
        -                if (defined $projectDirectory)
        -                    {
        -                    push @errorMessages, 'You cannot have more than one project directory.';
        -                    $valueRef = \$ignored;
        -                    }
        -                else
        -                    {  $valueRef = \$projectDirectory;  };
        -                }
        -            elsif ($option eq '-o')
        -                {
        -                push @outputStrings, undef;
        -                $valueRef = \$outputStrings[-1];
        -                }
        -            elsif ($option eq '-s')
        -                {
        -                $valueRef = \$styles[0];
        -                }
        -            elsif ($option eq '-t')
        -                {
        -                $valueRef = \$tabLength;
        -                }
        -            elsif ($option eq '-hl')
        -            	{
        -            	$valueRef = \$highlightString;
        -            	}
        -            elsif ($option eq '-ag')
        -                {
        -                push @errorMessages, 'The -ag setting is no longer supported.  You can use -nag (--no-auto-group) to turn off '
        -                                               . "auto-grouping, but there aren't multiple levels anymore.";
        -                $valueRef = \$ignored;
        -                }
        -
        -            # Options that aren't followed by content.
        -            else
        -                {
        -                $valueRef = undef;
        -
        -                if ($option eq '-r')
        -                    {
        -                    NaturalDocs::Project->ReparseEverything();
        -                    NaturalDocs::Project->RebuildEverything();
        -                    $rebuildData = 1;
        -                    }
        -                elsif ($option eq '-ro')
        -                    {
        -                    NaturalDocs::Project->RebuildEverything();
        -                    }
        -                elsif ($option eq '-do')
        -                    {  $documentedOnly = 1;  }
        -                elsif ($option eq '-oft')
        -                    {  $onlyFileTitles = 1;  }
        -                elsif ($option eq '-q')
        -                    {  $isQuiet = 1;  }
        -                elsif ($option eq '-ho')
        -                    {
        -                    push @errorMessages, 'The -ho setting is no longer supported.  You can have Natural Docs skip over the source file '
        -                                                   . 'extensions by editing Languages.txt in your project directory.';
        -                    }
        -                elsif ($option eq '-nag')
        -                    {  $noAutoGroup = 1;  }
        -                elsif ($option eq '-?' || $option eq '-h')
        -                    {
        -                    $self->PrintSyntax();
        -                    exit;
        -                    }
        -                else
        -                    {  push @errorMessages, 'Unrecognized option ' . $option;  };
        -
        -                };
        -
        -            }
        -
        -        # Is a segment of text, not an option...
        -        else
        -            {
        -            if (defined $valueRef)
        -                {
        -                # We want to preserve spaces in paths.
        -                if (defined $$valueRef)
        -                    {  $$valueRef .= ' ';  };
        -
        -                $$valueRef .= $arg;
        -                }
        -
        -            else
        -                {
        -                push @errorMessages, 'Unrecognized element ' . $arg;
        -                };
        -            };
        -
        -        $index++;
        -        };
        -
        -
        -    # Validate the style, if specified.
        -
        -    if ($styles[0])
        -        {
        -        my @stylePieces = split(/ +/, $styles[0]);
        -        @styles = ( );
        -
        -        while (scalar @stylePieces)
        -            {
        -            if (lc($stylePieces[0]) eq 'custom')
        -                {
        -                push @errorMessages, 'The "Custom" style setting is no longer supported.  Copy your custom style sheet to your '
        -                                               . 'project directory and you can refer to it with -s.';
        -                shift @stylePieces;
        -                }
        -            else
        -                {
        -                # People may use styles with spaces in them.  If a style doesn't exist, we need to join the pieces until we find one that
        -                # does or we run out of pieces.
        -
        -                my $extras = 0;
        -                my $success;
        -
        -                while ($extras < scalar @stylePieces)
        -                    {
        -                    my $style;
        -
        -                    if (!$extras)
        -                        {  $style = $stylePieces[0];  }
        -                    else
        -                        {  $style = join(' ', @stylePieces[0..$extras]);  };
        -
        -                    my $cssFile = NaturalDocs::File->JoinPaths( $self->StyleDirectory(), $style . '.css' );
        -                    if (-e $cssFile)
        -                        {
        -                        push @styles, $style;
        -                        splice(@stylePieces, 0, 1 + $extras);
        -                        $success = 1;
        -                        last;
        -                        }
        -                    else
        -                        {
        -                        $cssFile = NaturalDocs::File->JoinPaths( $self->ProjectDirectory(), $style . '.css' );
        -
        -                        if (-e $cssFile)
        -                            {
        -                            push @styles, $style;
        -                            splice(@stylePieces, 0, 1 + $extras);
        -                            $success = 1;
        -                            last;
        -                            }
        -                        else
        -                            {  $extras++;  };
        -                        };
        -                    };
        -
        -                if (!$success)
        -                    {
        -                    push @errorMessages, 'The style "' . $stylePieces[0] . '" does not exist.';
        -                    shift @stylePieces;
        -                    };
        -                };
        -            };
        -        }
        -    else
        -        {  @styles = ( 'Default' );  };
        -
        -
        -    # Decode and validate the output strings.
        -
        -    my %outputDirectories;
        -
        -    foreach my $outputString (@outputStrings)
        -        {
        -        my ($format, $directory) = split(/ /, $outputString, 2);
        -
        -        if (!defined $directory)
        -            {  push @errorMessages, 'The -o option needs two parameters: -o [format] [directory]';  }
        -        else
        -            {
        -            if (!NaturalDocs::File->PathIsAbsolute($directory))
        -                {  $directory = NaturalDocs::File->JoinPaths(Cwd::cwd(), $directory, 1);  };
        -
        -            $directory = NaturalDocs::File->CanonizePath($directory);
        -
        -            if (! -e $directory || ! -d $directory)
        -                {
        -                # They may have forgotten the format portion and the directory name had a space in it.
        -                if (-e ($format . ' ' . $directory) && -d ($format . ' ' . $directory))
        -                    {
        -                    push @errorMessages, 'The -o option needs two parameters: -o [format] [directory]';
        -                    $format = undef;
        -                    }
        -                else
        -                    {  push @errorMessages, 'The output directory ' . $directory . ' does not exist.';  }
        -                }
        -            elsif (exists $outputDirectories{$directory})
        -                {  push @errorMessages, 'You cannot specify the output directory ' . $directory . ' more than once.';  }
        -            else
        -                {  $outputDirectories{$directory} = 1;  };
        -
        -            if (defined $format)
        -                {
        -                my $builderPackage = NaturalDocs::Builder->OutputPackageOf($format);
        -
        -                if (defined $builderPackage)
        -                    {
        -                    push @buildTargets,
        -                            NaturalDocs::Settings::BuildTarget->New($builderPackage->New(), $directory);
        -                    }
        -                else
        -                    {
        -                    push @errorMessages, 'The output format ' . $format . ' doesn\'t exist or is not installed.';
        -                    $valueRef = \$ignored;
        -                    };
        -                };
        -            };
        -        };
        -
        -    if (!scalar @buildTargets)
        -        {  push @errorMessages, 'You did not specify an output directory.';  };
        -
        -
        -    # Decode and validate the image strings.
        -
        -    foreach my $imageString (@imageStrings)
        -        {
        -        if ($imageString =~ /^ *\*/)
        -            {
        -            # The below NaturalDocs::File functions assume everything is canonized.
        -            $imageString = NaturalDocs::File->CanonizePath($imageString);
        -
        -            my ($volume, $directoryString) = NaturalDocs::File->SplitPath($imageString, 1);
        -            my @directories = NaturalDocs::File->SplitDirectories($directoryString);
        -
        -            shift @directories;
        -
        -            $directoryString = NaturalDocs::File->JoinDirectories(@directories);
        -            push @relativeImageDirectories, NaturalDocs::File->JoinPath($volume, $directoryString);
        -            }
        -        else
        -            {
        -            if (!NaturalDocs::File->PathIsAbsolute($imageString))
        -                {  $imageString = NaturalDocs::File->JoinPaths(Cwd::cwd(), $imageString, 1);  };
        -
        -            $imageString = NaturalDocs::File->CanonizePath($imageString);
        -
        -            if (! -e $imageString || ! -d $imageString)
        -                {  push @errorMessages, 'The image directory ' . $imageString . ' does not exist.';  };
        -
        -            push @imageDirectories, $imageString;
        -            };
        -        };
        -
        -
        -    # Make sure the input and project directories are specified, canonized, and exist.
        -
        -    if (scalar @inputDirectories)
        -        {
        -        for (my $i = 0; $i < scalar @inputDirectories; $i++)
        -            {
        -            if (!NaturalDocs::File->PathIsAbsolute($inputDirectories[$i]))
        -                {  $inputDirectories[$i] = NaturalDocs::File->JoinPaths(Cwd::cwd(), $inputDirectories[$i], 1);  };
        -
        -            $inputDirectories[$i] = NaturalDocs::File->CanonizePath($inputDirectories[$i]);
        -
        -            if (! -e $inputDirectories[$i] || ! -d $inputDirectories[$i])
        -                {  push @errorMessages, 'The input directory ' . $inputDirectories[$i] . ' does not exist.';  };
        -            };
        -        }
        -    else
        -        {  push @errorMessages, 'You did not specify an input (source) directory.';  };
        -
        -    if (defined $projectDirectory)
        -        {
        -        if (!NaturalDocs::File->PathIsAbsolute($projectDirectory))
        -            {  $projectDirectory = NaturalDocs::File->JoinPaths(Cwd::cwd(), $projectDirectory, 1);  };
        -
        -        $projectDirectory = NaturalDocs::File->CanonizePath($projectDirectory);
        -
        -        if (! -e $projectDirectory || ! -d $projectDirectory)
        -            {  push @errorMessages, 'The project directory ' . $projectDirectory . ' does not exist.';  };
        -
        -        # Create the Data subdirectory if it doesn't exist.
        -        NaturalDocs::File->CreatePath( NaturalDocs::File->JoinPaths($projectDirectory, 'Data', 1) );
        -        }
        -    else
        -        {  push @errorMessages, 'You did not specify a project directory.';  };
        -
        -
        -    # Make sure the excluded input directories are canonized, and add the project and output directories to the list.
        -
        -    for (my $i = 0; $i < scalar @excludedInputDirectories; $i++)
        -        {
        -        if (!NaturalDocs::File->PathIsAbsolute($excludedInputDirectories[$i]))
        -            {  $excludedInputDirectories[$i] = NaturalDocs::File->JoinPaths(Cwd::cwd(), $excludedInputDirectories[$i], 1);  };
        -
        -        $excludedInputDirectories[$i] = NaturalDocs::File->CanonizePath($excludedInputDirectories[$i]);
        -        };
        -
        -    push @excludedInputDirectories, $projectDirectory;
        -
        -    foreach my $buildTarget (@buildTargets)
        -        {
        -        push @excludedInputDirectories, $buildTarget->Directory();
        -        };
        -
        -
        -    # Determine the tab length, and default to four if not specified.
        -
        -    if (defined $tabLength)
        -        {
        -        if ($tabLength !~ /^[0-9]+$/)
        -            {  push @errorMessages, 'The tab length must be a number.';  };
        -        }
        -    else
        -        {  $tabLength = 4;  };
        -
        -
        -    # Decode and validate the highlight setting.
        -
        -    if (defined $highlightString)
        -    	{
        -    	$highlightString = lc($highlightString);
        -
        -    	if ($highlightString eq 'off')
        -    		{
        -    		$highlightCode = undef;
        -    		$highlightAnonymous = undef;
        -    		}
        -    	elsif ($highlightString eq 'code')
        -    		{
        -    		$highlightCode = 1;
        -    		$highlightAnonymous = undef;
        -    		}
        -    	elsif ($highlightString eq 'all')
        -    		{
        -    		$highlightCode = 1;
        -    		$highlightAnonymous = 1;
        -    		}
        -    	else
        -    		{  push @errorMessages, $highlightString . ' is not a valid value for --highlight.';  }
        -    	}
        -    else
        -    	{
        -    	$highlightCode = 1;
        -    	$highlightAnonymous = undef;
        -    	}
        -
        -
        -    # Exit with the error message if there was one.
        -
        -    if (scalar @errorMessages)
        -        {
        -        print join("\n", @errorMessages) . "\nType NaturalDocs -h to see the syntax reference.\n";
        -        exit;
        -        };
        -    };
        -
        -#
        -#   Function: PrintSyntax
        -#
        -#   Prints the syntax reference.
        -#
        -sub PrintSyntax
        -    {
        -    my ($self) = @_;
        -
        -    # Make sure all line lengths are under 80 characters.
        -
        -    print
        -
        -    "Natural Docs, version " . $self->TextAppVersion() . "\n"
        -    . $self->AppURL() . "\n"
        -    . "This program is licensed under version 3 of the AGPL\n"
        -    . "Refer to License.txt for the complete details\n"
        -    . "--------------------------------------\n"
        -    . "\n"
        -    . "Syntax:\n"
        -    . "\n"
        -    . "    NaturalDocs -i [input (source) directory]\n"
        -    . "               (-i [input (source) directory] ...)\n"
        -    . "                -o [output format] [output directory]\n"
        -    . "               (-o [output format] [output directory] ...)\n"
        -    . "                -p [project directory]\n"
        -    . "                [options]\n"
        -    . "\n"
        -    . "Examples:\n"
        -    . "\n"
        -    . "    NaturalDocs -i C:\\My Project\\Source -o HTML C:\\My Project\\Docs\n"
        -    . "                -p C:\\My Project\\Natural Docs\n"
        -    . "    NaturalDocs -i /src/project -o HTML /doc/project\n"
        -    . "                -p /etc/naturaldocs/project -s Small -q\n"
        -    . "\n"
        -    . "Required Parameters:\n"
        -    . "\n"
        -    . " -i [dir]\n--input [dir]\n--source [dir]\n"
        -    . "     Specifies an input (source) directory.  Required.\n"
        -    . "     Can be specified multiple times.\n"
        -    . "\n"
        -    . " -o [fmt] [dir]\n--output [fmt] [dir]\n"
        -    . "    Specifies an output format and directory.  Required.\n"
        -    . "    Can be specified multiple times, but only once per directory.\n"
        -    . "    Possible output formats:\n";
        -
        -    $self->PrintOutputFormats('    - ');
        -
        -    print
        -    "\n"
        -    . " -p [dir]\n--project [dir]\n"
        -    . "    Specifies the project directory.  Required.\n"
        -    . "    There needs to be a unique project directory for every source directory.\n"
        -    . "\n"
        -    . "Optional Parameters:\n"
        -    . "\n"
        -    . " -s [style] ([style] [style] ...)\n--style [style] ([style] [style] ...)\n"
        -    . "    Specifies the CSS style when building HTML output.  If multiple styles are\n"
        -    . "    specified, they will all be included in the order given.\n"
        -    . "\n"
        -    . " -img [image directory]\n--image [image directory]\n"
        -    . "    Specifies an image directory.  Can be specified multiple times.\n"
        -    . "    Start with * to specify a relative directory, as in -img */images.\n"
        -    . "\n"
        -    . " -do\n--documented-only\n"
        -    . "    Specifies only documented code aspects should be included in the output.\n"
        -    . "\n"
        -    . " -t [len]\n--tab-length [len]\n"
        -    . "    Specifies the number of spaces tabs should be expanded to.  This only needs\n"
        -    . "    to be set if you use tabs in example code and text diagrams.  Defaults to 4.\n"
        -    . "\n"
        -    . " -xi [dir]\n--exclude-input [dir]\n--exclude-source [dir]\n"
        -    . "    Excludes an input (source) directory from the documentation.\n"
        -    . "    Automatically done for the project and output directories.  Can\n"
        -    . "    be specified multiple times.\n"
        -    . "\n"
        -    . " -nag\n--no-auto-group\n"
        -    . "    Turns off auto-grouping completely.\n"
        -    . "\n"
        -    . " -oft\n--only-file-titles\n"
        -    . "    Source files will only use the file name as the title.\n"
        -    . "\n"
        -    . " -hl [option]\n--highlight [option]\n"
        -    . "    Specifies when syntax highlighting should be applied.  Defaults to code.\n"
        -    . "    off  - No syntax highlighting is applied.\n"
        -    . "    code - Syntax highlighting is only applied to prototypes and (start code)\n"
        -    . "           segments.\n"
        -    . "    all  - Systax highlighting is applied to prototypes, (start code) segments,\n"
        -    . "           and lines starting with >, :, or |."
        -    . "\n"
        -    . " -r\n--rebuild\n"
        -    . "    Rebuilds all output and data files from scratch.\n"
        -    . "    Does not affect the menu file.\n"
        -    . "\n"
        -    . " -ro\n--rebuild-output\n"
        -    . "    Rebuilds all output files from scratch.\n"
        -    . "\n"
        -    . " -q\n--quiet\n"
        -    . "    Suppresses all non-error output.\n"
        -    . "\n"
        -    . " -?\n -h\n--help\n"
        -    . "    Displays this syntax reference.\n";
        -    };
        -
        -
        -#
        -#   Function: PrintOutputFormats
        -#
        -#   Prints all the possible output formats that can be specified with -o.  Each one will be placed on its own line.
        -#
        -#   Parameters:
        -#
        -#       prefix - Characters to prefix each one with, such as for indentation.
        -#
        -sub PrintOutputFormats #(prefix)
        -    {
        -    my ($self, $prefix) = @_;
        -
        -    my $outputPackages = NaturalDocs::Builder::OutputPackages();
        -
        -    foreach my $outputPackage (@$outputPackages)
        -        {
        -        print $prefix . $outputPackage->CommandLineOption() . "\n";
        -        };
        -    };
        -
        -
        -#
        -#   Function: LoadAndComparePreviousSettings
        -#
        -#   Loads <PreviousSettings.nd> and compares the values there with those in the command line.  If differences require it,
        -#   sets <rebuildData> and/or <rebuildOutput>.
        -#
        -sub LoadAndComparePreviousSettings
        -    {
        -    my ($self) = @_;
        -
        -    my $fileIsOkay;
        -
        -    if (!NaturalDocs::Settings->RebuildData())
        -        {
        -        my $version;
        -
        -        if (NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('PreviousSettings.nd'),
        -                                                                           NaturalDocs::Version->FromString('1.51') ))
        -            {  $fileIsOkay = 1;  };
        -        };
        -
        -    if (!$fileIsOkay)
        -        {
        -        # We need to reparse everything because --documented-only may have changed.
        -        # We need to rebuild everything because --tab-length may have changed.
        -        NaturalDocs::Project->ReparseEverything();
        -        NaturalDocs::Project->RebuildEverything();
        -        }
        -    else
        -        {
        -        my $raw;
        -
        -        # [UInt8: tab expansion]
        -        # [UInt8: documented only (0 or 1)]
        -        # [UInt8: no auto-group (0 or 1)]
        -        # [UInt8: only file titles (0 or 1)]
        -        # [UInt8: highlight code (0 or 1)]
        -        # [UInt8: highlight anonymous (0 or 1)]
        -
        -        my $prevTabLength = NaturalDocs::BinaryFile->GetUInt8();
        -        my $prevDocumentedOnly = NaturalDocs::BinaryFile->GetUInt8();
        -        my $prevNoAutoGroup = NaturalDocs::BinaryFile->GetUInt8();
        -        my $prevOnlyFileTitles = NaturalDocs::BinaryFile->GetUInt8();
        -        my $prevHighlightCode = NaturalDocs::BinaryFile->GetUInt8();
        -        my $prevHighlightAnonymous = NaturalDocs::BinaryFile->GetUInt8();
        -
        -        if ($prevDocumentedOnly == 0)
        -            {  $prevDocumentedOnly = undef;  };
        -        if ($prevNoAutoGroup == 0)
        -            {  $prevNoAutoGroup = undef;  };
        -        if ($prevOnlyFileTitles == 0)
        -            {  $prevOnlyFileTitles = undef;  };
        -        if ($prevHighlightCode == 0)
        -            {  $prevHighlightCode = undef;  };
        -        if ($prevHighlightAnonymous == 0)
        -            {  $prevHighlightAnonymous = undef;  };
        -
        -        if ($prevTabLength != $self->TabLength() ||
        -        	$prevHighlightCode != $self->HighlightCode() ||
        -        	$prevHighlightAnonymous != $self->HighlightAnonymous())
        -            {
        -            NaturalDocs::Project->RebuildEverything();
        -            };
        -
        -        if ($prevDocumentedOnly != $self->DocumentedOnly() ||
        -            $prevNoAutoGroup != $self->NoAutoGroup() ||
        -            $prevOnlyFileTitles != $self->OnlyFileTitles())
        -            {
        -            NaturalDocs::Project->ReparseEverything();
        -            };
        -
        -
        -        # [UInt8: number of input directories]
        -
        -        my $inputDirectoryCount = NaturalDocs::BinaryFile->GetUInt8();
        -
        -        while ($inputDirectoryCount)
        -            {
        -            # [AString16: input directory] [AString16: input directory name] ...
        -
        -            my $inputDirectory = NaturalDocs::BinaryFile->GetAString16();
        -            my $inputDirectoryName = NaturalDocs::BinaryFile->GetAString16();
        -
        -            # Not doing anything with this for now.
        -
        -            $inputDirectoryCount--;
        -            };
        -
        -
        -        # [UInt8: number of output targets]
        -
        -        my $outputTargetCount = NaturalDocs::BinaryFile->GetUInt8();
        -
        -        # Keys are the directories, values are the command line options.
        -        my %previousOutputDirectories;
        -
        -        while ($outputTargetCount)
        -            {
        -            # [AString16: output directory] [AString16: output format command line option] ...
        -
        -            my $outputDirectory = NaturalDocs::BinaryFile->GetAString16();
        -            my $outputCommand = NaturalDocs::BinaryFile->GetAString16();
        -
        -            $previousOutputDirectories{$outputDirectory} = $outputCommand;
        -
        -            $outputTargetCount--;
        -            };
        -
        -        # Check if any targets were added to the command line, or if their formats changed.  We don't care if targets were
        -        # removed.
        -        my $buildTargets = $self->BuildTargets();
        -
        -        foreach my $buildTarget (@$buildTargets)
        -            {
        -            if (!exists $previousOutputDirectories{$buildTarget->Directory()} ||
        -                $buildTarget->Builder()->CommandLineOption() ne $previousOutputDirectories{$buildTarget->Directory()})
        -                {
        -                NaturalDocs::Project->RebuildEverything();
        -                last;
        -                };
        -            };
        -
        -        NaturalDocs::BinaryFile->Close();
        -        };
        -    };
        -
        -
        -#
        -#   Function: SavePreviousSettings
        -#
        -#   Saves the settings into <PreviousSettings.nd>.
        -#
        -sub SavePreviousSettings
        -    {
        -    my ($self) = @_;
        -
        -    NaturalDocs::BinaryFile->OpenForWriting(  NaturalDocs::Project->DataFile('PreviousSettings.nd') );
        -
        -    # [UInt8: tab length]
        -    # [UInt8: documented only (0 or 1)]
        -    # [UInt8: no auto-group (0 or 1)]
        -    # [UInt8: only file titles (0 or 1)]
        -    # [UInt8: highlight code (0 or 1)]
        -    # [UInt8: highlight anonymous (0 or 1)]
        -    # [UInt8: number of input directories]
        -
        -    my $inputDirectories = $self->InputDirectories();
        -
        -    NaturalDocs::BinaryFile->WriteUInt8($self->TabLength());
        -    NaturalDocs::BinaryFile->WriteUInt8($self->DocumentedOnly() ? 1 : 0);
        -    NaturalDocs::BinaryFile->WriteUInt8($self->NoAutoGroup() ? 1 : 0);
        -    NaturalDocs::BinaryFile->WriteUInt8($self->OnlyFileTitles() ? 1 : 0);
        -    NaturalDocs::BinaryFile->WriteUInt8($self->HighlightCode() ? 1 : 0);
        -    NaturalDocs::BinaryFile->WriteUInt8($self->HighlightAnonymous() ? 1 : 0);
        -    NaturalDocs::BinaryFile->WriteUInt8(scalar @$inputDirectories);
        -
        -    foreach my $inputDirectory (@$inputDirectories)
        -        {
        -        my $inputDirectoryName = $self->InputDirectoryNameOf($inputDirectory);
        -
        -        # [AString16: input directory] [AString16: input directory name] ...
        -        NaturalDocs::BinaryFile->WriteAString16($inputDirectory);
        -        NaturalDocs::BinaryFile->WriteAString16($inputDirectoryName);
        -        };
        -
        -    # [UInt8: number of output targets]
        -
        -    my $buildTargets = $self->BuildTargets();
        -    NaturalDocs::BinaryFile->WriteUInt8(scalar @$buildTargets);
        -
        -    foreach my $buildTarget (@$buildTargets)
        -        {
        -        # [AString16: output directory] [AString16: output format command line option] ...
        -        NaturalDocs::BinaryFile->WriteAString16( $buildTarget->Directory() );
        -        NaturalDocs::BinaryFile->WriteAString16( $buildTarget->Builder()->CommandLineOption() );
        -        };
        -
        -    NaturalDocs::BinaryFile->Close();
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Settings/BuildTarget.pm b/vendor/naturaldocs/Modules/NaturalDocs/Settings/BuildTarget.pm
        deleted file mode 100644
        index 81595757e..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Settings/BuildTarget.pm
        +++ /dev/null
        @@ -1,67 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::Settings::BuildTarget
        -#
        -###############################################################################
        -#
        -#   A class that stores information about a build target.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Settings::BuildTarget;
        -
        -use NaturalDocs::DefineMembers 'BUILDER', 'Builder()', 'SetBuilder()',
        -                                                 'DIRECTORY', 'Directory()', 'SetDirectory()';
        -
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref with the members below.
        -#
        -#       BUILDER      - The <NaturalDocs::Builder::Base>-derived object for the target's output format.
        -#       DIRECTORY - The output directory of the target.
        -#
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       builder - The <NaturalDocs::Builder::Base>-derived object for the target's output format.
        -#       directory - The directory to place the output files in.
        -#
        -sub New #(builder, directory)
        -    {
        -    my ($package, $builder, $directory) = @_;
        -
        -    my $object = [ ];
        -    bless $object, $package;
        -
        -    $object->SetBuilder($builder);
        -    $object->SetDirectory($directory);
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Member Functions
        -#
        -#   Builder - Returns the <NaturalDocs::Builder::Base>-derived object for the target's output format.
        -#   SetBuilder - Replaces the <NaturalDocs::Builder::Base>-derived object for the target's output format.
        -#   Directory - Returns the directory for the target's output files.
        -#   SetDirectory - Replaces the directory for the target's output files.
        -#
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB.pm b/vendor/naturaldocs/Modules/NaturalDocs/SourceDB.pm
        deleted file mode 100644
        index 773aadc0b..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB.pm
        +++ /dev/null
        @@ -1,679 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SourceDB
        -#
        -###############################################################################
        -#
        -#   SourceDB is an experimental package meant to unify the tracking of various elements in the source code.
        -#
        -#   Requirements:
        -#
        -#       - All extension packages must call <RegisterExtension()> before they can be used.
        -#
        -#
        -#   Architecture: The Idea
        -#
        -#       For quite a while Natural Docs only needed <SymbolTable>.  However, 1.3 introduced the <ClassHierarchy> package
        -#       which duplicated some of its functionality to track classes and parent references.  1.4 now needs <ImageReferenceTable>,
        -#       so this package was an attempt to isolate the common functionality so the wheel doesn't have to keep being rewritten as
        -#       the scope of Natural Docs expands.
        -#
        -#       SourceDB is designed around <Extensions> and items.  The purposefully vague "items" are anything in the source code
        -#       that we need to track the definitions of.  Extensions are the packages to track them, only they're derived from
        -#       <NaturalDocs::SourceDB::Extension> and registered with this package instead of being free standing and duplicating
        -#       functionality such as watched files.
        -#
        -#       The architecture on this package isn't comprehensive yet.  As more extensions are added or previously made free standing
        -#       packages are migrated to it it will expand to encompass them.  However, it's still experimental so this concept may
        -#       eventually be abandoned for something better instead.
        -#
        -#
        -#   Architecture: Assumptions
        -#
        -#       SourceDB is built around certain assumptions.
        -#
        -#       One item per file:
        -#
        -#           SourceDB assumes that only the first item per file with a particular item string is relevant.  For example, if two functions
        -#           have the exact same name, there's no way to link to the second one either in HTML or internally so it doesn't matter for
        -#           our purposes.  Likewise, if two references are exactly the same they go to the same target, so it doesn't matter whether
        -#           there's one or two or a thousand.  All that matters is that at least one reference exists in this file because you only need
        -#           to determine whether the entire file gets rebuilt.  If two items are different in some meaningful way, they should generate
        -#           different item strings.
        -#
        -#       Watched file parsing:
        -#
        -#           SourceDB assumes the parse method is that the information that was stored from Natural Docs' previous run is loaded, a
        -#           file is watched, that file is reparsed, and then <AnalyzeWatchedFileChanges()> is called.  When the file is reparsed all
        -#           items within it are added the same as if the file was never parsed before.
        -#
        -#           If there's a new item this time around, that's fine no matter what.  However, a changed item wouldn't normally be
        -#           recorded because the previous run's definition is seen as the first one and subsequent ones are ignored.  Also, deleted
        -#           items would normally not be recorded either because we're only adding.
        -#
        -#           The watched file method fixes this because everything is also added to a second, clean database specifically for the
        -#           watched file.  Because it starts clean, it always gets the first definition from the current parse which can then be
        -#           compared to the original by <AnalyzeWatchedFileChanges()>.  Because it starts clean you can also compare it to the
        -#           main database to see if anything was deleted, because it would appear in the main database but not the watched one.
        -#
        -#           This means that functions like <ChangeDefinition()> and <DeleteDefinition()> should only be called by
        -#           <AnalyzeWatchedFileChanges()>.  Externally only <AddDefinition()> should be called.  <DeleteItem()> is okay to be
        -#           called externally because entire items aren't managed by the watched file database, only definitions.
        -#
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -use NaturalDocs::SourceDB::Extension;
        -use NaturalDocs::SourceDB::Item;
        -use NaturalDocs::SourceDB::ItemDefinition;
        -use NaturalDocs::SourceDB::File;
        -use NaturalDocs::SourceDB::WatchedFileDefinitions;
        -
        -
        -package NaturalDocs::SourceDB;
        -
        -
        -###############################################################################
        -# Group: Types
        -
        -
        -#
        -#   Type: ExtensionID
        -#
        -#   A unique identifier for each <NaturalDocs::SourceDB> extension as given out by <RegisterExtension()>.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   array: extensions
        -#
        -#   An array of <NaturalDocs::SourceDB::Extension>-derived extensions, as added with <RegisterExtension()>.  The indexes
        -#   are the <ExtensionIDs> and the values are package references.
        -#
        -my @extensions;
        -
        -#
        -#   array: extensionUsesDefinitionObjects
        -#
        -#   An array where the indexes are <ExtensionIDs> and the values are whether that extension uses its own definition class
        -#   derived from <NaturalDocs::SourceDB::ItemDefinition> or it just tracks their existence.
        -#
        -my @extensionUsesDefinitionObjects;
        -
        -
        -
        -#
        -#   array: items
        -#
        -#   The array of source items.  The <ExtensionIDs> are the indexes, and the values are hashrefs mapping the item
        -#   string to <NaturalDocs::SourceDB::Item>-derived objects.  Hashrefs may be undef.
        -#
        -my @items;
        -
        -
        -#
        -#   hash: files
        -#
        -#   A hashref mapping source <FileNames> to <NaturalDocs::SourceDB::Files>.
        -#
        -my %files;
        -
        -
        -#
        -#   object: watchedFile
        -#
        -#   When a file is being watched for changes, will be a <NaturalDocs::SourceDB::File> for that file.  Is undef otherwise.
        -#
        -#   When the file is parsed, items are added to both this and the version in <files>.  Thus afterwards we can compare the two to
        -#   see if any were deleted since the last time Natural Docs was run, because they would be in the <files> version but not this
        -#   one.
        -#
        -my $watchedFile;
        -
        -
        -#
        -#   string: watchedFileName
        -#
        -#   When a file is being watched for changes, will be the <FileName> of the file being watched.  Is undef otherwise.
        -#
        -my $watchedFileName;
        -
        -
        -#
        -#   object: watchedFileDefinitions
        -#
        -#   When a file is being watched for changes, will be a <NaturalDocs::SourceDB::WatchedFileDefinitions> object.  Is undef
        -#   otherwise.
        -#
        -#   When the file is parsed, items are added to both this and the version in <items>.  Since only the first definition is kept, this
        -#   will always have the definition info from the file whereas the version in <items> will have the first definition as of the last time
        -#   Natural Docs was run.  Thus they can be compared to see if the definitions of items that existed the last time around have
        -#   changed.
        -#
        -my $watchedFileDefinitions;
        -
        -
        -
        -###############################################################################
        -# Group: Extension Functions
        -
        -
        -#
        -#   Function: RegisterExtension
        -#
        -#   Registers a <NaturalDocs::SourceDB::Extension>-derived package and returns a unique <ExtensionID> for it.  All extensions
        -#   must call this before they can be used.
        -#
        -#   Registration Order:
        -#
        -#       The order in which extensions register is important.  Whenever possible, items are added in the order their extensions
        -#       registered.  However, items are changed and deleted in the reverse order.  Take advantage of this to minimize
        -#       churn between extensions that are dependent on each other.
        -#
        -#       For example, when symbols are added or deleted they may cause references to be retargeted and thus their files need to
        -#       be rebuilt.  However, adding or deleting references never causes the symbols' files to be rebuilt.  So it makes sense that
        -#       symbols should be created before references, and that references should be deleted before symbols.
        -#
        -#   Parameters:
        -#
        -#       extension - The package or object of the extension.  Must be derived from <NaturalDocs::SourceDB::Extension>.
        -#       usesDefinitionObjects - Whether the extension uses its own class derived from <NaturalDocs::SourceDB::ItemDefinition>
        -#                                         or simply tracks each definitions existence.
        -#
        -#   Returns:
        -#
        -#       An <ExtensionID> unique to the extension.  This should be saved because it's required in functions such as <AddItem()>.
        -#
        -sub RegisterExtension #(package extension, bool usesDefinitionObjects) => ExtensionID
        -    {
        -    my ($self, $extension, $usesDefinitionObjects) = @_;
        -
        -    push @extensions, $extension;
        -    push @extensionUsesDefinitionObjects, $usesDefinitionObjects;
        -
        -    return scalar @extensions - 1;
        -    };
        -
        -
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Loads the data of the source database and all the extensions.  Will call <NaturalDocs::SourceDB::Extension->Load()> for
        -#   all of them, unless there's a situation where all the source files are going to be reparsed anyway in which case it's not needed.
        -#
        -sub Load
        -    {
        -    my $self = shift;
        -
        -    # No point loading if RebuildData is set.
        -    if (!NaturalDocs::Settings->RebuildData())
        -        {
        -        # If any load fails, stop loading the rest and just reparse all the source files.
        -        my $success = 1;
        -
        -        for (my $extension = 0; $extension < scalar @extensions && $success; $extension++)
        -            {
        -            $success = $extensions[$extension]->Load();
        -            };
        -
        -        if (!$success)
        -            {  NaturalDocs::Project->ReparseEverything();  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves the data of the source database and all its extensions.  Will call <NaturalDocs::SourceDB::Extension->Save()> for all
        -#   of them.
        -#
        -sub Save
        -    {
        -    my $self = shift;
        -
        -    for (my $extension = scalar @extensions - 1; $extension >= 0; $extension--)
        -        {
        -        $extensions[$extension]->Save();
        -        };
        -    };
        -
        -
        -#
        -#   Function: PurgeDeletedSourceFiles
        -#
        -#   Removes all data associated with deleted source files.
        -#
        -sub PurgeDeletedSourceFiles
        -    {
        -    my $self = shift;
        -
        -    my $filesToPurge = NaturalDocs::Project->FilesToPurge();
        -
        -    # Extension is the outermost loop because we want the extensions added last to have their definitions removed first to cause
        -    # the least amount of churn between interdependent extensions.
        -    for (my $extension = scalar @extensions - 1; $extension >= 0; $extension--)
        -        {
        -        foreach my $file (keys %$filesToPurge)
        -            {
        -            if (exists $files{$file})
        -                {
        -                my @items = $files{$file}->ListItems($extension);
        -
        -                foreach my $item (@items)
        -                    {
        -                    $self->DeleteDefinition($extension, $item, $file);
        -                    };
        -                }; # file exists
        -            }; # each file
        -        }; # each extension
        -    };
        -
        -
        -
        -
        -
        -###############################################################################
        -# Group: Item Functions
        -
        -
        -#
        -#   Function: AddItem
        -#
        -#   Adds the passed item to the database.  This will not work if the item string already exists.  The item added should *not*
        -#   already have definitions attached.  Only use this to add blank items and then call <AddDefinition()> instead.
        -#
        -#   Parameters:
        -#
        -#       extension - An <ExtensionID>.
        -#       itemString - The string serving as the item identifier.
        -#       item - An object derived from <NaturalDocs::SourceDB::Item>.
        -#
        -#   Returns:
        -#
        -#       Whether the item was added, that is, whether it was the first time this item was added.
        -#
        -sub AddItem #(ExtensionID extension, string itemString, NaturalDocs::SourceDB::Item item) => bool
        -    {
        -    my ($self, $extension, $itemString, $item) = @_;
        -
        -    if (!defined $items[$extension])
        -        {  $items[$extension] = { };  };
        -
        -    if (!exists $items[$extension]->{$itemString})
        -        {
        -        if ($item->HasDefinitions())
        -            {  die "Tried to add an item to SourceDB that already had definitions.";  };
        -
        -        $items[$extension]->{$itemString} = $item;
        -        return 1;
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -#
        -#   Function: GetItem
        -#
        -#   Returns the <NaturalDocs::SourceDB::Item>-derived object for the passed <ExtensionID> and item string, or undef if there
        -#   is none.
        -#
        -sub GetItem #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extensionID, $itemString) = @_;
        -
        -    if (defined $items[$extensionID])
        -        {  return $items[$extensionID]->{$itemString};  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: DeleteItem
        -#
        -#   Deletes the record of the passed <ExtensionID> and item string.  Do *not* delete items that still have definitions.  Use
        -#   <DeleteDefinition()> first.
        -#
        -#   Parameters:
        -#
        -#       extension - The <ExtensionID>.
        -#       itemString - The item's identifying string.
        -#
        -#   Returns:
        -#
        -#       Whether it was successful, meaning whether an entry existed for it.
        -#
        -sub DeleteItem #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (defined $items[$extension] && exists $items[$extension]->{$itemString})
        -        {
        -        if ($items[$extension]->{$itemString}->HasDefinitions())
        -            {  die "Tried to delete an item from SourceDB that still has definitions.";  };
        -
        -        delete $items[$extension]->{$itemString};
        -        return 1;
        -        }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: HasItem
        -#
        -#   Returns whether there is an item defined for the passed <ExtensionID> and item string.
        -#
        -sub HasItem #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (defined $items[$extension])
        -        {  return (exists $items[$extension]->{$itemString});  }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: GetAllItemsHashRef
        -#
        -#   Returns a hashref of all the items defined for an extension.  *Do not change the contents.*  The keys are the item strings and
        -#   the values are <NaturalDocs::SourceDB::Items> or derived classes.
        -#
        -sub GetAllItemsHashRef #(ExtensionID extension) => hashref
        -    {
        -    my ($self, $extension) = @_;
        -    return $items[$extension];
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Definition Functions
        -
        -
        -#
        -#   Function: AddDefinition
        -#
        -#   Adds a definition to an item.  Assumes the item was already created with <AddItem()>.  If there's already a definition for this
        -#   file in the item, the new definition will be ignored.
        -#
        -#   Parameters:
        -#
        -#       extension - The <ExtensionID>.
        -#       itemString - The item string.
        -#       file - The <FileName> the definition is in.
        -#       definition - If you're using a custom <NaturalDocs::SourceDB::ItemDefinition> class, you must include an object for it here.
        -#                       Otherwise this parameter is ignored.
        -#
        -#   Returns:
        -#
        -#       Whether the definition was added, which is to say, whether this was the first definition for the passed <FileName>.
        -#
        -sub AddDefinition #(ExtensionID extension, string itemString, FileName file, optional NaturalDocs::SourceDB::ItemDefinition definition) => bool
        -    {
        -    my ($self, $extension, $itemString, $file, $definition) = @_;
        -
        -
        -    # Items
        -
        -    my $item = $self->GetItem($extension, $itemString);
        -
        -    if (!defined $item)
        -        {  die "Tried to add a definition to an undefined item in SourceDB.";  };
        -
        -    if (!$extensionUsesDefinitionObjects[$extension])
        -        {  $definition = 1;  };
        -
        -    my $result = $item->AddDefinition($file, $definition);
        -
        -
        -    # Files
        -
        -    if (!exists $files{$file})
        -        {  $files{$file} = NaturalDocs::SourceDB::File->New();  };
        -
        -    $files{$file}->AddItem($extension, $itemString);
        -
        -
        -    # Watched File
        -
        -    if ($self->WatchingFileForChanges())
        -        {
        -        $watchedFile->AddItem($extension, $itemString);
        -
        -        if ($extensionUsesDefinitionObjects[$extension])
        -            {  $watchedFileDefinitions->AddDefinition($extension, $itemString, $definition);  };
        -        };
        -
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: ChangeDefinition
        -#
        -#   Changes the definition of an item.  This function is only used for extensions that use custom
        -#   <NaturalDocs::SourceDB::ItemDefinition>-derived classes.
        -#
        -#   Parameters:
        -#
        -#       extension - The <ExtensionID>.
        -#       itemString - The item string.
        -#       file - The <FileName> the definition is in.
        -#       definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition>.
        -#
        -sub ChangeDefinition #(ExtensionID extension, string itemString, FileName file, NaturalDocs::SourceDB::ItemDefinition definition)
        -    {
        -    my ($self, $extension, $itemString, $file, $definition) = @_;
        -
        -    my $item = $self->GetItem($extension, $itemString);
        -
        -    if (!defined $item)
        -        {  die "Tried to change the definition of an undefined item in SourceDB.";  };
        -
        -    if (!$extensionUsesDefinitionObjects[$extension])
        -        {  die "Tried to change the definition of an item in an extension that doesn't use definition objects in SourceDB.";  };
        -
        -    if (!$item->HasDefinition($file))
        -        {  die "Tried to change a definition that doesn't exist in SourceDB.";  };
        -
        -    $item->ChangeDefinition($file, $definition);
        -    $extensions[$extension]->OnChangedDefinition($itemString, $file);
        -    };
        -
        -
        -#
        -#   Function: GetDefinition
        -#
        -#   If the extension uses custom <NaturalDocs::SourceDB::ItemDefinition> classes, returns it for the passed definition or undef
        -#   if it doesn't exist.  Otherwise returns whether it exists.
        -#
        -sub GetDefinition #(ExtensionID extension, string itemString, FileName file) => NaturalDocs::SourceDB::ItemDefinition or bool
        -    {
        -    my ($self, $extension, $itemString, $file) = @_;
        -
        -    my $item = $self->GetItem($extension, $itemString);
        -
        -    if (!defined $item)
        -        {  return undef;  };
        -
        -    return $item->GetDefinition($file);
        -    };
        -
        -
        -#
        -#   Function: DeleteDefinition
        -#
        -#   Removes the definition for the passed item.  Returns whether it was successful, meaning whether a definition existed for that
        -#   file.
        -#
        -sub DeleteDefinition #(ExtensionID extension, string itemString, FileName file) => bool
        -    {
        -    my ($self, $extension, $itemString, $file) = @_;
        -
        -    my $item = $self->GetItem($extension, $itemString);
        -
        -    if (!defined $item)
        -        {  return 0;  };
        -
        -    my $result = $item->DeleteDefinition($file);
        -
        -    if ($result)
        -        {
        -        $files{$file}->DeleteItem($extension, $itemString);
        -        $extensions[$extension]->OnDeletedDefinition($itemString, $file, !$item->HasDefinitions());
        -        };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: HasDefinitions
        -#
        -#   Returns whether there are any definitions for this item.
        -#
        -sub HasDefinitions #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    my $item = $self->GetItem($extension, $itemString);
        -
        -    if (!defined $item)
        -        {  return 0;  };
        -
        -    return $item->HasDefinitions();
        -    };
        -
        -
        -#
        -#   Function: HasDefinition
        -#
        -#   Returns whether there is a definition for the passed <FileName>.
        -#
        -sub HasDefinition #(ExtensionID extension, string itemString, FileName file) => bool
        -    {
        -    my ($self, $extension, $itemString, $file) = @_;
        -
        -    my $item = $self->GetItem($extension, $itemString);
        -
        -    if (!defined $item)
        -        {  return 0;  };
        -
        -    return $item->HasDefinition($file);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Watched File Functions
        -
        -
        -#
        -#   Function: WatchFileForChanges
        -#
        -#   Begins watching a file for changes.  Only one file at a time can be watched.
        -#
        -#   This should be called before a file is parsed so the file info goes both into the main database and the watched file info.
        -#   Afterwards you call <AnalyzeWatchedFileChanges()> so item deletions and definition changes can be detected.
        -#
        -#   Parameters:
        -#
        -#       filename - The <FileName> to watch.
        -#
        -sub WatchFileForChanges #(FileName filename)
        -    {
        -    my ($self, $filename) = @_;
        -
        -    $watchedFileName = $filename;
        -    $watchedFile = NaturalDocs::SourceDB::File->New();
        -    $watchedFileDefinitions = NaturalDocs::SourceDB::WatchedFileDefinitions->New();
        -    };
        -
        -
        -#
        -#   Function: WatchingFileForChanges
        -#
        -#   Returns whether we're currently watching a file for changes or not.
        -#
        -sub WatchingFileForChanges # => bool
        -    {
        -    my $self = shift;
        -    return defined $watchedFileName;
        -    };
        -
        -
        -#
        -#   Function: AnalyzeWatchedFileChanges
        -#
        -#   Analyzes the watched file for changes.  Will delete and change definitions as necessary.
        -#
        -sub AnalyzeWatchedFileChanges
        -    {
        -    my $self = shift;
        -
        -    if (!$self->WatchingFileForChanges())
        -        {  die "Tried to analyze watched file for changes in SourceDB when no file was being watched.";  };
        -    if (!$files{$watchedFileName})
        -        {  return;  };
        -
        -
        -    # Process extensions last registered to first.
        -
        -    for (my $extension = scalar @extensions - 1; $extension >= 0; $extension--)
        -        {
        -        my @items = $files{$watchedFileName}->ListItems($extension);
        -
        -        foreach my $item (@items)
        -            {
        -            if ($watchedFile->HasItem($extension, $item))
        -                {
        -                if ($extensionUsesDefinitionObjects[$extension])
        -                    {
        -                    my $originalDefinition = $items[$extension]->GetDefinition($watchedFileName);
        -                    my $watchedDefinition = $watchedFileDefinitions->GetDefinition($extension, $item);
        -
        -                    if (!$originalDefinition->Compare($watchedDefinition))
        -                        {  $self->ChangeDefinition($extension, $item, $watchedFileName, $watchedDefinition);  };
        -                    }
        -                }
        -            else # !$watchedFile->HasItem($item)
        -                {
        -                $self->DeleteDefinition($extension, $item, $watchedFileName);
        -                };
        -            };
        -        };
        -
        -
        -    $watchedFile = undef;
        -    $watchedFileName = undef;
        -    $watchedFileDefinitions = undef;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/Extension.pm b/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/Extension.pm
        deleted file mode 100644
        index d610b24be..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/Extension.pm
        +++ /dev/null
        @@ -1,85 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SourceDB::Extension
        -#
        -###############################################################################
        -#
        -#   A base package for all <SourceDB> extensions.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::SourceDB::Extension;
        -
        -
        -###############################################################################
        -# Group: Interface Functions
        -# These functions must be overridden by the derived class.
        -
        -
        -#
        -#   Function: Register
        -#
        -#   Override this function to register the package with <NaturalDocs::SourceDB->RegisterExtension()>.
        -#
        -sub Register
        -    {
        -    die "Called SourceDB::Extension->Register().  This function should be overridden by every extension.";
        -    };
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Called by <NaturalDocs::SourceDB->Load()> to load the extension's data.  Returns whether it was successful.
        -#
        -#   *This function might not be called.*  If there's a situation that would cause all the source files to be reparsed anyway,
        -#   <NaturalDocs::SourceDB> may skip calling Load() for the remaining extensions.  You should *not* depend on this function
        -#   for any critical initialization that needs to happen every time regardless.
        -#
        -sub Load # => bool
        -    {
        -    return 1;
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Called by <NaturalDocs::SourceDB->Save()> to save the extension's data.
        -#
        -sub Save
        -    {
        -    };
        -
        -
        -#
        -#   Function: OnDeletedDefinition
        -#
        -#   Called for each definition deleted by <NaturalDocs::SourceDB>.  This is called *after* the definition has been deleted from
        -#   the database, so don't expect to be able to read it.
        -#
        -sub OnDeletedDefinition #(string itemString, FileName file, bool wasLastDefinition)
        -    {
        -    };
        -
        -
        -#
        -#   Function: OnChangedDefinition
        -#
        -#   Called for each definition changed by <NaturalDocs::SourceDB>.  This is called *after* the definition has been changed, so
        -#   don't expect to be able to read the original value.
        -#
        -sub OnChangedDefinition #(string itemString, FileName file)
        -    {
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/File.pm b/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/File.pm
        deleted file mode 100644
        index 1a4419fd2..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/File.pm
        +++ /dev/null
        @@ -1,130 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SourceDB::File
        -#
        -###############################################################################
        -#
        -#   A class used to index items by file.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::SourceDB::File;
        -
        -use NaturalDocs::DefineMembers 'ITEMS';
        -
        -
        -#
        -#   Variables: Members
        -#
        -#   These constants serve as indexes into the object array.
        -#
        -#   ITEMS - An arrayref where an <ExtensionID> is the index and the members are existence hashrefs of the item strigs defined
        -#               in this file.  The arrayref will always exist, but the hashrefs may be undef.
        -#
        -
        -
        -#
        -#   Function: New
        -#
        -#   Returns a new object.
        -#
        -sub New
        -    {
        -    my $package = shift;
        -
        -    my $object = [ ];
        -    $object->[ITEMS] = [ ];
        -
        -    bless $object, $package;
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: AddItem
        -#
        -#   Adds an item to this file.  Returns whether this added a new item.
        -#
        -sub AddItem #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (!defined $self->[ITEMS]->[$extension])
        -        {
        -        $self->[ITEMS]->[$extension] = { $itemString => 1 };
        -        return 1;
        -        }
        -    elsif (!exists $self->[ITEMS]->[$extension]->{$itemString})
        -        {
        -        $self->[ITEMS]->[$extension]->{$itemString} = 1;
        -        return 1;
        -        }
        -    else
        -        {
        -        return 0;
        -        };
        -    };
        -
        -
        -#
        -#   Function: HasItem
        -#
        -#   Returns whether the item exists in this file.
        -#
        -sub HasItem #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (defined $self->[ITEMS]->[$extension])
        -        {  return exists $self->[ITEMS]->[$extension]->{$itemString};  }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: DeleteItem
        -#
        -#   Deletes the passed item.  Returns whether it existed.
        -#
        -sub DeleteItem #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (!defined $self->[ITEMS]->[$extension])
        -        {  return 0;  }
        -    elsif (exists $self->[ITEMS]->[$extension]->{$itemString})
        -        {
        -        delete $self->[ITEMS]->[$extension]->{$itemString};
        -        return 1;
        -        }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: ListItems
        -#
        -#   Returns an array of all the item strings defined for a particular extension, or an empty list if none.
        -#
        -sub ListItems #(ExtensionID extension) => string array
        -    {
        -    my ($self, $extension) = @_;
        -
        -    if (defined $self->[ITEMS]->[$extension])
        -        {  return keys %{$self->[ITEMS]->[$extension]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/Item.pm b/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/Item.pm
        deleted file mode 100644
        index b43475697..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/Item.pm
        +++ /dev/null
        @@ -1,202 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SourceDB::Item
        -#
        -###############################################################################
        -#
        -#   A base class for something being tracked in <NaturalDocs::SourceDB>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::SourceDB::Item;
        -
        -use NaturalDocs::DefineMembers 'DEFINITIONS';
        -
        -
        -#
        -#   Variables: Members
        -#
        -#   The following constants are indexes into the object array.
        -#
        -#   DEFINITIONS - A hashref that maps <FileNames> to either <NaturalDocs::SourceDB::ItemDefinition>-derived objects or
        -#                         serves as an existence hashref depending on whether the extension only tracks existence.  Will be undef if
        -#                         there are none.
        -#
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -sub New
        -    {
        -    my $class = shift;
        -
        -    my $object = [ ];
        -    bless $object, $class;
        -
        -    return $object;
        -    };
        -
        -
        -
        -###############################################################################
        -#
        -#   Group: Definition Functions
        -#
        -#   These functions should be called by <NaturalDocs::SourceDB>.  You should not be calling them directly.  Call functions
        -#   like <NaturalDocs::SourceDB->AddDefinition()> instead.
        -#
        -
        -
        -#
        -#   Function: AddDefinition
        -#
        -#   Adds a definition for the passed <FileName>.  If it's already defined, the new definition will be ignored.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName>.
        -#       definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition> or undef if
        -#                       the extension only tracks existence.
        -#
        -#   Returns:
        -#
        -#       Whether the definition was added, which is to say, whether this was the first definition for the passed <FileName>.
        -#
        -sub AddDefinition #(FileName file, optional NaturalDocs::SourceDB::ItemDefinition definition) => bool
        -    {
        -    my ($self, $file, $definition) = @_;
        -
        -    if (!defined $self->[DEFINITIONS])
        -        {  $self->[DEFINITIONS] = { };  };
        -
        -    if (!exists $self->[DEFINITIONS]->{$file})
        -        {
        -        if (!defined $definition)
        -            {  $definition = 1;  };
        -
        -        $self->[DEFINITIONS]->{$file} = $definition;
        -        return 1;
        -        }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: ChangeDefinition
        -#
        -#   Changes the definition for the passed <FileName>.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName>.
        -#       definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition>.
        -#
        -sub ChangeDefinition #(FileName file, NaturalDocs::SourceDB::ItemDefinition definition)
        -    {
        -    my ($self, $file, $definition) = @_;
        -
        -    if (!defined $self->[DEFINITIONS] || !exists $self->[DEFINITIONS]->{$file})
        -        {  die "Tried to change a non-existant definition in SourceD::Item.";  };
        -
        -    $self->[DEFINITIONS]->{$file} = $definition;
        -    };
        -
        -
        -#
        -#   Function: GetDefinition
        -#
        -#   Returns the <NaturalDocs::SourceDB::ItemDefinition>-derived object for the passed <FileName>, non-zero if it only tracks
        -#   existence, or undef if there is no definition.
        -#
        -sub GetDefinition #(FileName file) => NaturalDocs::SourceDB::ItemDefinition or bool
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (defined $self->[DEFINITIONS])
        -        {  return $self->[DEFINITIONS]->{$file};  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: DeleteDefinition
        -#
        -#   Removes the definition for the passed <FileName>.  Returns whether it was successful, meaning whether a definition existed
        -#   for that file.
        -#
        -sub DeleteDefinition #(FileName file) => bool
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (defined $self->[DEFINITIONS])
        -        {
        -        if (exists $self->[DEFINITIONS]->{$file})
        -            {
        -            delete $self->[DEFINITIONS]->{$file};
        -
        -            if (!scalar keys %{$self->[DEFINITIONS]})
        -                {  $self->[DEFINITIONS] = undef;  };
        -
        -            return 1;
        -            };
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -#
        -#   Function: HasDefinitions
        -#
        -#   Returns whether there are any definitions for this item.
        -#
        -sub HasDefinitions # => bool
        -    {
        -    my $self = shift;
        -    return (defined $self->[DEFINITIONS]);
        -    };
        -
        -
        -#
        -#   Function: HasDefinition
        -#
        -#   Returns whether there is a definition for the passed <FileName>.
        -#
        -sub HasDefinition #(FileName file) => bool
        -    {
        -    my ($self, $file) = @_;
        -
        -    if (defined $self->[DEFINITIONS])
        -        {  return (exists $self->[DEFINITIONS]->{$file});  }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: GetAllDefinitionsHashRef
        -#
        -#   Returns a hashref of all the definitions of this item.  *Do not change.*  The keys are the <FileNames>, and the values are
        -#   either <NaturalDocs::SourceDB::ItemDefinition>-derived objects or it's just an existence hashref if those aren't used.
        -#
        -sub GetAllDefinitionsHashRef
        -    {
        -    my $self = shift;
        -    return $self->[DEFINITIONS];
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm b/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm
        deleted file mode 100644
        index 5fe82f839..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm
        +++ /dev/null
        @@ -1,46 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SourceDB::ItemDefinition
        -#
        -###############################################################################
        -#
        -#   A base class for all item definitions for extensions that track more than existence.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::SourceDB::ItemDefinition;
        -
        -
        -#
        -#   Function: Compare
        -#
        -#   Returns whether the definitions are equal.  This version returns true by default, you must override it in your subclasses
        -#   to make the results relevant.  This is important for <NaturalDocs::SourceDB->AnalyzeTrackedFileChanges()>.
        -#
        -#   This will only be called between objects of the same <ExtensionID>.  If you use multiple derived classes for the same
        -#   <ExtensionID>, you will have to take that into account yourself.
        -#
        -#   Parameters:
        -#
        -#       other - Another <NaturalDocs::SourceDB::ItemDefinition>-derived object to compare this one to.  It will always be from
        -#                  the same <ExtensionID>.
        -#
        -#   Returns:
        -#
        -#       Whether they are equal.
        -#
        -sub Compare #(other)
        -    {
        -    return 1;
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm b/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm
        deleted file mode 100644
        index f42bbab38..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm
        +++ /dev/null
        @@ -1,160 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SourceDB::WatchedFileDefinitions
        -#
        -###############################################################################
        -#
        -#   A class to track the definitions appearing in a watched file.  This is only used for extensions that track definition info with
        -#   <NaturalDocs::SourceDB::ItemDefinition>-derived objects.  Do not use it for extensions that only track existence.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::SourceDB::WatchedFileDefinitions;
        -
        -
        -#
        -#   Variables: Members
        -#
        -#   This object would only have one member, which is an array, so the object itself serves as that member.
        -#
        -#   <ExtensionIDs> are used as indexes into this object.  Each entry is a hashref that maps item strings to
        -#   <NaturalDocs::SourceDB::ItemDefinition>-derived objects.  This is only done for extensions that use those objects to track
        -#   definitions, it's not needed for extensions that only track existence.  If there are no definitions, the entry will be undef.
        -#
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -sub New
        -    {
        -    my $class = shift;
        -
        -    my $object = [ ];
        -    bless $object, $class;
        -
        -    return $object;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Definition Functions
        -#
        -
        -
        -#
        -#   Function: AddDefinition
        -#
        -#   Adds a definition for the passed item string.  If it's already defined, the new definition will be ignored.
        -#
        -#   Parameters:
        -#
        -#       extension - The <ExtensionID>.
        -#       itemString - The item string.
        -#       definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition>.
        -#
        -#   Returns:
        -#
        -#       Whether the definition was added, which is to say, whether this was the first definition for the passed <FileName>.
        -#
        -sub AddDefinition #(ExtensionID extension, string itemString, NaturalDocs::SourceDB::ItemDefinition definition) => bool
        -    {
        -    my ($self, $extension, $itemString, $definition) = @_;
        -
        -    if (!defined $self->[$extension])
        -        {  $self->[$extension] = { };  };
        -
        -    if (!exists $self->[$extension]->{$itemString})
        -        {
        -        $self->[$extension]->{$itemString} = $definition;
        -        return 1;
        -        }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -#
        -#   Function: GetDefinition
        -#
        -#   Returns the <NaturalDocs::SourceDB::ItemDefinition>-derived object for the passed item string  or undef if there is none.
        -#
        -sub GetDefinition #(ExtensionID extension, string itemString) => NaturalDocs::SourceDB::ItemDefinition
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (defined $self->[$extension])
        -        {  return $self->[$extension]->{$itemString};  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: DeleteDefinition
        -#
        -#   Removes the definition for the passed item string.  Returns whether it was successful, meaning whether a definition existed
        -#   for that item.
        -#
        -sub DeleteDefinition #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (defined $self->[$extension])
        -        {
        -        if (exists $self->[$extension]->{$itemString})
        -            {
        -            delete $self->[$extension]->{$itemString};
        -
        -            if (!scalar keys %{$self->[$extension]})
        -                {  $self->[$extension] = undef;  };
        -
        -            return 1;
        -            };
        -        };
        -
        -    return 0;
        -    };
        -
        -
        -#
        -#   Function: HasDefinitions
        -#
        -#   Returns whether there are any definitions for this item.
        -#
        -sub HasDefinitions #(ExtensionID extension) => bool
        -    {
        -    my ($self, $extension) = @_;
        -
        -    return (defined $self->[$extension]);
        -    };
        -
        -
        -#
        -#   Function: HasDefinition
        -#
        -#   Returns whether there is a definition for the passed item string.
        -#
        -sub HasDefinition #(ExtensionID extension, string itemString) => bool
        -    {
        -    my ($self, $extension, $itemString) = @_;
        -
        -    if (defined $self->[$extension])
        -        {  return (exists $self->[$extension]->{$itemString});  }
        -    else
        -        {  return 0;  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/StatusMessage.pm b/vendor/naturaldocs/Modules/NaturalDocs/StatusMessage.pm
        deleted file mode 100644
        index e374c0e55..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/StatusMessage.pm
        +++ /dev/null
        @@ -1,103 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::StatusMessage
        -#
        -###############################################################################
        -#
        -#   A package to handle status message updates.  Automatically handles <NaturalDocs::Settings->IsQuiet()>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::StatusMessage;
        -
        -
        -#
        -#   var: message
        -#   The message to display.
        -#
        -my $message;
        -
        -#
        -#   var: total
        -#   The number of items to work through.
        -#
        -my $total;
        -
        -#
        -#   var: completed
        -#   The number of items completed.
        -#
        -my $completed;
        -
        -#
        -#   var: lastMessageTime
        -#   The time the last message was posted.
        -#
        -my $lastMessageTime;
        -
        -
        -#
        -#   constant: TIME_BETWEEN_UPDATES
        -#   The number of seconds that should occur between updates.
        -#
        -use constant TIME_BETWEEN_UPDATES => 10;
        -
        -
        -
        -#
        -#   Function: Start
        -#
        -#   Starts the status message.
        -#
        -#   Parameters:
        -#
        -#       message - The message to post.
        -#       total - The number of items that are going to be worked through.
        -#
        -sub Start #(message, total)
        -    {
        -    my $self = shift;
        -
        -    if (!NaturalDocs::Settings->IsQuiet())
        -        {
        -        ($message, $total) = @_;
        -        $completed = 0;
        -
        -        print $message . "\n";
        -
        -        $lastMessageTime = time();
        -        };
        -    };
        -
        -
        -#
        -#   Function: CompletedItem
        -#
        -#   Should be called every time an item is completed.
        -#
        -sub CompletedItem
        -    {
        -    my $self = shift;
        -
        -    if (!NaturalDocs::Settings->IsQuiet())
        -        {
        -        # We scale completed by 100 since we need to anyway to get the percentage.
        -
        -        $completed += 100;
        -
        -        if (time() >= $lastMessageTime + TIME_BETWEEN_UPDATES && $completed != $total * 100)
        -            {
        -            print $message . ' (' . ($completed / $total) . '%)' . "\n";
        -            $lastMessageTime = time();
        -            };
        -        };
        -    };
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolString.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolString.pm
        deleted file mode 100644
        index facebb289..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolString.pm
        +++ /dev/null
        @@ -1,213 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SymbolString
        -#
        -###############################################################################
        -#
        -#   A package to manage <SymbolString> handling throughout the program.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolString;
        -
        -
        -#
        -#   Function: FromText
        -#
        -#   Extracts and returns a <SymbolString> from plain text.
        -#
        -#   This should be the only way to get a <SymbolString> from plain text, as the splitting and normalization must be consistent
        -#   throughout the application.
        -#
        -sub FromText #(string textSymbol)
        -    {
        -    my ($self, $textSymbol) = @_;
        -
        -    # The internal format of a symbol is all the normalized identifiers separated by 0x1F characters.
        -
        -    # Convert whitespace and reserved characters to spaces, and condense multiple consecutive ones.
        -    $textSymbol =~ tr/ \t\r\n\x1C\x1D\x1E\x1F/ /s;
        -
        -    # DEPENDENCY: ReferenceString->MakeFrom() assumes all 0x1E characters were removed.
        -    # DEPENDENCY: ReferenceString->MakeFrom() assumes this encoding doesn't use 0x1E characters.
        -
        -    # Remove spaces unless they're separating two alphanumeric/underscore characters.
        -    $textSymbol =~ s/^ //;
        -    $textSymbol =~ s/ $//;
        -    $textSymbol =~ s/(\W) /$1/g;
        -    $textSymbol =~ s/ (\W)/$1/g;
        -
        -    # Remove trailing empty parenthesis, so Function and Function() are equivalent.
        -    $textSymbol =~ s/\(\)$//;
        -
        -    # Split the string into pieces.
        -    my @pieces = split(/(\.|::|->)/, $textSymbol);
        -    my $symbolString;
        -
        -    my $lastWasSeparator = 1;
        -
        -    foreach my $piece (@pieces)
        -        {
        -        if ($piece =~ /^(?:\.|::|->)$/)
        -            {
        -            if (!$lastWasSeparator)
        -                {
        -                $symbolString .= "\x1F";
        -                $lastWasSeparator = 1;
        -                };
        -            }
        -        elsif (length $piece)
        -            {
        -            $symbolString .= $piece;
        -            $lastWasSeparator = 0;
        -            };
        -        # Ignore empty pieces
        -        };
        -
        -    $symbolString =~ s/\x1F$//;
        -
        -    return $symbolString;
        -    };
        -
        -
        -#
        -#   Function: ToText
        -#
        -#   Converts a <SymbolString> to text, using the passed separator.
        -#
        -sub ToText #(SymbolString symbolString, string separator)
        -    {
        -    my ($self, $symbolString, $separator) = @_;
        -
        -    my @identifiers = $self->IdentifiersOf($symbolString);
        -    return join($separator, @identifiers);
        -    };
        -
        -
        -#
        -#   Function: ToBinaryFile
        -#
        -#   Writes a <SymbolString> to the passed filehandle.  Can also encode an undef.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The filehandle to write to.
        -#       symbol - The <SymbolString> to write, or undef.
        -#
        -#   Format:
        -#
        -#       > [UInt8: number of identifiers]
        -#       >    [AString16: identifier] [AString16: identifier] ...
        -#
        -#       Undef is represented by a zero for the number of identifiers.
        -#
        -sub ToBinaryFile #(FileHandle fileHandle, SymbolString symbol)
        -    {
        -    my ($self, $fileHandle, $symbol) = @_;
        -
        -    my @identifiers;
        -    if (defined $symbol)
        -        {  @identifiers = $self->IdentifiersOf($symbol);  };
        -
        -    print $fileHandle pack('C', scalar @identifiers);
        -
        -    foreach my $identifier (@identifiers)
        -        {
        -        print $fileHandle pack('nA*', length($identifier), $identifier);
        -        };
        -    };
        -
        -
        -#
        -#   Function: FromBinaryFile
        -#
        -#   Loads a <SymbolString> or undef from the filehandle and returns it.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The filehandle to read from.
        -#
        -#   Returns:
        -#
        -#       The <SymbolString> or undef.
        -#
        -#   See also:
        -#
        -#       See <ToBinaryFile()> for format and dependencies.
        -#
        -sub FromBinaryFile #(FileHandle fileHandle)
        -    {
        -    my ($self, $fileHandle) = @_;
        -
        -    my $raw;
        -
        -    # [UInt8: number of identifiers or 0 if none]
        -
        -    read($fileHandle, $raw, 1);
        -    my $identifierCount = unpack('C', $raw);
        -
        -    my @identifiers;
        -
        -    while ($identifierCount)
        -        {
        -        # [AString16: identifier] [AString16: identifier] ...
        -
        -        read($fileHandle, $raw, 2);
        -        my $identifierLength = unpack('n', $raw);
        -
        -        my $identifier;
        -        read($fileHandle, $identifier, $identifierLength);
        -
        -        push @identifiers, $identifier;
        -
        -        $identifierCount--;
        -        };
        -
        -    if (scalar @identifiers)
        -        {  return $self->Join(@identifiers);  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: IdentifiersOf
        -#
        -#   Returns the <SymbolString> as an array of identifiers.
        -#
        -sub IdentifiersOf #(SymbolString symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -    return split(/\x1F/, $symbol);
        -    };
        -
        -
        -#
        -#   Function: Join
        -#
        -#   Takes a list of identifiers and/or <SymbolStrings> and returns it as a new <SymbolString>.
        -#
        -sub Join #(string/SymbolString identifier/symbol, string/SymolString identifier/symbol, ...)
        -    {
        -    my ($self, @pieces) = @_;
        -
        -    # Can't have undefs screwing everything up.
        -    while (scalar @pieces && !defined $pieces[0])
        -        {  shift @pieces;  };
        -
        -    # We need to test @pieces first because joining on an empty array returns an empty string rather than undef.
        -    if (scalar @pieces)
        -       {  return join("\x1F", @pieces);  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable.pm
        deleted file mode 100644
        index cf868bd6f..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable.pm
        +++ /dev/null
        @@ -1,1985 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SymbolTable
        -#
        -###############################################################################
        -#
        -#   A package that handles all the gory details of managing symbols.  It handles where they are defined, which files
        -#   reference them, if any are undefined or duplicated, and loading and saving them to a file.
        -#
        -#   Usage and Dependencies:
        -#
        -#       - At any time, <RebuildAllIndexes()> can be called.
        -#
        -#       - <NaturalDocs::Settings>, <NaturalDocs::Languages>, and <NaturalDocs::Project> must be initialized before use.
        -#
        -#       - <Load()> must be called to initialize the package.  At this point, the <Information Functions> will return the symbol
        -#         table as of the last time Natural Docs was run.
        -#
        -#       - Note that <Load()> and <Save()> only manage <REFERENCE_TEXT> references.  All other reference types must be
        -#         managed by their respective classes.  They should be readded after <Load()> to recreate the state of the last time
        -#         Natural Docs was run.
        -#
        -#       - <Purge()> must be called, and then <NaturalDocs::Parser->ParseForInformation()> on all files that have changed so it
        -#         can fully resolve the symbol table via the <Modification Functions>.  Afterwards <PurgeResolvingInfo()> can be called
        -#         to reclaim some memory, and the symbol table will reflect the current state of the code.
        -#
        -#       - <Save()> must be called to commit any changes to the symbol table back to disk.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -
        -use NaturalDocs::SymbolTable::Symbol;
        -use NaturalDocs::SymbolTable::SymbolDefinition;
        -use NaturalDocs::SymbolTable::Reference;
        -use NaturalDocs::SymbolTable::File;
        -use NaturalDocs::SymbolTable::ReferenceTarget;
        -use NaturalDocs::SymbolTable::IndexElement;
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolTable;
        -
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -#
        -#   handle: SYMBOLTABLE_FILEHANDLE
        -#
        -#   The file handle used with <SymbolTable.nd>.
        -#
        -
        -#
        -#   hash: symbols
        -#
        -#   A hash of all <SymbolStrings>.  The keys are the <SymbolStrings> and the values are <NaturalDocs::SymbolTable::Symbol>
        -#   objects.
        -#
        -#   Prior to <PurgeResolvingInfo()>, both defined symbols and symbols that are merely potential interpretations of references
        -#   will be here.  Afterwards, only defined symbols will be here.
        -#
        -my %symbols;
        -
        -#
        -#   hash: references
        -#
        -#   A hash of all references in the project.  The keys are <ReferenceStrings> and the values are
        -#   <NaturalDocs::SymbolTable::Reference> objects.
        -#
        -#   Prior to <PurgeResolvingInfo()>, all possible interpretations will be stored for each reference.  Afterwards, only the current
        -#   interpretation will be.
        -#
        -my %references;
        -
        -#
        -#   hash: files
        -#
        -#   A hash of all the files that define symbols and references in the project.  The keys are the <FileNames>, and the values are
        -#   <NaturalDocs::SymbolTable::File> objects.
        -#
        -#   After <PurgeResolvingInfo()>, this hash will be empty.
        -#
        -my %files;
        -
        -#
        -#   object: watchedFile
        -#
        -#   A <NaturalDocs::SymbolTable::File> object of the file being watched for changes.  This is compared to the version in <files>
        -#   to see if anything was changed since the last parse.
        -#
        -my $watchedFile;
        -
        -#
        -#   string: watchedFileName
        -#
        -#   The <FileName> of the watched file, if any.  If there is no watched file, this will be undef.
        -#
        -my $watchedFileName;
        -
        -#
        -#   hash: watchedFileSymbolDefinitions
        -#
        -#   A hashref of the symbol definition information for all the <SymbolStrings> in the watched file.  The keys are the symbol strings,
        -#   and the values are <NaturalDocs::SymbolTable::SymbolDefinition> objects.
        -#
        -my %watchedFileSymbolDefinitions;
        -
        -
        -#
        -#   hash: indexes
        -#
        -#   A hash of generated symbol indexes.  The keys are <TopicTypes> and the values are sorted arrayrefs of
        -#   <NaturalDocs::SymbolTable::IndexElements>, or undef if its empty.
        -#
        -my %indexes;
        -
        -
        -#
        -#   hash: indexChanges
        -#
        -#   A hash of all the indexes that have changed.  The keys are the <TopicTypes> and the entries are undef if they have not
        -#   changed, or 1 if they have.  The key will not exist if the <TopicType> has not been checked.
        -#
        -my %indexChanges;
        -
        -
        -#
        -#   hash: indexSectionsWithContent
        -#
        -#   A hash of which sections in an index have content.  The keys are the <TopicTypes> of each index, and the values are
        -#   arrayrefs of bools where the first represents symbols, the second numbers, and the rest A-Z.  If there is no information
        -#   available for an index, it's entry will not exist here.
        -#
        -my %indexSectionsWithContent;
        -
        -
        -#
        -#   bool: rebuildIndexes
        -#
        -#   Whether all indexes should be rebuilt regardless of whether they have been changed.
        -#
        -my $rebuildIndexes;
        -
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: SymbolTable.nd
        -#
        -#   The storage file for the symbol table.
        -#
        -#   Format:
        -#
        -#       > [BINARY_FORMAT]
        -#       > [VersionInt: app version]
        -#
        -#       The file starts with the standard <BINARY_FORMAT> <VersionInt> header.
        -#
        -#       The first stage of the file is for symbol definitions, analogous to <symbols>.
        -#
        -#       > [SymbolString: symbol or undef to end] ...
        -#       >
        -#       > [UInt16: number of definitions]
        -#       >
        -#       >    [AString16: global definition file] [AString16: TopicType]
        -#       >       [AString16: prototype] [AString16: summary]
        -#       >
        -#       >    [AString16: definition file] ...
        -#       >
        -#       >    ...
        -#
        -#       These blocks continue until the <SymbolString> is undef.  Only defined symbols will be included in this file, so
        -#       number of definitions will never be zero.  The first one is always the global definition.  If a symbol does not have a
        -#       prototype or summary, the UInt16 length of the string will be zero.
        -#
        -#       The second stage is for references, which is analogous to <references>.  Only <REFERENCE_TEXT> references are
        -#       stored in this file, and their <Resolving Flags> are implied so they aren't stored either.
        -#
        -#       > [ReferenceString (no type, resolving flags): reference or undef to end]
        -#       >
        -#       > [UInt8: number of definition files]
        -#       >    [AString16: definition file] [AString16: definition file] ...
        -#
        -#       These blocks continue until the <ReferenceString> is undef.  Since there can be multiple using <SymbolStrings>, those
        -#       continue until the number of identifiers is zero.  Note that all interpretations are rebuilt rather than stored.
        -#
        -#   See Also:
        -#
        -#       <File Format Conventions>
        -#
        -#   Revisions:
        -#
        -#       1.3:
        -#
        -#           - Symbol <TopicTypes> were changed from UInt8s to AString16s, now that <TopicTypes> are strings instead of
        -#             integer constants.
        -#
        -#       1.22:
        -#
        -#           - File format was completely rebuilt to accommodate the new symbol format and to be in binary.  To see the plain text
        -#             format prior to 1.22, check out 1.21's version of this file from CVS.  It is too big a change to note here.
        -#
        -
        -
        -#
        -#   File: IndexInfo.nd
        -#
        -#   The storage file for information about the indexes.
        -#
        -#   Format:
        -#
        -#       > [Standard Header]
        -#
        -#       The standard binary file header.
        -#
        -#       > [AString16: index topic name]
        -#       > [uint8: symbols have content (0 or 1)]
        -#       > [uint8: numbers have content (0 or 1)]
        -#       > [uint8: A has content] [uint8: B has content] ...
        -#       > ...
        -#
        -#       Every index that has information about it is stored with the topic type name first, then 28 uint8s that say whether that
        -#       part of the index has content or not.  The first is for symbols, the second is for numbers, and the rest are for A-Z.  If an
        -#       index's state is unknown, it won't appear in this file.
        -#
        -#   Revisions:
        -#
        -#       1.4:
        -#
        -#           - The file is introduced.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Loads all data files from disk.
        -#
        -sub Load
        -    {
        -    my ($self) = @_;
        -
        -    $self->LoadSymbolTable();
        -    $self->LoadIndexInfo();
        -    };
        -
        -
        -#
        -#   Function: LoadSymbolTable
        -#
        -#   Loads <SymbolTable.nd> from disk.
        -#
        -sub LoadSymbolTable
        -    {
        -    my ($self) = @_;
        -
        -    my $fileIsOkay;
        -
        -    if (!NaturalDocs::Settings->RebuildData() &&
        -        open(SYMBOLTABLE_FILEHANDLE, '<' . NaturalDocs::Project->DataFile('SymbolTable.nd')) )
        -        {
        -        # See if it's binary.
        -        binmode(SYMBOLTABLE_FILEHANDLE);
        -
        -        my $firstChar;
        -        read(SYMBOLTABLE_FILEHANDLE, $firstChar, 1);
        -
        -        if ($firstChar == ::BINARY_FORMAT())
        -            {
        -            my $version = NaturalDocs::Version->FromBinaryFile(\*SYMBOLTABLE_FILEHANDLE);
        -
        -            # 1.3 is incompatible with previous versions.
        -
        -            if (NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.3') ))
        -                {  $fileIsOkay = 1;  }
        -            else
        -                {  close(SYMBOLTABLE_FILEHANDLE);  };
        -            }
        -
        -        else
        -            {  close(SYMBOLTABLE_FILEHANDLE);  };
        -        };
        -
        -
        -    if (!$fileIsOkay)
        -        {
        -        NaturalDocs::Project->ReparseEverything();
        -        return;
        -        }
        -
        -    my $raw;
        -
        -
        -    # Symbols
        -
        -    for (;;)
        -        {
        -        # [SymbolString: symbol or undef to end]
        -
        -        my $symbol = NaturalDocs::SymbolString->FromBinaryFile(\*SYMBOLTABLE_FILEHANDLE);
        -
        -        if (!defined $symbol)
        -            {  last;  };
        -
        -        my $symbolObject = NaturalDocs::SymbolTable::Symbol->New();
        -        $symbols{$symbol} = $symbolObject;
        -
        -        # [UInt16: number of definitions]
        -
        -        read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
        -        my $definitionCount = unpack('n', $raw);
        -
        -        do
        -            {
        -            # [AString16: (global?) definition file]
        -
        -            read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
        -            my $fileLength = unpack('n', $raw);
        -
        -            my $file;
        -            read(SYMBOLTABLE_FILEHANDLE, $file, $fileLength);
        -
        -            # [AString16: TopicType]
        -
        -            read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
        -            my $typeLength = unpack('n', $raw);
        -
        -            my $type;
        -            read(SYMBOLTABLE_FILEHANDLE, $type, $typeLength);
        -
        -            # [AString16: prototype]
        -
        -            read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
        -            my $prototypeLength = unpack('n', $raw);
        -
        -            my $prototype;
        -            if ($prototypeLength)
        -                {  read(SYMBOLTABLE_FILEHANDLE, $prototype, $prototypeLength);  };
        -
        -            # [AString16: summary]
        -
        -            read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
        -            my $summaryLength = unpack('n', $raw);
        -
        -            my $summary;
        -            if ($summaryLength)
        -                {  read(SYMBOLTABLE_FILEHANDLE, $summary, $summaryLength);  };
        -
        -            $symbolObject->AddDefinition($file, $type, $prototype, $summary);
        -
        -            # Add it.
        -
        -            if (!exists $files{$file})
        -                {  $files{$file} = NaturalDocs::SymbolTable::File->New();  };
        -
        -            $files{$file}->AddSymbol($symbol);
        -
        -            $definitionCount--;
        -            }
        -        while ($definitionCount);
        -        };
        -
        -
        -    # References
        -
        -    for (;;)
        -        {
        -        # [ReferenceString (no type, resolving flags): reference or undef to end]
        -
        -        my $referenceString = NaturalDocs::ReferenceString->FromBinaryFile(\*SYMBOLTABLE_FILEHANDLE,
        -                                                                                                              ::BINARYREF_NOTYPE() |
        -                                                                                                              ::BINARYREF_NORESOLVINGFLAGS(),
        -                                                                                                              ::REFERENCE_TEXT(), undef);
        -
        -        if (!defined $referenceString)
        -            {  last;  };
        -
        -        my $referenceObject = NaturalDocs::SymbolTable::Reference->New();
        -        $references{$referenceString} = $referenceObject;
        -
        -        # [UInt8: number of definition files]
        -
        -        read(SYMBOLTABLE_FILEHANDLE, $raw, 1);
        -        my $definitionCount = unpack('C', $raw);
        -        do
        -            {
        -            # [AString16: definition file] [AString16: definition file] ...
        -
        -            read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
        -            my $definitionLength = unpack('n', $raw);
        -
        -            my $definition;
        -            read(SYMBOLTABLE_FILEHANDLE, $definition, $definitionLength);
        -
        -            # Add it.
        -
        -            $referenceObject->AddDefinition($definition);
        -
        -            if (!exists $files{$definition})
        -                {  $files{$definition} = NaturalDocs::SymbolTable::File->New();  };
        -
        -            $files{$definition}->AddReference($referenceString);
        -
        -            $definitionCount--;
        -            }
        -        while ($definitionCount);
        -
        -        $self->GenerateInterpretations($referenceString);
        -        $self->InterpretReference($referenceString);
        -        };
        -
        -    close(SYMBOLTABLE_FILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: LoadIndexInfo
        -#
        -#   Loads <IndexInfo.nd> from disk.
        -#
        -sub LoadIndexInfo
        -    {
        -    my ($self) = @_;
        -
        -    if (NaturalDocs::Settings->RebuildData())
        -        {  return;  };
        -
        -    my $version = NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('IndexInfo.nd') );
        -
        -    if (!defined $version)
        -        {  return;  }
        -
        -    # The file format hasn't changed since it was introduced.
        -    if (!NaturalDocs::Version->CheckFileFormat($version))
        -        {
        -        NaturalDocs::BinaryFile->Close();
        -        return;
        -        };
        -
        -    my $topicTypeName;
        -    while ($topicTypeName = NaturalDocs::BinaryFile->GetAString16())
        -        {
        -        my $topicType = NaturalDocs::Topics->TypeFromName($topicTypeName);
        -        my $content = [ ];
        -
        -        for (my $i = 0; $i < 28; $i++)
        -            {  push @$content, NaturalDocs::BinaryFile->GetUInt8();  };
        -
        -        if (defined $topicType)  # The name in the file could be from a type that was deleted
        -            {  $indexSectionsWithContent{$topicType} = $content;  };
        -        };
        -
        -    NaturalDocs::BinaryFile->Close();
        -    };
        -
        -
        -#
        -#   Function: Purge
        -#
        -#   Purges the symbol table of all symbols and references from files that no longer have Natural Docs content.
        -#
        -sub Purge
        -    {
        -    my ($self) = @_;
        -
        -    my $filesToPurge = NaturalDocs::Project->FilesToPurge();
        -
        -    # We do this in two stages.  First we delete all the references, and then we delete all the definitions.  This causes us to go
        -    # through the list twice, but it makes sure no purged files get added to the build list.  For example, if we deleted all of
        -    # Purge File A's references and definitions, and Purge File B had a reference to one of those symbols, Purge File B
        -    # would be added to the build list because one of its references changed.  By removing all the references in all the files
        -    # before removing the definitions, we avoid this.
        -
        -    foreach my $file (keys %$filesToPurge)
        -        {
        -        if (exists $files{$file})
        -            {
        -            my @references = $files{$file}->References();
        -            foreach my $reference (@references)
        -                {  $self->DeleteReference($reference, $file);  };
        -            };
        -        };
        -
        -    foreach my $file (keys %$filesToPurge)
        -        {
        -        if (exists $files{$file})
        -            {
        -            my @symbols = $files{$file}->Symbols();
        -            foreach my $symbol (@symbols)
        -                {  $self->DeleteSymbol($symbol, $file);  };
        -
        -            delete $files{$file};
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves all data files to disk.
        -#
        -sub Save
        -    {
        -    my ($self) = @_;
        -
        -    $self->SaveSymbolTable();
        -    $self->SaveIndexInfo();
        -    };
        -
        -
        -#
        -#   Function: SaveSymbolTable
        -#
        -#   Saves <SymbolTable.nd> to disk.
        -#
        -sub SaveSymbolTable
        -    {
        -    my ($self) = @_;
        -
        -    open (SYMBOLTABLE_FILEHANDLE, '>' . NaturalDocs::Project->DataFile('SymbolTable.nd'))
        -        or die "Couldn't save " . NaturalDocs::Project->DataFile('SymbolTable.nd') . ".\n";
        -
        -    binmode(SYMBOLTABLE_FILEHANDLE);
        -
        -    print SYMBOLTABLE_FILEHANDLE '' . ::BINARY_FORMAT();
        -
        -    NaturalDocs::Version->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, NaturalDocs::Settings->AppVersion());
        -
        -
        -    # Symbols
        -
        -    while (my ($symbol, $symbolObject) = each %symbols)
        -        {
        -        # Only existing symbols.
        -        if ($symbolObject->IsDefined())
        -            {
        -            # [SymbolString: symbol or undef to end]
        -
        -            NaturalDocs::SymbolString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, $symbol);
        -
        -            # [UInt16: number of definitions]
        -
        -            my @definitions = $symbolObject->Definitions();
        -            print SYMBOLTABLE_FILEHANDLE pack('n', scalar @definitions);
        -
        -            # [AString16: global definition file] [AString16: TopicType]
        -
        -            print SYMBOLTABLE_FILEHANDLE pack('nA*nA*', length $symbolObject->GlobalDefinition(),
        -                                                                                   $symbolObject->GlobalDefinition(),
        -                                                                                   length $symbolObject->GlobalType(),
        -                                                                                   $symbolObject->GlobalType());
        -
        -            # [AString16: prototype]
        -
        -            my $prototype = $symbolObject->GlobalPrototype();
        -
        -            if (defined $prototype)
        -                {  print SYMBOLTABLE_FILEHANDLE pack('nA*', length($prototype), $prototype);  }
        -            else
        -                {  print SYMBOLTABLE_FILEHANDLE pack('n', 0);  };
        -
        -            # [AString16: summary]
        -
        -            my $summary = $symbolObject->GlobalSummary();
        -
        -            if (defined $summary)
        -                {  print SYMBOLTABLE_FILEHANDLE pack('nA*', length($summary), $summary);  }
        -            else
        -                {  print SYMBOLTABLE_FILEHANDLE pack('n', 0);  };
        -
        -
        -            foreach my $definition (@definitions)
        -                {
        -                if ($definition ne $symbolObject->GlobalDefinition())
        -                    {
        -                    # [AString16: definition file] [AString16: TopicType]
        -
        -                    print SYMBOLTABLE_FILEHANDLE pack('nA*nA*', length $definition, $definition,
        -                                                                                           length $symbolObject->TypeDefinedIn($definition),
        -                                                                                           $symbolObject->TypeDefinedIn($definition));
        -
        -                    # [AString16: prototype]
        -
        -                    my $prototype = $symbolObject->PrototypeDefinedIn($definition);
        -
        -                    if (defined $prototype)
        -                        {  print SYMBOLTABLE_FILEHANDLE pack('nA*', length($prototype), $prototype);  }
        -                    else
        -                        {  print SYMBOLTABLE_FILEHANDLE pack('n', 0);  };
        -
        -                    # [AString16: summary]
        -
        -                    my $summary = $symbolObject->SummaryDefinedIn($definition);
        -
        -                    if (defined $summary)
        -                        {  print SYMBOLTABLE_FILEHANDLE pack('nA*', length($summary), $summary);  }
        -                    else
        -                        {  print SYMBOLTABLE_FILEHANDLE pack('n', 0);  };
        -                    };
        -                };
        -            };
        -        };
        -
        -     # [SymbolString: symbol or undef to end]
        -
        -     NaturalDocs::SymbolString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, undef);
        -
        -
        -     # References
        -
        -    while (my ($reference, $referenceObject) = each %references)
        -        {
        -        my $type = NaturalDocs::ReferenceString->TypeOf($reference);
        -
        -        if ($type == ::REFERENCE_TEXT())
        -            {
        -            # [ReferenceString (no type, resolving flags): reference or undef to end]
        -
        -            NaturalDocs::ReferenceString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, $reference,
        -                                                                             ::BINARYREF_NOTYPE() | ::BINARYREF_NORESOLVINGFLAGS());
        -
        -            # [UInt8: number of definition files]
        -
        -            my @definitions = $referenceObject->Definitions();
        -            print SYMBOLTABLE_FILEHANDLE pack('C', scalar @definitions);
        -
        -            # [AString16: definition file] [AString16: definition file] ...
        -
        -            foreach my $definition (@definitions)
        -                {
        -                print SYMBOLTABLE_FILEHANDLE pack('nA*', length($definition), $definition);
        -                };
        -            };
        -        };
        -
        -    # [ReferenceString (no type, resolving flags): reference or undef to end]
        -
        -    NaturalDocs::ReferenceString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, undef,
        -                                                                     ::BINARYREF_NOTYPE() | ::BINARYREF_NORESOLVINGFLAGS());
        -
        -    close(SYMBOLTABLE_FILEHANDLE);
        -    };
        -
        -
        -#
        -#   Function: SaveIndexInfo
        -#
        -#   Saves <IndexInfo.nd> to disk.
        -#
        -sub SaveIndexInfo
        -    {
        -    my ($self) = @_;
        -
        -    NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('IndexInfo.nd') );
        -
        -    while (my ($topicType, $content) = each %indexSectionsWithContent)
        -        {
        -        NaturalDocs::BinaryFile->WriteAString16( NaturalDocs::Topics->NameOfType($topicType) );
        -
        -        for (my $i = 0; $i < 28; $i++)
        -            {
        -            if ($content->[$i])
        -                {  NaturalDocs::BinaryFile->WriteUInt8(1);  }
        -            else
        -                {  NaturalDocs::BinaryFile->WriteUInt8(0);  };
        -            };
        -        };
        -
        -    NaturalDocs::BinaryFile->Close();
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -# These functions should not be called after <PurgeResolvingInfo()>.
        -
        -#
        -#   Function: AddSymbol
        -#
        -#   Adds a symbol definition to the table, if it doesn't already exist.  If the definition changes or otherwise requires the files that
        -#   reference it to be updated, the function will call <NaturalDocs::Project->RebuildFile()> to make sure that they are.
        -#
        -#   Parameters:
        -#
        -#       symbol  - The <SymbolString>.
        -#       file        - The <FileName> where it's defined.
        -#       type      - The symbol's <TopicType>.
        -#       prototype - The symbol's prototype, if applicable.
        -#       summary - The symbol's summary, if applicable.
        -#
        -sub AddSymbol #(symbol, file, type, prototype, summary)
        -    {
        -    my ($self, $symbol, $file, $type, $prototype, $summary) = @_;
        -
        -
        -    # If the symbol doesn't exist...
        -    if (!exists $symbols{$symbol})
        -        {
        -        # Create the symbol.  There are no references that could be interpreted as this or else it would have existed already.
        -
        -        my $newSymbol = NaturalDocs::SymbolTable::Symbol->New();
        -        $newSymbol->AddDefinition($file, $type, $prototype, $summary);
        -
        -        $symbols{$symbol} = $newSymbol;
        -
        -        $self->OnIndexChange($type);
        -        NaturalDocs::Project->RebuildFile($file);
        -        }
        -
        -
        -    # If the symbol already exists...
        -    else
        -        {
        -        my $symbolObject = $symbols{$symbol};
        -
        -        # If the symbol isn't defined, i.e. it was a potential interpretation only...
        -        if (!$symbolObject->IsDefined())
        -            {
        -            $symbolObject->AddDefinition($file, $type, $prototype, $summary);
        -
        -            # See if this symbol provides a better interpretation of any references.  We can assume this symbol has interpretations
        -            # because the object won't exist without either that or definitions.
        -
        -            my %referencesAndScores = $symbolObject->ReferencesAndScores();
        -
        -            while (my ($referenceString, $referenceScore) = each %referencesAndScores)
        -                {
        -                my $referenceObject = $references{$referenceString};
        -
        -                if (!$referenceObject->HasCurrentInterpretation() ||
        -                    $referenceScore > $referenceObject->CurrentScore())
        -                    {
        -                    $referenceObject->SetCurrentInterpretation($symbol);
        -                    $self->OnInterpretationChange($referenceString);
        -                    };
        -                };
        -
        -            $self->OnIndexChange($type);
        -            NaturalDocs::Project->RebuildFile($file);
        -            }
        -
        -        # If the symbol is defined but not in this file...
        -        elsif (!$symbolObject->IsDefinedIn($file))
        -            {
        -            $symbolObject->AddDefinition($file, $type, $prototype, $summary);
        -
        -            $self->OnIndexChange($type);
        -            NaturalDocs::Project->RebuildFile($file);
        -
        -            # We don't have to check other files because if the symbol is defined it already has a global definiton,
        -            # and everything else is either using that or its own definition, and thus wouldn't be affected by this.
        -            };
        -
        -        # If the symbol was already defined in this file, ignore it.
        -
        -        };
        -
        -
        -    # Add it to the file index.
        -
        -    if (!exists $files{$file})
        -        {  $files{$file} = NaturalDocs::SymbolTable::File->New();  };
        -
        -    $files{$file}->AddSymbol($symbol);
        -
        -
        -    # Add it to the watched file, if necessary.
        -
        -    if (defined $watchedFileName)
        -        {
        -        $watchedFile->AddSymbol($symbol);
        -
        -        if (!exists $watchedFileSymbolDefinitions{$symbol})
        -            {
        -            $watchedFileSymbolDefinitions{$symbol} =
        -                 NaturalDocs::SymbolTable::SymbolDefinition->New($type, $prototype, $summary);
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: AddReference
        -#
        -#   Adds a reference to the table, if it doesn't already exist.
        -#
        -#   Parameters:
        -#
        -#       type        - The <ReferenceType>.
        -#       symbol    - The reference <SymbolString>.
        -#       scope      - The scope <SymbolString> it appears in.
        -#       using       - An arrayref of scope <SymbolStrings> accessible to the reference via "using" statements, or undef if none.
        -#       file          - The <FileName> where the reference appears.  This is not required unless the type is <REFERENCE_TEXT>.
        -#       resolvingFlags - The <Resolving Flags> of the reference.  They will be ignored if the type is <REFERENCE_TEXT>.
        -#
        -#   Alternate Parameters:
        -#
        -#       referenceString - The <ReferenceString> to add.
        -#       file - The <FileName> where the reference appears.  This is not required unless the type is <REFERENCE_TEXT>.
        -#
        -sub AddReference #(type, symbol, scope, using, file, resolvingFlags) or (referenceString, file)
        -    {
        -    my ($self, $referenceString, $file);
        -
        -    if (scalar @_ <= 3)
        -        {
        -        ($self, $referenceString, $file) = @_;
        -        }
        -    else
        -        {
        -        my ($type, $symbol, $scope, $using, $resolvingFlags);
        -        ($self, $type, $symbol, $scope, $using, $file, $resolvingFlags) = @_;
        -
        -        $referenceString = NaturalDocs::ReferenceString->MakeFrom($type, $symbol,
        -                                                                                                   NaturalDocs::Languages->LanguageOf($file)->Name(),
        -                                                                                                   $scope, $using, $resolvingFlags);
        -        };
        -
        -
        -    # If the reference doesn't exist...
        -    if (!exists $references{$referenceString})
        -        {
        -        my $referenceObject = NaturalDocs::SymbolTable::Reference->New();
        -
        -        $references{$referenceString} = $referenceObject;
        -
        -        $self->GenerateInterpretations($referenceString);
        -        $self->InterpretReference($referenceString);
        -        }
        -
        -
        -    if (defined $file)
        -        {
        -        $references{$referenceString}->AddDefinition($file);
        -
        -
        -        # Add it to the file index.
        -
        -        if (!exists $files{$file})
        -            {  $files{$file} = NaturalDocs::SymbolTable::File->New();  };
        -
        -        $files{$file}->AddReference($referenceString);
        -
        -
        -        # Add it to the watched file, if necessary.
        -
        -        if (defined $watchedFileName)
        -            {  $watchedFile->AddReference($referenceString);  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: WatchFileForChanges
        -#
        -#   Tracks a file to see if any symbols or references were changed or deleted in ways that would require other files to be rebuilt.
        -#   Assumes that after this function call, the entire file will be parsed again, and thus every symbol and reference will go through
        -#   <AddSymbol()> and <AddReference()>.  Afterwards, call <AnalyzeChanges()> to handle any differences.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> to watch.
        -#
        -sub WatchFileForChanges #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    $watchedFile = NaturalDocs::SymbolTable::File->New();
        -    $watchedFileName = $file;
        -    %watchedFileSymbolDefinitions = ( );
        -    };
        -
        -
        -#
        -#   Function: AnalyzeChanges
        -#
        -#   Handles any changes found when reparsing a file using <WatchFileForChanges()>.
        -#
        -sub AnalyzeChanges
        -    {
        -    my ($self) = @_;
        -
        -    if (exists $files{$watchedFileName})
        -        {
        -
        -        # Go through the references and remove any that were deleted.  Ones that were added will have already been added to
        -        # the table in AddReference().
        -
        -        my @references = $files{$watchedFileName}->References();
        -        foreach my $reference (@references)
        -            {
        -            if (!$watchedFile->DefinesReference($reference))
        -                {  $self->DeleteReference($reference, $watchedFileName);  };
        -            };
        -        };
        -
        -    # We have to check if the watched file exists again because DeleteReference() could have removed it.  I'm still not sure how a
        -    # file could have references without symbols, but apparently it's happened in the real world because it's crashed on people.
        -    if (exists $files{$watchedFileName})
        -        {
        -        # Go through the symbols.
        -
        -        my $rebuildFile;
        -
        -        my @symbols = $files{$watchedFileName}->Symbols();
        -        foreach my $symbol (@symbols)
        -            {
        -            # Delete symbols that don't exist.
        -
        -            if (!$watchedFile->DefinesSymbol($symbol))
        -                {
        -                $self->DeleteSymbol($symbol, $watchedFileName);
        -                $rebuildFile = 1;
        -                }
        -
        -            else
        -                {
        -                my $symbolObject = $symbols{$symbol};
        -                my $newSymbolDef = $watchedFileSymbolDefinitions{$symbol};
        -
        -                # Update symbols that changed.
        -
        -                if ( $symbolObject->TypeDefinedIn($watchedFileName) ne $newSymbolDef->Type() ||
        -                     $symbolObject->PrototypeDefinedIn($watchedFileName) ne $newSymbolDef->Prototype() ||
        -                     $symbolObject->SummaryDefinedIn($watchedFileName) ne $newSymbolDef->Summary() )
        -                    {
        -                    $self->OnIndexChange($symbolObject->TypeDefinedIn($watchedFileName));
        -                    $self->OnIndexChange($newSymbolDef->Type());
        -                    $rebuildFile = 1;
        -
        -                    $symbolObject->ChangeDefinition($watchedFileName, $newSymbolDef->Type(), $newSymbolDef->Prototype(),
        -                                                                       $newSymbolDef->Summary());
        -
        -                    # If the symbol definition was the global one, we need to update all files that reference it.  If it wasn't, the only file
        -                    # that could references it is itself, and the only way the symbol definition could change in the first place was if it was
        -                    # itself changed.
        -                    if ($symbolObject->GlobalDefinition() eq $watchedFileName)
        -                        {
        -                        # Rebuild the files that have references to this symbol
        -                        my @references = $symbolObject->References();
        -                        foreach my $reference (@references)
        -                            {
        -                            if ($references{$reference}->CurrentInterpretation() eq $symbol)
        -                                {  $self->OnTargetSymbolChange($reference);  };
        -                            }; # While references
        -                        }; # If global definition is watched file
        -                    }; # If the symbol definition changed
        -                }; # If the symbol still exists
        -            }; # foreach symbol in watched file
        -
        -        if ($rebuildFile)
        -            {  NaturalDocs::Project->RebuildFile($watchedFileName);  };
        -
        -        };
        -
        -
        -    $watchedFile = undef;
        -    $watchedFileName = undef;
        -    %watchedFileSymbolDefinitions = ( );
        -    };
        -
        -
        -#
        -#   Function: DeleteReference
        -#
        -#   Deletes a reference from the table.
        -#
        -#   Be careful with this function, as deleting a reference means there are no more of them in the file at all.  The tables do not
        -#   keep track of how many times references appear in a file.  In these cases you should instead call <WatchFileForChanges()>,
        -#   reparse the file, thus readding all the references, and call <AnalyzeChanges()>.
        -#
        -#   <REFERENCE_TEXT> references should *always* be managed with <WatchFileForChanges()> and <AnalyzeChanges()>.
        -#   This function should only be used externally for other types of references.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString>.
        -#       file - The <FileName> where the reference is.  This is not required unless the type is <REFERENCE_TEXT>.
        -#
        -sub DeleteReference #(referenceString, file)
        -    {
        -    my ($self, $referenceString, $file) = @_;
        -
        -
        -    # If the reference exists...
        -    if (exists $references{$referenceString})
        -        {
        -        my $referenceObject = $references{$referenceString};
        -
        -        if (defined $file)
        -            {  $referenceObject->DeleteDefinition($file);  };
        -
        -        # If there are no other definitions, or it doesn't use file definitions to begin with...
        -        if (!$referenceObject->IsDefined())
        -            {
        -            my @interpretations = $referenceObject->Interpretations();
        -            foreach my $interpretation (@interpretations)
        -                {
        -                $symbols{$interpretation}->DeleteReference($referenceString);
        -                };
        -
        -            delete $references{$referenceString};
        -            };
        -
        -
        -        if (defined $file)
        -            {
        -            # Remove it from the file index.
        -
        -            $files{$file}->DeleteReference($referenceString);
        -
        -            if (!$files{$file}->HasAnything())
        -                {  delete $files{$file};  };
        -
        -            # We don't need to worry about the watched file, since this function will only be called by AnalyzeChanges() and
        -            # LoadAndPurge().
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: RebuildAllIndexes
        -#
        -#   When called, it makes sure all indexes are listed as changed by <IndexChanged()>, regardless of whether they actually did
        -#   or not.
        -#
        -#   This can be called at any time.
        -#
        -sub RebuildAllIndexes
        -    {
        -    my $self = shift;
        -    $rebuildIndexes = 1;
        -    };
        -
        -
        -#
        -#   Function: PurgeResolvingInfo
        -#
        -#   Purges unnecessary information from the symbol table after it is fully resolved.  This will reduce the memory footprint for the
        -#   build stage.  After calling this function, you can only call the <Information Functions> and <Save()>.
        -#
        -sub PurgeResolvingInfo
        -    {
        -    my ($self) = @_;
        -
        -    # Go through the symbols.  We don't need to keep around potential symbols anymore, nor do we need what references can
        -    # be interpreted as the defined ones.
        -
        -    while (my ($symbol, $symbolObject) = each %symbols)
        -        {
        -        if ($symbolObject->IsDefined())
        -            {  $symbolObject->DeleteAllReferences();  }
        -        else
        -            {  delete $symbols{$symbol};  };
        -        };
        -
        -
        -    # Go through the references.  We don't need any of the interpretations except for the current.
        -
        -    foreach my $referenceObject (values %references)
        -        {  $referenceObject->DeleteAllInterpretationsButCurrent();  };
        -
        -
        -    # We don't need the information by file at all.
        -
        -    %files = ( );
        -    };
        -
        -
        -#
        -#   Function: PurgeIndexes
        -#
        -#   Clears all generated indexes.
        -#
        -sub PurgeIndexes
        -    {
        -    my ($self) = @_;
        -    %indexes = ( );
        -    };
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -# These functions should not be called until the symbol table is fully resolved.
        -
        -
        -#
        -#   Function: References
        -#
        -#   Returns what the passed reference information resolve to, if anything.  Note that this only works if the reference had
        -#   been previously added to the table via <AddReference()> with the exact same parameters.
        -#
        -#   Parameters:
        -#
        -#       type     - The <ReferenceType>.
        -#       symbol - The reference <SymbolString>.
        -#       scope   - The scope <SymbolString> the reference appears in, or undef if none.
        -#       using    - An arrayref of scope <SymbolStrings> available to the reference via using statements.
        -#       file       - The source <FileName> the reference appears in, or undef if none.
        -#       resolvingFlags - The <Resolving Flags> of the reference.  Ignored if the type is <REFERENCE_TEXT>.
        -#
        -#   Alternate Parameters:
        -#
        -#       referenceString - The <ReferenceString> to resolve.
        -#       file - The source <FileName> the reference appears in, or undef if none.
        -#
        -#   Returns:
        -#
        -#       A <NaturalDocs::SymbolTable::ReferenceTarget> object, or undef if the reference doesn't resolve to anything.
        -#
        -sub References #(type, symbol, scope, using, file, resolvingFlags) or (referenceString, file)
        -    {
        -    my ($self, $referenceString, $file);
        -
        -    if (scalar @_ <= 3)
        -        {  ($self, $referenceString, $file) = @_;  }
        -    else
        -        {
        -        my ($type, $symbol, $scope, $using, $resolvingFlags);
        -        ($self, $type, $symbol, $scope, $using, $file, $resolvingFlags) = @_;
        -
        -        $referenceString = NaturalDocs::ReferenceString->MakeFrom($type, $symbol,
        -                                                                                                  NaturalDocs::Languages->LanguageOf($file)->Name(),
        -                                                                                                  $scope, $using, $resolvingFlags);
        -        };
        -
        -    if (exists $references{$referenceString} && $references{$referenceString}->HasCurrentInterpretation())
        -        {
        -        my $targetSymbol = $references{$referenceString}->CurrentInterpretation();
        -        my $targetObject = $symbols{$targetSymbol};
        -
        -        my $targetFile;
        -        my $targetType;
        -        my $targetPrototype;
        -        my $targetSummary;
        -
        -        if (defined $file && $targetObject->IsDefinedIn($file))
        -            {
        -            $targetFile = $file;
        -            $targetType = $targetObject->TypeDefinedIn($file);
        -            $targetPrototype = $targetObject->PrototypeDefinedIn($file);
        -            $targetSummary = $targetObject->SummaryDefinedIn($file);
        -            }
        -        else
        -            {
        -            $targetFile = $targetObject->GlobalDefinition();
        -            $targetType = $targetObject->GlobalType();
        -            $targetPrototype = $targetObject->GlobalPrototype();
        -            $targetSummary = $targetObject->GlobalSummary();
        -            };
        -
        -        return NaturalDocs::SymbolTable::ReferenceTarget->New($targetSymbol, $targetFile, $targetType, $targetPrototype,
        -                                                                                             $targetSummary);
        -        }
        -
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: Lookup
        -#
        -#   Returns information on the passed <SymbolString>, if it exists.  Note that the symbol must be fully resolved.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString>.
        -#       file - The source <FileName> the reference appears in, or undef if none.
        -#
        -#   Returns:
        -#
        -#       A <NaturalDocs::SymbolTable::ReferenceTarget> object, or undef if the symbol isn't defined.
        -#
        -sub Lookup #(symbol, file)
        -    {
        -    my ($self, $symbol, $file) = @_;
        -
        -    my $symbolObject = $symbols{$symbol};
        -
        -    if (defined $symbolObject)
        -        {
        -        my $targetFile;
        -        my $targetType;
        -        my $targetPrototype;
        -        my $targetSummary;
        -
        -        if (defined $file && $symbolObject->IsDefinedIn($file))
        -            {
        -            $targetFile = $file;
        -            $targetType = $symbolObject->TypeDefinedIn($file);
        -            $targetPrototype = $symbolObject->PrototypeDefinedIn($file);
        -            $targetSummary = $symbolObject->SummaryDefinedIn($file);
        -            }
        -        else
        -            {
        -            $targetFile = $symbolObject->GlobalDefinition();
        -            $targetType = $symbolObject->GlobalType();
        -            $targetPrototype = $symbolObject->GlobalPrototype();
        -            $targetSummary = $symbolObject->GlobalSummary();
        -            };
        -
        -        return NaturalDocs::SymbolTable::ReferenceTarget->New($symbol, $targetFile, $targetType, $targetPrototype,
        -                                                                                             $targetSummary);
        -        }
        -
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: Index
        -#
        -#   Returns a symbol index.
        -#
        -#   Indexes are generated on demand, but they are stored so subsequent calls for the same index will be fast.  Call
        -#   <PurgeIndexes()> to clear the generated indexes.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> of symbol to limit the index to, or undef for none.
        -#
        -#   Returns:
        -#
        -#       An arrayref of sections.  The first represents all the symbols, the second the numbers, and the rest A through Z.
        -#       Each section is a sorted arrayref of <NaturalDocs::SymbolTable::IndexElement> objects.  If a section has no content,
        -#       it will be undef.
        -#
        -sub Index #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    if (!exists $indexes{$type})
        -        {  $indexes{$type} = $self->MakeIndex($type);  };
        -
        -    return $indexes{$type};
        -    };
        -
        -
        -#
        -#   Function: HasIndexes
        -#
        -#   Determines which indexes out of a list actually have content.
        -#
        -#   Parameters:
        -#
        -#       types  - An existence hashref of the <TopicTypes> to check for indexes.
        -#
        -#   Returns:
        -#
        -#       An existence hashref of all the specified indexes that have content.  Will return an empty hashref if none.
        -#
        -sub HasIndexes #(types)
        -    {
        -    my ($self, $types) = @_;
        -
        -    # EliminationHash is a copy of all the types, and the types will be deleted as they are found.  This allows us to quit early if
        -    # we've found all the types because the hash will be empty.  We'll later return the original hash minus what was left over
        -    # in here, which are the ones that weren't found.
        -    my %eliminationHash = %$types;
        -
        -    finddefs:
        -    foreach my $symbolObject (values %symbols)
        -        {
        -        foreach my $definition ($symbolObject->Definitions())
        -            {
        -            delete $eliminationHash{ $symbolObject->TypeDefinedIn($definition) };
        -            delete $eliminationHash{ ::TOPIC_GENERAL() };
        -
        -            if (!scalar keys %eliminationHash)
        -                {  last finddefs;  };
        -            };
        -        };
        -
        -    my $result = { %$types };
        -
        -    foreach my $type (keys %eliminationHash)
        -        {  delete $result->{$type};  };
        -
        -    return $result;
        -    };
        -
        -
        -#
        -#   Function: IndexChanged
        -#
        -#   Returns whether the specified index has changed.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> to limit the index to.
        -#
        -sub IndexChanged #(TopicType type)
        -    {
        -    my ($self, $type) = @_;
        -    return ($rebuildIndexes || defined $indexChanges{$type});
        -    };
        -
        -
        -#
        -#   Function: IndexSectionsWithContent
        -#
        -#   Returns an arrayref of whether each section of the specified index has content.  The first entry will be for symbols, the second
        -#   for numbers, and the rest A-Z.  Do not change the arrayref.
        -#
        -sub IndexSectionsWithContent #(TopicType type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    if (!exists $indexSectionsWithContent{$type})
        -        {
        -        # This is okay because Index() stores generated indexes.  It's not an expensive operation unless the index was never asked
        -        # for before or it will never be asked for otherwise, and this shouldn't be the case.
        -
        -        my $index = $self->Index($type);
        -        my $content = [ ];
        -
        -        for (my $i = 0; $i < 28; $i++)
        -            {
        -            push @$content, (defined $index->[$i] ? 1 : 0);
        -            };
        -
        -        $indexSectionsWithContent{$type} = $content;
        -        };
        -
        -    return $indexSectionsWithContent{$type};
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Event Handlers
        -
        -
        -#
        -#   Function: OnIndexChange
        -#
        -#   Called whenever a change happens to a symbol that would cause an index to be regenerated.
        -#
        -#   Parameters:
        -#
        -#       type - The <TopicType> of the symbol that caused the change.
        -#
        -sub OnIndexChange #(TopicType type)
        -    {
        -    my ($self, $type) = @_;
        -
        -    $indexChanges{$type} = 1;
        -    $indexChanges{::TOPIC_GENERAL()} = 1;
        -    delete $indexSectionsWithContent{$type};
        -    };
        -
        -
        -#
        -#   Function: OnInterpretationChange
        -#
        -#   Called whenever the current interpretation of a reference changes, meaning it switched from one symbol to another.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> whose current interpretation changed.
        -#
        -sub OnInterpretationChange #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -    my $referenceType = NaturalDocs::ReferenceString->TypeOf($referenceString);
        -
        -    if ($referenceType == ::REFERENCE_TEXT())
        -        {
        -        my @referenceDefinitions = $references{$referenceString}->Definitions();
        -
        -        foreach my $referenceDefinition (@referenceDefinitions)
        -            {
        -            NaturalDocs::Project->RebuildFile($referenceDefinition);
        -            };
        -        }
        -
        -    elsif (NaturalDocs::Constants->IsClassHierarchyReference($referenceType))
        -        {
        -        NaturalDocs::ClassHierarchy->OnInterpretationChange($referenceString);
        -        };
        -    };
        -
        -
        -#
        -#   Function: OnTargetSymbolChange
        -#
        -#   Called whenever the symbol that serves as the interpretation of a reference changes, but the reference still resolves to
        -#   the same symbol.  This would happen if the type, prototype, summary, or which file serves as global definition of the symbol
        -#   changes.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> whose interpretation's symbol changed.
        -#
        -sub OnTargetSymbolChange #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -    my $referenceType = NaturalDocs::ReferenceString->TypeOf($referenceString);
        -
        -    if ($referenceType == ::REFERENCE_TEXT())
        -        {
        -        my @referenceDefinitions = $references{$referenceString}->Definitions();
        -
        -        foreach my $referenceDefinition (@referenceDefinitions)
        -            {
        -            NaturalDocs::Project->RebuildFile($referenceDefinition);
        -            };
        -        }
        -
        -    elsif (NaturalDocs::Constants->IsClassHierarchyReference($referenceType))
        -        {
        -        NaturalDocs::ClassHierarchy->OnTargetSymbolChange($referenceString);
        -        };
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: DeleteSymbol
        -#
        -#   Removes a symbol definition from the table.  It will call <OnInterpretationChange()> for all references that have it as their
        -#   current interpretation.
        -#
        -#   External code should not attempt to delete symbols using this function.  Instead it should call <WatchFileFoChanges()>,
        -#   reparse the file, and call <AnalyzeChanges()>.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString>.
        -#       file       - The <FileName> where the definition is.
        -#
        -sub DeleteSymbol #(symbol, file)
        -    {
        -    my ($self, $symbol, $file) = @_;
        -
        -
        -    # If the symbol and definition exist...
        -    if (exists $symbols{$symbol} && $symbols{$symbol}->IsDefinedIn($file))
        -        {
        -        my $symbolObject = $symbols{$symbol};
        -        my $wasGlobal = ($symbolObject->GlobalDefinition() eq $file);
        -
        -        $self->OnIndexChange($symbolObject->TypeDefinedIn($file));
        -
        -        $symbolObject->DeleteDefinition($file);
        -
        -        # If this was one definition of many...
        -        if ($symbolObject->IsDefined())
        -            {
        -
        -            # If this was the global definition...
        -            if ($wasGlobal)
        -                {
        -                # Update every file that referenced the global symbol; i.e. every file that doesn't have its own definition.
        -
        -                my @references = $symbolObject->References();
        -
        -                foreach my $reference (@references)
        -                    {
        -                    if ($references{$reference}->CurrentInterpretation() eq $symbol)
        -                        {
        -                        $self->OnTargetSymbolChange($reference);
        -                        };
        -                    };
        -                }
        -
        -            # If this wasn't the global definition...
        -            else
        -                {
        -                # It's a safe bet that we don't need to do anything here.  The only thing that we even need to look for here is if the
        -                # file referenced its own symbol and thus should be rebuilt.  However, if the file is having a symbol deleted, it either
        -                # changed or was itself deleted.  If it changed and still has other Natural Docs content, it should already be on the
        -                # rebuild list.  If it was deleted or no longer has Natural Docs content, we certainly don't want to add it to the rebuild
        -                # list.
        -                };
        -            }
        -
        -        # If this is the only definition...
        -        else
        -            {
        -            # If this symbol is the interpretation of any references...
        -            if ($symbolObject->HasReferences())
        -                {
        -                # If this was the current interpretation of any references, reinterpret them and rebuild their files.
        -
        -                my @references = $symbolObject->References();
        -
        -                foreach my $reference (@references)
        -                    {
        -                    if ($references{$reference}->CurrentInterpretation() eq $symbol)
        -                        {
        -                        $self->InterpretReference($reference);
        -                        $self->OnInterpretationChange($reference);
        -                        };
        -                    };
        -                }
        -
        -            # If there are no interpretations of the symbol...
        -            else
        -                {
        -                # Delete the symbol entirely.
        -                delete $symbols{$symbol};
        -                };
        -            };
        -
        -        # Remove it from the file index.
        -
        -        $files{$file}->DeleteSymbol($symbol);
        -
        -        if (!$files{$file}->HasAnything())
        -            {  delete $files{$file};  };
        -
        -
        -        # We don't need to worry about the watched file, since this function will only be called by AnalyzeChanges() and
        -        # LoadAndPurge().
        -        };
        -    };
        -
        -
        -#
        -#   Function: GenerateInterpretations
        -#
        -#   Generates the list of interpretations for the passed reference.  Also creates potential symbols as necessary.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> to generate the interpretations of.
        -#
        -sub GenerateInterpretations #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    my ($type, $symbol, $languageName, $scope, $using, $resolvingFlags) =
        -        NaturalDocs::ReferenceString->InformationOf($referenceString);
        -
        -    # RESOLVE_NOPLURAL is handled by having @singulars be empty.
        -    my @singulars;
        -    if (!($resolvingFlags & ::RESOLVE_NOPLURAL()))
        -        {  @singulars = $self->SingularInterpretationsOf($symbol);  };
        -
        -    # Since higher scores are better, we'll start at a high number and decrement.
        -    my $score = 50000;
        -
        -
        -    # If RESOLVE_RELATIVE is set, we do all the scope relatives before the global.
        -    if ($resolvingFlags & ::RESOLVE_RELATIVE())
        -        {
        -        $score = $self->GenerateRelativeInterpretations($referenceString, $symbol, \@singulars, $scope, $score);
        -        }
        -
        -    # If neither RESOLVE_RELATIVE nor RESOLVE_ABSOLUTE is set, we only do the local before the global.
        -    elsif (!($resolvingFlags & ::RESOLVE_ABSOLUTE()))
        -        {
        -        $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($scope, $symbol), $score);
        -        $score--;
        -
        -        foreach my $singular (@singulars)
        -            {
        -            $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($scope, $singular), $score);
        -            $score--;
        -            };
        -        };
        -
        -
        -    # Do the global.
        -
        -    $self->AddInterpretation($referenceString, $symbol, $score);
        -    $score--;
        -
        -    foreach my $singular (@singulars)
        -        {
        -        $self->AddInterpretation($referenceString, $singular, $score);
        -        $score--;
        -        };
        -
        -
        -    # If neither RESOLVE_RELATIVE nor RESOLVE_ABSOLUTE is set, we need to do the rest of the scope relatives after the global.
        -    if (!($resolvingFlags & ::RESOLVE_RELATIVE()) && !($resolvingFlags & ::RESOLVE_ABSOLUTE()))
        -        {
        -        $score = $self->GenerateRelativeInterpretations($referenceString, $symbol, \@singulars, $scope, $score, 1);
        -        };
        -
        -
        -    # Finally, if RESOLVE_NOUSING isn't set, go through the using scopes.
        -    if (!($resolvingFlags & ::RESOLVE_NOUSING()) && defined $using)
        -        {
        -        foreach my $usingScope (@$using)
        -            {
        -            if ($resolvingFlags & ::RESOLVE_ABSOLUTE())
        -                {
        -                $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($usingScope, $symbol), $score);
        -                $score--;
        -
        -                foreach my $singular (@singulars)
        -                    {
        -                    $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($usingScope, $singular), $score);
        -                    $score--;
        -                    };
        -                }
        -            else
        -                {
        -                $score = $self->GenerateRelativeInterpretations($referenceString, $symbol, \@singulars, $usingScope, $score);
        -                };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: GenerateRelativeInterpretations
        -#
        -#   Generates the list of relative interpretations for the passed reference and packages.  Also creates potential symbols as
        -#   necessary.
        -#
        -#   This function will _not_ create global interpretations.  It _will_ create a local interpretations (symbol + all packages) unless
        -#   you set dontUseFull.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> to generate interpretations for.
        -#       symbol - The <SymbolString> to generate interpretations of.
        -#       singulars - A reference to an array of singular <SymbolStrings> to also generate interpretations of.  Set to an empty array
        -#                       if none.
        -#       package - The package <SymbolString> to use.  May be undef.
        -#       score - The starting score to apply.
        -#       dontUseFull - Whether to not generate an interpretation including the full package identifier.  If set, generated interpretations
        -#                           will start one level down.
        -#
        -#   Returns:
        -#
        -#       The next unused score.  This is basically the passed score minus the number of interpretations created.
        -#
        -sub GenerateRelativeInterpretations #(referenceString, symbol, singulars, package, score, dontUseFull)
        -    {
        -    my ($self, $referenceString, $symbol, $singulars, $package, $score, $dontUseFull) = @_;
        -
        -    my @packages = NaturalDocs::SymbolString->IdentifiersOf($package);
        -
        -    # The last package index to include.  This number is INCLUSIVE!
        -    my $packageLevel = scalar @packages - 1;
        -
        -    if ($dontUseFull)
        -        {  $packageLevel--;  };
        -
        -    while ($packageLevel >= 0)
        -        {
        -        $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join(@packages[0..$packageLevel], $symbol),
        -                                             $score);
        -        $score--;
        -
        -        foreach my $singular (@$singulars)
        -            {
        -            $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join(@packages[0..$packageLevel], $singular),
        -                                                 $score);
        -            $score--;
        -            };
        -
        -        $packageLevel--;
        -        };
        -
        -    return $score;
        -    };
        -
        -
        -#
        -#   Function: SingularInterpretationsOf
        -#
        -#   Generates singular interpretations of a <SymbolString> if it can be interpreted as a plural.  Not all of them will be valid singular
        -#   forms, but that doesn't matter since it's incredibly unlikely an invalid form would exist as a symbol.  What matters is that the
        -#   legimate singular is present on the list.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString>.
        -#
        -#   Returns:
        -#
        -#       An array of potential singular interpretations as <SymbolStrings>, in no particular order.  If the symbol can't be interpreted
        -#       as a plural, returns an empty array.
        -#
        -sub SingularInterpretationsOf #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -
        -    my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
        -    my $lastIdentifier = pop @identifiers;
        -    my $preIdentifiers = NaturalDocs::SymbolString->Join(@identifiers);
        -
        -    my @results;
        -
        -    # First cut off any 's or ' at the end, since they can appear after other plural forms.
        -    if ($lastIdentifier =~ s/\'s?$//i)
        -        {
        -        push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $lastIdentifier);
        -        };
        -
        -    # See http://www.gsu.edu/~wwwesl/egw/crump.htm for a good list of potential plural forms.  There are a couple more than
        -    # listed below, but they're fairly rare and this is already seriously over-engineered.  This is split by suffix length to make
        -    # comparisons more efficient.
        -
        -    # The fact that this will generate some impossible combinations (leaves => leave, leav, leaf, leafe) doesn't matter.  It's very
        -    # unlikely that more than one will manage to match a defined symbol.  Even if they do (leave, leaf), it's incredibly unlikely
        -    # that someone has defined an impossible one (leav, leafe).  So it's not so important that we remove impossible combinations,
        -    # just that we include all the possible ones.
        -
        -    my @suffixGroups = ( [ 's', undef,  # boys => boy
        -                                       'i', 'us',  # alumni => alumnus
        -                                       'a', 'um', # errata => erratum
        -                                       'a', 'on' ],  # phenomena => phenomenon
        -
        -                                    [ 'es', undef,  # foxes => fox
        -                                      'ae', 'a' ],  # amoebae => amoeba
        -
        -                                    [ 'ies', 'y',  # pennies => penny
        -                                      'ves', 'f',  # calves => calf
        -                                      'ves', 'fe',  # knives => knife
        -                                      'men', 'man',  # women => woman
        -                                      'ice', 'ouse',  # mice => mouse
        -                                      'oes', 'o',  # vetoes => veto
        -                                      'ces', 'x',  # matrices => matrix
        -                                      'xen', 'x' ],  # oxen => ox
        -
        -                                    [ 'ices', 'ex',  # indices => index
        -                                      'feet', 'foot',  # feet => foot
        -                                      'eese', 'oose',  # geese => goose
        -                                      'eeth', 'ooth',  # teeth => tooth
        -                                      'dren', 'd' ] );  # children => child
        -
        -    my $suffixLength = 1;
        -
        -    foreach my $suffixGroup (@suffixGroups)
        -        {
        -        my $identifierSuffix = lc( substr($lastIdentifier, 0 - $suffixLength) );
        -        my $cutIdentifier = substr($lastIdentifier, 0, 0 - $suffixLength);
        -
        -        for (my $i = 0; $i + 1 < scalar @$suffixGroup; $i += 2)
        -            {
        -            my $suffix = $suffixGroup->[$i];
        -            my $replacement = $suffixGroup->[$i + 1];
        -
        -            if ($identifierSuffix eq $suffix)
        -                {
        -                if (defined $replacement)
        -                    {
        -                    push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $cutIdentifier . $replacement);
        -                    push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $cutIdentifier . uc($replacement));
        -                    }
        -                else
        -                    {
        -                    push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $cutIdentifier);
        -                    };
        -                };
        -            };
        -
        -        $suffixLength++;
        -        };
        -
        -    return @results;
        -    };
        -
        -
        -#
        -#   Function: AddInterpretation
        -#
        -#   Adds an interpretation to an existing reference.  Creates potential symbols as necessary.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> to add the interpretation to.
        -#       symbol - The <SymbolString> the reference can be interpreted as.
        -#       score - The score of the interpretation.
        -#
        -sub AddInterpretation #(referenceString, symbol, score)
        -    {
        -    my ($self, $referenceString, $symbol, $score) = @_;
        -
        -    $references{$referenceString}->AddInterpretation($symbol, $score);
        -
        -    # Create a potential symbol if it doesn't exist.
        -
        -    if (!exists $symbols{$symbol})
        -        {  $symbols{$symbol} = NaturalDocs::SymbolTable::Symbol->New();  };
        -
        -    $symbols{$symbol}->AddReference($referenceString, $score);
        -    };
        -
        -
        -#
        -#   Function: InterpretReference
        -#
        -#   Interprets the passed reference, matching it to the defined symbol with the highest score.  If the symbol is already
        -#   interpreted, it will reinterpret it.  If there are no matches, it will make it an undefined reference.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> to interpret.
        -#
        -sub InterpretReference #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    my $interpretation;
        -    my $currentInterpretation;
        -    my $score;
        -    my $currentScore = -1;
        -
        -    my $referenceObject = $references{$referenceString};
        -
        -    my %interpretationsAndScores = $referenceObject->InterpretationsAndScores();
        -    while ( ($interpretation, $score) = each %interpretationsAndScores )
        -        {
        -        if ($score > $currentScore && $symbols{$interpretation}->IsDefined())
        -            {
        -            $currentScore = $score;
        -            $currentInterpretation = $interpretation;
        -            };
        -        };
        -
        -    if ($currentScore > -1)
        -        {  $referenceObject->SetCurrentInterpretation($currentInterpretation);  }
        -    else
        -        {  $referenceObject->SetCurrentInterpretation(undef);  };
        -    };
        -
        -
        -#
        -#   Function: MakeIndex
        -#
        -#   Generates a symbol index.
        -#
        -#   Parameters:
        -#
        -#       type  - The <TopicType> to limit the index to.
        -#
        -#   Returns:
        -#
        -#       An arrayref of sections.  The first represents all the symbols, the second the numbers, and the rest A through Z.
        -#       Each section is a sorted arrayref of <NaturalDocs::SymbolTable::IndexElement> objects.  If a section has no content,
        -#       it will be undef.
        -#
        -sub MakeIndex #(type)
        -    {
        -    my ($self, $type) = @_;
        -
        -
        -    # Go through the symbols and generate IndexElements for any that belong in the index.
        -
        -    # Keys are the symbol strings, values are IndexElements.
        -    my %indexSymbols;
        -
        -    while (my ($symbolString, $object) = each %symbols)
        -        {
        -        my ($symbol, $package) = $self->SplitSymbolForIndex($symbolString, $object->GlobalType());
        -        my @definitions = $object->Definitions();
        -
        -        foreach my $definition (@definitions)
        -            {
        -            my $definitionType = $object->TypeDefinedIn($definition);
        -
        -            if ($type eq ::TOPIC_GENERAL() || $type eq $definitionType)
        -                {
        -                if (!exists $indexSymbols{$symbol})
        -                    {
        -                    $indexSymbols{$symbol} =
        -                        NaturalDocs::SymbolTable::IndexElement->New($symbol, $package, $definition, $definitionType,
        -                                                                                               $object->PrototypeDefinedIn($definition),
        -                                                                                               $object->SummaryDefinedIn($definition) );
        -                    }
        -                else
        -                    {
        -                    $indexSymbols{$symbol}->Merge($package, $definition, $definitionType,
        -                                                                       $object->PrototypeDefinedIn($definition),
        -                                                                       $object->SummaryDefinedIn($definition) );
        -                    };
        -                }; # If type matches
        -            }; # Each definition
        -        }; # Each symbol
        -
        -
        -    # Generate sortable symbols for each IndexElement, sort them internally, and divide them into sections.
        -
        -    my $sections = [ ];
        -
        -    foreach my $indexElement (values %indexSymbols)
        -        {
        -        $indexElement->Sort();
        -        $indexElement->MakeSortableSymbol();
        -
        -        my $sectionNumber;
        -
        -        if ($indexElement->SortableSymbol() =~ /^([a-z])/i)
        -            {  $sectionNumber = ord(lc($1)) - ord('a') + 2;  }
        -        elsif ($indexElement->SortableSymbol() =~ /^[0-9]/)
        -            {  $sectionNumber = 1;  }
        -        else
        -            {  $sectionNumber = 0;  };
        -
        -        if (!defined $sections->[$sectionNumber])
        -            {  $sections->[$sectionNumber] = [ ];  };
        -
        -        push @{$sections->[$sectionNumber]}, $indexElement;
        -        };
        -
        -
        -    # Sort each section.
        -
        -    for (my $i = 0; $i < scalar @$sections; $i++)
        -        {
        -        if (defined $sections->[$i])
        -            {
        -            @{$sections->[$i]} = sort
        -                {
        -                my $result = ::StringCompare($a->SortableSymbol(), $b->SortableSymbol());
        -
        -                if ($result == 0)
        -                    {  $result = ::StringCompare($a->IgnoredPrefix(), $b->IgnoredPrefix());  };
        -
        -                return $result;
        -                }
        -            @{$sections->[$i]};
        -            };
        -        };
        -
        -    return $sections;
        -    };
        -
        -
        -#
        -#   Function: SplitSymbolForIndex
        -#
        -#   Splits a <SymbolString> into its symbol and package portions for indexing.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString>.
        -#       type - Its <TopicType>.
        -#
        -#   Returns:
        -#
        -#       The array ( symbol, package ), which are both <SymbolStrings>.  If the symbol is global, package will be undef.
        -#
        -sub SplitSymbolForIndex #(symbol, type)
        -    {
        -    my ($self, $symbol, $type) = @_;
        -
        -    my $scope = NaturalDocs::Topics->TypeInfo($type)->Scope();
        -
        -    if ($scope == ::SCOPE_START() || $scope == ::SCOPE_ALWAYS_GLOBAL())
        -        {  return ( $symbol, undef );  }
        -    else
        -        {
        -        my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
        -
        -        $symbol = pop @identifiers;
        -        my $package = NaturalDocs::SymbolString->Join(@identifiers);
        -
        -        return ( $symbol, $package );
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/File.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/File.pm
        deleted file mode 100644
        index f07c8c939..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/File.pm
        +++ /dev/null
        @@ -1,187 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SymbolTable::File
        -#
        -###############################################################################
        -#
        -#   A class representing a file, keeping track of what symbols and references are defined in it.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolTable::File;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are its members.
        -#
        -#       SYMBOLS       - An existence hashref of the <SymbolStrings> it defines.
        -#       REFERENCES  - An existence hashref of the <ReferenceStrings> in the file.
        -#
        -
        -# DEPENDENCY: New() depends on the order of these constants.  If they change, New() has to be updated.
        -use constant SYMBOLS => 0;
        -use constant REFERENCES => 1;
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -sub New
        -    {
        -    my $package = shift;
        -
        -    # Let's make it safe, since normally you can pass values to New.  Having them just be ignored would be an obscure error.
        -    if (scalar @_)
        -        {  die "You can't pass values to NaturalDocs::SymbolTable::File->New()\n";  };
        -
        -    # DEPENDENCY: This code depends on the order of the member constants.
        -    my $object = [ { }, { } ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: AddSymbol
        -#
        -#   Adds a <SymbolString> definition.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString> being added.
        -#
        -sub AddSymbol #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -    $self->[SYMBOLS]{$symbol} = 1;
        -    };
        -
        -
        -#
        -#   Function: DeleteSymbol
        -#
        -#   Removes a <SymbolString> definition.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString> to delete.
        -#
        -sub DeleteSymbol #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -    delete $self->[SYMBOLS]{$symbol};
        -    };
        -
        -
        -#
        -#   Function: AddReference
        -#
        -#   Adds a reference definition.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> being added.
        -#
        -sub AddReference #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -    $self->[REFERENCES]{$referenceString} = 1;
        -    };
        -
        -
        -#
        -#   Function: DeleteReference
        -#
        -#   Removes a reference definition.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The <ReferenceString> to delete.
        -#
        -sub DeleteReference #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -    delete $self->[REFERENCES]{$referenceString};
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -
        -#
        -#   Function: HasAnything
        -#
        -#   Returns whether the file has any symbol or reference definitions at all.
        -#
        -sub HasAnything
        -    {
        -    return (scalar keys %{$_[0]->[SYMBOLS]} || scalar keys %{$_[0]->[REFERENCES]});
        -    };
        -
        -#
        -#   Function: Symbols
        -#
        -#   Returns an array of all the <SymbolStrings> defined in this file.  If none, returns an empty array.
        -#
        -sub Symbols
        -    {
        -    return keys %{$_[0]->[SYMBOLS]};
        -    };
        -
        -
        -#
        -#   Function: References
        -#
        -#   Returns an array of all the <ReferenceStrings> defined in this file.  If none, returns an empty array.
        -#
        -sub References
        -    {
        -    return keys %{$_[0]->[REFERENCES]};
        -    };
        -
        -
        -#
        -#   Function: DefinesSymbol
        -#
        -#   Returns whether the file defines the passed <SymbolString> or not.
        -#
        -sub DefinesSymbol #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -    return exists $self->[SYMBOLS]{$symbol};
        -    };
        -
        -
        -#
        -#   Function: DefinesReference
        -#
        -#   Returns whether the file defines the passed <ReferenceString> or not.
        -#
        -sub DefinesReference #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -    return exists $self->[REFERENCES]{$referenceString};
        -    };
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm
        deleted file mode 100644
        index ee6a9e8cc..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm
        +++ /dev/null
        @@ -1,523 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::SymbolTable::IndexElement
        -#
        -###############################################################################
        -#
        -#   A class representing part of an indexed symbol.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use Tie::RefHash;
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::SymbolTable::IndexElement;
        -
        -
        -#
        -#   Topic: How IndexElements Work
        -#
        -#   This is a little tricky, so make sure you understand this.  Indexes are sorted by symbol, then packages, then file.  If there is only
        -#   one package for a symbol, or one file definition for a package/symbol, they are added inline to the entry.  However, if there are
        -#   multiple packages or files, the function for it returns an arrayref of IndexElements instead.  Which members are defined and
        -#   undefined should follow common sense.  For example, if a symbol is defined in multiple packages, the symbol's IndexElement
        -#   will not define <File()>, <Type()>, or <Prototype()>; those will be defined in child elements.  Similarly, the child elements will
        -#   not define <Symbol()> since it's redundant.
        -#
        -#   Diagrams may be clearer.  If a member isn't listed for an element, it isn't defined.
        -#
        -#   A symbol that only has one package and file:
        -#   > [Element]
        -#   > - Symbol
        -#   > - Package
        -#   > - File
        -#   > - Type
        -#   > - Prototype
        -#   > - Summary
        -#
        -#   A symbol that is defined by multiple packages, each with only one file:
        -#   > [Element]
        -#   > - Symbol
        -#   > - Package
        -#   >     [Element]
        -#   >     - Package
        -#   >     - File
        -#   >     - Type
        -#   >     - Prototype
        -#   >     - Summary
        -#   >     [Element]
        -#   >     - ...
        -#
        -#   A symbol that is defined by one package, but has multiple files
        -#   > [Element]
        -#   > - Symbol
        -#   > - Package
        -#   > - File
        -#   >    [Element]
        -#   >    - File
        -#   >    - Type
        -#   >    - Protype
        -#   >    - Summary
        -#   >    [Element]
        -#   >    - ...
        -#
        -#   A symbol that is defined by multiple packages which have multiple files:
        -#   > [Element]
        -#   > - Symbol
        -#   > - Package
        -#   >    [Element]
        -#   >    - Package
        -#   >    - File
        -#   >      [Element]
        -#   >      - File
        -#   >      - Type
        -#   >      - Prototype
        -#   >      - Summary
        -#   >      [Element]
        -#   >      - ...
        -#   >    [Element]
        -#   >    - ...
        -#
        -#   Why is it done this way?:
        -#
        -#   Because it makes it easier to generate nice indexes since all the splitting and combining is done for you.  If a symbol
        -#   has only one package, you just want to link to it, you don't want to break out a subindex for just one package.  However, if
        -#   it has multiple package, you do want the subindex and to link to each one individually.  Use <HasMultiplePackages()> and
        -#   <HasMultipleFiles()> to determine whether you need to add a subindex for it.
        -#
        -#
        -#   Combining Properties:
        -#
        -#   All IndexElements also have combining properties set.
        -#
        -#   CombinedType - The general <TopicType> of the entry.  Conflicts combine into <TOPIC_GENERAL>.
        -#   PackageSeparator - The package separator symbol of the entry.  Conflicts combine into a dot.
        -#
        -#   So if an IndexElement only has one definition, <CombinedType()> is the same as the <TopicType> and <PackageSeparator()>
        -#   is that of the definition's language.  If other definitions are added and they have the same properties, the combined properties
        -#   will remain the same.  However, if they're different, they switch values as noted above.
        -#
        -#
        -#   Sortable Symbol:
        -#
        -#   <SortableSymbol()> is a pseudo-combining property.  There were a few options for dealing with multiple languages defining
        -#   the same symbol but stripping different prefixes off it, but ultimately I decided to go with whatever the language does that
        -#   has the most definitions.  There's not likely to be many conflicts here in the real world; probably the only thing would be
        -#   defining it in a text file and forgetting to specify the prefixes to strip there too.  So this works.
        -#
        -#   Ties are broken pretty much randomly, except that text files always lose if its one of the options.
        -#
        -#   It's a pseudo-combining property because it's done after the IndexElements are all filled in and only stored in the top-level
        -#   ones.
        -#
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are its members.
        -#
        -#   SYMBOL - The <SymbolString> without the package portion.
        -#   PACKAGE - The package <SymbolString>.  Will be a package <SymbolString>, undef for global, or an arrayref of
        -#                    <NaturalDocs::SymbolTable::IndexElement> objects if multiple packages define the symbol.
        -#   FILE - The <FileName> the package/symbol is defined in.  Will be the file name or an arrayref of
        -#            <NaturalDocs::SymbolTable::IndexElements> if multiple files define the package/symbol.
        -#   TYPE - The package/symbol/file <TopicType>.
        -#   PROTOTYPE - The package/symbol/file prototype, or undef if not applicable.
        -#   SUMMARY - The package/symbol/file summary, or undef if not applicable.
        -#   COMBINED_TYPE - The combined <TopicType> of the element.
        -#   PACKAGE_SEPARATOR - The combined package separator symbol of the element.
        -#   SORTABLE_SYMBOL - The sortable symbol as a text string.
        -#   IGNORED_PREFIX - The part of the symbol that was stripped off to make the sortable symbol.
        -#
        -use NaturalDocs::DefineMembers 'SYMBOL', 'Symbol()',
        -                                                 'PACKAGE', 'Package()',
        -                                                 'FILE', 'File()',
        -                                                 'TYPE', 'Type()',
        -                                                 'PROTOTYPE', 'Prototype()',
        -                                                 'SUMMARY', 'Summary()',
        -                                                 'COMBINED_TYPE', 'CombinedType()',
        -                                                 'PACKAGE_SEPARATOR', 'PackageSeparator()',
        -                                                 'SORTABLE_SYMBOL', 'SortableSymbol()',
        -                                                 'IGNORED_PREFIX', 'IgnoredPrefix()';
        -# DEPENDENCY: New() depends on the order of these constants and that there is no inheritance..
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -#
        -#   Function: New
        -#
        -#   Returns a new object.
        -#
        -#   This should only be used for creating an entirely new symbol.  You should *not* pass arrayrefs as package or file parameters
        -#   if you are calling this externally.  Use <Merge()> instead.
        -#
        -#   Parameters:
        -#
        -#       symbol  - The <SymbolString> without the package portion.
        -#       package - The package <SymbolString>, or undef for global.
        -#       file  - The symbol's definition file.
        -#       type  - The symbol's <TopicType>.
        -#       prototype  - The symbol's prototype, if applicable.
        -#       summary  - The symbol's summary, if applicable.
        -#
        -#   Optional Parameters:
        -#
        -#       These parameters don't need to be specified.  You should ignore them when calling this externally.
        -#
        -#       combinedType - The symbol's combined <TopicType>.
        -#       packageSeparator - The symbol's combined package separator symbol.
        -#
        -sub New #(symbol, package, file, type, prototype, summary, combinedType, packageSeparator)
        -    {
        -    # DEPENDENCY: This depends on the parameter list being in the same order as the constants.
        -
        -    my $self = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $self;
        -
        -    if (!defined $object->[COMBINED_TYPE])
        -        {  $object->[COMBINED_TYPE] = $object->[TYPE];  };
        -
        -    if (!defined $object->[PACKAGE_SEPARATOR])
        -        {
        -        if ($object->[TYPE] eq ::TOPIC_FILE())
        -            {  $object->[PACKAGE_SEPARATOR] = '.';  }
        -        else
        -            {
        -            $object->[PACKAGE_SEPARATOR] = NaturalDocs::Languages->LanguageOf($object->[FILE])->PackageSeparator();
        -            };
        -        };
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: Merge
        -#
        -#   Adds another definition of the same symbol.  Perhaps it has a different package or defining file.
        -#
        -#   Parameters:
        -#
        -#       package - The package <SymbolString>, or undef for global.
        -#       file  - The symbol's definition file.
        -#       type  - The symbol's <TopicType>.
        -#       prototype  - The symbol's protoype if applicable.
        -#       summary  - The symbol's summary if applicable.
        -#
        -sub Merge #(package, file, type, prototype, summary)
        -    {
        -    my ($self, $package, $file, $type, $prototype, $summary) = @_;
        -
        -    # If there's only one package...
        -    if (!$self->HasMultiplePackages())
        -        {
        -        # If there's one package and it's the same as the new one...
        -        if ($package eq $self->Package())
        -            {
        -            $self->MergeFile($file, $type, $prototype, $summary);
        -            }
        -
        -        # If there's one package and the new one is different...
        -        else
        -            {
        -            my $selfDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, $self->Package(), $self->File(),
        -                                                                                                                 $self->Type(), $self->Prototype(),
        -                                                                                                                 $self->Summary(), $self->CombinedType(),
        -                                                                                                                 $self->PackageSeparator());
        -            my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, $package, $file, $type, $prototype,
        -                                                                                                                  $summary);
        -
        -            $self->[PACKAGE] = [ $selfDefinition, $newDefinition ];
        -            $self->[FILE] = undef;
        -            $self->[TYPE] = undef;
        -            $self->[PROTOTYPE] = undef;
        -            $self->[SUMMARY] = undef;
        -
        -            if ($newDefinition->Type() ne $self->CombinedType())
        -                {  $self->[COMBINED_TYPE] = ::TOPIC_GENERAL();  };
        -            if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
        -                {  $self->[PACKAGE_SEPARATOR] = '.';  };
        -            };
        -        }
        -
        -    # If there's more than one package...
        -    else
        -        {
        -        # See if the new package is one of them.
        -        my $selfPackages = $self->Package();
        -        my $matchingPackage;
        -
        -        foreach my $testPackage (@$selfPackages)
        -            {
        -            if ($package eq $testPackage->Package())
        -                {
        -                $testPackage->MergeFile($file, $type, $prototype, $summary);;
        -                return;
        -                };
        -            };
        -
        -        my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, $package, $file, $type, $prototype,
        -                                                                                                              $summary);
        -        push @{$self->[PACKAGE]}, $newDefinition;
        -
        -        if ($newDefinition->Type() ne $self->CombinedType())
        -            {  $self->[COMBINED_TYPE] = ::TOPIC_GENERAL();  };
        -        if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
        -            {  $self->[PACKAGE_SEPARATOR] = '.';  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: Sort
        -#
        -#   Sorts the package and file lists of the symbol.
        -#
        -sub Sort
        -    {
        -    my $self = shift;
        -
        -    if ($self->HasMultipleFiles())
        -        {
        -        @{$self->[FILE]} = sort { ::StringCompare($a->File(), $b->File()) } @{$self->File()};
        -        }
        -
        -    elsif ($self->HasMultiplePackages())
        -        {
        -        @{$self->[PACKAGE]} = sort { ::StringCompare( $a->Package(), $b->Package()) } @{$self->[PACKAGE]};
        -
        -        foreach my $packageElement ( @{$self->[PACKAGE]} )
        -            {
        -            if ($packageElement->HasMultipleFiles())
        -                {  $packageElement->Sort();  };
        -            };
        -        };
        -    };
        -
        -
        -#
        -#   Function: MakeSortableSymbol
        -#
        -#   Generates <SortableSymbol()> and <IgnoredPrefix()>.  Should only be called after everything is merged.
        -#
        -sub MakeSortableSymbol
        -    {
        -    my $self = shift;
        -
        -    my $finalLanguage;
        -
        -    if ($self->HasMultiplePackages() || $self->HasMultipleFiles())
        -        {
        -        # Collect all the files that define this symbol.
        -
        -        my @files;
        -
        -        if ($self->HasMultipleFiles())
        -            {
        -            my $fileElements = $self->File();
        -
        -            foreach my $fileElement (@$fileElements)
        -                {  push @files, $fileElement->File();  };
        -            }
        -        else # HasMultiplePackages
        -            {
        -            my $packages = $self->Package();
        -
        -            foreach my $package (@$packages)
        -                {
        -                if ($package->HasMultipleFiles())
        -                    {
        -                    my $fileElements = $package->File();
        -
        -                    foreach my $fileElement (@$fileElements)
        -                        {  push @files, $fileElement->File();  };
        -                    }
        -                else
        -                    {  push @files, $package->File();  };
        -                };
        -            };
        -
        -
        -        # Determine which language defines it the most.
        -
        -        # Keys are language objects, values are counts.
        -        my %languages;
        -        tie %languages, 'Tie::RefHash';
        -
        -        foreach my $file (@files)
        -            {
        -            my $language = NaturalDocs::Languages->LanguageOf($file);
        -
        -            if (exists $languages{$language})
        -                {  $languages{$language}++;  }
        -            else
        -                {  $languages{$language} = 1;  };
        -            };
        -
        -        my $topCount = 0;
        -        my @topLanguages;
        -
        -        while (my ($language, $count) = each %languages)
        -            {
        -            if ($count > $topCount)
        -                {
        -                $topCount = $count;
        -                @topLanguages = ( $language );
        -                }
        -            elsif ($count == $topCount)
        -                {
        -                push @topLanguages, $language;
        -                };
        -            };
        -
        -        if (scalar @topLanguages == 1)
        -            {  $finalLanguage = $topLanguages[0];  }
        -        else
        -            {
        -            if ($topLanguages[0]->Name() ne 'Text File')
        -                {  $finalLanguage = $topLanguages[0];  }
        -            else
        -                {  $finalLanguage = $topLanguages[1];  };
        -            };
        -        }
        -
        -    else # !hasMultiplePackages && !hasMultipleFiles
        -        {  $finalLanguage = NaturalDocs::Languages->LanguageOf($self->File());  };
        -
        -    my $textSymbol = NaturalDocs::SymbolString->ToText($self->Symbol(), $self->PackageSeparator());
        -    my $ignoredPrefixLength = $finalLanguage->IgnoredPrefixLength($textSymbol, $self->CombinedType());
        -
        -    if ($ignoredPrefixLength)
        -        {
        -        $self->[IGNORED_PREFIX] = substr($textSymbol, 0, $ignoredPrefixLength);
        -        $self->[SORTABLE_SYMBOL] = substr($textSymbol, $ignoredPrefixLength);
        -        }
        -    else
        -        {  $self->[SORTABLE_SYMBOL] = $textSymbol;  };
        -    };
        -
        -
        -
        -###############################################################################
        -#
        -#   Functions: Information Functions
        -#
        -#   Symbol - Returns the <SymbolString> without the package portion.
        -#   Package - If <HasMultiplePackages()> is true, returns an arrayref of <NaturalDocs::SymbolTable::IndexElement> objects.
        -#                  Otherwise returns the package <SymbolString>, or undef if global.
        -#   File - If <HasMultipleFiles()> is true, returns an arrayref of <NaturalDocs::SymbolTable::IndexElement> objects.  Otherwise
        -#           returns the name of the definition file.
        -#   Type - Returns the <TopicType> of the package/symbol/file, if applicable.
        -#   Prototype - Returns the prototype of the package/symbol/file, if applicable.
        -#   Summary - Returns the summary of the package/symbol/file, if applicable.
        -#   CombinedType - Returns the combined <TopicType> of the element.
        -#   PackageSeparator - Returns the combined package separator symbol of the element.
        -#   SortableSymbol - Returns the sortable symbol as a text string.  Only available after calling <MakeSortableSymbol()>.
        -#   IgnoredPrefix - Returns the part of the symbol that was stripped off to make the <SortableSymbol()>, or undef if none.
        -#                          Only available after calling <MakeSortableSymbol()>.
        -#
        -
        -#   Function: HasMultiplePackages
        -#   Returns whether <Packages()> is broken out into more elements.
        -sub HasMultiplePackages
        -    {  return ref($_[0]->[PACKAGE]);  };
        -
        -#   Function: HasMultipleFiles
        -#   Returns whether <File()> is broken out into more elements.
        -sub HasMultipleFiles
        -    {  return ref($_[0]->[FILE]);  };
        -
        -
        -
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -#
        -#   Function: MergeFile
        -#
        -#   Adds another definition of the same package/symbol.  Perhaps the file is different.
        -#
        -#   Parameters:
        -#
        -#       file  - The package/symbol's definition file.
        -#       type  - The package/symbol's <TopicType>.
        -#       prototype  - The package/symbol's protoype if applicable.
        -#       summary  - The package/symbol's summary if applicable.
        -#
        -sub MergeFile #(file, type, prototype, summary)
        -    {
        -    my ($self, $file, $type, $prototype, $summary) = @_;
        -
        -    # If there's only one file...
        -    if (!$self->HasMultipleFiles())
        -        {
        -        # If there's one file and it's the different from the new one...
        -        if ($file ne $self->File())
        -            {
        -            my $selfDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, undef, $self->File(), $self->Type(),
        -                                                                                                                 $self->Prototype(), $self->Summary(),
        -                                                                                                                 $self->CombinedType(),
        -                                                                                                                 $self->PackageSeparator());
        -            my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, undef, $file, $type, $prototype,
        -                                                                                                                  $summary);
        -
        -            $self->[FILE] = [ $selfDefinition, $newDefinition ];
        -            $self->[TYPE] = undef;
        -            $self->[PROTOTYPE] = undef;
        -            $self->[SUMMARY] = undef;
        -
        -            if ($newDefinition->Type() ne $self->CombinedType())
        -                {  $self->[COMBINED_TYPE] = ::TOPIC_GENERAL();  };
        -            if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
        -                {  $self->[PACKAGE_SEPARATOR] = '.';  };
        -            }
        -
        -        # If the file was the same, just ignore the duplicate in the index.
        -        }
        -
        -    # If there's more than one file...
        -    else
        -        {
        -        # See if the new file is one of them.
        -        my $files = $self->File();
        -
        -        foreach my $testElement (@$files)
        -            {
        -            if ($testElement->File() eq $file)
        -                {
        -                # If the new file's already in the index, ignore the duplicate.
        -                return;
        -                };
        -            };
        -
        -        my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, undef, $file, $type, $prototype,
        -                                                                                                              $summary);
        -        push @{$self->[FILE]}, $newDefinition;
        -
        -        if ($newDefinition->Type() ne $self->CombinedType())
        -            {  $self->[COMBINED_TYPE] = ::TOPIC_GENERAL();  };
        -        if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
        -            {  $self->[PACKAGE_SEPARATOR] = '.';  };
        -        };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/Reference.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/Reference.pm
        deleted file mode 100644
        index fd5ef7047..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/Reference.pm
        +++ /dev/null
        @@ -1,274 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SymbolTable::Reference
        -#
        -###############################################################################
        -#
        -#   A class representing a symbol or a potential symbol.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolTable::Reference;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are its members.
        -#
        -#       DEFINITIONS                        - An existence hashref of the <FileNames> that define this reference.
        -#       INTERPRETATIONS                - A hashref of the possible interpretations of this reference.  The keys are the <SymbolStrings>
        -#                                                     and the values are the scores.
        -#       CURRENT_INTERPRETATION  - The interpretation currently used as the reference target.  It will be the interpretation with
        -#                                                     the highest score that is actually defined.  If none are defined, this item will be undef.
        -#
        -
        -# DEPENDENCY: New() depends on the order of these constants.  If they change, New() has to be updated.
        -use constant DEFINITIONS => 0;
        -use constant INTERPRETATIONS => 1;
        -use constant CURRENT_INTERPRETATION => 2;
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -sub New
        -    {
        -    my $package = shift;
        -
        -    # Let's make it safe, since normally you can pass values to New.  Having them just be ignored would be an obscure error.
        -    if (scalar @_)
        -        {  die "You can't pass values to NaturalDocs::SymbolTable::Reference->New()\n";  };
        -
        -    # DEPENDENCY: This code depends on the order of the member constants.
        -    my $object = [ { }, { }, undef ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Function: AddDefinition
        -#
        -#   Adds a reference definition.
        -#
        -#   Parameters:
        -#
        -#       file   - The <FileName> that defines the reference.
        -#
        -sub AddDefinition #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    $self->[DEFINITIONS]{$file} = 1;
        -    };
        -
        -
        -#
        -#   Function: DeleteDefinition
        -#
        -#   Removes a reference definition.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> which has the definition to delete.
        -#
        -sub DeleteDefinition #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    delete $self->[DEFINITIONS]{$file};
        -    };
        -
        -
        -#
        -#   Function: AddInterpretation
        -#
        -#   Adds a symbol that this reference can be interpreted as.
        -#
        -#   Parameters:
        -#
        -#       symbol  - The <SymbolString>.
        -#       score     - The score of this interpretation.
        -#
        -sub AddInterpretation #(symbol, score)
        -    {
        -    my ($self, $symbol, $score) = @_;
        -
        -    $self->[INTERPRETATIONS]{$symbol} = $score;
        -    };
        -
        -
        -#
        -#   Function: DeleteInterpretation
        -#
        -#   Deletes a symbol that this reference can be interpreted as.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString> to delete.
        -#
        -sub DeleteInterpretation #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -
        -    delete $self->[INTERPRETATIONS]{$symbol};
        -    };
        -
        -
        -#
        -#   Function: DeleteAllInterpretationsButCurrent
        -#
        -#   Deletes all interpretations except for the current one.
        -#
        -sub DeleteAllInterpretationsButCurrent
        -    {
        -    my $self = shift;
        -
        -    if ($self->HasCurrentInterpretation())
        -        {
        -        my $score = $self->CurrentScore();
        -
        -        # Fastest way to clear a hash except for one item?  Make a new hash with just that item.
        -        %{$self->[INTERPRETATIONS]} = ( $self->[CURRENT_INTERPRETATION] => $score );
        -        };
        -    };
        -
        -
        -#
        -#   Function: SetCurrentInterpretation
        -#
        -#   Changes the current interpretation.  The new one must already have been added via <AddInterpretation()>.
        -#
        -#   Parameters:
        -#
        -#       symbol - The <SymbolString>l to make the current interpretation.  Can be set to undef to clear it.
        -#
        -sub SetCurrentInterpretation #(symbol)
        -    {
        -    my ($self, $symbol) = @_;
        -
        -    $self->[CURRENT_INTERPRETATION] = $symbol;
        -    };
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -
        -#
        -#   Function: Definitions
        -#
        -#   Returns an array of all the <FileNames> that define this reference.  If none do, returns an empty array.
        -#
        -sub Definitions
        -    {
        -    return keys %{$_[0]->[DEFINITIONS]};
        -    };
        -
        -
        -#
        -#   Function: IsDefined
        -#
        -#   Returns whether the reference has any definitions or not.
        -#
        -sub IsDefined
        -    {
        -    return scalar keys %{$_[0]->[DEFINITIONS]};
        -    };
        -
        -
        -#
        -#   Function: IsDefinedIn
        -#
        -#   Returns whether the reference is defined in the passed <FileName>.
        -#
        -sub IsDefinedIn #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    return exists $self->[DEFINITIONS]{$file};
        -    };
        -
        -
        -#
        -#   Function: Interpretations
        -#
        -#   Returns an array of all the <SymbolStrings> that this reference can be interpreted as.  If none, returns an empty array.
        -#
        -sub Interpretations
        -    {
        -    return keys %{$_[0]->[INTERPRETATIONS]};
        -    };
        -
        -
        -#
        -#   Function: InterpretationsAndScores
        -#
        -#   Returns a hash of all the <SymbolStrings> that this reference can be interpreted as and their scores.  The keys are the <SymbolStrings>
        -#   and the values are the scores.  If none, returns an empty hash.
        -#
        -sub InterpretationsAndScores
        -    {
        -    return %{$_[0]->[INTERPRETATIONS]};
        -    };
        -
        -
        -#
        -#   Function: HasCurrentInterpretation
        -#
        -#   Returns whether the reference has a current interpretation or not.
        -#
        -sub HasCurrentInterpretation
        -    {
        -    return defined $_[0]->[CURRENT_INTERPRETATION];
        -    };
        -
        -
        -#
        -#   Function: CurrentInterpretation
        -#
        -#   Returns the <SymbolString> of the current interpretation, or undef if none.
        -#
        -sub CurrentInterpretation
        -    {
        -    return $_[0]->[CURRENT_INTERPRETATION];
        -    };
        -
        -
        -#
        -#   Function: CurrentScore
        -#
        -#   Returns the score of the current interpretation, or undef if none.
        -#
        -sub CurrentScore
        -    {
        -    my $self = shift;
        -
        -    if (defined $self->[CURRENT_INTERPRETATION])
        -        {
        -        return $self->[INTERPRETATIONS]{ $self->[CURRENT_INTERPRETATION] };
        -        }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm
        deleted file mode 100644
        index 4f9ee407f..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm
        +++ /dev/null
        @@ -1,98 +0,0 @@
        -###############################################################################
        -#
        -#   Class: NaturalDocs::SymbolTable::ReferenceTarget
        -#
        -###############################################################################
        -#
        -#   A class for storing information about a reference target.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolTable::ReferenceTarget;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are its members.
        -#
        -#       SYMBOL  - The target <SymbolString>.
        -#       FILE        - The <FileName> the target is defined in.
        -#       TYPE       - The target <TopicType>.
        -#       PROTOTYPE - The target's prototype, or undef if none.
        -#       SUMMARY    - The target's summary, or undef if none.
        -#
        -
        -# DEPENDENCY: New() depends on the order of these constants.  If they change, New() has to be updated.
        -use constant SYMBOL => 0;
        -use constant FILE => 1;
        -use constant TYPE => 2;
        -use constant PROTOTYPE => 3;
        -use constant SUMMARY => 4;
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       symbol - The target <SymbolString>.
        -#       file       - The <FileName> the target is defined in.
        -#       type     - The <TopicType> of the target symbol.
        -#       prototype - The target's prototype.  Set to undef if not defined or not applicable.
        -#       summary - The target's summary.  Set to undef if not defined or not applicable.
        -#
        -sub New #(symbol, file, type, prototype, summary)
        -    {
        -    # DEPENDENCY: This code depends on the order of the member constants.
        -
        -    my $package = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -# Function: Symbol
        -# Returns the target's <SymbolString>.
        -sub Symbol
        -    {  return $_[0]->[SYMBOL];  };
        -
        -# Function: File
        -# Returns the <FileName> the target is defined in.
        -sub File
        -    {  return $_[0]->[FILE];  };
        -
        -# Function: Type
        -# Returns the target's <TopicType>.
        -sub Type
        -    {  return $_[0]->[TYPE];  };
        -
        -# Function: Prototype
        -# Returns the target's prototype, or undef if not defined or not applicable.
        -sub Prototype
        -    {  return $_[0]->[PROTOTYPE];  };
        -
        -# Function: Summary
        -# Returns the target's summary, or undef if not defined or not applicable.
        -sub Summary
        -    {  return $_[0]->[SUMMARY];  };
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/Symbol.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/Symbol.pm
        deleted file mode 100644
        index 83a7148a3..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/Symbol.pm
        +++ /dev/null
        @@ -1,429 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SymbolTable::Symbol
        -#
        -###############################################################################
        -#
        -#   A class representing a symbol or a potential symbol.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolTable::Symbol;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are its members.
        -#
        -#       DEFINITIONS             - A hashref of all the files which define this symbol.  The keys are the <FileNames>, and the values are
        -#                                         <NaturalDocs::SymbolTable::SymbolDefinition> objects.  If no files define this symbol, this item will
        -#                                          be undef.
        -#       GLOBAL_DEFINITION  - The <FileName> which defines the global version of the symbol, which is what is used if
        -#                                          a file references the symbol but does not have its own definition.  If there are no definitions, this
        -#                                          item will be undef.
        -#       REFERENCES              - A hashref of the references that can be interpreted as this symbol.  This doesn't mean these
        -#                                          references necessarily are.  The keys are the reference strings, and the values are the scores of
        -#                                          the interpretations.  If no references can be interpreted as this symbol, this item will be undef.
        -#
        -use constant DEFINITIONS => 0;
        -use constant GLOBAL_DEFINITION => 1;
        -use constant REFERENCES => 2;
        -
        -
        -###############################################################################
        -# Group: Modification Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -sub New
        -    {
        -    my $package = shift;
        -
        -    # Let's make it safe, since normally you can pass values to New.  Having them just be ignored would be an obscure error.
        -    if (scalar @_)
        -        {  die "You can't pass values to NaturalDocs::SymbolTable::Symbol->New()\n";  };
        -
        -    my $object = [ undef, undef, undef ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -#
        -#   Function: AddDefinition
        -#
        -#   Adds a symbol definition.  If this is the first definition for this symbol, it will become the global definition.  If the definition
        -#   already exists for the file, it will be ignored.
        -#
        -#   Parameters:
        -#
        -#       file   - The <FileName> that defines the symbol.
        -#       type - The <TopicType> of the definition.
        -#       prototype - The prototype of the definition, if applicable.  Undef otherwise.
        -#       summary - The summary for the definition, if applicable.  Undef otherwise.
        -#
        -#   Returns:
        -#
        -#       Whether this provided the first definition for this symbol.
        -#
        -sub AddDefinition #(file, type, prototype, summary)
        -    {
        -    my ($self, $file, $type, $prototype, $summary) = @_;
        -
        -    my $isFirst;
        -
        -    if (!defined $self->[DEFINITIONS])
        -        {
        -        $self->[DEFINITIONS] = { };
        -        $self->[GLOBAL_DEFINITION] = $file;
        -        $isFirst = 1;
        -        };
        -
        -    if (!exists $self->[DEFINITIONS]{$file})
        -        {
        -        $self->[DEFINITIONS]{$file} = NaturalDocs::SymbolTable::SymbolDefinition->New($type, $prototype, $summary);
        -        };
        -
        -    return $isFirst;
        -    };
        -
        -
        -#
        -#   Function: ChangeDefinition
        -#
        -#   Changes the information about an existing definition.
        -#
        -#   Parameters:
        -#
        -#       file   - The <FileName> that defines the symbol.  Must exist.
        -#       type - The new <TopicType> of the definition.
        -#       prototype - The new prototype of the definition, if applicable.  Undef otherwise.
        -#       summary - The new summary of the definition, if applicable.  Undef otherwise.
        -#
        -sub ChangeDefinition #(file, type, prototype, summary)
        -    {
        -    my ($self, $file, $type, $prototype, $summary) = @_;
        -
        -    if (defined $self->[DEFINITIONS] &&
        -        exists $self->[DEFINITIONS]{$file})
        -        {
        -        $self->[DEFINITIONS]{$file}->SetType($type);
        -        $self->[DEFINITIONS]{$file}->SetPrototype($prototype);
        -        $self->[DEFINITIONS]{$file}->SetSummary($summary);
        -        };
        -    };
        -
        -
        -#
        -#   Function: DeleteDefinition
        -#
        -#   Removes a symbol definition.  If the definition served as the global definition, a new one will be selected.
        -#
        -#   Parameters:
        -#
        -#       file - The <FileName> which contains definition to delete.
        -#
        -#   Returns:
        -#
        -#       Whether that was the only definition, and the symbol is now undefined.
        -#
        -sub DeleteDefinition #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    # If there are no definitions...
        -    if (!defined $self->[DEFINITIONS])
        -        {  return undef;  };
        -
        -    delete $self->[DEFINITIONS]{$file};
        -
        -    # If there are no more definitions...
        -    if (!scalar keys %{$self->[DEFINITIONS]})
        -        {
        -        $self->[DEFINITIONS] = undef;
        -
        -        # If definitions was previously defined, and now is empty, we can safely assume that the global definition was just deleted
        -        # without checking it against $file.
        -
        -        $self->[GLOBAL_DEFINITION] = undef;
        -
        -        return 1;
        -        }
        -
        -    # If there are more definitions and the global one was just deleted...
        -    elsif ($self->[GLOBAL_DEFINITION] eq $file)
        -        {
        -        # Which one becomes global is pretty much random.
        -        $self->[GLOBAL_DEFINITION] = (keys %{$self->[DEFINITIONS]})[0];
        -        return undef;
        -        };
        -    };
        -
        -
        -#
        -#   Function: AddReference
        -#
        -#   Adds a reference that can be interpreted as this symbol.  It can be, but not necessarily is.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The string of the reference.
        -#       score                - The score of this interpretation.
        -#
        -sub AddReference #(referenceString, score)
        -    {
        -    my ($self, $referenceString, $score) = @_;
        -
        -    if (!defined $self->[REFERENCES])
        -        {  $self->[REFERENCES] = { };  };
        -
        -    $self->[REFERENCES]{$referenceString} = $score;
        -    };
        -
        -
        -#
        -#   Function: DeleteReference
        -#
        -#   Deletes a reference that can be interpreted as this symbol.
        -#
        -#   Parameters:
        -#
        -#       referenceString - The string of the reference to delete.
        -#
        -sub DeleteReference #(referenceString)
        -    {
        -    my ($self, $referenceString) = @_;
        -
        -    # If there are no definitions...
        -    if (!defined $self->[REFERENCES])
        -        {  return;  };
        -
        -    delete $self->[REFERENCES]{$referenceString};
        -
        -    # If there are no more definitions...
        -    if (!scalar keys %{$self->[REFERENCES]})
        -        {
        -        $self->[REFERENCES] = undef;
        -        };
        -    };
        -
        -
        -#
        -#   Function: DeleteAllReferences
        -#
        -#   Removes all references that can be interpreted as this symbol.
        -#
        -sub DeleteAllReferences
        -    {
        -    $_[0]->[REFERENCES] = undef;
        -    };
        -
        -
        -###############################################################################
        -# Group: Information Functions
        -
        -#
        -#   Function: IsDefined
        -#
        -#   Returns whether the symbol is defined anywhere or not.  If it's not, that means it's just a potential interpretation of a
        -#   reference.
        -#
        -sub IsDefined
        -    {
        -    return defined $_[0]->[GLOBAL_DEFINITION];
        -    };
        -
        -#
        -#   Function: IsDefinedIn
        -#
        -#   Returns whether the symbol is defined in the passed <FileName>.
        -#
        -sub IsDefinedIn #(file)
        -    {
        -    my ($self, $file) = @_;
        -    return ($self->IsDefined() && exists $self->[DEFINITIONS]{$file});
        -    };
        -
        -
        -#
        -#   Function: Definitions
        -#
        -#   Returns an array of all the <FileNames> that define this symbol.  If none do, will return an empty array.
        -#
        -sub Definitions
        -    {
        -    my $self = shift;
        -
        -    if ($self->IsDefined())
        -        {  return keys %{$self->[DEFINITIONS]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -#
        -#   Function: GlobalDefinition
        -#
        -#   Returns the <FileName> that contains the global definition of this symbol, or undef if the symbol isn't defined.
        -#
        -sub GlobalDefinition
        -    {
        -    return $_[0]->[GLOBAL_DEFINITION];
        -    };
        -
        -
        -#
        -#   Function: TypeDefinedIn
        -#
        -#   Returns the <TopicType> of the symbol defined in the passed <FileName>, or undef if it's not defined in that file.
        -#
        -sub TypeDefinedIn #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if ($self->IsDefined())
        -        {  return $self->[DEFINITIONS]{$file}->Type();  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: GlobalType
        -#
        -#   Returns the <TopicType> of the global definition, or undef if the symbol isn't defined.
        -#
        -sub GlobalType
        -    {
        -    my $self = shift;
        -
        -    my $globalDefinition = $self->GlobalDefinition();
        -
        -    if (!defined $globalDefinition)
        -        {  return undef;  }
        -    else
        -        {  return $self->[DEFINITIONS]{$globalDefinition}->Type();  };
        -    };
        -
        -
        -#
        -#   Function: PrototypeDefinedIn
        -#
        -#   Returns the prototype of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
        -#
        -sub PrototypeDefinedIn #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if ($self->IsDefined())
        -        {  return $self->[DEFINITIONS]{$file}->Prototype();  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: GlobalPrototype
        -#
        -#   Returns the prototype of the global definition.  Will be undef if it doesn't exist or the symbol isn't defined.
        -#
        -sub GlobalPrototype
        -    {
        -    my $self = shift;
        -
        -    my $globalDefinition = $self->GlobalDefinition();
        -
        -    if (!defined $globalDefinition)
        -        {  return undef;  }
        -    else
        -        {  return $self->[DEFINITIONS]{$globalDefinition}->Prototype();  };
        -    };
        -
        -
        -#
        -#   Function: SummaryDefinedIn
        -#
        -#   Returns the summary of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
        -#
        -sub SummaryDefinedIn #(file)
        -    {
        -    my ($self, $file) = @_;
        -
        -    if ($self->IsDefined())
        -        {  return $self->[DEFINITIONS]{$file}->Summary();  }
        -    else
        -        {  return undef;  };
        -    };
        -
        -
        -#
        -#   Function: GlobalSummary
        -#
        -#   Returns the summary of the global definition.  Will be undef if it doesn't exist or the symbol isn't defined.
        -#
        -sub GlobalSummary
        -    {
        -    my $self = shift;
        -
        -    my $globalDefinition = $self->GlobalDefinition();
        -
        -    if (!defined $globalDefinition)
        -        {  return undef;  }
        -    else
        -        {  return $self->[DEFINITIONS]{$globalDefinition}->Summary();  };
        -    };
        -
        -
        -#
        -#   Function: HasReferences
        -#
        -#   Returns whether the symbol can be interpreted as any references.
        -#
        -sub HasReferences
        -    {
        -    return defined $_[0]->[REFERENCES];
        -    };
        -
        -#
        -#   Function: References
        -#
        -#   Returns an array of all the reference strings that can be interpreted as this symbol.  If none, will return an empty array.
        -#
        -sub References
        -    {
        -    if (defined $_[0]->[REFERENCES])
        -        {  return keys %{$_[0]->[REFERENCES]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -#
        -#   Function: ReferencesAndScores
        -#
        -#   Returns a hash of all the references that can be interpreted as this symbol and their scores.  The keys are the reference
        -#   strings, and the values are the scores.  If none, will return an empty hash.
        -#
        -sub ReferencesAndScores
        -    {
        -    if (defined $_[0]->[REFERENCES])
        -        {  return %{$_[0]->[REFERENCES]};  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm b/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm
        deleted file mode 100644
        index 9d5746057..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm
        +++ /dev/null
        @@ -1,97 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::SymbolTable::SymbolDefinition
        -#
        -###############################################################################
        -#
        -#   A class representing a symbol definition.  This does not store the definition symbol, class, or file.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::SymbolTable::SymbolDefinition;
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   Constants: Members
        -#
        -#   The class is implemented as a blessed arrayref.  The following constants are its members.
        -#
        -#       TYPE  - The symbol <TopicType>.
        -#       PROTOTYPE  - The symbol's prototype, if applicable.  Will be undef otherwise.
        -#       SUMMARY - The symbol's summary, if applicable.  Will be undef otherwise.
        -#
        -use constant TYPE => 0;
        -use constant PROTOTYPE => 1;
        -use constant SUMMARY => 2;
        -# New depends on the order of the constants.
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       type - The symbol <TopicType>.
        -#       prototype  - The symbol prototype, if applicable.  Undef otherwise.
        -#       summary - The symbol's summary, if applicable.  Undef otherwise.
        -#
        -sub New #(type, prototype, summary)
        -    {
        -    # This depends on the parameter list being the same as the constant order.
        -
        -    my $package = shift;
        -
        -    my $object = [ @_ ];
        -    bless $object, $package;
        -
        -    return $object;
        -    };
        -
        -
        -#   Function: Type
        -#   Returns the definition's <TopicType>.
        -sub Type
        -    {  return $_[0]->[TYPE];  };
        -
        -# Function: SetType
        -# Changes the <TopicType>.
        -sub SetType #(type)
        -    {  $_[0]->[TYPE] = $_[1];  };
        -
        -#   Function: Prototype
        -#   Returns the definition's prototype, or undef if it doesn't have one.
        -sub Prototype
        -    {  return $_[0]->[PROTOTYPE];  };
        -
        -# Function: SetPrototype
        -# Changes the prototype.
        -sub SetPrototype #(prototype)
        -    {  $_[0]->[PROTOTYPE] = $_[1];  };
        -
        -#   Function: Summary
        -#   Returns the definition's summary, or undef if it doesn't have one.
        -sub Summary
        -    {  return $_[0]->[SUMMARY];  };
        -
        -# Function: SetSummary
        -# Changes the summary.
        -sub SetSummary #(summary)
        -    {  $_[0]->[SUMMARY] = $_[1];  };
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Topics.pm b/vendor/naturaldocs/Modules/NaturalDocs/Topics.pm
        deleted file mode 100644
        index d2668782a..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Topics.pm
        +++ /dev/null
        @@ -1,1320 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Topics
        -#
        -###############################################################################
        -#
        -#   The topic constants and functions to convert them to and from strings used throughout the script.  All constants are exported
        -#   by default.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use Text::Wrap ( );
        -use Tie::RefHash ( );
        -
        -use strict;
        -use integer;
        -
        -use NaturalDocs::Topics::Type;
        -
        -package NaturalDocs::Topics;
        -
        -use base 'Exporter';
        -our @EXPORT = ( 'TOPIC_GENERAL', 'TOPIC_GENERIC', 'TOPIC_GROUP', 'TOPIC_CLASS', 'TOPIC_FILE', 'TOPIC_FUNCTION',
        -                          'TOPIC_VARIABLE', 'TOPIC_PROPERTY', 'TOPIC_TYPE', 'TOPIC_ENUMERATION', 'TOPIC_CONSTANT',
        -                          'TOPIC_INTERFACE', 'TOPIC_EVENT', 'TOPIC_DELEGATE', 'TOPIC_SECTION' );
        -
        -
        -
        -###############################################################################
        -# Group: Types
        -
        -
        -#
        -#   Type: TopicType
        -#
        -#   A string representing a topic type as defined in <Topics.txt>.  It's format should be treated as opaque; use <MakeTopicType()>
        -#   to get them from topic names.  However, they can be compared for equality with string functions.
        -#
        -
        -
        -#
        -#   Constants: Default TopicTypes
        -#
        -#   Exported constants of the default <TopicTypes>, so you don't have to go through <TypeFromName()> every time.
        -#
        -#   TOPIC_GENERAL - The general <TopicType>, which has the special meaning of none in particular.
        -#   TOPIC_GENERIC - Generic <TopicType>.
        -#   TOPIC_GROUP - Group <TopicType>.
        -#   TOPIC_CLASS - Class <TopicType>.
        -#   TOPIC_INTERFACE - Interface <TopicType>.
        -#   TOPIC_FILE - File <TopicType>.
        -#   TOPIC_SECTION - Section <TopicType>.
        -#   TOPIC_FUNCTION - Function <TopicType>.
        -#   TOPIC_VARIABLE - Variable <TopicType>.
        -#   TOPIC_PROPERTY - Property <TopicType>.
        -#   TOPIC_TYPE - Type <TopicType>.
        -#   TOPIC_CONSTANT - Constant <TopicType>.
        -#   TOPIC_ENUMERATION - Enum <TopicType>.
        -#   TOPIC_DELEGATE - Delegate <TopicType>.
        -#   TOPIC_EVENT - Event <TopicType>.
        -#
        -use constant TOPIC_GENERAL => 'general';
        -use constant TOPIC_GENERIC => 'generic';
        -use constant TOPIC_GROUP => 'group';
        -use constant TOPIC_CLASS => 'class';
        -use constant TOPIC_INTERFACE => 'interface';
        -use constant TOPIC_FILE => 'file';
        -use constant TOPIC_SECTION => 'section';
        -use constant TOPIC_FUNCTION => 'function';
        -use constant TOPIC_VARIABLE => 'variable';
        -use constant TOPIC_PROPERTY => 'property';
        -use constant TOPIC_TYPE => 'type';
        -use constant TOPIC_CONSTANT => 'constant';
        -use constant TOPIC_ENUMERATION => 'enumeration';
        -use constant TOPIC_DELEGATE => 'delegate';
        -use constant TOPIC_EVENT => 'event';
        -# Dependency: The values of these constants must match what is generated by MakeTopicType().
        -# Dependency: These types must be added to requiredTypeNames so that they always exist.
        -
        -
        -
        -
        -###############################################################################
        -# Group: Variables
        -
        -
        -#
        -#   handle: FH_TOPICS
        -#
        -#   The file handle used when writing to <Topics.txt>.
        -#
        -
        -
        -#
        -#   hash: types
        -#
        -#   A hashref that maps <TopicTypes> to <NaturalDocs::Topics::Type>s.
        -#
        -my %types;
        -
        -
        -#
        -#   hash: names
        -#
        -#   A hashref that maps various forms of the all-lowercase type names to <TopicTypes>.  All are in the same hash because
        -#   two names that reduce to the same thing it would cause big problems, and we need to catch that.  Keys include
        -#
        -#   - Topic names
        -#   - Plural topic names
        -#   - Alphanumeric-only topic names
        -#   - Alphanumeric-only plural topic names
        -#
        -my %names;
        -
        -
        -#
        -#   hash: keywords
        -#
        -#   A hashref that maps all-lowercase keywords to their <TopicTypes>.  Must not have any of the same keys as
        -#   <pluralKeywords>.
        -#
        -my %keywords;
        -
        -
        -#
        -#   hash: pluralKeywords
        -#
        -#   A hashref that maps all-lowercase plural keywords to their <TopicTypes>.  Must not have any of the same keys as
        -#   <keywords>.
        -#
        -my %pluralKeywords;
        -
        -
        -#
        -#   hash: indexable
        -#
        -#   An existence hash of all the indexable <TopicTypes>.
        -#
        -my %indexable;
        -
        -
        -#
        -#   array: requiredTypeNames
        -#
        -#   An array of the <TopicType> names which are required to be defined in the main file.  Are in the order they should appear
        -#   when reformatting.
        -#
        -my @requiredTypeNames = ( 'Generic', 'Class', 'Interface', 'Section', 'File', 'Group', 'Function', 'Variable', 'Property', 'Type',
        -                                           'Constant', 'Enumeration', 'Event', 'Delegate' );
        -
        -
        -#
        -#   array: legacyTypes
        -#
        -#   An array that converts the legacy topic types, which were numeric constants prior to 1.3, to the current <TopicTypes>.
        -#   The legacy types are used as an index into the array.  Note that this does not support list type values.
        -#
        -my @legacyTypes = ( TOPIC_GENERAL, TOPIC_CLASS, TOPIC_SECTION, TOPIC_FILE, TOPIC_GROUP, TOPIC_FUNCTION,
        -                                TOPIC_VARIABLE, TOPIC_GENERIC, TOPIC_TYPE, TOPIC_CONSTANT, TOPIC_PROPERTY );
        -
        -
        -#
        -#   array: mainTopicNames
        -#
        -#   An array of the <TopicType> names that are defined in the main <Topics.txt>.
        -#
        -my @mainTopicNames;
        -
        -
        -
        -###############################################################################
        -# Group: Files
        -
        -
        -#
        -#   File: Topics.txt
        -#
        -#   The configuration file that defines or overrides the topic definitions for Natural Docs.  One version sits in Natural Docs'
        -#   configuration directory, and another can be in a project directory to add to or override them.
        -#
        -#   > # [comments]
        -#
        -#   Everything after a # symbol is ignored.
        -#
        -#   Except when specifying topic names, everything below is case-insensitive.
        -#
        -#   > Format: [version]
        -#
        -#   Specifies the file format version of the file.
        -#
        -#
        -#   Sections:
        -#
        -#       > Ignore[d] Keyword[s]: [keyword], [keyword] ...
        -#       >    [keyword]
        -#       >    [keyword], [keyword]
        -#       >    ...
        -#
        -#       Ignores the keywords so that they're not recognized as Natural Docs topics anymore.  Can be specified as a list on the same
        -#       line and/or following like a normal Keywords section.
        -#
        -#       > Topic Type: [name]
        -#       > Alter Topic Type: [name]
        -#
        -#       Creates a new topic type or alters an existing one.  The name can only contain <CFChars> and isn't case sensitive, although
        -#       the original case is remembered for presentation.
        -#
        -#       The name General is reserved.  There are a number of default types that must be defined in the main file as well, but those
        -#       are governed by <NaturalDocs::Topics> and are not included here.  The default types can have their keywords or behaviors
        -#       changed, though, either by editing the default file or by overriding them in the user file.
        -#
        -#       Enumeration is a special type.  It is indexed with Types and its definition list members are listed with Constants according
        -#       to the rules in <Languages.txt>.
        -#
        -#
        -#   Topic Type Sections:
        -#
        -#       > Plural: [name]
        -#
        -#       Specifies the plural name of the topic type.  Defaults to the singular name.  Has the same restrictions as the topic type
        -#       name.
        -#
        -#       > Index: [yes|no]
        -#
        -#       Whether the topic type gets an index.  Defaults to yes.
        -#
        -#       > Scope: [normal|start|end|always global]
        -#
        -#       How the topic affects scope.  Defaults to normal.
        -#
        -#       normal - The topic stays within the current scope.
        -#       start - The topic starts a new scope for all the topics beneath it, like class topics.
        -#       end - The topic resets the scope back to global for all the topics beneath it, like section topics.
        -#       always global - The topic is defined as a global symbol, but does not change the scope for any other topics.
        -#
        -#       > Class Hierarchy: [yes|no]
        -#
        -#       Whether the topic is part of the class hierarchy.  Defaults to no.
        -#
        -#       > Page Title if First: [yes|no]
        -#
        -#       Whether the title of this topic becomes the page title if it is the first topic in a file.  Defaults to no.
        -#
        -#       > Break Lists: [yes|no]
        -#
        -#       Whether list topics should be broken into individual topics in the output.  Defaults to no.
        -#
        -#       > Can Group With: [topic type], [topic type], ...
        -#
        -#       The list of <TopicTypes> the topic can possibly be grouped with.
        -#
        -#       > [Add] Keyword[s]:
        -#       >    [keyword]
        -#       >    [keyword], [plural keyword]
        -#       >    ...
        -#
        -#       A list of the topic type's keywords.  Each line after the heading is the keyword and optionally its plural form.  This continues
        -#       until the next line in "keyword: value" format.  "Add" isn't required.
        -#
        -#       - Keywords can only have letters and numbers.  No punctuation or spaces are allowed.
        -#       - Keywords are not case sensitive.
        -#       - Subsequent keyword sections add to the list.  They don't replace it.
        -#       - Keywords can be redefined by other keyword sections.
        -#
        -#
        -#   Revisions:
        -#
        -#       1.3:
        -#
        -#           The initial version of this file.
        -#
        -
        -
        -###############################################################################
        -# Group: File Functions
        -
        -
        -#
        -#   Function: Load
        -#
        -#   Loads both the master and the project version of <Topics.txt>.
        -#
        -sub Load
        -    {
        -    my $self = shift;
        -
        -    # Add the special General topic type.
        -
        -    $types{::TOPIC_GENERAL()} = NaturalDocs::Topics::Type->New('General', 'General', 1, ::SCOPE_NORMAL(), undef);
        -    $names{'general'} = ::TOPIC_GENERAL();
        -    $indexable{::TOPIC_GENERAL()} = 1;
        -    # There are no keywords for the general topic.
        -
        -
        -    $self->LoadFile(1);  # Main
        -
        -    # Dependency: All the default topic types must be checked for existence.
        -
        -    # Check to see if the required types are defined.
        -    foreach my $name (@requiredTypeNames)
        -        {
        -        if (!exists $names{lc($name)})
        -            {  NaturalDocs::ConfigFile->AddError('The ' . $name . ' topic type must be defined in the main topics file.');  };
        -        };
        -
        -    my $errorCount = NaturalDocs::ConfigFile->ErrorCount();
        -
        -    if ($errorCount)
        -        {
        -        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
        -        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
        -                                                    . ' in ' . NaturalDocs::Project->MainConfigFile('Topics.txt'));
        -        }
        -
        -
        -    $self->LoadFile();  # User
        -
        -    $errorCount = NaturalDocs::ConfigFile->ErrorCount();
        -
        -    if ($errorCount)
        -        {
        -        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
        -        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
        -                                                    . ' in ' . NaturalDocs::Project->UserConfigFile('Topics.txt'));
        -        }
        -    };
        -
        -
        -#
        -#   Function: LoadFile
        -#
        -#   Loads a particular version of <Topics.txt>.
        -#
        -#   Parameters:
        -#
        -#       isMain - Whether the file is the main file or not.
        -#
        -sub LoadFile #(isMain)
        -    {
        -    my ($self, $isMain) = @_;
        -
        -    my ($file, $status);
        -
        -    if ($isMain)
        -        {
        -        $file = NaturalDocs::Project->MainConfigFile('Topics.txt');
        -        $status = NaturalDocs::Project->MainConfigFileStatus('Topics.txt');
        -        }
        -    else
        -        {
        -        $file = NaturalDocs::Project->UserConfigFile('Topics.txt');
        -        $status = NaturalDocs::Project->UserConfigFileStatus('Topics.txt');
        -        };
        -
        -    my $version;
        -
        -    if ($version = NaturalDocs::ConfigFile->Open($file))
        -        {
        -        # The format hasn't changed since the file was introduced.
        -
        -        if ($status == ::FILE_CHANGED())
        -            {  NaturalDocs::Project->ReparseEverything();  };
        -
        -        my ($topicTypeKeyword, $topicTypeName, $topicType, $topicTypeObject, $inKeywords, $inIgnoredKeywords);
        -
        -        # Keys are topic type objects, values are unparsed strings.
        -        my %canGroupWith;
        -        tie %canGroupWith, 'Tie::RefHash';
        -
        -        while (my ($keyword, $value) = NaturalDocs::ConfigFile->GetLine())
        -            {
        -            if ($keyword)
        -                {
        -                $inKeywords = 0;
        -                $inIgnoredKeywords = 0;
        -                };
        -
        -            if ($keyword eq 'topic type')
        -                {
        -                $topicTypeKeyword = $keyword;
        -                $topicTypeName = $value;
        -
        -                # Resolve conflicts and create the type if necessary.
        -
        -                $topicType = $self->MakeTopicType($topicTypeName);
        -                my $lcTopicTypeName = lc($topicTypeName);
        -
        -                my $lcTopicTypeAName = $lcTopicTypeName;
        -                $lcTopicTypeAName =~ tr/a-z0-9//cd;
        -
        -                if (!NaturalDocs::ConfigFile->HasOnlyCFChars($topicTypeName))
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Topic names can only have ' . NaturalDocs::ConfigFile->CFCharNames() . '.');
        -                    }
        -                elsif ($topicType eq ::TOPIC_GENERAL())
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('You cannot define a General topic type.');
        -                    }
        -                elsif (defined $types{$topicType} || defined $names{$lcTopicTypeName} || defined $names{$lcTopicTypeAName})
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Topic type ' . $topicTypeName . ' is already defined or its name is too '
        -                                                                     . 'similar to an existing name.  Use Alter Topic Type if you meant to override '
        -                                                                     . 'its settings.');
        -                    }
        -                else
        -                    {
        -                    $topicTypeObject = NaturalDocs::Topics::Type->New($topicTypeName, $topicTypeName, 1, ::SCOPE_NORMAL(),
        -                                                                                                  0, 0);
        -
        -                    $types{$topicType} = $topicTypeObject;
        -                    $names{$lcTopicTypeName} = $topicType;
        -                    $names{$lcTopicTypeAName} = $topicType;
        -
        -                    $indexable{$topicType} = 1;
        -
        -                    if ($isMain)
        -                        {  push @mainTopicNames, $topicTypeName;  };
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'alter topic type')
        -                {
        -                $topicTypeKeyword = $keyword;
        -                $topicTypeName = $value;
        -
        -                # Resolve conflicts and create the type if necessary.
        -
        -                $topicType = $names{lc($topicTypeName)};
        -
        -                if (!defined $topicType)
        -                    {  NaturalDocs::ConfigFile->AddError('Topic type ' . $topicTypeName . ' doesn\'t exist.');  }
        -                elsif ($topicType eq ::TOPIC_GENERAL())
        -                    {  NaturalDocs::ConfigFile->AddError('You cannot alter the General topic type.');  }
        -                else
        -                    {
        -                    $topicTypeObject = $types{$topicType};
        -                    };
        -                }
        -
        -            elsif ($keyword =~ /^ignored? keywords?$/)
        -                {
        -                $inIgnoredKeywords = 1;
        -
        -                my @ignoredKeywords = split(/ ?, ?/, lc($value));
        -
        -                foreach my $ignoredKeyword (@ignoredKeywords)
        -                    {
        -                    delete $keywords{$ignoredKeyword};
        -                    delete $pluralKeywords{$ignoredKeyword};
        -                    };
        -                }
        -
        -            # We continue even if there are errors in the topic type line so that we can find any other errors in the file as well.  We'd
        -            # rather them all show up at once instead of them showing up one at a time between Natural Docs runs.  So we just ignore
        -            # the settings if $topicTypeObject is undef.
        -
        -
        -            elsif ($keyword eq 'plural')
        -                {
        -                my $pluralName = $value;
        -                my $lcPluralName = lc($pluralName);
        -
        -                my $lcPluralAName = $lcPluralName;
        -                $lcPluralAName =~ tr/a-zA-Z0-9//cd;
        -
        -                if (!NaturalDocs::ConfigFile->HasOnlyCFChars($pluralName))
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Plural names can only have '
        -                                                                     . NaturalDocs::ConfigFile->CFCharNames() . '.');
        -                    }
        -                elsif ($lcPluralAName eq 'general')
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('You cannot use General as a plural name for ' . $topicTypeName . '.');
        -                    }
        -                elsif ( (defined $names{$lcPluralName} && $names{$lcPluralName} ne $topicType) ||
        -                         (defined $names{$lcPluralAName} && $names{$lcPluralAName} ne $topicType) )
        -                    {
        -                    NaturalDocs::ConfigFile->AddError($topicTypeName . "'s plural name, " . $pluralName
        -                                                                     . ', is already defined or is too similar to an existing name.');
        -                    }
        -
        -                elsif (defined $topicTypeObject)
        -                    {
        -                    $topicTypeObject->SetPluralName($pluralName);
        -
        -                    $names{$lcPluralName} = $topicType;
        -                    $names{$lcPluralAName} = $topicType;
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'index')
        -                {
        -                $value = lc($value);
        -
        -                if ($value eq 'yes')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {
        -                        $topicTypeObject->SetIndex(1);
        -                        $indexable{$topicType} = 1;
        -                        };
        -                    }
        -                elsif ($value eq 'no')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {
        -                        $topicTypeObject->SetIndex(0);
        -                        delete $indexable{$topicType};
        -                        };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Index lines can only be "yes" or "no".');
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'class hierarchy')
        -                {
        -                $value = lc($value);
        -
        -                if ($value eq 'yes')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetClassHierarchy(1);  };
        -                    }
        -                elsif ($value eq 'no')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetClassHierarchy(0);  };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Class Hierarchy lines can only be "yes" or "no".');
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'scope')
        -                {
        -                $value = lc($value);
        -
        -                if ($value eq 'normal')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetScope(::SCOPE_NORMAL());  };
        -                    }
        -                elsif ($value eq 'start')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetScope(::SCOPE_START());  };
        -                    }
        -                elsif ($value eq 'end')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetScope(::SCOPE_END());  };
        -                    }
        -                elsif ($value eq 'always global')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetScope(::SCOPE_ALWAYS_GLOBAL());  };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Scope lines can only be "normal", "start", "end", or "always global".');
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'page title if first')
        -                {
        -                $value = lc($value);
        -
        -                if ($value eq 'yes')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetPageTitleIfFirst(1);  };
        -                    }
        -                elsif ($value eq 'no')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetPageTitleIfFirst(undef);  };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Page Title if First lines can only be "yes" or "no".');
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'break lists')
        -                {
        -                $value = lc($value);
        -
        -                if ($value eq 'yes')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetBreakLists(1);  };
        -                    }
        -                elsif ($value eq 'no')
        -                    {
        -                    if (defined $topicTypeObject)
        -                        {  $topicTypeObject->SetBreakLists(undef);  };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Break Lists lines can only be "yes" or "no".');
        -                    };
        -                }
        -
        -            elsif ($keyword eq 'can group with')
        -                {
        -                if (defined $topicTypeObject)
        -                    {  $canGroupWith{$topicTypeObject} = lc($value);  };
        -                }
        -
        -            elsif ($keyword =~ /^(?:add )?keywords?$/)
        -                {
        -                $inKeywords = 1;
        -                }
        -
        -            elsif (defined $keyword)
        -                {  NaturalDocs::ConfigFile->AddError($keyword . ' is not a valid keyword.');  }
        -
        -            elsif (!$inKeywords && !$inIgnoredKeywords)
        -                {
        -                NaturalDocs::ConfigFile->AddError('All lines in ' . $topicTypeKeyword . ' sections must begin with a keyword.');
        -                }
        -
        -            else # No keyword but in keyword section.
        -                {
        -                $value = lc($value);
        -
        -                if ($value =~ /^([a-z0-9 ]*[a-z0-9]) ?, ?([a-z0-9 ]+)$/)
        -                    {
        -                    my ($singular, $plural) = ($1, $2);
        -
        -                    if ($inIgnoredKeywords)
        -                        {
        -                        delete $keywords{$singular};
        -                        delete $keywords{$plural};
        -                        delete $pluralKeywords{$singular};
        -                        delete $pluralKeywords{$plural};
        -                        }
        -                    elsif (defined $topicTypeObject)
        -                        {
        -                        $keywords{$singular} = $topicType;
        -                        delete $pluralKeywords{$singular};
        -
        -                        $pluralKeywords{$plural} = $topicType;
        -                        delete $keywords{$plural};
        -                        };
        -                    }
        -                elsif ($value =~ /^[a-z0-9 ]+$/)
        -                    {
        -                    if ($inIgnoredKeywords)
        -                        {
        -                        delete $keywords{$value};
        -                        delete $pluralKeywords{$value};
        -                        }
        -                    elsif (defined $topicType)
        -                        {
        -                        $keywords{$value} = $topicType;
        -                        delete $pluralKeywords{$value};
        -                        };
        -                    }
        -                else
        -                    {
        -                    NaturalDocs::ConfigFile->AddError('Keywords can only have letters, numbers, and spaces.  '
        -                                                                     . 'Plurals must be separated by a comma.');
        -                    };
        -                };
        -            };
        -
        -        NaturalDocs::ConfigFile->Close();
        -
        -
        -        # Parse out the Can Group With lines now that everything's defined.
        -
        -        while (my ($typeObject, $value) = each %canGroupWith)
        -            {
        -            my @values = split(/ ?, ?/, $value);
        -            my @types;
        -
        -            foreach my $value (@values)
        -                {
        -                # We're just going to ignore invalid items.
        -                if (exists $names{$value})
        -                    {  push @types, $names{$value};  };
        -                };
        -
        -            if (scalar @types)
        -                {  $typeObject->SetCanGroupWith(\@types);  };
        -            };
        -        }
        -
        -    else # couldn't open file
        -        {
        -        if ($isMain)
        -            {  die "Couldn't open topics file " . $file . "\n";  }
        -        else
        -            {  NaturalDocs::Project->ReparseEverything();  };
        -        };
        -    };
        -
        -
        -#
        -#   Function: Save
        -#
        -#   Saves the main and user versions of <Topics.txt>.
        -#
        -sub Save
        -    {
        -    my $self = shift;
        -
        -    $self->SaveFile(1); # Main
        -    $self->SaveFile(0); # User
        -    };
        -
        -
        -#
        -#   Function: SaveFile
        -#
        -#   Saves a particular version of <Topics.txt>.
        -#
        -#   Parameters:
        -#
        -#       isMain - Whether the file is the main file or not.
        -#
        -sub SaveFile #(isMain)
        -    {
        -    my ($self, $isMain) = @_;
        -
        -    my $file;
        -
        -    if ($isMain)
        -        {
        -        if (NaturalDocs::Project->MainConfigFileStatus('Topics.txt') == ::FILE_SAME())
        -            {  return;  };
        -        $file = NaturalDocs::Project->MainConfigFile('Topics.txt');
        -        }
        -    else
        -        {
        -        # We have to check the main one two because this lists the topics defined in it.
        -        if (NaturalDocs::Project->UserConfigFileStatus('Topics.txt') == ::FILE_SAME() &&
        -            NaturalDocs::Project->MainConfigFileStatus('Topics.txt') == ::FILE_SAME())
        -            {  return;  };
        -        $file = NaturalDocs::Project->UserConfigFile('Topics.txt');
        -        };
        -
        -
        -    # Array of topic type names in the order they appear in the file.  If Alter Topic Type is used, the name will end with an asterisk.
        -    my @topicTypeOrder;
        -
        -    # Keys are topic type names, values are property hashrefs.  Hashref keys are the property names, values the value.
        -    # For keywords, the key is Keywords and the values are arrayrefs of singular and plural pairs.  If no plural is defined, the entry
        -    # will be undef.
        -    my %properties;
        -
        -    # List of ignored keywords specified as Ignore Keywords: [keyword], [keyword], ...
        -    my @inlineIgnoredKeywords;
        -
        -    # List of ignored keywords specified in [keyword], [plural keyword] lines.  Done in pairs, like for regular keywords.
        -    my @separateIgnoredKeywords;
        -
        -    my $inIgnoredKeywords;
        -
        -    if (NaturalDocs::ConfigFile->Open($file))
        -        {
        -        # We can assume the file is valid.
        -
        -        my ($keyword, $value, $topicTypeName);
        -
        -        while (($keyword, $value) = NaturalDocs::ConfigFile->GetLine())
        -            {
        -            $keyword = lc($keyword);
        -
        -            if ($keyword eq 'topic type' || $keyword eq 'alter topic type')
        -                {
        -                $topicTypeName = $types{ $names{lc($value)} }->Name();
        -
        -                if ($keyword eq 'alter topic type')
        -                    {  $topicTypeName .= '*';  };
        -
        -                push @topicTypeOrder, $topicTypeName;
        -
        -                if (!exists $properties{$topicTypeName})
        -                    {  $properties{$topicTypeName} = { 'keywords' => [ ] };  };
        -                }
        -
        -            elsif ($keyword eq 'plural')
        -                {
        -                $properties{$topicTypeName}->{$keyword} = $value;
        -                }
        -
        -            elsif ($keyword eq 'index' ||
        -                    $keyword eq 'scope' ||
        -                    $keyword eq 'page title if first' ||
        -                    $keyword eq 'class hierarchy' ||
        -                    $keyword eq 'break lists' ||
        -                    $keyword eq 'can group with')
        -                {
        -                $properties{$topicTypeName}->{$keyword} = lc($value);
        -                }
        -
        -            elsif ($keyword =~ /^(?:add )?keywords?$/)
        -                {
        -                $inIgnoredKeywords = 0;
        -                }
        -
        -            elsif ($keyword =~ /^ignored? keywords?$/)
        -                {
        -                $inIgnoredKeywords = 1;
        -                if ($value)
        -                    {  push @inlineIgnoredKeywords, split(/ ?, ?/, $value);  };
        -                }
        -
        -            elsif (!$keyword)
        -                {
        -                my ($singular, $plural) = split(/ ?, ?/, lc($value));
        -
        -                if ($inIgnoredKeywords)
        -                    {  push @separateIgnoredKeywords, $singular, $plural;  }
        -                else
        -                    {  push @{$properties{$topicTypeName}->{'keywords'}}, $singular, $plural;  };
        -                };
        -            };
        -
        -        NaturalDocs::ConfigFile->Close();
        -        };
        -
        -
        -    if (!open(FH_TOPICS, '>' . $file))
        -        {
        -        # The main file may be on a shared volume or some other place the user doesn't have write access to.  Since this is only to
        -        # reformat the file, we can ignore the failure.
        -        if ($isMain)
        -            {  return;  }
        -        else
        -            {  die "Couldn't save " . $file;  };
        -        };
        -
        -    print FH_TOPICS 'Format: ' . NaturalDocs::Settings->TextAppVersion() . "\n\n";
        -
        -    # Remember the 80 character limit.
        -
        -    if ($isMain)
        -        {
        -        print FH_TOPICS
        -        "# This is the main Natural Docs topics file.  If you change anything here, it\n"
        -        . "# will apply to EVERY PROJECT you use Natural Docs on.  If you'd like to\n"
        -        . "# change something for just one project, edit the Topics.txt in its project\n"
        -        . "# directory instead.\n";
        -        }
        -    else
        -        {
        -        print FH_TOPICS
        -        "# This is the Natural Docs topics file for this project.  If you change anything\n"
        -        . "# here, it will apply to THIS PROJECT ONLY.  If you'd like to change something\n"
        -        . "# for all your projects, edit the Topics.txt in Natural Docs' Config directory\n"
        -        . "# instead.\n\n\n";
        -
        -        if (scalar @inlineIgnoredKeywords || scalar @separateIgnoredKeywords)
        -            {
        -            if (scalar @inlineIgnoredKeywords == 1 && !scalar @separateIgnoredKeywords)
        -                {
        -                print FH_TOPICS 'Ignore Keyword: ' . $inlineIgnoredKeywords[0] . "\n";
        -                }
        -            else
        -                {
        -                print FH_TOPICS
        -                'Ignore Keywords: ' . join(', ', @inlineIgnoredKeywords) . "\n";
        -
        -                for (my $i = 0; $i < scalar @separateIgnoredKeywords; $i += 2)
        -                    {
        -                    print FH_TOPICS '   ' . $separateIgnoredKeywords[$i];
        -
        -                    if (defined $separateIgnoredKeywords[$i + 1])
        -                        {  print FH_TOPICS ', ' . $separateIgnoredKeywords[$i + 1];  };
        -
        -                    print FH_TOPICS "\n";
        -                    };
        -                };
        -            }
        -        else
        -            {
        -            print FH_TOPICS
        -            "# If you'd like to prevent keywords from being recognized by Natural Docs, you\n"
        -            . "# can do it like this:\n"
        -            . "# Ignore Keywords: [keyword], [keyword], ...\n"
        -            . "#\n"
        -            . "# Or you can use the list syntax like how they are defined:\n"
        -            . "# Ignore Keywords:\n"
        -            . "#    [keyword]\n"
        -            . "#    [keyword], [plural keyword]\n"
        -            . "#    ...\n";
        -            };
        -        };
        -
        -    print FH_TOPICS # [CFChars]
        -    "\n\n"
        -    . "#-------------------------------------------------------------------------------\n"
        -    . "# SYNTAX:\n"
        -    . "#\n";
        -
        -    if ($isMain)
        -        {
        -        print FH_TOPICS
        -        "# Topic Type: [name]\n"
        -        . "#    Creates a new topic type.  Each type gets its own index and behavior\n"
        -        . "#    settings.  Its name can have letters, numbers, spaces, and these\n"
        -        . "#    charaters: - / . '\n"
        -        . "#\n"
        -        . "#    The Enumeration type is special.  It's indexed with Types but its members\n"
        -        . "#    are indexed with Constants according to the rules in Languages.txt.\n"
        -        . "#\n"
        -        }
        -    else
        -        {
        -        print FH_TOPICS
        -        "# Topic Type: [name]\n"
        -        . "# Alter Topic Type: [name]\n"
        -        . "#    Creates a new topic type or alters one from the main file.  Each type gets\n"
        -        . "#    its own index and behavior settings.  Its name can have letters, numbers,\n"
        -        . "#    spaces, and these charaters: - / . '\n"
        -        . "#\n";
        -        };
        -
        -    print FH_TOPICS
        -    "# Plural: [name]\n"
        -    . "#    Sets the plural name of the topic type, if different.\n"
        -    . "#\n"
        -    . "# Keywords:\n"
        -    . "#    [keyword]\n"
        -    . "#    [keyword], [plural keyword]\n"
        -    . "#    ...\n";
        -
        -    if ($isMain)
        -        {
        -        print FH_TOPICS
        -        "#    Defines a list of keywords for the topic type.  They may only contain\n"
        -        . "#    letters, numbers, and spaces and are not case sensitive.  Plural keywords\n"
        -        . "#    are used for list topics.\n";
        -        }
        -    else
        -        {
        -        print FH_TOPICS
        -        "#    Defines or adds to the list of keywords for the topic type.  They may only\n"
        -        . "#    contain letters, numbers, and spaces and are not case sensitive.  Plural\n"
        -        . "#    keywords are used for list topics.  You can redefine keywords found in the\n"
        -        . "#    main topics file.\n";
        -        }
        -
        -    print FH_TOPICS
        -    "#\n"
        -    . "# Index: [yes|no]\n"
        -    . "#    Whether the topics get their own index.  Defaults to yes.  Everything is\n"
        -    . "#    included in the general index regardless of this setting.\n"
        -    . "#\n"
        -    . "# Scope: [normal|start|end|always global]\n"
        -    . "#    How the topics affects scope.  Defaults to normal.\n"
        -    . "#    normal        - Topics stay within the current scope.\n"
        -    . "#    start         - Topics start a new scope for all the topics beneath it,\n"
        -    . "#                    like class topics.\n"
        -    . "#    end           - Topics reset the scope back to global for all the topics\n"
        -    . "#                    beneath it.\n"
        -    . "#    always global - Topics are defined as global, but do not change the scope\n"
        -    . "#                    for any other topics.\n"
        -    . "#\n"
        -    . "# Class Hierarchy: [yes|no]\n"
        -    . "#    Whether the topics are part of the class hierarchy.  Defaults to no.\n"
        -    . "#\n"
        -    . "# Page Title If First: [yes|no]\n"
        -    . "#    Whether the topic's title becomes the page title if it's the first one in\n"
        -    . "#    a file.  Defaults to no.\n"
        -    . "#\n"
        -    . "# Break Lists: [yes|no]\n"
        -    . "#    Whether list topics should be broken into individual topics in the output.\n"
        -    . "#    Defaults to no.\n"
        -    . "#\n"
        -    . "# Can Group With: [type], [type], ...\n"
        -    . "#    Defines a list of topic types that this one can possibly be grouped with.\n"
        -    . "#    Defaults to none.\n"
        -    . "#-------------------------------------------------------------------------------\n\n";
        -
        -    my $listToPrint;
        -
        -    if ($isMain)
        -        {
        -        print FH_TOPICS
        -        "# The following topics MUST be defined in this file:\n"
        -        . "#\n";
        -        $listToPrint = \@requiredTypeNames;
        -        }
        -    else
        -        {
        -        print FH_TOPICS
        -        "# The following topics are defined in the main file, if you'd like to alter\n"
        -        . "# their behavior or add keywords:\n"
        -        . "#\n";
        -        $listToPrint = \@mainTopicNames;
        -        }
        -
        -    print FH_TOPICS
        -    Text::Wrap::wrap('#    ', '#    ', join(', ', @$listToPrint)) . "\n"
        -    . "\n"
        -    . "# If you add something that you think would be useful to other developers\n"
        -    . "# and should be included in Natural Docs by default, please e-mail it to\n"
        -    . "# topics [at] naturaldocs [dot] org.\n";
        -
        -    # Existence hash.  We do this because we want the required ones to go first by adding them to @topicTypeOrder, but we don't
        -    # want them to appear twice.
        -    my %doneTopicTypes;
        -    my ($altering, $numberOfProperties);
        -
        -    if ($isMain)
        -        {  unshift @topicTypeOrder, @requiredTypeNames;  };
        -
        -    my @propertyOrder = ('Plural', 'Index', 'Scope', 'Class Hierarchy', 'Page Title If First', 'Break Lists');
        -
        -    foreach my $topicType (@topicTypeOrder)
        -        {
        -        if (!exists $doneTopicTypes{$topicType})
        -            {
        -            if (substr($topicType, -1) eq '*')
        -                {
        -                print FH_TOPICS "\n\n"
        -                . 'Alter Topic Type: ' . substr($topicType, 0, -1) . "\n\n";
        -
        -                $altering = 1;
        -                $numberOfProperties = 0;
        -                }
        -            else
        -                {
        -                print FH_TOPICS "\n\n"
        -                . 'Topic Type: ' . $topicType . "\n\n";
        -
        -                $altering = 0;
        -                $numberOfProperties = 0;
        -                };
        -
        -            foreach my $property (@propertyOrder)
        -                {
        -                if (exists $properties{$topicType}->{lc($property)})
        -                    {
        -                    print FH_TOPICS
        -                    '   ' . $property . ': ' . ucfirst( $properties{$topicType}->{lc($property)} ) . "\n";
        -
        -                    $numberOfProperties++;
        -                    };
        -                };
        -
        -            if (exists $properties{$topicType}->{'can group with'})
        -                {
        -                my @typeStrings = split(/ ?, ?/, lc($properties{$topicType}->{'can group with'}));
        -                my @types;
        -
        -                foreach my $typeString (@typeStrings)
        -                    {
        -                    if (exists $names{$typeString})
        -                        {  push @types, $names{$typeString};  };
        -                    };
        -
        -                if (scalar @types)
        -                    {
        -                    for (my $i = 0; $i < scalar @types; $i++)
        -                        {
        -                        my $name = NaturalDocs::Topics->NameOfType($types[$i], 1);
        -
        -                        if ($i == 0)
        -                            {  print FH_TOPICS '   Can Group With: ' . $name;  }
        -                        else
        -                            {  print FH_TOPICS ', ' . $name;  };
        -                        };
        -
        -                    print FH_TOPICS "\n";
        -                    $numberOfProperties++;
        -                    };
        -                };
        -
        -            if (scalar @{$properties{$topicType}->{'keywords'}})
        -                {
        -                if ($numberOfProperties > 1)
        -                    {  print FH_TOPICS "\n";  };
        -
        -                print FH_TOPICS
        -                '   ' . ($altering ? 'Add ' : '') . 'Keywords:' . "\n";
        -
        -                my $keywords = $properties{$topicType}->{'keywords'};
        -
        -                for (my $i = 0; $i < scalar @$keywords; $i += 2)
        -                    {
        -                    print FH_TOPICS '      ' . $keywords->[$i];
        -
        -                    if (defined $keywords->[$i + 1])
        -                        {  print FH_TOPICS ', ' . $keywords->[$i + 1];  };
        -
        -                    print FH_TOPICS "\n";
        -                    };
        -                };
        -
        -            $doneTopicTypes{$topicType} = 1;
        -            };
        -        };
        -
        -    close(FH_TOPICS);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: KeywordInfo
        -#
        -#   Returns information about a topic keyword.
        -#
        -#   Parameters:
        -#
        -#       keyword - The keyword, which may be plural.
        -#
        -#   Returns:
        -#
        -#       The array ( topicType, info, isPlural ), or an empty array if the keyword doesn't exist.
        -#
        -#       topicType - The <TopicType> of the keyword.
        -#       info - The <NaturalDocs::Topics::Type> of its type.
        -#       isPlural - Whether the keyword was plural or not.
        -#
        -sub KeywordInfo #(keyword)
        -    {
        -    my ($self, $keyword) = @_;
        -
        -    $keyword = lc($keyword);
        -
        -    my $type = $keywords{$keyword};
        -
        -    if (defined $type)
        -        {  return ( $type, $types{$type}, undef );  };
        -
        -    $type = $pluralKeywords{$keyword};
        -
        -    if (defined $type)
        -        {  return ( $type, $types{$type}, 1 );  };
        -
        -    return ( );
        -    };
        -
        -
        -#
        -#   Function: NameInfo
        -#
        -#   Returns information about a topic name.
        -#
        -#   Parameters:
        -#
        -#      name - The topic type name, which can be plural and/or alphanumeric only.
        -#
        -#   Returns:
        -#
        -#       The array ( topicType, info ), or an empty array if the name doesn't exist.  Note that unlike <KeywordInfo()>, this
        -#       does *not* tell you whether the name is plural or not.
        -#
        -#       topicType - The <TopicType> of the name.
        -#       info - The <NaturalDocs::Topics::Type> of the type.
        -#
        -sub NameInfo #(name)
        -    {
        -    my ($self, $name) = @_;
        -
        -    my $type = $names{lc($name)};
        -
        -    if (defined $type)
        -        {  return ( $type, $types{$type} );  }
        -    else
        -        {  return ( );  };
        -    };
        -
        -
        -#
        -#   Function: TypeInfo
        -#
        -#   Returns information about a <TopicType>.
        -#
        -#   Parameters:
        -#
        -#      type - The <TopicType>.
        -#
        -#   Returns:
        -#
        -#       The <NaturalDocs::Topics::Type> of the type, or undef if it didn't exist.
        -#
        -sub TypeInfo #(type)
        -    {
        -    my ($self, $type) = @_;
        -    return $types{$type};
        -    };
        -
        -
        -#
        -#   Function: NameOfType
        -#
        -#   Returns the name of the passed <TopicType>, or undef if it doesn't exist.
        -#
        -#   Parameters:
        -#
        -#       topicType - The <TopicType>.
        -#       plural - Whether to return the plural instead of the singular.
        -#       alphanumericOnly - Whether to strips everything but alphanumeric characters out.  Case isn't modified.
        -#
        -#   Returns:
        -#
        -#       The topic type name, according to what was specified in the parameters, or undef if it doesn't exist.
        -#
        -sub NameOfType #(topicType, plural, alphanumericOnly)
        -    {
        -    my ($self, $topicType, $plural, $alphanumericOnly) = @_;
        -
        -    my $topicObject = $types{$topicType};
        -
        -    if (!defined $topicObject)
        -        {  return undef;  };
        -
        -    my $topicName = ($plural ? $topicObject->PluralName() : $topicObject->Name());
        -
        -    if ($alphanumericOnly)
        -        {  $topicName =~ tr/a-zA-Z0-9//cd;  };
        -
        -    return $topicName;
        -    };
        -
        -
        -#
        -#   Function: TypeFromName
        -#
        -#   Returns a <TopicType> for the passed topic name.
        -#
        -#   Parameters:
        -#
        -#       topicName - The name of the topic, which can be plural and/or alphanumeric only.
        -#
        -#   Returns:
        -#
        -#       The <TopicType>.  It does not specify whether the name was plural or not.
        -#
        -sub TypeFromName #(topicName)
        -    {
        -    my ($self, $topicName) = @_;
        -
        -    return $names{lc($topicName)};
        -    };
        -
        -
        -#
        -#   Function: IsValidType
        -#
        -#   Returns whether the passed <TopicType> is defined.
        -#
        -sub IsValidType #(type)
        -    {
        -    my ($self, $type) = @_;
        -    return exists $types{$type};
        -    };
        -
        -
        -#
        -#   Function: TypeFromLegacy
        -#
        -#   Returns a <TopicType> for the passed legacy topic type integer.  <TopicTypes> were changed from integer constants to
        -#   strings in 1.3.
        -#
        -sub TypeFromLegacy #(legacyInt)
        -    {
        -    my ($self, $int) = @_;
        -    return $legacyTypes[$int];
        -    };
        -
        -
        -#
        -#   Function: AllIndexableTypes
        -#
        -#   Returns an array of all possible indexable <TopicTypes>.
        -#
        -sub AllIndexableTypes
        -    {
        -    my ($self) = @_;
        -    return keys %indexable;
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -
        -
        -#
        -#   Function: MakeTopicType
        -#
        -#   Returns a <TopicType> for the passed topic name.  It does not check to see if it exists already.
        -#
        -#   Parameters:
        -#
        -sub MakeTopicType #(topicName)
        -    {
        -    my ($self, $topicName) = @_;
        -
        -    # Dependency: The values of the default topic type constants must match what is generated here.
        -
        -    # Turn everything to lowercase and strip non-alphanumeric characters.
        -    $topicName = lc($topicName);
        -    $topicName =~ tr/a-z0-9//cd;
        -
        -    return $topicName;
        -    };
        -
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Topics/Type.pm b/vendor/naturaldocs/Modules/NaturalDocs/Topics/Type.pm
        deleted file mode 100644
        index 2ed959e9e..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Topics/Type.pm
        +++ /dev/null
        @@ -1,152 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Topics::Type
        -#
        -###############################################################################
        -#
        -#   A class storing information about a <TopicType>.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -
        -package NaturalDocs::Topics::Type;
        -
        -use NaturalDocs::DefineMembers 'NAME',                         'Name()',
        -                                                 'PLURAL_NAME',             'PluralName()',      'SetPluralName()',
        -                                                 'INDEX',                        'Index()',              'SetIndex()',
        -                                                 'SCOPE',                       'Scope()',              'SetScope()',
        -                                                 'PAGE_TITLE_IF_FIRST', 'PageTitleIfFirst()', 'SetPageTitleIfFirst()',
        -                                                 'BREAK_LISTS',             'BreakLists()',        'SetBreakLists()',
        -                                                 'CLASS_HIERARCHY',    'ClassHierarchy()',  'SetClassHierarchy()',
        -                                                 'CAN_GROUP_WITH';
        -
        -# Dependency: New() depends on the order of these and that there are no parent classes.
        -
        -use base 'Exporter';
        -our @EXPORT = ('SCOPE_NORMAL', 'SCOPE_START', 'SCOPE_END', 'SCOPE_ALWAYS_GLOBAL');
        -
        -#
        -#   Constants: Members
        -#
        -#   The object is implemented as a blessed arrayref, with the following constants as its indexes.
        -#
        -#   NAME - The topic's name.
        -#   PLURAL_NAME - The topic's plural name.
        -#   INDEX - Whether the topic is indexed.
        -#   SCOPE - The topic's <ScopeType>.
        -#   PAGE_TITLE_IF_FIRST - Whether the topic becomes the page title if it's first in a file.
        -#   BREAK_LISTS - Whether list topics should be broken into individual topics in the output.
        -#   CLASS_HIERARCHY - Whether the topic is part of the class hierarchy.
        -#   CAN_GROUP_WITH - The existence hashref of <TopicTypes> the type can be grouped with.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: Types
        -
        -
        -#
        -#   Constants: ScopeType
        -#
        -#   The possible values for <Scope()>.
        -#
        -#   SCOPE_NORMAL - The topic stays in the current scope without affecting it.
        -#   SCOPE_START - The topic starts a scope.
        -#   SCOPE_END - The topic ends a scope, returning it to global.
        -#   SCOPE_ALWAYS_GLOBAL - The topic is always global, but it doesn't affect the current scope.
        -#
        -use constant SCOPE_NORMAL => 1;
        -use constant SCOPE_START => 2;
        -use constant SCOPE_END => 3;
        -use constant SCOPE_ALWAYS_GLOBAL => 4;
        -
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: New
        -#
        -#   Creates and returns a new object.
        -#
        -#   Parameters:
        -#
        -#       name - The topic name.
        -#       pluralName - The topic's plural name.
        -#       index - Whether the topic is indexed.
        -#       scope - The topic's <ScopeType>.
        -#       pageTitleIfFirst - Whether the topic becomes the page title if it's the first one in a file.
        -#       breakLists - Whether list topics should be broken into individual topics in the output.
        -#
        -sub New #(name, pluralName, index, scope, pageTitleIfFirst, breakLists)
        -    {
        -    my ($self, @params) = @_;
        -
        -    # Dependency: Depends on the parameter order matching the member order and that there are no parent classes.
        -
        -    my $object = [ @params ];
        -    bless $object, $self;
        -
        -    return $object;
        -    };
        -
        -
        -#
        -#   Functions: Accessors
        -#
        -#   Name - Returns the topic name.
        -#   PluralName - Returns the topic's plural name.
        -#   SetPluralName - Replaces the topic's plural name.
        -#   Index - Whether the topic is indexed.
        -#   SetIndex - Sets whether the topic is indexed.
        -#   Scope - Returns the topic's <ScopeType>.
        -#   SetScope - Replaces the topic's <ScopeType>.
        -#   PageTitleIfFirst - Returns whether the topic becomes the page title if it's first in the file.
        -#   SetPageTitleIfFirst - Sets whether the topic becomes the page title if it's first in the file.
        -#   BreakLists - Returns whether list topics should be broken into individual topics in the output.
        -#   SetBreakLists - Sets whether list topics should be broken into individual topics in the output.
        -#   ClassHierarchy - Returns whether the topic is part of the class hierarchy.
        -#   SetClassHierarchy - Sets whether the topic is part of the class hierarchy.
        -#
        -
        -
        -#
        -#   Function: CanGroupWith
        -#
        -#   Returns whether the type can be grouped with the passed <TopicType>.
        -#
        -sub CanGroupWith #(TopicType type) -> bool
        -    {
        -    my ($self, $type) = @_;
        -    return ( defined $self->[CAN_GROUP_WITH] && exists $self->[CAN_GROUP_WITH]->{$type} );
        -    };
        -
        -
        -#
        -#   Function: SetCanGroupWith
        -#
        -#   Sets the list of <TopicTypes> the type can be grouped with.
        -#
        -sub SetCanGroupWith #(TopicType[] types)
        -    {
        -    my ($self, $types) = @_;
        -
        -    $self->[CAN_GROUP_WITH] = { };
        -
        -    foreach my $type (@$types)
        -        {  $self->[CAN_GROUP_WITH]->{$type} = 1;  };
        -    };
        -
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/Modules/NaturalDocs/Version.pm b/vendor/naturaldocs/Modules/NaturalDocs/Version.pm
        deleted file mode 100644
        index 27a22ecb8..000000000
        --- a/vendor/naturaldocs/Modules/NaturalDocs/Version.pm
        +++ /dev/null
        @@ -1,361 +0,0 @@
        -###############################################################################
        -#
        -#   Package: NaturalDocs::Version
        -#
        -###############################################################################
        -#
        -#   A package for handling version information.  What?  That's right.  Although it should be easy and obvious, version numbers
        -#   need to be dealt with in a variety of formats, plus there's compatibility with older releases which handled it differently.  I
        -#   wanted to centralize the code after it started getting complicated.  So there ya go.
        -#
        -###############################################################################
        -
        -# This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
        -# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
        -# Refer to License.txt for the complete details
        -
        -use strict;
        -use integer;
        -
        -package NaturalDocs::Version;
        -
        -
        -###############################################################################
        -# Group: Functions
        -
        -
        -#
        -#   Function: ToString
        -#
        -#   Converts a <VersionInt> to a string.
        -#
        -sub ToString #(VersionInt version) => string
        -    {
        -    my ($self, $version) = @_;
        -
        -    my ($major, $minor, $month, $day, $year) = $self->ToValues($version);
        -
        -    if ($minor % 10 == 0)
        -        {  $minor /= 10;  };
        -
        -    if ($day)
        -        {  return sprintf('Development Release %02d-%02d-%d (%d.%d base)', $month, $day, $year, $major, $minor);  }
        -    else
        -        {  return $major . '.' . $minor;  };
        -    };
        -
        -
        -#
        -#   Function: FromString
        -#
        -#   Converts a version string to a <VersionInt>.
        -#
        -sub FromString #(string string) => VersionInt
        -    {
        -    my ($self, $string) = @_;
        -
        -    if ($string eq '1')
        -        {
        -        return $self->FromValues(0, 91, 0, 0, 0);  # 0.91
        -        }
        -    else
        -        {
        -        my ($major, $minor, $month, $day, $year);
        -
        -        if ($string =~ /^(\d{1,2})\.(\d{1,2})$/)
        -            {
        -            ($major, $minor) = ($1, $2);
        -            ($month, $day, $year) = (0, 0, 0);
        -            }
        -        elsif ($string =~ /^Development Release (\d{1,2})-(\d{1,2})-(\d\d\d\d) \((\d{1,2})\.(\d{1,2}) base\)$/)
        -            {
        -            ($month, $day, $year, $major, $minor) = ($1, $2, $3, $4, $5);
        -
        -            # We have to do sanity checking because these can come from user-editable text files.  The version numbers should
        -            # already be constrained simply by being forced to have only two digits.
        -
        -            if ($month > 12 || $month < 1 || $day > 31 || $day < 1 || $year > 2255 || $year < 2000)
        -                {  die 'The version string ' . $string . " doesn't have a valid date.\n";  };
        -            }
        -        else
        -            {
        -            die 'The version string ' . $string . " isn't in a recognized format.\n";
        -            };
        -
        -        if (length $minor == 1)
        -            {  $minor *= 10;  };
        -
        -        return $self->FromValues($major, $minor, $month, $day, $year);
        -        };
        -    };
        -
        -
        -#
        -#   Function: ToTextFile
        -#
        -#   Writes a <VersionInt> to a text file.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The handle of the file to write it to.  It should be at the correct location.
        -#       version - The <VersionInt> to write.
        -#
        -sub ToTextFile #(handle fileHandle, VersionInt version)
        -    {
        -    my ($self, $fileHandle, $version) = @_;
        -
        -    print $fileHandle $self->ToString($version) . "\n";
        -    };
        -
        -
        -#
        -#   Function: ToBinaryFile
        -#
        -#   Writes a <VersionInt> to a binary file.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The handle of the file to write it to.  It should be at the correct location.
        -#       version - The <VersionInt> to write.
        -#
        -sub ToBinaryFile #(handle fileHandle, VersionInt version)
        -    {
        -    my ($self, $fileHandle, $version) = @_;
        -
        -    my ($major, $minor, $month, $day, $year) = $self->ToValues($version);
        -
        -    # 1.35 development releases are encoded as 1.36.  Everything else is literal.
        -    if ($day && $major == 1 && $minor == 35)
        -        {  $minor = 36;  };
        -
        -    print $fileHandle pack('CC', $major, $minor);
        -
        -    # Date fields didn't exist with 1.35 stable and earlier.  1.35 development releases are encoded as 1.36, so this works.
        -    if ($major > 1 || ($major == 1 && $minor > 35))
        -        {
        -        if ($day)
        -            {  $year -= 2000;  };
        -
        -        print $fileHandle pack('CCC', $month, $day, $year);
        -        };
        -    };
        -
        -
        -#
        -#   Function: FromBinaryFile
        -#
        -#   Retrieves a <VersionInt> from a binary file.
        -#
        -#   Parameters:
        -#
        -#       fileHandle - The handle of the file to read it from.  It should be at the correct location.
        -#
        -#   Returns:
        -#
        -#       The <VersionInt>.
        -#
        -sub FromBinaryFile #(handle fileHandle) => VersionInt
        -    {
        -    my ($self, $fileHandle) = @_;
        -
        -    my ($major, $minor, $month, $day, $year);
        -
        -    my $raw;
        -    read($fileHandle, $raw, 2);
        -
        -    ($major, $minor) = unpack('CC', $raw);
        -
        -    # 1.35 stable is the last release without the date fields.  1.35 development releases are encoded as 1.36, so this works.
        -    if ($major > 1 || ($major == 1 && $minor > 35))
        -        {
        -        read($fileHandle, $raw, 3);
        -        ($month, $day, $year) = unpack('CCC', $raw);
        -
        -        if ($day)
        -            {  $year += 2000;  };
        -        }
        -    else
        -        {  ($month, $day, $year) = (0, 0, 0);  };
        -
        -    # Fix the 1.35 development release special encoding.
        -    if ($major == 1 && $minor == 36)
        -        {  $minor = 35;  };
        -
        -
        -    return $self->FromValues($major, $minor, $month, $day, $year);
        -    };
        -
        -
        -#
        -#   Function: ToValues
        -#
        -#   Converts a <VersionInt> to the array ( major, minor, month, day, year ).  The minor version will be in two digit form, so x.2
        -#   will return 20.  The date fields will be zero for stable releases.
        -#
        -sub ToValues #(VersionInt version) => ( int, int, int, int, int )
        -    {
        -    my ($self, $version) = @_;
        -
        -    my $major = ($version & 0x00003F80) >> 7;
        -    my $minor = ($version & 0x0000007F);
        -    my $month = ($version & 0x00780000) >> 19;
        -    my $day = ($version & 0x0007C000) >> 14;
        -    my $year = ($version & 0x7F800000) >> 23;
        -
        -    if ($year)
        -        {  $year += 2000;  };
        -
        -    return ( $major, $minor, $month, $day, $year );
        -    };
        -
        -
        -#
        -#   Function: FromValues
        -#
        -#   Returns a <VersionInt> created from the passed values.
        -#
        -#   Parameters:
        -#
        -#       major - The major version number.  For development releases, it should be the stable version it's based off of.
        -#       minor - The minor version number.  It should always be two digits, so x.2 should pass 20.  For development
        -#                  releases, it should be the stable version it's based off of.
        -#       month - The numeric month of the development release.  For stable releases it should be zero.
        -#       day - The day of the development release.  For stable releases it should be zero.
        -#       year - The year of the development release.  For stable releases it should be zero.
        -#
        -#   Returns:
        -#
        -#       The <VersionInt>.
        -#
        -sub FromValues #(int major, int minor, int month, int day, int year) => VersionInt
        -    {
        -    my ($self, $major, $minor, $month, $day, $year) = @_;
        -
        -    if ($day)
        -        {  $year -= 2000;  };
        -
        -    return ($major << 7) + ($minor) + ($month << 19) + ($day << 14) + ($year << 23);
        -    };
        -
        -
        -#
        -#   Function: CheckFileFormat
        -#
        -#   Checks if a file's format is compatible with the current release.
        -#
        -#   - If the application is a development release or the file is from one, this only returns true if they are from the exact same
        -#     development release.
        -#   - If neither of them are development releases, this only returns true if the file is from a release between the minimum specified
        -#     and the current version.  If there's no minimum it just checks that it's below the current version.
        -#
        -#   Parameters:
        -#
        -#       fileVersion - The <VersionInt> of the file format.
        -#       minimumVersion - The minimum <VersionInt> required of the file format.  May be undef.
        -#
        -#   Returns:
        -#
        -#       Whether the file's format is compatible per the above rules.
        -#
        -sub CheckFileFormat #(VersionInt fileVersion, optional VersionInt minimumVersion) => bool
        -    {
        -    my ($self, $fileVersion, $minimumVersion) = @_;
        -
        -    my $appVersion = NaturalDocs::Settings->AppVersion();
        -
        -    if ($self->IsDevelopmentRelease($appVersion) || $self->IsDevelopmentRelease($fileVersion))
        -        {  return ($appVersion == $fileVersion);  }
        -    elsif ($minimumVersion && $fileVersion < $minimumVersion)
        -        {  return 0;  }
        -    else
        -        {  return ($fileVersion <= $appVersion);  };
        -    };
        -
        -
        -#
        -#   Function: IsDevelopmentRelease
        -#
        -#   Returns whether the passed <VersionInt> is for a development release.
        -#
        -sub IsDevelopmentRelease #(VersionInt version) => bool
        -    {
        -    my ($self, $version) = @_;
        -
        -    # Return if any of the date fields are set.
        -    return ($version & 0x7FFFC000);
        -    };
        -
        -
        -
        -###############################################################################
        -# Group: Implementation
        -
        -#
        -#   About: String Format
        -#
        -#   Full Releases:
        -#
        -#       Full releases are in the common major.minor format.  Either part can be up to two digits.  The minor version is interpreted
        -#       as decimal places, so 1.3 > 1.22.  There are no leading or trailing zeroes.
        -#
        -#   Development Releases:
        -#
        -#       Development releases are in the format "Development Release mm-dd-yyyy (vv.vv base)" where vv.vv is the version
        -#       number of the full release it's based off of.  The month and day will have leading zeroes where applicable.  Example:
        -#       "Development Release 07-09-2006 (1.35 base)".
        -#
        -#   0.91 and Earlier:
        -#
        -#       Text files from releases prior to 0.95 had a separate file format version number that was used instead of the application
        -#       version.  These were never changed between 0.85 and 0.91, so they are simply "1".  Text version numbers that are "1"
        -#       instead of "1.0" will be interpreted as 0.91.
        -#
        -
        -#
        -#   About: Integer Format
        -#
        -#   <VersionInts> are 32-bit values with the bit distribution below.
        -#
        -#   > s yyyyyyyy mmmm ddddd vvvvvvv xxxxxxx
        -#   > [syyy|yyyy] [ymmm|mddd] [ddvv|vvvv] [vxxx|xxxx]
        -#
        -#   s - The sign bit.  Always zero, so it's always interpreted as positive.
        -#   y - The year bits if it's a development release, zero otherwise.  2000 is added to the value, so the range is from 2000 to 2255.
        -#   m - The month bits if it's a development release, zero otherwise.
        -#   d - The day bits if it's a development release, zero otherwise.
        -#   v - The major version bits.  For development releases, it's the last stable version it was based off of.
        -#   x - The minor version bits.  It's always stored as two decimals, so x.2 would store 20 here.  For development releases, it's the
        -#        last stable version it was based off of.
        -#
        -#   It's stored with the development release date at a higher significance than the version because we want a stable release to
        -#   always treat a development release as higher than itself, and thus not attempt to read any of the data files.  I'm not tracking
        -#   data file formats at the development release level.
        -#
        -
        -#
        -#   About: Binary File Format
        -#
        -#   Current:
        -#
        -#       Five 8-bit unsigned values, appearing major, minor, month, day, year.  Minor is always stored with two digits, so x.2 would
        -#       store 20.  Year is stored minus 2000, so 2006 is stored 6.  Stable releases store zero for all the date fields.
        -#
        -#   1.35 Development Releases:
        -#
        -#       1.35-based development releases are stored the same as current releases, but with 1.36 as the version number.  This is
        -#       done so previous versions of Natural Docs that didn't include the date fields would still know it's a higher version.  There is
        -#       no actual 1.36 release.
        -#
        -#   1.35 and Earlier:
        -#
        -#       Two 8-bit unsigned values, appearing major then minor.  Minor is always stored with two digits, so x.2 would store 20.
        -#
        -
        -#
        -#   About: Text File Format
        -#
        -#   In text files, versions are the <String Format> followed by a native line break.
        -#
        -
        -
        -1;
        diff --git a/vendor/naturaldocs/NaturalDocs b/vendor/naturaldocs/NaturalDocs
        deleted file mode 100755
        index 1d523d6bf..000000000
        --- a/vendor/naturaldocs/NaturalDocs
        +++ /dev/null
        @@ -1,367 +0,0 @@
        -#!/usr/bin/perl
        -
        -=begin nd
        -
        -    Script: NaturalDocs
        -    ___________________________________________________________________________
        -
        -    Version 1.51
        -
        -    Copyright © 2003-2010 Greg Valure
        -
        -    http://www.naturaldocs.org
        -
        -	Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL).  Refer to the <License> for the
        -	complete details.
        -
        -
        -    Topic: Code Conventions
        -
        -        - Every package function is called with an arrow operator.  It's needed for inheritance in some places, and consistency
        -         when it's not.
        -
        -        - No constant will ever be zero or undef.  Those are reserved so any piece of code can allow a "none of the above" option
        -         and not worry about conflicts with an existing value.
        -
        -        - Existence hashes are hashes where the value doesn't matter.  It acts more as a set, where the existence of the key is
        -         the significant part.
        -
        -
        -    Topic: File Format Conventions
        -
        -        - All integers appear in big-endian format.  So a UInt16 should be handled with a 'n' in pack and unpack, not with a 'S'.
        -
        -        - AString16's are a big-endian UInt16 followed by that many ASCII characters.  A null-terminator is not stored.
        -
        -        - If a higher-level type is described in a file format, that means the loading and saving format is handled by that package.
        -         For example, if you see <SymbolString> in the format, that means <NaturalDocs::SymbolString->ToBinaryFile()> and
        -         <NaturalDocs::SymbolString->FromBinaryFile()> are used to manipulate it, and the underlying format should be treated
        -         as opaque.
        -
        -=cut
        -
        -
        -use strict;
        -use integer;
        -
        -use 5.008;  # When :encoding modifiers were allowed with file access.
        -
        -use English '-no_match_vars';
        -
        -use FindBin;
        -use lib "$FindBin::RealBin/Modules";
        -
        -sub INIT
        -    {
        -    # This function is just here so that when I start the debugger, it doesn't open a new file.  Normally it would jump to an INIT
        -    # function in some other file since that's the first piece of code to execute.
        -    };
        -
        -
        -use NaturalDocs::Constants;
        -use NaturalDocs::Version;
        -use NaturalDocs::File;
        -use NaturalDocs::Error;
        -
        -use NaturalDocs::LineReader;
        -use NaturalDocs::ConfigFile;
        -use NaturalDocs::BinaryFile;
        -use NaturalDocs::StatusMessage;
        -use NaturalDocs::SymbolString;
        -use NaturalDocs::ReferenceString;
        -use NaturalDocs::NDMarkup;
        -
        -use NaturalDocs::Settings;
        -use NaturalDocs::Topics;
        -use NaturalDocs::Languages;
        -use NaturalDocs::Project;
        -use NaturalDocs::Menu;
        -use NaturalDocs::SymbolTable;
        -use NaturalDocs::ClassHierarchy;
        -use NaturalDocs::SourceDB;
        -use NaturalDocs::ImageReferenceTable;
        -use NaturalDocs::Parser;
        -use NaturalDocs::Builder;
        -
        -
        -
        -###############################################################################
        -#
        -#   Group: Basic Types
        -#
        -#   Types used throughout the program.  As Perl is a weakly-typed language unless you box things into objects, these types are
        -#   for documentation purposes and are not enforced.
        -#
        -#
        -#   Type: FileName
        -#
        -#   A string representing the absolute, platform-dependent path to a file.  Relative file paths are no longer in use anywhere in the
        -#   program.  All path manipulation should be done through <NaturalDocs::File>.
        -#
        -#
        -#   Type: VersionInt
        -#
        -#   A comparable integer representing a version number.  Converting them to and from text and binary should be handled by
        -#   <NaturalDocs::Version>.
        -#
        -#
        -#   Type: SymbolString
        -#
        -#   A scalar which encodes a normalized array of identifier strings representing a full or partially-resolved symbol.  All symbols
        -#   must be retrieved from plain text via <NaturalDocs::SymbolString->FromText()> so that the separation and normalization is
        -#   always consistent.  SymbolStrings are comparable via string compare functions and are sortable.
        -#
        -#
        -#   Type: ReferenceString
        -#
        -#   All the information about a reference that makes it unique encoded into a string.  This includes the <SymbolString> of the
        -#   reference, the scope <SymbolString> it appears in, the scope <SymbolStrings> it has access to via "using", and the
        -#   <ReferenceType>.  This is done because if any of those parameters change, it needs to be treated as a completely separate
        -#   reference.
        -#
        -
        -
        -
        -###############################################################################
        -# Group: Support Functions
        -# General functions that are used throughout the program, and that don't really fit anywhere else.
        -
        -
        -#
        -#   Function: StringCompare
        -#
        -#   Compares two strings so that the result is good for proper sorting.  A proper sort orders the characters as
        -#   follows:
        -#
        -#   - End of string.
        -#   - Whitespace.  Line break-tab-space.
        -#   - Symbols, which is anything not included in the other entries.
        -#   - Numbers, 0-9.
        -#   - Letters, case insensitive except to break ties.
        -#
        -#   If you use cmp instead of this function, the result would go by ASCII/Unicode values which would place certain symbols
        -#   between letters and numbers instead of having them all grouped together.  Also, you would have to choose between case
        -#   sensitivity or complete case insensitivity, in which ties are broken arbitrarily.
        -#
        -#   Returns:
        -#
        -#   Like cmp, it returns zero if A and B are equal, a positive value if A is greater than B, and a negative value if A is less than B.
        -#
        -sub StringCompare #(a, b)
        -    {
        -    my ($a, $b) = @_;
        -
        -    if (!defined $a)
        -        {
        -        if (!defined $b)
        -            {  return 0;  }
        -        else
        -            {  return -1;  };
        -        }
        -    elsif (!defined $b)
        -        {
        -        return 1;
        -        };
        -
        -    my $translatedA = lc($a);
        -    my $translatedB = lc($b);
        -
        -    $translatedA =~ tr/\n\r\t 0-9a-z/\x01\x02\x03\x04\xDB-\xFE/;
        -    $translatedB =~ tr/\n\r\t 0-9a-z/\x01\x02\x03\x04\xDB-\xFE/;
        -
        -    my $result = $translatedA cmp $translatedB;
        -
        -    if ($result == 0)
        -        {
        -        # Break the tie by comparing their case.  Lowercase before uppercase.
        -
        -        # If statement just to keep everything theoretically kosher, even though in practice we don't need this.
        -        if (ord('A') > ord('a'))
        -            {  return ($a cmp $b);  }
        -        else
        -            {  return ($b cmp $a);  };
        -        }
        -    else
        -        {  return $result;  };
        -    };
        -
        -
        -#
        -#   Function: ShortenToMatchStrings
        -#
        -#   Compares two arrayrefs and shortens the first array to only contain shared entries.  Assumes all entries are strings.
        -#
        -#   Parameters:
        -#
        -#       sharedArrayRef - The arrayref that will be shortened to only contain common elements.
        -#       compareArrayRef - The arrayref to match.
        -#
        -sub ShortenToMatchStrings #(sharedArrayRef, compareArrayRef)
        -    {
        -    my ($sharedArrayRef, $compareArrayRef) = @_;
        -
        -    my $index = 0;
        -
        -    while ($index < scalar @$sharedArrayRef && $index < scalar @$compareArrayRef &&
        -             $sharedArrayRef->[$index] eq $compareArrayRef->[$index])
        -        {  $index++;  };
        -
        -    if ($index < scalar @$sharedArrayRef)
        -        {  splice(@$sharedArrayRef, $index);  };
        -    };
        -
        -
        -#
        -#   Function: FindFirstSymbol
        -#
        -#   Searches a string for a number of symbols to see which appears first.
        -#
        -#   Parameters:
        -#
        -#       string - The string to search.
        -#       symbols - An arrayref of symbols to look for.
        -#       index - The index to start at, if any.
        -#
        -#   Returns:
        -#
        -#       The array ( index, symbol ).
        -#
        -#       index - The index the first symbol appears at, or -1 if none appear.
        -#       symbol - The symbol that appeared, or undef if none.
        -#
        -sub FindFirstSymbol #(string, symbols, index)
        -    {
        -    my ($string, $symbols, $index) = @_;
        -
        -    if (!defined $index)
        -        {  $index = 0;  };
        -
        -    my $lowestIndex = -1;
        -    my $lowestSymbol;
        -
        -    foreach my $symbol (@$symbols)
        -        {
        -        my $testIndex = index($string, $symbol, $index);
        -
        -        if ($testIndex != -1 && ($lowestIndex == -1 || $testIndex < $lowestIndex))
        -            {
        -            $lowestIndex = $testIndex;
        -            $lowestSymbol = $symbol;
        -            };
        -        };
        -
        -    return ($lowestIndex, $lowestSymbol);
        -    };
        -
        -
        -
        -
        -###############################################################################
        -#
        -#   Main Code
        -#
        -#   The order in which functions are called here is critically important.  Read the "Usage and Dependencies" sections of all the
        -#   packages before even thinking about rearranging these.
        -#
        -
        -
        -eval {
        -
        -    # Check that our required packages are okay.
        -
        -    NaturalDocs::File->CheckCompatibility();
        -
        -
        -    # Almost everything requires Settings to be initialized.
        -
        -    NaturalDocs::Settings->Load();
        -
        -
        -    NaturalDocs::Project->LoadConfigFileInfo();
        -
        -    NaturalDocs::Topics->Load();
        -    NaturalDocs::Languages->Load();
        -
        -
        -    # Migrate from the old file names that were used prior to 1.14.
        -
        -    NaturalDocs::Project->MigrateOldFiles();
        -
        -
        -    if (!NaturalDocs::Settings->IsQuiet())
        -        {  print "Finding files and detecting changes...\n";  };
        -
        -    NaturalDocs::Project->LoadSourceFileInfo();
        -    NaturalDocs::Project->LoadImageFileInfo();
        -
        -    # Register SourceDB extensions.  Order is important.
        -    NaturalDocs::ImageReferenceTable->Register();
        -
        -    NaturalDocs::SymbolTable->Load();
        -    NaturalDocs::ClassHierarchy->Load();
        -    NaturalDocs::SourceDB->Load();
        -
        -    NaturalDocs::SymbolTable->Purge();
        -    NaturalDocs::ClassHierarchy->Purge();
        -    NaturalDocs::SourceDB->PurgeDeletedSourceFiles();
        -
        -
        -    # Parse any supported files that have changed.
        -
        -    my $filesToParse = NaturalDocs::Project->FilesToParse();
        -    my $amount = scalar keys %$filesToParse;
        -
        -    if ($amount > 0)
        -        {
        -        NaturalDocs::StatusMessage->Start('Parsing ' . $amount . ' file' . ($amount > 1 ? 's' : '') . '...', $amount);
        -
        -        foreach my $file (keys %$filesToParse)
        -            {
        -            NaturalDocs::Parser->ParseForInformation($file);
        -            NaturalDocs::StatusMessage->CompletedItem();
        -            };
        -        };
        -
        -
        -    # The symbol table is now fully resolved, so we can reduce its memory footprint.
        -
        -    NaturalDocs::SymbolTable->PurgeResolvingInfo();
        -
        -
        -    # Load and update the menu file.  We need to do this after parsing so when it is updated, it will detect files where the
        -    # default menu title has changed and files that have added or deleted Natural Docs content.
        -
        -    NaturalDocs::Menu->LoadAndUpdate();
        -
        -
        -    # Build any files that need it.  This needs to be run regardless of whether there are any files to build.  It will handle its own
        -    # output messages.
        -
        -    NaturalDocs::Builder->Run();
        -
        -
        -    # Write the changes back to disk.
        -
        -    NaturalDocs::Menu->Save();
        -    NaturalDocs::Project->SaveImageFileInfo();
        -    NaturalDocs::Project->SaveSourceFileInfo();
        -    NaturalDocs::SymbolTable->Save();
        -    NaturalDocs::ClassHierarchy->Save();
        -    NaturalDocs::SourceDB->Save();
        -    NaturalDocs::Settings->Save();
        -    NaturalDocs::Topics->Save();
        -    NaturalDocs::Languages->Save();
        -
        -    # Must be done last.
        -    NaturalDocs::Project->SaveConfigFileInfo();
        -
        -    if (!NaturalDocs::Settings->IsQuiet())
        -        {  print "Done.\n";  };
        -
        -};
        -
        -if ($EVAL_ERROR)  # Oops.
        -    {
        -    NaturalDocs::Error->HandleDeath();
        -    };
        -
        diff --git a/vendor/naturaldocs/NaturalDocs.bat b/vendor/naturaldocs/NaturalDocs.bat
        deleted file mode 100644
        index 59e396319..000000000
        --- a/vendor/naturaldocs/NaturalDocs.bat
        +++ /dev/null
        @@ -1,17 +0,0 @@
        -@echo off
        -
        -set NaturalDocsParams=
        -
        -rem Shift and loop so we can get more than nine parameters.
        -rem This is especially important if we have spaces in file names.
        -
        -:MORE
        -if "%1"=="" goto NOMORE
        -set NaturalDocsParams=%NaturalDocsParams% %1
        -shift
        -goto MORE
        -:NOMORE
        -
        -perl NaturalDocs %NaturalDocsParams%
        -
        -set NaturalDocsParams=
        \ No newline at end of file
        diff --git a/vendor/naturaldocs/Styles/Default.css b/vendor/naturaldocs/Styles/Default.css
        deleted file mode 100644
        index 511703fc4..000000000
        --- a/vendor/naturaldocs/Styles/Default.css
        +++ /dev/null
        @@ -1,828 +0,0 @@
        -/*
        -   IMPORTANT: If you're editing this file in the output directory of one of
        -   your projects, your changes will be overwritten the next time you run
        -   Natural Docs.  Instead, copy this file to your project directory, make your
        -   changes, and you can use it with -s.  Even better would be to make a CSS
        -   file in your project directory with only your changes, which you can then
        -   use with -s [original style] [your changes].
        -
        -   On the other hand, if you're editing this file in the Natural Docs styles
        -   directory, the changes will automatically be applied to all your projects
        -   that use this style the next time Natural Docs is run on them.
        -
        -   This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure.
        -   Natural Docs is licensed under version 3 of the GNU Affero General Public
        -   License (AGPL).  Refer to License.txt for the complete details.
        -
        -   This file may be distributed with documentation files generated by Natural Docs.
        -   Such documentation is not covered by Natural Docs' copyright and licensing,
        -   and may have its own copyright and distribution terms as decided by its author.
        -*/
        -
        -body {
        -    font: 10pt Verdana, Arial, sans-serif;
        -    color: #000000;
        -    margin: 0; padding: 0;
        -    }
        -
        -.ContentPage,
        -.IndexPage,
        -.FramedMenuPage {
        -    background-color: #E8E8E8;
        -    }
        -.FramedContentPage,
        -.FramedIndexPage,
        -.FramedSearchResultsPage,
        -.PopupSearchResultsPage {
        -    background-color: #FFFFFF;
        -    }
        -
        -
        -a:link,
        -a:visited { color: #900000; text-decoration: none }
        -a:hover { color: #900000; text-decoration: underline }
        -a:active { color: #FF0000; text-decoration: underline }
        -
        -td {
        -    vertical-align: top }
        -
        -img { border: 0;  }
        -
        -
        -/*
        -    Comment out this line to use web-style paragraphs (blank line between
        -    paragraphs, no indent) instead of print-style paragraphs (no blank line,
        -    indented.)
        -*/
        -p {
        -    text-indent: 5ex; margin: 0 }
        -
        -
        -/*  Opera doesn't break with just wbr, but will if you add this.  */
        -.Opera wbr:after {
        -	content: "\00200B";
        -	}
        -
        -
        -/*  Blockquotes are used as containers for things that may need to scroll.  */
        -blockquote {
        -    padding: 0;
        -    margin: 0;
        -    overflow: auto;
        -    }
        -
        -
        -.Firefox1 blockquote {
        -    padding-bottom: .5em;
        -    }
        -
        -/*  Turn off scrolling when printing.  */
        -@media print {
        -    blockquote {
        -        overflow: visible;
        -        }
        -    .IE blockquote {
        -        width: auto;
        -        }
        -    }
        -
        -
        -
        -#Menu {
        -    font-size: 9pt;
        -    padding: 10px 0 0 0;
        -    }
        -.ContentPage #Menu,
        -.IndexPage #Menu {
        -    position: absolute;
        -    top: 0;
        -    left: 0;
        -    width: 31ex;
        -    overflow: hidden;
        -    }
        -.ContentPage .Firefox #Menu,
        -.IndexPage .Firefox #Menu {
        -    width: 27ex;
        -    }
        -
        -
        -    .MTitle {
        -        font-size: 16pt; font-weight: bold; font-variant: small-caps;
        -        text-align: center;
        -        padding: 5px 10px 15px 10px;
        -        border-bottom: 1px dotted #000000;
        -        margin-bottom: 15px }
        -
        -    .MSubTitle {
        -        font-size: 9pt; font-weight: normal; font-variant: normal;
        -        margin-top: 1ex; margin-bottom: 5px }
        -
        -
        -    .MEntry a:link,
        -    .MEntry a:hover,
        -    .MEntry a:visited { color: #606060; margin-right: 0 }
        -    .MEntry a:active { color: #A00000; margin-right: 0 }
        -
        -
        -    .MGroup {
        -        font-variant: small-caps; font-weight: bold;
        -        margin: 1em 0 1em 10px;
        -        }
        -
        -    .MGroupContent {
        -        font-variant: normal; font-weight: normal }
        -
        -    .MGroup a:link,
        -    .MGroup a:hover,
        -    .MGroup a:visited { color: #545454; margin-right: 10px }
        -    .MGroup a:active { color: #A00000; margin-right: 10px }
        -
        -
        -    .MFile,
        -    .MText,
        -    .MLink,
        -    .MIndex {
        -        padding: 1px 17px 2px 10px;
        -        margin: .25em 0 .25em 0;
        -        }
        -
        -    .MText {
        -        font-size: 8pt; font-style: italic }
        -
        -    .MLink {
        -        font-style: italic }
        -
        -    #MSelected {
        -        color: #000000; background-color: #FFFFFF;
        -        /*  Replace padding with border.  */
        -        padding: 0 10px 0 10px;
        -        border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000;
        -        margin-right: 5px;
        -        }
        -
        -    /*  Close off the left side when its in a group.  */
        -    .MGroup #MSelected {
        -        padding-left: 9px; border-left-width: 1px }
        -
        -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
        -    .Firefox #MSelected {
        -        -moz-border-radius-topright: 10px;
        -        -moz-border-radius-bottomright: 10px }
        -    .Firefox .MGroup #MSelected {
        -        -moz-border-radius-topleft: 10px;
        -        -moz-border-radius-bottomleft: 10px }
        -
        -
        -    #MSearchPanel {
        -        padding: 0px 6px;
        -        margin: .25em 0;
        -        }
        -
        -
        -    #MSearchField {
        -        font: italic 9pt Verdana, sans-serif;
        -        color: #606060;
        -        background-color: #E8E8E8;
        -        border: none;
        -        padding: 2px 4px;
        -        width: 100%;
        -        }
        -    /* Only Opera gets it right. */
        -    .Firefox #MSearchField,
        -    .IE #MSearchField,
        -    .Safari #MSearchField {
        -        width: 94%;
        -        }
        -    .Opera9 #MSearchField,
        -    .Konqueror #MSearchField {
        -        width: 97%;
        -        }
        -    .FramedMenuPage .Firefox #MSearchField,
        -    .FramedMenuPage .Safari #MSearchField,
        -    .FramedMenuPage .Konqueror #MSearchField {
        -        width: 98%;
        -        }
        -
        -    /* Firefox doesn't do this right in frames without #MSearchPanel added on.
        -        It's presence doesn't hurt anything other browsers. */
        -    #MSearchPanel.MSearchPanelInactive:hover #MSearchField {
        -        background-color: #FFFFFF;
        -        border: 1px solid #C0C0C0;
        -        padding: 1px 3px;
        -        }
        -    .MSearchPanelActive #MSearchField {
        -        background-color: #FFFFFF;
        -        border: 1px solid #C0C0C0;
        -        font-style: normal;
        -        padding: 1px 3px;
        -        }
        -
        -    #MSearchType {
        -        visibility: hidden;
        -        font: 8pt Verdana, sans-serif;
        -        width: 98%;
        -        padding: 0;
        -        border: 1px solid #C0C0C0;
        -        }
        -    .MSearchPanelActive #MSearchType,
        -    /*  As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */
        -    #MSearchPanel.MSearchPanelInactive:hover #MSearchType,
        -    #MSearchType:focus {
        -        visibility: visible;
        -        color: #606060;
        -        }
        -    #MSearchType option#MSearchEverything {
        -        font-weight: bold;
        -        }
        -
        -    .Opera8 .MSearchPanelInactive:hover,
        -    .Opera8 .MSearchPanelActive {
        -        margin-left: -1px;
        -        }
        -
        -
        -    iframe#MSearchResults {
        -        width: 60ex;
        -        height: 15em;
        -        }
        -    #MSearchResultsWindow {
        -        display: none;
        -        position: absolute;
        -        left: 0; top: 0;
        -        border: 1px solid #000000;
        -        background-color: #E8E8E8;
        -        }
        -    #MSearchResultsWindowClose {
        -        font-weight: bold;
        -        font-size: 8pt;
        -        display: block;
        -        padding: 2px 5px;
        -        }
        -    #MSearchResultsWindowClose:link,
        -    #MSearchResultsWindowClose:visited {
        -        color: #000000;
        -        text-decoration: none;
        -        }
        -    #MSearchResultsWindowClose:active,
        -    #MSearchResultsWindowClose:hover {
        -        color: #800000;
        -        text-decoration: none;
        -        background-color: #F4F4F4;
        -        }
        -
        -
        -
        -
        -#Content {
        -    padding-bottom: 15px;
        -    }
        -
        -.ContentPage #Content {
        -    border-width: 0 0 1px 1px;
        -    border-style: solid;
        -    border-color: #000000;
        -    background-color: #FFFFFF;
        -    font-size: 9pt;  /* To make 31ex match the menu's 31ex. */
        -    margin-left: 31ex;
        -    }
        -.ContentPage .Firefox #Content {
        -    margin-left: 27ex;
        -    }
        -
        -
        -
        -    .CTopic {
        -        font-size: 10pt;
        -        margin-bottom: 3em;
        -        }
        -
        -
        -    .CTitle {
        -        font-size: 12pt; font-weight: bold;
        -        border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0;
        -        margin: 0 15px .5em 15px }
        -
        -    .CGroup .CTitle {
        -        font-size: 16pt; font-variant: small-caps;
        -        padding-left: 15px; padding-right: 15px;
        -        border-width: 0 0 2px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    .CClass .CTitle,
        -    .CInterface .CTitle,
        -    .CDatabase .CTitle,
        -    .CDatabaseTable .CTitle,
        -    .CSection .CTitle {
        -        font-size: 18pt;
        -        color: #FFFFFF; background-color: #A0A0A0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 2px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    #MainTopic .CTitle {
        -        font-size: 20pt;
        -        color: #FFFFFF; background-color: #7070C0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 0 0 3px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    .CBody {
        -        margin-left: 15px; margin-right: 15px }
        -
        -
        -    .CToolTip {
        -        position: absolute; visibility: hidden;
        -        left: 0; top: 0;
        -        background-color: #FFFFE0;
        -        padding: 5px;
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000;
        -        font-size: 8pt;
        -        }
        -
        -    .Opera .CToolTip {
        -        max-width: 98%;
        -        }
        -
        -    /*  Scrollbars would be useless.  */
        -    .CToolTip blockquote {
        -        overflow: hidden;
        -        }
        -    .IE6 .CToolTip blockquote {
        -        overflow: visible;
        -        }
        -
        -    .CHeading {
        -        font-weight: bold; font-size: 10pt;
        -        margin: 1.5em 0 .5em 0;
        -        }
        -
        -    .CBody pre {
        -        font: 10pt "Courier New", Courier, monospace;
        -	    background-color: #FCFCFC;
        -	    margin: 1em 35px;
        -	    padding: 10px 15px 10px 10px;
        -	    border-color: #E0E0E0 #E0E0E0 #E0E0E0 #E4E4E4;
        -	    border-width: 1px 1px 1px 6px;
        -	    border-style: dashed dashed dashed solid;
        -        }
        -
        -    .CBody ul {
        -        /*  I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever.
        -             Reapply it here as padding.  */
        -        padding-left: 15px; padding-right: 15px;
        -        margin: .5em 5ex .5em 5ex;
        -        }
        -
        -    .CDescriptionList {
        -        margin: .5em 5ex 0 5ex }
        -
        -        .CDLEntry {
        -            font: 10pt "Courier New", Courier, monospace; color: #808080;
        -            padding-bottom: .25em;
        -            white-space: nowrap }
        -
        -        .CDLDescription {
        -            font-size: 10pt;  /*  For browsers that don't inherit correctly, like Opera 5.  */
        -            padding-bottom: .5em; padding-left: 5ex }
        -
        -
        -    .CTopic img {
        -        text-align: center;
        -        display: block;
        -        margin: 1em auto;
        -        }
        -    .CImageCaption {
        -        font-variant: small-caps;
        -        font-size: 8pt;
        -        color: #808080;
        -        text-align: center;
        -        position: relative;
        -        top: 1em;
        -        }
        -
        -    .CImageLink {
        -        color: #808080;
        -        font-style: italic;
        -        }
        -    a.CImageLink:link,
        -    a.CImageLink:visited,
        -    a.CImageLink:hover { color: #808080 }
        -
        -
        -
        -
        -
        -.Prototype {
        -    font: 10pt "Courier New", Courier, monospace;
        -    padding: 5px 3ex;
        -    border-width: 1px; border-style: solid;
        -    margin: 0 5ex 1.5em 5ex;
        -    }
        -
        -    .Prototype td {
        -        font-size: 10pt;
        -        }
        -
        -    .PDefaultValue,
        -    .PDefaultValuePrefix,
        -    .PTypePrefix {
        -        color: #8F8F8F;
        -        }
        -    .PTypePrefix {
        -        text-align: right;
        -        }
        -    .PAfterParameters {
        -        vertical-align: bottom;
        -        }
        -
        -    .IE .Prototype table {
        -        padding: 0;
        -        }
        -
        -    .CFunction .Prototype {
        -        background-color: #F4F4F4; border-color: #D0D0D0 }
        -    .CProperty .Prototype {
        -        background-color: #F4F4FF; border-color: #C0C0E8 }
        -    .CVariable .Prototype {
        -        background-color: #FFFFF0; border-color: #E0E0A0 }
        -
        -    .CClass .Prototype {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
        -        background-color: #F4F4F4;
        -        }
        -    .CInterface .Prototype {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0;
        -        background-color: #F4F4FF;
        -        }
        -
        -    .CDatabaseIndex .Prototype,
        -    .CConstant .Prototype {
        -        background-color: #D0D0D0; border-color: #000000 }
        -    .CType .Prototype,
        -    .CEnumeration .Prototype {
        -        background-color: #FAF0F0; border-color: #E0B0B0;
        -        }
        -    .CDatabaseTrigger .Prototype,
        -    .CEvent .Prototype,
        -    .CDelegate .Prototype {
        -        background-color: #F0FCF0; border-color: #B8E4B8 }
        -
        -    .CToolTip .Prototype {
        -        margin: 0 0 .5em 0;
        -        white-space: nowrap;
        -        }
        -
        -
        -
        -
        -
        -.Summary {
        -    margin: 1.5em 5ex 0 5ex }
        -
        -    .STitle {
        -        font-size: 12pt; font-weight: bold;
        -        margin-bottom: .5em }
        -
        -
        -    .SBorder {
        -        background-color: #FFFFF0;
        -        padding: 15px;
        -        border: 1px solid #C0C060 }
        -
        -    /* In a frame IE 6 will make them too long unless you set the width to 100%.  Without frames it will be correct without a width
        -        or slightly too long (but not enough to scroll) with a width.  This arbitrary weirdness simply astounds me.  IE 7 has the same
        -        problem with frames, haven't tested it without.  */
        -    .FramedContentPage .IE .SBorder {
        -        width: 100% }
        -
        -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
        -    .Firefox .SBorder {
        -        -moz-border-radius: 20px }
        -
        -
        -    .STable {
        -        font-size: 9pt; width: 100% }
        -
        -    .SEntry {
        -        width: 30% }
        -    .SDescription {
        -        width: 70% }
        -
        -
        -    .SMarked {
        -        background-color: #F8F8D8 }
        -
        -    .SDescription { padding-left: 2ex }
        -    .SIndent1 .SEntry { padding-left: 1.5ex }   .SIndent1 .SDescription { padding-left: 3.5ex }
        -    .SIndent2 .SEntry { padding-left: 3.0ex }   .SIndent2 .SDescription { padding-left: 5.0ex }
        -    .SIndent3 .SEntry { padding-left: 4.5ex }   .SIndent3 .SDescription { padding-left: 6.5ex }
        -    .SIndent4 .SEntry { padding-left: 6.0ex }   .SIndent4 .SDescription { padding-left: 8.0ex }
        -    .SIndent5 .SEntry { padding-left: 7.5ex }   .SIndent5 .SDescription { padding-left: 9.5ex }
        -
        -    .SDescription a { color: #800000}
        -    .SDescription a:active { color: #A00000 }
        -
        -    .SGroup td {
        -        padding-top: .5em; padding-bottom: .25em }
        -
        -    .SGroup .SEntry {
        -        font-weight: bold; font-variant: small-caps }
        -
        -    .SGroup .SEntry a { color: #800000 }
        -    .SGroup .SEntry a:active { color: #F00000 }
        -
        -
        -    .SMain td,
        -    .SClass td,
        -    .SDatabase td,
        -    .SDatabaseTable td,
        -    .SSection td {
        -        font-size: 10pt;
        -        padding-bottom: .25em }
        -
        -    .SClass td,
        -    .SDatabase td,
        -    .SDatabaseTable td,
        -    .SSection td {
        -        padding-top: 1em }
        -
        -    .SMain .SEntry,
        -    .SClass .SEntry,
        -    .SDatabase .SEntry,
        -    .SDatabaseTable .SEntry,
        -    .SSection .SEntry {
        -        font-weight: bold;
        -        }
        -
        -    .SMain .SEntry a,
        -    .SClass .SEntry a,
        -    .SDatabase .SEntry a,
        -    .SDatabaseTable .SEntry a,
        -    .SSection .SEntry a { color: #000000 }
        -
        -    .SMain .SEntry a:active,
        -    .SClass .SEntry a:active,
        -    .SDatabase .SEntry a:active,
        -    .SDatabaseTable .SEntry a:active,
        -    .SSection .SEntry a:active { color: #A00000 }
        -
        -
        -
        -
        -
        -.ClassHierarchy {
        -    margin: 0 15px 1em 15px }
        -
        -    .CHEntry {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
        -        margin-bottom: 3px;
        -        padding: 2px 2ex;
        -        font-size: 10pt;
        -        background-color: #F4F4F4; color: #606060;
        -        }
        -
        -    .Firefox .CHEntry {
        -        -moz-border-radius: 4px;
        -        }
        -
        -    .CHCurrent .CHEntry {
        -        font-weight: bold;
        -        border-color: #000000;
        -        color: #000000;
        -        }
        -
        -    .CHChildNote .CHEntry {
        -        font-style: italic;
        -        font-size: 8pt;
        -        }
        -
        -    .CHIndent {
        -        margin-left: 3ex;
        -        }
        -
        -    .CHEntry a:link,
        -    .CHEntry a:visited,
        -    .CHEntry a:hover {
        -        color: #606060;
        -        }
        -    .CHEntry a:active {
        -        color: #800000;
        -        }
        -
        -
        -
        -
        -
        -#Index {
        -    background-color: #FFFFFF;
        -    }
        -
        -/*  As opposed to .PopupSearchResultsPage #Index  */
        -.IndexPage #Index,
        -.FramedIndexPage #Index,
        -.FramedSearchResultsPage #Index {
        -    padding: 15px;
        -    }
        -
        -.IndexPage #Index {
        -    border-width: 0 0 1px 1px;
        -    border-style: solid;
        -    border-color: #000000;
        -    font-size: 9pt;  /* To make 27ex match the menu's 27ex. */
        -    margin-left: 27ex;
        -    }
        -
        -
        -    .IPageTitle {
        -        font-size: 20pt; font-weight: bold;
        -        color: #FFFFFF; background-color: #7070C0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 0 0 3px 0; border-color: #000000; border-style: solid;
        -        margin: -15px -15px 0 -15px }
        -
        -    .FramedSearchResultsPage .IPageTitle {
        -        margin-bottom: 15px;
        -        }
        -
        -    .INavigationBar {
        -        font-size: 10pt;
        -        text-align: center;
        -        background-color: #FFFFF0;
        -        padding: 5px;
        -        border-bottom: solid 1px black;
        -        margin: 0 -15px 15px -15px;
        -        }
        -
        -    .INavigationBar a {
        -        font-weight: bold }
        -
        -    .IHeading {
        -        font-size: 16pt; font-weight: bold;
        -        padding: 2.5em 0 .5em 0;
        -        text-align: center;
        -        width: 3.5ex;
        -        }
        -    #IFirstHeading {
        -        padding-top: 0;
        -        }
        -
        -    .IEntry {
        -        font-size: 10pt;
        -        padding-left: 1ex;
        -        }
        -    .PopupSearchResultsPage .IEntry {
        -        font-size: 8pt;
        -        padding: 1px 5px;
        -        }
        -    .PopupSearchResultsPage .Opera9 .IEntry,
        -    .FramedSearchResultsPage .Opera9 .IEntry {
        -        text-align: left;
        -        }
        -    .FramedSearchResultsPage .IEntry {
        -        padding: 0;
        -        }
        -
        -    .ISubIndex {
        -        padding-left: 3ex; padding-bottom: .5em }
        -    .PopupSearchResultsPage .ISubIndex {
        -        display: none;
        -        }
        -
        -    /*  While it may cause some entries to look like links when they aren't, I found it's much easier to read the
        -         index if everything's the same color.  */
        -    .ISymbol {
        -        font-weight: bold; color: #900000  }
        -
        -    .IndexPage .ISymbolPrefix,
        -    .FramedIndexPage .ISymbolPrefix {
        -        font-size: 10pt;
        -        text-align: right;
        -        color: #C47C7C;
        -        background-color: #F8F8F8;
        -        border-right: 3px solid #E0E0E0;
        -        border-left: 1px solid #E0E0E0;
        -        padding: 0 1px 0 2px;
        -        }
        -    .PopupSearchResultsPage .ISymbolPrefix,
        -    .FramedSearchResultsPage .ISymbolPrefix {
        -        color: #900000;
        -        }
        -    .PopupSearchResultsPage .ISymbolPrefix {
        -        font-size: 8pt;
        -        }
        -
        -    .IndexPage #IFirstSymbolPrefix,
        -    .FramedIndexPage #IFirstSymbolPrefix {
        -        border-top: 1px solid #E0E0E0;
        -        }
        -    .IndexPage #ILastSymbolPrefix,
        -    .FramedIndexPage #ILastSymbolPrefix {
        -        border-bottom: 1px solid #E0E0E0;
        -        }
        -    .IndexPage #IOnlySymbolPrefix,
        -    .FramedIndexPage #IOnlySymbolPrefix {
        -        border-top: 1px solid #E0E0E0;
        -        border-bottom: 1px solid #E0E0E0;
        -        }
        -
        -    a.IParent,
        -    a.IFile {
        -        display: block;
        -        }
        -
        -    .PopupSearchResultsPage .SRStatus {
        -        padding: 2px 5px;
        -        font-size: 8pt;
        -        font-style: italic;
        -        }
        -    .FramedSearchResultsPage .SRStatus {
        -        font-size: 10pt;
        -        font-style: italic;
        -        }
        -
        -    .SRResult {
        -        display: none;
        -        }
        -
        -
        -
        -#Footer {
        -    font-size: 8pt;
        -    color: #989898;
        -    text-align: right;
        -    }
        -
        -#Footer p {
        -    text-indent: 0;
        -    margin-bottom: .5em;
        -    }
        -
        -.ContentPage #Footer,
        -.IndexPage #Footer {
        -    text-align: right;
        -    margin: 2px;
        -    }
        -
        -.FramedMenuPage #Footer {
        -    text-align: center;
        -    margin: 5em 10px 10px 10px;
        -    padding-top: 1em;
        -    border-top: 1px solid #C8C8C8;
        -    }
        -
        -    #Footer a:link,
        -    #Footer a:hover,
        -    #Footer a:visited { color: #989898 }
        -    #Footer a:active { color: #A00000 }
        -
        -
        -
        -.prettyprint .kwd { color: #800000; }  /* keywords */
        -
        -    .prettyprint.PDefaultValue .kwd,
        -    .prettyprint.PDefaultValuePrefix .kwd,
        -    .prettyprint.PTypePrefix .kwd {
        -        color: #C88F8F;
        -        }
        -
        -.prettyprint .com { color: #008000; }  /* comments */
        -
        -    .prettyprint.PDefaultValue .com,
        -    .prettyprint.PDefaultValuePrefix .com,
        -    .prettyprint.PTypePrefix .com {
        -        color: #8FC88F;
        -        }
        -
        -.prettyprint .str { color: #0000B0; }  /* strings */
        -.prettyprint .lit { color: #0000B0; }  /* literals */
        -
        -    .prettyprint.PDefaultValue .str,
        -    .prettyprint.PDefaultValuePrefix .str,
        -    .prettyprint.PTypePrefix .str,
        -    .prettyprint.PDefaultValue .lit,
        -    .prettyprint.PDefaultValuePrefix .lit,
        -    .prettyprint.PTypePrefix .lit {
        -        color: #8F8FC0;
        -        }
        -
        -.prettyprint .typ { color: #000000; }  /* types */
        -.prettyprint .pun { color: #000000; }  /* punctuation */
        -.prettyprint .pln { color: #000000; }  /* punctuation */
        -
        -    .prettyprint.PDefaultValue .typ,
        -    .prettyprint.PDefaultValuePrefix .typ,
        -    .prettyprint.PTypePrefix .typ,
        -    .prettyprint.PDefaultValue .pun,
        -    .prettyprint.PDefaultValuePrefix .pun,
        -    .prettyprint.PTypePrefix .pun,
        -    .prettyprint.PDefaultValue .pln,
        -    .prettyprint.PDefaultValuePrefix .pln,
        -    .prettyprint.PTypePrefix .pln {
        -        color: #8F8F8F;
        -        }
        -
        -.prettyprint .tag { color: #008; }
        -.prettyprint .atn { color: #606; }
        -.prettyprint .atv { color: #080; }
        -.prettyprint .dec { color: #606; }
        -
        diff --git a/vendor/naturaldocs/Styles/Roman.css b/vendor/naturaldocs/Styles/Roman.css
        deleted file mode 100644
        index 6c3f0cd72..000000000
        --- a/vendor/naturaldocs/Styles/Roman.css
        +++ /dev/null
        @@ -1,826 +0,0 @@
        -/*
        -   IMPORTANT: If you're editing this file in the output directory of one of
        -   your projects, your changes will be overwritten the next time you run
        -   Natural Docs.  Instead, copy this file to your project directory, make your
        -   changes, and you can use it with -s.  Even better would be to make a CSS
        -   file in your project directory with only your changes, which you can then
        -   use with -s [original style] [your changes].
        -
        -   On the other hand, if you're editing this file in the Natural Docs styles
        -   directory, the changes will automatically be applied to all your projects
        -   that use this style the next time Natural Docs is run on them.
        -
        -   This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure.
        -   Natural Docs is licensed under version 3 of the GNU Affero General Public
        -   License (AGPL).  Refer to License.txt for the complete details.
        -
        -   This file may be distributed with documentation files generated by Natural Docs.
        -   Such documentation is not covered by Natural Docs' copyright and licensing,
        -   and may have its own copyright and distribution terms as decided by its author.
        -*/
        -
        -body {
        -    font: 12pt "Times New Roman", Roman, serif;
        -    color: #000000;
        -    margin: 0; padding: 0;
        -    }
        -
        -.ContentPage,
        -.IndexPage,
        -.FramedMenuPage {
        -    background-color: #E8E8E8;
        -    }
        -.FramedContentPage,
        -.FramedIndexPage,
        -.FramedSearchResultsPage,
        -.PopupSearchResultsPage {
        -    background-color: #FFFFFF;
        -    }
        -
        -
        -a:link,
        -a:visited { color: #900000; text-decoration: none }
        -a:hover { color: #900000; text-decoration: underline }
        -a:active { color: #FF0000; text-decoration: underline }
        -
        -td {
        -    vertical-align: top }
        -
        -img { border: 0;  }
        -
        -
        -/*
        -    Comment out this line to use web-style paragraphs (blank line between
        -    paragraphs, no indent) instead of print-style paragraphs (no blank line,
        -    indented.)
        -*/
        -p {
        -    text-indent: 5ex; margin: 0 }
        -
        -
        -/*  Opera doesn't break with just wbr, but will if you add this.  */
        -.Opera wbr:after {
        -	content: "\00200B";
        -	}
        -
        -/*  Blockquotes are used as containers for things that may need to scroll.  */
        -blockquote {
        -    padding: 0;
        -    margin: 0;
        -    overflow: auto;
        -    }
        -
        -
        -.Firefox1 blockquote {
        -    padding-bottom: .5em;
        -    }
        -
        -/*  Turn off scrolling when printing.  */
        -@media print {
        -    blockquote {
        -        overflow: visible;
        -        }
        -    .IE blockquote {
        -        width: auto;
        -        }
        -    }
        -
        -
        -
        -#Menu {
        -    font-size: 10pt;
        -    padding: 10px 0 0 0;
        -    }
        -.ContentPage #Menu,
        -.IndexPage #Menu {
        -    position: absolute;
        -    top: 0;
        -    left: 0;
        -    width: 31ex;
        -    overflow: hidden;
        -    }
        -.ContentPage .Firefox #Menu,
        -.IndexPage .Firefox #Menu {
        -    width: 27ex;
        -    }
        -
        -
        -    .MTitle {
        -        font-size: 18pt; font-weight: bold; font-variant: small-caps;
        -        text-align: center;
        -        padding: 5px 10px 15px 10px;
        -        border-bottom: 1px dotted #000000;
        -        margin-bottom: 15px }
        -
        -    .MSubTitle {
        -        font-size: 10pt; font-weight: normal; font-variant: normal;
        -        margin-top: 1ex; margin-bottom: 5px }
        -
        -
        -    .MEntry a:link,
        -    .MEntry a:hover,
        -    .MEntry a:visited { color: #606060; margin-right: 0 }
        -    .MEntry a:active { color: #A00000; margin-right: 0 }
        -
        -
        -    .MGroup {
        -        font-variant: small-caps; font-weight: bold;
        -        margin: 1em 0 1em 10px;
        -        }
        -
        -    .MGroupContent {
        -        font-variant: normal; font-weight: normal }
        -
        -    .MGroup a:link,
        -    .MGroup a:hover,
        -    .MGroup a:visited { color: #545454; margin-right: 10px }
        -    .MGroup a:active { color: #A00000; margin-right: 10px }
        -
        -
        -    .MFile,
        -    .MText,
        -    .MLink,
        -    .MIndex {
        -        padding: 1px 17px 2px 10px;
        -        margin: .25em 0 .25em 0;
        -        }
        -
        -    .MText {
        -        font-size: 8pt; font-style: italic }
        -
        -    .MLink {
        -        font-style: italic }
        -
        -    #MSelected {
        -        color: #000000; background-color: #FFFFFF;
        -        /*  Replace padding with border.  */
        -        padding: 0 10px 0 10px;
        -        border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000;
        -        margin-right: 5px;
        -        }
        -
        -    /*  Close off the left side when its in a group.  */
        -    .MGroup #MSelected {
        -        padding-left: 9px; border-left-width: 1px }
        -
        -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
        -    .Firefox #MSelected {
        -        -moz-border-radius-topright: 10px;
        -        -moz-border-radius-bottomright: 10px }
        -    .Firefox .MGroup #MSelected {
        -        -moz-border-radius-topleft: 10px;
        -        -moz-border-radius-bottomleft: 10px }
        -
        -
        -    #MSearchPanel {
        -        padding: 0px 6px;
        -        margin: .25em 0;
        -        }
        -
        -
        -    #MSearchField {
        -        font: italic 10pt "Times New Roman", Roman, serif;
        -        color: #606060;
        -        background-color: #E8E8E8;
        -        border: none;
        -        padding: 2px 4px;
        -        width: 100%;
        -        }
        -    /* Only Opera gets it right. */
        -    .Firefox #MSearchField,
        -    .IE #MSearchField,
        -    .Safari #MSearchField {
        -        width: 94%;
        -        }
        -    .Opera9 #MSearchField,
        -    .Konqueror #MSearchField {
        -        width: 97%;
        -        }
        -    .FramedMenuPage .Firefox #MSearchField,
        -    .FramedMenuPage .Safari #MSearchField,
        -    .FramedMenuPage .Konqueror #MSearchField {
        -        width: 98%;
        -        }
        -
        -    /* Firefox doesn't do this right in frames without #MSearchPanel added on.
        -        It's presence doesn't hurt anything other browsers. */
        -    #MSearchPanel.MSearchPanelInactive:hover #MSearchField {
        -        background-color: #FFFFFF;
        -        border: 1px solid #C0C0C0;
        -        padding: 1px 3px;
        -        }
        -    .MSearchPanelActive #MSearchField {
        -        background-color: #FFFFFF;
        -        border: 1px solid #C0C0C0;
        -        font-style: normal;
        -        padding: 1px 3px;
        -        }
        -
        -    #MSearchType {
        -        visibility: hidden;
        -        font: 10pt "Times New Roman", Roman, serif;
        -        width: 98%;
        -        padding: 0;
        -        border: 1px solid #C0C0C0;
        -        }
        -    .MSearchPanelActive #MSearchType,
        -    /*  As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */
        -    #MSearchPanel.MSearchPanelInactive:hover #MSearchType,
        -    #MSearchType:focus {
        -        visibility: visible;
        -        color: #606060;
        -        }
        -    #MSearchType option#MSearchEverything {
        -        font-weight: bold;
        -        }
        -
        -    .Opera8 .MSearchPanelInactive:hover,
        -    .Opera8 .MSearchPanelActive {
        -        margin-left: -1px;
        -        }
        -
        -
        -    iframe#MSearchResults {
        -        width: 60ex;
        -        height: 15em;
        -        }
        -    #MSearchResultsWindow {
        -        display: none;
        -        position: absolute;
        -        left: 0; top: 0;
        -        border: 1px solid #000000;
        -        background-color: #E8E8E8;
        -        }
        -    #MSearchResultsWindowClose {
        -        font-weight: bold;
        -        font-size: 8pt;
        -        display: block;
        -        padding: 2px 5px;
        -        }
        -    #MSearchResultsWindowClose:link,
        -    #MSearchResultsWindowClose:visited {
        -        color: #000000;
        -        text-decoration: none;
        -        }
        -    #MSearchResultsWindowClose:active,
        -    #MSearchResultsWindowClose:hover {
        -        color: #800000;
        -        text-decoration: none;
        -        background-color: #F4F4F4;
        -        }
        -
        -
        -
        -
        -#Content {
        -    padding-bottom: 15px;
        -    }
        -
        -.ContentPage #Content {
        -    border-width: 0 0 1px 1px;
        -    border-style: solid;
        -    border-color: #000000;
        -    background-color: #FFFFFF;
        -    font-size: 10pt;  /* To make 31ex match the menu's 31ex. */
        -    margin-left: 31ex;
        -    }
        -.ContentPage .Firefox #Content {
        -    margin-left: 27ex;
        -    }
        -
        -
        -
        -    .CTopic {
        -        font-size: 12pt;
        -        margin-bottom: 3em;
        -        }
        -
        -
        -    .CTitle {
        -        font-size: 16pt; font-weight: bold;
        -        border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0;
        -        margin: 0 15px .5em 15px }
        -
        -    .CGroup .CTitle {
        -        font-size: 18pt; font-variant: small-caps;
        -        padding-left: 15px; padding-right: 15px;
        -        border-width: 0 0 2px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    .CClass .CTitle,
        -    .CInterface .CTitle,
        -    .CDatabase .CTitle,
        -    .CDatabaseTable .CTitle,
        -    .CSection .CTitle {
        -        font-size: 20pt;
        -        color: #FFFFFF; background-color: #A0A0A0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 2px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    #MainTopic .CTitle {
        -        font-size: 24pt;
        -        color: #FFFFFF; background-color: #7070C0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 0 0 3px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    .CBody {
        -        margin-left: 15px; margin-right: 15px }
        -
        -
        -    .CToolTip {
        -        position: absolute; visibility: hidden;
        -        left: 0; top: 0;
        -        background-color: #FFFFE0;
        -        padding: 5px;
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000;
        -        font-size: 10pt;
        -        }
        -
        -    .Opera .CToolTip {
        -        max-width: 98%;
        -        }
        -
        -    /*  Scrollbars would be useless.  */
        -    .CToolTip blockquote {
        -        overflow: hidden;
        -        }
        -    .IE6 .CToolTip blockquote {
        -        overflow: visible;
        -        }
        -
        -    .CHeading {
        -        font-weight: bold; font-size: 10pt;
        -        margin: 1.5em 0 .5em 0;
        -        }
        -
        -    .CBody pre {
        -        font: 10pt "Courier New", Courier, monospace;
        -	    background-color: #FCFCFC;
        -	    margin: 1em 35px;
        -	    padding: 10px 15px 10px 10px;
        -	    border-color: #E0E0E0 #E0E0E0 #E0E0E0 #E4E4E4;
        -	    border-width: 1px 1px 1px 6px;
        -	    border-style: dashed dashed dashed solid;
        -        }
        -
        -    .CBody ul {
        -        /*  I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever.
        -             Reapply it here as padding.  */
        -        padding-left: 15px; padding-right: 15px;
        -        margin: .5em 5ex .5em 5ex;
        -        }
        -
        -    .CDescriptionList {
        -        margin: .5em 5ex 0 5ex }
        -
        -        .CDLEntry {
        -            font: 10pt "Courier New", Courier, monospace; color: #808080;
        -            padding-bottom: .25em;
        -            white-space: nowrap }
        -
        -        .CDLDescription {
        -            font-size: 12pt;  /*  For browsers that don't inherit correctly, like Opera 5.  */
        -            padding-bottom: .5em; padding-left: 5ex }
        -
        -
        -    .CTopic img {
        -        text-align: center;
        -        display: block;
        -        margin: 1em auto;
        -        }
        -    .CImageCaption {
        -        font-variant: small-caps;
        -        font-size: 10pt;
        -        color: #808080;
        -        text-align: center;
        -        position: relative;
        -        top: 1em;
        -        }
        -
        -    .CImageLink {
        -        color: #808080;
        -        font-style: italic;
        -        }
        -    a.CImageLink:link,
        -    a.CImageLink:visited,
        -    a.CImageLink:hover { color: #808080 }
        -
        -
        -
        -
        -
        -.Prototype {
        -    font: 10pt "Courier New", Courier, monospace;
        -    padding: 5px 3ex;
        -    border-width: 1px; border-style: solid;
        -    margin: 0 5ex 1.5em 5ex;
        -    }
        -
        -    .Prototype td {
        -        font-size: 10pt;
        -        }
        -
        -    .PDefaultValue,
        -    .PDefaultValuePrefix,
        -    .PTypePrefix {
        -        color: #8F8F8F;
        -        }
        -    .PTypePrefix {
        -        text-align: right;
        -        }
        -    .PAfterParameters {
        -        vertical-align: bottom;
        -        }
        -
        -    .IE .Prototype table {
        -        padding: 0;
        -        }
        -
        -    .CFunction .Prototype {
        -        background-color: #F4F4F4; border-color: #D0D0D0 }
        -    .CProperty .Prototype {
        -        background-color: #F4F4FF; border-color: #C0C0E8 }
        -    .CVariable .Prototype {
        -        background-color: #FFFFF0; border-color: #E0E0A0 }
        -
        -    .CClass .Prototype {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
        -        background-color: #F4F4F4;
        -        }
        -    .CInterface .Prototype {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0;
        -        background-color: #F4F4FF;
        -        }
        -
        -    .CDatabaseIndex .Prototype,
        -    .CConstant .Prototype {
        -        background-color: #D0D0D0; border-color: #000000 }
        -    .CType .Prototype,
        -    .CEnumeration .Prototype {
        -        background-color: #FAF0F0; border-color: #E0B0B0;
        -        }
        -    .CDatabaseTrigger .Prototype,
        -    .CEvent .Prototype,
        -    .CDelegate .Prototype {
        -        background-color: #F0FCF0; border-color: #B8E4B8 }
        -
        -    .CToolTip .Prototype {
        -        margin: 0 0 .5em 0;
        -        white-space: nowrap;
        -        }
        -
        -
        -
        -
        -
        -.Summary {
        -    margin: 1.5em 5ex 0 5ex }
        -
        -    .STitle {
        -        font-size: 14pt; font-weight: bold;
        -        margin-bottom: .5em }
        -
        -
        -    .SBorder {
        -        background-color: #FFFFF0;
        -        padding: 15px;
        -        border: 1px solid #C0C060 }
        -
        -    /* In a frame IE 6 will make them too long unless you set the width to 100%.  Without frames it will be correct without a width
        -        or slightly too long (but not enough to scroll) with a width.  This arbitrary weirdness simply astounds me.  IE 7 has the same
        -        problem with frames, haven't tested it without.  */
        -    .FramedContentPage .IE .SBorder {
        -        width: 100% }
        -
        -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
        -    .Firefox .SBorder {
        -        -moz-border-radius: 20px }
        -
        -
        -    .STable {
        -        font-size: 10pt; width: 100% }
        -
        -    .SEntry {
        -        width: 30% }
        -    .SDescription {
        -        width: 70% }
        -
        -
        -    .SMarked {
        -        background-color: #F8F8D8 }
        -
        -    .SDescription { padding-left: 2ex }
        -    .SIndent1 .SEntry { padding-left: 1.5ex }   .SIndent1 .SDescription { padding-left: 3.5ex }
        -    .SIndent2 .SEntry { padding-left: 3.0ex }   .SIndent2 .SDescription { padding-left: 5.0ex }
        -    .SIndent3 .SEntry { padding-left: 4.5ex }   .SIndent3 .SDescription { padding-left: 6.5ex }
        -    .SIndent4 .SEntry { padding-left: 6.0ex }   .SIndent4 .SDescription { padding-left: 8.0ex }
        -    .SIndent5 .SEntry { padding-left: 7.5ex }   .SIndent5 .SDescription { padding-left: 9.5ex }
        -
        -    .SDescription a { color: #800000}
        -    .SDescription a:active { color: #A00000 }
        -
        -    .SGroup td {
        -        padding-top: .5em; padding-bottom: .25em }
        -
        -    .SGroup .SEntry {
        -        font-weight: bold; font-variant: small-caps }
        -
        -    .SGroup .SEntry a { color: #800000 }
        -    .SGroup .SEntry a:active { color: #F00000 }
        -
        -
        -    .SMain td,
        -    .SClass td,
        -    .SDatabase td,
        -    .SDatabaseTable td,
        -    .SSection td {
        -        font-size: 12pt;
        -        padding-bottom: .25em }
        -
        -    .SClass td,
        -    .SDatabase td,
        -    .SDatabaseTable td,
        -    .SSection td {
        -        padding-top: 1em }
        -
        -    .SMain .SEntry,
        -    .SClass .SEntry,
        -    .SDatabase .SEntry,
        -    .SDatabaseTable .SEntry,
        -    .SSection .SEntry {
        -        font-weight: bold;
        -        }
        -
        -    .SMain .SEntry a,
        -    .SClass .SEntry a,
        -    .SDatabase .SEntry a,
        -    .SDatabaseTable .SEntry a,
        -    .SSection .SEntry a { color: #000000 }
        -
        -    .SMain .SEntry a:active,
        -    .SClass .SEntry a:active,
        -    .SDatabase .SEntry a:active,
        -    .SDatabaseTable .SEntry a:active,
        -    .SSection .SEntry a:active { color: #A00000 }
        -
        -
        -
        -
        -
        -.ClassHierarchy {
        -    margin: 0 15px 1em 15px }
        -
        -    .CHEntry {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
        -        margin-bottom: 3px;
        -        padding: 2px 2ex;
        -        font-size: 12pt;
        -        background-color: #F4F4F4; color: #606060;
        -        }
        -
        -    .Firefox .CHEntry {
        -        -moz-border-radius: 4px;
        -        }
        -
        -    .CHCurrent .CHEntry {
        -        font-weight: bold;
        -        border-color: #000000;
        -        color: #000000;
        -        }
        -
        -    .CHChildNote .CHEntry {
        -        font-style: italic;
        -        font-size: 10pt;
        -        }
        -
        -    .CHIndent {
        -        margin-left: 3ex;
        -        }
        -
        -    .CHEntry a:link,
        -    .CHEntry a:visited,
        -    .CHEntry a:hover {
        -        color: #606060;
        -        }
        -    .CHEntry a:active {
        -        color: #800000;
        -        }
        -
        -
        -
        -
        -
        -#Index {
        -    background-color: #FFFFFF;
        -    }
        -
        -/*  As opposed to .PopupSearchResultsPage #Index  */
        -.IndexPage #Index,
        -.FramedIndexPage #Index,
        -.FramedSearchResultsPage #Index {
        -    padding: 15px;
        -    }
        -
        -.IndexPage #Index {
        -    border-width: 0 0 1px 1px;
        -    border-style: solid;
        -    border-color: #000000;
        -    font-size: 10pt;  /* To make 27ex match the menu's 27ex. */
        -    margin-left: 27ex;
        -    }
        -
        -
        -    .IPageTitle {
        -        font-size: 24pt; font-weight: bold;
        -        color: #FFFFFF; background-color: #7070C0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 0 0 3px 0; border-color: #000000; border-style: solid;
        -        margin: -15px -15px 0 -15px }
        -
        -    .FramedSearchResultsPage .IPageTitle {
        -        margin-bottom: 15px;
        -        }
        -
        -    .INavigationBar {
        -        text-align: center;
        -        background-color: #FFFFF0;
        -        padding: 5px;
        -        border-bottom: solid 1px black;
        -        margin: 0 -15px 15px -15px;
        -        }
        -
        -    .INavigationBar a {
        -        font-weight: bold }
        -
        -    .IHeading {
        -        font-size: 20pt; font-weight: bold;
        -        padding: 2.5em 0 .5em 0;
        -        text-align: center;
        -        width: 3.5ex;
        -        }
        -    #IFirstHeading {
        -        padding-top: 0;
        -        }
        -
        -    .IEntry {
        -        font-size: 12pt;
        -        padding-left: 1ex;
        -        }
        -    .PopupSearchResultsPage .IEntry {
        -        font-size: 10pt;
        -        padding: 1px 5px;
        -        }
        -    .PopupSearchResultsPage .Opera9 .IEntry,
        -    .FramedSearchResultsPage .Opera9 .IEntry {
        -        text-align: left;
        -        }
        -    .FramedSearchResultsPage .IEntry {
        -        padding: 0;
        -        }
        -
        -    .ISubIndex {
        -        padding-left: 3ex; padding-bottom: .5em }
        -    .PopupSearchResultsPage .ISubIndex {
        -        display: none;
        -        }
        -
        -    /*  While it may cause some entries to look like links when they aren't, I found it's much easier to read the
        -         index if everything's the same color.  */
        -    .ISymbol {
        -        font-weight: bold; color: #900000  }
        -
        -    .IndexPage .ISymbolPrefix,
        -    .FramedIndexPage .ISymbolPrefix {
        -        font-size: 12pt;
        -        text-align: right;
        -        color: #C47C7C;
        -        background-color: #F8F8F8;
        -        border-right: 3px solid #E0E0E0;
        -        border-left: 1px solid #E0E0E0;
        -        padding: 0 1px 0 2px;
        -        }
        -    .PopupSearchResultsPage .ISymbolPrefix,
        -    .FramedSearchResultsPage .ISymbolPrefix {
        -        color: #900000;
        -        }
        -    .PopupSearchResultsPage .ISymbolPrefix {
        -        font-size: 10pt;
        -        }
        -
        -    .IndexPage #IFirstSymbolPrefix,
        -    .FramedIndexPage #IFirstSymbolPrefix {
        -        border-top: 1px solid #E0E0E0;
        -        }
        -    .IndexPage #ILastSymbolPrefix,
        -    .FramedIndexPage #ILastSymbolPrefix {
        -        border-bottom: 1px solid #E0E0E0;
        -        }
        -    .IndexPage #IOnlySymbolPrefix,
        -    .FramedIndexPage #IOnlySymbolPrefix {
        -        border-top: 1px solid #E0E0E0;
        -        border-bottom: 1px solid #E0E0E0;
        -        }
        -
        -    a.IParent,
        -    a.IFile {
        -        display: block;
        -        }
        -
        -    .PopupSearchResultsPage .SRStatus {
        -        padding: 2px 5px;
        -        font-size: 10pt;
        -        font-style: italic;
        -        }
        -    .FramedSearchResultsPage .SRStatus {
        -        font-size: 12pt;
        -        font-style: italic;
        -        }
        -
        -    .SRResult {
        -        display: none;
        -        }
        -
        -
        -
        -#Footer {
        -    font-size: 8pt;
        -    color: #989898;
        -    text-align: right;
        -    }
        -
        -#Footer p {
        -    text-indent: 0;
        -    margin-bottom: .5em;
        -    }
        -
        -.ContentPage #Footer,
        -.IndexPage #Footer {
        -    text-align: right;
        -    margin: 2px;
        -    }
        -
        -.FramedMenuPage #Footer {
        -    text-align: center;
        -    margin: 5em 10px 10px 10px;
        -    padding-top: 1em;
        -    border-top: 1px solid #C8C8C8;
        -    }
        -
        -    #Footer a:link,
        -    #Footer a:hover,
        -    #Footer a:visited { color: #989898 }
        -    #Footer a:active { color: #A00000 }
        -
        -
        -
        -.prettyprint .kwd { color: #800000; }  /* keywords */
        -
        -    .prettyprint.PDefaultValue .kwd,
        -    .prettyprint.PDefaultValuePrefix .kwd,
        -    .prettyprint.PTypePrefix .kwd {
        -        color: #C88F8F;
        -        }
        -
        -.prettyprint .com { color: #008000; }  /* comments */
        -
        -    .prettyprint.PDefaultValue .com,
        -    .prettyprint.PDefaultValuePrefix .com,
        -    .prettyprint.PTypePrefix .com {
        -        color: #8FC88F;
        -        }
        -
        -.prettyprint .str { color: #0000B0; }  /* strings */
        -.prettyprint .lit { color: #0000B0; }  /* literals */
        -
        -    .prettyprint.PDefaultValue .str,
        -    .prettyprint.PDefaultValuePrefix .str,
        -    .prettyprint.PTypePrefix .str,
        -    .prettyprint.PDefaultValue .lit,
        -    .prettyprint.PDefaultValuePrefix .lit,
        -    .prettyprint.PTypePrefix .lit {
        -        color: #8F8FC0;
        -        }
        -
        -.prettyprint .typ { color: #000000; }  /* types */
        -.prettyprint .pun { color: #000000; }  /* punctuation */
        -.prettyprint .pln { color: #000000; }  /* punctuation */
        -
        -    .prettyprint.PDefaultValue .typ,
        -    .prettyprint.PDefaultValuePrefix .typ,
        -    .prettyprint.PTypePrefix .typ,
        -    .prettyprint.PDefaultValue .pun,
        -    .prettyprint.PDefaultValuePrefix .pun,
        -    .prettyprint.PTypePrefix .pun,
        -    .prettyprint.PDefaultValue .pln,
        -    .prettyprint.PDefaultValuePrefix .pln,
        -    .prettyprint.PTypePrefix .pln {
        -        color: #8F8F8F;
        -        }
        -
        -.prettyprint .tag { color: #008; }
        -.prettyprint .atn { color: #606; }
        -.prettyprint .atv { color: #080; }
        -.prettyprint .dec { color: #606; }
        -
        diff --git a/vendor/naturaldocs/Styles/Small.css b/vendor/naturaldocs/Styles/Small.css
        deleted file mode 100644
        index 1832d8f39..000000000
        --- a/vendor/naturaldocs/Styles/Small.css
        +++ /dev/null
        @@ -1,824 +0,0 @@
        -/*
        -   IMPORTANT: If you're editing this file in the output directory of one of
        -   your projects, your changes will be overwritten the next time you run
        -   Natural Docs.  Instead, copy this file to your project directory, make your
        -   changes, and you can use it with -s.  Even better would be to make a CSS
        -   file in your project directory with only your changes, which you can then
        -   use with -s [original style] [your changes].
        -
        -   On the other hand, if you're editing this file in the Natural Docs styles
        -   directory, the changes will automatically be applied to all your projects
        -   that use this style the next time Natural Docs is run on them.
        -
        -   This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure.
        -   Natural Docs is licensed under version 3 of the GNU Affero General Public
        -   License (AGPL).  Refer to License.txt for the complete details.
        -
        -   This file may be distributed with documentation files generated by Natural Docs.
        -   Such documentation is not covered by Natural Docs' copyright and licensing,
        -   and may have its own copyright and distribution terms as decided by its author.
        -*/
        -
        -body {
        -    font: 8pt Verdana, Arial, sans-serif;
        -    color: #000000;
        -    margin: 0; padding: 0;
        -    }
        -
        -.ContentPage,
        -.IndexPage,
        -.FramedMenuPage {
        -    background-color: #E8E8E8;
        -    }
        -.FramedContentPage,
        -.FramedIndexPage,
        -.FramedSearchResultsPage,
        -.PopupSearchResultsPage {
        -    background-color: #FFFFFF;
        -    }
        -
        -
        -a:link,
        -a:visited { color: #900000; text-decoration: none }
        -a:hover { color: #900000; text-decoration: underline }
        -a:active { color: #FF0000; text-decoration: underline }
        -
        -td {
        -    vertical-align: top }
        -
        -img { border: 0;  }
        -
        -
        -/*
        -    Comment out this line to use web-style paragraphs (blank line between
        -    paragraphs, no indent) instead of print-style paragraphs (no blank line,
        -    indented.)
        -*/
        -p {
        -    text-indent: 5ex; margin: 0 }
        -
        -
        -/*  Opera doesn't break with just wbr, but will if you add this.  */
        -.Opera wbr:after {
        -	content: "\00200B";
        -	}
        -
        -/*  Blockquotes are used as containers for things that may need to scroll.  */
        -blockquote {
        -    padding: 0;
        -    margin: 0;
        -    overflow: auto;
        -    }
        -
        -
        -.Firefox1 blockquote {
        -    padding-bottom: .5em;
        -    }
        -
        -/*  Turn off scrolling when printing.  */
        -@media print {
        -    blockquote {
        -        overflow: visible;
        -        }
        -    .IE blockquote {
        -        width: auto;
        -        }
        -    }
        -
        -
        -
        -#Menu {
        -    font-size: 8pt;
        -    padding: 10px 0 0 0;
        -    }
        -.ContentPage #Menu,
        -.IndexPage #Menu {
        -    position: absolute;
        -    top: 0;
        -    left: 0;
        -    width: 31ex;
        -    overflow: hidden;
        -    }
        -.ContentPage .Firefox #Menu,
        -.IndexPage .Firefox #Menu {
        -    width: 27ex;
        -    }
        -
        -
        -    .MTitle {
        -        font-size: 16pt; font-weight: bold; font-variant: small-caps;
        -        text-align: center;
        -        padding: 5px 10px 15px 10px;
        -        border-bottom: 1px dotted #000000;
        -        margin-bottom: 15px }
        -
        -    .MSubTitle {
        -        font-size: 9pt; font-weight: normal; font-variant: normal;
        -        margin-top: 1ex; margin-bottom: 5px }
        -
        -
        -    .MEntry a:link,
        -    .MEntry a:hover,
        -    .MEntry a:visited { color: #606060; margin-right: 0 }
        -    .MEntry a:active { color: #A00000; margin-right: 0 }
        -
        -
        -    .MGroup {
        -        font-variant: small-caps; font-weight: bold;
        -        margin: 1em 0 1em 10px;
        -        }
        -
        -    .MGroupContent {
        -        font-variant: normal; font-weight: normal }
        -
        -    .MGroup a:link,
        -    .MGroup a:hover,
        -    .MGroup a:visited { color: #545454; margin-right: 10px }
        -    .MGroup a:active { color: #A00000; margin-right: 10px }
        -
        -
        -    .MFile,
        -    .MText,
        -    .MLink,
        -    .MIndex {
        -        padding: 1px 17px 2px 10px;
        -        margin: .25em 0 .25em 0;
        -        }
        -
        -    .MText {
        -        font-size: 8pt; font-style: italic }
        -
        -    .MLink {
        -        font-style: italic }
        -
        -    #MSelected {
        -        color: #000000; background-color: #FFFFFF;
        -        /*  Replace padding with border.  */
        -        padding: 0 10px 0 10px;
        -        border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000;
        -        margin-right: 5px;
        -        }
        -
        -    /*  Close off the left side when its in a group.  */
        -    .MGroup #MSelected {
        -        padding-left: 9px; border-left-width: 1px }
        -
        -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
        -    .Firefox #MSelected {
        -        -moz-border-radius-topright: 10px;
        -        -moz-border-radius-bottomright: 10px }
        -    .Firefox .MGroup #MSelected {
        -        -moz-border-radius-topleft: 10px;
        -        -moz-border-radius-bottomleft: 10px }
        -
        -
        -    #MSearchPanel {
        -        padding: 0px 6px;
        -        margin: .25em 0;
        -        }
        -
        -
        -    #MSearchField {
        -        font: italic 8pt Verdana, sans-serif;
        -        color: #606060;
        -        background-color: #E8E8E8;
        -        border: none;
        -        padding: 2px 4px;
        -        width: 100%;
        -        }
        -    /* Only Opera gets it right. */
        -    .Firefox #MSearchField,
        -    .IE #MSearchField,
        -    .Safari #MSearchField {
        -        width: 94%;
        -        }
        -    .Opera9 #MSearchField,
        -    .Konqueror #MSearchField {
        -        width: 97%;
        -        }
        -    .FramedMenuPage .Firefox #MSearchField,
        -    .FramedMenuPage .Safari #MSearchField,
        -    .FramedMenuPage .Konqueror #MSearchField {
        -        width: 98%;
        -        }
        -
        -    /* Firefox doesn't do this right in frames without #MSearchPanel added on.
        -        It's presence doesn't hurt anything other browsers. */
        -    #MSearchPanel.MSearchPanelInactive:hover #MSearchField {
        -        background-color: #FFFFFF;
        -        border: 1px solid #C0C0C0;
        -        padding: 1px 3px;
        -        }
        -    .MSearchPanelActive #MSearchField {
        -        background-color: #FFFFFF;
        -        border: 1px solid #C0C0C0;
        -        font-style: normal;
        -        padding: 1px 3px;
        -        }
        -
        -    #MSearchType {
        -        visibility: hidden;
        -        font: 8pt Verdana, sans-serif;
        -        width: 98%;
        -        padding: 0;
        -        border: 1px solid #C0C0C0;
        -        }
        -    .MSearchPanelActive #MSearchType,
        -    /*  As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */
        -    #MSearchPanel.MSearchPanelInactive:hover #MSearchType,
        -    #MSearchType:focus {
        -        visibility: visible;
        -        color: #606060;
        -        }
        -    #MSearchType option#MSearchEverything {
        -        font-weight: bold;
        -        }
        -
        -    .Opera8 .MSearchPanelInactive:hover,
        -    .Opera8 .MSearchPanelActive {
        -        margin-left: -1px;
        -        }
        -
        -
        -    iframe#MSearchResults {
        -        width: 60ex;
        -        height: 15em;
        -        }
        -    #MSearchResultsWindow {
        -        display: none;
        -        position: absolute;
        -        left: 0; top: 0;
        -        border: 1px solid #000000;
        -        background-color: #E8E8E8;
        -        }
        -    #MSearchResultsWindowClose {
        -        font-weight: bold;
        -        font-size: 8pt;
        -        display: block;
        -        padding: 2px 5px;
        -        }
        -    #MSearchResultsWindowClose:link,
        -    #MSearchResultsWindowClose:visited {
        -        color: #000000;
        -        text-decoration: none;
        -        }
        -    #MSearchResultsWindowClose:active,
        -    #MSearchResultsWindowClose:hover {
        -        color: #800000;
        -        text-decoration: none;
        -        background-color: #F4F4F4;
        -        }
        -
        -
        -
        -
        -#Content {
        -    padding-bottom: 15px;
        -    }
        -
        -.ContentPage #Content {
        -    border-width: 0 0 1px 1px;
        -    border-style: solid;
        -    border-color: #000000;
        -    background-color: #FFFFFF;
        -    font-size: 8pt;  /* To make 31ex match the menu's 31ex. */
        -    margin-left: 31ex;
        -    }
        -.ContentPage .Firefox #Content {
        -    margin-left: 27ex;
        -    }
        -
        -
        -
        -    .CTopic {
        -        font-size: 8pt;
        -        margin-bottom: 3em;
        -        }
        -
        -
        -    .CTitle {
        -        font-size: 11pt; font-weight: bold;
        -        border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0;
        -        margin: 0 15px .5em 15px }
        -
        -    .CGroup .CTitle {
        -        font-size: 16pt; font-variant: small-caps;
        -        padding-left: 15px; padding-right: 15px;
        -        border-width: 0 0 2px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    .CClass .CTitle,
        -    .CInterface .CTitle,
        -    .CDatabase .CTitle,
        -    .CDatabaseTable .CTitle,
        -    .CSection .CTitle {
        -        font-size: 18pt;
        -        color: #FFFFFF; background-color: #A0A0A0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 2px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    #MainTopic .CTitle {
        -        font-size: 20pt;
        -        color: #FFFFFF; background-color: #7070C0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 0 0 3px 0; border-color: #000000;
        -        margin-left: 0; margin-right: 0 }
        -
        -    .CBody {
        -        margin-left: 15px; margin-right: 15px }
        -
        -
        -    .CToolTip {
        -        position: absolute; visibility: hidden;
        -        left: 0; top: 0;
        -        background-color: #FFFFE0;
        -        padding: 5px;
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000;
        -        font-size: 8pt;
        -        }
        -
        -    .Opera .CToolTip {
        -        max-width: 98%;
        -        }
        -
        -    /*  Scrollbars would be useless.  */
        -    .CToolTip blockquote {
        -        overflow: hidden;
        -        }
        -    .IE6 .CToolTip blockquote {
        -        overflow: visible;
        -        }
        -
        -    .CHeading {
        -        font-weight: bold; font-size: 9pt;
        -        margin: 1.5em 0 .5em 0;
        -        }
        -
        -    .CBody pre {
        -        font: 8pt "Courier New", Courier, monospace;
        -	    background-color: #FCFCFC;
        -	    margin: 1em 35px;
        -	    padding: 10px 15px 10px 10px;
        -	    border-color: #E0E0E0 #E0E0E0 #E0E0E0 #E4E4E4;
        -	    border-width: 1px 1px 1px 6px;
        -	    border-style: dashed dashed dashed solid;
        -        }
        -
        -    .CBody ul {
        -        /*  I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever.
        -             Reapply it here as padding.  */
        -        padding-left: 15px; padding-right: 15px;
        -        margin: .5em 5ex .5em 5ex;
        -        }
        -
        -    .CDescriptionList {
        -        margin: .5em 5ex 0 5ex }
        -
        -        .CDLEntry {
        -            font: 8pt "Courier New", Courier, monospace; color: #808080;
        -            padding-bottom: .25em;
        -            white-space: nowrap }
        -
        -        .CDLDescription {
        -            font-size: 8pt;  /*  For browsers that don't inherit correctly, like Opera 5.  */
        -            padding-bottom: .5em; padding-left: 5ex }
        -
        -
        -    .CTopic img {
        -        text-align: center;
        -        display: block;
        -        margin: 1em auto;
        -        }
        -    .CImageCaption {
        -        font-variant: small-caps;
        -        font-size: 8pt;
        -        color: #808080;
        -        text-align: center;
        -        position: relative;
        -        top: 1em;
        -        }
        -
        -    .CImageLink {
        -        color: #808080;
        -        font-style: italic;
        -        }
        -    a.CImageLink:link,
        -    a.CImageLink:visited,
        -    a.CImageLink:hover { color: #808080 }
        -
        -
        -
        -
        -
        -.Prototype {
        -    font: 8pt "Courier New", Courier, monospace;
        -    padding: 5px 3ex;
        -    border-width: 1px; border-style: solid;
        -    margin: 0 5ex 1.5em 5ex;
        -    }
        -
        -    .Prototype td {
        -        font-size: 8pt;
        -        }
        -
        -    .PDefaultValue,
        -    .PDefaultValuePrefix,
        -    .PTypePrefix {
        -        color: #8F8F8F;
        -        }
        -    .PTypePrefix {
        -        text-align: right;
        -        }
        -    .PAfterParameters {
        -        vertical-align: bottom;
        -        }
        -
        -    .IE .Prototype table {
        -        padding: 0;
        -        }
        -
        -    .CFunction .Prototype {
        -        background-color: #F4F4F4; border-color: #D0D0D0 }
        -    .CProperty .Prototype {
        -        background-color: #F4F4FF; border-color: #C0C0E8 }
        -    .CVariable .Prototype {
        -        background-color: #FFFFF0; border-color: #E0E0A0 }
        -
        -    .CClass .Prototype {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
        -        background-color: #F4F4F4;
        -        }
        -    .CInterface .Prototype {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0;
        -        background-color: #F4F4FF;
        -        }
        -
        -    .CDatabaseIndex .Prototype,
        -    .CConstant .Prototype {
        -        background-color: #D0D0D0; border-color: #000000 }
        -    .CType .Prototype,
        -    .CEnumeration .Prototype {
        -        background-color: #FAF0F0; border-color: #E0B0B0;
        -        }
        -    .CDatabaseTrigger .Prototype,
        -    .CEvent .Prototype,
        -    .CDelegate .Prototype {
        -        background-color: #F0FCF0; border-color: #B8E4B8 }
        -
        -    .CToolTip .Prototype {
        -        margin: 0 0 .5em 0;
        -        white-space: nowrap;
        -        }
        -
        -
        -
        -
        -
        -.Summary {
        -    margin: 1.5em 5ex 0 5ex }
        -
        -    .STitle {
        -        font-size: 11pt; font-weight: bold;
        -        margin-bottom: .5em }
        -
        -
        -    .SBorder {
        -        background-color: #FFFFF0;
        -        padding: 15px;
        -        border: 1px solid #C0C060 }
        -
        -    /* In a frame IE 6 will make them too long unless you set the width to 100%.  Without frames it will be correct without a width
        -        or slightly too long (but not enough to scroll) with a width.  This arbitrary weirdness simply astounds me.  IE 7 has the same
        -        problem with frames, haven't tested it without.  */
        -    .FramedContentPage .IE .SBorder {
        -        width: 100% }
        -
        -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
        -    .Firefox .SBorder {
        -        -moz-border-radius: 20px }
        -
        -
        -    .STable {
        -        font-size: 8pt; width: 100% }
        -
        -    .SEntry {
        -        width: 30% }
        -    .SDescription {
        -        width: 70% }
        -
        -
        -    .SMarked {
        -        background-color: #F8F8D8 }
        -
        -    .SDescription { padding-left: 2ex }
        -    .SIndent1 .SEntry { padding-left: 1.5ex }   .SIndent1 .SDescription { padding-left: 3.5ex }
        -    .SIndent2 .SEntry { padding-left: 3.0ex }   .SIndent2 .SDescription { padding-left: 5.0ex }
        -    .SIndent3 .SEntry { padding-left: 4.5ex }   .SIndent3 .SDescription { padding-left: 6.5ex }
        -    .SIndent4 .SEntry { padding-left: 6.0ex }   .SIndent4 .SDescription { padding-left: 8.0ex }
        -    .SIndent5 .SEntry { padding-left: 7.5ex }   .SIndent5 .SDescription { padding-left: 9.5ex }
        -
        -    .SDescription a { color: #800000}
        -    .SDescription a:active { color: #A00000 }
        -
        -    .SGroup td {
        -        padding-top: .5em; padding-bottom: .25em }
        -
        -    .SGroup .SEntry {
        -        font-weight: bold; font-variant: small-caps }
        -
        -    .SGroup .SEntry a { color: #800000 }
        -    .SGroup .SEntry a:active { color: #F00000 }
        -
        -
        -    .SMain td,
        -    .SClass td,
        -    .SDatabase td,
        -    .SDatabaseTable td,
        -    .SSection td {
        -        font-size: 10pt;
        -        padding-bottom: .25em }
        -
        -    .SClass td,
        -    .SDatabase td,
        -    .SDatabaseTable td,
        -    .SSection td {
        -        padding-top: 1em }
        -
        -    .SMain .SEntry,
        -    .SClass .SEntry,
        -    .SDatabase .SEntry,
        -    .SDatabaseTable .SEntry,
        -    .SSection .SEntry {
        -        font-weight: bold;
        -        }
        -
        -    .SMain .SEntry a,
        -    .SClass .SEntry a,
        -    .SDatabase .SEntry a,
        -    .SDatabaseTable .SEntry a,
        -    .SSection .SEntry a { color: #000000 }
        -
        -    .SMain .SEntry a:active,
        -    .SClass .SEntry a:active,
        -    .SDatabase .SEntry a:active,
        -    .SDatabaseTable .SEntry a:active,
        -    .SSection .SEntry a:active { color: #A00000 }
        -
        -
        -
        -
        -
        -.ClassHierarchy {
        -    margin: 0 15px 1em 15px }
        -
        -    .CHEntry {
        -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
        -        margin-bottom: 3px;
        -        padding: 2px 2ex;
        -        font-size: 8pt;
        -        background-color: #F4F4F4; color: #606060;
        -        }
        -
        -    .Firefox .CHEntry {
        -        -moz-border-radius: 4px;
        -        }
        -
        -    .CHCurrent .CHEntry {
        -        font-weight: bold;
        -        border-color: #000000;
        -        color: #000000;
        -        }
        -
        -    .CHChildNote .CHEntry {
        -        font-style: italic;
        -        font-size: 8pt;
        -        }
        -
        -    .CHIndent {
        -        margin-left: 3ex;
        -        }
        -
        -    .CHEntry a:link,
        -    .CHEntry a:visited,
        -    .CHEntry a:hover {
        -        color: #606060;
        -        }
        -    .CHEntry a:active {
        -        color: #800000;
        -        }
        -
        -
        -
        -
        -
        -#Index {
        -    background-color: #FFFFFF;
        -    }
        -
        -/*  As opposed to .PopupSearchResultsPage #Index  */
        -.IndexPage #Index,
        -.FramedIndexPage #Index,
        -.FramedSearchResultsPage #Index {
        -    padding: 15px;
        -    }
        -
        -.IndexPage #Index {
        -    border-width: 0 0 1px 1px;
        -    border-style: solid;
        -    border-color: #000000;
        -    font-size: 8pt;  /* To make 27ex match the menu's 27ex. */
        -    margin-left: 27ex;
        -    }
        -
        -
        -    .IPageTitle {
        -        font-size: 20pt; font-weight: bold;
        -        color: #FFFFFF; background-color: #7070C0;
        -        padding: 10px 15px 10px 15px;
        -        border-width: 0 0 3px 0; border-color: #000000; border-style: solid;
        -        margin: -15px -15px 0 -15px }
        -
        -    .FramedSearchResultsPage .IPageTitle {
        -        margin-bottom: 15px;
        -        }
        -
        -    .INavigationBar {
        -        text-align: center;
        -        background-color: #FFFFF0;
        -        padding: 5px;
        -        border-bottom: solid 1px black;
        -        margin: 0 -15px 15px -15px;
        -        }
        -
        -    .INavigationBar a {
        -        font-weight: bold }
        -
        -    .IHeading {
        -        font-size: 14pt; font-weight: bold;
        -        padding: 2.5em 0 .5em 0;
        -        text-align: center;
        -        width: 3.5ex;
        -        }
        -    #IFirstHeading {
        -        padding-top: 0;
        -        }
        -
        -    .IEntry {
        -        padding-left: 1ex;
        -        }
        -    .PopupSearchResultsPage .IEntry {
        -        font-size: 8pt;
        -        padding: 1px 5px;
        -        }
        -    .PopupSearchResultsPage .Opera9 .IEntry,
        -    .FramedSearchResultsPage .Opera9 .IEntry {
        -        text-align: left;
        -        }
        -    .FramedSearchResultsPage .IEntry {
        -        padding: 0;
        -        }
        -
        -    .ISubIndex {
        -        padding-left: 3ex; padding-bottom: .5em }
        -    .PopupSearchResultsPage .ISubIndex {
        -        display: none;
        -        }
        -
        -    /*  While it may cause some entries to look like links when they aren't, I found it's much easier to read the
        -         index if everything's the same color.  */
        -    .ISymbol {
        -        font-weight: bold; color: #900000  }
        -
        -    .IndexPage .ISymbolPrefix,
        -    .FramedIndexPage .ISymbolPrefix {
        -        text-align: right;
        -        color: #C47C7C;
        -        background-color: #F8F8F8;
        -        border-right: 3px solid #E0E0E0;
        -        border-left: 1px solid #E0E0E0;
        -        padding: 0 1px 0 2px;
        -        }
        -    .PopupSearchResultsPage .ISymbolPrefix,
        -    .FramedSearchResultsPage .ISymbolPrefix {
        -        color: #900000;
        -        }
        -    .PopupSearchResultsPage .ISymbolPrefix {
        -        font-size: 8pt;
        -        }
        -
        -    .IndexPage #IFirstSymbolPrefix,
        -    .FramedIndexPage #IFirstSymbolPrefix {
        -        border-top: 1px solid #E0E0E0;
        -        }
        -    .IndexPage #ILastSymbolPrefix,
        -    .FramedIndexPage #ILastSymbolPrefix {
        -        border-bottom: 1px solid #E0E0E0;
        -        }
        -    .IndexPage #IOnlySymbolPrefix,
        -    .FramedIndexPage #IOnlySymbolPrefix {
        -        border-top: 1px solid #E0E0E0;
        -        border-bottom: 1px solid #E0E0E0;
        -        }
        -
        -    a.IParent,
        -    a.IFile {
        -        display: block;
        -        }
        -
        -    .PopupSearchResultsPage .SRStatus {
        -        padding: 2px 5px;
        -        font-size: 8pt;
        -        font-style: italic;
        -        }
        -    .FramedSearchResultsPage .SRStatus {
        -        font-size: 8pt;
        -        font-style: italic;
        -        }
        -
        -    .SRResult {
        -        display: none;
        -        }
        -
        -
        -
        -#Footer {
        -    font-size: 8pt;
        -    color: #989898;
        -    text-align: right;
        -    }
        -
        -#Footer p {
        -    text-indent: 0;
        -    margin-bottom: .5em;
        -    }
        -
        -.ContentPage #Footer,
        -.IndexPage #Footer {
        -    text-align: right;
        -    margin: 2px;
        -    }
        -
        -.FramedMenuPage #Footer {
        -    text-align: center;
        -    margin: 5em 10px 10px 10px;
        -    padding-top: 1em;
        -    border-top: 1px solid #C8C8C8;
        -    }
        -
        -    #Footer a:link,
        -    #Footer a:hover,
        -    #Footer a:visited { color: #989898 }
        -    #Footer a:active { color: #A00000 }
        -
        -
        -
        -.prettyprint .kwd { color: #800000; }  /* keywords */
        -
        -    .prettyprint.PDefaultValue .kwd,
        -    .prettyprint.PDefaultValuePrefix .kwd,
        -    .prettyprint.PTypePrefix .kwd {
        -        color: #C88F8F;
        -        }
        -
        -.prettyprint .com { color: #008000; }  /* comments */
        -
        -    .prettyprint.PDefaultValue .com,
        -    .prettyprint.PDefaultValuePrefix .com,
        -    .prettyprint.PTypePrefix .com {
        -        color: #8FC88F;
        -        }
        -
        -.prettyprint .str { color: #0000B0; }  /* strings */
        -.prettyprint .lit { color: #0000B0; }  /* literals */
        -
        -    .prettyprint.PDefaultValue .str,
        -    .prettyprint.PDefaultValuePrefix .str,
        -    .prettyprint.PTypePrefix .str,
        -    .prettyprint.PDefaultValue .lit,
        -    .prettyprint.PDefaultValuePrefix .lit,
        -    .prettyprint.PTypePrefix .lit {
        -        color: #8F8FC0;
        -        }
        -
        -.prettyprint .typ { color: #000000; }  /* types */
        -.prettyprint .pun { color: #000000; }  /* punctuation */
        -.prettyprint .pln { color: #000000; }  /* punctuation */
        -
        -    .prettyprint.PDefaultValue .typ,
        -    .prettyprint.PDefaultValuePrefix .typ,
        -    .prettyprint.PTypePrefix .typ,
        -    .prettyprint.PDefaultValue .pun,
        -    .prettyprint.PDefaultValuePrefix .pun,
        -    .prettyprint.PTypePrefix .pun,
        -    .prettyprint.PDefaultValue .pln,
        -    .prettyprint.PDefaultValuePrefix .pln,
        -    .prettyprint.PTypePrefix .pln {
        -        color: #8F8F8F;
        -        }
        -
        -.prettyprint .tag { color: #008; }
        -.prettyprint .atn { color: #606; }
        -.prettyprint .atv { color: #080; }
        -.prettyprint .dec { color: #606; }
        -
        diff --git a/vendor/openssl/README.md b/vendor/openssl/README.md
        new file mode 100644
        index 000000000..916269d39
        --- /dev/null
        +++ b/vendor/openssl/README.md
        @@ -0,0 +1,4 @@
        +# Openssl
        +
        +I do not have the time to maintain working gyp metadata for openssl,
        +i've taken the easy way out and stolen it from [node.js](http://github.com/joyent/node.git).
        diff --git a/vendor/openssl/asm/Makefile b/vendor/openssl/asm/Makefile
        new file mode 100644
        index 000000000..55d812e9d
        --- /dev/null
        +++ b/vendor/openssl/asm/Makefile
        @@ -0,0 +1,213 @@
        +SED	?= sed
        +PERL	?= perl
        +PERL	+= -I../openssl/crypto/perlasm -I../openssl/crypto/bn/asm
        +
        +OUTPUTS	= \
        +	x86-elf-gas/aes/aes-586.s \
        +	x86-elf-gas/aes/aesni-x86.s \
        +	x86-elf-gas/bf/bf-686.s \
        +	x86-elf-gas/bn/x86-mont.s \
        +	x86-elf-gas/bn/x86.s \
        +	x86-elf-gas/camellia/cmll-x86.s \
        +	x86-elf-gas/cast/cast-586.s \
        +	x86-elf-gas/des/crypt586.s \
        +	x86-elf-gas/des/des-586.s \
        +	x86-elf-gas/md5/md5-586.s \
        +	x86-elf-gas/rc4/rc4-586.s \
        +	x86-elf-gas/rc5/rc5-586.s \
        +	x86-elf-gas/ripemd/rmd-586.s \
        +	x86-elf-gas/sha/sha1-586.s \
        +	x86-elf-gas/sha/sha256-586.s \
        +	x86-elf-gas/sha/sha512-586.s \
        +	x86-elf-gas/whrlpool/wp-mmx.s \
        +	x86-elf-gas/x86cpuid.s \
        +	x64-elf-gas/aes/aes-x86_64.s \
        +	x64-elf-gas/aes/aesni-x86_64.s \
        +	x64-elf-gas/aes/aesni-sha1-x86_64.s \
        +	x64-elf-gas/bn/modexp512-x86_64.s \
        +	x64-elf-gas/bn/x86_64-mont.s \
        +	x64-elf-gas/camellia/cmll-x86_64.s \
        +	x64-elf-gas/md5/md5-x86_64.s \
        +	x64-elf-gas/rc4/rc4-x86_64.s \
        +	x64-elf-gas/rc4/rc4-md5-x86_64.s \
        +	x64-elf-gas/sha/sha1-x86_64.s \
        +	x64-elf-gas/sha/sha512-x86_64.s \
        +	x64-elf-gas/whrlpool/wp-x86_64.s \
        +	x64-elf-gas/x86_64cpuid.s \
        +	x86-macosx-gas/aes/aes-586.s \
        +	x86-macosx-gas/aes/aesni-x86.s \
        +	x86-macosx-gas/bf/bf-686.s \
        +	x86-macosx-gas/bn/x86-mont.s \
        +	x86-macosx-gas/bn/x86.s \
        +	x86-macosx-gas/camellia/cmll-x86.s \
        +	x86-macosx-gas/cast/cast-586.s \
        +	x86-macosx-gas/des/crypt586.s \
        +	x86-macosx-gas/des/des-586.s \
        +	x86-macosx-gas/md5/md5-586.s \
        +	x86-macosx-gas/rc4/rc4-586.s \
        +	x86-macosx-gas/rc5/rc5-586.s \
        +	x86-macosx-gas/ripemd/rmd-586.s \
        +	x86-macosx-gas/sha/sha1-586.s \
        +	x86-macosx-gas/sha/sha256-586.s \
        +	x86-macosx-gas/sha/sha512-586.s \
        +	x86-macosx-gas/whrlpool/wp-mmx.s \
        +	x86-macosx-gas/x86cpuid.s \
        +	x64-macosx-gas/aes/aes-x86_64.s \
        +	x64-macosx-gas/aes/aesni-x86_64.s \
        +	x64-macosx-gas/aes/aesni-sha1-x86_64.s \
        +	x64-macosx-gas/bn/modexp512-x86_64.s \
        +	x64-macosx-gas/bn/x86_64-mont.s \
        +	x64-macosx-gas/camellia/cmll-x86_64.s \
        +	x64-macosx-gas/md5/md5-x86_64.s \
        +	x64-macosx-gas/rc4/rc4-x86_64.s \
        +	x64-macosx-gas/rc4/rc4-md5-x86_64.s \
        +	x64-macosx-gas/sha/sha1-x86_64.s \
        +	x64-macosx-gas/sha/sha512-x86_64.s \
        +	x64-macosx-gas/whrlpool/wp-x86_64.s \
        +	x64-macosx-gas/x86_64cpuid.s \
        +	x86-win32-masm/aes/aes-586.asm \
        +	x86-win32-masm/aes/aesni-x86.asm \
        +	x86-win32-masm/bf/bf-686.asm \
        +	x86-win32-masm/bn/x86-mont.asm \
        +	x86-win32-masm/bn/x86.asm \
        +	x86-win32-masm/camellia/cmll-x86.asm \
        +	x86-win32-masm/cast/cast-586.asm \
        +	x86-win32-masm/des/crypt586.asm \
        +	x86-win32-masm/des/des-586.asm \
        +	x86-win32-masm/md5/md5-586.asm \
        +	x86-win32-masm/rc4/rc4-586.asm \
        +	x86-win32-masm/rc5/rc5-586.asm \
        +	x86-win32-masm/ripemd/rmd-586.asm \
        +	x86-win32-masm/sha/sha1-586.asm \
        +	x86-win32-masm/sha/sha256-586.asm \
        +	x86-win32-masm/sha/sha512-586.asm \
        +	x86-win32-masm/whrlpool/wp-mmx.asm \
        +	x86-win32-masm/x86cpuid.asm \
        +	x64-win32-masm/aes/aes-x86_64.asm \
        +	x64-win32-masm/aes/aesni-x86_64.asm \
        +	x64-win32-masm/aes/aesni-sha1-x86_64.asm \
        +	x64-win32-masm/bn/modexp512-x86_64.asm \
        +	x64-win32-masm/bn/x86_64-mont.asm \
        +	x64-win32-masm/camellia/cmll-x86_64.asm \
        +	x64-win32-masm/md5/md5-x86_64.asm \
        +	x64-win32-masm/rc4/rc4-x86_64.asm \
        +	x64-win32-masm/rc4/rc4-md5-x86_64.asm \
        +	x64-win32-masm/sha/sha1-x86_64.asm \
        +	x64-win32-masm/sha/sha512-x86_64.asm \
        +	x64-win32-masm/whrlpool/wp-x86_64.asm \
        +	x64-win32-masm/x86_64cpuid.asm \
        +
        +x64-elf-gas/%.s x86-elf-gas/%.s:
        +	$(PERL) $< elf > $@
        +
        +x64-macosx-gas/%.s x86-macosx-gas/%.s:
        +	$(PERL) $< macosx > $@
        +
        +x64-win32-masm/%.asm:
        +	$(PERL) $< masm > $@
        +
        +x86-win32-masm/%.asm:
        +	$(PERL) $< win32 > $@
        +
        +.PHONY:	all
        +all:	$(OUTPUTS)
        +	# strip trailing whitespace and final blank newline
        +	$(SED) -sri -e 's/\s+$$/\n/' -e '$$ { /^$$/d }' $^
        +
        +clean:
        +	find . -iname '*.asm' -exec rm "{}" \;
        +	find . -iname '*.s' -exec rm "{}" \;
        +
        +x64-elf-gas/aes/aes-x86_64.s: ../openssl/crypto/aes/asm/aes-x86_64.pl
        +x64-elf-gas/aes/aesni-x86_64.s: ../openssl/crypto/aes/asm/aesni-x86_64.pl
        +x64-elf-gas/aes/aesni-sha1-x86_64.s: ../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
        +x64-elf-gas/bn/modexp512-x86_64.s: ../openssl/crypto/bn/asm/modexp512-x86_64.pl
        +x64-elf-gas/bn/x86_64-mont.s: ../openssl/crypto/bn/asm/x86_64-mont.pl
        +x64-elf-gas/camellia/cmll-x86_64.s: ../openssl/crypto/camellia/asm/cmll-x86_64.pl
        +x64-elf-gas/md5/md5-x86_64.s: ../openssl/crypto/md5/asm/md5-x86_64.pl
        +x64-elf-gas/rc4/rc4-x86_64.s: ../openssl/crypto/rc4/asm/rc4-x86_64.pl
        +x64-elf-gas/rc4/rc4-md5-x86_64.s: ../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
        +x64-elf-gas/sha/sha1-x86_64.s: ../openssl/crypto/sha/asm/sha1-x86_64.pl
        +x64-elf-gas/sha/sha512-x86_64.s: ../openssl/crypto/sha/asm/sha512-x86_64.pl
        +x64-elf-gas/whrlpool/wp-x86_64.s: ../openssl/crypto/whrlpool/asm/wp-x86_64.pl
        +x64-elf-gas/x86_64cpuid.s: ../openssl/crypto/x86_64cpuid.pl
        +x64-macosx-gas/aes/aes-x86_64.s: ../openssl/crypto/aes/asm/aes-x86_64.pl
        +x64-macosx-gas/aes/aesni-x86_64.s: ../openssl/crypto/aes/asm/aesni-x86_64.pl
        +x64-macosx-gas/aes/aesni-sha1-x86_64.s: ../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
        +x64-macosx-gas/bn/modexp512-x86_64.s: ../openssl/crypto/bn/asm/modexp512-x86_64.pl
        +x64-macosx-gas/bn/x86_64-mont.s: ../openssl/crypto/bn/asm/x86_64-mont.pl
        +x64-macosx-gas/camellia/cmll-x86_64.s: ../openssl/crypto/camellia/asm/cmll-x86_64.pl
        +x64-macosx-gas/md5/md5-x86_64.s: ../openssl/crypto/md5/asm/md5-x86_64.pl
        +x64-macosx-gas/rc4/rc4-x86_64.s: ../openssl/crypto/rc4/asm/rc4-x86_64.pl
        +x64-macosx-gas/rc4/rc4-md5-x86_64.s: ../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
        +x64-macosx-gas/sha/sha1-x86_64.s: ../openssl/crypto/sha/asm/sha1-x86_64.pl
        +x64-macosx-gas/sha/sha512-x86_64.s: ../openssl/crypto/sha/asm/sha512-x86_64.pl
        +x64-macosx-gas/whrlpool/wp-x86_64.s: ../openssl/crypto/whrlpool/asm/wp-x86_64.pl
        +x64-macosx-gas/x86_64cpuid.s: ../openssl/crypto/x86_64cpuid.pl
        +x64-win32-masm/aes/aes-x86_64.asm: ../openssl/crypto/aes/asm/aes-x86_64.pl
        +x64-win32-masm/aes/aesni-x86_64.asm: ../openssl/crypto/aes/asm/aesni-x86_64.pl
        +x64-win32-masm/aes/aesni-sha1-x86_64.asm: ../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
        +x64-win32-masm/bn/modexp512-x86_64.asm: ../openssl/crypto/bn/asm/modexp512-x86_64.pl
        +x64-win32-masm/bn/x86_64-mont.asm: ../openssl/crypto/bn/asm/x86_64-mont.pl
        +x64-win32-masm/camellia/cmll-x86_64.asm: ../openssl/crypto/camellia/asm/cmll-x86_64.pl
        +x64-win32-masm/md5/md5-x86_64.asm: ../openssl/crypto/md5/asm/md5-x86_64.pl
        +x64-win32-masm/rc4/rc4-x86_64.asm: ../openssl/crypto/rc4/asm/rc4-x86_64.pl
        +x64-win32-masm/rc4/rc4-md5-x86_64.asm: ../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
        +x64-win32-masm/sha/sha1-x86_64.asm: ../openssl/crypto/sha/asm/sha1-x86_64.pl
        +x64-win32-masm/sha/sha512-x86_64.asm: ../openssl/crypto/sha/asm/sha512-x86_64.pl
        +x64-win32-masm/whrlpool/wp-x86_64.asm: ../openssl/crypto/whrlpool/asm/wp-x86_64.pl
        +x64-win32-masm/x86_64cpuid.asm: ../openssl/crypto/x86_64cpuid.pl
        +x86-elf-gas/aes/aes-586.s: ../openssl/crypto/aes/asm/aes-586.pl
        +x86-elf-gas/aes/aesni-x86.s: ../openssl/crypto/aes/asm/aesni-x86.pl
        +x86-elf-gas/bf/bf-686.s: ../openssl/crypto/bf/asm/bf-686.pl
        +x86-elf-gas/bn/x86-mont.s: ../openssl/crypto/bn/asm/x86-mont.pl
        +x86-elf-gas/bn/x86.s: ../openssl/crypto/bn/asm/x86.pl
        +x86-elf-gas/camellia/cmll-x86.s: ../openssl/crypto/camellia/asm/cmll-x86.pl
        +x86-elf-gas/cast/cast-586.s: ../openssl/crypto/cast/asm/cast-586.pl
        +x86-elf-gas/des/crypt586.s: ../openssl/crypto/des/asm/crypt586.pl
        +x86-elf-gas/des/des-586.s: ../openssl/crypto/des/asm/des-586.pl
        +x86-elf-gas/md5/md5-586.s: ../openssl/crypto/md5/asm/md5-586.pl
        +x86-elf-gas/rc4/rc4-586.s: ../openssl/crypto/rc4/asm/rc4-586.pl
        +x86-elf-gas/rc5/rc5-586.s: ../openssl/crypto/rc5/asm/rc5-586.pl
        +x86-elf-gas/ripemd/rmd-586.s: ../openssl/crypto/ripemd/asm/rmd-586.pl
        +x86-elf-gas/sha/sha1-586.s: ../openssl/crypto/sha/asm/sha1-586.pl
        +x86-elf-gas/sha/sha256-586.s: ../openssl/crypto/sha/asm/sha256-586.pl
        +x86-elf-gas/sha/sha512-586.s: ../openssl/crypto/sha/asm/sha512-586.pl
        +x86-elf-gas/whrlpool/wp-mmx.s: ../openssl/crypto/whrlpool/asm/wp-mmx.pl
        +x86-elf-gas/x86cpuid.s: ../openssl/crypto/x86cpuid.pl
        +x86-macosx-gas/aes/aes-586.s: ../openssl/crypto/aes/asm/aes-586.pl
        +x86-macosx-gas/aes/aesni-x86.s: ../openssl/crypto/aes/asm/aesni-x86.pl
        +x86-macosx-gas/bf/bf-686.s: ../openssl/crypto/bf/asm/bf-686.pl
        +x86-macosx-gas/bn/x86-mont.s: ../openssl/crypto/bn/asm/x86-mont.pl
        +x86-macosx-gas/bn/x86.s: ../openssl/crypto/bn/asm/x86.pl
        +x86-macosx-gas/camellia/cmll-x86.s: ../openssl/crypto/camellia/asm/cmll-x86.pl
        +x86-macosx-gas/cast/cast-586.s: ../openssl/crypto/cast/asm/cast-586.pl
        +x86-macosx-gas/des/crypt586.s: ../openssl/crypto/des/asm/crypt586.pl
        +x86-macosx-gas/des/des-586.s: ../openssl/crypto/des/asm/des-586.pl
        +x86-macosx-gas/md5/md5-586.s: ../openssl/crypto/md5/asm/md5-586.pl
        +x86-macosx-gas/rc4/rc4-586.s: ../openssl/crypto/rc4/asm/rc4-586.pl
        +x86-macosx-gas/rc5/rc5-586.s: ../openssl/crypto/rc5/asm/rc5-586.pl
        +x86-macosx-gas/ripemd/rmd-586.s: ../openssl/crypto/ripemd/asm/rmd-586.pl
        +x86-macosx-gas/sha/sha1-586.s: ../openssl/crypto/sha/asm/sha1-586.pl
        +x86-macosx-gas/sha/sha256-586.s: ../openssl/crypto/sha/asm/sha256-586.pl
        +x86-macosx-gas/sha/sha512-586.s: ../openssl/crypto/sha/asm/sha512-586.pl
        +x86-macosx-gas/whrlpool/wp-mmx.s: ../openssl/crypto/whrlpool/asm/wp-mmx.pl
        +x86-macosx-gas/x86cpuid.s: ../openssl/crypto/x86cpuid.pl
        +x86-win32-masm/aes/aes-586.asm: ../openssl/crypto/aes/asm/aes-586.pl
        +x86-win32-masm/aes/aesni-x86.asm: ../openssl/crypto/aes/asm/aesni-x86.pl
        +x86-win32-masm/bf/bf-686.asm: ../openssl/crypto/bf/asm/bf-686.pl
        +x86-win32-masm/bn/x86.asm: ../openssl/crypto/bn/asm/x86.pl
        +x86-win32-masm/bn/x86-mont.asm: ../openssl/crypto/bn/asm/x86-mont.pl
        +x86-win32-masm/camellia/cmll-x86.asm: ../openssl/crypto/camellia/asm/cmll-x86.pl
        +x86-win32-masm/cast/cast-586.asm: ../openssl/crypto/cast/asm/cast-586.pl
        +x86-win32-masm/des/crypt586.asm: ../openssl/crypto/des/asm/crypt586.pl
        +x86-win32-masm/des/des-586.asm: ../openssl/crypto/des/asm/des-586.pl
        +x86-win32-masm/md5/md5-586.asm: ../openssl/crypto/md5/asm/md5-586.pl
        +x86-win32-masm/rc4/rc4-586.asm: ../openssl/crypto/rc4/asm/rc4-586.pl
        +x86-win32-masm/rc5/rc5-586.asm: ../openssl/crypto/rc5/asm/rc5-586.pl
        +x86-win32-masm/ripemd/rmd-586.asm: ../openssl/crypto/ripemd/asm/rmd-586.pl
        +x86-win32-masm/sha/sha1-586.asm: ../openssl/crypto/sha/asm/sha1-586.pl
        +x86-win32-masm/sha/sha256-586.asm: ../openssl/crypto/sha/asm/sha256-586.pl
        +x86-win32-masm/sha/sha512-586.asm: ../openssl/crypto/sha/asm/sha512-586.pl
        +x86-win32-masm/whrlpool/wp-mmx.asm: ../openssl/crypto/whrlpool/asm/wp-mmx.pl
        +x86-win32-masm/x86cpuid.asm: ../openssl/crypto/x86cpuid.pl
        diff --git a/vendor/openssl/asm/x64-elf-gas/aes/aes-x86_64.s b/vendor/openssl/asm/x64-elf-gas/aes/aes-x86_64.s
        new file mode 100644
        index 000000000..e7c261fe4
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/aes/aes-x86_64.s
        @@ -0,0 +1,2554 @@
        +.text
        +
        +.type	_x86_64_AES_encrypt,@function
        +.align	16
        +_x86_64_AES_encrypt:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +
        +	movl	240(%r15),%r13d
        +	subl	$1,%r13d
        +	jmp	.Lenc_loop
        +.align	16
        +.Lenc_loop:
        +
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movl	0(%r14,%rsi,8),%r10d
        +	movl	0(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r12d
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movzbl	%dl,%ebp
        +	xorl	3(%r14,%rsi,8),%r10d
        +	xorl	3(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r8d
        +
        +	movzbl	%dh,%esi
        +	shrl	$16,%ecx
        +	movzbl	%ah,%ebp
        +	xorl	3(%r14,%rsi,8),%r12d
        +	shrl	$16,%edx
        +	xorl	3(%r14,%rbp,8),%r8d
        +
        +	shrl	$16,%ebx
        +	leaq	16(%r15),%r15
        +	shrl	$16,%eax
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	xorl	2(%r14,%rsi,8),%r10d
        +	xorl	2(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r12d
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movzbl	%bl,%ebp
        +	xorl	1(%r14,%rsi,8),%r10d
        +	xorl	1(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r8d
        +
        +	movl	12(%r15),%edx
        +	movzbl	%bh,%edi
        +	movzbl	%ch,%ebp
        +	movl	0(%r15),%eax
        +	xorl	1(%r14,%rdi,8),%r12d
        +	xorl	1(%r14,%rbp,8),%r8d
        +
        +	movl	4(%r15),%ebx
        +	movl	8(%r15),%ecx
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +	subl	$1,%r13d
        +	jnz	.Lenc_loop
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movzbl	2(%r14,%rsi,8),%r10d
        +	movzbl	2(%r14,%rdi,8),%r11d
        +	movzbl	2(%r14,%rbp,8),%r12d
        +
        +	movzbl	%dl,%esi
        +	movzbl	%bh,%edi
        +	movzbl	%ch,%ebp
        +	movzbl	2(%r14,%rsi,8),%r8d
        +	movl	0(%r14,%rdi,8),%edi
        +	movl	0(%r14,%rbp,8),%ebp
        +
        +	andl	$65280,%edi
        +	andl	$65280,%ebp
        +
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +	shrl	$16,%ecx
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	shrl	$16,%edx
        +	movl	0(%r14,%rsi,8),%esi
        +	movl	0(%r14,%rdi,8),%edi
        +
        +	andl	$65280,%esi
        +	andl	$65280,%edi
        +	shrl	$16,%ebx
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +	shrl	$16,%eax
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	movl	0(%r14,%rsi,8),%esi
        +	movl	0(%r14,%rdi,8),%edi
        +	movl	0(%r14,%rbp,8),%ebp
        +
        +	andl	$16711680,%esi
        +	andl	$16711680,%edi
        +	andl	$16711680,%ebp
        +
        +	xorl	%esi,%r10d
        +	xorl	%edi,%r11d
        +	xorl	%ebp,%r12d
        +
        +	movzbl	%bl,%esi
        +	movzbl	%dh,%edi
        +	movzbl	%ah,%ebp
        +	movl	0(%r14,%rsi,8),%esi
        +	movl	2(%r14,%rdi,8),%edi
        +	movl	2(%r14,%rbp,8),%ebp
        +
        +	andl	$16711680,%esi
        +	andl	$4278190080,%edi
        +	andl	$4278190080,%ebp
        +
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movl	16+12(%r15),%edx
        +	movl	2(%r14,%rsi,8),%esi
        +	movl	2(%r14,%rdi,8),%edi
        +	movl	16+0(%r15),%eax
        +
        +	andl	$4278190080,%esi
        +	andl	$4278190080,%edi
        +
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +
        +	movl	16+4(%r15),%ebx
        +	movl	16+8(%r15),%ecx
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_AES_encrypt,.-_x86_64_AES_encrypt
        +.type	_x86_64_AES_encrypt_compact,@function
        +.align	16
        +_x86_64_AES_encrypt_compact:
        +	leaq	128(%r14),%r8
        +	movl	0-128(%r8),%edi
        +	movl	32-128(%r8),%ebp
        +	movl	64-128(%r8),%r10d
        +	movl	96-128(%r8),%r11d
        +	movl	128-128(%r8),%edi
        +	movl	160-128(%r8),%ebp
        +	movl	192-128(%r8),%r10d
        +	movl	224-128(%r8),%r11d
        +	jmp	.Lenc_loop_compact
        +.align	16
        +.Lenc_loop_compact:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +	leaq	16(%r15),%r15
        +	movzbl	%al,%r10d
        +	movzbl	%bl,%r11d
        +	movzbl	%cl,%r12d
        +	movzbl	(%r14,%r10,1),%r10d
        +	movzbl	(%r14,%r11,1),%r11d
        +	movzbl	(%r14,%r12,1),%r12d
        +
        +	movzbl	%dl,%r8d
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movzbl	(%r14,%r8,1),%r8d
        +	movzbl	(%r14,%rsi,1),%r9d
        +	movzbl	(%r14,%rdi,1),%r13d
        +
        +	movzbl	%dh,%ebp
        +	movzbl	%ah,%esi
        +	shrl	$16,%ecx
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	shrl	$16,%edx
        +
        +	movzbl	%cl,%edi
        +	shll	$8,%r9d
        +	shll	$8,%r13d
        +	movzbl	(%r14,%rdi,1),%edi
        +	xorl	%r9d,%r10d
        +	xorl	%r13d,%r11d
        +
        +	movzbl	%dl,%r9d
        +	shrl	$16,%eax
        +	shrl	$16,%ebx
        +	movzbl	%al,%r13d
        +	shll	$8,%ebp
        +	shll	$8,%esi
        +	movzbl	(%r14,%r9,1),%r9d
        +	movzbl	(%r14,%r13,1),%r13d
        +	xorl	%ebp,%r12d
        +	xorl	%esi,%r8d
        +
        +	movzbl	%bl,%ebp
        +	movzbl	%dh,%esi
        +	shll	$16,%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	xorl	%edi,%r10d
        +
        +	movzbl	%ah,%edi
        +	shrl	$8,%ecx
        +	shrl	$8,%ebx
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rcx,1),%edx
        +	movzbl	(%r14,%rbx,1),%ecx
        +	shll	$16,%r9d
        +	shll	$16,%r13d
        +	shll	$16,%ebp
        +	xorl	%r9d,%r11d
        +	xorl	%r13d,%r12d
        +	xorl	%ebp,%r8d
        +
        +	shll	$24,%esi
        +	shll	$24,%edi
        +	shll	$24,%edx
        +	xorl	%esi,%r10d
        +	shll	$24,%ecx
        +	xorl	%edi,%r11d
        +	movl	%r10d,%eax
        +	movl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +	cmpq	16(%rsp),%r15
        +	je	.Lenc_compact_done
        +	movl	%eax,%esi
        +	movl	%ebx,%edi
        +	andl	$2155905152,%esi
        +	andl	$2155905152,%edi
        +	movl	%esi,%r10d
        +	movl	%edi,%r11d
        +	shrl	$7,%r10d
        +	leal	(%rax,%rax,1),%r8d
        +	shrl	$7,%r11d
        +	leal	(%rbx,%rbx,1),%r9d
        +	subl	%r10d,%esi
        +	subl	%r11d,%edi
        +	andl	$4278124286,%r8d
        +	andl	$4278124286,%r9d
        +	andl	$454761243,%esi
        +	andl	$454761243,%edi
        +	movl	%eax,%r10d
        +	movl	%ebx,%r11d
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r9d
        +
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movl	%ecx,%esi
        +	movl	%edx,%edi
        +	roll	$24,%eax
        +	roll	$24,%ebx
        +	andl	$2155905152,%esi
        +	andl	$2155905152,%edi
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movl	%esi,%r12d
        +	movl	%edi,%ebp
        +	rorl	$16,%r10d
        +	rorl	$16,%r11d
        +	shrl	$7,%r12d
        +	leal	(%rcx,%rcx,1),%r8d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	shrl	$7,%ebp
        +	leal	(%rdx,%rdx,1),%r9d
        +	rorl	$8,%r10d
        +	rorl	$8,%r11d
        +	subl	%r12d,%esi
        +	subl	%ebp,%edi
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +
        +	andl	$4278124286,%r8d
        +	andl	$4278124286,%r9d
        +	andl	$454761243,%esi
        +	andl	$454761243,%edi
        +	movl	%ecx,%r12d
        +	movl	%edx,%ebp
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r9d
        +
        +	xorl	%r8d,%ecx
        +	xorl	%r9d,%edx
        +	roll	$24,%ecx
        +	roll	$24,%edx
        +	xorl	%r8d,%ecx
        +	xorl	%r9d,%edx
        +	movl	0(%r14),%esi
        +	rorl	$16,%r12d
        +	rorl	$16,%ebp
        +	movl	64(%r14),%edi
        +	xorl	%r12d,%ecx
        +	xorl	%ebp,%edx
        +	movl	128(%r14),%r8d
        +	rorl	$8,%r12d
        +	rorl	$8,%ebp
        +	movl	192(%r14),%r9d
        +	xorl	%r12d,%ecx
        +	xorl	%ebp,%edx
        +	jmp	.Lenc_loop_compact
        +.align	16
        +.Lenc_compact_done:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
        +.globl	AES_encrypt
        +.type	AES_encrypt,@function
        +.align	16
        +.globl	asm_AES_encrypt
        +.hidden	asm_AES_encrypt
        +asm_AES_encrypt:
        +AES_encrypt:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +
        +	movq	%rsp,%r10
        +	leaq	-63(%rdx),%rcx
        +	andq	$-64,%rsp
        +	subq	%rsp,%rcx
        +	negq	%rcx
        +	andq	$960,%rcx
        +	subq	%rcx,%rsp
        +	subq	$32,%rsp
        +
        +	movq	%rsi,16(%rsp)
        +	movq	%r10,24(%rsp)
        +.Lenc_prologue:
        +
        +	movq	%rdx,%r15
        +	movl	240(%r15),%r13d
        +
        +	movl	0(%rdi),%eax
        +	movl	4(%rdi),%ebx
        +	movl	8(%rdi),%ecx
        +	movl	12(%rdi),%edx
        +
        +	shll	$4,%r13d
        +	leaq	(%r15,%r13,1),%rbp
        +	movq	%r15,(%rsp)
        +	movq	%rbp,8(%rsp)
        +
        +
        +	leaq	.LAES_Te+2048(%rip),%r14
        +	leaq	768(%rsp),%rbp
        +	subq	%r14,%rbp
        +	andq	$768,%rbp
        +	leaq	(%r14,%rbp,1),%r14
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	movq	16(%rsp),%r9
        +	movq	24(%rsp),%rsi
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lenc_epilogue:
        +	.byte	0xf3,0xc3
        +.size	AES_encrypt,.-AES_encrypt
        +.type	_x86_64_AES_decrypt,@function
        +.align	16
        +_x86_64_AES_decrypt:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +
        +	movl	240(%r15),%r13d
        +	subl	$1,%r13d
        +	jmp	.Ldec_loop
        +.align	16
        +.Ldec_loop:
        +
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movl	0(%r14,%rsi,8),%r10d
        +	movl	0(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r12d
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movzbl	%dl,%ebp
        +	xorl	3(%r14,%rsi,8),%r10d
        +	xorl	3(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r8d
        +
        +	movzbl	%bh,%esi
        +	shrl	$16,%eax
        +	movzbl	%ch,%ebp
        +	xorl	3(%r14,%rsi,8),%r12d
        +	shrl	$16,%edx
        +	xorl	3(%r14,%rbp,8),%r8d
        +
        +	shrl	$16,%ebx
        +	leaq	16(%r15),%r15
        +	shrl	$16,%ecx
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	xorl	2(%r14,%rsi,8),%r10d
        +	xorl	2(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r12d
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movzbl	%bl,%ebp
        +	xorl	1(%r14,%rsi,8),%r10d
        +	xorl	1(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r8d
        +
        +	movzbl	%dh,%esi
        +	movl	12(%r15),%edx
        +	movzbl	%ah,%ebp
        +	xorl	1(%r14,%rsi,8),%r12d
        +	movl	0(%r15),%eax
        +	xorl	1(%r14,%rbp,8),%r8d
        +
        +	xorl	%r10d,%eax
        +	movl	4(%r15),%ebx
        +	movl	8(%r15),%ecx
        +	xorl	%r12d,%ecx
        +	xorl	%r11d,%ebx
        +	xorl	%r8d,%edx
        +	subl	$1,%r13d
        +	jnz	.Ldec_loop
        +	leaq	2048(%r14),%r14
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movzbl	(%r14,%rsi,1),%r10d
        +	movzbl	(%r14,%rdi,1),%r11d
        +	movzbl	(%r14,%rbp,1),%r12d
        +
        +	movzbl	%dl,%esi
        +	movzbl	%dh,%edi
        +	movzbl	%ah,%ebp
        +	movzbl	(%r14,%rsi,1),%r8d
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +
        +	shll	$8,%edi
        +	shll	$8,%ebp
        +
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +	shrl	$16,%edx
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	shrl	$16,%eax
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +
        +	shll	$8,%esi
        +	shll	$8,%edi
        +	shrl	$16,%ebx
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +	shrl	$16,%ecx
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +
        +	shll	$16,%esi
        +	shll	$16,%edi
        +	shll	$16,%ebp
        +
        +	xorl	%esi,%r10d
        +	xorl	%edi,%r11d
        +	xorl	%ebp,%r12d
        +
        +	movzbl	%bl,%esi
        +	movzbl	%bh,%edi
        +	movzbl	%ch,%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +
        +	shll	$16,%esi
        +	shll	$24,%edi
        +	shll	$24,%ebp
        +
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movl	16+12(%r15),%edx
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +	movl	16+0(%r15),%eax
        +
        +	shll	$24,%esi
        +	shll	$24,%edi
        +
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +
        +	movl	16+4(%r15),%ebx
        +	movl	16+8(%r15),%ecx
        +	leaq	-2048(%r14),%r14
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_AES_decrypt,.-_x86_64_AES_decrypt
        +.type	_x86_64_AES_decrypt_compact,@function
        +.align	16
        +_x86_64_AES_decrypt_compact:
        +	leaq	128(%r14),%r8
        +	movl	0-128(%r8),%edi
        +	movl	32-128(%r8),%ebp
        +	movl	64-128(%r8),%r10d
        +	movl	96-128(%r8),%r11d
        +	movl	128-128(%r8),%edi
        +	movl	160-128(%r8),%ebp
        +	movl	192-128(%r8),%r10d
        +	movl	224-128(%r8),%r11d
        +	jmp	.Ldec_loop_compact
        +
        +.align	16
        +.Ldec_loop_compact:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +	leaq	16(%r15),%r15
        +	movzbl	%al,%r10d
        +	movzbl	%bl,%r11d
        +	movzbl	%cl,%r12d
        +	movzbl	(%r14,%r10,1),%r10d
        +	movzbl	(%r14,%r11,1),%r11d
        +	movzbl	(%r14,%r12,1),%r12d
        +
        +	movzbl	%dl,%r8d
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movzbl	(%r14,%r8,1),%r8d
        +	movzbl	(%r14,%rsi,1),%r9d
        +	movzbl	(%r14,%rdi,1),%r13d
        +
        +	movzbl	%bh,%ebp
        +	movzbl	%ch,%esi
        +	shrl	$16,%ecx
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	shrl	$16,%edx
        +
        +	movzbl	%cl,%edi
        +	shll	$8,%r9d
        +	shll	$8,%r13d
        +	movzbl	(%r14,%rdi,1),%edi
        +	xorl	%r9d,%r10d
        +	xorl	%r13d,%r11d
        +
        +	movzbl	%dl,%r9d
        +	shrl	$16,%eax
        +	shrl	$16,%ebx
        +	movzbl	%al,%r13d
        +	shll	$8,%ebp
        +	shll	$8,%esi
        +	movzbl	(%r14,%r9,1),%r9d
        +	movzbl	(%r14,%r13,1),%r13d
        +	xorl	%ebp,%r12d
        +	xorl	%esi,%r8d
        +
        +	movzbl	%bl,%ebp
        +	movzbl	%bh,%esi
        +	shll	$16,%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	xorl	%edi,%r10d
        +
        +	movzbl	%ch,%edi
        +	shll	$16,%r9d
        +	shll	$16,%r13d
        +	movzbl	(%r14,%rdi,1),%ebx
        +	xorl	%r9d,%r11d
        +	xorl	%r13d,%r12d
        +
        +	movzbl	%dh,%edi
        +	shrl	$8,%eax
        +	shll	$16,%ebp
        +	movzbl	(%r14,%rdi,1),%ecx
        +	movzbl	(%r14,%rax,1),%edx
        +	xorl	%ebp,%r8d
        +
        +	shll	$24,%esi
        +	shll	$24,%ebx
        +	shll	$24,%ecx
        +	xorl	%esi,%r10d
        +	shll	$24,%edx
        +	xorl	%r11d,%ebx
        +	movl	%r10d,%eax
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +	cmpq	16(%rsp),%r15
        +	je	.Ldec_compact_done
        +
        +	movq	256+0(%r14),%rsi
        +	shlq	$32,%rbx
        +	shlq	$32,%rdx
        +	movq	256+8(%r14),%rdi
        +	orq	%rbx,%rax
        +	orq	%rdx,%rcx
        +	movq	256+16(%r14),%rbp
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +	shrq	$7,%r9
        +	leaq	(%rax,%rax,1),%r8
        +	shrq	$7,%r12
        +	leaq	(%rcx,%rcx,1),%r11
        +	subq	%r9,%rbx
        +	subq	%r12,%rdx
        +	andq	%rdi,%r8
        +	andq	%rdi,%r11
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r8,%rbx
        +	xorq	%r11,%rdx
        +	movq	%rbx,%r8
        +	movq	%rdx,%r11
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	leaq	(%r8,%r8,1),%r9
        +	shrq	$7,%r13
        +	leaq	(%r11,%r11,1),%r12
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	andq	%rdi,%r9
        +	andq	%rdi,%r12
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r9,%rbx
        +	xorq	%r12,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	xorq	%rax,%r8
        +	shrq	$7,%r13
        +	xorq	%rcx,%r11
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	leaq	(%r9,%r9,1),%r10
        +	leaq	(%r12,%r12,1),%r13
        +	xorq	%rax,%r9
        +	xorq	%rcx,%r12
        +	andq	%rdi,%r10
        +	andq	%rdi,%r13
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%rbx,%r10
        +	xorq	%rdx,%r13
        +
        +	xorq	%r10,%rax
        +	xorq	%r13,%rcx
        +	xorq	%r10,%r8
        +	xorq	%r13,%r11
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	xorq	%r10,%r9
        +	xorq	%r13,%r12
        +	shrq	$32,%rbx
        +	shrq	$32,%rdx
        +	xorq	%r8,%r10
        +	xorq	%r11,%r13
        +	roll	$8,%eax
        +	roll	$8,%ecx
        +	xorq	%r9,%r10
        +	xorq	%r12,%r13
        +
        +	roll	$8,%ebx
        +	roll	$8,%edx
        +	xorl	%r10d,%eax
        +	xorl	%r13d,%ecx
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +	movq	%r8,%r10
        +	movq	%r11,%r13
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	roll	$24,%r8d
        +	roll	$24,%r11d
        +	roll	$24,%r10d
        +	roll	$24,%r13d
        +	xorl	%r8d,%eax
        +	xorl	%r11d,%ecx
        +	movq	%r9,%r8
        +	movq	%r12,%r11
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +	movq	0(%r14),%rsi
        +	shrq	$32,%r8
        +	shrq	$32,%r11
        +	movq	64(%r14),%rdi
        +	roll	$16,%r9d
        +	roll	$16,%r12d
        +	movq	128(%r14),%rbp
        +	roll	$16,%r8d
        +	roll	$16,%r11d
        +	movq	192(%r14),%r10
        +	xorl	%r9d,%eax
        +	xorl	%r12d,%ecx
        +	movq	256(%r14),%r13
        +	xorl	%r8d,%ebx
        +	xorl	%r11d,%edx
        +	jmp	.Ldec_loop_compact
        +.align	16
        +.Ldec_compact_done:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
        +.globl	AES_decrypt
        +.type	AES_decrypt,@function
        +.align	16
        +.globl	asm_AES_decrypt
        +.hidden	asm_AES_decrypt
        +asm_AES_decrypt:
        +AES_decrypt:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +
        +	movq	%rsp,%r10
        +	leaq	-63(%rdx),%rcx
        +	andq	$-64,%rsp
        +	subq	%rsp,%rcx
        +	negq	%rcx
        +	andq	$960,%rcx
        +	subq	%rcx,%rsp
        +	subq	$32,%rsp
        +
        +	movq	%rsi,16(%rsp)
        +	movq	%r10,24(%rsp)
        +.Ldec_prologue:
        +
        +	movq	%rdx,%r15
        +	movl	240(%r15),%r13d
        +
        +	movl	0(%rdi),%eax
        +	movl	4(%rdi),%ebx
        +	movl	8(%rdi),%ecx
        +	movl	12(%rdi),%edx
        +
        +	shll	$4,%r13d
        +	leaq	(%r15,%r13,1),%rbp
        +	movq	%r15,(%rsp)
        +	movq	%rbp,8(%rsp)
        +
        +
        +	leaq	.LAES_Td+2048(%rip),%r14
        +	leaq	768(%rsp),%rbp
        +	subq	%r14,%rbp
        +	andq	$768,%rbp
        +	leaq	(%r14,%rbp,1),%r14
        +	shrq	$3,%rbp
        +	addq	%rbp,%r14
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	movq	16(%rsp),%r9
        +	movq	24(%rsp),%rsi
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Ldec_epilogue:
        +	.byte	0xf3,0xc3
        +.size	AES_decrypt,.-AES_decrypt
        +.globl	private_AES_set_encrypt_key
        +.type	private_AES_set_encrypt_key,@function
        +.align	16
        +private_AES_set_encrypt_key:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	subq	$8,%rsp
        +.Lenc_key_prologue:
        +
        +	call	_x86_64_AES_set_encrypt_key
        +
        +	movq	8(%rsp),%r15
        +	movq	16(%rsp),%r14
        +	movq	24(%rsp),%r13
        +	movq	32(%rsp),%r12
        +	movq	40(%rsp),%rbp
        +	movq	48(%rsp),%rbx
        +	addq	$56,%rsp
        +.Lenc_key_epilogue:
        +	.byte	0xf3,0xc3
        +.size	private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
        +
        +.type	_x86_64_AES_set_encrypt_key,@function
        +.align	16
        +_x86_64_AES_set_encrypt_key:
        +	movl	%esi,%ecx
        +	movq	%rdi,%rsi
        +	movq	%rdx,%rdi
        +
        +	testq	$-1,%rsi
        +	jz	.Lbadpointer
        +	testq	$-1,%rdi
        +	jz	.Lbadpointer
        +
        +	leaq	.LAES_Te(%rip),%rbp
        +	leaq	2048+128(%rbp),%rbp
        +
        +
        +	movl	0-128(%rbp),%eax
        +	movl	32-128(%rbp),%ebx
        +	movl	64-128(%rbp),%r8d
        +	movl	96-128(%rbp),%edx
        +	movl	128-128(%rbp),%eax
        +	movl	160-128(%rbp),%ebx
        +	movl	192-128(%rbp),%r8d
        +	movl	224-128(%rbp),%edx
        +
        +	cmpl	$128,%ecx
        +	je	.L10rounds
        +	cmpl	$192,%ecx
        +	je	.L12rounds
        +	cmpl	$256,%ecx
        +	je	.L14rounds
        +	movq	$-2,%rax
        +	jmp	.Lexit
        +
        +.L10rounds:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rdx,8(%rdi)
        +
        +	shrq	$32,%rdx
        +	xorl	%ecx,%ecx
        +	jmp	.L10shortcut
        +.align	4
        +.L10loop:
        +	movl	0(%rdi),%eax
        +	movl	12(%rdi),%edx
        +.L10shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	xorl	1024-128(%rbp,%rcx,4),%eax
        +	movl	%eax,16(%rdi)
        +	xorl	4(%rdi),%eax
        +	movl	%eax,20(%rdi)
        +	xorl	8(%rdi),%eax
        +	movl	%eax,24(%rdi)
        +	xorl	12(%rdi),%eax
        +	movl	%eax,28(%rdi)
        +	addl	$1,%ecx
        +	leaq	16(%rdi),%rdi
        +	cmpl	$10,%ecx
        +	jl	.L10loop
        +
        +	movl	$10,80(%rdi)
        +	xorq	%rax,%rax
        +	jmp	.Lexit
        +
        +.L12rounds:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	16(%rsi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rbx,8(%rdi)
        +	movq	%rdx,16(%rdi)
        +
        +	shrq	$32,%rdx
        +	xorl	%ecx,%ecx
        +	jmp	.L12shortcut
        +.align	4
        +.L12loop:
        +	movl	0(%rdi),%eax
        +	movl	20(%rdi),%edx
        +.L12shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	xorl	1024-128(%rbp,%rcx,4),%eax
        +	movl	%eax,24(%rdi)
        +	xorl	4(%rdi),%eax
        +	movl	%eax,28(%rdi)
        +	xorl	8(%rdi),%eax
        +	movl	%eax,32(%rdi)
        +	xorl	12(%rdi),%eax
        +	movl	%eax,36(%rdi)
        +
        +	cmpl	$7,%ecx
        +	je	.L12break
        +	addl	$1,%ecx
        +
        +	xorl	16(%rdi),%eax
        +	movl	%eax,40(%rdi)
        +	xorl	20(%rdi),%eax
        +	movl	%eax,44(%rdi)
        +
        +	leaq	24(%rdi),%rdi
        +	jmp	.L12loop
        +.L12break:
        +	movl	$12,72(%rdi)
        +	xorq	%rax,%rax
        +	jmp	.Lexit
        +
        +.L14rounds:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	16(%rsi),%rcx
        +	movq	24(%rsi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rbx,8(%rdi)
        +	movq	%rcx,16(%rdi)
        +	movq	%rdx,24(%rdi)
        +
        +	shrq	$32,%rdx
        +	xorl	%ecx,%ecx
        +	jmp	.L14shortcut
        +.align	4
        +.L14loop:
        +	movl	0(%rdi),%eax
        +	movl	28(%rdi),%edx
        +.L14shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	xorl	1024-128(%rbp,%rcx,4),%eax
        +	movl	%eax,32(%rdi)
        +	xorl	4(%rdi),%eax
        +	movl	%eax,36(%rdi)
        +	xorl	8(%rdi),%eax
        +	movl	%eax,40(%rdi)
        +	xorl	12(%rdi),%eax
        +	movl	%eax,44(%rdi)
        +
        +	cmpl	$6,%ecx
        +	je	.L14break
        +	addl	$1,%ecx
        +
        +	movl	%eax,%edx
        +	movl	16(%rdi),%eax
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	shll	$8,%ebx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movl	%eax,48(%rdi)
        +	xorl	20(%rdi),%eax
        +	movl	%eax,52(%rdi)
        +	xorl	24(%rdi),%eax
        +	movl	%eax,56(%rdi)
        +	xorl	28(%rdi),%eax
        +	movl	%eax,60(%rdi)
        +
        +	leaq	32(%rdi),%rdi
        +	jmp	.L14loop
        +.L14break:
        +	movl	$14,48(%rdi)
        +	xorq	%rax,%rax
        +	jmp	.Lexit
        +
        +.Lbadpointer:
        +	movq	$-1,%rax
        +.Lexit:
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
        +.globl	private_AES_set_decrypt_key
        +.type	private_AES_set_decrypt_key,@function
        +.align	16
        +private_AES_set_decrypt_key:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	pushq	%rdx
        +.Ldec_key_prologue:
        +
        +	call	_x86_64_AES_set_encrypt_key
        +	movq	(%rsp),%r8
        +	cmpl	$0,%eax
        +	jne	.Labort
        +
        +	movl	240(%r8),%r14d
        +	xorq	%rdi,%rdi
        +	leaq	(%rdi,%r14,4),%rcx
        +	movq	%r8,%rsi
        +	leaq	(%r8,%rcx,4),%rdi
        +.align	4
        +.Linvert:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	0(%rdi),%rcx
        +	movq	8(%rdi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rbx,8(%rdi)
        +	movq	%rcx,0(%rsi)
        +	movq	%rdx,8(%rsi)
        +	leaq	16(%rsi),%rsi
        +	leaq	-16(%rdi),%rdi
        +	cmpq	%rsi,%rdi
        +	jne	.Linvert
        +
        +	leaq	.LAES_Te+2048+1024(%rip),%rax
        +
        +	movq	40(%rax),%rsi
        +	movq	48(%rax),%rdi
        +	movq	56(%rax),%rbp
        +
        +	movq	%r8,%r15
        +	subl	$1,%r14d
        +.align	4
        +.Lpermute:
        +	leaq	16(%r15),%r15
        +	movq	0(%r15),%rax
        +	movq	8(%r15),%rcx
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +	shrq	$7,%r9
        +	leaq	(%rax,%rax,1),%r8
        +	shrq	$7,%r12
        +	leaq	(%rcx,%rcx,1),%r11
        +	subq	%r9,%rbx
        +	subq	%r12,%rdx
        +	andq	%rdi,%r8
        +	andq	%rdi,%r11
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r8,%rbx
        +	xorq	%r11,%rdx
        +	movq	%rbx,%r8
        +	movq	%rdx,%r11
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	leaq	(%r8,%r8,1),%r9
        +	shrq	$7,%r13
        +	leaq	(%r11,%r11,1),%r12
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	andq	%rdi,%r9
        +	andq	%rdi,%r12
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r9,%rbx
        +	xorq	%r12,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	xorq	%rax,%r8
        +	shrq	$7,%r13
        +	xorq	%rcx,%r11
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	leaq	(%r9,%r9,1),%r10
        +	leaq	(%r12,%r12,1),%r13
        +	xorq	%rax,%r9
        +	xorq	%rcx,%r12
        +	andq	%rdi,%r10
        +	andq	%rdi,%r13
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%rbx,%r10
        +	xorq	%rdx,%r13
        +
        +	xorq	%r10,%rax
        +	xorq	%r13,%rcx
        +	xorq	%r10,%r8
        +	xorq	%r13,%r11
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	xorq	%r10,%r9
        +	xorq	%r13,%r12
        +	shrq	$32,%rbx
        +	shrq	$32,%rdx
        +	xorq	%r8,%r10
        +	xorq	%r11,%r13
        +	roll	$8,%eax
        +	roll	$8,%ecx
        +	xorq	%r9,%r10
        +	xorq	%r12,%r13
        +
        +	roll	$8,%ebx
        +	roll	$8,%edx
        +	xorl	%r10d,%eax
        +	xorl	%r13d,%ecx
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +	movq	%r8,%r10
        +	movq	%r11,%r13
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	roll	$24,%r8d
        +	roll	$24,%r11d
        +	roll	$24,%r10d
        +	roll	$24,%r13d
        +	xorl	%r8d,%eax
        +	xorl	%r11d,%ecx
        +	movq	%r9,%r8
        +	movq	%r12,%r11
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +
        +	shrq	$32,%r8
        +	shrq	$32,%r11
        +
        +	roll	$16,%r9d
        +	roll	$16,%r12d
        +
        +	roll	$16,%r8d
        +	roll	$16,%r11d
        +
        +	xorl	%r9d,%eax
        +	xorl	%r12d,%ecx
        +
        +	xorl	%r8d,%ebx
        +	xorl	%r11d,%edx
        +	movl	%eax,0(%r15)
        +	movl	%ebx,4(%r15)
        +	movl	%ecx,8(%r15)
        +	movl	%edx,12(%r15)
        +	subl	$1,%r14d
        +	jnz	.Lpermute
        +
        +	xorq	%rax,%rax
        +.Labort:
        +	movq	8(%rsp),%r15
        +	movq	16(%rsp),%r14
        +	movq	24(%rsp),%r13
        +	movq	32(%rsp),%r12
        +	movq	40(%rsp),%rbp
        +	movq	48(%rsp),%rbx
        +	addq	$56,%rsp
        +.Ldec_key_epilogue:
        +	.byte	0xf3,0xc3
        +.size	private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
        +.globl	AES_cbc_encrypt
        +.type	AES_cbc_encrypt,@function
        +.align	16
        +
        +.globl	asm_AES_cbc_encrypt
        +.hidden	asm_AES_cbc_encrypt
        +asm_AES_cbc_encrypt:
        +AES_cbc_encrypt:
        +	cmpq	$0,%rdx
        +	je	.Lcbc_epilogue
        +	pushfq
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +.Lcbc_prologue:
        +
        +	cld
        +	movl	%r9d,%r9d
        +
        +	leaq	.LAES_Te(%rip),%r14
        +	cmpq	$0,%r9
        +	jne	.Lcbc_picked_te
        +	leaq	.LAES_Td(%rip),%r14
        +.Lcbc_picked_te:
        +
        +	movl	OPENSSL_ia32cap_P(%rip),%r10d
        +	cmpq	$512,%rdx
        +	jb	.Lcbc_slow_prologue
        +	testq	$15,%rdx
        +	jnz	.Lcbc_slow_prologue
        +
        +
        +
        +
        +	leaq	-88-248(%rsp),%r15
        +	andq	$-64,%r15
        +
        +
        +	movq	%r14,%r10
        +	leaq	2304(%r14),%r11
        +	movq	%r15,%r12
        +	andq	$4095,%r10
        +	andq	$4095,%r11
        +	andq	$4095,%r12
        +
        +	cmpq	%r11,%r12
        +	jb	.Lcbc_te_break_out
        +	subq	%r11,%r12
        +	subq	%r12,%r15
        +	jmp	.Lcbc_te_ok
        +.Lcbc_te_break_out:
        +	subq	%r10,%r12
        +	andq	$4095,%r12
        +	addq	$320,%r12
        +	subq	%r12,%r15
        +.align	4
        +.Lcbc_te_ok:
        +
        +	xchgq	%rsp,%r15
        +
        +	movq	%r15,16(%rsp)
        +.Lcbc_fast_body:
        +	movq	%rdi,24(%rsp)
        +	movq	%rsi,32(%rsp)
        +	movq	%rdx,40(%rsp)
        +	movq	%rcx,48(%rsp)
        +	movq	%r8,56(%rsp)
        +	movl	$0,80+240(%rsp)
        +	movq	%r8,%rbp
        +	movq	%r9,%rbx
        +	movq	%rsi,%r9
        +	movq	%rdi,%r8
        +	movq	%rcx,%r15
        +
        +	movl	240(%r15),%eax
        +
        +	movq	%r15,%r10
        +	subq	%r14,%r10
        +	andq	$4095,%r10
        +	cmpq	$2304,%r10
        +	jb	.Lcbc_do_ecopy
        +	cmpq	$4096-248,%r10
        +	jb	.Lcbc_skip_ecopy
        +.align	4
        +.Lcbc_do_ecopy:
        +	movq	%r15,%rsi
        +	leaq	80(%rsp),%rdi
        +	leaq	80(%rsp),%r15
        +	movl	$30,%ecx
        +.long	0x90A548F3
        +
        +	movl	%eax,(%rdi)
        +.Lcbc_skip_ecopy:
        +	movq	%r15,0(%rsp)
        +
        +	movl	$18,%ecx
        +.align	4
        +.Lcbc_prefetch_te:
        +	movq	0(%r14),%r10
        +	movq	32(%r14),%r11
        +	movq	64(%r14),%r12
        +	movq	96(%r14),%r13
        +	leaq	128(%r14),%r14
        +	subl	$1,%ecx
        +	jnz	.Lcbc_prefetch_te
        +	leaq	-2304(%r14),%r14
        +
        +	cmpq	$0,%rbx
        +	je	.LFAST_DECRYPT
        +
        +
        +	movl	0(%rbp),%eax
        +	movl	4(%rbp),%ebx
        +	movl	8(%rbp),%ecx
        +	movl	12(%rbp),%edx
        +
        +.align	4
        +.Lcbc_fast_enc_loop:
        +	xorl	0(%r8),%eax
        +	xorl	4(%r8),%ebx
        +	xorl	8(%r8),%ecx
        +	xorl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +
        +	call	_x86_64_AES_encrypt
        +
        +	movq	24(%rsp),%r8
        +	movq	40(%rsp),%r10
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	subq	$16,%r10
        +	testq	$-16,%r10
        +	movq	%r10,40(%rsp)
        +	jnz	.Lcbc_fast_enc_loop
        +	movq	56(%rsp),%rbp
        +	movl	%eax,0(%rbp)
        +	movl	%ebx,4(%rbp)
        +	movl	%ecx,8(%rbp)
        +	movl	%edx,12(%rbp)
        +
        +	jmp	.Lcbc_fast_cleanup
        +
        +
        +.align	16
        +.LFAST_DECRYPT:
        +	cmpq	%r8,%r9
        +	je	.Lcbc_fast_dec_in_place
        +
        +	movq	%rbp,64(%rsp)
        +.align	4
        +.Lcbc_fast_dec_loop:
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +
        +	call	_x86_64_AES_decrypt
        +
        +	movq	64(%rsp),%rbp
        +	movq	24(%rsp),%r8
        +	movq	40(%rsp),%r10
        +	xorl	0(%rbp),%eax
        +	xorl	4(%rbp),%ebx
        +	xorl	8(%rbp),%ecx
        +	xorl	12(%rbp),%edx
        +	movq	%r8,%rbp
        +
        +	subq	$16,%r10
        +	movq	%r10,40(%rsp)
        +	movq	%rbp,64(%rsp)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	jnz	.Lcbc_fast_dec_loop
        +	movq	56(%rsp),%r12
        +	movq	0(%rbp),%r10
        +	movq	8(%rbp),%r11
        +	movq	%r10,0(%r12)
        +	movq	%r11,8(%r12)
        +	jmp	.Lcbc_fast_cleanup
        +
        +.align	16
        +.Lcbc_fast_dec_in_place:
        +	movq	0(%rbp),%r10
        +	movq	8(%rbp),%r11
        +	movq	%r10,0+64(%rsp)
        +	movq	%r11,8+64(%rsp)
        +.align	4
        +.Lcbc_fast_dec_in_place_loop:
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +
        +	call	_x86_64_AES_decrypt
        +
        +	movq	24(%rsp),%r8
        +	movq	40(%rsp),%r10
        +	xorl	0+64(%rsp),%eax
        +	xorl	4+64(%rsp),%ebx
        +	xorl	8+64(%rsp),%ecx
        +	xorl	12+64(%rsp),%edx
        +
        +	movq	0(%r8),%r11
        +	movq	8(%r8),%r12
        +	subq	$16,%r10
        +	jz	.Lcbc_fast_dec_in_place_done
        +
        +	movq	%r11,0+64(%rsp)
        +	movq	%r12,8+64(%rsp)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	movq	%r10,40(%rsp)
        +	jmp	.Lcbc_fast_dec_in_place_loop
        +.Lcbc_fast_dec_in_place_done:
        +	movq	56(%rsp),%rdi
        +	movq	%r11,0(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +.align	4
        +.Lcbc_fast_cleanup:
        +	cmpl	$0,80+240(%rsp)
        +	leaq	80(%rsp),%rdi
        +	je	.Lcbc_exit
        +	movl	$30,%ecx
        +	xorq	%rax,%rax
        +.long	0x90AB48F3
        +
        +
        +	jmp	.Lcbc_exit
        +
        +
        +.align	16
        +.Lcbc_slow_prologue:
        +
        +	leaq	-88(%rsp),%rbp
        +	andq	$-64,%rbp
        +
        +	leaq	-88-63(%rcx),%r10
        +	subq	%rbp,%r10
        +	negq	%r10
        +	andq	$960,%r10
        +	subq	%r10,%rbp
        +
        +	xchgq	%rsp,%rbp
        +
        +	movq	%rbp,16(%rsp)
        +.Lcbc_slow_body:
        +
        +
        +
        +
        +	movq	%r8,56(%rsp)
        +	movq	%r8,%rbp
        +	movq	%r9,%rbx
        +	movq	%rsi,%r9
        +	movq	%rdi,%r8
        +	movq	%rcx,%r15
        +	movq	%rdx,%r10
        +
        +	movl	240(%r15),%eax
        +	movq	%r15,0(%rsp)
        +	shll	$4,%eax
        +	leaq	(%r15,%rax,1),%rax
        +	movq	%rax,8(%rsp)
        +
        +
        +	leaq	2048(%r14),%r14
        +	leaq	768-8(%rsp),%rax
        +	subq	%r14,%rax
        +	andq	$768,%rax
        +	leaq	(%r14,%rax,1),%r14
        +
        +	cmpq	$0,%rbx
        +	je	.LSLOW_DECRYPT
        +
        +
        +	testq	$-16,%r10
        +	movl	0(%rbp),%eax
        +	movl	4(%rbp),%ebx
        +	movl	8(%rbp),%ecx
        +	movl	12(%rbp),%edx
        +	jz	.Lcbc_slow_enc_tail
        +
        +
        +.align	4
        +.Lcbc_slow_enc_loop:
        +	xorl	0(%r8),%eax
        +	xorl	4(%r8),%ebx
        +	xorl	8(%r8),%ecx
        +	xorl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +	movq	%r9,32(%rsp)
        +	movq	%r10,40(%rsp)
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	movq	24(%rsp),%r8
        +	movq	32(%rsp),%r9
        +	movq	40(%rsp),%r10
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	subq	$16,%r10
        +	testq	$-16,%r10
        +	jnz	.Lcbc_slow_enc_loop
        +	testq	$15,%r10
        +	jnz	.Lcbc_slow_enc_tail
        +	movq	56(%rsp),%rbp
        +	movl	%eax,0(%rbp)
        +	movl	%ebx,4(%rbp)
        +	movl	%ecx,8(%rbp)
        +	movl	%edx,12(%rbp)
        +
        +	jmp	.Lcbc_exit
        +
        +.align	4
        +.Lcbc_slow_enc_tail:
        +	movq	%rax,%r11
        +	movq	%rcx,%r12
        +	movq	%r10,%rcx
        +	movq	%r8,%rsi
        +	movq	%r9,%rdi
        +.long	0x9066A4F3
        +
        +	movq	$16,%rcx
        +	subq	%r10,%rcx
        +	xorq	%rax,%rax
        +.long	0x9066AAF3
        +
        +	movq	%r9,%r8
        +	movq	$16,%r10
        +	movq	%r11,%rax
        +	movq	%r12,%rcx
        +	jmp	.Lcbc_slow_enc_loop
        +
        +
        +.align	16
        +.LSLOW_DECRYPT:
        +	shrq	$3,%rax
        +	addq	%rax,%r14
        +
        +	movq	0(%rbp),%r11
        +	movq	8(%rbp),%r12
        +	movq	%r11,0+64(%rsp)
        +	movq	%r12,8+64(%rsp)
        +
        +.align	4
        +.Lcbc_slow_dec_loop:
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +	movq	%r9,32(%rsp)
        +	movq	%r10,40(%rsp)
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	movq	24(%rsp),%r8
        +	movq	32(%rsp),%r9
        +	movq	40(%rsp),%r10
        +	xorl	0+64(%rsp),%eax
        +	xorl	4+64(%rsp),%ebx
        +	xorl	8+64(%rsp),%ecx
        +	xorl	12+64(%rsp),%edx
        +
        +	movq	0(%r8),%r11
        +	movq	8(%r8),%r12
        +	subq	$16,%r10
        +	jc	.Lcbc_slow_dec_partial
        +	jz	.Lcbc_slow_dec_done
        +
        +	movq	%r11,0+64(%rsp)
        +	movq	%r12,8+64(%rsp)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	jmp	.Lcbc_slow_dec_loop
        +.Lcbc_slow_dec_done:
        +	movq	56(%rsp),%rdi
        +	movq	%r11,0(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	jmp	.Lcbc_exit
        +
        +.align	4
        +.Lcbc_slow_dec_partial:
        +	movq	56(%rsp),%rdi
        +	movq	%r11,0(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	movl	%eax,0+64(%rsp)
        +	movl	%ebx,4+64(%rsp)
        +	movl	%ecx,8+64(%rsp)
        +	movl	%edx,12+64(%rsp)
        +
        +	movq	%r9,%rdi
        +	leaq	64(%rsp),%rsi
        +	leaq	16(%r10),%rcx
        +.long	0x9066A4F3
        +
        +	jmp	.Lcbc_exit
        +
        +.align	16
        +.Lcbc_exit:
        +	movq	16(%rsp),%rsi
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lcbc_popfq:
        +	popfq
        +.Lcbc_epilogue:
        +	.byte	0xf3,0xc3
        +.size	AES_cbc_encrypt,.-AES_cbc_encrypt
        +.align	64
        +.LAES_Te:
        +.long	0xa56363c6,0xa56363c6
        +.long	0x847c7cf8,0x847c7cf8
        +.long	0x997777ee,0x997777ee
        +.long	0x8d7b7bf6,0x8d7b7bf6
        +.long	0x0df2f2ff,0x0df2f2ff
        +.long	0xbd6b6bd6,0xbd6b6bd6
        +.long	0xb16f6fde,0xb16f6fde
        +.long	0x54c5c591,0x54c5c591
        +.long	0x50303060,0x50303060
        +.long	0x03010102,0x03010102
        +.long	0xa96767ce,0xa96767ce
        +.long	0x7d2b2b56,0x7d2b2b56
        +.long	0x19fefee7,0x19fefee7
        +.long	0x62d7d7b5,0x62d7d7b5
        +.long	0xe6abab4d,0xe6abab4d
        +.long	0x9a7676ec,0x9a7676ec
        +.long	0x45caca8f,0x45caca8f
        +.long	0x9d82821f,0x9d82821f
        +.long	0x40c9c989,0x40c9c989
        +.long	0x877d7dfa,0x877d7dfa
        +.long	0x15fafaef,0x15fafaef
        +.long	0xeb5959b2,0xeb5959b2
        +.long	0xc947478e,0xc947478e
        +.long	0x0bf0f0fb,0x0bf0f0fb
        +.long	0xecadad41,0xecadad41
        +.long	0x67d4d4b3,0x67d4d4b3
        +.long	0xfda2a25f,0xfda2a25f
        +.long	0xeaafaf45,0xeaafaf45
        +.long	0xbf9c9c23,0xbf9c9c23
        +.long	0xf7a4a453,0xf7a4a453
        +.long	0x967272e4,0x967272e4
        +.long	0x5bc0c09b,0x5bc0c09b
        +.long	0xc2b7b775,0xc2b7b775
        +.long	0x1cfdfde1,0x1cfdfde1
        +.long	0xae93933d,0xae93933d
        +.long	0x6a26264c,0x6a26264c
        +.long	0x5a36366c,0x5a36366c
        +.long	0x413f3f7e,0x413f3f7e
        +.long	0x02f7f7f5,0x02f7f7f5
        +.long	0x4fcccc83,0x4fcccc83
        +.long	0x5c343468,0x5c343468
        +.long	0xf4a5a551,0xf4a5a551
        +.long	0x34e5e5d1,0x34e5e5d1
        +.long	0x08f1f1f9,0x08f1f1f9
        +.long	0x937171e2,0x937171e2
        +.long	0x73d8d8ab,0x73d8d8ab
        +.long	0x53313162,0x53313162
        +.long	0x3f15152a,0x3f15152a
        +.long	0x0c040408,0x0c040408
        +.long	0x52c7c795,0x52c7c795
        +.long	0x65232346,0x65232346
        +.long	0x5ec3c39d,0x5ec3c39d
        +.long	0x28181830,0x28181830
        +.long	0xa1969637,0xa1969637
        +.long	0x0f05050a,0x0f05050a
        +.long	0xb59a9a2f,0xb59a9a2f
        +.long	0x0907070e,0x0907070e
        +.long	0x36121224,0x36121224
        +.long	0x9b80801b,0x9b80801b
        +.long	0x3de2e2df,0x3de2e2df
        +.long	0x26ebebcd,0x26ebebcd
        +.long	0x6927274e,0x6927274e
        +.long	0xcdb2b27f,0xcdb2b27f
        +.long	0x9f7575ea,0x9f7575ea
        +.long	0x1b090912,0x1b090912
        +.long	0x9e83831d,0x9e83831d
        +.long	0x742c2c58,0x742c2c58
        +.long	0x2e1a1a34,0x2e1a1a34
        +.long	0x2d1b1b36,0x2d1b1b36
        +.long	0xb26e6edc,0xb26e6edc
        +.long	0xee5a5ab4,0xee5a5ab4
        +.long	0xfba0a05b,0xfba0a05b
        +.long	0xf65252a4,0xf65252a4
        +.long	0x4d3b3b76,0x4d3b3b76
        +.long	0x61d6d6b7,0x61d6d6b7
        +.long	0xceb3b37d,0xceb3b37d
        +.long	0x7b292952,0x7b292952
        +.long	0x3ee3e3dd,0x3ee3e3dd
        +.long	0x712f2f5e,0x712f2f5e
        +.long	0x97848413,0x97848413
        +.long	0xf55353a6,0xf55353a6
        +.long	0x68d1d1b9,0x68d1d1b9
        +.long	0x00000000,0x00000000
        +.long	0x2cededc1,0x2cededc1
        +.long	0x60202040,0x60202040
        +.long	0x1ffcfce3,0x1ffcfce3
        +.long	0xc8b1b179,0xc8b1b179
        +.long	0xed5b5bb6,0xed5b5bb6
        +.long	0xbe6a6ad4,0xbe6a6ad4
        +.long	0x46cbcb8d,0x46cbcb8d
        +.long	0xd9bebe67,0xd9bebe67
        +.long	0x4b393972,0x4b393972
        +.long	0xde4a4a94,0xde4a4a94
        +.long	0xd44c4c98,0xd44c4c98
        +.long	0xe85858b0,0xe85858b0
        +.long	0x4acfcf85,0x4acfcf85
        +.long	0x6bd0d0bb,0x6bd0d0bb
        +.long	0x2aefefc5,0x2aefefc5
        +.long	0xe5aaaa4f,0xe5aaaa4f
        +.long	0x16fbfbed,0x16fbfbed
        +.long	0xc5434386,0xc5434386
        +.long	0xd74d4d9a,0xd74d4d9a
        +.long	0x55333366,0x55333366
        +.long	0x94858511,0x94858511
        +.long	0xcf45458a,0xcf45458a
        +.long	0x10f9f9e9,0x10f9f9e9
        +.long	0x06020204,0x06020204
        +.long	0x817f7ffe,0x817f7ffe
        +.long	0xf05050a0,0xf05050a0
        +.long	0x443c3c78,0x443c3c78
        +.long	0xba9f9f25,0xba9f9f25
        +.long	0xe3a8a84b,0xe3a8a84b
        +.long	0xf35151a2,0xf35151a2
        +.long	0xfea3a35d,0xfea3a35d
        +.long	0xc0404080,0xc0404080
        +.long	0x8a8f8f05,0x8a8f8f05
        +.long	0xad92923f,0xad92923f
        +.long	0xbc9d9d21,0xbc9d9d21
        +.long	0x48383870,0x48383870
        +.long	0x04f5f5f1,0x04f5f5f1
        +.long	0xdfbcbc63,0xdfbcbc63
        +.long	0xc1b6b677,0xc1b6b677
        +.long	0x75dadaaf,0x75dadaaf
        +.long	0x63212142,0x63212142
        +.long	0x30101020,0x30101020
        +.long	0x1affffe5,0x1affffe5
        +.long	0x0ef3f3fd,0x0ef3f3fd
        +.long	0x6dd2d2bf,0x6dd2d2bf
        +.long	0x4ccdcd81,0x4ccdcd81
        +.long	0x140c0c18,0x140c0c18
        +.long	0x35131326,0x35131326
        +.long	0x2fececc3,0x2fececc3
        +.long	0xe15f5fbe,0xe15f5fbe
        +.long	0xa2979735,0xa2979735
        +.long	0xcc444488,0xcc444488
        +.long	0x3917172e,0x3917172e
        +.long	0x57c4c493,0x57c4c493
        +.long	0xf2a7a755,0xf2a7a755
        +.long	0x827e7efc,0x827e7efc
        +.long	0x473d3d7a,0x473d3d7a
        +.long	0xac6464c8,0xac6464c8
        +.long	0xe75d5dba,0xe75d5dba
        +.long	0x2b191932,0x2b191932
        +.long	0x957373e6,0x957373e6
        +.long	0xa06060c0,0xa06060c0
        +.long	0x98818119,0x98818119
        +.long	0xd14f4f9e,0xd14f4f9e
        +.long	0x7fdcdca3,0x7fdcdca3
        +.long	0x66222244,0x66222244
        +.long	0x7e2a2a54,0x7e2a2a54
        +.long	0xab90903b,0xab90903b
        +.long	0x8388880b,0x8388880b
        +.long	0xca46468c,0xca46468c
        +.long	0x29eeeec7,0x29eeeec7
        +.long	0xd3b8b86b,0xd3b8b86b
        +.long	0x3c141428,0x3c141428
        +.long	0x79dedea7,0x79dedea7
        +.long	0xe25e5ebc,0xe25e5ebc
        +.long	0x1d0b0b16,0x1d0b0b16
        +.long	0x76dbdbad,0x76dbdbad
        +.long	0x3be0e0db,0x3be0e0db
        +.long	0x56323264,0x56323264
        +.long	0x4e3a3a74,0x4e3a3a74
        +.long	0x1e0a0a14,0x1e0a0a14
        +.long	0xdb494992,0xdb494992
        +.long	0x0a06060c,0x0a06060c
        +.long	0x6c242448,0x6c242448
        +.long	0xe45c5cb8,0xe45c5cb8
        +.long	0x5dc2c29f,0x5dc2c29f
        +.long	0x6ed3d3bd,0x6ed3d3bd
        +.long	0xefacac43,0xefacac43
        +.long	0xa66262c4,0xa66262c4
        +.long	0xa8919139,0xa8919139
        +.long	0xa4959531,0xa4959531
        +.long	0x37e4e4d3,0x37e4e4d3
        +.long	0x8b7979f2,0x8b7979f2
        +.long	0x32e7e7d5,0x32e7e7d5
        +.long	0x43c8c88b,0x43c8c88b
        +.long	0x5937376e,0x5937376e
        +.long	0xb76d6dda,0xb76d6dda
        +.long	0x8c8d8d01,0x8c8d8d01
        +.long	0x64d5d5b1,0x64d5d5b1
        +.long	0xd24e4e9c,0xd24e4e9c
        +.long	0xe0a9a949,0xe0a9a949
        +.long	0xb46c6cd8,0xb46c6cd8
        +.long	0xfa5656ac,0xfa5656ac
        +.long	0x07f4f4f3,0x07f4f4f3
        +.long	0x25eaeacf,0x25eaeacf
        +.long	0xaf6565ca,0xaf6565ca
        +.long	0x8e7a7af4,0x8e7a7af4
        +.long	0xe9aeae47,0xe9aeae47
        +.long	0x18080810,0x18080810
        +.long	0xd5baba6f,0xd5baba6f
        +.long	0x887878f0,0x887878f0
        +.long	0x6f25254a,0x6f25254a
        +.long	0x722e2e5c,0x722e2e5c
        +.long	0x241c1c38,0x241c1c38
        +.long	0xf1a6a657,0xf1a6a657
        +.long	0xc7b4b473,0xc7b4b473
        +.long	0x51c6c697,0x51c6c697
        +.long	0x23e8e8cb,0x23e8e8cb
        +.long	0x7cdddda1,0x7cdddda1
        +.long	0x9c7474e8,0x9c7474e8
        +.long	0x211f1f3e,0x211f1f3e
        +.long	0xdd4b4b96,0xdd4b4b96
        +.long	0xdcbdbd61,0xdcbdbd61
        +.long	0x868b8b0d,0x868b8b0d
        +.long	0x858a8a0f,0x858a8a0f
        +.long	0x907070e0,0x907070e0
        +.long	0x423e3e7c,0x423e3e7c
        +.long	0xc4b5b571,0xc4b5b571
        +.long	0xaa6666cc,0xaa6666cc
        +.long	0xd8484890,0xd8484890
        +.long	0x05030306,0x05030306
        +.long	0x01f6f6f7,0x01f6f6f7
        +.long	0x120e0e1c,0x120e0e1c
        +.long	0xa36161c2,0xa36161c2
        +.long	0x5f35356a,0x5f35356a
        +.long	0xf95757ae,0xf95757ae
        +.long	0xd0b9b969,0xd0b9b969
        +.long	0x91868617,0x91868617
        +.long	0x58c1c199,0x58c1c199
        +.long	0x271d1d3a,0x271d1d3a
        +.long	0xb99e9e27,0xb99e9e27
        +.long	0x38e1e1d9,0x38e1e1d9
        +.long	0x13f8f8eb,0x13f8f8eb
        +.long	0xb398982b,0xb398982b
        +.long	0x33111122,0x33111122
        +.long	0xbb6969d2,0xbb6969d2
        +.long	0x70d9d9a9,0x70d9d9a9
        +.long	0x898e8e07,0x898e8e07
        +.long	0xa7949433,0xa7949433
        +.long	0xb69b9b2d,0xb69b9b2d
        +.long	0x221e1e3c,0x221e1e3c
        +.long	0x92878715,0x92878715
        +.long	0x20e9e9c9,0x20e9e9c9
        +.long	0x49cece87,0x49cece87
        +.long	0xff5555aa,0xff5555aa
        +.long	0x78282850,0x78282850
        +.long	0x7adfdfa5,0x7adfdfa5
        +.long	0x8f8c8c03,0x8f8c8c03
        +.long	0xf8a1a159,0xf8a1a159
        +.long	0x80898909,0x80898909
        +.long	0x170d0d1a,0x170d0d1a
        +.long	0xdabfbf65,0xdabfbf65
        +.long	0x31e6e6d7,0x31e6e6d7
        +.long	0xc6424284,0xc6424284
        +.long	0xb86868d0,0xb86868d0
        +.long	0xc3414182,0xc3414182
        +.long	0xb0999929,0xb0999929
        +.long	0x772d2d5a,0x772d2d5a
        +.long	0x110f0f1e,0x110f0f1e
        +.long	0xcbb0b07b,0xcbb0b07b
        +.long	0xfc5454a8,0xfc5454a8
        +.long	0xd6bbbb6d,0xd6bbbb6d
        +.long	0x3a16162c,0x3a16162c
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
        +.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
        +.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
        +.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
        +.align	64
        +.LAES_Td:
        +.long	0x50a7f451,0x50a7f451
        +.long	0x5365417e,0x5365417e
        +.long	0xc3a4171a,0xc3a4171a
        +.long	0x965e273a,0x965e273a
        +.long	0xcb6bab3b,0xcb6bab3b
        +.long	0xf1459d1f,0xf1459d1f
        +.long	0xab58faac,0xab58faac
        +.long	0x9303e34b,0x9303e34b
        +.long	0x55fa3020,0x55fa3020
        +.long	0xf66d76ad,0xf66d76ad
        +.long	0x9176cc88,0x9176cc88
        +.long	0x254c02f5,0x254c02f5
        +.long	0xfcd7e54f,0xfcd7e54f
        +.long	0xd7cb2ac5,0xd7cb2ac5
        +.long	0x80443526,0x80443526
        +.long	0x8fa362b5,0x8fa362b5
        +.long	0x495ab1de,0x495ab1de
        +.long	0x671bba25,0x671bba25
        +.long	0x980eea45,0x980eea45
        +.long	0xe1c0fe5d,0xe1c0fe5d
        +.long	0x02752fc3,0x02752fc3
        +.long	0x12f04c81,0x12f04c81
        +.long	0xa397468d,0xa397468d
        +.long	0xc6f9d36b,0xc6f9d36b
        +.long	0xe75f8f03,0xe75f8f03
        +.long	0x959c9215,0x959c9215
        +.long	0xeb7a6dbf,0xeb7a6dbf
        +.long	0xda595295,0xda595295
        +.long	0x2d83bed4,0x2d83bed4
        +.long	0xd3217458,0xd3217458
        +.long	0x2969e049,0x2969e049
        +.long	0x44c8c98e,0x44c8c98e
        +.long	0x6a89c275,0x6a89c275
        +.long	0x78798ef4,0x78798ef4
        +.long	0x6b3e5899,0x6b3e5899
        +.long	0xdd71b927,0xdd71b927
        +.long	0xb64fe1be,0xb64fe1be
        +.long	0x17ad88f0,0x17ad88f0
        +.long	0x66ac20c9,0x66ac20c9
        +.long	0xb43ace7d,0xb43ace7d
        +.long	0x184adf63,0x184adf63
        +.long	0x82311ae5,0x82311ae5
        +.long	0x60335197,0x60335197
        +.long	0x457f5362,0x457f5362
        +.long	0xe07764b1,0xe07764b1
        +.long	0x84ae6bbb,0x84ae6bbb
        +.long	0x1ca081fe,0x1ca081fe
        +.long	0x942b08f9,0x942b08f9
        +.long	0x58684870,0x58684870
        +.long	0x19fd458f,0x19fd458f
        +.long	0x876cde94,0x876cde94
        +.long	0xb7f87b52,0xb7f87b52
        +.long	0x23d373ab,0x23d373ab
        +.long	0xe2024b72,0xe2024b72
        +.long	0x578f1fe3,0x578f1fe3
        +.long	0x2aab5566,0x2aab5566
        +.long	0x0728ebb2,0x0728ebb2
        +.long	0x03c2b52f,0x03c2b52f
        +.long	0x9a7bc586,0x9a7bc586
        +.long	0xa50837d3,0xa50837d3
        +.long	0xf2872830,0xf2872830
        +.long	0xb2a5bf23,0xb2a5bf23
        +.long	0xba6a0302,0xba6a0302
        +.long	0x5c8216ed,0x5c8216ed
        +.long	0x2b1ccf8a,0x2b1ccf8a
        +.long	0x92b479a7,0x92b479a7
        +.long	0xf0f207f3,0xf0f207f3
        +.long	0xa1e2694e,0xa1e2694e
        +.long	0xcdf4da65,0xcdf4da65
        +.long	0xd5be0506,0xd5be0506
        +.long	0x1f6234d1,0x1f6234d1
        +.long	0x8afea6c4,0x8afea6c4
        +.long	0x9d532e34,0x9d532e34
        +.long	0xa055f3a2,0xa055f3a2
        +.long	0x32e18a05,0x32e18a05
        +.long	0x75ebf6a4,0x75ebf6a4
        +.long	0x39ec830b,0x39ec830b
        +.long	0xaaef6040,0xaaef6040
        +.long	0x069f715e,0x069f715e
        +.long	0x51106ebd,0x51106ebd
        +.long	0xf98a213e,0xf98a213e
        +.long	0x3d06dd96,0x3d06dd96
        +.long	0xae053edd,0xae053edd
        +.long	0x46bde64d,0x46bde64d
        +.long	0xb58d5491,0xb58d5491
        +.long	0x055dc471,0x055dc471
        +.long	0x6fd40604,0x6fd40604
        +.long	0xff155060,0xff155060
        +.long	0x24fb9819,0x24fb9819
        +.long	0x97e9bdd6,0x97e9bdd6
        +.long	0xcc434089,0xcc434089
        +.long	0x779ed967,0x779ed967
        +.long	0xbd42e8b0,0xbd42e8b0
        +.long	0x888b8907,0x888b8907
        +.long	0x385b19e7,0x385b19e7
        +.long	0xdbeec879,0xdbeec879
        +.long	0x470a7ca1,0x470a7ca1
        +.long	0xe90f427c,0xe90f427c
        +.long	0xc91e84f8,0xc91e84f8
        +.long	0x00000000,0x00000000
        +.long	0x83868009,0x83868009
        +.long	0x48ed2b32,0x48ed2b32
        +.long	0xac70111e,0xac70111e
        +.long	0x4e725a6c,0x4e725a6c
        +.long	0xfbff0efd,0xfbff0efd
        +.long	0x5638850f,0x5638850f
        +.long	0x1ed5ae3d,0x1ed5ae3d
        +.long	0x27392d36,0x27392d36
        +.long	0x64d90f0a,0x64d90f0a
        +.long	0x21a65c68,0x21a65c68
        +.long	0xd1545b9b,0xd1545b9b
        +.long	0x3a2e3624,0x3a2e3624
        +.long	0xb1670a0c,0xb1670a0c
        +.long	0x0fe75793,0x0fe75793
        +.long	0xd296eeb4,0xd296eeb4
        +.long	0x9e919b1b,0x9e919b1b
        +.long	0x4fc5c080,0x4fc5c080
        +.long	0xa220dc61,0xa220dc61
        +.long	0x694b775a,0x694b775a
        +.long	0x161a121c,0x161a121c
        +.long	0x0aba93e2,0x0aba93e2
        +.long	0xe52aa0c0,0xe52aa0c0
        +.long	0x43e0223c,0x43e0223c
        +.long	0x1d171b12,0x1d171b12
        +.long	0x0b0d090e,0x0b0d090e
        +.long	0xadc78bf2,0xadc78bf2
        +.long	0xb9a8b62d,0xb9a8b62d
        +.long	0xc8a91e14,0xc8a91e14
        +.long	0x8519f157,0x8519f157
        +.long	0x4c0775af,0x4c0775af
        +.long	0xbbdd99ee,0xbbdd99ee
        +.long	0xfd607fa3,0xfd607fa3
        +.long	0x9f2601f7,0x9f2601f7
        +.long	0xbcf5725c,0xbcf5725c
        +.long	0xc53b6644,0xc53b6644
        +.long	0x347efb5b,0x347efb5b
        +.long	0x7629438b,0x7629438b
        +.long	0xdcc623cb,0xdcc623cb
        +.long	0x68fcedb6,0x68fcedb6
        +.long	0x63f1e4b8,0x63f1e4b8
        +.long	0xcadc31d7,0xcadc31d7
        +.long	0x10856342,0x10856342
        +.long	0x40229713,0x40229713
        +.long	0x2011c684,0x2011c684
        +.long	0x7d244a85,0x7d244a85
        +.long	0xf83dbbd2,0xf83dbbd2
        +.long	0x1132f9ae,0x1132f9ae
        +.long	0x6da129c7,0x6da129c7
        +.long	0x4b2f9e1d,0x4b2f9e1d
        +.long	0xf330b2dc,0xf330b2dc
        +.long	0xec52860d,0xec52860d
        +.long	0xd0e3c177,0xd0e3c177
        +.long	0x6c16b32b,0x6c16b32b
        +.long	0x99b970a9,0x99b970a9
        +.long	0xfa489411,0xfa489411
        +.long	0x2264e947,0x2264e947
        +.long	0xc48cfca8,0xc48cfca8
        +.long	0x1a3ff0a0,0x1a3ff0a0
        +.long	0xd82c7d56,0xd82c7d56
        +.long	0xef903322,0xef903322
        +.long	0xc74e4987,0xc74e4987
        +.long	0xc1d138d9,0xc1d138d9
        +.long	0xfea2ca8c,0xfea2ca8c
        +.long	0x360bd498,0x360bd498
        +.long	0xcf81f5a6,0xcf81f5a6
        +.long	0x28de7aa5,0x28de7aa5
        +.long	0x268eb7da,0x268eb7da
        +.long	0xa4bfad3f,0xa4bfad3f
        +.long	0xe49d3a2c,0xe49d3a2c
        +.long	0x0d927850,0x0d927850
        +.long	0x9bcc5f6a,0x9bcc5f6a
        +.long	0x62467e54,0x62467e54
        +.long	0xc2138df6,0xc2138df6
        +.long	0xe8b8d890,0xe8b8d890
        +.long	0x5ef7392e,0x5ef7392e
        +.long	0xf5afc382,0xf5afc382
        +.long	0xbe805d9f,0xbe805d9f
        +.long	0x7c93d069,0x7c93d069
        +.long	0xa92dd56f,0xa92dd56f
        +.long	0xb31225cf,0xb31225cf
        +.long	0x3b99acc8,0x3b99acc8
        +.long	0xa77d1810,0xa77d1810
        +.long	0x6e639ce8,0x6e639ce8
        +.long	0x7bbb3bdb,0x7bbb3bdb
        +.long	0x097826cd,0x097826cd
        +.long	0xf418596e,0xf418596e
        +.long	0x01b79aec,0x01b79aec
        +.long	0xa89a4f83,0xa89a4f83
        +.long	0x656e95e6,0x656e95e6
        +.long	0x7ee6ffaa,0x7ee6ffaa
        +.long	0x08cfbc21,0x08cfbc21
        +.long	0xe6e815ef,0xe6e815ef
        +.long	0xd99be7ba,0xd99be7ba
        +.long	0xce366f4a,0xce366f4a
        +.long	0xd4099fea,0xd4099fea
        +.long	0xd67cb029,0xd67cb029
        +.long	0xafb2a431,0xafb2a431
        +.long	0x31233f2a,0x31233f2a
        +.long	0x3094a5c6,0x3094a5c6
        +.long	0xc066a235,0xc066a235
        +.long	0x37bc4e74,0x37bc4e74
        +.long	0xa6ca82fc,0xa6ca82fc
        +.long	0xb0d090e0,0xb0d090e0
        +.long	0x15d8a733,0x15d8a733
        +.long	0x4a9804f1,0x4a9804f1
        +.long	0xf7daec41,0xf7daec41
        +.long	0x0e50cd7f,0x0e50cd7f
        +.long	0x2ff69117,0x2ff69117
        +.long	0x8dd64d76,0x8dd64d76
        +.long	0x4db0ef43,0x4db0ef43
        +.long	0x544daacc,0x544daacc
        +.long	0xdf0496e4,0xdf0496e4
        +.long	0xe3b5d19e,0xe3b5d19e
        +.long	0x1b886a4c,0x1b886a4c
        +.long	0xb81f2cc1,0xb81f2cc1
        +.long	0x7f516546,0x7f516546
        +.long	0x04ea5e9d,0x04ea5e9d
        +.long	0x5d358c01,0x5d358c01
        +.long	0x737487fa,0x737487fa
        +.long	0x2e410bfb,0x2e410bfb
        +.long	0x5a1d67b3,0x5a1d67b3
        +.long	0x52d2db92,0x52d2db92
        +.long	0x335610e9,0x335610e9
        +.long	0x1347d66d,0x1347d66d
        +.long	0x8c61d79a,0x8c61d79a
        +.long	0x7a0ca137,0x7a0ca137
        +.long	0x8e14f859,0x8e14f859
        +.long	0x893c13eb,0x893c13eb
        +.long	0xee27a9ce,0xee27a9ce
        +.long	0x35c961b7,0x35c961b7
        +.long	0xede51ce1,0xede51ce1
        +.long	0x3cb1477a,0x3cb1477a
        +.long	0x59dfd29c,0x59dfd29c
        +.long	0x3f73f255,0x3f73f255
        +.long	0x79ce1418,0x79ce1418
        +.long	0xbf37c773,0xbf37c773
        +.long	0xeacdf753,0xeacdf753
        +.long	0x5baafd5f,0x5baafd5f
        +.long	0x146f3ddf,0x146f3ddf
        +.long	0x86db4478,0x86db4478
        +.long	0x81f3afca,0x81f3afca
        +.long	0x3ec468b9,0x3ec468b9
        +.long	0x2c342438,0x2c342438
        +.long	0x5f40a3c2,0x5f40a3c2
        +.long	0x72c31d16,0x72c31d16
        +.long	0x0c25e2bc,0x0c25e2bc
        +.long	0x8b493c28,0x8b493c28
        +.long	0x41950dff,0x41950dff
        +.long	0x7101a839,0x7101a839
        +.long	0xdeb30c08,0xdeb30c08
        +.long	0x9ce4b4d8,0x9ce4b4d8
        +.long	0x90c15664,0x90c15664
        +.long	0x6184cb7b,0x6184cb7b
        +.long	0x70b632d5,0x70b632d5
        +.long	0x745c6c48,0x745c6c48
        +.long	0x4257b8d0,0x4257b8d0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	65,69,83,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	64
        diff --git a/vendor/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s b/vendor/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s
        new file mode 100644
        index 000000000..8f0475e0d
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s
        @@ -0,0 +1,1402 @@
        +.text
        +
        +
        +
        +.globl	aesni_cbc_sha1_enc
        +.type	aesni_cbc_sha1_enc,@function
        +.align	16
        +aesni_cbc_sha1_enc:
        +
        +	movl	OPENSSL_ia32cap_P+0(%rip),%r10d
        +	movl	OPENSSL_ia32cap_P+4(%rip),%r11d
        +	jmp	aesni_cbc_sha1_enc_ssse3
        +	.byte	0xf3,0xc3
        +.size	aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc
        +.type	aesni_cbc_sha1_enc_ssse3,@function
        +.align	16
        +aesni_cbc_sha1_enc_ssse3:
        +	movq	8(%rsp),%r10
        +
        +
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	leaq	-104(%rsp),%rsp
        +
        +
        +	movq	%rdi,%r12
        +	movq	%rsi,%r13
        +	movq	%rdx,%r14
        +	movq	%rcx,%r15
        +	movdqu	(%r8),%xmm11
        +	movq	%r8,88(%rsp)
        +	shlq	$6,%r14
        +	subq	%r12,%r13
        +	movl	240(%r15),%r8d
        +	addq	%r10,%r14
        +
        +	leaq	K_XX_XX(%rip),%r11
        +	movl	0(%r9),%eax
        +	movl	4(%r9),%ebx
        +	movl	8(%r9),%ecx
        +	movl	12(%r9),%edx
        +	movl	%ebx,%esi
        +	movl	16(%r9),%ebp
        +
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r10),%xmm0
        +	movdqu	16(%r10),%xmm1
        +	movdqu	32(%r10),%xmm2
        +	movdqu	48(%r10),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r10
        +.byte	102,15,56,0,206
        +.byte	102,15,56,0,214
        +.byte	102,15,56,0,222
        +	paddd	%xmm9,%xmm0
        +	paddd	%xmm9,%xmm1
        +	paddd	%xmm9,%xmm2
        +	movdqa	%xmm0,0(%rsp)
        +	psubd	%xmm9,%xmm0
        +	movdqa	%xmm1,16(%rsp)
        +	psubd	%xmm9,%xmm1
        +	movdqa	%xmm2,32(%rsp)
        +	psubd	%xmm9,%xmm2
        +	movups	(%r15),%xmm13
        +	movups	16(%r15),%xmm14
        +	jmp	.Loop_ssse3
        +.align	16
        +.Loop_ssse3:
        +	movdqa	%xmm1,%xmm4
        +	addl	0(%rsp),%ebp
        +	movups	0(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	xorl	%edx,%ecx
        +	movdqa	%xmm3,%xmm8
        +.byte	102,15,58,15,224,8
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	paddd	%xmm3,%xmm9
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrldq	$4,%xmm8
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	pxor	%xmm0,%xmm4
        +	rorl	$2,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm2,%xmm8
        +	addl	4(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pxor	%xmm8,%xmm4
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm9,48(%rsp)
        +	xorl	%ecx,%edi
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	addl	%ebp,%edx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm4,%xmm8
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	8(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	pslldq	$12,%xmm10
        +	paddd	%xmm4,%xmm4
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrld	$31,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm4
        +	addl	12(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm4
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	0(%r11),%xmm10
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	pxor	%xmm9,%xmm4
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movdqa	%xmm2,%xmm5
        +	addl	16(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movdqa	%xmm4,%xmm9
        +.byte	102,15,58,15,233,8
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	paddd	%xmm4,%xmm10
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrldq	$4,%xmm9
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	pxor	%xmm1,%xmm5
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm3,%xmm9
        +	addl	20(%rsp),%ebp
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pxor	%xmm9,%xmm5
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	%xmm10,0(%rsp)
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm5,%xmm9
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	24(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	pslldq	$12,%xmm8
        +	paddd	%xmm5,%xmm5
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	psrld	$31,%xmm9
        +	xorl	%ecx,%esi
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	addl	%ebp,%edx
        +	movdqa	%xmm8,%xmm10
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	psrld	$30,%xmm8
        +	por	%xmm9,%xmm5
        +	addl	28(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	pslld	$2,%xmm10
        +	pxor	%xmm8,%xmm5
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	16(%r11),%xmm8
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	pxor	%xmm10,%xmm5
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movdqa	%xmm3,%xmm6
        +	addl	32(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movdqa	%xmm5,%xmm10
        +.byte	102,15,58,15,242,8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	paddd	%xmm5,%xmm8
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	psrldq	$4,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	pxor	%xmm2,%xmm6
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm4,%xmm10
        +	addl	36(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	pxor	%xmm10,%xmm6
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm8,16(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm6,%xmm10
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	40(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%ecx
        +	pslldq	$12,%xmm9
        +	paddd	%xmm6,%xmm6
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrld	$31,%xmm10
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	psrld	$30,%xmm9
        +	por	%xmm10,%xmm6
        +	addl	44(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pslld	$2,%xmm8
        +	pxor	%xmm9,%xmm6
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	16(%r11),%xmm9
        +	xorl	%ecx,%edi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%ebp,%edx
        +	pxor	%xmm8,%xmm6
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movdqa	%xmm4,%xmm7
        +	addl	48(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm8
        +.byte	102,15,58,15,251,8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm6,%xmm9
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrldq	$4,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	pxor	%xmm3,%xmm7
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm5,%xmm8
        +	addl	52(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	pxor	%xmm8,%xmm7
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm7,%xmm8
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	56(%rsp),%eax
        +	xorl	%ebp,%edx
        +	pslldq	$12,%xmm10
        +	paddd	%xmm7,%xmm7
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrld	$31,%xmm8
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm7
        +	addl	60(%rsp),%ebp
        +	cmpl	$11,%r8d
        +	jb	.Laesenclast1
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	.Laesenclast1
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +.Laesenclast1:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm7
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	16(%r11),%xmm10
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	pxor	%xmm9,%xmm7
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movdqa	%xmm7,%xmm9
        +	addl	0(%rsp),%edx
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,206,8
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm1,%xmm0
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm7,%xmm10
        +	xorl	%ecx,%esi
        +	movups	16(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	movups	%xmm11,0(%r13,%r12,1)
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	addl	%ebp,%edx
        +	pxor	%xmm9,%xmm0
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	4(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm0,%xmm9
        +	movdqa	%xmm10,48(%rsp)
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	pslld	$2,%xmm0
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	psrld	$30,%xmm9
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	8(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	por	%xmm9,%xmm0
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm0,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	12(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	16(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,215,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm2,%xmm1
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm0,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm10,%xmm1
        +	addl	20(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm1,%xmm10
        +	movdqa	%xmm8,0(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm1
        +	addl	24(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm10
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm10,%xmm1
        +	addl	28(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movdqa	%xmm1,%xmm8
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	32(%rsp),%eax
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,192,8
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	pxor	%xmm3,%xmm2
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	movdqa	32(%r11),%xmm10
        +	paddd	%xmm1,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm8,%xmm2
        +	addl	36(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	movdqa	%xmm2,%xmm8
        +	movdqa	%xmm9,16(%rsp)
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	pslld	$2,%xmm2
        +	addl	40(%rsp),%edx
        +	xorl	%ecx,%esi
        +	psrld	$30,%xmm8
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	por	%xmm8,%xmm2
        +	addl	44(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movdqa	%xmm2,%xmm9
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	48(%rsp),%ebx
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,201,8
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	pxor	%xmm4,%xmm3
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm2,%xmm10
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm9,%xmm3
        +	addl	52(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	movdqa	%xmm3,%xmm9
        +	movdqa	%xmm10,32(%rsp)
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%esi
        +	psrld	$30,%xmm9
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	por	%xmm9,%xmm3
        +	addl	60(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movdqa	%xmm3,%xmm10
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	0(%rsp),%ecx
        +	pxor	%xmm0,%xmm4
        +.byte	102,68,15,58,15,210,8
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	pxor	%xmm5,%xmm4
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edx,%ecx
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm3,%xmm8
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm10,%xmm4
        +	addl	4(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm8,48(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	pslld	$2,%xmm4
        +	addl	8(%rsp),%eax
        +	xorl	%ebp,%esi
        +	psrld	$30,%xmm10
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	por	%xmm10,%xmm4
        +	addl	12(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movdqa	%xmm4,%xmm8
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	16(%rsp),%edx
        +	pxor	%xmm1,%xmm5
        +.byte	102,68,15,58,15,195,8
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm6,%xmm5
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm4,%xmm9
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	pxor	%xmm8,%xmm5
        +	addl	20(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm9,0(%rsp)
        +	xorl	%eax,%edi
        +	cmpl	$11,%r8d
        +	jb	.Laesenclast2
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	.Laesenclast2
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +.Laesenclast2:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	pslld	$2,%xmm5
        +	addl	24(%rsp),%ebx
        +	xorl	%eax,%esi
        +	psrld	$30,%xmm8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	por	%xmm8,%xmm5
        +	addl	28(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movdqa	%xmm5,%xmm9
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ecx,%edi
        +	movups	32(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	movups	%xmm11,16(%r13,%r12,1)
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	pxor	%xmm2,%xmm6
        +.byte	102,68,15,58,15,204,8
        +	xorl	%edx,%ecx
        +	addl	32(%rsp),%ebp
        +	andl	%edx,%edi
        +	pxor	%xmm7,%xmm6
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm5,%xmm10
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	pxor	%xmm9,%xmm6
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm10,16(%rsp)
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	36(%rsp),%edx
        +	andl	%ecx,%esi
        +	pslld	$2,%xmm6
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	psrld	$30,%xmm9
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	por	%xmm9,%xmm6
        +	movl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm10
        +	addl	40(%rsp),%ecx
        +	andl	%ebx,%edi
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	44(%rsp),%ebx
        +	andl	%eax,%esi
        +	andl	%ebp,%edi
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%edi
        +	pxor	%xmm3,%xmm7
        +.byte	102,68,15,58,15,213,8
        +	xorl	%ebp,%edx
        +	addl	48(%rsp),%eax
        +	andl	%ebp,%edi
        +	pxor	%xmm0,%xmm7
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	movdqa	48(%r11),%xmm9
        +	paddd	%xmm6,%xmm8
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	pxor	%xmm10,%xmm7
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm8,32(%rsp)
        +	movl	%ecx,%esi
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	addl	52(%rsp),%ebp
        +	andl	%edx,%esi
        +	pslld	$2,%xmm7
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	psrld	$30,%xmm10
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	por	%xmm10,%xmm7
        +	movl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm8
        +	addl	56(%rsp),%edx
        +	andl	%ecx,%edi
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	60(%rsp),%ecx
        +	andl	%ebx,%esi
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%edi
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,198,8
        +	xorl	%eax,%ebp
        +	addl	0(%rsp),%ebx
        +	andl	%eax,%edi
        +	pxor	%xmm1,%xmm0
        +	andl	%ebp,%esi
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	rorl	$7,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm7,%xmm9
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	pxor	%xmm8,%xmm0
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movdqa	%xmm0,%xmm8
        +	movdqa	%xmm9,48(%rsp)
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	4(%rsp),%eax
        +	andl	%ebp,%esi
        +	pslld	$2,%xmm0
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	psrld	$30,%xmm8
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	por	%xmm8,%xmm0
        +	movl	%ecx,%edi
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%ecx
        +	movdqa	%xmm0,%xmm9
        +	addl	8(%rsp),%ebp
        +	andl	%edx,%edi
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	12(%rsp),%edx
        +	andl	%ecx,%esi
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%edi
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,207,8
        +	xorl	%ebx,%eax
        +	addl	16(%rsp),%ecx
        +	andl	%ebx,%edi
        +	pxor	%xmm2,%xmm1
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm0,%xmm10
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	pxor	%xmm9,%xmm1
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movdqa	%xmm1,%xmm9
        +	movdqa	%xmm10,0(%rsp)
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	20(%rsp),%ebx
        +	andl	%eax,%esi
        +	pslld	$2,%xmm1
        +	andl	%ebp,%edi
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	rorl	$7,%edx
        +	psrld	$30,%xmm9
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	por	%xmm9,%xmm1
        +	movl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm1,%xmm10
        +	addl	24(%rsp),%eax
        +	andl	%ebp,%edi
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movl	%ecx,%esi
        +	cmpl	$11,%r8d
        +	jb	.Laesenclast3
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	.Laesenclast3
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +.Laesenclast3:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	addl	28(%rsp),%ebp
        +	andl	%edx,%esi
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%edi
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,208,8
        +	xorl	%ecx,%ebx
        +	addl	32(%rsp),%edx
        +	andl	%ecx,%edi
        +	pxor	%xmm3,%xmm2
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm1,%xmm8
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	pxor	%xmm10,%xmm2
        +	roll	$5,%ebp
        +	movups	48(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	movups	%xmm11,32(%r13,%r12,1)
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movdqa	%xmm2,%xmm10
        +	movdqa	%xmm8,16(%rsp)
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	36(%rsp),%ecx
        +	andl	%ebx,%esi
        +	pslld	$2,%xmm2
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	psrld	$30,%xmm10
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	por	%xmm10,%xmm2
        +	movl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm2,%xmm8
        +	addl	40(%rsp),%ebx
        +	andl	%eax,%edi
        +	andl	%ebp,%esi
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	44(%rsp),%eax
        +	andl	%ebp,%esi
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	addl	48(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,193,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm4,%xmm3
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm2,%xmm9
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm8,%xmm3
        +	addl	52(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm3,%xmm8
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm8,%xmm3
        +	addl	60(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	0(%rsp),%eax
        +	paddd	%xmm3,%xmm10
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	movdqa	%xmm10,48(%rsp)
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	4(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	8(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	12(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	cmpq	%r14,%r10
        +	je	.Ldone_ssse3
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r10),%xmm0
        +	movdqu	16(%r10),%xmm1
        +	movdqu	32(%r10),%xmm2
        +	movdqu	48(%r10),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r10
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +.byte	102,15,56,0,206
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	paddd	%xmm9,%xmm0
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movdqa	%xmm0,0(%rsp)
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	psubd	%xmm9,%xmm0
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +.byte	102,15,56,0,214
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm9,%xmm1
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movdqa	%xmm1,16(%rsp)
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	psubd	%xmm9,%xmm1
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +.byte	102,15,56,0,222
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	paddd	%xmm9,%xmm2
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movdqa	%xmm2,32(%rsp)
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	psubd	%xmm9,%xmm2
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	cmpl	$11,%r8d
        +	jb	.Laesenclast4
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	.Laesenclast4
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +.Laesenclast4:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movups	%xmm11,48(%r13,%r12,1)
        +	leaq	64(%r12),%r12
        +
        +	addl	0(%r9),%eax
        +	addl	4(%r9),%esi
        +	addl	8(%r9),%ecx
        +	addl	12(%r9),%edx
        +	movl	%eax,0(%r9)
        +	addl	16(%r9),%ebp
        +	movl	%esi,4(%r9)
        +	movl	%esi,%ebx
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +	movl	%ebp,16(%r9)
        +	jmp	.Loop_ssse3
        +
        +.align	16
        +.Ldone_ssse3:
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	cmpl	$11,%r8d
        +	jb	.Laesenclast5
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	.Laesenclast5
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +.Laesenclast5:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movups	%xmm11,48(%r13,%r12,1)
        +	movq	88(%rsp),%r8
        +
        +	addl	0(%r9),%eax
        +	addl	4(%r9),%esi
        +	addl	8(%r9),%ecx
        +	movl	%eax,0(%r9)
        +	addl	12(%r9),%edx
        +	movl	%esi,4(%r9)
        +	addl	16(%r9),%ebp
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +	movl	%ebp,16(%r9)
        +	movups	%xmm11,(%r8)
        +	leaq	104(%rsp),%rsi
        +	movq	0(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lepilogue_ssse3:
        +	.byte	0xf3,0xc3
        +.size	aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3
        +.align	64
        +K_XX_XX:
        +.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999
        +
        +.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
        +
        +.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
        +
        +.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
        +
        +.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
        +
        +
        +.byte	65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	64
        diff --git a/vendor/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s b/vendor/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s
        new file mode 100644
        index 000000000..2d24b7b28
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/aes/aesni-x86_64.s
        @@ -0,0 +1,2558 @@
        +.text
        +
        +.globl	aesni_encrypt
        +.type	aesni_encrypt,@function
        +.align	16
        +aesni_encrypt:
        +	movups	(%rdi),%xmm2
        +	movl	240(%rdx),%eax
        +	movups	(%rdx),%xmm0
        +	movups	16(%rdx),%xmm1
        +	leaq	32(%rdx),%rdx
        +	xorps	%xmm0,%xmm2
        +.Loop_enc1_1:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rdx),%xmm1
        +	leaq	16(%rdx),%rdx
        +	jnz	.Loop_enc1_1
        +
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%rsi)
        +	.byte	0xf3,0xc3
        +.size	aesni_encrypt,.-aesni_encrypt
        +
        +.globl	aesni_decrypt
        +.type	aesni_decrypt,@function
        +.align	16
        +aesni_decrypt:
        +	movups	(%rdi),%xmm2
        +	movl	240(%rdx),%eax
        +	movups	(%rdx),%xmm0
        +	movups	16(%rdx),%xmm1
        +	leaq	32(%rdx),%rdx
        +	xorps	%xmm0,%xmm2
        +.Loop_dec1_2:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rdx),%xmm1
        +	leaq	16(%rdx),%rdx
        +	jnz	.Loop_dec1_2
        +
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%rsi)
        +	.byte	0xf3,0xc3
        +.size	aesni_decrypt, .-aesni_decrypt
        +.type	_aesni_encrypt3,@function
        +.align	16
        +_aesni_encrypt3:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	movups	(%rcx),%xmm0
        +
        +.Lenc_loop3:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +	movups	(%rcx),%xmm0
        +	jnz	.Lenc_loop3
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +	.byte	0xf3,0xc3
        +.size	_aesni_encrypt3,.-_aesni_encrypt3
        +.type	_aesni_decrypt3,@function
        +.align	16
        +_aesni_decrypt3:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	movups	(%rcx),%xmm0
        +
        +.Ldec_loop3:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +	movups	(%rcx),%xmm0
        +	jnz	.Ldec_loop3
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +	.byte	0xf3,0xc3
        +.size	_aesni_decrypt3,.-_aesni_decrypt3
        +.type	_aesni_encrypt4,@function
        +.align	16
        +_aesni_encrypt4:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	xorps	%xmm0,%xmm5
        +	movups	(%rcx),%xmm0
        +
        +.Lenc_loop4:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +	movups	(%rcx),%xmm0
        +	jnz	.Lenc_loop4
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +	.byte	0xf3,0xc3
        +.size	_aesni_encrypt4,.-_aesni_encrypt4
        +.type	_aesni_decrypt4,@function
        +.align	16
        +_aesni_decrypt4:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	xorps	%xmm0,%xmm5
        +	movups	(%rcx),%xmm0
        +
        +.Ldec_loop4:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +	movups	(%rcx),%xmm0
        +	jnz	.Ldec_loop4
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +	.byte	0xf3,0xc3
        +.size	_aesni_decrypt4,.-_aesni_decrypt4
        +.type	_aesni_encrypt6,@function
        +.align	16
        +_aesni_encrypt6:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,220,241
        +	movups	(%rcx),%xmm0
        +.byte	102,15,56,220,249
        +	jmp	.Lenc_loop6_enter
        +.align	16
        +.Lenc_loop6:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.Lenc_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%rcx),%xmm0
        +	jnz	.Lenc_loop6
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +	.byte	0xf3,0xc3
        +.size	_aesni_encrypt6,.-_aesni_encrypt6
        +.type	_aesni_decrypt6,@function
        +.align	16
        +_aesni_decrypt6:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,222,241
        +	movups	(%rcx),%xmm0
        +.byte	102,15,56,222,249
        +	jmp	.Ldec_loop6_enter
        +.align	16
        +.Ldec_loop6:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.Ldec_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	(%rcx),%xmm0
        +	jnz	.Ldec_loop6
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +	.byte	0xf3,0xc3
        +.size	_aesni_decrypt6,.-_aesni_decrypt6
        +.type	_aesni_encrypt8,@function
        +.align	16
        +_aesni_encrypt8:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,220,241
        +	pxor	%xmm0,%xmm8
        +.byte	102,15,56,220,249
        +	pxor	%xmm0,%xmm9
        +	movups	(%rcx),%xmm0
        +.byte	102,68,15,56,220,193
        +.byte	102,68,15,56,220,201
        +	movups	16(%rcx),%xmm1
        +	jmp	.Lenc_loop8_enter
        +.align	16
        +.Lenc_loop8:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,68,15,56,220,193
        +.byte	102,68,15,56,220,201
        +	movups	16(%rcx),%xmm1
        +.Lenc_loop8_enter:
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +.byte	102,68,15,56,220,192
        +.byte	102,68,15,56,220,200
        +	movups	(%rcx),%xmm0
        +	jnz	.Lenc_loop8
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,68,15,56,220,193
        +.byte	102,68,15,56,220,201
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +.byte	102,68,15,56,221,192
        +.byte	102,68,15,56,221,200
        +	.byte	0xf3,0xc3
        +.size	_aesni_encrypt8,.-_aesni_encrypt8
        +.type	_aesni_decrypt8,@function
        +.align	16
        +_aesni_decrypt8:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,222,241
        +	pxor	%xmm0,%xmm8
        +.byte	102,15,56,222,249
        +	pxor	%xmm0,%xmm9
        +	movups	(%rcx),%xmm0
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +	movups	16(%rcx),%xmm1
        +	jmp	.Ldec_loop8_enter
        +.align	16
        +.Ldec_loop8:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +	movups	16(%rcx),%xmm1
        +.Ldec_loop8_enter:
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +.byte	102,68,15,56,222,192
        +.byte	102,68,15,56,222,200
        +	movups	(%rcx),%xmm0
        +	jnz	.Ldec_loop8
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +.byte	102,68,15,56,223,192
        +.byte	102,68,15,56,223,200
        +	.byte	0xf3,0xc3
        +.size	_aesni_decrypt8,.-_aesni_decrypt8
        +.globl	aesni_ecb_encrypt
        +.type	aesni_ecb_encrypt,@function
        +.align	16
        +aesni_ecb_encrypt:
        +	andq	$-16,%rdx
        +	jz	.Lecb_ret
        +
        +	movl	240(%rcx),%eax
        +	movups	(%rcx),%xmm0
        +	movq	%rcx,%r11
        +	movl	%eax,%r10d
        +	testl	%r8d,%r8d
        +	jz	.Lecb_decrypt
        +
        +	cmpq	$128,%rdx
        +	jb	.Lecb_enc_tail
        +
        +	movdqu	(%rdi),%xmm2
        +	movdqu	16(%rdi),%xmm3
        +	movdqu	32(%rdi),%xmm4
        +	movdqu	48(%rdi),%xmm5
        +	movdqu	64(%rdi),%xmm6
        +	movdqu	80(%rdi),%xmm7
        +	movdqu	96(%rdi),%xmm8
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +	subq	$128,%rdx
        +	jmp	.Lecb_enc_loop8_enter
        +.align	16
        +.Lecb_enc_loop8:
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movdqu	(%rdi),%xmm2
        +	movl	%r10d,%eax
        +	movups	%xmm3,16(%rsi)
        +	movdqu	16(%rdi),%xmm3
        +	movups	%xmm4,32(%rsi)
        +	movdqu	32(%rdi),%xmm4
        +	movups	%xmm5,48(%rsi)
        +	movdqu	48(%rdi),%xmm5
        +	movups	%xmm6,64(%rsi)
        +	movdqu	64(%rdi),%xmm6
        +	movups	%xmm7,80(%rsi)
        +	movdqu	80(%rdi),%xmm7
        +	movups	%xmm8,96(%rsi)
        +	movdqu	96(%rdi),%xmm8
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +.Lecb_enc_loop8_enter:
        +
        +	call	_aesni_encrypt8
        +
        +	subq	$128,%rdx
        +	jnc	.Lecb_enc_loop8
        +
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movups	%xmm3,16(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	addq	$128,%rdx
        +	jz	.Lecb_ret
        +
        +.Lecb_enc_tail:
        +	movups	(%rdi),%xmm2
        +	cmpq	$32,%rdx
        +	jb	.Lecb_enc_one
        +	movups	16(%rdi),%xmm3
        +	je	.Lecb_enc_two
        +	movups	32(%rdi),%xmm4
        +	cmpq	$64,%rdx
        +	jb	.Lecb_enc_three
        +	movups	48(%rdi),%xmm5
        +	je	.Lecb_enc_four
        +	movups	64(%rdi),%xmm6
        +	cmpq	$96,%rdx
        +	jb	.Lecb_enc_five
        +	movups	80(%rdi),%xmm7
        +	je	.Lecb_enc_six
        +	movdqu	96(%rdi),%xmm8
        +	call	_aesni_encrypt8
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_enc1_3:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_enc1_3
        +
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_encrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_three:
        +	call	_aesni_encrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_four:
        +	call	_aesni_encrypt4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_five:
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_encrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_six:
        +	call	_aesni_encrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	jmp	.Lecb_ret
        +
        +.align	16
        +.Lecb_decrypt:
        +	cmpq	$128,%rdx
        +	jb	.Lecb_dec_tail
        +
        +	movdqu	(%rdi),%xmm2
        +	movdqu	16(%rdi),%xmm3
        +	movdqu	32(%rdi),%xmm4
        +	movdqu	48(%rdi),%xmm5
        +	movdqu	64(%rdi),%xmm6
        +	movdqu	80(%rdi),%xmm7
        +	movdqu	96(%rdi),%xmm8
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +	subq	$128,%rdx
        +	jmp	.Lecb_dec_loop8_enter
        +.align	16
        +.Lecb_dec_loop8:
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movdqu	(%rdi),%xmm2
        +	movl	%r10d,%eax
        +	movups	%xmm3,16(%rsi)
        +	movdqu	16(%rdi),%xmm3
        +	movups	%xmm4,32(%rsi)
        +	movdqu	32(%rdi),%xmm4
        +	movups	%xmm5,48(%rsi)
        +	movdqu	48(%rdi),%xmm5
        +	movups	%xmm6,64(%rsi)
        +	movdqu	64(%rdi),%xmm6
        +	movups	%xmm7,80(%rsi)
        +	movdqu	80(%rdi),%xmm7
        +	movups	%xmm8,96(%rsi)
        +	movdqu	96(%rdi),%xmm8
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +.Lecb_dec_loop8_enter:
        +
        +	call	_aesni_decrypt8
        +
        +	movups	(%r11),%xmm0
        +	subq	$128,%rdx
        +	jnc	.Lecb_dec_loop8
        +
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movups	%xmm3,16(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	addq	$128,%rdx
        +	jz	.Lecb_ret
        +
        +.Lecb_dec_tail:
        +	movups	(%rdi),%xmm2
        +	cmpq	$32,%rdx
        +	jb	.Lecb_dec_one
        +	movups	16(%rdi),%xmm3
        +	je	.Lecb_dec_two
        +	movups	32(%rdi),%xmm4
        +	cmpq	$64,%rdx
        +	jb	.Lecb_dec_three
        +	movups	48(%rdi),%xmm5
        +	je	.Lecb_dec_four
        +	movups	64(%rdi),%xmm6
        +	cmpq	$96,%rdx
        +	jb	.Lecb_dec_five
        +	movups	80(%rdi),%xmm7
        +	je	.Lecb_dec_six
        +	movups	96(%rdi),%xmm8
        +	movups	(%rcx),%xmm0
        +	call	_aesni_decrypt8
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_dec1_4:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_dec1_4
        +
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_decrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_three:
        +	call	_aesni_decrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_four:
        +	call	_aesni_decrypt4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_five:
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_decrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_six:
        +	call	_aesni_decrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +
        +.Lecb_ret:
        +	.byte	0xf3,0xc3
        +.size	aesni_ecb_encrypt,.-aesni_ecb_encrypt
        +.globl	aesni_ccm64_encrypt_blocks
        +.type	aesni_ccm64_encrypt_blocks,@function
        +.align	16
        +aesni_ccm64_encrypt_blocks:
        +	movl	240(%rcx),%eax
        +	movdqu	(%r8),%xmm9
        +	movdqa	.Lincrement64(%rip),%xmm6
        +	movdqa	.Lbswap_mask(%rip),%xmm7
        +
        +	shrl	$1,%eax
        +	leaq	0(%rcx),%r11
        +	movdqu	(%r9),%xmm3
        +	movdqa	%xmm9,%xmm2
        +	movl	%eax,%r10d
        +.byte	102,68,15,56,0,207
        +	jmp	.Lccm64_enc_outer
        +.align	16
        +.Lccm64_enc_outer:
        +	movups	(%r11),%xmm0
        +	movl	%r10d,%eax
        +	movups	(%rdi),%xmm8
        +
        +	xorps	%xmm0,%xmm2
        +	movups	16(%r11),%xmm1
        +	xorps	%xmm8,%xmm0
        +	leaq	32(%r11),%rcx
        +	xorps	%xmm0,%xmm3
        +	movups	(%rcx),%xmm0
        +
        +.Lccm64_enc2_loop:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +.byte	102,15,56,220,217
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,216
        +	movups	0(%rcx),%xmm0
        +	jnz	.Lccm64_enc2_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	paddq	%xmm6,%xmm9
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +
        +	decq	%rdx
        +	leaq	16(%rdi),%rdi
        +	xorps	%xmm2,%xmm8
        +	movdqa	%xmm9,%xmm2
        +	movups	%xmm8,(%rsi)
        +	leaq	16(%rsi),%rsi
        +.byte	102,15,56,0,215
        +	jnz	.Lccm64_enc_outer
        +
        +	movups	%xmm3,(%r9)
        +	.byte	0xf3,0xc3
        +.size	aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks
        +.globl	aesni_ccm64_decrypt_blocks
        +.type	aesni_ccm64_decrypt_blocks,@function
        +.align	16
        +aesni_ccm64_decrypt_blocks:
        +	movl	240(%rcx),%eax
        +	movups	(%r8),%xmm9
        +	movdqu	(%r9),%xmm3
        +	movdqa	.Lincrement64(%rip),%xmm6
        +	movdqa	.Lbswap_mask(%rip),%xmm7
        +
        +	movaps	%xmm9,%xmm2
        +	movl	%eax,%r10d
        +	movq	%rcx,%r11
        +.byte	102,68,15,56,0,207
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_enc1_5:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_enc1_5
        +
        +.byte	102,15,56,221,209
        +	movups	(%rdi),%xmm8
        +	paddq	%xmm6,%xmm9
        +	leaq	16(%rdi),%rdi
        +	jmp	.Lccm64_dec_outer
        +.align	16
        +.Lccm64_dec_outer:
        +	xorps	%xmm2,%xmm8
        +	movdqa	%xmm9,%xmm2
        +	movl	%r10d,%eax
        +	movups	%xmm8,(%rsi)
        +	leaq	16(%rsi),%rsi
        +.byte	102,15,56,0,215
        +
        +	subq	$1,%rdx
        +	jz	.Lccm64_dec_break
        +
        +	movups	(%r11),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%r11),%xmm1
        +	xorps	%xmm0,%xmm8
        +	leaq	32(%r11),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm8,%xmm3
        +	movups	(%rcx),%xmm0
        +
        +.Lccm64_dec2_loop:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +.byte	102,15,56,220,217
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,216
        +	movups	0(%rcx),%xmm0
        +	jnz	.Lccm64_dec2_loop
        +	movups	(%rdi),%xmm8
        +	paddq	%xmm6,%xmm9
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	leaq	16(%rdi),%rdi
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +	jmp	.Lccm64_dec_outer
        +
        +.align	16
        +.Lccm64_dec_break:
        +
        +	movups	(%r11),%xmm0
        +	movups	16(%r11),%xmm1
        +	xorps	%xmm0,%xmm8
        +	leaq	32(%r11),%r11
        +	xorps	%xmm8,%xmm3
        +.Loop_enc1_6:
        +.byte	102,15,56,220,217
        +	decl	%eax
        +	movups	(%r11),%xmm1
        +	leaq	16(%r11),%r11
        +	jnz	.Loop_enc1_6
        +
        +.byte	102,15,56,221,217
        +	movups	%xmm3,(%r9)
        +	.byte	0xf3,0xc3
        +.size	aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks
        +.globl	aesni_ctr32_encrypt_blocks
        +.type	aesni_ctr32_encrypt_blocks,@function
        +.align	16
        +aesni_ctr32_encrypt_blocks:
        +	cmpq	$1,%rdx
        +	je	.Lctr32_one_shortcut
        +
        +	movdqu	(%r8),%xmm14
        +	movdqa	.Lbswap_mask(%rip),%xmm15
        +	xorl	%eax,%eax
        +.byte	102,69,15,58,22,242,3
        +.byte	102,68,15,58,34,240,3
        +
        +	movl	240(%rcx),%eax
        +	bswapl	%r10d
        +	pxor	%xmm12,%xmm12
        +	pxor	%xmm13,%xmm13
        +.byte	102,69,15,58,34,226,0
        +	leaq	3(%r10),%r11
        +.byte	102,69,15,58,34,235,0
        +	incl	%r10d
        +.byte	102,69,15,58,34,226,1
        +	incq	%r11
        +.byte	102,69,15,58,34,235,1
        +	incl	%r10d
        +.byte	102,69,15,58,34,226,2
        +	incq	%r11
        +.byte	102,69,15,58,34,235,2
        +	movdqa	%xmm12,-40(%rsp)
        +.byte	102,69,15,56,0,231
        +	movdqa	%xmm13,-24(%rsp)
        +.byte	102,69,15,56,0,239
        +
        +	pshufd	$192,%xmm12,%xmm2
        +	pshufd	$128,%xmm12,%xmm3
        +	pshufd	$64,%xmm12,%xmm4
        +	cmpq	$6,%rdx
        +	jb	.Lctr32_tail
        +	shrl	$1,%eax
        +	movq	%rcx,%r11
        +	movl	%eax,%r10d
        +	subq	$6,%rdx
        +	jmp	.Lctr32_loop6
        +
        +.align	16
        +.Lctr32_loop6:
        +	pshufd	$192,%xmm13,%xmm5
        +	por	%xmm14,%xmm2
        +	movups	(%r11),%xmm0
        +	pshufd	$128,%xmm13,%xmm6
        +	por	%xmm14,%xmm3
        +	movups	16(%r11),%xmm1
        +	pshufd	$64,%xmm13,%xmm7
        +	por	%xmm14,%xmm4
        +	por	%xmm14,%xmm5
        +	xorps	%xmm0,%xmm2
        +	por	%xmm14,%xmm6
        +	por	%xmm14,%xmm7
        +
        +
        +
        +
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	leaq	32(%r11),%rcx
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	movdqa	.Lincrement32(%rip),%xmm13
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	movdqa	-40(%rsp),%xmm12
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	movups	(%rcx),%xmm0
        +	decl	%eax
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +	jmp	.Lctr32_enc_loop6_enter
        +.align	16
        +.Lctr32_enc_loop6:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.Lctr32_enc_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%rcx),%xmm0
        +	jnz	.Lctr32_enc_loop6
        +
        +.byte	102,15,56,220,209
        +	paddd	%xmm13,%xmm12
        +.byte	102,15,56,220,217
        +	paddd	-24(%rsp),%xmm13
        +.byte	102,15,56,220,225
        +	movdqa	%xmm12,-40(%rsp)
        +.byte	102,15,56,220,233
        +	movdqa	%xmm13,-24(%rsp)
        +.byte	102,15,56,220,241
        +.byte	102,69,15,56,0,231
        +.byte	102,15,56,220,249
        +.byte	102,69,15,56,0,239
        +
        +.byte	102,15,56,221,208
        +	movups	(%rdi),%xmm8
        +.byte	102,15,56,221,216
        +	movups	16(%rdi),%xmm9
        +.byte	102,15,56,221,224
        +	movups	32(%rdi),%xmm10
        +.byte	102,15,56,221,232
        +	movups	48(%rdi),%xmm11
        +.byte	102,15,56,221,240
        +	movups	64(%rdi),%xmm1
        +.byte	102,15,56,221,248
        +	movups	80(%rdi),%xmm0
        +	leaq	96(%rdi),%rdi
        +
        +	xorps	%xmm2,%xmm8
        +	pshufd	$192,%xmm12,%xmm2
        +	xorps	%xmm3,%xmm9
        +	pshufd	$128,%xmm12,%xmm3
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	pshufd	$64,%xmm12,%xmm4
        +	movups	%xmm9,16(%rsi)
        +	xorps	%xmm5,%xmm11
        +	movups	%xmm10,32(%rsi)
        +	xorps	%xmm6,%xmm1
        +	movups	%xmm11,48(%rsi)
        +	xorps	%xmm7,%xmm0
        +	movups	%xmm1,64(%rsi)
        +	movups	%xmm0,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	movl	%r10d,%eax
        +	subq	$6,%rdx
        +	jnc	.Lctr32_loop6
        +
        +	addq	$6,%rdx
        +	jz	.Lctr32_done
        +	movq	%r11,%rcx
        +	leal	1(%rax,%rax,1),%eax
        +
        +.Lctr32_tail:
        +	por	%xmm14,%xmm2
        +	movups	(%rdi),%xmm8
        +	cmpq	$2,%rdx
        +	jb	.Lctr32_one
        +
        +	por	%xmm14,%xmm3
        +	movups	16(%rdi),%xmm9
        +	je	.Lctr32_two
        +
        +	pshufd	$192,%xmm13,%xmm5
        +	por	%xmm14,%xmm4
        +	movups	32(%rdi),%xmm10
        +	cmpq	$4,%rdx
        +	jb	.Lctr32_three
        +
        +	pshufd	$128,%xmm13,%xmm6
        +	por	%xmm14,%xmm5
        +	movups	48(%rdi),%xmm11
        +	je	.Lctr32_four
        +
        +	por	%xmm14,%xmm6
        +	xorps	%xmm7,%xmm7
        +
        +	call	_aesni_encrypt6
        +
        +	movups	64(%rdi),%xmm1
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	movups	%xmm9,16(%rsi)
        +	xorps	%xmm5,%xmm11
        +	movups	%xmm10,32(%rsi)
        +	xorps	%xmm6,%xmm1
        +	movups	%xmm11,48(%rsi)
        +	movups	%xmm1,64(%rsi)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_one_shortcut:
        +	movups	(%r8),%xmm2
        +	movups	(%rdi),%xmm8
        +	movl	240(%rcx),%eax
        +.Lctr32_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_enc1_7:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_enc1_7
        +
        +.byte	102,15,56,221,209
        +	xorps	%xmm2,%xmm8
        +	movups	%xmm8,(%rsi)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_encrypt3
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	movups	%xmm9,16(%rsi)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_three:
        +	call	_aesni_encrypt3
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	movups	%xmm9,16(%rsi)
        +	movups	%xmm10,32(%rsi)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_four:
        +	call	_aesni_encrypt4
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	movups	%xmm9,16(%rsi)
        +	xorps	%xmm5,%xmm11
        +	movups	%xmm10,32(%rsi)
        +	movups	%xmm11,48(%rsi)
        +
        +.Lctr32_done:
        +	.byte	0xf3,0xc3
        +.size	aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
        +.globl	aesni_xts_encrypt
        +.type	aesni_xts_encrypt,@function
        +.align	16
        +aesni_xts_encrypt:
        +	leaq	-104(%rsp),%rsp
        +	movups	(%r9),%xmm15
        +	movl	240(%r8),%eax
        +	movl	240(%rcx),%r10d
        +	movups	(%r8),%xmm0
        +	movups	16(%r8),%xmm1
        +	leaq	32(%r8),%r8
        +	xorps	%xmm0,%xmm15
        +.Loop_enc1_8:
        +.byte	102,68,15,56,220,249
        +	decl	%eax
        +	movups	(%r8),%xmm1
        +	leaq	16(%r8),%r8
        +	jnz	.Loop_enc1_8
        +
        +.byte	102,68,15,56,221,249
        +	movq	%rcx,%r11
        +	movl	%r10d,%eax
        +	movq	%rdx,%r9
        +	andq	$-16,%rdx
        +
        +	movdqa	.Lxts_magic(%rip),%xmm8
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	subq	$96,%rdx
        +	jc	.Lxts_enc_short
        +
        +	shrl	$1,%eax
        +	subl	$1,%eax
        +	movl	%eax,%r10d
        +	jmp	.Lxts_enc_grandloop
        +
        +.align	16
        +.Lxts_enc_grandloop:
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	0(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	pxor	%xmm12,%xmm4
        +	movdqu	80(%rdi),%xmm7
        +	leaq	96(%rdi),%rdi
        +	pxor	%xmm13,%xmm5
        +	movups	(%r11),%xmm0
        +	pxor	%xmm14,%xmm6
        +	pxor	%xmm15,%xmm7
        +
        +
        +
        +	movups	16(%r11),%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	movdqa	%xmm10,0(%rsp)
        +.byte	102,15,56,220,209
        +	leaq	32(%r11),%rcx
        +	pxor	%xmm0,%xmm4
        +	movdqa	%xmm11,16(%rsp)
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +	movdqa	%xmm12,32(%rsp)
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +	movdqa	%xmm13,48(%rsp)
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	movups	(%rcx),%xmm0
        +	decl	%eax
        +	movdqa	%xmm14,64(%rsp)
        +.byte	102,15,56,220,241
        +	movdqa	%xmm15,80(%rsp)
        +.byte	102,15,56,220,249
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	jmp	.Lxts_enc_loop6_enter
        +
        +.align	16
        +.Lxts_enc_loop6:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.Lxts_enc_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%rcx),%xmm0
        +	jnz	.Lxts_enc_loop6
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,220,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,220,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,220,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +	movups	16(%rcx),%xmm1
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,220,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,220,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,220,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	32(%rcx),%xmm0
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,220,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,220,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,220,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,221,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,221,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,221,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	xorps	0(%rsp),%xmm2
        +	pand	%xmm8,%xmm9
        +	xorps	16(%rsp),%xmm3
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +
        +	xorps	32(%rsp),%xmm4
        +	movups	%xmm2,0(%rsi)
        +	xorps	48(%rsp),%xmm5
        +	movups	%xmm3,16(%rsi)
        +	xorps	64(%rsp),%xmm6
        +	movups	%xmm4,32(%rsi)
        +	xorps	80(%rsp),%xmm7
        +	movups	%xmm5,48(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	subq	$96,%rdx
        +	jnc	.Lxts_enc_grandloop
        +
        +	leal	3(%rax,%rax,1),%eax
        +	movq	%r11,%rcx
        +	movl	%eax,%r10d
        +
        +.Lxts_enc_short:
        +	addq	$96,%rdx
        +	jz	.Lxts_enc_done
        +
        +	cmpq	$32,%rdx
        +	jb	.Lxts_enc_one
        +	je	.Lxts_enc_two
        +
        +	cmpq	$64,%rdx
        +	jb	.Lxts_enc_three
        +	je	.Lxts_enc_four
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	leaq	80(%rdi),%rdi
        +	pxor	%xmm12,%xmm4
        +	pxor	%xmm13,%xmm5
        +	pxor	%xmm14,%xmm6
        +
        +	call	_aesni_encrypt6
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm15,%xmm10
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movdqu	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movdqu	%xmm3,16(%rsi)
        +	xorps	%xmm14,%xmm6
        +	movdqu	%xmm4,32(%rsi)
        +	movdqu	%xmm5,48(%rsi)
        +	movdqu	%xmm6,64(%rsi)
        +	leaq	80(%rsi),%rsi
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_one:
        +	movups	(%rdi),%xmm2
        +	leaq	16(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_enc1_9:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_enc1_9
        +
        +.byte	102,15,56,221,209
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm11,%xmm10
        +	movups	%xmm2,(%rsi)
        +	leaq	16(%rsi),%rsi
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_two:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	leaq	32(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm12,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	leaq	32(%rsi),%rsi
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_three:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	32(%rdi),%xmm4
        +	leaq	48(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm13,%xmm10
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	leaq	48(%rsi),%rsi
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_four:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	32(%rdi),%xmm4
        +	xorps	%xmm10,%xmm2
        +	movups	48(%rdi),%xmm5
        +	leaq	64(%rdi),%rdi
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	xorps	%xmm13,%xmm5
        +
        +	call	_aesni_encrypt4
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm15,%xmm10
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	leaq	64(%rsi),%rsi
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_done:
        +	andq	$15,%r9
        +	jz	.Lxts_enc_ret
        +	movq	%r9,%rdx
        +
        +.Lxts_enc_steal:
        +	movzbl	(%rdi),%eax
        +	movzbl	-16(%rsi),%ecx
        +	leaq	1(%rdi),%rdi
        +	movb	%al,-16(%rsi)
        +	movb	%cl,0(%rsi)
        +	leaq	1(%rsi),%rsi
        +	subq	$1,%rdx
        +	jnz	.Lxts_enc_steal
        +
        +	subq	%r9,%rsi
        +	movq	%r11,%rcx
        +	movl	%r10d,%eax
        +
        +	movups	-16(%rsi),%xmm2
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_enc1_10:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_enc1_10
        +
        +.byte	102,15,56,221,209
        +	xorps	%xmm10,%xmm2
        +	movups	%xmm2,-16(%rsi)
        +
        +.Lxts_enc_ret:
        +	leaq	104(%rsp),%rsp
        +.Lxts_enc_epilogue:
        +	.byte	0xf3,0xc3
        +.size	aesni_xts_encrypt,.-aesni_xts_encrypt
        +.globl	aesni_xts_decrypt
        +.type	aesni_xts_decrypt,@function
        +.align	16
        +aesni_xts_decrypt:
        +	leaq	-104(%rsp),%rsp
        +	movups	(%r9),%xmm15
        +	movl	240(%r8),%eax
        +	movl	240(%rcx),%r10d
        +	movups	(%r8),%xmm0
        +	movups	16(%r8),%xmm1
        +	leaq	32(%r8),%r8
        +	xorps	%xmm0,%xmm15
        +.Loop_enc1_11:
        +.byte	102,68,15,56,220,249
        +	decl	%eax
        +	movups	(%r8),%xmm1
        +	leaq	16(%r8),%r8
        +	jnz	.Loop_enc1_11
        +
        +.byte	102,68,15,56,221,249
        +	xorl	%eax,%eax
        +	testq	$15,%rdx
        +	setnz	%al
        +	shlq	$4,%rax
        +	subq	%rax,%rdx
        +
        +	movq	%rcx,%r11
        +	movl	%r10d,%eax
        +	movq	%rdx,%r9
        +	andq	$-16,%rdx
        +
        +	movdqa	.Lxts_magic(%rip),%xmm8
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	subq	$96,%rdx
        +	jc	.Lxts_dec_short
        +
        +	shrl	$1,%eax
        +	subl	$1,%eax
        +	movl	%eax,%r10d
        +	jmp	.Lxts_dec_grandloop
        +
        +.align	16
        +.Lxts_dec_grandloop:
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	0(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	pxor	%xmm12,%xmm4
        +	movdqu	80(%rdi),%xmm7
        +	leaq	96(%rdi),%rdi
        +	pxor	%xmm13,%xmm5
        +	movups	(%r11),%xmm0
        +	pxor	%xmm14,%xmm6
        +	pxor	%xmm15,%xmm7
        +
        +
        +
        +	movups	16(%r11),%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	movdqa	%xmm10,0(%rsp)
        +.byte	102,15,56,222,209
        +	leaq	32(%r11),%rcx
        +	pxor	%xmm0,%xmm4
        +	movdqa	%xmm11,16(%rsp)
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +	movdqa	%xmm12,32(%rsp)
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +	movdqa	%xmm13,48(%rsp)
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	movups	(%rcx),%xmm0
        +	decl	%eax
        +	movdqa	%xmm14,64(%rsp)
        +.byte	102,15,56,222,241
        +	movdqa	%xmm15,80(%rsp)
        +.byte	102,15,56,222,249
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	jmp	.Lxts_dec_loop6_enter
        +
        +.align	16
        +.Lxts_dec_loop6:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.Lxts_dec_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	(%rcx),%xmm0
        +	jnz	.Lxts_dec_loop6
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,222,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,222,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,222,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +	movups	16(%rcx),%xmm1
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,222,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,222,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,222,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	32(%rcx),%xmm0
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,222,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,222,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,222,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,223,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,223,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,223,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	xorps	0(%rsp),%xmm2
        +	pand	%xmm8,%xmm9
        +	xorps	16(%rsp),%xmm3
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +
        +	xorps	32(%rsp),%xmm4
        +	movups	%xmm2,0(%rsi)
        +	xorps	48(%rsp),%xmm5
        +	movups	%xmm3,16(%rsi)
        +	xorps	64(%rsp),%xmm6
        +	movups	%xmm4,32(%rsi)
        +	xorps	80(%rsp),%xmm7
        +	movups	%xmm5,48(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	subq	$96,%rdx
        +	jnc	.Lxts_dec_grandloop
        +
        +	leal	3(%rax,%rax,1),%eax
        +	movq	%r11,%rcx
        +	movl	%eax,%r10d
        +
        +.Lxts_dec_short:
        +	addq	$96,%rdx
        +	jz	.Lxts_dec_done
        +
        +	cmpq	$32,%rdx
        +	jb	.Lxts_dec_one
        +	je	.Lxts_dec_two
        +
        +	cmpq	$64,%rdx
        +	jb	.Lxts_dec_three
        +	je	.Lxts_dec_four
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	leaq	80(%rdi),%rdi
        +	pxor	%xmm12,%xmm4
        +	pxor	%xmm13,%xmm5
        +	pxor	%xmm14,%xmm6
        +
        +	call	_aesni_decrypt6
        +
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movdqu	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movdqu	%xmm3,16(%rsi)
        +	xorps	%xmm14,%xmm6
        +	movdqu	%xmm4,32(%rsi)
        +	pxor	%xmm14,%xmm14
        +	movdqu	%xmm5,48(%rsi)
        +	pcmpgtd	%xmm15,%xmm14
        +	movdqu	%xmm6,64(%rsi)
        +	leaq	80(%rsi),%rsi
        +	pshufd	$19,%xmm14,%xmm11
        +	andq	$15,%r9
        +	jz	.Lxts_dec_ret
        +
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm11
        +	pxor	%xmm15,%xmm11
        +	jmp	.Lxts_dec_done2
        +
        +.align	16
        +.Lxts_dec_one:
        +	movups	(%rdi),%xmm2
        +	leaq	16(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_dec1_12:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_dec1_12
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm11,%xmm10
        +	movups	%xmm2,(%rsi)
        +	movdqa	%xmm12,%xmm11
        +	leaq	16(%rsi),%rsi
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_two:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	leaq	32(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm12,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movdqa	%xmm13,%xmm11
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	leaq	32(%rsi),%rsi
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_three:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	32(%rdi),%xmm4
        +	leaq	48(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm13,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movdqa	%xmm15,%xmm11
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	leaq	48(%rsi),%rsi
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_four:
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movups	(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movups	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movups	32(%rdi),%xmm4
        +	xorps	%xmm10,%xmm2
        +	movups	48(%rdi),%xmm5
        +	leaq	64(%rdi),%rdi
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	xorps	%xmm13,%xmm5
        +
        +	call	_aesni_decrypt4
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm14,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movdqa	%xmm15,%xmm11
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	leaq	64(%rsi),%rsi
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_done:
        +	andq	$15,%r9
        +	jz	.Lxts_dec_ret
        +.Lxts_dec_done2:
        +	movq	%r9,%rdx
        +	movq	%r11,%rcx
        +	movl	%r10d,%eax
        +
        +	movups	(%rdi),%xmm2
        +	xorps	%xmm11,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_dec1_13:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_dec1_13
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm11,%xmm2
        +	movups	%xmm2,(%rsi)
        +
        +.Lxts_dec_steal:
        +	movzbl	16(%rdi),%eax
        +	movzbl	(%rsi),%ecx
        +	leaq	1(%rdi),%rdi
        +	movb	%al,(%rsi)
        +	movb	%cl,16(%rsi)
        +	leaq	1(%rsi),%rsi
        +	subq	$1,%rdx
        +	jnz	.Lxts_dec_steal
        +
        +	subq	%r9,%rsi
        +	movq	%r11,%rcx
        +	movl	%r10d,%eax
        +
        +	movups	(%rsi),%xmm2
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_dec1_14:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_dec1_14
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm10,%xmm2
        +	movups	%xmm2,(%rsi)
        +
        +.Lxts_dec_ret:
        +	leaq	104(%rsp),%rsp
        +.Lxts_dec_epilogue:
        +	.byte	0xf3,0xc3
        +.size	aesni_xts_decrypt,.-aesni_xts_decrypt
        +.globl	aesni_cbc_encrypt
        +.type	aesni_cbc_encrypt,@function
        +.align	16
        +aesni_cbc_encrypt:
        +	testq	%rdx,%rdx
        +	jz	.Lcbc_ret
        +
        +	movl	240(%rcx),%r10d
        +	movq	%rcx,%r11
        +	testl	%r9d,%r9d
        +	jz	.Lcbc_decrypt
        +
        +	movups	(%r8),%xmm2
        +	movl	%r10d,%eax
        +	cmpq	$16,%rdx
        +	jb	.Lcbc_enc_tail
        +	subq	$16,%rdx
        +	jmp	.Lcbc_enc_loop
        +.align	16
        +.Lcbc_enc_loop:
        +	movups	(%rdi),%xmm3
        +	leaq	16(%rdi),%rdi
        +
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	xorps	%xmm0,%xmm3
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm3,%xmm2
        +.Loop_enc1_15:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_enc1_15
        +
        +.byte	102,15,56,221,209
        +	movl	%r10d,%eax
        +	movq	%r11,%rcx
        +	movups	%xmm2,0(%rsi)
        +	leaq	16(%rsi),%rsi
        +	subq	$16,%rdx
        +	jnc	.Lcbc_enc_loop
        +	addq	$16,%rdx
        +	jnz	.Lcbc_enc_tail
        +	movups	%xmm2,(%r8)
        +	jmp	.Lcbc_ret
        +
        +.Lcbc_enc_tail:
        +	movq	%rdx,%rcx
        +	xchgq	%rdi,%rsi
        +.long	0x9066A4F3
        +
        +	movl	$16,%ecx
        +	subq	%rdx,%rcx
        +	xorl	%eax,%eax
        +.long	0x9066AAF3
        +
        +	leaq	-16(%rdi),%rdi
        +	movl	%r10d,%eax
        +	movq	%rdi,%rsi
        +	movq	%r11,%rcx
        +	xorq	%rdx,%rdx
        +	jmp	.Lcbc_enc_loop
        +
        +
        +.align	16
        +.Lcbc_decrypt:
        +	movups	(%r8),%xmm9
        +	movl	%r10d,%eax
        +	cmpq	$112,%rdx
        +	jbe	.Lcbc_dec_tail
        +	shrl	$1,%r10d
        +	subq	$112,%rdx
        +	movl	%r10d,%eax
        +	movaps	%xmm9,-24(%rsp)
        +	jmp	.Lcbc_dec_loop8_enter
        +.align	16
        +.Lcbc_dec_loop8:
        +	movaps	%xmm0,-24(%rsp)
        +	movups	%xmm9,(%rsi)
        +	leaq	16(%rsi),%rsi
        +.Lcbc_dec_loop8_enter:
        +	movups	(%rcx),%xmm0
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	16(%rcx),%xmm1
        +
        +	leaq	32(%rcx),%rcx
        +	movdqu	32(%rdi),%xmm4
        +	xorps	%xmm0,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	xorps	%xmm0,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +	movdqu	80(%rdi),%xmm7
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +	movdqu	96(%rdi),%xmm8
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +	movdqu	112(%rdi),%xmm9
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,222,241
        +	pxor	%xmm0,%xmm8
        +.byte	102,15,56,222,249
        +	pxor	%xmm0,%xmm9
        +	movups	(%rcx),%xmm0
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +	movups	16(%rcx),%xmm1
        +
        +	call	.Ldec_loop8_enter
        +
        +	movups	(%rdi),%xmm1
        +	movups	16(%rdi),%xmm0
        +	xorps	-24(%rsp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%rdi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%rdi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%rdi),%xmm1
        +	xorps	%xmm0,%xmm6
        +	movups	80(%rdi),%xmm0
        +	xorps	%xmm1,%xmm7
        +	movups	96(%rdi),%xmm1
        +	xorps	%xmm0,%xmm8
        +	movups	112(%rdi),%xmm0
        +	xorps	%xmm1,%xmm9
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm6,64(%rsi)
        +	movq	%r11,%rcx
        +	movups	%xmm7,80(%rsi)
        +	leaq	128(%rdi),%rdi
        +	movups	%xmm8,96(%rsi)
        +	leaq	112(%rsi),%rsi
        +	subq	$128,%rdx
        +	ja	.Lcbc_dec_loop8
        +
        +	movaps	%xmm9,%xmm2
        +	movaps	%xmm0,%xmm9
        +	addq	$112,%rdx
        +	jle	.Lcbc_dec_tail_collected
        +	movups	%xmm2,(%rsi)
        +	leal	1(%r10,%r10,1),%eax
        +	leaq	16(%rsi),%rsi
        +.Lcbc_dec_tail:
        +	movups	(%rdi),%xmm2
        +	movaps	%xmm2,%xmm8
        +	cmpq	$16,%rdx
        +	jbe	.Lcbc_dec_one
        +
        +	movups	16(%rdi),%xmm3
        +	movaps	%xmm3,%xmm7
        +	cmpq	$32,%rdx
        +	jbe	.Lcbc_dec_two
        +
        +	movups	32(%rdi),%xmm4
        +	movaps	%xmm4,%xmm6
        +	cmpq	$48,%rdx
        +	jbe	.Lcbc_dec_three
        +
        +	movups	48(%rdi),%xmm5
        +	cmpq	$64,%rdx
        +	jbe	.Lcbc_dec_four
        +
        +	movups	64(%rdi),%xmm6
        +	cmpq	$80,%rdx
        +	jbe	.Lcbc_dec_five
        +
        +	movups	80(%rdi),%xmm7
        +	cmpq	$96,%rdx
        +	jbe	.Lcbc_dec_six
        +
        +	movups	96(%rdi),%xmm8
        +	movaps	%xmm9,-24(%rsp)
        +	call	_aesni_decrypt8
        +	movups	(%rdi),%xmm1
        +	movups	16(%rdi),%xmm0
        +	xorps	-24(%rsp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%rdi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%rdi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%rdi),%xmm1
        +	xorps	%xmm0,%xmm6
        +	movups	80(%rdi),%xmm0
        +	xorps	%xmm1,%xmm7
        +	movups	96(%rdi),%xmm9
        +	xorps	%xmm0,%xmm8
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	movaps	%xmm8,%xmm2
        +	subq	$112,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +.Loop_dec1_16:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	.Loop_dec1_16
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm9,%xmm2
        +	movaps	%xmm8,%xmm9
        +	subq	$16,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_decrypt3
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	movups	%xmm2,(%rsi)
        +	movaps	%xmm7,%xmm9
        +	movaps	%xmm3,%xmm2
        +	leaq	16(%rsi),%rsi
        +	subq	$32,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_three:
        +	call	_aesni_decrypt3
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm3,16(%rsi)
        +	movaps	%xmm6,%xmm9
        +	movaps	%xmm4,%xmm2
        +	leaq	32(%rsi),%rsi
        +	subq	$48,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_four:
        +	call	_aesni_decrypt4
        +	xorps	%xmm9,%xmm2
        +	movups	48(%rdi),%xmm9
        +	xorps	%xmm8,%xmm3
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm3,16(%rsi)
        +	xorps	%xmm6,%xmm5
        +	movups	%xmm4,32(%rsi)
        +	movaps	%xmm5,%xmm2
        +	leaq	48(%rsi),%rsi
        +	subq	$64,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_five:
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_decrypt6
        +	movups	16(%rdi),%xmm1
        +	movups	32(%rdi),%xmm0
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	xorps	%xmm1,%xmm4
        +	movups	48(%rdi),%xmm1
        +	xorps	%xmm0,%xmm5
        +	movups	64(%rdi),%xmm9
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	leaq	64(%rsi),%rsi
        +	movaps	%xmm6,%xmm2
        +	subq	$80,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_six:
        +	call	_aesni_decrypt6
        +	movups	16(%rdi),%xmm1
        +	movups	32(%rdi),%xmm0
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	xorps	%xmm1,%xmm4
        +	movups	48(%rdi),%xmm1
        +	xorps	%xmm0,%xmm5
        +	movups	64(%rdi),%xmm0
        +	xorps	%xmm1,%xmm6
        +	movups	80(%rdi),%xmm9
        +	xorps	%xmm0,%xmm7
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	leaq	80(%rsi),%rsi
        +	movaps	%xmm7,%xmm2
        +	subq	$96,%rdx
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_tail_collected:
        +	andq	$15,%rdx
        +	movups	%xmm9,(%r8)
        +	jnz	.Lcbc_dec_tail_partial
        +	movups	%xmm2,(%rsi)
        +	jmp	.Lcbc_dec_ret
        +.align	16
        +.Lcbc_dec_tail_partial:
        +	movaps	%xmm2,-24(%rsp)
        +	movq	$16,%rcx
        +	movq	%rsi,%rdi
        +	subq	%rdx,%rcx
        +	leaq	-24(%rsp),%rsi
        +.long	0x9066A4F3
        +
        +
        +.Lcbc_dec_ret:
        +.Lcbc_ret:
        +	.byte	0xf3,0xc3
        +.size	aesni_cbc_encrypt,.-aesni_cbc_encrypt
        +.globl	aesni_set_decrypt_key
        +.type	aesni_set_decrypt_key,@function
        +.align	16
        +aesni_set_decrypt_key:
        +.byte	0x48,0x83,0xEC,0x08
        +
        +	call	__aesni_set_encrypt_key
        +	shll	$4,%esi
        +	testl	%eax,%eax
        +	jnz	.Ldec_key_ret
        +	leaq	16(%rdx,%rsi,1),%rdi
        +
        +	movups	(%rdx),%xmm0
        +	movups	(%rdi),%xmm1
        +	movups	%xmm0,(%rdi)
        +	movups	%xmm1,(%rdx)
        +	leaq	16(%rdx),%rdx
        +	leaq	-16(%rdi),%rdi
        +
        +.Ldec_key_inverse:
        +	movups	(%rdx),%xmm0
        +	movups	(%rdi),%xmm1
        +.byte	102,15,56,219,192
        +.byte	102,15,56,219,201
        +	leaq	16(%rdx),%rdx
        +	leaq	-16(%rdi),%rdi
        +	movups	%xmm0,16(%rdi)
        +	movups	%xmm1,-16(%rdx)
        +	cmpq	%rdx,%rdi
        +	ja	.Ldec_key_inverse
        +
        +	movups	(%rdx),%xmm0
        +.byte	102,15,56,219,192
        +	movups	%xmm0,(%rdi)
        +.Ldec_key_ret:
        +	addq	$8,%rsp
        +	.byte	0xf3,0xc3
        +.LSEH_end_set_decrypt_key:
        +.size	aesni_set_decrypt_key,.-aesni_set_decrypt_key
        +.globl	aesni_set_encrypt_key
        +.type	aesni_set_encrypt_key,@function
        +.align	16
        +aesni_set_encrypt_key:
        +__aesni_set_encrypt_key:
        +.byte	0x48,0x83,0xEC,0x08
        +
        +	movq	$-1,%rax
        +	testq	%rdi,%rdi
        +	jz	.Lenc_key_ret
        +	testq	%rdx,%rdx
        +	jz	.Lenc_key_ret
        +
        +	movups	(%rdi),%xmm0
        +	xorps	%xmm4,%xmm4
        +	leaq	16(%rdx),%rax
        +	cmpl	$256,%esi
        +	je	.L14rounds
        +	cmpl	$192,%esi
        +	je	.L12rounds
        +	cmpl	$128,%esi
        +	jne	.Lbad_keybits
        +
        +.L10rounds:
        +	movl	$9,%esi
        +	movups	%xmm0,(%rdx)
        +.byte	102,15,58,223,200,1
        +	call	.Lkey_expansion_128_cold
        +.byte	102,15,58,223,200,2
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,4
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,8
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,16
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,32
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,64
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,128
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,27
        +	call	.Lkey_expansion_128
        +.byte	102,15,58,223,200,54
        +	call	.Lkey_expansion_128
        +	movups	%xmm0,(%rax)
        +	movl	%esi,80(%rax)
        +	xorl	%eax,%eax
        +	jmp	.Lenc_key_ret
        +
        +.align	16
        +.L12rounds:
        +	movq	16(%rdi),%xmm2
        +	movl	$11,%esi
        +	movups	%xmm0,(%rdx)
        +.byte	102,15,58,223,202,1
        +	call	.Lkey_expansion_192a_cold
        +.byte	102,15,58,223,202,2
        +	call	.Lkey_expansion_192b
        +.byte	102,15,58,223,202,4
        +	call	.Lkey_expansion_192a
        +.byte	102,15,58,223,202,8
        +	call	.Lkey_expansion_192b
        +.byte	102,15,58,223,202,16
        +	call	.Lkey_expansion_192a
        +.byte	102,15,58,223,202,32
        +	call	.Lkey_expansion_192b
        +.byte	102,15,58,223,202,64
        +	call	.Lkey_expansion_192a
        +.byte	102,15,58,223,202,128
        +	call	.Lkey_expansion_192b
        +	movups	%xmm0,(%rax)
        +	movl	%esi,48(%rax)
        +	xorq	%rax,%rax
        +	jmp	.Lenc_key_ret
        +
        +.align	16
        +.L14rounds:
        +	movups	16(%rdi),%xmm2
        +	movl	$13,%esi
        +	leaq	16(%rax),%rax
        +	movups	%xmm0,(%rdx)
        +	movups	%xmm2,16(%rdx)
        +.byte	102,15,58,223,202,1
        +	call	.Lkey_expansion_256a_cold
        +.byte	102,15,58,223,200,1
        +	call	.Lkey_expansion_256b
        +.byte	102,15,58,223,202,2
        +	call	.Lkey_expansion_256a
        +.byte	102,15,58,223,200,2
        +	call	.Lkey_expansion_256b
        +.byte	102,15,58,223,202,4
        +	call	.Lkey_expansion_256a
        +.byte	102,15,58,223,200,4
        +	call	.Lkey_expansion_256b
        +.byte	102,15,58,223,202,8
        +	call	.Lkey_expansion_256a
        +.byte	102,15,58,223,200,8
        +	call	.Lkey_expansion_256b
        +.byte	102,15,58,223,202,16
        +	call	.Lkey_expansion_256a
        +.byte	102,15,58,223,200,16
        +	call	.Lkey_expansion_256b
        +.byte	102,15,58,223,202,32
        +	call	.Lkey_expansion_256a
        +.byte	102,15,58,223,200,32
        +	call	.Lkey_expansion_256b
        +.byte	102,15,58,223,202,64
        +	call	.Lkey_expansion_256a
        +	movups	%xmm0,(%rax)
        +	movl	%esi,16(%rax)
        +	xorq	%rax,%rax
        +	jmp	.Lenc_key_ret
        +
        +.align	16
        +.Lbad_keybits:
        +	movq	$-2,%rax
        +.Lenc_key_ret:
        +	addq	$8,%rsp
        +	.byte	0xf3,0xc3
        +.LSEH_end_set_encrypt_key:
        +
        +.align	16
        +.Lkey_expansion_128:
        +	movups	%xmm0,(%rax)
        +	leaq	16(%rax),%rax
        +.Lkey_expansion_128_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	.byte	0xf3,0xc3
        +
        +.align	16
        +.Lkey_expansion_192a:
        +	movups	%xmm0,(%rax)
        +	leaq	16(%rax),%rax
        +.Lkey_expansion_192a_cold:
        +	movaps	%xmm2,%xmm5
        +.Lkey_expansion_192b_warm:
        +	shufps	$16,%xmm0,%xmm4
        +	movdqa	%xmm2,%xmm3
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	pslldq	$4,%xmm3
        +	xorps	%xmm4,%xmm0
        +	pshufd	$85,%xmm1,%xmm1
        +	pxor	%xmm3,%xmm2
        +	pxor	%xmm1,%xmm0
        +	pshufd	$255,%xmm0,%xmm3
        +	pxor	%xmm3,%xmm2
        +	.byte	0xf3,0xc3
        +
        +.align	16
        +.Lkey_expansion_192b:
        +	movaps	%xmm0,%xmm3
        +	shufps	$68,%xmm0,%xmm5
        +	movups	%xmm5,(%rax)
        +	shufps	$78,%xmm2,%xmm3
        +	movups	%xmm3,16(%rax)
        +	leaq	32(%rax),%rax
        +	jmp	.Lkey_expansion_192b_warm
        +
        +.align	16
        +.Lkey_expansion_256a:
        +	movups	%xmm2,(%rax)
        +	leaq	16(%rax),%rax
        +.Lkey_expansion_256a_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	.byte	0xf3,0xc3
        +
        +.align	16
        +.Lkey_expansion_256b:
        +	movups	%xmm0,(%rax)
        +	leaq	16(%rax),%rax
        +
        +	shufps	$16,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$140,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$170,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm2
        +	.byte	0xf3,0xc3
        +.size	aesni_set_encrypt_key,.-aesni_set_encrypt_key
        +.size	__aesni_set_encrypt_key,.-__aesni_set_encrypt_key
        +.align	64
        +.Lbswap_mask:
        +.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
        +.Lincrement32:
        +.long	6,6,6,0
        +.Lincrement64:
        +.long	1,0,0,0
        +.Lxts_magic:
        +.long	0x87,0,1,0
        +
        +.byte	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	64
        diff --git a/vendor/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s b/vendor/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s
        new file mode 100644
        index 000000000..c980dd073
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/bn/modexp512-x86_64.s
        @@ -0,0 +1,1776 @@
        +.text
        +
        +
        +.type	MULADD_128x512,@function
        +.align	16
        +MULADD_128x512:
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%r8,0(%rcx)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	8(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	movq	%r9,8(%rcx)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%r9
        +	.byte	0xf3,0xc3
        +.size	MULADD_128x512,.-MULADD_128x512
        +.type	mont_reduce,@function
        +.align	16
        +mont_reduce:
        +	leaq	192(%rsp),%rdi
        +	movq	32(%rsp),%rsi
        +	addq	$576,%rsi
        +	leaq	520(%rsp),%rcx
        +
        +	movq	96(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	movq	(%rcx),%r8
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%r8,0(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	movq	8(%rcx),%r9
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	movq	16(%rcx),%r10
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	movq	24(%rcx),%r11
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	movq	32(%rcx),%r12
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	movq	40(%rcx),%r13
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	movq	48(%rcx),%r14
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	movq	56(%rcx),%r15
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	104(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	movq	%r9,8(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%r9
        +	movq	112(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%r10,16(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +	movq	120(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,24(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	xorq	%rax,%rax
        +
        +	addq	64(%rcx),%r8
        +	adcq	72(%rcx),%r9
        +	adcq	80(%rcx),%r10
        +	adcq	88(%rcx),%r11
        +	adcq	$0,%rax
        +
        +
        +
        +
        +	movq	%r8,64(%rdi)
        +	movq	%r9,72(%rdi)
        +	movq	%r10,%rbp
        +	movq	%r11,88(%rdi)
        +
        +	movq	%rax,384(%rsp)
        +
        +	movq	0(%rdi),%r8
        +	movq	8(%rdi),%r9
        +	movq	16(%rdi),%r10
        +	movq	24(%rdi),%r11
        +
        +
        +
        +
        +
        +
        +
        +
        +	addq	$80,%rdi
        +
        +	addq	$64,%rsi
        +	leaq	296(%rsp),%rcx
        +
        +	call	MULADD_128x512
        +
        +
        +	movq	384(%rsp),%rax
        +
        +
        +	addq	-16(%rdi),%r8
        +	adcq	-8(%rdi),%r9
        +	movq	%r8,64(%rcx)
        +	movq	%r9,72(%rcx)
        +
        +	adcq	%rax,%rax
        +	movq	%rax,384(%rsp)
        +
        +	leaq	192(%rsp),%rdi
        +	addq	$64,%rsi
        +
        +
        +
        +
        +
        +	movq	(%rsi),%r8
        +	movq	8(%rsi),%rbx
        +
        +	movq	(%rcx),%rax
        +	mulq	%r8
        +	movq	%rax,%rbp
        +	movq	%rdx,%r9
        +
        +	movq	8(%rcx),%rax
        +	mulq	%r8
        +	addq	%rax,%r9
        +
        +	movq	(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r9
        +
        +	movq	%r9,8(%rdi)
        +
        +
        +	subq	$192,%rsi
        +
        +	movq	(%rcx),%r8
        +	movq	8(%rcx),%r9
        +
        +	call	MULADD_128x512
        +
        +
        +
        +
        +
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	16(%rsi),%rdi
        +	movq	24(%rsi),%rdx
        +
        +
        +	movq	384(%rsp),%rbp
        +
        +	addq	64(%rcx),%r8
        +	adcq	72(%rcx),%r9
        +
        +
        +	adcq	%rbp,%rbp
        +
        +
        +
        +	shlq	$3,%rbp
        +	movq	32(%rsp),%rcx
        +	addq	%rcx,%rbp
        +
        +
        +	xorq	%rsi,%rsi
        +
        +	addq	0(%rbp),%r10
        +	adcq	64(%rbp),%r11
        +	adcq	128(%rbp),%r12
        +	adcq	192(%rbp),%r13
        +	adcq	256(%rbp),%r14
        +	adcq	320(%rbp),%r15
        +	adcq	384(%rbp),%r8
        +	adcq	448(%rbp),%r9
        +
        +
        +
        +	sbbq	$0,%rsi
        +
        +
        +	andq	%rsi,%rax
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdi
        +	andq	%rsi,%rdx
        +
        +	movq	$1,%rbp
        +	subq	%rax,%r10
        +	sbbq	%rbx,%r11
        +	sbbq	%rdi,%r12
        +	sbbq	%rdx,%r13
        +
        +
        +
        +
        +	sbbq	$0,%rbp
        +
        +
        +
        +	addq	$512,%rcx
        +	movq	32(%rcx),%rax
        +	movq	40(%rcx),%rbx
        +	movq	48(%rcx),%rdi
        +	movq	56(%rcx),%rdx
        +
        +
        +
        +	andq	%rsi,%rax
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdi
        +	andq	%rsi,%rdx
        +
        +
        +
        +	subq	$1,%rbp
        +
        +	sbbq	%rax,%r14
        +	sbbq	%rbx,%r15
        +	sbbq	%rdi,%r8
        +	sbbq	%rdx,%r9
        +
        +
        +
        +	movq	144(%rsp),%rsi
        +	movq	%r10,0(%rsi)
        +	movq	%r11,8(%rsi)
        +	movq	%r12,16(%rsi)
        +	movq	%r13,24(%rsi)
        +	movq	%r14,32(%rsi)
        +	movq	%r15,40(%rsi)
        +	movq	%r8,48(%rsi)
        +	movq	%r9,56(%rsi)
        +
        +	.byte	0xf3,0xc3
        +.size	mont_reduce,.-mont_reduce
        +.type	mont_mul_a3b,@function
        +.align	16
        +mont_mul_a3b:
        +
        +
        +
        +
        +	movq	0(%rdi),%rbp
        +
        +	movq	%r10,%rax
        +	mulq	%rbp
        +	movq	%rax,520(%rsp)
        +	movq	%rdx,%r10
        +	movq	%r11,%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	movq	%r12,%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r12
        +	movq	%r13,%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +	movq	%r14,%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%r14
        +	movq	%r15,%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%r15
        +	movq	%r8,%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	%r9,%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%r9
        +	movq	8(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%r10,528(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +	movq	16(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,536(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	movq	24(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,544(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r12
        +	movq	32(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,552(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +	movq	40(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	movq	%r14,560(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%r14
        +	movq	48(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%r15,568(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%r15
        +	movq	56(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%r8,576(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	%r9,584(%rsp)
        +	movq	%r10,592(%rsp)
        +	movq	%r11,600(%rsp)
        +	movq	%r12,608(%rsp)
        +	movq	%r13,616(%rsp)
        +	movq	%r14,624(%rsp)
        +	movq	%r15,632(%rsp)
        +	movq	%r8,640(%rsp)
        +
        +
        +
        +
        +
        +	jmp	mont_reduce
        +
        +
        +.size	mont_mul_a3b,.-mont_mul_a3b
        +.type	sqr_reduce,@function
        +.align	16
        +sqr_reduce:
        +	movq	16(%rsp),%rcx
        +
        +
        +
        +	movq	%r10,%rbx
        +
        +	movq	%r11,%rax
        +	mulq	%rbx
        +	movq	%rax,528(%rsp)
        +	movq	%rdx,%r10
        +	movq	%r12,%rax
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	movq	%r13,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r12
        +	movq	%r14,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +	movq	%r15,%rax
        +	mulq	%rbx
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%r14
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%r15
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rsi
        +
        +	movq	%r10,536(%rsp)
        +
        +
        +
        +
        +
        +	movq	8(%rcx),%rbx
        +
        +	movq	16(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,544(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	24(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%r10,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,552(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	32(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%r10,%r14
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%r10,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%rsi
        +	adcq	$0,%rdx
        +	addq	%r10,%rsi
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r11
        +
        +
        +
        +
        +	movq	16(%rcx),%rbx
        +
        +	movq	24(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,560(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	32(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%r10,%r14
        +	adcq	$0,%rdx
        +	movq	%r14,568(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%r10,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%rsi
        +	adcq	$0,%rdx
        +	addq	%r10,%rsi
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%r10,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r12
        +
        +
        +
        +
        +
        +	movq	24(%rcx),%rbx
        +
        +	movq	32(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%r15,576(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%rsi
        +	adcq	$0,%rdx
        +	addq	%r10,%rsi
        +	adcq	$0,%rdx
        +	movq	%rsi,584(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%r10,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%r10,%r12
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r15
        +
        +
        +
        +
        +	movq	32(%rcx),%rbx
        +
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,592(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%r10,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,600(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%r10,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r11
        +
        +
        +
        +
        +	movq	40(%rcx),%rbx
        +
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%r15,608(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%r10,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,616(%rsp)
        +
        +	movq	%rdx,%r12
        +
        +
        +
        +
        +	movq	%r8,%rbx
        +
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,624(%rsp)
        +
        +	movq	%rdx,632(%rsp)
        +
        +
        +	movq	528(%rsp),%r10
        +	movq	536(%rsp),%r11
        +	movq	544(%rsp),%r12
        +	movq	552(%rsp),%r13
        +	movq	560(%rsp),%r14
        +	movq	568(%rsp),%r15
        +
        +	movq	24(%rcx),%rax
        +	mulq	%rax
        +	movq	%rax,%rdi
        +	movq	%rdx,%r8
        +
        +	addq	%r10,%r10
        +	adcq	%r11,%r11
        +	adcq	%r12,%r12
        +	adcq	%r13,%r13
        +	adcq	%r14,%r14
        +	adcq	%r15,%r15
        +	adcq	$0,%r8
        +
        +	movq	0(%rcx),%rax
        +	mulq	%rax
        +	movq	%rax,520(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbx,%r10
        +	adcq	%rax,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbx
        +	movq	%r10,528(%rsp)
        +	movq	%r11,536(%rsp)
        +
        +	movq	16(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbx,%r12
        +	adcq	%rax,%r13
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbx
        +
        +	movq	%r12,544(%rsp)
        +	movq	%r13,552(%rsp)
        +
        +	xorq	%rbp,%rbp
        +	addq	%rbx,%r14
        +	adcq	%rdi,%r15
        +	adcq	$0,%rbp
        +
        +	movq	%r14,560(%rsp)
        +	movq	%r15,568(%rsp)
        +
        +
        +
        +
        +	movq	576(%rsp),%r10
        +	movq	584(%rsp),%r11
        +	movq	592(%rsp),%r12
        +	movq	600(%rsp),%r13
        +	movq	608(%rsp),%r14
        +	movq	616(%rsp),%r15
        +	movq	624(%rsp),%rdi
        +	movq	632(%rsp),%rsi
        +
        +	movq	%r9,%rax
        +	mulq	%rax
        +	movq	%rax,%r9
        +	movq	%rdx,%rbx
        +
        +	addq	%r10,%r10
        +	adcq	%r11,%r11
        +	adcq	%r12,%r12
        +	adcq	%r13,%r13
        +	adcq	%r14,%r14
        +	adcq	%r15,%r15
        +	adcq	%rdi,%rdi
        +	adcq	%rsi,%rsi
        +	adcq	$0,%rbx
        +
        +	addq	%rbp,%r10
        +
        +	movq	32(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%r8,%r10
        +	adcq	%rax,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbp
        +
        +	movq	%r10,576(%rsp)
        +	movq	%r11,584(%rsp)
        +
        +	movq	40(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbp,%r12
        +	adcq	%rax,%r13
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbp
        +
        +	movq	%r12,592(%rsp)
        +	movq	%r13,600(%rsp)
        +
        +	movq	48(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbp,%r14
        +	adcq	%rax,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%r14,608(%rsp)
        +	movq	%r15,616(%rsp)
        +
        +	addq	%rdx,%rdi
        +	adcq	%r9,%rsi
        +	adcq	$0,%rbx
        +
        +	movq	%rdi,624(%rsp)
        +	movq	%rsi,632(%rsp)
        +	movq	%rbx,640(%rsp)
        +
        +	jmp	mont_reduce
        +
        +
        +.size	sqr_reduce,.-sqr_reduce
        +.globl	mod_exp_512
        +.type	mod_exp_512,@function
        +mod_exp_512:
        +	pushq	%rbp
        +	pushq	%rbx
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +
        +	movq	%rsp,%r8
        +	subq	$2688,%rsp
        +	andq	$-64,%rsp
        +
        +
        +	movq	%r8,0(%rsp)
        +	movq	%rdi,8(%rsp)
        +	movq	%rsi,16(%rsp)
        +	movq	%rcx,24(%rsp)
        +.Lbody:
        +
        +
        +
        +	pxor	%xmm4,%xmm4
        +	movdqu	0(%rsi),%xmm0
        +	movdqu	16(%rsi),%xmm1
        +	movdqu	32(%rsi),%xmm2
        +	movdqu	48(%rsi),%xmm3
        +	movdqa	%xmm4,512(%rsp)
        +	movdqa	%xmm4,528(%rsp)
        +	movdqa	%xmm4,608(%rsp)
        +	movdqa	%xmm4,624(%rsp)
        +	movdqa	%xmm0,544(%rsp)
        +	movdqa	%xmm1,560(%rsp)
        +	movdqa	%xmm2,576(%rsp)
        +	movdqa	%xmm3,592(%rsp)
        +
        +
        +	movdqu	0(%rdx),%xmm0
        +	movdqu	16(%rdx),%xmm1
        +	movdqu	32(%rdx),%xmm2
        +	movdqu	48(%rdx),%xmm3
        +
        +	leaq	384(%rsp),%rbx
        +	movq	%rbx,136(%rsp)
        +	call	mont_reduce
        +
        +
        +	leaq	448(%rsp),%rcx
        +	xorq	%rax,%rax
        +	movq	%rax,0(%rcx)
        +	movq	%rax,8(%rcx)
        +	movq	%rax,24(%rcx)
        +	movq	%rax,32(%rcx)
        +	movq	%rax,40(%rcx)
        +	movq	%rax,48(%rcx)
        +	movq	%rax,56(%rcx)
        +	movq	%rax,128(%rsp)
        +	movq	$1,16(%rcx)
        +
        +	leaq	640(%rsp),%rbp
        +	movq	%rcx,%rsi
        +	movq	%rbp,%rdi
        +	movq	$8,%rax
        +loop_0:
        +	movq	(%rcx),%rbx
        +	movw	%bx,(%rdi)
        +	shrq	$16,%rbx
        +	movw	%bx,64(%rdi)
        +	shrq	$16,%rbx
        +	movw	%bx,128(%rdi)
        +	shrq	$16,%rbx
        +	movw	%bx,192(%rdi)
        +	leaq	8(%rcx),%rcx
        +	leaq	256(%rdi),%rdi
        +	decq	%rax
        +	jnz	loop_0
        +	movq	$31,%rax
        +	movq	%rax,32(%rsp)
        +	movq	%rbp,40(%rsp)
        +
        +	movq	%rsi,136(%rsp)
        +	movq	0(%rsi),%r10
        +	movq	8(%rsi),%r11
        +	movq	16(%rsi),%r12
        +	movq	24(%rsi),%r13
        +	movq	32(%rsi),%r14
        +	movq	40(%rsi),%r15
        +	movq	48(%rsi),%r8
        +	movq	56(%rsi),%r9
        +init_loop:
        +	leaq	384(%rsp),%rdi
        +	call	mont_mul_a3b
        +	leaq	448(%rsp),%rsi
        +	movq	40(%rsp),%rbp
        +	addq	$2,%rbp
        +	movq	%rbp,40(%rsp)
        +	movq	%rsi,%rcx
        +	movq	$8,%rax
        +loop_1:
        +	movq	(%rcx),%rbx
        +	movw	%bx,(%rbp)
        +	shrq	$16,%rbx
        +	movw	%bx,64(%rbp)
        +	shrq	$16,%rbx
        +	movw	%bx,128(%rbp)
        +	shrq	$16,%rbx
        +	movw	%bx,192(%rbp)
        +	leaq	8(%rcx),%rcx
        +	leaq	256(%rbp),%rbp
        +	decq	%rax
        +	jnz	loop_1
        +	movq	32(%rsp),%rax
        +	subq	$1,%rax
        +	movq	%rax,32(%rsp)
        +	jne	init_loop
        +
        +
        +
        +	movdqa	%xmm0,64(%rsp)
        +	movdqa	%xmm1,80(%rsp)
        +	movdqa	%xmm2,96(%rsp)
        +	movdqa	%xmm3,112(%rsp)
        +
        +
        +
        +
        +
        +	movl	126(%rsp),%eax
        +	movq	%rax,%rdx
        +	shrq	$11,%rax
        +	andl	$2047,%edx
        +	movl	%edx,126(%rsp)
        +	leaq	640(%rsp,%rax,2),%rsi
        +	movq	8(%rsp),%rdx
        +	movq	$4,%rbp
        +loop_2:
        +	movzwq	192(%rsi),%rbx
        +	movzwq	448(%rsi),%rax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	128(%rsi),%bx
        +	movw	384(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	64(%rsi),%bx
        +	movw	320(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	0(%rsi),%bx
        +	movw	256(%rsi),%ax
        +	movq	%rbx,0(%rdx)
        +	movq	%rax,8(%rdx)
        +	leaq	512(%rsi),%rsi
        +	leaq	16(%rdx),%rdx
        +	subq	$1,%rbp
        +	jnz	loop_2
        +	movq	$505,48(%rsp)
        +
        +	movq	8(%rsp),%rcx
        +	movq	%rcx,136(%rsp)
        +	movq	0(%rcx),%r10
        +	movq	8(%rcx),%r11
        +	movq	16(%rcx),%r12
        +	movq	24(%rcx),%r13
        +	movq	32(%rcx),%r14
        +	movq	40(%rcx),%r15
        +	movq	48(%rcx),%r8
        +	movq	56(%rcx),%r9
        +	jmp	sqr_2
        +
        +main_loop_a3b:
        +	call	sqr_reduce
        +	call	sqr_reduce
        +	call	sqr_reduce
        +sqr_2:
        +	call	sqr_reduce
        +	call	sqr_reduce
        +
        +
        +
        +	movq	48(%rsp),%rcx
        +	movq	%rcx,%rax
        +	shrq	$4,%rax
        +	movl	64(%rsp,%rax,2),%edx
        +	andq	$15,%rcx
        +	shrq	%cl,%rdx
        +	andq	$31,%rdx
        +
        +	leaq	640(%rsp,%rdx,2),%rsi
        +	leaq	448(%rsp),%rdx
        +	movq	%rdx,%rdi
        +	movq	$4,%rbp
        +loop_3:
        +	movzwq	192(%rsi),%rbx
        +	movzwq	448(%rsi),%rax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	128(%rsi),%bx
        +	movw	384(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	64(%rsi),%bx
        +	movw	320(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	0(%rsi),%bx
        +	movw	256(%rsi),%ax
        +	movq	%rbx,0(%rdx)
        +	movq	%rax,8(%rdx)
        +	leaq	512(%rsi),%rsi
        +	leaq	16(%rdx),%rdx
        +	subq	$1,%rbp
        +	jnz	loop_3
        +	movq	8(%rsp),%rsi
        +	call	mont_mul_a3b
        +
        +
        +
        +	movq	48(%rsp),%rcx
        +	subq	$5,%rcx
        +	movq	%rcx,48(%rsp)
        +	jge	main_loop_a3b
        +
        +
        +
        +end_main_loop_a3b:
        +
        +
        +	movq	8(%rsp),%rdx
        +	pxor	%xmm4,%xmm4
        +	movdqu	0(%rdx),%xmm0
        +	movdqu	16(%rdx),%xmm1
        +	movdqu	32(%rdx),%xmm2
        +	movdqu	48(%rdx),%xmm3
        +	movdqa	%xmm4,576(%rsp)
        +	movdqa	%xmm4,592(%rsp)
        +	movdqa	%xmm4,608(%rsp)
        +	movdqa	%xmm4,624(%rsp)
        +	movdqa	%xmm0,512(%rsp)
        +	movdqa	%xmm1,528(%rsp)
        +	movdqa	%xmm2,544(%rsp)
        +	movdqa	%xmm3,560(%rsp)
        +	call	mont_reduce
        +
        +
        +
        +	movq	8(%rsp),%rax
        +	movq	0(%rax),%r8
        +	movq	8(%rax),%r9
        +	movq	16(%rax),%r10
        +	movq	24(%rax),%r11
        +	movq	32(%rax),%r12
        +	movq	40(%rax),%r13
        +	movq	48(%rax),%r14
        +	movq	56(%rax),%r15
        +
        +
        +	movq	24(%rsp),%rbx
        +	addq	$512,%rbx
        +
        +	subq	0(%rbx),%r8
        +	sbbq	8(%rbx),%r9
        +	sbbq	16(%rbx),%r10
        +	sbbq	24(%rbx),%r11
        +	sbbq	32(%rbx),%r12
        +	sbbq	40(%rbx),%r13
        +	sbbq	48(%rbx),%r14
        +	sbbq	56(%rbx),%r15
        +
        +
        +	movq	0(%rax),%rsi
        +	movq	8(%rax),%rdi
        +	movq	16(%rax),%rcx
        +	movq	24(%rax),%rdx
        +	cmovncq	%r8,%rsi
        +	cmovncq	%r9,%rdi
        +	cmovncq	%r10,%rcx
        +	cmovncq	%r11,%rdx
        +	movq	%rsi,0(%rax)
        +	movq	%rdi,8(%rax)
        +	movq	%rcx,16(%rax)
        +	movq	%rdx,24(%rax)
        +
        +	movq	32(%rax),%rsi
        +	movq	40(%rax),%rdi
        +	movq	48(%rax),%rcx
        +	movq	56(%rax),%rdx
        +	cmovncq	%r12,%rsi
        +	cmovncq	%r13,%rdi
        +	cmovncq	%r14,%rcx
        +	cmovncq	%r15,%rdx
        +	movq	%rsi,32(%rax)
        +	movq	%rdi,40(%rax)
        +	movq	%rcx,48(%rax)
        +	movq	%rdx,56(%rax)
        +
        +	movq	0(%rsp),%rsi
        +	movq	0(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbx
        +	movq	40(%rsi),%rbp
        +	leaq	48(%rsi),%rsp
        +.Lepilogue:
        +	.byte	0xf3,0xc3
        +.size	mod_exp_512, . - mod_exp_512
        diff --git a/vendor/openssl/asm/x64-elf-gas/bn/x86_64-mont.s b/vendor/openssl/asm/x64-elf-gas/bn/x86_64-mont.s
        new file mode 100644
        index 000000000..ea12bd408
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/bn/x86_64-mont.s
        @@ -0,0 +1,1375 @@
        +.text
        +
        +
        +.globl	bn_mul_mont
        +.type	bn_mul_mont,@function
        +.align	16
        +bn_mul_mont:
        +	testl	$3,%r9d
        +	jnz	.Lmul_enter
        +	cmpl	$8,%r9d
        +	jb	.Lmul_enter
        +	cmpq	%rsi,%rdx
        +	jne	.Lmul4x_enter
        +	jmp	.Lsqr4x_enter
        +
        +.align	16
        +.Lmul_enter:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	movl	%r9d,%r9d
        +	leaq	2(%r9),%r10
        +	movq	%rsp,%r11
        +	negq	%r10
        +	leaq	(%rsp,%r10,8),%rsp
        +	andq	$-1024,%rsp
        +
        +	movq	%r11,8(%rsp,%r9,8)
        +.Lmul_body:
        +	movq	%rdx,%r12
        +	movq	(%r8),%r8
        +	movq	(%r12),%rbx
        +	movq	(%rsi),%rax
        +
        +	xorq	%r14,%r14
        +	xorq	%r15,%r15
        +
        +	movq	%r8,%rbp
        +	mulq	%rbx
        +	movq	%rax,%r10
        +	movq	(%rcx),%rax
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +
        +	leaq	1(%r15),%r15
        +	jmp	.L1st_enter
        +
        +.align	16
        +.L1st:
        +	addq	%rax,%r13
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%r13
        +	movq	%r10,%r11
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +.L1st_enter:
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	leaq	1(%r15),%r15
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	cmpq	%r9,%r15
        +	jne	.L1st
        +
        +	addq	%rax,%r13
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +	movq	%r10,%r11
        +
        +	xorq	%rdx,%rdx
        +	addq	%r11,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r9,8)
        +	movq	%rdx,(%rsp,%r9,8)
        +
        +	leaq	1(%r14),%r14
        +	jmp	.Louter
        +.align	16
        +.Louter:
        +	movq	(%r12,%r14,8),%rbx
        +	xorq	%r15,%r15
        +	movq	%r8,%rbp
        +	movq	(%rsp),%r10
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx),%rax
        +	adcq	$0,%rdx
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	8(%rsp),%r10
        +	movq	%rdx,%r13
        +
        +	leaq	1(%r15),%r15
        +	jmp	.Linner_enter
        +
        +.align	16
        +.Linner:
        +	addq	%rax,%r13
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	movq	(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +.Linner_enter:
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%r10
        +	movq	%rdx,%r11
        +	adcq	$0,%r11
        +	leaq	1(%r15),%r15
        +
        +	mulq	%rbp
        +	cmpq	%r9,%r15
        +	jne	.Linner
        +
        +	addq	%rax,%r13
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	movq	(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	xorq	%rdx,%rdx
        +	addq	%r11,%r13
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r9,8)
        +	movq	%rdx,(%rsp,%r9,8)
        +
        +	leaq	1(%r14),%r14
        +	cmpq	%r9,%r14
        +	jl	.Louter
        +
        +	xorq	%r14,%r14
        +	movq	(%rsp),%rax
        +	leaq	(%rsp),%rsi
        +	movq	%r9,%r15
        +	jmp	.Lsub
        +.align	16
        +.Lsub:	sbbq	(%rcx,%r14,8),%rax
        +	movq	%rax,(%rdi,%r14,8)
        +	movq	8(%rsi,%r14,8),%rax
        +	leaq	1(%r14),%r14
        +	decq	%r15
        +	jnz	.Lsub
        +
        +	sbbq	$0,%rax
        +	xorq	%r14,%r14
        +	andq	%rax,%rsi
        +	notq	%rax
        +	movq	%rdi,%rcx
        +	andq	%rax,%rcx
        +	movq	%r9,%r15
        +	orq	%rcx,%rsi
        +.align	16
        +.Lcopy:
        +	movq	(%rsi,%r14,8),%rax
        +	movq	%r14,(%rsp,%r14,8)
        +	movq	%rax,(%rdi,%r14,8)
        +	leaq	1(%r14),%r14
        +	subq	$1,%r15
        +	jnz	.Lcopy
        +
        +	movq	8(%rsp,%r9,8),%rsi
        +	movq	$1,%rax
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lmul_epilogue:
        +	.byte	0xf3,0xc3
        +.size	bn_mul_mont,.-bn_mul_mont
        +.type	bn_mul4x_mont,@function
        +.align	16
        +bn_mul4x_mont:
        +.Lmul4x_enter:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	movl	%r9d,%r9d
        +	leaq	4(%r9),%r10
        +	movq	%rsp,%r11
        +	negq	%r10
        +	leaq	(%rsp,%r10,8),%rsp
        +	andq	$-1024,%rsp
        +
        +	movq	%r11,8(%rsp,%r9,8)
        +.Lmul4x_body:
        +	movq	%rdi,16(%rsp,%r9,8)
        +	movq	%rdx,%r12
        +	movq	(%r8),%r8
        +	movq	(%r12),%rbx
        +	movq	(%rsi),%rax
        +
        +	xorq	%r14,%r14
        +	xorq	%r15,%r15
        +
        +	movq	%r8,%rbp
        +	mulq	%rbx
        +	movq	%rax,%r10
        +	movq	(%rcx),%rax
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	16(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	leaq	4(%r15),%r15
        +	adcq	$0,%rdx
        +	movq	%rdi,(%rsp)
        +	movq	%rdx,%r13
        +	jmp	.L1st4x
        +.align	16
        +.L1st4x:
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	leaq	4(%r15),%r15
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	-16(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-32(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +	cmpq	%r9,%r15
        +	jl	.L1st4x
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	xorq	%rdi,%rdi
        +	addq	%r10,%r13
        +	adcq	$0,%rdi
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdi,(%rsp,%r15,8)
        +
        +	leaq	1(%r14),%r14
        +.align	4
        +.Louter4x:
        +	movq	(%r12,%r14,8),%rbx
        +	xorq	%r15,%r15
        +	movq	(%rsp),%r10
        +	movq	%r8,%rbp
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx),%rax
        +	adcq	$0,%rdx
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx),%rax
        +	adcq	$0,%rdx
        +	addq	8(%rsp),%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	16(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	leaq	4(%r15),%r15
        +	adcq	$0,%rdx
        +	movq	%rdi,(%rsp)
        +	movq	%rdx,%r13
        +	jmp	.Linner4x
        +.align	16
        +.Linner4x:
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-16(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-8(%rsp,%r15,8),%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	8(%rsp,%r15,8),%r11
        +	adcq	$0,%rdx
        +	leaq	4(%r15),%r15
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	-16(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-32(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +	cmpq	%r9,%r15
        +	jl	.Linner4x
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-16(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-8(%rsp,%r15,8),%r11
        +	adcq	$0,%rdx
        +	leaq	1(%r14),%r14
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	xorq	%rdi,%rdi
        +	addq	%r10,%r13
        +	adcq	$0,%rdi
        +	addq	(%rsp,%r9,8),%r13
        +	adcq	$0,%rdi
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdi,(%rsp,%r15,8)
        +
        +	cmpq	%r9,%r14
        +	jl	.Louter4x
        +	movq	16(%rsp,%r9,8),%rdi
        +	movq	0(%rsp),%rax
        +	pxor	%xmm0,%xmm0
        +	movq	8(%rsp),%rdx
        +	shrq	$2,%r9
        +	leaq	(%rsp),%rsi
        +	xorq	%r14,%r14
        +
        +	subq	0(%rcx),%rax
        +	movq	16(%rsi),%rbx
        +	movq	24(%rsi),%rbp
        +	sbbq	8(%rcx),%rdx
        +	leaq	-1(%r9),%r15
        +	jmp	.Lsub4x
        +.align	16
        +.Lsub4x:
        +	movq	%rax,0(%rdi,%r14,8)
        +	movq	%rdx,8(%rdi,%r14,8)
        +	sbbq	16(%rcx,%r14,8),%rbx
        +	movq	32(%rsi,%r14,8),%rax
        +	movq	40(%rsi,%r14,8),%rdx
        +	sbbq	24(%rcx,%r14,8),%rbp
        +	movq	%rbx,16(%rdi,%r14,8)
        +	movq	%rbp,24(%rdi,%r14,8)
        +	sbbq	32(%rcx,%r14,8),%rax
        +	movq	48(%rsi,%r14,8),%rbx
        +	movq	56(%rsi,%r14,8),%rbp
        +	sbbq	40(%rcx,%r14,8),%rdx
        +	leaq	4(%r14),%r14
        +	decq	%r15
        +	jnz	.Lsub4x
        +
        +	movq	%rax,0(%rdi,%r14,8)
        +	movq	32(%rsi,%r14,8),%rax
        +	sbbq	16(%rcx,%r14,8),%rbx
        +	movq	%rdx,8(%rdi,%r14,8)
        +	sbbq	24(%rcx,%r14,8),%rbp
        +	movq	%rbx,16(%rdi,%r14,8)
        +
        +	sbbq	$0,%rax
        +	movq	%rbp,24(%rdi,%r14,8)
        +	xorq	%r14,%r14
        +	andq	%rax,%rsi
        +	notq	%rax
        +	movq	%rdi,%rcx
        +	andq	%rax,%rcx
        +	leaq	-1(%r9),%r15
        +	orq	%rcx,%rsi
        +
        +	movdqu	(%rsi),%xmm1
        +	movdqa	%xmm0,(%rsp)
        +	movdqu	%xmm1,(%rdi)
        +	jmp	.Lcopy4x
        +.align	16
        +.Lcopy4x:
        +	movdqu	16(%rsi,%r14,1),%xmm2
        +	movdqu	32(%rsi,%r14,1),%xmm1
        +	movdqa	%xmm0,16(%rsp,%r14,1)
        +	movdqu	%xmm2,16(%rdi,%r14,1)
        +	movdqa	%xmm0,32(%rsp,%r14,1)
        +	movdqu	%xmm1,32(%rdi,%r14,1)
        +	leaq	32(%r14),%r14
        +	decq	%r15
        +	jnz	.Lcopy4x
        +
        +	shlq	$2,%r9
        +	movdqu	16(%rsi,%r14,1),%xmm2
        +	movdqa	%xmm0,16(%rsp,%r14,1)
        +	movdqu	%xmm2,16(%rdi,%r14,1)
        +	movq	8(%rsp,%r9,8),%rsi
        +	movq	$1,%rax
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lmul4x_epilogue:
        +	.byte	0xf3,0xc3
        +.size	bn_mul4x_mont,.-bn_mul4x_mont
        +.type	bn_sqr4x_mont,@function
        +.align	16
        +bn_sqr4x_mont:
        +.Lsqr4x_enter:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	shll	$3,%r9d
        +	xorq	%r10,%r10
        +	movq	%rsp,%r11
        +	subq	%r9,%r10
        +	movq	(%r8),%r8
        +	leaq	-72(%rsp,%r10,2),%rsp
        +	andq	$-1024,%rsp
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +	movq	%rdi,32(%rsp)
        +	movq	%rcx,40(%rsp)
        +	movq	%r8,48(%rsp)
        +	movq	%r11,56(%rsp)
        +.Lsqr4x_body:
        +
        +
        +
        +
        +
        +
        +
        +	leaq	32(%r10),%rbp
        +	leaq	(%rsi,%r9,1),%rsi
        +
        +	movq	%r9,%rcx
        +
        +
        +	movq	-32(%rsi,%rbp,1),%r14
        +	leaq	64(%rsp,%r9,2),%rdi
        +	movq	-24(%rsi,%rbp,1),%rax
        +	leaq	-32(%rdi,%rbp,1),%rdi
        +	movq	-16(%rsi,%rbp,1),%rbx
        +	movq	%rax,%r15
        +
        +	mulq	%r14
        +	movq	%rax,%r10
        +	movq	%rbx,%rax
        +	movq	%rdx,%r11
        +	movq	%r10,-24(%rdi,%rbp,1)
        +
        +	xorq	%r10,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,-16(%rdi,%rbp,1)
        +
        +	leaq	-16(%rbp),%rcx
        +
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	mulq	%r15
        +	movq	%rax,%r12
        +	movq	%rbx,%rax
        +	movq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	leaq	16(%rcx),%rcx
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi,%rcx,1)
        +	jmp	.Lsqr4x_1st
        +
        +.align	16
        +.Lsqr4x_1st:
        +	movq	(%rsi,%rcx,1),%rbx
        +	xorq	%r12,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,(%rdi,%rcx,1)
        +
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,8(%rdi,%rcx,1)
        +
        +	movq	16(%rsi,%rcx,1),%rbx
        +	xorq	%r12,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,16(%rdi,%rcx,1)
        +
        +
        +	movq	24(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	leaq	32(%rcx),%rcx
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi,%rcx,1)
        +
        +	cmpq	$0,%rcx
        +	jne	.Lsqr4x_1st
        +
        +	xorq	%r12,%r12
        +	addq	%r11,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	adcq	%rdx,%r12
        +
        +	movq	%r13,(%rdi)
        +	leaq	16(%rbp),%rbp
        +	movq	%r12,8(%rdi)
        +	jmp	.Lsqr4x_outer
        +
        +.align	16
        +.Lsqr4x_outer:
        +	movq	-32(%rsi,%rbp,1),%r14
        +	leaq	64(%rsp,%r9,2),%rdi
        +	movq	-24(%rsi,%rbp,1),%rax
        +	leaq	-32(%rdi,%rbp,1),%rdi
        +	movq	-16(%rsi,%rbp,1),%rbx
        +	movq	%rax,%r15
        +
        +	movq	-24(%rdi,%rbp,1),%r10
        +	xorq	%r11,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-24(%rdi,%rbp,1)
        +
        +	xorq	%r10,%r10
        +	addq	-16(%rdi,%rbp,1),%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,-16(%rdi,%rbp,1)
        +
        +	leaq	-16(%rbp),%rcx
        +	xorq	%r12,%r12
        +
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	8(%rdi,%rcx,1),%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,8(%rdi,%rcx,1)
        +
        +	leaq	16(%rcx),%rcx
        +	jmp	.Lsqr4x_inner
        +
        +.align	16
        +.Lsqr4x_inner:
        +	movq	(%rsi,%rcx,1),%rbx
        +	xorq	%r12,%r12
        +	addq	(%rdi,%rcx,1),%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,(%rdi,%rcx,1)
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	8(%rdi,%rcx,1),%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	leaq	16(%rcx),%rcx
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi,%rcx,1)
        +
        +	cmpq	$0,%rcx
        +	jne	.Lsqr4x_inner
        +
        +	xorq	%r12,%r12
        +	addq	%r11,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	adcq	%rdx,%r12
        +
        +	movq	%r13,(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	addq	$16,%rbp
        +	jnz	.Lsqr4x_outer
        +
        +
        +	movq	-32(%rsi),%r14
        +	leaq	64(%rsp,%r9,2),%rdi
        +	movq	-24(%rsi),%rax
        +	leaq	-32(%rdi,%rbp,1),%rdi
        +	movq	-16(%rsi),%rbx
        +	movq	%rax,%r15
        +
        +	xorq	%r11,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-24(%rdi)
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,-16(%rdi)
        +
        +	movq	-8(%rsi),%rbx
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	$0,%rdx
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	movq	%rdx,%r13
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi)
        +
        +	xorq	%r12,%r12
        +	addq	%r11,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	-16(%rsi),%rax
        +	adcq	%rdx,%r12
        +
        +	movq	%r13,(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	mulq	%rbx
        +	addq	$16,%rbp
        +	xorq	%r14,%r14
        +	subq	%r9,%rbp
        +	xorq	%r15,%r15
        +
        +	addq	%r12,%rax
        +	adcq	$0,%rdx
        +	movq	%rax,8(%rdi)
        +	movq	%rdx,16(%rdi)
        +	movq	%r15,24(%rdi)
        +
        +	movq	-16(%rsi,%rbp,1),%rax
        +	leaq	64(%rsp,%r9,2),%rdi
        +	xorq	%r10,%r10
        +	movq	-24(%rdi,%rbp,2),%r11
        +
        +	leaq	(%r14,%r10,2),%r12
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	-16(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	-8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%r12
        +	movq	-8(%rsi,%rbp,1),%rax
        +	movq	%r12,-32(%rdi,%rbp,2)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,-24(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	movq	0(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%rbx
        +	movq	0(%rsi,%rbp,1),%rax
        +	movq	%rbx,-16(%rdi,%rbp,2)
        +	adcq	%rdx,%r8
        +	leaq	16(%rbp),%rbp
        +	movq	%r8,-40(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	jmp	.Lsqr4x_shift_n_add
        +
        +.align	16
        +.Lsqr4x_shift_n_add:
        +	leaq	(%r14,%r10,2),%r12
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	-16(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	-8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%r12
        +	movq	-8(%rsi,%rbp,1),%rax
        +	movq	%r12,-32(%rdi,%rbp,2)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,-24(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	movq	0(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%rbx
        +	movq	0(%rsi,%rbp,1),%rax
        +	movq	%rbx,-16(%rdi,%rbp,2)
        +	adcq	%rdx,%r8
        +
        +	leaq	(%r14,%r10,2),%r12
        +	movq	%r8,-8(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	16(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	24(%rdi,%rbp,2),%r11
        +	adcq	%rax,%r12
        +	movq	8(%rsi,%rbp,1),%rax
        +	movq	%r12,0(%rdi,%rbp,2)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,8(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	movq	32(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	40(%rdi,%rbp,2),%r11
        +	adcq	%rax,%rbx
        +	movq	16(%rsi,%rbp,1),%rax
        +	movq	%rbx,16(%rdi,%rbp,2)
        +	adcq	%rdx,%r8
        +	movq	%r8,24(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	addq	$32,%rbp
        +	jnz	.Lsqr4x_shift_n_add
        +
        +	leaq	(%r14,%r10,2),%r12
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	-16(%rdi),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	-8(%rdi),%r11
        +	adcq	%rax,%r12
        +	movq	-8(%rsi),%rax
        +	movq	%r12,-32(%rdi)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,-24(%rdi)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	mulq	%rax
        +	negq	%r15
        +	adcq	%rax,%rbx
        +	adcq	%rdx,%r8
        +	movq	%rbx,-16(%rdi)
        +	movq	%r8,-8(%rdi)
        +	movq	40(%rsp),%rsi
        +	movq	48(%rsp),%r8
        +	xorq	%rcx,%rcx
        +	movq	%r9,0(%rsp)
        +	subq	%r9,%rcx
        +	movq	64(%rsp),%r10
        +	movq	%r8,%r14
        +	leaq	64(%rsp,%r9,2),%rax
        +	leaq	64(%rsp,%r9,1),%rdi
        +	movq	%rax,8(%rsp)
        +	leaq	(%rsi,%r9,1),%rsi
        +	xorq	%rbp,%rbp
        +
        +	movq	0(%rsi,%rcx,1),%rax
        +	movq	8(%rsi,%rcx,1),%r9
        +	imulq	%r10,%r14
        +	movq	%rax,%rbx
        +	jmp	.Lsqr4x_mont_outer
        +
        +.align	16
        +.Lsqr4x_mont_outer:
        +	xorq	%r11,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +	movq	%r8,%r15
        +
        +	xorq	%r10,%r10
        +	addq	8(%rdi,%rcx,1),%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +
        +	imulq	%r11,%r15
        +
        +	movq	16(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,8(%rdi,%rcx,1)
        +
        +	xorq	%r11,%r11
        +	addq	16(%rdi,%rcx,1),%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +
        +	movq	24(%rsi,%rcx,1),%r9
        +	xorq	%r12,%r12
        +	addq	%r10,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%r9,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,16(%rdi,%rcx,1)
        +
        +	xorq	%r10,%r10
        +	addq	24(%rdi,%rcx,1),%r11
        +	leaq	32(%rcx),%rcx
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	jmp	.Lsqr4x_mont_inner
        +
        +.align	16
        +.Lsqr4x_mont_inner:
        +	movq	(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,-8(%rdi,%rcx,1)
        +
        +	xorq	%r11,%r11
        +	addq	(%rdi,%rcx,1),%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +
        +	movq	8(%rsi,%rcx,1),%r9
        +	xorq	%r12,%r12
        +	addq	%r10,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%r9,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,(%rdi,%rcx,1)
        +
        +	xorq	%r10,%r10
        +	addq	8(%rdi,%rcx,1),%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +
        +
        +	movq	16(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,8(%rdi,%rcx,1)
        +
        +	xorq	%r11,%r11
        +	addq	16(%rdi,%rcx,1),%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +
        +	movq	24(%rsi,%rcx,1),%r9
        +	xorq	%r12,%r12
        +	addq	%r10,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%r9,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,16(%rdi,%rcx,1)
        +
        +	xorq	%r10,%r10
        +	addq	24(%rdi,%rcx,1),%r11
        +	leaq	32(%rcx),%rcx
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	cmpq	$0,%rcx
        +	jne	.Lsqr4x_mont_inner
        +
        +	subq	0(%rsp),%rcx
        +	movq	%r8,%r14
        +
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%r9,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,-8(%rdi)
        +
        +	xorq	%r11,%r11
        +	addq	(%rdi),%r10
        +	adcq	$0,%r11
        +	movq	0(%rsi,%rcx,1),%rbx
        +	addq	%rbp,%r10
        +	adcq	$0,%r11
        +
        +	imulq	16(%rdi,%rcx,1),%r14
        +	xorq	%r12,%r12
        +	movq	8(%rsi,%rcx,1),%r9
        +	addq	%r10,%r13
        +	movq	16(%rdi,%rcx,1),%r10
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,(%rdi)
        +
        +	xorq	%rbp,%rbp
        +	addq	8(%rdi),%r12
        +	adcq	%rbp,%rbp
        +	addq	%r11,%r12
        +	leaq	16(%rdi),%rdi
        +	adcq	$0,%rbp
        +	movq	%r12,-8(%rdi)
        +	cmpq	8(%rsp),%rdi
        +	jb	.Lsqr4x_mont_outer
        +
        +	movq	0(%rsp),%r9
        +	movq	%rbp,(%rdi)
        +	movq	64(%rsp,%r9,1),%rax
        +	leaq	64(%rsp,%r9,1),%rbx
        +	movq	40(%rsp),%rsi
        +	shrq	$5,%r9
        +	movq	8(%rbx),%rdx
        +	xorq	%rbp,%rbp
        +
        +	movq	32(%rsp),%rdi
        +	subq	0(%rsi),%rax
        +	movq	16(%rbx),%r10
        +	movq	24(%rbx),%r11
        +	sbbq	8(%rsi),%rdx
        +	leaq	-1(%r9),%rcx
        +	jmp	.Lsqr4x_sub
        +.align	16
        +.Lsqr4x_sub:
        +	movq	%rax,0(%rdi,%rbp,8)
        +	movq	%rdx,8(%rdi,%rbp,8)
        +	sbbq	16(%rsi,%rbp,8),%r10
        +	movq	32(%rbx,%rbp,8),%rax
        +	movq	40(%rbx,%rbp,8),%rdx
        +	sbbq	24(%rsi,%rbp,8),%r11
        +	movq	%r10,16(%rdi,%rbp,8)
        +	movq	%r11,24(%rdi,%rbp,8)
        +	sbbq	32(%rsi,%rbp,8),%rax
        +	movq	48(%rbx,%rbp,8),%r10
        +	movq	56(%rbx,%rbp,8),%r11
        +	sbbq	40(%rsi,%rbp,8),%rdx
        +	leaq	4(%rbp),%rbp
        +	decq	%rcx
        +	jnz	.Lsqr4x_sub
        +
        +	movq	%rax,0(%rdi,%rbp,8)
        +	movq	32(%rbx,%rbp,8),%rax
        +	sbbq	16(%rsi,%rbp,8),%r10
        +	movq	%rdx,8(%rdi,%rbp,8)
        +	sbbq	24(%rsi,%rbp,8),%r11
        +	movq	%r10,16(%rdi,%rbp,8)
        +
        +	sbbq	$0,%rax
        +	movq	%r11,24(%rdi,%rbp,8)
        +	xorq	%rbp,%rbp
        +	andq	%rax,%rbx
        +	notq	%rax
        +	movq	%rdi,%rsi
        +	andq	%rax,%rsi
        +	leaq	-1(%r9),%rcx
        +	orq	%rsi,%rbx
        +
        +	pxor	%xmm0,%xmm0
        +	leaq	64(%rsp,%r9,8),%rsi
        +	movdqu	(%rbx),%xmm1
        +	leaq	(%rsi,%r9,8),%rsi
        +	movdqa	%xmm0,64(%rsp)
        +	movdqa	%xmm0,(%rsi)
        +	movdqu	%xmm1,(%rdi)
        +	jmp	.Lsqr4x_copy
        +.align	16
        +.Lsqr4x_copy:
        +	movdqu	16(%rbx,%rbp,1),%xmm2
        +	movdqu	32(%rbx,%rbp,1),%xmm1
        +	movdqa	%xmm0,80(%rsp,%rbp,1)
        +	movdqa	%xmm0,96(%rsp,%rbp,1)
        +	movdqa	%xmm0,16(%rsi,%rbp,1)
        +	movdqa	%xmm0,32(%rsi,%rbp,1)
        +	movdqu	%xmm2,16(%rdi,%rbp,1)
        +	movdqu	%xmm1,32(%rdi,%rbp,1)
        +	leaq	32(%rbp),%rbp
        +	decq	%rcx
        +	jnz	.Lsqr4x_copy
        +
        +	movdqu	16(%rbx,%rbp,1),%xmm2
        +	movdqa	%xmm0,80(%rsp,%rbp,1)
        +	movdqa	%xmm0,16(%rsi,%rbp,1)
        +	movdqu	%xmm2,16(%rdi,%rbp,1)
        +	movq	56(%rsp),%rsi
        +	movq	$1,%rax
        +	movq	0(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lsqr4x_epilogue:
        +	.byte	0xf3,0xc3
        +.size	bn_sqr4x_mont,.-bn_sqr4x_mont
        +.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	16
        diff --git a/vendor/openssl/asm/x64-elf-gas/camellia/cmll-x86_64.s b/vendor/openssl/asm/x64-elf-gas/camellia/cmll-x86_64.s
        new file mode 100644
        index 000000000..3a5f4c423
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/camellia/cmll-x86_64.s
        @@ -0,0 +1,1844 @@
        +.text
        +
        +
        +
        +.globl	Camellia_EncryptBlock
        +.type	Camellia_EncryptBlock,@function
        +.align	16
        +Camellia_EncryptBlock:
        +	movl	$128,%eax
        +	subl	%edi,%eax
        +	movl	$3,%edi
        +	adcl	$0,%edi
        +	jmp	.Lenc_rounds
        +.size	Camellia_EncryptBlock,.-Camellia_EncryptBlock
        +
        +.globl	Camellia_EncryptBlock_Rounds
        +.type	Camellia_EncryptBlock_Rounds,@function
        +.align	16
        +.Lenc_rounds:
        +Camellia_EncryptBlock_Rounds:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +.Lenc_prologue:
        +
        +
        +	movq	%rcx,%r13
        +	movq	%rdx,%r14
        +
        +	shll	$6,%edi
        +	leaq	.LCamellia_SBOX(%rip),%rbp
        +	leaq	(%r14,%rdi,1),%r15
        +
        +	movl	0(%rsi),%r8d
        +	movl	4(%rsi),%r9d
        +	movl	8(%rsi),%r10d
        +	bswapl	%r8d
        +	movl	12(%rsi),%r11d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	movl	%r8d,0(%r13)
        +	bswapl	%r11d
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	movq	0(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r13
        +	movq	24(%rsp),%rbp
        +	movq	32(%rsp),%rbx
        +	leaq	40(%rsp),%rsp
        +.Lenc_epilogue:
        +	.byte	0xf3,0xc3
        +.size	Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
        +
        +.type	_x86_64_Camellia_encrypt,@function
        +.align	16
        +_x86_64_Camellia_encrypt:
        +	xorl	0(%r14),%r9d
        +	xorl	4(%r14),%r8d
        +	xorl	8(%r14),%r11d
        +	xorl	12(%r14),%r10d
        +.align	16
        +.Leloop:
        +	movl	16(%r14),%ebx
        +	movl	20(%r14),%eax
        +
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	24(%r14),%ebx
        +	movl	28(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	32(%r14),%ebx
        +	movl	36(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	40(%r14),%ebx
        +	movl	44(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	48(%r14),%ebx
        +	movl	52(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	56(%r14),%ebx
        +	movl	60(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	64(%r14),%ebx
        +	movl	68(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	leaq	64(%r14),%r14
        +	cmpq	%r15,%r14
        +	movl	8(%r14),%edx
        +	movl	12(%r14),%ecx
        +	je	.Ledone
        +
        +	andl	%r8d,%eax
        +	orl	%r11d,%edx
        +	roll	$1,%eax
        +	xorl	%edx,%r10d
        +	xorl	%eax,%r9d
        +	andl	%r10d,%ecx
        +	orl	%r9d,%ebx
        +	roll	$1,%ecx
        +	xorl	%ebx,%r8d
        +	xorl	%ecx,%r11d
        +	jmp	.Leloop
        +
        +.align	16
        +.Ledone:
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r8d,%ecx
        +	xorl	%r9d,%edx
        +
        +	movl	%eax,%r8d
        +	movl	%ebx,%r9d
        +	movl	%ecx,%r10d
        +	movl	%edx,%r11d
        +
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
        +
        +
        +.globl	Camellia_DecryptBlock
        +.type	Camellia_DecryptBlock,@function
        +.align	16
        +Camellia_DecryptBlock:
        +	movl	$128,%eax
        +	subl	%edi,%eax
        +	movl	$3,%edi
        +	adcl	$0,%edi
        +	jmp	.Ldec_rounds
        +.size	Camellia_DecryptBlock,.-Camellia_DecryptBlock
        +
        +.globl	Camellia_DecryptBlock_Rounds
        +.type	Camellia_DecryptBlock_Rounds,@function
        +.align	16
        +.Ldec_rounds:
        +Camellia_DecryptBlock_Rounds:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +.Ldec_prologue:
        +
        +
        +	movq	%rcx,%r13
        +	movq	%rdx,%r15
        +
        +	shll	$6,%edi
        +	leaq	.LCamellia_SBOX(%rip),%rbp
        +	leaq	(%r15,%rdi,1),%r14
        +
        +	movl	0(%rsi),%r8d
        +	movl	4(%rsi),%r9d
        +	movl	8(%rsi),%r10d
        +	bswapl	%r8d
        +	movl	12(%rsi),%r11d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	movl	%r8d,0(%r13)
        +	bswapl	%r11d
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	movq	0(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r13
        +	movq	24(%rsp),%rbp
        +	movq	32(%rsp),%rbx
        +	leaq	40(%rsp),%rsp
        +.Ldec_epilogue:
        +	.byte	0xf3,0xc3
        +.size	Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
        +
        +.type	_x86_64_Camellia_decrypt,@function
        +.align	16
        +_x86_64_Camellia_decrypt:
        +	xorl	0(%r14),%r9d
        +	xorl	4(%r14),%r8d
        +	xorl	8(%r14),%r11d
        +	xorl	12(%r14),%r10d
        +.align	16
        +.Ldloop:
        +	movl	-8(%r14),%ebx
        +	movl	-4(%r14),%eax
        +
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-16(%r14),%ebx
        +	movl	-12(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-24(%r14),%ebx
        +	movl	-20(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-32(%r14),%ebx
        +	movl	-28(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-40(%r14),%ebx
        +	movl	-36(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-48(%r14),%ebx
        +	movl	-44(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-56(%r14),%ebx
        +	movl	-52(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	leaq	-64(%r14),%r14
        +	cmpq	%r15,%r14
        +	movl	0(%r14),%edx
        +	movl	4(%r14),%ecx
        +	je	.Lddone
        +
        +	andl	%r8d,%eax
        +	orl	%r11d,%edx
        +	roll	$1,%eax
        +	xorl	%edx,%r10d
        +	xorl	%eax,%r9d
        +	andl	%r10d,%ecx
        +	orl	%r9d,%ebx
        +	roll	$1,%ecx
        +	xorl	%ebx,%r8d
        +	xorl	%ecx,%r11d
        +
        +	jmp	.Ldloop
        +
        +.align	16
        +.Lddone:
        +	xorl	%r10d,%ecx
        +	xorl	%r11d,%edx
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +
        +	movl	%ecx,%r8d
        +	movl	%edx,%r9d
        +	movl	%eax,%r10d
        +	movl	%ebx,%r11d
        +
        +.byte	0xf3,0xc3
        +
        +.size	_x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
        +.globl	Camellia_Ekeygen
        +.type	Camellia_Ekeygen,@function
        +.align	16
        +Camellia_Ekeygen:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +.Lkey_prologue:
        +
        +	movq	%rdi,%r15
        +	movq	%rdx,%r13
        +
        +	movl	0(%rsi),%r8d
        +	movl	4(%rsi),%r9d
        +	movl	8(%rsi),%r10d
        +	movl	12(%rsi),%r11d
        +
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +	movl	%r9d,0(%r13)
        +	movl	%r8d,4(%r13)
        +	movl	%r11d,8(%r13)
        +	movl	%r10d,12(%r13)
        +	cmpq	$128,%r15
        +	je	.L1st128
        +
        +	movl	16(%rsi),%r8d
        +	movl	20(%rsi),%r9d
        +	cmpq	$192,%r15
        +	je	.L1st192
        +	movl	24(%rsi),%r10d
        +	movl	28(%rsi),%r11d
        +	jmp	.L1st256
        +.L1st192:
        +	movl	%r8d,%r10d
        +	movl	%r9d,%r11d
        +	notl	%r10d
        +	notl	%r11d
        +.L1st256:
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +	movl	%r9d,32(%r13)
        +	movl	%r8d,36(%r13)
        +	movl	%r11d,40(%r13)
        +	movl	%r10d,44(%r13)
        +	xorl	0(%r13),%r9d
        +	xorl	4(%r13),%r8d
        +	xorl	8(%r13),%r11d
        +	xorl	12(%r13),%r10d
        +
        +.L1st128:
        +	leaq	.LCamellia_SIGMA(%rip),%r14
        +	leaq	.LCamellia_SBOX(%rip),%rbp
        +
        +	movl	0(%r14),%ebx
        +	movl	4(%r14),%eax
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	8(%r14),%ebx
        +	movl	12(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	16(%r14),%ebx
        +	movl	20(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	0(%r13),%r9d
        +	xorl	4(%r13),%r8d
        +	xorl	8(%r13),%r11d
        +	xorl	12(%r13),%r10d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	24(%r14),%ebx
        +	movl	28(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	32(%r14),%ebx
        +	movl	36(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	cmpq	$128,%r15
        +	jne	.L2nd256
        +
        +	leaq	128(%r13),%r13
        +	shlq	$32,%r8
        +	shlq	$32,%r10
        +	orq	%r9,%r8
        +	orq	%r11,%r10
        +	movq	-128(%r13),%rax
        +	movq	-120(%r13),%rbx
        +	movq	%r8,-112(%r13)
        +	movq	%r10,-104(%r13)
        +	movq	%rax,%r11
        +	shlq	$15,%rax
        +	movq	%rbx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rax
        +	shlq	$15,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,-96(%r13)
        +	movq	%rbx,-88(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-80(%r13)
        +	movq	%r10,-72(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-64(%r13)
        +	movq	%r10,-56(%r13)
        +	movq	%rax,%r11
        +	shlq	$30,%rax
        +	movq	%rbx,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%rax
        +	shlq	$30,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,-48(%r13)
        +	movq	%rbx,-40(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-32(%r13)
        +	movq	%rax,%r11
        +	shlq	$15,%rax
        +	movq	%rbx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rax
        +	shlq	$15,%rbx
        +	orq	%r11,%rbx
        +	movq	%rbx,-24(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-16(%r13)
        +	movq	%r10,-8(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,0(%r13)
        +	movq	%rbx,8(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,16(%r13)
        +	movq	%rbx,24(%r13)
        +	movq	%r8,%r11
        +	shlq	$34,%r8
        +	movq	%r10,%r9
        +	shrq	$30,%r9
        +	shrq	$30,%r11
        +	orq	%r9,%r8
        +	shlq	$34,%r10
        +	orq	%r11,%r10
        +	movq	%r8,32(%r13)
        +	movq	%r10,40(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,48(%r13)
        +	movq	%rbx,56(%r13)
        +	movq	%r8,%r11
        +	shlq	$17,%r8
        +	movq	%r10,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%r8
        +	shlq	$17,%r10
        +	orq	%r11,%r10
        +	movq	%r8,64(%r13)
        +	movq	%r10,72(%r13)
        +	movl	$3,%eax
        +	jmp	.Ldone
        +.align	16
        +.L2nd256:
        +	movl	%r9d,48(%r13)
        +	movl	%r8d,52(%r13)
        +	movl	%r11d,56(%r13)
        +	movl	%r10d,60(%r13)
        +	xorl	32(%r13),%r9d
        +	xorl	36(%r13),%r8d
        +	xorl	40(%r13),%r11d
        +	xorl	44(%r13),%r10d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	40(%r14),%ebx
        +	movl	44(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	48(%r14),%ebx
        +	movl	52(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	movq	0(%r13),%rax
        +	movq	8(%r13),%rbx
        +	movq	32(%r13),%rcx
        +	movq	40(%r13),%rdx
        +	movq	48(%r13),%r14
        +	movq	56(%r13),%r15
        +	leaq	128(%r13),%r13
        +	shlq	$32,%r8
        +	shlq	$32,%r10
        +	orq	%r9,%r8
        +	orq	%r11,%r10
        +	movq	%r8,-112(%r13)
        +	movq	%r10,-104(%r13)
        +	movq	%rcx,%r11
        +	shlq	$15,%rcx
        +	movq	%rdx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rcx
        +	shlq	$15,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,-96(%r13)
        +	movq	%rdx,-88(%r13)
        +	movq	%r14,%r11
        +	shlq	$15,%r14
        +	movq	%r15,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r14
        +	shlq	$15,%r15
        +	orq	%r11,%r15
        +	movq	%r14,-80(%r13)
        +	movq	%r15,-72(%r13)
        +	movq	%rcx,%r11
        +	shlq	$15,%rcx
        +	movq	%rdx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rcx
        +	shlq	$15,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,-64(%r13)
        +	movq	%rdx,-56(%r13)
        +	movq	%r8,%r11
        +	shlq	$30,%r8
        +	movq	%r10,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%r8
        +	shlq	$30,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-48(%r13)
        +	movq	%r10,-40(%r13)
        +	movq	%rax,%r11
        +	shlq	$45,%rax
        +	movq	%rbx,%r9
        +	shrq	$19,%r9
        +	shrq	$19,%r11
        +	orq	%r9,%rax
        +	shlq	$45,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,-32(%r13)
        +	movq	%rbx,-24(%r13)
        +	movq	%r14,%r11
        +	shlq	$30,%r14
        +	movq	%r15,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%r14
        +	shlq	$30,%r15
        +	orq	%r11,%r15
        +	movq	%r14,-16(%r13)
        +	movq	%r15,-8(%r13)
        +	movq	%rax,%r11
        +	shlq	$15,%rax
        +	movq	%rbx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rax
        +	shlq	$15,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,0(%r13)
        +	movq	%rbx,8(%r13)
        +	movq	%rcx,%r11
        +	shlq	$30,%rcx
        +	movq	%rdx,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%rcx
        +	shlq	$30,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,16(%r13)
        +	movq	%rdx,24(%r13)
        +	movq	%r8,%r11
        +	shlq	$30,%r8
        +	movq	%r10,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%r8
        +	shlq	$30,%r10
        +	orq	%r11,%r10
        +	movq	%r8,32(%r13)
        +	movq	%r10,40(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,48(%r13)
        +	movq	%rbx,56(%r13)
        +	movq	%r14,%r11
        +	shlq	$32,%r14
        +	movq	%r15,%r9
        +	shrq	$32,%r9
        +	shrq	$32,%r11
        +	orq	%r9,%r14
        +	shlq	$32,%r15
        +	orq	%r11,%r15
        +	movq	%r14,64(%r13)
        +	movq	%r15,72(%r13)
        +	movq	%rcx,%r11
        +	shlq	$34,%rcx
        +	movq	%rdx,%r9
        +	shrq	$30,%r9
        +	shrq	$30,%r11
        +	orq	%r9,%rcx
        +	shlq	$34,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,80(%r13)
        +	movq	%rdx,88(%r13)
        +	movq	%r14,%r11
        +	shlq	$17,%r14
        +	movq	%r15,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%r14
        +	shlq	$17,%r15
        +	orq	%r11,%r15
        +	movq	%r14,96(%r13)
        +	movq	%r15,104(%r13)
        +	movq	%rax,%r11
        +	shlq	$34,%rax
        +	movq	%rbx,%r9
        +	shrq	$30,%r9
        +	shrq	$30,%r11
        +	orq	%r9,%rax
        +	shlq	$34,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,112(%r13)
        +	movq	%rbx,120(%r13)
        +	movq	%r8,%r11
        +	shlq	$51,%r8
        +	movq	%r10,%r9
        +	shrq	$13,%r9
        +	shrq	$13,%r11
        +	orq	%r9,%r8
        +	shlq	$51,%r10
        +	orq	%r11,%r10
        +	movq	%r8,128(%r13)
        +	movq	%r10,136(%r13)
        +	movl	$4,%eax
        +.Ldone:
        +	movq	0(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r13
        +	movq	24(%rsp),%rbp
        +	movq	32(%rsp),%rbx
        +	leaq	40(%rsp),%rsp
        +.Lkey_epilogue:
        +	.byte	0xf3,0xc3
        +.size	Camellia_Ekeygen,.-Camellia_Ekeygen
        +.align	64
        +.LCamellia_SIGMA:
        +.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
        +.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
        +.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
        +.long	0,          0,          0,          0
        +.LCamellia_SBOX:
        +.long	0x70707000,0x70700070
        +.long	0x82828200,0x2c2c002c
        +.long	0x2c2c2c00,0xb3b300b3
        +.long	0xececec00,0xc0c000c0
        +.long	0xb3b3b300,0xe4e400e4
        +.long	0x27272700,0x57570057
        +.long	0xc0c0c000,0xeaea00ea
        +.long	0xe5e5e500,0xaeae00ae
        +.long	0xe4e4e400,0x23230023
        +.long	0x85858500,0x6b6b006b
        +.long	0x57575700,0x45450045
        +.long	0x35353500,0xa5a500a5
        +.long	0xeaeaea00,0xeded00ed
        +.long	0x0c0c0c00,0x4f4f004f
        +.long	0xaeaeae00,0x1d1d001d
        +.long	0x41414100,0x92920092
        +.long	0x23232300,0x86860086
        +.long	0xefefef00,0xafaf00af
        +.long	0x6b6b6b00,0x7c7c007c
        +.long	0x93939300,0x1f1f001f
        +.long	0x45454500,0x3e3e003e
        +.long	0x19191900,0xdcdc00dc
        +.long	0xa5a5a500,0x5e5e005e
        +.long	0x21212100,0x0b0b000b
        +.long	0xededed00,0xa6a600a6
        +.long	0x0e0e0e00,0x39390039
        +.long	0x4f4f4f00,0xd5d500d5
        +.long	0x4e4e4e00,0x5d5d005d
        +.long	0x1d1d1d00,0xd9d900d9
        +.long	0x65656500,0x5a5a005a
        +.long	0x92929200,0x51510051
        +.long	0xbdbdbd00,0x6c6c006c
        +.long	0x86868600,0x8b8b008b
        +.long	0xb8b8b800,0x9a9a009a
        +.long	0xafafaf00,0xfbfb00fb
        +.long	0x8f8f8f00,0xb0b000b0
        +.long	0x7c7c7c00,0x74740074
        +.long	0xebebeb00,0x2b2b002b
        +.long	0x1f1f1f00,0xf0f000f0
        +.long	0xcecece00,0x84840084
        +.long	0x3e3e3e00,0xdfdf00df
        +.long	0x30303000,0xcbcb00cb
        +.long	0xdcdcdc00,0x34340034
        +.long	0x5f5f5f00,0x76760076
        +.long	0x5e5e5e00,0x6d6d006d
        +.long	0xc5c5c500,0xa9a900a9
        +.long	0x0b0b0b00,0xd1d100d1
        +.long	0x1a1a1a00,0x04040004
        +.long	0xa6a6a600,0x14140014
        +.long	0xe1e1e100,0x3a3a003a
        +.long	0x39393900,0xdede00de
        +.long	0xcacaca00,0x11110011
        +.long	0xd5d5d500,0x32320032
        +.long	0x47474700,0x9c9c009c
        +.long	0x5d5d5d00,0x53530053
        +.long	0x3d3d3d00,0xf2f200f2
        +.long	0xd9d9d900,0xfefe00fe
        +.long	0x01010100,0xcfcf00cf
        +.long	0x5a5a5a00,0xc3c300c3
        +.long	0xd6d6d600,0x7a7a007a
        +.long	0x51515100,0x24240024
        +.long	0x56565600,0xe8e800e8
        +.long	0x6c6c6c00,0x60600060
        +.long	0x4d4d4d00,0x69690069
        +.long	0x8b8b8b00,0xaaaa00aa
        +.long	0x0d0d0d00,0xa0a000a0
        +.long	0x9a9a9a00,0xa1a100a1
        +.long	0x66666600,0x62620062
        +.long	0xfbfbfb00,0x54540054
        +.long	0xcccccc00,0x1e1e001e
        +.long	0xb0b0b000,0xe0e000e0
        +.long	0x2d2d2d00,0x64640064
        +.long	0x74747400,0x10100010
        +.long	0x12121200,0x00000000
        +.long	0x2b2b2b00,0xa3a300a3
        +.long	0x20202000,0x75750075
        +.long	0xf0f0f000,0x8a8a008a
        +.long	0xb1b1b100,0xe6e600e6
        +.long	0x84848400,0x09090009
        +.long	0x99999900,0xdddd00dd
        +.long	0xdfdfdf00,0x87870087
        +.long	0x4c4c4c00,0x83830083
        +.long	0xcbcbcb00,0xcdcd00cd
        +.long	0xc2c2c200,0x90900090
        +.long	0x34343400,0x73730073
        +.long	0x7e7e7e00,0xf6f600f6
        +.long	0x76767600,0x9d9d009d
        +.long	0x05050500,0xbfbf00bf
        +.long	0x6d6d6d00,0x52520052
        +.long	0xb7b7b700,0xd8d800d8
        +.long	0xa9a9a900,0xc8c800c8
        +.long	0x31313100,0xc6c600c6
        +.long	0xd1d1d100,0x81810081
        +.long	0x17171700,0x6f6f006f
        +.long	0x04040400,0x13130013
        +.long	0xd7d7d700,0x63630063
        +.long	0x14141400,0xe9e900e9
        +.long	0x58585800,0xa7a700a7
        +.long	0x3a3a3a00,0x9f9f009f
        +.long	0x61616100,0xbcbc00bc
        +.long	0xdedede00,0x29290029
        +.long	0x1b1b1b00,0xf9f900f9
        +.long	0x11111100,0x2f2f002f
        +.long	0x1c1c1c00,0xb4b400b4
        +.long	0x32323200,0x78780078
        +.long	0x0f0f0f00,0x06060006
        +.long	0x9c9c9c00,0xe7e700e7
        +.long	0x16161600,0x71710071
        +.long	0x53535300,0xd4d400d4
        +.long	0x18181800,0xabab00ab
        +.long	0xf2f2f200,0x88880088
        +.long	0x22222200,0x8d8d008d
        +.long	0xfefefe00,0x72720072
        +.long	0x44444400,0xb9b900b9
        +.long	0xcfcfcf00,0xf8f800f8
        +.long	0xb2b2b200,0xacac00ac
        +.long	0xc3c3c300,0x36360036
        +.long	0xb5b5b500,0x2a2a002a
        +.long	0x7a7a7a00,0x3c3c003c
        +.long	0x91919100,0xf1f100f1
        +.long	0x24242400,0x40400040
        +.long	0x08080800,0xd3d300d3
        +.long	0xe8e8e800,0xbbbb00bb
        +.long	0xa8a8a800,0x43430043
        +.long	0x60606000,0x15150015
        +.long	0xfcfcfc00,0xadad00ad
        +.long	0x69696900,0x77770077
        +.long	0x50505000,0x80800080
        +.long	0xaaaaaa00,0x82820082
        +.long	0xd0d0d000,0xecec00ec
        +.long	0xa0a0a000,0x27270027
        +.long	0x7d7d7d00,0xe5e500e5
        +.long	0xa1a1a100,0x85850085
        +.long	0x89898900,0x35350035
        +.long	0x62626200,0x0c0c000c
        +.long	0x97979700,0x41410041
        +.long	0x54545400,0xefef00ef
        +.long	0x5b5b5b00,0x93930093
        +.long	0x1e1e1e00,0x19190019
        +.long	0x95959500,0x21210021
        +.long	0xe0e0e000,0x0e0e000e
        +.long	0xffffff00,0x4e4e004e
        +.long	0x64646400,0x65650065
        +.long	0xd2d2d200,0xbdbd00bd
        +.long	0x10101000,0xb8b800b8
        +.long	0xc4c4c400,0x8f8f008f
        +.long	0x00000000,0xebeb00eb
        +.long	0x48484800,0xcece00ce
        +.long	0xa3a3a300,0x30300030
        +.long	0xf7f7f700,0x5f5f005f
        +.long	0x75757500,0xc5c500c5
        +.long	0xdbdbdb00,0x1a1a001a
        +.long	0x8a8a8a00,0xe1e100e1
        +.long	0x03030300,0xcaca00ca
        +.long	0xe6e6e600,0x47470047
        +.long	0xdadada00,0x3d3d003d
        +.long	0x09090900,0x01010001
        +.long	0x3f3f3f00,0xd6d600d6
        +.long	0xdddddd00,0x56560056
        +.long	0x94949400,0x4d4d004d
        +.long	0x87878700,0x0d0d000d
        +.long	0x5c5c5c00,0x66660066
        +.long	0x83838300,0xcccc00cc
        +.long	0x02020200,0x2d2d002d
        +.long	0xcdcdcd00,0x12120012
        +.long	0x4a4a4a00,0x20200020
        +.long	0x90909000,0xb1b100b1
        +.long	0x33333300,0x99990099
        +.long	0x73737300,0x4c4c004c
        +.long	0x67676700,0xc2c200c2
        +.long	0xf6f6f600,0x7e7e007e
        +.long	0xf3f3f300,0x05050005
        +.long	0x9d9d9d00,0xb7b700b7
        +.long	0x7f7f7f00,0x31310031
        +.long	0xbfbfbf00,0x17170017
        +.long	0xe2e2e200,0xd7d700d7
        +.long	0x52525200,0x58580058
        +.long	0x9b9b9b00,0x61610061
        +.long	0xd8d8d800,0x1b1b001b
        +.long	0x26262600,0x1c1c001c
        +.long	0xc8c8c800,0x0f0f000f
        +.long	0x37373700,0x16160016
        +.long	0xc6c6c600,0x18180018
        +.long	0x3b3b3b00,0x22220022
        +.long	0x81818100,0x44440044
        +.long	0x96969600,0xb2b200b2
        +.long	0x6f6f6f00,0xb5b500b5
        +.long	0x4b4b4b00,0x91910091
        +.long	0x13131300,0x08080008
        +.long	0xbebebe00,0xa8a800a8
        +.long	0x63636300,0xfcfc00fc
        +.long	0x2e2e2e00,0x50500050
        +.long	0xe9e9e900,0xd0d000d0
        +.long	0x79797900,0x7d7d007d
        +.long	0xa7a7a700,0x89890089
        +.long	0x8c8c8c00,0x97970097
        +.long	0x9f9f9f00,0x5b5b005b
        +.long	0x6e6e6e00,0x95950095
        +.long	0xbcbcbc00,0xffff00ff
        +.long	0x8e8e8e00,0xd2d200d2
        +.long	0x29292900,0xc4c400c4
        +.long	0xf5f5f500,0x48480048
        +.long	0xf9f9f900,0xf7f700f7
        +.long	0xb6b6b600,0xdbdb00db
        +.long	0x2f2f2f00,0x03030003
        +.long	0xfdfdfd00,0xdada00da
        +.long	0xb4b4b400,0x3f3f003f
        +.long	0x59595900,0x94940094
        +.long	0x78787800,0x5c5c005c
        +.long	0x98989800,0x02020002
        +.long	0x06060600,0x4a4a004a
        +.long	0x6a6a6a00,0x33330033
        +.long	0xe7e7e700,0x67670067
        +.long	0x46464600,0xf3f300f3
        +.long	0x71717100,0x7f7f007f
        +.long	0xbababa00,0xe2e200e2
        +.long	0xd4d4d400,0x9b9b009b
        +.long	0x25252500,0x26260026
        +.long	0xababab00,0x37370037
        +.long	0x42424200,0x3b3b003b
        +.long	0x88888800,0x96960096
        +.long	0xa2a2a200,0x4b4b004b
        +.long	0x8d8d8d00,0xbebe00be
        +.long	0xfafafa00,0x2e2e002e
        +.long	0x72727200,0x79790079
        +.long	0x07070700,0x8c8c008c
        +.long	0xb9b9b900,0x6e6e006e
        +.long	0x55555500,0x8e8e008e
        +.long	0xf8f8f800,0xf5f500f5
        +.long	0xeeeeee00,0xb6b600b6
        +.long	0xacacac00,0xfdfd00fd
        +.long	0x0a0a0a00,0x59590059
        +.long	0x36363600,0x98980098
        +.long	0x49494900,0x6a6a006a
        +.long	0x2a2a2a00,0x46460046
        +.long	0x68686800,0xbaba00ba
        +.long	0x3c3c3c00,0x25250025
        +.long	0x38383800,0x42420042
        +.long	0xf1f1f100,0xa2a200a2
        +.long	0xa4a4a400,0xfafa00fa
        +.long	0x40404000,0x07070007
        +.long	0x28282800,0x55550055
        +.long	0xd3d3d300,0xeeee00ee
        +.long	0x7b7b7b00,0x0a0a000a
        +.long	0xbbbbbb00,0x49490049
        +.long	0xc9c9c900,0x68680068
        +.long	0x43434300,0x38380038
        +.long	0xc1c1c100,0xa4a400a4
        +.long	0x15151500,0x28280028
        +.long	0xe3e3e300,0x7b7b007b
        +.long	0xadadad00,0xc9c900c9
        +.long	0xf4f4f400,0xc1c100c1
        +.long	0x77777700,0xe3e300e3
        +.long	0xc7c7c700,0xf4f400f4
        +.long	0x80808000,0xc7c700c7
        +.long	0x9e9e9e00,0x9e9e009e
        +.long	0x00e0e0e0,0x38003838
        +.long	0x00050505,0x41004141
        +.long	0x00585858,0x16001616
        +.long	0x00d9d9d9,0x76007676
        +.long	0x00676767,0xd900d9d9
        +.long	0x004e4e4e,0x93009393
        +.long	0x00818181,0x60006060
        +.long	0x00cbcbcb,0xf200f2f2
        +.long	0x00c9c9c9,0x72007272
        +.long	0x000b0b0b,0xc200c2c2
        +.long	0x00aeaeae,0xab00abab
        +.long	0x006a6a6a,0x9a009a9a
        +.long	0x00d5d5d5,0x75007575
        +.long	0x00181818,0x06000606
        +.long	0x005d5d5d,0x57005757
        +.long	0x00828282,0xa000a0a0
        +.long	0x00464646,0x91009191
        +.long	0x00dfdfdf,0xf700f7f7
        +.long	0x00d6d6d6,0xb500b5b5
        +.long	0x00272727,0xc900c9c9
        +.long	0x008a8a8a,0xa200a2a2
        +.long	0x00323232,0x8c008c8c
        +.long	0x004b4b4b,0xd200d2d2
        +.long	0x00424242,0x90009090
        +.long	0x00dbdbdb,0xf600f6f6
        +.long	0x001c1c1c,0x07000707
        +.long	0x009e9e9e,0xa700a7a7
        +.long	0x009c9c9c,0x27002727
        +.long	0x003a3a3a,0x8e008e8e
        +.long	0x00cacaca,0xb200b2b2
        +.long	0x00252525,0x49004949
        +.long	0x007b7b7b,0xde00dede
        +.long	0x000d0d0d,0x43004343
        +.long	0x00717171,0x5c005c5c
        +.long	0x005f5f5f,0xd700d7d7
        +.long	0x001f1f1f,0xc700c7c7
        +.long	0x00f8f8f8,0x3e003e3e
        +.long	0x00d7d7d7,0xf500f5f5
        +.long	0x003e3e3e,0x8f008f8f
        +.long	0x009d9d9d,0x67006767
        +.long	0x007c7c7c,0x1f001f1f
        +.long	0x00606060,0x18001818
        +.long	0x00b9b9b9,0x6e006e6e
        +.long	0x00bebebe,0xaf00afaf
        +.long	0x00bcbcbc,0x2f002f2f
        +.long	0x008b8b8b,0xe200e2e2
        +.long	0x00161616,0x85008585
        +.long	0x00343434,0x0d000d0d
        +.long	0x004d4d4d,0x53005353
        +.long	0x00c3c3c3,0xf000f0f0
        +.long	0x00727272,0x9c009c9c
        +.long	0x00959595,0x65006565
        +.long	0x00ababab,0xea00eaea
        +.long	0x008e8e8e,0xa300a3a3
        +.long	0x00bababa,0xae00aeae
        +.long	0x007a7a7a,0x9e009e9e
        +.long	0x00b3b3b3,0xec00ecec
        +.long	0x00020202,0x80008080
        +.long	0x00b4b4b4,0x2d002d2d
        +.long	0x00adadad,0x6b006b6b
        +.long	0x00a2a2a2,0xa800a8a8
        +.long	0x00acacac,0x2b002b2b
        +.long	0x00d8d8d8,0x36003636
        +.long	0x009a9a9a,0xa600a6a6
        +.long	0x00171717,0xc500c5c5
        +.long	0x001a1a1a,0x86008686
        +.long	0x00353535,0x4d004d4d
        +.long	0x00cccccc,0x33003333
        +.long	0x00f7f7f7,0xfd00fdfd
        +.long	0x00999999,0x66006666
        +.long	0x00616161,0x58005858
        +.long	0x005a5a5a,0x96009696
        +.long	0x00e8e8e8,0x3a003a3a
        +.long	0x00242424,0x09000909
        +.long	0x00565656,0x95009595
        +.long	0x00404040,0x10001010
        +.long	0x00e1e1e1,0x78007878
        +.long	0x00636363,0xd800d8d8
        +.long	0x00090909,0x42004242
        +.long	0x00333333,0xcc00cccc
        +.long	0x00bfbfbf,0xef00efef
        +.long	0x00989898,0x26002626
        +.long	0x00979797,0xe500e5e5
        +.long	0x00858585,0x61006161
        +.long	0x00686868,0x1a001a1a
        +.long	0x00fcfcfc,0x3f003f3f
        +.long	0x00ececec,0x3b003b3b
        +.long	0x000a0a0a,0x82008282
        +.long	0x00dadada,0xb600b6b6
        +.long	0x006f6f6f,0xdb00dbdb
        +.long	0x00535353,0xd400d4d4
        +.long	0x00626262,0x98009898
        +.long	0x00a3a3a3,0xe800e8e8
        +.long	0x002e2e2e,0x8b008b8b
        +.long	0x00080808,0x02000202
        +.long	0x00afafaf,0xeb00ebeb
        +.long	0x00282828,0x0a000a0a
        +.long	0x00b0b0b0,0x2c002c2c
        +.long	0x00747474,0x1d001d1d
        +.long	0x00c2c2c2,0xb000b0b0
        +.long	0x00bdbdbd,0x6f006f6f
        +.long	0x00363636,0x8d008d8d
        +.long	0x00222222,0x88008888
        +.long	0x00383838,0x0e000e0e
        +.long	0x00646464,0x19001919
        +.long	0x001e1e1e,0x87008787
        +.long	0x00393939,0x4e004e4e
        +.long	0x002c2c2c,0x0b000b0b
        +.long	0x00a6a6a6,0xa900a9a9
        +.long	0x00303030,0x0c000c0c
        +.long	0x00e5e5e5,0x79007979
        +.long	0x00444444,0x11001111
        +.long	0x00fdfdfd,0x7f007f7f
        +.long	0x00888888,0x22002222
        +.long	0x009f9f9f,0xe700e7e7
        +.long	0x00656565,0x59005959
        +.long	0x00878787,0xe100e1e1
        +.long	0x006b6b6b,0xda00dada
        +.long	0x00f4f4f4,0x3d003d3d
        +.long	0x00232323,0xc800c8c8
        +.long	0x00484848,0x12001212
        +.long	0x00101010,0x04000404
        +.long	0x00d1d1d1,0x74007474
        +.long	0x00515151,0x54005454
        +.long	0x00c0c0c0,0x30003030
        +.long	0x00f9f9f9,0x7e007e7e
        +.long	0x00d2d2d2,0xb400b4b4
        +.long	0x00a0a0a0,0x28002828
        +.long	0x00555555,0x55005555
        +.long	0x00a1a1a1,0x68006868
        +.long	0x00414141,0x50005050
        +.long	0x00fafafa,0xbe00bebe
        +.long	0x00434343,0xd000d0d0
        +.long	0x00131313,0xc400c4c4
        +.long	0x00c4c4c4,0x31003131
        +.long	0x002f2f2f,0xcb00cbcb
        +.long	0x00a8a8a8,0x2a002a2a
        +.long	0x00b6b6b6,0xad00adad
        +.long	0x003c3c3c,0x0f000f0f
        +.long	0x002b2b2b,0xca00caca
        +.long	0x00c1c1c1,0x70007070
        +.long	0x00ffffff,0xff00ffff
        +.long	0x00c8c8c8,0x32003232
        +.long	0x00a5a5a5,0x69006969
        +.long	0x00202020,0x08000808
        +.long	0x00898989,0x62006262
        +.long	0x00000000,0x00000000
        +.long	0x00909090,0x24002424
        +.long	0x00474747,0xd100d1d1
        +.long	0x00efefef,0xfb00fbfb
        +.long	0x00eaeaea,0xba00baba
        +.long	0x00b7b7b7,0xed00eded
        +.long	0x00151515,0x45004545
        +.long	0x00060606,0x81008181
        +.long	0x00cdcdcd,0x73007373
        +.long	0x00b5b5b5,0x6d006d6d
        +.long	0x00121212,0x84008484
        +.long	0x007e7e7e,0x9f009f9f
        +.long	0x00bbbbbb,0xee00eeee
        +.long	0x00292929,0x4a004a4a
        +.long	0x000f0f0f,0xc300c3c3
        +.long	0x00b8b8b8,0x2e002e2e
        +.long	0x00070707,0xc100c1c1
        +.long	0x00040404,0x01000101
        +.long	0x009b9b9b,0xe600e6e6
        +.long	0x00949494,0x25002525
        +.long	0x00212121,0x48004848
        +.long	0x00666666,0x99009999
        +.long	0x00e6e6e6,0xb900b9b9
        +.long	0x00cecece,0xb300b3b3
        +.long	0x00ededed,0x7b007b7b
        +.long	0x00e7e7e7,0xf900f9f9
        +.long	0x003b3b3b,0xce00cece
        +.long	0x00fefefe,0xbf00bfbf
        +.long	0x007f7f7f,0xdf00dfdf
        +.long	0x00c5c5c5,0x71007171
        +.long	0x00a4a4a4,0x29002929
        +.long	0x00373737,0xcd00cdcd
        +.long	0x00b1b1b1,0x6c006c6c
        +.long	0x004c4c4c,0x13001313
        +.long	0x00919191,0x64006464
        +.long	0x006e6e6e,0x9b009b9b
        +.long	0x008d8d8d,0x63006363
        +.long	0x00767676,0x9d009d9d
        +.long	0x00030303,0xc000c0c0
        +.long	0x002d2d2d,0x4b004b4b
        +.long	0x00dedede,0xb700b7b7
        +.long	0x00969696,0xa500a5a5
        +.long	0x00262626,0x89008989
        +.long	0x007d7d7d,0x5f005f5f
        +.long	0x00c6c6c6,0xb100b1b1
        +.long	0x005c5c5c,0x17001717
        +.long	0x00d3d3d3,0xf400f4f4
        +.long	0x00f2f2f2,0xbc00bcbc
        +.long	0x004f4f4f,0xd300d3d3
        +.long	0x00191919,0x46004646
        +.long	0x003f3f3f,0xcf00cfcf
        +.long	0x00dcdcdc,0x37003737
        +.long	0x00797979,0x5e005e5e
        +.long	0x001d1d1d,0x47004747
        +.long	0x00525252,0x94009494
        +.long	0x00ebebeb,0xfa00fafa
        +.long	0x00f3f3f3,0xfc00fcfc
        +.long	0x006d6d6d,0x5b005b5b
        +.long	0x005e5e5e,0x97009797
        +.long	0x00fbfbfb,0xfe00fefe
        +.long	0x00696969,0x5a005a5a
        +.long	0x00b2b2b2,0xac00acac
        +.long	0x00f0f0f0,0x3c003c3c
        +.long	0x00313131,0x4c004c4c
        +.long	0x000c0c0c,0x03000303
        +.long	0x00d4d4d4,0x35003535
        +.long	0x00cfcfcf,0xf300f3f3
        +.long	0x008c8c8c,0x23002323
        +.long	0x00e2e2e2,0xb800b8b8
        +.long	0x00757575,0x5d005d5d
        +.long	0x00a9a9a9,0x6a006a6a
        +.long	0x004a4a4a,0x92009292
        +.long	0x00575757,0xd500d5d5
        +.long	0x00848484,0x21002121
        +.long	0x00111111,0x44004444
        +.long	0x00454545,0x51005151
        +.long	0x001b1b1b,0xc600c6c6
        +.long	0x00f5f5f5,0x7d007d7d
        +.long	0x00e4e4e4,0x39003939
        +.long	0x000e0e0e,0x83008383
        +.long	0x00737373,0xdc00dcdc
        +.long	0x00aaaaaa,0xaa00aaaa
        +.long	0x00f1f1f1,0x7c007c7c
        +.long	0x00dddddd,0x77007777
        +.long	0x00595959,0x56005656
        +.long	0x00141414,0x05000505
        +.long	0x006c6c6c,0x1b001b1b
        +.long	0x00929292,0xa400a4a4
        +.long	0x00545454,0x15001515
        +.long	0x00d0d0d0,0x34003434
        +.long	0x00787878,0x1e001e1e
        +.long	0x00707070,0x1c001c1c
        +.long	0x00e3e3e3,0xf800f8f8
        +.long	0x00494949,0x52005252
        +.long	0x00808080,0x20002020
        +.long	0x00505050,0x14001414
        +.long	0x00a7a7a7,0xe900e9e9
        +.long	0x00f6f6f6,0xbd00bdbd
        +.long	0x00777777,0xdd00dddd
        +.long	0x00939393,0xe400e4e4
        +.long	0x00868686,0xa100a1a1
        +.long	0x00838383,0xe000e0e0
        +.long	0x002a2a2a,0x8a008a8a
        +.long	0x00c7c7c7,0xf100f1f1
        +.long	0x005b5b5b,0xd600d6d6
        +.long	0x00e9e9e9,0x7a007a7a
        +.long	0x00eeeeee,0xbb00bbbb
        +.long	0x008f8f8f,0xe300e3e3
        +.long	0x00010101,0x40004040
        +.long	0x003d3d3d,0x4f004f4f
        +.globl	Camellia_cbc_encrypt
        +.type	Camellia_cbc_encrypt,@function
        +.align	16
        +Camellia_cbc_encrypt:
        +	cmpq	$0,%rdx
        +	je	.Lcbc_abort
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +.Lcbc_prologue:
        +
        +	movq	%rsp,%rbp
        +	subq	$64,%rsp
        +	andq	$-64,%rsp
        +
        +
        +
        +	leaq	-64-63(%rcx),%r10
        +	subq	%rsp,%r10
        +	negq	%r10
        +	andq	$960,%r10
        +	subq	%r10,%rsp
        +
        +
        +	movq	%rdi,%r12
        +	movq	%rsi,%r13
        +	movq	%r8,%rbx
        +	movq	%rcx,%r14
        +	movl	272(%rcx),%r15d
        +
        +	movq	%r8,40(%rsp)
        +	movq	%rbp,48(%rsp)
        +
        +.Lcbc_body:
        +	leaq	.LCamellia_SBOX(%rip),%rbp
        +
        +	movl	$32,%ecx
        +.align	4
        +.Lcbc_prefetch_sbox:
        +	movq	0(%rbp),%rax
        +	movq	32(%rbp),%rsi
        +	movq	64(%rbp),%rdi
        +	movq	96(%rbp),%r11
        +	leaq	128(%rbp),%rbp
        +	loop	.Lcbc_prefetch_sbox
        +	subq	$4096,%rbp
        +	shlq	$6,%r15
        +	movq	%rdx,%rcx
        +	leaq	(%r14,%r15,1),%r15
        +
        +	cmpl	$0,%r9d
        +	je	.LCBC_DECRYPT
        +
        +	andq	$-16,%rdx
        +	andq	$15,%rcx
        +	leaq	(%r12,%rdx,1),%rdx
        +	movq	%r14,0(%rsp)
        +	movq	%rdx,8(%rsp)
        +	movq	%rcx,16(%rsp)
        +
        +	cmpq	%r12,%rdx
        +	movl	0(%rbx),%r8d
        +	movl	4(%rbx),%r9d
        +	movl	8(%rbx),%r10d
        +	movl	12(%rbx),%r11d
        +	je	.Lcbc_enc_tail
        +	jmp	.Lcbc_eloop
        +
        +.align	16
        +.Lcbc_eloop:
        +	xorl	0(%r12),%r8d
        +	xorl	4(%r12),%r9d
        +	xorl	8(%r12),%r10d
        +	bswapl	%r8d
        +	xorl	12(%r12),%r11d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	movq	0(%rsp),%r14
        +	bswapl	%r8d
        +	movq	8(%rsp),%rdx
        +	bswapl	%r9d
        +	movq	16(%rsp),%rcx
        +	bswapl	%r10d
        +	movl	%r8d,0(%r13)
        +	bswapl	%r11d
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	leaq	16(%r12),%r12
        +	movl	%r11d,12(%r13)
        +	cmpq	%rdx,%r12
        +	leaq	16(%r13),%r13
        +	jne	.Lcbc_eloop
        +
        +	cmpq	$0,%rcx
        +	jne	.Lcbc_enc_tail
        +
        +	movq	40(%rsp),%r13
        +	movl	%r8d,0(%r13)
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +	jmp	.Lcbc_done
        +
        +.align	16
        +.Lcbc_enc_tail:
        +	xorq	%rax,%rax
        +	movq	%rax,0+24(%rsp)
        +	movq	%rax,8+24(%rsp)
        +	movq	%rax,16(%rsp)
        +
        +.Lcbc_enc_pushf:
        +	pushfq
        +	cld
        +	movq	%r12,%rsi
        +	leaq	8+24(%rsp),%rdi
        +.long	0x9066A4F3
        +
        +	popfq
        +.Lcbc_enc_popf:
        +
        +	leaq	24(%rsp),%r12
        +	leaq	16+24(%rsp),%rax
        +	movq	%rax,8(%rsp)
        +	jmp	.Lcbc_eloop
        +
        +
        +.align	16
        +.LCBC_DECRYPT:
        +	xchgq	%r14,%r15
        +	addq	$15,%rdx
        +	andq	$15,%rcx
        +	andq	$-16,%rdx
        +	movq	%r14,0(%rsp)
        +	leaq	(%r12,%rdx,1),%rdx
        +	movq	%rdx,8(%rsp)
        +	movq	%rcx,16(%rsp)
        +
        +	movq	(%rbx),%rax
        +	movq	8(%rbx),%rbx
        +	jmp	.Lcbc_dloop
        +.align	16
        +.Lcbc_dloop:
        +	movl	0(%r12),%r8d
        +	movl	4(%r12),%r9d
        +	movl	8(%r12),%r10d
        +	bswapl	%r8d
        +	movl	12(%r12),%r11d
        +	bswapl	%r9d
        +	movq	%rax,0+24(%rsp)
        +	bswapl	%r10d
        +	movq	%rbx,8+24(%rsp)
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	movq	0(%rsp),%r14
        +	movq	8(%rsp),%rdx
        +	movq	16(%rsp),%rcx
        +
        +	bswapl	%r8d
        +	movq	(%r12),%rax
        +	bswapl	%r9d
        +	movq	8(%r12),%rbx
        +	bswapl	%r10d
        +	xorl	0+24(%rsp),%r8d
        +	bswapl	%r11d
        +	xorl	4+24(%rsp),%r9d
        +	xorl	8+24(%rsp),%r10d
        +	leaq	16(%r12),%r12
        +	xorl	12+24(%rsp),%r11d
        +	cmpq	%rdx,%r12
        +	je	.Lcbc_ddone
        +
        +	movl	%r8d,0(%r13)
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	leaq	16(%r13),%r13
        +	jmp	.Lcbc_dloop
        +
        +.align	16
        +.Lcbc_ddone:
        +	movq	40(%rsp),%rdx
        +	cmpq	$0,%rcx
        +	jne	.Lcbc_dec_tail
        +
        +	movl	%r8d,0(%r13)
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	movq	%rax,(%rdx)
        +	movq	%rbx,8(%rdx)
        +	jmp	.Lcbc_done
        +.align	16
        +.Lcbc_dec_tail:
        +	movl	%r8d,0+24(%rsp)
        +	movl	%r9d,4+24(%rsp)
        +	movl	%r10d,8+24(%rsp)
        +	movl	%r11d,12+24(%rsp)
        +
        +.Lcbc_dec_pushf:
        +	pushfq
        +	cld
        +	leaq	8+24(%rsp),%rsi
        +	leaq	(%r13),%rdi
        +.long	0x9066A4F3
        +
        +	popfq
        +.Lcbc_dec_popf:
        +
        +	movq	%rax,(%rdx)
        +	movq	%rbx,8(%rdx)
        +	jmp	.Lcbc_done
        +
        +.align	16
        +.Lcbc_done:
        +	movq	48(%rsp),%rcx
        +	movq	0(%rcx),%r15
        +	movq	8(%rcx),%r14
        +	movq	16(%rcx),%r13
        +	movq	24(%rcx),%r12
        +	movq	32(%rcx),%rbp
        +	movq	40(%rcx),%rbx
        +	leaq	48(%rcx),%rsp
        +.Lcbc_abort:
        +	.byte	0xf3,0xc3
        +.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
        +
        +.byte	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x64-elf-gas/md5/md5-x86_64.s b/vendor/openssl/asm/x64-elf-gas/md5/md5-x86_64.s
        new file mode 100644
        index 000000000..81b0c7a11
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/md5/md5-x86_64.s
        @@ -0,0 +1,671 @@
        +.text
        +
        +.align	16
        +
        +.globl	md5_block_asm_data_order
        +.type	md5_block_asm_data_order,@function
        +md5_block_asm_data_order:
        +	pushq	%rbp
        +	pushq	%rbx
        +	pushq	%r12
        +	pushq	%r14
        +	pushq	%r15
        +.Lprologue:
        +
        +
        +
        +
        +	movq	%rdi,%rbp
        +	shlq	$6,%rdx
        +	leaq	(%rsi,%rdx,1),%rdi
        +	movl	0(%rbp),%eax
        +	movl	4(%rbp),%ebx
        +	movl	8(%rbp),%ecx
        +	movl	12(%rbp),%edx
        +
        +
        +
        +
        +
        +
        +
        +	cmpq	%rdi,%rsi
        +	je	.Lend
        +
        +
        +
        +.Lloop:
        +	movl	%eax,%r8d
        +	movl	%ebx,%r9d
        +	movl	%ecx,%r14d
        +	movl	%edx,%r15d
        +	movl	0(%rsi),%r10d
        +	movl	%edx,%r11d
        +	xorl	%ecx,%r11d
        +	leal	-680876936(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	4(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	-389564586(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	8(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	606105819(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	12(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	-1044525330(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	16(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	xorl	%ecx,%r11d
        +	leal	-176418897(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	20(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	1200080426(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	24(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	-1473231341(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	28(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	-45705983(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	32(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	xorl	%ecx,%r11d
        +	leal	1770035416(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	36(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	-1958414417(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	40(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	-42063(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	44(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	-1990404162(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	48(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	xorl	%ecx,%r11d
        +	leal	1804603682(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	52(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	-40341101(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	56(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	-1502002290(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	60(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	1236535329(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	0(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	movl	4(%rsi),%r10d
        +	movl	%edx,%r11d
        +	movl	%edx,%r12d
        +	notl	%r11d
        +	leal	-165796510(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	24(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	-1069501632(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	44(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	643717713(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	0(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	-373897302(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	20(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	notl	%r11d
        +	leal	-701558691(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	40(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	38016083(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	60(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	-660478335(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	16(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	-405537848(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	36(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	notl	%r11d
        +	leal	568446438(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	56(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	-1019803690(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	12(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	-187363961(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	32(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	1163531501(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	52(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	notl	%r11d
        +	leal	-1444681467(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	8(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	-51403784(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	28(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	1735328473(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	48(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	-1926607734(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	0(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	movl	20(%rsi),%r10d
        +	movl	%ecx,%r11d
        +	leal	-378558(%rax,%r10,1),%eax
        +	movl	32(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	-2022574463(%rdx,%r10,1),%edx
        +	movl	44(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	1839030562(%rcx,%r10,1),%ecx
        +	movl	56(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	-35309556(%rbx,%r10,1),%ebx
        +	movl	4(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	leal	-1530992060(%rax,%r10,1),%eax
        +	movl	16(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	1272893353(%rdx,%r10,1),%edx
        +	movl	28(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	-155497632(%rcx,%r10,1),%ecx
        +	movl	40(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	-1094730640(%rbx,%r10,1),%ebx
        +	movl	52(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	leal	681279174(%rax,%r10,1),%eax
        +	movl	0(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	-358537222(%rdx,%r10,1),%edx
        +	movl	12(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	-722521979(%rcx,%r10,1),%ecx
        +	movl	24(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	76029189(%rbx,%r10,1),%ebx
        +	movl	36(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	leal	-640364487(%rax,%r10,1),%eax
        +	movl	48(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	-421815835(%rdx,%r10,1),%edx
        +	movl	60(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	530742520(%rcx,%r10,1),%ecx
        +	movl	8(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	-995338651(%rbx,%r10,1),%ebx
        +	movl	0(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	movl	0(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	xorl	%edx,%r11d
        +	leal	-198630844(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	28(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	1126891415(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	56(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	-1416354905(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	20(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	-57434055(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	48(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	leal	1700485571(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	12(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	-1894986606(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	40(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	-1051523(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	4(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	-2054922799(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	32(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	leal	1873313359(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	60(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	-30611744(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	24(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	-1560198380(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	52(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	1309151649(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	16(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	leal	-145523070(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	44(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	-1120210379(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	8(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	718787259(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	36(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	-343485551(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	0(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +
        +	addl	%r8d,%eax
        +	addl	%r9d,%ebx
        +	addl	%r14d,%ecx
        +	addl	%r15d,%edx
        +
        +
        +	addq	$64,%rsi
        +	cmpq	%rdi,%rsi
        +	jb	.Lloop
        +
        +
        +
        +.Lend:
        +	movl	%eax,0(%rbp)
        +	movl	%ebx,4(%rbp)
        +	movl	%ecx,8(%rbp)
        +	movl	%edx,12(%rbp)
        +
        +	movq	(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r12
        +	movq	24(%rsp),%rbx
        +	movq	32(%rsp),%rbp
        +	addq	$40,%rsp
        +.Lepilogue:
        +	.byte	0xf3,0xc3
        +.size	md5_block_asm_data_order,.-md5_block_asm_data_order
        diff --git a/vendor/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s b/vendor/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s
        new file mode 100644
        index 000000000..501027a80
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/rc4/rc4-md5-x86_64.s
        @@ -0,0 +1,1260 @@
        +.text
        +
        +.align	16
        +
        +.globl	rc4_md5_enc
        +.type	rc4_md5_enc,@function
        +rc4_md5_enc:
        +	cmpq	$0,%r9
        +	je	.Labort
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	subq	$40,%rsp
        +.Lbody:
        +	movq	%rcx,%r11
        +	movq	%r9,%r12
        +	movq	%rsi,%r13
        +	movq	%rdx,%r14
        +	movq	%r8,%r15
        +	xorq	%rbp,%rbp
        +	xorq	%rcx,%rcx
        +
        +	leaq	8(%rdi),%rdi
        +	movb	-8(%rdi),%bpl
        +	movb	-4(%rdi),%cl
        +
        +	incb	%bpl
        +	subq	%r13,%r14
        +	movl	(%rdi,%rbp,4),%eax
        +	addb	%al,%cl
        +	leaq	(%rdi,%rbp,4),%rsi
        +	shlq	$6,%r12
        +	addq	%r15,%r12
        +	movq	%r12,16(%rsp)
        +
        +	movq	%r11,24(%rsp)
        +	movl	0(%r11),%r8d
        +	movl	4(%r11),%r9d
        +	movl	8(%r11),%r10d
        +	movl	12(%r11),%r11d
        +	jmp	.Loop
        +
        +.align	16
        +.Loop:
        +	movl	%r8d,0(%rsp)
        +	movl	%r9d,4(%rsp)
        +	movl	%r10d,8(%rsp)
        +	movl	%r11d,%r12d
        +	movl	%r11d,12(%rsp)
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	0(%r15),%r8d
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	addl	$3614090360,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,0(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	4(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	8(%rsi),%eax
        +	addl	$3905402710,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,4(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	8(%r15),%r10d
        +	addb	%dl,%al
        +	movl	12(%rsi),%ebx
        +	addl	$606105819,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,8(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	12(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	16(%rsi),%eax
        +	addl	$3250441966,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,12(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	16(%r15),%r8d
        +	addb	%dl,%al
        +	movl	20(%rsi),%ebx
        +	addl	$4118548399,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,16(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	20(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	24(%rsi),%eax
        +	addl	$1200080426,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,20(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	24(%r15),%r10d
        +	addb	%dl,%al
        +	movl	28(%rsi),%ebx
        +	addl	$2821735955,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,24(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	28(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	32(%rsi),%eax
        +	addl	$4249261313,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,28(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	32(%r15),%r8d
        +	addb	%dl,%al
        +	movl	36(%rsi),%ebx
        +	addl	$1770035416,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,32(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	36(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	40(%rsi),%eax
        +	addl	$2336552879,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,36(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	40(%r15),%r10d
        +	addb	%dl,%al
        +	movl	44(%rsi),%ebx
        +	addl	$4294925233,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,40(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	44(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	48(%rsi),%eax
        +	addl	$2304563134,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,44(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	48(%r15),%r8d
        +	addb	%dl,%al
        +	movl	52(%rsi),%ebx
        +	addl	$1804603682,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,48(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	52(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	56(%rsi),%eax
        +	addl	$4254626195,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,52(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	56(%r15),%r10d
        +	addb	%dl,%al
        +	movl	60(%rsi),%ebx
        +	addl	$2792965006,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,56(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	(%r13),%xmm2
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	60(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	64(%rsi),%eax
        +	addl	$1236535329,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,60(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm1,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	4(%r15),%r8d
        +	addb	%dl,%al
        +	movl	68(%rsi),%ebx
        +	addl	$4129170786,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,64(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	24(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	72(%rsi),%eax
        +	addl	$3225465664,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,68(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	44(%r15),%r10d
        +	addb	%dl,%al
        +	movl	76(%rsi),%ebx
        +	addl	$643717713,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,72(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	0(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	80(%rsi),%eax
        +	addl	$3921069994,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,76(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	20(%r15),%r8d
        +	addb	%dl,%al
        +	movl	84(%rsi),%ebx
        +	addl	$3593408605,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,80(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	40(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	88(%rsi),%eax
        +	addl	$38016083,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,84(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	60(%r15),%r10d
        +	addb	%dl,%al
        +	movl	92(%rsi),%ebx
        +	addl	$3634488961,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,88(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	16(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	96(%rsi),%eax
        +	addl	$3889429448,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,92(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	36(%r15),%r8d
        +	addb	%dl,%al
        +	movl	100(%rsi),%ebx
        +	addl	$568446438,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,96(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	56(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	104(%rsi),%eax
        +	addl	$3275163606,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,100(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	12(%r15),%r10d
        +	addb	%dl,%al
        +	movl	108(%rsi),%ebx
        +	addl	$4107603335,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,104(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	32(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	112(%rsi),%eax
        +	addl	$1163531501,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,108(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	52(%r15),%r8d
        +	addb	%dl,%al
        +	movl	116(%rsi),%ebx
        +	addl	$2850285829,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,112(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	8(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	120(%rsi),%eax
        +	addl	$4243563512,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,116(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	28(%r15),%r10d
        +	addb	%dl,%al
        +	movl	124(%rsi),%ebx
        +	addl	$1735328473,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,120(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	16(%r13),%xmm3
        +	addb	$32,%bpl
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	48(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	0(%rdi,%rbp,4),%eax
        +	addl	$2368359562,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,124(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movq	%rcx,%rsi
        +	xorq	%rcx,%rcx
        +	movb	%sil,%cl
        +	leaq	(%rdi,%rbp,4),%rsi
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm1,%xmm3
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	20(%r15),%r8d
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	addl	$4294588738,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,0(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	32(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	8(%rsi),%eax
        +	addl	$2272392833,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,4(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	44(%r15),%r10d
        +	addb	%dl,%al
        +	movl	12(%rsi),%ebx
        +	addl	$1839030562,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,8(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	56(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	16(%rsi),%eax
        +	addl	$4259657740,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,12(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	4(%r15),%r8d
        +	addb	%dl,%al
        +	movl	20(%rsi),%ebx
        +	addl	$2763975236,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,16(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	16(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	24(%rsi),%eax
        +	addl	$1272893353,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,20(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	28(%r15),%r10d
        +	addb	%dl,%al
        +	movl	28(%rsi),%ebx
        +	addl	$4139469664,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,24(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	40(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	32(%rsi),%eax
        +	addl	$3200236656,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,28(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	52(%r15),%r8d
        +	addb	%dl,%al
        +	movl	36(%rsi),%ebx
        +	addl	$681279174,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,32(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	0(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	40(%rsi),%eax
        +	addl	$3936430074,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,36(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	12(%r15),%r10d
        +	addb	%dl,%al
        +	movl	44(%rsi),%ebx
        +	addl	$3572445317,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,40(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	24(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	48(%rsi),%eax
        +	addl	$76029189,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,44(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	36(%r15),%r8d
        +	addb	%dl,%al
        +	movl	52(%rsi),%ebx
        +	addl	$3654602809,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,48(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	48(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	56(%rsi),%eax
        +	addl	$3873151461,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,52(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	60(%r15),%r10d
        +	addb	%dl,%al
        +	movl	60(%rsi),%ebx
        +	addl	$530742520,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,56(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	32(%r13),%xmm4
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	8(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	64(%rsi),%eax
        +	addl	$3299628645,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,60(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm1,%xmm4
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	0(%r15),%r8d
        +	addb	%dl,%al
        +	movl	68(%rsi),%ebx
        +	addl	$4096336452,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,64(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	28(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	72(%rsi),%eax
        +	addl	$1126891415,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,68(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	56(%r15),%r10d
        +	addb	%dl,%al
        +	movl	76(%rsi),%ebx
        +	addl	$2878612391,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,72(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	20(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	80(%rsi),%eax
        +	addl	$4237533241,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,76(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	48(%r15),%r8d
        +	addb	%dl,%al
        +	movl	84(%rsi),%ebx
        +	addl	$1700485571,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,80(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	12(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	88(%rsi),%eax
        +	addl	$2399980690,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,84(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	40(%r15),%r10d
        +	addb	%dl,%al
        +	movl	92(%rsi),%ebx
        +	addl	$4293915773,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,88(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	4(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	96(%rsi),%eax
        +	addl	$2240044497,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,92(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	32(%r15),%r8d
        +	addb	%dl,%al
        +	movl	100(%rsi),%ebx
        +	addl	$1873313359,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,96(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	60(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	104(%rsi),%eax
        +	addl	$4264355552,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,100(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	24(%r15),%r10d
        +	addb	%dl,%al
        +	movl	108(%rsi),%ebx
        +	addl	$2734768916,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,104(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	52(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	112(%rsi),%eax
        +	addl	$1309151649,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,108(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	16(%r15),%r8d
        +	addb	%dl,%al
        +	movl	116(%rsi),%ebx
        +	addl	$4149444226,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,112(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	44(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	120(%rsi),%eax
        +	addl	$3174756917,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,116(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	8(%r15),%r10d
        +	addb	%dl,%al
        +	movl	124(%rsi),%ebx
        +	addl	$718787259,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,120(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	48(%r13),%xmm5
        +	addb	$32,%bpl
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	36(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	0(%rdi,%rbp,4),%eax
        +	addl	$3951481745,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,124(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movq	%rbp,%rsi
        +	xorq	%rbp,%rbp
        +	movb	%sil,%bpl
        +	movq	%rcx,%rsi
        +	xorq	%rcx,%rcx
        +	movb	%sil,%cl
        +	leaq	(%rdi,%rbp,4),%rsi
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm5
        +	pxor	%xmm1,%xmm5
        +	addl	0(%rsp),%r8d
        +	addl	4(%rsp),%r9d
        +	addl	8(%rsp),%r10d
        +	addl	12(%rsp),%r11d
        +
        +	movdqu	%xmm2,(%r14,%r13,1)
        +	movdqu	%xmm3,16(%r14,%r13,1)
        +	movdqu	%xmm4,32(%r14,%r13,1)
        +	movdqu	%xmm5,48(%r14,%r13,1)
        +	leaq	64(%r15),%r15
        +	leaq	64(%r13),%r13
        +	cmpq	16(%rsp),%r15
        +	jb	.Loop
        +
        +	movq	24(%rsp),%r12
        +	subb	%al,%cl
        +	movl	%r8d,0(%r12)
        +	movl	%r9d,4(%r12)
        +	movl	%r10d,8(%r12)
        +	movl	%r11d,12(%r12)
        +	subb	$1,%bpl
        +	movl	%ebp,-8(%rdi)
        +	movl	%ecx,-4(%rdi)
        +
        +	movq	40(%rsp),%r15
        +	movq	48(%rsp),%r14
        +	movq	56(%rsp),%r13
        +	movq	64(%rsp),%r12
        +	movq	72(%rsp),%rbp
        +	movq	80(%rsp),%rbx
        +	leaq	88(%rsp),%rsp
        +.Lepilogue:
        +.Labort:
        +	.byte	0xf3,0xc3
        +.size	rc4_md5_enc,.-rc4_md5_enc
        diff --git a/vendor/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s b/vendor/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s
        new file mode 100644
        index 000000000..f2b8a8bc0
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/rc4/rc4-x86_64.s
        @@ -0,0 +1,624 @@
        +.text
        +
        +
        +
        +.globl	RC4
        +.type	RC4,@function
        +.align	16
        +RC4:	orq	%rsi,%rsi
        +	jne	.Lentry
        +	.byte	0xf3,0xc3
        +.Lentry:
        +	pushq	%rbx
        +	pushq	%r12
        +	pushq	%r13
        +.Lprologue:
        +	movq	%rsi,%r11
        +	movq	%rdx,%r12
        +	movq	%rcx,%r13
        +	xorq	%r10,%r10
        +	xorq	%rcx,%rcx
        +
        +	leaq	8(%rdi),%rdi
        +	movb	-8(%rdi),%r10b
        +	movb	-4(%rdi),%cl
        +	cmpl	$-1,256(%rdi)
        +	je	.LRC4_CHAR
        +	movl	OPENSSL_ia32cap_P(%rip),%r8d
        +	xorq	%rbx,%rbx
        +	incb	%r10b
        +	subq	%r10,%rbx
        +	subq	%r12,%r13
        +	movl	(%rdi,%r10,4),%eax
        +	testq	$-16,%r11
        +	jz	.Lloop1
        +	btl	$30,%r8d
        +	jc	.Lintel
        +	andq	$7,%rbx
        +	leaq	1(%r10),%rsi
        +	jz	.Loop8
        +	subq	%rbx,%r11
        +.Loop8_warmup:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	%edx,(%rdi,%r10,4)
        +	addb	%dl,%al
        +	incb	%r10b
        +	movl	(%rdi,%rax,4),%edx
        +	movl	(%rdi,%r10,4),%eax
        +	xorb	(%r12),%dl
        +	movb	%dl,(%r13,%r12,1)
        +	leaq	1(%r12),%r12
        +	decq	%rbx
        +	jnz	.Loop8_warmup
        +
        +	leaq	1(%r10),%rsi
        +	jmp	.Loop8
        +.align	16
        +.Loop8:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	0(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,0(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	4(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,4(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	8(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,8(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	12(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,12(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	16(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,16(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	20(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,20(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	24(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,24(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	$8,%sil
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	-4(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,28(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	$8,%r10b
        +	rorq	$8,%r8
        +	subq	$8,%r11
        +
        +	xorq	(%r12),%r8
        +	movq	%r8,(%r13,%r12,1)
        +	leaq	8(%r12),%r12
        +
        +	testq	$-8,%r11
        +	jnz	.Loop8
        +	cmpq	$0,%r11
        +	jne	.Lloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.Lintel:
        +	testq	$-32,%r11
        +	jz	.Lloop1
        +	andq	$15,%rbx
        +	jz	.Loop16_is_hot
        +	subq	%rbx,%r11
        +.Loop16_warmup:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	%edx,(%rdi,%r10,4)
        +	addb	%dl,%al
        +	incb	%r10b
        +	movl	(%rdi,%rax,4),%edx
        +	movl	(%rdi,%r10,4),%eax
        +	xorb	(%r12),%dl
        +	movb	%dl,(%r13,%r12,1)
        +	leaq	1(%r12),%r12
        +	decq	%rbx
        +	jnz	.Loop16_warmup
        +
        +	movq	%rcx,%rbx
        +	xorq	%rcx,%rcx
        +	movb	%bl,%cl
        +
        +.Loop16_is_hot:
        +	leaq	(%rdi,%r10,4),%rsi
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	pxor	%xmm0,%xmm0
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,0(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$0,(%rdi,%rax,4),%xmm0
        +	jmp	.Loop16_enter
        +.align	16
        +.Loop16:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	pxor	%xmm0,%xmm2
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,0(%rsi)
        +	pxor	%xmm1,%xmm2
        +	addb	%bl,%cl
        +	pinsrw	$0,(%rdi,%rax,4),%xmm0
        +	movdqu	%xmm2,(%r13,%r12,1)
        +	leaq	16(%r12),%r12
        +.Loop16_enter:
        +	movl	(%rdi,%rcx,4),%edx
        +	pxor	%xmm1,%xmm1
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	8(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,4(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$0,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	12(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,8(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	16(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,12(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	20(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,16(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	24(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,20(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	28(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,24(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	32(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,28(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	36(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,32(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	40(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,36(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	44(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,40(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	48(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,44(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	52(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,48(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	56(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,52(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	60(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,56(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +	addb	$16,%r10b
        +	movdqu	(%r12),%xmm2
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movzbl	%bl,%ebx
        +	movl	%edx,60(%rsi)
        +	leaq	(%rdi,%r10,4),%rsi
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +	movl	(%rsi),%eax
        +	movq	%rcx,%rbx
        +	xorq	%rcx,%rcx
        +	subq	$16,%r11
        +	movb	%bl,%cl
        +	testq	$-16,%r11
        +	jnz	.Loop16
        +
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm1,%xmm2
        +	movdqu	%xmm2,(%r13,%r12,1)
        +	leaq	16(%r12),%r12
        +
        +	cmpq	$0,%r11
        +	jne	.Lloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.Lloop1:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	%edx,(%rdi,%r10,4)
        +	addb	%dl,%al
        +	incb	%r10b
        +	movl	(%rdi,%rax,4),%edx
        +	movl	(%rdi,%r10,4),%eax
        +	xorb	(%r12),%dl
        +	movb	%dl,(%r13,%r12,1)
        +	leaq	1(%r12),%r12
        +	decq	%r11
        +	jnz	.Lloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.LRC4_CHAR:
        +	addb	$1,%r10b
        +	movzbl	(%rdi,%r10,1),%eax
        +	testq	$-8,%r11
        +	jz	.Lcloop1
        +	jmp	.Lcloop8
        +.align	16
        +.Lcloop8:
        +	movl	(%r12),%r8d
        +	movl	4(%r12),%r9d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	.Lcmov0
        +
        +	movq	%rax,%rbx
        +.Lcmov0:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	.Lcmov1
        +
        +	movq	%rbx,%rax
        +.Lcmov1:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	.Lcmov2
        +
        +	movq	%rax,%rbx
        +.Lcmov2:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	.Lcmov3
        +
        +	movq	%rbx,%rax
        +.Lcmov3:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	.Lcmov4
        +
        +	movq	%rax,%rbx
        +.Lcmov4:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	.Lcmov5
        +
        +	movq	%rbx,%rax
        +.Lcmov5:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	.Lcmov6
        +
        +	movq	%rax,%rbx
        +.Lcmov6:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	.Lcmov7
        +
        +	movq	%rbx,%rax
        +.Lcmov7:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	leaq	-8(%r11),%r11
        +	movl	%r8d,(%r13)
        +	leaq	8(%r12),%r12
        +	movl	%r9d,4(%r13)
        +	leaq	8(%r13),%r13
        +
        +	testq	$-8,%r11
        +	jnz	.Lcloop8
        +	cmpq	$0,%r11
        +	jne	.Lcloop1
        +	jmp	.Lexit
        +.align	16
        +.Lcloop1:
        +	addb	%al,%cl
        +	movzbl	%cl,%ecx
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movb	%al,(%rdi,%rcx,1)
        +	movb	%dl,(%rdi,%r10,1)
        +	addb	%al,%dl
        +	addb	$1,%r10b
        +	movzbl	%dl,%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%rdx,1),%edx
        +	movzbl	(%rdi,%r10,1),%eax
        +	xorb	(%r12),%dl
        +	leaq	1(%r12),%r12
        +	movb	%dl,(%r13)
        +	leaq	1(%r13),%r13
        +	subq	$1,%r11
        +	jnz	.Lcloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.Lexit:
        +	subb	$1,%r10b
        +	movl	%r10d,-8(%rdi)
        +	movl	%ecx,-4(%rdi)
        +
        +	movq	(%rsp),%r13
        +	movq	8(%rsp),%r12
        +	movq	16(%rsp),%rbx
        +	addq	$24,%rsp
        +.Lepilogue:
        +	.byte	0xf3,0xc3
        +.size	RC4,.-RC4
        +.globl	private_RC4_set_key
        +.type	private_RC4_set_key,@function
        +.align	16
        +private_RC4_set_key:
        +	leaq	8(%rdi),%rdi
        +	leaq	(%rdx,%rsi,1),%rdx
        +	negq	%rsi
        +	movq	%rsi,%rcx
        +	xorl	%eax,%eax
        +	xorq	%r9,%r9
        +	xorq	%r10,%r10
        +	xorq	%r11,%r11
        +
        +	movl	OPENSSL_ia32cap_P(%rip),%r8d
        +	btl	$20,%r8d
        +	jc	.Lc1stloop
        +	jmp	.Lw1stloop
        +
        +.align	16
        +.Lw1stloop:
        +	movl	%eax,(%rdi,%rax,4)
        +	addb	$1,%al
        +	jnc	.Lw1stloop
        +
        +	xorq	%r9,%r9
        +	xorq	%r8,%r8
        +.align	16
        +.Lw2ndloop:
        +	movl	(%rdi,%r9,4),%r10d
        +	addb	(%rdx,%rsi,1),%r8b
        +	addb	%r10b,%r8b
        +	addq	$1,%rsi
        +	movl	(%rdi,%r8,4),%r11d
        +	cmovzq	%rcx,%rsi
        +	movl	%r10d,(%rdi,%r8,4)
        +	movl	%r11d,(%rdi,%r9,4)
        +	addb	$1,%r9b
        +	jnc	.Lw2ndloop
        +	jmp	.Lexit_key
        +
        +.align	16
        +.Lc1stloop:
        +	movb	%al,(%rdi,%rax,1)
        +	addb	$1,%al
        +	jnc	.Lc1stloop
        +
        +	xorq	%r9,%r9
        +	xorq	%r8,%r8
        +.align	16
        +.Lc2ndloop:
        +	movb	(%rdi,%r9,1),%r10b
        +	addb	(%rdx,%rsi,1),%r8b
        +	addb	%r10b,%r8b
        +	addq	$1,%rsi
        +	movb	(%rdi,%r8,1),%r11b
        +	jnz	.Lcnowrap
        +	movq	%rcx,%rsi
        +.Lcnowrap:
        +	movb	%r10b,(%rdi,%r8,1)
        +	movb	%r11b,(%rdi,%r9,1)
        +	addb	$1,%r9b
        +	jnc	.Lc2ndloop
        +	movl	$-1,256(%rdi)
        +
        +.align	16
        +.Lexit_key:
        +	xorl	%eax,%eax
        +	movl	%eax,-8(%rdi)
        +	movl	%eax,-4(%rdi)
        +	.byte	0xf3,0xc3
        +.size	private_RC4_set_key,.-private_RC4_set_key
        +
        +.globl	RC4_options
        +.type	RC4_options,@function
        +.align	16
        +RC4_options:
        +	leaq	.Lopts(%rip),%rax
        +	movl	OPENSSL_ia32cap_P(%rip),%edx
        +	btl	$20,%edx
        +	jc	.L8xchar
        +	btl	$30,%edx
        +	jnc	.Ldone
        +	addq	$25,%rax
        +	.byte	0xf3,0xc3
        +.L8xchar:
        +	addq	$12,%rax
        +.Ldone:
        +	.byte	0xf3,0xc3
        +.align	64
        +.Lopts:
        +.byte	114,99,52,40,56,120,44,105,110,116,41,0
        +.byte	114,99,52,40,56,120,44,99,104,97,114,41,0
        +.byte	114,99,52,40,49,54,120,44,105,110,116,41,0
        +.byte	82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	64
        +.size	RC4_options,.-RC4_options
        diff --git a/vendor/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s b/vendor/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s
        new file mode 100644
        index 000000000..c11c6f650
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/sha/sha1-x86_64.s
        @@ -0,0 +1,2492 @@
        +.text
        +
        +
        +
        +.globl	sha1_block_data_order
        +.type	sha1_block_data_order,@function
        +.align	16
        +sha1_block_data_order:
        +	movl	OPENSSL_ia32cap_P+0(%rip),%r9d
        +	movl	OPENSSL_ia32cap_P+4(%rip),%r8d
        +	testl	$512,%r8d
        +	jz	.Lialu
        +	jmp	_ssse3_shortcut
        +
        +.align	16
        +.Lialu:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	movq	%rsp,%r11
        +	movq	%rdi,%r8
        +	subq	$72,%rsp
        +	movq	%rsi,%r9
        +	andq	$-64,%rsp
        +	movq	%rdx,%r10
        +	movq	%r11,64(%rsp)
        +.Lprologue:
        +
        +	movl	0(%r8),%esi
        +	movl	4(%r8),%edi
        +	movl	8(%r8),%r11d
        +	movl	12(%r8),%r12d
        +	movl	16(%r8),%r13d
        +	jmp	.Lloop
        +
        +.align	16
        +.Lloop:
        +	movl	0(%r9),%edx
        +	bswapl	%edx
        +	movl	%edx,0(%rsp)
        +	movl	%r11d,%eax
        +	movl	4(%r9),%ebp
        +	movl	%esi,%ecx
        +	xorl	%r12d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r13,1),%r13d
        +	andl	%edi,%eax
        +	movl	%ebp,4(%rsp)
        +	addl	%ecx,%r13d
        +	xorl	%r12d,%eax
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	movl	%edi,%eax
        +	movl	8(%r9),%edx
        +	movl	%r13d,%ecx
        +	xorl	%r11d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r12,1),%r12d
        +	andl	%esi,%eax
        +	movl	%edx,8(%rsp)
        +	addl	%ecx,%r12d
        +	xorl	%r11d,%eax
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	movl	%esi,%eax
        +	movl	12(%r9),%ebp
        +	movl	%r12d,%ecx
        +	xorl	%edi,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r11,1),%r11d
        +	andl	%r13d,%eax
        +	movl	%ebp,12(%rsp)
        +	addl	%ecx,%r11d
        +	xorl	%edi,%eax
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	movl	%r13d,%eax
        +	movl	16(%r9),%edx
        +	movl	%r11d,%ecx
        +	xorl	%esi,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%rdi,1),%edi
        +	andl	%r12d,%eax
        +	movl	%edx,16(%rsp)
        +	addl	%ecx,%edi
        +	xorl	%esi,%eax
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	movl	%r12d,%eax
        +	movl	20(%r9),%ebp
        +	movl	%edi,%ecx
        +	xorl	%r13d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%rsi,1),%esi
        +	andl	%r11d,%eax
        +	movl	%ebp,20(%rsp)
        +	addl	%ecx,%esi
        +	xorl	%r13d,%eax
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	movl	%r11d,%eax
        +	movl	24(%r9),%edx
        +	movl	%esi,%ecx
        +	xorl	%r12d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r13,1),%r13d
        +	andl	%edi,%eax
        +	movl	%edx,24(%rsp)
        +	addl	%ecx,%r13d
        +	xorl	%r12d,%eax
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	movl	%edi,%eax
        +	movl	28(%r9),%ebp
        +	movl	%r13d,%ecx
        +	xorl	%r11d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r12,1),%r12d
        +	andl	%esi,%eax
        +	movl	%ebp,28(%rsp)
        +	addl	%ecx,%r12d
        +	xorl	%r11d,%eax
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	movl	%esi,%eax
        +	movl	32(%r9),%edx
        +	movl	%r12d,%ecx
        +	xorl	%edi,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r11,1),%r11d
        +	andl	%r13d,%eax
        +	movl	%edx,32(%rsp)
        +	addl	%ecx,%r11d
        +	xorl	%edi,%eax
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	movl	%r13d,%eax
        +	movl	36(%r9),%ebp
        +	movl	%r11d,%ecx
        +	xorl	%esi,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%rdi,1),%edi
        +	andl	%r12d,%eax
        +	movl	%ebp,36(%rsp)
        +	addl	%ecx,%edi
        +	xorl	%esi,%eax
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	movl	%r12d,%eax
        +	movl	40(%r9),%edx
        +	movl	%edi,%ecx
        +	xorl	%r13d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%rsi,1),%esi
        +	andl	%r11d,%eax
        +	movl	%edx,40(%rsp)
        +	addl	%ecx,%esi
        +	xorl	%r13d,%eax
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	movl	%r11d,%eax
        +	movl	44(%r9),%ebp
        +	movl	%esi,%ecx
        +	xorl	%r12d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r13,1),%r13d
        +	andl	%edi,%eax
        +	movl	%ebp,44(%rsp)
        +	addl	%ecx,%r13d
        +	xorl	%r12d,%eax
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	movl	%edi,%eax
        +	movl	48(%r9),%edx
        +	movl	%r13d,%ecx
        +	xorl	%r11d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r12,1),%r12d
        +	andl	%esi,%eax
        +	movl	%edx,48(%rsp)
        +	addl	%ecx,%r12d
        +	xorl	%r11d,%eax
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	movl	%esi,%eax
        +	movl	52(%r9),%ebp
        +	movl	%r12d,%ecx
        +	xorl	%edi,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r11,1),%r11d
        +	andl	%r13d,%eax
        +	movl	%ebp,52(%rsp)
        +	addl	%ecx,%r11d
        +	xorl	%edi,%eax
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	movl	%r13d,%eax
        +	movl	56(%r9),%edx
        +	movl	%r11d,%ecx
        +	xorl	%esi,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%rdi,1),%edi
        +	andl	%r12d,%eax
        +	movl	%edx,56(%rsp)
        +	addl	%ecx,%edi
        +	xorl	%esi,%eax
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	movl	%r12d,%eax
        +	movl	60(%r9),%ebp
        +	movl	%edi,%ecx
        +	xorl	%r13d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%rsi,1),%esi
        +	andl	%r11d,%eax
        +	movl	%ebp,60(%rsp)
        +	addl	%ecx,%esi
        +	xorl	%r13d,%eax
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	movl	0(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	xorl	32(%rsp),%edx
        +	andl	%edi,%eax
        +	leal	1518500249(%rbp,%r13,1),%r13d
        +	xorl	52(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$1,%edx
        +	addl	%ecx,%r13d
        +	roll	$30,%edi
        +	movl	%edx,0(%rsp)
        +	addl	%eax,%r13d
        +	movl	4(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	xorl	36(%rsp),%ebp
        +	andl	%esi,%eax
        +	leal	1518500249(%rdx,%r12,1),%r12d
        +	xorl	56(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$1,%ebp
        +	addl	%ecx,%r12d
        +	roll	$30,%esi
        +	movl	%ebp,4(%rsp)
        +	addl	%eax,%r12d
        +	movl	8(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	xorl	40(%rsp),%edx
        +	andl	%r13d,%eax
        +	leal	1518500249(%rbp,%r11,1),%r11d
        +	xorl	60(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$1,%edx
        +	addl	%ecx,%r11d
        +	roll	$30,%r13d
        +	movl	%edx,8(%rsp)
        +	addl	%eax,%r11d
        +	movl	12(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	xorl	44(%rsp),%ebp
        +	andl	%r12d,%eax
        +	leal	1518500249(%rdx,%rdi,1),%edi
        +	xorl	0(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$1,%ebp
        +	addl	%ecx,%edi
        +	roll	$30,%r12d
        +	movl	%ebp,12(%rsp)
        +	addl	%eax,%edi
        +	movl	16(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	xorl	48(%rsp),%edx
        +	andl	%r11d,%eax
        +	leal	1518500249(%rbp,%rsi,1),%esi
        +	xorl	4(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$1,%edx
        +	addl	%ecx,%esi
        +	roll	$30,%r11d
        +	movl	%edx,16(%rsp)
        +	addl	%eax,%esi
        +	movl	20(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r13,1),%r13d
        +	xorl	52(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	8(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,20(%rsp)
        +	movl	24(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r12,1),%r12d
        +	xorl	56(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	12(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,24(%rsp)
        +	movl	28(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r11,1),%r11d
        +	xorl	60(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	16(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,28(%rsp)
        +	movl	32(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rdi,1),%edi
        +	xorl	0(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	20(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,32(%rsp)
        +	movl	36(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	44(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rsi,1),%esi
        +	xorl	4(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	24(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,36(%rsp)
        +	movl	40(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	48(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r13,1),%r13d
        +	xorl	8(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	28(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,40(%rsp)
        +	movl	44(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	52(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r12,1),%r12d
        +	xorl	12(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	32(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	%ebp,44(%rsp)
        +	movl	48(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	56(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r11,1),%r11d
        +	xorl	16(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	36(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	%edx,48(%rsp)
        +	movl	52(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rdi,1),%edi
        +	xorl	20(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	40(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%ebp,52(%rsp)
        +	movl	56(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rsi,1),%esi
        +	xorl	24(%rsp),%edx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	44(%rsp),%edx
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%edx
        +	movl	%edx,56(%rsp)
        +	movl	60(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r13,1),%r13d
        +	xorl	28(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	48(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,60(%rsp)
        +	movl	0(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r12,1),%r12d
        +	xorl	32(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	52(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,0(%rsp)
        +	movl	4(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r11,1),%r11d
        +	xorl	36(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	56(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,4(%rsp)
        +	movl	8(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rdi,1),%edi
        +	xorl	40(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	60(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,8(%rsp)
        +	movl	12(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rsi,1),%esi
        +	xorl	44(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	0(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,12(%rsp)
        +	movl	16(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r13,1),%r13d
        +	xorl	48(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	4(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,16(%rsp)
        +	movl	20(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r12,1),%r12d
        +	xorl	52(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	8(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	%ebp,20(%rsp)
        +	movl	24(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r11,1),%r11d
        +	xorl	56(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	12(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	%edx,24(%rsp)
        +	movl	28(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rdi,1),%edi
        +	xorl	60(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	16(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%ebp,28(%rsp)
        +	movl	32(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rsi,1),%esi
        +	xorl	0(%rsp),%edx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	20(%rsp),%edx
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%edx
        +	movl	%edx,32(%rsp)
        +	movl	36(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	44(%rsp),%ebp
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rdx,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	24(%rsp),%ebp
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%ebp,36(%rsp)
        +	addl	%ecx,%r13d
        +	movl	40(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	48(%rsp),%edx
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rbp,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	28(%rsp),%edx
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%edx,40(%rsp)
        +	addl	%ecx,%r12d
        +	movl	44(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	52(%rsp),%ebp
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rdx,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	32(%rsp),%ebp
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%ebp,44(%rsp)
        +	addl	%ecx,%r11d
        +	movl	48(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	56(%rsp),%edx
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rbp,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	36(%rsp),%edx
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%edx,48(%rsp)
        +	addl	%ecx,%edi
        +	movl	52(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	60(%rsp),%ebp
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rdx,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	40(%rsp),%ebp
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%ebp,52(%rsp)
        +	addl	%ecx,%esi
        +	movl	56(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	0(%rsp),%edx
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rbp,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	44(%rsp),%edx
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%edx,56(%rsp)
        +	addl	%ecx,%r13d
        +	movl	60(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	4(%rsp),%ebp
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rdx,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	48(%rsp),%ebp
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%ebp,60(%rsp)
        +	addl	%ecx,%r12d
        +	movl	0(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	8(%rsp),%edx
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rbp,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	52(%rsp),%edx
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%edx,0(%rsp)
        +	addl	%ecx,%r11d
        +	movl	4(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	12(%rsp),%ebp
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rdx,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	56(%rsp),%ebp
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%ebp,4(%rsp)
        +	addl	%ecx,%edi
        +	movl	8(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	16(%rsp),%edx
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rbp,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	60(%rsp),%edx
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%edx,8(%rsp)
        +	addl	%ecx,%esi
        +	movl	12(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	20(%rsp),%ebp
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	44(%rsp),%ebp
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rdx,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	0(%rsp),%ebp
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%ebp,12(%rsp)
        +	addl	%ecx,%r13d
        +	movl	16(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	24(%rsp),%edx
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	48(%rsp),%edx
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rbp,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	4(%rsp),%edx
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%edx,16(%rsp)
        +	addl	%ecx,%r12d
        +	movl	20(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	28(%rsp),%ebp
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	52(%rsp),%ebp
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rdx,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	8(%rsp),%ebp
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%ebp,20(%rsp)
        +	addl	%ecx,%r11d
        +	movl	24(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	32(%rsp),%edx
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	56(%rsp),%edx
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rbp,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	12(%rsp),%edx
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%edx,24(%rsp)
        +	addl	%ecx,%edi
        +	movl	28(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	36(%rsp),%ebp
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rdx,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	16(%rsp),%ebp
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%ebp,28(%rsp)
        +	addl	%ecx,%esi
        +	movl	32(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	40(%rsp),%edx
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rbp,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	20(%rsp),%edx
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%edx,32(%rsp)
        +	addl	%ecx,%r13d
        +	movl	36(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	44(%rsp),%ebp
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rdx,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	24(%rsp),%ebp
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%ebp,36(%rsp)
        +	addl	%ecx,%r12d
        +	movl	40(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	48(%rsp),%edx
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rbp,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	28(%rsp),%edx
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%edx,40(%rsp)
        +	addl	%ecx,%r11d
        +	movl	44(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	52(%rsp),%ebp
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rdx,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	32(%rsp),%ebp
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%ebp,44(%rsp)
        +	addl	%ecx,%edi
        +	movl	48(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	56(%rsp),%edx
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rbp,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	36(%rsp),%edx
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%edx,48(%rsp)
        +	addl	%ecx,%esi
        +	movl	52(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r13,1),%r13d
        +	xorl	20(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	40(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,52(%rsp)
        +	movl	56(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r12,1),%r12d
        +	xorl	24(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	44(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,56(%rsp)
        +	movl	60(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r11,1),%r11d
        +	xorl	28(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	48(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,60(%rsp)
        +	movl	0(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%rdi,1),%edi
        +	xorl	32(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	52(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,0(%rsp)
        +	movl	4(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rsi,1),%esi
        +	xorl	36(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	56(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,4(%rsp)
        +	movl	8(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r13,1),%r13d
        +	xorl	40(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	60(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,8(%rsp)
        +	movl	12(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r12,1),%r12d
        +	xorl	44(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	0(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	%ebp,12(%rsp)
        +	movl	16(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r11,1),%r11d
        +	xorl	48(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	4(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	%edx,16(%rsp)
        +	movl	20(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rdi,1),%edi
        +	xorl	52(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	8(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%ebp,20(%rsp)
        +	movl	24(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%rsi,1),%esi
        +	xorl	56(%rsp),%edx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	12(%rsp),%edx
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%edx
        +	movl	%edx,24(%rsp)
        +	movl	28(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r13,1),%r13d
        +	xorl	60(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	16(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,28(%rsp)
        +	movl	32(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r12,1),%r12d
        +	xorl	0(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	20(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,32(%rsp)
        +	movl	36(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	44(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r11,1),%r11d
        +	xorl	4(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	24(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,36(%rsp)
        +	movl	40(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	48(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%rdi,1),%edi
        +	xorl	8(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	28(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,40(%rsp)
        +	movl	44(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	52(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rsi,1),%esi
        +	xorl	12(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	32(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,44(%rsp)
        +	movl	48(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	56(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r13,1),%r13d
        +	xorl	16(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	36(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,48(%rsp)
        +	movl	52(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r12,1),%r12d
        +	xorl	20(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	40(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	56(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r11,1),%r11d
        +	xorl	24(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	44(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	60(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rdi,1),%edi
        +	xorl	28(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	48(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	%r11d,%eax
        +	leal	-899497514(%rbp,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	addl	0(%r8),%esi
        +	addl	4(%r8),%edi
        +	addl	8(%r8),%r11d
        +	addl	12(%r8),%r12d
        +	addl	16(%r8),%r13d
        +	movl	%esi,0(%r8)
        +	movl	%edi,4(%r8)
        +	movl	%r11d,8(%r8)
        +	movl	%r12d,12(%r8)
        +	movl	%r13d,16(%r8)
        +
        +	subq	$1,%r10
        +	leaq	64(%r9),%r9
        +	jnz	.Lloop
        +
        +	movq	64(%rsp),%rsi
        +	movq	(%rsi),%r13
        +	movq	8(%rsi),%r12
        +	movq	16(%rsi),%rbp
        +	movq	24(%rsi),%rbx
        +	leaq	32(%rsi),%rsp
        +.Lepilogue:
        +	.byte	0xf3,0xc3
        +.size	sha1_block_data_order,.-sha1_block_data_order
        +.type	sha1_block_data_order_ssse3,@function
        +.align	16
        +sha1_block_data_order_ssse3:
        +_ssse3_shortcut:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	leaq	-64(%rsp),%rsp
        +	movq	%rdi,%r8
        +	movq	%rsi,%r9
        +	movq	%rdx,%r10
        +
        +	shlq	$6,%r10
        +	addq	%r9,%r10
        +	leaq	K_XX_XX(%rip),%r11
        +
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movl	%ebx,%esi
        +	movl	16(%r8),%ebp
        +
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r9),%xmm0
        +	movdqu	16(%r9),%xmm1
        +	movdqu	32(%r9),%xmm2
        +	movdqu	48(%r9),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r9
        +.byte	102,15,56,0,206
        +.byte	102,15,56,0,214
        +.byte	102,15,56,0,222
        +	paddd	%xmm9,%xmm0
        +	paddd	%xmm9,%xmm1
        +	paddd	%xmm9,%xmm2
        +	movdqa	%xmm0,0(%rsp)
        +	psubd	%xmm9,%xmm0
        +	movdqa	%xmm1,16(%rsp)
        +	psubd	%xmm9,%xmm1
        +	movdqa	%xmm2,32(%rsp)
        +	psubd	%xmm9,%xmm2
        +	jmp	.Loop_ssse3
        +.align	16
        +.Loop_ssse3:
        +	movdqa	%xmm1,%xmm4
        +	addl	0(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	movdqa	%xmm3,%xmm8
        +.byte	102,15,58,15,224,8
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	paddd	%xmm3,%xmm9
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrldq	$4,%xmm8
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	pxor	%xmm0,%xmm4
        +	rorl	$2,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm2,%xmm8
        +	addl	4(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pxor	%xmm8,%xmm4
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm9,48(%rsp)
        +	xorl	%ecx,%edi
        +	addl	%ebp,%edx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm4,%xmm8
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	8(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	pslldq	$12,%xmm10
        +	paddd	%xmm4,%xmm4
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrld	$31,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm4
        +	addl	12(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm4
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	0(%r11),%xmm10
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	pxor	%xmm9,%xmm4
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movdqa	%xmm2,%xmm5
        +	addl	16(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movdqa	%xmm4,%xmm9
        +.byte	102,15,58,15,233,8
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	paddd	%xmm4,%xmm10
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrldq	$4,%xmm9
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	pxor	%xmm1,%xmm5
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm3,%xmm9
        +	addl	20(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pxor	%xmm9,%xmm5
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	%xmm10,0(%rsp)
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm5,%xmm9
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	24(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	pslldq	$12,%xmm8
        +	paddd	%xmm5,%xmm5
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	psrld	$31,%xmm9
        +	xorl	%ecx,%esi
        +	addl	%ebp,%edx
        +	movdqa	%xmm8,%xmm10
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	psrld	$30,%xmm8
        +	por	%xmm9,%xmm5
        +	addl	28(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	pslld	$2,%xmm10
        +	pxor	%xmm8,%xmm5
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	16(%r11),%xmm8
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	pxor	%xmm10,%xmm5
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movdqa	%xmm3,%xmm6
        +	addl	32(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movdqa	%xmm5,%xmm10
        +.byte	102,15,58,15,242,8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	paddd	%xmm5,%xmm8
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	psrldq	$4,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	pxor	%xmm2,%xmm6
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm4,%xmm10
        +	addl	36(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	pxor	%xmm10,%xmm6
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm8,16(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm6,%xmm10
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	40(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	pslldq	$12,%xmm9
        +	paddd	%xmm6,%xmm6
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrld	$31,%xmm10
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	psrld	$30,%xmm9
        +	por	%xmm10,%xmm6
        +	addl	44(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pslld	$2,%xmm8
        +	pxor	%xmm9,%xmm6
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	16(%r11),%xmm9
        +	xorl	%ecx,%edi
        +	addl	%ebp,%edx
        +	pxor	%xmm8,%xmm6
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movdqa	%xmm4,%xmm7
        +	addl	48(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm8
        +.byte	102,15,58,15,251,8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm6,%xmm9
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrldq	$4,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	pxor	%xmm3,%xmm7
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm5,%xmm8
        +	addl	52(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	pxor	%xmm8,%xmm7
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm7,%xmm8
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	56(%rsp),%eax
        +	xorl	%ebp,%edx
        +	pslldq	$12,%xmm10
        +	paddd	%xmm7,%xmm7
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrld	$31,%xmm8
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm7
        +	addl	60(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm7
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	16(%r11),%xmm10
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	pxor	%xmm9,%xmm7
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movdqa	%xmm7,%xmm9
        +	addl	0(%rsp),%edx
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,206,8
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm1,%xmm0
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm7,%xmm10
        +	xorl	%ecx,%esi
        +	addl	%ebp,%edx
        +	pxor	%xmm9,%xmm0
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	4(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm0,%xmm9
        +	movdqa	%xmm10,48(%rsp)
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	pslld	$2,%xmm0
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	psrld	$30,%xmm9
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	8(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	por	%xmm9,%xmm0
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm0,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	12(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	16(%rsp),%ebp
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,215,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm2,%xmm1
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm0,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm10,%xmm1
        +	addl	20(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm1,%xmm10
        +	movdqa	%xmm8,0(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm1
        +	addl	24(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm10
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm10,%xmm1
        +	addl	28(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movdqa	%xmm1,%xmm8
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	32(%rsp),%eax
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,192,8
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	pxor	%xmm3,%xmm2
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	movdqa	32(%r11),%xmm10
        +	paddd	%xmm1,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm8,%xmm2
        +	addl	36(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	movdqa	%xmm2,%xmm8
        +	movdqa	%xmm9,16(%rsp)
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	pslld	$2,%xmm2
        +	addl	40(%rsp),%edx
        +	xorl	%ecx,%esi
        +	psrld	$30,%xmm8
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	por	%xmm8,%xmm2
        +	addl	44(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movdqa	%xmm2,%xmm9
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	48(%rsp),%ebx
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,201,8
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	pxor	%xmm4,%xmm3
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm2,%xmm10
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm9,%xmm3
        +	addl	52(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	movdqa	%xmm3,%xmm9
        +	movdqa	%xmm10,32(%rsp)
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ebp
        +	xorl	%edx,%esi
        +	psrld	$30,%xmm9
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	por	%xmm9,%xmm3
        +	addl	60(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movdqa	%xmm3,%xmm10
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	0(%rsp),%ecx
        +	pxor	%xmm0,%xmm4
        +.byte	102,68,15,58,15,210,8
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	pxor	%xmm5,%xmm4
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm3,%xmm8
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm10,%xmm4
        +	addl	4(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm8,48(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	pslld	$2,%xmm4
        +	addl	8(%rsp),%eax
        +	xorl	%ebp,%esi
        +	psrld	$30,%xmm10
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	por	%xmm10,%xmm4
        +	addl	12(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movdqa	%xmm4,%xmm8
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	16(%rsp),%edx
        +	pxor	%xmm1,%xmm5
        +.byte	102,68,15,58,15,195,8
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm6,%xmm5
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm4,%xmm9
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	pxor	%xmm8,%xmm5
        +	addl	20(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm9,0(%rsp)
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	pslld	$2,%xmm5
        +	addl	24(%rsp),%ebx
        +	xorl	%eax,%esi
        +	psrld	$30,%xmm8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	por	%xmm8,%xmm5
        +	addl	28(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movdqa	%xmm5,%xmm9
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ecx,%edi
        +	pxor	%xmm2,%xmm6
        +.byte	102,68,15,58,15,204,8
        +	xorl	%edx,%ecx
        +	addl	32(%rsp),%ebp
        +	andl	%edx,%edi
        +	pxor	%xmm7,%xmm6
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm5,%xmm10
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	pxor	%xmm9,%xmm6
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm10,16(%rsp)
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	36(%rsp),%edx
        +	andl	%ecx,%esi
        +	pslld	$2,%xmm6
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	psrld	$30,%xmm9
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	por	%xmm9,%xmm6
        +	movl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm10
        +	addl	40(%rsp),%ecx
        +	andl	%ebx,%edi
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	44(%rsp),%ebx
        +	andl	%eax,%esi
        +	andl	%ebp,%edi
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%edi
        +	pxor	%xmm3,%xmm7
        +.byte	102,68,15,58,15,213,8
        +	xorl	%ebp,%edx
        +	addl	48(%rsp),%eax
        +	andl	%ebp,%edi
        +	pxor	%xmm0,%xmm7
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	movdqa	48(%r11),%xmm9
        +	paddd	%xmm6,%xmm8
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	pxor	%xmm10,%xmm7
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm8,32(%rsp)
        +	movl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	addl	52(%rsp),%ebp
        +	andl	%edx,%esi
        +	pslld	$2,%xmm7
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	psrld	$30,%xmm10
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	por	%xmm10,%xmm7
        +	movl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm8
        +	addl	56(%rsp),%edx
        +	andl	%ecx,%edi
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	60(%rsp),%ecx
        +	andl	%ebx,%esi
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%edi
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,198,8
        +	xorl	%eax,%ebp
        +	addl	0(%rsp),%ebx
        +	andl	%eax,%edi
        +	pxor	%xmm1,%xmm0
        +	andl	%ebp,%esi
        +	rorl	$7,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm7,%xmm9
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	pxor	%xmm8,%xmm0
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movdqa	%xmm0,%xmm8
        +	movdqa	%xmm9,48(%rsp)
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	4(%rsp),%eax
        +	andl	%ebp,%esi
        +	pslld	$2,%xmm0
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	psrld	$30,%xmm8
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	por	%xmm8,%xmm0
        +	movl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	%xmm0,%xmm9
        +	addl	8(%rsp),%ebp
        +	andl	%edx,%edi
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	12(%rsp),%edx
        +	andl	%ecx,%esi
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%edi
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,207,8
        +	xorl	%ebx,%eax
        +	addl	16(%rsp),%ecx
        +	andl	%ebx,%edi
        +	pxor	%xmm2,%xmm1
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm0,%xmm10
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	pxor	%xmm9,%xmm1
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movdqa	%xmm1,%xmm9
        +	movdqa	%xmm10,0(%rsp)
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	20(%rsp),%ebx
        +	andl	%eax,%esi
        +	pslld	$2,%xmm1
        +	andl	%ebp,%edi
        +	rorl	$7,%edx
        +	psrld	$30,%xmm9
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	por	%xmm9,%xmm1
        +	movl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm1,%xmm10
        +	addl	24(%rsp),%eax
        +	andl	%ebp,%edi
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	addl	28(%rsp),%ebp
        +	andl	%edx,%esi
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%edi
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,208,8
        +	xorl	%ecx,%ebx
        +	addl	32(%rsp),%edx
        +	andl	%ecx,%edi
        +	pxor	%xmm3,%xmm2
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm1,%xmm8
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	pxor	%xmm10,%xmm2
        +	roll	$5,%ebp
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movdqa	%xmm2,%xmm10
        +	movdqa	%xmm8,16(%rsp)
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	36(%rsp),%ecx
        +	andl	%ebx,%esi
        +	pslld	$2,%xmm2
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	psrld	$30,%xmm10
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	por	%xmm10,%xmm2
        +	movl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm2,%xmm8
        +	addl	40(%rsp),%ebx
        +	andl	%eax,%edi
        +	andl	%ebp,%esi
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	44(%rsp),%eax
        +	andl	%ebp,%esi
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	addl	48(%rsp),%ebp
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,193,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm4,%xmm3
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm2,%xmm9
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm8,%xmm3
        +	addl	52(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm3,%xmm8
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm8,%xmm3
        +	addl	60(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	0(%rsp),%eax
        +	paddd	%xmm3,%xmm10
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	movdqa	%xmm10,48(%rsp)
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	4(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	8(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	12(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	cmpq	%r10,%r9
        +	je	.Ldone_ssse3
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r9),%xmm0
        +	movdqu	16(%r9),%xmm1
        +	movdqu	32(%r9),%xmm2
        +	movdqu	48(%r9),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r9
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +.byte	102,15,56,0,206
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	paddd	%xmm9,%xmm0
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movdqa	%xmm0,0(%rsp)
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	psubd	%xmm9,%xmm0
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +.byte	102,15,56,0,214
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm9,%xmm1
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movdqa	%xmm1,16(%rsp)
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	psubd	%xmm9,%xmm1
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +.byte	102,15,56,0,222
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	paddd	%xmm9,%xmm2
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movdqa	%xmm2,32(%rsp)
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	psubd	%xmm9,%xmm2
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	0(%r8),%eax
        +	addl	4(%r8),%esi
        +	addl	8(%r8),%ecx
        +	addl	12(%r8),%edx
        +	movl	%eax,0(%r8)
        +	addl	16(%r8),%ebp
        +	movl	%esi,4(%r8)
        +	movl	%esi,%ebx
        +	movl	%ecx,8(%r8)
        +	movl	%edx,12(%r8)
        +	movl	%ebp,16(%r8)
        +	jmp	.Loop_ssse3
        +
        +.align	16
        +.Ldone_ssse3:
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	0(%r8),%eax
        +	addl	4(%r8),%esi
        +	addl	8(%r8),%ecx
        +	movl	%eax,0(%r8)
        +	addl	12(%r8),%edx
        +	movl	%esi,4(%r8)
        +	addl	16(%r8),%ebp
        +	movl	%ecx,8(%r8)
        +	movl	%edx,12(%r8)
        +	movl	%ebp,16(%r8)
        +	leaq	64(%rsp),%rsi
        +	movq	0(%rsi),%r12
        +	movq	8(%rsi),%rbp
        +	movq	16(%rsi),%rbx
        +	leaq	24(%rsi),%rsp
        +.Lepilogue_ssse3:
        +	.byte	0xf3,0xc3
        +.size	sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
        +.align	64
        +K_XX_XX:
        +.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999
        +
        +.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
        +
        +.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
        +
        +.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
        +
        +.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
        +
        +.byte	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	64
        diff --git a/vendor/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s b/vendor/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s
        new file mode 100644
        index 000000000..576d7d8bf
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/sha/sha512-x86_64.s
        @@ -0,0 +1,1779 @@
        +.text
        +
        +
        +.globl	sha256_block_data_order
        +.type	sha256_block_data_order,@function
        +.align	16
        +sha256_block_data_order:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	movq	%rsp,%r11
        +	shlq	$4,%rdx
        +	subq	$64+32,%rsp
        +	leaq	(%rsi,%rdx,4),%rdx
        +	andq	$-64,%rsp
        +	movq	%rdi,64+0(%rsp)
        +	movq	%rsi,64+8(%rsp)
        +	movq	%rdx,64+16(%rsp)
        +	movq	%r11,64+24(%rsp)
        +.Lprologue:
        +
        +	leaq	K256(%rip),%rbp
        +
        +	movl	0(%rdi),%eax
        +	movl	4(%rdi),%ebx
        +	movl	8(%rdi),%ecx
        +	movl	12(%rdi),%edx
        +	movl	16(%rdi),%r8d
        +	movl	20(%rdi),%r9d
        +	movl	24(%rdi),%r10d
        +	movl	28(%rdi),%r11d
        +	jmp	.Lloop
        +
        +.align	16
        +.Lloop:
        +	xorq	%rdi,%rdi
        +	movl	0(%rsi),%r12d
        +	movl	%r8d,%r13d
        +	movl	%eax,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,0(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	4(%rsi),%r12d
        +	movl	%edx,%r13d
        +	movl	%r11d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,4(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	8(%rsi),%r12d
        +	movl	%ecx,%r13d
        +	movl	%r10d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,8(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	12(%rsi),%r12d
        +	movl	%ebx,%r13d
        +	movl	%r9d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,12(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	16(%rsi),%r12d
        +	movl	%eax,%r13d
        +	movl	%r8d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,16(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	20(%rsi),%r12d
        +	movl	%r11d,%r13d
        +	movl	%edx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,20(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	24(%rsi),%r12d
        +	movl	%r10d,%r13d
        +	movl	%ecx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,24(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	28(%rsi),%r12d
        +	movl	%r9d,%r13d
        +	movl	%ebx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,28(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	movl	32(%rsi),%r12d
        +	movl	%r8d,%r13d
        +	movl	%eax,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,32(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	36(%rsi),%r12d
        +	movl	%edx,%r13d
        +	movl	%r11d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,36(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	40(%rsi),%r12d
        +	movl	%ecx,%r13d
        +	movl	%r10d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,40(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	44(%rsi),%r12d
        +	movl	%ebx,%r13d
        +	movl	%r9d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,44(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	48(%rsi),%r12d
        +	movl	%eax,%r13d
        +	movl	%r8d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,48(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	52(%rsi),%r12d
        +	movl	%r11d,%r13d
        +	movl	%edx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,52(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	56(%rsi),%r12d
        +	movl	%r10d,%r13d
        +	movl	%ecx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,56(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	60(%rsi),%r12d
        +	movl	%r9d,%r13d
        +	movl	%ebx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,60(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	jmp	.Lrounds_16_xx
        +.align	16
        +.Lrounds_16_xx:
        +	movl	4(%rsp),%r13d
        +	movl	56(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	36(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	0(%rsp),%r12d
        +	movl	%r8d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%eax,%r14d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,0(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	8(%rsp),%r13d
        +	movl	60(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	40(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	4(%rsp),%r12d
        +	movl	%edx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r11d,%r14d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,4(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	12(%rsp),%r13d
        +	movl	0(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	44(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	8(%rsp),%r12d
        +	movl	%ecx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r10d,%r14d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,8(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	16(%rsp),%r13d
        +	movl	4(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	48(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	12(%rsp),%r12d
        +	movl	%ebx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r9d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,12(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	20(%rsp),%r13d
        +	movl	8(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	52(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	16(%rsp),%r12d
        +	movl	%eax,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r8d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,16(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	24(%rsp),%r13d
        +	movl	12(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	56(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	20(%rsp),%r12d
        +	movl	%r11d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%edx,%r14d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,20(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	28(%rsp),%r13d
        +	movl	16(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	60(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	24(%rsp),%r12d
        +	movl	%r10d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ecx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,24(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	32(%rsp),%r13d
        +	movl	20(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	0(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	28(%rsp),%r12d
        +	movl	%r9d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ebx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,28(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	movl	36(%rsp),%r13d
        +	movl	24(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	4(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	32(%rsp),%r12d
        +	movl	%r8d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%eax,%r14d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,32(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	40(%rsp),%r13d
        +	movl	28(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	8(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	36(%rsp),%r12d
        +	movl	%edx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r11d,%r14d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,36(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	44(%rsp),%r13d
        +	movl	32(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	12(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	40(%rsp),%r12d
        +	movl	%ecx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r10d,%r14d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,40(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	48(%rsp),%r13d
        +	movl	36(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	16(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	44(%rsp),%r12d
        +	movl	%ebx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r9d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,44(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	52(%rsp),%r13d
        +	movl	40(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	20(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	48(%rsp),%r12d
        +	movl	%eax,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r8d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,48(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	56(%rsp),%r13d
        +	movl	44(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	24(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	52(%rsp),%r12d
        +	movl	%r11d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%edx,%r14d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,52(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	60(%rsp),%r13d
        +	movl	48(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	28(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	56(%rsp),%r12d
        +	movl	%r10d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ecx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,56(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	0(%rsp),%r13d
        +	movl	52(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	32(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	60(%rsp),%r12d
        +	movl	%r9d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ebx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,60(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	cmpq	$64,%rdi
        +	jb	.Lrounds_16_xx
        +
        +	movq	64+0(%rsp),%rdi
        +	leaq	64(%rsi),%rsi
        +
        +	addl	0(%rdi),%eax
        +	addl	4(%rdi),%ebx
        +	addl	8(%rdi),%ecx
        +	addl	12(%rdi),%edx
        +	addl	16(%rdi),%r8d
        +	addl	20(%rdi),%r9d
        +	addl	24(%rdi),%r10d
        +	addl	28(%rdi),%r11d
        +
        +	cmpq	64+16(%rsp),%rsi
        +
        +	movl	%eax,0(%rdi)
        +	movl	%ebx,4(%rdi)
        +	movl	%ecx,8(%rdi)
        +	movl	%edx,12(%rdi)
        +	movl	%r8d,16(%rdi)
        +	movl	%r9d,20(%rdi)
        +	movl	%r10d,24(%rdi)
        +	movl	%r11d,28(%rdi)
        +	jb	.Lloop
        +
        +	movq	64+24(%rsp),%rsi
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lepilogue:
        +	.byte	0xf3,0xc3
        +.size	sha256_block_data_order,.-sha256_block_data_order
        +.align	64
        +.type	K256,@object
        +K256:
        +.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        diff --git a/vendor/openssl/asm/x64-elf-gas/whrlpool/wp-x86_64.s b/vendor/openssl/asm/x64-elf-gas/whrlpool/wp-x86_64.s
        new file mode 100644
        index 000000000..6c2656c9a
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/whrlpool/wp-x86_64.s
        @@ -0,0 +1,859 @@
        +.text
        +
        +
        +.globl	whirlpool_block
        +.type	whirlpool_block,@function
        +.align	16
        +whirlpool_block:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	movq	%rsp,%r11
        +	subq	$128+40,%rsp
        +	andq	$-64,%rsp
        +
        +	leaq	128(%rsp),%r10
        +	movq	%rdi,0(%r10)
        +	movq	%rsi,8(%r10)
        +	movq	%rdx,16(%r10)
        +	movq	%r11,32(%r10)
        +.Lprologue:
        +
        +	movq	%r10,%rbx
        +	leaq	.Ltable(%rip),%rbp
        +
        +	xorq	%rcx,%rcx
        +	xorq	%rdx,%rdx
        +	movq	0(%rdi),%r8
        +	movq	8(%rdi),%r9
        +	movq	16(%rdi),%r10
        +	movq	24(%rdi),%r11
        +	movq	32(%rdi),%r12
        +	movq	40(%rdi),%r13
        +	movq	48(%rdi),%r14
        +	movq	56(%rdi),%r15
        +.Louterloop:
        +	movq	%r8,0(%rsp)
        +	movq	%r9,8(%rsp)
        +	movq	%r10,16(%rsp)
        +	movq	%r11,24(%rsp)
        +	movq	%r12,32(%rsp)
        +	movq	%r13,40(%rsp)
        +	movq	%r14,48(%rsp)
        +	movq	%r15,56(%rsp)
        +	xorq	0(%rsi),%r8
        +	xorq	8(%rsi),%r9
        +	xorq	16(%rsi),%r10
        +	xorq	24(%rsi),%r11
        +	xorq	32(%rsi),%r12
        +	xorq	40(%rsi),%r13
        +	xorq	48(%rsi),%r14
        +	xorq	56(%rsi),%r15
        +	movq	%r8,64+0(%rsp)
        +	movq	%r9,64+8(%rsp)
        +	movq	%r10,64+16(%rsp)
        +	movq	%r11,64+24(%rsp)
        +	movq	%r12,64+32(%rsp)
        +	movq	%r13,64+40(%rsp)
        +	movq	%r14,64+48(%rsp)
        +	movq	%r15,64+56(%rsp)
        +	xorq	%rsi,%rsi
        +	movq	%rsi,24(%rbx)
        +.align	16
        +.Lround:
        +	movq	4096(%rbp,%rsi,8),%r8
        +	movl	0(%rsp),%eax
        +	movl	4(%rsp),%ebx
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r8
        +	movq	7(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	0+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	movq	6(%rbp,%rsi,8),%r10
        +	movq	5(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	movq	4(%rbp,%rsi,8),%r12
        +	movq	3(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	0+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	movq	2(%rbp,%rsi,8),%r14
        +	movq	1(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r9
        +	xorq	7(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	8+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r11
        +	xorq	5(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r13
        +	xorq	3(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	8+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r15
        +	xorq	1(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r10
        +	xorq	7(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	16+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r12
        +	xorq	5(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r14
        +	xorq	3(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	16+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r8
        +	xorq	1(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r11
        +	xorq	7(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	24+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r13
        +	xorq	5(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r15
        +	xorq	3(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	24+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r9
        +	xorq	1(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r12
        +	xorq	7(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	32+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r14
        +	xorq	5(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r8
        +	xorq	3(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	32+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r10
        +	xorq	1(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r13
        +	xorq	7(%rbp,%rdi,8),%r14
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	40+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r15
        +	xorq	5(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r9
        +	xorq	3(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	40+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r11
        +	xorq	1(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r14
        +	xorq	7(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	48+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r8
        +	xorq	5(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r10
        +	xorq	3(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	48+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r12
        +	xorq	1(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r15
        +	xorq	7(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	56+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r9
        +	xorq	5(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r11
        +	xorq	3(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	56+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r13
        +	xorq	1(%rbp,%rdi,8),%r14
        +	movq	%r8,0(%rsp)
        +	movq	%r9,8(%rsp)
        +	movq	%r10,16(%rsp)
        +	movq	%r11,24(%rsp)
        +	movq	%r12,32(%rsp)
        +	movq	%r13,40(%rsp)
        +	movq	%r14,48(%rsp)
        +	movq	%r15,56(%rsp)
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r8
        +	xorq	7(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+0+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r10
        +	xorq	5(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r12
        +	xorq	3(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+0+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r14
        +	xorq	1(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r9
        +	xorq	7(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+8+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r11
        +	xorq	5(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r13
        +	xorq	3(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+8+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r15
        +	xorq	1(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r10
        +	xorq	7(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+16+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r12
        +	xorq	5(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r14
        +	xorq	3(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+16+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r8
        +	xorq	1(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r11
        +	xorq	7(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+24+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r13
        +	xorq	5(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r15
        +	xorq	3(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+24+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r9
        +	xorq	1(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r12
        +	xorq	7(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+32+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r14
        +	xorq	5(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r8
        +	xorq	3(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+32+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r10
        +	xorq	1(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r13
        +	xorq	7(%rbp,%rdi,8),%r14
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+40+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r15
        +	xorq	5(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r9
        +	xorq	3(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+40+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r11
        +	xorq	1(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r14
        +	xorq	7(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+48+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r8
        +	xorq	5(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r10
        +	xorq	3(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+48+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r12
        +	xorq	1(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r15
        +	xorq	7(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r9
        +	xorq	5(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r11
        +	xorq	3(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r13
        +	xorq	1(%rbp,%rdi,8),%r14
        +	leaq	128(%rsp),%rbx
        +	movq	24(%rbx),%rsi
        +	addq	$1,%rsi
        +	cmpq	$10,%rsi
        +	je	.Lroundsdone
        +
        +	movq	%rsi,24(%rbx)
        +	movq	%r8,64+0(%rsp)
        +	movq	%r9,64+8(%rsp)
        +	movq	%r10,64+16(%rsp)
        +	movq	%r11,64+24(%rsp)
        +	movq	%r12,64+32(%rsp)
        +	movq	%r13,64+40(%rsp)
        +	movq	%r14,64+48(%rsp)
        +	movq	%r15,64+56(%rsp)
        +	jmp	.Lround
        +.align	16
        +.Lroundsdone:
        +	movq	0(%rbx),%rdi
        +	movq	8(%rbx),%rsi
        +	movq	16(%rbx),%rax
        +	xorq	0(%rsi),%r8
        +	xorq	8(%rsi),%r9
        +	xorq	16(%rsi),%r10
        +	xorq	24(%rsi),%r11
        +	xorq	32(%rsi),%r12
        +	xorq	40(%rsi),%r13
        +	xorq	48(%rsi),%r14
        +	xorq	56(%rsi),%r15
        +	xorq	0(%rdi),%r8
        +	xorq	8(%rdi),%r9
        +	xorq	16(%rdi),%r10
        +	xorq	24(%rdi),%r11
        +	xorq	32(%rdi),%r12
        +	xorq	40(%rdi),%r13
        +	xorq	48(%rdi),%r14
        +	xorq	56(%rdi),%r15
        +	movq	%r8,0(%rdi)
        +	movq	%r9,8(%rdi)
        +	movq	%r10,16(%rdi)
        +	movq	%r11,24(%rdi)
        +	movq	%r12,32(%rdi)
        +	movq	%r13,40(%rdi)
        +	movq	%r14,48(%rdi)
        +	movq	%r15,56(%rdi)
        +	leaq	64(%rsi),%rsi
        +	subq	$1,%rax
        +	jz	.Lalldone
        +	movq	%rsi,8(%rbx)
        +	movq	%rax,16(%rbx)
        +	jmp	.Louterloop
        +.Lalldone:
        +	movq	32(%rbx),%rsi
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +.Lepilogue:
        +	.byte	0xf3,0xc3
        +.size	whirlpool_block,.-whirlpool_block
        +
        +.align	64
        +.type	.Ltable,@object
        +.Ltable:
        +.byte	24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216
        +.byte	35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38
        +.byte	198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184
        +.byte	232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251
        +.byte	135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203
        +.byte	184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17
        +.byte	1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9
        +.byte	79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13
        +.byte	54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155
        +.byte	166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255
        +.byte	210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12
        +.byte	245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14
        +.byte	121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150
        +.byte	111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48
        +.byte	145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109
        +.byte	82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248
        +.byte	96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71
        +.byte	188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53
        +.byte	155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55
        +.byte	142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138
        +.byte	163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210
        +.byte	12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108
        +.byte	123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132
        +.byte	53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128
        +.byte	29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245
        +.byte	224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179
        +.byte	215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33
        +.byte	194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156
        +.byte	46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67
        +.byte	75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41
        +.byte	254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93
        +.byte	87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213
        +.byte	21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189
        +.byte	119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232
        +.byte	55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146
        +.byte	229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158
        +.byte	159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19
        +.byte	240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35
        +.byte	74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32
        +.byte	218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68
        +.byte	88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162
        +.byte	201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207
        +.byte	41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124
        +.byte	10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90
        +.byte	177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80
        +.byte	160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201
        +.byte	107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20
        +.byte	133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217
        +.byte	189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60
        +.byte	93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143
        +.byte	16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144
        +.byte	244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7
        +.byte	203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221
        +.byte	62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211
        +.byte	5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45
        +.byte	103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120
        +.byte	228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151
        +.byte	39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2
        +.byte	65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115
        +.byte	139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167
        +.byte	167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246
        +.byte	125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178
        +.byte	149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73
        +.byte	216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86
        +.byte	251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112
        +.byte	238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205
        +.byte	124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187
        +.byte	102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113
        +.byte	221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123
        +.byte	23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175
        +.byte	71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69
        +.byte	158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26
        +.byte	202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212
        +.byte	45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88
        +.byte	191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46
        +.byte	7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63
        +.byte	173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172
        +.byte	90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176
        +.byte	131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239
        +.byte	51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182
        +.byte	99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92
        +.byte	2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18
        +.byte	170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147
        +.byte	113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222
        +.byte	200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198
        +.byte	25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209
        +.byte	73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59
        +.byte	217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95
        +.byte	242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49
        +.byte	227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168
        +.byte	91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185
        +.byte	136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188
        +.byte	154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62
        +.byte	38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11
        +.byte	50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191
        +.byte	176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89
        +.byte	233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242
        +.byte	15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119
        +.byte	213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51
        +.byte	128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244
        +.byte	190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39
        +.byte	205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235
        +.byte	52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137
        +.byte	72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50
        +.byte	255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84
        +.byte	122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141
        +.byte	144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100
        +.byte	95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157
        +.byte	32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61
        +.byte	104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15
        +.byte	26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202
        +.byte	174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183
        +.byte	180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125
        +.byte	84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206
        +.byte	147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127
        +.byte	34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47
        +.byte	100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99
        +.byte	241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42
        +.byte	115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204
        +.byte	18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130
        +.byte	64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122
        +.byte	8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72
        +.byte	195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149
        +.byte	236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223
        +.byte	219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77
        +.byte	161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192
        +.byte	141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145
        +.byte	61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200
        +.byte	151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91
        +.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        +.byte	207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249
        +.byte	43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110
        +.byte	118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225
        +.byte	130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230
        +.byte	214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40
        +.byte	27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195
        +.byte	181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116
        +.byte	175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190
        +.byte	106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29
        +.byte	80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234
        +.byte	69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87
        +.byte	243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56
        +.byte	48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173
        +.byte	239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196
        +.byte	63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218
        +.byte	85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199
        +.byte	162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219
        +.byte	234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233
        +.byte	101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106
        +.byte	186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3
        +.byte	47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74
        +.byte	192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142
        +.byte	222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96
        +.byte	28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252
        +.byte	253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70
        +.byte	77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31
        +.byte	146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118
        +.byte	117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250
        +.byte	6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54
        +.byte	138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174
        +.byte	178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75
        +.byte	230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133
        +.byte	14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126
        +.byte	31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231
        +.byte	98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85
        +.byte	212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58
        +.byte	168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129
        +.byte	150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82
        +.byte	249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98
        +.byte	197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163
        +.byte	37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16
        +.byte	89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171
        +.byte	132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208
        +.byte	114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197
        +.byte	57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236
        +.byte	76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22
        +.byte	94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148
        +.byte	120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159
        +.byte	56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229
        +.byte	140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152
        +.byte	209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23
        +.byte	165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228
        +.byte	226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161
        +.byte	97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78
        +.byte	179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66
        +.byte	33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52
        +.byte	156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8
        +.byte	30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238
        +.byte	67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97
        +.byte	199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177
        +.byte	252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79
        +.byte	4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36
        +.byte	81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227
        +.byte	153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37
        +.byte	109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34
        +.byte	13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101
        +.byte	250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121
        +.byte	223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105
        +.byte	126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169
        +.byte	36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25
        +.byte	59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254
        +.byte	171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154
        +.byte	206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240
        +.byte	17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153
        +.byte	143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131
        +.byte	78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4
        +.byte	183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102
        +.byte	235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224
        +.byte	60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193
        +.byte	129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253
        +.byte	148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64
        +.byte	247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28
        +.byte	185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24
        +.byte	19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139
        +.byte	44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81
        +.byte	211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5
        +.byte	231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140
        +.byte	110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57
        +.byte	196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170
        +.byte	3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27
        +.byte	86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220
        +.byte	68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94
        +.byte	127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160
        +.byte	169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136
        +.byte	42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103
        +.byte	187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10
        +.byte	193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135
        +.byte	83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241
        +.byte	220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114
        +.byte	11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83
        +.byte	157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1
        +.byte	108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43
        +.byte	49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164
        +.byte	116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243
        +.byte	246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21
        +.byte	70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76
        +.byte	172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165
        +.byte	137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181
        +.byte	20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180
        +.byte	225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186
        +.byte	22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166
        +.byte	58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247
        +.byte	105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6
        +.byte	9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65
        +.byte	112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215
        +.byte	182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111
        +.byte	208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30
        +.byte	237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214
        +.byte	204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226
        +.byte	66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104
        +.byte	152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44
        +.byte	164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237
        +.byte	40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117
        +.byte	92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134
        +.byte	248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107
        +.byte	134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194
        +.byte	24,35,198,232,135,184,1,79
        +.byte	54,166,210,245,121,111,145,82
        +.byte	96,188,155,142,163,12,123,53
        +.byte	29,224,215,194,46,75,254,87
        +.byte	21,119,55,229,159,240,74,218
        +.byte	88,201,41,10,177,160,107,133
        +.byte	189,93,16,244,203,62,5,103
        +.byte	228,39,65,139,167,125,149,216
        +.byte	251,238,124,102,221,23,71,158
        +.byte	202,45,191,7,173,90,131,51
        diff --git a/vendor/openssl/asm/x64-elf-gas/x86_64cpuid.s b/vendor/openssl/asm/x64-elf-gas/x86_64cpuid.s
        new file mode 100644
        index 000000000..e0a828708
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-elf-gas/x86_64cpuid.s
        @@ -0,0 +1,238 @@
        +
        +.hidden	OPENSSL_cpuid_setup
        +.section	.init
        +	call	OPENSSL_cpuid_setup
        +
        +.hidden	OPENSSL_ia32cap_P
        +.comm	OPENSSL_ia32cap_P,8,4
        +
        +.text
        +
        +
        +.globl	OPENSSL_atomic_add
        +.type	OPENSSL_atomic_add,@function
        +.align	16
        +OPENSSL_atomic_add:
        +	movl	(%rdi),%eax
        +.Lspin:	leaq	(%rsi,%rax,1),%r8
        +.byte	0xf0
        +
        +	cmpxchgl	%r8d,(%rdi)
        +	jne	.Lspin
        +	movl	%r8d,%eax
        +.byte	0x48,0x98
        +
        +	.byte	0xf3,0xc3
        +.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
        +
        +.globl	OPENSSL_rdtsc
        +.type	OPENSSL_rdtsc,@function
        +.align	16
        +OPENSSL_rdtsc:
        +	rdtsc
        +	shlq	$32,%rdx
        +	orq	%rdx,%rax
        +	.byte	0xf3,0xc3
        +.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
        +
        +.globl	OPENSSL_ia32_cpuid
        +.type	OPENSSL_ia32_cpuid,@function
        +.align	16
        +OPENSSL_ia32_cpuid:
        +	movq	%rbx,%r8
        +
        +	xorl	%eax,%eax
        +	cpuid
        +	movl	%eax,%r11d
        +
        +	xorl	%eax,%eax
        +	cmpl	$1970169159,%ebx
        +	setne	%al
        +	movl	%eax,%r9d
        +	cmpl	$1231384169,%edx
        +	setne	%al
        +	orl	%eax,%r9d
        +	cmpl	$1818588270,%ecx
        +	setne	%al
        +	orl	%eax,%r9d
        +	jz	.Lintel
        +
        +	cmpl	$1752462657,%ebx
        +	setne	%al
        +	movl	%eax,%r10d
        +	cmpl	$1769238117,%edx
        +	setne	%al
        +	orl	%eax,%r10d
        +	cmpl	$1145913699,%ecx
        +	setne	%al
        +	orl	%eax,%r10d
        +	jnz	.Lintel
        +
        +
        +	movl	$2147483648,%eax
        +	cpuid
        +	cmpl	$2147483649,%eax
        +	jb	.Lintel
        +	movl	%eax,%r10d
        +	movl	$2147483649,%eax
        +	cpuid
        +	orl	%ecx,%r9d
        +	andl	$2049,%r9d
        +
        +	cmpl	$2147483656,%r10d
        +	jb	.Lintel
        +
        +	movl	$2147483656,%eax
        +	cpuid
        +	movzbq	%cl,%r10
        +	incq	%r10
        +
        +	movl	$1,%eax
        +	cpuid
        +	btl	$28,%edx
        +	jnc	.Lgeneric
        +	shrl	$16,%ebx
        +	cmpb	%r10b,%bl
        +	ja	.Lgeneric
        +	andl	$4026531839,%edx
        +	jmp	.Lgeneric
        +
        +.Lintel:
        +	cmpl	$4,%r11d
        +	movl	$-1,%r10d
        +	jb	.Lnocacheinfo
        +
        +	movl	$4,%eax
        +	movl	$0,%ecx
        +	cpuid
        +	movl	%eax,%r10d
        +	shrl	$14,%r10d
        +	andl	$4095,%r10d
        +
        +.Lnocacheinfo:
        +	movl	$1,%eax
        +	cpuid
        +	andl	$3220176895,%edx
        +	cmpl	$0,%r9d
        +	jne	.Lnotintel
        +	orl	$1073741824,%edx
        +	andb	$15,%ah
        +	cmpb	$15,%ah
        +	jne	.Lnotintel
        +	orl	$1048576,%edx
        +.Lnotintel:
        +	btl	$28,%edx
        +	jnc	.Lgeneric
        +	andl	$4026531839,%edx
        +	cmpl	$0,%r10d
        +	je	.Lgeneric
        +
        +	orl	$268435456,%edx
        +	shrl	$16,%ebx
        +	cmpb	$1,%bl
        +	ja	.Lgeneric
        +	andl	$4026531839,%edx
        +.Lgeneric:
        +	andl	$2048,%r9d
        +	andl	$4294965247,%ecx
        +	orl	%ecx,%r9d
        +
        +	movl	%edx,%r10d
        +	btl	$27,%r9d
        +	jnc	.Lclear_avx
        +	xorl	%ecx,%ecx
        +.byte	0x0f,0x01,0xd0
        +
        +	andl	$6,%eax
        +	cmpl	$6,%eax
        +	je	.Ldone
        +.Lclear_avx:
        +	movl	$4026525695,%eax
        +	andl	%eax,%r9d
        +.Ldone:
        +	shlq	$32,%r9
        +	movl	%r10d,%eax
        +	movq	%r8,%rbx
        +	orq	%r9,%rax
        +	.byte	0xf3,0xc3
        +.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
        +
        +.globl	OPENSSL_cleanse
        +.type	OPENSSL_cleanse,@function
        +.align	16
        +OPENSSL_cleanse:
        +	xorq	%rax,%rax
        +	cmpq	$15,%rsi
        +	jae	.Lot
        +	cmpq	$0,%rsi
        +	je	.Lret
        +.Little:
        +	movb	%al,(%rdi)
        +	subq	$1,%rsi
        +	leaq	1(%rdi),%rdi
        +	jnz	.Little
        +.Lret:
        +	.byte	0xf3,0xc3
        +.align	16
        +.Lot:
        +	testq	$7,%rdi
        +	jz	.Laligned
        +	movb	%al,(%rdi)
        +	leaq	-1(%rsi),%rsi
        +	leaq	1(%rdi),%rdi
        +	jmp	.Lot
        +.Laligned:
        +	movq	%rax,(%rdi)
        +	leaq	-8(%rsi),%rsi
        +	testq	$-8,%rsi
        +	leaq	8(%rdi),%rdi
        +	jnz	.Laligned
        +	cmpq	$0,%rsi
        +	jne	.Little
        +	.byte	0xf3,0xc3
        +.size	OPENSSL_cleanse,.-OPENSSL_cleanse
        +.globl	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,@function
        +.align	16
        +OPENSSL_wipe_cpu:
        +	pxor	%xmm0,%xmm0
        +	pxor	%xmm1,%xmm1
        +	pxor	%xmm2,%xmm2
        +	pxor	%xmm3,%xmm3
        +	pxor	%xmm4,%xmm4
        +	pxor	%xmm5,%xmm5
        +	pxor	%xmm6,%xmm6
        +	pxor	%xmm7,%xmm7
        +	pxor	%xmm8,%xmm8
        +	pxor	%xmm9,%xmm9
        +	pxor	%xmm10,%xmm10
        +	pxor	%xmm11,%xmm11
        +	pxor	%xmm12,%xmm12
        +	pxor	%xmm13,%xmm13
        +	pxor	%xmm14,%xmm14
        +	pxor	%xmm15,%xmm15
        +	xorq	%rcx,%rcx
        +	xorq	%rdx,%rdx
        +	xorq	%rsi,%rsi
        +	xorq	%rdi,%rdi
        +	xorq	%r8,%r8
        +	xorq	%r9,%r9
        +	xorq	%r10,%r10
        +	xorq	%r11,%r11
        +	leaq	8(%rsp),%rax
        +	.byte	0xf3,0xc3
        +.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
        +.globl	OPENSSL_ia32_rdrand
        +.type	OPENSSL_ia32_rdrand,@function
        +.align	16
        +OPENSSL_ia32_rdrand:
        +	movl	$8,%ecx
        +.Loop_rdrand:
        +.byte	72,15,199,240
        +	jc	.Lbreak_rdrand
        +	loop	.Loop_rdrand
        +.Lbreak_rdrand:
        +	cmpq	$0,%rax
        +	cmoveq	%rcx,%rax
        +	.byte	0xf3,0xc3
        +.size	OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand
        diff --git a/vendor/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s
        new file mode 100644
        index 000000000..88120a189
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/aes/aes-x86_64.s
        @@ -0,0 +1,2554 @@
        +.text
        +
        +
        +.p2align	4
        +_x86_64_AES_encrypt:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +
        +	movl	240(%r15),%r13d
        +	subl	$1,%r13d
        +	jmp	L$enc_loop
        +.p2align	4
        +L$enc_loop:
        +
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movl	0(%r14,%rsi,8),%r10d
        +	movl	0(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r12d
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movzbl	%dl,%ebp
        +	xorl	3(%r14,%rsi,8),%r10d
        +	xorl	3(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r8d
        +
        +	movzbl	%dh,%esi
        +	shrl	$16,%ecx
        +	movzbl	%ah,%ebp
        +	xorl	3(%r14,%rsi,8),%r12d
        +	shrl	$16,%edx
        +	xorl	3(%r14,%rbp,8),%r8d
        +
        +	shrl	$16,%ebx
        +	leaq	16(%r15),%r15
        +	shrl	$16,%eax
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	xorl	2(%r14,%rsi,8),%r10d
        +	xorl	2(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r12d
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movzbl	%bl,%ebp
        +	xorl	1(%r14,%rsi,8),%r10d
        +	xorl	1(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r8d
        +
        +	movl	12(%r15),%edx
        +	movzbl	%bh,%edi
        +	movzbl	%ch,%ebp
        +	movl	0(%r15),%eax
        +	xorl	1(%r14,%rdi,8),%r12d
        +	xorl	1(%r14,%rbp,8),%r8d
        +
        +	movl	4(%r15),%ebx
        +	movl	8(%r15),%ecx
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +	subl	$1,%r13d
        +	jnz	L$enc_loop
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movzbl	2(%r14,%rsi,8),%r10d
        +	movzbl	2(%r14,%rdi,8),%r11d
        +	movzbl	2(%r14,%rbp,8),%r12d
        +
        +	movzbl	%dl,%esi
        +	movzbl	%bh,%edi
        +	movzbl	%ch,%ebp
        +	movzbl	2(%r14,%rsi,8),%r8d
        +	movl	0(%r14,%rdi,8),%edi
        +	movl	0(%r14,%rbp,8),%ebp
        +
        +	andl	$65280,%edi
        +	andl	$65280,%ebp
        +
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +	shrl	$16,%ecx
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	shrl	$16,%edx
        +	movl	0(%r14,%rsi,8),%esi
        +	movl	0(%r14,%rdi,8),%edi
        +
        +	andl	$65280,%esi
        +	andl	$65280,%edi
        +	shrl	$16,%ebx
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +	shrl	$16,%eax
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	movl	0(%r14,%rsi,8),%esi
        +	movl	0(%r14,%rdi,8),%edi
        +	movl	0(%r14,%rbp,8),%ebp
        +
        +	andl	$16711680,%esi
        +	andl	$16711680,%edi
        +	andl	$16711680,%ebp
        +
        +	xorl	%esi,%r10d
        +	xorl	%edi,%r11d
        +	xorl	%ebp,%r12d
        +
        +	movzbl	%bl,%esi
        +	movzbl	%dh,%edi
        +	movzbl	%ah,%ebp
        +	movl	0(%r14,%rsi,8),%esi
        +	movl	2(%r14,%rdi,8),%edi
        +	movl	2(%r14,%rbp,8),%ebp
        +
        +	andl	$16711680,%esi
        +	andl	$4278190080,%edi
        +	andl	$4278190080,%ebp
        +
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movl	16+12(%r15),%edx
        +	movl	2(%r14,%rsi,8),%esi
        +	movl	2(%r14,%rdi,8),%edi
        +	movl	16+0(%r15),%eax
        +
        +	andl	$4278190080,%esi
        +	andl	$4278190080,%edi
        +
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +
        +	movl	16+4(%r15),%ebx
        +	movl	16+8(%r15),%ecx
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +.byte	0xf3,0xc3
        +
        +
        +
        +.p2align	4
        +_x86_64_AES_encrypt_compact:
        +	leaq	128(%r14),%r8
        +	movl	0-128(%r8),%edi
        +	movl	32-128(%r8),%ebp
        +	movl	64-128(%r8),%r10d
        +	movl	96-128(%r8),%r11d
        +	movl	128-128(%r8),%edi
        +	movl	160-128(%r8),%ebp
        +	movl	192-128(%r8),%r10d
        +	movl	224-128(%r8),%r11d
        +	jmp	L$enc_loop_compact
        +.p2align	4
        +L$enc_loop_compact:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +	leaq	16(%r15),%r15
        +	movzbl	%al,%r10d
        +	movzbl	%bl,%r11d
        +	movzbl	%cl,%r12d
        +	movzbl	(%r14,%r10,1),%r10d
        +	movzbl	(%r14,%r11,1),%r11d
        +	movzbl	(%r14,%r12,1),%r12d
        +
        +	movzbl	%dl,%r8d
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movzbl	(%r14,%r8,1),%r8d
        +	movzbl	(%r14,%rsi,1),%r9d
        +	movzbl	(%r14,%rdi,1),%r13d
        +
        +	movzbl	%dh,%ebp
        +	movzbl	%ah,%esi
        +	shrl	$16,%ecx
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	shrl	$16,%edx
        +
        +	movzbl	%cl,%edi
        +	shll	$8,%r9d
        +	shll	$8,%r13d
        +	movzbl	(%r14,%rdi,1),%edi
        +	xorl	%r9d,%r10d
        +	xorl	%r13d,%r11d
        +
        +	movzbl	%dl,%r9d
        +	shrl	$16,%eax
        +	shrl	$16,%ebx
        +	movzbl	%al,%r13d
        +	shll	$8,%ebp
        +	shll	$8,%esi
        +	movzbl	(%r14,%r9,1),%r9d
        +	movzbl	(%r14,%r13,1),%r13d
        +	xorl	%ebp,%r12d
        +	xorl	%esi,%r8d
        +
        +	movzbl	%bl,%ebp
        +	movzbl	%dh,%esi
        +	shll	$16,%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	xorl	%edi,%r10d
        +
        +	movzbl	%ah,%edi
        +	shrl	$8,%ecx
        +	shrl	$8,%ebx
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rcx,1),%edx
        +	movzbl	(%r14,%rbx,1),%ecx
        +	shll	$16,%r9d
        +	shll	$16,%r13d
        +	shll	$16,%ebp
        +	xorl	%r9d,%r11d
        +	xorl	%r13d,%r12d
        +	xorl	%ebp,%r8d
        +
        +	shll	$24,%esi
        +	shll	$24,%edi
        +	shll	$24,%edx
        +	xorl	%esi,%r10d
        +	shll	$24,%ecx
        +	xorl	%edi,%r11d
        +	movl	%r10d,%eax
        +	movl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +	cmpq	16(%rsp),%r15
        +	je	L$enc_compact_done
        +	movl	%eax,%esi
        +	movl	%ebx,%edi
        +	andl	$2155905152,%esi
        +	andl	$2155905152,%edi
        +	movl	%esi,%r10d
        +	movl	%edi,%r11d
        +	shrl	$7,%r10d
        +	leal	(%rax,%rax,1),%r8d
        +	shrl	$7,%r11d
        +	leal	(%rbx,%rbx,1),%r9d
        +	subl	%r10d,%esi
        +	subl	%r11d,%edi
        +	andl	$4278124286,%r8d
        +	andl	$4278124286,%r9d
        +	andl	$454761243,%esi
        +	andl	$454761243,%edi
        +	movl	%eax,%r10d
        +	movl	%ebx,%r11d
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r9d
        +
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movl	%ecx,%esi
        +	movl	%edx,%edi
        +	roll	$24,%eax
        +	roll	$24,%ebx
        +	andl	$2155905152,%esi
        +	andl	$2155905152,%edi
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movl	%esi,%r12d
        +	movl	%edi,%ebp
        +	rorl	$16,%r10d
        +	rorl	$16,%r11d
        +	shrl	$7,%r12d
        +	leal	(%rcx,%rcx,1),%r8d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	shrl	$7,%ebp
        +	leal	(%rdx,%rdx,1),%r9d
        +	rorl	$8,%r10d
        +	rorl	$8,%r11d
        +	subl	%r12d,%esi
        +	subl	%ebp,%edi
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +
        +	andl	$4278124286,%r8d
        +	andl	$4278124286,%r9d
        +	andl	$454761243,%esi
        +	andl	$454761243,%edi
        +	movl	%ecx,%r12d
        +	movl	%edx,%ebp
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r9d
        +
        +	xorl	%r8d,%ecx
        +	xorl	%r9d,%edx
        +	roll	$24,%ecx
        +	roll	$24,%edx
        +	xorl	%r8d,%ecx
        +	xorl	%r9d,%edx
        +	movl	0(%r14),%esi
        +	rorl	$16,%r12d
        +	rorl	$16,%ebp
        +	movl	64(%r14),%edi
        +	xorl	%r12d,%ecx
        +	xorl	%ebp,%edx
        +	movl	128(%r14),%r8d
        +	rorl	$8,%r12d
        +	rorl	$8,%ebp
        +	movl	192(%r14),%r9d
        +	xorl	%r12d,%ecx
        +	xorl	%ebp,%edx
        +	jmp	L$enc_loop_compact
        +.p2align	4
        +L$enc_compact_done:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +.byte	0xf3,0xc3
        +
        +
        +.globl	_AES_encrypt
        +
        +.p2align	4
        +.globl	_asm_AES_encrypt
        +.private_extern	_asm_AES_encrypt
        +_asm_AES_encrypt:
        +_AES_encrypt:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +
        +	movq	%rsp,%r10
        +	leaq	-63(%rdx),%rcx
        +	andq	$-64,%rsp
        +	subq	%rsp,%rcx
        +	negq	%rcx
        +	andq	$960,%rcx
        +	subq	%rcx,%rsp
        +	subq	$32,%rsp
        +
        +	movq	%rsi,16(%rsp)
        +	movq	%r10,24(%rsp)
        +L$enc_prologue:
        +
        +	movq	%rdx,%r15
        +	movl	240(%r15),%r13d
        +
        +	movl	0(%rdi),%eax
        +	movl	4(%rdi),%ebx
        +	movl	8(%rdi),%ecx
        +	movl	12(%rdi),%edx
        +
        +	shll	$4,%r13d
        +	leaq	(%r15,%r13,1),%rbp
        +	movq	%r15,(%rsp)
        +	movq	%rbp,8(%rsp)
        +
        +
        +	leaq	L$AES_Te+2048(%rip),%r14
        +	leaq	768(%rsp),%rbp
        +	subq	%r14,%rbp
        +	andq	$768,%rbp
        +	leaq	(%r14,%rbp,1),%r14
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	movq	16(%rsp),%r9
        +	movq	24(%rsp),%rsi
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$enc_epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_x86_64_AES_decrypt:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +
        +	movl	240(%r15),%r13d
        +	subl	$1,%r13d
        +	jmp	L$dec_loop
        +.p2align	4
        +L$dec_loop:
        +
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movl	0(%r14,%rsi,8),%r10d
        +	movl	0(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r12d
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movzbl	%dl,%ebp
        +	xorl	3(%r14,%rsi,8),%r10d
        +	xorl	3(%r14,%rdi,8),%r11d
        +	movl	0(%r14,%rbp,8),%r8d
        +
        +	movzbl	%bh,%esi
        +	shrl	$16,%eax
        +	movzbl	%ch,%ebp
        +	xorl	3(%r14,%rsi,8),%r12d
        +	shrl	$16,%edx
        +	xorl	3(%r14,%rbp,8),%r8d
        +
        +	shrl	$16,%ebx
        +	leaq	16(%r15),%r15
        +	shrl	$16,%ecx
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	xorl	2(%r14,%rsi,8),%r10d
        +	xorl	2(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r12d
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	movzbl	%bl,%ebp
        +	xorl	1(%r14,%rsi,8),%r10d
        +	xorl	1(%r14,%rdi,8),%r11d
        +	xorl	2(%r14,%rbp,8),%r8d
        +
        +	movzbl	%dh,%esi
        +	movl	12(%r15),%edx
        +	movzbl	%ah,%ebp
        +	xorl	1(%r14,%rsi,8),%r12d
        +	movl	0(%r15),%eax
        +	xorl	1(%r14,%rbp,8),%r8d
        +
        +	xorl	%r10d,%eax
        +	movl	4(%r15),%ebx
        +	movl	8(%r15),%ecx
        +	xorl	%r12d,%ecx
        +	xorl	%r11d,%ebx
        +	xorl	%r8d,%edx
        +	subl	$1,%r13d
        +	jnz	L$dec_loop
        +	leaq	2048(%r14),%r14
        +	movzbl	%al,%esi
        +	movzbl	%bl,%edi
        +	movzbl	%cl,%ebp
        +	movzbl	(%r14,%rsi,1),%r10d
        +	movzbl	(%r14,%rdi,1),%r11d
        +	movzbl	(%r14,%rbp,1),%r12d
        +
        +	movzbl	%dl,%esi
        +	movzbl	%dh,%edi
        +	movzbl	%ah,%ebp
        +	movzbl	(%r14,%rsi,1),%r8d
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +
        +	shll	$8,%edi
        +	shll	$8,%ebp
        +
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +	shrl	$16,%edx
        +
        +	movzbl	%bh,%esi
        +	movzbl	%ch,%edi
        +	shrl	$16,%eax
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +
        +	shll	$8,%esi
        +	shll	$8,%edi
        +	shrl	$16,%ebx
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +	shrl	$16,%ecx
        +
        +	movzbl	%cl,%esi
        +	movzbl	%dl,%edi
        +	movzbl	%al,%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +
        +	shll	$16,%esi
        +	shll	$16,%edi
        +	shll	$16,%ebp
        +
        +	xorl	%esi,%r10d
        +	xorl	%edi,%r11d
        +	xorl	%ebp,%r12d
        +
        +	movzbl	%bl,%esi
        +	movzbl	%bh,%edi
        +	movzbl	%ch,%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +
        +	shll	$16,%esi
        +	shll	$24,%edi
        +	shll	$24,%ebp
        +
        +	xorl	%esi,%r8d
        +	xorl	%edi,%r10d
        +	xorl	%ebp,%r11d
        +
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movl	16+12(%r15),%edx
        +	movzbl	(%r14,%rsi,1),%esi
        +	movzbl	(%r14,%rdi,1),%edi
        +	movl	16+0(%r15),%eax
        +
        +	shll	$24,%esi
        +	shll	$24,%edi
        +
        +	xorl	%esi,%r12d
        +	xorl	%edi,%r8d
        +
        +	movl	16+4(%r15),%ebx
        +	movl	16+8(%r15),%ecx
        +	leaq	-2048(%r14),%r14
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +.byte	0xf3,0xc3
        +
        +
        +
        +.p2align	4
        +_x86_64_AES_decrypt_compact:
        +	leaq	128(%r14),%r8
        +	movl	0-128(%r8),%edi
        +	movl	32-128(%r8),%ebp
        +	movl	64-128(%r8),%r10d
        +	movl	96-128(%r8),%r11d
        +	movl	128-128(%r8),%edi
        +	movl	160-128(%r8),%ebp
        +	movl	192-128(%r8),%r10d
        +	movl	224-128(%r8),%r11d
        +	jmp	L$dec_loop_compact
        +
        +.p2align	4
        +L$dec_loop_compact:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +	leaq	16(%r15),%r15
        +	movzbl	%al,%r10d
        +	movzbl	%bl,%r11d
        +	movzbl	%cl,%r12d
        +	movzbl	(%r14,%r10,1),%r10d
        +	movzbl	(%r14,%r11,1),%r11d
        +	movzbl	(%r14,%r12,1),%r12d
        +
        +	movzbl	%dl,%r8d
        +	movzbl	%dh,%esi
        +	movzbl	%ah,%edi
        +	movzbl	(%r14,%r8,1),%r8d
        +	movzbl	(%r14,%rsi,1),%r9d
        +	movzbl	(%r14,%rdi,1),%r13d
        +
        +	movzbl	%bh,%ebp
        +	movzbl	%ch,%esi
        +	shrl	$16,%ecx
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	shrl	$16,%edx
        +
        +	movzbl	%cl,%edi
        +	shll	$8,%r9d
        +	shll	$8,%r13d
        +	movzbl	(%r14,%rdi,1),%edi
        +	xorl	%r9d,%r10d
        +	xorl	%r13d,%r11d
        +
        +	movzbl	%dl,%r9d
        +	shrl	$16,%eax
        +	shrl	$16,%ebx
        +	movzbl	%al,%r13d
        +	shll	$8,%ebp
        +	shll	$8,%esi
        +	movzbl	(%r14,%r9,1),%r9d
        +	movzbl	(%r14,%r13,1),%r13d
        +	xorl	%ebp,%r12d
        +	xorl	%esi,%r8d
        +
        +	movzbl	%bl,%ebp
        +	movzbl	%bh,%esi
        +	shll	$16,%edi
        +	movzbl	(%r14,%rbp,1),%ebp
        +	movzbl	(%r14,%rsi,1),%esi
        +	xorl	%edi,%r10d
        +
        +	movzbl	%ch,%edi
        +	shll	$16,%r9d
        +	shll	$16,%r13d
        +	movzbl	(%r14,%rdi,1),%ebx
        +	xorl	%r9d,%r11d
        +	xorl	%r13d,%r12d
        +
        +	movzbl	%dh,%edi
        +	shrl	$8,%eax
        +	shll	$16,%ebp
        +	movzbl	(%r14,%rdi,1),%ecx
        +	movzbl	(%r14,%rax,1),%edx
        +	xorl	%ebp,%r8d
        +
        +	shll	$24,%esi
        +	shll	$24,%ebx
        +	shll	$24,%ecx
        +	xorl	%esi,%r10d
        +	shll	$24,%edx
        +	xorl	%r11d,%ebx
        +	movl	%r10d,%eax
        +	xorl	%r12d,%ecx
        +	xorl	%r8d,%edx
        +	cmpq	16(%rsp),%r15
        +	je	L$dec_compact_done
        +
        +	movq	256+0(%r14),%rsi
        +	shlq	$32,%rbx
        +	shlq	$32,%rdx
        +	movq	256+8(%r14),%rdi
        +	orq	%rbx,%rax
        +	orq	%rdx,%rcx
        +	movq	256+16(%r14),%rbp
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +	shrq	$7,%r9
        +	leaq	(%rax,%rax,1),%r8
        +	shrq	$7,%r12
        +	leaq	(%rcx,%rcx,1),%r11
        +	subq	%r9,%rbx
        +	subq	%r12,%rdx
        +	andq	%rdi,%r8
        +	andq	%rdi,%r11
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r8,%rbx
        +	xorq	%r11,%rdx
        +	movq	%rbx,%r8
        +	movq	%rdx,%r11
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	leaq	(%r8,%r8,1),%r9
        +	shrq	$7,%r13
        +	leaq	(%r11,%r11,1),%r12
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	andq	%rdi,%r9
        +	andq	%rdi,%r12
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r9,%rbx
        +	xorq	%r12,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	xorq	%rax,%r8
        +	shrq	$7,%r13
        +	xorq	%rcx,%r11
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	leaq	(%r9,%r9,1),%r10
        +	leaq	(%r12,%r12,1),%r13
        +	xorq	%rax,%r9
        +	xorq	%rcx,%r12
        +	andq	%rdi,%r10
        +	andq	%rdi,%r13
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%rbx,%r10
        +	xorq	%rdx,%r13
        +
        +	xorq	%r10,%rax
        +	xorq	%r13,%rcx
        +	xorq	%r10,%r8
        +	xorq	%r13,%r11
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	xorq	%r10,%r9
        +	xorq	%r13,%r12
        +	shrq	$32,%rbx
        +	shrq	$32,%rdx
        +	xorq	%r8,%r10
        +	xorq	%r11,%r13
        +	roll	$8,%eax
        +	roll	$8,%ecx
        +	xorq	%r9,%r10
        +	xorq	%r12,%r13
        +
        +	roll	$8,%ebx
        +	roll	$8,%edx
        +	xorl	%r10d,%eax
        +	xorl	%r13d,%ecx
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +	movq	%r8,%r10
        +	movq	%r11,%r13
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	roll	$24,%r8d
        +	roll	$24,%r11d
        +	roll	$24,%r10d
        +	roll	$24,%r13d
        +	xorl	%r8d,%eax
        +	xorl	%r11d,%ecx
        +	movq	%r9,%r8
        +	movq	%r12,%r11
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +	movq	0(%r14),%rsi
        +	shrq	$32,%r8
        +	shrq	$32,%r11
        +	movq	64(%r14),%rdi
        +	roll	$16,%r9d
        +	roll	$16,%r12d
        +	movq	128(%r14),%rbp
        +	roll	$16,%r8d
        +	roll	$16,%r11d
        +	movq	192(%r14),%r10
        +	xorl	%r9d,%eax
        +	xorl	%r12d,%ecx
        +	movq	256(%r14),%r13
        +	xorl	%r8d,%ebx
        +	xorl	%r11d,%edx
        +	jmp	L$dec_loop_compact
        +.p2align	4
        +L$dec_compact_done:
        +	xorl	0(%r15),%eax
        +	xorl	4(%r15),%ebx
        +	xorl	8(%r15),%ecx
        +	xorl	12(%r15),%edx
        +.byte	0xf3,0xc3
        +
        +
        +.globl	_AES_decrypt
        +
        +.p2align	4
        +.globl	_asm_AES_decrypt
        +.private_extern	_asm_AES_decrypt
        +_asm_AES_decrypt:
        +_AES_decrypt:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +
        +	movq	%rsp,%r10
        +	leaq	-63(%rdx),%rcx
        +	andq	$-64,%rsp
        +	subq	%rsp,%rcx
        +	negq	%rcx
        +	andq	$960,%rcx
        +	subq	%rcx,%rsp
        +	subq	$32,%rsp
        +
        +	movq	%rsi,16(%rsp)
        +	movq	%r10,24(%rsp)
        +L$dec_prologue:
        +
        +	movq	%rdx,%r15
        +	movl	240(%r15),%r13d
        +
        +	movl	0(%rdi),%eax
        +	movl	4(%rdi),%ebx
        +	movl	8(%rdi),%ecx
        +	movl	12(%rdi),%edx
        +
        +	shll	$4,%r13d
        +	leaq	(%r15,%r13,1),%rbp
        +	movq	%r15,(%rsp)
        +	movq	%rbp,8(%rsp)
        +
        +
        +	leaq	L$AES_Td+2048(%rip),%r14
        +	leaq	768(%rsp),%rbp
        +	subq	%r14,%rbp
        +	andq	$768,%rbp
        +	leaq	(%r14,%rbp,1),%r14
        +	shrq	$3,%rbp
        +	addq	%rbp,%r14
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	movq	16(%rsp),%r9
        +	movq	24(%rsp),%rsi
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$dec_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.globl	_private_AES_set_encrypt_key
        +
        +.p2align	4
        +_private_AES_set_encrypt_key:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	subq	$8,%rsp
        +L$enc_key_prologue:
        +
        +	call	_x86_64_AES_set_encrypt_key
        +
        +	movq	8(%rsp),%r15
        +	movq	16(%rsp),%r14
        +	movq	24(%rsp),%r13
        +	movq	32(%rsp),%r12
        +	movq	40(%rsp),%rbp
        +	movq	48(%rsp),%rbx
        +	addq	$56,%rsp
        +L$enc_key_epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +
        +.p2align	4
        +_x86_64_AES_set_encrypt_key:
        +	movl	%esi,%ecx
        +	movq	%rdi,%rsi
        +	movq	%rdx,%rdi
        +
        +	testq	$-1,%rsi
        +	jz	L$badpointer
        +	testq	$-1,%rdi
        +	jz	L$badpointer
        +
        +	leaq	L$AES_Te(%rip),%rbp
        +	leaq	2048+128(%rbp),%rbp
        +
        +
        +	movl	0-128(%rbp),%eax
        +	movl	32-128(%rbp),%ebx
        +	movl	64-128(%rbp),%r8d
        +	movl	96-128(%rbp),%edx
        +	movl	128-128(%rbp),%eax
        +	movl	160-128(%rbp),%ebx
        +	movl	192-128(%rbp),%r8d
        +	movl	224-128(%rbp),%edx
        +
        +	cmpl	$128,%ecx
        +	je	L$10rounds
        +	cmpl	$192,%ecx
        +	je	L$12rounds
        +	cmpl	$256,%ecx
        +	je	L$14rounds
        +	movq	$-2,%rax
        +	jmp	L$exit
        +
        +L$10rounds:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rdx,8(%rdi)
        +
        +	shrq	$32,%rdx
        +	xorl	%ecx,%ecx
        +	jmp	L$10shortcut
        +.p2align	2
        +L$10loop:
        +	movl	0(%rdi),%eax
        +	movl	12(%rdi),%edx
        +L$10shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	xorl	1024-128(%rbp,%rcx,4),%eax
        +	movl	%eax,16(%rdi)
        +	xorl	4(%rdi),%eax
        +	movl	%eax,20(%rdi)
        +	xorl	8(%rdi),%eax
        +	movl	%eax,24(%rdi)
        +	xorl	12(%rdi),%eax
        +	movl	%eax,28(%rdi)
        +	addl	$1,%ecx
        +	leaq	16(%rdi),%rdi
        +	cmpl	$10,%ecx
        +	jl	L$10loop
        +
        +	movl	$10,80(%rdi)
        +	xorq	%rax,%rax
        +	jmp	L$exit
        +
        +L$12rounds:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	16(%rsi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rbx,8(%rdi)
        +	movq	%rdx,16(%rdi)
        +
        +	shrq	$32,%rdx
        +	xorl	%ecx,%ecx
        +	jmp	L$12shortcut
        +.p2align	2
        +L$12loop:
        +	movl	0(%rdi),%eax
        +	movl	20(%rdi),%edx
        +L$12shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	xorl	1024-128(%rbp,%rcx,4),%eax
        +	movl	%eax,24(%rdi)
        +	xorl	4(%rdi),%eax
        +	movl	%eax,28(%rdi)
        +	xorl	8(%rdi),%eax
        +	movl	%eax,32(%rdi)
        +	xorl	12(%rdi),%eax
        +	movl	%eax,36(%rdi)
        +
        +	cmpl	$7,%ecx
        +	je	L$12break
        +	addl	$1,%ecx
        +
        +	xorl	16(%rdi),%eax
        +	movl	%eax,40(%rdi)
        +	xorl	20(%rdi),%eax
        +	movl	%eax,44(%rdi)
        +
        +	leaq	24(%rdi),%rdi
        +	jmp	L$12loop
        +L$12break:
        +	movl	$12,72(%rdi)
        +	xorq	%rax,%rax
        +	jmp	L$exit
        +
        +L$14rounds:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	16(%rsi),%rcx
        +	movq	24(%rsi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rbx,8(%rdi)
        +	movq	%rcx,16(%rdi)
        +	movq	%rdx,24(%rdi)
        +
        +	shrq	$32,%rdx
        +	xorl	%ecx,%ecx
        +	jmp	L$14shortcut
        +.p2align	2
        +L$14loop:
        +	movl	0(%rdi),%eax
        +	movl	28(%rdi),%edx
        +L$14shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	xorl	1024-128(%rbp,%rcx,4),%eax
        +	movl	%eax,32(%rdi)
        +	xorl	4(%rdi),%eax
        +	movl	%eax,36(%rdi)
        +	xorl	8(%rdi),%eax
        +	movl	%eax,40(%rdi)
        +	xorl	12(%rdi),%eax
        +	movl	%eax,44(%rdi)
        +
        +	cmpl	$6,%ecx
        +	je	L$14break
        +	addl	$1,%ecx
        +
        +	movl	%eax,%edx
        +	movl	16(%rdi),%eax
        +	movzbl	%dl,%esi
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shrl	$16,%edx
        +	shll	$8,%ebx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +
        +	movzbl	-128(%rbp,%rsi,1),%ebx
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +
        +	movl	%eax,48(%rdi)
        +	xorl	20(%rdi),%eax
        +	movl	%eax,52(%rdi)
        +	xorl	24(%rdi),%eax
        +	movl	%eax,56(%rdi)
        +	xorl	28(%rdi),%eax
        +	movl	%eax,60(%rdi)
        +
        +	leaq	32(%rdi),%rdi
        +	jmp	L$14loop
        +L$14break:
        +	movl	$14,48(%rdi)
        +	xorq	%rax,%rax
        +	jmp	L$exit
        +
        +L$badpointer:
        +	movq	$-1,%rax
        +L$exit:
        +.byte	0xf3,0xc3
        +
        +
        +.globl	_private_AES_set_decrypt_key
        +
        +.p2align	4
        +_private_AES_set_decrypt_key:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	pushq	%rdx
        +L$dec_key_prologue:
        +
        +	call	_x86_64_AES_set_encrypt_key
        +	movq	(%rsp),%r8
        +	cmpl	$0,%eax
        +	jne	L$abort
        +
        +	movl	240(%r8),%r14d
        +	xorq	%rdi,%rdi
        +	leaq	(%rdi,%r14,4),%rcx
        +	movq	%r8,%rsi
        +	leaq	(%r8,%rcx,4),%rdi
        +.p2align	2
        +L$invert:
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	0(%rdi),%rcx
        +	movq	8(%rdi),%rdx
        +	movq	%rax,0(%rdi)
        +	movq	%rbx,8(%rdi)
        +	movq	%rcx,0(%rsi)
        +	movq	%rdx,8(%rsi)
        +	leaq	16(%rsi),%rsi
        +	leaq	-16(%rdi),%rdi
        +	cmpq	%rsi,%rdi
        +	jne	L$invert
        +
        +	leaq	L$AES_Te+2048+1024(%rip),%rax
        +
        +	movq	40(%rax),%rsi
        +	movq	48(%rax),%rdi
        +	movq	56(%rax),%rbp
        +
        +	movq	%r8,%r15
        +	subl	$1,%r14d
        +.p2align	2
        +L$permute:
        +	leaq	16(%r15),%r15
        +	movq	0(%r15),%rax
        +	movq	8(%r15),%rcx
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +	shrq	$7,%r9
        +	leaq	(%rax,%rax,1),%r8
        +	shrq	$7,%r12
        +	leaq	(%rcx,%rcx,1),%r11
        +	subq	%r9,%rbx
        +	subq	%r12,%rdx
        +	andq	%rdi,%r8
        +	andq	%rdi,%r11
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r8,%rbx
        +	xorq	%r11,%rdx
        +	movq	%rbx,%r8
        +	movq	%rdx,%r11
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	leaq	(%r8,%r8,1),%r9
        +	shrq	$7,%r13
        +	leaq	(%r11,%r11,1),%r12
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	andq	%rdi,%r9
        +	andq	%rdi,%r12
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%r9,%rbx
        +	xorq	%r12,%rdx
        +	movq	%rbx,%r9
        +	movq	%rdx,%r12
        +
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdx
        +	movq	%rbx,%r10
        +	movq	%rdx,%r13
        +	shrq	$7,%r10
        +	xorq	%rax,%r8
        +	shrq	$7,%r13
        +	xorq	%rcx,%r11
        +	subq	%r10,%rbx
        +	subq	%r13,%rdx
        +	leaq	(%r9,%r9,1),%r10
        +	leaq	(%r12,%r12,1),%r13
        +	xorq	%rax,%r9
        +	xorq	%rcx,%r12
        +	andq	%rdi,%r10
        +	andq	%rdi,%r13
        +	andq	%rbp,%rbx
        +	andq	%rbp,%rdx
        +	xorq	%rbx,%r10
        +	xorq	%rdx,%r13
        +
        +	xorq	%r10,%rax
        +	xorq	%r13,%rcx
        +	xorq	%r10,%r8
        +	xorq	%r13,%r11
        +	movq	%rax,%rbx
        +	movq	%rcx,%rdx
        +	xorq	%r10,%r9
        +	xorq	%r13,%r12
        +	shrq	$32,%rbx
        +	shrq	$32,%rdx
        +	xorq	%r8,%r10
        +	xorq	%r11,%r13
        +	roll	$8,%eax
        +	roll	$8,%ecx
        +	xorq	%r9,%r10
        +	xorq	%r12,%r13
        +
        +	roll	$8,%ebx
        +	roll	$8,%edx
        +	xorl	%r10d,%eax
        +	xorl	%r13d,%ecx
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +	movq	%r8,%r10
        +	movq	%r11,%r13
        +	shrq	$32,%r10
        +	shrq	$32,%r13
        +	roll	$24,%r8d
        +	roll	$24,%r11d
        +	roll	$24,%r10d
        +	roll	$24,%r13d
        +	xorl	%r8d,%eax
        +	xorl	%r11d,%ecx
        +	movq	%r9,%r8
        +	movq	%r12,%r11
        +	xorl	%r10d,%ebx
        +	xorl	%r13d,%edx
        +
        +
        +	shrq	$32,%r8
        +	shrq	$32,%r11
        +
        +	roll	$16,%r9d
        +	roll	$16,%r12d
        +
        +	roll	$16,%r8d
        +	roll	$16,%r11d
        +
        +	xorl	%r9d,%eax
        +	xorl	%r12d,%ecx
        +
        +	xorl	%r8d,%ebx
        +	xorl	%r11d,%edx
        +	movl	%eax,0(%r15)
        +	movl	%ebx,4(%r15)
        +	movl	%ecx,8(%r15)
        +	movl	%edx,12(%r15)
        +	subl	$1,%r14d
        +	jnz	L$permute
        +
        +	xorq	%rax,%rax
        +L$abort:
        +	movq	8(%rsp),%r15
        +	movq	16(%rsp),%r14
        +	movq	24(%rsp),%r13
        +	movq	32(%rsp),%r12
        +	movq	40(%rsp),%rbp
        +	movq	48(%rsp),%rbx
        +	addq	$56,%rsp
        +L$dec_key_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.globl	_AES_cbc_encrypt
        +
        +.p2align	4
        +
        +.globl	_asm_AES_cbc_encrypt
        +.private_extern	_asm_AES_cbc_encrypt
        +_asm_AES_cbc_encrypt:
        +_AES_cbc_encrypt:
        +	cmpq	$0,%rdx
        +	je	L$cbc_epilogue
        +	pushfq
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +L$cbc_prologue:
        +
        +	cld
        +	movl	%r9d,%r9d
        +
        +	leaq	L$AES_Te(%rip),%r14
        +	cmpq	$0,%r9
        +	jne	L$cbc_picked_te
        +	leaq	L$AES_Td(%rip),%r14
        +L$cbc_picked_te:
        +
        +	movl	_OPENSSL_ia32cap_P(%rip),%r10d
        +	cmpq	$512,%rdx
        +	jb	L$cbc_slow_prologue
        +	testq	$15,%rdx
        +	jnz	L$cbc_slow_prologue
        +
        +
        +
        +
        +	leaq	-88-248(%rsp),%r15
        +	andq	$-64,%r15
        +
        +
        +	movq	%r14,%r10
        +	leaq	2304(%r14),%r11
        +	movq	%r15,%r12
        +	andq	$4095,%r10
        +	andq	$4095,%r11
        +	andq	$4095,%r12
        +
        +	cmpq	%r11,%r12
        +	jb	L$cbc_te_break_out
        +	subq	%r11,%r12
        +	subq	%r12,%r15
        +	jmp	L$cbc_te_ok
        +L$cbc_te_break_out:
        +	subq	%r10,%r12
        +	andq	$4095,%r12
        +	addq	$320,%r12
        +	subq	%r12,%r15
        +.p2align	2
        +L$cbc_te_ok:
        +
        +	xchgq	%rsp,%r15
        +
        +	movq	%r15,16(%rsp)
        +L$cbc_fast_body:
        +	movq	%rdi,24(%rsp)
        +	movq	%rsi,32(%rsp)
        +	movq	%rdx,40(%rsp)
        +	movq	%rcx,48(%rsp)
        +	movq	%r8,56(%rsp)
        +	movl	$0,80+240(%rsp)
        +	movq	%r8,%rbp
        +	movq	%r9,%rbx
        +	movq	%rsi,%r9
        +	movq	%rdi,%r8
        +	movq	%rcx,%r15
        +
        +	movl	240(%r15),%eax
        +
        +	movq	%r15,%r10
        +	subq	%r14,%r10
        +	andq	$4095,%r10
        +	cmpq	$2304,%r10
        +	jb	L$cbc_do_ecopy
        +	cmpq	$4096-248,%r10
        +	jb	L$cbc_skip_ecopy
        +.p2align	2
        +L$cbc_do_ecopy:
        +	movq	%r15,%rsi
        +	leaq	80(%rsp),%rdi
        +	leaq	80(%rsp),%r15
        +	movl	$30,%ecx
        +.long	0x90A548F3
        +
        +	movl	%eax,(%rdi)
        +L$cbc_skip_ecopy:
        +	movq	%r15,0(%rsp)
        +
        +	movl	$18,%ecx
        +.p2align	2
        +L$cbc_prefetch_te:
        +	movq	0(%r14),%r10
        +	movq	32(%r14),%r11
        +	movq	64(%r14),%r12
        +	movq	96(%r14),%r13
        +	leaq	128(%r14),%r14
        +	subl	$1,%ecx
        +	jnz	L$cbc_prefetch_te
        +	leaq	-2304(%r14),%r14
        +
        +	cmpq	$0,%rbx
        +	je	L$FAST_DECRYPT
        +
        +
        +	movl	0(%rbp),%eax
        +	movl	4(%rbp),%ebx
        +	movl	8(%rbp),%ecx
        +	movl	12(%rbp),%edx
        +
        +.p2align	2
        +L$cbc_fast_enc_loop:
        +	xorl	0(%r8),%eax
        +	xorl	4(%r8),%ebx
        +	xorl	8(%r8),%ecx
        +	xorl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +
        +	call	_x86_64_AES_encrypt
        +
        +	movq	24(%rsp),%r8
        +	movq	40(%rsp),%r10
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	subq	$16,%r10
        +	testq	$-16,%r10
        +	movq	%r10,40(%rsp)
        +	jnz	L$cbc_fast_enc_loop
        +	movq	56(%rsp),%rbp
        +	movl	%eax,0(%rbp)
        +	movl	%ebx,4(%rbp)
        +	movl	%ecx,8(%rbp)
        +	movl	%edx,12(%rbp)
        +
        +	jmp	L$cbc_fast_cleanup
        +
        +
        +.p2align	4
        +L$FAST_DECRYPT:
        +	cmpq	%r8,%r9
        +	je	L$cbc_fast_dec_in_place
        +
        +	movq	%rbp,64(%rsp)
        +.p2align	2
        +L$cbc_fast_dec_loop:
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +
        +	call	_x86_64_AES_decrypt
        +
        +	movq	64(%rsp),%rbp
        +	movq	24(%rsp),%r8
        +	movq	40(%rsp),%r10
        +	xorl	0(%rbp),%eax
        +	xorl	4(%rbp),%ebx
        +	xorl	8(%rbp),%ecx
        +	xorl	12(%rbp),%edx
        +	movq	%r8,%rbp
        +
        +	subq	$16,%r10
        +	movq	%r10,40(%rsp)
        +	movq	%rbp,64(%rsp)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	jnz	L$cbc_fast_dec_loop
        +	movq	56(%rsp),%r12
        +	movq	0(%rbp),%r10
        +	movq	8(%rbp),%r11
        +	movq	%r10,0(%r12)
        +	movq	%r11,8(%r12)
        +	jmp	L$cbc_fast_cleanup
        +
        +.p2align	4
        +L$cbc_fast_dec_in_place:
        +	movq	0(%rbp),%r10
        +	movq	8(%rbp),%r11
        +	movq	%r10,0+64(%rsp)
        +	movq	%r11,8+64(%rsp)
        +.p2align	2
        +L$cbc_fast_dec_in_place_loop:
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +
        +	call	_x86_64_AES_decrypt
        +
        +	movq	24(%rsp),%r8
        +	movq	40(%rsp),%r10
        +	xorl	0+64(%rsp),%eax
        +	xorl	4+64(%rsp),%ebx
        +	xorl	8+64(%rsp),%ecx
        +	xorl	12+64(%rsp),%edx
        +
        +	movq	0(%r8),%r11
        +	movq	8(%r8),%r12
        +	subq	$16,%r10
        +	jz	L$cbc_fast_dec_in_place_done
        +
        +	movq	%r11,0+64(%rsp)
        +	movq	%r12,8+64(%rsp)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	movq	%r10,40(%rsp)
        +	jmp	L$cbc_fast_dec_in_place_loop
        +L$cbc_fast_dec_in_place_done:
        +	movq	56(%rsp),%rdi
        +	movq	%r11,0(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +.p2align	2
        +L$cbc_fast_cleanup:
        +	cmpl	$0,80+240(%rsp)
        +	leaq	80(%rsp),%rdi
        +	je	L$cbc_exit
        +	movl	$30,%ecx
        +	xorq	%rax,%rax
        +.long	0x90AB48F3
        +
        +
        +	jmp	L$cbc_exit
        +
        +
        +.p2align	4
        +L$cbc_slow_prologue:
        +
        +	leaq	-88(%rsp),%rbp
        +	andq	$-64,%rbp
        +
        +	leaq	-88-63(%rcx),%r10
        +	subq	%rbp,%r10
        +	negq	%r10
        +	andq	$960,%r10
        +	subq	%r10,%rbp
        +
        +	xchgq	%rsp,%rbp
        +
        +	movq	%rbp,16(%rsp)
        +L$cbc_slow_body:
        +
        +
        +
        +
        +	movq	%r8,56(%rsp)
        +	movq	%r8,%rbp
        +	movq	%r9,%rbx
        +	movq	%rsi,%r9
        +	movq	%rdi,%r8
        +	movq	%rcx,%r15
        +	movq	%rdx,%r10
        +
        +	movl	240(%r15),%eax
        +	movq	%r15,0(%rsp)
        +	shll	$4,%eax
        +	leaq	(%r15,%rax,1),%rax
        +	movq	%rax,8(%rsp)
        +
        +
        +	leaq	2048(%r14),%r14
        +	leaq	768-8(%rsp),%rax
        +	subq	%r14,%rax
        +	andq	$768,%rax
        +	leaq	(%r14,%rax,1),%r14
        +
        +	cmpq	$0,%rbx
        +	je	L$SLOW_DECRYPT
        +
        +
        +	testq	$-16,%r10
        +	movl	0(%rbp),%eax
        +	movl	4(%rbp),%ebx
        +	movl	8(%rbp),%ecx
        +	movl	12(%rbp),%edx
        +	jz	L$cbc_slow_enc_tail
        +
        +
        +.p2align	2
        +L$cbc_slow_enc_loop:
        +	xorl	0(%r8),%eax
        +	xorl	4(%r8),%ebx
        +	xorl	8(%r8),%ecx
        +	xorl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +	movq	%r9,32(%rsp)
        +	movq	%r10,40(%rsp)
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	movq	24(%rsp),%r8
        +	movq	32(%rsp),%r9
        +	movq	40(%rsp),%r10
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	subq	$16,%r10
        +	testq	$-16,%r10
        +	jnz	L$cbc_slow_enc_loop
        +	testq	$15,%r10
        +	jnz	L$cbc_slow_enc_tail
        +	movq	56(%rsp),%rbp
        +	movl	%eax,0(%rbp)
        +	movl	%ebx,4(%rbp)
        +	movl	%ecx,8(%rbp)
        +	movl	%edx,12(%rbp)
        +
        +	jmp	L$cbc_exit
        +
        +.p2align	2
        +L$cbc_slow_enc_tail:
        +	movq	%rax,%r11
        +	movq	%rcx,%r12
        +	movq	%r10,%rcx
        +	movq	%r8,%rsi
        +	movq	%r9,%rdi
        +.long	0x9066A4F3
        +
        +	movq	$16,%rcx
        +	subq	%r10,%rcx
        +	xorq	%rax,%rax
        +.long	0x9066AAF3
        +
        +	movq	%r9,%r8
        +	movq	$16,%r10
        +	movq	%r11,%rax
        +	movq	%r12,%rcx
        +	jmp	L$cbc_slow_enc_loop
        +
        +
        +.p2align	4
        +L$SLOW_DECRYPT:
        +	shrq	$3,%rax
        +	addq	%rax,%r14
        +
        +	movq	0(%rbp),%r11
        +	movq	8(%rbp),%r12
        +	movq	%r11,0+64(%rsp)
        +	movq	%r12,8+64(%rsp)
        +
        +.p2align	2
        +L$cbc_slow_dec_loop:
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movq	0(%rsp),%r15
        +	movq	%r8,24(%rsp)
        +	movq	%r9,32(%rsp)
        +	movq	%r10,40(%rsp)
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	movq	24(%rsp),%r8
        +	movq	32(%rsp),%r9
        +	movq	40(%rsp),%r10
        +	xorl	0+64(%rsp),%eax
        +	xorl	4+64(%rsp),%ebx
        +	xorl	8+64(%rsp),%ecx
        +	xorl	12+64(%rsp),%edx
        +
        +	movq	0(%r8),%r11
        +	movq	8(%r8),%r12
        +	subq	$16,%r10
        +	jc	L$cbc_slow_dec_partial
        +	jz	L$cbc_slow_dec_done
        +
        +	movq	%r11,0+64(%rsp)
        +	movq	%r12,8+64(%rsp)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	leaq	16(%r8),%r8
        +	leaq	16(%r9),%r9
        +	jmp	L$cbc_slow_dec_loop
        +L$cbc_slow_dec_done:
        +	movq	56(%rsp),%rdi
        +	movq	%r11,0(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	movl	%eax,0(%r9)
        +	movl	%ebx,4(%r9)
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +
        +	jmp	L$cbc_exit
        +
        +.p2align	2
        +L$cbc_slow_dec_partial:
        +	movq	56(%rsp),%rdi
        +	movq	%r11,0(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	movl	%eax,0+64(%rsp)
        +	movl	%ebx,4+64(%rsp)
        +	movl	%ecx,8+64(%rsp)
        +	movl	%edx,12+64(%rsp)
        +
        +	movq	%r9,%rdi
        +	leaq	64(%rsp),%rsi
        +	leaq	16(%r10),%rcx
        +.long	0x9066A4F3
        +
        +	jmp	L$cbc_exit
        +
        +.p2align	4
        +L$cbc_exit:
        +	movq	16(%rsp),%rsi
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$cbc_popfq:
        +	popfq
        +L$cbc_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.p2align	6
        +L$AES_Te:
        +.long	0xa56363c6,0xa56363c6
        +.long	0x847c7cf8,0x847c7cf8
        +.long	0x997777ee,0x997777ee
        +.long	0x8d7b7bf6,0x8d7b7bf6
        +.long	0x0df2f2ff,0x0df2f2ff
        +.long	0xbd6b6bd6,0xbd6b6bd6
        +.long	0xb16f6fde,0xb16f6fde
        +.long	0x54c5c591,0x54c5c591
        +.long	0x50303060,0x50303060
        +.long	0x03010102,0x03010102
        +.long	0xa96767ce,0xa96767ce
        +.long	0x7d2b2b56,0x7d2b2b56
        +.long	0x19fefee7,0x19fefee7
        +.long	0x62d7d7b5,0x62d7d7b5
        +.long	0xe6abab4d,0xe6abab4d
        +.long	0x9a7676ec,0x9a7676ec
        +.long	0x45caca8f,0x45caca8f
        +.long	0x9d82821f,0x9d82821f
        +.long	0x40c9c989,0x40c9c989
        +.long	0x877d7dfa,0x877d7dfa
        +.long	0x15fafaef,0x15fafaef
        +.long	0xeb5959b2,0xeb5959b2
        +.long	0xc947478e,0xc947478e
        +.long	0x0bf0f0fb,0x0bf0f0fb
        +.long	0xecadad41,0xecadad41
        +.long	0x67d4d4b3,0x67d4d4b3
        +.long	0xfda2a25f,0xfda2a25f
        +.long	0xeaafaf45,0xeaafaf45
        +.long	0xbf9c9c23,0xbf9c9c23
        +.long	0xf7a4a453,0xf7a4a453
        +.long	0x967272e4,0x967272e4
        +.long	0x5bc0c09b,0x5bc0c09b
        +.long	0xc2b7b775,0xc2b7b775
        +.long	0x1cfdfde1,0x1cfdfde1
        +.long	0xae93933d,0xae93933d
        +.long	0x6a26264c,0x6a26264c
        +.long	0x5a36366c,0x5a36366c
        +.long	0x413f3f7e,0x413f3f7e
        +.long	0x02f7f7f5,0x02f7f7f5
        +.long	0x4fcccc83,0x4fcccc83
        +.long	0x5c343468,0x5c343468
        +.long	0xf4a5a551,0xf4a5a551
        +.long	0x34e5e5d1,0x34e5e5d1
        +.long	0x08f1f1f9,0x08f1f1f9
        +.long	0x937171e2,0x937171e2
        +.long	0x73d8d8ab,0x73d8d8ab
        +.long	0x53313162,0x53313162
        +.long	0x3f15152a,0x3f15152a
        +.long	0x0c040408,0x0c040408
        +.long	0x52c7c795,0x52c7c795
        +.long	0x65232346,0x65232346
        +.long	0x5ec3c39d,0x5ec3c39d
        +.long	0x28181830,0x28181830
        +.long	0xa1969637,0xa1969637
        +.long	0x0f05050a,0x0f05050a
        +.long	0xb59a9a2f,0xb59a9a2f
        +.long	0x0907070e,0x0907070e
        +.long	0x36121224,0x36121224
        +.long	0x9b80801b,0x9b80801b
        +.long	0x3de2e2df,0x3de2e2df
        +.long	0x26ebebcd,0x26ebebcd
        +.long	0x6927274e,0x6927274e
        +.long	0xcdb2b27f,0xcdb2b27f
        +.long	0x9f7575ea,0x9f7575ea
        +.long	0x1b090912,0x1b090912
        +.long	0x9e83831d,0x9e83831d
        +.long	0x742c2c58,0x742c2c58
        +.long	0x2e1a1a34,0x2e1a1a34
        +.long	0x2d1b1b36,0x2d1b1b36
        +.long	0xb26e6edc,0xb26e6edc
        +.long	0xee5a5ab4,0xee5a5ab4
        +.long	0xfba0a05b,0xfba0a05b
        +.long	0xf65252a4,0xf65252a4
        +.long	0x4d3b3b76,0x4d3b3b76
        +.long	0x61d6d6b7,0x61d6d6b7
        +.long	0xceb3b37d,0xceb3b37d
        +.long	0x7b292952,0x7b292952
        +.long	0x3ee3e3dd,0x3ee3e3dd
        +.long	0x712f2f5e,0x712f2f5e
        +.long	0x97848413,0x97848413
        +.long	0xf55353a6,0xf55353a6
        +.long	0x68d1d1b9,0x68d1d1b9
        +.long	0x00000000,0x00000000
        +.long	0x2cededc1,0x2cededc1
        +.long	0x60202040,0x60202040
        +.long	0x1ffcfce3,0x1ffcfce3
        +.long	0xc8b1b179,0xc8b1b179
        +.long	0xed5b5bb6,0xed5b5bb6
        +.long	0xbe6a6ad4,0xbe6a6ad4
        +.long	0x46cbcb8d,0x46cbcb8d
        +.long	0xd9bebe67,0xd9bebe67
        +.long	0x4b393972,0x4b393972
        +.long	0xde4a4a94,0xde4a4a94
        +.long	0xd44c4c98,0xd44c4c98
        +.long	0xe85858b0,0xe85858b0
        +.long	0x4acfcf85,0x4acfcf85
        +.long	0x6bd0d0bb,0x6bd0d0bb
        +.long	0x2aefefc5,0x2aefefc5
        +.long	0xe5aaaa4f,0xe5aaaa4f
        +.long	0x16fbfbed,0x16fbfbed
        +.long	0xc5434386,0xc5434386
        +.long	0xd74d4d9a,0xd74d4d9a
        +.long	0x55333366,0x55333366
        +.long	0x94858511,0x94858511
        +.long	0xcf45458a,0xcf45458a
        +.long	0x10f9f9e9,0x10f9f9e9
        +.long	0x06020204,0x06020204
        +.long	0x817f7ffe,0x817f7ffe
        +.long	0xf05050a0,0xf05050a0
        +.long	0x443c3c78,0x443c3c78
        +.long	0xba9f9f25,0xba9f9f25
        +.long	0xe3a8a84b,0xe3a8a84b
        +.long	0xf35151a2,0xf35151a2
        +.long	0xfea3a35d,0xfea3a35d
        +.long	0xc0404080,0xc0404080
        +.long	0x8a8f8f05,0x8a8f8f05
        +.long	0xad92923f,0xad92923f
        +.long	0xbc9d9d21,0xbc9d9d21
        +.long	0x48383870,0x48383870
        +.long	0x04f5f5f1,0x04f5f5f1
        +.long	0xdfbcbc63,0xdfbcbc63
        +.long	0xc1b6b677,0xc1b6b677
        +.long	0x75dadaaf,0x75dadaaf
        +.long	0x63212142,0x63212142
        +.long	0x30101020,0x30101020
        +.long	0x1affffe5,0x1affffe5
        +.long	0x0ef3f3fd,0x0ef3f3fd
        +.long	0x6dd2d2bf,0x6dd2d2bf
        +.long	0x4ccdcd81,0x4ccdcd81
        +.long	0x140c0c18,0x140c0c18
        +.long	0x35131326,0x35131326
        +.long	0x2fececc3,0x2fececc3
        +.long	0xe15f5fbe,0xe15f5fbe
        +.long	0xa2979735,0xa2979735
        +.long	0xcc444488,0xcc444488
        +.long	0x3917172e,0x3917172e
        +.long	0x57c4c493,0x57c4c493
        +.long	0xf2a7a755,0xf2a7a755
        +.long	0x827e7efc,0x827e7efc
        +.long	0x473d3d7a,0x473d3d7a
        +.long	0xac6464c8,0xac6464c8
        +.long	0xe75d5dba,0xe75d5dba
        +.long	0x2b191932,0x2b191932
        +.long	0x957373e6,0x957373e6
        +.long	0xa06060c0,0xa06060c0
        +.long	0x98818119,0x98818119
        +.long	0xd14f4f9e,0xd14f4f9e
        +.long	0x7fdcdca3,0x7fdcdca3
        +.long	0x66222244,0x66222244
        +.long	0x7e2a2a54,0x7e2a2a54
        +.long	0xab90903b,0xab90903b
        +.long	0x8388880b,0x8388880b
        +.long	0xca46468c,0xca46468c
        +.long	0x29eeeec7,0x29eeeec7
        +.long	0xd3b8b86b,0xd3b8b86b
        +.long	0x3c141428,0x3c141428
        +.long	0x79dedea7,0x79dedea7
        +.long	0xe25e5ebc,0xe25e5ebc
        +.long	0x1d0b0b16,0x1d0b0b16
        +.long	0x76dbdbad,0x76dbdbad
        +.long	0x3be0e0db,0x3be0e0db
        +.long	0x56323264,0x56323264
        +.long	0x4e3a3a74,0x4e3a3a74
        +.long	0x1e0a0a14,0x1e0a0a14
        +.long	0xdb494992,0xdb494992
        +.long	0x0a06060c,0x0a06060c
        +.long	0x6c242448,0x6c242448
        +.long	0xe45c5cb8,0xe45c5cb8
        +.long	0x5dc2c29f,0x5dc2c29f
        +.long	0x6ed3d3bd,0x6ed3d3bd
        +.long	0xefacac43,0xefacac43
        +.long	0xa66262c4,0xa66262c4
        +.long	0xa8919139,0xa8919139
        +.long	0xa4959531,0xa4959531
        +.long	0x37e4e4d3,0x37e4e4d3
        +.long	0x8b7979f2,0x8b7979f2
        +.long	0x32e7e7d5,0x32e7e7d5
        +.long	0x43c8c88b,0x43c8c88b
        +.long	0x5937376e,0x5937376e
        +.long	0xb76d6dda,0xb76d6dda
        +.long	0x8c8d8d01,0x8c8d8d01
        +.long	0x64d5d5b1,0x64d5d5b1
        +.long	0xd24e4e9c,0xd24e4e9c
        +.long	0xe0a9a949,0xe0a9a949
        +.long	0xb46c6cd8,0xb46c6cd8
        +.long	0xfa5656ac,0xfa5656ac
        +.long	0x07f4f4f3,0x07f4f4f3
        +.long	0x25eaeacf,0x25eaeacf
        +.long	0xaf6565ca,0xaf6565ca
        +.long	0x8e7a7af4,0x8e7a7af4
        +.long	0xe9aeae47,0xe9aeae47
        +.long	0x18080810,0x18080810
        +.long	0xd5baba6f,0xd5baba6f
        +.long	0x887878f0,0x887878f0
        +.long	0x6f25254a,0x6f25254a
        +.long	0x722e2e5c,0x722e2e5c
        +.long	0x241c1c38,0x241c1c38
        +.long	0xf1a6a657,0xf1a6a657
        +.long	0xc7b4b473,0xc7b4b473
        +.long	0x51c6c697,0x51c6c697
        +.long	0x23e8e8cb,0x23e8e8cb
        +.long	0x7cdddda1,0x7cdddda1
        +.long	0x9c7474e8,0x9c7474e8
        +.long	0x211f1f3e,0x211f1f3e
        +.long	0xdd4b4b96,0xdd4b4b96
        +.long	0xdcbdbd61,0xdcbdbd61
        +.long	0x868b8b0d,0x868b8b0d
        +.long	0x858a8a0f,0x858a8a0f
        +.long	0x907070e0,0x907070e0
        +.long	0x423e3e7c,0x423e3e7c
        +.long	0xc4b5b571,0xc4b5b571
        +.long	0xaa6666cc,0xaa6666cc
        +.long	0xd8484890,0xd8484890
        +.long	0x05030306,0x05030306
        +.long	0x01f6f6f7,0x01f6f6f7
        +.long	0x120e0e1c,0x120e0e1c
        +.long	0xa36161c2,0xa36161c2
        +.long	0x5f35356a,0x5f35356a
        +.long	0xf95757ae,0xf95757ae
        +.long	0xd0b9b969,0xd0b9b969
        +.long	0x91868617,0x91868617
        +.long	0x58c1c199,0x58c1c199
        +.long	0x271d1d3a,0x271d1d3a
        +.long	0xb99e9e27,0xb99e9e27
        +.long	0x38e1e1d9,0x38e1e1d9
        +.long	0x13f8f8eb,0x13f8f8eb
        +.long	0xb398982b,0xb398982b
        +.long	0x33111122,0x33111122
        +.long	0xbb6969d2,0xbb6969d2
        +.long	0x70d9d9a9,0x70d9d9a9
        +.long	0x898e8e07,0x898e8e07
        +.long	0xa7949433,0xa7949433
        +.long	0xb69b9b2d,0xb69b9b2d
        +.long	0x221e1e3c,0x221e1e3c
        +.long	0x92878715,0x92878715
        +.long	0x20e9e9c9,0x20e9e9c9
        +.long	0x49cece87,0x49cece87
        +.long	0xff5555aa,0xff5555aa
        +.long	0x78282850,0x78282850
        +.long	0x7adfdfa5,0x7adfdfa5
        +.long	0x8f8c8c03,0x8f8c8c03
        +.long	0xf8a1a159,0xf8a1a159
        +.long	0x80898909,0x80898909
        +.long	0x170d0d1a,0x170d0d1a
        +.long	0xdabfbf65,0xdabfbf65
        +.long	0x31e6e6d7,0x31e6e6d7
        +.long	0xc6424284,0xc6424284
        +.long	0xb86868d0,0xb86868d0
        +.long	0xc3414182,0xc3414182
        +.long	0xb0999929,0xb0999929
        +.long	0x772d2d5a,0x772d2d5a
        +.long	0x110f0f1e,0x110f0f1e
        +.long	0xcbb0b07b,0xcbb0b07b
        +.long	0xfc5454a8,0xfc5454a8
        +.long	0xd6bbbb6d,0xd6bbbb6d
        +.long	0x3a16162c,0x3a16162c
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
        +.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
        +.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
        +.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
        +.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
        +.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
        +.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
        +.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
        +.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
        +.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
        +.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
        +.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
        +.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
        +.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
        +.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
        +.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
        +.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
        +.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
        +.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
        +.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
        +.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
        +.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
        +.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
        +.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
        +.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
        +.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
        +.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
        +.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
        +.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
        +.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
        +.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
        +.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
        +.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
        +.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
        +.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
        +.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
        +.p2align	6
        +L$AES_Td:
        +.long	0x50a7f451,0x50a7f451
        +.long	0x5365417e,0x5365417e
        +.long	0xc3a4171a,0xc3a4171a
        +.long	0x965e273a,0x965e273a
        +.long	0xcb6bab3b,0xcb6bab3b
        +.long	0xf1459d1f,0xf1459d1f
        +.long	0xab58faac,0xab58faac
        +.long	0x9303e34b,0x9303e34b
        +.long	0x55fa3020,0x55fa3020
        +.long	0xf66d76ad,0xf66d76ad
        +.long	0x9176cc88,0x9176cc88
        +.long	0x254c02f5,0x254c02f5
        +.long	0xfcd7e54f,0xfcd7e54f
        +.long	0xd7cb2ac5,0xd7cb2ac5
        +.long	0x80443526,0x80443526
        +.long	0x8fa362b5,0x8fa362b5
        +.long	0x495ab1de,0x495ab1de
        +.long	0x671bba25,0x671bba25
        +.long	0x980eea45,0x980eea45
        +.long	0xe1c0fe5d,0xe1c0fe5d
        +.long	0x02752fc3,0x02752fc3
        +.long	0x12f04c81,0x12f04c81
        +.long	0xa397468d,0xa397468d
        +.long	0xc6f9d36b,0xc6f9d36b
        +.long	0xe75f8f03,0xe75f8f03
        +.long	0x959c9215,0x959c9215
        +.long	0xeb7a6dbf,0xeb7a6dbf
        +.long	0xda595295,0xda595295
        +.long	0x2d83bed4,0x2d83bed4
        +.long	0xd3217458,0xd3217458
        +.long	0x2969e049,0x2969e049
        +.long	0x44c8c98e,0x44c8c98e
        +.long	0x6a89c275,0x6a89c275
        +.long	0x78798ef4,0x78798ef4
        +.long	0x6b3e5899,0x6b3e5899
        +.long	0xdd71b927,0xdd71b927
        +.long	0xb64fe1be,0xb64fe1be
        +.long	0x17ad88f0,0x17ad88f0
        +.long	0x66ac20c9,0x66ac20c9
        +.long	0xb43ace7d,0xb43ace7d
        +.long	0x184adf63,0x184adf63
        +.long	0x82311ae5,0x82311ae5
        +.long	0x60335197,0x60335197
        +.long	0x457f5362,0x457f5362
        +.long	0xe07764b1,0xe07764b1
        +.long	0x84ae6bbb,0x84ae6bbb
        +.long	0x1ca081fe,0x1ca081fe
        +.long	0x942b08f9,0x942b08f9
        +.long	0x58684870,0x58684870
        +.long	0x19fd458f,0x19fd458f
        +.long	0x876cde94,0x876cde94
        +.long	0xb7f87b52,0xb7f87b52
        +.long	0x23d373ab,0x23d373ab
        +.long	0xe2024b72,0xe2024b72
        +.long	0x578f1fe3,0x578f1fe3
        +.long	0x2aab5566,0x2aab5566
        +.long	0x0728ebb2,0x0728ebb2
        +.long	0x03c2b52f,0x03c2b52f
        +.long	0x9a7bc586,0x9a7bc586
        +.long	0xa50837d3,0xa50837d3
        +.long	0xf2872830,0xf2872830
        +.long	0xb2a5bf23,0xb2a5bf23
        +.long	0xba6a0302,0xba6a0302
        +.long	0x5c8216ed,0x5c8216ed
        +.long	0x2b1ccf8a,0x2b1ccf8a
        +.long	0x92b479a7,0x92b479a7
        +.long	0xf0f207f3,0xf0f207f3
        +.long	0xa1e2694e,0xa1e2694e
        +.long	0xcdf4da65,0xcdf4da65
        +.long	0xd5be0506,0xd5be0506
        +.long	0x1f6234d1,0x1f6234d1
        +.long	0x8afea6c4,0x8afea6c4
        +.long	0x9d532e34,0x9d532e34
        +.long	0xa055f3a2,0xa055f3a2
        +.long	0x32e18a05,0x32e18a05
        +.long	0x75ebf6a4,0x75ebf6a4
        +.long	0x39ec830b,0x39ec830b
        +.long	0xaaef6040,0xaaef6040
        +.long	0x069f715e,0x069f715e
        +.long	0x51106ebd,0x51106ebd
        +.long	0xf98a213e,0xf98a213e
        +.long	0x3d06dd96,0x3d06dd96
        +.long	0xae053edd,0xae053edd
        +.long	0x46bde64d,0x46bde64d
        +.long	0xb58d5491,0xb58d5491
        +.long	0x055dc471,0x055dc471
        +.long	0x6fd40604,0x6fd40604
        +.long	0xff155060,0xff155060
        +.long	0x24fb9819,0x24fb9819
        +.long	0x97e9bdd6,0x97e9bdd6
        +.long	0xcc434089,0xcc434089
        +.long	0x779ed967,0x779ed967
        +.long	0xbd42e8b0,0xbd42e8b0
        +.long	0x888b8907,0x888b8907
        +.long	0x385b19e7,0x385b19e7
        +.long	0xdbeec879,0xdbeec879
        +.long	0x470a7ca1,0x470a7ca1
        +.long	0xe90f427c,0xe90f427c
        +.long	0xc91e84f8,0xc91e84f8
        +.long	0x00000000,0x00000000
        +.long	0x83868009,0x83868009
        +.long	0x48ed2b32,0x48ed2b32
        +.long	0xac70111e,0xac70111e
        +.long	0x4e725a6c,0x4e725a6c
        +.long	0xfbff0efd,0xfbff0efd
        +.long	0x5638850f,0x5638850f
        +.long	0x1ed5ae3d,0x1ed5ae3d
        +.long	0x27392d36,0x27392d36
        +.long	0x64d90f0a,0x64d90f0a
        +.long	0x21a65c68,0x21a65c68
        +.long	0xd1545b9b,0xd1545b9b
        +.long	0x3a2e3624,0x3a2e3624
        +.long	0xb1670a0c,0xb1670a0c
        +.long	0x0fe75793,0x0fe75793
        +.long	0xd296eeb4,0xd296eeb4
        +.long	0x9e919b1b,0x9e919b1b
        +.long	0x4fc5c080,0x4fc5c080
        +.long	0xa220dc61,0xa220dc61
        +.long	0x694b775a,0x694b775a
        +.long	0x161a121c,0x161a121c
        +.long	0x0aba93e2,0x0aba93e2
        +.long	0xe52aa0c0,0xe52aa0c0
        +.long	0x43e0223c,0x43e0223c
        +.long	0x1d171b12,0x1d171b12
        +.long	0x0b0d090e,0x0b0d090e
        +.long	0xadc78bf2,0xadc78bf2
        +.long	0xb9a8b62d,0xb9a8b62d
        +.long	0xc8a91e14,0xc8a91e14
        +.long	0x8519f157,0x8519f157
        +.long	0x4c0775af,0x4c0775af
        +.long	0xbbdd99ee,0xbbdd99ee
        +.long	0xfd607fa3,0xfd607fa3
        +.long	0x9f2601f7,0x9f2601f7
        +.long	0xbcf5725c,0xbcf5725c
        +.long	0xc53b6644,0xc53b6644
        +.long	0x347efb5b,0x347efb5b
        +.long	0x7629438b,0x7629438b
        +.long	0xdcc623cb,0xdcc623cb
        +.long	0x68fcedb6,0x68fcedb6
        +.long	0x63f1e4b8,0x63f1e4b8
        +.long	0xcadc31d7,0xcadc31d7
        +.long	0x10856342,0x10856342
        +.long	0x40229713,0x40229713
        +.long	0x2011c684,0x2011c684
        +.long	0x7d244a85,0x7d244a85
        +.long	0xf83dbbd2,0xf83dbbd2
        +.long	0x1132f9ae,0x1132f9ae
        +.long	0x6da129c7,0x6da129c7
        +.long	0x4b2f9e1d,0x4b2f9e1d
        +.long	0xf330b2dc,0xf330b2dc
        +.long	0xec52860d,0xec52860d
        +.long	0xd0e3c177,0xd0e3c177
        +.long	0x6c16b32b,0x6c16b32b
        +.long	0x99b970a9,0x99b970a9
        +.long	0xfa489411,0xfa489411
        +.long	0x2264e947,0x2264e947
        +.long	0xc48cfca8,0xc48cfca8
        +.long	0x1a3ff0a0,0x1a3ff0a0
        +.long	0xd82c7d56,0xd82c7d56
        +.long	0xef903322,0xef903322
        +.long	0xc74e4987,0xc74e4987
        +.long	0xc1d138d9,0xc1d138d9
        +.long	0xfea2ca8c,0xfea2ca8c
        +.long	0x360bd498,0x360bd498
        +.long	0xcf81f5a6,0xcf81f5a6
        +.long	0x28de7aa5,0x28de7aa5
        +.long	0x268eb7da,0x268eb7da
        +.long	0xa4bfad3f,0xa4bfad3f
        +.long	0xe49d3a2c,0xe49d3a2c
        +.long	0x0d927850,0x0d927850
        +.long	0x9bcc5f6a,0x9bcc5f6a
        +.long	0x62467e54,0x62467e54
        +.long	0xc2138df6,0xc2138df6
        +.long	0xe8b8d890,0xe8b8d890
        +.long	0x5ef7392e,0x5ef7392e
        +.long	0xf5afc382,0xf5afc382
        +.long	0xbe805d9f,0xbe805d9f
        +.long	0x7c93d069,0x7c93d069
        +.long	0xa92dd56f,0xa92dd56f
        +.long	0xb31225cf,0xb31225cf
        +.long	0x3b99acc8,0x3b99acc8
        +.long	0xa77d1810,0xa77d1810
        +.long	0x6e639ce8,0x6e639ce8
        +.long	0x7bbb3bdb,0x7bbb3bdb
        +.long	0x097826cd,0x097826cd
        +.long	0xf418596e,0xf418596e
        +.long	0x01b79aec,0x01b79aec
        +.long	0xa89a4f83,0xa89a4f83
        +.long	0x656e95e6,0x656e95e6
        +.long	0x7ee6ffaa,0x7ee6ffaa
        +.long	0x08cfbc21,0x08cfbc21
        +.long	0xe6e815ef,0xe6e815ef
        +.long	0xd99be7ba,0xd99be7ba
        +.long	0xce366f4a,0xce366f4a
        +.long	0xd4099fea,0xd4099fea
        +.long	0xd67cb029,0xd67cb029
        +.long	0xafb2a431,0xafb2a431
        +.long	0x31233f2a,0x31233f2a
        +.long	0x3094a5c6,0x3094a5c6
        +.long	0xc066a235,0xc066a235
        +.long	0x37bc4e74,0x37bc4e74
        +.long	0xa6ca82fc,0xa6ca82fc
        +.long	0xb0d090e0,0xb0d090e0
        +.long	0x15d8a733,0x15d8a733
        +.long	0x4a9804f1,0x4a9804f1
        +.long	0xf7daec41,0xf7daec41
        +.long	0x0e50cd7f,0x0e50cd7f
        +.long	0x2ff69117,0x2ff69117
        +.long	0x8dd64d76,0x8dd64d76
        +.long	0x4db0ef43,0x4db0ef43
        +.long	0x544daacc,0x544daacc
        +.long	0xdf0496e4,0xdf0496e4
        +.long	0xe3b5d19e,0xe3b5d19e
        +.long	0x1b886a4c,0x1b886a4c
        +.long	0xb81f2cc1,0xb81f2cc1
        +.long	0x7f516546,0x7f516546
        +.long	0x04ea5e9d,0x04ea5e9d
        +.long	0x5d358c01,0x5d358c01
        +.long	0x737487fa,0x737487fa
        +.long	0x2e410bfb,0x2e410bfb
        +.long	0x5a1d67b3,0x5a1d67b3
        +.long	0x52d2db92,0x52d2db92
        +.long	0x335610e9,0x335610e9
        +.long	0x1347d66d,0x1347d66d
        +.long	0x8c61d79a,0x8c61d79a
        +.long	0x7a0ca137,0x7a0ca137
        +.long	0x8e14f859,0x8e14f859
        +.long	0x893c13eb,0x893c13eb
        +.long	0xee27a9ce,0xee27a9ce
        +.long	0x35c961b7,0x35c961b7
        +.long	0xede51ce1,0xede51ce1
        +.long	0x3cb1477a,0x3cb1477a
        +.long	0x59dfd29c,0x59dfd29c
        +.long	0x3f73f255,0x3f73f255
        +.long	0x79ce1418,0x79ce1418
        +.long	0xbf37c773,0xbf37c773
        +.long	0xeacdf753,0xeacdf753
        +.long	0x5baafd5f,0x5baafd5f
        +.long	0x146f3ddf,0x146f3ddf
        +.long	0x86db4478,0x86db4478
        +.long	0x81f3afca,0x81f3afca
        +.long	0x3ec468b9,0x3ec468b9
        +.long	0x2c342438,0x2c342438
        +.long	0x5f40a3c2,0x5f40a3c2
        +.long	0x72c31d16,0x72c31d16
        +.long	0x0c25e2bc,0x0c25e2bc
        +.long	0x8b493c28,0x8b493c28
        +.long	0x41950dff,0x41950dff
        +.long	0x7101a839,0x7101a839
        +.long	0xdeb30c08,0xdeb30c08
        +.long	0x9ce4b4d8,0x9ce4b4d8
        +.long	0x90c15664,0x90c15664
        +.long	0x6184cb7b,0x6184cb7b
        +.long	0x70b632d5,0x70b632d5
        +.long	0x745c6c48,0x745c6c48
        +.long	0x4257b8d0,0x4257b8d0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
        +.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
        +.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
        +.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
        +.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
        +.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
        +.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
        +.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
        +.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
        +.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
        +.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
        +.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
        +.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
        +.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
        +.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
        +.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
        +.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
        +.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
        +.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
        +.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
        +.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
        +.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
        +.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
        +.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
        +.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
        +.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
        +.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
        +.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
        +.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
        +.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
        +.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
        +.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
        +.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.byte	65,69,83,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.p2align	6
        diff --git a/vendor/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s
        new file mode 100644
        index 000000000..5ae41e019
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s
        @@ -0,0 +1,1402 @@
        +.text
        +
        +
        +
        +.globl	_aesni_cbc_sha1_enc
        +
        +.p2align	4
        +_aesni_cbc_sha1_enc:
        +
        +	movl	_OPENSSL_ia32cap_P+0(%rip),%r10d
        +	movl	_OPENSSL_ia32cap_P+4(%rip),%r11d
        +	jmp	aesni_cbc_sha1_enc_ssse3
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +aesni_cbc_sha1_enc_ssse3:
        +	movq	8(%rsp),%r10
        +
        +
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	leaq	-104(%rsp),%rsp
        +
        +
        +	movq	%rdi,%r12
        +	movq	%rsi,%r13
        +	movq	%rdx,%r14
        +	movq	%rcx,%r15
        +	movdqu	(%r8),%xmm11
        +	movq	%r8,88(%rsp)
        +	shlq	$6,%r14
        +	subq	%r12,%r13
        +	movl	240(%r15),%r8d
        +	addq	%r10,%r14
        +
        +	leaq	K_XX_XX(%rip),%r11
        +	movl	0(%r9),%eax
        +	movl	4(%r9),%ebx
        +	movl	8(%r9),%ecx
        +	movl	12(%r9),%edx
        +	movl	%ebx,%esi
        +	movl	16(%r9),%ebp
        +
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r10),%xmm0
        +	movdqu	16(%r10),%xmm1
        +	movdqu	32(%r10),%xmm2
        +	movdqu	48(%r10),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r10
        +.byte	102,15,56,0,206
        +.byte	102,15,56,0,214
        +.byte	102,15,56,0,222
        +	paddd	%xmm9,%xmm0
        +	paddd	%xmm9,%xmm1
        +	paddd	%xmm9,%xmm2
        +	movdqa	%xmm0,0(%rsp)
        +	psubd	%xmm9,%xmm0
        +	movdqa	%xmm1,16(%rsp)
        +	psubd	%xmm9,%xmm1
        +	movdqa	%xmm2,32(%rsp)
        +	psubd	%xmm9,%xmm2
        +	movups	(%r15),%xmm13
        +	movups	16(%r15),%xmm14
        +	jmp	L$oop_ssse3
        +.p2align	4
        +L$oop_ssse3:
        +	movdqa	%xmm1,%xmm4
        +	addl	0(%rsp),%ebp
        +	movups	0(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	xorl	%edx,%ecx
        +	movdqa	%xmm3,%xmm8
        +.byte	102,15,58,15,224,8
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	paddd	%xmm3,%xmm9
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrldq	$4,%xmm8
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	pxor	%xmm0,%xmm4
        +	rorl	$2,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm2,%xmm8
        +	addl	4(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pxor	%xmm8,%xmm4
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm9,48(%rsp)
        +	xorl	%ecx,%edi
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	addl	%ebp,%edx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm4,%xmm8
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	8(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	pslldq	$12,%xmm10
        +	paddd	%xmm4,%xmm4
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrld	$31,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm4
        +	addl	12(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm4
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	0(%r11),%xmm10
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	pxor	%xmm9,%xmm4
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movdqa	%xmm2,%xmm5
        +	addl	16(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movdqa	%xmm4,%xmm9
        +.byte	102,15,58,15,233,8
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	paddd	%xmm4,%xmm10
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrldq	$4,%xmm9
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	pxor	%xmm1,%xmm5
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm3,%xmm9
        +	addl	20(%rsp),%ebp
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pxor	%xmm9,%xmm5
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	%xmm10,0(%rsp)
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm5,%xmm9
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	24(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	pslldq	$12,%xmm8
        +	paddd	%xmm5,%xmm5
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	psrld	$31,%xmm9
        +	xorl	%ecx,%esi
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	addl	%ebp,%edx
        +	movdqa	%xmm8,%xmm10
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	psrld	$30,%xmm8
        +	por	%xmm9,%xmm5
        +	addl	28(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	pslld	$2,%xmm10
        +	pxor	%xmm8,%xmm5
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	16(%r11),%xmm8
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	pxor	%xmm10,%xmm5
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movdqa	%xmm3,%xmm6
        +	addl	32(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movdqa	%xmm5,%xmm10
        +.byte	102,15,58,15,242,8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	paddd	%xmm5,%xmm8
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	psrldq	$4,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	pxor	%xmm2,%xmm6
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm4,%xmm10
        +	addl	36(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	pxor	%xmm10,%xmm6
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm8,16(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm6,%xmm10
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	40(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%ecx
        +	pslldq	$12,%xmm9
        +	paddd	%xmm6,%xmm6
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrld	$31,%xmm10
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	psrld	$30,%xmm9
        +	por	%xmm10,%xmm6
        +	addl	44(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pslld	$2,%xmm8
        +	pxor	%xmm9,%xmm6
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	16(%r11),%xmm9
        +	xorl	%ecx,%edi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%ebp,%edx
        +	pxor	%xmm8,%xmm6
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movdqa	%xmm4,%xmm7
        +	addl	48(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm8
        +.byte	102,15,58,15,251,8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm6,%xmm9
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrldq	$4,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	pxor	%xmm3,%xmm7
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm5,%xmm8
        +	addl	52(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	pxor	%xmm8,%xmm7
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm7,%xmm8
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	56(%rsp),%eax
        +	xorl	%ebp,%edx
        +	pslldq	$12,%xmm10
        +	paddd	%xmm7,%xmm7
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrld	$31,%xmm8
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm7
        +	addl	60(%rsp),%ebp
        +	cmpl	$11,%r8d
        +	jb	L$aesenclast1
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	L$aesenclast1
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +L$aesenclast1:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm7
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	16(%r11),%xmm10
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	pxor	%xmm9,%xmm7
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movdqa	%xmm7,%xmm9
        +	addl	0(%rsp),%edx
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,206,8
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm1,%xmm0
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm7,%xmm10
        +	xorl	%ecx,%esi
        +	movups	16(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	movups	%xmm11,0(%r13,%r12,1)
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	addl	%ebp,%edx
        +	pxor	%xmm9,%xmm0
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	4(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm0,%xmm9
        +	movdqa	%xmm10,48(%rsp)
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	pslld	$2,%xmm0
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	psrld	$30,%xmm9
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	8(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	por	%xmm9,%xmm0
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm0,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	12(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	16(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,215,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm2,%xmm1
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm0,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm10,%xmm1
        +	addl	20(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm1,%xmm10
        +	movdqa	%xmm8,0(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm1
        +	addl	24(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm10
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm10,%xmm1
        +	addl	28(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movdqa	%xmm1,%xmm8
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	32(%rsp),%eax
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,192,8
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	pxor	%xmm3,%xmm2
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	movdqa	32(%r11),%xmm10
        +	paddd	%xmm1,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm8,%xmm2
        +	addl	36(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	movdqa	%xmm2,%xmm8
        +	movdqa	%xmm9,16(%rsp)
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	pslld	$2,%xmm2
        +	addl	40(%rsp),%edx
        +	xorl	%ecx,%esi
        +	psrld	$30,%xmm8
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	por	%xmm8,%xmm2
        +	addl	44(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movdqa	%xmm2,%xmm9
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	48(%rsp),%ebx
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,201,8
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	pxor	%xmm4,%xmm3
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm2,%xmm10
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm9,%xmm3
        +	addl	52(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	movdqa	%xmm3,%xmm9
        +	movdqa	%xmm10,32(%rsp)
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%esi
        +	psrld	$30,%xmm9
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	por	%xmm9,%xmm3
        +	addl	60(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movdqa	%xmm3,%xmm10
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	0(%rsp),%ecx
        +	pxor	%xmm0,%xmm4
        +.byte	102,68,15,58,15,210,8
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	pxor	%xmm5,%xmm4
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edx,%ecx
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm3,%xmm8
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm10,%xmm4
        +	addl	4(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm8,48(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	pslld	$2,%xmm4
        +	addl	8(%rsp),%eax
        +	xorl	%ebp,%esi
        +	psrld	$30,%xmm10
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	por	%xmm10,%xmm4
        +	addl	12(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movdqa	%xmm4,%xmm8
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	16(%rsp),%edx
        +	pxor	%xmm1,%xmm5
        +.byte	102,68,15,58,15,195,8
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm6,%xmm5
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm4,%xmm9
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	pxor	%xmm8,%xmm5
        +	addl	20(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm9,0(%rsp)
        +	xorl	%eax,%edi
        +	cmpl	$11,%r8d
        +	jb	L$aesenclast2
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	L$aesenclast2
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +L$aesenclast2:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	pslld	$2,%xmm5
        +	addl	24(%rsp),%ebx
        +	xorl	%eax,%esi
        +	psrld	$30,%xmm8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	por	%xmm8,%xmm5
        +	addl	28(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movdqa	%xmm5,%xmm9
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ecx,%edi
        +	movups	32(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	movups	%xmm11,16(%r13,%r12,1)
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	pxor	%xmm2,%xmm6
        +.byte	102,68,15,58,15,204,8
        +	xorl	%edx,%ecx
        +	addl	32(%rsp),%ebp
        +	andl	%edx,%edi
        +	pxor	%xmm7,%xmm6
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm5,%xmm10
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	pxor	%xmm9,%xmm6
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm10,16(%rsp)
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	36(%rsp),%edx
        +	andl	%ecx,%esi
        +	pslld	$2,%xmm6
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	psrld	$30,%xmm9
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	por	%xmm9,%xmm6
        +	movl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm10
        +	addl	40(%rsp),%ecx
        +	andl	%ebx,%edi
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	44(%rsp),%ebx
        +	andl	%eax,%esi
        +	andl	%ebp,%edi
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%edi
        +	pxor	%xmm3,%xmm7
        +.byte	102,68,15,58,15,213,8
        +	xorl	%ebp,%edx
        +	addl	48(%rsp),%eax
        +	andl	%ebp,%edi
        +	pxor	%xmm0,%xmm7
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	movdqa	48(%r11),%xmm9
        +	paddd	%xmm6,%xmm8
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	pxor	%xmm10,%xmm7
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm8,32(%rsp)
        +	movl	%ecx,%esi
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	addl	52(%rsp),%ebp
        +	andl	%edx,%esi
        +	pslld	$2,%xmm7
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	psrld	$30,%xmm10
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	por	%xmm10,%xmm7
        +	movl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm8
        +	addl	56(%rsp),%edx
        +	andl	%ecx,%edi
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	60(%rsp),%ecx
        +	andl	%ebx,%esi
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%edi
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,198,8
        +	xorl	%eax,%ebp
        +	addl	0(%rsp),%ebx
        +	andl	%eax,%edi
        +	pxor	%xmm1,%xmm0
        +	andl	%ebp,%esi
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	rorl	$7,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm7,%xmm9
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	pxor	%xmm8,%xmm0
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movdqa	%xmm0,%xmm8
        +	movdqa	%xmm9,48(%rsp)
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	4(%rsp),%eax
        +	andl	%ebp,%esi
        +	pslld	$2,%xmm0
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	psrld	$30,%xmm8
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	por	%xmm8,%xmm0
        +	movl	%ecx,%edi
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%ecx
        +	movdqa	%xmm0,%xmm9
        +	addl	8(%rsp),%ebp
        +	andl	%edx,%edi
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	12(%rsp),%edx
        +	andl	%ecx,%esi
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%edi
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,207,8
        +	xorl	%ebx,%eax
        +	addl	16(%rsp),%ecx
        +	andl	%ebx,%edi
        +	pxor	%xmm2,%xmm1
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm0,%xmm10
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	pxor	%xmm9,%xmm1
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movdqa	%xmm1,%xmm9
        +	movdqa	%xmm10,0(%rsp)
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	20(%rsp),%ebx
        +	andl	%eax,%esi
        +	pslld	$2,%xmm1
        +	andl	%ebp,%edi
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	rorl	$7,%edx
        +	psrld	$30,%xmm9
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	por	%xmm9,%xmm1
        +	movl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm1,%xmm10
        +	addl	24(%rsp),%eax
        +	andl	%ebp,%edi
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movl	%ecx,%esi
        +	cmpl	$11,%r8d
        +	jb	L$aesenclast3
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	L$aesenclast3
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +L$aesenclast3:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	xorl	%edx,%ecx
        +	addl	28(%rsp),%ebp
        +	andl	%edx,%esi
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%edi
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,208,8
        +	xorl	%ecx,%ebx
        +	addl	32(%rsp),%edx
        +	andl	%ecx,%edi
        +	pxor	%xmm3,%xmm2
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm1,%xmm8
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	pxor	%xmm10,%xmm2
        +	roll	$5,%ebp
        +	movups	48(%r12),%xmm12
        +	xorps	%xmm13,%xmm12
        +	movups	%xmm11,32(%r13,%r12,1)
        +	xorps	%xmm12,%xmm11
        +.byte	102,69,15,56,220,222
        +	movups	32(%r15),%xmm15
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movdqa	%xmm2,%xmm10
        +	movdqa	%xmm8,16(%rsp)
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	36(%rsp),%ecx
        +	andl	%ebx,%esi
        +	pslld	$2,%xmm2
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	psrld	$30,%xmm10
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	por	%xmm10,%xmm2
        +	movl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm2,%xmm8
        +	addl	40(%rsp),%ebx
        +	andl	%eax,%edi
        +	andl	%ebp,%esi
        +.byte	102,69,15,56,220,223
        +	movups	48(%r15),%xmm14
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	44(%rsp),%eax
        +	andl	%ebp,%esi
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	addl	48(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	64(%r15),%xmm15
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,193,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm4,%xmm3
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm2,%xmm9
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm8,%xmm3
        +	addl	52(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm3,%xmm8
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	80(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm8,%xmm3
        +	addl	60(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	0(%rsp),%eax
        +	paddd	%xmm3,%xmm10
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	movdqa	%xmm10,48(%rsp)
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	4(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	96(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	8(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	12(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +.byte	102,69,15,56,220,223
        +	movups	112(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	cmpq	%r14,%r10
        +	je	L$done_ssse3
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r10),%xmm0
        +	movdqu	16(%r10),%xmm1
        +	movdqu	32(%r10),%xmm2
        +	movdqu	48(%r10),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r10
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +.byte	102,15,56,0,206
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	paddd	%xmm9,%xmm0
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movdqa	%xmm0,0(%rsp)
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	psubd	%xmm9,%xmm0
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +.byte	102,15,56,0,214
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm9,%xmm1
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movdqa	%xmm1,16(%rsp)
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	psubd	%xmm9,%xmm1
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +.byte	102,15,56,0,222
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	paddd	%xmm9,%xmm2
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movdqa	%xmm2,32(%rsp)
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	psubd	%xmm9,%xmm2
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	cmpl	$11,%r8d
        +	jb	L$aesenclast4
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	L$aesenclast4
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +L$aesenclast4:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movups	%xmm11,48(%r13,%r12,1)
        +	leaq	64(%r12),%r12
        +
        +	addl	0(%r9),%eax
        +	addl	4(%r9),%esi
        +	addl	8(%r9),%ecx
        +	addl	12(%r9),%edx
        +	movl	%eax,0(%r9)
        +	addl	16(%r9),%ebp
        +	movl	%esi,4(%r9)
        +	movl	%esi,%ebx
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +	movl	%ebp,16(%r9)
        +	jmp	L$oop_ssse3
        +
        +.p2align	4
        +L$done_ssse3:
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	128(%r15),%xmm15
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +.byte	102,69,15,56,220,223
        +	movups	144(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +.byte	102,69,15,56,220,222
        +	movups	160(%r15),%xmm15
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	cmpl	$11,%r8d
        +	jb	L$aesenclast5
        +	movups	176(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	192(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +	je	L$aesenclast5
        +	movups	208(%r15),%xmm14
        +.byte	102,69,15,56,220,223
        +	movups	224(%r15),%xmm15
        +.byte	102,69,15,56,220,222
        +L$aesenclast5:
        +.byte	102,69,15,56,221,223
        +	movups	16(%r15),%xmm14
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movups	%xmm11,48(%r13,%r12,1)
        +	movq	88(%rsp),%r8
        +
        +	addl	0(%r9),%eax
        +	addl	4(%r9),%esi
        +	addl	8(%r9),%ecx
        +	movl	%eax,0(%r9)
        +	addl	12(%r9),%edx
        +	movl	%esi,4(%r9)
        +	addl	16(%r9),%ebp
        +	movl	%ecx,8(%r9)
        +	movl	%edx,12(%r9)
        +	movl	%ebp,16(%r9)
        +	movups	%xmm11,(%r8)
        +	leaq	104(%rsp),%rsi
        +	movq	0(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$epilogue_ssse3:
        +	.byte	0xf3,0xc3
        +
        +.p2align	6
        +K_XX_XX:
        +.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999
        +
        +.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
        +
        +.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
        +
        +.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
        +
        +.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
        +
        +
        +.byte	65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.p2align	6
        diff --git a/vendor/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s
        new file mode 100644
        index 000000000..2ea2d3460
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/aes/aesni-x86_64.s
        @@ -0,0 +1,2558 @@
        +.text
        +
        +.globl	_aesni_encrypt
        +
        +.p2align	4
        +_aesni_encrypt:
        +	movups	(%rdi),%xmm2
        +	movl	240(%rdx),%eax
        +	movups	(%rdx),%xmm0
        +	movups	16(%rdx),%xmm1
        +	leaq	32(%rdx),%rdx
        +	xorps	%xmm0,%xmm2
        +L$oop_enc1_1:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rdx),%xmm1
        +	leaq	16(%rdx),%rdx
        +	jnz	L$oop_enc1_1
        +
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%rsi)
        +	.byte	0xf3,0xc3
        +
        +
        +.globl	_aesni_decrypt
        +
        +.p2align	4
        +_aesni_decrypt:
        +	movups	(%rdi),%xmm2
        +	movl	240(%rdx),%eax
        +	movups	(%rdx),%xmm0
        +	movups	16(%rdx),%xmm1
        +	leaq	32(%rdx),%rdx
        +	xorps	%xmm0,%xmm2
        +L$oop_dec1_2:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rdx),%xmm1
        +	leaq	16(%rdx),%rdx
        +	jnz	L$oop_dec1_2
        +
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%rsi)
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_encrypt3:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	movups	(%rcx),%xmm0
        +
        +L$enc_loop3:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +	movups	(%rcx),%xmm0
        +	jnz	L$enc_loop3
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_decrypt3:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	movups	(%rcx),%xmm0
        +
        +L$dec_loop3:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +	movups	(%rcx),%xmm0
        +	jnz	L$dec_loop3
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_encrypt4:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	xorps	%xmm0,%xmm5
        +	movups	(%rcx),%xmm0
        +
        +L$enc_loop4:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +	movups	(%rcx),%xmm0
        +	jnz	L$enc_loop4
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_decrypt4:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +	xorps	%xmm0,%xmm4
        +	xorps	%xmm0,%xmm5
        +	movups	(%rcx),%xmm0
        +
        +L$dec_loop4:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +	movups	(%rcx),%xmm0
        +	jnz	L$dec_loop4
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_encrypt6:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,220,241
        +	movups	(%rcx),%xmm0
        +.byte	102,15,56,220,249
        +	jmp	L$enc_loop6_enter
        +.p2align	4
        +L$enc_loop6:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +L$enc_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%rcx),%xmm0
        +	jnz	L$enc_loop6
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_decrypt6:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,222,241
        +	movups	(%rcx),%xmm0
        +.byte	102,15,56,222,249
        +	jmp	L$dec_loop6_enter
        +.p2align	4
        +L$dec_loop6:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +L$dec_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	(%rcx),%xmm0
        +	jnz	L$dec_loop6
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_encrypt8:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,220,241
        +	pxor	%xmm0,%xmm8
        +.byte	102,15,56,220,249
        +	pxor	%xmm0,%xmm9
        +	movups	(%rcx),%xmm0
        +.byte	102,68,15,56,220,193
        +.byte	102,68,15,56,220,201
        +	movups	16(%rcx),%xmm1
        +	jmp	L$enc_loop8_enter
        +.p2align	4
        +L$enc_loop8:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,68,15,56,220,193
        +.byte	102,68,15,56,220,201
        +	movups	16(%rcx),%xmm1
        +L$enc_loop8_enter:
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +.byte	102,68,15,56,220,192
        +.byte	102,68,15,56,220,200
        +	movups	(%rcx),%xmm0
        +	jnz	L$enc_loop8
        +
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,68,15,56,220,193
        +.byte	102,68,15,56,220,201
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +.byte	102,68,15,56,221,192
        +.byte	102,68,15,56,221,200
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +_aesni_decrypt8:
        +	movups	(%rcx),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm0,%xmm3
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,222,241
        +	pxor	%xmm0,%xmm8
        +.byte	102,15,56,222,249
        +	pxor	%xmm0,%xmm9
        +	movups	(%rcx),%xmm0
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +	movups	16(%rcx),%xmm1
        +	jmp	L$dec_loop8_enter
        +.p2align	4
        +L$dec_loop8:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +	movups	16(%rcx),%xmm1
        +L$dec_loop8_enter:
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +.byte	102,68,15,56,222,192
        +.byte	102,68,15,56,222,200
        +	movups	(%rcx),%xmm0
        +	jnz	L$dec_loop8
        +
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +.byte	102,68,15,56,223,192
        +.byte	102,68,15,56,223,200
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_ecb_encrypt
        +
        +.p2align	4
        +_aesni_ecb_encrypt:
        +	andq	$-16,%rdx
        +	jz	L$ecb_ret
        +
        +	movl	240(%rcx),%eax
        +	movups	(%rcx),%xmm0
        +	movq	%rcx,%r11
        +	movl	%eax,%r10d
        +	testl	%r8d,%r8d
        +	jz	L$ecb_decrypt
        +
        +	cmpq	$128,%rdx
        +	jb	L$ecb_enc_tail
        +
        +	movdqu	(%rdi),%xmm2
        +	movdqu	16(%rdi),%xmm3
        +	movdqu	32(%rdi),%xmm4
        +	movdqu	48(%rdi),%xmm5
        +	movdqu	64(%rdi),%xmm6
        +	movdqu	80(%rdi),%xmm7
        +	movdqu	96(%rdi),%xmm8
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +	subq	$128,%rdx
        +	jmp	L$ecb_enc_loop8_enter
        +.p2align	4
        +L$ecb_enc_loop8:
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movdqu	(%rdi),%xmm2
        +	movl	%r10d,%eax
        +	movups	%xmm3,16(%rsi)
        +	movdqu	16(%rdi),%xmm3
        +	movups	%xmm4,32(%rsi)
        +	movdqu	32(%rdi),%xmm4
        +	movups	%xmm5,48(%rsi)
        +	movdqu	48(%rdi),%xmm5
        +	movups	%xmm6,64(%rsi)
        +	movdqu	64(%rdi),%xmm6
        +	movups	%xmm7,80(%rsi)
        +	movdqu	80(%rdi),%xmm7
        +	movups	%xmm8,96(%rsi)
        +	movdqu	96(%rdi),%xmm8
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +L$ecb_enc_loop8_enter:
        +
        +	call	_aesni_encrypt8
        +
        +	subq	$128,%rdx
        +	jnc	L$ecb_enc_loop8
        +
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movups	%xmm3,16(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	addq	$128,%rdx
        +	jz	L$ecb_ret
        +
        +L$ecb_enc_tail:
        +	movups	(%rdi),%xmm2
        +	cmpq	$32,%rdx
        +	jb	L$ecb_enc_one
        +	movups	16(%rdi),%xmm3
        +	je	L$ecb_enc_two
        +	movups	32(%rdi),%xmm4
        +	cmpq	$64,%rdx
        +	jb	L$ecb_enc_three
        +	movups	48(%rdi),%xmm5
        +	je	L$ecb_enc_four
        +	movups	64(%rdi),%xmm6
        +	cmpq	$96,%rdx
        +	jb	L$ecb_enc_five
        +	movups	80(%rdi),%xmm7
        +	je	L$ecb_enc_six
        +	movdqu	96(%rdi),%xmm8
        +	call	_aesni_encrypt8
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_enc_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_enc1_3:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_enc1_3
        +
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_enc_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_encrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_enc_three:
        +	call	_aesni_encrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_enc_four:
        +	call	_aesni_encrypt4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_enc_five:
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_encrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_enc_six:
        +	call	_aesni_encrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	jmp	L$ecb_ret
        +
        +.p2align	4
        +L$ecb_decrypt:
        +	cmpq	$128,%rdx
        +	jb	L$ecb_dec_tail
        +
        +	movdqu	(%rdi),%xmm2
        +	movdqu	16(%rdi),%xmm3
        +	movdqu	32(%rdi),%xmm4
        +	movdqu	48(%rdi),%xmm5
        +	movdqu	64(%rdi),%xmm6
        +	movdqu	80(%rdi),%xmm7
        +	movdqu	96(%rdi),%xmm8
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +	subq	$128,%rdx
        +	jmp	L$ecb_dec_loop8_enter
        +.p2align	4
        +L$ecb_dec_loop8:
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movdqu	(%rdi),%xmm2
        +	movl	%r10d,%eax
        +	movups	%xmm3,16(%rsi)
        +	movdqu	16(%rdi),%xmm3
        +	movups	%xmm4,32(%rsi)
        +	movdqu	32(%rdi),%xmm4
        +	movups	%xmm5,48(%rsi)
        +	movdqu	48(%rdi),%xmm5
        +	movups	%xmm6,64(%rsi)
        +	movdqu	64(%rdi),%xmm6
        +	movups	%xmm7,80(%rsi)
        +	movdqu	80(%rdi),%xmm7
        +	movups	%xmm8,96(%rsi)
        +	movdqu	96(%rdi),%xmm8
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	movdqu	112(%rdi),%xmm9
        +	leaq	128(%rdi),%rdi
        +L$ecb_dec_loop8_enter:
        +
        +	call	_aesni_decrypt8
        +
        +	movups	(%r11),%xmm0
        +	subq	$128,%rdx
        +	jnc	L$ecb_dec_loop8
        +
        +	movups	%xmm2,(%rsi)
        +	movq	%r11,%rcx
        +	movups	%xmm3,16(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	movups	%xmm9,112(%rsi)
        +	leaq	128(%rsi),%rsi
        +	addq	$128,%rdx
        +	jz	L$ecb_ret
        +
        +L$ecb_dec_tail:
        +	movups	(%rdi),%xmm2
        +	cmpq	$32,%rdx
        +	jb	L$ecb_dec_one
        +	movups	16(%rdi),%xmm3
        +	je	L$ecb_dec_two
        +	movups	32(%rdi),%xmm4
        +	cmpq	$64,%rdx
        +	jb	L$ecb_dec_three
        +	movups	48(%rdi),%xmm5
        +	je	L$ecb_dec_four
        +	movups	64(%rdi),%xmm6
        +	cmpq	$96,%rdx
        +	jb	L$ecb_dec_five
        +	movups	80(%rdi),%xmm7
        +	je	L$ecb_dec_six
        +	movups	96(%rdi),%xmm8
        +	movups	(%rcx),%xmm0
        +	call	_aesni_decrypt8
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	movups	%xmm8,96(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_dec_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_dec1_4:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_dec1_4
        +
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_decrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_dec_three:
        +	call	_aesni_decrypt3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_dec_four:
        +	call	_aesni_decrypt4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_dec_five:
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_decrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	jmp	L$ecb_ret
        +.p2align	4
        +L$ecb_dec_six:
        +	call	_aesni_decrypt6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +
        +L$ecb_ret:
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_ccm64_encrypt_blocks
        +
        +.p2align	4
        +_aesni_ccm64_encrypt_blocks:
        +	movl	240(%rcx),%eax
        +	movdqu	(%r8),%xmm9
        +	movdqa	L$increment64(%rip),%xmm6
        +	movdqa	L$bswap_mask(%rip),%xmm7
        +
        +	shrl	$1,%eax
        +	leaq	0(%rcx),%r11
        +	movdqu	(%r9),%xmm3
        +	movdqa	%xmm9,%xmm2
        +	movl	%eax,%r10d
        +.byte	102,68,15,56,0,207
        +	jmp	L$ccm64_enc_outer
        +.p2align	4
        +L$ccm64_enc_outer:
        +	movups	(%r11),%xmm0
        +	movl	%r10d,%eax
        +	movups	(%rdi),%xmm8
        +
        +	xorps	%xmm0,%xmm2
        +	movups	16(%r11),%xmm1
        +	xorps	%xmm8,%xmm0
        +	leaq	32(%r11),%rcx
        +	xorps	%xmm0,%xmm3
        +	movups	(%rcx),%xmm0
        +
        +L$ccm64_enc2_loop:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +.byte	102,15,56,220,217
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,216
        +	movups	0(%rcx),%xmm0
        +	jnz	L$ccm64_enc2_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	paddq	%xmm6,%xmm9
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +
        +	decq	%rdx
        +	leaq	16(%rdi),%rdi
        +	xorps	%xmm2,%xmm8
        +	movdqa	%xmm9,%xmm2
        +	movups	%xmm8,(%rsi)
        +	leaq	16(%rsi),%rsi
        +.byte	102,15,56,0,215
        +	jnz	L$ccm64_enc_outer
        +
        +	movups	%xmm3,(%r9)
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_ccm64_decrypt_blocks
        +
        +.p2align	4
        +_aesni_ccm64_decrypt_blocks:
        +	movl	240(%rcx),%eax
        +	movups	(%r8),%xmm9
        +	movdqu	(%r9),%xmm3
        +	movdqa	L$increment64(%rip),%xmm6
        +	movdqa	L$bswap_mask(%rip),%xmm7
        +
        +	movaps	%xmm9,%xmm2
        +	movl	%eax,%r10d
        +	movq	%rcx,%r11
        +.byte	102,68,15,56,0,207
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_enc1_5:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_enc1_5
        +
        +.byte	102,15,56,221,209
        +	movups	(%rdi),%xmm8
        +	paddq	%xmm6,%xmm9
        +	leaq	16(%rdi),%rdi
        +	jmp	L$ccm64_dec_outer
        +.p2align	4
        +L$ccm64_dec_outer:
        +	xorps	%xmm2,%xmm8
        +	movdqa	%xmm9,%xmm2
        +	movl	%r10d,%eax
        +	movups	%xmm8,(%rsi)
        +	leaq	16(%rsi),%rsi
        +.byte	102,15,56,0,215
        +
        +	subq	$1,%rdx
        +	jz	L$ccm64_dec_break
        +
        +	movups	(%r11),%xmm0
        +	shrl	$1,%eax
        +	movups	16(%r11),%xmm1
        +	xorps	%xmm0,%xmm8
        +	leaq	32(%r11),%rcx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm8,%xmm3
        +	movups	(%rcx),%xmm0
        +
        +L$ccm64_dec2_loop:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +.byte	102,15,56,220,217
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,216
        +	movups	0(%rcx),%xmm0
        +	jnz	L$ccm64_dec2_loop
        +	movups	(%rdi),%xmm8
        +	paddq	%xmm6,%xmm9
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	leaq	16(%rdi),%rdi
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +	jmp	L$ccm64_dec_outer
        +
        +.p2align	4
        +L$ccm64_dec_break:
        +
        +	movups	(%r11),%xmm0
        +	movups	16(%r11),%xmm1
        +	xorps	%xmm0,%xmm8
        +	leaq	32(%r11),%r11
        +	xorps	%xmm8,%xmm3
        +L$oop_enc1_6:
        +.byte	102,15,56,220,217
        +	decl	%eax
        +	movups	(%r11),%xmm1
        +	leaq	16(%r11),%r11
        +	jnz	L$oop_enc1_6
        +
        +.byte	102,15,56,221,217
        +	movups	%xmm3,(%r9)
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_ctr32_encrypt_blocks
        +
        +.p2align	4
        +_aesni_ctr32_encrypt_blocks:
        +	cmpq	$1,%rdx
        +	je	L$ctr32_one_shortcut
        +
        +	movdqu	(%r8),%xmm14
        +	movdqa	L$bswap_mask(%rip),%xmm15
        +	xorl	%eax,%eax
        +.byte	102,69,15,58,22,242,3
        +.byte	102,68,15,58,34,240,3
        +
        +	movl	240(%rcx),%eax
        +	bswapl	%r10d
        +	pxor	%xmm12,%xmm12
        +	pxor	%xmm13,%xmm13
        +.byte	102,69,15,58,34,226,0
        +	leaq	3(%r10),%r11
        +.byte	102,69,15,58,34,235,0
        +	incl	%r10d
        +.byte	102,69,15,58,34,226,1
        +	incq	%r11
        +.byte	102,69,15,58,34,235,1
        +	incl	%r10d
        +.byte	102,69,15,58,34,226,2
        +	incq	%r11
        +.byte	102,69,15,58,34,235,2
        +	movdqa	%xmm12,-40(%rsp)
        +.byte	102,69,15,56,0,231
        +	movdqa	%xmm13,-24(%rsp)
        +.byte	102,69,15,56,0,239
        +
        +	pshufd	$192,%xmm12,%xmm2
        +	pshufd	$128,%xmm12,%xmm3
        +	pshufd	$64,%xmm12,%xmm4
        +	cmpq	$6,%rdx
        +	jb	L$ctr32_tail
        +	shrl	$1,%eax
        +	movq	%rcx,%r11
        +	movl	%eax,%r10d
        +	subq	$6,%rdx
        +	jmp	L$ctr32_loop6
        +
        +.p2align	4
        +L$ctr32_loop6:
        +	pshufd	$192,%xmm13,%xmm5
        +	por	%xmm14,%xmm2
        +	movups	(%r11),%xmm0
        +	pshufd	$128,%xmm13,%xmm6
        +	por	%xmm14,%xmm3
        +	movups	16(%r11),%xmm1
        +	pshufd	$64,%xmm13,%xmm7
        +	por	%xmm14,%xmm4
        +	por	%xmm14,%xmm5
        +	xorps	%xmm0,%xmm2
        +	por	%xmm14,%xmm6
        +	por	%xmm14,%xmm7
        +
        +
        +
        +
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	leaq	32(%r11),%rcx
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	movdqa	L$increment32(%rip),%xmm13
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	movdqa	-40(%rsp),%xmm12
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	movups	(%rcx),%xmm0
        +	decl	%eax
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +	jmp	L$ctr32_enc_loop6_enter
        +.p2align	4
        +L$ctr32_enc_loop6:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +L$ctr32_enc_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%rcx),%xmm0
        +	jnz	L$ctr32_enc_loop6
        +
        +.byte	102,15,56,220,209
        +	paddd	%xmm13,%xmm12
        +.byte	102,15,56,220,217
        +	paddd	-24(%rsp),%xmm13
        +.byte	102,15,56,220,225
        +	movdqa	%xmm12,-40(%rsp)
        +.byte	102,15,56,220,233
        +	movdqa	%xmm13,-24(%rsp)
        +.byte	102,15,56,220,241
        +.byte	102,69,15,56,0,231
        +.byte	102,15,56,220,249
        +.byte	102,69,15,56,0,239
        +
        +.byte	102,15,56,221,208
        +	movups	(%rdi),%xmm8
        +.byte	102,15,56,221,216
        +	movups	16(%rdi),%xmm9
        +.byte	102,15,56,221,224
        +	movups	32(%rdi),%xmm10
        +.byte	102,15,56,221,232
        +	movups	48(%rdi),%xmm11
        +.byte	102,15,56,221,240
        +	movups	64(%rdi),%xmm1
        +.byte	102,15,56,221,248
        +	movups	80(%rdi),%xmm0
        +	leaq	96(%rdi),%rdi
        +
        +	xorps	%xmm2,%xmm8
        +	pshufd	$192,%xmm12,%xmm2
        +	xorps	%xmm3,%xmm9
        +	pshufd	$128,%xmm12,%xmm3
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	pshufd	$64,%xmm12,%xmm4
        +	movups	%xmm9,16(%rsi)
        +	xorps	%xmm5,%xmm11
        +	movups	%xmm10,32(%rsi)
        +	xorps	%xmm6,%xmm1
        +	movups	%xmm11,48(%rsi)
        +	xorps	%xmm7,%xmm0
        +	movups	%xmm1,64(%rsi)
        +	movups	%xmm0,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	movl	%r10d,%eax
        +	subq	$6,%rdx
        +	jnc	L$ctr32_loop6
        +
        +	addq	$6,%rdx
        +	jz	L$ctr32_done
        +	movq	%r11,%rcx
        +	leal	1(%rax,%rax,1),%eax
        +
        +L$ctr32_tail:
        +	por	%xmm14,%xmm2
        +	movups	(%rdi),%xmm8
        +	cmpq	$2,%rdx
        +	jb	L$ctr32_one
        +
        +	por	%xmm14,%xmm3
        +	movups	16(%rdi),%xmm9
        +	je	L$ctr32_two
        +
        +	pshufd	$192,%xmm13,%xmm5
        +	por	%xmm14,%xmm4
        +	movups	32(%rdi),%xmm10
        +	cmpq	$4,%rdx
        +	jb	L$ctr32_three
        +
        +	pshufd	$128,%xmm13,%xmm6
        +	por	%xmm14,%xmm5
        +	movups	48(%rdi),%xmm11
        +	je	L$ctr32_four
        +
        +	por	%xmm14,%xmm6
        +	xorps	%xmm7,%xmm7
        +
        +	call	_aesni_encrypt6
        +
        +	movups	64(%rdi),%xmm1
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	movups	%xmm9,16(%rsi)
        +	xorps	%xmm5,%xmm11
        +	movups	%xmm10,32(%rsi)
        +	xorps	%xmm6,%xmm1
        +	movups	%xmm11,48(%rsi)
        +	movups	%xmm1,64(%rsi)
        +	jmp	L$ctr32_done
        +
        +.p2align	4
        +L$ctr32_one_shortcut:
        +	movups	(%r8),%xmm2
        +	movups	(%rdi),%xmm8
        +	movl	240(%rcx),%eax
        +L$ctr32_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_enc1_7:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_enc1_7
        +
        +.byte	102,15,56,221,209
        +	xorps	%xmm2,%xmm8
        +	movups	%xmm8,(%rsi)
        +	jmp	L$ctr32_done
        +
        +.p2align	4
        +L$ctr32_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_encrypt3
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	movups	%xmm9,16(%rsi)
        +	jmp	L$ctr32_done
        +
        +.p2align	4
        +L$ctr32_three:
        +	call	_aesni_encrypt3
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	movups	%xmm9,16(%rsi)
        +	movups	%xmm10,32(%rsi)
        +	jmp	L$ctr32_done
        +
        +.p2align	4
        +L$ctr32_four:
        +	call	_aesni_encrypt4
        +	xorps	%xmm2,%xmm8
        +	xorps	%xmm3,%xmm9
        +	movups	%xmm8,(%rsi)
        +	xorps	%xmm4,%xmm10
        +	movups	%xmm9,16(%rsi)
        +	xorps	%xmm5,%xmm11
        +	movups	%xmm10,32(%rsi)
        +	movups	%xmm11,48(%rsi)
        +
        +L$ctr32_done:
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_xts_encrypt
        +
        +.p2align	4
        +_aesni_xts_encrypt:
        +	leaq	-104(%rsp),%rsp
        +	movups	(%r9),%xmm15
        +	movl	240(%r8),%eax
        +	movl	240(%rcx),%r10d
        +	movups	(%r8),%xmm0
        +	movups	16(%r8),%xmm1
        +	leaq	32(%r8),%r8
        +	xorps	%xmm0,%xmm15
        +L$oop_enc1_8:
        +.byte	102,68,15,56,220,249
        +	decl	%eax
        +	movups	(%r8),%xmm1
        +	leaq	16(%r8),%r8
        +	jnz	L$oop_enc1_8
        +
        +.byte	102,68,15,56,221,249
        +	movq	%rcx,%r11
        +	movl	%r10d,%eax
        +	movq	%rdx,%r9
        +	andq	$-16,%rdx
        +
        +	movdqa	L$xts_magic(%rip),%xmm8
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	subq	$96,%rdx
        +	jc	L$xts_enc_short
        +
        +	shrl	$1,%eax
        +	subl	$1,%eax
        +	movl	%eax,%r10d
        +	jmp	L$xts_enc_grandloop
        +
        +.p2align	4
        +L$xts_enc_grandloop:
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	0(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	pxor	%xmm12,%xmm4
        +	movdqu	80(%rdi),%xmm7
        +	leaq	96(%rdi),%rdi
        +	pxor	%xmm13,%xmm5
        +	movups	(%r11),%xmm0
        +	pxor	%xmm14,%xmm6
        +	pxor	%xmm15,%xmm7
        +
        +
        +
        +	movups	16(%r11),%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	movdqa	%xmm10,0(%rsp)
        +.byte	102,15,56,220,209
        +	leaq	32(%r11),%rcx
        +	pxor	%xmm0,%xmm4
        +	movdqa	%xmm11,16(%rsp)
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +	movdqa	%xmm12,32(%rsp)
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +	movdqa	%xmm13,48(%rsp)
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +	movups	(%rcx),%xmm0
        +	decl	%eax
        +	movdqa	%xmm14,64(%rsp)
        +.byte	102,15,56,220,241
        +	movdqa	%xmm15,80(%rsp)
        +.byte	102,15,56,220,249
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	jmp	L$xts_enc_loop6_enter
        +
        +.p2align	4
        +L$xts_enc_loop6:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%eax
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +L$xts_enc_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%rcx),%xmm0
        +	jnz	L$xts_enc_loop6
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,220,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,220,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,220,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +	movups	16(%rcx),%xmm1
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,220,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,220,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,220,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	32(%rcx),%xmm0
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,220,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,220,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,220,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,221,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,221,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,221,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	xorps	0(%rsp),%xmm2
        +	pand	%xmm8,%xmm9
        +	xorps	16(%rsp),%xmm3
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +
        +	xorps	32(%rsp),%xmm4
        +	movups	%xmm2,0(%rsi)
        +	xorps	48(%rsp),%xmm5
        +	movups	%xmm3,16(%rsi)
        +	xorps	64(%rsp),%xmm6
        +	movups	%xmm4,32(%rsi)
        +	xorps	80(%rsp),%xmm7
        +	movups	%xmm5,48(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	subq	$96,%rdx
        +	jnc	L$xts_enc_grandloop
        +
        +	leal	3(%rax,%rax,1),%eax
        +	movq	%r11,%rcx
        +	movl	%eax,%r10d
        +
        +L$xts_enc_short:
        +	addq	$96,%rdx
        +	jz	L$xts_enc_done
        +
        +	cmpq	$32,%rdx
        +	jb	L$xts_enc_one
        +	je	L$xts_enc_two
        +
        +	cmpq	$64,%rdx
        +	jb	L$xts_enc_three
        +	je	L$xts_enc_four
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	leaq	80(%rdi),%rdi
        +	pxor	%xmm12,%xmm4
        +	pxor	%xmm13,%xmm5
        +	pxor	%xmm14,%xmm6
        +
        +	call	_aesni_encrypt6
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm15,%xmm10
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movdqu	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movdqu	%xmm3,16(%rsi)
        +	xorps	%xmm14,%xmm6
        +	movdqu	%xmm4,32(%rsi)
        +	movdqu	%xmm5,48(%rsi)
        +	movdqu	%xmm6,64(%rsi)
        +	leaq	80(%rsi),%rsi
        +	jmp	L$xts_enc_done
        +
        +.p2align	4
        +L$xts_enc_one:
        +	movups	(%rdi),%xmm2
        +	leaq	16(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_enc1_9:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_enc1_9
        +
        +.byte	102,15,56,221,209
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm11,%xmm10
        +	movups	%xmm2,(%rsi)
        +	leaq	16(%rsi),%rsi
        +	jmp	L$xts_enc_done
        +
        +.p2align	4
        +L$xts_enc_two:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	leaq	32(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm12,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	leaq	32(%rsi),%rsi
        +	jmp	L$xts_enc_done
        +
        +.p2align	4
        +L$xts_enc_three:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	32(%rdi),%xmm4
        +	leaq	48(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm13,%xmm10
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	leaq	48(%rsi),%rsi
        +	jmp	L$xts_enc_done
        +
        +.p2align	4
        +L$xts_enc_four:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	32(%rdi),%xmm4
        +	xorps	%xmm10,%xmm2
        +	movups	48(%rdi),%xmm5
        +	leaq	64(%rdi),%rdi
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	xorps	%xmm13,%xmm5
        +
        +	call	_aesni_encrypt4
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm15,%xmm10
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	leaq	64(%rsi),%rsi
        +	jmp	L$xts_enc_done
        +
        +.p2align	4
        +L$xts_enc_done:
        +	andq	$15,%r9
        +	jz	L$xts_enc_ret
        +	movq	%r9,%rdx
        +
        +L$xts_enc_steal:
        +	movzbl	(%rdi),%eax
        +	movzbl	-16(%rsi),%ecx
        +	leaq	1(%rdi),%rdi
        +	movb	%al,-16(%rsi)
        +	movb	%cl,0(%rsi)
        +	leaq	1(%rsi),%rsi
        +	subq	$1,%rdx
        +	jnz	L$xts_enc_steal
        +
        +	subq	%r9,%rsi
        +	movq	%r11,%rcx
        +	movl	%r10d,%eax
        +
        +	movups	-16(%rsi),%xmm2
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_enc1_10:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_enc1_10
        +
        +.byte	102,15,56,221,209
        +	xorps	%xmm10,%xmm2
        +	movups	%xmm2,-16(%rsi)
        +
        +L$xts_enc_ret:
        +	leaq	104(%rsp),%rsp
        +L$xts_enc_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_xts_decrypt
        +
        +.p2align	4
        +_aesni_xts_decrypt:
        +	leaq	-104(%rsp),%rsp
        +	movups	(%r9),%xmm15
        +	movl	240(%r8),%eax
        +	movl	240(%rcx),%r10d
        +	movups	(%r8),%xmm0
        +	movups	16(%r8),%xmm1
        +	leaq	32(%r8),%r8
        +	xorps	%xmm0,%xmm15
        +L$oop_enc1_11:
        +.byte	102,68,15,56,220,249
        +	decl	%eax
        +	movups	(%r8),%xmm1
        +	leaq	16(%r8),%r8
        +	jnz	L$oop_enc1_11
        +
        +.byte	102,68,15,56,221,249
        +	xorl	%eax,%eax
        +	testq	$15,%rdx
        +	setnz	%al
        +	shlq	$4,%rax
        +	subq	%rax,%rdx
        +
        +	movq	%rcx,%r11
        +	movl	%r10d,%eax
        +	movq	%rdx,%r9
        +	andq	$-16,%rdx
        +
        +	movdqa	L$xts_magic(%rip),%xmm8
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm9
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +	subq	$96,%rdx
        +	jc	L$xts_dec_short
        +
        +	shrl	$1,%eax
        +	subl	$1,%eax
        +	movl	%eax,%r10d
        +	jmp	L$xts_dec_grandloop
        +
        +.p2align	4
        +L$xts_dec_grandloop:
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	0(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	pxor	%xmm12,%xmm4
        +	movdqu	80(%rdi),%xmm7
        +	leaq	96(%rdi),%rdi
        +	pxor	%xmm13,%xmm5
        +	movups	(%r11),%xmm0
        +	pxor	%xmm14,%xmm6
        +	pxor	%xmm15,%xmm7
        +
        +
        +
        +	movups	16(%r11),%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	movdqa	%xmm10,0(%rsp)
        +.byte	102,15,56,222,209
        +	leaq	32(%r11),%rcx
        +	pxor	%xmm0,%xmm4
        +	movdqa	%xmm11,16(%rsp)
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +	movdqa	%xmm12,32(%rsp)
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +	movdqa	%xmm13,48(%rsp)
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	movups	(%rcx),%xmm0
        +	decl	%eax
        +	movdqa	%xmm14,64(%rsp)
        +.byte	102,15,56,222,241
        +	movdqa	%xmm15,80(%rsp)
        +.byte	102,15,56,222,249
        +	pxor	%xmm14,%xmm14
        +	pcmpgtd	%xmm15,%xmm14
        +	jmp	L$xts_dec_loop6_enter
        +
        +.p2align	4
        +L$xts_dec_loop6:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%eax
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +L$xts_dec_loop6_enter:
        +	movups	16(%rcx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leaq	32(%rcx),%rcx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	(%rcx),%xmm0
        +	jnz	L$xts_dec_loop6
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,222,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,222,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,222,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +	movups	16(%rcx),%xmm1
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,222,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,222,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,222,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	32(%rcx),%xmm0
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm11
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,222,209
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,222,217
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,222,225
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm12
        +	paddq	%xmm15,%xmm15
        +.byte	102,15,56,223,208
        +	pand	%xmm8,%xmm9
        +.byte	102,15,56,223,216
        +	pcmpgtd	%xmm15,%xmm14
        +.byte	102,15,56,223,224
        +	pxor	%xmm9,%xmm15
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	pxor	%xmm14,%xmm14
        +	movdqa	%xmm15,%xmm13
        +	paddq	%xmm15,%xmm15
        +	xorps	0(%rsp),%xmm2
        +	pand	%xmm8,%xmm9
        +	xorps	16(%rsp),%xmm3
        +	pcmpgtd	%xmm15,%xmm14
        +	pxor	%xmm9,%xmm15
        +
        +	xorps	32(%rsp),%xmm4
        +	movups	%xmm2,0(%rsi)
        +	xorps	48(%rsp),%xmm5
        +	movups	%xmm3,16(%rsi)
        +	xorps	64(%rsp),%xmm6
        +	movups	%xmm4,32(%rsi)
        +	xorps	80(%rsp),%xmm7
        +	movups	%xmm5,48(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	subq	$96,%rdx
        +	jnc	L$xts_dec_grandloop
        +
        +	leal	3(%rax,%rax,1),%eax
        +	movq	%r11,%rcx
        +	movl	%eax,%r10d
        +
        +L$xts_dec_short:
        +	addq	$96,%rdx
        +	jz	L$xts_dec_done
        +
        +	cmpq	$32,%rdx
        +	jb	L$xts_dec_one
        +	je	L$xts_dec_two
        +
        +	cmpq	$64,%rdx
        +	jb	L$xts_dec_three
        +	je	L$xts_dec_four
        +
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movdqu	(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movdqu	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movdqu	32(%rdi),%xmm4
        +	pxor	%xmm10,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	pxor	%xmm11,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +	leaq	80(%rdi),%rdi
        +	pxor	%xmm12,%xmm4
        +	pxor	%xmm13,%xmm5
        +	pxor	%xmm14,%xmm6
        +
        +	call	_aesni_decrypt6
        +
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	movdqu	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movdqu	%xmm3,16(%rsi)
        +	xorps	%xmm14,%xmm6
        +	movdqu	%xmm4,32(%rsi)
        +	pxor	%xmm14,%xmm14
        +	movdqu	%xmm5,48(%rsi)
        +	pcmpgtd	%xmm15,%xmm14
        +	movdqu	%xmm6,64(%rsi)
        +	leaq	80(%rsi),%rsi
        +	pshufd	$19,%xmm14,%xmm11
        +	andq	$15,%r9
        +	jz	L$xts_dec_ret
        +
        +	movdqa	%xmm15,%xmm10
        +	paddq	%xmm15,%xmm15
        +	pand	%xmm8,%xmm11
        +	pxor	%xmm15,%xmm11
        +	jmp	L$xts_dec_done2
        +
        +.p2align	4
        +L$xts_dec_one:
        +	movups	(%rdi),%xmm2
        +	leaq	16(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_dec1_12:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_dec1_12
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm11,%xmm10
        +	movups	%xmm2,(%rsi)
        +	movdqa	%xmm12,%xmm11
        +	leaq	16(%rsi),%rsi
        +	jmp	L$xts_dec_done
        +
        +.p2align	4
        +L$xts_dec_two:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	leaq	32(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm12,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movdqa	%xmm13,%xmm11
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	leaq	32(%rsi),%rsi
        +	jmp	L$xts_dec_done
        +
        +.p2align	4
        +L$xts_dec_three:
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	32(%rdi),%xmm4
        +	leaq	48(%rdi),%rdi
        +	xorps	%xmm10,%xmm2
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm13,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movdqa	%xmm15,%xmm11
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	leaq	48(%rsi),%rsi
        +	jmp	L$xts_dec_done
        +
        +.p2align	4
        +L$xts_dec_four:
        +	pshufd	$19,%xmm14,%xmm9
        +	movdqa	%xmm15,%xmm14
        +	paddq	%xmm15,%xmm15
        +	movups	(%rdi),%xmm2
        +	pand	%xmm8,%xmm9
        +	movups	16(%rdi),%xmm3
        +	pxor	%xmm9,%xmm15
        +
        +	movups	32(%rdi),%xmm4
        +	xorps	%xmm10,%xmm2
        +	movups	48(%rdi),%xmm5
        +	leaq	64(%rdi),%rdi
        +	xorps	%xmm11,%xmm3
        +	xorps	%xmm12,%xmm4
        +	xorps	%xmm13,%xmm5
        +
        +	call	_aesni_decrypt4
        +
        +	xorps	%xmm10,%xmm2
        +	movdqa	%xmm14,%xmm10
        +	xorps	%xmm11,%xmm3
        +	movdqa	%xmm15,%xmm11
        +	xorps	%xmm12,%xmm4
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm13,%xmm5
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	leaq	64(%rsi),%rsi
        +	jmp	L$xts_dec_done
        +
        +.p2align	4
        +L$xts_dec_done:
        +	andq	$15,%r9
        +	jz	L$xts_dec_ret
        +L$xts_dec_done2:
        +	movq	%r9,%rdx
        +	movq	%r11,%rcx
        +	movl	%r10d,%eax
        +
        +	movups	(%rdi),%xmm2
        +	xorps	%xmm11,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_dec1_13:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_dec1_13
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm11,%xmm2
        +	movups	%xmm2,(%rsi)
        +
        +L$xts_dec_steal:
        +	movzbl	16(%rdi),%eax
        +	movzbl	(%rsi),%ecx
        +	leaq	1(%rdi),%rdi
        +	movb	%al,(%rsi)
        +	movb	%cl,16(%rsi)
        +	leaq	1(%rsi),%rsi
        +	subq	$1,%rdx
        +	jnz	L$xts_dec_steal
        +
        +	subq	%r9,%rsi
        +	movq	%r11,%rcx
        +	movl	%r10d,%eax
        +
        +	movups	(%rsi),%xmm2
        +	xorps	%xmm10,%xmm2
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_dec1_14:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_dec1_14
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm10,%xmm2
        +	movups	%xmm2,(%rsi)
        +
        +L$xts_dec_ret:
        +	leaq	104(%rsp),%rsp
        +L$xts_dec_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_cbc_encrypt
        +
        +.p2align	4
        +_aesni_cbc_encrypt:
        +	testq	%rdx,%rdx
        +	jz	L$cbc_ret
        +
        +	movl	240(%rcx),%r10d
        +	movq	%rcx,%r11
        +	testl	%r9d,%r9d
        +	jz	L$cbc_decrypt
        +
        +	movups	(%r8),%xmm2
        +	movl	%r10d,%eax
        +	cmpq	$16,%rdx
        +	jb	L$cbc_enc_tail
        +	subq	$16,%rdx
        +	jmp	L$cbc_enc_loop
        +.p2align	4
        +L$cbc_enc_loop:
        +	movups	(%rdi),%xmm3
        +	leaq	16(%rdi),%rdi
        +
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	xorps	%xmm0,%xmm3
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm3,%xmm2
        +L$oop_enc1_15:
        +.byte	102,15,56,220,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_enc1_15
        +
        +.byte	102,15,56,221,209
        +	movl	%r10d,%eax
        +	movq	%r11,%rcx
        +	movups	%xmm2,0(%rsi)
        +	leaq	16(%rsi),%rsi
        +	subq	$16,%rdx
        +	jnc	L$cbc_enc_loop
        +	addq	$16,%rdx
        +	jnz	L$cbc_enc_tail
        +	movups	%xmm2,(%r8)
        +	jmp	L$cbc_ret
        +
        +L$cbc_enc_tail:
        +	movq	%rdx,%rcx
        +	xchgq	%rdi,%rsi
        +.long	0x9066A4F3
        +
        +	movl	$16,%ecx
        +	subq	%rdx,%rcx
        +	xorl	%eax,%eax
        +.long	0x9066AAF3
        +
        +	leaq	-16(%rdi),%rdi
        +	movl	%r10d,%eax
        +	movq	%rdi,%rsi
        +	movq	%r11,%rcx
        +	xorq	%rdx,%rdx
        +	jmp	L$cbc_enc_loop
        +
        +
        +.p2align	4
        +L$cbc_decrypt:
        +	movups	(%r8),%xmm9
        +	movl	%r10d,%eax
        +	cmpq	$112,%rdx
        +	jbe	L$cbc_dec_tail
        +	shrl	$1,%r10d
        +	subq	$112,%rdx
        +	movl	%r10d,%eax
        +	movaps	%xmm9,-24(%rsp)
        +	jmp	L$cbc_dec_loop8_enter
        +.p2align	4
        +L$cbc_dec_loop8:
        +	movaps	%xmm0,-24(%rsp)
        +	movups	%xmm9,(%rsi)
        +	leaq	16(%rsi),%rsi
        +L$cbc_dec_loop8_enter:
        +	movups	(%rcx),%xmm0
        +	movups	(%rdi),%xmm2
        +	movups	16(%rdi),%xmm3
        +	movups	16(%rcx),%xmm1
        +
        +	leaq	32(%rcx),%rcx
        +	movdqu	32(%rdi),%xmm4
        +	xorps	%xmm0,%xmm2
        +	movdqu	48(%rdi),%xmm5
        +	xorps	%xmm0,%xmm3
        +	movdqu	64(%rdi),%xmm6
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +	movdqu	80(%rdi),%xmm7
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +	movdqu	96(%rdi),%xmm8
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +	movdqu	112(%rdi),%xmm9
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +	decl	%eax
        +.byte	102,15,56,222,241
        +	pxor	%xmm0,%xmm8
        +.byte	102,15,56,222,249
        +	pxor	%xmm0,%xmm9
        +	movups	(%rcx),%xmm0
        +.byte	102,68,15,56,222,193
        +.byte	102,68,15,56,222,201
        +	movups	16(%rcx),%xmm1
        +
        +	call	L$dec_loop8_enter
        +
        +	movups	(%rdi),%xmm1
        +	movups	16(%rdi),%xmm0
        +	xorps	-24(%rsp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%rdi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%rdi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%rdi),%xmm1
        +	xorps	%xmm0,%xmm6
        +	movups	80(%rdi),%xmm0
        +	xorps	%xmm1,%xmm7
        +	movups	96(%rdi),%xmm1
        +	xorps	%xmm0,%xmm8
        +	movups	112(%rdi),%xmm0
        +	xorps	%xmm1,%xmm9
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movl	%r10d,%eax
        +	movups	%xmm6,64(%rsi)
        +	movq	%r11,%rcx
        +	movups	%xmm7,80(%rsi)
        +	leaq	128(%rdi),%rdi
        +	movups	%xmm8,96(%rsi)
        +	leaq	112(%rsi),%rsi
        +	subq	$128,%rdx
        +	ja	L$cbc_dec_loop8
        +
        +	movaps	%xmm9,%xmm2
        +	movaps	%xmm0,%xmm9
        +	addq	$112,%rdx
        +	jle	L$cbc_dec_tail_collected
        +	movups	%xmm2,(%rsi)
        +	leal	1(%r10,%r10,1),%eax
        +	leaq	16(%rsi),%rsi
        +L$cbc_dec_tail:
        +	movups	(%rdi),%xmm2
        +	movaps	%xmm2,%xmm8
        +	cmpq	$16,%rdx
        +	jbe	L$cbc_dec_one
        +
        +	movups	16(%rdi),%xmm3
        +	movaps	%xmm3,%xmm7
        +	cmpq	$32,%rdx
        +	jbe	L$cbc_dec_two
        +
        +	movups	32(%rdi),%xmm4
        +	movaps	%xmm4,%xmm6
        +	cmpq	$48,%rdx
        +	jbe	L$cbc_dec_three
        +
        +	movups	48(%rdi),%xmm5
        +	cmpq	$64,%rdx
        +	jbe	L$cbc_dec_four
        +
        +	movups	64(%rdi),%xmm6
        +	cmpq	$80,%rdx
        +	jbe	L$cbc_dec_five
        +
        +	movups	80(%rdi),%xmm7
        +	cmpq	$96,%rdx
        +	jbe	L$cbc_dec_six
        +
        +	movups	96(%rdi),%xmm8
        +	movaps	%xmm9,-24(%rsp)
        +	call	_aesni_decrypt8
        +	movups	(%rdi),%xmm1
        +	movups	16(%rdi),%xmm0
        +	xorps	-24(%rsp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%rdi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%rdi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%rdi),%xmm1
        +	xorps	%xmm0,%xmm6
        +	movups	80(%rdi),%xmm0
        +	xorps	%xmm1,%xmm7
        +	movups	96(%rdi),%xmm9
        +	xorps	%xmm0,%xmm8
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	movups	%xmm7,80(%rsi)
        +	leaq	96(%rsi),%rsi
        +	movaps	%xmm8,%xmm2
        +	subq	$112,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_one:
        +	movups	(%rcx),%xmm0
        +	movups	16(%rcx),%xmm1
        +	leaq	32(%rcx),%rcx
        +	xorps	%xmm0,%xmm2
        +L$oop_dec1_16:
        +.byte	102,15,56,222,209
        +	decl	%eax
        +	movups	(%rcx),%xmm1
        +	leaq	16(%rcx),%rcx
        +	jnz	L$oop_dec1_16
        +
        +.byte	102,15,56,223,209
        +	xorps	%xmm9,%xmm2
        +	movaps	%xmm8,%xmm9
        +	subq	$16,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_decrypt3
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	movups	%xmm2,(%rsi)
        +	movaps	%xmm7,%xmm9
        +	movaps	%xmm3,%xmm2
        +	leaq	16(%rsi),%rsi
        +	subq	$32,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_three:
        +	call	_aesni_decrypt3
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm3,16(%rsi)
        +	movaps	%xmm6,%xmm9
        +	movaps	%xmm4,%xmm2
        +	leaq	32(%rsi),%rsi
        +	subq	$48,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_four:
        +	call	_aesni_decrypt4
        +	xorps	%xmm9,%xmm2
        +	movups	48(%rdi),%xmm9
        +	xorps	%xmm8,%xmm3
        +	movups	%xmm2,(%rsi)
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm3,16(%rsi)
        +	xorps	%xmm6,%xmm5
        +	movups	%xmm4,32(%rsi)
        +	movaps	%xmm5,%xmm2
        +	leaq	48(%rsi),%rsi
        +	subq	$64,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_five:
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_decrypt6
        +	movups	16(%rdi),%xmm1
        +	movups	32(%rdi),%xmm0
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	xorps	%xmm1,%xmm4
        +	movups	48(%rdi),%xmm1
        +	xorps	%xmm0,%xmm5
        +	movups	64(%rdi),%xmm9
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	leaq	64(%rsi),%rsi
        +	movaps	%xmm6,%xmm2
        +	subq	$80,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_six:
        +	call	_aesni_decrypt6
        +	movups	16(%rdi),%xmm1
        +	movups	32(%rdi),%xmm0
        +	xorps	%xmm9,%xmm2
        +	xorps	%xmm8,%xmm3
        +	xorps	%xmm1,%xmm4
        +	movups	48(%rdi),%xmm1
        +	xorps	%xmm0,%xmm5
        +	movups	64(%rdi),%xmm0
        +	xorps	%xmm1,%xmm6
        +	movups	80(%rdi),%xmm9
        +	xorps	%xmm0,%xmm7
        +	movups	%xmm2,(%rsi)
        +	movups	%xmm3,16(%rsi)
        +	movups	%xmm4,32(%rsi)
        +	movups	%xmm5,48(%rsi)
        +	movups	%xmm6,64(%rsi)
        +	leaq	80(%rsi),%rsi
        +	movaps	%xmm7,%xmm2
        +	subq	$96,%rdx
        +	jmp	L$cbc_dec_tail_collected
        +.p2align	4
        +L$cbc_dec_tail_collected:
        +	andq	$15,%rdx
        +	movups	%xmm9,(%r8)
        +	jnz	L$cbc_dec_tail_partial
        +	movups	%xmm2,(%rsi)
        +	jmp	L$cbc_dec_ret
        +.p2align	4
        +L$cbc_dec_tail_partial:
        +	movaps	%xmm2,-24(%rsp)
        +	movq	$16,%rcx
        +	movq	%rsi,%rdi
        +	subq	%rdx,%rcx
        +	leaq	-24(%rsp),%rsi
        +.long	0x9066A4F3
        +
        +
        +L$cbc_dec_ret:
        +L$cbc_ret:
        +	.byte	0xf3,0xc3
        +
        +.globl	_aesni_set_decrypt_key
        +
        +.p2align	4
        +_aesni_set_decrypt_key:
        +.byte	0x48,0x83,0xEC,0x08
        +
        +	call	__aesni_set_encrypt_key
        +	shll	$4,%esi
        +	testl	%eax,%eax
        +	jnz	L$dec_key_ret
        +	leaq	16(%rdx,%rsi,1),%rdi
        +
        +	movups	(%rdx),%xmm0
        +	movups	(%rdi),%xmm1
        +	movups	%xmm0,(%rdi)
        +	movups	%xmm1,(%rdx)
        +	leaq	16(%rdx),%rdx
        +	leaq	-16(%rdi),%rdi
        +
        +L$dec_key_inverse:
        +	movups	(%rdx),%xmm0
        +	movups	(%rdi),%xmm1
        +.byte	102,15,56,219,192
        +.byte	102,15,56,219,201
        +	leaq	16(%rdx),%rdx
        +	leaq	-16(%rdi),%rdi
        +	movups	%xmm0,16(%rdi)
        +	movups	%xmm1,-16(%rdx)
        +	cmpq	%rdx,%rdi
        +	ja	L$dec_key_inverse
        +
        +	movups	(%rdx),%xmm0
        +.byte	102,15,56,219,192
        +	movups	%xmm0,(%rdi)
        +L$dec_key_ret:
        +	addq	$8,%rsp
        +	.byte	0xf3,0xc3
        +L$SEH_end_set_decrypt_key:
        +
        +.globl	_aesni_set_encrypt_key
        +
        +.p2align	4
        +_aesni_set_encrypt_key:
        +__aesni_set_encrypt_key:
        +.byte	0x48,0x83,0xEC,0x08
        +
        +	movq	$-1,%rax
        +	testq	%rdi,%rdi
        +	jz	L$enc_key_ret
        +	testq	%rdx,%rdx
        +	jz	L$enc_key_ret
        +
        +	movups	(%rdi),%xmm0
        +	xorps	%xmm4,%xmm4
        +	leaq	16(%rdx),%rax
        +	cmpl	$256,%esi
        +	je	L$14rounds
        +	cmpl	$192,%esi
        +	je	L$12rounds
        +	cmpl	$128,%esi
        +	jne	L$bad_keybits
        +
        +L$10rounds:
        +	movl	$9,%esi
        +	movups	%xmm0,(%rdx)
        +.byte	102,15,58,223,200,1
        +	call	L$key_expansion_128_cold
        +.byte	102,15,58,223,200,2
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,4
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,8
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,16
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,32
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,64
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,128
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,27
        +	call	L$key_expansion_128
        +.byte	102,15,58,223,200,54
        +	call	L$key_expansion_128
        +	movups	%xmm0,(%rax)
        +	movl	%esi,80(%rax)
        +	xorl	%eax,%eax
        +	jmp	L$enc_key_ret
        +
        +.p2align	4
        +L$12rounds:
        +	movq	16(%rdi),%xmm2
        +	movl	$11,%esi
        +	movups	%xmm0,(%rdx)
        +.byte	102,15,58,223,202,1
        +	call	L$key_expansion_192a_cold
        +.byte	102,15,58,223,202,2
        +	call	L$key_expansion_192b
        +.byte	102,15,58,223,202,4
        +	call	L$key_expansion_192a
        +.byte	102,15,58,223,202,8
        +	call	L$key_expansion_192b
        +.byte	102,15,58,223,202,16
        +	call	L$key_expansion_192a
        +.byte	102,15,58,223,202,32
        +	call	L$key_expansion_192b
        +.byte	102,15,58,223,202,64
        +	call	L$key_expansion_192a
        +.byte	102,15,58,223,202,128
        +	call	L$key_expansion_192b
        +	movups	%xmm0,(%rax)
        +	movl	%esi,48(%rax)
        +	xorq	%rax,%rax
        +	jmp	L$enc_key_ret
        +
        +.p2align	4
        +L$14rounds:
        +	movups	16(%rdi),%xmm2
        +	movl	$13,%esi
        +	leaq	16(%rax),%rax
        +	movups	%xmm0,(%rdx)
        +	movups	%xmm2,16(%rdx)
        +.byte	102,15,58,223,202,1
        +	call	L$key_expansion_256a_cold
        +.byte	102,15,58,223,200,1
        +	call	L$key_expansion_256b
        +.byte	102,15,58,223,202,2
        +	call	L$key_expansion_256a
        +.byte	102,15,58,223,200,2
        +	call	L$key_expansion_256b
        +.byte	102,15,58,223,202,4
        +	call	L$key_expansion_256a
        +.byte	102,15,58,223,200,4
        +	call	L$key_expansion_256b
        +.byte	102,15,58,223,202,8
        +	call	L$key_expansion_256a
        +.byte	102,15,58,223,200,8
        +	call	L$key_expansion_256b
        +.byte	102,15,58,223,202,16
        +	call	L$key_expansion_256a
        +.byte	102,15,58,223,200,16
        +	call	L$key_expansion_256b
        +.byte	102,15,58,223,202,32
        +	call	L$key_expansion_256a
        +.byte	102,15,58,223,200,32
        +	call	L$key_expansion_256b
        +.byte	102,15,58,223,202,64
        +	call	L$key_expansion_256a
        +	movups	%xmm0,(%rax)
        +	movl	%esi,16(%rax)
        +	xorq	%rax,%rax
        +	jmp	L$enc_key_ret
        +
        +.p2align	4
        +L$bad_keybits:
        +	movq	$-2,%rax
        +L$enc_key_ret:
        +	addq	$8,%rsp
        +	.byte	0xf3,0xc3
        +L$SEH_end_set_encrypt_key:
        +
        +.p2align	4
        +L$key_expansion_128:
        +	movups	%xmm0,(%rax)
        +	leaq	16(%rax),%rax
        +L$key_expansion_128_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	.byte	0xf3,0xc3
        +
        +.p2align	4
        +L$key_expansion_192a:
        +	movups	%xmm0,(%rax)
        +	leaq	16(%rax),%rax
        +L$key_expansion_192a_cold:
        +	movaps	%xmm2,%xmm5
        +L$key_expansion_192b_warm:
        +	shufps	$16,%xmm0,%xmm4
        +	movdqa	%xmm2,%xmm3
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	pslldq	$4,%xmm3
        +	xorps	%xmm4,%xmm0
        +	pshufd	$85,%xmm1,%xmm1
        +	pxor	%xmm3,%xmm2
        +	pxor	%xmm1,%xmm0
        +	pshufd	$255,%xmm0,%xmm3
        +	pxor	%xmm3,%xmm2
        +	.byte	0xf3,0xc3
        +
        +.p2align	4
        +L$key_expansion_192b:
        +	movaps	%xmm0,%xmm3
        +	shufps	$68,%xmm0,%xmm5
        +	movups	%xmm5,(%rax)
        +	shufps	$78,%xmm2,%xmm3
        +	movups	%xmm3,16(%rax)
        +	leaq	32(%rax),%rax
        +	jmp	L$key_expansion_192b_warm
        +
        +.p2align	4
        +L$key_expansion_256a:
        +	movups	%xmm2,(%rax)
        +	leaq	16(%rax),%rax
        +L$key_expansion_256a_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	.byte	0xf3,0xc3
        +
        +.p2align	4
        +L$key_expansion_256b:
        +	movups	%xmm0,(%rax)
        +	leaq	16(%rax),%rax
        +
        +	shufps	$16,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$140,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$170,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm2
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	6
        +L$bswap_mask:
        +.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
        +L$increment32:
        +.long	6,6,6,0
        +L$increment64:
        +.long	1,0,0,0
        +L$xts_magic:
        +.long	0x87,0,1,0
        +
        +.byte	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.p2align	6
        diff --git a/vendor/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s
        new file mode 100644
        index 000000000..00c529a07
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/bn/modexp512-x86_64.s
        @@ -0,0 +1,1775 @@
        +.text
        +
        +
        +
        +.p2align	4
        +MULADD_128x512:
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%r8,0(%rcx)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	8(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	movq	%r9,8(%rcx)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%r9
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +mont_reduce:
        +	leaq	192(%rsp),%rdi
        +	movq	32(%rsp),%rsi
        +	addq	$576,%rsi
        +	leaq	520(%rsp),%rcx
        +
        +	movq	96(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	movq	(%rcx),%r8
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%r8,0(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	movq	8(%rcx),%r9
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	movq	16(%rcx),%r10
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	movq	24(%rcx),%r11
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	movq	32(%rcx),%r12
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	movq	40(%rcx),%r13
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	movq	48(%rcx),%r14
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	movq	56(%rcx),%r15
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	104(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	movq	%r9,8(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%r9
        +	movq	112(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%r10,16(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +	movq	120(%rcx),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,24(%rdi)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	xorq	%rax,%rax
        +
        +	addq	64(%rcx),%r8
        +	adcq	72(%rcx),%r9
        +	adcq	80(%rcx),%r10
        +	adcq	88(%rcx),%r11
        +	adcq	$0,%rax
        +
        +
        +
        +
        +	movq	%r8,64(%rdi)
        +	movq	%r9,72(%rdi)
        +	movq	%r10,%rbp
        +	movq	%r11,88(%rdi)
        +
        +	movq	%rax,384(%rsp)
        +
        +	movq	0(%rdi),%r8
        +	movq	8(%rdi),%r9
        +	movq	16(%rdi),%r10
        +	movq	24(%rdi),%r11
        +
        +
        +
        +
        +
        +
        +
        +
        +	addq	$80,%rdi
        +
        +	addq	$64,%rsi
        +	leaq	296(%rsp),%rcx
        +
        +	call	MULADD_128x512
        +
        +
        +	movq	384(%rsp),%rax
        +
        +
        +	addq	-16(%rdi),%r8
        +	adcq	-8(%rdi),%r9
        +	movq	%r8,64(%rcx)
        +	movq	%r9,72(%rcx)
        +
        +	adcq	%rax,%rax
        +	movq	%rax,384(%rsp)
        +
        +	leaq	192(%rsp),%rdi
        +	addq	$64,%rsi
        +
        +
        +
        +
        +
        +	movq	(%rsi),%r8
        +	movq	8(%rsi),%rbx
        +
        +	movq	(%rcx),%rax
        +	mulq	%r8
        +	movq	%rax,%rbp
        +	movq	%rdx,%r9
        +
        +	movq	8(%rcx),%rax
        +	mulq	%r8
        +	addq	%rax,%r9
        +
        +	movq	(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r9
        +
        +	movq	%r9,8(%rdi)
        +
        +
        +	subq	$192,%rsi
        +
        +	movq	(%rcx),%r8
        +	movq	8(%rcx),%r9
        +
        +	call	MULADD_128x512
        +
        +
        +
        +
        +
        +	movq	0(%rsi),%rax
        +	movq	8(%rsi),%rbx
        +	movq	16(%rsi),%rdi
        +	movq	24(%rsi),%rdx
        +
        +
        +	movq	384(%rsp),%rbp
        +
        +	addq	64(%rcx),%r8
        +	adcq	72(%rcx),%r9
        +
        +
        +	adcq	%rbp,%rbp
        +
        +
        +
        +	shlq	$3,%rbp
        +	movq	32(%rsp),%rcx
        +	addq	%rcx,%rbp
        +
        +
        +	xorq	%rsi,%rsi
        +
        +	addq	0(%rbp),%r10
        +	adcq	64(%rbp),%r11
        +	adcq	128(%rbp),%r12
        +	adcq	192(%rbp),%r13
        +	adcq	256(%rbp),%r14
        +	adcq	320(%rbp),%r15
        +	adcq	384(%rbp),%r8
        +	adcq	448(%rbp),%r9
        +
        +
        +
        +	sbbq	$0,%rsi
        +
        +
        +	andq	%rsi,%rax
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdi
        +	andq	%rsi,%rdx
        +
        +	movq	$1,%rbp
        +	subq	%rax,%r10
        +	sbbq	%rbx,%r11
        +	sbbq	%rdi,%r12
        +	sbbq	%rdx,%r13
        +
        +
        +
        +
        +	sbbq	$0,%rbp
        +
        +
        +
        +	addq	$512,%rcx
        +	movq	32(%rcx),%rax
        +	movq	40(%rcx),%rbx
        +	movq	48(%rcx),%rdi
        +	movq	56(%rcx),%rdx
        +
        +
        +
        +	andq	%rsi,%rax
        +	andq	%rsi,%rbx
        +	andq	%rsi,%rdi
        +	andq	%rsi,%rdx
        +
        +
        +
        +	subq	$1,%rbp
        +
        +	sbbq	%rax,%r14
        +	sbbq	%rbx,%r15
        +	sbbq	%rdi,%r8
        +	sbbq	%rdx,%r9
        +
        +
        +
        +	movq	144(%rsp),%rsi
        +	movq	%r10,0(%rsi)
        +	movq	%r11,8(%rsi)
        +	movq	%r12,16(%rsi)
        +	movq	%r13,24(%rsi)
        +	movq	%r14,32(%rsi)
        +	movq	%r15,40(%rsi)
        +	movq	%r8,48(%rsi)
        +	movq	%r9,56(%rsi)
        +
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +mont_mul_a3b:
        +
        +
        +
        +
        +	movq	0(%rdi),%rbp
        +
        +	movq	%r10,%rax
        +	mulq	%rbp
        +	movq	%rax,520(%rsp)
        +	movq	%rdx,%r10
        +	movq	%r11,%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	movq	%r12,%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r12
        +	movq	%r13,%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +	movq	%r14,%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%r14
        +	movq	%r15,%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%r15
        +	movq	%r8,%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	%r9,%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%r9
        +	movq	8(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%r10,528(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +	movq	16(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,536(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	movq	24(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,544(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r12
        +	movq	32(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,552(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +	movq	40(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	movq	%r14,560(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%r14
        +	movq	48(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%r15,568(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	addq	%rbx,%r8
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%r15
        +	movq	56(%rdi),%rbp
        +	movq	0(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r8
        +	adcq	$0,%rdx
        +	movq	%r8,576(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r9
        +	adcq	$0,%rdx
        +	addq	%rbx,%r9
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	16(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	addq	%rbx,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	24(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%rbx,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	32(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%rbx,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	40(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%rbx,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	48(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%rbx,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%rbx
        +
        +	movq	56(%rsi),%rax
        +	mulq	%rbp
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%rbx,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%r8
        +	movq	%r9,584(%rsp)
        +	movq	%r10,592(%rsp)
        +	movq	%r11,600(%rsp)
        +	movq	%r12,608(%rsp)
        +	movq	%r13,616(%rsp)
        +	movq	%r14,624(%rsp)
        +	movq	%r15,632(%rsp)
        +	movq	%r8,640(%rsp)
        +
        +
        +
        +
        +
        +	jmp	mont_reduce
        +
        +
        +
        +
        +.p2align	4
        +sqr_reduce:
        +	movq	16(%rsp),%rcx
        +
        +
        +
        +	movq	%r10,%rbx
        +
        +	movq	%r11,%rax
        +	mulq	%rbx
        +	movq	%rax,528(%rsp)
        +	movq	%rdx,%r10
        +	movq	%r12,%rax
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +	movq	%r13,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r12
        +	movq	%r14,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +	movq	%r15,%rax
        +	mulq	%rbx
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%rdx,%r14
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	movq	%rdx,%r15
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%rdx,%rsi
        +
        +	movq	%r10,536(%rsp)
        +
        +
        +
        +
        +
        +	movq	8(%rcx),%rbx
        +
        +	movq	16(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,544(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	24(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%r10,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,552(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	32(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%r10,%r14
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%r10,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%rsi
        +	adcq	$0,%rdx
        +	addq	%r10,%rsi
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r11
        +
        +
        +
        +
        +	movq	16(%rcx),%rbx
        +
        +	movq	24(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,560(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	32(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r14
        +	adcq	$0,%rdx
        +	addq	%r10,%r14
        +	adcq	$0,%rdx
        +	movq	%r14,568(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%r10,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%rsi
        +	adcq	$0,%rdx
        +	addq	%r10,%rsi
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%r10,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r12
        +
        +
        +
        +
        +
        +	movq	24(%rcx),%rbx
        +
        +	movq	32(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%r15,576(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%rsi
        +	adcq	$0,%rdx
        +	addq	%r10,%rsi
        +	adcq	$0,%rdx
        +	movq	%rsi,584(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%r10,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%r10,%r12
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r15
        +
        +
        +
        +
        +	movq	32(%rcx),%rbx
        +
        +	movq	40(%rcx),%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,592(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	addq	%r10,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,600(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	addq	%r10,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%r11
        +
        +
        +
        +
        +	movq	40(%rcx),%rbx
        +
        +	movq	%r8,%rax
        +	mulq	%rbx
        +	addq	%rax,%r15
        +	adcq	$0,%rdx
        +	movq	%r15,608(%rsp)
        +
        +	movq	%rdx,%r10
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	adcq	$0,%rdx
        +	addq	%r10,%r11
        +	adcq	$0,%rdx
        +	movq	%r11,616(%rsp)
        +
        +	movq	%rdx,%r12
        +
        +
        +
        +
        +	movq	%r8,%rbx
        +
        +	movq	%r9,%rax
        +	mulq	%rbx
        +	addq	%rax,%r12
        +	adcq	$0,%rdx
        +	movq	%r12,624(%rsp)
        +
        +	movq	%rdx,632(%rsp)
        +
        +
        +	movq	528(%rsp),%r10
        +	movq	536(%rsp),%r11
        +	movq	544(%rsp),%r12
        +	movq	552(%rsp),%r13
        +	movq	560(%rsp),%r14
        +	movq	568(%rsp),%r15
        +
        +	movq	24(%rcx),%rax
        +	mulq	%rax
        +	movq	%rax,%rdi
        +	movq	%rdx,%r8
        +
        +	addq	%r10,%r10
        +	adcq	%r11,%r11
        +	adcq	%r12,%r12
        +	adcq	%r13,%r13
        +	adcq	%r14,%r14
        +	adcq	%r15,%r15
        +	adcq	$0,%r8
        +
        +	movq	0(%rcx),%rax
        +	mulq	%rax
        +	movq	%rax,520(%rsp)
        +	movq	%rdx,%rbx
        +
        +	movq	8(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbx,%r10
        +	adcq	%rax,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbx
        +	movq	%r10,528(%rsp)
        +	movq	%r11,536(%rsp)
        +
        +	movq	16(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbx,%r12
        +	adcq	%rax,%r13
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbx
        +
        +	movq	%r12,544(%rsp)
        +	movq	%r13,552(%rsp)
        +
        +	xorq	%rbp,%rbp
        +	addq	%rbx,%r14
        +	adcq	%rdi,%r15
        +	adcq	$0,%rbp
        +
        +	movq	%r14,560(%rsp)
        +	movq	%r15,568(%rsp)
        +
        +
        +
        +
        +	movq	576(%rsp),%r10
        +	movq	584(%rsp),%r11
        +	movq	592(%rsp),%r12
        +	movq	600(%rsp),%r13
        +	movq	608(%rsp),%r14
        +	movq	616(%rsp),%r15
        +	movq	624(%rsp),%rdi
        +	movq	632(%rsp),%rsi
        +
        +	movq	%r9,%rax
        +	mulq	%rax
        +	movq	%rax,%r9
        +	movq	%rdx,%rbx
        +
        +	addq	%r10,%r10
        +	adcq	%r11,%r11
        +	adcq	%r12,%r12
        +	adcq	%r13,%r13
        +	adcq	%r14,%r14
        +	adcq	%r15,%r15
        +	adcq	%rdi,%rdi
        +	adcq	%rsi,%rsi
        +	adcq	$0,%rbx
        +
        +	addq	%rbp,%r10
        +
        +	movq	32(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%r8,%r10
        +	adcq	%rax,%r11
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbp
        +
        +	movq	%r10,576(%rsp)
        +	movq	%r11,584(%rsp)
        +
        +	movq	40(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbp,%r12
        +	adcq	%rax,%r13
        +	adcq	$0,%rdx
        +
        +	movq	%rdx,%rbp
        +
        +	movq	%r12,592(%rsp)
        +	movq	%r13,600(%rsp)
        +
        +	movq	48(%rcx),%rax
        +	mulq	%rax
        +
        +	addq	%rbp,%r14
        +	adcq	%rax,%r15
        +	adcq	$0,%rdx
        +
        +	movq	%r14,608(%rsp)
        +	movq	%r15,616(%rsp)
        +
        +	addq	%rdx,%rdi
        +	adcq	%r9,%rsi
        +	adcq	$0,%rbx
        +
        +	movq	%rdi,624(%rsp)
        +	movq	%rsi,632(%rsp)
        +	movq	%rbx,640(%rsp)
        +
        +	jmp	mont_reduce
        +
        +
        +
        +.globl	_mod_exp_512
        +
        +_mod_exp_512:
        +	pushq	%rbp
        +	pushq	%rbx
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +
        +	movq	%rsp,%r8
        +	subq	$2688,%rsp
        +	andq	$-64,%rsp
        +
        +
        +	movq	%r8,0(%rsp)
        +	movq	%rdi,8(%rsp)
        +	movq	%rsi,16(%rsp)
        +	movq	%rcx,24(%rsp)
        +L$body:
        +
        +
        +
        +	pxor	%xmm4,%xmm4
        +	movdqu	0(%rsi),%xmm0
        +	movdqu	16(%rsi),%xmm1
        +	movdqu	32(%rsi),%xmm2
        +	movdqu	48(%rsi),%xmm3
        +	movdqa	%xmm4,512(%rsp)
        +	movdqa	%xmm4,528(%rsp)
        +	movdqa	%xmm4,608(%rsp)
        +	movdqa	%xmm4,624(%rsp)
        +	movdqa	%xmm0,544(%rsp)
        +	movdqa	%xmm1,560(%rsp)
        +	movdqa	%xmm2,576(%rsp)
        +	movdqa	%xmm3,592(%rsp)
        +
        +
        +	movdqu	0(%rdx),%xmm0
        +	movdqu	16(%rdx),%xmm1
        +	movdqu	32(%rdx),%xmm2
        +	movdqu	48(%rdx),%xmm3
        +
        +	leaq	384(%rsp),%rbx
        +	movq	%rbx,136(%rsp)
        +	call	mont_reduce
        +
        +
        +	leaq	448(%rsp),%rcx
        +	xorq	%rax,%rax
        +	movq	%rax,0(%rcx)
        +	movq	%rax,8(%rcx)
        +	movq	%rax,24(%rcx)
        +	movq	%rax,32(%rcx)
        +	movq	%rax,40(%rcx)
        +	movq	%rax,48(%rcx)
        +	movq	%rax,56(%rcx)
        +	movq	%rax,128(%rsp)
        +	movq	$1,16(%rcx)
        +
        +	leaq	640(%rsp),%rbp
        +	movq	%rcx,%rsi
        +	movq	%rbp,%rdi
        +	movq	$8,%rax
        +loop_0:
        +	movq	(%rcx),%rbx
        +	movw	%bx,(%rdi)
        +	shrq	$16,%rbx
        +	movw	%bx,64(%rdi)
        +	shrq	$16,%rbx
        +	movw	%bx,128(%rdi)
        +	shrq	$16,%rbx
        +	movw	%bx,192(%rdi)
        +	leaq	8(%rcx),%rcx
        +	leaq	256(%rdi),%rdi
        +	decq	%rax
        +	jnz	loop_0
        +	movq	$31,%rax
        +	movq	%rax,32(%rsp)
        +	movq	%rbp,40(%rsp)
        +
        +	movq	%rsi,136(%rsp)
        +	movq	0(%rsi),%r10
        +	movq	8(%rsi),%r11
        +	movq	16(%rsi),%r12
        +	movq	24(%rsi),%r13
        +	movq	32(%rsi),%r14
        +	movq	40(%rsi),%r15
        +	movq	48(%rsi),%r8
        +	movq	56(%rsi),%r9
        +init_loop:
        +	leaq	384(%rsp),%rdi
        +	call	mont_mul_a3b
        +	leaq	448(%rsp),%rsi
        +	movq	40(%rsp),%rbp
        +	addq	$2,%rbp
        +	movq	%rbp,40(%rsp)
        +	movq	%rsi,%rcx
        +	movq	$8,%rax
        +loop_1:
        +	movq	(%rcx),%rbx
        +	movw	%bx,(%rbp)
        +	shrq	$16,%rbx
        +	movw	%bx,64(%rbp)
        +	shrq	$16,%rbx
        +	movw	%bx,128(%rbp)
        +	shrq	$16,%rbx
        +	movw	%bx,192(%rbp)
        +	leaq	8(%rcx),%rcx
        +	leaq	256(%rbp),%rbp
        +	decq	%rax
        +	jnz	loop_1
        +	movq	32(%rsp),%rax
        +	subq	$1,%rax
        +	movq	%rax,32(%rsp)
        +	jne	init_loop
        +
        +
        +
        +	movdqa	%xmm0,64(%rsp)
        +	movdqa	%xmm1,80(%rsp)
        +	movdqa	%xmm2,96(%rsp)
        +	movdqa	%xmm3,112(%rsp)
        +
        +
        +
        +
        +
        +	movl	126(%rsp),%eax
        +	movq	%rax,%rdx
        +	shrq	$11,%rax
        +	andl	$2047,%edx
        +	movl	%edx,126(%rsp)
        +	leaq	640(%rsp,%rax,2),%rsi
        +	movq	8(%rsp),%rdx
        +	movq	$4,%rbp
        +loop_2:
        +	movzwq	192(%rsi),%rbx
        +	movzwq	448(%rsi),%rax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	128(%rsi),%bx
        +	movw	384(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	64(%rsi),%bx
        +	movw	320(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	0(%rsi),%bx
        +	movw	256(%rsi),%ax
        +	movq	%rbx,0(%rdx)
        +	movq	%rax,8(%rdx)
        +	leaq	512(%rsi),%rsi
        +	leaq	16(%rdx),%rdx
        +	subq	$1,%rbp
        +	jnz	loop_2
        +	movq	$505,48(%rsp)
        +
        +	movq	8(%rsp),%rcx
        +	movq	%rcx,136(%rsp)
        +	movq	0(%rcx),%r10
        +	movq	8(%rcx),%r11
        +	movq	16(%rcx),%r12
        +	movq	24(%rcx),%r13
        +	movq	32(%rcx),%r14
        +	movq	40(%rcx),%r15
        +	movq	48(%rcx),%r8
        +	movq	56(%rcx),%r9
        +	jmp	sqr_2
        +
        +main_loop_a3b:
        +	call	sqr_reduce
        +	call	sqr_reduce
        +	call	sqr_reduce
        +sqr_2:
        +	call	sqr_reduce
        +	call	sqr_reduce
        +
        +
        +
        +	movq	48(%rsp),%rcx
        +	movq	%rcx,%rax
        +	shrq	$4,%rax
        +	movl	64(%rsp,%rax,2),%edx
        +	andq	$15,%rcx
        +	shrq	%cl,%rdx
        +	andq	$31,%rdx
        +
        +	leaq	640(%rsp,%rdx,2),%rsi
        +	leaq	448(%rsp),%rdx
        +	movq	%rdx,%rdi
        +	movq	$4,%rbp
        +loop_3:
        +	movzwq	192(%rsi),%rbx
        +	movzwq	448(%rsi),%rax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	128(%rsi),%bx
        +	movw	384(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	64(%rsi),%bx
        +	movw	320(%rsi),%ax
        +	shlq	$16,%rbx
        +	shlq	$16,%rax
        +	movw	0(%rsi),%bx
        +	movw	256(%rsi),%ax
        +	movq	%rbx,0(%rdx)
        +	movq	%rax,8(%rdx)
        +	leaq	512(%rsi),%rsi
        +	leaq	16(%rdx),%rdx
        +	subq	$1,%rbp
        +	jnz	loop_3
        +	movq	8(%rsp),%rsi
        +	call	mont_mul_a3b
        +
        +
        +
        +	movq	48(%rsp),%rcx
        +	subq	$5,%rcx
        +	movq	%rcx,48(%rsp)
        +	jge	main_loop_a3b
        +
        +
        +
        +end_main_loop_a3b:
        +
        +
        +	movq	8(%rsp),%rdx
        +	pxor	%xmm4,%xmm4
        +	movdqu	0(%rdx),%xmm0
        +	movdqu	16(%rdx),%xmm1
        +	movdqu	32(%rdx),%xmm2
        +	movdqu	48(%rdx),%xmm3
        +	movdqa	%xmm4,576(%rsp)
        +	movdqa	%xmm4,592(%rsp)
        +	movdqa	%xmm4,608(%rsp)
        +	movdqa	%xmm4,624(%rsp)
        +	movdqa	%xmm0,512(%rsp)
        +	movdqa	%xmm1,528(%rsp)
        +	movdqa	%xmm2,544(%rsp)
        +	movdqa	%xmm3,560(%rsp)
        +	call	mont_reduce
        +
        +
        +
        +	movq	8(%rsp),%rax
        +	movq	0(%rax),%r8
        +	movq	8(%rax),%r9
        +	movq	16(%rax),%r10
        +	movq	24(%rax),%r11
        +	movq	32(%rax),%r12
        +	movq	40(%rax),%r13
        +	movq	48(%rax),%r14
        +	movq	56(%rax),%r15
        +
        +
        +	movq	24(%rsp),%rbx
        +	addq	$512,%rbx
        +
        +	subq	0(%rbx),%r8
        +	sbbq	8(%rbx),%r9
        +	sbbq	16(%rbx),%r10
        +	sbbq	24(%rbx),%r11
        +	sbbq	32(%rbx),%r12
        +	sbbq	40(%rbx),%r13
        +	sbbq	48(%rbx),%r14
        +	sbbq	56(%rbx),%r15
        +
        +
        +	movq	0(%rax),%rsi
        +	movq	8(%rax),%rdi
        +	movq	16(%rax),%rcx
        +	movq	24(%rax),%rdx
        +	cmovncq	%r8,%rsi
        +	cmovncq	%r9,%rdi
        +	cmovncq	%r10,%rcx
        +	cmovncq	%r11,%rdx
        +	movq	%rsi,0(%rax)
        +	movq	%rdi,8(%rax)
        +	movq	%rcx,16(%rax)
        +	movq	%rdx,24(%rax)
        +
        +	movq	32(%rax),%rsi
        +	movq	40(%rax),%rdi
        +	movq	48(%rax),%rcx
        +	movq	56(%rax),%rdx
        +	cmovncq	%r12,%rsi
        +	cmovncq	%r13,%rdi
        +	cmovncq	%r14,%rcx
        +	cmovncq	%r15,%rdx
        +	movq	%rsi,32(%rax)
        +	movq	%rdi,40(%rax)
        +	movq	%rcx,48(%rax)
        +	movq	%rdx,56(%rax)
        +
        +	movq	0(%rsp),%rsi
        +	movq	0(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbx
        +	movq	40(%rsi),%rbp
        +	leaq	48(%rsi),%rsp
        +L$epilogue:
        +	.byte	0xf3,0xc3
        diff --git a/vendor/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s b/vendor/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s
        new file mode 100644
        index 000000000..ece106c49
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/bn/x86_64-mont.s
        @@ -0,0 +1,1375 @@
        +.text
        +
        +
        +.globl	_bn_mul_mont
        +
        +.p2align	4
        +_bn_mul_mont:
        +	testl	$3,%r9d
        +	jnz	L$mul_enter
        +	cmpl	$8,%r9d
        +	jb	L$mul_enter
        +	cmpq	%rsi,%rdx
        +	jne	L$mul4x_enter
        +	jmp	L$sqr4x_enter
        +
        +.p2align	4
        +L$mul_enter:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	movl	%r9d,%r9d
        +	leaq	2(%r9),%r10
        +	movq	%rsp,%r11
        +	negq	%r10
        +	leaq	(%rsp,%r10,8),%rsp
        +	andq	$-1024,%rsp
        +
        +	movq	%r11,8(%rsp,%r9,8)
        +L$mul_body:
        +	movq	%rdx,%r12
        +	movq	(%r8),%r8
        +	movq	(%r12),%rbx
        +	movq	(%rsi),%rax
        +
        +	xorq	%r14,%r14
        +	xorq	%r15,%r15
        +
        +	movq	%r8,%rbp
        +	mulq	%rbx
        +	movq	%rax,%r10
        +	movq	(%rcx),%rax
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r13
        +
        +	leaq	1(%r15),%r15
        +	jmp	L$1st_enter
        +
        +.p2align	4
        +L$1st:
        +	addq	%rax,%r13
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%r13
        +	movq	%r10,%r11
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +L$1st_enter:
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	leaq	1(%r15),%r15
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	cmpq	%r9,%r15
        +	jne	L$1st
        +
        +	addq	%rax,%r13
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +	movq	%r10,%r11
        +
        +	xorq	%rdx,%rdx
        +	addq	%r11,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r9,8)
        +	movq	%rdx,(%rsp,%r9,8)
        +
        +	leaq	1(%r14),%r14
        +	jmp	L$outer
        +.p2align	4
        +L$outer:
        +	movq	(%r12,%r14,8),%rbx
        +	xorq	%r15,%r15
        +	movq	%r8,%rbp
        +	movq	(%rsp),%r10
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx),%rax
        +	adcq	$0,%rdx
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	8(%rsp),%r10
        +	movq	%rdx,%r13
        +
        +	leaq	1(%r15),%r15
        +	jmp	L$inner_enter
        +
        +.p2align	4
        +L$inner:
        +	addq	%rax,%r13
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	movq	(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +L$inner_enter:
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%r10
        +	movq	%rdx,%r11
        +	adcq	$0,%r11
        +	leaq	1(%r15),%r15
        +
        +	mulq	%rbp
        +	cmpq	%r9,%r15
        +	jne	L$inner
        +
        +	addq	%rax,%r13
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	movq	(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%r13,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	xorq	%rdx,%rdx
        +	addq	%r11,%r13
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r9,8)
        +	movq	%rdx,(%rsp,%r9,8)
        +
        +	leaq	1(%r14),%r14
        +	cmpq	%r9,%r14
        +	jl	L$outer
        +
        +	xorq	%r14,%r14
        +	movq	(%rsp),%rax
        +	leaq	(%rsp),%rsi
        +	movq	%r9,%r15
        +	jmp	L$sub
        +.p2align	4
        +L$sub:	sbbq	(%rcx,%r14,8),%rax
        +	movq	%rax,(%rdi,%r14,8)
        +	movq	8(%rsi,%r14,8),%rax
        +	leaq	1(%r14),%r14
        +	decq	%r15
        +	jnz	L$sub
        +
        +	sbbq	$0,%rax
        +	xorq	%r14,%r14
        +	andq	%rax,%rsi
        +	notq	%rax
        +	movq	%rdi,%rcx
        +	andq	%rax,%rcx
        +	movq	%r9,%r15
        +	orq	%rcx,%rsi
        +.p2align	4
        +L$copy:
        +	movq	(%rsi,%r14,8),%rax
        +	movq	%r14,(%rsp,%r14,8)
        +	movq	%rax,(%rdi,%r14,8)
        +	leaq	1(%r14),%r14
        +	subq	$1,%r15
        +	jnz	L$copy
        +
        +	movq	8(%rsp,%r9,8),%rsi
        +	movq	$1,%rax
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$mul_epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +bn_mul4x_mont:
        +L$mul4x_enter:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	movl	%r9d,%r9d
        +	leaq	4(%r9),%r10
        +	movq	%rsp,%r11
        +	negq	%r10
        +	leaq	(%rsp,%r10,8),%rsp
        +	andq	$-1024,%rsp
        +
        +	movq	%r11,8(%rsp,%r9,8)
        +L$mul4x_body:
        +	movq	%rdi,16(%rsp,%r9,8)
        +	movq	%rdx,%r12
        +	movq	(%r8),%r8
        +	movq	(%r12),%rbx
        +	movq	(%rsi),%rax
        +
        +	xorq	%r14,%r14
        +	xorq	%r15,%r15
        +
        +	movq	%r8,%rbp
        +	mulq	%rbx
        +	movq	%rax,%r10
        +	movq	(%rcx),%rax
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	16(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	leaq	4(%r15),%r15
        +	adcq	$0,%rdx
        +	movq	%rdi,(%rsp)
        +	movq	%rdx,%r13
        +	jmp	L$1st4x
        +.p2align	4
        +L$1st4x:
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	leaq	4(%r15),%r15
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	-16(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-32(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +	cmpq	%r9,%r15
        +	jl	L$1st4x
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	xorq	%rdi,%rdi
        +	addq	%r10,%r13
        +	adcq	$0,%rdi
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdi,(%rsp,%r15,8)
        +
        +	leaq	1(%r14),%r14
        +.p2align	2
        +L$outer4x:
        +	movq	(%r12,%r14,8),%rbx
        +	xorq	%r15,%r15
        +	movq	(%rsp),%r10
        +	movq	%r8,%rbp
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx),%rax
        +	adcq	$0,%rdx
        +
        +	imulq	%r10,%rbp
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r10
        +	movq	8(%rsi),%rax
        +	adcq	$0,%rdx
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx),%rax
        +	adcq	$0,%rdx
        +	addq	8(%rsp),%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	16(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	leaq	4(%r15),%r15
        +	adcq	$0,%rdx
        +	movq	%rdi,(%rsp)
        +	movq	%rdx,%r13
        +	jmp	L$inner4x
        +.p2align	4
        +L$inner4x:
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-16(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-8(%rsp,%r15,8),%r11
        +	adcq	$0,%rdx
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	8(%rsp,%r15,8),%r11
        +	adcq	$0,%rdx
        +	leaq	4(%r15),%r15
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	-16(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-32(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +	cmpq	%r9,%r15
        +	jl	L$inner4x
        +
        +	mulq	%rbx
        +	addq	%rax,%r10
        +	movq	-16(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-16(%rsp,%r15,8),%r10
        +	adcq	$0,%rdx
        +	movq	%rdx,%r11
        +
        +	mulq	%rbp
        +	addq	%rax,%r13
        +	movq	-8(%rsi,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	%r10,%r13
        +	adcq	$0,%rdx
        +	movq	%r13,-24(%rsp,%r15,8)
        +	movq	%rdx,%rdi
        +
        +	mulq	%rbx
        +	addq	%rax,%r11
        +	movq	-8(%rcx,%r15,8),%rax
        +	adcq	$0,%rdx
        +	addq	-8(%rsp,%r15,8),%r11
        +	adcq	$0,%rdx
        +	leaq	1(%r14),%r14
        +	movq	%rdx,%r10
        +
        +	mulq	%rbp
        +	addq	%rax,%rdi
        +	movq	(%rsi),%rax
        +	adcq	$0,%rdx
        +	addq	%r11,%rdi
        +	adcq	$0,%rdx
        +	movq	%rdi,-16(%rsp,%r15,8)
        +	movq	%rdx,%r13
        +
        +	xorq	%rdi,%rdi
        +	addq	%r10,%r13
        +	adcq	$0,%rdi
        +	addq	(%rsp,%r9,8),%r13
        +	adcq	$0,%rdi
        +	movq	%r13,-8(%rsp,%r15,8)
        +	movq	%rdi,(%rsp,%r15,8)
        +
        +	cmpq	%r9,%r14
        +	jl	L$outer4x
        +	movq	16(%rsp,%r9,8),%rdi
        +	movq	0(%rsp),%rax
        +	pxor	%xmm0,%xmm0
        +	movq	8(%rsp),%rdx
        +	shrq	$2,%r9
        +	leaq	(%rsp),%rsi
        +	xorq	%r14,%r14
        +
        +	subq	0(%rcx),%rax
        +	movq	16(%rsi),%rbx
        +	movq	24(%rsi),%rbp
        +	sbbq	8(%rcx),%rdx
        +	leaq	-1(%r9),%r15
        +	jmp	L$sub4x
        +.p2align	4
        +L$sub4x:
        +	movq	%rax,0(%rdi,%r14,8)
        +	movq	%rdx,8(%rdi,%r14,8)
        +	sbbq	16(%rcx,%r14,8),%rbx
        +	movq	32(%rsi,%r14,8),%rax
        +	movq	40(%rsi,%r14,8),%rdx
        +	sbbq	24(%rcx,%r14,8),%rbp
        +	movq	%rbx,16(%rdi,%r14,8)
        +	movq	%rbp,24(%rdi,%r14,8)
        +	sbbq	32(%rcx,%r14,8),%rax
        +	movq	48(%rsi,%r14,8),%rbx
        +	movq	56(%rsi,%r14,8),%rbp
        +	sbbq	40(%rcx,%r14,8),%rdx
        +	leaq	4(%r14),%r14
        +	decq	%r15
        +	jnz	L$sub4x
        +
        +	movq	%rax,0(%rdi,%r14,8)
        +	movq	32(%rsi,%r14,8),%rax
        +	sbbq	16(%rcx,%r14,8),%rbx
        +	movq	%rdx,8(%rdi,%r14,8)
        +	sbbq	24(%rcx,%r14,8),%rbp
        +	movq	%rbx,16(%rdi,%r14,8)
        +
        +	sbbq	$0,%rax
        +	movq	%rbp,24(%rdi,%r14,8)
        +	xorq	%r14,%r14
        +	andq	%rax,%rsi
        +	notq	%rax
        +	movq	%rdi,%rcx
        +	andq	%rax,%rcx
        +	leaq	-1(%r9),%r15
        +	orq	%rcx,%rsi
        +
        +	movdqu	(%rsi),%xmm1
        +	movdqa	%xmm0,(%rsp)
        +	movdqu	%xmm1,(%rdi)
        +	jmp	L$copy4x
        +.p2align	4
        +L$copy4x:
        +	movdqu	16(%rsi,%r14,1),%xmm2
        +	movdqu	32(%rsi,%r14,1),%xmm1
        +	movdqa	%xmm0,16(%rsp,%r14,1)
        +	movdqu	%xmm2,16(%rdi,%r14,1)
        +	movdqa	%xmm0,32(%rsp,%r14,1)
        +	movdqu	%xmm1,32(%rdi,%r14,1)
        +	leaq	32(%r14),%r14
        +	decq	%r15
        +	jnz	L$copy4x
        +
        +	shlq	$2,%r9
        +	movdqu	16(%rsi,%r14,1),%xmm2
        +	movdqa	%xmm0,16(%rsp,%r14,1)
        +	movdqu	%xmm2,16(%rdi,%r14,1)
        +	movq	8(%rsp,%r9,8),%rsi
        +	movq	$1,%rax
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$mul4x_epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +bn_sqr4x_mont:
        +L$sqr4x_enter:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	shll	$3,%r9d
        +	xorq	%r10,%r10
        +	movq	%rsp,%r11
        +	subq	%r9,%r10
        +	movq	(%r8),%r8
        +	leaq	-72(%rsp,%r10,2),%rsp
        +	andq	$-1024,%rsp
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +	movq	%rdi,32(%rsp)
        +	movq	%rcx,40(%rsp)
        +	movq	%r8,48(%rsp)
        +	movq	%r11,56(%rsp)
        +L$sqr4x_body:
        +
        +
        +
        +
        +
        +
        +
        +	leaq	32(%r10),%rbp
        +	leaq	(%rsi,%r9,1),%rsi
        +
        +	movq	%r9,%rcx
        +
        +
        +	movq	-32(%rsi,%rbp,1),%r14
        +	leaq	64(%rsp,%r9,2),%rdi
        +	movq	-24(%rsi,%rbp,1),%rax
        +	leaq	-32(%rdi,%rbp,1),%rdi
        +	movq	-16(%rsi,%rbp,1),%rbx
        +	movq	%rax,%r15
        +
        +	mulq	%r14
        +	movq	%rax,%r10
        +	movq	%rbx,%rax
        +	movq	%rdx,%r11
        +	movq	%r10,-24(%rdi,%rbp,1)
        +
        +	xorq	%r10,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,-16(%rdi,%rbp,1)
        +
        +	leaq	-16(%rbp),%rcx
        +
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	mulq	%r15
        +	movq	%rax,%r12
        +	movq	%rbx,%rax
        +	movq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	leaq	16(%rcx),%rcx
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi,%rcx,1)
        +	jmp	L$sqr4x_1st
        +
        +.p2align	4
        +L$sqr4x_1st:
        +	movq	(%rsi,%rcx,1),%rbx
        +	xorq	%r12,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,(%rdi,%rcx,1)
        +
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,8(%rdi,%rcx,1)
        +
        +	movq	16(%rsi,%rcx,1),%rbx
        +	xorq	%r12,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,16(%rdi,%rcx,1)
        +
        +
        +	movq	24(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	leaq	32(%rcx),%rcx
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi,%rcx,1)
        +
        +	cmpq	$0,%rcx
        +	jne	L$sqr4x_1st
        +
        +	xorq	%r12,%r12
        +	addq	%r11,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	adcq	%rdx,%r12
        +
        +	movq	%r13,(%rdi)
        +	leaq	16(%rbp),%rbp
        +	movq	%r12,8(%rdi)
        +	jmp	L$sqr4x_outer
        +
        +.p2align	4
        +L$sqr4x_outer:
        +	movq	-32(%rsi,%rbp,1),%r14
        +	leaq	64(%rsp,%r9,2),%rdi
        +	movq	-24(%rsi,%rbp,1),%rax
        +	leaq	-32(%rdi,%rbp,1),%rdi
        +	movq	-16(%rsi,%rbp,1),%rbx
        +	movq	%rax,%r15
        +
        +	movq	-24(%rdi,%rbp,1),%r10
        +	xorq	%r11,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-24(%rdi,%rbp,1)
        +
        +	xorq	%r10,%r10
        +	addq	-16(%rdi,%rbp,1),%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,-16(%rdi,%rbp,1)
        +
        +	leaq	-16(%rbp),%rcx
        +	xorq	%r12,%r12
        +
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	8(%rdi,%rcx,1),%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,8(%rdi,%rcx,1)
        +
        +	leaq	16(%rcx),%rcx
        +	jmp	L$sqr4x_inner
        +
        +.p2align	4
        +L$sqr4x_inner:
        +	movq	(%rsi,%rcx,1),%rbx
        +	xorq	%r12,%r12
        +	addq	(%rdi,%rcx,1),%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,(%rdi,%rcx,1)
        +
        +	movq	8(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	8(%rdi,%rcx,1),%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	leaq	16(%rcx),%rcx
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi,%rcx,1)
        +
        +	cmpq	$0,%rcx
        +	jne	L$sqr4x_inner
        +
        +	xorq	%r12,%r12
        +	addq	%r11,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	adcq	%rdx,%r12
        +
        +	movq	%r13,(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	addq	$16,%rbp
        +	jnz	L$sqr4x_outer
        +
        +
        +	movq	-32(%rsi),%r14
        +	leaq	64(%rsp,%r9,2),%rdi
        +	movq	-24(%rsi),%rax
        +	leaq	-32(%rdi,%rbp,1),%rdi
        +	movq	-16(%rsi),%rbx
        +	movq	%rax,%r15
        +
        +	xorq	%r11,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-24(%rdi)
        +
        +	xorq	%r10,%r10
        +	addq	%r13,%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	movq	%r11,-16(%rdi)
        +
        +	movq	-8(%rsi),%rbx
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	$0,%rdx
        +
        +	xorq	%r11,%r11
        +	addq	%r12,%r10
        +	movq	%rdx,%r13
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r11
        +	movq	%r10,-8(%rdi)
        +
        +	xorq	%r12,%r12
        +	addq	%r11,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	-16(%rsi),%rax
        +	adcq	%rdx,%r12
        +
        +	movq	%r13,(%rdi)
        +	movq	%r12,8(%rdi)
        +
        +	mulq	%rbx
        +	addq	$16,%rbp
        +	xorq	%r14,%r14
        +	subq	%r9,%rbp
        +	xorq	%r15,%r15
        +
        +	addq	%r12,%rax
        +	adcq	$0,%rdx
        +	movq	%rax,8(%rdi)
        +	movq	%rdx,16(%rdi)
        +	movq	%r15,24(%rdi)
        +
        +	movq	-16(%rsi,%rbp,1),%rax
        +	leaq	64(%rsp,%r9,2),%rdi
        +	xorq	%r10,%r10
        +	movq	-24(%rdi,%rbp,2),%r11
        +
        +	leaq	(%r14,%r10,2),%r12
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	-16(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	-8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%r12
        +	movq	-8(%rsi,%rbp,1),%rax
        +	movq	%r12,-32(%rdi,%rbp,2)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,-24(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	movq	0(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%rbx
        +	movq	0(%rsi,%rbp,1),%rax
        +	movq	%rbx,-16(%rdi,%rbp,2)
        +	adcq	%rdx,%r8
        +	leaq	16(%rbp),%rbp
        +	movq	%r8,-40(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	jmp	L$sqr4x_shift_n_add
        +
        +.p2align	4
        +L$sqr4x_shift_n_add:
        +	leaq	(%r14,%r10,2),%r12
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	-16(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	-8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%r12
        +	movq	-8(%rsi,%rbp,1),%rax
        +	movq	%r12,-32(%rdi,%rbp,2)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,-24(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	movq	0(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	8(%rdi,%rbp,2),%r11
        +	adcq	%rax,%rbx
        +	movq	0(%rsi,%rbp,1),%rax
        +	movq	%rbx,-16(%rdi,%rbp,2)
        +	adcq	%rdx,%r8
        +
        +	leaq	(%r14,%r10,2),%r12
        +	movq	%r8,-8(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	16(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	24(%rdi,%rbp,2),%r11
        +	adcq	%rax,%r12
        +	movq	8(%rsi,%rbp,1),%rax
        +	movq	%r12,0(%rdi,%rbp,2)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,8(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	movq	32(%rdi,%rbp,2),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	40(%rdi,%rbp,2),%r11
        +	adcq	%rax,%rbx
        +	movq	16(%rsi,%rbp,1),%rax
        +	movq	%rbx,16(%rdi,%rbp,2)
        +	adcq	%rdx,%r8
        +	movq	%r8,24(%rdi,%rbp,2)
        +	sbbq	%r15,%r15
        +	addq	$32,%rbp
        +	jnz	L$sqr4x_shift_n_add
        +
        +	leaq	(%r14,%r10,2),%r12
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r13
        +	shrq	$63,%r11
        +	orq	%r10,%r13
        +	movq	-16(%rdi),%r10
        +	movq	%r11,%r14
        +	mulq	%rax
        +	negq	%r15
        +	movq	-8(%rdi),%r11
        +	adcq	%rax,%r12
        +	movq	-8(%rsi),%rax
        +	movq	%r12,-32(%rdi)
        +	adcq	%rdx,%r13
        +
        +	leaq	(%r14,%r10,2),%rbx
        +	movq	%r13,-24(%rdi)
        +	sbbq	%r15,%r15
        +	shrq	$63,%r10
        +	leaq	(%rcx,%r11,2),%r8
        +	shrq	$63,%r11
        +	orq	%r10,%r8
        +	mulq	%rax
        +	negq	%r15
        +	adcq	%rax,%rbx
        +	adcq	%rdx,%r8
        +	movq	%rbx,-16(%rdi)
        +	movq	%r8,-8(%rdi)
        +	movq	40(%rsp),%rsi
        +	movq	48(%rsp),%r8
        +	xorq	%rcx,%rcx
        +	movq	%r9,0(%rsp)
        +	subq	%r9,%rcx
        +	movq	64(%rsp),%r10
        +	movq	%r8,%r14
        +	leaq	64(%rsp,%r9,2),%rax
        +	leaq	64(%rsp,%r9,1),%rdi
        +	movq	%rax,8(%rsp)
        +	leaq	(%rsi,%r9,1),%rsi
        +	xorq	%rbp,%rbp
        +
        +	movq	0(%rsi,%rcx,1),%rax
        +	movq	8(%rsi,%rcx,1),%r9
        +	imulq	%r10,%r14
        +	movq	%rax,%rbx
        +	jmp	L$sqr4x_mont_outer
        +
        +.p2align	4
        +L$sqr4x_mont_outer:
        +	xorq	%r11,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +	movq	%r8,%r15
        +
        +	xorq	%r10,%r10
        +	addq	8(%rdi,%rcx,1),%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +
        +	imulq	%r11,%r15
        +
        +	movq	16(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,8(%rdi,%rcx,1)
        +
        +	xorq	%r11,%r11
        +	addq	16(%rdi,%rcx,1),%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +
        +	movq	24(%rsi,%rcx,1),%r9
        +	xorq	%r12,%r12
        +	addq	%r10,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%r9,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,16(%rdi,%rcx,1)
        +
        +	xorq	%r10,%r10
        +	addq	24(%rdi,%rcx,1),%r11
        +	leaq	32(%rcx),%rcx
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	jmp	L$sqr4x_mont_inner
        +
        +.p2align	4
        +L$sqr4x_mont_inner:
        +	movq	(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,-8(%rdi,%rcx,1)
        +
        +	xorq	%r11,%r11
        +	addq	(%rdi,%rcx,1),%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +
        +	movq	8(%rsi,%rcx,1),%r9
        +	xorq	%r12,%r12
        +	addq	%r10,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%r9,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,(%rdi,%rcx,1)
        +
        +	xorq	%r10,%r10
        +	addq	8(%rdi,%rcx,1),%r11
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +
        +
        +	movq	16(%rsi,%rcx,1),%rbx
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,8(%rdi,%rcx,1)
        +
        +	xorq	%r11,%r11
        +	addq	16(%rdi,%rcx,1),%r10
        +	adcq	$0,%r11
        +	mulq	%r14
        +	addq	%rax,%r10
        +	movq	%r9,%rax
        +	adcq	%rdx,%r11
        +
        +	movq	24(%rsi,%rcx,1),%r9
        +	xorq	%r12,%r12
        +	addq	%r10,%r13
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%r9,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,16(%rdi,%rcx,1)
        +
        +	xorq	%r10,%r10
        +	addq	24(%rdi,%rcx,1),%r11
        +	leaq	32(%rcx),%rcx
        +	adcq	$0,%r10
        +	mulq	%r14
        +	addq	%rax,%r11
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r10
        +	cmpq	$0,%rcx
        +	jne	L$sqr4x_mont_inner
        +
        +	subq	0(%rsp),%rcx
        +	movq	%r8,%r14
        +
        +	xorq	%r13,%r13
        +	addq	%r11,%r12
        +	adcq	$0,%r13
        +	mulq	%r15
        +	addq	%rax,%r12
        +	movq	%r9,%rax
        +	adcq	%rdx,%r13
        +	movq	%r12,-8(%rdi)
        +
        +	xorq	%r11,%r11
        +	addq	(%rdi),%r10
        +	adcq	$0,%r11
        +	movq	0(%rsi,%rcx,1),%rbx
        +	addq	%rbp,%r10
        +	adcq	$0,%r11
        +
        +	imulq	16(%rdi,%rcx,1),%r14
        +	xorq	%r12,%r12
        +	movq	8(%rsi,%rcx,1),%r9
        +	addq	%r10,%r13
        +	movq	16(%rdi,%rcx,1),%r10
        +	adcq	$0,%r12
        +	mulq	%r15
        +	addq	%rax,%r13
        +	movq	%rbx,%rax
        +	adcq	%rdx,%r12
        +	movq	%r13,(%rdi)
        +
        +	xorq	%rbp,%rbp
        +	addq	8(%rdi),%r12
        +	adcq	%rbp,%rbp
        +	addq	%r11,%r12
        +	leaq	16(%rdi),%rdi
        +	adcq	$0,%rbp
        +	movq	%r12,-8(%rdi)
        +	cmpq	8(%rsp),%rdi
        +	jb	L$sqr4x_mont_outer
        +
        +	movq	0(%rsp),%r9
        +	movq	%rbp,(%rdi)
        +	movq	64(%rsp,%r9,1),%rax
        +	leaq	64(%rsp,%r9,1),%rbx
        +	movq	40(%rsp),%rsi
        +	shrq	$5,%r9
        +	movq	8(%rbx),%rdx
        +	xorq	%rbp,%rbp
        +
        +	movq	32(%rsp),%rdi
        +	subq	0(%rsi),%rax
        +	movq	16(%rbx),%r10
        +	movq	24(%rbx),%r11
        +	sbbq	8(%rsi),%rdx
        +	leaq	-1(%r9),%rcx
        +	jmp	L$sqr4x_sub
        +.p2align	4
        +L$sqr4x_sub:
        +	movq	%rax,0(%rdi,%rbp,8)
        +	movq	%rdx,8(%rdi,%rbp,8)
        +	sbbq	16(%rsi,%rbp,8),%r10
        +	movq	32(%rbx,%rbp,8),%rax
        +	movq	40(%rbx,%rbp,8),%rdx
        +	sbbq	24(%rsi,%rbp,8),%r11
        +	movq	%r10,16(%rdi,%rbp,8)
        +	movq	%r11,24(%rdi,%rbp,8)
        +	sbbq	32(%rsi,%rbp,8),%rax
        +	movq	48(%rbx,%rbp,8),%r10
        +	movq	56(%rbx,%rbp,8),%r11
        +	sbbq	40(%rsi,%rbp,8),%rdx
        +	leaq	4(%rbp),%rbp
        +	decq	%rcx
        +	jnz	L$sqr4x_sub
        +
        +	movq	%rax,0(%rdi,%rbp,8)
        +	movq	32(%rbx,%rbp,8),%rax
        +	sbbq	16(%rsi,%rbp,8),%r10
        +	movq	%rdx,8(%rdi,%rbp,8)
        +	sbbq	24(%rsi,%rbp,8),%r11
        +	movq	%r10,16(%rdi,%rbp,8)
        +
        +	sbbq	$0,%rax
        +	movq	%r11,24(%rdi,%rbp,8)
        +	xorq	%rbp,%rbp
        +	andq	%rax,%rbx
        +	notq	%rax
        +	movq	%rdi,%rsi
        +	andq	%rax,%rsi
        +	leaq	-1(%r9),%rcx
        +	orq	%rsi,%rbx
        +
        +	pxor	%xmm0,%xmm0
        +	leaq	64(%rsp,%r9,8),%rsi
        +	movdqu	(%rbx),%xmm1
        +	leaq	(%rsi,%r9,8),%rsi
        +	movdqa	%xmm0,64(%rsp)
        +	movdqa	%xmm0,(%rsi)
        +	movdqu	%xmm1,(%rdi)
        +	jmp	L$sqr4x_copy
        +.p2align	4
        +L$sqr4x_copy:
        +	movdqu	16(%rbx,%rbp,1),%xmm2
        +	movdqu	32(%rbx,%rbp,1),%xmm1
        +	movdqa	%xmm0,80(%rsp,%rbp,1)
        +	movdqa	%xmm0,96(%rsp,%rbp,1)
        +	movdqa	%xmm0,16(%rsi,%rbp,1)
        +	movdqa	%xmm0,32(%rsi,%rbp,1)
        +	movdqu	%xmm2,16(%rdi,%rbp,1)
        +	movdqu	%xmm1,32(%rdi,%rbp,1)
        +	leaq	32(%rbp),%rbp
        +	decq	%rcx
        +	jnz	L$sqr4x_copy
        +
        +	movdqu	16(%rbx,%rbp,1),%xmm2
        +	movdqa	%xmm0,80(%rsp,%rbp,1)
        +	movdqa	%xmm0,16(%rsi,%rbp,1)
        +	movdqu	%xmm2,16(%rdi,%rbp,1)
        +	movq	56(%rsp),%rsi
        +	movq	$1,%rax
        +	movq	0(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$sqr4x_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.p2align	4
        diff --git a/vendor/openssl/asm/x64-macosx-gas/camellia/cmll-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/camellia/cmll-x86_64.s
        new file mode 100644
        index 000000000..dfc8d592e
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/camellia/cmll-x86_64.s
        @@ -0,0 +1,1844 @@
        +.text
        +
        +
        +
        +.globl	_Camellia_EncryptBlock
        +
        +.p2align	4
        +_Camellia_EncryptBlock:
        +	movl	$128,%eax
        +	subl	%edi,%eax
        +	movl	$3,%edi
        +	adcl	$0,%edi
        +	jmp	L$enc_rounds
        +
        +
        +.globl	_Camellia_EncryptBlock_Rounds
        +
        +.p2align	4
        +L$enc_rounds:
        +_Camellia_EncryptBlock_Rounds:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +L$enc_prologue:
        +
        +
        +	movq	%rcx,%r13
        +	movq	%rdx,%r14
        +
        +	shll	$6,%edi
        +	leaq	L$Camellia_SBOX(%rip),%rbp
        +	leaq	(%r14,%rdi,1),%r15
        +
        +	movl	0(%rsi),%r8d
        +	movl	4(%rsi),%r9d
        +	movl	8(%rsi),%r10d
        +	bswapl	%r8d
        +	movl	12(%rsi),%r11d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	movl	%r8d,0(%r13)
        +	bswapl	%r11d
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	movq	0(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r13
        +	movq	24(%rsp),%rbp
        +	movq	32(%rsp),%rbx
        +	leaq	40(%rsp),%rsp
        +L$enc_epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +
        +.p2align	4
        +_x86_64_Camellia_encrypt:
        +	xorl	0(%r14),%r9d
        +	xorl	4(%r14),%r8d
        +	xorl	8(%r14),%r11d
        +	xorl	12(%r14),%r10d
        +.p2align	4
        +L$eloop:
        +	movl	16(%r14),%ebx
        +	movl	20(%r14),%eax
        +
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	24(%r14),%ebx
        +	movl	28(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	32(%r14),%ebx
        +	movl	36(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	40(%r14),%ebx
        +	movl	44(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	48(%r14),%ebx
        +	movl	52(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	56(%r14),%ebx
        +	movl	60(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	64(%r14),%ebx
        +	movl	68(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	leaq	64(%r14),%r14
        +	cmpq	%r15,%r14
        +	movl	8(%r14),%edx
        +	movl	12(%r14),%ecx
        +	je	L$edone
        +
        +	andl	%r8d,%eax
        +	orl	%r11d,%edx
        +	roll	$1,%eax
        +	xorl	%edx,%r10d
        +	xorl	%eax,%r9d
        +	andl	%r10d,%ecx
        +	orl	%r9d,%ebx
        +	roll	$1,%ecx
        +	xorl	%ebx,%r8d
        +	xorl	%ecx,%r11d
        +	jmp	L$eloop
        +
        +.p2align	4
        +L$edone:
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	xorl	%r8d,%ecx
        +	xorl	%r9d,%edx
        +
        +	movl	%eax,%r8d
        +	movl	%ebx,%r9d
        +	movl	%ecx,%r10d
        +	movl	%edx,%r11d
        +
        +.byte	0xf3,0xc3
        +
        +
        +
        +
        +.globl	_Camellia_DecryptBlock
        +
        +.p2align	4
        +_Camellia_DecryptBlock:
        +	movl	$128,%eax
        +	subl	%edi,%eax
        +	movl	$3,%edi
        +	adcl	$0,%edi
        +	jmp	L$dec_rounds
        +
        +
        +.globl	_Camellia_DecryptBlock_Rounds
        +
        +.p2align	4
        +L$dec_rounds:
        +_Camellia_DecryptBlock_Rounds:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +L$dec_prologue:
        +
        +
        +	movq	%rcx,%r13
        +	movq	%rdx,%r15
        +
        +	shll	$6,%edi
        +	leaq	L$Camellia_SBOX(%rip),%rbp
        +	leaq	(%r15,%rdi,1),%r14
        +
        +	movl	0(%rsi),%r8d
        +	movl	4(%rsi),%r9d
        +	movl	8(%rsi),%r10d
        +	bswapl	%r8d
        +	movl	12(%rsi),%r11d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	movl	%r8d,0(%r13)
        +	bswapl	%r11d
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	movq	0(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r13
        +	movq	24(%rsp),%rbp
        +	movq	32(%rsp),%rbx
        +	leaq	40(%rsp),%rsp
        +L$dec_epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +
        +.p2align	4
        +_x86_64_Camellia_decrypt:
        +	xorl	0(%r14),%r9d
        +	xorl	4(%r14),%r8d
        +	xorl	8(%r14),%r11d
        +	xorl	12(%r14),%r10d
        +.p2align	4
        +L$dloop:
        +	movl	-8(%r14),%ebx
        +	movl	-4(%r14),%eax
        +
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-16(%r14),%ebx
        +	movl	-12(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-24(%r14),%ebx
        +	movl	-20(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-32(%r14),%ebx
        +	movl	-28(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-40(%r14),%ebx
        +	movl	-36(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-48(%r14),%ebx
        +	movl	-44(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	-56(%r14),%ebx
        +	movl	-52(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	leaq	-64(%r14),%r14
        +	cmpq	%r15,%r14
        +	movl	0(%r14),%edx
        +	movl	4(%r14),%ecx
        +	je	L$ddone
        +
        +	andl	%r8d,%eax
        +	orl	%r11d,%edx
        +	roll	$1,%eax
        +	xorl	%edx,%r10d
        +	xorl	%eax,%r9d
        +	andl	%r10d,%ecx
        +	orl	%r9d,%ebx
        +	roll	$1,%ecx
        +	xorl	%ebx,%r8d
        +	xorl	%ecx,%r11d
        +
        +	jmp	L$dloop
        +
        +.p2align	4
        +L$ddone:
        +	xorl	%r10d,%ecx
        +	xorl	%r11d,%edx
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +
        +	movl	%ecx,%r8d
        +	movl	%edx,%r9d
        +	movl	%eax,%r10d
        +	movl	%ebx,%r11d
        +
        +.byte	0xf3,0xc3
        +
        +
        +.globl	_Camellia_Ekeygen
        +
        +.p2align	4
        +_Camellia_Ekeygen:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +L$key_prologue:
        +
        +	movq	%rdi,%r15
        +	movq	%rdx,%r13
        +
        +	movl	0(%rsi),%r8d
        +	movl	4(%rsi),%r9d
        +	movl	8(%rsi),%r10d
        +	movl	12(%rsi),%r11d
        +
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +	movl	%r9d,0(%r13)
        +	movl	%r8d,4(%r13)
        +	movl	%r11d,8(%r13)
        +	movl	%r10d,12(%r13)
        +	cmpq	$128,%r15
        +	je	L$1st128
        +
        +	movl	16(%rsi),%r8d
        +	movl	20(%rsi),%r9d
        +	cmpq	$192,%r15
        +	je	L$1st192
        +	movl	24(%rsi),%r10d
        +	movl	28(%rsi),%r11d
        +	jmp	L$1st256
        +L$1st192:
        +	movl	%r8d,%r10d
        +	movl	%r9d,%r11d
        +	notl	%r10d
        +	notl	%r11d
        +L$1st256:
        +	bswapl	%r8d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +	movl	%r9d,32(%r13)
        +	movl	%r8d,36(%r13)
        +	movl	%r11d,40(%r13)
        +	movl	%r10d,44(%r13)
        +	xorl	0(%r13),%r9d
        +	xorl	4(%r13),%r8d
        +	xorl	8(%r13),%r11d
        +	xorl	12(%r13),%r10d
        +
        +L$1st128:
        +	leaq	L$Camellia_SIGMA(%rip),%r14
        +	leaq	L$Camellia_SBOX(%rip),%rbp
        +
        +	movl	0(%r14),%ebx
        +	movl	4(%r14),%eax
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	8(%r14),%ebx
        +	movl	12(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	16(%r14),%ebx
        +	movl	20(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	xorl	0(%r13),%r9d
        +	xorl	4(%r13),%r8d
        +	xorl	8(%r13),%r11d
        +	xorl	12(%r13),%r10d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	24(%r14),%ebx
        +	movl	28(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	32(%r14),%ebx
        +	movl	36(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	cmpq	$128,%r15
        +	jne	L$2nd256
        +
        +	leaq	128(%r13),%r13
        +	shlq	$32,%r8
        +	shlq	$32,%r10
        +	orq	%r9,%r8
        +	orq	%r11,%r10
        +	movq	-128(%r13),%rax
        +	movq	-120(%r13),%rbx
        +	movq	%r8,-112(%r13)
        +	movq	%r10,-104(%r13)
        +	movq	%rax,%r11
        +	shlq	$15,%rax
        +	movq	%rbx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rax
        +	shlq	$15,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,-96(%r13)
        +	movq	%rbx,-88(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-80(%r13)
        +	movq	%r10,-72(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-64(%r13)
        +	movq	%r10,-56(%r13)
        +	movq	%rax,%r11
        +	shlq	$30,%rax
        +	movq	%rbx,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%rax
        +	shlq	$30,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,-48(%r13)
        +	movq	%rbx,-40(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-32(%r13)
        +	movq	%rax,%r11
        +	shlq	$15,%rax
        +	movq	%rbx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rax
        +	shlq	$15,%rbx
        +	orq	%r11,%rbx
        +	movq	%rbx,-24(%r13)
        +	movq	%r8,%r11
        +	shlq	$15,%r8
        +	movq	%r10,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r8
        +	shlq	$15,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-16(%r13)
        +	movq	%r10,-8(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,0(%r13)
        +	movq	%rbx,8(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,16(%r13)
        +	movq	%rbx,24(%r13)
        +	movq	%r8,%r11
        +	shlq	$34,%r8
        +	movq	%r10,%r9
        +	shrq	$30,%r9
        +	shrq	$30,%r11
        +	orq	%r9,%r8
        +	shlq	$34,%r10
        +	orq	%r11,%r10
        +	movq	%r8,32(%r13)
        +	movq	%r10,40(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,48(%r13)
        +	movq	%rbx,56(%r13)
        +	movq	%r8,%r11
        +	shlq	$17,%r8
        +	movq	%r10,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%r8
        +	shlq	$17,%r10
        +	orq	%r11,%r10
        +	movq	%r8,64(%r13)
        +	movq	%r10,72(%r13)
        +	movl	$3,%eax
        +	jmp	L$done
        +.p2align	4
        +L$2nd256:
        +	movl	%r9d,48(%r13)
        +	movl	%r8d,52(%r13)
        +	movl	%r11d,56(%r13)
        +	movl	%r10d,60(%r13)
        +	xorl	32(%r13),%r9d
        +	xorl	36(%r13),%r8d
        +	xorl	40(%r13),%r11d
        +	xorl	44(%r13),%r10d
        +	xorl	%r8d,%eax
        +	xorl	%r9d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	40(%r14),%ebx
        +	movl	44(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	xorl	%r10d,%eax
        +	xorl	%r11d,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	movl	2052(%rbp,%rsi,8),%edx
        +	movl	0(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	shrl	$16,%eax
        +	movzbl	%bh,%edi
        +	xorl	4(%rbp,%rsi,8),%edx
        +	shrl	$16,%ebx
        +	xorl	4(%rbp,%rdi,8),%ecx
        +	movzbl	%ah,%esi
        +	movzbl	%bl,%edi
        +	xorl	0(%rbp,%rsi,8),%edx
        +	xorl	2052(%rbp,%rdi,8),%ecx
        +	movzbl	%al,%esi
        +	movzbl	%bh,%edi
        +	xorl	2048(%rbp,%rsi,8),%edx
        +	xorl	2048(%rbp,%rdi,8),%ecx
        +	movl	48(%r14),%ebx
        +	movl	52(%r14),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	%ecx,%r8d
        +	xorl	%ecx,%r9d
        +	xorl	%edx,%r9d
        +	movq	0(%r13),%rax
        +	movq	8(%r13),%rbx
        +	movq	32(%r13),%rcx
        +	movq	40(%r13),%rdx
        +	movq	48(%r13),%r14
        +	movq	56(%r13),%r15
        +	leaq	128(%r13),%r13
        +	shlq	$32,%r8
        +	shlq	$32,%r10
        +	orq	%r9,%r8
        +	orq	%r11,%r10
        +	movq	%r8,-112(%r13)
        +	movq	%r10,-104(%r13)
        +	movq	%rcx,%r11
        +	shlq	$15,%rcx
        +	movq	%rdx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rcx
        +	shlq	$15,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,-96(%r13)
        +	movq	%rdx,-88(%r13)
        +	movq	%r14,%r11
        +	shlq	$15,%r14
        +	movq	%r15,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%r14
        +	shlq	$15,%r15
        +	orq	%r11,%r15
        +	movq	%r14,-80(%r13)
        +	movq	%r15,-72(%r13)
        +	movq	%rcx,%r11
        +	shlq	$15,%rcx
        +	movq	%rdx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rcx
        +	shlq	$15,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,-64(%r13)
        +	movq	%rdx,-56(%r13)
        +	movq	%r8,%r11
        +	shlq	$30,%r8
        +	movq	%r10,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%r8
        +	shlq	$30,%r10
        +	orq	%r11,%r10
        +	movq	%r8,-48(%r13)
        +	movq	%r10,-40(%r13)
        +	movq	%rax,%r11
        +	shlq	$45,%rax
        +	movq	%rbx,%r9
        +	shrq	$19,%r9
        +	shrq	$19,%r11
        +	orq	%r9,%rax
        +	shlq	$45,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,-32(%r13)
        +	movq	%rbx,-24(%r13)
        +	movq	%r14,%r11
        +	shlq	$30,%r14
        +	movq	%r15,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%r14
        +	shlq	$30,%r15
        +	orq	%r11,%r15
        +	movq	%r14,-16(%r13)
        +	movq	%r15,-8(%r13)
        +	movq	%rax,%r11
        +	shlq	$15,%rax
        +	movq	%rbx,%r9
        +	shrq	$49,%r9
        +	shrq	$49,%r11
        +	orq	%r9,%rax
        +	shlq	$15,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,0(%r13)
        +	movq	%rbx,8(%r13)
        +	movq	%rcx,%r11
        +	shlq	$30,%rcx
        +	movq	%rdx,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%rcx
        +	shlq	$30,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,16(%r13)
        +	movq	%rdx,24(%r13)
        +	movq	%r8,%r11
        +	shlq	$30,%r8
        +	movq	%r10,%r9
        +	shrq	$34,%r9
        +	shrq	$34,%r11
        +	orq	%r9,%r8
        +	shlq	$30,%r10
        +	orq	%r11,%r10
        +	movq	%r8,32(%r13)
        +	movq	%r10,40(%r13)
        +	movq	%rax,%r11
        +	shlq	$17,%rax
        +	movq	%rbx,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%rax
        +	shlq	$17,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,48(%r13)
        +	movq	%rbx,56(%r13)
        +	movq	%r14,%r11
        +	shlq	$32,%r14
        +	movq	%r15,%r9
        +	shrq	$32,%r9
        +	shrq	$32,%r11
        +	orq	%r9,%r14
        +	shlq	$32,%r15
        +	orq	%r11,%r15
        +	movq	%r14,64(%r13)
        +	movq	%r15,72(%r13)
        +	movq	%rcx,%r11
        +	shlq	$34,%rcx
        +	movq	%rdx,%r9
        +	shrq	$30,%r9
        +	shrq	$30,%r11
        +	orq	%r9,%rcx
        +	shlq	$34,%rdx
        +	orq	%r11,%rdx
        +	movq	%rcx,80(%r13)
        +	movq	%rdx,88(%r13)
        +	movq	%r14,%r11
        +	shlq	$17,%r14
        +	movq	%r15,%r9
        +	shrq	$47,%r9
        +	shrq	$47,%r11
        +	orq	%r9,%r14
        +	shlq	$17,%r15
        +	orq	%r11,%r15
        +	movq	%r14,96(%r13)
        +	movq	%r15,104(%r13)
        +	movq	%rax,%r11
        +	shlq	$34,%rax
        +	movq	%rbx,%r9
        +	shrq	$30,%r9
        +	shrq	$30,%r11
        +	orq	%r9,%rax
        +	shlq	$34,%rbx
        +	orq	%r11,%rbx
        +	movq	%rax,112(%r13)
        +	movq	%rbx,120(%r13)
        +	movq	%r8,%r11
        +	shlq	$51,%r8
        +	movq	%r10,%r9
        +	shrq	$13,%r9
        +	shrq	$13,%r11
        +	orq	%r9,%r8
        +	shlq	$51,%r10
        +	orq	%r11,%r10
        +	movq	%r8,128(%r13)
        +	movq	%r10,136(%r13)
        +	movl	$4,%eax
        +L$done:
        +	movq	0(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r13
        +	movq	24(%rsp),%rbp
        +	movq	32(%rsp),%rbx
        +	leaq	40(%rsp),%rsp
        +L$key_epilogue:
        +	.byte	0xf3,0xc3
        +
        +.p2align	6
        +L$Camellia_SIGMA:
        +.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
        +.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
        +.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
        +.long	0,          0,          0,          0
        +L$Camellia_SBOX:
        +.long	0x70707000,0x70700070
        +.long	0x82828200,0x2c2c002c
        +.long	0x2c2c2c00,0xb3b300b3
        +.long	0xececec00,0xc0c000c0
        +.long	0xb3b3b300,0xe4e400e4
        +.long	0x27272700,0x57570057
        +.long	0xc0c0c000,0xeaea00ea
        +.long	0xe5e5e500,0xaeae00ae
        +.long	0xe4e4e400,0x23230023
        +.long	0x85858500,0x6b6b006b
        +.long	0x57575700,0x45450045
        +.long	0x35353500,0xa5a500a5
        +.long	0xeaeaea00,0xeded00ed
        +.long	0x0c0c0c00,0x4f4f004f
        +.long	0xaeaeae00,0x1d1d001d
        +.long	0x41414100,0x92920092
        +.long	0x23232300,0x86860086
        +.long	0xefefef00,0xafaf00af
        +.long	0x6b6b6b00,0x7c7c007c
        +.long	0x93939300,0x1f1f001f
        +.long	0x45454500,0x3e3e003e
        +.long	0x19191900,0xdcdc00dc
        +.long	0xa5a5a500,0x5e5e005e
        +.long	0x21212100,0x0b0b000b
        +.long	0xededed00,0xa6a600a6
        +.long	0x0e0e0e00,0x39390039
        +.long	0x4f4f4f00,0xd5d500d5
        +.long	0x4e4e4e00,0x5d5d005d
        +.long	0x1d1d1d00,0xd9d900d9
        +.long	0x65656500,0x5a5a005a
        +.long	0x92929200,0x51510051
        +.long	0xbdbdbd00,0x6c6c006c
        +.long	0x86868600,0x8b8b008b
        +.long	0xb8b8b800,0x9a9a009a
        +.long	0xafafaf00,0xfbfb00fb
        +.long	0x8f8f8f00,0xb0b000b0
        +.long	0x7c7c7c00,0x74740074
        +.long	0xebebeb00,0x2b2b002b
        +.long	0x1f1f1f00,0xf0f000f0
        +.long	0xcecece00,0x84840084
        +.long	0x3e3e3e00,0xdfdf00df
        +.long	0x30303000,0xcbcb00cb
        +.long	0xdcdcdc00,0x34340034
        +.long	0x5f5f5f00,0x76760076
        +.long	0x5e5e5e00,0x6d6d006d
        +.long	0xc5c5c500,0xa9a900a9
        +.long	0x0b0b0b00,0xd1d100d1
        +.long	0x1a1a1a00,0x04040004
        +.long	0xa6a6a600,0x14140014
        +.long	0xe1e1e100,0x3a3a003a
        +.long	0x39393900,0xdede00de
        +.long	0xcacaca00,0x11110011
        +.long	0xd5d5d500,0x32320032
        +.long	0x47474700,0x9c9c009c
        +.long	0x5d5d5d00,0x53530053
        +.long	0x3d3d3d00,0xf2f200f2
        +.long	0xd9d9d900,0xfefe00fe
        +.long	0x01010100,0xcfcf00cf
        +.long	0x5a5a5a00,0xc3c300c3
        +.long	0xd6d6d600,0x7a7a007a
        +.long	0x51515100,0x24240024
        +.long	0x56565600,0xe8e800e8
        +.long	0x6c6c6c00,0x60600060
        +.long	0x4d4d4d00,0x69690069
        +.long	0x8b8b8b00,0xaaaa00aa
        +.long	0x0d0d0d00,0xa0a000a0
        +.long	0x9a9a9a00,0xa1a100a1
        +.long	0x66666600,0x62620062
        +.long	0xfbfbfb00,0x54540054
        +.long	0xcccccc00,0x1e1e001e
        +.long	0xb0b0b000,0xe0e000e0
        +.long	0x2d2d2d00,0x64640064
        +.long	0x74747400,0x10100010
        +.long	0x12121200,0x00000000
        +.long	0x2b2b2b00,0xa3a300a3
        +.long	0x20202000,0x75750075
        +.long	0xf0f0f000,0x8a8a008a
        +.long	0xb1b1b100,0xe6e600e6
        +.long	0x84848400,0x09090009
        +.long	0x99999900,0xdddd00dd
        +.long	0xdfdfdf00,0x87870087
        +.long	0x4c4c4c00,0x83830083
        +.long	0xcbcbcb00,0xcdcd00cd
        +.long	0xc2c2c200,0x90900090
        +.long	0x34343400,0x73730073
        +.long	0x7e7e7e00,0xf6f600f6
        +.long	0x76767600,0x9d9d009d
        +.long	0x05050500,0xbfbf00bf
        +.long	0x6d6d6d00,0x52520052
        +.long	0xb7b7b700,0xd8d800d8
        +.long	0xa9a9a900,0xc8c800c8
        +.long	0x31313100,0xc6c600c6
        +.long	0xd1d1d100,0x81810081
        +.long	0x17171700,0x6f6f006f
        +.long	0x04040400,0x13130013
        +.long	0xd7d7d700,0x63630063
        +.long	0x14141400,0xe9e900e9
        +.long	0x58585800,0xa7a700a7
        +.long	0x3a3a3a00,0x9f9f009f
        +.long	0x61616100,0xbcbc00bc
        +.long	0xdedede00,0x29290029
        +.long	0x1b1b1b00,0xf9f900f9
        +.long	0x11111100,0x2f2f002f
        +.long	0x1c1c1c00,0xb4b400b4
        +.long	0x32323200,0x78780078
        +.long	0x0f0f0f00,0x06060006
        +.long	0x9c9c9c00,0xe7e700e7
        +.long	0x16161600,0x71710071
        +.long	0x53535300,0xd4d400d4
        +.long	0x18181800,0xabab00ab
        +.long	0xf2f2f200,0x88880088
        +.long	0x22222200,0x8d8d008d
        +.long	0xfefefe00,0x72720072
        +.long	0x44444400,0xb9b900b9
        +.long	0xcfcfcf00,0xf8f800f8
        +.long	0xb2b2b200,0xacac00ac
        +.long	0xc3c3c300,0x36360036
        +.long	0xb5b5b500,0x2a2a002a
        +.long	0x7a7a7a00,0x3c3c003c
        +.long	0x91919100,0xf1f100f1
        +.long	0x24242400,0x40400040
        +.long	0x08080800,0xd3d300d3
        +.long	0xe8e8e800,0xbbbb00bb
        +.long	0xa8a8a800,0x43430043
        +.long	0x60606000,0x15150015
        +.long	0xfcfcfc00,0xadad00ad
        +.long	0x69696900,0x77770077
        +.long	0x50505000,0x80800080
        +.long	0xaaaaaa00,0x82820082
        +.long	0xd0d0d000,0xecec00ec
        +.long	0xa0a0a000,0x27270027
        +.long	0x7d7d7d00,0xe5e500e5
        +.long	0xa1a1a100,0x85850085
        +.long	0x89898900,0x35350035
        +.long	0x62626200,0x0c0c000c
        +.long	0x97979700,0x41410041
        +.long	0x54545400,0xefef00ef
        +.long	0x5b5b5b00,0x93930093
        +.long	0x1e1e1e00,0x19190019
        +.long	0x95959500,0x21210021
        +.long	0xe0e0e000,0x0e0e000e
        +.long	0xffffff00,0x4e4e004e
        +.long	0x64646400,0x65650065
        +.long	0xd2d2d200,0xbdbd00bd
        +.long	0x10101000,0xb8b800b8
        +.long	0xc4c4c400,0x8f8f008f
        +.long	0x00000000,0xebeb00eb
        +.long	0x48484800,0xcece00ce
        +.long	0xa3a3a300,0x30300030
        +.long	0xf7f7f700,0x5f5f005f
        +.long	0x75757500,0xc5c500c5
        +.long	0xdbdbdb00,0x1a1a001a
        +.long	0x8a8a8a00,0xe1e100e1
        +.long	0x03030300,0xcaca00ca
        +.long	0xe6e6e600,0x47470047
        +.long	0xdadada00,0x3d3d003d
        +.long	0x09090900,0x01010001
        +.long	0x3f3f3f00,0xd6d600d6
        +.long	0xdddddd00,0x56560056
        +.long	0x94949400,0x4d4d004d
        +.long	0x87878700,0x0d0d000d
        +.long	0x5c5c5c00,0x66660066
        +.long	0x83838300,0xcccc00cc
        +.long	0x02020200,0x2d2d002d
        +.long	0xcdcdcd00,0x12120012
        +.long	0x4a4a4a00,0x20200020
        +.long	0x90909000,0xb1b100b1
        +.long	0x33333300,0x99990099
        +.long	0x73737300,0x4c4c004c
        +.long	0x67676700,0xc2c200c2
        +.long	0xf6f6f600,0x7e7e007e
        +.long	0xf3f3f300,0x05050005
        +.long	0x9d9d9d00,0xb7b700b7
        +.long	0x7f7f7f00,0x31310031
        +.long	0xbfbfbf00,0x17170017
        +.long	0xe2e2e200,0xd7d700d7
        +.long	0x52525200,0x58580058
        +.long	0x9b9b9b00,0x61610061
        +.long	0xd8d8d800,0x1b1b001b
        +.long	0x26262600,0x1c1c001c
        +.long	0xc8c8c800,0x0f0f000f
        +.long	0x37373700,0x16160016
        +.long	0xc6c6c600,0x18180018
        +.long	0x3b3b3b00,0x22220022
        +.long	0x81818100,0x44440044
        +.long	0x96969600,0xb2b200b2
        +.long	0x6f6f6f00,0xb5b500b5
        +.long	0x4b4b4b00,0x91910091
        +.long	0x13131300,0x08080008
        +.long	0xbebebe00,0xa8a800a8
        +.long	0x63636300,0xfcfc00fc
        +.long	0x2e2e2e00,0x50500050
        +.long	0xe9e9e900,0xd0d000d0
        +.long	0x79797900,0x7d7d007d
        +.long	0xa7a7a700,0x89890089
        +.long	0x8c8c8c00,0x97970097
        +.long	0x9f9f9f00,0x5b5b005b
        +.long	0x6e6e6e00,0x95950095
        +.long	0xbcbcbc00,0xffff00ff
        +.long	0x8e8e8e00,0xd2d200d2
        +.long	0x29292900,0xc4c400c4
        +.long	0xf5f5f500,0x48480048
        +.long	0xf9f9f900,0xf7f700f7
        +.long	0xb6b6b600,0xdbdb00db
        +.long	0x2f2f2f00,0x03030003
        +.long	0xfdfdfd00,0xdada00da
        +.long	0xb4b4b400,0x3f3f003f
        +.long	0x59595900,0x94940094
        +.long	0x78787800,0x5c5c005c
        +.long	0x98989800,0x02020002
        +.long	0x06060600,0x4a4a004a
        +.long	0x6a6a6a00,0x33330033
        +.long	0xe7e7e700,0x67670067
        +.long	0x46464600,0xf3f300f3
        +.long	0x71717100,0x7f7f007f
        +.long	0xbababa00,0xe2e200e2
        +.long	0xd4d4d400,0x9b9b009b
        +.long	0x25252500,0x26260026
        +.long	0xababab00,0x37370037
        +.long	0x42424200,0x3b3b003b
        +.long	0x88888800,0x96960096
        +.long	0xa2a2a200,0x4b4b004b
        +.long	0x8d8d8d00,0xbebe00be
        +.long	0xfafafa00,0x2e2e002e
        +.long	0x72727200,0x79790079
        +.long	0x07070700,0x8c8c008c
        +.long	0xb9b9b900,0x6e6e006e
        +.long	0x55555500,0x8e8e008e
        +.long	0xf8f8f800,0xf5f500f5
        +.long	0xeeeeee00,0xb6b600b6
        +.long	0xacacac00,0xfdfd00fd
        +.long	0x0a0a0a00,0x59590059
        +.long	0x36363600,0x98980098
        +.long	0x49494900,0x6a6a006a
        +.long	0x2a2a2a00,0x46460046
        +.long	0x68686800,0xbaba00ba
        +.long	0x3c3c3c00,0x25250025
        +.long	0x38383800,0x42420042
        +.long	0xf1f1f100,0xa2a200a2
        +.long	0xa4a4a400,0xfafa00fa
        +.long	0x40404000,0x07070007
        +.long	0x28282800,0x55550055
        +.long	0xd3d3d300,0xeeee00ee
        +.long	0x7b7b7b00,0x0a0a000a
        +.long	0xbbbbbb00,0x49490049
        +.long	0xc9c9c900,0x68680068
        +.long	0x43434300,0x38380038
        +.long	0xc1c1c100,0xa4a400a4
        +.long	0x15151500,0x28280028
        +.long	0xe3e3e300,0x7b7b007b
        +.long	0xadadad00,0xc9c900c9
        +.long	0xf4f4f400,0xc1c100c1
        +.long	0x77777700,0xe3e300e3
        +.long	0xc7c7c700,0xf4f400f4
        +.long	0x80808000,0xc7c700c7
        +.long	0x9e9e9e00,0x9e9e009e
        +.long	0x00e0e0e0,0x38003838
        +.long	0x00050505,0x41004141
        +.long	0x00585858,0x16001616
        +.long	0x00d9d9d9,0x76007676
        +.long	0x00676767,0xd900d9d9
        +.long	0x004e4e4e,0x93009393
        +.long	0x00818181,0x60006060
        +.long	0x00cbcbcb,0xf200f2f2
        +.long	0x00c9c9c9,0x72007272
        +.long	0x000b0b0b,0xc200c2c2
        +.long	0x00aeaeae,0xab00abab
        +.long	0x006a6a6a,0x9a009a9a
        +.long	0x00d5d5d5,0x75007575
        +.long	0x00181818,0x06000606
        +.long	0x005d5d5d,0x57005757
        +.long	0x00828282,0xa000a0a0
        +.long	0x00464646,0x91009191
        +.long	0x00dfdfdf,0xf700f7f7
        +.long	0x00d6d6d6,0xb500b5b5
        +.long	0x00272727,0xc900c9c9
        +.long	0x008a8a8a,0xa200a2a2
        +.long	0x00323232,0x8c008c8c
        +.long	0x004b4b4b,0xd200d2d2
        +.long	0x00424242,0x90009090
        +.long	0x00dbdbdb,0xf600f6f6
        +.long	0x001c1c1c,0x07000707
        +.long	0x009e9e9e,0xa700a7a7
        +.long	0x009c9c9c,0x27002727
        +.long	0x003a3a3a,0x8e008e8e
        +.long	0x00cacaca,0xb200b2b2
        +.long	0x00252525,0x49004949
        +.long	0x007b7b7b,0xde00dede
        +.long	0x000d0d0d,0x43004343
        +.long	0x00717171,0x5c005c5c
        +.long	0x005f5f5f,0xd700d7d7
        +.long	0x001f1f1f,0xc700c7c7
        +.long	0x00f8f8f8,0x3e003e3e
        +.long	0x00d7d7d7,0xf500f5f5
        +.long	0x003e3e3e,0x8f008f8f
        +.long	0x009d9d9d,0x67006767
        +.long	0x007c7c7c,0x1f001f1f
        +.long	0x00606060,0x18001818
        +.long	0x00b9b9b9,0x6e006e6e
        +.long	0x00bebebe,0xaf00afaf
        +.long	0x00bcbcbc,0x2f002f2f
        +.long	0x008b8b8b,0xe200e2e2
        +.long	0x00161616,0x85008585
        +.long	0x00343434,0x0d000d0d
        +.long	0x004d4d4d,0x53005353
        +.long	0x00c3c3c3,0xf000f0f0
        +.long	0x00727272,0x9c009c9c
        +.long	0x00959595,0x65006565
        +.long	0x00ababab,0xea00eaea
        +.long	0x008e8e8e,0xa300a3a3
        +.long	0x00bababa,0xae00aeae
        +.long	0x007a7a7a,0x9e009e9e
        +.long	0x00b3b3b3,0xec00ecec
        +.long	0x00020202,0x80008080
        +.long	0x00b4b4b4,0x2d002d2d
        +.long	0x00adadad,0x6b006b6b
        +.long	0x00a2a2a2,0xa800a8a8
        +.long	0x00acacac,0x2b002b2b
        +.long	0x00d8d8d8,0x36003636
        +.long	0x009a9a9a,0xa600a6a6
        +.long	0x00171717,0xc500c5c5
        +.long	0x001a1a1a,0x86008686
        +.long	0x00353535,0x4d004d4d
        +.long	0x00cccccc,0x33003333
        +.long	0x00f7f7f7,0xfd00fdfd
        +.long	0x00999999,0x66006666
        +.long	0x00616161,0x58005858
        +.long	0x005a5a5a,0x96009696
        +.long	0x00e8e8e8,0x3a003a3a
        +.long	0x00242424,0x09000909
        +.long	0x00565656,0x95009595
        +.long	0x00404040,0x10001010
        +.long	0x00e1e1e1,0x78007878
        +.long	0x00636363,0xd800d8d8
        +.long	0x00090909,0x42004242
        +.long	0x00333333,0xcc00cccc
        +.long	0x00bfbfbf,0xef00efef
        +.long	0x00989898,0x26002626
        +.long	0x00979797,0xe500e5e5
        +.long	0x00858585,0x61006161
        +.long	0x00686868,0x1a001a1a
        +.long	0x00fcfcfc,0x3f003f3f
        +.long	0x00ececec,0x3b003b3b
        +.long	0x000a0a0a,0x82008282
        +.long	0x00dadada,0xb600b6b6
        +.long	0x006f6f6f,0xdb00dbdb
        +.long	0x00535353,0xd400d4d4
        +.long	0x00626262,0x98009898
        +.long	0x00a3a3a3,0xe800e8e8
        +.long	0x002e2e2e,0x8b008b8b
        +.long	0x00080808,0x02000202
        +.long	0x00afafaf,0xeb00ebeb
        +.long	0x00282828,0x0a000a0a
        +.long	0x00b0b0b0,0x2c002c2c
        +.long	0x00747474,0x1d001d1d
        +.long	0x00c2c2c2,0xb000b0b0
        +.long	0x00bdbdbd,0x6f006f6f
        +.long	0x00363636,0x8d008d8d
        +.long	0x00222222,0x88008888
        +.long	0x00383838,0x0e000e0e
        +.long	0x00646464,0x19001919
        +.long	0x001e1e1e,0x87008787
        +.long	0x00393939,0x4e004e4e
        +.long	0x002c2c2c,0x0b000b0b
        +.long	0x00a6a6a6,0xa900a9a9
        +.long	0x00303030,0x0c000c0c
        +.long	0x00e5e5e5,0x79007979
        +.long	0x00444444,0x11001111
        +.long	0x00fdfdfd,0x7f007f7f
        +.long	0x00888888,0x22002222
        +.long	0x009f9f9f,0xe700e7e7
        +.long	0x00656565,0x59005959
        +.long	0x00878787,0xe100e1e1
        +.long	0x006b6b6b,0xda00dada
        +.long	0x00f4f4f4,0x3d003d3d
        +.long	0x00232323,0xc800c8c8
        +.long	0x00484848,0x12001212
        +.long	0x00101010,0x04000404
        +.long	0x00d1d1d1,0x74007474
        +.long	0x00515151,0x54005454
        +.long	0x00c0c0c0,0x30003030
        +.long	0x00f9f9f9,0x7e007e7e
        +.long	0x00d2d2d2,0xb400b4b4
        +.long	0x00a0a0a0,0x28002828
        +.long	0x00555555,0x55005555
        +.long	0x00a1a1a1,0x68006868
        +.long	0x00414141,0x50005050
        +.long	0x00fafafa,0xbe00bebe
        +.long	0x00434343,0xd000d0d0
        +.long	0x00131313,0xc400c4c4
        +.long	0x00c4c4c4,0x31003131
        +.long	0x002f2f2f,0xcb00cbcb
        +.long	0x00a8a8a8,0x2a002a2a
        +.long	0x00b6b6b6,0xad00adad
        +.long	0x003c3c3c,0x0f000f0f
        +.long	0x002b2b2b,0xca00caca
        +.long	0x00c1c1c1,0x70007070
        +.long	0x00ffffff,0xff00ffff
        +.long	0x00c8c8c8,0x32003232
        +.long	0x00a5a5a5,0x69006969
        +.long	0x00202020,0x08000808
        +.long	0x00898989,0x62006262
        +.long	0x00000000,0x00000000
        +.long	0x00909090,0x24002424
        +.long	0x00474747,0xd100d1d1
        +.long	0x00efefef,0xfb00fbfb
        +.long	0x00eaeaea,0xba00baba
        +.long	0x00b7b7b7,0xed00eded
        +.long	0x00151515,0x45004545
        +.long	0x00060606,0x81008181
        +.long	0x00cdcdcd,0x73007373
        +.long	0x00b5b5b5,0x6d006d6d
        +.long	0x00121212,0x84008484
        +.long	0x007e7e7e,0x9f009f9f
        +.long	0x00bbbbbb,0xee00eeee
        +.long	0x00292929,0x4a004a4a
        +.long	0x000f0f0f,0xc300c3c3
        +.long	0x00b8b8b8,0x2e002e2e
        +.long	0x00070707,0xc100c1c1
        +.long	0x00040404,0x01000101
        +.long	0x009b9b9b,0xe600e6e6
        +.long	0x00949494,0x25002525
        +.long	0x00212121,0x48004848
        +.long	0x00666666,0x99009999
        +.long	0x00e6e6e6,0xb900b9b9
        +.long	0x00cecece,0xb300b3b3
        +.long	0x00ededed,0x7b007b7b
        +.long	0x00e7e7e7,0xf900f9f9
        +.long	0x003b3b3b,0xce00cece
        +.long	0x00fefefe,0xbf00bfbf
        +.long	0x007f7f7f,0xdf00dfdf
        +.long	0x00c5c5c5,0x71007171
        +.long	0x00a4a4a4,0x29002929
        +.long	0x00373737,0xcd00cdcd
        +.long	0x00b1b1b1,0x6c006c6c
        +.long	0x004c4c4c,0x13001313
        +.long	0x00919191,0x64006464
        +.long	0x006e6e6e,0x9b009b9b
        +.long	0x008d8d8d,0x63006363
        +.long	0x00767676,0x9d009d9d
        +.long	0x00030303,0xc000c0c0
        +.long	0x002d2d2d,0x4b004b4b
        +.long	0x00dedede,0xb700b7b7
        +.long	0x00969696,0xa500a5a5
        +.long	0x00262626,0x89008989
        +.long	0x007d7d7d,0x5f005f5f
        +.long	0x00c6c6c6,0xb100b1b1
        +.long	0x005c5c5c,0x17001717
        +.long	0x00d3d3d3,0xf400f4f4
        +.long	0x00f2f2f2,0xbc00bcbc
        +.long	0x004f4f4f,0xd300d3d3
        +.long	0x00191919,0x46004646
        +.long	0x003f3f3f,0xcf00cfcf
        +.long	0x00dcdcdc,0x37003737
        +.long	0x00797979,0x5e005e5e
        +.long	0x001d1d1d,0x47004747
        +.long	0x00525252,0x94009494
        +.long	0x00ebebeb,0xfa00fafa
        +.long	0x00f3f3f3,0xfc00fcfc
        +.long	0x006d6d6d,0x5b005b5b
        +.long	0x005e5e5e,0x97009797
        +.long	0x00fbfbfb,0xfe00fefe
        +.long	0x00696969,0x5a005a5a
        +.long	0x00b2b2b2,0xac00acac
        +.long	0x00f0f0f0,0x3c003c3c
        +.long	0x00313131,0x4c004c4c
        +.long	0x000c0c0c,0x03000303
        +.long	0x00d4d4d4,0x35003535
        +.long	0x00cfcfcf,0xf300f3f3
        +.long	0x008c8c8c,0x23002323
        +.long	0x00e2e2e2,0xb800b8b8
        +.long	0x00757575,0x5d005d5d
        +.long	0x00a9a9a9,0x6a006a6a
        +.long	0x004a4a4a,0x92009292
        +.long	0x00575757,0xd500d5d5
        +.long	0x00848484,0x21002121
        +.long	0x00111111,0x44004444
        +.long	0x00454545,0x51005151
        +.long	0x001b1b1b,0xc600c6c6
        +.long	0x00f5f5f5,0x7d007d7d
        +.long	0x00e4e4e4,0x39003939
        +.long	0x000e0e0e,0x83008383
        +.long	0x00737373,0xdc00dcdc
        +.long	0x00aaaaaa,0xaa00aaaa
        +.long	0x00f1f1f1,0x7c007c7c
        +.long	0x00dddddd,0x77007777
        +.long	0x00595959,0x56005656
        +.long	0x00141414,0x05000505
        +.long	0x006c6c6c,0x1b001b1b
        +.long	0x00929292,0xa400a4a4
        +.long	0x00545454,0x15001515
        +.long	0x00d0d0d0,0x34003434
        +.long	0x00787878,0x1e001e1e
        +.long	0x00707070,0x1c001c1c
        +.long	0x00e3e3e3,0xf800f8f8
        +.long	0x00494949,0x52005252
        +.long	0x00808080,0x20002020
        +.long	0x00505050,0x14001414
        +.long	0x00a7a7a7,0xe900e9e9
        +.long	0x00f6f6f6,0xbd00bdbd
        +.long	0x00777777,0xdd00dddd
        +.long	0x00939393,0xe400e4e4
        +.long	0x00868686,0xa100a1a1
        +.long	0x00838383,0xe000e0e0
        +.long	0x002a2a2a,0x8a008a8a
        +.long	0x00c7c7c7,0xf100f1f1
        +.long	0x005b5b5b,0xd600d6d6
        +.long	0x00e9e9e9,0x7a007a7a
        +.long	0x00eeeeee,0xbb00bbbb
        +.long	0x008f8f8f,0xe300e3e3
        +.long	0x00010101,0x40004040
        +.long	0x003d3d3d,0x4f004f4f
        +.globl	_Camellia_cbc_encrypt
        +
        +.p2align	4
        +_Camellia_cbc_encrypt:
        +	cmpq	$0,%rdx
        +	je	L$cbc_abort
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +L$cbc_prologue:
        +
        +	movq	%rsp,%rbp
        +	subq	$64,%rsp
        +	andq	$-64,%rsp
        +
        +
        +
        +	leaq	-64-63(%rcx),%r10
        +	subq	%rsp,%r10
        +	negq	%r10
        +	andq	$960,%r10
        +	subq	%r10,%rsp
        +
        +
        +	movq	%rdi,%r12
        +	movq	%rsi,%r13
        +	movq	%r8,%rbx
        +	movq	%rcx,%r14
        +	movl	272(%rcx),%r15d
        +
        +	movq	%r8,40(%rsp)
        +	movq	%rbp,48(%rsp)
        +
        +L$cbc_body:
        +	leaq	L$Camellia_SBOX(%rip),%rbp
        +
        +	movl	$32,%ecx
        +.p2align	2
        +L$cbc_prefetch_sbox:
        +	movq	0(%rbp),%rax
        +	movq	32(%rbp),%rsi
        +	movq	64(%rbp),%rdi
        +	movq	96(%rbp),%r11
        +	leaq	128(%rbp),%rbp
        +	loop	L$cbc_prefetch_sbox
        +	subq	$4096,%rbp
        +	shlq	$6,%r15
        +	movq	%rdx,%rcx
        +	leaq	(%r14,%r15,1),%r15
        +
        +	cmpl	$0,%r9d
        +	je	L$CBC_DECRYPT
        +
        +	andq	$-16,%rdx
        +	andq	$15,%rcx
        +	leaq	(%r12,%rdx,1),%rdx
        +	movq	%r14,0(%rsp)
        +	movq	%rdx,8(%rsp)
        +	movq	%rcx,16(%rsp)
        +
        +	cmpq	%r12,%rdx
        +	movl	0(%rbx),%r8d
        +	movl	4(%rbx),%r9d
        +	movl	8(%rbx),%r10d
        +	movl	12(%rbx),%r11d
        +	je	L$cbc_enc_tail
        +	jmp	L$cbc_eloop
        +
        +.p2align	4
        +L$cbc_eloop:
        +	xorl	0(%r12),%r8d
        +	xorl	4(%r12),%r9d
        +	xorl	8(%r12),%r10d
        +	bswapl	%r8d
        +	xorl	12(%r12),%r11d
        +	bswapl	%r9d
        +	bswapl	%r10d
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	movq	0(%rsp),%r14
        +	bswapl	%r8d
        +	movq	8(%rsp),%rdx
        +	bswapl	%r9d
        +	movq	16(%rsp),%rcx
        +	bswapl	%r10d
        +	movl	%r8d,0(%r13)
        +	bswapl	%r11d
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	leaq	16(%r12),%r12
        +	movl	%r11d,12(%r13)
        +	cmpq	%rdx,%r12
        +	leaq	16(%r13),%r13
        +	jne	L$cbc_eloop
        +
        +	cmpq	$0,%rcx
        +	jne	L$cbc_enc_tail
        +
        +	movq	40(%rsp),%r13
        +	movl	%r8d,0(%r13)
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +	jmp	L$cbc_done
        +
        +.p2align	4
        +L$cbc_enc_tail:
        +	xorq	%rax,%rax
        +	movq	%rax,0+24(%rsp)
        +	movq	%rax,8+24(%rsp)
        +	movq	%rax,16(%rsp)
        +
        +L$cbc_enc_pushf:
        +	pushfq
        +	cld
        +	movq	%r12,%rsi
        +	leaq	8+24(%rsp),%rdi
        +.long	0x9066A4F3
        +
        +	popfq
        +L$cbc_enc_popf:
        +
        +	leaq	24(%rsp),%r12
        +	leaq	16+24(%rsp),%rax
        +	movq	%rax,8(%rsp)
        +	jmp	L$cbc_eloop
        +
        +
        +.p2align	4
        +L$CBC_DECRYPT:
        +	xchgq	%r14,%r15
        +	addq	$15,%rdx
        +	andq	$15,%rcx
        +	andq	$-16,%rdx
        +	movq	%r14,0(%rsp)
        +	leaq	(%r12,%rdx,1),%rdx
        +	movq	%rdx,8(%rsp)
        +	movq	%rcx,16(%rsp)
        +
        +	movq	(%rbx),%rax
        +	movq	8(%rbx),%rbx
        +	jmp	L$cbc_dloop
        +.p2align	4
        +L$cbc_dloop:
        +	movl	0(%r12),%r8d
        +	movl	4(%r12),%r9d
        +	movl	8(%r12),%r10d
        +	bswapl	%r8d
        +	movl	12(%r12),%r11d
        +	bswapl	%r9d
        +	movq	%rax,0+24(%rsp)
        +	bswapl	%r10d
        +	movq	%rbx,8+24(%rsp)
        +	bswapl	%r11d
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	movq	0(%rsp),%r14
        +	movq	8(%rsp),%rdx
        +	movq	16(%rsp),%rcx
        +
        +	bswapl	%r8d
        +	movq	(%r12),%rax
        +	bswapl	%r9d
        +	movq	8(%r12),%rbx
        +	bswapl	%r10d
        +	xorl	0+24(%rsp),%r8d
        +	bswapl	%r11d
        +	xorl	4+24(%rsp),%r9d
        +	xorl	8+24(%rsp),%r10d
        +	leaq	16(%r12),%r12
        +	xorl	12+24(%rsp),%r11d
        +	cmpq	%rdx,%r12
        +	je	L$cbc_ddone
        +
        +	movl	%r8d,0(%r13)
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	leaq	16(%r13),%r13
        +	jmp	L$cbc_dloop
        +
        +.p2align	4
        +L$cbc_ddone:
        +	movq	40(%rsp),%rdx
        +	cmpq	$0,%rcx
        +	jne	L$cbc_dec_tail
        +
        +	movl	%r8d,0(%r13)
        +	movl	%r9d,4(%r13)
        +	movl	%r10d,8(%r13)
        +	movl	%r11d,12(%r13)
        +
        +	movq	%rax,(%rdx)
        +	movq	%rbx,8(%rdx)
        +	jmp	L$cbc_done
        +.p2align	4
        +L$cbc_dec_tail:
        +	movl	%r8d,0+24(%rsp)
        +	movl	%r9d,4+24(%rsp)
        +	movl	%r10d,8+24(%rsp)
        +	movl	%r11d,12+24(%rsp)
        +
        +L$cbc_dec_pushf:
        +	pushfq
        +	cld
        +	leaq	8+24(%rsp),%rsi
        +	leaq	(%r13),%rdi
        +.long	0x9066A4F3
        +
        +	popfq
        +L$cbc_dec_popf:
        +
        +	movq	%rax,(%rdx)
        +	movq	%rbx,8(%rdx)
        +	jmp	L$cbc_done
        +
        +.p2align	4
        +L$cbc_done:
        +	movq	48(%rsp),%rcx
        +	movq	0(%rcx),%r15
        +	movq	8(%rcx),%r14
        +	movq	16(%rcx),%r13
        +	movq	24(%rcx),%r12
        +	movq	32(%rcx),%rbp
        +	movq	40(%rcx),%rbx
        +	leaq	48(%rcx),%rsp
        +L$cbc_abort:
        +	.byte	0xf3,0xc3
        +
        +
        +.byte	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s
        new file mode 100644
        index 000000000..cdecac7b4
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/md5/md5-x86_64.s
        @@ -0,0 +1,670 @@
        +.text
        +
        +.p2align	4
        +
        +.globl	_md5_block_asm_data_order
        +
        +_md5_block_asm_data_order:
        +	pushq	%rbp
        +	pushq	%rbx
        +	pushq	%r12
        +	pushq	%r14
        +	pushq	%r15
        +L$prologue:
        +
        +
        +
        +
        +	movq	%rdi,%rbp
        +	shlq	$6,%rdx
        +	leaq	(%rsi,%rdx,1),%rdi
        +	movl	0(%rbp),%eax
        +	movl	4(%rbp),%ebx
        +	movl	8(%rbp),%ecx
        +	movl	12(%rbp),%edx
        +
        +
        +
        +
        +
        +
        +
        +	cmpq	%rdi,%rsi
        +	je	L$end
        +
        +
        +
        +L$loop:
        +	movl	%eax,%r8d
        +	movl	%ebx,%r9d
        +	movl	%ecx,%r14d
        +	movl	%edx,%r15d
        +	movl	0(%rsi),%r10d
        +	movl	%edx,%r11d
        +	xorl	%ecx,%r11d
        +	leal	-680876936(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	4(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	-389564586(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	8(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	606105819(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	12(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	-1044525330(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	16(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	xorl	%ecx,%r11d
        +	leal	-176418897(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	20(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	1200080426(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	24(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	-1473231341(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	28(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	-45705983(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	32(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	xorl	%ecx,%r11d
        +	leal	1770035416(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	36(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	-1958414417(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	40(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	-42063(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	44(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	-1990404162(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	48(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	xorl	%ecx,%r11d
        +	leal	1804603682(%rax,%r10,1),%eax
        +	andl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	movl	52(%rsi),%r10d
        +	addl	%r11d,%eax
        +	roll	$7,%eax
        +	movl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	xorl	%ebx,%r11d
        +	leal	-40341101(%rdx,%r10,1),%edx
        +	andl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	movl	56(%rsi),%r10d
        +	addl	%r11d,%edx
        +	roll	$12,%edx
        +	movl	%ebx,%r11d
        +	addl	%eax,%edx
        +	xorl	%eax,%r11d
        +	leal	-1502002290(%rcx,%r10,1),%ecx
        +	andl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	movl	60(%rsi),%r10d
        +	addl	%r11d,%ecx
        +	roll	$17,%ecx
        +	movl	%eax,%r11d
        +	addl	%edx,%ecx
        +	xorl	%edx,%r11d
        +	leal	1236535329(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	movl	0(%rsi),%r10d
        +	addl	%r11d,%ebx
        +	roll	$22,%ebx
        +	movl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	movl	4(%rsi),%r10d
        +	movl	%edx,%r11d
        +	movl	%edx,%r12d
        +	notl	%r11d
        +	leal	-165796510(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	24(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	-1069501632(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	44(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	643717713(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	0(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	-373897302(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	20(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	notl	%r11d
        +	leal	-701558691(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	40(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	38016083(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	60(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	-660478335(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	16(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	-405537848(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	36(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	notl	%r11d
        +	leal	568446438(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	56(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	-1019803690(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	12(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	-187363961(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	32(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	1163531501(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	52(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	notl	%r11d
        +	leal	-1444681467(%rax,%r10,1),%eax
        +	andl	%ebx,%r12d
        +	andl	%ecx,%r11d
        +	movl	8(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ecx,%r11d
        +	addl	%r12d,%eax
        +	movl	%ecx,%r12d
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	notl	%r11d
        +	leal	-51403784(%rdx,%r10,1),%edx
        +	andl	%eax,%r12d
        +	andl	%ebx,%r11d
        +	movl	28(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%ebx,%r11d
        +	addl	%r12d,%edx
        +	movl	%ebx,%r12d
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	notl	%r11d
        +	leal	1735328473(%rcx,%r10,1),%ecx
        +	andl	%edx,%r12d
        +	andl	%eax,%r11d
        +	movl	48(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%eax,%r11d
        +	addl	%r12d,%ecx
        +	movl	%eax,%r12d
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	notl	%r11d
        +	leal	-1926607734(%rbx,%r10,1),%ebx
        +	andl	%ecx,%r12d
        +	andl	%edx,%r11d
        +	movl	0(%rsi),%r10d
        +	orl	%r11d,%r12d
        +	movl	%edx,%r11d
        +	addl	%r12d,%ebx
        +	movl	%edx,%r12d
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	movl	20(%rsi),%r10d
        +	movl	%ecx,%r11d
        +	leal	-378558(%rax,%r10,1),%eax
        +	movl	32(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	-2022574463(%rdx,%r10,1),%edx
        +	movl	44(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	1839030562(%rcx,%r10,1),%ecx
        +	movl	56(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	-35309556(%rbx,%r10,1),%ebx
        +	movl	4(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	leal	-1530992060(%rax,%r10,1),%eax
        +	movl	16(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	1272893353(%rdx,%r10,1),%edx
        +	movl	28(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	-155497632(%rcx,%r10,1),%ecx
        +	movl	40(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	-1094730640(%rbx,%r10,1),%ebx
        +	movl	52(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	leal	681279174(%rax,%r10,1),%eax
        +	movl	0(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	-358537222(%rdx,%r10,1),%edx
        +	movl	12(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	-722521979(%rcx,%r10,1),%ecx
        +	movl	24(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	76029189(%rbx,%r10,1),%ebx
        +	movl	36(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	leal	-640364487(%rax,%r10,1),%eax
        +	movl	48(%rsi),%r10d
        +	xorl	%edx,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%eax
        +	roll	$4,%eax
        +	movl	%ebx,%r11d
        +	addl	%ebx,%eax
        +	leal	-421815835(%rdx,%r10,1),%edx
        +	movl	60(%rsi),%r10d
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%edx
        +	roll	$11,%edx
        +	movl	%eax,%r11d
        +	addl	%eax,%edx
        +	leal	530742520(%rcx,%r10,1),%ecx
        +	movl	8(%rsi),%r10d
        +	xorl	%ebx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ecx
        +	roll	$16,%ecx
        +	movl	%edx,%r11d
        +	addl	%edx,%ecx
        +	leal	-995338651(%rbx,%r10,1),%ebx
        +	movl	0(%rsi),%r10d
        +	xorl	%eax,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%ebx
        +	roll	$23,%ebx
        +	movl	%ecx,%r11d
        +	addl	%ecx,%ebx
        +	movl	0(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	xorl	%edx,%r11d
        +	leal	-198630844(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	28(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	1126891415(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	56(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	-1416354905(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	20(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	-57434055(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	48(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	leal	1700485571(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	12(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	-1894986606(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	40(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	-1051523(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	4(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	-2054922799(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	32(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	leal	1873313359(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	60(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	-30611744(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	24(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	-1560198380(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	52(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	1309151649(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	16(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +	leal	-145523070(%rax,%r10,1),%eax
        +	orl	%ebx,%r11d
        +	xorl	%ecx,%r11d
        +	addl	%r11d,%eax
        +	movl	44(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$6,%eax
        +	xorl	%ecx,%r11d
        +	addl	%ebx,%eax
        +	leal	-1120210379(%rdx,%r10,1),%edx
        +	orl	%eax,%r11d
        +	xorl	%ebx,%r11d
        +	addl	%r11d,%edx
        +	movl	8(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$10,%edx
        +	xorl	%ebx,%r11d
        +	addl	%eax,%edx
        +	leal	718787259(%rcx,%r10,1),%ecx
        +	orl	%edx,%r11d
        +	xorl	%eax,%r11d
        +	addl	%r11d,%ecx
        +	movl	36(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$15,%ecx
        +	xorl	%eax,%r11d
        +	addl	%edx,%ecx
        +	leal	-343485551(%rbx,%r10,1),%ebx
        +	orl	%ecx,%r11d
        +	xorl	%edx,%r11d
        +	addl	%r11d,%ebx
        +	movl	0(%rsi),%r10d
        +	movl	$4294967295,%r11d
        +	roll	$21,%ebx
        +	xorl	%edx,%r11d
        +	addl	%ecx,%ebx
        +
        +	addl	%r8d,%eax
        +	addl	%r9d,%ebx
        +	addl	%r14d,%ecx
        +	addl	%r15d,%edx
        +
        +
        +	addq	$64,%rsi
        +	cmpq	%rdi,%rsi
        +	jb	L$loop
        +
        +
        +
        +L$end:
        +	movl	%eax,0(%rbp)
        +	movl	%ebx,4(%rbp)
        +	movl	%ecx,8(%rbp)
        +	movl	%edx,12(%rbp)
        +
        +	movq	(%rsp),%r15
        +	movq	8(%rsp),%r14
        +	movq	16(%rsp),%r12
        +	movq	24(%rsp),%rbx
        +	movq	32(%rsp),%rbp
        +	addq	$40,%rsp
        +L$epilogue:
        +	.byte	0xf3,0xc3
        diff --git a/vendor/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s
        new file mode 100644
        index 000000000..85f9905a8
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/rc4/rc4-md5-x86_64.s
        @@ -0,0 +1,1259 @@
        +.text
        +
        +.p2align	4
        +
        +.globl	_rc4_md5_enc
        +
        +_rc4_md5_enc:
        +	cmpq	$0,%r9
        +	je	L$abort
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	subq	$40,%rsp
        +L$body:
        +	movq	%rcx,%r11
        +	movq	%r9,%r12
        +	movq	%rsi,%r13
        +	movq	%rdx,%r14
        +	movq	%r8,%r15
        +	xorq	%rbp,%rbp
        +	xorq	%rcx,%rcx
        +
        +	leaq	8(%rdi),%rdi
        +	movb	-8(%rdi),%bpl
        +	movb	-4(%rdi),%cl
        +
        +	incb	%bpl
        +	subq	%r13,%r14
        +	movl	(%rdi,%rbp,4),%eax
        +	addb	%al,%cl
        +	leaq	(%rdi,%rbp,4),%rsi
        +	shlq	$6,%r12
        +	addq	%r15,%r12
        +	movq	%r12,16(%rsp)
        +
        +	movq	%r11,24(%rsp)
        +	movl	0(%r11),%r8d
        +	movl	4(%r11),%r9d
        +	movl	8(%r11),%r10d
        +	movl	12(%r11),%r11d
        +	jmp	L$oop
        +
        +.p2align	4
        +L$oop:
        +	movl	%r8d,0(%rsp)
        +	movl	%r9d,4(%rsp)
        +	movl	%r10d,8(%rsp)
        +	movl	%r11d,%r12d
        +	movl	%r11d,12(%rsp)
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	0(%r15),%r8d
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	addl	$3614090360,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,0(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	4(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	8(%rsi),%eax
        +	addl	$3905402710,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,4(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	8(%r15),%r10d
        +	addb	%dl,%al
        +	movl	12(%rsi),%ebx
        +	addl	$606105819,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,8(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	12(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	16(%rsi),%eax
        +	addl	$3250441966,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,12(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	16(%r15),%r8d
        +	addb	%dl,%al
        +	movl	20(%rsi),%ebx
        +	addl	$4118548399,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,16(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	20(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	24(%rsi),%eax
        +	addl	$1200080426,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,20(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	24(%r15),%r10d
        +	addb	%dl,%al
        +	movl	28(%rsi),%ebx
        +	addl	$2821735955,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,24(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	28(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	32(%rsi),%eax
        +	addl	$4249261313,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,28(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	32(%r15),%r8d
        +	addb	%dl,%al
        +	movl	36(%rsi),%ebx
        +	addl	$1770035416,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,32(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	36(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	40(%rsi),%eax
        +	addl	$2336552879,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,36(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	40(%r15),%r10d
        +	addb	%dl,%al
        +	movl	44(%rsi),%ebx
        +	addl	$4294925233,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,40(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	44(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	48(%rsi),%eax
        +	addl	$2304563134,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,44(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	48(%r15),%r8d
        +	addb	%dl,%al
        +	movl	52(%rsi),%ebx
        +	addl	$1804603682,%r8d
        +	xorl	%r11d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,48(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$7,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	52(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	56(%rsi),%eax
        +	addl	$4254626195,%r11d
        +	xorl	%r10d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,52(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$12,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	56(%r15),%r10d
        +	addb	%dl,%al
        +	movl	60(%rsi),%ebx
        +	addl	$2792965006,%r10d
        +	xorl	%r9d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,56(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$17,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	(%r13),%xmm2
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	60(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	64(%rsi),%eax
        +	addl	$1236535329,%r9d
        +	xorl	%r8d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,60(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$22,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm1,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	4(%r15),%r8d
        +	addb	%dl,%al
        +	movl	68(%rsi),%ebx
        +	addl	$4129170786,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,64(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	24(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	72(%rsi),%eax
        +	addl	$3225465664,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,68(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	44(%r15),%r10d
        +	addb	%dl,%al
        +	movl	76(%rsi),%ebx
        +	addl	$643717713,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,72(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	0(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	80(%rsi),%eax
        +	addl	$3921069994,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,76(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	20(%r15),%r8d
        +	addb	%dl,%al
        +	movl	84(%rsi),%ebx
        +	addl	$3593408605,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,80(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	40(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	88(%rsi),%eax
        +	addl	$38016083,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,84(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	60(%r15),%r10d
        +	addb	%dl,%al
        +	movl	92(%rsi),%ebx
        +	addl	$3634488961,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,88(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	16(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	96(%rsi),%eax
        +	addl	$3889429448,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,92(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	36(%r15),%r8d
        +	addb	%dl,%al
        +	movl	100(%rsi),%ebx
        +	addl	$568446438,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,96(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	56(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	104(%rsi),%eax
        +	addl	$3275163606,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,100(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	12(%r15),%r10d
        +	addb	%dl,%al
        +	movl	108(%rsi),%ebx
        +	addl	$4107603335,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,104(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	32(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	112(%rsi),%eax
        +	addl	$1163531501,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,108(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r10d,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r11d,%r12d
        +	addl	52(%r15),%r8d
        +	addb	%dl,%al
        +	movl	116(%rsi),%ebx
        +	addl	$2850285829,%r8d
        +	xorl	%r10d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,112(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$5,%r8d
        +	movl	%r9d,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r10d,%r12d
        +	addl	8(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	120(%rsi),%eax
        +	addl	$4243563512,%r11d
        +	xorl	%r9d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,116(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$9,%r11d
        +	movl	%r8d,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	andl	%r9d,%r12d
        +	addl	28(%r15),%r10d
        +	addb	%dl,%al
        +	movl	124(%rsi),%ebx
        +	addl	$1735328473,%r10d
        +	xorl	%r8d,%r12d
        +	movzbl	%al,%eax
        +	movl	%edx,120(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$14,%r10d
        +	movl	%r11d,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	16(%r13),%xmm3
        +	addb	$32,%bpl
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	andl	%r8d,%r12d
        +	addl	48(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	0(%rdi,%rbp,4),%eax
        +	addl	$2368359562,%r9d
        +	xorl	%r11d,%r12d
        +	movzbl	%bl,%ebx
        +	movl	%edx,124(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$20,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movq	%rcx,%rsi
        +	xorq	%rcx,%rcx
        +	movb	%sil,%cl
        +	leaq	(%rdi,%rbp,4),%rsi
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm1,%xmm3
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	20(%r15),%r8d
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	addl	$4294588738,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,0(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	32(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	8(%rsi),%eax
        +	addl	$2272392833,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,4(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	44(%r15),%r10d
        +	addb	%dl,%al
        +	movl	12(%rsi),%ebx
        +	addl	$1839030562,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,8(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	56(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	16(%rsi),%eax
        +	addl	$4259657740,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,12(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	4(%r15),%r8d
        +	addb	%dl,%al
        +	movl	20(%rsi),%ebx
        +	addl	$2763975236,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,16(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	16(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	24(%rsi),%eax
        +	addl	$1272893353,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,20(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	28(%r15),%r10d
        +	addb	%dl,%al
        +	movl	28(%rsi),%ebx
        +	addl	$4139469664,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,24(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	40(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	32(%rsi),%eax
        +	addl	$3200236656,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,28(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	52(%r15),%r8d
        +	addb	%dl,%al
        +	movl	36(%rsi),%ebx
        +	addl	$681279174,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,32(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	0(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	40(%rsi),%eax
        +	addl	$3936430074,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,36(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	12(%r15),%r10d
        +	addb	%dl,%al
        +	movl	44(%rsi),%ebx
        +	addl	$3572445317,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,40(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	24(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	48(%rsi),%eax
        +	addl	$76029189,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,44(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	%r11d,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r9d,%r12d
        +	addl	36(%r15),%r8d
        +	addb	%dl,%al
        +	movl	52(%rsi),%ebx
        +	addl	$3654602809,%r8d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r8d
        +	movl	%edx,48(%rsi)
        +	addb	%bl,%cl
        +	roll	$4,%r8d
        +	movl	%r10d,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r8d,%r12d
        +	addl	48(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	56(%rsi),%eax
        +	addl	$3873151461,%r11d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r11d
        +	movl	%edx,52(%rsi)
        +	addb	%al,%cl
        +	roll	$11,%r11d
        +	movl	%r9d,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	xorl	%r11d,%r12d
        +	addl	60(%r15),%r10d
        +	addb	%dl,%al
        +	movl	60(%rsi),%ebx
        +	addl	$530742520,%r10d
        +	movzbl	%al,%eax
        +	addl	%r12d,%r10d
        +	movl	%edx,56(%rsi)
        +	addb	%bl,%cl
        +	roll	$16,%r10d
        +	movl	%r8d,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	32(%r13),%xmm4
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	xorl	%r10d,%r12d
        +	addl	8(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	64(%rsi),%eax
        +	addl	$3299628645,%r9d
        +	movzbl	%bl,%ebx
        +	addl	%r12d,%r9d
        +	movl	%edx,60(%rsi)
        +	addb	%al,%cl
        +	roll	$23,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm1,%xmm4
        +	pxor	%xmm0,%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	0(%r15),%r8d
        +	addb	%dl,%al
        +	movl	68(%rsi),%ebx
        +	addl	$4096336452,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,64(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	movd	(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	pxor	%xmm1,%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	28(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	72(%rsi),%eax
        +	addl	$1126891415,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,68(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	movd	(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	56(%r15),%r10d
        +	addb	%dl,%al
        +	movl	76(%rsi),%ebx
        +	addl	$2878612391,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,72(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	20(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	80(%rsi),%eax
        +	addl	$4237533241,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,76(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	48(%r15),%r8d
        +	addb	%dl,%al
        +	movl	84(%rsi),%ebx
        +	addl	$1700485571,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,80(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	12(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	88(%rsi),%eax
        +	addl	$2399980690,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,84(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	40(%r15),%r10d
        +	addb	%dl,%al
        +	movl	92(%rsi),%ebx
        +	addl	$4293915773,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,88(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	4(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	96(%rsi),%eax
        +	addl	$2240044497,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,92(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	32(%r15),%r8d
        +	addb	%dl,%al
        +	movl	100(%rsi),%ebx
        +	addl	$1873313359,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,96(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	60(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	104(%rsi),%eax
        +	addl	$4264355552,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,100(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	24(%r15),%r10d
        +	addb	%dl,%al
        +	movl	108(%rsi),%ebx
        +	addl	$2734768916,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,104(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	52(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	112(%rsi),%eax
        +	addl	$1309151649,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,108(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r11d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r9d,%r12d
        +	addl	16(%r15),%r8d
        +	addb	%dl,%al
        +	movl	116(%rsi),%ebx
        +	addl	$4149444226,%r8d
        +	movzbl	%al,%eax
        +	xorl	%r10d,%r12d
        +	movl	%edx,112(%rsi)
        +	addl	%r12d,%r8d
        +	addb	%bl,%cl
        +	roll	$6,%r8d
        +	movl	$-1,%r12d
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r9d,%r8d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r10d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r8d,%r12d
        +	addl	44(%r15),%r11d
        +	addb	%dl,%bl
        +	movl	120(%rsi),%eax
        +	addl	$3174756917,%r11d
        +	movzbl	%bl,%ebx
        +	xorl	%r9d,%r12d
        +	movl	%edx,116(%rsi)
        +	addl	%r12d,%r11d
        +	addb	%al,%cl
        +	roll	$10,%r11d
        +	movl	$-1,%r12d
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r8d,%r11d
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r9d,%r12d
        +	movl	%eax,(%rdi,%rcx,4)
        +	orl	%r11d,%r12d
        +	addl	8(%r15),%r10d
        +	addb	%dl,%al
        +	movl	124(%rsi),%ebx
        +	addl	$718787259,%r10d
        +	movzbl	%al,%eax
        +	xorl	%r8d,%r12d
        +	movl	%edx,120(%rsi)
        +	addl	%r12d,%r10d
        +	addb	%bl,%cl
        +	roll	$15,%r10d
        +	movl	$-1,%r12d
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +
        +	addl	%r11d,%r10d
        +	movdqu	48(%r13),%xmm5
        +	addb	$32,%bpl
        +	movl	(%rdi,%rcx,4),%edx
        +	xorl	%r8d,%r12d
        +	movl	%ebx,(%rdi,%rcx,4)
        +	orl	%r10d,%r12d
        +	addl	36(%r15),%r9d
        +	addb	%dl,%bl
        +	movl	0(%rdi,%rbp,4),%eax
        +	addl	$3951481745,%r9d
        +	movzbl	%bl,%ebx
        +	xorl	%r11d,%r12d
        +	movl	%edx,124(%rsi)
        +	addl	%r12d,%r9d
        +	addb	%al,%cl
        +	roll	$21,%r9d
        +	movl	$-1,%r12d
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +
        +	addl	%r10d,%r9d
        +	movq	%rbp,%rsi
        +	xorq	%rbp,%rbp
        +	movb	%sil,%bpl
        +	movq	%rcx,%rsi
        +	xorq	%rcx,%rcx
        +	movb	%sil,%cl
        +	leaq	(%rdi,%rbp,4),%rsi
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm5
        +	pxor	%xmm1,%xmm5
        +	addl	0(%rsp),%r8d
        +	addl	4(%rsp),%r9d
        +	addl	8(%rsp),%r10d
        +	addl	12(%rsp),%r11d
        +
        +	movdqu	%xmm2,(%r14,%r13,1)
        +	movdqu	%xmm3,16(%r14,%r13,1)
        +	movdqu	%xmm4,32(%r14,%r13,1)
        +	movdqu	%xmm5,48(%r14,%r13,1)
        +	leaq	64(%r15),%r15
        +	leaq	64(%r13),%r13
        +	cmpq	16(%rsp),%r15
        +	jb	L$oop
        +
        +	movq	24(%rsp),%r12
        +	subb	%al,%cl
        +	movl	%r8d,0(%r12)
        +	movl	%r9d,4(%r12)
        +	movl	%r10d,8(%r12)
        +	movl	%r11d,12(%r12)
        +	subb	$1,%bpl
        +	movl	%ebp,-8(%rdi)
        +	movl	%ecx,-4(%rdi)
        +
        +	movq	40(%rsp),%r15
        +	movq	48(%rsp),%r14
        +	movq	56(%rsp),%r13
        +	movq	64(%rsp),%r12
        +	movq	72(%rsp),%rbp
        +	movq	80(%rsp),%rbx
        +	leaq	88(%rsp),%rsp
        +L$epilogue:
        +L$abort:
        +	.byte	0xf3,0xc3
        diff --git a/vendor/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s
        new file mode 100644
        index 000000000..8c4f29ecb
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/rc4/rc4-x86_64.s
        @@ -0,0 +1,623 @@
        +.text
        +
        +
        +
        +.globl	_RC4
        +
        +.p2align	4
        +_RC4:	orq	%rsi,%rsi
        +	jne	L$entry
        +	.byte	0xf3,0xc3
        +L$entry:
        +	pushq	%rbx
        +	pushq	%r12
        +	pushq	%r13
        +L$prologue:
        +	movq	%rsi,%r11
        +	movq	%rdx,%r12
        +	movq	%rcx,%r13
        +	xorq	%r10,%r10
        +	xorq	%rcx,%rcx
        +
        +	leaq	8(%rdi),%rdi
        +	movb	-8(%rdi),%r10b
        +	movb	-4(%rdi),%cl
        +	cmpl	$-1,256(%rdi)
        +	je	L$RC4_CHAR
        +	movl	_OPENSSL_ia32cap_P(%rip),%r8d
        +	xorq	%rbx,%rbx
        +	incb	%r10b
        +	subq	%r10,%rbx
        +	subq	%r12,%r13
        +	movl	(%rdi,%r10,4),%eax
        +	testq	$-16,%r11
        +	jz	L$loop1
        +	btl	$30,%r8d
        +	jc	L$intel
        +	andq	$7,%rbx
        +	leaq	1(%r10),%rsi
        +	jz	L$oop8
        +	subq	%rbx,%r11
        +L$oop8_warmup:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	%edx,(%rdi,%r10,4)
        +	addb	%dl,%al
        +	incb	%r10b
        +	movl	(%rdi,%rax,4),%edx
        +	movl	(%rdi,%r10,4),%eax
        +	xorb	(%r12),%dl
        +	movb	%dl,(%r13,%r12,1)
        +	leaq	1(%r12),%r12
        +	decq	%rbx
        +	jnz	L$oop8_warmup
        +
        +	leaq	1(%r10),%rsi
        +	jmp	L$oop8
        +.p2align	4
        +L$oop8:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	0(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,0(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	4(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,4(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	8(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,8(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	12(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,12(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	16(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,16(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	20(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,20(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	24(%rdi,%rsi,4),%ebx
        +	rorq	$8,%r8
        +	movl	%edx,24(%rdi,%r10,4)
        +	addb	%al,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	$8,%sil
        +	addb	%bl,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	movl	-4(%rdi,%rsi,4),%eax
        +	rorq	$8,%r8
        +	movl	%edx,28(%rdi,%r10,4)
        +	addb	%bl,%dl
        +	movb	(%rdi,%rdx,4),%r8b
        +	addb	$8,%r10b
        +	rorq	$8,%r8
        +	subq	$8,%r11
        +
        +	xorq	(%r12),%r8
        +	movq	%r8,(%r13,%r12,1)
        +	leaq	8(%r12),%r12
        +
        +	testq	$-8,%r11
        +	jnz	L$oop8
        +	cmpq	$0,%r11
        +	jne	L$loop1
        +	jmp	L$exit
        +
        +.p2align	4
        +L$intel:
        +	testq	$-32,%r11
        +	jz	L$loop1
        +	andq	$15,%rbx
        +	jz	L$oop16_is_hot
        +	subq	%rbx,%r11
        +L$oop16_warmup:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	%edx,(%rdi,%r10,4)
        +	addb	%dl,%al
        +	incb	%r10b
        +	movl	(%rdi,%rax,4),%edx
        +	movl	(%rdi,%r10,4),%eax
        +	xorb	(%r12),%dl
        +	movb	%dl,(%r13,%r12,1)
        +	leaq	1(%r12),%r12
        +	decq	%rbx
        +	jnz	L$oop16_warmup
        +
        +	movq	%rcx,%rbx
        +	xorq	%rcx,%rcx
        +	movb	%bl,%cl
        +
        +L$oop16_is_hot:
        +	leaq	(%rdi,%r10,4),%rsi
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	pxor	%xmm0,%xmm0
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,0(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$0,(%rdi,%rax,4),%xmm0
        +	jmp	L$oop16_enter
        +.p2align	4
        +L$oop16:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	pxor	%xmm0,%xmm2
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	4(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,0(%rsi)
        +	pxor	%xmm1,%xmm2
        +	addb	%bl,%cl
        +	pinsrw	$0,(%rdi,%rax,4),%xmm0
        +	movdqu	%xmm2,(%r13,%r12,1)
        +	leaq	16(%r12),%r12
        +L$oop16_enter:
        +	movl	(%rdi,%rcx,4),%edx
        +	pxor	%xmm1,%xmm1
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	8(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,4(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$0,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	12(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,8(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$1,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	16(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,12(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$1,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	20(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,16(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$2,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	24(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,20(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$2,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	28(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,24(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$3,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	32(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,28(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$3,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	36(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,32(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$4,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	40(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,36(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$4,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	44(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,40(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$5,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	48(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,44(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$5,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	52(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,48(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$6,(%rdi,%rax,4),%xmm0
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movl	56(%rsi),%eax
        +	movzbl	%bl,%ebx
        +	movl	%edx,52(%rsi)
        +	addb	%al,%cl
        +	pinsrw	$6,(%rdi,%rbx,4),%xmm1
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	addb	%dl,%al
        +	movl	60(%rsi),%ebx
        +	movzbl	%al,%eax
        +	movl	%edx,56(%rsi)
        +	addb	%bl,%cl
        +	pinsrw	$7,(%rdi,%rax,4),%xmm0
        +	addb	$16,%r10b
        +	movdqu	(%r12),%xmm2
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%ebx,(%rdi,%rcx,4)
        +	addb	%dl,%bl
        +	movzbl	%bl,%ebx
        +	movl	%edx,60(%rsi)
        +	leaq	(%rdi,%r10,4),%rsi
        +	pinsrw	$7,(%rdi,%rbx,4),%xmm1
        +	movl	(%rsi),%eax
        +	movq	%rcx,%rbx
        +	xorq	%rcx,%rcx
        +	subq	$16,%r11
        +	movb	%bl,%cl
        +	testq	$-16,%r11
        +	jnz	L$oop16
        +
        +	psllq	$8,%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm1,%xmm2
        +	movdqu	%xmm2,(%r13,%r12,1)
        +	leaq	16(%r12),%r12
        +
        +	cmpq	$0,%r11
        +	jne	L$loop1
        +	jmp	L$exit
        +
        +.p2align	4
        +L$loop1:
        +	addb	%al,%cl
        +	movl	(%rdi,%rcx,4),%edx
        +	movl	%eax,(%rdi,%rcx,4)
        +	movl	%edx,(%rdi,%r10,4)
        +	addb	%dl,%al
        +	incb	%r10b
        +	movl	(%rdi,%rax,4),%edx
        +	movl	(%rdi,%r10,4),%eax
        +	xorb	(%r12),%dl
        +	movb	%dl,(%r13,%r12,1)
        +	leaq	1(%r12),%r12
        +	decq	%r11
        +	jnz	L$loop1
        +	jmp	L$exit
        +
        +.p2align	4
        +L$RC4_CHAR:
        +	addb	$1,%r10b
        +	movzbl	(%rdi,%r10,1),%eax
        +	testq	$-8,%r11
        +	jz	L$cloop1
        +	jmp	L$cloop8
        +.p2align	4
        +L$cloop8:
        +	movl	(%r12),%r8d
        +	movl	4(%r12),%r9d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	L$cmov0
        +
        +	movq	%rax,%rbx
        +L$cmov0:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	L$cmov1
        +
        +	movq	%rbx,%rax
        +L$cmov1:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	L$cmov2
        +
        +	movq	%rax,%rbx
        +L$cmov2:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	L$cmov3
        +
        +	movq	%rbx,%rax
        +L$cmov3:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r8b
        +	rorl	$8,%r8d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	L$cmov4
        +
        +	movq	%rax,%rbx
        +L$cmov4:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	L$cmov5
        +
        +	movq	%rbx,%rax
        +L$cmov5:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	addb	%al,%cl
        +	leaq	1(%r10),%rsi
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%sil,%esi
        +	movzbl	(%rdi,%rsi,1),%ebx
        +	movb	%al,(%rdi,%rcx,1)
        +	cmpq	%rsi,%rcx
        +	movb	%dl,(%rdi,%r10,1)
        +	jne	L$cmov6
        +
        +	movq	%rax,%rbx
        +L$cmov6:
        +	addb	%al,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	addb	%bl,%cl
        +	leaq	1(%rsi),%r10
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%r10,1),%eax
        +	movb	%bl,(%rdi,%rcx,1)
        +	cmpq	%r10,%rcx
        +	movb	%dl,(%rdi,%rsi,1)
        +	jne	L$cmov7
        +
        +	movq	%rbx,%rax
        +L$cmov7:
        +	addb	%bl,%dl
        +	xorb	(%rdi,%rdx,1),%r9b
        +	rorl	$8,%r9d
        +	leaq	-8(%r11),%r11
        +	movl	%r8d,(%r13)
        +	leaq	8(%r12),%r12
        +	movl	%r9d,4(%r13)
        +	leaq	8(%r13),%r13
        +
        +	testq	$-8,%r11
        +	jnz	L$cloop8
        +	cmpq	$0,%r11
        +	jne	L$cloop1
        +	jmp	L$exit
        +.p2align	4
        +L$cloop1:
        +	addb	%al,%cl
        +	movzbl	%cl,%ecx
        +	movzbl	(%rdi,%rcx,1),%edx
        +	movb	%al,(%rdi,%rcx,1)
        +	movb	%dl,(%rdi,%r10,1)
        +	addb	%al,%dl
        +	addb	$1,%r10b
        +	movzbl	%dl,%edx
        +	movzbl	%r10b,%r10d
        +	movzbl	(%rdi,%rdx,1),%edx
        +	movzbl	(%rdi,%r10,1),%eax
        +	xorb	(%r12),%dl
        +	leaq	1(%r12),%r12
        +	movb	%dl,(%r13)
        +	leaq	1(%r13),%r13
        +	subq	$1,%r11
        +	jnz	L$cloop1
        +	jmp	L$exit
        +
        +.p2align	4
        +L$exit:
        +	subb	$1,%r10b
        +	movl	%r10d,-8(%rdi)
        +	movl	%ecx,-4(%rdi)
        +
        +	movq	(%rsp),%r13
        +	movq	8(%rsp),%r12
        +	movq	16(%rsp),%rbx
        +	addq	$24,%rsp
        +L$epilogue:
        +	.byte	0xf3,0xc3
        +
        +.globl	_private_RC4_set_key
        +
        +.p2align	4
        +_private_RC4_set_key:
        +	leaq	8(%rdi),%rdi
        +	leaq	(%rdx,%rsi,1),%rdx
        +	negq	%rsi
        +	movq	%rsi,%rcx
        +	xorl	%eax,%eax
        +	xorq	%r9,%r9
        +	xorq	%r10,%r10
        +	xorq	%r11,%r11
        +
        +	movl	_OPENSSL_ia32cap_P(%rip),%r8d
        +	btl	$20,%r8d
        +	jc	L$c1stloop
        +	jmp	L$w1stloop
        +
        +.p2align	4
        +L$w1stloop:
        +	movl	%eax,(%rdi,%rax,4)
        +	addb	$1,%al
        +	jnc	L$w1stloop
        +
        +	xorq	%r9,%r9
        +	xorq	%r8,%r8
        +.p2align	4
        +L$w2ndloop:
        +	movl	(%rdi,%r9,4),%r10d
        +	addb	(%rdx,%rsi,1),%r8b
        +	addb	%r10b,%r8b
        +	addq	$1,%rsi
        +	movl	(%rdi,%r8,4),%r11d
        +	cmovzq	%rcx,%rsi
        +	movl	%r10d,(%rdi,%r8,4)
        +	movl	%r11d,(%rdi,%r9,4)
        +	addb	$1,%r9b
        +	jnc	L$w2ndloop
        +	jmp	L$exit_key
        +
        +.p2align	4
        +L$c1stloop:
        +	movb	%al,(%rdi,%rax,1)
        +	addb	$1,%al
        +	jnc	L$c1stloop
        +
        +	xorq	%r9,%r9
        +	xorq	%r8,%r8
        +.p2align	4
        +L$c2ndloop:
        +	movb	(%rdi,%r9,1),%r10b
        +	addb	(%rdx,%rsi,1),%r8b
        +	addb	%r10b,%r8b
        +	addq	$1,%rsi
        +	movb	(%rdi,%r8,1),%r11b
        +	jnz	L$cnowrap
        +	movq	%rcx,%rsi
        +L$cnowrap:
        +	movb	%r10b,(%rdi,%r8,1)
        +	movb	%r11b,(%rdi,%r9,1)
        +	addb	$1,%r9b
        +	jnc	L$c2ndloop
        +	movl	$-1,256(%rdi)
        +
        +.p2align	4
        +L$exit_key:
        +	xorl	%eax,%eax
        +	movl	%eax,-8(%rdi)
        +	movl	%eax,-4(%rdi)
        +	.byte	0xf3,0xc3
        +
        +
        +.globl	_RC4_options
        +
        +.p2align	4
        +_RC4_options:
        +	leaq	L$opts(%rip),%rax
        +	movl	_OPENSSL_ia32cap_P(%rip),%edx
        +	btl	$20,%edx
        +	jc	L$8xchar
        +	btl	$30,%edx
        +	jnc	L$done
        +	addq	$25,%rax
        +	.byte	0xf3,0xc3
        +L$8xchar:
        +	addq	$12,%rax
        +L$done:
        +	.byte	0xf3,0xc3
        +.p2align	6
        +L$opts:
        +.byte	114,99,52,40,56,120,44,105,110,116,41,0
        +.byte	114,99,52,40,56,120,44,99,104,97,114,41,0
        +.byte	114,99,52,40,49,54,120,44,105,110,116,41,0
        +.byte	82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.p2align	6
        diff --git a/vendor/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s
        new file mode 100644
        index 000000000..9bb9bf0f2
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/sha/sha1-x86_64.s
        @@ -0,0 +1,2492 @@
        +.text
        +
        +
        +
        +.globl	_sha1_block_data_order
        +
        +.p2align	4
        +_sha1_block_data_order:
        +	movl	_OPENSSL_ia32cap_P+0(%rip),%r9d
        +	movl	_OPENSSL_ia32cap_P+4(%rip),%r8d
        +	testl	$512,%r8d
        +	jz	L$ialu
        +	jmp	_ssse3_shortcut
        +
        +.p2align	4
        +L$ialu:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	movq	%rsp,%r11
        +	movq	%rdi,%r8
        +	subq	$72,%rsp
        +	movq	%rsi,%r9
        +	andq	$-64,%rsp
        +	movq	%rdx,%r10
        +	movq	%r11,64(%rsp)
        +L$prologue:
        +
        +	movl	0(%r8),%esi
        +	movl	4(%r8),%edi
        +	movl	8(%r8),%r11d
        +	movl	12(%r8),%r12d
        +	movl	16(%r8),%r13d
        +	jmp	L$loop
        +
        +.p2align	4
        +L$loop:
        +	movl	0(%r9),%edx
        +	bswapl	%edx
        +	movl	%edx,0(%rsp)
        +	movl	%r11d,%eax
        +	movl	4(%r9),%ebp
        +	movl	%esi,%ecx
        +	xorl	%r12d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r13,1),%r13d
        +	andl	%edi,%eax
        +	movl	%ebp,4(%rsp)
        +	addl	%ecx,%r13d
        +	xorl	%r12d,%eax
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	movl	%edi,%eax
        +	movl	8(%r9),%edx
        +	movl	%r13d,%ecx
        +	xorl	%r11d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r12,1),%r12d
        +	andl	%esi,%eax
        +	movl	%edx,8(%rsp)
        +	addl	%ecx,%r12d
        +	xorl	%r11d,%eax
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	movl	%esi,%eax
        +	movl	12(%r9),%ebp
        +	movl	%r12d,%ecx
        +	xorl	%edi,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r11,1),%r11d
        +	andl	%r13d,%eax
        +	movl	%ebp,12(%rsp)
        +	addl	%ecx,%r11d
        +	xorl	%edi,%eax
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	movl	%r13d,%eax
        +	movl	16(%r9),%edx
        +	movl	%r11d,%ecx
        +	xorl	%esi,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%rdi,1),%edi
        +	andl	%r12d,%eax
        +	movl	%edx,16(%rsp)
        +	addl	%ecx,%edi
        +	xorl	%esi,%eax
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	movl	%r12d,%eax
        +	movl	20(%r9),%ebp
        +	movl	%edi,%ecx
        +	xorl	%r13d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%rsi,1),%esi
        +	andl	%r11d,%eax
        +	movl	%ebp,20(%rsp)
        +	addl	%ecx,%esi
        +	xorl	%r13d,%eax
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	movl	%r11d,%eax
        +	movl	24(%r9),%edx
        +	movl	%esi,%ecx
        +	xorl	%r12d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r13,1),%r13d
        +	andl	%edi,%eax
        +	movl	%edx,24(%rsp)
        +	addl	%ecx,%r13d
        +	xorl	%r12d,%eax
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	movl	%edi,%eax
        +	movl	28(%r9),%ebp
        +	movl	%r13d,%ecx
        +	xorl	%r11d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r12,1),%r12d
        +	andl	%esi,%eax
        +	movl	%ebp,28(%rsp)
        +	addl	%ecx,%r12d
        +	xorl	%r11d,%eax
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	movl	%esi,%eax
        +	movl	32(%r9),%edx
        +	movl	%r12d,%ecx
        +	xorl	%edi,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r11,1),%r11d
        +	andl	%r13d,%eax
        +	movl	%edx,32(%rsp)
        +	addl	%ecx,%r11d
        +	xorl	%edi,%eax
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	movl	%r13d,%eax
        +	movl	36(%r9),%ebp
        +	movl	%r11d,%ecx
        +	xorl	%esi,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%rdi,1),%edi
        +	andl	%r12d,%eax
        +	movl	%ebp,36(%rsp)
        +	addl	%ecx,%edi
        +	xorl	%esi,%eax
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	movl	%r12d,%eax
        +	movl	40(%r9),%edx
        +	movl	%edi,%ecx
        +	xorl	%r13d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%rsi,1),%esi
        +	andl	%r11d,%eax
        +	movl	%edx,40(%rsp)
        +	addl	%ecx,%esi
        +	xorl	%r13d,%eax
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	movl	%r11d,%eax
        +	movl	44(%r9),%ebp
        +	movl	%esi,%ecx
        +	xorl	%r12d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r13,1),%r13d
        +	andl	%edi,%eax
        +	movl	%ebp,44(%rsp)
        +	addl	%ecx,%r13d
        +	xorl	%r12d,%eax
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	movl	%edi,%eax
        +	movl	48(%r9),%edx
        +	movl	%r13d,%ecx
        +	xorl	%r11d,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%r12,1),%r12d
        +	andl	%esi,%eax
        +	movl	%edx,48(%rsp)
        +	addl	%ecx,%r12d
        +	xorl	%r11d,%eax
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	movl	%esi,%eax
        +	movl	52(%r9),%ebp
        +	movl	%r12d,%ecx
        +	xorl	%edi,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%r11,1),%r11d
        +	andl	%r13d,%eax
        +	movl	%ebp,52(%rsp)
        +	addl	%ecx,%r11d
        +	xorl	%edi,%eax
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	movl	%r13d,%eax
        +	movl	56(%r9),%edx
        +	movl	%r11d,%ecx
        +	xorl	%esi,%eax
        +	bswapl	%edx
        +	roll	$5,%ecx
        +	leal	1518500249(%rbp,%rdi,1),%edi
        +	andl	%r12d,%eax
        +	movl	%edx,56(%rsp)
        +	addl	%ecx,%edi
        +	xorl	%esi,%eax
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	movl	%r12d,%eax
        +	movl	60(%r9),%ebp
        +	movl	%edi,%ecx
        +	xorl	%r13d,%eax
        +	bswapl	%ebp
        +	roll	$5,%ecx
        +	leal	1518500249(%rdx,%rsi,1),%esi
        +	andl	%r11d,%eax
        +	movl	%ebp,60(%rsp)
        +	addl	%ecx,%esi
        +	xorl	%r13d,%eax
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	movl	0(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	xorl	32(%rsp),%edx
        +	andl	%edi,%eax
        +	leal	1518500249(%rbp,%r13,1),%r13d
        +	xorl	52(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$1,%edx
        +	addl	%ecx,%r13d
        +	roll	$30,%edi
        +	movl	%edx,0(%rsp)
        +	addl	%eax,%r13d
        +	movl	4(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	xorl	36(%rsp),%ebp
        +	andl	%esi,%eax
        +	leal	1518500249(%rdx,%r12,1),%r12d
        +	xorl	56(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$1,%ebp
        +	addl	%ecx,%r12d
        +	roll	$30,%esi
        +	movl	%ebp,4(%rsp)
        +	addl	%eax,%r12d
        +	movl	8(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	xorl	40(%rsp),%edx
        +	andl	%r13d,%eax
        +	leal	1518500249(%rbp,%r11,1),%r11d
        +	xorl	60(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$1,%edx
        +	addl	%ecx,%r11d
        +	roll	$30,%r13d
        +	movl	%edx,8(%rsp)
        +	addl	%eax,%r11d
        +	movl	12(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	xorl	44(%rsp),%ebp
        +	andl	%r12d,%eax
        +	leal	1518500249(%rdx,%rdi,1),%edi
        +	xorl	0(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$1,%ebp
        +	addl	%ecx,%edi
        +	roll	$30,%r12d
        +	movl	%ebp,12(%rsp)
        +	addl	%eax,%edi
        +	movl	16(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	xorl	48(%rsp),%edx
        +	andl	%r11d,%eax
        +	leal	1518500249(%rbp,%rsi,1),%esi
        +	xorl	4(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$1,%edx
        +	addl	%ecx,%esi
        +	roll	$30,%r11d
        +	movl	%edx,16(%rsp)
        +	addl	%eax,%esi
        +	movl	20(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r13,1),%r13d
        +	xorl	52(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	8(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,20(%rsp)
        +	movl	24(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r12,1),%r12d
        +	xorl	56(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	12(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,24(%rsp)
        +	movl	28(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r11,1),%r11d
        +	xorl	60(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	16(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,28(%rsp)
        +	movl	32(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rdi,1),%edi
        +	xorl	0(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	20(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,32(%rsp)
        +	movl	36(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	44(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rsi,1),%esi
        +	xorl	4(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	24(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,36(%rsp)
        +	movl	40(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	48(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r13,1),%r13d
        +	xorl	8(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	28(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,40(%rsp)
        +	movl	44(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	52(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r12,1),%r12d
        +	xorl	12(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	32(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	%ebp,44(%rsp)
        +	movl	48(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	56(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r11,1),%r11d
        +	xorl	16(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	36(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	%edx,48(%rsp)
        +	movl	52(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rdi,1),%edi
        +	xorl	20(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	40(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%ebp,52(%rsp)
        +	movl	56(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rsi,1),%esi
        +	xorl	24(%rsp),%edx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	44(%rsp),%edx
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%edx
        +	movl	%edx,56(%rsp)
        +	movl	60(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r13,1),%r13d
        +	xorl	28(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	48(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,60(%rsp)
        +	movl	0(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r12,1),%r12d
        +	xorl	32(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	52(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,0(%rsp)
        +	movl	4(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r11,1),%r11d
        +	xorl	36(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	56(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,4(%rsp)
        +	movl	8(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rdi,1),%edi
        +	xorl	40(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	60(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,8(%rsp)
        +	movl	12(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rsi,1),%esi
        +	xorl	44(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	0(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,12(%rsp)
        +	movl	16(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r13,1),%r13d
        +	xorl	48(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	4(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,16(%rsp)
        +	movl	20(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%r12,1),%r12d
        +	xorl	52(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	8(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	%ebp,20(%rsp)
        +	movl	24(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%r11,1),%r11d
        +	xorl	56(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	12(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	%edx,24(%rsp)
        +	movl	28(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rdx,%rdi,1),%edi
        +	xorl	60(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	16(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%ebp,28(%rsp)
        +	movl	32(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	1859775393(%rbp,%rsi,1),%esi
        +	xorl	0(%rsp),%edx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	20(%rsp),%edx
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%edx
        +	movl	%edx,32(%rsp)
        +	movl	36(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	44(%rsp),%ebp
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rdx,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	24(%rsp),%ebp
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%ebp,36(%rsp)
        +	addl	%ecx,%r13d
        +	movl	40(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	48(%rsp),%edx
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rbp,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	28(%rsp),%edx
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%edx,40(%rsp)
        +	addl	%ecx,%r12d
        +	movl	44(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	52(%rsp),%ebp
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rdx,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	32(%rsp),%ebp
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%ebp,44(%rsp)
        +	addl	%ecx,%r11d
        +	movl	48(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	56(%rsp),%edx
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rbp,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	36(%rsp),%edx
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%edx,48(%rsp)
        +	addl	%ecx,%edi
        +	movl	52(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	60(%rsp),%ebp
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rdx,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	40(%rsp),%ebp
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%ebp,52(%rsp)
        +	addl	%ecx,%esi
        +	movl	56(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	0(%rsp),%edx
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rbp,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	44(%rsp),%edx
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%edx,56(%rsp)
        +	addl	%ecx,%r13d
        +	movl	60(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	4(%rsp),%ebp
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rdx,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	48(%rsp),%ebp
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%ebp,60(%rsp)
        +	addl	%ecx,%r12d
        +	movl	0(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	8(%rsp),%edx
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rbp,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	52(%rsp),%edx
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%edx,0(%rsp)
        +	addl	%ecx,%r11d
        +	movl	4(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	12(%rsp),%ebp
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rdx,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	56(%rsp),%ebp
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%ebp,4(%rsp)
        +	addl	%ecx,%edi
        +	movl	8(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	16(%rsp),%edx
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rbp,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	60(%rsp),%edx
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%edx,8(%rsp)
        +	addl	%ecx,%esi
        +	movl	12(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	20(%rsp),%ebp
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	44(%rsp),%ebp
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rdx,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	0(%rsp),%ebp
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%ebp,12(%rsp)
        +	addl	%ecx,%r13d
        +	movl	16(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	24(%rsp),%edx
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	48(%rsp),%edx
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rbp,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	4(%rsp),%edx
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%edx,16(%rsp)
        +	addl	%ecx,%r12d
        +	movl	20(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	28(%rsp),%ebp
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	52(%rsp),%ebp
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rdx,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	8(%rsp),%ebp
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%ebp,20(%rsp)
        +	addl	%ecx,%r11d
        +	movl	24(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	32(%rsp),%edx
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	56(%rsp),%edx
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rbp,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	12(%rsp),%edx
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%edx,24(%rsp)
        +	addl	%ecx,%edi
        +	movl	28(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	36(%rsp),%ebp
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rdx,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	16(%rsp),%ebp
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%ebp,28(%rsp)
        +	addl	%ecx,%esi
        +	movl	32(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%r11d,%ebx
        +	xorl	40(%rsp),%edx
        +	andl	%r12d,%eax
        +	movl	%esi,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%r12d,%ebx
        +	leal	-1894007588(%rbp,%r13,1),%r13d
        +	roll	$5,%ecx
        +	xorl	20(%rsp),%edx
        +	addl	%eax,%r13d
        +	andl	%edi,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r13d
        +	roll	$30,%edi
        +	movl	%edx,32(%rsp)
        +	addl	%ecx,%r13d
        +	movl	36(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%edi,%ebx
        +	xorl	44(%rsp),%ebp
        +	andl	%r11d,%eax
        +	movl	%r13d,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r11d,%ebx
        +	leal	-1894007588(%rdx,%r12,1),%r12d
        +	roll	$5,%ecx
        +	xorl	24(%rsp),%ebp
        +	addl	%eax,%r12d
        +	andl	%esi,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%r12d
        +	roll	$30,%esi
        +	movl	%ebp,36(%rsp)
        +	addl	%ecx,%r12d
        +	movl	40(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%esi,%ebx
        +	xorl	48(%rsp),%edx
        +	andl	%edi,%eax
        +	movl	%r12d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%edi,%ebx
        +	leal	-1894007588(%rbp,%r11,1),%r11d
        +	roll	$5,%ecx
        +	xorl	28(%rsp),%edx
        +	addl	%eax,%r11d
        +	andl	%r13d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%r11d
        +	roll	$30,%r13d
        +	movl	%edx,40(%rsp)
        +	addl	%ecx,%r11d
        +	movl	44(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r13d,%ebx
        +	xorl	52(%rsp),%ebp
        +	andl	%esi,%eax
        +	movl	%r11d,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%esi,%ebx
        +	leal	-1894007588(%rdx,%rdi,1),%edi
        +	roll	$5,%ecx
        +	xorl	32(%rsp),%ebp
        +	addl	%eax,%edi
        +	andl	%r12d,%ebx
        +	roll	$1,%ebp
        +	addl	%ebx,%edi
        +	roll	$30,%r12d
        +	movl	%ebp,44(%rsp)
        +	addl	%ecx,%edi
        +	movl	48(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%r12d,%ebx
        +	xorl	56(%rsp),%edx
        +	andl	%r13d,%eax
        +	movl	%edi,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%r13d,%ebx
        +	leal	-1894007588(%rbp,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	36(%rsp),%edx
        +	addl	%eax,%esi
        +	andl	%r11d,%ebx
        +	roll	$1,%edx
        +	addl	%ebx,%esi
        +	roll	$30,%r11d
        +	movl	%edx,48(%rsp)
        +	addl	%ecx,%esi
        +	movl	52(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r13,1),%r13d
        +	xorl	20(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	40(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,52(%rsp)
        +	movl	56(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r12,1),%r12d
        +	xorl	24(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	44(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,56(%rsp)
        +	movl	60(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r11,1),%r11d
        +	xorl	28(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	48(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,60(%rsp)
        +	movl	0(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	8(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%rdi,1),%edi
        +	xorl	32(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	52(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,0(%rsp)
        +	movl	4(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	12(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rsi,1),%esi
        +	xorl	36(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	56(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,4(%rsp)
        +	movl	8(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	16(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r13,1),%r13d
        +	xorl	40(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	60(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,8(%rsp)
        +	movl	12(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	20(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r12,1),%r12d
        +	xorl	44(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	0(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	%ebp,12(%rsp)
        +	movl	16(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	24(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r11,1),%r11d
        +	xorl	48(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	4(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	%edx,16(%rsp)
        +	movl	20(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	28(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rdi,1),%edi
        +	xorl	52(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	8(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%ebp,20(%rsp)
        +	movl	24(%rsp),%edx
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	32(%rsp),%edx
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%rsi,1),%esi
        +	xorl	56(%rsp),%edx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	12(%rsp),%edx
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%edx
        +	movl	%edx,24(%rsp)
        +	movl	28(%rsp),%ebp
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	36(%rsp),%ebp
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r13,1),%r13d
        +	xorl	60(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	16(%rsp),%ebp
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%ebp
        +	movl	%ebp,28(%rsp)
        +	movl	32(%rsp),%edx
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	40(%rsp),%edx
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r12,1),%r12d
        +	xorl	0(%rsp),%edx
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	20(%rsp),%edx
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%edx
        +	movl	%edx,32(%rsp)
        +	movl	36(%rsp),%ebp
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	44(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r11,1),%r11d
        +	xorl	4(%rsp),%ebp
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	24(%rsp),%ebp
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%ebp
        +	movl	%ebp,36(%rsp)
        +	movl	40(%rsp),%edx
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	48(%rsp),%edx
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%rdi,1),%edi
        +	xorl	8(%rsp),%edx
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	28(%rsp),%edx
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%edx
        +	movl	%edx,40(%rsp)
        +	movl	44(%rsp),%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	52(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rsi,1),%esi
        +	xorl	12(%rsp),%ebp
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	xorl	32(%rsp),%ebp
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	roll	$1,%ebp
        +	movl	%ebp,44(%rsp)
        +	movl	48(%rsp),%edx
        +	movl	%r11d,%eax
        +	movl	%esi,%ecx
        +	xorl	56(%rsp),%edx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r13,1),%r13d
        +	xorl	16(%rsp),%edx
        +	xorl	%r12d,%eax
        +	addl	%ecx,%r13d
        +	xorl	36(%rsp),%edx
        +	roll	$30,%edi
        +	addl	%eax,%r13d
        +	roll	$1,%edx
        +	movl	%edx,48(%rsp)
        +	movl	52(%rsp),%ebp
        +	movl	%edi,%eax
        +	movl	%r13d,%ecx
        +	xorl	60(%rsp),%ebp
        +	xorl	%esi,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%r12,1),%r12d
        +	xorl	20(%rsp),%ebp
        +	xorl	%r11d,%eax
        +	addl	%ecx,%r12d
        +	xorl	40(%rsp),%ebp
        +	roll	$30,%esi
        +	addl	%eax,%r12d
        +	roll	$1,%ebp
        +	movl	56(%rsp),%edx
        +	movl	%esi,%eax
        +	movl	%r12d,%ecx
        +	xorl	0(%rsp),%edx
        +	xorl	%r13d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rbp,%r11,1),%r11d
        +	xorl	24(%rsp),%edx
        +	xorl	%edi,%eax
        +	addl	%ecx,%r11d
        +	xorl	44(%rsp),%edx
        +	roll	$30,%r13d
        +	addl	%eax,%r11d
        +	roll	$1,%edx
        +	movl	60(%rsp),%ebp
        +	movl	%r13d,%eax
        +	movl	%r11d,%ecx
        +	xorl	4(%rsp),%ebp
        +	xorl	%r12d,%eax
        +	roll	$5,%ecx
        +	leal	-899497514(%rdx,%rdi,1),%edi
        +	xorl	28(%rsp),%ebp
        +	xorl	%esi,%eax
        +	addl	%ecx,%edi
        +	xorl	48(%rsp),%ebp
        +	roll	$30,%r12d
        +	addl	%eax,%edi
        +	roll	$1,%ebp
        +	movl	%r12d,%eax
        +	movl	%edi,%ecx
        +	xorl	%r11d,%eax
        +	leal	-899497514(%rbp,%rsi,1),%esi
        +	roll	$5,%ecx
        +	xorl	%r13d,%eax
        +	addl	%ecx,%esi
        +	roll	$30,%r11d
        +	addl	%eax,%esi
        +	addl	0(%r8),%esi
        +	addl	4(%r8),%edi
        +	addl	8(%r8),%r11d
        +	addl	12(%r8),%r12d
        +	addl	16(%r8),%r13d
        +	movl	%esi,0(%r8)
        +	movl	%edi,4(%r8)
        +	movl	%r11d,8(%r8)
        +	movl	%r12d,12(%r8)
        +	movl	%r13d,16(%r8)
        +
        +	subq	$1,%r10
        +	leaq	64(%r9),%r9
        +	jnz	L$loop
        +
        +	movq	64(%rsp),%rsi
        +	movq	(%rsi),%r13
        +	movq	8(%rsi),%r12
        +	movq	16(%rsi),%rbp
        +	movq	24(%rsi),%rbx
        +	leaq	32(%rsi),%rsp
        +L$epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	4
        +sha1_block_data_order_ssse3:
        +_ssse3_shortcut:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	leaq	-64(%rsp),%rsp
        +	movq	%rdi,%r8
        +	movq	%rsi,%r9
        +	movq	%rdx,%r10
        +
        +	shlq	$6,%r10
        +	addq	%r9,%r10
        +	leaq	K_XX_XX(%rip),%r11
        +
        +	movl	0(%r8),%eax
        +	movl	4(%r8),%ebx
        +	movl	8(%r8),%ecx
        +	movl	12(%r8),%edx
        +	movl	%ebx,%esi
        +	movl	16(%r8),%ebp
        +
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r9),%xmm0
        +	movdqu	16(%r9),%xmm1
        +	movdqu	32(%r9),%xmm2
        +	movdqu	48(%r9),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r9
        +.byte	102,15,56,0,206
        +.byte	102,15,56,0,214
        +.byte	102,15,56,0,222
        +	paddd	%xmm9,%xmm0
        +	paddd	%xmm9,%xmm1
        +	paddd	%xmm9,%xmm2
        +	movdqa	%xmm0,0(%rsp)
        +	psubd	%xmm9,%xmm0
        +	movdqa	%xmm1,16(%rsp)
        +	psubd	%xmm9,%xmm1
        +	movdqa	%xmm2,32(%rsp)
        +	psubd	%xmm9,%xmm2
        +	jmp	L$oop_ssse3
        +.p2align	4
        +L$oop_ssse3:
        +	movdqa	%xmm1,%xmm4
        +	addl	0(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	movdqa	%xmm3,%xmm8
        +.byte	102,15,58,15,224,8
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	paddd	%xmm3,%xmm9
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrldq	$4,%xmm8
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	pxor	%xmm0,%xmm4
        +	rorl	$2,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm2,%xmm8
        +	addl	4(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pxor	%xmm8,%xmm4
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm9,48(%rsp)
        +	xorl	%ecx,%edi
        +	addl	%ebp,%edx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm4,%xmm8
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	8(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	pslldq	$12,%xmm10
        +	paddd	%xmm4,%xmm4
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrld	$31,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm4
        +	addl	12(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm4
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	0(%r11),%xmm10
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	pxor	%xmm9,%xmm4
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movdqa	%xmm2,%xmm5
        +	addl	16(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movdqa	%xmm4,%xmm9
        +.byte	102,15,58,15,233,8
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	paddd	%xmm4,%xmm10
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrldq	$4,%xmm9
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	pxor	%xmm1,%xmm5
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm3,%xmm9
        +	addl	20(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pxor	%xmm9,%xmm5
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	%xmm10,0(%rsp)
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm5,%xmm9
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	24(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	pslldq	$12,%xmm8
        +	paddd	%xmm5,%xmm5
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	psrld	$31,%xmm9
        +	xorl	%ecx,%esi
        +	addl	%ebp,%edx
        +	movdqa	%xmm8,%xmm10
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	psrld	$30,%xmm8
        +	por	%xmm9,%xmm5
        +	addl	28(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	pslld	$2,%xmm10
        +	pxor	%xmm8,%xmm5
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	16(%r11),%xmm8
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	pxor	%xmm10,%xmm5
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movdqa	%xmm3,%xmm6
        +	addl	32(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movdqa	%xmm5,%xmm10
        +.byte	102,15,58,15,242,8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	paddd	%xmm5,%xmm8
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	psrldq	$4,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	pxor	%xmm2,%xmm6
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm4,%xmm10
        +	addl	36(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	pxor	%xmm10,%xmm6
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm8,16(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm6,%xmm10
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	40(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	pslldq	$12,%xmm9
        +	paddd	%xmm6,%xmm6
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	andl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	psrld	$31,%xmm10
        +	xorl	%edx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	psrld	$30,%xmm9
        +	por	%xmm10,%xmm6
        +	addl	44(%rsp),%edx
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	pslld	$2,%xmm8
        +	pxor	%xmm9,%xmm6
        +	andl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	16(%r11),%xmm9
        +	xorl	%ecx,%edi
        +	addl	%ebp,%edx
        +	pxor	%xmm8,%xmm6
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movdqa	%xmm4,%xmm7
        +	addl	48(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm8
        +.byte	102,15,58,15,251,8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm6,%xmm9
        +	andl	%eax,%esi
        +	xorl	%ebx,%eax
        +	psrldq	$4,%xmm8
        +	xorl	%ebx,%esi
        +	addl	%edx,%ecx
        +	pxor	%xmm3,%xmm7
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm5,%xmm8
        +	addl	52(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	pxor	%xmm8,%xmm7
        +	andl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%eax,%edi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm7,%xmm8
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	56(%rsp),%eax
        +	xorl	%ebp,%edx
        +	pslldq	$12,%xmm10
        +	paddd	%xmm7,%xmm7
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	andl	%edx,%esi
        +	xorl	%ebp,%edx
        +	psrld	$31,%xmm8
        +	xorl	%ebp,%esi
        +	addl	%ebx,%eax
        +	movdqa	%xmm10,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	psrld	$30,%xmm10
        +	por	%xmm8,%xmm7
        +	addl	60(%rsp),%ebp
        +	xorl	%edx,%ecx
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	pslld	$2,%xmm9
        +	pxor	%xmm10,%xmm7
        +	andl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	16(%r11),%xmm10
        +	xorl	%edx,%edi
        +	addl	%eax,%ebp
        +	pxor	%xmm9,%xmm7
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movdqa	%xmm7,%xmm9
        +	addl	0(%rsp),%edx
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,206,8
        +	xorl	%ecx,%ebx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm1,%xmm0
        +	andl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm7,%xmm10
        +	xorl	%ecx,%esi
        +	addl	%ebp,%edx
        +	pxor	%xmm9,%xmm0
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	4(%rsp),%ecx
        +	xorl	%ebx,%eax
        +	movdqa	%xmm0,%xmm9
        +	movdqa	%xmm10,48(%rsp)
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	andl	%eax,%edi
        +	xorl	%ebx,%eax
        +	pslld	$2,%xmm0
        +	xorl	%ebx,%edi
        +	addl	%edx,%ecx
        +	psrld	$30,%xmm9
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	8(%rsp),%ebx
        +	xorl	%eax,%ebp
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	por	%xmm9,%xmm0
        +	andl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm0,%xmm10
        +	xorl	%eax,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	12(%rsp),%eax
        +	xorl	%ebp,%edx
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	andl	%edx,%edi
        +	xorl	%ebp,%edx
        +	xorl	%ebp,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	16(%rsp),%ebp
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,215,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm2,%xmm1
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm0,%xmm8
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm10,%xmm1
        +	addl	20(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm1,%xmm10
        +	movdqa	%xmm8,0(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm1
        +	addl	24(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm10
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm10,%xmm1
        +	addl	28(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movdqa	%xmm1,%xmm8
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	32(%rsp),%eax
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,192,8
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	pxor	%xmm3,%xmm2
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	movdqa	32(%r11),%xmm10
        +	paddd	%xmm1,%xmm9
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	pxor	%xmm8,%xmm2
        +	addl	36(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	movdqa	%xmm2,%xmm8
        +	movdqa	%xmm9,16(%rsp)
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	pslld	$2,%xmm2
        +	addl	40(%rsp),%edx
        +	xorl	%ecx,%esi
        +	psrld	$30,%xmm8
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	por	%xmm8,%xmm2
        +	addl	44(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movdqa	%xmm2,%xmm9
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	48(%rsp),%ebx
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,201,8
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	pxor	%xmm4,%xmm3
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm2,%xmm10
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	pxor	%xmm9,%xmm3
        +	addl	52(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	movdqa	%xmm3,%xmm9
        +	movdqa	%xmm10,32(%rsp)
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ebp
        +	xorl	%edx,%esi
        +	psrld	$30,%xmm9
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	por	%xmm9,%xmm3
        +	addl	60(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movdqa	%xmm3,%xmm10
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	0(%rsp),%ecx
        +	pxor	%xmm0,%xmm4
        +.byte	102,68,15,58,15,210,8
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	pxor	%xmm5,%xmm4
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm3,%xmm8
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	pxor	%xmm10,%xmm4
        +	addl	4(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	movdqa	%xmm4,%xmm10
        +	movdqa	%xmm8,48(%rsp)
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	pslld	$2,%xmm4
        +	addl	8(%rsp),%eax
        +	xorl	%ebp,%esi
        +	psrld	$30,%xmm10
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	por	%xmm10,%xmm4
        +	addl	12(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movdqa	%xmm4,%xmm8
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	16(%rsp),%edx
        +	pxor	%xmm1,%xmm5
        +.byte	102,68,15,58,15,195,8
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	pxor	%xmm6,%xmm5
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm4,%xmm9
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	pxor	%xmm8,%xmm5
        +	addl	20(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	movdqa	%xmm5,%xmm8
        +	movdqa	%xmm9,0(%rsp)
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	pslld	$2,%xmm5
        +	addl	24(%rsp),%ebx
        +	xorl	%eax,%esi
        +	psrld	$30,%xmm8
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	por	%xmm8,%xmm5
        +	addl	28(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movdqa	%xmm5,%xmm9
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ecx,%edi
        +	pxor	%xmm2,%xmm6
        +.byte	102,68,15,58,15,204,8
        +	xorl	%edx,%ecx
        +	addl	32(%rsp),%ebp
        +	andl	%edx,%edi
        +	pxor	%xmm7,%xmm6
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm5,%xmm10
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	pxor	%xmm9,%xmm6
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movdqa	%xmm6,%xmm9
        +	movdqa	%xmm10,16(%rsp)
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	36(%rsp),%edx
        +	andl	%ecx,%esi
        +	pslld	$2,%xmm6
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	psrld	$30,%xmm9
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	por	%xmm9,%xmm6
        +	movl	%eax,%edi
        +	xorl	%ebx,%eax
        +	movdqa	%xmm6,%xmm10
        +	addl	40(%rsp),%ecx
        +	andl	%ebx,%edi
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	44(%rsp),%ebx
        +	andl	%eax,%esi
        +	andl	%ebp,%edi
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%edi
        +	pxor	%xmm3,%xmm7
        +.byte	102,68,15,58,15,213,8
        +	xorl	%ebp,%edx
        +	addl	48(%rsp),%eax
        +	andl	%ebp,%edi
        +	pxor	%xmm0,%xmm7
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	movdqa	48(%r11),%xmm9
        +	paddd	%xmm6,%xmm8
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	pxor	%xmm10,%xmm7
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movdqa	%xmm7,%xmm10
        +	movdqa	%xmm8,32(%rsp)
        +	movl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	addl	52(%rsp),%ebp
        +	andl	%edx,%esi
        +	pslld	$2,%xmm7
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	psrld	$30,%xmm10
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	por	%xmm10,%xmm7
        +	movl	%ebx,%edi
        +	xorl	%ecx,%ebx
        +	movdqa	%xmm7,%xmm8
        +	addl	56(%rsp),%edx
        +	andl	%ecx,%edi
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	60(%rsp),%ecx
        +	andl	%ebx,%esi
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movl	%ebp,%edi
        +	pxor	%xmm4,%xmm0
        +.byte	102,68,15,58,15,198,8
        +	xorl	%eax,%ebp
        +	addl	0(%rsp),%ebx
        +	andl	%eax,%edi
        +	pxor	%xmm1,%xmm0
        +	andl	%ebp,%esi
        +	rorl	$7,%edx
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm7,%xmm9
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	pxor	%xmm8,%xmm0
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movdqa	%xmm0,%xmm8
        +	movdqa	%xmm9,48(%rsp)
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	4(%rsp),%eax
        +	andl	%ebp,%esi
        +	pslld	$2,%xmm0
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	psrld	$30,%xmm8
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	por	%xmm8,%xmm0
        +	movl	%ecx,%edi
        +	xorl	%edx,%ecx
        +	movdqa	%xmm0,%xmm9
        +	addl	8(%rsp),%ebp
        +	andl	%edx,%edi
        +	andl	%ecx,%esi
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	addl	%esi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%esi
        +	xorl	%ecx,%ebx
        +	addl	12(%rsp),%edx
        +	andl	%ecx,%esi
        +	andl	%ebx,%edi
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	addl	%edi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movl	%eax,%edi
        +	pxor	%xmm5,%xmm1
        +.byte	102,68,15,58,15,207,8
        +	xorl	%ebx,%eax
        +	addl	16(%rsp),%ecx
        +	andl	%ebx,%edi
        +	pxor	%xmm2,%xmm1
        +	andl	%eax,%esi
        +	rorl	$7,%ebp
        +	movdqa	%xmm10,%xmm8
        +	paddd	%xmm0,%xmm10
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	pxor	%xmm9,%xmm1
        +	roll	$5,%edx
        +	addl	%esi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	movdqa	%xmm1,%xmm9
        +	movdqa	%xmm10,0(%rsp)
        +	movl	%ebp,%esi
        +	xorl	%eax,%ebp
        +	addl	20(%rsp),%ebx
        +	andl	%eax,%esi
        +	pslld	$2,%xmm1
        +	andl	%ebp,%edi
        +	rorl	$7,%edx
        +	psrld	$30,%xmm9
        +	addl	%esi,%ebx
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	addl	%edi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	por	%xmm9,%xmm1
        +	movl	%edx,%edi
        +	xorl	%ebp,%edx
        +	movdqa	%xmm1,%xmm10
        +	addl	24(%rsp),%eax
        +	andl	%ebp,%edi
        +	andl	%edx,%esi
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	addl	%esi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	movl	%ecx,%esi
        +	xorl	%edx,%ecx
        +	addl	28(%rsp),%ebp
        +	andl	%edx,%esi
        +	andl	%ecx,%edi
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	addl	%edi,%ebp
        +	xorl	%edx,%ecx
        +	addl	%eax,%ebp
        +	movl	%ebx,%edi
        +	pxor	%xmm6,%xmm2
        +.byte	102,68,15,58,15,208,8
        +	xorl	%ecx,%ebx
        +	addl	32(%rsp),%edx
        +	andl	%ecx,%edi
        +	pxor	%xmm3,%xmm2
        +	andl	%ebx,%esi
        +	rorl	$7,%eax
        +	movdqa	%xmm8,%xmm9
        +	paddd	%xmm1,%xmm8
        +	addl	%edi,%edx
        +	movl	%ebp,%edi
        +	pxor	%xmm10,%xmm2
        +	roll	$5,%ebp
        +	addl	%esi,%edx
        +	xorl	%ecx,%ebx
        +	addl	%ebp,%edx
        +	movdqa	%xmm2,%xmm10
        +	movdqa	%xmm8,16(%rsp)
        +	movl	%eax,%esi
        +	xorl	%ebx,%eax
        +	addl	36(%rsp),%ecx
        +	andl	%ebx,%esi
        +	pslld	$2,%xmm2
        +	andl	%eax,%edi
        +	rorl	$7,%ebp
        +	psrld	$30,%xmm10
        +	addl	%esi,%ecx
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	addl	%edi,%ecx
        +	xorl	%ebx,%eax
        +	addl	%edx,%ecx
        +	por	%xmm10,%xmm2
        +	movl	%ebp,%edi
        +	xorl	%eax,%ebp
        +	movdqa	%xmm2,%xmm8
        +	addl	40(%rsp),%ebx
        +	andl	%eax,%edi
        +	andl	%ebp,%esi
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	addl	%esi,%ebx
        +	xorl	%eax,%ebp
        +	addl	%ecx,%ebx
        +	movl	%edx,%esi
        +	xorl	%ebp,%edx
        +	addl	44(%rsp),%eax
        +	andl	%ebp,%esi
        +	andl	%edx,%edi
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	addl	%edi,%eax
        +	xorl	%ebp,%edx
        +	addl	%ebx,%eax
        +	addl	48(%rsp),%ebp
        +	pxor	%xmm7,%xmm3
        +.byte	102,68,15,58,15,193,8
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	pxor	%xmm4,%xmm3
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	movdqa	%xmm9,%xmm10
        +	paddd	%xmm2,%xmm9
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	pxor	%xmm8,%xmm3
        +	addl	52(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	movdqa	%xmm3,%xmm8
        +	movdqa	%xmm9,32(%rsp)
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	pslld	$2,%xmm3
        +	addl	56(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	psrld	$30,%xmm8
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	por	%xmm8,%xmm3
        +	addl	60(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	0(%rsp),%eax
        +	paddd	%xmm3,%xmm10
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	movdqa	%xmm10,48(%rsp)
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	4(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	8(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	12(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	cmpq	%r10,%r9
        +	je	L$done_ssse3
        +	movdqa	64(%r11),%xmm6
        +	movdqa	0(%r11),%xmm9
        +	movdqu	0(%r9),%xmm0
        +	movdqu	16(%r9),%xmm1
        +	movdqu	32(%r9),%xmm2
        +	movdqu	48(%r9),%xmm3
        +.byte	102,15,56,0,198
        +	addq	$64,%r9
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +.byte	102,15,56,0,206
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	paddd	%xmm9,%xmm0
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	movdqa	%xmm0,0(%rsp)
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	psubd	%xmm9,%xmm0
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +.byte	102,15,56,0,214
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	paddd	%xmm9,%xmm1
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	movdqa	%xmm1,16(%rsp)
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	psubd	%xmm9,%xmm1
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +.byte	102,15,56,0,222
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	paddd	%xmm9,%xmm2
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	movdqa	%xmm2,32(%rsp)
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	psubd	%xmm9,%xmm2
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	0(%r8),%eax
        +	addl	4(%r8),%esi
        +	addl	8(%r8),%ecx
        +	addl	12(%r8),%edx
        +	movl	%eax,0(%r8)
        +	addl	16(%r8),%ebp
        +	movl	%esi,4(%r8)
        +	movl	%esi,%ebx
        +	movl	%ecx,8(%r8)
        +	movl	%edx,12(%r8)
        +	movl	%ebp,16(%r8)
        +	jmp	L$oop_ssse3
        +
        +.p2align	4
        +L$done_ssse3:
        +	addl	16(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	20(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	24(%rsp),%ebp
        +	xorl	%edx,%esi
        +	movl	%eax,%edi
        +	roll	$5,%eax
        +	xorl	%ecx,%esi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%esi,%ebp
        +	addl	28(%rsp),%edx
        +	xorl	%ecx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%edi,%edx
        +	addl	32(%rsp),%ecx
        +	xorl	%ebx,%esi
        +	movl	%edx,%edi
        +	roll	$5,%edx
        +	xorl	%eax,%esi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%esi,%ecx
        +	addl	36(%rsp),%ebx
        +	xorl	%eax,%edi
        +	movl	%ecx,%esi
        +	roll	$5,%ecx
        +	xorl	%ebp,%edi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%edi,%ebx
        +	addl	40(%rsp),%eax
        +	xorl	%ebp,%esi
        +	movl	%ebx,%edi
        +	roll	$5,%ebx
        +	xorl	%edx,%esi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%esi,%eax
        +	addl	44(%rsp),%ebp
        +	xorl	%edx,%edi
        +	movl	%eax,%esi
        +	roll	$5,%eax
        +	xorl	%ecx,%edi
        +	addl	%eax,%ebp
        +	rorl	$7,%ebx
        +	addl	%edi,%ebp
        +	addl	48(%rsp),%edx
        +	xorl	%ecx,%esi
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%esi
        +	addl	%ebp,%edx
        +	rorl	$7,%eax
        +	addl	%esi,%edx
        +	addl	52(%rsp),%ecx
        +	xorl	%ebx,%edi
        +	movl	%edx,%esi
        +	roll	$5,%edx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	rorl	$7,%ebp
        +	addl	%edi,%ecx
        +	addl	56(%rsp),%ebx
        +	xorl	%eax,%esi
        +	movl	%ecx,%edi
        +	roll	$5,%ecx
        +	xorl	%ebp,%esi
        +	addl	%ecx,%ebx
        +	rorl	$7,%edx
        +	addl	%esi,%ebx
        +	addl	60(%rsp),%eax
        +	xorl	%ebp,%edi
        +	movl	%ebx,%esi
        +	roll	$5,%ebx
        +	xorl	%edx,%edi
        +	addl	%ebx,%eax
        +	rorl	$7,%ecx
        +	addl	%edi,%eax
        +	addl	0(%r8),%eax
        +	addl	4(%r8),%esi
        +	addl	8(%r8),%ecx
        +	movl	%eax,0(%r8)
        +	addl	12(%r8),%edx
        +	movl	%esi,4(%r8)
        +	addl	16(%r8),%ebp
        +	movl	%ecx,8(%r8)
        +	movl	%edx,12(%r8)
        +	movl	%ebp,16(%r8)
        +	leaq	64(%rsp),%rsi
        +	movq	0(%rsi),%r12
        +	movq	8(%rsi),%rbp
        +	movq	16(%rsi),%rbx
        +	leaq	24(%rsi),%rsp
        +L$epilogue_ssse3:
        +	.byte	0xf3,0xc3
        +
        +.p2align	6
        +K_XX_XX:
        +.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999
        +
        +.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1
        +
        +.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc
        +
        +.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6
        +
        +.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
        +
        +.byte	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.p2align	6
        diff --git a/vendor/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s
        new file mode 100644
        index 000000000..dda5a96e9
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/sha/sha512-x86_64.s
        @@ -0,0 +1,1779 @@
        +.text
        +
        +
        +.globl	_sha256_block_data_order
        +
        +.p2align	4
        +_sha256_block_data_order:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +	movq	%rsp,%r11
        +	shlq	$4,%rdx
        +	subq	$64+32,%rsp
        +	leaq	(%rsi,%rdx,4),%rdx
        +	andq	$-64,%rsp
        +	movq	%rdi,64+0(%rsp)
        +	movq	%rsi,64+8(%rsp)
        +	movq	%rdx,64+16(%rsp)
        +	movq	%r11,64+24(%rsp)
        +L$prologue:
        +
        +	leaq	K256(%rip),%rbp
        +
        +	movl	0(%rdi),%eax
        +	movl	4(%rdi),%ebx
        +	movl	8(%rdi),%ecx
        +	movl	12(%rdi),%edx
        +	movl	16(%rdi),%r8d
        +	movl	20(%rdi),%r9d
        +	movl	24(%rdi),%r10d
        +	movl	28(%rdi),%r11d
        +	jmp	L$loop
        +
        +.p2align	4
        +L$loop:
        +	xorq	%rdi,%rdi
        +	movl	0(%rsi),%r12d
        +	movl	%r8d,%r13d
        +	movl	%eax,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,0(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	4(%rsi),%r12d
        +	movl	%edx,%r13d
        +	movl	%r11d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,4(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	8(%rsi),%r12d
        +	movl	%ecx,%r13d
        +	movl	%r10d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,8(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	12(%rsi),%r12d
        +	movl	%ebx,%r13d
        +	movl	%r9d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,12(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	16(%rsi),%r12d
        +	movl	%eax,%r13d
        +	movl	%r8d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,16(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	20(%rsi),%r12d
        +	movl	%r11d,%r13d
        +	movl	%edx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,20(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	24(%rsi),%r12d
        +	movl	%r10d,%r13d
        +	movl	%ecx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,24(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	28(%rsi),%r12d
        +	movl	%r9d,%r13d
        +	movl	%ebx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,28(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	movl	32(%rsi),%r12d
        +	movl	%r8d,%r13d
        +	movl	%eax,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,32(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	36(%rsi),%r12d
        +	movl	%edx,%r13d
        +	movl	%r11d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,36(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	40(%rsi),%r12d
        +	movl	%ecx,%r13d
        +	movl	%r10d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,40(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	44(%rsi),%r12d
        +	movl	%ebx,%r13d
        +	movl	%r9d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,44(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	48(%rsi),%r12d
        +	movl	%eax,%r13d
        +	movl	%r8d,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,48(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	52(%rsi),%r12d
        +	movl	%r11d,%r13d
        +	movl	%edx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,52(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	56(%rsi),%r12d
        +	movl	%r10d,%r13d
        +	movl	%ecx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,56(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	60(%rsi),%r12d
        +	movl	%r9d,%r13d
        +	movl	%ebx,%r14d
        +	bswapl	%r12d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,60(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	jmp	L$rounds_16_xx
        +.p2align	4
        +L$rounds_16_xx:
        +	movl	4(%rsp),%r13d
        +	movl	56(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	36(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	0(%rsp),%r12d
        +	movl	%r8d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%eax,%r14d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,0(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	8(%rsp),%r13d
        +	movl	60(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	40(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	4(%rsp),%r12d
        +	movl	%edx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r11d,%r14d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,4(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	12(%rsp),%r13d
        +	movl	0(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	44(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	8(%rsp),%r12d
        +	movl	%ecx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r10d,%r14d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,8(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	16(%rsp),%r13d
        +	movl	4(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	48(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	12(%rsp),%r12d
        +	movl	%ebx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r9d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,12(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	20(%rsp),%r13d
        +	movl	8(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	52(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	16(%rsp),%r12d
        +	movl	%eax,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r8d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,16(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	24(%rsp),%r13d
        +	movl	12(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	56(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	20(%rsp),%r12d
        +	movl	%r11d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%edx,%r14d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,20(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	28(%rsp),%r13d
        +	movl	16(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	60(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	24(%rsp),%r12d
        +	movl	%r10d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ecx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,24(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	32(%rsp),%r13d
        +	movl	20(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	0(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	28(%rsp),%r12d
        +	movl	%r9d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ebx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,28(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	movl	36(%rsp),%r13d
        +	movl	24(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	4(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	32(%rsp),%r12d
        +	movl	%r8d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%eax,%r14d
        +	rorl	$14,%r13d
        +	movl	%r9d,%r15d
        +	movl	%r12d,32(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r11d,%r12d
        +	xorl	%eax,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r8d,%r15d
        +	movl	%ebx,%r11d
        +
        +	rorl	$11,%r14d
        +	xorl	%r8d,%r13d
        +	xorl	%r10d,%r15d
        +
        +	xorl	%ecx,%r11d
        +	xorl	%eax,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ebx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%eax,%r11d
        +	andl	%ecx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r11d
        +
        +	addl	%r12d,%edx
        +	addl	%r12d,%r11d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r11d
        +
        +	movl	40(%rsp),%r13d
        +	movl	28(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	8(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	36(%rsp),%r12d
        +	movl	%edx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r11d,%r14d
        +	rorl	$14,%r13d
        +	movl	%r8d,%r15d
        +	movl	%r12d,36(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r10d,%r12d
        +	xorl	%r11d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%edx,%r15d
        +	movl	%eax,%r10d
        +
        +	rorl	$11,%r14d
        +	xorl	%edx,%r13d
        +	xorl	%r9d,%r15d
        +
        +	xorl	%ebx,%r10d
        +	xorl	%r11d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%eax,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r11d,%r10d
        +	andl	%ebx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r10d
        +
        +	addl	%r12d,%ecx
        +	addl	%r12d,%r10d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r10d
        +
        +	movl	44(%rsp),%r13d
        +	movl	32(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	12(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	40(%rsp),%r12d
        +	movl	%ecx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r10d,%r14d
        +	rorl	$14,%r13d
        +	movl	%edx,%r15d
        +	movl	%r12d,40(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r9d,%r12d
        +	xorl	%r10d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ecx,%r15d
        +	movl	%r11d,%r9d
        +
        +	rorl	$11,%r14d
        +	xorl	%ecx,%r13d
        +	xorl	%r8d,%r15d
        +
        +	xorl	%eax,%r9d
        +	xorl	%r10d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r11d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r10d,%r9d
        +	andl	%eax,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r9d
        +
        +	addl	%r12d,%ebx
        +	addl	%r12d,%r9d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r9d
        +
        +	movl	48(%rsp),%r13d
        +	movl	36(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	16(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	44(%rsp),%r12d
        +	movl	%ebx,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r9d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ecx,%r15d
        +	movl	%r12d,44(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%r8d,%r12d
        +	xorl	%r9d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%ebx,%r15d
        +	movl	%r10d,%r8d
        +
        +	rorl	$11,%r14d
        +	xorl	%ebx,%r13d
        +	xorl	%edx,%r15d
        +
        +	xorl	%r11d,%r8d
        +	xorl	%r9d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r10d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r9d,%r8d
        +	andl	%r11d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%r8d
        +
        +	addl	%r12d,%eax
        +	addl	%r12d,%r8d
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%r8d
        +
        +	movl	52(%rsp),%r13d
        +	movl	40(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	20(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	48(%rsp),%r12d
        +	movl	%eax,%r13d
        +	addl	%r14d,%r12d
        +	movl	%r8d,%r14d
        +	rorl	$14,%r13d
        +	movl	%ebx,%r15d
        +	movl	%r12d,48(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%edx,%r12d
        +	xorl	%r8d,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%eax,%r15d
        +	movl	%r9d,%edx
        +
        +	rorl	$11,%r14d
        +	xorl	%eax,%r13d
        +	xorl	%ecx,%r15d
        +
        +	xorl	%r10d,%edx
        +	xorl	%r8d,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r9d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%r8d,%edx
        +	andl	%r10d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%edx
        +
        +	addl	%r12d,%r11d
        +	addl	%r12d,%edx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%edx
        +
        +	movl	56(%rsp),%r13d
        +	movl	44(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	24(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	52(%rsp),%r12d
        +	movl	%r11d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%edx,%r14d
        +	rorl	$14,%r13d
        +	movl	%eax,%r15d
        +	movl	%r12d,52(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ecx,%r12d
        +	xorl	%edx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r11d,%r15d
        +	movl	%r8d,%ecx
        +
        +	rorl	$11,%r14d
        +	xorl	%r11d,%r13d
        +	xorl	%ebx,%r15d
        +
        +	xorl	%r9d,%ecx
        +	xorl	%edx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%r8d,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%edx,%ecx
        +	andl	%r9d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ecx
        +
        +	addl	%r12d,%r10d
        +	addl	%r12d,%ecx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ecx
        +
        +	movl	60(%rsp),%r13d
        +	movl	48(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	28(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	56(%rsp),%r12d
        +	movl	%r10d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ecx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r11d,%r15d
        +	movl	%r12d,56(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%ebx,%r12d
        +	xorl	%ecx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r10d,%r15d
        +	movl	%edx,%ebx
        +
        +	rorl	$11,%r14d
        +	xorl	%r10d,%r13d
        +	xorl	%eax,%r15d
        +
        +	xorl	%r8d,%ebx
        +	xorl	%ecx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%edx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ecx,%ebx
        +	andl	%r8d,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%ebx
        +
        +	addl	%r12d,%r9d
        +	addl	%r12d,%ebx
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%ebx
        +
        +	movl	0(%rsp),%r13d
        +	movl	52(%rsp),%r14d
        +	movl	%r13d,%r12d
        +	movl	%r14d,%r15d
        +
        +	rorl	$11,%r12d
        +	xorl	%r13d,%r12d
        +	shrl	$3,%r13d
        +
        +	rorl	$7,%r12d
        +	xorl	%r12d,%r13d
        +	movl	32(%rsp),%r12d
        +
        +	rorl	$2,%r15d
        +	xorl	%r14d,%r15d
        +	shrl	$10,%r14d
        +
        +	rorl	$17,%r15d
        +	addl	%r13d,%r12d
        +	xorl	%r15d,%r14d
        +
        +	addl	60(%rsp),%r12d
        +	movl	%r9d,%r13d
        +	addl	%r14d,%r12d
        +	movl	%ebx,%r14d
        +	rorl	$14,%r13d
        +	movl	%r10d,%r15d
        +	movl	%r12d,60(%rsp)
        +
        +	rorl	$9,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	rorl	$5,%r13d
        +	addl	%eax,%r12d
        +	xorl	%ebx,%r14d
        +
        +	addl	(%rbp,%rdi,4),%r12d
        +	andl	%r9d,%r15d
        +	movl	%ecx,%eax
        +
        +	rorl	$11,%r14d
        +	xorl	%r9d,%r13d
        +	xorl	%r11d,%r15d
        +
        +	xorl	%edx,%eax
        +	xorl	%ebx,%r14d
        +	addl	%r15d,%r12d
        +	movl	%ecx,%r15d
        +
        +	rorl	$6,%r13d
        +	andl	%ebx,%eax
        +	andl	%edx,%r15d
        +
        +	rorl	$2,%r14d
        +	addl	%r13d,%r12d
        +	addl	%r15d,%eax
        +
        +	addl	%r12d,%r8d
        +	addl	%r12d,%eax
        +	leaq	1(%rdi),%rdi
        +	addl	%r14d,%eax
        +
        +	cmpq	$64,%rdi
        +	jb	L$rounds_16_xx
        +
        +	movq	64+0(%rsp),%rdi
        +	leaq	64(%rsi),%rsi
        +
        +	addl	0(%rdi),%eax
        +	addl	4(%rdi),%ebx
        +	addl	8(%rdi),%ecx
        +	addl	12(%rdi),%edx
        +	addl	16(%rdi),%r8d
        +	addl	20(%rdi),%r9d
        +	addl	24(%rdi),%r10d
        +	addl	28(%rdi),%r11d
        +
        +	cmpq	64+16(%rsp),%rsi
        +
        +	movl	%eax,0(%rdi)
        +	movl	%ebx,4(%rdi)
        +	movl	%ecx,8(%rdi)
        +	movl	%edx,12(%rdi)
        +	movl	%r8d,16(%rdi)
        +	movl	%r9d,20(%rdi)
        +	movl	%r10d,24(%rdi)
        +	movl	%r11d,28(%rdi)
        +	jb	L$loop
        +
        +	movq	64+24(%rsp),%rsi
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$epilogue:
        +	.byte	0xf3,0xc3
        +
        +.p2align	6
        +
        +K256:
        +.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        diff --git a/vendor/openssl/asm/x64-macosx-gas/whrlpool/wp-x86_64.s b/vendor/openssl/asm/x64-macosx-gas/whrlpool/wp-x86_64.s
        new file mode 100644
        index 000000000..5e87e554e
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/whrlpool/wp-x86_64.s
        @@ -0,0 +1,859 @@
        +.text
        +
        +
        +.globl	_whirlpool_block
        +
        +.p2align	4
        +_whirlpool_block:
        +	pushq	%rbx
        +	pushq	%rbp
        +	pushq	%r12
        +	pushq	%r13
        +	pushq	%r14
        +	pushq	%r15
        +
        +	movq	%rsp,%r11
        +	subq	$128+40,%rsp
        +	andq	$-64,%rsp
        +
        +	leaq	128(%rsp),%r10
        +	movq	%rdi,0(%r10)
        +	movq	%rsi,8(%r10)
        +	movq	%rdx,16(%r10)
        +	movq	%r11,32(%r10)
        +L$prologue:
        +
        +	movq	%r10,%rbx
        +	leaq	L$table(%rip),%rbp
        +
        +	xorq	%rcx,%rcx
        +	xorq	%rdx,%rdx
        +	movq	0(%rdi),%r8
        +	movq	8(%rdi),%r9
        +	movq	16(%rdi),%r10
        +	movq	24(%rdi),%r11
        +	movq	32(%rdi),%r12
        +	movq	40(%rdi),%r13
        +	movq	48(%rdi),%r14
        +	movq	56(%rdi),%r15
        +L$outerloop:
        +	movq	%r8,0(%rsp)
        +	movq	%r9,8(%rsp)
        +	movq	%r10,16(%rsp)
        +	movq	%r11,24(%rsp)
        +	movq	%r12,32(%rsp)
        +	movq	%r13,40(%rsp)
        +	movq	%r14,48(%rsp)
        +	movq	%r15,56(%rsp)
        +	xorq	0(%rsi),%r8
        +	xorq	8(%rsi),%r9
        +	xorq	16(%rsi),%r10
        +	xorq	24(%rsi),%r11
        +	xorq	32(%rsi),%r12
        +	xorq	40(%rsi),%r13
        +	xorq	48(%rsi),%r14
        +	xorq	56(%rsi),%r15
        +	movq	%r8,64+0(%rsp)
        +	movq	%r9,64+8(%rsp)
        +	movq	%r10,64+16(%rsp)
        +	movq	%r11,64+24(%rsp)
        +	movq	%r12,64+32(%rsp)
        +	movq	%r13,64+40(%rsp)
        +	movq	%r14,64+48(%rsp)
        +	movq	%r15,64+56(%rsp)
        +	xorq	%rsi,%rsi
        +	movq	%rsi,24(%rbx)
        +.p2align	4
        +L$round:
        +	movq	4096(%rbp,%rsi,8),%r8
        +	movl	0(%rsp),%eax
        +	movl	4(%rsp),%ebx
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r8
        +	movq	7(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	0+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	movq	6(%rbp,%rsi,8),%r10
        +	movq	5(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	movq	4(%rbp,%rsi,8),%r12
        +	movq	3(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	0+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	movq	2(%rbp,%rsi,8),%r14
        +	movq	1(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r9
        +	xorq	7(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	8+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r11
        +	xorq	5(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r13
        +	xorq	3(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	8+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r15
        +	xorq	1(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r10
        +	xorq	7(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	16+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r12
        +	xorq	5(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r14
        +	xorq	3(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	16+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r8
        +	xorq	1(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r11
        +	xorq	7(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	24+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r13
        +	xorq	5(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r15
        +	xorq	3(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	24+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r9
        +	xorq	1(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r12
        +	xorq	7(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	32+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r14
        +	xorq	5(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r8
        +	xorq	3(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	32+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r10
        +	xorq	1(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r13
        +	xorq	7(%rbp,%rdi,8),%r14
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	40+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r15
        +	xorq	5(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r9
        +	xorq	3(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	40+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r11
        +	xorq	1(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r14
        +	xorq	7(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	48+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r8
        +	xorq	5(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r10
        +	xorq	3(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	48+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r12
        +	xorq	1(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r15
        +	xorq	7(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	56+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r9
        +	xorq	5(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r11
        +	xorq	3(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	56+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r13
        +	xorq	1(%rbp,%rdi,8),%r14
        +	movq	%r8,0(%rsp)
        +	movq	%r9,8(%rsp)
        +	movq	%r10,16(%rsp)
        +	movq	%r11,24(%rsp)
        +	movq	%r12,32(%rsp)
        +	movq	%r13,40(%rsp)
        +	movq	%r14,48(%rsp)
        +	movq	%r15,56(%rsp)
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r8
        +	xorq	7(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+0+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r10
        +	xorq	5(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r12
        +	xorq	3(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+0+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r14
        +	xorq	1(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r9
        +	xorq	7(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+8+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r11
        +	xorq	5(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r13
        +	xorq	3(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+8+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r15
        +	xorq	1(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r10
        +	xorq	7(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+16+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r12
        +	xorq	5(%rbp,%rdi,8),%r13
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r14
        +	xorq	3(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+16+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r8
        +	xorq	1(%rbp,%rdi,8),%r9
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r11
        +	xorq	7(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+24+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r13
        +	xorq	5(%rbp,%rdi,8),%r14
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r15
        +	xorq	3(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+24+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r9
        +	xorq	1(%rbp,%rdi,8),%r10
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r12
        +	xorq	7(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+32+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r14
        +	xorq	5(%rbp,%rdi,8),%r15
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r8
        +	xorq	3(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+32+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r10
        +	xorq	1(%rbp,%rdi,8),%r11
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r13
        +	xorq	7(%rbp,%rdi,8),%r14
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+40+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r15
        +	xorq	5(%rbp,%rdi,8),%r8
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r9
        +	xorq	3(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+40+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r11
        +	xorq	1(%rbp,%rdi,8),%r12
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r14
        +	xorq	7(%rbp,%rdi,8),%r15
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64+48+8(%rsp),%eax
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r8
        +	xorq	5(%rbp,%rdi,8),%r9
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r10
        +	xorq	3(%rbp,%rdi,8),%r11
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	64+48+8+4(%rsp),%ebx
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r12
        +	xorq	1(%rbp,%rdi,8),%r13
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%eax
        +	xorq	0(%rbp,%rsi,8),%r15
        +	xorq	7(%rbp,%rdi,8),%r8
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	6(%rbp,%rsi,8),%r9
        +	xorq	5(%rbp,%rdi,8),%r10
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	shrl	$16,%ebx
        +	xorq	4(%rbp,%rsi,8),%r11
        +	xorq	3(%rbp,%rdi,8),%r12
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +
        +	leaq	(%rcx,%rcx,1),%rsi
        +	leaq	(%rdx,%rdx,1),%rdi
        +	xorq	2(%rbp,%rsi,8),%r13
        +	xorq	1(%rbp,%rdi,8),%r14
        +	leaq	128(%rsp),%rbx
        +	movq	24(%rbx),%rsi
        +	addq	$1,%rsi
        +	cmpq	$10,%rsi
        +	je	L$roundsdone
        +
        +	movq	%rsi,24(%rbx)
        +	movq	%r8,64+0(%rsp)
        +	movq	%r9,64+8(%rsp)
        +	movq	%r10,64+16(%rsp)
        +	movq	%r11,64+24(%rsp)
        +	movq	%r12,64+32(%rsp)
        +	movq	%r13,64+40(%rsp)
        +	movq	%r14,64+48(%rsp)
        +	movq	%r15,64+56(%rsp)
        +	jmp	L$round
        +.p2align	4
        +L$roundsdone:
        +	movq	0(%rbx),%rdi
        +	movq	8(%rbx),%rsi
        +	movq	16(%rbx),%rax
        +	xorq	0(%rsi),%r8
        +	xorq	8(%rsi),%r9
        +	xorq	16(%rsi),%r10
        +	xorq	24(%rsi),%r11
        +	xorq	32(%rsi),%r12
        +	xorq	40(%rsi),%r13
        +	xorq	48(%rsi),%r14
        +	xorq	56(%rsi),%r15
        +	xorq	0(%rdi),%r8
        +	xorq	8(%rdi),%r9
        +	xorq	16(%rdi),%r10
        +	xorq	24(%rdi),%r11
        +	xorq	32(%rdi),%r12
        +	xorq	40(%rdi),%r13
        +	xorq	48(%rdi),%r14
        +	xorq	56(%rdi),%r15
        +	movq	%r8,0(%rdi)
        +	movq	%r9,8(%rdi)
        +	movq	%r10,16(%rdi)
        +	movq	%r11,24(%rdi)
        +	movq	%r12,32(%rdi)
        +	movq	%r13,40(%rdi)
        +	movq	%r14,48(%rdi)
        +	movq	%r15,56(%rdi)
        +	leaq	64(%rsi),%rsi
        +	subq	$1,%rax
        +	jz	L$alldone
        +	movq	%rsi,8(%rbx)
        +	movq	%rax,16(%rbx)
        +	jmp	L$outerloop
        +L$alldone:
        +	movq	32(%rbx),%rsi
        +	movq	(%rsi),%r15
        +	movq	8(%rsi),%r14
        +	movq	16(%rsi),%r13
        +	movq	24(%rsi),%r12
        +	movq	32(%rsi),%rbp
        +	movq	40(%rsi),%rbx
        +	leaq	48(%rsi),%rsp
        +L$epilogue:
        +	.byte	0xf3,0xc3
        +
        +
        +.p2align	6
        +
        +L$table:
        +.byte	24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216
        +.byte	35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38
        +.byte	198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184
        +.byte	232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251
        +.byte	135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203
        +.byte	184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17
        +.byte	1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9
        +.byte	79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13
        +.byte	54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155
        +.byte	166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255
        +.byte	210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12
        +.byte	245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14
        +.byte	121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150
        +.byte	111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48
        +.byte	145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109
        +.byte	82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248
        +.byte	96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71
        +.byte	188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53
        +.byte	155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55
        +.byte	142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138
        +.byte	163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210
        +.byte	12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108
        +.byte	123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132
        +.byte	53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128
        +.byte	29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245
        +.byte	224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179
        +.byte	215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33
        +.byte	194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156
        +.byte	46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67
        +.byte	75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41
        +.byte	254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93
        +.byte	87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213
        +.byte	21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189
        +.byte	119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232
        +.byte	55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146
        +.byte	229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158
        +.byte	159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19
        +.byte	240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35
        +.byte	74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32
        +.byte	218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68
        +.byte	88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162
        +.byte	201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207
        +.byte	41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124
        +.byte	10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90
        +.byte	177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80
        +.byte	160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201
        +.byte	107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20
        +.byte	133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217
        +.byte	189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60
        +.byte	93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143
        +.byte	16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144
        +.byte	244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7
        +.byte	203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221
        +.byte	62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211
        +.byte	5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45
        +.byte	103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120
        +.byte	228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151
        +.byte	39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2
        +.byte	65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115
        +.byte	139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167
        +.byte	167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246
        +.byte	125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178
        +.byte	149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73
        +.byte	216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86
        +.byte	251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112
        +.byte	238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205
        +.byte	124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187
        +.byte	102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113
        +.byte	221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123
        +.byte	23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175
        +.byte	71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69
        +.byte	158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26
        +.byte	202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212
        +.byte	45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88
        +.byte	191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46
        +.byte	7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63
        +.byte	173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172
        +.byte	90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176
        +.byte	131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239
        +.byte	51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182
        +.byte	99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92
        +.byte	2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18
        +.byte	170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147
        +.byte	113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222
        +.byte	200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198
        +.byte	25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209
        +.byte	73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59
        +.byte	217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95
        +.byte	242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49
        +.byte	227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168
        +.byte	91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185
        +.byte	136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188
        +.byte	154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62
        +.byte	38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11
        +.byte	50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191
        +.byte	176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89
        +.byte	233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242
        +.byte	15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119
        +.byte	213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51
        +.byte	128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244
        +.byte	190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39
        +.byte	205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235
        +.byte	52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137
        +.byte	72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50
        +.byte	255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84
        +.byte	122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141
        +.byte	144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100
        +.byte	95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157
        +.byte	32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61
        +.byte	104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15
        +.byte	26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202
        +.byte	174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183
        +.byte	180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125
        +.byte	84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206
        +.byte	147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127
        +.byte	34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47
        +.byte	100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99
        +.byte	241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42
        +.byte	115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204
        +.byte	18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130
        +.byte	64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122
        +.byte	8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72
        +.byte	195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149
        +.byte	236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223
        +.byte	219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77
        +.byte	161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192
        +.byte	141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145
        +.byte	61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200
        +.byte	151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91
        +.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        +.byte	207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249
        +.byte	43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110
        +.byte	118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225
        +.byte	130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230
        +.byte	214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40
        +.byte	27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195
        +.byte	181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116
        +.byte	175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190
        +.byte	106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29
        +.byte	80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234
        +.byte	69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87
        +.byte	243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56
        +.byte	48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173
        +.byte	239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196
        +.byte	63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218
        +.byte	85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199
        +.byte	162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219
        +.byte	234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233
        +.byte	101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106
        +.byte	186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3
        +.byte	47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74
        +.byte	192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142
        +.byte	222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96
        +.byte	28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252
        +.byte	253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70
        +.byte	77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31
        +.byte	146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118
        +.byte	117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250
        +.byte	6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54
        +.byte	138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174
        +.byte	178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75
        +.byte	230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133
        +.byte	14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126
        +.byte	31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231
        +.byte	98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85
        +.byte	212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58
        +.byte	168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129
        +.byte	150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82
        +.byte	249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98
        +.byte	197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163
        +.byte	37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16
        +.byte	89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171
        +.byte	132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208
        +.byte	114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197
        +.byte	57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236
        +.byte	76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22
        +.byte	94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148
        +.byte	120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159
        +.byte	56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229
        +.byte	140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152
        +.byte	209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23
        +.byte	165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228
        +.byte	226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161
        +.byte	97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78
        +.byte	179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66
        +.byte	33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52
        +.byte	156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8
        +.byte	30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238
        +.byte	67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97
        +.byte	199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177
        +.byte	252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79
        +.byte	4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36
        +.byte	81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227
        +.byte	153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37
        +.byte	109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34
        +.byte	13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101
        +.byte	250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121
        +.byte	223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105
        +.byte	126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169
        +.byte	36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25
        +.byte	59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254
        +.byte	171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154
        +.byte	206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240
        +.byte	17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153
        +.byte	143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131
        +.byte	78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4
        +.byte	183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102
        +.byte	235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224
        +.byte	60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193
        +.byte	129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253
        +.byte	148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64
        +.byte	247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28
        +.byte	185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24
        +.byte	19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139
        +.byte	44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81
        +.byte	211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5
        +.byte	231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140
        +.byte	110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57
        +.byte	196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170
        +.byte	3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27
        +.byte	86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220
        +.byte	68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94
        +.byte	127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160
        +.byte	169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136
        +.byte	42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103
        +.byte	187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10
        +.byte	193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135
        +.byte	83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241
        +.byte	220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114
        +.byte	11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83
        +.byte	157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1
        +.byte	108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43
        +.byte	49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164
        +.byte	116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243
        +.byte	246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21
        +.byte	70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76
        +.byte	172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165
        +.byte	137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181
        +.byte	20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180
        +.byte	225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186
        +.byte	22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166
        +.byte	58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247
        +.byte	105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6
        +.byte	9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65
        +.byte	112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215
        +.byte	182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111
        +.byte	208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30
        +.byte	237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214
        +.byte	204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226
        +.byte	66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104
        +.byte	152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44
        +.byte	164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237
        +.byte	40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117
        +.byte	92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134
        +.byte	248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107
        +.byte	134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194
        +.byte	24,35,198,232,135,184,1,79
        +.byte	54,166,210,245,121,111,145,82
        +.byte	96,188,155,142,163,12,123,53
        +.byte	29,224,215,194,46,75,254,87
        +.byte	21,119,55,229,159,240,74,218
        +.byte	88,201,41,10,177,160,107,133
        +.byte	189,93,16,244,203,62,5,103
        +.byte	228,39,65,139,167,125,149,216
        +.byte	251,238,124,102,221,23,71,158
        +.byte	202,45,191,7,173,90,131,51
        diff --git a/vendor/openssl/asm/x64-macosx-gas/x86_64cpuid.s b/vendor/openssl/asm/x64-macosx-gas/x86_64cpuid.s
        new file mode 100644
        index 000000000..21e8a8fc2
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-macosx-gas/x86_64cpuid.s
        @@ -0,0 +1,238 @@
        +
        +.private_extern	_OPENSSL_cpuid_setup
        +.mod_init_func
        +	.p2align	3
        +	.quad	_OPENSSL_cpuid_setup
        +
        +.private_extern	_OPENSSL_ia32cap_P
        +.comm	_OPENSSL_ia32cap_P,8,2
        +
        +.text
        +
        +
        +.globl	_OPENSSL_atomic_add
        +
        +.p2align	4
        +_OPENSSL_atomic_add:
        +	movl	(%rdi),%eax
        +L$spin:	leaq	(%rsi,%rax,1),%r8
        +.byte	0xf0
        +
        +	cmpxchgl	%r8d,(%rdi)
        +	jne	L$spin
        +	movl	%r8d,%eax
        +.byte	0x48,0x98
        +
        +	.byte	0xf3,0xc3
        +
        +
        +.globl	_OPENSSL_rdtsc
        +
        +.p2align	4
        +_OPENSSL_rdtsc:
        +	rdtsc
        +	shlq	$32,%rdx
        +	orq	%rdx,%rax
        +	.byte	0xf3,0xc3
        +
        +
        +.globl	_OPENSSL_ia32_cpuid
        +
        +.p2align	4
        +_OPENSSL_ia32_cpuid:
        +	movq	%rbx,%r8
        +
        +	xorl	%eax,%eax
        +	cpuid
        +	movl	%eax,%r11d
        +
        +	xorl	%eax,%eax
        +	cmpl	$1970169159,%ebx
        +	setne	%al
        +	movl	%eax,%r9d
        +	cmpl	$1231384169,%edx
        +	setne	%al
        +	orl	%eax,%r9d
        +	cmpl	$1818588270,%ecx
        +	setne	%al
        +	orl	%eax,%r9d
        +	jz	L$intel
        +
        +	cmpl	$1752462657,%ebx
        +	setne	%al
        +	movl	%eax,%r10d
        +	cmpl	$1769238117,%edx
        +	setne	%al
        +	orl	%eax,%r10d
        +	cmpl	$1145913699,%ecx
        +	setne	%al
        +	orl	%eax,%r10d
        +	jnz	L$intel
        +
        +
        +	movl	$2147483648,%eax
        +	cpuid
        +	cmpl	$2147483649,%eax
        +	jb	L$intel
        +	movl	%eax,%r10d
        +	movl	$2147483649,%eax
        +	cpuid
        +	orl	%ecx,%r9d
        +	andl	$2049,%r9d
        +
        +	cmpl	$2147483656,%r10d
        +	jb	L$intel
        +
        +	movl	$2147483656,%eax
        +	cpuid
        +	movzbq	%cl,%r10
        +	incq	%r10
        +
        +	movl	$1,%eax
        +	cpuid
        +	btl	$28,%edx
        +	jnc	L$generic
        +	shrl	$16,%ebx
        +	cmpb	%r10b,%bl
        +	ja	L$generic
        +	andl	$4026531839,%edx
        +	jmp	L$generic
        +
        +L$intel:
        +	cmpl	$4,%r11d
        +	movl	$-1,%r10d
        +	jb	L$nocacheinfo
        +
        +	movl	$4,%eax
        +	movl	$0,%ecx
        +	cpuid
        +	movl	%eax,%r10d
        +	shrl	$14,%r10d
        +	andl	$4095,%r10d
        +
        +L$nocacheinfo:
        +	movl	$1,%eax
        +	cpuid
        +	andl	$3220176895,%edx
        +	cmpl	$0,%r9d
        +	jne	L$notintel
        +	orl	$1073741824,%edx
        +	andb	$15,%ah
        +	cmpb	$15,%ah
        +	jne	L$notintel
        +	orl	$1048576,%edx
        +L$notintel:
        +	btl	$28,%edx
        +	jnc	L$generic
        +	andl	$4026531839,%edx
        +	cmpl	$0,%r10d
        +	je	L$generic
        +
        +	orl	$268435456,%edx
        +	shrl	$16,%ebx
        +	cmpb	$1,%bl
        +	ja	L$generic
        +	andl	$4026531839,%edx
        +L$generic:
        +	andl	$2048,%r9d
        +	andl	$4294965247,%ecx
        +	orl	%ecx,%r9d
        +
        +	movl	%edx,%r10d
        +	btl	$27,%r9d
        +	jnc	L$clear_avx
        +	xorl	%ecx,%ecx
        +.byte	0x0f,0x01,0xd0
        +
        +	andl	$6,%eax
        +	cmpl	$6,%eax
        +	je	L$done
        +L$clear_avx:
        +	movl	$4026525695,%eax
        +	andl	%eax,%r9d
        +L$done:
        +	shlq	$32,%r9
        +	movl	%r10d,%eax
        +	movq	%r8,%rbx
        +	orq	%r9,%rax
        +	.byte	0xf3,0xc3
        +
        +
        +.globl	_OPENSSL_cleanse
        +
        +.p2align	4
        +_OPENSSL_cleanse:
        +	xorq	%rax,%rax
        +	cmpq	$15,%rsi
        +	jae	L$ot
        +	cmpq	$0,%rsi
        +	je	L$ret
        +L$ittle:
        +	movb	%al,(%rdi)
        +	subq	$1,%rsi
        +	leaq	1(%rdi),%rdi
        +	jnz	L$ittle
        +L$ret:
        +	.byte	0xf3,0xc3
        +.p2align	4
        +L$ot:
        +	testq	$7,%rdi
        +	jz	L$aligned
        +	movb	%al,(%rdi)
        +	leaq	-1(%rsi),%rsi
        +	leaq	1(%rdi),%rdi
        +	jmp	L$ot
        +L$aligned:
        +	movq	%rax,(%rdi)
        +	leaq	-8(%rsi),%rsi
        +	testq	$-8,%rsi
        +	leaq	8(%rdi),%rdi
        +	jnz	L$aligned
        +	cmpq	$0,%rsi
        +	jne	L$ittle
        +	.byte	0xf3,0xc3
        +
        +.globl	_OPENSSL_wipe_cpu
        +
        +.p2align	4
        +_OPENSSL_wipe_cpu:
        +	pxor	%xmm0,%xmm0
        +	pxor	%xmm1,%xmm1
        +	pxor	%xmm2,%xmm2
        +	pxor	%xmm3,%xmm3
        +	pxor	%xmm4,%xmm4
        +	pxor	%xmm5,%xmm5
        +	pxor	%xmm6,%xmm6
        +	pxor	%xmm7,%xmm7
        +	pxor	%xmm8,%xmm8
        +	pxor	%xmm9,%xmm9
        +	pxor	%xmm10,%xmm10
        +	pxor	%xmm11,%xmm11
        +	pxor	%xmm12,%xmm12
        +	pxor	%xmm13,%xmm13
        +	pxor	%xmm14,%xmm14
        +	pxor	%xmm15,%xmm15
        +	xorq	%rcx,%rcx
        +	xorq	%rdx,%rdx
        +	xorq	%rsi,%rsi
        +	xorq	%rdi,%rdi
        +	xorq	%r8,%r8
        +	xorq	%r9,%r9
        +	xorq	%r10,%r10
        +	xorq	%r11,%r11
        +	leaq	8(%rsp),%rax
        +	.byte	0xf3,0xc3
        +
        +.globl	_OPENSSL_ia32_rdrand
        +
        +.p2align	4
        +_OPENSSL_ia32_rdrand:
        +	movl	$8,%ecx
        +L$oop_rdrand:
        +.byte	72,15,199,240
        +	jc	L$break_rdrand
        +	loop	L$oop_rdrand
        +L$break_rdrand:
        +	cmpq	$0,%rax
        +	cmoveq	%rcx,%rax
        +	.byte	0xf3,0xc3
        diff --git a/vendor/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm
        new file mode 100644
        index 000000000..b9f6fd081
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/aes/aes-x86_64.asm
        @@ -0,0 +1,2894 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +ALIGN	16
        +_x86_64_AES_encrypt	PROC PRIVATE
        +	xor	eax,DWORD PTR[r15]
        +	xor	ebx,DWORD PTR[4+r15]
        +	xor	ecx,DWORD PTR[8+r15]
        +	xor	edx,DWORD PTR[12+r15]
        +
        +	mov	r13d,DWORD PTR[240+r15]
        +	sub	r13d,1
        +	jmp	$L$enc_loop
        +ALIGN	16
        +$L$enc_loop::
        +
        +	movzx	esi,al
        +	movzx	edi,bl
        +	movzx	ebp,cl
        +	mov	r10d,DWORD PTR[rsi*8+r14]
        +	mov	r11d,DWORD PTR[rdi*8+r14]
        +	mov	r12d,DWORD PTR[rbp*8+r14]
        +
        +	movzx	esi,bh
        +	movzx	edi,ch
        +	movzx	ebp,dl
        +	xor	r10d,DWORD PTR[3+rsi*8+r14]
        +	xor	r11d,DWORD PTR[3+rdi*8+r14]
        +	mov	r8d,DWORD PTR[rbp*8+r14]
        +
        +	movzx	esi,dh
        +	shr	ecx,16
        +	movzx	ebp,ah
        +	xor	r12d,DWORD PTR[3+rsi*8+r14]
        +	shr	edx,16
        +	xor	r8d,DWORD PTR[3+rbp*8+r14]
        +
        +	shr	ebx,16
        +	lea	r15,QWORD PTR[16+r15]
        +	shr	eax,16
        +
        +	movzx	esi,cl
        +	movzx	edi,dl
        +	movzx	ebp,al
        +	xor	r10d,DWORD PTR[2+rsi*8+r14]
        +	xor	r11d,DWORD PTR[2+rdi*8+r14]
        +	xor	r12d,DWORD PTR[2+rbp*8+r14]
        +
        +	movzx	esi,dh
        +	movzx	edi,ah
        +	movzx	ebp,bl
        +	xor	r10d,DWORD PTR[1+rsi*8+r14]
        +	xor	r11d,DWORD PTR[1+rdi*8+r14]
        +	xor	r8d,DWORD PTR[2+rbp*8+r14]
        +
        +	mov	edx,DWORD PTR[12+r15]
        +	movzx	edi,bh
        +	movzx	ebp,ch
        +	mov	eax,DWORD PTR[r15]
        +	xor	r12d,DWORD PTR[1+rdi*8+r14]
        +	xor	r8d,DWORD PTR[1+rbp*8+r14]
        +
        +	mov	ebx,DWORD PTR[4+r15]
        +	mov	ecx,DWORD PTR[8+r15]
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	xor	ecx,r12d
        +	xor	edx,r8d
        +	sub	r13d,1
        +	jnz	$L$enc_loop
        +	movzx	esi,al
        +	movzx	edi,bl
        +	movzx	ebp,cl
        +	movzx	r10d,BYTE PTR[2+rsi*8+r14]
        +	movzx	r11d,BYTE PTR[2+rdi*8+r14]
        +	movzx	r12d,BYTE PTR[2+rbp*8+r14]
        +
        +	movzx	esi,dl
        +	movzx	edi,bh
        +	movzx	ebp,ch
        +	movzx	r8d,BYTE PTR[2+rsi*8+r14]
        +	mov	edi,DWORD PTR[rdi*8+r14]
        +	mov	ebp,DWORD PTR[rbp*8+r14]
        +
        +	and	edi,00000ff00h
        +	and	ebp,00000ff00h
        +
        +	xor	r10d,edi
        +	xor	r11d,ebp
        +	shr	ecx,16
        +
        +	movzx	esi,dh
        +	movzx	edi,ah
        +	shr	edx,16
        +	mov	esi,DWORD PTR[rsi*8+r14]
        +	mov	edi,DWORD PTR[rdi*8+r14]
        +
        +	and	esi,00000ff00h
        +	and	edi,00000ff00h
        +	shr	ebx,16
        +	xor	r12d,esi
        +	xor	r8d,edi
        +	shr	eax,16
        +
        +	movzx	esi,cl
        +	movzx	edi,dl
        +	movzx	ebp,al
        +	mov	esi,DWORD PTR[rsi*8+r14]
        +	mov	edi,DWORD PTR[rdi*8+r14]
        +	mov	ebp,DWORD PTR[rbp*8+r14]
        +
        +	and	esi,000ff0000h
        +	and	edi,000ff0000h
        +	and	ebp,000ff0000h
        +
        +	xor	r10d,esi
        +	xor	r11d,edi
        +	xor	r12d,ebp
        +
        +	movzx	esi,bl
        +	movzx	edi,dh
        +	movzx	ebp,ah
        +	mov	esi,DWORD PTR[rsi*8+r14]
        +	mov	edi,DWORD PTR[2+rdi*8+r14]
        +	mov	ebp,DWORD PTR[2+rbp*8+r14]
        +
        +	and	esi,000ff0000h
        +	and	edi,0ff000000h
        +	and	ebp,0ff000000h
        +
        +	xor	r8d,esi
        +	xor	r10d,edi
        +	xor	r11d,ebp
        +
        +	movzx	esi,bh
        +	movzx	edi,ch
        +	mov	edx,DWORD PTR[((16+12))+r15]
        +	mov	esi,DWORD PTR[2+rsi*8+r14]
        +	mov	edi,DWORD PTR[2+rdi*8+r14]
        +	mov	eax,DWORD PTR[((16+0))+r15]
        +
        +	and	esi,0ff000000h
        +	and	edi,0ff000000h
        +
        +	xor	r12d,esi
        +	xor	r8d,edi
        +
        +	mov	ebx,DWORD PTR[((16+4))+r15]
        +	mov	ecx,DWORD PTR[((16+8))+r15]
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	xor	ecx,r12d
        +	xor	edx,r8d
        +DB	0f3h,0c3h
        +
        +_x86_64_AES_encrypt	ENDP
        +
        +ALIGN	16
        +_x86_64_AES_encrypt_compact	PROC PRIVATE
        +	lea	r8,QWORD PTR[128+r14]
        +	mov	edi,DWORD PTR[((0-128))+r8]
        +	mov	ebp,DWORD PTR[((32-128))+r8]
        +	mov	r10d,DWORD PTR[((64-128))+r8]
        +	mov	r11d,DWORD PTR[((96-128))+r8]
        +	mov	edi,DWORD PTR[((128-128))+r8]
        +	mov	ebp,DWORD PTR[((160-128))+r8]
        +	mov	r10d,DWORD PTR[((192-128))+r8]
        +	mov	r11d,DWORD PTR[((224-128))+r8]
        +	jmp	$L$enc_loop_compact
        +ALIGN	16
        +$L$enc_loop_compact::
        +	xor	eax,DWORD PTR[r15]
        +	xor	ebx,DWORD PTR[4+r15]
        +	xor	ecx,DWORD PTR[8+r15]
        +	xor	edx,DWORD PTR[12+r15]
        +	lea	r15,QWORD PTR[16+r15]
        +	movzx	r10d,al
        +	movzx	r11d,bl
        +	movzx	r12d,cl
        +	movzx	r10d,BYTE PTR[r10*1+r14]
        +	movzx	r11d,BYTE PTR[r11*1+r14]
        +	movzx	r12d,BYTE PTR[r12*1+r14]
        +
        +	movzx	r8d,dl
        +	movzx	esi,bh
        +	movzx	edi,ch
        +	movzx	r8d,BYTE PTR[r8*1+r14]
        +	movzx	r9d,BYTE PTR[rsi*1+r14]
        +	movzx	r13d,BYTE PTR[rdi*1+r14]
        +
        +	movzx	ebp,dh
        +	movzx	esi,ah
        +	shr	ecx,16
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	shr	edx,16
        +
        +	movzx	edi,cl
        +	shl	r9d,8
        +	shl	r13d,8
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	xor	r10d,r9d
        +	xor	r11d,r13d
        +
        +	movzx	r9d,dl
        +	shr	eax,16
        +	shr	ebx,16
        +	movzx	r13d,al
        +	shl	ebp,8
        +	shl	esi,8
        +	movzx	r9d,BYTE PTR[r9*1+r14]
        +	movzx	r13d,BYTE PTR[r13*1+r14]
        +	xor	r12d,ebp
        +	xor	r8d,esi
        +
        +	movzx	ebp,bl
        +	movzx	esi,dh
        +	shl	edi,16
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	xor	r10d,edi
        +
        +	movzx	edi,ah
        +	shr	ecx,8
        +	shr	ebx,8
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	movzx	edx,BYTE PTR[rcx*1+r14]
        +	movzx	ecx,BYTE PTR[rbx*1+r14]
        +	shl	r9d,16
        +	shl	r13d,16
        +	shl	ebp,16
        +	xor	r11d,r9d
        +	xor	r12d,r13d
        +	xor	r8d,ebp
        +
        +	shl	esi,24
        +	shl	edi,24
        +	shl	edx,24
        +	xor	r10d,esi
        +	shl	ecx,24
        +	xor	r11d,edi
        +	mov	eax,r10d
        +	mov	ebx,r11d
        +	xor	ecx,r12d
        +	xor	edx,r8d
        +	cmp	r15,QWORD PTR[16+rsp]
        +	je	$L$enc_compact_done
        +	mov	esi,eax
        +	mov	edi,ebx
        +	and	esi,080808080h
        +	and	edi,080808080h
        +	mov	r10d,esi
        +	mov	r11d,edi
        +	shr	r10d,7
        +	lea	r8d,DWORD PTR[rax*1+rax]
        +	shr	r11d,7
        +	lea	r9d,DWORD PTR[rbx*1+rbx]
        +	sub	esi,r10d
        +	sub	edi,r11d
        +	and	r8d,0fefefefeh
        +	and	r9d,0fefefefeh
        +	and	esi,01b1b1b1bh
        +	and	edi,01b1b1b1bh
        +	mov	r10d,eax
        +	mov	r11d,ebx
        +	xor	r8d,esi
        +	xor	r9d,edi
        +
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	mov	esi,ecx
        +	mov	edi,edx
        +	rol	eax,24
        +	rol	ebx,24
        +	and	esi,080808080h
        +	and	edi,080808080h
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	mov	r12d,esi
        +	mov	ebp,edi
        +	ror	r10d,16
        +	ror	r11d,16
        +	shr	r12d,7
        +	lea	r8d,DWORD PTR[rcx*1+rcx]
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	shr	ebp,7
        +	lea	r9d,DWORD PTR[rdx*1+rdx]
        +	ror	r10d,8
        +	ror	r11d,8
        +	sub	esi,r12d
        +	sub	edi,ebp
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +
        +	and	r8d,0fefefefeh
        +	and	r9d,0fefefefeh
        +	and	esi,01b1b1b1bh
        +	and	edi,01b1b1b1bh
        +	mov	r12d,ecx
        +	mov	ebp,edx
        +	xor	r8d,esi
        +	xor	r9d,edi
        +
        +	xor	ecx,r8d
        +	xor	edx,r9d
        +	rol	ecx,24
        +	rol	edx,24
        +	xor	ecx,r8d
        +	xor	edx,r9d
        +	mov	esi,DWORD PTR[r14]
        +	ror	r12d,16
        +	ror	ebp,16
        +	mov	edi,DWORD PTR[64+r14]
        +	xor	ecx,r12d
        +	xor	edx,ebp
        +	mov	r8d,DWORD PTR[128+r14]
        +	ror	r12d,8
        +	ror	ebp,8
        +	mov	r9d,DWORD PTR[192+r14]
        +	xor	ecx,r12d
        +	xor	edx,ebp
        +	jmp	$L$enc_loop_compact
        +ALIGN	16
        +$L$enc_compact_done::
        +	xor	eax,DWORD PTR[r15]
        +	xor	ebx,DWORD PTR[4+r15]
        +	xor	ecx,DWORD PTR[8+r15]
        +	xor	edx,DWORD PTR[12+r15]
        +DB	0f3h,0c3h
        +
        +_x86_64_AES_encrypt_compact	ENDP
        +PUBLIC	AES_encrypt
        +
        +ALIGN	16
        +PUBLIC	asm_AES_encrypt
        +
        +asm_AES_encrypt::
        +AES_encrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_AES_encrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +
        +	mov	r10,rsp
        +	lea	rcx,QWORD PTR[((-63))+rdx]
        +	and	rsp,-64
        +	sub	rcx,rsp
        +	neg	rcx
        +	and	rcx,03c0h
        +	sub	rsp,rcx
        +	sub	rsp,32
        +
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	QWORD PTR[24+rsp],r10
        +$L$enc_prologue::
        +
        +	mov	r15,rdx
        +	mov	r13d,DWORD PTR[240+r15]
        +
        +	mov	eax,DWORD PTR[rdi]
        +	mov	ebx,DWORD PTR[4+rdi]
        +	mov	ecx,DWORD PTR[8+rdi]
        +	mov	edx,DWORD PTR[12+rdi]
        +
        +	shl	r13d,4
        +	lea	rbp,QWORD PTR[r13*1+r15]
        +	mov	QWORD PTR[rsp],r15
        +	mov	QWORD PTR[8+rsp],rbp
        +
        +
        +	lea	r14,QWORD PTR[(($L$AES_Te+2048))]
        +	lea	rbp,QWORD PTR[768+rsp]
        +	sub	rbp,r14
        +	and	rbp,0300h
        +	lea	r14,QWORD PTR[rbp*1+r14]
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	mov	r9,QWORD PTR[16+rsp]
        +	mov	rsi,QWORD PTR[24+rsp]
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$enc_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_AES_encrypt::
        +AES_encrypt	ENDP
        +
        +ALIGN	16
        +_x86_64_AES_decrypt	PROC PRIVATE
        +	xor	eax,DWORD PTR[r15]
        +	xor	ebx,DWORD PTR[4+r15]
        +	xor	ecx,DWORD PTR[8+r15]
        +	xor	edx,DWORD PTR[12+r15]
        +
        +	mov	r13d,DWORD PTR[240+r15]
        +	sub	r13d,1
        +	jmp	$L$dec_loop
        +ALIGN	16
        +$L$dec_loop::
        +
        +	movzx	esi,al
        +	movzx	edi,bl
        +	movzx	ebp,cl
        +	mov	r10d,DWORD PTR[rsi*8+r14]
        +	mov	r11d,DWORD PTR[rdi*8+r14]
        +	mov	r12d,DWORD PTR[rbp*8+r14]
        +
        +	movzx	esi,dh
        +	movzx	edi,ah
        +	movzx	ebp,dl
        +	xor	r10d,DWORD PTR[3+rsi*8+r14]
        +	xor	r11d,DWORD PTR[3+rdi*8+r14]
        +	mov	r8d,DWORD PTR[rbp*8+r14]
        +
        +	movzx	esi,bh
        +	shr	eax,16
        +	movzx	ebp,ch
        +	xor	r12d,DWORD PTR[3+rsi*8+r14]
        +	shr	edx,16
        +	xor	r8d,DWORD PTR[3+rbp*8+r14]
        +
        +	shr	ebx,16
        +	lea	r15,QWORD PTR[16+r15]
        +	shr	ecx,16
        +
        +	movzx	esi,cl
        +	movzx	edi,dl
        +	movzx	ebp,al
        +	xor	r10d,DWORD PTR[2+rsi*8+r14]
        +	xor	r11d,DWORD PTR[2+rdi*8+r14]
        +	xor	r12d,DWORD PTR[2+rbp*8+r14]
        +
        +	movzx	esi,bh
        +	movzx	edi,ch
        +	movzx	ebp,bl
        +	xor	r10d,DWORD PTR[1+rsi*8+r14]
        +	xor	r11d,DWORD PTR[1+rdi*8+r14]
        +	xor	r8d,DWORD PTR[2+rbp*8+r14]
        +
        +	movzx	esi,dh
        +	mov	edx,DWORD PTR[12+r15]
        +	movzx	ebp,ah
        +	xor	r12d,DWORD PTR[1+rsi*8+r14]
        +	mov	eax,DWORD PTR[r15]
        +	xor	r8d,DWORD PTR[1+rbp*8+r14]
        +
        +	xor	eax,r10d
        +	mov	ebx,DWORD PTR[4+r15]
        +	mov	ecx,DWORD PTR[8+r15]
        +	xor	ecx,r12d
        +	xor	ebx,r11d
        +	xor	edx,r8d
        +	sub	r13d,1
        +	jnz	$L$dec_loop
        +	lea	r14,QWORD PTR[2048+r14]
        +	movzx	esi,al
        +	movzx	edi,bl
        +	movzx	ebp,cl
        +	movzx	r10d,BYTE PTR[rsi*1+r14]
        +	movzx	r11d,BYTE PTR[rdi*1+r14]
        +	movzx	r12d,BYTE PTR[rbp*1+r14]
        +
        +	movzx	esi,dl
        +	movzx	edi,dh
        +	movzx	ebp,ah
        +	movzx	r8d,BYTE PTR[rsi*1+r14]
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +
        +	shl	edi,8
        +	shl	ebp,8
        +
        +	xor	r10d,edi
        +	xor	r11d,ebp
        +	shr	edx,16
        +
        +	movzx	esi,bh
        +	movzx	edi,ch
        +	shr	eax,16
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +
        +	shl	esi,8
        +	shl	edi,8
        +	shr	ebx,16
        +	xor	r12d,esi
        +	xor	r8d,edi
        +	shr	ecx,16
        +
        +	movzx	esi,cl
        +	movzx	edi,dl
        +	movzx	ebp,al
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +
        +	shl	esi,16
        +	shl	edi,16
        +	shl	ebp,16
        +
        +	xor	r10d,esi
        +	xor	r11d,edi
        +	xor	r12d,ebp
        +
        +	movzx	esi,bl
        +	movzx	edi,bh
        +	movzx	ebp,ch
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +
        +	shl	esi,16
        +	shl	edi,24
        +	shl	ebp,24
        +
        +	xor	r8d,esi
        +	xor	r10d,edi
        +	xor	r11d,ebp
        +
        +	movzx	esi,dh
        +	movzx	edi,ah
        +	mov	edx,DWORD PTR[((16+12))+r15]
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	mov	eax,DWORD PTR[((16+0))+r15]
        +
        +	shl	esi,24
        +	shl	edi,24
        +
        +	xor	r12d,esi
        +	xor	r8d,edi
        +
        +	mov	ebx,DWORD PTR[((16+4))+r15]
        +	mov	ecx,DWORD PTR[((16+8))+r15]
        +	lea	r14,QWORD PTR[((-2048))+r14]
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	xor	ecx,r12d
        +	xor	edx,r8d
        +DB	0f3h,0c3h
        +
        +_x86_64_AES_decrypt	ENDP
        +
        +ALIGN	16
        +_x86_64_AES_decrypt_compact	PROC PRIVATE
        +	lea	r8,QWORD PTR[128+r14]
        +	mov	edi,DWORD PTR[((0-128))+r8]
        +	mov	ebp,DWORD PTR[((32-128))+r8]
        +	mov	r10d,DWORD PTR[((64-128))+r8]
        +	mov	r11d,DWORD PTR[((96-128))+r8]
        +	mov	edi,DWORD PTR[((128-128))+r8]
        +	mov	ebp,DWORD PTR[((160-128))+r8]
        +	mov	r10d,DWORD PTR[((192-128))+r8]
        +	mov	r11d,DWORD PTR[((224-128))+r8]
        +	jmp	$L$dec_loop_compact
        +
        +ALIGN	16
        +$L$dec_loop_compact::
        +	xor	eax,DWORD PTR[r15]
        +	xor	ebx,DWORD PTR[4+r15]
        +	xor	ecx,DWORD PTR[8+r15]
        +	xor	edx,DWORD PTR[12+r15]
        +	lea	r15,QWORD PTR[16+r15]
        +	movzx	r10d,al
        +	movzx	r11d,bl
        +	movzx	r12d,cl
        +	movzx	r10d,BYTE PTR[r10*1+r14]
        +	movzx	r11d,BYTE PTR[r11*1+r14]
        +	movzx	r12d,BYTE PTR[r12*1+r14]
        +
        +	movzx	r8d,dl
        +	movzx	esi,dh
        +	movzx	edi,ah
        +	movzx	r8d,BYTE PTR[r8*1+r14]
        +	movzx	r9d,BYTE PTR[rsi*1+r14]
        +	movzx	r13d,BYTE PTR[rdi*1+r14]
        +
        +	movzx	ebp,bh
        +	movzx	esi,ch
        +	shr	ecx,16
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	shr	edx,16
        +
        +	movzx	edi,cl
        +	shl	r9d,8
        +	shl	r13d,8
        +	movzx	edi,BYTE PTR[rdi*1+r14]
        +	xor	r10d,r9d
        +	xor	r11d,r13d
        +
        +	movzx	r9d,dl
        +	shr	eax,16
        +	shr	ebx,16
        +	movzx	r13d,al
        +	shl	ebp,8
        +	shl	esi,8
        +	movzx	r9d,BYTE PTR[r9*1+r14]
        +	movzx	r13d,BYTE PTR[r13*1+r14]
        +	xor	r12d,ebp
        +	xor	r8d,esi
        +
        +	movzx	ebp,bl
        +	movzx	esi,bh
        +	shl	edi,16
        +	movzx	ebp,BYTE PTR[rbp*1+r14]
        +	movzx	esi,BYTE PTR[rsi*1+r14]
        +	xor	r10d,edi
        +
        +	movzx	edi,ch
        +	shl	r9d,16
        +	shl	r13d,16
        +	movzx	ebx,BYTE PTR[rdi*1+r14]
        +	xor	r11d,r9d
        +	xor	r12d,r13d
        +
        +	movzx	edi,dh
        +	shr	eax,8
        +	shl	ebp,16
        +	movzx	ecx,BYTE PTR[rdi*1+r14]
        +	movzx	edx,BYTE PTR[rax*1+r14]
        +	xor	r8d,ebp
        +
        +	shl	esi,24
        +	shl	ebx,24
        +	shl	ecx,24
        +	xor	r10d,esi
        +	shl	edx,24
        +	xor	ebx,r11d
        +	mov	eax,r10d
        +	xor	ecx,r12d
        +	xor	edx,r8d
        +	cmp	r15,QWORD PTR[16+rsp]
        +	je	$L$dec_compact_done
        +
        +	mov	rsi,QWORD PTR[((256+0))+r14]
        +	shl	rbx,32
        +	shl	rdx,32
        +	mov	rdi,QWORD PTR[((256+8))+r14]
        +	or	rax,rbx
        +	or	rcx,rdx
        +	mov	rbp,QWORD PTR[((256+16))+r14]
        +	mov	rbx,rax
        +	mov	rdx,rcx
        +	and	rbx,rsi
        +	and	rdx,rsi
        +	mov	r9,rbx
        +	mov	r12,rdx
        +	shr	r9,7
        +	lea	r8,QWORD PTR[rax*1+rax]
        +	shr	r12,7
        +	lea	r11,QWORD PTR[rcx*1+rcx]
        +	sub	rbx,r9
        +	sub	rdx,r12
        +	and	r8,rdi
        +	and	r11,rdi
        +	and	rbx,rbp
        +	and	rdx,rbp
        +	xor	rbx,r8
        +	xor	rdx,r11
        +	mov	r8,rbx
        +	mov	r11,rdx
        +
        +	and	rbx,rsi
        +	and	rdx,rsi
        +	mov	r10,rbx
        +	mov	r13,rdx
        +	shr	r10,7
        +	lea	r9,QWORD PTR[r8*1+r8]
        +	shr	r13,7
        +	lea	r12,QWORD PTR[r11*1+r11]
        +	sub	rbx,r10
        +	sub	rdx,r13
        +	and	r9,rdi
        +	and	r12,rdi
        +	and	rbx,rbp
        +	and	rdx,rbp
        +	xor	rbx,r9
        +	xor	rdx,r12
        +	mov	r9,rbx
        +	mov	r12,rdx
        +
        +	and	rbx,rsi
        +	and	rdx,rsi
        +	mov	r10,rbx
        +	mov	r13,rdx
        +	shr	r10,7
        +	xor	r8,rax
        +	shr	r13,7
        +	xor	r11,rcx
        +	sub	rbx,r10
        +	sub	rdx,r13
        +	lea	r10,QWORD PTR[r9*1+r9]
        +	lea	r13,QWORD PTR[r12*1+r12]
        +	xor	r9,rax
        +	xor	r12,rcx
        +	and	r10,rdi
        +	and	r13,rdi
        +	and	rbx,rbp
        +	and	rdx,rbp
        +	xor	r10,rbx
        +	xor	r13,rdx
        +
        +	xor	rax,r10
        +	xor	rcx,r13
        +	xor	r8,r10
        +	xor	r11,r13
        +	mov	rbx,rax
        +	mov	rdx,rcx
        +	xor	r9,r10
        +	xor	r12,r13
        +	shr	rbx,32
        +	shr	rdx,32
        +	xor	r10,r8
        +	xor	r13,r11
        +	rol	eax,8
        +	rol	ecx,8
        +	xor	r10,r9
        +	xor	r13,r12
        +
        +	rol	ebx,8
        +	rol	edx,8
        +	xor	eax,r10d
        +	xor	ecx,r13d
        +	shr	r10,32
        +	shr	r13,32
        +	xor	ebx,r10d
        +	xor	edx,r13d
        +
        +	mov	r10,r8
        +	mov	r13,r11
        +	shr	r10,32
        +	shr	r13,32
        +	rol	r8d,24
        +	rol	r11d,24
        +	rol	r10d,24
        +	rol	r13d,24
        +	xor	eax,r8d
        +	xor	ecx,r11d
        +	mov	r8,r9
        +	mov	r11,r12
        +	xor	ebx,r10d
        +	xor	edx,r13d
        +
        +	mov	rsi,QWORD PTR[r14]
        +	shr	r8,32
        +	shr	r11,32
        +	mov	rdi,QWORD PTR[64+r14]
        +	rol	r9d,16
        +	rol	r12d,16
        +	mov	rbp,QWORD PTR[128+r14]
        +	rol	r8d,16
        +	rol	r11d,16
        +	mov	r10,QWORD PTR[192+r14]
        +	xor	eax,r9d
        +	xor	ecx,r12d
        +	mov	r13,QWORD PTR[256+r14]
        +	xor	ebx,r8d
        +	xor	edx,r11d
        +	jmp	$L$dec_loop_compact
        +ALIGN	16
        +$L$dec_compact_done::
        +	xor	eax,DWORD PTR[r15]
        +	xor	ebx,DWORD PTR[4+r15]
        +	xor	ecx,DWORD PTR[8+r15]
        +	xor	edx,DWORD PTR[12+r15]
        +DB	0f3h,0c3h
        +
        +_x86_64_AES_decrypt_compact	ENDP
        +PUBLIC	AES_decrypt
        +
        +ALIGN	16
        +PUBLIC	asm_AES_decrypt
        +
        +asm_AES_decrypt::
        +AES_decrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_AES_decrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +
        +	mov	r10,rsp
        +	lea	rcx,QWORD PTR[((-63))+rdx]
        +	and	rsp,-64
        +	sub	rcx,rsp
        +	neg	rcx
        +	and	rcx,03c0h
        +	sub	rsp,rcx
        +	sub	rsp,32
        +
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	QWORD PTR[24+rsp],r10
        +$L$dec_prologue::
        +
        +	mov	r15,rdx
        +	mov	r13d,DWORD PTR[240+r15]
        +
        +	mov	eax,DWORD PTR[rdi]
        +	mov	ebx,DWORD PTR[4+rdi]
        +	mov	ecx,DWORD PTR[8+rdi]
        +	mov	edx,DWORD PTR[12+rdi]
        +
        +	shl	r13d,4
        +	lea	rbp,QWORD PTR[r13*1+r15]
        +	mov	QWORD PTR[rsp],r15
        +	mov	QWORD PTR[8+rsp],rbp
        +
        +
        +	lea	r14,QWORD PTR[(($L$AES_Td+2048))]
        +	lea	rbp,QWORD PTR[768+rsp]
        +	sub	rbp,r14
        +	and	rbp,0300h
        +	lea	r14,QWORD PTR[rbp*1+r14]
        +	shr	rbp,3
        +	add	r14,rbp
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	mov	r9,QWORD PTR[16+rsp]
        +	mov	rsi,QWORD PTR[24+rsp]
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$dec_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_AES_decrypt::
        +AES_decrypt	ENDP
        +PUBLIC	private_AES_set_encrypt_key
        +
        +ALIGN	16
        +private_AES_set_encrypt_key	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_private_AES_set_encrypt_key::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	sub	rsp,8
        +$L$enc_key_prologue::
        +
        +	call	_x86_64_AES_set_encrypt_key
        +
        +	mov	r15,QWORD PTR[8+rsp]
        +	mov	r14,QWORD PTR[16+rsp]
        +	mov	r13,QWORD PTR[24+rsp]
        +	mov	r12,QWORD PTR[32+rsp]
        +	mov	rbp,QWORD PTR[40+rsp]
        +	mov	rbx,QWORD PTR[48+rsp]
        +	add	rsp,56
        +$L$enc_key_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_private_AES_set_encrypt_key::
        +private_AES_set_encrypt_key	ENDP
        +
        +
        +ALIGN	16
        +_x86_64_AES_set_encrypt_key	PROC PRIVATE
        +	mov	ecx,esi
        +	mov	rsi,rdi
        +	mov	rdi,rdx
        +
        +	test	rsi,-1
        +	jz	$L$badpointer
        +	test	rdi,-1
        +	jz	$L$badpointer
        +
        +	lea	rbp,QWORD PTR[$L$AES_Te]
        +	lea	rbp,QWORD PTR[((2048+128))+rbp]
        +
        +
        +	mov	eax,DWORD PTR[((0-128))+rbp]
        +	mov	ebx,DWORD PTR[((32-128))+rbp]
        +	mov	r8d,DWORD PTR[((64-128))+rbp]
        +	mov	edx,DWORD PTR[((96-128))+rbp]
        +	mov	eax,DWORD PTR[((128-128))+rbp]
        +	mov	ebx,DWORD PTR[((160-128))+rbp]
        +	mov	r8d,DWORD PTR[((192-128))+rbp]
        +	mov	edx,DWORD PTR[((224-128))+rbp]
        +
        +	cmp	ecx,128
        +	je	$L$10rounds
        +	cmp	ecx,192
        +	je	$L$12rounds
        +	cmp	ecx,256
        +	je	$L$14rounds
        +	mov	rax,-2
        +	jmp	$L$exit
        +
        +$L$10rounds::
        +	mov	rax,QWORD PTR[rsi]
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	QWORD PTR[rdi],rax
        +	mov	QWORD PTR[8+rdi],rdx
        +
        +	shr	rdx,32
        +	xor	ecx,ecx
        +	jmp	$L$10shortcut
        +ALIGN	4
        +$L$10loop::
        +	mov	eax,DWORD PTR[rdi]
        +	mov	edx,DWORD PTR[12+rdi]
        +$L$10shortcut::
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,24
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shr	edx,16
        +	movzx	esi,dl
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,8
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shl	ebx,16
        +	xor	eax,ebx
        +
        +	xor	eax,DWORD PTR[((1024-128))+rcx*4+rbp]
        +	mov	DWORD PTR[16+rdi],eax
        +	xor	eax,DWORD PTR[4+rdi]
        +	mov	DWORD PTR[20+rdi],eax
        +	xor	eax,DWORD PTR[8+rdi]
        +	mov	DWORD PTR[24+rdi],eax
        +	xor	eax,DWORD PTR[12+rdi]
        +	mov	DWORD PTR[28+rdi],eax
        +	add	ecx,1
        +	lea	rdi,QWORD PTR[16+rdi]
        +	cmp	ecx,10
        +	jl	$L$10loop
        +
        +	mov	DWORD PTR[80+rdi],10
        +	xor	rax,rax
        +	jmp	$L$exit
        +
        +$L$12rounds::
        +	mov	rax,QWORD PTR[rsi]
        +	mov	rbx,QWORD PTR[8+rsi]
        +	mov	rdx,QWORD PTR[16+rsi]
        +	mov	QWORD PTR[rdi],rax
        +	mov	QWORD PTR[8+rdi],rbx
        +	mov	QWORD PTR[16+rdi],rdx
        +
        +	shr	rdx,32
        +	xor	ecx,ecx
        +	jmp	$L$12shortcut
        +ALIGN	4
        +$L$12loop::
        +	mov	eax,DWORD PTR[rdi]
        +	mov	edx,DWORD PTR[20+rdi]
        +$L$12shortcut::
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,24
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shr	edx,16
        +	movzx	esi,dl
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,8
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shl	ebx,16
        +	xor	eax,ebx
        +
        +	xor	eax,DWORD PTR[((1024-128))+rcx*4+rbp]
        +	mov	DWORD PTR[24+rdi],eax
        +	xor	eax,DWORD PTR[4+rdi]
        +	mov	DWORD PTR[28+rdi],eax
        +	xor	eax,DWORD PTR[8+rdi]
        +	mov	DWORD PTR[32+rdi],eax
        +	xor	eax,DWORD PTR[12+rdi]
        +	mov	DWORD PTR[36+rdi],eax
        +
        +	cmp	ecx,7
        +	je	$L$12break
        +	add	ecx,1
        +
        +	xor	eax,DWORD PTR[16+rdi]
        +	mov	DWORD PTR[40+rdi],eax
        +	xor	eax,DWORD PTR[20+rdi]
        +	mov	DWORD PTR[44+rdi],eax
        +
        +	lea	rdi,QWORD PTR[24+rdi]
        +	jmp	$L$12loop
        +$L$12break::
        +	mov	DWORD PTR[72+rdi],12
        +	xor	rax,rax
        +	jmp	$L$exit
        +
        +$L$14rounds::
        +	mov	rax,QWORD PTR[rsi]
        +	mov	rbx,QWORD PTR[8+rsi]
        +	mov	rcx,QWORD PTR[16+rsi]
        +	mov	rdx,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[rdi],rax
        +	mov	QWORD PTR[8+rdi],rbx
        +	mov	QWORD PTR[16+rdi],rcx
        +	mov	QWORD PTR[24+rdi],rdx
        +
        +	shr	rdx,32
        +	xor	ecx,ecx
        +	jmp	$L$14shortcut
        +ALIGN	4
        +$L$14loop::
        +	mov	eax,DWORD PTR[rdi]
        +	mov	edx,DWORD PTR[28+rdi]
        +$L$14shortcut::
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,24
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shr	edx,16
        +	movzx	esi,dl
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,8
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shl	ebx,16
        +	xor	eax,ebx
        +
        +	xor	eax,DWORD PTR[((1024-128))+rcx*4+rbp]
        +	mov	DWORD PTR[32+rdi],eax
        +	xor	eax,DWORD PTR[4+rdi]
        +	mov	DWORD PTR[36+rdi],eax
        +	xor	eax,DWORD PTR[8+rdi]
        +	mov	DWORD PTR[40+rdi],eax
        +	xor	eax,DWORD PTR[12+rdi]
        +	mov	DWORD PTR[44+rdi],eax
        +
        +	cmp	ecx,6
        +	je	$L$14break
        +	add	ecx,1
        +
        +	mov	edx,eax
        +	mov	eax,DWORD PTR[16+rdi]
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shr	edx,16
        +	shl	ebx,8
        +	movzx	esi,dl
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	movzx	esi,dh
        +	shl	ebx,16
        +	xor	eax,ebx
        +
        +	movzx	ebx,BYTE PTR[((-128))+rsi*1+rbp]
        +	shl	ebx,24
        +	xor	eax,ebx
        +
        +	mov	DWORD PTR[48+rdi],eax
        +	xor	eax,DWORD PTR[20+rdi]
        +	mov	DWORD PTR[52+rdi],eax
        +	xor	eax,DWORD PTR[24+rdi]
        +	mov	DWORD PTR[56+rdi],eax
        +	xor	eax,DWORD PTR[28+rdi]
        +	mov	DWORD PTR[60+rdi],eax
        +
        +	lea	rdi,QWORD PTR[32+rdi]
        +	jmp	$L$14loop
        +$L$14break::
        +	mov	DWORD PTR[48+rdi],14
        +	xor	rax,rax
        +	jmp	$L$exit
        +
        +$L$badpointer::
        +	mov	rax,-1
        +$L$exit::
        +DB	0f3h,0c3h
        +
        +_x86_64_AES_set_encrypt_key	ENDP
        +PUBLIC	private_AES_set_decrypt_key
        +
        +ALIGN	16
        +private_AES_set_decrypt_key	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_private_AES_set_decrypt_key::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	push	rdx
        +$L$dec_key_prologue::
        +
        +	call	_x86_64_AES_set_encrypt_key
        +	mov	r8,QWORD PTR[rsp]
        +	cmp	eax,0
        +	jne	$L$abort
        +
        +	mov	r14d,DWORD PTR[240+r8]
        +	xor	rdi,rdi
        +	lea	rcx,QWORD PTR[r14*4+rdi]
        +	mov	rsi,r8
        +	lea	rdi,QWORD PTR[rcx*4+r8]
        +ALIGN	4
        +$L$invert::
        +	mov	rax,QWORD PTR[rsi]
        +	mov	rbx,QWORD PTR[8+rsi]
        +	mov	rcx,QWORD PTR[rdi]
        +	mov	rdx,QWORD PTR[8+rdi]
        +	mov	QWORD PTR[rdi],rax
        +	mov	QWORD PTR[8+rdi],rbx
        +	mov	QWORD PTR[rsi],rcx
        +	mov	QWORD PTR[8+rsi],rdx
        +	lea	rsi,QWORD PTR[16+rsi]
        +	lea	rdi,QWORD PTR[((-16))+rdi]
        +	cmp	rdi,rsi
        +	jne	$L$invert
        +
        +	lea	rax,QWORD PTR[(($L$AES_Te+2048+1024))]
        +
        +	mov	rsi,QWORD PTR[40+rax]
        +	mov	rdi,QWORD PTR[48+rax]
        +	mov	rbp,QWORD PTR[56+rax]
        +
        +	mov	r15,r8
        +	sub	r14d,1
        +ALIGN	4
        +$L$permute::
        +	lea	r15,QWORD PTR[16+r15]
        +	mov	rax,QWORD PTR[r15]
        +	mov	rcx,QWORD PTR[8+r15]
        +	mov	rbx,rax
        +	mov	rdx,rcx
        +	and	rbx,rsi
        +	and	rdx,rsi
        +	mov	r9,rbx
        +	mov	r12,rdx
        +	shr	r9,7
        +	lea	r8,QWORD PTR[rax*1+rax]
        +	shr	r12,7
        +	lea	r11,QWORD PTR[rcx*1+rcx]
        +	sub	rbx,r9
        +	sub	rdx,r12
        +	and	r8,rdi
        +	and	r11,rdi
        +	and	rbx,rbp
        +	and	rdx,rbp
        +	xor	rbx,r8
        +	xor	rdx,r11
        +	mov	r8,rbx
        +	mov	r11,rdx
        +
        +	and	rbx,rsi
        +	and	rdx,rsi
        +	mov	r10,rbx
        +	mov	r13,rdx
        +	shr	r10,7
        +	lea	r9,QWORD PTR[r8*1+r8]
        +	shr	r13,7
        +	lea	r12,QWORD PTR[r11*1+r11]
        +	sub	rbx,r10
        +	sub	rdx,r13
        +	and	r9,rdi
        +	and	r12,rdi
        +	and	rbx,rbp
        +	and	rdx,rbp
        +	xor	rbx,r9
        +	xor	rdx,r12
        +	mov	r9,rbx
        +	mov	r12,rdx
        +
        +	and	rbx,rsi
        +	and	rdx,rsi
        +	mov	r10,rbx
        +	mov	r13,rdx
        +	shr	r10,7
        +	xor	r8,rax
        +	shr	r13,7
        +	xor	r11,rcx
        +	sub	rbx,r10
        +	sub	rdx,r13
        +	lea	r10,QWORD PTR[r9*1+r9]
        +	lea	r13,QWORD PTR[r12*1+r12]
        +	xor	r9,rax
        +	xor	r12,rcx
        +	and	r10,rdi
        +	and	r13,rdi
        +	and	rbx,rbp
        +	and	rdx,rbp
        +	xor	r10,rbx
        +	xor	r13,rdx
        +
        +	xor	rax,r10
        +	xor	rcx,r13
        +	xor	r8,r10
        +	xor	r11,r13
        +	mov	rbx,rax
        +	mov	rdx,rcx
        +	xor	r9,r10
        +	xor	r12,r13
        +	shr	rbx,32
        +	shr	rdx,32
        +	xor	r10,r8
        +	xor	r13,r11
        +	rol	eax,8
        +	rol	ecx,8
        +	xor	r10,r9
        +	xor	r13,r12
        +
        +	rol	ebx,8
        +	rol	edx,8
        +	xor	eax,r10d
        +	xor	ecx,r13d
        +	shr	r10,32
        +	shr	r13,32
        +	xor	ebx,r10d
        +	xor	edx,r13d
        +
        +	mov	r10,r8
        +	mov	r13,r11
        +	shr	r10,32
        +	shr	r13,32
        +	rol	r8d,24
        +	rol	r11d,24
        +	rol	r10d,24
        +	rol	r13d,24
        +	xor	eax,r8d
        +	xor	ecx,r11d
        +	mov	r8,r9
        +	mov	r11,r12
        +	xor	ebx,r10d
        +	xor	edx,r13d
        +
        +
        +	shr	r8,32
        +	shr	r11,32
        +
        +	rol	r9d,16
        +	rol	r12d,16
        +
        +	rol	r8d,16
        +	rol	r11d,16
        +
        +	xor	eax,r9d
        +	xor	ecx,r12d
        +
        +	xor	ebx,r8d
        +	xor	edx,r11d
        +	mov	DWORD PTR[r15],eax
        +	mov	DWORD PTR[4+r15],ebx
        +	mov	DWORD PTR[8+r15],ecx
        +	mov	DWORD PTR[12+r15],edx
        +	sub	r14d,1
        +	jnz	$L$permute
        +
        +	xor	rax,rax
        +$L$abort::
        +	mov	r15,QWORD PTR[8+rsp]
        +	mov	r14,QWORD PTR[16+rsp]
        +	mov	r13,QWORD PTR[24+rsp]
        +	mov	r12,QWORD PTR[32+rsp]
        +	mov	rbp,QWORD PTR[40+rsp]
        +	mov	rbx,QWORD PTR[48+rsp]
        +	add	rsp,56
        +$L$dec_key_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_private_AES_set_decrypt_key::
        +private_AES_set_decrypt_key	ENDP
        +PUBLIC	AES_cbc_encrypt
        +
        +ALIGN	16
        +EXTERN	OPENSSL_ia32cap_P:NEAR
        +PUBLIC	asm_AES_cbc_encrypt
        +
        +asm_AES_cbc_encrypt::
        +AES_cbc_encrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_AES_cbc_encrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	cmp	rdx,0
        +	je	$L$cbc_epilogue
        +	pushfq
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +$L$cbc_prologue::
        +
        +	cld
        +	mov	r9d,r9d
        +
        +	lea	r14,QWORD PTR[$L$AES_Te]
        +	cmp	r9,0
        +	jne	$L$cbc_picked_te
        +	lea	r14,QWORD PTR[$L$AES_Td]
        +$L$cbc_picked_te::
        +
        +	mov	r10d,DWORD PTR[OPENSSL_ia32cap_P]
        +	cmp	rdx,512
        +	jb	$L$cbc_slow_prologue
        +	test	rdx,15
        +	jnz	$L$cbc_slow_prologue
        +
        +
        +
        +
        +	lea	r15,QWORD PTR[((-88-248))+rsp]
        +	and	r15,-64
        +
        +
        +	mov	r10,r14
        +	lea	r11,QWORD PTR[2304+r14]
        +	mov	r12,r15
        +	and	r10,0FFFh
        +	and	r11,0FFFh
        +	and	r12,0FFFh
        +
        +	cmp	r12,r11
        +	jb	$L$cbc_te_break_out
        +	sub	r12,r11
        +	sub	r15,r12
        +	jmp	$L$cbc_te_ok
        +$L$cbc_te_break_out::
        +	sub	r12,r10
        +	and	r12,0FFFh
        +	add	r12,320
        +	sub	r15,r12
        +ALIGN	4
        +$L$cbc_te_ok::
        +
        +	xchg	r15,rsp
        +
        +	mov	QWORD PTR[16+rsp],r15
        +$L$cbc_fast_body::
        +	mov	QWORD PTR[24+rsp],rdi
        +	mov	QWORD PTR[32+rsp],rsi
        +	mov	QWORD PTR[40+rsp],rdx
        +	mov	QWORD PTR[48+rsp],rcx
        +	mov	QWORD PTR[56+rsp],r8
        +	mov	DWORD PTR[((80+240))+rsp],0
        +	mov	rbp,r8
        +	mov	rbx,r9
        +	mov	r9,rsi
        +	mov	r8,rdi
        +	mov	r15,rcx
        +
        +	mov	eax,DWORD PTR[240+r15]
        +
        +	mov	r10,r15
        +	sub	r10,r14
        +	and	r10,0fffh
        +	cmp	r10,2304
        +	jb	$L$cbc_do_ecopy
        +	cmp	r10,4096-248
        +	jb	$L$cbc_skip_ecopy
        +ALIGN	4
        +$L$cbc_do_ecopy::
        +	mov	rsi,r15
        +	lea	rdi,QWORD PTR[80+rsp]
        +	lea	r15,QWORD PTR[80+rsp]
        +	mov	ecx,240/8
        +	DD	090A548F3h
        +
        +	mov	DWORD PTR[rdi],eax
        +$L$cbc_skip_ecopy::
        +	mov	QWORD PTR[rsp],r15
        +
        +	mov	ecx,18
        +ALIGN	4
        +$L$cbc_prefetch_te::
        +	mov	r10,QWORD PTR[r14]
        +	mov	r11,QWORD PTR[32+r14]
        +	mov	r12,QWORD PTR[64+r14]
        +	mov	r13,QWORD PTR[96+r14]
        +	lea	r14,QWORD PTR[128+r14]
        +	sub	ecx,1
        +	jnz	$L$cbc_prefetch_te
        +	lea	r14,QWORD PTR[((-2304))+r14]
        +
        +	cmp	rbx,0
        +	je	$L$FAST_DECRYPT
        +
        +
        +	mov	eax,DWORD PTR[rbp]
        +	mov	ebx,DWORD PTR[4+rbp]
        +	mov	ecx,DWORD PTR[8+rbp]
        +	mov	edx,DWORD PTR[12+rbp]
        +
        +ALIGN	4
        +$L$cbc_fast_enc_loop::
        +	xor	eax,DWORD PTR[r8]
        +	xor	ebx,DWORD PTR[4+r8]
        +	xor	ecx,DWORD PTR[8+r8]
        +	xor	edx,DWORD PTR[12+r8]
        +	mov	r15,QWORD PTR[rsp]
        +	mov	QWORD PTR[24+rsp],r8
        +
        +	call	_x86_64_AES_encrypt
        +
        +	mov	r8,QWORD PTR[24+rsp]
        +	mov	r10,QWORD PTR[40+rsp]
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	r9,QWORD PTR[16+r9]
        +	sub	r10,16
        +	test	r10,-16
        +	mov	QWORD PTR[40+rsp],r10
        +	jnz	$L$cbc_fast_enc_loop
        +	mov	rbp,QWORD PTR[56+rsp]
        +	mov	DWORD PTR[rbp],eax
        +	mov	DWORD PTR[4+rbp],ebx
        +	mov	DWORD PTR[8+rbp],ecx
        +	mov	DWORD PTR[12+rbp],edx
        +
        +	jmp	$L$cbc_fast_cleanup
        +
        +
        +ALIGN	16
        +$L$FAST_DECRYPT::
        +	cmp	r9,r8
        +	je	$L$cbc_fast_dec_in_place
        +
        +	mov	QWORD PTR[64+rsp],rbp
        +ALIGN	4
        +$L$cbc_fast_dec_loop::
        +	mov	eax,DWORD PTR[r8]
        +	mov	ebx,DWORD PTR[4+r8]
        +	mov	ecx,DWORD PTR[8+r8]
        +	mov	edx,DWORD PTR[12+r8]
        +	mov	r15,QWORD PTR[rsp]
        +	mov	QWORD PTR[24+rsp],r8
        +
        +	call	_x86_64_AES_decrypt
        +
        +	mov	rbp,QWORD PTR[64+rsp]
        +	mov	r8,QWORD PTR[24+rsp]
        +	mov	r10,QWORD PTR[40+rsp]
        +	xor	eax,DWORD PTR[rbp]
        +	xor	ebx,DWORD PTR[4+rbp]
        +	xor	ecx,DWORD PTR[8+rbp]
        +	xor	edx,DWORD PTR[12+rbp]
        +	mov	rbp,r8
        +
        +	sub	r10,16
        +	mov	QWORD PTR[40+rsp],r10
        +	mov	QWORD PTR[64+rsp],rbp
        +
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	r9,QWORD PTR[16+r9]
        +	jnz	$L$cbc_fast_dec_loop
        +	mov	r12,QWORD PTR[56+rsp]
        +	mov	r10,QWORD PTR[rbp]
        +	mov	r11,QWORD PTR[8+rbp]
        +	mov	QWORD PTR[r12],r10
        +	mov	QWORD PTR[8+r12],r11
        +	jmp	$L$cbc_fast_cleanup
        +
        +ALIGN	16
        +$L$cbc_fast_dec_in_place::
        +	mov	r10,QWORD PTR[rbp]
        +	mov	r11,QWORD PTR[8+rbp]
        +	mov	QWORD PTR[((0+64))+rsp],r10
        +	mov	QWORD PTR[((8+64))+rsp],r11
        +ALIGN	4
        +$L$cbc_fast_dec_in_place_loop::
        +	mov	eax,DWORD PTR[r8]
        +	mov	ebx,DWORD PTR[4+r8]
        +	mov	ecx,DWORD PTR[8+r8]
        +	mov	edx,DWORD PTR[12+r8]
        +	mov	r15,QWORD PTR[rsp]
        +	mov	QWORD PTR[24+rsp],r8
        +
        +	call	_x86_64_AES_decrypt
        +
        +	mov	r8,QWORD PTR[24+rsp]
        +	mov	r10,QWORD PTR[40+rsp]
        +	xor	eax,DWORD PTR[((0+64))+rsp]
        +	xor	ebx,DWORD PTR[((4+64))+rsp]
        +	xor	ecx,DWORD PTR[((8+64))+rsp]
        +	xor	edx,DWORD PTR[((12+64))+rsp]
        +
        +	mov	r11,QWORD PTR[r8]
        +	mov	r12,QWORD PTR[8+r8]
        +	sub	r10,16
        +	jz	$L$cbc_fast_dec_in_place_done
        +
        +	mov	QWORD PTR[((0+64))+rsp],r11
        +	mov	QWORD PTR[((8+64))+rsp],r12
        +
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	r9,QWORD PTR[16+r9]
        +	mov	QWORD PTR[40+rsp],r10
        +	jmp	$L$cbc_fast_dec_in_place_loop
        +$L$cbc_fast_dec_in_place_done::
        +	mov	rdi,QWORD PTR[56+rsp]
        +	mov	QWORD PTR[rdi],r11
        +	mov	QWORD PTR[8+rdi],r12
        +
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +ALIGN	4
        +$L$cbc_fast_cleanup::
        +	cmp	DWORD PTR[((80+240))+rsp],0
        +	lea	rdi,QWORD PTR[80+rsp]
        +	je	$L$cbc_exit
        +	mov	ecx,240/8
        +	xor	rax,rax
        +	DD	090AB48F3h
        +
        +
        +	jmp	$L$cbc_exit
        +
        +
        +ALIGN	16
        +$L$cbc_slow_prologue::
        +
        +	lea	rbp,QWORD PTR[((-88))+rsp]
        +	and	rbp,-64
        +
        +	lea	r10,QWORD PTR[((-88-63))+rcx]
        +	sub	r10,rbp
        +	neg	r10
        +	and	r10,03c0h
        +	sub	rbp,r10
        +
        +	xchg	rbp,rsp
        +
        +	mov	QWORD PTR[16+rsp],rbp
        +$L$cbc_slow_body::
        +
        +
        +
        +
        +	mov	QWORD PTR[56+rsp],r8
        +	mov	rbp,r8
        +	mov	rbx,r9
        +	mov	r9,rsi
        +	mov	r8,rdi
        +	mov	r15,rcx
        +	mov	r10,rdx
        +
        +	mov	eax,DWORD PTR[240+r15]
        +	mov	QWORD PTR[rsp],r15
        +	shl	eax,4
        +	lea	rax,QWORD PTR[rax*1+r15]
        +	mov	QWORD PTR[8+rsp],rax
        +
        +
        +	lea	r14,QWORD PTR[2048+r14]
        +	lea	rax,QWORD PTR[((768-8))+rsp]
        +	sub	rax,r14
        +	and	rax,0300h
        +	lea	r14,QWORD PTR[rax*1+r14]
        +
        +	cmp	rbx,0
        +	je	$L$SLOW_DECRYPT
        +
        +
        +	test	r10,-16
        +	mov	eax,DWORD PTR[rbp]
        +	mov	ebx,DWORD PTR[4+rbp]
        +	mov	ecx,DWORD PTR[8+rbp]
        +	mov	edx,DWORD PTR[12+rbp]
        +	jz	$L$cbc_slow_enc_tail
        +
        +
        +ALIGN	4
        +$L$cbc_slow_enc_loop::
        +	xor	eax,DWORD PTR[r8]
        +	xor	ebx,DWORD PTR[4+r8]
        +	xor	ecx,DWORD PTR[8+r8]
        +	xor	edx,DWORD PTR[12+r8]
        +	mov	r15,QWORD PTR[rsp]
        +	mov	QWORD PTR[24+rsp],r8
        +	mov	QWORD PTR[32+rsp],r9
        +	mov	QWORD PTR[40+rsp],r10
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	mov	r8,QWORD PTR[24+rsp]
        +	mov	r9,QWORD PTR[32+rsp]
        +	mov	r10,QWORD PTR[40+rsp]
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	r9,QWORD PTR[16+r9]
        +	sub	r10,16
        +	test	r10,-16
        +	jnz	$L$cbc_slow_enc_loop
        +	test	r10,15
        +	jnz	$L$cbc_slow_enc_tail
        +	mov	rbp,QWORD PTR[56+rsp]
        +	mov	DWORD PTR[rbp],eax
        +	mov	DWORD PTR[4+rbp],ebx
        +	mov	DWORD PTR[8+rbp],ecx
        +	mov	DWORD PTR[12+rbp],edx
        +
        +	jmp	$L$cbc_exit
        +
        +ALIGN	4
        +$L$cbc_slow_enc_tail::
        +	mov	r11,rax
        +	mov	r12,rcx
        +	mov	rcx,r10
        +	mov	rsi,r8
        +	mov	rdi,r9
        +	DD	09066A4F3h
        +
        +	mov	rcx,16
        +	sub	rcx,r10
        +	xor	rax,rax
        +	DD	09066AAF3h
        +
        +	mov	r8,r9
        +	mov	r10,16
        +	mov	rax,r11
        +	mov	rcx,r12
        +	jmp	$L$cbc_slow_enc_loop
        +
        +
        +ALIGN	16
        +$L$SLOW_DECRYPT::
        +	shr	rax,3
        +	add	r14,rax
        +
        +	mov	r11,QWORD PTR[rbp]
        +	mov	r12,QWORD PTR[8+rbp]
        +	mov	QWORD PTR[((0+64))+rsp],r11
        +	mov	QWORD PTR[((8+64))+rsp],r12
        +
        +ALIGN	4
        +$L$cbc_slow_dec_loop::
        +	mov	eax,DWORD PTR[r8]
        +	mov	ebx,DWORD PTR[4+r8]
        +	mov	ecx,DWORD PTR[8+r8]
        +	mov	edx,DWORD PTR[12+r8]
        +	mov	r15,QWORD PTR[rsp]
        +	mov	QWORD PTR[24+rsp],r8
        +	mov	QWORD PTR[32+rsp],r9
        +	mov	QWORD PTR[40+rsp],r10
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	mov	r8,QWORD PTR[24+rsp]
        +	mov	r9,QWORD PTR[32+rsp]
        +	mov	r10,QWORD PTR[40+rsp]
        +	xor	eax,DWORD PTR[((0+64))+rsp]
        +	xor	ebx,DWORD PTR[((4+64))+rsp]
        +	xor	ecx,DWORD PTR[((8+64))+rsp]
        +	xor	edx,DWORD PTR[((12+64))+rsp]
        +
        +	mov	r11,QWORD PTR[r8]
        +	mov	r12,QWORD PTR[8+r8]
        +	sub	r10,16
        +	jc	$L$cbc_slow_dec_partial
        +	jz	$L$cbc_slow_dec_done
        +
        +	mov	QWORD PTR[((0+64))+rsp],r11
        +	mov	QWORD PTR[((8+64))+rsp],r12
        +
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	r9,QWORD PTR[16+r9]
        +	jmp	$L$cbc_slow_dec_loop
        +$L$cbc_slow_dec_done::
        +	mov	rdi,QWORD PTR[56+rsp]
        +	mov	QWORD PTR[rdi],r11
        +	mov	QWORD PTR[8+rdi],r12
        +
        +	mov	DWORD PTR[r9],eax
        +	mov	DWORD PTR[4+r9],ebx
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +
        +	jmp	$L$cbc_exit
        +
        +ALIGN	4
        +$L$cbc_slow_dec_partial::
        +	mov	rdi,QWORD PTR[56+rsp]
        +	mov	QWORD PTR[rdi],r11
        +	mov	QWORD PTR[8+rdi],r12
        +
        +	mov	DWORD PTR[((0+64))+rsp],eax
        +	mov	DWORD PTR[((4+64))+rsp],ebx
        +	mov	DWORD PTR[((8+64))+rsp],ecx
        +	mov	DWORD PTR[((12+64))+rsp],edx
        +
        +	mov	rdi,r9
        +	lea	rsi,QWORD PTR[64+rsp]
        +	lea	rcx,QWORD PTR[16+r10]
        +	DD	09066A4F3h
        +
        +	jmp	$L$cbc_exit
        +
        +ALIGN	16
        +$L$cbc_exit::
        +	mov	rsi,QWORD PTR[16+rsp]
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$cbc_popfq::
        +	popfq
        +$L$cbc_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_AES_cbc_encrypt::
        +AES_cbc_encrypt	ENDP
        +ALIGN	64
        +$L$AES_Te::
        +	DD	0a56363c6h,0a56363c6h
        +	DD	0847c7cf8h,0847c7cf8h
        +	DD	0997777eeh,0997777eeh
        +	DD	08d7b7bf6h,08d7b7bf6h
        +	DD	00df2f2ffh,00df2f2ffh
        +	DD	0bd6b6bd6h,0bd6b6bd6h
        +	DD	0b16f6fdeh,0b16f6fdeh
        +	DD	054c5c591h,054c5c591h
        +	DD	050303060h,050303060h
        +	DD	003010102h,003010102h
        +	DD	0a96767ceh,0a96767ceh
        +	DD	07d2b2b56h,07d2b2b56h
        +	DD	019fefee7h,019fefee7h
        +	DD	062d7d7b5h,062d7d7b5h
        +	DD	0e6abab4dh,0e6abab4dh
        +	DD	09a7676ech,09a7676ech
        +	DD	045caca8fh,045caca8fh
        +	DD	09d82821fh,09d82821fh
        +	DD	040c9c989h,040c9c989h
        +	DD	0877d7dfah,0877d7dfah
        +	DD	015fafaefh,015fafaefh
        +	DD	0eb5959b2h,0eb5959b2h
        +	DD	0c947478eh,0c947478eh
        +	DD	00bf0f0fbh,00bf0f0fbh
        +	DD	0ecadad41h,0ecadad41h
        +	DD	067d4d4b3h,067d4d4b3h
        +	DD	0fda2a25fh,0fda2a25fh
        +	DD	0eaafaf45h,0eaafaf45h
        +	DD	0bf9c9c23h,0bf9c9c23h
        +	DD	0f7a4a453h,0f7a4a453h
        +	DD	0967272e4h,0967272e4h
        +	DD	05bc0c09bh,05bc0c09bh
        +	DD	0c2b7b775h,0c2b7b775h
        +	DD	01cfdfde1h,01cfdfde1h
        +	DD	0ae93933dh,0ae93933dh
        +	DD	06a26264ch,06a26264ch
        +	DD	05a36366ch,05a36366ch
        +	DD	0413f3f7eh,0413f3f7eh
        +	DD	002f7f7f5h,002f7f7f5h
        +	DD	04fcccc83h,04fcccc83h
        +	DD	05c343468h,05c343468h
        +	DD	0f4a5a551h,0f4a5a551h
        +	DD	034e5e5d1h,034e5e5d1h
        +	DD	008f1f1f9h,008f1f1f9h
        +	DD	0937171e2h,0937171e2h
        +	DD	073d8d8abh,073d8d8abh
        +	DD	053313162h,053313162h
        +	DD	03f15152ah,03f15152ah
        +	DD	00c040408h,00c040408h
        +	DD	052c7c795h,052c7c795h
        +	DD	065232346h,065232346h
        +	DD	05ec3c39dh,05ec3c39dh
        +	DD	028181830h,028181830h
        +	DD	0a1969637h,0a1969637h
        +	DD	00f05050ah,00f05050ah
        +	DD	0b59a9a2fh,0b59a9a2fh
        +	DD	00907070eh,00907070eh
        +	DD	036121224h,036121224h
        +	DD	09b80801bh,09b80801bh
        +	DD	03de2e2dfh,03de2e2dfh
        +	DD	026ebebcdh,026ebebcdh
        +	DD	06927274eh,06927274eh
        +	DD	0cdb2b27fh,0cdb2b27fh
        +	DD	09f7575eah,09f7575eah
        +	DD	01b090912h,01b090912h
        +	DD	09e83831dh,09e83831dh
        +	DD	0742c2c58h,0742c2c58h
        +	DD	02e1a1a34h,02e1a1a34h
        +	DD	02d1b1b36h,02d1b1b36h
        +	DD	0b26e6edch,0b26e6edch
        +	DD	0ee5a5ab4h,0ee5a5ab4h
        +	DD	0fba0a05bh,0fba0a05bh
        +	DD	0f65252a4h,0f65252a4h
        +	DD	04d3b3b76h,04d3b3b76h
        +	DD	061d6d6b7h,061d6d6b7h
        +	DD	0ceb3b37dh,0ceb3b37dh
        +	DD	07b292952h,07b292952h
        +	DD	03ee3e3ddh,03ee3e3ddh
        +	DD	0712f2f5eh,0712f2f5eh
        +	DD	097848413h,097848413h
        +	DD	0f55353a6h,0f55353a6h
        +	DD	068d1d1b9h,068d1d1b9h
        +	DD	000000000h,000000000h
        +	DD	02cededc1h,02cededc1h
        +	DD	060202040h,060202040h
        +	DD	01ffcfce3h,01ffcfce3h
        +	DD	0c8b1b179h,0c8b1b179h
        +	DD	0ed5b5bb6h,0ed5b5bb6h
        +	DD	0be6a6ad4h,0be6a6ad4h
        +	DD	046cbcb8dh,046cbcb8dh
        +	DD	0d9bebe67h,0d9bebe67h
        +	DD	04b393972h,04b393972h
        +	DD	0de4a4a94h,0de4a4a94h
        +	DD	0d44c4c98h,0d44c4c98h
        +	DD	0e85858b0h,0e85858b0h
        +	DD	04acfcf85h,04acfcf85h
        +	DD	06bd0d0bbh,06bd0d0bbh
        +	DD	02aefefc5h,02aefefc5h
        +	DD	0e5aaaa4fh,0e5aaaa4fh
        +	DD	016fbfbedh,016fbfbedh
        +	DD	0c5434386h,0c5434386h
        +	DD	0d74d4d9ah,0d74d4d9ah
        +	DD	055333366h,055333366h
        +	DD	094858511h,094858511h
        +	DD	0cf45458ah,0cf45458ah
        +	DD	010f9f9e9h,010f9f9e9h
        +	DD	006020204h,006020204h
        +	DD	0817f7ffeh,0817f7ffeh
        +	DD	0f05050a0h,0f05050a0h
        +	DD	0443c3c78h,0443c3c78h
        +	DD	0ba9f9f25h,0ba9f9f25h
        +	DD	0e3a8a84bh,0e3a8a84bh
        +	DD	0f35151a2h,0f35151a2h
        +	DD	0fea3a35dh,0fea3a35dh
        +	DD	0c0404080h,0c0404080h
        +	DD	08a8f8f05h,08a8f8f05h
        +	DD	0ad92923fh,0ad92923fh
        +	DD	0bc9d9d21h,0bc9d9d21h
        +	DD	048383870h,048383870h
        +	DD	004f5f5f1h,004f5f5f1h
        +	DD	0dfbcbc63h,0dfbcbc63h
        +	DD	0c1b6b677h,0c1b6b677h
        +	DD	075dadaafh,075dadaafh
        +	DD	063212142h,063212142h
        +	DD	030101020h,030101020h
        +	DD	01affffe5h,01affffe5h
        +	DD	00ef3f3fdh,00ef3f3fdh
        +	DD	06dd2d2bfh,06dd2d2bfh
        +	DD	04ccdcd81h,04ccdcd81h
        +	DD	0140c0c18h,0140c0c18h
        +	DD	035131326h,035131326h
        +	DD	02fececc3h,02fececc3h
        +	DD	0e15f5fbeh,0e15f5fbeh
        +	DD	0a2979735h,0a2979735h
        +	DD	0cc444488h,0cc444488h
        +	DD	03917172eh,03917172eh
        +	DD	057c4c493h,057c4c493h
        +	DD	0f2a7a755h,0f2a7a755h
        +	DD	0827e7efch,0827e7efch
        +	DD	0473d3d7ah,0473d3d7ah
        +	DD	0ac6464c8h,0ac6464c8h
        +	DD	0e75d5dbah,0e75d5dbah
        +	DD	02b191932h,02b191932h
        +	DD	0957373e6h,0957373e6h
        +	DD	0a06060c0h,0a06060c0h
        +	DD	098818119h,098818119h
        +	DD	0d14f4f9eh,0d14f4f9eh
        +	DD	07fdcdca3h,07fdcdca3h
        +	DD	066222244h,066222244h
        +	DD	07e2a2a54h,07e2a2a54h
        +	DD	0ab90903bh,0ab90903bh
        +	DD	08388880bh,08388880bh
        +	DD	0ca46468ch,0ca46468ch
        +	DD	029eeeec7h,029eeeec7h
        +	DD	0d3b8b86bh,0d3b8b86bh
        +	DD	03c141428h,03c141428h
        +	DD	079dedea7h,079dedea7h
        +	DD	0e25e5ebch,0e25e5ebch
        +	DD	01d0b0b16h,01d0b0b16h
        +	DD	076dbdbadh,076dbdbadh
        +	DD	03be0e0dbh,03be0e0dbh
        +	DD	056323264h,056323264h
        +	DD	04e3a3a74h,04e3a3a74h
        +	DD	01e0a0a14h,01e0a0a14h
        +	DD	0db494992h,0db494992h
        +	DD	00a06060ch,00a06060ch
        +	DD	06c242448h,06c242448h
        +	DD	0e45c5cb8h,0e45c5cb8h
        +	DD	05dc2c29fh,05dc2c29fh
        +	DD	06ed3d3bdh,06ed3d3bdh
        +	DD	0efacac43h,0efacac43h
        +	DD	0a66262c4h,0a66262c4h
        +	DD	0a8919139h,0a8919139h
        +	DD	0a4959531h,0a4959531h
        +	DD	037e4e4d3h,037e4e4d3h
        +	DD	08b7979f2h,08b7979f2h
        +	DD	032e7e7d5h,032e7e7d5h
        +	DD	043c8c88bh,043c8c88bh
        +	DD	05937376eh,05937376eh
        +	DD	0b76d6ddah,0b76d6ddah
        +	DD	08c8d8d01h,08c8d8d01h
        +	DD	064d5d5b1h,064d5d5b1h
        +	DD	0d24e4e9ch,0d24e4e9ch
        +	DD	0e0a9a949h,0e0a9a949h
        +	DD	0b46c6cd8h,0b46c6cd8h
        +	DD	0fa5656ach,0fa5656ach
        +	DD	007f4f4f3h,007f4f4f3h
        +	DD	025eaeacfh,025eaeacfh
        +	DD	0af6565cah,0af6565cah
        +	DD	08e7a7af4h,08e7a7af4h
        +	DD	0e9aeae47h,0e9aeae47h
        +	DD	018080810h,018080810h
        +	DD	0d5baba6fh,0d5baba6fh
        +	DD	0887878f0h,0887878f0h
        +	DD	06f25254ah,06f25254ah
        +	DD	0722e2e5ch,0722e2e5ch
        +	DD	0241c1c38h,0241c1c38h
        +	DD	0f1a6a657h,0f1a6a657h
        +	DD	0c7b4b473h,0c7b4b473h
        +	DD	051c6c697h,051c6c697h
        +	DD	023e8e8cbh,023e8e8cbh
        +	DD	07cdddda1h,07cdddda1h
        +	DD	09c7474e8h,09c7474e8h
        +	DD	0211f1f3eh,0211f1f3eh
        +	DD	0dd4b4b96h,0dd4b4b96h
        +	DD	0dcbdbd61h,0dcbdbd61h
        +	DD	0868b8b0dh,0868b8b0dh
        +	DD	0858a8a0fh,0858a8a0fh
        +	DD	0907070e0h,0907070e0h
        +	DD	0423e3e7ch,0423e3e7ch
        +	DD	0c4b5b571h,0c4b5b571h
        +	DD	0aa6666cch,0aa6666cch
        +	DD	0d8484890h,0d8484890h
        +	DD	005030306h,005030306h
        +	DD	001f6f6f7h,001f6f6f7h
        +	DD	0120e0e1ch,0120e0e1ch
        +	DD	0a36161c2h,0a36161c2h
        +	DD	05f35356ah,05f35356ah
        +	DD	0f95757aeh,0f95757aeh
        +	DD	0d0b9b969h,0d0b9b969h
        +	DD	091868617h,091868617h
        +	DD	058c1c199h,058c1c199h
        +	DD	0271d1d3ah,0271d1d3ah
        +	DD	0b99e9e27h,0b99e9e27h
        +	DD	038e1e1d9h,038e1e1d9h
        +	DD	013f8f8ebh,013f8f8ebh
        +	DD	0b398982bh,0b398982bh
        +	DD	033111122h,033111122h
        +	DD	0bb6969d2h,0bb6969d2h
        +	DD	070d9d9a9h,070d9d9a9h
        +	DD	0898e8e07h,0898e8e07h
        +	DD	0a7949433h,0a7949433h
        +	DD	0b69b9b2dh,0b69b9b2dh
        +	DD	0221e1e3ch,0221e1e3ch
        +	DD	092878715h,092878715h
        +	DD	020e9e9c9h,020e9e9c9h
        +	DD	049cece87h,049cece87h
        +	DD	0ff5555aah,0ff5555aah
        +	DD	078282850h,078282850h
        +	DD	07adfdfa5h,07adfdfa5h
        +	DD	08f8c8c03h,08f8c8c03h
        +	DD	0f8a1a159h,0f8a1a159h
        +	DD	080898909h,080898909h
        +	DD	0170d0d1ah,0170d0d1ah
        +	DD	0dabfbf65h,0dabfbf65h
        +	DD	031e6e6d7h,031e6e6d7h
        +	DD	0c6424284h,0c6424284h
        +	DD	0b86868d0h,0b86868d0h
        +	DD	0c3414182h,0c3414182h
        +	DD	0b0999929h,0b0999929h
        +	DD	0772d2d5ah,0772d2d5ah
        +	DD	0110f0f1eh,0110f0f1eh
        +	DD	0cbb0b07bh,0cbb0b07bh
        +	DD	0fc5454a8h,0fc5454a8h
        +	DD	0d6bbbb6dh,0d6bbbb6dh
        +	DD	03a16162ch,03a16162ch
        +DB	063h,07ch,077h,07bh,0f2h,06bh,06fh,0c5h
        +DB	030h,001h,067h,02bh,0feh,0d7h,0abh,076h
        +DB	0cah,082h,0c9h,07dh,0fah,059h,047h,0f0h
        +DB	0adh,0d4h,0a2h,0afh,09ch,0a4h,072h,0c0h
        +DB	0b7h,0fdh,093h,026h,036h,03fh,0f7h,0cch
        +DB	034h,0a5h,0e5h,0f1h,071h,0d8h,031h,015h
        +DB	004h,0c7h,023h,0c3h,018h,096h,005h,09ah
        +DB	007h,012h,080h,0e2h,0ebh,027h,0b2h,075h
        +DB	009h,083h,02ch,01ah,01bh,06eh,05ah,0a0h
        +DB	052h,03bh,0d6h,0b3h,029h,0e3h,02fh,084h
        +DB	053h,0d1h,000h,0edh,020h,0fch,0b1h,05bh
        +DB	06ah,0cbh,0beh,039h,04ah,04ch,058h,0cfh
        +DB	0d0h,0efh,0aah,0fbh,043h,04dh,033h,085h
        +DB	045h,0f9h,002h,07fh,050h,03ch,09fh,0a8h
        +DB	051h,0a3h,040h,08fh,092h,09dh,038h,0f5h
        +DB	0bch,0b6h,0dah,021h,010h,0ffh,0f3h,0d2h
        +DB	0cdh,00ch,013h,0ech,05fh,097h,044h,017h
        +DB	0c4h,0a7h,07eh,03dh,064h,05dh,019h,073h
        +DB	060h,081h,04fh,0dch,022h,02ah,090h,088h
        +DB	046h,0eeh,0b8h,014h,0deh,05eh,00bh,0dbh
        +DB	0e0h,032h,03ah,00ah,049h,006h,024h,05ch
        +DB	0c2h,0d3h,0ach,062h,091h,095h,0e4h,079h
        +DB	0e7h,0c8h,037h,06dh,08dh,0d5h,04eh,0a9h
        +DB	06ch,056h,0f4h,0eah,065h,07ah,0aeh,008h
        +DB	0bah,078h,025h,02eh,01ch,0a6h,0b4h,0c6h
        +DB	0e8h,0ddh,074h,01fh,04bh,0bdh,08bh,08ah
        +DB	070h,03eh,0b5h,066h,048h,003h,0f6h,00eh
        +DB	061h,035h,057h,0b9h,086h,0c1h,01dh,09eh
        +DB	0e1h,0f8h,098h,011h,069h,0d9h,08eh,094h
        +DB	09bh,01eh,087h,0e9h,0ceh,055h,028h,0dfh
        +DB	08ch,0a1h,089h,00dh,0bfh,0e6h,042h,068h
        +DB	041h,099h,02dh,00fh,0b0h,054h,0bbh,016h
        +DB	063h,07ch,077h,07bh,0f2h,06bh,06fh,0c5h
        +DB	030h,001h,067h,02bh,0feh,0d7h,0abh,076h
        +DB	0cah,082h,0c9h,07dh,0fah,059h,047h,0f0h
        +DB	0adh,0d4h,0a2h,0afh,09ch,0a4h,072h,0c0h
        +DB	0b7h,0fdh,093h,026h,036h,03fh,0f7h,0cch
        +DB	034h,0a5h,0e5h,0f1h,071h,0d8h,031h,015h
        +DB	004h,0c7h,023h,0c3h,018h,096h,005h,09ah
        +DB	007h,012h,080h,0e2h,0ebh,027h,0b2h,075h
        +DB	009h,083h,02ch,01ah,01bh,06eh,05ah,0a0h
        +DB	052h,03bh,0d6h,0b3h,029h,0e3h,02fh,084h
        +DB	053h,0d1h,000h,0edh,020h,0fch,0b1h,05bh
        +DB	06ah,0cbh,0beh,039h,04ah,04ch,058h,0cfh
        +DB	0d0h,0efh,0aah,0fbh,043h,04dh,033h,085h
        +DB	045h,0f9h,002h,07fh,050h,03ch,09fh,0a8h
        +DB	051h,0a3h,040h,08fh,092h,09dh,038h,0f5h
        +DB	0bch,0b6h,0dah,021h,010h,0ffh,0f3h,0d2h
        +DB	0cdh,00ch,013h,0ech,05fh,097h,044h,017h
        +DB	0c4h,0a7h,07eh,03dh,064h,05dh,019h,073h
        +DB	060h,081h,04fh,0dch,022h,02ah,090h,088h
        +DB	046h,0eeh,0b8h,014h,0deh,05eh,00bh,0dbh
        +DB	0e0h,032h,03ah,00ah,049h,006h,024h,05ch
        +DB	0c2h,0d3h,0ach,062h,091h,095h,0e4h,079h
        +DB	0e7h,0c8h,037h,06dh,08dh,0d5h,04eh,0a9h
        +DB	06ch,056h,0f4h,0eah,065h,07ah,0aeh,008h
        +DB	0bah,078h,025h,02eh,01ch,0a6h,0b4h,0c6h
        +DB	0e8h,0ddh,074h,01fh,04bh,0bdh,08bh,08ah
        +DB	070h,03eh,0b5h,066h,048h,003h,0f6h,00eh
        +DB	061h,035h,057h,0b9h,086h,0c1h,01dh,09eh
        +DB	0e1h,0f8h,098h,011h,069h,0d9h,08eh,094h
        +DB	09bh,01eh,087h,0e9h,0ceh,055h,028h,0dfh
        +DB	08ch,0a1h,089h,00dh,0bfh,0e6h,042h,068h
        +DB	041h,099h,02dh,00fh,0b0h,054h,0bbh,016h
        +DB	063h,07ch,077h,07bh,0f2h,06bh,06fh,0c5h
        +DB	030h,001h,067h,02bh,0feh,0d7h,0abh,076h
        +DB	0cah,082h,0c9h,07dh,0fah,059h,047h,0f0h
        +DB	0adh,0d4h,0a2h,0afh,09ch,0a4h,072h,0c0h
        +DB	0b7h,0fdh,093h,026h,036h,03fh,0f7h,0cch
        +DB	034h,0a5h,0e5h,0f1h,071h,0d8h,031h,015h
        +DB	004h,0c7h,023h,0c3h,018h,096h,005h,09ah
        +DB	007h,012h,080h,0e2h,0ebh,027h,0b2h,075h
        +DB	009h,083h,02ch,01ah,01bh,06eh,05ah,0a0h
        +DB	052h,03bh,0d6h,0b3h,029h,0e3h,02fh,084h
        +DB	053h,0d1h,000h,0edh,020h,0fch,0b1h,05bh
        +DB	06ah,0cbh,0beh,039h,04ah,04ch,058h,0cfh
        +DB	0d0h,0efh,0aah,0fbh,043h,04dh,033h,085h
        +DB	045h,0f9h,002h,07fh,050h,03ch,09fh,0a8h
        +DB	051h,0a3h,040h,08fh,092h,09dh,038h,0f5h
        +DB	0bch,0b6h,0dah,021h,010h,0ffh,0f3h,0d2h
        +DB	0cdh,00ch,013h,0ech,05fh,097h,044h,017h
        +DB	0c4h,0a7h,07eh,03dh,064h,05dh,019h,073h
        +DB	060h,081h,04fh,0dch,022h,02ah,090h,088h
        +DB	046h,0eeh,0b8h,014h,0deh,05eh,00bh,0dbh
        +DB	0e0h,032h,03ah,00ah,049h,006h,024h,05ch
        +DB	0c2h,0d3h,0ach,062h,091h,095h,0e4h,079h
        +DB	0e7h,0c8h,037h,06dh,08dh,0d5h,04eh,0a9h
        +DB	06ch,056h,0f4h,0eah,065h,07ah,0aeh,008h
        +DB	0bah,078h,025h,02eh,01ch,0a6h,0b4h,0c6h
        +DB	0e8h,0ddh,074h,01fh,04bh,0bdh,08bh,08ah
        +DB	070h,03eh,0b5h,066h,048h,003h,0f6h,00eh
        +DB	061h,035h,057h,0b9h,086h,0c1h,01dh,09eh
        +DB	0e1h,0f8h,098h,011h,069h,0d9h,08eh,094h
        +DB	09bh,01eh,087h,0e9h,0ceh,055h,028h,0dfh
        +DB	08ch,0a1h,089h,00dh,0bfh,0e6h,042h,068h
        +DB	041h,099h,02dh,00fh,0b0h,054h,0bbh,016h
        +DB	063h,07ch,077h,07bh,0f2h,06bh,06fh,0c5h
        +DB	030h,001h,067h,02bh,0feh,0d7h,0abh,076h
        +DB	0cah,082h,0c9h,07dh,0fah,059h,047h,0f0h
        +DB	0adh,0d4h,0a2h,0afh,09ch,0a4h,072h,0c0h
        +DB	0b7h,0fdh,093h,026h,036h,03fh,0f7h,0cch
        +DB	034h,0a5h,0e5h,0f1h,071h,0d8h,031h,015h
        +DB	004h,0c7h,023h,0c3h,018h,096h,005h,09ah
        +DB	007h,012h,080h,0e2h,0ebh,027h,0b2h,075h
        +DB	009h,083h,02ch,01ah,01bh,06eh,05ah,0a0h
        +DB	052h,03bh,0d6h,0b3h,029h,0e3h,02fh,084h
        +DB	053h,0d1h,000h,0edh,020h,0fch,0b1h,05bh
        +DB	06ah,0cbh,0beh,039h,04ah,04ch,058h,0cfh
        +DB	0d0h,0efh,0aah,0fbh,043h,04dh,033h,085h
        +DB	045h,0f9h,002h,07fh,050h,03ch,09fh,0a8h
        +DB	051h,0a3h,040h,08fh,092h,09dh,038h,0f5h
        +DB	0bch,0b6h,0dah,021h,010h,0ffh,0f3h,0d2h
        +DB	0cdh,00ch,013h,0ech,05fh,097h,044h,017h
        +DB	0c4h,0a7h,07eh,03dh,064h,05dh,019h,073h
        +DB	060h,081h,04fh,0dch,022h,02ah,090h,088h
        +DB	046h,0eeh,0b8h,014h,0deh,05eh,00bh,0dbh
        +DB	0e0h,032h,03ah,00ah,049h,006h,024h,05ch
        +DB	0c2h,0d3h,0ach,062h,091h,095h,0e4h,079h
        +DB	0e7h,0c8h,037h,06dh,08dh,0d5h,04eh,0a9h
        +DB	06ch,056h,0f4h,0eah,065h,07ah,0aeh,008h
        +DB	0bah,078h,025h,02eh,01ch,0a6h,0b4h,0c6h
        +DB	0e8h,0ddh,074h,01fh,04bh,0bdh,08bh,08ah
        +DB	070h,03eh,0b5h,066h,048h,003h,0f6h,00eh
        +DB	061h,035h,057h,0b9h,086h,0c1h,01dh,09eh
        +DB	0e1h,0f8h,098h,011h,069h,0d9h,08eh,094h
        +DB	09bh,01eh,087h,0e9h,0ceh,055h,028h,0dfh
        +DB	08ch,0a1h,089h,00dh,0bfh,0e6h,042h,068h
        +DB	041h,099h,02dh,00fh,0b0h,054h,0bbh,016h
        +	DD	000000001h,000000002h,000000004h,000000008h
        +	DD	000000010h,000000020h,000000040h,000000080h
        +	DD	00000001bh,000000036h,080808080h,080808080h
        +	DD	0fefefefeh,0fefefefeh,01b1b1b1bh,01b1b1b1bh
        +ALIGN	64
        +$L$AES_Td::
        +	DD	050a7f451h,050a7f451h
        +	DD	05365417eh,05365417eh
        +	DD	0c3a4171ah,0c3a4171ah
        +	DD	0965e273ah,0965e273ah
        +	DD	0cb6bab3bh,0cb6bab3bh
        +	DD	0f1459d1fh,0f1459d1fh
        +	DD	0ab58faach,0ab58faach
        +	DD	09303e34bh,09303e34bh
        +	DD	055fa3020h,055fa3020h
        +	DD	0f66d76adh,0f66d76adh
        +	DD	09176cc88h,09176cc88h
        +	DD	0254c02f5h,0254c02f5h
        +	DD	0fcd7e54fh,0fcd7e54fh
        +	DD	0d7cb2ac5h,0d7cb2ac5h
        +	DD	080443526h,080443526h
        +	DD	08fa362b5h,08fa362b5h
        +	DD	0495ab1deh,0495ab1deh
        +	DD	0671bba25h,0671bba25h
        +	DD	0980eea45h,0980eea45h
        +	DD	0e1c0fe5dh,0e1c0fe5dh
        +	DD	002752fc3h,002752fc3h
        +	DD	012f04c81h,012f04c81h
        +	DD	0a397468dh,0a397468dh
        +	DD	0c6f9d36bh,0c6f9d36bh
        +	DD	0e75f8f03h,0e75f8f03h
        +	DD	0959c9215h,0959c9215h
        +	DD	0eb7a6dbfh,0eb7a6dbfh
        +	DD	0da595295h,0da595295h
        +	DD	02d83bed4h,02d83bed4h
        +	DD	0d3217458h,0d3217458h
        +	DD	02969e049h,02969e049h
        +	DD	044c8c98eh,044c8c98eh
        +	DD	06a89c275h,06a89c275h
        +	DD	078798ef4h,078798ef4h
        +	DD	06b3e5899h,06b3e5899h
        +	DD	0dd71b927h,0dd71b927h
        +	DD	0b64fe1beh,0b64fe1beh
        +	DD	017ad88f0h,017ad88f0h
        +	DD	066ac20c9h,066ac20c9h
        +	DD	0b43ace7dh,0b43ace7dh
        +	DD	0184adf63h,0184adf63h
        +	DD	082311ae5h,082311ae5h
        +	DD	060335197h,060335197h
        +	DD	0457f5362h,0457f5362h
        +	DD	0e07764b1h,0e07764b1h
        +	DD	084ae6bbbh,084ae6bbbh
        +	DD	01ca081feh,01ca081feh
        +	DD	0942b08f9h,0942b08f9h
        +	DD	058684870h,058684870h
        +	DD	019fd458fh,019fd458fh
        +	DD	0876cde94h,0876cde94h
        +	DD	0b7f87b52h,0b7f87b52h
        +	DD	023d373abh,023d373abh
        +	DD	0e2024b72h,0e2024b72h
        +	DD	0578f1fe3h,0578f1fe3h
        +	DD	02aab5566h,02aab5566h
        +	DD	00728ebb2h,00728ebb2h
        +	DD	003c2b52fh,003c2b52fh
        +	DD	09a7bc586h,09a7bc586h
        +	DD	0a50837d3h,0a50837d3h
        +	DD	0f2872830h,0f2872830h
        +	DD	0b2a5bf23h,0b2a5bf23h
        +	DD	0ba6a0302h,0ba6a0302h
        +	DD	05c8216edh,05c8216edh
        +	DD	02b1ccf8ah,02b1ccf8ah
        +	DD	092b479a7h,092b479a7h
        +	DD	0f0f207f3h,0f0f207f3h
        +	DD	0a1e2694eh,0a1e2694eh
        +	DD	0cdf4da65h,0cdf4da65h
        +	DD	0d5be0506h,0d5be0506h
        +	DD	01f6234d1h,01f6234d1h
        +	DD	08afea6c4h,08afea6c4h
        +	DD	09d532e34h,09d532e34h
        +	DD	0a055f3a2h,0a055f3a2h
        +	DD	032e18a05h,032e18a05h
        +	DD	075ebf6a4h,075ebf6a4h
        +	DD	039ec830bh,039ec830bh
        +	DD	0aaef6040h,0aaef6040h
        +	DD	0069f715eh,0069f715eh
        +	DD	051106ebdh,051106ebdh
        +	DD	0f98a213eh,0f98a213eh
        +	DD	03d06dd96h,03d06dd96h
        +	DD	0ae053eddh,0ae053eddh
        +	DD	046bde64dh,046bde64dh
        +	DD	0b58d5491h,0b58d5491h
        +	DD	0055dc471h,0055dc471h
        +	DD	06fd40604h,06fd40604h
        +	DD	0ff155060h,0ff155060h
        +	DD	024fb9819h,024fb9819h
        +	DD	097e9bdd6h,097e9bdd6h
        +	DD	0cc434089h,0cc434089h
        +	DD	0779ed967h,0779ed967h
        +	DD	0bd42e8b0h,0bd42e8b0h
        +	DD	0888b8907h,0888b8907h
        +	DD	0385b19e7h,0385b19e7h
        +	DD	0dbeec879h,0dbeec879h
        +	DD	0470a7ca1h,0470a7ca1h
        +	DD	0e90f427ch,0e90f427ch
        +	DD	0c91e84f8h,0c91e84f8h
        +	DD	000000000h,000000000h
        +	DD	083868009h,083868009h
        +	DD	048ed2b32h,048ed2b32h
        +	DD	0ac70111eh,0ac70111eh
        +	DD	04e725a6ch,04e725a6ch
        +	DD	0fbff0efdh,0fbff0efdh
        +	DD	05638850fh,05638850fh
        +	DD	01ed5ae3dh,01ed5ae3dh
        +	DD	027392d36h,027392d36h
        +	DD	064d90f0ah,064d90f0ah
        +	DD	021a65c68h,021a65c68h
        +	DD	0d1545b9bh,0d1545b9bh
        +	DD	03a2e3624h,03a2e3624h
        +	DD	0b1670a0ch,0b1670a0ch
        +	DD	00fe75793h,00fe75793h
        +	DD	0d296eeb4h,0d296eeb4h
        +	DD	09e919b1bh,09e919b1bh
        +	DD	04fc5c080h,04fc5c080h
        +	DD	0a220dc61h,0a220dc61h
        +	DD	0694b775ah,0694b775ah
        +	DD	0161a121ch,0161a121ch
        +	DD	00aba93e2h,00aba93e2h
        +	DD	0e52aa0c0h,0e52aa0c0h
        +	DD	043e0223ch,043e0223ch
        +	DD	01d171b12h,01d171b12h
        +	DD	00b0d090eh,00b0d090eh
        +	DD	0adc78bf2h,0adc78bf2h
        +	DD	0b9a8b62dh,0b9a8b62dh
        +	DD	0c8a91e14h,0c8a91e14h
        +	DD	08519f157h,08519f157h
        +	DD	04c0775afh,04c0775afh
        +	DD	0bbdd99eeh,0bbdd99eeh
        +	DD	0fd607fa3h,0fd607fa3h
        +	DD	09f2601f7h,09f2601f7h
        +	DD	0bcf5725ch,0bcf5725ch
        +	DD	0c53b6644h,0c53b6644h
        +	DD	0347efb5bh,0347efb5bh
        +	DD	07629438bh,07629438bh
        +	DD	0dcc623cbh,0dcc623cbh
        +	DD	068fcedb6h,068fcedb6h
        +	DD	063f1e4b8h,063f1e4b8h
        +	DD	0cadc31d7h,0cadc31d7h
        +	DD	010856342h,010856342h
        +	DD	040229713h,040229713h
        +	DD	02011c684h,02011c684h
        +	DD	07d244a85h,07d244a85h
        +	DD	0f83dbbd2h,0f83dbbd2h
        +	DD	01132f9aeh,01132f9aeh
        +	DD	06da129c7h,06da129c7h
        +	DD	04b2f9e1dh,04b2f9e1dh
        +	DD	0f330b2dch,0f330b2dch
        +	DD	0ec52860dh,0ec52860dh
        +	DD	0d0e3c177h,0d0e3c177h
        +	DD	06c16b32bh,06c16b32bh
        +	DD	099b970a9h,099b970a9h
        +	DD	0fa489411h,0fa489411h
        +	DD	02264e947h,02264e947h
        +	DD	0c48cfca8h,0c48cfca8h
        +	DD	01a3ff0a0h,01a3ff0a0h
        +	DD	0d82c7d56h,0d82c7d56h
        +	DD	0ef903322h,0ef903322h
        +	DD	0c74e4987h,0c74e4987h
        +	DD	0c1d138d9h,0c1d138d9h
        +	DD	0fea2ca8ch,0fea2ca8ch
        +	DD	0360bd498h,0360bd498h
        +	DD	0cf81f5a6h,0cf81f5a6h
        +	DD	028de7aa5h,028de7aa5h
        +	DD	0268eb7dah,0268eb7dah
        +	DD	0a4bfad3fh,0a4bfad3fh
        +	DD	0e49d3a2ch,0e49d3a2ch
        +	DD	00d927850h,00d927850h
        +	DD	09bcc5f6ah,09bcc5f6ah
        +	DD	062467e54h,062467e54h
        +	DD	0c2138df6h,0c2138df6h
        +	DD	0e8b8d890h,0e8b8d890h
        +	DD	05ef7392eh,05ef7392eh
        +	DD	0f5afc382h,0f5afc382h
        +	DD	0be805d9fh,0be805d9fh
        +	DD	07c93d069h,07c93d069h
        +	DD	0a92dd56fh,0a92dd56fh
        +	DD	0b31225cfh,0b31225cfh
        +	DD	03b99acc8h,03b99acc8h
        +	DD	0a77d1810h,0a77d1810h
        +	DD	06e639ce8h,06e639ce8h
        +	DD	07bbb3bdbh,07bbb3bdbh
        +	DD	0097826cdh,0097826cdh
        +	DD	0f418596eh,0f418596eh
        +	DD	001b79aech,001b79aech
        +	DD	0a89a4f83h,0a89a4f83h
        +	DD	0656e95e6h,0656e95e6h
        +	DD	07ee6ffaah,07ee6ffaah
        +	DD	008cfbc21h,008cfbc21h
        +	DD	0e6e815efh,0e6e815efh
        +	DD	0d99be7bah,0d99be7bah
        +	DD	0ce366f4ah,0ce366f4ah
        +	DD	0d4099feah,0d4099feah
        +	DD	0d67cb029h,0d67cb029h
        +	DD	0afb2a431h,0afb2a431h
        +	DD	031233f2ah,031233f2ah
        +	DD	03094a5c6h,03094a5c6h
        +	DD	0c066a235h,0c066a235h
        +	DD	037bc4e74h,037bc4e74h
        +	DD	0a6ca82fch,0a6ca82fch
        +	DD	0b0d090e0h,0b0d090e0h
        +	DD	015d8a733h,015d8a733h
        +	DD	04a9804f1h,04a9804f1h
        +	DD	0f7daec41h,0f7daec41h
        +	DD	00e50cd7fh,00e50cd7fh
        +	DD	02ff69117h,02ff69117h
        +	DD	08dd64d76h,08dd64d76h
        +	DD	04db0ef43h,04db0ef43h
        +	DD	0544daacch,0544daacch
        +	DD	0df0496e4h,0df0496e4h
        +	DD	0e3b5d19eh,0e3b5d19eh
        +	DD	01b886a4ch,01b886a4ch
        +	DD	0b81f2cc1h,0b81f2cc1h
        +	DD	07f516546h,07f516546h
        +	DD	004ea5e9dh,004ea5e9dh
        +	DD	05d358c01h,05d358c01h
        +	DD	0737487fah,0737487fah
        +	DD	02e410bfbh,02e410bfbh
        +	DD	05a1d67b3h,05a1d67b3h
        +	DD	052d2db92h,052d2db92h
        +	DD	0335610e9h,0335610e9h
        +	DD	01347d66dh,01347d66dh
        +	DD	08c61d79ah,08c61d79ah
        +	DD	07a0ca137h,07a0ca137h
        +	DD	08e14f859h,08e14f859h
        +	DD	0893c13ebh,0893c13ebh
        +	DD	0ee27a9ceh,0ee27a9ceh
        +	DD	035c961b7h,035c961b7h
        +	DD	0ede51ce1h,0ede51ce1h
        +	DD	03cb1477ah,03cb1477ah
        +	DD	059dfd29ch,059dfd29ch
        +	DD	03f73f255h,03f73f255h
        +	DD	079ce1418h,079ce1418h
        +	DD	0bf37c773h,0bf37c773h
        +	DD	0eacdf753h,0eacdf753h
        +	DD	05baafd5fh,05baafd5fh
        +	DD	0146f3ddfh,0146f3ddfh
        +	DD	086db4478h,086db4478h
        +	DD	081f3afcah,081f3afcah
        +	DD	03ec468b9h,03ec468b9h
        +	DD	02c342438h,02c342438h
        +	DD	05f40a3c2h,05f40a3c2h
        +	DD	072c31d16h,072c31d16h
        +	DD	00c25e2bch,00c25e2bch
        +	DD	08b493c28h,08b493c28h
        +	DD	041950dffh,041950dffh
        +	DD	07101a839h,07101a839h
        +	DD	0deb30c08h,0deb30c08h
        +	DD	09ce4b4d8h,09ce4b4d8h
        +	DD	090c15664h,090c15664h
        +	DD	06184cb7bh,06184cb7bh
        +	DD	070b632d5h,070b632d5h
        +	DD	0745c6c48h,0745c6c48h
        +	DD	04257b8d0h,04257b8d0h
        +DB	052h,009h,06ah,0d5h,030h,036h,0a5h,038h
        +DB	0bfh,040h,0a3h,09eh,081h,0f3h,0d7h,0fbh
        +DB	07ch,0e3h,039h,082h,09bh,02fh,0ffh,087h
        +DB	034h,08eh,043h,044h,0c4h,0deh,0e9h,0cbh
        +DB	054h,07bh,094h,032h,0a6h,0c2h,023h,03dh
        +DB	0eeh,04ch,095h,00bh,042h,0fah,0c3h,04eh
        +DB	008h,02eh,0a1h,066h,028h,0d9h,024h,0b2h
        +DB	076h,05bh,0a2h,049h,06dh,08bh,0d1h,025h
        +DB	072h,0f8h,0f6h,064h,086h,068h,098h,016h
        +DB	0d4h,0a4h,05ch,0cch,05dh,065h,0b6h,092h
        +DB	06ch,070h,048h,050h,0fdh,0edh,0b9h,0dah
        +DB	05eh,015h,046h,057h,0a7h,08dh,09dh,084h
        +DB	090h,0d8h,0abh,000h,08ch,0bch,0d3h,00ah
        +DB	0f7h,0e4h,058h,005h,0b8h,0b3h,045h,006h
        +DB	0d0h,02ch,01eh,08fh,0cah,03fh,00fh,002h
        +DB	0c1h,0afh,0bdh,003h,001h,013h,08ah,06bh
        +DB	03ah,091h,011h,041h,04fh,067h,0dch,0eah
        +DB	097h,0f2h,0cfh,0ceh,0f0h,0b4h,0e6h,073h
        +DB	096h,0ach,074h,022h,0e7h,0adh,035h,085h
        +DB	0e2h,0f9h,037h,0e8h,01ch,075h,0dfh,06eh
        +DB	047h,0f1h,01ah,071h,01dh,029h,0c5h,089h
        +DB	06fh,0b7h,062h,00eh,0aah,018h,0beh,01bh
        +DB	0fch,056h,03eh,04bh,0c6h,0d2h,079h,020h
        +DB	09ah,0dbh,0c0h,0feh,078h,0cdh,05ah,0f4h
        +DB	01fh,0ddh,0a8h,033h,088h,007h,0c7h,031h
        +DB	0b1h,012h,010h,059h,027h,080h,0ech,05fh
        +DB	060h,051h,07fh,0a9h,019h,0b5h,04ah,00dh
        +DB	02dh,0e5h,07ah,09fh,093h,0c9h,09ch,0efh
        +DB	0a0h,0e0h,03bh,04dh,0aeh,02ah,0f5h,0b0h
        +DB	0c8h,0ebh,0bbh,03ch,083h,053h,099h,061h
        +DB	017h,02bh,004h,07eh,0bah,077h,0d6h,026h
        +DB	0e1h,069h,014h,063h,055h,021h,00ch,07dh
        +	DD	080808080h,080808080h,0fefefefeh,0fefefefeh
        +	DD	01b1b1b1bh,01b1b1b1bh,0,0
        +DB	052h,009h,06ah,0d5h,030h,036h,0a5h,038h
        +DB	0bfh,040h,0a3h,09eh,081h,0f3h,0d7h,0fbh
        +DB	07ch,0e3h,039h,082h,09bh,02fh,0ffh,087h
        +DB	034h,08eh,043h,044h,0c4h,0deh,0e9h,0cbh
        +DB	054h,07bh,094h,032h,0a6h,0c2h,023h,03dh
        +DB	0eeh,04ch,095h,00bh,042h,0fah,0c3h,04eh
        +DB	008h,02eh,0a1h,066h,028h,0d9h,024h,0b2h
        +DB	076h,05bh,0a2h,049h,06dh,08bh,0d1h,025h
        +DB	072h,0f8h,0f6h,064h,086h,068h,098h,016h
        +DB	0d4h,0a4h,05ch,0cch,05dh,065h,0b6h,092h
        +DB	06ch,070h,048h,050h,0fdh,0edh,0b9h,0dah
        +DB	05eh,015h,046h,057h,0a7h,08dh,09dh,084h
        +DB	090h,0d8h,0abh,000h,08ch,0bch,0d3h,00ah
        +DB	0f7h,0e4h,058h,005h,0b8h,0b3h,045h,006h
        +DB	0d0h,02ch,01eh,08fh,0cah,03fh,00fh,002h
        +DB	0c1h,0afh,0bdh,003h,001h,013h,08ah,06bh
        +DB	03ah,091h,011h,041h,04fh,067h,0dch,0eah
        +DB	097h,0f2h,0cfh,0ceh,0f0h,0b4h,0e6h,073h
        +DB	096h,0ach,074h,022h,0e7h,0adh,035h,085h
        +DB	0e2h,0f9h,037h,0e8h,01ch,075h,0dfh,06eh
        +DB	047h,0f1h,01ah,071h,01dh,029h,0c5h,089h
        +DB	06fh,0b7h,062h,00eh,0aah,018h,0beh,01bh
        +DB	0fch,056h,03eh,04bh,0c6h,0d2h,079h,020h
        +DB	09ah,0dbh,0c0h,0feh,078h,0cdh,05ah,0f4h
        +DB	01fh,0ddh,0a8h,033h,088h,007h,0c7h,031h
        +DB	0b1h,012h,010h,059h,027h,080h,0ech,05fh
        +DB	060h,051h,07fh,0a9h,019h,0b5h,04ah,00dh
        +DB	02dh,0e5h,07ah,09fh,093h,0c9h,09ch,0efh
        +DB	0a0h,0e0h,03bh,04dh,0aeh,02ah,0f5h,0b0h
        +DB	0c8h,0ebh,0bbh,03ch,083h,053h,099h,061h
        +DB	017h,02bh,004h,07eh,0bah,077h,0d6h,026h
        +DB	0e1h,069h,014h,063h,055h,021h,00ch,07dh
        +	DD	080808080h,080808080h,0fefefefeh,0fefefefeh
        +	DD	01b1b1b1bh,01b1b1b1bh,0,0
        +DB	052h,009h,06ah,0d5h,030h,036h,0a5h,038h
        +DB	0bfh,040h,0a3h,09eh,081h,0f3h,0d7h,0fbh
        +DB	07ch,0e3h,039h,082h,09bh,02fh,0ffh,087h
        +DB	034h,08eh,043h,044h,0c4h,0deh,0e9h,0cbh
        +DB	054h,07bh,094h,032h,0a6h,0c2h,023h,03dh
        +DB	0eeh,04ch,095h,00bh,042h,0fah,0c3h,04eh
        +DB	008h,02eh,0a1h,066h,028h,0d9h,024h,0b2h
        +DB	076h,05bh,0a2h,049h,06dh,08bh,0d1h,025h
        +DB	072h,0f8h,0f6h,064h,086h,068h,098h,016h
        +DB	0d4h,0a4h,05ch,0cch,05dh,065h,0b6h,092h
        +DB	06ch,070h,048h,050h,0fdh,0edh,0b9h,0dah
        +DB	05eh,015h,046h,057h,0a7h,08dh,09dh,084h
        +DB	090h,0d8h,0abh,000h,08ch,0bch,0d3h,00ah
        +DB	0f7h,0e4h,058h,005h,0b8h,0b3h,045h,006h
        +DB	0d0h,02ch,01eh,08fh,0cah,03fh,00fh,002h
        +DB	0c1h,0afh,0bdh,003h,001h,013h,08ah,06bh
        +DB	03ah,091h,011h,041h,04fh,067h,0dch,0eah
        +DB	097h,0f2h,0cfh,0ceh,0f0h,0b4h,0e6h,073h
        +DB	096h,0ach,074h,022h,0e7h,0adh,035h,085h
        +DB	0e2h,0f9h,037h,0e8h,01ch,075h,0dfh,06eh
        +DB	047h,0f1h,01ah,071h,01dh,029h,0c5h,089h
        +DB	06fh,0b7h,062h,00eh,0aah,018h,0beh,01bh
        +DB	0fch,056h,03eh,04bh,0c6h,0d2h,079h,020h
        +DB	09ah,0dbh,0c0h,0feh,078h,0cdh,05ah,0f4h
        +DB	01fh,0ddh,0a8h,033h,088h,007h,0c7h,031h
        +DB	0b1h,012h,010h,059h,027h,080h,0ech,05fh
        +DB	060h,051h,07fh,0a9h,019h,0b5h,04ah,00dh
        +DB	02dh,0e5h,07ah,09fh,093h,0c9h,09ch,0efh
        +DB	0a0h,0e0h,03bh,04dh,0aeh,02ah,0f5h,0b0h
        +DB	0c8h,0ebh,0bbh,03ch,083h,053h,099h,061h
        +DB	017h,02bh,004h,07eh,0bah,077h,0d6h,026h
        +DB	0e1h,069h,014h,063h,055h,021h,00ch,07dh
        +	DD	080808080h,080808080h,0fefefefeh,0fefefefeh
        +	DD	01b1b1b1bh,01b1b1b1bh,0,0
        +DB	052h,009h,06ah,0d5h,030h,036h,0a5h,038h
        +DB	0bfh,040h,0a3h,09eh,081h,0f3h,0d7h,0fbh
        +DB	07ch,0e3h,039h,082h,09bh,02fh,0ffh,087h
        +DB	034h,08eh,043h,044h,0c4h,0deh,0e9h,0cbh
        +DB	054h,07bh,094h,032h,0a6h,0c2h,023h,03dh
        +DB	0eeh,04ch,095h,00bh,042h,0fah,0c3h,04eh
        +DB	008h,02eh,0a1h,066h,028h,0d9h,024h,0b2h
        +DB	076h,05bh,0a2h,049h,06dh,08bh,0d1h,025h
        +DB	072h,0f8h,0f6h,064h,086h,068h,098h,016h
        +DB	0d4h,0a4h,05ch,0cch,05dh,065h,0b6h,092h
        +DB	06ch,070h,048h,050h,0fdh,0edh,0b9h,0dah
        +DB	05eh,015h,046h,057h,0a7h,08dh,09dh,084h
        +DB	090h,0d8h,0abh,000h,08ch,0bch,0d3h,00ah
        +DB	0f7h,0e4h,058h,005h,0b8h,0b3h,045h,006h
        +DB	0d0h,02ch,01eh,08fh,0cah,03fh,00fh,002h
        +DB	0c1h,0afh,0bdh,003h,001h,013h,08ah,06bh
        +DB	03ah,091h,011h,041h,04fh,067h,0dch,0eah
        +DB	097h,0f2h,0cfh,0ceh,0f0h,0b4h,0e6h,073h
        +DB	096h,0ach,074h,022h,0e7h,0adh,035h,085h
        +DB	0e2h,0f9h,037h,0e8h,01ch,075h,0dfh,06eh
        +DB	047h,0f1h,01ah,071h,01dh,029h,0c5h,089h
        +DB	06fh,0b7h,062h,00eh,0aah,018h,0beh,01bh
        +DB	0fch,056h,03eh,04bh,0c6h,0d2h,079h,020h
        +DB	09ah,0dbh,0c0h,0feh,078h,0cdh,05ah,0f4h
        +DB	01fh,0ddh,0a8h,033h,088h,007h,0c7h,031h
        +DB	0b1h,012h,010h,059h,027h,080h,0ech,05fh
        +DB	060h,051h,07fh,0a9h,019h,0b5h,04ah,00dh
        +DB	02dh,0e5h,07ah,09fh,093h,0c9h,09ch,0efh
        +DB	0a0h,0e0h,03bh,04dh,0aeh,02ah,0f5h,0b0h
        +DB	0c8h,0ebh,0bbh,03ch,083h,053h,099h,061h
        +DB	017h,02bh,004h,07eh,0bah,077h,0d6h,026h
        +DB	0e1h,069h,014h,063h,055h,021h,00ch,07dh
        +	DD	080808080h,080808080h,0fefefefeh,0fefefefeh
        +	DD	01b1b1b1bh,01b1b1b1bh,0,0
        +DB	65,69,83,32,102,111,114,32,120,56,54,95,54,52,44,32
        +DB	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +DB	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +DB	62,0
        +ALIGN	64
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +block_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$in_block_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$in_block_prologue
        +
        +	mov	rax,QWORD PTR[24+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_block_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	jmp	$L$common_seh_exit
        +block_se_handler	ENDP
        +
        +
        +ALIGN	16
        +key_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$in_key_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$in_key_prologue
        +
        +	lea	rax,QWORD PTR[56+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_key_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	jmp	$L$common_seh_exit
        +key_se_handler	ENDP
        +
        +
        +ALIGN	16
        +cbc_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$cbc_prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_prologue
        +
        +	lea	r10,QWORD PTR[$L$cbc_fast_body]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_frame_setup
        +
        +	lea	r10,QWORD PTR[$L$cbc_slow_prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_body
        +
        +	lea	r10,QWORD PTR[$L$cbc_slow_body]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_frame_setup
        +
        +$L$in_cbc_body::
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$cbc_epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_cbc_prologue
        +
        +	lea	rax,QWORD PTR[8+rax]
        +
        +	lea	r10,QWORD PTR[$L$cbc_popfq]
        +	cmp	rbx,r10
        +	jae	$L$in_cbc_prologue
        +
        +	mov	rax,QWORD PTR[8+rax]
        +	lea	rax,QWORD PTR[56+rax]
        +
        +$L$in_cbc_frame_setup::
        +	mov	rbx,QWORD PTR[((-16))+rax]
        +	mov	rbp,QWORD PTR[((-24))+rax]
        +	mov	r12,QWORD PTR[((-32))+rax]
        +	mov	r13,QWORD PTR[((-40))+rax]
        +	mov	r14,QWORD PTR[((-48))+rax]
        +	mov	r15,QWORD PTR[((-56))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_cbc_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +$L$common_seh_exit::
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +cbc_se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_AES_encrypt
        +	DD	imagerel $L$SEH_end_AES_encrypt
        +	DD	imagerel $L$SEH_info_AES_encrypt
        +
        +	DD	imagerel $L$SEH_begin_AES_decrypt
        +	DD	imagerel $L$SEH_end_AES_decrypt
        +	DD	imagerel $L$SEH_info_AES_decrypt
        +
        +	DD	imagerel $L$SEH_begin_private_AES_set_encrypt_key
        +	DD	imagerel $L$SEH_end_private_AES_set_encrypt_key
        +	DD	imagerel $L$SEH_info_private_AES_set_encrypt_key
        +
        +	DD	imagerel $L$SEH_begin_private_AES_set_decrypt_key
        +	DD	imagerel $L$SEH_end_private_AES_set_decrypt_key
        +	DD	imagerel $L$SEH_info_private_AES_set_decrypt_key
        +
        +	DD	imagerel $L$SEH_begin_AES_cbc_encrypt
        +	DD	imagerel $L$SEH_end_AES_cbc_encrypt
        +	DD	imagerel $L$SEH_info_AES_cbc_encrypt
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_AES_encrypt::
        +DB	9,0,0,0
        +	DD	imagerel block_se_handler
        +	DD	imagerel $L$enc_prologue,imagerel $L$enc_epilogue
        +
        +$L$SEH_info_AES_decrypt::
        +DB	9,0,0,0
        +	DD	imagerel block_se_handler
        +	DD	imagerel $L$dec_prologue,imagerel $L$dec_epilogue
        +
        +$L$SEH_info_private_AES_set_encrypt_key::
        +DB	9,0,0,0
        +	DD	imagerel key_se_handler
        +	DD	imagerel $L$enc_key_prologue,imagerel $L$enc_key_epilogue
        +
        +$L$SEH_info_private_AES_set_decrypt_key::
        +DB	9,0,0,0
        +	DD	imagerel key_se_handler
        +	DD	imagerel $L$dec_key_prologue,imagerel $L$dec_key_epilogue
        +
        +$L$SEH_info_AES_cbc_encrypt::
        +DB	9,0,0,0
        +	DD	imagerel cbc_se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm
        new file mode 100644
        index 000000000..3f205a16a
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm
        @@ -0,0 +1,1554 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +EXTERN	OPENSSL_ia32cap_P:NEAR
        +
        +PUBLIC	aesni_cbc_sha1_enc
        +
        +ALIGN	16
        +aesni_cbc_sha1_enc	PROC PUBLIC
        +
        +	mov	r10d,DWORD PTR[((OPENSSL_ia32cap_P+0))]
        +	mov	r11d,DWORD PTR[((OPENSSL_ia32cap_P+4))]
        +	jmp	aesni_cbc_sha1_enc_ssse3
        +	DB	0F3h,0C3h		;repret
        +aesni_cbc_sha1_enc	ENDP
        +
        +ALIGN	16
        +aesni_cbc_sha1_enc_ssse3	PROC PRIVATE
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_cbc_sha1_enc_ssse3::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	mov	r10,QWORD PTR[56+rsp]
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	lea	rsp,QWORD PTR[((-264))+rsp]
        +
        +
        +	movaps	XMMWORD PTR[(96+0)+rsp],xmm6
        +	movaps	XMMWORD PTR[(96+16)+rsp],xmm7
        +	movaps	XMMWORD PTR[(96+32)+rsp],xmm8
        +	movaps	XMMWORD PTR[(96+48)+rsp],xmm9
        +	movaps	XMMWORD PTR[(96+64)+rsp],xmm10
        +	movaps	XMMWORD PTR[(96+80)+rsp],xmm11
        +	movaps	XMMWORD PTR[(96+96)+rsp],xmm12
        +	movaps	XMMWORD PTR[(96+112)+rsp],xmm13
        +	movaps	XMMWORD PTR[(96+128)+rsp],xmm14
        +	movaps	XMMWORD PTR[(96+144)+rsp],xmm15
        +$L$prologue_ssse3::
        +	mov	r12,rdi
        +	mov	r13,rsi
        +	mov	r14,rdx
        +	mov	r15,rcx
        +	movdqu	xmm11,XMMWORD PTR[r8]
        +	mov	QWORD PTR[88+rsp],r8
        +	shl	r14,6
        +	sub	r13,r12
        +	mov	r8d,DWORD PTR[240+r15]
        +	add	r14,r10
        +
        +	lea	r11,QWORD PTR[K_XX_XX]
        +	mov	eax,DWORD PTR[r9]
        +	mov	ebx,DWORD PTR[4+r9]
        +	mov	ecx,DWORD PTR[8+r9]
        +	mov	edx,DWORD PTR[12+r9]
        +	mov	esi,ebx
        +	mov	ebp,DWORD PTR[16+r9]
        +
        +	movdqa	xmm6,XMMWORD PTR[64+r11]
        +	movdqa	xmm9,XMMWORD PTR[r11]
        +	movdqu	xmm0,XMMWORD PTR[r10]
        +	movdqu	xmm1,XMMWORD PTR[16+r10]
        +	movdqu	xmm2,XMMWORD PTR[32+r10]
        +	movdqu	xmm3,XMMWORD PTR[48+r10]
        +DB	102,15,56,0,198
        +	add	r10,64
        +DB	102,15,56,0,206
        +DB	102,15,56,0,214
        +DB	102,15,56,0,222
        +	paddd	xmm0,xmm9
        +	paddd	xmm1,xmm9
        +	paddd	xmm2,xmm9
        +	movdqa	XMMWORD PTR[rsp],xmm0
        +	psubd	xmm0,xmm9
        +	movdqa	XMMWORD PTR[16+rsp],xmm1
        +	psubd	xmm1,xmm9
        +	movdqa	XMMWORD PTR[32+rsp],xmm2
        +	psubd	xmm2,xmm9
        +	movups	xmm13,XMMWORD PTR[r15]
        +	movups	xmm14,XMMWORD PTR[16+r15]
        +	jmp	$L$oop_ssse3
        +ALIGN	16
        +$L$oop_ssse3::
        +	movdqa	xmm4,xmm1
        +	add	ebp,DWORD PTR[rsp]
        +	movups	xmm12,XMMWORD PTR[r12]
        +	xorps	xmm12,xmm13
        +	xorps	xmm11,xmm12
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[32+r15]
        +	xor	ecx,edx
        +	movdqa	xmm8,xmm3
        +DB	102,15,58,15,224,8
        +	mov	edi,eax
        +	rol	eax,5
        +	paddd	xmm9,xmm3
        +	and	esi,ecx
        +	xor	ecx,edx
        +	psrldq	xmm8,4
        +	xor	esi,edx
        +	add	ebp,eax
        +	pxor	xmm4,xmm0
        +	ror	ebx,2
        +	add	ebp,esi
        +	pxor	xmm8,xmm2
        +	add	edx,DWORD PTR[4+rsp]
        +	xor	ebx,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	pxor	xmm4,xmm8
        +	and	edi,ebx
        +	xor	ebx,ecx
        +	movdqa	XMMWORD PTR[48+rsp],xmm9
        +	xor	edi,ecx
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[48+r15]
        +	add	edx,ebp
        +	movdqa	xmm10,xmm4
        +	movdqa	xmm8,xmm4
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[8+rsp]
        +	xor	eax,ebx
        +	pslldq	xmm10,12
        +	paddd	xmm4,xmm4
        +	mov	edi,edx
        +	rol	edx,5
        +	and	esi,eax
        +	xor	eax,ebx
        +	psrld	xmm8,31
        +	xor	esi,ebx
        +	add	ecx,edx
        +	movdqa	xmm9,xmm10
        +	ror	ebp,7
        +	add	ecx,esi
        +	psrld	xmm10,30
        +	por	xmm4,xmm8
        +	add	ebx,DWORD PTR[12+rsp]
        +	xor	ebp,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[64+r15]
        +	pslld	xmm9,2
        +	pxor	xmm4,xmm10
        +	and	edi,ebp
        +	xor	ebp,eax
        +	movdqa	xmm10,XMMWORD PTR[r11]
        +	xor	edi,eax
        +	add	ebx,ecx
        +	pxor	xmm4,xmm9
        +	ror	edx,7
        +	add	ebx,edi
        +	movdqa	xmm5,xmm2
        +	add	eax,DWORD PTR[16+rsp]
        +	xor	edx,ebp
        +	movdqa	xmm9,xmm4
        +DB	102,15,58,15,233,8
        +	mov	edi,ebx
        +	rol	ebx,5
        +	paddd	xmm10,xmm4
        +	and	esi,edx
        +	xor	edx,ebp
        +	psrldq	xmm9,4
        +	xor	esi,ebp
        +	add	eax,ebx
        +	pxor	xmm5,xmm1
        +	ror	ecx,7
        +	add	eax,esi
        +	pxor	xmm9,xmm3
        +	add	ebp,DWORD PTR[20+rsp]
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[80+r15]
        +	xor	ecx,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	pxor	xmm5,xmm9
        +	and	edi,ecx
        +	xor	ecx,edx
        +	movdqa	XMMWORD PTR[rsp],xmm10
        +	xor	edi,edx
        +	add	ebp,eax
        +	movdqa	xmm8,xmm5
        +	movdqa	xmm9,xmm5
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[24+rsp]
        +	xor	ebx,ecx
        +	pslldq	xmm8,12
        +	paddd	xmm5,xmm5
        +	mov	edi,ebp
        +	rol	ebp,5
        +	and	esi,ebx
        +	xor	ebx,ecx
        +	psrld	xmm9,31
        +	xor	esi,ecx
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[96+r15]
        +	add	edx,ebp
        +	movdqa	xmm10,xmm8
        +	ror	eax,7
        +	add	edx,esi
        +	psrld	xmm8,30
        +	por	xmm5,xmm9
        +	add	ecx,DWORD PTR[28+rsp]
        +	xor	eax,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	pslld	xmm10,2
        +	pxor	xmm5,xmm8
        +	and	edi,eax
        +	xor	eax,ebx
        +	movdqa	xmm8,XMMWORD PTR[16+r11]
        +	xor	edi,ebx
        +	add	ecx,edx
        +	pxor	xmm5,xmm10
        +	ror	ebp,7
        +	add	ecx,edi
        +	movdqa	xmm6,xmm3
        +	add	ebx,DWORD PTR[32+rsp]
        +	xor	ebp,eax
        +	movdqa	xmm10,xmm5
        +DB	102,15,58,15,242,8
        +	mov	edi,ecx
        +	rol	ecx,5
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[112+r15]
        +	paddd	xmm8,xmm5
        +	and	esi,ebp
        +	xor	ebp,eax
        +	psrldq	xmm10,4
        +	xor	esi,eax
        +	add	ebx,ecx
        +	pxor	xmm6,xmm2
        +	ror	edx,7
        +	add	ebx,esi
        +	pxor	xmm10,xmm4
        +	add	eax,DWORD PTR[36+rsp]
        +	xor	edx,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	pxor	xmm6,xmm10
        +	and	edi,edx
        +	xor	edx,ebp
        +	movdqa	XMMWORD PTR[16+rsp],xmm8
        +	xor	edi,ebp
        +	add	eax,ebx
        +	movdqa	xmm9,xmm6
        +	movdqa	xmm10,xmm6
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[40+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[128+r15]
        +	xor	ecx,edx
        +	pslldq	xmm9,12
        +	paddd	xmm6,xmm6
        +	mov	edi,eax
        +	rol	eax,5
        +	and	esi,ecx
        +	xor	ecx,edx
        +	psrld	xmm10,31
        +	xor	esi,edx
        +	add	ebp,eax
        +	movdqa	xmm8,xmm9
        +	ror	ebx,7
        +	add	ebp,esi
        +	psrld	xmm9,30
        +	por	xmm6,xmm10
        +	add	edx,DWORD PTR[44+rsp]
        +	xor	ebx,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	pslld	xmm8,2
        +	pxor	xmm6,xmm9
        +	and	edi,ebx
        +	xor	ebx,ecx
        +	movdqa	xmm9,XMMWORD PTR[16+r11]
        +	xor	edi,ecx
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[144+r15]
        +	add	edx,ebp
        +	pxor	xmm6,xmm8
        +	ror	eax,7
        +	add	edx,edi
        +	movdqa	xmm7,xmm4
        +	add	ecx,DWORD PTR[48+rsp]
        +	xor	eax,ebx
        +	movdqa	xmm8,xmm6
        +DB	102,15,58,15,251,8
        +	mov	edi,edx
        +	rol	edx,5
        +	paddd	xmm9,xmm6
        +	and	esi,eax
        +	xor	eax,ebx
        +	psrldq	xmm8,4
        +	xor	esi,ebx
        +	add	ecx,edx
        +	pxor	xmm7,xmm3
        +	ror	ebp,7
        +	add	ecx,esi
        +	pxor	xmm8,xmm5
        +	add	ebx,DWORD PTR[52+rsp]
        +	xor	ebp,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[160+r15]
        +	pxor	xmm7,xmm8
        +	and	edi,ebp
        +	xor	ebp,eax
        +	movdqa	XMMWORD PTR[32+rsp],xmm9
        +	xor	edi,eax
        +	add	ebx,ecx
        +	movdqa	xmm10,xmm7
        +	movdqa	xmm8,xmm7
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[56+rsp]
        +	xor	edx,ebp
        +	pslldq	xmm10,12
        +	paddd	xmm7,xmm7
        +	mov	edi,ebx
        +	rol	ebx,5
        +	and	esi,edx
        +	xor	edx,ebp
        +	psrld	xmm8,31
        +	xor	esi,ebp
        +	add	eax,ebx
        +	movdqa	xmm9,xmm10
        +	ror	ecx,7
        +	add	eax,esi
        +	psrld	xmm10,30
        +	por	xmm7,xmm8
        +	add	ebp,DWORD PTR[60+rsp]
        +	cmp	r8d,11
        +	jb	$L$aesenclast1
        +	movups	xmm14,XMMWORD PTR[176+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[192+r15]
        +DB	102,69,15,56,220,222
        +	je	$L$aesenclast1
        +	movups	xmm14,XMMWORD PTR[208+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[224+r15]
        +DB	102,69,15,56,220,222
        +$L$aesenclast1::
        +DB	102,69,15,56,221,223
        +	movups	xmm14,XMMWORD PTR[16+r15]
        +	xor	ecx,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	pslld	xmm9,2
        +	pxor	xmm7,xmm10
        +	and	edi,ecx
        +	xor	ecx,edx
        +	movdqa	xmm10,XMMWORD PTR[16+r11]
        +	xor	edi,edx
        +	add	ebp,eax
        +	pxor	xmm7,xmm9
        +	ror	ebx,7
        +	add	ebp,edi
        +	movdqa	xmm9,xmm7
        +	add	edx,DWORD PTR[rsp]
        +	pxor	xmm0,xmm4
        +DB	102,68,15,58,15,206,8
        +	xor	ebx,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	pxor	xmm0,xmm1
        +	and	esi,ebx
        +	xor	ebx,ecx
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm7
        +	xor	esi,ecx
        +	movups	xmm12,XMMWORD PTR[16+r12]
        +	xorps	xmm12,xmm13
        +	movups	XMMWORD PTR[r12*1+r13],xmm11
        +	xorps	xmm11,xmm12
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[32+r15]
        +	add	edx,ebp
        +	pxor	xmm0,xmm9
        +	ror	eax,7
        +	add	edx,esi
        +	add	ecx,DWORD PTR[4+rsp]
        +	xor	eax,ebx
        +	movdqa	xmm9,xmm0
        +	movdqa	XMMWORD PTR[48+rsp],xmm10
        +	mov	esi,edx
        +	rol	edx,5
        +	and	edi,eax
        +	xor	eax,ebx
        +	pslld	xmm0,2
        +	xor	edi,ebx
        +	add	ecx,edx
        +	psrld	xmm9,30
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[8+rsp]
        +	xor	ebp,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[48+r15]
        +	por	xmm0,xmm9
        +	and	esi,ebp
        +	xor	ebp,eax
        +	movdqa	xmm10,xmm0
        +	xor	esi,eax
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[12+rsp]
        +	xor	edx,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	and	edi,edx
        +	xor	edx,ebp
        +	xor	edi,ebp
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[16+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[64+r15]
        +	pxor	xmm1,xmm5
        +DB	102,68,15,58,15,215,8
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	pxor	xmm1,xmm2
        +	xor	esi,ecx
        +	add	ebp,eax
        +	movdqa	xmm9,xmm8
        +	paddd	xmm8,xmm0
        +	ror	ebx,7
        +	add	ebp,esi
        +	pxor	xmm1,xmm10
        +	add	edx,DWORD PTR[20+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	movdqa	xmm10,xmm1
        +	movdqa	XMMWORD PTR[rsp],xmm8
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	pslld	xmm1,2
        +	add	ecx,DWORD PTR[24+rsp]
        +	xor	esi,ebx
        +	psrld	xmm10,30
        +	mov	edi,edx
        +	rol	edx,5
        +	xor	esi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[80+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	por	xmm1,xmm10
        +	add	ebx,DWORD PTR[28+rsp]
        +	xor	edi,eax
        +	movdqa	xmm8,xmm1
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[32+rsp]
        +	pxor	xmm2,xmm6
        +DB	102,68,15,58,15,192,8
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	pxor	xmm2,xmm3
        +	xor	esi,edx
        +	add	eax,ebx
        +	movdqa	xmm10,XMMWORD PTR[32+r11]
        +	paddd	xmm9,xmm1
        +	ror	ecx,7
        +	add	eax,esi
        +	pxor	xmm2,xmm8
        +	add	ebp,DWORD PTR[36+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[96+r15]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	movdqa	xmm8,xmm2
        +	movdqa	XMMWORD PTR[16+rsp],xmm9
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	pslld	xmm2,2
        +	add	edx,DWORD PTR[40+rsp]
        +	xor	esi,ecx
        +	psrld	xmm8,30
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	por	xmm2,xmm8
        +	add	ecx,DWORD PTR[44+rsp]
        +	xor	edi,ebx
        +	movdqa	xmm9,xmm2
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[112+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[48+rsp]
        +	pxor	xmm3,xmm7
        +DB	102,68,15,58,15,201,8
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	pxor	xmm3,xmm4
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm2
        +	ror	edx,7
        +	add	ebx,esi
        +	pxor	xmm3,xmm9
        +	add	eax,DWORD PTR[52+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	movdqa	xmm9,xmm3
        +	movdqa	XMMWORD PTR[32+rsp],xmm10
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	pslld	xmm3,2
        +	add	ebp,DWORD PTR[56+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[128+r15]
        +	xor	esi,edx
        +	psrld	xmm9,30
        +	mov	edi,eax
        +	rol	eax,5
        +	xor	esi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,esi
        +	por	xmm3,xmm9
        +	add	edx,DWORD PTR[60+rsp]
        +	xor	edi,ecx
        +	movdqa	xmm10,xmm3
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[rsp]
        +	pxor	xmm4,xmm0
        +DB	102,68,15,58,15,210,8
        +	xor	esi,ebx
        +	mov	edi,edx
        +	rol	edx,5
        +	pxor	xmm4,xmm5
        +	xor	esi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[144+r15]
        +	add	ecx,edx
        +	movdqa	xmm9,xmm8
        +	paddd	xmm8,xmm3
        +	ror	ebp,7
        +	add	ecx,esi
        +	pxor	xmm4,xmm10
        +	add	ebx,DWORD PTR[4+rsp]
        +	xor	edi,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	movdqa	xmm10,xmm4
        +	movdqa	XMMWORD PTR[48+rsp],xmm8
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	pslld	xmm4,2
        +	add	eax,DWORD PTR[8+rsp]
        +	xor	esi,ebp
        +	psrld	xmm10,30
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	por	xmm4,xmm10
        +	add	ebp,DWORD PTR[12+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[160+r15]
        +	xor	edi,edx
        +	movdqa	xmm8,xmm4
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[16+rsp]
        +	pxor	xmm5,xmm1
        +DB	102,68,15,58,15,195,8
        +	xor	esi,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	pxor	xmm5,xmm6
        +	xor	esi,ebx
        +	add	edx,ebp
        +	movdqa	xmm10,xmm9
        +	paddd	xmm9,xmm4
        +	ror	eax,7
        +	add	edx,esi
        +	pxor	xmm5,xmm8
        +	add	ecx,DWORD PTR[20+rsp]
        +	xor	edi,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	movdqa	xmm8,xmm5
        +	movdqa	XMMWORD PTR[rsp],xmm9
        +	xor	edi,eax
        +	cmp	r8d,11
        +	jb	$L$aesenclast2
        +	movups	xmm14,XMMWORD PTR[176+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[192+r15]
        +DB	102,69,15,56,220,222
        +	je	$L$aesenclast2
        +	movups	xmm14,XMMWORD PTR[208+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[224+r15]
        +DB	102,69,15,56,220,222
        +$L$aesenclast2::
        +DB	102,69,15,56,221,223
        +	movups	xmm14,XMMWORD PTR[16+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	pslld	xmm5,2
        +	add	ebx,DWORD PTR[24+rsp]
        +	xor	esi,eax
        +	psrld	xmm8,30
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	por	xmm5,xmm8
        +	add	eax,DWORD PTR[28+rsp]
        +	xor	edi,ebp
        +	movdqa	xmm9,xmm5
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	mov	edi,ecx
        +	movups	xmm12,XMMWORD PTR[32+r12]
        +	xorps	xmm12,xmm13
        +	movups	XMMWORD PTR[16+r12*1+r13],xmm11
        +	xorps	xmm11,xmm12
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[32+r15]
        +	pxor	xmm6,xmm2
        +DB	102,68,15,58,15,204,8
        +	xor	ecx,edx
        +	add	ebp,DWORD PTR[32+rsp]
        +	and	edi,edx
        +	pxor	xmm6,xmm7
        +	and	esi,ecx
        +	ror	ebx,7
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm5
        +	add	ebp,edi
        +	mov	edi,eax
        +	pxor	xmm6,xmm9
        +	rol	eax,5
        +	add	ebp,esi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	movdqa	xmm9,xmm6
        +	movdqa	XMMWORD PTR[16+rsp],xmm10
        +	mov	esi,ebx
        +	xor	ebx,ecx
        +	add	edx,DWORD PTR[36+rsp]
        +	and	esi,ecx
        +	pslld	xmm6,2
        +	and	edi,ebx
        +	ror	eax,7
        +	psrld	xmm9,30
        +	add	edx,esi
        +	mov	esi,ebp
        +	rol	ebp,5
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[48+r15]
        +	add	edx,edi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	por	xmm6,xmm9
        +	mov	edi,eax
        +	xor	eax,ebx
        +	movdqa	xmm10,xmm6
        +	add	ecx,DWORD PTR[40+rsp]
        +	and	edi,ebx
        +	and	esi,eax
        +	ror	ebp,7
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	edx,5
        +	add	ecx,esi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	mov	esi,ebp
        +	xor	ebp,eax
        +	add	ebx,DWORD PTR[44+rsp]
        +	and	esi,eax
        +	and	edi,ebp
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[64+r15]
        +	ror	edx,7
        +	add	ebx,esi
        +	mov	esi,ecx
        +	rol	ecx,5
        +	add	ebx,edi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	mov	edi,edx
        +	pxor	xmm7,xmm3
        +DB	102,68,15,58,15,213,8
        +	xor	edx,ebp
        +	add	eax,DWORD PTR[48+rsp]
        +	and	edi,ebp
        +	pxor	xmm7,xmm0
        +	and	esi,edx
        +	ror	ecx,7
        +	movdqa	xmm9,XMMWORD PTR[48+r11]
        +	paddd	xmm8,xmm6
        +	add	eax,edi
        +	mov	edi,ebx
        +	pxor	xmm7,xmm10
        +	rol	ebx,5
        +	add	eax,esi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	movdqa	xmm10,xmm7
        +	movdqa	XMMWORD PTR[32+rsp],xmm8
        +	mov	esi,ecx
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[80+r15]
        +	xor	ecx,edx
        +	add	ebp,DWORD PTR[52+rsp]
        +	and	esi,edx
        +	pslld	xmm7,2
        +	and	edi,ecx
        +	ror	ebx,7
        +	psrld	xmm10,30
        +	add	ebp,esi
        +	mov	esi,eax
        +	rol	eax,5
        +	add	ebp,edi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	por	xmm7,xmm10
        +	mov	edi,ebx
        +	xor	ebx,ecx
        +	movdqa	xmm8,xmm7
        +	add	edx,DWORD PTR[56+rsp]
        +	and	edi,ecx
        +	and	esi,ebx
        +	ror	eax,7
        +	add	edx,edi
        +	mov	edi,ebp
        +	rol	ebp,5
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[96+r15]
        +	add	edx,esi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	mov	esi,eax
        +	xor	eax,ebx
        +	add	ecx,DWORD PTR[60+rsp]
        +	and	esi,ebx
        +	and	edi,eax
        +	ror	ebp,7
        +	add	ecx,esi
        +	mov	esi,edx
        +	rol	edx,5
        +	add	ecx,edi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	mov	edi,ebp
        +	pxor	xmm0,xmm4
        +DB	102,68,15,58,15,198,8
        +	xor	ebp,eax
        +	add	ebx,DWORD PTR[rsp]
        +	and	edi,eax
        +	pxor	xmm0,xmm1
        +	and	esi,ebp
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[112+r15]
        +	ror	edx,7
        +	movdqa	xmm10,xmm9
        +	paddd	xmm9,xmm7
        +	add	ebx,edi
        +	mov	edi,ecx
        +	pxor	xmm0,xmm8
        +	rol	ecx,5
        +	add	ebx,esi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	movdqa	xmm8,xmm0
        +	movdqa	XMMWORD PTR[48+rsp],xmm9
        +	mov	esi,edx
        +	xor	edx,ebp
        +	add	eax,DWORD PTR[4+rsp]
        +	and	esi,ebp
        +	pslld	xmm0,2
        +	and	edi,edx
        +	ror	ecx,7
        +	psrld	xmm8,30
        +	add	eax,esi
        +	mov	esi,ebx
        +	rol	ebx,5
        +	add	eax,edi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	por	xmm0,xmm8
        +	mov	edi,ecx
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[128+r15]
        +	xor	ecx,edx
        +	movdqa	xmm9,xmm0
        +	add	ebp,DWORD PTR[8+rsp]
        +	and	edi,edx
        +	and	esi,ecx
        +	ror	ebx,7
        +	add	ebp,edi
        +	mov	edi,eax
        +	rol	eax,5
        +	add	ebp,esi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	mov	esi,ebx
        +	xor	ebx,ecx
        +	add	edx,DWORD PTR[12+rsp]
        +	and	esi,ecx
        +	and	edi,ebx
        +	ror	eax,7
        +	add	edx,esi
        +	mov	esi,ebp
        +	rol	ebp,5
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[144+r15]
        +	add	edx,edi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	mov	edi,eax
        +	pxor	xmm1,xmm5
        +DB	102,68,15,58,15,207,8
        +	xor	eax,ebx
        +	add	ecx,DWORD PTR[16+rsp]
        +	and	edi,ebx
        +	pxor	xmm1,xmm2
        +	and	esi,eax
        +	ror	ebp,7
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm0
        +	add	ecx,edi
        +	mov	edi,edx
        +	pxor	xmm1,xmm9
        +	rol	edx,5
        +	add	ecx,esi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	movdqa	xmm9,xmm1
        +	movdqa	XMMWORD PTR[rsp],xmm10
        +	mov	esi,ebp
        +	xor	ebp,eax
        +	add	ebx,DWORD PTR[20+rsp]
        +	and	esi,eax
        +	pslld	xmm1,2
        +	and	edi,ebp
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[160+r15]
        +	ror	edx,7
        +	psrld	xmm9,30
        +	add	ebx,esi
        +	mov	esi,ecx
        +	rol	ecx,5
        +	add	ebx,edi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	por	xmm1,xmm9
        +	mov	edi,edx
        +	xor	edx,ebp
        +	movdqa	xmm10,xmm1
        +	add	eax,DWORD PTR[24+rsp]
        +	and	edi,ebp
        +	and	esi,edx
        +	ror	ecx,7
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	ebx,5
        +	add	eax,esi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	mov	esi,ecx
        +	cmp	r8d,11
        +	jb	$L$aesenclast3
        +	movups	xmm14,XMMWORD PTR[176+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[192+r15]
        +DB	102,69,15,56,220,222
        +	je	$L$aesenclast3
        +	movups	xmm14,XMMWORD PTR[208+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[224+r15]
        +DB	102,69,15,56,220,222
        +$L$aesenclast3::
        +DB	102,69,15,56,221,223
        +	movups	xmm14,XMMWORD PTR[16+r15]
        +	xor	ecx,edx
        +	add	ebp,DWORD PTR[28+rsp]
        +	and	esi,edx
        +	and	edi,ecx
        +	ror	ebx,7
        +	add	ebp,esi
        +	mov	esi,eax
        +	rol	eax,5
        +	add	ebp,edi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	mov	edi,ebx
        +	pxor	xmm2,xmm6
        +DB	102,68,15,58,15,208,8
        +	xor	ebx,ecx
        +	add	edx,DWORD PTR[32+rsp]
        +	and	edi,ecx
        +	pxor	xmm2,xmm3
        +	and	esi,ebx
        +	ror	eax,7
        +	movdqa	xmm9,xmm8
        +	paddd	xmm8,xmm1
        +	add	edx,edi
        +	mov	edi,ebp
        +	pxor	xmm2,xmm10
        +	rol	ebp,5
        +	movups	xmm12,XMMWORD PTR[48+r12]
        +	xorps	xmm12,xmm13
        +	movups	XMMWORD PTR[32+r12*1+r13],xmm11
        +	xorps	xmm11,xmm12
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[32+r15]
        +	add	edx,esi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	movdqa	xmm10,xmm2
        +	movdqa	XMMWORD PTR[16+rsp],xmm8
        +	mov	esi,eax
        +	xor	eax,ebx
        +	add	ecx,DWORD PTR[36+rsp]
        +	and	esi,ebx
        +	pslld	xmm2,2
        +	and	edi,eax
        +	ror	ebp,7
        +	psrld	xmm10,30
        +	add	ecx,esi
        +	mov	esi,edx
        +	rol	edx,5
        +	add	ecx,edi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	por	xmm2,xmm10
        +	mov	edi,ebp
        +	xor	ebp,eax
        +	movdqa	xmm8,xmm2
        +	add	ebx,DWORD PTR[40+rsp]
        +	and	edi,eax
        +	and	esi,ebp
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[48+r15]
        +	ror	edx,7
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ecx,5
        +	add	ebx,esi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	mov	esi,edx
        +	xor	edx,ebp
        +	add	eax,DWORD PTR[44+rsp]
        +	and	esi,ebp
        +	and	edi,edx
        +	ror	ecx,7
        +	add	eax,esi
        +	mov	esi,ebx
        +	rol	ebx,5
        +	add	eax,edi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	add	ebp,DWORD PTR[48+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[64+r15]
        +	pxor	xmm3,xmm7
        +DB	102,68,15,58,15,193,8
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	pxor	xmm3,xmm4
        +	xor	esi,ecx
        +	add	ebp,eax
        +	movdqa	xmm10,xmm9
        +	paddd	xmm9,xmm2
        +	ror	ebx,7
        +	add	ebp,esi
        +	pxor	xmm3,xmm8
        +	add	edx,DWORD PTR[52+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	movdqa	xmm8,xmm3
        +	movdqa	XMMWORD PTR[32+rsp],xmm9
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	pslld	xmm3,2
        +	add	ecx,DWORD PTR[56+rsp]
        +	xor	esi,ebx
        +	psrld	xmm8,30
        +	mov	edi,edx
        +	rol	edx,5
        +	xor	esi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[80+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	por	xmm3,xmm8
        +	add	ebx,DWORD PTR[60+rsp]
        +	xor	edi,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[rsp]
        +	paddd	xmm10,xmm3
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	movdqa	XMMWORD PTR[48+rsp],xmm10
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	add	ebp,DWORD PTR[4+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[96+r15]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[8+rsp]
        +	xor	esi,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	add	ecx,DWORD PTR[12+rsp]
        +	xor	edi,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[112+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	cmp	r10,r14
        +	je	$L$done_ssse3
        +	movdqa	xmm6,XMMWORD PTR[64+r11]
        +	movdqa	xmm9,XMMWORD PTR[r11]
        +	movdqu	xmm0,XMMWORD PTR[r10]
        +	movdqu	xmm1,XMMWORD PTR[16+r10]
        +	movdqu	xmm2,XMMWORD PTR[32+r10]
        +	movdqu	xmm3,XMMWORD PTR[48+r10]
        +DB	102,15,56,0,198
        +	add	r10,64
        +	add	ebx,DWORD PTR[16+rsp]
        +	xor	esi,eax
        +DB	102,15,56,0,206
        +	mov	edi,ecx
        +	rol	ecx,5
        +	paddd	xmm0,xmm9
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	movdqa	XMMWORD PTR[rsp],xmm0
        +	add	eax,DWORD PTR[20+rsp]
        +	xor	edi,ebp
        +	psubd	xmm0,xmm9
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[24+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[128+r15]
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	xor	esi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,esi
        +	add	edx,DWORD PTR[28+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[32+rsp]
        +	xor	esi,ebx
        +DB	102,15,56,0,214
        +	mov	edi,edx
        +	rol	edx,5
        +	paddd	xmm1,xmm9
        +	xor	esi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[144+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	movdqa	XMMWORD PTR[16+rsp],xmm1
        +	add	ebx,DWORD PTR[36+rsp]
        +	xor	edi,eax
        +	psubd	xmm1,xmm9
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[40+rsp]
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	add	ebp,DWORD PTR[44+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[160+r15]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[48+rsp]
        +	xor	esi,ecx
        +DB	102,15,56,0,222
        +	mov	edi,ebp
        +	rol	ebp,5
        +	paddd	xmm2,xmm9
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	movdqa	XMMWORD PTR[32+rsp],xmm2
        +	add	ecx,DWORD PTR[52+rsp]
        +	xor	edi,ebx
        +	psubd	xmm2,xmm9
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +	cmp	r8d,11
        +	jb	$L$aesenclast4
        +	movups	xmm14,XMMWORD PTR[176+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[192+r15]
        +DB	102,69,15,56,220,222
        +	je	$L$aesenclast4
        +	movups	xmm14,XMMWORD PTR[208+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[224+r15]
        +DB	102,69,15,56,220,222
        +$L$aesenclast4::
        +DB	102,69,15,56,221,223
        +	movups	xmm14,XMMWORD PTR[16+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[56+rsp]
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[60+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	movups	XMMWORD PTR[48+r12*1+r13],xmm11
        +	lea	r12,QWORD PTR[64+r12]
        +
        +	add	eax,DWORD PTR[r9]
        +	add	esi,DWORD PTR[4+r9]
        +	add	ecx,DWORD PTR[8+r9]
        +	add	edx,DWORD PTR[12+r9]
        +	mov	DWORD PTR[r9],eax
        +	add	ebp,DWORD PTR[16+r9]
        +	mov	DWORD PTR[4+r9],esi
        +	mov	ebx,esi
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +	mov	DWORD PTR[16+r9],ebp
        +	jmp	$L$oop_ssse3
        +
        +ALIGN	16
        +$L$done_ssse3::
        +	add	ebx,DWORD PTR[16+rsp]
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[20+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[24+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[128+r15]
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	xor	esi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,esi
        +	add	edx,DWORD PTR[28+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[32+rsp]
        +	xor	esi,ebx
        +	mov	edi,edx
        +	rol	edx,5
        +	xor	esi,eax
        +DB	102,69,15,56,220,223
        +	movups	xmm14,XMMWORD PTR[144+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	add	ebx,DWORD PTR[36+rsp]
        +	xor	edi,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[40+rsp]
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	add	ebp,DWORD PTR[44+rsp]
        +DB	102,69,15,56,220,222
        +	movups	xmm15,XMMWORD PTR[160+r15]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[48+rsp]
        +	xor	esi,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	add	ecx,DWORD PTR[52+rsp]
        +	xor	edi,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +	cmp	r8d,11
        +	jb	$L$aesenclast5
        +	movups	xmm14,XMMWORD PTR[176+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[192+r15]
        +DB	102,69,15,56,220,222
        +	je	$L$aesenclast5
        +	movups	xmm14,XMMWORD PTR[208+r15]
        +DB	102,69,15,56,220,223
        +	movups	xmm15,XMMWORD PTR[224+r15]
        +DB	102,69,15,56,220,222
        +$L$aesenclast5::
        +DB	102,69,15,56,221,223
        +	movups	xmm14,XMMWORD PTR[16+r15]
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[56+rsp]
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[60+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	movups	XMMWORD PTR[48+r12*1+r13],xmm11
        +	mov	r8,QWORD PTR[88+rsp]
        +
        +	add	eax,DWORD PTR[r9]
        +	add	esi,DWORD PTR[4+r9]
        +	add	ecx,DWORD PTR[8+r9]
        +	mov	DWORD PTR[r9],eax
        +	add	edx,DWORD PTR[12+r9]
        +	mov	DWORD PTR[4+r9],esi
        +	add	ebp,DWORD PTR[16+r9]
        +	mov	DWORD PTR[8+r9],ecx
        +	mov	DWORD PTR[12+r9],edx
        +	mov	DWORD PTR[16+r9],ebp
        +	movups	XMMWORD PTR[r8],xmm11
        +	movaps	xmm6,XMMWORD PTR[((96+0))+rsp]
        +	movaps	xmm7,XMMWORD PTR[((96+16))+rsp]
        +	movaps	xmm8,XMMWORD PTR[((96+32))+rsp]
        +	movaps	xmm9,XMMWORD PTR[((96+48))+rsp]
        +	movaps	xmm10,XMMWORD PTR[((96+64))+rsp]
        +	movaps	xmm11,XMMWORD PTR[((96+80))+rsp]
        +	movaps	xmm12,XMMWORD PTR[((96+96))+rsp]
        +	movaps	xmm13,XMMWORD PTR[((96+112))+rsp]
        +	movaps	xmm14,XMMWORD PTR[((96+128))+rsp]
        +	movaps	xmm15,XMMWORD PTR[((96+144))+rsp]
        +	lea	rsi,QWORD PTR[264+rsp]
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$epilogue_ssse3::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_cbc_sha1_enc_ssse3::
        +aesni_cbc_sha1_enc_ssse3	ENDP
        +ALIGN	64
        +K_XX_XX::
        +	DD	05a827999h,05a827999h,05a827999h,05a827999h
        +
        +	DD	06ed9eba1h,06ed9eba1h,06ed9eba1h,06ed9eba1h
        +
        +	DD	08f1bbcdch,08f1bbcdch,08f1bbcdch,08f1bbcdch
        +
        +	DD	0ca62c1d6h,0ca62c1d6h,0ca62c1d6h,0ca62c1d6h
        +
        +	DD	000010203h,004050607h,008090a0bh,00c0d0e0fh
        +
        +
        +DB	65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115
        +DB	116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52
        +DB	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
        +DB	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
        +DB	114,103,62,0
        +ALIGN	64
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +ssse3_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	lea	rsi,QWORD PTR[96+rax]
        +	lea	rdi,QWORD PTR[512+r8]
        +	mov	ecx,20
        +	DD	0a548f3fch
        +
        +	lea	rax,QWORD PTR[264+rax]
        +
        +	mov	r15,QWORD PTR[rax]
        +	mov	r14,QWORD PTR[8+rax]
        +	mov	r13,QWORD PTR[16+rax]
        +	mov	r12,QWORD PTR[24+rax]
        +	mov	rbp,QWORD PTR[32+rax]
        +	mov	rbx,QWORD PTR[40+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$common_seh_tail::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +ssse3_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_aesni_cbc_sha1_enc_ssse3
        +	DD	imagerel $L$SEH_end_aesni_cbc_sha1_enc_ssse3
        +	DD	imagerel $L$SEH_info_aesni_cbc_sha1_enc_ssse3
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_aesni_cbc_sha1_enc_ssse3::
        +DB	9,0,0,0
        +	DD	imagerel ssse3_handler
        +	DD	imagerel $L$prologue_ssse3,imagerel $L$epilogue_ssse3
        +
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm
        new file mode 100644
        index 000000000..9d5a62607
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/aes/aesni-x86_64.asm
        @@ -0,0 +1,3062 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +PUBLIC	aesni_encrypt
        +
        +ALIGN	16
        +aesni_encrypt	PROC PUBLIC
        +	movups	xmm2,XMMWORD PTR[rcx]
        +	mov	eax,DWORD PTR[240+r8]
        +	movups	xmm0,XMMWORD PTR[r8]
        +	movups	xmm1,XMMWORD PTR[16+r8]
        +	lea	r8,QWORD PTR[32+r8]
        +	xorps	xmm2,xmm0
        +$L$oop_enc1_1::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[r8]
        +	lea	r8,QWORD PTR[16+r8]
        +	jnz	$L$oop_enc1_1
        +
        +DB	102,15,56,221,209
        +	movups	XMMWORD PTR[rdx],xmm2
        +	DB	0F3h,0C3h		;repret
        +aesni_encrypt	ENDP
        +
        +PUBLIC	aesni_decrypt
        +
        +ALIGN	16
        +aesni_decrypt	PROC PUBLIC
        +	movups	xmm2,XMMWORD PTR[rcx]
        +	mov	eax,DWORD PTR[240+r8]
        +	movups	xmm0,XMMWORD PTR[r8]
        +	movups	xmm1,XMMWORD PTR[16+r8]
        +	lea	r8,QWORD PTR[32+r8]
        +	xorps	xmm2,xmm0
        +$L$oop_dec1_2::
        +DB	102,15,56,222,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[r8]
        +	lea	r8,QWORD PTR[16+r8]
        +	jnz	$L$oop_dec1_2
        +
        +DB	102,15,56,223,209
        +	movups	XMMWORD PTR[rdx],xmm2
        +	DB	0F3h,0C3h		;repret
        +aesni_decrypt	ENDP
        +
        +ALIGN	16
        +_aesni_encrypt3	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm0
        +	xorps	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +
        +$L$enc_loop3::
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	eax
        +DB	102,15,56,220,225
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,224
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$enc_loop3
        +
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +	DB	0F3h,0C3h		;repret
        +_aesni_encrypt3	ENDP
        +
        +ALIGN	16
        +_aesni_decrypt3	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm0
        +	xorps	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +
        +$L$dec_loop3::
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	eax
        +DB	102,15,56,222,225
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,222,224
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$dec_loop3
        +
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +	DB	0F3h,0C3h		;repret
        +_aesni_decrypt3	ENDP
        +
        +ALIGN	16
        +_aesni_encrypt4	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm0
        +	xorps	xmm4,xmm0
        +	xorps	xmm5,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +
        +$L$enc_loop4::
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	eax
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$enc_loop4
        +
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +DB	102,15,56,221,232
        +	DB	0F3h,0C3h		;repret
        +_aesni_encrypt4	ENDP
        +
        +ALIGN	16
        +_aesni_decrypt4	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm0
        +	xorps	xmm4,xmm0
        +	xorps	xmm5,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +
        +$L$dec_loop4::
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	eax
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,222,224
        +DB	102,15,56,222,232
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$dec_loop4
        +
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +DB	102,15,56,223,232
        +	DB	0F3h,0C3h		;repret
        +_aesni_decrypt4	ENDP
        +
        +ALIGN	16
        +_aesni_encrypt6	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +DB	102,15,56,220,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,220,217
        +	pxor	xmm5,xmm0
        +DB	102,15,56,220,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +	dec	eax
        +DB	102,15,56,220,241
        +	movups	xmm0,XMMWORD PTR[rcx]
        +DB	102,15,56,220,249
        +	jmp	$L$enc_loop6_enter
        +ALIGN	16
        +$L$enc_loop6::
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	eax
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +$L$enc_loop6_enter::
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +DB	102,15,56,220,240
        +DB	102,15,56,220,248
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$enc_loop6
        +
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +DB	102,15,56,221,232
        +DB	102,15,56,221,240
        +DB	102,15,56,221,248
        +	DB	0F3h,0C3h		;repret
        +_aesni_encrypt6	ENDP
        +
        +ALIGN	16
        +_aesni_decrypt6	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +DB	102,15,56,222,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,222,217
        +	pxor	xmm5,xmm0
        +DB	102,15,56,222,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,222,233
        +	pxor	xmm7,xmm0
        +	dec	eax
        +DB	102,15,56,222,241
        +	movups	xmm0,XMMWORD PTR[rcx]
        +DB	102,15,56,222,249
        +	jmp	$L$dec_loop6_enter
        +ALIGN	16
        +$L$dec_loop6::
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	eax
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +$L$dec_loop6_enter::
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,222,224
        +DB	102,15,56,222,232
        +DB	102,15,56,222,240
        +DB	102,15,56,222,248
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$dec_loop6
        +
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +DB	102,15,56,223,232
        +DB	102,15,56,223,240
        +DB	102,15,56,223,248
        +	DB	0F3h,0C3h		;repret
        +_aesni_decrypt6	ENDP
        +
        +ALIGN	16
        +_aesni_encrypt8	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm0
        +DB	102,15,56,220,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,220,217
        +	pxor	xmm5,xmm0
        +DB	102,15,56,220,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +	dec	eax
        +DB	102,15,56,220,241
        +	pxor	xmm8,xmm0
        +DB	102,15,56,220,249
        +	pxor	xmm9,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +DB	102,68,15,56,220,193
        +DB	102,68,15,56,220,201
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	jmp	$L$enc_loop8_enter
        +ALIGN	16
        +$L$enc_loop8::
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	eax
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +DB	102,68,15,56,220,193
        +DB	102,68,15,56,220,201
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +$L$enc_loop8_enter::
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +DB	102,15,56,220,240
        +DB	102,15,56,220,248
        +DB	102,68,15,56,220,192
        +DB	102,68,15,56,220,200
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$enc_loop8
        +
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +DB	102,68,15,56,220,193
        +DB	102,68,15,56,220,201
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +DB	102,15,56,221,232
        +DB	102,15,56,221,240
        +DB	102,15,56,221,248
        +DB	102,68,15,56,221,192
        +DB	102,68,15,56,221,200
        +	DB	0F3h,0C3h		;repret
        +_aesni_encrypt8	ENDP
        +
        +ALIGN	16
        +_aesni_decrypt8	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm0
        +DB	102,15,56,222,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,222,217
        +	pxor	xmm5,xmm0
        +DB	102,15,56,222,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,222,233
        +	pxor	xmm7,xmm0
        +	dec	eax
        +DB	102,15,56,222,241
        +	pxor	xmm8,xmm0
        +DB	102,15,56,222,249
        +	pxor	xmm9,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +DB	102,68,15,56,222,193
        +DB	102,68,15,56,222,201
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	jmp	$L$dec_loop8_enter
        +ALIGN	16
        +$L$dec_loop8::
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	eax
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +DB	102,68,15,56,222,193
        +DB	102,68,15,56,222,201
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +$L$dec_loop8_enter::
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,222,224
        +DB	102,15,56,222,232
        +DB	102,15,56,222,240
        +DB	102,15,56,222,248
        +DB	102,68,15,56,222,192
        +DB	102,68,15,56,222,200
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$dec_loop8
        +
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +DB	102,68,15,56,222,193
        +DB	102,68,15,56,222,201
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +DB	102,15,56,223,232
        +DB	102,15,56,223,240
        +DB	102,15,56,223,248
        +DB	102,68,15,56,223,192
        +DB	102,68,15,56,223,200
        +	DB	0F3h,0C3h		;repret
        +_aesni_decrypt8	ENDP
        +PUBLIC	aesni_ecb_encrypt
        +
        +ALIGN	16
        +aesni_ecb_encrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_ecb_encrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +
        +
        +	and	rdx,-16
        +	jz	$L$ecb_ret
        +
        +	mov	eax,DWORD PTR[240+rcx]
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	mov	r11,rcx
        +	mov	r10d,eax
        +	test	r8d,r8d
        +	jz	$L$ecb_decrypt
        +
        +	cmp	rdx,080h
        +	jb	$L$ecb_enc_tail
        +
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +	movdqu	xmm8,XMMWORD PTR[96+rdi]
        +	movdqu	xmm9,XMMWORD PTR[112+rdi]
        +	lea	rdi,QWORD PTR[128+rdi]
        +	sub	rdx,080h
        +	jmp	$L$ecb_enc_loop8_enter
        +ALIGN	16
        +$L$ecb_enc_loop8::
        +	movups	XMMWORD PTR[rsi],xmm2
        +	mov	rcx,r11
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	movdqu	xmm8,XMMWORD PTR[96+rdi]
        +	movups	XMMWORD PTR[112+rsi],xmm9
        +	lea	rsi,QWORD PTR[128+rsi]
        +	movdqu	xmm9,XMMWORD PTR[112+rdi]
        +	lea	rdi,QWORD PTR[128+rdi]
        +$L$ecb_enc_loop8_enter::
        +
        +	call	_aesni_encrypt8
        +
        +	sub	rdx,080h
        +	jnc	$L$ecb_enc_loop8
        +
        +	movups	XMMWORD PTR[rsi],xmm2
        +	mov	rcx,r11
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	movups	XMMWORD PTR[112+rsi],xmm9
        +	lea	rsi,QWORD PTR[128+rsi]
        +	add	rdx,080h
        +	jz	$L$ecb_ret
        +
        +$L$ecb_enc_tail::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	cmp	rdx,020h
        +	jb	$L$ecb_enc_one
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	je	$L$ecb_enc_two
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	cmp	rdx,040h
        +	jb	$L$ecb_enc_three
        +	movups	xmm5,XMMWORD PTR[48+rdi]
        +	je	$L$ecb_enc_four
        +	movups	xmm6,XMMWORD PTR[64+rdi]
        +	cmp	rdx,060h
        +	jb	$L$ecb_enc_five
        +	movups	xmm7,XMMWORD PTR[80+rdi]
        +	je	$L$ecb_enc_six
        +	movdqu	xmm8,XMMWORD PTR[96+rdi]
        +	call	_aesni_encrypt8
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_enc_one::
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_enc1_3::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_enc1_3
        +
        +DB	102,15,56,221,209
        +	movups	XMMWORD PTR[rsi],xmm2
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_enc_two::
        +	xorps	xmm4,xmm4
        +	call	_aesni_encrypt3
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_enc_three::
        +	call	_aesni_encrypt3
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_enc_four::
        +	call	_aesni_encrypt4
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_enc_five::
        +	xorps	xmm7,xmm7
        +	call	_aesni_encrypt6
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_enc_six::
        +	call	_aesni_encrypt6
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	jmp	$L$ecb_ret
        +
        +ALIGN	16
        +$L$ecb_decrypt::
        +	cmp	rdx,080h
        +	jb	$L$ecb_dec_tail
        +
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +	movdqu	xmm8,XMMWORD PTR[96+rdi]
        +	movdqu	xmm9,XMMWORD PTR[112+rdi]
        +	lea	rdi,QWORD PTR[128+rdi]
        +	sub	rdx,080h
        +	jmp	$L$ecb_dec_loop8_enter
        +ALIGN	16
        +$L$ecb_dec_loop8::
        +	movups	XMMWORD PTR[rsi],xmm2
        +	mov	rcx,r11
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	movdqu	xmm8,XMMWORD PTR[96+rdi]
        +	movups	XMMWORD PTR[112+rsi],xmm9
        +	lea	rsi,QWORD PTR[128+rsi]
        +	movdqu	xmm9,XMMWORD PTR[112+rdi]
        +	lea	rdi,QWORD PTR[128+rdi]
        +$L$ecb_dec_loop8_enter::
        +
        +	call	_aesni_decrypt8
        +
        +	movups	xmm0,XMMWORD PTR[r11]
        +	sub	rdx,080h
        +	jnc	$L$ecb_dec_loop8
        +
        +	movups	XMMWORD PTR[rsi],xmm2
        +	mov	rcx,r11
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	movups	XMMWORD PTR[112+rsi],xmm9
        +	lea	rsi,QWORD PTR[128+rsi]
        +	add	rdx,080h
        +	jz	$L$ecb_ret
        +
        +$L$ecb_dec_tail::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	cmp	rdx,020h
        +	jb	$L$ecb_dec_one
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	je	$L$ecb_dec_two
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	cmp	rdx,040h
        +	jb	$L$ecb_dec_three
        +	movups	xmm5,XMMWORD PTR[48+rdi]
        +	je	$L$ecb_dec_four
        +	movups	xmm6,XMMWORD PTR[64+rdi]
        +	cmp	rdx,060h
        +	jb	$L$ecb_dec_five
        +	movups	xmm7,XMMWORD PTR[80+rdi]
        +	je	$L$ecb_dec_six
        +	movups	xmm8,XMMWORD PTR[96+rdi]
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	call	_aesni_decrypt8
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_dec_one::
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_dec1_4::
        +DB	102,15,56,222,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_dec1_4
        +
        +DB	102,15,56,223,209
        +	movups	XMMWORD PTR[rsi],xmm2
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_dec_two::
        +	xorps	xmm4,xmm4
        +	call	_aesni_decrypt3
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_dec_three::
        +	call	_aesni_decrypt3
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_dec_four::
        +	call	_aesni_decrypt4
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_dec_five::
        +	xorps	xmm7,xmm7
        +	call	_aesni_decrypt6
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	jmp	$L$ecb_ret
        +ALIGN	16
        +$L$ecb_dec_six::
        +	call	_aesni_decrypt6
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +
        +$L$ecb_ret::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_ecb_encrypt::
        +aesni_ecb_encrypt	ENDP
        +PUBLIC	aesni_ccm64_encrypt_blocks
        +
        +ALIGN	16
        +aesni_ccm64_encrypt_blocks	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_ccm64_encrypt_blocks::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	lea	rsp,QWORD PTR[((-88))+rsp]
        +	movaps	XMMWORD PTR[rsp],xmm6
        +	movaps	XMMWORD PTR[16+rsp],xmm7
        +	movaps	XMMWORD PTR[32+rsp],xmm8
        +	movaps	XMMWORD PTR[48+rsp],xmm9
        +$L$ccm64_enc_body::
        +	mov	eax,DWORD PTR[240+rcx]
        +	movdqu	xmm9,XMMWORD PTR[r8]
        +	movdqa	xmm6,XMMWORD PTR[$L$increment64]
        +	movdqa	xmm7,XMMWORD PTR[$L$bswap_mask]
        +
        +	shr	eax,1
        +	lea	r11,QWORD PTR[rcx]
        +	movdqu	xmm3,XMMWORD PTR[r9]
        +	movdqa	xmm2,xmm9
        +	mov	r10d,eax
        +DB	102,68,15,56,0,207
        +	jmp	$L$ccm64_enc_outer
        +ALIGN	16
        +$L$ccm64_enc_outer::
        +	movups	xmm0,XMMWORD PTR[r11]
        +	mov	eax,r10d
        +	movups	xmm8,XMMWORD PTR[rdi]
        +
        +	xorps	xmm2,xmm0
        +	movups	xmm1,XMMWORD PTR[16+r11]
        +	xorps	xmm0,xmm8
        +	lea	rcx,QWORD PTR[32+r11]
        +	xorps	xmm3,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +
        +$L$ccm64_enc2_loop::
        +DB	102,15,56,220,209
        +	dec	eax
        +DB	102,15,56,220,217
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,216
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$ccm64_enc2_loop
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	paddq	xmm9,xmm6
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +
        +	dec	rdx
        +	lea	rdi,QWORD PTR[16+rdi]
        +	xorps	xmm8,xmm2
        +	movdqa	xmm2,xmm9
        +	movups	XMMWORD PTR[rsi],xmm8
        +	lea	rsi,QWORD PTR[16+rsi]
        +DB	102,15,56,0,215
        +	jnz	$L$ccm64_enc_outer
        +
        +	movups	XMMWORD PTR[r9],xmm3
        +	movaps	xmm6,XMMWORD PTR[rsp]
        +	movaps	xmm7,XMMWORD PTR[16+rsp]
        +	movaps	xmm8,XMMWORD PTR[32+rsp]
        +	movaps	xmm9,XMMWORD PTR[48+rsp]
        +	lea	rsp,QWORD PTR[88+rsp]
        +$L$ccm64_enc_ret::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_ccm64_encrypt_blocks::
        +aesni_ccm64_encrypt_blocks	ENDP
        +PUBLIC	aesni_ccm64_decrypt_blocks
        +
        +ALIGN	16
        +aesni_ccm64_decrypt_blocks	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_ccm64_decrypt_blocks::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	lea	rsp,QWORD PTR[((-88))+rsp]
        +	movaps	XMMWORD PTR[rsp],xmm6
        +	movaps	XMMWORD PTR[16+rsp],xmm7
        +	movaps	XMMWORD PTR[32+rsp],xmm8
        +	movaps	XMMWORD PTR[48+rsp],xmm9
        +$L$ccm64_dec_body::
        +	mov	eax,DWORD PTR[240+rcx]
        +	movups	xmm9,XMMWORD PTR[r8]
        +	movdqu	xmm3,XMMWORD PTR[r9]
        +	movdqa	xmm6,XMMWORD PTR[$L$increment64]
        +	movdqa	xmm7,XMMWORD PTR[$L$bswap_mask]
        +
        +	movaps	xmm2,xmm9
        +	mov	r10d,eax
        +	mov	r11,rcx
        +DB	102,68,15,56,0,207
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_enc1_5::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_enc1_5
        +
        +DB	102,15,56,221,209
        +	movups	xmm8,XMMWORD PTR[rdi]
        +	paddq	xmm9,xmm6
        +	lea	rdi,QWORD PTR[16+rdi]
        +	jmp	$L$ccm64_dec_outer
        +ALIGN	16
        +$L$ccm64_dec_outer::
        +	xorps	xmm8,xmm2
        +	movdqa	xmm2,xmm9
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[rsi],xmm8
        +	lea	rsi,QWORD PTR[16+rsi]
        +DB	102,15,56,0,215
        +
        +	sub	rdx,1
        +	jz	$L$ccm64_dec_break
        +
        +	movups	xmm0,XMMWORD PTR[r11]
        +	shr	eax,1
        +	movups	xmm1,XMMWORD PTR[16+r11]
        +	xorps	xmm8,xmm0
        +	lea	rcx,QWORD PTR[32+r11]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm8
        +	movups	xmm0,XMMWORD PTR[rcx]
        +
        +$L$ccm64_dec2_loop::
        +DB	102,15,56,220,209
        +	dec	eax
        +DB	102,15,56,220,217
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,216
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$ccm64_dec2_loop
        +	movups	xmm8,XMMWORD PTR[rdi]
        +	paddq	xmm9,xmm6
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	lea	rdi,QWORD PTR[16+rdi]
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +	jmp	$L$ccm64_dec_outer
        +
        +ALIGN	16
        +$L$ccm64_dec_break::
        +
        +	movups	xmm0,XMMWORD PTR[r11]
        +	movups	xmm1,XMMWORD PTR[16+r11]
        +	xorps	xmm8,xmm0
        +	lea	r11,QWORD PTR[32+r11]
        +	xorps	xmm3,xmm8
        +$L$oop_enc1_6::
        +DB	102,15,56,220,217
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[r11]
        +	lea	r11,QWORD PTR[16+r11]
        +	jnz	$L$oop_enc1_6
        +
        +DB	102,15,56,221,217
        +	movups	XMMWORD PTR[r9],xmm3
        +	movaps	xmm6,XMMWORD PTR[rsp]
        +	movaps	xmm7,XMMWORD PTR[16+rsp]
        +	movaps	xmm8,XMMWORD PTR[32+rsp]
        +	movaps	xmm9,XMMWORD PTR[48+rsp]
        +	lea	rsp,QWORD PTR[88+rsp]
        +$L$ccm64_dec_ret::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_ccm64_decrypt_blocks::
        +aesni_ccm64_decrypt_blocks	ENDP
        +PUBLIC	aesni_ctr32_encrypt_blocks
        +
        +ALIGN	16
        +aesni_ctr32_encrypt_blocks	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_ctr32_encrypt_blocks::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +
        +
        +	lea	rsp,QWORD PTR[((-200))+rsp]
        +	movaps	XMMWORD PTR[32+rsp],xmm6
        +	movaps	XMMWORD PTR[48+rsp],xmm7
        +	movaps	XMMWORD PTR[64+rsp],xmm8
        +	movaps	XMMWORD PTR[80+rsp],xmm9
        +	movaps	XMMWORD PTR[96+rsp],xmm10
        +	movaps	XMMWORD PTR[112+rsp],xmm11
        +	movaps	XMMWORD PTR[128+rsp],xmm12
        +	movaps	XMMWORD PTR[144+rsp],xmm13
        +	movaps	XMMWORD PTR[160+rsp],xmm14
        +	movaps	XMMWORD PTR[176+rsp],xmm15
        +$L$ctr32_body::
        +	cmp	rdx,1
        +	je	$L$ctr32_one_shortcut
        +
        +	movdqu	xmm14,XMMWORD PTR[r8]
        +	movdqa	xmm15,XMMWORD PTR[$L$bswap_mask]
        +	xor	eax,eax
        +DB	102,69,15,58,22,242,3
        +DB	102,68,15,58,34,240,3
        +
        +	mov	eax,DWORD PTR[240+rcx]
        +	bswap	r10d
        +	pxor	xmm12,xmm12
        +	pxor	xmm13,xmm13
        +DB	102,69,15,58,34,226,0
        +	lea	r11,QWORD PTR[3+r10]
        +DB	102,69,15,58,34,235,0
        +	inc	r10d
        +DB	102,69,15,58,34,226,1
        +	inc	r11
        +DB	102,69,15,58,34,235,1
        +	inc	r10d
        +DB	102,69,15,58,34,226,2
        +	inc	r11
        +DB	102,69,15,58,34,235,2
        +	movdqa	XMMWORD PTR[rsp],xmm12
        +DB	102,69,15,56,0,231
        +	movdqa	XMMWORD PTR[16+rsp],xmm13
        +DB	102,69,15,56,0,239
        +
        +	pshufd	xmm2,xmm12,192
        +	pshufd	xmm3,xmm12,128
        +	pshufd	xmm4,xmm12,64
        +	cmp	rdx,6
        +	jb	$L$ctr32_tail
        +	shr	eax,1
        +	mov	r11,rcx
        +	mov	r10d,eax
        +	sub	rdx,6
        +	jmp	$L$ctr32_loop6
        +
        +ALIGN	16
        +$L$ctr32_loop6::
        +	pshufd	xmm5,xmm13,192
        +	por	xmm2,xmm14
        +	movups	xmm0,XMMWORD PTR[r11]
        +	pshufd	xmm6,xmm13,128
        +	por	xmm3,xmm14
        +	movups	xmm1,XMMWORD PTR[16+r11]
        +	pshufd	xmm7,xmm13,64
        +	por	xmm4,xmm14
        +	por	xmm5,xmm14
        +	xorps	xmm2,xmm0
        +	por	xmm6,xmm14
        +	por	xmm7,xmm14
        +
        +
        +
        +
        +	pxor	xmm3,xmm0
        +DB	102,15,56,220,209
        +	lea	rcx,QWORD PTR[32+r11]
        +	pxor	xmm4,xmm0
        +DB	102,15,56,220,217
        +	movdqa	xmm13,XMMWORD PTR[$L$increment32]
        +	pxor	xmm5,xmm0
        +DB	102,15,56,220,225
        +	movdqa	xmm12,XMMWORD PTR[rsp]
        +	pxor	xmm6,xmm0
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	dec	eax
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +	jmp	$L$ctr32_enc_loop6_enter
        +ALIGN	16
        +$L$ctr32_enc_loop6::
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	eax
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +$L$ctr32_enc_loop6_enter::
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +DB	102,15,56,220,240
        +DB	102,15,56,220,248
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$ctr32_enc_loop6
        +
        +DB	102,15,56,220,209
        +	paddd	xmm12,xmm13
        +DB	102,15,56,220,217
        +	paddd	xmm13,XMMWORD PTR[16+rsp]
        +DB	102,15,56,220,225
        +	movdqa	XMMWORD PTR[rsp],xmm12
        +DB	102,15,56,220,233
        +	movdqa	XMMWORD PTR[16+rsp],xmm13
        +DB	102,15,56,220,241
        +DB	102,69,15,56,0,231
        +DB	102,15,56,220,249
        +DB	102,69,15,56,0,239
        +
        +DB	102,15,56,221,208
        +	movups	xmm8,XMMWORD PTR[rdi]
        +DB	102,15,56,221,216
        +	movups	xmm9,XMMWORD PTR[16+rdi]
        +DB	102,15,56,221,224
        +	movups	xmm10,XMMWORD PTR[32+rdi]
        +DB	102,15,56,221,232
        +	movups	xmm11,XMMWORD PTR[48+rdi]
        +DB	102,15,56,221,240
        +	movups	xmm1,XMMWORD PTR[64+rdi]
        +DB	102,15,56,221,248
        +	movups	xmm0,XMMWORD PTR[80+rdi]
        +	lea	rdi,QWORD PTR[96+rdi]
        +
        +	xorps	xmm8,xmm2
        +	pshufd	xmm2,xmm12,192
        +	xorps	xmm9,xmm3
        +	pshufd	xmm3,xmm12,128
        +	movups	XMMWORD PTR[rsi],xmm8
        +	xorps	xmm10,xmm4
        +	pshufd	xmm4,xmm12,64
        +	movups	XMMWORD PTR[16+rsi],xmm9
        +	xorps	xmm11,xmm5
        +	movups	XMMWORD PTR[32+rsi],xmm10
        +	xorps	xmm1,xmm6
        +	movups	XMMWORD PTR[48+rsi],xmm11
        +	xorps	xmm0,xmm7
        +	movups	XMMWORD PTR[64+rsi],xmm1
        +	movups	XMMWORD PTR[80+rsi],xmm0
        +	lea	rsi,QWORD PTR[96+rsi]
        +	mov	eax,r10d
        +	sub	rdx,6
        +	jnc	$L$ctr32_loop6
        +
        +	add	rdx,6
        +	jz	$L$ctr32_done
        +	mov	rcx,r11
        +	lea	eax,DWORD PTR[1+rax*1+rax]
        +
        +$L$ctr32_tail::
        +	por	xmm2,xmm14
        +	movups	xmm8,XMMWORD PTR[rdi]
        +	cmp	rdx,2
        +	jb	$L$ctr32_one
        +
        +	por	xmm3,xmm14
        +	movups	xmm9,XMMWORD PTR[16+rdi]
        +	je	$L$ctr32_two
        +
        +	pshufd	xmm5,xmm13,192
        +	por	xmm4,xmm14
        +	movups	xmm10,XMMWORD PTR[32+rdi]
        +	cmp	rdx,4
        +	jb	$L$ctr32_three
        +
        +	pshufd	xmm6,xmm13,128
        +	por	xmm5,xmm14
        +	movups	xmm11,XMMWORD PTR[48+rdi]
        +	je	$L$ctr32_four
        +
        +	por	xmm6,xmm14
        +	xorps	xmm7,xmm7
        +
        +	call	_aesni_encrypt6
        +
        +	movups	xmm1,XMMWORD PTR[64+rdi]
        +	xorps	xmm8,xmm2
        +	xorps	xmm9,xmm3
        +	movups	XMMWORD PTR[rsi],xmm8
        +	xorps	xmm10,xmm4
        +	movups	XMMWORD PTR[16+rsi],xmm9
        +	xorps	xmm11,xmm5
        +	movups	XMMWORD PTR[32+rsi],xmm10
        +	xorps	xmm1,xmm6
        +	movups	XMMWORD PTR[48+rsi],xmm11
        +	movups	XMMWORD PTR[64+rsi],xmm1
        +	jmp	$L$ctr32_done
        +
        +ALIGN	16
        +$L$ctr32_one_shortcut::
        +	movups	xmm2,XMMWORD PTR[r8]
        +	movups	xmm8,XMMWORD PTR[rdi]
        +	mov	eax,DWORD PTR[240+rcx]
        +$L$ctr32_one::
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_enc1_7::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_enc1_7
        +
        +DB	102,15,56,221,209
        +	xorps	xmm8,xmm2
        +	movups	XMMWORD PTR[rsi],xmm8
        +	jmp	$L$ctr32_done
        +
        +ALIGN	16
        +$L$ctr32_two::
        +	xorps	xmm4,xmm4
        +	call	_aesni_encrypt3
        +	xorps	xmm8,xmm2
        +	xorps	xmm9,xmm3
        +	movups	XMMWORD PTR[rsi],xmm8
        +	movups	XMMWORD PTR[16+rsi],xmm9
        +	jmp	$L$ctr32_done
        +
        +ALIGN	16
        +$L$ctr32_three::
        +	call	_aesni_encrypt3
        +	xorps	xmm8,xmm2
        +	xorps	xmm9,xmm3
        +	movups	XMMWORD PTR[rsi],xmm8
        +	xorps	xmm10,xmm4
        +	movups	XMMWORD PTR[16+rsi],xmm9
        +	movups	XMMWORD PTR[32+rsi],xmm10
        +	jmp	$L$ctr32_done
        +
        +ALIGN	16
        +$L$ctr32_four::
        +	call	_aesni_encrypt4
        +	xorps	xmm8,xmm2
        +	xorps	xmm9,xmm3
        +	movups	XMMWORD PTR[rsi],xmm8
        +	xorps	xmm10,xmm4
        +	movups	XMMWORD PTR[16+rsi],xmm9
        +	xorps	xmm11,xmm5
        +	movups	XMMWORD PTR[32+rsi],xmm10
        +	movups	XMMWORD PTR[48+rsi],xmm11
        +
        +$L$ctr32_done::
        +	movaps	xmm6,XMMWORD PTR[32+rsp]
        +	movaps	xmm7,XMMWORD PTR[48+rsp]
        +	movaps	xmm8,XMMWORD PTR[64+rsp]
        +	movaps	xmm9,XMMWORD PTR[80+rsp]
        +	movaps	xmm10,XMMWORD PTR[96+rsp]
        +	movaps	xmm11,XMMWORD PTR[112+rsp]
        +	movaps	xmm12,XMMWORD PTR[128+rsp]
        +	movaps	xmm13,XMMWORD PTR[144+rsp]
        +	movaps	xmm14,XMMWORD PTR[160+rsp]
        +	movaps	xmm15,XMMWORD PTR[176+rsp]
        +	lea	rsp,QWORD PTR[200+rsp]
        +$L$ctr32_ret::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_ctr32_encrypt_blocks::
        +aesni_ctr32_encrypt_blocks	ENDP
        +PUBLIC	aesni_xts_encrypt
        +
        +ALIGN	16
        +aesni_xts_encrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_xts_encrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	lea	rsp,QWORD PTR[((-264))+rsp]
        +	movaps	XMMWORD PTR[96+rsp],xmm6
        +	movaps	XMMWORD PTR[112+rsp],xmm7
        +	movaps	XMMWORD PTR[128+rsp],xmm8
        +	movaps	XMMWORD PTR[144+rsp],xmm9
        +	movaps	XMMWORD PTR[160+rsp],xmm10
        +	movaps	XMMWORD PTR[176+rsp],xmm11
        +	movaps	XMMWORD PTR[192+rsp],xmm12
        +	movaps	XMMWORD PTR[208+rsp],xmm13
        +	movaps	XMMWORD PTR[224+rsp],xmm14
        +	movaps	XMMWORD PTR[240+rsp],xmm15
        +$L$xts_enc_body::
        +	movups	xmm15,XMMWORD PTR[r9]
        +	mov	eax,DWORD PTR[240+r8]
        +	mov	r10d,DWORD PTR[240+rcx]
        +	movups	xmm0,XMMWORD PTR[r8]
        +	movups	xmm1,XMMWORD PTR[16+r8]
        +	lea	r8,QWORD PTR[32+r8]
        +	xorps	xmm15,xmm0
        +$L$oop_enc1_8::
        +DB	102,68,15,56,220,249
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[r8]
        +	lea	r8,QWORD PTR[16+r8]
        +	jnz	$L$oop_enc1_8
        +
        +DB	102,68,15,56,221,249
        +	mov	r11,rcx
        +	mov	eax,r10d
        +	mov	r9,rdx
        +	and	rdx,-16
        +
        +	movdqa	xmm8,XMMWORD PTR[$L$xts_magic]
        +	pxor	xmm14,xmm14
        +	pcmpgtd	xmm14,xmm15
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm10,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm11,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm12,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm13,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	sub	rdx,16*6
        +	jc	$L$xts_enc_short
        +
        +	shr	eax,1
        +	sub	eax,1
        +	mov	r10d,eax
        +	jmp	$L$xts_enc_grandloop
        +
        +ALIGN	16
        +$L$xts_enc_grandloop::
        +	pshufd	xmm9,xmm14,013h
        +	movdqa	xmm14,xmm15
        +	paddq	xmm15,xmm15
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	pand	xmm9,xmm8
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	pxor	xmm15,xmm9
        +
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	pxor	xmm2,xmm10
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	pxor	xmm3,xmm11
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	pxor	xmm4,xmm12
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +	lea	rdi,QWORD PTR[96+rdi]
        +	pxor	xmm5,xmm13
        +	movups	xmm0,XMMWORD PTR[r11]
        +	pxor	xmm6,xmm14
        +	pxor	xmm7,xmm15
        +
        +
        +
        +	movups	xmm1,XMMWORD PTR[16+r11]
        +	pxor	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +	movdqa	XMMWORD PTR[rsp],xmm10
        +DB	102,15,56,220,209
        +	lea	rcx,QWORD PTR[32+r11]
        +	pxor	xmm4,xmm0
        +	movdqa	XMMWORD PTR[16+rsp],xmm11
        +DB	102,15,56,220,217
        +	pxor	xmm5,xmm0
        +	movdqa	XMMWORD PTR[32+rsp],xmm12
        +DB	102,15,56,220,225
        +	pxor	xmm6,xmm0
        +	movdqa	XMMWORD PTR[48+rsp],xmm13
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	dec	eax
        +	movdqa	XMMWORD PTR[64+rsp],xmm14
        +DB	102,15,56,220,241
        +	movdqa	XMMWORD PTR[80+rsp],xmm15
        +DB	102,15,56,220,249
        +	pxor	xmm14,xmm14
        +	pcmpgtd	xmm14,xmm15
        +	jmp	$L$xts_enc_loop6_enter
        +
        +ALIGN	16
        +$L$xts_enc_loop6::
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	eax
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +$L$xts_enc_loop6_enter::
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +DB	102,15,56,220,240
        +DB	102,15,56,220,248
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$xts_enc_loop6
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	paddq	xmm15,xmm15
        +DB	102,15,56,220,209
        +	pand	xmm9,xmm8
        +DB	102,15,56,220,217
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,220,225
        +	pxor	xmm15,xmm9
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm10,xmm15
        +	paddq	xmm15,xmm15
        +DB	102,15,56,220,208
        +	pand	xmm9,xmm8
        +DB	102,15,56,220,216
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,220,224
        +	pxor	xmm15,xmm9
        +DB	102,15,56,220,232
        +DB	102,15,56,220,240
        +DB	102,15,56,220,248
        +	movups	xmm0,XMMWORD PTR[32+rcx]
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm11,xmm15
        +	paddq	xmm15,xmm15
        +DB	102,15,56,220,209
        +	pand	xmm9,xmm8
        +DB	102,15,56,220,217
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,220,225
        +	pxor	xmm15,xmm9
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm12,xmm15
        +	paddq	xmm15,xmm15
        +DB	102,15,56,221,208
        +	pand	xmm9,xmm8
        +DB	102,15,56,221,216
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,221,224
        +	pxor	xmm15,xmm9
        +DB	102,15,56,221,232
        +DB	102,15,56,221,240
        +DB	102,15,56,221,248
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm13,xmm15
        +	paddq	xmm15,xmm15
        +	xorps	xmm2,XMMWORD PTR[rsp]
        +	pand	xmm9,xmm8
        +	xorps	xmm3,XMMWORD PTR[16+rsp]
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +
        +	xorps	xmm4,XMMWORD PTR[32+rsp]
        +	movups	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm5,XMMWORD PTR[48+rsp]
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	xorps	xmm6,XMMWORD PTR[64+rsp]
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	xorps	xmm7,XMMWORD PTR[80+rsp]
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	lea	rsi,QWORD PTR[96+rsi]
        +	sub	rdx,16*6
        +	jnc	$L$xts_enc_grandloop
        +
        +	lea	eax,DWORD PTR[3+rax*1+rax]
        +	mov	rcx,r11
        +	mov	r10d,eax
        +
        +$L$xts_enc_short::
        +	add	rdx,16*6
        +	jz	$L$xts_enc_done
        +
        +	cmp	rdx,020h
        +	jb	$L$xts_enc_one
        +	je	$L$xts_enc_two
        +
        +	cmp	rdx,040h
        +	jb	$L$xts_enc_three
        +	je	$L$xts_enc_four
        +
        +	pshufd	xmm9,xmm14,013h
        +	movdqa	xmm14,xmm15
        +	paddq	xmm15,xmm15
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	pand	xmm9,xmm8
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	pxor	xmm15,xmm9
        +
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	pxor	xmm2,xmm10
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	pxor	xmm3,xmm11
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	lea	rdi,QWORD PTR[80+rdi]
        +	pxor	xmm4,xmm12
        +	pxor	xmm5,xmm13
        +	pxor	xmm6,xmm14
        +
        +	call	_aesni_encrypt6
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm15
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +	movdqu	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm5,xmm13
        +	movdqu	XMMWORD PTR[16+rsi],xmm3
        +	xorps	xmm6,xmm14
        +	movdqu	XMMWORD PTR[32+rsi],xmm4
        +	movdqu	XMMWORD PTR[48+rsi],xmm5
        +	movdqu	XMMWORD PTR[64+rsi],xmm6
        +	lea	rsi,QWORD PTR[80+rsi]
        +	jmp	$L$xts_enc_done
        +
        +ALIGN	16
        +$L$xts_enc_one::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	lea	rdi,QWORD PTR[16+rdi]
        +	xorps	xmm2,xmm10
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_enc1_9::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_enc1_9
        +
        +DB	102,15,56,221,209
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm11
        +	movups	XMMWORD PTR[rsi],xmm2
        +	lea	rsi,QWORD PTR[16+rsi]
        +	jmp	$L$xts_enc_done
        +
        +ALIGN	16
        +$L$xts_enc_two::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	lea	rdi,QWORD PTR[32+rdi]
        +	xorps	xmm2,xmm10
        +	xorps	xmm3,xmm11
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm12
        +	xorps	xmm3,xmm11
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	lea	rsi,QWORD PTR[32+rsi]
        +	jmp	$L$xts_enc_done
        +
        +ALIGN	16
        +$L$xts_enc_three::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	lea	rdi,QWORD PTR[48+rdi]
        +	xorps	xmm2,xmm10
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm13
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	lea	rsi,QWORD PTR[48+rsi]
        +	jmp	$L$xts_enc_done
        +
        +ALIGN	16
        +$L$xts_enc_four::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	xorps	xmm2,xmm10
        +	movups	xmm5,XMMWORD PTR[48+rdi]
        +	lea	rdi,QWORD PTR[64+rdi]
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +	xorps	xmm5,xmm13
        +
        +	call	_aesni_encrypt4
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm15
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +	movups	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm5,xmm13
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	lea	rsi,QWORD PTR[64+rsi]
        +	jmp	$L$xts_enc_done
        +
        +ALIGN	16
        +$L$xts_enc_done::
        +	and	r9,15
        +	jz	$L$xts_enc_ret
        +	mov	rdx,r9
        +
        +$L$xts_enc_steal::
        +	movzx	eax,BYTE PTR[rdi]
        +	movzx	ecx,BYTE PTR[((-16))+rsi]
        +	lea	rdi,QWORD PTR[1+rdi]
        +	mov	BYTE PTR[((-16))+rsi],al
        +	mov	BYTE PTR[rsi],cl
        +	lea	rsi,QWORD PTR[1+rsi]
        +	sub	rdx,1
        +	jnz	$L$xts_enc_steal
        +
        +	sub	rsi,r9
        +	mov	rcx,r11
        +	mov	eax,r10d
        +
        +	movups	xmm2,XMMWORD PTR[((-16))+rsi]
        +	xorps	xmm2,xmm10
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_enc1_10::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_enc1_10
        +
        +DB	102,15,56,221,209
        +	xorps	xmm2,xmm10
        +	movups	XMMWORD PTR[(-16)+rsi],xmm2
        +
        +$L$xts_enc_ret::
        +	movaps	xmm6,XMMWORD PTR[96+rsp]
        +	movaps	xmm7,XMMWORD PTR[112+rsp]
        +	movaps	xmm8,XMMWORD PTR[128+rsp]
        +	movaps	xmm9,XMMWORD PTR[144+rsp]
        +	movaps	xmm10,XMMWORD PTR[160+rsp]
        +	movaps	xmm11,XMMWORD PTR[176+rsp]
        +	movaps	xmm12,XMMWORD PTR[192+rsp]
        +	movaps	xmm13,XMMWORD PTR[208+rsp]
        +	movaps	xmm14,XMMWORD PTR[224+rsp]
        +	movaps	xmm15,XMMWORD PTR[240+rsp]
        +	lea	rsp,QWORD PTR[264+rsp]
        +$L$xts_enc_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_xts_encrypt::
        +aesni_xts_encrypt	ENDP
        +PUBLIC	aesni_xts_decrypt
        +
        +ALIGN	16
        +aesni_xts_decrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_xts_decrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	lea	rsp,QWORD PTR[((-264))+rsp]
        +	movaps	XMMWORD PTR[96+rsp],xmm6
        +	movaps	XMMWORD PTR[112+rsp],xmm7
        +	movaps	XMMWORD PTR[128+rsp],xmm8
        +	movaps	XMMWORD PTR[144+rsp],xmm9
        +	movaps	XMMWORD PTR[160+rsp],xmm10
        +	movaps	XMMWORD PTR[176+rsp],xmm11
        +	movaps	XMMWORD PTR[192+rsp],xmm12
        +	movaps	XMMWORD PTR[208+rsp],xmm13
        +	movaps	XMMWORD PTR[224+rsp],xmm14
        +	movaps	XMMWORD PTR[240+rsp],xmm15
        +$L$xts_dec_body::
        +	movups	xmm15,XMMWORD PTR[r9]
        +	mov	eax,DWORD PTR[240+r8]
        +	mov	r10d,DWORD PTR[240+rcx]
        +	movups	xmm0,XMMWORD PTR[r8]
        +	movups	xmm1,XMMWORD PTR[16+r8]
        +	lea	r8,QWORD PTR[32+r8]
        +	xorps	xmm15,xmm0
        +$L$oop_enc1_11::
        +DB	102,68,15,56,220,249
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[r8]
        +	lea	r8,QWORD PTR[16+r8]
        +	jnz	$L$oop_enc1_11
        +
        +DB	102,68,15,56,221,249
        +	xor	eax,eax
        +	test	rdx,15
        +	setnz	al
        +	shl	rax,4
        +	sub	rdx,rax
        +
        +	mov	r11,rcx
        +	mov	eax,r10d
        +	mov	r9,rdx
        +	and	rdx,-16
        +
        +	movdqa	xmm8,XMMWORD PTR[$L$xts_magic]
        +	pxor	xmm14,xmm14
        +	pcmpgtd	xmm14,xmm15
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm10,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm11,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm12,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm13,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm9,xmm8
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +	sub	rdx,16*6
        +	jc	$L$xts_dec_short
        +
        +	shr	eax,1
        +	sub	eax,1
        +	mov	r10d,eax
        +	jmp	$L$xts_dec_grandloop
        +
        +ALIGN	16
        +$L$xts_dec_grandloop::
        +	pshufd	xmm9,xmm14,013h
        +	movdqa	xmm14,xmm15
        +	paddq	xmm15,xmm15
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	pand	xmm9,xmm8
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	pxor	xmm15,xmm9
        +
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	pxor	xmm2,xmm10
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	pxor	xmm3,xmm11
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	pxor	xmm4,xmm12
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +	lea	rdi,QWORD PTR[96+rdi]
        +	pxor	xmm5,xmm13
        +	movups	xmm0,XMMWORD PTR[r11]
        +	pxor	xmm6,xmm14
        +	pxor	xmm7,xmm15
        +
        +
        +
        +	movups	xmm1,XMMWORD PTR[16+r11]
        +	pxor	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +	movdqa	XMMWORD PTR[rsp],xmm10
        +DB	102,15,56,222,209
        +	lea	rcx,QWORD PTR[32+r11]
        +	pxor	xmm4,xmm0
        +	movdqa	XMMWORD PTR[16+rsp],xmm11
        +DB	102,15,56,222,217
        +	pxor	xmm5,xmm0
        +	movdqa	XMMWORD PTR[32+rsp],xmm12
        +DB	102,15,56,222,225
        +	pxor	xmm6,xmm0
        +	movdqa	XMMWORD PTR[48+rsp],xmm13
        +DB	102,15,56,222,233
        +	pxor	xmm7,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	dec	eax
        +	movdqa	XMMWORD PTR[64+rsp],xmm14
        +DB	102,15,56,222,241
        +	movdqa	XMMWORD PTR[80+rsp],xmm15
        +DB	102,15,56,222,249
        +	pxor	xmm14,xmm14
        +	pcmpgtd	xmm14,xmm15
        +	jmp	$L$xts_dec_loop6_enter
        +
        +ALIGN	16
        +$L$xts_dec_loop6::
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	eax
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +$L$xts_dec_loop6_enter::
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	rcx,QWORD PTR[32+rcx]
        +DB	102,15,56,222,224
        +DB	102,15,56,222,232
        +DB	102,15,56,222,240
        +DB	102,15,56,222,248
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	jnz	$L$xts_dec_loop6
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	paddq	xmm15,xmm15
        +DB	102,15,56,222,209
        +	pand	xmm9,xmm8
        +DB	102,15,56,222,217
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,222,225
        +	pxor	xmm15,xmm9
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm10,xmm15
        +	paddq	xmm15,xmm15
        +DB	102,15,56,222,208
        +	pand	xmm9,xmm8
        +DB	102,15,56,222,216
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,222,224
        +	pxor	xmm15,xmm9
        +DB	102,15,56,222,232
        +DB	102,15,56,222,240
        +DB	102,15,56,222,248
        +	movups	xmm0,XMMWORD PTR[32+rcx]
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm11,xmm15
        +	paddq	xmm15,xmm15
        +DB	102,15,56,222,209
        +	pand	xmm9,xmm8
        +DB	102,15,56,222,217
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,222,225
        +	pxor	xmm15,xmm9
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm12,xmm15
        +	paddq	xmm15,xmm15
        +DB	102,15,56,223,208
        +	pand	xmm9,xmm8
        +DB	102,15,56,223,216
        +	pcmpgtd	xmm14,xmm15
        +DB	102,15,56,223,224
        +	pxor	xmm15,xmm9
        +DB	102,15,56,223,232
        +DB	102,15,56,223,240
        +DB	102,15,56,223,248
        +
        +	pshufd	xmm9,xmm14,013h
        +	pxor	xmm14,xmm14
        +	movdqa	xmm13,xmm15
        +	paddq	xmm15,xmm15
        +	xorps	xmm2,XMMWORD PTR[rsp]
        +	pand	xmm9,xmm8
        +	xorps	xmm3,XMMWORD PTR[16+rsp]
        +	pcmpgtd	xmm14,xmm15
        +	pxor	xmm15,xmm9
        +
        +	xorps	xmm4,XMMWORD PTR[32+rsp]
        +	movups	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm5,XMMWORD PTR[48+rsp]
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	xorps	xmm6,XMMWORD PTR[64+rsp]
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	xorps	xmm7,XMMWORD PTR[80+rsp]
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	lea	rsi,QWORD PTR[96+rsi]
        +	sub	rdx,16*6
        +	jnc	$L$xts_dec_grandloop
        +
        +	lea	eax,DWORD PTR[3+rax*1+rax]
        +	mov	rcx,r11
        +	mov	r10d,eax
        +
        +$L$xts_dec_short::
        +	add	rdx,16*6
        +	jz	$L$xts_dec_done
        +
        +	cmp	rdx,020h
        +	jb	$L$xts_dec_one
        +	je	$L$xts_dec_two
        +
        +	cmp	rdx,040h
        +	jb	$L$xts_dec_three
        +	je	$L$xts_dec_four
        +
        +	pshufd	xmm9,xmm14,013h
        +	movdqa	xmm14,xmm15
        +	paddq	xmm15,xmm15
        +	movdqu	xmm2,XMMWORD PTR[rdi]
        +	pand	xmm9,xmm8
        +	movdqu	xmm3,XMMWORD PTR[16+rdi]
        +	pxor	xmm15,xmm9
        +
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	pxor	xmm2,xmm10
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	pxor	xmm3,xmm11
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +	lea	rdi,QWORD PTR[80+rdi]
        +	pxor	xmm4,xmm12
        +	pxor	xmm5,xmm13
        +	pxor	xmm6,xmm14
        +
        +	call	_aesni_decrypt6
        +
        +	xorps	xmm2,xmm10
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +	movdqu	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm5,xmm13
        +	movdqu	XMMWORD PTR[16+rsi],xmm3
        +	xorps	xmm6,xmm14
        +	movdqu	XMMWORD PTR[32+rsi],xmm4
        +	pxor	xmm14,xmm14
        +	movdqu	XMMWORD PTR[48+rsi],xmm5
        +	pcmpgtd	xmm14,xmm15
        +	movdqu	XMMWORD PTR[64+rsi],xmm6
        +	lea	rsi,QWORD PTR[80+rsi]
        +	pshufd	xmm11,xmm14,013h
        +	and	r9,15
        +	jz	$L$xts_dec_ret
        +
        +	movdqa	xmm10,xmm15
        +	paddq	xmm15,xmm15
        +	pand	xmm11,xmm8
        +	pxor	xmm11,xmm15
        +	jmp	$L$xts_dec_done2
        +
        +ALIGN	16
        +$L$xts_dec_one::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	lea	rdi,QWORD PTR[16+rdi]
        +	xorps	xmm2,xmm10
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_dec1_12::
        +DB	102,15,56,222,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_dec1_12
        +
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm11
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movdqa	xmm11,xmm12
        +	lea	rsi,QWORD PTR[16+rsi]
        +	jmp	$L$xts_dec_done
        +
        +ALIGN	16
        +$L$xts_dec_two::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	lea	rdi,QWORD PTR[32+rdi]
        +	xorps	xmm2,xmm10
        +	xorps	xmm3,xmm11
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm12
        +	xorps	xmm3,xmm11
        +	movdqa	xmm11,xmm13
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	lea	rsi,QWORD PTR[32+rsi]
        +	jmp	$L$xts_dec_done
        +
        +ALIGN	16
        +$L$xts_dec_three::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	lea	rdi,QWORD PTR[48+rdi]
        +	xorps	xmm2,xmm10
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm13
        +	xorps	xmm3,xmm11
        +	movdqa	xmm11,xmm15
        +	xorps	xmm4,xmm12
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	lea	rsi,QWORD PTR[48+rsi]
        +	jmp	$L$xts_dec_done
        +
        +ALIGN	16
        +$L$xts_dec_four::
        +	pshufd	xmm9,xmm14,013h
        +	movdqa	xmm14,xmm15
        +	paddq	xmm15,xmm15
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	pand	xmm9,xmm8
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	pxor	xmm15,xmm9
        +
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	xorps	xmm2,xmm10
        +	movups	xmm5,XMMWORD PTR[48+rdi]
        +	lea	rdi,QWORD PTR[64+rdi]
        +	xorps	xmm3,xmm11
        +	xorps	xmm4,xmm12
        +	xorps	xmm5,xmm13
        +
        +	call	_aesni_decrypt4
        +
        +	xorps	xmm2,xmm10
        +	movdqa	xmm10,xmm14
        +	xorps	xmm3,xmm11
        +	movdqa	xmm11,xmm15
        +	xorps	xmm4,xmm12
        +	movups	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm5,xmm13
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	lea	rsi,QWORD PTR[64+rsi]
        +	jmp	$L$xts_dec_done
        +
        +ALIGN	16
        +$L$xts_dec_done::
        +	and	r9,15
        +	jz	$L$xts_dec_ret
        +$L$xts_dec_done2::
        +	mov	rdx,r9
        +	mov	rcx,r11
        +	mov	eax,r10d
        +
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	xorps	xmm2,xmm11
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_dec1_13::
        +DB	102,15,56,222,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_dec1_13
        +
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm11
        +	movups	XMMWORD PTR[rsi],xmm2
        +
        +$L$xts_dec_steal::
        +	movzx	eax,BYTE PTR[16+rdi]
        +	movzx	ecx,BYTE PTR[rsi]
        +	lea	rdi,QWORD PTR[1+rdi]
        +	mov	BYTE PTR[rsi],al
        +	mov	BYTE PTR[16+rsi],cl
        +	lea	rsi,QWORD PTR[1+rsi]
        +	sub	rdx,1
        +	jnz	$L$xts_dec_steal
        +
        +	sub	rsi,r9
        +	mov	rcx,r11
        +	mov	eax,r10d
        +
        +	movups	xmm2,XMMWORD PTR[rsi]
        +	xorps	xmm2,xmm10
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_dec1_14::
        +DB	102,15,56,222,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_dec1_14
        +
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm10
        +	movups	XMMWORD PTR[rsi],xmm2
        +
        +$L$xts_dec_ret::
        +	movaps	xmm6,XMMWORD PTR[96+rsp]
        +	movaps	xmm7,XMMWORD PTR[112+rsp]
        +	movaps	xmm8,XMMWORD PTR[128+rsp]
        +	movaps	xmm9,XMMWORD PTR[144+rsp]
        +	movaps	xmm10,XMMWORD PTR[160+rsp]
        +	movaps	xmm11,XMMWORD PTR[176+rsp]
        +	movaps	xmm12,XMMWORD PTR[192+rsp]
        +	movaps	xmm13,XMMWORD PTR[208+rsp]
        +	movaps	xmm14,XMMWORD PTR[224+rsp]
        +	movaps	xmm15,XMMWORD PTR[240+rsp]
        +	lea	rsp,QWORD PTR[264+rsp]
        +$L$xts_dec_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_xts_decrypt::
        +aesni_xts_decrypt	ENDP
        +PUBLIC	aesni_cbc_encrypt
        +
        +ALIGN	16
        +aesni_cbc_encrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_aesni_cbc_encrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	test	rdx,rdx
        +	jz	$L$cbc_ret
        +
        +	mov	r10d,DWORD PTR[240+rcx]
        +	mov	r11,rcx
        +	test	r9d,r9d
        +	jz	$L$cbc_decrypt
        +
        +	movups	xmm2,XMMWORD PTR[r8]
        +	mov	eax,r10d
        +	cmp	rdx,16
        +	jb	$L$cbc_enc_tail
        +	sub	rdx,16
        +	jmp	$L$cbc_enc_loop
        +ALIGN	16
        +$L$cbc_enc_loop::
        +	movups	xmm3,XMMWORD PTR[rdi]
        +	lea	rdi,QWORD PTR[16+rdi]
        +
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	xorps	xmm3,xmm0
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm3
        +$L$oop_enc1_15::
        +DB	102,15,56,220,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_enc1_15
        +
        +DB	102,15,56,221,209
        +	mov	eax,r10d
        +	mov	rcx,r11
        +	movups	XMMWORD PTR[rsi],xmm2
        +	lea	rsi,QWORD PTR[16+rsi]
        +	sub	rdx,16
        +	jnc	$L$cbc_enc_loop
        +	add	rdx,16
        +	jnz	$L$cbc_enc_tail
        +	movups	XMMWORD PTR[r8],xmm2
        +	jmp	$L$cbc_ret
        +
        +$L$cbc_enc_tail::
        +	mov	rcx,rdx
        +	xchg	rsi,rdi
        +	DD	09066A4F3h
        +
        +	mov	ecx,16
        +	sub	rcx,rdx
        +	xor	eax,eax
        +	DD	09066AAF3h
        +
        +	lea	rdi,QWORD PTR[((-16))+rdi]
        +	mov	eax,r10d
        +	mov	rsi,rdi
        +	mov	rcx,r11
        +	xor	rdx,rdx
        +	jmp	$L$cbc_enc_loop
        +
        +
        +ALIGN	16
        +$L$cbc_decrypt::
        +	lea	rsp,QWORD PTR[((-88))+rsp]
        +	movaps	XMMWORD PTR[rsp],xmm6
        +	movaps	XMMWORD PTR[16+rsp],xmm7
        +	movaps	XMMWORD PTR[32+rsp],xmm8
        +	movaps	XMMWORD PTR[48+rsp],xmm9
        +$L$cbc_decrypt_body::
        +	movups	xmm9,XMMWORD PTR[r8]
        +	mov	eax,r10d
        +	cmp	rdx,070h
        +	jbe	$L$cbc_dec_tail
        +	shr	r10d,1
        +	sub	rdx,070h
        +	mov	eax,r10d
        +	movaps	XMMWORD PTR[64+rsp],xmm9
        +	jmp	$L$cbc_dec_loop8_enter
        +ALIGN	16
        +$L$cbc_dec_loop8::
        +	movaps	XMMWORD PTR[64+rsp],xmm0
        +	movups	XMMWORD PTR[rsi],xmm9
        +	lea	rsi,QWORD PTR[16+rsi]
        +$L$cbc_dec_loop8_enter::
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +
        +	lea	rcx,QWORD PTR[32+rcx]
        +	movdqu	xmm4,XMMWORD PTR[32+rdi]
        +	xorps	xmm2,xmm0
        +	movdqu	xmm5,XMMWORD PTR[48+rdi]
        +	xorps	xmm3,xmm0
        +	movdqu	xmm6,XMMWORD PTR[64+rdi]
        +DB	102,15,56,222,209
        +	pxor	xmm4,xmm0
        +	movdqu	xmm7,XMMWORD PTR[80+rdi]
        +DB	102,15,56,222,217
        +	pxor	xmm5,xmm0
        +	movdqu	xmm8,XMMWORD PTR[96+rdi]
        +DB	102,15,56,222,225
        +	pxor	xmm6,xmm0
        +	movdqu	xmm9,XMMWORD PTR[112+rdi]
        +DB	102,15,56,222,233
        +	pxor	xmm7,xmm0
        +	dec	eax
        +DB	102,15,56,222,241
        +	pxor	xmm8,xmm0
        +DB	102,15,56,222,249
        +	pxor	xmm9,xmm0
        +	movups	xmm0,XMMWORD PTR[rcx]
        +DB	102,68,15,56,222,193
        +DB	102,68,15,56,222,201
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +
        +	call	$L$dec_loop8_enter
        +
        +	movups	xmm1,XMMWORD PTR[rdi]
        +	movups	xmm0,XMMWORD PTR[16+rdi]
        +	xorps	xmm2,XMMWORD PTR[64+rsp]
        +	xorps	xmm3,xmm1
        +	movups	xmm1,XMMWORD PTR[32+rdi]
        +	xorps	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR[48+rdi]
        +	xorps	xmm5,xmm1
        +	movups	xmm1,XMMWORD PTR[64+rdi]
        +	xorps	xmm6,xmm0
        +	movups	xmm0,XMMWORD PTR[80+rdi]
        +	xorps	xmm7,xmm1
        +	movups	xmm1,XMMWORD PTR[96+rdi]
        +	xorps	xmm8,xmm0
        +	movups	xmm0,XMMWORD PTR[112+rdi]
        +	xorps	xmm9,xmm1
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	mov	eax,r10d
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	mov	rcx,r11
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	lea	rdi,QWORD PTR[128+rdi]
        +	movups	XMMWORD PTR[96+rsi],xmm8
        +	lea	rsi,QWORD PTR[112+rsi]
        +	sub	rdx,080h
        +	ja	$L$cbc_dec_loop8
        +
        +	movaps	xmm2,xmm9
        +	movaps	xmm9,xmm0
        +	add	rdx,070h
        +	jle	$L$cbc_dec_tail_collected
        +	movups	XMMWORD PTR[rsi],xmm2
        +	lea	eax,DWORD PTR[1+r10*1+r10]
        +	lea	rsi,QWORD PTR[16+rsi]
        +$L$cbc_dec_tail::
        +	movups	xmm2,XMMWORD PTR[rdi]
        +	movaps	xmm8,xmm2
        +	cmp	rdx,010h
        +	jbe	$L$cbc_dec_one
        +
        +	movups	xmm3,XMMWORD PTR[16+rdi]
        +	movaps	xmm7,xmm3
        +	cmp	rdx,020h
        +	jbe	$L$cbc_dec_two
        +
        +	movups	xmm4,XMMWORD PTR[32+rdi]
        +	movaps	xmm6,xmm4
        +	cmp	rdx,030h
        +	jbe	$L$cbc_dec_three
        +
        +	movups	xmm5,XMMWORD PTR[48+rdi]
        +	cmp	rdx,040h
        +	jbe	$L$cbc_dec_four
        +
        +	movups	xmm6,XMMWORD PTR[64+rdi]
        +	cmp	rdx,050h
        +	jbe	$L$cbc_dec_five
        +
        +	movups	xmm7,XMMWORD PTR[80+rdi]
        +	cmp	rdx,060h
        +	jbe	$L$cbc_dec_six
        +
        +	movups	xmm8,XMMWORD PTR[96+rdi]
        +	movaps	XMMWORD PTR[64+rsp],xmm9
        +	call	_aesni_decrypt8
        +	movups	xmm1,XMMWORD PTR[rdi]
        +	movups	xmm0,XMMWORD PTR[16+rdi]
        +	xorps	xmm2,XMMWORD PTR[64+rsp]
        +	xorps	xmm3,xmm1
        +	movups	xmm1,XMMWORD PTR[32+rdi]
        +	xorps	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR[48+rdi]
        +	xorps	xmm5,xmm1
        +	movups	xmm1,XMMWORD PTR[64+rdi]
        +	xorps	xmm6,xmm0
        +	movups	xmm0,XMMWORD PTR[80+rdi]
        +	xorps	xmm7,xmm1
        +	movups	xmm9,XMMWORD PTR[96+rdi]
        +	xorps	xmm8,xmm0
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	movups	XMMWORD PTR[80+rsi],xmm7
        +	lea	rsi,QWORD PTR[96+rsi]
        +	movaps	xmm2,xmm8
        +	sub	rdx,070h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_one::
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	movups	xmm1,XMMWORD PTR[16+rcx]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	xorps	xmm2,xmm0
        +$L$oop_dec1_16::
        +DB	102,15,56,222,209
        +	dec	eax
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jnz	$L$oop_dec1_16
        +
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm9
        +	movaps	xmm9,xmm8
        +	sub	rdx,010h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_two::
        +	xorps	xmm4,xmm4
        +	call	_aesni_decrypt3
        +	xorps	xmm2,xmm9
        +	xorps	xmm3,xmm8
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movaps	xmm9,xmm7
        +	movaps	xmm2,xmm3
        +	lea	rsi,QWORD PTR[16+rsi]
        +	sub	rdx,020h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_three::
        +	call	_aesni_decrypt3
        +	xorps	xmm2,xmm9
        +	xorps	xmm3,xmm8
        +	movups	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movaps	xmm9,xmm6
        +	movaps	xmm2,xmm4
        +	lea	rsi,QWORD PTR[32+rsi]
        +	sub	rdx,030h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_four::
        +	call	_aesni_decrypt4
        +	xorps	xmm2,xmm9
        +	movups	xmm9,XMMWORD PTR[48+rdi]
        +	xorps	xmm3,xmm8
        +	movups	XMMWORD PTR[rsi],xmm2
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	xorps	xmm5,xmm6
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movaps	xmm2,xmm5
        +	lea	rsi,QWORD PTR[48+rsi]
        +	sub	rdx,040h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_five::
        +	xorps	xmm7,xmm7
        +	call	_aesni_decrypt6
        +	movups	xmm1,XMMWORD PTR[16+rdi]
        +	movups	xmm0,XMMWORD PTR[32+rdi]
        +	xorps	xmm2,xmm9
        +	xorps	xmm3,xmm8
        +	xorps	xmm4,xmm1
        +	movups	xmm1,XMMWORD PTR[48+rdi]
        +	xorps	xmm5,xmm0
        +	movups	xmm9,XMMWORD PTR[64+rdi]
        +	xorps	xmm6,xmm1
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	lea	rsi,QWORD PTR[64+rsi]
        +	movaps	xmm2,xmm6
        +	sub	rdx,050h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_six::
        +	call	_aesni_decrypt6
        +	movups	xmm1,XMMWORD PTR[16+rdi]
        +	movups	xmm0,XMMWORD PTR[32+rdi]
        +	xorps	xmm2,xmm9
        +	xorps	xmm3,xmm8
        +	xorps	xmm4,xmm1
        +	movups	xmm1,XMMWORD PTR[48+rdi]
        +	xorps	xmm5,xmm0
        +	movups	xmm0,XMMWORD PTR[64+rdi]
        +	xorps	xmm6,xmm1
        +	movups	xmm9,XMMWORD PTR[80+rdi]
        +	xorps	xmm7,xmm0
        +	movups	XMMWORD PTR[rsi],xmm2
        +	movups	XMMWORD PTR[16+rsi],xmm3
        +	movups	XMMWORD PTR[32+rsi],xmm4
        +	movups	XMMWORD PTR[48+rsi],xmm5
        +	movups	XMMWORD PTR[64+rsi],xmm6
        +	lea	rsi,QWORD PTR[80+rsi]
        +	movaps	xmm2,xmm7
        +	sub	rdx,060h
        +	jmp	$L$cbc_dec_tail_collected
        +ALIGN	16
        +$L$cbc_dec_tail_collected::
        +	and	rdx,15
        +	movups	XMMWORD PTR[r8],xmm9
        +	jnz	$L$cbc_dec_tail_partial
        +	movups	XMMWORD PTR[rsi],xmm2
        +	jmp	$L$cbc_dec_ret
        +ALIGN	16
        +$L$cbc_dec_tail_partial::
        +	movaps	XMMWORD PTR[64+rsp],xmm2
        +	mov	rcx,16
        +	mov	rdi,rsi
        +	sub	rcx,rdx
        +	lea	rsi,QWORD PTR[64+rsp]
        +	DD	09066A4F3h
        +
        +
        +$L$cbc_dec_ret::
        +	movaps	xmm6,XMMWORD PTR[rsp]
        +	movaps	xmm7,XMMWORD PTR[16+rsp]
        +	movaps	xmm8,XMMWORD PTR[32+rsp]
        +	movaps	xmm9,XMMWORD PTR[48+rsp]
        +	lea	rsp,QWORD PTR[88+rsp]
        +$L$cbc_ret::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_aesni_cbc_encrypt::
        +aesni_cbc_encrypt	ENDP
        +PUBLIC	aesni_set_decrypt_key
        +
        +ALIGN	16
        +aesni_set_decrypt_key	PROC PUBLIC
        +DB	048h,083h,0ECh,008h
        +
        +	call	__aesni_set_encrypt_key
        +	shl	edx,4
        +	test	eax,eax
        +	jnz	$L$dec_key_ret
        +	lea	rcx,QWORD PTR[16+rdx*1+r8]
        +
        +	movups	xmm0,XMMWORD PTR[r8]
        +	movups	xmm1,XMMWORD PTR[rcx]
        +	movups	XMMWORD PTR[rcx],xmm0
        +	movups	XMMWORD PTR[r8],xmm1
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	rcx,QWORD PTR[((-16))+rcx]
        +
        +$L$dec_key_inverse::
        +	movups	xmm0,XMMWORD PTR[r8]
        +	movups	xmm1,XMMWORD PTR[rcx]
        +DB	102,15,56,219,192
        +DB	102,15,56,219,201
        +	lea	r8,QWORD PTR[16+r8]
        +	lea	rcx,QWORD PTR[((-16))+rcx]
        +	movups	XMMWORD PTR[16+rcx],xmm0
        +	movups	XMMWORD PTR[(-16)+r8],xmm1
        +	cmp	rcx,r8
        +	ja	$L$dec_key_inverse
        +
        +	movups	xmm0,XMMWORD PTR[r8]
        +DB	102,15,56,219,192
        +	movups	XMMWORD PTR[rcx],xmm0
        +$L$dec_key_ret::
        +	add	rsp,8
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_set_decrypt_key::
        +aesni_set_decrypt_key	ENDP
        +PUBLIC	aesni_set_encrypt_key
        +
        +ALIGN	16
        +aesni_set_encrypt_key	PROC PUBLIC
        +__aesni_set_encrypt_key::
        +DB	048h,083h,0ECh,008h
        +
        +	mov	rax,-1
        +	test	rcx,rcx
        +	jz	$L$enc_key_ret
        +	test	r8,r8
        +	jz	$L$enc_key_ret
        +
        +	movups	xmm0,XMMWORD PTR[rcx]
        +	xorps	xmm4,xmm4
        +	lea	rax,QWORD PTR[16+r8]
        +	cmp	edx,256
        +	je	$L$14rounds
        +	cmp	edx,192
        +	je	$L$12rounds
        +	cmp	edx,128
        +	jne	$L$bad_keybits
        +
        +$L$10rounds::
        +	mov	edx,9
        +	movups	XMMWORD PTR[r8],xmm0
        +DB	102,15,58,223,200,1
        +	call	$L$key_expansion_128_cold
        +DB	102,15,58,223,200,2
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,4
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,8
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,16
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,32
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,64
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,128
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,27
        +	call	$L$key_expansion_128
        +DB	102,15,58,223,200,54
        +	call	$L$key_expansion_128
        +	movups	XMMWORD PTR[rax],xmm0
        +	mov	DWORD PTR[80+rax],edx
        +	xor	eax,eax
        +	jmp	$L$enc_key_ret
        +
        +ALIGN	16
        +$L$12rounds::
        +	movq	xmm2,QWORD PTR[16+rcx]
        +	mov	edx,11
        +	movups	XMMWORD PTR[r8],xmm0
        +DB	102,15,58,223,202,1
        +	call	$L$key_expansion_192a_cold
        +DB	102,15,58,223,202,2
        +	call	$L$key_expansion_192b
        +DB	102,15,58,223,202,4
        +	call	$L$key_expansion_192a
        +DB	102,15,58,223,202,8
        +	call	$L$key_expansion_192b
        +DB	102,15,58,223,202,16
        +	call	$L$key_expansion_192a
        +DB	102,15,58,223,202,32
        +	call	$L$key_expansion_192b
        +DB	102,15,58,223,202,64
        +	call	$L$key_expansion_192a
        +DB	102,15,58,223,202,128
        +	call	$L$key_expansion_192b
        +	movups	XMMWORD PTR[rax],xmm0
        +	mov	DWORD PTR[48+rax],edx
        +	xor	rax,rax
        +	jmp	$L$enc_key_ret
        +
        +ALIGN	16
        +$L$14rounds::
        +	movups	xmm2,XMMWORD PTR[16+rcx]
        +	mov	edx,13
        +	lea	rax,QWORD PTR[16+rax]
        +	movups	XMMWORD PTR[r8],xmm0
        +	movups	XMMWORD PTR[16+r8],xmm2
        +DB	102,15,58,223,202,1
        +	call	$L$key_expansion_256a_cold
        +DB	102,15,58,223,200,1
        +	call	$L$key_expansion_256b
        +DB	102,15,58,223,202,2
        +	call	$L$key_expansion_256a
        +DB	102,15,58,223,200,2
        +	call	$L$key_expansion_256b
        +DB	102,15,58,223,202,4
        +	call	$L$key_expansion_256a
        +DB	102,15,58,223,200,4
        +	call	$L$key_expansion_256b
        +DB	102,15,58,223,202,8
        +	call	$L$key_expansion_256a
        +DB	102,15,58,223,200,8
        +	call	$L$key_expansion_256b
        +DB	102,15,58,223,202,16
        +	call	$L$key_expansion_256a
        +DB	102,15,58,223,200,16
        +	call	$L$key_expansion_256b
        +DB	102,15,58,223,202,32
        +	call	$L$key_expansion_256a
        +DB	102,15,58,223,200,32
        +	call	$L$key_expansion_256b
        +DB	102,15,58,223,202,64
        +	call	$L$key_expansion_256a
        +	movups	XMMWORD PTR[rax],xmm0
        +	mov	DWORD PTR[16+rax],edx
        +	xor	rax,rax
        +	jmp	$L$enc_key_ret
        +
        +ALIGN	16
        +$L$bad_keybits::
        +	mov	rax,-2
        +$L$enc_key_ret::
        +	add	rsp,8
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_set_encrypt_key::
        +
        +ALIGN	16
        +$L$key_expansion_128::
        +	movups	XMMWORD PTR[rax],xmm0
        +	lea	rax,QWORD PTR[16+rax]
        +$L$key_expansion_128_cold::
        +	shufps	xmm4,xmm0,16
        +	xorps	xmm0,xmm4
        +	shufps	xmm4,xmm0,140
        +	xorps	xmm0,xmm4
        +	shufps	xmm1,xmm1,255
        +	xorps	xmm0,xmm1
        +	DB	0F3h,0C3h		;repret
        +
        +ALIGN	16
        +$L$key_expansion_192a::
        +	movups	XMMWORD PTR[rax],xmm0
        +	lea	rax,QWORD PTR[16+rax]
        +$L$key_expansion_192a_cold::
        +	movaps	xmm5,xmm2
        +$L$key_expansion_192b_warm::
        +	shufps	xmm4,xmm0,16
        +	movdqa	xmm3,xmm2
        +	xorps	xmm0,xmm4
        +	shufps	xmm4,xmm0,140
        +	pslldq	xmm3,4
        +	xorps	xmm0,xmm4
        +	pshufd	xmm1,xmm1,85
        +	pxor	xmm2,xmm3
        +	pxor	xmm0,xmm1
        +	pshufd	xmm3,xmm0,255
        +	pxor	xmm2,xmm3
        +	DB	0F3h,0C3h		;repret
        +
        +ALIGN	16
        +$L$key_expansion_192b::
        +	movaps	xmm3,xmm0
        +	shufps	xmm5,xmm0,68
        +	movups	XMMWORD PTR[rax],xmm5
        +	shufps	xmm3,xmm2,78
        +	movups	XMMWORD PTR[16+rax],xmm3
        +	lea	rax,QWORD PTR[32+rax]
        +	jmp	$L$key_expansion_192b_warm
        +
        +ALIGN	16
        +$L$key_expansion_256a::
        +	movups	XMMWORD PTR[rax],xmm2
        +	lea	rax,QWORD PTR[16+rax]
        +$L$key_expansion_256a_cold::
        +	shufps	xmm4,xmm0,16
        +	xorps	xmm0,xmm4
        +	shufps	xmm4,xmm0,140
        +	xorps	xmm0,xmm4
        +	shufps	xmm1,xmm1,255
        +	xorps	xmm0,xmm1
        +	DB	0F3h,0C3h		;repret
        +
        +ALIGN	16
        +$L$key_expansion_256b::
        +	movups	XMMWORD PTR[rax],xmm0
        +	lea	rax,QWORD PTR[16+rax]
        +
        +	shufps	xmm4,xmm2,16
        +	xorps	xmm2,xmm4
        +	shufps	xmm4,xmm2,140
        +	xorps	xmm2,xmm4
        +	shufps	xmm1,xmm1,170
        +	xorps	xmm2,xmm1
        +	DB	0F3h,0C3h		;repret
        +aesni_set_encrypt_key	ENDP
        +
        +ALIGN	64
        +$L$bswap_mask::
        +DB	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
        +$L$increment32::
        +	DD	6,6,6,0
        +$L$increment64::
        +	DD	1,0,0,0
        +$L$xts_magic::
        +	DD	087h,0,1,0
        +
        +DB	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
        +DB	83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
        +DB	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +DB	115,108,46,111,114,103,62,0
        +ALIGN	64
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +ecb_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	jmp	$L$common_seh_tail
        +ecb_se_handler	ENDP
        +
        +
        +ALIGN	16
        +ccm64_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	lea	rsi,QWORD PTR[rax]
        +	lea	rdi,QWORD PTR[512+r8]
        +	mov	ecx,8
        +	DD	0a548f3fch
        +
        +	lea	rax,QWORD PTR[88+rax]
        +
        +	jmp	$L$common_seh_tail
        +ccm64_se_handler	ENDP
        +
        +
        +ALIGN	16
        +ctr32_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$ctr32_body]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$ctr32_ret]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	lea	rsi,QWORD PTR[32+rax]
        +	lea	rdi,QWORD PTR[512+r8]
        +	mov	ecx,20
        +	DD	0a548f3fch
        +
        +	lea	rax,QWORD PTR[200+rax]
        +
        +	jmp	$L$common_seh_tail
        +ctr32_se_handler	ENDP
        +
        +
        +ALIGN	16
        +xts_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	lea	rsi,QWORD PTR[96+rax]
        +	lea	rdi,QWORD PTR[512+r8]
        +	mov	ecx,20
        +	DD	0a548f3fch
        +
        +	lea	rax,QWORD PTR[((104+160))+rax]
        +
        +	jmp	$L$common_seh_tail
        +xts_se_handler	ENDP
        +
        +ALIGN	16
        +cbc_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[152+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$cbc_decrypt]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	lea	r10,QWORD PTR[$L$cbc_decrypt_body]
        +	cmp	rbx,r10
        +	jb	$L$restore_cbc_rax
        +
        +	lea	r10,QWORD PTR[$L$cbc_ret]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	lea	rsi,QWORD PTR[rax]
        +	lea	rdi,QWORD PTR[512+r8]
        +	mov	ecx,8
        +	DD	0a548f3fch
        +
        +	lea	rax,QWORD PTR[88+rax]
        +	jmp	$L$common_seh_tail
        +
        +$L$restore_cbc_rax::
        +	mov	rax,QWORD PTR[120+r8]
        +
        +$L$common_seh_tail::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +cbc_se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_aesni_ecb_encrypt
        +	DD	imagerel $L$SEH_end_aesni_ecb_encrypt
        +	DD	imagerel $L$SEH_info_ecb
        +
        +	DD	imagerel $L$SEH_begin_aesni_ccm64_encrypt_blocks
        +	DD	imagerel $L$SEH_end_aesni_ccm64_encrypt_blocks
        +	DD	imagerel $L$SEH_info_ccm64_enc
        +
        +	DD	imagerel $L$SEH_begin_aesni_ccm64_decrypt_blocks
        +	DD	imagerel $L$SEH_end_aesni_ccm64_decrypt_blocks
        +	DD	imagerel $L$SEH_info_ccm64_dec
        +
        +	DD	imagerel $L$SEH_begin_aesni_ctr32_encrypt_blocks
        +	DD	imagerel $L$SEH_end_aesni_ctr32_encrypt_blocks
        +	DD	imagerel $L$SEH_info_ctr32
        +
        +	DD	imagerel $L$SEH_begin_aesni_xts_encrypt
        +	DD	imagerel $L$SEH_end_aesni_xts_encrypt
        +	DD	imagerel $L$SEH_info_xts_enc
        +
        +	DD	imagerel $L$SEH_begin_aesni_xts_decrypt
        +	DD	imagerel $L$SEH_end_aesni_xts_decrypt
        +	DD	imagerel $L$SEH_info_xts_dec
        +	DD	imagerel $L$SEH_begin_aesni_cbc_encrypt
        +	DD	imagerel $L$SEH_end_aesni_cbc_encrypt
        +	DD	imagerel $L$SEH_info_cbc
        +
        +	DD	imagerel aesni_set_decrypt_key
        +	DD	imagerel $L$SEH_end_set_decrypt_key
        +	DD	imagerel $L$SEH_info_key
        +
        +	DD	imagerel aesni_set_encrypt_key
        +	DD	imagerel $L$SEH_end_set_encrypt_key
        +	DD	imagerel $L$SEH_info_key
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_ecb::
        +DB	9,0,0,0
        +	DD	imagerel ecb_se_handler
        +$L$SEH_info_ccm64_enc::
        +DB	9,0,0,0
        +	DD	imagerel ccm64_se_handler
        +	DD	imagerel $L$ccm64_enc_body,imagerel $L$ccm64_enc_ret
        +
        +$L$SEH_info_ccm64_dec::
        +DB	9,0,0,0
        +	DD	imagerel ccm64_se_handler
        +	DD	imagerel $L$ccm64_dec_body,imagerel $L$ccm64_dec_ret
        +
        +$L$SEH_info_ctr32::
        +DB	9,0,0,0
        +	DD	imagerel ctr32_se_handler
        +$L$SEH_info_xts_enc::
        +DB	9,0,0,0
        +	DD	imagerel xts_se_handler
        +	DD	imagerel $L$xts_enc_body,imagerel $L$xts_enc_epilogue
        +
        +$L$SEH_info_xts_dec::
        +DB	9,0,0,0
        +	DD	imagerel xts_se_handler
        +	DD	imagerel $L$xts_dec_body,imagerel $L$xts_dec_epilogue
        +
        +$L$SEH_info_cbc::
        +DB	9,0,0,0
        +	DD	imagerel cbc_se_handler
        +$L$SEH_info_key::
        +DB	001h,004h,001h,000h
        +DB	004h,002h,000h,000h
        +
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm
        new file mode 100644
        index 000000000..b83aa18d4
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/bn/modexp512-x86_64.asm
        @@ -0,0 +1,1890 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +
        +ALIGN	16
        +MULADD_128x512	PROC PRIVATE
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[rcx],r8
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	r8,rdx
        +	mov	rbp,QWORD PTR[8+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[8+rcx],r9
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	r9,rdx
        +	DB	0F3h,0C3h		;repret
        +MULADD_128x512	ENDP
        +
        +ALIGN	16
        +mont_reduce	PROC PRIVATE
        +	lea	rdi,QWORD PTR[192+rsp]
        +	mov	rsi,QWORD PTR[32+rsp]
        +	add	rsi,576
        +	lea	rcx,QWORD PTR[520+rsp]
        +
        +	mov	rbp,QWORD PTR[96+rcx]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	mov	r8,QWORD PTR[rcx]
        +	add	r8,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[rdi],r8
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	mov	r9,QWORD PTR[8+rcx]
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	mov	r10,QWORD PTR[16+rcx]
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	mov	r11,QWORD PTR[24+rcx]
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	mov	r12,QWORD PTR[32+rcx]
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	mov	r13,QWORD PTR[40+rcx]
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	mov	r14,QWORD PTR[48+rcx]
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	mov	r15,QWORD PTR[56+rcx]
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	r8,rdx
        +	mov	rbp,QWORD PTR[104+rcx]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[8+rdi],r9
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	r9,rdx
        +	mov	rbp,QWORD PTR[112+rcx]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[16+rdi],r10
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	r10,rdx
        +	mov	rbp,QWORD PTR[120+rcx]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[24+rdi],r11
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	r11,rdx
        +	xor	rax,rax
        +
        +	add	r8,QWORD PTR[64+rcx]
        +	adc	r9,QWORD PTR[72+rcx]
        +	adc	r10,QWORD PTR[80+rcx]
        +	adc	r11,QWORD PTR[88+rcx]
        +	adc	rax,0
        +
        +
        +
        +
        +	mov	QWORD PTR[64+rdi],r8
        +	mov	QWORD PTR[72+rdi],r9
        +	mov	rbp,r10
        +	mov	QWORD PTR[88+rdi],r11
        +
        +	mov	QWORD PTR[384+rsp],rax
        +
        +	mov	r8,QWORD PTR[rdi]
        +	mov	r9,QWORD PTR[8+rdi]
        +	mov	r10,QWORD PTR[16+rdi]
        +	mov	r11,QWORD PTR[24+rdi]
        +
        +
        +
        +
        +
        +
        +
        +
        +	add	rdi,8*10
        +
        +	add	rsi,64
        +	lea	rcx,QWORD PTR[296+rsp]
        +
        +	call	MULADD_128x512
        +
        +
        +	mov	rax,QWORD PTR[384+rsp]
        +
        +
        +	add	r8,QWORD PTR[((-16))+rdi]
        +	adc	r9,QWORD PTR[((-8))+rdi]
        +	mov	QWORD PTR[64+rcx],r8
        +	mov	QWORD PTR[72+rcx],r9
        +
        +	adc	rax,rax
        +	mov	QWORD PTR[384+rsp],rax
        +
        +	lea	rdi,QWORD PTR[192+rsp]
        +	add	rsi,64
        +
        +
        +
        +
        +
        +	mov	r8,QWORD PTR[rsi]
        +	mov	rbx,QWORD PTR[8+rsi]
        +
        +	mov	rax,QWORD PTR[rcx]
        +	mul	r8
        +	mov	rbp,rax
        +	mov	r9,rdx
        +
        +	mov	rax,QWORD PTR[8+rcx]
        +	mul	r8
        +	add	r9,rax
        +
        +	mov	rax,QWORD PTR[rcx]
        +	mul	rbx
        +	add	r9,rax
        +
        +	mov	QWORD PTR[8+rdi],r9
        +
        +
        +	sub	rsi,192
        +
        +	mov	r8,QWORD PTR[rcx]
        +	mov	r9,QWORD PTR[8+rcx]
        +
        +	call	MULADD_128x512
        +
        +
        +
        +
        +
        +	mov	rax,QWORD PTR[rsi]
        +	mov	rbx,QWORD PTR[8+rsi]
        +	mov	rdi,QWORD PTR[16+rsi]
        +	mov	rdx,QWORD PTR[24+rsi]
        +
        +
        +	mov	rbp,QWORD PTR[384+rsp]
        +
        +	add	r8,QWORD PTR[64+rcx]
        +	adc	r9,QWORD PTR[72+rcx]
        +
        +
        +	adc	rbp,rbp
        +
        +
        +
        +	shl	rbp,3
        +	mov	rcx,QWORD PTR[32+rsp]
        +	add	rbp,rcx
        +
        +
        +	xor	rsi,rsi
        +
        +	add	r10,QWORD PTR[rbp]
        +	adc	r11,QWORD PTR[64+rbp]
        +	adc	r12,QWORD PTR[128+rbp]
        +	adc	r13,QWORD PTR[192+rbp]
        +	adc	r14,QWORD PTR[256+rbp]
        +	adc	r15,QWORD PTR[320+rbp]
        +	adc	r8,QWORD PTR[384+rbp]
        +	adc	r9,QWORD PTR[448+rbp]
        +
        +
        +
        +	sbb	rsi,0
        +
        +
        +	and	rax,rsi
        +	and	rbx,rsi
        +	and	rdi,rsi
        +	and	rdx,rsi
        +
        +	mov	rbp,1
        +	sub	r10,rax
        +	sbb	r11,rbx
        +	sbb	r12,rdi
        +	sbb	r13,rdx
        +
        +
        +
        +
        +	sbb	rbp,0
        +
        +
        +
        +	add	rcx,512
        +	mov	rax,QWORD PTR[32+rcx]
        +	mov	rbx,QWORD PTR[40+rcx]
        +	mov	rdi,QWORD PTR[48+rcx]
        +	mov	rdx,QWORD PTR[56+rcx]
        +
        +
        +
        +	and	rax,rsi
        +	and	rbx,rsi
        +	and	rdi,rsi
        +	and	rdx,rsi
        +
        +
        +
        +	sub	rbp,1
        +
        +	sbb	r14,rax
        +	sbb	r15,rbx
        +	sbb	r8,rdi
        +	sbb	r9,rdx
        +
        +
        +
        +	mov	rsi,QWORD PTR[144+rsp]
        +	mov	QWORD PTR[rsi],r10
        +	mov	QWORD PTR[8+rsi],r11
        +	mov	QWORD PTR[16+rsi],r12
        +	mov	QWORD PTR[24+rsi],r13
        +	mov	QWORD PTR[32+rsi],r14
        +	mov	QWORD PTR[40+rsi],r15
        +	mov	QWORD PTR[48+rsi],r8
        +	mov	QWORD PTR[56+rsi],r9
        +
        +	DB	0F3h,0C3h		;repret
        +mont_reduce	ENDP
        +
        +ALIGN	16
        +mont_mul_a3b	PROC PRIVATE
        +
        +
        +
        +
        +	mov	rbp,QWORD PTR[rdi]
        +
        +	mov	rax,r10
        +	mul	rbp
        +	mov	QWORD PTR[520+rsp],rax
        +	mov	r10,rdx
        +	mov	rax,r11
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	mov	r11,rdx
        +	mov	rax,r12
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	mov	r12,rdx
        +	mov	rax,r13
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	mov	r13,rdx
        +	mov	rax,r14
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	mov	r14,rdx
        +	mov	rax,r15
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	mov	r15,rdx
        +	mov	rax,r8
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	mov	r8,rdx
        +	mov	rax,r9
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	mov	r9,rdx
        +	mov	rbp,QWORD PTR[8+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[528+rsp],r10
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	r10,rdx
        +	mov	rbp,QWORD PTR[16+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[536+rsp],r11
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	r11,rdx
        +	mov	rbp,QWORD PTR[24+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[544+rsp],r12
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	r12,rdx
        +	mov	rbp,QWORD PTR[32+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[552+rsp],r13
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	r13,rdx
        +	mov	rbp,QWORD PTR[40+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[560+rsp],r14
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	r14,rdx
        +	mov	rbp,QWORD PTR[48+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[568+rsp],r15
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	add	r8,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	r15,rdx
        +	mov	rbp,QWORD PTR[56+rdi]
        +	mov	rax,QWORD PTR[rsi]
        +	mul	rbp
        +	add	r8,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[576+rsp],r8
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rsi]
        +	mul	rbp
        +	add	r9,rax
        +	adc	rdx,0
        +	add	r9,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[16+rsi]
        +	mul	rbp
        +	add	r10,rax
        +	adc	rdx,0
        +	add	r10,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[24+rsi]
        +	mul	rbp
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[32+rsi]
        +	mul	rbp
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[40+rsi]
        +	mul	rbp
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[48+rsi]
        +	mul	rbp
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,rbx
        +	adc	rdx,0
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[56+rsi]
        +	mul	rbp
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,rbx
        +	adc	rdx,0
        +	mov	r8,rdx
        +	mov	QWORD PTR[584+rsp],r9
        +	mov	QWORD PTR[592+rsp],r10
        +	mov	QWORD PTR[600+rsp],r11
        +	mov	QWORD PTR[608+rsp],r12
        +	mov	QWORD PTR[616+rsp],r13
        +	mov	QWORD PTR[624+rsp],r14
        +	mov	QWORD PTR[632+rsp],r15
        +	mov	QWORD PTR[640+rsp],r8
        +
        +
        +
        +
        +
        +	jmp	mont_reduce
        +
        +
        +mont_mul_a3b	ENDP
        +
        +ALIGN	16
        +sqr_reduce	PROC PRIVATE
        +	mov	rcx,QWORD PTR[16+rsp]
        +
        +
        +
        +	mov	rbx,r10
        +
        +	mov	rax,r11
        +	mul	rbx
        +	mov	QWORD PTR[528+rsp],rax
        +	mov	r10,rdx
        +	mov	rax,r12
        +	mul	rbx
        +	add	r10,rax
        +	adc	rdx,0
        +	mov	r11,rdx
        +	mov	rax,r13
        +	mul	rbx
        +	add	r11,rax
        +	adc	rdx,0
        +	mov	r12,rdx
        +	mov	rax,r14
        +	mul	rbx
        +	add	r12,rax
        +	adc	rdx,0
        +	mov	r13,rdx
        +	mov	rax,r15
        +	mul	rbx
        +	add	r13,rax
        +	adc	rdx,0
        +	mov	r14,rdx
        +	mov	rax,r8
        +	mul	rbx
        +	add	r14,rax
        +	adc	rdx,0
        +	mov	r15,rdx
        +	mov	rax,r9
        +	mul	rbx
        +	add	r15,rax
        +	adc	rdx,0
        +	mov	rsi,rdx
        +
        +	mov	QWORD PTR[536+rsp],r10
        +
        +
        +
        +
        +
        +	mov	rbx,QWORD PTR[8+rcx]
        +
        +	mov	rax,QWORD PTR[16+rcx]
        +	mul	rbx
        +	add	r11,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[544+rsp],r11
        +
        +	mov	r10,rdx
        +	mov	rax,QWORD PTR[24+rcx]
        +	mul	rbx
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[552+rsp],r12
        +
        +	mov	r10,rdx
        +	mov	rax,QWORD PTR[32+rcx]
        +	mul	rbx
        +	add	r13,rax
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +
        +	mov	r10,rdx
        +	mov	rax,QWORD PTR[40+rcx]
        +	mul	rbx
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,r10
        +	adc	rdx,0
        +
        +	mov	r10,rdx
        +	mov	rax,r8
        +	mul	rbx
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,r10
        +	adc	rdx,0
        +
        +	mov	r10,rdx
        +	mov	rax,r9
        +	mul	rbx
        +	add	rsi,rax
        +	adc	rdx,0
        +	add	rsi,r10
        +	adc	rdx,0
        +
        +	mov	r11,rdx
        +
        +
        +
        +
        +	mov	rbx,QWORD PTR[16+rcx]
        +
        +	mov	rax,QWORD PTR[24+rcx]
        +	mul	rbx
        +	add	r13,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[560+rsp],r13
        +
        +	mov	r10,rdx
        +	mov	rax,QWORD PTR[32+rcx]
        +	mul	rbx
        +	add	r14,rax
        +	adc	rdx,0
        +	add	r14,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[568+rsp],r14
        +
        +	mov	r10,rdx
        +	mov	rax,QWORD PTR[40+rcx]
        +	mul	rbx
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,r10
        +	adc	rdx,0
        +
        +	mov	r10,rdx
        +	mov	rax,r8
        +	mul	rbx
        +	add	rsi,rax
        +	adc	rdx,0
        +	add	rsi,r10
        +	adc	rdx,0
        +
        +	mov	r10,rdx
        +	mov	rax,r9
        +	mul	rbx
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,r10
        +	adc	rdx,0
        +
        +	mov	r12,rdx
        +
        +
        +
        +
        +
        +	mov	rbx,QWORD PTR[24+rcx]
        +
        +	mov	rax,QWORD PTR[32+rcx]
        +	mul	rbx
        +	add	r15,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[576+rsp],r15
        +
        +	mov	r10,rdx
        +	mov	rax,QWORD PTR[40+rcx]
        +	mul	rbx
        +	add	rsi,rax
        +	adc	rdx,0
        +	add	rsi,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[584+rsp],rsi
        +
        +	mov	r10,rdx
        +	mov	rax,r8
        +	mul	rbx
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,r10
        +	adc	rdx,0
        +
        +	mov	r10,rdx
        +	mov	rax,r9
        +	mul	rbx
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,r10
        +	adc	rdx,0
        +
        +	mov	r15,rdx
        +
        +
        +
        +
        +	mov	rbx,QWORD PTR[32+rcx]
        +
        +	mov	rax,QWORD PTR[40+rcx]
        +	mul	rbx
        +	add	r11,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[592+rsp],r11
        +
        +	mov	r10,rdx
        +	mov	rax,r8
        +	mul	rbx
        +	add	r12,rax
        +	adc	rdx,0
        +	add	r12,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[600+rsp],r12
        +
        +	mov	r10,rdx
        +	mov	rax,r9
        +	mul	rbx
        +	add	r15,rax
        +	adc	rdx,0
        +	add	r15,r10
        +	adc	rdx,0
        +
        +	mov	r11,rdx
        +
        +
        +
        +
        +	mov	rbx,QWORD PTR[40+rcx]
        +
        +	mov	rax,r8
        +	mul	rbx
        +	add	r15,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[608+rsp],r15
        +
        +	mov	r10,rdx
        +	mov	rax,r9
        +	mul	rbx
        +	add	r11,rax
        +	adc	rdx,0
        +	add	r11,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[616+rsp],r11
        +
        +	mov	r12,rdx
        +
        +
        +
        +
        +	mov	rbx,r8
        +
        +	mov	rax,r9
        +	mul	rbx
        +	add	r12,rax
        +	adc	rdx,0
        +	mov	QWORD PTR[624+rsp],r12
        +
        +	mov	QWORD PTR[632+rsp],rdx
        +
        +
        +	mov	r10,QWORD PTR[528+rsp]
        +	mov	r11,QWORD PTR[536+rsp]
        +	mov	r12,QWORD PTR[544+rsp]
        +	mov	r13,QWORD PTR[552+rsp]
        +	mov	r14,QWORD PTR[560+rsp]
        +	mov	r15,QWORD PTR[568+rsp]
        +
        +	mov	rax,QWORD PTR[24+rcx]
        +	mul	rax
        +	mov	rdi,rax
        +	mov	r8,rdx
        +
        +	add	r10,r10
        +	adc	r11,r11
        +	adc	r12,r12
        +	adc	r13,r13
        +	adc	r14,r14
        +	adc	r15,r15
        +	adc	r8,0
        +
        +	mov	rax,QWORD PTR[rcx]
        +	mul	rax
        +	mov	QWORD PTR[520+rsp],rax
        +	mov	rbx,rdx
        +
        +	mov	rax,QWORD PTR[8+rcx]
        +	mul	rax
        +
        +	add	r10,rbx
        +	adc	r11,rax
        +	adc	rdx,0
        +
        +	mov	rbx,rdx
        +	mov	QWORD PTR[528+rsp],r10
        +	mov	QWORD PTR[536+rsp],r11
        +
        +	mov	rax,QWORD PTR[16+rcx]
        +	mul	rax
        +
        +	add	r12,rbx
        +	adc	r13,rax
        +	adc	rdx,0
        +
        +	mov	rbx,rdx
        +
        +	mov	QWORD PTR[544+rsp],r12
        +	mov	QWORD PTR[552+rsp],r13
        +
        +	xor	rbp,rbp
        +	add	r14,rbx
        +	adc	r15,rdi
        +	adc	rbp,0
        +
        +	mov	QWORD PTR[560+rsp],r14
        +	mov	QWORD PTR[568+rsp],r15
        +
        +
        +
        +
        +	mov	r10,QWORD PTR[576+rsp]
        +	mov	r11,QWORD PTR[584+rsp]
        +	mov	r12,QWORD PTR[592+rsp]
        +	mov	r13,QWORD PTR[600+rsp]
        +	mov	r14,QWORD PTR[608+rsp]
        +	mov	r15,QWORD PTR[616+rsp]
        +	mov	rdi,QWORD PTR[624+rsp]
        +	mov	rsi,QWORD PTR[632+rsp]
        +
        +	mov	rax,r9
        +	mul	rax
        +	mov	r9,rax
        +	mov	rbx,rdx
        +
        +	add	r10,r10
        +	adc	r11,r11
        +	adc	r12,r12
        +	adc	r13,r13
        +	adc	r14,r14
        +	adc	r15,r15
        +	adc	rdi,rdi
        +	adc	rsi,rsi
        +	adc	rbx,0
        +
        +	add	r10,rbp
        +
        +	mov	rax,QWORD PTR[32+rcx]
        +	mul	rax
        +
        +	add	r10,r8
        +	adc	r11,rax
        +	adc	rdx,0
        +
        +	mov	rbp,rdx
        +
        +	mov	QWORD PTR[576+rsp],r10
        +	mov	QWORD PTR[584+rsp],r11
        +
        +	mov	rax,QWORD PTR[40+rcx]
        +	mul	rax
        +
        +	add	r12,rbp
        +	adc	r13,rax
        +	adc	rdx,0
        +
        +	mov	rbp,rdx
        +
        +	mov	QWORD PTR[592+rsp],r12
        +	mov	QWORD PTR[600+rsp],r13
        +
        +	mov	rax,QWORD PTR[48+rcx]
        +	mul	rax
        +
        +	add	r14,rbp
        +	adc	r15,rax
        +	adc	rdx,0
        +
        +	mov	QWORD PTR[608+rsp],r14
        +	mov	QWORD PTR[616+rsp],r15
        +
        +	add	rdi,rdx
        +	adc	rsi,r9
        +	adc	rbx,0
        +
        +	mov	QWORD PTR[624+rsp],rdi
        +	mov	QWORD PTR[632+rsp],rsi
        +	mov	QWORD PTR[640+rsp],rbx
        +
        +	jmp	mont_reduce
        +
        +
        +sqr_reduce	ENDP
        +PUBLIC	mod_exp_512
        +
        +mod_exp_512	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_mod_exp_512::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +
        +
        +	push	rbp
        +	push	rbx
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +
        +	mov	r8,rsp
        +	sub	rsp,2688
        +	and	rsp,-64
        +
        +
        +	mov	QWORD PTR[rsp],r8
        +	mov	QWORD PTR[8+rsp],rdi
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	QWORD PTR[24+rsp],rcx
        +$L$body::
        +
        +
        +
        +	pxor	xmm4,xmm4
        +	movdqu	xmm0,XMMWORD PTR[rsi]
        +	movdqu	xmm1,XMMWORD PTR[16+rsi]
        +	movdqu	xmm2,XMMWORD PTR[32+rsi]
        +	movdqu	xmm3,XMMWORD PTR[48+rsi]
        +	movdqa	XMMWORD PTR[512+rsp],xmm4
        +	movdqa	XMMWORD PTR[528+rsp],xmm4
        +	movdqa	XMMWORD PTR[608+rsp],xmm4
        +	movdqa	XMMWORD PTR[624+rsp],xmm4
        +	movdqa	XMMWORD PTR[544+rsp],xmm0
        +	movdqa	XMMWORD PTR[560+rsp],xmm1
        +	movdqa	XMMWORD PTR[576+rsp],xmm2
        +	movdqa	XMMWORD PTR[592+rsp],xmm3
        +
        +
        +	movdqu	xmm0,XMMWORD PTR[rdx]
        +	movdqu	xmm1,XMMWORD PTR[16+rdx]
        +	movdqu	xmm2,XMMWORD PTR[32+rdx]
        +	movdqu	xmm3,XMMWORD PTR[48+rdx]
        +
        +	lea	rbx,QWORD PTR[384+rsp]
        +	mov	QWORD PTR[136+rsp],rbx
        +	call	mont_reduce
        +
        +
        +	lea	rcx,QWORD PTR[448+rsp]
        +	xor	rax,rax
        +	mov	QWORD PTR[rcx],rax
        +	mov	QWORD PTR[8+rcx],rax
        +	mov	QWORD PTR[24+rcx],rax
        +	mov	QWORD PTR[32+rcx],rax
        +	mov	QWORD PTR[40+rcx],rax
        +	mov	QWORD PTR[48+rcx],rax
        +	mov	QWORD PTR[56+rcx],rax
        +	mov	QWORD PTR[128+rsp],rax
        +	mov	QWORD PTR[16+rcx],1
        +
        +	lea	rbp,QWORD PTR[640+rsp]
        +	mov	rsi,rcx
        +	mov	rdi,rbp
        +	mov	rax,8
        +loop_0::
        +	mov	rbx,QWORD PTR[rcx]
        +	mov	WORD PTR[rdi],bx
        +	shr	rbx,16
        +	mov	WORD PTR[64+rdi],bx
        +	shr	rbx,16
        +	mov	WORD PTR[128+rdi],bx
        +	shr	rbx,16
        +	mov	WORD PTR[192+rdi],bx
        +	lea	rcx,QWORD PTR[8+rcx]
        +	lea	rdi,QWORD PTR[256+rdi]
        +	dec	rax
        +	jnz	loop_0
        +	mov	rax,31
        +	mov	QWORD PTR[32+rsp],rax
        +	mov	QWORD PTR[40+rsp],rbp
        +
        +	mov	QWORD PTR[136+rsp],rsi
        +	mov	r10,QWORD PTR[rsi]
        +	mov	r11,QWORD PTR[8+rsi]
        +	mov	r12,QWORD PTR[16+rsi]
        +	mov	r13,QWORD PTR[24+rsi]
        +	mov	r14,QWORD PTR[32+rsi]
        +	mov	r15,QWORD PTR[40+rsi]
        +	mov	r8,QWORD PTR[48+rsi]
        +	mov	r9,QWORD PTR[56+rsi]
        +init_loop::
        +	lea	rdi,QWORD PTR[384+rsp]
        +	call	mont_mul_a3b
        +	lea	rsi,QWORD PTR[448+rsp]
        +	mov	rbp,QWORD PTR[40+rsp]
        +	add	rbp,2
        +	mov	QWORD PTR[40+rsp],rbp
        +	mov	rcx,rsi
        +	mov	rax,8
        +loop_1::
        +	mov	rbx,QWORD PTR[rcx]
        +	mov	WORD PTR[rbp],bx
        +	shr	rbx,16
        +	mov	WORD PTR[64+rbp],bx
        +	shr	rbx,16
        +	mov	WORD PTR[128+rbp],bx
        +	shr	rbx,16
        +	mov	WORD PTR[192+rbp],bx
        +	lea	rcx,QWORD PTR[8+rcx]
        +	lea	rbp,QWORD PTR[256+rbp]
        +	dec	rax
        +	jnz	loop_1
        +	mov	rax,QWORD PTR[32+rsp]
        +	sub	rax,1
        +	mov	QWORD PTR[32+rsp],rax
        +	jne	init_loop
        +
        +
        +
        +	movdqa	XMMWORD PTR[64+rsp],xmm0
        +	movdqa	XMMWORD PTR[80+rsp],xmm1
        +	movdqa	XMMWORD PTR[96+rsp],xmm2
        +	movdqa	XMMWORD PTR[112+rsp],xmm3
        +
        +
        +
        +
        +
        +	mov	eax,DWORD PTR[126+rsp]
        +	mov	rdx,rax
        +	shr	rax,11
        +	and	edx,007FFh
        +	mov	DWORD PTR[126+rsp],edx
        +	lea	rsi,QWORD PTR[640+rax*2+rsp]
        +	mov	rdx,QWORD PTR[8+rsp]
        +	mov	rbp,4
        +loop_2::
        +	movzx	rbx,WORD PTR[192+rsi]
        +	movzx	rax,WORD PTR[448+rsi]
        +	shl	rbx,16
        +	shl	rax,16
        +	mov	bx,WORD PTR[128+rsi]
        +	mov	ax,WORD PTR[384+rsi]
        +	shl	rbx,16
        +	shl	rax,16
        +	mov	bx,WORD PTR[64+rsi]
        +	mov	ax,WORD PTR[320+rsi]
        +	shl	rbx,16
        +	shl	rax,16
        +	mov	bx,WORD PTR[rsi]
        +	mov	ax,WORD PTR[256+rsi]
        +	mov	QWORD PTR[rdx],rbx
        +	mov	QWORD PTR[8+rdx],rax
        +	lea	rsi,QWORD PTR[512+rsi]
        +	lea	rdx,QWORD PTR[16+rdx]
        +	sub	rbp,1
        +	jnz	loop_2
        +	mov	QWORD PTR[48+rsp],505
        +
        +	mov	rcx,QWORD PTR[8+rsp]
        +	mov	QWORD PTR[136+rsp],rcx
        +	mov	r10,QWORD PTR[rcx]
        +	mov	r11,QWORD PTR[8+rcx]
        +	mov	r12,QWORD PTR[16+rcx]
        +	mov	r13,QWORD PTR[24+rcx]
        +	mov	r14,QWORD PTR[32+rcx]
        +	mov	r15,QWORD PTR[40+rcx]
        +	mov	r8,QWORD PTR[48+rcx]
        +	mov	r9,QWORD PTR[56+rcx]
        +	jmp	sqr_2
        +
        +main_loop_a3b::
        +	call	sqr_reduce
        +	call	sqr_reduce
        +	call	sqr_reduce
        +sqr_2::
        +	call	sqr_reduce
        +	call	sqr_reduce
        +
        +
        +
        +	mov	rcx,QWORD PTR[48+rsp]
        +	mov	rax,rcx
        +	shr	rax,4
        +	mov	edx,DWORD PTR[64+rax*2+rsp]
        +	and	rcx,15
        +	shr	rdx,cl
        +	and	rdx,01Fh
        +
        +	lea	rsi,QWORD PTR[640+rdx*2+rsp]
        +	lea	rdx,QWORD PTR[448+rsp]
        +	mov	rdi,rdx
        +	mov	rbp,4
        +loop_3::
        +	movzx	rbx,WORD PTR[192+rsi]
        +	movzx	rax,WORD PTR[448+rsi]
        +	shl	rbx,16
        +	shl	rax,16
        +	mov	bx,WORD PTR[128+rsi]
        +	mov	ax,WORD PTR[384+rsi]
        +	shl	rbx,16
        +	shl	rax,16
        +	mov	bx,WORD PTR[64+rsi]
        +	mov	ax,WORD PTR[320+rsi]
        +	shl	rbx,16
        +	shl	rax,16
        +	mov	bx,WORD PTR[rsi]
        +	mov	ax,WORD PTR[256+rsi]
        +	mov	QWORD PTR[rdx],rbx
        +	mov	QWORD PTR[8+rdx],rax
        +	lea	rsi,QWORD PTR[512+rsi]
        +	lea	rdx,QWORD PTR[16+rdx]
        +	sub	rbp,1
        +	jnz	loop_3
        +	mov	rsi,QWORD PTR[8+rsp]
        +	call	mont_mul_a3b
        +
        +
        +
        +	mov	rcx,QWORD PTR[48+rsp]
        +	sub	rcx,5
        +	mov	QWORD PTR[48+rsp],rcx
        +	jge	main_loop_a3b
        +
        +
        +
        +end_main_loop_a3b::
        +
        +
        +	mov	rdx,QWORD PTR[8+rsp]
        +	pxor	xmm4,xmm4
        +	movdqu	xmm0,XMMWORD PTR[rdx]
        +	movdqu	xmm1,XMMWORD PTR[16+rdx]
        +	movdqu	xmm2,XMMWORD PTR[32+rdx]
        +	movdqu	xmm3,XMMWORD PTR[48+rdx]
        +	movdqa	XMMWORD PTR[576+rsp],xmm4
        +	movdqa	XMMWORD PTR[592+rsp],xmm4
        +	movdqa	XMMWORD PTR[608+rsp],xmm4
        +	movdqa	XMMWORD PTR[624+rsp],xmm4
        +	movdqa	XMMWORD PTR[512+rsp],xmm0
        +	movdqa	XMMWORD PTR[528+rsp],xmm1
        +	movdqa	XMMWORD PTR[544+rsp],xmm2
        +	movdqa	XMMWORD PTR[560+rsp],xmm3
        +	call	mont_reduce
        +
        +
        +
        +	mov	rax,QWORD PTR[8+rsp]
        +	mov	r8,QWORD PTR[rax]
        +	mov	r9,QWORD PTR[8+rax]
        +	mov	r10,QWORD PTR[16+rax]
        +	mov	r11,QWORD PTR[24+rax]
        +	mov	r12,QWORD PTR[32+rax]
        +	mov	r13,QWORD PTR[40+rax]
        +	mov	r14,QWORD PTR[48+rax]
        +	mov	r15,QWORD PTR[56+rax]
        +
        +
        +	mov	rbx,QWORD PTR[24+rsp]
        +	add	rbx,512
        +
        +	sub	r8,QWORD PTR[rbx]
        +	sbb	r9,QWORD PTR[8+rbx]
        +	sbb	r10,QWORD PTR[16+rbx]
        +	sbb	r11,QWORD PTR[24+rbx]
        +	sbb	r12,QWORD PTR[32+rbx]
        +	sbb	r13,QWORD PTR[40+rbx]
        +	sbb	r14,QWORD PTR[48+rbx]
        +	sbb	r15,QWORD PTR[56+rbx]
        +
        +
        +	mov	rsi,QWORD PTR[rax]
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rcx,QWORD PTR[16+rax]
        +	mov	rdx,QWORD PTR[24+rax]
        +	cmovnc	rsi,r8
        +	cmovnc	rdi,r9
        +	cmovnc	rcx,r10
        +	cmovnc	rdx,r11
        +	mov	QWORD PTR[rax],rsi
        +	mov	QWORD PTR[8+rax],rdi
        +	mov	QWORD PTR[16+rax],rcx
        +	mov	QWORD PTR[24+rax],rdx
        +
        +	mov	rsi,QWORD PTR[32+rax]
        +	mov	rdi,QWORD PTR[40+rax]
        +	mov	rcx,QWORD PTR[48+rax]
        +	mov	rdx,QWORD PTR[56+rax]
        +	cmovnc	rsi,r12
        +	cmovnc	rdi,r13
        +	cmovnc	rcx,r14
        +	cmovnc	rdx,r15
        +	mov	QWORD PTR[32+rax],rsi
        +	mov	QWORD PTR[40+rax],rdi
        +	mov	QWORD PTR[48+rax],rcx
        +	mov	QWORD PTR[56+rax],rdx
        +
        +	mov	rsi,QWORD PTR[rsp]
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbx,QWORD PTR[32+rsi]
        +	mov	rbp,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_mod_exp_512::
        +mod_exp_512	ENDP
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +mod_exp_512_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$body]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[rax]
        +
        +	mov	rbx,QWORD PTR[32+rax]
        +	mov	rbp,QWORD PTR[40+rax]
        +	mov	r12,QWORD PTR[24+rax]
        +	mov	r13,QWORD PTR[16+rax]
        +	mov	r14,QWORD PTR[8+rax]
        +	mov	r15,QWORD PTR[rax]
        +	lea	rax,QWORD PTR[48+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +mod_exp_512_se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_mod_exp_512
        +	DD	imagerel $L$SEH_end_mod_exp_512
        +	DD	imagerel $L$SEH_info_mod_exp_512
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_mod_exp_512::
        +DB	9,0,0,0
        +	DD	imagerel mod_exp_512_se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm b/vendor/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm
        new file mode 100644
        index 000000000..f4518aa3b
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/bn/x86_64-mont.asm
        @@ -0,0 +1,1595 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +PUBLIC	bn_mul_mont
        +
        +ALIGN	16
        +bn_mul_mont	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_bn_mul_mont::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	test	r9d,3
        +	jnz	$L$mul_enter
        +	cmp	r9d,8
        +	jb	$L$mul_enter
        +	cmp	rdx,rsi
        +	jne	$L$mul4x_enter
        +	jmp	$L$sqr4x_enter
        +
        +ALIGN	16
        +$L$mul_enter::
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +	mov	r9d,r9d
        +	lea	r10,QWORD PTR[2+r9]
        +	mov	r11,rsp
        +	neg	r10
        +	lea	rsp,QWORD PTR[r10*8+rsp]
        +	and	rsp,-1024
        +
        +	mov	QWORD PTR[8+r9*8+rsp],r11
        +$L$mul_body::
        +	mov	r12,rdx
        +	mov	r8,QWORD PTR[r8]
        +	mov	rbx,QWORD PTR[r12]
        +	mov	rax,QWORD PTR[rsi]
        +
        +	xor	r14,r14
        +	xor	r15,r15
        +
        +	mov	rbp,r8
        +	mul	rbx
        +	mov	r10,rax
        +	mov	rax,QWORD PTR[rcx]
        +
        +	imul	rbp,r10
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r10,rax
        +	mov	rax,QWORD PTR[8+rsi]
        +	adc	rdx,0
        +	mov	r13,rdx
        +
        +	lea	r15,QWORD PTR[1+r15]
        +	jmp	$L$1st_enter
        +
        +ALIGN	16
        +$L$1st::
        +	add	r13,rax
        +	mov	rax,QWORD PTR[r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r11
        +	mov	r11,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],r13
        +	mov	r13,rdx
        +
        +$L$1st_enter::
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[r15*8+rcx]
        +	adc	rdx,0
        +	lea	r15,QWORD PTR[1+r15]
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	cmp	r15,r9
        +	jne	$L$1st
        +
        +	add	r13,rax
        +	mov	rax,QWORD PTR[rsi]
        +	adc	rdx,0
        +	add	r13,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],r13
        +	mov	r13,rdx
        +	mov	r11,r10
        +
        +	xor	rdx,rdx
        +	add	r13,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-8))+r9*8+rsp],r13
        +	mov	QWORD PTR[r9*8+rsp],rdx
        +
        +	lea	r14,QWORD PTR[1+r14]
        +	jmp	$L$outer
        +ALIGN	16
        +$L$outer::
        +	mov	rbx,QWORD PTR[r14*8+r12]
        +	xor	r15,r15
        +	mov	rbp,r8
        +	mov	r10,QWORD PTR[rsp]
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[rcx]
        +	adc	rdx,0
        +
        +	imul	rbp,r10
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r10,rax
        +	mov	rax,QWORD PTR[8+rsi]
        +	adc	rdx,0
        +	mov	r10,QWORD PTR[8+rsp]
        +	mov	r13,rdx
        +
        +	lea	r15,QWORD PTR[1+r15]
        +	jmp	$L$inner_enter
        +
        +ALIGN	16
        +$L$inner::
        +	add	r13,rax
        +	mov	rax,QWORD PTR[r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	mov	r10,QWORD PTR[r15*8+rsp]
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],r13
        +	mov	r13,rdx
        +
        +$L$inner_enter::
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[r15*8+rcx]
        +	adc	rdx,0
        +	add	r10,r11
        +	mov	r11,rdx
        +	adc	r11,0
        +	lea	r15,QWORD PTR[1+r15]
        +
        +	mul	rbp
        +	cmp	r15,r9
        +	jne	$L$inner
        +
        +	add	r13,rax
        +	mov	rax,QWORD PTR[rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	mov	r10,QWORD PTR[r15*8+rsp]
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],r13
        +	mov	r13,rdx
        +
        +	xor	rdx,rdx
        +	add	r13,r11
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-8))+r9*8+rsp],r13
        +	mov	QWORD PTR[r9*8+rsp],rdx
        +
        +	lea	r14,QWORD PTR[1+r14]
        +	cmp	r14,r9
        +	jl	$L$outer
        +
        +	xor	r14,r14
        +	mov	rax,QWORD PTR[rsp]
        +	lea	rsi,QWORD PTR[rsp]
        +	mov	r15,r9
        +	jmp	$L$sub
        +ALIGN	16
        +$L$sub::	sbb	rax,QWORD PTR[r14*8+rcx]
        +	mov	QWORD PTR[r14*8+rdi],rax
        +	mov	rax,QWORD PTR[8+r14*8+rsi]
        +	lea	r14,QWORD PTR[1+r14]
        +	dec	r15
        +	jnz	$L$sub
        +
        +	sbb	rax,0
        +	xor	r14,r14
        +	and	rsi,rax
        +	not	rax
        +	mov	rcx,rdi
        +	and	rcx,rax
        +	mov	r15,r9
        +	or	rsi,rcx
        +ALIGN	16
        +$L$copy::
        +	mov	rax,QWORD PTR[r14*8+rsi]
        +	mov	QWORD PTR[r14*8+rsp],r14
        +	mov	QWORD PTR[r14*8+rdi],rax
        +	lea	r14,QWORD PTR[1+r14]
        +	sub	r15,1
        +	jnz	$L$copy
        +
        +	mov	rsi,QWORD PTR[8+r9*8+rsp]
        +	mov	rax,1
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$mul_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_bn_mul_mont::
        +bn_mul_mont	ENDP
        +
        +ALIGN	16
        +bn_mul4x_mont	PROC PRIVATE
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_bn_mul4x_mont::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +$L$mul4x_enter::
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +	mov	r9d,r9d
        +	lea	r10,QWORD PTR[4+r9]
        +	mov	r11,rsp
        +	neg	r10
        +	lea	rsp,QWORD PTR[r10*8+rsp]
        +	and	rsp,-1024
        +
        +	mov	QWORD PTR[8+r9*8+rsp],r11
        +$L$mul4x_body::
        +	mov	QWORD PTR[16+r9*8+rsp],rdi
        +	mov	r12,rdx
        +	mov	r8,QWORD PTR[r8]
        +	mov	rbx,QWORD PTR[r12]
        +	mov	rax,QWORD PTR[rsi]
        +
        +	xor	r14,r14
        +	xor	r15,r15
        +
        +	mov	rbp,r8
        +	mul	rbx
        +	mov	r10,rax
        +	mov	rax,QWORD PTR[rcx]
        +
        +	imul	rbp,r10
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r10,rax
        +	mov	rax,QWORD PTR[8+rsi]
        +	adc	rdx,0
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[8+rcx]
        +	adc	rdx,0
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[16+rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	lea	r15,QWORD PTR[4+r15]
        +	adc	rdx,0
        +	mov	QWORD PTR[rsp],rdi
        +	mov	r13,rdx
        +	jmp	$L$1st4x
        +ALIGN	16
        +$L$1st4x::
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[((-16))+r15*8+rcx]
        +	adc	rdx,0
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r13,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-24))+r15*8+rsp],r13
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rcx]
        +	adc	rdx,0
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[r15*8+rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],rdi
        +	mov	r13,rdx
        +
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[r15*8+rcx]
        +	adc	rdx,0
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r13,rax
        +	mov	rax,QWORD PTR[8+r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-8))+r15*8+rsp],r13
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[8+r15*8+rcx]
        +	adc	rdx,0
        +	lea	r15,QWORD PTR[4+r15]
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[((-16))+r15*8+rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-32))+r15*8+rsp],rdi
        +	mov	r13,rdx
        +	cmp	r15,r9
        +	jl	$L$1st4x
        +
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[((-16))+r15*8+rcx]
        +	adc	rdx,0
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r13,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-24))+r15*8+rsp],r13
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rcx]
        +	adc	rdx,0
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],rdi
        +	mov	r13,rdx
        +
        +	xor	rdi,rdi
        +	add	r13,r10
        +	adc	rdi,0
        +	mov	QWORD PTR[((-8))+r15*8+rsp],r13
        +	mov	QWORD PTR[r15*8+rsp],rdi
        +
        +	lea	r14,QWORD PTR[1+r14]
        +ALIGN	4
        +$L$outer4x::
        +	mov	rbx,QWORD PTR[r14*8+r12]
        +	xor	r15,r15
        +	mov	r10,QWORD PTR[rsp]
        +	mov	rbp,r8
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[rcx]
        +	adc	rdx,0
        +
        +	imul	rbp,r10
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r10,rax
        +	mov	rax,QWORD PTR[8+rsi]
        +	adc	rdx,0
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[8+rcx]
        +	adc	rdx,0
        +	add	r11,QWORD PTR[8+rsp]
        +	adc	rdx,0
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[16+rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	lea	r15,QWORD PTR[4+r15]
        +	adc	rdx,0
        +	mov	QWORD PTR[rsp],rdi
        +	mov	r13,rdx
        +	jmp	$L$inner4x
        +ALIGN	16
        +$L$inner4x::
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[((-16))+r15*8+rcx]
        +	adc	rdx,0
        +	add	r10,QWORD PTR[((-16))+r15*8+rsp]
        +	adc	rdx,0
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r13,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-24))+r15*8+rsp],r13
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rcx]
        +	adc	rdx,0
        +	add	r11,QWORD PTR[((-8))+r15*8+rsp]
        +	adc	rdx,0
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[r15*8+rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],rdi
        +	mov	r13,rdx
        +
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[r15*8+rcx]
        +	adc	rdx,0
        +	add	r10,QWORD PTR[r15*8+rsp]
        +	adc	rdx,0
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r13,rax
        +	mov	rax,QWORD PTR[8+r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-8))+r15*8+rsp],r13
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[8+r15*8+rcx]
        +	adc	rdx,0
        +	add	r11,QWORD PTR[8+r15*8+rsp]
        +	adc	rdx,0
        +	lea	r15,QWORD PTR[4+r15]
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[((-16))+r15*8+rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-32))+r15*8+rsp],rdi
        +	mov	r13,rdx
        +	cmp	r15,r9
        +	jl	$L$inner4x
        +
        +	mul	rbx
        +	add	r10,rax
        +	mov	rax,QWORD PTR[((-16))+r15*8+rcx]
        +	adc	rdx,0
        +	add	r10,QWORD PTR[((-16))+r15*8+rsp]
        +	adc	rdx,0
        +	mov	r11,rdx
        +
        +	mul	rbp
        +	add	r13,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rsi]
        +	adc	rdx,0
        +	add	r13,r10
        +	adc	rdx,0
        +	mov	QWORD PTR[((-24))+r15*8+rsp],r13
        +	mov	rdi,rdx
        +
        +	mul	rbx
        +	add	r11,rax
        +	mov	rax,QWORD PTR[((-8))+r15*8+rcx]
        +	adc	rdx,0
        +	add	r11,QWORD PTR[((-8))+r15*8+rsp]
        +	adc	rdx,0
        +	lea	r14,QWORD PTR[1+r14]
        +	mov	r10,rdx
        +
        +	mul	rbp
        +	add	rdi,rax
        +	mov	rax,QWORD PTR[rsi]
        +	adc	rdx,0
        +	add	rdi,r11
        +	adc	rdx,0
        +	mov	QWORD PTR[((-16))+r15*8+rsp],rdi
        +	mov	r13,rdx
        +
        +	xor	rdi,rdi
        +	add	r13,r10
        +	adc	rdi,0
        +	add	r13,QWORD PTR[r9*8+rsp]
        +	adc	rdi,0
        +	mov	QWORD PTR[((-8))+r15*8+rsp],r13
        +	mov	QWORD PTR[r15*8+rsp],rdi
        +
        +	cmp	r14,r9
        +	jl	$L$outer4x
        +	mov	rdi,QWORD PTR[16+r9*8+rsp]
        +	mov	rax,QWORD PTR[rsp]
        +	pxor	xmm0,xmm0
        +	mov	rdx,QWORD PTR[8+rsp]
        +	shr	r9,2
        +	lea	rsi,QWORD PTR[rsp]
        +	xor	r14,r14
        +
        +	sub	rax,QWORD PTR[rcx]
        +	mov	rbx,QWORD PTR[16+rsi]
        +	mov	rbp,QWORD PTR[24+rsi]
        +	sbb	rdx,QWORD PTR[8+rcx]
        +	lea	r15,QWORD PTR[((-1))+r9]
        +	jmp	$L$sub4x
        +ALIGN	16
        +$L$sub4x::
        +	mov	QWORD PTR[r14*8+rdi],rax
        +	mov	QWORD PTR[8+r14*8+rdi],rdx
        +	sbb	rbx,QWORD PTR[16+r14*8+rcx]
        +	mov	rax,QWORD PTR[32+r14*8+rsi]
        +	mov	rdx,QWORD PTR[40+r14*8+rsi]
        +	sbb	rbp,QWORD PTR[24+r14*8+rcx]
        +	mov	QWORD PTR[16+r14*8+rdi],rbx
        +	mov	QWORD PTR[24+r14*8+rdi],rbp
        +	sbb	rax,QWORD PTR[32+r14*8+rcx]
        +	mov	rbx,QWORD PTR[48+r14*8+rsi]
        +	mov	rbp,QWORD PTR[56+r14*8+rsi]
        +	sbb	rdx,QWORD PTR[40+r14*8+rcx]
        +	lea	r14,QWORD PTR[4+r14]
        +	dec	r15
        +	jnz	$L$sub4x
        +
        +	mov	QWORD PTR[r14*8+rdi],rax
        +	mov	rax,QWORD PTR[32+r14*8+rsi]
        +	sbb	rbx,QWORD PTR[16+r14*8+rcx]
        +	mov	QWORD PTR[8+r14*8+rdi],rdx
        +	sbb	rbp,QWORD PTR[24+r14*8+rcx]
        +	mov	QWORD PTR[16+r14*8+rdi],rbx
        +
        +	sbb	rax,0
        +	mov	QWORD PTR[24+r14*8+rdi],rbp
        +	xor	r14,r14
        +	and	rsi,rax
        +	not	rax
        +	mov	rcx,rdi
        +	and	rcx,rax
        +	lea	r15,QWORD PTR[((-1))+r9]
        +	or	rsi,rcx
        +
        +	movdqu	xmm1,XMMWORD PTR[rsi]
        +	movdqa	XMMWORD PTR[rsp],xmm0
        +	movdqu	XMMWORD PTR[rdi],xmm1
        +	jmp	$L$copy4x
        +ALIGN	16
        +$L$copy4x::
        +	movdqu	xmm2,XMMWORD PTR[16+r14*1+rsi]
        +	movdqu	xmm1,XMMWORD PTR[32+r14*1+rsi]
        +	movdqa	XMMWORD PTR[16+r14*1+rsp],xmm0
        +	movdqu	XMMWORD PTR[16+r14*1+rdi],xmm2
        +	movdqa	XMMWORD PTR[32+r14*1+rsp],xmm0
        +	movdqu	XMMWORD PTR[32+r14*1+rdi],xmm1
        +	lea	r14,QWORD PTR[32+r14]
        +	dec	r15
        +	jnz	$L$copy4x
        +
        +	shl	r9,2
        +	movdqu	xmm2,XMMWORD PTR[16+r14*1+rsi]
        +	movdqa	XMMWORD PTR[16+r14*1+rsp],xmm0
        +	movdqu	XMMWORD PTR[16+r14*1+rdi],xmm2
        +	mov	rsi,QWORD PTR[8+r9*8+rsp]
        +	mov	rax,1
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$mul4x_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_bn_mul4x_mont::
        +bn_mul4x_mont	ENDP
        +
        +ALIGN	16
        +bn_sqr4x_mont	PROC PRIVATE
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_bn_sqr4x_mont::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +$L$sqr4x_enter::
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +	shl	r9d,3
        +	xor	r10,r10
        +	mov	r11,rsp
        +	sub	r10,r9
        +	mov	r8,QWORD PTR[r8]
        +	lea	rsp,QWORD PTR[((-72))+r10*2+rsp]
        +	and	rsp,-1024
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +	mov	QWORD PTR[32+rsp],rdi
        +	mov	QWORD PTR[40+rsp],rcx
        +	mov	QWORD PTR[48+rsp],r8
        +	mov	QWORD PTR[56+rsp],r11
        +$L$sqr4x_body::
        +
        +
        +
        +
        +
        +
        +
        +	lea	rbp,QWORD PTR[32+r10]
        +	lea	rsi,QWORD PTR[r9*1+rsi]
        +
        +	mov	rcx,r9
        +
        +
        +	mov	r14,QWORD PTR[((-32))+rbp*1+rsi]
        +	lea	rdi,QWORD PTR[64+r9*2+rsp]
        +	mov	rax,QWORD PTR[((-24))+rbp*1+rsi]
        +	lea	rdi,QWORD PTR[((-32))+rbp*1+rdi]
        +	mov	rbx,QWORD PTR[((-16))+rbp*1+rsi]
        +	mov	r15,rax
        +
        +	mul	r14
        +	mov	r10,rax
        +	mov	rax,rbx
        +	mov	r11,rdx
        +	mov	QWORD PTR[((-24))+rbp*1+rdi],r10
        +
        +	xor	r10,r10
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	mov	QWORD PTR[((-16))+rbp*1+rdi],r11
        +
        +	lea	rcx,QWORD PTR[((-16))+rbp]
        +
        +
        +	mov	rbx,QWORD PTR[8+rcx*1+rsi]
        +	mul	r15
        +	mov	r12,rax
        +	mov	rax,rbx
        +	mov	r13,rdx
        +
        +	xor	r11,r11
        +	add	r10,r12
        +	lea	rcx,QWORD PTR[16+rcx]
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[((-8))+rcx*1+rdi],r10
        +	jmp	$L$sqr4x_1st
        +
        +ALIGN	16
        +$L$sqr4x_1st::
        +	mov	rbx,QWORD PTR[rcx*1+rsi]
        +	xor	r12,r12
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,rbx
        +	adc	r12,rdx
        +
        +	xor	r10,r10
        +	add	r11,r13
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	mov	QWORD PTR[rcx*1+rdi],r11
        +
        +
        +	mov	rbx,QWORD PTR[8+rcx*1+rsi]
        +	xor	r13,r13
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +
        +	xor	r11,r11
        +	add	r10,r12
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[8+rcx*1+rdi],r10
        +
        +	mov	rbx,QWORD PTR[16+rcx*1+rsi]
        +	xor	r12,r12
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,rbx
        +	adc	r12,rdx
        +
        +	xor	r10,r10
        +	add	r11,r13
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	mov	QWORD PTR[16+rcx*1+rdi],r11
        +
        +
        +	mov	rbx,QWORD PTR[24+rcx*1+rsi]
        +	xor	r13,r13
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +
        +	xor	r11,r11
        +	add	r10,r12
        +	lea	rcx,QWORD PTR[32+rcx]
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[((-8))+rcx*1+rdi],r10
        +
        +	cmp	rcx,0
        +	jne	$L$sqr4x_1st
        +
        +	xor	r12,r12
        +	add	r13,r11
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	adc	r12,rdx
        +
        +	mov	QWORD PTR[rdi],r13
        +	lea	rbp,QWORD PTR[16+rbp]
        +	mov	QWORD PTR[8+rdi],r12
        +	jmp	$L$sqr4x_outer
        +
        +ALIGN	16
        +$L$sqr4x_outer::
        +	mov	r14,QWORD PTR[((-32))+rbp*1+rsi]
        +	lea	rdi,QWORD PTR[64+r9*2+rsp]
        +	mov	rax,QWORD PTR[((-24))+rbp*1+rsi]
        +	lea	rdi,QWORD PTR[((-32))+rbp*1+rdi]
        +	mov	rbx,QWORD PTR[((-16))+rbp*1+rsi]
        +	mov	r15,rax
        +
        +	mov	r10,QWORD PTR[((-24))+rbp*1+rdi]
        +	xor	r11,r11
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[((-24))+rbp*1+rdi],r10
        +
        +	xor	r10,r10
        +	add	r11,QWORD PTR[((-16))+rbp*1+rdi]
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	mov	QWORD PTR[((-16))+rbp*1+rdi],r11
        +
        +	lea	rcx,QWORD PTR[((-16))+rbp]
        +	xor	r12,r12
        +
        +
        +	mov	rbx,QWORD PTR[8+rcx*1+rsi]
        +	xor	r13,r13
        +	add	r12,QWORD PTR[8+rcx*1+rdi]
        +	adc	r13,0
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +
        +	xor	r11,r11
        +	add	r10,r12
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[8+rcx*1+rdi],r10
        +
        +	lea	rcx,QWORD PTR[16+rcx]
        +	jmp	$L$sqr4x_inner
        +
        +ALIGN	16
        +$L$sqr4x_inner::
        +	mov	rbx,QWORD PTR[rcx*1+rsi]
        +	xor	r12,r12
        +	add	r13,QWORD PTR[rcx*1+rdi]
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,rbx
        +	adc	r12,rdx
        +
        +	xor	r10,r10
        +	add	r11,r13
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	mov	QWORD PTR[rcx*1+rdi],r11
        +
        +	mov	rbx,QWORD PTR[8+rcx*1+rsi]
        +	xor	r13,r13
        +	add	r12,QWORD PTR[8+rcx*1+rdi]
        +	adc	r13,0
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +
        +	xor	r11,r11
        +	add	r10,r12
        +	lea	rcx,QWORD PTR[16+rcx]
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[((-8))+rcx*1+rdi],r10
        +
        +	cmp	rcx,0
        +	jne	$L$sqr4x_inner
        +
        +	xor	r12,r12
        +	add	r13,r11
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	adc	r12,rdx
        +
        +	mov	QWORD PTR[rdi],r13
        +	mov	QWORD PTR[8+rdi],r12
        +
        +	add	rbp,16
        +	jnz	$L$sqr4x_outer
        +
        +
        +	mov	r14,QWORD PTR[((-32))+rsi]
        +	lea	rdi,QWORD PTR[64+r9*2+rsp]
        +	mov	rax,QWORD PTR[((-24))+rsi]
        +	lea	rdi,QWORD PTR[((-32))+rbp*1+rdi]
        +	mov	rbx,QWORD PTR[((-16))+rsi]
        +	mov	r15,rax
        +
        +	xor	r11,r11
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[((-24))+rdi],r10
        +
        +	xor	r10,r10
        +	add	r11,r13
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	mov	QWORD PTR[((-16))+rdi],r11
        +
        +	mov	rbx,QWORD PTR[((-8))+rsi]
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	rdx,0
        +
        +	xor	r11,r11
        +	add	r10,r12
        +	mov	r13,rdx
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,rbx
        +	adc	r11,rdx
        +	mov	QWORD PTR[((-8))+rdi],r10
        +
        +	xor	r12,r12
        +	add	r13,r11
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,QWORD PTR[((-16))+rsi]
        +	adc	r12,rdx
        +
        +	mov	QWORD PTR[rdi],r13
        +	mov	QWORD PTR[8+rdi],r12
        +
        +	mul	rbx
        +	add	rbp,16
        +	xor	r14,r14
        +	sub	rbp,r9
        +	xor	r15,r15
        +
        +	add	rax,r12
        +	adc	rdx,0
        +	mov	QWORD PTR[8+rdi],rax
        +	mov	QWORD PTR[16+rdi],rdx
        +	mov	QWORD PTR[24+rdi],r15
        +
        +	mov	rax,QWORD PTR[((-16))+rbp*1+rsi]
        +	lea	rdi,QWORD PTR[64+r9*2+rsp]
        +	xor	r10,r10
        +	mov	r11,QWORD PTR[((-24))+rbp*2+rdi]
        +
        +	lea	r12,QWORD PTR[r10*2+r14]
        +	shr	r10,63
        +	lea	r13,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r13,r10
        +	mov	r10,QWORD PTR[((-16))+rbp*2+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[((-8))+rbp*2+rdi]
        +	adc	r12,rax
        +	mov	rax,QWORD PTR[((-8))+rbp*1+rsi]
        +	mov	QWORD PTR[((-32))+rbp*2+rdi],r12
        +	adc	r13,rdx
        +
        +	lea	rbx,QWORD PTR[r10*2+r14]
        +	mov	QWORD PTR[((-24))+rbp*2+rdi],r13
        +	sbb	r15,r15
        +	shr	r10,63
        +	lea	r8,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r8,r10
        +	mov	r10,QWORD PTR[rbp*2+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[8+rbp*2+rdi]
        +	adc	rbx,rax
        +	mov	rax,QWORD PTR[rbp*1+rsi]
        +	mov	QWORD PTR[((-16))+rbp*2+rdi],rbx
        +	adc	r8,rdx
        +	lea	rbp,QWORD PTR[16+rbp]
        +	mov	QWORD PTR[((-40))+rbp*2+rdi],r8
        +	sbb	r15,r15
        +	jmp	$L$sqr4x_shift_n_add
        +
        +ALIGN	16
        +$L$sqr4x_shift_n_add::
        +	lea	r12,QWORD PTR[r10*2+r14]
        +	shr	r10,63
        +	lea	r13,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r13,r10
        +	mov	r10,QWORD PTR[((-16))+rbp*2+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[((-8))+rbp*2+rdi]
        +	adc	r12,rax
        +	mov	rax,QWORD PTR[((-8))+rbp*1+rsi]
        +	mov	QWORD PTR[((-32))+rbp*2+rdi],r12
        +	adc	r13,rdx
        +
        +	lea	rbx,QWORD PTR[r10*2+r14]
        +	mov	QWORD PTR[((-24))+rbp*2+rdi],r13
        +	sbb	r15,r15
        +	shr	r10,63
        +	lea	r8,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r8,r10
        +	mov	r10,QWORD PTR[rbp*2+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[8+rbp*2+rdi]
        +	adc	rbx,rax
        +	mov	rax,QWORD PTR[rbp*1+rsi]
        +	mov	QWORD PTR[((-16))+rbp*2+rdi],rbx
        +	adc	r8,rdx
        +
        +	lea	r12,QWORD PTR[r10*2+r14]
        +	mov	QWORD PTR[((-8))+rbp*2+rdi],r8
        +	sbb	r15,r15
        +	shr	r10,63
        +	lea	r13,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r13,r10
        +	mov	r10,QWORD PTR[16+rbp*2+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[24+rbp*2+rdi]
        +	adc	r12,rax
        +	mov	rax,QWORD PTR[8+rbp*1+rsi]
        +	mov	QWORD PTR[rbp*2+rdi],r12
        +	adc	r13,rdx
        +
        +	lea	rbx,QWORD PTR[r10*2+r14]
        +	mov	QWORD PTR[8+rbp*2+rdi],r13
        +	sbb	r15,r15
        +	shr	r10,63
        +	lea	r8,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r8,r10
        +	mov	r10,QWORD PTR[32+rbp*2+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[40+rbp*2+rdi]
        +	adc	rbx,rax
        +	mov	rax,QWORD PTR[16+rbp*1+rsi]
        +	mov	QWORD PTR[16+rbp*2+rdi],rbx
        +	adc	r8,rdx
        +	mov	QWORD PTR[24+rbp*2+rdi],r8
        +	sbb	r15,r15
        +	add	rbp,32
        +	jnz	$L$sqr4x_shift_n_add
        +
        +	lea	r12,QWORD PTR[r10*2+r14]
        +	shr	r10,63
        +	lea	r13,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r13,r10
        +	mov	r10,QWORD PTR[((-16))+rdi]
        +	mov	r14,r11
        +	mul	rax
        +	neg	r15
        +	mov	r11,QWORD PTR[((-8))+rdi]
        +	adc	r12,rax
        +	mov	rax,QWORD PTR[((-8))+rsi]
        +	mov	QWORD PTR[((-32))+rdi],r12
        +	adc	r13,rdx
        +
        +	lea	rbx,QWORD PTR[r10*2+r14]
        +	mov	QWORD PTR[((-24))+rdi],r13
        +	sbb	r15,r15
        +	shr	r10,63
        +	lea	r8,QWORD PTR[r11*2+rcx]
        +	shr	r11,63
        +	or	r8,r10
        +	mul	rax
        +	neg	r15
        +	adc	rbx,rax
        +	adc	r8,rdx
        +	mov	QWORD PTR[((-16))+rdi],rbx
        +	mov	QWORD PTR[((-8))+rdi],r8
        +	mov	rsi,QWORD PTR[40+rsp]
        +	mov	r8,QWORD PTR[48+rsp]
        +	xor	rcx,rcx
        +	mov	QWORD PTR[rsp],r9
        +	sub	rcx,r9
        +	mov	r10,QWORD PTR[64+rsp]
        +	mov	r14,r8
        +	lea	rax,QWORD PTR[64+r9*2+rsp]
        +	lea	rdi,QWORD PTR[64+r9*1+rsp]
        +	mov	QWORD PTR[8+rsp],rax
        +	lea	rsi,QWORD PTR[r9*1+rsi]
        +	xor	rbp,rbp
        +
        +	mov	rax,QWORD PTR[rcx*1+rsi]
        +	mov	r9,QWORD PTR[8+rcx*1+rsi]
        +	imul	r14,r10
        +	mov	rbx,rax
        +	jmp	$L$sqr4x_mont_outer
        +
        +ALIGN	16
        +$L$sqr4x_mont_outer::
        +	xor	r11,r11
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,r9
        +	adc	r11,rdx
        +	mov	r15,r8
        +
        +	xor	r10,r10
        +	add	r11,QWORD PTR[8+rcx*1+rdi]
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +
        +	imul	r15,r11
        +
        +	mov	rbx,QWORD PTR[16+rcx*1+rsi]
        +	xor	r13,r13
        +	add	r12,r11
        +	adc	r13,0
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +	mov	QWORD PTR[8+rcx*1+rdi],r12
        +
        +	xor	r11,r11
        +	add	r10,QWORD PTR[16+rcx*1+rdi]
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,r9
        +	adc	r11,rdx
        +
        +	mov	r9,QWORD PTR[24+rcx*1+rsi]
        +	xor	r12,r12
        +	add	r13,r10
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,r9
        +	adc	r12,rdx
        +	mov	QWORD PTR[16+rcx*1+rdi],r13
        +
        +	xor	r10,r10
        +	add	r11,QWORD PTR[24+rcx*1+rdi]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	jmp	$L$sqr4x_mont_inner
        +
        +ALIGN	16
        +$L$sqr4x_mont_inner::
        +	mov	rbx,QWORD PTR[rcx*1+rsi]
        +	xor	r13,r13
        +	add	r12,r11
        +	adc	r13,0
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +	mov	QWORD PTR[((-8))+rcx*1+rdi],r12
        +
        +	xor	r11,r11
        +	add	r10,QWORD PTR[rcx*1+rdi]
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,r9
        +	adc	r11,rdx
        +
        +	mov	r9,QWORD PTR[8+rcx*1+rsi]
        +	xor	r12,r12
        +	add	r13,r10
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,r9
        +	adc	r12,rdx
        +	mov	QWORD PTR[rcx*1+rdi],r13
        +
        +	xor	r10,r10
        +	add	r11,QWORD PTR[8+rcx*1+rdi]
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +
        +
        +	mov	rbx,QWORD PTR[16+rcx*1+rsi]
        +	xor	r13,r13
        +	add	r12,r11
        +	adc	r13,0
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,rbx
        +	adc	r13,rdx
        +	mov	QWORD PTR[8+rcx*1+rdi],r12
        +
        +	xor	r11,r11
        +	add	r10,QWORD PTR[16+rcx*1+rdi]
        +	adc	r11,0
        +	mul	r14
        +	add	r10,rax
        +	mov	rax,r9
        +	adc	r11,rdx
        +
        +	mov	r9,QWORD PTR[24+rcx*1+rsi]
        +	xor	r12,r12
        +	add	r13,r10
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,r9
        +	adc	r12,rdx
        +	mov	QWORD PTR[16+rcx*1+rdi],r13
        +
        +	xor	r10,r10
        +	add	r11,QWORD PTR[24+rcx*1+rdi]
        +	lea	rcx,QWORD PTR[32+rcx]
        +	adc	r10,0
        +	mul	r14
        +	add	r11,rax
        +	mov	rax,rbx
        +	adc	r10,rdx
        +	cmp	rcx,0
        +	jne	$L$sqr4x_mont_inner
        +
        +	sub	rcx,QWORD PTR[rsp]
        +	mov	r14,r8
        +
        +	xor	r13,r13
        +	add	r12,r11
        +	adc	r13,0
        +	mul	r15
        +	add	r12,rax
        +	mov	rax,r9
        +	adc	r13,rdx
        +	mov	QWORD PTR[((-8))+rdi],r12
        +
        +	xor	r11,r11
        +	add	r10,QWORD PTR[rdi]
        +	adc	r11,0
        +	mov	rbx,QWORD PTR[rcx*1+rsi]
        +	add	r10,rbp
        +	adc	r11,0
        +
        +	imul	r14,QWORD PTR[16+rcx*1+rdi]
        +	xor	r12,r12
        +	mov	r9,QWORD PTR[8+rcx*1+rsi]
        +	add	r13,r10
        +	mov	r10,QWORD PTR[16+rcx*1+rdi]
        +	adc	r12,0
        +	mul	r15
        +	add	r13,rax
        +	mov	rax,rbx
        +	adc	r12,rdx
        +	mov	QWORD PTR[rdi],r13
        +
        +	xor	rbp,rbp
        +	add	r12,QWORD PTR[8+rdi]
        +	adc	rbp,rbp
        +	add	r12,r11
        +	lea	rdi,QWORD PTR[16+rdi]
        +	adc	rbp,0
        +	mov	QWORD PTR[((-8))+rdi],r12
        +	cmp	rdi,QWORD PTR[8+rsp]
        +	jb	$L$sqr4x_mont_outer
        +
        +	mov	r9,QWORD PTR[rsp]
        +	mov	QWORD PTR[rdi],rbp
        +	mov	rax,QWORD PTR[64+r9*1+rsp]
        +	lea	rbx,QWORD PTR[64+r9*1+rsp]
        +	mov	rsi,QWORD PTR[40+rsp]
        +	shr	r9,5
        +	mov	rdx,QWORD PTR[8+rbx]
        +	xor	rbp,rbp
        +
        +	mov	rdi,QWORD PTR[32+rsp]
        +	sub	rax,QWORD PTR[rsi]
        +	mov	r10,QWORD PTR[16+rbx]
        +	mov	r11,QWORD PTR[24+rbx]
        +	sbb	rdx,QWORD PTR[8+rsi]
        +	lea	rcx,QWORD PTR[((-1))+r9]
        +	jmp	$L$sqr4x_sub
        +ALIGN	16
        +$L$sqr4x_sub::
        +	mov	QWORD PTR[rbp*8+rdi],rax
        +	mov	QWORD PTR[8+rbp*8+rdi],rdx
        +	sbb	r10,QWORD PTR[16+rbp*8+rsi]
        +	mov	rax,QWORD PTR[32+rbp*8+rbx]
        +	mov	rdx,QWORD PTR[40+rbp*8+rbx]
        +	sbb	r11,QWORD PTR[24+rbp*8+rsi]
        +	mov	QWORD PTR[16+rbp*8+rdi],r10
        +	mov	QWORD PTR[24+rbp*8+rdi],r11
        +	sbb	rax,QWORD PTR[32+rbp*8+rsi]
        +	mov	r10,QWORD PTR[48+rbp*8+rbx]
        +	mov	r11,QWORD PTR[56+rbp*8+rbx]
        +	sbb	rdx,QWORD PTR[40+rbp*8+rsi]
        +	lea	rbp,QWORD PTR[4+rbp]
        +	dec	rcx
        +	jnz	$L$sqr4x_sub
        +
        +	mov	QWORD PTR[rbp*8+rdi],rax
        +	mov	rax,QWORD PTR[32+rbp*8+rbx]
        +	sbb	r10,QWORD PTR[16+rbp*8+rsi]
        +	mov	QWORD PTR[8+rbp*8+rdi],rdx
        +	sbb	r11,QWORD PTR[24+rbp*8+rsi]
        +	mov	QWORD PTR[16+rbp*8+rdi],r10
        +
        +	sbb	rax,0
        +	mov	QWORD PTR[24+rbp*8+rdi],r11
        +	xor	rbp,rbp
        +	and	rbx,rax
        +	not	rax
        +	mov	rsi,rdi
        +	and	rsi,rax
        +	lea	rcx,QWORD PTR[((-1))+r9]
        +	or	rbx,rsi
        +
        +	pxor	xmm0,xmm0
        +	lea	rsi,QWORD PTR[64+r9*8+rsp]
        +	movdqu	xmm1,XMMWORD PTR[rbx]
        +	lea	rsi,QWORD PTR[r9*8+rsi]
        +	movdqa	XMMWORD PTR[64+rsp],xmm0
        +	movdqa	XMMWORD PTR[rsi],xmm0
        +	movdqu	XMMWORD PTR[rdi],xmm1
        +	jmp	$L$sqr4x_copy
        +ALIGN	16
        +$L$sqr4x_copy::
        +	movdqu	xmm2,XMMWORD PTR[16+rbp*1+rbx]
        +	movdqu	xmm1,XMMWORD PTR[32+rbp*1+rbx]
        +	movdqa	XMMWORD PTR[80+rbp*1+rsp],xmm0
        +	movdqa	XMMWORD PTR[96+rbp*1+rsp],xmm0
        +	movdqa	XMMWORD PTR[16+rbp*1+rsi],xmm0
        +	movdqa	XMMWORD PTR[32+rbp*1+rsi],xmm0
        +	movdqu	XMMWORD PTR[16+rbp*1+rdi],xmm2
        +	movdqu	XMMWORD PTR[32+rbp*1+rdi],xmm1
        +	lea	rbp,QWORD PTR[32+rbp]
        +	dec	rcx
        +	jnz	$L$sqr4x_copy
        +
        +	movdqu	xmm2,XMMWORD PTR[16+rbp*1+rbx]
        +	movdqa	XMMWORD PTR[80+rbp*1+rsp],xmm0
        +	movdqa	XMMWORD PTR[16+rbp*1+rsi],xmm0
        +	movdqu	XMMWORD PTR[16+rbp*1+rdi],xmm2
        +	mov	rsi,QWORD PTR[56+rsp]
        +	mov	rax,1
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$sqr4x_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_bn_sqr4x_mont::
        +bn_sqr4x_mont	ENDP
        +DB	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
        +DB	112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56
        +DB	54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83
        +DB	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +DB	115,108,46,111,114,103,62,0
        +ALIGN	16
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +mul_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	mov	r10,QWORD PTR[192+r8]
        +	mov	rax,QWORD PTR[8+r10*8+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +	jmp	$L$common_seh_tail
        +mul_handler	ENDP
        +
        +
        +ALIGN	16
        +sqr_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$sqr4x_body]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$sqr4x_epilogue]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[56+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$common_seh_tail::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +sqr_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_bn_mul_mont
        +	DD	imagerel $L$SEH_end_bn_mul_mont
        +	DD	imagerel $L$SEH_info_bn_mul_mont
        +
        +	DD	imagerel $L$SEH_begin_bn_mul4x_mont
        +	DD	imagerel $L$SEH_end_bn_mul4x_mont
        +	DD	imagerel $L$SEH_info_bn_mul4x_mont
        +
        +	DD	imagerel $L$SEH_begin_bn_sqr4x_mont
        +	DD	imagerel $L$SEH_end_bn_sqr4x_mont
        +	DD	imagerel $L$SEH_info_bn_sqr4x_mont
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_bn_mul_mont::
        +DB	9,0,0,0
        +	DD	imagerel mul_handler
        +	DD	imagerel $L$mul_body,imagerel $L$mul_epilogue
        +
        +$L$SEH_info_bn_mul4x_mont::
        +DB	9,0,0,0
        +	DD	imagerel mul_handler
        +	DD	imagerel $L$mul4x_body,imagerel $L$mul4x_epilogue
        +
        +$L$SEH_info_bn_sqr4x_mont::
        +DB	9,0,0,0
        +	DD	imagerel sqr_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm
        new file mode 100644
        index 000000000..0ea789b6a
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/camellia/cmll-x86_64.asm
        @@ -0,0 +1,2108 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +
        +PUBLIC	Camellia_EncryptBlock
        +
        +ALIGN	16
        +Camellia_EncryptBlock	PROC PUBLIC
        +	mov	eax,128
        +	sub	eax,ecx
        +	mov	ecx,3
        +	adc	ecx,0
        +	jmp	$L$enc_rounds
        +Camellia_EncryptBlock	ENDP
        +
        +PUBLIC	Camellia_EncryptBlock_Rounds
        +
        +ALIGN	16
        +$L$enc_rounds::
        +Camellia_EncryptBlock_Rounds	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_Camellia_EncryptBlock_Rounds::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r13
        +	push	r14
        +	push	r15
        +$L$enc_prologue::
        +
        +
        +	mov	r13,rcx
        +	mov	r14,rdx
        +
        +	shl	edi,6
        +	lea	rbp,QWORD PTR[$L$Camellia_SBOX]
        +	lea	r15,QWORD PTR[rdi*1+r14]
        +
        +	mov	r8d,DWORD PTR[rsi]
        +	mov	r9d,DWORD PTR[4+rsi]
        +	mov	r10d,DWORD PTR[8+rsi]
        +	bswap	r8d
        +	mov	r11d,DWORD PTR[12+rsi]
        +	bswap	r9d
        +	bswap	r10d
        +	bswap	r11d
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	bswap	r8d
        +	bswap	r9d
        +	bswap	r10d
        +	mov	DWORD PTR[r13],r8d
        +	bswap	r11d
        +	mov	DWORD PTR[4+r13],r9d
        +	mov	DWORD PTR[8+r13],r10d
        +	mov	DWORD PTR[12+r13],r11d
        +
        +	mov	r15,QWORD PTR[rsp]
        +	mov	r14,QWORD PTR[8+rsp]
        +	mov	r13,QWORD PTR[16+rsp]
        +	mov	rbp,QWORD PTR[24+rsp]
        +	mov	rbx,QWORD PTR[32+rsp]
        +	lea	rsp,QWORD PTR[40+rsp]
        +$L$enc_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_Camellia_EncryptBlock_Rounds::
        +Camellia_EncryptBlock_Rounds	ENDP
        +
        +
        +ALIGN	16
        +_x86_64_Camellia_encrypt	PROC PRIVATE
        +	xor	r9d,DWORD PTR[r14]
        +	xor	r8d,DWORD PTR[4+r14]
        +	xor	r11d,DWORD PTR[8+r14]
        +	xor	r10d,DWORD PTR[12+r14]
        +ALIGN	16
        +$L$eloop::
        +	mov	ebx,DWORD PTR[16+r14]
        +	mov	eax,DWORD PTR[20+r14]
        +
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[24+r14]
        +	mov	eax,DWORD PTR[28+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[32+r14]
        +	mov	eax,DWORD PTR[36+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[40+r14]
        +	mov	eax,DWORD PTR[44+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[48+r14]
        +	mov	eax,DWORD PTR[52+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[56+r14]
        +	mov	eax,DWORD PTR[60+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[64+r14]
        +	mov	eax,DWORD PTR[68+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	lea	r14,QWORD PTR[64+r14]
        +	cmp	r14,r15
        +	mov	edx,DWORD PTR[8+r14]
        +	mov	ecx,DWORD PTR[12+r14]
        +	je	$L$edone
        +
        +	and	eax,r8d
        +	or	edx,r11d
        +	rol	eax,1
        +	xor	r10d,edx
        +	xor	r9d,eax
        +	and	ecx,r10d
        +	or	ebx,r9d
        +	rol	ecx,1
        +	xor	r8d,ebx
        +	xor	r11d,ecx
        +	jmp	$L$eloop
        +
        +ALIGN	16
        +$L$edone::
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	xor	ecx,r8d
        +	xor	edx,r9d
        +
        +	mov	r8d,eax
        +	mov	r9d,ebx
        +	mov	r10d,ecx
        +	mov	r11d,edx
        +
        +DB	0f3h,0c3h
        +
        +_x86_64_Camellia_encrypt	ENDP
        +
        +
        +PUBLIC	Camellia_DecryptBlock
        +
        +ALIGN	16
        +Camellia_DecryptBlock	PROC PUBLIC
        +	mov	eax,128
        +	sub	eax,ecx
        +	mov	ecx,3
        +	adc	ecx,0
        +	jmp	$L$dec_rounds
        +Camellia_DecryptBlock	ENDP
        +
        +PUBLIC	Camellia_DecryptBlock_Rounds
        +
        +ALIGN	16
        +$L$dec_rounds::
        +Camellia_DecryptBlock_Rounds	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_Camellia_DecryptBlock_Rounds::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r13
        +	push	r14
        +	push	r15
        +$L$dec_prologue::
        +
        +
        +	mov	r13,rcx
        +	mov	r15,rdx
        +
        +	shl	edi,6
        +	lea	rbp,QWORD PTR[$L$Camellia_SBOX]
        +	lea	r14,QWORD PTR[rdi*1+r15]
        +
        +	mov	r8d,DWORD PTR[rsi]
        +	mov	r9d,DWORD PTR[4+rsi]
        +	mov	r10d,DWORD PTR[8+rsi]
        +	bswap	r8d
        +	mov	r11d,DWORD PTR[12+rsi]
        +	bswap	r9d
        +	bswap	r10d
        +	bswap	r11d
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	bswap	r8d
        +	bswap	r9d
        +	bswap	r10d
        +	mov	DWORD PTR[r13],r8d
        +	bswap	r11d
        +	mov	DWORD PTR[4+r13],r9d
        +	mov	DWORD PTR[8+r13],r10d
        +	mov	DWORD PTR[12+r13],r11d
        +
        +	mov	r15,QWORD PTR[rsp]
        +	mov	r14,QWORD PTR[8+rsp]
        +	mov	r13,QWORD PTR[16+rsp]
        +	mov	rbp,QWORD PTR[24+rsp]
        +	mov	rbx,QWORD PTR[32+rsp]
        +	lea	rsp,QWORD PTR[40+rsp]
        +$L$dec_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_Camellia_DecryptBlock_Rounds::
        +Camellia_DecryptBlock_Rounds	ENDP
        +
        +
        +ALIGN	16
        +_x86_64_Camellia_decrypt	PROC PRIVATE
        +	xor	r9d,DWORD PTR[r14]
        +	xor	r8d,DWORD PTR[4+r14]
        +	xor	r11d,DWORD PTR[8+r14]
        +	xor	r10d,DWORD PTR[12+r14]
        +ALIGN	16
        +$L$dloop::
        +	mov	ebx,DWORD PTR[((-8))+r14]
        +	mov	eax,DWORD PTR[((-4))+r14]
        +
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[((-16))+r14]
        +	mov	eax,DWORD PTR[((-12))+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[((-24))+r14]
        +	mov	eax,DWORD PTR[((-20))+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[((-32))+r14]
        +	mov	eax,DWORD PTR[((-28))+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[((-40))+r14]
        +	mov	eax,DWORD PTR[((-36))+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[((-48))+r14]
        +	mov	eax,DWORD PTR[((-44))+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[((-56))+r14]
        +	mov	eax,DWORD PTR[((-52))+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	lea	r14,QWORD PTR[((-64))+r14]
        +	cmp	r14,r15
        +	mov	edx,DWORD PTR[r14]
        +	mov	ecx,DWORD PTR[4+r14]
        +	je	$L$ddone
        +
        +	and	eax,r8d
        +	or	edx,r11d
        +	rol	eax,1
        +	xor	r10d,edx
        +	xor	r9d,eax
        +	and	ecx,r10d
        +	or	ebx,r9d
        +	rol	ecx,1
        +	xor	r8d,ebx
        +	xor	r11d,ecx
        +
        +	jmp	$L$dloop
        +
        +ALIGN	16
        +$L$ddone::
        +	xor	ecx,r10d
        +	xor	edx,r11d
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +
        +	mov	r8d,ecx
        +	mov	r9d,edx
        +	mov	r10d,eax
        +	mov	r11d,ebx
        +
        +DB	0f3h,0c3h
        +
        +_x86_64_Camellia_decrypt	ENDP
        +PUBLIC	Camellia_Ekeygen
        +
        +ALIGN	16
        +Camellia_Ekeygen	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_Camellia_Ekeygen::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r13
        +	push	r14
        +	push	r15
        +$L$key_prologue::
        +
        +	mov	r15,rdi
        +	mov	r13,rdx
        +
        +	mov	r8d,DWORD PTR[rsi]
        +	mov	r9d,DWORD PTR[4+rsi]
        +	mov	r10d,DWORD PTR[8+rsi]
        +	mov	r11d,DWORD PTR[12+rsi]
        +
        +	bswap	r8d
        +	bswap	r9d
        +	bswap	r10d
        +	bswap	r11d
        +	mov	DWORD PTR[r13],r9d
        +	mov	DWORD PTR[4+r13],r8d
        +	mov	DWORD PTR[8+r13],r11d
        +	mov	DWORD PTR[12+r13],r10d
        +	cmp	r15,128
        +	je	$L$1st128
        +
        +	mov	r8d,DWORD PTR[16+rsi]
        +	mov	r9d,DWORD PTR[20+rsi]
        +	cmp	r15,192
        +	je	$L$1st192
        +	mov	r10d,DWORD PTR[24+rsi]
        +	mov	r11d,DWORD PTR[28+rsi]
        +	jmp	$L$1st256
        +$L$1st192::
        +	mov	r10d,r8d
        +	mov	r11d,r9d
        +	not	r10d
        +	not	r11d
        +$L$1st256::
        +	bswap	r8d
        +	bswap	r9d
        +	bswap	r10d
        +	bswap	r11d
        +	mov	DWORD PTR[32+r13],r9d
        +	mov	DWORD PTR[36+r13],r8d
        +	mov	DWORD PTR[40+r13],r11d
        +	mov	DWORD PTR[44+r13],r10d
        +	xor	r9d,DWORD PTR[r13]
        +	xor	r8d,DWORD PTR[4+r13]
        +	xor	r11d,DWORD PTR[8+r13]
        +	xor	r10d,DWORD PTR[12+r13]
        +
        +$L$1st128::
        +	lea	r14,QWORD PTR[$L$Camellia_SIGMA]
        +	lea	rbp,QWORD PTR[$L$Camellia_SBOX]
        +
        +	mov	ebx,DWORD PTR[r14]
        +	mov	eax,DWORD PTR[4+r14]
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[8+r14]
        +	mov	eax,DWORD PTR[12+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[16+r14]
        +	mov	eax,DWORD PTR[20+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	xor	r9d,DWORD PTR[r13]
        +	xor	r8d,DWORD PTR[4+r13]
        +	xor	r11d,DWORD PTR[8+r13]
        +	xor	r10d,DWORD PTR[12+r13]
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[24+r14]
        +	mov	eax,DWORD PTR[28+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[32+r14]
        +	mov	eax,DWORD PTR[36+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	cmp	r15,128
        +	jne	$L$2nd256
        +
        +	lea	r13,QWORD PTR[128+r13]
        +	shl	r8,32
        +	shl	r10,32
        +	or	r8,r9
        +	or	r10,r11
        +	mov	rax,QWORD PTR[((-128))+r13]
        +	mov	rbx,QWORD PTR[((-120))+r13]
        +	mov	QWORD PTR[((-112))+r13],r8
        +	mov	QWORD PTR[((-104))+r13],r10
        +	mov	r11,rax
        +	shl	rax,15
        +	mov	r9,rbx
        +	shr	r9,49
        +	shr	r11,49
        +	or	rax,r9
        +	shl	rbx,15
        +	or	rbx,r11
        +	mov	QWORD PTR[((-96))+r13],rax
        +	mov	QWORD PTR[((-88))+r13],rbx
        +	mov	r11,r8
        +	shl	r8,15
        +	mov	r9,r10
        +	shr	r9,49
        +	shr	r11,49
        +	or	r8,r9
        +	shl	r10,15
        +	or	r10,r11
        +	mov	QWORD PTR[((-80))+r13],r8
        +	mov	QWORD PTR[((-72))+r13],r10
        +	mov	r11,r8
        +	shl	r8,15
        +	mov	r9,r10
        +	shr	r9,49
        +	shr	r11,49
        +	or	r8,r9
        +	shl	r10,15
        +	or	r10,r11
        +	mov	QWORD PTR[((-64))+r13],r8
        +	mov	QWORD PTR[((-56))+r13],r10
        +	mov	r11,rax
        +	shl	rax,30
        +	mov	r9,rbx
        +	shr	r9,34
        +	shr	r11,34
        +	or	rax,r9
        +	shl	rbx,30
        +	or	rbx,r11
        +	mov	QWORD PTR[((-48))+r13],rax
        +	mov	QWORD PTR[((-40))+r13],rbx
        +	mov	r11,r8
        +	shl	r8,15
        +	mov	r9,r10
        +	shr	r9,49
        +	shr	r11,49
        +	or	r8,r9
        +	shl	r10,15
        +	or	r10,r11
        +	mov	QWORD PTR[((-32))+r13],r8
        +	mov	r11,rax
        +	shl	rax,15
        +	mov	r9,rbx
        +	shr	r9,49
        +	shr	r11,49
        +	or	rax,r9
        +	shl	rbx,15
        +	or	rbx,r11
        +	mov	QWORD PTR[((-24))+r13],rbx
        +	mov	r11,r8
        +	shl	r8,15
        +	mov	r9,r10
        +	shr	r9,49
        +	shr	r11,49
        +	or	r8,r9
        +	shl	r10,15
        +	or	r10,r11
        +	mov	QWORD PTR[((-16))+r13],r8
        +	mov	QWORD PTR[((-8))+r13],r10
        +	mov	r11,rax
        +	shl	rax,17
        +	mov	r9,rbx
        +	shr	r9,47
        +	shr	r11,47
        +	or	rax,r9
        +	shl	rbx,17
        +	or	rbx,r11
        +	mov	QWORD PTR[r13],rax
        +	mov	QWORD PTR[8+r13],rbx
        +	mov	r11,rax
        +	shl	rax,17
        +	mov	r9,rbx
        +	shr	r9,47
        +	shr	r11,47
        +	or	rax,r9
        +	shl	rbx,17
        +	or	rbx,r11
        +	mov	QWORD PTR[16+r13],rax
        +	mov	QWORD PTR[24+r13],rbx
        +	mov	r11,r8
        +	shl	r8,34
        +	mov	r9,r10
        +	shr	r9,30
        +	shr	r11,30
        +	or	r8,r9
        +	shl	r10,34
        +	or	r10,r11
        +	mov	QWORD PTR[32+r13],r8
        +	mov	QWORD PTR[40+r13],r10
        +	mov	r11,rax
        +	shl	rax,17
        +	mov	r9,rbx
        +	shr	r9,47
        +	shr	r11,47
        +	or	rax,r9
        +	shl	rbx,17
        +	or	rbx,r11
        +	mov	QWORD PTR[48+r13],rax
        +	mov	QWORD PTR[56+r13],rbx
        +	mov	r11,r8
        +	shl	r8,17
        +	mov	r9,r10
        +	shr	r9,47
        +	shr	r11,47
        +	or	r8,r9
        +	shl	r10,17
        +	or	r10,r11
        +	mov	QWORD PTR[64+r13],r8
        +	mov	QWORD PTR[72+r13],r10
        +	mov	eax,3
        +	jmp	$L$done
        +ALIGN	16
        +$L$2nd256::
        +	mov	DWORD PTR[48+r13],r9d
        +	mov	DWORD PTR[52+r13],r8d
        +	mov	DWORD PTR[56+r13],r11d
        +	mov	DWORD PTR[60+r13],r10d
        +	xor	r9d,DWORD PTR[32+r13]
        +	xor	r8d,DWORD PTR[36+r13]
        +	xor	r11d,DWORD PTR[40+r13]
        +	xor	r10d,DWORD PTR[44+r13]
        +	xor	eax,r8d
        +	xor	ebx,r9d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[40+r14]
        +	mov	eax,DWORD PTR[44+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r10d,ecx
        +	xor	r11d,ecx
        +	xor	r11d,edx
        +	xor	eax,r10d
        +	xor	ebx,r11d
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	mov	edx,DWORD PTR[2052+rsi*8+rbp]
        +	mov	ecx,DWORD PTR[rdi*8+rbp]
        +	movzx	esi,al
        +	shr	eax,16
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[4+rsi*8+rbp]
        +	shr	ebx,16
        +	xor	ecx,DWORD PTR[4+rdi*8+rbp]
        +	movzx	esi,ah
        +	movzx	edi,bl
        +	xor	edx,DWORD PTR[rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2052+rdi*8+rbp]
        +	movzx	esi,al
        +	movzx	edi,bh
        +	xor	edx,DWORD PTR[2048+rsi*8+rbp]
        +	xor	ecx,DWORD PTR[2048+rdi*8+rbp]
        +	mov	ebx,DWORD PTR[48+r14]
        +	mov	eax,DWORD PTR[52+r14]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	r8d,ecx
        +	xor	r9d,ecx
        +	xor	r9d,edx
        +	mov	rax,QWORD PTR[r13]
        +	mov	rbx,QWORD PTR[8+r13]
        +	mov	rcx,QWORD PTR[32+r13]
        +	mov	rdx,QWORD PTR[40+r13]
        +	mov	r14,QWORD PTR[48+r13]
        +	mov	r15,QWORD PTR[56+r13]
        +	lea	r13,QWORD PTR[128+r13]
        +	shl	r8,32
        +	shl	r10,32
        +	or	r8,r9
        +	or	r10,r11
        +	mov	QWORD PTR[((-112))+r13],r8
        +	mov	QWORD PTR[((-104))+r13],r10
        +	mov	r11,rcx
        +	shl	rcx,15
        +	mov	r9,rdx
        +	shr	r9,49
        +	shr	r11,49
        +	or	rcx,r9
        +	shl	rdx,15
        +	or	rdx,r11
        +	mov	QWORD PTR[((-96))+r13],rcx
        +	mov	QWORD PTR[((-88))+r13],rdx
        +	mov	r11,r14
        +	shl	r14,15
        +	mov	r9,r15
        +	shr	r9,49
        +	shr	r11,49
        +	or	r14,r9
        +	shl	r15,15
        +	or	r15,r11
        +	mov	QWORD PTR[((-80))+r13],r14
        +	mov	QWORD PTR[((-72))+r13],r15
        +	mov	r11,rcx
        +	shl	rcx,15
        +	mov	r9,rdx
        +	shr	r9,49
        +	shr	r11,49
        +	or	rcx,r9
        +	shl	rdx,15
        +	or	rdx,r11
        +	mov	QWORD PTR[((-64))+r13],rcx
        +	mov	QWORD PTR[((-56))+r13],rdx
        +	mov	r11,r8
        +	shl	r8,30
        +	mov	r9,r10
        +	shr	r9,34
        +	shr	r11,34
        +	or	r8,r9
        +	shl	r10,30
        +	or	r10,r11
        +	mov	QWORD PTR[((-48))+r13],r8
        +	mov	QWORD PTR[((-40))+r13],r10
        +	mov	r11,rax
        +	shl	rax,45
        +	mov	r9,rbx
        +	shr	r9,19
        +	shr	r11,19
        +	or	rax,r9
        +	shl	rbx,45
        +	or	rbx,r11
        +	mov	QWORD PTR[((-32))+r13],rax
        +	mov	QWORD PTR[((-24))+r13],rbx
        +	mov	r11,r14
        +	shl	r14,30
        +	mov	r9,r15
        +	shr	r9,34
        +	shr	r11,34
        +	or	r14,r9
        +	shl	r15,30
        +	or	r15,r11
        +	mov	QWORD PTR[((-16))+r13],r14
        +	mov	QWORD PTR[((-8))+r13],r15
        +	mov	r11,rax
        +	shl	rax,15
        +	mov	r9,rbx
        +	shr	r9,49
        +	shr	r11,49
        +	or	rax,r9
        +	shl	rbx,15
        +	or	rbx,r11
        +	mov	QWORD PTR[r13],rax
        +	mov	QWORD PTR[8+r13],rbx
        +	mov	r11,rcx
        +	shl	rcx,30
        +	mov	r9,rdx
        +	shr	r9,34
        +	shr	r11,34
        +	or	rcx,r9
        +	shl	rdx,30
        +	or	rdx,r11
        +	mov	QWORD PTR[16+r13],rcx
        +	mov	QWORD PTR[24+r13],rdx
        +	mov	r11,r8
        +	shl	r8,30
        +	mov	r9,r10
        +	shr	r9,34
        +	shr	r11,34
        +	or	r8,r9
        +	shl	r10,30
        +	or	r10,r11
        +	mov	QWORD PTR[32+r13],r8
        +	mov	QWORD PTR[40+r13],r10
        +	mov	r11,rax
        +	shl	rax,17
        +	mov	r9,rbx
        +	shr	r9,47
        +	shr	r11,47
        +	or	rax,r9
        +	shl	rbx,17
        +	or	rbx,r11
        +	mov	QWORD PTR[48+r13],rax
        +	mov	QWORD PTR[56+r13],rbx
        +	mov	r11,r14
        +	shl	r14,32
        +	mov	r9,r15
        +	shr	r9,32
        +	shr	r11,32
        +	or	r14,r9
        +	shl	r15,32
        +	or	r15,r11
        +	mov	QWORD PTR[64+r13],r14
        +	mov	QWORD PTR[72+r13],r15
        +	mov	r11,rcx
        +	shl	rcx,34
        +	mov	r9,rdx
        +	shr	r9,30
        +	shr	r11,30
        +	or	rcx,r9
        +	shl	rdx,34
        +	or	rdx,r11
        +	mov	QWORD PTR[80+r13],rcx
        +	mov	QWORD PTR[88+r13],rdx
        +	mov	r11,r14
        +	shl	r14,17
        +	mov	r9,r15
        +	shr	r9,47
        +	shr	r11,47
        +	or	r14,r9
        +	shl	r15,17
        +	or	r15,r11
        +	mov	QWORD PTR[96+r13],r14
        +	mov	QWORD PTR[104+r13],r15
        +	mov	r11,rax
        +	shl	rax,34
        +	mov	r9,rbx
        +	shr	r9,30
        +	shr	r11,30
        +	or	rax,r9
        +	shl	rbx,34
        +	or	rbx,r11
        +	mov	QWORD PTR[112+r13],rax
        +	mov	QWORD PTR[120+r13],rbx
        +	mov	r11,r8
        +	shl	r8,51
        +	mov	r9,r10
        +	shr	r9,13
        +	shr	r11,13
        +	or	r8,r9
        +	shl	r10,51
        +	or	r10,r11
        +	mov	QWORD PTR[128+r13],r8
        +	mov	QWORD PTR[136+r13],r10
        +	mov	eax,4
        +$L$done::
        +	mov	r15,QWORD PTR[rsp]
        +	mov	r14,QWORD PTR[8+rsp]
        +	mov	r13,QWORD PTR[16+rsp]
        +	mov	rbp,QWORD PTR[24+rsp]
        +	mov	rbx,QWORD PTR[32+rsp]
        +	lea	rsp,QWORD PTR[40+rsp]
        +$L$key_epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_Camellia_Ekeygen::
        +Camellia_Ekeygen	ENDP
        +ALIGN	64
        +$L$Camellia_SIGMA::
        +	DD	03bcc908bh,0a09e667fh,04caa73b2h,0b67ae858h
        +	DD	0e94f82beh,0c6ef372fh,0f1d36f1ch,054ff53a5h
        +	DD	0de682d1dh,010e527fah,0b3e6c1fdh,0b05688c2h
        +	DD	0,0,0,0
        +$L$Camellia_SBOX::
        +	DD	070707000h,070700070h
        +	DD	082828200h,02c2c002ch
        +	DD	02c2c2c00h,0b3b300b3h
        +	DD	0ececec00h,0c0c000c0h
        +	DD	0b3b3b300h,0e4e400e4h
        +	DD	027272700h,057570057h
        +	DD	0c0c0c000h,0eaea00eah
        +	DD	0e5e5e500h,0aeae00aeh
        +	DD	0e4e4e400h,023230023h
        +	DD	085858500h,06b6b006bh
        +	DD	057575700h,045450045h
        +	DD	035353500h,0a5a500a5h
        +	DD	0eaeaea00h,0eded00edh
        +	DD	00c0c0c00h,04f4f004fh
        +	DD	0aeaeae00h,01d1d001dh
        +	DD	041414100h,092920092h
        +	DD	023232300h,086860086h
        +	DD	0efefef00h,0afaf00afh
        +	DD	06b6b6b00h,07c7c007ch
        +	DD	093939300h,01f1f001fh
        +	DD	045454500h,03e3e003eh
        +	DD	019191900h,0dcdc00dch
        +	DD	0a5a5a500h,05e5e005eh
        +	DD	021212100h,00b0b000bh
        +	DD	0ededed00h,0a6a600a6h
        +	DD	00e0e0e00h,039390039h
        +	DD	04f4f4f00h,0d5d500d5h
        +	DD	04e4e4e00h,05d5d005dh
        +	DD	01d1d1d00h,0d9d900d9h
        +	DD	065656500h,05a5a005ah
        +	DD	092929200h,051510051h
        +	DD	0bdbdbd00h,06c6c006ch
        +	DD	086868600h,08b8b008bh
        +	DD	0b8b8b800h,09a9a009ah
        +	DD	0afafaf00h,0fbfb00fbh
        +	DD	08f8f8f00h,0b0b000b0h
        +	DD	07c7c7c00h,074740074h
        +	DD	0ebebeb00h,02b2b002bh
        +	DD	01f1f1f00h,0f0f000f0h
        +	DD	0cecece00h,084840084h
        +	DD	03e3e3e00h,0dfdf00dfh
        +	DD	030303000h,0cbcb00cbh
        +	DD	0dcdcdc00h,034340034h
        +	DD	05f5f5f00h,076760076h
        +	DD	05e5e5e00h,06d6d006dh
        +	DD	0c5c5c500h,0a9a900a9h
        +	DD	00b0b0b00h,0d1d100d1h
        +	DD	01a1a1a00h,004040004h
        +	DD	0a6a6a600h,014140014h
        +	DD	0e1e1e100h,03a3a003ah
        +	DD	039393900h,0dede00deh
        +	DD	0cacaca00h,011110011h
        +	DD	0d5d5d500h,032320032h
        +	DD	047474700h,09c9c009ch
        +	DD	05d5d5d00h,053530053h
        +	DD	03d3d3d00h,0f2f200f2h
        +	DD	0d9d9d900h,0fefe00feh
        +	DD	001010100h,0cfcf00cfh
        +	DD	05a5a5a00h,0c3c300c3h
        +	DD	0d6d6d600h,07a7a007ah
        +	DD	051515100h,024240024h
        +	DD	056565600h,0e8e800e8h
        +	DD	06c6c6c00h,060600060h
        +	DD	04d4d4d00h,069690069h
        +	DD	08b8b8b00h,0aaaa00aah
        +	DD	00d0d0d00h,0a0a000a0h
        +	DD	09a9a9a00h,0a1a100a1h
        +	DD	066666600h,062620062h
        +	DD	0fbfbfb00h,054540054h
        +	DD	0cccccc00h,01e1e001eh
        +	DD	0b0b0b000h,0e0e000e0h
        +	DD	02d2d2d00h,064640064h
        +	DD	074747400h,010100010h
        +	DD	012121200h,000000000h
        +	DD	02b2b2b00h,0a3a300a3h
        +	DD	020202000h,075750075h
        +	DD	0f0f0f000h,08a8a008ah
        +	DD	0b1b1b100h,0e6e600e6h
        +	DD	084848400h,009090009h
        +	DD	099999900h,0dddd00ddh
        +	DD	0dfdfdf00h,087870087h
        +	DD	04c4c4c00h,083830083h
        +	DD	0cbcbcb00h,0cdcd00cdh
        +	DD	0c2c2c200h,090900090h
        +	DD	034343400h,073730073h
        +	DD	07e7e7e00h,0f6f600f6h
        +	DD	076767600h,09d9d009dh
        +	DD	005050500h,0bfbf00bfh
        +	DD	06d6d6d00h,052520052h
        +	DD	0b7b7b700h,0d8d800d8h
        +	DD	0a9a9a900h,0c8c800c8h
        +	DD	031313100h,0c6c600c6h
        +	DD	0d1d1d100h,081810081h
        +	DD	017171700h,06f6f006fh
        +	DD	004040400h,013130013h
        +	DD	0d7d7d700h,063630063h
        +	DD	014141400h,0e9e900e9h
        +	DD	058585800h,0a7a700a7h
        +	DD	03a3a3a00h,09f9f009fh
        +	DD	061616100h,0bcbc00bch
        +	DD	0dedede00h,029290029h
        +	DD	01b1b1b00h,0f9f900f9h
        +	DD	011111100h,02f2f002fh
        +	DD	01c1c1c00h,0b4b400b4h
        +	DD	032323200h,078780078h
        +	DD	00f0f0f00h,006060006h
        +	DD	09c9c9c00h,0e7e700e7h
        +	DD	016161600h,071710071h
        +	DD	053535300h,0d4d400d4h
        +	DD	018181800h,0abab00abh
        +	DD	0f2f2f200h,088880088h
        +	DD	022222200h,08d8d008dh
        +	DD	0fefefe00h,072720072h
        +	DD	044444400h,0b9b900b9h
        +	DD	0cfcfcf00h,0f8f800f8h
        +	DD	0b2b2b200h,0acac00ach
        +	DD	0c3c3c300h,036360036h
        +	DD	0b5b5b500h,02a2a002ah
        +	DD	07a7a7a00h,03c3c003ch
        +	DD	091919100h,0f1f100f1h
        +	DD	024242400h,040400040h
        +	DD	008080800h,0d3d300d3h
        +	DD	0e8e8e800h,0bbbb00bbh
        +	DD	0a8a8a800h,043430043h
        +	DD	060606000h,015150015h
        +	DD	0fcfcfc00h,0adad00adh
        +	DD	069696900h,077770077h
        +	DD	050505000h,080800080h
        +	DD	0aaaaaa00h,082820082h
        +	DD	0d0d0d000h,0ecec00ech
        +	DD	0a0a0a000h,027270027h
        +	DD	07d7d7d00h,0e5e500e5h
        +	DD	0a1a1a100h,085850085h
        +	DD	089898900h,035350035h
        +	DD	062626200h,00c0c000ch
        +	DD	097979700h,041410041h
        +	DD	054545400h,0efef00efh
        +	DD	05b5b5b00h,093930093h
        +	DD	01e1e1e00h,019190019h
        +	DD	095959500h,021210021h
        +	DD	0e0e0e000h,00e0e000eh
        +	DD	0ffffff00h,04e4e004eh
        +	DD	064646400h,065650065h
        +	DD	0d2d2d200h,0bdbd00bdh
        +	DD	010101000h,0b8b800b8h
        +	DD	0c4c4c400h,08f8f008fh
        +	DD	000000000h,0ebeb00ebh
        +	DD	048484800h,0cece00ceh
        +	DD	0a3a3a300h,030300030h
        +	DD	0f7f7f700h,05f5f005fh
        +	DD	075757500h,0c5c500c5h
        +	DD	0dbdbdb00h,01a1a001ah
        +	DD	08a8a8a00h,0e1e100e1h
        +	DD	003030300h,0caca00cah
        +	DD	0e6e6e600h,047470047h
        +	DD	0dadada00h,03d3d003dh
        +	DD	009090900h,001010001h
        +	DD	03f3f3f00h,0d6d600d6h
        +	DD	0dddddd00h,056560056h
        +	DD	094949400h,04d4d004dh
        +	DD	087878700h,00d0d000dh
        +	DD	05c5c5c00h,066660066h
        +	DD	083838300h,0cccc00cch
        +	DD	002020200h,02d2d002dh
        +	DD	0cdcdcd00h,012120012h
        +	DD	04a4a4a00h,020200020h
        +	DD	090909000h,0b1b100b1h
        +	DD	033333300h,099990099h
        +	DD	073737300h,04c4c004ch
        +	DD	067676700h,0c2c200c2h
        +	DD	0f6f6f600h,07e7e007eh
        +	DD	0f3f3f300h,005050005h
        +	DD	09d9d9d00h,0b7b700b7h
        +	DD	07f7f7f00h,031310031h
        +	DD	0bfbfbf00h,017170017h
        +	DD	0e2e2e200h,0d7d700d7h
        +	DD	052525200h,058580058h
        +	DD	09b9b9b00h,061610061h
        +	DD	0d8d8d800h,01b1b001bh
        +	DD	026262600h,01c1c001ch
        +	DD	0c8c8c800h,00f0f000fh
        +	DD	037373700h,016160016h
        +	DD	0c6c6c600h,018180018h
        +	DD	03b3b3b00h,022220022h
        +	DD	081818100h,044440044h
        +	DD	096969600h,0b2b200b2h
        +	DD	06f6f6f00h,0b5b500b5h
        +	DD	04b4b4b00h,091910091h
        +	DD	013131300h,008080008h
        +	DD	0bebebe00h,0a8a800a8h
        +	DD	063636300h,0fcfc00fch
        +	DD	02e2e2e00h,050500050h
        +	DD	0e9e9e900h,0d0d000d0h
        +	DD	079797900h,07d7d007dh
        +	DD	0a7a7a700h,089890089h
        +	DD	08c8c8c00h,097970097h
        +	DD	09f9f9f00h,05b5b005bh
        +	DD	06e6e6e00h,095950095h
        +	DD	0bcbcbc00h,0ffff00ffh
        +	DD	08e8e8e00h,0d2d200d2h
        +	DD	029292900h,0c4c400c4h
        +	DD	0f5f5f500h,048480048h
        +	DD	0f9f9f900h,0f7f700f7h
        +	DD	0b6b6b600h,0dbdb00dbh
        +	DD	02f2f2f00h,003030003h
        +	DD	0fdfdfd00h,0dada00dah
        +	DD	0b4b4b400h,03f3f003fh
        +	DD	059595900h,094940094h
        +	DD	078787800h,05c5c005ch
        +	DD	098989800h,002020002h
        +	DD	006060600h,04a4a004ah
        +	DD	06a6a6a00h,033330033h
        +	DD	0e7e7e700h,067670067h
        +	DD	046464600h,0f3f300f3h
        +	DD	071717100h,07f7f007fh
        +	DD	0bababa00h,0e2e200e2h
        +	DD	0d4d4d400h,09b9b009bh
        +	DD	025252500h,026260026h
        +	DD	0ababab00h,037370037h
        +	DD	042424200h,03b3b003bh
        +	DD	088888800h,096960096h
        +	DD	0a2a2a200h,04b4b004bh
        +	DD	08d8d8d00h,0bebe00beh
        +	DD	0fafafa00h,02e2e002eh
        +	DD	072727200h,079790079h
        +	DD	007070700h,08c8c008ch
        +	DD	0b9b9b900h,06e6e006eh
        +	DD	055555500h,08e8e008eh
        +	DD	0f8f8f800h,0f5f500f5h
        +	DD	0eeeeee00h,0b6b600b6h
        +	DD	0acacac00h,0fdfd00fdh
        +	DD	00a0a0a00h,059590059h
        +	DD	036363600h,098980098h
        +	DD	049494900h,06a6a006ah
        +	DD	02a2a2a00h,046460046h
        +	DD	068686800h,0baba00bah
        +	DD	03c3c3c00h,025250025h
        +	DD	038383800h,042420042h
        +	DD	0f1f1f100h,0a2a200a2h
        +	DD	0a4a4a400h,0fafa00fah
        +	DD	040404000h,007070007h
        +	DD	028282800h,055550055h
        +	DD	0d3d3d300h,0eeee00eeh
        +	DD	07b7b7b00h,00a0a000ah
        +	DD	0bbbbbb00h,049490049h
        +	DD	0c9c9c900h,068680068h
        +	DD	043434300h,038380038h
        +	DD	0c1c1c100h,0a4a400a4h
        +	DD	015151500h,028280028h
        +	DD	0e3e3e300h,07b7b007bh
        +	DD	0adadad00h,0c9c900c9h
        +	DD	0f4f4f400h,0c1c100c1h
        +	DD	077777700h,0e3e300e3h
        +	DD	0c7c7c700h,0f4f400f4h
        +	DD	080808000h,0c7c700c7h
        +	DD	09e9e9e00h,09e9e009eh
        +	DD	000e0e0e0h,038003838h
        +	DD	000050505h,041004141h
        +	DD	000585858h,016001616h
        +	DD	000d9d9d9h,076007676h
        +	DD	000676767h,0d900d9d9h
        +	DD	0004e4e4eh,093009393h
        +	DD	000818181h,060006060h
        +	DD	000cbcbcbh,0f200f2f2h
        +	DD	000c9c9c9h,072007272h
        +	DD	0000b0b0bh,0c200c2c2h
        +	DD	000aeaeaeh,0ab00ababh
        +	DD	0006a6a6ah,09a009a9ah
        +	DD	000d5d5d5h,075007575h
        +	DD	000181818h,006000606h
        +	DD	0005d5d5dh,057005757h
        +	DD	000828282h,0a000a0a0h
        +	DD	000464646h,091009191h
        +	DD	000dfdfdfh,0f700f7f7h
        +	DD	000d6d6d6h,0b500b5b5h
        +	DD	000272727h,0c900c9c9h
        +	DD	0008a8a8ah,0a200a2a2h
        +	DD	000323232h,08c008c8ch
        +	DD	0004b4b4bh,0d200d2d2h
        +	DD	000424242h,090009090h
        +	DD	000dbdbdbh,0f600f6f6h
        +	DD	0001c1c1ch,007000707h
        +	DD	0009e9e9eh,0a700a7a7h
        +	DD	0009c9c9ch,027002727h
        +	DD	0003a3a3ah,08e008e8eh
        +	DD	000cacacah,0b200b2b2h
        +	DD	000252525h,049004949h
        +	DD	0007b7b7bh,0de00dedeh
        +	DD	0000d0d0dh,043004343h
        +	DD	000717171h,05c005c5ch
        +	DD	0005f5f5fh,0d700d7d7h
        +	DD	0001f1f1fh,0c700c7c7h
        +	DD	000f8f8f8h,03e003e3eh
        +	DD	000d7d7d7h,0f500f5f5h
        +	DD	0003e3e3eh,08f008f8fh
        +	DD	0009d9d9dh,067006767h
        +	DD	0007c7c7ch,01f001f1fh
        +	DD	000606060h,018001818h
        +	DD	000b9b9b9h,06e006e6eh
        +	DD	000bebebeh,0af00afafh
        +	DD	000bcbcbch,02f002f2fh
        +	DD	0008b8b8bh,0e200e2e2h
        +	DD	000161616h,085008585h
        +	DD	000343434h,00d000d0dh
        +	DD	0004d4d4dh,053005353h
        +	DD	000c3c3c3h,0f000f0f0h
        +	DD	000727272h,09c009c9ch
        +	DD	000959595h,065006565h
        +	DD	000abababh,0ea00eaeah
        +	DD	0008e8e8eh,0a300a3a3h
        +	DD	000bababah,0ae00aeaeh
        +	DD	0007a7a7ah,09e009e9eh
        +	DD	000b3b3b3h,0ec00ecech
        +	DD	000020202h,080008080h
        +	DD	000b4b4b4h,02d002d2dh
        +	DD	000adadadh,06b006b6bh
        +	DD	000a2a2a2h,0a800a8a8h
        +	DD	000acacach,02b002b2bh
        +	DD	000d8d8d8h,036003636h
        +	DD	0009a9a9ah,0a600a6a6h
        +	DD	000171717h,0c500c5c5h
        +	DD	0001a1a1ah,086008686h
        +	DD	000353535h,04d004d4dh
        +	DD	000cccccch,033003333h
        +	DD	000f7f7f7h,0fd00fdfdh
        +	DD	000999999h,066006666h
        +	DD	000616161h,058005858h
        +	DD	0005a5a5ah,096009696h
        +	DD	000e8e8e8h,03a003a3ah
        +	DD	000242424h,009000909h
        +	DD	000565656h,095009595h
        +	DD	000404040h,010001010h
        +	DD	000e1e1e1h,078007878h
        +	DD	000636363h,0d800d8d8h
        +	DD	000090909h,042004242h
        +	DD	000333333h,0cc00cccch
        +	DD	000bfbfbfh,0ef00efefh
        +	DD	000989898h,026002626h
        +	DD	000979797h,0e500e5e5h
        +	DD	000858585h,061006161h
        +	DD	000686868h,01a001a1ah
        +	DD	000fcfcfch,03f003f3fh
        +	DD	000ececech,03b003b3bh
        +	DD	0000a0a0ah,082008282h
        +	DD	000dadadah,0b600b6b6h
        +	DD	0006f6f6fh,0db00dbdbh
        +	DD	000535353h,0d400d4d4h
        +	DD	000626262h,098009898h
        +	DD	000a3a3a3h,0e800e8e8h
        +	DD	0002e2e2eh,08b008b8bh
        +	DD	000080808h,002000202h
        +	DD	000afafafh,0eb00ebebh
        +	DD	000282828h,00a000a0ah
        +	DD	000b0b0b0h,02c002c2ch
        +	DD	000747474h,01d001d1dh
        +	DD	000c2c2c2h,0b000b0b0h
        +	DD	000bdbdbdh,06f006f6fh
        +	DD	000363636h,08d008d8dh
        +	DD	000222222h,088008888h
        +	DD	000383838h,00e000e0eh
        +	DD	000646464h,019001919h
        +	DD	0001e1e1eh,087008787h
        +	DD	000393939h,04e004e4eh
        +	DD	0002c2c2ch,00b000b0bh
        +	DD	000a6a6a6h,0a900a9a9h
        +	DD	000303030h,00c000c0ch
        +	DD	000e5e5e5h,079007979h
        +	DD	000444444h,011001111h
        +	DD	000fdfdfdh,07f007f7fh
        +	DD	000888888h,022002222h
        +	DD	0009f9f9fh,0e700e7e7h
        +	DD	000656565h,059005959h
        +	DD	000878787h,0e100e1e1h
        +	DD	0006b6b6bh,0da00dadah
        +	DD	000f4f4f4h,03d003d3dh
        +	DD	000232323h,0c800c8c8h
        +	DD	000484848h,012001212h
        +	DD	000101010h,004000404h
        +	DD	000d1d1d1h,074007474h
        +	DD	000515151h,054005454h
        +	DD	000c0c0c0h,030003030h
        +	DD	000f9f9f9h,07e007e7eh
        +	DD	000d2d2d2h,0b400b4b4h
        +	DD	000a0a0a0h,028002828h
        +	DD	000555555h,055005555h
        +	DD	000a1a1a1h,068006868h
        +	DD	000414141h,050005050h
        +	DD	000fafafah,0be00bebeh
        +	DD	000434343h,0d000d0d0h
        +	DD	000131313h,0c400c4c4h
        +	DD	000c4c4c4h,031003131h
        +	DD	0002f2f2fh,0cb00cbcbh
        +	DD	000a8a8a8h,02a002a2ah
        +	DD	000b6b6b6h,0ad00adadh
        +	DD	0003c3c3ch,00f000f0fh
        +	DD	0002b2b2bh,0ca00cacah
        +	DD	000c1c1c1h,070007070h
        +	DD	000ffffffh,0ff00ffffh
        +	DD	000c8c8c8h,032003232h
        +	DD	000a5a5a5h,069006969h
        +	DD	000202020h,008000808h
        +	DD	000898989h,062006262h
        +	DD	000000000h,000000000h
        +	DD	000909090h,024002424h
        +	DD	000474747h,0d100d1d1h
        +	DD	000efefefh,0fb00fbfbh
        +	DD	000eaeaeah,0ba00babah
        +	DD	000b7b7b7h,0ed00ededh
        +	DD	000151515h,045004545h
        +	DD	000060606h,081008181h
        +	DD	000cdcdcdh,073007373h
        +	DD	000b5b5b5h,06d006d6dh
        +	DD	000121212h,084008484h
        +	DD	0007e7e7eh,09f009f9fh
        +	DD	000bbbbbbh,0ee00eeeeh
        +	DD	000292929h,04a004a4ah
        +	DD	0000f0f0fh,0c300c3c3h
        +	DD	000b8b8b8h,02e002e2eh
        +	DD	000070707h,0c100c1c1h
        +	DD	000040404h,001000101h
        +	DD	0009b9b9bh,0e600e6e6h
        +	DD	000949494h,025002525h
        +	DD	000212121h,048004848h
        +	DD	000666666h,099009999h
        +	DD	000e6e6e6h,0b900b9b9h
        +	DD	000cececeh,0b300b3b3h
        +	DD	000edededh,07b007b7bh
        +	DD	000e7e7e7h,0f900f9f9h
        +	DD	0003b3b3bh,0ce00ceceh
        +	DD	000fefefeh,0bf00bfbfh
        +	DD	0007f7f7fh,0df00dfdfh
        +	DD	000c5c5c5h,071007171h
        +	DD	000a4a4a4h,029002929h
        +	DD	000373737h,0cd00cdcdh
        +	DD	000b1b1b1h,06c006c6ch
        +	DD	0004c4c4ch,013001313h
        +	DD	000919191h,064006464h
        +	DD	0006e6e6eh,09b009b9bh
        +	DD	0008d8d8dh,063006363h
        +	DD	000767676h,09d009d9dh
        +	DD	000030303h,0c000c0c0h
        +	DD	0002d2d2dh,04b004b4bh
        +	DD	000dededeh,0b700b7b7h
        +	DD	000969696h,0a500a5a5h
        +	DD	000262626h,089008989h
        +	DD	0007d7d7dh,05f005f5fh
        +	DD	000c6c6c6h,0b100b1b1h
        +	DD	0005c5c5ch,017001717h
        +	DD	000d3d3d3h,0f400f4f4h
        +	DD	000f2f2f2h,0bc00bcbch
        +	DD	0004f4f4fh,0d300d3d3h
        +	DD	000191919h,046004646h
        +	DD	0003f3f3fh,0cf00cfcfh
        +	DD	000dcdcdch,037003737h
        +	DD	000797979h,05e005e5eh
        +	DD	0001d1d1dh,047004747h
        +	DD	000525252h,094009494h
        +	DD	000ebebebh,0fa00fafah
        +	DD	000f3f3f3h,0fc00fcfch
        +	DD	0006d6d6dh,05b005b5bh
        +	DD	0005e5e5eh,097009797h
        +	DD	000fbfbfbh,0fe00fefeh
        +	DD	000696969h,05a005a5ah
        +	DD	000b2b2b2h,0ac00acach
        +	DD	000f0f0f0h,03c003c3ch
        +	DD	000313131h,04c004c4ch
        +	DD	0000c0c0ch,003000303h
        +	DD	000d4d4d4h,035003535h
        +	DD	000cfcfcfh,0f300f3f3h
        +	DD	0008c8c8ch,023002323h
        +	DD	000e2e2e2h,0b800b8b8h
        +	DD	000757575h,05d005d5dh
        +	DD	000a9a9a9h,06a006a6ah
        +	DD	0004a4a4ah,092009292h
        +	DD	000575757h,0d500d5d5h
        +	DD	000848484h,021002121h
        +	DD	000111111h,044004444h
        +	DD	000454545h,051005151h
        +	DD	0001b1b1bh,0c600c6c6h
        +	DD	000f5f5f5h,07d007d7dh
        +	DD	000e4e4e4h,039003939h
        +	DD	0000e0e0eh,083008383h
        +	DD	000737373h,0dc00dcdch
        +	DD	000aaaaaah,0aa00aaaah
        +	DD	000f1f1f1h,07c007c7ch
        +	DD	000ddddddh,077007777h
        +	DD	000595959h,056005656h
        +	DD	000141414h,005000505h
        +	DD	0006c6c6ch,01b001b1bh
        +	DD	000929292h,0a400a4a4h
        +	DD	000545454h,015001515h
        +	DD	000d0d0d0h,034003434h
        +	DD	000787878h,01e001e1eh
        +	DD	000707070h,01c001c1ch
        +	DD	000e3e3e3h,0f800f8f8h
        +	DD	000494949h,052005252h
        +	DD	000808080h,020002020h
        +	DD	000505050h,014001414h
        +	DD	000a7a7a7h,0e900e9e9h
        +	DD	000f6f6f6h,0bd00bdbdh
        +	DD	000777777h,0dd00ddddh
        +	DD	000939393h,0e400e4e4h
        +	DD	000868686h,0a100a1a1h
        +	DD	000838383h,0e000e0e0h
        +	DD	0002a2a2ah,08a008a8ah
        +	DD	000c7c7c7h,0f100f1f1h
        +	DD	0005b5b5bh,0d600d6d6h
        +	DD	000e9e9e9h,07a007a7ah
        +	DD	000eeeeeeh,0bb00bbbbh
        +	DD	0008f8f8fh,0e300e3e3h
        +	DD	000010101h,040004040h
        +	DD	0003d3d3dh,04f004f4fh
        +PUBLIC	Camellia_cbc_encrypt
        +
        +ALIGN	16
        +Camellia_cbc_encrypt	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_Camellia_cbc_encrypt::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	cmp	rdx,0
        +	je	$L$cbc_abort
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +$L$cbc_prologue::
        +
        +	mov	rbp,rsp
        +	sub	rsp,64
        +	and	rsp,-64
        +
        +
        +
        +	lea	r10,QWORD PTR[((-64-63))+rcx]
        +	sub	r10,rsp
        +	neg	r10
        +	and	r10,03C0h
        +	sub	rsp,r10
        +
        +
        +	mov	r12,rdi
        +	mov	r13,rsi
        +	mov	rbx,r8
        +	mov	r14,rcx
        +	mov	r15d,DWORD PTR[272+rcx]
        +
        +	mov	QWORD PTR[40+rsp],r8
        +	mov	QWORD PTR[48+rsp],rbp
        +
        +$L$cbc_body::
        +	lea	rbp,QWORD PTR[$L$Camellia_SBOX]
        +
        +	mov	ecx,32
        +ALIGN	4
        +$L$cbc_prefetch_sbox::
        +	mov	rax,QWORD PTR[rbp]
        +	mov	rsi,QWORD PTR[32+rbp]
        +	mov	rdi,QWORD PTR[64+rbp]
        +	mov	r11,QWORD PTR[96+rbp]
        +	lea	rbp,QWORD PTR[128+rbp]
        +	loop	$L$cbc_prefetch_sbox
        +	sub	rbp,4096
        +	shl	r15,6
        +	mov	rcx,rdx
        +	lea	r15,QWORD PTR[r15*1+r14]
        +
        +	cmp	r9d,0
        +	je	$L$CBC_DECRYPT
        +
        +	and	rdx,-16
        +	and	rcx,15
        +	lea	rdx,QWORD PTR[rdx*1+r12]
        +	mov	QWORD PTR[rsp],r14
        +	mov	QWORD PTR[8+rsp],rdx
        +	mov	QWORD PTR[16+rsp],rcx
        +
        +	cmp	rdx,r12
        +	mov	r8d,DWORD PTR[rbx]
        +	mov	r9d,DWORD PTR[4+rbx]
        +	mov	r10d,DWORD PTR[8+rbx]
        +	mov	r11d,DWORD PTR[12+rbx]
        +	je	$L$cbc_enc_tail
        +	jmp	$L$cbc_eloop
        +
        +ALIGN	16
        +$L$cbc_eloop::
        +	xor	r8d,DWORD PTR[r12]
        +	xor	r9d,DWORD PTR[4+r12]
        +	xor	r10d,DWORD PTR[8+r12]
        +	bswap	r8d
        +	xor	r11d,DWORD PTR[12+r12]
        +	bswap	r9d
        +	bswap	r10d
        +	bswap	r11d
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	mov	r14,QWORD PTR[rsp]
        +	bswap	r8d
        +	mov	rdx,QWORD PTR[8+rsp]
        +	bswap	r9d
        +	mov	rcx,QWORD PTR[16+rsp]
        +	bswap	r10d
        +	mov	DWORD PTR[r13],r8d
        +	bswap	r11d
        +	mov	DWORD PTR[4+r13],r9d
        +	mov	DWORD PTR[8+r13],r10d
        +	lea	r12,QWORD PTR[16+r12]
        +	mov	DWORD PTR[12+r13],r11d
        +	cmp	r12,rdx
        +	lea	r13,QWORD PTR[16+r13]
        +	jne	$L$cbc_eloop
        +
        +	cmp	rcx,0
        +	jne	$L$cbc_enc_tail
        +
        +	mov	r13,QWORD PTR[40+rsp]
        +	mov	DWORD PTR[r13],r8d
        +	mov	DWORD PTR[4+r13],r9d
        +	mov	DWORD PTR[8+r13],r10d
        +	mov	DWORD PTR[12+r13],r11d
        +	jmp	$L$cbc_done
        +
        +ALIGN	16
        +$L$cbc_enc_tail::
        +	xor	rax,rax
        +	mov	QWORD PTR[((0+24))+rsp],rax
        +	mov	QWORD PTR[((8+24))+rsp],rax
        +	mov	QWORD PTR[16+rsp],rax
        +
        +$L$cbc_enc_pushf::
        +	pushfq
        +	cld
        +	mov	rsi,r12
        +	lea	rdi,QWORD PTR[((8+24))+rsp]
        +	DD	09066A4F3h
        +
        +	popfq
        +$L$cbc_enc_popf::
        +
        +	lea	r12,QWORD PTR[24+rsp]
        +	lea	rax,QWORD PTR[((16+24))+rsp]
        +	mov	QWORD PTR[8+rsp],rax
        +	jmp	$L$cbc_eloop
        +
        +
        +ALIGN	16
        +$L$CBC_DECRYPT::
        +	xchg	r15,r14
        +	add	rdx,15
        +	and	rcx,15
        +	and	rdx,-16
        +	mov	QWORD PTR[rsp],r14
        +	lea	rdx,QWORD PTR[rdx*1+r12]
        +	mov	QWORD PTR[8+rsp],rdx
        +	mov	QWORD PTR[16+rsp],rcx
        +
        +	mov	rax,QWORD PTR[rbx]
        +	mov	rbx,QWORD PTR[8+rbx]
        +	jmp	$L$cbc_dloop
        +ALIGN	16
        +$L$cbc_dloop::
        +	mov	r8d,DWORD PTR[r12]
        +	mov	r9d,DWORD PTR[4+r12]
        +	mov	r10d,DWORD PTR[8+r12]
        +	bswap	r8d
        +	mov	r11d,DWORD PTR[12+r12]
        +	bswap	r9d
        +	mov	QWORD PTR[((0+24))+rsp],rax
        +	bswap	r10d
        +	mov	QWORD PTR[((8+24))+rsp],rbx
        +	bswap	r11d
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	mov	r14,QWORD PTR[rsp]
        +	mov	rdx,QWORD PTR[8+rsp]
        +	mov	rcx,QWORD PTR[16+rsp]
        +
        +	bswap	r8d
        +	mov	rax,QWORD PTR[r12]
        +	bswap	r9d
        +	mov	rbx,QWORD PTR[8+r12]
        +	bswap	r10d
        +	xor	r8d,DWORD PTR[((0+24))+rsp]
        +	bswap	r11d
        +	xor	r9d,DWORD PTR[((4+24))+rsp]
        +	xor	r10d,DWORD PTR[((8+24))+rsp]
        +	lea	r12,QWORD PTR[16+r12]
        +	xor	r11d,DWORD PTR[((12+24))+rsp]
        +	cmp	r12,rdx
        +	je	$L$cbc_ddone
        +
        +	mov	DWORD PTR[r13],r8d
        +	mov	DWORD PTR[4+r13],r9d
        +	mov	DWORD PTR[8+r13],r10d
        +	mov	DWORD PTR[12+r13],r11d
        +
        +	lea	r13,QWORD PTR[16+r13]
        +	jmp	$L$cbc_dloop
        +
        +ALIGN	16
        +$L$cbc_ddone::
        +	mov	rdx,QWORD PTR[40+rsp]
        +	cmp	rcx,0
        +	jne	$L$cbc_dec_tail
        +
        +	mov	DWORD PTR[r13],r8d
        +	mov	DWORD PTR[4+r13],r9d
        +	mov	DWORD PTR[8+r13],r10d
        +	mov	DWORD PTR[12+r13],r11d
        +
        +	mov	QWORD PTR[rdx],rax
        +	mov	QWORD PTR[8+rdx],rbx
        +	jmp	$L$cbc_done
        +ALIGN	16
        +$L$cbc_dec_tail::
        +	mov	DWORD PTR[((0+24))+rsp],r8d
        +	mov	DWORD PTR[((4+24))+rsp],r9d
        +	mov	DWORD PTR[((8+24))+rsp],r10d
        +	mov	DWORD PTR[((12+24))+rsp],r11d
        +
        +$L$cbc_dec_pushf::
        +	pushfq
        +	cld
        +	lea	rsi,QWORD PTR[((8+24))+rsp]
        +	lea	rdi,QWORD PTR[r13]
        +	DD	09066A4F3h
        +
        +	popfq
        +$L$cbc_dec_popf::
        +
        +	mov	QWORD PTR[rdx],rax
        +	mov	QWORD PTR[8+rdx],rbx
        +	jmp	$L$cbc_done
        +
        +ALIGN	16
        +$L$cbc_done::
        +	mov	rcx,QWORD PTR[48+rsp]
        +	mov	r15,QWORD PTR[rcx]
        +	mov	r14,QWORD PTR[8+rcx]
        +	mov	r13,QWORD PTR[16+rcx]
        +	mov	r12,QWORD PTR[24+rcx]
        +	mov	rbp,QWORD PTR[32+rcx]
        +	mov	rbx,QWORD PTR[40+rcx]
        +	lea	rsp,QWORD PTR[48+rcx]
        +$L$cbc_abort::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_Camellia_cbc_encrypt::
        +Camellia_cbc_encrypt	ENDP
        +
        +DB	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54
        +DB	95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112
        +DB	101,110,115,115,108,46,111,114,103,62,0
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +common_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	lea	rsp,QWORD PTR[((-64))+rsp]
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	lea	rax,QWORD PTR[40+rax]
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r13,QWORD PTR[((-24))+rax]
        +	mov	r14,QWORD PTR[((-32))+rax]
        +	mov	r15,QWORD PTR[((-40))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	jmp	$L$common_seh_exit
        +common_se_handler	ENDP
        +
        +
        +ALIGN	16
        +cbc_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	lea	rsp,QWORD PTR[((-64))+rsp]
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$cbc_prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_prologue
        +
        +	lea	r10,QWORD PTR[$L$cbc_body]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_frame_setup
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$cbc_abort]
        +	cmp	rbx,r10
        +	jae	$L$in_cbc_prologue
        +
        +
        +	lea	r10,QWORD PTR[$L$cbc_enc_pushf]
        +	cmp	rbx,r10
        +	jbe	$L$in_cbc_no_flag
        +	lea	rax,QWORD PTR[8+rax]
        +	lea	r10,QWORD PTR[$L$cbc_enc_popf]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_no_flag
        +	lea	rax,QWORD PTR[((-8))+rax]
        +	lea	r10,QWORD PTR[$L$cbc_dec_pushf]
        +	cmp	rbx,r10
        +	jbe	$L$in_cbc_no_flag
        +	lea	rax,QWORD PTR[8+rax]
        +	lea	r10,QWORD PTR[$L$cbc_dec_popf]
        +	cmp	rbx,r10
        +	jb	$L$in_cbc_no_flag
        +	lea	rax,QWORD PTR[((-8))+rax]
        +
        +$L$in_cbc_no_flag::
        +	mov	rax,QWORD PTR[48+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +
        +$L$in_cbc_frame_setup::
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_cbc_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +ALIGN	4
        +$L$common_seh_exit::
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	lea	rsp,QWORD PTR[64+rsp]
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +cbc_se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_Camellia_EncryptBlock_Rounds
        +	DD	imagerel $L$SEH_end_Camellia_EncryptBlock_Rounds
        +	DD	imagerel $L$SEH_info_Camellia_EncryptBlock_Rounds
        +
        +	DD	imagerel $L$SEH_begin_Camellia_DecryptBlock_Rounds
        +	DD	imagerel $L$SEH_end_Camellia_DecryptBlock_Rounds
        +	DD	imagerel $L$SEH_info_Camellia_DecryptBlock_Rounds
        +
        +	DD	imagerel $L$SEH_begin_Camellia_Ekeygen
        +	DD	imagerel $L$SEH_end_Camellia_Ekeygen
        +	DD	imagerel $L$SEH_info_Camellia_Ekeygen
        +
        +	DD	imagerel $L$SEH_begin_Camellia_cbc_encrypt
        +	DD	imagerel $L$SEH_end_Camellia_cbc_encrypt
        +	DD	imagerel $L$SEH_info_Camellia_cbc_encrypt
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_Camellia_EncryptBlock_Rounds::
        +DB	9,0,0,0
        +	DD	imagerel common_se_handler
        +	DD	imagerel $L$enc_prologue,imagerel $L$enc_epilogue
        +
        +$L$SEH_info_Camellia_DecryptBlock_Rounds::
        +DB	9,0,0,0
        +	DD	imagerel common_se_handler
        +	DD	imagerel $L$dec_prologue,imagerel $L$dec_epilogue
        +
        +$L$SEH_info_Camellia_Ekeygen::
        +DB	9,0,0,0
        +	DD	imagerel common_se_handler
        +	DD	imagerel $L$key_prologue,imagerel $L$key_epilogue
        +
        +$L$SEH_info_Camellia_cbc_encrypt::
        +DB	9,0,0,0
        +	DD	imagerel cbc_se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm
        new file mode 100644
        index 000000000..8ddad41c8
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/md5/md5-x86_64.asm
        @@ -0,0 +1,781 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ALIGN	16
        +
        +PUBLIC	md5_block_asm_data_order
        +
        +md5_block_asm_data_order	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_md5_block_asm_data_order::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbp
        +	push	rbx
        +	push	r12
        +	push	r14
        +	push	r15
        +$L$prologue::
        +
        +
        +
        +
        +	mov	rbp,rdi
        +	shl	rdx,6
        +	lea	rdi,QWORD PTR[rdx*1+rsi]
        +	mov	eax,DWORD PTR[rbp]
        +	mov	ebx,DWORD PTR[4+rbp]
        +	mov	ecx,DWORD PTR[8+rbp]
        +	mov	edx,DWORD PTR[12+rbp]
        +
        +
        +
        +
        +
        +
        +
        +	cmp	rsi,rdi
        +	je	$L$end
        +
        +
        +
        +$L$loop::
        +	mov	r8d,eax
        +	mov	r9d,ebx
        +	mov	r14d,ecx
        +	mov	r15d,edx
        +	mov	r10d,DWORD PTR[rsi]
        +	mov	r11d,edx
        +	xor	r11d,ecx
        +	lea	eax,DWORD PTR[((-680876936))+r10*1+rax]
        +	and	r11d,ebx
        +	xor	r11d,edx
        +	mov	r10d,DWORD PTR[4+rsi]
        +	add	eax,r11d
        +	rol	eax,7
        +	mov	r11d,ecx
        +	add	eax,ebx
        +	xor	r11d,ebx
        +	lea	edx,DWORD PTR[((-389564586))+r10*1+rdx]
        +	and	r11d,eax
        +	xor	r11d,ecx
        +	mov	r10d,DWORD PTR[8+rsi]
        +	add	edx,r11d
        +	rol	edx,12
        +	mov	r11d,ebx
        +	add	edx,eax
        +	xor	r11d,eax
        +	lea	ecx,DWORD PTR[606105819+r10*1+rcx]
        +	and	r11d,edx
        +	xor	r11d,ebx
        +	mov	r10d,DWORD PTR[12+rsi]
        +	add	ecx,r11d
        +	rol	ecx,17
        +	mov	r11d,eax
        +	add	ecx,edx
        +	xor	r11d,edx
        +	lea	ebx,DWORD PTR[((-1044525330))+r10*1+rbx]
        +	and	r11d,ecx
        +	xor	r11d,eax
        +	mov	r10d,DWORD PTR[16+rsi]
        +	add	ebx,r11d
        +	rol	ebx,22
        +	mov	r11d,edx
        +	add	ebx,ecx
        +	xor	r11d,ecx
        +	lea	eax,DWORD PTR[((-176418897))+r10*1+rax]
        +	and	r11d,ebx
        +	xor	r11d,edx
        +	mov	r10d,DWORD PTR[20+rsi]
        +	add	eax,r11d
        +	rol	eax,7
        +	mov	r11d,ecx
        +	add	eax,ebx
        +	xor	r11d,ebx
        +	lea	edx,DWORD PTR[1200080426+r10*1+rdx]
        +	and	r11d,eax
        +	xor	r11d,ecx
        +	mov	r10d,DWORD PTR[24+rsi]
        +	add	edx,r11d
        +	rol	edx,12
        +	mov	r11d,ebx
        +	add	edx,eax
        +	xor	r11d,eax
        +	lea	ecx,DWORD PTR[((-1473231341))+r10*1+rcx]
        +	and	r11d,edx
        +	xor	r11d,ebx
        +	mov	r10d,DWORD PTR[28+rsi]
        +	add	ecx,r11d
        +	rol	ecx,17
        +	mov	r11d,eax
        +	add	ecx,edx
        +	xor	r11d,edx
        +	lea	ebx,DWORD PTR[((-45705983))+r10*1+rbx]
        +	and	r11d,ecx
        +	xor	r11d,eax
        +	mov	r10d,DWORD PTR[32+rsi]
        +	add	ebx,r11d
        +	rol	ebx,22
        +	mov	r11d,edx
        +	add	ebx,ecx
        +	xor	r11d,ecx
        +	lea	eax,DWORD PTR[1770035416+r10*1+rax]
        +	and	r11d,ebx
        +	xor	r11d,edx
        +	mov	r10d,DWORD PTR[36+rsi]
        +	add	eax,r11d
        +	rol	eax,7
        +	mov	r11d,ecx
        +	add	eax,ebx
        +	xor	r11d,ebx
        +	lea	edx,DWORD PTR[((-1958414417))+r10*1+rdx]
        +	and	r11d,eax
        +	xor	r11d,ecx
        +	mov	r10d,DWORD PTR[40+rsi]
        +	add	edx,r11d
        +	rol	edx,12
        +	mov	r11d,ebx
        +	add	edx,eax
        +	xor	r11d,eax
        +	lea	ecx,DWORD PTR[((-42063))+r10*1+rcx]
        +	and	r11d,edx
        +	xor	r11d,ebx
        +	mov	r10d,DWORD PTR[44+rsi]
        +	add	ecx,r11d
        +	rol	ecx,17
        +	mov	r11d,eax
        +	add	ecx,edx
        +	xor	r11d,edx
        +	lea	ebx,DWORD PTR[((-1990404162))+r10*1+rbx]
        +	and	r11d,ecx
        +	xor	r11d,eax
        +	mov	r10d,DWORD PTR[48+rsi]
        +	add	ebx,r11d
        +	rol	ebx,22
        +	mov	r11d,edx
        +	add	ebx,ecx
        +	xor	r11d,ecx
        +	lea	eax,DWORD PTR[1804603682+r10*1+rax]
        +	and	r11d,ebx
        +	xor	r11d,edx
        +	mov	r10d,DWORD PTR[52+rsi]
        +	add	eax,r11d
        +	rol	eax,7
        +	mov	r11d,ecx
        +	add	eax,ebx
        +	xor	r11d,ebx
        +	lea	edx,DWORD PTR[((-40341101))+r10*1+rdx]
        +	and	r11d,eax
        +	xor	r11d,ecx
        +	mov	r10d,DWORD PTR[56+rsi]
        +	add	edx,r11d
        +	rol	edx,12
        +	mov	r11d,ebx
        +	add	edx,eax
        +	xor	r11d,eax
        +	lea	ecx,DWORD PTR[((-1502002290))+r10*1+rcx]
        +	and	r11d,edx
        +	xor	r11d,ebx
        +	mov	r10d,DWORD PTR[60+rsi]
        +	add	ecx,r11d
        +	rol	ecx,17
        +	mov	r11d,eax
        +	add	ecx,edx
        +	xor	r11d,edx
        +	lea	ebx,DWORD PTR[1236535329+r10*1+rbx]
        +	and	r11d,ecx
        +	xor	r11d,eax
        +	mov	r10d,DWORD PTR[rsi]
        +	add	ebx,r11d
        +	rol	ebx,22
        +	mov	r11d,edx
        +	add	ebx,ecx
        +	mov	r10d,DWORD PTR[4+rsi]
        +	mov	r11d,edx
        +	mov	r12d,edx
        +	not	r11d
        +	lea	eax,DWORD PTR[((-165796510))+r10*1+rax]
        +	and	r12d,ebx
        +	and	r11d,ecx
        +	mov	r10d,DWORD PTR[24+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ecx
        +	add	eax,r12d
        +	mov	r12d,ecx
        +	rol	eax,5
        +	add	eax,ebx
        +	not	r11d
        +	lea	edx,DWORD PTR[((-1069501632))+r10*1+rdx]
        +	and	r12d,eax
        +	and	r11d,ebx
        +	mov	r10d,DWORD PTR[44+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ebx
        +	add	edx,r12d
        +	mov	r12d,ebx
        +	rol	edx,9
        +	add	edx,eax
        +	not	r11d
        +	lea	ecx,DWORD PTR[643717713+r10*1+rcx]
        +	and	r12d,edx
        +	and	r11d,eax
        +	mov	r10d,DWORD PTR[rsi]
        +	or	r12d,r11d
        +	mov	r11d,eax
        +	add	ecx,r12d
        +	mov	r12d,eax
        +	rol	ecx,14
        +	add	ecx,edx
        +	not	r11d
        +	lea	ebx,DWORD PTR[((-373897302))+r10*1+rbx]
        +	and	r12d,ecx
        +	and	r11d,edx
        +	mov	r10d,DWORD PTR[20+rsi]
        +	or	r12d,r11d
        +	mov	r11d,edx
        +	add	ebx,r12d
        +	mov	r12d,edx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	not	r11d
        +	lea	eax,DWORD PTR[((-701558691))+r10*1+rax]
        +	and	r12d,ebx
        +	and	r11d,ecx
        +	mov	r10d,DWORD PTR[40+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ecx
        +	add	eax,r12d
        +	mov	r12d,ecx
        +	rol	eax,5
        +	add	eax,ebx
        +	not	r11d
        +	lea	edx,DWORD PTR[38016083+r10*1+rdx]
        +	and	r12d,eax
        +	and	r11d,ebx
        +	mov	r10d,DWORD PTR[60+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ebx
        +	add	edx,r12d
        +	mov	r12d,ebx
        +	rol	edx,9
        +	add	edx,eax
        +	not	r11d
        +	lea	ecx,DWORD PTR[((-660478335))+r10*1+rcx]
        +	and	r12d,edx
        +	and	r11d,eax
        +	mov	r10d,DWORD PTR[16+rsi]
        +	or	r12d,r11d
        +	mov	r11d,eax
        +	add	ecx,r12d
        +	mov	r12d,eax
        +	rol	ecx,14
        +	add	ecx,edx
        +	not	r11d
        +	lea	ebx,DWORD PTR[((-405537848))+r10*1+rbx]
        +	and	r12d,ecx
        +	and	r11d,edx
        +	mov	r10d,DWORD PTR[36+rsi]
        +	or	r12d,r11d
        +	mov	r11d,edx
        +	add	ebx,r12d
        +	mov	r12d,edx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	not	r11d
        +	lea	eax,DWORD PTR[568446438+r10*1+rax]
        +	and	r12d,ebx
        +	and	r11d,ecx
        +	mov	r10d,DWORD PTR[56+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ecx
        +	add	eax,r12d
        +	mov	r12d,ecx
        +	rol	eax,5
        +	add	eax,ebx
        +	not	r11d
        +	lea	edx,DWORD PTR[((-1019803690))+r10*1+rdx]
        +	and	r12d,eax
        +	and	r11d,ebx
        +	mov	r10d,DWORD PTR[12+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ebx
        +	add	edx,r12d
        +	mov	r12d,ebx
        +	rol	edx,9
        +	add	edx,eax
        +	not	r11d
        +	lea	ecx,DWORD PTR[((-187363961))+r10*1+rcx]
        +	and	r12d,edx
        +	and	r11d,eax
        +	mov	r10d,DWORD PTR[32+rsi]
        +	or	r12d,r11d
        +	mov	r11d,eax
        +	add	ecx,r12d
        +	mov	r12d,eax
        +	rol	ecx,14
        +	add	ecx,edx
        +	not	r11d
        +	lea	ebx,DWORD PTR[1163531501+r10*1+rbx]
        +	and	r12d,ecx
        +	and	r11d,edx
        +	mov	r10d,DWORD PTR[52+rsi]
        +	or	r12d,r11d
        +	mov	r11d,edx
        +	add	ebx,r12d
        +	mov	r12d,edx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	not	r11d
        +	lea	eax,DWORD PTR[((-1444681467))+r10*1+rax]
        +	and	r12d,ebx
        +	and	r11d,ecx
        +	mov	r10d,DWORD PTR[8+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ecx
        +	add	eax,r12d
        +	mov	r12d,ecx
        +	rol	eax,5
        +	add	eax,ebx
        +	not	r11d
        +	lea	edx,DWORD PTR[((-51403784))+r10*1+rdx]
        +	and	r12d,eax
        +	and	r11d,ebx
        +	mov	r10d,DWORD PTR[28+rsi]
        +	or	r12d,r11d
        +	mov	r11d,ebx
        +	add	edx,r12d
        +	mov	r12d,ebx
        +	rol	edx,9
        +	add	edx,eax
        +	not	r11d
        +	lea	ecx,DWORD PTR[1735328473+r10*1+rcx]
        +	and	r12d,edx
        +	and	r11d,eax
        +	mov	r10d,DWORD PTR[48+rsi]
        +	or	r12d,r11d
        +	mov	r11d,eax
        +	add	ecx,r12d
        +	mov	r12d,eax
        +	rol	ecx,14
        +	add	ecx,edx
        +	not	r11d
        +	lea	ebx,DWORD PTR[((-1926607734))+r10*1+rbx]
        +	and	r12d,ecx
        +	and	r11d,edx
        +	mov	r10d,DWORD PTR[rsi]
        +	or	r12d,r11d
        +	mov	r11d,edx
        +	add	ebx,r12d
        +	mov	r12d,edx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	mov	r10d,DWORD PTR[20+rsi]
        +	mov	r11d,ecx
        +	lea	eax,DWORD PTR[((-378558))+r10*1+rax]
        +	mov	r10d,DWORD PTR[32+rsi]
        +	xor	r11d,edx
        +	xor	r11d,ebx
        +	add	eax,r11d
        +	rol	eax,4
        +	mov	r11d,ebx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[((-2022574463))+r10*1+rdx]
        +	mov	r10d,DWORD PTR[44+rsi]
        +	xor	r11d,ecx
        +	xor	r11d,eax
        +	add	edx,r11d
        +	rol	edx,11
        +	mov	r11d,eax
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[1839030562+r10*1+rcx]
        +	mov	r10d,DWORD PTR[56+rsi]
        +	xor	r11d,ebx
        +	xor	r11d,edx
        +	add	ecx,r11d
        +	rol	ecx,16
        +	mov	r11d,edx
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[((-35309556))+r10*1+rbx]
        +	mov	r10d,DWORD PTR[4+rsi]
        +	xor	r11d,eax
        +	xor	r11d,ecx
        +	add	ebx,r11d
        +	rol	ebx,23
        +	mov	r11d,ecx
        +	add	ebx,ecx
        +	lea	eax,DWORD PTR[((-1530992060))+r10*1+rax]
        +	mov	r10d,DWORD PTR[16+rsi]
        +	xor	r11d,edx
        +	xor	r11d,ebx
        +	add	eax,r11d
        +	rol	eax,4
        +	mov	r11d,ebx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[1272893353+r10*1+rdx]
        +	mov	r10d,DWORD PTR[28+rsi]
        +	xor	r11d,ecx
        +	xor	r11d,eax
        +	add	edx,r11d
        +	rol	edx,11
        +	mov	r11d,eax
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[((-155497632))+r10*1+rcx]
        +	mov	r10d,DWORD PTR[40+rsi]
        +	xor	r11d,ebx
        +	xor	r11d,edx
        +	add	ecx,r11d
        +	rol	ecx,16
        +	mov	r11d,edx
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[((-1094730640))+r10*1+rbx]
        +	mov	r10d,DWORD PTR[52+rsi]
        +	xor	r11d,eax
        +	xor	r11d,ecx
        +	add	ebx,r11d
        +	rol	ebx,23
        +	mov	r11d,ecx
        +	add	ebx,ecx
        +	lea	eax,DWORD PTR[681279174+r10*1+rax]
        +	mov	r10d,DWORD PTR[rsi]
        +	xor	r11d,edx
        +	xor	r11d,ebx
        +	add	eax,r11d
        +	rol	eax,4
        +	mov	r11d,ebx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[((-358537222))+r10*1+rdx]
        +	mov	r10d,DWORD PTR[12+rsi]
        +	xor	r11d,ecx
        +	xor	r11d,eax
        +	add	edx,r11d
        +	rol	edx,11
        +	mov	r11d,eax
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[((-722521979))+r10*1+rcx]
        +	mov	r10d,DWORD PTR[24+rsi]
        +	xor	r11d,ebx
        +	xor	r11d,edx
        +	add	ecx,r11d
        +	rol	ecx,16
        +	mov	r11d,edx
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[76029189+r10*1+rbx]
        +	mov	r10d,DWORD PTR[36+rsi]
        +	xor	r11d,eax
        +	xor	r11d,ecx
        +	add	ebx,r11d
        +	rol	ebx,23
        +	mov	r11d,ecx
        +	add	ebx,ecx
        +	lea	eax,DWORD PTR[((-640364487))+r10*1+rax]
        +	mov	r10d,DWORD PTR[48+rsi]
        +	xor	r11d,edx
        +	xor	r11d,ebx
        +	add	eax,r11d
        +	rol	eax,4
        +	mov	r11d,ebx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[((-421815835))+r10*1+rdx]
        +	mov	r10d,DWORD PTR[60+rsi]
        +	xor	r11d,ecx
        +	xor	r11d,eax
        +	add	edx,r11d
        +	rol	edx,11
        +	mov	r11d,eax
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[530742520+r10*1+rcx]
        +	mov	r10d,DWORD PTR[8+rsi]
        +	xor	r11d,ebx
        +	xor	r11d,edx
        +	add	ecx,r11d
        +	rol	ecx,16
        +	mov	r11d,edx
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[((-995338651))+r10*1+rbx]
        +	mov	r10d,DWORD PTR[rsi]
        +	xor	r11d,eax
        +	xor	r11d,ecx
        +	add	ebx,r11d
        +	rol	ebx,23
        +	mov	r11d,ecx
        +	add	ebx,ecx
        +	mov	r10d,DWORD PTR[rsi]
        +	mov	r11d,0ffffffffh
        +	xor	r11d,edx
        +	lea	eax,DWORD PTR[((-198630844))+r10*1+rax]
        +	or	r11d,ebx
        +	xor	r11d,ecx
        +	add	eax,r11d
        +	mov	r10d,DWORD PTR[28+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	eax,6
        +	xor	r11d,ecx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[1126891415+r10*1+rdx]
        +	or	r11d,eax
        +	xor	r11d,ebx
        +	add	edx,r11d
        +	mov	r10d,DWORD PTR[56+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	edx,10
        +	xor	r11d,ebx
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[((-1416354905))+r10*1+rcx]
        +	or	r11d,edx
        +	xor	r11d,eax
        +	add	ecx,r11d
        +	mov	r10d,DWORD PTR[20+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ecx,15
        +	xor	r11d,eax
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[((-57434055))+r10*1+rbx]
        +	or	r11d,ecx
        +	xor	r11d,edx
        +	add	ebx,r11d
        +	mov	r10d,DWORD PTR[48+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ebx,21
        +	xor	r11d,edx
        +	add	ebx,ecx
        +	lea	eax,DWORD PTR[1700485571+r10*1+rax]
        +	or	r11d,ebx
        +	xor	r11d,ecx
        +	add	eax,r11d
        +	mov	r10d,DWORD PTR[12+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	eax,6
        +	xor	r11d,ecx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[((-1894986606))+r10*1+rdx]
        +	or	r11d,eax
        +	xor	r11d,ebx
        +	add	edx,r11d
        +	mov	r10d,DWORD PTR[40+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	edx,10
        +	xor	r11d,ebx
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[((-1051523))+r10*1+rcx]
        +	or	r11d,edx
        +	xor	r11d,eax
        +	add	ecx,r11d
        +	mov	r10d,DWORD PTR[4+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ecx,15
        +	xor	r11d,eax
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[((-2054922799))+r10*1+rbx]
        +	or	r11d,ecx
        +	xor	r11d,edx
        +	add	ebx,r11d
        +	mov	r10d,DWORD PTR[32+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ebx,21
        +	xor	r11d,edx
        +	add	ebx,ecx
        +	lea	eax,DWORD PTR[1873313359+r10*1+rax]
        +	or	r11d,ebx
        +	xor	r11d,ecx
        +	add	eax,r11d
        +	mov	r10d,DWORD PTR[60+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	eax,6
        +	xor	r11d,ecx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[((-30611744))+r10*1+rdx]
        +	or	r11d,eax
        +	xor	r11d,ebx
        +	add	edx,r11d
        +	mov	r10d,DWORD PTR[24+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	edx,10
        +	xor	r11d,ebx
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[((-1560198380))+r10*1+rcx]
        +	or	r11d,edx
        +	xor	r11d,eax
        +	add	ecx,r11d
        +	mov	r10d,DWORD PTR[52+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ecx,15
        +	xor	r11d,eax
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[1309151649+r10*1+rbx]
        +	or	r11d,ecx
        +	xor	r11d,edx
        +	add	ebx,r11d
        +	mov	r10d,DWORD PTR[16+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ebx,21
        +	xor	r11d,edx
        +	add	ebx,ecx
        +	lea	eax,DWORD PTR[((-145523070))+r10*1+rax]
        +	or	r11d,ebx
        +	xor	r11d,ecx
        +	add	eax,r11d
        +	mov	r10d,DWORD PTR[44+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	eax,6
        +	xor	r11d,ecx
        +	add	eax,ebx
        +	lea	edx,DWORD PTR[((-1120210379))+r10*1+rdx]
        +	or	r11d,eax
        +	xor	r11d,ebx
        +	add	edx,r11d
        +	mov	r10d,DWORD PTR[8+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	edx,10
        +	xor	r11d,ebx
        +	add	edx,eax
        +	lea	ecx,DWORD PTR[718787259+r10*1+rcx]
        +	or	r11d,edx
        +	xor	r11d,eax
        +	add	ecx,r11d
        +	mov	r10d,DWORD PTR[36+rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ecx,15
        +	xor	r11d,eax
        +	add	ecx,edx
        +	lea	ebx,DWORD PTR[((-343485551))+r10*1+rbx]
        +	or	r11d,ecx
        +	xor	r11d,edx
        +	add	ebx,r11d
        +	mov	r10d,DWORD PTR[rsi]
        +	mov	r11d,0ffffffffh
        +	rol	ebx,21
        +	xor	r11d,edx
        +	add	ebx,ecx
        +
        +	add	eax,r8d
        +	add	ebx,r9d
        +	add	ecx,r14d
        +	add	edx,r15d
        +
        +
        +	add	rsi,64
        +	cmp	rsi,rdi
        +	jb	$L$loop
        +
        +
        +
        +$L$end::
        +	mov	DWORD PTR[rbp],eax
        +	mov	DWORD PTR[4+rbp],ebx
        +	mov	DWORD PTR[8+rbp],ecx
        +	mov	DWORD PTR[12+rbp],edx
        +
        +	mov	r15,QWORD PTR[rsp]
        +	mov	r14,QWORD PTR[8+rsp]
        +	mov	r12,QWORD PTR[16+rsp]
        +	mov	rbx,QWORD PTR[24+rsp]
        +	mov	rbp,QWORD PTR[32+rsp]
        +	add	rsp,40
        +$L$epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_md5_block_asm_data_order::
        +md5_block_asm_data_order	ENDP
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	lea	rax,QWORD PTR[40+rax]
        +
        +	mov	rbp,QWORD PTR[((-8))+rax]
        +	mov	rbx,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r14,QWORD PTR[((-32))+rax]
        +	mov	r15,QWORD PTR[((-40))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_md5_block_asm_data_order
        +	DD	imagerel $L$SEH_end_md5_block_asm_data_order
        +	DD	imagerel $L$SEH_info_md5_block_asm_data_order
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_md5_block_asm_data_order::
        +DB	9,0,0,0
        +	DD	imagerel se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm
        new file mode 100644
        index 000000000..4af838e3e
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/rc4/rc4-md5-x86_64.asm
        @@ -0,0 +1,1375 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ALIGN	16
        +
        +PUBLIC	rc4_md5_enc
        +
        +rc4_md5_enc	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_rc4_md5_enc::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +	mov	r8,QWORD PTR[40+rsp]
        +	mov	r9,QWORD PTR[48+rsp]
        +
        +
        +	cmp	r9,0
        +	je	$L$abort
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	sub	rsp,40
        +$L$body::
        +	mov	r11,rcx
        +	mov	r12,r9
        +	mov	r13,rsi
        +	mov	r14,rdx
        +	mov	r15,r8
        +	xor	rbp,rbp
        +	xor	rcx,rcx
        +
        +	lea	rdi,QWORD PTR[8+rdi]
        +	mov	bpl,BYTE PTR[((-8))+rdi]
        +	mov	cl,BYTE PTR[((-4))+rdi]
        +
        +	inc	bpl
        +	sub	r14,r13
        +	mov	eax,DWORD PTR[rbp*4+rdi]
        +	add	cl,al
        +	lea	rsi,QWORD PTR[rbp*4+rdi]
        +	shl	r12,6
        +	add	r12,r15
        +	mov	QWORD PTR[16+rsp],r12
        +
        +	mov	QWORD PTR[24+rsp],r11
        +	mov	r8d,DWORD PTR[r11]
        +	mov	r9d,DWORD PTR[4+r11]
        +	mov	r10d,DWORD PTR[8+r11]
        +	mov	r11d,DWORD PTR[12+r11]
        +	jmp	$L$oop
        +
        +ALIGN	16
        +$L$oop::
        +	mov	DWORD PTR[rsp],r8d
        +	mov	DWORD PTR[4+rsp],r9d
        +	mov	DWORD PTR[8+rsp],r10d
        +	mov	r12d,r11d
        +	mov	DWORD PTR[12+rsp],r11d
        +	pxor	xmm0,xmm0
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r8d,DWORD PTR[r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[4+rsi]
        +	add	r8d,3614090360
        +	xor	r12d,r11d
        +	movzx	eax,al
        +	mov	DWORD PTR[rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,7
        +	mov	r12d,r10d
        +	movd	xmm0,DWORD PTR[rax*4+rdi]
        +
        +	add	r8d,r9d
        +	pxor	xmm1,xmm1
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r11d,DWORD PTR[4+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[8+rsi]
        +	add	r11d,3905402710
        +	xor	r12d,r10d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[4+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,12
        +	mov	r12d,r9d
        +	movd	xmm1,DWORD PTR[rbx*4+rdi]
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r10d,DWORD PTR[8+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[12+rsi]
        +	add	r10d,606105819
        +	xor	r12d,r9d
        +	movzx	eax,al
        +	mov	DWORD PTR[8+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,17
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],1
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r9d,DWORD PTR[12+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[16+rsi]
        +	add	r9d,3250441966
        +	xor	r12d,r8d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[12+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,22
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],1
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r8d,DWORD PTR[16+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[20+rsi]
        +	add	r8d,4118548399
        +	xor	r12d,r11d
        +	movzx	eax,al
        +	mov	DWORD PTR[16+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,7
        +	mov	r12d,r10d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],2
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r11d,DWORD PTR[20+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[24+rsi]
        +	add	r11d,1200080426
        +	xor	r12d,r10d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[20+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,12
        +	mov	r12d,r9d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],2
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r10d,DWORD PTR[24+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[28+rsi]
        +	add	r10d,2821735955
        +	xor	r12d,r9d
        +	movzx	eax,al
        +	mov	DWORD PTR[24+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,17
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],3
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r9d,DWORD PTR[28+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[32+rsi]
        +	add	r9d,4249261313
        +	xor	r12d,r8d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[28+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,22
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],3
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r8d,DWORD PTR[32+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[36+rsi]
        +	add	r8d,1770035416
        +	xor	r12d,r11d
        +	movzx	eax,al
        +	mov	DWORD PTR[32+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,7
        +	mov	r12d,r10d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],4
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r11d,DWORD PTR[36+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[40+rsi]
        +	add	r11d,2336552879
        +	xor	r12d,r10d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[36+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,12
        +	mov	r12d,r9d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],4
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r10d,DWORD PTR[40+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[44+rsi]
        +	add	r10d,4294925233
        +	xor	r12d,r9d
        +	movzx	eax,al
        +	mov	DWORD PTR[40+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,17
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],5
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r9d,DWORD PTR[44+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[48+rsi]
        +	add	r9d,2304563134
        +	xor	r12d,r8d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[44+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,22
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],5
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r8d,DWORD PTR[48+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[52+rsi]
        +	add	r8d,1804603682
        +	xor	r12d,r11d
        +	movzx	eax,al
        +	mov	DWORD PTR[48+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,7
        +	mov	r12d,r10d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],6
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r11d,DWORD PTR[52+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[56+rsi]
        +	add	r11d,4254626195
        +	xor	r12d,r10d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[52+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,12
        +	mov	r12d,r9d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],6
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r10d,DWORD PTR[56+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[60+rsi]
        +	add	r10d,2792965006
        +	xor	r12d,r9d
        +	movzx	eax,al
        +	mov	DWORD PTR[56+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,17
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],7
        +
        +	add	r10d,r11d
        +	movdqu	xmm2,XMMWORD PTR[r13]
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r9d,DWORD PTR[60+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[64+rsi]
        +	add	r9d,1236535329
        +	xor	r12d,r8d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[60+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,22
        +	mov	r12d,r10d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],7
        +
        +	add	r9d,r10d
        +	psllq	xmm1,8
        +	pxor	xmm2,xmm0
        +	pxor	xmm2,xmm1
        +	pxor	xmm0,xmm0
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r8d,DWORD PTR[4+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[68+rsi]
        +	add	r8d,4129170786
        +	xor	r12d,r10d
        +	movzx	eax,al
        +	mov	DWORD PTR[64+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,5
        +	mov	r12d,r9d
        +	movd	xmm0,DWORD PTR[rax*4+rdi]
        +
        +	add	r8d,r9d
        +	pxor	xmm1,xmm1
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r11d,DWORD PTR[24+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[72+rsi]
        +	add	r11d,3225465664
        +	xor	r12d,r9d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[68+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,9
        +	mov	r12d,r8d
        +	movd	xmm1,DWORD PTR[rbx*4+rdi]
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r10d,DWORD PTR[44+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[76+rsi]
        +	add	r10d,643717713
        +	xor	r12d,r8d
        +	movzx	eax,al
        +	mov	DWORD PTR[72+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,14
        +	mov	r12d,r11d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],1
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r9d,DWORD PTR[r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[80+rsi]
        +	add	r9d,3921069994
        +	xor	r12d,r11d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[76+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,20
        +	mov	r12d,r10d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],1
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r8d,DWORD PTR[20+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[84+rsi]
        +	add	r8d,3593408605
        +	xor	r12d,r10d
        +	movzx	eax,al
        +	mov	DWORD PTR[80+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,5
        +	mov	r12d,r9d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],2
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r11d,DWORD PTR[40+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[88+rsi]
        +	add	r11d,38016083
        +	xor	r12d,r9d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[84+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,9
        +	mov	r12d,r8d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],2
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r10d,DWORD PTR[60+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[92+rsi]
        +	add	r10d,3634488961
        +	xor	r12d,r8d
        +	movzx	eax,al
        +	mov	DWORD PTR[88+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,14
        +	mov	r12d,r11d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],3
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r9d,DWORD PTR[16+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[96+rsi]
        +	add	r9d,3889429448
        +	xor	r12d,r11d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[92+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,20
        +	mov	r12d,r10d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],3
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r8d,DWORD PTR[36+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[100+rsi]
        +	add	r8d,568446438
        +	xor	r12d,r10d
        +	movzx	eax,al
        +	mov	DWORD PTR[96+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,5
        +	mov	r12d,r9d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],4
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r11d,DWORD PTR[56+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[104+rsi]
        +	add	r11d,3275163606
        +	xor	r12d,r9d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[100+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,9
        +	mov	r12d,r8d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],4
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r10d,DWORD PTR[12+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[108+rsi]
        +	add	r10d,4107603335
        +	xor	r12d,r8d
        +	movzx	eax,al
        +	mov	DWORD PTR[104+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,14
        +	mov	r12d,r11d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],5
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r9d,DWORD PTR[32+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[112+rsi]
        +	add	r9d,1163531501
        +	xor	r12d,r11d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[108+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,20
        +	mov	r12d,r10d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],5
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r11d
        +	add	r8d,DWORD PTR[52+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[116+rsi]
        +	add	r8d,2850285829
        +	xor	r12d,r10d
        +	movzx	eax,al
        +	mov	DWORD PTR[112+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,5
        +	mov	r12d,r9d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],6
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r10d
        +	add	r11d,DWORD PTR[8+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[120+rsi]
        +	add	r11d,4243563512
        +	xor	r12d,r9d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[116+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,9
        +	mov	r12d,r8d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],6
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	and	r12d,r9d
        +	add	r10d,DWORD PTR[28+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[124+rsi]
        +	add	r10d,1735328473
        +	xor	r12d,r8d
        +	movzx	eax,al
        +	mov	DWORD PTR[120+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,14
        +	mov	r12d,r11d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],7
        +
        +	add	r10d,r11d
        +	movdqu	xmm3,XMMWORD PTR[16+r13]
        +	add	bpl,32
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	and	r12d,r8d
        +	add	r9d,DWORD PTR[48+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[rbp*4+rdi]
        +	add	r9d,2368359562
        +	xor	r12d,r11d
        +	movzx	ebx,bl
        +	mov	DWORD PTR[124+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,20
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],7
        +
        +	add	r9d,r10d
        +	mov	rsi,rcx
        +	xor	rcx,rcx
        +	mov	cl,sil
        +	lea	rsi,QWORD PTR[rbp*4+rdi]
        +	psllq	xmm1,8
        +	pxor	xmm3,xmm0
        +	pxor	xmm3,xmm1
        +	pxor	xmm0,xmm0
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r9d
        +	add	r8d,DWORD PTR[20+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[4+rsi]
        +	add	r8d,4294588738
        +	movzx	eax,al
        +	add	r8d,r12d
        +	mov	DWORD PTR[rsi],edx
        +	add	cl,bl
        +	rol	r8d,4
        +	mov	r12d,r10d
        +	movd	xmm0,DWORD PTR[rax*4+rdi]
        +
        +	add	r8d,r9d
        +	pxor	xmm1,xmm1
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r8d
        +	add	r11d,DWORD PTR[32+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[8+rsi]
        +	add	r11d,2272392833
        +	movzx	ebx,bl
        +	add	r11d,r12d
        +	mov	DWORD PTR[4+rsi],edx
        +	add	cl,al
        +	rol	r11d,11
        +	mov	r12d,r9d
        +	movd	xmm1,DWORD PTR[rbx*4+rdi]
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r11d
        +	add	r10d,DWORD PTR[44+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[12+rsi]
        +	add	r10d,1839030562
        +	movzx	eax,al
        +	add	r10d,r12d
        +	mov	DWORD PTR[8+rsi],edx
        +	add	cl,bl
        +	rol	r10d,16
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],1
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r10d
        +	add	r9d,DWORD PTR[56+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[16+rsi]
        +	add	r9d,4259657740
        +	movzx	ebx,bl
        +	add	r9d,r12d
        +	mov	DWORD PTR[12+rsi],edx
        +	add	cl,al
        +	rol	r9d,23
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],1
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r9d
        +	add	r8d,DWORD PTR[4+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[20+rsi]
        +	add	r8d,2763975236
        +	movzx	eax,al
        +	add	r8d,r12d
        +	mov	DWORD PTR[16+rsi],edx
        +	add	cl,bl
        +	rol	r8d,4
        +	mov	r12d,r10d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],2
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r8d
        +	add	r11d,DWORD PTR[16+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[24+rsi]
        +	add	r11d,1272893353
        +	movzx	ebx,bl
        +	add	r11d,r12d
        +	mov	DWORD PTR[20+rsi],edx
        +	add	cl,al
        +	rol	r11d,11
        +	mov	r12d,r9d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],2
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r11d
        +	add	r10d,DWORD PTR[28+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[28+rsi]
        +	add	r10d,4139469664
        +	movzx	eax,al
        +	add	r10d,r12d
        +	mov	DWORD PTR[24+rsi],edx
        +	add	cl,bl
        +	rol	r10d,16
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],3
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r10d
        +	add	r9d,DWORD PTR[40+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[32+rsi]
        +	add	r9d,3200236656
        +	movzx	ebx,bl
        +	add	r9d,r12d
        +	mov	DWORD PTR[28+rsi],edx
        +	add	cl,al
        +	rol	r9d,23
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],3
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r9d
        +	add	r8d,DWORD PTR[52+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[36+rsi]
        +	add	r8d,681279174
        +	movzx	eax,al
        +	add	r8d,r12d
        +	mov	DWORD PTR[32+rsi],edx
        +	add	cl,bl
        +	rol	r8d,4
        +	mov	r12d,r10d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],4
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r8d
        +	add	r11d,DWORD PTR[r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[40+rsi]
        +	add	r11d,3936430074
        +	movzx	ebx,bl
        +	add	r11d,r12d
        +	mov	DWORD PTR[36+rsi],edx
        +	add	cl,al
        +	rol	r11d,11
        +	mov	r12d,r9d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],4
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r11d
        +	add	r10d,DWORD PTR[12+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[44+rsi]
        +	add	r10d,3572445317
        +	movzx	eax,al
        +	add	r10d,r12d
        +	mov	DWORD PTR[40+rsi],edx
        +	add	cl,bl
        +	rol	r10d,16
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],5
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r10d
        +	add	r9d,DWORD PTR[24+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[48+rsi]
        +	add	r9d,76029189
        +	movzx	ebx,bl
        +	add	r9d,r12d
        +	mov	DWORD PTR[44+rsi],edx
        +	add	cl,al
        +	rol	r9d,23
        +	mov	r12d,r11d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],5
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r9d
        +	add	r8d,DWORD PTR[36+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[52+rsi]
        +	add	r8d,3654602809
        +	movzx	eax,al
        +	add	r8d,r12d
        +	mov	DWORD PTR[48+rsi],edx
        +	add	cl,bl
        +	rol	r8d,4
        +	mov	r12d,r10d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],6
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r8d
        +	add	r11d,DWORD PTR[48+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[56+rsi]
        +	add	r11d,3873151461
        +	movzx	ebx,bl
        +	add	r11d,r12d
        +	mov	DWORD PTR[52+rsi],edx
        +	add	cl,al
        +	rol	r11d,11
        +	mov	r12d,r9d
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],6
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	xor	r12d,r11d
        +	add	r10d,DWORD PTR[60+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[60+rsi]
        +	add	r10d,530742520
        +	movzx	eax,al
        +	add	r10d,r12d
        +	mov	DWORD PTR[56+rsi],edx
        +	add	cl,bl
        +	rol	r10d,16
        +	mov	r12d,r8d
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],7
        +
        +	add	r10d,r11d
        +	movdqu	xmm4,XMMWORD PTR[32+r13]
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	xor	r12d,r10d
        +	add	r9d,DWORD PTR[8+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[64+rsi]
        +	add	r9d,3299628645
        +	movzx	ebx,bl
        +	add	r9d,r12d
        +	mov	DWORD PTR[60+rsi],edx
        +	add	cl,al
        +	rol	r9d,23
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],7
        +
        +	add	r9d,r10d
        +	psllq	xmm1,8
        +	pxor	xmm4,xmm0
        +	pxor	xmm4,xmm1
        +	pxor	xmm0,xmm0
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r9d
        +	add	r8d,DWORD PTR[r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[68+rsi]
        +	add	r8d,4096336452
        +	movzx	eax,al
        +	xor	r12d,r10d
        +	mov	DWORD PTR[64+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,6
        +	mov	r12d,-1
        +	movd	xmm0,DWORD PTR[rax*4+rdi]
        +
        +	add	r8d,r9d
        +	pxor	xmm1,xmm1
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r8d
        +	add	r11d,DWORD PTR[28+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[72+rsi]
        +	add	r11d,1126891415
        +	movzx	ebx,bl
        +	xor	r12d,r9d
        +	mov	DWORD PTR[68+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,10
        +	mov	r12d,-1
        +	movd	xmm1,DWORD PTR[rbx*4+rdi]
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r11d
        +	add	r10d,DWORD PTR[56+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[76+rsi]
        +	add	r10d,2878612391
        +	movzx	eax,al
        +	xor	r12d,r8d
        +	mov	DWORD PTR[72+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,15
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],1
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r10d
        +	add	r9d,DWORD PTR[20+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[80+rsi]
        +	add	r9d,4237533241
        +	movzx	ebx,bl
        +	xor	r12d,r11d
        +	mov	DWORD PTR[76+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,21
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],1
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r9d
        +	add	r8d,DWORD PTR[48+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[84+rsi]
        +	add	r8d,1700485571
        +	movzx	eax,al
        +	xor	r12d,r10d
        +	mov	DWORD PTR[80+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,6
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],2
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r8d
        +	add	r11d,DWORD PTR[12+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[88+rsi]
        +	add	r11d,2399980690
        +	movzx	ebx,bl
        +	xor	r12d,r9d
        +	mov	DWORD PTR[84+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,10
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],2
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r11d
        +	add	r10d,DWORD PTR[40+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[92+rsi]
        +	add	r10d,4293915773
        +	movzx	eax,al
        +	xor	r12d,r8d
        +	mov	DWORD PTR[88+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,15
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],3
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r10d
        +	add	r9d,DWORD PTR[4+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[96+rsi]
        +	add	r9d,2240044497
        +	movzx	ebx,bl
        +	xor	r12d,r11d
        +	mov	DWORD PTR[92+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,21
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],3
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r9d
        +	add	r8d,DWORD PTR[32+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[100+rsi]
        +	add	r8d,1873313359
        +	movzx	eax,al
        +	xor	r12d,r10d
        +	mov	DWORD PTR[96+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,6
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],4
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r8d
        +	add	r11d,DWORD PTR[60+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[104+rsi]
        +	add	r11d,4264355552
        +	movzx	ebx,bl
        +	xor	r12d,r9d
        +	mov	DWORD PTR[100+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,10
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],4
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r11d
        +	add	r10d,DWORD PTR[24+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[108+rsi]
        +	add	r10d,2734768916
        +	movzx	eax,al
        +	xor	r12d,r8d
        +	mov	DWORD PTR[104+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,15
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],5
        +
        +	add	r10d,r11d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r10d
        +	add	r9d,DWORD PTR[52+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[112+rsi]
        +	add	r9d,1309151649
        +	movzx	ebx,bl
        +	xor	r12d,r11d
        +	mov	DWORD PTR[108+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,21
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],5
        +
        +	add	r9d,r10d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r11d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r9d
        +	add	r8d,DWORD PTR[16+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[116+rsi]
        +	add	r8d,4149444226
        +	movzx	eax,al
        +	xor	r12d,r10d
        +	mov	DWORD PTR[112+rsi],edx
        +	add	r8d,r12d
        +	add	cl,bl
        +	rol	r8d,6
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],6
        +
        +	add	r8d,r9d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r10d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r8d
        +	add	r11d,DWORD PTR[44+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[120+rsi]
        +	add	r11d,3174756917
        +	movzx	ebx,bl
        +	xor	r12d,r9d
        +	mov	DWORD PTR[116+rsi],edx
        +	add	r11d,r12d
        +	add	cl,al
        +	rol	r11d,10
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],6
        +
        +	add	r11d,r8d
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r9d
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	or	r12d,r11d
        +	add	r10d,DWORD PTR[8+r15]
        +	add	al,dl
        +	mov	ebx,DWORD PTR[124+rsi]
        +	add	r10d,718787259
        +	movzx	eax,al
        +	xor	r12d,r8d
        +	mov	DWORD PTR[120+rsi],edx
        +	add	r10d,r12d
        +	add	cl,bl
        +	rol	r10d,15
        +	mov	r12d,-1
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],7
        +
        +	add	r10d,r11d
        +	movdqu	xmm5,XMMWORD PTR[48+r13]
        +	add	bpl,32
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	xor	r12d,r8d
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	or	r12d,r10d
        +	add	r9d,DWORD PTR[36+r15]
        +	add	bl,dl
        +	mov	eax,DWORD PTR[rbp*4+rdi]
        +	add	r9d,3951481745
        +	movzx	ebx,bl
        +	xor	r12d,r11d
        +	mov	DWORD PTR[124+rsi],edx
        +	add	r9d,r12d
        +	add	cl,al
        +	rol	r9d,21
        +	mov	r12d,-1
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],7
        +
        +	add	r9d,r10d
        +	mov	rsi,rbp
        +	xor	rbp,rbp
        +	mov	bpl,sil
        +	mov	rsi,rcx
        +	xor	rcx,rcx
        +	mov	cl,sil
        +	lea	rsi,QWORD PTR[rbp*4+rdi]
        +	psllq	xmm1,8
        +	pxor	xmm5,xmm0
        +	pxor	xmm5,xmm1
        +	add	r8d,DWORD PTR[rsp]
        +	add	r9d,DWORD PTR[4+rsp]
        +	add	r10d,DWORD PTR[8+rsp]
        +	add	r11d,DWORD PTR[12+rsp]
        +
        +	movdqu	XMMWORD PTR[r13*1+r14],xmm2
        +	movdqu	XMMWORD PTR[16+r13*1+r14],xmm3
        +	movdqu	XMMWORD PTR[32+r13*1+r14],xmm4
        +	movdqu	XMMWORD PTR[48+r13*1+r14],xmm5
        +	lea	r15,QWORD PTR[64+r15]
        +	lea	r13,QWORD PTR[64+r13]
        +	cmp	r15,QWORD PTR[16+rsp]
        +	jb	$L$oop
        +
        +	mov	r12,QWORD PTR[24+rsp]
        +	sub	cl,al
        +	mov	DWORD PTR[r12],r8d
        +	mov	DWORD PTR[4+r12],r9d
        +	mov	DWORD PTR[8+r12],r10d
        +	mov	DWORD PTR[12+r12],r11d
        +	sub	bpl,1
        +	mov	DWORD PTR[((-8))+rdi],ebp
        +	mov	DWORD PTR[((-4))+rdi],ecx
        +
        +	mov	r15,QWORD PTR[40+rsp]
        +	mov	r14,QWORD PTR[48+rsp]
        +	mov	r13,QWORD PTR[56+rsp]
        +	mov	r12,QWORD PTR[64+rsp]
        +	mov	rbp,QWORD PTR[72+rsp]
        +	mov	rbx,QWORD PTR[80+rsp]
        +	lea	rsp,QWORD PTR[88+rsp]
        +$L$epilogue::
        +$L$abort::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_rc4_md5_enc::
        +rc4_md5_enc	ENDP
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$body]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	mov	r15,QWORD PTR[40+rax]
        +	mov	r14,QWORD PTR[48+rax]
        +	mov	r13,QWORD PTR[56+rax]
        +	mov	r12,QWORD PTR[64+rax]
        +	mov	rbp,QWORD PTR[72+rax]
        +	mov	rbx,QWORD PTR[80+rax]
        +	lea	rax,QWORD PTR[88+rax]
        +
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_rc4_md5_enc
        +	DD	imagerel $L$SEH_end_rc4_md5_enc
        +	DD	imagerel $L$SEH_info_rc4_md5_enc
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_rc4_md5_enc::
        +DB	9,0,0,0
        +	DD	imagerel se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm
        new file mode 100644
        index 000000000..aea304fba
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/rc4/rc4-x86_64.asm
        @@ -0,0 +1,780 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +EXTERN	OPENSSL_ia32cap_P:NEAR
        +
        +PUBLIC	RC4
        +
        +ALIGN	16
        +RC4	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_RC4::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +
        +	or	rsi,rsi
        +	jne	$L$entry
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$entry::
        +	push	rbx
        +	push	r12
        +	push	r13
        +$L$prologue::
        +	mov	r11,rsi
        +	mov	r12,rdx
        +	mov	r13,rcx
        +	xor	r10,r10
        +	xor	rcx,rcx
        +
        +	lea	rdi,QWORD PTR[8+rdi]
        +	mov	r10b,BYTE PTR[((-8))+rdi]
        +	mov	cl,BYTE PTR[((-4))+rdi]
        +	cmp	DWORD PTR[256+rdi],-1
        +	je	$L$RC4_CHAR
        +	mov	r8d,DWORD PTR[OPENSSL_ia32cap_P]
        +	xor	rbx,rbx
        +	inc	r10b
        +	sub	rbx,r10
        +	sub	r13,r12
        +	mov	eax,DWORD PTR[r10*4+rdi]
        +	test	r11,-16
        +	jz	$L$loop1
        +	bt	r8d,30
        +	jc	$L$intel
        +	and	rbx,7
        +	lea	rsi,QWORD PTR[1+r10]
        +	jz	$L$oop8
        +	sub	r11,rbx
        +$L$oop8_warmup::
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	DWORD PTR[r10*4+rdi],edx
        +	add	al,dl
        +	inc	r10b
        +	mov	edx,DWORD PTR[rax*4+rdi]
        +	mov	eax,DWORD PTR[r10*4+rdi]
        +	xor	dl,BYTE PTR[r12]
        +	mov	BYTE PTR[r12*1+r13],dl
        +	lea	r12,QWORD PTR[1+r12]
        +	dec	rbx
        +	jnz	$L$oop8_warmup
        +
        +	lea	rsi,QWORD PTR[1+r10]
        +	jmp	$L$oop8
        +ALIGN	16
        +$L$oop8::
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	ebx,DWORD PTR[rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[r10*4+rdi],edx
        +	add	dl,al
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	cl,bl
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	mov	eax,DWORD PTR[4+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[4+r10*4+rdi],edx
        +	add	dl,bl
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	ebx,DWORD PTR[8+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[8+r10*4+rdi],edx
        +	add	dl,al
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	cl,bl
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	mov	eax,DWORD PTR[12+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[12+r10*4+rdi],edx
        +	add	dl,bl
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	ebx,DWORD PTR[16+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[16+r10*4+rdi],edx
        +	add	dl,al
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	cl,bl
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	mov	eax,DWORD PTR[20+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[20+r10*4+rdi],edx
        +	add	dl,bl
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	ebx,DWORD PTR[24+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[24+r10*4+rdi],edx
        +	add	dl,al
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	sil,8
        +	add	cl,bl
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	mov	eax,DWORD PTR[((-4))+rsi*4+rdi]
        +	ror	r8,8
        +	mov	DWORD PTR[28+r10*4+rdi],edx
        +	add	dl,bl
        +	mov	r8b,BYTE PTR[rdx*4+rdi]
        +	add	r10b,8
        +	ror	r8,8
        +	sub	r11,8
        +
        +	xor	r8,QWORD PTR[r12]
        +	mov	QWORD PTR[r12*1+r13],r8
        +	lea	r12,QWORD PTR[8+r12]
        +
        +	test	r11,-8
        +	jnz	$L$oop8
        +	cmp	r11,0
        +	jne	$L$loop1
        +	jmp	$L$exit
        +
        +ALIGN	16
        +$L$intel::
        +	test	r11,-32
        +	jz	$L$loop1
        +	and	rbx,15
        +	jz	$L$oop16_is_hot
        +	sub	r11,rbx
        +$L$oop16_warmup::
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	DWORD PTR[r10*4+rdi],edx
        +	add	al,dl
        +	inc	r10b
        +	mov	edx,DWORD PTR[rax*4+rdi]
        +	mov	eax,DWORD PTR[r10*4+rdi]
        +	xor	dl,BYTE PTR[r12]
        +	mov	BYTE PTR[r12*1+r13],dl
        +	lea	r12,QWORD PTR[1+r12]
        +	dec	rbx
        +	jnz	$L$oop16_warmup
        +
        +	mov	rbx,rcx
        +	xor	rcx,rcx
        +	mov	cl,bl
        +
        +$L$oop16_is_hot::
        +	lea	rsi,QWORD PTR[r10*4+rdi]
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	pxor	xmm0,xmm0
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[4+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],0
        +	jmp	$L$oop16_enter
        +ALIGN	16
        +$L$oop16::
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	pxor	xmm2,xmm0
        +	psllq	xmm1,8
        +	pxor	xmm0,xmm0
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[4+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[rsi],edx
        +	pxor	xmm2,xmm1
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],0
        +	movdqu	XMMWORD PTR[r12*1+r13],xmm2
        +	lea	r12,QWORD PTR[16+r12]
        +$L$oop16_enter::
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	pxor	xmm1,xmm1
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[8+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[4+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],0
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[12+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[8+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],1
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[16+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[12+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],1
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[20+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[16+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],2
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[24+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[20+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],2
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[28+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[24+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],3
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[32+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[28+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],3
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[36+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[32+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],4
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[40+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[36+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],4
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[44+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[40+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],5
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[48+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[44+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],5
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[52+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[48+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],6
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	mov	eax,DWORD PTR[56+rsi]
        +	movzx	ebx,bl
        +	mov	DWORD PTR[52+rsi],edx
        +	add	cl,al
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],6
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	add	al,dl
        +	mov	ebx,DWORD PTR[60+rsi]
        +	movzx	eax,al
        +	mov	DWORD PTR[56+rsi],edx
        +	add	cl,bl
        +	pinsrw	xmm0,WORD PTR[rax*4+rdi],7
        +	add	r10b,16
        +	movdqu	xmm2,XMMWORD PTR[r12]
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],ebx
        +	add	bl,dl
        +	movzx	ebx,bl
        +	mov	DWORD PTR[60+rsi],edx
        +	lea	rsi,QWORD PTR[r10*4+rdi]
        +	pinsrw	xmm1,WORD PTR[rbx*4+rdi],7
        +	mov	eax,DWORD PTR[rsi]
        +	mov	rbx,rcx
        +	xor	rcx,rcx
        +	sub	r11,16
        +	mov	cl,bl
        +	test	r11,-16
        +	jnz	$L$oop16
        +
        +	psllq	xmm1,8
        +	pxor	xmm2,xmm0
        +	pxor	xmm2,xmm1
        +	movdqu	XMMWORD PTR[r12*1+r13],xmm2
        +	lea	r12,QWORD PTR[16+r12]
        +
        +	cmp	r11,0
        +	jne	$L$loop1
        +	jmp	$L$exit
        +
        +ALIGN	16
        +$L$loop1::
        +	add	cl,al
        +	mov	edx,DWORD PTR[rcx*4+rdi]
        +	mov	DWORD PTR[rcx*4+rdi],eax
        +	mov	DWORD PTR[r10*4+rdi],edx
        +	add	al,dl
        +	inc	r10b
        +	mov	edx,DWORD PTR[rax*4+rdi]
        +	mov	eax,DWORD PTR[r10*4+rdi]
        +	xor	dl,BYTE PTR[r12]
        +	mov	BYTE PTR[r12*1+r13],dl
        +	lea	r12,QWORD PTR[1+r12]
        +	dec	r11
        +	jnz	$L$loop1
        +	jmp	$L$exit
        +
        +ALIGN	16
        +$L$RC4_CHAR::
        +	add	r10b,1
        +	movzx	eax,BYTE PTR[r10*1+rdi]
        +	test	r11,-8
        +	jz	$L$cloop1
        +	jmp	$L$cloop8
        +ALIGN	16
        +$L$cloop8::
        +	mov	r8d,DWORD PTR[r12]
        +	mov	r9d,DWORD PTR[4+r12]
        +	add	cl,al
        +	lea	rsi,QWORD PTR[1+r10]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	esi,sil
        +	movzx	ebx,BYTE PTR[rsi*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],al
        +	cmp	rcx,rsi
        +	mov	BYTE PTR[r10*1+rdi],dl
        +	jne	$L$cmov0
        +
        +	mov	rbx,rax
        +$L$cmov0::
        +	add	dl,al
        +	xor	r8b,BYTE PTR[rdx*1+rdi]
        +	ror	r8d,8
        +	add	cl,bl
        +	lea	r10,QWORD PTR[1+rsi]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	r10d,r10b
        +	movzx	eax,BYTE PTR[r10*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],bl
        +	cmp	rcx,r10
        +	mov	BYTE PTR[rsi*1+rdi],dl
        +	jne	$L$cmov1
        +
        +	mov	rax,rbx
        +$L$cmov1::
        +	add	dl,bl
        +	xor	r8b,BYTE PTR[rdx*1+rdi]
        +	ror	r8d,8
        +	add	cl,al
        +	lea	rsi,QWORD PTR[1+r10]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	esi,sil
        +	movzx	ebx,BYTE PTR[rsi*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],al
        +	cmp	rcx,rsi
        +	mov	BYTE PTR[r10*1+rdi],dl
        +	jne	$L$cmov2
        +
        +	mov	rbx,rax
        +$L$cmov2::
        +	add	dl,al
        +	xor	r8b,BYTE PTR[rdx*1+rdi]
        +	ror	r8d,8
        +	add	cl,bl
        +	lea	r10,QWORD PTR[1+rsi]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	r10d,r10b
        +	movzx	eax,BYTE PTR[r10*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],bl
        +	cmp	rcx,r10
        +	mov	BYTE PTR[rsi*1+rdi],dl
        +	jne	$L$cmov3
        +
        +	mov	rax,rbx
        +$L$cmov3::
        +	add	dl,bl
        +	xor	r8b,BYTE PTR[rdx*1+rdi]
        +	ror	r8d,8
        +	add	cl,al
        +	lea	rsi,QWORD PTR[1+r10]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	esi,sil
        +	movzx	ebx,BYTE PTR[rsi*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],al
        +	cmp	rcx,rsi
        +	mov	BYTE PTR[r10*1+rdi],dl
        +	jne	$L$cmov4
        +
        +	mov	rbx,rax
        +$L$cmov4::
        +	add	dl,al
        +	xor	r9b,BYTE PTR[rdx*1+rdi]
        +	ror	r9d,8
        +	add	cl,bl
        +	lea	r10,QWORD PTR[1+rsi]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	r10d,r10b
        +	movzx	eax,BYTE PTR[r10*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],bl
        +	cmp	rcx,r10
        +	mov	BYTE PTR[rsi*1+rdi],dl
        +	jne	$L$cmov5
        +
        +	mov	rax,rbx
        +$L$cmov5::
        +	add	dl,bl
        +	xor	r9b,BYTE PTR[rdx*1+rdi]
        +	ror	r9d,8
        +	add	cl,al
        +	lea	rsi,QWORD PTR[1+r10]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	esi,sil
        +	movzx	ebx,BYTE PTR[rsi*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],al
        +	cmp	rcx,rsi
        +	mov	BYTE PTR[r10*1+rdi],dl
        +	jne	$L$cmov6
        +
        +	mov	rbx,rax
        +$L$cmov6::
        +	add	dl,al
        +	xor	r9b,BYTE PTR[rdx*1+rdi]
        +	ror	r9d,8
        +	add	cl,bl
        +	lea	r10,QWORD PTR[1+rsi]
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	movzx	r10d,r10b
        +	movzx	eax,BYTE PTR[r10*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],bl
        +	cmp	rcx,r10
        +	mov	BYTE PTR[rsi*1+rdi],dl
        +	jne	$L$cmov7
        +
        +	mov	rax,rbx
        +$L$cmov7::
        +	add	dl,bl
        +	xor	r9b,BYTE PTR[rdx*1+rdi]
        +	ror	r9d,8
        +	lea	r11,QWORD PTR[((-8))+r11]
        +	mov	DWORD PTR[r13],r8d
        +	lea	r12,QWORD PTR[8+r12]
        +	mov	DWORD PTR[4+r13],r9d
        +	lea	r13,QWORD PTR[8+r13]
        +
        +	test	r11,-8
        +	jnz	$L$cloop8
        +	cmp	r11,0
        +	jne	$L$cloop1
        +	jmp	$L$exit
        +ALIGN	16
        +$L$cloop1::
        +	add	cl,al
        +	movzx	ecx,cl
        +	movzx	edx,BYTE PTR[rcx*1+rdi]
        +	mov	BYTE PTR[rcx*1+rdi],al
        +	mov	BYTE PTR[r10*1+rdi],dl
        +	add	dl,al
        +	add	r10b,1
        +	movzx	edx,dl
        +	movzx	r10d,r10b
        +	movzx	edx,BYTE PTR[rdx*1+rdi]
        +	movzx	eax,BYTE PTR[r10*1+rdi]
        +	xor	dl,BYTE PTR[r12]
        +	lea	r12,QWORD PTR[1+r12]
        +	mov	BYTE PTR[r13],dl
        +	lea	r13,QWORD PTR[1+r13]
        +	sub	r11,1
        +	jnz	$L$cloop1
        +	jmp	$L$exit
        +
        +ALIGN	16
        +$L$exit::
        +	sub	r10b,1
        +	mov	DWORD PTR[((-8))+rdi],r10d
        +	mov	DWORD PTR[((-4))+rdi],ecx
        +
        +	mov	r13,QWORD PTR[rsp]
        +	mov	r12,QWORD PTR[8+rsp]
        +	mov	rbx,QWORD PTR[16+rsp]
        +	add	rsp,24
        +$L$epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_RC4::
        +RC4	ENDP
        +PUBLIC	private_RC4_set_key
        +
        +ALIGN	16
        +private_RC4_set_key	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_private_RC4_set_key::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	lea	rdi,QWORD PTR[8+rdi]
        +	lea	rdx,QWORD PTR[rsi*1+rdx]
        +	neg	rsi
        +	mov	rcx,rsi
        +	xor	eax,eax
        +	xor	r9,r9
        +	xor	r10,r10
        +	xor	r11,r11
        +
        +	mov	r8d,DWORD PTR[OPENSSL_ia32cap_P]
        +	bt	r8d,20
        +	jc	$L$c1stloop
        +	jmp	$L$w1stloop
        +
        +ALIGN	16
        +$L$w1stloop::
        +	mov	DWORD PTR[rax*4+rdi],eax
        +	add	al,1
        +	jnc	$L$w1stloop
        +
        +	xor	r9,r9
        +	xor	r8,r8
        +ALIGN	16
        +$L$w2ndloop::
        +	mov	r10d,DWORD PTR[r9*4+rdi]
        +	add	r8b,BYTE PTR[rsi*1+rdx]
        +	add	r8b,r10b
        +	add	rsi,1
        +	mov	r11d,DWORD PTR[r8*4+rdi]
        +	cmovz	rsi,rcx
        +	mov	DWORD PTR[r8*4+rdi],r10d
        +	mov	DWORD PTR[r9*4+rdi],r11d
        +	add	r9b,1
        +	jnc	$L$w2ndloop
        +	jmp	$L$exit_key
        +
        +ALIGN	16
        +$L$c1stloop::
        +	mov	BYTE PTR[rax*1+rdi],al
        +	add	al,1
        +	jnc	$L$c1stloop
        +
        +	xor	r9,r9
        +	xor	r8,r8
        +ALIGN	16
        +$L$c2ndloop::
        +	mov	r10b,BYTE PTR[r9*1+rdi]
        +	add	r8b,BYTE PTR[rsi*1+rdx]
        +	add	r8b,r10b
        +	add	rsi,1
        +	mov	r11b,BYTE PTR[r8*1+rdi]
        +	jnz	$L$cnowrap
        +	mov	rsi,rcx
        +$L$cnowrap::
        +	mov	BYTE PTR[r8*1+rdi],r10b
        +	mov	BYTE PTR[r9*1+rdi],r11b
        +	add	r9b,1
        +	jnc	$L$c2ndloop
        +	mov	DWORD PTR[256+rdi],-1
        +
        +ALIGN	16
        +$L$exit_key::
        +	xor	eax,eax
        +	mov	DWORD PTR[((-8))+rdi],eax
        +	mov	DWORD PTR[((-4))+rdi],eax
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_private_RC4_set_key::
        +private_RC4_set_key	ENDP
        +
        +PUBLIC	RC4_options
        +
        +ALIGN	16
        +RC4_options	PROC PUBLIC
        +	lea	rax,QWORD PTR[$L$opts]
        +	mov	edx,DWORD PTR[OPENSSL_ia32cap_P]
        +	bt	edx,20
        +	jc	$L$8xchar
        +	bt	edx,30
        +	jnc	$L$done
        +	add	rax,25
        +	DB	0F3h,0C3h		;repret
        +$L$8xchar::
        +	add	rax,12
        +$L$done::
        +	DB	0F3h,0C3h		;repret
        +ALIGN	64
        +$L$opts::
        +DB	114,99,52,40,56,120,44,105,110,116,41,0
        +DB	114,99,52,40,56,120,44,99,104,97,114,41,0
        +DB	114,99,52,40,49,54,120,44,105,110,116,41,0
        +DB	82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32
        +DB	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +DB	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +DB	62,0
        +ALIGN	64
        +RC4_options	ENDP
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +stream_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	lea	rax,QWORD PTR[24+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	r12,QWORD PTR[((-16))+rax]
        +	mov	r13,QWORD PTR[((-24))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	jmp	$L$common_seh_exit
        +stream_se_handler	ENDP
        +
        +
        +ALIGN	16
        +key_se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[152+r8]
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +$L$common_seh_exit::
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +key_se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_RC4
        +	DD	imagerel $L$SEH_end_RC4
        +	DD	imagerel $L$SEH_info_RC4
        +
        +	DD	imagerel $L$SEH_begin_private_RC4_set_key
        +	DD	imagerel $L$SEH_end_private_RC4_set_key
        +	DD	imagerel $L$SEH_info_private_RC4_set_key
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_RC4::
        +DB	9,0,0,0
        +	DD	imagerel stream_se_handler
        +$L$SEH_info_private_RC4_set_key::
        +DB	9,0,0,0
        +	DD	imagerel key_se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm
        new file mode 100644
        index 000000000..9589f7fa0
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/sha/sha1-x86_64.asm
        @@ -0,0 +1,2684 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +EXTERN	OPENSSL_ia32cap_P:NEAR
        +
        +PUBLIC	sha1_block_data_order
        +
        +ALIGN	16
        +sha1_block_data_order	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_sha1_block_data_order::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	mov	r9d,DWORD PTR[((OPENSSL_ia32cap_P+0))]
        +	mov	r8d,DWORD PTR[((OPENSSL_ia32cap_P+4))]
        +	test	r8d,512
        +	jz	$L$ialu
        +	jmp	_ssse3_shortcut
        +
        +ALIGN	16
        +$L$ialu::
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	mov	r11,rsp
        +	mov	r8,rdi
        +	sub	rsp,72
        +	mov	r9,rsi
        +	and	rsp,-64
        +	mov	r10,rdx
        +	mov	QWORD PTR[64+rsp],r11
        +$L$prologue::
        +
        +	mov	esi,DWORD PTR[r8]
        +	mov	edi,DWORD PTR[4+r8]
        +	mov	r11d,DWORD PTR[8+r8]
        +	mov	r12d,DWORD PTR[12+r8]
        +	mov	r13d,DWORD PTR[16+r8]
        +	jmp	$L$loop
        +
        +ALIGN	16
        +$L$loop::
        +	mov	edx,DWORD PTR[r9]
        +	bswap	edx
        +	mov	DWORD PTR[rsp],edx
        +	mov	eax,r11d
        +	mov	ebp,DWORD PTR[4+r9]
        +	mov	ecx,esi
        +	xor	eax,r12d
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1518500249+r13*1+rdx]
        +	and	eax,edi
        +	mov	DWORD PTR[4+rsp],ebp
        +	add	r13d,ecx
        +	xor	eax,r12d
        +	rol	edi,30
        +	add	r13d,eax
        +	mov	eax,edi
        +	mov	edx,DWORD PTR[8+r9]
        +	mov	ecx,r13d
        +	xor	eax,r11d
        +	bswap	edx
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1518500249+r12*1+rbp]
        +	and	eax,esi
        +	mov	DWORD PTR[8+rsp],edx
        +	add	r12d,ecx
        +	xor	eax,r11d
        +	rol	esi,30
        +	add	r12d,eax
        +	mov	eax,esi
        +	mov	ebp,DWORD PTR[12+r9]
        +	mov	ecx,r12d
        +	xor	eax,edi
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1518500249+r11*1+rdx]
        +	and	eax,r13d
        +	mov	DWORD PTR[12+rsp],ebp
        +	add	r11d,ecx
        +	xor	eax,edi
        +	rol	r13d,30
        +	add	r11d,eax
        +	mov	eax,r13d
        +	mov	edx,DWORD PTR[16+r9]
        +	mov	ecx,r11d
        +	xor	eax,esi
        +	bswap	edx
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1518500249+rdi*1+rbp]
        +	and	eax,r12d
        +	mov	DWORD PTR[16+rsp],edx
        +	add	edi,ecx
        +	xor	eax,esi
        +	rol	r12d,30
        +	add	edi,eax
        +	mov	eax,r12d
        +	mov	ebp,DWORD PTR[20+r9]
        +	mov	ecx,edi
        +	xor	eax,r13d
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1518500249+rsi*1+rdx]
        +	and	eax,r11d
        +	mov	DWORD PTR[20+rsp],ebp
        +	add	esi,ecx
        +	xor	eax,r13d
        +	rol	r11d,30
        +	add	esi,eax
        +	mov	eax,r11d
        +	mov	edx,DWORD PTR[24+r9]
        +	mov	ecx,esi
        +	xor	eax,r12d
        +	bswap	edx
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1518500249+r13*1+rbp]
        +	and	eax,edi
        +	mov	DWORD PTR[24+rsp],edx
        +	add	r13d,ecx
        +	xor	eax,r12d
        +	rol	edi,30
        +	add	r13d,eax
        +	mov	eax,edi
        +	mov	ebp,DWORD PTR[28+r9]
        +	mov	ecx,r13d
        +	xor	eax,r11d
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1518500249+r12*1+rdx]
        +	and	eax,esi
        +	mov	DWORD PTR[28+rsp],ebp
        +	add	r12d,ecx
        +	xor	eax,r11d
        +	rol	esi,30
        +	add	r12d,eax
        +	mov	eax,esi
        +	mov	edx,DWORD PTR[32+r9]
        +	mov	ecx,r12d
        +	xor	eax,edi
        +	bswap	edx
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1518500249+r11*1+rbp]
        +	and	eax,r13d
        +	mov	DWORD PTR[32+rsp],edx
        +	add	r11d,ecx
        +	xor	eax,edi
        +	rol	r13d,30
        +	add	r11d,eax
        +	mov	eax,r13d
        +	mov	ebp,DWORD PTR[36+r9]
        +	mov	ecx,r11d
        +	xor	eax,esi
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1518500249+rdi*1+rdx]
        +	and	eax,r12d
        +	mov	DWORD PTR[36+rsp],ebp
        +	add	edi,ecx
        +	xor	eax,esi
        +	rol	r12d,30
        +	add	edi,eax
        +	mov	eax,r12d
        +	mov	edx,DWORD PTR[40+r9]
        +	mov	ecx,edi
        +	xor	eax,r13d
        +	bswap	edx
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1518500249+rsi*1+rbp]
        +	and	eax,r11d
        +	mov	DWORD PTR[40+rsp],edx
        +	add	esi,ecx
        +	xor	eax,r13d
        +	rol	r11d,30
        +	add	esi,eax
        +	mov	eax,r11d
        +	mov	ebp,DWORD PTR[44+r9]
        +	mov	ecx,esi
        +	xor	eax,r12d
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1518500249+r13*1+rdx]
        +	and	eax,edi
        +	mov	DWORD PTR[44+rsp],ebp
        +	add	r13d,ecx
        +	xor	eax,r12d
        +	rol	edi,30
        +	add	r13d,eax
        +	mov	eax,edi
        +	mov	edx,DWORD PTR[48+r9]
        +	mov	ecx,r13d
        +	xor	eax,r11d
        +	bswap	edx
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1518500249+r12*1+rbp]
        +	and	eax,esi
        +	mov	DWORD PTR[48+rsp],edx
        +	add	r12d,ecx
        +	xor	eax,r11d
        +	rol	esi,30
        +	add	r12d,eax
        +	mov	eax,esi
        +	mov	ebp,DWORD PTR[52+r9]
        +	mov	ecx,r12d
        +	xor	eax,edi
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1518500249+r11*1+rdx]
        +	and	eax,r13d
        +	mov	DWORD PTR[52+rsp],ebp
        +	add	r11d,ecx
        +	xor	eax,edi
        +	rol	r13d,30
        +	add	r11d,eax
        +	mov	eax,r13d
        +	mov	edx,DWORD PTR[56+r9]
        +	mov	ecx,r11d
        +	xor	eax,esi
        +	bswap	edx
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1518500249+rdi*1+rbp]
        +	and	eax,r12d
        +	mov	DWORD PTR[56+rsp],edx
        +	add	edi,ecx
        +	xor	eax,esi
        +	rol	r12d,30
        +	add	edi,eax
        +	mov	eax,r12d
        +	mov	ebp,DWORD PTR[60+r9]
        +	mov	ecx,edi
        +	xor	eax,r13d
        +	bswap	ebp
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1518500249+rsi*1+rdx]
        +	and	eax,r11d
        +	mov	DWORD PTR[60+rsp],ebp
        +	add	esi,ecx
        +	xor	eax,r13d
        +	rol	r11d,30
        +	add	esi,eax
        +	mov	edx,DWORD PTR[rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[32+rsp]
        +	and	eax,edi
        +	lea	r13d,DWORD PTR[1518500249+r13*1+rbp]
        +	xor	edx,DWORD PTR[52+rsp]
        +	xor	eax,r12d
        +	rol	edx,1
        +	add	r13d,ecx
        +	rol	edi,30
        +	mov	DWORD PTR[rsp],edx
        +	add	r13d,eax
        +	mov	ebp,DWORD PTR[4+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[36+rsp]
        +	and	eax,esi
        +	lea	r12d,DWORD PTR[1518500249+r12*1+rdx]
        +	xor	ebp,DWORD PTR[56+rsp]
        +	xor	eax,r11d
        +	rol	ebp,1
        +	add	r12d,ecx
        +	rol	esi,30
        +	mov	DWORD PTR[4+rsp],ebp
        +	add	r12d,eax
        +	mov	edx,DWORD PTR[8+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[40+rsp]
        +	and	eax,r13d
        +	lea	r11d,DWORD PTR[1518500249+r11*1+rbp]
        +	xor	edx,DWORD PTR[60+rsp]
        +	xor	eax,edi
        +	rol	edx,1
        +	add	r11d,ecx
        +	rol	r13d,30
        +	mov	DWORD PTR[8+rsp],edx
        +	add	r11d,eax
        +	mov	ebp,DWORD PTR[12+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[44+rsp]
        +	and	eax,r12d
        +	lea	edi,DWORD PTR[1518500249+rdi*1+rdx]
        +	xor	ebp,DWORD PTR[rsp]
        +	xor	eax,esi
        +	rol	ebp,1
        +	add	edi,ecx
        +	rol	r12d,30
        +	mov	DWORD PTR[12+rsp],ebp
        +	add	edi,eax
        +	mov	edx,DWORD PTR[16+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[48+rsp]
        +	and	eax,r11d
        +	lea	esi,DWORD PTR[1518500249+rsi*1+rbp]
        +	xor	edx,DWORD PTR[4+rsp]
        +	xor	eax,r13d
        +	rol	edx,1
        +	add	esi,ecx
        +	rol	r11d,30
        +	mov	DWORD PTR[16+rsp],edx
        +	add	esi,eax
        +	mov	ebp,DWORD PTR[20+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1859775393+r13*1+rdx]
        +	xor	ebp,DWORD PTR[52+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	ebp,DWORD PTR[8+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[20+rsp],ebp
        +	mov	edx,DWORD PTR[24+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	edx,DWORD PTR[32+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1859775393+r12*1+rbp]
        +	xor	edx,DWORD PTR[56+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	edx,DWORD PTR[12+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[24+rsp],edx
        +	mov	ebp,DWORD PTR[28+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	ebp,DWORD PTR[36+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1859775393+r11*1+rdx]
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	ebp,DWORD PTR[16+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[28+rsp],ebp
        +	mov	edx,DWORD PTR[32+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	edx,DWORD PTR[40+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1859775393+rdi*1+rbp]
        +	xor	edx,DWORD PTR[rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	edx,DWORD PTR[20+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[32+rsp],edx
        +	mov	ebp,DWORD PTR[36+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	ebp,DWORD PTR[44+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1859775393+rsi*1+rdx]
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	ebp,DWORD PTR[24+rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[36+rsp],ebp
        +	mov	edx,DWORD PTR[40+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[48+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1859775393+r13*1+rbp]
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	edx,DWORD PTR[28+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[40+rsp],edx
        +	mov	ebp,DWORD PTR[44+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[52+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1859775393+r12*1+rdx]
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	ebp,DWORD PTR[32+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[44+rsp],ebp
        +	mov	edx,DWORD PTR[48+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[56+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1859775393+r11*1+rbp]
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	edx,DWORD PTR[36+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[48+rsp],edx
        +	mov	ebp,DWORD PTR[52+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1859775393+rdi*1+rdx]
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	ebp,DWORD PTR[40+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[52+rsp],ebp
        +	mov	edx,DWORD PTR[56+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	edx,DWORD PTR[rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1859775393+rsi*1+rbp]
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	edx,DWORD PTR[44+rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[56+rsp],edx
        +	mov	ebp,DWORD PTR[60+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1859775393+r13*1+rdx]
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	ebp,DWORD PTR[48+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[60+rsp],ebp
        +	mov	edx,DWORD PTR[rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1859775393+r12*1+rbp]
        +	xor	edx,DWORD PTR[32+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	edx,DWORD PTR[52+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[rsp],edx
        +	mov	ebp,DWORD PTR[4+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1859775393+r11*1+rdx]
        +	xor	ebp,DWORD PTR[36+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	ebp,DWORD PTR[56+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[4+rsp],ebp
        +	mov	edx,DWORD PTR[8+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1859775393+rdi*1+rbp]
        +	xor	edx,DWORD PTR[40+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	edx,DWORD PTR[60+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[8+rsp],edx
        +	mov	ebp,DWORD PTR[12+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1859775393+rsi*1+rdx]
        +	xor	ebp,DWORD PTR[44+rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	ebp,DWORD PTR[rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[12+rsp],ebp
        +	mov	edx,DWORD PTR[16+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[1859775393+r13*1+rbp]
        +	xor	edx,DWORD PTR[48+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	edx,DWORD PTR[4+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[16+rsp],edx
        +	mov	ebp,DWORD PTR[20+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[1859775393+r12*1+rdx]
        +	xor	ebp,DWORD PTR[52+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	ebp,DWORD PTR[8+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[20+rsp],ebp
        +	mov	edx,DWORD PTR[24+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[32+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[1859775393+r11*1+rbp]
        +	xor	edx,DWORD PTR[56+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	edx,DWORD PTR[12+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[24+rsp],edx
        +	mov	ebp,DWORD PTR[28+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[36+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[1859775393+rdi*1+rdx]
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	ebp,DWORD PTR[16+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[28+rsp],ebp
        +	mov	edx,DWORD PTR[32+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	edx,DWORD PTR[40+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[1859775393+rsi*1+rbp]
        +	xor	edx,DWORD PTR[rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	edx,DWORD PTR[20+rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[32+rsp],edx
        +	mov	ebp,DWORD PTR[36+rsp]
        +	mov	eax,r11d
        +	mov	ebx,r11d
        +	xor	ebp,DWORD PTR[44+rsp]
        +	and	eax,r12d
        +	mov	ecx,esi
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	ebx,r12d
        +	lea	r13d,DWORD PTR[((-1894007588))+r13*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[24+rsp]
        +	add	r13d,eax
        +	and	ebx,edi
        +	rol	ebp,1
        +	add	r13d,ebx
        +	rol	edi,30
        +	mov	DWORD PTR[36+rsp],ebp
        +	add	r13d,ecx
        +	mov	edx,DWORD PTR[40+rsp]
        +	mov	eax,edi
        +	mov	ebx,edi
        +	xor	edx,DWORD PTR[48+rsp]
        +	and	eax,r11d
        +	mov	ecx,r13d
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	ebx,r11d
        +	lea	r12d,DWORD PTR[((-1894007588))+r12*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[28+rsp]
        +	add	r12d,eax
        +	and	ebx,esi
        +	rol	edx,1
        +	add	r12d,ebx
        +	rol	esi,30
        +	mov	DWORD PTR[40+rsp],edx
        +	add	r12d,ecx
        +	mov	ebp,DWORD PTR[44+rsp]
        +	mov	eax,esi
        +	mov	ebx,esi
        +	xor	ebp,DWORD PTR[52+rsp]
        +	and	eax,edi
        +	mov	ecx,r12d
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	ebx,edi
        +	lea	r11d,DWORD PTR[((-1894007588))+r11*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[32+rsp]
        +	add	r11d,eax
        +	and	ebx,r13d
        +	rol	ebp,1
        +	add	r11d,ebx
        +	rol	r13d,30
        +	mov	DWORD PTR[44+rsp],ebp
        +	add	r11d,ecx
        +	mov	edx,DWORD PTR[48+rsp]
        +	mov	eax,r13d
        +	mov	ebx,r13d
        +	xor	edx,DWORD PTR[56+rsp]
        +	and	eax,esi
        +	mov	ecx,r11d
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	ebx,esi
        +	lea	edi,DWORD PTR[((-1894007588))+rdi*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[36+rsp]
        +	add	edi,eax
        +	and	ebx,r12d
        +	rol	edx,1
        +	add	edi,ebx
        +	rol	r12d,30
        +	mov	DWORD PTR[48+rsp],edx
        +	add	edi,ecx
        +	mov	ebp,DWORD PTR[52+rsp]
        +	mov	eax,r12d
        +	mov	ebx,r12d
        +	xor	ebp,DWORD PTR[60+rsp]
        +	and	eax,r13d
        +	mov	ecx,edi
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	ebx,r13d
        +	lea	esi,DWORD PTR[((-1894007588))+rsi*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[40+rsp]
        +	add	esi,eax
        +	and	ebx,r11d
        +	rol	ebp,1
        +	add	esi,ebx
        +	rol	r11d,30
        +	mov	DWORD PTR[52+rsp],ebp
        +	add	esi,ecx
        +	mov	edx,DWORD PTR[56+rsp]
        +	mov	eax,r11d
        +	mov	ebx,r11d
        +	xor	edx,DWORD PTR[rsp]
        +	and	eax,r12d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	ebx,r12d
        +	lea	r13d,DWORD PTR[((-1894007588))+r13*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[44+rsp]
        +	add	r13d,eax
        +	and	ebx,edi
        +	rol	edx,1
        +	add	r13d,ebx
        +	rol	edi,30
        +	mov	DWORD PTR[56+rsp],edx
        +	add	r13d,ecx
        +	mov	ebp,DWORD PTR[60+rsp]
        +	mov	eax,edi
        +	mov	ebx,edi
        +	xor	ebp,DWORD PTR[4+rsp]
        +	and	eax,r11d
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	ebx,r11d
        +	lea	r12d,DWORD PTR[((-1894007588))+r12*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[48+rsp]
        +	add	r12d,eax
        +	and	ebx,esi
        +	rol	ebp,1
        +	add	r12d,ebx
        +	rol	esi,30
        +	mov	DWORD PTR[60+rsp],ebp
        +	add	r12d,ecx
        +	mov	edx,DWORD PTR[rsp]
        +	mov	eax,esi
        +	mov	ebx,esi
        +	xor	edx,DWORD PTR[8+rsp]
        +	and	eax,edi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[32+rsp]
        +	xor	ebx,edi
        +	lea	r11d,DWORD PTR[((-1894007588))+r11*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[52+rsp]
        +	add	r11d,eax
        +	and	ebx,r13d
        +	rol	edx,1
        +	add	r11d,ebx
        +	rol	r13d,30
        +	mov	DWORD PTR[rsp],edx
        +	add	r11d,ecx
        +	mov	ebp,DWORD PTR[4+rsp]
        +	mov	eax,r13d
        +	mov	ebx,r13d
        +	xor	ebp,DWORD PTR[12+rsp]
        +	and	eax,esi
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[36+rsp]
        +	xor	ebx,esi
        +	lea	edi,DWORD PTR[((-1894007588))+rdi*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[56+rsp]
        +	add	edi,eax
        +	and	ebx,r12d
        +	rol	ebp,1
        +	add	edi,ebx
        +	rol	r12d,30
        +	mov	DWORD PTR[4+rsp],ebp
        +	add	edi,ecx
        +	mov	edx,DWORD PTR[8+rsp]
        +	mov	eax,r12d
        +	mov	ebx,r12d
        +	xor	edx,DWORD PTR[16+rsp]
        +	and	eax,r13d
        +	mov	ecx,edi
        +	xor	edx,DWORD PTR[40+rsp]
        +	xor	ebx,r13d
        +	lea	esi,DWORD PTR[((-1894007588))+rsi*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[60+rsp]
        +	add	esi,eax
        +	and	ebx,r11d
        +	rol	edx,1
        +	add	esi,ebx
        +	rol	r11d,30
        +	mov	DWORD PTR[8+rsp],edx
        +	add	esi,ecx
        +	mov	ebp,DWORD PTR[12+rsp]
        +	mov	eax,r11d
        +	mov	ebx,r11d
        +	xor	ebp,DWORD PTR[20+rsp]
        +	and	eax,r12d
        +	mov	ecx,esi
        +	xor	ebp,DWORD PTR[44+rsp]
        +	xor	ebx,r12d
        +	lea	r13d,DWORD PTR[((-1894007588))+r13*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[rsp]
        +	add	r13d,eax
        +	and	ebx,edi
        +	rol	ebp,1
        +	add	r13d,ebx
        +	rol	edi,30
        +	mov	DWORD PTR[12+rsp],ebp
        +	add	r13d,ecx
        +	mov	edx,DWORD PTR[16+rsp]
        +	mov	eax,edi
        +	mov	ebx,edi
        +	xor	edx,DWORD PTR[24+rsp]
        +	and	eax,r11d
        +	mov	ecx,r13d
        +	xor	edx,DWORD PTR[48+rsp]
        +	xor	ebx,r11d
        +	lea	r12d,DWORD PTR[((-1894007588))+r12*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[4+rsp]
        +	add	r12d,eax
        +	and	ebx,esi
        +	rol	edx,1
        +	add	r12d,ebx
        +	rol	esi,30
        +	mov	DWORD PTR[16+rsp],edx
        +	add	r12d,ecx
        +	mov	ebp,DWORD PTR[20+rsp]
        +	mov	eax,esi
        +	mov	ebx,esi
        +	xor	ebp,DWORD PTR[28+rsp]
        +	and	eax,edi
        +	mov	ecx,r12d
        +	xor	ebp,DWORD PTR[52+rsp]
        +	xor	ebx,edi
        +	lea	r11d,DWORD PTR[((-1894007588))+r11*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[8+rsp]
        +	add	r11d,eax
        +	and	ebx,r13d
        +	rol	ebp,1
        +	add	r11d,ebx
        +	rol	r13d,30
        +	mov	DWORD PTR[20+rsp],ebp
        +	add	r11d,ecx
        +	mov	edx,DWORD PTR[24+rsp]
        +	mov	eax,r13d
        +	mov	ebx,r13d
        +	xor	edx,DWORD PTR[32+rsp]
        +	and	eax,esi
        +	mov	ecx,r11d
        +	xor	edx,DWORD PTR[56+rsp]
        +	xor	ebx,esi
        +	lea	edi,DWORD PTR[((-1894007588))+rdi*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[12+rsp]
        +	add	edi,eax
        +	and	ebx,r12d
        +	rol	edx,1
        +	add	edi,ebx
        +	rol	r12d,30
        +	mov	DWORD PTR[24+rsp],edx
        +	add	edi,ecx
        +	mov	ebp,DWORD PTR[28+rsp]
        +	mov	eax,r12d
        +	mov	ebx,r12d
        +	xor	ebp,DWORD PTR[36+rsp]
        +	and	eax,r13d
        +	mov	ecx,edi
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	ebx,r13d
        +	lea	esi,DWORD PTR[((-1894007588))+rsi*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[16+rsp]
        +	add	esi,eax
        +	and	ebx,r11d
        +	rol	ebp,1
        +	add	esi,ebx
        +	rol	r11d,30
        +	mov	DWORD PTR[28+rsp],ebp
        +	add	esi,ecx
        +	mov	edx,DWORD PTR[32+rsp]
        +	mov	eax,r11d
        +	mov	ebx,r11d
        +	xor	edx,DWORD PTR[40+rsp]
        +	and	eax,r12d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[rsp]
        +	xor	ebx,r12d
        +	lea	r13d,DWORD PTR[((-1894007588))+r13*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[20+rsp]
        +	add	r13d,eax
        +	and	ebx,edi
        +	rol	edx,1
        +	add	r13d,ebx
        +	rol	edi,30
        +	mov	DWORD PTR[32+rsp],edx
        +	add	r13d,ecx
        +	mov	ebp,DWORD PTR[36+rsp]
        +	mov	eax,edi
        +	mov	ebx,edi
        +	xor	ebp,DWORD PTR[44+rsp]
        +	and	eax,r11d
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	ebx,r11d
        +	lea	r12d,DWORD PTR[((-1894007588))+r12*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[24+rsp]
        +	add	r12d,eax
        +	and	ebx,esi
        +	rol	ebp,1
        +	add	r12d,ebx
        +	rol	esi,30
        +	mov	DWORD PTR[36+rsp],ebp
        +	add	r12d,ecx
        +	mov	edx,DWORD PTR[40+rsp]
        +	mov	eax,esi
        +	mov	ebx,esi
        +	xor	edx,DWORD PTR[48+rsp]
        +	and	eax,edi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	ebx,edi
        +	lea	r11d,DWORD PTR[((-1894007588))+r11*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[28+rsp]
        +	add	r11d,eax
        +	and	ebx,r13d
        +	rol	edx,1
        +	add	r11d,ebx
        +	rol	r13d,30
        +	mov	DWORD PTR[40+rsp],edx
        +	add	r11d,ecx
        +	mov	ebp,DWORD PTR[44+rsp]
        +	mov	eax,r13d
        +	mov	ebx,r13d
        +	xor	ebp,DWORD PTR[52+rsp]
        +	and	eax,esi
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	ebx,esi
        +	lea	edi,DWORD PTR[((-1894007588))+rdi*1+rdx]
        +	rol	ecx,5
        +	xor	ebp,DWORD PTR[32+rsp]
        +	add	edi,eax
        +	and	ebx,r12d
        +	rol	ebp,1
        +	add	edi,ebx
        +	rol	r12d,30
        +	mov	DWORD PTR[44+rsp],ebp
        +	add	edi,ecx
        +	mov	edx,DWORD PTR[48+rsp]
        +	mov	eax,r12d
        +	mov	ebx,r12d
        +	xor	edx,DWORD PTR[56+rsp]
        +	and	eax,r13d
        +	mov	ecx,edi
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	ebx,r13d
        +	lea	esi,DWORD PTR[((-1894007588))+rsi*1+rbp]
        +	rol	ecx,5
        +	xor	edx,DWORD PTR[36+rsp]
        +	add	esi,eax
        +	and	ebx,r11d
        +	rol	edx,1
        +	add	esi,ebx
        +	rol	r11d,30
        +	mov	DWORD PTR[48+rsp],edx
        +	add	esi,ecx
        +	mov	ebp,DWORD PTR[52+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[((-899497514))+r13*1+rdx]
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	ebp,DWORD PTR[40+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[52+rsp],ebp
        +	mov	edx,DWORD PTR[56+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	edx,DWORD PTR[rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[((-899497514))+r12*1+rbp]
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	edx,DWORD PTR[44+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[56+rsp],edx
        +	mov	ebp,DWORD PTR[60+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[((-899497514))+r11*1+rdx]
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	ebp,DWORD PTR[48+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[60+rsp],ebp
        +	mov	edx,DWORD PTR[rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[((-899497514))+rdi*1+rbp]
        +	xor	edx,DWORD PTR[32+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	edx,DWORD PTR[52+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[rsp],edx
        +	mov	ebp,DWORD PTR[4+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[((-899497514))+rsi*1+rdx]
        +	xor	ebp,DWORD PTR[36+rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	ebp,DWORD PTR[56+rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[4+rsp],ebp
        +	mov	edx,DWORD PTR[8+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[((-899497514))+r13*1+rbp]
        +	xor	edx,DWORD PTR[40+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	edx,DWORD PTR[60+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[8+rsp],edx
        +	mov	ebp,DWORD PTR[12+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[((-899497514))+r12*1+rdx]
        +	xor	ebp,DWORD PTR[44+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	ebp,DWORD PTR[rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[12+rsp],ebp
        +	mov	edx,DWORD PTR[16+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[((-899497514))+r11*1+rbp]
        +	xor	edx,DWORD PTR[48+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	edx,DWORD PTR[4+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[16+rsp],edx
        +	mov	ebp,DWORD PTR[20+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[((-899497514))+rdi*1+rdx]
        +	xor	ebp,DWORD PTR[52+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	ebp,DWORD PTR[8+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[20+rsp],ebp
        +	mov	edx,DWORD PTR[24+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	edx,DWORD PTR[32+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[((-899497514))+rsi*1+rbp]
        +	xor	edx,DWORD PTR[56+rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	edx,DWORD PTR[12+rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[24+rsp],edx
        +	mov	ebp,DWORD PTR[28+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	ebp,DWORD PTR[36+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[((-899497514))+r13*1+rdx]
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	ebp,DWORD PTR[16+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[28+rsp],ebp
        +	mov	edx,DWORD PTR[32+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	edx,DWORD PTR[40+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[((-899497514))+r12*1+rbp]
        +	xor	edx,DWORD PTR[rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	edx,DWORD PTR[20+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[32+rsp],edx
        +	mov	ebp,DWORD PTR[36+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	ebp,DWORD PTR[44+rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[((-899497514))+r11*1+rdx]
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	ebp,DWORD PTR[24+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[36+rsp],ebp
        +	mov	edx,DWORD PTR[40+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	edx,DWORD PTR[48+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[((-899497514))+rdi*1+rbp]
        +	xor	edx,DWORD PTR[8+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	edx,DWORD PTR[28+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	edx,1
        +	mov	DWORD PTR[40+rsp],edx
        +	mov	ebp,DWORD PTR[44+rsp]
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	ebp,DWORD PTR[52+rsp]
        +	xor	eax,r11d
        +	rol	ecx,5
        +	lea	esi,DWORD PTR[((-899497514))+rsi*1+rdx]
        +	xor	ebp,DWORD PTR[12+rsp]
        +	xor	eax,r13d
        +	add	esi,ecx
        +	xor	ebp,DWORD PTR[32+rsp]
        +	rol	r11d,30
        +	add	esi,eax
        +	rol	ebp,1
        +	mov	DWORD PTR[44+rsp],ebp
        +	mov	edx,DWORD PTR[48+rsp]
        +	mov	eax,r11d
        +	mov	ecx,esi
        +	xor	edx,DWORD PTR[56+rsp]
        +	xor	eax,edi
        +	rol	ecx,5
        +	lea	r13d,DWORD PTR[((-899497514))+r13*1+rbp]
        +	xor	edx,DWORD PTR[16+rsp]
        +	xor	eax,r12d
        +	add	r13d,ecx
        +	xor	edx,DWORD PTR[36+rsp]
        +	rol	edi,30
        +	add	r13d,eax
        +	rol	edx,1
        +	mov	DWORD PTR[48+rsp],edx
        +	mov	ebp,DWORD PTR[52+rsp]
        +	mov	eax,edi
        +	mov	ecx,r13d
        +	xor	ebp,DWORD PTR[60+rsp]
        +	xor	eax,esi
        +	rol	ecx,5
        +	lea	r12d,DWORD PTR[((-899497514))+r12*1+rdx]
        +	xor	ebp,DWORD PTR[20+rsp]
        +	xor	eax,r11d
        +	add	r12d,ecx
        +	xor	ebp,DWORD PTR[40+rsp]
        +	rol	esi,30
        +	add	r12d,eax
        +	rol	ebp,1
        +	mov	edx,DWORD PTR[56+rsp]
        +	mov	eax,esi
        +	mov	ecx,r12d
        +	xor	edx,DWORD PTR[rsp]
        +	xor	eax,r13d
        +	rol	ecx,5
        +	lea	r11d,DWORD PTR[((-899497514))+r11*1+rbp]
        +	xor	edx,DWORD PTR[24+rsp]
        +	xor	eax,edi
        +	add	r11d,ecx
        +	xor	edx,DWORD PTR[44+rsp]
        +	rol	r13d,30
        +	add	r11d,eax
        +	rol	edx,1
        +	mov	ebp,DWORD PTR[60+rsp]
        +	mov	eax,r13d
        +	mov	ecx,r11d
        +	xor	ebp,DWORD PTR[4+rsp]
        +	xor	eax,r12d
        +	rol	ecx,5
        +	lea	edi,DWORD PTR[((-899497514))+rdi*1+rdx]
        +	xor	ebp,DWORD PTR[28+rsp]
        +	xor	eax,esi
        +	add	edi,ecx
        +	xor	ebp,DWORD PTR[48+rsp]
        +	rol	r12d,30
        +	add	edi,eax
        +	rol	ebp,1
        +	mov	eax,r12d
        +	mov	ecx,edi
        +	xor	eax,r11d
        +	lea	esi,DWORD PTR[((-899497514))+rsi*1+rbp]
        +	rol	ecx,5
        +	xor	eax,r13d
        +	add	esi,ecx
        +	rol	r11d,30
        +	add	esi,eax
        +	add	esi,DWORD PTR[r8]
        +	add	edi,DWORD PTR[4+r8]
        +	add	r11d,DWORD PTR[8+r8]
        +	add	r12d,DWORD PTR[12+r8]
        +	add	r13d,DWORD PTR[16+r8]
        +	mov	DWORD PTR[r8],esi
        +	mov	DWORD PTR[4+r8],edi
        +	mov	DWORD PTR[8+r8],r11d
        +	mov	DWORD PTR[12+r8],r12d
        +	mov	DWORD PTR[16+r8],r13d
        +
        +	sub	r10,1
        +	lea	r9,QWORD PTR[64+r9]
        +	jnz	$L$loop
        +
        +	mov	rsi,QWORD PTR[64+rsp]
        +	mov	r13,QWORD PTR[rsi]
        +	mov	r12,QWORD PTR[8+rsi]
        +	mov	rbp,QWORD PTR[16+rsi]
        +	mov	rbx,QWORD PTR[24+rsi]
        +	lea	rsp,QWORD PTR[32+rsi]
        +$L$epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_sha1_block_data_order::
        +sha1_block_data_order	ENDP
        +
        +ALIGN	16
        +sha1_block_data_order_ssse3	PROC PRIVATE
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_sha1_block_data_order_ssse3::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +_ssse3_shortcut::
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	lea	rsp,QWORD PTR[((-144))+rsp]
        +	movaps	XMMWORD PTR[(64+0)+rsp],xmm6
        +	movaps	XMMWORD PTR[(64+16)+rsp],xmm7
        +	movaps	XMMWORD PTR[(64+32)+rsp],xmm8
        +	movaps	XMMWORD PTR[(64+48)+rsp],xmm9
        +	movaps	XMMWORD PTR[(64+64)+rsp],xmm10
        +$L$prologue_ssse3::
        +	mov	r8,rdi
        +	mov	r9,rsi
        +	mov	r10,rdx
        +
        +	shl	r10,6
        +	add	r10,r9
        +	lea	r11,QWORD PTR[K_XX_XX]
        +
        +	mov	eax,DWORD PTR[r8]
        +	mov	ebx,DWORD PTR[4+r8]
        +	mov	ecx,DWORD PTR[8+r8]
        +	mov	edx,DWORD PTR[12+r8]
        +	mov	esi,ebx
        +	mov	ebp,DWORD PTR[16+r8]
        +
        +	movdqa	xmm6,XMMWORD PTR[64+r11]
        +	movdqa	xmm9,XMMWORD PTR[r11]
        +	movdqu	xmm0,XMMWORD PTR[r9]
        +	movdqu	xmm1,XMMWORD PTR[16+r9]
        +	movdqu	xmm2,XMMWORD PTR[32+r9]
        +	movdqu	xmm3,XMMWORD PTR[48+r9]
        +DB	102,15,56,0,198
        +	add	r9,64
        +DB	102,15,56,0,206
        +DB	102,15,56,0,214
        +DB	102,15,56,0,222
        +	paddd	xmm0,xmm9
        +	paddd	xmm1,xmm9
        +	paddd	xmm2,xmm9
        +	movdqa	XMMWORD PTR[rsp],xmm0
        +	psubd	xmm0,xmm9
        +	movdqa	XMMWORD PTR[16+rsp],xmm1
        +	psubd	xmm1,xmm9
        +	movdqa	XMMWORD PTR[32+rsp],xmm2
        +	psubd	xmm2,xmm9
        +	jmp	$L$oop_ssse3
        +ALIGN	16
        +$L$oop_ssse3::
        +	movdqa	xmm4,xmm1
        +	add	ebp,DWORD PTR[rsp]
        +	xor	ecx,edx
        +	movdqa	xmm8,xmm3
        +DB	102,15,58,15,224,8
        +	mov	edi,eax
        +	rol	eax,5
        +	paddd	xmm9,xmm3
        +	and	esi,ecx
        +	xor	ecx,edx
        +	psrldq	xmm8,4
        +	xor	esi,edx
        +	add	ebp,eax
        +	pxor	xmm4,xmm0
        +	ror	ebx,2
        +	add	ebp,esi
        +	pxor	xmm8,xmm2
        +	add	edx,DWORD PTR[4+rsp]
        +	xor	ebx,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	pxor	xmm4,xmm8
        +	and	edi,ebx
        +	xor	ebx,ecx
        +	movdqa	XMMWORD PTR[48+rsp],xmm9
        +	xor	edi,ecx
        +	add	edx,ebp
        +	movdqa	xmm10,xmm4
        +	movdqa	xmm8,xmm4
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[8+rsp]
        +	xor	eax,ebx
        +	pslldq	xmm10,12
        +	paddd	xmm4,xmm4
        +	mov	edi,edx
        +	rol	edx,5
        +	and	esi,eax
        +	xor	eax,ebx
        +	psrld	xmm8,31
        +	xor	esi,ebx
        +	add	ecx,edx
        +	movdqa	xmm9,xmm10
        +	ror	ebp,7
        +	add	ecx,esi
        +	psrld	xmm10,30
        +	por	xmm4,xmm8
        +	add	ebx,DWORD PTR[12+rsp]
        +	xor	ebp,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	pslld	xmm9,2
        +	pxor	xmm4,xmm10
        +	and	edi,ebp
        +	xor	ebp,eax
        +	movdqa	xmm10,XMMWORD PTR[r11]
        +	xor	edi,eax
        +	add	ebx,ecx
        +	pxor	xmm4,xmm9
        +	ror	edx,7
        +	add	ebx,edi
        +	movdqa	xmm5,xmm2
        +	add	eax,DWORD PTR[16+rsp]
        +	xor	edx,ebp
        +	movdqa	xmm9,xmm4
        +DB	102,15,58,15,233,8
        +	mov	edi,ebx
        +	rol	ebx,5
        +	paddd	xmm10,xmm4
        +	and	esi,edx
        +	xor	edx,ebp
        +	psrldq	xmm9,4
        +	xor	esi,ebp
        +	add	eax,ebx
        +	pxor	xmm5,xmm1
        +	ror	ecx,7
        +	add	eax,esi
        +	pxor	xmm9,xmm3
        +	add	ebp,DWORD PTR[20+rsp]
        +	xor	ecx,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	pxor	xmm5,xmm9
        +	and	edi,ecx
        +	xor	ecx,edx
        +	movdqa	XMMWORD PTR[rsp],xmm10
        +	xor	edi,edx
        +	add	ebp,eax
        +	movdqa	xmm8,xmm5
        +	movdqa	xmm9,xmm5
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[24+rsp]
        +	xor	ebx,ecx
        +	pslldq	xmm8,12
        +	paddd	xmm5,xmm5
        +	mov	edi,ebp
        +	rol	ebp,5
        +	and	esi,ebx
        +	xor	ebx,ecx
        +	psrld	xmm9,31
        +	xor	esi,ecx
        +	add	edx,ebp
        +	movdqa	xmm10,xmm8
        +	ror	eax,7
        +	add	edx,esi
        +	psrld	xmm8,30
        +	por	xmm5,xmm9
        +	add	ecx,DWORD PTR[28+rsp]
        +	xor	eax,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	pslld	xmm10,2
        +	pxor	xmm5,xmm8
        +	and	edi,eax
        +	xor	eax,ebx
        +	movdqa	xmm8,XMMWORD PTR[16+r11]
        +	xor	edi,ebx
        +	add	ecx,edx
        +	pxor	xmm5,xmm10
        +	ror	ebp,7
        +	add	ecx,edi
        +	movdqa	xmm6,xmm3
        +	add	ebx,DWORD PTR[32+rsp]
        +	xor	ebp,eax
        +	movdqa	xmm10,xmm5
        +DB	102,15,58,15,242,8
        +	mov	edi,ecx
        +	rol	ecx,5
        +	paddd	xmm8,xmm5
        +	and	esi,ebp
        +	xor	ebp,eax
        +	psrldq	xmm10,4
        +	xor	esi,eax
        +	add	ebx,ecx
        +	pxor	xmm6,xmm2
        +	ror	edx,7
        +	add	ebx,esi
        +	pxor	xmm10,xmm4
        +	add	eax,DWORD PTR[36+rsp]
        +	xor	edx,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	pxor	xmm6,xmm10
        +	and	edi,edx
        +	xor	edx,ebp
        +	movdqa	XMMWORD PTR[16+rsp],xmm8
        +	xor	edi,ebp
        +	add	eax,ebx
        +	movdqa	xmm9,xmm6
        +	movdqa	xmm10,xmm6
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[40+rsp]
        +	xor	ecx,edx
        +	pslldq	xmm9,12
        +	paddd	xmm6,xmm6
        +	mov	edi,eax
        +	rol	eax,5
        +	and	esi,ecx
        +	xor	ecx,edx
        +	psrld	xmm10,31
        +	xor	esi,edx
        +	add	ebp,eax
        +	movdqa	xmm8,xmm9
        +	ror	ebx,7
        +	add	ebp,esi
        +	psrld	xmm9,30
        +	por	xmm6,xmm10
        +	add	edx,DWORD PTR[44+rsp]
        +	xor	ebx,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	pslld	xmm8,2
        +	pxor	xmm6,xmm9
        +	and	edi,ebx
        +	xor	ebx,ecx
        +	movdqa	xmm9,XMMWORD PTR[16+r11]
        +	xor	edi,ecx
        +	add	edx,ebp
        +	pxor	xmm6,xmm8
        +	ror	eax,7
        +	add	edx,edi
        +	movdqa	xmm7,xmm4
        +	add	ecx,DWORD PTR[48+rsp]
        +	xor	eax,ebx
        +	movdqa	xmm8,xmm6
        +DB	102,15,58,15,251,8
        +	mov	edi,edx
        +	rol	edx,5
        +	paddd	xmm9,xmm6
        +	and	esi,eax
        +	xor	eax,ebx
        +	psrldq	xmm8,4
        +	xor	esi,ebx
        +	add	ecx,edx
        +	pxor	xmm7,xmm3
        +	ror	ebp,7
        +	add	ecx,esi
        +	pxor	xmm8,xmm5
        +	add	ebx,DWORD PTR[52+rsp]
        +	xor	ebp,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	pxor	xmm7,xmm8
        +	and	edi,ebp
        +	xor	ebp,eax
        +	movdqa	XMMWORD PTR[32+rsp],xmm9
        +	xor	edi,eax
        +	add	ebx,ecx
        +	movdqa	xmm10,xmm7
        +	movdqa	xmm8,xmm7
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[56+rsp]
        +	xor	edx,ebp
        +	pslldq	xmm10,12
        +	paddd	xmm7,xmm7
        +	mov	edi,ebx
        +	rol	ebx,5
        +	and	esi,edx
        +	xor	edx,ebp
        +	psrld	xmm8,31
        +	xor	esi,ebp
        +	add	eax,ebx
        +	movdqa	xmm9,xmm10
        +	ror	ecx,7
        +	add	eax,esi
        +	psrld	xmm10,30
        +	por	xmm7,xmm8
        +	add	ebp,DWORD PTR[60+rsp]
        +	xor	ecx,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	pslld	xmm9,2
        +	pxor	xmm7,xmm10
        +	and	edi,ecx
        +	xor	ecx,edx
        +	movdqa	xmm10,XMMWORD PTR[16+r11]
        +	xor	edi,edx
        +	add	ebp,eax
        +	pxor	xmm7,xmm9
        +	ror	ebx,7
        +	add	ebp,edi
        +	movdqa	xmm9,xmm7
        +	add	edx,DWORD PTR[rsp]
        +	pxor	xmm0,xmm4
        +DB	102,68,15,58,15,206,8
        +	xor	ebx,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	pxor	xmm0,xmm1
        +	and	esi,ebx
        +	xor	ebx,ecx
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm7
        +	xor	esi,ecx
        +	add	edx,ebp
        +	pxor	xmm0,xmm9
        +	ror	eax,7
        +	add	edx,esi
        +	add	ecx,DWORD PTR[4+rsp]
        +	xor	eax,ebx
        +	movdqa	xmm9,xmm0
        +	movdqa	XMMWORD PTR[48+rsp],xmm10
        +	mov	esi,edx
        +	rol	edx,5
        +	and	edi,eax
        +	xor	eax,ebx
        +	pslld	xmm0,2
        +	xor	edi,ebx
        +	add	ecx,edx
        +	psrld	xmm9,30
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[8+rsp]
        +	xor	ebp,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	por	xmm0,xmm9
        +	and	esi,ebp
        +	xor	ebp,eax
        +	movdqa	xmm10,xmm0
        +	xor	esi,eax
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[12+rsp]
        +	xor	edx,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	and	edi,edx
        +	xor	edx,ebp
        +	xor	edi,ebp
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[16+rsp]
        +	pxor	xmm1,xmm5
        +DB	102,68,15,58,15,215,8
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	pxor	xmm1,xmm2
        +	xor	esi,ecx
        +	add	ebp,eax
        +	movdqa	xmm9,xmm8
        +	paddd	xmm8,xmm0
        +	ror	ebx,7
        +	add	ebp,esi
        +	pxor	xmm1,xmm10
        +	add	edx,DWORD PTR[20+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	movdqa	xmm10,xmm1
        +	movdqa	XMMWORD PTR[rsp],xmm8
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	pslld	xmm1,2
        +	add	ecx,DWORD PTR[24+rsp]
        +	xor	esi,ebx
        +	psrld	xmm10,30
        +	mov	edi,edx
        +	rol	edx,5
        +	xor	esi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	por	xmm1,xmm10
        +	add	ebx,DWORD PTR[28+rsp]
        +	xor	edi,eax
        +	movdqa	xmm8,xmm1
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[32+rsp]
        +	pxor	xmm2,xmm6
        +DB	102,68,15,58,15,192,8
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	pxor	xmm2,xmm3
        +	xor	esi,edx
        +	add	eax,ebx
        +	movdqa	xmm10,XMMWORD PTR[32+r11]
        +	paddd	xmm9,xmm1
        +	ror	ecx,7
        +	add	eax,esi
        +	pxor	xmm2,xmm8
        +	add	ebp,DWORD PTR[36+rsp]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	movdqa	xmm8,xmm2
        +	movdqa	XMMWORD PTR[16+rsp],xmm9
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	pslld	xmm2,2
        +	add	edx,DWORD PTR[40+rsp]
        +	xor	esi,ecx
        +	psrld	xmm8,30
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	por	xmm2,xmm8
        +	add	ecx,DWORD PTR[44+rsp]
        +	xor	edi,ebx
        +	movdqa	xmm9,xmm2
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[48+rsp]
        +	pxor	xmm3,xmm7
        +DB	102,68,15,58,15,201,8
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	pxor	xmm3,xmm4
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm2
        +	ror	edx,7
        +	add	ebx,esi
        +	pxor	xmm3,xmm9
        +	add	eax,DWORD PTR[52+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	movdqa	xmm9,xmm3
        +	movdqa	XMMWORD PTR[32+rsp],xmm10
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	pslld	xmm3,2
        +	add	ebp,DWORD PTR[56+rsp]
        +	xor	esi,edx
        +	psrld	xmm9,30
        +	mov	edi,eax
        +	rol	eax,5
        +	xor	esi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,esi
        +	por	xmm3,xmm9
        +	add	edx,DWORD PTR[60+rsp]
        +	xor	edi,ecx
        +	movdqa	xmm10,xmm3
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[rsp]
        +	pxor	xmm4,xmm0
        +DB	102,68,15,58,15,210,8
        +	xor	esi,ebx
        +	mov	edi,edx
        +	rol	edx,5
        +	pxor	xmm4,xmm5
        +	xor	esi,eax
        +	add	ecx,edx
        +	movdqa	xmm9,xmm8
        +	paddd	xmm8,xmm3
        +	ror	ebp,7
        +	add	ecx,esi
        +	pxor	xmm4,xmm10
        +	add	ebx,DWORD PTR[4+rsp]
        +	xor	edi,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	movdqa	xmm10,xmm4
        +	movdqa	XMMWORD PTR[48+rsp],xmm8
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	pslld	xmm4,2
        +	add	eax,DWORD PTR[8+rsp]
        +	xor	esi,ebp
        +	psrld	xmm10,30
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	por	xmm4,xmm10
        +	add	ebp,DWORD PTR[12+rsp]
        +	xor	edi,edx
        +	movdqa	xmm8,xmm4
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[16+rsp]
        +	pxor	xmm5,xmm1
        +DB	102,68,15,58,15,195,8
        +	xor	esi,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	pxor	xmm5,xmm6
        +	xor	esi,ebx
        +	add	edx,ebp
        +	movdqa	xmm10,xmm9
        +	paddd	xmm9,xmm4
        +	ror	eax,7
        +	add	edx,esi
        +	pxor	xmm5,xmm8
        +	add	ecx,DWORD PTR[20+rsp]
        +	xor	edi,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	movdqa	xmm8,xmm5
        +	movdqa	XMMWORD PTR[rsp],xmm9
        +	xor	edi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	pslld	xmm5,2
        +	add	ebx,DWORD PTR[24+rsp]
        +	xor	esi,eax
        +	psrld	xmm8,30
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	por	xmm5,xmm8
        +	add	eax,DWORD PTR[28+rsp]
        +	xor	edi,ebp
        +	movdqa	xmm9,xmm5
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	mov	edi,ecx
        +	pxor	xmm6,xmm2
        +DB	102,68,15,58,15,204,8
        +	xor	ecx,edx
        +	add	ebp,DWORD PTR[32+rsp]
        +	and	edi,edx
        +	pxor	xmm6,xmm7
        +	and	esi,ecx
        +	ror	ebx,7
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm5
        +	add	ebp,edi
        +	mov	edi,eax
        +	pxor	xmm6,xmm9
        +	rol	eax,5
        +	add	ebp,esi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	movdqa	xmm9,xmm6
        +	movdqa	XMMWORD PTR[16+rsp],xmm10
        +	mov	esi,ebx
        +	xor	ebx,ecx
        +	add	edx,DWORD PTR[36+rsp]
        +	and	esi,ecx
        +	pslld	xmm6,2
        +	and	edi,ebx
        +	ror	eax,7
        +	psrld	xmm9,30
        +	add	edx,esi
        +	mov	esi,ebp
        +	rol	ebp,5
        +	add	edx,edi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	por	xmm6,xmm9
        +	mov	edi,eax
        +	xor	eax,ebx
        +	movdqa	xmm10,xmm6
        +	add	ecx,DWORD PTR[40+rsp]
        +	and	edi,ebx
        +	and	esi,eax
        +	ror	ebp,7
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	edx,5
        +	add	ecx,esi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	mov	esi,ebp
        +	xor	ebp,eax
        +	add	ebx,DWORD PTR[44+rsp]
        +	and	esi,eax
        +	and	edi,ebp
        +	ror	edx,7
        +	add	ebx,esi
        +	mov	esi,ecx
        +	rol	ecx,5
        +	add	ebx,edi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	mov	edi,edx
        +	pxor	xmm7,xmm3
        +DB	102,68,15,58,15,213,8
        +	xor	edx,ebp
        +	add	eax,DWORD PTR[48+rsp]
        +	and	edi,ebp
        +	pxor	xmm7,xmm0
        +	and	esi,edx
        +	ror	ecx,7
        +	movdqa	xmm9,XMMWORD PTR[48+r11]
        +	paddd	xmm8,xmm6
        +	add	eax,edi
        +	mov	edi,ebx
        +	pxor	xmm7,xmm10
        +	rol	ebx,5
        +	add	eax,esi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	movdqa	xmm10,xmm7
        +	movdqa	XMMWORD PTR[32+rsp],xmm8
        +	mov	esi,ecx
        +	xor	ecx,edx
        +	add	ebp,DWORD PTR[52+rsp]
        +	and	esi,edx
        +	pslld	xmm7,2
        +	and	edi,ecx
        +	ror	ebx,7
        +	psrld	xmm10,30
        +	add	ebp,esi
        +	mov	esi,eax
        +	rol	eax,5
        +	add	ebp,edi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	por	xmm7,xmm10
        +	mov	edi,ebx
        +	xor	ebx,ecx
        +	movdqa	xmm8,xmm7
        +	add	edx,DWORD PTR[56+rsp]
        +	and	edi,ecx
        +	and	esi,ebx
        +	ror	eax,7
        +	add	edx,edi
        +	mov	edi,ebp
        +	rol	ebp,5
        +	add	edx,esi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	mov	esi,eax
        +	xor	eax,ebx
        +	add	ecx,DWORD PTR[60+rsp]
        +	and	esi,ebx
        +	and	edi,eax
        +	ror	ebp,7
        +	add	ecx,esi
        +	mov	esi,edx
        +	rol	edx,5
        +	add	ecx,edi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	mov	edi,ebp
        +	pxor	xmm0,xmm4
        +DB	102,68,15,58,15,198,8
        +	xor	ebp,eax
        +	add	ebx,DWORD PTR[rsp]
        +	and	edi,eax
        +	pxor	xmm0,xmm1
        +	and	esi,ebp
        +	ror	edx,7
        +	movdqa	xmm10,xmm9
        +	paddd	xmm9,xmm7
        +	add	ebx,edi
        +	mov	edi,ecx
        +	pxor	xmm0,xmm8
        +	rol	ecx,5
        +	add	ebx,esi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	movdqa	xmm8,xmm0
        +	movdqa	XMMWORD PTR[48+rsp],xmm9
        +	mov	esi,edx
        +	xor	edx,ebp
        +	add	eax,DWORD PTR[4+rsp]
        +	and	esi,ebp
        +	pslld	xmm0,2
        +	and	edi,edx
        +	ror	ecx,7
        +	psrld	xmm8,30
        +	add	eax,esi
        +	mov	esi,ebx
        +	rol	ebx,5
        +	add	eax,edi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	por	xmm0,xmm8
        +	mov	edi,ecx
        +	xor	ecx,edx
        +	movdqa	xmm9,xmm0
        +	add	ebp,DWORD PTR[8+rsp]
        +	and	edi,edx
        +	and	esi,ecx
        +	ror	ebx,7
        +	add	ebp,edi
        +	mov	edi,eax
        +	rol	eax,5
        +	add	ebp,esi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	mov	esi,ebx
        +	xor	ebx,ecx
        +	add	edx,DWORD PTR[12+rsp]
        +	and	esi,ecx
        +	and	edi,ebx
        +	ror	eax,7
        +	add	edx,esi
        +	mov	esi,ebp
        +	rol	ebp,5
        +	add	edx,edi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	mov	edi,eax
        +	pxor	xmm1,xmm5
        +DB	102,68,15,58,15,207,8
        +	xor	eax,ebx
        +	add	ecx,DWORD PTR[16+rsp]
        +	and	edi,ebx
        +	pxor	xmm1,xmm2
        +	and	esi,eax
        +	ror	ebp,7
        +	movdqa	xmm8,xmm10
        +	paddd	xmm10,xmm0
        +	add	ecx,edi
        +	mov	edi,edx
        +	pxor	xmm1,xmm9
        +	rol	edx,5
        +	add	ecx,esi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	movdqa	xmm9,xmm1
        +	movdqa	XMMWORD PTR[rsp],xmm10
        +	mov	esi,ebp
        +	xor	ebp,eax
        +	add	ebx,DWORD PTR[20+rsp]
        +	and	esi,eax
        +	pslld	xmm1,2
        +	and	edi,ebp
        +	ror	edx,7
        +	psrld	xmm9,30
        +	add	ebx,esi
        +	mov	esi,ecx
        +	rol	ecx,5
        +	add	ebx,edi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	por	xmm1,xmm9
        +	mov	edi,edx
        +	xor	edx,ebp
        +	movdqa	xmm10,xmm1
        +	add	eax,DWORD PTR[24+rsp]
        +	and	edi,ebp
        +	and	esi,edx
        +	ror	ecx,7
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	ebx,5
        +	add	eax,esi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	mov	esi,ecx
        +	xor	ecx,edx
        +	add	ebp,DWORD PTR[28+rsp]
        +	and	esi,edx
        +	and	edi,ecx
        +	ror	ebx,7
        +	add	ebp,esi
        +	mov	esi,eax
        +	rol	eax,5
        +	add	ebp,edi
        +	xor	ecx,edx
        +	add	ebp,eax
        +	mov	edi,ebx
        +	pxor	xmm2,xmm6
        +DB	102,68,15,58,15,208,8
        +	xor	ebx,ecx
        +	add	edx,DWORD PTR[32+rsp]
        +	and	edi,ecx
        +	pxor	xmm2,xmm3
        +	and	esi,ebx
        +	ror	eax,7
        +	movdqa	xmm9,xmm8
        +	paddd	xmm8,xmm1
        +	add	edx,edi
        +	mov	edi,ebp
        +	pxor	xmm2,xmm10
        +	rol	ebp,5
        +	add	edx,esi
        +	xor	ebx,ecx
        +	add	edx,ebp
        +	movdqa	xmm10,xmm2
        +	movdqa	XMMWORD PTR[16+rsp],xmm8
        +	mov	esi,eax
        +	xor	eax,ebx
        +	add	ecx,DWORD PTR[36+rsp]
        +	and	esi,ebx
        +	pslld	xmm2,2
        +	and	edi,eax
        +	ror	ebp,7
        +	psrld	xmm10,30
        +	add	ecx,esi
        +	mov	esi,edx
        +	rol	edx,5
        +	add	ecx,edi
        +	xor	eax,ebx
        +	add	ecx,edx
        +	por	xmm2,xmm10
        +	mov	edi,ebp
        +	xor	ebp,eax
        +	movdqa	xmm8,xmm2
        +	add	ebx,DWORD PTR[40+rsp]
        +	and	edi,eax
        +	and	esi,ebp
        +	ror	edx,7
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ecx,5
        +	add	ebx,esi
        +	xor	ebp,eax
        +	add	ebx,ecx
        +	mov	esi,edx
        +	xor	edx,ebp
        +	add	eax,DWORD PTR[44+rsp]
        +	and	esi,ebp
        +	and	edi,edx
        +	ror	ecx,7
        +	add	eax,esi
        +	mov	esi,ebx
        +	rol	ebx,5
        +	add	eax,edi
        +	xor	edx,ebp
        +	add	eax,ebx
        +	add	ebp,DWORD PTR[48+rsp]
        +	pxor	xmm3,xmm7
        +DB	102,68,15,58,15,193,8
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	pxor	xmm3,xmm4
        +	xor	esi,ecx
        +	add	ebp,eax
        +	movdqa	xmm10,xmm9
        +	paddd	xmm9,xmm2
        +	ror	ebx,7
        +	add	ebp,esi
        +	pxor	xmm3,xmm8
        +	add	edx,DWORD PTR[52+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	movdqa	xmm8,xmm3
        +	movdqa	XMMWORD PTR[32+rsp],xmm9
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	pslld	xmm3,2
        +	add	ecx,DWORD PTR[56+rsp]
        +	xor	esi,ebx
        +	psrld	xmm8,30
        +	mov	edi,edx
        +	rol	edx,5
        +	xor	esi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	por	xmm3,xmm8
        +	add	ebx,DWORD PTR[60+rsp]
        +	xor	edi,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[rsp]
        +	paddd	xmm10,xmm3
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	movdqa	XMMWORD PTR[48+rsp],xmm10
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	add	ebp,DWORD PTR[4+rsp]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[8+rsp]
        +	xor	esi,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	add	ecx,DWORD PTR[12+rsp]
        +	xor	edi,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	cmp	r9,r10
        +	je	$L$done_ssse3
        +	movdqa	xmm6,XMMWORD PTR[64+r11]
        +	movdqa	xmm9,XMMWORD PTR[r11]
        +	movdqu	xmm0,XMMWORD PTR[r9]
        +	movdqu	xmm1,XMMWORD PTR[16+r9]
        +	movdqu	xmm2,XMMWORD PTR[32+r9]
        +	movdqu	xmm3,XMMWORD PTR[48+r9]
        +DB	102,15,56,0,198
        +	add	r9,64
        +	add	ebx,DWORD PTR[16+rsp]
        +	xor	esi,eax
        +DB	102,15,56,0,206
        +	mov	edi,ecx
        +	rol	ecx,5
        +	paddd	xmm0,xmm9
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	movdqa	XMMWORD PTR[rsp],xmm0
        +	add	eax,DWORD PTR[20+rsp]
        +	xor	edi,ebp
        +	psubd	xmm0,xmm9
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[24+rsp]
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	xor	esi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,esi
        +	add	edx,DWORD PTR[28+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[32+rsp]
        +	xor	esi,ebx
        +DB	102,15,56,0,214
        +	mov	edi,edx
        +	rol	edx,5
        +	paddd	xmm1,xmm9
        +	xor	esi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	movdqa	XMMWORD PTR[16+rsp],xmm1
        +	add	ebx,DWORD PTR[36+rsp]
        +	xor	edi,eax
        +	psubd	xmm1,xmm9
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[40+rsp]
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	add	ebp,DWORD PTR[44+rsp]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[48+rsp]
        +	xor	esi,ecx
        +DB	102,15,56,0,222
        +	mov	edi,ebp
        +	rol	ebp,5
        +	paddd	xmm2,xmm9
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	movdqa	XMMWORD PTR[32+rsp],xmm2
        +	add	ecx,DWORD PTR[52+rsp]
        +	xor	edi,ebx
        +	psubd	xmm2,xmm9
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[56+rsp]
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[60+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	eax,DWORD PTR[r8]
        +	add	esi,DWORD PTR[4+r8]
        +	add	ecx,DWORD PTR[8+r8]
        +	add	edx,DWORD PTR[12+r8]
        +	mov	DWORD PTR[r8],eax
        +	add	ebp,DWORD PTR[16+r8]
        +	mov	DWORD PTR[4+r8],esi
        +	mov	ebx,esi
        +	mov	DWORD PTR[8+r8],ecx
        +	mov	DWORD PTR[12+r8],edx
        +	mov	DWORD PTR[16+r8],ebp
        +	jmp	$L$oop_ssse3
        +
        +ALIGN	16
        +$L$done_ssse3::
        +	add	ebx,DWORD PTR[16+rsp]
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[20+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	ebp,DWORD PTR[24+rsp]
        +	xor	esi,edx
        +	mov	edi,eax
        +	rol	eax,5
        +	xor	esi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,esi
        +	add	edx,DWORD PTR[28+rsp]
        +	xor	edi,ecx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,edi
        +	add	ecx,DWORD PTR[32+rsp]
        +	xor	esi,ebx
        +	mov	edi,edx
        +	rol	edx,5
        +	xor	esi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,esi
        +	add	ebx,DWORD PTR[36+rsp]
        +	xor	edi,eax
        +	mov	esi,ecx
        +	rol	ecx,5
        +	xor	edi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,edi
        +	add	eax,DWORD PTR[40+rsp]
        +	xor	esi,ebp
        +	mov	edi,ebx
        +	rol	ebx,5
        +	xor	esi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,esi
        +	add	ebp,DWORD PTR[44+rsp]
        +	xor	edi,edx
        +	mov	esi,eax
        +	rol	eax,5
        +	xor	edi,ecx
        +	add	ebp,eax
        +	ror	ebx,7
        +	add	ebp,edi
        +	add	edx,DWORD PTR[48+rsp]
        +	xor	esi,ecx
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	esi,ebx
        +	add	edx,ebp
        +	ror	eax,7
        +	add	edx,esi
        +	add	ecx,DWORD PTR[52+rsp]
        +	xor	edi,ebx
        +	mov	esi,edx
        +	rol	edx,5
        +	xor	edi,eax
        +	add	ecx,edx
        +	ror	ebp,7
        +	add	ecx,edi
        +	add	ebx,DWORD PTR[56+rsp]
        +	xor	esi,eax
        +	mov	edi,ecx
        +	rol	ecx,5
        +	xor	esi,ebp
        +	add	ebx,ecx
        +	ror	edx,7
        +	add	ebx,esi
        +	add	eax,DWORD PTR[60+rsp]
        +	xor	edi,ebp
        +	mov	esi,ebx
        +	rol	ebx,5
        +	xor	edi,edx
        +	add	eax,ebx
        +	ror	ecx,7
        +	add	eax,edi
        +	add	eax,DWORD PTR[r8]
        +	add	esi,DWORD PTR[4+r8]
        +	add	ecx,DWORD PTR[8+r8]
        +	mov	DWORD PTR[r8],eax
        +	add	edx,DWORD PTR[12+r8]
        +	mov	DWORD PTR[4+r8],esi
        +	add	ebp,DWORD PTR[16+r8]
        +	mov	DWORD PTR[8+r8],ecx
        +	mov	DWORD PTR[12+r8],edx
        +	mov	DWORD PTR[16+r8],ebp
        +	movaps	xmm6,XMMWORD PTR[((64+0))+rsp]
        +	movaps	xmm7,XMMWORD PTR[((64+16))+rsp]
        +	movaps	xmm8,XMMWORD PTR[((64+32))+rsp]
        +	movaps	xmm9,XMMWORD PTR[((64+48))+rsp]
        +	movaps	xmm10,XMMWORD PTR[((64+64))+rsp]
        +	lea	rsi,QWORD PTR[144+rsp]
        +	mov	r12,QWORD PTR[rsi]
        +	mov	rbp,QWORD PTR[8+rsi]
        +	mov	rbx,QWORD PTR[16+rsi]
        +	lea	rsp,QWORD PTR[24+rsi]
        +$L$epilogue_ssse3::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_sha1_block_data_order_ssse3::
        +sha1_block_data_order_ssse3	ENDP
        +ALIGN	64
        +K_XX_XX::
        +	DD	05a827999h,05a827999h,05a827999h,05a827999h
        +
        +	DD	06ed9eba1h,06ed9eba1h,06ed9eba1h,06ed9eba1h
        +
        +	DD	08f1bbcdch,08f1bbcdch,08f1bbcdch,08f1bbcdch
        +
        +	DD	0ca62c1d6h,0ca62c1d6h,0ca62c1d6h,0ca62c1d6h
        +
        +	DD	000010203h,004050607h,008090a0bh,00c0d0e0fh
        +
        +DB	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115
        +DB	102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44
        +DB	32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60
        +DB	97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114
        +DB	103,62,0
        +ALIGN	64
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$prologue]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[64+rax]
        +	lea	rax,QWORD PTR[32+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +
        +	jmp	$L$common_seh_tail
        +se_handler	ENDP
        +
        +
        +ALIGN	16
        +ssse3_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	mov	rsi,QWORD PTR[8+r9]
        +	mov	r11,QWORD PTR[56+r9]
        +
        +	mov	r10d,DWORD PTR[r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jb	$L$common_seh_tail
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	mov	r10d,DWORD PTR[4+r11]
        +	lea	r10,QWORD PTR[r10*1+rsi]
        +	cmp	rbx,r10
        +	jae	$L$common_seh_tail
        +
        +	lea	rsi,QWORD PTR[64+rax]
        +	lea	rdi,QWORD PTR[512+r8]
        +	mov	ecx,10
        +	DD	0a548f3fch
        +
        +	lea	rax,QWORD PTR[168+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +
        +$L$common_seh_tail::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +ssse3_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_sha1_block_data_order
        +	DD	imagerel $L$SEH_end_sha1_block_data_order
        +	DD	imagerel $L$SEH_info_sha1_block_data_order
        +	DD	imagerel $L$SEH_begin_sha1_block_data_order_ssse3
        +	DD	imagerel $L$SEH_end_sha1_block_data_order_ssse3
        +	DD	imagerel $L$SEH_info_sha1_block_data_order_ssse3
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_sha1_block_data_order::
        +DB	9,0,0,0
        +	DD	imagerel se_handler
        +$L$SEH_info_sha1_block_data_order_ssse3::
        +DB	9,0,0,0
        +	DD	imagerel ssse3_handler
        +	DD	imagerel $L$prologue_ssse3,imagerel $L$epilogue_ssse3
        +
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm
        new file mode 100644
        index 000000000..f685c2fdf
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/sha/sha512-x86_64.asm
        @@ -0,0 +1,1893 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +PUBLIC	sha256_block_data_order
        +
        +ALIGN	16
        +sha256_block_data_order	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_sha256_block_data_order::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +	mov	rcx,r9
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	mov	r11,rsp
        +	shl	rdx,4
        +	sub	rsp,16*4+4*8
        +	lea	rdx,QWORD PTR[rdx*4+rsi]
        +	and	rsp,-64
        +	mov	QWORD PTR[((64+0))+rsp],rdi
        +	mov	QWORD PTR[((64+8))+rsp],rsi
        +	mov	QWORD PTR[((64+16))+rsp],rdx
        +	mov	QWORD PTR[((64+24))+rsp],r11
        +$L$prologue::
        +
        +	lea	rbp,QWORD PTR[K256]
        +
        +	mov	eax,DWORD PTR[rdi]
        +	mov	ebx,DWORD PTR[4+rdi]
        +	mov	ecx,DWORD PTR[8+rdi]
        +	mov	edx,DWORD PTR[12+rdi]
        +	mov	r8d,DWORD PTR[16+rdi]
        +	mov	r9d,DWORD PTR[20+rdi]
        +	mov	r10d,DWORD PTR[24+rdi]
        +	mov	r11d,DWORD PTR[28+rdi]
        +	jmp	$L$loop
        +
        +ALIGN	16
        +$L$loop::
        +	xor	rdi,rdi
        +	mov	r12d,DWORD PTR[rsi]
        +	mov	r13d,r8d
        +	mov	r14d,eax
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r9d
        +	mov	DWORD PTR[rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	ror	r13d,5
        +	add	r12d,r11d
        +	xor	r14d,eax
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r8d
        +	mov	r11d,ebx
        +
        +	ror	r14d,11
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	xor	r11d,ecx
        +	xor	r14d,eax
        +	add	r12d,r15d
        +	mov	r15d,ebx
        +
        +	ror	r13d,6
        +	and	r11d,eax
        +	and	r15d,ecx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r11d,r15d
        +
        +	add	edx,r12d
        +	add	r11d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r11d,r14d
        +
        +	mov	r12d,DWORD PTR[4+rsi]
        +	mov	r13d,edx
        +	mov	r14d,r11d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r8d
        +	mov	DWORD PTR[4+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	ror	r13d,5
        +	add	r12d,r10d
        +	xor	r14d,r11d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,edx
        +	mov	r10d,eax
        +
        +	ror	r14d,11
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	xor	r10d,ebx
        +	xor	r14d,r11d
        +	add	r12d,r15d
        +	mov	r15d,eax
        +
        +	ror	r13d,6
        +	and	r10d,r11d
        +	and	r15d,ebx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r10d,r15d
        +
        +	add	ecx,r12d
        +	add	r10d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r10d,r14d
        +
        +	mov	r12d,DWORD PTR[8+rsi]
        +	mov	r13d,ecx
        +	mov	r14d,r10d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,edx
        +	mov	DWORD PTR[8+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	ror	r13d,5
        +	add	r12d,r9d
        +	xor	r14d,r10d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ecx
        +	mov	r9d,r11d
        +
        +	ror	r14d,11
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	xor	r9d,eax
        +	xor	r14d,r10d
        +	add	r12d,r15d
        +	mov	r15d,r11d
        +
        +	ror	r13d,6
        +	and	r9d,r10d
        +	and	r15d,eax
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r9d,r15d
        +
        +	add	ebx,r12d
        +	add	r9d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r9d,r14d
        +
        +	mov	r12d,DWORD PTR[12+rsi]
        +	mov	r13d,ebx
        +	mov	r14d,r9d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,ecx
        +	mov	DWORD PTR[12+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	ror	r13d,5
        +	add	r12d,r8d
        +	xor	r14d,r9d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ebx
        +	mov	r8d,r10d
        +
        +	ror	r14d,11
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	xor	r8d,r11d
        +	xor	r14d,r9d
        +	add	r12d,r15d
        +	mov	r15d,r10d
        +
        +	ror	r13d,6
        +	and	r8d,r9d
        +	and	r15d,r11d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r8d,r15d
        +
        +	add	eax,r12d
        +	add	r8d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r8d,r14d
        +
        +	mov	r12d,DWORD PTR[16+rsi]
        +	mov	r13d,eax
        +	mov	r14d,r8d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,ebx
        +	mov	DWORD PTR[16+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	ror	r13d,5
        +	add	r12d,edx
        +	xor	r14d,r8d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,eax
        +	mov	edx,r9d
        +
        +	ror	r14d,11
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	xor	edx,r10d
        +	xor	r14d,r8d
        +	add	r12d,r15d
        +	mov	r15d,r9d
        +
        +	ror	r13d,6
        +	and	edx,r8d
        +	and	r15d,r10d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	edx,r15d
        +
        +	add	r11d,r12d
        +	add	edx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	edx,r14d
        +
        +	mov	r12d,DWORD PTR[20+rsi]
        +	mov	r13d,r11d
        +	mov	r14d,edx
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,eax
        +	mov	DWORD PTR[20+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	ror	r13d,5
        +	add	r12d,ecx
        +	xor	r14d,edx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r11d
        +	mov	ecx,r8d
        +
        +	ror	r14d,11
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	xor	ecx,r9d
        +	xor	r14d,edx
        +	add	r12d,r15d
        +	mov	r15d,r8d
        +
        +	ror	r13d,6
        +	and	ecx,edx
        +	and	r15d,r9d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ecx,r15d
        +
        +	add	r10d,r12d
        +	add	ecx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ecx,r14d
        +
        +	mov	r12d,DWORD PTR[24+rsi]
        +	mov	r13d,r10d
        +	mov	r14d,ecx
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r11d
        +	mov	DWORD PTR[24+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	ror	r13d,5
        +	add	r12d,ebx
        +	xor	r14d,ecx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r10d
        +	mov	ebx,edx
        +
        +	ror	r14d,11
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	xor	ebx,r8d
        +	xor	r14d,ecx
        +	add	r12d,r15d
        +	mov	r15d,edx
        +
        +	ror	r13d,6
        +	and	ebx,ecx
        +	and	r15d,r8d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ebx,r15d
        +
        +	add	r9d,r12d
        +	add	ebx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ebx,r14d
        +
        +	mov	r12d,DWORD PTR[28+rsi]
        +	mov	r13d,r9d
        +	mov	r14d,ebx
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r10d
        +	mov	DWORD PTR[28+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	ror	r13d,5
        +	add	r12d,eax
        +	xor	r14d,ebx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r9d
        +	mov	eax,ecx
        +
        +	ror	r14d,11
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	xor	eax,edx
        +	xor	r14d,ebx
        +	add	r12d,r15d
        +	mov	r15d,ecx
        +
        +	ror	r13d,6
        +	and	eax,ebx
        +	and	r15d,edx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	eax,r15d
        +
        +	add	r8d,r12d
        +	add	eax,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	eax,r14d
        +
        +	mov	r12d,DWORD PTR[32+rsi]
        +	mov	r13d,r8d
        +	mov	r14d,eax
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r9d
        +	mov	DWORD PTR[32+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	ror	r13d,5
        +	add	r12d,r11d
        +	xor	r14d,eax
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r8d
        +	mov	r11d,ebx
        +
        +	ror	r14d,11
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	xor	r11d,ecx
        +	xor	r14d,eax
        +	add	r12d,r15d
        +	mov	r15d,ebx
        +
        +	ror	r13d,6
        +	and	r11d,eax
        +	and	r15d,ecx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r11d,r15d
        +
        +	add	edx,r12d
        +	add	r11d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r11d,r14d
        +
        +	mov	r12d,DWORD PTR[36+rsi]
        +	mov	r13d,edx
        +	mov	r14d,r11d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r8d
        +	mov	DWORD PTR[36+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	ror	r13d,5
        +	add	r12d,r10d
        +	xor	r14d,r11d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,edx
        +	mov	r10d,eax
        +
        +	ror	r14d,11
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	xor	r10d,ebx
        +	xor	r14d,r11d
        +	add	r12d,r15d
        +	mov	r15d,eax
        +
        +	ror	r13d,6
        +	and	r10d,r11d
        +	and	r15d,ebx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r10d,r15d
        +
        +	add	ecx,r12d
        +	add	r10d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r10d,r14d
        +
        +	mov	r12d,DWORD PTR[40+rsi]
        +	mov	r13d,ecx
        +	mov	r14d,r10d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,edx
        +	mov	DWORD PTR[40+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	ror	r13d,5
        +	add	r12d,r9d
        +	xor	r14d,r10d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ecx
        +	mov	r9d,r11d
        +
        +	ror	r14d,11
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	xor	r9d,eax
        +	xor	r14d,r10d
        +	add	r12d,r15d
        +	mov	r15d,r11d
        +
        +	ror	r13d,6
        +	and	r9d,r10d
        +	and	r15d,eax
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r9d,r15d
        +
        +	add	ebx,r12d
        +	add	r9d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r9d,r14d
        +
        +	mov	r12d,DWORD PTR[44+rsi]
        +	mov	r13d,ebx
        +	mov	r14d,r9d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,ecx
        +	mov	DWORD PTR[44+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	ror	r13d,5
        +	add	r12d,r8d
        +	xor	r14d,r9d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ebx
        +	mov	r8d,r10d
        +
        +	ror	r14d,11
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	xor	r8d,r11d
        +	xor	r14d,r9d
        +	add	r12d,r15d
        +	mov	r15d,r10d
        +
        +	ror	r13d,6
        +	and	r8d,r9d
        +	and	r15d,r11d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r8d,r15d
        +
        +	add	eax,r12d
        +	add	r8d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r8d,r14d
        +
        +	mov	r12d,DWORD PTR[48+rsi]
        +	mov	r13d,eax
        +	mov	r14d,r8d
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,ebx
        +	mov	DWORD PTR[48+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	ror	r13d,5
        +	add	r12d,edx
        +	xor	r14d,r8d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,eax
        +	mov	edx,r9d
        +
        +	ror	r14d,11
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	xor	edx,r10d
        +	xor	r14d,r8d
        +	add	r12d,r15d
        +	mov	r15d,r9d
        +
        +	ror	r13d,6
        +	and	edx,r8d
        +	and	r15d,r10d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	edx,r15d
        +
        +	add	r11d,r12d
        +	add	edx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	edx,r14d
        +
        +	mov	r12d,DWORD PTR[52+rsi]
        +	mov	r13d,r11d
        +	mov	r14d,edx
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,eax
        +	mov	DWORD PTR[52+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	ror	r13d,5
        +	add	r12d,ecx
        +	xor	r14d,edx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r11d
        +	mov	ecx,r8d
        +
        +	ror	r14d,11
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	xor	ecx,r9d
        +	xor	r14d,edx
        +	add	r12d,r15d
        +	mov	r15d,r8d
        +
        +	ror	r13d,6
        +	and	ecx,edx
        +	and	r15d,r9d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ecx,r15d
        +
        +	add	r10d,r12d
        +	add	ecx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ecx,r14d
        +
        +	mov	r12d,DWORD PTR[56+rsi]
        +	mov	r13d,r10d
        +	mov	r14d,ecx
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r11d
        +	mov	DWORD PTR[56+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	ror	r13d,5
        +	add	r12d,ebx
        +	xor	r14d,ecx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r10d
        +	mov	ebx,edx
        +
        +	ror	r14d,11
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	xor	ebx,r8d
        +	xor	r14d,ecx
        +	add	r12d,r15d
        +	mov	r15d,edx
        +
        +	ror	r13d,6
        +	and	ebx,ecx
        +	and	r15d,r8d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ebx,r15d
        +
        +	add	r9d,r12d
        +	add	ebx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ebx,r14d
        +
        +	mov	r12d,DWORD PTR[60+rsi]
        +	mov	r13d,r9d
        +	mov	r14d,ebx
        +	bswap	r12d
        +	ror	r13d,14
        +	mov	r15d,r10d
        +	mov	DWORD PTR[60+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	ror	r13d,5
        +	add	r12d,eax
        +	xor	r14d,ebx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r9d
        +	mov	eax,ecx
        +
        +	ror	r14d,11
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	xor	eax,edx
        +	xor	r14d,ebx
        +	add	r12d,r15d
        +	mov	r15d,ecx
        +
        +	ror	r13d,6
        +	and	eax,ebx
        +	and	r15d,edx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	eax,r15d
        +
        +	add	r8d,r12d
        +	add	eax,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	eax,r14d
        +
        +	jmp	$L$rounds_16_xx
        +ALIGN	16
        +$L$rounds_16_xx::
        +	mov	r13d,DWORD PTR[4+rsp]
        +	mov	r14d,DWORD PTR[56+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[36+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[rsp]
        +	mov	r13d,r8d
        +	add	r12d,r14d
        +	mov	r14d,eax
        +	ror	r13d,14
        +	mov	r15d,r9d
        +	mov	DWORD PTR[rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	ror	r13d,5
        +	add	r12d,r11d
        +	xor	r14d,eax
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r8d
        +	mov	r11d,ebx
        +
        +	ror	r14d,11
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	xor	r11d,ecx
        +	xor	r14d,eax
        +	add	r12d,r15d
        +	mov	r15d,ebx
        +
        +	ror	r13d,6
        +	and	r11d,eax
        +	and	r15d,ecx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r11d,r15d
        +
        +	add	edx,r12d
        +	add	r11d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r11d,r14d
        +
        +	mov	r13d,DWORD PTR[8+rsp]
        +	mov	r14d,DWORD PTR[60+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[40+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[4+rsp]
        +	mov	r13d,edx
        +	add	r12d,r14d
        +	mov	r14d,r11d
        +	ror	r13d,14
        +	mov	r15d,r8d
        +	mov	DWORD PTR[4+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	ror	r13d,5
        +	add	r12d,r10d
        +	xor	r14d,r11d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,edx
        +	mov	r10d,eax
        +
        +	ror	r14d,11
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	xor	r10d,ebx
        +	xor	r14d,r11d
        +	add	r12d,r15d
        +	mov	r15d,eax
        +
        +	ror	r13d,6
        +	and	r10d,r11d
        +	and	r15d,ebx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r10d,r15d
        +
        +	add	ecx,r12d
        +	add	r10d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r10d,r14d
        +
        +	mov	r13d,DWORD PTR[12+rsp]
        +	mov	r14d,DWORD PTR[rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[44+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[8+rsp]
        +	mov	r13d,ecx
        +	add	r12d,r14d
        +	mov	r14d,r10d
        +	ror	r13d,14
        +	mov	r15d,edx
        +	mov	DWORD PTR[8+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	ror	r13d,5
        +	add	r12d,r9d
        +	xor	r14d,r10d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ecx
        +	mov	r9d,r11d
        +
        +	ror	r14d,11
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	xor	r9d,eax
        +	xor	r14d,r10d
        +	add	r12d,r15d
        +	mov	r15d,r11d
        +
        +	ror	r13d,6
        +	and	r9d,r10d
        +	and	r15d,eax
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r9d,r15d
        +
        +	add	ebx,r12d
        +	add	r9d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r9d,r14d
        +
        +	mov	r13d,DWORD PTR[16+rsp]
        +	mov	r14d,DWORD PTR[4+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[48+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[12+rsp]
        +	mov	r13d,ebx
        +	add	r12d,r14d
        +	mov	r14d,r9d
        +	ror	r13d,14
        +	mov	r15d,ecx
        +	mov	DWORD PTR[12+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	ror	r13d,5
        +	add	r12d,r8d
        +	xor	r14d,r9d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ebx
        +	mov	r8d,r10d
        +
        +	ror	r14d,11
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	xor	r8d,r11d
        +	xor	r14d,r9d
        +	add	r12d,r15d
        +	mov	r15d,r10d
        +
        +	ror	r13d,6
        +	and	r8d,r9d
        +	and	r15d,r11d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r8d,r15d
        +
        +	add	eax,r12d
        +	add	r8d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r8d,r14d
        +
        +	mov	r13d,DWORD PTR[20+rsp]
        +	mov	r14d,DWORD PTR[8+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[52+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[16+rsp]
        +	mov	r13d,eax
        +	add	r12d,r14d
        +	mov	r14d,r8d
        +	ror	r13d,14
        +	mov	r15d,ebx
        +	mov	DWORD PTR[16+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	ror	r13d,5
        +	add	r12d,edx
        +	xor	r14d,r8d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,eax
        +	mov	edx,r9d
        +
        +	ror	r14d,11
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	xor	edx,r10d
        +	xor	r14d,r8d
        +	add	r12d,r15d
        +	mov	r15d,r9d
        +
        +	ror	r13d,6
        +	and	edx,r8d
        +	and	r15d,r10d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	edx,r15d
        +
        +	add	r11d,r12d
        +	add	edx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	edx,r14d
        +
        +	mov	r13d,DWORD PTR[24+rsp]
        +	mov	r14d,DWORD PTR[12+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[56+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[20+rsp]
        +	mov	r13d,r11d
        +	add	r12d,r14d
        +	mov	r14d,edx
        +	ror	r13d,14
        +	mov	r15d,eax
        +	mov	DWORD PTR[20+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	ror	r13d,5
        +	add	r12d,ecx
        +	xor	r14d,edx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r11d
        +	mov	ecx,r8d
        +
        +	ror	r14d,11
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	xor	ecx,r9d
        +	xor	r14d,edx
        +	add	r12d,r15d
        +	mov	r15d,r8d
        +
        +	ror	r13d,6
        +	and	ecx,edx
        +	and	r15d,r9d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ecx,r15d
        +
        +	add	r10d,r12d
        +	add	ecx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ecx,r14d
        +
        +	mov	r13d,DWORD PTR[28+rsp]
        +	mov	r14d,DWORD PTR[16+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[60+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[24+rsp]
        +	mov	r13d,r10d
        +	add	r12d,r14d
        +	mov	r14d,ecx
        +	ror	r13d,14
        +	mov	r15d,r11d
        +	mov	DWORD PTR[24+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	ror	r13d,5
        +	add	r12d,ebx
        +	xor	r14d,ecx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r10d
        +	mov	ebx,edx
        +
        +	ror	r14d,11
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	xor	ebx,r8d
        +	xor	r14d,ecx
        +	add	r12d,r15d
        +	mov	r15d,edx
        +
        +	ror	r13d,6
        +	and	ebx,ecx
        +	and	r15d,r8d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ebx,r15d
        +
        +	add	r9d,r12d
        +	add	ebx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ebx,r14d
        +
        +	mov	r13d,DWORD PTR[32+rsp]
        +	mov	r14d,DWORD PTR[20+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[28+rsp]
        +	mov	r13d,r9d
        +	add	r12d,r14d
        +	mov	r14d,ebx
        +	ror	r13d,14
        +	mov	r15d,r10d
        +	mov	DWORD PTR[28+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	ror	r13d,5
        +	add	r12d,eax
        +	xor	r14d,ebx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r9d
        +	mov	eax,ecx
        +
        +	ror	r14d,11
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	xor	eax,edx
        +	xor	r14d,ebx
        +	add	r12d,r15d
        +	mov	r15d,ecx
        +
        +	ror	r13d,6
        +	and	eax,ebx
        +	and	r15d,edx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	eax,r15d
        +
        +	add	r8d,r12d
        +	add	eax,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	eax,r14d
        +
        +	mov	r13d,DWORD PTR[36+rsp]
        +	mov	r14d,DWORD PTR[24+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[4+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[32+rsp]
        +	mov	r13d,r8d
        +	add	r12d,r14d
        +	mov	r14d,eax
        +	ror	r13d,14
        +	mov	r15d,r9d
        +	mov	DWORD PTR[32+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	ror	r13d,5
        +	add	r12d,r11d
        +	xor	r14d,eax
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r8d
        +	mov	r11d,ebx
        +
        +	ror	r14d,11
        +	xor	r13d,r8d
        +	xor	r15d,r10d
        +
        +	xor	r11d,ecx
        +	xor	r14d,eax
        +	add	r12d,r15d
        +	mov	r15d,ebx
        +
        +	ror	r13d,6
        +	and	r11d,eax
        +	and	r15d,ecx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r11d,r15d
        +
        +	add	edx,r12d
        +	add	r11d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r11d,r14d
        +
        +	mov	r13d,DWORD PTR[40+rsp]
        +	mov	r14d,DWORD PTR[28+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[8+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[36+rsp]
        +	mov	r13d,edx
        +	add	r12d,r14d
        +	mov	r14d,r11d
        +	ror	r13d,14
        +	mov	r15d,r8d
        +	mov	DWORD PTR[36+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	ror	r13d,5
        +	add	r12d,r10d
        +	xor	r14d,r11d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,edx
        +	mov	r10d,eax
        +
        +	ror	r14d,11
        +	xor	r13d,edx
        +	xor	r15d,r9d
        +
        +	xor	r10d,ebx
        +	xor	r14d,r11d
        +	add	r12d,r15d
        +	mov	r15d,eax
        +
        +	ror	r13d,6
        +	and	r10d,r11d
        +	and	r15d,ebx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r10d,r15d
        +
        +	add	ecx,r12d
        +	add	r10d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r10d,r14d
        +
        +	mov	r13d,DWORD PTR[44+rsp]
        +	mov	r14d,DWORD PTR[32+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[12+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[40+rsp]
        +	mov	r13d,ecx
        +	add	r12d,r14d
        +	mov	r14d,r10d
        +	ror	r13d,14
        +	mov	r15d,edx
        +	mov	DWORD PTR[40+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	ror	r13d,5
        +	add	r12d,r9d
        +	xor	r14d,r10d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ecx
        +	mov	r9d,r11d
        +
        +	ror	r14d,11
        +	xor	r13d,ecx
        +	xor	r15d,r8d
        +
        +	xor	r9d,eax
        +	xor	r14d,r10d
        +	add	r12d,r15d
        +	mov	r15d,r11d
        +
        +	ror	r13d,6
        +	and	r9d,r10d
        +	and	r15d,eax
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r9d,r15d
        +
        +	add	ebx,r12d
        +	add	r9d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r9d,r14d
        +
        +	mov	r13d,DWORD PTR[48+rsp]
        +	mov	r14d,DWORD PTR[36+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[16+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[44+rsp]
        +	mov	r13d,ebx
        +	add	r12d,r14d
        +	mov	r14d,r9d
        +	ror	r13d,14
        +	mov	r15d,ecx
        +	mov	DWORD PTR[44+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	ror	r13d,5
        +	add	r12d,r8d
        +	xor	r14d,r9d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,ebx
        +	mov	r8d,r10d
        +
        +	ror	r14d,11
        +	xor	r13d,ebx
        +	xor	r15d,edx
        +
        +	xor	r8d,r11d
        +	xor	r14d,r9d
        +	add	r12d,r15d
        +	mov	r15d,r10d
        +
        +	ror	r13d,6
        +	and	r8d,r9d
        +	and	r15d,r11d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	r8d,r15d
        +
        +	add	eax,r12d
        +	add	r8d,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	r8d,r14d
        +
        +	mov	r13d,DWORD PTR[52+rsp]
        +	mov	r14d,DWORD PTR[40+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[20+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[48+rsp]
        +	mov	r13d,eax
        +	add	r12d,r14d
        +	mov	r14d,r8d
        +	ror	r13d,14
        +	mov	r15d,ebx
        +	mov	DWORD PTR[48+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	ror	r13d,5
        +	add	r12d,edx
        +	xor	r14d,r8d
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,eax
        +	mov	edx,r9d
        +
        +	ror	r14d,11
        +	xor	r13d,eax
        +	xor	r15d,ecx
        +
        +	xor	edx,r10d
        +	xor	r14d,r8d
        +	add	r12d,r15d
        +	mov	r15d,r9d
        +
        +	ror	r13d,6
        +	and	edx,r8d
        +	and	r15d,r10d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	edx,r15d
        +
        +	add	r11d,r12d
        +	add	edx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	edx,r14d
        +
        +	mov	r13d,DWORD PTR[56+rsp]
        +	mov	r14d,DWORD PTR[44+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[24+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[52+rsp]
        +	mov	r13d,r11d
        +	add	r12d,r14d
        +	mov	r14d,edx
        +	ror	r13d,14
        +	mov	r15d,eax
        +	mov	DWORD PTR[52+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	ror	r13d,5
        +	add	r12d,ecx
        +	xor	r14d,edx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r11d
        +	mov	ecx,r8d
        +
        +	ror	r14d,11
        +	xor	r13d,r11d
        +	xor	r15d,ebx
        +
        +	xor	ecx,r9d
        +	xor	r14d,edx
        +	add	r12d,r15d
        +	mov	r15d,r8d
        +
        +	ror	r13d,6
        +	and	ecx,edx
        +	and	r15d,r9d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ecx,r15d
        +
        +	add	r10d,r12d
        +	add	ecx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ecx,r14d
        +
        +	mov	r13d,DWORD PTR[60+rsp]
        +	mov	r14d,DWORD PTR[48+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[28+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[56+rsp]
        +	mov	r13d,r10d
        +	add	r12d,r14d
        +	mov	r14d,ecx
        +	ror	r13d,14
        +	mov	r15d,r11d
        +	mov	DWORD PTR[56+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	ror	r13d,5
        +	add	r12d,ebx
        +	xor	r14d,ecx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r10d
        +	mov	ebx,edx
        +
        +	ror	r14d,11
        +	xor	r13d,r10d
        +	xor	r15d,eax
        +
        +	xor	ebx,r8d
        +	xor	r14d,ecx
        +	add	r12d,r15d
        +	mov	r15d,edx
        +
        +	ror	r13d,6
        +	and	ebx,ecx
        +	and	r15d,r8d
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	ebx,r15d
        +
        +	add	r9d,r12d
        +	add	ebx,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	ebx,r14d
        +
        +	mov	r13d,DWORD PTR[rsp]
        +	mov	r14d,DWORD PTR[52+rsp]
        +	mov	r12d,r13d
        +	mov	r15d,r14d
        +
        +	ror	r12d,11
        +	xor	r12d,r13d
        +	shr	r13d,3
        +
        +	ror	r12d,7
        +	xor	r13d,r12d
        +	mov	r12d,DWORD PTR[32+rsp]
        +
        +	ror	r15d,2
        +	xor	r15d,r14d
        +	shr	r14d,10
        +
        +	ror	r15d,17
        +	add	r12d,r13d
        +	xor	r14d,r15d
        +
        +	add	r12d,DWORD PTR[60+rsp]
        +	mov	r13d,r9d
        +	add	r12d,r14d
        +	mov	r14d,ebx
        +	ror	r13d,14
        +	mov	r15d,r10d
        +	mov	DWORD PTR[60+rsp],r12d
        +
        +	ror	r14d,9
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	ror	r13d,5
        +	add	r12d,eax
        +	xor	r14d,ebx
        +
        +	add	r12d,DWORD PTR[rdi*4+rbp]
        +	and	r15d,r9d
        +	mov	eax,ecx
        +
        +	ror	r14d,11
        +	xor	r13d,r9d
        +	xor	r15d,r11d
        +
        +	xor	eax,edx
        +	xor	r14d,ebx
        +	add	r12d,r15d
        +	mov	r15d,ecx
        +
        +	ror	r13d,6
        +	and	eax,ebx
        +	and	r15d,edx
        +
        +	ror	r14d,2
        +	add	r12d,r13d
        +	add	eax,r15d
        +
        +	add	r8d,r12d
        +	add	eax,r12d
        +	lea	rdi,QWORD PTR[1+rdi]
        +	add	eax,r14d
        +
        +	cmp	rdi,64
        +	jb	$L$rounds_16_xx
        +
        +	mov	rdi,QWORD PTR[((64+0))+rsp]
        +	lea	rsi,QWORD PTR[64+rsi]
        +
        +	add	eax,DWORD PTR[rdi]
        +	add	ebx,DWORD PTR[4+rdi]
        +	add	ecx,DWORD PTR[8+rdi]
        +	add	edx,DWORD PTR[12+rdi]
        +	add	r8d,DWORD PTR[16+rdi]
        +	add	r9d,DWORD PTR[20+rdi]
        +	add	r10d,DWORD PTR[24+rdi]
        +	add	r11d,DWORD PTR[28+rdi]
        +
        +	cmp	rsi,QWORD PTR[((64+16))+rsp]
        +
        +	mov	DWORD PTR[rdi],eax
        +	mov	DWORD PTR[4+rdi],ebx
        +	mov	DWORD PTR[8+rdi],ecx
        +	mov	DWORD PTR[12+rdi],edx
        +	mov	DWORD PTR[16+rdi],r8d
        +	mov	DWORD PTR[20+rdi],r9d
        +	mov	DWORD PTR[24+rdi],r10d
        +	mov	DWORD PTR[28+rdi],r11d
        +	jb	$L$loop
        +
        +	mov	rsi,QWORD PTR[((64+24))+rsp]
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_sha256_block_data_order::
        +sha256_block_data_order	ENDP
        +ALIGN	64
        +
        +K256::
        +	DD	0428a2f98h,071374491h,0b5c0fbcfh,0e9b5dba5h
        +	DD	03956c25bh,059f111f1h,0923f82a4h,0ab1c5ed5h
        +	DD	0d807aa98h,012835b01h,0243185beh,0550c7dc3h
        +	DD	072be5d74h,080deb1feh,09bdc06a7h,0c19bf174h
        +	DD	0e49b69c1h,0efbe4786h,00fc19dc6h,0240ca1cch
        +	DD	02de92c6fh,04a7484aah,05cb0a9dch,076f988dah
        +	DD	0983e5152h,0a831c66dh,0b00327c8h,0bf597fc7h
        +	DD	0c6e00bf3h,0d5a79147h,006ca6351h,014292967h
        +	DD	027b70a85h,02e1b2138h,04d2c6dfch,053380d13h
        +	DD	0650a7354h,0766a0abbh,081c2c92eh,092722c85h
        +	DD	0a2bfe8a1h,0a81a664bh,0c24b8b70h,0c76c51a3h
        +	DD	0d192e819h,0d6990624h,0f40e3585h,0106aa070h
        +	DD	019a4c116h,01e376c08h,02748774ch,034b0bcb5h
        +	DD	0391c0cb3h,04ed8aa4ah,05b9cca4fh,0682e6ff3h
        +	DD	0748f82eeh,078a5636fh,084c87814h,08cc70208h
        +	DD	090befffah,0a4506cebh,0bef9a3f7h,0c67178f2h
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[((64+24))+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_sha256_block_data_order
        +	DD	imagerel $L$SEH_end_sha256_block_data_order
        +	DD	imagerel $L$SEH_info_sha256_block_data_order
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_sha256_block_data_order::
        +DB	9,0,0,0
        +	DD	imagerel se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm b/vendor/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm
        new file mode 100644
        index 000000000..42b524dc8
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/whrlpool/wp-x86_64.asm
        @@ -0,0 +1,972 @@
        +OPTION	DOTNAME
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +PUBLIC	whirlpool_block
        +
        +ALIGN	16
        +whirlpool_block	PROC PUBLIC
        +	mov	QWORD PTR[8+rsp],rdi	;WIN64 prologue
        +	mov	QWORD PTR[16+rsp],rsi
        +	mov	rax,rsp
        +$L$SEH_begin_whirlpool_block::
        +	mov	rdi,rcx
        +	mov	rsi,rdx
        +	mov	rdx,r8
        +
        +
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +
        +	mov	r11,rsp
        +	sub	rsp,128+40
        +	and	rsp,-64
        +
        +	lea	r10,QWORD PTR[128+rsp]
        +	mov	QWORD PTR[r10],rdi
        +	mov	QWORD PTR[8+r10],rsi
        +	mov	QWORD PTR[16+r10],rdx
        +	mov	QWORD PTR[32+r10],r11
        +$L$prologue::
        +
        +	mov	rbx,r10
        +	lea	rbp,QWORD PTR[$L$table]
        +
        +	xor	rcx,rcx
        +	xor	rdx,rdx
        +	mov	r8,QWORD PTR[rdi]
        +	mov	r9,QWORD PTR[8+rdi]
        +	mov	r10,QWORD PTR[16+rdi]
        +	mov	r11,QWORD PTR[24+rdi]
        +	mov	r12,QWORD PTR[32+rdi]
        +	mov	r13,QWORD PTR[40+rdi]
        +	mov	r14,QWORD PTR[48+rdi]
        +	mov	r15,QWORD PTR[56+rdi]
        +$L$outerloop::
        +	mov	QWORD PTR[rsp],r8
        +	mov	QWORD PTR[8+rsp],r9
        +	mov	QWORD PTR[16+rsp],r10
        +	mov	QWORD PTR[24+rsp],r11
        +	mov	QWORD PTR[32+rsp],r12
        +	mov	QWORD PTR[40+rsp],r13
        +	mov	QWORD PTR[48+rsp],r14
        +	mov	QWORD PTR[56+rsp],r15
        +	xor	r8,QWORD PTR[rsi]
        +	xor	r9,QWORD PTR[8+rsi]
        +	xor	r10,QWORD PTR[16+rsi]
        +	xor	r11,QWORD PTR[24+rsi]
        +	xor	r12,QWORD PTR[32+rsi]
        +	xor	r13,QWORD PTR[40+rsi]
        +	xor	r14,QWORD PTR[48+rsi]
        +	xor	r15,QWORD PTR[56+rsi]
        +	mov	QWORD PTR[((64+0))+rsp],r8
        +	mov	QWORD PTR[((64+8))+rsp],r9
        +	mov	QWORD PTR[((64+16))+rsp],r10
        +	mov	QWORD PTR[((64+24))+rsp],r11
        +	mov	QWORD PTR[((64+32))+rsp],r12
        +	mov	QWORD PTR[((64+40))+rsp],r13
        +	mov	QWORD PTR[((64+48))+rsp],r14
        +	mov	QWORD PTR[((64+56))+rsp],r15
        +	xor	rsi,rsi
        +	mov	QWORD PTR[24+rbx],rsi
        +ALIGN	16
        +$L$round::
        +	mov	r8,QWORD PTR[4096+rsi*8+rbp]
        +	mov	eax,DWORD PTR[rsp]
        +	mov	ebx,DWORD PTR[4+rsp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r8,QWORD PTR[rsi*8+rbp]
        +	mov	r9,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((0+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	mov	r10,QWORD PTR[6+rsi*8+rbp]
        +	mov	r11,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	mov	r12,QWORD PTR[4+rsi*8+rbp]
        +	mov	r13,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((0+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	mov	r14,QWORD PTR[2+rsi*8+rbp]
        +	mov	r15,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r9,QWORD PTR[rsi*8+rbp]
        +	xor	r10,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((8+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r11,QWORD PTR[6+rsi*8+rbp]
        +	xor	r12,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r13,QWORD PTR[4+rsi*8+rbp]
        +	xor	r14,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((8+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r15,QWORD PTR[2+rsi*8+rbp]
        +	xor	r8,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r10,QWORD PTR[rsi*8+rbp]
        +	xor	r11,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((16+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r12,QWORD PTR[6+rsi*8+rbp]
        +	xor	r13,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r14,QWORD PTR[4+rsi*8+rbp]
        +	xor	r15,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((16+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r8,QWORD PTR[2+rsi*8+rbp]
        +	xor	r9,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r11,QWORD PTR[rsi*8+rbp]
        +	xor	r12,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((24+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r13,QWORD PTR[6+rsi*8+rbp]
        +	xor	r14,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r15,QWORD PTR[4+rsi*8+rbp]
        +	xor	r8,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((24+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r9,QWORD PTR[2+rsi*8+rbp]
        +	xor	r10,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r12,QWORD PTR[rsi*8+rbp]
        +	xor	r13,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((32+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r14,QWORD PTR[6+rsi*8+rbp]
        +	xor	r15,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r8,QWORD PTR[4+rsi*8+rbp]
        +	xor	r9,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((32+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r10,QWORD PTR[2+rsi*8+rbp]
        +	xor	r11,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r13,QWORD PTR[rsi*8+rbp]
        +	xor	r14,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((40+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r15,QWORD PTR[6+rsi*8+rbp]
        +	xor	r8,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r9,QWORD PTR[4+rsi*8+rbp]
        +	xor	r10,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((40+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r11,QWORD PTR[2+rsi*8+rbp]
        +	xor	r12,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r14,QWORD PTR[rsi*8+rbp]
        +	xor	r15,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((48+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r8,QWORD PTR[6+rsi*8+rbp]
        +	xor	r9,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r10,QWORD PTR[4+rsi*8+rbp]
        +	xor	r11,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((48+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r12,QWORD PTR[2+rsi*8+rbp]
        +	xor	r13,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r15,QWORD PTR[rsi*8+rbp]
        +	xor	r8,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((56+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r9,QWORD PTR[6+rsi*8+rbp]
        +	xor	r10,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r11,QWORD PTR[4+rsi*8+rbp]
        +	xor	r12,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((56+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r13,QWORD PTR[2+rsi*8+rbp]
        +	xor	r14,QWORD PTR[1+rdi*8+rbp]
        +	mov	QWORD PTR[rsp],r8
        +	mov	QWORD PTR[8+rsp],r9
        +	mov	QWORD PTR[16+rsp],r10
        +	mov	QWORD PTR[24+rsp],r11
        +	mov	QWORD PTR[32+rsp],r12
        +	mov	QWORD PTR[40+rsp],r13
        +	mov	QWORD PTR[48+rsp],r14
        +	mov	QWORD PTR[56+rsp],r15
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r8,QWORD PTR[rsi*8+rbp]
        +	xor	r9,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+0+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r10,QWORD PTR[6+rsi*8+rbp]
        +	xor	r11,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r12,QWORD PTR[4+rsi*8+rbp]
        +	xor	r13,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+0+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r14,QWORD PTR[2+rsi*8+rbp]
        +	xor	r15,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r9,QWORD PTR[rsi*8+rbp]
        +	xor	r10,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+8+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r11,QWORD PTR[6+rsi*8+rbp]
        +	xor	r12,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r13,QWORD PTR[4+rsi*8+rbp]
        +	xor	r14,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+8+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r15,QWORD PTR[2+rsi*8+rbp]
        +	xor	r8,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r10,QWORD PTR[rsi*8+rbp]
        +	xor	r11,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+16+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r12,QWORD PTR[6+rsi*8+rbp]
        +	xor	r13,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r14,QWORD PTR[4+rsi*8+rbp]
        +	xor	r15,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+16+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r8,QWORD PTR[2+rsi*8+rbp]
        +	xor	r9,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r11,QWORD PTR[rsi*8+rbp]
        +	xor	r12,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+24+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r13,QWORD PTR[6+rsi*8+rbp]
        +	xor	r14,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r15,QWORD PTR[4+rsi*8+rbp]
        +	xor	r8,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+24+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r9,QWORD PTR[2+rsi*8+rbp]
        +	xor	r10,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r12,QWORD PTR[rsi*8+rbp]
        +	xor	r13,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+32+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r14,QWORD PTR[6+rsi*8+rbp]
        +	xor	r15,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r8,QWORD PTR[4+rsi*8+rbp]
        +	xor	r9,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+32+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r10,QWORD PTR[2+rsi*8+rbp]
        +	xor	r11,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r13,QWORD PTR[rsi*8+rbp]
        +	xor	r14,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+40+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r15,QWORD PTR[6+rsi*8+rbp]
        +	xor	r8,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r9,QWORD PTR[4+rsi*8+rbp]
        +	xor	r10,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+40+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r11,QWORD PTR[2+rsi*8+rbp]
        +	xor	r12,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r14,QWORD PTR[rsi*8+rbp]
        +	xor	r15,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR[((64+48+8))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r8,QWORD PTR[6+rsi*8+rbp]
        +	xor	r9,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r10,QWORD PTR[4+rsi*8+rbp]
        +	xor	r11,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR[((64+48+8+4))+rsp]
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r12,QWORD PTR[2+rsi*8+rbp]
        +	xor	r13,QWORD PTR[1+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	eax,16
        +	xor	r15,QWORD PTR[rsi*8+rbp]
        +	xor	r8,QWORD PTR[7+rdi*8+rbp]
        +	mov	cl,al
        +	mov	dl,ah
        +
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r9,QWORD PTR[6+rsi*8+rbp]
        +	xor	r10,QWORD PTR[5+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	shr	ebx,16
        +	xor	r11,QWORD PTR[4+rsi*8+rbp]
        +	xor	r12,QWORD PTR[3+rdi*8+rbp]
        +	mov	cl,bl
        +	mov	dl,bh
        +
        +	lea	rsi,QWORD PTR[rcx*1+rcx]
        +	lea	rdi,QWORD PTR[rdx*1+rdx]
        +	xor	r13,QWORD PTR[2+rsi*8+rbp]
        +	xor	r14,QWORD PTR[1+rdi*8+rbp]
        +	lea	rbx,QWORD PTR[128+rsp]
        +	mov	rsi,QWORD PTR[24+rbx]
        +	add	rsi,1
        +	cmp	rsi,10
        +	je	$L$roundsdone
        +
        +	mov	QWORD PTR[24+rbx],rsi
        +	mov	QWORD PTR[((64+0))+rsp],r8
        +	mov	QWORD PTR[((64+8))+rsp],r9
        +	mov	QWORD PTR[((64+16))+rsp],r10
        +	mov	QWORD PTR[((64+24))+rsp],r11
        +	mov	QWORD PTR[((64+32))+rsp],r12
        +	mov	QWORD PTR[((64+40))+rsp],r13
        +	mov	QWORD PTR[((64+48))+rsp],r14
        +	mov	QWORD PTR[((64+56))+rsp],r15
        +	jmp	$L$round
        +ALIGN	16
        +$L$roundsdone::
        +	mov	rdi,QWORD PTR[rbx]
        +	mov	rsi,QWORD PTR[8+rbx]
        +	mov	rax,QWORD PTR[16+rbx]
        +	xor	r8,QWORD PTR[rsi]
        +	xor	r9,QWORD PTR[8+rsi]
        +	xor	r10,QWORD PTR[16+rsi]
        +	xor	r11,QWORD PTR[24+rsi]
        +	xor	r12,QWORD PTR[32+rsi]
        +	xor	r13,QWORD PTR[40+rsi]
        +	xor	r14,QWORD PTR[48+rsi]
        +	xor	r15,QWORD PTR[56+rsi]
        +	xor	r8,QWORD PTR[rdi]
        +	xor	r9,QWORD PTR[8+rdi]
        +	xor	r10,QWORD PTR[16+rdi]
        +	xor	r11,QWORD PTR[24+rdi]
        +	xor	r12,QWORD PTR[32+rdi]
        +	xor	r13,QWORD PTR[40+rdi]
        +	xor	r14,QWORD PTR[48+rdi]
        +	xor	r15,QWORD PTR[56+rdi]
        +	mov	QWORD PTR[rdi],r8
        +	mov	QWORD PTR[8+rdi],r9
        +	mov	QWORD PTR[16+rdi],r10
        +	mov	QWORD PTR[24+rdi],r11
        +	mov	QWORD PTR[32+rdi],r12
        +	mov	QWORD PTR[40+rdi],r13
        +	mov	QWORD PTR[48+rdi],r14
        +	mov	QWORD PTR[56+rdi],r15
        +	lea	rsi,QWORD PTR[64+rsi]
        +	sub	rax,1
        +	jz	$L$alldone
        +	mov	QWORD PTR[8+rbx],rsi
        +	mov	QWORD PTR[16+rbx],rax
        +	jmp	$L$outerloop
        +$L$alldone::
        +	mov	rsi,QWORD PTR[32+rbx]
        +	mov	r15,QWORD PTR[rsi]
        +	mov	r14,QWORD PTR[8+rsi]
        +	mov	r13,QWORD PTR[16+rsi]
        +	mov	r12,QWORD PTR[24+rsi]
        +	mov	rbp,QWORD PTR[32+rsi]
        +	mov	rbx,QWORD PTR[40+rsi]
        +	lea	rsp,QWORD PTR[48+rsi]
        +$L$epilogue::
        +	mov	rdi,QWORD PTR[8+rsp]	;WIN64 epilogue
        +	mov	rsi,QWORD PTR[16+rsp]
        +	DB	0F3h,0C3h		;repret
        +$L$SEH_end_whirlpool_block::
        +whirlpool_block	ENDP
        +
        +ALIGN	64
        +
        +$L$table::
        +DB	24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216
        +DB	35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38
        +DB	198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184
        +DB	232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251
        +DB	135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203
        +DB	184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17
        +DB	1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9
        +DB	79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13
        +DB	54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155
        +DB	166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255
        +DB	210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12
        +DB	245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14
        +DB	121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150
        +DB	111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48
        +DB	145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109
        +DB	82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248
        +DB	96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71
        +DB	188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53
        +DB	155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55
        +DB	142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138
        +DB	163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210
        +DB	12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108
        +DB	123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132
        +DB	53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128
        +DB	29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245
        +DB	224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179
        +DB	215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33
        +DB	194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156
        +DB	46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67
        +DB	75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41
        +DB	254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93
        +DB	87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213
        +DB	21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189
        +DB	119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232
        +DB	55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146
        +DB	229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158
        +DB	159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19
        +DB	240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35
        +DB	74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32
        +DB	218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68
        +DB	88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162
        +DB	201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207
        +DB	41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124
        +DB	10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90
        +DB	177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80
        +DB	160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201
        +DB	107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20
        +DB	133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217
        +DB	189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60
        +DB	93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143
        +DB	16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144
        +DB	244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7
        +DB	203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221
        +DB	62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211
        +DB	5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45
        +DB	103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120
        +DB	228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151
        +DB	39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2
        +DB	65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115
        +DB	139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167
        +DB	167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246
        +DB	125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178
        +DB	149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73
        +DB	216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86
        +DB	251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112
        +DB	238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205
        +DB	124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187
        +DB	102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113
        +DB	221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123
        +DB	23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175
        +DB	71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69
        +DB	158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26
        +DB	202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212
        +DB	45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88
        +DB	191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46
        +DB	7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63
        +DB	173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172
        +DB	90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176
        +DB	131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239
        +DB	51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182
        +DB	99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92
        +DB	2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18
        +DB	170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147
        +DB	113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222
        +DB	200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198
        +DB	25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209
        +DB	73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59
        +DB	217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95
        +DB	242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49
        +DB	227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168
        +DB	91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185
        +DB	136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188
        +DB	154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62
        +DB	38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11
        +DB	50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191
        +DB	176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89
        +DB	233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242
        +DB	15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119
        +DB	213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51
        +DB	128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244
        +DB	190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39
        +DB	205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235
        +DB	52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137
        +DB	72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50
        +DB	255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84
        +DB	122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141
        +DB	144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100
        +DB	95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157
        +DB	32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61
        +DB	104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15
        +DB	26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202
        +DB	174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183
        +DB	180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125
        +DB	84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206
        +DB	147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127
        +DB	34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47
        +DB	100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99
        +DB	241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42
        +DB	115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204
        +DB	18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130
        +DB	64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122
        +DB	8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72
        +DB	195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149
        +DB	236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223
        +DB	219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77
        +DB	161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192
        +DB	141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145
        +DB	61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200
        +DB	151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91
        +DB	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        +DB	207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249
        +DB	43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110
        +DB	118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225
        +DB	130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230
        +DB	214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40
        +DB	27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195
        +DB	181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116
        +DB	175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190
        +DB	106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29
        +DB	80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234
        +DB	69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87
        +DB	243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56
        +DB	48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173
        +DB	239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196
        +DB	63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218
        +DB	85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199
        +DB	162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219
        +DB	234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233
        +DB	101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106
        +DB	186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3
        +DB	47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74
        +DB	192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142
        +DB	222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96
        +DB	28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252
        +DB	253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70
        +DB	77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31
        +DB	146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118
        +DB	117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250
        +DB	6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54
        +DB	138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174
        +DB	178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75
        +DB	230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133
        +DB	14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126
        +DB	31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231
        +DB	98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85
        +DB	212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58
        +DB	168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129
        +DB	150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82
        +DB	249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98
        +DB	197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163
        +DB	37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16
        +DB	89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171
        +DB	132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208
        +DB	114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197
        +DB	57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236
        +DB	76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22
        +DB	94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148
        +DB	120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159
        +DB	56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229
        +DB	140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152
        +DB	209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23
        +DB	165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228
        +DB	226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161
        +DB	97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78
        +DB	179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66
        +DB	33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52
        +DB	156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8
        +DB	30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238
        +DB	67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97
        +DB	199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177
        +DB	252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79
        +DB	4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36
        +DB	81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227
        +DB	153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37
        +DB	109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34
        +DB	13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101
        +DB	250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121
        +DB	223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105
        +DB	126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169
        +DB	36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25
        +DB	59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254
        +DB	171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154
        +DB	206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240
        +DB	17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153
        +DB	143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131
        +DB	78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4
        +DB	183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102
        +DB	235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224
        +DB	60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193
        +DB	129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253
        +DB	148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64
        +DB	247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28
        +DB	185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24
        +DB	19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139
        +DB	44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81
        +DB	211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5
        +DB	231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140
        +DB	110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57
        +DB	196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170
        +DB	3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27
        +DB	86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220
        +DB	68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94
        +DB	127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160
        +DB	169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136
        +DB	42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103
        +DB	187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10
        +DB	193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135
        +DB	83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241
        +DB	220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114
        +DB	11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83
        +DB	157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1
        +DB	108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43
        +DB	49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164
        +DB	116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243
        +DB	246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21
        +DB	70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76
        +DB	172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165
        +DB	137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181
        +DB	20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180
        +DB	225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186
        +DB	22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166
        +DB	58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247
        +DB	105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6
        +DB	9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65
        +DB	112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215
        +DB	182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111
        +DB	208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30
        +DB	237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214
        +DB	204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226
        +DB	66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104
        +DB	152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44
        +DB	164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237
        +DB	40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117
        +DB	92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134
        +DB	248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107
        +DB	134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194
        +DB	24,35,198,232,135,184,1,79
        +DB	54,166,210,245,121,111,145,82
        +DB	96,188,155,142,163,12,123,53
        +DB	29,224,215,194,46,75,254,87
        +DB	21,119,55,229,159,240,74,218
        +DB	88,201,41,10,177,160,107,133
        +DB	189,93,16,244,203,62,5,103
        +DB	228,39,65,139,167,125,149,216
        +DB	251,238,124,102,221,23,71,158
        +DB	202,45,191,7,173,90,131,51
        +EXTERN	__imp_RtlVirtualUnwind:NEAR
        +
        +ALIGN	16
        +se_handler	PROC PRIVATE
        +	push	rsi
        +	push	rdi
        +	push	rbx
        +	push	rbp
        +	push	r12
        +	push	r13
        +	push	r14
        +	push	r15
        +	pushfq
        +	sub	rsp,64
        +
        +	mov	rax,QWORD PTR[120+r8]
        +	mov	rbx,QWORD PTR[248+r8]
        +
        +	lea	r10,QWORD PTR[$L$prologue]
        +	cmp	rbx,r10
        +	jb	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[152+r8]
        +
        +	lea	r10,QWORD PTR[$L$epilogue]
        +	cmp	rbx,r10
        +	jae	$L$in_prologue
        +
        +	mov	rax,QWORD PTR[((128+32))+rax]
        +	lea	rax,QWORD PTR[48+rax]
        +
        +	mov	rbx,QWORD PTR[((-8))+rax]
        +	mov	rbp,QWORD PTR[((-16))+rax]
        +	mov	r12,QWORD PTR[((-24))+rax]
        +	mov	r13,QWORD PTR[((-32))+rax]
        +	mov	r14,QWORD PTR[((-40))+rax]
        +	mov	r15,QWORD PTR[((-48))+rax]
        +	mov	QWORD PTR[144+r8],rbx
        +	mov	QWORD PTR[160+r8],rbp
        +	mov	QWORD PTR[216+r8],r12
        +	mov	QWORD PTR[224+r8],r13
        +	mov	QWORD PTR[232+r8],r14
        +	mov	QWORD PTR[240+r8],r15
        +
        +$L$in_prologue::
        +	mov	rdi,QWORD PTR[8+rax]
        +	mov	rsi,QWORD PTR[16+rax]
        +	mov	QWORD PTR[152+r8],rax
        +	mov	QWORD PTR[168+r8],rsi
        +	mov	QWORD PTR[176+r8],rdi
        +
        +	mov	rdi,QWORD PTR[40+r9]
        +	mov	rsi,r8
        +	mov	ecx,154
        +	DD	0a548f3fch
        +
        +
        +	mov	rsi,r9
        +	xor	rcx,rcx
        +	mov	rdx,QWORD PTR[8+rsi]
        +	mov	r8,QWORD PTR[rsi]
        +	mov	r9,QWORD PTR[16+rsi]
        +	mov	r10,QWORD PTR[40+rsi]
        +	lea	r11,QWORD PTR[56+rsi]
        +	lea	r12,QWORD PTR[24+rsi]
        +	mov	QWORD PTR[32+rsp],r10
        +	mov	QWORD PTR[40+rsp],r11
        +	mov	QWORD PTR[48+rsp],r12
        +	mov	QWORD PTR[56+rsp],rcx
        +	call	QWORD PTR[__imp_RtlVirtualUnwind]
        +
        +	mov	eax,1
        +	add	rsp,64
        +	popfq
        +	pop	r15
        +	pop	r14
        +	pop	r13
        +	pop	r12
        +	pop	rbp
        +	pop	rbx
        +	pop	rdi
        +	pop	rsi
        +	DB	0F3h,0C3h		;repret
        +se_handler	ENDP
        +
        +.text$	ENDS
        +.pdata	SEGMENT READONLY ALIGN(4)
        +ALIGN	4
        +	DD	imagerel $L$SEH_begin_whirlpool_block
        +	DD	imagerel $L$SEH_end_whirlpool_block
        +	DD	imagerel $L$SEH_info_whirlpool_block
        +
        +.pdata	ENDS
        +.xdata	SEGMENT READONLY ALIGN(8)
        +ALIGN	8
        +$L$SEH_info_whirlpool_block::
        +DB	9,0,0,0
        +	DD	imagerel se_handler
        +
        +.xdata	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/x86_64cpuid.asm b/vendor/openssl/asm/x64-win32-masm/x86_64cpuid.asm
        new file mode 100644
        index 000000000..497160cbc
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/x86_64cpuid.asm
        @@ -0,0 +1,232 @@
        +OPTION	DOTNAME
        +EXTERN	OPENSSL_cpuid_setup:NEAR
        +
        +.CRT$XCU	SEGMENT READONLY ALIGN(8)
        +		DQ	OPENSSL_cpuid_setup
        +
        +
        +.CRT$XCU	ENDS
        +_DATA	SEGMENT
        +COMM	OPENSSL_ia32cap_P:DWORD:2
        +
        +_DATA	ENDS
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +PUBLIC	OPENSSL_atomic_add
        +
        +ALIGN	16
        +OPENSSL_atomic_add	PROC PUBLIC
        +	mov	eax,DWORD PTR[rcx]
        +$L$spin::	lea	r8,QWORD PTR[rax*1+rdx]
        +DB	0f0h
        +
        +	cmpxchg	DWORD PTR[rcx],r8d
        +	jne	$L$spin
        +	mov	eax,r8d
        +DB	048h,098h
        +
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_atomic_add	ENDP
        +
        +PUBLIC	OPENSSL_rdtsc
        +
        +ALIGN	16
        +OPENSSL_rdtsc	PROC PUBLIC
        +	rdtsc
        +	shl	rdx,32
        +	or	rax,rdx
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_rdtsc	ENDP
        +
        +PUBLIC	OPENSSL_ia32_cpuid
        +
        +ALIGN	16
        +OPENSSL_ia32_cpuid	PROC PUBLIC
        +	mov	r8,rbx
        +
        +	xor	eax,eax
        +	cpuid
        +	mov	r11d,eax
        +
        +	xor	eax,eax
        +	cmp	ebx,0756e6547h
        +	setne	al
        +	mov	r9d,eax
        +	cmp	edx,049656e69h
        +	setne	al
        +	or	r9d,eax
        +	cmp	ecx,06c65746eh
        +	setne	al
        +	or	r9d,eax
        +	jz	$L$intel
        +
        +	cmp	ebx,068747541h
        +	setne	al
        +	mov	r10d,eax
        +	cmp	edx,069746E65h
        +	setne	al
        +	or	r10d,eax
        +	cmp	ecx,0444D4163h
        +	setne	al
        +	or	r10d,eax
        +	jnz	$L$intel
        +
        +
        +	mov	eax,080000000h
        +	cpuid
        +	cmp	eax,080000001h
        +	jb	$L$intel
        +	mov	r10d,eax
        +	mov	eax,080000001h
        +	cpuid
        +	or	r9d,ecx
        +	and	r9d,000000801h
        +
        +	cmp	r10d,080000008h
        +	jb	$L$intel
        +
        +	mov	eax,080000008h
        +	cpuid
        +	movzx	r10,cl
        +	inc	r10
        +
        +	mov	eax,1
        +	cpuid
        +	bt	edx,28
        +	jnc	$L$generic
        +	shr	ebx,16
        +	cmp	bl,r10b
        +	ja	$L$generic
        +	and	edx,0efffffffh
        +	jmp	$L$generic
        +
        +$L$intel::
        +	cmp	r11d,4
        +	mov	r10d,-1
        +	jb	$L$nocacheinfo
        +
        +	mov	eax,4
        +	mov	ecx,0
        +	cpuid
        +	mov	r10d,eax
        +	shr	r10d,14
        +	and	r10d,0fffh
        +
        +$L$nocacheinfo::
        +	mov	eax,1
        +	cpuid
        +	and	edx,0bfefffffh
        +	cmp	r9d,0
        +	jne	$L$notintel
        +	or	edx,040000000h
        +	and	ah,15
        +	cmp	ah,15
        +	jne	$L$notintel
        +	or	edx,000100000h
        +$L$notintel::
        +	bt	edx,28
        +	jnc	$L$generic
        +	and	edx,0efffffffh
        +	cmp	r10d,0
        +	je	$L$generic
        +
        +	or	edx,010000000h
        +	shr	ebx,16
        +	cmp	bl,1
        +	ja	$L$generic
        +	and	edx,0efffffffh
        +$L$generic::
        +	and	r9d,000000800h
        +	and	ecx,0fffff7ffh
        +	or	r9d,ecx
        +
        +	mov	r10d,edx
        +	bt	r9d,27
        +	jnc	$L$clear_avx
        +	xor	ecx,ecx
        +DB	00fh,001h,0d0h
        +
        +	and	eax,6
        +	cmp	eax,6
        +	je	$L$done
        +$L$clear_avx::
        +	mov	eax,0efffe7ffh
        +	and	r9d,eax
        +$L$done::
        +	shl	r9,32
        +	mov	eax,r10d
        +	mov	rbx,r8
        +	or	rax,r9
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_ia32_cpuid	ENDP
        +
        +PUBLIC	OPENSSL_cleanse
        +
        +ALIGN	16
        +OPENSSL_cleanse	PROC PUBLIC
        +	xor	rax,rax
        +	cmp	rdx,15
        +	jae	$L$ot
        +	cmp	rdx,0
        +	je	$L$ret
        +$L$ittle::
        +	mov	BYTE PTR[rcx],al
        +	sub	rdx,1
        +	lea	rcx,QWORD PTR[1+rcx]
        +	jnz	$L$ittle
        +$L$ret::
        +	DB	0F3h,0C3h		;repret
        +ALIGN	16
        +$L$ot::
        +	test	rcx,7
        +	jz	$L$aligned
        +	mov	BYTE PTR[rcx],al
        +	lea	rdx,QWORD PTR[((-1))+rdx]
        +	lea	rcx,QWORD PTR[1+rcx]
        +	jmp	$L$ot
        +$L$aligned::
        +	mov	QWORD PTR[rcx],rax
        +	lea	rdx,QWORD PTR[((-8))+rdx]
        +	test	rdx,-8
        +	lea	rcx,QWORD PTR[8+rcx]
        +	jnz	$L$aligned
        +	cmp	rdx,0
        +	jne	$L$ittle
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_cleanse	ENDP
        +PUBLIC	OPENSSL_wipe_cpu
        +
        +ALIGN	16
        +OPENSSL_wipe_cpu	PROC PUBLIC
        +	pxor	xmm0,xmm0
        +	pxor	xmm1,xmm1
        +	pxor	xmm2,xmm2
        +	pxor	xmm3,xmm3
        +	pxor	xmm4,xmm4
        +	pxor	xmm5,xmm5
        +	xor	rcx,rcx
        +	xor	rdx,rdx
        +	xor	r8,r8
        +	xor	r9,r9
        +	xor	r10,r10
        +	xor	r11,r11
        +	lea	rax,QWORD PTR[8+rsp]
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_wipe_cpu	ENDP
        +PUBLIC	OPENSSL_ia32_rdrand
        +
        +ALIGN	16
        +OPENSSL_ia32_rdrand	PROC PUBLIC
        +	mov	ecx,8
        +$L$oop_rdrand::
        +DB	72,15,199,240
        +	jc	$L$break_rdrand
        +	loop	$L$oop_rdrand
        +$L$break_rdrand::
        +	cmp	rax,0
        +	cmove	rax,rcx
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_ia32_rdrand	ENDP
        +
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig b/vendor/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig
        new file mode 100644
        index 000000000..cf970738b
        --- /dev/null
        +++ b/vendor/openssl/asm/x64-win32-masm/x86_64cpuid.asm.orig
        @@ -0,0 +1,235 @@
        +OPTION	DOTNAME
        +EXTERN	OPENSSL_cpuid_setup:NEAR
        +<<<<<<< HEAD
        +=======
        +
        +>>>>>>> openssl: regenerate asm files for openssl 1.0.1
        +.CRT$XCU	SEGMENT READONLY ALIGN(8)
        +		DQ	OPENSSL_cpuid_setup
        +
        +
        +.CRT$XCU	ENDS
        +_DATA	SEGMENT
        +COMM	OPENSSL_ia32cap_P:DWORD:2
        +
        +_DATA	ENDS
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +
        +PUBLIC	OPENSSL_atomic_add
        +
        +ALIGN	16
        +OPENSSL_atomic_add	PROC PUBLIC
        +	mov	eax,DWORD PTR[rcx]
        +$L$spin::	lea	r8,QWORD PTR[rax*1+rdx]
        +DB	0f0h
        +
        +	cmpxchg	DWORD PTR[rcx],r8d
        +	jne	$L$spin
        +	mov	eax,r8d
        +DB	048h,098h
        +
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_atomic_add	ENDP
        +
        +PUBLIC	OPENSSL_rdtsc
        +
        +ALIGN	16
        +OPENSSL_rdtsc	PROC PUBLIC
        +	rdtsc
        +	shl	rdx,32
        +	or	rax,rdx
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_rdtsc	ENDP
        +
        +PUBLIC	OPENSSL_ia32_cpuid
        +
        +ALIGN	16
        +OPENSSL_ia32_cpuid	PROC PUBLIC
        +	mov	r8,rbx
        +
        +	xor	eax,eax
        +	cpuid
        +	mov	r11d,eax
        +
        +	xor	eax,eax
        +	cmp	ebx,0756e6547h
        +	setne	al
        +	mov	r9d,eax
        +	cmp	edx,049656e69h
        +	setne	al
        +	or	r9d,eax
        +	cmp	ecx,06c65746eh
        +	setne	al
        +	or	r9d,eax
        +	jz	$L$intel
        +
        +	cmp	ebx,068747541h
        +	setne	al
        +	mov	r10d,eax
        +	cmp	edx,069746E65h
        +	setne	al
        +	or	r10d,eax
        +	cmp	ecx,0444D4163h
        +	setne	al
        +	or	r10d,eax
        +	jnz	$L$intel
        +
        +
        +	mov	eax,080000000h
        +	cpuid
        +	cmp	eax,080000001h
        +	jb	$L$intel
        +	mov	r10d,eax
        +	mov	eax,080000001h
        +	cpuid
        +	or	r9d,ecx
        +	and	r9d,000000801h
        +
        +	cmp	r10d,080000008h
        +	jb	$L$intel
        +
        +	mov	eax,080000008h
        +	cpuid
        +	movzx	r10,cl
        +	inc	r10
        +
        +	mov	eax,1
        +	cpuid
        +	bt	edx,28
        +	jnc	$L$generic
        +	shr	ebx,16
        +	cmp	bl,r10b
        +	ja	$L$generic
        +	and	edx,0efffffffh
        +	jmp	$L$generic
        +
        +$L$intel::
        +	cmp	r11d,4
        +	mov	r10d,-1
        +	jb	$L$nocacheinfo
        +
        +	mov	eax,4
        +	mov	ecx,0
        +	cpuid
        +	mov	r10d,eax
        +	shr	r10d,14
        +	and	r10d,0fffh
        +
        +$L$nocacheinfo::
        +	mov	eax,1
        +	cpuid
        +	and	edx,0bfefffffh
        +	cmp	r9d,0
        +	jne	$L$notintel
        +	or	edx,040000000h
        +	and	ah,15
        +	cmp	ah,15
        +	jne	$L$notintel
        +	or	edx,000100000h
        +$L$notintel::
        +	bt	edx,28
        +	jnc	$L$generic
        +	and	edx,0efffffffh
        +	cmp	r10d,0
        +	je	$L$generic
        +
        +	or	edx,010000000h
        +	shr	ebx,16
        +	cmp	bl,1
        +	ja	$L$generic
        +	and	edx,0efffffffh
        +$L$generic::
        +	and	r9d,000000800h
        +	and	ecx,0fffff7ffh
        +	or	r9d,ecx
        +
        +	mov	r10d,edx
        +	bt	r9d,27
        +	jnc	$L$clear_avx
        +	xor	ecx,ecx
        +DB	00fh,001h,0d0h
        +
        +	and	eax,6
        +	cmp	eax,6
        +	je	$L$done
        +$L$clear_avx::
        +	mov	eax,0efffe7ffh
        +	and	r9d,eax
        +$L$done::
        +	shl	r9,32
        +	mov	eax,r10d
        +	mov	rbx,r8
        +	or	rax,r9
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_ia32_cpuid	ENDP
        +
        +PUBLIC	OPENSSL_cleanse
        +
        +ALIGN	16
        +OPENSSL_cleanse	PROC PUBLIC
        +	xor	rax,rax
        +	cmp	rdx,15
        +	jae	$L$ot
        +	cmp	rdx,0
        +	je	$L$ret
        +$L$ittle::
        +	mov	BYTE PTR[rcx],al
        +	sub	rdx,1
        +	lea	rcx,QWORD PTR[1+rcx]
        +	jnz	$L$ittle
        +$L$ret::
        +	DB	0F3h,0C3h		;repret
        +ALIGN	16
        +$L$ot::
        +	test	rcx,7
        +	jz	$L$aligned
        +	mov	BYTE PTR[rcx],al
        +	lea	rdx,QWORD PTR[((-1))+rdx]
        +	lea	rcx,QWORD PTR[1+rcx]
        +	jmp	$L$ot
        +$L$aligned::
        +	mov	QWORD PTR[rcx],rax
        +	lea	rdx,QWORD PTR[((-8))+rdx]
        +	test	rdx,-8
        +	lea	rcx,QWORD PTR[8+rcx]
        +	jnz	$L$aligned
        +	cmp	rdx,0
        +	jne	$L$ittle
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_cleanse	ENDP
        +PUBLIC	OPENSSL_wipe_cpu
        +
        +ALIGN	16
        +OPENSSL_wipe_cpu	PROC PUBLIC
        +	pxor	xmm0,xmm0
        +	pxor	xmm1,xmm1
        +	pxor	xmm2,xmm2
        +	pxor	xmm3,xmm3
        +	pxor	xmm4,xmm4
        +	pxor	xmm5,xmm5
        +	xor	rcx,rcx
        +	xor	rdx,rdx
        +	xor	r8,r8
        +	xor	r9,r9
        +	xor	r10,r10
        +	xor	r11,r11
        +	lea	rax,QWORD PTR[8+rsp]
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_wipe_cpu	ENDP
        +PUBLIC	OPENSSL_ia32_rdrand
        +
        +ALIGN	16
        +OPENSSL_ia32_rdrand	PROC PUBLIC
        +	mov	ecx,8
        +$L$oop_rdrand::
        +DB	72,15,199,240
        +	jc	$L$break_rdrand
        +	loop	$L$oop_rdrand
        +$L$break_rdrand::
        +	cmp	rax,0
        +	cmove	rax,rcx
        +	DB	0F3h,0C3h		;repret
        +OPENSSL_ia32_rdrand	ENDP
        +
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-elf-gas/aes/aes-586.s b/vendor/openssl/asm/x86-elf-gas/aes/aes-586.s
        new file mode 100644
        index 000000000..f586d3df6
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/aes/aes-586.s
        @@ -0,0 +1,3234 @@
        +.file	"aes-586.s"
        +.text
        +.type	_x86_AES_encrypt_compact,@function
        +.align	16
        +_x86_AES_encrypt_compact:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	-128(%ebp),%edi
        +	movl	-96(%ebp),%esi
        +	movl	-64(%ebp),%edi
        +	movl	-32(%ebp),%esi
        +	movl	(%ebp),%edi
        +	movl	32(%ebp),%esi
        +	movl	64(%ebp),%edi
        +	movl	96(%ebp),%esi
        +.align	16
        +.L000loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ch,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ah,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$8,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$24,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +
        +	movl	%ecx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%ecx,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%ecx
        +	roll	$24,%ecx
        +	xorl	%esi,%ecx
        +	rorl	$16,%ebp
        +	xorl	%ebp,%ecx
        +	rorl	$8,%ebp
        +	xorl	%ebp,%ecx
        +	movl	%edx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%edx,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%edx
        +	roll	$24,%edx
        +	xorl	%esi,%edx
        +	rorl	$16,%ebp
        +	xorl	%ebp,%edx
        +	rorl	$8,%ebp
        +	xorl	%ebp,%edx
        +	movl	%eax,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%eax,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%eax
        +	roll	$24,%eax
        +	xorl	%esi,%eax
        +	rorl	$16,%ebp
        +	xorl	%ebp,%eax
        +	rorl	$8,%ebp
        +	xorl	%ebp,%eax
        +	movl	%ebx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%ebx,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%ebx
        +	roll	$24,%ebx
        +	xorl	%esi,%ebx
        +	rorl	$16,%ebp
        +	xorl	%ebp,%ebx
        +	rorl	$8,%ebp
        +	xorl	%ebp,%ebx
        +	movl	20(%esp),%edi
        +	movl	28(%esp),%ebp
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	.L000loop
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ch,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ah,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$8,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$24,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +
        +	xorl	16(%edi),%eax
        +	xorl	20(%edi),%ebx
        +	xorl	24(%edi),%ecx
        +	xorl	28(%edi),%edx
        +	ret
        +.size	_x86_AES_encrypt_compact,.-_x86_AES_encrypt_compact
        +.type	_sse_AES_encrypt_compact,@function
        +.align	16
        +_sse_AES_encrypt_compact:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	$454761243,%eax
        +	movl	%eax,8(%esp)
        +	movl	%eax,12(%esp)
        +	movl	-128(%ebp),%eax
        +	movl	-96(%ebp),%ebx
        +	movl	-64(%ebp),%ecx
        +	movl	-32(%ebp),%edx
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +.align	16
        +.L001loop:
        +	pshufw	$8,%mm0,%mm1
        +	pshufw	$13,%mm4,%mm5
        +	movd	%mm1,%eax
        +	movd	%mm5,%ebx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	pshufw	$13,%mm0,%mm2
        +	movzbl	%ah,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	shll	$8,%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	pshufw	$8,%mm4,%mm6
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%edx
        +	shrl	$16,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm0
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	movd	%mm2,%eax
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	movd	%mm6,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm1
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	shrl	$16,%eax
        +	punpckldq	%mm1,%mm0
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	andl	$255,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$16,%eax
        +	orl	%eax,%edx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm4
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	orl	%ebx,%edx
        +	movd	%edx,%mm5
        +	punpckldq	%mm5,%mm4
        +	addl	$16,%edi
        +	cmpl	24(%esp),%edi
        +	ja	.L002out
        +	movq	8(%esp),%mm2
        +	pxor	%mm3,%mm3
        +	pxor	%mm7,%mm7
        +	movq	%mm0,%mm1
        +	movq	%mm4,%mm5
        +	pcmpgtb	%mm0,%mm3
        +	pcmpgtb	%mm4,%mm7
        +	pand	%mm2,%mm3
        +	pand	%mm2,%mm7
        +	pshufw	$177,%mm0,%mm2
        +	pshufw	$177,%mm4,%mm6
        +	paddb	%mm0,%mm0
        +	paddb	%mm4,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pshufw	$177,%mm2,%mm3
        +	pshufw	$177,%mm6,%mm7
        +	pxor	%mm0,%mm1
        +	pxor	%mm4,%mm5
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	movq	%mm3,%mm2
        +	movq	%mm7,%mm6
        +	pslld	$8,%mm3
        +	pslld	$8,%mm7
        +	psrld	$24,%mm2
        +	psrld	$24,%mm6
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	movq	%mm1,%mm3
        +	movq	%mm5,%mm7
        +	movq	(%edi),%mm2
        +	movq	8(%edi),%mm6
        +	psrld	$8,%mm1
        +	psrld	$8,%mm5
        +	movl	-128(%ebp),%eax
        +	pslld	$24,%mm3
        +	pslld	$24,%mm7
        +	movl	-64(%ebp),%ebx
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	movl	(%ebp),%ecx
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	movl	64(%ebp),%edx
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	jmp	.L001loop
        +.align	16
        +.L002out:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	ret
        +.size	_sse_AES_encrypt_compact,.-_sse_AES_encrypt_compact
        +.type	_x86_AES_encrypt,@function
        +.align	16
        +_x86_AES_encrypt:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +.align	16
        +.L003loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%bh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,4(%esp)
        +
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%ch,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,8(%esp)
        +
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%dh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movzbl	%bh,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +
        +	movl	20(%esp),%edi
        +	movl	(%ebp,%edx,8),%edx
        +	movzbl	%ah,%eax
        +	xorl	3(%ebp,%eax,8),%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	xorl	2(%ebp,%ebx,8),%edx
        +	movl	8(%esp),%ebx
        +	xorl	1(%ebp,%ecx,8),%edx
        +	movl	%esi,%ecx
        +
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	.L003loop
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movl	2(%ebp,%esi,8),%esi
        +	andl	$255,%esi
        +	movzbl	%bh,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$65280,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$16711680,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movl	2(%ebp,%edi,8),%edi
        +	andl	$4278190080,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movl	2(%ebp,%esi,8),%esi
        +	andl	$255,%esi
        +	movzbl	%ch,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$65280,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$16711680,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	movl	2(%ebp,%edi,8),%edi
        +	andl	$4278190080,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movl	2(%ebp,%esi,8),%esi
        +	andl	$255,%esi
        +	movzbl	%dh,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$65280,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$16711680,%edi
        +	xorl	%edi,%esi
        +	movzbl	%bh,%edi
        +	movl	2(%ebp,%edi,8),%edi
        +	andl	$4278190080,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movl	2(%ebp,%edx,8),%edx
        +	andl	$255,%edx
        +	movzbl	%ah,%eax
        +	movl	(%ebp,%eax,8),%eax
        +	andl	$65280,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	movl	(%ebp,%ebx,8),%ebx
        +	andl	$16711680,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	movl	2(%ebp,%ecx,8),%ecx
        +	andl	$4278190080,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	ret
        +.align	64
        +.LAES_Te:
        +.long	2774754246,2774754246
        +.long	2222750968,2222750968
        +.long	2574743534,2574743534
        +.long	2373680118,2373680118
        +.long	234025727,234025727
        +.long	3177933782,3177933782
        +.long	2976870366,2976870366
        +.long	1422247313,1422247313
        +.long	1345335392,1345335392
        +.long	50397442,50397442
        +.long	2842126286,2842126286
        +.long	2099981142,2099981142
        +.long	436141799,436141799
        +.long	1658312629,1658312629
        +.long	3870010189,3870010189
        +.long	2591454956,2591454956
        +.long	1170918031,1170918031
        +.long	2642575903,2642575903
        +.long	1086966153,1086966153
        +.long	2273148410,2273148410
        +.long	368769775,368769775
        +.long	3948501426,3948501426
        +.long	3376891790,3376891790
        +.long	200339707,200339707
        +.long	3970805057,3970805057
        +.long	1742001331,1742001331
        +.long	4255294047,4255294047
        +.long	3937382213,3937382213
        +.long	3214711843,3214711843
        +.long	4154762323,4154762323
        +.long	2524082916,2524082916
        +.long	1539358875,1539358875
        +.long	3266819957,3266819957
        +.long	486407649,486407649
        +.long	2928907069,2928907069
        +.long	1780885068,1780885068
        +.long	1513502316,1513502316
        +.long	1094664062,1094664062
        +.long	49805301,49805301
        +.long	1338821763,1338821763
        +.long	1546925160,1546925160
        +.long	4104496465,4104496465
        +.long	887481809,887481809
        +.long	150073849,150073849
        +.long	2473685474,2473685474
        +.long	1943591083,1943591083
        +.long	1395732834,1395732834
        +.long	1058346282,1058346282
        +.long	201589768,201589768
        +.long	1388824469,1388824469
        +.long	1696801606,1696801606
        +.long	1589887901,1589887901
        +.long	672667696,672667696
        +.long	2711000631,2711000631
        +.long	251987210,251987210
        +.long	3046808111,3046808111
        +.long	151455502,151455502
        +.long	907153956,907153956
        +.long	2608889883,2608889883
        +.long	1038279391,1038279391
        +.long	652995533,652995533
        +.long	1764173646,1764173646
        +.long	3451040383,3451040383
        +.long	2675275242,2675275242
        +.long	453576978,453576978
        +.long	2659418909,2659418909
        +.long	1949051992,1949051992
        +.long	773462580,773462580
        +.long	756751158,756751158
        +.long	2993581788,2993581788
        +.long	3998898868,3998898868
        +.long	4221608027,4221608027
        +.long	4132590244,4132590244
        +.long	1295727478,1295727478
        +.long	1641469623,1641469623
        +.long	3467883389,3467883389
        +.long	2066295122,2066295122
        +.long	1055122397,1055122397
        +.long	1898917726,1898917726
        +.long	2542044179,2542044179
        +.long	4115878822,4115878822
        +.long	1758581177,1758581177
        +.long	0,0
        +.long	753790401,753790401
        +.long	1612718144,1612718144
        +.long	536673507,536673507
        +.long	3367088505,3367088505
        +.long	3982187446,3982187446
        +.long	3194645204,3194645204
        +.long	1187761037,1187761037
        +.long	3653156455,3653156455
        +.long	1262041458,1262041458
        +.long	3729410708,3729410708
        +.long	3561770136,3561770136
        +.long	3898103984,3898103984
        +.long	1255133061,1255133061
        +.long	1808847035,1808847035
        +.long	720367557,720367557
        +.long	3853167183,3853167183
        +.long	385612781,385612781
        +.long	3309519750,3309519750
        +.long	3612167578,3612167578
        +.long	1429418854,1429418854
        +.long	2491778321,2491778321
        +.long	3477423498,3477423498
        +.long	284817897,284817897
        +.long	100794884,100794884
        +.long	2172616702,2172616702
        +.long	4031795360,4031795360
        +.long	1144798328,1144798328
        +.long	3131023141,3131023141
        +.long	3819481163,3819481163
        +.long	4082192802,4082192802
        +.long	4272137053,4272137053
        +.long	3225436288,3225436288
        +.long	2324664069,2324664069
        +.long	2912064063,2912064063
        +.long	3164445985,3164445985
        +.long	1211644016,1211644016
        +.long	83228145,83228145
        +.long	3753688163,3753688163
        +.long	3249976951,3249976951
        +.long	1977277103,1977277103
        +.long	1663115586,1663115586
        +.long	806359072,806359072
        +.long	452984805,452984805
        +.long	250868733,250868733
        +.long	1842533055,1842533055
        +.long	1288555905,1288555905
        +.long	336333848,336333848
        +.long	890442534,890442534
        +.long	804056259,804056259
        +.long	3781124030,3781124030
        +.long	2727843637,2727843637
        +.long	3427026056,3427026056
        +.long	957814574,957814574
        +.long	1472513171,1472513171
        +.long	4071073621,4071073621
        +.long	2189328124,2189328124
        +.long	1195195770,1195195770
        +.long	2892260552,2892260552
        +.long	3881655738,3881655738
        +.long	723065138,723065138
        +.long	2507371494,2507371494
        +.long	2690670784,2690670784
        +.long	2558624025,2558624025
        +.long	3511635870,3511635870
        +.long	2145180835,2145180835
        +.long	1713513028,1713513028
        +.long	2116692564,2116692564
        +.long	2878378043,2878378043
        +.long	2206763019,2206763019
        +.long	3393603212,3393603212
        +.long	703524551,703524551
        +.long	3552098411,3552098411
        +.long	1007948840,1007948840
        +.long	2044649127,2044649127
        +.long	3797835452,3797835452
        +.long	487262998,487262998
        +.long	1994120109,1994120109
        +.long	1004593371,1004593371
        +.long	1446130276,1446130276
        +.long	1312438900,1312438900
        +.long	503974420,503974420
        +.long	3679013266,3679013266
        +.long	168166924,168166924
        +.long	1814307912,1814307912
        +.long	3831258296,3831258296
        +.long	1573044895,1573044895
        +.long	1859376061,1859376061
        +.long	4021070915,4021070915
        +.long	2791465668,2791465668
        +.long	2828112185,2828112185
        +.long	2761266481,2761266481
        +.long	937747667,937747667
        +.long	2339994098,2339994098
        +.long	854058965,854058965
        +.long	1137232011,1137232011
        +.long	1496790894,1496790894
        +.long	3077402074,3077402074
        +.long	2358086913,2358086913
        +.long	1691735473,1691735473
        +.long	3528347292,3528347292
        +.long	3769215305,3769215305
        +.long	3027004632,3027004632
        +.long	4199962284,4199962284
        +.long	133494003,133494003
        +.long	636152527,636152527
        +.long	2942657994,2942657994
        +.long	2390391540,2390391540
        +.long	3920539207,3920539207
        +.long	403179536,403179536
        +.long	3585784431,3585784431
        +.long	2289596656,2289596656
        +.long	1864705354,1864705354
        +.long	1915629148,1915629148
        +.long	605822008,605822008
        +.long	4054230615,4054230615
        +.long	3350508659,3350508659
        +.long	1371981463,1371981463
        +.long	602466507,602466507
        +.long	2094914977,2094914977
        +.long	2624877800,2624877800
        +.long	555687742,555687742
        +.long	3712699286,3712699286
        +.long	3703422305,3703422305
        +.long	2257292045,2257292045
        +.long	2240449039,2240449039
        +.long	2423288032,2423288032
        +.long	1111375484,1111375484
        +.long	3300242801,3300242801
        +.long	2858837708,2858837708
        +.long	3628615824,3628615824
        +.long	84083462,84083462
        +.long	32962295,32962295
        +.long	302911004,302911004
        +.long	2741068226,2741068226
        +.long	1597322602,1597322602
        +.long	4183250862,4183250862
        +.long	3501832553,3501832553
        +.long	2441512471,2441512471
        +.long	1489093017,1489093017
        +.long	656219450,656219450
        +.long	3114180135,3114180135
        +.long	954327513,954327513
        +.long	335083755,335083755
        +.long	3013122091,3013122091
        +.long	856756514,856756514
        +.long	3144247762,3144247762
        +.long	1893325225,1893325225
        +.long	2307821063,2307821063
        +.long	2811532339,2811532339
        +.long	3063651117,3063651117
        +.long	572399164,572399164
        +.long	2458355477,2458355477
        +.long	552200649,552200649
        +.long	1238290055,1238290055
        +.long	4283782570,4283782570
        +.long	2015897680,2015897680
        +.long	2061492133,2061492133
        +.long	2408352771,2408352771
        +.long	4171342169,4171342169
        +.long	2156497161,2156497161
        +.long	386731290,386731290
        +.long	3669999461,3669999461
        +.long	837215959,837215959
        +.long	3326231172,3326231172
        +.long	3093850320,3093850320
        +.long	3275833730,3275833730
        +.long	2962856233,2962856233
        +.long	1999449434,1999449434
        +.long	286199582,286199582
        +.long	3417354363,3417354363
        +.long	4233385128,4233385128
        +.long	3602627437,3602627437
        +.long	974525996,974525996
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.long	1,2,4,8
        +.long	16,32,64,128
        +.long	27,54,0,0
        +.long	0,0,0,0
        +.size	_x86_AES_encrypt,.-_x86_AES_encrypt
        +.globl	AES_encrypt
        +.type	AES_encrypt,@function
        +.align	16
        +AES_encrypt:
        +.L_AES_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%eax
        +	subl	$36,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ebx
        +	subl	%esp,%ebx
        +	negl	%ebx
        +	andl	$960,%ebx
        +	subl	%ebx,%esp
        +	addl	$4,%esp
        +	movl	%eax,28(%esp)
        +	call	.L004pic_point
        +.L004pic_point:
        +	popl	%ebp
        +	leal	OPENSSL_ia32cap_P,%eax
        +	leal	.LAES_Te-.L004pic_point(%ebp),%ebp
        +	leal	764(%esp),%ebx
        +	subl	%ebp,%ebx
        +	andl	$768,%ebx
        +	leal	2176(%ebp,%ebx,1),%ebp
        +	btl	$25,(%eax)
        +	jnc	.L005x86
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm4
        +	call	_sse_AES_encrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movq	%mm0,(%esi)
        +	movq	%mm4,8(%esi)
        +	emms
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	16
        +.L005x86:
        +	movl	%ebp,24(%esp)
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	call	_x86_AES_encrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	AES_encrypt,.-.L_AES_encrypt_begin
        +.type	_x86_AES_decrypt_compact,@function
        +.align	16
        +_x86_AES_decrypt_compact:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	-128(%ebp),%edi
        +	movl	-96(%ebp),%esi
        +	movl	-64(%ebp),%edi
        +	movl	-32(%ebp),%esi
        +	movl	(%ebp),%edi
        +	movl	32(%ebp),%esi
        +	movl	64(%ebp),%edi
        +	movl	96(%ebp),%esi
        +.align	16
        +.L006loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ah,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ch,%ecx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$8,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	shrl	$24,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	xorl	%eax,%edx
        +	movl	%ecx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%eax
        +	subl	%edi,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	xorl	%eax,%esi
        +	movl	%esi,%eax
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%eax,%eax,1),%ebx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%eax
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ebx,%ebx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%ecx,%ebx
        +	roll	$8,%ecx
        +	xorl	%esi,%ebp
        +	xorl	%eax,%ecx
        +	xorl	%ebp,%eax
        +	roll	$24,%eax
        +	xorl	%ebx,%ecx
        +	xorl	%ebp,%ebx
        +	roll	$16,%ebx
        +	xorl	%ebp,%ecx
        +	roll	$8,%ebp
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%ecx
        +	movl	4(%esp),%eax
        +	xorl	%ebp,%ecx
        +	movl	%ecx,12(%esp)
        +	movl	%edx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%edx,%edx,1),%ebx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%edx,%ebx
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%edx,%ecx
        +	roll	$8,%edx
        +	xorl	%esi,%ebp
        +	xorl	%ebx,%edx
        +	xorl	%ebp,%ebx
        +	roll	$24,%ebx
        +	xorl	%ecx,%edx
        +	xorl	%ebp,%ecx
        +	roll	$16,%ecx
        +	xorl	%ebp,%edx
        +	roll	$8,%ebp
        +	xorl	%ebx,%edx
        +	xorl	%ecx,%edx
        +	movl	8(%esp),%ebx
        +	xorl	%ebp,%edx
        +	movl	%edx,16(%esp)
        +	movl	%eax,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%eax,%eax,1),%ecx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%edi,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%eax,%ecx
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%edx,%edx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%eax,%edx
        +	roll	$8,%eax
        +	xorl	%esi,%ebp
        +	xorl	%ecx,%eax
        +	xorl	%ebp,%ecx
        +	roll	$24,%ecx
        +	xorl	%edx,%eax
        +	xorl	%ebp,%edx
        +	roll	$16,%edx
        +	xorl	%ebp,%eax
        +	roll	$8,%ebp
        +	xorl	%ecx,%eax
        +	xorl	%edx,%eax
        +	xorl	%ebp,%eax
        +	movl	%ebx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%edi,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%ecx
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%edx,%edx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%ebx,%edx
        +	roll	$8,%ebx
        +	xorl	%esi,%ebp
        +	xorl	%ecx,%ebx
        +	xorl	%ebp,%ecx
        +	roll	$24,%ecx
        +	xorl	%edx,%ebx
        +	xorl	%ebp,%edx
        +	roll	$16,%edx
        +	xorl	%ebp,%ebx
        +	roll	$8,%ebp
        +	xorl	%ecx,%ebx
        +	xorl	%edx,%ebx
        +	movl	12(%esp),%ecx
        +	xorl	%ebp,%ebx
        +	movl	16(%esp),%edx
        +	movl	20(%esp),%edi
        +	movl	28(%esp),%ebp
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	.L006loop
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ah,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ch,%ecx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$8,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	shrl	$24,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	xorl	16(%edi),%eax
        +	xorl	20(%edi),%ebx
        +	xorl	24(%edi),%ecx
        +	xorl	28(%edi),%edx
        +	ret
        +.size	_x86_AES_decrypt_compact,.-_x86_AES_decrypt_compact
        +.type	_sse_AES_decrypt_compact,@function
        +.align	16
        +_sse_AES_decrypt_compact:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	$454761243,%eax
        +	movl	%eax,8(%esp)
        +	movl	%eax,12(%esp)
        +	movl	-128(%ebp),%eax
        +	movl	-96(%ebp),%ebx
        +	movl	-64(%ebp),%ecx
        +	movl	-32(%ebp),%edx
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +.align	16
        +.L007loop:
        +	pshufw	$12,%mm0,%mm1
        +	movd	%mm1,%eax
        +	pshufw	$9,%mm4,%mm5
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	movd	%mm5,%ebx
        +	movzbl	%ah,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	shll	$8,%edx
        +	pshufw	$6,%mm0,%mm2
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	shrl	$16,%eax
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%edx
        +	shrl	$16,%ebx
        +	pshufw	$3,%mm4,%mm6
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm0
        +	movzbl	%al,%esi
        +	movd	%mm2,%eax
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	shll	$16,%ecx
        +	movzbl	%bl,%esi
        +	movd	%mm6,%ebx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	orl	%esi,%ecx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	orl	%esi,%edx
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%edx
        +	movd	%edx,%mm1
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%edx
        +	shll	$8,%edx
        +	movzbl	%bh,%esi
        +	shrl	$16,%eax
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%edx
        +	shrl	$16,%ebx
        +	punpckldq	%mm1,%mm0
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	orl	%ebx,%edx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%edx
        +	movd	%edx,%mm4
        +	movzbl	%ah,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	orl	%eax,%ecx
        +	movd	%ecx,%mm5
        +	punpckldq	%mm5,%mm4
        +	addl	$16,%edi
        +	cmpl	24(%esp),%edi
        +	ja	.L008out
        +	movq	%mm0,%mm3
        +	movq	%mm4,%mm7
        +	pshufw	$228,%mm0,%mm2
        +	pshufw	$228,%mm4,%mm6
        +	movq	%mm0,%mm1
        +	movq	%mm4,%mm5
        +	pshufw	$177,%mm0,%mm0
        +	pshufw	$177,%mm4,%mm4
        +	pslld	$8,%mm2
        +	pslld	$8,%mm6
        +	psrld	$8,%mm3
        +	psrld	$8,%mm7
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pslld	$16,%mm2
        +	pslld	$16,%mm6
        +	psrld	$16,%mm3
        +	psrld	$16,%mm7
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	movq	8(%esp),%mm3
        +	pxor	%mm2,%mm2
        +	pxor	%mm6,%mm6
        +	pcmpgtb	%mm1,%mm2
        +	pcmpgtb	%mm5,%mm6
        +	pand	%mm3,%mm2
        +	pand	%mm3,%mm6
        +	paddb	%mm1,%mm1
        +	paddb	%mm5,%mm5
        +	pxor	%mm2,%mm1
        +	pxor	%mm6,%mm5
        +	movq	%mm1,%mm3
        +	movq	%mm5,%mm7
        +	movq	%mm1,%mm2
        +	movq	%mm5,%mm6
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	pslld	$24,%mm3
        +	pslld	$24,%mm7
        +	psrld	$8,%mm2
        +	psrld	$8,%mm6
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	movq	8(%esp),%mm2
        +	pxor	%mm3,%mm3
        +	pxor	%mm7,%mm7
        +	pcmpgtb	%mm1,%mm3
        +	pcmpgtb	%mm5,%mm7
        +	pand	%mm2,%mm3
        +	pand	%mm2,%mm7
        +	paddb	%mm1,%mm1
        +	paddb	%mm5,%mm5
        +	pxor	%mm3,%mm1
        +	pxor	%mm7,%mm5
        +	pshufw	$177,%mm1,%mm3
        +	pshufw	$177,%mm5,%mm7
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm3,%mm3
        +	pxor	%mm7,%mm7
        +	pcmpgtb	%mm1,%mm3
        +	pcmpgtb	%mm5,%mm7
        +	pand	%mm2,%mm3
        +	pand	%mm2,%mm7
        +	paddb	%mm1,%mm1
        +	paddb	%mm5,%mm5
        +	pxor	%mm3,%mm1
        +	pxor	%mm7,%mm5
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	movq	%mm1,%mm3
        +	movq	%mm5,%mm7
        +	pshufw	$177,%mm1,%mm2
        +	pshufw	$177,%mm5,%mm6
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	pslld	$8,%mm1
        +	pslld	$8,%mm5
        +	psrld	$8,%mm3
        +	psrld	$8,%mm7
        +	movq	(%edi),%mm2
        +	movq	8(%edi),%mm6
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	movl	-128(%ebp),%eax
        +	pslld	$16,%mm1
        +	pslld	$16,%mm5
        +	movl	-64(%ebp),%ebx
        +	psrld	$16,%mm3
        +	psrld	$16,%mm7
        +	movl	(%ebp),%ecx
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	movl	64(%ebp),%edx
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	jmp	.L007loop
        +.align	16
        +.L008out:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	ret
        +.size	_sse_AES_decrypt_compact,.-_sse_AES_decrypt_compact
        +.type	_x86_AES_decrypt,@function
        +.align	16
        +_x86_AES_decrypt:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +.align	16
        +.L009loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%dh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,4(%esp)
        +
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%ah,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,8(%esp)
        +
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%bh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movl	(%ebp,%edx,8),%edx
        +	movzbl	%ch,%ecx
        +	xorl	3(%ebp,%ecx,8),%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	xorl	2(%ebp,%ebx,8),%edx
        +	movl	8(%esp),%ebx
        +	shrl	$24,%eax
        +	xorl	1(%ebp,%eax,8),%edx
        +	movl	4(%esp),%eax
        +
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	.L009loop
        +	leal	2176(%ebp),%ebp
        +	movl	-128(%ebp),%edi
        +	movl	-96(%ebp),%esi
        +	movl	-64(%ebp),%edi
        +	movl	-32(%ebp),%esi
        +	movl	(%ebp),%edi
        +	movl	32(%ebp),%esi
        +	movl	64(%ebp),%edi
        +	movl	96(%ebp),%esi
        +	leal	-128(%ebp),%ebp
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movzbl	(%ebp,%esi,1),%esi
        +	movzbl	%ah,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movzbl	(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movzbl	(%ebp,%edx,1),%edx
        +	movzbl	%ch,%ecx
        +	movzbl	(%ebp,%ecx,1),%ecx
        +	shll	$8,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	movzbl	(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	shrl	$24,%eax
        +	movzbl	(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	leal	-2048(%ebp),%ebp
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	ret
        +.align	64
        +.LAES_Td:
        +.long	1353184337,1353184337
        +.long	1399144830,1399144830
        +.long	3282310938,3282310938
        +.long	2522752826,2522752826
        +.long	3412831035,3412831035
        +.long	4047871263,4047871263
        +.long	2874735276,2874735276
        +.long	2466505547,2466505547
        +.long	1442459680,1442459680
        +.long	4134368941,4134368941
        +.long	2440481928,2440481928
        +.long	625738485,625738485
        +.long	4242007375,4242007375
        +.long	3620416197,3620416197
        +.long	2151953702,2151953702
        +.long	2409849525,2409849525
        +.long	1230680542,1230680542
        +.long	1729870373,1729870373
        +.long	2551114309,2551114309
        +.long	3787521629,3787521629
        +.long	41234371,41234371
        +.long	317738113,317738113
        +.long	2744600205,2744600205
        +.long	3338261355,3338261355
        +.long	3881799427,3881799427
        +.long	2510066197,2510066197
        +.long	3950669247,3950669247
        +.long	3663286933,3663286933
        +.long	763608788,763608788
        +.long	3542185048,3542185048
        +.long	694804553,694804553
        +.long	1154009486,1154009486
        +.long	1787413109,1787413109
        +.long	2021232372,2021232372
        +.long	1799248025,1799248025
        +.long	3715217703,3715217703
        +.long	3058688446,3058688446
        +.long	397248752,397248752
        +.long	1722556617,1722556617
        +.long	3023752829,3023752829
        +.long	407560035,407560035
        +.long	2184256229,2184256229
        +.long	1613975959,1613975959
        +.long	1165972322,1165972322
        +.long	3765920945,3765920945
        +.long	2226023355,2226023355
        +.long	480281086,480281086
        +.long	2485848313,2485848313
        +.long	1483229296,1483229296
        +.long	436028815,436028815
        +.long	2272059028,2272059028
        +.long	3086515026,3086515026
        +.long	601060267,601060267
        +.long	3791801202,3791801202
        +.long	1468997603,1468997603
        +.long	715871590,715871590
        +.long	120122290,120122290
        +.long	63092015,63092015
        +.long	2591802758,2591802758
        +.long	2768779219,2768779219
        +.long	4068943920,4068943920
        +.long	2997206819,2997206819
        +.long	3127509762,3127509762
        +.long	1552029421,1552029421
        +.long	723308426,723308426
        +.long	2461301159,2461301159
        +.long	4042393587,4042393587
        +.long	2715969870,2715969870
        +.long	3455375973,3455375973
        +.long	3586000134,3586000134
        +.long	526529745,526529745
        +.long	2331944644,2331944644
        +.long	2639474228,2639474228
        +.long	2689987490,2689987490
        +.long	853641733,853641733
        +.long	1978398372,1978398372
        +.long	971801355,971801355
        +.long	2867814464,2867814464
        +.long	111112542,111112542
        +.long	1360031421,1360031421
        +.long	4186579262,4186579262
        +.long	1023860118,1023860118
        +.long	2919579357,2919579357
        +.long	1186850381,1186850381
        +.long	3045938321,3045938321
        +.long	90031217,90031217
        +.long	1876166148,1876166148
        +.long	4279586912,4279586912
        +.long	620468249,620468249
        +.long	2548678102,2548678102
        +.long	3426959497,3426959497
        +.long	2006899047,2006899047
        +.long	3175278768,3175278768
        +.long	2290845959,2290845959
        +.long	945494503,945494503
        +.long	3689859193,3689859193
        +.long	1191869601,1191869601
        +.long	3910091388,3910091388
        +.long	3374220536,3374220536
        +.long	0,0
        +.long	2206629897,2206629897
        +.long	1223502642,1223502642
        +.long	2893025566,2893025566
        +.long	1316117100,1316117100
        +.long	4227796733,4227796733
        +.long	1446544655,1446544655
        +.long	517320253,517320253
        +.long	658058550,658058550
        +.long	1691946762,1691946762
        +.long	564550760,564550760
        +.long	3511966619,3511966619
        +.long	976107044,976107044
        +.long	2976320012,2976320012
        +.long	266819475,266819475
        +.long	3533106868,3533106868
        +.long	2660342555,2660342555
        +.long	1338359936,1338359936
        +.long	2720062561,2720062561
        +.long	1766553434,1766553434
        +.long	370807324,370807324
        +.long	179999714,179999714
        +.long	3844776128,3844776128
        +.long	1138762300,1138762300
        +.long	488053522,488053522
        +.long	185403662,185403662
        +.long	2915535858,2915535858
        +.long	3114841645,3114841645
        +.long	3366526484,3366526484
        +.long	2233069911,2233069911
        +.long	1275557295,1275557295
        +.long	3151862254,3151862254
        +.long	4250959779,4250959779
        +.long	2670068215,2670068215
        +.long	3170202204,3170202204
        +.long	3309004356,3309004356
        +.long	880737115,880737115
        +.long	1982415755,1982415755
        +.long	3703972811,3703972811
        +.long	1761406390,1761406390
        +.long	1676797112,1676797112
        +.long	3403428311,3403428311
        +.long	277177154,277177154
        +.long	1076008723,1076008723
        +.long	538035844,538035844
        +.long	2099530373,2099530373
        +.long	4164795346,4164795346
        +.long	288553390,288553390
        +.long	1839278535,1839278535
        +.long	1261411869,1261411869
        +.long	4080055004,4080055004
        +.long	3964831245,3964831245
        +.long	3504587127,3504587127
        +.long	1813426987,1813426987
        +.long	2579067049,2579067049
        +.long	4199060497,4199060497
        +.long	577038663,577038663
        +.long	3297574056,3297574056
        +.long	440397984,440397984
        +.long	3626794326,3626794326
        +.long	4019204898,4019204898
        +.long	3343796615,3343796615
        +.long	3251714265,3251714265
        +.long	4272081548,4272081548
        +.long	906744984,906744984
        +.long	3481400742,3481400742
        +.long	685669029,685669029
        +.long	646887386,646887386
        +.long	2764025151,2764025151
        +.long	3835509292,3835509292
        +.long	227702864,227702864
        +.long	2613862250,2613862250
        +.long	1648787028,1648787028
        +.long	3256061430,3256061430
        +.long	3904428176,3904428176
        +.long	1593260334,1593260334
        +.long	4121936770,4121936770
        +.long	3196083615,3196083615
        +.long	2090061929,2090061929
        +.long	2838353263,2838353263
        +.long	3004310991,3004310991
        +.long	999926984,999926984
        +.long	2809993232,2809993232
        +.long	1852021992,1852021992
        +.long	2075868123,2075868123
        +.long	158869197,158869197
        +.long	4095236462,4095236462
        +.long	28809964,28809964
        +.long	2828685187,2828685187
        +.long	1701746150,1701746150
        +.long	2129067946,2129067946
        +.long	147831841,147831841
        +.long	3873969647,3873969647
        +.long	3650873274,3650873274
        +.long	3459673930,3459673930
        +.long	3557400554,3557400554
        +.long	3598495785,3598495785
        +.long	2947720241,2947720241
        +.long	824393514,824393514
        +.long	815048134,815048134
        +.long	3227951669,3227951669
        +.long	935087732,935087732
        +.long	2798289660,2798289660
        +.long	2966458592,2966458592
        +.long	366520115,366520115
        +.long	1251476721,1251476721
        +.long	4158319681,4158319681
        +.long	240176511,240176511
        +.long	804688151,804688151
        +.long	2379631990,2379631990
        +.long	1303441219,1303441219
        +.long	1414376140,1414376140
        +.long	3741619940,3741619940
        +.long	3820343710,3820343710
        +.long	461924940,461924940
        +.long	3089050817,3089050817
        +.long	2136040774,2136040774
        +.long	82468509,82468509
        +.long	1563790337,1563790337
        +.long	1937016826,1937016826
        +.long	776014843,776014843
        +.long	1511876531,1511876531
        +.long	1389550482,1389550482
        +.long	861278441,861278441
        +.long	323475053,323475053
        +.long	2355222426,2355222426
        +.long	2047648055,2047648055
        +.long	2383738969,2383738969
        +.long	2302415851,2302415851
        +.long	3995576782,3995576782
        +.long	902390199,902390199
        +.long	3991215329,3991215329
        +.long	1018251130,1018251130
        +.long	1507840668,1507840668
        +.long	1064563285,1064563285
        +.long	2043548696,2043548696
        +.long	3208103795,3208103795
        +.long	3939366739,3939366739
        +.long	1537932639,1537932639
        +.long	342834655,342834655
        +.long	2262516856,2262516856
        +.long	2180231114,2180231114
        +.long	1053059257,1053059257
        +.long	741614648,741614648
        +.long	1598071746,1598071746
        +.long	1925389590,1925389590
        +.long	203809468,203809468
        +.long	2336832552,2336832552
        +.long	1100287487,1100287487
        +.long	1895934009,1895934009
        +.long	3736275976,3736275976
        +.long	2632234200,2632234200
        +.long	2428589668,2428589668
        +.long	1636092795,1636092795
        +.long	1890988757,1890988757
        +.long	1952214088,1952214088
        +.long	1113045200,1113045200
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.size	_x86_AES_decrypt,.-_x86_AES_decrypt
        +.globl	AES_decrypt
        +.type	AES_decrypt,@function
        +.align	16
        +AES_decrypt:
        +.L_AES_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%eax
        +	subl	$36,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ebx
        +	subl	%esp,%ebx
        +	negl	%ebx
        +	andl	$960,%ebx
        +	subl	%ebx,%esp
        +	addl	$4,%esp
        +	movl	%eax,28(%esp)
        +	call	.L010pic_point
        +.L010pic_point:
        +	popl	%ebp
        +	leal	OPENSSL_ia32cap_P,%eax
        +	leal	.LAES_Td-.L010pic_point(%ebp),%ebp
        +	leal	764(%esp),%ebx
        +	subl	%ebp,%ebx
        +	andl	$768,%ebx
        +	leal	2176(%ebp,%ebx,1),%ebp
        +	btl	$25,(%eax)
        +	jnc	.L011x86
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm4
        +	call	_sse_AES_decrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movq	%mm0,(%esi)
        +	movq	%mm4,8(%esi)
        +	emms
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	16
        +.L011x86:
        +	movl	%ebp,24(%esp)
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	call	_x86_AES_decrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	AES_decrypt,.-.L_AES_decrypt_begin
        +.globl	AES_cbc_encrypt
        +.type	AES_cbc_encrypt,@function
        +.align	16
        +AES_cbc_encrypt:
        +.L_AES_cbc_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ecx
        +	cmpl	$0,%ecx
        +	je	.L012drop_out
        +	call	.L013pic_point
        +.L013pic_point:
        +	popl	%ebp
        +	leal	OPENSSL_ia32cap_P,%eax
        +	cmpl	$0,40(%esp)
        +	leal	.LAES_Te-.L013pic_point(%ebp),%ebp
        +	jne	.L014picked_te
        +	leal	.LAES_Td-.LAES_Te(%ebp),%ebp
        +.L014picked_te:
        +	pushfl
        +	cld
        +	cmpl	$512,%ecx
        +	jb	.L015slow_way
        +	testl	$15,%ecx
        +	jnz	.L015slow_way
        +	leal	-324(%esp),%esi
        +	andl	$-64,%esi
        +	movl	%ebp,%eax
        +	leal	2304(%ebp),%ebx
        +	movl	%esi,%edx
        +	andl	$4095,%eax
        +	andl	$4095,%ebx
        +	andl	$4095,%edx
        +	cmpl	%ebx,%edx
        +	jb	.L016tbl_break_out
        +	subl	%ebx,%edx
        +	subl	%edx,%esi
        +	jmp	.L017tbl_ok
        +.align	4
        +.L016tbl_break_out:
        +	subl	%eax,%edx
        +	andl	$4095,%edx
        +	addl	$384,%edx
        +	subl	%edx,%esi
        +.align	4
        +.L017tbl_ok:
        +	leal	24(%esp),%edx
        +	xchgl	%esi,%esp
        +	addl	$4,%esp
        +	movl	%ebp,24(%esp)
        +	movl	%esi,28(%esp)
        +	movl	(%edx),%eax
        +	movl	4(%edx),%ebx
        +	movl	12(%edx),%edi
        +	movl	16(%edx),%esi
        +	movl	20(%edx),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,40(%esp)
        +	movl	%edi,44(%esp)
        +	movl	%esi,48(%esp)
        +	movl	$0,316(%esp)
        +	movl	%edi,%ebx
        +	movl	$61,%ecx
        +	subl	%ebp,%ebx
        +	movl	%edi,%esi
        +	andl	$4095,%ebx
        +	leal	76(%esp),%edi
        +	cmpl	$2304,%ebx
        +	jb	.L018do_copy
        +	cmpl	$3852,%ebx
        +	jb	.L019skip_copy
        +.align	4
        +.L018do_copy:
        +	movl	%edi,44(%esp)
        +.long	2784229001
        +.L019skip_copy:
        +	movl	$16,%edi
        +.align	4
        +.L020prefetch_tbl:
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%esi
        +	leal	128(%ebp),%ebp
        +	subl	$1,%edi
        +	jnz	.L020prefetch_tbl
        +	subl	$2048,%ebp
        +	movl	32(%esp),%esi
        +	movl	48(%esp),%edi
        +	cmpl	$0,%edx
        +	je	.L021fast_decrypt
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +.align	16
        +.L022fast_enc_loop:
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	xorl	12(%esi),%edx
        +	movl	44(%esp),%edi
        +	call	_x86_AES_encrypt
        +	movl	32(%esp),%esi
        +	movl	36(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	leal	16(%esi),%esi
        +	movl	40(%esp),%ecx
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,36(%esp)
        +	subl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jnz	.L022fast_enc_loop
        +	movl	48(%esp),%esi
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	cmpl	$0,316(%esp)
        +	movl	44(%esp),%edi
        +	je	.L023skip_ezero
        +	movl	$60,%ecx
        +	xorl	%eax,%eax
        +.align	4
        +.long	2884892297
        +.L023skip_ezero:
        +	movl	28(%esp),%esp
        +	popfl
        +.L012drop_out:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L021fast_decrypt:
        +	cmpl	36(%esp),%esi
        +	je	.L024fast_dec_in_place
        +	movl	%edi,52(%esp)
        +.align	4
        +.align	16
        +.L025fast_dec_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	44(%esp),%edi
        +	call	_x86_AES_decrypt
        +	movl	52(%esp),%edi
        +	movl	40(%esp),%esi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	36(%esp),%edi
        +	movl	32(%esp),%esi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	40(%esp),%ecx
        +	movl	%esi,52(%esp)
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edi
        +	movl	%edi,36(%esp)
        +	subl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jnz	.L025fast_dec_loop
        +	movl	52(%esp),%edi
        +	movl	48(%esp),%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	jmp	.L026fast_dec_out
        +.align	16
        +.L024fast_dec_in_place:
        +.L027fast_dec_in_place_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	leal	60(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	44(%esp),%edi
        +	call	_x86_AES_decrypt
        +	movl	48(%esp),%edi
        +	movl	36(%esp),%esi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	leal	16(%esi),%esi
        +	movl	%esi,36(%esp)
        +	leal	60(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	32(%esp),%esi
        +	movl	40(%esp),%ecx
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	subl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jnz	.L027fast_dec_in_place_loop
        +.align	4
        +.L026fast_dec_out:
        +	cmpl	$0,316(%esp)
        +	movl	44(%esp),%edi
        +	je	.L028skip_dzero
        +	movl	$60,%ecx
        +	xorl	%eax,%eax
        +.align	4
        +.long	2884892297
        +.L028skip_dzero:
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L015slow_way:
        +	movl	(%eax),%eax
        +	movl	36(%esp),%edi
        +	leal	-80(%esp),%esi
        +	andl	$-64,%esi
        +	leal	-143(%edi),%ebx
        +	subl	%esi,%ebx
        +	negl	%ebx
        +	andl	$960,%ebx
        +	subl	%ebx,%esi
        +	leal	768(%esi),%ebx
        +	subl	%ebp,%ebx
        +	andl	$768,%ebx
        +	leal	2176(%ebp,%ebx,1),%ebp
        +	leal	24(%esp),%edx
        +	xchgl	%esi,%esp
        +	addl	$4,%esp
        +	movl	%ebp,24(%esp)
        +	movl	%esi,28(%esp)
        +	movl	%eax,52(%esp)
        +	movl	(%edx),%eax
        +	movl	4(%edx),%ebx
        +	movl	16(%edx),%esi
        +	movl	20(%edx),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,40(%esp)
        +	movl	%edi,44(%esp)
        +	movl	%esi,48(%esp)
        +	movl	%esi,%edi
        +	movl	%eax,%esi
        +	cmpl	$0,%edx
        +	je	.L029slow_decrypt
        +	cmpl	$16,%ecx
        +	movl	%ebx,%edx
        +	jb	.L030slow_enc_tail
        +	btl	$25,52(%esp)
        +	jnc	.L031slow_enc_x86
        +	movq	(%edi),%mm0
        +	movq	8(%edi),%mm4
        +.align	16
        +.L032slow_enc_loop_sse:
        +	pxor	(%esi),%mm0
        +	pxor	8(%esi),%mm4
        +	movl	44(%esp),%edi
        +	call	_sse_AES_encrypt_compact
        +	movl	32(%esp),%esi
        +	movl	36(%esp),%edi
        +	movl	40(%esp),%ecx
        +	movq	%mm0,(%edi)
        +	movq	%mm4,8(%edi)
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,36(%esp)
        +	subl	$16,%ecx
        +	cmpl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jae	.L032slow_enc_loop_sse
        +	testl	$15,%ecx
        +	jnz	.L030slow_enc_tail
        +	movl	48(%esp),%esi
        +	movq	%mm0,(%esi)
        +	movq	%mm4,8(%esi)
        +	emms
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L031slow_enc_x86:
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +.align	4
        +.L033slow_enc_loop_x86:
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	xorl	12(%esi),%edx
        +	movl	44(%esp),%edi
        +	call	_x86_AES_encrypt_compact
        +	movl	32(%esp),%esi
        +	movl	36(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	40(%esp),%ecx
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,36(%esp)
        +	subl	$16,%ecx
        +	cmpl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jae	.L033slow_enc_loop_x86
        +	testl	$15,%ecx
        +	jnz	.L030slow_enc_tail
        +	movl	48(%esp),%esi
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L030slow_enc_tail:
        +	emms
        +	movl	%edx,%edi
        +	movl	$16,%ebx
        +	subl	%ecx,%ebx
        +	cmpl	%esi,%edi
        +	je	.L034enc_in_place
        +.align	4
        +.long	2767451785
        +	jmp	.L035enc_skip_in_place
        +.L034enc_in_place:
        +	leal	(%edi,%ecx,1),%edi
        +.L035enc_skip_in_place:
        +	movl	%ebx,%ecx
        +	xorl	%eax,%eax
        +.align	4
        +.long	2868115081
        +	movl	48(%esp),%edi
        +	movl	%edx,%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	$16,40(%esp)
        +	jmp	.L033slow_enc_loop_x86
        +.align	16
        +.L029slow_decrypt:
        +	btl	$25,52(%esp)
        +	jnc	.L036slow_dec_loop_x86
        +.align	4
        +.L037slow_dec_loop_sse:
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm4
        +	movl	44(%esp),%edi
        +	call	_sse_AES_decrypt_compact
        +	movl	32(%esp),%esi
        +	leal	60(%esp),%eax
        +	movl	36(%esp),%ebx
        +	movl	40(%esp),%ecx
        +	movl	48(%esp),%edi
        +	movq	(%esi),%mm1
        +	movq	8(%esi),%mm5
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	movq	%mm1,(%edi)
        +	movq	%mm5,8(%edi)
        +	subl	$16,%ecx
        +	jc	.L038slow_dec_partial_sse
        +	movq	%mm0,(%ebx)
        +	movq	%mm4,8(%ebx)
        +	leal	16(%ebx),%ebx
        +	movl	%ebx,36(%esp)
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	movl	%ecx,40(%esp)
        +	jnz	.L037slow_dec_loop_sse
        +	emms
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L038slow_dec_partial_sse:
        +	movq	%mm0,(%eax)
        +	movq	%mm4,8(%eax)
        +	emms
        +	addl	$16,%ecx
        +	movl	%ebx,%edi
        +	movl	%eax,%esi
        +.align	4
        +.long	2767451785
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L036slow_dec_loop_x86:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	leal	60(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	44(%esp),%edi
        +	call	_x86_AES_decrypt_compact
        +	movl	48(%esp),%edi
        +	movl	40(%esp),%esi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	subl	$16,%esi
        +	jc	.L039slow_dec_partial_x86
        +	movl	%esi,40(%esp)
        +	movl	36(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	leal	16(%esi),%esi
        +	movl	%esi,36(%esp)
        +	leal	60(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	32(%esp),%esi
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	jnz	.L036slow_dec_loop_x86
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	16
        +.L039slow_dec_partial_x86:
        +	leal	60(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	32(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	40(%esp),%ecx
        +	movl	36(%esp),%edi
        +	leal	60(%esp),%esi
        +.align	4
        +.long	2767451785
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	AES_cbc_encrypt,.-.L_AES_cbc_encrypt_begin
        +.type	_x86_AES_set_encrypt_key,@function
        +.align	16
        +_x86_AES_set_encrypt_key:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	24(%esp),%esi
        +	movl	32(%esp),%edi
        +	testl	$-1,%esi
        +	jz	.L040badpointer
        +	testl	$-1,%edi
        +	jz	.L040badpointer
        +	call	.L041pic_point
        +.L041pic_point:
        +	popl	%ebp
        +	leal	.LAES_Te-.L041pic_point(%ebp),%ebp
        +	leal	2176(%ebp),%ebp
        +	movl	-128(%ebp),%eax
        +	movl	-96(%ebp),%ebx
        +	movl	-64(%ebp),%ecx
        +	movl	-32(%ebp),%edx
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +	movl	28(%esp),%ecx
        +	cmpl	$128,%ecx
        +	je	.L04210rounds
        +	cmpl	$192,%ecx
        +	je	.L04312rounds
        +	cmpl	$256,%ecx
        +	je	.L04414rounds
        +	movl	$-2,%eax
        +	jmp	.L045exit
        +.L04210rounds:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	xorl	%ecx,%ecx
        +	jmp	.L04610shortcut
        +.align	4
        +.L04710loop:
        +	movl	(%edi),%eax
        +	movl	12(%edi),%edx
        +.L04610shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	xorl	896(%ebp,%ecx,4),%eax
        +	movl	%eax,16(%edi)
        +	xorl	4(%edi),%eax
        +	movl	%eax,20(%edi)
        +	xorl	8(%edi),%eax
        +	movl	%eax,24(%edi)
        +	xorl	12(%edi),%eax
        +	movl	%eax,28(%edi)
        +	incl	%ecx
        +	addl	$16,%edi
        +	cmpl	$10,%ecx
        +	jl	.L04710loop
        +	movl	$10,80(%edi)
        +	xorl	%eax,%eax
        +	jmp	.L045exit
        +.L04312rounds:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	16(%esi),%ecx
        +	movl	20(%esi),%edx
        +	movl	%ecx,16(%edi)
        +	movl	%edx,20(%edi)
        +	xorl	%ecx,%ecx
        +	jmp	.L04812shortcut
        +.align	4
        +.L04912loop:
        +	movl	(%edi),%eax
        +	movl	20(%edi),%edx
        +.L04812shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	xorl	896(%ebp,%ecx,4),%eax
        +	movl	%eax,24(%edi)
        +	xorl	4(%edi),%eax
        +	movl	%eax,28(%edi)
        +	xorl	8(%edi),%eax
        +	movl	%eax,32(%edi)
        +	xorl	12(%edi),%eax
        +	movl	%eax,36(%edi)
        +	cmpl	$7,%ecx
        +	je	.L05012break
        +	incl	%ecx
        +	xorl	16(%edi),%eax
        +	movl	%eax,40(%edi)
        +	xorl	20(%edi),%eax
        +	movl	%eax,44(%edi)
        +	addl	$24,%edi
        +	jmp	.L04912loop
        +.L05012break:
        +	movl	$12,72(%edi)
        +	xorl	%eax,%eax
        +	jmp	.L045exit
        +.L04414rounds:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	movl	%eax,16(%edi)
        +	movl	%ebx,20(%edi)
        +	movl	%ecx,24(%edi)
        +	movl	%edx,28(%edi)
        +	xorl	%ecx,%ecx
        +	jmp	.L05114shortcut
        +.align	4
        +.L05214loop:
        +	movl	28(%edi),%edx
        +.L05114shortcut:
        +	movl	(%edi),%eax
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	xorl	896(%ebp,%ecx,4),%eax
        +	movl	%eax,32(%edi)
        +	xorl	4(%edi),%eax
        +	movl	%eax,36(%edi)
        +	xorl	8(%edi),%eax
        +	movl	%eax,40(%edi)
        +	xorl	12(%edi),%eax
        +	movl	%eax,44(%edi)
        +	cmpl	$6,%ecx
        +	je	.L05314break
        +	incl	%ecx
        +	movl	%eax,%edx
        +	movl	16(%edi),%eax
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	shll	$8,%ebx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movl	%eax,48(%edi)
        +	xorl	20(%edi),%eax
        +	movl	%eax,52(%edi)
        +	xorl	24(%edi),%eax
        +	movl	%eax,56(%edi)
        +	xorl	28(%edi),%eax
        +	movl	%eax,60(%edi)
        +	addl	$32,%edi
        +	jmp	.L05214loop
        +.L05314break:
        +	movl	$14,48(%edi)
        +	xorl	%eax,%eax
        +	jmp	.L045exit
        +.L040badpointer:
        +	movl	$-1,%eax
        +.L045exit:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	_x86_AES_set_encrypt_key,.-_x86_AES_set_encrypt_key
        +.globl	private_AES_set_encrypt_key
        +.type	private_AES_set_encrypt_key,@function
        +.align	16
        +private_AES_set_encrypt_key:
        +.L_private_AES_set_encrypt_key_begin:
        +	call	_x86_AES_set_encrypt_key
        +	ret
        +.size	private_AES_set_encrypt_key,.-.L_private_AES_set_encrypt_key_begin
        +.globl	private_AES_set_decrypt_key
        +.type	private_AES_set_decrypt_key,@function
        +.align	16
        +private_AES_set_decrypt_key:
        +.L_private_AES_set_decrypt_key_begin:
        +	call	_x86_AES_set_encrypt_key
        +	cmpl	$0,%eax
        +	je	.L054proceed
        +	ret
        +.L054proceed:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%esi
        +	movl	240(%esi),%ecx
        +	leal	(,%ecx,4),%ecx
        +	leal	(%esi,%ecx,4),%edi
        +.align	4
        +.L055invert:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	(%edi),%ecx
        +	movl	4(%edi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,(%esi)
        +	movl	%edx,4(%esi)
        +	movl	8(%esi),%eax
        +	movl	12(%esi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,8(%edi)
        +	movl	%ebx,12(%edi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	addl	$16,%esi
        +	subl	$16,%edi
        +	cmpl	%edi,%esi
        +	jne	.L055invert
        +	movl	28(%esp),%edi
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,28(%esp)
        +	movl	16(%edi),%eax
        +.align	4
        +.L056permute:
        +	addl	$16,%edi
        +	movl	%eax,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%ebx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%eax,%ebx
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edx
        +	xorl	%eax,%ecx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	roll	$8,%eax
        +	xorl	%esi,%edx
        +	movl	4(%edi),%ebp
        +	xorl	%ebx,%eax
        +	xorl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$24,%ebx
        +	xorl	%edx,%ecx
        +	xorl	%edx,%eax
        +	roll	$16,%ecx
        +	xorl	%ebx,%eax
        +	roll	$8,%edx
        +	xorl	%ecx,%eax
        +	movl	%ebp,%ebx
        +	xorl	%edx,%eax
        +	movl	%eax,(%edi)
        +	movl	%ebx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%ecx
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%eax
        +	xorl	%ebx,%edx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	roll	$8,%ebx
        +	xorl	%esi,%eax
        +	movl	8(%edi),%ebp
        +	xorl	%ecx,%ebx
        +	xorl	%eax,%ecx
        +	xorl	%edx,%ebx
        +	roll	$24,%ecx
        +	xorl	%eax,%edx
        +	xorl	%eax,%ebx
        +	roll	$16,%edx
        +	xorl	%ecx,%ebx
        +	roll	$8,%eax
        +	xorl	%edx,%ebx
        +	movl	%ebp,%ecx
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%eax
        +	subl	%ebp,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	xorl	%ecx,%edx
        +	xorl	%eax,%esi
        +	movl	%esi,%eax
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%ebx
        +	xorl	%ecx,%eax
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	roll	$8,%ecx
        +	xorl	%esi,%ebx
        +	movl	12(%edi),%ebp
        +	xorl	%edx,%ecx
        +	xorl	%ebx,%edx
        +	xorl	%eax,%ecx
        +	roll	$24,%edx
        +	xorl	%ebx,%eax
        +	xorl	%ebx,%ecx
        +	roll	$16,%eax
        +	xorl	%edx,%ecx
        +	roll	$8,%ebx
        +	xorl	%eax,%ecx
        +	movl	%ebp,%edx
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%edi)
        +	movl	%edx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%eax
        +	subl	%ebp,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	xorl	%eax,%esi
        +	movl	%esi,%eax
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%ebx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%edx,%eax
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%ecx
        +	xorl	%edx,%ebx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	roll	$8,%edx
        +	xorl	%esi,%ecx
        +	movl	16(%edi),%ebp
        +	xorl	%eax,%edx
        +	xorl	%ecx,%eax
        +	xorl	%ebx,%edx
        +	roll	$24,%eax
        +	xorl	%ecx,%ebx
        +	xorl	%ecx,%edx
        +	roll	$16,%ebx
        +	xorl	%eax,%edx
        +	roll	$8,%ecx
        +	xorl	%ebx,%edx
        +	movl	%ebp,%eax
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%edi)
        +	cmpl	28(%esp),%edi
        +	jb	.L056permute
        +	xorl	%eax,%eax
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	private_AES_set_decrypt_key,.-.L_private_AES_set_decrypt_key_begin
        +.byte	65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89
        +.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
        +.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.comm	OPENSSL_ia32cap_P,8,4
        diff --git a/vendor/openssl/asm/x86-elf-gas/aes/aesni-x86.s b/vendor/openssl/asm/x86-elf-gas/aes/aesni-x86.s
        new file mode 100644
        index 000000000..d9f268855
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/aes/aesni-x86.s
        @@ -0,0 +1,2143 @@
        +.file	"../openssl/crypto/aes/asm/aesni-x86.s"
        +.text
        +.globl	aesni_encrypt
        +.type	aesni_encrypt,@function
        +.align	16
        +aesni_encrypt:
        +.L_aesni_encrypt_begin:
        +	movl	4(%esp),%eax
        +	movl	12(%esp),%edx
        +	movups	(%eax),%xmm2
        +	movl	240(%edx),%ecx
        +	movl	8(%esp),%eax
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L000enc1_loop_1:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L000enc1_loop_1
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%eax)
        +	ret
        +.size	aesni_encrypt,.-.L_aesni_encrypt_begin
        +.globl	aesni_decrypt
        +.type	aesni_decrypt,@function
        +.align	16
        +aesni_decrypt:
        +.L_aesni_decrypt_begin:
        +	movl	4(%esp),%eax
        +	movl	12(%esp),%edx
        +	movups	(%eax),%xmm2
        +	movl	240(%edx),%ecx
        +	movl	8(%esp),%eax
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L001dec1_loop_2:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L001dec1_loop_2
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%eax)
        +	ret
        +.size	aesni_decrypt,.-.L_aesni_decrypt_begin
        +.type	_aesni_encrypt3,@function
        +.align	16
        +_aesni_encrypt3:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	movups	(%edx),%xmm0
        +.L002enc3_loop:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,224
        +	movups	(%edx),%xmm0
        +	jnz	.L002enc3_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +	ret
        +.size	_aesni_encrypt3,.-_aesni_encrypt3
        +.type	_aesni_decrypt3,@function
        +.align	16
        +_aesni_decrypt3:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	movups	(%edx),%xmm0
        +.L003dec3_loop:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,222,224
        +	movups	(%edx),%xmm0
        +	jnz	.L003dec3_loop
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +	ret
        +.size	_aesni_decrypt3,.-_aesni_decrypt3
        +.type	_aesni_encrypt4,@function
        +.align	16
        +_aesni_encrypt4:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	shrl	$1,%ecx
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm0,%xmm5
        +	movups	(%edx),%xmm0
        +.L004enc4_loop:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +	movups	(%edx),%xmm0
        +	jnz	.L004enc4_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +	ret
        +.size	_aesni_encrypt4,.-_aesni_encrypt4
        +.type	_aesni_decrypt4,@function
        +.align	16
        +_aesni_decrypt4:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	shrl	$1,%ecx
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm0,%xmm5
        +	movups	(%edx),%xmm0
        +.L005dec4_loop:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +	movups	(%edx),%xmm0
        +	jnz	.L005dec4_loop
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +	ret
        +.size	_aesni_decrypt4,.-_aesni_decrypt4
        +.type	_aesni_encrypt6,@function
        +.align	16
        +_aesni_encrypt6:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,220,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,220,249
        +	jmp	.L_aesni_encrypt6_enter
        +.align	16
        +.L006enc6_loop:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.align	16
        +.L_aesni_encrypt6_enter:
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%edx),%xmm0
        +	jnz	.L006enc6_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +	ret
        +.size	_aesni_encrypt6,.-_aesni_encrypt6
        +.type	_aesni_decrypt6,@function
        +.align	16
        +_aesni_decrypt6:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,222,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,222,249
        +	jmp	.L_aesni_decrypt6_enter
        +.align	16
        +.L007dec6_loop:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.align	16
        +.L_aesni_decrypt6_enter:
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	(%edx),%xmm0
        +	jnz	.L007dec6_loop
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +	ret
        +.size	_aesni_decrypt6,.-_aesni_decrypt6
        +.globl	aesni_ecb_encrypt
        +.type	aesni_ecb_encrypt,@function
        +.align	16
        +aesni_ecb_encrypt:
        +.L_aesni_ecb_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	andl	$-16,%eax
        +	jz	.L008ecb_ret
        +	movl	240(%edx),%ecx
        +	testl	%ebx,%ebx
        +	jz	.L009ecb_decrypt
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	cmpl	$96,%eax
        +	jb	.L010ecb_enc_tail
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	movdqu	48(%esi),%xmm5
        +	movdqu	64(%esi),%xmm6
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +	subl	$96,%eax
        +	jmp	.L011ecb_enc_loop6_enter
        +.align	16
        +.L012ecb_enc_loop6:
        +	movups	%xmm2,(%edi)
        +	movdqu	(%esi),%xmm2
        +	movups	%xmm3,16(%edi)
        +	movdqu	16(%esi),%xmm3
        +	movups	%xmm4,32(%edi)
        +	movdqu	32(%esi),%xmm4
        +	movups	%xmm5,48(%edi)
        +	movdqu	48(%esi),%xmm5
        +	movups	%xmm6,64(%edi)
        +	movdqu	64(%esi),%xmm6
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +.L011ecb_enc_loop6_enter:
        +	call	_aesni_encrypt6
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	subl	$96,%eax
        +	jnc	.L012ecb_enc_loop6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	addl	$96,%eax
        +	jz	.L008ecb_ret
        +.L010ecb_enc_tail:
        +	movups	(%esi),%xmm2
        +	cmpl	$32,%eax
        +	jb	.L013ecb_enc_one
        +	movups	16(%esi),%xmm3
        +	je	.L014ecb_enc_two
        +	movups	32(%esi),%xmm4
        +	cmpl	$64,%eax
        +	jb	.L015ecb_enc_three
        +	movups	48(%esi),%xmm5
        +	je	.L016ecb_enc_four
        +	movups	64(%esi),%xmm6
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_encrypt6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L013ecb_enc_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L017enc1_loop_3:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L017enc1_loop_3
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L014ecb_enc_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_encrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L015ecb_enc_three:
        +	call	_aesni_encrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L016ecb_enc_four:
        +	call	_aesni_encrypt4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L009ecb_decrypt:
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	cmpl	$96,%eax
        +	jb	.L018ecb_dec_tail
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	movdqu	48(%esi),%xmm5
        +	movdqu	64(%esi),%xmm6
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +	subl	$96,%eax
        +	jmp	.L019ecb_dec_loop6_enter
        +.align	16
        +.L020ecb_dec_loop6:
        +	movups	%xmm2,(%edi)
        +	movdqu	(%esi),%xmm2
        +	movups	%xmm3,16(%edi)
        +	movdqu	16(%esi),%xmm3
        +	movups	%xmm4,32(%edi)
        +	movdqu	32(%esi),%xmm4
        +	movups	%xmm5,48(%edi)
        +	movdqu	48(%esi),%xmm5
        +	movups	%xmm6,64(%edi)
        +	movdqu	64(%esi),%xmm6
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +.L019ecb_dec_loop6_enter:
        +	call	_aesni_decrypt6
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	subl	$96,%eax
        +	jnc	.L020ecb_dec_loop6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	addl	$96,%eax
        +	jz	.L008ecb_ret
        +.L018ecb_dec_tail:
        +	movups	(%esi),%xmm2
        +	cmpl	$32,%eax
        +	jb	.L021ecb_dec_one
        +	movups	16(%esi),%xmm3
        +	je	.L022ecb_dec_two
        +	movups	32(%esi),%xmm4
        +	cmpl	$64,%eax
        +	jb	.L023ecb_dec_three
        +	movups	48(%esi),%xmm5
        +	je	.L024ecb_dec_four
        +	movups	64(%esi),%xmm6
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_decrypt6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L021ecb_dec_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L025dec1_loop_4:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L025dec1_loop_4
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L022ecb_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_decrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L023ecb_dec_three:
        +	call	_aesni_decrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	jmp	.L008ecb_ret
        +.align	16
        +.L024ecb_dec_four:
        +	call	_aesni_decrypt4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +.L008ecb_ret:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_ecb_encrypt,.-.L_aesni_ecb_encrypt_begin
        +.globl	aesni_ccm64_encrypt_blocks
        +.type	aesni_ccm64_encrypt_blocks,@function
        +.align	16
        +aesni_ccm64_encrypt_blocks:
        +.L_aesni_ccm64_encrypt_blocks_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	movl	40(%esp),%ecx
        +	movl	%esp,%ebp
        +	subl	$60,%esp
        +	andl	$-16,%esp
        +	movl	%ebp,48(%esp)
        +	movdqu	(%ebx),%xmm7
        +	movdqu	(%ecx),%xmm3
        +	movl	240(%edx),%ecx
        +	movl	$202182159,(%esp)
        +	movl	$134810123,4(%esp)
        +	movl	$67438087,8(%esp)
        +	movl	$66051,12(%esp)
        +	movl	$1,%ebx
        +	xorl	%ebp,%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ebp,20(%esp)
        +	movl	%ebp,24(%esp)
        +	movl	%ebp,28(%esp)
        +	shrl	$1,%ecx
        +	leal	(%edx),%ebp
        +	movdqa	(%esp),%xmm5
        +	movdqa	%xmm7,%xmm2
        +	movl	%ecx,%ebx
        +.byte	102,15,56,0,253
        +.L026ccm64_enc_outer:
        +	movups	(%ebp),%xmm0
        +	movl	%ebx,%ecx
        +	movups	(%esi),%xmm6
        +	xorps	%xmm0,%xmm2
        +	movups	16(%ebp),%xmm1
        +	xorps	%xmm6,%xmm0
        +	leal	32(%ebp),%edx
        +	xorps	%xmm0,%xmm3
        +	movups	(%edx),%xmm0
        +.L027ccm64_enc2_loop:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +.byte	102,15,56,220,217
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,216
        +	movups	(%edx),%xmm0
        +	jnz	.L027ccm64_enc2_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	paddq	16(%esp),%xmm7
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +	decl	%eax
        +	leal	16(%esi),%esi
        +	xorps	%xmm2,%xmm6
        +	movdqa	%xmm7,%xmm2
        +	movups	%xmm6,(%edi)
        +	leal	16(%edi),%edi
        +.byte	102,15,56,0,213
        +	jnz	.L026ccm64_enc_outer
        +	movl	48(%esp),%esp
        +	movl	40(%esp),%edi
        +	movups	%xmm3,(%edi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_ccm64_encrypt_blocks,.-.L_aesni_ccm64_encrypt_blocks_begin
        +.globl	aesni_ccm64_decrypt_blocks
        +.type	aesni_ccm64_decrypt_blocks,@function
        +.align	16
        +aesni_ccm64_decrypt_blocks:
        +.L_aesni_ccm64_decrypt_blocks_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	movl	40(%esp),%ecx
        +	movl	%esp,%ebp
        +	subl	$60,%esp
        +	andl	$-16,%esp
        +	movl	%ebp,48(%esp)
        +	movdqu	(%ebx),%xmm7
        +	movdqu	(%ecx),%xmm3
        +	movl	240(%edx),%ecx
        +	movl	$202182159,(%esp)
        +	movl	$134810123,4(%esp)
        +	movl	$67438087,8(%esp)
        +	movl	$66051,12(%esp)
        +	movl	$1,%ebx
        +	xorl	%ebp,%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ebp,20(%esp)
        +	movl	%ebp,24(%esp)
        +	movl	%ebp,28(%esp)
        +	movdqa	(%esp),%xmm5
        +	movdqa	%xmm7,%xmm2
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +.byte	102,15,56,0,253
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L028enc1_loop_5:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L028enc1_loop_5
        +.byte	102,15,56,221,209
        +	movups	(%esi),%xmm6
        +	paddq	16(%esp),%xmm7
        +	leal	16(%esi),%esi
        +	jmp	.L029ccm64_dec_outer
        +.align	16
        +.L029ccm64_dec_outer:
        +	xorps	%xmm2,%xmm6
        +	movdqa	%xmm7,%xmm2
        +	movl	%ebx,%ecx
        +	movups	%xmm6,(%edi)
        +	leal	16(%edi),%edi
        +.byte	102,15,56,0,213
        +	subl	$1,%eax
        +	jz	.L030ccm64_dec_break
        +	movups	(%ebp),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%ebp),%xmm1
        +	xorps	%xmm0,%xmm6
        +	leal	32(%ebp),%edx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	(%edx),%xmm0
        +.L031ccm64_dec2_loop:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +.byte	102,15,56,220,217
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,216
        +	movups	(%edx),%xmm0
        +	jnz	.L031ccm64_dec2_loop
        +	movups	(%esi),%xmm6
        +	paddq	16(%esp),%xmm7
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	leal	16(%esi),%esi
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +	jmp	.L029ccm64_dec_outer
        +.align	16
        +.L030ccm64_dec_break:
        +	movl	%ebp,%edx
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	xorps	%xmm0,%xmm6
        +	leal	32(%edx),%edx
        +	xorps	%xmm6,%xmm3
        +.L032enc1_loop_6:
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L032enc1_loop_6
        +.byte	102,15,56,221,217
        +	movl	48(%esp),%esp
        +	movl	40(%esp),%edi
        +	movups	%xmm3,(%edi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_ccm64_decrypt_blocks,.-.L_aesni_ccm64_decrypt_blocks_begin
        +.globl	aesni_ctr32_encrypt_blocks
        +.type	aesni_ctr32_encrypt_blocks,@function
        +.align	16
        +aesni_ctr32_encrypt_blocks:
        +.L_aesni_ctr32_encrypt_blocks_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	movl	%esp,%ebp
        +	subl	$88,%esp
        +	andl	$-16,%esp
        +	movl	%ebp,80(%esp)
        +	cmpl	$1,%eax
        +	je	.L033ctr32_one_shortcut
        +	movdqu	(%ebx),%xmm7
        +	movl	$202182159,(%esp)
        +	movl	$134810123,4(%esp)
        +	movl	$67438087,8(%esp)
        +	movl	$66051,12(%esp)
        +	movl	$6,%ecx
        +	xorl	%ebp,%ebp
        +	movl	%ecx,16(%esp)
        +	movl	%ecx,20(%esp)
        +	movl	%ecx,24(%esp)
        +	movl	%ebp,28(%esp)
        +.byte	102,15,58,22,251,3
        +.byte	102,15,58,34,253,3
        +	movl	240(%edx),%ecx
        +	bswap	%ebx
        +	pxor	%xmm1,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movdqa	(%esp),%xmm2
        +.byte	102,15,58,34,203,0
        +	leal	3(%ebx),%ebp
        +.byte	102,15,58,34,197,0
        +	incl	%ebx
        +.byte	102,15,58,34,203,1
        +	incl	%ebp
        +.byte	102,15,58,34,197,1
        +	incl	%ebx
        +.byte	102,15,58,34,203,2
        +	incl	%ebp
        +.byte	102,15,58,34,197,2
        +	movdqa	%xmm1,48(%esp)
        +.byte	102,15,56,0,202
        +	movdqa	%xmm0,64(%esp)
        +.byte	102,15,56,0,194
        +	pshufd	$192,%xmm1,%xmm2
        +	pshufd	$128,%xmm1,%xmm3
        +	cmpl	$6,%eax
        +	jb	.L034ctr32_tail
        +	movdqa	%xmm7,32(%esp)
        +	shrl	$1,%ecx
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	subl	$6,%eax
        +	jmp	.L035ctr32_loop6
        +.align	16
        +.L035ctr32_loop6:
        +	pshufd	$64,%xmm1,%xmm4
        +	movdqa	32(%esp),%xmm1
        +	pshufd	$192,%xmm0,%xmm5
        +	por	%xmm1,%xmm2
        +	pshufd	$128,%xmm0,%xmm6
        +	por	%xmm1,%xmm3
        +	pshufd	$64,%xmm0,%xmm7
        +	por	%xmm1,%xmm4
        +	por	%xmm1,%xmm5
        +	por	%xmm1,%xmm6
        +	por	%xmm1,%xmm7
        +	movups	(%ebp),%xmm0
        +	movups	16(%ebp),%xmm1
        +	leal	32(%ebp),%edx
        +	decl	%ecx
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,220,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,220,249
        +	call	.L_aesni_encrypt6_enter
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	%xmm1,%xmm2
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm3
        +	movups	%xmm2,(%edi)
        +	movdqa	16(%esp),%xmm0
        +	xorps	%xmm1,%xmm4
        +	movdqa	48(%esp),%xmm1
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	paddd	%xmm0,%xmm1
        +	paddd	64(%esp),%xmm0
        +	movdqa	(%esp),%xmm2
        +	movups	48(%esi),%xmm3
        +	movups	64(%esi),%xmm4
        +	xorps	%xmm3,%xmm5
        +	movups	80(%esi),%xmm3
        +	leal	96(%esi),%esi
        +	movdqa	%xmm1,48(%esp)
        +.byte	102,15,56,0,202
        +	xorps	%xmm4,%xmm6
        +	movups	%xmm5,48(%edi)
        +	xorps	%xmm3,%xmm7
        +	movdqa	%xmm0,64(%esp)
        +.byte	102,15,56,0,194
        +	movups	%xmm6,64(%edi)
        +	pshufd	$192,%xmm1,%xmm2
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movl	%ebx,%ecx
        +	pshufd	$128,%xmm1,%xmm3
        +	subl	$6,%eax
        +	jnc	.L035ctr32_loop6
        +	addl	$6,%eax
        +	jz	.L036ctr32_ret
        +	movl	%ebp,%edx
        +	leal	1(,%ecx,2),%ecx
        +	movdqa	32(%esp),%xmm7
        +.L034ctr32_tail:
        +	por	%xmm7,%xmm2
        +	cmpl	$2,%eax
        +	jb	.L037ctr32_one
        +	pshufd	$64,%xmm1,%xmm4
        +	por	%xmm7,%xmm3
        +	je	.L038ctr32_two
        +	pshufd	$192,%xmm0,%xmm5
        +	por	%xmm7,%xmm4
        +	cmpl	$4,%eax
        +	jb	.L039ctr32_three
        +	pshufd	$128,%xmm0,%xmm6
        +	por	%xmm7,%xmm5
        +	je	.L040ctr32_four
        +	por	%xmm7,%xmm6
        +	call	_aesni_encrypt6
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	%xmm1,%xmm2
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm3
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm1,%xmm4
        +	movups	64(%esi),%xmm1
        +	xorps	%xmm0,%xmm5
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	jmp	.L036ctr32_ret
        +.align	16
        +.L033ctr32_one_shortcut:
        +	movups	(%ebx),%xmm2
        +	movl	240(%edx),%ecx
        +.L037ctr32_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L041enc1_loop_7:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L041enc1_loop_7
        +.byte	102,15,56,221,209
        +	movups	(%esi),%xmm6
        +	xorps	%xmm2,%xmm6
        +	movups	%xmm6,(%edi)
        +	jmp	.L036ctr32_ret
        +.align	16
        +.L038ctr32_two:
        +	call	_aesni_encrypt3
        +	movups	(%esi),%xmm5
        +	movups	16(%esi),%xmm6
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	jmp	.L036ctr32_ret
        +.align	16
        +.L039ctr32_three:
        +	call	_aesni_encrypt3
        +	movups	(%esi),%xmm5
        +	movups	16(%esi),%xmm6
        +	xorps	%xmm5,%xmm2
        +	movups	32(%esi),%xmm7
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	jmp	.L036ctr32_ret
        +.align	16
        +.L040ctr32_four:
        +	call	_aesni_encrypt4
        +	movups	(%esi),%xmm6
        +	movups	16(%esi),%xmm7
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm6,%xmm2
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm7,%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm1,%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm0,%xmm5
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +.L036ctr32_ret:
        +	movl	80(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_ctr32_encrypt_blocks,.-.L_aesni_ctr32_encrypt_blocks_begin
        +.globl	aesni_xts_encrypt
        +.type	aesni_xts_encrypt,@function
        +.align	16
        +aesni_xts_encrypt:
        +.L_aesni_xts_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	36(%esp),%edx
        +	movl	40(%esp),%esi
        +	movl	240(%edx),%ecx
        +	movups	(%esi),%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L042enc1_loop_8:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L042enc1_loop_8
        +.byte	102,15,56,221,209
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	%esp,%ebp
        +	subl	$120,%esp
        +	movl	240(%edx),%ecx
        +	andl	$-16,%esp
        +	movl	$135,96(%esp)
        +	movl	$0,100(%esp)
        +	movl	$1,104(%esp)
        +	movl	$0,108(%esp)
        +	movl	%eax,112(%esp)
        +	movl	%ebp,116(%esp)
        +	movdqa	%xmm2,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movdqa	96(%esp),%xmm3
        +	pcmpgtd	%xmm1,%xmm0
        +	andl	$-16,%eax
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	subl	$96,%eax
        +	jc	.L043xts_enc_short
        +	shrl	$1,%ecx
        +	movl	%ecx,%ebx
        +	jmp	.L044xts_enc_loop6
        +.align	16
        +.L044xts_enc_loop6:
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,16(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,32(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,64(%esp)
        +	paddq	%xmm1,%xmm1
        +	movups	(%ebp),%xmm0
        +	pand	%xmm3,%xmm7
        +	movups	(%esi),%xmm2
        +	pxor	%xmm1,%xmm7
        +	movdqu	16(%esi),%xmm3
        +	xorps	%xmm0,%xmm2
        +	movdqu	32(%esi),%xmm4
        +	pxor	%xmm0,%xmm3
        +	movdqu	48(%esi),%xmm5
        +	pxor	%xmm0,%xmm4
        +	movdqu	64(%esi),%xmm6
        +	pxor	%xmm0,%xmm5
        +	movdqu	80(%esi),%xmm1
        +	pxor	%xmm0,%xmm6
        +	leal	96(%esi),%esi
        +	pxor	(%esp),%xmm2
        +	movdqa	%xmm7,80(%esp)
        +	pxor	%xmm1,%xmm7
        +	movups	16(%ebp),%xmm1
        +	leal	32(%ebp),%edx
        +	pxor	16(%esp),%xmm3
        +.byte	102,15,56,220,209
        +	pxor	32(%esp),%xmm4
        +.byte	102,15,56,220,217
        +	pxor	48(%esp),%xmm5
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +	pxor	64(%esp),%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,220,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,220,249
        +	call	.L_aesni_encrypt6_enter
        +	movdqa	80(%esp),%xmm1
        +	pxor	%xmm0,%xmm0
        +	xorps	(%esp),%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	xorps	16(%esp),%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm4,32(%edi)
        +	xorps	64(%esp),%xmm6
        +	movups	%xmm5,48(%edi)
        +	xorps	%xmm1,%xmm7
        +	movups	%xmm6,64(%edi)
        +	pshufd	$19,%xmm0,%xmm2
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqa	96(%esp),%xmm3
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%ebx,%ecx
        +	pxor	%xmm2,%xmm1
        +	subl	$96,%eax
        +	jnc	.L044xts_enc_loop6
        +	leal	1(,%ecx,2),%ecx
        +	movl	%ebp,%edx
        +	movl	%ecx,%ebx
        +.L043xts_enc_short:
        +	addl	$96,%eax
        +	jz	.L045xts_enc_done6x
        +	movdqa	%xmm1,%xmm5
        +	cmpl	$32,%eax
        +	jb	.L046xts_enc_one
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	je	.L047xts_enc_two
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm6
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	cmpl	$64,%eax
        +	jb	.L048xts_enc_three
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm7
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	movdqa	%xmm5,(%esp)
        +	movdqa	%xmm6,16(%esp)
        +	je	.L049xts_enc_four
        +	movdqa	%xmm7,32(%esp)
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm7
        +	pxor	%xmm1,%xmm7
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	pxor	(%esp),%xmm2
        +	movdqu	48(%esi),%xmm5
        +	pxor	16(%esp),%xmm3
        +	movdqu	64(%esi),%xmm6
        +	pxor	32(%esp),%xmm4
        +	leal	80(%esi),%esi
        +	pxor	48(%esp),%xmm5
        +	movdqa	%xmm7,64(%esp)
        +	pxor	%xmm7,%xmm6
        +	call	_aesni_encrypt6
        +	movaps	64(%esp),%xmm1
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	leal	80(%edi),%edi
        +	jmp	.L050xts_enc_done
        +.align	16
        +.L046xts_enc_one:
        +	movups	(%esi),%xmm2
        +	leal	16(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L051enc1_loop_9:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L051enc1_loop_9
        +.byte	102,15,56,221,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +	movdqa	%xmm5,%xmm1
        +	jmp	.L050xts_enc_done
        +.align	16
        +.L047xts_enc_two:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	leal	32(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_encrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	leal	32(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	.L050xts_enc_done
        +.align	16
        +.L048xts_enc_three:
        +	movaps	%xmm1,%xmm7
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	leal	48(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	call	_aesni_encrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	leal	48(%edi),%edi
        +	movdqa	%xmm7,%xmm1
        +	jmp	.L050xts_enc_done
        +.align	16
        +.L049xts_enc_four:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	xorps	(%esp),%xmm2
        +	movups	48(%esi),%xmm5
        +	leal	64(%esi),%esi
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	xorps	%xmm6,%xmm5
        +	call	_aesni_encrypt4
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm6,%xmm5
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	leal	64(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	.L050xts_enc_done
        +.align	16
        +.L045xts_enc_done6x:
        +	movl	112(%esp),%eax
        +	andl	$15,%eax
        +	jz	.L052xts_enc_ret
        +	movdqa	%xmm1,%xmm5
        +	movl	%eax,112(%esp)
        +	jmp	.L053xts_enc_steal
        +.align	16
        +.L050xts_enc_done:
        +	movl	112(%esp),%eax
        +	pxor	%xmm0,%xmm0
        +	andl	$15,%eax
        +	jz	.L052xts_enc_ret
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%eax,112(%esp)
        +	pshufd	$19,%xmm0,%xmm5
        +	paddq	%xmm1,%xmm1
        +	pand	96(%esp),%xmm5
        +	pxor	%xmm1,%xmm5
        +.L053xts_enc_steal:
        +	movzbl	(%esi),%ecx
        +	movzbl	-16(%edi),%edx
        +	leal	1(%esi),%esi
        +	movb	%cl,-16(%edi)
        +	movb	%dl,(%edi)
        +	leal	1(%edi),%edi
        +	subl	$1,%eax
        +	jnz	.L053xts_enc_steal
        +	subl	112(%esp),%edi
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	movups	-16(%edi),%xmm2
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L054enc1_loop_10:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L054enc1_loop_10
        +.byte	102,15,56,221,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,-16(%edi)
        +.L052xts_enc_ret:
        +	movl	116(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_xts_encrypt,.-.L_aesni_xts_encrypt_begin
        +.globl	aesni_xts_decrypt
        +.type	aesni_xts_decrypt,@function
        +.align	16
        +aesni_xts_decrypt:
        +.L_aesni_xts_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	36(%esp),%edx
        +	movl	40(%esp),%esi
        +	movl	240(%edx),%ecx
        +	movups	(%esi),%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L055enc1_loop_11:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L055enc1_loop_11
        +.byte	102,15,56,221,209
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	%esp,%ebp
        +	subl	$120,%esp
        +	andl	$-16,%esp
        +	xorl	%ebx,%ebx
        +	testl	$15,%eax
        +	setnz	%bl
        +	shll	$4,%ebx
        +	subl	%ebx,%eax
        +	movl	$135,96(%esp)
        +	movl	$0,100(%esp)
        +	movl	$1,104(%esp)
        +	movl	$0,108(%esp)
        +	movl	%eax,112(%esp)
        +	movl	%ebp,116(%esp)
        +	movl	240(%edx),%ecx
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	movdqa	%xmm2,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movdqa	96(%esp),%xmm3
        +	pcmpgtd	%xmm1,%xmm0
        +	andl	$-16,%eax
        +	subl	$96,%eax
        +	jc	.L056xts_dec_short
        +	shrl	$1,%ecx
        +	movl	%ecx,%ebx
        +	jmp	.L057xts_dec_loop6
        +.align	16
        +.L057xts_dec_loop6:
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,16(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,32(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,64(%esp)
        +	paddq	%xmm1,%xmm1
        +	movups	(%ebp),%xmm0
        +	pand	%xmm3,%xmm7
        +	movups	(%esi),%xmm2
        +	pxor	%xmm1,%xmm7
        +	movdqu	16(%esi),%xmm3
        +	xorps	%xmm0,%xmm2
        +	movdqu	32(%esi),%xmm4
        +	pxor	%xmm0,%xmm3
        +	movdqu	48(%esi),%xmm5
        +	pxor	%xmm0,%xmm4
        +	movdqu	64(%esi),%xmm6
        +	pxor	%xmm0,%xmm5
        +	movdqu	80(%esi),%xmm1
        +	pxor	%xmm0,%xmm6
        +	leal	96(%esi),%esi
        +	pxor	(%esp),%xmm2
        +	movdqa	%xmm7,80(%esp)
        +	pxor	%xmm1,%xmm7
        +	movups	16(%ebp),%xmm1
        +	leal	32(%ebp),%edx
        +	pxor	16(%esp),%xmm3
        +.byte	102,15,56,222,209
        +	pxor	32(%esp),%xmm4
        +.byte	102,15,56,222,217
        +	pxor	48(%esp),%xmm5
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +	pxor	64(%esp),%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,222,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,222,249
        +	call	.L_aesni_decrypt6_enter
        +	movdqa	80(%esp),%xmm1
        +	pxor	%xmm0,%xmm0
        +	xorps	(%esp),%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	xorps	16(%esp),%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm4,32(%edi)
        +	xorps	64(%esp),%xmm6
        +	movups	%xmm5,48(%edi)
        +	xorps	%xmm1,%xmm7
        +	movups	%xmm6,64(%edi)
        +	pshufd	$19,%xmm0,%xmm2
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqa	96(%esp),%xmm3
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%ebx,%ecx
        +	pxor	%xmm2,%xmm1
        +	subl	$96,%eax
        +	jnc	.L057xts_dec_loop6
        +	leal	1(,%ecx,2),%ecx
        +	movl	%ebp,%edx
        +	movl	%ecx,%ebx
        +.L056xts_dec_short:
        +	addl	$96,%eax
        +	jz	.L058xts_dec_done6x
        +	movdqa	%xmm1,%xmm5
        +	cmpl	$32,%eax
        +	jb	.L059xts_dec_one
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	je	.L060xts_dec_two
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm6
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	cmpl	$64,%eax
        +	jb	.L061xts_dec_three
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm7
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	movdqa	%xmm5,(%esp)
        +	movdqa	%xmm6,16(%esp)
        +	je	.L062xts_dec_four
        +	movdqa	%xmm7,32(%esp)
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm7
        +	pxor	%xmm1,%xmm7
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	pxor	(%esp),%xmm2
        +	movdqu	48(%esi),%xmm5
        +	pxor	16(%esp),%xmm3
        +	movdqu	64(%esi),%xmm6
        +	pxor	32(%esp),%xmm4
        +	leal	80(%esi),%esi
        +	pxor	48(%esp),%xmm5
        +	movdqa	%xmm7,64(%esp)
        +	pxor	%xmm7,%xmm6
        +	call	_aesni_decrypt6
        +	movaps	64(%esp),%xmm1
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	leal	80(%edi),%edi
        +	jmp	.L063xts_dec_done
        +.align	16
        +.L059xts_dec_one:
        +	movups	(%esi),%xmm2
        +	leal	16(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L064dec1_loop_12:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L064dec1_loop_12
        +.byte	102,15,56,223,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +	movdqa	%xmm5,%xmm1
        +	jmp	.L063xts_dec_done
        +.align	16
        +.L060xts_dec_two:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	leal	32(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	call	_aesni_decrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	leal	32(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	.L063xts_dec_done
        +.align	16
        +.L061xts_dec_three:
        +	movaps	%xmm1,%xmm7
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	leal	48(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	call	_aesni_decrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	leal	48(%edi),%edi
        +	movdqa	%xmm7,%xmm1
        +	jmp	.L063xts_dec_done
        +.align	16
        +.L062xts_dec_four:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	xorps	(%esp),%xmm2
        +	movups	48(%esi),%xmm5
        +	leal	64(%esi),%esi
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	xorps	%xmm6,%xmm5
        +	call	_aesni_decrypt4
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm6,%xmm5
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	leal	64(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	.L063xts_dec_done
        +.align	16
        +.L058xts_dec_done6x:
        +	movl	112(%esp),%eax
        +	andl	$15,%eax
        +	jz	.L065xts_dec_ret
        +	movl	%eax,112(%esp)
        +	jmp	.L066xts_dec_only_one_more
        +.align	16
        +.L063xts_dec_done:
        +	movl	112(%esp),%eax
        +	pxor	%xmm0,%xmm0
        +	andl	$15,%eax
        +	jz	.L065xts_dec_ret
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%eax,112(%esp)
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	96(%esp),%xmm3
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +.L066xts_dec_only_one_more:
        +	pshufd	$19,%xmm0,%xmm5
        +	movdqa	%xmm1,%xmm6
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm5
        +	pxor	%xmm1,%xmm5
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	movups	(%esi),%xmm2
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L067dec1_loop_13:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L067dec1_loop_13
        +.byte	102,15,56,223,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,(%edi)
        +.L068xts_dec_steal:
        +	movzbl	16(%esi),%ecx
        +	movzbl	(%edi),%edx
        +	leal	1(%esi),%esi
        +	movb	%cl,(%edi)
        +	movb	%dl,16(%edi)
        +	leal	1(%edi),%edi
        +	subl	$1,%eax
        +	jnz	.L068xts_dec_steal
        +	subl	112(%esp),%edi
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	movups	(%edi),%xmm2
        +	xorps	%xmm6,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L069dec1_loop_14:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L069dec1_loop_14
        +.byte	102,15,56,223,209
        +	xorps	%xmm6,%xmm2
        +	movups	%xmm2,(%edi)
        +.L065xts_dec_ret:
        +	movl	116(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_xts_decrypt,.-.L_aesni_xts_decrypt_begin
        +.globl	aesni_cbc_encrypt
        +.type	aesni_cbc_encrypt,@function
        +.align	16
        +aesni_cbc_encrypt:
        +.L_aesni_cbc_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	%esp,%ebx
        +	movl	24(%esp),%edi
        +	subl	$24,%ebx
        +	movl	28(%esp),%eax
        +	andl	$-16,%ebx
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebp
        +	testl	%eax,%eax
        +	jz	.L070cbc_abort
        +	cmpl	$0,40(%esp)
        +	xchgl	%esp,%ebx
        +	movups	(%ebp),%xmm7
        +	movl	240(%edx),%ecx
        +	movl	%edx,%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ecx,%ebx
        +	je	.L071cbc_decrypt
        +	movaps	%xmm7,%xmm2
        +	cmpl	$16,%eax
        +	jb	.L072cbc_enc_tail
        +	subl	$16,%eax
        +	jmp	.L073cbc_enc_loop
        +.align	16
        +.L073cbc_enc_loop:
        +	movups	(%esi),%xmm7
        +	leal	16(%esi),%esi
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	xorps	%xmm0,%xmm7
        +	leal	32(%edx),%edx
        +	xorps	%xmm7,%xmm2
        +.L074enc1_loop_15:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L074enc1_loop_15
        +.byte	102,15,56,221,209
        +	movl	%ebx,%ecx
        +	movl	%ebp,%edx
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +	subl	$16,%eax
        +	jnc	.L073cbc_enc_loop
        +	addl	$16,%eax
        +	jnz	.L072cbc_enc_tail
        +	movaps	%xmm2,%xmm7
        +	jmp	.L075cbc_ret
        +.L072cbc_enc_tail:
        +	movl	%eax,%ecx
        +.long	2767451785
        +	movl	$16,%ecx
        +	subl	%eax,%ecx
        +	xorl	%eax,%eax
        +.long	2868115081
        +	leal	-16(%edi),%edi
        +	movl	%ebx,%ecx
        +	movl	%edi,%esi
        +	movl	%ebp,%edx
        +	jmp	.L073cbc_enc_loop
        +.align	16
        +.L071cbc_decrypt:
        +	cmpl	$80,%eax
        +	jbe	.L076cbc_dec_tail
        +	movaps	%xmm7,(%esp)
        +	subl	$80,%eax
        +	jmp	.L077cbc_dec_loop6_enter
        +.align	16
        +.L078cbc_dec_loop6:
        +	movaps	%xmm0,(%esp)
        +	movups	%xmm7,(%edi)
        +	leal	16(%edi),%edi
        +.L077cbc_dec_loop6_enter:
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	movdqu	48(%esi),%xmm5
        +	movdqu	64(%esi),%xmm6
        +	movdqu	80(%esi),%xmm7
        +	call	_aesni_decrypt6
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	(%esp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%esi),%xmm1
        +	xorps	%xmm0,%xmm6
        +	movups	80(%esi),%xmm0
        +	xorps	%xmm1,%xmm7
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	leal	96(%esi),%esi
        +	movups	%xmm4,32(%edi)
        +	movl	%ebx,%ecx
        +	movups	%xmm5,48(%edi)
        +	movl	%ebp,%edx
        +	movups	%xmm6,64(%edi)
        +	leal	80(%edi),%edi
        +	subl	$96,%eax
        +	ja	.L078cbc_dec_loop6
        +	movaps	%xmm7,%xmm2
        +	movaps	%xmm0,%xmm7
        +	addl	$80,%eax
        +	jle	.L079cbc_dec_tail_collected
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +.L076cbc_dec_tail:
        +	movups	(%esi),%xmm2
        +	movaps	%xmm2,%xmm6
        +	cmpl	$16,%eax
        +	jbe	.L080cbc_dec_one
        +	movups	16(%esi),%xmm3
        +	movaps	%xmm3,%xmm5
        +	cmpl	$32,%eax
        +	jbe	.L081cbc_dec_two
        +	movups	32(%esi),%xmm4
        +	cmpl	$48,%eax
        +	jbe	.L082cbc_dec_three
        +	movups	48(%esi),%xmm5
        +	cmpl	$64,%eax
        +	jbe	.L083cbc_dec_four
        +	movups	64(%esi),%xmm6
        +	movaps	%xmm7,(%esp)
        +	movups	(%esi),%xmm2
        +	xorps	%xmm7,%xmm7
        +	call	_aesni_decrypt6
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	(%esp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%esi),%xmm7
        +	xorps	%xmm0,%xmm6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	leal	64(%edi),%edi
        +	movaps	%xmm6,%xmm2
        +	subl	$80,%eax
        +	jmp	.L079cbc_dec_tail_collected
        +.align	16
        +.L080cbc_dec_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +.L084dec1_loop_16:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	.L084dec1_loop_16
        +.byte	102,15,56,223,209
        +	xorps	%xmm7,%xmm2
        +	movaps	%xmm6,%xmm7
        +	subl	$16,%eax
        +	jmp	.L079cbc_dec_tail_collected
        +.align	16
        +.L081cbc_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	_aesni_decrypt3
        +	xorps	%xmm7,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movaps	%xmm3,%xmm2
        +	leal	16(%edi),%edi
        +	movaps	%xmm5,%xmm7
        +	subl	$32,%eax
        +	jmp	.L079cbc_dec_tail_collected
        +.align	16
        +.L082cbc_dec_three:
        +	call	_aesni_decrypt3
        +	xorps	%xmm7,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm5,%xmm4
        +	movups	%xmm2,(%edi)
        +	movaps	%xmm4,%xmm2
        +	movups	%xmm3,16(%edi)
        +	leal	32(%edi),%edi
        +	movups	32(%esi),%xmm7
        +	subl	$48,%eax
        +	jmp	.L079cbc_dec_tail_collected
        +.align	16
        +.L083cbc_dec_four:
        +	call	_aesni_decrypt4
        +	movups	16(%esi),%xmm1
        +	movups	32(%esi),%xmm0
        +	xorps	%xmm7,%xmm2
        +	movups	48(%esi),%xmm7
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm1,%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm0,%xmm5
        +	movups	%xmm4,32(%edi)
        +	leal	48(%edi),%edi
        +	movaps	%xmm5,%xmm2
        +	subl	$64,%eax
        +.L079cbc_dec_tail_collected:
        +	andl	$15,%eax
        +	jnz	.L085cbc_dec_tail_partial
        +	movups	%xmm2,(%edi)
        +	jmp	.L075cbc_ret
        +.align	16
        +.L085cbc_dec_tail_partial:
        +	movaps	%xmm2,(%esp)
        +	movl	$16,%ecx
        +	movl	%esp,%esi
        +	subl	%eax,%ecx
        +.long	2767451785
        +.L075cbc_ret:
        +	movl	16(%esp),%esp
        +	movl	36(%esp),%ebp
        +	movups	%xmm7,(%ebp)
        +.L070cbc_abort:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	aesni_cbc_encrypt,.-.L_aesni_cbc_encrypt_begin
        +.type	_aesni_set_encrypt_key,@function
        +.align	16
        +_aesni_set_encrypt_key:
        +	testl	%eax,%eax
        +	jz	.L086bad_pointer
        +	testl	%edx,%edx
        +	jz	.L086bad_pointer
        +	movups	(%eax),%xmm0
        +	xorps	%xmm4,%xmm4
        +	leal	16(%edx),%edx
        +	cmpl	$256,%ecx
        +	je	.L08714rounds
        +	cmpl	$192,%ecx
        +	je	.L08812rounds
        +	cmpl	$128,%ecx
        +	jne	.L089bad_keybits
        +.align	16
        +.L09010rounds:
        +	movl	$9,%ecx
        +	movups	%xmm0,-16(%edx)
        +.byte	102,15,58,223,200,1
        +	call	.L091key_128_cold
        +.byte	102,15,58,223,200,2
        +	call	.L092key_128
        +.byte	102,15,58,223,200,4
        +	call	.L092key_128
        +.byte	102,15,58,223,200,8
        +	call	.L092key_128
        +.byte	102,15,58,223,200,16
        +	call	.L092key_128
        +.byte	102,15,58,223,200,32
        +	call	.L092key_128
        +.byte	102,15,58,223,200,64
        +	call	.L092key_128
        +.byte	102,15,58,223,200,128
        +	call	.L092key_128
        +.byte	102,15,58,223,200,27
        +	call	.L092key_128
        +.byte	102,15,58,223,200,54
        +	call	.L092key_128
        +	movups	%xmm0,(%edx)
        +	movl	%ecx,80(%edx)
        +	xorl	%eax,%eax
        +	ret
        +.align	16
        +.L092key_128:
        +	movups	%xmm0,(%edx)
        +	leal	16(%edx),%edx
        +.L091key_128_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	ret
        +.align	16
        +.L08812rounds:
        +	movq	16(%eax),%xmm2
        +	movl	$11,%ecx
        +	movups	%xmm0,-16(%edx)
        +.byte	102,15,58,223,202,1
        +	call	.L093key_192a_cold
        +.byte	102,15,58,223,202,2
        +	call	.L094key_192b
        +.byte	102,15,58,223,202,4
        +	call	.L095key_192a
        +.byte	102,15,58,223,202,8
        +	call	.L094key_192b
        +.byte	102,15,58,223,202,16
        +	call	.L095key_192a
        +.byte	102,15,58,223,202,32
        +	call	.L094key_192b
        +.byte	102,15,58,223,202,64
        +	call	.L095key_192a
        +.byte	102,15,58,223,202,128
        +	call	.L094key_192b
        +	movups	%xmm0,(%edx)
        +	movl	%ecx,48(%edx)
        +	xorl	%eax,%eax
        +	ret
        +.align	16
        +.L095key_192a:
        +	movups	%xmm0,(%edx)
        +	leal	16(%edx),%edx
        +.align	16
        +.L093key_192a_cold:
        +	movaps	%xmm2,%xmm5
        +.L096key_192b_warm:
        +	shufps	$16,%xmm0,%xmm4
        +	movdqa	%xmm2,%xmm3
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	pslldq	$4,%xmm3
        +	xorps	%xmm4,%xmm0
        +	pshufd	$85,%xmm1,%xmm1
        +	pxor	%xmm3,%xmm2
        +	pxor	%xmm1,%xmm0
        +	pshufd	$255,%xmm0,%xmm3
        +	pxor	%xmm3,%xmm2
        +	ret
        +.align	16
        +.L094key_192b:
        +	movaps	%xmm0,%xmm3
        +	shufps	$68,%xmm0,%xmm5
        +	movups	%xmm5,(%edx)
        +	shufps	$78,%xmm2,%xmm3
        +	movups	%xmm3,16(%edx)
        +	leal	32(%edx),%edx
        +	jmp	.L096key_192b_warm
        +.align	16
        +.L08714rounds:
        +	movups	16(%eax),%xmm2
        +	movl	$13,%ecx
        +	leal	16(%edx),%edx
        +	movups	%xmm0,-32(%edx)
        +	movups	%xmm2,-16(%edx)
        +.byte	102,15,58,223,202,1
        +	call	.L097key_256a_cold
        +.byte	102,15,58,223,200,1
        +	call	.L098key_256b
        +.byte	102,15,58,223,202,2
        +	call	.L099key_256a
        +.byte	102,15,58,223,200,2
        +	call	.L098key_256b
        +.byte	102,15,58,223,202,4
        +	call	.L099key_256a
        +.byte	102,15,58,223,200,4
        +	call	.L098key_256b
        +.byte	102,15,58,223,202,8
        +	call	.L099key_256a
        +.byte	102,15,58,223,200,8
        +	call	.L098key_256b
        +.byte	102,15,58,223,202,16
        +	call	.L099key_256a
        +.byte	102,15,58,223,200,16
        +	call	.L098key_256b
        +.byte	102,15,58,223,202,32
        +	call	.L099key_256a
        +.byte	102,15,58,223,200,32
        +	call	.L098key_256b
        +.byte	102,15,58,223,202,64
        +	call	.L099key_256a
        +	movups	%xmm0,(%edx)
        +	movl	%ecx,16(%edx)
        +	xorl	%eax,%eax
        +	ret
        +.align	16
        +.L099key_256a:
        +	movups	%xmm2,(%edx)
        +	leal	16(%edx),%edx
        +.L097key_256a_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	ret
        +.align	16
        +.L098key_256b:
        +	movups	%xmm0,(%edx)
        +	leal	16(%edx),%edx
        +	shufps	$16,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$140,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$170,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm2
        +	ret
        +.align	4
        +.L086bad_pointer:
        +	movl	$-1,%eax
        +	ret
        +.align	4
        +.L089bad_keybits:
        +	movl	$-2,%eax
        +	ret
        +.size	_aesni_set_encrypt_key,.-_aesni_set_encrypt_key
        +.globl	aesni_set_encrypt_key
        +.type	aesni_set_encrypt_key,@function
        +.align	16
        +aesni_set_encrypt_key:
        +.L_aesni_set_encrypt_key_begin:
        +	movl	4(%esp),%eax
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	call	_aesni_set_encrypt_key
        +	ret
        +.size	aesni_set_encrypt_key,.-.L_aesni_set_encrypt_key_begin
        +.globl	aesni_set_decrypt_key
        +.type	aesni_set_decrypt_key,@function
        +.align	16
        +aesni_set_decrypt_key:
        +.L_aesni_set_decrypt_key_begin:
        +	movl	4(%esp),%eax
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	call	_aesni_set_encrypt_key
        +	movl	12(%esp),%edx
        +	shll	$4,%ecx
        +	testl	%eax,%eax
        +	jnz	.L100dec_key_ret
        +	leal	16(%edx,%ecx,1),%eax
        +	movups	(%edx),%xmm0
        +	movups	(%eax),%xmm1
        +	movups	%xmm0,(%eax)
        +	movups	%xmm1,(%edx)
        +	leal	16(%edx),%edx
        +	leal	-16(%eax),%eax
        +.L101dec_key_inverse:
        +	movups	(%edx),%xmm0
        +	movups	(%eax),%xmm1
        +.byte	102,15,56,219,192
        +.byte	102,15,56,219,201
        +	leal	16(%edx),%edx
        +	leal	-16(%eax),%eax
        +	movups	%xmm0,16(%eax)
        +	movups	%xmm1,-16(%edx)
        +	cmpl	%edx,%eax
        +	ja	.L101dec_key_inverse
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,219,192
        +	movups	%xmm0,(%edx)
        +	xorl	%eax,%eax
        +.L100dec_key_ret:
        +	ret
        +.size	aesni_set_decrypt_key,.-.L_aesni_set_decrypt_key_begin
        +.byte	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
        +.byte	83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
        +.byte	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +.byte	115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-elf-gas/bf/bf-686.s b/vendor/openssl/asm/x86-elf-gas/bf/bf-686.s
        new file mode 100644
        index 000000000..69b0ce681
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/bf/bf-686.s
        @@ -0,0 +1,864 @@
        +.file	"bf-686.s"
        +.text
        +.globl	BF_encrypt
        +.type	BF_encrypt,@function
        +.align	16
        +BF_encrypt:
        +.L_BF_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	movl	20(%esp),%eax
        +	movl	(%eax),%ecx
        +	movl	4(%eax),%edx
        +
        +
        +	movl	24(%esp),%edi
        +	xorl	%eax,%eax
        +	xorl	%ebx,%ebx
        +	xorl	(%edi),%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	4(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	8(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	12(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	16(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	20(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	24(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	28(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	32(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	36(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	40(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	44(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	48(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	52(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	56(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	60(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	64(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +	xorl	68(%edi),%edx
        +	movl	20(%esp),%eax
        +	movl	%edx,(%eax)
        +	movl	%ecx,4(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	BF_encrypt,.-.L_BF_encrypt_begin
        +.globl	BF_decrypt
        +.type	BF_decrypt,@function
        +.align	16
        +BF_decrypt:
        +.L_BF_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	movl	20(%esp),%eax
        +	movl	(%eax),%ecx
        +	movl	4(%eax),%edx
        +
        +
        +	movl	24(%esp),%edi
        +	xorl	%eax,%eax
        +	xorl	%ebx,%ebx
        +	xorl	68(%edi),%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	64(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	60(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	56(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	52(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	48(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	44(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	40(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	36(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	32(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	28(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	24(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	20(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	16(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	12(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +
        +	rorl	$16,%ecx
        +	movl	8(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +
        +	rorl	$16,%edx
        +	movl	4(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +	xorl	(%edi),%edx
        +	movl	20(%esp),%eax
        +	movl	%edx,(%eax)
        +	movl	%ecx,4(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	BF_decrypt,.-.L_BF_decrypt_begin
        +.globl	BF_cbc_encrypt
        +.type	BF_cbc_encrypt,@function
        +.align	16
        +BF_cbc_encrypt:
        +.L_BF_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +
        +	movl	56(%esp),%ecx
        +
        +	movl	48(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	.L000decrypt
        +	andl	$4294967288,%ebp
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	jz	.L001encrypt_finish
        +.L002encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_BF_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L002encrypt_loop
        +.L001encrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L003finish
        +	call	.L004PIC_point
        +.L004PIC_point:
        +	popl	%edx
        +	leal	.L005cbc_enc_jmp_table-.L004PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +.L006ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +.L007ej6:
        +	movb	5(%esi),%dh
        +.L008ej5:
        +	movb	4(%esi),%dl
        +.L009ej4:
        +	movl	(%esi),%ecx
        +	jmp	.L010ejend
        +.L011ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +.L012ej2:
        +	movb	1(%esi),%ch
        +.L013ej1:
        +	movb	(%esi),%cl
        +.L010ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_BF_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	.L003finish
        +.L000decrypt:
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	.L014decrypt_finish
        +.L015decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_BF_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L015decrypt_loop
        +.L014decrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L003finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_BF_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +.L016dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +.L017dj6:
        +	movb	%dh,5(%edi)
        +.L018dj5:
        +	movb	%dl,4(%edi)
        +.L019dj4:
        +	movl	%ecx,(%edi)
        +	jmp	.L020djend
        +.L021dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +.L022dj2:
        +	movb	%ch,1(%esi)
        +.L023dj1:
        +	movb	%cl,(%esi)
        +.L020djend:
        +	jmp	.L003finish
        +.L003finish:
        +	movl	60(%esp),%ecx
        +	addl	$24,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L005cbc_enc_jmp_table:
        +.long	0
        +.long	.L013ej1-.L004PIC_point
        +.long	.L012ej2-.L004PIC_point
        +.long	.L011ej3-.L004PIC_point
        +.long	.L009ej4-.L004PIC_point
        +.long	.L008ej5-.L004PIC_point
        +.long	.L007ej6-.L004PIC_point
        +.long	.L006ej7-.L004PIC_point
        +.align	64
        +.size	BF_cbc_encrypt,.-.L_BF_cbc_encrypt_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/bn/x86-mont.s b/vendor/openssl/asm/x86-elf-gas/bn/x86-mont.s
        new file mode 100644
        index 000000000..d71cc6441
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/bn/x86-mont.s
        @@ -0,0 +1,338 @@
        +.file	"../openssl/crypto/bn/asm/x86-mont.s"
        +.text
        +.globl	bn_mul_mont
        +.type	bn_mul_mont,@function
        +.align	16
        +bn_mul_mont:
        +.L_bn_mul_mont_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	xorl	%eax,%eax
        +	movl	40(%esp),%edi
        +	cmpl	$4,%edi
        +	jl	.L000just_leave
        +	leal	20(%esp),%esi
        +	leal	24(%esp),%edx
        +	movl	%esp,%ebp
        +	addl	$2,%edi
        +	negl	%edi
        +	leal	-32(%esp,%edi,4),%esp
        +	negl	%edi
        +	movl	%esp,%eax
        +	subl	%edx,%eax
        +	andl	$2047,%eax
        +	subl	%eax,%esp
        +	xorl	%esp,%edx
        +	andl	$2048,%edx
        +	xorl	$2048,%edx
        +	subl	%edx,%esp
        +	andl	$-64,%esp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	16(%esi),%esi
        +	movl	(%esi),%esi
        +	movl	%eax,4(%esp)
        +	movl	%ebx,8(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edx,16(%esp)
        +	movl	%esi,20(%esp)
        +	leal	-3(%edi),%ebx
        +	movl	%ebp,24(%esp)
        +	movl	8(%esp),%esi
        +	leal	1(%ebx),%ebp
        +	movl	12(%esp),%edi
        +	xorl	%ecx,%ecx
        +	movl	%esi,%edx
        +	andl	$1,%ebp
        +	subl	%edi,%edx
        +	leal	4(%edi,%ebx,4),%eax
        +	orl	%edx,%ebp
        +	movl	(%edi),%edi
        +	jz	.L001bn_sqr_mont
        +	movl	%eax,28(%esp)
        +	movl	(%esi),%eax
        +	xorl	%edx,%edx
        +.align	16
        +.L002mull:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%eax,%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	movl	(%esi,%ecx,4),%eax
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	jl	.L002mull
        +	movl	%edx,%ebp
        +	mull	%edi
        +	movl	20(%esp),%edi
        +	addl	%ebp,%eax
        +	movl	16(%esp),%esi
        +	adcl	$0,%edx
        +	imull	32(%esp),%edi
        +	movl	%eax,32(%esp,%ebx,4)
        +	xorl	%ecx,%ecx
        +	movl	%edx,36(%esp,%ebx,4)
        +	movl	%ecx,40(%esp,%ebx,4)
        +	movl	(%esi),%eax
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	movl	4(%esi),%eax
        +	adcl	$0,%edx
        +	incl	%ecx
        +	jmp	.L0032ndmadd
        +.align	16
        +.L0041stmadd:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	jl	.L0041stmadd
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ebx,4),%eax
        +	movl	20(%esp),%edi
        +	adcl	$0,%edx
        +	movl	16(%esp),%esi
        +	addl	%eax,%ebp
        +	adcl	$0,%edx
        +	imull	32(%esp),%edi
        +	xorl	%ecx,%ecx
        +	addl	36(%esp,%ebx,4),%edx
        +	movl	%ebp,32(%esp,%ebx,4)
        +	adcl	$0,%ecx
        +	movl	(%esi),%eax
        +	movl	%edx,36(%esp,%ebx,4)
        +	movl	%ecx,40(%esp,%ebx,4)
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	movl	4(%esi),%eax
        +	adcl	$0,%edx
        +	movl	$1,%ecx
        +.align	16
        +.L0032ndmadd:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,24(%esp,%ecx,4)
        +	jl	.L0032ndmadd
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ebx,4),%ebp
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	adcl	$0,%edx
        +	movl	%ebp,28(%esp,%ebx,4)
        +	xorl	%eax,%eax
        +	movl	12(%esp),%ecx
        +	addl	36(%esp,%ebx,4),%edx
        +	adcl	40(%esp,%ebx,4),%eax
        +	leal	4(%ecx),%ecx
        +	movl	%edx,32(%esp,%ebx,4)
        +	cmpl	28(%esp),%ecx
        +	movl	%eax,36(%esp,%ebx,4)
        +	je	.L005common_tail
        +	movl	(%ecx),%edi
        +	movl	8(%esp),%esi
        +	movl	%ecx,12(%esp)
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	movl	(%esi),%eax
        +	jmp	.L0041stmadd
        +.align	16
        +.L001bn_sqr_mont:
        +	movl	%ebx,(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edi,%eax
        +	mull	%edi
        +	movl	%eax,32(%esp)
        +	movl	%edx,%ebx
        +	shrl	$1,%edx
        +	andl	$1,%ebx
        +	incl	%ecx
        +.align	16
        +.L006sqr:
        +	movl	(%esi,%ecx,4),%eax
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%ebp,%eax
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	leal	(%ebx,%eax,2),%ebp
        +	shrl	$31,%eax
        +	cmpl	(%esp),%ecx
        +	movl	%eax,%ebx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	jl	.L006sqr
        +	movl	(%esi,%ecx,4),%eax
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%ebp,%eax
        +	movl	20(%esp),%edi
        +	adcl	$0,%edx
        +	movl	16(%esp),%esi
        +	leal	(%ebx,%eax,2),%ebp
        +	imull	32(%esp),%edi
        +	shrl	$31,%eax
        +	movl	%ebp,32(%esp,%ecx,4)
        +	leal	(%eax,%edx,2),%ebp
        +	movl	(%esi),%eax
        +	shrl	$31,%edx
        +	movl	%ebp,36(%esp,%ecx,4)
        +	movl	%edx,40(%esp,%ecx,4)
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	movl	%ecx,%ebx
        +	adcl	$0,%edx
        +	movl	4(%esi),%eax
        +	movl	$1,%ecx
        +.align	16
        +.L0073rdmadd:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%ebp
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	36(%esp,%ecx,4),%ebp
        +	leal	2(%ecx),%ecx
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,24(%esp,%ecx,4)
        +	jl	.L0073rdmadd
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ebx,4),%ebp
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	adcl	$0,%edx
        +	movl	%ebp,28(%esp,%ebx,4)
        +	movl	12(%esp),%ecx
        +	xorl	%eax,%eax
        +	movl	8(%esp),%esi
        +	addl	36(%esp,%ebx,4),%edx
        +	adcl	40(%esp,%ebx,4),%eax
        +	movl	%edx,32(%esp,%ebx,4)
        +	cmpl	%ebx,%ecx
        +	movl	%eax,36(%esp,%ebx,4)
        +	je	.L005common_tail
        +	movl	4(%esi,%ecx,4),%edi
        +	leal	1(%ecx),%ecx
        +	movl	%edi,%eax
        +	movl	%ecx,12(%esp)
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%eax
        +	adcl	$0,%edx
        +	movl	%eax,32(%esp,%ecx,4)
        +	xorl	%ebp,%ebp
        +	cmpl	%ebx,%ecx
        +	leal	1(%ecx),%ecx
        +	je	.L008sqrlast
        +	movl	%edx,%ebx
        +	shrl	$1,%edx
        +	andl	$1,%ebx
        +.align	16
        +.L009sqradd:
        +	movl	(%esi,%ecx,4),%eax
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%ebp,%eax
        +	leal	(%eax,%eax,1),%ebp
        +	adcl	$0,%edx
        +	shrl	$31,%eax
        +	addl	32(%esp,%ecx,4),%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%eax
        +	addl	%ebx,%ebp
        +	adcl	$0,%eax
        +	cmpl	(%esp),%ecx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	movl	%eax,%ebx
        +	jle	.L009sqradd
        +	movl	%edx,%ebp
        +	addl	%edx,%edx
        +	shrl	$31,%ebp
        +	addl	%ebx,%edx
        +	adcl	$0,%ebp
        +.L008sqrlast:
        +	movl	20(%esp),%edi
        +	movl	16(%esp),%esi
        +	imull	32(%esp),%edi
        +	addl	32(%esp,%ecx,4),%edx
        +	movl	(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%edx,32(%esp,%ecx,4)
        +	movl	%ebp,36(%esp,%ecx,4)
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	leal	-1(%ecx),%ebx
        +	adcl	$0,%edx
        +	movl	$1,%ecx
        +	movl	4(%esi),%eax
        +	jmp	.L0073rdmadd
        +.align	16
        +.L005common_tail:
        +	movl	16(%esp),%ebp
        +	movl	4(%esp),%edi
        +	leal	32(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	%ebx,%ecx
        +	xorl	%edx,%edx
        +.align	16
        +.L010sub:
        +	sbbl	(%ebp,%edx,4),%eax
        +	movl	%eax,(%edi,%edx,4)
        +	decl	%ecx
        +	movl	4(%esi,%edx,4),%eax
        +	leal	1(%edx),%edx
        +	jge	.L010sub
        +	sbbl	$0,%eax
        +	andl	%eax,%esi
        +	notl	%eax
        +	movl	%edi,%ebp
        +	andl	%eax,%ebp
        +	orl	%ebp,%esi
        +.align	16
        +.L011copy:
        +	movl	(%esi,%ebx,4),%eax
        +	movl	%eax,(%edi,%ebx,4)
        +	movl	%ecx,32(%esp,%ebx,4)
        +	decl	%ebx
        +	jge	.L011copy
        +	movl	24(%esp),%esp
        +	movl	$1,%eax
        +.L000just_leave:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_mul_mont,.-.L_bn_mul_mont_begin
        +.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
        +.byte	112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56
        +.byte	54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121
        +.byte	32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46
        +.byte	111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-elf-gas/bn/x86.s b/vendor/openssl/asm/x86-elf-gas/bn/x86.s
        new file mode 100644
        index 000000000..c41c8e917
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/bn/x86.s
        @@ -0,0 +1,2114 @@
        +.file	"../openssl/crypto/bn/asm/x86.s"
        +.text
        +.globl	bn_mul_add_words
        +.type	bn_mul_add_words,@function
        +.align	16
        +bn_mul_add_words:
        +.L_bn_mul_add_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	xorl	%esi,%esi
        +	movl	20(%esp),%edi
        +	movl	28(%esp),%ecx
        +	movl	24(%esp),%ebx
        +	andl	$4294967288,%ecx
        +	movl	32(%esp),%ebp
        +	pushl	%ecx
        +	jz	.L000maw_finish
        +.L001maw_loop:
        +	movl	%ecx,(%esp)
        +
        +	movl	(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +
        +	movl	4(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	4(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +
        +	movl	8(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	8(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +
        +	movl	12(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	12(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +
        +	movl	16(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	16(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +
        +	movl	20(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	20(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +
        +	movl	24(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	24(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +
        +	movl	28(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	28(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,28(%edi)
        +	movl	%edx,%esi
        +
        +	movl	(%esp),%ecx
        +	addl	$32,%ebx
        +	addl	$32,%edi
        +	subl	$8,%ecx
        +	jnz	.L001maw_loop
        +.L000maw_finish:
        +	movl	32(%esp),%ecx
        +	andl	$7,%ecx
        +	jnz	.L002maw_finish2
        +	jmp	.L003maw_end
        +.L002maw_finish2:
        +
        +	movl	(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +	jz	.L003maw_end
        +
        +	movl	4(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	4(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +	jz	.L003maw_end
        +
        +	movl	8(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	8(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +	jz	.L003maw_end
        +
        +	movl	12(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	12(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +	jz	.L003maw_end
        +
        +	movl	16(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	16(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +	jz	.L003maw_end
        +
        +	movl	20(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	20(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +	jz	.L003maw_end
        +
        +	movl	24(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	24(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +.L003maw_end:
        +	movl	%esi,%eax
        +	popl	%ecx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_mul_add_words,.-.L_bn_mul_add_words_begin
        +.globl	bn_mul_words
        +.type	bn_mul_words,@function
        +.align	16
        +bn_mul_words:
        +.L_bn_mul_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	xorl	%esi,%esi
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%ebx
        +	movl	28(%esp),%ebp
        +	movl	32(%esp),%ecx
        +	andl	$4294967288,%ebp
        +	jz	.L004mw_finish
        +.L005mw_loop:
        +
        +	movl	(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +
        +	movl	4(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +
        +	movl	8(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +
        +	movl	12(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +
        +	movl	16(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +
        +	movl	20(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +
        +	movl	24(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +
        +	movl	28(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,28(%edi)
        +	movl	%edx,%esi
        +
        +	addl	$32,%ebx
        +	addl	$32,%edi
        +	subl	$8,%ebp
        +	jz	.L004mw_finish
        +	jmp	.L005mw_loop
        +.L004mw_finish:
        +	movl	28(%esp),%ebp
        +	andl	$7,%ebp
        +	jnz	.L006mw_finish2
        +	jmp	.L007mw_end
        +.L006mw_finish2:
        +
        +	movl	(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	.L007mw_end
        +
        +	movl	4(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	.L007mw_end
        +
        +	movl	8(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	.L007mw_end
        +
        +	movl	12(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	.L007mw_end
        +
        +	movl	16(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	.L007mw_end
        +
        +	movl	20(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	.L007mw_end
        +
        +	movl	24(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +.L007mw_end:
        +	movl	%esi,%eax
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_mul_words,.-.L_bn_mul_words_begin
        +.globl	bn_sqr_words
        +.type	bn_sqr_words,@function
        +.align	16
        +bn_sqr_words:
        +.L_bn_sqr_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%ebx
        +	andl	$4294967288,%ebx
        +	jz	.L008sw_finish
        +.L009sw_loop:
        +
        +	movl	(%edi),%eax
        +	mull	%eax
        +	movl	%eax,(%esi)
        +	movl	%edx,4(%esi)
        +
        +	movl	4(%edi),%eax
        +	mull	%eax
        +	movl	%eax,8(%esi)
        +	movl	%edx,12(%esi)
        +
        +	movl	8(%edi),%eax
        +	mull	%eax
        +	movl	%eax,16(%esi)
        +	movl	%edx,20(%esi)
        +
        +	movl	12(%edi),%eax
        +	mull	%eax
        +	movl	%eax,24(%esi)
        +	movl	%edx,28(%esi)
        +
        +	movl	16(%edi),%eax
        +	mull	%eax
        +	movl	%eax,32(%esi)
        +	movl	%edx,36(%esi)
        +
        +	movl	20(%edi),%eax
        +	mull	%eax
        +	movl	%eax,40(%esi)
        +	movl	%edx,44(%esi)
        +
        +	movl	24(%edi),%eax
        +	mull	%eax
        +	movl	%eax,48(%esi)
        +	movl	%edx,52(%esi)
        +
        +	movl	28(%edi),%eax
        +	mull	%eax
        +	movl	%eax,56(%esi)
        +	movl	%edx,60(%esi)
        +
        +	addl	$32,%edi
        +	addl	$64,%esi
        +	subl	$8,%ebx
        +	jnz	.L009sw_loop
        +.L008sw_finish:
        +	movl	28(%esp),%ebx
        +	andl	$7,%ebx
        +	jz	.L010sw_end
        +
        +	movl	(%edi),%eax
        +	mull	%eax
        +	movl	%eax,(%esi)
        +	decl	%ebx
        +	movl	%edx,4(%esi)
        +	jz	.L010sw_end
        +
        +	movl	4(%edi),%eax
        +	mull	%eax
        +	movl	%eax,8(%esi)
        +	decl	%ebx
        +	movl	%edx,12(%esi)
        +	jz	.L010sw_end
        +
        +	movl	8(%edi),%eax
        +	mull	%eax
        +	movl	%eax,16(%esi)
        +	decl	%ebx
        +	movl	%edx,20(%esi)
        +	jz	.L010sw_end
        +
        +	movl	12(%edi),%eax
        +	mull	%eax
        +	movl	%eax,24(%esi)
        +	decl	%ebx
        +	movl	%edx,28(%esi)
        +	jz	.L010sw_end
        +
        +	movl	16(%edi),%eax
        +	mull	%eax
        +	movl	%eax,32(%esi)
        +	decl	%ebx
        +	movl	%edx,36(%esi)
        +	jz	.L010sw_end
        +
        +	movl	20(%edi),%eax
        +	mull	%eax
        +	movl	%eax,40(%esi)
        +	decl	%ebx
        +	movl	%edx,44(%esi)
        +	jz	.L010sw_end
        +
        +	movl	24(%edi),%eax
        +	mull	%eax
        +	movl	%eax,48(%esi)
        +	movl	%edx,52(%esi)
        +.L010sw_end:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_sqr_words,.-.L_bn_sqr_words_begin
        +.globl	bn_div_words
        +.type	bn_div_words,@function
        +.align	16
        +bn_div_words:
        +.L_bn_div_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%edx
        +	movl	24(%esp),%eax
        +	movl	28(%esp),%ebx
        +	divl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_div_words,.-.L_bn_div_words_begin
        +.globl	bn_add_words
        +.type	bn_add_words,@function
        +.align	16
        +bn_add_words:
        +.L_bn_add_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	32(%esp),%ebp
        +	xorl	%eax,%eax
        +	andl	$4294967288,%ebp
        +	jz	.L011aw_finish
        +.L012aw_loop:
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,(%ebx)
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,4(%ebx)
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,8(%ebx)
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,12(%ebx)
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,16(%ebx)
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,20(%ebx)
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +
        +	movl	28(%esi),%ecx
        +	movl	28(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,28(%ebx)
        +
        +	addl	$32,%esi
        +	addl	$32,%edi
        +	addl	$32,%ebx
        +	subl	$8,%ebp
        +	jnz	.L012aw_loop
        +.L011aw_finish:
        +	movl	32(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L013aw_end
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,(%ebx)
        +	jz	.L013aw_end
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,4(%ebx)
        +	jz	.L013aw_end
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,8(%ebx)
        +	jz	.L013aw_end
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,12(%ebx)
        +	jz	.L013aw_end
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,16(%ebx)
        +	jz	.L013aw_end
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,20(%ebx)
        +	jz	.L013aw_end
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +.L013aw_end:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_add_words,.-.L_bn_add_words_begin
        +.globl	bn_sub_words
        +.type	bn_sub_words,@function
        +.align	16
        +bn_sub_words:
        +.L_bn_sub_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	32(%esp),%ebp
        +	xorl	%eax,%eax
        +	andl	$4294967288,%ebp
        +	jz	.L014aw_finish
        +.L015aw_loop:
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,(%ebx)
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,4(%ebx)
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,8(%ebx)
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,12(%ebx)
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,16(%ebx)
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,20(%ebx)
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +
        +	movl	28(%esi),%ecx
        +	movl	28(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,28(%ebx)
        +
        +	addl	$32,%esi
        +	addl	$32,%edi
        +	addl	$32,%ebx
        +	subl	$8,%ebp
        +	jnz	.L015aw_loop
        +.L014aw_finish:
        +	movl	32(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L016aw_end
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,(%ebx)
        +	jz	.L016aw_end
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,4(%ebx)
        +	jz	.L016aw_end
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,8(%ebx)
        +	jz	.L016aw_end
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,12(%ebx)
        +	jz	.L016aw_end
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,16(%ebx)
        +	jz	.L016aw_end
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,20(%ebx)
        +	jz	.L016aw_end
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +.L016aw_end:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	bn_sub_words,.-.L_bn_sub_words_begin
        +.globl	bn_mul_comba8
        +.type	bn_mul_comba8,@function
        +.align	16
        +bn_mul_comba8:
        +.L_bn_mul_comba8_begin:
        +	pushl	%esi
        +	movl	12(%esp),%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	xorl	%ebx,%ebx
        +	movl	(%esi),%eax
        +	xorl	%ecx,%ecx
        +	movl	(%edi),%edx
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%eax)
        +	movl	4(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%eax)
        +	movl	8(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%eax)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%eax)
        +	movl	16(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%eax)
        +	movl	20(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%eax)
        +	movl	24(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,28(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,32(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,36(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,40(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,44(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,48(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,52(%eax)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	adcl	$0,%ecx
        +	movl	%ebp,56(%eax)
        +
        +
        +	movl	%ebx,60(%eax)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	bn_mul_comba8,.-.L_bn_mul_comba8_begin
        +.globl	bn_mul_comba4
        +.type	bn_mul_comba4,@function
        +.align	16
        +bn_mul_comba4:
        +.L_bn_mul_comba4_begin:
        +	pushl	%esi
        +	movl	12(%esp),%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	xorl	%ebx,%ebx
        +	movl	(%esi),%eax
        +	xorl	%ecx,%ecx
        +	movl	(%edi),%edx
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%eax)
        +	movl	4(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%eax)
        +	movl	8(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%eax)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%eax)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%eax)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%eax)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%eax)
        +
        +
        +	movl	%ecx,28(%eax)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	bn_mul_comba4,.-.L_bn_mul_comba4_begin
        +.globl	bn_sqr_comba8
        +.type	bn_sqr_comba8,@function
        +.align	16
        +bn_sqr_comba8:
        +.L_bn_sqr_comba8_begin:
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%esi
        +	xorl	%ebx,%ebx
        +	xorl	%ecx,%ecx
        +	movl	(%esi),%eax
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%edi)
        +	movl	4(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%edi)
        +	movl	(%esi),%edx
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	4(%esi),%eax
        +	adcl	$0,%ecx
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	(%esi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%edi)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	4(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%edi)
        +	movl	(%esi),%edx
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	12(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	4(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +
        +	mull	%eax
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	(%esi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%edi)
        +	movl	20(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	4(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	8(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%edi)
        +	movl	(%esi),%edx
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	4(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	8(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ebp
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%edi)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	4(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	8(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	16(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	12(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	28(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,28(%edi)
        +	movl	4(%esi),%edx
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	8(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	20(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	12(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ecx
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	8(%esi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,32(%edi)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	12(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	16(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	28(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%ebx,36(%edi)
        +	movl	12(%esi),%edx
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	16(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebx
        +
        +	mull	%eax
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	16(%esi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,40(%edi)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	20(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	28(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	%ebp,44(%edi)
        +	movl	20(%esi),%edx
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebp
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	24(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,48(%edi)
        +	movl	28(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	28(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,52(%edi)
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	adcl	$0,%ecx
        +	movl	%ebp,56(%edi)
        +
        +	movl	%ebx,60(%edi)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	bn_sqr_comba8,.-.L_bn_sqr_comba8_begin
        +.globl	bn_sqr_comba4
        +.type	bn_sqr_comba4,@function
        +.align	16
        +bn_sqr_comba4:
        +.L_bn_sqr_comba4_begin:
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%esi
        +	xorl	%ebx,%ebx
        +	xorl	%ecx,%ecx
        +	movl	(%esi),%eax
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%edi)
        +	movl	4(%esi),%eax
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%edi)
        +	movl	(%esi),%edx
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	4(%esi),%eax
        +	adcl	$0,%ecx
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	(%esi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%edi)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	4(%esi),%edx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%edi)
        +	movl	4(%esi),%edx
        +
        +
        +	xorl	%ebx,%ebx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +
        +	mull	%eax
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%edi)
        +	movl	12(%esi),%eax
        +
        +
        +	xorl	%ecx,%ecx
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%edi)
        +
        +
        +	xorl	%ebp,%ebp
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%edi)
        +
        +	movl	%ecx,28(%edi)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	bn_sqr_comba4,.-.L_bn_sqr_comba4_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/camellia/cmll-x86.s b/vendor/openssl/asm/x86-elf-gas/camellia/cmll-x86.s
        new file mode 100644
        index 000000000..5c87910e3
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/camellia/cmll-x86.s
        @@ -0,0 +1,2375 @@
        +.file	"cmll-586.s"
        +.text
        +.globl	Camellia_EncryptBlock_Rounds
        +.type	Camellia_EncryptBlock_Rounds,@function
        +.align	16
        +Camellia_EncryptBlock_Rounds:
        +.L_Camellia_EncryptBlock_Rounds_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	leal	(%edi,%eax,1),%eax
        +	movl	%ebx,20(%esp)
        +	movl	%eax,16(%esp)
        +	call	.L000pic_point
        +.L000pic_point:
        +	popl	%ebp
        +	leal	.LCamellia_SBOX-.L000pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_encrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	32(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	Camellia_EncryptBlock_Rounds,.-.L_Camellia_EncryptBlock_Rounds_begin
        +.globl	Camellia_EncryptBlock
        +.type	Camellia_EncryptBlock,@function
        +.align	16
        +Camellia_EncryptBlock:
        +.L_Camellia_EncryptBlock_begin:
        +	movl	$128,%eax
        +	subl	4(%esp),%eax
        +	movl	$3,%eax
        +	adcl	$0,%eax
        +	movl	%eax,4(%esp)
        +	jmp	.L_Camellia_EncryptBlock_Rounds_begin
        +.size	Camellia_EncryptBlock,.-.L_Camellia_EncryptBlock_begin
        +.globl	Camellia_encrypt
        +.type	Camellia_encrypt,@function
        +.align	16
        +Camellia_encrypt:
        +.L_Camellia_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	movl	272(%edi),%eax
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	leal	(%edi,%eax,1),%eax
        +	movl	%ebx,20(%esp)
        +	movl	%eax,16(%esp)
        +	call	.L001pic_point
        +.L001pic_point:
        +	popl	%ebp
        +	leal	.LCamellia_SBOX-.L001pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_encrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	24(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	Camellia_encrypt,.-.L_Camellia_encrypt_begin
        +.type	_x86_Camellia_encrypt,@function
        +.align	16
        +_x86_Camellia_encrypt:
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	16(%edi),%esi
        +	movl	%eax,4(%esp)
        +	movl	%ebx,8(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edx,16(%esp)
        +.align	16
        +.L002loop:
        +	xorl	%esi,%eax
        +	xorl	20(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	24(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	28(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	32(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	36(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	40(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	44(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	48(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	52(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	56(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	60(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	64(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	addl	$64,%edi
        +	cmpl	20(%esp),%edi
        +	je	.L003done
        +	andl	%eax,%esi
        +	movl	16(%esp),%edx
        +	roll	$1,%esi
        +	movl	%edx,%ecx
        +	xorl	%esi,%ebx
        +	orl	12(%edi),%ecx
        +	movl	%ebx,8(%esp)
        +	xorl	12(%esp),%ecx
        +	movl	4(%edi),%esi
        +	movl	%ecx,12(%esp)
        +	orl	%ebx,%esi
        +	andl	8(%edi),%ecx
        +	xorl	%esi,%eax
        +	roll	$1,%ecx
        +	movl	%eax,4(%esp)
        +	xorl	%ecx,%edx
        +	movl	16(%edi),%esi
        +	movl	%edx,16(%esp)
        +	jmp	.L002loop
        +.align	8
        +.L003done:
        +	movl	%eax,%ecx
        +	movl	%ebx,%edx
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	xorl	%esi,%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	ret
        +.size	_x86_Camellia_encrypt,.-_x86_Camellia_encrypt
        +.globl	Camellia_DecryptBlock_Rounds
        +.type	Camellia_DecryptBlock_Rounds,@function
        +.align	16
        +Camellia_DecryptBlock_Rounds:
        +.L_Camellia_DecryptBlock_Rounds_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	movl	%edi,16(%esp)
        +	leal	(%edi,%eax,1),%edi
        +	movl	%ebx,20(%esp)
        +	call	.L004pic_point
        +.L004pic_point:
        +	popl	%ebp
        +	leal	.LCamellia_SBOX-.L004pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_decrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	32(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	Camellia_DecryptBlock_Rounds,.-.L_Camellia_DecryptBlock_Rounds_begin
        +.globl	Camellia_DecryptBlock
        +.type	Camellia_DecryptBlock,@function
        +.align	16
        +Camellia_DecryptBlock:
        +.L_Camellia_DecryptBlock_begin:
        +	movl	$128,%eax
        +	subl	4(%esp),%eax
        +	movl	$3,%eax
        +	adcl	$0,%eax
        +	movl	%eax,4(%esp)
        +	jmp	.L_Camellia_DecryptBlock_Rounds_begin
        +.size	Camellia_DecryptBlock,.-.L_Camellia_DecryptBlock_begin
        +.globl	Camellia_decrypt
        +.type	Camellia_decrypt,@function
        +.align	16
        +Camellia_decrypt:
        +.L_Camellia_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	movl	272(%edi),%eax
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	movl	%edi,16(%esp)
        +	leal	(%edi,%eax,1),%edi
        +	movl	%ebx,20(%esp)
        +	call	.L005pic_point
        +.L005pic_point:
        +	popl	%ebp
        +	leal	.LCamellia_SBOX-.L005pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_decrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	24(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	Camellia_decrypt,.-.L_Camellia_decrypt_begin
        +.type	_x86_Camellia_decrypt,@function
        +.align	16
        +_x86_Camellia_decrypt:
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	-8(%edi),%esi
        +	movl	%eax,4(%esp)
        +	movl	%ebx,8(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edx,16(%esp)
        +.align	16
        +.L006loop:
        +	xorl	%esi,%eax
        +	xorl	-4(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	-16(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	-12(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	-24(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	-20(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	-32(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	-28(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	-40(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	-36(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	-48(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	-44(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	-56(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	subl	$64,%edi
        +	cmpl	20(%esp),%edi
        +	je	.L007done
        +	andl	%eax,%esi
        +	movl	16(%esp),%edx
        +	roll	$1,%esi
        +	movl	%edx,%ecx
        +	xorl	%esi,%ebx
        +	orl	4(%edi),%ecx
        +	movl	%ebx,8(%esp)
        +	xorl	12(%esp),%ecx
        +	movl	12(%edi),%esi
        +	movl	%ecx,12(%esp)
        +	orl	%ebx,%esi
        +	andl	(%edi),%ecx
        +	xorl	%esi,%eax
        +	roll	$1,%ecx
        +	movl	%eax,4(%esp)
        +	xorl	%ecx,%edx
        +	movl	-8(%edi),%esi
        +	movl	%edx,16(%esp)
        +	jmp	.L006loop
        +.align	8
        +.L007done:
        +	movl	%eax,%ecx
        +	movl	%ebx,%edx
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	12(%edi),%edx
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	ret
        +.size	_x86_Camellia_decrypt,.-_x86_Camellia_decrypt
        +.globl	Camellia_Ekeygen
        +.type	Camellia_Ekeygen,@function
        +.align	16
        +Camellia_Ekeygen:
        +.L_Camellia_Ekeygen_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	subl	$16,%esp
        +	movl	36(%esp),%ebp
        +	movl	40(%esp),%esi
        +	movl	44(%esp),%edi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	cmpl	$128,%ebp
        +	je	.L0081st128
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	cmpl	$192,%ebp
        +	je	.L0091st192
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	jmp	.L0101st256
        +.align	4
        +.L0091st192:
        +	movl	%eax,%ecx
        +	movl	%ebx,%edx
        +	notl	%ecx
        +	notl	%edx
        +.align	4
        +.L0101st256:
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,32(%edi)
        +	movl	%ebx,36(%edi)
        +	movl	%ecx,40(%edi)
        +	movl	%edx,44(%edi)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +.align	4
        +.L0081st128:
        +	call	.L011pic_point
        +.L011pic_point:
        +	popl	%ebp
        +	leal	.LCamellia_SBOX-.L011pic_point(%ebp),%ebp
        +	leal	.LCamellia_SIGMA-.LCamellia_SBOX(%ebp),%edi
        +	movl	(%edi),%esi
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	xorl	%esi,%eax
        +	xorl	4(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	12(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	8(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	8(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%esp)
        +	xorl	%esi,%ecx
        +	xorl	12(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	4(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	16(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,(%esp)
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	44(%esp),%esi
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	xorl	12(%esi),%edx
        +	movl	16(%edi),%esi
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	xorl	%esi,%eax
        +	xorl	20(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	12(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	8(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	24(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%esp)
        +	xorl	%esi,%ecx
        +	xorl	28(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	4(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	32(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,(%esp)
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	36(%esp),%esi
        +	cmpl	$128,%esi
        +	jne	.L0122nd256
        +	movl	44(%esp),%edi
        +	leal	128(%edi),%edi
        +	movl	%eax,-112(%edi)
        +	movl	%ebx,-108(%edi)
        +	movl	%ecx,-104(%edi)
        +	movl	%edx,-100(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-80(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-76(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-72(%edi)
        +	movl	%edx,-68(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-64(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-60(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-56(%edi)
        +	movl	%edx,-52(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-32(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-28(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-16(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-12(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-8(%edi)
        +	movl	%edx,-4(%edi)
        +	movl	%ebx,%ebp
        +	shll	$2,%ebx
        +	movl	%ecx,%esi
        +	shrl	$30,%esi
        +	shll	$2,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$2,%edx
        +	movl	%ebx,32(%edi)
        +	shrl	$30,%esi
        +	orl	%esi,%ecx
        +	shrl	$30,%ebp
        +	movl	%eax,%esi
        +	shrl	$30,%esi
        +	movl	%ecx,36(%edi)
        +	shll	$2,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,40(%edi)
        +	movl	%eax,44(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,64(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,68(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,72(%edi)
        +	movl	%eax,76(%edi)
        +	movl	-128(%edi),%ebx
        +	movl	-124(%edi),%ecx
        +	movl	-120(%edi),%edx
        +	movl	-116(%edi),%eax
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	movl	%ebx,-96(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	movl	%ecx,-92(%edi)
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-88(%edi)
        +	movl	%eax,-84(%edi)
        +	movl	%ebx,%ebp
        +	shll	$30,%ebx
        +	movl	%ecx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$30,%edx
        +	movl	%ebx,-48(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ecx
        +	shrl	$2,%ebp
        +	movl	%eax,%esi
        +	shrl	$2,%esi
        +	movl	%ecx,-44(%edi)
        +	shll	$30,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-40(%edi)
        +	movl	%eax,-36(%edi)
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-24(%edi)
        +	movl	%eax,-20(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,4(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,8(%edi)
        +	movl	%eax,12(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,16(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,20(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,24(%edi)
        +	movl	%eax,28(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,48(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,52(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,56(%edi)
        +	movl	%eax,60(%edi)
        +	movl	$3,%eax
        +	jmp	.L013done
        +.align	16
        +.L0122nd256:
        +	movl	44(%esp),%esi
        +	movl	%eax,48(%esi)
        +	movl	%ebx,52(%esi)
        +	movl	%ecx,56(%esi)
        +	movl	%edx,60(%esi)
        +	xorl	32(%esi),%eax
        +	xorl	36(%esi),%ebx
        +	xorl	40(%esi),%ecx
        +	xorl	44(%esi),%edx
        +	movl	32(%edi),%esi
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	xorl	%esi,%eax
        +	xorl	36(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	12(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	8(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	40(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%esp)
        +	xorl	%esi,%ecx
        +	xorl	44(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	4(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	48(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,(%esp)
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	44(%esp),%edi
        +	leal	128(%edi),%edi
        +	movl	%eax,-112(%edi)
        +	movl	%ebx,-108(%edi)
        +	movl	%ecx,-104(%edi)
        +	movl	%edx,-100(%edi)
        +	movl	%eax,%ebp
        +	shll	$30,%eax
        +	movl	%ebx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$30,%ecx
        +	movl	%eax,-48(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ebx
        +	shrl	$2,%ebp
        +	movl	%edx,%esi
        +	shrl	$2,%esi
        +	movl	%ebx,-44(%edi)
        +	shll	$30,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-40(%edi)
        +	movl	%edx,-36(%edi)
        +	movl	%eax,%ebp
        +	shll	$30,%eax
        +	movl	%ebx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$30,%ecx
        +	movl	%eax,32(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ebx
        +	shrl	$2,%ebp
        +	movl	%edx,%esi
        +	shrl	$2,%esi
        +	movl	%ebx,36(%edi)
        +	shll	$30,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,40(%edi)
        +	movl	%edx,44(%edi)
        +	movl	%ebx,%ebp
        +	shll	$19,%ebx
        +	movl	%ecx,%esi
        +	shrl	$13,%esi
        +	shll	$19,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$19,%edx
        +	movl	%ebx,128(%edi)
        +	shrl	$13,%esi
        +	orl	%esi,%ecx
        +	shrl	$13,%ebp
        +	movl	%eax,%esi
        +	shrl	$13,%esi
        +	movl	%ecx,132(%edi)
        +	shll	$19,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,136(%edi)
        +	movl	%eax,140(%edi)
        +	movl	-96(%edi),%ebx
        +	movl	-92(%edi),%ecx
        +	movl	-88(%edi),%edx
        +	movl	-84(%edi),%eax
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	movl	%ebx,-96(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	movl	%ecx,-92(%edi)
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-88(%edi)
        +	movl	%eax,-84(%edi)
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	movl	%ebx,-64(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	movl	%ecx,-60(%edi)
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-56(%edi)
        +	movl	%eax,-52(%edi)
        +	movl	%ebx,%ebp
        +	shll	$30,%ebx
        +	movl	%ecx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$30,%edx
        +	movl	%ebx,16(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ecx
        +	shrl	$2,%ebp
        +	movl	%eax,%esi
        +	shrl	$2,%esi
        +	movl	%ecx,20(%edi)
        +	shll	$30,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,24(%edi)
        +	movl	%eax,28(%edi)
        +	movl	%ecx,%ebp
        +	shll	$2,%ecx
        +	movl	%edx,%esi
        +	shrl	$30,%esi
        +	shll	$2,%edx
        +	orl	%esi,%ecx
        +	movl	%eax,%esi
        +	shll	$2,%eax
        +	movl	%ecx,80(%edi)
        +	shrl	$30,%esi
        +	orl	%esi,%edx
        +	shrl	$30,%ebp
        +	movl	%ebx,%esi
        +	shrl	$30,%esi
        +	movl	%edx,84(%edi)
        +	shll	$2,%ebx
        +	orl	%esi,%eax
        +	orl	%ebp,%ebx
        +	movl	%eax,88(%edi)
        +	movl	%ebx,92(%edi)
        +	movl	-80(%edi),%ecx
        +	movl	-76(%edi),%edx
        +	movl	-72(%edi),%eax
        +	movl	-68(%edi),%ebx
        +	movl	%ecx,%ebp
        +	shll	$15,%ecx
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	movl	%eax,%esi
        +	shll	$15,%eax
        +	movl	%ecx,-80(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%edx
        +	shrl	$17,%ebp
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	movl	%edx,-76(%edi)
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	orl	%ebp,%ebx
        +	movl	%eax,-72(%edi)
        +	movl	%ebx,-68(%edi)
        +	movl	%ecx,%ebp
        +	shll	$30,%ecx
        +	movl	%edx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%edx
        +	orl	%esi,%ecx
        +	movl	%eax,%esi
        +	shll	$30,%eax
        +	movl	%ecx,-16(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%edx
        +	shrl	$2,%ebp
        +	movl	%ebx,%esi
        +	shrl	$2,%esi
        +	movl	%edx,-12(%edi)
        +	shll	$30,%ebx
        +	orl	%esi,%eax
        +	orl	%ebp,%ebx
        +	movl	%eax,-8(%edi)
        +	movl	%ebx,-4(%edi)
        +	movl	%edx,64(%edi)
        +	movl	%eax,68(%edi)
        +	movl	%ebx,72(%edi)
        +	movl	%ecx,76(%edi)
        +	movl	%edx,%ebp
        +	shll	$17,%edx
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	movl	%ebx,%esi
        +	shll	$17,%ebx
        +	movl	%edx,96(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%eax
        +	shrl	$15,%ebp
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	movl	%eax,100(%edi)
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	orl	%ebp,%ecx
        +	movl	%ebx,104(%edi)
        +	movl	%ecx,108(%edi)
        +	movl	-128(%edi),%edx
        +	movl	-124(%edi),%eax
        +	movl	-120(%edi),%ebx
        +	movl	-116(%edi),%ecx
        +	movl	%eax,%ebp
        +	shll	$13,%eax
        +	movl	%ebx,%esi
        +	shrl	$19,%esi
        +	shll	$13,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$13,%ecx
        +	movl	%eax,-32(%edi)
        +	shrl	$19,%esi
        +	orl	%esi,%ebx
        +	shrl	$19,%ebp
        +	movl	%edx,%esi
        +	shrl	$19,%esi
        +	movl	%ebx,-28(%edi)
        +	shll	$13,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-24(%edi)
        +	movl	%edx,-20(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,4(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	%eax,%ebp
        +	shll	$17,%eax
        +	movl	%ebx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$17,%ecx
        +	movl	%eax,48(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ebx
        +	shrl	$15,%ebp
        +	movl	%edx,%esi
        +	shrl	$15,%esi
        +	movl	%ebx,52(%edi)
        +	shll	$17,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,56(%edi)
        +	movl	%edx,60(%edi)
        +	movl	%ebx,%ebp
        +	shll	$2,%ebx
        +	movl	%ecx,%esi
        +	shrl	$30,%esi
        +	shll	$2,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$2,%edx
        +	movl	%ebx,112(%edi)
        +	shrl	$30,%esi
        +	orl	%esi,%ecx
        +	shrl	$30,%ebp
        +	movl	%eax,%esi
        +	shrl	$30,%esi
        +	movl	%ecx,116(%edi)
        +	shll	$2,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,120(%edi)
        +	movl	%eax,124(%edi)
        +	movl	$4,%eax
        +.L013done:
        +	leal	144(%edi),%edx
        +	addl	$16,%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	Camellia_Ekeygen,.-.L_Camellia_Ekeygen_begin
        +.globl	private_Camellia_set_key
        +.type	private_Camellia_set_key,@function
        +.align	16
        +private_Camellia_set_key:
        +.L_private_Camellia_set_key_begin:
        +	pushl	%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%edx
        +	movl	$-1,%eax
        +	testl	%ecx,%ecx
        +	jz	.L014done
        +	testl	%edx,%edx
        +	jz	.L014done
        +	movl	$-2,%eax
        +	cmpl	$256,%ebx
        +	je	.L015arg_ok
        +	cmpl	$192,%ebx
        +	je	.L015arg_ok
        +	cmpl	$128,%ebx
        +	jne	.L014done
        +.align	4
        +.L015arg_ok:
        +	pushl	%edx
        +	pushl	%ecx
        +	pushl	%ebx
        +	call	.L_Camellia_Ekeygen_begin
        +	addl	$12,%esp
        +	movl	%eax,(%edx)
        +	xorl	%eax,%eax
        +.align	4
        +.L014done:
        +	popl	%ebx
        +	ret
        +.size	private_Camellia_set_key,.-.L_private_Camellia_set_key_begin
        +.align	64
        +.LCamellia_SIGMA:
        +.long	2694735487,1003262091,3061508184,1286239154,3337565999,3914302142,1426019237,4057165596,283453434,3731369245,2958461122,3018244605,0,0,0,0
        +.align	64
        +.LCamellia_SBOX:
        +.long	1886416896,1886388336
        +.long	2189591040,741081132
        +.long	741092352,3014852787
        +.long	3974949888,3233808576
        +.long	3014898432,3840147684
        +.long	656877312,1465319511
        +.long	3233857536,3941204202
        +.long	3857048832,2930639022
        +.long	3840205824,589496355
        +.long	2240120064,1802174571
        +.long	1465341696,1162149957
        +.long	892679424,2779054245
        +.long	3941263872,3991732461
        +.long	202116096,1330577487
        +.long	2930683392,488439837
        +.long	1094795520,2459041938
        +.long	589505280,2256928902
        +.long	4025478912,2947481775
        +.long	1802201856,2088501372
        +.long	2475922176,522125343
        +.long	1162167552,1044250686
        +.long	421075200,3705405660
        +.long	2779096320,1583218782
        +.long	555819264,185270283
        +.long	3991792896,2795896998
        +.long	235802112,960036921
        +.long	1330597632,3587506389
        +.long	1313754624,1566376029
        +.long	488447232,3654877401
        +.long	1701143808,1515847770
        +.long	2459079168,1364262993
        +.long	3183328512,1819017324
        +.long	2256963072,2341142667
        +.long	3099113472,2593783962
        +.long	2947526400,4227531003
        +.long	2408550144,2964324528
        +.long	2088532992,1953759348
        +.long	3958106880,724238379
        +.long	522133248,4042260720
        +.long	3469659648,2223243396
        +.long	1044266496,3755933919
        +.long	808464384,3419078859
        +.long	3705461760,875823156
        +.long	1600085760,1987444854
        +.long	1583242752,1835860077
        +.long	3318072576,2846425257
        +.long	185273088,3520135377
        +.long	437918208,67371012
        +.long	2795939328,336855060
        +.long	3789676800,976879674
        +.long	960051456,3739091166
        +.long	3402287616,286326801
        +.long	3587560704,842137650
        +.long	1195853568,2627469468
        +.long	1566399744,1397948499
        +.long	1027423488,4075946226
        +.long	3654932736,4278059262
        +.long	16843008,3486449871
        +.long	1515870720,3284336835
        +.long	3604403712,2054815866
        +.long	1364283648,606339108
        +.long	1448498688,3907518696
        +.long	1819044864,1616904288
        +.long	1296911616,1768489065
        +.long	2341178112,2863268010
        +.long	218959104,2694840480
        +.long	2593823232,2711683233
        +.long	1717986816,1650589794
        +.long	4227595008,1414791252
        +.long	3435973632,505282590
        +.long	2964369408,3772776672
        +.long	757935360,1684275300
        +.long	1953788928,269484048
        +.long	303174144,0
        +.long	724249344,2745368739
        +.long	538976256,1970602101
        +.long	4042321920,2324299914
        +.long	2981212416,3873833190
        +.long	2223277056,151584777
        +.long	2576980224,3722248413
        +.long	3755990784,2273771655
        +.long	1280068608,2206400643
        +.long	3419130624,3452764365
        +.long	3267543552,2425356432
        +.long	875836416,1936916595
        +.long	2122219008,4143317238
        +.long	1987474944,2644312221
        +.long	84215040,3216965823
        +.long	1835887872,1381105746
        +.long	3082270464,3638034648
        +.long	2846468352,3368550600
        +.long	825307392,3334865094
        +.long	3520188672,2172715137
        +.long	387389184,1869545583
        +.long	67372032,320012307
        +.long	3621246720,1667432547
        +.long	336860160,3924361449
        +.long	1482184704,2812739751
        +.long	976894464,2677997727
        +.long	1633771776,3166437564
        +.long	3739147776,690552873
        +.long	454761216,4193845497
        +.long	286331136,791609391
        +.long	471604224,3031695540
        +.long	842150400,2021130360
        +.long	252645120,101056518
        +.long	2627509248,3890675943
        +.long	370546176,1903231089
        +.long	1397969664,3570663636
        +.long	404232192,2880110763
        +.long	4076007936,2290614408
        +.long	572662272,2374828173
        +.long	4278124032,1920073842
        +.long	1145324544,3115909305
        +.long	3486502656,4177002744
        +.long	2998055424,2896953516
        +.long	3284386560,909508662
        +.long	3048584448,707395626
        +.long	2054846976,1010565180
        +.long	2442236160,4059103473
        +.long	606348288,1077936192
        +.long	134744064,3553820883
        +.long	3907577856,3149594811
        +.long	2829625344,1128464451
        +.long	1616928768,353697813
        +.long	4244438016,2913796269
        +.long	1768515840,2004287607
        +.long	1347440640,2155872384
        +.long	2863311360,2189557890
        +.long	3503345664,3974889708
        +.long	2694881280,656867367
        +.long	2105376000,3856990437
        +.long	2711724288,2240086149
        +.long	2307492096,892665909
        +.long	1650614784,202113036
        +.long	2543294208,1094778945
        +.long	1414812672,4025417967
        +.long	1532713728,2475884691
        +.long	505290240,421068825
        +.long	2509608192,555810849
        +.long	3772833792,235798542
        +.long	4294967040,1313734734
        +.long	1684300800,1701118053
        +.long	3537031680,3183280317
        +.long	269488128,3099066552
        +.long	3301229568,2408513679
        +.long	0,3958046955
        +.long	1212696576,3469607118
        +.long	2745410304,808452144
        +.long	4160222976,1600061535
        +.long	1970631936,3318022341
        +.long	3688618752,437911578
        +.long	2324335104,3789619425
        +.long	50529024,3402236106
        +.long	3873891840,1195835463
        +.long	3671775744,1027407933
        +.long	151587072,16842753
        +.long	1061109504,3604349142
        +.long	3722304768,1448476758
        +.long	2492765184,1296891981
        +.long	2273806080,218955789
        +.long	1549556736,1717960806
        +.long	2206434048,3435921612
        +.long	33686016,757923885
        +.long	3452816640,303169554
        +.long	1246382592,538968096
        +.long	2425393152,2981167281
        +.long	858993408,2576941209
        +.long	1936945920,1280049228
        +.long	1734829824,3267494082
        +.long	4143379968,2122186878
        +.long	4092850944,84213765
        +.long	2644352256,3082223799
        +.long	2139062016,825294897
        +.long	3217014528,387383319
        +.long	3806519808,3621191895
        +.long	1381126656,1482162264
        +.long	2610666240,1633747041
        +.long	3638089728,454754331
        +.long	640034304,471597084
        +.long	3368601600,252641295
        +.long	926365440,370540566
        +.long	3334915584,404226072
        +.long	993737472,572653602
        +.long	2172748032,1145307204
        +.long	2526451200,2998010034
        +.long	1869573888,3048538293
        +.long	1263225600,2442199185
        +.long	320017152,134742024
        +.long	3200171520,2829582504
        +.long	1667457792,4244373756
        +.long	774778368,1347420240
        +.long	3924420864,3503292624
        +.long	2038003968,2105344125
        +.long	2812782336,2307457161
        +.long	2358021120,2543255703
        +.long	2678038272,1532690523
        +.long	1852730880,2509570197
        +.long	3166485504,4294902015
        +.long	2391707136,3536978130
        +.long	690563328,3301179588
        +.long	4126536960,1212678216
        +.long	4193908992,4160159991
        +.long	3065427456,3688562907
        +.long	791621376,50528259
        +.long	4261281024,3671720154
        +.long	3031741440,1061093439
        +.long	1499027712,2492727444
        +.long	2021160960,1549533276
        +.long	2560137216,33685506
        +.long	101058048,1246363722
        +.long	1785358848,858980403
        +.long	3890734848,1734803559
        +.long	1179010560,4092788979
        +.long	1903259904,2139029631
        +.long	3132799488,3806462178
        +.long	3570717696,2610626715
        +.long	623191296,640024614
        +.long	2880154368,926351415
        +.long	1111638528,993722427
        +.long	2290649088,2526412950
        +.long	2728567296,1263206475
        +.long	2374864128,3200123070
        +.long	4210752000,774766638
        +.long	1920102912,2037973113
        +.long	117901056,2357985420
        +.long	3115956480,1852702830
        +.long	1431655680,2391670926
        +.long	4177065984,4126474485
        +.long	4008635904,3065381046
        +.long	2896997376,4261216509
        +.long	168430080,1499005017
        +.long	909522432,2560098456
        +.long	1229539584,1785331818
        +.long	707406336,1178992710
        +.long	1751672832,3132752058
        +.long	1010580480,623181861
        +.long	943208448,1111621698
        +.long	4059164928,2728525986
        +.long	2762253312,4210688250
        +.long	1077952512,117899271
        +.long	673720320,1431634005
        +.long	3553874688,4008575214
        +.long	2071689984,168427530
        +.long	3149642496,1229520969
        +.long	3385444608,1751646312
        +.long	1128481536,943194168
        +.long	3250700544,2762211492
        +.long	353703168,673710120
        +.long	3823362816,2071658619
        +.long	2913840384,3385393353
        +.long	4109693952,3250651329
        +.long	2004317952,3823304931
        +.long	3351758592,4109631732
        +.long	2155905024,3351707847
        +.long	2661195264,2661154974
        +.long	14737632,939538488
        +.long	328965,1090535745
        +.long	5789784,369104406
        +.long	14277081,1979741814
        +.long	6776679,3640711641
        +.long	5131854,2466288531
        +.long	8487297,1610637408
        +.long	13355979,4060148466
        +.long	13224393,1912631922
        +.long	723723,3254829762
        +.long	11447982,2868947883
        +.long	6974058,2583730842
        +.long	14013909,1962964341
        +.long	1579032,100664838
        +.long	6118749,1459640151
        +.long	8553090,2684395680
        +.long	4605510,2432733585
        +.long	14671839,4144035831
        +.long	14079702,3036722613
        +.long	2565927,3372272073
        +.long	9079434,2717950626
        +.long	3289650,2348846220
        +.long	4934475,3523269330
        +.long	4342338,2415956112
        +.long	14408667,4127258358
        +.long	1842204,117442311
        +.long	10395294,2801837991
        +.long	10263708,654321447
        +.long	3815994,2382401166
        +.long	13290186,2986390194
        +.long	2434341,1224755529
        +.long	8092539,3724599006
        +.long	855309,1124090691
        +.long	7434609,1543527516
        +.long	6250335,3607156695
        +.long	2039583,3338717127
        +.long	16316664,1040203326
        +.long	14145495,4110480885
        +.long	4079166,2399178639
        +.long	10329501,1728079719
        +.long	8158332,520101663
        +.long	6316128,402659352
        +.long	12171705,1845522030
        +.long	12500670,2936057775
        +.long	12369084,788541231
        +.long	9145227,3791708898
        +.long	1447446,2231403909
        +.long	3421236,218107149
        +.long	5066061,1392530259
        +.long	12829635,4026593520
        +.long	7500402,2617285788
        +.long	9803157,1694524773
        +.long	11250603,3925928682
        +.long	9342606,2734728099
        +.long	12237498,2919280302
        +.long	8026746,2650840734
        +.long	11776947,3959483628
        +.long	131586,2147516544
        +.long	11842740,754986285
        +.long	11382189,1795189611
        +.long	10658466,2818615464
        +.long	11316396,721431339
        +.long	14211288,905983542
        +.long	10132122,2785060518
        +.long	1513239,3305162181
        +.long	1710618,2248181382
        +.long	3487029,1291865421
        +.long	13421772,855651123
        +.long	16250871,4244700669
        +.long	10066329,1711302246
        +.long	6381921,1476417624
        +.long	5921370,2516620950
        +.long	15263976,973093434
        +.long	2368548,150997257
        +.long	5658198,2499843477
        +.long	4210752,268439568
        +.long	14803425,2013296760
        +.long	6513507,3623934168
        +.long	592137,1107313218
        +.long	3355443,3422604492
        +.long	12566463,4009816047
        +.long	10000536,637543974
        +.long	9934743,3842041317
        +.long	8750469,1627414881
        +.long	6842472,436214298
        +.long	16579836,1056980799
        +.long	15527148,989870907
        +.long	657930,2181071490
        +.long	14342874,3053500086
        +.long	7303023,3674266587
        +.long	5460819,3556824276
        +.long	6447714,2550175896
        +.long	10724259,3892373736
        +.long	3026478,2332068747
        +.long	526344,33554946
        +.long	11513775,3942706155
        +.long	2631720,167774730
        +.long	11579568,738208812
        +.long	7631988,486546717
        +.long	12763842,2952835248
        +.long	12434877,1862299503
        +.long	3552822,2365623693
        +.long	2236962,2281736328
        +.long	3684408,234884622
        +.long	6579300,419436825
        +.long	1973790,2264958855
        +.long	3750201,1308642894
        +.long	2894892,184552203
        +.long	10921638,2835392937
        +.long	3158064,201329676
        +.long	15066597,2030074233
        +.long	4473924,285217041
        +.long	16645629,2130739071
        +.long	8947848,570434082
        +.long	10461087,3875596263
        +.long	6645093,1493195097
        +.long	8882055,3774931425
        +.long	7039851,3657489114
        +.long	16053492,1023425853
        +.long	2302755,3355494600
        +.long	4737096,301994514
        +.long	1052688,67109892
        +.long	13750737,1946186868
        +.long	5329233,1409307732
        +.long	12632256,805318704
        +.long	16382457,2113961598
        +.long	13816530,3019945140
        +.long	10526880,671098920
        +.long	5592405,1426085205
        +.long	10592673,1744857192
        +.long	4276545,1342197840
        +.long	16448250,3187719870
        +.long	4408131,3489714384
        +.long	1250067,3288384708
        +.long	12895428,822096177
        +.long	3092271,3405827019
        +.long	11053224,704653866
        +.long	11974326,2902502829
        +.long	3947580,251662095
        +.long	2829099,3389049546
        +.long	12698049,1879076976
        +.long	16777215,4278255615
        +.long	13158600,838873650
        +.long	10855845,1761634665
        +.long	2105376,134219784
        +.long	9013641,1644192354
        +.long	0,0
        +.long	9474192,603989028
        +.long	4671303,3506491857
        +.long	15724527,4211145723
        +.long	15395562,3120609978
        +.long	12040119,3976261101
        +.long	1381653,1157645637
        +.long	394758,2164294017
        +.long	13487565,1929409395
        +.long	11908533,1828744557
        +.long	1184274,2214626436
        +.long	8289918,2667618207
        +.long	12303291,3993038574
        +.long	2697513,1241533002
        +.long	986895,3271607235
        +.long	12105912,771763758
        +.long	460551,3238052289
        +.long	263172,16777473
        +.long	10197915,3858818790
        +.long	9737364,620766501
        +.long	2171169,1207978056
        +.long	6710886,2566953369
        +.long	15132390,3103832505
        +.long	13553358,3003167667
        +.long	15592941,2063629179
        +.long	15198183,4177590777
        +.long	3881787,3456159438
        +.long	16711422,3204497343
        +.long	8355711,3741376479
        +.long	12961221,1895854449
        +.long	10790052,687876393
        +.long	3618615,3439381965
        +.long	11645361,1811967084
        +.long	5000268,318771987
        +.long	9539985,1677747300
        +.long	7237230,2600508315
        +.long	9276813,1660969827
        +.long	7763574,2634063261
        +.long	197379,3221274816
        +.long	2960685,1258310475
        +.long	14606046,3070277559
        +.long	9868950,2768283045
        +.long	2500134,2298513801
        +.long	8224125,1593859935
        +.long	13027014,2969612721
        +.long	6052956,385881879
        +.long	13882323,4093703412
        +.long	15921906,3154164924
        +.long	5197647,3540046803
        +.long	1644825,1174423110
        +.long	4144959,3472936911
        +.long	14474460,922761015
        +.long	7960953,1577082462
        +.long	1907997,1191200583
        +.long	5395026,2483066004
        +.long	15461355,4194368250
        +.long	15987699,4227923196
        +.long	7171437,1526750043
        +.long	6184542,2533398423
        +.long	16514043,4261478142
        +.long	6908265,1509972570
        +.long	11711154,2885725356
        +.long	15790320,1006648380
        +.long	3223857,1275087948
        +.long	789516,50332419
        +.long	13948116,889206069
        +.long	13619151,4076925939
        +.long	9211020,587211555
        +.long	14869218,3087055032
        +.long	7697781,1560304989
        +.long	11119017,1778412138
        +.long	4868682,2449511058
        +.long	5723991,3573601749
        +.long	8684676,553656609
        +.long	1118481,1140868164
        +.long	4539717,1358975313
        +.long	1776411,3321939654
        +.long	16119285,2097184125
        +.long	15000804,956315961
        +.long	921102,2197848963
        +.long	7566195,3691044060
        +.long	11184810,2852170410
        +.long	15856113,2080406652
        +.long	14540253,1996519287
        +.long	5855577,1442862678
        +.long	1315860,83887365
        +.long	7105644,452991771
        +.long	9605778,2751505572
        +.long	5526612,352326933
        +.long	13684944,872428596
        +.long	7895160,503324190
        +.long	7368816,469769244
        +.long	14935011,4160813304
        +.long	4802889,1375752786
        +.long	8421504,536879136
        +.long	5263440,335549460
        +.long	10987431,3909151209
        +.long	16185078,3170942397
        +.long	7829367,3707821533
        +.long	9671571,3825263844
        +.long	8816262,2701173153
        +.long	8618883,3758153952
        +.long	2763306,2315291274
        +.long	13092807,4043370993
        +.long	5987163,3590379222
        +.long	15329769,2046851706
        +.long	15658734,3137387451
        +.long	9408399,3808486371
        +.long	65793,1073758272
        +.long	4013373,1325420367
        +.globl	Camellia_cbc_encrypt
        +.type	Camellia_cbc_encrypt,@function
        +.align	16
        +Camellia_cbc_encrypt:
        +.L_Camellia_cbc_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ecx
        +	cmpl	$0,%ecx
        +	je	.L016enc_out
        +	pushfl
        +	cld
        +	movl	24(%esp),%eax
        +	movl	28(%esp),%ebx
        +	movl	36(%esp),%edx
        +	movl	40(%esp),%ebp
        +	leal	-64(%esp),%esi
        +	andl	$-64,%esi
        +	leal	-127(%edx),%edi
        +	subl	%esi,%edi
        +	negl	%edi
        +	andl	$960,%edi
        +	subl	%edi,%esi
        +	movl	44(%esp),%edi
        +	xchgl	%esi,%esp
        +	addl	$4,%esp
        +	movl	%esi,20(%esp)
        +	movl	%eax,24(%esp)
        +	movl	%ebx,28(%esp)
        +	movl	%ecx,32(%esp)
        +	movl	%edx,36(%esp)
        +	movl	%ebp,40(%esp)
        +	call	.L017pic_point
        +.L017pic_point:
        +	popl	%ebp
        +	leal	.LCamellia_SBOX-.L017pic_point(%ebp),%ebp
        +	movl	$32,%esi
        +.align	4
        +.L018prefetch_sbox:
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +	leal	128(%ebp),%ebp
        +	decl	%esi
        +	jnz	.L018prefetch_sbox
        +	movl	36(%esp),%eax
        +	subl	$4096,%ebp
        +	movl	24(%esp),%esi
        +	movl	272(%eax),%edx
        +	cmpl	$0,%edi
        +	je	.L019DECRYPT
        +	movl	32(%esp),%ecx
        +	movl	40(%esp),%edi
        +	shll	$6,%edx
        +	leal	(%eax,%edx,1),%edx
        +	movl	%edx,16(%esp)
        +	testl	$4294967280,%ecx
        +	jz	.L020enc_tail
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +.align	4
        +.L021enc_loop:
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	bswap	%eax
        +	xorl	12(%esi),%edx
        +	bswap	%ebx
        +	movl	36(%esp),%edi
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_encrypt
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	movl	%eax,(%edi)
        +	bswap	%edx
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	32(%esp),%ecx
        +	leal	16(%esi),%esi
        +	movl	%esi,24(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,28(%esp)
        +	subl	$16,%ecx
        +	testl	$4294967280,%ecx
        +	movl	%ecx,32(%esp)
        +	jnz	.L021enc_loop
        +	testl	$15,%ecx
        +	jnz	.L020enc_tail
        +	movl	40(%esp),%esi
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	20(%esp),%esp
        +	popfl
        +.L016enc_out:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4
        +.L020enc_tail:
        +	movl	%edi,%eax
        +	movl	28(%esp),%edi
        +	pushl	%eax
        +	movl	$16,%ebx
        +	subl	%ecx,%ebx
        +	cmpl	%esi,%edi
        +	je	.L022enc_in_place
        +.align	4
        +.long	2767451785
        +	jmp	.L023enc_skip_in_place
        +.L022enc_in_place:
        +	leal	(%edi,%ecx,1),%edi
        +.L023enc_skip_in_place:
        +	movl	%ebx,%ecx
        +	xorl	%eax,%eax
        +.align	4
        +.long	2868115081
        +	popl	%edi
        +	movl	28(%esp),%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	$16,32(%esp)
        +	jmp	.L021enc_loop
        +.align	16
        +.L019DECRYPT:
        +	shll	$6,%edx
        +	leal	(%eax,%edx,1),%edx
        +	movl	%eax,16(%esp)
        +	movl	%edx,36(%esp)
        +	cmpl	28(%esp),%esi
        +	je	.L024dec_in_place
        +	movl	40(%esp),%edi
        +	movl	%edi,44(%esp)
        +.align	4
        +.L025dec_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	movl	36(%esp),%edi
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_decrypt
        +	movl	44(%esp),%edi
        +	movl	32(%esp),%esi
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	xorl	(%edi),%eax
        +	bswap	%edx
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	subl	$16,%esi
        +	jc	.L026dec_partial
        +	movl	%esi,32(%esp)
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	%esi,44(%esp)
        +	leal	16(%esi),%esi
        +	movl	%esi,24(%esp)
        +	leal	16(%edi),%edi
        +	movl	%edi,28(%esp)
        +	jnz	.L025dec_loop
        +	movl	44(%esp),%edi
        +.L027dec_end:
        +	movl	40(%esp),%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	jmp	.L028dec_out
        +.align	4
        +.L026dec_partial:
        +	leal	44(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	leal	16(%esi),%ecx
        +	movl	%edi,%esi
        +	movl	28(%esp),%edi
        +.long	2767451785
        +	movl	24(%esp),%edi
        +	jmp	.L027dec_end
        +.align	4
        +.L024dec_in_place:
        +.L029dec_in_place_loop:
        +	leal	44(%esp),%edi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	bswap	%eax
        +	movl	%edx,12(%edi)
        +	bswap	%ebx
        +	movl	36(%esp),%edi
        +	bswap	%ecx
        +	bswap	%edx
        +	call	_x86_Camellia_decrypt
        +	movl	40(%esp),%edi
        +	movl	28(%esp),%esi
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	xorl	(%edi),%eax
        +	bswap	%edx
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	leal	16(%esi),%esi
        +	movl	%esi,28(%esp)
        +	leal	44(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	24(%esp),%esi
        +	leal	16(%esi),%esi
        +	movl	%esi,24(%esp)
        +	movl	32(%esp),%ecx
        +	subl	$16,%ecx
        +	jc	.L030dec_in_place_partial
        +	movl	%ecx,32(%esp)
        +	jnz	.L029dec_in_place_loop
        +	jmp	.L028dec_out
        +.align	4
        +.L030dec_in_place_partial:
        +	movl	28(%esp),%edi
        +	leal	44(%esp),%esi
        +	leal	(%edi,%ecx,1),%edi
        +	leal	16(%esi,%ecx,1),%esi
        +	negl	%ecx
        +.long	2767451785
        +.align	4
        +.L028dec_out:
        +	movl	20(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	Camellia_cbc_encrypt,.-.L_Camellia_cbc_encrypt_begin
        +.byte	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54
        +.byte	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +.byte	115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-elf-gas/cast/cast-586.s b/vendor/openssl/asm/x86-elf-gas/cast/cast-586.s
        new file mode 100644
        index 000000000..3ef7fe32b
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/cast/cast-586.s
        @@ -0,0 +1,933 @@
        +.file	"cast-586.s"
        +.text
        +.globl	CAST_encrypt
        +.type	CAST_encrypt,@function
        +.align	16
        +CAST_encrypt:
        +.L_CAST_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ebp
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +
        +	movl	128(%ebp),%eax
        +	pushl	%eax
        +	xorl	%eax,%eax
        +
        +	movl	(%ebp),%edx
        +	movl	4(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	8(%ebp),%edx
        +	movl	12(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	16(%ebp),%edx
        +	movl	20(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	24(%ebp),%edx
        +	movl	28(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	32(%ebp),%edx
        +	movl	36(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	40(%ebp),%edx
        +	movl	44(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	48(%ebp),%edx
        +	movl	52(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	56(%ebp),%edx
        +	movl	60(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	64(%ebp),%edx
        +	movl	68(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	72(%ebp),%edx
        +	movl	76(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	80(%ebp),%edx
        +	movl	84(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	88(%ebp),%edx
        +	movl	92(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	popl	%edx
        +	orl	%edx,%edx
        +	jnz	.L000cast_enc_done
        +
        +	movl	96(%ebp),%edx
        +	movl	100(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	104(%ebp),%edx
        +	movl	108(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	112(%ebp),%edx
        +	movl	116(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	120(%ebp),%edx
        +	movl	124(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +.L000cast_enc_done:
        +	nop
        +	movl	20(%esp),%eax
        +	movl	%edi,4(%eax)
        +	movl	%esi,(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	CAST_encrypt,.-.L_CAST_encrypt_begin
        +.globl	CAST_decrypt
        +.type	CAST_decrypt,@function
        +.align	16
        +CAST_decrypt:
        +.L_CAST_decrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ebp
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +
        +	movl	128(%ebp),%eax
        +	orl	%eax,%eax
        +	jnz	.L001cast_dec_skip
        +	xorl	%eax,%eax
        +
        +	movl	120(%ebp),%edx
        +	movl	124(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	112(%ebp),%edx
        +	movl	116(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	104(%ebp),%edx
        +	movl	108(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	96(%ebp),%edx
        +	movl	100(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +.L001cast_dec_skip:
        +
        +	movl	88(%ebp),%edx
        +	movl	92(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	80(%ebp),%edx
        +	movl	84(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	72(%ebp),%edx
        +	movl	76(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	64(%ebp),%edx
        +	movl	68(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	56(%ebp),%edx
        +	movl	60(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	48(%ebp),%edx
        +	movl	52(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	40(%ebp),%edx
        +	movl	44(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	32(%ebp),%edx
        +	movl	36(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	24(%ebp),%edx
        +	movl	28(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	16(%ebp),%edx
        +	movl	20(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +
        +	movl	8(%ebp),%edx
        +	movl	12(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +
        +	movl	(%ebp),%edx
        +	movl	4(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	CAST_S_table0(,%ecx,4),%ecx
        +	movl	CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	nop
        +	movl	20(%esp),%eax
        +	movl	%edi,4(%eax)
        +	movl	%esi,(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	CAST_decrypt,.-.L_CAST_decrypt_begin
        +.globl	CAST_cbc_encrypt
        +.type	CAST_cbc_encrypt,@function
        +.align	16
        +CAST_cbc_encrypt:
        +.L_CAST_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +
        +	movl	56(%esp),%ecx
        +
        +	movl	48(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	.L002decrypt
        +	andl	$4294967288,%ebp
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	jz	.L003encrypt_finish
        +.L004encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_CAST_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L004encrypt_loop
        +.L003encrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L005finish
        +	call	.L006PIC_point
        +.L006PIC_point:
        +	popl	%edx
        +	leal	.L007cbc_enc_jmp_table-.L006PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +.L008ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +.L009ej6:
        +	movb	5(%esi),%dh
        +.L010ej5:
        +	movb	4(%esi),%dl
        +.L011ej4:
        +	movl	(%esi),%ecx
        +	jmp	.L012ejend
        +.L013ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +.L014ej2:
        +	movb	1(%esi),%ch
        +.L015ej1:
        +	movb	(%esi),%cl
        +.L012ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_CAST_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	.L005finish
        +.L002decrypt:
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	.L016decrypt_finish
        +.L017decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_CAST_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L017decrypt_loop
        +.L016decrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L005finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_CAST_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +.L018dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +.L019dj6:
        +	movb	%dh,5(%edi)
        +.L020dj5:
        +	movb	%dl,4(%edi)
        +.L021dj4:
        +	movl	%ecx,(%edi)
        +	jmp	.L022djend
        +.L023dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +.L024dj2:
        +	movb	%ch,1(%esi)
        +.L025dj1:
        +	movb	%cl,(%esi)
        +.L022djend:
        +	jmp	.L005finish
        +.L005finish:
        +	movl	60(%esp),%ecx
        +	addl	$24,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L007cbc_enc_jmp_table:
        +.long	0
        +.long	.L015ej1-.L006PIC_point
        +.long	.L014ej2-.L006PIC_point
        +.long	.L013ej3-.L006PIC_point
        +.long	.L011ej4-.L006PIC_point
        +.long	.L010ej5-.L006PIC_point
        +.long	.L009ej6-.L006PIC_point
        +.long	.L008ej7-.L006PIC_point
        +.align	64
        +.size	CAST_cbc_encrypt,.-.L_CAST_cbc_encrypt_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/des/crypt586.s b/vendor/openssl/asm/x86-elf-gas/des/crypt586.s
        new file mode 100644
        index 000000000..46c81c493
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/des/crypt586.s
        @@ -0,0 +1,875 @@
        +.file	"crypt586.s"
        +.text
        +.globl	fcrypt_body
        +.type	fcrypt_body,@function
        +.align	16
        +fcrypt_body:
        +.L_fcrypt_body_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	xorl	%edi,%edi
        +	xorl	%esi,%esi
        +	leal	DES_SPtrans,%edx
        +	pushl	%edx
        +	movl	28(%esp),%ebp
        +	pushl	$25
        +.L000start:
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	4(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	8(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	12(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	16(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	20(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	24(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	28(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	32(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	36(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	40(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	44(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	48(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	52(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	56(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	60(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	64(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	68(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	72(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	76(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	80(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	84(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	88(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	92(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	96(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	100(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	104(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	108(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	112(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	116(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	120(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	124(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +	movl	(%esp),%ebx
        +	movl	%edi,%eax
        +	decl	%ebx
        +	movl	%esi,%edi
        +	movl	%eax,%esi
        +	movl	%ebx,(%esp)
        +	jnz	.L000start
        +
        +
        +	movl	28(%esp),%edx
        +	rorl	$1,%edi
        +	movl	%esi,%eax
        +	xorl	%edi,%esi
        +	andl	$0xaaaaaaaa,%esi
        +	xorl	%esi,%eax
        +	xorl	%esi,%edi
        +
        +	roll	$23,%eax
        +	movl	%eax,%esi
        +	xorl	%edi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%esi
        +	xorl	%eax,%edi
        +
        +	roll	$10,%esi
        +	movl	%esi,%eax
        +	xorl	%edi,%esi
        +	andl	$0x33333333,%esi
        +	xorl	%esi,%eax
        +	xorl	%esi,%edi
        +
        +	roll	$18,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xfff0000f,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	roll	$12,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xf0f0f0f0,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%edx)
        +	movl	%edi,4(%edx)
        +	addl	$8,%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	fcrypt_body,.-.L_fcrypt_body_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/des/des-586.s b/vendor/openssl/asm/x86-elf-gas/des/des-586.s
        new file mode 100644
        index 000000000..2fbd340da
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/des/des-586.s
        @@ -0,0 +1,1837 @@
        +.file	"des-586.s"
        +.text
        +.globl	DES_SPtrans
        +.type	_x86_DES_encrypt,@function
        +.align	16
        +_x86_DES_encrypt:
        +	pushl	%ecx
        +
        +	movl	(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	4(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	8(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	12(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	16(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	20(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	24(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	28(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	32(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	36(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	40(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	44(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	48(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	52(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	56(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	60(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	64(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	68(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	72(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	76(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	80(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	84(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	88(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	92(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	96(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	100(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	104(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	108(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	112(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	116(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	120(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	124(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	addl	$4,%esp
        +	ret
        +.size	_x86_DES_encrypt,.-_x86_DES_encrypt
        +.type	_x86_DES_decrypt,@function
        +.align	16
        +_x86_DES_decrypt:
        +	pushl	%ecx
        +
        +	movl	120(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	124(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	112(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	116(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	104(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	108(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	96(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	100(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	88(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	92(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	80(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	84(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	72(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	76(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	64(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	68(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	56(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	60(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	48(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	52(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	40(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	44(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	32(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	36(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	24(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	28(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	16(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	20(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +
        +	movl	8(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	12(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +
        +	movl	(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	4(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	addl	$4,%esp
        +	ret
        +.size	_x86_DES_decrypt,.-_x86_DES_decrypt
        +.globl	DES_encrypt1
        +.type	DES_encrypt1,@function
        +.align	16
        +DES_encrypt1:
        +.L_DES_encrypt1_begin:
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	movl	12(%esp),%esi
        +	xorl	%ecx,%ecx
        +	pushl	%ebx
        +	pushl	%ebp
        +	movl	(%esi),%eax
        +	movl	28(%esp),%ebx
        +	movl	4(%esi),%edi
        +
        +
        +	roll	$4,%eax
        +	movl	%eax,%esi
        +	xorl	%edi,%eax
        +	andl	$0xf0f0f0f0,%eax
        +	xorl	%eax,%esi
        +	xorl	%eax,%edi
        +
        +	roll	$20,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xfff0000f,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$14,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x33333333,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$22,%esi
        +	movl	%esi,%eax
        +	xorl	%edi,%esi
        +	andl	$0x03fc03fc,%esi
        +	xorl	%esi,%eax
        +	xorl	%esi,%edi
        +
        +	roll	$9,%eax
        +	movl	%eax,%esi
        +	xorl	%edi,%eax
        +	andl	$0xaaaaaaaa,%eax
        +	xorl	%eax,%esi
        +	xorl	%eax,%edi
        +
        +	roll	$1,%edi
        +	call	.L000pic_point
        +.L000pic_point:
        +	popl	%ebp
        +	leal	DES_SPtrans-.L000pic_point(%ebp),%ebp
        +	movl	24(%esp),%ecx
        +	cmpl	$0,%ebx
        +	je	.L001decrypt
        +	call	_x86_DES_encrypt
        +	jmp	.L002done
        +.L001decrypt:
        +	call	_x86_DES_decrypt
        +.L002done:
        +
        +
        +	movl	20(%esp),%edx
        +	rorl	$1,%esi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$23,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$10,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$18,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	roll	$12,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%edx)
        +	movl	%esi,4(%edx)
        +	popl	%ebp
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	DES_encrypt1,.-.L_DES_encrypt1_begin
        +.globl	DES_encrypt2
        +.type	DES_encrypt2,@function
        +.align	16
        +DES_encrypt2:
        +.L_DES_encrypt2_begin:
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	movl	12(%esp),%eax
        +	xorl	%ecx,%ecx
        +	pushl	%ebx
        +	pushl	%ebp
        +	movl	(%eax),%esi
        +	movl	28(%esp),%ebx
        +	roll	$3,%esi
        +	movl	4(%eax),%edi
        +	roll	$3,%edi
        +	call	.L003pic_point
        +.L003pic_point:
        +	popl	%ebp
        +	leal	DES_SPtrans-.L003pic_point(%ebp),%ebp
        +	movl	24(%esp),%ecx
        +	cmpl	$0,%ebx
        +	je	.L004decrypt
        +	call	_x86_DES_encrypt
        +	jmp	.L005done
        +.L004decrypt:
        +	call	_x86_DES_decrypt
        +.L005done:
        +
        +
        +	rorl	$3,%edi
        +	movl	20(%esp),%eax
        +	rorl	$3,%esi
        +	movl	%edi,(%eax)
        +	movl	%esi,4(%eax)
        +	popl	%ebp
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	DES_encrypt2,.-.L_DES_encrypt2_begin
        +.globl	DES_encrypt3
        +.type	DES_encrypt3,@function
        +.align	16
        +DES_encrypt3:
        +.L_DES_encrypt3_begin:
        +	pushl	%ebx
        +	movl	8(%esp),%ebx
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +	subl	$12,%esp
        +
        +
        +	roll	$4,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	roll	$20,%esi
        +	movl	%esi,%edi
        +	xorl	%edx,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%edx
        +
        +	roll	$14,%edi
        +	movl	%edi,%esi
        +	xorl	%edx,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%edx
        +
        +	roll	$22,%edx
        +	movl	%edx,%edi
        +	xorl	%esi,%edx
        +	andl	$0x03fc03fc,%edx
        +	xorl	%edx,%edi
        +	xorl	%edx,%esi
        +
        +	roll	$9,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	rorl	$3,%edx
        +	rorl	$2,%esi
        +	movl	%esi,4(%ebx)
        +	movl	36(%esp),%eax
        +	movl	%edx,(%ebx)
        +	movl	40(%esp),%edi
        +	movl	44(%esp),%esi
        +	movl	$1,8(%esp)
        +	movl	%eax,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	.L_DES_encrypt2_begin
        +	movl	$0,8(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	.L_DES_encrypt2_begin
        +	movl	$1,8(%esp)
        +	movl	%esi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	.L_DES_encrypt2_begin
        +	addl	$12,%esp
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +
        +
        +	roll	$2,%esi
        +	roll	$3,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$23,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$10,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$18,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	roll	$12,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%ebx)
        +	movl	%esi,4(%ebx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	popl	%ebx
        +	ret
        +.size	DES_encrypt3,.-.L_DES_encrypt3_begin
        +.globl	DES_decrypt3
        +.type	DES_decrypt3,@function
        +.align	16
        +DES_decrypt3:
        +.L_DES_decrypt3_begin:
        +	pushl	%ebx
        +	movl	8(%esp),%ebx
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +	subl	$12,%esp
        +
        +
        +	roll	$4,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	roll	$20,%esi
        +	movl	%esi,%edi
        +	xorl	%edx,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%edx
        +
        +	roll	$14,%edi
        +	movl	%edi,%esi
        +	xorl	%edx,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%edx
        +
        +	roll	$22,%edx
        +	movl	%edx,%edi
        +	xorl	%esi,%edx
        +	andl	$0x03fc03fc,%edx
        +	xorl	%edx,%edi
        +	xorl	%edx,%esi
        +
        +	roll	$9,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	rorl	$3,%edx
        +	rorl	$2,%esi
        +	movl	%esi,4(%ebx)
        +	movl	36(%esp),%esi
        +	movl	%edx,(%ebx)
        +	movl	40(%esp),%edi
        +	movl	44(%esp),%eax
        +	movl	$0,8(%esp)
        +	movl	%eax,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	.L_DES_encrypt2_begin
        +	movl	$1,8(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	.L_DES_encrypt2_begin
        +	movl	$0,8(%esp)
        +	movl	%esi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	.L_DES_encrypt2_begin
        +	addl	$12,%esp
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +
        +
        +	roll	$2,%esi
        +	roll	$3,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$23,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$10,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$18,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	roll	$12,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%ebx)
        +	movl	%esi,4(%ebx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	popl	%ebx
        +	ret
        +.size	DES_decrypt3,.-.L_DES_decrypt3_begin
        +.globl	DES_ncbc_encrypt
        +.type	DES_ncbc_encrypt,@function
        +.align	16
        +DES_ncbc_encrypt:
        +.L_DES_ncbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +
        +	movl	56(%esp),%ecx
        +
        +	pushl	%ecx
        +
        +	movl	52(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	.L006decrypt
        +	andl	$4294967288,%ebp
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	jz	.L007encrypt_finish
        +.L008encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	.L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L008encrypt_loop
        +.L007encrypt_finish:
        +	movl	56(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L009finish
        +	call	.L010PIC_point
        +.L010PIC_point:
        +	popl	%edx
        +	leal	.L011cbc_enc_jmp_table-.L010PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +.L012ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +.L013ej6:
        +	movb	5(%esi),%dh
        +.L014ej5:
        +	movb	4(%esi),%dl
        +.L015ej4:
        +	movl	(%esi),%ecx
        +	jmp	.L016ejend
        +.L017ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +.L018ej2:
        +	movb	1(%esi),%ch
        +.L019ej1:
        +	movb	(%esi),%cl
        +.L016ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	.L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	.L009finish
        +.L006decrypt:
        +	andl	$4294967288,%ebp
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%ebx
        +	jz	.L020decrypt_finish
        +.L021decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	.L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	20(%esp),%ecx
        +	movl	24(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,20(%esp)
        +	movl	%ebx,24(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L021decrypt_loop
        +.L020decrypt_finish:
        +	movl	56(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L009finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	.L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	20(%esp),%ecx
        +	movl	24(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +.L022dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +.L023dj6:
        +	movb	%dh,5(%edi)
        +.L024dj5:
        +	movb	%dl,4(%edi)
        +.L025dj4:
        +	movl	%ecx,(%edi)
        +	jmp	.L026djend
        +.L027dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +.L028dj2:
        +	movb	%ch,1(%esi)
        +.L029dj1:
        +	movb	%cl,(%esi)
        +.L026djend:
        +	jmp	.L009finish
        +.L009finish:
        +	movl	64(%esp),%ecx
        +	addl	$28,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L011cbc_enc_jmp_table:
        +.long	0
        +.long	.L019ej1-.L010PIC_point
        +.long	.L018ej2-.L010PIC_point
        +.long	.L017ej3-.L010PIC_point
        +.long	.L015ej4-.L010PIC_point
        +.long	.L014ej5-.L010PIC_point
        +.long	.L013ej6-.L010PIC_point
        +.long	.L012ej7-.L010PIC_point
        +.align	64
        +.size	DES_ncbc_encrypt,.-.L_DES_ncbc_encrypt_begin
        +.globl	DES_ede3_cbc_encrypt
        +.type	DES_ede3_cbc_encrypt,@function
        +.align	16
        +DES_ede3_cbc_encrypt:
        +.L_DES_ede3_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +
        +	movl	44(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +
        +	movl	64(%esp),%ecx
        +
        +	movl	56(%esp),%eax
        +	pushl	%eax
        +
        +	movl	56(%esp),%eax
        +	pushl	%eax
        +
        +	movl	56(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	.L030decrypt
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	.L031encrypt_finish
        +.L032encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	.L_DES_encrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L032encrypt_loop
        +.L031encrypt_finish:
        +	movl	60(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L033finish
        +	call	.L034PIC_point
        +.L034PIC_point:
        +	popl	%edx
        +	leal	.L035cbc_enc_jmp_table-.L034PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +.L036ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +.L037ej6:
        +	movb	5(%esi),%dh
        +.L038ej5:
        +	movb	4(%esi),%dl
        +.L039ej4:
        +	movl	(%esi),%ecx
        +	jmp	.L040ejend
        +.L041ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +.L042ej2:
        +	movb	1(%esi),%ch
        +.L043ej1:
        +	movb	(%esi),%cl
        +.L040ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	.L_DES_encrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	.L033finish
        +.L030decrypt:
        +	andl	$4294967288,%ebp
        +	movl	24(%esp),%eax
        +	movl	28(%esp),%ebx
        +	jz	.L044decrypt_finish
        +.L045decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	.L_DES_decrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%ecx
        +	movl	28(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,24(%esp)
        +	movl	%ebx,28(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L045decrypt_loop
        +.L044decrypt_finish:
        +	movl	60(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L033finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	.L_DES_decrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%ecx
        +	movl	28(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +.L046dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +.L047dj6:
        +	movb	%dh,5(%edi)
        +.L048dj5:
        +	movb	%dl,4(%edi)
        +.L049dj4:
        +	movl	%ecx,(%edi)
        +	jmp	.L050djend
        +.L051dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +.L052dj2:
        +	movb	%ch,1(%esi)
        +.L053dj1:
        +	movb	%cl,(%esi)
        +.L050djend:
        +	jmp	.L033finish
        +.L033finish:
        +	movl	76(%esp),%ecx
        +	addl	$32,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L035cbc_enc_jmp_table:
        +.long	0
        +.long	.L043ej1-.L034PIC_point
        +.long	.L042ej2-.L034PIC_point
        +.long	.L041ej3-.L034PIC_point
        +.long	.L039ej4-.L034PIC_point
        +.long	.L038ej5-.L034PIC_point
        +.long	.L037ej6-.L034PIC_point
        +.long	.L036ej7-.L034PIC_point
        +.align	64
        +.size	DES_ede3_cbc_encrypt,.-.L_DES_ede3_cbc_encrypt_begin
        +.align	64
        +DES_SPtrans:
        +.long	34080768,524288,33554434,34080770
        +.long	33554432,526338,524290,33554434
        +.long	526338,34080768,34078720,2050
        +.long	33556482,33554432,0,524290
        +.long	524288,2,33556480,526336
        +.long	34080770,34078720,2050,33556480
        +.long	2,2048,526336,34078722
        +.long	2048,33556482,34078722,0
        +.long	0,34080770,33556480,524290
        +.long	34080768,524288,2050,33556480
        +.long	34078722,2048,526336,33554434
        +.long	526338,2,33554434,34078720
        +.long	34080770,526336,34078720,33556482
        +.long	33554432,2050,524290,0
        +.long	524288,33554432,33556482,34080768
        +.long	2,34078722,2048,526338
        +.long	1074823184,0,1081344,1074790400
        +.long	1073741840,32784,1073774592,1081344
        +.long	32768,1074790416,16,1073774592
        +.long	1048592,1074823168,1074790400,16
        +.long	1048576,1073774608,1074790416,32768
        +.long	1081360,1073741824,0,1048592
        +.long	1073774608,1081360,1074823168,1073741840
        +.long	1073741824,1048576,32784,1074823184
        +.long	1048592,1074823168,1073774592,1081360
        +.long	1074823184,1048592,1073741840,0
        +.long	1073741824,32784,1048576,1074790416
        +.long	32768,1073741824,1081360,1073774608
        +.long	1074823168,32768,0,1073741840
        +.long	16,1074823184,1081344,1074790400
        +.long	1074790416,1048576,32784,1073774592
        +.long	1073774608,16,1074790400,1081344
        +.long	67108865,67371264,256,67109121
        +.long	262145,67108864,67109121,262400
        +.long	67109120,262144,67371008,1
        +.long	67371265,257,1,67371009
        +.long	0,262145,67371264,256
        +.long	257,67371265,262144,67108865
        +.long	67371009,67109120,262401,67371008
        +.long	262400,0,67108864,262401
        +.long	67371264,256,1,262144
        +.long	257,262145,67371008,67109121
        +.long	0,67371264,262400,67371009
        +.long	262145,67108864,67371265,1
        +.long	262401,67108865,67108864,67371265
        +.long	262144,67109120,67109121,262400
        +.long	67109120,0,67371009,257
        +.long	67108865,262401,256,67371008
        +.long	4198408,268439552,8,272633864
        +.long	0,272629760,268439560,4194312
        +.long	272633856,268435464,268435456,4104
        +.long	268435464,4198408,4194304,268435456
        +.long	272629768,4198400,4096,8
        +.long	4198400,268439560,272629760,4096
        +.long	4104,0,4194312,272633856
        +.long	268439552,272629768,272633864,4194304
        +.long	272629768,4104,4194304,268435464
        +.long	4198400,268439552,8,272629760
        +.long	268439560,0,4096,4194312
        +.long	0,272629768,272633856,4096
        +.long	268435456,272633864,4198408,4194304
        +.long	272633864,8,268439552,4198408
        +.long	4194312,4198400,272629760,268439560
        +.long	4104,268435456,268435464,272633856
        +.long	134217728,65536,1024,134284320
        +.long	134283296,134218752,66592,134283264
        +.long	65536,32,134217760,66560
        +.long	134218784,134283296,134284288,0
        +.long	66560,134217728,65568,1056
        +.long	134218752,66592,0,134217760
        +.long	32,134218784,134284320,65568
        +.long	134283264,1024,1056,134284288
        +.long	134284288,134218784,65568,134283264
        +.long	65536,32,134217760,134218752
        +.long	134217728,66560,134284320,0
        +.long	66592,134217728,1024,65568
        +.long	134218784,1024,0,134284320
        +.long	134283296,134284288,1056,65536
        +.long	66560,134283296,134218752,1056
        +.long	32,66592,134283264,134217760
        +.long	2147483712,2097216,0,2149588992
        +.long	2097216,8192,2147491904,2097152
        +.long	8256,2149589056,2105344,2147483648
        +.long	2147491840,2147483712,2149580800,2105408
        +.long	2097152,2147491904,2149580864,0
        +.long	8192,64,2149588992,2149580864
        +.long	2149589056,2149580800,2147483648,8256
        +.long	64,2105344,2105408,2147491840
        +.long	8256,2147483648,2147491840,2105408
        +.long	2149588992,2097216,0,2147491840
        +.long	2147483648,8192,2149580864,2097152
        +.long	2097216,2149589056,2105344,64
        +.long	2149589056,2105344,2097152,2147491904
        +.long	2147483712,2149580800,2105408,0
        +.long	8192,2147483712,2147491904,2149588992
        +.long	2149580800,8256,64,2149580864
        +.long	16384,512,16777728,16777220
        +.long	16794116,16388,16896,0
        +.long	16777216,16777732,516,16793600
        +.long	4,16794112,16793600,516
        +.long	16777732,16384,16388,16794116
        +.long	0,16777728,16777220,16896
        +.long	16793604,16900,16794112,4
        +.long	16900,16793604,512,16777216
        +.long	16900,16793600,16793604,516
        +.long	16384,512,16777216,16793604
        +.long	16777732,16900,16896,0
        +.long	512,16777220,4,16777728
        +.long	0,16777732,16777728,16896
        +.long	516,16384,16794116,16777216
        +.long	16794112,4,16388,16794116
        +.long	16777220,16794112,16793600,16388
        +.long	545259648,545390592,131200,0
        +.long	537001984,8388736,545259520,545390720
        +.long	128,536870912,8519680,131200
        +.long	8519808,537002112,536871040,545259520
        +.long	131072,8519808,8388736,537001984
        +.long	545390720,536871040,0,8519680
        +.long	536870912,8388608,537002112,545259648
        +.long	8388608,131072,545390592,128
        +.long	8388608,131072,536871040,545390720
        +.long	131200,536870912,0,8519680
        +.long	545259648,537002112,537001984,8388736
        +.long	545390592,128,8388736,537001984
        +.long	545390720,8388608,545259520,536871040
        +.long	8519680,131200,537002112,545259520
        +.long	128,545390592,8519808,0
        +.long	536870912,545259648,131072,8519808
        diff --git a/vendor/openssl/asm/x86-elf-gas/md5/md5-586.s b/vendor/openssl/asm/x86-elf-gas/md5/md5-586.s
        new file mode 100644
        index 000000000..e354c4ebc
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/md5/md5-586.s
        @@ -0,0 +1,679 @@
        +.file	"../openssl/crypto/md5/asm/md5-586.s"
        +.text
        +.globl	md5_block_asm_data_order
        +.type	md5_block_asm_data_order,@function
        +.align	16
        +md5_block_asm_data_order:
        +.L_md5_block_asm_data_order_begin:
        +	pushl	%esi
        +	pushl	%edi
        +	movl	12(%esp),%edi
        +	movl	16(%esp),%esi
        +	movl	20(%esp),%ecx
        +	pushl	%ebp
        +	shll	$6,%ecx
        +	pushl	%ebx
        +	addl	%esi,%ecx
        +	subl	$64,%ecx
        +	movl	(%edi),%eax
        +	pushl	%ecx
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +.L000start:
        +
        +
        +	movl	%ecx,%edi
        +	movl	(%esi),%ebp
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	3614090360(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	4(%esi),%ebp
        +	addl	%ebx,%eax
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	3905402710(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	8(%esi),%ebp
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	606105819(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	12(%esi),%ebp
        +	addl	%edx,%ecx
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	3250441966(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	16(%esi),%ebp
        +	addl	%ecx,%ebx
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	4118548399(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	20(%esi),%ebp
        +	addl	%ebx,%eax
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	1200080426(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	24(%esi),%ebp
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	2821735955(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	28(%esi),%ebp
        +	addl	%edx,%ecx
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	4249261313(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	32(%esi),%ebp
        +	addl	%ecx,%ebx
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	1770035416(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	36(%esi),%ebp
        +	addl	%ebx,%eax
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	2336552879(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	40(%esi),%ebp
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	4294925233(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	44(%esi),%ebp
        +	addl	%edx,%ecx
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	2304563134(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	48(%esi),%ebp
        +	addl	%ecx,%ebx
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	1804603682(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	52(%esi),%ebp
        +	addl	%ebx,%eax
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	4254626195(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	56(%esi),%ebp
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	2792965006(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	60(%esi),%ebp
        +	addl	%edx,%ecx
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	1236535329(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	4(%esi),%ebp
        +	addl	%ecx,%ebx
        +
        +
        +
        +	leal	4129170786(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	24(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +
        +	leal	3225465664(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	44(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +
        +	leal	643717713(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +
        +	leal	3921069994(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	20(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +
        +	leal	3593408605(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	40(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +
        +	leal	38016083(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	60(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +
        +	leal	3634488961(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	16(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +
        +	leal	3889429448(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	36(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +
        +	leal	568446438(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	56(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +
        +	leal	3275163606(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	12(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +
        +	leal	4107603335(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	32(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +
        +	leal	1163531501(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	52(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +
        +	leal	2850285829(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	8(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +
        +	leal	4243563512(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	28(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +
        +	leal	1735328473(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	48(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +
        +	leal	2368359562(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	20(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +
        +
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	4294588738(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	32(%esi),%ebp
        +	movl	%ebx,%edi
        +
        +	leal	2272392833(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	44(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	1839030562(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	56(%esi),%ebp
        +	movl	%edx,%edi
        +
        +	leal	4259657740(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	4(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	2763975236(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	16(%esi),%ebp
        +	movl	%ebx,%edi
        +
        +	leal	1272893353(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	28(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	4139469664(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	40(%esi),%ebp
        +	movl	%edx,%edi
        +
        +	leal	3200236656(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	52(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	681279174(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	(%esi),%ebp
        +	movl	%ebx,%edi
        +
        +	leal	3936430074(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	12(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	3572445317(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	24(%esi),%ebp
        +	movl	%edx,%edi
        +
        +	leal	76029189(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	36(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	3654602809(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	48(%esi),%ebp
        +	movl	%ebx,%edi
        +
        +	leal	3873151461(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	60(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	530742520(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	8(%esi),%ebp
        +	movl	%edx,%edi
        +
        +	leal	3299628645(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +
        +
        +
        +	xorl	%edx,%edi
        +	orl	%ebx,%edi
        +	leal	4096336452(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	28(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +
        +	orl	%eax,%edi
        +	leal	1126891415(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	56(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +
        +	orl	%edx,%edi
        +	leal	2878612391(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	20(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +
        +	orl	%ecx,%edi
        +	leal	4237533241(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	48(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$21,%ebx
        +	xorl	%edx,%edi
        +	addl	%ecx,%ebx
        +
        +	orl	%ebx,%edi
        +	leal	1700485571(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	12(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +
        +	orl	%eax,%edi
        +	leal	2399980690(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	40(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +
        +	orl	%edx,%edi
        +	leal	4293915773(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	4(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +
        +	orl	%ecx,%edi
        +	leal	2240044497(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	32(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$21,%ebx
        +	xorl	%edx,%edi
        +	addl	%ecx,%ebx
        +
        +	orl	%ebx,%edi
        +	leal	1873313359(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	60(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +
        +	orl	%eax,%edi
        +	leal	4264355552(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	24(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +
        +	orl	%edx,%edi
        +	leal	2734768916(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	52(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +
        +	orl	%ecx,%edi
        +	leal	1309151649(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	16(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$21,%ebx
        +	xorl	%edx,%edi
        +	addl	%ecx,%ebx
        +
        +	orl	%ebx,%edi
        +	leal	4149444226(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	44(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +
        +	orl	%eax,%edi
        +	leal	3174756917(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	8(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +
        +	orl	%edx,%edi
        +	leal	718787259(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	36(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +
        +	orl	%ecx,%edi
        +	leal	3951481745(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	24(%esp),%ebp
        +	addl	%edi,%ebx
        +	addl	$64,%esi
        +	roll	$21,%ebx
        +	movl	(%ebp),%edi
        +	addl	%ecx,%ebx
        +	addl	%edi,%eax
        +	movl	4(%ebp),%edi
        +	addl	%edi,%ebx
        +	movl	8(%ebp),%edi
        +	addl	%edi,%ecx
        +	movl	12(%ebp),%edi
        +	addl	%edi,%edx
        +	movl	%eax,(%ebp)
        +	movl	%ebx,4(%ebp)
        +	movl	(%esp),%edi
        +	movl	%ecx,8(%ebp)
        +	movl	%edx,12(%ebp)
        +	cmpl	%esi,%edi
        +	jae	.L000start
        +	popl	%eax
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	md5_block_asm_data_order,.-.L_md5_block_asm_data_order_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/rc4/rc4-586.s b/vendor/openssl/asm/x86-elf-gas/rc4/rc4-586.s
        new file mode 100644
        index 000000000..513ce6a58
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/rc4/rc4-586.s
        @@ -0,0 +1,372 @@
        +.file	"rc4-586.s"
        +.text
        +.globl	RC4
        +.type	RC4,@function
        +.align	16
        +RC4:
        +.L_RC4_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%edx
        +	movl	28(%esp),%esi
        +	movl	32(%esp),%ebp
        +	xorl	%eax,%eax
        +	xorl	%ebx,%ebx
        +	cmpl	$0,%edx
        +	je	.L000abort
        +	movb	(%edi),%al
        +	movb	4(%edi),%bl
        +	addl	$8,%edi
        +	leal	(%esi,%edx,1),%ecx
        +	subl	%esi,%ebp
        +	movl	%ecx,24(%esp)
        +	incb	%al
        +	cmpl	$-1,256(%edi)
        +	je	.L001RC4_CHAR
        +	movl	(%edi,%eax,4),%ecx
        +	andl	$-4,%edx
        +	jz	.L002loop1
        +	testl	$-8,%edx
        +	movl	%ebp,32(%esp)
        +	jz	.L003go4loop4
        +	leal	OPENSSL_ia32cap_P,%ebp
        +	btl	$26,(%ebp)
        +	jnc	.L003go4loop4
        +	movl	32(%esp),%ebp
        +	andl	$-8,%edx
        +	leal	-8(%esi,%edx,1),%edx
        +	movl	%edx,-4(%edi)
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	movq	(%esi),%mm0
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm2
        +	jmp	.L004loop_mmx_enter
        +.align	16
        +.L005loop_mmx:
        +	addb	%cl,%bl
        +	psllq	$56,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movq	(%esi),%mm0
        +	movq	%mm2,-8(%ebp,%esi,1)
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm2
        +.L004loop_mmx_enter:
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm0,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$8,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$16,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$24,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$32,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$40,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$48,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	movl	%ebx,%edx
        +	xorl	%ebx,%ebx
        +	movb	%dl,%bl
        +	cmpl	-4(%edi),%esi
        +	leal	8(%esi),%esi
        +	jb	.L005loop_mmx
        +	psllq	$56,%mm1
        +	pxor	%mm1,%mm2
        +	movq	%mm2,-8(%ebp,%esi,1)
        +	emms
        +	cmpl	24(%esp),%esi
        +	je	.L006done
        +	jmp	.L002loop1
        +.align	16
        +.L003go4loop4:
        +	leal	-4(%esi,%edx,1),%edx
        +	movl	%edx,28(%esp)
        +.L007loop4:
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	movl	(%edi,%eax,4),%ecx
        +	movl	(%edi,%edx,4),%ebp
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	rorl	$8,%ebp
        +	movl	(%edi,%eax,4),%ecx
        +	orl	(%edi,%edx,4),%ebp
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	rorl	$8,%ebp
        +	movl	(%edi,%eax,4),%ecx
        +	orl	(%edi,%edx,4),%ebp
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	rorl	$8,%ebp
        +	movl	32(%esp),%ecx
        +	orl	(%edi,%edx,4),%ebp
        +	rorl	$8,%ebp
        +	xorl	(%esi),%ebp
        +	cmpl	28(%esp),%esi
        +	movl	%ebp,(%ecx,%esi,1)
        +	leal	4(%esi),%esi
        +	movl	(%edi,%eax,4),%ecx
        +	jb	.L007loop4
        +	cmpl	24(%esp),%esi
        +	je	.L006done
        +	movl	32(%esp),%ebp
        +.align	16
        +.L002loop1:
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	movl	(%edi,%edx,4),%edx
        +	xorb	(%esi),%dl
        +	leal	1(%esi),%esi
        +	movl	(%edi,%eax,4),%ecx
        +	cmpl	24(%esp),%esi
        +	movb	%dl,-1(%ebp,%esi,1)
        +	jb	.L002loop1
        +	jmp	.L006done
        +.align	16
        +.L001RC4_CHAR:
        +	movzbl	(%edi,%eax,1),%ecx
        +.L008cloop1:
        +	addb	%cl,%bl
        +	movzbl	(%edi,%ebx,1),%edx
        +	movb	%cl,(%edi,%ebx,1)
        +	movb	%dl,(%edi,%eax,1)
        +	addb	%cl,%dl
        +	movzbl	(%edi,%edx,1),%edx
        +	addb	$1,%al
        +	xorb	(%esi),%dl
        +	leal	1(%esi),%esi
        +	movzbl	(%edi,%eax,1),%ecx
        +	cmpl	24(%esp),%esi
        +	movb	%dl,-1(%ebp,%esi,1)
        +	jb	.L008cloop1
        +.L006done:
        +	decb	%al
        +	movl	%ebx,-4(%edi)
        +	movb	%al,-8(%edi)
        +.L000abort:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	RC4,.-.L_RC4_begin
        +.globl	private_RC4_set_key
        +.type	private_RC4_set_key,@function
        +.align	16
        +private_RC4_set_key:
        +.L_private_RC4_set_key_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%ebp
        +	movl	28(%esp),%esi
        +	leal	OPENSSL_ia32cap_P,%edx
        +	leal	8(%edi),%edi
        +	leal	(%esi,%ebp,1),%esi
        +	negl	%ebp
        +	xorl	%eax,%eax
        +	movl	%ebp,-4(%edi)
        +	btl	$20,(%edx)
        +	jc	.L009c1stloop
        +.align	16
        +.L010w1stloop:
        +	movl	%eax,(%edi,%eax,4)
        +	addb	$1,%al
        +	jnc	.L010w1stloop
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +.align	16
        +.L011w2ndloop:
        +	movl	(%edi,%ecx,4),%eax
        +	addb	(%esi,%ebp,1),%dl
        +	addb	%al,%dl
        +	addl	$1,%ebp
        +	movl	(%edi,%edx,4),%ebx
        +	jnz	.L012wnowrap
        +	movl	-4(%edi),%ebp
        +.L012wnowrap:
        +	movl	%eax,(%edi,%edx,4)
        +	movl	%ebx,(%edi,%ecx,4)
        +	addb	$1,%cl
        +	jnc	.L011w2ndloop
        +	jmp	.L013exit
        +.align	16
        +.L009c1stloop:
        +	movb	%al,(%edi,%eax,1)
        +	addb	$1,%al
        +	jnc	.L009c1stloop
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	xorl	%ebx,%ebx
        +.align	16
        +.L014c2ndloop:
        +	movb	(%edi,%ecx,1),%al
        +	addb	(%esi,%ebp,1),%dl
        +	addb	%al,%dl
        +	addl	$1,%ebp
        +	movb	(%edi,%edx,1),%bl
        +	jnz	.L015cnowrap
        +	movl	-4(%edi),%ebp
        +.L015cnowrap:
        +	movb	%al,(%edi,%edx,1)
        +	movb	%bl,(%edi,%ecx,1)
        +	addb	$1,%cl
        +	jnc	.L014c2ndloop
        +	movl	$-1,256(%edi)
        +.L013exit:
        +	xorl	%eax,%eax
        +	movl	%eax,-8(%edi)
        +	movl	%eax,-4(%edi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	private_RC4_set_key,.-.L_private_RC4_set_key_begin
        +.globl	RC4_options
        +.type	RC4_options,@function
        +.align	16
        +RC4_options:
        +.L_RC4_options_begin:
        +	call	.L016pic_point
        +.L016pic_point:
        +	popl	%eax
        +	leal	.L017opts-.L016pic_point(%eax),%eax
        +	leal	OPENSSL_ia32cap_P,%edx
        +	movl	(%edx),%edx
        +	btl	$20,%edx
        +	jc	.L0181xchar
        +	btl	$26,%edx
        +	jnc	.L019ret
        +	addl	$25,%eax
        +	ret
        +.L0181xchar:
        +	addl	$12,%eax
        +.L019ret:
        +	ret
        +.align	64
        +.L017opts:
        +.byte	114,99,52,40,52,120,44,105,110,116,41,0
        +.byte	114,99,52,40,49,120,44,99,104,97,114,41,0
        +.byte	114,99,52,40,56,120,44,109,109,120,41,0
        +.byte	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
        +.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
        +.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	64
        +.size	RC4_options,.-.L_RC4_options_begin
        +.comm	OPENSSL_ia32cap_P,8,4
        diff --git a/vendor/openssl/asm/x86-elf-gas/rc5/rc5-586.s b/vendor/openssl/asm/x86-elf-gas/rc5/rc5-586.s
        new file mode 100644
        index 000000000..ff8a4929a
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/rc5/rc5-586.s
        @@ -0,0 +1,564 @@
        +.file	"rc5-586.s"
        +.text
        +.globl	RC5_32_encrypt
        +.type	RC5_32_encrypt,@function
        +.align	16
        +RC5_32_encrypt:
        +.L_RC5_32_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +	movl	16(%esp),%edx
        +	movl	20(%esp),%ebp
        +
        +	movl	(%edx),%edi
        +	movl	4(%edx),%esi
        +	pushl	%ebx
        +	movl	(%ebp),%ebx
        +	addl	4(%ebp),%edi
        +	addl	8(%ebp),%esi
        +	xorl	%esi,%edi
        +	movl	12(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	16(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	20(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	24(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	28(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	32(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	36(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	40(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	44(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	48(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	52(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	56(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	60(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	64(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	68(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	72(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	cmpl	$8,%ebx
        +	je	.L000rc5_exit
        +	xorl	%esi,%edi
        +	movl	76(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	80(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	84(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	88(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	92(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	96(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	100(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	104(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	cmpl	$12,%ebx
        +	je	.L000rc5_exit
        +	xorl	%esi,%edi
        +	movl	108(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	112(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	116(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	120(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	124(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	128(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	132(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	136(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +.L000rc5_exit:
        +	movl	%edi,(%edx)
        +	movl	%esi,4(%edx)
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	ret
        +.size	RC5_32_encrypt,.-.L_RC5_32_encrypt_begin
        +.globl	RC5_32_decrypt
        +.type	RC5_32_decrypt,@function
        +.align	16
        +RC5_32_decrypt:
        +.L_RC5_32_decrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +	movl	16(%esp),%edx
        +	movl	20(%esp),%ebp
        +
        +	movl	(%edx),%edi
        +	movl	4(%edx),%esi
        +	pushl	%ebx
        +	movl	(%ebp),%ebx
        +	cmpl	$12,%ebx
        +	je	.L001rc5_dec_12
        +	cmpl	$8,%ebx
        +	je	.L002rc5_dec_8
        +	movl	136(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	132(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	128(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	124(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	120(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	116(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	112(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	108(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +.L001rc5_dec_12:
        +	movl	104(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	100(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	96(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	92(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	88(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	84(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	80(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	76(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +.L002rc5_dec_8:
        +	movl	72(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	68(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	64(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	60(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	56(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	52(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	48(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	44(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	40(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	36(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	32(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	28(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	24(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	20(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	16(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	12(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	subl	8(%ebp),%esi
        +	subl	4(%ebp),%edi
        +.L003rc5_exit:
        +	movl	%edi,(%edx)
        +	movl	%esi,4(%edx)
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	ret
        +.size	RC5_32_decrypt,.-.L_RC5_32_decrypt_begin
        +.globl	RC5_32_cbc_encrypt
        +.type	RC5_32_cbc_encrypt,@function
        +.align	16
        +RC5_32_cbc_encrypt:
        +.L_RC5_32_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +
        +	movl	56(%esp),%ecx
        +
        +	movl	48(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	.L004decrypt
        +	andl	$4294967288,%ebp
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	jz	.L005encrypt_finish
        +.L006encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_RC5_32_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L006encrypt_loop
        +.L005encrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L007finish
        +	call	.L008PIC_point
        +.L008PIC_point:
        +	popl	%edx
        +	leal	.L009cbc_enc_jmp_table-.L008PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +.L010ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +.L011ej6:
        +	movb	5(%esi),%dh
        +.L012ej5:
        +	movb	4(%esi),%dl
        +.L013ej4:
        +	movl	(%esi),%ecx
        +	jmp	.L014ejend
        +.L015ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +.L016ej2:
        +	movb	1(%esi),%ch
        +.L017ej1:
        +	movb	(%esi),%cl
        +.L014ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_RC5_32_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	.L007finish
        +.L004decrypt:
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	.L018decrypt_finish
        +.L019decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_RC5_32_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	.L019decrypt_loop
        +.L018decrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	.L007finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	.L_RC5_32_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +.L020dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +.L021dj6:
        +	movb	%dh,5(%edi)
        +.L022dj5:
        +	movb	%dl,4(%edi)
        +.L023dj4:
        +	movl	%ecx,(%edi)
        +	jmp	.L024djend
        +.L025dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +.L026dj2:
        +	movb	%ch,1(%esi)
        +.L027dj1:
        +	movb	%cl,(%esi)
        +.L024djend:
        +	jmp	.L007finish
        +.L007finish:
        +	movl	60(%esp),%ecx
        +	addl	$24,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L009cbc_enc_jmp_table:
        +.long	0
        +.long	.L017ej1-.L008PIC_point
        +.long	.L016ej2-.L008PIC_point
        +.long	.L015ej3-.L008PIC_point
        +.long	.L013ej4-.L008PIC_point
        +.long	.L012ej5-.L008PIC_point
        +.long	.L011ej6-.L008PIC_point
        +.long	.L010ej7-.L008PIC_point
        +.align	64
        +.size	RC5_32_cbc_encrypt,.-.L_RC5_32_cbc_encrypt_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/ripemd/rmd-586.s b/vendor/openssl/asm/x86-elf-gas/ripemd/rmd-586.s
        new file mode 100644
        index 000000000..3c45fb91d
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/ripemd/rmd-586.s
        @@ -0,0 +1,1965 @@
        +.file	"../openssl/crypto/ripemd/asm/rmd-586.s"
        +.text
        +.globl	ripemd160_block_asm_data_order
        +.type	ripemd160_block_asm_data_order,@function
        +.align	16
        +ripemd160_block_asm_data_order:
        +.L_ripemd160_block_asm_data_order_begin:
        +	movl	4(%esp),%edx
        +	movl	8(%esp),%eax
        +	pushl	%esi
        +	movl	(%edx),%ecx
        +	pushl	%edi
        +	movl	4(%edx),%esi
        +	pushl	%ebp
        +	movl	8(%edx),%edi
        +	pushl	%ebx
        +	subl	$108,%esp
        +.L000start:
        +
        +	movl	(%eax),%ebx
        +	movl	4(%eax),%ebp
        +	movl	%ebx,(%esp)
        +	movl	%ebp,4(%esp)
        +	movl	8(%eax),%ebx
        +	movl	12(%eax),%ebp
        +	movl	%ebx,8(%esp)
        +	movl	%ebp,12(%esp)
        +	movl	16(%eax),%ebx
        +	movl	20(%eax),%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ebp,20(%esp)
        +	movl	24(%eax),%ebx
        +	movl	28(%eax),%ebp
        +	movl	%ebx,24(%esp)
        +	movl	%ebp,28(%esp)
        +	movl	32(%eax),%ebx
        +	movl	36(%eax),%ebp
        +	movl	%ebx,32(%esp)
        +	movl	%ebp,36(%esp)
        +	movl	40(%eax),%ebx
        +	movl	44(%eax),%ebp
        +	movl	%ebx,40(%esp)
        +	movl	%ebp,44(%esp)
        +	movl	48(%eax),%ebx
        +	movl	52(%eax),%ebp
        +	movl	%ebx,48(%esp)
        +	movl	%ebp,52(%esp)
        +	movl	56(%eax),%ebx
        +	movl	60(%eax),%ebp
        +	movl	%ebx,56(%esp)
        +	movl	%ebp,60(%esp)
        +	movl	%edi,%eax
        +	movl	12(%edx),%ebx
        +	movl	16(%edx),%ebp
        +
        +	xorl	%ebx,%eax
        +	movl	(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%edx,%ecx
        +	roll	$10,%edi
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$11,%ecx
        +	addl	%ebp,%ecx
        +
        +	xorl	%edi,%eax
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$10,%esi
        +	addl	%edx,%ebp
        +	xorl	%esi,%eax
        +	roll	$14,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	8(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%edx,%ebx
        +	roll	$10,%ecx
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$15,%ebx
        +	addl	%edi,%ebx
        +
        +	xorl	%ecx,%eax
        +	movl	12(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	addl	%edx,%edi
        +	xorl	%ebp,%eax
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +
        +	movl	16(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +
        +	xorl	%ebx,%eax
        +	movl	20(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	xorl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	24(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%edx,%ebp
        +	roll	$10,%esi
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +
        +	xorl	%esi,%eax
        +	movl	28(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$10,%ecx
        +	addl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	32(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%edx,%edi
        +	roll	$10,%ebp
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +
        +	xorl	%ebp,%eax
        +	movl	36(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$10,%ebx
        +	addl	%edx,%esi
        +	xorl	%ebx,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +
        +	movl	40(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%edx,%ecx
        +	roll	$10,%edi
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +
        +	xorl	%edi,%eax
        +	movl	44(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$10,%esi
        +	addl	%edx,%ebp
        +	xorl	%esi,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	48(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%edx,%ebx
        +	roll	$10,%ecx
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$6,%ebx
        +	addl	%edi,%ebx
        +
        +	xorl	%ecx,%eax
        +	movl	52(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	addl	%edx,%edi
        +	xorl	%ebp,%eax
        +	roll	$7,%edi
        +	addl	%esi,%edi
        +
        +	movl	56(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +
        +	xorl	%ebx,%eax
        +	movl	60(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	movl	28(%esp),%edx
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%edx,%ebp
        +	movl	%esi,%edx
        +	subl	%ecx,%eax
        +	andl	%ecx,%edx
        +	andl	%edi,%eax
        +	orl	%eax,%edx
        +	movl	16(%esp),%eax
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	subl	%ebp,%edx
        +	andl	%ebp,%eax
        +	andl	%esi,%edx
        +	orl	%edx,%eax
        +	movl	52(%esp),%edx
        +	roll	$10,%ecx
        +	leal	1518500249(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$6,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1518500249(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$8,%edi
        +	addl	%esi,%edi
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	40(%esp),%edx
        +	roll	$10,%ebx
        +	leal	1518500249(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%edi
        +	leal	1518500249(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$11,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	60(%esp),%edx
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	movl	$-1,%eax
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +
        +	addl	%edx,%ebx
        +	movl	%ecx,%edx
        +	subl	%ebp,%eax
        +	andl	%ebp,%edx
        +	andl	%esi,%eax
        +	orl	%eax,%edx
        +	movl	12(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1518500249(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	roll	$7,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	subl	%ebx,%edx
        +	andl	%ebx,%eax
        +	andl	%ecx,%edx
        +	orl	%edx,%eax
        +	movl	48(%esp),%edx
        +	roll	$10,%ebp
        +	leal	1518500249(%edi,%eax,1),%edi
        +	movl	$-1,%eax
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +
        +	addl	%edx,%esi
        +	movl	%ebx,%edx
        +	subl	%edi,%eax
        +	andl	%edi,%edx
        +	andl	%ebp,%eax
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1518500249(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	subl	%esi,%edx
        +	andl	%esi,%eax
        +	andl	%ebx,%edx
        +	orl	%edx,%eax
        +	movl	36(%esp),%edx
        +	roll	$10,%edi
        +	leal	1518500249(%ecx,%eax,1),%ecx
        +	movl	$-1,%eax
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%edx,%ebp
        +	movl	%esi,%edx
        +	subl	%ecx,%eax
        +	andl	%ecx,%edx
        +	andl	%edi,%eax
        +	orl	%eax,%edx
        +	movl	20(%esp),%eax
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	subl	%ebp,%edx
        +	andl	%ebp,%eax
        +	andl	%esi,%edx
        +	orl	%edx,%eax
        +	movl	8(%esp),%edx
        +	roll	$10,%ecx
        +	leal	1518500249(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1518500249(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	44(%esp),%edx
        +	roll	$10,%ebx
        +	leal	1518500249(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	32(%esp),%eax
        +	roll	$10,%edi
        +	leal	1518500249(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	subl	%ecx,%edx
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	12(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$11,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	40(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1859775393(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$13,%edi
        +	addl	%esi,%edi
        +
        +	movl	56(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1859775393(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +
        +	movl	16(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1859775393(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$7,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	36(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1859775393(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$14,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	60(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	subl	%ebp,%edx
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	32(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%edi
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	1859775393(%edi,%edx,1),%edi
        +	subl	%ebx,%eax
        +	roll	$13,%edi
        +	addl	%esi,%edi
        +
        +	movl	4(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%esi
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	1859775393(%esi,%eax,1),%esi
        +	subl	%edi,%edx
        +	roll	$15,%esi
        +	addl	%ecx,%esi
        +
        +	movl	8(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1859775393(%ecx,%edx,1),%ecx
        +	subl	%esi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	28(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebp
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1859775393(%ebp,%eax,1),%ebp
        +	subl	%ecx,%edx
        +	roll	$8,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$13,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	24(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1859775393(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +
        +	movl	52(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1859775393(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +
        +	movl	44(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1859775393(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	20(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1859775393(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	48(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	%ecx,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	36(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2400959708(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$12,%esi
        +	addl	%ecx,%esi
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	44(%esp),%eax
        +	roll	$10,%edi
        +	leal	2400959708(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	40(%esp),%eax
        +	roll	$10,%esi
        +	leal	2400959708(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2400959708(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	32(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	48(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2400959708(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	16(%esp),%eax
        +	roll	$10,%edi
        +	leal	2400959708(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	52(%esp),%eax
        +	roll	$10,%esi
        +	leal	2400959708(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	12(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2400959708(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	28(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$5,%edi
        +	addl	%esi,%edi
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	60(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2400959708(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%edi
        +	leal	2400959708(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	20(%esp),%eax
        +	roll	$10,%esi
        +	leal	2400959708(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$6,%ebp
        +	addl	%ebx,%ebp
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2400959708(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	8(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	subl	%ebp,%edx
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +
        +	movl	16(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +
        +	movl	(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	2840853838(%ecx,%eax,1),%ecx
        +	subl	%edi,%edx
        +	roll	$15,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	20(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ebp
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	2840853838(%ebp,%edx,1),%ebp
        +	subl	%esi,%eax
        +	roll	$5,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	36(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebx
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	2840853838(%ebx,%eax,1),%ebx
        +	subl	%ecx,%edx
        +	roll	$11,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	28(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%edi
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	2840853838(%edi,%edx,1),%edi
        +	subl	%ebp,%eax
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +
        +	movl	48(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%esi
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%eax,1),%esi
        +	subl	%ebx,%edx
        +	roll	$8,%esi
        +	addl	%ecx,%esi
        +
        +	movl	8(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%ecx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	2840853838(%ecx,%edx,1),%ecx
        +	subl	%edi,%eax
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	40(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ebp
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	2840853838(%ebp,%eax,1),%ebp
        +	subl	%esi,%edx
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	56(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebx
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	2840853838(%ebx,%edx,1),%ebx
        +	subl	%ecx,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	4(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%edi
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	2840853838(%edi,%eax,1),%edi
        +	subl	%ebp,%edx
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +
        +	movl	12(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +
        +	movl	32(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	2840853838(%ecx,%eax,1),%ecx
        +	subl	%edi,%edx
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	44(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ebp
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	2840853838(%ebp,%edx,1),%ebp
        +	subl	%esi,%eax
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	24(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebx
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	2840853838(%ebx,%eax,1),%ebx
        +	subl	%ecx,%edx
        +	roll	$8,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	60(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%edi
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	2840853838(%edi,%edx,1),%edi
        +	subl	%ebp,%eax
        +	roll	$5,%edi
        +	addl	%esi,%edi
        +
        +	movl	52(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%esi
        +	xorl	%edi,%eax
        +	movl	128(%esp),%edx
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%eax,1),%esi
        +	movl	%ecx,64(%esp)
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +	movl	(%edx),%ecx
        +	movl	%esi,68(%esp)
        +	movl	%edi,72(%esp)
        +	movl	4(%edx),%esi
        +	movl	%ebx,76(%esp)
        +	movl	8(%edx),%edi
        +	movl	%ebp,80(%esp)
        +	movl	12(%edx),%ebx
        +	movl	16(%edx),%ebp
        +
        +	movl	$-1,%edx
        +	subl	%ebx,%edx
        +	movl	20(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%ecx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%edx,1),%ecx
        +	subl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	56(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ebp
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1352829926(%ebp,%eax,1),%ebp
        +	subl	%esi,%edx
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	28(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebx
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1352829926(%ebx,%edx,1),%ebx
        +	subl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%edi
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1352829926(%edi,%eax,1),%edi
        +	subl	%ebp,%edx
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +
        +	movl	36(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1352829926(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +
        +	movl	8(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%eax,1),%ecx
        +	subl	%edi,%edx
        +	roll	$15,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	44(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ebp
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1352829926(%ebp,%edx,1),%ebp
        +	subl	%esi,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	16(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebx
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1352829926(%ebx,%eax,1),%ebx
        +	subl	%ecx,%edx
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	52(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%edi
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	1352829926(%edi,%edx,1),%edi
        +	subl	%ebp,%eax
        +	roll	$7,%edi
        +	addl	%esi,%edi
        +
        +	movl	24(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%esi
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	1352829926(%esi,%eax,1),%esi
        +	subl	%ebx,%edx
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +
        +	movl	60(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%ecx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%edx,1),%ecx
        +	subl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	32(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ebp
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1352829926(%ebp,%eax,1),%ebp
        +	subl	%esi,%edx
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	4(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebx
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1352829926(%ebx,%edx,1),%ebx
        +	subl	%ecx,%eax
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	40(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%edi
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1352829926(%edi,%eax,1),%edi
        +	subl	%ebp,%edx
        +	roll	$14,%edi
        +	addl	%esi,%edi
        +
        +	movl	12(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1352829926(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$12,%esi
        +	addl	%ecx,%esi
        +
        +	movl	48(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%eax,1),%ecx
        +	movl	%edi,%eax
        +	roll	$6,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	44(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1548603684(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$13,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	12(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1548603684(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	28(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1548603684(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%edi
        +	leal	1548603684(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	52(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$8,%ebp
        +	addl	%ebx,%ebp
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	20(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1548603684(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	40(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1548603684(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1548603684(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	60(%esp),%eax
        +	roll	$10,%edi
        +	leal	1548603684(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$7,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	32(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	48(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1548603684(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$7,%ebx
        +	addl	%edi,%ebx
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	16(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1548603684(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	36(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1548603684(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$15,%esi
        +	addl	%ecx,%esi
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%edi
        +	leal	1548603684(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	8(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	subl	%ecx,%edx
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	60(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	20(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1836072691(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$7,%edi
        +	addl	%esi,%edi
        +
        +	movl	4(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1836072691(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$15,%esi
        +	addl	%ecx,%esi
        +
        +	movl	12(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1836072691(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$11,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	28(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1836072691(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$8,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	56(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%eax,1),%ebx
        +	subl	%ebp,%edx
        +	roll	$6,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	24(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%edi
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	1836072691(%edi,%edx,1),%edi
        +	subl	%ebx,%eax
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +
        +	movl	36(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%esi
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	1836072691(%esi,%eax,1),%esi
        +	subl	%edi,%edx
        +	roll	$14,%esi
        +	addl	%ecx,%esi
        +
        +	movl	44(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1836072691(%ecx,%edx,1),%ecx
        +	subl	%esi,%eax
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	32(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebp
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1836072691(%ebp,%eax,1),%ebp
        +	subl	%ecx,%edx
        +	roll	$13,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	48(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	8(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1836072691(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$14,%edi
        +	addl	%esi,%edi
        +
        +	movl	40(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1836072691(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +
        +	movl	(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1836072691(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	16(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1836072691(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	52(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	32(%esp),%edx
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	16(%esp),%edx
        +	roll	$10,%ebx
        +	leal	2053994217(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%edi
        +	leal	2053994217(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	12(%esp),%edx
        +	roll	$10,%esi
        +	leal	2053994217(%ebp,%eax,1),%ebp
        +	movl	$-1,%eax
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +
        +	addl	%edx,%ebx
        +	movl	%ecx,%edx
        +	subl	%ebp,%eax
        +	andl	%ebp,%edx
        +	andl	%esi,%eax
        +	orl	%eax,%edx
        +	movl	44(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2053994217(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	subl	%ebx,%edx
        +	andl	%ebx,%eax
        +	andl	%ecx,%edx
        +	orl	%edx,%eax
        +	movl	60(%esp),%edx
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%eax,1),%edi
        +	movl	$-1,%eax
        +	roll	$14,%edi
        +	addl	%esi,%edi
        +
        +	addl	%edx,%esi
        +	movl	%ebx,%edx
        +	subl	%edi,%eax
        +	andl	%edi,%edx
        +	andl	%ebp,%eax
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2053994217(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	subl	%esi,%edx
        +	andl	%esi,%eax
        +	andl	%ebx,%edx
        +	orl	%edx,%eax
        +	movl	20(%esp),%edx
        +	roll	$10,%edi
        +	leal	2053994217(%ecx,%eax,1),%ecx
        +	movl	$-1,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%edx,%ebp
        +	movl	%esi,%edx
        +	subl	%ecx,%eax
        +	andl	%ecx,%edx
        +	andl	%edi,%eax
        +	orl	%eax,%edx
        +	movl	48(%esp),%eax
        +	roll	$10,%esi
        +	leal	2053994217(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	roll	$6,%ebp
        +	addl	%ebx,%ebp
        +
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	subl	%ebp,%edx
        +	andl	%ebp,%eax
        +	andl	%esi,%edx
        +	orl	%edx,%eax
        +	movl	8(%esp),%edx
        +	roll	$10,%ecx
        +	leal	2053994217(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	52(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	36(%esp),%edx
        +	roll	$10,%ebx
        +	leal	2053994217(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	28(%esp),%eax
        +	roll	$10,%edi
        +	leal	2053994217(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	40(%esp),%edx
        +	roll	$10,%esi
        +	leal	2053994217(%ebp,%eax,1),%ebp
        +	movl	$-1,%eax
        +	roll	$5,%ebp
        +	addl	%ebx,%ebp
        +
        +	addl	%edx,%ebx
        +	movl	%ecx,%edx
        +	subl	%ebp,%eax
        +	andl	%ebp,%edx
        +	andl	%esi,%eax
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2053994217(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	roll	$15,%ebx
        +	addl	%edi,%ebx
        +
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	subl	%ebx,%edx
        +	andl	%ebx,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%edx,1),%edi
        +	xorl	%ebp,%eax
        +	roll	$8,%edi
        +	addl	%esi,%edi
        +
        +	movl	48(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$8,%esi
        +	addl	%ecx,%esi
        +
        +	xorl	%ebx,%eax
        +	movl	60(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	40(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%edx,%ebp
        +	roll	$10,%esi
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +
        +	xorl	%esi,%eax
        +	movl	16(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$10,%ecx
        +	addl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	4(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%edx,%edi
        +	roll	$10,%ebp
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +
        +	xorl	%ebp,%eax
        +	movl	20(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$10,%ebx
        +	addl	%edx,%esi
        +	xorl	%ebx,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +
        +	movl	32(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%edx,%ecx
        +	roll	$10,%edi
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +
        +	xorl	%edi,%eax
        +	movl	28(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$10,%esi
        +	addl	%edx,%ebp
        +	xorl	%esi,%eax
        +	roll	$6,%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	24(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%edx,%ebx
        +	roll	$10,%ecx
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$8,%ebx
        +	addl	%edi,%ebx
        +
        +	xorl	%ecx,%eax
        +	movl	8(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	addl	%edx,%edi
        +	xorl	%ebp,%eax
        +	roll	$13,%edi
        +	addl	%esi,%edi
        +
        +	movl	52(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +
        +	xorl	%ebx,%eax
        +	movl	56(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	addl	%ebp,%ecx
        +
        +	movl	(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%edx,%ebp
        +	roll	$10,%esi
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +
        +	xorl	%esi,%eax
        +	movl	12(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$10,%ecx
        +	addl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$13,%ebx
        +	addl	%edi,%ebx
        +
        +	movl	36(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%edx,%edi
        +	roll	$10,%ebp
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +
        +	xorl	%ebp,%eax
        +	movl	44(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%eax,%esi
        +	roll	$10,%ebx
        +	addl	%edx,%esi
        +	movl	128(%esp),%edx
        +	roll	$11,%esi
        +	addl	%ecx,%esi
        +	movl	4(%edx),%eax
        +	addl	%eax,%ebx
        +	movl	72(%esp),%eax
        +	addl	%eax,%ebx
        +	movl	8(%edx),%eax
        +	addl	%eax,%ebp
        +	movl	76(%esp),%eax
        +	addl	%eax,%ebp
        +	movl	12(%edx),%eax
        +	addl	%eax,%ecx
        +	movl	80(%esp),%eax
        +	addl	%eax,%ecx
        +	movl	16(%edx),%eax
        +	addl	%eax,%esi
        +	movl	64(%esp),%eax
        +	addl	%eax,%esi
        +	movl	(%edx),%eax
        +	addl	%eax,%edi
        +	movl	68(%esp),%eax
        +	addl	%eax,%edi
        +	movl	136(%esp),%eax
        +	movl	%ebx,(%edx)
        +	movl	%ebp,4(%edx)
        +	movl	%ecx,8(%edx)
        +	subl	$1,%eax
        +	movl	%esi,12(%edx)
        +	movl	%edi,16(%edx)
        +	jle	.L001get_out
        +	movl	%eax,136(%esp)
        +	movl	%ecx,%edi
        +	movl	132(%esp),%eax
        +	movl	%ebx,%ecx
        +	addl	$64,%eax
        +	movl	%ebp,%esi
        +	movl	%eax,132(%esp)
        +	jmp	.L000start
        +.L001get_out:
        +	addl	$108,%esp
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.size	ripemd160_block_asm_data_order,.-.L_ripemd160_block_asm_data_order_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/sha/sha1-586.s b/vendor/openssl/asm/x86-elf-gas/sha/sha1-586.s
        new file mode 100644
        index 000000000..e77f65412
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/sha/sha1-586.s
        @@ -0,0 +1,1380 @@
        +.file	"sha1-586.s"
        +.text
        +.globl	sha1_block_data_order
        +.type	sha1_block_data_order,@function
        +.align	16
        +sha1_block_data_order:
        +.L_sha1_block_data_order_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%ebp
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%eax
        +	subl	$76,%esp
        +	shll	$6,%eax
        +	addl	%esi,%eax
        +	movl	%eax,104(%esp)
        +	movl	16(%ebp),%edi
        +	jmp	.L000loop
        +.align	16
        +.L000loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	movl	%ecx,24(%esp)
        +	movl	%edx,28(%esp)
        +	movl	32(%esi),%eax
        +	movl	36(%esi),%ebx
        +	movl	40(%esi),%ecx
        +	movl	44(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,40(%esp)
        +	movl	%edx,44(%esp)
        +	movl	48(%esi),%eax
        +	movl	52(%esi),%ebx
        +	movl	56(%esi),%ecx
        +	movl	60(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,48(%esp)
        +	movl	%ebx,52(%esp)
        +	movl	%ecx,56(%esp)
        +	movl	%edx,60(%esp)
        +	movl	%esi,100(%esp)
        +	movl	(%ebp),%eax
        +	movl	4(%ebp),%ebx
        +	movl	8(%ebp),%ecx
        +	movl	12(%ebp),%edx
        +
        +	movl	%ecx,%esi
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	xorl	%edx,%esi
        +	addl	%edi,%ebp
        +	movl	(%esp),%edi
        +	andl	%ebx,%esi
        +	rorl	$2,%ebx
        +	xorl	%edx,%esi
        +	leal	1518500249(%ebp,%edi,1),%ebp
        +	addl	%esi,%ebp
        +
        +	movl	%ebx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ecx,%edi
        +	addl	%edx,%ebp
        +	movl	4(%esp),%edx
        +	andl	%eax,%edi
        +	rorl	$2,%eax
        +	xorl	%ecx,%edi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	addl	%edi,%ebp
        +
        +	movl	%eax,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edx
        +	addl	%ecx,%ebp
        +	movl	8(%esp),%ecx
        +	andl	%esi,%edx
        +	rorl	$2,%esi
        +	xorl	%ebx,%edx
        +	leal	1518500249(%ebp,%ecx,1),%ebp
        +	addl	%edx,%ebp
        +
        +	movl	%esi,%ecx
        +	movl	%ebp,%edx
        +	roll	$5,%ebp
        +	xorl	%eax,%ecx
        +	addl	%ebx,%ebp
        +	movl	12(%esp),%ebx
        +	andl	%edi,%ecx
        +	rorl	$2,%edi
        +	xorl	%eax,%ecx
        +	leal	1518500249(%ebp,%ebx,1),%ebp
        +	addl	%ecx,%ebp
        +
        +	movl	%edi,%ebx
        +	movl	%ebp,%ecx
        +	roll	$5,%ebp
        +	xorl	%esi,%ebx
        +	addl	%eax,%ebp
        +	movl	16(%esp),%eax
        +	andl	%edx,%ebx
        +	rorl	$2,%edx
        +	xorl	%esi,%ebx
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	%edx,%eax
        +	movl	%ebp,%ebx
        +	roll	$5,%ebp
        +	xorl	%edi,%eax
        +	addl	%esi,%ebp
        +	movl	20(%esp),%esi
        +	andl	%ecx,%eax
        +	rorl	$2,%ecx
        +	xorl	%edi,%eax
        +	leal	1518500249(%ebp,%esi,1),%ebp
        +	addl	%eax,%ebp
        +
        +	movl	%ecx,%esi
        +	movl	%ebp,%eax
        +	roll	$5,%ebp
        +	xorl	%edx,%esi
        +	addl	%edi,%ebp
        +	movl	24(%esp),%edi
        +	andl	%ebx,%esi
        +	rorl	$2,%ebx
        +	xorl	%edx,%esi
        +	leal	1518500249(%ebp,%edi,1),%ebp
        +	addl	%esi,%ebp
        +
        +	movl	%ebx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ecx,%edi
        +	addl	%edx,%ebp
        +	movl	28(%esp),%edx
        +	andl	%eax,%edi
        +	rorl	$2,%eax
        +	xorl	%ecx,%edi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	addl	%edi,%ebp
        +
        +	movl	%eax,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edx
        +	addl	%ecx,%ebp
        +	movl	32(%esp),%ecx
        +	andl	%esi,%edx
        +	rorl	$2,%esi
        +	xorl	%ebx,%edx
        +	leal	1518500249(%ebp,%ecx,1),%ebp
        +	addl	%edx,%ebp
        +
        +	movl	%esi,%ecx
        +	movl	%ebp,%edx
        +	roll	$5,%ebp
        +	xorl	%eax,%ecx
        +	addl	%ebx,%ebp
        +	movl	36(%esp),%ebx
        +	andl	%edi,%ecx
        +	rorl	$2,%edi
        +	xorl	%eax,%ecx
        +	leal	1518500249(%ebp,%ebx,1),%ebp
        +	addl	%ecx,%ebp
        +
        +	movl	%edi,%ebx
        +	movl	%ebp,%ecx
        +	roll	$5,%ebp
        +	xorl	%esi,%ebx
        +	addl	%eax,%ebp
        +	movl	40(%esp),%eax
        +	andl	%edx,%ebx
        +	rorl	$2,%edx
        +	xorl	%esi,%ebx
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	addl	%ebx,%ebp
        +
        +	movl	%edx,%eax
        +	movl	%ebp,%ebx
        +	roll	$5,%ebp
        +	xorl	%edi,%eax
        +	addl	%esi,%ebp
        +	movl	44(%esp),%esi
        +	andl	%ecx,%eax
        +	rorl	$2,%ecx
        +	xorl	%edi,%eax
        +	leal	1518500249(%ebp,%esi,1),%ebp
        +	addl	%eax,%ebp
        +
        +	movl	%ecx,%esi
        +	movl	%ebp,%eax
        +	roll	$5,%ebp
        +	xorl	%edx,%esi
        +	addl	%edi,%ebp
        +	movl	48(%esp),%edi
        +	andl	%ebx,%esi
        +	rorl	$2,%ebx
        +	xorl	%edx,%esi
        +	leal	1518500249(%ebp,%edi,1),%ebp
        +	addl	%esi,%ebp
        +
        +	movl	%ebx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ecx,%edi
        +	addl	%edx,%ebp
        +	movl	52(%esp),%edx
        +	andl	%eax,%edi
        +	rorl	$2,%eax
        +	xorl	%ecx,%edi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	addl	%edi,%ebp
        +
        +	movl	%eax,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edx
        +	addl	%ecx,%ebp
        +	movl	56(%esp),%ecx
        +	andl	%esi,%edx
        +	rorl	$2,%esi
        +	xorl	%ebx,%edx
        +	leal	1518500249(%ebp,%ecx,1),%ebp
        +	addl	%edx,%ebp
        +
        +	movl	%esi,%ecx
        +	movl	%ebp,%edx
        +	roll	$5,%ebp
        +	xorl	%eax,%ecx
        +	addl	%ebx,%ebp
        +	movl	60(%esp),%ebx
        +	andl	%edi,%ecx
        +	rorl	$2,%edi
        +	xorl	%eax,%ecx
        +	leal	1518500249(%ebp,%ebx,1),%ebp
        +	movl	(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edi,%ebp
        +	xorl	8(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	32(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	52(%esp),%ebx
        +	roll	$1,%ebx
        +	xorl	%esi,%ebp
        +	addl	%ebp,%eax
        +	movl	%ecx,%ebp
        +	rorl	$2,%edx
        +	movl	%ebx,(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%ebx,%eax,1),%ebx
        +	movl	4(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%edx,%ebp
        +	xorl	12(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	36(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	56(%esp),%eax
        +	roll	$1,%eax
        +	xorl	%edi,%ebp
        +	addl	%ebp,%esi
        +	movl	%ebx,%ebp
        +	rorl	$2,%ecx
        +	movl	%eax,4(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%eax,%esi,1),%eax
        +	movl	8(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ecx,%ebp
        +	xorl	16(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	40(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	60(%esp),%esi
        +	roll	$1,%esi
        +	xorl	%edx,%ebp
        +	addl	%ebp,%edi
        +	movl	%eax,%ebp
        +	rorl	$2,%ebx
        +	movl	%esi,8(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%esi,%edi,1),%esi
        +	movl	12(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%ebx,%ebp
        +	xorl	20(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	44(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	(%esp),%edi
        +	roll	$1,%edi
        +	xorl	%ecx,%ebp
        +	addl	%ebp,%edx
        +	movl	%esi,%ebp
        +	rorl	$2,%eax
        +	movl	%edi,12(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%edi,%edx,1),%edi
        +	movl	16(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	24(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,16(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	20(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	28(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,20(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	24(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edx,%ebp
        +	xorl	32(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,24(%esp)
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	28(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%ecx,%ebp
        +	xorl	36(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,28(%esp)
        +	leal	1859775393(%eax,%esi,1),%eax
        +	movl	32(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	40(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,32(%esp)
        +	leal	1859775393(%esi,%edi,1),%esi
        +	movl	36(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	44(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,36(%esp)
        +	leal	1859775393(%edi,%edx,1),%edi
        +	movl	40(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,40(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	44(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	32(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,44(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	48(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edx,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	36(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,48(%esp)
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	52(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%ecx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	40(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,52(%esp)
        +	leal	1859775393(%eax,%esi,1),%eax
        +	movl	56(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	44(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,56(%esp)
        +	leal	1859775393(%esi,%edi,1),%esi
        +	movl	60(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	48(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,60(%esp)
        +	leal	1859775393(%edi,%edx,1),%edi
        +	movl	(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	8(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	32(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	52(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	4(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	12(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	36(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	56(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,4(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	8(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edx,%ebp
        +	xorl	16(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	40(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	60(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,8(%esp)
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	12(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%ecx,%ebp
        +	xorl	20(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	44(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,12(%esp)
        +	leal	1859775393(%eax,%esi,1),%eax
        +	movl	16(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	24(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	48(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	4(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,16(%esp)
        +	leal	1859775393(%esi,%edi,1),%esi
        +	movl	20(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	28(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	52(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	8(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,20(%esp)
        +	leal	1859775393(%edi,%edx,1),%edi
        +	movl	24(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	32(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	56(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	12(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,24(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	28(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	36(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	60(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	16(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,28(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	32(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edi,%ebp
        +	xorl	40(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	20(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,32(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	36(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%edx,%ebp
        +	xorl	44(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	4(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	24(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,36(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	40(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ecx,%ebp
        +	xorl	48(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	8(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	28(%esp),%esi
        +	roll	$1,%esi
        +	addl	%edi,%ebp
        +	rorl	$2,%ebx
        +	movl	%eax,%edi
        +	roll	$5,%edi
        +	movl	%esi,40(%esp)
        +	leal	2400959708(%esi,%ebp,1),%esi
        +	movl	%ecx,%ebp
        +	addl	%edi,%esi
        +	andl	%edx,%ebp
        +	movl	44(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%ebx,%ebp
        +	xorl	52(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	12(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	32(%esp),%edi
        +	roll	$1,%edi
        +	addl	%edx,%ebp
        +	rorl	$2,%eax
        +	movl	%esi,%edx
        +	roll	$5,%edx
        +	movl	%edi,44(%esp)
        +	leal	2400959708(%edi,%ebp,1),%edi
        +	movl	%ebx,%ebp
        +	addl	%edx,%edi
        +	andl	%ecx,%ebp
        +	movl	48(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%eax,%ebp
        +	xorl	56(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	16(%esp),%edx
        +	andl	%esi,%ebp
        +	xorl	36(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ecx,%ebp
        +	rorl	$2,%esi
        +	movl	%edi,%ecx
        +	roll	$5,%ecx
        +	movl	%edx,48(%esp)
        +	leal	2400959708(%edx,%ebp,1),%edx
        +	movl	%eax,%ebp
        +	addl	%ecx,%edx
        +	andl	%ebx,%ebp
        +	movl	52(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%esi,%ebp
        +	xorl	60(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	20(%esp),%ecx
        +	andl	%edi,%ebp
        +	xorl	40(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebx,%ebp
        +	rorl	$2,%edi
        +	movl	%edx,%ebx
        +	roll	$5,%ebx
        +	movl	%ecx,52(%esp)
        +	leal	2400959708(%ecx,%ebp,1),%ecx
        +	movl	%esi,%ebp
        +	addl	%ebx,%ecx
        +	andl	%eax,%ebp
        +	movl	56(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edi,%ebp
        +	xorl	(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	24(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	44(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,56(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	60(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%edx,%ebp
        +	xorl	4(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	28(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	48(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,60(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ecx,%ebp
        +	xorl	8(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	32(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	52(%esp),%esi
        +	roll	$1,%esi
        +	addl	%edi,%ebp
        +	rorl	$2,%ebx
        +	movl	%eax,%edi
        +	roll	$5,%edi
        +	movl	%esi,(%esp)
        +	leal	2400959708(%esi,%ebp,1),%esi
        +	movl	%ecx,%ebp
        +	addl	%edi,%esi
        +	andl	%edx,%ebp
        +	movl	4(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%ebx,%ebp
        +	xorl	12(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	36(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	56(%esp),%edi
        +	roll	$1,%edi
        +	addl	%edx,%ebp
        +	rorl	$2,%eax
        +	movl	%esi,%edx
        +	roll	$5,%edx
        +	movl	%edi,4(%esp)
        +	leal	2400959708(%edi,%ebp,1),%edi
        +	movl	%ebx,%ebp
        +	addl	%edx,%edi
        +	andl	%ecx,%ebp
        +	movl	8(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%eax,%ebp
        +	xorl	16(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	40(%esp),%edx
        +	andl	%esi,%ebp
        +	xorl	60(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ecx,%ebp
        +	rorl	$2,%esi
        +	movl	%edi,%ecx
        +	roll	$5,%ecx
        +	movl	%edx,8(%esp)
        +	leal	2400959708(%edx,%ebp,1),%edx
        +	movl	%eax,%ebp
        +	addl	%ecx,%edx
        +	andl	%ebx,%ebp
        +	movl	12(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%esi,%ebp
        +	xorl	20(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	44(%esp),%ecx
        +	andl	%edi,%ebp
        +	xorl	(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebx,%ebp
        +	rorl	$2,%edi
        +	movl	%edx,%ebx
        +	roll	$5,%ebx
        +	movl	%ecx,12(%esp)
        +	leal	2400959708(%ecx,%ebp,1),%ecx
        +	movl	%esi,%ebp
        +	addl	%ebx,%ecx
        +	andl	%eax,%ebp
        +	movl	16(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edi,%ebp
        +	xorl	24(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	48(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	4(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,16(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	20(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%edx,%ebp
        +	xorl	28(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	52(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	8(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,20(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	24(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ecx,%ebp
        +	xorl	32(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	56(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	12(%esp),%esi
        +	roll	$1,%esi
        +	addl	%edi,%ebp
        +	rorl	$2,%ebx
        +	movl	%eax,%edi
        +	roll	$5,%edi
        +	movl	%esi,24(%esp)
        +	leal	2400959708(%esi,%ebp,1),%esi
        +	movl	%ecx,%ebp
        +	addl	%edi,%esi
        +	andl	%edx,%ebp
        +	movl	28(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%ebx,%ebp
        +	xorl	36(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	60(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	16(%esp),%edi
        +	roll	$1,%edi
        +	addl	%edx,%ebp
        +	rorl	$2,%eax
        +	movl	%esi,%edx
        +	roll	$5,%edx
        +	movl	%edi,28(%esp)
        +	leal	2400959708(%edi,%ebp,1),%edi
        +	movl	%ebx,%ebp
        +	addl	%edx,%edi
        +	andl	%ecx,%ebp
        +	movl	32(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%eax,%ebp
        +	xorl	40(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	(%esp),%edx
        +	andl	%esi,%ebp
        +	xorl	20(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ecx,%ebp
        +	rorl	$2,%esi
        +	movl	%edi,%ecx
        +	roll	$5,%ecx
        +	movl	%edx,32(%esp)
        +	leal	2400959708(%edx,%ebp,1),%edx
        +	movl	%eax,%ebp
        +	addl	%ecx,%edx
        +	andl	%ebx,%ebp
        +	movl	36(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%esi,%ebp
        +	xorl	44(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	4(%esp),%ecx
        +	andl	%edi,%ebp
        +	xorl	24(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebx,%ebp
        +	rorl	$2,%edi
        +	movl	%edx,%ebx
        +	roll	$5,%ebx
        +	movl	%ecx,36(%esp)
        +	leal	2400959708(%ecx,%ebp,1),%ecx
        +	movl	%esi,%ebp
        +	addl	%ebx,%ecx
        +	andl	%eax,%ebp
        +	movl	40(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edi,%ebp
        +	xorl	48(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	8(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	28(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,40(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	44(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%edx,%ebp
        +	xorl	52(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	12(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	32(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,44(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	48(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	56(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	16(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	36(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,48(%esp)
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	52(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	60(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	20(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	40(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,52(%esp)
        +	leal	3395469782(%edi,%edx,1),%edi
        +	movl	56(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	24(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	44(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,56(%esp)
        +	leal	3395469782(%edx,%ecx,1),%edx
        +	movl	60(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	4(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	28(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	48(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,60(%esp)
        +	leal	3395469782(%ecx,%ebx,1),%ecx
        +	movl	(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edx,%ebp
        +	xorl	8(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	32(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	52(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,(%esp)
        +	leal	3395469782(%ebx,%eax,1),%ebx
        +	movl	4(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%ecx,%ebp
        +	xorl	12(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	36(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	56(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,4(%esp)
        +	leal	3395469782(%eax,%esi,1),%eax
        +	movl	8(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	16(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	40(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	60(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,8(%esp)
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	12(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	20(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	44(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,12(%esp)
        +	leal	3395469782(%edi,%edx,1),%edi
        +	movl	16(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	24(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,16(%esp)
        +	leal	3395469782(%edx,%ecx,1),%edx
        +	movl	20(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	28(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,20(%esp)
        +	leal	3395469782(%ecx,%ebx,1),%ecx
        +	movl	24(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edx,%ebp
        +	xorl	32(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,24(%esp)
        +	leal	3395469782(%ebx,%eax,1),%ebx
        +	movl	28(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%ecx,%ebp
        +	xorl	36(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,28(%esp)
        +	leal	3395469782(%eax,%esi,1),%eax
        +	movl	32(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	40(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,32(%esp)
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	36(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	44(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,36(%esp)
        +	leal	3395469782(%edi,%edx,1),%edi
        +	movl	40(%esp),%edx
        +	addl	%ebp,%edi
        +
        +	movl	%esi,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,40(%esp)
        +	leal	3395469782(%edx,%ecx,1),%edx
        +	movl	44(%esp),%ecx
        +	addl	%ebp,%edx
        +
        +	movl	%edi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	32(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,44(%esp)
        +	leal	3395469782(%ecx,%ebx,1),%ecx
        +	movl	48(%esp),%ebx
        +	addl	%ebp,%ecx
        +
        +	movl	%edx,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	36(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,48(%esp)
        +	leal	3395469782(%ebx,%eax,1),%ebx
        +	movl	52(%esp),%eax
        +	addl	%ebp,%ebx
        +
        +	movl	%ecx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	40(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	leal	3395469782(%eax,%esi,1),%eax
        +	movl	56(%esp),%esi
        +	addl	%ebp,%eax
        +
        +	movl	%ebx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	44(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	60(%esp),%edi
        +	addl	%ebp,%esi
        +
        +	movl	%eax,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	48(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	leal	3395469782(%edi,%edx,1),%edi
        +	addl	%ebp,%edi
        +	movl	96(%esp),%ebp
        +	movl	100(%esp),%edx
        +	addl	(%ebp),%edi
        +	addl	4(%ebp),%esi
        +	addl	8(%ebp),%eax
        +	addl	12(%ebp),%ebx
        +	addl	16(%ebp),%ecx
        +	movl	%edi,(%ebp)
        +	addl	$64,%edx
        +	movl	%esi,4(%ebp)
        +	cmpl	104(%esp),%edx
        +	movl	%eax,8(%ebp)
        +	movl	%ecx,%edi
        +	movl	%ebx,12(%ebp)
        +	movl	%edx,%esi
        +	movl	%ecx,16(%ebp)
        +	jb	.L000loop
        +	addl	$76,%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	sha1_block_data_order,.-.L_sha1_block_data_order_begin
        +.byte	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115
        +.byte	102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82
        +.byte	89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112
        +.byte	114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-elf-gas/sha/sha256-586.s b/vendor/openssl/asm/x86-elf-gas/sha/sha256-586.s
        new file mode 100644
        index 000000000..77a89514f
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/sha/sha256-586.s
        @@ -0,0 +1,258 @@
        +.file	"sha512-586.s"
        +.text
        +.globl	sha256_block_data_order
        +.type	sha256_block_data_order,@function
        +.align	16
        +sha256_block_data_order:
        +.L_sha256_block_data_order_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	%esp,%ebx
        +	call	.L000pic_point
        +.L000pic_point:
        +	popl	%ebp
        +	leal	.L001K256-.L000pic_point(%ebp),%ebp
        +	subl	$16,%esp
        +	andl	$-64,%esp
        +	shll	$6,%eax
        +	addl	%edi,%eax
        +	movl	%esi,(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +.align	16
        +.L002loop:
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	16(%edi),%eax
        +	movl	20(%edi),%ebx
        +	movl	24(%edi),%ecx
        +	movl	28(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	32(%edi),%eax
        +	movl	36(%edi),%ebx
        +	movl	40(%edi),%ecx
        +	movl	44(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	48(%edi),%eax
        +	movl	52(%edi),%ebx
        +	movl	56(%edi),%ecx
        +	movl	60(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	addl	$64,%edi
        +	subl	$32,%esp
        +	movl	%edi,100(%esp)
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edi
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edi,12(%esp)
        +	movl	16(%esi),%edx
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edi
        +	movl	%ebx,20(%esp)
        +	movl	%ecx,24(%esp)
        +	movl	%edi,28(%esp)
        +.align	16
        +.L00300_15:
        +	movl	92(%esp),%ebx
        +	movl	%edx,%ecx
        +	rorl	$14,%ecx
        +	movl	20(%esp),%esi
        +	xorl	%edx,%ecx
        +	rorl	$5,%ecx
        +	xorl	%edx,%ecx
        +	rorl	$6,%ecx
        +	movl	24(%esp),%edi
        +	addl	%ecx,%ebx
        +	xorl	%edi,%esi
        +	movl	%edx,16(%esp)
        +	movl	%eax,%ecx
        +	andl	%edx,%esi
        +	movl	12(%esp),%edx
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	addl	%esi,%ebx
        +	rorl	$9,%ecx
        +	addl	28(%esp),%ebx
        +	xorl	%eax,%ecx
        +	rorl	$11,%ecx
        +	movl	4(%esp),%esi
        +	xorl	%eax,%ecx
        +	rorl	$2,%ecx
        +	addl	%ebx,%edx
        +	movl	8(%esp),%edi
        +	addl	%ecx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%eax,%ecx
        +	subl	$4,%esp
        +	orl	%esi,%eax
        +	andl	%esi,%ecx
        +	andl	%edi,%eax
        +	movl	(%ebp),%esi
        +	orl	%ecx,%eax
        +	addl	$4,%ebp
        +	addl	%ebx,%eax
        +	addl	%esi,%edx
        +	addl	%esi,%eax
        +	cmpl	$3248222580,%esi
        +	jne	.L00300_15
        +	movl	152(%esp),%ebx
        +.align	16
        +.L00416_63:
        +	movl	%ebx,%esi
        +	movl	100(%esp),%ecx
        +	rorl	$11,%esi
        +	movl	%ecx,%edi
        +	xorl	%ebx,%esi
        +	rorl	$7,%esi
        +	shrl	$3,%ebx
        +	rorl	$2,%edi
        +	xorl	%esi,%ebx
        +	xorl	%ecx,%edi
        +	rorl	$17,%edi
        +	shrl	$10,%ecx
        +	addl	156(%esp),%ebx
        +	xorl	%ecx,%edi
        +	addl	120(%esp),%ebx
        +	movl	%edx,%ecx
        +	addl	%edi,%ebx
        +	rorl	$14,%ecx
        +	movl	20(%esp),%esi
        +	xorl	%edx,%ecx
        +	rorl	$5,%ecx
        +	movl	%ebx,92(%esp)
        +	xorl	%edx,%ecx
        +	rorl	$6,%ecx
        +	movl	24(%esp),%edi
        +	addl	%ecx,%ebx
        +	xorl	%edi,%esi
        +	movl	%edx,16(%esp)
        +	movl	%eax,%ecx
        +	andl	%edx,%esi
        +	movl	12(%esp),%edx
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	addl	%esi,%ebx
        +	rorl	$9,%ecx
        +	addl	28(%esp),%ebx
        +	xorl	%eax,%ecx
        +	rorl	$11,%ecx
        +	movl	4(%esp),%esi
        +	xorl	%eax,%ecx
        +	rorl	$2,%ecx
        +	addl	%ebx,%edx
        +	movl	8(%esp),%edi
        +	addl	%ecx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%eax,%ecx
        +	subl	$4,%esp
        +	orl	%esi,%eax
        +	andl	%esi,%ecx
        +	andl	%edi,%eax
        +	movl	(%ebp),%esi
        +	orl	%ecx,%eax
        +	addl	$4,%ebp
        +	addl	%ebx,%eax
        +	movl	152(%esp),%ebx
        +	addl	%esi,%edx
        +	addl	%esi,%eax
        +	cmpl	$3329325298,%esi
        +	jne	.L00416_63
        +	movl	352(%esp),%esi
        +	movl	4(%esp),%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edi
        +	addl	(%esi),%eax
        +	addl	4(%esi),%ebx
        +	addl	8(%esi),%ecx
        +	addl	12(%esi),%edi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edi,12(%esi)
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%ebx
        +	movl	28(%esp),%ecx
        +	movl	356(%esp),%edi
        +	addl	16(%esi),%edx
        +	addl	20(%esi),%eax
        +	addl	24(%esi),%ebx
        +	addl	28(%esi),%ecx
        +	movl	%edx,16(%esi)
        +	movl	%eax,20(%esi)
        +	movl	%ebx,24(%esi)
        +	movl	%ecx,28(%esi)
        +	addl	$352,%esp
        +	subl	$256,%ebp
        +	cmpl	8(%esp),%edi
        +	jb	.L002loop
        +	movl	12(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L001K256:
        +.long	1116352408,1899447441,3049323471,3921009573
        +.long	961987163,1508970993,2453635748,2870763221
        +.long	3624381080,310598401,607225278,1426881987
        +.long	1925078388,2162078206,2614888103,3248222580
        +.long	3835390401,4022224774,264347078,604807628
        +.long	770255983,1249150122,1555081692,1996064986
        +.long	2554220882,2821834349,2952996808,3210313671
        +.long	3336571891,3584528711,113926993,338241895
        +.long	666307205,773529912,1294757372,1396182291
        +.long	1695183700,1986661051,2177026350,2456956037
        +.long	2730485921,2820302411,3259730800,3345764771
        +.long	3516065817,3600352804,4094571909,275423344
        +.long	430227734,506948616,659060556,883997877
        +.long	958139571,1322822218,1537002063,1747873779
        +.long	1955562222,2024104815,2227730452,2361852424
        +.long	2428436474,2756734187,3204031479,3329325298
        +.size	sha256_block_data_order,.-.L_sha256_block_data_order_begin
        +.byte	83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97
        +.byte	110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32
        +.byte	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +.byte	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +.byte	62,0
        diff --git a/vendor/openssl/asm/x86-elf-gas/sha/sha512-586.s b/vendor/openssl/asm/x86-elf-gas/sha/sha512-586.s
        new file mode 100644
        index 000000000..4b806f352
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/sha/sha512-586.s
        @@ -0,0 +1,563 @@
        +.file	"sha512-586.s"
        +.text
        +.globl	sha512_block_data_order
        +.type	sha512_block_data_order,@function
        +.align	16
        +sha512_block_data_order:
        +.L_sha512_block_data_order_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	%esp,%ebx
        +	call	.L000pic_point
        +.L000pic_point:
        +	popl	%ebp
        +	leal	.L001K512-.L000pic_point(%ebp),%ebp
        +	subl	$16,%esp
        +	andl	$-64,%esp
        +	shll	$7,%eax
        +	addl	%edi,%eax
        +	movl	%esi,(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +.align	16
        +.L002loop_x86:
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	16(%edi),%eax
        +	movl	20(%edi),%ebx
        +	movl	24(%edi),%ecx
        +	movl	28(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	32(%edi),%eax
        +	movl	36(%edi),%ebx
        +	movl	40(%edi),%ecx
        +	movl	44(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	48(%edi),%eax
        +	movl	52(%edi),%ebx
        +	movl	56(%edi),%ecx
        +	movl	60(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	64(%edi),%eax
        +	movl	68(%edi),%ebx
        +	movl	72(%edi),%ecx
        +	movl	76(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	80(%edi),%eax
        +	movl	84(%edi),%ebx
        +	movl	88(%edi),%ecx
        +	movl	92(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	96(%edi),%eax
        +	movl	100(%edi),%ebx
        +	movl	104(%edi),%ecx
        +	movl	108(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	112(%edi),%eax
        +	movl	116(%edi),%ebx
        +	movl	120(%edi),%ecx
        +	movl	124(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	addl	$128,%edi
        +	subl	$72,%esp
        +	movl	%edi,204(%esp)
        +	leal	8(%esp),%edi
        +	movl	$16,%ecx
        +.long	2784229001
        +.align	16
        +.L00300_15_x86:
        +	movl	40(%esp),%ecx
        +	movl	44(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$9,%ecx
        +	movl	%edx,%edi
        +	shrl	$9,%edx
        +	movl	%ecx,%ebx
        +	shll	$14,%esi
        +	movl	%edx,%eax
        +	shll	$14,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%eax
        +	shll	$4,%esi
        +	xorl	%edx,%ebx
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$4,%ecx
        +	xorl	%edi,%eax
        +	shrl	$4,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	48(%esp),%ecx
        +	movl	52(%esp),%edx
        +	movl	56(%esp),%esi
        +	movl	60(%esp),%edi
        +	addl	64(%esp),%eax
        +	adcl	68(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	andl	40(%esp),%ecx
        +	andl	44(%esp),%edx
        +	addl	192(%esp),%eax
        +	adcl	196(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	movl	(%ebp),%esi
        +	movl	4(%ebp),%edi
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	32(%esp),%ecx
        +	movl	36(%esp),%edx
        +	addl	%esi,%eax
        +	adcl	%edi,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,%esi
        +	shrl	$2,%ecx
        +	movl	%edx,%edi
        +	shrl	$2,%edx
        +	movl	%ecx,%ebx
        +	shll	$4,%esi
        +	movl	%edx,%eax
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%ebx
        +	shll	$21,%esi
        +	xorl	%edx,%eax
        +	shll	$21,%edi
        +	xorl	%esi,%eax
        +	shrl	$21,%ecx
        +	xorl	%edi,%ebx
        +	shrl	$21,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	16(%esp),%esi
        +	movl	20(%esp),%edi
        +	addl	(%esp),%eax
        +	adcl	4(%esp),%ebx
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	andl	24(%esp),%ecx
        +	andl	28(%esp),%edx
        +	andl	8(%esp),%esi
        +	andl	12(%esp),%edi
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movb	(%ebp),%dl
        +	subl	$8,%esp
        +	leal	8(%ebp),%ebp
        +	cmpb	$148,%dl
        +	jne	.L00300_15_x86
        +.align	16
        +.L00416_79_x86:
        +	movl	312(%esp),%ecx
        +	movl	316(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$1,%ecx
        +	movl	%edx,%edi
        +	shrl	$1,%edx
        +	movl	%ecx,%eax
        +	shll	$24,%esi
        +	movl	%edx,%ebx
        +	shll	$24,%edi
        +	xorl	%esi,%ebx
        +	shrl	$6,%ecx
        +	xorl	%edi,%eax
        +	shrl	$6,%edx
        +	xorl	%ecx,%eax
        +	shll	$7,%esi
        +	xorl	%edx,%ebx
        +	shll	$1,%edi
        +	xorl	%esi,%ebx
        +	shrl	$1,%ecx
        +	xorl	%edi,%eax
        +	shrl	$1,%edx
        +	xorl	%ecx,%eax
        +	shll	$6,%edi
        +	xorl	%edx,%ebx
        +	xorl	%edi,%eax
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	208(%esp),%ecx
        +	movl	212(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$6,%ecx
        +	movl	%edx,%edi
        +	shrl	$6,%edx
        +	movl	%ecx,%eax
        +	shll	$3,%esi
        +	movl	%edx,%ebx
        +	shll	$3,%edi
        +	xorl	%esi,%eax
        +	shrl	$13,%ecx
        +	xorl	%edi,%ebx
        +	shrl	$13,%edx
        +	xorl	%ecx,%eax
        +	shll	$10,%esi
        +	xorl	%edx,%ebx
        +	shll	$10,%edi
        +	xorl	%esi,%ebx
        +	shrl	$10,%ecx
        +	xorl	%edi,%eax
        +	shrl	$10,%edx
        +	xorl	%ecx,%ebx
        +	shll	$13,%edi
        +	xorl	%edx,%eax
        +	xorl	%edi,%eax
        +	movl	320(%esp),%ecx
        +	movl	324(%esp),%edx
        +	addl	(%esp),%eax
        +	adcl	4(%esp),%ebx
        +	movl	248(%esp),%esi
        +	movl	252(%esp),%edi
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	addl	%esi,%eax
        +	adcl	%edi,%ebx
        +	movl	%eax,192(%esp)
        +	movl	%ebx,196(%esp)
        +	movl	40(%esp),%ecx
        +	movl	44(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$9,%ecx
        +	movl	%edx,%edi
        +	shrl	$9,%edx
        +	movl	%ecx,%ebx
        +	shll	$14,%esi
        +	movl	%edx,%eax
        +	shll	$14,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%eax
        +	shll	$4,%esi
        +	xorl	%edx,%ebx
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$4,%ecx
        +	xorl	%edi,%eax
        +	shrl	$4,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	48(%esp),%ecx
        +	movl	52(%esp),%edx
        +	movl	56(%esp),%esi
        +	movl	60(%esp),%edi
        +	addl	64(%esp),%eax
        +	adcl	68(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	andl	40(%esp),%ecx
        +	andl	44(%esp),%edx
        +	addl	192(%esp),%eax
        +	adcl	196(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	movl	(%ebp),%esi
        +	movl	4(%ebp),%edi
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	32(%esp),%ecx
        +	movl	36(%esp),%edx
        +	addl	%esi,%eax
        +	adcl	%edi,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,%esi
        +	shrl	$2,%ecx
        +	movl	%edx,%edi
        +	shrl	$2,%edx
        +	movl	%ecx,%ebx
        +	shll	$4,%esi
        +	movl	%edx,%eax
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%ebx
        +	shll	$21,%esi
        +	xorl	%edx,%eax
        +	shll	$21,%edi
        +	xorl	%esi,%eax
        +	shrl	$21,%ecx
        +	xorl	%edi,%ebx
        +	shrl	$21,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	16(%esp),%esi
        +	movl	20(%esp),%edi
        +	addl	(%esp),%eax
        +	adcl	4(%esp),%ebx
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	andl	24(%esp),%ecx
        +	andl	28(%esp),%edx
        +	andl	8(%esp),%esi
        +	andl	12(%esp),%edi
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movb	(%ebp),%dl
        +	subl	$8,%esp
        +	leal	8(%ebp),%ebp
        +	cmpb	$23,%dl
        +	jne	.L00416_79_x86
        +	movl	840(%esp),%esi
        +	movl	844(%esp),%edi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	addl	8(%esp),%eax
        +	adcl	12(%esp),%ebx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	addl	16(%esp),%ecx
        +	adcl	20(%esp),%edx
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	addl	24(%esp),%eax
        +	adcl	28(%esp),%ebx
        +	movl	%eax,16(%esi)
        +	movl	%ebx,20(%esi)
        +	addl	32(%esp),%ecx
        +	adcl	36(%esp),%edx
        +	movl	%ecx,24(%esi)
        +	movl	%edx,28(%esi)
        +	movl	32(%esi),%eax
        +	movl	36(%esi),%ebx
        +	movl	40(%esi),%ecx
        +	movl	44(%esi),%edx
        +	addl	40(%esp),%eax
        +	adcl	44(%esp),%ebx
        +	movl	%eax,32(%esi)
        +	movl	%ebx,36(%esi)
        +	addl	48(%esp),%ecx
        +	adcl	52(%esp),%edx
        +	movl	%ecx,40(%esi)
        +	movl	%edx,44(%esi)
        +	movl	48(%esi),%eax
        +	movl	52(%esi),%ebx
        +	movl	56(%esi),%ecx
        +	movl	60(%esi),%edx
        +	addl	56(%esp),%eax
        +	adcl	60(%esp),%ebx
        +	movl	%eax,48(%esi)
        +	movl	%ebx,52(%esi)
        +	addl	64(%esp),%ecx
        +	adcl	68(%esp),%edx
        +	movl	%ecx,56(%esi)
        +	movl	%edx,60(%esi)
        +	addl	$840,%esp
        +	subl	$640,%ebp
        +	cmpl	8(%esp),%edi
        +	jb	.L002loop_x86
        +	movl	12(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L001K512:
        +.long	3609767458,1116352408
        +.long	602891725,1899447441
        +.long	3964484399,3049323471
        +.long	2173295548,3921009573
        +.long	4081628472,961987163
        +.long	3053834265,1508970993
        +.long	2937671579,2453635748
        +.long	3664609560,2870763221
        +.long	2734883394,3624381080
        +.long	1164996542,310598401
        +.long	1323610764,607225278
        +.long	3590304994,1426881987
        +.long	4068182383,1925078388
        +.long	991336113,2162078206
        +.long	633803317,2614888103
        +.long	3479774868,3248222580
        +.long	2666613458,3835390401
        +.long	944711139,4022224774
        +.long	2341262773,264347078
        +.long	2007800933,604807628
        +.long	1495990901,770255983
        +.long	1856431235,1249150122
        +.long	3175218132,1555081692
        +.long	2198950837,1996064986
        +.long	3999719339,2554220882
        +.long	766784016,2821834349
        +.long	2566594879,2952996808
        +.long	3203337956,3210313671
        +.long	1034457026,3336571891
        +.long	2466948901,3584528711
        +.long	3758326383,113926993
        +.long	168717936,338241895
        +.long	1188179964,666307205
        +.long	1546045734,773529912
        +.long	1522805485,1294757372
        +.long	2643833823,1396182291
        +.long	2343527390,1695183700
        +.long	1014477480,1986661051
        +.long	1206759142,2177026350
        +.long	344077627,2456956037
        +.long	1290863460,2730485921
        +.long	3158454273,2820302411
        +.long	3505952657,3259730800
        +.long	106217008,3345764771
        +.long	3606008344,3516065817
        +.long	1432725776,3600352804
        +.long	1467031594,4094571909
        +.long	851169720,275423344
        +.long	3100823752,430227734
        +.long	1363258195,506948616
        +.long	3750685593,659060556
        +.long	3785050280,883997877
        +.long	3318307427,958139571
        +.long	3812723403,1322822218
        +.long	2003034995,1537002063
        +.long	3602036899,1747873779
        +.long	1575990012,1955562222
        +.long	1125592928,2024104815
        +.long	2716904306,2227730452
        +.long	442776044,2361852424
        +.long	593698344,2428436474
        +.long	3733110249,2756734187
        +.long	2999351573,3204031479
        +.long	3815920427,3329325298
        +.long	3928383900,3391569614
        +.long	566280711,3515267271
        +.long	3454069534,3940187606
        +.long	4000239992,4118630271
        +.long	1914138554,116418474
        +.long	2731055270,174292421
        +.long	3203993006,289380356
        +.long	320620315,460393269
        +.long	587496836,685471733
        +.long	1086792851,852142971
        +.long	365543100,1017036298
        +.long	2618297676,1126000580
        +.long	3409855158,1288033470
        +.long	4234509866,1501505948
        +.long	987167468,1607167915
        +.long	1246189591,1816402316
        +.size	sha512_block_data_order,.-.L_sha512_block_data_order_begin
        +.byte	83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97
        +.byte	110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32
        +.byte	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +.byte	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +.byte	62,0
        diff --git a/vendor/openssl/asm/x86-elf-gas/whrlpool/wp-mmx.s b/vendor/openssl/asm/x86-elf-gas/whrlpool/wp-mmx.s
        new file mode 100644
        index 000000000..c03f3f6cb
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/whrlpool/wp-mmx.s
        @@ -0,0 +1,1105 @@
        +.file	"wp-mmx.s"
        +.text
        +.globl	whirlpool_block_mmx
        +.type	whirlpool_block_mmx,@function
        +.align	16
        +whirlpool_block_mmx:
        +.L_whirlpool_block_mmx_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%ebp
        +	movl	%esp,%eax
        +	subl	$148,%esp
        +	andl	$-64,%esp
        +	leal	128(%esp),%ebx
        +	movl	%esi,(%ebx)
        +	movl	%edi,4(%ebx)
        +	movl	%ebp,8(%ebx)
        +	movl	%eax,16(%ebx)
        +	call	.L000pic_point
        +.L000pic_point:
        +	popl	%ebp
        +	leal	.L001table-.L000pic_point(%ebp),%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm1
        +	movq	16(%esi),%mm2
        +	movq	24(%esi),%mm3
        +	movq	32(%esi),%mm4
        +	movq	40(%esi),%mm5
        +	movq	48(%esi),%mm6
        +	movq	56(%esi),%mm7
        +.L002outerloop:
        +	movq	%mm0,(%esp)
        +	movq	%mm1,8(%esp)
        +	movq	%mm2,16(%esp)
        +	movq	%mm3,24(%esp)
        +	movq	%mm4,32(%esp)
        +	movq	%mm5,40(%esp)
        +	movq	%mm6,48(%esp)
        +	movq	%mm7,56(%esp)
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm1
        +	pxor	16(%edi),%mm2
        +	pxor	24(%edi),%mm3
        +	pxor	32(%edi),%mm4
        +	pxor	40(%edi),%mm5
        +	pxor	48(%edi),%mm6
        +	pxor	56(%edi),%mm7
        +	movq	%mm0,64(%esp)
        +	movq	%mm1,72(%esp)
        +	movq	%mm2,80(%esp)
        +	movq	%mm3,88(%esp)
        +	movq	%mm4,96(%esp)
        +	movq	%mm5,104(%esp)
        +	movq	%mm6,112(%esp)
        +	movq	%mm7,120(%esp)
        +	xorl	%esi,%esi
        +	movl	%esi,12(%ebx)
        +.align	16
        +.L003round:
        +	movq	4096(%ebp,%esi,8),%mm0
        +	movl	(%esp),%eax
        +	movl	4(%esp),%ebx
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm0
        +	movq	7(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	8(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	movq	6(%ebp,%esi,8),%mm2
        +	movq	5(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	movq	4(%ebp,%esi,8),%mm4
        +	movq	3(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	12(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	movq	2(%ebp,%esi,8),%mm6
        +	movq	1(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm1
        +	pxor	7(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	16(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm3
        +	pxor	5(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm5
        +	pxor	3(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	20(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm7
        +	pxor	1(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm2
        +	pxor	7(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	24(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm4
        +	pxor	5(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm6
        +	pxor	3(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	28(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm0
        +	pxor	1(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm3
        +	pxor	7(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	32(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm5
        +	pxor	5(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm7
        +	pxor	3(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	36(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm1
        +	pxor	1(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm4
        +	pxor	7(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	40(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm6
        +	pxor	5(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm0
        +	pxor	3(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	44(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm2
        +	pxor	1(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm5
        +	pxor	7(%ebp,%edi,8),%mm6
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	48(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm7
        +	pxor	5(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm1
        +	pxor	3(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	52(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm3
        +	pxor	1(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm6
        +	pxor	7(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	56(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm0
        +	pxor	5(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm2
        +	pxor	3(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	60(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm4
        +	pxor	1(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm7
        +	pxor	7(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm1
        +	pxor	5(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm3
        +	pxor	3(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	68(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm5
        +	pxor	1(%ebp,%edi,8),%mm6
        +	movq	%mm0,(%esp)
        +	movq	%mm1,8(%esp)
        +	movq	%mm2,16(%esp)
        +	movq	%mm3,24(%esp)
        +	movq	%mm4,32(%esp)
        +	movq	%mm5,40(%esp)
        +	movq	%mm6,48(%esp)
        +	movq	%mm7,56(%esp)
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm0
        +	pxor	7(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	72(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm2
        +	pxor	5(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm4
        +	pxor	3(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	76(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm6
        +	pxor	1(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm1
        +	pxor	7(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	80(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm3
        +	pxor	5(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm5
        +	pxor	3(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	84(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm7
        +	pxor	1(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm2
        +	pxor	7(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	88(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm4
        +	pxor	5(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm6
        +	pxor	3(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	92(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm0
        +	pxor	1(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm3
        +	pxor	7(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	96(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm5
        +	pxor	5(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm7
        +	pxor	3(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	100(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm1
        +	pxor	1(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm4
        +	pxor	7(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	104(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm6
        +	pxor	5(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm0
        +	pxor	3(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	108(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm2
        +	pxor	1(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm5
        +	pxor	7(%ebp,%edi,8),%mm6
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	112(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm7
        +	pxor	5(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm1
        +	pxor	3(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	116(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm3
        +	pxor	1(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm6
        +	pxor	7(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	120(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm0
        +	pxor	5(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm2
        +	pxor	3(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	124(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm4
        +	pxor	1(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm7
        +	pxor	7(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm1
        +	pxor	5(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm3
        +	pxor	3(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm5
        +	pxor	1(%ebp,%edi,8),%mm6
        +	leal	128(%esp),%ebx
        +	movl	12(%ebx),%esi
        +	addl	$1,%esi
        +	cmpl	$10,%esi
        +	je	.L004roundsdone
        +	movl	%esi,12(%ebx)
        +	movq	%mm0,64(%esp)
        +	movq	%mm1,72(%esp)
        +	movq	%mm2,80(%esp)
        +	movq	%mm3,88(%esp)
        +	movq	%mm4,96(%esp)
        +	movq	%mm5,104(%esp)
        +	movq	%mm6,112(%esp)
        +	movq	%mm7,120(%esp)
        +	jmp	.L003round
        +.align	16
        +.L004roundsdone:
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	movl	8(%ebx),%eax
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm1
        +	pxor	16(%edi),%mm2
        +	pxor	24(%edi),%mm3
        +	pxor	32(%edi),%mm4
        +	pxor	40(%edi),%mm5
        +	pxor	48(%edi),%mm6
        +	pxor	56(%edi),%mm7
        +	pxor	(%esi),%mm0
        +	pxor	8(%esi),%mm1
        +	pxor	16(%esi),%mm2
        +	pxor	24(%esi),%mm3
        +	pxor	32(%esi),%mm4
        +	pxor	40(%esi),%mm5
        +	pxor	48(%esi),%mm6
        +	pxor	56(%esi),%mm7
        +	movq	%mm0,(%esi)
        +	movq	%mm1,8(%esi)
        +	movq	%mm2,16(%esi)
        +	movq	%mm3,24(%esi)
        +	movq	%mm4,32(%esi)
        +	movq	%mm5,40(%esi)
        +	movq	%mm6,48(%esi)
        +	movq	%mm7,56(%esi)
        +	leal	64(%edi),%edi
        +	subl	$1,%eax
        +	jz	.L005alldone
        +	movl	%edi,4(%ebx)
        +	movl	%eax,8(%ebx)
        +	jmp	.L002outerloop
        +.L005alldone:
        +	emms
        +	movl	16(%ebx),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	64
        +.L001table:
        +.byte	24,24,96,24,192,120,48,216
        +.byte	24,24,96,24,192,120,48,216
        +.byte	35,35,140,35,5,175,70,38
        +.byte	35,35,140,35,5,175,70,38
        +.byte	198,198,63,198,126,249,145,184
        +.byte	198,198,63,198,126,249,145,184
        +.byte	232,232,135,232,19,111,205,251
        +.byte	232,232,135,232,19,111,205,251
        +.byte	135,135,38,135,76,161,19,203
        +.byte	135,135,38,135,76,161,19,203
        +.byte	184,184,218,184,169,98,109,17
        +.byte	184,184,218,184,169,98,109,17
        +.byte	1,1,4,1,8,5,2,9
        +.byte	1,1,4,1,8,5,2,9
        +.byte	79,79,33,79,66,110,158,13
        +.byte	79,79,33,79,66,110,158,13
        +.byte	54,54,216,54,173,238,108,155
        +.byte	54,54,216,54,173,238,108,155
        +.byte	166,166,162,166,89,4,81,255
        +.byte	166,166,162,166,89,4,81,255
        +.byte	210,210,111,210,222,189,185,12
        +.byte	210,210,111,210,222,189,185,12
        +.byte	245,245,243,245,251,6,247,14
        +.byte	245,245,243,245,251,6,247,14
        +.byte	121,121,249,121,239,128,242,150
        +.byte	121,121,249,121,239,128,242,150
        +.byte	111,111,161,111,95,206,222,48
        +.byte	111,111,161,111,95,206,222,48
        +.byte	145,145,126,145,252,239,63,109
        +.byte	145,145,126,145,252,239,63,109
        +.byte	82,82,85,82,170,7,164,248
        +.byte	82,82,85,82,170,7,164,248
        +.byte	96,96,157,96,39,253,192,71
        +.byte	96,96,157,96,39,253,192,71
        +.byte	188,188,202,188,137,118,101,53
        +.byte	188,188,202,188,137,118,101,53
        +.byte	155,155,86,155,172,205,43,55
        +.byte	155,155,86,155,172,205,43,55
        +.byte	142,142,2,142,4,140,1,138
        +.byte	142,142,2,142,4,140,1,138
        +.byte	163,163,182,163,113,21,91,210
        +.byte	163,163,182,163,113,21,91,210
        +.byte	12,12,48,12,96,60,24,108
        +.byte	12,12,48,12,96,60,24,108
        +.byte	123,123,241,123,255,138,246,132
        +.byte	123,123,241,123,255,138,246,132
        +.byte	53,53,212,53,181,225,106,128
        +.byte	53,53,212,53,181,225,106,128
        +.byte	29,29,116,29,232,105,58,245
        +.byte	29,29,116,29,232,105,58,245
        +.byte	224,224,167,224,83,71,221,179
        +.byte	224,224,167,224,83,71,221,179
        +.byte	215,215,123,215,246,172,179,33
        +.byte	215,215,123,215,246,172,179,33
        +.byte	194,194,47,194,94,237,153,156
        +.byte	194,194,47,194,94,237,153,156
        +.byte	46,46,184,46,109,150,92,67
        +.byte	46,46,184,46,109,150,92,67
        +.byte	75,75,49,75,98,122,150,41
        +.byte	75,75,49,75,98,122,150,41
        +.byte	254,254,223,254,163,33,225,93
        +.byte	254,254,223,254,163,33,225,93
        +.byte	87,87,65,87,130,22,174,213
        +.byte	87,87,65,87,130,22,174,213
        +.byte	21,21,84,21,168,65,42,189
        +.byte	21,21,84,21,168,65,42,189
        +.byte	119,119,193,119,159,182,238,232
        +.byte	119,119,193,119,159,182,238,232
        +.byte	55,55,220,55,165,235,110,146
        +.byte	55,55,220,55,165,235,110,146
        +.byte	229,229,179,229,123,86,215,158
        +.byte	229,229,179,229,123,86,215,158
        +.byte	159,159,70,159,140,217,35,19
        +.byte	159,159,70,159,140,217,35,19
        +.byte	240,240,231,240,211,23,253,35
        +.byte	240,240,231,240,211,23,253,35
        +.byte	74,74,53,74,106,127,148,32
        +.byte	74,74,53,74,106,127,148,32
        +.byte	218,218,79,218,158,149,169,68
        +.byte	218,218,79,218,158,149,169,68
        +.byte	88,88,125,88,250,37,176,162
        +.byte	88,88,125,88,250,37,176,162
        +.byte	201,201,3,201,6,202,143,207
        +.byte	201,201,3,201,6,202,143,207
        +.byte	41,41,164,41,85,141,82,124
        +.byte	41,41,164,41,85,141,82,124
        +.byte	10,10,40,10,80,34,20,90
        +.byte	10,10,40,10,80,34,20,90
        +.byte	177,177,254,177,225,79,127,80
        +.byte	177,177,254,177,225,79,127,80
        +.byte	160,160,186,160,105,26,93,201
        +.byte	160,160,186,160,105,26,93,201
        +.byte	107,107,177,107,127,218,214,20
        +.byte	107,107,177,107,127,218,214,20
        +.byte	133,133,46,133,92,171,23,217
        +.byte	133,133,46,133,92,171,23,217
        +.byte	189,189,206,189,129,115,103,60
        +.byte	189,189,206,189,129,115,103,60
        +.byte	93,93,105,93,210,52,186,143
        +.byte	93,93,105,93,210,52,186,143
        +.byte	16,16,64,16,128,80,32,144
        +.byte	16,16,64,16,128,80,32,144
        +.byte	244,244,247,244,243,3,245,7
        +.byte	244,244,247,244,243,3,245,7
        +.byte	203,203,11,203,22,192,139,221
        +.byte	203,203,11,203,22,192,139,221
        +.byte	62,62,248,62,237,198,124,211
        +.byte	62,62,248,62,237,198,124,211
        +.byte	5,5,20,5,40,17,10,45
        +.byte	5,5,20,5,40,17,10,45
        +.byte	103,103,129,103,31,230,206,120
        +.byte	103,103,129,103,31,230,206,120
        +.byte	228,228,183,228,115,83,213,151
        +.byte	228,228,183,228,115,83,213,151
        +.byte	39,39,156,39,37,187,78,2
        +.byte	39,39,156,39,37,187,78,2
        +.byte	65,65,25,65,50,88,130,115
        +.byte	65,65,25,65,50,88,130,115
        +.byte	139,139,22,139,44,157,11,167
        +.byte	139,139,22,139,44,157,11,167
        +.byte	167,167,166,167,81,1,83,246
        +.byte	167,167,166,167,81,1,83,246
        +.byte	125,125,233,125,207,148,250,178
        +.byte	125,125,233,125,207,148,250,178
        +.byte	149,149,110,149,220,251,55,73
        +.byte	149,149,110,149,220,251,55,73
        +.byte	216,216,71,216,142,159,173,86
        +.byte	216,216,71,216,142,159,173,86
        +.byte	251,251,203,251,139,48,235,112
        +.byte	251,251,203,251,139,48,235,112
        +.byte	238,238,159,238,35,113,193,205
        +.byte	238,238,159,238,35,113,193,205
        +.byte	124,124,237,124,199,145,248,187
        +.byte	124,124,237,124,199,145,248,187
        +.byte	102,102,133,102,23,227,204,113
        +.byte	102,102,133,102,23,227,204,113
        +.byte	221,221,83,221,166,142,167,123
        +.byte	221,221,83,221,166,142,167,123
        +.byte	23,23,92,23,184,75,46,175
        +.byte	23,23,92,23,184,75,46,175
        +.byte	71,71,1,71,2,70,142,69
        +.byte	71,71,1,71,2,70,142,69
        +.byte	158,158,66,158,132,220,33,26
        +.byte	158,158,66,158,132,220,33,26
        +.byte	202,202,15,202,30,197,137,212
        +.byte	202,202,15,202,30,197,137,212
        +.byte	45,45,180,45,117,153,90,88
        +.byte	45,45,180,45,117,153,90,88
        +.byte	191,191,198,191,145,121,99,46
        +.byte	191,191,198,191,145,121,99,46
        +.byte	7,7,28,7,56,27,14,63
        +.byte	7,7,28,7,56,27,14,63
        +.byte	173,173,142,173,1,35,71,172
        +.byte	173,173,142,173,1,35,71,172
        +.byte	90,90,117,90,234,47,180,176
        +.byte	90,90,117,90,234,47,180,176
        +.byte	131,131,54,131,108,181,27,239
        +.byte	131,131,54,131,108,181,27,239
        +.byte	51,51,204,51,133,255,102,182
        +.byte	51,51,204,51,133,255,102,182
        +.byte	99,99,145,99,63,242,198,92
        +.byte	99,99,145,99,63,242,198,92
        +.byte	2,2,8,2,16,10,4,18
        +.byte	2,2,8,2,16,10,4,18
        +.byte	170,170,146,170,57,56,73,147
        +.byte	170,170,146,170,57,56,73,147
        +.byte	113,113,217,113,175,168,226,222
        +.byte	113,113,217,113,175,168,226,222
        +.byte	200,200,7,200,14,207,141,198
        +.byte	200,200,7,200,14,207,141,198
        +.byte	25,25,100,25,200,125,50,209
        +.byte	25,25,100,25,200,125,50,209
        +.byte	73,73,57,73,114,112,146,59
        +.byte	73,73,57,73,114,112,146,59
        +.byte	217,217,67,217,134,154,175,95
        +.byte	217,217,67,217,134,154,175,95
        +.byte	242,242,239,242,195,29,249,49
        +.byte	242,242,239,242,195,29,249,49
        +.byte	227,227,171,227,75,72,219,168
        +.byte	227,227,171,227,75,72,219,168
        +.byte	91,91,113,91,226,42,182,185
        +.byte	91,91,113,91,226,42,182,185
        +.byte	136,136,26,136,52,146,13,188
        +.byte	136,136,26,136,52,146,13,188
        +.byte	154,154,82,154,164,200,41,62
        +.byte	154,154,82,154,164,200,41,62
        +.byte	38,38,152,38,45,190,76,11
        +.byte	38,38,152,38,45,190,76,11
        +.byte	50,50,200,50,141,250,100,191
        +.byte	50,50,200,50,141,250,100,191
        +.byte	176,176,250,176,233,74,125,89
        +.byte	176,176,250,176,233,74,125,89
        +.byte	233,233,131,233,27,106,207,242
        +.byte	233,233,131,233,27,106,207,242
        +.byte	15,15,60,15,120,51,30,119
        +.byte	15,15,60,15,120,51,30,119
        +.byte	213,213,115,213,230,166,183,51
        +.byte	213,213,115,213,230,166,183,51
        +.byte	128,128,58,128,116,186,29,244
        +.byte	128,128,58,128,116,186,29,244
        +.byte	190,190,194,190,153,124,97,39
        +.byte	190,190,194,190,153,124,97,39
        +.byte	205,205,19,205,38,222,135,235
        +.byte	205,205,19,205,38,222,135,235
        +.byte	52,52,208,52,189,228,104,137
        +.byte	52,52,208,52,189,228,104,137
        +.byte	72,72,61,72,122,117,144,50
        +.byte	72,72,61,72,122,117,144,50
        +.byte	255,255,219,255,171,36,227,84
        +.byte	255,255,219,255,171,36,227,84
        +.byte	122,122,245,122,247,143,244,141
        +.byte	122,122,245,122,247,143,244,141
        +.byte	144,144,122,144,244,234,61,100
        +.byte	144,144,122,144,244,234,61,100
        +.byte	95,95,97,95,194,62,190,157
        +.byte	95,95,97,95,194,62,190,157
        +.byte	32,32,128,32,29,160,64,61
        +.byte	32,32,128,32,29,160,64,61
        +.byte	104,104,189,104,103,213,208,15
        +.byte	104,104,189,104,103,213,208,15
        +.byte	26,26,104,26,208,114,52,202
        +.byte	26,26,104,26,208,114,52,202
        +.byte	174,174,130,174,25,44,65,183
        +.byte	174,174,130,174,25,44,65,183
        +.byte	180,180,234,180,201,94,117,125
        +.byte	180,180,234,180,201,94,117,125
        +.byte	84,84,77,84,154,25,168,206
        +.byte	84,84,77,84,154,25,168,206
        +.byte	147,147,118,147,236,229,59,127
        +.byte	147,147,118,147,236,229,59,127
        +.byte	34,34,136,34,13,170,68,47
        +.byte	34,34,136,34,13,170,68,47
        +.byte	100,100,141,100,7,233,200,99
        +.byte	100,100,141,100,7,233,200,99
        +.byte	241,241,227,241,219,18,255,42
        +.byte	241,241,227,241,219,18,255,42
        +.byte	115,115,209,115,191,162,230,204
        +.byte	115,115,209,115,191,162,230,204
        +.byte	18,18,72,18,144,90,36,130
        +.byte	18,18,72,18,144,90,36,130
        +.byte	64,64,29,64,58,93,128,122
        +.byte	64,64,29,64,58,93,128,122
        +.byte	8,8,32,8,64,40,16,72
        +.byte	8,8,32,8,64,40,16,72
        +.byte	195,195,43,195,86,232,155,149
        +.byte	195,195,43,195,86,232,155,149
        +.byte	236,236,151,236,51,123,197,223
        +.byte	236,236,151,236,51,123,197,223
        +.byte	219,219,75,219,150,144,171,77
        +.byte	219,219,75,219,150,144,171,77
        +.byte	161,161,190,161,97,31,95,192
        +.byte	161,161,190,161,97,31,95,192
        +.byte	141,141,14,141,28,131,7,145
        +.byte	141,141,14,141,28,131,7,145
        +.byte	61,61,244,61,245,201,122,200
        +.byte	61,61,244,61,245,201,122,200
        +.byte	151,151,102,151,204,241,51,91
        +.byte	151,151,102,151,204,241,51,91
        +.byte	0,0,0,0,0,0,0,0
        +.byte	0,0,0,0,0,0,0,0
        +.byte	207,207,27,207,54,212,131,249
        +.byte	207,207,27,207,54,212,131,249
        +.byte	43,43,172,43,69,135,86,110
        +.byte	43,43,172,43,69,135,86,110
        +.byte	118,118,197,118,151,179,236,225
        +.byte	118,118,197,118,151,179,236,225
        +.byte	130,130,50,130,100,176,25,230
        +.byte	130,130,50,130,100,176,25,230
        +.byte	214,214,127,214,254,169,177,40
        +.byte	214,214,127,214,254,169,177,40
        +.byte	27,27,108,27,216,119,54,195
        +.byte	27,27,108,27,216,119,54,195
        +.byte	181,181,238,181,193,91,119,116
        +.byte	181,181,238,181,193,91,119,116
        +.byte	175,175,134,175,17,41,67,190
        +.byte	175,175,134,175,17,41,67,190
        +.byte	106,106,181,106,119,223,212,29
        +.byte	106,106,181,106,119,223,212,29
        +.byte	80,80,93,80,186,13,160,234
        +.byte	80,80,93,80,186,13,160,234
        +.byte	69,69,9,69,18,76,138,87
        +.byte	69,69,9,69,18,76,138,87
        +.byte	243,243,235,243,203,24,251,56
        +.byte	243,243,235,243,203,24,251,56
        +.byte	48,48,192,48,157,240,96,173
        +.byte	48,48,192,48,157,240,96,173
        +.byte	239,239,155,239,43,116,195,196
        +.byte	239,239,155,239,43,116,195,196
        +.byte	63,63,252,63,229,195,126,218
        +.byte	63,63,252,63,229,195,126,218
        +.byte	85,85,73,85,146,28,170,199
        +.byte	85,85,73,85,146,28,170,199
        +.byte	162,162,178,162,121,16,89,219
        +.byte	162,162,178,162,121,16,89,219
        +.byte	234,234,143,234,3,101,201,233
        +.byte	234,234,143,234,3,101,201,233
        +.byte	101,101,137,101,15,236,202,106
        +.byte	101,101,137,101,15,236,202,106
        +.byte	186,186,210,186,185,104,105,3
        +.byte	186,186,210,186,185,104,105,3
        +.byte	47,47,188,47,101,147,94,74
        +.byte	47,47,188,47,101,147,94,74
        +.byte	192,192,39,192,78,231,157,142
        +.byte	192,192,39,192,78,231,157,142
        +.byte	222,222,95,222,190,129,161,96
        +.byte	222,222,95,222,190,129,161,96
        +.byte	28,28,112,28,224,108,56,252
        +.byte	28,28,112,28,224,108,56,252
        +.byte	253,253,211,253,187,46,231,70
        +.byte	253,253,211,253,187,46,231,70
        +.byte	77,77,41,77,82,100,154,31
        +.byte	77,77,41,77,82,100,154,31
        +.byte	146,146,114,146,228,224,57,118
        +.byte	146,146,114,146,228,224,57,118
        +.byte	117,117,201,117,143,188,234,250
        +.byte	117,117,201,117,143,188,234,250
        +.byte	6,6,24,6,48,30,12,54
        +.byte	6,6,24,6,48,30,12,54
        +.byte	138,138,18,138,36,152,9,174
        +.byte	138,138,18,138,36,152,9,174
        +.byte	178,178,242,178,249,64,121,75
        +.byte	178,178,242,178,249,64,121,75
        +.byte	230,230,191,230,99,89,209,133
        +.byte	230,230,191,230,99,89,209,133
        +.byte	14,14,56,14,112,54,28,126
        +.byte	14,14,56,14,112,54,28,126
        +.byte	31,31,124,31,248,99,62,231
        +.byte	31,31,124,31,248,99,62,231
        +.byte	98,98,149,98,55,247,196,85
        +.byte	98,98,149,98,55,247,196,85
        +.byte	212,212,119,212,238,163,181,58
        +.byte	212,212,119,212,238,163,181,58
        +.byte	168,168,154,168,41,50,77,129
        +.byte	168,168,154,168,41,50,77,129
        +.byte	150,150,98,150,196,244,49,82
        +.byte	150,150,98,150,196,244,49,82
        +.byte	249,249,195,249,155,58,239,98
        +.byte	249,249,195,249,155,58,239,98
        +.byte	197,197,51,197,102,246,151,163
        +.byte	197,197,51,197,102,246,151,163
        +.byte	37,37,148,37,53,177,74,16
        +.byte	37,37,148,37,53,177,74,16
        +.byte	89,89,121,89,242,32,178,171
        +.byte	89,89,121,89,242,32,178,171
        +.byte	132,132,42,132,84,174,21,208
        +.byte	132,132,42,132,84,174,21,208
        +.byte	114,114,213,114,183,167,228,197
        +.byte	114,114,213,114,183,167,228,197
        +.byte	57,57,228,57,213,221,114,236
        +.byte	57,57,228,57,213,221,114,236
        +.byte	76,76,45,76,90,97,152,22
        +.byte	76,76,45,76,90,97,152,22
        +.byte	94,94,101,94,202,59,188,148
        +.byte	94,94,101,94,202,59,188,148
        +.byte	120,120,253,120,231,133,240,159
        +.byte	120,120,253,120,231,133,240,159
        +.byte	56,56,224,56,221,216,112,229
        +.byte	56,56,224,56,221,216,112,229
        +.byte	140,140,10,140,20,134,5,152
        +.byte	140,140,10,140,20,134,5,152
        +.byte	209,209,99,209,198,178,191,23
        +.byte	209,209,99,209,198,178,191,23
        +.byte	165,165,174,165,65,11,87,228
        +.byte	165,165,174,165,65,11,87,228
        +.byte	226,226,175,226,67,77,217,161
        +.byte	226,226,175,226,67,77,217,161
        +.byte	97,97,153,97,47,248,194,78
        +.byte	97,97,153,97,47,248,194,78
        +.byte	179,179,246,179,241,69,123,66
        +.byte	179,179,246,179,241,69,123,66
        +.byte	33,33,132,33,21,165,66,52
        +.byte	33,33,132,33,21,165,66,52
        +.byte	156,156,74,156,148,214,37,8
        +.byte	156,156,74,156,148,214,37,8
        +.byte	30,30,120,30,240,102,60,238
        +.byte	30,30,120,30,240,102,60,238
        +.byte	67,67,17,67,34,82,134,97
        +.byte	67,67,17,67,34,82,134,97
        +.byte	199,199,59,199,118,252,147,177
        +.byte	199,199,59,199,118,252,147,177
        +.byte	252,252,215,252,179,43,229,79
        +.byte	252,252,215,252,179,43,229,79
        +.byte	4,4,16,4,32,20,8,36
        +.byte	4,4,16,4,32,20,8,36
        +.byte	81,81,89,81,178,8,162,227
        +.byte	81,81,89,81,178,8,162,227
        +.byte	153,153,94,153,188,199,47,37
        +.byte	153,153,94,153,188,199,47,37
        +.byte	109,109,169,109,79,196,218,34
        +.byte	109,109,169,109,79,196,218,34
        +.byte	13,13,52,13,104,57,26,101
        +.byte	13,13,52,13,104,57,26,101
        +.byte	250,250,207,250,131,53,233,121
        +.byte	250,250,207,250,131,53,233,121
        +.byte	223,223,91,223,182,132,163,105
        +.byte	223,223,91,223,182,132,163,105
        +.byte	126,126,229,126,215,155,252,169
        +.byte	126,126,229,126,215,155,252,169
        +.byte	36,36,144,36,61,180,72,25
        +.byte	36,36,144,36,61,180,72,25
        +.byte	59,59,236,59,197,215,118,254
        +.byte	59,59,236,59,197,215,118,254
        +.byte	171,171,150,171,49,61,75,154
        +.byte	171,171,150,171,49,61,75,154
        +.byte	206,206,31,206,62,209,129,240
        +.byte	206,206,31,206,62,209,129,240
        +.byte	17,17,68,17,136,85,34,153
        +.byte	17,17,68,17,136,85,34,153
        +.byte	143,143,6,143,12,137,3,131
        +.byte	143,143,6,143,12,137,3,131
        +.byte	78,78,37,78,74,107,156,4
        +.byte	78,78,37,78,74,107,156,4
        +.byte	183,183,230,183,209,81,115,102
        +.byte	183,183,230,183,209,81,115,102
        +.byte	235,235,139,235,11,96,203,224
        +.byte	235,235,139,235,11,96,203,224
        +.byte	60,60,240,60,253,204,120,193
        +.byte	60,60,240,60,253,204,120,193
        +.byte	129,129,62,129,124,191,31,253
        +.byte	129,129,62,129,124,191,31,253
        +.byte	148,148,106,148,212,254,53,64
        +.byte	148,148,106,148,212,254,53,64
        +.byte	247,247,251,247,235,12,243,28
        +.byte	247,247,251,247,235,12,243,28
        +.byte	185,185,222,185,161,103,111,24
        +.byte	185,185,222,185,161,103,111,24
        +.byte	19,19,76,19,152,95,38,139
        +.byte	19,19,76,19,152,95,38,139
        +.byte	44,44,176,44,125,156,88,81
        +.byte	44,44,176,44,125,156,88,81
        +.byte	211,211,107,211,214,184,187,5
        +.byte	211,211,107,211,214,184,187,5
        +.byte	231,231,187,231,107,92,211,140
        +.byte	231,231,187,231,107,92,211,140
        +.byte	110,110,165,110,87,203,220,57
        +.byte	110,110,165,110,87,203,220,57
        +.byte	196,196,55,196,110,243,149,170
        +.byte	196,196,55,196,110,243,149,170
        +.byte	3,3,12,3,24,15,6,27
        +.byte	3,3,12,3,24,15,6,27
        +.byte	86,86,69,86,138,19,172,220
        +.byte	86,86,69,86,138,19,172,220
        +.byte	68,68,13,68,26,73,136,94
        +.byte	68,68,13,68,26,73,136,94
        +.byte	127,127,225,127,223,158,254,160
        +.byte	127,127,225,127,223,158,254,160
        +.byte	169,169,158,169,33,55,79,136
        +.byte	169,169,158,169,33,55,79,136
        +.byte	42,42,168,42,77,130,84,103
        +.byte	42,42,168,42,77,130,84,103
        +.byte	187,187,214,187,177,109,107,10
        +.byte	187,187,214,187,177,109,107,10
        +.byte	193,193,35,193,70,226,159,135
        +.byte	193,193,35,193,70,226,159,135
        +.byte	83,83,81,83,162,2,166,241
        +.byte	83,83,81,83,162,2,166,241
        +.byte	220,220,87,220,174,139,165,114
        +.byte	220,220,87,220,174,139,165,114
        +.byte	11,11,44,11,88,39,22,83
        +.byte	11,11,44,11,88,39,22,83
        +.byte	157,157,78,157,156,211,39,1
        +.byte	157,157,78,157,156,211,39,1
        +.byte	108,108,173,108,71,193,216,43
        +.byte	108,108,173,108,71,193,216,43
        +.byte	49,49,196,49,149,245,98,164
        +.byte	49,49,196,49,149,245,98,164
        +.byte	116,116,205,116,135,185,232,243
        +.byte	116,116,205,116,135,185,232,243
        +.byte	246,246,255,246,227,9,241,21
        +.byte	246,246,255,246,227,9,241,21
        +.byte	70,70,5,70,10,67,140,76
        +.byte	70,70,5,70,10,67,140,76
        +.byte	172,172,138,172,9,38,69,165
        +.byte	172,172,138,172,9,38,69,165
        +.byte	137,137,30,137,60,151,15,181
        +.byte	137,137,30,137,60,151,15,181
        +.byte	20,20,80,20,160,68,40,180
        +.byte	20,20,80,20,160,68,40,180
        +.byte	225,225,163,225,91,66,223,186
        +.byte	225,225,163,225,91,66,223,186
        +.byte	22,22,88,22,176,78,44,166
        +.byte	22,22,88,22,176,78,44,166
        +.byte	58,58,232,58,205,210,116,247
        +.byte	58,58,232,58,205,210,116,247
        +.byte	105,105,185,105,111,208,210,6
        +.byte	105,105,185,105,111,208,210,6
        +.byte	9,9,36,9,72,45,18,65
        +.byte	9,9,36,9,72,45,18,65
        +.byte	112,112,221,112,167,173,224,215
        +.byte	112,112,221,112,167,173,224,215
        +.byte	182,182,226,182,217,84,113,111
        +.byte	182,182,226,182,217,84,113,111
        +.byte	208,208,103,208,206,183,189,30
        +.byte	208,208,103,208,206,183,189,30
        +.byte	237,237,147,237,59,126,199,214
        +.byte	237,237,147,237,59,126,199,214
        +.byte	204,204,23,204,46,219,133,226
        +.byte	204,204,23,204,46,219,133,226
        +.byte	66,66,21,66,42,87,132,104
        +.byte	66,66,21,66,42,87,132,104
        +.byte	152,152,90,152,180,194,45,44
        +.byte	152,152,90,152,180,194,45,44
        +.byte	164,164,170,164,73,14,85,237
        +.byte	164,164,170,164,73,14,85,237
        +.byte	40,40,160,40,93,136,80,117
        +.byte	40,40,160,40,93,136,80,117
        +.byte	92,92,109,92,218,49,184,134
        +.byte	92,92,109,92,218,49,184,134
        +.byte	248,248,199,248,147,63,237,107
        +.byte	248,248,199,248,147,63,237,107
        +.byte	134,134,34,134,68,164,17,194
        +.byte	134,134,34,134,68,164,17,194
        +.byte	24,35,198,232,135,184,1,79
        +.byte	54,166,210,245,121,111,145,82
        +.byte	96,188,155,142,163,12,123,53
        +.byte	29,224,215,194,46,75,254,87
        +.byte	21,119,55,229,159,240,74,218
        +.byte	88,201,41,10,177,160,107,133
        +.byte	189,93,16,244,203,62,5,103
        +.byte	228,39,65,139,167,125,149,216
        +.byte	251,238,124,102,221,23,71,158
        +.byte	202,45,191,7,173,90,131,51
        +.size	whirlpool_block_mmx,.-.L_whirlpool_block_mmx_begin
        diff --git a/vendor/openssl/asm/x86-elf-gas/x86cpuid.s b/vendor/openssl/asm/x86-elf-gas/x86cpuid.s
        new file mode 100644
        index 000000000..f9cd03805
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-elf-gas/x86cpuid.s
        @@ -0,0 +1,320 @@
        +.file	"x86cpuid.s"
        +.text
        +.globl	OPENSSL_ia32_cpuid
        +.type	OPENSSL_ia32_cpuid,@function
        +.align	16
        +OPENSSL_ia32_cpuid:
        +.L_OPENSSL_ia32_cpuid_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	xorl	%edx,%edx
        +	pushfl
        +	popl	%eax
        +	movl	%eax,%ecx
        +	xorl	$2097152,%eax
        +	pushl	%eax
        +	popfl
        +	pushfl
        +	popl	%eax
        +	xorl	%eax,%ecx
        +	xorl	%eax,%eax
        +	btl	$21,%ecx
        +	jnc	.L000nocpuid
        +	.byte	0x0f,0xa2
        +	movl	%eax,%edi
        +	xorl	%eax,%eax
        +	cmpl	$1970169159,%ebx
        +	setne	%al
        +	movl	%eax,%ebp
        +	cmpl	$1231384169,%edx
        +	setne	%al
        +	orl	%eax,%ebp
        +	cmpl	$1818588270,%ecx
        +	setne	%al
        +	orl	%eax,%ebp
        +	jz	.L001intel
        +	cmpl	$1752462657,%ebx
        +	setne	%al
        +	movl	%eax,%esi
        +	cmpl	$1769238117,%edx
        +	setne	%al
        +	orl	%eax,%esi
        +	cmpl	$1145913699,%ecx
        +	setne	%al
        +	orl	%eax,%esi
        +	jnz	.L001intel
        +	movl	$2147483648,%eax
        +	.byte	0x0f,0xa2
        +	cmpl	$2147483649,%eax
        +	jb	.L001intel
        +	movl	%eax,%esi
        +	movl	$2147483649,%eax
        +	.byte	0x0f,0xa2
        +	orl	%ecx,%ebp
        +	andl	$2049,%ebp
        +	cmpl	$2147483656,%esi
        +	jb	.L001intel
        +	movl	$2147483656,%eax
        +	.byte	0x0f,0xa2
        +	movzbl	%cl,%esi
        +	incl	%esi
        +	movl	$1,%eax
        +	.byte	0x0f,0xa2
        +	btl	$28,%edx
        +	jnc	.L002generic
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	cmpl	%esi,%ebx
        +	ja	.L002generic
        +	andl	$4026531839,%edx
        +	jmp	.L002generic
        +.L001intel:
        +	cmpl	$4,%edi
        +	movl	$-1,%edi
        +	jb	.L003nocacheinfo
        +	movl	$4,%eax
        +	movl	$0,%ecx
        +	.byte	0x0f,0xa2
        +	movl	%eax,%edi
        +	shrl	$14,%edi
        +	andl	$4095,%edi
        +.L003nocacheinfo:
        +	movl	$1,%eax
        +	.byte	0x0f,0xa2
        +	andl	$3220176895,%edx
        +	cmpl	$0,%ebp
        +	jne	.L004notintel
        +	orl	$1073741824,%edx
        +	andb	$15,%ah
        +	cmpb	$15,%ah
        +	jne	.L004notintel
        +	orl	$1048576,%edx
        +.L004notintel:
        +	btl	$28,%edx
        +	jnc	.L002generic
        +	andl	$4026531839,%edx
        +	cmpl	$0,%edi
        +	je	.L002generic
        +	orl	$268435456,%edx
        +	shrl	$16,%ebx
        +	cmpb	$1,%bl
        +	ja	.L002generic
        +	andl	$4026531839,%edx
        +.L002generic:
        +	andl	$2048,%ebp
        +	andl	$4294965247,%ecx
        +	movl	%edx,%esi
        +	orl	%ecx,%ebp
        +	btl	$27,%ecx
        +	jnc	.L005clear_avx
        +	xorl	%ecx,%ecx
        +.byte	15,1,208
        +	andl	$6,%eax
        +	cmpl	$6,%eax
        +	je	.L006done
        +	cmpl	$2,%eax
        +	je	.L005clear_avx
        +.L007clear_xmm:
        +	andl	$4261412861,%ebp
        +	andl	$4278190079,%esi
        +.L005clear_avx:
        +	andl	$4026525695,%ebp
        +.L006done:
        +	movl	%esi,%eax
        +	movl	%ebp,%edx
        +.L000nocpuid:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.size	OPENSSL_ia32_cpuid,.-.L_OPENSSL_ia32_cpuid_begin
        +.globl	OPENSSL_rdtsc
        +.type	OPENSSL_rdtsc,@function
        +.align	16
        +OPENSSL_rdtsc:
        +.L_OPENSSL_rdtsc_begin:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	leal	OPENSSL_ia32cap_P,%ecx
        +	btl	$4,(%ecx)
        +	jnc	.L008notsc
        +	.byte	0x0f,0x31
        +.L008notsc:
        +	ret
        +.size	OPENSSL_rdtsc,.-.L_OPENSSL_rdtsc_begin
        +.globl	OPENSSL_instrument_halt
        +.type	OPENSSL_instrument_halt,@function
        +.align	16
        +OPENSSL_instrument_halt:
        +.L_OPENSSL_instrument_halt_begin:
        +	leal	OPENSSL_ia32cap_P,%ecx
        +	btl	$4,(%ecx)
        +	jnc	.L009nohalt
        +.long	2421723150
        +	andl	$3,%eax
        +	jnz	.L009nohalt
        +	pushfl
        +	popl	%eax
        +	btl	$9,%eax
        +	jnc	.L009nohalt
        +	.byte	0x0f,0x31
        +	pushl	%edx
        +	pushl	%eax
        +	hlt
        +	.byte	0x0f,0x31
        +	subl	(%esp),%eax
        +	sbbl	4(%esp),%edx
        +	addl	$8,%esp
        +	ret
        +.L009nohalt:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	ret
        +.size	OPENSSL_instrument_halt,.-.L_OPENSSL_instrument_halt_begin
        +.globl	OPENSSL_far_spin
        +.type	OPENSSL_far_spin,@function
        +.align	16
        +OPENSSL_far_spin:
        +.L_OPENSSL_far_spin_begin:
        +	pushfl
        +	popl	%eax
        +	btl	$9,%eax
        +	jnc	.L010nospin
        +	movl	4(%esp),%eax
        +	movl	8(%esp),%ecx
        +.long	2430111262
        +	xorl	%eax,%eax
        +	movl	(%ecx),%edx
        +	jmp	.L011spin
        +.align	16
        +.L011spin:
        +	incl	%eax
        +	cmpl	(%ecx),%edx
        +	je	.L011spin
        +.long	529567888
        +	ret
        +.L010nospin:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	ret
        +.size	OPENSSL_far_spin,.-.L_OPENSSL_far_spin_begin
        +.globl	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,@function
        +.align	16
        +OPENSSL_wipe_cpu:
        +.L_OPENSSL_wipe_cpu_begin:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	leal	OPENSSL_ia32cap_P,%ecx
        +	movl	(%ecx),%ecx
        +	btl	$1,(%ecx)
        +	jnc	.L012no_x87
        +.long	4007259865,4007259865,4007259865,4007259865,2430851995
        +.L012no_x87:
        +	leal	4(%esp),%eax
        +	ret
        +.size	OPENSSL_wipe_cpu,.-.L_OPENSSL_wipe_cpu_begin
        +.globl	OPENSSL_atomic_add
        +.type	OPENSSL_atomic_add,@function
        +.align	16
        +OPENSSL_atomic_add:
        +.L_OPENSSL_atomic_add_begin:
        +	movl	4(%esp),%edx
        +	movl	8(%esp),%ecx
        +	pushl	%ebx
        +	nop
        +	movl	(%edx),%eax
        +.L013spin:
        +	leal	(%eax,%ecx,1),%ebx
        +	nop
        +.long	447811568
        +	jne	.L013spin
        +	movl	%ebx,%eax
        +	popl	%ebx
        +	ret
        +.size	OPENSSL_atomic_add,.-.L_OPENSSL_atomic_add_begin
        +.globl	OPENSSL_indirect_call
        +.type	OPENSSL_indirect_call,@function
        +.align	16
        +OPENSSL_indirect_call:
        +.L_OPENSSL_indirect_call_begin:
        +	pushl	%ebp
        +	movl	%esp,%ebp
        +	subl	$28,%esp
        +	movl	12(%ebp),%ecx
        +	movl	%ecx,(%esp)
        +	movl	16(%ebp),%edx
        +	movl	%edx,4(%esp)
        +	movl	20(%ebp),%eax
        +	movl	%eax,8(%esp)
        +	movl	24(%ebp),%eax
        +	movl	%eax,12(%esp)
        +	movl	28(%ebp),%eax
        +	movl	%eax,16(%esp)
        +	movl	32(%ebp),%eax
        +	movl	%eax,20(%esp)
        +	movl	36(%ebp),%eax
        +	movl	%eax,24(%esp)
        +	call	*8(%ebp)
        +	movl	%ebp,%esp
        +	popl	%ebp
        +	ret
        +.size	OPENSSL_indirect_call,.-.L_OPENSSL_indirect_call_begin
        +.globl	OPENSSL_cleanse
        +.type	OPENSSL_cleanse,@function
        +.align	16
        +OPENSSL_cleanse:
        +.L_OPENSSL_cleanse_begin:
        +	movl	4(%esp),%edx
        +	movl	8(%esp),%ecx
        +	xorl	%eax,%eax
        +	cmpl	$7,%ecx
        +	jae	.L014lot
        +	cmpl	$0,%ecx
        +	je	.L015ret
        +.L016little:
        +	movb	%al,(%edx)
        +	subl	$1,%ecx
        +	leal	1(%edx),%edx
        +	jnz	.L016little
        +.L015ret:
        +	ret
        +.align	16
        +.L014lot:
        +	testl	$3,%edx
        +	jz	.L017aligned
        +	movb	%al,(%edx)
        +	leal	-1(%ecx),%ecx
        +	leal	1(%edx),%edx
        +	jmp	.L014lot
        +.L017aligned:
        +	movl	%eax,(%edx)
        +	leal	-4(%ecx),%ecx
        +	testl	$-4,%ecx
        +	leal	4(%edx),%edx
        +	jnz	.L017aligned
        +	cmpl	$0,%ecx
        +	jne	.L016little
        +	ret
        +.size	OPENSSL_cleanse,.-.L_OPENSSL_cleanse_begin
        +.globl	OPENSSL_ia32_rdrand
        +.type	OPENSSL_ia32_rdrand,@function
        +.align	16
        +OPENSSL_ia32_rdrand:
        +.L_OPENSSL_ia32_rdrand_begin:
        +	movl	$8,%ecx
        +.L018loop:
        +.byte	15,199,240
        +	jc	.L019break
        +	loop	.L018loop
        +.L019break:
        +	cmpl	$0,%eax
        +	cmovel	%ecx,%eax
        +	ret
        +.size	OPENSSL_ia32_rdrand,.-.L_OPENSSL_ia32_rdrand_begin
        +.comm	OPENSSL_ia32cap_P,8,4
        +.section	.init
        +	call	OPENSSL_cpuid_setup
        diff --git a/vendor/openssl/asm/x86-macosx-gas/aes/aes-586.s b/vendor/openssl/asm/x86-macosx-gas/aes/aes-586.s
        new file mode 100644
        index 000000000..a58ea6f76
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/aes/aes-586.s
        @@ -0,0 +1,3198 @@
        +.file	"aes-586.s"
        +.text
        +.align	4
        +__x86_AES_encrypt_compact:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	-128(%ebp),%edi
        +	movl	-96(%ebp),%esi
        +	movl	-64(%ebp),%edi
        +	movl	-32(%ebp),%esi
        +	movl	(%ebp),%edi
        +	movl	32(%ebp),%esi
        +	movl	64(%ebp),%edi
        +	movl	96(%ebp),%esi
        +.align	4,0x90
        +L000loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ch,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ah,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$8,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$24,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	movl	%ecx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%ecx,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%ecx
        +	roll	$24,%ecx
        +	xorl	%esi,%ecx
        +	rorl	$16,%ebp
        +	xorl	%ebp,%ecx
        +	rorl	$8,%ebp
        +	xorl	%ebp,%ecx
        +	movl	%edx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%edx,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%edx
        +	roll	$24,%edx
        +	xorl	%esi,%edx
        +	rorl	$16,%ebp
        +	xorl	%ebp,%edx
        +	rorl	$8,%ebp
        +	xorl	%ebp,%edx
        +	movl	%eax,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%eax,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%eax
        +	roll	$24,%eax
        +	xorl	%esi,%eax
        +	rorl	$16,%ebp
        +	xorl	%ebp,%eax
        +	rorl	$8,%ebp
        +	xorl	%ebp,%eax
        +	movl	%ebx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%edi
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edi
        +	andl	$454761243,%esi
        +	movl	%ebx,%ebp
        +	xorl	%edi,%esi
        +	xorl	%esi,%ebx
        +	roll	$24,%ebx
        +	xorl	%esi,%ebx
        +	rorl	$16,%ebp
        +	xorl	%ebp,%ebx
        +	rorl	$8,%ebp
        +	xorl	%ebp,%ebx
        +	movl	20(%esp),%edi
        +	movl	28(%esp),%ebp
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	L000loop
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ch,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ah,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$8,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$24,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	xorl	16(%edi),%eax
        +	xorl	20(%edi),%ebx
        +	xorl	24(%edi),%ecx
        +	xorl	28(%edi),%edx
        +	ret
        +.align	4
        +__sse_AES_encrypt_compact:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	$454761243,%eax
        +	movl	%eax,8(%esp)
        +	movl	%eax,12(%esp)
        +	movl	-128(%ebp),%eax
        +	movl	-96(%ebp),%ebx
        +	movl	-64(%ebp),%ecx
        +	movl	-32(%ebp),%edx
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +.align	4,0x90
        +L001loop:
        +	pshufw	$8,%mm0,%mm1
        +	pshufw	$13,%mm4,%mm5
        +	movd	%mm1,%eax
        +	movd	%mm5,%ebx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	pshufw	$13,%mm0,%mm2
        +	movzbl	%ah,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	shll	$8,%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	pshufw	$8,%mm4,%mm6
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%edx
        +	shrl	$16,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm0
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	movd	%mm2,%eax
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	movd	%mm6,%ebx
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm1
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	shrl	$16,%eax
        +	punpckldq	%mm1,%mm0
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	andl	$255,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$16,%eax
        +	orl	%eax,%edx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm4
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	orl	%ebx,%edx
        +	movd	%edx,%mm5
        +	punpckldq	%mm5,%mm4
        +	addl	$16,%edi
        +	cmpl	24(%esp),%edi
        +	ja	L002out
        +	movq	8(%esp),%mm2
        +	pxor	%mm3,%mm3
        +	pxor	%mm7,%mm7
        +	movq	%mm0,%mm1
        +	movq	%mm4,%mm5
        +	pcmpgtb	%mm0,%mm3
        +	pcmpgtb	%mm4,%mm7
        +	pand	%mm2,%mm3
        +	pand	%mm2,%mm7
        +	pshufw	$177,%mm0,%mm2
        +	pshufw	$177,%mm4,%mm6
        +	paddb	%mm0,%mm0
        +	paddb	%mm4,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pshufw	$177,%mm2,%mm3
        +	pshufw	$177,%mm6,%mm7
        +	pxor	%mm0,%mm1
        +	pxor	%mm4,%mm5
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	movq	%mm3,%mm2
        +	movq	%mm7,%mm6
        +	pslld	$8,%mm3
        +	pslld	$8,%mm7
        +	psrld	$24,%mm2
        +	psrld	$24,%mm6
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	movq	%mm1,%mm3
        +	movq	%mm5,%mm7
        +	movq	(%edi),%mm2
        +	movq	8(%edi),%mm6
        +	psrld	$8,%mm1
        +	psrld	$8,%mm5
        +	movl	-128(%ebp),%eax
        +	pslld	$24,%mm3
        +	pslld	$24,%mm7
        +	movl	-64(%ebp),%ebx
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	movl	(%ebp),%ecx
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	movl	64(%ebp),%edx
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	jmp	L001loop
        +.align	4,0x90
        +L002out:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	ret
        +.align	4
        +__x86_AES_encrypt:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +.align	4,0x90
        +L003loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%bh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%ch,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%dh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movzbl	%bh,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	20(%esp),%edi
        +	movl	(%ebp,%edx,8),%edx
        +	movzbl	%ah,%eax
        +	xorl	3(%ebp,%eax,8),%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	xorl	2(%ebp,%ebx,8),%edx
        +	movl	8(%esp),%ebx
        +	xorl	1(%ebp,%ecx,8),%edx
        +	movl	%esi,%ecx
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	L003loop
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movl	2(%ebp,%esi,8),%esi
        +	andl	$255,%esi
        +	movzbl	%bh,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$65280,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$16711680,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movl	2(%ebp,%edi,8),%edi
        +	andl	$4278190080,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	shrl	$16,%ebx
        +	movl	2(%ebp,%esi,8),%esi
        +	andl	$255,%esi
        +	movzbl	%ch,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$65280,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$16711680,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$24,%edi
        +	movl	2(%ebp,%edi,8),%edi
        +	andl	$4278190080,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	shrl	$24,%ecx
        +	movl	2(%ebp,%esi,8),%esi
        +	andl	$255,%esi
        +	movzbl	%dh,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$65280,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edx
        +	andl	$255,%edi
        +	movl	(%ebp,%edi,8),%edi
        +	andl	$16711680,%edi
        +	xorl	%edi,%esi
        +	movzbl	%bh,%edi
        +	movl	2(%ebp,%edi,8),%edi
        +	andl	$4278190080,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movl	2(%ebp,%edx,8),%edx
        +	andl	$255,%edx
        +	movzbl	%ah,%eax
        +	movl	(%ebp,%eax,8),%eax
        +	andl	$65280,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	andl	$255,%ebx
        +	movl	(%ebp,%ebx,8),%ebx
        +	andl	$16711680,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	movl	2(%ebp,%ecx,8),%ecx
        +	andl	$4278190080,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	ret
        +.align	6,0x90
        +LAES_Te:
        +.long	2774754246,2774754246
        +.long	2222750968,2222750968
        +.long	2574743534,2574743534
        +.long	2373680118,2373680118
        +.long	234025727,234025727
        +.long	3177933782,3177933782
        +.long	2976870366,2976870366
        +.long	1422247313,1422247313
        +.long	1345335392,1345335392
        +.long	50397442,50397442
        +.long	2842126286,2842126286
        +.long	2099981142,2099981142
        +.long	436141799,436141799
        +.long	1658312629,1658312629
        +.long	3870010189,3870010189
        +.long	2591454956,2591454956
        +.long	1170918031,1170918031
        +.long	2642575903,2642575903
        +.long	1086966153,1086966153
        +.long	2273148410,2273148410
        +.long	368769775,368769775
        +.long	3948501426,3948501426
        +.long	3376891790,3376891790
        +.long	200339707,200339707
        +.long	3970805057,3970805057
        +.long	1742001331,1742001331
        +.long	4255294047,4255294047
        +.long	3937382213,3937382213
        +.long	3214711843,3214711843
        +.long	4154762323,4154762323
        +.long	2524082916,2524082916
        +.long	1539358875,1539358875
        +.long	3266819957,3266819957
        +.long	486407649,486407649
        +.long	2928907069,2928907069
        +.long	1780885068,1780885068
        +.long	1513502316,1513502316
        +.long	1094664062,1094664062
        +.long	49805301,49805301
        +.long	1338821763,1338821763
        +.long	1546925160,1546925160
        +.long	4104496465,4104496465
        +.long	887481809,887481809
        +.long	150073849,150073849
        +.long	2473685474,2473685474
        +.long	1943591083,1943591083
        +.long	1395732834,1395732834
        +.long	1058346282,1058346282
        +.long	201589768,201589768
        +.long	1388824469,1388824469
        +.long	1696801606,1696801606
        +.long	1589887901,1589887901
        +.long	672667696,672667696
        +.long	2711000631,2711000631
        +.long	251987210,251987210
        +.long	3046808111,3046808111
        +.long	151455502,151455502
        +.long	907153956,907153956
        +.long	2608889883,2608889883
        +.long	1038279391,1038279391
        +.long	652995533,652995533
        +.long	1764173646,1764173646
        +.long	3451040383,3451040383
        +.long	2675275242,2675275242
        +.long	453576978,453576978
        +.long	2659418909,2659418909
        +.long	1949051992,1949051992
        +.long	773462580,773462580
        +.long	756751158,756751158
        +.long	2993581788,2993581788
        +.long	3998898868,3998898868
        +.long	4221608027,4221608027
        +.long	4132590244,4132590244
        +.long	1295727478,1295727478
        +.long	1641469623,1641469623
        +.long	3467883389,3467883389
        +.long	2066295122,2066295122
        +.long	1055122397,1055122397
        +.long	1898917726,1898917726
        +.long	2542044179,2542044179
        +.long	4115878822,4115878822
        +.long	1758581177,1758581177
        +.long	0,0
        +.long	753790401,753790401
        +.long	1612718144,1612718144
        +.long	536673507,536673507
        +.long	3367088505,3367088505
        +.long	3982187446,3982187446
        +.long	3194645204,3194645204
        +.long	1187761037,1187761037
        +.long	3653156455,3653156455
        +.long	1262041458,1262041458
        +.long	3729410708,3729410708
        +.long	3561770136,3561770136
        +.long	3898103984,3898103984
        +.long	1255133061,1255133061
        +.long	1808847035,1808847035
        +.long	720367557,720367557
        +.long	3853167183,3853167183
        +.long	385612781,385612781
        +.long	3309519750,3309519750
        +.long	3612167578,3612167578
        +.long	1429418854,1429418854
        +.long	2491778321,2491778321
        +.long	3477423498,3477423498
        +.long	284817897,284817897
        +.long	100794884,100794884
        +.long	2172616702,2172616702
        +.long	4031795360,4031795360
        +.long	1144798328,1144798328
        +.long	3131023141,3131023141
        +.long	3819481163,3819481163
        +.long	4082192802,4082192802
        +.long	4272137053,4272137053
        +.long	3225436288,3225436288
        +.long	2324664069,2324664069
        +.long	2912064063,2912064063
        +.long	3164445985,3164445985
        +.long	1211644016,1211644016
        +.long	83228145,83228145
        +.long	3753688163,3753688163
        +.long	3249976951,3249976951
        +.long	1977277103,1977277103
        +.long	1663115586,1663115586
        +.long	806359072,806359072
        +.long	452984805,452984805
        +.long	250868733,250868733
        +.long	1842533055,1842533055
        +.long	1288555905,1288555905
        +.long	336333848,336333848
        +.long	890442534,890442534
        +.long	804056259,804056259
        +.long	3781124030,3781124030
        +.long	2727843637,2727843637
        +.long	3427026056,3427026056
        +.long	957814574,957814574
        +.long	1472513171,1472513171
        +.long	4071073621,4071073621
        +.long	2189328124,2189328124
        +.long	1195195770,1195195770
        +.long	2892260552,2892260552
        +.long	3881655738,3881655738
        +.long	723065138,723065138
        +.long	2507371494,2507371494
        +.long	2690670784,2690670784
        +.long	2558624025,2558624025
        +.long	3511635870,3511635870
        +.long	2145180835,2145180835
        +.long	1713513028,1713513028
        +.long	2116692564,2116692564
        +.long	2878378043,2878378043
        +.long	2206763019,2206763019
        +.long	3393603212,3393603212
        +.long	703524551,703524551
        +.long	3552098411,3552098411
        +.long	1007948840,1007948840
        +.long	2044649127,2044649127
        +.long	3797835452,3797835452
        +.long	487262998,487262998
        +.long	1994120109,1994120109
        +.long	1004593371,1004593371
        +.long	1446130276,1446130276
        +.long	1312438900,1312438900
        +.long	503974420,503974420
        +.long	3679013266,3679013266
        +.long	168166924,168166924
        +.long	1814307912,1814307912
        +.long	3831258296,3831258296
        +.long	1573044895,1573044895
        +.long	1859376061,1859376061
        +.long	4021070915,4021070915
        +.long	2791465668,2791465668
        +.long	2828112185,2828112185
        +.long	2761266481,2761266481
        +.long	937747667,937747667
        +.long	2339994098,2339994098
        +.long	854058965,854058965
        +.long	1137232011,1137232011
        +.long	1496790894,1496790894
        +.long	3077402074,3077402074
        +.long	2358086913,2358086913
        +.long	1691735473,1691735473
        +.long	3528347292,3528347292
        +.long	3769215305,3769215305
        +.long	3027004632,3027004632
        +.long	4199962284,4199962284
        +.long	133494003,133494003
        +.long	636152527,636152527
        +.long	2942657994,2942657994
        +.long	2390391540,2390391540
        +.long	3920539207,3920539207
        +.long	403179536,403179536
        +.long	3585784431,3585784431
        +.long	2289596656,2289596656
        +.long	1864705354,1864705354
        +.long	1915629148,1915629148
        +.long	605822008,605822008
        +.long	4054230615,4054230615
        +.long	3350508659,3350508659
        +.long	1371981463,1371981463
        +.long	602466507,602466507
        +.long	2094914977,2094914977
        +.long	2624877800,2624877800
        +.long	555687742,555687742
        +.long	3712699286,3712699286
        +.long	3703422305,3703422305
        +.long	2257292045,2257292045
        +.long	2240449039,2240449039
        +.long	2423288032,2423288032
        +.long	1111375484,1111375484
        +.long	3300242801,3300242801
        +.long	2858837708,2858837708
        +.long	3628615824,3628615824
        +.long	84083462,84083462
        +.long	32962295,32962295
        +.long	302911004,302911004
        +.long	2741068226,2741068226
        +.long	1597322602,1597322602
        +.long	4183250862,4183250862
        +.long	3501832553,3501832553
        +.long	2441512471,2441512471
        +.long	1489093017,1489093017
        +.long	656219450,656219450
        +.long	3114180135,3114180135
        +.long	954327513,954327513
        +.long	335083755,335083755
        +.long	3013122091,3013122091
        +.long	856756514,856756514
        +.long	3144247762,3144247762
        +.long	1893325225,1893325225
        +.long	2307821063,2307821063
        +.long	2811532339,2811532339
        +.long	3063651117,3063651117
        +.long	572399164,572399164
        +.long	2458355477,2458355477
        +.long	552200649,552200649
        +.long	1238290055,1238290055
        +.long	4283782570,4283782570
        +.long	2015897680,2015897680
        +.long	2061492133,2061492133
        +.long	2408352771,2408352771
        +.long	4171342169,4171342169
        +.long	2156497161,2156497161
        +.long	386731290,386731290
        +.long	3669999461,3669999461
        +.long	837215959,837215959
        +.long	3326231172,3326231172
        +.long	3093850320,3093850320
        +.long	3275833730,3275833730
        +.long	2962856233,2962856233
        +.long	1999449434,1999449434
        +.long	286199582,286199582
        +.long	3417354363,3417354363
        +.long	4233385128,4233385128
        +.long	3602627437,3602627437
        +.long	974525996,974525996
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.byte	99,124,119,123,242,107,111,197
        +.byte	48,1,103,43,254,215,171,118
        +.byte	202,130,201,125,250,89,71,240
        +.byte	173,212,162,175,156,164,114,192
        +.byte	183,253,147,38,54,63,247,204
        +.byte	52,165,229,241,113,216,49,21
        +.byte	4,199,35,195,24,150,5,154
        +.byte	7,18,128,226,235,39,178,117
        +.byte	9,131,44,26,27,110,90,160
        +.byte	82,59,214,179,41,227,47,132
        +.byte	83,209,0,237,32,252,177,91
        +.byte	106,203,190,57,74,76,88,207
        +.byte	208,239,170,251,67,77,51,133
        +.byte	69,249,2,127,80,60,159,168
        +.byte	81,163,64,143,146,157,56,245
        +.byte	188,182,218,33,16,255,243,210
        +.byte	205,12,19,236,95,151,68,23
        +.byte	196,167,126,61,100,93,25,115
        +.byte	96,129,79,220,34,42,144,136
        +.byte	70,238,184,20,222,94,11,219
        +.byte	224,50,58,10,73,6,36,92
        +.byte	194,211,172,98,145,149,228,121
        +.byte	231,200,55,109,141,213,78,169
        +.byte	108,86,244,234,101,122,174,8
        +.byte	186,120,37,46,28,166,180,198
        +.byte	232,221,116,31,75,189,139,138
        +.byte	112,62,181,102,72,3,246,14
        +.byte	97,53,87,185,134,193,29,158
        +.byte	225,248,152,17,105,217,142,148
        +.byte	155,30,135,233,206,85,40,223
        +.byte	140,161,137,13,191,230,66,104
        +.byte	65,153,45,15,176,84,187,22
        +.long	1,2,4,8
        +.long	16,32,64,128
        +.long	27,54,0,0
        +.long	0,0,0,0
        +.globl	_AES_encrypt
        +.align	4
        +_AES_encrypt:
        +L_AES_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%eax
        +	subl	$36,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ebx
        +	subl	%esp,%ebx
        +	negl	%ebx
        +	andl	$960,%ebx
        +	subl	%ebx,%esp
        +	addl	$4,%esp
        +	movl	%eax,28(%esp)
        +	call	L004pic_point
        +L004pic_point:
        +	popl	%ebp
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L004pic_point(%ebp),%eax
        +	leal	LAES_Te-L004pic_point(%ebp),%ebp
        +	leal	764(%esp),%ebx
        +	subl	%ebp,%ebx
        +	andl	$768,%ebx
        +	leal	2176(%ebp,%ebx,1),%ebp
        +	btl	$25,(%eax)
        +	jnc	L005x86
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm4
        +	call	__sse_AES_encrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movq	%mm0,(%esi)
        +	movq	%mm4,8(%esi)
        +	emms
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4,0x90
        +L005x86:
        +	movl	%ebp,24(%esp)
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	call	__x86_AES_encrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4
        +__x86_AES_decrypt_compact:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	-128(%ebp),%edi
        +	movl	-96(%ebp),%esi
        +	movl	-64(%ebp),%edi
        +	movl	-32(%ebp),%esi
        +	movl	(%ebp),%edi
        +	movl	32(%ebp),%esi
        +	movl	64(%ebp),%edi
        +	movl	96(%ebp),%esi
        +.align	4,0x90
        +L006loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ah,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ch,%ecx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$8,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	shrl	$24,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	xorl	%eax,%edx
        +	movl	%ecx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%eax
        +	subl	%edi,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	xorl	%eax,%esi
        +	movl	%esi,%eax
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%eax,%eax,1),%ebx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%eax
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ebx,%ebx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%ecx,%ebx
        +	roll	$8,%ecx
        +	xorl	%esi,%ebp
        +	xorl	%eax,%ecx
        +	xorl	%ebp,%eax
        +	roll	$24,%eax
        +	xorl	%ebx,%ecx
        +	xorl	%ebp,%ebx
        +	roll	$16,%ebx
        +	xorl	%ebp,%ecx
        +	roll	$8,%ebp
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%ecx
        +	movl	4(%esp),%eax
        +	xorl	%ebp,%ecx
        +	movl	%ecx,12(%esp)
        +	movl	%edx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%edx,%edx,1),%ebx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%edx,%ebx
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%edx,%ecx
        +	roll	$8,%edx
        +	xorl	%esi,%ebp
        +	xorl	%ebx,%edx
        +	xorl	%ebp,%ebx
        +	roll	$24,%ebx
        +	xorl	%ecx,%edx
        +	xorl	%ebp,%ecx
        +	roll	$16,%ecx
        +	xorl	%ebp,%edx
        +	roll	$8,%ebp
        +	xorl	%ebx,%edx
        +	xorl	%ecx,%edx
        +	movl	8(%esp),%ebx
        +	xorl	%ebp,%edx
        +	movl	%edx,16(%esp)
        +	movl	%eax,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%eax,%eax,1),%ecx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%edi,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%eax,%ecx
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%edx,%edx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%eax,%edx
        +	roll	$8,%eax
        +	xorl	%esi,%ebp
        +	xorl	%ecx,%eax
        +	xorl	%ebp,%ecx
        +	roll	$24,%ecx
        +	xorl	%edx,%eax
        +	xorl	%ebp,%edx
        +	roll	$16,%edx
        +	xorl	%ebp,%eax
        +	roll	$8,%ebp
        +	xorl	%ecx,%eax
        +	xorl	%edx,%eax
        +	xorl	%ebp,%eax
        +	movl	%ebx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%edi,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%edi,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%ecx
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%edi
        +	shrl	$7,%edi
        +	leal	(%edx,%edx,1),%ebp
        +	subl	%edi,%esi
        +	andl	$4278124286,%ebp
        +	andl	$454761243,%esi
        +	xorl	%ebx,%edx
        +	roll	$8,%ebx
        +	xorl	%esi,%ebp
        +	xorl	%ecx,%ebx
        +	xorl	%ebp,%ecx
        +	roll	$24,%ecx
        +	xorl	%edx,%ebx
        +	xorl	%ebp,%edx
        +	roll	$16,%edx
        +	xorl	%ebp,%ebx
        +	roll	$8,%ebp
        +	xorl	%ecx,%ebx
        +	xorl	%edx,%ebx
        +	movl	12(%esp),%ecx
        +	xorl	%ebp,%ebx
        +	movl	16(%esp),%edx
        +	movl	20(%esp),%edi
        +	movl	28(%esp),%ebp
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	L006loop
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%ah,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	-128(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	movzbl	%ch,%ecx
        +	movzbl	-128(%ebp,%ecx,1),%ecx
        +	shll	$8,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	shrl	$24,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	xorl	16(%edi),%eax
        +	xorl	20(%edi),%ebx
        +	xorl	24(%edi),%ecx
        +	xorl	28(%edi),%edx
        +	ret
        +.align	4
        +__sse_AES_decrypt_compact:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +	movl	$454761243,%eax
        +	movl	%eax,8(%esp)
        +	movl	%eax,12(%esp)
        +	movl	-128(%ebp),%eax
        +	movl	-96(%ebp),%ebx
        +	movl	-64(%ebp),%ecx
        +	movl	-32(%ebp),%edx
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +.align	4,0x90
        +L007loop:
        +	pshufw	$12,%mm0,%mm1
        +	movd	%mm1,%eax
        +	pshufw	$9,%mm4,%mm5
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	movd	%mm5,%ebx
        +	movzbl	%ah,%edx
        +	movzbl	-128(%ebp,%edx,1),%edx
        +	shll	$8,%edx
        +	pshufw	$6,%mm0,%mm2
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%ecx
        +	shrl	$16,%eax
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%edx
        +	shrl	$16,%ebx
        +	pshufw	$3,%mm4,%mm6
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%ecx
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	movd	%ecx,%mm0
        +	movzbl	%al,%esi
        +	movd	%mm2,%eax
        +	movzbl	-128(%ebp,%esi,1),%ecx
        +	shll	$16,%ecx
        +	movzbl	%bl,%esi
        +	movd	%mm6,%ebx
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	orl	%esi,%ecx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	orl	%esi,%edx
        +	movzbl	%bl,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%edx
        +	movd	%edx,%mm1
        +	movzbl	%ah,%esi
        +	movzbl	-128(%ebp,%esi,1),%edx
        +	shll	$8,%edx
        +	movzbl	%bh,%esi
        +	shrl	$16,%eax
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$24,%esi
        +	orl	%esi,%edx
        +	shrl	$16,%ebx
        +	punpckldq	%mm1,%mm0
        +	movzbl	%bh,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$8,%esi
        +	orl	%esi,%ecx
        +	andl	$255,%ebx
        +	movzbl	-128(%ebp,%ebx,1),%ebx
        +	orl	%ebx,%edx
        +	movzbl	%al,%esi
        +	movzbl	-128(%ebp,%esi,1),%esi
        +	shll	$16,%esi
        +	orl	%esi,%edx
        +	movd	%edx,%mm4
        +	movzbl	%ah,%eax
        +	movzbl	-128(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	orl	%eax,%ecx
        +	movd	%ecx,%mm5
        +	punpckldq	%mm5,%mm4
        +	addl	$16,%edi
        +	cmpl	24(%esp),%edi
        +	ja	L008out
        +	movq	%mm0,%mm3
        +	movq	%mm4,%mm7
        +	pshufw	$228,%mm0,%mm2
        +	pshufw	$228,%mm4,%mm6
        +	movq	%mm0,%mm1
        +	movq	%mm4,%mm5
        +	pshufw	$177,%mm0,%mm0
        +	pshufw	$177,%mm4,%mm4
        +	pslld	$8,%mm2
        +	pslld	$8,%mm6
        +	psrld	$8,%mm3
        +	psrld	$8,%mm7
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pslld	$16,%mm2
        +	pslld	$16,%mm6
        +	psrld	$16,%mm3
        +	psrld	$16,%mm7
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	movq	8(%esp),%mm3
        +	pxor	%mm2,%mm2
        +	pxor	%mm6,%mm6
        +	pcmpgtb	%mm1,%mm2
        +	pcmpgtb	%mm5,%mm6
        +	pand	%mm3,%mm2
        +	pand	%mm3,%mm6
        +	paddb	%mm1,%mm1
        +	paddb	%mm5,%mm5
        +	pxor	%mm2,%mm1
        +	pxor	%mm6,%mm5
        +	movq	%mm1,%mm3
        +	movq	%mm5,%mm7
        +	movq	%mm1,%mm2
        +	movq	%mm5,%mm6
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	pslld	$24,%mm3
        +	pslld	$24,%mm7
        +	psrld	$8,%mm2
        +	psrld	$8,%mm6
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	movq	8(%esp),%mm2
        +	pxor	%mm3,%mm3
        +	pxor	%mm7,%mm7
        +	pcmpgtb	%mm1,%mm3
        +	pcmpgtb	%mm5,%mm7
        +	pand	%mm2,%mm3
        +	pand	%mm2,%mm7
        +	paddb	%mm1,%mm1
        +	paddb	%mm5,%mm5
        +	pxor	%mm3,%mm1
        +	pxor	%mm7,%mm5
        +	pshufw	$177,%mm1,%mm3
        +	pshufw	$177,%mm5,%mm7
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm3,%mm3
        +	pxor	%mm7,%mm7
        +	pcmpgtb	%mm1,%mm3
        +	pcmpgtb	%mm5,%mm7
        +	pand	%mm2,%mm3
        +	pand	%mm2,%mm7
        +	paddb	%mm1,%mm1
        +	paddb	%mm5,%mm5
        +	pxor	%mm3,%mm1
        +	pxor	%mm7,%mm5
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	movq	%mm1,%mm3
        +	movq	%mm5,%mm7
        +	pshufw	$177,%mm1,%mm2
        +	pshufw	$177,%mm5,%mm6
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	pslld	$8,%mm1
        +	pslld	$8,%mm5
        +	psrld	$8,%mm3
        +	psrld	$8,%mm7
        +	movq	(%edi),%mm2
        +	movq	8(%edi),%mm6
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	movl	-128(%ebp),%eax
        +	pslld	$16,%mm1
        +	pslld	$16,%mm5
        +	movl	-64(%ebp),%ebx
        +	psrld	$16,%mm3
        +	psrld	$16,%mm7
        +	movl	(%ebp),%ecx
        +	pxor	%mm1,%mm0
        +	pxor	%mm5,%mm4
        +	movl	64(%ebp),%edx
        +	pxor	%mm3,%mm0
        +	pxor	%mm7,%mm4
        +	pxor	%mm2,%mm0
        +	pxor	%mm6,%mm4
        +	jmp	L007loop
        +.align	4,0x90
        +L008out:
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	ret
        +.align	4
        +__x86_AES_decrypt:
        +	movl	%edi,20(%esp)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,24(%esp)
        +.align	4,0x90
        +L009loop:
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%dh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%ah,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movl	(%ebp,%esi,8),%esi
        +	movzbl	%bh,%edi
        +	xorl	3(%ebp,%edi,8),%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	xorl	2(%ebp,%edi,8),%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	xorl	1(%ebp,%edi,8),%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movl	(%ebp,%edx,8),%edx
        +	movzbl	%ch,%ecx
        +	xorl	3(%ebp,%ecx,8),%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	xorl	2(%ebp,%ebx,8),%edx
        +	movl	8(%esp),%ebx
        +	shrl	$24,%eax
        +	xorl	1(%ebp,%eax,8),%edx
        +	movl	4(%esp),%eax
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	cmpl	24(%esp),%edi
        +	movl	%edi,20(%esp)
        +	jb	L009loop
        +	leal	2176(%ebp),%ebp
        +	movl	-128(%ebp),%edi
        +	movl	-96(%ebp),%esi
        +	movl	-64(%ebp),%edi
        +	movl	-32(%ebp),%esi
        +	movl	(%ebp),%edi
        +	movl	32(%ebp),%esi
        +	movl	64(%ebp),%edi
        +	movl	96(%ebp),%esi
        +	leal	-128(%ebp),%ebp
        +	movl	%eax,%esi
        +	andl	$255,%esi
        +	movzbl	(%ebp,%esi,1),%esi
        +	movzbl	%dh,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ebx,%edi
        +	shrl	$24,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,4(%esp)
        +	movl	%ebx,%esi
        +	andl	$255,%esi
        +	movzbl	(%ebp,%esi,1),%esi
        +	movzbl	%ah,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%ecx,%edi
        +	shrl	$24,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	%esi,8(%esp)
        +	movl	%ecx,%esi
        +	andl	$255,%esi
        +	movzbl	(%ebp,%esi,1),%esi
        +	movzbl	%bh,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$8,%edi
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	shrl	$16,%edi
        +	andl	$255,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$16,%edi
        +	xorl	%edi,%esi
        +	movl	%edx,%edi
        +	shrl	$24,%edi
        +	movzbl	(%ebp,%edi,1),%edi
        +	shll	$24,%edi
        +	xorl	%edi,%esi
        +	movl	20(%esp),%edi
        +	andl	$255,%edx
        +	movzbl	(%ebp,%edx,1),%edx
        +	movzbl	%ch,%ecx
        +	movzbl	(%ebp,%ecx,1),%ecx
        +	shll	$8,%ecx
        +	xorl	%ecx,%edx
        +	movl	%esi,%ecx
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	movzbl	(%ebp,%ebx,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%edx
        +	movl	8(%esp),%ebx
        +	shrl	$24,%eax
        +	movzbl	(%ebp,%eax,1),%eax
        +	shll	$24,%eax
        +	xorl	%eax,%edx
        +	movl	4(%esp),%eax
        +	leal	-2048(%ebp),%ebp
        +	addl	$16,%edi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	ret
        +.align	6,0x90
        +LAES_Td:
        +.long	1353184337,1353184337
        +.long	1399144830,1399144830
        +.long	3282310938,3282310938
        +.long	2522752826,2522752826
        +.long	3412831035,3412831035
        +.long	4047871263,4047871263
        +.long	2874735276,2874735276
        +.long	2466505547,2466505547
        +.long	1442459680,1442459680
        +.long	4134368941,4134368941
        +.long	2440481928,2440481928
        +.long	625738485,625738485
        +.long	4242007375,4242007375
        +.long	3620416197,3620416197
        +.long	2151953702,2151953702
        +.long	2409849525,2409849525
        +.long	1230680542,1230680542
        +.long	1729870373,1729870373
        +.long	2551114309,2551114309
        +.long	3787521629,3787521629
        +.long	41234371,41234371
        +.long	317738113,317738113
        +.long	2744600205,2744600205
        +.long	3338261355,3338261355
        +.long	3881799427,3881799427
        +.long	2510066197,2510066197
        +.long	3950669247,3950669247
        +.long	3663286933,3663286933
        +.long	763608788,763608788
        +.long	3542185048,3542185048
        +.long	694804553,694804553
        +.long	1154009486,1154009486
        +.long	1787413109,1787413109
        +.long	2021232372,2021232372
        +.long	1799248025,1799248025
        +.long	3715217703,3715217703
        +.long	3058688446,3058688446
        +.long	397248752,397248752
        +.long	1722556617,1722556617
        +.long	3023752829,3023752829
        +.long	407560035,407560035
        +.long	2184256229,2184256229
        +.long	1613975959,1613975959
        +.long	1165972322,1165972322
        +.long	3765920945,3765920945
        +.long	2226023355,2226023355
        +.long	480281086,480281086
        +.long	2485848313,2485848313
        +.long	1483229296,1483229296
        +.long	436028815,436028815
        +.long	2272059028,2272059028
        +.long	3086515026,3086515026
        +.long	601060267,601060267
        +.long	3791801202,3791801202
        +.long	1468997603,1468997603
        +.long	715871590,715871590
        +.long	120122290,120122290
        +.long	63092015,63092015
        +.long	2591802758,2591802758
        +.long	2768779219,2768779219
        +.long	4068943920,4068943920
        +.long	2997206819,2997206819
        +.long	3127509762,3127509762
        +.long	1552029421,1552029421
        +.long	723308426,723308426
        +.long	2461301159,2461301159
        +.long	4042393587,4042393587
        +.long	2715969870,2715969870
        +.long	3455375973,3455375973
        +.long	3586000134,3586000134
        +.long	526529745,526529745
        +.long	2331944644,2331944644
        +.long	2639474228,2639474228
        +.long	2689987490,2689987490
        +.long	853641733,853641733
        +.long	1978398372,1978398372
        +.long	971801355,971801355
        +.long	2867814464,2867814464
        +.long	111112542,111112542
        +.long	1360031421,1360031421
        +.long	4186579262,4186579262
        +.long	1023860118,1023860118
        +.long	2919579357,2919579357
        +.long	1186850381,1186850381
        +.long	3045938321,3045938321
        +.long	90031217,90031217
        +.long	1876166148,1876166148
        +.long	4279586912,4279586912
        +.long	620468249,620468249
        +.long	2548678102,2548678102
        +.long	3426959497,3426959497
        +.long	2006899047,2006899047
        +.long	3175278768,3175278768
        +.long	2290845959,2290845959
        +.long	945494503,945494503
        +.long	3689859193,3689859193
        +.long	1191869601,1191869601
        +.long	3910091388,3910091388
        +.long	3374220536,3374220536
        +.long	0,0
        +.long	2206629897,2206629897
        +.long	1223502642,1223502642
        +.long	2893025566,2893025566
        +.long	1316117100,1316117100
        +.long	4227796733,4227796733
        +.long	1446544655,1446544655
        +.long	517320253,517320253
        +.long	658058550,658058550
        +.long	1691946762,1691946762
        +.long	564550760,564550760
        +.long	3511966619,3511966619
        +.long	976107044,976107044
        +.long	2976320012,2976320012
        +.long	266819475,266819475
        +.long	3533106868,3533106868
        +.long	2660342555,2660342555
        +.long	1338359936,1338359936
        +.long	2720062561,2720062561
        +.long	1766553434,1766553434
        +.long	370807324,370807324
        +.long	179999714,179999714
        +.long	3844776128,3844776128
        +.long	1138762300,1138762300
        +.long	488053522,488053522
        +.long	185403662,185403662
        +.long	2915535858,2915535858
        +.long	3114841645,3114841645
        +.long	3366526484,3366526484
        +.long	2233069911,2233069911
        +.long	1275557295,1275557295
        +.long	3151862254,3151862254
        +.long	4250959779,4250959779
        +.long	2670068215,2670068215
        +.long	3170202204,3170202204
        +.long	3309004356,3309004356
        +.long	880737115,880737115
        +.long	1982415755,1982415755
        +.long	3703972811,3703972811
        +.long	1761406390,1761406390
        +.long	1676797112,1676797112
        +.long	3403428311,3403428311
        +.long	277177154,277177154
        +.long	1076008723,1076008723
        +.long	538035844,538035844
        +.long	2099530373,2099530373
        +.long	4164795346,4164795346
        +.long	288553390,288553390
        +.long	1839278535,1839278535
        +.long	1261411869,1261411869
        +.long	4080055004,4080055004
        +.long	3964831245,3964831245
        +.long	3504587127,3504587127
        +.long	1813426987,1813426987
        +.long	2579067049,2579067049
        +.long	4199060497,4199060497
        +.long	577038663,577038663
        +.long	3297574056,3297574056
        +.long	440397984,440397984
        +.long	3626794326,3626794326
        +.long	4019204898,4019204898
        +.long	3343796615,3343796615
        +.long	3251714265,3251714265
        +.long	4272081548,4272081548
        +.long	906744984,906744984
        +.long	3481400742,3481400742
        +.long	685669029,685669029
        +.long	646887386,646887386
        +.long	2764025151,2764025151
        +.long	3835509292,3835509292
        +.long	227702864,227702864
        +.long	2613862250,2613862250
        +.long	1648787028,1648787028
        +.long	3256061430,3256061430
        +.long	3904428176,3904428176
        +.long	1593260334,1593260334
        +.long	4121936770,4121936770
        +.long	3196083615,3196083615
        +.long	2090061929,2090061929
        +.long	2838353263,2838353263
        +.long	3004310991,3004310991
        +.long	999926984,999926984
        +.long	2809993232,2809993232
        +.long	1852021992,1852021992
        +.long	2075868123,2075868123
        +.long	158869197,158869197
        +.long	4095236462,4095236462
        +.long	28809964,28809964
        +.long	2828685187,2828685187
        +.long	1701746150,1701746150
        +.long	2129067946,2129067946
        +.long	147831841,147831841
        +.long	3873969647,3873969647
        +.long	3650873274,3650873274
        +.long	3459673930,3459673930
        +.long	3557400554,3557400554
        +.long	3598495785,3598495785
        +.long	2947720241,2947720241
        +.long	824393514,824393514
        +.long	815048134,815048134
        +.long	3227951669,3227951669
        +.long	935087732,935087732
        +.long	2798289660,2798289660
        +.long	2966458592,2966458592
        +.long	366520115,366520115
        +.long	1251476721,1251476721
        +.long	4158319681,4158319681
        +.long	240176511,240176511
        +.long	804688151,804688151
        +.long	2379631990,2379631990
        +.long	1303441219,1303441219
        +.long	1414376140,1414376140
        +.long	3741619940,3741619940
        +.long	3820343710,3820343710
        +.long	461924940,461924940
        +.long	3089050817,3089050817
        +.long	2136040774,2136040774
        +.long	82468509,82468509
        +.long	1563790337,1563790337
        +.long	1937016826,1937016826
        +.long	776014843,776014843
        +.long	1511876531,1511876531
        +.long	1389550482,1389550482
        +.long	861278441,861278441
        +.long	323475053,323475053
        +.long	2355222426,2355222426
        +.long	2047648055,2047648055
        +.long	2383738969,2383738969
        +.long	2302415851,2302415851
        +.long	3995576782,3995576782
        +.long	902390199,902390199
        +.long	3991215329,3991215329
        +.long	1018251130,1018251130
        +.long	1507840668,1507840668
        +.long	1064563285,1064563285
        +.long	2043548696,2043548696
        +.long	3208103795,3208103795
        +.long	3939366739,3939366739
        +.long	1537932639,1537932639
        +.long	342834655,342834655
        +.long	2262516856,2262516856
        +.long	2180231114,2180231114
        +.long	1053059257,1053059257
        +.long	741614648,741614648
        +.long	1598071746,1598071746
        +.long	1925389590,1925389590
        +.long	203809468,203809468
        +.long	2336832552,2336832552
        +.long	1100287487,1100287487
        +.long	1895934009,1895934009
        +.long	3736275976,3736275976
        +.long	2632234200,2632234200
        +.long	2428589668,2428589668
        +.long	1636092795,1636092795
        +.long	1890988757,1890988757
        +.long	1952214088,1952214088
        +.long	1113045200,1113045200
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.byte	82,9,106,213,48,54,165,56
        +.byte	191,64,163,158,129,243,215,251
        +.byte	124,227,57,130,155,47,255,135
        +.byte	52,142,67,68,196,222,233,203
        +.byte	84,123,148,50,166,194,35,61
        +.byte	238,76,149,11,66,250,195,78
        +.byte	8,46,161,102,40,217,36,178
        +.byte	118,91,162,73,109,139,209,37
        +.byte	114,248,246,100,134,104,152,22
        +.byte	212,164,92,204,93,101,182,146
        +.byte	108,112,72,80,253,237,185,218
        +.byte	94,21,70,87,167,141,157,132
        +.byte	144,216,171,0,140,188,211,10
        +.byte	247,228,88,5,184,179,69,6
        +.byte	208,44,30,143,202,63,15,2
        +.byte	193,175,189,3,1,19,138,107
        +.byte	58,145,17,65,79,103,220,234
        +.byte	151,242,207,206,240,180,230,115
        +.byte	150,172,116,34,231,173,53,133
        +.byte	226,249,55,232,28,117,223,110
        +.byte	71,241,26,113,29,41,197,137
        +.byte	111,183,98,14,170,24,190,27
        +.byte	252,86,62,75,198,210,121,32
        +.byte	154,219,192,254,120,205,90,244
        +.byte	31,221,168,51,136,7,199,49
        +.byte	177,18,16,89,39,128,236,95
        +.byte	96,81,127,169,25,181,74,13
        +.byte	45,229,122,159,147,201,156,239
        +.byte	160,224,59,77,174,42,245,176
        +.byte	200,235,187,60,131,83,153,97
        +.byte	23,43,4,126,186,119,214,38
        +.byte	225,105,20,99,85,33,12,125
        +.globl	_AES_decrypt
        +.align	4
        +_AES_decrypt:
        +L_AES_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%eax
        +	subl	$36,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ebx
        +	subl	%esp,%ebx
        +	negl	%ebx
        +	andl	$960,%ebx
        +	subl	%ebx,%esp
        +	addl	$4,%esp
        +	movl	%eax,28(%esp)
        +	call	L010pic_point
        +L010pic_point:
        +	popl	%ebp
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L010pic_point(%ebp),%eax
        +	leal	LAES_Td-L010pic_point(%ebp),%ebp
        +	leal	764(%esp),%ebx
        +	subl	%ebp,%ebx
        +	andl	$768,%ebx
        +	leal	2176(%ebp,%ebx,1),%ebp
        +	btl	$25,(%eax)
        +	jnc	L011x86
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm4
        +	call	__sse_AES_decrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movq	%mm0,(%esi)
        +	movq	%mm4,8(%esi)
        +	emms
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4,0x90
        +L011x86:
        +	movl	%ebp,24(%esp)
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	call	__x86_AES_decrypt_compact
        +	movl	28(%esp),%esp
        +	movl	24(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_AES_cbc_encrypt
        +.align	4
        +_AES_cbc_encrypt:
        +L_AES_cbc_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ecx
        +	cmpl	$0,%ecx
        +	je	L012drop_out
        +	call	L013pic_point
        +L013pic_point:
        +	popl	%ebp
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L013pic_point(%ebp),%eax
        +	cmpl	$0,40(%esp)
        +	leal	LAES_Te-L013pic_point(%ebp),%ebp
        +	jne	L014picked_te
        +	leal	LAES_Td-LAES_Te(%ebp),%ebp
        +L014picked_te:
        +	pushfl
        +	cld
        +	cmpl	$512,%ecx
        +	jb	L015slow_way
        +	testl	$15,%ecx
        +	jnz	L015slow_way
        +	leal	-324(%esp),%esi
        +	andl	$-64,%esi
        +	movl	%ebp,%eax
        +	leal	2304(%ebp),%ebx
        +	movl	%esi,%edx
        +	andl	$4095,%eax
        +	andl	$4095,%ebx
        +	andl	$4095,%edx
        +	cmpl	%ebx,%edx
        +	jb	L016tbl_break_out
        +	subl	%ebx,%edx
        +	subl	%edx,%esi
        +	jmp	L017tbl_ok
        +.align	2,0x90
        +L016tbl_break_out:
        +	subl	%eax,%edx
        +	andl	$4095,%edx
        +	addl	$384,%edx
        +	subl	%edx,%esi
        +.align	2,0x90
        +L017tbl_ok:
        +	leal	24(%esp),%edx
        +	xchgl	%esi,%esp
        +	addl	$4,%esp
        +	movl	%ebp,24(%esp)
        +	movl	%esi,28(%esp)
        +	movl	(%edx),%eax
        +	movl	4(%edx),%ebx
        +	movl	12(%edx),%edi
        +	movl	16(%edx),%esi
        +	movl	20(%edx),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,40(%esp)
        +	movl	%edi,44(%esp)
        +	movl	%esi,48(%esp)
        +	movl	$0,316(%esp)
        +	movl	%edi,%ebx
        +	movl	$61,%ecx
        +	subl	%ebp,%ebx
        +	movl	%edi,%esi
        +	andl	$4095,%ebx
        +	leal	76(%esp),%edi
        +	cmpl	$2304,%ebx
        +	jb	L018do_copy
        +	cmpl	$3852,%ebx
        +	jb	L019skip_copy
        +.align	2,0x90
        +L018do_copy:
        +	movl	%edi,44(%esp)
        +.long	2784229001
        +L019skip_copy:
        +	movl	$16,%edi
        +.align	2,0x90
        +L020prefetch_tbl:
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%esi
        +	leal	128(%ebp),%ebp
        +	subl	$1,%edi
        +	jnz	L020prefetch_tbl
        +	subl	$2048,%ebp
        +	movl	32(%esp),%esi
        +	movl	48(%esp),%edi
        +	cmpl	$0,%edx
        +	je	L021fast_decrypt
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +.align	4,0x90
        +L022fast_enc_loop:
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	xorl	12(%esi),%edx
        +	movl	44(%esp),%edi
        +	call	__x86_AES_encrypt
        +	movl	32(%esp),%esi
        +	movl	36(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	leal	16(%esi),%esi
        +	movl	40(%esp),%ecx
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,36(%esp)
        +	subl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jnz	L022fast_enc_loop
        +	movl	48(%esp),%esi
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	cmpl	$0,316(%esp)
        +	movl	44(%esp),%edi
        +	je	L023skip_ezero
        +	movl	$60,%ecx
        +	xorl	%eax,%eax
        +.align	2,0x90
        +.long	2884892297
        +L023skip_ezero:
        +	movl	28(%esp),%esp
        +	popfl
        +L012drop_out:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L021fast_decrypt:
        +	cmpl	36(%esp),%esi
        +	je	L024fast_dec_in_place
        +	movl	%edi,52(%esp)
        +.align	2,0x90
        +.align	4,0x90
        +L025fast_dec_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	44(%esp),%edi
        +	call	__x86_AES_decrypt
        +	movl	52(%esp),%edi
        +	movl	40(%esp),%esi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	36(%esp),%edi
        +	movl	32(%esp),%esi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	40(%esp),%ecx
        +	movl	%esi,52(%esp)
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edi
        +	movl	%edi,36(%esp)
        +	subl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jnz	L025fast_dec_loop
        +	movl	52(%esp),%edi
        +	movl	48(%esp),%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	jmp	L026fast_dec_out
        +.align	4,0x90
        +L024fast_dec_in_place:
        +L027fast_dec_in_place_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	leal	60(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	44(%esp),%edi
        +	call	__x86_AES_decrypt
        +	movl	48(%esp),%edi
        +	movl	36(%esp),%esi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	leal	16(%esi),%esi
        +	movl	%esi,36(%esp)
        +	leal	60(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	32(%esp),%esi
        +	movl	40(%esp),%ecx
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	subl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jnz	L027fast_dec_in_place_loop
        +.align	2,0x90
        +L026fast_dec_out:
        +	cmpl	$0,316(%esp)
        +	movl	44(%esp),%edi
        +	je	L028skip_dzero
        +	movl	$60,%ecx
        +	xorl	%eax,%eax
        +.align	2,0x90
        +.long	2884892297
        +L028skip_dzero:
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L015slow_way:
        +	movl	(%eax),%eax
        +	movl	36(%esp),%edi
        +	leal	-80(%esp),%esi
        +	andl	$-64,%esi
        +	leal	-143(%edi),%ebx
        +	subl	%esi,%ebx
        +	negl	%ebx
        +	andl	$960,%ebx
        +	subl	%ebx,%esi
        +	leal	768(%esi),%ebx
        +	subl	%ebp,%ebx
        +	andl	$768,%ebx
        +	leal	2176(%ebp,%ebx,1),%ebp
        +	leal	24(%esp),%edx
        +	xchgl	%esi,%esp
        +	addl	$4,%esp
        +	movl	%ebp,24(%esp)
        +	movl	%esi,28(%esp)
        +	movl	%eax,52(%esp)
        +	movl	(%edx),%eax
        +	movl	4(%edx),%ebx
        +	movl	16(%edx),%esi
        +	movl	20(%edx),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,40(%esp)
        +	movl	%edi,44(%esp)
        +	movl	%esi,48(%esp)
        +	movl	%esi,%edi
        +	movl	%eax,%esi
        +	cmpl	$0,%edx
        +	je	L029slow_decrypt
        +	cmpl	$16,%ecx
        +	movl	%ebx,%edx
        +	jb	L030slow_enc_tail
        +	btl	$25,52(%esp)
        +	jnc	L031slow_enc_x86
        +	movq	(%edi),%mm0
        +	movq	8(%edi),%mm4
        +.align	4,0x90
        +L032slow_enc_loop_sse:
        +	pxor	(%esi),%mm0
        +	pxor	8(%esi),%mm4
        +	movl	44(%esp),%edi
        +	call	__sse_AES_encrypt_compact
        +	movl	32(%esp),%esi
        +	movl	36(%esp),%edi
        +	movl	40(%esp),%ecx
        +	movq	%mm0,(%edi)
        +	movq	%mm4,8(%edi)
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,36(%esp)
        +	subl	$16,%ecx
        +	cmpl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jae	L032slow_enc_loop_sse
        +	testl	$15,%ecx
        +	jnz	L030slow_enc_tail
        +	movl	48(%esp),%esi
        +	movq	%mm0,(%esi)
        +	movq	%mm4,8(%esi)
        +	emms
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L031slow_enc_x86:
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +.align	2,0x90
        +L033slow_enc_loop_x86:
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	xorl	12(%esi),%edx
        +	movl	44(%esp),%edi
        +	call	__x86_AES_encrypt_compact
        +	movl	32(%esp),%esi
        +	movl	36(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	40(%esp),%ecx
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,36(%esp)
        +	subl	$16,%ecx
        +	cmpl	$16,%ecx
        +	movl	%ecx,40(%esp)
        +	jae	L033slow_enc_loop_x86
        +	testl	$15,%ecx
        +	jnz	L030slow_enc_tail
        +	movl	48(%esp),%esi
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L030slow_enc_tail:
        +	emms
        +	movl	%edx,%edi
        +	movl	$16,%ebx
        +	subl	%ecx,%ebx
        +	cmpl	%esi,%edi
        +	je	L034enc_in_place
        +.align	2,0x90
        +.long	2767451785
        +	jmp	L035enc_skip_in_place
        +L034enc_in_place:
        +	leal	(%edi,%ecx,1),%edi
        +L035enc_skip_in_place:
        +	movl	%ebx,%ecx
        +	xorl	%eax,%eax
        +.align	2,0x90
        +.long	2868115081
        +	movl	48(%esp),%edi
        +	movl	%edx,%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	$16,40(%esp)
        +	jmp	L033slow_enc_loop_x86
        +.align	4,0x90
        +L029slow_decrypt:
        +	btl	$25,52(%esp)
        +	jnc	L036slow_dec_loop_x86
        +.align	2,0x90
        +L037slow_dec_loop_sse:
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm4
        +	movl	44(%esp),%edi
        +	call	__sse_AES_decrypt_compact
        +	movl	32(%esp),%esi
        +	leal	60(%esp),%eax
        +	movl	36(%esp),%ebx
        +	movl	40(%esp),%ecx
        +	movl	48(%esp),%edi
        +	movq	(%esi),%mm1
        +	movq	8(%esi),%mm5
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm4
        +	movq	%mm1,(%edi)
        +	movq	%mm5,8(%edi)
        +	subl	$16,%ecx
        +	jc	L038slow_dec_partial_sse
        +	movq	%mm0,(%ebx)
        +	movq	%mm4,8(%ebx)
        +	leal	16(%ebx),%ebx
        +	movl	%ebx,36(%esp)
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	movl	%ecx,40(%esp)
        +	jnz	L037slow_dec_loop_sse
        +	emms
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L038slow_dec_partial_sse:
        +	movq	%mm0,(%eax)
        +	movq	%mm4,8(%eax)
        +	emms
        +	addl	$16,%ecx
        +	movl	%ebx,%edi
        +	movl	%eax,%esi
        +.align	2,0x90
        +.long	2767451785
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L036slow_dec_loop_x86:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	leal	60(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	44(%esp),%edi
        +	call	__x86_AES_decrypt_compact
        +	movl	48(%esp),%edi
        +	movl	40(%esp),%esi
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	subl	$16,%esi
        +	jc	L039slow_dec_partial_x86
        +	movl	%esi,40(%esp)
        +	movl	36(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	leal	16(%esi),%esi
        +	movl	%esi,36(%esp)
        +	leal	60(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	32(%esp),%esi
        +	leal	16(%esi),%esi
        +	movl	%esi,32(%esp)
        +	jnz	L036slow_dec_loop_x86
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	4,0x90
        +L039slow_dec_partial_x86:
        +	leal	60(%esp),%esi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	32(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	40(%esp),%ecx
        +	movl	36(%esp),%edi
        +	leal	60(%esp),%esi
        +.align	2,0x90
        +.long	2767451785
        +	movl	28(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4
        +__x86_AES_set_encrypt_key:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	24(%esp),%esi
        +	movl	32(%esp),%edi
        +	testl	$-1,%esi
        +	jz	L040badpointer
        +	testl	$-1,%edi
        +	jz	L040badpointer
        +	call	L041pic_point
        +L041pic_point:
        +	popl	%ebp
        +	leal	LAES_Te-L041pic_point(%ebp),%ebp
        +	leal	2176(%ebp),%ebp
        +	movl	-128(%ebp),%eax
        +	movl	-96(%ebp),%ebx
        +	movl	-64(%ebp),%ecx
        +	movl	-32(%ebp),%edx
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +	movl	28(%esp),%ecx
        +	cmpl	$128,%ecx
        +	je	L04210rounds
        +	cmpl	$192,%ecx
        +	je	L04312rounds
        +	cmpl	$256,%ecx
        +	je	L04414rounds
        +	movl	$-2,%eax
        +	jmp	L045exit
        +L04210rounds:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	xorl	%ecx,%ecx
        +	jmp	L04610shortcut
        +.align	2,0x90
        +L04710loop:
        +	movl	(%edi),%eax
        +	movl	12(%edi),%edx
        +L04610shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	xorl	896(%ebp,%ecx,4),%eax
        +	movl	%eax,16(%edi)
        +	xorl	4(%edi),%eax
        +	movl	%eax,20(%edi)
        +	xorl	8(%edi),%eax
        +	movl	%eax,24(%edi)
        +	xorl	12(%edi),%eax
        +	movl	%eax,28(%edi)
        +	incl	%ecx
        +	addl	$16,%edi
        +	cmpl	$10,%ecx
        +	jl	L04710loop
        +	movl	$10,80(%edi)
        +	xorl	%eax,%eax
        +	jmp	L045exit
        +L04312rounds:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	16(%esi),%ecx
        +	movl	20(%esi),%edx
        +	movl	%ecx,16(%edi)
        +	movl	%edx,20(%edi)
        +	xorl	%ecx,%ecx
        +	jmp	L04812shortcut
        +.align	2,0x90
        +L04912loop:
        +	movl	(%edi),%eax
        +	movl	20(%edi),%edx
        +L04812shortcut:
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	xorl	896(%ebp,%ecx,4),%eax
        +	movl	%eax,24(%edi)
        +	xorl	4(%edi),%eax
        +	movl	%eax,28(%edi)
        +	xorl	8(%edi),%eax
        +	movl	%eax,32(%edi)
        +	xorl	12(%edi),%eax
        +	movl	%eax,36(%edi)
        +	cmpl	$7,%ecx
        +	je	L05012break
        +	incl	%ecx
        +	xorl	16(%edi),%eax
        +	movl	%eax,40(%edi)
        +	xorl	20(%edi),%eax
        +	movl	%eax,44(%edi)
        +	addl	$24,%edi
        +	jmp	L04912loop
        +L05012break:
        +	movl	$12,72(%edi)
        +	xorl	%eax,%eax
        +	jmp	L045exit
        +L04414rounds:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	movl	%eax,16(%edi)
        +	movl	%ebx,20(%edi)
        +	movl	%ecx,24(%edi)
        +	movl	%edx,28(%edi)
        +	xorl	%ecx,%ecx
        +	jmp	L05114shortcut
        +.align	2,0x90
        +L05214loop:
        +	movl	28(%edi),%edx
        +L05114shortcut:
        +	movl	(%edi),%eax
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$8,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	xorl	896(%ebp,%ecx,4),%eax
        +	movl	%eax,32(%edi)
        +	xorl	4(%edi),%eax
        +	movl	%eax,36(%edi)
        +	xorl	8(%edi),%eax
        +	movl	%eax,40(%edi)
        +	xorl	12(%edi),%eax
        +	movl	%eax,44(%edi)
        +	cmpl	$6,%ecx
        +	je	L05314break
        +	incl	%ecx
        +	movl	%eax,%edx
        +	movl	16(%edi),%eax
        +	movzbl	%dl,%esi
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shrl	$16,%edx
        +	shll	$8,%ebx
        +	movzbl	%dl,%esi
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	movzbl	%dh,%esi
        +	shll	$16,%ebx
        +	xorl	%ebx,%eax
        +	movzbl	-128(%ebp,%esi,1),%ebx
        +	shll	$24,%ebx
        +	xorl	%ebx,%eax
        +	movl	%eax,48(%edi)
        +	xorl	20(%edi),%eax
        +	movl	%eax,52(%edi)
        +	xorl	24(%edi),%eax
        +	movl	%eax,56(%edi)
        +	xorl	28(%edi),%eax
        +	movl	%eax,60(%edi)
        +	addl	$32,%edi
        +	jmp	L05214loop
        +L05314break:
        +	movl	$14,48(%edi)
        +	xorl	%eax,%eax
        +	jmp	L045exit
        +L040badpointer:
        +	movl	$-1,%eax
        +L045exit:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_private_AES_set_encrypt_key
        +.align	4
        +_private_AES_set_encrypt_key:
        +L_private_AES_set_encrypt_key_begin:
        +	call	__x86_AES_set_encrypt_key
        +	ret
        +.globl	_private_AES_set_decrypt_key
        +.align	4
        +_private_AES_set_decrypt_key:
        +L_private_AES_set_decrypt_key_begin:
        +	call	__x86_AES_set_encrypt_key
        +	cmpl	$0,%eax
        +	je	L054proceed
        +	ret
        +L054proceed:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%esi
        +	movl	240(%esi),%ecx
        +	leal	(,%ecx,4),%ecx
        +	leal	(%esi,%ecx,4),%edi
        +.align	2,0x90
        +L055invert:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	(%edi),%ecx
        +	movl	4(%edi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,(%esi)
        +	movl	%edx,4(%esi)
        +	movl	8(%esi),%eax
        +	movl	12(%esi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,8(%edi)
        +	movl	%ebx,12(%edi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	addl	$16,%esi
        +	subl	$16,%edi
        +	cmpl	%edi,%esi
        +	jne	L055invert
        +	movl	28(%esp),%edi
        +	movl	240(%edi),%esi
        +	leal	-2(%esi,%esi,1),%esi
        +	leal	(%edi,%esi,8),%esi
        +	movl	%esi,28(%esp)
        +	movl	16(%edi),%eax
        +.align	2,0x90
        +L056permute:
        +	addl	$16,%edi
        +	movl	%eax,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%ebx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%eax,%ebx
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edx
        +	xorl	%eax,%ecx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	roll	$8,%eax
        +	xorl	%esi,%edx
        +	movl	4(%edi),%ebp
        +	xorl	%ebx,%eax
        +	xorl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$24,%ebx
        +	xorl	%edx,%ecx
        +	xorl	%edx,%eax
        +	roll	$16,%ecx
        +	xorl	%ebx,%eax
        +	roll	$8,%edx
        +	xorl	%ecx,%eax
        +	movl	%ebp,%ebx
        +	xorl	%edx,%eax
        +	movl	%eax,(%edi)
        +	movl	%ebx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%ecx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	xorl	%ecx,%esi
        +	movl	%esi,%ecx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%ebx,%ecx
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%eax
        +	xorl	%ebx,%edx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	roll	$8,%ebx
        +	xorl	%esi,%eax
        +	movl	8(%edi),%ebp
        +	xorl	%ecx,%ebx
        +	xorl	%eax,%ecx
        +	xorl	%edx,%ebx
        +	roll	$24,%ecx
        +	xorl	%eax,%edx
        +	xorl	%eax,%ebx
        +	roll	$16,%edx
        +	xorl	%ecx,%ebx
        +	roll	$8,%eax
        +	xorl	%edx,%ebx
        +	movl	%ebp,%ecx
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ecx,%ecx,1),%edx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%edx
        +	andl	$454761243,%esi
        +	xorl	%edx,%esi
        +	movl	%esi,%edx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%eax
        +	subl	%ebp,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	xorl	%ecx,%edx
        +	xorl	%eax,%esi
        +	movl	%esi,%eax
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%ebx
        +	xorl	%ecx,%eax
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	roll	$8,%ecx
        +	xorl	%esi,%ebx
        +	movl	12(%edi),%ebp
        +	xorl	%edx,%ecx
        +	xorl	%ebx,%edx
        +	xorl	%eax,%ecx
        +	roll	$24,%edx
        +	xorl	%ebx,%eax
        +	xorl	%ebx,%ecx
        +	roll	$16,%eax
        +	xorl	%edx,%ecx
        +	roll	$8,%ebx
        +	xorl	%eax,%ecx
        +	movl	%ebp,%edx
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%edi)
        +	movl	%edx,%esi
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%edx,%edx,1),%eax
        +	subl	%ebp,%esi
        +	andl	$4278124286,%eax
        +	andl	$454761243,%esi
        +	xorl	%eax,%esi
        +	movl	%esi,%eax
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%eax,%eax,1),%ebx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ebx
        +	andl	$454761243,%esi
        +	xorl	%edx,%eax
        +	xorl	%ebx,%esi
        +	movl	%esi,%ebx
        +	andl	$2155905152,%esi
        +	movl	%esi,%ebp
        +	shrl	$7,%ebp
        +	leal	(%ebx,%ebx,1),%ecx
        +	xorl	%edx,%ebx
        +	subl	%ebp,%esi
        +	andl	$4278124286,%ecx
        +	andl	$454761243,%esi
        +	roll	$8,%edx
        +	xorl	%esi,%ecx
        +	movl	16(%edi),%ebp
        +	xorl	%eax,%edx
        +	xorl	%ecx,%eax
        +	xorl	%ebx,%edx
        +	roll	$24,%eax
        +	xorl	%ecx,%ebx
        +	xorl	%ecx,%edx
        +	roll	$16,%ebx
        +	xorl	%eax,%edx
        +	roll	$8,%ecx
        +	xorl	%ebx,%edx
        +	movl	%ebp,%eax
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%edi)
        +	cmpl	28(%esp),%edi
        +	jb	L056permute
        +	xorl	%eax,%eax
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.byte	65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89
        +.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
        +.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.section __IMPORT,__pointers,non_lazy_symbol_pointers
        +L_OPENSSL_ia32cap_P$non_lazy_ptr:
        +.indirect_symbol	_OPENSSL_ia32cap_P
        +.long	0
        +.comm	_OPENSSL_ia32cap_P,8,2
        diff --git a/vendor/openssl/asm/x86-macosx-gas/aes/aesni-x86.s b/vendor/openssl/asm/x86-macosx-gas/aes/aesni-x86.s
        new file mode 100644
        index 000000000..183ecad29
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/aes/aesni-x86.s
        @@ -0,0 +1,2107 @@
        +.file	"../openssl/crypto/aes/asm/aesni-x86.s"
        +.text
        +.globl	_aesni_encrypt
        +.align	4
        +_aesni_encrypt:
        +L_aesni_encrypt_begin:
        +	movl	4(%esp),%eax
        +	movl	12(%esp),%edx
        +	movups	(%eax),%xmm2
        +	movl	240(%edx),%ecx
        +	movl	8(%esp),%eax
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L000enc1_loop_1:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L000enc1_loop_1
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%eax)
        +	ret
        +.globl	_aesni_decrypt
        +.align	4
        +_aesni_decrypt:
        +L_aesni_decrypt_begin:
        +	movl	4(%esp),%eax
        +	movl	12(%esp),%edx
        +	movups	(%eax),%xmm2
        +	movl	240(%edx),%ecx
        +	movl	8(%esp),%eax
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L001dec1_loop_2:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L001dec1_loop_2
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%eax)
        +	ret
        +.align	4
        +__aesni_encrypt3:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	movups	(%edx),%xmm0
        +L002enc3_loop:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,224
        +	movups	(%edx),%xmm0
        +	jnz	L002enc3_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +	ret
        +.align	4
        +__aesni_decrypt3:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	movups	(%edx),%xmm0
        +L003dec3_loop:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,222,224
        +	movups	(%edx),%xmm0
        +	jnz	L003dec3_loop
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +	ret
        +.align	4
        +__aesni_encrypt4:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	shrl	$1,%ecx
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm0,%xmm5
        +	movups	(%edx),%xmm0
        +L004enc4_loop:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +	movups	(%edx),%xmm0
        +	jnz	L004enc4_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +	ret
        +.align	4
        +__aesni_decrypt4:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	shrl	$1,%ecx
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm0,%xmm5
        +	movups	(%edx),%xmm0
        +L005dec4_loop:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +	movups	(%edx),%xmm0
        +	jnz	L005dec4_loop
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +	ret
        +.align	4
        +__aesni_encrypt6:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,220,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,220,249
        +	jmp	L_aesni_encrypt6_enter
        +.align	4,0x90
        +L006enc6_loop:
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.align	4,0x90
        +L_aesni_encrypt6_enter:
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +.byte	102,15,56,220,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,224
        +.byte	102,15,56,220,232
        +.byte	102,15,56,220,240
        +.byte	102,15,56,220,248
        +	movups	(%edx),%xmm0
        +	jnz	L006enc6_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +.byte	102,15,56,220,225
        +.byte	102,15,56,220,233
        +.byte	102,15,56,220,241
        +.byte	102,15,56,220,249
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +.byte	102,15,56,221,224
        +.byte	102,15,56,221,232
        +.byte	102,15,56,221,240
        +.byte	102,15,56,221,248
        +	ret
        +.align	4
        +__aesni_decrypt6:
        +	movups	(%edx),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,222,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,222,217
        +	pxor	%xmm0,%xmm5
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,222,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,222,249
        +	jmp	L_aesni_decrypt6_enter
        +.align	4,0x90
        +L007dec6_loop:
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.align	4,0x90
        +L_aesni_decrypt6_enter:
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,222,208
        +.byte	102,15,56,222,216
        +	leal	32(%edx),%edx
        +.byte	102,15,56,222,224
        +.byte	102,15,56,222,232
        +.byte	102,15,56,222,240
        +.byte	102,15,56,222,248
        +	movups	(%edx),%xmm0
        +	jnz	L007dec6_loop
        +.byte	102,15,56,222,209
        +.byte	102,15,56,222,217
        +.byte	102,15,56,222,225
        +.byte	102,15,56,222,233
        +.byte	102,15,56,222,241
        +.byte	102,15,56,222,249
        +.byte	102,15,56,223,208
        +.byte	102,15,56,223,216
        +.byte	102,15,56,223,224
        +.byte	102,15,56,223,232
        +.byte	102,15,56,223,240
        +.byte	102,15,56,223,248
        +	ret
        +.globl	_aesni_ecb_encrypt
        +.align	4
        +_aesni_ecb_encrypt:
        +L_aesni_ecb_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	andl	$-16,%eax
        +	jz	L008ecb_ret
        +	movl	240(%edx),%ecx
        +	testl	%ebx,%ebx
        +	jz	L009ecb_decrypt
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	cmpl	$96,%eax
        +	jb	L010ecb_enc_tail
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	movdqu	48(%esi),%xmm5
        +	movdqu	64(%esi),%xmm6
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +	subl	$96,%eax
        +	jmp	L011ecb_enc_loop6_enter
        +.align	4,0x90
        +L012ecb_enc_loop6:
        +	movups	%xmm2,(%edi)
        +	movdqu	(%esi),%xmm2
        +	movups	%xmm3,16(%edi)
        +	movdqu	16(%esi),%xmm3
        +	movups	%xmm4,32(%edi)
        +	movdqu	32(%esi),%xmm4
        +	movups	%xmm5,48(%edi)
        +	movdqu	48(%esi),%xmm5
        +	movups	%xmm6,64(%edi)
        +	movdqu	64(%esi),%xmm6
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +L011ecb_enc_loop6_enter:
        +	call	__aesni_encrypt6
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	subl	$96,%eax
        +	jnc	L012ecb_enc_loop6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	addl	$96,%eax
        +	jz	L008ecb_ret
        +L010ecb_enc_tail:
        +	movups	(%esi),%xmm2
        +	cmpl	$32,%eax
        +	jb	L013ecb_enc_one
        +	movups	16(%esi),%xmm3
        +	je	L014ecb_enc_two
        +	movups	32(%esi),%xmm4
        +	cmpl	$64,%eax
        +	jb	L015ecb_enc_three
        +	movups	48(%esi),%xmm5
        +	je	L016ecb_enc_four
        +	movups	64(%esi),%xmm6
        +	xorps	%xmm7,%xmm7
        +	call	__aesni_encrypt6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L013ecb_enc_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L017enc1_loop_3:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L017enc1_loop_3
        +.byte	102,15,56,221,209
        +	movups	%xmm2,(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L014ecb_enc_two:
        +	xorps	%xmm4,%xmm4
        +	call	__aesni_encrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L015ecb_enc_three:
        +	call	__aesni_encrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L016ecb_enc_four:
        +	call	__aesni_encrypt4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L009ecb_decrypt:
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	cmpl	$96,%eax
        +	jb	L018ecb_dec_tail
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	movdqu	48(%esi),%xmm5
        +	movdqu	64(%esi),%xmm6
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +	subl	$96,%eax
        +	jmp	L019ecb_dec_loop6_enter
        +.align	4,0x90
        +L020ecb_dec_loop6:
        +	movups	%xmm2,(%edi)
        +	movdqu	(%esi),%xmm2
        +	movups	%xmm3,16(%edi)
        +	movdqu	16(%esi),%xmm3
        +	movups	%xmm4,32(%edi)
        +	movdqu	32(%esi),%xmm4
        +	movups	%xmm5,48(%edi)
        +	movdqu	48(%esi),%xmm5
        +	movups	%xmm6,64(%edi)
        +	movdqu	64(%esi),%xmm6
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqu	80(%esi),%xmm7
        +	leal	96(%esi),%esi
        +L019ecb_dec_loop6_enter:
        +	call	__aesni_decrypt6
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	subl	$96,%eax
        +	jnc	L020ecb_dec_loop6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	addl	$96,%eax
        +	jz	L008ecb_ret
        +L018ecb_dec_tail:
        +	movups	(%esi),%xmm2
        +	cmpl	$32,%eax
        +	jb	L021ecb_dec_one
        +	movups	16(%esi),%xmm3
        +	je	L022ecb_dec_two
        +	movups	32(%esi),%xmm4
        +	cmpl	$64,%eax
        +	jb	L023ecb_dec_three
        +	movups	48(%esi),%xmm5
        +	je	L024ecb_dec_four
        +	movups	64(%esi),%xmm6
        +	xorps	%xmm7,%xmm7
        +	call	__aesni_decrypt6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L021ecb_dec_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L025dec1_loop_4:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L025dec1_loop_4
        +.byte	102,15,56,223,209
        +	movups	%xmm2,(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L022ecb_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	__aesni_decrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L023ecb_dec_three:
        +	call	__aesni_decrypt3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	jmp	L008ecb_ret
        +.align	4,0x90
        +L024ecb_dec_four:
        +	call	__aesni_decrypt4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +L008ecb_ret:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_aesni_ccm64_encrypt_blocks
        +.align	4
        +_aesni_ccm64_encrypt_blocks:
        +L_aesni_ccm64_encrypt_blocks_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	movl	40(%esp),%ecx
        +	movl	%esp,%ebp
        +	subl	$60,%esp
        +	andl	$-16,%esp
        +	movl	%ebp,48(%esp)
        +	movdqu	(%ebx),%xmm7
        +	movdqu	(%ecx),%xmm3
        +	movl	240(%edx),%ecx
        +	movl	$202182159,(%esp)
        +	movl	$134810123,4(%esp)
        +	movl	$67438087,8(%esp)
        +	movl	$66051,12(%esp)
        +	movl	$1,%ebx
        +	xorl	%ebp,%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ebp,20(%esp)
        +	movl	%ebp,24(%esp)
        +	movl	%ebp,28(%esp)
        +	shrl	$1,%ecx
        +	leal	(%edx),%ebp
        +	movdqa	(%esp),%xmm5
        +	movdqa	%xmm7,%xmm2
        +	movl	%ecx,%ebx
        +.byte	102,15,56,0,253
        +L026ccm64_enc_outer:
        +	movups	(%ebp),%xmm0
        +	movl	%ebx,%ecx
        +	movups	(%esi),%xmm6
        +	xorps	%xmm0,%xmm2
        +	movups	16(%ebp),%xmm1
        +	xorps	%xmm6,%xmm0
        +	leal	32(%ebp),%edx
        +	xorps	%xmm0,%xmm3
        +	movups	(%edx),%xmm0
        +L027ccm64_enc2_loop:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +.byte	102,15,56,220,217
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,216
        +	movups	(%edx),%xmm0
        +	jnz	L027ccm64_enc2_loop
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	paddq	16(%esp),%xmm7
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +	decl	%eax
        +	leal	16(%esi),%esi
        +	xorps	%xmm2,%xmm6
        +	movdqa	%xmm7,%xmm2
        +	movups	%xmm6,(%edi)
        +	leal	16(%edi),%edi
        +.byte	102,15,56,0,213
        +	jnz	L026ccm64_enc_outer
        +	movl	48(%esp),%esp
        +	movl	40(%esp),%edi
        +	movups	%xmm3,(%edi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_aesni_ccm64_decrypt_blocks
        +.align	4
        +_aesni_ccm64_decrypt_blocks:
        +L_aesni_ccm64_decrypt_blocks_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	movl	40(%esp),%ecx
        +	movl	%esp,%ebp
        +	subl	$60,%esp
        +	andl	$-16,%esp
        +	movl	%ebp,48(%esp)
        +	movdqu	(%ebx),%xmm7
        +	movdqu	(%ecx),%xmm3
        +	movl	240(%edx),%ecx
        +	movl	$202182159,(%esp)
        +	movl	$134810123,4(%esp)
        +	movl	$67438087,8(%esp)
        +	movl	$66051,12(%esp)
        +	movl	$1,%ebx
        +	xorl	%ebp,%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ebp,20(%esp)
        +	movl	%ebp,24(%esp)
        +	movl	%ebp,28(%esp)
        +	movdqa	(%esp),%xmm5
        +	movdqa	%xmm7,%xmm2
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +.byte	102,15,56,0,253
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L028enc1_loop_5:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L028enc1_loop_5
        +.byte	102,15,56,221,209
        +	movups	(%esi),%xmm6
        +	paddq	16(%esp),%xmm7
        +	leal	16(%esi),%esi
        +	jmp	L029ccm64_dec_outer
        +.align	4,0x90
        +L029ccm64_dec_outer:
        +	xorps	%xmm2,%xmm6
        +	movdqa	%xmm7,%xmm2
        +	movl	%ebx,%ecx
        +	movups	%xmm6,(%edi)
        +	leal	16(%edi),%edi
        +.byte	102,15,56,0,213
        +	subl	$1,%eax
        +	jz	L030ccm64_dec_break
        +	movups	(%ebp),%xmm0
        +	shrl	$1,%ecx
        +	movups	16(%ebp),%xmm1
        +	xorps	%xmm0,%xmm6
        +	leal	32(%ebp),%edx
        +	xorps	%xmm0,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	(%edx),%xmm0
        +L031ccm64_dec2_loop:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +.byte	102,15,56,220,217
        +	movups	16(%edx),%xmm1
        +.byte	102,15,56,220,208
        +	leal	32(%edx),%edx
        +.byte	102,15,56,220,216
        +	movups	(%edx),%xmm0
        +	jnz	L031ccm64_dec2_loop
        +	movups	(%esi),%xmm6
        +	paddq	16(%esp),%xmm7
        +.byte	102,15,56,220,209
        +.byte	102,15,56,220,217
        +	leal	16(%esi),%esi
        +.byte	102,15,56,221,208
        +.byte	102,15,56,221,216
        +	jmp	L029ccm64_dec_outer
        +.align	4,0x90
        +L030ccm64_dec_break:
        +	movl	%ebp,%edx
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	xorps	%xmm0,%xmm6
        +	leal	32(%edx),%edx
        +	xorps	%xmm6,%xmm3
        +L032enc1_loop_6:
        +.byte	102,15,56,220,217
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L032enc1_loop_6
        +.byte	102,15,56,221,217
        +	movl	48(%esp),%esp
        +	movl	40(%esp),%edi
        +	movups	%xmm3,(%edi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_aesni_ctr32_encrypt_blocks
        +.align	4
        +_aesni_ctr32_encrypt_blocks:
        +L_aesni_ctr32_encrypt_blocks_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebx
        +	movl	%esp,%ebp
        +	subl	$88,%esp
        +	andl	$-16,%esp
        +	movl	%ebp,80(%esp)
        +	cmpl	$1,%eax
        +	je	L033ctr32_one_shortcut
        +	movdqu	(%ebx),%xmm7
        +	movl	$202182159,(%esp)
        +	movl	$134810123,4(%esp)
        +	movl	$67438087,8(%esp)
        +	movl	$66051,12(%esp)
        +	movl	$6,%ecx
        +	xorl	%ebp,%ebp
        +	movl	%ecx,16(%esp)
        +	movl	%ecx,20(%esp)
        +	movl	%ecx,24(%esp)
        +	movl	%ebp,28(%esp)
        +.byte	102,15,58,22,251,3
        +.byte	102,15,58,34,253,3
        +	movl	240(%edx),%ecx
        +	bswap	%ebx
        +	pxor	%xmm1,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movdqa	(%esp),%xmm2
        +.byte	102,15,58,34,203,0
        +	leal	3(%ebx),%ebp
        +.byte	102,15,58,34,197,0
        +	incl	%ebx
        +.byte	102,15,58,34,203,1
        +	incl	%ebp
        +.byte	102,15,58,34,197,1
        +	incl	%ebx
        +.byte	102,15,58,34,203,2
        +	incl	%ebp
        +.byte	102,15,58,34,197,2
        +	movdqa	%xmm1,48(%esp)
        +.byte	102,15,56,0,202
        +	movdqa	%xmm0,64(%esp)
        +.byte	102,15,56,0,194
        +	pshufd	$192,%xmm1,%xmm2
        +	pshufd	$128,%xmm1,%xmm3
        +	cmpl	$6,%eax
        +	jb	L034ctr32_tail
        +	movdqa	%xmm7,32(%esp)
        +	shrl	$1,%ecx
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	subl	$6,%eax
        +	jmp	L035ctr32_loop6
        +.align	4,0x90
        +L035ctr32_loop6:
        +	pshufd	$64,%xmm1,%xmm4
        +	movdqa	32(%esp),%xmm1
        +	pshufd	$192,%xmm0,%xmm5
        +	por	%xmm1,%xmm2
        +	pshufd	$128,%xmm0,%xmm6
        +	por	%xmm1,%xmm3
        +	pshufd	$64,%xmm0,%xmm7
        +	por	%xmm1,%xmm4
        +	por	%xmm1,%xmm5
        +	por	%xmm1,%xmm6
        +	por	%xmm1,%xmm7
        +	movups	(%ebp),%xmm0
        +	movups	16(%ebp),%xmm1
        +	leal	32(%ebp),%edx
        +	decl	%ecx
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm0,%xmm3
        +.byte	102,15,56,220,209
        +	pxor	%xmm0,%xmm4
        +.byte	102,15,56,220,217
        +	pxor	%xmm0,%xmm5
        +.byte	102,15,56,220,225
        +	pxor	%xmm0,%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,220,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,220,249
        +	call	L_aesni_encrypt6_enter
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	%xmm1,%xmm2
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm3
        +	movups	%xmm2,(%edi)
        +	movdqa	16(%esp),%xmm0
        +	xorps	%xmm1,%xmm4
        +	movdqa	48(%esp),%xmm1
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	paddd	%xmm0,%xmm1
        +	paddd	64(%esp),%xmm0
        +	movdqa	(%esp),%xmm2
        +	movups	48(%esi),%xmm3
        +	movups	64(%esi),%xmm4
        +	xorps	%xmm3,%xmm5
        +	movups	80(%esi),%xmm3
        +	leal	96(%esi),%esi
        +	movdqa	%xmm1,48(%esp)
        +.byte	102,15,56,0,202
        +	xorps	%xmm4,%xmm6
        +	movups	%xmm5,48(%edi)
        +	xorps	%xmm3,%xmm7
        +	movdqa	%xmm0,64(%esp)
        +.byte	102,15,56,0,194
        +	movups	%xmm6,64(%edi)
        +	pshufd	$192,%xmm1,%xmm2
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movl	%ebx,%ecx
        +	pshufd	$128,%xmm1,%xmm3
        +	subl	$6,%eax
        +	jnc	L035ctr32_loop6
        +	addl	$6,%eax
        +	jz	L036ctr32_ret
        +	movl	%ebp,%edx
        +	leal	1(,%ecx,2),%ecx
        +	movdqa	32(%esp),%xmm7
        +L034ctr32_tail:
        +	por	%xmm7,%xmm2
        +	cmpl	$2,%eax
        +	jb	L037ctr32_one
        +	pshufd	$64,%xmm1,%xmm4
        +	por	%xmm7,%xmm3
        +	je	L038ctr32_two
        +	pshufd	$192,%xmm0,%xmm5
        +	por	%xmm7,%xmm4
        +	cmpl	$4,%eax
        +	jb	L039ctr32_three
        +	pshufd	$128,%xmm0,%xmm6
        +	por	%xmm7,%xmm5
        +	je	L040ctr32_four
        +	por	%xmm7,%xmm6
        +	call	__aesni_encrypt6
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	%xmm1,%xmm2
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm3
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm1,%xmm4
        +	movups	64(%esi),%xmm1
        +	xorps	%xmm0,%xmm5
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	jmp	L036ctr32_ret
        +.align	4,0x90
        +L033ctr32_one_shortcut:
        +	movups	(%ebx),%xmm2
        +	movl	240(%edx),%ecx
        +L037ctr32_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L041enc1_loop_7:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L041enc1_loop_7
        +.byte	102,15,56,221,209
        +	movups	(%esi),%xmm6
        +	xorps	%xmm2,%xmm6
        +	movups	%xmm6,(%edi)
        +	jmp	L036ctr32_ret
        +.align	4,0x90
        +L038ctr32_two:
        +	call	__aesni_encrypt3
        +	movups	(%esi),%xmm5
        +	movups	16(%esi),%xmm6
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	jmp	L036ctr32_ret
        +.align	4,0x90
        +L039ctr32_three:
        +	call	__aesni_encrypt3
        +	movups	(%esi),%xmm5
        +	movups	16(%esi),%xmm6
        +	xorps	%xmm5,%xmm2
        +	movups	32(%esi),%xmm7
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	jmp	L036ctr32_ret
        +.align	4,0x90
        +L040ctr32_four:
        +	call	__aesni_encrypt4
        +	movups	(%esi),%xmm6
        +	movups	16(%esi),%xmm7
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm6,%xmm2
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm7,%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm1,%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm0,%xmm5
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +L036ctr32_ret:
        +	movl	80(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_aesni_xts_encrypt
        +.align	4
        +_aesni_xts_encrypt:
        +L_aesni_xts_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	36(%esp),%edx
        +	movl	40(%esp),%esi
        +	movl	240(%edx),%ecx
        +	movups	(%esi),%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L042enc1_loop_8:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L042enc1_loop_8
        +.byte	102,15,56,221,209
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	%esp,%ebp
        +	subl	$120,%esp
        +	movl	240(%edx),%ecx
        +	andl	$-16,%esp
        +	movl	$135,96(%esp)
        +	movl	$0,100(%esp)
        +	movl	$1,104(%esp)
        +	movl	$0,108(%esp)
        +	movl	%eax,112(%esp)
        +	movl	%ebp,116(%esp)
        +	movdqa	%xmm2,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movdqa	96(%esp),%xmm3
        +	pcmpgtd	%xmm1,%xmm0
        +	andl	$-16,%eax
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	subl	$96,%eax
        +	jc	L043xts_enc_short
        +	shrl	$1,%ecx
        +	movl	%ecx,%ebx
        +	jmp	L044xts_enc_loop6
        +.align	4,0x90
        +L044xts_enc_loop6:
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,16(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,32(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,64(%esp)
        +	paddq	%xmm1,%xmm1
        +	movups	(%ebp),%xmm0
        +	pand	%xmm3,%xmm7
        +	movups	(%esi),%xmm2
        +	pxor	%xmm1,%xmm7
        +	movdqu	16(%esi),%xmm3
        +	xorps	%xmm0,%xmm2
        +	movdqu	32(%esi),%xmm4
        +	pxor	%xmm0,%xmm3
        +	movdqu	48(%esi),%xmm5
        +	pxor	%xmm0,%xmm4
        +	movdqu	64(%esi),%xmm6
        +	pxor	%xmm0,%xmm5
        +	movdqu	80(%esi),%xmm1
        +	pxor	%xmm0,%xmm6
        +	leal	96(%esi),%esi
        +	pxor	(%esp),%xmm2
        +	movdqa	%xmm7,80(%esp)
        +	pxor	%xmm1,%xmm7
        +	movups	16(%ebp),%xmm1
        +	leal	32(%ebp),%edx
        +	pxor	16(%esp),%xmm3
        +.byte	102,15,56,220,209
        +	pxor	32(%esp),%xmm4
        +.byte	102,15,56,220,217
        +	pxor	48(%esp),%xmm5
        +	decl	%ecx
        +.byte	102,15,56,220,225
        +	pxor	64(%esp),%xmm6
        +.byte	102,15,56,220,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,220,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,220,249
        +	call	L_aesni_encrypt6_enter
        +	movdqa	80(%esp),%xmm1
        +	pxor	%xmm0,%xmm0
        +	xorps	(%esp),%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	xorps	16(%esp),%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm4,32(%edi)
        +	xorps	64(%esp),%xmm6
        +	movups	%xmm5,48(%edi)
        +	xorps	%xmm1,%xmm7
        +	movups	%xmm6,64(%edi)
        +	pshufd	$19,%xmm0,%xmm2
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqa	96(%esp),%xmm3
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%ebx,%ecx
        +	pxor	%xmm2,%xmm1
        +	subl	$96,%eax
        +	jnc	L044xts_enc_loop6
        +	leal	1(,%ecx,2),%ecx
        +	movl	%ebp,%edx
        +	movl	%ecx,%ebx
        +L043xts_enc_short:
        +	addl	$96,%eax
        +	jz	L045xts_enc_done6x
        +	movdqa	%xmm1,%xmm5
        +	cmpl	$32,%eax
        +	jb	L046xts_enc_one
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	je	L047xts_enc_two
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm6
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	cmpl	$64,%eax
        +	jb	L048xts_enc_three
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm7
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	movdqa	%xmm5,(%esp)
        +	movdqa	%xmm6,16(%esp)
        +	je	L049xts_enc_four
        +	movdqa	%xmm7,32(%esp)
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm7
        +	pxor	%xmm1,%xmm7
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	pxor	(%esp),%xmm2
        +	movdqu	48(%esi),%xmm5
        +	pxor	16(%esp),%xmm3
        +	movdqu	64(%esi),%xmm6
        +	pxor	32(%esp),%xmm4
        +	leal	80(%esi),%esi
        +	pxor	48(%esp),%xmm5
        +	movdqa	%xmm7,64(%esp)
        +	pxor	%xmm7,%xmm6
        +	call	__aesni_encrypt6
        +	movaps	64(%esp),%xmm1
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	leal	80(%edi),%edi
        +	jmp	L050xts_enc_done
        +.align	4,0x90
        +L046xts_enc_one:
        +	movups	(%esi),%xmm2
        +	leal	16(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L051enc1_loop_9:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L051enc1_loop_9
        +.byte	102,15,56,221,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +	movdqa	%xmm5,%xmm1
        +	jmp	L050xts_enc_done
        +.align	4,0x90
        +L047xts_enc_two:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	leal	32(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm4,%xmm4
        +	call	__aesni_encrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	leal	32(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	L050xts_enc_done
        +.align	4,0x90
        +L048xts_enc_three:
        +	movaps	%xmm1,%xmm7
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	leal	48(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	call	__aesni_encrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	leal	48(%edi),%edi
        +	movdqa	%xmm7,%xmm1
        +	jmp	L050xts_enc_done
        +.align	4,0x90
        +L049xts_enc_four:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	xorps	(%esp),%xmm2
        +	movups	48(%esi),%xmm5
        +	leal	64(%esi),%esi
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	xorps	%xmm6,%xmm5
        +	call	__aesni_encrypt4
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm6,%xmm5
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	leal	64(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	L050xts_enc_done
        +.align	4,0x90
        +L045xts_enc_done6x:
        +	movl	112(%esp),%eax
        +	andl	$15,%eax
        +	jz	L052xts_enc_ret
        +	movdqa	%xmm1,%xmm5
        +	movl	%eax,112(%esp)
        +	jmp	L053xts_enc_steal
        +.align	4,0x90
        +L050xts_enc_done:
        +	movl	112(%esp),%eax
        +	pxor	%xmm0,%xmm0
        +	andl	$15,%eax
        +	jz	L052xts_enc_ret
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%eax,112(%esp)
        +	pshufd	$19,%xmm0,%xmm5
        +	paddq	%xmm1,%xmm1
        +	pand	96(%esp),%xmm5
        +	pxor	%xmm1,%xmm5
        +L053xts_enc_steal:
        +	movzbl	(%esi),%ecx
        +	movzbl	-16(%edi),%edx
        +	leal	1(%esi),%esi
        +	movb	%cl,-16(%edi)
        +	movb	%dl,(%edi)
        +	leal	1(%edi),%edi
        +	subl	$1,%eax
        +	jnz	L053xts_enc_steal
        +	subl	112(%esp),%edi
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	movups	-16(%edi),%xmm2
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L054enc1_loop_10:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L054enc1_loop_10
        +.byte	102,15,56,221,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,-16(%edi)
        +L052xts_enc_ret:
        +	movl	116(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_aesni_xts_decrypt
        +.align	4
        +_aesni_xts_decrypt:
        +L_aesni_xts_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	36(%esp),%edx
        +	movl	40(%esp),%esi
        +	movl	240(%edx),%ecx
        +	movups	(%esi),%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L055enc1_loop_11:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L055enc1_loop_11
        +.byte	102,15,56,221,209
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	32(%esp),%edx
        +	movl	%esp,%ebp
        +	subl	$120,%esp
        +	andl	$-16,%esp
        +	xorl	%ebx,%ebx
        +	testl	$15,%eax
        +	setnz	%bl
        +	shll	$4,%ebx
        +	subl	%ebx,%eax
        +	movl	$135,96(%esp)
        +	movl	$0,100(%esp)
        +	movl	$1,104(%esp)
        +	movl	$0,108(%esp)
        +	movl	%eax,112(%esp)
        +	movl	%ebp,116(%esp)
        +	movl	240(%edx),%ecx
        +	movl	%edx,%ebp
        +	movl	%ecx,%ebx
        +	movdqa	%xmm2,%xmm1
        +	pxor	%xmm0,%xmm0
        +	movdqa	96(%esp),%xmm3
        +	pcmpgtd	%xmm1,%xmm0
        +	andl	$-16,%eax
        +	subl	$96,%eax
        +	jc	L056xts_dec_short
        +	shrl	$1,%ecx
        +	movl	%ecx,%ebx
        +	jmp	L057xts_dec_loop6
        +.align	4,0x90
        +L057xts_dec_loop6:
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,16(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,32(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,64(%esp)
        +	paddq	%xmm1,%xmm1
        +	movups	(%ebp),%xmm0
        +	pand	%xmm3,%xmm7
        +	movups	(%esi),%xmm2
        +	pxor	%xmm1,%xmm7
        +	movdqu	16(%esi),%xmm3
        +	xorps	%xmm0,%xmm2
        +	movdqu	32(%esi),%xmm4
        +	pxor	%xmm0,%xmm3
        +	movdqu	48(%esi),%xmm5
        +	pxor	%xmm0,%xmm4
        +	movdqu	64(%esi),%xmm6
        +	pxor	%xmm0,%xmm5
        +	movdqu	80(%esi),%xmm1
        +	pxor	%xmm0,%xmm6
        +	leal	96(%esi),%esi
        +	pxor	(%esp),%xmm2
        +	movdqa	%xmm7,80(%esp)
        +	pxor	%xmm1,%xmm7
        +	movups	16(%ebp),%xmm1
        +	leal	32(%ebp),%edx
        +	pxor	16(%esp),%xmm3
        +.byte	102,15,56,222,209
        +	pxor	32(%esp),%xmm4
        +.byte	102,15,56,222,217
        +	pxor	48(%esp),%xmm5
        +	decl	%ecx
        +.byte	102,15,56,222,225
        +	pxor	64(%esp),%xmm6
        +.byte	102,15,56,222,233
        +	pxor	%xmm0,%xmm7
        +.byte	102,15,56,222,241
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,222,249
        +	call	L_aesni_decrypt6_enter
        +	movdqa	80(%esp),%xmm1
        +	pxor	%xmm0,%xmm0
        +	xorps	(%esp),%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	xorps	16(%esp),%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm4,32(%edi)
        +	xorps	64(%esp),%xmm6
        +	movups	%xmm5,48(%edi)
        +	xorps	%xmm1,%xmm7
        +	movups	%xmm6,64(%edi)
        +	pshufd	$19,%xmm0,%xmm2
        +	movups	%xmm7,80(%edi)
        +	leal	96(%edi),%edi
        +	movdqa	96(%esp),%xmm3
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%ebx,%ecx
        +	pxor	%xmm2,%xmm1
        +	subl	$96,%eax
        +	jnc	L057xts_dec_loop6
        +	leal	1(,%ecx,2),%ecx
        +	movl	%ebp,%edx
        +	movl	%ecx,%ebx
        +L056xts_dec_short:
        +	addl	$96,%eax
        +	jz	L058xts_dec_done6x
        +	movdqa	%xmm1,%xmm5
        +	cmpl	$32,%eax
        +	jb	L059xts_dec_one
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	je	L060xts_dec_two
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm6
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	cmpl	$64,%eax
        +	jb	L061xts_dec_three
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	%xmm1,%xmm7
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +	movdqa	%xmm5,(%esp)
        +	movdqa	%xmm6,16(%esp)
        +	je	L062xts_dec_four
        +	movdqa	%xmm7,32(%esp)
        +	pshufd	$19,%xmm0,%xmm7
        +	movdqa	%xmm1,48(%esp)
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm7
        +	pxor	%xmm1,%xmm7
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	pxor	(%esp),%xmm2
        +	movdqu	48(%esi),%xmm5
        +	pxor	16(%esp),%xmm3
        +	movdqu	64(%esi),%xmm6
        +	pxor	32(%esp),%xmm4
        +	leal	80(%esi),%esi
        +	pxor	48(%esp),%xmm5
        +	movdqa	%xmm7,64(%esp)
        +	pxor	%xmm7,%xmm6
        +	call	__aesni_decrypt6
        +	movaps	64(%esp),%xmm1
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	32(%esp),%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	48(%esp),%xmm5
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm1,%xmm6
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	movups	%xmm6,64(%edi)
        +	leal	80(%edi),%edi
        +	jmp	L063xts_dec_done
        +.align	4,0x90
        +L059xts_dec_one:
        +	movups	(%esi),%xmm2
        +	leal	16(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L064dec1_loop_12:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L064dec1_loop_12
        +.byte	102,15,56,223,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +	movdqa	%xmm5,%xmm1
        +	jmp	L063xts_dec_done
        +.align	4,0x90
        +L060xts_dec_two:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	leal	32(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	call	__aesni_decrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	leal	32(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	L063xts_dec_done
        +.align	4,0x90
        +L061xts_dec_three:
        +	movaps	%xmm1,%xmm7
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	leal	48(%esi),%esi
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	call	__aesni_decrypt3
        +	xorps	%xmm5,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	leal	48(%edi),%edi
        +	movdqa	%xmm7,%xmm1
        +	jmp	L063xts_dec_done
        +.align	4,0x90
        +L062xts_dec_four:
        +	movaps	%xmm1,%xmm6
        +	movups	(%esi),%xmm2
        +	movups	16(%esi),%xmm3
        +	movups	32(%esi),%xmm4
        +	xorps	(%esp),%xmm2
        +	movups	48(%esi),%xmm5
        +	leal	64(%esi),%esi
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	xorps	%xmm6,%xmm5
        +	call	__aesni_decrypt4
        +	xorps	(%esp),%xmm2
        +	xorps	16(%esp),%xmm3
        +	xorps	%xmm7,%xmm4
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm6,%xmm5
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	leal	64(%edi),%edi
        +	movdqa	%xmm6,%xmm1
        +	jmp	L063xts_dec_done
        +.align	4,0x90
        +L058xts_dec_done6x:
        +	movl	112(%esp),%eax
        +	andl	$15,%eax
        +	jz	L065xts_dec_ret
        +	movl	%eax,112(%esp)
        +	jmp	L066xts_dec_only_one_more
        +.align	4,0x90
        +L063xts_dec_done:
        +	movl	112(%esp),%eax
        +	pxor	%xmm0,%xmm0
        +	andl	$15,%eax
        +	jz	L065xts_dec_ret
        +	pcmpgtd	%xmm1,%xmm0
        +	movl	%eax,112(%esp)
        +	pshufd	$19,%xmm0,%xmm2
        +	pxor	%xmm0,%xmm0
        +	movdqa	96(%esp),%xmm3
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm2
        +	pcmpgtd	%xmm1,%xmm0
        +	pxor	%xmm2,%xmm1
        +L066xts_dec_only_one_more:
        +	pshufd	$19,%xmm0,%xmm5
        +	movdqa	%xmm1,%xmm6
        +	paddq	%xmm1,%xmm1
        +	pand	%xmm3,%xmm5
        +	pxor	%xmm1,%xmm5
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	movups	(%esi),%xmm2
        +	xorps	%xmm5,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L067dec1_loop_13:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L067dec1_loop_13
        +.byte	102,15,56,223,209
        +	xorps	%xmm5,%xmm2
        +	movups	%xmm2,(%edi)
        +L068xts_dec_steal:
        +	movzbl	16(%esi),%ecx
        +	movzbl	(%edi),%edx
        +	leal	1(%esi),%esi
        +	movb	%cl,(%edi)
        +	movb	%dl,16(%edi)
        +	leal	1(%edi),%edi
        +	subl	$1,%eax
        +	jnz	L068xts_dec_steal
        +	subl	112(%esp),%edi
        +	movl	%ebp,%edx
        +	movl	%ebx,%ecx
        +	movups	(%edi),%xmm2
        +	xorps	%xmm6,%xmm2
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L069dec1_loop_14:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L069dec1_loop_14
        +.byte	102,15,56,223,209
        +	xorps	%xmm6,%xmm2
        +	movups	%xmm2,(%edi)
        +L065xts_dec_ret:
        +	movl	116(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_aesni_cbc_encrypt
        +.align	4
        +_aesni_cbc_encrypt:
        +L_aesni_cbc_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	%esp,%ebx
        +	movl	24(%esp),%edi
        +	subl	$24,%ebx
        +	movl	28(%esp),%eax
        +	andl	$-16,%ebx
        +	movl	32(%esp),%edx
        +	movl	36(%esp),%ebp
        +	testl	%eax,%eax
        +	jz	L070cbc_abort
        +	cmpl	$0,40(%esp)
        +	xchgl	%esp,%ebx
        +	movups	(%ebp),%xmm7
        +	movl	240(%edx),%ecx
        +	movl	%edx,%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ecx,%ebx
        +	je	L071cbc_decrypt
        +	movaps	%xmm7,%xmm2
        +	cmpl	$16,%eax
        +	jb	L072cbc_enc_tail
        +	subl	$16,%eax
        +	jmp	L073cbc_enc_loop
        +.align	4,0x90
        +L073cbc_enc_loop:
        +	movups	(%esi),%xmm7
        +	leal	16(%esi),%esi
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	xorps	%xmm0,%xmm7
        +	leal	32(%edx),%edx
        +	xorps	%xmm7,%xmm2
        +L074enc1_loop_15:
        +.byte	102,15,56,220,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L074enc1_loop_15
        +.byte	102,15,56,221,209
        +	movl	%ebx,%ecx
        +	movl	%ebp,%edx
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +	subl	$16,%eax
        +	jnc	L073cbc_enc_loop
        +	addl	$16,%eax
        +	jnz	L072cbc_enc_tail
        +	movaps	%xmm2,%xmm7
        +	jmp	L075cbc_ret
        +L072cbc_enc_tail:
        +	movl	%eax,%ecx
        +.long	2767451785
        +	movl	$16,%ecx
        +	subl	%eax,%ecx
        +	xorl	%eax,%eax
        +.long	2868115081
        +	leal	-16(%edi),%edi
        +	movl	%ebx,%ecx
        +	movl	%edi,%esi
        +	movl	%ebp,%edx
        +	jmp	L073cbc_enc_loop
        +.align	4,0x90
        +L071cbc_decrypt:
        +	cmpl	$80,%eax
        +	jbe	L076cbc_dec_tail
        +	movaps	%xmm7,(%esp)
        +	subl	$80,%eax
        +	jmp	L077cbc_dec_loop6_enter
        +.align	4,0x90
        +L078cbc_dec_loop6:
        +	movaps	%xmm0,(%esp)
        +	movups	%xmm7,(%edi)
        +	leal	16(%edi),%edi
        +L077cbc_dec_loop6_enter:
        +	movdqu	(%esi),%xmm2
        +	movdqu	16(%esi),%xmm3
        +	movdqu	32(%esi),%xmm4
        +	movdqu	48(%esi),%xmm5
        +	movdqu	64(%esi),%xmm6
        +	movdqu	80(%esi),%xmm7
        +	call	__aesni_decrypt6
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	(%esp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%esi),%xmm1
        +	xorps	%xmm0,%xmm6
        +	movups	80(%esi),%xmm0
        +	xorps	%xmm1,%xmm7
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	leal	96(%esi),%esi
        +	movups	%xmm4,32(%edi)
        +	movl	%ebx,%ecx
        +	movups	%xmm5,48(%edi)
        +	movl	%ebp,%edx
        +	movups	%xmm6,64(%edi)
        +	leal	80(%edi),%edi
        +	subl	$96,%eax
        +	ja	L078cbc_dec_loop6
        +	movaps	%xmm7,%xmm2
        +	movaps	%xmm0,%xmm7
        +	addl	$80,%eax
        +	jle	L079cbc_dec_tail_collected
        +	movups	%xmm2,(%edi)
        +	leal	16(%edi),%edi
        +L076cbc_dec_tail:
        +	movups	(%esi),%xmm2
        +	movaps	%xmm2,%xmm6
        +	cmpl	$16,%eax
        +	jbe	L080cbc_dec_one
        +	movups	16(%esi),%xmm3
        +	movaps	%xmm3,%xmm5
        +	cmpl	$32,%eax
        +	jbe	L081cbc_dec_two
        +	movups	32(%esi),%xmm4
        +	cmpl	$48,%eax
        +	jbe	L082cbc_dec_three
        +	movups	48(%esi),%xmm5
        +	cmpl	$64,%eax
        +	jbe	L083cbc_dec_four
        +	movups	64(%esi),%xmm6
        +	movaps	%xmm7,(%esp)
        +	movups	(%esi),%xmm2
        +	xorps	%xmm7,%xmm7
        +	call	__aesni_decrypt6
        +	movups	(%esi),%xmm1
        +	movups	16(%esi),%xmm0
        +	xorps	(%esp),%xmm2
        +	xorps	%xmm1,%xmm3
        +	movups	32(%esi),%xmm1
        +	xorps	%xmm0,%xmm4
        +	movups	48(%esi),%xmm0
        +	xorps	%xmm1,%xmm5
        +	movups	64(%esi),%xmm7
        +	xorps	%xmm0,%xmm6
        +	movups	%xmm2,(%edi)
        +	movups	%xmm3,16(%edi)
        +	movups	%xmm4,32(%edi)
        +	movups	%xmm5,48(%edi)
        +	leal	64(%edi),%edi
        +	movaps	%xmm6,%xmm2
        +	subl	$80,%eax
        +	jmp	L079cbc_dec_tail_collected
        +.align	4,0x90
        +L080cbc_dec_one:
        +	movups	(%edx),%xmm0
        +	movups	16(%edx),%xmm1
        +	leal	32(%edx),%edx
        +	xorps	%xmm0,%xmm2
        +L084dec1_loop_16:
        +.byte	102,15,56,222,209
        +	decl	%ecx
        +	movups	(%edx),%xmm1
        +	leal	16(%edx),%edx
        +	jnz	L084dec1_loop_16
        +.byte	102,15,56,223,209
        +	xorps	%xmm7,%xmm2
        +	movaps	%xmm6,%xmm7
        +	subl	$16,%eax
        +	jmp	L079cbc_dec_tail_collected
        +.align	4,0x90
        +L081cbc_dec_two:
        +	xorps	%xmm4,%xmm4
        +	call	__aesni_decrypt3
        +	xorps	%xmm7,%xmm2
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	movaps	%xmm3,%xmm2
        +	leal	16(%edi),%edi
        +	movaps	%xmm5,%xmm7
        +	subl	$32,%eax
        +	jmp	L079cbc_dec_tail_collected
        +.align	4,0x90
        +L082cbc_dec_three:
        +	call	__aesni_decrypt3
        +	xorps	%xmm7,%xmm2
        +	xorps	%xmm6,%xmm3
        +	xorps	%xmm5,%xmm4
        +	movups	%xmm2,(%edi)
        +	movaps	%xmm4,%xmm2
        +	movups	%xmm3,16(%edi)
        +	leal	32(%edi),%edi
        +	movups	32(%esi),%xmm7
        +	subl	$48,%eax
        +	jmp	L079cbc_dec_tail_collected
        +.align	4,0x90
        +L083cbc_dec_four:
        +	call	__aesni_decrypt4
        +	movups	16(%esi),%xmm1
        +	movups	32(%esi),%xmm0
        +	xorps	%xmm7,%xmm2
        +	movups	48(%esi),%xmm7
        +	xorps	%xmm6,%xmm3
        +	movups	%xmm2,(%edi)
        +	xorps	%xmm1,%xmm4
        +	movups	%xmm3,16(%edi)
        +	xorps	%xmm0,%xmm5
        +	movups	%xmm4,32(%edi)
        +	leal	48(%edi),%edi
        +	movaps	%xmm5,%xmm2
        +	subl	$64,%eax
        +L079cbc_dec_tail_collected:
        +	andl	$15,%eax
        +	jnz	L085cbc_dec_tail_partial
        +	movups	%xmm2,(%edi)
        +	jmp	L075cbc_ret
        +.align	4,0x90
        +L085cbc_dec_tail_partial:
        +	movaps	%xmm2,(%esp)
        +	movl	$16,%ecx
        +	movl	%esp,%esi
        +	subl	%eax,%ecx
        +.long	2767451785
        +L075cbc_ret:
        +	movl	16(%esp),%esp
        +	movl	36(%esp),%ebp
        +	movups	%xmm7,(%ebp)
        +L070cbc_abort:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4
        +__aesni_set_encrypt_key:
        +	testl	%eax,%eax
        +	jz	L086bad_pointer
        +	testl	%edx,%edx
        +	jz	L086bad_pointer
        +	movups	(%eax),%xmm0
        +	xorps	%xmm4,%xmm4
        +	leal	16(%edx),%edx
        +	cmpl	$256,%ecx
        +	je	L08714rounds
        +	cmpl	$192,%ecx
        +	je	L08812rounds
        +	cmpl	$128,%ecx
        +	jne	L089bad_keybits
        +.align	4,0x90
        +L09010rounds:
        +	movl	$9,%ecx
        +	movups	%xmm0,-16(%edx)
        +.byte	102,15,58,223,200,1
        +	call	L091key_128_cold
        +.byte	102,15,58,223,200,2
        +	call	L092key_128
        +.byte	102,15,58,223,200,4
        +	call	L092key_128
        +.byte	102,15,58,223,200,8
        +	call	L092key_128
        +.byte	102,15,58,223,200,16
        +	call	L092key_128
        +.byte	102,15,58,223,200,32
        +	call	L092key_128
        +.byte	102,15,58,223,200,64
        +	call	L092key_128
        +.byte	102,15,58,223,200,128
        +	call	L092key_128
        +.byte	102,15,58,223,200,27
        +	call	L092key_128
        +.byte	102,15,58,223,200,54
        +	call	L092key_128
        +	movups	%xmm0,(%edx)
        +	movl	%ecx,80(%edx)
        +	xorl	%eax,%eax
        +	ret
        +.align	4,0x90
        +L092key_128:
        +	movups	%xmm0,(%edx)
        +	leal	16(%edx),%edx
        +L091key_128_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	ret
        +.align	4,0x90
        +L08812rounds:
        +	movq	16(%eax),%xmm2
        +	movl	$11,%ecx
        +	movups	%xmm0,-16(%edx)
        +.byte	102,15,58,223,202,1
        +	call	L093key_192a_cold
        +.byte	102,15,58,223,202,2
        +	call	L094key_192b
        +.byte	102,15,58,223,202,4
        +	call	L095key_192a
        +.byte	102,15,58,223,202,8
        +	call	L094key_192b
        +.byte	102,15,58,223,202,16
        +	call	L095key_192a
        +.byte	102,15,58,223,202,32
        +	call	L094key_192b
        +.byte	102,15,58,223,202,64
        +	call	L095key_192a
        +.byte	102,15,58,223,202,128
        +	call	L094key_192b
        +	movups	%xmm0,(%edx)
        +	movl	%ecx,48(%edx)
        +	xorl	%eax,%eax
        +	ret
        +.align	4,0x90
        +L095key_192a:
        +	movups	%xmm0,(%edx)
        +	leal	16(%edx),%edx
        +.align	4,0x90
        +L093key_192a_cold:
        +	movaps	%xmm2,%xmm5
        +L096key_192b_warm:
        +	shufps	$16,%xmm0,%xmm4
        +	movdqa	%xmm2,%xmm3
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	pslldq	$4,%xmm3
        +	xorps	%xmm4,%xmm0
        +	pshufd	$85,%xmm1,%xmm1
        +	pxor	%xmm3,%xmm2
        +	pxor	%xmm1,%xmm0
        +	pshufd	$255,%xmm0,%xmm3
        +	pxor	%xmm3,%xmm2
        +	ret
        +.align	4,0x90
        +L094key_192b:
        +	movaps	%xmm0,%xmm3
        +	shufps	$68,%xmm0,%xmm5
        +	movups	%xmm5,(%edx)
        +	shufps	$78,%xmm2,%xmm3
        +	movups	%xmm3,16(%edx)
        +	leal	32(%edx),%edx
        +	jmp	L096key_192b_warm
        +.align	4,0x90
        +L08714rounds:
        +	movups	16(%eax),%xmm2
        +	movl	$13,%ecx
        +	leal	16(%edx),%edx
        +	movups	%xmm0,-32(%edx)
        +	movups	%xmm2,-16(%edx)
        +.byte	102,15,58,223,202,1
        +	call	L097key_256a_cold
        +.byte	102,15,58,223,200,1
        +	call	L098key_256b
        +.byte	102,15,58,223,202,2
        +	call	L099key_256a
        +.byte	102,15,58,223,200,2
        +	call	L098key_256b
        +.byte	102,15,58,223,202,4
        +	call	L099key_256a
        +.byte	102,15,58,223,200,4
        +	call	L098key_256b
        +.byte	102,15,58,223,202,8
        +	call	L099key_256a
        +.byte	102,15,58,223,200,8
        +	call	L098key_256b
        +.byte	102,15,58,223,202,16
        +	call	L099key_256a
        +.byte	102,15,58,223,200,16
        +	call	L098key_256b
        +.byte	102,15,58,223,202,32
        +	call	L099key_256a
        +.byte	102,15,58,223,200,32
        +	call	L098key_256b
        +.byte	102,15,58,223,202,64
        +	call	L099key_256a
        +	movups	%xmm0,(%edx)
        +	movl	%ecx,16(%edx)
        +	xorl	%eax,%eax
        +	ret
        +.align	4,0x90
        +L099key_256a:
        +	movups	%xmm2,(%edx)
        +	leal	16(%edx),%edx
        +L097key_256a_cold:
        +	shufps	$16,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$140,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	$255,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm0
        +	ret
        +.align	4,0x90
        +L098key_256b:
        +	movups	%xmm0,(%edx)
        +	leal	16(%edx),%edx
        +	shufps	$16,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$140,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	$170,%xmm1,%xmm1
        +	xorps	%xmm1,%xmm2
        +	ret
        +.align	2,0x90
        +L086bad_pointer:
        +	movl	$-1,%eax
        +	ret
        +.align	2,0x90
        +L089bad_keybits:
        +	movl	$-2,%eax
        +	ret
        +.globl	_aesni_set_encrypt_key
        +.align	4
        +_aesni_set_encrypt_key:
        +L_aesni_set_encrypt_key_begin:
        +	movl	4(%esp),%eax
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	call	__aesni_set_encrypt_key
        +	ret
        +.globl	_aesni_set_decrypt_key
        +.align	4
        +_aesni_set_decrypt_key:
        +L_aesni_set_decrypt_key_begin:
        +	movl	4(%esp),%eax
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	call	__aesni_set_encrypt_key
        +	movl	12(%esp),%edx
        +	shll	$4,%ecx
        +	testl	%eax,%eax
        +	jnz	L100dec_key_ret
        +	leal	16(%edx,%ecx,1),%eax
        +	movups	(%edx),%xmm0
        +	movups	(%eax),%xmm1
        +	movups	%xmm0,(%eax)
        +	movups	%xmm1,(%edx)
        +	leal	16(%edx),%edx
        +	leal	-16(%eax),%eax
        +L101dec_key_inverse:
        +	movups	(%edx),%xmm0
        +	movups	(%eax),%xmm1
        +.byte	102,15,56,219,192
        +.byte	102,15,56,219,201
        +	leal	16(%edx),%edx
        +	leal	-16(%eax),%eax
        +	movups	%xmm0,16(%eax)
        +	movups	%xmm1,-16(%edx)
        +	cmpl	%edx,%eax
        +	ja	L101dec_key_inverse
        +	movups	(%edx),%xmm0
        +.byte	102,15,56,219,192
        +	movups	%xmm0,(%edx)
        +	xorl	%eax,%eax
        +L100dec_key_ret:
        +	ret
        +.byte	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
        +.byte	83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
        +.byte	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +.byte	115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/bf/bf-686.s b/vendor/openssl/asm/x86-macosx-gas/bf/bf-686.s
        new file mode 100644
        index 000000000..013d2dec8
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/bf/bf-686.s
        @@ -0,0 +1,897 @@
        +.file	"bf-686.s"
        +.text
        +.globl	_BF_encrypt
        +.align	4
        +_BF_encrypt:
        +L_BF_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the 2 words
        +
        +	movl	20(%esp),%eax
        +	movl	(%eax),%ecx
        +	movl	4(%eax),%edx
        +
        +	# P pointer, s and enc flag
        +
        +	movl	24(%esp),%edi
        +	xorl	%eax,%eax
        +	xorl	%ebx,%ebx
        +	xorl	(%edi),%ecx
        +
        +	# Round 0
        +
        +	rorl	$16,%ecx
        +	movl	4(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 1
        +
        +	rorl	$16,%edx
        +	movl	8(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 2
        +
        +	rorl	$16,%ecx
        +	movl	12(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 3
        +
        +	rorl	$16,%edx
        +	movl	16(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 4
        +
        +	rorl	$16,%ecx
        +	movl	20(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 5
        +
        +	rorl	$16,%edx
        +	movl	24(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 6
        +
        +	rorl	$16,%ecx
        +	movl	28(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 7
        +
        +	rorl	$16,%edx
        +	movl	32(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 8
        +
        +	rorl	$16,%ecx
        +	movl	36(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 9
        +
        +	rorl	$16,%edx
        +	movl	40(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 10
        +
        +	rorl	$16,%ecx
        +	movl	44(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 11
        +
        +	rorl	$16,%edx
        +	movl	48(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 12
        +
        +	rorl	$16,%ecx
        +	movl	52(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 13
        +
        +	rorl	$16,%edx
        +	movl	56(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 14
        +
        +	rorl	$16,%ecx
        +	movl	60(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 15
        +
        +	rorl	$16,%edx
        +	movl	64(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +	xorl	68(%edi),%edx
        +	movl	20(%esp),%eax
        +	movl	%edx,(%eax)
        +	movl	%ecx,4(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_BF_decrypt
        +.align	4
        +_BF_decrypt:
        +L_BF_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the 2 words
        +
        +	movl	20(%esp),%eax
        +	movl	(%eax),%ecx
        +	movl	4(%eax),%edx
        +
        +	# P pointer, s and enc flag
        +
        +	movl	24(%esp),%edi
        +	xorl	%eax,%eax
        +	xorl	%ebx,%ebx
        +	xorl	68(%edi),%ecx
        +
        +	# Round 16
        +
        +	rorl	$16,%ecx
        +	movl	64(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 15
        +
        +	rorl	$16,%edx
        +	movl	60(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 14
        +
        +	rorl	$16,%ecx
        +	movl	56(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 13
        +
        +	rorl	$16,%edx
        +	movl	52(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 12
        +
        +	rorl	$16,%ecx
        +	movl	48(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 11
        +
        +	rorl	$16,%edx
        +	movl	44(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 10
        +
        +	rorl	$16,%ecx
        +	movl	40(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 9
        +
        +	rorl	$16,%edx
        +	movl	36(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 8
        +
        +	rorl	$16,%ecx
        +	movl	32(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 7
        +
        +	rorl	$16,%edx
        +	movl	28(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 6
        +
        +	rorl	$16,%ecx
        +	movl	24(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 5
        +
        +	rorl	$16,%edx
        +	movl	20(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 4
        +
        +	rorl	$16,%ecx
        +	movl	16(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 3
        +
        +	rorl	$16,%edx
        +	movl	12(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +
        +	# Round 2
        +
        +	rorl	$16,%ecx
        +	movl	8(%edi),%esi
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	rorl	$16,%ecx
        +	xorl	%esi,%edx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%ch,%al
        +	movb	%cl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%edx
        +
        +	# Round 1
        +
        +	rorl	$16,%edx
        +	movl	4(%edi),%esi
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	rorl	$16,%edx
        +	xorl	%esi,%ecx
        +	movl	72(%edi,%eax,4),%esi
        +	movl	1096(%edi,%ebx,4),%ebp
        +	movb	%dh,%al
        +	movb	%dl,%bl
        +	addl	%ebp,%esi
        +	movl	2120(%edi,%eax,4),%eax
        +	xorl	%eax,%esi
        +	movl	3144(%edi,%ebx,4),%ebp
        +	addl	%ebp,%esi
        +	xorl	%eax,%eax
        +	xorl	%esi,%ecx
        +	xorl	(%edi),%edx
        +	movl	20(%esp),%eax
        +	movl	%edx,(%eax)
        +	movl	%ecx,4(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_BF_cbc_encrypt
        +.align	4
        +_BF_cbc_encrypt:
        +L_BF_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +	# getting iv ptr from parameter 4
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +	# getting encrypt flag from parameter 5
        +
        +	movl	56(%esp),%ecx
        +	# get and push parameter 3
        +
        +	movl	48(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	L000decrypt
        +	andl	$4294967288,%ebp
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	jz	L001encrypt_finish
        +L002encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_BF_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L002encrypt_loop
        +L001encrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L003finish
        +	call	L004PIC_point
        +L004PIC_point:
        +	popl	%edx
        +	leal	L005cbc_enc_jmp_table-L004PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +L006ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +L007ej6:
        +	movb	5(%esi),%dh
        +L008ej5:
        +	movb	4(%esi),%dl
        +L009ej4:
        +	movl	(%esi),%ecx
        +	jmp	L010ejend
        +L011ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +L012ej2:
        +	movb	1(%esi),%ch
        +L013ej1:
        +	movb	(%esi),%cl
        +L010ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_BF_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	L003finish
        +L000decrypt:
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	L014decrypt_finish
        +L015decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_BF_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L015decrypt_loop
        +L014decrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L003finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_BF_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +L016dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +L017dj6:
        +	movb	%dh,5(%edi)
        +L018dj5:
        +	movb	%dl,4(%edi)
        +L019dj4:
        +	movl	%ecx,(%edi)
        +	jmp	L020djend
        +L021dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +L022dj2:
        +	movb	%ch,1(%esi)
        +L023dj1:
        +	movb	%cl,(%esi)
        +L020djend:
        +	jmp	L003finish
        +L003finish:
        +	movl	60(%esp),%ecx
        +	addl	$24,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L005cbc_enc_jmp_table:
        +.long	0
        +.long	L013ej1-L004PIC_point
        +.long	L012ej2-L004PIC_point
        +.long	L011ej3-L004PIC_point
        +.long	L009ej4-L004PIC_point
        +.long	L008ej5-L004PIC_point
        +.long	L007ej6-L004PIC_point
        +.long	L006ej7-L004PIC_point
        +.align	6,0x90
        diff --git a/vendor/openssl/asm/x86-macosx-gas/bn/x86-mont.s b/vendor/openssl/asm/x86-macosx-gas/bn/x86-mont.s
        new file mode 100644
        index 000000000..48598cc62
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/bn/x86-mont.s
        @@ -0,0 +1,336 @@
        +.file	"../openssl/crypto/bn/asm/x86-mont.s"
        +.text
        +.globl	_bn_mul_mont
        +.align	4
        +_bn_mul_mont:
        +L_bn_mul_mont_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	xorl	%eax,%eax
        +	movl	40(%esp),%edi
        +	cmpl	$4,%edi
        +	jl	L000just_leave
        +	leal	20(%esp),%esi
        +	leal	24(%esp),%edx
        +	movl	%esp,%ebp
        +	addl	$2,%edi
        +	negl	%edi
        +	leal	-32(%esp,%edi,4),%esp
        +	negl	%edi
        +	movl	%esp,%eax
        +	subl	%edx,%eax
        +	andl	$2047,%eax
        +	subl	%eax,%esp
        +	xorl	%esp,%edx
        +	andl	$2048,%edx
        +	xorl	$2048,%edx
        +	subl	%edx,%esp
        +	andl	$-64,%esp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	16(%esi),%esi
        +	movl	(%esi),%esi
        +	movl	%eax,4(%esp)
        +	movl	%ebx,8(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edx,16(%esp)
        +	movl	%esi,20(%esp)
        +	leal	-3(%edi),%ebx
        +	movl	%ebp,24(%esp)
        +	movl	8(%esp),%esi
        +	leal	1(%ebx),%ebp
        +	movl	12(%esp),%edi
        +	xorl	%ecx,%ecx
        +	movl	%esi,%edx
        +	andl	$1,%ebp
        +	subl	%edi,%edx
        +	leal	4(%edi,%ebx,4),%eax
        +	orl	%edx,%ebp
        +	movl	(%edi),%edi
        +	jz	L001bn_sqr_mont
        +	movl	%eax,28(%esp)
        +	movl	(%esi),%eax
        +	xorl	%edx,%edx
        +.align	4,0x90
        +L002mull:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%eax,%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	movl	(%esi,%ecx,4),%eax
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	jl	L002mull
        +	movl	%edx,%ebp
        +	mull	%edi
        +	movl	20(%esp),%edi
        +	addl	%ebp,%eax
        +	movl	16(%esp),%esi
        +	adcl	$0,%edx
        +	imull	32(%esp),%edi
        +	movl	%eax,32(%esp,%ebx,4)
        +	xorl	%ecx,%ecx
        +	movl	%edx,36(%esp,%ebx,4)
        +	movl	%ecx,40(%esp,%ebx,4)
        +	movl	(%esi),%eax
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	movl	4(%esi),%eax
        +	adcl	$0,%edx
        +	incl	%ecx
        +	jmp	L0032ndmadd
        +.align	4,0x90
        +L0041stmadd:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	jl	L0041stmadd
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ebx,4),%eax
        +	movl	20(%esp),%edi
        +	adcl	$0,%edx
        +	movl	16(%esp),%esi
        +	addl	%eax,%ebp
        +	adcl	$0,%edx
        +	imull	32(%esp),%edi
        +	xorl	%ecx,%ecx
        +	addl	36(%esp,%ebx,4),%edx
        +	movl	%ebp,32(%esp,%ebx,4)
        +	adcl	$0,%ecx
        +	movl	(%esi),%eax
        +	movl	%edx,36(%esp,%ebx,4)
        +	movl	%ecx,40(%esp,%ebx,4)
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	movl	4(%esi),%eax
        +	adcl	$0,%edx
        +	movl	$1,%ecx
        +.align	4,0x90
        +L0032ndmadd:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,24(%esp,%ecx,4)
        +	jl	L0032ndmadd
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ebx,4),%ebp
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	adcl	$0,%edx
        +	movl	%ebp,28(%esp,%ebx,4)
        +	xorl	%eax,%eax
        +	movl	12(%esp),%ecx
        +	addl	36(%esp,%ebx,4),%edx
        +	adcl	40(%esp,%ebx,4),%eax
        +	leal	4(%ecx),%ecx
        +	movl	%edx,32(%esp,%ebx,4)
        +	cmpl	28(%esp),%ecx
        +	movl	%eax,36(%esp,%ebx,4)
        +	je	L005common_tail
        +	movl	(%ecx),%edi
        +	movl	8(%esp),%esi
        +	movl	%ecx,12(%esp)
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	movl	(%esi),%eax
        +	jmp	L0041stmadd
        +.align	4,0x90
        +L001bn_sqr_mont:
        +	movl	%ebx,(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edi,%eax
        +	mull	%edi
        +	movl	%eax,32(%esp)
        +	movl	%edx,%ebx
        +	shrl	$1,%edx
        +	andl	$1,%ebx
        +	incl	%ecx
        +.align	4,0x90
        +L006sqr:
        +	movl	(%esi,%ecx,4),%eax
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%ebp,%eax
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%edx
        +	leal	(%ebx,%eax,2),%ebp
        +	shrl	$31,%eax
        +	cmpl	(%esp),%ecx
        +	movl	%eax,%ebx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	jl	L006sqr
        +	movl	(%esi,%ecx,4),%eax
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%ebp,%eax
        +	movl	20(%esp),%edi
        +	adcl	$0,%edx
        +	movl	16(%esp),%esi
        +	leal	(%ebx,%eax,2),%ebp
        +	imull	32(%esp),%edi
        +	shrl	$31,%eax
        +	movl	%ebp,32(%esp,%ecx,4)
        +	leal	(%eax,%edx,2),%ebp
        +	movl	(%esi),%eax
        +	shrl	$31,%edx
        +	movl	%ebp,36(%esp,%ecx,4)
        +	movl	%edx,40(%esp,%ecx,4)
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	movl	%ecx,%ebx
        +	adcl	$0,%edx
        +	movl	4(%esi),%eax
        +	movl	$1,%ecx
        +.align	4,0x90
        +L0073rdmadd:
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%ebp
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	36(%esp,%ecx,4),%ebp
        +	leal	2(%ecx),%ecx
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	movl	(%esi,%ecx,4),%eax
        +	adcl	$0,%edx
        +	cmpl	%ebx,%ecx
        +	movl	%ebp,24(%esp,%ecx,4)
        +	jl	L0073rdmadd
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	32(%esp,%ebx,4),%ebp
        +	adcl	$0,%edx
        +	addl	%eax,%ebp
        +	adcl	$0,%edx
        +	movl	%ebp,28(%esp,%ebx,4)
        +	movl	12(%esp),%ecx
        +	xorl	%eax,%eax
        +	movl	8(%esp),%esi
        +	addl	36(%esp,%ebx,4),%edx
        +	adcl	40(%esp,%ebx,4),%eax
        +	movl	%edx,32(%esp,%ebx,4)
        +	cmpl	%ebx,%ecx
        +	movl	%eax,36(%esp,%ebx,4)
        +	je	L005common_tail
        +	movl	4(%esi,%ecx,4),%edi
        +	leal	1(%ecx),%ecx
        +	movl	%edi,%eax
        +	movl	%ecx,12(%esp)
        +	mull	%edi
        +	addl	32(%esp,%ecx,4),%eax
        +	adcl	$0,%edx
        +	movl	%eax,32(%esp,%ecx,4)
        +	xorl	%ebp,%ebp
        +	cmpl	%ebx,%ecx
        +	leal	1(%ecx),%ecx
        +	je	L008sqrlast
        +	movl	%edx,%ebx
        +	shrl	$1,%edx
        +	andl	$1,%ebx
        +.align	4,0x90
        +L009sqradd:
        +	movl	(%esi,%ecx,4),%eax
        +	movl	%edx,%ebp
        +	mull	%edi
        +	addl	%ebp,%eax
        +	leal	(%eax,%eax,1),%ebp
        +	adcl	$0,%edx
        +	shrl	$31,%eax
        +	addl	32(%esp,%ecx,4),%ebp
        +	leal	1(%ecx),%ecx
        +	adcl	$0,%eax
        +	addl	%ebx,%ebp
        +	adcl	$0,%eax
        +	cmpl	(%esp),%ecx
        +	movl	%ebp,28(%esp,%ecx,4)
        +	movl	%eax,%ebx
        +	jle	L009sqradd
        +	movl	%edx,%ebp
        +	addl	%edx,%edx
        +	shrl	$31,%ebp
        +	addl	%ebx,%edx
        +	adcl	$0,%ebp
        +L008sqrlast:
        +	movl	20(%esp),%edi
        +	movl	16(%esp),%esi
        +	imull	32(%esp),%edi
        +	addl	32(%esp,%ecx,4),%edx
        +	movl	(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%edx,32(%esp,%ecx,4)
        +	movl	%ebp,36(%esp,%ecx,4)
        +	mull	%edi
        +	addl	32(%esp),%eax
        +	leal	-1(%ecx),%ebx
        +	adcl	$0,%edx
        +	movl	$1,%ecx
        +	movl	4(%esi),%eax
        +	jmp	L0073rdmadd
        +.align	4,0x90
        +L005common_tail:
        +	movl	16(%esp),%ebp
        +	movl	4(%esp),%edi
        +	leal	32(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	%ebx,%ecx
        +	xorl	%edx,%edx
        +.align	4,0x90
        +L010sub:
        +	sbbl	(%ebp,%edx,4),%eax
        +	movl	%eax,(%edi,%edx,4)
        +	decl	%ecx
        +	movl	4(%esi,%edx,4),%eax
        +	leal	1(%edx),%edx
        +	jge	L010sub
        +	sbbl	$0,%eax
        +	andl	%eax,%esi
        +	notl	%eax
        +	movl	%edi,%ebp
        +	andl	%eax,%ebp
        +	orl	%ebp,%esi
        +.align	4,0x90
        +L011copy:
        +	movl	(%esi,%ebx,4),%eax
        +	movl	%eax,(%edi,%ebx,4)
        +	movl	%ecx,32(%esp,%ebx,4)
        +	decl	%ebx
        +	jge	L011copy
        +	movl	24(%esp),%esp
        +	movl	$1,%eax
        +L000just_leave:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
        +.byte	112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56
        +.byte	54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121
        +.byte	32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46
        +.byte	111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/bn/x86.s b/vendor/openssl/asm/x86-macosx-gas/bn/x86.s
        new file mode 100644
        index 000000000..eb975d247
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/bn/x86.s
        @@ -0,0 +1,2385 @@
        +.file	"../openssl/crypto/bn/asm/x86.s"
        +.text
        +.globl	_bn_mul_add_words
        +.align	4
        +_bn_mul_add_words:
        +L_bn_mul_add_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	xorl	%esi,%esi
        +	movl	20(%esp),%edi
        +	movl	28(%esp),%ecx
        +	movl	24(%esp),%ebx
        +	andl	$4294967288,%ecx
        +	movl	32(%esp),%ebp
        +	pushl	%ecx
        +	jz	L000maw_finish
        +L001maw_loop:
        +	movl	%ecx,(%esp)
        +	# Round 0
        +
        +	movl	(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +	# Round 4
        +
        +	movl	4(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	4(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +	# Round 8
        +
        +	movl	8(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	8(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +	# Round 12
        +
        +	movl	12(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	12(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +	# Round 16
        +
        +	movl	16(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	16(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +	# Round 20
        +
        +	movl	20(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	20(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +	# Round 24
        +
        +	movl	24(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	24(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +	# Round 28
        +
        +	movl	28(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	28(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,28(%edi)
        +	movl	%edx,%esi
        +
        +	movl	(%esp),%ecx
        +	addl	$32,%ebx
        +	addl	$32,%edi
        +	subl	$8,%ecx
        +	jnz	L001maw_loop
        +L000maw_finish:
        +	movl	32(%esp),%ecx
        +	andl	$7,%ecx
        +	jnz	L002maw_finish2
        +	jmp	L003maw_end
        +L002maw_finish2:
        +	# Tail Round 0
        +
        +	movl	(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +	jz	L003maw_end
        +	# Tail Round 1
        +
        +	movl	4(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	4(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +	jz	L003maw_end
        +	# Tail Round 2
        +
        +	movl	8(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	8(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +	jz	L003maw_end
        +	# Tail Round 3
        +
        +	movl	12(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	12(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +	jz	L003maw_end
        +	# Tail Round 4
        +
        +	movl	16(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	16(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +	jz	L003maw_end
        +	# Tail Round 5
        +
        +	movl	20(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	20(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	decl	%ecx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +	jz	L003maw_end
        +	# Tail Round 6
        +
        +	movl	24(%ebx),%eax
        +	mull	%ebp
        +	addl	%esi,%eax
        +	movl	24(%edi),%esi
        +	adcl	$0,%edx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +L003maw_end:
        +	movl	%esi,%eax
        +	popl	%ecx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_bn_mul_words
        +.align	4
        +_bn_mul_words:
        +L_bn_mul_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	xorl	%esi,%esi
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%ebx
        +	movl	28(%esp),%ebp
        +	movl	32(%esp),%ecx
        +	andl	$4294967288,%ebp
        +	jz	L004mw_finish
        +L005mw_loop:
        +	# Round 0
        +
        +	movl	(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +	# Round 4
        +
        +	movl	4(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +	# Round 8
        +
        +	movl	8(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +	# Round 12
        +
        +	movl	12(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +	# Round 16
        +
        +	movl	16(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +	# Round 20
        +
        +	movl	20(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +	# Round 24
        +
        +	movl	24(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +	# Round 28
        +
        +	movl	28(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,28(%edi)
        +	movl	%edx,%esi
        +
        +	addl	$32,%ebx
        +	addl	$32,%edi
        +	subl	$8,%ebp
        +	jz	L004mw_finish
        +	jmp	L005mw_loop
        +L004mw_finish:
        +	movl	28(%esp),%ebp
        +	andl	$7,%ebp
        +	jnz	L006mw_finish2
        +	jmp	L007mw_end
        +L006mw_finish2:
        +	# Tail Round 0
        +
        +	movl	(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	L007mw_end
        +	# Tail Round 1
        +
        +	movl	4(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,4(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	L007mw_end
        +	# Tail Round 2
        +
        +	movl	8(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,8(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	L007mw_end
        +	# Tail Round 3
        +
        +	movl	12(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,12(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	L007mw_end
        +	# Tail Round 4
        +
        +	movl	16(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,16(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	L007mw_end
        +	# Tail Round 5
        +
        +	movl	20(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,20(%edi)
        +	movl	%edx,%esi
        +	decl	%ebp
        +	jz	L007mw_end
        +	# Tail Round 6
        +
        +	movl	24(%ebx),%eax
        +	mull	%ecx
        +	addl	%esi,%eax
        +	adcl	$0,%edx
        +	movl	%eax,24(%edi)
        +	movl	%edx,%esi
        +L007mw_end:
        +	movl	%esi,%eax
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_bn_sqr_words
        +.align	4
        +_bn_sqr_words:
        +L_bn_sqr_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%ebx
        +	andl	$4294967288,%ebx
        +	jz	L008sw_finish
        +L009sw_loop:
        +	# Round 0
        +
        +	movl	(%edi),%eax
        +	mull	%eax
        +	movl	%eax,(%esi)
        +	movl	%edx,4(%esi)
        +	# Round 4
        +
        +	movl	4(%edi),%eax
        +	mull	%eax
        +	movl	%eax,8(%esi)
        +	movl	%edx,12(%esi)
        +	# Round 8
        +
        +	movl	8(%edi),%eax
        +	mull	%eax
        +	movl	%eax,16(%esi)
        +	movl	%edx,20(%esi)
        +	# Round 12
        +
        +	movl	12(%edi),%eax
        +	mull	%eax
        +	movl	%eax,24(%esi)
        +	movl	%edx,28(%esi)
        +	# Round 16
        +
        +	movl	16(%edi),%eax
        +	mull	%eax
        +	movl	%eax,32(%esi)
        +	movl	%edx,36(%esi)
        +	# Round 20
        +
        +	movl	20(%edi),%eax
        +	mull	%eax
        +	movl	%eax,40(%esi)
        +	movl	%edx,44(%esi)
        +	# Round 24
        +
        +	movl	24(%edi),%eax
        +	mull	%eax
        +	movl	%eax,48(%esi)
        +	movl	%edx,52(%esi)
        +	# Round 28
        +
        +	movl	28(%edi),%eax
        +	mull	%eax
        +	movl	%eax,56(%esi)
        +	movl	%edx,60(%esi)
        +
        +	addl	$32,%edi
        +	addl	$64,%esi
        +	subl	$8,%ebx
        +	jnz	L009sw_loop
        +L008sw_finish:
        +	movl	28(%esp),%ebx
        +	andl	$7,%ebx
        +	jz	L010sw_end
        +	# Tail Round 0
        +
        +	movl	(%edi),%eax
        +	mull	%eax
        +	movl	%eax,(%esi)
        +	decl	%ebx
        +	movl	%edx,4(%esi)
        +	jz	L010sw_end
        +	# Tail Round 1
        +
        +	movl	4(%edi),%eax
        +	mull	%eax
        +	movl	%eax,8(%esi)
        +	decl	%ebx
        +	movl	%edx,12(%esi)
        +	jz	L010sw_end
        +	# Tail Round 2
        +
        +	movl	8(%edi),%eax
        +	mull	%eax
        +	movl	%eax,16(%esi)
        +	decl	%ebx
        +	movl	%edx,20(%esi)
        +	jz	L010sw_end
        +	# Tail Round 3
        +
        +	movl	12(%edi),%eax
        +	mull	%eax
        +	movl	%eax,24(%esi)
        +	decl	%ebx
        +	movl	%edx,28(%esi)
        +	jz	L010sw_end
        +	# Tail Round 4
        +
        +	movl	16(%edi),%eax
        +	mull	%eax
        +	movl	%eax,32(%esi)
        +	decl	%ebx
        +	movl	%edx,36(%esi)
        +	jz	L010sw_end
        +	# Tail Round 5
        +
        +	movl	20(%edi),%eax
        +	mull	%eax
        +	movl	%eax,40(%esi)
        +	decl	%ebx
        +	movl	%edx,44(%esi)
        +	jz	L010sw_end
        +	# Tail Round 6
        +
        +	movl	24(%edi),%eax
        +	mull	%eax
        +	movl	%eax,48(%esi)
        +	movl	%edx,52(%esi)
        +L010sw_end:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_bn_div_words
        +.align	4
        +_bn_div_words:
        +L_bn_div_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%edx
        +	movl	24(%esp),%eax
        +	movl	28(%esp),%ebx
        +	divl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_bn_add_words
        +.align	4
        +_bn_add_words:
        +L_bn_add_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	32(%esp),%ebp
        +	xorl	%eax,%eax
        +	andl	$4294967288,%ebp
        +	jz	L011aw_finish
        +L012aw_loop:
        +	# Round 0
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,(%ebx)
        +	# Round 1
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,4(%ebx)
        +	# Round 2
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,8(%ebx)
        +	# Round 3
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,12(%ebx)
        +	# Round 4
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,16(%ebx)
        +	# Round 5
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,20(%ebx)
        +	# Round 6
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +	# Round 7
        +
        +	movl	28(%esi),%ecx
        +	movl	28(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,28(%ebx)
        +
        +	addl	$32,%esi
        +	addl	$32,%edi
        +	addl	$32,%ebx
        +	subl	$8,%ebp
        +	jnz	L012aw_loop
        +L011aw_finish:
        +	movl	32(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L013aw_end
        +	# Tail Round 0
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,(%ebx)
        +	jz	L013aw_end
        +	# Tail Round 1
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,4(%ebx)
        +	jz	L013aw_end
        +	# Tail Round 2
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,8(%ebx)
        +	jz	L013aw_end
        +	# Tail Round 3
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,12(%ebx)
        +	jz	L013aw_end
        +	# Tail Round 4
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,16(%ebx)
        +	jz	L013aw_end
        +	# Tail Round 5
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,20(%ebx)
        +	jz	L013aw_end
        +	# Tail Round 6
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	addl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	addl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +L013aw_end:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_bn_sub_words
        +.align	4
        +_bn_sub_words:
        +L_bn_sub_words_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	32(%esp),%ebp
        +	xorl	%eax,%eax
        +	andl	$4294967288,%ebp
        +	jz	L014aw_finish
        +L015aw_loop:
        +	# Round 0
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,(%ebx)
        +	# Round 1
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,4(%ebx)
        +	# Round 2
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,8(%ebx)
        +	# Round 3
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,12(%ebx)
        +	# Round 4
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,16(%ebx)
        +	# Round 5
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,20(%ebx)
        +	# Round 6
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +	# Round 7
        +
        +	movl	28(%esi),%ecx
        +	movl	28(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,28(%ebx)
        +
        +	addl	$32,%esi
        +	addl	$32,%edi
        +	addl	$32,%ebx
        +	subl	$8,%ebp
        +	jnz	L015aw_loop
        +L014aw_finish:
        +	movl	32(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L016aw_end
        +	# Tail Round 0
        +
        +	movl	(%esi),%ecx
        +	movl	(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,(%ebx)
        +	jz	L016aw_end
        +	# Tail Round 1
        +
        +	movl	4(%esi),%ecx
        +	movl	4(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,4(%ebx)
        +	jz	L016aw_end
        +	# Tail Round 2
        +
        +	movl	8(%esi),%ecx
        +	movl	8(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,8(%ebx)
        +	jz	L016aw_end
        +	# Tail Round 3
        +
        +	movl	12(%esi),%ecx
        +	movl	12(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,12(%ebx)
        +	jz	L016aw_end
        +	# Tail Round 4
        +
        +	movl	16(%esi),%ecx
        +	movl	16(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,16(%ebx)
        +	jz	L016aw_end
        +	# Tail Round 5
        +
        +	movl	20(%esi),%ecx
        +	movl	20(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	decl	%ebp
        +	movl	%ecx,20(%ebx)
        +	jz	L016aw_end
        +	# Tail Round 6
        +
        +	movl	24(%esi),%ecx
        +	movl	24(%edi),%edx
        +	subl	%eax,%ecx
        +	movl	$0,%eax
        +	adcl	%eax,%eax
        +	subl	%edx,%ecx
        +	adcl	$0,%eax
        +	movl	%ecx,24(%ebx)
        +L016aw_end:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_bn_mul_comba8
        +.align	4
        +_bn_mul_comba8:
        +L_bn_mul_comba8_begin:
        +	pushl	%esi
        +	movl	12(%esp),%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	xorl	%ebx,%ebx
        +	movl	(%esi),%eax
        +	xorl	%ecx,%ecx
        +	movl	(%edi),%edx
        +	# ################## Calculate word 0
        +
        +	xorl	%ebp,%ebp
        +	# mul a[0]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%eax)
        +	movl	4(%esi),%eax
        +	# saved r[0]
        +
        +	# ################## Calculate word 1
        +
        +	xorl	%ebx,%ebx
        +	# mul a[1]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[0]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%eax)
        +	movl	8(%esi),%eax
        +	# saved r[1]
        +
        +	# ################## Calculate word 2
        +
        +	xorl	%ecx,%ecx
        +	# mul a[2]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[1]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[0]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%eax)
        +	movl	12(%esi),%eax
        +	# saved r[2]
        +
        +	# ################## Calculate word 3
        +
        +	xorl	%ebp,%ebp
        +	# mul a[3]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[2]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[1]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[0]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%eax)
        +	movl	16(%esi),%eax
        +	# saved r[3]
        +
        +	# ################## Calculate word 4
        +
        +	xorl	%ebx,%ebx
        +	# mul a[4]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[3]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[2]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[1]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[0]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%eax)
        +	movl	20(%esi),%eax
        +	# saved r[4]
        +
        +	# ################## Calculate word 5
        +
        +	xorl	%ecx,%ecx
        +	# mul a[5]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[4]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[3]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[2]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[1]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[0]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%eax)
        +	movl	24(%esi),%eax
        +	# saved r[5]
        +
        +	# ################## Calculate word 6
        +
        +	xorl	%ebp,%ebp
        +	# mul a[6]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[5]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[4]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[3]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[2]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[1]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[0]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[6]
        +
        +	# ################## Calculate word 7
        +
        +	xorl	%ebx,%ebx
        +	# mul a[7]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[6]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[5]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[4]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[3]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[2]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[1]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[0]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,28(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[7]
        +
        +	# ################## Calculate word 8
        +
        +	xorl	%ecx,%ecx
        +	# mul a[7]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[6]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[5]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[4]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[3]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[2]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[1]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,32(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[8]
        +
        +	# ################## Calculate word 9
        +
        +	xorl	%ebp,%ebp
        +	# mul a[7]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[6]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[5]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[4]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[3]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[2]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,36(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[9]
        +
        +	# ################## Calculate word 10
        +
        +	xorl	%ebx,%ebx
        +	# mul a[7]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[6]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	20(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[5]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[4]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	12(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[3]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	16(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,40(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[10]
        +
        +	# ################## Calculate word 11
        +
        +	xorl	%ecx,%ecx
        +	# mul a[7]*b[4]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[6]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[5]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	16(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[4]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	20(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,44(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[11]
        +
        +	# ################## Calculate word 12
        +
        +	xorl	%ebp,%ebp
        +	# mul a[7]*b[5]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[6]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[5]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	24(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,48(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[12]
        +
        +	# ################## Calculate word 13
        +
        +	xorl	%ebx,%ebx
        +	# mul a[7]*b[6]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	24(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[6]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	28(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,52(%eax)
        +	movl	28(%esi),%eax
        +	# saved r[13]
        +
        +	# ################## Calculate word 14
        +
        +	xorl	%ecx,%ecx
        +	# mul a[7]*b[7]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	adcl	$0,%ecx
        +	movl	%ebp,56(%eax)
        +	# saved r[14]
        +
        +	# save r[15]
        +
        +	movl	%ebx,60(%eax)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.globl	_bn_mul_comba4
        +.align	4
        +_bn_mul_comba4:
        +L_bn_mul_comba4_begin:
        +	pushl	%esi
        +	movl	12(%esp),%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	xorl	%ebx,%ebx
        +	movl	(%esi),%eax
        +	xorl	%ecx,%ecx
        +	movl	(%edi),%edx
        +	# ################## Calculate word 0
        +
        +	xorl	%ebp,%ebp
        +	# mul a[0]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%eax)
        +	movl	4(%esi),%eax
        +	# saved r[0]
        +
        +	# ################## Calculate word 1
        +
        +	xorl	%ebx,%ebx
        +	# mul a[1]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[0]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%eax)
        +	movl	8(%esi),%eax
        +	# saved r[1]
        +
        +	# ################## Calculate word 2
        +
        +	xorl	%ecx,%ecx
        +	# mul a[2]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[1]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[0]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%eax)
        +	movl	12(%esi),%eax
        +	# saved r[2]
        +
        +	# ################## Calculate word 3
        +
        +	xorl	%ebp,%ebp
        +	# mul a[3]*b[0]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[2]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[1]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	(%esi),%eax
        +	adcl	%edx,%ecx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebp
        +	# mul a[0]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	movl	4(%edi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%eax)
        +	movl	12(%esi),%eax
        +	# saved r[3]
        +
        +	# ################## Calculate word 4
        +
        +	xorl	%ebx,%ebx
        +	# mul a[3]*b[1]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[2]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	4(%esi),%eax
        +	adcl	%edx,%ebp
        +	movl	12(%edi),%edx
        +	adcl	$0,%ebx
        +	# mul a[1]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ecx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebp
        +	movl	8(%edi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%eax)
        +	movl	12(%esi),%eax
        +	# saved r[4]
        +
        +	# ################## Calculate word 5
        +
        +	xorl	%ecx,%ecx
        +	# mul a[3]*b[2]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	8(%esi),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +	# mul a[2]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebp
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ebx
        +	movl	12(%edi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%eax)
        +	movl	12(%esi),%eax
        +	# saved r[5]
        +
        +	# ################## Calculate word 6
        +
        +	xorl	%ebp,%ebp
        +	# mul a[3]*b[3]
        +
        +	mull	%edx
        +	addl	%eax,%ebx
        +	movl	20(%esp),%eax
        +	adcl	%edx,%ecx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%eax)
        +	# saved r[6]
        +
        +	# save r[7]
        +
        +	movl	%ecx,28(%eax)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.globl	_bn_sqr_comba8
        +.align	4
        +_bn_sqr_comba8:
        +L_bn_sqr_comba8_begin:
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%esi
        +	xorl	%ebx,%ebx
        +	xorl	%ecx,%ecx
        +	movl	(%esi),%eax
        +	# ############### Calculate word 0
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[0]*a[0]
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%edi)
        +	movl	4(%esi),%eax
        +	# saved r[0]
        +
        +	# ############### Calculate word 1
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[1]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%edi)
        +	movl	(%esi),%edx
        +	# saved r[1]
        +
        +	# ############### Calculate word 2
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[2]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	4(%esi),%eax
        +	adcl	$0,%ecx
        +	# sqr a[1]*a[1]
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	(%esi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%edi)
        +	movl	12(%esi),%eax
        +	# saved r[2]
        +
        +	# ############### Calculate word 3
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[3]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	4(%esi),%edx
        +	# sqr a[2]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%edi)
        +	movl	(%esi),%edx
        +	# saved r[3]
        +
        +	# ############### Calculate word 4
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[4]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	12(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	4(%esi),%edx
        +	# sqr a[3]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +	# sqr a[2]*a[2]
        +
        +	mull	%eax
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	(%esi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%edi)
        +	movl	20(%esi),%eax
        +	# saved r[4]
        +
        +	# ############### Calculate word 5
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[5]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	4(%esi),%edx
        +	# sqr a[4]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	8(%esi),%edx
        +	# sqr a[3]*a[2]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%edi)
        +	movl	(%esi),%edx
        +	# saved r[5]
        +
        +	# ############### Calculate word 6
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[6]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	4(%esi),%edx
        +	# sqr a[5]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	8(%esi),%edx
        +	# sqr a[4]*a[2]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ebp
        +	# sqr a[3]*a[3]
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%edi)
        +	movl	28(%esi),%eax
        +	# saved r[6]
        +
        +	# ############### Calculate word 7
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[7]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	4(%esi),%edx
        +	# sqr a[6]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	8(%esi),%edx
        +	# sqr a[5]*a[2]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	16(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	12(%esi),%edx
        +	# sqr a[4]*a[3]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	28(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,28(%edi)
        +	movl	4(%esi),%edx
        +	# saved r[7]
        +
        +	# ############### Calculate word 8
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[7]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	8(%esi),%edx
        +	# sqr a[6]*a[2]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	20(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	12(%esi),%edx
        +	# sqr a[5]*a[3]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	16(%esi),%eax
        +	adcl	$0,%ecx
        +	# sqr a[4]*a[4]
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	8(%esi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,32(%edi)
        +	movl	28(%esi),%eax
        +	# saved r[8]
        +
        +	# ############### Calculate word 9
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[7]*a[2]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	12(%esi),%edx
        +	# sqr a[6]*a[3]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	16(%esi),%edx
        +	# sqr a[5]*a[4]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	28(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%ebx,36(%edi)
        +	movl	12(%esi),%edx
        +	# saved r[9]
        +
        +	# ############### Calculate word 10
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[7]*a[3]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	16(%esi),%edx
        +	# sqr a[6]*a[4]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	20(%esi),%eax
        +	adcl	$0,%ebx
        +	# sqr a[5]*a[5]
        +
        +	mull	%eax
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	16(%esi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,40(%edi)
        +	movl	28(%esi),%eax
        +	# saved r[10]
        +
        +	# ############### Calculate word 11
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[7]*a[4]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	20(%esi),%edx
        +	# sqr a[6]*a[5]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	28(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	%ebp,44(%edi)
        +	movl	20(%esi),%edx
        +	# saved r[11]
        +
        +	# ############### Calculate word 12
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[7]*a[5]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	24(%esi),%eax
        +	adcl	$0,%ebp
        +	# sqr a[6]*a[6]
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	24(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,48(%edi)
        +	movl	28(%esi),%eax
        +	# saved r[12]
        +
        +	# ############### Calculate word 13
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[7]*a[6]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	28(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,52(%edi)
        +	# saved r[13]
        +
        +	# ############### Calculate word 14
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[7]*a[7]
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	adcl	$0,%ecx
        +	movl	%ebp,56(%edi)
        +	# saved r[14]
        +
        +	movl	%ebx,60(%edi)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.globl	_bn_sqr_comba4
        +.align	4
        +_bn_sqr_comba4:
        +L_bn_sqr_comba4_begin:
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%esi
        +	xorl	%ebx,%ebx
        +	xorl	%ecx,%ecx
        +	movl	(%esi),%eax
        +	# ############### Calculate word 0
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[0]*a[0]
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	(%esi),%edx
        +	adcl	$0,%ebp
        +	movl	%ebx,(%edi)
        +	movl	4(%esi),%eax
        +	# saved r[0]
        +
        +	# ############### Calculate word 1
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[1]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +	movl	%ecx,4(%edi)
        +	movl	(%esi),%edx
        +	# saved r[1]
        +
        +	# ############### Calculate word 2
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[2]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	4(%esi),%eax
        +	adcl	$0,%ecx
        +	# sqr a[1]*a[1]
        +
        +	mull	%eax
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	(%esi),%edx
        +	adcl	$0,%ecx
        +	movl	%ebp,8(%edi)
        +	movl	12(%esi),%eax
        +	# saved r[2]
        +
        +	# ############### Calculate word 3
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[3]*a[0]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	4(%esi),%edx
        +	# sqr a[2]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebp
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ebp
        +	movl	%ebx,12(%edi)
        +	movl	4(%esi),%edx
        +	# saved r[3]
        +
        +	# ############### Calculate word 4
        +
        +	xorl	%ebx,%ebx
        +	# sqr a[3]*a[1]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ebx
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%eax
        +	adcl	$0,%ebx
        +	# sqr a[2]*a[2]
        +
        +	mull	%eax
        +	addl	%eax,%ecx
        +	adcl	%edx,%ebp
        +	movl	8(%esi),%edx
        +	adcl	$0,%ebx
        +	movl	%ecx,16(%edi)
        +	movl	12(%esi),%eax
        +	# saved r[4]
        +
        +	# ############### Calculate word 5
        +
        +	xorl	%ecx,%ecx
        +	# sqr a[3]*a[2]
        +
        +	mull	%edx
        +	addl	%eax,%eax
        +	adcl	%edx,%edx
        +	adcl	$0,%ecx
        +	addl	%eax,%ebp
        +	adcl	%edx,%ebx
        +	movl	12(%esi),%eax
        +	adcl	$0,%ecx
        +	movl	%ebp,20(%edi)
        +	# saved r[5]
        +
        +	# ############### Calculate word 6
        +
        +	xorl	%ebp,%ebp
        +	# sqr a[3]*a[3]
        +
        +	mull	%eax
        +	addl	%eax,%ebx
        +	adcl	%edx,%ecx
        +	adcl	$0,%ebp
        +	movl	%ebx,24(%edi)
        +	# saved r[6]
        +
        +	movl	%ecx,28(%edi)
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        diff --git a/vendor/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s b/vendor/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s
        new file mode 100644
        index 000000000..2367cee78
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/camellia/cmll-x86.s
        @@ -0,0 +1,2353 @@
        +.file	"cmll-586.s"
        +.text
        +.globl	_Camellia_EncryptBlock_Rounds
        +.align	4
        +_Camellia_EncryptBlock_Rounds:
        +L_Camellia_EncryptBlock_Rounds_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	leal	(%edi,%eax,1),%eax
        +	movl	%ebx,20(%esp)
        +	movl	%eax,16(%esp)
        +	call	L000pic_point
        +L000pic_point:
        +	popl	%ebp
        +	leal	LCamellia_SBOX-L000pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_encrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	32(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_Camellia_EncryptBlock
        +.align	4
        +_Camellia_EncryptBlock:
        +L_Camellia_EncryptBlock_begin:
        +	movl	$128,%eax
        +	subl	4(%esp),%eax
        +	movl	$3,%eax
        +	adcl	$0,%eax
        +	movl	%eax,4(%esp)
        +	jmp	L_Camellia_EncryptBlock_Rounds_begin
        +.globl	_Camellia_encrypt
        +.align	4
        +_Camellia_encrypt:
        +L_Camellia_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	movl	272(%edi),%eax
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	leal	(%edi,%eax,1),%eax
        +	movl	%ebx,20(%esp)
        +	movl	%eax,16(%esp)
        +	call	L001pic_point
        +L001pic_point:
        +	popl	%ebp
        +	leal	LCamellia_SBOX-L001pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_encrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	24(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4
        +__x86_Camellia_encrypt:
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	16(%edi),%esi
        +	movl	%eax,4(%esp)
        +	movl	%ebx,8(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edx,16(%esp)
        +.align	4,0x90
        +L002loop:
        +	xorl	%esi,%eax
        +	xorl	20(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	24(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	28(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	32(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	36(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	40(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	44(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	48(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	52(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	56(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	60(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	64(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	addl	$64,%edi
        +	cmpl	20(%esp),%edi
        +	je	L003done
        +	andl	%eax,%esi
        +	movl	16(%esp),%edx
        +	roll	$1,%esi
        +	movl	%edx,%ecx
        +	xorl	%esi,%ebx
        +	orl	12(%edi),%ecx
        +	movl	%ebx,8(%esp)
        +	xorl	12(%esp),%ecx
        +	movl	4(%edi),%esi
        +	movl	%ecx,12(%esp)
        +	orl	%ebx,%esi
        +	andl	8(%edi),%ecx
        +	xorl	%esi,%eax
        +	roll	$1,%ecx
        +	movl	%eax,4(%esp)
        +	xorl	%ecx,%edx
        +	movl	16(%edi),%esi
        +	movl	%edx,16(%esp)
        +	jmp	L002loop
        +.align	3,0x90
        +L003done:
        +	movl	%eax,%ecx
        +	movl	%ebx,%edx
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	xorl	%esi,%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	ret
        +.globl	_Camellia_DecryptBlock_Rounds
        +.align	4
        +_Camellia_DecryptBlock_Rounds:
        +L_Camellia_DecryptBlock_Rounds_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	movl	%edi,16(%esp)
        +	leal	(%edi,%eax,1),%edi
        +	movl	%ebx,20(%esp)
        +	call	L004pic_point
        +L004pic_point:
        +	popl	%ebp
        +	leal	LCamellia_SBOX-L004pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_decrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	32(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_Camellia_DecryptBlock
        +.align	4
        +_Camellia_DecryptBlock:
        +L_Camellia_DecryptBlock_begin:
        +	movl	$128,%eax
        +	subl	4(%esp),%eax
        +	movl	$3,%eax
        +	adcl	$0,%eax
        +	movl	%eax,4(%esp)
        +	jmp	L_Camellia_DecryptBlock_Rounds_begin
        +.globl	_Camellia_decrypt
        +.align	4
        +_Camellia_decrypt:
        +L_Camellia_decrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%esp,%ebx
        +	subl	$28,%esp
        +	andl	$-64,%esp
        +	movl	272(%edi),%eax
        +	leal	-127(%edi),%ecx
        +	subl	%esp,%ecx
        +	negl	%ecx
        +	andl	$960,%ecx
        +	subl	%ecx,%esp
        +	addl	$4,%esp
        +	shll	$6,%eax
        +	movl	%edi,16(%esp)
        +	leal	(%edi,%eax,1),%edi
        +	movl	%ebx,20(%esp)
        +	call	L005pic_point
        +L005pic_point:
        +	popl	%ebp
        +	leal	LCamellia_SBOX-L005pic_point(%ebp),%ebp
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_decrypt
        +	movl	20(%esp),%esp
        +	bswap	%eax
        +	movl	24(%esp),%esi
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	4
        +__x86_Camellia_decrypt:
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	-8(%edi),%esi
        +	movl	%eax,4(%esp)
        +	movl	%ebx,8(%esp)
        +	movl	%ecx,12(%esp)
        +	movl	%edx,16(%esp)
        +.align	4,0x90
        +L006loop:
        +	xorl	%esi,%eax
        +	xorl	-4(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	-16(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	-12(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	-24(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	-20(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	-32(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	-28(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	-40(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	xorl	%esi,%eax
        +	xorl	-36(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	16(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	12(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	-48(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,16(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,12(%esp)
        +	xorl	%esi,%ecx
        +	xorl	-44(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	8(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	-56(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,8(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,4(%esp)
        +	subl	$64,%edi
        +	cmpl	20(%esp),%edi
        +	je	L007done
        +	andl	%eax,%esi
        +	movl	16(%esp),%edx
        +	roll	$1,%esi
        +	movl	%edx,%ecx
        +	xorl	%esi,%ebx
        +	orl	4(%edi),%ecx
        +	movl	%ebx,8(%esp)
        +	xorl	12(%esp),%ecx
        +	movl	12(%edi),%esi
        +	movl	%ecx,12(%esp)
        +	orl	%ebx,%esi
        +	andl	(%edi),%ecx
        +	xorl	%esi,%eax
        +	roll	$1,%ecx
        +	movl	%eax,4(%esp)
        +	xorl	%ecx,%edx
        +	movl	-8(%edi),%esi
        +	movl	%edx,16(%esp)
        +	jmp	L006loop
        +.align	3,0x90
        +L007done:
        +	movl	%eax,%ecx
        +	movl	%ebx,%edx
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	12(%edi),%edx
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	ret
        +.globl	_Camellia_Ekeygen
        +.align	4
        +_Camellia_Ekeygen:
        +L_Camellia_Ekeygen_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	subl	$16,%esp
        +	movl	36(%esp),%ebp
        +	movl	40(%esp),%esi
        +	movl	44(%esp),%edi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	cmpl	$128,%ebp
        +	je	L0081st128
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	cmpl	$192,%ebp
        +	je	L0091st192
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	jmp	L0101st256
        +.align	2,0x90
        +L0091st192:
        +	movl	%eax,%ecx
        +	movl	%ebx,%edx
        +	notl	%ecx
        +	notl	%edx
        +.align	2,0x90
        +L0101st256:
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,32(%edi)
        +	movl	%ebx,36(%edi)
        +	movl	%ecx,40(%edi)
        +	movl	%edx,44(%edi)
        +	xorl	(%edi),%eax
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +.align	2,0x90
        +L0081st128:
        +	call	L011pic_point
        +L011pic_point:
        +	popl	%ebp
        +	leal	LCamellia_SBOX-L011pic_point(%ebp),%ebp
        +	leal	LCamellia_SIGMA-LCamellia_SBOX(%ebp),%edi
        +	movl	(%edi),%esi
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	xorl	%esi,%eax
        +	xorl	4(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	12(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	8(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	8(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%esp)
        +	xorl	%esi,%ecx
        +	xorl	12(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	4(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	16(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,(%esp)
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	44(%esp),%esi
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	xorl	12(%esi),%edx
        +	movl	16(%edi),%esi
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	xorl	%esi,%eax
        +	xorl	20(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	12(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	8(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	24(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%esp)
        +	xorl	%esi,%ecx
        +	xorl	28(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	4(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	32(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,(%esp)
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	36(%esp),%esi
        +	cmpl	$128,%esi
        +	jne	L0122nd256
        +	movl	44(%esp),%edi
        +	leal	128(%edi),%edi
        +	movl	%eax,-112(%edi)
        +	movl	%ebx,-108(%edi)
        +	movl	%ecx,-104(%edi)
        +	movl	%edx,-100(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-80(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-76(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-72(%edi)
        +	movl	%edx,-68(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-64(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-60(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-56(%edi)
        +	movl	%edx,-52(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-32(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-28(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,-16(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,-12(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-8(%edi)
        +	movl	%edx,-4(%edi)
        +	movl	%ebx,%ebp
        +	shll	$2,%ebx
        +	movl	%ecx,%esi
        +	shrl	$30,%esi
        +	shll	$2,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$2,%edx
        +	movl	%ebx,32(%edi)
        +	shrl	$30,%esi
        +	orl	%esi,%ecx
        +	shrl	$30,%ebp
        +	movl	%eax,%esi
        +	shrl	$30,%esi
        +	movl	%ecx,36(%edi)
        +	shll	$2,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,40(%edi)
        +	movl	%eax,44(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,64(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,68(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,72(%edi)
        +	movl	%eax,76(%edi)
        +	movl	-128(%edi),%ebx
        +	movl	-124(%edi),%ecx
        +	movl	-120(%edi),%edx
        +	movl	-116(%edi),%eax
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	movl	%ebx,-96(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	movl	%ecx,-92(%edi)
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-88(%edi)
        +	movl	%eax,-84(%edi)
        +	movl	%ebx,%ebp
        +	shll	$30,%ebx
        +	movl	%ecx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$30,%edx
        +	movl	%ebx,-48(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ecx
        +	shrl	$2,%ebp
        +	movl	%eax,%esi
        +	shrl	$2,%esi
        +	movl	%ecx,-44(%edi)
        +	shll	$30,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-40(%edi)
        +	movl	%eax,-36(%edi)
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-24(%edi)
        +	movl	%eax,-20(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,4(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,8(%edi)
        +	movl	%eax,12(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,16(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,20(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,24(%edi)
        +	movl	%eax,28(%edi)
        +	movl	%ebx,%ebp
        +	shll	$17,%ebx
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$17,%edx
        +	movl	%ebx,48(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ecx
        +	shrl	$15,%ebp
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	movl	%ecx,52(%edi)
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,56(%edi)
        +	movl	%eax,60(%edi)
        +	movl	$3,%eax
        +	jmp	L013done
        +.align	4,0x90
        +L0122nd256:
        +	movl	44(%esp),%esi
        +	movl	%eax,48(%esi)
        +	movl	%ebx,52(%esi)
        +	movl	%ecx,56(%esi)
        +	movl	%edx,60(%esi)
        +	xorl	32(%esi),%eax
        +	xorl	36(%esi),%ebx
        +	xorl	40(%esi),%ecx
        +	xorl	44(%esi),%edx
        +	movl	32(%edi),%esi
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	xorl	%esi,%eax
        +	xorl	36(%edi),%ebx
        +	movzbl	%ah,%esi
        +	movl	2052(%ebp,%esi,8),%edx
        +	movzbl	%al,%esi
        +	xorl	4(%ebp,%esi,8),%edx
        +	shrl	$16,%eax
        +	movzbl	%bl,%esi
        +	movl	(%ebp,%esi,8),%ecx
        +	movzbl	%ah,%esi
        +	xorl	(%ebp,%esi,8),%edx
        +	movzbl	%bh,%esi
        +	xorl	4(%ebp,%esi,8),%ecx
        +	shrl	$16,%ebx
        +	movzbl	%al,%eax
        +	xorl	2048(%ebp,%eax,8),%edx
        +	movzbl	%bh,%esi
        +	movl	12(%esp),%eax
        +	xorl	%edx,%ecx
        +	rorl	$8,%edx
        +	xorl	2048(%ebp,%esi,8),%ecx
        +	movzbl	%bl,%esi
        +	movl	8(%esp),%ebx
        +	xorl	%eax,%edx
        +	xorl	2052(%ebp,%esi,8),%ecx
        +	movl	40(%edi),%esi
        +	xorl	%ecx,%edx
        +	movl	%edx,12(%esp)
        +	xorl	%ebx,%ecx
        +	movl	%ecx,8(%esp)
        +	xorl	%esi,%ecx
        +	xorl	44(%edi),%edx
        +	movzbl	%ch,%esi
        +	movl	2052(%ebp,%esi,8),%ebx
        +	movzbl	%cl,%esi
        +	xorl	4(%ebp,%esi,8),%ebx
        +	shrl	$16,%ecx
        +	movzbl	%dl,%esi
        +	movl	(%ebp,%esi,8),%eax
        +	movzbl	%ch,%esi
        +	xorl	(%ebp,%esi,8),%ebx
        +	movzbl	%dh,%esi
        +	xorl	4(%ebp,%esi,8),%eax
        +	shrl	$16,%edx
        +	movzbl	%cl,%ecx
        +	xorl	2048(%ebp,%ecx,8),%ebx
        +	movzbl	%dh,%esi
        +	movl	4(%esp),%ecx
        +	xorl	%ebx,%eax
        +	rorl	$8,%ebx
        +	xorl	2048(%ebp,%esi,8),%eax
        +	movzbl	%dl,%esi
        +	movl	(%esp),%edx
        +	xorl	%ecx,%ebx
        +	xorl	2052(%ebp,%esi,8),%eax
        +	movl	48(%edi),%esi
        +	xorl	%eax,%ebx
        +	movl	%ebx,4(%esp)
        +	xorl	%edx,%eax
        +	movl	%eax,(%esp)
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	44(%esp),%edi
        +	leal	128(%edi),%edi
        +	movl	%eax,-112(%edi)
        +	movl	%ebx,-108(%edi)
        +	movl	%ecx,-104(%edi)
        +	movl	%edx,-100(%edi)
        +	movl	%eax,%ebp
        +	shll	$30,%eax
        +	movl	%ebx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$30,%ecx
        +	movl	%eax,-48(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ebx
        +	shrl	$2,%ebp
        +	movl	%edx,%esi
        +	shrl	$2,%esi
        +	movl	%ebx,-44(%edi)
        +	shll	$30,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-40(%edi)
        +	movl	%edx,-36(%edi)
        +	movl	%eax,%ebp
        +	shll	$30,%eax
        +	movl	%ebx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$30,%ecx
        +	movl	%eax,32(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ebx
        +	shrl	$2,%ebp
        +	movl	%edx,%esi
        +	shrl	$2,%esi
        +	movl	%ebx,36(%edi)
        +	shll	$30,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,40(%edi)
        +	movl	%edx,44(%edi)
        +	movl	%ebx,%ebp
        +	shll	$19,%ebx
        +	movl	%ecx,%esi
        +	shrl	$13,%esi
        +	shll	$19,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$19,%edx
        +	movl	%ebx,128(%edi)
        +	shrl	$13,%esi
        +	orl	%esi,%ecx
        +	shrl	$13,%ebp
        +	movl	%eax,%esi
        +	shrl	$13,%esi
        +	movl	%ecx,132(%edi)
        +	shll	$19,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,136(%edi)
        +	movl	%eax,140(%edi)
        +	movl	-96(%edi),%ebx
        +	movl	-92(%edi),%ecx
        +	movl	-88(%edi),%edx
        +	movl	-84(%edi),%eax
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	movl	%ebx,-96(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	movl	%ecx,-92(%edi)
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-88(%edi)
        +	movl	%eax,-84(%edi)
        +	movl	%ebx,%ebp
        +	shll	$15,%ebx
        +	movl	%ecx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$15,%edx
        +	movl	%ebx,-64(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ecx
        +	shrl	$17,%ebp
        +	movl	%eax,%esi
        +	shrl	$17,%esi
        +	movl	%ecx,-60(%edi)
        +	shll	$15,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,-56(%edi)
        +	movl	%eax,-52(%edi)
        +	movl	%ebx,%ebp
        +	shll	$30,%ebx
        +	movl	%ecx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$30,%edx
        +	movl	%ebx,16(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%ecx
        +	shrl	$2,%ebp
        +	movl	%eax,%esi
        +	shrl	$2,%esi
        +	movl	%ecx,20(%edi)
        +	shll	$30,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,24(%edi)
        +	movl	%eax,28(%edi)
        +	movl	%ecx,%ebp
        +	shll	$2,%ecx
        +	movl	%edx,%esi
        +	shrl	$30,%esi
        +	shll	$2,%edx
        +	orl	%esi,%ecx
        +	movl	%eax,%esi
        +	shll	$2,%eax
        +	movl	%ecx,80(%edi)
        +	shrl	$30,%esi
        +	orl	%esi,%edx
        +	shrl	$30,%ebp
        +	movl	%ebx,%esi
        +	shrl	$30,%esi
        +	movl	%edx,84(%edi)
        +	shll	$2,%ebx
        +	orl	%esi,%eax
        +	orl	%ebp,%ebx
        +	movl	%eax,88(%edi)
        +	movl	%ebx,92(%edi)
        +	movl	-80(%edi),%ecx
        +	movl	-76(%edi),%edx
        +	movl	-72(%edi),%eax
        +	movl	-68(%edi),%ebx
        +	movl	%ecx,%ebp
        +	shll	$15,%ecx
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	movl	%eax,%esi
        +	shll	$15,%eax
        +	movl	%ecx,-80(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%edx
        +	shrl	$17,%ebp
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	movl	%edx,-76(%edi)
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	orl	%ebp,%ebx
        +	movl	%eax,-72(%edi)
        +	movl	%ebx,-68(%edi)
        +	movl	%ecx,%ebp
        +	shll	$30,%ecx
        +	movl	%edx,%esi
        +	shrl	$2,%esi
        +	shll	$30,%edx
        +	orl	%esi,%ecx
        +	movl	%eax,%esi
        +	shll	$30,%eax
        +	movl	%ecx,-16(%edi)
        +	shrl	$2,%esi
        +	orl	%esi,%edx
        +	shrl	$2,%ebp
        +	movl	%ebx,%esi
        +	shrl	$2,%esi
        +	movl	%edx,-12(%edi)
        +	shll	$30,%ebx
        +	orl	%esi,%eax
        +	orl	%ebp,%ebx
        +	movl	%eax,-8(%edi)
        +	movl	%ebx,-4(%edi)
        +	movl	%edx,64(%edi)
        +	movl	%eax,68(%edi)
        +	movl	%ebx,72(%edi)
        +	movl	%ecx,76(%edi)
        +	movl	%edx,%ebp
        +	shll	$17,%edx
        +	movl	%eax,%esi
        +	shrl	$15,%esi
        +	shll	$17,%eax
        +	orl	%esi,%edx
        +	movl	%ebx,%esi
        +	shll	$17,%ebx
        +	movl	%edx,96(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%eax
        +	shrl	$15,%ebp
        +	movl	%ecx,%esi
        +	shrl	$15,%esi
        +	movl	%eax,100(%edi)
        +	shll	$17,%ecx
        +	orl	%esi,%ebx
        +	orl	%ebp,%ecx
        +	movl	%ebx,104(%edi)
        +	movl	%ecx,108(%edi)
        +	movl	-128(%edi),%edx
        +	movl	-124(%edi),%eax
        +	movl	-120(%edi),%ebx
        +	movl	-116(%edi),%ecx
        +	movl	%eax,%ebp
        +	shll	$13,%eax
        +	movl	%ebx,%esi
        +	shrl	$19,%esi
        +	shll	$13,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$13,%ecx
        +	movl	%eax,-32(%edi)
        +	shrl	$19,%esi
        +	orl	%esi,%ebx
        +	shrl	$19,%ebp
        +	movl	%edx,%esi
        +	shrl	$19,%esi
        +	movl	%ebx,-28(%edi)
        +	shll	$13,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,-24(%edi)
        +	movl	%edx,-20(%edi)
        +	movl	%eax,%ebp
        +	shll	$15,%eax
        +	movl	%ebx,%esi
        +	shrl	$17,%esi
        +	shll	$15,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$15,%ecx
        +	movl	%eax,(%edi)
        +	shrl	$17,%esi
        +	orl	%esi,%ebx
        +	shrl	$17,%ebp
        +	movl	%edx,%esi
        +	shrl	$17,%esi
        +	movl	%ebx,4(%edi)
        +	shll	$15,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	%eax,%ebp
        +	shll	$17,%eax
        +	movl	%ebx,%esi
        +	shrl	$15,%esi
        +	shll	$17,%ebx
        +	orl	%esi,%eax
        +	movl	%ecx,%esi
        +	shll	$17,%ecx
        +	movl	%eax,48(%edi)
        +	shrl	$15,%esi
        +	orl	%esi,%ebx
        +	shrl	$15,%ebp
        +	movl	%edx,%esi
        +	shrl	$15,%esi
        +	movl	%ebx,52(%edi)
        +	shll	$17,%edx
        +	orl	%esi,%ecx
        +	orl	%ebp,%edx
        +	movl	%ecx,56(%edi)
        +	movl	%edx,60(%edi)
        +	movl	%ebx,%ebp
        +	shll	$2,%ebx
        +	movl	%ecx,%esi
        +	shrl	$30,%esi
        +	shll	$2,%ecx
        +	orl	%esi,%ebx
        +	movl	%edx,%esi
        +	shll	$2,%edx
        +	movl	%ebx,112(%edi)
        +	shrl	$30,%esi
        +	orl	%esi,%ecx
        +	shrl	$30,%ebp
        +	movl	%eax,%esi
        +	shrl	$30,%esi
        +	movl	%ecx,116(%edi)
        +	shll	$2,%eax
        +	orl	%esi,%edx
        +	orl	%ebp,%eax
        +	movl	%edx,120(%edi)
        +	movl	%eax,124(%edi)
        +	movl	$4,%eax
        +L013done:
        +	leal	144(%edi),%edx
        +	addl	$16,%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_private_Camellia_set_key
        +.align	4
        +_private_Camellia_set_key:
        +L_private_Camellia_set_key_begin:
        +	pushl	%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%edx
        +	movl	$-1,%eax
        +	testl	%ecx,%ecx
        +	jz	L014done
        +	testl	%edx,%edx
        +	jz	L014done
        +	movl	$-2,%eax
        +	cmpl	$256,%ebx
        +	je	L015arg_ok
        +	cmpl	$192,%ebx
        +	je	L015arg_ok
        +	cmpl	$128,%ebx
        +	jne	L014done
        +.align	2,0x90
        +L015arg_ok:
        +	pushl	%edx
        +	pushl	%ecx
        +	pushl	%ebx
        +	call	L_Camellia_Ekeygen_begin
        +	addl	$12,%esp
        +	movl	%eax,(%edx)
        +	xorl	%eax,%eax
        +.align	2,0x90
        +L014done:
        +	popl	%ebx
        +	ret
        +.align	6,0x90
        +LCamellia_SIGMA:
        +.long	2694735487,1003262091,3061508184,1286239154,3337565999,3914302142,1426019237,4057165596,283453434,3731369245,2958461122,3018244605,0,0,0,0
        +.align	6,0x90
        +LCamellia_SBOX:
        +.long	1886416896,1886388336
        +.long	2189591040,741081132
        +.long	741092352,3014852787
        +.long	3974949888,3233808576
        +.long	3014898432,3840147684
        +.long	656877312,1465319511
        +.long	3233857536,3941204202
        +.long	3857048832,2930639022
        +.long	3840205824,589496355
        +.long	2240120064,1802174571
        +.long	1465341696,1162149957
        +.long	892679424,2779054245
        +.long	3941263872,3991732461
        +.long	202116096,1330577487
        +.long	2930683392,488439837
        +.long	1094795520,2459041938
        +.long	589505280,2256928902
        +.long	4025478912,2947481775
        +.long	1802201856,2088501372
        +.long	2475922176,522125343
        +.long	1162167552,1044250686
        +.long	421075200,3705405660
        +.long	2779096320,1583218782
        +.long	555819264,185270283
        +.long	3991792896,2795896998
        +.long	235802112,960036921
        +.long	1330597632,3587506389
        +.long	1313754624,1566376029
        +.long	488447232,3654877401
        +.long	1701143808,1515847770
        +.long	2459079168,1364262993
        +.long	3183328512,1819017324
        +.long	2256963072,2341142667
        +.long	3099113472,2593783962
        +.long	2947526400,4227531003
        +.long	2408550144,2964324528
        +.long	2088532992,1953759348
        +.long	3958106880,724238379
        +.long	522133248,4042260720
        +.long	3469659648,2223243396
        +.long	1044266496,3755933919
        +.long	808464384,3419078859
        +.long	3705461760,875823156
        +.long	1600085760,1987444854
        +.long	1583242752,1835860077
        +.long	3318072576,2846425257
        +.long	185273088,3520135377
        +.long	437918208,67371012
        +.long	2795939328,336855060
        +.long	3789676800,976879674
        +.long	960051456,3739091166
        +.long	3402287616,286326801
        +.long	3587560704,842137650
        +.long	1195853568,2627469468
        +.long	1566399744,1397948499
        +.long	1027423488,4075946226
        +.long	3654932736,4278059262
        +.long	16843008,3486449871
        +.long	1515870720,3284336835
        +.long	3604403712,2054815866
        +.long	1364283648,606339108
        +.long	1448498688,3907518696
        +.long	1819044864,1616904288
        +.long	1296911616,1768489065
        +.long	2341178112,2863268010
        +.long	218959104,2694840480
        +.long	2593823232,2711683233
        +.long	1717986816,1650589794
        +.long	4227595008,1414791252
        +.long	3435973632,505282590
        +.long	2964369408,3772776672
        +.long	757935360,1684275300
        +.long	1953788928,269484048
        +.long	303174144,0
        +.long	724249344,2745368739
        +.long	538976256,1970602101
        +.long	4042321920,2324299914
        +.long	2981212416,3873833190
        +.long	2223277056,151584777
        +.long	2576980224,3722248413
        +.long	3755990784,2273771655
        +.long	1280068608,2206400643
        +.long	3419130624,3452764365
        +.long	3267543552,2425356432
        +.long	875836416,1936916595
        +.long	2122219008,4143317238
        +.long	1987474944,2644312221
        +.long	84215040,3216965823
        +.long	1835887872,1381105746
        +.long	3082270464,3638034648
        +.long	2846468352,3368550600
        +.long	825307392,3334865094
        +.long	3520188672,2172715137
        +.long	387389184,1869545583
        +.long	67372032,320012307
        +.long	3621246720,1667432547
        +.long	336860160,3924361449
        +.long	1482184704,2812739751
        +.long	976894464,2677997727
        +.long	1633771776,3166437564
        +.long	3739147776,690552873
        +.long	454761216,4193845497
        +.long	286331136,791609391
        +.long	471604224,3031695540
        +.long	842150400,2021130360
        +.long	252645120,101056518
        +.long	2627509248,3890675943
        +.long	370546176,1903231089
        +.long	1397969664,3570663636
        +.long	404232192,2880110763
        +.long	4076007936,2290614408
        +.long	572662272,2374828173
        +.long	4278124032,1920073842
        +.long	1145324544,3115909305
        +.long	3486502656,4177002744
        +.long	2998055424,2896953516
        +.long	3284386560,909508662
        +.long	3048584448,707395626
        +.long	2054846976,1010565180
        +.long	2442236160,4059103473
        +.long	606348288,1077936192
        +.long	134744064,3553820883
        +.long	3907577856,3149594811
        +.long	2829625344,1128464451
        +.long	1616928768,353697813
        +.long	4244438016,2913796269
        +.long	1768515840,2004287607
        +.long	1347440640,2155872384
        +.long	2863311360,2189557890
        +.long	3503345664,3974889708
        +.long	2694881280,656867367
        +.long	2105376000,3856990437
        +.long	2711724288,2240086149
        +.long	2307492096,892665909
        +.long	1650614784,202113036
        +.long	2543294208,1094778945
        +.long	1414812672,4025417967
        +.long	1532713728,2475884691
        +.long	505290240,421068825
        +.long	2509608192,555810849
        +.long	3772833792,235798542
        +.long	4294967040,1313734734
        +.long	1684300800,1701118053
        +.long	3537031680,3183280317
        +.long	269488128,3099066552
        +.long	3301229568,2408513679
        +.long	0,3958046955
        +.long	1212696576,3469607118
        +.long	2745410304,808452144
        +.long	4160222976,1600061535
        +.long	1970631936,3318022341
        +.long	3688618752,437911578
        +.long	2324335104,3789619425
        +.long	50529024,3402236106
        +.long	3873891840,1195835463
        +.long	3671775744,1027407933
        +.long	151587072,16842753
        +.long	1061109504,3604349142
        +.long	3722304768,1448476758
        +.long	2492765184,1296891981
        +.long	2273806080,218955789
        +.long	1549556736,1717960806
        +.long	2206434048,3435921612
        +.long	33686016,757923885
        +.long	3452816640,303169554
        +.long	1246382592,538968096
        +.long	2425393152,2981167281
        +.long	858993408,2576941209
        +.long	1936945920,1280049228
        +.long	1734829824,3267494082
        +.long	4143379968,2122186878
        +.long	4092850944,84213765
        +.long	2644352256,3082223799
        +.long	2139062016,825294897
        +.long	3217014528,387383319
        +.long	3806519808,3621191895
        +.long	1381126656,1482162264
        +.long	2610666240,1633747041
        +.long	3638089728,454754331
        +.long	640034304,471597084
        +.long	3368601600,252641295
        +.long	926365440,370540566
        +.long	3334915584,404226072
        +.long	993737472,572653602
        +.long	2172748032,1145307204
        +.long	2526451200,2998010034
        +.long	1869573888,3048538293
        +.long	1263225600,2442199185
        +.long	320017152,134742024
        +.long	3200171520,2829582504
        +.long	1667457792,4244373756
        +.long	774778368,1347420240
        +.long	3924420864,3503292624
        +.long	2038003968,2105344125
        +.long	2812782336,2307457161
        +.long	2358021120,2543255703
        +.long	2678038272,1532690523
        +.long	1852730880,2509570197
        +.long	3166485504,4294902015
        +.long	2391707136,3536978130
        +.long	690563328,3301179588
        +.long	4126536960,1212678216
        +.long	4193908992,4160159991
        +.long	3065427456,3688562907
        +.long	791621376,50528259
        +.long	4261281024,3671720154
        +.long	3031741440,1061093439
        +.long	1499027712,2492727444
        +.long	2021160960,1549533276
        +.long	2560137216,33685506
        +.long	101058048,1246363722
        +.long	1785358848,858980403
        +.long	3890734848,1734803559
        +.long	1179010560,4092788979
        +.long	1903259904,2139029631
        +.long	3132799488,3806462178
        +.long	3570717696,2610626715
        +.long	623191296,640024614
        +.long	2880154368,926351415
        +.long	1111638528,993722427
        +.long	2290649088,2526412950
        +.long	2728567296,1263206475
        +.long	2374864128,3200123070
        +.long	4210752000,774766638
        +.long	1920102912,2037973113
        +.long	117901056,2357985420
        +.long	3115956480,1852702830
        +.long	1431655680,2391670926
        +.long	4177065984,4126474485
        +.long	4008635904,3065381046
        +.long	2896997376,4261216509
        +.long	168430080,1499005017
        +.long	909522432,2560098456
        +.long	1229539584,1785331818
        +.long	707406336,1178992710
        +.long	1751672832,3132752058
        +.long	1010580480,623181861
        +.long	943208448,1111621698
        +.long	4059164928,2728525986
        +.long	2762253312,4210688250
        +.long	1077952512,117899271
        +.long	673720320,1431634005
        +.long	3553874688,4008575214
        +.long	2071689984,168427530
        +.long	3149642496,1229520969
        +.long	3385444608,1751646312
        +.long	1128481536,943194168
        +.long	3250700544,2762211492
        +.long	353703168,673710120
        +.long	3823362816,2071658619
        +.long	2913840384,3385393353
        +.long	4109693952,3250651329
        +.long	2004317952,3823304931
        +.long	3351758592,4109631732
        +.long	2155905024,3351707847
        +.long	2661195264,2661154974
        +.long	14737632,939538488
        +.long	328965,1090535745
        +.long	5789784,369104406
        +.long	14277081,1979741814
        +.long	6776679,3640711641
        +.long	5131854,2466288531
        +.long	8487297,1610637408
        +.long	13355979,4060148466
        +.long	13224393,1912631922
        +.long	723723,3254829762
        +.long	11447982,2868947883
        +.long	6974058,2583730842
        +.long	14013909,1962964341
        +.long	1579032,100664838
        +.long	6118749,1459640151
        +.long	8553090,2684395680
        +.long	4605510,2432733585
        +.long	14671839,4144035831
        +.long	14079702,3036722613
        +.long	2565927,3372272073
        +.long	9079434,2717950626
        +.long	3289650,2348846220
        +.long	4934475,3523269330
        +.long	4342338,2415956112
        +.long	14408667,4127258358
        +.long	1842204,117442311
        +.long	10395294,2801837991
        +.long	10263708,654321447
        +.long	3815994,2382401166
        +.long	13290186,2986390194
        +.long	2434341,1224755529
        +.long	8092539,3724599006
        +.long	855309,1124090691
        +.long	7434609,1543527516
        +.long	6250335,3607156695
        +.long	2039583,3338717127
        +.long	16316664,1040203326
        +.long	14145495,4110480885
        +.long	4079166,2399178639
        +.long	10329501,1728079719
        +.long	8158332,520101663
        +.long	6316128,402659352
        +.long	12171705,1845522030
        +.long	12500670,2936057775
        +.long	12369084,788541231
        +.long	9145227,3791708898
        +.long	1447446,2231403909
        +.long	3421236,218107149
        +.long	5066061,1392530259
        +.long	12829635,4026593520
        +.long	7500402,2617285788
        +.long	9803157,1694524773
        +.long	11250603,3925928682
        +.long	9342606,2734728099
        +.long	12237498,2919280302
        +.long	8026746,2650840734
        +.long	11776947,3959483628
        +.long	131586,2147516544
        +.long	11842740,754986285
        +.long	11382189,1795189611
        +.long	10658466,2818615464
        +.long	11316396,721431339
        +.long	14211288,905983542
        +.long	10132122,2785060518
        +.long	1513239,3305162181
        +.long	1710618,2248181382
        +.long	3487029,1291865421
        +.long	13421772,855651123
        +.long	16250871,4244700669
        +.long	10066329,1711302246
        +.long	6381921,1476417624
        +.long	5921370,2516620950
        +.long	15263976,973093434
        +.long	2368548,150997257
        +.long	5658198,2499843477
        +.long	4210752,268439568
        +.long	14803425,2013296760
        +.long	6513507,3623934168
        +.long	592137,1107313218
        +.long	3355443,3422604492
        +.long	12566463,4009816047
        +.long	10000536,637543974
        +.long	9934743,3842041317
        +.long	8750469,1627414881
        +.long	6842472,436214298
        +.long	16579836,1056980799
        +.long	15527148,989870907
        +.long	657930,2181071490
        +.long	14342874,3053500086
        +.long	7303023,3674266587
        +.long	5460819,3556824276
        +.long	6447714,2550175896
        +.long	10724259,3892373736
        +.long	3026478,2332068747
        +.long	526344,33554946
        +.long	11513775,3942706155
        +.long	2631720,167774730
        +.long	11579568,738208812
        +.long	7631988,486546717
        +.long	12763842,2952835248
        +.long	12434877,1862299503
        +.long	3552822,2365623693
        +.long	2236962,2281736328
        +.long	3684408,234884622
        +.long	6579300,419436825
        +.long	1973790,2264958855
        +.long	3750201,1308642894
        +.long	2894892,184552203
        +.long	10921638,2835392937
        +.long	3158064,201329676
        +.long	15066597,2030074233
        +.long	4473924,285217041
        +.long	16645629,2130739071
        +.long	8947848,570434082
        +.long	10461087,3875596263
        +.long	6645093,1493195097
        +.long	8882055,3774931425
        +.long	7039851,3657489114
        +.long	16053492,1023425853
        +.long	2302755,3355494600
        +.long	4737096,301994514
        +.long	1052688,67109892
        +.long	13750737,1946186868
        +.long	5329233,1409307732
        +.long	12632256,805318704
        +.long	16382457,2113961598
        +.long	13816530,3019945140
        +.long	10526880,671098920
        +.long	5592405,1426085205
        +.long	10592673,1744857192
        +.long	4276545,1342197840
        +.long	16448250,3187719870
        +.long	4408131,3489714384
        +.long	1250067,3288384708
        +.long	12895428,822096177
        +.long	3092271,3405827019
        +.long	11053224,704653866
        +.long	11974326,2902502829
        +.long	3947580,251662095
        +.long	2829099,3389049546
        +.long	12698049,1879076976
        +.long	16777215,4278255615
        +.long	13158600,838873650
        +.long	10855845,1761634665
        +.long	2105376,134219784
        +.long	9013641,1644192354
        +.long	0,0
        +.long	9474192,603989028
        +.long	4671303,3506491857
        +.long	15724527,4211145723
        +.long	15395562,3120609978
        +.long	12040119,3976261101
        +.long	1381653,1157645637
        +.long	394758,2164294017
        +.long	13487565,1929409395
        +.long	11908533,1828744557
        +.long	1184274,2214626436
        +.long	8289918,2667618207
        +.long	12303291,3993038574
        +.long	2697513,1241533002
        +.long	986895,3271607235
        +.long	12105912,771763758
        +.long	460551,3238052289
        +.long	263172,16777473
        +.long	10197915,3858818790
        +.long	9737364,620766501
        +.long	2171169,1207978056
        +.long	6710886,2566953369
        +.long	15132390,3103832505
        +.long	13553358,3003167667
        +.long	15592941,2063629179
        +.long	15198183,4177590777
        +.long	3881787,3456159438
        +.long	16711422,3204497343
        +.long	8355711,3741376479
        +.long	12961221,1895854449
        +.long	10790052,687876393
        +.long	3618615,3439381965
        +.long	11645361,1811967084
        +.long	5000268,318771987
        +.long	9539985,1677747300
        +.long	7237230,2600508315
        +.long	9276813,1660969827
        +.long	7763574,2634063261
        +.long	197379,3221274816
        +.long	2960685,1258310475
        +.long	14606046,3070277559
        +.long	9868950,2768283045
        +.long	2500134,2298513801
        +.long	8224125,1593859935
        +.long	13027014,2969612721
        +.long	6052956,385881879
        +.long	13882323,4093703412
        +.long	15921906,3154164924
        +.long	5197647,3540046803
        +.long	1644825,1174423110
        +.long	4144959,3472936911
        +.long	14474460,922761015
        +.long	7960953,1577082462
        +.long	1907997,1191200583
        +.long	5395026,2483066004
        +.long	15461355,4194368250
        +.long	15987699,4227923196
        +.long	7171437,1526750043
        +.long	6184542,2533398423
        +.long	16514043,4261478142
        +.long	6908265,1509972570
        +.long	11711154,2885725356
        +.long	15790320,1006648380
        +.long	3223857,1275087948
        +.long	789516,50332419
        +.long	13948116,889206069
        +.long	13619151,4076925939
        +.long	9211020,587211555
        +.long	14869218,3087055032
        +.long	7697781,1560304989
        +.long	11119017,1778412138
        +.long	4868682,2449511058
        +.long	5723991,3573601749
        +.long	8684676,553656609
        +.long	1118481,1140868164
        +.long	4539717,1358975313
        +.long	1776411,3321939654
        +.long	16119285,2097184125
        +.long	15000804,956315961
        +.long	921102,2197848963
        +.long	7566195,3691044060
        +.long	11184810,2852170410
        +.long	15856113,2080406652
        +.long	14540253,1996519287
        +.long	5855577,1442862678
        +.long	1315860,83887365
        +.long	7105644,452991771
        +.long	9605778,2751505572
        +.long	5526612,352326933
        +.long	13684944,872428596
        +.long	7895160,503324190
        +.long	7368816,469769244
        +.long	14935011,4160813304
        +.long	4802889,1375752786
        +.long	8421504,536879136
        +.long	5263440,335549460
        +.long	10987431,3909151209
        +.long	16185078,3170942397
        +.long	7829367,3707821533
        +.long	9671571,3825263844
        +.long	8816262,2701173153
        +.long	8618883,3758153952
        +.long	2763306,2315291274
        +.long	13092807,4043370993
        +.long	5987163,3590379222
        +.long	15329769,2046851706
        +.long	15658734,3137387451
        +.long	9408399,3808486371
        +.long	65793,1073758272
        +.long	4013373,1325420367
        +.globl	_Camellia_cbc_encrypt
        +.align	4
        +_Camellia_cbc_encrypt:
        +L_Camellia_cbc_encrypt_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ecx
        +	cmpl	$0,%ecx
        +	je	L016enc_out
        +	pushfl
        +	cld
        +	movl	24(%esp),%eax
        +	movl	28(%esp),%ebx
        +	movl	36(%esp),%edx
        +	movl	40(%esp),%ebp
        +	leal	-64(%esp),%esi
        +	andl	$-64,%esi
        +	leal	-127(%edx),%edi
        +	subl	%esi,%edi
        +	negl	%edi
        +	andl	$960,%edi
        +	subl	%edi,%esi
        +	movl	44(%esp),%edi
        +	xchgl	%esi,%esp
        +	addl	$4,%esp
        +	movl	%esi,20(%esp)
        +	movl	%eax,24(%esp)
        +	movl	%ebx,28(%esp)
        +	movl	%ecx,32(%esp)
        +	movl	%edx,36(%esp)
        +	movl	%ebp,40(%esp)
        +	call	L017pic_point
        +L017pic_point:
        +	popl	%ebp
        +	leal	LCamellia_SBOX-L017pic_point(%ebp),%ebp
        +	movl	$32,%esi
        +.align	2,0x90
        +L018prefetch_sbox:
        +	movl	(%ebp),%eax
        +	movl	32(%ebp),%ebx
        +	movl	64(%ebp),%ecx
        +	movl	96(%ebp),%edx
        +	leal	128(%ebp),%ebp
        +	decl	%esi
        +	jnz	L018prefetch_sbox
        +	movl	36(%esp),%eax
        +	subl	$4096,%ebp
        +	movl	24(%esp),%esi
        +	movl	272(%eax),%edx
        +	cmpl	$0,%edi
        +	je	L019DECRYPT
        +	movl	32(%esp),%ecx
        +	movl	40(%esp),%edi
        +	shll	$6,%edx
        +	leal	(%eax,%edx,1),%edx
        +	movl	%edx,16(%esp)
        +	testl	$4294967280,%ecx
        +	jz	L020enc_tail
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +.align	2,0x90
        +L021enc_loop:
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	xorl	(%esi),%eax
        +	xorl	4(%esi),%ebx
        +	xorl	8(%esi),%ecx
        +	bswap	%eax
        +	xorl	12(%esi),%edx
        +	bswap	%ebx
        +	movl	36(%esp),%edi
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_encrypt
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	movl	%eax,(%edi)
        +	bswap	%edx
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	32(%esp),%ecx
        +	leal	16(%esi),%esi
        +	movl	%esi,24(%esp)
        +	leal	16(%edi),%edx
        +	movl	%edx,28(%esp)
        +	subl	$16,%ecx
        +	testl	$4294967280,%ecx
        +	movl	%ecx,32(%esp)
        +	jnz	L021enc_loop
        +	testl	$15,%ecx
        +	jnz	L020enc_tail
        +	movl	40(%esp),%esi
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	20(%esp),%esp
        +	popfl
        +L016enc_out:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +	pushfl
        +.align	2,0x90
        +L020enc_tail:
        +	movl	%edi,%eax
        +	movl	28(%esp),%edi
        +	pushl	%eax
        +	movl	$16,%ebx
        +	subl	%ecx,%ebx
        +	cmpl	%esi,%edi
        +	je	L022enc_in_place
        +.align	2,0x90
        +.long	2767451785
        +	jmp	L023enc_skip_in_place
        +L022enc_in_place:
        +	leal	(%edi,%ecx,1),%edi
        +L023enc_skip_in_place:
        +	movl	%ebx,%ecx
        +	xorl	%eax,%eax
        +.align	2,0x90
        +.long	2868115081
        +	popl	%edi
        +	movl	28(%esp),%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	$16,32(%esp)
        +	jmp	L021enc_loop
        +.align	4,0x90
        +L019DECRYPT:
        +	shll	$6,%edx
        +	leal	(%eax,%edx,1),%edx
        +	movl	%eax,16(%esp)
        +	movl	%edx,36(%esp)
        +	cmpl	28(%esp),%esi
        +	je	L024dec_in_place
        +	movl	40(%esp),%edi
        +	movl	%edi,44(%esp)
        +.align	2,0x90
        +L025dec_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	bswap	%eax
        +	movl	12(%esi),%edx
        +	bswap	%ebx
        +	movl	36(%esp),%edi
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_decrypt
        +	movl	44(%esp),%edi
        +	movl	32(%esp),%esi
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	xorl	(%edi),%eax
        +	bswap	%edx
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	subl	$16,%esi
        +	jc	L026dec_partial
        +	movl	%esi,32(%esp)
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	%esi,44(%esp)
        +	leal	16(%esi),%esi
        +	movl	%esi,24(%esp)
        +	leal	16(%edi),%edi
        +	movl	%edi,28(%esp)
        +	jnz	L025dec_loop
        +	movl	44(%esp),%edi
        +L027dec_end:
        +	movl	40(%esp),%esi
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	jmp	L028dec_out
        +.align	2,0x90
        +L026dec_partial:
        +	leal	44(%esp),%edi
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	leal	16(%esi),%ecx
        +	movl	%edi,%esi
        +	movl	28(%esp),%edi
        +.long	2767451785
        +	movl	24(%esp),%edi
        +	jmp	L027dec_end
        +.align	2,0x90
        +L024dec_in_place:
        +L029dec_in_place_loop:
        +	leal	44(%esp),%edi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	bswap	%eax
        +	movl	%edx,12(%edi)
        +	bswap	%ebx
        +	movl	36(%esp),%edi
        +	bswap	%ecx
        +	bswap	%edx
        +	call	__x86_Camellia_decrypt
        +	movl	40(%esp),%edi
        +	movl	28(%esp),%esi
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	xorl	(%edi),%eax
        +	bswap	%edx
        +	xorl	4(%edi),%ebx
        +	xorl	8(%edi),%ecx
        +	xorl	12(%edi),%edx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	leal	16(%esi),%esi
        +	movl	%esi,28(%esp)
        +	leal	44(%esp),%esi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	movl	%ecx,8(%edi)
        +	movl	%edx,12(%edi)
        +	movl	24(%esp),%esi
        +	leal	16(%esi),%esi
        +	movl	%esi,24(%esp)
        +	movl	32(%esp),%ecx
        +	subl	$16,%ecx
        +	jc	L030dec_in_place_partial
        +	movl	%ecx,32(%esp)
        +	jnz	L029dec_in_place_loop
        +	jmp	L028dec_out
        +.align	2,0x90
        +L030dec_in_place_partial:
        +	movl	28(%esp),%edi
        +	leal	44(%esp),%esi
        +	leal	(%edi,%ecx,1),%edi
        +	leal	16(%esi,%ecx,1),%esi
        +	negl	%ecx
        +.long	2767451785
        +.align	2,0x90
        +L028dec_out:
        +	movl	20(%esp),%esp
        +	popfl
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.byte	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54
        +.byte	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +.byte	115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/cast/cast-586.s b/vendor/openssl/asm/x86-macosx-gas/cast/cast-586.s
        new file mode 100644
        index 000000000..9314dff21
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/cast/cast-586.s
        @@ -0,0 +1,967 @@
        +.file	"cast-586.s"
        +.text
        +.globl	_CAST_encrypt
        +.align	4
        +_CAST_encrypt:
        +L_CAST_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ebp
        +	pushl	%esi
        +	pushl	%edi
        +	# Load the 2 words
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +	# Get short key flag
        +
        +	movl	128(%ebp),%eax
        +	pushl	%eax
        +	xorl	%eax,%eax
        +	# round 0
        +
        +	movl	(%ebp),%edx
        +	movl	4(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 1
        +
        +	movl	8(%ebp),%edx
        +	movl	12(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 2
        +
        +	movl	16(%ebp),%edx
        +	movl	20(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 3
        +
        +	movl	24(%ebp),%edx
        +	movl	28(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 4
        +
        +	movl	32(%ebp),%edx
        +	movl	36(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 5
        +
        +	movl	40(%ebp),%edx
        +	movl	44(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 6
        +
        +	movl	48(%ebp),%edx
        +	movl	52(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 7
        +
        +	movl	56(%ebp),%edx
        +	movl	60(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 8
        +
        +	movl	64(%ebp),%edx
        +	movl	68(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 9
        +
        +	movl	72(%ebp),%edx
        +	movl	76(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 10
        +
        +	movl	80(%ebp),%edx
        +	movl	84(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 11
        +
        +	movl	88(%ebp),%edx
        +	movl	92(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# test short key flag
        +
        +	popl	%edx
        +	orl	%edx,%edx
        +	jnz	L000cast_enc_done
        +	# round 12
        +
        +	movl	96(%ebp),%edx
        +	movl	100(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 13
        +
        +	movl	104(%ebp),%edx
        +	movl	108(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 14
        +
        +	movl	112(%ebp),%edx
        +	movl	116(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 15
        +
        +	movl	120(%ebp),%edx
        +	movl	124(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +L000cast_enc_done:
        +	nop
        +	movl	20(%esp),%eax
        +	movl	%edi,4(%eax)
        +	movl	%esi,(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_CAST_decrypt
        +.align	4
        +_CAST_decrypt:
        +L_CAST_decrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ebp
        +	pushl	%esi
        +	pushl	%edi
        +	# Load the 2 words
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +	# Get short key flag
        +
        +	movl	128(%ebp),%eax
        +	orl	%eax,%eax
        +	jnz	L001cast_dec_skip
        +	xorl	%eax,%eax
        +	# round 15
        +
        +	movl	120(%ebp),%edx
        +	movl	124(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 14
        +
        +	movl	112(%ebp),%edx
        +	movl	116(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 13
        +
        +	movl	104(%ebp),%edx
        +	movl	108(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 12
        +
        +	movl	96(%ebp),%edx
        +	movl	100(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +L001cast_dec_skip:
        +	# round 11
        +
        +	movl	88(%ebp),%edx
        +	movl	92(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 10
        +
        +	movl	80(%ebp),%edx
        +	movl	84(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 9
        +
        +	movl	72(%ebp),%edx
        +	movl	76(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 8
        +
        +	movl	64(%ebp),%edx
        +	movl	68(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 7
        +
        +	movl	56(%ebp),%edx
        +	movl	60(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 6
        +
        +	movl	48(%ebp),%edx
        +	movl	52(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 5
        +
        +	movl	40(%ebp),%edx
        +	movl	44(%ebp),%ecx
        +	subl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 4
        +
        +	movl	32(%ebp),%edx
        +	movl	36(%ebp),%ecx
        +	xorl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 3
        +
        +	movl	24(%ebp),%edx
        +	movl	28(%ebp),%ecx
        +	addl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 2
        +
        +	movl	16(%ebp),%edx
        +	movl	20(%ebp),%ecx
        +	subl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	subl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	# round 1
        +
        +	movl	8(%ebp),%edx
        +	movl	12(%ebp),%ecx
        +	xorl	%esi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	addl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	xorl	%ebx,%ecx
        +	xorl	%ecx,%edi
        +	# round 0
        +
        +	movl	(%ebp),%edx
        +	movl	4(%ebp),%ecx
        +	addl	%edi,%edx
        +	roll	%cl,%edx
        +	movl	%edx,%ebx
        +	xorl	%ecx,%ecx
        +	movb	%dh,%cl
        +	andl	$255,%ebx
        +	shrl	$16,%edx
        +	xorl	%eax,%eax
        +	movb	%dh,%al
        +	andl	$255,%edx
        +	movl	_CAST_S_table0(,%ecx,4),%ecx
        +	movl	_CAST_S_table1(,%ebx,4),%ebx
        +	xorl	%ebx,%ecx
        +	movl	_CAST_S_table2(,%eax,4),%ebx
        +	subl	%ebx,%ecx
        +	movl	_CAST_S_table3(,%edx,4),%ebx
        +	addl	%ebx,%ecx
        +	xorl	%ecx,%esi
        +	nop
        +	movl	20(%esp),%eax
        +	movl	%edi,4(%eax)
        +	movl	%esi,(%eax)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_CAST_cbc_encrypt
        +.align	4
        +_CAST_cbc_encrypt:
        +L_CAST_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +	# getting iv ptr from parameter 4
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +	# getting encrypt flag from parameter 5
        +
        +	movl	56(%esp),%ecx
        +	# get and push parameter 3
        +
        +	movl	48(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	L002decrypt
        +	andl	$4294967288,%ebp
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	jz	L003encrypt_finish
        +L004encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_CAST_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L004encrypt_loop
        +L003encrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L005finish
        +	call	L006PIC_point
        +L006PIC_point:
        +	popl	%edx
        +	leal	L007cbc_enc_jmp_table-L006PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +L008ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +L009ej6:
        +	movb	5(%esi),%dh
        +L010ej5:
        +	movb	4(%esi),%dl
        +L011ej4:
        +	movl	(%esi),%ecx
        +	jmp	L012ejend
        +L013ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +L014ej2:
        +	movb	1(%esi),%ch
        +L015ej1:
        +	movb	(%esi),%cl
        +L012ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_CAST_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	L005finish
        +L002decrypt:
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	L016decrypt_finish
        +L017decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_CAST_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L017decrypt_loop
        +L016decrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L005finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_CAST_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	bswap	%eax
        +	bswap	%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +L018dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +L019dj6:
        +	movb	%dh,5(%edi)
        +L020dj5:
        +	movb	%dl,4(%edi)
        +L021dj4:
        +	movl	%ecx,(%edi)
        +	jmp	L022djend
        +L023dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +L024dj2:
        +	movb	%ch,1(%esi)
        +L025dj1:
        +	movb	%cl,(%esi)
        +L022djend:
        +	jmp	L005finish
        +L005finish:
        +	movl	60(%esp),%ecx
        +	addl	$24,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L007cbc_enc_jmp_table:
        +.long	0
        +.long	L015ej1-L006PIC_point
        +.long	L014ej2-L006PIC_point
        +.long	L013ej3-L006PIC_point
        +.long	L011ej4-L006PIC_point
        +.long	L010ej5-L006PIC_point
        +.long	L009ej6-L006PIC_point
        +.long	L008ej7-L006PIC_point
        +.align	6,0x90
        diff --git a/vendor/openssl/asm/x86-macosx-gas/des/crypt586.s b/vendor/openssl/asm/x86-macosx-gas/des/crypt586.s
        new file mode 100644
        index 000000000..7d0074ec2
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/des/crypt586.s
        @@ -0,0 +1,898 @@
        +.file	"crypt586.s"
        +.text
        +.globl	_fcrypt_body
        +.align	4
        +_fcrypt_body:
        +L_fcrypt_body_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the 2 words
        +
        +	xorl	%edi,%edi
        +	xorl	%esi,%esi
        +	call	L000PIC_me_up
        +L000PIC_me_up:
        +	popl	%edx
        +	movl	L_DES_SPtrans$non_lazy_ptr-L000PIC_me_up(%edx),%edx
        +	pushl	%edx
        +	movl	28(%esp),%ebp
        +	pushl	$25
        +L001start:
        +
        +	# Round 0
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	4(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 1
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	8(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	12(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 2
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	16(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	20(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 3
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	24(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	28(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 4
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	32(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	36(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 5
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	40(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	44(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 6
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	48(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	52(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 7
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	56(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	60(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 8
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	64(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	68(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 9
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	72(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	76(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 10
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	80(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	84(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 11
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	88(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	92(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 12
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	96(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	100(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 13
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	104(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	108(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +
        +	# Round 14
        +
        +	movl	36(%esp),%eax
        +	movl	%esi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%esi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	112(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	116(%ebp),%ecx
        +	xorl	%esi,%eax
        +	xorl	%esi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%edi
        +	movl	32(%esp),%ebp
        +
        +	# Round 15
        +
        +	movl	36(%esp),%eax
        +	movl	%edi,%edx
        +	shrl	$16,%edx
        +	movl	40(%esp),%ecx
        +	xorl	%edi,%edx
        +	andl	%edx,%eax
        +	andl	%ecx,%edx
        +	movl	%eax,%ebx
        +	shll	$16,%ebx
        +	movl	%edx,%ecx
        +	shll	$16,%ecx
        +	xorl	%ebx,%eax
        +	xorl	%ecx,%edx
        +	movl	120(%ebp),%ebx
        +	xorl	%ebx,%eax
        +	movl	124(%ebp),%ecx
        +	xorl	%edi,%eax
        +	xorl	%edi,%edx
        +	xorl	%ecx,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	xorl	%ebx,%ebx
        +	andl	$0xcfcfcfcf,%edx
        +	xorl	%ecx,%ecx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	movl	4(%esp),%ebp
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	movl	0x600(%ebp,%ebx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x700(%ebp,%ecx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x400(%ebp,%eax,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	0x500(%ebp,%edx,1),%ebx
        +	xorl	%ebx,%esi
        +	movl	32(%esp),%ebp
        +	movl	(%esp),%ebx
        +	movl	%edi,%eax
        +	decl	%ebx
        +	movl	%esi,%edi
        +	movl	%eax,%esi
        +	movl	%ebx,(%esp)
        +	jnz	L001start
        +
        +	# FP
        +
        +	movl	28(%esp),%edx
        +	rorl	$1,%edi
        +	movl	%esi,%eax
        +	xorl	%edi,%esi
        +	andl	$0xaaaaaaaa,%esi
        +	xorl	%esi,%eax
        +	xorl	%esi,%edi
        +
        +	roll	$23,%eax
        +	movl	%eax,%esi
        +	xorl	%edi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%esi
        +	xorl	%eax,%edi
        +
        +	roll	$10,%esi
        +	movl	%esi,%eax
        +	xorl	%edi,%esi
        +	andl	$0x33333333,%esi
        +	xorl	%esi,%eax
        +	xorl	%esi,%edi
        +
        +	roll	$18,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xfff0000f,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	roll	$12,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xf0f0f0f0,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%edx)
        +	movl	%edi,4(%edx)
        +	addl	$8,%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.section __IMPORT,__pointers,non_lazy_symbol_pointers
        +L_DES_SPtrans$non_lazy_ptr:
        +.indirect_symbol	_DES_SPtrans
        +.long	0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/des/des-586.s b/vendor/openssl/asm/x86-macosx-gas/des/des-586.s
        new file mode 100644
        index 000000000..f9e0ad333
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/des/des-586.s
        @@ -0,0 +1,1873 @@
        +.file	"des-586.s"
        +.text
        +.globl	_DES_SPtrans
        +.align	4
        +__x86_DES_encrypt:
        +	pushl	%ecx
        +	# Round 0
        +
        +	movl	(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	4(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 1
        +
        +	movl	8(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	12(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 2
        +
        +	movl	16(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	20(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 3
        +
        +	movl	24(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	28(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 4
        +
        +	movl	32(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	36(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 5
        +
        +	movl	40(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	44(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 6
        +
        +	movl	48(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	52(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 7
        +
        +	movl	56(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	60(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 8
        +
        +	movl	64(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	68(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 9
        +
        +	movl	72(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	76(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 10
        +
        +	movl	80(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	84(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 11
        +
        +	movl	88(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	92(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 12
        +
        +	movl	96(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	100(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 13
        +
        +	movl	104(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	108(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 14
        +
        +	movl	112(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	116(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 15
        +
        +	movl	120(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	124(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	addl	$4,%esp
        +	ret
        +.align	4
        +__x86_DES_decrypt:
        +	pushl	%ecx
        +	# Round 15
        +
        +	movl	120(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	124(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 14
        +
        +	movl	112(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	116(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 13
        +
        +	movl	104(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	108(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 12
        +
        +	movl	96(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	100(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 11
        +
        +	movl	88(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	92(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 10
        +
        +	movl	80(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	84(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 9
        +
        +	movl	72(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	76(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 8
        +
        +	movl	64(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	68(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 7
        +
        +	movl	56(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	60(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 6
        +
        +	movl	48(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	52(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 5
        +
        +	movl	40(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	44(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 4
        +
        +	movl	32(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	36(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 3
        +
        +	movl	24(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	28(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 2
        +
        +	movl	16(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	20(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	# Round 1
        +
        +	movl	8(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	12(%ecx),%edx
        +	xorl	%esi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%esi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%edi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%edi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%edi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%edi
        +	xorl	0x700(%ebp,%ecx,1),%edi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%edi
        +	xorl	0x500(%ebp,%edx,1),%edi
        +	# Round 0
        +
        +	movl	(%ecx),%eax
        +	xorl	%ebx,%ebx
        +	movl	4(%ecx),%edx
        +	xorl	%edi,%eax
        +	xorl	%ecx,%ecx
        +	xorl	%edi,%edx
        +	andl	$0xfcfcfcfc,%eax
        +	andl	$0xcfcfcfcf,%edx
        +	movb	%al,%bl
        +	movb	%ah,%cl
        +	rorl	$4,%edx
        +	xorl	(%ebp,%ebx,1),%esi
        +	movb	%dl,%bl
        +	xorl	0x200(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	shrl	$16,%eax
        +	xorl	0x100(%ebp,%ebx,1),%esi
        +	movb	%ah,%bl
        +	shrl	$16,%edx
        +	xorl	0x300(%ebp,%ecx,1),%esi
        +	movb	%dh,%cl
        +	andl	$0xff,%eax
        +	andl	$0xff,%edx
        +	xorl	0x600(%ebp,%ebx,1),%esi
        +	xorl	0x700(%ebp,%ecx,1),%esi
        +	movl	(%esp),%ecx
        +	xorl	0x400(%ebp,%eax,1),%esi
        +	xorl	0x500(%ebp,%edx,1),%esi
        +	addl	$4,%esp
        +	ret
        +.globl	_DES_encrypt1
        +.align	4
        +_DES_encrypt1:
        +L_DES_encrypt1_begin:
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the 2 words
        +
        +	movl	12(%esp),%esi
        +	xorl	%ecx,%ecx
        +	pushl	%ebx
        +	pushl	%ebp
        +	movl	(%esi),%eax
        +	movl	28(%esp),%ebx
        +	movl	4(%esi),%edi
        +
        +	# IP
        +
        +	roll	$4,%eax
        +	movl	%eax,%esi
        +	xorl	%edi,%eax
        +	andl	$0xf0f0f0f0,%eax
        +	xorl	%eax,%esi
        +	xorl	%eax,%edi
        +
        +	roll	$20,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xfff0000f,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$14,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x33333333,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$22,%esi
        +	movl	%esi,%eax
        +	xorl	%edi,%esi
        +	andl	$0x03fc03fc,%esi
        +	xorl	%esi,%eax
        +	xorl	%esi,%edi
        +
        +	roll	$9,%eax
        +	movl	%eax,%esi
        +	xorl	%edi,%eax
        +	andl	$0xaaaaaaaa,%eax
        +	xorl	%eax,%esi
        +	xorl	%eax,%edi
        +
        +	roll	$1,%edi
        +	call	L000pic_point
        +L000pic_point:
        +	popl	%ebp
        +	leal	_DES_SPtrans-L000pic_point(%ebp),%ebp
        +	movl	24(%esp),%ecx
        +	cmpl	$0,%ebx
        +	je	L001decrypt
        +	call	__x86_DES_encrypt
        +	jmp	L002done
        +L001decrypt:
        +	call	__x86_DES_decrypt
        +L002done:
        +
        +	# FP
        +
        +	movl	20(%esp),%edx
        +	rorl	$1,%esi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$23,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$10,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$18,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	roll	$12,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%edx)
        +	movl	%esi,4(%edx)
        +	popl	%ebp
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.globl	_DES_encrypt2
        +.align	4
        +_DES_encrypt2:
        +L_DES_encrypt2_begin:
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the 2 words
        +
        +	movl	12(%esp),%eax
        +	xorl	%ecx,%ecx
        +	pushl	%ebx
        +	pushl	%ebp
        +	movl	(%eax),%esi
        +	movl	28(%esp),%ebx
        +	roll	$3,%esi
        +	movl	4(%eax),%edi
        +	roll	$3,%edi
        +	call	L003pic_point
        +L003pic_point:
        +	popl	%ebp
        +	leal	_DES_SPtrans-L003pic_point(%ebp),%ebp
        +	movl	24(%esp),%ecx
        +	cmpl	$0,%ebx
        +	je	L004decrypt
        +	call	__x86_DES_encrypt
        +	jmp	L005done
        +L004decrypt:
        +	call	__x86_DES_decrypt
        +L005done:
        +
        +	# Fixup
        +
        +	rorl	$3,%edi
        +	movl	20(%esp),%eax
        +	rorl	$3,%esi
        +	movl	%edi,(%eax)
        +	movl	%esi,4(%eax)
        +	popl	%ebp
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	ret
        +.globl	_DES_encrypt3
        +.align	4
        +_DES_encrypt3:
        +L_DES_encrypt3_begin:
        +	pushl	%ebx
        +	movl	8(%esp),%ebx
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the data words
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +	subl	$12,%esp
        +
        +	# IP
        +
        +	roll	$4,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	roll	$20,%esi
        +	movl	%esi,%edi
        +	xorl	%edx,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%edx
        +
        +	roll	$14,%edi
        +	movl	%edi,%esi
        +	xorl	%edx,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%edx
        +
        +	roll	$22,%edx
        +	movl	%edx,%edi
        +	xorl	%esi,%edx
        +	andl	$0x03fc03fc,%edx
        +	xorl	%edx,%edi
        +	xorl	%edx,%esi
        +
        +	roll	$9,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	rorl	$3,%edx
        +	rorl	$2,%esi
        +	movl	%esi,4(%ebx)
        +	movl	36(%esp),%eax
        +	movl	%edx,(%ebx)
        +	movl	40(%esp),%edi
        +	movl	44(%esp),%esi
        +	movl	$1,8(%esp)
        +	movl	%eax,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	L_DES_encrypt2_begin
        +	movl	$0,8(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	L_DES_encrypt2_begin
        +	movl	$1,8(%esp)
        +	movl	%esi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	L_DES_encrypt2_begin
        +	addl	$12,%esp
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +
        +	# FP
        +
        +	roll	$2,%esi
        +	roll	$3,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$23,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$10,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$18,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	roll	$12,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%ebx)
        +	movl	%esi,4(%ebx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	popl	%ebx
        +	ret
        +.globl	_DES_decrypt3
        +.align	4
        +_DES_decrypt3:
        +L_DES_decrypt3_begin:
        +	pushl	%ebx
        +	movl	8(%esp),%ebx
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +
        +	# Load the data words
        +
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +	subl	$12,%esp
        +
        +	# IP
        +
        +	roll	$4,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	roll	$20,%esi
        +	movl	%esi,%edi
        +	xorl	%edx,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%edx
        +
        +	roll	$14,%edi
        +	movl	%edi,%esi
        +	xorl	%edx,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%edx
        +
        +	roll	$22,%edx
        +	movl	%edx,%edi
        +	xorl	%esi,%edx
        +	andl	$0x03fc03fc,%edx
        +	xorl	%edx,%edi
        +	xorl	%edx,%esi
        +
        +	roll	$9,%edi
        +	movl	%edi,%edx
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%edx
        +	xorl	%edi,%esi
        +
        +	rorl	$3,%edx
        +	rorl	$2,%esi
        +	movl	%esi,4(%ebx)
        +	movl	36(%esp),%esi
        +	movl	%edx,(%ebx)
        +	movl	40(%esp),%edi
        +	movl	44(%esp),%eax
        +	movl	$0,8(%esp)
        +	movl	%eax,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	L_DES_encrypt2_begin
        +	movl	$1,8(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	L_DES_encrypt2_begin
        +	movl	$0,8(%esp)
        +	movl	%esi,4(%esp)
        +	movl	%ebx,(%esp)
        +	call	L_DES_encrypt2_begin
        +	addl	$12,%esp
        +	movl	(%ebx),%edi
        +	movl	4(%ebx),%esi
        +
        +	# FP
        +
        +	roll	$2,%esi
        +	roll	$3,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0xaaaaaaaa,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$23,%eax
        +	movl	%eax,%edi
        +	xorl	%esi,%eax
        +	andl	$0x03fc03fc,%eax
        +	xorl	%eax,%edi
        +	xorl	%eax,%esi
        +
        +	roll	$10,%edi
        +	movl	%edi,%eax
        +	xorl	%esi,%edi
        +	andl	$0x33333333,%edi
        +	xorl	%edi,%eax
        +	xorl	%edi,%esi
        +
        +	roll	$18,%esi
        +	movl	%esi,%edi
        +	xorl	%eax,%esi
        +	andl	$0xfff0000f,%esi
        +	xorl	%esi,%edi
        +	xorl	%esi,%eax
        +
        +	roll	$12,%edi
        +	movl	%edi,%esi
        +	xorl	%eax,%edi
        +	andl	$0xf0f0f0f0,%edi
        +	xorl	%edi,%esi
        +	xorl	%edi,%eax
        +
        +	rorl	$4,%eax
        +	movl	%eax,(%ebx)
        +	movl	%esi,4(%ebx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	popl	%ebx
        +	ret
        +.globl	_DES_ncbc_encrypt
        +.align	4
        +_DES_ncbc_encrypt:
        +L_DES_ncbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +	# getting iv ptr from parameter 4
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +	# getting encrypt flag from parameter 5
        +
        +	movl	56(%esp),%ecx
        +	# get and push parameter 5
        +
        +	pushl	%ecx
        +	# get and push parameter 3
        +
        +	movl	52(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	L006decrypt
        +	andl	$4294967288,%ebp
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	jz	L007encrypt_finish
        +L008encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L008encrypt_loop
        +L007encrypt_finish:
        +	movl	56(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L009finish
        +	call	L010PIC_point
        +L010PIC_point:
        +	popl	%edx
        +	leal	L011cbc_enc_jmp_table-L010PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +L012ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +L013ej6:
        +	movb	5(%esi),%dh
        +L014ej5:
        +	movb	4(%esi),%dl
        +L015ej4:
        +	movl	(%esi),%ecx
        +	jmp	L016ejend
        +L017ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +L018ej2:
        +	movb	1(%esi),%ch
        +L019ej1:
        +	movb	(%esi),%cl
        +L016ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	L009finish
        +L006decrypt:
        +	andl	$4294967288,%ebp
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%ebx
        +	jz	L020decrypt_finish
        +L021decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	20(%esp),%ecx
        +	movl	24(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,20(%esp)
        +	movl	%ebx,24(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L021decrypt_loop
        +L020decrypt_finish:
        +	movl	56(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L009finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,12(%esp)
        +	movl	%ebx,16(%esp)
        +	call	L_DES_encrypt1_begin
        +	movl	12(%esp),%eax
        +	movl	16(%esp),%ebx
        +	movl	20(%esp),%ecx
        +	movl	24(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +L022dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +L023dj6:
        +	movb	%dh,5(%edi)
        +L024dj5:
        +	movb	%dl,4(%edi)
        +L025dj4:
        +	movl	%ecx,(%edi)
        +	jmp	L026djend
        +L027dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +L028dj2:
        +	movb	%ch,1(%esi)
        +L029dj1:
        +	movb	%cl,(%esi)
        +L026djend:
        +	jmp	L009finish
        +L009finish:
        +	movl	64(%esp),%ecx
        +	addl	$28,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L011cbc_enc_jmp_table:
        +.long	0
        +.long	L019ej1-L010PIC_point
        +.long	L018ej2-L010PIC_point
        +.long	L017ej3-L010PIC_point
        +.long	L015ej4-L010PIC_point
        +.long	L014ej5-L010PIC_point
        +.long	L013ej6-L010PIC_point
        +.long	L012ej7-L010PIC_point
        +.align	6,0x90
        +.globl	_DES_ede3_cbc_encrypt
        +.align	4
        +_DES_ede3_cbc_encrypt:
        +L_DES_ede3_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +	# getting iv ptr from parameter 6
        +
        +	movl	44(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +	# getting encrypt flag from parameter 7
        +
        +	movl	64(%esp),%ecx
        +	# get and push parameter 5
        +
        +	movl	56(%esp),%eax
        +	pushl	%eax
        +	# get and push parameter 4
        +
        +	movl	56(%esp),%eax
        +	pushl	%eax
        +	# get and push parameter 3
        +
        +	movl	56(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	L030decrypt
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	L031encrypt_finish
        +L032encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	L_DES_encrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L032encrypt_loop
        +L031encrypt_finish:
        +	movl	60(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L033finish
        +	call	L034PIC_point
        +L034PIC_point:
        +	popl	%edx
        +	leal	L035cbc_enc_jmp_table-L034PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +L036ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +L037ej6:
        +	movb	5(%esi),%dh
        +L038ej5:
        +	movb	4(%esi),%dl
        +L039ej4:
        +	movl	(%esi),%ecx
        +	jmp	L040ejend
        +L041ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +L042ej2:
        +	movb	1(%esi),%ch
        +L043ej1:
        +	movb	(%esi),%cl
        +L040ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	L_DES_encrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	L033finish
        +L030decrypt:
        +	andl	$4294967288,%ebp
        +	movl	24(%esp),%eax
        +	movl	28(%esp),%ebx
        +	jz	L044decrypt_finish
        +L045decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	L_DES_decrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%ecx
        +	movl	28(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,24(%esp)
        +	movl	%ebx,28(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L045decrypt_loop
        +L044decrypt_finish:
        +	movl	60(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L033finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	call	L_DES_decrypt3_begin
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	movl	24(%esp),%ecx
        +	movl	28(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +L046dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +L047dj6:
        +	movb	%dh,5(%edi)
        +L048dj5:
        +	movb	%dl,4(%edi)
        +L049dj4:
        +	movl	%ecx,(%edi)
        +	jmp	L050djend
        +L051dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +L052dj2:
        +	movb	%ch,1(%esi)
        +L053dj1:
        +	movb	%cl,(%esi)
        +L050djend:
        +	jmp	L033finish
        +L033finish:
        +	movl	76(%esp),%ecx
        +	addl	$32,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L035cbc_enc_jmp_table:
        +.long	0
        +.long	L043ej1-L034PIC_point
        +.long	L042ej2-L034PIC_point
        +.long	L041ej3-L034PIC_point
        +.long	L039ej4-L034PIC_point
        +.long	L038ej5-L034PIC_point
        +.long	L037ej6-L034PIC_point
        +.long	L036ej7-L034PIC_point
        +.align	6,0x90
        +.align	6,0x90
        +_DES_SPtrans:
        +.long	34080768,524288,33554434,34080770
        +.long	33554432,526338,524290,33554434
        +.long	526338,34080768,34078720,2050
        +.long	33556482,33554432,0,524290
        +.long	524288,2,33556480,526336
        +.long	34080770,34078720,2050,33556480
        +.long	2,2048,526336,34078722
        +.long	2048,33556482,34078722,0
        +.long	0,34080770,33556480,524290
        +.long	34080768,524288,2050,33556480
        +.long	34078722,2048,526336,33554434
        +.long	526338,2,33554434,34078720
        +.long	34080770,526336,34078720,33556482
        +.long	33554432,2050,524290,0
        +.long	524288,33554432,33556482,34080768
        +.long	2,34078722,2048,526338
        +.long	1074823184,0,1081344,1074790400
        +.long	1073741840,32784,1073774592,1081344
        +.long	32768,1074790416,16,1073774592
        +.long	1048592,1074823168,1074790400,16
        +.long	1048576,1073774608,1074790416,32768
        +.long	1081360,1073741824,0,1048592
        +.long	1073774608,1081360,1074823168,1073741840
        +.long	1073741824,1048576,32784,1074823184
        +.long	1048592,1074823168,1073774592,1081360
        +.long	1074823184,1048592,1073741840,0
        +.long	1073741824,32784,1048576,1074790416
        +.long	32768,1073741824,1081360,1073774608
        +.long	1074823168,32768,0,1073741840
        +.long	16,1074823184,1081344,1074790400
        +.long	1074790416,1048576,32784,1073774592
        +.long	1073774608,16,1074790400,1081344
        +.long	67108865,67371264,256,67109121
        +.long	262145,67108864,67109121,262400
        +.long	67109120,262144,67371008,1
        +.long	67371265,257,1,67371009
        +.long	0,262145,67371264,256
        +.long	257,67371265,262144,67108865
        +.long	67371009,67109120,262401,67371008
        +.long	262400,0,67108864,262401
        +.long	67371264,256,1,262144
        +.long	257,262145,67371008,67109121
        +.long	0,67371264,262400,67371009
        +.long	262145,67108864,67371265,1
        +.long	262401,67108865,67108864,67371265
        +.long	262144,67109120,67109121,262400
        +.long	67109120,0,67371009,257
        +.long	67108865,262401,256,67371008
        +.long	4198408,268439552,8,272633864
        +.long	0,272629760,268439560,4194312
        +.long	272633856,268435464,268435456,4104
        +.long	268435464,4198408,4194304,268435456
        +.long	272629768,4198400,4096,8
        +.long	4198400,268439560,272629760,4096
        +.long	4104,0,4194312,272633856
        +.long	268439552,272629768,272633864,4194304
        +.long	272629768,4104,4194304,268435464
        +.long	4198400,268439552,8,272629760
        +.long	268439560,0,4096,4194312
        +.long	0,272629768,272633856,4096
        +.long	268435456,272633864,4198408,4194304
        +.long	272633864,8,268439552,4198408
        +.long	4194312,4198400,272629760,268439560
        +.long	4104,268435456,268435464,272633856
        +.long	134217728,65536,1024,134284320
        +.long	134283296,134218752,66592,134283264
        +.long	65536,32,134217760,66560
        +.long	134218784,134283296,134284288,0
        +.long	66560,134217728,65568,1056
        +.long	134218752,66592,0,134217760
        +.long	32,134218784,134284320,65568
        +.long	134283264,1024,1056,134284288
        +.long	134284288,134218784,65568,134283264
        +.long	65536,32,134217760,134218752
        +.long	134217728,66560,134284320,0
        +.long	66592,134217728,1024,65568
        +.long	134218784,1024,0,134284320
        +.long	134283296,134284288,1056,65536
        +.long	66560,134283296,134218752,1056
        +.long	32,66592,134283264,134217760
        +.long	2147483712,2097216,0,2149588992
        +.long	2097216,8192,2147491904,2097152
        +.long	8256,2149589056,2105344,2147483648
        +.long	2147491840,2147483712,2149580800,2105408
        +.long	2097152,2147491904,2149580864,0
        +.long	8192,64,2149588992,2149580864
        +.long	2149589056,2149580800,2147483648,8256
        +.long	64,2105344,2105408,2147491840
        +.long	8256,2147483648,2147491840,2105408
        +.long	2149588992,2097216,0,2147491840
        +.long	2147483648,8192,2149580864,2097152
        +.long	2097216,2149589056,2105344,64
        +.long	2149589056,2105344,2097152,2147491904
        +.long	2147483712,2149580800,2105408,0
        +.long	8192,2147483712,2147491904,2149588992
        +.long	2149580800,8256,64,2149580864
        +.long	16384,512,16777728,16777220
        +.long	16794116,16388,16896,0
        +.long	16777216,16777732,516,16793600
        +.long	4,16794112,16793600,516
        +.long	16777732,16384,16388,16794116
        +.long	0,16777728,16777220,16896
        +.long	16793604,16900,16794112,4
        +.long	16900,16793604,512,16777216
        +.long	16900,16793600,16793604,516
        +.long	16384,512,16777216,16793604
        +.long	16777732,16900,16896,0
        +.long	512,16777220,4,16777728
        +.long	0,16777732,16777728,16896
        +.long	516,16384,16794116,16777216
        +.long	16794112,4,16388,16794116
        +.long	16777220,16794112,16793600,16388
        +.long	545259648,545390592,131200,0
        +.long	537001984,8388736,545259520,545390720
        +.long	128,536870912,8519680,131200
        +.long	8519808,537002112,536871040,545259520
        +.long	131072,8519808,8388736,537001984
        +.long	545390720,536871040,0,8519680
        +.long	536870912,8388608,537002112,545259648
        +.long	8388608,131072,545390592,128
        +.long	8388608,131072,536871040,545390720
        +.long	131200,536870912,0,8519680
        +.long	545259648,537002112,537001984,8388736
        +.long	545390592,128,8388736,537001984
        +.long	545390720,8388608,545259520,536871040
        +.long	8519680,131200,537002112,545259520
        +.long	128,545390592,8519808,0
        +.long	536870912,545259648,131072,8519808
        diff --git a/vendor/openssl/asm/x86-macosx-gas/md5/md5-586.s b/vendor/openssl/asm/x86-macosx-gas/md5/md5-586.s
        new file mode 100644
        index 000000000..5336574c8
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/md5/md5-586.s
        @@ -0,0 +1,745 @@
        +.file	"../openssl/crypto/md5/asm/md5-586.s"
        +.text
        +.globl	_md5_block_asm_data_order
        +.align	4
        +_md5_block_asm_data_order:
        +L_md5_block_asm_data_order_begin:
        +	pushl	%esi
        +	pushl	%edi
        +	movl	12(%esp),%edi
        +	movl	16(%esp),%esi
        +	movl	20(%esp),%ecx
        +	pushl	%ebp
        +	shll	$6,%ecx
        +	pushl	%ebx
        +	addl	%esi,%ecx
        +	subl	$64,%ecx
        +	movl	(%edi),%eax
        +	pushl	%ecx
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +L000start:
        +
        +	# R0 section
        +
        +	movl	%ecx,%edi
        +	movl	(%esi),%ebp
        +	# R0 0
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	3614090360(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	4(%esi),%ebp
        +	addl	%ebx,%eax
        +	# R0 1
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	3905402710(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	8(%esi),%ebp
        +	addl	%eax,%edx
        +	# R0 2
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	606105819(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	12(%esi),%ebp
        +	addl	%edx,%ecx
        +	# R0 3
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	3250441966(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	16(%esi),%ebp
        +	addl	%ecx,%ebx
        +	# R0 4
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	4118548399(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	20(%esi),%ebp
        +	addl	%ebx,%eax
        +	# R0 5
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	1200080426(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	24(%esi),%ebp
        +	addl	%eax,%edx
        +	# R0 6
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	2821735955(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	28(%esi),%ebp
        +	addl	%edx,%ecx
        +	# R0 7
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	4249261313(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	32(%esi),%ebp
        +	addl	%ecx,%ebx
        +	# R0 8
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	1770035416(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	36(%esi),%ebp
        +	addl	%ebx,%eax
        +	# R0 9
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	2336552879(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	40(%esi),%ebp
        +	addl	%eax,%edx
        +	# R0 10
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	4294925233(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	44(%esi),%ebp
        +	addl	%edx,%ecx
        +	# R0 11
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	2304563134(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	48(%esi),%ebp
        +	addl	%ecx,%ebx
        +	# R0 12
        +
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	leal	1804603682(%eax,%ebp,1),%eax
        +	xorl	%edx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$7,%eax
        +	movl	52(%esi),%ebp
        +	addl	%ebx,%eax
        +	# R0 13
        +
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	leal	4254626195(%edx,%ebp,1),%edx
        +	xorl	%ecx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$12,%edx
        +	movl	56(%esi),%ebp
        +	addl	%eax,%edx
        +	# R0 14
        +
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	leal	2792965006(%ecx,%ebp,1),%ecx
        +	xorl	%ebx,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$17,%ecx
        +	movl	60(%esi),%ebp
        +	addl	%edx,%ecx
        +	# R0 15
        +
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	leal	1236535329(%ebx,%ebp,1),%ebx
        +	xorl	%eax,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$22,%ebx
        +	movl	4(%esi),%ebp
        +	addl	%ecx,%ebx
        +
        +	# R1 section
        +
        +	# R1 16
        +
        +	leal	4129170786(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	24(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	# R1 17
        +
        +	leal	3225465664(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	44(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	# R1 18
        +
        +	leal	643717713(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	# R1 19
        +
        +	leal	3921069994(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	20(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	# R1 20
        +
        +	leal	3593408605(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	40(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	# R1 21
        +
        +	leal	38016083(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	60(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	# R1 22
        +
        +	leal	3634488961(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	16(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	# R1 23
        +
        +	leal	3889429448(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	36(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	# R1 24
        +
        +	leal	568446438(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	56(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	# R1 25
        +
        +	leal	3275163606(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	12(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	# R1 26
        +
        +	leal	4107603335(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	32(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	# R1 27
        +
        +	leal	1163531501(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	52(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +	# R1 28
        +
        +	leal	2850285829(%eax,%ebp,1),%eax
        +	xorl	%ebx,%edi
        +	andl	%edx,%edi
        +	movl	8(%esi),%ebp
        +	xorl	%ecx,%edi
        +	addl	%edi,%eax
        +	movl	%ebx,%edi
        +	roll	$5,%eax
        +	addl	%ebx,%eax
        +	# R1 29
        +
        +	leal	4243563512(%edx,%ebp,1),%edx
        +	xorl	%eax,%edi
        +	andl	%ecx,%edi
        +	movl	28(%esi),%ebp
        +	xorl	%ebx,%edi
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$9,%edx
        +	addl	%eax,%edx
        +	# R1 30
        +
        +	leal	1735328473(%ecx,%ebp,1),%ecx
        +	xorl	%edx,%edi
        +	andl	%ebx,%edi
        +	movl	48(%esi),%ebp
        +	xorl	%eax,%edi
        +	addl	%edi,%ecx
        +	movl	%edx,%edi
        +	roll	$14,%ecx
        +	addl	%edx,%ecx
        +	# R1 31
        +
        +	leal	2368359562(%ebx,%ebp,1),%ebx
        +	xorl	%ecx,%edi
        +	andl	%eax,%edi
        +	movl	20(%esi),%ebp
        +	xorl	%edx,%edi
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$20,%ebx
        +	addl	%ecx,%ebx
        +
        +	# R2 section
        +
        +	# R2 32
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	4294588738(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	32(%esi),%ebp
        +	movl	%ebx,%edi
        +	# R2 33
        +
        +	leal	2272392833(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	44(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +	# R2 34
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	1839030562(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	56(%esi),%ebp
        +	movl	%edx,%edi
        +	# R2 35
        +
        +	leal	4259657740(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	4(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +	# R2 36
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	2763975236(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	16(%esi),%ebp
        +	movl	%ebx,%edi
        +	# R2 37
        +
        +	leal	1272893353(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	28(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +	# R2 38
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	4139469664(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	40(%esi),%ebp
        +	movl	%edx,%edi
        +	# R2 39
        +
        +	leal	3200236656(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	52(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +	# R2 40
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	681279174(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	(%esi),%ebp
        +	movl	%ebx,%edi
        +	# R2 41
        +
        +	leal	3936430074(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	12(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +	# R2 42
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	3572445317(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	24(%esi),%ebp
        +	movl	%edx,%edi
        +	# R2 43
        +
        +	leal	76029189(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	36(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	%ecx,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +	# R2 44
        +
        +	xorl	%edx,%edi
        +	xorl	%ebx,%edi
        +	leal	3654602809(%eax,%ebp,1),%eax
        +	addl	%edi,%eax
        +	roll	$4,%eax
        +	movl	48(%esi),%ebp
        +	movl	%ebx,%edi
        +	# R2 45
        +
        +	leal	3873151461(%edx,%ebp,1),%edx
        +	addl	%ebx,%eax
        +	xorl	%ecx,%edi
        +	xorl	%eax,%edi
        +	movl	60(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	%eax,%edi
        +	roll	$11,%edx
        +	addl	%eax,%edx
        +	# R2 46
        +
        +	xorl	%ebx,%edi
        +	xorl	%edx,%edi
        +	leal	530742520(%ecx,%ebp,1),%ecx
        +	addl	%edi,%ecx
        +	roll	$16,%ecx
        +	movl	8(%esi),%ebp
        +	movl	%edx,%edi
        +	# R2 47
        +
        +	leal	3299628645(%ebx,%ebp,1),%ebx
        +	addl	%edx,%ecx
        +	xorl	%eax,%edi
        +	xorl	%ecx,%edi
        +	movl	(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$23,%ebx
        +	addl	%ecx,%ebx
        +
        +	# R3 section
        +
        +	# R3 48
        +
        +	xorl	%edx,%edi
        +	orl	%ebx,%edi
        +	leal	4096336452(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	28(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +	# R3 49
        +
        +	orl	%eax,%edi
        +	leal	1126891415(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	56(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +	# R3 50
        +
        +	orl	%edx,%edi
        +	leal	2878612391(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	20(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	# R3 51
        +
        +	orl	%ecx,%edi
        +	leal	4237533241(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	48(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$21,%ebx
        +	xorl	%edx,%edi
        +	addl	%ecx,%ebx
        +	# R3 52
        +
        +	orl	%ebx,%edi
        +	leal	1700485571(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	12(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +	# R3 53
        +
        +	orl	%eax,%edi
        +	leal	2399980690(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	40(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +	# R3 54
        +
        +	orl	%edx,%edi
        +	leal	4293915773(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	4(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	# R3 55
        +
        +	orl	%ecx,%edi
        +	leal	2240044497(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	32(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$21,%ebx
        +	xorl	%edx,%edi
        +	addl	%ecx,%ebx
        +	# R3 56
        +
        +	orl	%ebx,%edi
        +	leal	1873313359(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	60(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +	# R3 57
        +
        +	orl	%eax,%edi
        +	leal	4264355552(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	24(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +	# R3 58
        +
        +	orl	%edx,%edi
        +	leal	2734768916(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	52(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	# R3 59
        +
        +	orl	%ecx,%edi
        +	leal	1309151649(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	16(%esi),%ebp
        +	addl	%edi,%ebx
        +	movl	$-1,%edi
        +	roll	$21,%ebx
        +	xorl	%edx,%edi
        +	addl	%ecx,%ebx
        +	# R3 60
        +
        +	orl	%ebx,%edi
        +	leal	4149444226(%eax,%ebp,1),%eax
        +	xorl	%ecx,%edi
        +	movl	44(%esi),%ebp
        +	addl	%edi,%eax
        +	movl	$-1,%edi
        +	roll	$6,%eax
        +	xorl	%ecx,%edi
        +	addl	%ebx,%eax
        +	# R3 61
        +
        +	orl	%eax,%edi
        +	leal	3174756917(%edx,%ebp,1),%edx
        +	xorl	%ebx,%edi
        +	movl	8(%esi),%ebp
        +	addl	%edi,%edx
        +	movl	$-1,%edi
        +	roll	$10,%edx
        +	xorl	%ebx,%edi
        +	addl	%eax,%edx
        +	# R3 62
        +
        +	orl	%edx,%edi
        +	leal	718787259(%ecx,%ebp,1),%ecx
        +	xorl	%eax,%edi
        +	movl	36(%esi),%ebp
        +	addl	%edi,%ecx
        +	movl	$-1,%edi
        +	roll	$15,%ecx
        +	xorl	%eax,%edi
        +	addl	%edx,%ecx
        +	# R3 63
        +
        +	orl	%ecx,%edi
        +	leal	3951481745(%ebx,%ebp,1),%ebx
        +	xorl	%edx,%edi
        +	movl	24(%esp),%ebp
        +	addl	%edi,%ebx
        +	addl	$64,%esi
        +	roll	$21,%ebx
        +	movl	(%ebp),%edi
        +	addl	%ecx,%ebx
        +	addl	%edi,%eax
        +	movl	4(%ebp),%edi
        +	addl	%edi,%ebx
        +	movl	8(%ebp),%edi
        +	addl	%edi,%ecx
        +	movl	12(%ebp),%edi
        +	addl	%edi,%edx
        +	movl	%eax,(%ebp)
        +	movl	%ebx,4(%ebp)
        +	movl	(%esp),%edi
        +	movl	%ecx,8(%ebp)
        +	movl	%edx,12(%ebp)
        +	cmpl	%esi,%edi
        +	jae	L000start
        +	popl	%eax
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        diff --git a/vendor/openssl/asm/x86-macosx-gas/rc4/rc4-586.s b/vendor/openssl/asm/x86-macosx-gas/rc4/rc4-586.s
        new file mode 100644
        index 000000000..882a02d74
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/rc4/rc4-586.s
        @@ -0,0 +1,379 @@
        +.file	"rc4-586.s"
        +.text
        +.globl	_RC4
        +.align	4
        +_RC4:
        +L_RC4_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%edx
        +	movl	28(%esp),%esi
        +	movl	32(%esp),%ebp
        +	xorl	%eax,%eax
        +	xorl	%ebx,%ebx
        +	cmpl	$0,%edx
        +	je	L000abort
        +	movb	(%edi),%al
        +	movb	4(%edi),%bl
        +	addl	$8,%edi
        +	leal	(%esi,%edx,1),%ecx
        +	subl	%esi,%ebp
        +	movl	%ecx,24(%esp)
        +	incb	%al
        +	cmpl	$-1,256(%edi)
        +	je	L001RC4_CHAR
        +	movl	(%edi,%eax,4),%ecx
        +	andl	$-4,%edx
        +	jz	L002loop1
        +	testl	$-8,%edx
        +	movl	%ebp,32(%esp)
        +	jz	L003go4loop4
        +	call	L004PIC_me_up
        +L004PIC_me_up:
        +	popl	%ebp
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L004PIC_me_up(%ebp),%ebp
        +	btl	$26,(%ebp)
        +	jnc	L003go4loop4
        +	movl	32(%esp),%ebp
        +	andl	$-8,%edx
        +	leal	-8(%esi,%edx,1),%edx
        +	movl	%edx,-4(%edi)
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	movq	(%esi),%mm0
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm2
        +	jmp	L005loop_mmx_enter
        +.align	4,0x90
        +L006loop_mmx:
        +	addb	%cl,%bl
        +	psllq	$56,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movq	(%esi),%mm0
        +	movq	%mm2,-8(%ebp,%esi,1)
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm2
        +L005loop_mmx_enter:
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm0,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$8,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$16,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$24,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$32,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$40,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	addb	%cl,%bl
        +	psllq	$48,%mm1
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	incl	%eax
        +	addl	%ecx,%edx
        +	movzbl	%al,%eax
        +	movzbl	%dl,%edx
        +	pxor	%mm1,%mm2
        +	movl	(%edi,%eax,4),%ecx
        +	movd	(%edi,%edx,4),%mm1
        +	movl	%ebx,%edx
        +	xorl	%ebx,%ebx
        +	movb	%dl,%bl
        +	cmpl	-4(%edi),%esi
        +	leal	8(%esi),%esi
        +	jb	L006loop_mmx
        +	psllq	$56,%mm1
        +	pxor	%mm1,%mm2
        +	movq	%mm2,-8(%ebp,%esi,1)
        +	emms
        +	cmpl	24(%esp),%esi
        +	je	L007done
        +	jmp	L002loop1
        +.align	4,0x90
        +L003go4loop4:
        +	leal	-4(%esi,%edx,1),%edx
        +	movl	%edx,28(%esp)
        +L008loop4:
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	movl	(%edi,%eax,4),%ecx
        +	movl	(%edi,%edx,4),%ebp
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	rorl	$8,%ebp
        +	movl	(%edi,%eax,4),%ecx
        +	orl	(%edi,%edx,4),%ebp
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	rorl	$8,%ebp
        +	movl	(%edi,%eax,4),%ecx
        +	orl	(%edi,%edx,4),%ebp
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	rorl	$8,%ebp
        +	movl	32(%esp),%ecx
        +	orl	(%edi,%edx,4),%ebp
        +	rorl	$8,%ebp
        +	xorl	(%esi),%ebp
        +	cmpl	28(%esp),%esi
        +	movl	%ebp,(%ecx,%esi,1)
        +	leal	4(%esi),%esi
        +	movl	(%edi,%eax,4),%ecx
        +	jb	L008loop4
        +	cmpl	24(%esp),%esi
        +	je	L007done
        +	movl	32(%esp),%ebp
        +.align	4,0x90
        +L002loop1:
        +	addb	%cl,%bl
        +	movl	(%edi,%ebx,4),%edx
        +	movl	%ecx,(%edi,%ebx,4)
        +	movl	%edx,(%edi,%eax,4)
        +	addl	%ecx,%edx
        +	incb	%al
        +	andl	$255,%edx
        +	movl	(%edi,%edx,4),%edx
        +	xorb	(%esi),%dl
        +	leal	1(%esi),%esi
        +	movl	(%edi,%eax,4),%ecx
        +	cmpl	24(%esp),%esi
        +	movb	%dl,-1(%ebp,%esi,1)
        +	jb	L002loop1
        +	jmp	L007done
        +.align	4,0x90
        +L001RC4_CHAR:
        +	movzbl	(%edi,%eax,1),%ecx
        +L009cloop1:
        +	addb	%cl,%bl
        +	movzbl	(%edi,%ebx,1),%edx
        +	movb	%cl,(%edi,%ebx,1)
        +	movb	%dl,(%edi,%eax,1)
        +	addb	%cl,%dl
        +	movzbl	(%edi,%edx,1),%edx
        +	addb	$1,%al
        +	xorb	(%esi),%dl
        +	leal	1(%esi),%esi
        +	movzbl	(%edi,%eax,1),%ecx
        +	cmpl	24(%esp),%esi
        +	movb	%dl,-1(%ebp,%esi,1)
        +	jb	L009cloop1
        +L007done:
        +	decb	%al
        +	movl	%ebx,-4(%edi)
        +	movb	%al,-8(%edi)
        +L000abort:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_private_RC4_set_key
        +.align	4
        +_private_RC4_set_key:
        +L_private_RC4_set_key_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%edi
        +	movl	24(%esp),%ebp
        +	movl	28(%esp),%esi
        +	call	L010PIC_me_up
        +L010PIC_me_up:
        +	popl	%edx
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L010PIC_me_up(%edx),%edx
        +	leal	8(%edi),%edi
        +	leal	(%esi,%ebp,1),%esi
        +	negl	%ebp
        +	xorl	%eax,%eax
        +	movl	%ebp,-4(%edi)
        +	btl	$20,(%edx)
        +	jc	L011c1stloop
        +.align	4,0x90
        +L012w1stloop:
        +	movl	%eax,(%edi,%eax,4)
        +	addb	$1,%al
        +	jnc	L012w1stloop
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +.align	4,0x90
        +L013w2ndloop:
        +	movl	(%edi,%ecx,4),%eax
        +	addb	(%esi,%ebp,1),%dl
        +	addb	%al,%dl
        +	addl	$1,%ebp
        +	movl	(%edi,%edx,4),%ebx
        +	jnz	L014wnowrap
        +	movl	-4(%edi),%ebp
        +L014wnowrap:
        +	movl	%eax,(%edi,%edx,4)
        +	movl	%ebx,(%edi,%ecx,4)
        +	addb	$1,%cl
        +	jnc	L013w2ndloop
        +	jmp	L015exit
        +.align	4,0x90
        +L011c1stloop:
        +	movb	%al,(%edi,%eax,1)
        +	addb	$1,%al
        +	jnc	L011c1stloop
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	xorl	%ebx,%ebx
        +.align	4,0x90
        +L016c2ndloop:
        +	movb	(%edi,%ecx,1),%al
        +	addb	(%esi,%ebp,1),%dl
        +	addb	%al,%dl
        +	addl	$1,%ebp
        +	movb	(%edi,%edx,1),%bl
        +	jnz	L017cnowrap
        +	movl	-4(%edi),%ebp
        +L017cnowrap:
        +	movb	%al,(%edi,%edx,1)
        +	movb	%bl,(%edi,%ecx,1)
        +	addb	$1,%cl
        +	jnc	L016c2ndloop
        +	movl	$-1,256(%edi)
        +L015exit:
        +	xorl	%eax,%eax
        +	movl	%eax,-8(%edi)
        +	movl	%eax,-4(%edi)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_RC4_options
        +.align	4
        +_RC4_options:
        +L_RC4_options_begin:
        +	call	L018pic_point
        +L018pic_point:
        +	popl	%eax
        +	leal	L019opts-L018pic_point(%eax),%eax
        +	call	L020PIC_me_up
        +L020PIC_me_up:
        +	popl	%edx
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L020PIC_me_up(%edx),%edx
        +	movl	(%edx),%edx
        +	btl	$20,%edx
        +	jc	L0211xchar
        +	btl	$26,%edx
        +	jnc	L022ret
        +	addl	$25,%eax
        +	ret
        +L0211xchar:
        +	addl	$12,%eax
        +L022ret:
        +	ret
        +.align	6,0x90
        +L019opts:
        +.byte	114,99,52,40,52,120,44,105,110,116,41,0
        +.byte	114,99,52,40,49,120,44,99,104,97,114,41,0
        +.byte	114,99,52,40,56,120,44,109,109,120,41,0
        +.byte	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
        +.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
        +.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.align	6,0x90
        +.section __IMPORT,__pointers,non_lazy_symbol_pointers
        +L_OPENSSL_ia32cap_P$non_lazy_ptr:
        +.indirect_symbol	_OPENSSL_ia32cap_P
        +.long	0
        +.comm	_OPENSSL_ia32cap_P,8,2
        diff --git a/vendor/openssl/asm/x86-macosx-gas/rc5/rc5-586.s b/vendor/openssl/asm/x86-macosx-gas/rc5/rc5-586.s
        new file mode 100644
        index 000000000..ed7f7dc76
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/rc5/rc5-586.s
        @@ -0,0 +1,563 @@
        +.file	"rc5-586.s"
        +.text
        +.globl	_RC5_32_encrypt
        +.align	4
        +_RC5_32_encrypt:
        +L_RC5_32_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +	movl	16(%esp),%edx
        +	movl	20(%esp),%ebp
        +	# Load the 2 words
        +
        +	movl	(%edx),%edi
        +	movl	4(%edx),%esi
        +	pushl	%ebx
        +	movl	(%ebp),%ebx
        +	addl	4(%ebp),%edi
        +	addl	8(%ebp),%esi
        +	xorl	%esi,%edi
        +	movl	12(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	16(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	20(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	24(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	28(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	32(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	36(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	40(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	44(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	48(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	52(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	56(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	60(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	64(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	68(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	72(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	cmpl	$8,%ebx
        +	je	L000rc5_exit
        +	xorl	%esi,%edi
        +	movl	76(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	80(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	84(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	88(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	92(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	96(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	100(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	104(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	cmpl	$12,%ebx
        +	je	L000rc5_exit
        +	xorl	%esi,%edi
        +	movl	108(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	112(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	116(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	120(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	124(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	128(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +	xorl	%esi,%edi
        +	movl	132(%ebp),%eax
        +	movl	%esi,%ecx
        +	roll	%cl,%edi
        +	addl	%eax,%edi
        +	xorl	%edi,%esi
        +	movl	136(%ebp),%eax
        +	movl	%edi,%ecx
        +	roll	%cl,%esi
        +	addl	%eax,%esi
        +L000rc5_exit:
        +	movl	%edi,(%edx)
        +	movl	%esi,4(%edx)
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	ret
        +.globl	_RC5_32_decrypt
        +.align	4
        +_RC5_32_decrypt:
        +L_RC5_32_decrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%esi
        +	pushl	%edi
        +	movl	16(%esp),%edx
        +	movl	20(%esp),%ebp
        +	# Load the 2 words
        +
        +	movl	(%edx),%edi
        +	movl	4(%edx),%esi
        +	pushl	%ebx
        +	movl	(%ebp),%ebx
        +	cmpl	$12,%ebx
        +	je	L001rc5_dec_12
        +	cmpl	$8,%ebx
        +	je	L002rc5_dec_8
        +	movl	136(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	132(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	128(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	124(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	120(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	116(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	112(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	108(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +L001rc5_dec_12:
        +	movl	104(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	100(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	96(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	92(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	88(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	84(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	80(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	76(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +L002rc5_dec_8:
        +	movl	72(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	68(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	64(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	60(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	56(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	52(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	48(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	44(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	40(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	36(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	32(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	28(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	24(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	20(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	movl	16(%ebp),%eax
        +	subl	%eax,%esi
        +	movl	%edi,%ecx
        +	rorl	%cl,%esi
        +	xorl	%edi,%esi
        +	movl	12(%ebp),%eax
        +	subl	%eax,%edi
        +	movl	%esi,%ecx
        +	rorl	%cl,%edi
        +	xorl	%esi,%edi
        +	subl	8(%ebp),%esi
        +	subl	4(%ebp),%edi
        +L003rc5_exit:
        +	movl	%edi,(%edx)
        +	movl	%esi,4(%edx)
        +	popl	%ebx
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebp
        +	ret
        +.globl	_RC5_32_cbc_encrypt
        +.align	4
        +_RC5_32_cbc_encrypt:
        +L_RC5_32_cbc_encrypt_begin:
        +
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	28(%esp),%ebp
        +	# getting iv ptr from parameter 4
        +
        +	movl	36(%esp),%ebx
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	pushl	%edi
        +	pushl	%esi
        +	pushl	%edi
        +	pushl	%esi
        +	movl	%esp,%ebx
        +	movl	36(%esp),%esi
        +	movl	40(%esp),%edi
        +	# getting encrypt flag from parameter 5
        +
        +	movl	56(%esp),%ecx
        +	# get and push parameter 3
        +
        +	movl	48(%esp),%eax
        +	pushl	%eax
        +	pushl	%ebx
        +	cmpl	$0,%ecx
        +	jz	L004decrypt
        +	andl	$4294967288,%ebp
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	jz	L005encrypt_finish
        +L006encrypt_loop:
        +	movl	(%esi),%ecx
        +	movl	4(%esi),%edx
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_RC5_32_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L006encrypt_loop
        +L005encrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L007finish
        +	call	L008PIC_point
        +L008PIC_point:
        +	popl	%edx
        +	leal	L009cbc_enc_jmp_table-L008PIC_point(%edx),%ecx
        +	movl	(%ecx,%ebp,4),%ebp
        +	addl	%edx,%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	jmp	*%ebp
        +L010ej7:
        +	movb	6(%esi),%dh
        +	shll	$8,%edx
        +L011ej6:
        +	movb	5(%esi),%dh
        +L012ej5:
        +	movb	4(%esi),%dl
        +L013ej4:
        +	movl	(%esi),%ecx
        +	jmp	L014ejend
        +L015ej3:
        +	movb	2(%esi),%ch
        +	shll	$8,%ecx
        +L016ej2:
        +	movb	1(%esi),%ch
        +L017ej1:
        +	movb	(%esi),%cl
        +L014ejend:
        +	xorl	%ecx,%eax
        +	xorl	%edx,%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_RC5_32_encrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	%eax,(%edi)
        +	movl	%ebx,4(%edi)
        +	jmp	L007finish
        +L004decrypt:
        +	andl	$4294967288,%ebp
        +	movl	16(%esp),%eax
        +	movl	20(%esp),%ebx
        +	jz	L018decrypt_finish
        +L019decrypt_loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_RC5_32_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%ecx,(%edi)
        +	movl	%edx,4(%edi)
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	addl	$8,%esi
        +	addl	$8,%edi
        +	subl	$8,%ebp
        +	jnz	L019decrypt_loop
        +L018decrypt_finish:
        +	movl	52(%esp),%ebp
        +	andl	$7,%ebp
        +	jz	L007finish
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +	call	L_RC5_32_decrypt_begin
        +	movl	8(%esp),%eax
        +	movl	12(%esp),%ebx
        +	movl	16(%esp),%ecx
        +	movl	20(%esp),%edx
        +	xorl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +L020dj7:
        +	rorl	$16,%edx
        +	movb	%dl,6(%edi)
        +	shrl	$16,%edx
        +L021dj6:
        +	movb	%dh,5(%edi)
        +L022dj5:
        +	movb	%dl,4(%edi)
        +L023dj4:
        +	movl	%ecx,(%edi)
        +	jmp	L024djend
        +L025dj3:
        +	rorl	$16,%ecx
        +	movb	%cl,2(%edi)
        +	shll	$16,%ecx
        +L026dj2:
        +	movb	%ch,1(%esi)
        +L027dj1:
        +	movb	%cl,(%esi)
        +L024djend:
        +	jmp	L007finish
        +L007finish:
        +	movl	60(%esp),%ecx
        +	addl	$24,%esp
        +	movl	%eax,(%ecx)
        +	movl	%ebx,4(%ecx)
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L009cbc_enc_jmp_table:
        +.long	0
        +.long	L017ej1-L008PIC_point
        +.long	L016ej2-L008PIC_point
        +.long	L015ej3-L008PIC_point
        +.long	L013ej4-L008PIC_point
        +.long	L012ej5-L008PIC_point
        +.long	L011ej6-L008PIC_point
        +.long	L010ej7-L008PIC_point
        +.align	6,0x90
        diff --git a/vendor/openssl/asm/x86-macosx-gas/ripemd/rmd-586.s b/vendor/openssl/asm/x86-macosx-gas/ripemd/rmd-586.s
        new file mode 100644
        index 000000000..7d9d0e4d6
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/ripemd/rmd-586.s
        @@ -0,0 +1,2123 @@
        +.file	"../openssl/crypto/ripemd/asm/rmd-586.s"
        +.text
        +.globl	_ripemd160_block_asm_data_order
        +.align	4
        +_ripemd160_block_asm_data_order:
        +L_ripemd160_block_asm_data_order_begin:
        +	movl	4(%esp),%edx
        +	movl	8(%esp),%eax
        +	pushl	%esi
        +	movl	(%edx),%ecx
        +	pushl	%edi
        +	movl	4(%edx),%esi
        +	pushl	%ebp
        +	movl	8(%edx),%edi
        +	pushl	%ebx
        +	subl	$108,%esp
        +L000start:
        +
        +	movl	(%eax),%ebx
        +	movl	4(%eax),%ebp
        +	movl	%ebx,(%esp)
        +	movl	%ebp,4(%esp)
        +	movl	8(%eax),%ebx
        +	movl	12(%eax),%ebp
        +	movl	%ebx,8(%esp)
        +	movl	%ebp,12(%esp)
        +	movl	16(%eax),%ebx
        +	movl	20(%eax),%ebp
        +	movl	%ebx,16(%esp)
        +	movl	%ebp,20(%esp)
        +	movl	24(%eax),%ebx
        +	movl	28(%eax),%ebp
        +	movl	%ebx,24(%esp)
        +	movl	%ebp,28(%esp)
        +	movl	32(%eax),%ebx
        +	movl	36(%eax),%ebp
        +	movl	%ebx,32(%esp)
        +	movl	%ebp,36(%esp)
        +	movl	40(%eax),%ebx
        +	movl	44(%eax),%ebp
        +	movl	%ebx,40(%esp)
        +	movl	%ebp,44(%esp)
        +	movl	48(%eax),%ebx
        +	movl	52(%eax),%ebp
        +	movl	%ebx,48(%esp)
        +	movl	%ebp,52(%esp)
        +	movl	56(%eax),%ebx
        +	movl	60(%eax),%ebp
        +	movl	%ebx,56(%esp)
        +	movl	%ebp,60(%esp)
        +	movl	%edi,%eax
        +	movl	12(%edx),%ebx
        +	movl	16(%edx),%ebp
        +	# 0
        +
        +	xorl	%ebx,%eax
        +	movl	(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%edx,%ecx
        +	roll	$10,%edi
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$11,%ecx
        +	addl	%ebp,%ecx
        +	# 1
        +
        +	xorl	%edi,%eax
        +	movl	4(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$10,%esi
        +	addl	%edx,%ebp
        +	xorl	%esi,%eax
        +	roll	$14,%ebp
        +	addl	%ebx,%ebp
        +	# 2
        +
        +	movl	8(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%edx,%ebx
        +	roll	$10,%ecx
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$15,%ebx
        +	addl	%edi,%ebx
        +	# 3
        +
        +	xorl	%ecx,%eax
        +	movl	12(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	addl	%edx,%edi
        +	xorl	%ebp,%eax
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +	# 4
        +
        +	movl	16(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +	# 5
        +
        +	xorl	%ebx,%eax
        +	movl	20(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	xorl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 6
        +
        +	movl	24(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%edx,%ebp
        +	roll	$10,%esi
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +	# 7
        +
        +	xorl	%esi,%eax
        +	movl	28(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$10,%ecx
        +	addl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 8
        +
        +	movl	32(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%edx,%edi
        +	roll	$10,%ebp
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +	# 9
        +
        +	xorl	%ebp,%eax
        +	movl	36(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$10,%ebx
        +	addl	%edx,%esi
        +	xorl	%ebx,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +	# 10
        +
        +	movl	40(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%edx,%ecx
        +	roll	$10,%edi
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +	# 11
        +
        +	xorl	%edi,%eax
        +	movl	44(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$10,%esi
        +	addl	%edx,%ebp
        +	xorl	%esi,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +	# 12
        +
        +	movl	48(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%edx,%ebx
        +	roll	$10,%ecx
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$6,%ebx
        +	addl	%edi,%ebx
        +	# 13
        +
        +	xorl	%ecx,%eax
        +	movl	52(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	addl	%edx,%edi
        +	xorl	%ebp,%eax
        +	roll	$7,%edi
        +	addl	%esi,%edi
        +	# 14
        +
        +	movl	56(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +	# 15
        +
        +	xorl	%ebx,%eax
        +	movl	60(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	movl	28(%esp),%edx
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 16
        +
        +	addl	%edx,%ebp
        +	movl	%esi,%edx
        +	subl	%ecx,%eax
        +	andl	%ecx,%edx
        +	andl	%edi,%eax
        +	orl	%eax,%edx
        +	movl	16(%esp),%eax
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +	# 17
        +
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	subl	%ebp,%edx
        +	andl	%ebp,%eax
        +	andl	%esi,%edx
        +	orl	%edx,%eax
        +	movl	52(%esp),%edx
        +	roll	$10,%ecx
        +	leal	1518500249(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$6,%ebx
        +	addl	%edi,%ebx
        +	# 18
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1518500249(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$8,%edi
        +	addl	%esi,%edi
        +	# 19
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	40(%esp),%edx
        +	roll	$10,%ebx
        +	leal	1518500249(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +	# 20
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%edi
        +	leal	1518500249(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$11,%ecx
        +	addl	%ebp,%ecx
        +	# 21
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	60(%esp),%edx
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	movl	$-1,%eax
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +	# 22
        +
        +	addl	%edx,%ebx
        +	movl	%ecx,%edx
        +	subl	%ebp,%eax
        +	andl	%ebp,%edx
        +	andl	%esi,%eax
        +	orl	%eax,%edx
        +	movl	12(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1518500249(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	roll	$7,%ebx
        +	addl	%edi,%ebx
        +	# 23
        +
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	subl	%ebx,%edx
        +	andl	%ebx,%eax
        +	andl	%ecx,%edx
        +	orl	%edx,%eax
        +	movl	48(%esp),%edx
        +	roll	$10,%ebp
        +	leal	1518500249(%edi,%eax,1),%edi
        +	movl	$-1,%eax
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +	# 24
        +
        +	addl	%edx,%esi
        +	movl	%ebx,%edx
        +	subl	%edi,%eax
        +	andl	%edi,%edx
        +	andl	%ebp,%eax
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1518500249(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +	# 25
        +
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	subl	%esi,%edx
        +	andl	%esi,%eax
        +	andl	%ebx,%edx
        +	orl	%edx,%eax
        +	movl	36(%esp),%edx
        +	roll	$10,%edi
        +	leal	1518500249(%ecx,%eax,1),%ecx
        +	movl	$-1,%eax
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +	# 26
        +
        +	addl	%edx,%ebp
        +	movl	%esi,%edx
        +	subl	%ecx,%eax
        +	andl	%ecx,%edx
        +	andl	%edi,%eax
        +	orl	%eax,%edx
        +	movl	20(%esp),%eax
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +	# 27
        +
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	subl	%ebp,%edx
        +	andl	%ebp,%eax
        +	andl	%esi,%edx
        +	orl	%edx,%eax
        +	movl	8(%esp),%edx
        +	roll	$10,%ecx
        +	leal	1518500249(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 28
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1518500249(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +	# 29
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	44(%esp),%edx
        +	roll	$10,%ebx
        +	leal	1518500249(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +	# 30
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	32(%esp),%eax
        +	roll	$10,%edi
        +	leal	1518500249(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +	# 31
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	subl	%ecx,%edx
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +	# 32
        +
        +	movl	12(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$11,%ebx
        +	addl	%edi,%ebx
        +	# 33
        +
        +	movl	40(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1859775393(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$13,%edi
        +	addl	%esi,%edi
        +	# 34
        +
        +	movl	56(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1859775393(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +	# 35
        +
        +	movl	16(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1859775393(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$7,%ecx
        +	addl	%ebp,%ecx
        +	# 36
        +
        +	movl	36(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1859775393(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$14,%ebp
        +	addl	%ebx,%ebp
        +	# 37
        +
        +	movl	60(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	subl	%ebp,%edx
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 38
        +
        +	movl	32(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%edi
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	1859775393(%edi,%edx,1),%edi
        +	subl	%ebx,%eax
        +	roll	$13,%edi
        +	addl	%esi,%edi
        +	# 39
        +
        +	movl	4(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%esi
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	1859775393(%esi,%eax,1),%esi
        +	subl	%edi,%edx
        +	roll	$15,%esi
        +	addl	%ecx,%esi
        +	# 40
        +
        +	movl	8(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1859775393(%ecx,%edx,1),%ecx
        +	subl	%esi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +	# 41
        +
        +	movl	28(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebp
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1859775393(%ebp,%eax,1),%ebp
        +	subl	%ecx,%edx
        +	roll	$8,%ebp
        +	addl	%ebx,%ebp
        +	# 42
        +
        +	movl	(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$13,%ebx
        +	addl	%edi,%ebx
        +	# 43
        +
        +	movl	24(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1859775393(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +	# 44
        +
        +	movl	52(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1859775393(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +	# 45
        +
        +	movl	44(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1859775393(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +	# 46
        +
        +	movl	20(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1859775393(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +	# 47
        +
        +	movl	48(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	%ecx,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +	# 48
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +	# 49
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	36(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2400959708(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$12,%esi
        +	addl	%ecx,%esi
        +	# 50
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	44(%esp),%eax
        +	roll	$10,%edi
        +	leal	2400959708(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +	# 51
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	40(%esp),%eax
        +	roll	$10,%esi
        +	leal	2400959708(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +	# 52
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2400959708(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +	# 53
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	32(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +	# 54
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	48(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2400959708(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +	# 55
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	16(%esp),%eax
        +	roll	$10,%edi
        +	leal	2400959708(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 56
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	52(%esp),%eax
        +	roll	$10,%esi
        +	leal	2400959708(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +	# 57
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	12(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2400959708(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +	# 58
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	28(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$5,%edi
        +	addl	%esi,%edi
        +	# 59
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	60(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2400959708(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +	# 60
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%edi
        +	leal	2400959708(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 61
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	20(%esp),%eax
        +	roll	$10,%esi
        +	leal	2400959708(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$6,%ebp
        +	addl	%ebx,%ebp
        +	# 62
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2400959708(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +	# 63
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	8(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2400959708(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	subl	%ebp,%edx
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +	# 64
        +
        +	movl	16(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +	# 65
        +
        +	movl	(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	2840853838(%ecx,%eax,1),%ecx
        +	subl	%edi,%edx
        +	roll	$15,%ecx
        +	addl	%ebp,%ecx
        +	# 66
        +
        +	movl	20(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ebp
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	2840853838(%ebp,%edx,1),%ebp
        +	subl	%esi,%eax
        +	roll	$5,%ebp
        +	addl	%ebx,%ebp
        +	# 67
        +
        +	movl	36(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebx
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	2840853838(%ebx,%eax,1),%ebx
        +	subl	%ecx,%edx
        +	roll	$11,%ebx
        +	addl	%edi,%ebx
        +	# 68
        +
        +	movl	28(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%edi
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	2840853838(%edi,%edx,1),%edi
        +	subl	%ebp,%eax
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +	# 69
        +
        +	movl	48(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%esi
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%eax,1),%esi
        +	subl	%ebx,%edx
        +	roll	$8,%esi
        +	addl	%ecx,%esi
        +	# 70
        +
        +	movl	8(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%ecx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	2840853838(%ecx,%edx,1),%ecx
        +	subl	%edi,%eax
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +	# 71
        +
        +	movl	40(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ebp
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	2840853838(%ebp,%eax,1),%ebp
        +	subl	%esi,%edx
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +	# 72
        +
        +	movl	56(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebx
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	2840853838(%ebx,%edx,1),%ebx
        +	subl	%ecx,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +	# 73
        +
        +	movl	4(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%edi
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	2840853838(%edi,%eax,1),%edi
        +	subl	%ebp,%edx
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +	# 74
        +
        +	movl	12(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +	# 75
        +
        +	movl	32(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	2840853838(%ecx,%eax,1),%ecx
        +	subl	%edi,%edx
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +	# 76
        +
        +	movl	44(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ebp
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	2840853838(%ebp,%edx,1),%ebp
        +	subl	%esi,%eax
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +	# 77
        +
        +	movl	24(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebx
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	2840853838(%ebx,%eax,1),%ebx
        +	subl	%ecx,%edx
        +	roll	$8,%ebx
        +	addl	%edi,%ebx
        +	# 78
        +
        +	movl	60(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%edi
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	2840853838(%edi,%edx,1),%edi
        +	subl	%ebp,%eax
        +	roll	$5,%edi
        +	addl	%esi,%edi
        +	# 79
        +
        +	movl	52(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%esi
        +	xorl	%edi,%eax
        +	movl	128(%esp),%edx
        +	roll	$10,%ebx
        +	leal	2840853838(%esi,%eax,1),%esi
        +	movl	%ecx,64(%esp)
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +	movl	(%edx),%ecx
        +	movl	%esi,68(%esp)
        +	movl	%edi,72(%esp)
        +	movl	4(%edx),%esi
        +	movl	%ebx,76(%esp)
        +	movl	8(%edx),%edi
        +	movl	%ebp,80(%esp)
        +	movl	12(%edx),%ebx
        +	movl	16(%edx),%ebp
        +	# 80
        +
        +	movl	$-1,%edx
        +	subl	%ebx,%edx
        +	movl	20(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%ecx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%edx,1),%ecx
        +	subl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 81
        +
        +	movl	56(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ebp
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1352829926(%ebp,%eax,1),%ebp
        +	subl	%esi,%edx
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +	# 82
        +
        +	movl	28(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebx
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1352829926(%ebx,%edx,1),%ebx
        +	subl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 83
        +
        +	movl	(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%edi
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1352829926(%edi,%eax,1),%edi
        +	subl	%ebp,%edx
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +	# 84
        +
        +	movl	36(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1352829926(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +	# 85
        +
        +	movl	8(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%eax,1),%ecx
        +	subl	%edi,%edx
        +	roll	$15,%ecx
        +	addl	%ebp,%ecx
        +	# 86
        +
        +	movl	44(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ebp
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1352829926(%ebp,%edx,1),%ebp
        +	subl	%esi,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +	# 87
        +
        +	movl	16(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebx
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1352829926(%ebx,%eax,1),%ebx
        +	subl	%ecx,%edx
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +	# 88
        +
        +	movl	52(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%edi
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	1352829926(%edi,%edx,1),%edi
        +	subl	%ebp,%eax
        +	roll	$7,%edi
        +	addl	%esi,%edi
        +	# 89
        +
        +	movl	24(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%esi
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	1352829926(%esi,%eax,1),%esi
        +	subl	%ebx,%edx
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +	# 90
        +
        +	movl	60(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%ecx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%edx,1),%ecx
        +	subl	%edi,%eax
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 91
        +
        +	movl	32(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ebp
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1352829926(%ebp,%eax,1),%ebp
        +	subl	%esi,%edx
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +	# 92
        +
        +	movl	4(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebx
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1352829926(%ebx,%edx,1),%ebx
        +	subl	%ecx,%eax
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +	# 93
        +
        +	movl	40(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%edi
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1352829926(%edi,%eax,1),%edi
        +	subl	%ebp,%edx
        +	roll	$14,%edi
        +	addl	%esi,%edi
        +	# 94
        +
        +	movl	12(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%esi
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1352829926(%esi,%edx,1),%esi
        +	subl	%ebx,%eax
        +	roll	$12,%esi
        +	addl	%ecx,%esi
        +	# 95
        +
        +	movl	48(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%ecx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1352829926(%ecx,%eax,1),%ecx
        +	movl	%edi,%eax
        +	roll	$6,%ecx
        +	addl	%ebp,%ecx
        +	# 96
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$9,%ebp
        +	addl	%ebx,%ebp
        +	# 97
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	44(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1548603684(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$13,%ebx
        +	addl	%edi,%ebx
        +	# 98
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	12(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1548603684(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +	# 99
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	28(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1548603684(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +	# 100
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%edi
        +	leal	1548603684(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +	# 101
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	52(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$8,%ebp
        +	addl	%ebx,%ebp
        +	# 102
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	20(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1548603684(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 103
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	40(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1548603684(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +	# 104
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1548603684(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$7,%esi
        +	addl	%ecx,%esi
        +	# 105
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	60(%esp),%eax
        +	roll	$10,%edi
        +	leal	1548603684(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$7,%ecx
        +	addl	%ebp,%ecx
        +	# 106
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	32(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +	# 107
        +
        +	subl	%esi,%edx
        +	andl	%ebp,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	48(%esp),%eax
        +	roll	$10,%ecx
        +	leal	1548603684(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	roll	$7,%ebx
        +	addl	%edi,%ebx
        +	# 108
        +
        +	subl	%ecx,%edx
        +	andl	%ebx,%eax
        +	andl	%ebp,%edx
        +	orl	%eax,%edx
        +	movl	16(%esp),%eax
        +	roll	$10,%ebp
        +	leal	1548603684(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +	# 109
        +
        +	subl	%ebp,%edx
        +	andl	%edi,%eax
        +	andl	%ebx,%edx
        +	orl	%eax,%edx
        +	movl	36(%esp),%eax
        +	roll	$10,%ebx
        +	leal	1548603684(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	roll	$15,%esi
        +	addl	%ecx,%esi
        +	# 110
        +
        +	subl	%ebx,%edx
        +	andl	%esi,%eax
        +	andl	%edi,%edx
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%edi
        +	leal	1548603684(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +	# 111
        +
        +	subl	%edi,%edx
        +	andl	%ecx,%eax
        +	andl	%esi,%edx
        +	orl	%eax,%edx
        +	movl	8(%esp),%eax
        +	roll	$10,%esi
        +	leal	1548603684(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	addl	%eax,%ebp
        +	subl	%ecx,%edx
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +	# 112
        +
        +	movl	60(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 113
        +
        +	movl	20(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1836072691(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$7,%edi
        +	addl	%esi,%edi
        +	# 114
        +
        +	movl	4(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1836072691(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$15,%esi
        +	addl	%ecx,%esi
        +	# 115
        +
        +	movl	12(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1836072691(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$11,%ecx
        +	addl	%ebp,%ecx
        +	# 116
        +
        +	movl	28(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1836072691(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$8,%ebp
        +	addl	%ebx,%ebp
        +	# 117
        +
        +	movl	56(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%eax,1),%ebx
        +	subl	%ebp,%edx
        +	roll	$6,%ebx
        +	addl	%edi,%ebx
        +	# 118
        +
        +	movl	24(%esp),%eax
        +	orl	%ebx,%edx
        +	addl	%eax,%edi
        +	xorl	%ecx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebp
        +	leal	1836072691(%edi,%edx,1),%edi
        +	subl	%ebx,%eax
        +	roll	$6,%edi
        +	addl	%esi,%edi
        +	# 119
        +
        +	movl	36(%esp),%edx
        +	orl	%edi,%eax
        +	addl	%edx,%esi
        +	xorl	%ebp,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebx
        +	leal	1836072691(%esi,%eax,1),%esi
        +	subl	%edi,%edx
        +	roll	$14,%esi
        +	addl	%ecx,%esi
        +	# 120
        +
        +	movl	44(%esp),%eax
        +	orl	%esi,%edx
        +	addl	%eax,%ecx
        +	xorl	%ebx,%edx
        +	movl	$-1,%eax
        +	roll	$10,%edi
        +	leal	1836072691(%ecx,%edx,1),%ecx
        +	subl	%esi,%eax
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +	# 121
        +
        +	movl	32(%esp),%edx
        +	orl	%ecx,%eax
        +	addl	%edx,%ebp
        +	xorl	%edi,%eax
        +	movl	$-1,%edx
        +	roll	$10,%esi
        +	leal	1836072691(%ebp,%eax,1),%ebp
        +	subl	%ecx,%edx
        +	roll	$13,%ebp
        +	addl	%ebx,%ebp
        +	# 122
        +
        +	movl	48(%esp),%eax
        +	orl	%ebp,%edx
        +	addl	%eax,%ebx
        +	xorl	%esi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%edx,1),%ebx
        +	subl	%ebp,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +	# 123
        +
        +	movl	8(%esp),%edx
        +	orl	%ebx,%eax
        +	addl	%edx,%edi
        +	xorl	%ecx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%ebp
        +	leal	1836072691(%edi,%eax,1),%edi
        +	subl	%ebx,%edx
        +	roll	$14,%edi
        +	addl	%esi,%edi
        +	# 124
        +
        +	movl	40(%esp),%eax
        +	orl	%edi,%edx
        +	addl	%eax,%esi
        +	xorl	%ebp,%edx
        +	movl	$-1,%eax
        +	roll	$10,%ebx
        +	leal	1836072691(%esi,%edx,1),%esi
        +	subl	%edi,%eax
        +	roll	$13,%esi
        +	addl	%ecx,%esi
        +	# 125
        +
        +	movl	(%esp),%edx
        +	orl	%esi,%eax
        +	addl	%edx,%ecx
        +	xorl	%ebx,%eax
        +	movl	$-1,%edx
        +	roll	$10,%edi
        +	leal	1836072691(%ecx,%eax,1),%ecx
        +	subl	%esi,%edx
        +	roll	$13,%ecx
        +	addl	%ebp,%ecx
        +	# 126
        +
        +	movl	16(%esp),%eax
        +	orl	%ecx,%edx
        +	addl	%eax,%ebp
        +	xorl	%edi,%edx
        +	movl	$-1,%eax
        +	roll	$10,%esi
        +	leal	1836072691(%ebp,%edx,1),%ebp
        +	subl	%ecx,%eax
        +	roll	$7,%ebp
        +	addl	%ebx,%ebp
        +	# 127
        +
        +	movl	52(%esp),%edx
        +	orl	%ebp,%eax
        +	addl	%edx,%ebx
        +	xorl	%esi,%eax
        +	movl	32(%esp),%edx
        +	roll	$10,%ecx
        +	leal	1836072691(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$5,%ebx
        +	addl	%edi,%ebx
        +	# 128
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	24(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$15,%edi
        +	addl	%esi,%edi
        +	# 129
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	16(%esp),%edx
        +	roll	$10,%ebx
        +	leal	2053994217(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +	# 130
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	4(%esp),%eax
        +	roll	$10,%edi
        +	leal	2053994217(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$8,%ecx
        +	addl	%ebp,%ecx
        +	# 131
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	12(%esp),%edx
        +	roll	$10,%esi
        +	leal	2053994217(%ebp,%eax,1),%ebp
        +	movl	$-1,%eax
        +	roll	$11,%ebp
        +	addl	%ebx,%ebp
        +	# 132
        +
        +	addl	%edx,%ebx
        +	movl	%ecx,%edx
        +	subl	%ebp,%eax
        +	andl	%ebp,%edx
        +	andl	%esi,%eax
        +	orl	%eax,%edx
        +	movl	44(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2053994217(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	roll	$14,%ebx
        +	addl	%edi,%ebx
        +	# 133
        +
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	subl	%ebx,%edx
        +	andl	%ebx,%eax
        +	andl	%ecx,%edx
        +	orl	%edx,%eax
        +	movl	60(%esp),%edx
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%eax,1),%edi
        +	movl	$-1,%eax
        +	roll	$14,%edi
        +	addl	%esi,%edi
        +	# 134
        +
        +	addl	%edx,%esi
        +	movl	%ebx,%edx
        +	subl	%edi,%eax
        +	andl	%edi,%edx
        +	andl	%ebp,%eax
        +	orl	%eax,%edx
        +	movl	(%esp),%eax
        +	roll	$10,%ebx
        +	leal	2053994217(%esi,%edx,1),%esi
        +	movl	$-1,%edx
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +	# 135
        +
        +	addl	%eax,%ecx
        +	movl	%edi,%eax
        +	subl	%esi,%edx
        +	andl	%esi,%eax
        +	andl	%ebx,%edx
        +	orl	%edx,%eax
        +	movl	20(%esp),%edx
        +	roll	$10,%edi
        +	leal	2053994217(%ecx,%eax,1),%ecx
        +	movl	$-1,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +	# 136
        +
        +	addl	%edx,%ebp
        +	movl	%esi,%edx
        +	subl	%ecx,%eax
        +	andl	%ecx,%edx
        +	andl	%edi,%eax
        +	orl	%eax,%edx
        +	movl	48(%esp),%eax
        +	roll	$10,%esi
        +	leal	2053994217(%ebp,%edx,1),%ebp
        +	movl	$-1,%edx
        +	roll	$6,%ebp
        +	addl	%ebx,%ebp
        +	# 137
        +
        +	addl	%eax,%ebx
        +	movl	%ecx,%eax
        +	subl	%ebp,%edx
        +	andl	%ebp,%eax
        +	andl	%esi,%edx
        +	orl	%edx,%eax
        +	movl	8(%esp),%edx
        +	roll	$10,%ecx
        +	leal	2053994217(%ebx,%eax,1),%ebx
        +	movl	$-1,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 138
        +
        +	addl	%edx,%edi
        +	movl	%ebp,%edx
        +	subl	%ebx,%eax
        +	andl	%ebx,%edx
        +	andl	%ecx,%eax
        +	orl	%eax,%edx
        +	movl	52(%esp),%eax
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%edx,1),%edi
        +	movl	$-1,%edx
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +	# 139
        +
        +	addl	%eax,%esi
        +	movl	%ebx,%eax
        +	subl	%edi,%edx
        +	andl	%edi,%eax
        +	andl	%ebp,%edx
        +	orl	%edx,%eax
        +	movl	36(%esp),%edx
        +	roll	$10,%ebx
        +	leal	2053994217(%esi,%eax,1),%esi
        +	movl	$-1,%eax
        +	roll	$9,%esi
        +	addl	%ecx,%esi
        +	# 140
        +
        +	addl	%edx,%ecx
        +	movl	%edi,%edx
        +	subl	%esi,%eax
        +	andl	%esi,%edx
        +	andl	%ebx,%eax
        +	orl	%eax,%edx
        +	movl	28(%esp),%eax
        +	roll	$10,%edi
        +	leal	2053994217(%ecx,%edx,1),%ecx
        +	movl	$-1,%edx
        +	roll	$12,%ecx
        +	addl	%ebp,%ecx
        +	# 141
        +
        +	addl	%eax,%ebp
        +	movl	%esi,%eax
        +	subl	%ecx,%edx
        +	andl	%ecx,%eax
        +	andl	%edi,%edx
        +	orl	%edx,%eax
        +	movl	40(%esp),%edx
        +	roll	$10,%esi
        +	leal	2053994217(%ebp,%eax,1),%ebp
        +	movl	$-1,%eax
        +	roll	$5,%ebp
        +	addl	%ebx,%ebp
        +	# 142
        +
        +	addl	%edx,%ebx
        +	movl	%ecx,%edx
        +	subl	%ebp,%eax
        +	andl	%ebp,%edx
        +	andl	%esi,%eax
        +	orl	%eax,%edx
        +	movl	56(%esp),%eax
        +	roll	$10,%ecx
        +	leal	2053994217(%ebx,%edx,1),%ebx
        +	movl	$-1,%edx
        +	roll	$15,%ebx
        +	addl	%edi,%ebx
        +	# 143
        +
        +	addl	%eax,%edi
        +	movl	%ebp,%eax
        +	subl	%ebx,%edx
        +	andl	%ebx,%eax
        +	andl	%ecx,%edx
        +	orl	%eax,%edx
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	leal	2053994217(%edi,%edx,1),%edi
        +	xorl	%ebp,%eax
        +	roll	$8,%edi
        +	addl	%esi,%edi
        +	# 144
        +
        +	movl	48(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$8,%esi
        +	addl	%ecx,%esi
        +	# 145
        +
        +	xorl	%ebx,%eax
        +	movl	60(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	addl	%ebp,%ecx
        +	# 146
        +
        +	movl	40(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%edx,%ebp
        +	roll	$10,%esi
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$12,%ebp
        +	addl	%ebx,%ebp
        +	# 147
        +
        +	xorl	%esi,%eax
        +	movl	16(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$10,%ecx
        +	addl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$9,%ebx
        +	addl	%edi,%ebx
        +	# 148
        +
        +	movl	4(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%edx,%edi
        +	roll	$10,%ebp
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$12,%edi
        +	addl	%esi,%edi
        +	# 149
        +
        +	xorl	%ebp,%eax
        +	movl	20(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$10,%ebx
        +	addl	%edx,%esi
        +	xorl	%ebx,%eax
        +	roll	$5,%esi
        +	addl	%ecx,%esi
        +	# 150
        +
        +	movl	32(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%edx,%ecx
        +	roll	$10,%edi
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$14,%ecx
        +	addl	%ebp,%ecx
        +	# 151
        +
        +	xorl	%edi,%eax
        +	movl	28(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$10,%esi
        +	addl	%edx,%ebp
        +	xorl	%esi,%eax
        +	roll	$6,%ebp
        +	addl	%ebx,%ebp
        +	# 152
        +
        +	movl	24(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%edx,%ebx
        +	roll	$10,%ecx
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$8,%ebx
        +	addl	%edi,%ebx
        +	# 153
        +
        +	xorl	%ecx,%eax
        +	movl	8(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$10,%ebp
        +	addl	%edx,%edi
        +	xorl	%ebp,%eax
        +	roll	$13,%edi
        +	addl	%esi,%edi
        +	# 154
        +
        +	movl	52(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%edx,%esi
        +	roll	$10,%ebx
        +	addl	%eax,%esi
        +	movl	%edi,%eax
        +	roll	$6,%esi
        +	addl	%ecx,%esi
        +	# 155
        +
        +	xorl	%ebx,%eax
        +	movl	56(%esp),%edx
        +	xorl	%esi,%eax
        +	addl	%eax,%ecx
        +	movl	%esi,%eax
        +	roll	$10,%edi
        +	addl	%edx,%ecx
        +	xorl	%edi,%eax
        +	roll	$5,%ecx
        +	addl	%ebp,%ecx
        +	# 156
        +
        +	movl	(%esp),%edx
        +	xorl	%ecx,%eax
        +	addl	%edx,%ebp
        +	roll	$10,%esi
        +	addl	%eax,%ebp
        +	movl	%ecx,%eax
        +	roll	$15,%ebp
        +	addl	%ebx,%ebp
        +	# 157
        +
        +	xorl	%esi,%eax
        +	movl	12(%esp),%edx
        +	xorl	%ebp,%eax
        +	addl	%eax,%ebx
        +	movl	%ebp,%eax
        +	roll	$10,%ecx
        +	addl	%edx,%ebx
        +	xorl	%ecx,%eax
        +	roll	$13,%ebx
        +	addl	%edi,%ebx
        +	# 158
        +
        +	movl	36(%esp),%edx
        +	xorl	%ebx,%eax
        +	addl	%edx,%edi
        +	roll	$10,%ebp
        +	addl	%eax,%edi
        +	movl	%ebx,%eax
        +	roll	$11,%edi
        +	addl	%esi,%edi
        +	# 159
        +
        +	xorl	%ebp,%eax
        +	movl	44(%esp),%edx
        +	xorl	%edi,%eax
        +	addl	%eax,%esi
        +	roll	$10,%ebx
        +	addl	%edx,%esi
        +	movl	128(%esp),%edx
        +	roll	$11,%esi
        +	addl	%ecx,%esi
        +	movl	4(%edx),%eax
        +	addl	%eax,%ebx
        +	movl	72(%esp),%eax
        +	addl	%eax,%ebx
        +	movl	8(%edx),%eax
        +	addl	%eax,%ebp
        +	movl	76(%esp),%eax
        +	addl	%eax,%ebp
        +	movl	12(%edx),%eax
        +	addl	%eax,%ecx
        +	movl	80(%esp),%eax
        +	addl	%eax,%ecx
        +	movl	16(%edx),%eax
        +	addl	%eax,%esi
        +	movl	64(%esp),%eax
        +	addl	%eax,%esi
        +	movl	(%edx),%eax
        +	addl	%eax,%edi
        +	movl	68(%esp),%eax
        +	addl	%eax,%edi
        +	movl	136(%esp),%eax
        +	movl	%ebx,(%edx)
        +	movl	%ebp,4(%edx)
        +	movl	%ecx,8(%edx)
        +	subl	$1,%eax
        +	movl	%esi,12(%edx)
        +	movl	%edi,16(%edx)
        +	jle	L001get_out
        +	movl	%eax,136(%esp)
        +	movl	%ecx,%edi
        +	movl	132(%esp),%eax
        +	movl	%ebx,%ecx
        +	addl	$64,%eax
        +	movl	%ebp,%esi
        +	movl	%eax,132(%esp)
        +	jmp	L000start
        +L001get_out:
        +	addl	$108,%esp
        +	popl	%ebx
        +	popl	%ebp
        +	popl	%edi
        +	popl	%esi
        +	ret
        diff --git a/vendor/openssl/asm/x86-macosx-gas/sha/sha1-586.s b/vendor/openssl/asm/x86-macosx-gas/sha/sha1-586.s
        new file mode 100644
        index 000000000..28d95721b
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/sha/sha1-586.s
        @@ -0,0 +1,1458 @@
        +.file	"sha1-586.s"
        +.text
        +.globl	_sha1_block_data_order
        +.align	4
        +_sha1_block_data_order:
        +L_sha1_block_data_order_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%ebp
        +	movl	24(%esp),%esi
        +	movl	28(%esp),%eax
        +	subl	$76,%esp
        +	shll	$6,%eax
        +	addl	%esi,%eax
        +	movl	%eax,104(%esp)
        +	movl	16(%ebp),%edi
        +	jmp	L000loop
        +.align	4,0x90
        +L000loop:
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edx,12(%esp)
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,16(%esp)
        +	movl	%ebx,20(%esp)
        +	movl	%ecx,24(%esp)
        +	movl	%edx,28(%esp)
        +	movl	32(%esi),%eax
        +	movl	36(%esi),%ebx
        +	movl	40(%esi),%ecx
        +	movl	44(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,40(%esp)
        +	movl	%edx,44(%esp)
        +	movl	48(%esi),%eax
        +	movl	52(%esi),%ebx
        +	movl	56(%esi),%ecx
        +	movl	60(%esi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	movl	%eax,48(%esp)
        +	movl	%ebx,52(%esp)
        +	movl	%ecx,56(%esp)
        +	movl	%edx,60(%esp)
        +	movl	%esi,100(%esp)
        +	movl	(%ebp),%eax
        +	movl	4(%ebp),%ebx
        +	movl	8(%ebp),%ecx
        +	movl	12(%ebp),%edx
        +	# 00_15 0
        +
        +	movl	%ecx,%esi
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	xorl	%edx,%esi
        +	addl	%edi,%ebp
        +	movl	(%esp),%edi
        +	andl	%ebx,%esi
        +	rorl	$2,%ebx
        +	xorl	%edx,%esi
        +	leal	1518500249(%ebp,%edi,1),%ebp
        +	addl	%esi,%ebp
        +	# 00_15 1
        +
        +	movl	%ebx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ecx,%edi
        +	addl	%edx,%ebp
        +	movl	4(%esp),%edx
        +	andl	%eax,%edi
        +	rorl	$2,%eax
        +	xorl	%ecx,%edi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	addl	%edi,%ebp
        +	# 00_15 2
        +
        +	movl	%eax,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edx
        +	addl	%ecx,%ebp
        +	movl	8(%esp),%ecx
        +	andl	%esi,%edx
        +	rorl	$2,%esi
        +	xorl	%ebx,%edx
        +	leal	1518500249(%ebp,%ecx,1),%ebp
        +	addl	%edx,%ebp
        +	# 00_15 3
        +
        +	movl	%esi,%ecx
        +	movl	%ebp,%edx
        +	roll	$5,%ebp
        +	xorl	%eax,%ecx
        +	addl	%ebx,%ebp
        +	movl	12(%esp),%ebx
        +	andl	%edi,%ecx
        +	rorl	$2,%edi
        +	xorl	%eax,%ecx
        +	leal	1518500249(%ebp,%ebx,1),%ebp
        +	addl	%ecx,%ebp
        +	# 00_15 4
        +
        +	movl	%edi,%ebx
        +	movl	%ebp,%ecx
        +	roll	$5,%ebp
        +	xorl	%esi,%ebx
        +	addl	%eax,%ebp
        +	movl	16(%esp),%eax
        +	andl	%edx,%ebx
        +	rorl	$2,%edx
        +	xorl	%esi,%ebx
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	addl	%ebx,%ebp
        +	# 00_15 5
        +
        +	movl	%edx,%eax
        +	movl	%ebp,%ebx
        +	roll	$5,%ebp
        +	xorl	%edi,%eax
        +	addl	%esi,%ebp
        +	movl	20(%esp),%esi
        +	andl	%ecx,%eax
        +	rorl	$2,%ecx
        +	xorl	%edi,%eax
        +	leal	1518500249(%ebp,%esi,1),%ebp
        +	addl	%eax,%ebp
        +	# 00_15 6
        +
        +	movl	%ecx,%esi
        +	movl	%ebp,%eax
        +	roll	$5,%ebp
        +	xorl	%edx,%esi
        +	addl	%edi,%ebp
        +	movl	24(%esp),%edi
        +	andl	%ebx,%esi
        +	rorl	$2,%ebx
        +	xorl	%edx,%esi
        +	leal	1518500249(%ebp,%edi,1),%ebp
        +	addl	%esi,%ebp
        +	# 00_15 7
        +
        +	movl	%ebx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ecx,%edi
        +	addl	%edx,%ebp
        +	movl	28(%esp),%edx
        +	andl	%eax,%edi
        +	rorl	$2,%eax
        +	xorl	%ecx,%edi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	addl	%edi,%ebp
        +	# 00_15 8
        +
        +	movl	%eax,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edx
        +	addl	%ecx,%ebp
        +	movl	32(%esp),%ecx
        +	andl	%esi,%edx
        +	rorl	$2,%esi
        +	xorl	%ebx,%edx
        +	leal	1518500249(%ebp,%ecx,1),%ebp
        +	addl	%edx,%ebp
        +	# 00_15 9
        +
        +	movl	%esi,%ecx
        +	movl	%ebp,%edx
        +	roll	$5,%ebp
        +	xorl	%eax,%ecx
        +	addl	%ebx,%ebp
        +	movl	36(%esp),%ebx
        +	andl	%edi,%ecx
        +	rorl	$2,%edi
        +	xorl	%eax,%ecx
        +	leal	1518500249(%ebp,%ebx,1),%ebp
        +	addl	%ecx,%ebp
        +	# 00_15 10
        +
        +	movl	%edi,%ebx
        +	movl	%ebp,%ecx
        +	roll	$5,%ebp
        +	xorl	%esi,%ebx
        +	addl	%eax,%ebp
        +	movl	40(%esp),%eax
        +	andl	%edx,%ebx
        +	rorl	$2,%edx
        +	xorl	%esi,%ebx
        +	leal	1518500249(%ebp,%eax,1),%ebp
        +	addl	%ebx,%ebp
        +	# 00_15 11
        +
        +	movl	%edx,%eax
        +	movl	%ebp,%ebx
        +	roll	$5,%ebp
        +	xorl	%edi,%eax
        +	addl	%esi,%ebp
        +	movl	44(%esp),%esi
        +	andl	%ecx,%eax
        +	rorl	$2,%ecx
        +	xorl	%edi,%eax
        +	leal	1518500249(%ebp,%esi,1),%ebp
        +	addl	%eax,%ebp
        +	# 00_15 12
        +
        +	movl	%ecx,%esi
        +	movl	%ebp,%eax
        +	roll	$5,%ebp
        +	xorl	%edx,%esi
        +	addl	%edi,%ebp
        +	movl	48(%esp),%edi
        +	andl	%ebx,%esi
        +	rorl	$2,%ebx
        +	xorl	%edx,%esi
        +	leal	1518500249(%ebp,%edi,1),%ebp
        +	addl	%esi,%ebp
        +	# 00_15 13
        +
        +	movl	%ebx,%edi
        +	movl	%ebp,%esi
        +	roll	$5,%ebp
        +	xorl	%ecx,%edi
        +	addl	%edx,%ebp
        +	movl	52(%esp),%edx
        +	andl	%eax,%edi
        +	rorl	$2,%eax
        +	xorl	%ecx,%edi
        +	leal	1518500249(%ebp,%edx,1),%ebp
        +	addl	%edi,%ebp
        +	# 00_15 14
        +
        +	movl	%eax,%edx
        +	movl	%ebp,%edi
        +	roll	$5,%ebp
        +	xorl	%ebx,%edx
        +	addl	%ecx,%ebp
        +	movl	56(%esp),%ecx
        +	andl	%esi,%edx
        +	rorl	$2,%esi
        +	xorl	%ebx,%edx
        +	leal	1518500249(%ebp,%ecx,1),%ebp
        +	addl	%edx,%ebp
        +	# 00_15 15
        +
        +	movl	%esi,%ecx
        +	movl	%ebp,%edx
        +	roll	$5,%ebp
        +	xorl	%eax,%ecx
        +	addl	%ebx,%ebp
        +	movl	60(%esp),%ebx
        +	andl	%edi,%ecx
        +	rorl	$2,%edi
        +	xorl	%eax,%ecx
        +	leal	1518500249(%ebp,%ebx,1),%ebp
        +	movl	(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 16_19 16
        +
        +	movl	%edi,%ebp
        +	xorl	8(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	32(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	52(%esp),%ebx
        +	roll	$1,%ebx
        +	xorl	%esi,%ebp
        +	addl	%ebp,%eax
        +	movl	%ecx,%ebp
        +	rorl	$2,%edx
        +	movl	%ebx,(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%ebx,%eax,1),%ebx
        +	movl	4(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 16_19 17
        +
        +	movl	%edx,%ebp
        +	xorl	12(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	36(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	56(%esp),%eax
        +	roll	$1,%eax
        +	xorl	%edi,%ebp
        +	addl	%ebp,%esi
        +	movl	%ebx,%ebp
        +	rorl	$2,%ecx
        +	movl	%eax,4(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%eax,%esi,1),%eax
        +	movl	8(%esp),%esi
        +	addl	%ebp,%eax
        +	# 16_19 18
        +
        +	movl	%ecx,%ebp
        +	xorl	16(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	40(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	60(%esp),%esi
        +	roll	$1,%esi
        +	xorl	%edx,%ebp
        +	addl	%ebp,%edi
        +	movl	%eax,%ebp
        +	rorl	$2,%ebx
        +	movl	%esi,8(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%esi,%edi,1),%esi
        +	movl	12(%esp),%edi
        +	addl	%ebp,%esi
        +	# 16_19 19
        +
        +	movl	%ebx,%ebp
        +	xorl	20(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	44(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	(%esp),%edi
        +	roll	$1,%edi
        +	xorl	%ecx,%ebp
        +	addl	%ebp,%edx
        +	movl	%esi,%ebp
        +	rorl	$2,%eax
        +	movl	%edi,12(%esp)
        +	roll	$5,%ebp
        +	leal	1518500249(%edi,%edx,1),%edi
        +	movl	16(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 20
        +
        +	movl	%esi,%ebp
        +	xorl	24(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,16(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	20(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 21
        +
        +	movl	%edi,%ebp
        +	xorl	28(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,20(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	24(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 20_39 22
        +
        +	movl	%edx,%ebp
        +	xorl	32(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,24(%esp)
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	28(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 20_39 23
        +
        +	movl	%ecx,%ebp
        +	xorl	36(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,28(%esp)
        +	leal	1859775393(%eax,%esi,1),%eax
        +	movl	32(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 24
        +
        +	movl	%ebx,%ebp
        +	xorl	40(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,32(%esp)
        +	leal	1859775393(%esi,%edi,1),%esi
        +	movl	36(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 25
        +
        +	movl	%eax,%ebp
        +	xorl	44(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,36(%esp)
        +	leal	1859775393(%edi,%edx,1),%edi
        +	movl	40(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 26
        +
        +	movl	%esi,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,40(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	44(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 27
        +
        +	movl	%edi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	32(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,44(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	48(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 20_39 28
        +
        +	movl	%edx,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	36(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,48(%esp)
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	52(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 20_39 29
        +
        +	movl	%ecx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	40(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,52(%esp)
        +	leal	1859775393(%eax,%esi,1),%eax
        +	movl	56(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 30
        +
        +	movl	%ebx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	44(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,56(%esp)
        +	leal	1859775393(%esi,%edi,1),%esi
        +	movl	60(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 31
        +
        +	movl	%eax,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	48(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,60(%esp)
        +	leal	1859775393(%edi,%edx,1),%edi
        +	movl	(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 32
        +
        +	movl	%esi,%ebp
        +	xorl	8(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	32(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	52(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	4(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 33
        +
        +	movl	%edi,%ebp
        +	xorl	12(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	36(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	56(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,4(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	8(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 20_39 34
        +
        +	movl	%edx,%ebp
        +	xorl	16(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	40(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	60(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,8(%esp)
        +	leal	1859775393(%ebx,%eax,1),%ebx
        +	movl	12(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 20_39 35
        +
        +	movl	%ecx,%ebp
        +	xorl	20(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	44(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,12(%esp)
        +	leal	1859775393(%eax,%esi,1),%eax
        +	movl	16(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 36
        +
        +	movl	%ebx,%ebp
        +	xorl	24(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	48(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	4(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,16(%esp)
        +	leal	1859775393(%esi,%edi,1),%esi
        +	movl	20(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 37
        +
        +	movl	%eax,%ebp
        +	xorl	28(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	52(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	8(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,20(%esp)
        +	leal	1859775393(%edi,%edx,1),%edi
        +	movl	24(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 38
        +
        +	movl	%esi,%ebp
        +	xorl	32(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	56(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	12(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,24(%esp)
        +	leal	1859775393(%edx,%ecx,1),%edx
        +	movl	28(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 39
        +
        +	movl	%edi,%ebp
        +	xorl	36(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	60(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	16(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,28(%esp)
        +	leal	1859775393(%ecx,%ebx,1),%ecx
        +	movl	32(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 40_59 40
        +
        +	movl	%edi,%ebp
        +	xorl	40(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	20(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,32(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	36(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 40_59 41
        +
        +	movl	%edx,%ebp
        +	xorl	44(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	4(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	24(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,36(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	40(%esp),%esi
        +	addl	%ebp,%eax
        +	# 40_59 42
        +
        +	movl	%ecx,%ebp
        +	xorl	48(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	8(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	28(%esp),%esi
        +	roll	$1,%esi
        +	addl	%edi,%ebp
        +	rorl	$2,%ebx
        +	movl	%eax,%edi
        +	roll	$5,%edi
        +	movl	%esi,40(%esp)
        +	leal	2400959708(%esi,%ebp,1),%esi
        +	movl	%ecx,%ebp
        +	addl	%edi,%esi
        +	andl	%edx,%ebp
        +	movl	44(%esp),%edi
        +	addl	%ebp,%esi
        +	# 40_59 43
        +
        +	movl	%ebx,%ebp
        +	xorl	52(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	12(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	32(%esp),%edi
        +	roll	$1,%edi
        +	addl	%edx,%ebp
        +	rorl	$2,%eax
        +	movl	%esi,%edx
        +	roll	$5,%edx
        +	movl	%edi,44(%esp)
        +	leal	2400959708(%edi,%ebp,1),%edi
        +	movl	%ebx,%ebp
        +	addl	%edx,%edi
        +	andl	%ecx,%ebp
        +	movl	48(%esp),%edx
        +	addl	%ebp,%edi
        +	# 40_59 44
        +
        +	movl	%eax,%ebp
        +	xorl	56(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	16(%esp),%edx
        +	andl	%esi,%ebp
        +	xorl	36(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ecx,%ebp
        +	rorl	$2,%esi
        +	movl	%edi,%ecx
        +	roll	$5,%ecx
        +	movl	%edx,48(%esp)
        +	leal	2400959708(%edx,%ebp,1),%edx
        +	movl	%eax,%ebp
        +	addl	%ecx,%edx
        +	andl	%ebx,%ebp
        +	movl	52(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 40_59 45
        +
        +	movl	%esi,%ebp
        +	xorl	60(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	20(%esp),%ecx
        +	andl	%edi,%ebp
        +	xorl	40(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebx,%ebp
        +	rorl	$2,%edi
        +	movl	%edx,%ebx
        +	roll	$5,%ebx
        +	movl	%ecx,52(%esp)
        +	leal	2400959708(%ecx,%ebp,1),%ecx
        +	movl	%esi,%ebp
        +	addl	%ebx,%ecx
        +	andl	%eax,%ebp
        +	movl	56(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 40_59 46
        +
        +	movl	%edi,%ebp
        +	xorl	(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	24(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	44(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,56(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	60(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 40_59 47
        +
        +	movl	%edx,%ebp
        +	xorl	4(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	28(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	48(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,60(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	(%esp),%esi
        +	addl	%ebp,%eax
        +	# 40_59 48
        +
        +	movl	%ecx,%ebp
        +	xorl	8(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	32(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	52(%esp),%esi
        +	roll	$1,%esi
        +	addl	%edi,%ebp
        +	rorl	$2,%ebx
        +	movl	%eax,%edi
        +	roll	$5,%edi
        +	movl	%esi,(%esp)
        +	leal	2400959708(%esi,%ebp,1),%esi
        +	movl	%ecx,%ebp
        +	addl	%edi,%esi
        +	andl	%edx,%ebp
        +	movl	4(%esp),%edi
        +	addl	%ebp,%esi
        +	# 40_59 49
        +
        +	movl	%ebx,%ebp
        +	xorl	12(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	36(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	56(%esp),%edi
        +	roll	$1,%edi
        +	addl	%edx,%ebp
        +	rorl	$2,%eax
        +	movl	%esi,%edx
        +	roll	$5,%edx
        +	movl	%edi,4(%esp)
        +	leal	2400959708(%edi,%ebp,1),%edi
        +	movl	%ebx,%ebp
        +	addl	%edx,%edi
        +	andl	%ecx,%ebp
        +	movl	8(%esp),%edx
        +	addl	%ebp,%edi
        +	# 40_59 50
        +
        +	movl	%eax,%ebp
        +	xorl	16(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	40(%esp),%edx
        +	andl	%esi,%ebp
        +	xorl	60(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ecx,%ebp
        +	rorl	$2,%esi
        +	movl	%edi,%ecx
        +	roll	$5,%ecx
        +	movl	%edx,8(%esp)
        +	leal	2400959708(%edx,%ebp,1),%edx
        +	movl	%eax,%ebp
        +	addl	%ecx,%edx
        +	andl	%ebx,%ebp
        +	movl	12(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 40_59 51
        +
        +	movl	%esi,%ebp
        +	xorl	20(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	44(%esp),%ecx
        +	andl	%edi,%ebp
        +	xorl	(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebx,%ebp
        +	rorl	$2,%edi
        +	movl	%edx,%ebx
        +	roll	$5,%ebx
        +	movl	%ecx,12(%esp)
        +	leal	2400959708(%ecx,%ebp,1),%ecx
        +	movl	%esi,%ebp
        +	addl	%ebx,%ecx
        +	andl	%eax,%ebp
        +	movl	16(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 40_59 52
        +
        +	movl	%edi,%ebp
        +	xorl	24(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	48(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	4(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,16(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	20(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 40_59 53
        +
        +	movl	%edx,%ebp
        +	xorl	28(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	52(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	8(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,20(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	24(%esp),%esi
        +	addl	%ebp,%eax
        +	# 40_59 54
        +
        +	movl	%ecx,%ebp
        +	xorl	32(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	56(%esp),%esi
        +	andl	%ebx,%ebp
        +	xorl	12(%esp),%esi
        +	roll	$1,%esi
        +	addl	%edi,%ebp
        +	rorl	$2,%ebx
        +	movl	%eax,%edi
        +	roll	$5,%edi
        +	movl	%esi,24(%esp)
        +	leal	2400959708(%esi,%ebp,1),%esi
        +	movl	%ecx,%ebp
        +	addl	%edi,%esi
        +	andl	%edx,%ebp
        +	movl	28(%esp),%edi
        +	addl	%ebp,%esi
        +	# 40_59 55
        +
        +	movl	%ebx,%ebp
        +	xorl	36(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	60(%esp),%edi
        +	andl	%eax,%ebp
        +	xorl	16(%esp),%edi
        +	roll	$1,%edi
        +	addl	%edx,%ebp
        +	rorl	$2,%eax
        +	movl	%esi,%edx
        +	roll	$5,%edx
        +	movl	%edi,28(%esp)
        +	leal	2400959708(%edi,%ebp,1),%edi
        +	movl	%ebx,%ebp
        +	addl	%edx,%edi
        +	andl	%ecx,%ebp
        +	movl	32(%esp),%edx
        +	addl	%ebp,%edi
        +	# 40_59 56
        +
        +	movl	%eax,%ebp
        +	xorl	40(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	(%esp),%edx
        +	andl	%esi,%ebp
        +	xorl	20(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ecx,%ebp
        +	rorl	$2,%esi
        +	movl	%edi,%ecx
        +	roll	$5,%ecx
        +	movl	%edx,32(%esp)
        +	leal	2400959708(%edx,%ebp,1),%edx
        +	movl	%eax,%ebp
        +	addl	%ecx,%edx
        +	andl	%ebx,%ebp
        +	movl	36(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 40_59 57
        +
        +	movl	%esi,%ebp
        +	xorl	44(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	4(%esp),%ecx
        +	andl	%edi,%ebp
        +	xorl	24(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebx,%ebp
        +	rorl	$2,%edi
        +	movl	%edx,%ebx
        +	roll	$5,%ebx
        +	movl	%ecx,36(%esp)
        +	leal	2400959708(%ecx,%ebp,1),%ecx
        +	movl	%esi,%ebp
        +	addl	%ebx,%ecx
        +	andl	%eax,%ebp
        +	movl	40(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 40_59 58
        +
        +	movl	%edi,%ebp
        +	xorl	48(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	8(%esp),%ebx
        +	andl	%edx,%ebp
        +	xorl	28(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%eax,%ebp
        +	rorl	$2,%edx
        +	movl	%ecx,%eax
        +	roll	$5,%eax
        +	movl	%ebx,40(%esp)
        +	leal	2400959708(%ebx,%ebp,1),%ebx
        +	movl	%edi,%ebp
        +	addl	%eax,%ebx
        +	andl	%esi,%ebp
        +	movl	44(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 40_59 59
        +
        +	movl	%edx,%ebp
        +	xorl	52(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	12(%esp),%eax
        +	andl	%ecx,%ebp
        +	xorl	32(%esp),%eax
        +	roll	$1,%eax
        +	addl	%esi,%ebp
        +	rorl	$2,%ecx
        +	movl	%ebx,%esi
        +	roll	$5,%esi
        +	movl	%eax,44(%esp)
        +	leal	2400959708(%eax,%ebp,1),%eax
        +	movl	%edx,%ebp
        +	addl	%esi,%eax
        +	andl	%edi,%ebp
        +	movl	48(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 60
        +
        +	movl	%ebx,%ebp
        +	xorl	56(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	16(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	36(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,48(%esp)
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	52(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 61
        +
        +	movl	%eax,%ebp
        +	xorl	60(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	20(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	40(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,52(%esp)
        +	leal	3395469782(%edi,%edx,1),%edi
        +	movl	56(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 62
        +
        +	movl	%esi,%ebp
        +	xorl	(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	24(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	44(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,56(%esp)
        +	leal	3395469782(%edx,%ecx,1),%edx
        +	movl	60(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 63
        +
        +	movl	%edi,%ebp
        +	xorl	4(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	28(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	48(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,60(%esp)
        +	leal	3395469782(%ecx,%ebx,1),%ecx
        +	movl	(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 20_39 64
        +
        +	movl	%edx,%ebp
        +	xorl	8(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	32(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	52(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,(%esp)
        +	leal	3395469782(%ebx,%eax,1),%ebx
        +	movl	4(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 20_39 65
        +
        +	movl	%ecx,%ebp
        +	xorl	12(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	36(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	56(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,4(%esp)
        +	leal	3395469782(%eax,%esi,1),%eax
        +	movl	8(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 66
        +
        +	movl	%ebx,%ebp
        +	xorl	16(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	40(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	60(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,8(%esp)
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	12(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 67
        +
        +	movl	%eax,%ebp
        +	xorl	20(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	44(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,12(%esp)
        +	leal	3395469782(%edi,%edx,1),%edi
        +	movl	16(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 68
        +
        +	movl	%esi,%ebp
        +	xorl	24(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,16(%esp)
        +	leal	3395469782(%edx,%ecx,1),%edx
        +	movl	20(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 69
        +
        +	movl	%edi,%ebp
        +	xorl	28(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,20(%esp)
        +	leal	3395469782(%ecx,%ebx,1),%ecx
        +	movl	24(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 20_39 70
        +
        +	movl	%edx,%ebp
        +	xorl	32(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,24(%esp)
        +	leal	3395469782(%ebx,%eax,1),%ebx
        +	movl	28(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 20_39 71
        +
        +	movl	%ecx,%ebp
        +	xorl	36(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	movl	%eax,28(%esp)
        +	leal	3395469782(%eax,%esi,1),%eax
        +	movl	32(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 72
        +
        +	movl	%ebx,%ebp
        +	xorl	40(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	movl	%esi,32(%esp)
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	36(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 73
        +
        +	movl	%eax,%ebp
        +	xorl	44(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	movl	%edi,36(%esp)
        +	leal	3395469782(%edi,%edx,1),%edi
        +	movl	40(%esp),%edx
        +	addl	%ebp,%edi
        +	# 20_39 74
        +
        +	movl	%esi,%ebp
        +	xorl	48(%esp),%edx
        +	xorl	%eax,%ebp
        +	xorl	8(%esp),%edx
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edx
        +	roll	$1,%edx
        +	addl	%ebp,%ecx
        +	rorl	$2,%esi
        +	movl	%edi,%ebp
        +	roll	$5,%ebp
        +	movl	%edx,40(%esp)
        +	leal	3395469782(%edx,%ecx,1),%edx
        +	movl	44(%esp),%ecx
        +	addl	%ebp,%edx
        +	# 20_39 75
        +
        +	movl	%edi,%ebp
        +	xorl	52(%esp),%ecx
        +	xorl	%esi,%ebp
        +	xorl	12(%esp),%ecx
        +	xorl	%eax,%ebp
        +	xorl	32(%esp),%ecx
        +	roll	$1,%ecx
        +	addl	%ebp,%ebx
        +	rorl	$2,%edi
        +	movl	%edx,%ebp
        +	roll	$5,%ebp
        +	movl	%ecx,44(%esp)
        +	leal	3395469782(%ecx,%ebx,1),%ecx
        +	movl	48(%esp),%ebx
        +	addl	%ebp,%ecx
        +	# 20_39 76
        +
        +	movl	%edx,%ebp
        +	xorl	56(%esp),%ebx
        +	xorl	%edi,%ebp
        +	xorl	16(%esp),%ebx
        +	xorl	%esi,%ebp
        +	xorl	36(%esp),%ebx
        +	roll	$1,%ebx
        +	addl	%ebp,%eax
        +	rorl	$2,%edx
        +	movl	%ecx,%ebp
        +	roll	$5,%ebp
        +	movl	%ebx,48(%esp)
        +	leal	3395469782(%ebx,%eax,1),%ebx
        +	movl	52(%esp),%eax
        +	addl	%ebp,%ebx
        +	# 20_39 77
        +
        +	movl	%ecx,%ebp
        +	xorl	60(%esp),%eax
        +	xorl	%edx,%ebp
        +	xorl	20(%esp),%eax
        +	xorl	%edi,%ebp
        +	xorl	40(%esp),%eax
        +	roll	$1,%eax
        +	addl	%ebp,%esi
        +	rorl	$2,%ecx
        +	movl	%ebx,%ebp
        +	roll	$5,%ebp
        +	leal	3395469782(%eax,%esi,1),%eax
        +	movl	56(%esp),%esi
        +	addl	%ebp,%eax
        +	# 20_39 78
        +
        +	movl	%ebx,%ebp
        +	xorl	(%esp),%esi
        +	xorl	%ecx,%ebp
        +	xorl	24(%esp),%esi
        +	xorl	%edx,%ebp
        +	xorl	44(%esp),%esi
        +	roll	$1,%esi
        +	addl	%ebp,%edi
        +	rorl	$2,%ebx
        +	movl	%eax,%ebp
        +	roll	$5,%ebp
        +	leal	3395469782(%esi,%edi,1),%esi
        +	movl	60(%esp),%edi
        +	addl	%ebp,%esi
        +	# 20_39 79
        +
        +	movl	%eax,%ebp
        +	xorl	4(%esp),%edi
        +	xorl	%ebx,%ebp
        +	xorl	28(%esp),%edi
        +	xorl	%ecx,%ebp
        +	xorl	48(%esp),%edi
        +	roll	$1,%edi
        +	addl	%ebp,%edx
        +	rorl	$2,%eax
        +	movl	%esi,%ebp
        +	roll	$5,%ebp
        +	leal	3395469782(%edi,%edx,1),%edi
        +	addl	%ebp,%edi
        +	movl	96(%esp),%ebp
        +	movl	100(%esp),%edx
        +	addl	(%ebp),%edi
        +	addl	4(%ebp),%esi
        +	addl	8(%ebp),%eax
        +	addl	12(%ebp),%ebx
        +	addl	16(%ebp),%ecx
        +	movl	%edi,(%ebp)
        +	addl	$64,%edx
        +	movl	%esi,4(%ebp)
        +	cmpl	104(%esp),%edx
        +	movl	%eax,8(%ebp)
        +	movl	%ecx,%edi
        +	movl	%ebx,12(%ebp)
        +	movl	%edx,%esi
        +	movl	%ecx,16(%ebp)
        +	jb	L000loop
        +	addl	$76,%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.byte	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115
        +.byte	102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82
        +.byte	89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112
        +.byte	114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/sha/sha256-586.s b/vendor/openssl/asm/x86-macosx-gas/sha/sha256-586.s
        new file mode 100644
        index 000000000..67c7a96bc
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/sha/sha256-586.s
        @@ -0,0 +1,256 @@
        +.file	"sha512-586.s"
        +.text
        +.globl	_sha256_block_data_order
        +.align	4
        +_sha256_block_data_order:
        +L_sha256_block_data_order_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	%esp,%ebx
        +	call	L000pic_point
        +L000pic_point:
        +	popl	%ebp
        +	leal	L001K256-L000pic_point(%ebp),%ebp
        +	subl	$16,%esp
        +	andl	$-64,%esp
        +	shll	$6,%eax
        +	addl	%edi,%eax
        +	movl	%esi,(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +.align	4,0x90
        +L002loop:
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	16(%edi),%eax
        +	movl	20(%edi),%ebx
        +	movl	24(%edi),%ecx
        +	movl	28(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	32(%edi),%eax
        +	movl	36(%edi),%ebx
        +	movl	40(%edi),%ecx
        +	movl	44(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	48(%edi),%eax
        +	movl	52(%edi),%ebx
        +	movl	56(%edi),%ecx
        +	movl	60(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	addl	$64,%edi
        +	subl	$32,%esp
        +	movl	%edi,100(%esp)
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edi
        +	movl	%ebx,4(%esp)
        +	movl	%ecx,8(%esp)
        +	movl	%edi,12(%esp)
        +	movl	16(%esi),%edx
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edi
        +	movl	%ebx,20(%esp)
        +	movl	%ecx,24(%esp)
        +	movl	%edi,28(%esp)
        +.align	4,0x90
        +L00300_15:
        +	movl	92(%esp),%ebx
        +	movl	%edx,%ecx
        +	rorl	$14,%ecx
        +	movl	20(%esp),%esi
        +	xorl	%edx,%ecx
        +	rorl	$5,%ecx
        +	xorl	%edx,%ecx
        +	rorl	$6,%ecx
        +	movl	24(%esp),%edi
        +	addl	%ecx,%ebx
        +	xorl	%edi,%esi
        +	movl	%edx,16(%esp)
        +	movl	%eax,%ecx
        +	andl	%edx,%esi
        +	movl	12(%esp),%edx
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	addl	%esi,%ebx
        +	rorl	$9,%ecx
        +	addl	28(%esp),%ebx
        +	xorl	%eax,%ecx
        +	rorl	$11,%ecx
        +	movl	4(%esp),%esi
        +	xorl	%eax,%ecx
        +	rorl	$2,%ecx
        +	addl	%ebx,%edx
        +	movl	8(%esp),%edi
        +	addl	%ecx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%eax,%ecx
        +	subl	$4,%esp
        +	orl	%esi,%eax
        +	andl	%esi,%ecx
        +	andl	%edi,%eax
        +	movl	(%ebp),%esi
        +	orl	%ecx,%eax
        +	addl	$4,%ebp
        +	addl	%ebx,%eax
        +	addl	%esi,%edx
        +	addl	%esi,%eax
        +	cmpl	$3248222580,%esi
        +	jne	L00300_15
        +	movl	152(%esp),%ebx
        +.align	4,0x90
        +L00416_63:
        +	movl	%ebx,%esi
        +	movl	100(%esp),%ecx
        +	rorl	$11,%esi
        +	movl	%ecx,%edi
        +	xorl	%ebx,%esi
        +	rorl	$7,%esi
        +	shrl	$3,%ebx
        +	rorl	$2,%edi
        +	xorl	%esi,%ebx
        +	xorl	%ecx,%edi
        +	rorl	$17,%edi
        +	shrl	$10,%ecx
        +	addl	156(%esp),%ebx
        +	xorl	%ecx,%edi
        +	addl	120(%esp),%ebx
        +	movl	%edx,%ecx
        +	addl	%edi,%ebx
        +	rorl	$14,%ecx
        +	movl	20(%esp),%esi
        +	xorl	%edx,%ecx
        +	rorl	$5,%ecx
        +	movl	%ebx,92(%esp)
        +	xorl	%edx,%ecx
        +	rorl	$6,%ecx
        +	movl	24(%esp),%edi
        +	addl	%ecx,%ebx
        +	xorl	%edi,%esi
        +	movl	%edx,16(%esp)
        +	movl	%eax,%ecx
        +	andl	%edx,%esi
        +	movl	12(%esp),%edx
        +	xorl	%edi,%esi
        +	movl	%eax,%edi
        +	addl	%esi,%ebx
        +	rorl	$9,%ecx
        +	addl	28(%esp),%ebx
        +	xorl	%eax,%ecx
        +	rorl	$11,%ecx
        +	movl	4(%esp),%esi
        +	xorl	%eax,%ecx
        +	rorl	$2,%ecx
        +	addl	%ebx,%edx
        +	movl	8(%esp),%edi
        +	addl	%ecx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%eax,%ecx
        +	subl	$4,%esp
        +	orl	%esi,%eax
        +	andl	%esi,%ecx
        +	andl	%edi,%eax
        +	movl	(%ebp),%esi
        +	orl	%ecx,%eax
        +	addl	$4,%ebp
        +	addl	%ebx,%eax
        +	movl	152(%esp),%ebx
        +	addl	%esi,%edx
        +	addl	%esi,%eax
        +	cmpl	$3329325298,%esi
        +	jne	L00416_63
        +	movl	352(%esp),%esi
        +	movl	4(%esp),%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edi
        +	addl	(%esi),%eax
        +	addl	4(%esi),%ebx
        +	addl	8(%esi),%ecx
        +	addl	12(%esi),%edi
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	movl	%ecx,8(%esi)
        +	movl	%edi,12(%esi)
        +	movl	20(%esp),%eax
        +	movl	24(%esp),%ebx
        +	movl	28(%esp),%ecx
        +	movl	356(%esp),%edi
        +	addl	16(%esi),%edx
        +	addl	20(%esi),%eax
        +	addl	24(%esi),%ebx
        +	addl	28(%esi),%ecx
        +	movl	%edx,16(%esi)
        +	movl	%eax,20(%esi)
        +	movl	%ebx,24(%esi)
        +	movl	%ecx,28(%esi)
        +	addl	$352,%esp
        +	subl	$256,%ebp
        +	cmpl	8(%esp),%edi
        +	jb	L002loop
        +	movl	12(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L001K256:
        +.long	1116352408,1899447441,3049323471,3921009573
        +.long	961987163,1508970993,2453635748,2870763221
        +.long	3624381080,310598401,607225278,1426881987
        +.long	1925078388,2162078206,2614888103,3248222580
        +.long	3835390401,4022224774,264347078,604807628
        +.long	770255983,1249150122,1555081692,1996064986
        +.long	2554220882,2821834349,2952996808,3210313671
        +.long	3336571891,3584528711,113926993,338241895
        +.long	666307205,773529912,1294757372,1396182291
        +.long	1695183700,1986661051,2177026350,2456956037
        +.long	2730485921,2820302411,3259730800,3345764771
        +.long	3516065817,3600352804,4094571909,275423344
        +.long	430227734,506948616,659060556,883997877
        +.long	958139571,1322822218,1537002063,1747873779
        +.long	1955562222,2024104815,2227730452,2361852424
        +.long	2428436474,2756734187,3204031479,3329325298
        +.byte	83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97
        +.byte	110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32
        +.byte	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +.byte	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +.byte	62,0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/sha/sha512-586.s b/vendor/openssl/asm/x86-macosx-gas/sha/sha512-586.s
        new file mode 100644
        index 000000000..2c9975305
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/sha/sha512-586.s
        @@ -0,0 +1,561 @@
        +.file	"sha512-586.s"
        +.text
        +.globl	_sha512_block_data_order
        +.align	4
        +_sha512_block_data_order:
        +L_sha512_block_data_order_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%eax
        +	movl	%esp,%ebx
        +	call	L000pic_point
        +L000pic_point:
        +	popl	%ebp
        +	leal	L001K512-L000pic_point(%ebp),%ebp
        +	subl	$16,%esp
        +	andl	$-64,%esp
        +	shll	$7,%eax
        +	addl	%edi,%eax
        +	movl	%esi,(%esp)
        +	movl	%edi,4(%esp)
        +	movl	%eax,8(%esp)
        +	movl	%ebx,12(%esp)
        +.align	4,0x90
        +L002loop_x86:
        +	movl	(%edi),%eax
        +	movl	4(%edi),%ebx
        +	movl	8(%edi),%ecx
        +	movl	12(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	16(%edi),%eax
        +	movl	20(%edi),%ebx
        +	movl	24(%edi),%ecx
        +	movl	28(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	32(%edi),%eax
        +	movl	36(%edi),%ebx
        +	movl	40(%edi),%ecx
        +	movl	44(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	48(%edi),%eax
        +	movl	52(%edi),%ebx
        +	movl	56(%edi),%ecx
        +	movl	60(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	64(%edi),%eax
        +	movl	68(%edi),%ebx
        +	movl	72(%edi),%ecx
        +	movl	76(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	80(%edi),%eax
        +	movl	84(%edi),%ebx
        +	movl	88(%edi),%ecx
        +	movl	92(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	96(%edi),%eax
        +	movl	100(%edi),%ebx
        +	movl	104(%edi),%ecx
        +	movl	108(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	movl	112(%edi),%eax
        +	movl	116(%edi),%ebx
        +	movl	120(%edi),%ecx
        +	movl	124(%edi),%edx
        +	bswap	%eax
        +	bswap	%ebx
        +	bswap	%ecx
        +	bswap	%edx
        +	pushl	%eax
        +	pushl	%ebx
        +	pushl	%ecx
        +	pushl	%edx
        +	addl	$128,%edi
        +	subl	$72,%esp
        +	movl	%edi,204(%esp)
        +	leal	8(%esp),%edi
        +	movl	$16,%ecx
        +.long	2784229001
        +.align	4,0x90
        +L00300_15_x86:
        +	movl	40(%esp),%ecx
        +	movl	44(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$9,%ecx
        +	movl	%edx,%edi
        +	shrl	$9,%edx
        +	movl	%ecx,%ebx
        +	shll	$14,%esi
        +	movl	%edx,%eax
        +	shll	$14,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%eax
        +	shll	$4,%esi
        +	xorl	%edx,%ebx
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$4,%ecx
        +	xorl	%edi,%eax
        +	shrl	$4,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	48(%esp),%ecx
        +	movl	52(%esp),%edx
        +	movl	56(%esp),%esi
        +	movl	60(%esp),%edi
        +	addl	64(%esp),%eax
        +	adcl	68(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	andl	40(%esp),%ecx
        +	andl	44(%esp),%edx
        +	addl	192(%esp),%eax
        +	adcl	196(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	movl	(%ebp),%esi
        +	movl	4(%ebp),%edi
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	32(%esp),%ecx
        +	movl	36(%esp),%edx
        +	addl	%esi,%eax
        +	adcl	%edi,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,%esi
        +	shrl	$2,%ecx
        +	movl	%edx,%edi
        +	shrl	$2,%edx
        +	movl	%ecx,%ebx
        +	shll	$4,%esi
        +	movl	%edx,%eax
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%ebx
        +	shll	$21,%esi
        +	xorl	%edx,%eax
        +	shll	$21,%edi
        +	xorl	%esi,%eax
        +	shrl	$21,%ecx
        +	xorl	%edi,%ebx
        +	shrl	$21,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	16(%esp),%esi
        +	movl	20(%esp),%edi
        +	addl	(%esp),%eax
        +	adcl	4(%esp),%ebx
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	andl	24(%esp),%ecx
        +	andl	28(%esp),%edx
        +	andl	8(%esp),%esi
        +	andl	12(%esp),%edi
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movb	(%ebp),%dl
        +	subl	$8,%esp
        +	leal	8(%ebp),%ebp
        +	cmpb	$148,%dl
        +	jne	L00300_15_x86
        +.align	4,0x90
        +L00416_79_x86:
        +	movl	312(%esp),%ecx
        +	movl	316(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$1,%ecx
        +	movl	%edx,%edi
        +	shrl	$1,%edx
        +	movl	%ecx,%eax
        +	shll	$24,%esi
        +	movl	%edx,%ebx
        +	shll	$24,%edi
        +	xorl	%esi,%ebx
        +	shrl	$6,%ecx
        +	xorl	%edi,%eax
        +	shrl	$6,%edx
        +	xorl	%ecx,%eax
        +	shll	$7,%esi
        +	xorl	%edx,%ebx
        +	shll	$1,%edi
        +	xorl	%esi,%ebx
        +	shrl	$1,%ecx
        +	xorl	%edi,%eax
        +	shrl	$1,%edx
        +	xorl	%ecx,%eax
        +	shll	$6,%edi
        +	xorl	%edx,%ebx
        +	xorl	%edi,%eax
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movl	208(%esp),%ecx
        +	movl	212(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$6,%ecx
        +	movl	%edx,%edi
        +	shrl	$6,%edx
        +	movl	%ecx,%eax
        +	shll	$3,%esi
        +	movl	%edx,%ebx
        +	shll	$3,%edi
        +	xorl	%esi,%eax
        +	shrl	$13,%ecx
        +	xorl	%edi,%ebx
        +	shrl	$13,%edx
        +	xorl	%ecx,%eax
        +	shll	$10,%esi
        +	xorl	%edx,%ebx
        +	shll	$10,%edi
        +	xorl	%esi,%ebx
        +	shrl	$10,%ecx
        +	xorl	%edi,%eax
        +	shrl	$10,%edx
        +	xorl	%ecx,%ebx
        +	shll	$13,%edi
        +	xorl	%edx,%eax
        +	xorl	%edi,%eax
        +	movl	320(%esp),%ecx
        +	movl	324(%esp),%edx
        +	addl	(%esp),%eax
        +	adcl	4(%esp),%ebx
        +	movl	248(%esp),%esi
        +	movl	252(%esp),%edi
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	addl	%esi,%eax
        +	adcl	%edi,%ebx
        +	movl	%eax,192(%esp)
        +	movl	%ebx,196(%esp)
        +	movl	40(%esp),%ecx
        +	movl	44(%esp),%edx
        +	movl	%ecx,%esi
        +	shrl	$9,%ecx
        +	movl	%edx,%edi
        +	shrl	$9,%edx
        +	movl	%ecx,%ebx
        +	shll	$14,%esi
        +	movl	%edx,%eax
        +	shll	$14,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%eax
        +	shll	$4,%esi
        +	xorl	%edx,%ebx
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$4,%ecx
        +	xorl	%edi,%eax
        +	shrl	$4,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	48(%esp),%ecx
        +	movl	52(%esp),%edx
        +	movl	56(%esp),%esi
        +	movl	60(%esp),%edi
        +	addl	64(%esp),%eax
        +	adcl	68(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	andl	40(%esp),%ecx
        +	andl	44(%esp),%edx
        +	addl	192(%esp),%eax
        +	adcl	196(%esp),%ebx
        +	xorl	%esi,%ecx
        +	xorl	%edi,%edx
        +	movl	(%ebp),%esi
        +	movl	4(%ebp),%edi
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	32(%esp),%ecx
        +	movl	36(%esp),%edx
        +	addl	%esi,%eax
        +	adcl	%edi,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	%eax,32(%esp)
        +	movl	%ebx,36(%esp)
        +	movl	%ecx,%esi
        +	shrl	$2,%ecx
        +	movl	%edx,%edi
        +	shrl	$2,%edx
        +	movl	%ecx,%ebx
        +	shll	$4,%esi
        +	movl	%edx,%eax
        +	shll	$4,%edi
        +	xorl	%esi,%ebx
        +	shrl	$5,%ecx
        +	xorl	%edi,%eax
        +	shrl	$5,%edx
        +	xorl	%ecx,%ebx
        +	shll	$21,%esi
        +	xorl	%edx,%eax
        +	shll	$21,%edi
        +	xorl	%esi,%eax
        +	shrl	$21,%ecx
        +	xorl	%edi,%ebx
        +	shrl	$21,%edx
        +	xorl	%ecx,%eax
        +	shll	$5,%esi
        +	xorl	%edx,%ebx
        +	shll	$5,%edi
        +	xorl	%esi,%eax
        +	xorl	%edi,%ebx
        +	movl	8(%esp),%ecx
        +	movl	12(%esp),%edx
        +	movl	16(%esp),%esi
        +	movl	20(%esp),%edi
        +	addl	(%esp),%eax
        +	adcl	4(%esp),%ebx
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	andl	24(%esp),%ecx
        +	andl	28(%esp),%edx
        +	andl	8(%esp),%esi
        +	andl	12(%esp),%edi
        +	orl	%esi,%ecx
        +	orl	%edi,%edx
        +	addl	%ecx,%eax
        +	adcl	%edx,%ebx
        +	movl	%eax,(%esp)
        +	movl	%ebx,4(%esp)
        +	movb	(%ebp),%dl
        +	subl	$8,%esp
        +	leal	8(%ebp),%ebp
        +	cmpb	$23,%dl
        +	jne	L00416_79_x86
        +	movl	840(%esp),%esi
        +	movl	844(%esp),%edi
        +	movl	(%esi),%eax
        +	movl	4(%esi),%ebx
        +	movl	8(%esi),%ecx
        +	movl	12(%esi),%edx
        +	addl	8(%esp),%eax
        +	adcl	12(%esp),%ebx
        +	movl	%eax,(%esi)
        +	movl	%ebx,4(%esi)
        +	addl	16(%esp),%ecx
        +	adcl	20(%esp),%edx
        +	movl	%ecx,8(%esi)
        +	movl	%edx,12(%esi)
        +	movl	16(%esi),%eax
        +	movl	20(%esi),%ebx
        +	movl	24(%esi),%ecx
        +	movl	28(%esi),%edx
        +	addl	24(%esp),%eax
        +	adcl	28(%esp),%ebx
        +	movl	%eax,16(%esi)
        +	movl	%ebx,20(%esi)
        +	addl	32(%esp),%ecx
        +	adcl	36(%esp),%edx
        +	movl	%ecx,24(%esi)
        +	movl	%edx,28(%esi)
        +	movl	32(%esi),%eax
        +	movl	36(%esi),%ebx
        +	movl	40(%esi),%ecx
        +	movl	44(%esi),%edx
        +	addl	40(%esp),%eax
        +	adcl	44(%esp),%ebx
        +	movl	%eax,32(%esi)
        +	movl	%ebx,36(%esi)
        +	addl	48(%esp),%ecx
        +	adcl	52(%esp),%edx
        +	movl	%ecx,40(%esi)
        +	movl	%edx,44(%esi)
        +	movl	48(%esi),%eax
        +	movl	52(%esi),%ebx
        +	movl	56(%esi),%ecx
        +	movl	60(%esi),%edx
        +	addl	56(%esp),%eax
        +	adcl	60(%esp),%ebx
        +	movl	%eax,48(%esi)
        +	movl	%ebx,52(%esi)
        +	addl	64(%esp),%ecx
        +	adcl	68(%esp),%edx
        +	movl	%ecx,56(%esi)
        +	movl	%edx,60(%esi)
        +	addl	$840,%esp
        +	subl	$640,%ebp
        +	cmpl	8(%esp),%edi
        +	jb	L002loop_x86
        +	movl	12(%esp),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L001K512:
        +.long	3609767458,1116352408
        +.long	602891725,1899447441
        +.long	3964484399,3049323471
        +.long	2173295548,3921009573
        +.long	4081628472,961987163
        +.long	3053834265,1508970993
        +.long	2937671579,2453635748
        +.long	3664609560,2870763221
        +.long	2734883394,3624381080
        +.long	1164996542,310598401
        +.long	1323610764,607225278
        +.long	3590304994,1426881987
        +.long	4068182383,1925078388
        +.long	991336113,2162078206
        +.long	633803317,2614888103
        +.long	3479774868,3248222580
        +.long	2666613458,3835390401
        +.long	944711139,4022224774
        +.long	2341262773,264347078
        +.long	2007800933,604807628
        +.long	1495990901,770255983
        +.long	1856431235,1249150122
        +.long	3175218132,1555081692
        +.long	2198950837,1996064986
        +.long	3999719339,2554220882
        +.long	766784016,2821834349
        +.long	2566594879,2952996808
        +.long	3203337956,3210313671
        +.long	1034457026,3336571891
        +.long	2466948901,3584528711
        +.long	3758326383,113926993
        +.long	168717936,338241895
        +.long	1188179964,666307205
        +.long	1546045734,773529912
        +.long	1522805485,1294757372
        +.long	2643833823,1396182291
        +.long	2343527390,1695183700
        +.long	1014477480,1986661051
        +.long	1206759142,2177026350
        +.long	344077627,2456956037
        +.long	1290863460,2730485921
        +.long	3158454273,2820302411
        +.long	3505952657,3259730800
        +.long	106217008,3345764771
        +.long	3606008344,3516065817
        +.long	1432725776,3600352804
        +.long	1467031594,4094571909
        +.long	851169720,275423344
        +.long	3100823752,430227734
        +.long	1363258195,506948616
        +.long	3750685593,659060556
        +.long	3785050280,883997877
        +.long	3318307427,958139571
        +.long	3812723403,1322822218
        +.long	2003034995,1537002063
        +.long	3602036899,1747873779
        +.long	1575990012,1955562222
        +.long	1125592928,2024104815
        +.long	2716904306,2227730452
        +.long	442776044,2361852424
        +.long	593698344,2428436474
        +.long	3733110249,2756734187
        +.long	2999351573,3204031479
        +.long	3815920427,3329325298
        +.long	3928383900,3391569614
        +.long	566280711,3515267271
        +.long	3454069534,3940187606
        +.long	4000239992,4118630271
        +.long	1914138554,116418474
        +.long	2731055270,174292421
        +.long	3203993006,289380356
        +.long	320620315,460393269
        +.long	587496836,685471733
        +.long	1086792851,852142971
        +.long	365543100,1017036298
        +.long	2618297676,1126000580
        +.long	3409855158,1288033470
        +.long	4234509866,1501505948
        +.long	987167468,1607167915
        +.long	1246189591,1816402316
        +.byte	83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97
        +.byte	110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32
        +.byte	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +.byte	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +.byte	62,0
        diff --git a/vendor/openssl/asm/x86-macosx-gas/whrlpool/wp-mmx.s b/vendor/openssl/asm/x86-macosx-gas/whrlpool/wp-mmx.s
        new file mode 100644
        index 000000000..5d612e0f7
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/whrlpool/wp-mmx.s
        @@ -0,0 +1,1103 @@
        +.file	"wp-mmx.s"
        +.text
        +.globl	_whirlpool_block_mmx
        +.align	4
        +_whirlpool_block_mmx:
        +L_whirlpool_block_mmx_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	movl	20(%esp),%esi
        +	movl	24(%esp),%edi
        +	movl	28(%esp),%ebp
        +	movl	%esp,%eax
        +	subl	$148,%esp
        +	andl	$-64,%esp
        +	leal	128(%esp),%ebx
        +	movl	%esi,(%ebx)
        +	movl	%edi,4(%ebx)
        +	movl	%ebp,8(%ebx)
        +	movl	%eax,16(%ebx)
        +	call	L000pic_point
        +L000pic_point:
        +	popl	%ebp
        +	leal	L001table-L000pic_point(%ebp),%ebp
        +	xorl	%ecx,%ecx
        +	xorl	%edx,%edx
        +	movq	(%esi),%mm0
        +	movq	8(%esi),%mm1
        +	movq	16(%esi),%mm2
        +	movq	24(%esi),%mm3
        +	movq	32(%esi),%mm4
        +	movq	40(%esi),%mm5
        +	movq	48(%esi),%mm6
        +	movq	56(%esi),%mm7
        +L002outerloop:
        +	movq	%mm0,(%esp)
        +	movq	%mm1,8(%esp)
        +	movq	%mm2,16(%esp)
        +	movq	%mm3,24(%esp)
        +	movq	%mm4,32(%esp)
        +	movq	%mm5,40(%esp)
        +	movq	%mm6,48(%esp)
        +	movq	%mm7,56(%esp)
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm1
        +	pxor	16(%edi),%mm2
        +	pxor	24(%edi),%mm3
        +	pxor	32(%edi),%mm4
        +	pxor	40(%edi),%mm5
        +	pxor	48(%edi),%mm6
        +	pxor	56(%edi),%mm7
        +	movq	%mm0,64(%esp)
        +	movq	%mm1,72(%esp)
        +	movq	%mm2,80(%esp)
        +	movq	%mm3,88(%esp)
        +	movq	%mm4,96(%esp)
        +	movq	%mm5,104(%esp)
        +	movq	%mm6,112(%esp)
        +	movq	%mm7,120(%esp)
        +	xorl	%esi,%esi
        +	movl	%esi,12(%ebx)
        +.align	4,0x90
        +L003round:
        +	movq	4096(%ebp,%esi,8),%mm0
        +	movl	(%esp),%eax
        +	movl	4(%esp),%ebx
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm0
        +	movq	7(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	8(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	movq	6(%ebp,%esi,8),%mm2
        +	movq	5(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	movq	4(%ebp,%esi,8),%mm4
        +	movq	3(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	12(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	movq	2(%ebp,%esi,8),%mm6
        +	movq	1(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm1
        +	pxor	7(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	16(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm3
        +	pxor	5(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm5
        +	pxor	3(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	20(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm7
        +	pxor	1(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm2
        +	pxor	7(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	24(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm4
        +	pxor	5(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm6
        +	pxor	3(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	28(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm0
        +	pxor	1(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm3
        +	pxor	7(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	32(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm5
        +	pxor	5(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm7
        +	pxor	3(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	36(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm1
        +	pxor	1(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm4
        +	pxor	7(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	40(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm6
        +	pxor	5(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm0
        +	pxor	3(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	44(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm2
        +	pxor	1(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm5
        +	pxor	7(%ebp,%edi,8),%mm6
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	48(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm7
        +	pxor	5(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm1
        +	pxor	3(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	52(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm3
        +	pxor	1(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm6
        +	pxor	7(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	56(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm0
        +	pxor	5(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm2
        +	pxor	3(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	60(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm4
        +	pxor	1(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm7
        +	pxor	7(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	64(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm1
        +	pxor	5(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm3
        +	pxor	3(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	68(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm5
        +	pxor	1(%ebp,%edi,8),%mm6
        +	movq	%mm0,(%esp)
        +	movq	%mm1,8(%esp)
        +	movq	%mm2,16(%esp)
        +	movq	%mm3,24(%esp)
        +	movq	%mm4,32(%esp)
        +	movq	%mm5,40(%esp)
        +	movq	%mm6,48(%esp)
        +	movq	%mm7,56(%esp)
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm0
        +	pxor	7(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	72(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm2
        +	pxor	5(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm4
        +	pxor	3(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	76(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm6
        +	pxor	1(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm1
        +	pxor	7(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	80(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm3
        +	pxor	5(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm5
        +	pxor	3(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	84(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm7
        +	pxor	1(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm2
        +	pxor	7(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	88(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm4
        +	pxor	5(%ebp,%edi,8),%mm5
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm6
        +	pxor	3(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	92(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm0
        +	pxor	1(%ebp,%edi,8),%mm1
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm3
        +	pxor	7(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	96(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm5
        +	pxor	5(%ebp,%edi,8),%mm6
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm7
        +	pxor	3(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	100(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm1
        +	pxor	1(%ebp,%edi,8),%mm2
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm4
        +	pxor	7(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	104(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm6
        +	pxor	5(%ebp,%edi,8),%mm7
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm0
        +	pxor	3(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	108(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm2
        +	pxor	1(%ebp,%edi,8),%mm3
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm5
        +	pxor	7(%ebp,%edi,8),%mm6
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	112(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm7
        +	pxor	5(%ebp,%edi,8),%mm0
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm1
        +	pxor	3(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	116(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm3
        +	pxor	1(%ebp,%edi,8),%mm4
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm6
        +	pxor	7(%ebp,%edi,8),%mm7
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	movl	120(%esp),%eax
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm0
        +	pxor	5(%ebp,%edi,8),%mm1
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm2
        +	pxor	3(%ebp,%edi,8),%mm3
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	movl	124(%esp),%ebx
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm4
        +	pxor	1(%ebp,%edi,8),%mm5
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%eax
        +	pxor	(%ebp,%esi,8),%mm7
        +	pxor	7(%ebp,%edi,8),%mm0
        +	movb	%al,%cl
        +	movb	%ah,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	6(%ebp,%esi,8),%mm1
        +	pxor	5(%ebp,%edi,8),%mm2
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	shrl	$16,%ebx
        +	pxor	4(%ebp,%esi,8),%mm3
        +	pxor	3(%ebp,%edi,8),%mm4
        +	movb	%bl,%cl
        +	movb	%bh,%dl
        +	leal	(%ecx,%ecx,1),%esi
        +	leal	(%edx,%edx,1),%edi
        +	pxor	2(%ebp,%esi,8),%mm5
        +	pxor	1(%ebp,%edi,8),%mm6
        +	leal	128(%esp),%ebx
        +	movl	12(%ebx),%esi
        +	addl	$1,%esi
        +	cmpl	$10,%esi
        +	je	L004roundsdone
        +	movl	%esi,12(%ebx)
        +	movq	%mm0,64(%esp)
        +	movq	%mm1,72(%esp)
        +	movq	%mm2,80(%esp)
        +	movq	%mm3,88(%esp)
        +	movq	%mm4,96(%esp)
        +	movq	%mm5,104(%esp)
        +	movq	%mm6,112(%esp)
        +	movq	%mm7,120(%esp)
        +	jmp	L003round
        +.align	4,0x90
        +L004roundsdone:
        +	movl	(%ebx),%esi
        +	movl	4(%ebx),%edi
        +	movl	8(%ebx),%eax
        +	pxor	(%edi),%mm0
        +	pxor	8(%edi),%mm1
        +	pxor	16(%edi),%mm2
        +	pxor	24(%edi),%mm3
        +	pxor	32(%edi),%mm4
        +	pxor	40(%edi),%mm5
        +	pxor	48(%edi),%mm6
        +	pxor	56(%edi),%mm7
        +	pxor	(%esi),%mm0
        +	pxor	8(%esi),%mm1
        +	pxor	16(%esi),%mm2
        +	pxor	24(%esi),%mm3
        +	pxor	32(%esi),%mm4
        +	pxor	40(%esi),%mm5
        +	pxor	48(%esi),%mm6
        +	pxor	56(%esi),%mm7
        +	movq	%mm0,(%esi)
        +	movq	%mm1,8(%esi)
        +	movq	%mm2,16(%esi)
        +	movq	%mm3,24(%esi)
        +	movq	%mm4,32(%esi)
        +	movq	%mm5,40(%esi)
        +	movq	%mm6,48(%esi)
        +	movq	%mm7,56(%esi)
        +	leal	64(%edi),%edi
        +	subl	$1,%eax
        +	jz	L005alldone
        +	movl	%edi,4(%ebx)
        +	movl	%eax,8(%ebx)
        +	jmp	L002outerloop
        +L005alldone:
        +	emms
        +	movl	16(%ebx),%esp
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.align	6,0x90
        +L001table:
        +.byte	24,24,96,24,192,120,48,216
        +.byte	24,24,96,24,192,120,48,216
        +.byte	35,35,140,35,5,175,70,38
        +.byte	35,35,140,35,5,175,70,38
        +.byte	198,198,63,198,126,249,145,184
        +.byte	198,198,63,198,126,249,145,184
        +.byte	232,232,135,232,19,111,205,251
        +.byte	232,232,135,232,19,111,205,251
        +.byte	135,135,38,135,76,161,19,203
        +.byte	135,135,38,135,76,161,19,203
        +.byte	184,184,218,184,169,98,109,17
        +.byte	184,184,218,184,169,98,109,17
        +.byte	1,1,4,1,8,5,2,9
        +.byte	1,1,4,1,8,5,2,9
        +.byte	79,79,33,79,66,110,158,13
        +.byte	79,79,33,79,66,110,158,13
        +.byte	54,54,216,54,173,238,108,155
        +.byte	54,54,216,54,173,238,108,155
        +.byte	166,166,162,166,89,4,81,255
        +.byte	166,166,162,166,89,4,81,255
        +.byte	210,210,111,210,222,189,185,12
        +.byte	210,210,111,210,222,189,185,12
        +.byte	245,245,243,245,251,6,247,14
        +.byte	245,245,243,245,251,6,247,14
        +.byte	121,121,249,121,239,128,242,150
        +.byte	121,121,249,121,239,128,242,150
        +.byte	111,111,161,111,95,206,222,48
        +.byte	111,111,161,111,95,206,222,48
        +.byte	145,145,126,145,252,239,63,109
        +.byte	145,145,126,145,252,239,63,109
        +.byte	82,82,85,82,170,7,164,248
        +.byte	82,82,85,82,170,7,164,248
        +.byte	96,96,157,96,39,253,192,71
        +.byte	96,96,157,96,39,253,192,71
        +.byte	188,188,202,188,137,118,101,53
        +.byte	188,188,202,188,137,118,101,53
        +.byte	155,155,86,155,172,205,43,55
        +.byte	155,155,86,155,172,205,43,55
        +.byte	142,142,2,142,4,140,1,138
        +.byte	142,142,2,142,4,140,1,138
        +.byte	163,163,182,163,113,21,91,210
        +.byte	163,163,182,163,113,21,91,210
        +.byte	12,12,48,12,96,60,24,108
        +.byte	12,12,48,12,96,60,24,108
        +.byte	123,123,241,123,255,138,246,132
        +.byte	123,123,241,123,255,138,246,132
        +.byte	53,53,212,53,181,225,106,128
        +.byte	53,53,212,53,181,225,106,128
        +.byte	29,29,116,29,232,105,58,245
        +.byte	29,29,116,29,232,105,58,245
        +.byte	224,224,167,224,83,71,221,179
        +.byte	224,224,167,224,83,71,221,179
        +.byte	215,215,123,215,246,172,179,33
        +.byte	215,215,123,215,246,172,179,33
        +.byte	194,194,47,194,94,237,153,156
        +.byte	194,194,47,194,94,237,153,156
        +.byte	46,46,184,46,109,150,92,67
        +.byte	46,46,184,46,109,150,92,67
        +.byte	75,75,49,75,98,122,150,41
        +.byte	75,75,49,75,98,122,150,41
        +.byte	254,254,223,254,163,33,225,93
        +.byte	254,254,223,254,163,33,225,93
        +.byte	87,87,65,87,130,22,174,213
        +.byte	87,87,65,87,130,22,174,213
        +.byte	21,21,84,21,168,65,42,189
        +.byte	21,21,84,21,168,65,42,189
        +.byte	119,119,193,119,159,182,238,232
        +.byte	119,119,193,119,159,182,238,232
        +.byte	55,55,220,55,165,235,110,146
        +.byte	55,55,220,55,165,235,110,146
        +.byte	229,229,179,229,123,86,215,158
        +.byte	229,229,179,229,123,86,215,158
        +.byte	159,159,70,159,140,217,35,19
        +.byte	159,159,70,159,140,217,35,19
        +.byte	240,240,231,240,211,23,253,35
        +.byte	240,240,231,240,211,23,253,35
        +.byte	74,74,53,74,106,127,148,32
        +.byte	74,74,53,74,106,127,148,32
        +.byte	218,218,79,218,158,149,169,68
        +.byte	218,218,79,218,158,149,169,68
        +.byte	88,88,125,88,250,37,176,162
        +.byte	88,88,125,88,250,37,176,162
        +.byte	201,201,3,201,6,202,143,207
        +.byte	201,201,3,201,6,202,143,207
        +.byte	41,41,164,41,85,141,82,124
        +.byte	41,41,164,41,85,141,82,124
        +.byte	10,10,40,10,80,34,20,90
        +.byte	10,10,40,10,80,34,20,90
        +.byte	177,177,254,177,225,79,127,80
        +.byte	177,177,254,177,225,79,127,80
        +.byte	160,160,186,160,105,26,93,201
        +.byte	160,160,186,160,105,26,93,201
        +.byte	107,107,177,107,127,218,214,20
        +.byte	107,107,177,107,127,218,214,20
        +.byte	133,133,46,133,92,171,23,217
        +.byte	133,133,46,133,92,171,23,217
        +.byte	189,189,206,189,129,115,103,60
        +.byte	189,189,206,189,129,115,103,60
        +.byte	93,93,105,93,210,52,186,143
        +.byte	93,93,105,93,210,52,186,143
        +.byte	16,16,64,16,128,80,32,144
        +.byte	16,16,64,16,128,80,32,144
        +.byte	244,244,247,244,243,3,245,7
        +.byte	244,244,247,244,243,3,245,7
        +.byte	203,203,11,203,22,192,139,221
        +.byte	203,203,11,203,22,192,139,221
        +.byte	62,62,248,62,237,198,124,211
        +.byte	62,62,248,62,237,198,124,211
        +.byte	5,5,20,5,40,17,10,45
        +.byte	5,5,20,5,40,17,10,45
        +.byte	103,103,129,103,31,230,206,120
        +.byte	103,103,129,103,31,230,206,120
        +.byte	228,228,183,228,115,83,213,151
        +.byte	228,228,183,228,115,83,213,151
        +.byte	39,39,156,39,37,187,78,2
        +.byte	39,39,156,39,37,187,78,2
        +.byte	65,65,25,65,50,88,130,115
        +.byte	65,65,25,65,50,88,130,115
        +.byte	139,139,22,139,44,157,11,167
        +.byte	139,139,22,139,44,157,11,167
        +.byte	167,167,166,167,81,1,83,246
        +.byte	167,167,166,167,81,1,83,246
        +.byte	125,125,233,125,207,148,250,178
        +.byte	125,125,233,125,207,148,250,178
        +.byte	149,149,110,149,220,251,55,73
        +.byte	149,149,110,149,220,251,55,73
        +.byte	216,216,71,216,142,159,173,86
        +.byte	216,216,71,216,142,159,173,86
        +.byte	251,251,203,251,139,48,235,112
        +.byte	251,251,203,251,139,48,235,112
        +.byte	238,238,159,238,35,113,193,205
        +.byte	238,238,159,238,35,113,193,205
        +.byte	124,124,237,124,199,145,248,187
        +.byte	124,124,237,124,199,145,248,187
        +.byte	102,102,133,102,23,227,204,113
        +.byte	102,102,133,102,23,227,204,113
        +.byte	221,221,83,221,166,142,167,123
        +.byte	221,221,83,221,166,142,167,123
        +.byte	23,23,92,23,184,75,46,175
        +.byte	23,23,92,23,184,75,46,175
        +.byte	71,71,1,71,2,70,142,69
        +.byte	71,71,1,71,2,70,142,69
        +.byte	158,158,66,158,132,220,33,26
        +.byte	158,158,66,158,132,220,33,26
        +.byte	202,202,15,202,30,197,137,212
        +.byte	202,202,15,202,30,197,137,212
        +.byte	45,45,180,45,117,153,90,88
        +.byte	45,45,180,45,117,153,90,88
        +.byte	191,191,198,191,145,121,99,46
        +.byte	191,191,198,191,145,121,99,46
        +.byte	7,7,28,7,56,27,14,63
        +.byte	7,7,28,7,56,27,14,63
        +.byte	173,173,142,173,1,35,71,172
        +.byte	173,173,142,173,1,35,71,172
        +.byte	90,90,117,90,234,47,180,176
        +.byte	90,90,117,90,234,47,180,176
        +.byte	131,131,54,131,108,181,27,239
        +.byte	131,131,54,131,108,181,27,239
        +.byte	51,51,204,51,133,255,102,182
        +.byte	51,51,204,51,133,255,102,182
        +.byte	99,99,145,99,63,242,198,92
        +.byte	99,99,145,99,63,242,198,92
        +.byte	2,2,8,2,16,10,4,18
        +.byte	2,2,8,2,16,10,4,18
        +.byte	170,170,146,170,57,56,73,147
        +.byte	170,170,146,170,57,56,73,147
        +.byte	113,113,217,113,175,168,226,222
        +.byte	113,113,217,113,175,168,226,222
        +.byte	200,200,7,200,14,207,141,198
        +.byte	200,200,7,200,14,207,141,198
        +.byte	25,25,100,25,200,125,50,209
        +.byte	25,25,100,25,200,125,50,209
        +.byte	73,73,57,73,114,112,146,59
        +.byte	73,73,57,73,114,112,146,59
        +.byte	217,217,67,217,134,154,175,95
        +.byte	217,217,67,217,134,154,175,95
        +.byte	242,242,239,242,195,29,249,49
        +.byte	242,242,239,242,195,29,249,49
        +.byte	227,227,171,227,75,72,219,168
        +.byte	227,227,171,227,75,72,219,168
        +.byte	91,91,113,91,226,42,182,185
        +.byte	91,91,113,91,226,42,182,185
        +.byte	136,136,26,136,52,146,13,188
        +.byte	136,136,26,136,52,146,13,188
        +.byte	154,154,82,154,164,200,41,62
        +.byte	154,154,82,154,164,200,41,62
        +.byte	38,38,152,38,45,190,76,11
        +.byte	38,38,152,38,45,190,76,11
        +.byte	50,50,200,50,141,250,100,191
        +.byte	50,50,200,50,141,250,100,191
        +.byte	176,176,250,176,233,74,125,89
        +.byte	176,176,250,176,233,74,125,89
        +.byte	233,233,131,233,27,106,207,242
        +.byte	233,233,131,233,27,106,207,242
        +.byte	15,15,60,15,120,51,30,119
        +.byte	15,15,60,15,120,51,30,119
        +.byte	213,213,115,213,230,166,183,51
        +.byte	213,213,115,213,230,166,183,51
        +.byte	128,128,58,128,116,186,29,244
        +.byte	128,128,58,128,116,186,29,244
        +.byte	190,190,194,190,153,124,97,39
        +.byte	190,190,194,190,153,124,97,39
        +.byte	205,205,19,205,38,222,135,235
        +.byte	205,205,19,205,38,222,135,235
        +.byte	52,52,208,52,189,228,104,137
        +.byte	52,52,208,52,189,228,104,137
        +.byte	72,72,61,72,122,117,144,50
        +.byte	72,72,61,72,122,117,144,50
        +.byte	255,255,219,255,171,36,227,84
        +.byte	255,255,219,255,171,36,227,84
        +.byte	122,122,245,122,247,143,244,141
        +.byte	122,122,245,122,247,143,244,141
        +.byte	144,144,122,144,244,234,61,100
        +.byte	144,144,122,144,244,234,61,100
        +.byte	95,95,97,95,194,62,190,157
        +.byte	95,95,97,95,194,62,190,157
        +.byte	32,32,128,32,29,160,64,61
        +.byte	32,32,128,32,29,160,64,61
        +.byte	104,104,189,104,103,213,208,15
        +.byte	104,104,189,104,103,213,208,15
        +.byte	26,26,104,26,208,114,52,202
        +.byte	26,26,104,26,208,114,52,202
        +.byte	174,174,130,174,25,44,65,183
        +.byte	174,174,130,174,25,44,65,183
        +.byte	180,180,234,180,201,94,117,125
        +.byte	180,180,234,180,201,94,117,125
        +.byte	84,84,77,84,154,25,168,206
        +.byte	84,84,77,84,154,25,168,206
        +.byte	147,147,118,147,236,229,59,127
        +.byte	147,147,118,147,236,229,59,127
        +.byte	34,34,136,34,13,170,68,47
        +.byte	34,34,136,34,13,170,68,47
        +.byte	100,100,141,100,7,233,200,99
        +.byte	100,100,141,100,7,233,200,99
        +.byte	241,241,227,241,219,18,255,42
        +.byte	241,241,227,241,219,18,255,42
        +.byte	115,115,209,115,191,162,230,204
        +.byte	115,115,209,115,191,162,230,204
        +.byte	18,18,72,18,144,90,36,130
        +.byte	18,18,72,18,144,90,36,130
        +.byte	64,64,29,64,58,93,128,122
        +.byte	64,64,29,64,58,93,128,122
        +.byte	8,8,32,8,64,40,16,72
        +.byte	8,8,32,8,64,40,16,72
        +.byte	195,195,43,195,86,232,155,149
        +.byte	195,195,43,195,86,232,155,149
        +.byte	236,236,151,236,51,123,197,223
        +.byte	236,236,151,236,51,123,197,223
        +.byte	219,219,75,219,150,144,171,77
        +.byte	219,219,75,219,150,144,171,77
        +.byte	161,161,190,161,97,31,95,192
        +.byte	161,161,190,161,97,31,95,192
        +.byte	141,141,14,141,28,131,7,145
        +.byte	141,141,14,141,28,131,7,145
        +.byte	61,61,244,61,245,201,122,200
        +.byte	61,61,244,61,245,201,122,200
        +.byte	151,151,102,151,204,241,51,91
        +.byte	151,151,102,151,204,241,51,91
        +.byte	0,0,0,0,0,0,0,0
        +.byte	0,0,0,0,0,0,0,0
        +.byte	207,207,27,207,54,212,131,249
        +.byte	207,207,27,207,54,212,131,249
        +.byte	43,43,172,43,69,135,86,110
        +.byte	43,43,172,43,69,135,86,110
        +.byte	118,118,197,118,151,179,236,225
        +.byte	118,118,197,118,151,179,236,225
        +.byte	130,130,50,130,100,176,25,230
        +.byte	130,130,50,130,100,176,25,230
        +.byte	214,214,127,214,254,169,177,40
        +.byte	214,214,127,214,254,169,177,40
        +.byte	27,27,108,27,216,119,54,195
        +.byte	27,27,108,27,216,119,54,195
        +.byte	181,181,238,181,193,91,119,116
        +.byte	181,181,238,181,193,91,119,116
        +.byte	175,175,134,175,17,41,67,190
        +.byte	175,175,134,175,17,41,67,190
        +.byte	106,106,181,106,119,223,212,29
        +.byte	106,106,181,106,119,223,212,29
        +.byte	80,80,93,80,186,13,160,234
        +.byte	80,80,93,80,186,13,160,234
        +.byte	69,69,9,69,18,76,138,87
        +.byte	69,69,9,69,18,76,138,87
        +.byte	243,243,235,243,203,24,251,56
        +.byte	243,243,235,243,203,24,251,56
        +.byte	48,48,192,48,157,240,96,173
        +.byte	48,48,192,48,157,240,96,173
        +.byte	239,239,155,239,43,116,195,196
        +.byte	239,239,155,239,43,116,195,196
        +.byte	63,63,252,63,229,195,126,218
        +.byte	63,63,252,63,229,195,126,218
        +.byte	85,85,73,85,146,28,170,199
        +.byte	85,85,73,85,146,28,170,199
        +.byte	162,162,178,162,121,16,89,219
        +.byte	162,162,178,162,121,16,89,219
        +.byte	234,234,143,234,3,101,201,233
        +.byte	234,234,143,234,3,101,201,233
        +.byte	101,101,137,101,15,236,202,106
        +.byte	101,101,137,101,15,236,202,106
        +.byte	186,186,210,186,185,104,105,3
        +.byte	186,186,210,186,185,104,105,3
        +.byte	47,47,188,47,101,147,94,74
        +.byte	47,47,188,47,101,147,94,74
        +.byte	192,192,39,192,78,231,157,142
        +.byte	192,192,39,192,78,231,157,142
        +.byte	222,222,95,222,190,129,161,96
        +.byte	222,222,95,222,190,129,161,96
        +.byte	28,28,112,28,224,108,56,252
        +.byte	28,28,112,28,224,108,56,252
        +.byte	253,253,211,253,187,46,231,70
        +.byte	253,253,211,253,187,46,231,70
        +.byte	77,77,41,77,82,100,154,31
        +.byte	77,77,41,77,82,100,154,31
        +.byte	146,146,114,146,228,224,57,118
        +.byte	146,146,114,146,228,224,57,118
        +.byte	117,117,201,117,143,188,234,250
        +.byte	117,117,201,117,143,188,234,250
        +.byte	6,6,24,6,48,30,12,54
        +.byte	6,6,24,6,48,30,12,54
        +.byte	138,138,18,138,36,152,9,174
        +.byte	138,138,18,138,36,152,9,174
        +.byte	178,178,242,178,249,64,121,75
        +.byte	178,178,242,178,249,64,121,75
        +.byte	230,230,191,230,99,89,209,133
        +.byte	230,230,191,230,99,89,209,133
        +.byte	14,14,56,14,112,54,28,126
        +.byte	14,14,56,14,112,54,28,126
        +.byte	31,31,124,31,248,99,62,231
        +.byte	31,31,124,31,248,99,62,231
        +.byte	98,98,149,98,55,247,196,85
        +.byte	98,98,149,98,55,247,196,85
        +.byte	212,212,119,212,238,163,181,58
        +.byte	212,212,119,212,238,163,181,58
        +.byte	168,168,154,168,41,50,77,129
        +.byte	168,168,154,168,41,50,77,129
        +.byte	150,150,98,150,196,244,49,82
        +.byte	150,150,98,150,196,244,49,82
        +.byte	249,249,195,249,155,58,239,98
        +.byte	249,249,195,249,155,58,239,98
        +.byte	197,197,51,197,102,246,151,163
        +.byte	197,197,51,197,102,246,151,163
        +.byte	37,37,148,37,53,177,74,16
        +.byte	37,37,148,37,53,177,74,16
        +.byte	89,89,121,89,242,32,178,171
        +.byte	89,89,121,89,242,32,178,171
        +.byte	132,132,42,132,84,174,21,208
        +.byte	132,132,42,132,84,174,21,208
        +.byte	114,114,213,114,183,167,228,197
        +.byte	114,114,213,114,183,167,228,197
        +.byte	57,57,228,57,213,221,114,236
        +.byte	57,57,228,57,213,221,114,236
        +.byte	76,76,45,76,90,97,152,22
        +.byte	76,76,45,76,90,97,152,22
        +.byte	94,94,101,94,202,59,188,148
        +.byte	94,94,101,94,202,59,188,148
        +.byte	120,120,253,120,231,133,240,159
        +.byte	120,120,253,120,231,133,240,159
        +.byte	56,56,224,56,221,216,112,229
        +.byte	56,56,224,56,221,216,112,229
        +.byte	140,140,10,140,20,134,5,152
        +.byte	140,140,10,140,20,134,5,152
        +.byte	209,209,99,209,198,178,191,23
        +.byte	209,209,99,209,198,178,191,23
        +.byte	165,165,174,165,65,11,87,228
        +.byte	165,165,174,165,65,11,87,228
        +.byte	226,226,175,226,67,77,217,161
        +.byte	226,226,175,226,67,77,217,161
        +.byte	97,97,153,97,47,248,194,78
        +.byte	97,97,153,97,47,248,194,78
        +.byte	179,179,246,179,241,69,123,66
        +.byte	179,179,246,179,241,69,123,66
        +.byte	33,33,132,33,21,165,66,52
        +.byte	33,33,132,33,21,165,66,52
        +.byte	156,156,74,156,148,214,37,8
        +.byte	156,156,74,156,148,214,37,8
        +.byte	30,30,120,30,240,102,60,238
        +.byte	30,30,120,30,240,102,60,238
        +.byte	67,67,17,67,34,82,134,97
        +.byte	67,67,17,67,34,82,134,97
        +.byte	199,199,59,199,118,252,147,177
        +.byte	199,199,59,199,118,252,147,177
        +.byte	252,252,215,252,179,43,229,79
        +.byte	252,252,215,252,179,43,229,79
        +.byte	4,4,16,4,32,20,8,36
        +.byte	4,4,16,4,32,20,8,36
        +.byte	81,81,89,81,178,8,162,227
        +.byte	81,81,89,81,178,8,162,227
        +.byte	153,153,94,153,188,199,47,37
        +.byte	153,153,94,153,188,199,47,37
        +.byte	109,109,169,109,79,196,218,34
        +.byte	109,109,169,109,79,196,218,34
        +.byte	13,13,52,13,104,57,26,101
        +.byte	13,13,52,13,104,57,26,101
        +.byte	250,250,207,250,131,53,233,121
        +.byte	250,250,207,250,131,53,233,121
        +.byte	223,223,91,223,182,132,163,105
        +.byte	223,223,91,223,182,132,163,105
        +.byte	126,126,229,126,215,155,252,169
        +.byte	126,126,229,126,215,155,252,169
        +.byte	36,36,144,36,61,180,72,25
        +.byte	36,36,144,36,61,180,72,25
        +.byte	59,59,236,59,197,215,118,254
        +.byte	59,59,236,59,197,215,118,254
        +.byte	171,171,150,171,49,61,75,154
        +.byte	171,171,150,171,49,61,75,154
        +.byte	206,206,31,206,62,209,129,240
        +.byte	206,206,31,206,62,209,129,240
        +.byte	17,17,68,17,136,85,34,153
        +.byte	17,17,68,17,136,85,34,153
        +.byte	143,143,6,143,12,137,3,131
        +.byte	143,143,6,143,12,137,3,131
        +.byte	78,78,37,78,74,107,156,4
        +.byte	78,78,37,78,74,107,156,4
        +.byte	183,183,230,183,209,81,115,102
        +.byte	183,183,230,183,209,81,115,102
        +.byte	235,235,139,235,11,96,203,224
        +.byte	235,235,139,235,11,96,203,224
        +.byte	60,60,240,60,253,204,120,193
        +.byte	60,60,240,60,253,204,120,193
        +.byte	129,129,62,129,124,191,31,253
        +.byte	129,129,62,129,124,191,31,253
        +.byte	148,148,106,148,212,254,53,64
        +.byte	148,148,106,148,212,254,53,64
        +.byte	247,247,251,247,235,12,243,28
        +.byte	247,247,251,247,235,12,243,28
        +.byte	185,185,222,185,161,103,111,24
        +.byte	185,185,222,185,161,103,111,24
        +.byte	19,19,76,19,152,95,38,139
        +.byte	19,19,76,19,152,95,38,139
        +.byte	44,44,176,44,125,156,88,81
        +.byte	44,44,176,44,125,156,88,81
        +.byte	211,211,107,211,214,184,187,5
        +.byte	211,211,107,211,214,184,187,5
        +.byte	231,231,187,231,107,92,211,140
        +.byte	231,231,187,231,107,92,211,140
        +.byte	110,110,165,110,87,203,220,57
        +.byte	110,110,165,110,87,203,220,57
        +.byte	196,196,55,196,110,243,149,170
        +.byte	196,196,55,196,110,243,149,170
        +.byte	3,3,12,3,24,15,6,27
        +.byte	3,3,12,3,24,15,6,27
        +.byte	86,86,69,86,138,19,172,220
        +.byte	86,86,69,86,138,19,172,220
        +.byte	68,68,13,68,26,73,136,94
        +.byte	68,68,13,68,26,73,136,94
        +.byte	127,127,225,127,223,158,254,160
        +.byte	127,127,225,127,223,158,254,160
        +.byte	169,169,158,169,33,55,79,136
        +.byte	169,169,158,169,33,55,79,136
        +.byte	42,42,168,42,77,130,84,103
        +.byte	42,42,168,42,77,130,84,103
        +.byte	187,187,214,187,177,109,107,10
        +.byte	187,187,214,187,177,109,107,10
        +.byte	193,193,35,193,70,226,159,135
        +.byte	193,193,35,193,70,226,159,135
        +.byte	83,83,81,83,162,2,166,241
        +.byte	83,83,81,83,162,2,166,241
        +.byte	220,220,87,220,174,139,165,114
        +.byte	220,220,87,220,174,139,165,114
        +.byte	11,11,44,11,88,39,22,83
        +.byte	11,11,44,11,88,39,22,83
        +.byte	157,157,78,157,156,211,39,1
        +.byte	157,157,78,157,156,211,39,1
        +.byte	108,108,173,108,71,193,216,43
        +.byte	108,108,173,108,71,193,216,43
        +.byte	49,49,196,49,149,245,98,164
        +.byte	49,49,196,49,149,245,98,164
        +.byte	116,116,205,116,135,185,232,243
        +.byte	116,116,205,116,135,185,232,243
        +.byte	246,246,255,246,227,9,241,21
        +.byte	246,246,255,246,227,9,241,21
        +.byte	70,70,5,70,10,67,140,76
        +.byte	70,70,5,70,10,67,140,76
        +.byte	172,172,138,172,9,38,69,165
        +.byte	172,172,138,172,9,38,69,165
        +.byte	137,137,30,137,60,151,15,181
        +.byte	137,137,30,137,60,151,15,181
        +.byte	20,20,80,20,160,68,40,180
        +.byte	20,20,80,20,160,68,40,180
        +.byte	225,225,163,225,91,66,223,186
        +.byte	225,225,163,225,91,66,223,186
        +.byte	22,22,88,22,176,78,44,166
        +.byte	22,22,88,22,176,78,44,166
        +.byte	58,58,232,58,205,210,116,247
        +.byte	58,58,232,58,205,210,116,247
        +.byte	105,105,185,105,111,208,210,6
        +.byte	105,105,185,105,111,208,210,6
        +.byte	9,9,36,9,72,45,18,65
        +.byte	9,9,36,9,72,45,18,65
        +.byte	112,112,221,112,167,173,224,215
        +.byte	112,112,221,112,167,173,224,215
        +.byte	182,182,226,182,217,84,113,111
        +.byte	182,182,226,182,217,84,113,111
        +.byte	208,208,103,208,206,183,189,30
        +.byte	208,208,103,208,206,183,189,30
        +.byte	237,237,147,237,59,126,199,214
        +.byte	237,237,147,237,59,126,199,214
        +.byte	204,204,23,204,46,219,133,226
        +.byte	204,204,23,204,46,219,133,226
        +.byte	66,66,21,66,42,87,132,104
        +.byte	66,66,21,66,42,87,132,104
        +.byte	152,152,90,152,180,194,45,44
        +.byte	152,152,90,152,180,194,45,44
        +.byte	164,164,170,164,73,14,85,237
        +.byte	164,164,170,164,73,14,85,237
        +.byte	40,40,160,40,93,136,80,117
        +.byte	40,40,160,40,93,136,80,117
        +.byte	92,92,109,92,218,49,184,134
        +.byte	92,92,109,92,218,49,184,134
        +.byte	248,248,199,248,147,63,237,107
        +.byte	248,248,199,248,147,63,237,107
        +.byte	134,134,34,134,68,164,17,194
        +.byte	134,134,34,134,68,164,17,194
        +.byte	24,35,198,232,135,184,1,79
        +.byte	54,166,210,245,121,111,145,82
        +.byte	96,188,155,142,163,12,123,53
        +.byte	29,224,215,194,46,75,254,87
        +.byte	21,119,55,229,159,240,74,218
        +.byte	88,201,41,10,177,160,107,133
        +.byte	189,93,16,244,203,62,5,103
        +.byte	228,39,65,139,167,125,149,216
        +.byte	251,238,124,102,221,23,71,158
        +.byte	202,45,191,7,173,90,131,51
        diff --git a/vendor/openssl/asm/x86-macosx-gas/x86cpuid.s b/vendor/openssl/asm/x86-macosx-gas/x86cpuid.s
        new file mode 100644
        index 000000000..db36e6f50
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-macosx-gas/x86cpuid.s
        @@ -0,0 +1,316 @@
        +.file	"x86cpuid.s"
        +.text
        +.globl	_OPENSSL_ia32_cpuid
        +.align	4
        +_OPENSSL_ia32_cpuid:
        +L_OPENSSL_ia32_cpuid_begin:
        +	pushl	%ebp
        +	pushl	%ebx
        +	pushl	%esi
        +	pushl	%edi
        +	xorl	%edx,%edx
        +	pushfl
        +	popl	%eax
        +	movl	%eax,%ecx
        +	xorl	$2097152,%eax
        +	pushl	%eax
        +	popfl
        +	pushfl
        +	popl	%eax
        +	xorl	%eax,%ecx
        +	xorl	%eax,%eax
        +	btl	$21,%ecx
        +	jnc	L000nocpuid
        +	.byte	0x0f,0xa2
        +	movl	%eax,%edi
        +	xorl	%eax,%eax
        +	cmpl	$1970169159,%ebx
        +	setne	%al
        +	movl	%eax,%ebp
        +	cmpl	$1231384169,%edx
        +	setne	%al
        +	orl	%eax,%ebp
        +	cmpl	$1818588270,%ecx
        +	setne	%al
        +	orl	%eax,%ebp
        +	jz	L001intel
        +	cmpl	$1752462657,%ebx
        +	setne	%al
        +	movl	%eax,%esi
        +	cmpl	$1769238117,%edx
        +	setne	%al
        +	orl	%eax,%esi
        +	cmpl	$1145913699,%ecx
        +	setne	%al
        +	orl	%eax,%esi
        +	jnz	L001intel
        +	movl	$2147483648,%eax
        +	.byte	0x0f,0xa2
        +	cmpl	$2147483649,%eax
        +	jb	L001intel
        +	movl	%eax,%esi
        +	movl	$2147483649,%eax
        +	.byte	0x0f,0xa2
        +	orl	%ecx,%ebp
        +	andl	$2049,%ebp
        +	cmpl	$2147483656,%esi
        +	jb	L001intel
        +	movl	$2147483656,%eax
        +	.byte	0x0f,0xa2
        +	movzbl	%cl,%esi
        +	incl	%esi
        +	movl	$1,%eax
        +	.byte	0x0f,0xa2
        +	btl	$28,%edx
        +	jnc	L002generic
        +	shrl	$16,%ebx
        +	andl	$255,%ebx
        +	cmpl	%esi,%ebx
        +	ja	L002generic
        +	andl	$4026531839,%edx
        +	jmp	L002generic
        +L001intel:
        +	cmpl	$4,%edi
        +	movl	$-1,%edi
        +	jb	L003nocacheinfo
        +	movl	$4,%eax
        +	movl	$0,%ecx
        +	.byte	0x0f,0xa2
        +	movl	%eax,%edi
        +	shrl	$14,%edi
        +	andl	$4095,%edi
        +L003nocacheinfo:
        +	movl	$1,%eax
        +	.byte	0x0f,0xa2
        +	andl	$3220176895,%edx
        +	cmpl	$0,%ebp
        +	jne	L004notintel
        +	orl	$1073741824,%edx
        +	andb	$15,%ah
        +	cmpb	$15,%ah
        +	jne	L004notintel
        +	orl	$1048576,%edx
        +L004notintel:
        +	btl	$28,%edx
        +	jnc	L002generic
        +	andl	$4026531839,%edx
        +	cmpl	$0,%edi
        +	je	L002generic
        +	orl	$268435456,%edx
        +	shrl	$16,%ebx
        +	cmpb	$1,%bl
        +	ja	L002generic
        +	andl	$4026531839,%edx
        +L002generic:
        +	andl	$2048,%ebp
        +	andl	$4294965247,%ecx
        +	movl	%edx,%esi
        +	orl	%ecx,%ebp
        +	btl	$27,%ecx
        +	jnc	L005clear_avx
        +	xorl	%ecx,%ecx
        +.byte	15,1,208
        +	andl	$6,%eax
        +	cmpl	$6,%eax
        +	je	L006done
        +	cmpl	$2,%eax
        +	je	L005clear_avx
        +L007clear_xmm:
        +	andl	$4261412861,%ebp
        +	andl	$4278190079,%esi
        +L005clear_avx:
        +	andl	$4026525695,%ebp
        +L006done:
        +	movl	%esi,%eax
        +	movl	%ebp,%edx
        +L000nocpuid:
        +	popl	%edi
        +	popl	%esi
        +	popl	%ebx
        +	popl	%ebp
        +	ret
        +.globl	_OPENSSL_rdtsc
        +.align	4
        +_OPENSSL_rdtsc:
        +L_OPENSSL_rdtsc_begin:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	call	L008PIC_me_up
        +L008PIC_me_up:
        +	popl	%ecx
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L008PIC_me_up(%ecx),%ecx
        +	btl	$4,(%ecx)
        +	jnc	L009notsc
        +	.byte	0x0f,0x31
        +L009notsc:
        +	ret
        +.globl	_OPENSSL_instrument_halt
        +.align	4
        +_OPENSSL_instrument_halt:
        +L_OPENSSL_instrument_halt_begin:
        +	call	L010PIC_me_up
        +L010PIC_me_up:
        +	popl	%ecx
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L010PIC_me_up(%ecx),%ecx
        +	btl	$4,(%ecx)
        +	jnc	L011nohalt
        +.long	2421723150
        +	andl	$3,%eax
        +	jnz	L011nohalt
        +	pushfl
        +	popl	%eax
        +	btl	$9,%eax
        +	jnc	L011nohalt
        +	.byte	0x0f,0x31
        +	pushl	%edx
        +	pushl	%eax
        +	hlt
        +	.byte	0x0f,0x31
        +	subl	(%esp),%eax
        +	sbbl	4(%esp),%edx
        +	addl	$8,%esp
        +	ret
        +L011nohalt:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	ret
        +.globl	_OPENSSL_far_spin
        +.align	4
        +_OPENSSL_far_spin:
        +L_OPENSSL_far_spin_begin:
        +	pushfl
        +	popl	%eax
        +	btl	$9,%eax
        +	jnc	L012nospin
        +	movl	4(%esp),%eax
        +	movl	8(%esp),%ecx
        +.long	2430111262
        +	xorl	%eax,%eax
        +	movl	(%ecx),%edx
        +	jmp	L013spin
        +.align	4,0x90
        +L013spin:
        +	incl	%eax
        +	cmpl	(%ecx),%edx
        +	je	L013spin
        +.long	529567888
        +	ret
        +L012nospin:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	ret
        +.globl	_OPENSSL_wipe_cpu
        +.align	4
        +_OPENSSL_wipe_cpu:
        +L_OPENSSL_wipe_cpu_begin:
        +	xorl	%eax,%eax
        +	xorl	%edx,%edx
        +	call	L014PIC_me_up
        +L014PIC_me_up:
        +	popl	%ecx
        +	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L014PIC_me_up(%ecx),%ecx
        +	movl	(%ecx),%ecx
        +	btl	$1,(%ecx)
        +	jnc	L015no_x87
        +.long	4007259865,4007259865,4007259865,4007259865,2430851995
        +L015no_x87:
        +	leal	4(%esp),%eax
        +	ret
        +.globl	_OPENSSL_atomic_add
        +.align	4
        +_OPENSSL_atomic_add:
        +L_OPENSSL_atomic_add_begin:
        +	movl	4(%esp),%edx
        +	movl	8(%esp),%ecx
        +	pushl	%ebx
        +	nop
        +	movl	(%edx),%eax
        +L016spin:
        +	leal	(%eax,%ecx,1),%ebx
        +	nop
        +.long	447811568
        +	jne	L016spin
        +	movl	%ebx,%eax
        +	popl	%ebx
        +	ret
        +.globl	_OPENSSL_indirect_call
        +.align	4
        +_OPENSSL_indirect_call:
        +L_OPENSSL_indirect_call_begin:
        +	pushl	%ebp
        +	movl	%esp,%ebp
        +	subl	$28,%esp
        +	movl	12(%ebp),%ecx
        +	movl	%ecx,(%esp)
        +	movl	16(%ebp),%edx
        +	movl	%edx,4(%esp)
        +	movl	20(%ebp),%eax
        +	movl	%eax,8(%esp)
        +	movl	24(%ebp),%eax
        +	movl	%eax,12(%esp)
        +	movl	28(%ebp),%eax
        +	movl	%eax,16(%esp)
        +	movl	32(%ebp),%eax
        +	movl	%eax,20(%esp)
        +	movl	36(%ebp),%eax
        +	movl	%eax,24(%esp)
        +	call	*8(%ebp)
        +	movl	%ebp,%esp
        +	popl	%ebp
        +	ret
        +.globl	_OPENSSL_cleanse
        +.align	4
        +_OPENSSL_cleanse:
        +L_OPENSSL_cleanse_begin:
        +	movl	4(%esp),%edx
        +	movl	8(%esp),%ecx
        +	xorl	%eax,%eax
        +	cmpl	$7,%ecx
        +	jae	L017lot
        +	cmpl	$0,%ecx
        +	je	L018ret
        +L019little:
        +	movb	%al,(%edx)
        +	subl	$1,%ecx
        +	leal	1(%edx),%edx
        +	jnz	L019little
        +L018ret:
        +	ret
        +.align	4,0x90
        +L017lot:
        +	testl	$3,%edx
        +	jz	L020aligned
        +	movb	%al,(%edx)
        +	leal	-1(%ecx),%ecx
        +	leal	1(%edx),%edx
        +	jmp	L017lot
        +L020aligned:
        +	movl	%eax,(%edx)
        +	leal	-4(%ecx),%ecx
        +	testl	$-4,%ecx
        +	leal	4(%edx),%edx
        +	jnz	L020aligned
        +	cmpl	$0,%ecx
        +	jne	L019little
        +	ret
        +.globl	_OPENSSL_ia32_rdrand
        +.align	4
        +_OPENSSL_ia32_rdrand:
        +L_OPENSSL_ia32_rdrand_begin:
        +	movl	$8,%ecx
        +L021loop:
        +.byte	15,199,240
        +	jc	L022break
        +	loop	L021loop
        +L022break:
        +	cmpl	$0,%eax
        +	cmovel	%ecx,%eax
        +	ret
        +.section __IMPORT,__pointers,non_lazy_symbol_pointers
        +L_OPENSSL_ia32cap_P$non_lazy_ptr:
        +.indirect_symbol	_OPENSSL_ia32cap_P
        +.long	0
        +.comm	_OPENSSL_ia32cap_P,8,2
        +.mod_init_func
        +.align 2
        +.long   _OPENSSL_cpuid_setup
        diff --git a/vendor/openssl/asm/x86-win32-masm/aes/aes-586.asm b/vendor/openssl/asm/x86-win32-masm/aes/aes-586.asm
        new file mode 100644
        index 000000000..e4ac96e64
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/aes/aes-586.asm
        @@ -0,0 +1,3222 @@
        +TITLE	aes-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.XMM
        +IF @Version LT 800
        +XMMWORD STRUCT 16
        +DQ	2 dup (?)
        +XMMWORD	ENDS
        +ENDIF
        +
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +__x86_AES_encrypt_compact	PROC PRIVATE
        +	mov	DWORD PTR 20[esp],edi
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 24[esp],esi
        +	mov	edi,DWORD PTR [ebp-128]
        +	mov	esi,DWORD PTR [ebp-96]
        +	mov	edi,DWORD PTR [ebp-64]
        +	mov	esi,DWORD PTR [ebp-32]
        +	mov	edi,DWORD PTR [ebp]
        +	mov	esi,DWORD PTR 32[ebp]
        +	mov	edi,DWORD PTR 64[ebp]
        +	mov	esi,DWORD PTR 96[ebp]
        +ALIGN	16
        +$L000loop:
        +	mov	esi,eax
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	shr	ebx,16
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,ch
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	shr	ecx,24
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,dh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edx,255
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	and	edx,255
        +	movzx	edx,BYTE PTR [edx*1+ebp-128]
        +	movzx	eax,ah
        +	movzx	eax,BYTE PTR [eax*1+ebp-128]
        +	shl	eax,8
        +	xor	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp-128]
        +	shl	ebx,16
        +	xor	edx,ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	movzx	ecx,BYTE PTR [ecx*1+ebp-128]
        +	shl	ecx,24
        +	xor	edx,ecx
        +	mov	ecx,esi
        +	mov	esi,ecx
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edi,DWORD PTR [ecx*1+ecx]
        +	sub	esi,ebp
        +	and	edi,4278124286
        +	and	esi,454761243
        +	mov	ebp,ecx
        +	xor	esi,edi
        +	xor	ecx,esi
        +	rol	ecx,24
        +	xor	ecx,esi
        +	ror	ebp,16
        +	xor	ecx,ebp
        +	ror	ebp,8
        +	xor	ecx,ebp
        +	mov	esi,edx
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	sub	esi,ebp
        +	and	edi,4278124286
        +	and	esi,454761243
        +	mov	ebp,edx
        +	xor	esi,edi
        +	xor	edx,esi
        +	rol	edx,24
        +	xor	edx,esi
        +	ror	ebp,16
        +	xor	edx,ebp
        +	ror	ebp,8
        +	xor	edx,ebp
        +	mov	esi,eax
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edi,DWORD PTR [eax*1+eax]
        +	sub	esi,ebp
        +	and	edi,4278124286
        +	and	esi,454761243
        +	mov	ebp,eax
        +	xor	esi,edi
        +	xor	eax,esi
        +	rol	eax,24
        +	xor	eax,esi
        +	ror	ebp,16
        +	xor	eax,ebp
        +	ror	ebp,8
        +	xor	eax,ebp
        +	mov	esi,ebx
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edi,DWORD PTR [ebx*1+ebx]
        +	sub	esi,ebp
        +	and	edi,4278124286
        +	and	esi,454761243
        +	mov	ebp,ebx
        +	xor	esi,edi
        +	xor	ebx,esi
        +	rol	ebx,24
        +	xor	ebx,esi
        +	ror	ebp,16
        +	xor	ebx,ebp
        +	ror	ebp,8
        +	xor	ebx,ebp
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	ebp,DWORD PTR 28[esp]
        +	add	edi,16
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	cmp	edi,DWORD PTR 24[esp]
        +	mov	DWORD PTR 20[esp],edi
        +	jb	$L000loop
        +	mov	esi,eax
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	shr	ebx,16
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,ch
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	shr	ecx,24
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,dh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edx,255
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	edi,DWORD PTR 20[esp]
        +	and	edx,255
        +	movzx	edx,BYTE PTR [edx*1+ebp-128]
        +	movzx	eax,ah
        +	movzx	eax,BYTE PTR [eax*1+ebp-128]
        +	shl	eax,8
        +	xor	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp-128]
        +	shl	ebx,16
        +	xor	edx,ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	movzx	ecx,BYTE PTR [ecx*1+ebp-128]
        +	shl	ecx,24
        +	xor	edx,ecx
        +	mov	ecx,esi
        +	xor	eax,DWORD PTR 16[edi]
        +	xor	ebx,DWORD PTR 20[edi]
        +	xor	ecx,DWORD PTR 24[edi]
        +	xor	edx,DWORD PTR 28[edi]
        +	ret
        +__x86_AES_encrypt_compact ENDP
        +ALIGN	16
        +__sse_AES_encrypt_compact	PROC PRIVATE
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm4,QWORD PTR 8[edi]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 24[esp],esi
        +	mov	eax,454761243
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],eax
        +	mov	eax,DWORD PTR [ebp-128]
        +	mov	ebx,DWORD PTR [ebp-96]
        +	mov	ecx,DWORD PTR [ebp-64]
        +	mov	edx,DWORD PTR [ebp-32]
        +	mov	eax,DWORD PTR [ebp]
        +	mov	ebx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 64[ebp]
        +	mov	edx,DWORD PTR 96[ebp]
        +ALIGN	16
        +$L001loop:
        +	pshufw	mm1,mm0,8
        +	pshufw	mm5,mm4,13
        +	movd	eax,mm1
        +	movd	ebx,mm5
        +	movzx	esi,al
        +	movzx	ecx,BYTE PTR [esi*1+ebp-128]
        +	pshufw	mm2,mm0,13
        +	movzx	edx,ah
        +	movzx	edx,BYTE PTR [edx*1+ebp-128]
        +	shl	edx,8
        +	shr	eax,16
        +	movzx	esi,bl
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,16
        +	or	ecx,esi
        +	pshufw	mm6,mm4,8
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	edx,esi
        +	shr	ebx,16
        +	movzx	esi,ah
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,8
        +	or	ecx,esi
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	ecx,esi
        +	movd	mm0,ecx
        +	movzx	esi,al
        +	movzx	ecx,BYTE PTR [esi*1+ebp-128]
        +	movd	eax,mm2
        +	movzx	esi,bl
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,16
        +	or	ecx,esi
        +	movd	ebx,mm6
        +	movzx	esi,ah
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	ecx,esi
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,8
        +	or	ecx,esi
        +	movd	mm1,ecx
        +	movzx	esi,bl
        +	movzx	ecx,BYTE PTR [esi*1+ebp-128]
        +	shr	ebx,16
        +	movzx	esi,al
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,16
        +	or	ecx,esi
        +	shr	eax,16
        +	punpckldq	mm0,mm1
        +	movzx	esi,ah
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	ecx,esi
        +	and	eax,255
        +	movzx	eax,BYTE PTR [eax*1+ebp-128]
        +	shl	eax,16
        +	or	edx,eax
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,8
        +	or	ecx,esi
        +	movd	mm4,ecx
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp-128]
        +	or	edx,ebx
        +	movd	mm5,edx
        +	punpckldq	mm4,mm5
        +	add	edi,16
        +	cmp	edi,DWORD PTR 24[esp]
        +	ja	$L002out
        +	movq	mm2,QWORD PTR 8[esp]
        +	pxor	mm3,mm3
        +	pxor	mm7,mm7
        +	movq	mm1,mm0
        +	movq	mm5,mm4
        +	pcmpgtb	mm3,mm0
        +	pcmpgtb	mm7,mm4
        +	pand	mm3,mm2
        +	pand	mm7,mm2
        +	pshufw	mm2,mm0,177
        +	pshufw	mm6,mm4,177
        +	paddb	mm0,mm0
        +	paddb	mm4,mm4
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	pshufw	mm3,mm2,177
        +	pshufw	mm7,mm6,177
        +	pxor	mm1,mm0
        +	pxor	mm5,mm4
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	movq	mm2,mm3
        +	movq	mm6,mm7
        +	pslld	mm3,8
        +	pslld	mm7,8
        +	psrld	mm2,24
        +	psrld	mm6,24
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	movq	mm3,mm1
        +	movq	mm7,mm5
        +	movq	mm2,QWORD PTR [edi]
        +	movq	mm6,QWORD PTR 8[edi]
        +	psrld	mm1,8
        +	psrld	mm5,8
        +	mov	eax,DWORD PTR [ebp-128]
        +	pslld	mm3,24
        +	pslld	mm7,24
        +	mov	ebx,DWORD PTR [ebp-64]
        +	pxor	mm0,mm1
        +	pxor	mm4,mm5
        +	mov	ecx,DWORD PTR [ebp]
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	mov	edx,DWORD PTR 64[ebp]
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	jmp	$L001loop
        +ALIGN	16
        +$L002out:
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm4,QWORD PTR 8[edi]
        +	ret
        +__sse_AES_encrypt_compact ENDP
        +ALIGN	16
        +__x86_AES_encrypt	PROC PRIVATE
        +	mov	DWORD PTR 20[esp],edi
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 24[esp],esi
        +ALIGN	16
        +$L003loop:
        +	mov	esi,eax
        +	and	esi,255
        +	mov	esi,DWORD PTR [esi*8+ebp]
        +	movzx	edi,bh
        +	xor	esi,DWORD PTR 3[edi*8+ebp]
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	xor	esi,DWORD PTR 2[edi*8+ebp]
        +	mov	edi,edx
        +	shr	edi,24
        +	xor	esi,DWORD PTR 1[edi*8+ebp]
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	shr	ebx,16
        +	mov	esi,DWORD PTR [esi*8+ebp]
        +	movzx	edi,ch
        +	xor	esi,DWORD PTR 3[edi*8+ebp]
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	xor	esi,DWORD PTR 2[edi*8+ebp]
        +	mov	edi,eax
        +	shr	edi,24
        +	xor	esi,DWORD PTR 1[edi*8+ebp]
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	shr	ecx,24
        +	mov	esi,DWORD PTR [esi*8+ebp]
        +	movzx	edi,dh
        +	xor	esi,DWORD PTR 3[edi*8+ebp]
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edx,255
        +	and	edi,255
        +	xor	esi,DWORD PTR 2[edi*8+ebp]
        +	movzx	edi,bh
        +	xor	esi,DWORD PTR 1[edi*8+ebp]
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	edx,DWORD PTR [edx*8+ebp]
        +	movzx	eax,ah
        +	xor	edx,DWORD PTR 3[eax*8+ebp]
        +	mov	eax,DWORD PTR 4[esp]
        +	and	ebx,255
        +	xor	edx,DWORD PTR 2[ebx*8+ebp]
        +	mov	ebx,DWORD PTR 8[esp]
        +	xor	edx,DWORD PTR 1[ecx*8+ebp]
        +	mov	ecx,esi
        +	add	edi,16
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	cmp	edi,DWORD PTR 24[esp]
        +	mov	DWORD PTR 20[esp],edi
        +	jb	$L003loop
        +	mov	esi,eax
        +	and	esi,255
        +	mov	esi,DWORD PTR 2[esi*8+ebp]
        +	and	esi,255
        +	movzx	edi,bh
        +	mov	edi,DWORD PTR [edi*8+ebp]
        +	and	edi,65280
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	mov	edi,DWORD PTR [edi*8+ebp]
        +	and	edi,16711680
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,24
        +	mov	edi,DWORD PTR 2[edi*8+ebp]
        +	and	edi,4278190080
        +	xor	esi,edi
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	shr	ebx,16
        +	mov	esi,DWORD PTR 2[esi*8+ebp]
        +	and	esi,255
        +	movzx	edi,ch
        +	mov	edi,DWORD PTR [edi*8+ebp]
        +	and	edi,65280
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	mov	edi,DWORD PTR [edi*8+ebp]
        +	and	edi,16711680
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,24
        +	mov	edi,DWORD PTR 2[edi*8+ebp]
        +	and	edi,4278190080
        +	xor	esi,edi
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	shr	ecx,24
        +	mov	esi,DWORD PTR 2[esi*8+ebp]
        +	and	esi,255
        +	movzx	edi,dh
        +	mov	edi,DWORD PTR [edi*8+ebp]
        +	and	edi,65280
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edx,255
        +	and	edi,255
        +	mov	edi,DWORD PTR [edi*8+ebp]
        +	and	edi,16711680
        +	xor	esi,edi
        +	movzx	edi,bh
        +	mov	edi,DWORD PTR 2[edi*8+ebp]
        +	and	edi,4278190080
        +	xor	esi,edi
        +	mov	edi,DWORD PTR 20[esp]
        +	and	edx,255
        +	mov	edx,DWORD PTR 2[edx*8+ebp]
        +	and	edx,255
        +	movzx	eax,ah
        +	mov	eax,DWORD PTR [eax*8+ebp]
        +	and	eax,65280
        +	xor	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	and	ebx,255
        +	mov	ebx,DWORD PTR [ebx*8+ebp]
        +	and	ebx,16711680
        +	xor	edx,ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	mov	ecx,DWORD PTR 2[ecx*8+ebp]
        +	and	ecx,4278190080
        +	xor	edx,ecx
        +	mov	ecx,esi
        +	add	edi,16
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	ret
        +ALIGN	64
        +$LAES_Te::
        +DD	2774754246,2774754246
        +DD	2222750968,2222750968
        +DD	2574743534,2574743534
        +DD	2373680118,2373680118
        +DD	234025727,234025727
        +DD	3177933782,3177933782
        +DD	2976870366,2976870366
        +DD	1422247313,1422247313
        +DD	1345335392,1345335392
        +DD	50397442,50397442
        +DD	2842126286,2842126286
        +DD	2099981142,2099981142
        +DD	436141799,436141799
        +DD	1658312629,1658312629
        +DD	3870010189,3870010189
        +DD	2591454956,2591454956
        +DD	1170918031,1170918031
        +DD	2642575903,2642575903
        +DD	1086966153,1086966153
        +DD	2273148410,2273148410
        +DD	368769775,368769775
        +DD	3948501426,3948501426
        +DD	3376891790,3376891790
        +DD	200339707,200339707
        +DD	3970805057,3970805057
        +DD	1742001331,1742001331
        +DD	4255294047,4255294047
        +DD	3937382213,3937382213
        +DD	3214711843,3214711843
        +DD	4154762323,4154762323
        +DD	2524082916,2524082916
        +DD	1539358875,1539358875
        +DD	3266819957,3266819957
        +DD	486407649,486407649
        +DD	2928907069,2928907069
        +DD	1780885068,1780885068
        +DD	1513502316,1513502316
        +DD	1094664062,1094664062
        +DD	49805301,49805301
        +DD	1338821763,1338821763
        +DD	1546925160,1546925160
        +DD	4104496465,4104496465
        +DD	887481809,887481809
        +DD	150073849,150073849
        +DD	2473685474,2473685474
        +DD	1943591083,1943591083
        +DD	1395732834,1395732834
        +DD	1058346282,1058346282
        +DD	201589768,201589768
        +DD	1388824469,1388824469
        +DD	1696801606,1696801606
        +DD	1589887901,1589887901
        +DD	672667696,672667696
        +DD	2711000631,2711000631
        +DD	251987210,251987210
        +DD	3046808111,3046808111
        +DD	151455502,151455502
        +DD	907153956,907153956
        +DD	2608889883,2608889883
        +DD	1038279391,1038279391
        +DD	652995533,652995533
        +DD	1764173646,1764173646
        +DD	3451040383,3451040383
        +DD	2675275242,2675275242
        +DD	453576978,453576978
        +DD	2659418909,2659418909
        +DD	1949051992,1949051992
        +DD	773462580,773462580
        +DD	756751158,756751158
        +DD	2993581788,2993581788
        +DD	3998898868,3998898868
        +DD	4221608027,4221608027
        +DD	4132590244,4132590244
        +DD	1295727478,1295727478
        +DD	1641469623,1641469623
        +DD	3467883389,3467883389
        +DD	2066295122,2066295122
        +DD	1055122397,1055122397
        +DD	1898917726,1898917726
        +DD	2542044179,2542044179
        +DD	4115878822,4115878822
        +DD	1758581177,1758581177
        +DD	0,0
        +DD	753790401,753790401
        +DD	1612718144,1612718144
        +DD	536673507,536673507
        +DD	3367088505,3367088505
        +DD	3982187446,3982187446
        +DD	3194645204,3194645204
        +DD	1187761037,1187761037
        +DD	3653156455,3653156455
        +DD	1262041458,1262041458
        +DD	3729410708,3729410708
        +DD	3561770136,3561770136
        +DD	3898103984,3898103984
        +DD	1255133061,1255133061
        +DD	1808847035,1808847035
        +DD	720367557,720367557
        +DD	3853167183,3853167183
        +DD	385612781,385612781
        +DD	3309519750,3309519750
        +DD	3612167578,3612167578
        +DD	1429418854,1429418854
        +DD	2491778321,2491778321
        +DD	3477423498,3477423498
        +DD	284817897,284817897
        +DD	100794884,100794884
        +DD	2172616702,2172616702
        +DD	4031795360,4031795360
        +DD	1144798328,1144798328
        +DD	3131023141,3131023141
        +DD	3819481163,3819481163
        +DD	4082192802,4082192802
        +DD	4272137053,4272137053
        +DD	3225436288,3225436288
        +DD	2324664069,2324664069
        +DD	2912064063,2912064063
        +DD	3164445985,3164445985
        +DD	1211644016,1211644016
        +DD	83228145,83228145
        +DD	3753688163,3753688163
        +DD	3249976951,3249976951
        +DD	1977277103,1977277103
        +DD	1663115586,1663115586
        +DD	806359072,806359072
        +DD	452984805,452984805
        +DD	250868733,250868733
        +DD	1842533055,1842533055
        +DD	1288555905,1288555905
        +DD	336333848,336333848
        +DD	890442534,890442534
        +DD	804056259,804056259
        +DD	3781124030,3781124030
        +DD	2727843637,2727843637
        +DD	3427026056,3427026056
        +DD	957814574,957814574
        +DD	1472513171,1472513171
        +DD	4071073621,4071073621
        +DD	2189328124,2189328124
        +DD	1195195770,1195195770
        +DD	2892260552,2892260552
        +DD	3881655738,3881655738
        +DD	723065138,723065138
        +DD	2507371494,2507371494
        +DD	2690670784,2690670784
        +DD	2558624025,2558624025
        +DD	3511635870,3511635870
        +DD	2145180835,2145180835
        +DD	1713513028,1713513028
        +DD	2116692564,2116692564
        +DD	2878378043,2878378043
        +DD	2206763019,2206763019
        +DD	3393603212,3393603212
        +DD	703524551,703524551
        +DD	3552098411,3552098411
        +DD	1007948840,1007948840
        +DD	2044649127,2044649127
        +DD	3797835452,3797835452
        +DD	487262998,487262998
        +DD	1994120109,1994120109
        +DD	1004593371,1004593371
        +DD	1446130276,1446130276
        +DD	1312438900,1312438900
        +DD	503974420,503974420
        +DD	3679013266,3679013266
        +DD	168166924,168166924
        +DD	1814307912,1814307912
        +DD	3831258296,3831258296
        +DD	1573044895,1573044895
        +DD	1859376061,1859376061
        +DD	4021070915,4021070915
        +DD	2791465668,2791465668
        +DD	2828112185,2828112185
        +DD	2761266481,2761266481
        +DD	937747667,937747667
        +DD	2339994098,2339994098
        +DD	854058965,854058965
        +DD	1137232011,1137232011
        +DD	1496790894,1496790894
        +DD	3077402074,3077402074
        +DD	2358086913,2358086913
        +DD	1691735473,1691735473
        +DD	3528347292,3528347292
        +DD	3769215305,3769215305
        +DD	3027004632,3027004632
        +DD	4199962284,4199962284
        +DD	133494003,133494003
        +DD	636152527,636152527
        +DD	2942657994,2942657994
        +DD	2390391540,2390391540
        +DD	3920539207,3920539207
        +DD	403179536,403179536
        +DD	3585784431,3585784431
        +DD	2289596656,2289596656
        +DD	1864705354,1864705354
        +DD	1915629148,1915629148
        +DD	605822008,605822008
        +DD	4054230615,4054230615
        +DD	3350508659,3350508659
        +DD	1371981463,1371981463
        +DD	602466507,602466507
        +DD	2094914977,2094914977
        +DD	2624877800,2624877800
        +DD	555687742,555687742
        +DD	3712699286,3712699286
        +DD	3703422305,3703422305
        +DD	2257292045,2257292045
        +DD	2240449039,2240449039
        +DD	2423288032,2423288032
        +DD	1111375484,1111375484
        +DD	3300242801,3300242801
        +DD	2858837708,2858837708
        +DD	3628615824,3628615824
        +DD	84083462,84083462
        +DD	32962295,32962295
        +DD	302911004,302911004
        +DD	2741068226,2741068226
        +DD	1597322602,1597322602
        +DD	4183250862,4183250862
        +DD	3501832553,3501832553
        +DD	2441512471,2441512471
        +DD	1489093017,1489093017
        +DD	656219450,656219450
        +DD	3114180135,3114180135
        +DD	954327513,954327513
        +DD	335083755,335083755
        +DD	3013122091,3013122091
        +DD	856756514,856756514
        +DD	3144247762,3144247762
        +DD	1893325225,1893325225
        +DD	2307821063,2307821063
        +DD	2811532339,2811532339
        +DD	3063651117,3063651117
        +DD	572399164,572399164
        +DD	2458355477,2458355477
        +DD	552200649,552200649
        +DD	1238290055,1238290055
        +DD	4283782570,4283782570
        +DD	2015897680,2015897680
        +DD	2061492133,2061492133
        +DD	2408352771,2408352771
        +DD	4171342169,4171342169
        +DD	2156497161,2156497161
        +DD	386731290,386731290
        +DD	3669999461,3669999461
        +DD	837215959,837215959
        +DD	3326231172,3326231172
        +DD	3093850320,3093850320
        +DD	3275833730,3275833730
        +DD	2962856233,2962856233
        +DD	1999449434,1999449434
        +DD	286199582,286199582
        +DD	3417354363,3417354363
        +DD	4233385128,4233385128
        +DD	3602627437,3602627437
        +DD	974525996,974525996
        +DB	99,124,119,123,242,107,111,197
        +DB	48,1,103,43,254,215,171,118
        +DB	202,130,201,125,250,89,71,240
        +DB	173,212,162,175,156,164,114,192
        +DB	183,253,147,38,54,63,247,204
        +DB	52,165,229,241,113,216,49,21
        +DB	4,199,35,195,24,150,5,154
        +DB	7,18,128,226,235,39,178,117
        +DB	9,131,44,26,27,110,90,160
        +DB	82,59,214,179,41,227,47,132
        +DB	83,209,0,237,32,252,177,91
        +DB	106,203,190,57,74,76,88,207
        +DB	208,239,170,251,67,77,51,133
        +DB	69,249,2,127,80,60,159,168
        +DB	81,163,64,143,146,157,56,245
        +DB	188,182,218,33,16,255,243,210
        +DB	205,12,19,236,95,151,68,23
        +DB	196,167,126,61,100,93,25,115
        +DB	96,129,79,220,34,42,144,136
        +DB	70,238,184,20,222,94,11,219
        +DB	224,50,58,10,73,6,36,92
        +DB	194,211,172,98,145,149,228,121
        +DB	231,200,55,109,141,213,78,169
        +DB	108,86,244,234,101,122,174,8
        +DB	186,120,37,46,28,166,180,198
        +DB	232,221,116,31,75,189,139,138
        +DB	112,62,181,102,72,3,246,14
        +DB	97,53,87,185,134,193,29,158
        +DB	225,248,152,17,105,217,142,148
        +DB	155,30,135,233,206,85,40,223
        +DB	140,161,137,13,191,230,66,104
        +DB	65,153,45,15,176,84,187,22
        +DB	99,124,119,123,242,107,111,197
        +DB	48,1,103,43,254,215,171,118
        +DB	202,130,201,125,250,89,71,240
        +DB	173,212,162,175,156,164,114,192
        +DB	183,253,147,38,54,63,247,204
        +DB	52,165,229,241,113,216,49,21
        +DB	4,199,35,195,24,150,5,154
        +DB	7,18,128,226,235,39,178,117
        +DB	9,131,44,26,27,110,90,160
        +DB	82,59,214,179,41,227,47,132
        +DB	83,209,0,237,32,252,177,91
        +DB	106,203,190,57,74,76,88,207
        +DB	208,239,170,251,67,77,51,133
        +DB	69,249,2,127,80,60,159,168
        +DB	81,163,64,143,146,157,56,245
        +DB	188,182,218,33,16,255,243,210
        +DB	205,12,19,236,95,151,68,23
        +DB	196,167,126,61,100,93,25,115
        +DB	96,129,79,220,34,42,144,136
        +DB	70,238,184,20,222,94,11,219
        +DB	224,50,58,10,73,6,36,92
        +DB	194,211,172,98,145,149,228,121
        +DB	231,200,55,109,141,213,78,169
        +DB	108,86,244,234,101,122,174,8
        +DB	186,120,37,46,28,166,180,198
        +DB	232,221,116,31,75,189,139,138
        +DB	112,62,181,102,72,3,246,14
        +DB	97,53,87,185,134,193,29,158
        +DB	225,248,152,17,105,217,142,148
        +DB	155,30,135,233,206,85,40,223
        +DB	140,161,137,13,191,230,66,104
        +DB	65,153,45,15,176,84,187,22
        +DB	99,124,119,123,242,107,111,197
        +DB	48,1,103,43,254,215,171,118
        +DB	202,130,201,125,250,89,71,240
        +DB	173,212,162,175,156,164,114,192
        +DB	183,253,147,38,54,63,247,204
        +DB	52,165,229,241,113,216,49,21
        +DB	4,199,35,195,24,150,5,154
        +DB	7,18,128,226,235,39,178,117
        +DB	9,131,44,26,27,110,90,160
        +DB	82,59,214,179,41,227,47,132
        +DB	83,209,0,237,32,252,177,91
        +DB	106,203,190,57,74,76,88,207
        +DB	208,239,170,251,67,77,51,133
        +DB	69,249,2,127,80,60,159,168
        +DB	81,163,64,143,146,157,56,245
        +DB	188,182,218,33,16,255,243,210
        +DB	205,12,19,236,95,151,68,23
        +DB	196,167,126,61,100,93,25,115
        +DB	96,129,79,220,34,42,144,136
        +DB	70,238,184,20,222,94,11,219
        +DB	224,50,58,10,73,6,36,92
        +DB	194,211,172,98,145,149,228,121
        +DB	231,200,55,109,141,213,78,169
        +DB	108,86,244,234,101,122,174,8
        +DB	186,120,37,46,28,166,180,198
        +DB	232,221,116,31,75,189,139,138
        +DB	112,62,181,102,72,3,246,14
        +DB	97,53,87,185,134,193,29,158
        +DB	225,248,152,17,105,217,142,148
        +DB	155,30,135,233,206,85,40,223
        +DB	140,161,137,13,191,230,66,104
        +DB	65,153,45,15,176,84,187,22
        +DB	99,124,119,123,242,107,111,197
        +DB	48,1,103,43,254,215,171,118
        +DB	202,130,201,125,250,89,71,240
        +DB	173,212,162,175,156,164,114,192
        +DB	183,253,147,38,54,63,247,204
        +DB	52,165,229,241,113,216,49,21
        +DB	4,199,35,195,24,150,5,154
        +DB	7,18,128,226,235,39,178,117
        +DB	9,131,44,26,27,110,90,160
        +DB	82,59,214,179,41,227,47,132
        +DB	83,209,0,237,32,252,177,91
        +DB	106,203,190,57,74,76,88,207
        +DB	208,239,170,251,67,77,51,133
        +DB	69,249,2,127,80,60,159,168
        +DB	81,163,64,143,146,157,56,245
        +DB	188,182,218,33,16,255,243,210
        +DB	205,12,19,236,95,151,68,23
        +DB	196,167,126,61,100,93,25,115
        +DB	96,129,79,220,34,42,144,136
        +DB	70,238,184,20,222,94,11,219
        +DB	224,50,58,10,73,6,36,92
        +DB	194,211,172,98,145,149,228,121
        +DB	231,200,55,109,141,213,78,169
        +DB	108,86,244,234,101,122,174,8
        +DB	186,120,37,46,28,166,180,198
        +DB	232,221,116,31,75,189,139,138
        +DB	112,62,181,102,72,3,246,14
        +DB	97,53,87,185,134,193,29,158
        +DB	225,248,152,17,105,217,142,148
        +DB	155,30,135,233,206,85,40,223
        +DB	140,161,137,13,191,230,66,104
        +DB	65,153,45,15,176,84,187,22
        +DD	1,2,4,8
        +DD	16,32,64,128
        +DD	27,54,0,0
        +DD	0,0,0,0
        +__x86_AES_encrypt ENDP
        +ALIGN	16
        +_AES_encrypt	PROC PUBLIC
        +$L_AES_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	eax,esp
        +	sub	esp,36
        +	and	esp,-64
        +	lea	ebx,DWORD PTR [edi-127]
        +	sub	ebx,esp
        +	neg	ebx
        +	and	ebx,960
        +	sub	esp,ebx
        +	add	esp,4
        +	mov	DWORD PTR 28[esp],eax
        +	call	$L004pic_point
        +$L004pic_point:
        +	pop	ebp
        +	lea	eax,DWORD PTR _OPENSSL_ia32cap_P
        +	lea	ebp,DWORD PTR ($LAES_Te-$L004pic_point)[ebp]
        +	lea	ebx,DWORD PTR 764[esp]
        +	sub	ebx,ebp
        +	and	ebx,768
        +	lea	ebp,DWORD PTR 2176[ebx*1+ebp]
        +	bt	DWORD PTR [eax],25
        +	jnc	$L005x86
        +	movq	mm0,QWORD PTR [esi]
        +	movq	mm4,QWORD PTR 8[esi]
        +	call	__sse_AES_encrypt_compact
        +	mov	esp,DWORD PTR 28[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	movq	QWORD PTR [esi],mm0
        +	movq	QWORD PTR 8[esi],mm4
        +	emms
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	16
        +$L005x86:
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	call	__x86_AES_encrypt_compact
        +	mov	esp,DWORD PTR 28[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_AES_encrypt ENDP
        +ALIGN	16
        +__x86_AES_decrypt_compact	PROC PRIVATE
        +	mov	DWORD PTR 20[esp],edi
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 24[esp],esi
        +	mov	edi,DWORD PTR [ebp-128]
        +	mov	esi,DWORD PTR [ebp-96]
        +	mov	edi,DWORD PTR [ebp-64]
        +	mov	esi,DWORD PTR [ebp-32]
        +	mov	edi,DWORD PTR [ebp]
        +	mov	esi,DWORD PTR 32[ebp]
        +	mov	edi,DWORD PTR 64[ebp]
        +	mov	esi,DWORD PTR 96[ebp]
        +ALIGN	16
        +$L006loop:
        +	mov	esi,eax
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,dh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,ebx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,ah
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	and	edx,255
        +	movzx	edx,BYTE PTR [edx*1+ebp-128]
        +	movzx	ecx,ch
        +	movzx	ecx,BYTE PTR [ecx*1+ebp-128]
        +	shl	ecx,8
        +	xor	edx,ecx
        +	mov	ecx,esi
        +	shr	ebx,16
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp-128]
        +	shl	ebx,16
        +	xor	edx,ebx
        +	shr	eax,24
        +	movzx	eax,BYTE PTR [eax*1+ebp-128]
        +	shl	eax,24
        +	xor	edx,eax
        +	mov	esi,ecx
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	eax,DWORD PTR [ecx*1+ecx]
        +	sub	esi,edi
        +	and	eax,4278124286
        +	and	esi,454761243
        +	xor	esi,eax
        +	mov	eax,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ebx,DWORD PTR [eax*1+eax]
        +	sub	esi,edi
        +	and	ebx,4278124286
        +	and	esi,454761243
        +	xor	eax,ecx
        +	xor	esi,ebx
        +	mov	ebx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ebp,DWORD PTR [ebx*1+ebx]
        +	sub	esi,edi
        +	and	ebp,4278124286
        +	and	esi,454761243
        +	xor	ebx,ecx
        +	rol	ecx,8
        +	xor	ebp,esi
        +	xor	ecx,eax
        +	xor	eax,ebp
        +	rol	eax,24
        +	xor	ecx,ebx
        +	xor	ebx,ebp
        +	rol	ebx,16
        +	xor	ecx,ebp
        +	rol	ebp,8
        +	xor	ecx,eax
        +	xor	ecx,ebx
        +	mov	eax,DWORD PTR 4[esp]
        +	xor	ecx,ebp
        +	mov	DWORD PTR 12[esp],ecx
        +	mov	esi,edx
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ebx,DWORD PTR [edx*1+edx]
        +	sub	esi,edi
        +	and	ebx,4278124286
        +	and	esi,454761243
        +	xor	esi,ebx
        +	mov	ebx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ecx,DWORD PTR [ebx*1+ebx]
        +	sub	esi,edi
        +	and	ecx,4278124286
        +	and	esi,454761243
        +	xor	ebx,edx
        +	xor	esi,ecx
        +	mov	ecx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ebp,DWORD PTR [ecx*1+ecx]
        +	sub	esi,edi
        +	and	ebp,4278124286
        +	and	esi,454761243
        +	xor	ecx,edx
        +	rol	edx,8
        +	xor	ebp,esi
        +	xor	edx,ebx
        +	xor	ebx,ebp
        +	rol	ebx,24
        +	xor	edx,ecx
        +	xor	ecx,ebp
        +	rol	ecx,16
        +	xor	edx,ebp
        +	rol	ebp,8
        +	xor	edx,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 8[esp]
        +	xor	edx,ebp
        +	mov	DWORD PTR 16[esp],edx
        +	mov	esi,eax
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ecx,DWORD PTR [eax*1+eax]
        +	sub	esi,edi
        +	and	ecx,4278124286
        +	and	esi,454761243
        +	xor	esi,ecx
        +	mov	ecx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	edx,DWORD PTR [ecx*1+ecx]
        +	sub	esi,edi
        +	and	edx,4278124286
        +	and	esi,454761243
        +	xor	ecx,eax
        +	xor	esi,edx
        +	mov	edx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ebp,DWORD PTR [edx*1+edx]
        +	sub	esi,edi
        +	and	ebp,4278124286
        +	and	esi,454761243
        +	xor	edx,eax
        +	rol	eax,8
        +	xor	ebp,esi
        +	xor	eax,ecx
        +	xor	ecx,ebp
        +	rol	ecx,24
        +	xor	eax,edx
        +	xor	edx,ebp
        +	rol	edx,16
        +	xor	eax,ebp
        +	rol	ebp,8
        +	xor	eax,ecx
        +	xor	eax,edx
        +	xor	eax,ebp
        +	mov	esi,ebx
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ecx,DWORD PTR [ebx*1+ebx]
        +	sub	esi,edi
        +	and	ecx,4278124286
        +	and	esi,454761243
        +	xor	esi,ecx
        +	mov	ecx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	edx,DWORD PTR [ecx*1+ecx]
        +	sub	esi,edi
        +	and	edx,4278124286
        +	and	esi,454761243
        +	xor	ecx,ebx
        +	xor	esi,edx
        +	mov	edx,esi
        +	and	esi,2155905152
        +	mov	edi,esi
        +	shr	edi,7
        +	lea	ebp,DWORD PTR [edx*1+edx]
        +	sub	esi,edi
        +	and	ebp,4278124286
        +	and	esi,454761243
        +	xor	edx,ebx
        +	rol	ebx,8
        +	xor	ebp,esi
        +	xor	ebx,ecx
        +	xor	ecx,ebp
        +	rol	ecx,24
        +	xor	ebx,edx
        +	xor	edx,ebp
        +	rol	edx,16
        +	xor	ebx,ebp
        +	rol	ebp,8
        +	xor	ebx,ecx
        +	xor	ebx,edx
        +	mov	ecx,DWORD PTR 12[esp]
        +	xor	ebx,ebp
        +	mov	edx,DWORD PTR 16[esp]
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	ebp,DWORD PTR 28[esp]
        +	add	edi,16
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	cmp	edi,DWORD PTR 24[esp]
        +	mov	DWORD PTR 20[esp],edi
        +	jb	$L006loop
        +	mov	esi,eax
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,dh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,ebx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,ah
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp-128]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	edi,DWORD PTR 20[esp]
        +	and	edx,255
        +	movzx	edx,BYTE PTR [edx*1+ebp-128]
        +	movzx	ecx,ch
        +	movzx	ecx,BYTE PTR [ecx*1+ebp-128]
        +	shl	ecx,8
        +	xor	edx,ecx
        +	mov	ecx,esi
        +	shr	ebx,16
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp-128]
        +	shl	ebx,16
        +	xor	edx,ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	shr	eax,24
        +	movzx	eax,BYTE PTR [eax*1+ebp-128]
        +	shl	eax,24
        +	xor	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	xor	eax,DWORD PTR 16[edi]
        +	xor	ebx,DWORD PTR 20[edi]
        +	xor	ecx,DWORD PTR 24[edi]
        +	xor	edx,DWORD PTR 28[edi]
        +	ret
        +__x86_AES_decrypt_compact ENDP
        +ALIGN	16
        +__sse_AES_decrypt_compact	PROC PRIVATE
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm4,QWORD PTR 8[edi]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 24[esp],esi
        +	mov	eax,454761243
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],eax
        +	mov	eax,DWORD PTR [ebp-128]
        +	mov	ebx,DWORD PTR [ebp-96]
        +	mov	ecx,DWORD PTR [ebp-64]
        +	mov	edx,DWORD PTR [ebp-32]
        +	mov	eax,DWORD PTR [ebp]
        +	mov	ebx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 64[ebp]
        +	mov	edx,DWORD PTR 96[ebp]
        +ALIGN	16
        +$L007loop:
        +	pshufw	mm1,mm0,12
        +	movd	eax,mm1
        +	pshufw	mm5,mm4,9
        +	movzx	esi,al
        +	movzx	ecx,BYTE PTR [esi*1+ebp-128]
        +	movd	ebx,mm5
        +	movzx	edx,ah
        +	movzx	edx,BYTE PTR [edx*1+ebp-128]
        +	shl	edx,8
        +	pshufw	mm2,mm0,6
        +	movzx	esi,bl
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,16
        +	or	ecx,esi
        +	shr	eax,16
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	edx,esi
        +	shr	ebx,16
        +	pshufw	mm6,mm4,3
        +	movzx	esi,ah
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	ecx,esi
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,8
        +	or	ecx,esi
        +	movd	mm0,ecx
        +	movzx	esi,al
        +	movd	eax,mm2
        +	movzx	ecx,BYTE PTR [esi*1+ebp-128]
        +	shl	ecx,16
        +	movzx	esi,bl
        +	movd	ebx,mm6
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	or	ecx,esi
        +	movzx	esi,al
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	or	edx,esi
        +	movzx	esi,bl
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,16
        +	or	edx,esi
        +	movd	mm1,edx
        +	movzx	esi,ah
        +	movzx	edx,BYTE PTR [esi*1+ebp-128]
        +	shl	edx,8
        +	movzx	esi,bh
        +	shr	eax,16
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,24
        +	or	edx,esi
        +	shr	ebx,16
        +	punpckldq	mm0,mm1
        +	movzx	esi,bh
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,8
        +	or	ecx,esi
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp-128]
        +	or	edx,ebx
        +	movzx	esi,al
        +	movzx	esi,BYTE PTR [esi*1+ebp-128]
        +	shl	esi,16
        +	or	edx,esi
        +	movd	mm4,edx
        +	movzx	eax,ah
        +	movzx	eax,BYTE PTR [eax*1+ebp-128]
        +	shl	eax,24
        +	or	ecx,eax
        +	movd	mm5,ecx
        +	punpckldq	mm4,mm5
        +	add	edi,16
        +	cmp	edi,DWORD PTR 24[esp]
        +	ja	$L008out
        +	movq	mm3,mm0
        +	movq	mm7,mm4
        +	pshufw	mm2,mm0,228
        +	pshufw	mm6,mm4,228
        +	movq	mm1,mm0
        +	movq	mm5,mm4
        +	pshufw	mm0,mm0,177
        +	pshufw	mm4,mm4,177
        +	pslld	mm2,8
        +	pslld	mm6,8
        +	psrld	mm3,8
        +	psrld	mm7,8
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	pslld	mm2,16
        +	pslld	mm6,16
        +	psrld	mm3,16
        +	psrld	mm7,16
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	movq	mm3,QWORD PTR 8[esp]
        +	pxor	mm2,mm2
        +	pxor	mm6,mm6
        +	pcmpgtb	mm2,mm1
        +	pcmpgtb	mm6,mm5
        +	pand	mm2,mm3
        +	pand	mm6,mm3
        +	paddb	mm1,mm1
        +	paddb	mm5,mm5
        +	pxor	mm1,mm2
        +	pxor	mm5,mm6
        +	movq	mm3,mm1
        +	movq	mm7,mm5
        +	movq	mm2,mm1
        +	movq	mm6,mm5
        +	pxor	mm0,mm1
        +	pxor	mm4,mm5
        +	pslld	mm3,24
        +	pslld	mm7,24
        +	psrld	mm2,8
        +	psrld	mm6,8
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	movq	mm2,QWORD PTR 8[esp]
        +	pxor	mm3,mm3
        +	pxor	mm7,mm7
        +	pcmpgtb	mm3,mm1
        +	pcmpgtb	mm7,mm5
        +	pand	mm3,mm2
        +	pand	mm7,mm2
        +	paddb	mm1,mm1
        +	paddb	mm5,mm5
        +	pxor	mm1,mm3
        +	pxor	mm5,mm7
        +	pshufw	mm3,mm1,177
        +	pshufw	mm7,mm5,177
        +	pxor	mm0,mm1
        +	pxor	mm4,mm5
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	pxor	mm3,mm3
        +	pxor	mm7,mm7
        +	pcmpgtb	mm3,mm1
        +	pcmpgtb	mm7,mm5
        +	pand	mm3,mm2
        +	pand	mm7,mm2
        +	paddb	mm1,mm1
        +	paddb	mm5,mm5
        +	pxor	mm1,mm3
        +	pxor	mm5,mm7
        +	pxor	mm0,mm1
        +	pxor	mm4,mm5
        +	movq	mm3,mm1
        +	movq	mm7,mm5
        +	pshufw	mm2,mm1,177
        +	pshufw	mm6,mm5,177
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	pslld	mm1,8
        +	pslld	mm5,8
        +	psrld	mm3,8
        +	psrld	mm7,8
        +	movq	mm2,QWORD PTR [edi]
        +	movq	mm6,QWORD PTR 8[edi]
        +	pxor	mm0,mm1
        +	pxor	mm4,mm5
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	mov	eax,DWORD PTR [ebp-128]
        +	pslld	mm1,16
        +	pslld	mm5,16
        +	mov	ebx,DWORD PTR [ebp-64]
        +	psrld	mm3,16
        +	psrld	mm7,16
        +	mov	ecx,DWORD PTR [ebp]
        +	pxor	mm0,mm1
        +	pxor	mm4,mm5
        +	mov	edx,DWORD PTR 64[ebp]
        +	pxor	mm0,mm3
        +	pxor	mm4,mm7
        +	pxor	mm0,mm2
        +	pxor	mm4,mm6
        +	jmp	$L007loop
        +ALIGN	16
        +$L008out:
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm4,QWORD PTR 8[edi]
        +	ret
        +__sse_AES_decrypt_compact ENDP
        +ALIGN	16
        +__x86_AES_decrypt	PROC PRIVATE
        +	mov	DWORD PTR 20[esp],edi
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 24[esp],esi
        +ALIGN	16
        +$L009loop:
        +	mov	esi,eax
        +	and	esi,255
        +	mov	esi,DWORD PTR [esi*8+ebp]
        +	movzx	edi,dh
        +	xor	esi,DWORD PTR 3[edi*8+ebp]
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	xor	esi,DWORD PTR 2[edi*8+ebp]
        +	mov	edi,ebx
        +	shr	edi,24
        +	xor	esi,DWORD PTR 1[edi*8+ebp]
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	mov	esi,DWORD PTR [esi*8+ebp]
        +	movzx	edi,ah
        +	xor	esi,DWORD PTR 3[edi*8+ebp]
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	xor	esi,DWORD PTR 2[edi*8+ebp]
        +	mov	edi,ecx
        +	shr	edi,24
        +	xor	esi,DWORD PTR 1[edi*8+ebp]
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	mov	esi,DWORD PTR [esi*8+ebp]
        +	movzx	edi,bh
        +	xor	esi,DWORD PTR 3[edi*8+ebp]
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edi,255
        +	xor	esi,DWORD PTR 2[edi*8+ebp]
        +	mov	edi,edx
        +	shr	edi,24
        +	xor	esi,DWORD PTR 1[edi*8+ebp]
        +	mov	edi,DWORD PTR 20[esp]
        +	and	edx,255
        +	mov	edx,DWORD PTR [edx*8+ebp]
        +	movzx	ecx,ch
        +	xor	edx,DWORD PTR 3[ecx*8+ebp]
        +	mov	ecx,esi
        +	shr	ebx,16
        +	and	ebx,255
        +	xor	edx,DWORD PTR 2[ebx*8+ebp]
        +	mov	ebx,DWORD PTR 8[esp]
        +	shr	eax,24
        +	xor	edx,DWORD PTR 1[eax*8+ebp]
        +	mov	eax,DWORD PTR 4[esp]
        +	add	edi,16
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	cmp	edi,DWORD PTR 24[esp]
        +	mov	DWORD PTR 20[esp],edi
        +	jb	$L009loop
        +	lea	ebp,DWORD PTR 2176[ebp]
        +	mov	edi,DWORD PTR [ebp-128]
        +	mov	esi,DWORD PTR [ebp-96]
        +	mov	edi,DWORD PTR [ebp-64]
        +	mov	esi,DWORD PTR [ebp-32]
        +	mov	edi,DWORD PTR [ebp]
        +	mov	esi,DWORD PTR 32[ebp]
        +	mov	edi,DWORD PTR 64[ebp]
        +	mov	esi,DWORD PTR 96[ebp]
        +	lea	ebp,DWORD PTR [ebp-128]
        +	mov	esi,eax
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp]
        +	movzx	edi,dh
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,ebx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 4[esp],esi
        +	mov	esi,ebx
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp]
        +	movzx	edi,ah
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,ecx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	DWORD PTR 8[esp],esi
        +	mov	esi,ecx
        +	and	esi,255
        +	movzx	esi,BYTE PTR [esi*1+ebp]
        +	movzx	edi,bh
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,8
        +	xor	esi,edi
        +	mov	edi,eax
        +	shr	edi,16
        +	and	edi,255
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,16
        +	xor	esi,edi
        +	mov	edi,edx
        +	shr	edi,24
        +	movzx	edi,BYTE PTR [edi*1+ebp]
        +	shl	edi,24
        +	xor	esi,edi
        +	mov	edi,DWORD PTR 20[esp]
        +	and	edx,255
        +	movzx	edx,BYTE PTR [edx*1+ebp]
        +	movzx	ecx,ch
        +	movzx	ecx,BYTE PTR [ecx*1+ebp]
        +	shl	ecx,8
        +	xor	edx,ecx
        +	mov	ecx,esi
        +	shr	ebx,16
        +	and	ebx,255
        +	movzx	ebx,BYTE PTR [ebx*1+ebp]
        +	shl	ebx,16
        +	xor	edx,ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	shr	eax,24
        +	movzx	eax,BYTE PTR [eax*1+ebp]
        +	shl	eax,24
        +	xor	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	lea	ebp,DWORD PTR [ebp-2048]
        +	add	edi,16
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	ret
        +ALIGN	64
        +$LAES_Td::
        +DD	1353184337,1353184337
        +DD	1399144830,1399144830
        +DD	3282310938,3282310938
        +DD	2522752826,2522752826
        +DD	3412831035,3412831035
        +DD	4047871263,4047871263
        +DD	2874735276,2874735276
        +DD	2466505547,2466505547
        +DD	1442459680,1442459680
        +DD	4134368941,4134368941
        +DD	2440481928,2440481928
        +DD	625738485,625738485
        +DD	4242007375,4242007375
        +DD	3620416197,3620416197
        +DD	2151953702,2151953702
        +DD	2409849525,2409849525
        +DD	1230680542,1230680542
        +DD	1729870373,1729870373
        +DD	2551114309,2551114309
        +DD	3787521629,3787521629
        +DD	41234371,41234371
        +DD	317738113,317738113
        +DD	2744600205,2744600205
        +DD	3338261355,3338261355
        +DD	3881799427,3881799427
        +DD	2510066197,2510066197
        +DD	3950669247,3950669247
        +DD	3663286933,3663286933
        +DD	763608788,763608788
        +DD	3542185048,3542185048
        +DD	694804553,694804553
        +DD	1154009486,1154009486
        +DD	1787413109,1787413109
        +DD	2021232372,2021232372
        +DD	1799248025,1799248025
        +DD	3715217703,3715217703
        +DD	3058688446,3058688446
        +DD	397248752,397248752
        +DD	1722556617,1722556617
        +DD	3023752829,3023752829
        +DD	407560035,407560035
        +DD	2184256229,2184256229
        +DD	1613975959,1613975959
        +DD	1165972322,1165972322
        +DD	3765920945,3765920945
        +DD	2226023355,2226023355
        +DD	480281086,480281086
        +DD	2485848313,2485848313
        +DD	1483229296,1483229296
        +DD	436028815,436028815
        +DD	2272059028,2272059028
        +DD	3086515026,3086515026
        +DD	601060267,601060267
        +DD	3791801202,3791801202
        +DD	1468997603,1468997603
        +DD	715871590,715871590
        +DD	120122290,120122290
        +DD	63092015,63092015
        +DD	2591802758,2591802758
        +DD	2768779219,2768779219
        +DD	4068943920,4068943920
        +DD	2997206819,2997206819
        +DD	3127509762,3127509762
        +DD	1552029421,1552029421
        +DD	723308426,723308426
        +DD	2461301159,2461301159
        +DD	4042393587,4042393587
        +DD	2715969870,2715969870
        +DD	3455375973,3455375973
        +DD	3586000134,3586000134
        +DD	526529745,526529745
        +DD	2331944644,2331944644
        +DD	2639474228,2639474228
        +DD	2689987490,2689987490
        +DD	853641733,853641733
        +DD	1978398372,1978398372
        +DD	971801355,971801355
        +DD	2867814464,2867814464
        +DD	111112542,111112542
        +DD	1360031421,1360031421
        +DD	4186579262,4186579262
        +DD	1023860118,1023860118
        +DD	2919579357,2919579357
        +DD	1186850381,1186850381
        +DD	3045938321,3045938321
        +DD	90031217,90031217
        +DD	1876166148,1876166148
        +DD	4279586912,4279586912
        +DD	620468249,620468249
        +DD	2548678102,2548678102
        +DD	3426959497,3426959497
        +DD	2006899047,2006899047
        +DD	3175278768,3175278768
        +DD	2290845959,2290845959
        +DD	945494503,945494503
        +DD	3689859193,3689859193
        +DD	1191869601,1191869601
        +DD	3910091388,3910091388
        +DD	3374220536,3374220536
        +DD	0,0
        +DD	2206629897,2206629897
        +DD	1223502642,1223502642
        +DD	2893025566,2893025566
        +DD	1316117100,1316117100
        +DD	4227796733,4227796733
        +DD	1446544655,1446544655
        +DD	517320253,517320253
        +DD	658058550,658058550
        +DD	1691946762,1691946762
        +DD	564550760,564550760
        +DD	3511966619,3511966619
        +DD	976107044,976107044
        +DD	2976320012,2976320012
        +DD	266819475,266819475
        +DD	3533106868,3533106868
        +DD	2660342555,2660342555
        +DD	1338359936,1338359936
        +DD	2720062561,2720062561
        +DD	1766553434,1766553434
        +DD	370807324,370807324
        +DD	179999714,179999714
        +DD	3844776128,3844776128
        +DD	1138762300,1138762300
        +DD	488053522,488053522
        +DD	185403662,185403662
        +DD	2915535858,2915535858
        +DD	3114841645,3114841645
        +DD	3366526484,3366526484
        +DD	2233069911,2233069911
        +DD	1275557295,1275557295
        +DD	3151862254,3151862254
        +DD	4250959779,4250959779
        +DD	2670068215,2670068215
        +DD	3170202204,3170202204
        +DD	3309004356,3309004356
        +DD	880737115,880737115
        +DD	1982415755,1982415755
        +DD	3703972811,3703972811
        +DD	1761406390,1761406390
        +DD	1676797112,1676797112
        +DD	3403428311,3403428311
        +DD	277177154,277177154
        +DD	1076008723,1076008723
        +DD	538035844,538035844
        +DD	2099530373,2099530373
        +DD	4164795346,4164795346
        +DD	288553390,288553390
        +DD	1839278535,1839278535
        +DD	1261411869,1261411869
        +DD	4080055004,4080055004
        +DD	3964831245,3964831245
        +DD	3504587127,3504587127
        +DD	1813426987,1813426987
        +DD	2579067049,2579067049
        +DD	4199060497,4199060497
        +DD	577038663,577038663
        +DD	3297574056,3297574056
        +DD	440397984,440397984
        +DD	3626794326,3626794326
        +DD	4019204898,4019204898
        +DD	3343796615,3343796615
        +DD	3251714265,3251714265
        +DD	4272081548,4272081548
        +DD	906744984,906744984
        +DD	3481400742,3481400742
        +DD	685669029,685669029
        +DD	646887386,646887386
        +DD	2764025151,2764025151
        +DD	3835509292,3835509292
        +DD	227702864,227702864
        +DD	2613862250,2613862250
        +DD	1648787028,1648787028
        +DD	3256061430,3256061430
        +DD	3904428176,3904428176
        +DD	1593260334,1593260334
        +DD	4121936770,4121936770
        +DD	3196083615,3196083615
        +DD	2090061929,2090061929
        +DD	2838353263,2838353263
        +DD	3004310991,3004310991
        +DD	999926984,999926984
        +DD	2809993232,2809993232
        +DD	1852021992,1852021992
        +DD	2075868123,2075868123
        +DD	158869197,158869197
        +DD	4095236462,4095236462
        +DD	28809964,28809964
        +DD	2828685187,2828685187
        +DD	1701746150,1701746150
        +DD	2129067946,2129067946
        +DD	147831841,147831841
        +DD	3873969647,3873969647
        +DD	3650873274,3650873274
        +DD	3459673930,3459673930
        +DD	3557400554,3557400554
        +DD	3598495785,3598495785
        +DD	2947720241,2947720241
        +DD	824393514,824393514
        +DD	815048134,815048134
        +DD	3227951669,3227951669
        +DD	935087732,935087732
        +DD	2798289660,2798289660
        +DD	2966458592,2966458592
        +DD	366520115,366520115
        +DD	1251476721,1251476721
        +DD	4158319681,4158319681
        +DD	240176511,240176511
        +DD	804688151,804688151
        +DD	2379631990,2379631990
        +DD	1303441219,1303441219
        +DD	1414376140,1414376140
        +DD	3741619940,3741619940
        +DD	3820343710,3820343710
        +DD	461924940,461924940
        +DD	3089050817,3089050817
        +DD	2136040774,2136040774
        +DD	82468509,82468509
        +DD	1563790337,1563790337
        +DD	1937016826,1937016826
        +DD	776014843,776014843
        +DD	1511876531,1511876531
        +DD	1389550482,1389550482
        +DD	861278441,861278441
        +DD	323475053,323475053
        +DD	2355222426,2355222426
        +DD	2047648055,2047648055
        +DD	2383738969,2383738969
        +DD	2302415851,2302415851
        +DD	3995576782,3995576782
        +DD	902390199,902390199
        +DD	3991215329,3991215329
        +DD	1018251130,1018251130
        +DD	1507840668,1507840668
        +DD	1064563285,1064563285
        +DD	2043548696,2043548696
        +DD	3208103795,3208103795
        +DD	3939366739,3939366739
        +DD	1537932639,1537932639
        +DD	342834655,342834655
        +DD	2262516856,2262516856
        +DD	2180231114,2180231114
        +DD	1053059257,1053059257
        +DD	741614648,741614648
        +DD	1598071746,1598071746
        +DD	1925389590,1925389590
        +DD	203809468,203809468
        +DD	2336832552,2336832552
        +DD	1100287487,1100287487
        +DD	1895934009,1895934009
        +DD	3736275976,3736275976
        +DD	2632234200,2632234200
        +DD	2428589668,2428589668
        +DD	1636092795,1636092795
        +DD	1890988757,1890988757
        +DD	1952214088,1952214088
        +DD	1113045200,1113045200
        +DB	82,9,106,213,48,54,165,56
        +DB	191,64,163,158,129,243,215,251
        +DB	124,227,57,130,155,47,255,135
        +DB	52,142,67,68,196,222,233,203
        +DB	84,123,148,50,166,194,35,61
        +DB	238,76,149,11,66,250,195,78
        +DB	8,46,161,102,40,217,36,178
        +DB	118,91,162,73,109,139,209,37
        +DB	114,248,246,100,134,104,152,22
        +DB	212,164,92,204,93,101,182,146
        +DB	108,112,72,80,253,237,185,218
        +DB	94,21,70,87,167,141,157,132
        +DB	144,216,171,0,140,188,211,10
        +DB	247,228,88,5,184,179,69,6
        +DB	208,44,30,143,202,63,15,2
        +DB	193,175,189,3,1,19,138,107
        +DB	58,145,17,65,79,103,220,234
        +DB	151,242,207,206,240,180,230,115
        +DB	150,172,116,34,231,173,53,133
        +DB	226,249,55,232,28,117,223,110
        +DB	71,241,26,113,29,41,197,137
        +DB	111,183,98,14,170,24,190,27
        +DB	252,86,62,75,198,210,121,32
        +DB	154,219,192,254,120,205,90,244
        +DB	31,221,168,51,136,7,199,49
        +DB	177,18,16,89,39,128,236,95
        +DB	96,81,127,169,25,181,74,13
        +DB	45,229,122,159,147,201,156,239
        +DB	160,224,59,77,174,42,245,176
        +DB	200,235,187,60,131,83,153,97
        +DB	23,43,4,126,186,119,214,38
        +DB	225,105,20,99,85,33,12,125
        +DB	82,9,106,213,48,54,165,56
        +DB	191,64,163,158,129,243,215,251
        +DB	124,227,57,130,155,47,255,135
        +DB	52,142,67,68,196,222,233,203
        +DB	84,123,148,50,166,194,35,61
        +DB	238,76,149,11,66,250,195,78
        +DB	8,46,161,102,40,217,36,178
        +DB	118,91,162,73,109,139,209,37
        +DB	114,248,246,100,134,104,152,22
        +DB	212,164,92,204,93,101,182,146
        +DB	108,112,72,80,253,237,185,218
        +DB	94,21,70,87,167,141,157,132
        +DB	144,216,171,0,140,188,211,10
        +DB	247,228,88,5,184,179,69,6
        +DB	208,44,30,143,202,63,15,2
        +DB	193,175,189,3,1,19,138,107
        +DB	58,145,17,65,79,103,220,234
        +DB	151,242,207,206,240,180,230,115
        +DB	150,172,116,34,231,173,53,133
        +DB	226,249,55,232,28,117,223,110
        +DB	71,241,26,113,29,41,197,137
        +DB	111,183,98,14,170,24,190,27
        +DB	252,86,62,75,198,210,121,32
        +DB	154,219,192,254,120,205,90,244
        +DB	31,221,168,51,136,7,199,49
        +DB	177,18,16,89,39,128,236,95
        +DB	96,81,127,169,25,181,74,13
        +DB	45,229,122,159,147,201,156,239
        +DB	160,224,59,77,174,42,245,176
        +DB	200,235,187,60,131,83,153,97
        +DB	23,43,4,126,186,119,214,38
        +DB	225,105,20,99,85,33,12,125
        +DB	82,9,106,213,48,54,165,56
        +DB	191,64,163,158,129,243,215,251
        +DB	124,227,57,130,155,47,255,135
        +DB	52,142,67,68,196,222,233,203
        +DB	84,123,148,50,166,194,35,61
        +DB	238,76,149,11,66,250,195,78
        +DB	8,46,161,102,40,217,36,178
        +DB	118,91,162,73,109,139,209,37
        +DB	114,248,246,100,134,104,152,22
        +DB	212,164,92,204,93,101,182,146
        +DB	108,112,72,80,253,237,185,218
        +DB	94,21,70,87,167,141,157,132
        +DB	144,216,171,0,140,188,211,10
        +DB	247,228,88,5,184,179,69,6
        +DB	208,44,30,143,202,63,15,2
        +DB	193,175,189,3,1,19,138,107
        +DB	58,145,17,65,79,103,220,234
        +DB	151,242,207,206,240,180,230,115
        +DB	150,172,116,34,231,173,53,133
        +DB	226,249,55,232,28,117,223,110
        +DB	71,241,26,113,29,41,197,137
        +DB	111,183,98,14,170,24,190,27
        +DB	252,86,62,75,198,210,121,32
        +DB	154,219,192,254,120,205,90,244
        +DB	31,221,168,51,136,7,199,49
        +DB	177,18,16,89,39,128,236,95
        +DB	96,81,127,169,25,181,74,13
        +DB	45,229,122,159,147,201,156,239
        +DB	160,224,59,77,174,42,245,176
        +DB	200,235,187,60,131,83,153,97
        +DB	23,43,4,126,186,119,214,38
        +DB	225,105,20,99,85,33,12,125
        +DB	82,9,106,213,48,54,165,56
        +DB	191,64,163,158,129,243,215,251
        +DB	124,227,57,130,155,47,255,135
        +DB	52,142,67,68,196,222,233,203
        +DB	84,123,148,50,166,194,35,61
        +DB	238,76,149,11,66,250,195,78
        +DB	8,46,161,102,40,217,36,178
        +DB	118,91,162,73,109,139,209,37
        +DB	114,248,246,100,134,104,152,22
        +DB	212,164,92,204,93,101,182,146
        +DB	108,112,72,80,253,237,185,218
        +DB	94,21,70,87,167,141,157,132
        +DB	144,216,171,0,140,188,211,10
        +DB	247,228,88,5,184,179,69,6
        +DB	208,44,30,143,202,63,15,2
        +DB	193,175,189,3,1,19,138,107
        +DB	58,145,17,65,79,103,220,234
        +DB	151,242,207,206,240,180,230,115
        +DB	150,172,116,34,231,173,53,133
        +DB	226,249,55,232,28,117,223,110
        +DB	71,241,26,113,29,41,197,137
        +DB	111,183,98,14,170,24,190,27
        +DB	252,86,62,75,198,210,121,32
        +DB	154,219,192,254,120,205,90,244
        +DB	31,221,168,51,136,7,199,49
        +DB	177,18,16,89,39,128,236,95
        +DB	96,81,127,169,25,181,74,13
        +DB	45,229,122,159,147,201,156,239
        +DB	160,224,59,77,174,42,245,176
        +DB	200,235,187,60,131,83,153,97
        +DB	23,43,4,126,186,119,214,38
        +DB	225,105,20,99,85,33,12,125
        +__x86_AES_decrypt ENDP
        +ALIGN	16
        +_AES_decrypt	PROC PUBLIC
        +$L_AES_decrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	eax,esp
        +	sub	esp,36
        +	and	esp,-64
        +	lea	ebx,DWORD PTR [edi-127]
        +	sub	ebx,esp
        +	neg	ebx
        +	and	ebx,960
        +	sub	esp,ebx
        +	add	esp,4
        +	mov	DWORD PTR 28[esp],eax
        +	call	$L010pic_point
        +$L010pic_point:
        +	pop	ebp
        +	lea	eax,DWORD PTR _OPENSSL_ia32cap_P
        +	lea	ebp,DWORD PTR ($LAES_Td-$L010pic_point)[ebp]
        +	lea	ebx,DWORD PTR 764[esp]
        +	sub	ebx,ebp
        +	and	ebx,768
        +	lea	ebp,DWORD PTR 2176[ebx*1+ebp]
        +	bt	DWORD PTR [eax],25
        +	jnc	$L011x86
        +	movq	mm0,QWORD PTR [esi]
        +	movq	mm4,QWORD PTR 8[esi]
        +	call	__sse_AES_decrypt_compact
        +	mov	esp,DWORD PTR 28[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	movq	QWORD PTR [esi],mm0
        +	movq	QWORD PTR 8[esi],mm4
        +	emms
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	16
        +$L011x86:
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	call	__x86_AES_decrypt_compact
        +	mov	esp,DWORD PTR 28[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_AES_decrypt ENDP
        +ALIGN	16
        +_AES_cbc_encrypt	PROC PUBLIC
        +$L_AES_cbc_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ecx,DWORD PTR 28[esp]
        +	cmp	ecx,0
        +	je	$L012drop_out
        +	call	$L013pic_point
        +$L013pic_point:
        +	pop	ebp
        +	lea	eax,DWORD PTR _OPENSSL_ia32cap_P
        +	cmp	DWORD PTR 40[esp],0
        +	lea	ebp,DWORD PTR ($LAES_Te-$L013pic_point)[ebp]
        +	jne	$L014picked_te
        +	lea	ebp,DWORD PTR ($LAES_Td-$LAES_Te)[ebp]
        +$L014picked_te:
        +	pushfd
        +	cld
        +	cmp	ecx,512
        +	jb	$L015slow_way
        +	test	ecx,15
        +	jnz	$L015slow_way
        +	lea	esi,DWORD PTR [esp-324]
        +	and	esi,-64
        +	mov	eax,ebp
        +	lea	ebx,DWORD PTR 2304[ebp]
        +	mov	edx,esi
        +	and	eax,4095
        +	and	ebx,4095
        +	and	edx,4095
        +	cmp	edx,ebx
        +	jb	$L016tbl_break_out
        +	sub	edx,ebx
        +	sub	esi,edx
        +	jmp	$L017tbl_ok
        +ALIGN	4
        +$L016tbl_break_out:
        +	sub	edx,eax
        +	and	edx,4095
        +	add	edx,384
        +	sub	esi,edx
        +ALIGN	4
        +$L017tbl_ok:
        +	lea	edx,DWORD PTR 24[esp]
        +	xchg	esp,esi
        +	add	esp,4
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	DWORD PTR 28[esp],esi
        +	mov	eax,DWORD PTR [edx]
        +	mov	ebx,DWORD PTR 4[edx]
        +	mov	edi,DWORD PTR 12[edx]
        +	mov	esi,DWORD PTR 16[edx]
        +	mov	edx,DWORD PTR 20[edx]
        +	mov	DWORD PTR 32[esp],eax
        +	mov	DWORD PTR 36[esp],ebx
        +	mov	DWORD PTR 40[esp],ecx
        +	mov	DWORD PTR 44[esp],edi
        +	mov	DWORD PTR 48[esp],esi
        +	mov	DWORD PTR 316[esp],0
        +	mov	ebx,edi
        +	mov	ecx,61
        +	sub	ebx,ebp
        +	mov	esi,edi
        +	and	ebx,4095
        +	lea	edi,DWORD PTR 76[esp]
        +	cmp	ebx,2304
        +	jb	$L018do_copy
        +	cmp	ebx,3852
        +	jb	$L019skip_copy
        +ALIGN	4
        +$L018do_copy:
        +	mov	DWORD PTR 44[esp],edi
        +DD	2784229001
        +$L019skip_copy:
        +	mov	edi,16
        +ALIGN	4
        +$L020prefetch_tbl:
        +	mov	eax,DWORD PTR [ebp]
        +	mov	ebx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 64[ebp]
        +	mov	esi,DWORD PTR 96[ebp]
        +	lea	ebp,DWORD PTR 128[ebp]
        +	sub	edi,1
        +	jnz	$L020prefetch_tbl
        +	sub	ebp,2048
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	edi,DWORD PTR 48[esp]
        +	cmp	edx,0
        +	je	$L021fast_decrypt
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +ALIGN	16
        +$L022fast_enc_loop:
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	xor	eax,DWORD PTR [esi]
        +	xor	ebx,DWORD PTR 4[esi]
        +	xor	ecx,DWORD PTR 8[esi]
        +	xor	edx,DWORD PTR 12[esi]
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__x86_AES_encrypt
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	edi,DWORD PTR 36[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	DWORD PTR 32[esp],esi
        +	lea	edx,DWORD PTR 16[edi]
        +	mov	DWORD PTR 36[esp],edx
        +	sub	ecx,16
        +	mov	DWORD PTR 40[esp],ecx
        +	jnz	$L022fast_enc_loop
        +	mov	esi,DWORD PTR 48[esp]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	cmp	DWORD PTR 316[esp],0
        +	mov	edi,DWORD PTR 44[esp]
        +	je	$L023skip_ezero
        +	mov	ecx,60
        +	xor	eax,eax
        +ALIGN	4
        +DD	2884892297
        +$L023skip_ezero:
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +$L012drop_out:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L021fast_decrypt:
        +	cmp	esi,DWORD PTR 36[esp]
        +	je	$L024fast_dec_in_place
        +	mov	DWORD PTR 52[esp],edi
        +ALIGN	4
        +ALIGN	16
        +$L025fast_dec_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__x86_AES_decrypt
        +	mov	edi,DWORD PTR 52[esp]
        +	mov	esi,DWORD PTR 40[esp]
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	edi,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	DWORD PTR 52[esp],esi
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 32[esp],esi
        +	lea	edi,DWORD PTR 16[edi]
        +	mov	DWORD PTR 36[esp],edi
        +	sub	ecx,16
        +	mov	DWORD PTR 40[esp],ecx
        +	jnz	$L025fast_dec_loop
        +	mov	edi,DWORD PTR 52[esp]
        +	mov	esi,DWORD PTR 48[esp]
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	jmp	$L026fast_dec_out
        +ALIGN	16
        +$L024fast_dec_in_place:
        +$L027fast_dec_in_place_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	lea	edi,DWORD PTR 60[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__x86_AES_decrypt
        +	mov	edi,DWORD PTR 48[esp]
        +	mov	esi,DWORD PTR 36[esp]
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 36[esp],esi
        +	lea	esi,DWORD PTR 60[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	ecx,DWORD PTR 40[esp]
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 32[esp],esi
        +	sub	ecx,16
        +	mov	DWORD PTR 40[esp],ecx
        +	jnz	$L027fast_dec_in_place_loop
        +ALIGN	4
        +$L026fast_dec_out:
        +	cmp	DWORD PTR 316[esp],0
        +	mov	edi,DWORD PTR 44[esp]
        +	je	$L028skip_dzero
        +	mov	ecx,60
        +	xor	eax,eax
        +ALIGN	4
        +DD	2884892297
        +$L028skip_dzero:
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L015slow_way:
        +	mov	eax,DWORD PTR [eax]
        +	mov	edi,DWORD PTR 36[esp]
        +	lea	esi,DWORD PTR [esp-80]
        +	and	esi,-64
        +	lea	ebx,DWORD PTR [edi-143]
        +	sub	ebx,esi
        +	neg	ebx
        +	and	ebx,960
        +	sub	esi,ebx
        +	lea	ebx,DWORD PTR 768[esi]
        +	sub	ebx,ebp
        +	and	ebx,768
        +	lea	ebp,DWORD PTR 2176[ebx*1+ebp]
        +	lea	edx,DWORD PTR 24[esp]
        +	xchg	esp,esi
        +	add	esp,4
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	DWORD PTR 28[esp],esi
        +	mov	DWORD PTR 52[esp],eax
        +	mov	eax,DWORD PTR [edx]
        +	mov	ebx,DWORD PTR 4[edx]
        +	mov	esi,DWORD PTR 16[edx]
        +	mov	edx,DWORD PTR 20[edx]
        +	mov	DWORD PTR 32[esp],eax
        +	mov	DWORD PTR 36[esp],ebx
        +	mov	DWORD PTR 40[esp],ecx
        +	mov	DWORD PTR 44[esp],edi
        +	mov	DWORD PTR 48[esp],esi
        +	mov	edi,esi
        +	mov	esi,eax
        +	cmp	edx,0
        +	je	$L029slow_decrypt
        +	cmp	ecx,16
        +	mov	edx,ebx
        +	jb	$L030slow_enc_tail
        +	bt	DWORD PTR 52[esp],25
        +	jnc	$L031slow_enc_x86
        +	movq	mm0,QWORD PTR [edi]
        +	movq	mm4,QWORD PTR 8[edi]
        +ALIGN	16
        +$L032slow_enc_loop_sse:
        +	pxor	mm0,QWORD PTR [esi]
        +	pxor	mm4,QWORD PTR 8[esi]
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__sse_AES_encrypt_compact
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	edi,DWORD PTR 36[esp]
        +	mov	ecx,DWORD PTR 40[esp]
        +	movq	QWORD PTR [edi],mm0
        +	movq	QWORD PTR 8[edi],mm4
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 32[esp],esi
        +	lea	edx,DWORD PTR 16[edi]
        +	mov	DWORD PTR 36[esp],edx
        +	sub	ecx,16
        +	cmp	ecx,16
        +	mov	DWORD PTR 40[esp],ecx
        +	jae	$L032slow_enc_loop_sse
        +	test	ecx,15
        +	jnz	$L030slow_enc_tail
        +	mov	esi,DWORD PTR 48[esp]
        +	movq	QWORD PTR [esi],mm0
        +	movq	QWORD PTR 8[esi],mm4
        +	emms
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L031slow_enc_x86:
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +ALIGN	4
        +$L033slow_enc_loop_x86:
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	xor	eax,DWORD PTR [esi]
        +	xor	ebx,DWORD PTR 4[esi]
        +	xor	ecx,DWORD PTR 8[esi]
        +	xor	edx,DWORD PTR 12[esi]
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__x86_AES_encrypt_compact
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	edi,DWORD PTR 36[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	ecx,DWORD PTR 40[esp]
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 32[esp],esi
        +	lea	edx,DWORD PTR 16[edi]
        +	mov	DWORD PTR 36[esp],edx
        +	sub	ecx,16
        +	cmp	ecx,16
        +	mov	DWORD PTR 40[esp],ecx
        +	jae	$L033slow_enc_loop_x86
        +	test	ecx,15
        +	jnz	$L030slow_enc_tail
        +	mov	esi,DWORD PTR 48[esp]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L030slow_enc_tail:
        +	emms
        +	mov	edi,edx
        +	mov	ebx,16
        +	sub	ebx,ecx
        +	cmp	edi,esi
        +	je	$L034enc_in_place
        +ALIGN	4
        +DD	2767451785
        +	jmp	$L035enc_skip_in_place
        +$L034enc_in_place:
        +	lea	edi,DWORD PTR [ecx*1+edi]
        +$L035enc_skip_in_place:
        +	mov	ecx,ebx
        +	xor	eax,eax
        +ALIGN	4
        +DD	2868115081
        +	mov	edi,DWORD PTR 48[esp]
        +	mov	esi,edx
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	DWORD PTR 40[esp],16
        +	jmp	$L033slow_enc_loop_x86
        +ALIGN	16
        +$L029slow_decrypt:
        +	bt	DWORD PTR 52[esp],25
        +	jnc	$L036slow_dec_loop_x86
        +ALIGN	4
        +$L037slow_dec_loop_sse:
        +	movq	mm0,QWORD PTR [esi]
        +	movq	mm4,QWORD PTR 8[esi]
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__sse_AES_decrypt_compact
        +	mov	esi,DWORD PTR 32[esp]
        +	lea	eax,DWORD PTR 60[esp]
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	edi,DWORD PTR 48[esp]
        +	movq	mm1,QWORD PTR [esi]
        +	movq	mm5,QWORD PTR 8[esi]
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm4,QWORD PTR 8[edi]
        +	movq	QWORD PTR [edi],mm1
        +	movq	QWORD PTR 8[edi],mm5
        +	sub	ecx,16
        +	jc	$L038slow_dec_partial_sse
        +	movq	QWORD PTR [ebx],mm0
        +	movq	QWORD PTR 8[ebx],mm4
        +	lea	ebx,DWORD PTR 16[ebx]
        +	mov	DWORD PTR 36[esp],ebx
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 32[esp],esi
        +	mov	DWORD PTR 40[esp],ecx
        +	jnz	$L037slow_dec_loop_sse
        +	emms
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L038slow_dec_partial_sse:
        +	movq	QWORD PTR [eax],mm0
        +	movq	QWORD PTR 8[eax],mm4
        +	emms
        +	add	ecx,16
        +	mov	edi,ebx
        +	mov	esi,eax
        +ALIGN	4
        +DD	2767451785
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L036slow_dec_loop_x86:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	lea	edi,DWORD PTR 60[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	edi,DWORD PTR 44[esp]
        +	call	__x86_AES_decrypt_compact
        +	mov	edi,DWORD PTR 48[esp]
        +	mov	esi,DWORD PTR 40[esp]
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	sub	esi,16
        +	jc	$L039slow_dec_partial_x86
        +	mov	DWORD PTR 40[esp],esi
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 36[esp],esi
        +	lea	esi,DWORD PTR 60[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	esi,DWORD PTR 32[esp]
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 32[esp],esi
        +	jnz	$L036slow_dec_loop_x86
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	16
        +$L039slow_dec_partial_x86:
        +	lea	esi,DWORD PTR 60[esp]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	mov	esi,DWORD PTR 32[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	edi,DWORD PTR 36[esp]
        +	lea	esi,DWORD PTR 60[esp]
        +ALIGN	4
        +DD	2767451785
        +	mov	esp,DWORD PTR 28[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_AES_cbc_encrypt ENDP
        +ALIGN	16
        +__x86_AES_set_encrypt_key	PROC PRIVATE
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 32[esp]
        +	test	esi,-1
        +	jz	$L040badpointer
        +	test	edi,-1
        +	jz	$L040badpointer
        +	call	$L041pic_point
        +$L041pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LAES_Te-$L041pic_point)[ebp]
        +	lea	ebp,DWORD PTR 2176[ebp]
        +	mov	eax,DWORD PTR [ebp-128]
        +	mov	ebx,DWORD PTR [ebp-96]
        +	mov	ecx,DWORD PTR [ebp-64]
        +	mov	edx,DWORD PTR [ebp-32]
        +	mov	eax,DWORD PTR [ebp]
        +	mov	ebx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 64[ebp]
        +	mov	edx,DWORD PTR 96[ebp]
        +	mov	ecx,DWORD PTR 28[esp]
        +	cmp	ecx,128
        +	je	$L04210rounds
        +	cmp	ecx,192
        +	je	$L04312rounds
        +	cmp	ecx,256
        +	je	$L04414rounds
        +	mov	eax,-2
        +	jmp	$L045exit
        +$L04210rounds:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	xor	ecx,ecx
        +	jmp	$L04610shortcut
        +ALIGN	4
        +$L04710loop:
        +	mov	eax,DWORD PTR [edi]
        +	mov	edx,DWORD PTR 12[edi]
        +$L04610shortcut:
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,24
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shr	edx,16
        +	movzx	esi,dl
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,8
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shl	ebx,16
        +	xor	eax,ebx
        +	xor	eax,DWORD PTR 896[ecx*4+ebp]
        +	mov	DWORD PTR 16[edi],eax
        +	xor	eax,DWORD PTR 4[edi]
        +	mov	DWORD PTR 20[edi],eax
        +	xor	eax,DWORD PTR 8[edi]
        +	mov	DWORD PTR 24[edi],eax
        +	xor	eax,DWORD PTR 12[edi]
        +	mov	DWORD PTR 28[edi],eax
        +	inc	ecx
        +	add	edi,16
        +	cmp	ecx,10
        +	jl	$L04710loop
        +	mov	DWORD PTR 80[edi],10
        +	xor	eax,eax
        +	jmp	$L045exit
        +$L04312rounds:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	ecx,DWORD PTR 16[esi]
        +	mov	edx,DWORD PTR 20[esi]
        +	mov	DWORD PTR 16[edi],ecx
        +	mov	DWORD PTR 20[edi],edx
        +	xor	ecx,ecx
        +	jmp	$L04812shortcut
        +ALIGN	4
        +$L04912loop:
        +	mov	eax,DWORD PTR [edi]
        +	mov	edx,DWORD PTR 20[edi]
        +$L04812shortcut:
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,24
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shr	edx,16
        +	movzx	esi,dl
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,8
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shl	ebx,16
        +	xor	eax,ebx
        +	xor	eax,DWORD PTR 896[ecx*4+ebp]
        +	mov	DWORD PTR 24[edi],eax
        +	xor	eax,DWORD PTR 4[edi]
        +	mov	DWORD PTR 28[edi],eax
        +	xor	eax,DWORD PTR 8[edi]
        +	mov	DWORD PTR 32[edi],eax
        +	xor	eax,DWORD PTR 12[edi]
        +	mov	DWORD PTR 36[edi],eax
        +	cmp	ecx,7
        +	je	$L05012break
        +	inc	ecx
        +	xor	eax,DWORD PTR 16[edi]
        +	mov	DWORD PTR 40[edi],eax
        +	xor	eax,DWORD PTR 20[edi]
        +	mov	DWORD PTR 44[edi],eax
        +	add	edi,24
        +	jmp	$L04912loop
        +$L05012break:
        +	mov	DWORD PTR 72[edi],12
        +	xor	eax,eax
        +	jmp	$L045exit
        +$L04414rounds:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	eax,DWORD PTR 16[esi]
        +	mov	ebx,DWORD PTR 20[esi]
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 28[esi]
        +	mov	DWORD PTR 16[edi],eax
        +	mov	DWORD PTR 20[edi],ebx
        +	mov	DWORD PTR 24[edi],ecx
        +	mov	DWORD PTR 28[edi],edx
        +	xor	ecx,ecx
        +	jmp	$L05114shortcut
        +ALIGN	4
        +$L05214loop:
        +	mov	edx,DWORD PTR 28[edi]
        +$L05114shortcut:
        +	mov	eax,DWORD PTR [edi]
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,24
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shr	edx,16
        +	movzx	esi,dl
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,8
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shl	ebx,16
        +	xor	eax,ebx
        +	xor	eax,DWORD PTR 896[ecx*4+ebp]
        +	mov	DWORD PTR 32[edi],eax
        +	xor	eax,DWORD PTR 4[edi]
        +	mov	DWORD PTR 36[edi],eax
        +	xor	eax,DWORD PTR 8[edi]
        +	mov	DWORD PTR 40[edi],eax
        +	xor	eax,DWORD PTR 12[edi]
        +	mov	DWORD PTR 44[edi],eax
        +	cmp	ecx,6
        +	je	$L05314break
        +	inc	ecx
        +	mov	edx,eax
        +	mov	eax,DWORD PTR 16[edi]
        +	movzx	esi,dl
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shr	edx,16
        +	shl	ebx,8
        +	movzx	esi,dl
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	movzx	esi,dh
        +	shl	ebx,16
        +	xor	eax,ebx
        +	movzx	ebx,BYTE PTR [esi*1+ebp-128]
        +	shl	ebx,24
        +	xor	eax,ebx
        +	mov	DWORD PTR 48[edi],eax
        +	xor	eax,DWORD PTR 20[edi]
        +	mov	DWORD PTR 52[edi],eax
        +	xor	eax,DWORD PTR 24[edi]
        +	mov	DWORD PTR 56[edi],eax
        +	xor	eax,DWORD PTR 28[edi]
        +	mov	DWORD PTR 60[edi],eax
        +	add	edi,32
        +	jmp	$L05214loop
        +$L05314break:
        +	mov	DWORD PTR 48[edi],14
        +	xor	eax,eax
        +	jmp	$L045exit
        +$L040badpointer:
        +	mov	eax,-1
        +$L045exit:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +__x86_AES_set_encrypt_key ENDP
        +ALIGN	16
        +_private_AES_set_encrypt_key	PROC PUBLIC
        +$L_private_AES_set_encrypt_key_begin::
        +	call	__x86_AES_set_encrypt_key
        +	ret
        +_private_AES_set_encrypt_key ENDP
        +ALIGN	16
        +_private_AES_set_decrypt_key	PROC PUBLIC
        +$L_private_AES_set_decrypt_key_begin::
        +	call	__x86_AES_set_encrypt_key
        +	cmp	eax,0
        +	je	$L054proceed
        +	ret
        +$L054proceed:
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 28[esp]
        +	mov	ecx,DWORD PTR 240[esi]
        +	lea	ecx,DWORD PTR [ecx*4]
        +	lea	edi,DWORD PTR [ecx*4+esi]
        +ALIGN	4
        +$L055invert:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR [edi]
        +	mov	edx,DWORD PTR 4[edi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR [esi],ecx
        +	mov	DWORD PTR 4[esi],edx
        +	mov	eax,DWORD PTR 8[esi]
        +	mov	ebx,DWORD PTR 12[esi]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR 8[edi],eax
        +	mov	DWORD PTR 12[edi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	add	esi,16
        +	sub	edi,16
        +	cmp	esi,edi
        +	jne	$L055invert
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	esi,DWORD PTR 240[edi]
        +	lea	esi,DWORD PTR [esi*1+esi-2]
        +	lea	esi,DWORD PTR [esi*8+edi]
        +	mov	DWORD PTR 28[esp],esi
        +	mov	eax,DWORD PTR 16[edi]
        +ALIGN	4
        +$L056permute:
        +	add	edi,16
        +	mov	esi,eax
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	ebx,DWORD PTR [eax*1+eax]
        +	sub	esi,ebp
        +	and	ebx,4278124286
        +	and	esi,454761243
        +	xor	esi,ebx
        +	mov	ebx,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	ecx,DWORD PTR [ebx*1+ebx]
        +	sub	esi,ebp
        +	and	ecx,4278124286
        +	and	esi,454761243
        +	xor	ebx,eax
        +	xor	esi,ecx
        +	mov	ecx,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edx,DWORD PTR [ecx*1+ecx]
        +	xor	ecx,eax
        +	sub	esi,ebp
        +	and	edx,4278124286
        +	and	esi,454761243
        +	rol	eax,8
        +	xor	edx,esi
        +	mov	ebp,DWORD PTR 4[edi]
        +	xor	eax,ebx
        +	xor	ebx,edx
        +	xor	eax,ecx
        +	rol	ebx,24
        +	xor	ecx,edx
        +	xor	eax,edx
        +	rol	ecx,16
        +	xor	eax,ebx
        +	rol	edx,8
        +	xor	eax,ecx
        +	mov	ebx,ebp
        +	xor	eax,edx
        +	mov	DWORD PTR [edi],eax
        +	mov	esi,ebx
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	ecx,DWORD PTR [ebx*1+ebx]
        +	sub	esi,ebp
        +	and	ecx,4278124286
        +	and	esi,454761243
        +	xor	esi,ecx
        +	mov	ecx,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edx,DWORD PTR [ecx*1+ecx]
        +	sub	esi,ebp
        +	and	edx,4278124286
        +	and	esi,454761243
        +	xor	ecx,ebx
        +	xor	esi,edx
        +	mov	edx,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	eax,DWORD PTR [edx*1+edx]
        +	xor	edx,ebx
        +	sub	esi,ebp
        +	and	eax,4278124286
        +	and	esi,454761243
        +	rol	ebx,8
        +	xor	eax,esi
        +	mov	ebp,DWORD PTR 8[edi]
        +	xor	ebx,ecx
        +	xor	ecx,eax
        +	xor	ebx,edx
        +	rol	ecx,24
        +	xor	edx,eax
        +	xor	ebx,eax
        +	rol	edx,16
        +	xor	ebx,ecx
        +	rol	eax,8
        +	xor	ebx,edx
        +	mov	ecx,ebp
        +	xor	ebx,eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	esi,ecx
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	edx,DWORD PTR [ecx*1+ecx]
        +	sub	esi,ebp
        +	and	edx,4278124286
        +	and	esi,454761243
        +	xor	esi,edx
        +	mov	edx,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	eax,DWORD PTR [edx*1+edx]
        +	sub	esi,ebp
        +	and	eax,4278124286
        +	and	esi,454761243
        +	xor	edx,ecx
        +	xor	esi,eax
        +	mov	eax,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	ebx,DWORD PTR [eax*1+eax]
        +	xor	eax,ecx
        +	sub	esi,ebp
        +	and	ebx,4278124286
        +	and	esi,454761243
        +	rol	ecx,8
        +	xor	ebx,esi
        +	mov	ebp,DWORD PTR 12[edi]
        +	xor	ecx,edx
        +	xor	edx,ebx
        +	xor	ecx,eax
        +	rol	edx,24
        +	xor	eax,ebx
        +	xor	ecx,ebx
        +	rol	eax,16
        +	xor	ecx,edx
        +	rol	ebx,8
        +	xor	ecx,eax
        +	mov	edx,ebp
        +	xor	ecx,ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	esi,edx
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	eax,DWORD PTR [edx*1+edx]
        +	sub	esi,ebp
        +	and	eax,4278124286
        +	and	esi,454761243
        +	xor	esi,eax
        +	mov	eax,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	ebx,DWORD PTR [eax*1+eax]
        +	sub	esi,ebp
        +	and	ebx,4278124286
        +	and	esi,454761243
        +	xor	eax,edx
        +	xor	esi,ebx
        +	mov	ebx,esi
        +	and	esi,2155905152
        +	mov	ebp,esi
        +	shr	ebp,7
        +	lea	ecx,DWORD PTR [ebx*1+ebx]
        +	xor	ebx,edx
        +	sub	esi,ebp
        +	and	ecx,4278124286
        +	and	esi,454761243
        +	rol	edx,8
        +	xor	ecx,esi
        +	mov	ebp,DWORD PTR 16[edi]
        +	xor	edx,eax
        +	xor	eax,ecx
        +	xor	edx,ebx
        +	rol	eax,24
        +	xor	ebx,ecx
        +	xor	edx,ecx
        +	rol	ebx,16
        +	xor	edx,eax
        +	rol	ecx,8
        +	xor	edx,ebx
        +	mov	eax,ebp
        +	xor	edx,ecx
        +	mov	DWORD PTR 12[edi],edx
        +	cmp	edi,DWORD PTR 28[esp]
        +	jb	$L056permute
        +	xor	eax,eax
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_private_AES_set_decrypt_key ENDP
        +DB	65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89
        +DB	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
        +DB	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.text$	ENDS
        +.bss	SEGMENT 'BSS'
        +COMM	_OPENSSL_ia32cap_P:QWORD
        +.bss	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/aes/aesni-x86.asm b/vendor/openssl/asm/x86-win32-masm/aes/aesni-x86.asm
        new file mode 100644
        index 000000000..a1602cc69
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/aes/aesni-x86.asm
        @@ -0,0 +1,2133 @@
        +TITLE	../openssl/crypto/aes/asm/aesni-x86.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.XMM
        +IF @Version LT 800
        +XMMWORD STRUCT 16
        +DQ	2 dup (?)
        +XMMWORD	ENDS
        +ENDIF
        +
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_aesni_encrypt	PROC PUBLIC
        +$L_aesni_encrypt_begin::
        +	mov	eax,DWORD PTR 4[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	movups	xmm2,XMMWORD PTR [eax]
        +	mov	ecx,DWORD PTR 240[edx]
        +	mov	eax,DWORD PTR 8[esp]
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L000enc1_loop_1:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L000enc1_loop_1
        +DB	102,15,56,221,209
        +	movups	XMMWORD PTR [eax],xmm2
        +	ret
        +_aesni_encrypt ENDP
        +ALIGN	16
        +_aesni_decrypt	PROC PUBLIC
        +$L_aesni_decrypt_begin::
        +	mov	eax,DWORD PTR 4[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	movups	xmm2,XMMWORD PTR [eax]
        +	mov	ecx,DWORD PTR 240[edx]
        +	mov	eax,DWORD PTR 8[esp]
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L001dec1_loop_2:
        +DB	102,15,56,222,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L001dec1_loop_2
        +DB	102,15,56,223,209
        +	movups	XMMWORD PTR [eax],xmm2
        +	ret
        +_aesni_decrypt ENDP
        +ALIGN	16
        +__aesni_encrypt3	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR [edx]
        +	shr	ecx,1
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +	pxor	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR [edx]
        +$L002enc3_loop:
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	ecx
        +DB	102,15,56,220,225
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,220,224
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L002enc3_loop
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +	ret
        +__aesni_encrypt3 ENDP
        +ALIGN	16
        +__aesni_decrypt3	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR [edx]
        +	shr	ecx,1
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +	pxor	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR [edx]
        +$L003dec3_loop:
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	ecx
        +DB	102,15,56,222,225
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,222,224
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L003dec3_loop
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +	ret
        +__aesni_decrypt3 ENDP
        +ALIGN	16
        +__aesni_encrypt4	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	shr	ecx,1
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +	pxor	xmm4,xmm0
        +	pxor	xmm5,xmm0
        +	movups	xmm0,XMMWORD PTR [edx]
        +$L004enc4_loop:
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	ecx
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L004enc4_loop
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +DB	102,15,56,221,232
        +	ret
        +__aesni_encrypt4 ENDP
        +ALIGN	16
        +__aesni_decrypt4	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	shr	ecx,1
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +	pxor	xmm4,xmm0
        +	pxor	xmm5,xmm0
        +	movups	xmm0,XMMWORD PTR [edx]
        +$L005dec4_loop:
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	ecx
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,222,224
        +DB	102,15,56,222,232
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L005dec4_loop
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +DB	102,15,56,223,232
        +	ret
        +__aesni_decrypt4 ENDP
        +ALIGN	16
        +__aesni_encrypt6	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR [edx]
        +	shr	ecx,1
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +DB	102,15,56,220,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,220,217
        +	pxor	xmm5,xmm0
        +	dec	ecx
        +DB	102,15,56,220,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +DB	102,15,56,220,241
        +	movups	xmm0,XMMWORD PTR [edx]
        +DB	102,15,56,220,249
        +	jmp	$L_aesni_encrypt6_enter
        +ALIGN	16
        +$L006enc6_loop:
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	dec	ecx
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +ALIGN	16
        +$L_aesni_encrypt6_enter::
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,220,208
        +DB	102,15,56,220,216
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,220,224
        +DB	102,15,56,220,232
        +DB	102,15,56,220,240
        +DB	102,15,56,220,248
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L006enc6_loop
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +DB	102,15,56,220,225
        +DB	102,15,56,220,233
        +DB	102,15,56,220,241
        +DB	102,15,56,220,249
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +DB	102,15,56,221,224
        +DB	102,15,56,221,232
        +DB	102,15,56,221,240
        +DB	102,15,56,221,248
        +	ret
        +__aesni_encrypt6 ENDP
        +ALIGN	16
        +__aesni_decrypt6	PROC PRIVATE
        +	movups	xmm0,XMMWORD PTR [edx]
        +	shr	ecx,1
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +DB	102,15,56,222,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,222,217
        +	pxor	xmm5,xmm0
        +	dec	ecx
        +DB	102,15,56,222,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,222,233
        +	pxor	xmm7,xmm0
        +DB	102,15,56,222,241
        +	movups	xmm0,XMMWORD PTR [edx]
        +DB	102,15,56,222,249
        +	jmp	$L_aesni_decrypt6_enter
        +ALIGN	16
        +$L007dec6_loop:
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +	dec	ecx
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +ALIGN	16
        +$L_aesni_decrypt6_enter::
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,222,208
        +DB	102,15,56,222,216
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,222,224
        +DB	102,15,56,222,232
        +DB	102,15,56,222,240
        +DB	102,15,56,222,248
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L007dec6_loop
        +DB	102,15,56,222,209
        +DB	102,15,56,222,217
        +DB	102,15,56,222,225
        +DB	102,15,56,222,233
        +DB	102,15,56,222,241
        +DB	102,15,56,222,249
        +DB	102,15,56,223,208
        +DB	102,15,56,223,216
        +DB	102,15,56,223,224
        +DB	102,15,56,223,232
        +DB	102,15,56,223,240
        +DB	102,15,56,223,248
        +	ret
        +__aesni_decrypt6 ENDP
        +ALIGN	16
        +_aesni_ecb_encrypt	PROC PUBLIC
        +$L_aesni_ecb_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebx,DWORD PTR 36[esp]
        +	and	eax,-16
        +	jz	$L008ecb_ret
        +	mov	ecx,DWORD PTR 240[edx]
        +	test	ebx,ebx
        +	jz	$L009ecb_decrypt
        +	mov	ebp,edx
        +	mov	ebx,ecx
        +	cmp	eax,96
        +	jb	$L010ecb_enc_tail
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	movdqu	xmm7,XMMWORD PTR 80[esi]
        +	lea	esi,DWORD PTR 96[esi]
        +	sub	eax,96
        +	jmp	$L011ecb_enc_loop6_enter
        +ALIGN	16
        +$L012ecb_enc_loop6:
        +	movups	XMMWORD PTR [edi],xmm2
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	movdqu	xmm7,XMMWORD PTR 80[esi]
        +	lea	esi,DWORD PTR 96[esi]
        +$L011ecb_enc_loop6_enter:
        +	call	__aesni_encrypt6
        +	mov	edx,ebp
        +	mov	ecx,ebx
        +	sub	eax,96
        +	jnc	$L012ecb_enc_loop6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	add	eax,96
        +	jz	$L008ecb_ret
        +$L010ecb_enc_tail:
        +	movups	xmm2,XMMWORD PTR [esi]
        +	cmp	eax,32
        +	jb	$L013ecb_enc_one
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	je	$L014ecb_enc_two
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	cmp	eax,64
        +	jb	$L015ecb_enc_three
        +	movups	xmm5,XMMWORD PTR 48[esi]
        +	je	$L016ecb_enc_four
        +	movups	xmm6,XMMWORD PTR 64[esi]
        +	xorps	xmm7,xmm7
        +	call	__aesni_encrypt6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L013ecb_enc_one:
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L017enc1_loop_3:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L017enc1_loop_3
        +DB	102,15,56,221,209
        +	movups	XMMWORD PTR [edi],xmm2
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L014ecb_enc_two:
        +	xorps	xmm4,xmm4
        +	call	__aesni_encrypt3
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L015ecb_enc_three:
        +	call	__aesni_encrypt3
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L016ecb_enc_four:
        +	call	__aesni_encrypt4
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L009ecb_decrypt:
        +	mov	ebp,edx
        +	mov	ebx,ecx
        +	cmp	eax,96
        +	jb	$L018ecb_dec_tail
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	movdqu	xmm7,XMMWORD PTR 80[esi]
        +	lea	esi,DWORD PTR 96[esi]
        +	sub	eax,96
        +	jmp	$L019ecb_dec_loop6_enter
        +ALIGN	16
        +$L020ecb_dec_loop6:
        +	movups	XMMWORD PTR [edi],xmm2
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	movdqu	xmm7,XMMWORD PTR 80[esi]
        +	lea	esi,DWORD PTR 96[esi]
        +$L019ecb_dec_loop6_enter:
        +	call	__aesni_decrypt6
        +	mov	edx,ebp
        +	mov	ecx,ebx
        +	sub	eax,96
        +	jnc	$L020ecb_dec_loop6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	add	eax,96
        +	jz	$L008ecb_ret
        +$L018ecb_dec_tail:
        +	movups	xmm2,XMMWORD PTR [esi]
        +	cmp	eax,32
        +	jb	$L021ecb_dec_one
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	je	$L022ecb_dec_two
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	cmp	eax,64
        +	jb	$L023ecb_dec_three
        +	movups	xmm5,XMMWORD PTR 48[esi]
        +	je	$L024ecb_dec_four
        +	movups	xmm6,XMMWORD PTR 64[esi]
        +	xorps	xmm7,xmm7
        +	call	__aesni_decrypt6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L021ecb_dec_one:
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L025dec1_loop_4:
        +DB	102,15,56,222,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L025dec1_loop_4
        +DB	102,15,56,223,209
        +	movups	XMMWORD PTR [edi],xmm2
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L022ecb_dec_two:
        +	xorps	xmm4,xmm4
        +	call	__aesni_decrypt3
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L023ecb_dec_three:
        +	call	__aesni_decrypt3
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	jmp	$L008ecb_ret
        +ALIGN	16
        +$L024ecb_dec_four:
        +	call	__aesni_decrypt4
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +$L008ecb_ret:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_ecb_encrypt ENDP
        +ALIGN	16
        +_aesni_ccm64_encrypt_blocks	PROC PUBLIC
        +$L_aesni_ccm64_encrypt_blocks_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	ebp,esp
        +	sub	esp,60
        +	and	esp,-16
        +	mov	DWORD PTR 48[esp],ebp
        +	movdqu	xmm7,XMMWORD PTR [ebx]
        +	movdqu	xmm3,XMMWORD PTR [ecx]
        +	mov	ecx,DWORD PTR 240[edx]
        +	mov	DWORD PTR [esp],202182159
        +	mov	DWORD PTR 4[esp],134810123
        +	mov	DWORD PTR 8[esp],67438087
        +	mov	DWORD PTR 12[esp],66051
        +	mov	ebx,1
        +	xor	ebp,ebp
        +	mov	DWORD PTR 16[esp],ebx
        +	mov	DWORD PTR 20[esp],ebp
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	DWORD PTR 28[esp],ebp
        +	shr	ecx,1
        +	lea	ebp,DWORD PTR [edx]
        +	movdqa	xmm5,XMMWORD PTR [esp]
        +	movdqa	xmm2,xmm7
        +	mov	ebx,ecx
        +DB	102,15,56,0,253
        +$L026ccm64_enc_outer:
        +	movups	xmm0,XMMWORD PTR [ebp]
        +	mov	ecx,ebx
        +	movups	xmm6,XMMWORD PTR [esi]
        +	xorps	xmm2,xmm0
        +	movups	xmm1,XMMWORD PTR 16[ebp]
        +	xorps	xmm0,xmm6
        +	lea	edx,DWORD PTR 32[ebp]
        +	xorps	xmm3,xmm0
        +	movups	xmm0,XMMWORD PTR [edx]
        +$L027ccm64_enc2_loop:
        +DB	102,15,56,220,209
        +	dec	ecx
        +DB	102,15,56,220,217
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,220,208
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,220,216
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L027ccm64_enc2_loop
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	paddq	xmm7,XMMWORD PTR 16[esp]
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +	dec	eax
        +	lea	esi,DWORD PTR 16[esi]
        +	xorps	xmm6,xmm2
        +	movdqa	xmm2,xmm7
        +	movups	XMMWORD PTR [edi],xmm6
        +	lea	edi,DWORD PTR 16[edi]
        +DB	102,15,56,0,213
        +	jnz	$L026ccm64_enc_outer
        +	mov	esp,DWORD PTR 48[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	movups	XMMWORD PTR [edi],xmm3
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_ccm64_encrypt_blocks ENDP
        +ALIGN	16
        +_aesni_ccm64_decrypt_blocks	PROC PUBLIC
        +$L_aesni_ccm64_decrypt_blocks_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	ebp,esp
        +	sub	esp,60
        +	and	esp,-16
        +	mov	DWORD PTR 48[esp],ebp
        +	movdqu	xmm7,XMMWORD PTR [ebx]
        +	movdqu	xmm3,XMMWORD PTR [ecx]
        +	mov	ecx,DWORD PTR 240[edx]
        +	mov	DWORD PTR [esp],202182159
        +	mov	DWORD PTR 4[esp],134810123
        +	mov	DWORD PTR 8[esp],67438087
        +	mov	DWORD PTR 12[esp],66051
        +	mov	ebx,1
        +	xor	ebp,ebp
        +	mov	DWORD PTR 16[esp],ebx
        +	mov	DWORD PTR 20[esp],ebp
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	DWORD PTR 28[esp],ebp
        +	movdqa	xmm5,XMMWORD PTR [esp]
        +	movdqa	xmm2,xmm7
        +	mov	ebp,edx
        +	mov	ebx,ecx
        +DB	102,15,56,0,253
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L028enc1_loop_5:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L028enc1_loop_5
        +DB	102,15,56,221,209
        +	movups	xmm6,XMMWORD PTR [esi]
        +	paddq	xmm7,XMMWORD PTR 16[esp]
        +	lea	esi,QWORD PTR 16[esi]
        +	jmp	$L029ccm64_dec_outer
        +ALIGN	16
        +$L029ccm64_dec_outer:
        +	xorps	xmm6,xmm2
        +	movdqa	xmm2,xmm7
        +	mov	ecx,ebx
        +	movups	XMMWORD PTR [edi],xmm6
        +	lea	edi,DWORD PTR 16[edi]
        +DB	102,15,56,0,213
        +	sub	eax,1
        +	jz	$L030ccm64_dec_break
        +	movups	xmm0,XMMWORD PTR [ebp]
        +	shr	ecx,1
        +	movups	xmm1,XMMWORD PTR 16[ebp]
        +	xorps	xmm6,xmm0
        +	lea	edx,DWORD PTR 32[ebp]
        +	xorps	xmm2,xmm0
        +	xorps	xmm3,xmm6
        +	movups	xmm0,XMMWORD PTR [edx]
        +$L031ccm64_dec2_loop:
        +DB	102,15,56,220,209
        +	dec	ecx
        +DB	102,15,56,220,217
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +DB	102,15,56,220,208
        +	lea	edx,DWORD PTR 32[edx]
        +DB	102,15,56,220,216
        +	movups	xmm0,XMMWORD PTR [edx]
        +	jnz	$L031ccm64_dec2_loop
        +	movups	xmm6,XMMWORD PTR [esi]
        +	paddq	xmm7,XMMWORD PTR 16[esp]
        +DB	102,15,56,220,209
        +DB	102,15,56,220,217
        +	lea	esi,QWORD PTR 16[esi]
        +DB	102,15,56,221,208
        +DB	102,15,56,221,216
        +	jmp	$L029ccm64_dec_outer
        +ALIGN	16
        +$L030ccm64_dec_break:
        +	mov	edx,ebp
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	xorps	xmm6,xmm0
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm3,xmm6
        +$L032enc1_loop_6:
        +DB	102,15,56,220,217
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L032enc1_loop_6
        +DB	102,15,56,221,217
        +	mov	esp,DWORD PTR 48[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	movups	XMMWORD PTR [edi],xmm3
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_ccm64_decrypt_blocks ENDP
        +ALIGN	16
        +_aesni_ctr32_encrypt_blocks	PROC PUBLIC
        +$L_aesni_ctr32_encrypt_blocks_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	ebp,esp
        +	sub	esp,88
        +	and	esp,-16
        +	mov	DWORD PTR 80[esp],ebp
        +	cmp	eax,1
        +	je	$L033ctr32_one_shortcut
        +	movdqu	xmm7,XMMWORD PTR [ebx]
        +	mov	DWORD PTR [esp],202182159
        +	mov	DWORD PTR 4[esp],134810123
        +	mov	DWORD PTR 8[esp],67438087
        +	mov	DWORD PTR 12[esp],66051
        +	mov	ecx,6
        +	xor	ebp,ebp
        +	mov	DWORD PTR 16[esp],ecx
        +	mov	DWORD PTR 20[esp],ecx
        +	mov	DWORD PTR 24[esp],ecx
        +	mov	DWORD PTR 28[esp],ebp
        +DB	102,15,58,22,251,3
        +DB	102,15,58,34,253,3
        +	mov	ecx,DWORD PTR 240[edx]
        +	bswap	ebx
        +	pxor	xmm1,xmm1
        +	pxor	xmm0,xmm0
        +	movdqa	xmm2,XMMWORD PTR [esp]
        +DB	102,15,58,34,203,0
        +	lea	ebp,DWORD PTR 3[ebx]
        +DB	102,15,58,34,197,0
        +	inc	ebx
        +DB	102,15,58,34,203,1
        +	inc	ebp
        +DB	102,15,58,34,197,1
        +	inc	ebx
        +DB	102,15,58,34,203,2
        +	inc	ebp
        +DB	102,15,58,34,197,2
        +	movdqa	XMMWORD PTR 48[esp],xmm1
        +DB	102,15,56,0,202
        +	movdqa	XMMWORD PTR 64[esp],xmm0
        +DB	102,15,56,0,194
        +	pshufd	xmm2,xmm1,192
        +	pshufd	xmm3,xmm1,128
        +	cmp	eax,6
        +	jb	$L034ctr32_tail
        +	movdqa	XMMWORD PTR 32[esp],xmm7
        +	shr	ecx,1
        +	mov	ebp,edx
        +	mov	ebx,ecx
        +	sub	eax,6
        +	jmp	$L035ctr32_loop6
        +ALIGN	16
        +$L035ctr32_loop6:
        +	pshufd	xmm4,xmm1,64
        +	movdqa	xmm1,XMMWORD PTR 32[esp]
        +	pshufd	xmm5,xmm0,192
        +	por	xmm2,xmm1
        +	pshufd	xmm6,xmm0,128
        +	por	xmm3,xmm1
        +	pshufd	xmm7,xmm0,64
        +	por	xmm4,xmm1
        +	por	xmm5,xmm1
        +	por	xmm6,xmm1
        +	por	xmm7,xmm1
        +	movups	xmm0,XMMWORD PTR [ebp]
        +	movups	xmm1,XMMWORD PTR 16[ebp]
        +	lea	edx,DWORD PTR 32[ebp]
        +	dec	ecx
        +	pxor	xmm2,xmm0
        +	pxor	xmm3,xmm0
        +DB	102,15,56,220,209
        +	pxor	xmm4,xmm0
        +DB	102,15,56,220,217
        +	pxor	xmm5,xmm0
        +DB	102,15,56,220,225
        +	pxor	xmm6,xmm0
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +DB	102,15,56,220,241
        +	movups	xmm0,XMMWORD PTR [edx]
        +DB	102,15,56,220,249
        +	call	$L_aesni_encrypt6_enter
        +	movups	xmm1,XMMWORD PTR [esi]
        +	movups	xmm0,XMMWORD PTR 16[esi]
        +	xorps	xmm2,xmm1
        +	movups	xmm1,XMMWORD PTR 32[esi]
        +	xorps	xmm3,xmm0
        +	movups	XMMWORD PTR [edi],xmm2
        +	movdqa	xmm0,XMMWORD PTR 16[esp]
        +	xorps	xmm4,xmm1
        +	movdqa	xmm1,XMMWORD PTR 48[esp]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	paddd	xmm1,xmm0
        +	paddd	xmm0,XMMWORD PTR 64[esp]
        +	movdqa	xmm2,XMMWORD PTR [esp]
        +	movups	xmm3,XMMWORD PTR 48[esi]
        +	movups	xmm4,XMMWORD PTR 64[esi]
        +	xorps	xmm5,xmm3
        +	movups	xmm3,XMMWORD PTR 80[esi]
        +	lea	esi,DWORD PTR 96[esi]
        +	movdqa	XMMWORD PTR 48[esp],xmm1
        +DB	102,15,56,0,202
        +	xorps	xmm6,xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	xorps	xmm7,xmm3
        +	movdqa	XMMWORD PTR 64[esp],xmm0
        +DB	102,15,56,0,194
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	pshufd	xmm2,xmm1,192
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	mov	ecx,ebx
        +	pshufd	xmm3,xmm1,128
        +	sub	eax,6
        +	jnc	$L035ctr32_loop6
        +	add	eax,6
        +	jz	$L036ctr32_ret
        +	mov	edx,ebp
        +	lea	ecx,DWORD PTR 1[ecx*2]
        +	movdqa	xmm7,XMMWORD PTR 32[esp]
        +$L034ctr32_tail:
        +	por	xmm2,xmm7
        +	cmp	eax,2
        +	jb	$L037ctr32_one
        +	pshufd	xmm4,xmm1,64
        +	por	xmm3,xmm7
        +	je	$L038ctr32_two
        +	pshufd	xmm5,xmm0,192
        +	por	xmm4,xmm7
        +	cmp	eax,4
        +	jb	$L039ctr32_three
        +	pshufd	xmm6,xmm0,128
        +	por	xmm5,xmm7
        +	je	$L040ctr32_four
        +	por	xmm6,xmm7
        +	call	__aesni_encrypt6
        +	movups	xmm1,XMMWORD PTR [esi]
        +	movups	xmm0,XMMWORD PTR 16[esi]
        +	xorps	xmm2,xmm1
        +	movups	xmm1,XMMWORD PTR 32[esi]
        +	xorps	xmm3,xmm0
        +	movups	xmm0,XMMWORD PTR 48[esi]
        +	xorps	xmm4,xmm1
        +	movups	xmm1,XMMWORD PTR 64[esi]
        +	xorps	xmm5,xmm0
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm6,xmm1
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	jmp	$L036ctr32_ret
        +ALIGN	16
        +$L033ctr32_one_shortcut:
        +	movups	xmm2,XMMWORD PTR [ebx]
        +	mov	ecx,DWORD PTR 240[edx]
        +$L037ctr32_one:
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L041enc1_loop_7:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L041enc1_loop_7
        +DB	102,15,56,221,209
        +	movups	xmm6,XMMWORD PTR [esi]
        +	xorps	xmm6,xmm2
        +	movups	XMMWORD PTR [edi],xmm6
        +	jmp	$L036ctr32_ret
        +ALIGN	16
        +$L038ctr32_two:
        +	call	__aesni_encrypt3
        +	movups	xmm5,XMMWORD PTR [esi]
        +	movups	xmm6,XMMWORD PTR 16[esi]
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	jmp	$L036ctr32_ret
        +ALIGN	16
        +$L039ctr32_three:
        +	call	__aesni_encrypt3
        +	movups	xmm5,XMMWORD PTR [esi]
        +	movups	xmm6,XMMWORD PTR 16[esi]
        +	xorps	xmm2,xmm5
        +	movups	xmm7,XMMWORD PTR 32[esi]
        +	xorps	xmm3,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	jmp	$L036ctr32_ret
        +ALIGN	16
        +$L040ctr32_four:
        +	call	__aesni_encrypt4
        +	movups	xmm6,XMMWORD PTR [esi]
        +	movups	xmm7,XMMWORD PTR 16[esi]
        +	movups	xmm1,XMMWORD PTR 32[esi]
        +	xorps	xmm2,xmm6
        +	movups	xmm0,XMMWORD PTR 48[esi]
        +	xorps	xmm3,xmm7
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm4,xmm1
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	xorps	xmm5,xmm0
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +$L036ctr32_ret:
        +	mov	esp,DWORD PTR 80[esp]
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_ctr32_encrypt_blocks ENDP
        +ALIGN	16
        +_aesni_xts_encrypt	PROC PUBLIC
        +$L_aesni_xts_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	edx,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR 40[esp]
        +	mov	ecx,DWORD PTR 240[edx]
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L042enc1_loop_8:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L042enc1_loop_8
        +DB	102,15,56,221,209
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebp,esp
        +	sub	esp,120
        +	mov	ecx,DWORD PTR 240[edx]
        +	and	esp,-16
        +	mov	DWORD PTR 96[esp],135
        +	mov	DWORD PTR 100[esp],0
        +	mov	DWORD PTR 104[esp],1
        +	mov	DWORD PTR 108[esp],0
        +	mov	DWORD PTR 112[esp],eax
        +	mov	DWORD PTR 116[esp],ebp
        +	movdqa	xmm1,xmm2
        +	pxor	xmm0,xmm0
        +	movdqa	xmm3,XMMWORD PTR 96[esp]
        +	pcmpgtd	xmm0,xmm1
        +	and	eax,-16
        +	mov	ebp,edx
        +	mov	ebx,ecx
        +	sub	eax,96
        +	jc	$L043xts_enc_short
        +	shr	ecx,1
        +	mov	ebx,ecx
        +	jmp	$L044xts_enc_loop6
        +ALIGN	16
        +$L044xts_enc_loop6:
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR [esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR 16[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR 32[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR 48[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm7,xmm0,19
        +	movdqa	XMMWORD PTR 64[esp],xmm1
        +	paddq	xmm1,xmm1
        +	movups	xmm0,XMMWORD PTR [ebp]
        +	pand	xmm7,xmm3
        +	movups	xmm2,XMMWORD PTR [esi]
        +	pxor	xmm7,xmm1
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	xorps	xmm2,xmm0
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	pxor	xmm3,xmm0
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	pxor	xmm4,xmm0
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	pxor	xmm5,xmm0
        +	movdqu	xmm1,XMMWORD PTR 80[esi]
        +	pxor	xmm6,xmm0
        +	lea	esi,DWORD PTR 96[esi]
        +	pxor	xmm2,XMMWORD PTR [esp]
        +	movdqa	XMMWORD PTR 80[esp],xmm7
        +	pxor	xmm7,xmm1
        +	movups	xmm1,XMMWORD PTR 16[ebp]
        +	lea	edx,DWORD PTR 32[ebp]
        +	pxor	xmm3,XMMWORD PTR 16[esp]
        +DB	102,15,56,220,209
        +	pxor	xmm4,XMMWORD PTR 32[esp]
        +DB	102,15,56,220,217
        +	pxor	xmm5,XMMWORD PTR 48[esp]
        +	dec	ecx
        +DB	102,15,56,220,225
        +	pxor	xmm6,XMMWORD PTR 64[esp]
        +DB	102,15,56,220,233
        +	pxor	xmm7,xmm0
        +DB	102,15,56,220,241
        +	movups	xmm0,XMMWORD PTR [edx]
        +DB	102,15,56,220,249
        +	call	$L_aesni_encrypt6_enter
        +	movdqa	xmm1,XMMWORD PTR 80[esp]
        +	pxor	xmm0,xmm0
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	pcmpgtd	xmm0,xmm1
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm4,XMMWORD PTR 32[esp]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	xorps	xmm5,XMMWORD PTR 48[esp]
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	xorps	xmm6,XMMWORD PTR 64[esp]
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	xorps	xmm7,xmm1
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	pshufd	xmm2,xmm0,19
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	movdqa	xmm3,XMMWORD PTR 96[esp]
        +	pxor	xmm0,xmm0
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	mov	ecx,ebx
        +	pxor	xmm1,xmm2
        +	sub	eax,96
        +	jnc	$L044xts_enc_loop6
        +	lea	ecx,DWORD PTR 1[ecx*2]
        +	mov	edx,ebp
        +	mov	ebx,ecx
        +$L043xts_enc_short:
        +	add	eax,96
        +	jz	$L045xts_enc_done6x
        +	movdqa	xmm5,xmm1
        +	cmp	eax,32
        +	jb	$L046xts_enc_one
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	je	$L047xts_enc_two
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	xmm6,xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	cmp	eax,64
        +	jb	$L048xts_enc_three
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	xmm7,xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	movdqa	XMMWORD PTR [esp],xmm5
        +	movdqa	XMMWORD PTR 16[esp],xmm6
        +	je	$L049xts_enc_four
        +	movdqa	XMMWORD PTR 32[esp],xmm7
        +	pshufd	xmm7,xmm0,19
        +	movdqa	XMMWORD PTR 48[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm7,xmm3
        +	pxor	xmm7,xmm1
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	pxor	xmm2,XMMWORD PTR [esp]
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	pxor	xmm3,XMMWORD PTR 16[esp]
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	pxor	xmm4,XMMWORD PTR 32[esp]
        +	lea	esi,DWORD PTR 80[esi]
        +	pxor	xmm5,XMMWORD PTR 48[esp]
        +	movdqa	XMMWORD PTR 64[esp],xmm7
        +	pxor	xmm6,xmm7
        +	call	__aesni_encrypt6
        +	movaps	xmm1,XMMWORD PTR 64[esp]
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	xorps	xmm4,XMMWORD PTR 32[esp]
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm5,XMMWORD PTR 48[esp]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	xorps	xmm6,xmm1
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	lea	edi,DWORD PTR 80[edi]
        +	jmp	$L050xts_enc_done
        +ALIGN	16
        +$L046xts_enc_one:
        +	movups	xmm2,XMMWORD PTR [esi]
        +	lea	esi,DWORD PTR 16[esi]
        +	xorps	xmm2,xmm5
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L051enc1_loop_9:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L051enc1_loop_9
        +DB	102,15,56,221,209
        +	xorps	xmm2,xmm5
        +	movups	XMMWORD PTR [edi],xmm2
        +	lea	edi,DWORD PTR 16[edi]
        +	movdqa	xmm1,xmm5
        +	jmp	$L050xts_enc_done
        +ALIGN	16
        +$L047xts_enc_two:
        +	movaps	xmm6,xmm1
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	lea	esi,DWORD PTR 32[esi]
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	xorps	xmm4,xmm4
        +	call	__aesni_encrypt3
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	lea	edi,DWORD PTR 32[edi]
        +	movdqa	xmm1,xmm6
        +	jmp	$L050xts_enc_done
        +ALIGN	16
        +$L048xts_enc_three:
        +	movaps	xmm7,xmm1
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	lea	esi,DWORD PTR 48[esi]
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	xorps	xmm4,xmm7
        +	call	__aesni_encrypt3
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	lea	edi,DWORD PTR 48[edi]
        +	movdqa	xmm1,xmm7
        +	jmp	$L050xts_enc_done
        +ALIGN	16
        +$L049xts_enc_four:
        +	movaps	xmm6,xmm1
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	movups	xmm5,XMMWORD PTR 48[esi]
        +	lea	esi,DWORD PTR 64[esi]
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	xorps	xmm4,xmm7
        +	xorps	xmm5,xmm6
        +	call	__aesni_encrypt4
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm5,xmm6
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	lea	edi,DWORD PTR 64[edi]
        +	movdqa	xmm1,xmm6
        +	jmp	$L050xts_enc_done
        +ALIGN	16
        +$L045xts_enc_done6x:
        +	mov	eax,DWORD PTR 112[esp]
        +	and	eax,15
        +	jz	$L052xts_enc_ret
        +	movdqa	xmm5,xmm1
        +	mov	DWORD PTR 112[esp],eax
        +	jmp	$L053xts_enc_steal
        +ALIGN	16
        +$L050xts_enc_done:
        +	mov	eax,DWORD PTR 112[esp]
        +	pxor	xmm0,xmm0
        +	and	eax,15
        +	jz	$L052xts_enc_ret
        +	pcmpgtd	xmm0,xmm1
        +	mov	DWORD PTR 112[esp],eax
        +	pshufd	xmm5,xmm0,19
        +	paddq	xmm1,xmm1
        +	pand	xmm5,XMMWORD PTR 96[esp]
        +	pxor	xmm5,xmm1
        +$L053xts_enc_steal:
        +	movzx	ecx,BYTE PTR [esi]
        +	movzx	edx,BYTE PTR [edi-16]
        +	lea	esi,DWORD PTR 1[esi]
        +	mov	BYTE PTR [edi-16],cl
        +	mov	BYTE PTR [edi],dl
        +	lea	edi,DWORD PTR 1[edi]
        +	sub	eax,1
        +	jnz	$L053xts_enc_steal
        +	sub	edi,DWORD PTR 112[esp]
        +	mov	edx,ebp
        +	mov	ecx,ebx
        +	movups	xmm2,XMMWORD PTR [edi-16]
        +	xorps	xmm2,xmm5
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L054enc1_loop_10:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L054enc1_loop_10
        +DB	102,15,56,221,209
        +	xorps	xmm2,xmm5
        +	movups	XMMWORD PTR [edi-16],xmm2
        +$L052xts_enc_ret:
        +	mov	esp,DWORD PTR 116[esp]
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_xts_encrypt ENDP
        +ALIGN	16
        +_aesni_xts_decrypt	PROC PUBLIC
        +$L_aesni_xts_decrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	edx,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR 40[esp]
        +	mov	ecx,DWORD PTR 240[edx]
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L055enc1_loop_11:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L055enc1_loop_11
        +DB	102,15,56,221,209
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebp,esp
        +	sub	esp,120
        +	and	esp,-16
        +	xor	ebx,ebx
        +	test	eax,15
        +	setnz	bl
        +	shl	ebx,4
        +	sub	eax,ebx
        +	mov	DWORD PTR 96[esp],135
        +	mov	DWORD PTR 100[esp],0
        +	mov	DWORD PTR 104[esp],1
        +	mov	DWORD PTR 108[esp],0
        +	mov	DWORD PTR 112[esp],eax
        +	mov	DWORD PTR 116[esp],ebp
        +	mov	ecx,DWORD PTR 240[edx]
        +	mov	ebp,edx
        +	mov	ebx,ecx
        +	movdqa	xmm1,xmm2
        +	pxor	xmm0,xmm0
        +	movdqa	xmm3,XMMWORD PTR 96[esp]
        +	pcmpgtd	xmm0,xmm1
        +	and	eax,-16
        +	sub	eax,96
        +	jc	$L056xts_dec_short
        +	shr	ecx,1
        +	mov	ebx,ecx
        +	jmp	$L057xts_dec_loop6
        +ALIGN	16
        +$L057xts_dec_loop6:
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR [esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR 16[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR 32[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	XMMWORD PTR 48[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	pshufd	xmm7,xmm0,19
        +	movdqa	XMMWORD PTR 64[esp],xmm1
        +	paddq	xmm1,xmm1
        +	movups	xmm0,XMMWORD PTR [ebp]
        +	pand	xmm7,xmm3
        +	movups	xmm2,XMMWORD PTR [esi]
        +	pxor	xmm7,xmm1
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	xorps	xmm2,xmm0
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	pxor	xmm3,xmm0
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	pxor	xmm4,xmm0
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	pxor	xmm5,xmm0
        +	movdqu	xmm1,XMMWORD PTR 80[esi]
        +	pxor	xmm6,xmm0
        +	lea	esi,DWORD PTR 96[esi]
        +	pxor	xmm2,XMMWORD PTR [esp]
        +	movdqa	XMMWORD PTR 80[esp],xmm7
        +	pxor	xmm7,xmm1
        +	movups	xmm1,XMMWORD PTR 16[ebp]
        +	lea	edx,DWORD PTR 32[ebp]
        +	pxor	xmm3,XMMWORD PTR 16[esp]
        +DB	102,15,56,222,209
        +	pxor	xmm4,XMMWORD PTR 32[esp]
        +DB	102,15,56,222,217
        +	pxor	xmm5,XMMWORD PTR 48[esp]
        +	dec	ecx
        +DB	102,15,56,222,225
        +	pxor	xmm6,XMMWORD PTR 64[esp]
        +DB	102,15,56,222,233
        +	pxor	xmm7,xmm0
        +DB	102,15,56,222,241
        +	movups	xmm0,XMMWORD PTR [edx]
        +DB	102,15,56,222,249
        +	call	$L_aesni_decrypt6_enter
        +	movdqa	xmm1,XMMWORD PTR 80[esp]
        +	pxor	xmm0,xmm0
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	pcmpgtd	xmm0,xmm1
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm4,XMMWORD PTR 32[esp]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	xorps	xmm5,XMMWORD PTR 48[esp]
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	xorps	xmm6,XMMWORD PTR 64[esp]
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	xorps	xmm7,xmm1
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	pshufd	xmm2,xmm0,19
        +	movups	XMMWORD PTR 80[edi],xmm7
        +	lea	edi,DWORD PTR 96[edi]
        +	movdqa	xmm3,XMMWORD PTR 96[esp]
        +	pxor	xmm0,xmm0
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	mov	ecx,ebx
        +	pxor	xmm1,xmm2
        +	sub	eax,96
        +	jnc	$L057xts_dec_loop6
        +	lea	ecx,DWORD PTR 1[ecx*2]
        +	mov	edx,ebp
        +	mov	ebx,ecx
        +$L056xts_dec_short:
        +	add	eax,96
        +	jz	$L058xts_dec_done6x
        +	movdqa	xmm5,xmm1
        +	cmp	eax,32
        +	jb	$L059xts_dec_one
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	je	$L060xts_dec_two
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	xmm6,xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	cmp	eax,64
        +	jb	$L061xts_dec_three
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	xmm7,xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +	movdqa	XMMWORD PTR [esp],xmm5
        +	movdqa	XMMWORD PTR 16[esp],xmm6
        +	je	$L062xts_dec_four
        +	movdqa	XMMWORD PTR 32[esp],xmm7
        +	pshufd	xmm7,xmm0,19
        +	movdqa	XMMWORD PTR 48[esp],xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm7,xmm3
        +	pxor	xmm7,xmm1
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	pxor	xmm2,XMMWORD PTR [esp]
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	pxor	xmm3,XMMWORD PTR 16[esp]
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	pxor	xmm4,XMMWORD PTR 32[esp]
        +	lea	esi,DWORD PTR 80[esi]
        +	pxor	xmm5,XMMWORD PTR 48[esp]
        +	movdqa	XMMWORD PTR 64[esp],xmm7
        +	pxor	xmm6,xmm7
        +	call	__aesni_decrypt6
        +	movaps	xmm1,XMMWORD PTR 64[esp]
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	xorps	xmm4,XMMWORD PTR 32[esp]
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm5,XMMWORD PTR 48[esp]
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	xorps	xmm6,xmm1
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	lea	edi,DWORD PTR 80[edi]
        +	jmp	$L063xts_dec_done
        +ALIGN	16
        +$L059xts_dec_one:
        +	movups	xmm2,XMMWORD PTR [esi]
        +	lea	esi,DWORD PTR 16[esi]
        +	xorps	xmm2,xmm5
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L064dec1_loop_12:
        +DB	102,15,56,222,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L064dec1_loop_12
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm5
        +	movups	XMMWORD PTR [edi],xmm2
        +	lea	edi,DWORD PTR 16[edi]
        +	movdqa	xmm1,xmm5
        +	jmp	$L063xts_dec_done
        +ALIGN	16
        +$L060xts_dec_two:
        +	movaps	xmm6,xmm1
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	lea	esi,DWORD PTR 32[esi]
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	call	__aesni_decrypt3
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	lea	edi,DWORD PTR 32[edi]
        +	movdqa	xmm1,xmm6
        +	jmp	$L063xts_dec_done
        +ALIGN	16
        +$L061xts_dec_three:
        +	movaps	xmm7,xmm1
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	lea	esi,DWORD PTR 48[esi]
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	xorps	xmm4,xmm7
        +	call	__aesni_decrypt3
        +	xorps	xmm2,xmm5
        +	xorps	xmm3,xmm6
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	lea	edi,DWORD PTR 48[edi]
        +	movdqa	xmm1,xmm7
        +	jmp	$L063xts_dec_done
        +ALIGN	16
        +$L062xts_dec_four:
        +	movaps	xmm6,xmm1
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	movups	xmm5,XMMWORD PTR 48[esi]
        +	lea	esi,DWORD PTR 64[esi]
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	xorps	xmm4,xmm7
        +	xorps	xmm5,xmm6
        +	call	__aesni_decrypt4
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	xorps	xmm3,XMMWORD PTR 16[esp]
        +	xorps	xmm4,xmm7
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm5,xmm6
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	lea	edi,DWORD PTR 64[edi]
        +	movdqa	xmm1,xmm6
        +	jmp	$L063xts_dec_done
        +ALIGN	16
        +$L058xts_dec_done6x:
        +	mov	eax,DWORD PTR 112[esp]
        +	and	eax,15
        +	jz	$L065xts_dec_ret
        +	mov	DWORD PTR 112[esp],eax
        +	jmp	$L066xts_dec_only_one_more
        +ALIGN	16
        +$L063xts_dec_done:
        +	mov	eax,DWORD PTR 112[esp]
        +	pxor	xmm0,xmm0
        +	and	eax,15
        +	jz	$L065xts_dec_ret
        +	pcmpgtd	xmm0,xmm1
        +	mov	DWORD PTR 112[esp],eax
        +	pshufd	xmm2,xmm0,19
        +	pxor	xmm0,xmm0
        +	movdqa	xmm3,XMMWORD PTR 96[esp]
        +	paddq	xmm1,xmm1
        +	pand	xmm2,xmm3
        +	pcmpgtd	xmm0,xmm1
        +	pxor	xmm1,xmm2
        +$L066xts_dec_only_one_more:
        +	pshufd	xmm5,xmm0,19
        +	movdqa	xmm6,xmm1
        +	paddq	xmm1,xmm1
        +	pand	xmm5,xmm3
        +	pxor	xmm5,xmm1
        +	mov	edx,ebp
        +	mov	ecx,ebx
        +	movups	xmm2,XMMWORD PTR [esi]
        +	xorps	xmm2,xmm5
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L067dec1_loop_13:
        +DB	102,15,56,222,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L067dec1_loop_13
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm5
        +	movups	XMMWORD PTR [edi],xmm2
        +$L068xts_dec_steal:
        +	movzx	ecx,BYTE PTR 16[esi]
        +	movzx	edx,BYTE PTR [edi]
        +	lea	esi,DWORD PTR 1[esi]
        +	mov	BYTE PTR [edi],cl
        +	mov	BYTE PTR 16[edi],dl
        +	lea	edi,DWORD PTR 1[edi]
        +	sub	eax,1
        +	jnz	$L068xts_dec_steal
        +	sub	edi,DWORD PTR 112[esp]
        +	mov	edx,ebp
        +	mov	ecx,ebx
        +	movups	xmm2,XMMWORD PTR [edi]
        +	xorps	xmm2,xmm6
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L069dec1_loop_14:
        +DB	102,15,56,222,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L069dec1_loop_14
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +$L065xts_dec_ret:
        +	mov	esp,DWORD PTR 116[esp]
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_xts_decrypt ENDP
        +ALIGN	16
        +_aesni_cbc_encrypt	PROC PUBLIC
        +$L_aesni_cbc_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	ebx,esp
        +	mov	edi,DWORD PTR 24[esp]
        +	sub	ebx,24
        +	mov	eax,DWORD PTR 28[esp]
        +	and	ebx,-16
        +	mov	edx,DWORD PTR 32[esp]
        +	mov	ebp,DWORD PTR 36[esp]
        +	test	eax,eax
        +	jz	$L070cbc_abort
        +	cmp	DWORD PTR 40[esp],0
        +	xchg	ebx,esp
        +	movups	xmm7,XMMWORD PTR [ebp]
        +	mov	ecx,DWORD PTR 240[edx]
        +	mov	ebp,edx
        +	mov	DWORD PTR 16[esp],ebx
        +	mov	ebx,ecx
        +	je	$L071cbc_decrypt
        +	movaps	xmm2,xmm7
        +	cmp	eax,16
        +	jb	$L072cbc_enc_tail
        +	sub	eax,16
        +	jmp	$L073cbc_enc_loop
        +ALIGN	16
        +$L073cbc_enc_loop:
        +	movups	xmm7,XMMWORD PTR [esi]
        +	lea	esi,DWORD PTR 16[esi]
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	xorps	xmm7,xmm0
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm7
        +$L074enc1_loop_15:
        +DB	102,15,56,220,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L074enc1_loop_15
        +DB	102,15,56,221,209
        +	mov	ecx,ebx
        +	mov	edx,ebp
        +	movups	XMMWORD PTR [edi],xmm2
        +	lea	edi,DWORD PTR 16[edi]
        +	sub	eax,16
        +	jnc	$L073cbc_enc_loop
        +	add	eax,16
        +	jnz	$L072cbc_enc_tail
        +	movaps	xmm7,xmm2
        +	jmp	$L075cbc_ret
        +$L072cbc_enc_tail:
        +	mov	ecx,eax
        +DD	2767451785
        +	mov	ecx,16
        +	sub	ecx,eax
        +	xor	eax,eax
        +DD	2868115081
        +	lea	edi,DWORD PTR [edi-16]
        +	mov	ecx,ebx
        +	mov	esi,edi
        +	mov	edx,ebp
        +	jmp	$L073cbc_enc_loop
        +ALIGN	16
        +$L071cbc_decrypt:
        +	cmp	eax,80
        +	jbe	$L076cbc_dec_tail
        +	movaps	XMMWORD PTR [esp],xmm7
        +	sub	eax,80
        +	jmp	$L077cbc_dec_loop6_enter
        +ALIGN	16
        +$L078cbc_dec_loop6:
        +	movaps	XMMWORD PTR [esp],xmm0
        +	movups	XMMWORD PTR [edi],xmm7
        +	lea	edi,DWORD PTR 16[edi]
        +$L077cbc_dec_loop6_enter:
        +	movdqu	xmm2,XMMWORD PTR [esi]
        +	movdqu	xmm3,XMMWORD PTR 16[esi]
        +	movdqu	xmm4,XMMWORD PTR 32[esi]
        +	movdqu	xmm5,XMMWORD PTR 48[esi]
        +	movdqu	xmm6,XMMWORD PTR 64[esi]
        +	movdqu	xmm7,XMMWORD PTR 80[esi]
        +	call	__aesni_decrypt6
        +	movups	xmm1,XMMWORD PTR [esi]
        +	movups	xmm0,XMMWORD PTR 16[esi]
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	xorps	xmm3,xmm1
        +	movups	xmm1,XMMWORD PTR 32[esi]
        +	xorps	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR 48[esi]
        +	xorps	xmm5,xmm1
        +	movups	xmm1,XMMWORD PTR 64[esi]
        +	xorps	xmm6,xmm0
        +	movups	xmm0,XMMWORD PTR 80[esi]
        +	xorps	xmm7,xmm1
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	lea	esi,DWORD PTR 96[esi]
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	mov	ecx,ebx
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	mov	edx,ebp
        +	movups	XMMWORD PTR 64[edi],xmm6
        +	lea	edi,DWORD PTR 80[edi]
        +	sub	eax,96
        +	ja	$L078cbc_dec_loop6
        +	movaps	xmm2,xmm7
        +	movaps	xmm7,xmm0
        +	add	eax,80
        +	jle	$L079cbc_dec_tail_collected
        +	movups	XMMWORD PTR [edi],xmm2
        +	lea	edi,DWORD PTR 16[edi]
        +$L076cbc_dec_tail:
        +	movups	xmm2,XMMWORD PTR [esi]
        +	movaps	xmm6,xmm2
        +	cmp	eax,16
        +	jbe	$L080cbc_dec_one
        +	movups	xmm3,XMMWORD PTR 16[esi]
        +	movaps	xmm5,xmm3
        +	cmp	eax,32
        +	jbe	$L081cbc_dec_two
        +	movups	xmm4,XMMWORD PTR 32[esi]
        +	cmp	eax,48
        +	jbe	$L082cbc_dec_three
        +	movups	xmm5,XMMWORD PTR 48[esi]
        +	cmp	eax,64
        +	jbe	$L083cbc_dec_four
        +	movups	xmm6,XMMWORD PTR 64[esi]
        +	movaps	XMMWORD PTR [esp],xmm7
        +	movups	xmm2,XMMWORD PTR [esi]
        +	xorps	xmm7,xmm7
        +	call	__aesni_decrypt6
        +	movups	xmm1,XMMWORD PTR [esi]
        +	movups	xmm0,XMMWORD PTR 16[esi]
        +	xorps	xmm2,XMMWORD PTR [esp]
        +	xorps	xmm3,xmm1
        +	movups	xmm1,XMMWORD PTR 32[esi]
        +	xorps	xmm4,xmm0
        +	movups	xmm0,XMMWORD PTR 48[esi]
        +	xorps	xmm5,xmm1
        +	movups	xmm7,XMMWORD PTR 64[esi]
        +	xorps	xmm6,xmm0
        +	movups	XMMWORD PTR [edi],xmm2
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	movups	XMMWORD PTR 48[edi],xmm5
        +	lea	edi,DWORD PTR 64[edi]
        +	movaps	xmm2,xmm6
        +	sub	eax,80
        +	jmp	$L079cbc_dec_tail_collected
        +ALIGN	16
        +$L080cbc_dec_one:
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR 16[edx]
        +	lea	edx,DWORD PTR 32[edx]
        +	xorps	xmm2,xmm0
        +$L084dec1_loop_16:
        +DB	102,15,56,222,209
        +	dec	ecx
        +	movups	xmm1,XMMWORD PTR [edx]
        +	lea	edx,DWORD PTR 16[edx]
        +	jnz	$L084dec1_loop_16
        +DB	102,15,56,223,209
        +	xorps	xmm2,xmm7
        +	movaps	xmm7,xmm6
        +	sub	eax,16
        +	jmp	$L079cbc_dec_tail_collected
        +ALIGN	16
        +$L081cbc_dec_two:
        +	xorps	xmm4,xmm4
        +	call	__aesni_decrypt3
        +	xorps	xmm2,xmm7
        +	xorps	xmm3,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +	movaps	xmm2,xmm3
        +	lea	edi,DWORD PTR 16[edi]
        +	movaps	xmm7,xmm5
        +	sub	eax,32
        +	jmp	$L079cbc_dec_tail_collected
        +ALIGN	16
        +$L082cbc_dec_three:
        +	call	__aesni_decrypt3
        +	xorps	xmm2,xmm7
        +	xorps	xmm3,xmm6
        +	xorps	xmm4,xmm5
        +	movups	XMMWORD PTR [edi],xmm2
        +	movaps	xmm2,xmm4
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	lea	edi,DWORD PTR 32[edi]
        +	movups	xmm7,XMMWORD PTR 32[esi]
        +	sub	eax,48
        +	jmp	$L079cbc_dec_tail_collected
        +ALIGN	16
        +$L083cbc_dec_four:
        +	call	__aesni_decrypt4
        +	movups	xmm1,XMMWORD PTR 16[esi]
        +	movups	xmm0,XMMWORD PTR 32[esi]
        +	xorps	xmm2,xmm7
        +	movups	xmm7,XMMWORD PTR 48[esi]
        +	xorps	xmm3,xmm6
        +	movups	XMMWORD PTR [edi],xmm2
        +	xorps	xmm4,xmm1
        +	movups	XMMWORD PTR 16[edi],xmm3
        +	xorps	xmm5,xmm0
        +	movups	XMMWORD PTR 32[edi],xmm4
        +	lea	edi,DWORD PTR 48[edi]
        +	movaps	xmm2,xmm5
        +	sub	eax,64
        +$L079cbc_dec_tail_collected:
        +	and	eax,15
        +	jnz	$L085cbc_dec_tail_partial
        +	movups	XMMWORD PTR [edi],xmm2
        +	jmp	$L075cbc_ret
        +ALIGN	16
        +$L085cbc_dec_tail_partial:
        +	movaps	XMMWORD PTR [esp],xmm2
        +	mov	ecx,16
        +	mov	esi,esp
        +	sub	ecx,eax
        +DD	2767451785
        +$L075cbc_ret:
        +	mov	esp,DWORD PTR 16[esp]
        +	mov	ebp,DWORD PTR 36[esp]
        +	movups	XMMWORD PTR [ebp],xmm7
        +$L070cbc_abort:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_aesni_cbc_encrypt ENDP
        +ALIGN	16
        +__aesni_set_encrypt_key	PROC PRIVATE
        +	test	eax,eax
        +	jz	$L086bad_pointer
        +	test	edx,edx
        +	jz	$L086bad_pointer
        +	movups	xmm0,XMMWORD PTR [eax]
        +	xorps	xmm4,xmm4
        +	lea	edx,DWORD PTR 16[edx]
        +	cmp	ecx,256
        +	je	$L08714rounds
        +	cmp	ecx,192
        +	je	$L08812rounds
        +	cmp	ecx,128
        +	jne	$L089bad_keybits
        +ALIGN	16
        +$L09010rounds:
        +	mov	ecx,9
        +	movups	XMMWORD PTR [edx-16],xmm0
        +DB	102,15,58,223,200,1
        +	call	$L091key_128_cold
        +DB	102,15,58,223,200,2
        +	call	$L092key_128
        +DB	102,15,58,223,200,4
        +	call	$L092key_128
        +DB	102,15,58,223,200,8
        +	call	$L092key_128
        +DB	102,15,58,223,200,16
        +	call	$L092key_128
        +DB	102,15,58,223,200,32
        +	call	$L092key_128
        +DB	102,15,58,223,200,64
        +	call	$L092key_128
        +DB	102,15,58,223,200,128
        +	call	$L092key_128
        +DB	102,15,58,223,200,27
        +	call	$L092key_128
        +DB	102,15,58,223,200,54
        +	call	$L092key_128
        +	movups	XMMWORD PTR [edx],xmm0
        +	mov	DWORD PTR 80[edx],ecx
        +	xor	eax,eax
        +	ret
        +ALIGN	16
        +$L092key_128:
        +	movups	XMMWORD PTR [edx],xmm0
        +	lea	edx,DWORD PTR 16[edx]
        +$L091key_128_cold:
        +	shufps	xmm4,xmm0,16
        +	xorps	xmm0,xmm4
        +	shufps	xmm4,xmm0,140
        +	xorps	xmm0,xmm4
        +	shufps	xmm1,xmm1,255
        +	xorps	xmm0,xmm1
        +	ret
        +ALIGN	16
        +$L08812rounds:
        +	movq	xmm2,QWORD PTR 16[eax]
        +	mov	ecx,11
        +	movups	XMMWORD PTR [edx-16],xmm0
        +DB	102,15,58,223,202,1
        +	call	$L093key_192a_cold
        +DB	102,15,58,223,202,2
        +	call	$L094key_192b
        +DB	102,15,58,223,202,4
        +	call	$L095key_192a
        +DB	102,15,58,223,202,8
        +	call	$L094key_192b
        +DB	102,15,58,223,202,16
        +	call	$L095key_192a
        +DB	102,15,58,223,202,32
        +	call	$L094key_192b
        +DB	102,15,58,223,202,64
        +	call	$L095key_192a
        +DB	102,15,58,223,202,128
        +	call	$L094key_192b
        +	movups	XMMWORD PTR [edx],xmm0
        +	mov	DWORD PTR 48[edx],ecx
        +	xor	eax,eax
        +	ret
        +ALIGN	16
        +$L095key_192a:
        +	movups	XMMWORD PTR [edx],xmm0
        +	lea	edx,DWORD PTR 16[edx]
        +ALIGN	16
        +$L093key_192a_cold:
        +	movaps	xmm5,xmm2
        +$L096key_192b_warm:
        +	shufps	xmm4,xmm0,16
        +	movdqa	xmm3,xmm2
        +	xorps	xmm0,xmm4
        +	shufps	xmm4,xmm0,140
        +	pslldq	xmm3,4
        +	xorps	xmm0,xmm4
        +	pshufd	xmm1,xmm1,85
        +	pxor	xmm2,xmm3
        +	pxor	xmm0,xmm1
        +	pshufd	xmm3,xmm0,255
        +	pxor	xmm2,xmm3
        +	ret
        +ALIGN	16
        +$L094key_192b:
        +	movaps	xmm3,xmm0
        +	shufps	xmm5,xmm0,68
        +	movups	XMMWORD PTR [edx],xmm5
        +	shufps	xmm3,xmm2,78
        +	movups	XMMWORD PTR 16[edx],xmm3
        +	lea	edx,DWORD PTR 32[edx]
        +	jmp	$L096key_192b_warm
        +ALIGN	16
        +$L08714rounds:
        +	movups	xmm2,XMMWORD PTR 16[eax]
        +	mov	ecx,13
        +	lea	edx,DWORD PTR 16[edx]
        +	movups	XMMWORD PTR [edx-32],xmm0
        +	movups	XMMWORD PTR [edx-16],xmm2
        +DB	102,15,58,223,202,1
        +	call	$L097key_256a_cold
        +DB	102,15,58,223,200,1
        +	call	$L098key_256b
        +DB	102,15,58,223,202,2
        +	call	$L099key_256a
        +DB	102,15,58,223,200,2
        +	call	$L098key_256b
        +DB	102,15,58,223,202,4
        +	call	$L099key_256a
        +DB	102,15,58,223,200,4
        +	call	$L098key_256b
        +DB	102,15,58,223,202,8
        +	call	$L099key_256a
        +DB	102,15,58,223,200,8
        +	call	$L098key_256b
        +DB	102,15,58,223,202,16
        +	call	$L099key_256a
        +DB	102,15,58,223,200,16
        +	call	$L098key_256b
        +DB	102,15,58,223,202,32
        +	call	$L099key_256a
        +DB	102,15,58,223,200,32
        +	call	$L098key_256b
        +DB	102,15,58,223,202,64
        +	call	$L099key_256a
        +	movups	XMMWORD PTR [edx],xmm0
        +	mov	DWORD PTR 16[edx],ecx
        +	xor	eax,eax
        +	ret
        +ALIGN	16
        +$L099key_256a:
        +	movups	XMMWORD PTR [edx],xmm2
        +	lea	edx,DWORD PTR 16[edx]
        +$L097key_256a_cold:
        +	shufps	xmm4,xmm0,16
        +	xorps	xmm0,xmm4
        +	shufps	xmm4,xmm0,140
        +	xorps	xmm0,xmm4
        +	shufps	xmm1,xmm1,255
        +	xorps	xmm0,xmm1
        +	ret
        +ALIGN	16
        +$L098key_256b:
        +	movups	XMMWORD PTR [edx],xmm0
        +	lea	edx,DWORD PTR 16[edx]
        +	shufps	xmm4,xmm2,16
        +	xorps	xmm2,xmm4
        +	shufps	xmm4,xmm2,140
        +	xorps	xmm2,xmm4
        +	shufps	xmm1,xmm1,170
        +	xorps	xmm2,xmm1
        +	ret
        +ALIGN	4
        +$L086bad_pointer:
        +	mov	eax,-1
        +	ret
        +ALIGN	4
        +$L089bad_keybits:
        +	mov	eax,-2
        +	ret
        +__aesni_set_encrypt_key ENDP
        +ALIGN	16
        +_aesni_set_encrypt_key	PROC PUBLIC
        +$L_aesni_set_encrypt_key_begin::
        +	mov	eax,DWORD PTR 4[esp]
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	call	__aesni_set_encrypt_key
        +	ret
        +_aesni_set_encrypt_key ENDP
        +ALIGN	16
        +_aesni_set_decrypt_key	PROC PUBLIC
        +$L_aesni_set_decrypt_key_begin::
        +	mov	eax,DWORD PTR 4[esp]
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	call	__aesni_set_encrypt_key
        +	mov	edx,DWORD PTR 12[esp]
        +	shl	ecx,4
        +	test	eax,eax
        +	jnz	$L100dec_key_ret
        +	lea	eax,DWORD PTR 16[ecx*1+edx]
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR [eax]
        +	movups	XMMWORD PTR [eax],xmm0
        +	movups	XMMWORD PTR [edx],xmm1
        +	lea	edx,DWORD PTR 16[edx]
        +	lea	eax,DWORD PTR [eax-16]
        +$L101dec_key_inverse:
        +	movups	xmm0,XMMWORD PTR [edx]
        +	movups	xmm1,XMMWORD PTR [eax]
        +DB	102,15,56,219,192
        +DB	102,15,56,219,201
        +	lea	edx,DWORD PTR 16[edx]
        +	lea	eax,DWORD PTR [eax-16]
        +	movups	XMMWORD PTR 16[eax],xmm0
        +	movups	XMMWORD PTR [edx-16],xmm1
        +	cmp	eax,edx
        +	ja	$L101dec_key_inverse
        +	movups	xmm0,XMMWORD PTR [edx]
        +DB	102,15,56,219,192
        +	movups	XMMWORD PTR [edx],xmm0
        +	xor	eax,eax
        +$L100dec_key_ret:
        +	ret
        +_aesni_set_decrypt_key ENDP
        +DB	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69
        +DB	83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83
        +DB	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +DB	115,108,46,111,114,103,62,0
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/bf/bf-686.asm b/vendor/openssl/asm/x86-win32-masm/bf/bf-686.asm
        new file mode 100644
        index 000000000..288317967
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/bf/bf-686.asm
        @@ -0,0 +1,907 @@
        +TITLE	bf-686.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_BF_encrypt	PROC PUBLIC
        +$L_BF_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the 2 words
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	ecx,DWORD PTR [eax]
        +	mov	edx,DWORD PTR 4[eax]
        +	;
        +
        +	; P pointer, s and enc flag
        +	mov	edi,DWORD PTR 24[esp]
        +	xor	eax,eax
        +	xor	ebx,ebx
        +	xor	ecx,DWORD PTR [edi]
        +	;
        +
        +	; Round 0
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 4[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 1
        +	ror	edx,16
        +	mov	esi,DWORD PTR 8[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 2
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 12[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 3
        +	ror	edx,16
        +	mov	esi,DWORD PTR 16[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 4
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 20[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 5
        +	ror	edx,16
        +	mov	esi,DWORD PTR 24[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 6
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 28[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 7
        +	ror	edx,16
        +	mov	esi,DWORD PTR 32[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 8
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 36[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 9
        +	ror	edx,16
        +	mov	esi,DWORD PTR 40[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 10
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 44[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 11
        +	ror	edx,16
        +	mov	esi,DWORD PTR 48[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 12
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 52[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 13
        +	ror	edx,16
        +	mov	esi,DWORD PTR 56[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 14
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 60[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 15
        +	ror	edx,16
        +	mov	esi,DWORD PTR 64[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 68[edi]
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	DWORD PTR [eax],edx
        +	mov	DWORD PTR 4[eax],ecx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_BF_encrypt ENDP
        +ALIGN	16
        +_BF_decrypt	PROC PUBLIC
        +$L_BF_decrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the 2 words
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	ecx,DWORD PTR [eax]
        +	mov	edx,DWORD PTR 4[eax]
        +	;
        +
        +	; P pointer, s and enc flag
        +	mov	edi,DWORD PTR 24[esp]
        +	xor	eax,eax
        +	xor	ebx,ebx
        +	xor	ecx,DWORD PTR 68[edi]
        +	;
        +
        +	; Round 16
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 64[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 15
        +	ror	edx,16
        +	mov	esi,DWORD PTR 60[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 14
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 56[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 13
        +	ror	edx,16
        +	mov	esi,DWORD PTR 52[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 12
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 48[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 11
        +	ror	edx,16
        +	mov	esi,DWORD PTR 44[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 10
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 40[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 9
        +	ror	edx,16
        +	mov	esi,DWORD PTR 36[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 8
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 32[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 7
        +	ror	edx,16
        +	mov	esi,DWORD PTR 28[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 6
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 24[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 5
        +	ror	edx,16
        +	mov	esi,DWORD PTR 20[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 4
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 16[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 3
        +	ror	edx,16
        +	mov	esi,DWORD PTR 12[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	;
        +
        +	; Round 2
        +	ror	ecx,16
        +	mov	esi,DWORD PTR 8[edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	ror	ecx,16
        +	xor	edx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,ch
        +	mov	bl,cl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	edx,esi
        +	;
        +
        +	; Round 1
        +	ror	edx,16
        +	mov	esi,DWORD PTR 4[edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	ror	edx,16
        +	xor	ecx,esi
        +	mov	esi,DWORD PTR 72[eax*4+edi]
        +	mov	ebp,DWORD PTR 1096[ebx*4+edi]
        +	mov	al,dh
        +	mov	bl,dl
        +	add	esi,ebp
        +	mov	eax,DWORD PTR 2120[eax*4+edi]
        +	xor	esi,eax
        +	mov	ebp,DWORD PTR 3144[ebx*4+edi]
        +	add	esi,ebp
        +	xor	eax,eax
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR [edi]
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	DWORD PTR [eax],edx
        +	mov	DWORD PTR 4[eax],ecx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_BF_decrypt ENDP
        +ALIGN	16
        +_BF_cbc_encrypt	PROC PUBLIC
        +$L_BF_cbc_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ebp,DWORD PTR 28[esp]
        +	; getting iv ptr from parameter 4
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR [ebx]
        +	mov	edi,DWORD PTR 4[ebx]
        +	push	edi
        +	push	esi
        +	push	edi
        +	push	esi
        +	mov	ebx,esp
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	; getting encrypt flag from parameter 5
        +	mov	ecx,DWORD PTR 56[esp]
        +	; get and push parameter 3
        +	mov	eax,DWORD PTR 48[esp]
        +	push	eax
        +	push	ebx
        +	cmp	ecx,0
        +	jz	$L000decrypt
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	jz	$L001encrypt_finish
        +$L002encrypt_loop:
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR 4[esi]
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_BF_encrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L002encrypt_loop
        +$L001encrypt_finish:
        +	mov	ebp,DWORD PTR 52[esp]
        +	and	ebp,7
        +	jz	$L003finish
        +	call	$L004PIC_point
        +$L004PIC_point:
        +	pop	edx
        +	lea	ecx,DWORD PTR ($L005cbc_enc_jmp_table-$L004PIC_point)[edx]
        +	mov	ebp,DWORD PTR [ebp*4+ecx]
        +	add	ebp,edx
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	jmp	ebp
        +$L006ej7:
        +	mov	dh,BYTE PTR 6[esi]
        +	shl	edx,8
        +$L007ej6:
        +	mov	dh,BYTE PTR 5[esi]
        +$L008ej5:
        +	mov	dl,BYTE PTR 4[esi]
        +$L009ej4:
        +	mov	ecx,DWORD PTR [esi]
        +	jmp	$L010ejend
        +$L011ej3:
        +	mov	ch,BYTE PTR 2[esi]
        +	shl	ecx,8
        +$L012ej2:
        +	mov	ch,BYTE PTR 1[esi]
        +$L013ej1:
        +	mov	cl,BYTE PTR [esi]
        +$L010ejend:
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_BF_encrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	jmp	$L003finish
        +$L000decrypt:
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	jz	$L014decrypt_finish
        +$L015decrypt_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_BF_decrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	ecx,DWORD PTR 16[esp]
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR [edi],ecx
        +	mov	DWORD PTR 4[edi],edx
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L015decrypt_loop
        +$L014decrypt_finish:
        +	mov	ebp,DWORD PTR 52[esp]
        +	and	ebp,7
        +	jz	$L003finish
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_BF_decrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	ecx,DWORD PTR 16[esp]
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +$L016dj7:
        +	ror	edx,16
        +	mov	BYTE PTR 6[edi],dl
        +	shr	edx,16
        +$L017dj6:
        +	mov	BYTE PTR 5[edi],dh
        +$L018dj5:
        +	mov	BYTE PTR 4[edi],dl
        +$L019dj4:
        +	mov	DWORD PTR [edi],ecx
        +	jmp	$L020djend
        +$L021dj3:
        +	ror	ecx,16
        +	mov	BYTE PTR 2[edi],cl
        +	shl	ecx,16
        +$L022dj2:
        +	mov	BYTE PTR 1[esi],ch
        +$L023dj1:
        +	mov	BYTE PTR [esi],cl
        +$L020djend:
        +	jmp	$L003finish
        +$L003finish:
        +	mov	ecx,DWORD PTR 60[esp]
        +	add	esp,24
        +	mov	DWORD PTR [ecx],eax
        +	mov	DWORD PTR 4[ecx],ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L005cbc_enc_jmp_table:
        +DD	0
        +DD	$L013ej1-$L004PIC_point
        +DD	$L012ej2-$L004PIC_point
        +DD	$L011ej3-$L004PIC_point
        +DD	$L009ej4-$L004PIC_point
        +DD	$L008ej5-$L004PIC_point
        +DD	$L007ej6-$L004PIC_point
        +DD	$L006ej7-$L004PIC_point
        +ALIGN	64
        +_BF_cbc_encrypt ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/bn/x86-mont.asm b/vendor/openssl/asm/x86-win32-masm/bn/x86-mont.asm
        new file mode 100644
        index 000000000..031be4e7e
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/bn/x86-mont.asm
        @@ -0,0 +1,348 @@
        +TITLE	../openssl/crypto/bn/asm/x86-mont.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_bn_mul_mont	PROC PUBLIC
        +$L_bn_mul_mont_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	xor	eax,eax
        +	mov	edi,DWORD PTR 40[esp]
        +	cmp	edi,4
        +	jl	$L000just_leave
        +	lea	esi,DWORD PTR 20[esp]
        +	lea	edx,DWORD PTR 24[esp]
        +	mov	ebp,esp
        +	add	edi,2
        +	neg	edi
        +	lea	esp,DWORD PTR [edi*4+esp-32]
        +	neg	edi
        +	mov	eax,esp
        +	sub	eax,edx
        +	and	eax,2047
        +	sub	esp,eax
        +	xor	edx,esp
        +	and	edx,2048
        +	xor	edx,2048
        +	sub	esp,edx
        +	and	esp,-64
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	esi,DWORD PTR 16[esi]
        +	mov	esi,DWORD PTR [esi]
        +	mov	DWORD PTR 4[esp],eax
        +	mov	DWORD PTR 8[esp],ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	mov	DWORD PTR 16[esp],edx
        +	mov	DWORD PTR 20[esp],esi
        +	lea	ebx,DWORD PTR [edi-3]
        +	mov	DWORD PTR 24[esp],ebp
        +	mov	esi,DWORD PTR 8[esp]
        +	lea	ebp,DWORD PTR 1[ebx]
        +	mov	edi,DWORD PTR 12[esp]
        +	xor	ecx,ecx
        +	mov	edx,esi
        +	and	ebp,1
        +	sub	edx,edi
        +	lea	eax,DWORD PTR 4[ebx*4+edi]
        +	or	ebp,edx
        +	mov	edi,DWORD PTR [edi]
        +	jz	$L001bn_sqr_mont
        +	mov	DWORD PTR 28[esp],eax
        +	mov	eax,DWORD PTR [esi]
        +	xor	edx,edx
        +ALIGN	16
        +$L002mull:
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,eax
        +	lea	ecx,DWORD PTR 1[ecx]
        +	adc	edx,0
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	cmp	ecx,ebx
        +	mov	DWORD PTR 28[ecx*4+esp],ebp
        +	jl	$L002mull
        +	mov	ebp,edx
        +	mul	edi
        +	mov	edi,DWORD PTR 20[esp]
        +	add	eax,ebp
        +	mov	esi,DWORD PTR 16[esp]
        +	adc	edx,0
        +	imul	edi,DWORD PTR 32[esp]
        +	mov	DWORD PTR 32[ebx*4+esp],eax
        +	xor	ecx,ecx
        +	mov	DWORD PTR 36[ebx*4+esp],edx
        +	mov	DWORD PTR 40[ebx*4+esp],ecx
        +	mov	eax,DWORD PTR [esi]
        +	mul	edi
        +	add	eax,DWORD PTR 32[esp]
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	edx,0
        +	inc	ecx
        +	jmp	$L0032ndmadd
        +ALIGN	16
        +$L0041stmadd:
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,DWORD PTR 32[ecx*4+esp]
        +	lea	ecx,DWORD PTR 1[ecx]
        +	adc	edx,0
        +	add	ebp,eax
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	adc	edx,0
        +	cmp	ecx,ebx
        +	mov	DWORD PTR 28[ecx*4+esp],ebp
        +	jl	$L0041stmadd
        +	mov	ebp,edx
        +	mul	edi
        +	add	eax,DWORD PTR 32[ebx*4+esp]
        +	mov	edi,DWORD PTR 20[esp]
        +	adc	edx,0
        +	mov	esi,DWORD PTR 16[esp]
        +	add	ebp,eax
        +	adc	edx,0
        +	imul	edi,DWORD PTR 32[esp]
        +	xor	ecx,ecx
        +	add	edx,DWORD PTR 36[ebx*4+esp]
        +	mov	DWORD PTR 32[ebx*4+esp],ebp
        +	adc	ecx,0
        +	mov	eax,DWORD PTR [esi]
        +	mov	DWORD PTR 36[ebx*4+esp],edx
        +	mov	DWORD PTR 40[ebx*4+esp],ecx
        +	mul	edi
        +	add	eax,DWORD PTR 32[esp]
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	edx,0
        +	mov	ecx,1
        +ALIGN	16
        +$L0032ndmadd:
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,DWORD PTR 32[ecx*4+esp]
        +	lea	ecx,DWORD PTR 1[ecx]
        +	adc	edx,0
        +	add	ebp,eax
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	adc	edx,0
        +	cmp	ecx,ebx
        +	mov	DWORD PTR 24[ecx*4+esp],ebp
        +	jl	$L0032ndmadd
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,DWORD PTR 32[ebx*4+esp]
        +	adc	edx,0
        +	add	ebp,eax
        +	adc	edx,0
        +	mov	DWORD PTR 28[ebx*4+esp],ebp
        +	xor	eax,eax
        +	mov	ecx,DWORD PTR 12[esp]
        +	add	edx,DWORD PTR 36[ebx*4+esp]
        +	adc	eax,DWORD PTR 40[ebx*4+esp]
        +	lea	ecx,DWORD PTR 4[ecx]
        +	mov	DWORD PTR 32[ebx*4+esp],edx
        +	cmp	ecx,DWORD PTR 28[esp]
        +	mov	DWORD PTR 36[ebx*4+esp],eax
        +	je	$L005common_tail
        +	mov	edi,DWORD PTR [ecx]
        +	mov	esi,DWORD PTR 8[esp]
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	mov	eax,DWORD PTR [esi]
        +	jmp	$L0041stmadd
        +ALIGN	16
        +$L001bn_sqr_mont:
        +	mov	DWORD PTR [esp],ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	mov	eax,edi
        +	mul	edi
        +	mov	DWORD PTR 32[esp],eax
        +	mov	ebx,edx
        +	shr	edx,1
        +	and	ebx,1
        +	inc	ecx
        +ALIGN	16
        +$L006sqr:
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	mov	ebp,edx
        +	mul	edi
        +	add	eax,ebp
        +	lea	ecx,DWORD PTR 1[ecx]
        +	adc	edx,0
        +	lea	ebp,DWORD PTR [eax*2+ebx]
        +	shr	eax,31
        +	cmp	ecx,DWORD PTR [esp]
        +	mov	ebx,eax
        +	mov	DWORD PTR 28[ecx*4+esp],ebp
        +	jl	$L006sqr
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	mov	ebp,edx
        +	mul	edi
        +	add	eax,ebp
        +	mov	edi,DWORD PTR 20[esp]
        +	adc	edx,0
        +	mov	esi,DWORD PTR 16[esp]
        +	lea	ebp,DWORD PTR [eax*2+ebx]
        +	imul	edi,DWORD PTR 32[esp]
        +	shr	eax,31
        +	mov	DWORD PTR 32[ecx*4+esp],ebp
        +	lea	ebp,DWORD PTR [edx*2+eax]
        +	mov	eax,DWORD PTR [esi]
        +	shr	edx,31
        +	mov	DWORD PTR 36[ecx*4+esp],ebp
        +	mov	DWORD PTR 40[ecx*4+esp],edx
        +	mul	edi
        +	add	eax,DWORD PTR 32[esp]
        +	mov	ebx,ecx
        +	adc	edx,0
        +	mov	eax,DWORD PTR 4[esi]
        +	mov	ecx,1
        +ALIGN	16
        +$L0073rdmadd:
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,DWORD PTR 32[ecx*4+esp]
        +	adc	edx,0
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 4[ecx*4+esi]
        +	adc	edx,0
        +	mov	DWORD PTR 28[ecx*4+esp],ebp
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,DWORD PTR 36[ecx*4+esp]
        +	lea	ecx,DWORD PTR 2[ecx]
        +	adc	edx,0
        +	add	ebp,eax
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	adc	edx,0
        +	cmp	ecx,ebx
        +	mov	DWORD PTR 24[ecx*4+esp],ebp
        +	jl	$L0073rdmadd
        +	mov	ebp,edx
        +	mul	edi
        +	add	ebp,DWORD PTR 32[ebx*4+esp]
        +	adc	edx,0
        +	add	ebp,eax
        +	adc	edx,0
        +	mov	DWORD PTR 28[ebx*4+esp],ebp
        +	mov	ecx,DWORD PTR 12[esp]
        +	xor	eax,eax
        +	mov	esi,DWORD PTR 8[esp]
        +	add	edx,DWORD PTR 36[ebx*4+esp]
        +	adc	eax,DWORD PTR 40[ebx*4+esp]
        +	mov	DWORD PTR 32[ebx*4+esp],edx
        +	cmp	ecx,ebx
        +	mov	DWORD PTR 36[ebx*4+esp],eax
        +	je	$L005common_tail
        +	mov	edi,DWORD PTR 4[ecx*4+esi]
        +	lea	ecx,DWORD PTR 1[ecx]
        +	mov	eax,edi
        +	mov	DWORD PTR 12[esp],ecx
        +	mul	edi
        +	add	eax,DWORD PTR 32[ecx*4+esp]
        +	adc	edx,0
        +	mov	DWORD PTR 32[ecx*4+esp],eax
        +	xor	ebp,ebp
        +	cmp	ecx,ebx
        +	lea	ecx,DWORD PTR 1[ecx]
        +	je	$L008sqrlast
        +	mov	ebx,edx
        +	shr	edx,1
        +	and	ebx,1
        +ALIGN	16
        +$L009sqradd:
        +	mov	eax,DWORD PTR [ecx*4+esi]
        +	mov	ebp,edx
        +	mul	edi
        +	add	eax,ebp
        +	lea	ebp,DWORD PTR [eax*1+eax]
        +	adc	edx,0
        +	shr	eax,31
        +	add	ebp,DWORD PTR 32[ecx*4+esp]
        +	lea	ecx,DWORD PTR 1[ecx]
        +	adc	eax,0
        +	add	ebp,ebx
        +	adc	eax,0
        +	cmp	ecx,DWORD PTR [esp]
        +	mov	DWORD PTR 28[ecx*4+esp],ebp
        +	mov	ebx,eax
        +	jle	$L009sqradd
        +	mov	ebp,edx
        +	add	edx,edx
        +	shr	ebp,31
        +	add	edx,ebx
        +	adc	ebp,0
        +$L008sqrlast:
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 16[esp]
        +	imul	edi,DWORD PTR 32[esp]
        +	add	edx,DWORD PTR 32[ecx*4+esp]
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebp,0
        +	mov	DWORD PTR 32[ecx*4+esp],edx
        +	mov	DWORD PTR 36[ecx*4+esp],ebp
        +	mul	edi
        +	add	eax,DWORD PTR 32[esp]
        +	lea	ebx,DWORD PTR [ecx-1]
        +	adc	edx,0
        +	mov	ecx,1
        +	mov	eax,DWORD PTR 4[esi]
        +	jmp	$L0073rdmadd
        +ALIGN	16
        +$L005common_tail:
        +	mov	ebp,DWORD PTR 16[esp]
        +	mov	edi,DWORD PTR 4[esp]
        +	lea	esi,DWORD PTR 32[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ecx,ebx
        +	xor	edx,edx
        +ALIGN	16
        +$L010sub:
        +	sbb	eax,DWORD PTR [edx*4+ebp]
        +	mov	DWORD PTR [edx*4+edi],eax
        +	dec	ecx
        +	mov	eax,DWORD PTR 4[edx*4+esi]
        +	lea	edx,DWORD PTR 1[edx]
        +	jge	$L010sub
        +	sbb	eax,0
        +	and	esi,eax
        +	not	eax
        +	mov	ebp,edi
        +	and	ebp,eax
        +	or	esi,ebp
        +ALIGN	16
        +$L011copy:
        +	mov	eax,DWORD PTR [ebx*4+esi]
        +	mov	DWORD PTR [ebx*4+edi],eax
        +	mov	DWORD PTR 32[ebx*4+esp],ecx
        +	dec	ebx
        +	jge	$L011copy
        +	mov	esp,DWORD PTR 24[esp]
        +	mov	eax,1
        +$L000just_leave:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_mul_mont ENDP
        +DB	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
        +DB	112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56
        +DB	54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121
        +DB	32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46
        +DB	111,114,103,62,0
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/bn/x86.asm b/vendor/openssl/asm/x86-win32-masm/bn/x86.asm
        new file mode 100644
        index 000000000..2e7a0d4aa
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/bn/x86.asm
        @@ -0,0 +1,2116 @@
        +TITLE	../openssl/crypto/bn/asm/x86.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_bn_mul_add_words	PROC PUBLIC
        +$L_bn_mul_add_words_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	xor	esi,esi
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	ecx,DWORD PTR 28[esp]
        +	mov	ebx,DWORD PTR 24[esp]
        +	and	ecx,4294967288
        +	mov	ebp,DWORD PTR 32[esp]
        +	push	ecx
        +	jz	$L000maw_finish
        +$L001maw_loop:
        +	mov	DWORD PTR [esp],ecx
        +	; Round 0
        +	mov	eax,DWORD PTR [ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR [edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR [edi],eax
        +	mov	esi,edx
        +	; Round 4
        +	mov	eax,DWORD PTR 4[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 4[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 4[edi],eax
        +	mov	esi,edx
        +	; Round 8
        +	mov	eax,DWORD PTR 8[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 8[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 8[edi],eax
        +	mov	esi,edx
        +	; Round 12
        +	mov	eax,DWORD PTR 12[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 12[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 12[edi],eax
        +	mov	esi,edx
        +	; Round 16
        +	mov	eax,DWORD PTR 16[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 16[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 16[edi],eax
        +	mov	esi,edx
        +	; Round 20
        +	mov	eax,DWORD PTR 20[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 20[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 20[edi],eax
        +	mov	esi,edx
        +	; Round 24
        +	mov	eax,DWORD PTR 24[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 24[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 24[edi],eax
        +	mov	esi,edx
        +	; Round 28
        +	mov	eax,DWORD PTR 28[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 28[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 28[edi],eax
        +	mov	esi,edx
        +	;
        +
        +	mov	ecx,DWORD PTR [esp]
        +	add	ebx,32
        +	add	edi,32
        +	sub	ecx,8
        +	jnz	$L001maw_loop
        +$L000maw_finish:
        +	mov	ecx,DWORD PTR 32[esp]
        +	and	ecx,7
        +	jnz	$L002maw_finish2
        +	jmp	$L003maw_end
        +$L002maw_finish2:
        +	; Tail Round 0
        +	mov	eax,DWORD PTR [ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR [edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	dec	ecx
        +	mov	DWORD PTR [edi],eax
        +	mov	esi,edx
        +	jz	$L003maw_end
        +	; Tail Round 1
        +	mov	eax,DWORD PTR 4[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 4[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	dec	ecx
        +	mov	DWORD PTR 4[edi],eax
        +	mov	esi,edx
        +	jz	$L003maw_end
        +	; Tail Round 2
        +	mov	eax,DWORD PTR 8[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 8[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	dec	ecx
        +	mov	DWORD PTR 8[edi],eax
        +	mov	esi,edx
        +	jz	$L003maw_end
        +	; Tail Round 3
        +	mov	eax,DWORD PTR 12[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 12[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	dec	ecx
        +	mov	DWORD PTR 12[edi],eax
        +	mov	esi,edx
        +	jz	$L003maw_end
        +	; Tail Round 4
        +	mov	eax,DWORD PTR 16[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 16[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	dec	ecx
        +	mov	DWORD PTR 16[edi],eax
        +	mov	esi,edx
        +	jz	$L003maw_end
        +	; Tail Round 5
        +	mov	eax,DWORD PTR 20[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 20[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	dec	ecx
        +	mov	DWORD PTR 20[edi],eax
        +	mov	esi,edx
        +	jz	$L003maw_end
        +	; Tail Round 6
        +	mov	eax,DWORD PTR 24[ebx]
        +	mul	ebp
        +	add	eax,esi
        +	mov	esi,DWORD PTR 24[edi]
        +	adc	edx,0
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 24[edi],eax
        +	mov	esi,edx
        +$L003maw_end:
        +	mov	eax,esi
        +	pop	ecx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_mul_add_words ENDP
        +ALIGN	16
        +_bn_mul_words	PROC PUBLIC
        +$L_bn_mul_words_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	xor	esi,esi
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	ebx,DWORD PTR 24[esp]
        +	mov	ebp,DWORD PTR 28[esp]
        +	mov	ecx,DWORD PTR 32[esp]
        +	and	ebp,4294967288
        +	jz	$L004mw_finish
        +$L005mw_loop:
        +	; Round 0
        +	mov	eax,DWORD PTR [ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR [edi],eax
        +	mov	esi,edx
        +	; Round 4
        +	mov	eax,DWORD PTR 4[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 4[edi],eax
        +	mov	esi,edx
        +	; Round 8
        +	mov	eax,DWORD PTR 8[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 8[edi],eax
        +	mov	esi,edx
        +	; Round 12
        +	mov	eax,DWORD PTR 12[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 12[edi],eax
        +	mov	esi,edx
        +	; Round 16
        +	mov	eax,DWORD PTR 16[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 16[edi],eax
        +	mov	esi,edx
        +	; Round 20
        +	mov	eax,DWORD PTR 20[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 20[edi],eax
        +	mov	esi,edx
        +	; Round 24
        +	mov	eax,DWORD PTR 24[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 24[edi],eax
        +	mov	esi,edx
        +	; Round 28
        +	mov	eax,DWORD PTR 28[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 28[edi],eax
        +	mov	esi,edx
        +	;
        +
        +	add	ebx,32
        +	add	edi,32
        +	sub	ebp,8
        +	jz	$L004mw_finish
        +	jmp	$L005mw_loop
        +$L004mw_finish:
        +	mov	ebp,DWORD PTR 28[esp]
        +	and	ebp,7
        +	jnz	$L006mw_finish2
        +	jmp	$L007mw_end
        +$L006mw_finish2:
        +	; Tail Round 0
        +	mov	eax,DWORD PTR [ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR [edi],eax
        +	mov	esi,edx
        +	dec	ebp
        +	jz	$L007mw_end
        +	; Tail Round 1
        +	mov	eax,DWORD PTR 4[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 4[edi],eax
        +	mov	esi,edx
        +	dec	ebp
        +	jz	$L007mw_end
        +	; Tail Round 2
        +	mov	eax,DWORD PTR 8[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 8[edi],eax
        +	mov	esi,edx
        +	dec	ebp
        +	jz	$L007mw_end
        +	; Tail Round 3
        +	mov	eax,DWORD PTR 12[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 12[edi],eax
        +	mov	esi,edx
        +	dec	ebp
        +	jz	$L007mw_end
        +	; Tail Round 4
        +	mov	eax,DWORD PTR 16[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 16[edi],eax
        +	mov	esi,edx
        +	dec	ebp
        +	jz	$L007mw_end
        +	; Tail Round 5
        +	mov	eax,DWORD PTR 20[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 20[edi],eax
        +	mov	esi,edx
        +	dec	ebp
        +	jz	$L007mw_end
        +	; Tail Round 6
        +	mov	eax,DWORD PTR 24[ebx]
        +	mul	ecx
        +	add	eax,esi
        +	adc	edx,0
        +	mov	DWORD PTR 24[edi],eax
        +	mov	esi,edx
        +$L007mw_end:
        +	mov	eax,esi
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_mul_words ENDP
        +ALIGN	16
        +_bn_sqr_words	PROC PUBLIC
        +$L_bn_sqr_words_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	ebx,DWORD PTR 28[esp]
        +	and	ebx,4294967288
        +	jz	$L008sw_finish
        +$L009sw_loop:
        +	; Round 0
        +	mov	eax,DWORD PTR [edi]
        +	mul	eax
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],edx
        +	; Round 4
        +	mov	eax,DWORD PTR 4[edi]
        +	mul	eax
        +	mov	DWORD PTR 8[esi],eax
        +	mov	DWORD PTR 12[esi],edx
        +	; Round 8
        +	mov	eax,DWORD PTR 8[edi]
        +	mul	eax
        +	mov	DWORD PTR 16[esi],eax
        +	mov	DWORD PTR 20[esi],edx
        +	; Round 12
        +	mov	eax,DWORD PTR 12[edi]
        +	mul	eax
        +	mov	DWORD PTR 24[esi],eax
        +	mov	DWORD PTR 28[esi],edx
        +	; Round 16
        +	mov	eax,DWORD PTR 16[edi]
        +	mul	eax
        +	mov	DWORD PTR 32[esi],eax
        +	mov	DWORD PTR 36[esi],edx
        +	; Round 20
        +	mov	eax,DWORD PTR 20[edi]
        +	mul	eax
        +	mov	DWORD PTR 40[esi],eax
        +	mov	DWORD PTR 44[esi],edx
        +	; Round 24
        +	mov	eax,DWORD PTR 24[edi]
        +	mul	eax
        +	mov	DWORD PTR 48[esi],eax
        +	mov	DWORD PTR 52[esi],edx
        +	; Round 28
        +	mov	eax,DWORD PTR 28[edi]
        +	mul	eax
        +	mov	DWORD PTR 56[esi],eax
        +	mov	DWORD PTR 60[esi],edx
        +	;
        +
        +	add	edi,32
        +	add	esi,64
        +	sub	ebx,8
        +	jnz	$L009sw_loop
        +$L008sw_finish:
        +	mov	ebx,DWORD PTR 28[esp]
        +	and	ebx,7
        +	jz	$L010sw_end
        +	; Tail Round 0
        +	mov	eax,DWORD PTR [edi]
        +	mul	eax
        +	mov	DWORD PTR [esi],eax
        +	dec	ebx
        +	mov	DWORD PTR 4[esi],edx
        +	jz	$L010sw_end
        +	; Tail Round 1
        +	mov	eax,DWORD PTR 4[edi]
        +	mul	eax
        +	mov	DWORD PTR 8[esi],eax
        +	dec	ebx
        +	mov	DWORD PTR 12[esi],edx
        +	jz	$L010sw_end
        +	; Tail Round 2
        +	mov	eax,DWORD PTR 8[edi]
        +	mul	eax
        +	mov	DWORD PTR 16[esi],eax
        +	dec	ebx
        +	mov	DWORD PTR 20[esi],edx
        +	jz	$L010sw_end
        +	; Tail Round 3
        +	mov	eax,DWORD PTR 12[edi]
        +	mul	eax
        +	mov	DWORD PTR 24[esi],eax
        +	dec	ebx
        +	mov	DWORD PTR 28[esi],edx
        +	jz	$L010sw_end
        +	; Tail Round 4
        +	mov	eax,DWORD PTR 16[edi]
        +	mul	eax
        +	mov	DWORD PTR 32[esi],eax
        +	dec	ebx
        +	mov	DWORD PTR 36[esi],edx
        +	jz	$L010sw_end
        +	; Tail Round 5
        +	mov	eax,DWORD PTR 20[edi]
        +	mul	eax
        +	mov	DWORD PTR 40[esi],eax
        +	dec	ebx
        +	mov	DWORD PTR 44[esi],edx
        +	jz	$L010sw_end
        +	; Tail Round 6
        +	mov	eax,DWORD PTR 24[edi]
        +	mul	eax
        +	mov	DWORD PTR 48[esi],eax
        +	mov	DWORD PTR 52[esi],edx
        +$L010sw_end:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_sqr_words ENDP
        +ALIGN	16
        +_bn_div_words	PROC PUBLIC
        +$L_bn_div_words_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	edx,DWORD PTR 20[esp]
        +	mov	eax,DWORD PTR 24[esp]
        +	mov	ebx,DWORD PTR 28[esp]
        +	div	ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_div_words ENDP
        +ALIGN	16
        +_bn_add_words	PROC PUBLIC
        +$L_bn_add_words_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	mov	ebx,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	ebp,DWORD PTR 32[esp]
        +	xor	eax,eax
        +	and	ebp,4294967288
        +	jz	$L011aw_finish
        +$L012aw_loop:
        +	; Round 0
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR [edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR [ebx],ecx
        +	; Round 1
        +	mov	ecx,DWORD PTR 4[esi]
        +	mov	edx,DWORD PTR 4[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 4[ebx],ecx
        +	; Round 2
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 8[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 8[ebx],ecx
        +	; Round 3
        +	mov	ecx,DWORD PTR 12[esi]
        +	mov	edx,DWORD PTR 12[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 12[ebx],ecx
        +	; Round 4
        +	mov	ecx,DWORD PTR 16[esi]
        +	mov	edx,DWORD PTR 16[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 16[ebx],ecx
        +	; Round 5
        +	mov	ecx,DWORD PTR 20[esi]
        +	mov	edx,DWORD PTR 20[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 20[ebx],ecx
        +	; Round 6
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 24[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 24[ebx],ecx
        +	; Round 7
        +	mov	ecx,DWORD PTR 28[esi]
        +	mov	edx,DWORD PTR 28[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 28[ebx],ecx
        +	;
        +
        +	add	esi,32
        +	add	edi,32
        +	add	ebx,32
        +	sub	ebp,8
        +	jnz	$L012aw_loop
        +$L011aw_finish:
        +	mov	ebp,DWORD PTR 32[esp]
        +	and	ebp,7
        +	jz	$L013aw_end
        +	; Tail Round 0
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR [edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR [ebx],ecx
        +	jz	$L013aw_end
        +	; Tail Round 1
        +	mov	ecx,DWORD PTR 4[esi]
        +	mov	edx,DWORD PTR 4[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 4[ebx],ecx
        +	jz	$L013aw_end
        +	; Tail Round 2
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 8[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 8[ebx],ecx
        +	jz	$L013aw_end
        +	; Tail Round 3
        +	mov	ecx,DWORD PTR 12[esi]
        +	mov	edx,DWORD PTR 12[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 12[ebx],ecx
        +	jz	$L013aw_end
        +	; Tail Round 4
        +	mov	ecx,DWORD PTR 16[esi]
        +	mov	edx,DWORD PTR 16[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 16[ebx],ecx
        +	jz	$L013aw_end
        +	; Tail Round 5
        +	mov	ecx,DWORD PTR 20[esi]
        +	mov	edx,DWORD PTR 20[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 20[ebx],ecx
        +	jz	$L013aw_end
        +	; Tail Round 6
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 24[edi]
        +	add	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	add	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 24[ebx],ecx
        +$L013aw_end:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_add_words ENDP
        +ALIGN	16
        +_bn_sub_words	PROC PUBLIC
        +$L_bn_sub_words_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	mov	ebx,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	ebp,DWORD PTR 32[esp]
        +	xor	eax,eax
        +	and	ebp,4294967288
        +	jz	$L014aw_finish
        +$L015aw_loop:
        +	; Round 0
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR [edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR [ebx],ecx
        +	; Round 1
        +	mov	ecx,DWORD PTR 4[esi]
        +	mov	edx,DWORD PTR 4[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 4[ebx],ecx
        +	; Round 2
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 8[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 8[ebx],ecx
        +	; Round 3
        +	mov	ecx,DWORD PTR 12[esi]
        +	mov	edx,DWORD PTR 12[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 12[ebx],ecx
        +	; Round 4
        +	mov	ecx,DWORD PTR 16[esi]
        +	mov	edx,DWORD PTR 16[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 16[ebx],ecx
        +	; Round 5
        +	mov	ecx,DWORD PTR 20[esi]
        +	mov	edx,DWORD PTR 20[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 20[ebx],ecx
        +	; Round 6
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 24[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 24[ebx],ecx
        +	; Round 7
        +	mov	ecx,DWORD PTR 28[esi]
        +	mov	edx,DWORD PTR 28[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 28[ebx],ecx
        +	;
        +
        +	add	esi,32
        +	add	edi,32
        +	add	ebx,32
        +	sub	ebp,8
        +	jnz	$L015aw_loop
        +$L014aw_finish:
        +	mov	ebp,DWORD PTR 32[esp]
        +	and	ebp,7
        +	jz	$L016aw_end
        +	; Tail Round 0
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR [edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR [ebx],ecx
        +	jz	$L016aw_end
        +	; Tail Round 1
        +	mov	ecx,DWORD PTR 4[esi]
        +	mov	edx,DWORD PTR 4[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 4[ebx],ecx
        +	jz	$L016aw_end
        +	; Tail Round 2
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 8[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 8[ebx],ecx
        +	jz	$L016aw_end
        +	; Tail Round 3
        +	mov	ecx,DWORD PTR 12[esi]
        +	mov	edx,DWORD PTR 12[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 12[ebx],ecx
        +	jz	$L016aw_end
        +	; Tail Round 4
        +	mov	ecx,DWORD PTR 16[esi]
        +	mov	edx,DWORD PTR 16[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 16[ebx],ecx
        +	jz	$L016aw_end
        +	; Tail Round 5
        +	mov	ecx,DWORD PTR 20[esi]
        +	mov	edx,DWORD PTR 20[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	dec	ebp
        +	mov	DWORD PTR 20[ebx],ecx
        +	jz	$L016aw_end
        +	; Tail Round 6
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 24[edi]
        +	sub	ecx,eax
        +	mov	eax,0
        +	adc	eax,eax
        +	sub	ecx,edx
        +	adc	eax,0
        +	mov	DWORD PTR 24[ebx],ecx
        +$L016aw_end:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_bn_sub_words ENDP
        +ALIGN	16
        +_bn_mul_comba8	PROC PUBLIC
        +$L_bn_mul_comba8_begin::
        +	push	esi
        +	mov	esi,DWORD PTR 12[esp]
        +	push	edi
        +	mov	edi,DWORD PTR 20[esp]
        +	push	ebp
        +	push	ebx
        +	xor	ebx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	xor	ecx,ecx
        +	mov	edx,DWORD PTR [edi]
        +	; ################## Calculate word 0
        +	xor	ebp,ebp
        +	; mul a[0]*b[0]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebp,0
        +	mov	DWORD PTR [eax],ebx
        +	mov	eax,DWORD PTR 4[esi]
        +	; saved r[0]
        +	; ################## Calculate word 1
        +	xor	ebx,ebx
        +	; mul a[1]*b[0]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebx,0
        +	; mul a[0]*b[1]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 4[eax],ecx
        +	mov	eax,DWORD PTR 8[esi]
        +	; saved r[1]
        +	; ################## Calculate word 2
        +	xor	ecx,ecx
        +	; mul a[2]*b[0]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ecx,0
        +	; mul a[1]*b[1]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ecx,0
        +	; mul a[0]*b[2]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ecx,0
        +	mov	DWORD PTR 8[eax],ebp
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[2]
        +	; ################## Calculate word 3
        +	xor	ebp,ebp
        +	; mul a[3]*b[0]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebp,0
        +	; mul a[2]*b[1]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebp,0
        +	; mul a[1]*b[2]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebp,0
        +	; mul a[0]*b[3]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebp,0
        +	mov	DWORD PTR 12[eax],ebx
        +	mov	eax,DWORD PTR 16[esi]
        +	; saved r[3]
        +	; ################## Calculate word 4
        +	xor	ebx,ebx
        +	; mul a[4]*b[0]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebx,0
        +	; mul a[3]*b[1]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebx,0
        +	; mul a[2]*b[2]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebx,0
        +	; mul a[1]*b[3]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ebx,0
        +	; mul a[0]*b[4]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 16[eax],ecx
        +	mov	eax,DWORD PTR 20[esi]
        +	; saved r[4]
        +	; ################## Calculate word 5
        +	xor	ecx,ecx
        +	; mul a[5]*b[0]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ecx,0
        +	; mul a[4]*b[1]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ecx,0
        +	; mul a[3]*b[2]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ecx,0
        +	; mul a[2]*b[3]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ecx,0
        +	; mul a[1]*b[4]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ecx,0
        +	; mul a[0]*b[5]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ecx,0
        +	mov	DWORD PTR 20[eax],ebp
        +	mov	eax,DWORD PTR 24[esi]
        +	; saved r[5]
        +	; ################## Calculate word 6
        +	xor	ebp,ebp
        +	; mul a[6]*b[0]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebp,0
        +	; mul a[5]*b[1]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebp,0
        +	; mul a[4]*b[2]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebp,0
        +	; mul a[3]*b[3]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ebp,0
        +	; mul a[2]*b[4]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ebp,0
        +	; mul a[1]*b[5]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ebp,0
        +	; mul a[0]*b[6]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebp,0
        +	mov	DWORD PTR 24[eax],ebx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[6]
        +	; ################## Calculate word 7
        +	xor	ebx,ebx
        +	; mul a[7]*b[0]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebx,0
        +	; mul a[6]*b[1]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebx,0
        +	; mul a[5]*b[2]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebx,0
        +	; mul a[4]*b[3]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ebx,0
        +	; mul a[3]*b[4]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ebx,0
        +	; mul a[2]*b[5]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ebx,0
        +	; mul a[1]*b[6]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ebx,0
        +	; mul a[0]*b[7]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 28[eax],ecx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[7]
        +	; ################## Calculate word 8
        +	xor	ecx,ecx
        +	; mul a[7]*b[1]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ecx,0
        +	; mul a[6]*b[2]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ecx,0
        +	; mul a[5]*b[3]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ecx,0
        +	; mul a[4]*b[4]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ecx,0
        +	; mul a[3]*b[5]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ecx,0
        +	; mul a[2]*b[6]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ecx,0
        +	; mul a[1]*b[7]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ecx,0
        +	mov	DWORD PTR 32[eax],ebp
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[8]
        +	; ################## Calculate word 9
        +	xor	ebp,ebp
        +	; mul a[7]*b[2]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebp,0
        +	; mul a[6]*b[3]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ebp,0
        +	; mul a[5]*b[4]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ebp,0
        +	; mul a[4]*b[5]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ebp,0
        +	; mul a[3]*b[6]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ebp,0
        +	; mul a[2]*b[7]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebp,0
        +	mov	DWORD PTR 36[eax],ebx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[9]
        +	; ################## Calculate word 10
        +	xor	ebx,ebx
        +	; mul a[7]*b[3]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ebx,0
        +	; mul a[6]*b[4]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ebx,0
        +	; mul a[5]*b[5]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ebx,0
        +	; mul a[4]*b[6]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ebx,0
        +	; mul a[3]*b[7]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 16[edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 40[eax],ecx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[10]
        +	; ################## Calculate word 11
        +	xor	ecx,ecx
        +	; mul a[7]*b[4]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ecx,0
        +	; mul a[6]*b[5]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ecx,0
        +	; mul a[5]*b[6]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ecx,0
        +	; mul a[4]*b[7]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 20[edi]
        +	adc	ecx,0
        +	mov	DWORD PTR 44[eax],ebp
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[11]
        +	; ################## Calculate word 12
        +	xor	ebp,ebp
        +	; mul a[7]*b[5]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ebp,0
        +	; mul a[6]*b[6]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ebp,0
        +	; mul a[5]*b[7]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 24[edi]
        +	adc	ebp,0
        +	mov	DWORD PTR 48[eax],ebx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[12]
        +	; ################## Calculate word 13
        +	xor	ebx,ebx
        +	; mul a[7]*b[6]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ebx,0
        +	; mul a[6]*b[7]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 28[edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 52[eax],ecx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[13]
        +	; ################## Calculate word 14
        +	xor	ecx,ecx
        +	; mul a[7]*b[7]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	adc	ecx,0
        +	mov	DWORD PTR 56[eax],ebp
        +	; saved r[14]
        +	; save r[15]
        +	mov	DWORD PTR 60[eax],ebx
        +	pop	ebx
        +	pop	ebp
        +	pop	edi
        +	pop	esi
        +	ret
        +_bn_mul_comba8 ENDP
        +ALIGN	16
        +_bn_mul_comba4	PROC PUBLIC
        +$L_bn_mul_comba4_begin::
        +	push	esi
        +	mov	esi,DWORD PTR 12[esp]
        +	push	edi
        +	mov	edi,DWORD PTR 20[esp]
        +	push	ebp
        +	push	ebx
        +	xor	ebx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	xor	ecx,ecx
        +	mov	edx,DWORD PTR [edi]
        +	; ################## Calculate word 0
        +	xor	ebp,ebp
        +	; mul a[0]*b[0]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebp,0
        +	mov	DWORD PTR [eax],ebx
        +	mov	eax,DWORD PTR 4[esi]
        +	; saved r[0]
        +	; ################## Calculate word 1
        +	xor	ebx,ebx
        +	; mul a[1]*b[0]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebx,0
        +	; mul a[0]*b[1]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 4[eax],ecx
        +	mov	eax,DWORD PTR 8[esi]
        +	; saved r[1]
        +	; ################## Calculate word 2
        +	xor	ecx,ecx
        +	; mul a[2]*b[0]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ecx,0
        +	; mul a[1]*b[1]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ecx,0
        +	; mul a[0]*b[2]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR [edi]
        +	adc	ecx,0
        +	mov	DWORD PTR 8[eax],ebp
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[2]
        +	; ################## Calculate word 3
        +	xor	ebp,ebp
        +	; mul a[3]*b[0]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebp,0
        +	; mul a[2]*b[1]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebp,0
        +	; mul a[1]*b[2]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR [esi]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebp,0
        +	; mul a[0]*b[3]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 4[edi]
        +	adc	ebp,0
        +	mov	DWORD PTR 12[eax],ebx
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[3]
        +	; ################## Calculate word 4
        +	xor	ebx,ebx
        +	; mul a[3]*b[1]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebx,0
        +	; mul a[2]*b[2]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ebx,0
        +	; mul a[1]*b[3]
        +	mul	edx
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 8[edi]
        +	adc	ebx,0
        +	mov	DWORD PTR 16[eax],ecx
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[4]
        +	; ################## Calculate word 5
        +	xor	ecx,ecx
        +	; mul a[3]*b[2]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ecx,0
        +	; mul a[2]*b[3]
        +	mul	edx
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 12[edi]
        +	adc	ecx,0
        +	mov	DWORD PTR 20[eax],ebp
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[5]
        +	; ################## Calculate word 6
        +	xor	ebp,ebp
        +	; mul a[3]*b[3]
        +	mul	edx
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	adc	ecx,edx
        +	adc	ebp,0
        +	mov	DWORD PTR 24[eax],ebx
        +	; saved r[6]
        +	; save r[7]
        +	mov	DWORD PTR 28[eax],ecx
        +	pop	ebx
        +	pop	ebp
        +	pop	edi
        +	pop	esi
        +	ret
        +_bn_mul_comba4 ENDP
        +ALIGN	16
        +_bn_sqr_comba8	PROC PUBLIC
        +$L_bn_sqr_comba8_begin::
        +	push	esi
        +	push	edi
        +	push	ebp
        +	push	ebx
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	xor	ebx,ebx
        +	xor	ecx,ecx
        +	mov	eax,DWORD PTR [esi]
        +	; ############### Calculate word 0
        +	xor	ebp,ebp
        +	; sqr a[0]*a[0]
        +	mul	eax
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [esi]
        +	adc	ebp,0
        +	mov	DWORD PTR [edi],ebx
        +	mov	eax,DWORD PTR 4[esi]
        +	; saved r[0]
        +	; ############### Calculate word 1
        +	xor	ebx,ebx
        +	; sqr a[1]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 4[edi],ecx
        +	mov	edx,DWORD PTR [esi]
        +	; saved r[1]
        +	; ############### Calculate word 2
        +	xor	ecx,ecx
        +	; sqr a[2]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ecx,0
        +	; sqr a[1]*a[1]
        +	mul	eax
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR [esi]
        +	adc	ecx,0
        +	mov	DWORD PTR 8[edi],ebp
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[2]
        +	; ############### Calculate word 3
        +	xor	ebp,ebp
        +	; sqr a[3]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebp,0
        +	mov	edx,DWORD PTR 4[esi]
        +	; sqr a[2]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebp,0
        +	mov	DWORD PTR 12[edi],ebx
        +	mov	edx,DWORD PTR [esi]
        +	; saved r[3]
        +	; ############### Calculate word 4
        +	xor	ebx,ebx
        +	; sqr a[4]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebx,0
        +	mov	edx,DWORD PTR 4[esi]
        +	; sqr a[3]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,0
        +	; sqr a[2]*a[2]
        +	mul	eax
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR [esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 16[edi],ecx
        +	mov	eax,DWORD PTR 20[esi]
        +	; saved r[4]
        +	; ############### Calculate word 5
        +	xor	ecx,ecx
        +	; sqr a[5]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ecx,0
        +	mov	edx,DWORD PTR 4[esi]
        +	; sqr a[4]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ecx,0
        +	mov	edx,DWORD PTR 8[esi]
        +	; sqr a[3]*a[2]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ecx,0
        +	mov	DWORD PTR 20[edi],ebp
        +	mov	edx,DWORD PTR [esi]
        +	; saved r[5]
        +	; ############### Calculate word 6
        +	xor	ebp,ebp
        +	; sqr a[6]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebp,0
        +	mov	edx,DWORD PTR 4[esi]
        +	; sqr a[5]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebp,0
        +	mov	edx,DWORD PTR 8[esi]
        +	; sqr a[4]*a[2]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebp,0
        +	; sqr a[3]*a[3]
        +	mul	eax
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [esi]
        +	adc	ebp,0
        +	mov	DWORD PTR 24[edi],ebx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[6]
        +	; ############### Calculate word 7
        +	xor	ebx,ebx
        +	; sqr a[7]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebx,0
        +	mov	edx,DWORD PTR 4[esi]
        +	; sqr a[6]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebx,0
        +	mov	edx,DWORD PTR 8[esi]
        +	; sqr a[5]*a[2]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ebx,0
        +	mov	edx,DWORD PTR 12[esi]
        +	; sqr a[4]*a[3]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 28[esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 28[edi],ecx
        +	mov	edx,DWORD PTR 4[esi]
        +	; saved r[7]
        +	; ############### Calculate word 8
        +	xor	ecx,ecx
        +	; sqr a[7]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ecx,0
        +	mov	edx,DWORD PTR 8[esi]
        +	; sqr a[6]*a[2]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ecx,0
        +	mov	edx,DWORD PTR 12[esi]
        +	; sqr a[5]*a[3]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 16[esi]
        +	adc	ecx,0
        +	; sqr a[4]*a[4]
        +	mul	eax
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR 8[esi]
        +	adc	ecx,0
        +	mov	DWORD PTR 32[edi],ebp
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[8]
        +	; ############### Calculate word 9
        +	xor	ebp,ebp
        +	; sqr a[7]*a[2]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebp,0
        +	mov	edx,DWORD PTR 12[esi]
        +	; sqr a[6]*a[3]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebp,0
        +	mov	edx,DWORD PTR 16[esi]
        +	; sqr a[5]*a[4]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 28[esi]
        +	adc	ebp,0
        +	mov	DWORD PTR 36[edi],ebx
        +	mov	edx,DWORD PTR 12[esi]
        +	; saved r[9]
        +	; ############### Calculate word 10
        +	xor	ebx,ebx
        +	; sqr a[7]*a[3]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebx,0
        +	mov	edx,DWORD PTR 16[esi]
        +	; sqr a[6]*a[4]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 20[esi]
        +	adc	ebx,0
        +	; sqr a[5]*a[5]
        +	mul	eax
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 16[esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 40[edi],ecx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[10]
        +	; ############### Calculate word 11
        +	xor	ecx,ecx
        +	; sqr a[7]*a[4]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ecx,0
        +	mov	edx,DWORD PTR 20[esi]
        +	; sqr a[6]*a[5]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 28[esi]
        +	adc	ecx,0
        +	mov	DWORD PTR 44[edi],ebp
        +	mov	edx,DWORD PTR 20[esi]
        +	; saved r[11]
        +	; ############### Calculate word 12
        +	xor	ebp,ebp
        +	; sqr a[7]*a[5]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 24[esi]
        +	adc	ebp,0
        +	; sqr a[6]*a[6]
        +	mul	eax
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR 24[esi]
        +	adc	ebp,0
        +	mov	DWORD PTR 48[edi],ebx
        +	mov	eax,DWORD PTR 28[esi]
        +	; saved r[12]
        +	; ############### Calculate word 13
        +	xor	ebx,ebx
        +	; sqr a[7]*a[6]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 28[esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 52[edi],ecx
        +	; saved r[13]
        +	; ############### Calculate word 14
        +	xor	ecx,ecx
        +	; sqr a[7]*a[7]
        +	mul	eax
        +	add	ebp,eax
        +	adc	ebx,edx
        +	adc	ecx,0
        +	mov	DWORD PTR 56[edi],ebp
        +	; saved r[14]
        +	mov	DWORD PTR 60[edi],ebx
        +	pop	ebx
        +	pop	ebp
        +	pop	edi
        +	pop	esi
        +	ret
        +_bn_sqr_comba8 ENDP
        +ALIGN	16
        +_bn_sqr_comba4	PROC PUBLIC
        +$L_bn_sqr_comba4_begin::
        +	push	esi
        +	push	edi
        +	push	ebp
        +	push	ebx
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	xor	ebx,ebx
        +	xor	ecx,ecx
        +	mov	eax,DWORD PTR [esi]
        +	; ############### Calculate word 0
        +	xor	ebp,ebp
        +	; sqr a[0]*a[0]
        +	mul	eax
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	edx,DWORD PTR [esi]
        +	adc	ebp,0
        +	mov	DWORD PTR [edi],ebx
        +	mov	eax,DWORD PTR 4[esi]
        +	; saved r[0]
        +	; ############### Calculate word 1
        +	xor	ebx,ebx
        +	; sqr a[1]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 4[edi],ecx
        +	mov	edx,DWORD PTR [esi]
        +	; saved r[1]
        +	; ############### Calculate word 2
        +	xor	ecx,ecx
        +	; sqr a[2]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 4[esi]
        +	adc	ecx,0
        +	; sqr a[1]*a[1]
        +	mul	eax
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	edx,DWORD PTR [esi]
        +	adc	ecx,0
        +	mov	DWORD PTR 8[edi],ebp
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[2]
        +	; ############### Calculate word 3
        +	xor	ebp,ebp
        +	; sqr a[3]*a[0]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebp,0
        +	mov	edx,DWORD PTR 4[esi]
        +	; sqr a[2]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebp,0
        +	add	ebx,eax
        +	adc	ecx,edx
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ebp,0
        +	mov	DWORD PTR 12[edi],ebx
        +	mov	edx,DWORD PTR 4[esi]
        +	; saved r[3]
        +	; ############### Calculate word 4
        +	xor	ebx,ebx
        +	; sqr a[3]*a[1]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ebx,0
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	eax,DWORD PTR 8[esi]
        +	adc	ebx,0
        +	; sqr a[2]*a[2]
        +	mul	eax
        +	add	ecx,eax
        +	adc	ebp,edx
        +	mov	edx,DWORD PTR 8[esi]
        +	adc	ebx,0
        +	mov	DWORD PTR 16[edi],ecx
        +	mov	eax,DWORD PTR 12[esi]
        +	; saved r[4]
        +	; ############### Calculate word 5
        +	xor	ecx,ecx
        +	; sqr a[3]*a[2]
        +	mul	edx
        +	add	eax,eax
        +	adc	edx,edx
        +	adc	ecx,0
        +	add	ebp,eax
        +	adc	ebx,edx
        +	mov	eax,DWORD PTR 12[esi]
        +	adc	ecx,0
        +	mov	DWORD PTR 20[edi],ebp
        +	; saved r[5]
        +	; ############### Calculate word 6
        +	xor	ebp,ebp
        +	; sqr a[3]*a[3]
        +	mul	eax
        +	add	ebx,eax
        +	adc	ecx,edx
        +	adc	ebp,0
        +	mov	DWORD PTR 24[edi],ebx
        +	; saved r[6]
        +	mov	DWORD PTR 28[edi],ecx
        +	pop	ebx
        +	pop	ebp
        +	pop	edi
        +	pop	esi
        +	ret
        +_bn_sqr_comba4 ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm b/vendor/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm
        new file mode 100644
        index 000000000..e32d28135
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/camellia/cmll-x86.asm
        @@ -0,0 +1,2367 @@
        +TITLE	cmll-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_Camellia_EncryptBlock_Rounds	PROC PUBLIC
        +$L_Camellia_EncryptBlock_Rounds_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	ebx,esp
        +	sub	esp,28
        +	and	esp,-64
        +	lea	ecx,DWORD PTR [edi-127]
        +	sub	ecx,esp
        +	neg	ecx
        +	and	ecx,960
        +	sub	esp,ecx
        +	add	esp,4
        +	shl	eax,6
        +	lea	eax,DWORD PTR [eax*1+edi]
        +	mov	DWORD PTR 20[esp],ebx
        +	mov	DWORD PTR 16[esp],eax
        +	call	$L000pic_point
        +$L000pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LCamellia_SBOX-$L000pic_point)[ebp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	bswap	eax
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_encrypt
        +	mov	esp,DWORD PTR 20[esp]
        +	bswap	eax
        +	mov	esi,DWORD PTR 32[esp]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_Camellia_EncryptBlock_Rounds ENDP
        +ALIGN	16
        +_Camellia_EncryptBlock	PROC PUBLIC
        +$L_Camellia_EncryptBlock_begin::
        +	mov	eax,128
        +	sub	eax,DWORD PTR 4[esp]
        +	mov	eax,3
        +	adc	eax,0
        +	mov	DWORD PTR 4[esp],eax
        +	jmp	$L_Camellia_EncryptBlock_Rounds_begin
        +_Camellia_EncryptBlock ENDP
        +ALIGN	16
        +_Camellia_encrypt	PROC PUBLIC
        +$L_Camellia_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	ebx,esp
        +	sub	esp,28
        +	and	esp,-64
        +	mov	eax,DWORD PTR 272[edi]
        +	lea	ecx,DWORD PTR [edi-127]
        +	sub	ecx,esp
        +	neg	ecx
        +	and	ecx,960
        +	sub	esp,ecx
        +	add	esp,4
        +	shl	eax,6
        +	lea	eax,DWORD PTR [eax*1+edi]
        +	mov	DWORD PTR 20[esp],ebx
        +	mov	DWORD PTR 16[esp],eax
        +	call	$L001pic_point
        +$L001pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LCamellia_SBOX-$L001pic_point)[ebp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	bswap	eax
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_encrypt
        +	mov	esp,DWORD PTR 20[esp]
        +	bswap	eax
        +	mov	esi,DWORD PTR 24[esp]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_Camellia_encrypt ENDP
        +ALIGN	16
        +__x86_Camellia_encrypt	PROC PRIVATE
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	esi,DWORD PTR 16[edi]
        +	mov	DWORD PTR 4[esp],eax
        +	mov	DWORD PTR 8[esp],ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	mov	DWORD PTR 16[esp],edx
        +ALIGN	16
        +$L002loop:
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 20[edi]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 16[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 12[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 24[edi]
        +	xor	edx,ecx
        +	mov	DWORD PTR 16[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 28[edi]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 32[edi]
        +	xor	ebx,eax
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR 4[esp],eax
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 36[edi]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 16[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 12[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 40[edi]
        +	xor	edx,ecx
        +	mov	DWORD PTR 16[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 44[edi]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 48[edi]
        +	xor	ebx,eax
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR 4[esp],eax
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 52[edi]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 16[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 12[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 56[edi]
        +	xor	edx,ecx
        +	mov	DWORD PTR 16[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 60[edi]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 64[edi]
        +	xor	ebx,eax
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR 4[esp],eax
        +	add	edi,64
        +	cmp	edi,DWORD PTR 20[esp]
        +	je	$L003done
        +	and	esi,eax
        +	mov	edx,DWORD PTR 16[esp]
        +	rol	esi,1
        +	mov	ecx,edx
        +	xor	ebx,esi
        +	or	ecx,DWORD PTR 12[edi]
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	ecx,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 4[edi]
        +	mov	DWORD PTR 12[esp],ecx
        +	or	esi,ebx
        +	and	ecx,DWORD PTR 8[edi]
        +	xor	eax,esi
        +	rol	ecx,1
        +	mov	DWORD PTR 4[esp],eax
        +	xor	edx,ecx
        +	mov	esi,DWORD PTR 16[edi]
        +	mov	DWORD PTR 16[esp],edx
        +	jmp	$L002loop
        +ALIGN	8
        +$L003done:
        +	mov	ecx,eax
        +	mov	edx,ebx
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	ret
        +__x86_Camellia_encrypt ENDP
        +ALIGN	16
        +_Camellia_DecryptBlock_Rounds	PROC PUBLIC
        +$L_Camellia_DecryptBlock_Rounds_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	ebx,esp
        +	sub	esp,28
        +	and	esp,-64
        +	lea	ecx,DWORD PTR [edi-127]
        +	sub	ecx,esp
        +	neg	ecx
        +	and	ecx,960
        +	sub	esp,ecx
        +	add	esp,4
        +	shl	eax,6
        +	mov	DWORD PTR 16[esp],edi
        +	lea	edi,DWORD PTR [eax*1+edi]
        +	mov	DWORD PTR 20[esp],ebx
        +	call	$L004pic_point
        +$L004pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LCamellia_SBOX-$L004pic_point)[ebp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	bswap	eax
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_decrypt
        +	mov	esp,DWORD PTR 20[esp]
        +	bswap	eax
        +	mov	esi,DWORD PTR 32[esp]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_Camellia_DecryptBlock_Rounds ENDP
        +ALIGN	16
        +_Camellia_DecryptBlock	PROC PUBLIC
        +$L_Camellia_DecryptBlock_begin::
        +	mov	eax,128
        +	sub	eax,DWORD PTR 4[esp]
        +	mov	eax,3
        +	adc	eax,0
        +	mov	DWORD PTR 4[esp],eax
        +	jmp	$L_Camellia_DecryptBlock_Rounds_begin
        +_Camellia_DecryptBlock ENDP
        +ALIGN	16
        +_Camellia_decrypt	PROC PUBLIC
        +$L_Camellia_decrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	ebx,esp
        +	sub	esp,28
        +	and	esp,-64
        +	mov	eax,DWORD PTR 272[edi]
        +	lea	ecx,DWORD PTR [edi-127]
        +	sub	ecx,esp
        +	neg	ecx
        +	and	ecx,960
        +	sub	esp,ecx
        +	add	esp,4
        +	shl	eax,6
        +	mov	DWORD PTR 16[esp],edi
        +	lea	edi,DWORD PTR [eax*1+edi]
        +	mov	DWORD PTR 20[esp],ebx
        +	call	$L005pic_point
        +$L005pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LCamellia_SBOX-$L005pic_point)[ebp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	bswap	eax
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_decrypt
        +	mov	esp,DWORD PTR 20[esp]
        +	bswap	eax
        +	mov	esi,DWORD PTR 24[esp]
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_Camellia_decrypt ENDP
        +ALIGN	16
        +__x86_Camellia_decrypt	PROC PRIVATE
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	esi,DWORD PTR [edi-8]
        +	mov	DWORD PTR 4[esp],eax
        +	mov	DWORD PTR 8[esp],ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	mov	DWORD PTR 16[esp],edx
        +ALIGN	16
        +$L006loop:
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR [edi-4]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 16[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 12[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR [edi-16]
        +	xor	edx,ecx
        +	mov	DWORD PTR 16[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR [edi-12]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR [edi-24]
        +	xor	ebx,eax
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR 4[esp],eax
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR [edi-20]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 16[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 12[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR [edi-32]
        +	xor	edx,ecx
        +	mov	DWORD PTR 16[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR [edi-28]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR [edi-40]
        +	xor	ebx,eax
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR 4[esp],eax
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR [edi-36]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 16[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 12[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR [edi-48]
        +	xor	edx,ecx
        +	mov	DWORD PTR 16[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 12[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR [edi-44]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR [edi-56]
        +	xor	ebx,eax
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR 4[esp],eax
        +	sub	edi,64
        +	cmp	edi,DWORD PTR 20[esp]
        +	je	$L007done
        +	and	esi,eax
        +	mov	edx,DWORD PTR 16[esp]
        +	rol	esi,1
        +	mov	ecx,edx
        +	xor	ebx,esi
        +	or	ecx,DWORD PTR 4[edi]
        +	mov	DWORD PTR 8[esp],ebx
        +	xor	ecx,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 12[edi]
        +	mov	DWORD PTR 12[esp],ecx
        +	or	esi,ebx
        +	and	ecx,DWORD PTR [edi]
        +	xor	eax,esi
        +	rol	ecx,1
        +	mov	DWORD PTR 4[esp],eax
        +	xor	edx,ecx
        +	mov	esi,DWORD PTR [edi-8]
        +	mov	DWORD PTR 16[esp],edx
        +	jmp	$L006loop
        +ALIGN	8
        +$L007done:
        +	mov	ecx,eax
        +	mov	edx,ebx
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 12[edi]
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	ret
        +__x86_Camellia_decrypt ENDP
        +ALIGN	16
        +_Camellia_Ekeygen	PROC PUBLIC
        +$L_Camellia_Ekeygen_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	sub	esp,16
        +	mov	ebp,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR 40[esp]
        +	mov	edi,DWORD PTR 44[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	cmp	ebp,128
        +	je	$L0081st128
        +	mov	eax,DWORD PTR 16[esi]
        +	mov	ebx,DWORD PTR 20[esi]
        +	cmp	ebp,192
        +	je	$L0091st192
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 28[esi]
        +	jmp	$L0101st256
        +ALIGN	4
        +$L0091st192:
        +	mov	ecx,eax
        +	mov	edx,ebx
        +	not	ecx
        +	not	edx
        +ALIGN	4
        +$L0101st256:
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR 32[edi],eax
        +	mov	DWORD PTR 36[edi],ebx
        +	mov	DWORD PTR 40[edi],ecx
        +	mov	DWORD PTR 44[edi],edx
        +	xor	eax,DWORD PTR [edi]
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +ALIGN	4
        +$L0081st128:
        +	call	$L011pic_point
        +$L011pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LCamellia_SBOX-$L011pic_point)[ebp]
        +	lea	edi,DWORD PTR ($LCamellia_SIGMA-$LCamellia_SBOX)[ebp]
        +	mov	esi,DWORD PTR [edi]
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	mov	DWORD PTR 12[esp],edx
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 4[edi]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 12[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 8[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 8[edi]
        +	xor	edx,ecx
        +	mov	DWORD PTR 12[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 12[edi]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 4[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR [esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 16[edi]
        +	xor	ebx,eax
        +	mov	DWORD PTR 4[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR [esp],eax
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 44[esp]
        +	xor	eax,DWORD PTR [esi]
        +	xor	ebx,DWORD PTR 4[esi]
        +	xor	ecx,DWORD PTR 8[esi]
        +	xor	edx,DWORD PTR 12[esi]
        +	mov	esi,DWORD PTR 16[edi]
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	mov	DWORD PTR 12[esp],edx
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 20[edi]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 12[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 8[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 24[edi]
        +	xor	edx,ecx
        +	mov	DWORD PTR 12[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 28[edi]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 4[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR [esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 32[edi]
        +	xor	ebx,eax
        +	mov	DWORD PTR 4[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR [esp],eax
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 36[esp]
        +	cmp	esi,128
        +	jne	$L0122nd256
        +	mov	edi,DWORD PTR 44[esp]
        +	lea	edi,DWORD PTR 128[edi]
        +	mov	DWORD PTR [edi-112],eax
        +	mov	DWORD PTR [edi-108],ebx
        +	mov	DWORD PTR [edi-104],ecx
        +	mov	DWORD PTR [edi-100],edx
        +	mov	ebp,eax
        +	shl	eax,15
        +	mov	esi,ebx
        +	shr	esi,17
        +	shl	ebx,15
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,15
        +	mov	DWORD PTR [edi-80],eax
        +	shr	esi,17
        +	or	ebx,esi
        +	shr	ebp,17
        +	mov	esi,edx
        +	shr	esi,17
        +	mov	DWORD PTR [edi-76],ebx
        +	shl	edx,15
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR [edi-72],ecx
        +	mov	DWORD PTR [edi-68],edx
        +	mov	ebp,eax
        +	shl	eax,15
        +	mov	esi,ebx
        +	shr	esi,17
        +	shl	ebx,15
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,15
        +	mov	DWORD PTR [edi-64],eax
        +	shr	esi,17
        +	or	ebx,esi
        +	shr	ebp,17
        +	mov	esi,edx
        +	shr	esi,17
        +	mov	DWORD PTR [edi-60],ebx
        +	shl	edx,15
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR [edi-56],ecx
        +	mov	DWORD PTR [edi-52],edx
        +	mov	ebp,eax
        +	shl	eax,15
        +	mov	esi,ebx
        +	shr	esi,17
        +	shl	ebx,15
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,15
        +	mov	DWORD PTR [edi-32],eax
        +	shr	esi,17
        +	or	ebx,esi
        +	shr	ebp,17
        +	mov	esi,edx
        +	shr	esi,17
        +	mov	DWORD PTR [edi-28],ebx
        +	shl	edx,15
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	ebp,eax
        +	shl	eax,15
        +	mov	esi,ebx
        +	shr	esi,17
        +	shl	ebx,15
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,15
        +	mov	DWORD PTR [edi-16],eax
        +	shr	esi,17
        +	or	ebx,esi
        +	shr	ebp,17
        +	mov	esi,edx
        +	shr	esi,17
        +	mov	DWORD PTR [edi-12],ebx
        +	shl	edx,15
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR [edi-8],ecx
        +	mov	DWORD PTR [edi-4],edx
        +	mov	ebp,ebx
        +	shl	ebx,2
        +	mov	esi,ecx
        +	shr	esi,30
        +	shl	ecx,2
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,2
        +	mov	DWORD PTR 32[edi],ebx
        +	shr	esi,30
        +	or	ecx,esi
        +	shr	ebp,30
        +	mov	esi,eax
        +	shr	esi,30
        +	mov	DWORD PTR 36[edi],ecx
        +	shl	eax,2
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 40[edi],edx
        +	mov	DWORD PTR 44[edi],eax
        +	mov	ebp,ebx
        +	shl	ebx,17
        +	mov	esi,ecx
        +	shr	esi,15
        +	shl	ecx,17
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,17
        +	mov	DWORD PTR 64[edi],ebx
        +	shr	esi,15
        +	or	ecx,esi
        +	shr	ebp,15
        +	mov	esi,eax
        +	shr	esi,15
        +	mov	DWORD PTR 68[edi],ecx
        +	shl	eax,17
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 72[edi],edx
        +	mov	DWORD PTR 76[edi],eax
        +	mov	ebx,DWORD PTR [edi-128]
        +	mov	ecx,DWORD PTR [edi-124]
        +	mov	edx,DWORD PTR [edi-120]
        +	mov	eax,DWORD PTR [edi-116]
        +	mov	ebp,ebx
        +	shl	ebx,15
        +	mov	esi,ecx
        +	shr	esi,17
        +	shl	ecx,15
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,15
        +	mov	DWORD PTR [edi-96],ebx
        +	shr	esi,17
        +	or	ecx,esi
        +	shr	ebp,17
        +	mov	esi,eax
        +	shr	esi,17
        +	mov	DWORD PTR [edi-92],ecx
        +	shl	eax,15
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR [edi-88],edx
        +	mov	DWORD PTR [edi-84],eax
        +	mov	ebp,ebx
        +	shl	ebx,30
        +	mov	esi,ecx
        +	shr	esi,2
        +	shl	ecx,30
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,30
        +	mov	DWORD PTR [edi-48],ebx
        +	shr	esi,2
        +	or	ecx,esi
        +	shr	ebp,2
        +	mov	esi,eax
        +	shr	esi,2
        +	mov	DWORD PTR [edi-44],ecx
        +	shl	eax,30
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR [edi-40],edx
        +	mov	DWORD PTR [edi-36],eax
        +	mov	ebp,ebx
        +	shl	ebx,15
        +	mov	esi,ecx
        +	shr	esi,17
        +	shl	ecx,15
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,15
        +	shr	esi,17
        +	or	ecx,esi
        +	shr	ebp,17
        +	mov	esi,eax
        +	shr	esi,17
        +	shl	eax,15
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR [edi-24],edx
        +	mov	DWORD PTR [edi-20],eax
        +	mov	ebp,ebx
        +	shl	ebx,17
        +	mov	esi,ecx
        +	shr	esi,15
        +	shl	ecx,17
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,17
        +	mov	DWORD PTR [edi],ebx
        +	shr	esi,15
        +	or	ecx,esi
        +	shr	ebp,15
        +	mov	esi,eax
        +	shr	esi,15
        +	mov	DWORD PTR 4[edi],ecx
        +	shl	eax,17
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 8[edi],edx
        +	mov	DWORD PTR 12[edi],eax
        +	mov	ebp,ebx
        +	shl	ebx,17
        +	mov	esi,ecx
        +	shr	esi,15
        +	shl	ecx,17
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,17
        +	mov	DWORD PTR 16[edi],ebx
        +	shr	esi,15
        +	or	ecx,esi
        +	shr	ebp,15
        +	mov	esi,eax
        +	shr	esi,15
        +	mov	DWORD PTR 20[edi],ecx
        +	shl	eax,17
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 24[edi],edx
        +	mov	DWORD PTR 28[edi],eax
        +	mov	ebp,ebx
        +	shl	ebx,17
        +	mov	esi,ecx
        +	shr	esi,15
        +	shl	ecx,17
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,17
        +	mov	DWORD PTR 48[edi],ebx
        +	shr	esi,15
        +	or	ecx,esi
        +	shr	ebp,15
        +	mov	esi,eax
        +	shr	esi,15
        +	mov	DWORD PTR 52[edi],ecx
        +	shl	eax,17
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 56[edi],edx
        +	mov	DWORD PTR 60[edi],eax
        +	mov	eax,3
        +	jmp	$L013done
        +ALIGN	16
        +$L0122nd256:
        +	mov	esi,DWORD PTR 44[esp]
        +	mov	DWORD PTR 48[esi],eax
        +	mov	DWORD PTR 52[esi],ebx
        +	mov	DWORD PTR 56[esi],ecx
        +	mov	DWORD PTR 60[esi],edx
        +	xor	eax,DWORD PTR 32[esi]
        +	xor	ebx,DWORD PTR 36[esi]
        +	xor	ecx,DWORD PTR 40[esi]
        +	xor	edx,DWORD PTR 44[esi]
        +	mov	esi,DWORD PTR 32[edi]
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	mov	DWORD PTR 12[esp],edx
        +	xor	eax,esi
        +	xor	ebx,DWORD PTR 36[edi]
        +	movzx	esi,ah
        +	mov	edx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,al
        +	xor	edx,DWORD PTR 4[esi*8+ebp]
        +	shr	eax,16
        +	movzx	esi,bl
        +	mov	ecx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ah
        +	xor	edx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,bh
        +	xor	ecx,DWORD PTR 4[esi*8+ebp]
        +	shr	ebx,16
        +	movzx	eax,al
        +	xor	edx,DWORD PTR 2048[eax*8+ebp]
        +	movzx	esi,bh
        +	mov	eax,DWORD PTR 12[esp]
        +	xor	ecx,edx
        +	ror	edx,8
        +	xor	ecx,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,bl
        +	mov	ebx,DWORD PTR 8[esp]
        +	xor	edx,eax
        +	xor	ecx,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 40[edi]
        +	xor	edx,ecx
        +	mov	DWORD PTR 12[esp],edx
        +	xor	ecx,ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	xor	ecx,esi
        +	xor	edx,DWORD PTR 44[edi]
        +	movzx	esi,ch
        +	mov	ebx,DWORD PTR 2052[esi*8+ebp]
        +	movzx	esi,cl
        +	xor	ebx,DWORD PTR 4[esi*8+ebp]
        +	shr	ecx,16
        +	movzx	esi,dl
        +	mov	eax,DWORD PTR [esi*8+ebp]
        +	movzx	esi,ch
        +	xor	ebx,DWORD PTR [esi*8+ebp]
        +	movzx	esi,dh
        +	xor	eax,DWORD PTR 4[esi*8+ebp]
        +	shr	edx,16
        +	movzx	ecx,cl
        +	xor	ebx,DWORD PTR 2048[ecx*8+ebp]
        +	movzx	esi,dh
        +	mov	ecx,DWORD PTR 4[esp]
        +	xor	eax,ebx
        +	ror	ebx,8
        +	xor	eax,DWORD PTR 2048[esi*8+ebp]
        +	movzx	esi,dl
        +	mov	edx,DWORD PTR [esp]
        +	xor	ebx,ecx
        +	xor	eax,DWORD PTR 2052[esi*8+ebp]
        +	mov	esi,DWORD PTR 48[edi]
        +	xor	ebx,eax
        +	mov	DWORD PTR 4[esp],ebx
        +	xor	eax,edx
        +	mov	DWORD PTR [esp],eax
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	edi,DWORD PTR 44[esp]
        +	lea	edi,DWORD PTR 128[edi]
        +	mov	DWORD PTR [edi-112],eax
        +	mov	DWORD PTR [edi-108],ebx
        +	mov	DWORD PTR [edi-104],ecx
        +	mov	DWORD PTR [edi-100],edx
        +	mov	ebp,eax
        +	shl	eax,30
        +	mov	esi,ebx
        +	shr	esi,2
        +	shl	ebx,30
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,30
        +	mov	DWORD PTR [edi-48],eax
        +	shr	esi,2
        +	or	ebx,esi
        +	shr	ebp,2
        +	mov	esi,edx
        +	shr	esi,2
        +	mov	DWORD PTR [edi-44],ebx
        +	shl	edx,30
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR [edi-40],ecx
        +	mov	DWORD PTR [edi-36],edx
        +	mov	ebp,eax
        +	shl	eax,30
        +	mov	esi,ebx
        +	shr	esi,2
        +	shl	ebx,30
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,30
        +	mov	DWORD PTR 32[edi],eax
        +	shr	esi,2
        +	or	ebx,esi
        +	shr	ebp,2
        +	mov	esi,edx
        +	shr	esi,2
        +	mov	DWORD PTR 36[edi],ebx
        +	shl	edx,30
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR 40[edi],ecx
        +	mov	DWORD PTR 44[edi],edx
        +	mov	ebp,ebx
        +	shl	ebx,19
        +	mov	esi,ecx
        +	shr	esi,13
        +	shl	ecx,19
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,19
        +	mov	DWORD PTR 128[edi],ebx
        +	shr	esi,13
        +	or	ecx,esi
        +	shr	ebp,13
        +	mov	esi,eax
        +	shr	esi,13
        +	mov	DWORD PTR 132[edi],ecx
        +	shl	eax,19
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 136[edi],edx
        +	mov	DWORD PTR 140[edi],eax
        +	mov	ebx,DWORD PTR [edi-96]
        +	mov	ecx,DWORD PTR [edi-92]
        +	mov	edx,DWORD PTR [edi-88]
        +	mov	eax,DWORD PTR [edi-84]
        +	mov	ebp,ebx
        +	shl	ebx,15
        +	mov	esi,ecx
        +	shr	esi,17
        +	shl	ecx,15
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,15
        +	mov	DWORD PTR [edi-96],ebx
        +	shr	esi,17
        +	or	ecx,esi
        +	shr	ebp,17
        +	mov	esi,eax
        +	shr	esi,17
        +	mov	DWORD PTR [edi-92],ecx
        +	shl	eax,15
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR [edi-88],edx
        +	mov	DWORD PTR [edi-84],eax
        +	mov	ebp,ebx
        +	shl	ebx,15
        +	mov	esi,ecx
        +	shr	esi,17
        +	shl	ecx,15
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,15
        +	mov	DWORD PTR [edi-64],ebx
        +	shr	esi,17
        +	or	ecx,esi
        +	shr	ebp,17
        +	mov	esi,eax
        +	shr	esi,17
        +	mov	DWORD PTR [edi-60],ecx
        +	shl	eax,15
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR [edi-56],edx
        +	mov	DWORD PTR [edi-52],eax
        +	mov	ebp,ebx
        +	shl	ebx,30
        +	mov	esi,ecx
        +	shr	esi,2
        +	shl	ecx,30
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,30
        +	mov	DWORD PTR 16[edi],ebx
        +	shr	esi,2
        +	or	ecx,esi
        +	shr	ebp,2
        +	mov	esi,eax
        +	shr	esi,2
        +	mov	DWORD PTR 20[edi],ecx
        +	shl	eax,30
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 24[edi],edx
        +	mov	DWORD PTR 28[edi],eax
        +	mov	ebp,ecx
        +	shl	ecx,2
        +	mov	esi,edx
        +	shr	esi,30
        +	shl	edx,2
        +	or	ecx,esi
        +	mov	esi,eax
        +	shl	eax,2
        +	mov	DWORD PTR 80[edi],ecx
        +	shr	esi,30
        +	or	edx,esi
        +	shr	ebp,30
        +	mov	esi,ebx
        +	shr	esi,30
        +	mov	DWORD PTR 84[edi],edx
        +	shl	ebx,2
        +	or	eax,esi
        +	or	ebx,ebp
        +	mov	DWORD PTR 88[edi],eax
        +	mov	DWORD PTR 92[edi],ebx
        +	mov	ecx,DWORD PTR [edi-80]
        +	mov	edx,DWORD PTR [edi-76]
        +	mov	eax,DWORD PTR [edi-72]
        +	mov	ebx,DWORD PTR [edi-68]
        +	mov	ebp,ecx
        +	shl	ecx,15
        +	mov	esi,edx
        +	shr	esi,17
        +	shl	edx,15
        +	or	ecx,esi
        +	mov	esi,eax
        +	shl	eax,15
        +	mov	DWORD PTR [edi-80],ecx
        +	shr	esi,17
        +	or	edx,esi
        +	shr	ebp,17
        +	mov	esi,ebx
        +	shr	esi,17
        +	mov	DWORD PTR [edi-76],edx
        +	shl	ebx,15
        +	or	eax,esi
        +	or	ebx,ebp
        +	mov	DWORD PTR [edi-72],eax
        +	mov	DWORD PTR [edi-68],ebx
        +	mov	ebp,ecx
        +	shl	ecx,30
        +	mov	esi,edx
        +	shr	esi,2
        +	shl	edx,30
        +	or	ecx,esi
        +	mov	esi,eax
        +	shl	eax,30
        +	mov	DWORD PTR [edi-16],ecx
        +	shr	esi,2
        +	or	edx,esi
        +	shr	ebp,2
        +	mov	esi,ebx
        +	shr	esi,2
        +	mov	DWORD PTR [edi-12],edx
        +	shl	ebx,30
        +	or	eax,esi
        +	or	ebx,ebp
        +	mov	DWORD PTR [edi-8],eax
        +	mov	DWORD PTR [edi-4],ebx
        +	mov	DWORD PTR 64[edi],edx
        +	mov	DWORD PTR 68[edi],eax
        +	mov	DWORD PTR 72[edi],ebx
        +	mov	DWORD PTR 76[edi],ecx
        +	mov	ebp,edx
        +	shl	edx,17
        +	mov	esi,eax
        +	shr	esi,15
        +	shl	eax,17
        +	or	edx,esi
        +	mov	esi,ebx
        +	shl	ebx,17
        +	mov	DWORD PTR 96[edi],edx
        +	shr	esi,15
        +	or	eax,esi
        +	shr	ebp,15
        +	mov	esi,ecx
        +	shr	esi,15
        +	mov	DWORD PTR 100[edi],eax
        +	shl	ecx,17
        +	or	ebx,esi
        +	or	ecx,ebp
        +	mov	DWORD PTR 104[edi],ebx
        +	mov	DWORD PTR 108[edi],ecx
        +	mov	edx,DWORD PTR [edi-128]
        +	mov	eax,DWORD PTR [edi-124]
        +	mov	ebx,DWORD PTR [edi-120]
        +	mov	ecx,DWORD PTR [edi-116]
        +	mov	ebp,eax
        +	shl	eax,13
        +	mov	esi,ebx
        +	shr	esi,19
        +	shl	ebx,13
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,13
        +	mov	DWORD PTR [edi-32],eax
        +	shr	esi,19
        +	or	ebx,esi
        +	shr	ebp,19
        +	mov	esi,edx
        +	shr	esi,19
        +	mov	DWORD PTR [edi-28],ebx
        +	shl	edx,13
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR [edi-24],ecx
        +	mov	DWORD PTR [edi-20],edx
        +	mov	ebp,eax
        +	shl	eax,15
        +	mov	esi,ebx
        +	shr	esi,17
        +	shl	ebx,15
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,15
        +	mov	DWORD PTR [edi],eax
        +	shr	esi,17
        +	or	ebx,esi
        +	shr	ebp,17
        +	mov	esi,edx
        +	shr	esi,17
        +	mov	DWORD PTR 4[edi],ebx
        +	shl	edx,15
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	ebp,eax
        +	shl	eax,17
        +	mov	esi,ebx
        +	shr	esi,15
        +	shl	ebx,17
        +	or	eax,esi
        +	mov	esi,ecx
        +	shl	ecx,17
        +	mov	DWORD PTR 48[edi],eax
        +	shr	esi,15
        +	or	ebx,esi
        +	shr	ebp,15
        +	mov	esi,edx
        +	shr	esi,15
        +	mov	DWORD PTR 52[edi],ebx
        +	shl	edx,17
        +	or	ecx,esi
        +	or	edx,ebp
        +	mov	DWORD PTR 56[edi],ecx
        +	mov	DWORD PTR 60[edi],edx
        +	mov	ebp,ebx
        +	shl	ebx,2
        +	mov	esi,ecx
        +	shr	esi,30
        +	shl	ecx,2
        +	or	ebx,esi
        +	mov	esi,edx
        +	shl	edx,2
        +	mov	DWORD PTR 112[edi],ebx
        +	shr	esi,30
        +	or	ecx,esi
        +	shr	ebp,30
        +	mov	esi,eax
        +	shr	esi,30
        +	mov	DWORD PTR 116[edi],ecx
        +	shl	eax,2
        +	or	edx,esi
        +	or	eax,ebp
        +	mov	DWORD PTR 120[edi],edx
        +	mov	DWORD PTR 124[edi],eax
        +	mov	eax,4
        +$L013done:
        +	lea	edx,DWORD PTR 144[edi]
        +	add	esp,16
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_Camellia_Ekeygen ENDP
        +ALIGN	16
        +_private_Camellia_set_key	PROC PUBLIC
        +$L_private_Camellia_set_key_begin::
        +	push	ebx
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	edx,DWORD PTR 16[esp]
        +	mov	eax,-1
        +	test	ecx,ecx
        +	jz	$L014done
        +	test	edx,edx
        +	jz	$L014done
        +	mov	eax,-2
        +	cmp	ebx,256
        +	je	$L015arg_ok
        +	cmp	ebx,192
        +	je	$L015arg_ok
        +	cmp	ebx,128
        +	jne	$L014done
        +ALIGN	4
        +$L015arg_ok:
        +	push	edx
        +	push	ecx
        +	push	ebx
        +	call	$L_Camellia_Ekeygen_begin
        +	add	esp,12
        +	mov	DWORD PTR [edx],eax
        +	xor	eax,eax
        +ALIGN	4
        +$L014done:
        +	pop	ebx
        +	ret
        +_private_Camellia_set_key ENDP
        +ALIGN	64
        +$LCamellia_SIGMA::
        +DD	2694735487,1003262091,3061508184,1286239154,3337565999,3914302142,1426019237,4057165596,283453434,3731369245,2958461122,3018244605,0,0,0,0
        +ALIGN	64
        +$LCamellia_SBOX::
        +DD	1886416896,1886388336
        +DD	2189591040,741081132
        +DD	741092352,3014852787
        +DD	3974949888,3233808576
        +DD	3014898432,3840147684
        +DD	656877312,1465319511
        +DD	3233857536,3941204202
        +DD	3857048832,2930639022
        +DD	3840205824,589496355
        +DD	2240120064,1802174571
        +DD	1465341696,1162149957
        +DD	892679424,2779054245
        +DD	3941263872,3991732461
        +DD	202116096,1330577487
        +DD	2930683392,488439837
        +DD	1094795520,2459041938
        +DD	589505280,2256928902
        +DD	4025478912,2947481775
        +DD	1802201856,2088501372
        +DD	2475922176,522125343
        +DD	1162167552,1044250686
        +DD	421075200,3705405660
        +DD	2779096320,1583218782
        +DD	555819264,185270283
        +DD	3991792896,2795896998
        +DD	235802112,960036921
        +DD	1330597632,3587506389
        +DD	1313754624,1566376029
        +DD	488447232,3654877401
        +DD	1701143808,1515847770
        +DD	2459079168,1364262993
        +DD	3183328512,1819017324
        +DD	2256963072,2341142667
        +DD	3099113472,2593783962
        +DD	2947526400,4227531003
        +DD	2408550144,2964324528
        +DD	2088532992,1953759348
        +DD	3958106880,724238379
        +DD	522133248,4042260720
        +DD	3469659648,2223243396
        +DD	1044266496,3755933919
        +DD	808464384,3419078859
        +DD	3705461760,875823156
        +DD	1600085760,1987444854
        +DD	1583242752,1835860077
        +DD	3318072576,2846425257
        +DD	185273088,3520135377
        +DD	437918208,67371012
        +DD	2795939328,336855060
        +DD	3789676800,976879674
        +DD	960051456,3739091166
        +DD	3402287616,286326801
        +DD	3587560704,842137650
        +DD	1195853568,2627469468
        +DD	1566399744,1397948499
        +DD	1027423488,4075946226
        +DD	3654932736,4278059262
        +DD	16843008,3486449871
        +DD	1515870720,3284336835
        +DD	3604403712,2054815866
        +DD	1364283648,606339108
        +DD	1448498688,3907518696
        +DD	1819044864,1616904288
        +DD	1296911616,1768489065
        +DD	2341178112,2863268010
        +DD	218959104,2694840480
        +DD	2593823232,2711683233
        +DD	1717986816,1650589794
        +DD	4227595008,1414791252
        +DD	3435973632,505282590
        +DD	2964369408,3772776672
        +DD	757935360,1684275300
        +DD	1953788928,269484048
        +DD	303174144,0
        +DD	724249344,2745368739
        +DD	538976256,1970602101
        +DD	4042321920,2324299914
        +DD	2981212416,3873833190
        +DD	2223277056,151584777
        +DD	2576980224,3722248413
        +DD	3755990784,2273771655
        +DD	1280068608,2206400643
        +DD	3419130624,3452764365
        +DD	3267543552,2425356432
        +DD	875836416,1936916595
        +DD	2122219008,4143317238
        +DD	1987474944,2644312221
        +DD	84215040,3216965823
        +DD	1835887872,1381105746
        +DD	3082270464,3638034648
        +DD	2846468352,3368550600
        +DD	825307392,3334865094
        +DD	3520188672,2172715137
        +DD	387389184,1869545583
        +DD	67372032,320012307
        +DD	3621246720,1667432547
        +DD	336860160,3924361449
        +DD	1482184704,2812739751
        +DD	976894464,2677997727
        +DD	1633771776,3166437564
        +DD	3739147776,690552873
        +DD	454761216,4193845497
        +DD	286331136,791609391
        +DD	471604224,3031695540
        +DD	842150400,2021130360
        +DD	252645120,101056518
        +DD	2627509248,3890675943
        +DD	370546176,1903231089
        +DD	1397969664,3570663636
        +DD	404232192,2880110763
        +DD	4076007936,2290614408
        +DD	572662272,2374828173
        +DD	4278124032,1920073842
        +DD	1145324544,3115909305
        +DD	3486502656,4177002744
        +DD	2998055424,2896953516
        +DD	3284386560,909508662
        +DD	3048584448,707395626
        +DD	2054846976,1010565180
        +DD	2442236160,4059103473
        +DD	606348288,1077936192
        +DD	134744064,3553820883
        +DD	3907577856,3149594811
        +DD	2829625344,1128464451
        +DD	1616928768,353697813
        +DD	4244438016,2913796269
        +DD	1768515840,2004287607
        +DD	1347440640,2155872384
        +DD	2863311360,2189557890
        +DD	3503345664,3974889708
        +DD	2694881280,656867367
        +DD	2105376000,3856990437
        +DD	2711724288,2240086149
        +DD	2307492096,892665909
        +DD	1650614784,202113036
        +DD	2543294208,1094778945
        +DD	1414812672,4025417967
        +DD	1532713728,2475884691
        +DD	505290240,421068825
        +DD	2509608192,555810849
        +DD	3772833792,235798542
        +DD	4294967040,1313734734
        +DD	1684300800,1701118053
        +DD	3537031680,3183280317
        +DD	269488128,3099066552
        +DD	3301229568,2408513679
        +DD	0,3958046955
        +DD	1212696576,3469607118
        +DD	2745410304,808452144
        +DD	4160222976,1600061535
        +DD	1970631936,3318022341
        +DD	3688618752,437911578
        +DD	2324335104,3789619425
        +DD	50529024,3402236106
        +DD	3873891840,1195835463
        +DD	3671775744,1027407933
        +DD	151587072,16842753
        +DD	1061109504,3604349142
        +DD	3722304768,1448476758
        +DD	2492765184,1296891981
        +DD	2273806080,218955789
        +DD	1549556736,1717960806
        +DD	2206434048,3435921612
        +DD	33686016,757923885
        +DD	3452816640,303169554
        +DD	1246382592,538968096
        +DD	2425393152,2981167281
        +DD	858993408,2576941209
        +DD	1936945920,1280049228
        +DD	1734829824,3267494082
        +DD	4143379968,2122186878
        +DD	4092850944,84213765
        +DD	2644352256,3082223799
        +DD	2139062016,825294897
        +DD	3217014528,387383319
        +DD	3806519808,3621191895
        +DD	1381126656,1482162264
        +DD	2610666240,1633747041
        +DD	3638089728,454754331
        +DD	640034304,471597084
        +DD	3368601600,252641295
        +DD	926365440,370540566
        +DD	3334915584,404226072
        +DD	993737472,572653602
        +DD	2172748032,1145307204
        +DD	2526451200,2998010034
        +DD	1869573888,3048538293
        +DD	1263225600,2442199185
        +DD	320017152,134742024
        +DD	3200171520,2829582504
        +DD	1667457792,4244373756
        +DD	774778368,1347420240
        +DD	3924420864,3503292624
        +DD	2038003968,2105344125
        +DD	2812782336,2307457161
        +DD	2358021120,2543255703
        +DD	2678038272,1532690523
        +DD	1852730880,2509570197
        +DD	3166485504,4294902015
        +DD	2391707136,3536978130
        +DD	690563328,3301179588
        +DD	4126536960,1212678216
        +DD	4193908992,4160159991
        +DD	3065427456,3688562907
        +DD	791621376,50528259
        +DD	4261281024,3671720154
        +DD	3031741440,1061093439
        +DD	1499027712,2492727444
        +DD	2021160960,1549533276
        +DD	2560137216,33685506
        +DD	101058048,1246363722
        +DD	1785358848,858980403
        +DD	3890734848,1734803559
        +DD	1179010560,4092788979
        +DD	1903259904,2139029631
        +DD	3132799488,3806462178
        +DD	3570717696,2610626715
        +DD	623191296,640024614
        +DD	2880154368,926351415
        +DD	1111638528,993722427
        +DD	2290649088,2526412950
        +DD	2728567296,1263206475
        +DD	2374864128,3200123070
        +DD	4210752000,774766638
        +DD	1920102912,2037973113
        +DD	117901056,2357985420
        +DD	3115956480,1852702830
        +DD	1431655680,2391670926
        +DD	4177065984,4126474485
        +DD	4008635904,3065381046
        +DD	2896997376,4261216509
        +DD	168430080,1499005017
        +DD	909522432,2560098456
        +DD	1229539584,1785331818
        +DD	707406336,1178992710
        +DD	1751672832,3132752058
        +DD	1010580480,623181861
        +DD	943208448,1111621698
        +DD	4059164928,2728525986
        +DD	2762253312,4210688250
        +DD	1077952512,117899271
        +DD	673720320,1431634005
        +DD	3553874688,4008575214
        +DD	2071689984,168427530
        +DD	3149642496,1229520969
        +DD	3385444608,1751646312
        +DD	1128481536,943194168
        +DD	3250700544,2762211492
        +DD	353703168,673710120
        +DD	3823362816,2071658619
        +DD	2913840384,3385393353
        +DD	4109693952,3250651329
        +DD	2004317952,3823304931
        +DD	3351758592,4109631732
        +DD	2155905024,3351707847
        +DD	2661195264,2661154974
        +DD	14737632,939538488
        +DD	328965,1090535745
        +DD	5789784,369104406
        +DD	14277081,1979741814
        +DD	6776679,3640711641
        +DD	5131854,2466288531
        +DD	8487297,1610637408
        +DD	13355979,4060148466
        +DD	13224393,1912631922
        +DD	723723,3254829762
        +DD	11447982,2868947883
        +DD	6974058,2583730842
        +DD	14013909,1962964341
        +DD	1579032,100664838
        +DD	6118749,1459640151
        +DD	8553090,2684395680
        +DD	4605510,2432733585
        +DD	14671839,4144035831
        +DD	14079702,3036722613
        +DD	2565927,3372272073
        +DD	9079434,2717950626
        +DD	3289650,2348846220
        +DD	4934475,3523269330
        +DD	4342338,2415956112
        +DD	14408667,4127258358
        +DD	1842204,117442311
        +DD	10395294,2801837991
        +DD	10263708,654321447
        +DD	3815994,2382401166
        +DD	13290186,2986390194
        +DD	2434341,1224755529
        +DD	8092539,3724599006
        +DD	855309,1124090691
        +DD	7434609,1543527516
        +DD	6250335,3607156695
        +DD	2039583,3338717127
        +DD	16316664,1040203326
        +DD	14145495,4110480885
        +DD	4079166,2399178639
        +DD	10329501,1728079719
        +DD	8158332,520101663
        +DD	6316128,402659352
        +DD	12171705,1845522030
        +DD	12500670,2936057775
        +DD	12369084,788541231
        +DD	9145227,3791708898
        +DD	1447446,2231403909
        +DD	3421236,218107149
        +DD	5066061,1392530259
        +DD	12829635,4026593520
        +DD	7500402,2617285788
        +DD	9803157,1694524773
        +DD	11250603,3925928682
        +DD	9342606,2734728099
        +DD	12237498,2919280302
        +DD	8026746,2650840734
        +DD	11776947,3959483628
        +DD	131586,2147516544
        +DD	11842740,754986285
        +DD	11382189,1795189611
        +DD	10658466,2818615464
        +DD	11316396,721431339
        +DD	14211288,905983542
        +DD	10132122,2785060518
        +DD	1513239,3305162181
        +DD	1710618,2248181382
        +DD	3487029,1291865421
        +DD	13421772,855651123
        +DD	16250871,4244700669
        +DD	10066329,1711302246
        +DD	6381921,1476417624
        +DD	5921370,2516620950
        +DD	15263976,973093434
        +DD	2368548,150997257
        +DD	5658198,2499843477
        +DD	4210752,268439568
        +DD	14803425,2013296760
        +DD	6513507,3623934168
        +DD	592137,1107313218
        +DD	3355443,3422604492
        +DD	12566463,4009816047
        +DD	10000536,637543974
        +DD	9934743,3842041317
        +DD	8750469,1627414881
        +DD	6842472,436214298
        +DD	16579836,1056980799
        +DD	15527148,989870907
        +DD	657930,2181071490
        +DD	14342874,3053500086
        +DD	7303023,3674266587
        +DD	5460819,3556824276
        +DD	6447714,2550175896
        +DD	10724259,3892373736
        +DD	3026478,2332068747
        +DD	526344,33554946
        +DD	11513775,3942706155
        +DD	2631720,167774730
        +DD	11579568,738208812
        +DD	7631988,486546717
        +DD	12763842,2952835248
        +DD	12434877,1862299503
        +DD	3552822,2365623693
        +DD	2236962,2281736328
        +DD	3684408,234884622
        +DD	6579300,419436825
        +DD	1973790,2264958855
        +DD	3750201,1308642894
        +DD	2894892,184552203
        +DD	10921638,2835392937
        +DD	3158064,201329676
        +DD	15066597,2030074233
        +DD	4473924,285217041
        +DD	16645629,2130739071
        +DD	8947848,570434082
        +DD	10461087,3875596263
        +DD	6645093,1493195097
        +DD	8882055,3774931425
        +DD	7039851,3657489114
        +DD	16053492,1023425853
        +DD	2302755,3355494600
        +DD	4737096,301994514
        +DD	1052688,67109892
        +DD	13750737,1946186868
        +DD	5329233,1409307732
        +DD	12632256,805318704
        +DD	16382457,2113961598
        +DD	13816530,3019945140
        +DD	10526880,671098920
        +DD	5592405,1426085205
        +DD	10592673,1744857192
        +DD	4276545,1342197840
        +DD	16448250,3187719870
        +DD	4408131,3489714384
        +DD	1250067,3288384708
        +DD	12895428,822096177
        +DD	3092271,3405827019
        +DD	11053224,704653866
        +DD	11974326,2902502829
        +DD	3947580,251662095
        +DD	2829099,3389049546
        +DD	12698049,1879076976
        +DD	16777215,4278255615
        +DD	13158600,838873650
        +DD	10855845,1761634665
        +DD	2105376,134219784
        +DD	9013641,1644192354
        +DD	0,0
        +DD	9474192,603989028
        +DD	4671303,3506491857
        +DD	15724527,4211145723
        +DD	15395562,3120609978
        +DD	12040119,3976261101
        +DD	1381653,1157645637
        +DD	394758,2164294017
        +DD	13487565,1929409395
        +DD	11908533,1828744557
        +DD	1184274,2214626436
        +DD	8289918,2667618207
        +DD	12303291,3993038574
        +DD	2697513,1241533002
        +DD	986895,3271607235
        +DD	12105912,771763758
        +DD	460551,3238052289
        +DD	263172,16777473
        +DD	10197915,3858818790
        +DD	9737364,620766501
        +DD	2171169,1207978056
        +DD	6710886,2566953369
        +DD	15132390,3103832505
        +DD	13553358,3003167667
        +DD	15592941,2063629179
        +DD	15198183,4177590777
        +DD	3881787,3456159438
        +DD	16711422,3204497343
        +DD	8355711,3741376479
        +DD	12961221,1895854449
        +DD	10790052,687876393
        +DD	3618615,3439381965
        +DD	11645361,1811967084
        +DD	5000268,318771987
        +DD	9539985,1677747300
        +DD	7237230,2600508315
        +DD	9276813,1660969827
        +DD	7763574,2634063261
        +DD	197379,3221274816
        +DD	2960685,1258310475
        +DD	14606046,3070277559
        +DD	9868950,2768283045
        +DD	2500134,2298513801
        +DD	8224125,1593859935
        +DD	13027014,2969612721
        +DD	6052956,385881879
        +DD	13882323,4093703412
        +DD	15921906,3154164924
        +DD	5197647,3540046803
        +DD	1644825,1174423110
        +DD	4144959,3472936911
        +DD	14474460,922761015
        +DD	7960953,1577082462
        +DD	1907997,1191200583
        +DD	5395026,2483066004
        +DD	15461355,4194368250
        +DD	15987699,4227923196
        +DD	7171437,1526750043
        +DD	6184542,2533398423
        +DD	16514043,4261478142
        +DD	6908265,1509972570
        +DD	11711154,2885725356
        +DD	15790320,1006648380
        +DD	3223857,1275087948
        +DD	789516,50332419
        +DD	13948116,889206069
        +DD	13619151,4076925939
        +DD	9211020,587211555
        +DD	14869218,3087055032
        +DD	7697781,1560304989
        +DD	11119017,1778412138
        +DD	4868682,2449511058
        +DD	5723991,3573601749
        +DD	8684676,553656609
        +DD	1118481,1140868164
        +DD	4539717,1358975313
        +DD	1776411,3321939654
        +DD	16119285,2097184125
        +DD	15000804,956315961
        +DD	921102,2197848963
        +DD	7566195,3691044060
        +DD	11184810,2852170410
        +DD	15856113,2080406652
        +DD	14540253,1996519287
        +DD	5855577,1442862678
        +DD	1315860,83887365
        +DD	7105644,452991771
        +DD	9605778,2751505572
        +DD	5526612,352326933
        +DD	13684944,872428596
        +DD	7895160,503324190
        +DD	7368816,469769244
        +DD	14935011,4160813304
        +DD	4802889,1375752786
        +DD	8421504,536879136
        +DD	5263440,335549460
        +DD	10987431,3909151209
        +DD	16185078,3170942397
        +DD	7829367,3707821533
        +DD	9671571,3825263844
        +DD	8816262,2701173153
        +DD	8618883,3758153952
        +DD	2763306,2315291274
        +DD	13092807,4043370993
        +DD	5987163,3590379222
        +DD	15329769,2046851706
        +DD	15658734,3137387451
        +DD	9408399,3808486371
        +DD	65793,1073758272
        +DD	4013373,1325420367
        +ALIGN	16
        +_Camellia_cbc_encrypt	PROC PUBLIC
        +$L_Camellia_cbc_encrypt_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ecx,DWORD PTR 28[esp]
        +	cmp	ecx,0
        +	je	$L016enc_out
        +	pushfd
        +	cld
        +	mov	eax,DWORD PTR 24[esp]
        +	mov	ebx,DWORD PTR 28[esp]
        +	mov	edx,DWORD PTR 36[esp]
        +	mov	ebp,DWORD PTR 40[esp]
        +	lea	esi,DWORD PTR [esp-64]
        +	and	esi,-64
        +	lea	edi,DWORD PTR [edx-127]
        +	sub	edi,esi
        +	neg	edi
        +	and	edi,960
        +	sub	esi,edi
        +	mov	edi,DWORD PTR 44[esp]
        +	xchg	esp,esi
        +	add	esp,4
        +	mov	DWORD PTR 20[esp],esi
        +	mov	DWORD PTR 24[esp],eax
        +	mov	DWORD PTR 28[esp],ebx
        +	mov	DWORD PTR 32[esp],ecx
        +	mov	DWORD PTR 36[esp],edx
        +	mov	DWORD PTR 40[esp],ebp
        +	call	$L017pic_point
        +$L017pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($LCamellia_SBOX-$L017pic_point)[ebp]
        +	mov	esi,32
        +ALIGN	4
        +$L018prefetch_sbox:
        +	mov	eax,DWORD PTR [ebp]
        +	mov	ebx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 64[ebp]
        +	mov	edx,DWORD PTR 96[ebp]
        +	lea	ebp,DWORD PTR 128[ebp]
        +	dec	esi
        +	jnz	$L018prefetch_sbox
        +	mov	eax,DWORD PTR 36[esp]
        +	sub	ebp,4096
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edx,DWORD PTR 272[eax]
        +	cmp	edi,0
        +	je	$L019DECRYPT
        +	mov	ecx,DWORD PTR 32[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	shl	edx,6
        +	lea	edx,DWORD PTR [edx*1+eax]
        +	mov	DWORD PTR 16[esp],edx
        +	test	ecx,4294967280
        +	jz	$L020enc_tail
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +ALIGN	4
        +$L021enc_loop:
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	xor	eax,DWORD PTR [esi]
        +	xor	ebx,DWORD PTR 4[esi]
        +	xor	ecx,DWORD PTR 8[esi]
        +	bswap	eax
        +	xor	edx,DWORD PTR 12[esi]
        +	bswap	ebx
        +	mov	edi,DWORD PTR 36[esp]
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_encrypt
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	mov	DWORD PTR [edi],eax
        +	bswap	edx
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	ecx,DWORD PTR 32[esp]
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 24[esp],esi
        +	lea	edx,DWORD PTR 16[edi]
        +	mov	DWORD PTR 28[esp],edx
        +	sub	ecx,16
        +	test	ecx,4294967280
        +	mov	DWORD PTR 32[esp],ecx
        +	jnz	$L021enc_loop
        +	test	ecx,15
        +	jnz	$L020enc_tail
        +	mov	esi,DWORD PTR 40[esp]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	mov	esp,DWORD PTR 20[esp]
        +	popfd
        +$L016enc_out:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +	pushfd
        +ALIGN	4
        +$L020enc_tail:
        +	mov	eax,edi
        +	mov	edi,DWORD PTR 28[esp]
        +	push	eax
        +	mov	ebx,16
        +	sub	ebx,ecx
        +	cmp	edi,esi
        +	je	$L022enc_in_place
        +ALIGN	4
        +DD	2767451785
        +	jmp	$L023enc_skip_in_place
        +$L022enc_in_place:
        +	lea	edi,DWORD PTR [ecx*1+edi]
        +$L023enc_skip_in_place:
        +	mov	ecx,ebx
        +	xor	eax,eax
        +ALIGN	4
        +DD	2868115081
        +	pop	edi
        +	mov	esi,DWORD PTR 28[esp]
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	DWORD PTR 32[esp],16
        +	jmp	$L021enc_loop
        +ALIGN	16
        +$L019DECRYPT:
        +	shl	edx,6
        +	lea	edx,DWORD PTR [edx*1+eax]
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 36[esp],edx
        +	cmp	esi,DWORD PTR 28[esp]
        +	je	$L024dec_in_place
        +	mov	edi,DWORD PTR 40[esp]
        +	mov	DWORD PTR 44[esp],edi
        +ALIGN	4
        +$L025dec_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	bswap	eax
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	ebx
        +	mov	edi,DWORD PTR 36[esp]
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_decrypt
        +	mov	edi,DWORD PTR 44[esp]
        +	mov	esi,DWORD PTR 32[esp]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	xor	eax,DWORD PTR [edi]
        +	bswap	edx
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	sub	esi,16
        +	jc	$L026dec_partial
        +	mov	DWORD PTR 32[esp],esi
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	edi,DWORD PTR 28[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	DWORD PTR 44[esp],esi
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 24[esp],esi
        +	lea	edi,DWORD PTR 16[edi]
        +	mov	DWORD PTR 28[esp],edi
        +	jnz	$L025dec_loop
        +	mov	edi,DWORD PTR 44[esp]
        +$L027dec_end:
        +	mov	esi,DWORD PTR 40[esp]
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	jmp	$L028dec_out
        +ALIGN	4
        +$L026dec_partial:
        +	lea	edi,DWORD PTR 44[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	lea	ecx,DWORD PTR 16[esi]
        +	mov	esi,edi
        +	mov	edi,DWORD PTR 28[esp]
        +DD	2767451785
        +	mov	edi,DWORD PTR 24[esp]
        +	jmp	$L027dec_end
        +ALIGN	4
        +$L024dec_in_place:
        +$L029dec_in_place_loop:
        +	lea	edi,DWORD PTR 44[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	bswap	eax
        +	mov	DWORD PTR 12[edi],edx
        +	bswap	ebx
        +	mov	edi,DWORD PTR 36[esp]
        +	bswap	ecx
        +	bswap	edx
        +	call	__x86_Camellia_decrypt
        +	mov	edi,DWORD PTR 40[esp]
        +	mov	esi,DWORD PTR 28[esp]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	xor	eax,DWORD PTR [edi]
        +	bswap	edx
        +	xor	ebx,DWORD PTR 4[edi]
        +	xor	ecx,DWORD PTR 8[edi]
        +	xor	edx,DWORD PTR 12[edi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 28[esp],esi
        +	lea	esi,DWORD PTR 44[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	mov	DWORD PTR 8[edi],ecx
        +	mov	DWORD PTR 12[edi],edx
        +	mov	esi,DWORD PTR 24[esp]
        +	lea	esi,DWORD PTR 16[esi]
        +	mov	DWORD PTR 24[esp],esi
        +	mov	ecx,DWORD PTR 32[esp]
        +	sub	ecx,16
        +	jc	$L030dec_in_place_partial
        +	mov	DWORD PTR 32[esp],ecx
        +	jnz	$L029dec_in_place_loop
        +	jmp	$L028dec_out
        +ALIGN	4
        +$L030dec_in_place_partial:
        +	mov	edi,DWORD PTR 28[esp]
        +	lea	esi,DWORD PTR 44[esp]
        +	lea	edi,DWORD PTR [ecx*1+edi]
        +	lea	esi,DWORD PTR 16[ecx*1+esi]
        +	neg	ecx
        +DD	2767451785
        +ALIGN	4
        +$L028dec_out:
        +	mov	esp,DWORD PTR 20[esp]
        +	popfd
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_Camellia_cbc_encrypt ENDP
        +DB	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54
        +DB	32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115
        +DB	115,108,46,111,114,103,62,0
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/cast/cast-586.asm b/vendor/openssl/asm/x86-win32-masm/cast/cast-586.asm
        new file mode 100644
        index 000000000..6f85c34d2
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/cast/cast-586.asm
        @@ -0,0 +1,950 @@
        +TITLE	cast-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +EXTERN	_CAST_S_table0:NEAR
        +EXTERN	_CAST_S_table1:NEAR
        +EXTERN	_CAST_S_table2:NEAR
        +EXTERN	_CAST_S_table3:NEAR
        +ALIGN	16
        +_CAST_encrypt	PROC PUBLIC
        +$L_CAST_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	ebp,DWORD PTR 16[esp]
        +	push	esi
        +	push	edi
        +	; Load the 2 words
        +	mov	edi,DWORD PTR [ebx]
        +	mov	esi,DWORD PTR 4[ebx]
        +	; Get short key flag
        +	mov	eax,DWORD PTR 128[ebp]
        +	push	eax
        +	xor	eax,eax
        +	; round 0
        +	mov	edx,DWORD PTR [ebp]
        +	mov	ecx,DWORD PTR 4[ebp]
        +	add	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	edi,ecx
        +	; round 1
        +	mov	edx,DWORD PTR 8[ebp]
        +	mov	ecx,DWORD PTR 12[ebp]
        +	xor	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	esi,ecx
        +	; round 2
        +	mov	edx,DWORD PTR 16[ebp]
        +	mov	ecx,DWORD PTR 20[ebp]
        +	sub	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	edi,ecx
        +	; round 3
        +	mov	edx,DWORD PTR 24[ebp]
        +	mov	ecx,DWORD PTR 28[ebp]
        +	add	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	esi,ecx
        +	; round 4
        +	mov	edx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 36[ebp]
        +	xor	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	edi,ecx
        +	; round 5
        +	mov	edx,DWORD PTR 40[ebp]
        +	mov	ecx,DWORD PTR 44[ebp]
        +	sub	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	esi,ecx
        +	; round 6
        +	mov	edx,DWORD PTR 48[ebp]
        +	mov	ecx,DWORD PTR 52[ebp]
        +	add	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	edi,ecx
        +	; round 7
        +	mov	edx,DWORD PTR 56[ebp]
        +	mov	ecx,DWORD PTR 60[ebp]
        +	xor	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	esi,ecx
        +	; round 8
        +	mov	edx,DWORD PTR 64[ebp]
        +	mov	ecx,DWORD PTR 68[ebp]
        +	sub	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	edi,ecx
        +	; round 9
        +	mov	edx,DWORD PTR 72[ebp]
        +	mov	ecx,DWORD PTR 76[ebp]
        +	add	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	esi,ecx
        +	; round 10
        +	mov	edx,DWORD PTR 80[ebp]
        +	mov	ecx,DWORD PTR 84[ebp]
        +	xor	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	edi,ecx
        +	; round 11
        +	mov	edx,DWORD PTR 88[ebp]
        +	mov	ecx,DWORD PTR 92[ebp]
        +	sub	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	esi,ecx
        +	; test short key flag
        +	pop	edx
        +	or	edx,edx
        +	jnz	$L000cast_enc_done
        +	; round 12
        +	mov	edx,DWORD PTR 96[ebp]
        +	mov	ecx,DWORD PTR 100[ebp]
        +	add	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	edi,ecx
        +	; round 13
        +	mov	edx,DWORD PTR 104[ebp]
        +	mov	ecx,DWORD PTR 108[ebp]
        +	xor	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	esi,ecx
        +	; round 14
        +	mov	edx,DWORD PTR 112[ebp]
        +	mov	ecx,DWORD PTR 116[ebp]
        +	sub	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	edi,ecx
        +	; round 15
        +	mov	edx,DWORD PTR 120[ebp]
        +	mov	ecx,DWORD PTR 124[ebp]
        +	add	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	esi,ecx
        +$L000cast_enc_done:
        +	nop
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	DWORD PTR 4[eax],edi
        +	mov	DWORD PTR [eax],esi
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_CAST_encrypt ENDP
        +EXTERN	_CAST_S_table0:NEAR
        +EXTERN	_CAST_S_table1:NEAR
        +EXTERN	_CAST_S_table2:NEAR
        +EXTERN	_CAST_S_table3:NEAR
        +ALIGN	16
        +_CAST_decrypt	PROC PUBLIC
        +$L_CAST_decrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	ebp,DWORD PTR 16[esp]
        +	push	esi
        +	push	edi
        +	; Load the 2 words
        +	mov	edi,DWORD PTR [ebx]
        +	mov	esi,DWORD PTR 4[ebx]
        +	; Get short key flag
        +	mov	eax,DWORD PTR 128[ebp]
        +	or	eax,eax
        +	jnz	$L001cast_dec_skip
        +	xor	eax,eax
        +	; round 15
        +	mov	edx,DWORD PTR 120[ebp]
        +	mov	ecx,DWORD PTR 124[ebp]
        +	add	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	edi,ecx
        +	; round 14
        +	mov	edx,DWORD PTR 112[ebp]
        +	mov	ecx,DWORD PTR 116[ebp]
        +	sub	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	esi,ecx
        +	; round 13
        +	mov	edx,DWORD PTR 104[ebp]
        +	mov	ecx,DWORD PTR 108[ebp]
        +	xor	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	edi,ecx
        +	; round 12
        +	mov	edx,DWORD PTR 96[ebp]
        +	mov	ecx,DWORD PTR 100[ebp]
        +	add	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	esi,ecx
        +$L001cast_dec_skip:
        +	; round 11
        +	mov	edx,DWORD PTR 88[ebp]
        +	mov	ecx,DWORD PTR 92[ebp]
        +	sub	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	edi,ecx
        +	; round 10
        +	mov	edx,DWORD PTR 80[ebp]
        +	mov	ecx,DWORD PTR 84[ebp]
        +	xor	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	esi,ecx
        +	; round 9
        +	mov	edx,DWORD PTR 72[ebp]
        +	mov	ecx,DWORD PTR 76[ebp]
        +	add	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	edi,ecx
        +	; round 8
        +	mov	edx,DWORD PTR 64[ebp]
        +	mov	ecx,DWORD PTR 68[ebp]
        +	sub	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	esi,ecx
        +	; round 7
        +	mov	edx,DWORD PTR 56[ebp]
        +	mov	ecx,DWORD PTR 60[ebp]
        +	xor	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	edi,ecx
        +	; round 6
        +	mov	edx,DWORD PTR 48[ebp]
        +	mov	ecx,DWORD PTR 52[ebp]
        +	add	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	esi,ecx
        +	; round 5
        +	mov	edx,DWORD PTR 40[ebp]
        +	mov	ecx,DWORD PTR 44[ebp]
        +	sub	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	edi,ecx
        +	; round 4
        +	mov	edx,DWORD PTR 32[ebp]
        +	mov	ecx,DWORD PTR 36[ebp]
        +	xor	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	esi,ecx
        +	; round 3
        +	mov	edx,DWORD PTR 24[ebp]
        +	mov	ecx,DWORD PTR 28[ebp]
        +	add	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	edi,ecx
        +	; round 2
        +	mov	edx,DWORD PTR 16[ebp]
        +	mov	ecx,DWORD PTR 20[ebp]
        +	sub	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	sub	ecx,ebx
        +	xor	esi,ecx
        +	; round 1
        +	mov	edx,DWORD PTR 8[ebp]
        +	mov	ecx,DWORD PTR 12[ebp]
        +	xor	edx,esi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	add	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	xor	ecx,ebx
        +	xor	edi,ecx
        +	; round 0
        +	mov	edx,DWORD PTR [ebp]
        +	mov	ecx,DWORD PTR 4[ebp]
        +	add	edx,edi
        +	rol	edx,cl
        +	mov	ebx,edx
        +	xor	ecx,ecx
        +	mov	cl,dh
        +	and	ebx,255
        +	shr	edx,16
        +	xor	eax,eax
        +	mov	al,dh
        +	and	edx,255
        +	mov	ecx,DWORD PTR _CAST_S_table0[ecx*4]
        +	mov	ebx,DWORD PTR _CAST_S_table1[ebx*4]
        +	xor	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table2[eax*4]
        +	sub	ecx,ebx
        +	mov	ebx,DWORD PTR _CAST_S_table3[edx*4]
        +	add	ecx,ebx
        +	xor	esi,ecx
        +	nop
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	DWORD PTR 4[eax],edi
        +	mov	DWORD PTR [eax],esi
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_CAST_decrypt ENDP
        +ALIGN	16
        +_CAST_cbc_encrypt	PROC PUBLIC
        +$L_CAST_cbc_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ebp,DWORD PTR 28[esp]
        +	; getting iv ptr from parameter 4
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR [ebx]
        +	mov	edi,DWORD PTR 4[ebx]
        +	push	edi
        +	push	esi
        +	push	edi
        +	push	esi
        +	mov	ebx,esp
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	; getting encrypt flag from parameter 5
        +	mov	ecx,DWORD PTR 56[esp]
        +	; get and push parameter 3
        +	mov	eax,DWORD PTR 48[esp]
        +	push	eax
        +	push	ebx
        +	cmp	ecx,0
        +	jz	$L002decrypt
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	jz	$L003encrypt_finish
        +$L004encrypt_loop:
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR 4[esi]
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_CAST_encrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L004encrypt_loop
        +$L003encrypt_finish:
        +	mov	ebp,DWORD PTR 52[esp]
        +	and	ebp,7
        +	jz	$L005finish
        +	call	$L006PIC_point
        +$L006PIC_point:
        +	pop	edx
        +	lea	ecx,DWORD PTR ($L007cbc_enc_jmp_table-$L006PIC_point)[edx]
        +	mov	ebp,DWORD PTR [ebp*4+ecx]
        +	add	ebp,edx
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	jmp	ebp
        +$L008ej7:
        +	mov	dh,BYTE PTR 6[esi]
        +	shl	edx,8
        +$L009ej6:
        +	mov	dh,BYTE PTR 5[esi]
        +$L010ej5:
        +	mov	dl,BYTE PTR 4[esi]
        +$L011ej4:
        +	mov	ecx,DWORD PTR [esi]
        +	jmp	$L012ejend
        +$L013ej3:
        +	mov	ch,BYTE PTR 2[esi]
        +	shl	ecx,8
        +$L014ej2:
        +	mov	ch,BYTE PTR 1[esi]
        +$L015ej1:
        +	mov	cl,BYTE PTR [esi]
        +$L012ejend:
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_CAST_encrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	jmp	$L005finish
        +$L002decrypt:
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	jz	$L016decrypt_finish
        +$L017decrypt_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_CAST_decrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	ecx,DWORD PTR 16[esp]
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR [edi],ecx
        +	mov	DWORD PTR 4[edi],edx
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L017decrypt_loop
        +$L016decrypt_finish:
        +	mov	ebp,DWORD PTR 52[esp]
        +	and	ebp,7
        +	jz	$L005finish
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	bswap	eax
        +	bswap	ebx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_CAST_decrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	bswap	eax
        +	bswap	ebx
        +	mov	ecx,DWORD PTR 16[esp]
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +$L018dj7:
        +	ror	edx,16
        +	mov	BYTE PTR 6[edi],dl
        +	shr	edx,16
        +$L019dj6:
        +	mov	BYTE PTR 5[edi],dh
        +$L020dj5:
        +	mov	BYTE PTR 4[edi],dl
        +$L021dj4:
        +	mov	DWORD PTR [edi],ecx
        +	jmp	$L022djend
        +$L023dj3:
        +	ror	ecx,16
        +	mov	BYTE PTR 2[edi],cl
        +	shl	ecx,16
        +$L024dj2:
        +	mov	BYTE PTR 1[esi],ch
        +$L025dj1:
        +	mov	BYTE PTR [esi],cl
        +$L022djend:
        +	jmp	$L005finish
        +$L005finish:
        +	mov	ecx,DWORD PTR 60[esp]
        +	add	esp,24
        +	mov	DWORD PTR [ecx],eax
        +	mov	DWORD PTR 4[ecx],ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L007cbc_enc_jmp_table:
        +DD	0
        +DD	$L015ej1-$L006PIC_point
        +DD	$L014ej2-$L006PIC_point
        +DD	$L013ej3-$L006PIC_point
        +DD	$L011ej4-$L006PIC_point
        +DD	$L010ej5-$L006PIC_point
        +DD	$L009ej6-$L006PIC_point
        +DD	$L008ej7-$L006PIC_point
        +ALIGN	64
        +_CAST_cbc_encrypt ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/des/crypt586.asm b/vendor/openssl/asm/x86-win32-masm/des/crypt586.asm
        new file mode 100644
        index 000000000..4c82c7a26
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/des/crypt586.asm
        @@ -0,0 +1,909 @@
        +TITLE	crypt586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +EXTERN	_DES_SPtrans:NEAR
        +ALIGN	16
        +_fcrypt_body	PROC PUBLIC
        +$L_fcrypt_body_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the 2 words
        +	xor	edi,edi
        +	xor	esi,esi
        +	lea	edx,DWORD PTR _DES_SPtrans
        +	push	edx
        +	mov	ebp,DWORD PTR 28[esp]
        +	push	25
        +$L000start:
        +	;
        +
        +	; Round 0
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR [ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 4[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 1
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 8[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 12[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 2
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 16[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 20[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 3
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 24[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 28[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 4
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 32[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 36[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 5
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 40[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 44[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 6
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 48[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 52[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 7
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 56[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 60[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 8
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 64[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 68[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 9
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 72[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 76[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 10
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 80[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 84[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 11
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 88[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 92[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 12
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 96[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 100[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 13
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 104[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 108[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 14
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,esi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,esi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 112[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 116[ebp]
        +	xor	eax,esi
        +	xor	edx,esi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	;
        +
        +	; Round 15
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	edx,edi
        +	shr	edx,16
        +	mov	ecx,DWORD PTR 40[esp]
        +	xor	edx,edi
        +	and	eax,edx
        +	and	edx,ecx
        +	mov	ebx,eax
        +	shl	ebx,16
        +	mov	ecx,edx
        +	shl	ecx,16
        +	xor	eax,ebx
        +	xor	edx,ecx
        +	mov	ebx,DWORD PTR 120[ebp]
        +	xor	eax,ebx
        +	mov	ecx,DWORD PTR 124[ebp]
        +	xor	eax,edi
        +	xor	edx,edi
        +	xor	edx,ecx
        +	and	eax,0fcfcfcfch
        +	xor	ebx,ebx
        +	and	edx,0cfcfcfcfh
        +	xor	ecx,ecx
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	mov	ebp,DWORD PTR 4[esp]
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	mov	ebx,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0700h[ecx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,ebx
        +	mov	ebx,DWORD PTR 0500h[edx*1+ebp]
        +	xor	esi,ebx
        +	mov	ebp,DWORD PTR 32[esp]
        +	mov	ebx,DWORD PTR [esp]
        +	mov	eax,edi
        +	dec	ebx
        +	mov	edi,esi
        +	mov	esi,eax
        +	mov	DWORD PTR [esp],ebx
        +	jnz	$L000start
        +	;
        +
        +	; FP
        +	mov	edx,DWORD PTR 28[esp]
        +	ror	edi,1
        +	mov	eax,esi
        +	xor	esi,edi
        +	and	esi,0aaaaaaaah
        +	xor	eax,esi
        +	xor	edi,esi
        +	;
        +
        +	rol	eax,23
        +	mov	esi,eax
        +	xor	eax,edi
        +	and	eax,003fc03fch
        +	xor	esi,eax
        +	xor	edi,eax
        +	;
        +
        +	rol	esi,10
        +	mov	eax,esi
        +	xor	esi,edi
        +	and	esi,033333333h
        +	xor	eax,esi
        +	xor	edi,esi
        +	;
        +
        +	rol	edi,18
        +	mov	esi,edi
        +	xor	edi,eax
        +	and	edi,0fff0000fh
        +	xor	esi,edi
        +	xor	eax,edi
        +	;
        +
        +	rol	esi,12
        +	mov	edi,esi
        +	xor	esi,eax
        +	and	esi,0f0f0f0f0h
        +	xor	edi,esi
        +	xor	eax,esi
        +	;
        +
        +	ror	eax,4
        +	mov	DWORD PTR [edx],eax
        +	mov	DWORD PTR 4[edx],edi
        +	add	esp,8
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_fcrypt_body ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/des/des-586.asm b/vendor/openssl/asm/x86-win32-masm/des/des-586.asm
        new file mode 100644
        index 000000000..24f19a660
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/des/des-586.asm
        @@ -0,0 +1,1878 @@
        +TITLE	des-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +PUBLIC	_DES_SPtrans
        +ALIGN	16
        +__x86_DES_encrypt	PROC PRIVATE
        +	push	ecx
        +	; Round 0
        +	mov	eax,DWORD PTR [ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 4[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 1
        +	mov	eax,DWORD PTR 8[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 12[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 2
        +	mov	eax,DWORD PTR 16[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 20[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 3
        +	mov	eax,DWORD PTR 24[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 28[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 4
        +	mov	eax,DWORD PTR 32[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 36[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 5
        +	mov	eax,DWORD PTR 40[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 44[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 6
        +	mov	eax,DWORD PTR 48[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 52[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 7
        +	mov	eax,DWORD PTR 56[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 60[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 8
        +	mov	eax,DWORD PTR 64[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 68[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 9
        +	mov	eax,DWORD PTR 72[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 76[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 10
        +	mov	eax,DWORD PTR 80[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 84[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 11
        +	mov	eax,DWORD PTR 88[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 92[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 12
        +	mov	eax,DWORD PTR 96[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 100[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 13
        +	mov	eax,DWORD PTR 104[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 108[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 14
        +	mov	eax,DWORD PTR 112[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 116[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 15
        +	mov	eax,DWORD PTR 120[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 124[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	add	esp,4
        +	ret
        +__x86_DES_encrypt ENDP
        +ALIGN	16
        +__x86_DES_decrypt	PROC PRIVATE
        +	push	ecx
        +	; Round 15
        +	mov	eax,DWORD PTR 120[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 124[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 14
        +	mov	eax,DWORD PTR 112[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 116[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 13
        +	mov	eax,DWORD PTR 104[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 108[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 12
        +	mov	eax,DWORD PTR 96[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 100[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 11
        +	mov	eax,DWORD PTR 88[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 92[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 10
        +	mov	eax,DWORD PTR 80[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 84[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 9
        +	mov	eax,DWORD PTR 72[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 76[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 8
        +	mov	eax,DWORD PTR 64[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 68[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 7
        +	mov	eax,DWORD PTR 56[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 60[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 6
        +	mov	eax,DWORD PTR 48[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 52[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 5
        +	mov	eax,DWORD PTR 40[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 44[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 4
        +	mov	eax,DWORD PTR 32[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 36[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 3
        +	mov	eax,DWORD PTR 24[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 28[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 2
        +	mov	eax,DWORD PTR 16[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 20[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 1
        +	mov	eax,DWORD PTR 8[ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 12[ecx]
        +	xor	eax,esi
        +	xor	ecx,ecx
        +	xor	edx,esi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	edi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	edi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	edi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	edi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	edi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	edi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	edi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	edi,DWORD PTR 0500h[edx*1+ebp]
        +	; Round 0
        +	mov	eax,DWORD PTR [ecx]
        +	xor	ebx,ebx
        +	mov	edx,DWORD PTR 4[ecx]
        +	xor	eax,edi
        +	xor	ecx,ecx
        +	xor	edx,edi
        +	and	eax,0fcfcfcfch
        +	and	edx,0cfcfcfcfh
        +	mov	bl,al
        +	mov	cl,ah
        +	ror	edx,4
        +	xor	esi,DWORD PTR [ebx*1+ebp]
        +	mov	bl,dl
        +	xor	esi,DWORD PTR 0200h[ecx*1+ebp]
        +	mov	cl,dh
        +	shr	eax,16
        +	xor	esi,DWORD PTR 0100h[ebx*1+ebp]
        +	mov	bl,ah
        +	shr	edx,16
        +	xor	esi,DWORD PTR 0300h[ecx*1+ebp]
        +	mov	cl,dh
        +	and	eax,0ffh
        +	and	edx,0ffh
        +	xor	esi,DWORD PTR 0600h[ebx*1+ebp]
        +	xor	esi,DWORD PTR 0700h[ecx*1+ebp]
        +	mov	ecx,DWORD PTR [esp]
        +	xor	esi,DWORD PTR 0400h[eax*1+ebp]
        +	xor	esi,DWORD PTR 0500h[edx*1+ebp]
        +	add	esp,4
        +	ret
        +__x86_DES_decrypt ENDP
        +ALIGN	16
        +_DES_encrypt1	PROC PUBLIC
        +$L_DES_encrypt1_begin::
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the 2 words
        +	mov	esi,DWORD PTR 12[esp]
        +	xor	ecx,ecx
        +	push	ebx
        +	push	ebp
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 28[esp]
        +	mov	edi,DWORD PTR 4[esi]
        +	;
        +
        +	; IP
        +	rol	eax,4
        +	mov	esi,eax
        +	xor	eax,edi
        +	and	eax,0f0f0f0f0h
        +	xor	esi,eax
        +	xor	edi,eax
        +	;
        +
        +	rol	edi,20
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,0fff0000fh
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	eax,14
        +	mov	edi,eax
        +	xor	eax,esi
        +	and	eax,033333333h
        +	xor	edi,eax
        +	xor	esi,eax
        +	;
        +
        +	rol	esi,22
        +	mov	eax,esi
        +	xor	esi,edi
        +	and	esi,003fc03fch
        +	xor	eax,esi
        +	xor	edi,esi
        +	;
        +
        +	rol	eax,9
        +	mov	esi,eax
        +	xor	eax,edi
        +	and	eax,0aaaaaaaah
        +	xor	esi,eax
        +	xor	edi,eax
        +	;
        +
        +	rol	edi,1
        +	call	$L000pic_point
        +$L000pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR (_DES_SPtrans-$L000pic_point)[ebp]
        +	mov	ecx,DWORD PTR 24[esp]
        +	cmp	ebx,0
        +	je	$L001decrypt
        +	call	__x86_DES_encrypt
        +	jmp	$L002done
        +$L001decrypt:
        +	call	__x86_DES_decrypt
        +$L002done:
        +	;
        +
        +	; FP
        +	mov	edx,DWORD PTR 20[esp]
        +	ror	esi,1
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,0aaaaaaaah
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	eax,23
        +	mov	edi,eax
        +	xor	eax,esi
        +	and	eax,003fc03fch
        +	xor	edi,eax
        +	xor	esi,eax
        +	;
        +
        +	rol	edi,10
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,033333333h
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	esi,18
        +	mov	edi,esi
        +	xor	esi,eax
        +	and	esi,0fff0000fh
        +	xor	edi,esi
        +	xor	eax,esi
        +	;
        +
        +	rol	edi,12
        +	mov	esi,edi
        +	xor	edi,eax
        +	and	edi,0f0f0f0f0h
        +	xor	esi,edi
        +	xor	eax,edi
        +	;
        +
        +	ror	eax,4
        +	mov	DWORD PTR [edx],eax
        +	mov	DWORD PTR 4[edx],esi
        +	pop	ebp
        +	pop	ebx
        +	pop	edi
        +	pop	esi
        +	ret
        +_DES_encrypt1 ENDP
        +ALIGN	16
        +_DES_encrypt2	PROC PUBLIC
        +$L_DES_encrypt2_begin::
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the 2 words
        +	mov	eax,DWORD PTR 12[esp]
        +	xor	ecx,ecx
        +	push	ebx
        +	push	ebp
        +	mov	esi,DWORD PTR [eax]
        +	mov	ebx,DWORD PTR 28[esp]
        +	rol	esi,3
        +	mov	edi,DWORD PTR 4[eax]
        +	rol	edi,3
        +	call	$L003pic_point
        +$L003pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR (_DES_SPtrans-$L003pic_point)[ebp]
        +	mov	ecx,DWORD PTR 24[esp]
        +	cmp	ebx,0
        +	je	$L004decrypt
        +	call	__x86_DES_encrypt
        +	jmp	$L005done
        +$L004decrypt:
        +	call	__x86_DES_decrypt
        +$L005done:
        +	;
        +
        +	; Fixup
        +	ror	edi,3
        +	mov	eax,DWORD PTR 20[esp]
        +	ror	esi,3
        +	mov	DWORD PTR [eax],edi
        +	mov	DWORD PTR 4[eax],esi
        +	pop	ebp
        +	pop	ebx
        +	pop	edi
        +	pop	esi
        +	ret
        +_DES_encrypt2 ENDP
        +ALIGN	16
        +_DES_encrypt3	PROC PUBLIC
        +$L_DES_encrypt3_begin::
        +	push	ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	push	ebp
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the data words
        +	mov	edi,DWORD PTR [ebx]
        +	mov	esi,DWORD PTR 4[ebx]
        +	sub	esp,12
        +	;
        +
        +	; IP
        +	rol	edi,4
        +	mov	edx,edi
        +	xor	edi,esi
        +	and	edi,0f0f0f0f0h
        +	xor	edx,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	esi,20
        +	mov	edi,esi
        +	xor	esi,edx
        +	and	esi,0fff0000fh
        +	xor	edi,esi
        +	xor	edx,esi
        +	;
        +
        +	rol	edi,14
        +	mov	esi,edi
        +	xor	edi,edx
        +	and	edi,033333333h
        +	xor	esi,edi
        +	xor	edx,edi
        +	;
        +
        +	rol	edx,22
        +	mov	edi,edx
        +	xor	edx,esi
        +	and	edx,003fc03fch
        +	xor	edi,edx
        +	xor	esi,edx
        +	;
        +
        +	rol	edi,9
        +	mov	edx,edi
        +	xor	edi,esi
        +	and	edi,0aaaaaaaah
        +	xor	edx,edi
        +	xor	esi,edi
        +	;
        +
        +	ror	edx,3
        +	ror	esi,2
        +	mov	DWORD PTR 4[ebx],esi
        +	mov	eax,DWORD PTR 36[esp]
        +	mov	DWORD PTR [ebx],edx
        +	mov	edi,DWORD PTR 40[esp]
        +	mov	esi,DWORD PTR 44[esp]
        +	mov	DWORD PTR 8[esp],1
        +	mov	DWORD PTR 4[esp],eax
        +	mov	DWORD PTR [esp],ebx
        +	call	$L_DES_encrypt2_begin
        +	mov	DWORD PTR 8[esp],0
        +	mov	DWORD PTR 4[esp],edi
        +	mov	DWORD PTR [esp],ebx
        +	call	$L_DES_encrypt2_begin
        +	mov	DWORD PTR 8[esp],1
        +	mov	DWORD PTR 4[esp],esi
        +	mov	DWORD PTR [esp],ebx
        +	call	$L_DES_encrypt2_begin
        +	add	esp,12
        +	mov	edi,DWORD PTR [ebx]
        +	mov	esi,DWORD PTR 4[ebx]
        +	;
        +
        +	; FP
        +	rol	esi,2
        +	rol	edi,3
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,0aaaaaaaah
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	eax,23
        +	mov	edi,eax
        +	xor	eax,esi
        +	and	eax,003fc03fch
        +	xor	edi,eax
        +	xor	esi,eax
        +	;
        +
        +	rol	edi,10
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,033333333h
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	esi,18
        +	mov	edi,esi
        +	xor	esi,eax
        +	and	esi,0fff0000fh
        +	xor	edi,esi
        +	xor	eax,esi
        +	;
        +
        +	rol	edi,12
        +	mov	esi,edi
        +	xor	edi,eax
        +	and	edi,0f0f0f0f0h
        +	xor	esi,edi
        +	xor	eax,edi
        +	;
        +
        +	ror	eax,4
        +	mov	DWORD PTR [ebx],eax
        +	mov	DWORD PTR 4[ebx],esi
        +	pop	edi
        +	pop	esi
        +	pop	ebp
        +	pop	ebx
        +	ret
        +_DES_encrypt3 ENDP
        +ALIGN	16
        +_DES_decrypt3	PROC PUBLIC
        +$L_DES_decrypt3_begin::
        +	push	ebx
        +	mov	ebx,DWORD PTR 8[esp]
        +	push	ebp
        +	push	esi
        +	push	edi
        +	;
        +
        +	; Load the data words
        +	mov	edi,DWORD PTR [ebx]
        +	mov	esi,DWORD PTR 4[ebx]
        +	sub	esp,12
        +	;
        +
        +	; IP
        +	rol	edi,4
        +	mov	edx,edi
        +	xor	edi,esi
        +	and	edi,0f0f0f0f0h
        +	xor	edx,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	esi,20
        +	mov	edi,esi
        +	xor	esi,edx
        +	and	esi,0fff0000fh
        +	xor	edi,esi
        +	xor	edx,esi
        +	;
        +
        +	rol	edi,14
        +	mov	esi,edi
        +	xor	edi,edx
        +	and	edi,033333333h
        +	xor	esi,edi
        +	xor	edx,edi
        +	;
        +
        +	rol	edx,22
        +	mov	edi,edx
        +	xor	edx,esi
        +	and	edx,003fc03fch
        +	xor	edi,edx
        +	xor	esi,edx
        +	;
        +
        +	rol	edi,9
        +	mov	edx,edi
        +	xor	edi,esi
        +	and	edi,0aaaaaaaah
        +	xor	edx,edi
        +	xor	esi,edi
        +	;
        +
        +	ror	edx,3
        +	ror	esi,2
        +	mov	DWORD PTR 4[ebx],esi
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	DWORD PTR [ebx],edx
        +	mov	edi,DWORD PTR 40[esp]
        +	mov	eax,DWORD PTR 44[esp]
        +	mov	DWORD PTR 8[esp],0
        +	mov	DWORD PTR 4[esp],eax
        +	mov	DWORD PTR [esp],ebx
        +	call	$L_DES_encrypt2_begin
        +	mov	DWORD PTR 8[esp],1
        +	mov	DWORD PTR 4[esp],edi
        +	mov	DWORD PTR [esp],ebx
        +	call	$L_DES_encrypt2_begin
        +	mov	DWORD PTR 8[esp],0
        +	mov	DWORD PTR 4[esp],esi
        +	mov	DWORD PTR [esp],ebx
        +	call	$L_DES_encrypt2_begin
        +	add	esp,12
        +	mov	edi,DWORD PTR [ebx]
        +	mov	esi,DWORD PTR 4[ebx]
        +	;
        +
        +	; FP
        +	rol	esi,2
        +	rol	edi,3
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,0aaaaaaaah
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	eax,23
        +	mov	edi,eax
        +	xor	eax,esi
        +	and	eax,003fc03fch
        +	xor	edi,eax
        +	xor	esi,eax
        +	;
        +
        +	rol	edi,10
        +	mov	eax,edi
        +	xor	edi,esi
        +	and	edi,033333333h
        +	xor	eax,edi
        +	xor	esi,edi
        +	;
        +
        +	rol	esi,18
        +	mov	edi,esi
        +	xor	esi,eax
        +	and	esi,0fff0000fh
        +	xor	edi,esi
        +	xor	eax,esi
        +	;
        +
        +	rol	edi,12
        +	mov	esi,edi
        +	xor	edi,eax
        +	and	edi,0f0f0f0f0h
        +	xor	esi,edi
        +	xor	eax,edi
        +	;
        +
        +	ror	eax,4
        +	mov	DWORD PTR [ebx],eax
        +	mov	DWORD PTR 4[ebx],esi
        +	pop	edi
        +	pop	esi
        +	pop	ebp
        +	pop	ebx
        +	ret
        +_DES_decrypt3 ENDP
        +ALIGN	16
        +_DES_ncbc_encrypt	PROC PUBLIC
        +$L_DES_ncbc_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ebp,DWORD PTR 28[esp]
        +	; getting iv ptr from parameter 4
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR [ebx]
        +	mov	edi,DWORD PTR 4[ebx]
        +	push	edi
        +	push	esi
        +	push	edi
        +	push	esi
        +	mov	ebx,esp
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	; getting encrypt flag from parameter 5
        +	mov	ecx,DWORD PTR 56[esp]
        +	; get and push parameter 5
        +	push	ecx
        +	; get and push parameter 3
        +	mov	eax,DWORD PTR 52[esp]
        +	push	eax
        +	push	ebx
        +	cmp	ecx,0
        +	jz	$L006decrypt
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	jz	$L007encrypt_finish
        +$L008encrypt_loop:
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR 4[esi]
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	mov	DWORD PTR 12[esp],eax
        +	mov	DWORD PTR 16[esp],ebx
        +	call	$L_DES_encrypt1_begin
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L008encrypt_loop
        +$L007encrypt_finish:
        +	mov	ebp,DWORD PTR 56[esp]
        +	and	ebp,7
        +	jz	$L009finish
        +	call	$L010PIC_point
        +$L010PIC_point:
        +	pop	edx
        +	lea	ecx,DWORD PTR ($L011cbc_enc_jmp_table-$L010PIC_point)[edx]
        +	mov	ebp,DWORD PTR [ebp*4+ecx]
        +	add	ebp,edx
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	jmp	ebp
        +$L012ej7:
        +	mov	dh,BYTE PTR 6[esi]
        +	shl	edx,8
        +$L013ej6:
        +	mov	dh,BYTE PTR 5[esi]
        +$L014ej5:
        +	mov	dl,BYTE PTR 4[esi]
        +$L015ej4:
        +	mov	ecx,DWORD PTR [esi]
        +	jmp	$L016ejend
        +$L017ej3:
        +	mov	ch,BYTE PTR 2[esi]
        +	shl	ecx,8
        +$L018ej2:
        +	mov	ch,BYTE PTR 1[esi]
        +$L019ej1:
        +	mov	cl,BYTE PTR [esi]
        +$L016ejend:
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	mov	DWORD PTR 12[esp],eax
        +	mov	DWORD PTR 16[esp],ebx
        +	call	$L_DES_encrypt1_begin
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	jmp	$L009finish
        +$L006decrypt:
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	ebx,DWORD PTR 24[esp]
        +	jz	$L020decrypt_finish
        +$L021decrypt_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR 12[esp],eax
        +	mov	DWORD PTR 16[esp],ebx
        +	call	$L_DES_encrypt1_begin
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	mov	ecx,DWORD PTR 20[esp]
        +	mov	edx,DWORD PTR 24[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR [edi],ecx
        +	mov	DWORD PTR 4[edi],edx
        +	mov	DWORD PTR 20[esp],eax
        +	mov	DWORD PTR 24[esp],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L021decrypt_loop
        +$L020decrypt_finish:
        +	mov	ebp,DWORD PTR 56[esp]
        +	and	ebp,7
        +	jz	$L009finish
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR 12[esp],eax
        +	mov	DWORD PTR 16[esp],ebx
        +	call	$L_DES_encrypt1_begin
        +	mov	eax,DWORD PTR 12[esp]
        +	mov	ebx,DWORD PTR 16[esp]
        +	mov	ecx,DWORD PTR 20[esp]
        +	mov	edx,DWORD PTR 24[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +$L022dj7:
        +	ror	edx,16
        +	mov	BYTE PTR 6[edi],dl
        +	shr	edx,16
        +$L023dj6:
        +	mov	BYTE PTR 5[edi],dh
        +$L024dj5:
        +	mov	BYTE PTR 4[edi],dl
        +$L025dj4:
        +	mov	DWORD PTR [edi],ecx
        +	jmp	$L026djend
        +$L027dj3:
        +	ror	ecx,16
        +	mov	BYTE PTR 2[edi],cl
        +	shl	ecx,16
        +$L028dj2:
        +	mov	BYTE PTR 1[esi],ch
        +$L029dj1:
        +	mov	BYTE PTR [esi],cl
        +$L026djend:
        +	jmp	$L009finish
        +$L009finish:
        +	mov	ecx,DWORD PTR 64[esp]
        +	add	esp,28
        +	mov	DWORD PTR [ecx],eax
        +	mov	DWORD PTR 4[ecx],ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L011cbc_enc_jmp_table:
        +DD	0
        +DD	$L019ej1-$L010PIC_point
        +DD	$L018ej2-$L010PIC_point
        +DD	$L017ej3-$L010PIC_point
        +DD	$L015ej4-$L010PIC_point
        +DD	$L014ej5-$L010PIC_point
        +DD	$L013ej6-$L010PIC_point
        +DD	$L012ej7-$L010PIC_point
        +ALIGN	64
        +_DES_ncbc_encrypt ENDP
        +ALIGN	16
        +_DES_ede3_cbc_encrypt	PROC PUBLIC
        +$L_DES_ede3_cbc_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ebp,DWORD PTR 28[esp]
        +	; getting iv ptr from parameter 6
        +	mov	ebx,DWORD PTR 44[esp]
        +	mov	esi,DWORD PTR [ebx]
        +	mov	edi,DWORD PTR 4[ebx]
        +	push	edi
        +	push	esi
        +	push	edi
        +	push	esi
        +	mov	ebx,esp
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	; getting encrypt flag from parameter 7
        +	mov	ecx,DWORD PTR 64[esp]
        +	; get and push parameter 5
        +	mov	eax,DWORD PTR 56[esp]
        +	push	eax
        +	; get and push parameter 4
        +	mov	eax,DWORD PTR 56[esp]
        +	push	eax
        +	; get and push parameter 3
        +	mov	eax,DWORD PTR 56[esp]
        +	push	eax
        +	push	ebx
        +	cmp	ecx,0
        +	jz	$L030decrypt
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	jz	$L031encrypt_finish
        +$L032encrypt_loop:
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR 4[esi]
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	call	$L_DES_encrypt3_begin
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L032encrypt_loop
        +$L031encrypt_finish:
        +	mov	ebp,DWORD PTR 60[esp]
        +	and	ebp,7
        +	jz	$L033finish
        +	call	$L034PIC_point
        +$L034PIC_point:
        +	pop	edx
        +	lea	ecx,DWORD PTR ($L035cbc_enc_jmp_table-$L034PIC_point)[edx]
        +	mov	ebp,DWORD PTR [ebp*4+ecx]
        +	add	ebp,edx
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	jmp	ebp
        +$L036ej7:
        +	mov	dh,BYTE PTR 6[esi]
        +	shl	edx,8
        +$L037ej6:
        +	mov	dh,BYTE PTR 5[esi]
        +$L038ej5:
        +	mov	dl,BYTE PTR 4[esi]
        +$L039ej4:
        +	mov	ecx,DWORD PTR [esi]
        +	jmp	$L040ejend
        +$L041ej3:
        +	mov	ch,BYTE PTR 2[esi]
        +	shl	ecx,8
        +$L042ej2:
        +	mov	ch,BYTE PTR 1[esi]
        +$L043ej1:
        +	mov	cl,BYTE PTR [esi]
        +$L040ejend:
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	call	$L_DES_encrypt3_begin
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	jmp	$L033finish
        +$L030decrypt:
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 24[esp]
        +	mov	ebx,DWORD PTR 28[esp]
        +	jz	$L044decrypt_finish
        +$L045decrypt_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	call	$L_DES_decrypt3_begin
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	mov	ecx,DWORD PTR 24[esp]
        +	mov	edx,DWORD PTR 28[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR [edi],ecx
        +	mov	DWORD PTR 4[edi],edx
        +	mov	DWORD PTR 24[esp],eax
        +	mov	DWORD PTR 28[esp],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L045decrypt_loop
        +$L044decrypt_finish:
        +	mov	ebp,DWORD PTR 60[esp]
        +	and	ebp,7
        +	jz	$L033finish
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	call	$L_DES_decrypt3_begin
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	mov	ecx,DWORD PTR 24[esp]
        +	mov	edx,DWORD PTR 28[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +$L046dj7:
        +	ror	edx,16
        +	mov	BYTE PTR 6[edi],dl
        +	shr	edx,16
        +$L047dj6:
        +	mov	BYTE PTR 5[edi],dh
        +$L048dj5:
        +	mov	BYTE PTR 4[edi],dl
        +$L049dj4:
        +	mov	DWORD PTR [edi],ecx
        +	jmp	$L050djend
        +$L051dj3:
        +	ror	ecx,16
        +	mov	BYTE PTR 2[edi],cl
        +	shl	ecx,16
        +$L052dj2:
        +	mov	BYTE PTR 1[esi],ch
        +$L053dj1:
        +	mov	BYTE PTR [esi],cl
        +$L050djend:
        +	jmp	$L033finish
        +$L033finish:
        +	mov	ecx,DWORD PTR 76[esp]
        +	add	esp,32
        +	mov	DWORD PTR [ecx],eax
        +	mov	DWORD PTR 4[ecx],ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L035cbc_enc_jmp_table:
        +DD	0
        +DD	$L043ej1-$L034PIC_point
        +DD	$L042ej2-$L034PIC_point
        +DD	$L041ej3-$L034PIC_point
        +DD	$L039ej4-$L034PIC_point
        +DD	$L038ej5-$L034PIC_point
        +DD	$L037ej6-$L034PIC_point
        +DD	$L036ej7-$L034PIC_point
        +ALIGN	64
        +_DES_ede3_cbc_encrypt ENDP
        +ALIGN	64
        +_DES_SPtrans::
        +DD	34080768,524288,33554434,34080770
        +DD	33554432,526338,524290,33554434
        +DD	526338,34080768,34078720,2050
        +DD	33556482,33554432,0,524290
        +DD	524288,2,33556480,526336
        +DD	34080770,34078720,2050,33556480
        +DD	2,2048,526336,34078722
        +DD	2048,33556482,34078722,0
        +DD	0,34080770,33556480,524290
        +DD	34080768,524288,2050,33556480
        +DD	34078722,2048,526336,33554434
        +DD	526338,2,33554434,34078720
        +DD	34080770,526336,34078720,33556482
        +DD	33554432,2050,524290,0
        +DD	524288,33554432,33556482,34080768
        +DD	2,34078722,2048,526338
        +DD	1074823184,0,1081344,1074790400
        +DD	1073741840,32784,1073774592,1081344
        +DD	32768,1074790416,16,1073774592
        +DD	1048592,1074823168,1074790400,16
        +DD	1048576,1073774608,1074790416,32768
        +DD	1081360,1073741824,0,1048592
        +DD	1073774608,1081360,1074823168,1073741840
        +DD	1073741824,1048576,32784,1074823184
        +DD	1048592,1074823168,1073774592,1081360
        +DD	1074823184,1048592,1073741840,0
        +DD	1073741824,32784,1048576,1074790416
        +DD	32768,1073741824,1081360,1073774608
        +DD	1074823168,32768,0,1073741840
        +DD	16,1074823184,1081344,1074790400
        +DD	1074790416,1048576,32784,1073774592
        +DD	1073774608,16,1074790400,1081344
        +DD	67108865,67371264,256,67109121
        +DD	262145,67108864,67109121,262400
        +DD	67109120,262144,67371008,1
        +DD	67371265,257,1,67371009
        +DD	0,262145,67371264,256
        +DD	257,67371265,262144,67108865
        +DD	67371009,67109120,262401,67371008
        +DD	262400,0,67108864,262401
        +DD	67371264,256,1,262144
        +DD	257,262145,67371008,67109121
        +DD	0,67371264,262400,67371009
        +DD	262145,67108864,67371265,1
        +DD	262401,67108865,67108864,67371265
        +DD	262144,67109120,67109121,262400
        +DD	67109120,0,67371009,257
        +DD	67108865,262401,256,67371008
        +DD	4198408,268439552,8,272633864
        +DD	0,272629760,268439560,4194312
        +DD	272633856,268435464,268435456,4104
        +DD	268435464,4198408,4194304,268435456
        +DD	272629768,4198400,4096,8
        +DD	4198400,268439560,272629760,4096
        +DD	4104,0,4194312,272633856
        +DD	268439552,272629768,272633864,4194304
        +DD	272629768,4104,4194304,268435464
        +DD	4198400,268439552,8,272629760
        +DD	268439560,0,4096,4194312
        +DD	0,272629768,272633856,4096
        +DD	268435456,272633864,4198408,4194304
        +DD	272633864,8,268439552,4198408
        +DD	4194312,4198400,272629760,268439560
        +DD	4104,268435456,268435464,272633856
        +DD	134217728,65536,1024,134284320
        +DD	134283296,134218752,66592,134283264
        +DD	65536,32,134217760,66560
        +DD	134218784,134283296,134284288,0
        +DD	66560,134217728,65568,1056
        +DD	134218752,66592,0,134217760
        +DD	32,134218784,134284320,65568
        +DD	134283264,1024,1056,134284288
        +DD	134284288,134218784,65568,134283264
        +DD	65536,32,134217760,134218752
        +DD	134217728,66560,134284320,0
        +DD	66592,134217728,1024,65568
        +DD	134218784,1024,0,134284320
        +DD	134283296,134284288,1056,65536
        +DD	66560,134283296,134218752,1056
        +DD	32,66592,134283264,134217760
        +DD	2147483712,2097216,0,2149588992
        +DD	2097216,8192,2147491904,2097152
        +DD	8256,2149589056,2105344,2147483648
        +DD	2147491840,2147483712,2149580800,2105408
        +DD	2097152,2147491904,2149580864,0
        +DD	8192,64,2149588992,2149580864
        +DD	2149589056,2149580800,2147483648,8256
        +DD	64,2105344,2105408,2147491840
        +DD	8256,2147483648,2147491840,2105408
        +DD	2149588992,2097216,0,2147491840
        +DD	2147483648,8192,2149580864,2097152
        +DD	2097216,2149589056,2105344,64
        +DD	2149589056,2105344,2097152,2147491904
        +DD	2147483712,2149580800,2105408,0
        +DD	8192,2147483712,2147491904,2149588992
        +DD	2149580800,8256,64,2149580864
        +DD	16384,512,16777728,16777220
        +DD	16794116,16388,16896,0
        +DD	16777216,16777732,516,16793600
        +DD	4,16794112,16793600,516
        +DD	16777732,16384,16388,16794116
        +DD	0,16777728,16777220,16896
        +DD	16793604,16900,16794112,4
        +DD	16900,16793604,512,16777216
        +DD	16900,16793600,16793604,516
        +DD	16384,512,16777216,16793604
        +DD	16777732,16900,16896,0
        +DD	512,16777220,4,16777728
        +DD	0,16777732,16777728,16896
        +DD	516,16384,16794116,16777216
        +DD	16794112,4,16388,16794116
        +DD	16777220,16794112,16793600,16388
        +DD	545259648,545390592,131200,0
        +DD	537001984,8388736,545259520,545390720
        +DD	128,536870912,8519680,131200
        +DD	8519808,537002112,536871040,545259520
        +DD	131072,8519808,8388736,537001984
        +DD	545390720,536871040,0,8519680
        +DD	536870912,8388608,537002112,545259648
        +DD	8388608,131072,545390592,128
        +DD	8388608,131072,536871040,545390720
        +DD	131200,536870912,0,8519680
        +DD	545259648,537002112,537001984,8388736
        +DD	545390592,128,8388736,537001984
        +DD	545390720,8388608,545259520,536871040
        +DD	8519680,131200,537002112,545259520
        +DD	128,545390592,8519808,0
        +DD	536870912,545259648,131072,8519808
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/md5/md5-586.asm b/vendor/openssl/asm/x86-win32-masm/md5/md5-586.asm
        new file mode 100644
        index 000000000..8e263de0f
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/md5/md5-586.asm
        @@ -0,0 +1,693 @@
        +TITLE	../openssl/crypto/md5/asm/md5-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_md5_block_asm_data_order	PROC PUBLIC
        +$L_md5_block_asm_data_order_begin::
        +	push	esi
        +	push	edi
        +	mov	edi,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 16[esp]
        +	mov	ecx,DWORD PTR 20[esp]
        +	push	ebp
        +	shl	ecx,6
        +	push	ebx
        +	add	ecx,esi
        +	sub	ecx,64
        +	mov	eax,DWORD PTR [edi]
        +	push	ecx
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +$L000start:
        +	;
        +
        +	; R0 section
        +	mov	edi,ecx
        +	mov	ebp,DWORD PTR [esi]
        +	; R0 0
        +	xor	edi,edx
        +	and	edi,ebx
        +	lea	eax,DWORD PTR 3614090360[ebp*1+eax]
        +	xor	edi,edx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,7
        +	mov	ebp,DWORD PTR 4[esi]
        +	add	eax,ebx
        +	; R0 1
        +	xor	edi,ecx
        +	and	edi,eax
        +	lea	edx,DWORD PTR 3905402710[ebp*1+edx]
        +	xor	edi,ecx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,12
        +	mov	ebp,DWORD PTR 8[esi]
        +	add	edx,eax
        +	; R0 2
        +	xor	edi,ebx
        +	and	edi,edx
        +	lea	ecx,DWORD PTR 606105819[ebp*1+ecx]
        +	xor	edi,ebx
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,17
        +	mov	ebp,DWORD PTR 12[esi]
        +	add	ecx,edx
        +	; R0 3
        +	xor	edi,eax
        +	and	edi,ecx
        +	lea	ebx,DWORD PTR 3250441966[ebp*1+ebx]
        +	xor	edi,eax
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,22
        +	mov	ebp,DWORD PTR 16[esi]
        +	add	ebx,ecx
        +	; R0 4
        +	xor	edi,edx
        +	and	edi,ebx
        +	lea	eax,DWORD PTR 4118548399[ebp*1+eax]
        +	xor	edi,edx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,7
        +	mov	ebp,DWORD PTR 20[esi]
        +	add	eax,ebx
        +	; R0 5
        +	xor	edi,ecx
        +	and	edi,eax
        +	lea	edx,DWORD PTR 1200080426[ebp*1+edx]
        +	xor	edi,ecx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,12
        +	mov	ebp,DWORD PTR 24[esi]
        +	add	edx,eax
        +	; R0 6
        +	xor	edi,ebx
        +	and	edi,edx
        +	lea	ecx,DWORD PTR 2821735955[ebp*1+ecx]
        +	xor	edi,ebx
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,17
        +	mov	ebp,DWORD PTR 28[esi]
        +	add	ecx,edx
        +	; R0 7
        +	xor	edi,eax
        +	and	edi,ecx
        +	lea	ebx,DWORD PTR 4249261313[ebp*1+ebx]
        +	xor	edi,eax
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,22
        +	mov	ebp,DWORD PTR 32[esi]
        +	add	ebx,ecx
        +	; R0 8
        +	xor	edi,edx
        +	and	edi,ebx
        +	lea	eax,DWORD PTR 1770035416[ebp*1+eax]
        +	xor	edi,edx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,7
        +	mov	ebp,DWORD PTR 36[esi]
        +	add	eax,ebx
        +	; R0 9
        +	xor	edi,ecx
        +	and	edi,eax
        +	lea	edx,DWORD PTR 2336552879[ebp*1+edx]
        +	xor	edi,ecx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,12
        +	mov	ebp,DWORD PTR 40[esi]
        +	add	edx,eax
        +	; R0 10
        +	xor	edi,ebx
        +	and	edi,edx
        +	lea	ecx,DWORD PTR 4294925233[ebp*1+ecx]
        +	xor	edi,ebx
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,17
        +	mov	ebp,DWORD PTR 44[esi]
        +	add	ecx,edx
        +	; R0 11
        +	xor	edi,eax
        +	and	edi,ecx
        +	lea	ebx,DWORD PTR 2304563134[ebp*1+ebx]
        +	xor	edi,eax
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,22
        +	mov	ebp,DWORD PTR 48[esi]
        +	add	ebx,ecx
        +	; R0 12
        +	xor	edi,edx
        +	and	edi,ebx
        +	lea	eax,DWORD PTR 1804603682[ebp*1+eax]
        +	xor	edi,edx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,7
        +	mov	ebp,DWORD PTR 52[esi]
        +	add	eax,ebx
        +	; R0 13
        +	xor	edi,ecx
        +	and	edi,eax
        +	lea	edx,DWORD PTR 4254626195[ebp*1+edx]
        +	xor	edi,ecx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,12
        +	mov	ebp,DWORD PTR 56[esi]
        +	add	edx,eax
        +	; R0 14
        +	xor	edi,ebx
        +	and	edi,edx
        +	lea	ecx,DWORD PTR 2792965006[ebp*1+ecx]
        +	xor	edi,ebx
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,17
        +	mov	ebp,DWORD PTR 60[esi]
        +	add	ecx,edx
        +	; R0 15
        +	xor	edi,eax
        +	and	edi,ecx
        +	lea	ebx,DWORD PTR 1236535329[ebp*1+ebx]
        +	xor	edi,eax
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,22
        +	mov	ebp,DWORD PTR 4[esi]
        +	add	ebx,ecx
        +	;
        +
        +	; R1 section
        +	; R1 16
        +	lea	eax,DWORD PTR 4129170786[ebp*1+eax]
        +	xor	edi,ebx
        +	and	edi,edx
        +	mov	ebp,DWORD PTR 24[esi]
        +	xor	edi,ecx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,5
        +	add	eax,ebx
        +	; R1 17
        +	lea	edx,DWORD PTR 3225465664[ebp*1+edx]
        +	xor	edi,eax
        +	and	edi,ecx
        +	mov	ebp,DWORD PTR 44[esi]
        +	xor	edi,ebx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,9
        +	add	edx,eax
        +	; R1 18
        +	lea	ecx,DWORD PTR 643717713[ebp*1+ecx]
        +	xor	edi,edx
        +	and	edi,ebx
        +	mov	ebp,DWORD PTR [esi]
        +	xor	edi,eax
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,14
        +	add	ecx,edx
        +	; R1 19
        +	lea	ebx,DWORD PTR 3921069994[ebp*1+ebx]
        +	xor	edi,ecx
        +	and	edi,eax
        +	mov	ebp,DWORD PTR 20[esi]
        +	xor	edi,edx
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	; R1 20
        +	lea	eax,DWORD PTR 3593408605[ebp*1+eax]
        +	xor	edi,ebx
        +	and	edi,edx
        +	mov	ebp,DWORD PTR 40[esi]
        +	xor	edi,ecx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,5
        +	add	eax,ebx
        +	; R1 21
        +	lea	edx,DWORD PTR 38016083[ebp*1+edx]
        +	xor	edi,eax
        +	and	edi,ecx
        +	mov	ebp,DWORD PTR 60[esi]
        +	xor	edi,ebx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,9
        +	add	edx,eax
        +	; R1 22
        +	lea	ecx,DWORD PTR 3634488961[ebp*1+ecx]
        +	xor	edi,edx
        +	and	edi,ebx
        +	mov	ebp,DWORD PTR 16[esi]
        +	xor	edi,eax
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,14
        +	add	ecx,edx
        +	; R1 23
        +	lea	ebx,DWORD PTR 3889429448[ebp*1+ebx]
        +	xor	edi,ecx
        +	and	edi,eax
        +	mov	ebp,DWORD PTR 36[esi]
        +	xor	edi,edx
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	; R1 24
        +	lea	eax,DWORD PTR 568446438[ebp*1+eax]
        +	xor	edi,ebx
        +	and	edi,edx
        +	mov	ebp,DWORD PTR 56[esi]
        +	xor	edi,ecx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,5
        +	add	eax,ebx
        +	; R1 25
        +	lea	edx,DWORD PTR 3275163606[ebp*1+edx]
        +	xor	edi,eax
        +	and	edi,ecx
        +	mov	ebp,DWORD PTR 12[esi]
        +	xor	edi,ebx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,9
        +	add	edx,eax
        +	; R1 26
        +	lea	ecx,DWORD PTR 4107603335[ebp*1+ecx]
        +	xor	edi,edx
        +	and	edi,ebx
        +	mov	ebp,DWORD PTR 32[esi]
        +	xor	edi,eax
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,14
        +	add	ecx,edx
        +	; R1 27
        +	lea	ebx,DWORD PTR 1163531501[ebp*1+ebx]
        +	xor	edi,ecx
        +	and	edi,eax
        +	mov	ebp,DWORD PTR 52[esi]
        +	xor	edi,edx
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	; R1 28
        +	lea	eax,DWORD PTR 2850285829[ebp*1+eax]
        +	xor	edi,ebx
        +	and	edi,edx
        +	mov	ebp,DWORD PTR 8[esi]
        +	xor	edi,ecx
        +	add	eax,edi
        +	mov	edi,ebx
        +	rol	eax,5
        +	add	eax,ebx
        +	; R1 29
        +	lea	edx,DWORD PTR 4243563512[ebp*1+edx]
        +	xor	edi,eax
        +	and	edi,ecx
        +	mov	ebp,DWORD PTR 28[esi]
        +	xor	edi,ebx
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,9
        +	add	edx,eax
        +	; R1 30
        +	lea	ecx,DWORD PTR 1735328473[ebp*1+ecx]
        +	xor	edi,edx
        +	and	edi,ebx
        +	mov	ebp,DWORD PTR 48[esi]
        +	xor	edi,eax
        +	add	ecx,edi
        +	mov	edi,edx
        +	rol	ecx,14
        +	add	ecx,edx
        +	; R1 31
        +	lea	ebx,DWORD PTR 2368359562[ebp*1+ebx]
        +	xor	edi,ecx
        +	and	edi,eax
        +	mov	ebp,DWORD PTR 20[esi]
        +	xor	edi,edx
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,20
        +	add	ebx,ecx
        +	;
        +
        +	; R2 section
        +	; R2 32
        +	xor	edi,edx
        +	xor	edi,ebx
        +	lea	eax,DWORD PTR 4294588738[ebp*1+eax]
        +	add	eax,edi
        +	rol	eax,4
        +	mov	ebp,DWORD PTR 32[esi]
        +	mov	edi,ebx
        +	; R2 33
        +	lea	edx,DWORD PTR 2272392833[ebp*1+edx]
        +	add	eax,ebx
        +	xor	edi,ecx
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 44[esi]
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,11
        +	add	edx,eax
        +	; R2 34
        +	xor	edi,ebx
        +	xor	edi,edx
        +	lea	ecx,DWORD PTR 1839030562[ebp*1+ecx]
        +	add	ecx,edi
        +	rol	ecx,16
        +	mov	ebp,DWORD PTR 56[esi]
        +	mov	edi,edx
        +	; R2 35
        +	lea	ebx,DWORD PTR 4259657740[ebp*1+ebx]
        +	add	ecx,edx
        +	xor	edi,eax
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 4[esi]
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,23
        +	add	ebx,ecx
        +	; R2 36
        +	xor	edi,edx
        +	xor	edi,ebx
        +	lea	eax,DWORD PTR 2763975236[ebp*1+eax]
        +	add	eax,edi
        +	rol	eax,4
        +	mov	ebp,DWORD PTR 16[esi]
        +	mov	edi,ebx
        +	; R2 37
        +	lea	edx,DWORD PTR 1272893353[ebp*1+edx]
        +	add	eax,ebx
        +	xor	edi,ecx
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 28[esi]
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,11
        +	add	edx,eax
        +	; R2 38
        +	xor	edi,ebx
        +	xor	edi,edx
        +	lea	ecx,DWORD PTR 4139469664[ebp*1+ecx]
        +	add	ecx,edi
        +	rol	ecx,16
        +	mov	ebp,DWORD PTR 40[esi]
        +	mov	edi,edx
        +	; R2 39
        +	lea	ebx,DWORD PTR 3200236656[ebp*1+ebx]
        +	add	ecx,edx
        +	xor	edi,eax
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 52[esi]
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,23
        +	add	ebx,ecx
        +	; R2 40
        +	xor	edi,edx
        +	xor	edi,ebx
        +	lea	eax,DWORD PTR 681279174[ebp*1+eax]
        +	add	eax,edi
        +	rol	eax,4
        +	mov	ebp,DWORD PTR [esi]
        +	mov	edi,ebx
        +	; R2 41
        +	lea	edx,DWORD PTR 3936430074[ebp*1+edx]
        +	add	eax,ebx
        +	xor	edi,ecx
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 12[esi]
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,11
        +	add	edx,eax
        +	; R2 42
        +	xor	edi,ebx
        +	xor	edi,edx
        +	lea	ecx,DWORD PTR 3572445317[ebp*1+ecx]
        +	add	ecx,edi
        +	rol	ecx,16
        +	mov	ebp,DWORD PTR 24[esi]
        +	mov	edi,edx
        +	; R2 43
        +	lea	ebx,DWORD PTR 76029189[ebp*1+ebx]
        +	add	ecx,edx
        +	xor	edi,eax
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 36[esi]
        +	add	ebx,edi
        +	mov	edi,ecx
        +	rol	ebx,23
        +	add	ebx,ecx
        +	; R2 44
        +	xor	edi,edx
        +	xor	edi,ebx
        +	lea	eax,DWORD PTR 3654602809[ebp*1+eax]
        +	add	eax,edi
        +	rol	eax,4
        +	mov	ebp,DWORD PTR 48[esi]
        +	mov	edi,ebx
        +	; R2 45
        +	lea	edx,DWORD PTR 3873151461[ebp*1+edx]
        +	add	eax,ebx
        +	xor	edi,ecx
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 60[esi]
        +	add	edx,edi
        +	mov	edi,eax
        +	rol	edx,11
        +	add	edx,eax
        +	; R2 46
        +	xor	edi,ebx
        +	xor	edi,edx
        +	lea	ecx,DWORD PTR 530742520[ebp*1+ecx]
        +	add	ecx,edi
        +	rol	ecx,16
        +	mov	ebp,DWORD PTR 8[esi]
        +	mov	edi,edx
        +	; R2 47
        +	lea	ebx,DWORD PTR 3299628645[ebp*1+ebx]
        +	add	ecx,edx
        +	xor	edi,eax
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR [esi]
        +	add	ebx,edi
        +	mov	edi,-1
        +	rol	ebx,23
        +	add	ebx,ecx
        +	;
        +
        +	; R3 section
        +	; R3 48
        +	xor	edi,edx
        +	or	edi,ebx
        +	lea	eax,DWORD PTR 4096336452[ebp*1+eax]
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 28[esi]
        +	add	eax,edi
        +	mov	edi,-1
        +	rol	eax,6
        +	xor	edi,ecx
        +	add	eax,ebx
        +	; R3 49
        +	or	edi,eax
        +	lea	edx,DWORD PTR 1126891415[ebp*1+edx]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 56[esi]
        +	add	edx,edi
        +	mov	edi,-1
        +	rol	edx,10
        +	xor	edi,ebx
        +	add	edx,eax
        +	; R3 50
        +	or	edi,edx
        +	lea	ecx,DWORD PTR 2878612391[ebp*1+ecx]
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 20[esi]
        +	add	ecx,edi
        +	mov	edi,-1
        +	rol	ecx,15
        +	xor	edi,eax
        +	add	ecx,edx
        +	; R3 51
        +	or	edi,ecx
        +	lea	ebx,DWORD PTR 4237533241[ebp*1+ebx]
        +	xor	edi,edx
        +	mov	ebp,DWORD PTR 48[esi]
        +	add	ebx,edi
        +	mov	edi,-1
        +	rol	ebx,21
        +	xor	edi,edx
        +	add	ebx,ecx
        +	; R3 52
        +	or	edi,ebx
        +	lea	eax,DWORD PTR 1700485571[ebp*1+eax]
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 12[esi]
        +	add	eax,edi
        +	mov	edi,-1
        +	rol	eax,6
        +	xor	edi,ecx
        +	add	eax,ebx
        +	; R3 53
        +	or	edi,eax
        +	lea	edx,DWORD PTR 2399980690[ebp*1+edx]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 40[esi]
        +	add	edx,edi
        +	mov	edi,-1
        +	rol	edx,10
        +	xor	edi,ebx
        +	add	edx,eax
        +	; R3 54
        +	or	edi,edx
        +	lea	ecx,DWORD PTR 4293915773[ebp*1+ecx]
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 4[esi]
        +	add	ecx,edi
        +	mov	edi,-1
        +	rol	ecx,15
        +	xor	edi,eax
        +	add	ecx,edx
        +	; R3 55
        +	or	edi,ecx
        +	lea	ebx,DWORD PTR 2240044497[ebp*1+ebx]
        +	xor	edi,edx
        +	mov	ebp,DWORD PTR 32[esi]
        +	add	ebx,edi
        +	mov	edi,-1
        +	rol	ebx,21
        +	xor	edi,edx
        +	add	ebx,ecx
        +	; R3 56
        +	or	edi,ebx
        +	lea	eax,DWORD PTR 1873313359[ebp*1+eax]
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 60[esi]
        +	add	eax,edi
        +	mov	edi,-1
        +	rol	eax,6
        +	xor	edi,ecx
        +	add	eax,ebx
        +	; R3 57
        +	or	edi,eax
        +	lea	edx,DWORD PTR 4264355552[ebp*1+edx]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 24[esi]
        +	add	edx,edi
        +	mov	edi,-1
        +	rol	edx,10
        +	xor	edi,ebx
        +	add	edx,eax
        +	; R3 58
        +	or	edi,edx
        +	lea	ecx,DWORD PTR 2734768916[ebp*1+ecx]
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 52[esi]
        +	add	ecx,edi
        +	mov	edi,-1
        +	rol	ecx,15
        +	xor	edi,eax
        +	add	ecx,edx
        +	; R3 59
        +	or	edi,ecx
        +	lea	ebx,DWORD PTR 1309151649[ebp*1+ebx]
        +	xor	edi,edx
        +	mov	ebp,DWORD PTR 16[esi]
        +	add	ebx,edi
        +	mov	edi,-1
        +	rol	ebx,21
        +	xor	edi,edx
        +	add	ebx,ecx
        +	; R3 60
        +	or	edi,ebx
        +	lea	eax,DWORD PTR 4149444226[ebp*1+eax]
        +	xor	edi,ecx
        +	mov	ebp,DWORD PTR 44[esi]
        +	add	eax,edi
        +	mov	edi,-1
        +	rol	eax,6
        +	xor	edi,ecx
        +	add	eax,ebx
        +	; R3 61
        +	or	edi,eax
        +	lea	edx,DWORD PTR 3174756917[ebp*1+edx]
        +	xor	edi,ebx
        +	mov	ebp,DWORD PTR 8[esi]
        +	add	edx,edi
        +	mov	edi,-1
        +	rol	edx,10
        +	xor	edi,ebx
        +	add	edx,eax
        +	; R3 62
        +	or	edi,edx
        +	lea	ecx,DWORD PTR 718787259[ebp*1+ecx]
        +	xor	edi,eax
        +	mov	ebp,DWORD PTR 36[esi]
        +	add	ecx,edi
        +	mov	edi,-1
        +	rol	ecx,15
        +	xor	edi,eax
        +	add	ecx,edx
        +	; R3 63
        +	or	edi,ecx
        +	lea	ebx,DWORD PTR 3951481745[ebp*1+ebx]
        +	xor	edi,edx
        +	mov	ebp,DWORD PTR 24[esp]
        +	add	ebx,edi
        +	add	esi,64
        +	rol	ebx,21
        +	mov	edi,DWORD PTR [ebp]
        +	add	ebx,ecx
        +	add	eax,edi
        +	mov	edi,DWORD PTR 4[ebp]
        +	add	ebx,edi
        +	mov	edi,DWORD PTR 8[ebp]
        +	add	ecx,edi
        +	mov	edi,DWORD PTR 12[ebp]
        +	add	edx,edi
        +	mov	DWORD PTR [ebp],eax
        +	mov	DWORD PTR 4[ebp],ebx
        +	mov	edi,DWORD PTR [esp]
        +	mov	DWORD PTR 8[ebp],ecx
        +	mov	DWORD PTR 12[ebp],edx
        +	cmp	edi,esi
        +	jae	$L000start
        +	pop	eax
        +	pop	ebx
        +	pop	ebp
        +	pop	edi
        +	pop	esi
        +	ret
        +_md5_block_asm_data_order ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/rc4/rc4-586.asm b/vendor/openssl/asm/x86-win32-masm/rc4/rc4-586.asm
        new file mode 100644
        index 000000000..d17909091
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/rc4/rc4-586.asm
        @@ -0,0 +1,388 @@
        +TITLE	rc4-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.XMM
        +IF @Version LT 800
        +XMMWORD STRUCT 16
        +DQ	2 dup (?)
        +XMMWORD	ENDS
        +ENDIF
        +
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +;EXTERN	_OPENSSL_ia32cap_P:NEAR
        +ALIGN	16
        +_RC4	PROC PUBLIC
        +$L_RC4_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	edx,DWORD PTR 24[esp]
        +	mov	esi,DWORD PTR 28[esp]
        +	mov	ebp,DWORD PTR 32[esp]
        +	xor	eax,eax
        +	xor	ebx,ebx
        +	cmp	edx,0
        +	je	$L000abort
        +	mov	al,BYTE PTR [edi]
        +	mov	bl,BYTE PTR 4[edi]
        +	add	edi,8
        +	lea	ecx,DWORD PTR [edx*1+esi]
        +	sub	ebp,esi
        +	mov	DWORD PTR 24[esp],ecx
        +	inc	al
        +	cmp	DWORD PTR 256[edi],-1
        +	je	$L001RC4_CHAR
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	and	edx,-4
        +	jz	$L002loop1
        +	test	edx,-8
        +	mov	DWORD PTR 32[esp],ebp
        +	jz	$L003go4loop4
        +	lea	ebp,DWORD PTR _OPENSSL_ia32cap_P
        +	bt	DWORD PTR [ebp],26
        +	jnc	$L003go4loop4
        +	mov	ebp,DWORD PTR 32[esp]
        +	and	edx,-8
        +	lea	edx,DWORD PTR [edx*1+esi-8]
        +	mov	DWORD PTR [edi-4],edx
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	movq	mm0,QWORD PTR [esi]
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm2,DWORD PTR [edx*4+edi]
        +	jmp	$L004loop_mmx_enter
        +ALIGN	16
        +$L005loop_mmx:
        +	add	bl,cl
        +	psllq	mm1,56
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	movq	mm0,QWORD PTR [esi]
        +	movq	QWORD PTR [esi*1+ebp-8],mm2
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm2,DWORD PTR [edx*4+edi]
        +$L004loop_mmx_enter:
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm0
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	psllq	mm1,8
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	psllq	mm1,16
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	psllq	mm1,24
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	psllq	mm1,32
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	psllq	mm1,40
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	psllq	mm1,48
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	inc	eax
        +	add	edx,ecx
        +	movzx	eax,al
        +	movzx	edx,dl
        +	pxor	mm2,mm1
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	movd	mm1,DWORD PTR [edx*4+edi]
        +	mov	edx,ebx
        +	xor	ebx,ebx
        +	mov	bl,dl
        +	cmp	esi,DWORD PTR [edi-4]
        +	lea	esi,DWORD PTR 8[esi]
        +	jb	$L005loop_mmx
        +	psllq	mm1,56
        +	pxor	mm2,mm1
        +	movq	QWORD PTR [esi*1+ebp-8],mm2
        +	emms
        +	cmp	esi,DWORD PTR 24[esp]
        +	je	$L006done
        +	jmp	$L002loop1
        +ALIGN	16
        +$L003go4loop4:
        +	lea	edx,DWORD PTR [edx*1+esi-4]
        +	mov	DWORD PTR 28[esp],edx
        +$L007loop4:
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	add	edx,ecx
        +	inc	al
        +	and	edx,255
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	mov	ebp,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	add	edx,ecx
        +	inc	al
        +	and	edx,255
        +	ror	ebp,8
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	or	ebp,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	add	edx,ecx
        +	inc	al
        +	and	edx,255
        +	ror	ebp,8
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	or	ebp,DWORD PTR [edx*4+edi]
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	add	edx,ecx
        +	inc	al
        +	and	edx,255
        +	ror	ebp,8
        +	mov	ecx,DWORD PTR 32[esp]
        +	or	ebp,DWORD PTR [edx*4+edi]
        +	ror	ebp,8
        +	xor	ebp,DWORD PTR [esi]
        +	cmp	esi,DWORD PTR 28[esp]
        +	mov	DWORD PTR [esi*1+ecx],ebp
        +	lea	esi,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	jb	$L007loop4
        +	cmp	esi,DWORD PTR 24[esp]
        +	je	$L006done
        +	mov	ebp,DWORD PTR 32[esp]
        +ALIGN	16
        +$L002loop1:
        +	add	bl,cl
        +	mov	edx,DWORD PTR [ebx*4+edi]
        +	mov	DWORD PTR [ebx*4+edi],ecx
        +	mov	DWORD PTR [eax*4+edi],edx
        +	add	edx,ecx
        +	inc	al
        +	and	edx,255
        +	mov	edx,DWORD PTR [edx*4+edi]
        +	xor	dl,BYTE PTR [esi]
        +	lea	esi,DWORD PTR 1[esi]
        +	mov	ecx,DWORD PTR [eax*4+edi]
        +	cmp	esi,DWORD PTR 24[esp]
        +	mov	BYTE PTR [esi*1+ebp-1],dl
        +	jb	$L002loop1
        +	jmp	$L006done
        +ALIGN	16
        +$L001RC4_CHAR:
        +	movzx	ecx,BYTE PTR [eax*1+edi]
        +$L008cloop1:
        +	add	bl,cl
        +	movzx	edx,BYTE PTR [ebx*1+edi]
        +	mov	BYTE PTR [ebx*1+edi],cl
        +	mov	BYTE PTR [eax*1+edi],dl
        +	add	dl,cl
        +	movzx	edx,BYTE PTR [edx*1+edi]
        +	add	al,1
        +	xor	dl,BYTE PTR [esi]
        +	lea	esi,DWORD PTR 1[esi]
        +	movzx	ecx,BYTE PTR [eax*1+edi]
        +	cmp	esi,DWORD PTR 24[esp]
        +	mov	BYTE PTR [esi*1+ebp-1],dl
        +	jb	$L008cloop1
        +$L006done:
        +	dec	al
        +	mov	DWORD PTR [edi-4],ebx
        +	mov	BYTE PTR [edi-8],al
        +$L000abort:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_RC4 ENDP
        +ALIGN	16
        +_private_RC4_set_key	PROC PUBLIC
        +$L_private_RC4_set_key_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	edi,DWORD PTR 20[esp]
        +	mov	ebp,DWORD PTR 24[esp]
        +	mov	esi,DWORD PTR 28[esp]
        +	lea	edx,DWORD PTR _OPENSSL_ia32cap_P
        +	lea	edi,DWORD PTR 8[edi]
        +	lea	esi,DWORD PTR [ebp*1+esi]
        +	neg	ebp
        +	xor	eax,eax
        +	mov	DWORD PTR [edi-4],ebp
        +	bt	DWORD PTR [edx],20
        +	jc	$L009c1stloop
        +ALIGN	16
        +$L010w1stloop:
        +	mov	DWORD PTR [eax*4+edi],eax
        +	add	al,1
        +	jnc	$L010w1stloop
        +	xor	ecx,ecx
        +	xor	edx,edx
        +ALIGN	16
        +$L011w2ndloop:
        +	mov	eax,DWORD PTR [ecx*4+edi]
        +	add	dl,BYTE PTR [ebp*1+esi]
        +	add	dl,al
        +	add	ebp,1
        +	mov	ebx,DWORD PTR [edx*4+edi]
        +	jnz	$L012wnowrap
        +	mov	ebp,DWORD PTR [edi-4]
        +$L012wnowrap:
        +	mov	DWORD PTR [edx*4+edi],eax
        +	mov	DWORD PTR [ecx*4+edi],ebx
        +	add	cl,1
        +	jnc	$L011w2ndloop
        +	jmp	$L013exit
        +ALIGN	16
        +$L009c1stloop:
        +	mov	BYTE PTR [eax*1+edi],al
        +	add	al,1
        +	jnc	$L009c1stloop
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	xor	ebx,ebx
        +ALIGN	16
        +$L014c2ndloop:
        +	mov	al,BYTE PTR [ecx*1+edi]
        +	add	dl,BYTE PTR [ebp*1+esi]
        +	add	dl,al
        +	add	ebp,1
        +	mov	bl,BYTE PTR [edx*1+edi]
        +	jnz	$L015cnowrap
        +	mov	ebp,DWORD PTR [edi-4]
        +$L015cnowrap:
        +	mov	BYTE PTR [edx*1+edi],al
        +	mov	BYTE PTR [ecx*1+edi],bl
        +	add	cl,1
        +	jnc	$L014c2ndloop
        +	mov	DWORD PTR 256[edi],-1
        +$L013exit:
        +	xor	eax,eax
        +	mov	DWORD PTR [edi-8],eax
        +	mov	DWORD PTR [edi-4],eax
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_private_RC4_set_key ENDP
        +ALIGN	16
        +_RC4_options	PROC PUBLIC
        +$L_RC4_options_begin::
        +	call	$L016pic_point
        +$L016pic_point:
        +	pop	eax
        +	lea	eax,DWORD PTR ($L017opts-$L016pic_point)[eax]
        +	lea	edx,DWORD PTR _OPENSSL_ia32cap_P
        +	mov	edx,DWORD PTR [edx]
        +	bt	edx,20
        +	jc	$L0181xchar
        +	bt	edx,26
        +	jnc	$L019ret
        +	add	eax,25
        +	ret
        +$L0181xchar:
        +	add	eax,12
        +$L019ret:
        +	ret
        +ALIGN	64
        +$L017opts:
        +DB	114,99,52,40,52,120,44,105,110,116,41,0
        +DB	114,99,52,40,49,120,44,99,104,97,114,41,0
        +DB	114,99,52,40,56,120,44,109,109,120,41,0
        +DB	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
        +DB	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
        +DB	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +ALIGN	64
        +_RC4_options ENDP
        +.text$	ENDS
        +.bss	SEGMENT 'BSS'
        +COMM	_OPENSSL_ia32cap_P:QWORD
        +.bss	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/rc5/rc5-586.asm b/vendor/openssl/asm/x86-win32-masm/rc5/rc5-586.asm
        new file mode 100644
        index 000000000..7ce74110e
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/rc5/rc5-586.asm
        @@ -0,0 +1,573 @@
        +TITLE	rc5-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_RC5_32_encrypt	PROC PUBLIC
        +$L_RC5_32_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	esi
        +	push	edi
        +	mov	edx,DWORD PTR 16[esp]
        +	mov	ebp,DWORD PTR 20[esp]
        +	; Load the 2 words
        +	mov	edi,DWORD PTR [edx]
        +	mov	esi,DWORD PTR 4[edx]
        +	push	ebx
        +	mov	ebx,DWORD PTR [ebp]
        +	add	edi,DWORD PTR 4[ebp]
        +	add	esi,DWORD PTR 8[ebp]
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 12[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 16[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 20[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 24[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 28[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 32[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 36[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 40[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 44[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 48[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 52[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 56[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 60[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 64[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 68[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 72[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	cmp	ebx,8
        +	je	$L000rc5_exit
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 76[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 80[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 84[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 88[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 92[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 96[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 100[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 104[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	cmp	ebx,12
        +	je	$L000rc5_exit
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 108[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 112[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 116[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 120[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 124[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 128[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 132[ebp]
        +	mov	ecx,esi
        +	rol	edi,cl
        +	add	edi,eax
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 136[ebp]
        +	mov	ecx,edi
        +	rol	esi,cl
        +	add	esi,eax
        +$L000rc5_exit:
        +	mov	DWORD PTR [edx],edi
        +	mov	DWORD PTR 4[edx],esi
        +	pop	ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebp
        +	ret
        +_RC5_32_encrypt ENDP
        +ALIGN	16
        +_RC5_32_decrypt	PROC PUBLIC
        +$L_RC5_32_decrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	esi
        +	push	edi
        +	mov	edx,DWORD PTR 16[esp]
        +	mov	ebp,DWORD PTR 20[esp]
        +	; Load the 2 words
        +	mov	edi,DWORD PTR [edx]
        +	mov	esi,DWORD PTR 4[edx]
        +	push	ebx
        +	mov	ebx,DWORD PTR [ebp]
        +	cmp	ebx,12
        +	je	$L001rc5_dec_12
        +	cmp	ebx,8
        +	je	$L002rc5_dec_8
        +	mov	eax,DWORD PTR 136[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 132[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 128[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 124[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 120[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 116[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 112[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 108[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +$L001rc5_dec_12:
        +	mov	eax,DWORD PTR 104[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 100[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 96[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 92[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 88[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 84[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 80[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 76[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +$L002rc5_dec_8:
        +	mov	eax,DWORD PTR 72[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 68[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 64[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 60[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 56[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 52[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 48[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 44[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 40[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 36[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 32[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 28[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 24[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 20[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	mov	eax,DWORD PTR 16[ebp]
        +	sub	esi,eax
        +	mov	ecx,edi
        +	ror	esi,cl
        +	xor	esi,edi
        +	mov	eax,DWORD PTR 12[ebp]
        +	sub	edi,eax
        +	mov	ecx,esi
        +	ror	edi,cl
        +	xor	edi,esi
        +	sub	esi,DWORD PTR 8[ebp]
        +	sub	edi,DWORD PTR 4[ebp]
        +$L003rc5_exit:
        +	mov	DWORD PTR [edx],edi
        +	mov	DWORD PTR 4[edx],esi
        +	pop	ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebp
        +	ret
        +_RC5_32_decrypt ENDP
        +ALIGN	16
        +_RC5_32_cbc_encrypt	PROC PUBLIC
        +$L_RC5_32_cbc_encrypt_begin::
        +	;
        +
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ebp,DWORD PTR 28[esp]
        +	; getting iv ptr from parameter 4
        +	mov	ebx,DWORD PTR 36[esp]
        +	mov	esi,DWORD PTR [ebx]
        +	mov	edi,DWORD PTR 4[ebx]
        +	push	edi
        +	push	esi
        +	push	edi
        +	push	esi
        +	mov	ebx,esp
        +	mov	esi,DWORD PTR 36[esp]
        +	mov	edi,DWORD PTR 40[esp]
        +	; getting encrypt flag from parameter 5
        +	mov	ecx,DWORD PTR 56[esp]
        +	; get and push parameter 3
        +	mov	eax,DWORD PTR 48[esp]
        +	push	eax
        +	push	ebx
        +	cmp	ecx,0
        +	jz	$L004decrypt
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	jz	$L005encrypt_finish
        +$L006encrypt_loop:
        +	mov	ecx,DWORD PTR [esi]
        +	mov	edx,DWORD PTR 4[esi]
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_RC5_32_encrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L006encrypt_loop
        +$L005encrypt_finish:
        +	mov	ebp,DWORD PTR 52[esp]
        +	and	ebp,7
        +	jz	$L007finish
        +	call	$L008PIC_point
        +$L008PIC_point:
        +	pop	edx
        +	lea	ecx,DWORD PTR ($L009cbc_enc_jmp_table-$L008PIC_point)[edx]
        +	mov	ebp,DWORD PTR [ebp*4+ecx]
        +	add	ebp,edx
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	jmp	ebp
        +$L010ej7:
        +	mov	dh,BYTE PTR 6[esi]
        +	shl	edx,8
        +$L011ej6:
        +	mov	dh,BYTE PTR 5[esi]
        +$L012ej5:
        +	mov	dl,BYTE PTR 4[esi]
        +$L013ej4:
        +	mov	ecx,DWORD PTR [esi]
        +	jmp	$L014ejend
        +$L015ej3:
        +	mov	ch,BYTE PTR 2[esi]
        +	shl	ecx,8
        +$L016ej2:
        +	mov	ch,BYTE PTR 1[esi]
        +$L017ej1:
        +	mov	cl,BYTE PTR [esi]
        +$L014ejend:
        +	xor	eax,ecx
        +	xor	ebx,edx
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_RC5_32_encrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	DWORD PTR [edi],eax
        +	mov	DWORD PTR 4[edi],ebx
        +	jmp	$L007finish
        +$L004decrypt:
        +	and	ebp,4294967288
        +	mov	eax,DWORD PTR 16[esp]
        +	mov	ebx,DWORD PTR 20[esp]
        +	jz	$L018decrypt_finish
        +$L019decrypt_loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_RC5_32_decrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	ecx,DWORD PTR 16[esp]
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR [edi],ecx
        +	mov	DWORD PTR 4[edi],edx
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	add	esi,8
        +	add	edi,8
        +	sub	ebp,8
        +	jnz	$L019decrypt_loop
        +$L018decrypt_finish:
        +	mov	ebp,DWORD PTR 52[esp]
        +	and	ebp,7
        +	jz	$L007finish
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +	call	$L_RC5_32_decrypt_begin
        +	mov	eax,DWORD PTR 8[esp]
        +	mov	ebx,DWORD PTR 12[esp]
        +	mov	ecx,DWORD PTR 16[esp]
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +$L020dj7:
        +	ror	edx,16
        +	mov	BYTE PTR 6[edi],dl
        +	shr	edx,16
        +$L021dj6:
        +	mov	BYTE PTR 5[edi],dh
        +$L022dj5:
        +	mov	BYTE PTR 4[edi],dl
        +$L023dj4:
        +	mov	DWORD PTR [edi],ecx
        +	jmp	$L024djend
        +$L025dj3:
        +	ror	ecx,16
        +	mov	BYTE PTR 2[edi],cl
        +	shl	ecx,16
        +$L026dj2:
        +	mov	BYTE PTR 1[esi],ch
        +$L027dj1:
        +	mov	BYTE PTR [esi],cl
        +$L024djend:
        +	jmp	$L007finish
        +$L007finish:
        +	mov	ecx,DWORD PTR 60[esp]
        +	add	esp,24
        +	mov	DWORD PTR [ecx],eax
        +	mov	DWORD PTR 4[ecx],ebx
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L009cbc_enc_jmp_table:
        +DD	0
        +DD	$L017ej1-$L008PIC_point
        +DD	$L016ej2-$L008PIC_point
        +DD	$L015ej3-$L008PIC_point
        +DD	$L013ej4-$L008PIC_point
        +DD	$L012ej5-$L008PIC_point
        +DD	$L011ej6-$L008PIC_point
        +DD	$L010ej7-$L008PIC_point
        +ALIGN	64
        +_RC5_32_cbc_encrypt ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm b/vendor/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm
        new file mode 100644
        index 000000000..7f6458cef
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/ripemd/rmd-586.asm
        @@ -0,0 +1,1976 @@
        +TITLE	../openssl/crypto/ripemd/asm/rmd-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_ripemd160_block_asm_data_order	PROC PUBLIC
        +$L_ripemd160_block_asm_data_order_begin::
        +	mov	edx,DWORD PTR 4[esp]
        +	mov	eax,DWORD PTR 8[esp]
        +	push	esi
        +	mov	ecx,DWORD PTR [edx]
        +	push	edi
        +	mov	esi,DWORD PTR 4[edx]
        +	push	ebp
        +	mov	edi,DWORD PTR 8[edx]
        +	push	ebx
        +	sub	esp,108
        +$L000start:
        +	;
        +
        +	mov	ebx,DWORD PTR [eax]
        +	mov	ebp,DWORD PTR 4[eax]
        +	mov	DWORD PTR [esp],ebx
        +	mov	DWORD PTR 4[esp],ebp
        +	mov	ebx,DWORD PTR 8[eax]
        +	mov	ebp,DWORD PTR 12[eax]
        +	mov	DWORD PTR 8[esp],ebx
        +	mov	DWORD PTR 12[esp],ebp
        +	mov	ebx,DWORD PTR 16[eax]
        +	mov	ebp,DWORD PTR 20[eax]
        +	mov	DWORD PTR 16[esp],ebx
        +	mov	DWORD PTR 20[esp],ebp
        +	mov	ebx,DWORD PTR 24[eax]
        +	mov	ebp,DWORD PTR 28[eax]
        +	mov	DWORD PTR 24[esp],ebx
        +	mov	DWORD PTR 28[esp],ebp
        +	mov	ebx,DWORD PTR 32[eax]
        +	mov	ebp,DWORD PTR 36[eax]
        +	mov	DWORD PTR 32[esp],ebx
        +	mov	DWORD PTR 36[esp],ebp
        +	mov	ebx,DWORD PTR 40[eax]
        +	mov	ebp,DWORD PTR 44[eax]
        +	mov	DWORD PTR 40[esp],ebx
        +	mov	DWORD PTR 44[esp],ebp
        +	mov	ebx,DWORD PTR 48[eax]
        +	mov	ebp,DWORD PTR 52[eax]
        +	mov	DWORD PTR 48[esp],ebx
        +	mov	DWORD PTR 52[esp],ebp
        +	mov	ebx,DWORD PTR 56[eax]
        +	mov	ebp,DWORD PTR 60[eax]
        +	mov	DWORD PTR 56[esp],ebx
        +	mov	DWORD PTR 60[esp],ebp
        +	mov	eax,edi
        +	mov	ebx,DWORD PTR 12[edx]
        +	mov	ebp,DWORD PTR 16[edx]
        +	; 0
        +	xor	eax,ebx
        +	mov	edx,DWORD PTR [esp]
        +	xor	eax,esi
        +	add	ecx,edx
        +	rol	edi,10
        +	add	ecx,eax
        +	mov	eax,esi
        +	rol	ecx,11
        +	add	ecx,ebp
        +	; 1
        +	xor	eax,edi
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	eax,ecx
        +	add	ebp,eax
        +	mov	eax,ecx
        +	rol	esi,10
        +	add	ebp,edx
        +	xor	eax,esi
        +	rol	ebp,14
        +	add	ebp,ebx
        +	; 2
        +	mov	edx,DWORD PTR 8[esp]
        +	xor	eax,ebp
        +	add	ebx,edx
        +	rol	ecx,10
        +	add	ebx,eax
        +	mov	eax,ebp
        +	rol	ebx,15
        +	add	ebx,edi
        +	; 3
        +	xor	eax,ecx
        +	mov	edx,DWORD PTR 12[esp]
        +	xor	eax,ebx
        +	add	edi,eax
        +	mov	eax,ebx
        +	rol	ebp,10
        +	add	edi,edx
        +	xor	eax,ebp
        +	rol	edi,12
        +	add	edi,esi
        +	; 4
        +	mov	edx,DWORD PTR 16[esp]
        +	xor	eax,edi
        +	add	esi,edx
        +	rol	ebx,10
        +	add	esi,eax
        +	mov	eax,edi
        +	rol	esi,5
        +	add	esi,ecx
        +	; 5
        +	xor	eax,ebx
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	eax,esi
        +	add	ecx,eax
        +	mov	eax,esi
        +	rol	edi,10
        +	add	ecx,edx
        +	xor	eax,edi
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 6
        +	mov	edx,DWORD PTR 24[esp]
        +	xor	eax,ecx
        +	add	ebp,edx
        +	rol	esi,10
        +	add	ebp,eax
        +	mov	eax,ecx
        +	rol	ebp,7
        +	add	ebp,ebx
        +	; 7
        +	xor	eax,esi
        +	mov	edx,DWORD PTR 28[esp]
        +	xor	eax,ebp
        +	add	ebx,eax
        +	mov	eax,ebp
        +	rol	ecx,10
        +	add	ebx,edx
        +	xor	eax,ecx
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 8
        +	mov	edx,DWORD PTR 32[esp]
        +	xor	eax,ebx
        +	add	edi,edx
        +	rol	ebp,10
        +	add	edi,eax
        +	mov	eax,ebx
        +	rol	edi,11
        +	add	edi,esi
        +	; 9
        +	xor	eax,ebp
        +	mov	edx,DWORD PTR 36[esp]
        +	xor	eax,edi
        +	add	esi,eax
        +	mov	eax,edi
        +	rol	ebx,10
        +	add	esi,edx
        +	xor	eax,ebx
        +	rol	esi,13
        +	add	esi,ecx
        +	; 10
        +	mov	edx,DWORD PTR 40[esp]
        +	xor	eax,esi
        +	add	ecx,edx
        +	rol	edi,10
        +	add	ecx,eax
        +	mov	eax,esi
        +	rol	ecx,14
        +	add	ecx,ebp
        +	; 11
        +	xor	eax,edi
        +	mov	edx,DWORD PTR 44[esp]
        +	xor	eax,ecx
        +	add	ebp,eax
        +	mov	eax,ecx
        +	rol	esi,10
        +	add	ebp,edx
        +	xor	eax,esi
        +	rol	ebp,15
        +	add	ebp,ebx
        +	; 12
        +	mov	edx,DWORD PTR 48[esp]
        +	xor	eax,ebp
        +	add	ebx,edx
        +	rol	ecx,10
        +	add	ebx,eax
        +	mov	eax,ebp
        +	rol	ebx,6
        +	add	ebx,edi
        +	; 13
        +	xor	eax,ecx
        +	mov	edx,DWORD PTR 52[esp]
        +	xor	eax,ebx
        +	add	edi,eax
        +	mov	eax,ebx
        +	rol	ebp,10
        +	add	edi,edx
        +	xor	eax,ebp
        +	rol	edi,7
        +	add	edi,esi
        +	; 14
        +	mov	edx,DWORD PTR 56[esp]
        +	xor	eax,edi
        +	add	esi,edx
        +	rol	ebx,10
        +	add	esi,eax
        +	mov	eax,edi
        +	rol	esi,9
        +	add	esi,ecx
        +	; 15
        +	xor	eax,ebx
        +	mov	edx,DWORD PTR 60[esp]
        +	xor	eax,esi
        +	add	ecx,eax
        +	mov	eax,-1
        +	rol	edi,10
        +	add	ecx,edx
        +	mov	edx,DWORD PTR 28[esp]
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 16
        +	add	ebp,edx
        +	mov	edx,esi
        +	sub	eax,ecx
        +	and	edx,ecx
        +	and	eax,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 16[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1518500249[edx*1+ebp]
        +	mov	edx,-1
        +	rol	ebp,7
        +	add	ebp,ebx
        +	; 17
        +	add	ebx,eax
        +	mov	eax,ecx
        +	sub	edx,ebp
        +	and	eax,ebp
        +	and	edx,esi
        +	or	eax,edx
        +	mov	edx,DWORD PTR 52[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1518500249[eax*1+ebx]
        +	mov	eax,-1
        +	rol	ebx,6
        +	add	ebx,edi
        +	; 18
        +	add	edi,edx
        +	mov	edx,ebp
        +	sub	eax,ebx
        +	and	edx,ebx
        +	and	eax,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1518500249[edx*1+edi]
        +	mov	edx,-1
        +	rol	edi,8
        +	add	edi,esi
        +	; 19
        +	add	esi,eax
        +	mov	eax,ebx
        +	sub	edx,edi
        +	and	eax,edi
        +	and	edx,ebp
        +	or	eax,edx
        +	mov	edx,DWORD PTR 40[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1518500249[eax*1+esi]
        +	mov	eax,-1
        +	rol	esi,13
        +	add	esi,ecx
        +	; 20
        +	add	ecx,edx
        +	mov	edx,edi
        +	sub	eax,esi
        +	and	edx,esi
        +	and	eax,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 24[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1518500249[edx*1+ecx]
        +	mov	edx,-1
        +	rol	ecx,11
        +	add	ecx,ebp
        +	; 21
        +	add	ebp,eax
        +	mov	eax,esi
        +	sub	edx,ecx
        +	and	eax,ecx
        +	and	edx,edi
        +	or	eax,edx
        +	mov	edx,DWORD PTR 60[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1518500249[eax*1+ebp]
        +	mov	eax,-1
        +	rol	ebp,9
        +	add	ebp,ebx
        +	; 22
        +	add	ebx,edx
        +	mov	edx,ecx
        +	sub	eax,ebp
        +	and	edx,ebp
        +	and	eax,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 12[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1518500249[edx*1+ebx]
        +	mov	edx,-1
        +	rol	ebx,7
        +	add	ebx,edi
        +	; 23
        +	add	edi,eax
        +	mov	eax,ebp
        +	sub	edx,ebx
        +	and	eax,ebx
        +	and	edx,ecx
        +	or	eax,edx
        +	mov	edx,DWORD PTR 48[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1518500249[eax*1+edi]
        +	mov	eax,-1
        +	rol	edi,15
        +	add	edi,esi
        +	; 24
        +	add	esi,edx
        +	mov	edx,ebx
        +	sub	eax,edi
        +	and	edx,edi
        +	and	eax,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR [esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1518500249[edx*1+esi]
        +	mov	edx,-1
        +	rol	esi,7
        +	add	esi,ecx
        +	; 25
        +	add	ecx,eax
        +	mov	eax,edi
        +	sub	edx,esi
        +	and	eax,esi
        +	and	edx,ebx
        +	or	eax,edx
        +	mov	edx,DWORD PTR 36[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1518500249[eax*1+ecx]
        +	mov	eax,-1
        +	rol	ecx,12
        +	add	ecx,ebp
        +	; 26
        +	add	ebp,edx
        +	mov	edx,esi
        +	sub	eax,ecx
        +	and	edx,ecx
        +	and	eax,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1518500249[edx*1+ebp]
        +	mov	edx,-1
        +	rol	ebp,15
        +	add	ebp,ebx
        +	; 27
        +	add	ebx,eax
        +	mov	eax,ecx
        +	sub	edx,ebp
        +	and	eax,ebp
        +	and	edx,esi
        +	or	eax,edx
        +	mov	edx,DWORD PTR 8[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1518500249[eax*1+ebx]
        +	mov	eax,-1
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 28
        +	add	edi,edx
        +	mov	edx,ebp
        +	sub	eax,ebx
        +	and	edx,ebx
        +	and	eax,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 56[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1518500249[edx*1+edi]
        +	mov	edx,-1
        +	rol	edi,11
        +	add	edi,esi
        +	; 29
        +	add	esi,eax
        +	mov	eax,ebx
        +	sub	edx,edi
        +	and	eax,edi
        +	and	edx,ebp
        +	or	eax,edx
        +	mov	edx,DWORD PTR 44[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1518500249[eax*1+esi]
        +	mov	eax,-1
        +	rol	esi,7
        +	add	esi,ecx
        +	; 30
        +	add	ecx,edx
        +	mov	edx,edi
        +	sub	eax,esi
        +	and	edx,esi
        +	and	eax,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 32[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1518500249[edx*1+ecx]
        +	mov	edx,-1
        +	rol	ecx,13
        +	add	ecx,ebp
        +	; 31
        +	add	ebp,eax
        +	mov	eax,esi
        +	sub	edx,ecx
        +	and	eax,ecx
        +	and	edx,edi
        +	or	eax,edx
        +	mov	edx,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1518500249[eax*1+ebp]
        +	sub	edx,ecx
        +	rol	ebp,12
        +	add	ebp,ebx
        +	; 32
        +	mov	eax,DWORD PTR 12[esp]
        +	or	edx,ebp
        +	add	ebx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1859775393[edx*1+ebx]
        +	sub	eax,ebp
        +	rol	ebx,11
        +	add	ebx,edi
        +	; 33
        +	mov	edx,DWORD PTR 40[esp]
        +	or	eax,ebx
        +	add	edi,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1859775393[eax*1+edi]
        +	sub	edx,ebx
        +	rol	edi,13
        +	add	edi,esi
        +	; 34
        +	mov	eax,DWORD PTR 56[esp]
        +	or	edx,edi
        +	add	esi,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1859775393[edx*1+esi]
        +	sub	eax,edi
        +	rol	esi,6
        +	add	esi,ecx
        +	; 35
        +	mov	edx,DWORD PTR 16[esp]
        +	or	eax,esi
        +	add	ecx,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1859775393[eax*1+ecx]
        +	sub	edx,esi
        +	rol	ecx,7
        +	add	ecx,ebp
        +	; 36
        +	mov	eax,DWORD PTR 36[esp]
        +	or	edx,ecx
        +	add	ebp,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1859775393[edx*1+ebp]
        +	sub	eax,ecx
        +	rol	ebp,14
        +	add	ebp,ebx
        +	; 37
        +	mov	edx,DWORD PTR 60[esp]
        +	or	eax,ebp
        +	add	ebx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1859775393[eax*1+ebx]
        +	sub	edx,ebp
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 38
        +	mov	eax,DWORD PTR 32[esp]
        +	or	edx,ebx
        +	add	edi,eax
        +	xor	edx,ecx
        +	mov	eax,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1859775393[edx*1+edi]
        +	sub	eax,ebx
        +	rol	edi,13
        +	add	edi,esi
        +	; 39
        +	mov	edx,DWORD PTR 4[esp]
        +	or	eax,edi
        +	add	esi,edx
        +	xor	eax,ebp
        +	mov	edx,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1859775393[eax*1+esi]
        +	sub	edx,edi
        +	rol	esi,15
        +	add	esi,ecx
        +	; 40
        +	mov	eax,DWORD PTR 8[esp]
        +	or	edx,esi
        +	add	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1859775393[edx*1+ecx]
        +	sub	eax,esi
        +	rol	ecx,14
        +	add	ecx,ebp
        +	; 41
        +	mov	edx,DWORD PTR 28[esp]
        +	or	eax,ecx
        +	add	ebp,edx
        +	xor	eax,edi
        +	mov	edx,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1859775393[eax*1+ebp]
        +	sub	edx,ecx
        +	rol	ebp,8
        +	add	ebp,ebx
        +	; 42
        +	mov	eax,DWORD PTR [esp]
        +	or	edx,ebp
        +	add	ebx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1859775393[edx*1+ebx]
        +	sub	eax,ebp
        +	rol	ebx,13
        +	add	ebx,edi
        +	; 43
        +	mov	edx,DWORD PTR 24[esp]
        +	or	eax,ebx
        +	add	edi,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1859775393[eax*1+edi]
        +	sub	edx,ebx
        +	rol	edi,6
        +	add	edi,esi
        +	; 44
        +	mov	eax,DWORD PTR 52[esp]
        +	or	edx,edi
        +	add	esi,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1859775393[edx*1+esi]
        +	sub	eax,edi
        +	rol	esi,5
        +	add	esi,ecx
        +	; 45
        +	mov	edx,DWORD PTR 44[esp]
        +	or	eax,esi
        +	add	ecx,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1859775393[eax*1+ecx]
        +	sub	edx,esi
        +	rol	ecx,12
        +	add	ecx,ebp
        +	; 46
        +	mov	eax,DWORD PTR 20[esp]
        +	or	edx,ecx
        +	add	ebp,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1859775393[edx*1+ebp]
        +	sub	eax,ecx
        +	rol	ebp,7
        +	add	ebp,ebx
        +	; 47
        +	mov	edx,DWORD PTR 48[esp]
        +	or	eax,ebp
        +	add	ebx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1859775393[eax*1+ebx]
        +	mov	eax,ecx
        +	rol	ebx,5
        +	add	ebx,edi
        +	; 48
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2400959708[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	mov	eax,ebp
        +	rol	edi,11
        +	add	edi,esi
        +	; 49
        +	sub	edx,ebp
        +	and	eax,edi
        +	and	edx,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 36[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2400959708[edx*1+esi]
        +	mov	edx,-1
        +	add	esi,eax
        +	mov	eax,ebx
        +	rol	esi,12
        +	add	esi,ecx
        +	; 50
        +	sub	edx,ebx
        +	and	eax,esi
        +	and	edx,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 44[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2400959708[edx*1+ecx]
        +	mov	edx,-1
        +	add	ecx,eax
        +	mov	eax,edi
        +	rol	ecx,14
        +	add	ecx,ebp
        +	; 51
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 40[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2400959708[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	mov	eax,esi
        +	rol	ebp,15
        +	add	ebp,ebx
        +	; 52
        +	sub	edx,esi
        +	and	eax,ebp
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR [esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2400959708[edx*1+ebx]
        +	mov	edx,-1
        +	add	ebx,eax
        +	mov	eax,ecx
        +	rol	ebx,14
        +	add	ebx,edi
        +	; 53
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 32[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2400959708[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	mov	eax,ebp
        +	rol	edi,15
        +	add	edi,esi
        +	; 54
        +	sub	edx,ebp
        +	and	eax,edi
        +	and	edx,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 48[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2400959708[edx*1+esi]
        +	mov	edx,-1
        +	add	esi,eax
        +	mov	eax,ebx
        +	rol	esi,9
        +	add	esi,ecx
        +	; 55
        +	sub	edx,ebx
        +	and	eax,esi
        +	and	edx,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 16[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2400959708[edx*1+ecx]
        +	mov	edx,-1
        +	add	ecx,eax
        +	mov	eax,edi
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 56
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 52[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2400959708[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	mov	eax,esi
        +	rol	ebp,9
        +	add	ebp,ebx
        +	; 57
        +	sub	edx,esi
        +	and	eax,ebp
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 12[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2400959708[edx*1+ebx]
        +	mov	edx,-1
        +	add	ebx,eax
        +	mov	eax,ecx
        +	rol	ebx,14
        +	add	ebx,edi
        +	; 58
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 28[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2400959708[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	mov	eax,ebp
        +	rol	edi,5
        +	add	edi,esi
        +	; 59
        +	sub	edx,ebp
        +	and	eax,edi
        +	and	edx,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 60[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2400959708[edx*1+esi]
        +	mov	edx,-1
        +	add	esi,eax
        +	mov	eax,ebx
        +	rol	esi,6
        +	add	esi,ecx
        +	; 60
        +	sub	edx,ebx
        +	and	eax,esi
        +	and	edx,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 56[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2400959708[edx*1+ecx]
        +	mov	edx,-1
        +	add	ecx,eax
        +	mov	eax,edi
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 61
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2400959708[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	mov	eax,esi
        +	rol	ebp,6
        +	add	ebp,ebx
        +	; 62
        +	sub	edx,esi
        +	and	eax,ebp
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 24[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2400959708[edx*1+ebx]
        +	mov	edx,-1
        +	add	ebx,eax
        +	mov	eax,ecx
        +	rol	ebx,5
        +	add	ebx,edi
        +	; 63
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 8[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2400959708[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	sub	edx,ebp
        +	rol	edi,12
        +	add	edi,esi
        +	; 64
        +	mov	eax,DWORD PTR 16[esp]
        +	or	edx,ebx
        +	add	esi,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2840853838[edx*1+esi]
        +	sub	eax,ebx
        +	rol	esi,9
        +	add	esi,ecx
        +	; 65
        +	mov	edx,DWORD PTR [esp]
        +	or	eax,edi
        +	add	ecx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2840853838[eax*1+ecx]
        +	sub	edx,edi
        +	rol	ecx,15
        +	add	ecx,ebp
        +	; 66
        +	mov	eax,DWORD PTR 20[esp]
        +	or	edx,esi
        +	add	ebp,eax
        +	xor	edx,ecx
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2840853838[edx*1+ebp]
        +	sub	eax,esi
        +	rol	ebp,5
        +	add	ebp,ebx
        +	; 67
        +	mov	edx,DWORD PTR 36[esp]
        +	or	eax,ecx
        +	add	ebx,edx
        +	xor	eax,ebp
        +	mov	edx,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2840853838[eax*1+ebx]
        +	sub	edx,ecx
        +	rol	ebx,11
        +	add	ebx,edi
        +	; 68
        +	mov	eax,DWORD PTR 28[esp]
        +	or	edx,ebp
        +	add	edi,eax
        +	xor	edx,ebx
        +	mov	eax,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2840853838[edx*1+edi]
        +	sub	eax,ebp
        +	rol	edi,6
        +	add	edi,esi
        +	; 69
        +	mov	edx,DWORD PTR 48[esp]
        +	or	eax,ebx
        +	add	esi,edx
        +	xor	eax,edi
        +	mov	edx,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2840853838[eax*1+esi]
        +	sub	edx,ebx
        +	rol	esi,8
        +	add	esi,ecx
        +	; 70
        +	mov	eax,DWORD PTR 8[esp]
        +	or	edx,edi
        +	add	ecx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2840853838[edx*1+ecx]
        +	sub	eax,edi
        +	rol	ecx,13
        +	add	ecx,ebp
        +	; 71
        +	mov	edx,DWORD PTR 40[esp]
        +	or	eax,esi
        +	add	ebp,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2840853838[eax*1+ebp]
        +	sub	edx,esi
        +	rol	ebp,12
        +	add	ebp,ebx
        +	; 72
        +	mov	eax,DWORD PTR 56[esp]
        +	or	edx,ecx
        +	add	ebx,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2840853838[edx*1+ebx]
        +	sub	eax,ecx
        +	rol	ebx,5
        +	add	ebx,edi
        +	; 73
        +	mov	edx,DWORD PTR 4[esp]
        +	or	eax,ebp
        +	add	edi,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2840853838[eax*1+edi]
        +	sub	edx,ebp
        +	rol	edi,12
        +	add	edi,esi
        +	; 74
        +	mov	eax,DWORD PTR 12[esp]
        +	or	edx,ebx
        +	add	esi,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2840853838[edx*1+esi]
        +	sub	eax,ebx
        +	rol	esi,13
        +	add	esi,ecx
        +	; 75
        +	mov	edx,DWORD PTR 32[esp]
        +	or	eax,edi
        +	add	ecx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2840853838[eax*1+ecx]
        +	sub	edx,edi
        +	rol	ecx,14
        +	add	ecx,ebp
        +	; 76
        +	mov	eax,DWORD PTR 44[esp]
        +	or	edx,esi
        +	add	ebp,eax
        +	xor	edx,ecx
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2840853838[edx*1+ebp]
        +	sub	eax,esi
        +	rol	ebp,11
        +	add	ebp,ebx
        +	; 77
        +	mov	edx,DWORD PTR 24[esp]
        +	or	eax,ecx
        +	add	ebx,edx
        +	xor	eax,ebp
        +	mov	edx,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2840853838[eax*1+ebx]
        +	sub	edx,ecx
        +	rol	ebx,8
        +	add	ebx,edi
        +	; 78
        +	mov	eax,DWORD PTR 60[esp]
        +	or	edx,ebp
        +	add	edi,eax
        +	xor	edx,ebx
        +	mov	eax,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2840853838[edx*1+edi]
        +	sub	eax,ebp
        +	rol	edi,5
        +	add	edi,esi
        +	; 79
        +	mov	edx,DWORD PTR 52[esp]
        +	or	eax,ebx
        +	add	esi,edx
        +	xor	eax,edi
        +	mov	edx,DWORD PTR 128[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2840853838[eax*1+esi]
        +	mov	DWORD PTR 64[esp],ecx
        +	rol	esi,6
        +	add	esi,ecx
        +	mov	ecx,DWORD PTR [edx]
        +	mov	DWORD PTR 68[esp],esi
        +	mov	DWORD PTR 72[esp],edi
        +	mov	esi,DWORD PTR 4[edx]
        +	mov	DWORD PTR 76[esp],ebx
        +	mov	edi,DWORD PTR 8[edx]
        +	mov	DWORD PTR 80[esp],ebp
        +	mov	ebx,DWORD PTR 12[edx]
        +	mov	ebp,DWORD PTR 16[edx]
        +	; 80
        +	mov	edx,-1
        +	sub	edx,ebx
        +	mov	eax,DWORD PTR 20[esp]
        +	or	edx,edi
        +	add	ecx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1352829926[edx*1+ecx]
        +	sub	eax,edi
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 81
        +	mov	edx,DWORD PTR 56[esp]
        +	or	eax,esi
        +	add	ebp,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1352829926[eax*1+ebp]
        +	sub	edx,esi
        +	rol	ebp,9
        +	add	ebp,ebx
        +	; 82
        +	mov	eax,DWORD PTR 28[esp]
        +	or	edx,ecx
        +	add	ebx,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1352829926[edx*1+ebx]
        +	sub	eax,ecx
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 83
        +	mov	edx,DWORD PTR [esp]
        +	or	eax,ebp
        +	add	edi,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1352829926[eax*1+edi]
        +	sub	edx,ebp
        +	rol	edi,11
        +	add	edi,esi
        +	; 84
        +	mov	eax,DWORD PTR 36[esp]
        +	or	edx,ebx
        +	add	esi,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1352829926[edx*1+esi]
        +	sub	eax,ebx
        +	rol	esi,13
        +	add	esi,ecx
        +	; 85
        +	mov	edx,DWORD PTR 8[esp]
        +	or	eax,edi
        +	add	ecx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1352829926[eax*1+ecx]
        +	sub	edx,edi
        +	rol	ecx,15
        +	add	ecx,ebp
        +	; 86
        +	mov	eax,DWORD PTR 44[esp]
        +	or	edx,esi
        +	add	ebp,eax
        +	xor	edx,ecx
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1352829926[edx*1+ebp]
        +	sub	eax,esi
        +	rol	ebp,15
        +	add	ebp,ebx
        +	; 87
        +	mov	edx,DWORD PTR 16[esp]
        +	or	eax,ecx
        +	add	ebx,edx
        +	xor	eax,ebp
        +	mov	edx,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1352829926[eax*1+ebx]
        +	sub	edx,ecx
        +	rol	ebx,5
        +	add	ebx,edi
        +	; 88
        +	mov	eax,DWORD PTR 52[esp]
        +	or	edx,ebp
        +	add	edi,eax
        +	xor	edx,ebx
        +	mov	eax,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1352829926[edx*1+edi]
        +	sub	eax,ebp
        +	rol	edi,7
        +	add	edi,esi
        +	; 89
        +	mov	edx,DWORD PTR 24[esp]
        +	or	eax,ebx
        +	add	esi,edx
        +	xor	eax,edi
        +	mov	edx,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1352829926[eax*1+esi]
        +	sub	edx,ebx
        +	rol	esi,7
        +	add	esi,ecx
        +	; 90
        +	mov	eax,DWORD PTR 60[esp]
        +	or	edx,edi
        +	add	ecx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1352829926[edx*1+ecx]
        +	sub	eax,edi
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 91
        +	mov	edx,DWORD PTR 32[esp]
        +	or	eax,esi
        +	add	ebp,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1352829926[eax*1+ebp]
        +	sub	edx,esi
        +	rol	ebp,11
        +	add	ebp,ebx
        +	; 92
        +	mov	eax,DWORD PTR 4[esp]
        +	or	edx,ecx
        +	add	ebx,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1352829926[edx*1+ebx]
        +	sub	eax,ecx
        +	rol	ebx,14
        +	add	ebx,edi
        +	; 93
        +	mov	edx,DWORD PTR 40[esp]
        +	or	eax,ebp
        +	add	edi,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1352829926[eax*1+edi]
        +	sub	edx,ebp
        +	rol	edi,14
        +	add	edi,esi
        +	; 94
        +	mov	eax,DWORD PTR 12[esp]
        +	or	edx,ebx
        +	add	esi,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1352829926[edx*1+esi]
        +	sub	eax,ebx
        +	rol	esi,12
        +	add	esi,ecx
        +	; 95
        +	mov	edx,DWORD PTR 48[esp]
        +	or	eax,edi
        +	add	ecx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1352829926[eax*1+ecx]
        +	mov	eax,edi
        +	rol	ecx,6
        +	add	ecx,ebp
        +	; 96
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 24[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1548603684[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	mov	eax,esi
        +	rol	ebp,9
        +	add	ebp,ebx
        +	; 97
        +	sub	edx,esi
        +	and	eax,ebp
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 44[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1548603684[edx*1+ebx]
        +	mov	edx,-1
        +	add	ebx,eax
        +	mov	eax,ecx
        +	rol	ebx,13
        +	add	ebx,edi
        +	; 98
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 12[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1548603684[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	mov	eax,ebp
        +	rol	edi,15
        +	add	edi,esi
        +	; 99
        +	sub	edx,ebp
        +	and	eax,edi
        +	and	edx,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 28[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1548603684[edx*1+esi]
        +	mov	edx,-1
        +	add	esi,eax
        +	mov	eax,ebx
        +	rol	esi,7
        +	add	esi,ecx
        +	; 100
        +	sub	edx,ebx
        +	and	eax,esi
        +	and	edx,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR [esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1548603684[edx*1+ecx]
        +	mov	edx,-1
        +	add	ecx,eax
        +	mov	eax,edi
        +	rol	ecx,12
        +	add	ecx,ebp
        +	; 101
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 52[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1548603684[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	mov	eax,esi
        +	rol	ebp,8
        +	add	ebp,ebx
        +	; 102
        +	sub	edx,esi
        +	and	eax,ebp
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 20[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1548603684[edx*1+ebx]
        +	mov	edx,-1
        +	add	ebx,eax
        +	mov	eax,ecx
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 103
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 40[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1548603684[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	mov	eax,ebp
        +	rol	edi,11
        +	add	edi,esi
        +	; 104
        +	sub	edx,ebp
        +	and	eax,edi
        +	and	edx,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 56[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1548603684[edx*1+esi]
        +	mov	edx,-1
        +	add	esi,eax
        +	mov	eax,ebx
        +	rol	esi,7
        +	add	esi,ecx
        +	; 105
        +	sub	edx,ebx
        +	and	eax,esi
        +	and	edx,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 60[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1548603684[edx*1+ecx]
        +	mov	edx,-1
        +	add	ecx,eax
        +	mov	eax,edi
        +	rol	ecx,7
        +	add	ecx,ebp
        +	; 106
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 32[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1548603684[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	mov	eax,esi
        +	rol	ebp,12
        +	add	ebp,ebx
        +	; 107
        +	sub	edx,esi
        +	and	eax,ebp
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 48[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1548603684[edx*1+ebx]
        +	mov	edx,-1
        +	add	ebx,eax
        +	mov	eax,ecx
        +	rol	ebx,7
        +	add	ebx,edi
        +	; 108
        +	sub	edx,ecx
        +	and	eax,ebx
        +	and	edx,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR 16[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1548603684[edx*1+edi]
        +	mov	edx,-1
        +	add	edi,eax
        +	mov	eax,ebp
        +	rol	edi,6
        +	add	edi,esi
        +	; 109
        +	sub	edx,ebp
        +	and	eax,edi
        +	and	edx,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 36[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1548603684[edx*1+esi]
        +	mov	edx,-1
        +	add	esi,eax
        +	mov	eax,ebx
        +	rol	esi,15
        +	add	esi,ecx
        +	; 110
        +	sub	edx,ebx
        +	and	eax,esi
        +	and	edx,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1548603684[edx*1+ecx]
        +	mov	edx,-1
        +	add	ecx,eax
        +	mov	eax,edi
        +	rol	ecx,13
        +	add	ecx,ebp
        +	; 111
        +	sub	edx,edi
        +	and	eax,ecx
        +	and	edx,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 8[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1548603684[edx*1+ebp]
        +	mov	edx,-1
        +	add	ebp,eax
        +	sub	edx,ecx
        +	rol	ebp,11
        +	add	ebp,ebx
        +	; 112
        +	mov	eax,DWORD PTR 60[esp]
        +	or	edx,ebp
        +	add	ebx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1836072691[edx*1+ebx]
        +	sub	eax,ebp
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 113
        +	mov	edx,DWORD PTR 20[esp]
        +	or	eax,ebx
        +	add	edi,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1836072691[eax*1+edi]
        +	sub	edx,ebx
        +	rol	edi,7
        +	add	edi,esi
        +	; 114
        +	mov	eax,DWORD PTR 4[esp]
        +	or	edx,edi
        +	add	esi,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1836072691[edx*1+esi]
        +	sub	eax,edi
        +	rol	esi,15
        +	add	esi,ecx
        +	; 115
        +	mov	edx,DWORD PTR 12[esp]
        +	or	eax,esi
        +	add	ecx,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1836072691[eax*1+ecx]
        +	sub	edx,esi
        +	rol	ecx,11
        +	add	ecx,ebp
        +	; 116
        +	mov	eax,DWORD PTR 28[esp]
        +	or	edx,ecx
        +	add	ebp,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1836072691[edx*1+ebp]
        +	sub	eax,ecx
        +	rol	ebp,8
        +	add	ebp,ebx
        +	; 117
        +	mov	edx,DWORD PTR 56[esp]
        +	or	eax,ebp
        +	add	ebx,edx
        +	xor	eax,esi
        +	mov	edx,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1836072691[eax*1+ebx]
        +	sub	edx,ebp
        +	rol	ebx,6
        +	add	ebx,edi
        +	; 118
        +	mov	eax,DWORD PTR 24[esp]
        +	or	edx,ebx
        +	add	edi,eax
        +	xor	edx,ecx
        +	mov	eax,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1836072691[edx*1+edi]
        +	sub	eax,ebx
        +	rol	edi,6
        +	add	edi,esi
        +	; 119
        +	mov	edx,DWORD PTR 36[esp]
        +	or	eax,edi
        +	add	esi,edx
        +	xor	eax,ebp
        +	mov	edx,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1836072691[eax*1+esi]
        +	sub	edx,edi
        +	rol	esi,14
        +	add	esi,ecx
        +	; 120
        +	mov	eax,DWORD PTR 44[esp]
        +	or	edx,esi
        +	add	ecx,eax
        +	xor	edx,ebx
        +	mov	eax,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1836072691[edx*1+ecx]
        +	sub	eax,esi
        +	rol	ecx,12
        +	add	ecx,ebp
        +	; 121
        +	mov	edx,DWORD PTR 32[esp]
        +	or	eax,ecx
        +	add	ebp,edx
        +	xor	eax,edi
        +	mov	edx,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1836072691[eax*1+ebp]
        +	sub	edx,ecx
        +	rol	ebp,13
        +	add	ebp,ebx
        +	; 122
        +	mov	eax,DWORD PTR 48[esp]
        +	or	edx,ebp
        +	add	ebx,eax
        +	xor	edx,esi
        +	mov	eax,-1
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1836072691[edx*1+ebx]
        +	sub	eax,ebp
        +	rol	ebx,5
        +	add	ebx,edi
        +	; 123
        +	mov	edx,DWORD PTR 8[esp]
        +	or	eax,ebx
        +	add	edi,edx
        +	xor	eax,ecx
        +	mov	edx,-1
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 1836072691[eax*1+edi]
        +	sub	edx,ebx
        +	rol	edi,14
        +	add	edi,esi
        +	; 124
        +	mov	eax,DWORD PTR 40[esp]
        +	or	edx,edi
        +	add	esi,eax
        +	xor	edx,ebp
        +	mov	eax,-1
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 1836072691[edx*1+esi]
        +	sub	eax,edi
        +	rol	esi,13
        +	add	esi,ecx
        +	; 125
        +	mov	edx,DWORD PTR [esp]
        +	or	eax,esi
        +	add	ecx,edx
        +	xor	eax,ebx
        +	mov	edx,-1
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 1836072691[eax*1+ecx]
        +	sub	edx,esi
        +	rol	ecx,13
        +	add	ecx,ebp
        +	; 126
        +	mov	eax,DWORD PTR 16[esp]
        +	or	edx,ecx
        +	add	ebp,eax
        +	xor	edx,edi
        +	mov	eax,-1
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 1836072691[edx*1+ebp]
        +	sub	eax,ecx
        +	rol	ebp,7
        +	add	ebp,ebx
        +	; 127
        +	mov	edx,DWORD PTR 52[esp]
        +	or	eax,ebp
        +	add	ebx,edx
        +	xor	eax,esi
        +	mov	edx,DWORD PTR 32[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 1836072691[eax*1+ebx]
        +	mov	eax,-1
        +	rol	ebx,5
        +	add	ebx,edi
        +	; 128
        +	add	edi,edx
        +	mov	edx,ebp
        +	sub	eax,ebx
        +	and	edx,ebx
        +	and	eax,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 24[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2053994217[edx*1+edi]
        +	mov	edx,-1
        +	rol	edi,15
        +	add	edi,esi
        +	; 129
        +	add	esi,eax
        +	mov	eax,ebx
        +	sub	edx,edi
        +	and	eax,edi
        +	and	edx,ebp
        +	or	eax,edx
        +	mov	edx,DWORD PTR 16[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2053994217[eax*1+esi]
        +	mov	eax,-1
        +	rol	esi,5
        +	add	esi,ecx
        +	; 130
        +	add	ecx,edx
        +	mov	edx,edi
        +	sub	eax,esi
        +	and	edx,esi
        +	and	eax,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 4[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2053994217[edx*1+ecx]
        +	mov	edx,-1
        +	rol	ecx,8
        +	add	ecx,ebp
        +	; 131
        +	add	ebp,eax
        +	mov	eax,esi
        +	sub	edx,ecx
        +	and	eax,ecx
        +	and	edx,edi
        +	or	eax,edx
        +	mov	edx,DWORD PTR 12[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2053994217[eax*1+ebp]
        +	mov	eax,-1
        +	rol	ebp,11
        +	add	ebp,ebx
        +	; 132
        +	add	ebx,edx
        +	mov	edx,ecx
        +	sub	eax,ebp
        +	and	edx,ebp
        +	and	eax,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 44[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2053994217[edx*1+ebx]
        +	mov	edx,-1
        +	rol	ebx,14
        +	add	ebx,edi
        +	; 133
        +	add	edi,eax
        +	mov	eax,ebp
        +	sub	edx,ebx
        +	and	eax,ebx
        +	and	edx,ecx
        +	or	eax,edx
        +	mov	edx,DWORD PTR 60[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2053994217[eax*1+edi]
        +	mov	eax,-1
        +	rol	edi,14
        +	add	edi,esi
        +	; 134
        +	add	esi,edx
        +	mov	edx,ebx
        +	sub	eax,edi
        +	and	edx,edi
        +	and	eax,ebp
        +	or	edx,eax
        +	mov	eax,DWORD PTR [esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2053994217[edx*1+esi]
        +	mov	edx,-1
        +	rol	esi,6
        +	add	esi,ecx
        +	; 135
        +	add	ecx,eax
        +	mov	eax,edi
        +	sub	edx,esi
        +	and	eax,esi
        +	and	edx,ebx
        +	or	eax,edx
        +	mov	edx,DWORD PTR 20[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2053994217[eax*1+ecx]
        +	mov	eax,-1
        +	rol	ecx,14
        +	add	ecx,ebp
        +	; 136
        +	add	ebp,edx
        +	mov	edx,esi
        +	sub	eax,ecx
        +	and	edx,ecx
        +	and	eax,edi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 48[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2053994217[edx*1+ebp]
        +	mov	edx,-1
        +	rol	ebp,6
        +	add	ebp,ebx
        +	; 137
        +	add	ebx,eax
        +	mov	eax,ecx
        +	sub	edx,ebp
        +	and	eax,ebp
        +	and	edx,esi
        +	or	eax,edx
        +	mov	edx,DWORD PTR 8[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2053994217[eax*1+ebx]
        +	mov	eax,-1
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 138
        +	add	edi,edx
        +	mov	edx,ebp
        +	sub	eax,ebx
        +	and	edx,ebx
        +	and	eax,ecx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 52[esp]
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2053994217[edx*1+edi]
        +	mov	edx,-1
        +	rol	edi,12
        +	add	edi,esi
        +	; 139
        +	add	esi,eax
        +	mov	eax,ebx
        +	sub	edx,edi
        +	and	eax,edi
        +	and	edx,ebp
        +	or	eax,edx
        +	mov	edx,DWORD PTR 36[esp]
        +	rol	ebx,10
        +	lea	esi,DWORD PTR 2053994217[eax*1+esi]
        +	mov	eax,-1
        +	rol	esi,9
        +	add	esi,ecx
        +	; 140
        +	add	ecx,edx
        +	mov	edx,edi
        +	sub	eax,esi
        +	and	edx,esi
        +	and	eax,ebx
        +	or	edx,eax
        +	mov	eax,DWORD PTR 28[esp]
        +	rol	edi,10
        +	lea	ecx,DWORD PTR 2053994217[edx*1+ecx]
        +	mov	edx,-1
        +	rol	ecx,12
        +	add	ecx,ebp
        +	; 141
        +	add	ebp,eax
        +	mov	eax,esi
        +	sub	edx,ecx
        +	and	eax,ecx
        +	and	edx,edi
        +	or	eax,edx
        +	mov	edx,DWORD PTR 40[esp]
        +	rol	esi,10
        +	lea	ebp,DWORD PTR 2053994217[eax*1+ebp]
        +	mov	eax,-1
        +	rol	ebp,5
        +	add	ebp,ebx
        +	; 142
        +	add	ebx,edx
        +	mov	edx,ecx
        +	sub	eax,ebp
        +	and	edx,ebp
        +	and	eax,esi
        +	or	edx,eax
        +	mov	eax,DWORD PTR 56[esp]
        +	rol	ecx,10
        +	lea	ebx,DWORD PTR 2053994217[edx*1+ebx]
        +	mov	edx,-1
        +	rol	ebx,15
        +	add	ebx,edi
        +	; 143
        +	add	edi,eax
        +	mov	eax,ebp
        +	sub	edx,ebx
        +	and	eax,ebx
        +	and	edx,ecx
        +	or	edx,eax
        +	mov	eax,ebx
        +	rol	ebp,10
        +	lea	edi,DWORD PTR 2053994217[edx*1+edi]
        +	xor	eax,ebp
        +	rol	edi,8
        +	add	edi,esi
        +	; 144
        +	mov	edx,DWORD PTR 48[esp]
        +	xor	eax,edi
        +	add	esi,edx
        +	rol	ebx,10
        +	add	esi,eax
        +	mov	eax,edi
        +	rol	esi,8
        +	add	esi,ecx
        +	; 145
        +	xor	eax,ebx
        +	mov	edx,DWORD PTR 60[esp]
        +	xor	eax,esi
        +	add	ecx,eax
        +	mov	eax,esi
        +	rol	edi,10
        +	add	ecx,edx
        +	xor	eax,edi
        +	rol	ecx,5
        +	add	ecx,ebp
        +	; 146
        +	mov	edx,DWORD PTR 40[esp]
        +	xor	eax,ecx
        +	add	ebp,edx
        +	rol	esi,10
        +	add	ebp,eax
        +	mov	eax,ecx
        +	rol	ebp,12
        +	add	ebp,ebx
        +	; 147
        +	xor	eax,esi
        +	mov	edx,DWORD PTR 16[esp]
        +	xor	eax,ebp
        +	add	ebx,eax
        +	mov	eax,ebp
        +	rol	ecx,10
        +	add	ebx,edx
        +	xor	eax,ecx
        +	rol	ebx,9
        +	add	ebx,edi
        +	; 148
        +	mov	edx,DWORD PTR 4[esp]
        +	xor	eax,ebx
        +	add	edi,edx
        +	rol	ebp,10
        +	add	edi,eax
        +	mov	eax,ebx
        +	rol	edi,12
        +	add	edi,esi
        +	; 149
        +	xor	eax,ebp
        +	mov	edx,DWORD PTR 20[esp]
        +	xor	eax,edi
        +	add	esi,eax
        +	mov	eax,edi
        +	rol	ebx,10
        +	add	esi,edx
        +	xor	eax,ebx
        +	rol	esi,5
        +	add	esi,ecx
        +	; 150
        +	mov	edx,DWORD PTR 32[esp]
        +	xor	eax,esi
        +	add	ecx,edx
        +	rol	edi,10
        +	add	ecx,eax
        +	mov	eax,esi
        +	rol	ecx,14
        +	add	ecx,ebp
        +	; 151
        +	xor	eax,edi
        +	mov	edx,DWORD PTR 28[esp]
        +	xor	eax,ecx
        +	add	ebp,eax
        +	mov	eax,ecx
        +	rol	esi,10
        +	add	ebp,edx
        +	xor	eax,esi
        +	rol	ebp,6
        +	add	ebp,ebx
        +	; 152
        +	mov	edx,DWORD PTR 24[esp]
        +	xor	eax,ebp
        +	add	ebx,edx
        +	rol	ecx,10
        +	add	ebx,eax
        +	mov	eax,ebp
        +	rol	ebx,8
        +	add	ebx,edi
        +	; 153
        +	xor	eax,ecx
        +	mov	edx,DWORD PTR 8[esp]
        +	xor	eax,ebx
        +	add	edi,eax
        +	mov	eax,ebx
        +	rol	ebp,10
        +	add	edi,edx
        +	xor	eax,ebp
        +	rol	edi,13
        +	add	edi,esi
        +	; 154
        +	mov	edx,DWORD PTR 52[esp]
        +	xor	eax,edi
        +	add	esi,edx
        +	rol	ebx,10
        +	add	esi,eax
        +	mov	eax,edi
        +	rol	esi,6
        +	add	esi,ecx
        +	; 155
        +	xor	eax,ebx
        +	mov	edx,DWORD PTR 56[esp]
        +	xor	eax,esi
        +	add	ecx,eax
        +	mov	eax,esi
        +	rol	edi,10
        +	add	ecx,edx
        +	xor	eax,edi
        +	rol	ecx,5
        +	add	ecx,ebp
        +	; 156
        +	mov	edx,DWORD PTR [esp]
        +	xor	eax,ecx
        +	add	ebp,edx
        +	rol	esi,10
        +	add	ebp,eax
        +	mov	eax,ecx
        +	rol	ebp,15
        +	add	ebp,ebx
        +	; 157
        +	xor	eax,esi
        +	mov	edx,DWORD PTR 12[esp]
        +	xor	eax,ebp
        +	add	ebx,eax
        +	mov	eax,ebp
        +	rol	ecx,10
        +	add	ebx,edx
        +	xor	eax,ecx
        +	rol	ebx,13
        +	add	ebx,edi
        +	; 158
        +	mov	edx,DWORD PTR 36[esp]
        +	xor	eax,ebx
        +	add	edi,edx
        +	rol	ebp,10
        +	add	edi,eax
        +	mov	eax,ebx
        +	rol	edi,11
        +	add	edi,esi
        +	; 159
        +	xor	eax,ebp
        +	mov	edx,DWORD PTR 44[esp]
        +	xor	eax,edi
        +	add	esi,eax
        +	rol	ebx,10
        +	add	esi,edx
        +	mov	edx,DWORD PTR 128[esp]
        +	rol	esi,11
        +	add	esi,ecx
        +	mov	eax,DWORD PTR 4[edx]
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 72[esp]
        +	add	ebx,eax
        +	mov	eax,DWORD PTR 8[edx]
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 76[esp]
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 12[edx]
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 80[esp]
        +	add	ecx,eax
        +	mov	eax,DWORD PTR 16[edx]
        +	add	esi,eax
        +	mov	eax,DWORD PTR 64[esp]
        +	add	esi,eax
        +	mov	eax,DWORD PTR [edx]
        +	add	edi,eax
        +	mov	eax,DWORD PTR 68[esp]
        +	add	edi,eax
        +	mov	eax,DWORD PTR 136[esp]
        +	mov	DWORD PTR [edx],ebx
        +	mov	DWORD PTR 4[edx],ebp
        +	mov	DWORD PTR 8[edx],ecx
        +	sub	eax,1
        +	mov	DWORD PTR 12[edx],esi
        +	mov	DWORD PTR 16[edx],edi
        +	jle	$L001get_out
        +	mov	DWORD PTR 136[esp],eax
        +	mov	edi,ecx
        +	mov	eax,DWORD PTR 132[esp]
        +	mov	ecx,ebx
        +	add	eax,64
        +	mov	esi,ebp
        +	mov	DWORD PTR 132[esp],eax
        +	jmp	$L000start
        +$L001get_out:
        +	add	esp,108
        +	pop	ebx
        +	pop	ebp
        +	pop	edi
        +	pop	esi
        +	ret
        +_ripemd160_block_asm_data_order ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/sha/sha1-586.asm b/vendor/openssl/asm/x86-win32-masm/sha/sha1-586.asm
        new file mode 100644
        index 000000000..878b1d3b9
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/sha/sha1-586.asm
        @@ -0,0 +1,1390 @@
        +TITLE	sha1-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_sha1_block_data_order	PROC PUBLIC
        +$L_sha1_block_data_order_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	ebp,DWORD PTR 20[esp]
        +	mov	esi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	sub	esp,76
        +	shl	eax,6
        +	add	eax,esi
        +	mov	DWORD PTR 104[esp],eax
        +	mov	edi,DWORD PTR 16[ebp]
        +	jmp	$L000loop
        +ALIGN	16
        +$L000loop:
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	mov	DWORD PTR 12[esp],edx
        +	mov	eax,DWORD PTR 16[esi]
        +	mov	ebx,DWORD PTR 20[esi]
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 28[esi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR 16[esp],eax
        +	mov	DWORD PTR 20[esp],ebx
        +	mov	DWORD PTR 24[esp],ecx
        +	mov	DWORD PTR 28[esp],edx
        +	mov	eax,DWORD PTR 32[esi]
        +	mov	ebx,DWORD PTR 36[esi]
        +	mov	ecx,DWORD PTR 40[esi]
        +	mov	edx,DWORD PTR 44[esi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR 32[esp],eax
        +	mov	DWORD PTR 36[esp],ebx
        +	mov	DWORD PTR 40[esp],ecx
        +	mov	DWORD PTR 44[esp],edx
        +	mov	eax,DWORD PTR 48[esi]
        +	mov	ebx,DWORD PTR 52[esi]
        +	mov	ecx,DWORD PTR 56[esi]
        +	mov	edx,DWORD PTR 60[esi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	mov	DWORD PTR 48[esp],eax
        +	mov	DWORD PTR 52[esp],ebx
        +	mov	DWORD PTR 56[esp],ecx
        +	mov	DWORD PTR 60[esp],edx
        +	mov	DWORD PTR 100[esp],esi
        +	mov	eax,DWORD PTR [ebp]
        +	mov	ebx,DWORD PTR 4[ebp]
        +	mov	ecx,DWORD PTR 8[ebp]
        +	mov	edx,DWORD PTR 12[ebp]
        +	; 00_15 0
        +	mov	esi,ecx
        +	mov	ebp,eax
        +	rol	ebp,5
        +	xor	esi,edx
        +	add	ebp,edi
        +	mov	edi,DWORD PTR [esp]
        +	and	esi,ebx
        +	ror	ebx,2
        +	xor	esi,edx
        +	lea	ebp,DWORD PTR 1518500249[edi*1+ebp]
        +	add	ebp,esi
        +	; 00_15 1
        +	mov	edi,ebx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ecx
        +	add	ebp,edx
        +	mov	edx,DWORD PTR 4[esp]
        +	and	edi,eax
        +	ror	eax,2
        +	xor	edi,ecx
        +	lea	ebp,DWORD PTR 1518500249[edx*1+ebp]
        +	add	ebp,edi
        +	; 00_15 2
        +	mov	edx,eax
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	edx,ebx
        +	add	ebp,ecx
        +	mov	ecx,DWORD PTR 8[esp]
        +	and	edx,esi
        +	ror	esi,2
        +	xor	edx,ebx
        +	lea	ebp,DWORD PTR 1518500249[ecx*1+ebp]
        +	add	ebp,edx
        +	; 00_15 3
        +	mov	ecx,esi
        +	mov	edx,ebp
        +	rol	ebp,5
        +	xor	ecx,eax
        +	add	ebp,ebx
        +	mov	ebx,DWORD PTR 12[esp]
        +	and	ecx,edi
        +	ror	edi,2
        +	xor	ecx,eax
        +	lea	ebp,DWORD PTR 1518500249[ebx*1+ebp]
        +	add	ebp,ecx
        +	; 00_15 4
        +	mov	ebx,edi
        +	mov	ecx,ebp
        +	rol	ebp,5
        +	xor	ebx,esi
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 16[esp]
        +	and	ebx,edx
        +	ror	edx,2
        +	xor	ebx,esi
        +	lea	ebp,DWORD PTR 1518500249[eax*1+ebp]
        +	add	ebp,ebx
        +	; 00_15 5
        +	mov	eax,edx
        +	mov	ebx,ebp
        +	rol	ebp,5
        +	xor	eax,edi
        +	add	ebp,esi
        +	mov	esi,DWORD PTR 20[esp]
        +	and	eax,ecx
        +	ror	ecx,2
        +	xor	eax,edi
        +	lea	ebp,DWORD PTR 1518500249[esi*1+ebp]
        +	add	ebp,eax
        +	; 00_15 6
        +	mov	esi,ecx
        +	mov	eax,ebp
        +	rol	ebp,5
        +	xor	esi,edx
        +	add	ebp,edi
        +	mov	edi,DWORD PTR 24[esp]
        +	and	esi,ebx
        +	ror	ebx,2
        +	xor	esi,edx
        +	lea	ebp,DWORD PTR 1518500249[edi*1+ebp]
        +	add	ebp,esi
        +	; 00_15 7
        +	mov	edi,ebx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ecx
        +	add	ebp,edx
        +	mov	edx,DWORD PTR 28[esp]
        +	and	edi,eax
        +	ror	eax,2
        +	xor	edi,ecx
        +	lea	ebp,DWORD PTR 1518500249[edx*1+ebp]
        +	add	ebp,edi
        +	; 00_15 8
        +	mov	edx,eax
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	edx,ebx
        +	add	ebp,ecx
        +	mov	ecx,DWORD PTR 32[esp]
        +	and	edx,esi
        +	ror	esi,2
        +	xor	edx,ebx
        +	lea	ebp,DWORD PTR 1518500249[ecx*1+ebp]
        +	add	ebp,edx
        +	; 00_15 9
        +	mov	ecx,esi
        +	mov	edx,ebp
        +	rol	ebp,5
        +	xor	ecx,eax
        +	add	ebp,ebx
        +	mov	ebx,DWORD PTR 36[esp]
        +	and	ecx,edi
        +	ror	edi,2
        +	xor	ecx,eax
        +	lea	ebp,DWORD PTR 1518500249[ebx*1+ebp]
        +	add	ebp,ecx
        +	; 00_15 10
        +	mov	ebx,edi
        +	mov	ecx,ebp
        +	rol	ebp,5
        +	xor	ebx,esi
        +	add	ebp,eax
        +	mov	eax,DWORD PTR 40[esp]
        +	and	ebx,edx
        +	ror	edx,2
        +	xor	ebx,esi
        +	lea	ebp,DWORD PTR 1518500249[eax*1+ebp]
        +	add	ebp,ebx
        +	; 00_15 11
        +	mov	eax,edx
        +	mov	ebx,ebp
        +	rol	ebp,5
        +	xor	eax,edi
        +	add	ebp,esi
        +	mov	esi,DWORD PTR 44[esp]
        +	and	eax,ecx
        +	ror	ecx,2
        +	xor	eax,edi
        +	lea	ebp,DWORD PTR 1518500249[esi*1+ebp]
        +	add	ebp,eax
        +	; 00_15 12
        +	mov	esi,ecx
        +	mov	eax,ebp
        +	rol	ebp,5
        +	xor	esi,edx
        +	add	ebp,edi
        +	mov	edi,DWORD PTR 48[esp]
        +	and	esi,ebx
        +	ror	ebx,2
        +	xor	esi,edx
        +	lea	ebp,DWORD PTR 1518500249[edi*1+ebp]
        +	add	ebp,esi
        +	; 00_15 13
        +	mov	edi,ebx
        +	mov	esi,ebp
        +	rol	ebp,5
        +	xor	edi,ecx
        +	add	ebp,edx
        +	mov	edx,DWORD PTR 52[esp]
        +	and	edi,eax
        +	ror	eax,2
        +	xor	edi,ecx
        +	lea	ebp,DWORD PTR 1518500249[edx*1+ebp]
        +	add	ebp,edi
        +	; 00_15 14
        +	mov	edx,eax
        +	mov	edi,ebp
        +	rol	ebp,5
        +	xor	edx,ebx
        +	add	ebp,ecx
        +	mov	ecx,DWORD PTR 56[esp]
        +	and	edx,esi
        +	ror	esi,2
        +	xor	edx,ebx
        +	lea	ebp,DWORD PTR 1518500249[ecx*1+ebp]
        +	add	ebp,edx
        +	; 00_15 15
        +	mov	ecx,esi
        +	mov	edx,ebp
        +	rol	ebp,5
        +	xor	ecx,eax
        +	add	ebp,ebx
        +	mov	ebx,DWORD PTR 60[esp]
        +	and	ecx,edi
        +	ror	edi,2
        +	xor	ecx,eax
        +	lea	ebp,DWORD PTR 1518500249[ebx*1+ebp]
        +	mov	ebx,DWORD PTR [esp]
        +	add	ecx,ebp
        +	; 16_19 16
        +	mov	ebp,edi
        +	xor	ebx,DWORD PTR 8[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 32[esp]
        +	and	ebp,edx
        +	xor	ebx,DWORD PTR 52[esp]
        +	rol	ebx,1
        +	xor	ebp,esi
        +	add	eax,ebp
        +	mov	ebp,ecx
        +	ror	edx,2
        +	mov	DWORD PTR [esp],ebx
        +	rol	ebp,5
        +	lea	ebx,DWORD PTR 1518500249[eax*1+ebx]
        +	mov	eax,DWORD PTR 4[esp]
        +	add	ebx,ebp
        +	; 16_19 17
        +	mov	ebp,edx
        +	xor	eax,DWORD PTR 12[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 36[esp]
        +	and	ebp,ecx
        +	xor	eax,DWORD PTR 56[esp]
        +	rol	eax,1
        +	xor	ebp,edi
        +	add	esi,ebp
        +	mov	ebp,ebx
        +	ror	ecx,2
        +	mov	DWORD PTR 4[esp],eax
        +	rol	ebp,5
        +	lea	eax,DWORD PTR 1518500249[esi*1+eax]
        +	mov	esi,DWORD PTR 8[esp]
        +	add	eax,ebp
        +	; 16_19 18
        +	mov	ebp,ecx
        +	xor	esi,DWORD PTR 16[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 40[esp]
        +	and	ebp,ebx
        +	xor	esi,DWORD PTR 60[esp]
        +	rol	esi,1
        +	xor	ebp,edx
        +	add	edi,ebp
        +	mov	ebp,eax
        +	ror	ebx,2
        +	mov	DWORD PTR 8[esp],esi
        +	rol	ebp,5
        +	lea	esi,DWORD PTR 1518500249[edi*1+esi]
        +	mov	edi,DWORD PTR 12[esp]
        +	add	esi,ebp
        +	; 16_19 19
        +	mov	ebp,ebx
        +	xor	edi,DWORD PTR 20[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 44[esp]
        +	and	ebp,eax
        +	xor	edi,DWORD PTR [esp]
        +	rol	edi,1
        +	xor	ebp,ecx
        +	add	edx,ebp
        +	mov	ebp,esi
        +	ror	eax,2
        +	mov	DWORD PTR 12[esp],edi
        +	rol	ebp,5
        +	lea	edi,DWORD PTR 1518500249[edx*1+edi]
        +	mov	edx,DWORD PTR 16[esp]
        +	add	edi,ebp
        +	; 20_39 20
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR 24[esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 48[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 4[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR 16[esp],edx
        +	lea	edx,DWORD PTR 1859775393[ecx*1+edx]
        +	mov	ecx,DWORD PTR 20[esp]
        +	add	edx,ebp
        +	; 20_39 21
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 28[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 52[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 8[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 20[esp],ecx
        +	lea	ecx,DWORD PTR 1859775393[ebx*1+ecx]
        +	mov	ebx,DWORD PTR 24[esp]
        +	add	ecx,ebp
        +	; 20_39 22
        +	mov	ebp,edx
        +	xor	ebx,DWORD PTR 32[esp]
        +	xor	ebp,edi
        +	xor	ebx,DWORD PTR 56[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 12[esp]
        +	rol	ebx,1
        +	add	eax,ebp
        +	ror	edx,2
        +	mov	ebp,ecx
        +	rol	ebp,5
        +	mov	DWORD PTR 24[esp],ebx
        +	lea	ebx,DWORD PTR 1859775393[eax*1+ebx]
        +	mov	eax,DWORD PTR 28[esp]
        +	add	ebx,ebp
        +	; 20_39 23
        +	mov	ebp,ecx
        +	xor	eax,DWORD PTR 36[esp]
        +	xor	ebp,edx
        +	xor	eax,DWORD PTR 60[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 16[esp]
        +	rol	eax,1
        +	add	esi,ebp
        +	ror	ecx,2
        +	mov	ebp,ebx
        +	rol	ebp,5
        +	mov	DWORD PTR 28[esp],eax
        +	lea	eax,DWORD PTR 1859775393[esi*1+eax]
        +	mov	esi,DWORD PTR 32[esp]
        +	add	eax,ebp
        +	; 20_39 24
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR 40[esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR [esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 20[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	mov	DWORD PTR 32[esp],esi
        +	lea	esi,DWORD PTR 1859775393[edi*1+esi]
        +	mov	edi,DWORD PTR 36[esp]
        +	add	esi,ebp
        +	; 20_39 25
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 44[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 4[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 24[esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	mov	DWORD PTR 36[esp],edi
        +	lea	edi,DWORD PTR 1859775393[edx*1+edi]
        +	mov	edx,DWORD PTR 40[esp]
        +	add	edi,ebp
        +	; 20_39 26
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR 48[esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 8[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 28[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR 40[esp],edx
        +	lea	edx,DWORD PTR 1859775393[ecx*1+edx]
        +	mov	ecx,DWORD PTR 44[esp]
        +	add	edx,ebp
        +	; 20_39 27
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 52[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 12[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 32[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 44[esp],ecx
        +	lea	ecx,DWORD PTR 1859775393[ebx*1+ecx]
        +	mov	ebx,DWORD PTR 48[esp]
        +	add	ecx,ebp
        +	; 20_39 28
        +	mov	ebp,edx
        +	xor	ebx,DWORD PTR 56[esp]
        +	xor	ebp,edi
        +	xor	ebx,DWORD PTR 16[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 36[esp]
        +	rol	ebx,1
        +	add	eax,ebp
        +	ror	edx,2
        +	mov	ebp,ecx
        +	rol	ebp,5
        +	mov	DWORD PTR 48[esp],ebx
        +	lea	ebx,DWORD PTR 1859775393[eax*1+ebx]
        +	mov	eax,DWORD PTR 52[esp]
        +	add	ebx,ebp
        +	; 20_39 29
        +	mov	ebp,ecx
        +	xor	eax,DWORD PTR 60[esp]
        +	xor	ebp,edx
        +	xor	eax,DWORD PTR 20[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 40[esp]
        +	rol	eax,1
        +	add	esi,ebp
        +	ror	ecx,2
        +	mov	ebp,ebx
        +	rol	ebp,5
        +	mov	DWORD PTR 52[esp],eax
        +	lea	eax,DWORD PTR 1859775393[esi*1+eax]
        +	mov	esi,DWORD PTR 56[esp]
        +	add	eax,ebp
        +	; 20_39 30
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR [esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR 24[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 44[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	mov	DWORD PTR 56[esp],esi
        +	lea	esi,DWORD PTR 1859775393[edi*1+esi]
        +	mov	edi,DWORD PTR 60[esp]
        +	add	esi,ebp
        +	; 20_39 31
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 4[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 28[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 48[esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	mov	DWORD PTR 60[esp],edi
        +	lea	edi,DWORD PTR 1859775393[edx*1+edi]
        +	mov	edx,DWORD PTR [esp]
        +	add	edi,ebp
        +	; 20_39 32
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR 8[esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 32[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 52[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR [esp],edx
        +	lea	edx,DWORD PTR 1859775393[ecx*1+edx]
        +	mov	ecx,DWORD PTR 4[esp]
        +	add	edx,ebp
        +	; 20_39 33
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 12[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 36[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 56[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 4[esp],ecx
        +	lea	ecx,DWORD PTR 1859775393[ebx*1+ecx]
        +	mov	ebx,DWORD PTR 8[esp]
        +	add	ecx,ebp
        +	; 20_39 34
        +	mov	ebp,edx
        +	xor	ebx,DWORD PTR 16[esp]
        +	xor	ebp,edi
        +	xor	ebx,DWORD PTR 40[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 60[esp]
        +	rol	ebx,1
        +	add	eax,ebp
        +	ror	edx,2
        +	mov	ebp,ecx
        +	rol	ebp,5
        +	mov	DWORD PTR 8[esp],ebx
        +	lea	ebx,DWORD PTR 1859775393[eax*1+ebx]
        +	mov	eax,DWORD PTR 12[esp]
        +	add	ebx,ebp
        +	; 20_39 35
        +	mov	ebp,ecx
        +	xor	eax,DWORD PTR 20[esp]
        +	xor	ebp,edx
        +	xor	eax,DWORD PTR 44[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR [esp]
        +	rol	eax,1
        +	add	esi,ebp
        +	ror	ecx,2
        +	mov	ebp,ebx
        +	rol	ebp,5
        +	mov	DWORD PTR 12[esp],eax
        +	lea	eax,DWORD PTR 1859775393[esi*1+eax]
        +	mov	esi,DWORD PTR 16[esp]
        +	add	eax,ebp
        +	; 20_39 36
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR 24[esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR 48[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 4[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	mov	DWORD PTR 16[esp],esi
        +	lea	esi,DWORD PTR 1859775393[edi*1+esi]
        +	mov	edi,DWORD PTR 20[esp]
        +	add	esi,ebp
        +	; 20_39 37
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 28[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 52[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 8[esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	mov	DWORD PTR 20[esp],edi
        +	lea	edi,DWORD PTR 1859775393[edx*1+edi]
        +	mov	edx,DWORD PTR 24[esp]
        +	add	edi,ebp
        +	; 20_39 38
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR 32[esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 56[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 12[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR 24[esp],edx
        +	lea	edx,DWORD PTR 1859775393[ecx*1+edx]
        +	mov	ecx,DWORD PTR 28[esp]
        +	add	edx,ebp
        +	; 20_39 39
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 36[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 60[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 16[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 28[esp],ecx
        +	lea	ecx,DWORD PTR 1859775393[ebx*1+ecx]
        +	mov	ebx,DWORD PTR 32[esp]
        +	add	ecx,ebp
        +	; 40_59 40
        +	mov	ebp,edi
        +	xor	ebx,DWORD PTR 40[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR [esp]
        +	and	ebp,edx
        +	xor	ebx,DWORD PTR 20[esp]
        +	rol	ebx,1
        +	add	ebp,eax
        +	ror	edx,2
        +	mov	eax,ecx
        +	rol	eax,5
        +	mov	DWORD PTR 32[esp],ebx
        +	lea	ebx,DWORD PTR 2400959708[ebp*1+ebx]
        +	mov	ebp,edi
        +	add	ebx,eax
        +	and	ebp,esi
        +	mov	eax,DWORD PTR 36[esp]
        +	add	ebx,ebp
        +	; 40_59 41
        +	mov	ebp,edx
        +	xor	eax,DWORD PTR 44[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 4[esp]
        +	and	ebp,ecx
        +	xor	eax,DWORD PTR 24[esp]
        +	rol	eax,1
        +	add	ebp,esi
        +	ror	ecx,2
        +	mov	esi,ebx
        +	rol	esi,5
        +	mov	DWORD PTR 36[esp],eax
        +	lea	eax,DWORD PTR 2400959708[ebp*1+eax]
        +	mov	ebp,edx
        +	add	eax,esi
        +	and	ebp,edi
        +	mov	esi,DWORD PTR 40[esp]
        +	add	eax,ebp
        +	; 40_59 42
        +	mov	ebp,ecx
        +	xor	esi,DWORD PTR 48[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 8[esp]
        +	and	ebp,ebx
        +	xor	esi,DWORD PTR 28[esp]
        +	rol	esi,1
        +	add	ebp,edi
        +	ror	ebx,2
        +	mov	edi,eax
        +	rol	edi,5
        +	mov	DWORD PTR 40[esp],esi
        +	lea	esi,DWORD PTR 2400959708[ebp*1+esi]
        +	mov	ebp,ecx
        +	add	esi,edi
        +	and	ebp,edx
        +	mov	edi,DWORD PTR 44[esp]
        +	add	esi,ebp
        +	; 40_59 43
        +	mov	ebp,ebx
        +	xor	edi,DWORD PTR 52[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 12[esp]
        +	and	ebp,eax
        +	xor	edi,DWORD PTR 32[esp]
        +	rol	edi,1
        +	add	ebp,edx
        +	ror	eax,2
        +	mov	edx,esi
        +	rol	edx,5
        +	mov	DWORD PTR 44[esp],edi
        +	lea	edi,DWORD PTR 2400959708[ebp*1+edi]
        +	mov	ebp,ebx
        +	add	edi,edx
        +	and	ebp,ecx
        +	mov	edx,DWORD PTR 48[esp]
        +	add	edi,ebp
        +	; 40_59 44
        +	mov	ebp,eax
        +	xor	edx,DWORD PTR 56[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 16[esp]
        +	and	ebp,esi
        +	xor	edx,DWORD PTR 36[esp]
        +	rol	edx,1
        +	add	ebp,ecx
        +	ror	esi,2
        +	mov	ecx,edi
        +	rol	ecx,5
        +	mov	DWORD PTR 48[esp],edx
        +	lea	edx,DWORD PTR 2400959708[ebp*1+edx]
        +	mov	ebp,eax
        +	add	edx,ecx
        +	and	ebp,ebx
        +	mov	ecx,DWORD PTR 52[esp]
        +	add	edx,ebp
        +	; 40_59 45
        +	mov	ebp,esi
        +	xor	ecx,DWORD PTR 60[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 20[esp]
        +	and	ebp,edi
        +	xor	ecx,DWORD PTR 40[esp]
        +	rol	ecx,1
        +	add	ebp,ebx
        +	ror	edi,2
        +	mov	ebx,edx
        +	rol	ebx,5
        +	mov	DWORD PTR 52[esp],ecx
        +	lea	ecx,DWORD PTR 2400959708[ebp*1+ecx]
        +	mov	ebp,esi
        +	add	ecx,ebx
        +	and	ebp,eax
        +	mov	ebx,DWORD PTR 56[esp]
        +	add	ecx,ebp
        +	; 40_59 46
        +	mov	ebp,edi
        +	xor	ebx,DWORD PTR [esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 24[esp]
        +	and	ebp,edx
        +	xor	ebx,DWORD PTR 44[esp]
        +	rol	ebx,1
        +	add	ebp,eax
        +	ror	edx,2
        +	mov	eax,ecx
        +	rol	eax,5
        +	mov	DWORD PTR 56[esp],ebx
        +	lea	ebx,DWORD PTR 2400959708[ebp*1+ebx]
        +	mov	ebp,edi
        +	add	ebx,eax
        +	and	ebp,esi
        +	mov	eax,DWORD PTR 60[esp]
        +	add	ebx,ebp
        +	; 40_59 47
        +	mov	ebp,edx
        +	xor	eax,DWORD PTR 4[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 28[esp]
        +	and	ebp,ecx
        +	xor	eax,DWORD PTR 48[esp]
        +	rol	eax,1
        +	add	ebp,esi
        +	ror	ecx,2
        +	mov	esi,ebx
        +	rol	esi,5
        +	mov	DWORD PTR 60[esp],eax
        +	lea	eax,DWORD PTR 2400959708[ebp*1+eax]
        +	mov	ebp,edx
        +	add	eax,esi
        +	and	ebp,edi
        +	mov	esi,DWORD PTR [esp]
        +	add	eax,ebp
        +	; 40_59 48
        +	mov	ebp,ecx
        +	xor	esi,DWORD PTR 8[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 32[esp]
        +	and	ebp,ebx
        +	xor	esi,DWORD PTR 52[esp]
        +	rol	esi,1
        +	add	ebp,edi
        +	ror	ebx,2
        +	mov	edi,eax
        +	rol	edi,5
        +	mov	DWORD PTR [esp],esi
        +	lea	esi,DWORD PTR 2400959708[ebp*1+esi]
        +	mov	ebp,ecx
        +	add	esi,edi
        +	and	ebp,edx
        +	mov	edi,DWORD PTR 4[esp]
        +	add	esi,ebp
        +	; 40_59 49
        +	mov	ebp,ebx
        +	xor	edi,DWORD PTR 12[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 36[esp]
        +	and	ebp,eax
        +	xor	edi,DWORD PTR 56[esp]
        +	rol	edi,1
        +	add	ebp,edx
        +	ror	eax,2
        +	mov	edx,esi
        +	rol	edx,5
        +	mov	DWORD PTR 4[esp],edi
        +	lea	edi,DWORD PTR 2400959708[ebp*1+edi]
        +	mov	ebp,ebx
        +	add	edi,edx
        +	and	ebp,ecx
        +	mov	edx,DWORD PTR 8[esp]
        +	add	edi,ebp
        +	; 40_59 50
        +	mov	ebp,eax
        +	xor	edx,DWORD PTR 16[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 40[esp]
        +	and	ebp,esi
        +	xor	edx,DWORD PTR 60[esp]
        +	rol	edx,1
        +	add	ebp,ecx
        +	ror	esi,2
        +	mov	ecx,edi
        +	rol	ecx,5
        +	mov	DWORD PTR 8[esp],edx
        +	lea	edx,DWORD PTR 2400959708[ebp*1+edx]
        +	mov	ebp,eax
        +	add	edx,ecx
        +	and	ebp,ebx
        +	mov	ecx,DWORD PTR 12[esp]
        +	add	edx,ebp
        +	; 40_59 51
        +	mov	ebp,esi
        +	xor	ecx,DWORD PTR 20[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 44[esp]
        +	and	ebp,edi
        +	xor	ecx,DWORD PTR [esp]
        +	rol	ecx,1
        +	add	ebp,ebx
        +	ror	edi,2
        +	mov	ebx,edx
        +	rol	ebx,5
        +	mov	DWORD PTR 12[esp],ecx
        +	lea	ecx,DWORD PTR 2400959708[ebp*1+ecx]
        +	mov	ebp,esi
        +	add	ecx,ebx
        +	and	ebp,eax
        +	mov	ebx,DWORD PTR 16[esp]
        +	add	ecx,ebp
        +	; 40_59 52
        +	mov	ebp,edi
        +	xor	ebx,DWORD PTR 24[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 48[esp]
        +	and	ebp,edx
        +	xor	ebx,DWORD PTR 4[esp]
        +	rol	ebx,1
        +	add	ebp,eax
        +	ror	edx,2
        +	mov	eax,ecx
        +	rol	eax,5
        +	mov	DWORD PTR 16[esp],ebx
        +	lea	ebx,DWORD PTR 2400959708[ebp*1+ebx]
        +	mov	ebp,edi
        +	add	ebx,eax
        +	and	ebp,esi
        +	mov	eax,DWORD PTR 20[esp]
        +	add	ebx,ebp
        +	; 40_59 53
        +	mov	ebp,edx
        +	xor	eax,DWORD PTR 28[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 52[esp]
        +	and	ebp,ecx
        +	xor	eax,DWORD PTR 8[esp]
        +	rol	eax,1
        +	add	ebp,esi
        +	ror	ecx,2
        +	mov	esi,ebx
        +	rol	esi,5
        +	mov	DWORD PTR 20[esp],eax
        +	lea	eax,DWORD PTR 2400959708[ebp*1+eax]
        +	mov	ebp,edx
        +	add	eax,esi
        +	and	ebp,edi
        +	mov	esi,DWORD PTR 24[esp]
        +	add	eax,ebp
        +	; 40_59 54
        +	mov	ebp,ecx
        +	xor	esi,DWORD PTR 32[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 56[esp]
        +	and	ebp,ebx
        +	xor	esi,DWORD PTR 12[esp]
        +	rol	esi,1
        +	add	ebp,edi
        +	ror	ebx,2
        +	mov	edi,eax
        +	rol	edi,5
        +	mov	DWORD PTR 24[esp],esi
        +	lea	esi,DWORD PTR 2400959708[ebp*1+esi]
        +	mov	ebp,ecx
        +	add	esi,edi
        +	and	ebp,edx
        +	mov	edi,DWORD PTR 28[esp]
        +	add	esi,ebp
        +	; 40_59 55
        +	mov	ebp,ebx
        +	xor	edi,DWORD PTR 36[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 60[esp]
        +	and	ebp,eax
        +	xor	edi,DWORD PTR 16[esp]
        +	rol	edi,1
        +	add	ebp,edx
        +	ror	eax,2
        +	mov	edx,esi
        +	rol	edx,5
        +	mov	DWORD PTR 28[esp],edi
        +	lea	edi,DWORD PTR 2400959708[ebp*1+edi]
        +	mov	ebp,ebx
        +	add	edi,edx
        +	and	ebp,ecx
        +	mov	edx,DWORD PTR 32[esp]
        +	add	edi,ebp
        +	; 40_59 56
        +	mov	ebp,eax
        +	xor	edx,DWORD PTR 40[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR [esp]
        +	and	ebp,esi
        +	xor	edx,DWORD PTR 20[esp]
        +	rol	edx,1
        +	add	ebp,ecx
        +	ror	esi,2
        +	mov	ecx,edi
        +	rol	ecx,5
        +	mov	DWORD PTR 32[esp],edx
        +	lea	edx,DWORD PTR 2400959708[ebp*1+edx]
        +	mov	ebp,eax
        +	add	edx,ecx
        +	and	ebp,ebx
        +	mov	ecx,DWORD PTR 36[esp]
        +	add	edx,ebp
        +	; 40_59 57
        +	mov	ebp,esi
        +	xor	ecx,DWORD PTR 44[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 4[esp]
        +	and	ebp,edi
        +	xor	ecx,DWORD PTR 24[esp]
        +	rol	ecx,1
        +	add	ebp,ebx
        +	ror	edi,2
        +	mov	ebx,edx
        +	rol	ebx,5
        +	mov	DWORD PTR 36[esp],ecx
        +	lea	ecx,DWORD PTR 2400959708[ebp*1+ecx]
        +	mov	ebp,esi
        +	add	ecx,ebx
        +	and	ebp,eax
        +	mov	ebx,DWORD PTR 40[esp]
        +	add	ecx,ebp
        +	; 40_59 58
        +	mov	ebp,edi
        +	xor	ebx,DWORD PTR 48[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 8[esp]
        +	and	ebp,edx
        +	xor	ebx,DWORD PTR 28[esp]
        +	rol	ebx,1
        +	add	ebp,eax
        +	ror	edx,2
        +	mov	eax,ecx
        +	rol	eax,5
        +	mov	DWORD PTR 40[esp],ebx
        +	lea	ebx,DWORD PTR 2400959708[ebp*1+ebx]
        +	mov	ebp,edi
        +	add	ebx,eax
        +	and	ebp,esi
        +	mov	eax,DWORD PTR 44[esp]
        +	add	ebx,ebp
        +	; 40_59 59
        +	mov	ebp,edx
        +	xor	eax,DWORD PTR 52[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 12[esp]
        +	and	ebp,ecx
        +	xor	eax,DWORD PTR 32[esp]
        +	rol	eax,1
        +	add	ebp,esi
        +	ror	ecx,2
        +	mov	esi,ebx
        +	rol	esi,5
        +	mov	DWORD PTR 44[esp],eax
        +	lea	eax,DWORD PTR 2400959708[ebp*1+eax]
        +	mov	ebp,edx
        +	add	eax,esi
        +	and	ebp,edi
        +	mov	esi,DWORD PTR 48[esp]
        +	add	eax,ebp
        +	; 20_39 60
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR 56[esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR 16[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 36[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	mov	DWORD PTR 48[esp],esi
        +	lea	esi,DWORD PTR 3395469782[edi*1+esi]
        +	mov	edi,DWORD PTR 52[esp]
        +	add	esi,ebp
        +	; 20_39 61
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 60[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 20[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 40[esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	mov	DWORD PTR 52[esp],edi
        +	lea	edi,DWORD PTR 3395469782[edx*1+edi]
        +	mov	edx,DWORD PTR 56[esp]
        +	add	edi,ebp
        +	; 20_39 62
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR [esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 24[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 44[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR 56[esp],edx
        +	lea	edx,DWORD PTR 3395469782[ecx*1+edx]
        +	mov	ecx,DWORD PTR 60[esp]
        +	add	edx,ebp
        +	; 20_39 63
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 4[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 28[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 48[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 60[esp],ecx
        +	lea	ecx,DWORD PTR 3395469782[ebx*1+ecx]
        +	mov	ebx,DWORD PTR [esp]
        +	add	ecx,ebp
        +	; 20_39 64
        +	mov	ebp,edx
        +	xor	ebx,DWORD PTR 8[esp]
        +	xor	ebp,edi
        +	xor	ebx,DWORD PTR 32[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 52[esp]
        +	rol	ebx,1
        +	add	eax,ebp
        +	ror	edx,2
        +	mov	ebp,ecx
        +	rol	ebp,5
        +	mov	DWORD PTR [esp],ebx
        +	lea	ebx,DWORD PTR 3395469782[eax*1+ebx]
        +	mov	eax,DWORD PTR 4[esp]
        +	add	ebx,ebp
        +	; 20_39 65
        +	mov	ebp,ecx
        +	xor	eax,DWORD PTR 12[esp]
        +	xor	ebp,edx
        +	xor	eax,DWORD PTR 36[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 56[esp]
        +	rol	eax,1
        +	add	esi,ebp
        +	ror	ecx,2
        +	mov	ebp,ebx
        +	rol	ebp,5
        +	mov	DWORD PTR 4[esp],eax
        +	lea	eax,DWORD PTR 3395469782[esi*1+eax]
        +	mov	esi,DWORD PTR 8[esp]
        +	add	eax,ebp
        +	; 20_39 66
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR 16[esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR 40[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 60[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	mov	DWORD PTR 8[esp],esi
        +	lea	esi,DWORD PTR 3395469782[edi*1+esi]
        +	mov	edi,DWORD PTR 12[esp]
        +	add	esi,ebp
        +	; 20_39 67
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 20[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 44[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR [esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	mov	DWORD PTR 12[esp],edi
        +	lea	edi,DWORD PTR 3395469782[edx*1+edi]
        +	mov	edx,DWORD PTR 16[esp]
        +	add	edi,ebp
        +	; 20_39 68
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR 24[esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 48[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 4[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR 16[esp],edx
        +	lea	edx,DWORD PTR 3395469782[ecx*1+edx]
        +	mov	ecx,DWORD PTR 20[esp]
        +	add	edx,ebp
        +	; 20_39 69
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 28[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 52[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 8[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 20[esp],ecx
        +	lea	ecx,DWORD PTR 3395469782[ebx*1+ecx]
        +	mov	ebx,DWORD PTR 24[esp]
        +	add	ecx,ebp
        +	; 20_39 70
        +	mov	ebp,edx
        +	xor	ebx,DWORD PTR 32[esp]
        +	xor	ebp,edi
        +	xor	ebx,DWORD PTR 56[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 12[esp]
        +	rol	ebx,1
        +	add	eax,ebp
        +	ror	edx,2
        +	mov	ebp,ecx
        +	rol	ebp,5
        +	mov	DWORD PTR 24[esp],ebx
        +	lea	ebx,DWORD PTR 3395469782[eax*1+ebx]
        +	mov	eax,DWORD PTR 28[esp]
        +	add	ebx,ebp
        +	; 20_39 71
        +	mov	ebp,ecx
        +	xor	eax,DWORD PTR 36[esp]
        +	xor	ebp,edx
        +	xor	eax,DWORD PTR 60[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 16[esp]
        +	rol	eax,1
        +	add	esi,ebp
        +	ror	ecx,2
        +	mov	ebp,ebx
        +	rol	ebp,5
        +	mov	DWORD PTR 28[esp],eax
        +	lea	eax,DWORD PTR 3395469782[esi*1+eax]
        +	mov	esi,DWORD PTR 32[esp]
        +	add	eax,ebp
        +	; 20_39 72
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR 40[esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR [esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 20[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	mov	DWORD PTR 32[esp],esi
        +	lea	esi,DWORD PTR 3395469782[edi*1+esi]
        +	mov	edi,DWORD PTR 36[esp]
        +	add	esi,ebp
        +	; 20_39 73
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 44[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 4[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 24[esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	mov	DWORD PTR 36[esp],edi
        +	lea	edi,DWORD PTR 3395469782[edx*1+edi]
        +	mov	edx,DWORD PTR 40[esp]
        +	add	edi,ebp
        +	; 20_39 74
        +	mov	ebp,esi
        +	xor	edx,DWORD PTR 48[esp]
        +	xor	ebp,eax
        +	xor	edx,DWORD PTR 8[esp]
        +	xor	ebp,ebx
        +	xor	edx,DWORD PTR 28[esp]
        +	rol	edx,1
        +	add	ecx,ebp
        +	ror	esi,2
        +	mov	ebp,edi
        +	rol	ebp,5
        +	mov	DWORD PTR 40[esp],edx
        +	lea	edx,DWORD PTR 3395469782[ecx*1+edx]
        +	mov	ecx,DWORD PTR 44[esp]
        +	add	edx,ebp
        +	; 20_39 75
        +	mov	ebp,edi
        +	xor	ecx,DWORD PTR 52[esp]
        +	xor	ebp,esi
        +	xor	ecx,DWORD PTR 12[esp]
        +	xor	ebp,eax
        +	xor	ecx,DWORD PTR 32[esp]
        +	rol	ecx,1
        +	add	ebx,ebp
        +	ror	edi,2
        +	mov	ebp,edx
        +	rol	ebp,5
        +	mov	DWORD PTR 44[esp],ecx
        +	lea	ecx,DWORD PTR 3395469782[ebx*1+ecx]
        +	mov	ebx,DWORD PTR 48[esp]
        +	add	ecx,ebp
        +	; 20_39 76
        +	mov	ebp,edx
        +	xor	ebx,DWORD PTR 56[esp]
        +	xor	ebp,edi
        +	xor	ebx,DWORD PTR 16[esp]
        +	xor	ebp,esi
        +	xor	ebx,DWORD PTR 36[esp]
        +	rol	ebx,1
        +	add	eax,ebp
        +	ror	edx,2
        +	mov	ebp,ecx
        +	rol	ebp,5
        +	mov	DWORD PTR 48[esp],ebx
        +	lea	ebx,DWORD PTR 3395469782[eax*1+ebx]
        +	mov	eax,DWORD PTR 52[esp]
        +	add	ebx,ebp
        +	; 20_39 77
        +	mov	ebp,ecx
        +	xor	eax,DWORD PTR 60[esp]
        +	xor	ebp,edx
        +	xor	eax,DWORD PTR 20[esp]
        +	xor	ebp,edi
        +	xor	eax,DWORD PTR 40[esp]
        +	rol	eax,1
        +	add	esi,ebp
        +	ror	ecx,2
        +	mov	ebp,ebx
        +	rol	ebp,5
        +	lea	eax,DWORD PTR 3395469782[esi*1+eax]
        +	mov	esi,DWORD PTR 56[esp]
        +	add	eax,ebp
        +	; 20_39 78
        +	mov	ebp,ebx
        +	xor	esi,DWORD PTR [esp]
        +	xor	ebp,ecx
        +	xor	esi,DWORD PTR 24[esp]
        +	xor	ebp,edx
        +	xor	esi,DWORD PTR 44[esp]
        +	rol	esi,1
        +	add	edi,ebp
        +	ror	ebx,2
        +	mov	ebp,eax
        +	rol	ebp,5
        +	lea	esi,DWORD PTR 3395469782[edi*1+esi]
        +	mov	edi,DWORD PTR 60[esp]
        +	add	esi,ebp
        +	; 20_39 79
        +	mov	ebp,eax
        +	xor	edi,DWORD PTR 4[esp]
        +	xor	ebp,ebx
        +	xor	edi,DWORD PTR 28[esp]
        +	xor	ebp,ecx
        +	xor	edi,DWORD PTR 48[esp]
        +	rol	edi,1
        +	add	edx,ebp
        +	ror	eax,2
        +	mov	ebp,esi
        +	rol	ebp,5
        +	lea	edi,DWORD PTR 3395469782[edx*1+edi]
        +	add	edi,ebp
        +	mov	ebp,DWORD PTR 96[esp]
        +	mov	edx,DWORD PTR 100[esp]
        +	add	edi,DWORD PTR [ebp]
        +	add	esi,DWORD PTR 4[ebp]
        +	add	eax,DWORD PTR 8[ebp]
        +	add	ebx,DWORD PTR 12[ebp]
        +	add	ecx,DWORD PTR 16[ebp]
        +	mov	DWORD PTR [ebp],edi
        +	add	edx,64
        +	mov	DWORD PTR 4[ebp],esi
        +	cmp	edx,DWORD PTR 104[esp]
        +	mov	DWORD PTR 8[ebp],eax
        +	mov	edi,ecx
        +	mov	DWORD PTR 12[ebp],ebx
        +	mov	esi,edx
        +	mov	DWORD PTR 16[ebp],ecx
        +	jb	$L000loop
        +	add	esp,76
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_sha1_block_data_order ENDP
        +DB	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115
        +DB	102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82
        +DB	89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112
        +DB	114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/sha/sha256-586.asm b/vendor/openssl/asm/x86-win32-masm/sha/sha256-586.asm
        new file mode 100644
        index 000000000..577c38ffa
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/sha/sha256-586.asm
        @@ -0,0 +1,268 @@
        +TITLE	sha512-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_sha256_block_data_order	PROC PUBLIC
        +$L_sha256_block_data_order_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	ebx,esp
        +	call	$L000pic_point
        +$L000pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($L001K256-$L000pic_point)[ebp]
        +	sub	esp,16
        +	and	esp,-64
        +	shl	eax,6
        +	add	eax,edi
        +	mov	DWORD PTR [esp],esi
        +	mov	DWORD PTR 4[esp],edi
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +ALIGN	16
        +$L002loop:
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 16[edi]
        +	mov	ebx,DWORD PTR 20[edi]
        +	mov	ecx,DWORD PTR 24[edi]
        +	mov	edx,DWORD PTR 28[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 32[edi]
        +	mov	ebx,DWORD PTR 36[edi]
        +	mov	ecx,DWORD PTR 40[edi]
        +	mov	edx,DWORD PTR 44[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 48[edi]
        +	mov	ebx,DWORD PTR 52[edi]
        +	mov	ecx,DWORD PTR 56[edi]
        +	mov	edx,DWORD PTR 60[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	add	edi,64
        +	sub	esp,32
        +	mov	DWORD PTR 100[esp],edi
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edi,DWORD PTR 12[esi]
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	DWORD PTR 8[esp],ecx
        +	mov	DWORD PTR 12[esp],edi
        +	mov	edx,DWORD PTR 16[esi]
        +	mov	ebx,DWORD PTR 20[esi]
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edi,DWORD PTR 28[esi]
        +	mov	DWORD PTR 20[esp],ebx
        +	mov	DWORD PTR 24[esp],ecx
        +	mov	DWORD PTR 28[esp],edi
        +ALIGN	16
        +$L00300_15:
        +	mov	ebx,DWORD PTR 92[esp]
        +	mov	ecx,edx
        +	ror	ecx,14
        +	mov	esi,DWORD PTR 20[esp]
        +	xor	ecx,edx
        +	ror	ecx,5
        +	xor	ecx,edx
        +	ror	ecx,6
        +	mov	edi,DWORD PTR 24[esp]
        +	add	ebx,ecx
        +	xor	esi,edi
        +	mov	DWORD PTR 16[esp],edx
        +	mov	ecx,eax
        +	and	esi,edx
        +	mov	edx,DWORD PTR 12[esp]
        +	xor	esi,edi
        +	mov	edi,eax
        +	add	ebx,esi
        +	ror	ecx,9
        +	add	ebx,DWORD PTR 28[esp]
        +	xor	ecx,eax
        +	ror	ecx,11
        +	mov	esi,DWORD PTR 4[esp]
        +	xor	ecx,eax
        +	ror	ecx,2
        +	add	edx,ebx
        +	mov	edi,DWORD PTR 8[esp]
        +	add	ebx,ecx
        +	mov	DWORD PTR [esp],eax
        +	mov	ecx,eax
        +	sub	esp,4
        +	or	eax,esi
        +	and	ecx,esi
        +	and	eax,edi
        +	mov	esi,DWORD PTR [ebp]
        +	or	eax,ecx
        +	add	ebp,4
        +	add	eax,ebx
        +	add	edx,esi
        +	add	eax,esi
        +	cmp	esi,3248222580
        +	jne	$L00300_15
        +	mov	ebx,DWORD PTR 152[esp]
        +ALIGN	16
        +$L00416_63:
        +	mov	esi,ebx
        +	mov	ecx,DWORD PTR 100[esp]
        +	ror	esi,11
        +	mov	edi,ecx
        +	xor	esi,ebx
        +	ror	esi,7
        +	shr	ebx,3
        +	ror	edi,2
        +	xor	ebx,esi
        +	xor	edi,ecx
        +	ror	edi,17
        +	shr	ecx,10
        +	add	ebx,DWORD PTR 156[esp]
        +	xor	edi,ecx
        +	add	ebx,DWORD PTR 120[esp]
        +	mov	ecx,edx
        +	add	ebx,edi
        +	ror	ecx,14
        +	mov	esi,DWORD PTR 20[esp]
        +	xor	ecx,edx
        +	ror	ecx,5
        +	mov	DWORD PTR 92[esp],ebx
        +	xor	ecx,edx
        +	ror	ecx,6
        +	mov	edi,DWORD PTR 24[esp]
        +	add	ebx,ecx
        +	xor	esi,edi
        +	mov	DWORD PTR 16[esp],edx
        +	mov	ecx,eax
        +	and	esi,edx
        +	mov	edx,DWORD PTR 12[esp]
        +	xor	esi,edi
        +	mov	edi,eax
        +	add	ebx,esi
        +	ror	ecx,9
        +	add	ebx,DWORD PTR 28[esp]
        +	xor	ecx,eax
        +	ror	ecx,11
        +	mov	esi,DWORD PTR 4[esp]
        +	xor	ecx,eax
        +	ror	ecx,2
        +	add	edx,ebx
        +	mov	edi,DWORD PTR 8[esp]
        +	add	ebx,ecx
        +	mov	DWORD PTR [esp],eax
        +	mov	ecx,eax
        +	sub	esp,4
        +	or	eax,esi
        +	and	ecx,esi
        +	and	eax,edi
        +	mov	esi,DWORD PTR [ebp]
        +	or	eax,ecx
        +	add	ebp,4
        +	add	eax,ebx
        +	mov	ebx,DWORD PTR 152[esp]
        +	add	edx,esi
        +	add	eax,esi
        +	cmp	esi,3329325298
        +	jne	$L00416_63
        +	mov	esi,DWORD PTR 352[esp]
        +	mov	ebx,DWORD PTR 4[esp]
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edi,DWORD PTR 12[esp]
        +	add	eax,DWORD PTR [esi]
        +	add	ebx,DWORD PTR 4[esi]
        +	add	ecx,DWORD PTR 8[esi]
        +	add	edi,DWORD PTR 12[esi]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edi
        +	mov	eax,DWORD PTR 20[esp]
        +	mov	ebx,DWORD PTR 24[esp]
        +	mov	ecx,DWORD PTR 28[esp]
        +	mov	edi,DWORD PTR 356[esp]
        +	add	edx,DWORD PTR 16[esi]
        +	add	eax,DWORD PTR 20[esi]
        +	add	ebx,DWORD PTR 24[esi]
        +	add	ecx,DWORD PTR 28[esi]
        +	mov	DWORD PTR 16[esi],edx
        +	mov	DWORD PTR 20[esi],eax
        +	mov	DWORD PTR 24[esi],ebx
        +	mov	DWORD PTR 28[esi],ecx
        +	add	esp,352
        +	sub	ebp,256
        +	cmp	edi,DWORD PTR 8[esp]
        +	jb	$L002loop
        +	mov	esp,DWORD PTR 12[esp]
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L001K256:
        +DD	1116352408,1899447441,3049323471,3921009573
        +DD	961987163,1508970993,2453635748,2870763221
        +DD	3624381080,310598401,607225278,1426881987
        +DD	1925078388,2162078206,2614888103,3248222580
        +DD	3835390401,4022224774,264347078,604807628
        +DD	770255983,1249150122,1555081692,1996064986
        +DD	2554220882,2821834349,2952996808,3210313671
        +DD	3336571891,3584528711,113926993,338241895
        +DD	666307205,773529912,1294757372,1396182291
        +DD	1695183700,1986661051,2177026350,2456956037
        +DD	2730485921,2820302411,3259730800,3345764771
        +DD	3516065817,3600352804,4094571909,275423344
        +DD	430227734,506948616,659060556,883997877
        +DD	958139571,1322822218,1537002063,1747873779
        +DD	1955562222,2024104815,2227730452,2361852424
        +DD	2428436474,2756734187,3204031479,3329325298
        +_sha256_block_data_order ENDP
        +DB	83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97
        +DB	110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32
        +DB	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +DB	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +DB	62,0
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/sha/sha512-586.asm b/vendor/openssl/asm/x86-win32-masm/sha/sha512-586.asm
        new file mode 100644
        index 000000000..98c1c070d
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/sha/sha512-586.asm
        @@ -0,0 +1,573 @@
        +TITLE	sha512-586.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_sha512_block_data_order	PROC PUBLIC
        +$L_sha512_block_data_order_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	eax,DWORD PTR 28[esp]
        +	mov	ebx,esp
        +	call	$L000pic_point
        +$L000pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($L001K512-$L000pic_point)[ebp]
        +	sub	esp,16
        +	and	esp,-64
        +	shl	eax,7
        +	add	eax,edi
        +	mov	DWORD PTR [esp],esi
        +	mov	DWORD PTR 4[esp],edi
        +	mov	DWORD PTR 8[esp],eax
        +	mov	DWORD PTR 12[esp],ebx
        +ALIGN	16
        +$L002loop_x86:
        +	mov	eax,DWORD PTR [edi]
        +	mov	ebx,DWORD PTR 4[edi]
        +	mov	ecx,DWORD PTR 8[edi]
        +	mov	edx,DWORD PTR 12[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 16[edi]
        +	mov	ebx,DWORD PTR 20[edi]
        +	mov	ecx,DWORD PTR 24[edi]
        +	mov	edx,DWORD PTR 28[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 32[edi]
        +	mov	ebx,DWORD PTR 36[edi]
        +	mov	ecx,DWORD PTR 40[edi]
        +	mov	edx,DWORD PTR 44[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 48[edi]
        +	mov	ebx,DWORD PTR 52[edi]
        +	mov	ecx,DWORD PTR 56[edi]
        +	mov	edx,DWORD PTR 60[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 64[edi]
        +	mov	ebx,DWORD PTR 68[edi]
        +	mov	ecx,DWORD PTR 72[edi]
        +	mov	edx,DWORD PTR 76[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 80[edi]
        +	mov	ebx,DWORD PTR 84[edi]
        +	mov	ecx,DWORD PTR 88[edi]
        +	mov	edx,DWORD PTR 92[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 96[edi]
        +	mov	ebx,DWORD PTR 100[edi]
        +	mov	ecx,DWORD PTR 104[edi]
        +	mov	edx,DWORD PTR 108[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	mov	eax,DWORD PTR 112[edi]
        +	mov	ebx,DWORD PTR 116[edi]
        +	mov	ecx,DWORD PTR 120[edi]
        +	mov	edx,DWORD PTR 124[edi]
        +	bswap	eax
        +	bswap	ebx
        +	bswap	ecx
        +	bswap	edx
        +	push	eax
        +	push	ebx
        +	push	ecx
        +	push	edx
        +	add	edi,128
        +	sub	esp,72
        +	mov	DWORD PTR 204[esp],edi
        +	lea	edi,DWORD PTR 8[esp]
        +	mov	ecx,16
        +DD	2784229001
        +ALIGN	16
        +$L00300_15_x86:
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	edx,DWORD PTR 44[esp]
        +	mov	esi,ecx
        +	shr	ecx,9
        +	mov	edi,edx
        +	shr	edx,9
        +	mov	ebx,ecx
        +	shl	esi,14
        +	mov	eax,edx
        +	shl	edi,14
        +	xor	ebx,esi
        +	shr	ecx,5
        +	xor	eax,edi
        +	shr	edx,5
        +	xor	eax,ecx
        +	shl	esi,4
        +	xor	ebx,edx
        +	shl	edi,4
        +	xor	ebx,esi
        +	shr	ecx,4
        +	xor	eax,edi
        +	shr	edx,4
        +	xor	eax,ecx
        +	shl	esi,5
        +	xor	ebx,edx
        +	shl	edi,5
        +	xor	eax,esi
        +	xor	ebx,edi
        +	mov	ecx,DWORD PTR 48[esp]
        +	mov	edx,DWORD PTR 52[esp]
        +	mov	esi,DWORD PTR 56[esp]
        +	mov	edi,DWORD PTR 60[esp]
        +	add	eax,DWORD PTR 64[esp]
        +	adc	ebx,DWORD PTR 68[esp]
        +	xor	ecx,esi
        +	xor	edx,edi
        +	and	ecx,DWORD PTR 40[esp]
        +	and	edx,DWORD PTR 44[esp]
        +	add	eax,DWORD PTR 192[esp]
        +	adc	ebx,DWORD PTR 196[esp]
        +	xor	ecx,esi
        +	xor	edx,edi
        +	mov	esi,DWORD PTR [ebp]
        +	mov	edi,DWORD PTR 4[ebp]
        +	add	eax,ecx
        +	adc	ebx,edx
        +	mov	ecx,DWORD PTR 32[esp]
        +	mov	edx,DWORD PTR 36[esp]
        +	add	eax,esi
        +	adc	ebx,edi
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	add	eax,ecx
        +	adc	ebx,edx
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	DWORD PTR 32[esp],eax
        +	mov	DWORD PTR 36[esp],ebx
        +	mov	esi,ecx
        +	shr	ecx,2
        +	mov	edi,edx
        +	shr	edx,2
        +	mov	ebx,ecx
        +	shl	esi,4
        +	mov	eax,edx
        +	shl	edi,4
        +	xor	ebx,esi
        +	shr	ecx,5
        +	xor	eax,edi
        +	shr	edx,5
        +	xor	ebx,ecx
        +	shl	esi,21
        +	xor	eax,edx
        +	shl	edi,21
        +	xor	eax,esi
        +	shr	ecx,21
        +	xor	ebx,edi
        +	shr	edx,21
        +	xor	eax,ecx
        +	shl	esi,5
        +	xor	ebx,edx
        +	shl	edi,5
        +	xor	eax,esi
        +	xor	ebx,edi
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 16[esp]
        +	mov	edi,DWORD PTR 20[esp]
        +	add	eax,DWORD PTR [esp]
        +	adc	ebx,DWORD PTR 4[esp]
        +	or	ecx,esi
        +	or	edx,edi
        +	and	ecx,DWORD PTR 24[esp]
        +	and	edx,DWORD PTR 28[esp]
        +	and	esi,DWORD PTR 8[esp]
        +	and	edi,DWORD PTR 12[esp]
        +	or	ecx,esi
        +	or	edx,edi
        +	add	eax,ecx
        +	adc	ebx,edx
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	dl,BYTE PTR [ebp]
        +	sub	esp,8
        +	lea	ebp,DWORD PTR 8[ebp]
        +	cmp	dl,148
        +	jne	$L00300_15_x86
        +ALIGN	16
        +$L00416_79_x86:
        +	mov	ecx,DWORD PTR 312[esp]
        +	mov	edx,DWORD PTR 316[esp]
        +	mov	esi,ecx
        +	shr	ecx,1
        +	mov	edi,edx
        +	shr	edx,1
        +	mov	eax,ecx
        +	shl	esi,24
        +	mov	ebx,edx
        +	shl	edi,24
        +	xor	ebx,esi
        +	shr	ecx,6
        +	xor	eax,edi
        +	shr	edx,6
        +	xor	eax,ecx
        +	shl	esi,7
        +	xor	ebx,edx
        +	shl	edi,1
        +	xor	ebx,esi
        +	shr	ecx,1
        +	xor	eax,edi
        +	shr	edx,1
        +	xor	eax,ecx
        +	shl	edi,6
        +	xor	ebx,edx
        +	xor	eax,edi
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	ecx,DWORD PTR 208[esp]
        +	mov	edx,DWORD PTR 212[esp]
        +	mov	esi,ecx
        +	shr	ecx,6
        +	mov	edi,edx
        +	shr	edx,6
        +	mov	eax,ecx
        +	shl	esi,3
        +	mov	ebx,edx
        +	shl	edi,3
        +	xor	eax,esi
        +	shr	ecx,13
        +	xor	ebx,edi
        +	shr	edx,13
        +	xor	eax,ecx
        +	shl	esi,10
        +	xor	ebx,edx
        +	shl	edi,10
        +	xor	ebx,esi
        +	shr	ecx,10
        +	xor	eax,edi
        +	shr	edx,10
        +	xor	ebx,ecx
        +	shl	edi,13
        +	xor	eax,edx
        +	xor	eax,edi
        +	mov	ecx,DWORD PTR 320[esp]
        +	mov	edx,DWORD PTR 324[esp]
        +	add	eax,DWORD PTR [esp]
        +	adc	ebx,DWORD PTR 4[esp]
        +	mov	esi,DWORD PTR 248[esp]
        +	mov	edi,DWORD PTR 252[esp]
        +	add	eax,ecx
        +	adc	ebx,edx
        +	add	eax,esi
        +	adc	ebx,edi
        +	mov	DWORD PTR 192[esp],eax
        +	mov	DWORD PTR 196[esp],ebx
        +	mov	ecx,DWORD PTR 40[esp]
        +	mov	edx,DWORD PTR 44[esp]
        +	mov	esi,ecx
        +	shr	ecx,9
        +	mov	edi,edx
        +	shr	edx,9
        +	mov	ebx,ecx
        +	shl	esi,14
        +	mov	eax,edx
        +	shl	edi,14
        +	xor	ebx,esi
        +	shr	ecx,5
        +	xor	eax,edi
        +	shr	edx,5
        +	xor	eax,ecx
        +	shl	esi,4
        +	xor	ebx,edx
        +	shl	edi,4
        +	xor	ebx,esi
        +	shr	ecx,4
        +	xor	eax,edi
        +	shr	edx,4
        +	xor	eax,ecx
        +	shl	esi,5
        +	xor	ebx,edx
        +	shl	edi,5
        +	xor	eax,esi
        +	xor	ebx,edi
        +	mov	ecx,DWORD PTR 48[esp]
        +	mov	edx,DWORD PTR 52[esp]
        +	mov	esi,DWORD PTR 56[esp]
        +	mov	edi,DWORD PTR 60[esp]
        +	add	eax,DWORD PTR 64[esp]
        +	adc	ebx,DWORD PTR 68[esp]
        +	xor	ecx,esi
        +	xor	edx,edi
        +	and	ecx,DWORD PTR 40[esp]
        +	and	edx,DWORD PTR 44[esp]
        +	add	eax,DWORD PTR 192[esp]
        +	adc	ebx,DWORD PTR 196[esp]
        +	xor	ecx,esi
        +	xor	edx,edi
        +	mov	esi,DWORD PTR [ebp]
        +	mov	edi,DWORD PTR 4[ebp]
        +	add	eax,ecx
        +	adc	ebx,edx
        +	mov	ecx,DWORD PTR 32[esp]
        +	mov	edx,DWORD PTR 36[esp]
        +	add	eax,esi
        +	adc	ebx,edi
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	add	eax,ecx
        +	adc	ebx,edx
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	DWORD PTR 32[esp],eax
        +	mov	DWORD PTR 36[esp],ebx
        +	mov	esi,ecx
        +	shr	ecx,2
        +	mov	edi,edx
        +	shr	edx,2
        +	mov	ebx,ecx
        +	shl	esi,4
        +	mov	eax,edx
        +	shl	edi,4
        +	xor	ebx,esi
        +	shr	ecx,5
        +	xor	eax,edi
        +	shr	edx,5
        +	xor	ebx,ecx
        +	shl	esi,21
        +	xor	eax,edx
        +	shl	edi,21
        +	xor	eax,esi
        +	shr	ecx,21
        +	xor	ebx,edi
        +	shr	edx,21
        +	xor	eax,ecx
        +	shl	esi,5
        +	xor	ebx,edx
        +	shl	edi,5
        +	xor	eax,esi
        +	xor	ebx,edi
        +	mov	ecx,DWORD PTR 8[esp]
        +	mov	edx,DWORD PTR 12[esp]
        +	mov	esi,DWORD PTR 16[esp]
        +	mov	edi,DWORD PTR 20[esp]
        +	add	eax,DWORD PTR [esp]
        +	adc	ebx,DWORD PTR 4[esp]
        +	or	ecx,esi
        +	or	edx,edi
        +	and	ecx,DWORD PTR 24[esp]
        +	and	edx,DWORD PTR 28[esp]
        +	and	esi,DWORD PTR 8[esp]
        +	and	edi,DWORD PTR 12[esp]
        +	or	ecx,esi
        +	or	edx,edi
        +	add	eax,ecx
        +	adc	ebx,edx
        +	mov	DWORD PTR [esp],eax
        +	mov	DWORD PTR 4[esp],ebx
        +	mov	dl,BYTE PTR [ebp]
        +	sub	esp,8
        +	lea	ebp,DWORD PTR 8[ebp]
        +	cmp	dl,23
        +	jne	$L00416_79_x86
        +	mov	esi,DWORD PTR 840[esp]
        +	mov	edi,DWORD PTR 844[esp]
        +	mov	eax,DWORD PTR [esi]
        +	mov	ebx,DWORD PTR 4[esi]
        +	mov	ecx,DWORD PTR 8[esi]
        +	mov	edx,DWORD PTR 12[esi]
        +	add	eax,DWORD PTR 8[esp]
        +	adc	ebx,DWORD PTR 12[esp]
        +	mov	DWORD PTR [esi],eax
        +	mov	DWORD PTR 4[esi],ebx
        +	add	ecx,DWORD PTR 16[esp]
        +	adc	edx,DWORD PTR 20[esp]
        +	mov	DWORD PTR 8[esi],ecx
        +	mov	DWORD PTR 12[esi],edx
        +	mov	eax,DWORD PTR 16[esi]
        +	mov	ebx,DWORD PTR 20[esi]
        +	mov	ecx,DWORD PTR 24[esi]
        +	mov	edx,DWORD PTR 28[esi]
        +	add	eax,DWORD PTR 24[esp]
        +	adc	ebx,DWORD PTR 28[esp]
        +	mov	DWORD PTR 16[esi],eax
        +	mov	DWORD PTR 20[esi],ebx
        +	add	ecx,DWORD PTR 32[esp]
        +	adc	edx,DWORD PTR 36[esp]
        +	mov	DWORD PTR 24[esi],ecx
        +	mov	DWORD PTR 28[esi],edx
        +	mov	eax,DWORD PTR 32[esi]
        +	mov	ebx,DWORD PTR 36[esi]
        +	mov	ecx,DWORD PTR 40[esi]
        +	mov	edx,DWORD PTR 44[esi]
        +	add	eax,DWORD PTR 40[esp]
        +	adc	ebx,DWORD PTR 44[esp]
        +	mov	DWORD PTR 32[esi],eax
        +	mov	DWORD PTR 36[esi],ebx
        +	add	ecx,DWORD PTR 48[esp]
        +	adc	edx,DWORD PTR 52[esp]
        +	mov	DWORD PTR 40[esi],ecx
        +	mov	DWORD PTR 44[esi],edx
        +	mov	eax,DWORD PTR 48[esi]
        +	mov	ebx,DWORD PTR 52[esi]
        +	mov	ecx,DWORD PTR 56[esi]
        +	mov	edx,DWORD PTR 60[esi]
        +	add	eax,DWORD PTR 56[esp]
        +	adc	ebx,DWORD PTR 60[esp]
        +	mov	DWORD PTR 48[esi],eax
        +	mov	DWORD PTR 52[esi],ebx
        +	add	ecx,DWORD PTR 64[esp]
        +	adc	edx,DWORD PTR 68[esp]
        +	mov	DWORD PTR 56[esi],ecx
        +	mov	DWORD PTR 60[esi],edx
        +	add	esp,840
        +	sub	ebp,640
        +	cmp	edi,DWORD PTR 8[esp]
        +	jb	$L002loop_x86
        +	mov	esp,DWORD PTR 12[esp]
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L001K512:
        +DD	3609767458,1116352408
        +DD	602891725,1899447441
        +DD	3964484399,3049323471
        +DD	2173295548,3921009573
        +DD	4081628472,961987163
        +DD	3053834265,1508970993
        +DD	2937671579,2453635748
        +DD	3664609560,2870763221
        +DD	2734883394,3624381080
        +DD	1164996542,310598401
        +DD	1323610764,607225278
        +DD	3590304994,1426881987
        +DD	4068182383,1925078388
        +DD	991336113,2162078206
        +DD	633803317,2614888103
        +DD	3479774868,3248222580
        +DD	2666613458,3835390401
        +DD	944711139,4022224774
        +DD	2341262773,264347078
        +DD	2007800933,604807628
        +DD	1495990901,770255983
        +DD	1856431235,1249150122
        +DD	3175218132,1555081692
        +DD	2198950837,1996064986
        +DD	3999719339,2554220882
        +DD	766784016,2821834349
        +DD	2566594879,2952996808
        +DD	3203337956,3210313671
        +DD	1034457026,3336571891
        +DD	2466948901,3584528711
        +DD	3758326383,113926993
        +DD	168717936,338241895
        +DD	1188179964,666307205
        +DD	1546045734,773529912
        +DD	1522805485,1294757372
        +DD	2643833823,1396182291
        +DD	2343527390,1695183700
        +DD	1014477480,1986661051
        +DD	1206759142,2177026350
        +DD	344077627,2456956037
        +DD	1290863460,2730485921
        +DD	3158454273,2820302411
        +DD	3505952657,3259730800
        +DD	106217008,3345764771
        +DD	3606008344,3516065817
        +DD	1432725776,3600352804
        +DD	1467031594,4094571909
        +DD	851169720,275423344
        +DD	3100823752,430227734
        +DD	1363258195,506948616
        +DD	3750685593,659060556
        +DD	3785050280,883997877
        +DD	3318307427,958139571
        +DD	3812723403,1322822218
        +DD	2003034995,1537002063
        +DD	3602036899,1747873779
        +DD	1575990012,1955562222
        +DD	1125592928,2024104815
        +DD	2716904306,2227730452
        +DD	442776044,2361852424
        +DD	593698344,2428436474
        +DD	3733110249,2756734187
        +DD	2999351573,3204031479
        +DD	3815920427,3329325298
        +DD	3928383900,3391569614
        +DD	566280711,3515267271
        +DD	3454069534,3940187606
        +DD	4000239992,4118630271
        +DD	1914138554,116418474
        +DD	2731055270,174292421
        +DD	3203993006,289380356
        +DD	320620315,460393269
        +DD	587496836,685471733
        +DD	1086792851,852142971
        +DD	365543100,1017036298
        +DD	2618297676,1126000580
        +DD	3409855158,1288033470
        +DD	4234509866,1501505948
        +DD	987167468,1607167915
        +DD	1246189591,1816402316
        +_sha512_block_data_order ENDP
        +DB	83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97
        +DB	110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32
        +DB	67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
        +DB	112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
        +DB	62,0
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/whrlpool/wp-mmx.asm b/vendor/openssl/asm/x86-win32-masm/whrlpool/wp-mmx.asm
        new file mode 100644
        index 000000000..9fa36662c
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/whrlpool/wp-mmx.asm
        @@ -0,0 +1,1122 @@
        +TITLE	wp-mmx.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.XMM
        +IF @Version LT 800
        +XMMWORD STRUCT 16
        +DQ	2 dup (?)
        +XMMWORD	ENDS
        +ENDIF
        +
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_whirlpool_block_mmx	PROC PUBLIC
        +$L_whirlpool_block_mmx_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	mov	esi,DWORD PTR 20[esp]
        +	mov	edi,DWORD PTR 24[esp]
        +	mov	ebp,DWORD PTR 28[esp]
        +	mov	eax,esp
        +	sub	esp,148
        +	and	esp,-64
        +	lea	ebx,DWORD PTR 128[esp]
        +	mov	DWORD PTR [ebx],esi
        +	mov	DWORD PTR 4[ebx],edi
        +	mov	DWORD PTR 8[ebx],ebp
        +	mov	DWORD PTR 16[ebx],eax
        +	call	$L000pic_point
        +$L000pic_point:
        +	pop	ebp
        +	lea	ebp,DWORD PTR ($L001table-$L000pic_point)[ebp]
        +	xor	ecx,ecx
        +	xor	edx,edx
        +	movq	mm0,QWORD PTR [esi]
        +	movq	mm1,QWORD PTR 8[esi]
        +	movq	mm2,QWORD PTR 16[esi]
        +	movq	mm3,QWORD PTR 24[esi]
        +	movq	mm4,QWORD PTR 32[esi]
        +	movq	mm5,QWORD PTR 40[esi]
        +	movq	mm6,QWORD PTR 48[esi]
        +	movq	mm7,QWORD PTR 56[esi]
        +$L002outerloop:
        +	movq	QWORD PTR [esp],mm0
        +	movq	QWORD PTR 8[esp],mm1
        +	movq	QWORD PTR 16[esp],mm2
        +	movq	QWORD PTR 24[esp],mm3
        +	movq	QWORD PTR 32[esp],mm4
        +	movq	QWORD PTR 40[esp],mm5
        +	movq	QWORD PTR 48[esp],mm6
        +	movq	QWORD PTR 56[esp],mm7
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm1,QWORD PTR 8[edi]
        +	pxor	mm2,QWORD PTR 16[edi]
        +	pxor	mm3,QWORD PTR 24[edi]
        +	pxor	mm4,QWORD PTR 32[edi]
        +	pxor	mm5,QWORD PTR 40[edi]
        +	pxor	mm6,QWORD PTR 48[edi]
        +	pxor	mm7,QWORD PTR 56[edi]
        +	movq	QWORD PTR 64[esp],mm0
        +	movq	QWORD PTR 72[esp],mm1
        +	movq	QWORD PTR 80[esp],mm2
        +	movq	QWORD PTR 88[esp],mm3
        +	movq	QWORD PTR 96[esp],mm4
        +	movq	QWORD PTR 104[esp],mm5
        +	movq	QWORD PTR 112[esp],mm6
        +	movq	QWORD PTR 120[esp],mm7
        +	xor	esi,esi
        +	mov	DWORD PTR 12[ebx],esi
        +ALIGN	16
        +$L003round:
        +	movq	mm0,QWORD PTR 4096[esi*8+ebp]
        +	mov	eax,DWORD PTR [esp]
        +	mov	ebx,DWORD PTR 4[esp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm0,QWORD PTR [esi*8+ebp]
        +	movq	mm1,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 8[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	movq	mm2,QWORD PTR 6[esi*8+ebp]
        +	movq	mm3,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	movq	mm4,QWORD PTR 4[esi*8+ebp]
        +	movq	mm5,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 12[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	movq	mm6,QWORD PTR 2[esi*8+ebp]
        +	movq	mm7,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm1,QWORD PTR [esi*8+ebp]
        +	pxor	mm2,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 16[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm3,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm4,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm5,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm6,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 20[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm7,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm0,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm2,QWORD PTR [esi*8+ebp]
        +	pxor	mm3,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 24[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm4,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm5,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm6,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm7,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 28[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm0,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm1,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm3,QWORD PTR [esi*8+ebp]
        +	pxor	mm4,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 32[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm5,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm6,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm7,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm0,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 36[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm1,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm2,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm4,QWORD PTR [esi*8+ebp]
        +	pxor	mm5,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 40[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm6,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm7,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm0,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm1,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 44[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm2,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm3,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm5,QWORD PTR [esi*8+ebp]
        +	pxor	mm6,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 48[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm7,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm0,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm1,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm2,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 52[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm3,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm4,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm6,QWORD PTR [esi*8+ebp]
        +	pxor	mm7,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 56[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm0,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm1,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm2,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm3,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 60[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm4,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm5,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm7,QWORD PTR [esi*8+ebp]
        +	pxor	mm0,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 64[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm1,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm2,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm3,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm4,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 68[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm5,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm6,QWORD PTR 1[edi*8+ebp]
        +	movq	QWORD PTR [esp],mm0
        +	movq	QWORD PTR 8[esp],mm1
        +	movq	QWORD PTR 16[esp],mm2
        +	movq	QWORD PTR 24[esp],mm3
        +	movq	QWORD PTR 32[esp],mm4
        +	movq	QWORD PTR 40[esp],mm5
        +	movq	QWORD PTR 48[esp],mm6
        +	movq	QWORD PTR 56[esp],mm7
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm0,QWORD PTR [esi*8+ebp]
        +	pxor	mm1,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 72[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm2,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm3,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm4,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm5,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 76[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm6,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm7,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm1,QWORD PTR [esi*8+ebp]
        +	pxor	mm2,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 80[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm3,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm4,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm5,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm6,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 84[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm7,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm0,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm2,QWORD PTR [esi*8+ebp]
        +	pxor	mm3,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 88[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm4,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm5,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm6,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm7,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 92[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm0,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm1,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm3,QWORD PTR [esi*8+ebp]
        +	pxor	mm4,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 96[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm5,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm6,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm7,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm0,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 100[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm1,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm2,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm4,QWORD PTR [esi*8+ebp]
        +	pxor	mm5,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 104[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm6,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm7,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm0,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm1,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 108[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm2,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm3,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm5,QWORD PTR [esi*8+ebp]
        +	pxor	mm6,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 112[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm7,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm0,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm1,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm2,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 116[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm3,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm4,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm6,QWORD PTR [esi*8+ebp]
        +	pxor	mm7,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	mov	eax,DWORD PTR 120[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm0,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm1,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm2,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm3,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	mov	ebx,DWORD PTR 124[esp]
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm4,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm5,QWORD PTR 1[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	eax,16
        +	pxor	mm7,QWORD PTR [esi*8+ebp]
        +	pxor	mm0,QWORD PTR 7[edi*8+ebp]
        +	mov	cl,al
        +	mov	dl,ah
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm1,QWORD PTR 6[esi*8+ebp]
        +	pxor	mm2,QWORD PTR 5[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	shr	ebx,16
        +	pxor	mm3,QWORD PTR 4[esi*8+ebp]
        +	pxor	mm4,QWORD PTR 3[edi*8+ebp]
        +	mov	cl,bl
        +	mov	dl,bh
        +	lea	esi,DWORD PTR [ecx*1+ecx]
        +	lea	edi,DWORD PTR [edx*1+edx]
        +	pxor	mm5,QWORD PTR 2[esi*8+ebp]
        +	pxor	mm6,QWORD PTR 1[edi*8+ebp]
        +	lea	ebx,DWORD PTR 128[esp]
        +	mov	esi,DWORD PTR 12[ebx]
        +	add	esi,1
        +	cmp	esi,10
        +	je	$L004roundsdone
        +	mov	DWORD PTR 12[ebx],esi
        +	movq	QWORD PTR 64[esp],mm0
        +	movq	QWORD PTR 72[esp],mm1
        +	movq	QWORD PTR 80[esp],mm2
        +	movq	QWORD PTR 88[esp],mm3
        +	movq	QWORD PTR 96[esp],mm4
        +	movq	QWORD PTR 104[esp],mm5
        +	movq	QWORD PTR 112[esp],mm6
        +	movq	QWORD PTR 120[esp],mm7
        +	jmp	$L003round
        +ALIGN	16
        +$L004roundsdone:
        +	mov	esi,DWORD PTR [ebx]
        +	mov	edi,DWORD PTR 4[ebx]
        +	mov	eax,DWORD PTR 8[ebx]
        +	pxor	mm0,QWORD PTR [edi]
        +	pxor	mm1,QWORD PTR 8[edi]
        +	pxor	mm2,QWORD PTR 16[edi]
        +	pxor	mm3,QWORD PTR 24[edi]
        +	pxor	mm4,QWORD PTR 32[edi]
        +	pxor	mm5,QWORD PTR 40[edi]
        +	pxor	mm6,QWORD PTR 48[edi]
        +	pxor	mm7,QWORD PTR 56[edi]
        +	pxor	mm0,QWORD PTR [esi]
        +	pxor	mm1,QWORD PTR 8[esi]
        +	pxor	mm2,QWORD PTR 16[esi]
        +	pxor	mm3,QWORD PTR 24[esi]
        +	pxor	mm4,QWORD PTR 32[esi]
        +	pxor	mm5,QWORD PTR 40[esi]
        +	pxor	mm6,QWORD PTR 48[esi]
        +	pxor	mm7,QWORD PTR 56[esi]
        +	movq	QWORD PTR [esi],mm0
        +	movq	QWORD PTR 8[esi],mm1
        +	movq	QWORD PTR 16[esi],mm2
        +	movq	QWORD PTR 24[esi],mm3
        +	movq	QWORD PTR 32[esi],mm4
        +	movq	QWORD PTR 40[esi],mm5
        +	movq	QWORD PTR 48[esi],mm6
        +	movq	QWORD PTR 56[esi],mm7
        +	lea	edi,DWORD PTR 64[edi]
        +	sub	eax,1
        +	jz	$L005alldone
        +	mov	DWORD PTR 4[ebx],edi
        +	mov	DWORD PTR 8[ebx],eax
        +	jmp	$L002outerloop
        +$L005alldone:
        +	emms
        +	mov	esp,DWORD PTR 16[ebx]
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +ALIGN	64
        +$L001table:
        +DB	24,24,96,24,192,120,48,216
        +DB	24,24,96,24,192,120,48,216
        +DB	35,35,140,35,5,175,70,38
        +DB	35,35,140,35,5,175,70,38
        +DB	198,198,63,198,126,249,145,184
        +DB	198,198,63,198,126,249,145,184
        +DB	232,232,135,232,19,111,205,251
        +DB	232,232,135,232,19,111,205,251
        +DB	135,135,38,135,76,161,19,203
        +DB	135,135,38,135,76,161,19,203
        +DB	184,184,218,184,169,98,109,17
        +DB	184,184,218,184,169,98,109,17
        +DB	1,1,4,1,8,5,2,9
        +DB	1,1,4,1,8,5,2,9
        +DB	79,79,33,79,66,110,158,13
        +DB	79,79,33,79,66,110,158,13
        +DB	54,54,216,54,173,238,108,155
        +DB	54,54,216,54,173,238,108,155
        +DB	166,166,162,166,89,4,81,255
        +DB	166,166,162,166,89,4,81,255
        +DB	210,210,111,210,222,189,185,12
        +DB	210,210,111,210,222,189,185,12
        +DB	245,245,243,245,251,6,247,14
        +DB	245,245,243,245,251,6,247,14
        +DB	121,121,249,121,239,128,242,150
        +DB	121,121,249,121,239,128,242,150
        +DB	111,111,161,111,95,206,222,48
        +DB	111,111,161,111,95,206,222,48
        +DB	145,145,126,145,252,239,63,109
        +DB	145,145,126,145,252,239,63,109
        +DB	82,82,85,82,170,7,164,248
        +DB	82,82,85,82,170,7,164,248
        +DB	96,96,157,96,39,253,192,71
        +DB	96,96,157,96,39,253,192,71
        +DB	188,188,202,188,137,118,101,53
        +DB	188,188,202,188,137,118,101,53
        +DB	155,155,86,155,172,205,43,55
        +DB	155,155,86,155,172,205,43,55
        +DB	142,142,2,142,4,140,1,138
        +DB	142,142,2,142,4,140,1,138
        +DB	163,163,182,163,113,21,91,210
        +DB	163,163,182,163,113,21,91,210
        +DB	12,12,48,12,96,60,24,108
        +DB	12,12,48,12,96,60,24,108
        +DB	123,123,241,123,255,138,246,132
        +DB	123,123,241,123,255,138,246,132
        +DB	53,53,212,53,181,225,106,128
        +DB	53,53,212,53,181,225,106,128
        +DB	29,29,116,29,232,105,58,245
        +DB	29,29,116,29,232,105,58,245
        +DB	224,224,167,224,83,71,221,179
        +DB	224,224,167,224,83,71,221,179
        +DB	215,215,123,215,246,172,179,33
        +DB	215,215,123,215,246,172,179,33
        +DB	194,194,47,194,94,237,153,156
        +DB	194,194,47,194,94,237,153,156
        +DB	46,46,184,46,109,150,92,67
        +DB	46,46,184,46,109,150,92,67
        +DB	75,75,49,75,98,122,150,41
        +DB	75,75,49,75,98,122,150,41
        +DB	254,254,223,254,163,33,225,93
        +DB	254,254,223,254,163,33,225,93
        +DB	87,87,65,87,130,22,174,213
        +DB	87,87,65,87,130,22,174,213
        +DB	21,21,84,21,168,65,42,189
        +DB	21,21,84,21,168,65,42,189
        +DB	119,119,193,119,159,182,238,232
        +DB	119,119,193,119,159,182,238,232
        +DB	55,55,220,55,165,235,110,146
        +DB	55,55,220,55,165,235,110,146
        +DB	229,229,179,229,123,86,215,158
        +DB	229,229,179,229,123,86,215,158
        +DB	159,159,70,159,140,217,35,19
        +DB	159,159,70,159,140,217,35,19
        +DB	240,240,231,240,211,23,253,35
        +DB	240,240,231,240,211,23,253,35
        +DB	74,74,53,74,106,127,148,32
        +DB	74,74,53,74,106,127,148,32
        +DB	218,218,79,218,158,149,169,68
        +DB	218,218,79,218,158,149,169,68
        +DB	88,88,125,88,250,37,176,162
        +DB	88,88,125,88,250,37,176,162
        +DB	201,201,3,201,6,202,143,207
        +DB	201,201,3,201,6,202,143,207
        +DB	41,41,164,41,85,141,82,124
        +DB	41,41,164,41,85,141,82,124
        +DB	10,10,40,10,80,34,20,90
        +DB	10,10,40,10,80,34,20,90
        +DB	177,177,254,177,225,79,127,80
        +DB	177,177,254,177,225,79,127,80
        +DB	160,160,186,160,105,26,93,201
        +DB	160,160,186,160,105,26,93,201
        +DB	107,107,177,107,127,218,214,20
        +DB	107,107,177,107,127,218,214,20
        +DB	133,133,46,133,92,171,23,217
        +DB	133,133,46,133,92,171,23,217
        +DB	189,189,206,189,129,115,103,60
        +DB	189,189,206,189,129,115,103,60
        +DB	93,93,105,93,210,52,186,143
        +DB	93,93,105,93,210,52,186,143
        +DB	16,16,64,16,128,80,32,144
        +DB	16,16,64,16,128,80,32,144
        +DB	244,244,247,244,243,3,245,7
        +DB	244,244,247,244,243,3,245,7
        +DB	203,203,11,203,22,192,139,221
        +DB	203,203,11,203,22,192,139,221
        +DB	62,62,248,62,237,198,124,211
        +DB	62,62,248,62,237,198,124,211
        +DB	5,5,20,5,40,17,10,45
        +DB	5,5,20,5,40,17,10,45
        +DB	103,103,129,103,31,230,206,120
        +DB	103,103,129,103,31,230,206,120
        +DB	228,228,183,228,115,83,213,151
        +DB	228,228,183,228,115,83,213,151
        +DB	39,39,156,39,37,187,78,2
        +DB	39,39,156,39,37,187,78,2
        +DB	65,65,25,65,50,88,130,115
        +DB	65,65,25,65,50,88,130,115
        +DB	139,139,22,139,44,157,11,167
        +DB	139,139,22,139,44,157,11,167
        +DB	167,167,166,167,81,1,83,246
        +DB	167,167,166,167,81,1,83,246
        +DB	125,125,233,125,207,148,250,178
        +DB	125,125,233,125,207,148,250,178
        +DB	149,149,110,149,220,251,55,73
        +DB	149,149,110,149,220,251,55,73
        +DB	216,216,71,216,142,159,173,86
        +DB	216,216,71,216,142,159,173,86
        +DB	251,251,203,251,139,48,235,112
        +DB	251,251,203,251,139,48,235,112
        +DB	238,238,159,238,35,113,193,205
        +DB	238,238,159,238,35,113,193,205
        +DB	124,124,237,124,199,145,248,187
        +DB	124,124,237,124,199,145,248,187
        +DB	102,102,133,102,23,227,204,113
        +DB	102,102,133,102,23,227,204,113
        +DB	221,221,83,221,166,142,167,123
        +DB	221,221,83,221,166,142,167,123
        +DB	23,23,92,23,184,75,46,175
        +DB	23,23,92,23,184,75,46,175
        +DB	71,71,1,71,2,70,142,69
        +DB	71,71,1,71,2,70,142,69
        +DB	158,158,66,158,132,220,33,26
        +DB	158,158,66,158,132,220,33,26
        +DB	202,202,15,202,30,197,137,212
        +DB	202,202,15,202,30,197,137,212
        +DB	45,45,180,45,117,153,90,88
        +DB	45,45,180,45,117,153,90,88
        +DB	191,191,198,191,145,121,99,46
        +DB	191,191,198,191,145,121,99,46
        +DB	7,7,28,7,56,27,14,63
        +DB	7,7,28,7,56,27,14,63
        +DB	173,173,142,173,1,35,71,172
        +DB	173,173,142,173,1,35,71,172
        +DB	90,90,117,90,234,47,180,176
        +DB	90,90,117,90,234,47,180,176
        +DB	131,131,54,131,108,181,27,239
        +DB	131,131,54,131,108,181,27,239
        +DB	51,51,204,51,133,255,102,182
        +DB	51,51,204,51,133,255,102,182
        +DB	99,99,145,99,63,242,198,92
        +DB	99,99,145,99,63,242,198,92
        +DB	2,2,8,2,16,10,4,18
        +DB	2,2,8,2,16,10,4,18
        +DB	170,170,146,170,57,56,73,147
        +DB	170,170,146,170,57,56,73,147
        +DB	113,113,217,113,175,168,226,222
        +DB	113,113,217,113,175,168,226,222
        +DB	200,200,7,200,14,207,141,198
        +DB	200,200,7,200,14,207,141,198
        +DB	25,25,100,25,200,125,50,209
        +DB	25,25,100,25,200,125,50,209
        +DB	73,73,57,73,114,112,146,59
        +DB	73,73,57,73,114,112,146,59
        +DB	217,217,67,217,134,154,175,95
        +DB	217,217,67,217,134,154,175,95
        +DB	242,242,239,242,195,29,249,49
        +DB	242,242,239,242,195,29,249,49
        +DB	227,227,171,227,75,72,219,168
        +DB	227,227,171,227,75,72,219,168
        +DB	91,91,113,91,226,42,182,185
        +DB	91,91,113,91,226,42,182,185
        +DB	136,136,26,136,52,146,13,188
        +DB	136,136,26,136,52,146,13,188
        +DB	154,154,82,154,164,200,41,62
        +DB	154,154,82,154,164,200,41,62
        +DB	38,38,152,38,45,190,76,11
        +DB	38,38,152,38,45,190,76,11
        +DB	50,50,200,50,141,250,100,191
        +DB	50,50,200,50,141,250,100,191
        +DB	176,176,250,176,233,74,125,89
        +DB	176,176,250,176,233,74,125,89
        +DB	233,233,131,233,27,106,207,242
        +DB	233,233,131,233,27,106,207,242
        +DB	15,15,60,15,120,51,30,119
        +DB	15,15,60,15,120,51,30,119
        +DB	213,213,115,213,230,166,183,51
        +DB	213,213,115,213,230,166,183,51
        +DB	128,128,58,128,116,186,29,244
        +DB	128,128,58,128,116,186,29,244
        +DB	190,190,194,190,153,124,97,39
        +DB	190,190,194,190,153,124,97,39
        +DB	205,205,19,205,38,222,135,235
        +DB	205,205,19,205,38,222,135,235
        +DB	52,52,208,52,189,228,104,137
        +DB	52,52,208,52,189,228,104,137
        +DB	72,72,61,72,122,117,144,50
        +DB	72,72,61,72,122,117,144,50
        +DB	255,255,219,255,171,36,227,84
        +DB	255,255,219,255,171,36,227,84
        +DB	122,122,245,122,247,143,244,141
        +DB	122,122,245,122,247,143,244,141
        +DB	144,144,122,144,244,234,61,100
        +DB	144,144,122,144,244,234,61,100
        +DB	95,95,97,95,194,62,190,157
        +DB	95,95,97,95,194,62,190,157
        +DB	32,32,128,32,29,160,64,61
        +DB	32,32,128,32,29,160,64,61
        +DB	104,104,189,104,103,213,208,15
        +DB	104,104,189,104,103,213,208,15
        +DB	26,26,104,26,208,114,52,202
        +DB	26,26,104,26,208,114,52,202
        +DB	174,174,130,174,25,44,65,183
        +DB	174,174,130,174,25,44,65,183
        +DB	180,180,234,180,201,94,117,125
        +DB	180,180,234,180,201,94,117,125
        +DB	84,84,77,84,154,25,168,206
        +DB	84,84,77,84,154,25,168,206
        +DB	147,147,118,147,236,229,59,127
        +DB	147,147,118,147,236,229,59,127
        +DB	34,34,136,34,13,170,68,47
        +DB	34,34,136,34,13,170,68,47
        +DB	100,100,141,100,7,233,200,99
        +DB	100,100,141,100,7,233,200,99
        +DB	241,241,227,241,219,18,255,42
        +DB	241,241,227,241,219,18,255,42
        +DB	115,115,209,115,191,162,230,204
        +DB	115,115,209,115,191,162,230,204
        +DB	18,18,72,18,144,90,36,130
        +DB	18,18,72,18,144,90,36,130
        +DB	64,64,29,64,58,93,128,122
        +DB	64,64,29,64,58,93,128,122
        +DB	8,8,32,8,64,40,16,72
        +DB	8,8,32,8,64,40,16,72
        +DB	195,195,43,195,86,232,155,149
        +DB	195,195,43,195,86,232,155,149
        +DB	236,236,151,236,51,123,197,223
        +DB	236,236,151,236,51,123,197,223
        +DB	219,219,75,219,150,144,171,77
        +DB	219,219,75,219,150,144,171,77
        +DB	161,161,190,161,97,31,95,192
        +DB	161,161,190,161,97,31,95,192
        +DB	141,141,14,141,28,131,7,145
        +DB	141,141,14,141,28,131,7,145
        +DB	61,61,244,61,245,201,122,200
        +DB	61,61,244,61,245,201,122,200
        +DB	151,151,102,151,204,241,51,91
        +DB	151,151,102,151,204,241,51,91
        +DB	0,0,0,0,0,0,0,0
        +DB	0,0,0,0,0,0,0,0
        +DB	207,207,27,207,54,212,131,249
        +DB	207,207,27,207,54,212,131,249
        +DB	43,43,172,43,69,135,86,110
        +DB	43,43,172,43,69,135,86,110
        +DB	118,118,197,118,151,179,236,225
        +DB	118,118,197,118,151,179,236,225
        +DB	130,130,50,130,100,176,25,230
        +DB	130,130,50,130,100,176,25,230
        +DB	214,214,127,214,254,169,177,40
        +DB	214,214,127,214,254,169,177,40
        +DB	27,27,108,27,216,119,54,195
        +DB	27,27,108,27,216,119,54,195
        +DB	181,181,238,181,193,91,119,116
        +DB	181,181,238,181,193,91,119,116
        +DB	175,175,134,175,17,41,67,190
        +DB	175,175,134,175,17,41,67,190
        +DB	106,106,181,106,119,223,212,29
        +DB	106,106,181,106,119,223,212,29
        +DB	80,80,93,80,186,13,160,234
        +DB	80,80,93,80,186,13,160,234
        +DB	69,69,9,69,18,76,138,87
        +DB	69,69,9,69,18,76,138,87
        +DB	243,243,235,243,203,24,251,56
        +DB	243,243,235,243,203,24,251,56
        +DB	48,48,192,48,157,240,96,173
        +DB	48,48,192,48,157,240,96,173
        +DB	239,239,155,239,43,116,195,196
        +DB	239,239,155,239,43,116,195,196
        +DB	63,63,252,63,229,195,126,218
        +DB	63,63,252,63,229,195,126,218
        +DB	85,85,73,85,146,28,170,199
        +DB	85,85,73,85,146,28,170,199
        +DB	162,162,178,162,121,16,89,219
        +DB	162,162,178,162,121,16,89,219
        +DB	234,234,143,234,3,101,201,233
        +DB	234,234,143,234,3,101,201,233
        +DB	101,101,137,101,15,236,202,106
        +DB	101,101,137,101,15,236,202,106
        +DB	186,186,210,186,185,104,105,3
        +DB	186,186,210,186,185,104,105,3
        +DB	47,47,188,47,101,147,94,74
        +DB	47,47,188,47,101,147,94,74
        +DB	192,192,39,192,78,231,157,142
        +DB	192,192,39,192,78,231,157,142
        +DB	222,222,95,222,190,129,161,96
        +DB	222,222,95,222,190,129,161,96
        +DB	28,28,112,28,224,108,56,252
        +DB	28,28,112,28,224,108,56,252
        +DB	253,253,211,253,187,46,231,70
        +DB	253,253,211,253,187,46,231,70
        +DB	77,77,41,77,82,100,154,31
        +DB	77,77,41,77,82,100,154,31
        +DB	146,146,114,146,228,224,57,118
        +DB	146,146,114,146,228,224,57,118
        +DB	117,117,201,117,143,188,234,250
        +DB	117,117,201,117,143,188,234,250
        +DB	6,6,24,6,48,30,12,54
        +DB	6,6,24,6,48,30,12,54
        +DB	138,138,18,138,36,152,9,174
        +DB	138,138,18,138,36,152,9,174
        +DB	178,178,242,178,249,64,121,75
        +DB	178,178,242,178,249,64,121,75
        +DB	230,230,191,230,99,89,209,133
        +DB	230,230,191,230,99,89,209,133
        +DB	14,14,56,14,112,54,28,126
        +DB	14,14,56,14,112,54,28,126
        +DB	31,31,124,31,248,99,62,231
        +DB	31,31,124,31,248,99,62,231
        +DB	98,98,149,98,55,247,196,85
        +DB	98,98,149,98,55,247,196,85
        +DB	212,212,119,212,238,163,181,58
        +DB	212,212,119,212,238,163,181,58
        +DB	168,168,154,168,41,50,77,129
        +DB	168,168,154,168,41,50,77,129
        +DB	150,150,98,150,196,244,49,82
        +DB	150,150,98,150,196,244,49,82
        +DB	249,249,195,249,155,58,239,98
        +DB	249,249,195,249,155,58,239,98
        +DB	197,197,51,197,102,246,151,163
        +DB	197,197,51,197,102,246,151,163
        +DB	37,37,148,37,53,177,74,16
        +DB	37,37,148,37,53,177,74,16
        +DB	89,89,121,89,242,32,178,171
        +DB	89,89,121,89,242,32,178,171
        +DB	132,132,42,132,84,174,21,208
        +DB	132,132,42,132,84,174,21,208
        +DB	114,114,213,114,183,167,228,197
        +DB	114,114,213,114,183,167,228,197
        +DB	57,57,228,57,213,221,114,236
        +DB	57,57,228,57,213,221,114,236
        +DB	76,76,45,76,90,97,152,22
        +DB	76,76,45,76,90,97,152,22
        +DB	94,94,101,94,202,59,188,148
        +DB	94,94,101,94,202,59,188,148
        +DB	120,120,253,120,231,133,240,159
        +DB	120,120,253,120,231,133,240,159
        +DB	56,56,224,56,221,216,112,229
        +DB	56,56,224,56,221,216,112,229
        +DB	140,140,10,140,20,134,5,152
        +DB	140,140,10,140,20,134,5,152
        +DB	209,209,99,209,198,178,191,23
        +DB	209,209,99,209,198,178,191,23
        +DB	165,165,174,165,65,11,87,228
        +DB	165,165,174,165,65,11,87,228
        +DB	226,226,175,226,67,77,217,161
        +DB	226,226,175,226,67,77,217,161
        +DB	97,97,153,97,47,248,194,78
        +DB	97,97,153,97,47,248,194,78
        +DB	179,179,246,179,241,69,123,66
        +DB	179,179,246,179,241,69,123,66
        +DB	33,33,132,33,21,165,66,52
        +DB	33,33,132,33,21,165,66,52
        +DB	156,156,74,156,148,214,37,8
        +DB	156,156,74,156,148,214,37,8
        +DB	30,30,120,30,240,102,60,238
        +DB	30,30,120,30,240,102,60,238
        +DB	67,67,17,67,34,82,134,97
        +DB	67,67,17,67,34,82,134,97
        +DB	199,199,59,199,118,252,147,177
        +DB	199,199,59,199,118,252,147,177
        +DB	252,252,215,252,179,43,229,79
        +DB	252,252,215,252,179,43,229,79
        +DB	4,4,16,4,32,20,8,36
        +DB	4,4,16,4,32,20,8,36
        +DB	81,81,89,81,178,8,162,227
        +DB	81,81,89,81,178,8,162,227
        +DB	153,153,94,153,188,199,47,37
        +DB	153,153,94,153,188,199,47,37
        +DB	109,109,169,109,79,196,218,34
        +DB	109,109,169,109,79,196,218,34
        +DB	13,13,52,13,104,57,26,101
        +DB	13,13,52,13,104,57,26,101
        +DB	250,250,207,250,131,53,233,121
        +DB	250,250,207,250,131,53,233,121
        +DB	223,223,91,223,182,132,163,105
        +DB	223,223,91,223,182,132,163,105
        +DB	126,126,229,126,215,155,252,169
        +DB	126,126,229,126,215,155,252,169
        +DB	36,36,144,36,61,180,72,25
        +DB	36,36,144,36,61,180,72,25
        +DB	59,59,236,59,197,215,118,254
        +DB	59,59,236,59,197,215,118,254
        +DB	171,171,150,171,49,61,75,154
        +DB	171,171,150,171,49,61,75,154
        +DB	206,206,31,206,62,209,129,240
        +DB	206,206,31,206,62,209,129,240
        +DB	17,17,68,17,136,85,34,153
        +DB	17,17,68,17,136,85,34,153
        +DB	143,143,6,143,12,137,3,131
        +DB	143,143,6,143,12,137,3,131
        +DB	78,78,37,78,74,107,156,4
        +DB	78,78,37,78,74,107,156,4
        +DB	183,183,230,183,209,81,115,102
        +DB	183,183,230,183,209,81,115,102
        +DB	235,235,139,235,11,96,203,224
        +DB	235,235,139,235,11,96,203,224
        +DB	60,60,240,60,253,204,120,193
        +DB	60,60,240,60,253,204,120,193
        +DB	129,129,62,129,124,191,31,253
        +DB	129,129,62,129,124,191,31,253
        +DB	148,148,106,148,212,254,53,64
        +DB	148,148,106,148,212,254,53,64
        +DB	247,247,251,247,235,12,243,28
        +DB	247,247,251,247,235,12,243,28
        +DB	185,185,222,185,161,103,111,24
        +DB	185,185,222,185,161,103,111,24
        +DB	19,19,76,19,152,95,38,139
        +DB	19,19,76,19,152,95,38,139
        +DB	44,44,176,44,125,156,88,81
        +DB	44,44,176,44,125,156,88,81
        +DB	211,211,107,211,214,184,187,5
        +DB	211,211,107,211,214,184,187,5
        +DB	231,231,187,231,107,92,211,140
        +DB	231,231,187,231,107,92,211,140
        +DB	110,110,165,110,87,203,220,57
        +DB	110,110,165,110,87,203,220,57
        +DB	196,196,55,196,110,243,149,170
        +DB	196,196,55,196,110,243,149,170
        +DB	3,3,12,3,24,15,6,27
        +DB	3,3,12,3,24,15,6,27
        +DB	86,86,69,86,138,19,172,220
        +DB	86,86,69,86,138,19,172,220
        +DB	68,68,13,68,26,73,136,94
        +DB	68,68,13,68,26,73,136,94
        +DB	127,127,225,127,223,158,254,160
        +DB	127,127,225,127,223,158,254,160
        +DB	169,169,158,169,33,55,79,136
        +DB	169,169,158,169,33,55,79,136
        +DB	42,42,168,42,77,130,84,103
        +DB	42,42,168,42,77,130,84,103
        +DB	187,187,214,187,177,109,107,10
        +DB	187,187,214,187,177,109,107,10
        +DB	193,193,35,193,70,226,159,135
        +DB	193,193,35,193,70,226,159,135
        +DB	83,83,81,83,162,2,166,241
        +DB	83,83,81,83,162,2,166,241
        +DB	220,220,87,220,174,139,165,114
        +DB	220,220,87,220,174,139,165,114
        +DB	11,11,44,11,88,39,22,83
        +DB	11,11,44,11,88,39,22,83
        +DB	157,157,78,157,156,211,39,1
        +DB	157,157,78,157,156,211,39,1
        +DB	108,108,173,108,71,193,216,43
        +DB	108,108,173,108,71,193,216,43
        +DB	49,49,196,49,149,245,98,164
        +DB	49,49,196,49,149,245,98,164
        +DB	116,116,205,116,135,185,232,243
        +DB	116,116,205,116,135,185,232,243
        +DB	246,246,255,246,227,9,241,21
        +DB	246,246,255,246,227,9,241,21
        +DB	70,70,5,70,10,67,140,76
        +DB	70,70,5,70,10,67,140,76
        +DB	172,172,138,172,9,38,69,165
        +DB	172,172,138,172,9,38,69,165
        +DB	137,137,30,137,60,151,15,181
        +DB	137,137,30,137,60,151,15,181
        +DB	20,20,80,20,160,68,40,180
        +DB	20,20,80,20,160,68,40,180
        +DB	225,225,163,225,91,66,223,186
        +DB	225,225,163,225,91,66,223,186
        +DB	22,22,88,22,176,78,44,166
        +DB	22,22,88,22,176,78,44,166
        +DB	58,58,232,58,205,210,116,247
        +DB	58,58,232,58,205,210,116,247
        +DB	105,105,185,105,111,208,210,6
        +DB	105,105,185,105,111,208,210,6
        +DB	9,9,36,9,72,45,18,65
        +DB	9,9,36,9,72,45,18,65
        +DB	112,112,221,112,167,173,224,215
        +DB	112,112,221,112,167,173,224,215
        +DB	182,182,226,182,217,84,113,111
        +DB	182,182,226,182,217,84,113,111
        +DB	208,208,103,208,206,183,189,30
        +DB	208,208,103,208,206,183,189,30
        +DB	237,237,147,237,59,126,199,214
        +DB	237,237,147,237,59,126,199,214
        +DB	204,204,23,204,46,219,133,226
        +DB	204,204,23,204,46,219,133,226
        +DB	66,66,21,66,42,87,132,104
        +DB	66,66,21,66,42,87,132,104
        +DB	152,152,90,152,180,194,45,44
        +DB	152,152,90,152,180,194,45,44
        +DB	164,164,170,164,73,14,85,237
        +DB	164,164,170,164,73,14,85,237
        +DB	40,40,160,40,93,136,80,117
        +DB	40,40,160,40,93,136,80,117
        +DB	92,92,109,92,218,49,184,134
        +DB	92,92,109,92,218,49,184,134
        +DB	248,248,199,248,147,63,237,107
        +DB	248,248,199,248,147,63,237,107
        +DB	134,134,34,134,68,164,17,194
        +DB	134,134,34,134,68,164,17,194
        +DB	24,35,198,232,135,184,1,79
        +DB	54,166,210,245,121,111,145,82
        +DB	96,188,155,142,163,12,123,53
        +DB	29,224,215,194,46,75,254,87
        +DB	21,119,55,229,159,240,74,218
        +DB	88,201,41,10,177,160,107,133
        +DB	189,93,16,244,203,62,5,103
        +DB	228,39,65,139,167,125,149,216
        +DB	251,238,124,102,221,23,71,158
        +DB	202,45,191,7,173,90,131,51
        +_whirlpool_block_mmx ENDP
        +.text$	ENDS
        +END
        diff --git a/vendor/openssl/asm/x86-win32-masm/x86cpuid.asm b/vendor/openssl/asm/x86-win32-masm/x86cpuid.asm
        new file mode 100644
        index 000000000..b9b1c2584
        --- /dev/null
        +++ b/vendor/openssl/asm/x86-win32-masm/x86cpuid.asm
        @@ -0,0 +1,319 @@
        +TITLE	x86cpuid.asm
        +IF @Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF @Version LT 800
        +.text$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +ALIGN	16
        +_OPENSSL_ia32_cpuid	PROC PUBLIC
        +$L_OPENSSL_ia32_cpuid_begin::
        +	push	ebp
        +	push	ebx
        +	push	esi
        +	push	edi
        +	xor	edx,edx
        +	pushfd
        +	pop	eax
        +	mov	ecx,eax
        +	xor	eax,2097152
        +	push	eax
        +	popfd
        +	pushfd
        +	pop	eax
        +	xor	ecx,eax
        +	xor	eax,eax
        +	bt	ecx,21
        +	jnc	$L000nocpuid
        +	cpuid
        +	mov	edi,eax
        +	xor	eax,eax
        +	cmp	ebx,1970169159
        +	setne	al
        +	mov	ebp,eax
        +	cmp	edx,1231384169
        +	setne	al
        +	or	ebp,eax
        +	cmp	ecx,1818588270
        +	setne	al
        +	or	ebp,eax
        +	jz	$L001intel
        +	cmp	ebx,1752462657
        +	setne	al
        +	mov	esi,eax
        +	cmp	edx,1769238117
        +	setne	al
        +	or	esi,eax
        +	cmp	ecx,1145913699
        +	setne	al
        +	or	esi,eax
        +	jnz	$L001intel
        +	mov	eax,2147483648
        +	cpuid
        +	cmp	eax,2147483649
        +	jb	$L001intel
        +	mov	esi,eax
        +	mov	eax,2147483649
        +	cpuid
        +	or	ebp,ecx
        +	and	ebp,2049
        +	cmp	esi,2147483656
        +	jb	$L001intel
        +	mov	eax,2147483656
        +	cpuid
        +	movzx	esi,cl
        +	inc	esi
        +	mov	eax,1
        +	cpuid
        +	bt	edx,28
        +	jnc	$L002generic
        +	shr	ebx,16
        +	and	ebx,255
        +	cmp	ebx,esi
        +	ja	$L002generic
        +	and	edx,4026531839
        +	jmp	$L002generic
        +$L001intel:
        +	cmp	edi,4
        +	mov	edi,-1
        +	jb	$L003nocacheinfo
        +	mov	eax,4
        +	mov	ecx,0
        +	cpuid
        +	mov	edi,eax
        +	shr	edi,14
        +	and	edi,4095
        +$L003nocacheinfo:
        +	mov	eax,1
        +	cpuid
        +	and	edx,3220176895
        +	cmp	ebp,0
        +	jne	$L004notintel
        +	or	edx,1073741824
        +	and	ah,15
        +	cmp	ah,15
        +	jne	$L004notintel
        +	or	edx,1048576
        +$L004notintel:
        +	bt	edx,28
        +	jnc	$L002generic
        +	and	edx,4026531839
        +	cmp	edi,0
        +	je	$L002generic
        +	or	edx,268435456
        +	shr	ebx,16
        +	cmp	bl,1
        +	ja	$L002generic
        +	and	edx,4026531839
        +$L002generic:
        +	and	ebp,2048
        +	and	ecx,4294965247
        +	mov	esi,edx
        +	or	ebp,ecx
        +	bt	ecx,27
        +	jnc	$L005clear_avx
        +	xor	ecx,ecx
        +DB	15,1,208
        +	and	eax,6
        +	cmp	eax,6
        +	je	$L006done
        +	cmp	eax,2
        +	je	$L005clear_avx
        +$L007clear_xmm:
        +	and	ebp,4261412861
        +	and	esi,4278190079
        +$L005clear_avx:
        +	and	ebp,4026525695
        +$L006done:
        +	mov	eax,esi
        +	mov	edx,ebp
        +$L000nocpuid:
        +	pop	edi
        +	pop	esi
        +	pop	ebx
        +	pop	ebp
        +	ret
        +_OPENSSL_ia32_cpuid ENDP
        +;EXTERN	_OPENSSL_ia32cap_P:NEAR
        +ALIGN	16
        +_OPENSSL_rdtsc	PROC PUBLIC
        +$L_OPENSSL_rdtsc_begin::
        +	xor	eax,eax
        +	xor	edx,edx
        +	lea	ecx,DWORD PTR _OPENSSL_ia32cap_P
        +	bt	DWORD PTR [ecx],4
        +	jnc	$L008notsc
        +	rdtsc
        +$L008notsc:
        +	ret
        +_OPENSSL_rdtsc ENDP
        +ALIGN	16
        +_OPENSSL_instrument_halt	PROC PUBLIC
        +$L_OPENSSL_instrument_halt_begin::
        +	lea	ecx,DWORD PTR _OPENSSL_ia32cap_P
        +	bt	DWORD PTR [ecx],4
        +	jnc	$L009nohalt
        +DD	2421723150
        +	and	eax,3
        +	jnz	$L009nohalt
        +	pushfd
        +	pop	eax
        +	bt	eax,9
        +	jnc	$L009nohalt
        +	rdtsc
        +	push	edx
        +	push	eax
        +	hlt
        +	rdtsc
        +	sub	eax,DWORD PTR [esp]
        +	sbb	edx,DWORD PTR 4[esp]
        +	add	esp,8
        +	ret
        +$L009nohalt:
        +	xor	eax,eax
        +	xor	edx,edx
        +	ret
        +_OPENSSL_instrument_halt ENDP
        +ALIGN	16
        +_OPENSSL_far_spin	PROC PUBLIC
        +$L_OPENSSL_far_spin_begin::
        +	pushfd
        +	pop	eax
        +	bt	eax,9
        +	jnc	$L010nospin
        +	mov	eax,DWORD PTR 4[esp]
        +	mov	ecx,DWORD PTR 8[esp]
        +DD	2430111262
        +	xor	eax,eax
        +	mov	edx,DWORD PTR [ecx]
        +	jmp	$L011spin
        +ALIGN	16
        +$L011spin:
        +	inc	eax
        +	cmp	edx,DWORD PTR [ecx]
        +	je	$L011spin
        +DD	529567888
        +	ret
        +$L010nospin:
        +	xor	eax,eax
        +	xor	edx,edx
        +	ret
        +_OPENSSL_far_spin ENDP
        +ALIGN	16
        +_OPENSSL_wipe_cpu	PROC PUBLIC
        +$L_OPENSSL_wipe_cpu_begin::
        +	xor	eax,eax
        +	xor	edx,edx
        +	lea	ecx,DWORD PTR _OPENSSL_ia32cap_P
        +	mov	ecx,DWORD PTR [ecx]
        +	bt	DWORD PTR [ecx],1
        +	jnc	$L012no_x87
        +DD	4007259865,4007259865,4007259865,4007259865,2430851995
        +$L012no_x87:
        +	lea	eax,DWORD PTR 4[esp]
        +	ret
        +_OPENSSL_wipe_cpu ENDP
        +ALIGN	16
        +_OPENSSL_atomic_add	PROC PUBLIC
        +$L_OPENSSL_atomic_add_begin::
        +	mov	edx,DWORD PTR 4[esp]
        +	mov	ecx,DWORD PTR 8[esp]
        +	push	ebx
        +	nop
        +	mov	eax,DWORD PTR [edx]
        +$L013spin:
        +	lea	ebx,DWORD PTR [ecx*1+eax]
        +	nop
        +DD	447811568
        +	jne	$L013spin
        +	mov	eax,ebx
        +	pop	ebx
        +	ret
        +_OPENSSL_atomic_add ENDP
        +ALIGN	16
        +_OPENSSL_indirect_call	PROC PUBLIC
        +$L_OPENSSL_indirect_call_begin::
        +	push	ebp
        +	mov	ebp,esp
        +	sub	esp,28
        +	mov	ecx,DWORD PTR 12[ebp]
        +	mov	DWORD PTR [esp],ecx
        +	mov	edx,DWORD PTR 16[ebp]
        +	mov	DWORD PTR 4[esp],edx
        +	mov	eax,DWORD PTR 20[ebp]
        +	mov	DWORD PTR 8[esp],eax
        +	mov	eax,DWORD PTR 24[ebp]
        +	mov	DWORD PTR 12[esp],eax
        +	mov	eax,DWORD PTR 28[ebp]
        +	mov	DWORD PTR 16[esp],eax
        +	mov	eax,DWORD PTR 32[ebp]
        +	mov	DWORD PTR 20[esp],eax
        +	mov	eax,DWORD PTR 36[ebp]
        +	mov	DWORD PTR 24[esp],eax
        +	call	DWORD PTR 8[ebp]
        +	mov	esp,ebp
        +	pop	ebp
        +	ret
        +_OPENSSL_indirect_call ENDP
        +ALIGN	16
        +_OPENSSL_cleanse	PROC PUBLIC
        +$L_OPENSSL_cleanse_begin::
        +	mov	edx,DWORD PTR 4[esp]
        +	mov	ecx,DWORD PTR 8[esp]
        +	xor	eax,eax
        +	cmp	ecx,7
        +	jae	$L014lot
        +	cmp	ecx,0
        +	je	$L015ret
        +$L016little:
        +	mov	BYTE PTR [edx],al
        +	sub	ecx,1
        +	lea	edx,DWORD PTR 1[edx]
        +	jnz	$L016little
        +$L015ret:
        +	ret
        +ALIGN	16
        +$L014lot:
        +	test	edx,3
        +	jz	$L017aligned
        +	mov	BYTE PTR [edx],al
        +	lea	ecx,DWORD PTR [ecx-1]
        +	lea	edx,DWORD PTR 1[edx]
        +	jmp	$L014lot
        +$L017aligned:
        +	mov	DWORD PTR [edx],eax
        +	lea	ecx,DWORD PTR [ecx-4]
        +	test	ecx,-4
        +	lea	edx,DWORD PTR 4[edx]
        +	jnz	$L017aligned
        +	cmp	ecx,0
        +	jne	$L016little
        +	ret
        +_OPENSSL_cleanse ENDP
        +ALIGN	16
        +_OPENSSL_ia32_rdrand	PROC PUBLIC
        +$L_OPENSSL_ia32_rdrand_begin::
        +	mov	ecx,8
        +$L018loop:
        +DB	15,199,240
        +	jc	$L019break
        +	loop	$L018loop
        +$L019break:
        +	cmp	eax,0
        +	cmove	eax,ecx
        +	ret
        +_OPENSSL_ia32_rdrand ENDP
        +.text$	ENDS
        +.bss	SEGMENT 'BSS'
        +COMM	_OPENSSL_ia32cap_P:QWORD
        +.bss	ENDS
        +.CRT$XCU	SEGMENT DWORD PUBLIC 'DATA'
        +EXTERN	_OPENSSL_cpuid_setup:NEAR
        +DD	_OPENSSL_cpuid_setup
        +.CRT$XCU	ENDS
        +END
        diff --git a/vendor/openssl/config/opensslconf.h b/vendor/openssl/config/opensslconf.h
        new file mode 100644
        index 000000000..9bf23692d
        --- /dev/null
        +++ b/vendor/openssl/config/opensslconf.h
        @@ -0,0 +1,333 @@
        +/* opensslconf.h */
        +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
        +
        +/* OpenSSL was configured with the following options: */
        +#undef OPENSSL_SYSNAME_WIN32
        +#if defined(_WIN32)
        +# define OPENSSL_SYSNAME_WIN32
        +#endif
        +
        +#ifndef OPENSSL_DOING_MAKEDEPEND
        +# ifndef OPENSSL_NO_CAPIENG
        +#  define OPENSSL_NO_CAPIENG
        +# endif
        +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +#  define OPENSSL_NO_EC_NISTP_64_GCC_128
        +# endif
        +# ifndef OPENSSL_NO_GMP
        +#  define OPENSSL_NO_GMP
        +# endif
        +# ifndef OPENSSL_NO_GOST
        +#  define OPENSSL_NO_GOST
        +# endif
        +# ifndef OPENSSL_NO_HW_PADLOCK
        +#  define OPENSSL_NO_HW_PADLOCK
        +# endif
        +# ifndef OPENSSL_NO_JPAKE
        +#  define OPENSSL_NO_JPAKE
        +# endif
        +# ifndef OPENSSL_NO_KRB5
        +#  define OPENSSL_NO_KRB5
        +# endif
        +# ifndef OPENSSL_NO_MD2
        +#  define OPENSSL_NO_MD2
        +# endif
        +# ifndef OPENSSL_NO_RC5
        +#  define OPENSSL_NO_RC5
        +# endif
        +# ifndef OPENSSL_NO_RFC3779
        +#  define OPENSSL_NO_RFC3779
        +# endif
        +# ifndef OPENSSL_NO_SCTP
        +#  define OPENSSL_NO_SCTP
        +# endif
        +# ifndef OPENSSL_NO_STORE
        +#  define OPENSSL_NO_STORE
        +# endif
        +#endif /* OPENSSL_DOING_MAKEDEPEND */
        +
        +#ifndef OPENSSL_THREADS
        +# define OPENSSL_THREADS
        +#endif
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +# define OPENSSL_NO_DYNAMIC_ENGINE
        +#endif
        +
        +/* The OPENSSL_NO_* macros are also defined as NO_* if the application
        +   asks for it.  This is a transient feature that is provided for those
        +   who haven't had the time to do the appropriate changes in their
        +   applications.  */
        +#ifdef OPENSSL_ALGORITHM_DEFINES
        +# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
        +#  define NO_CAMELLIA
        +# endif
        +# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
        +#  define NO_CAPIENG
        +# endif
        +# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
        +#  define NO_CAST
        +# endif
        +# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
        +#  define NO_CMS
        +# endif
        +# if defined(OPENSSL_NO_FIPS) && !defined(NO_FIPS)
        +#  define NO_FIPS
        +# endif
        +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
        +#  define NO_GMP
        +# endif
        +# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
        +#  define NO_IDEA
        +# endif
        +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
        +#  define NO_JPAKE
        +# endif
        +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
        +#  define NO_KRB5
        +# endif
        +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
        +#  define NO_MD2
        +# endif
        +# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
        +#  define NO_MDC2
        +# endif
        +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
        +#  define NO_RC5
        +# endif
        +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
        +#  define NO_RFC3779
        +# endif
        +# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
        +#  define NO_SEED
        +# endif
        +# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
        +#  define NO_SHA0
        +# endif
        +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
        +#  define NO_STORE
        +# endif
        +# if defined(OPENSSL_NO_WHRLPOOL) && !defined(NO_WHRLPOOL)
        +#  define NO_WHRLPOOL
        +# endif
        +# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
        +#  define NO_MDC2
        +# endif
        +#endif
        +
        +/* crypto/opensslconf.h.in */
        +
        +#ifdef OPENSSL_DOING_MAKEDEPEND
        + /* Include any symbols here that have to be explicitly set to enable a feature
        +  * that should be visible to makedepend.
        +  *
        +  * [Our "make depend" doesn't actually look at this, we use actual build settings
        +  * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
        +  */
        +# ifndef OPENSSL_FIPS
        +#  define OPENSSL_FIPS
        +# endif
        +#endif
        +
        +/* Generate 80386 code? */
        +#undef I386_ONLY
        +
        +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
        +# if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
        +#  if defined(_WIN32)
        +#   define ENGINESDIR "ssl/lib/engines"
        +#   define OPENSSLDIR "ssl"
        +#  else
        +#   define ENGINESDIR "/usr/local/ssl/lib/engines"
        +#   define OPENSSLDIR "/usr/local/ssl"
        +#  endif
        +# endif
        +#endif
        +
        +#undef OPENSSL_UNISTD
        +#define OPENSSL_UNISTD <unistd.h>
        +#if !defined(_WIN32) && !defined(__arm__) && !defined(__mips__) && !defined(SWIG)
        +# include <unistd.h>
        +#endif
        +
        +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +#if defined(_WIN32)
        +# define OPENSSL_EXPORT_VAR_AS_FUNCTION
        +#endif
        +
        +#if defined(HEADER_IDEA_H)
        +# undef IDEA_INT
        +# define IDEA_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_MD2_H)
        +# undef MD2_INT
        +# define MD2_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_RC2_H)
        +/* I need to put in a mod for the alpha - eay */
        +# undef RC2_INT
        +# define RC2_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_RC4_H)
        + /* using int types make the structure larger but make the code faster
        +  * on most boxes I have tested - up to %20 faster. */
        + /*
        +  * I don't know what does "most" mean, but declaring "int" is a must on:
        +  * - Intel P6 because partial register stalls are very expensive;
        +  * - elder Alpha because it lacks byte load/store instructions;
        +  */
        +# undef RC4_INT
        +# if defined(__arm__)
        +#  define RC4_INT unsigned char
        +# else
        +#  define RC4_INT unsigned int
        +# endif
        +
        +  /*
        +   * This enables code handling data aligned at natural CPU word
        +   * boundary. See crypto/rc4/rc4_enc.c for further details.
        +   */
        +# undef RC4_CHUNK
        +# if (defined(_M_X64) || defined(__x86_64__)) && defined(_WIN32)
        +#  define RC4_CHUNK unsigned long long
        +# elif (defined(_M_X64) || defined(__x86_64__)) && !defined(_WIN32)
        +#  define RC4_CHUNK unsigned long
        +# elif defined(__arm__)
        +#  define RC4_CHUNK unsigned long
        +# else
        +   /* On x86 RC4_CHUNK is not defined */
        +# endif
        +#endif
        +
        +#if defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)
        + /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
        +  * %20 speed up (longs are 8 bytes, int's are 4). */
        +# undef DES_LONG
        +# if defined(_M_X64) || defined(__x86_64__) || defined(__arm__) || defined(__mips__)
        +#  define DES_LONG unsigned int
        +# elif defined(_M_IX86) || defined(__i386__)
        +#  define DES_LONG unsigned long
        +# endif
        +#endif
        +
        +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
        +# define CONFIG_HEADER_BN_H
        +
        +# undef BL_LLONG
        +# if defined(_M_IX86) || defined(__i386__) || defined(__arm__)
        +#  define BL_LLONG
        +# endif
        +
        + /* Should we define BN_DIV2W here? */
        +
        + /* Only one for the following should be defined */
        + /* The prime number generation stuff may not work when
        +  * EIGHT_BIT but I don't care since I've only used this mode
        +  * for debuging the bignum libraries */
        +# undef SIXTY_FOUR_BIT_LONG
        +# undef SIXTY_FOUR_BIT
        +# undef THIRTY_TWO_BIT
        +# undef SIXTEEN_BIT
        +# undef EIGHT_BIT
        +# if (defined(_M_X64) || defined(__x86_64__)) && defined(_WIN32)
        +#  define SIXTY_FOUR_BIT
        +# elif (defined(_M_X64) || defined(__x86_64__)) && !defined(_WIN32)
        +#  define SIXTY_FOUR_BIT_LONG
        +# elif defined(_M_IX86) || defined(__i386__) || defined(__arm__) || defined(__mips__)
        +#  define THIRTY_TWO_BIT
        +# endif
        +#endif
        +
        +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
        +# define CONFIG_HEADER_RC4_LOCL_H
        + /* if this is defined data[i] is used instead of *data, this is a %20
        +  * speedup on x86 */
        +# undef RC4_INDEX
        +# if defined(_M_IX86) || defined(__i386__)
        +#  define RC4_INDEX
        +# endif
        +#endif
        +
        +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
        +# define CONFIG_HEADER_BF_LOCL_H
        +# undef BF_PTR
        +# if defined(__arm__)
        +#  define BF_PTR
        +# endif
        +#endif /* HEADER_BF_LOCL_H */
        +
        +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
        +# define CONFIG_HEADER_DES_LOCL_H
        +
        +# ifndef DES_DEFAULT_OPTIONS
        +   /* the following is tweaked from a config script, that is why it is a
        +    * protected undef/define */
        +#  undef DES_PTR
        +#  if !defined(_WIN32) && (defined(_M_IX86) || defined(__i386__))
        +#   define DES_PTR
        +#  endif
        +
        +   /* This helps C compiler generate the correct code for multiple functional
        +    * units.  It reduces register dependancies at the expense of 2 more
        +    * registers */
        +#  undef DES_RISC1
        +#  if !defined(_WIN32) && (defined(_M_IX86) || defined(__i386__))
        +#   define DES_RISC1
        +#  endif
        +
        +#  undef DES_RISC2
        +
        +#  if defined(DES_RISC1) && defined(DES_RISC2)
        +#   error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
        +#  endif
        +
        +  /* Unroll the inner loop, this sometimes helps, sometimes hinders.
        +   * Very mucy CPU dependant */
        +#  undef DES_UNROLL
        +#  if !defined(_WIN32)
        +#   define DES_UNROLL
        +#  endif
        +
        +  /* These default values were supplied by
        +   * Peter Gutman <pgut001@cs.auckland.ac.nz>
        +   * They are only used if nothing else has been defined */
        +# if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
        +   /* Special defines which change the way the code is built depending on the
        +      CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
        +      even newer MIPS CPU's, but at the moment one size fits all for
        +      optimization options.  Older Sparc's work better with only UNROLL, but
        +      there's no way to tell at compile time what it is you're running on */
        +#  if defined( sun )		/* Newer Sparc's */
        +#    define DES_PTR
        +#    define DES_RISC1
        +#    define DES_UNROLL
        +#  elif defined( __ultrix )	/* Older MIPS */
        +#    define DES_PTR
        +#    define DES_RISC2
        +#    define DES_UNROLL
        +#  elif defined( __osf1__ )	/* Alpha */
        +#    define DES_PTR
        +#    define DES_RISC2
        +#  elif defined ( _AIX )		/* RS6000 */
        +    /* Unknown */
        +#  elif defined( __hpux )		/* HP-PA */
        +    /* Unknown */
        +#  elif defined( __aux )		/* 68K */
        +    /* Unknown */
        +#  elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
        +#    define DES_UNROLL
        +#  elif defined( __sgi )		/* Newer MIPS */
        +#    define DES_PTR
        +#    define DES_RISC2
        +#    define DES_UNROLL
        +#  elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
        +#    define DES_PTR
        +#    define DES_RISC1
        +#    define DES_UNROLL
        +#  endif /* Systems-specific speed defines */
        +# endif
        +
        +# endif /* DES_DEFAULT_OPTIONS */
        +#endif /* HEADER_DES_LOCL_H */
        diff --git a/vendor/openssl/openssl/ACKNOWLEDGMENTS b/vendor/openssl/openssl/ACKNOWLEDGMENTS
        new file mode 100644
        index 000000000..fb6dd912c
        --- /dev/null
        +++ b/vendor/openssl/openssl/ACKNOWLEDGMENTS
        @@ -0,0 +1,25 @@
        +The OpenSSL project depends on volunteer efforts and financial support from
        +the end user community. That support comes in the form of donations and paid
        +sponsorships, software support contracts, paid consulting services
        +and commissioned software development.
        +
        +Since all these activities support the continued development and improvement
        +of OpenSSL we consider all these clients and customers as sponsors of the
        +OpenSSL project.
        +
        +We would like to identify and thank the following such sponsors for their past
        +or current significant support of the OpenSSL project:
        +
        +Very significant support:
        +
        +	OpenGear: www.opengear.com
        +
        +Significant support:
        +
        +	PSW Group: www.psw.net
        +
        +Please note that we ask permission to identify sponsors and that some sponsors
        +we consider eligible for inclusion here have requested to remain anonymous.
        +
        +Additional sponsorship or financial support is always welcome: for more
        +information please contact the OpenSSL Software Foundation.
        diff --git a/vendor/openssl/openssl/CHANGES b/vendor/openssl/openssl/CHANGES
        new file mode 100644
        index 000000000..ca82ad295
        --- /dev/null
        +++ b/vendor/openssl/openssl/CHANGES
        @@ -0,0 +1,10039 @@
        +
        + OpenSSL CHANGES
        + _______________
        +
        + Changes between 1.0.1d and 1.0.1e [11 Feb 2013]
        +
        +  *)
        +
        + Changes between 1.0.1c and 1.0.1d [5 Feb 2013]
        +
        +  *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time.
        +
        +     This addresses the flaw in CBC record processing discovered by 
        +     Nadhem Alfardan and Kenny Paterson. Details of this attack can be found
        +     at: http://www.isg.rhul.ac.uk/tls/     
        +
        +     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
        +     Security Group at Royal Holloway, University of London
        +     (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and
        +     Emilia Käsper for the initial patch.
        +     (CVE-2013-0169)
        +     [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson]
        +
        +  *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode
        +     ciphersuites which can be exploited in a denial of service attack.
        +     Thanks go to and to Adam Langley <agl@chromium.org> for discovering
        +     and detecting this bug and to Wolfgang Ettlinger
        +     <wolfgang.ettlinger@gmail.com> for independently discovering this issue.
        +     (CVE-2012-2686)
        +     [Adam Langley]
        +
        +  *) Return an error when checking OCSP signatures when key is NULL.
        +     This fixes a DoS attack. (CVE-2013-0166)
        +     [Steve Henson]
        +
        +  *) Make openssl verify return errors.
        +     [Chris Palmer <palmer@google.com> and Ben Laurie]
        +
        +  *) Call OCSP Stapling callback after ciphersuite has been chosen, so
        +     the right response is stapled. Also change SSL_get_certificate()
        +     so it returns the certificate actually sent.
        +     See http://rt.openssl.org/Ticket/Display.html?id=2836.
        +     [Rob Stradling <rob.stradling@comodo.com>]
        +
        +  *) Fix possible deadlock when decoding public keys.
        +     [Steve Henson]
        +
        +  *) Don't use TLS 1.0 record version number in initial client hello
        +     if renegotiating.
        +     [Steve Henson]
        +
        + Changes between 1.0.1b and 1.0.1c [10 May 2012]
        +
        +  *) Sanity check record length before skipping explicit IV in TLS
        +     1.2, 1.1 and DTLS to fix DoS attack.
        +
        +     Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic
        +     fuzzing as a service testing platform.
        +     (CVE-2012-2333)
        +     [Steve Henson]
        +
        +  *) Initialise tkeylen properly when encrypting CMS messages.
        +     Thanks to Solar Designer of Openwall for reporting this issue.
        +     [Steve Henson]
        +
        +  *) In FIPS mode don't try to use composite ciphers as they are not
        +     approved.
        +     [Steve Henson]
        +
        + Changes between 1.0.1a and 1.0.1b [26 Apr 2012]
        +
        +  *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and
        +     1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately
        +     mean any application compiled against OpenSSL 1.0.0 headers setting
        +     SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng
        +     TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to
        +     0x10000000L Any application which was previously compiled against
        +     OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1
        +     will need to be recompiled as a result. Letting be results in
        +     inability to disable specifically TLS 1.1 and in client context,
        +     in unlike event, limit maximum offered version to TLS 1.0 [see below].
        +     [Steve Henson]
        +
        +  *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not
        +     disable just protocol X, but all protocols above X *if* there are
        +     protocols *below* X still enabled. In more practical terms it means
        +     that if application wants to disable TLS1.0 in favor of TLS1.1 and
        +     above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass
        +     SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to
        +     client side.
        +     [Andy Polyakov]
        +
        + Changes between 1.0.1 and 1.0.1a [19 Apr 2012]
        +
        +  *) Check for potentially exploitable overflows in asn1_d2i_read_bio
        +     BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer
        +     in CRYPTO_realloc_clean.
        +
        +     Thanks to Tavis Ormandy, Google Security Team, for discovering this
        +     issue and to Adam Langley <agl@chromium.org> for fixing it.
        +     (CVE-2012-2110)
        +     [Adam Langley (Google), Tavis Ormandy, Google Security Team]
        +
        +  *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
        +     [Adam Langley]
        +
        +  *) Workarounds for some broken servers that "hang" if a client hello
        +     record length exceeds 255 bytes.
        +
        +     1. Do not use record version number > TLS 1.0 in initial client
        +        hello: some (but not all) hanging servers will now work.
        +     2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate
        +	the number of ciphers sent in the client hello. This should be
        +        set to an even number, such as 50, for example by passing:
        +        -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure.
        +        Most broken servers should now work.
        +     3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable
        +	TLS 1.2 client support entirely.
        +     [Steve Henson]
        +
        +  *) Fix SEGV in Vector Permutation AES module observed in OpenSSH.
        +     [Andy Polyakov]
        +
        + Changes between 1.0.0h and 1.0.1  [14 Mar 2012]
        +
        +  *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET
        +     STRING form instead of a DigestInfo.
        +     [Steve Henson]
        +
        +  *) The format used for MDC2 RSA signatures is inconsistent between EVP
        +     and the RSA_sign/RSA_verify functions. This was made more apparent when
        +     OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular
        +     those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect 
        +     the correct format in RSA_verify so both forms transparently work.
        +     [Steve Henson]
        +
        +  *) Some servers which support TLS 1.0 can choke if we initially indicate
        +     support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
        +     encrypted premaster secret. As a workaround use the maximum pemitted
        +     client version in client hello, this should keep such servers happy
        +     and still work with previous versions of OpenSSL.
        +     [Steve Henson]
        +
        +  *) Add support for TLS/DTLS heartbeats.
        +     [Robin Seggelmann <seggelmann@fh-muenster.de>]
        +
        +  *) Add support for SCTP.
        +     [Robin Seggelmann <seggelmann@fh-muenster.de>]
        +
        +  *) Improved PRNG seeding for VOS.
        +     [Paul Green <Paul.Green@stratus.com>]
        +
        +  *) Extensive assembler packs updates, most notably:
        +
        +	- x86[_64]:     AES-NI, PCLMULQDQ, RDRAND support;
        +	- x86[_64]:     SSSE3 support (SHA1, vector-permutation AES);
        +	- x86_64:       bit-sliced AES implementation;
        +	- ARM:          NEON support, contemporary platforms optimizations;
        +	- s390x:        z196 support;
        +	- *:            GHASH and GF(2^m) multiplication implementations;
        +
        +     [Andy Polyakov]
        +
        +  *) Make TLS-SRP code conformant with RFC 5054 API cleanup
        +     (removal of unnecessary code)
        +     [Peter Sylvester <peter.sylvester@edelweb.fr>]
        +
        +  *) Add TLS key material exporter from RFC 5705.
        +     [Eric Rescorla]
        +
        +  *) Add DTLS-SRTP negotiation from RFC 5764.
        +     [Eric Rescorla]
        +
        +  *) Add Next Protocol Negotiation,
        +     http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be
        +     disabled with a no-npn flag to config or Configure. Code donated
        +     by Google.
        +     [Adam Langley <agl@google.com> and Ben Laurie]
        +
        +  *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224,
        +     NIST-P256, NIST-P521, with constant-time single point multiplication on
        +     typical inputs. Compiler support for the nonstandard type __uint128_t is
        +     required to use this (present in gcc 4.4 and later, for 64-bit builds).
        +     Code made available under Apache License version 2.0.
        +
        +     Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command
        +     line to include this in your build of OpenSSL, and run "make depend" (or
        +     "make update"). This enables the following EC_METHODs:
        +
        +         EC_GFp_nistp224_method()
        +         EC_GFp_nistp256_method()
        +         EC_GFp_nistp521_method()
        +
        +     EC_GROUP_new_by_curve_name() will automatically use these (while
        +     EC_GROUP_new_curve_GFp() currently prefers the more flexible
        +     implementations).
        +     [Emilia Käsper, Adam Langley, Bodo Moeller (Google)]
        +
        +  *) Use type ossl_ssize_t instad of ssize_t which isn't available on
        +     all platforms. Move ssize_t definition from e_os.h to the public
        +     header file e_os2.h as it now appears in public header file cms.h
        +     [Steve Henson]
        +
        +  *) New -sigopt option to the ca, req and x509 utilities. Additional
        +     signature parameters can be passed using this option and in
        +     particular PSS. 
        +     [Steve Henson]
        +
        +  *) Add RSA PSS signing function. This will generate and set the
        +     appropriate AlgorithmIdentifiers for PSS based on those in the
        +     corresponding EVP_MD_CTX structure. No application support yet.
        +     [Steve Henson]
        +
        +  *) Support for companion algorithm specific ASN1 signing routines.
        +     New function ASN1_item_sign_ctx() signs a pre-initialised
        +     EVP_MD_CTX structure and sets AlgorithmIdentifiers based on
        +     the appropriate parameters.
        +     [Steve Henson]
        +
        +  *) Add new algorithm specific ASN1 verification initialisation function
        +     to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1
        +     handling will be the same no matter what EVP_PKEY_METHOD is used.
        +     Add a PSS handler to support verification of PSS signatures: checked
        +     against a number of sample certificates.
        +     [Steve Henson]
        +
        +  *) Add signature printing for PSS. Add PSS OIDs.
        +     [Steve Henson, Martin Kaiser <lists@kaiser.cx>]
        +
        +  *) Add algorithm specific signature printing. An individual ASN1 method
        +     can now print out signatures instead of the standard hex dump. 
        +
        +     More complex signatures (e.g. PSS) can print out more meaningful
        +     information. Include DSA version that prints out the signature
        +     parameters r, s.
        +     [Steve Henson]
        +
        +  *) Password based recipient info support for CMS library: implementing
        +     RFC3211.
        +     [Steve Henson]
        +
        +  *) Split password based encryption into PBES2 and PBKDF2 functions. This
        +     neatly separates the code into cipher and PBE sections and is required
        +     for some algorithms that split PBES2 into separate pieces (such as
        +     password based CMS).
        +     [Steve Henson]
        +
        +  *) Session-handling fixes:
        +     - Fix handling of connections that are resuming with a session ID,
        +       but also support Session Tickets.
        +     - Fix a bug that suppressed issuing of a new ticket if the client
        +       presented a ticket with an expired session.
        +     - Try to set the ticket lifetime hint to something reasonable.
        +     - Make tickets shorter by excluding irrelevant information.
        +     - On the client side, don't ignore renewed tickets.
        +     [Adam Langley, Bodo Moeller (Google)]
        +
        +  *) Fix PSK session representation.
        +     [Bodo Moeller]
        +
        +  *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations.
        +
        +     This work was sponsored by Intel.
        +     [Andy Polyakov]
        +
        +  *) Add GCM support to TLS library. Some custom code is needed to split
        +     the IV between the fixed (from PRF) and explicit (from TLS record)
        +     portions. This adds all GCM ciphersuites supported by RFC5288 and 
        +     RFC5289. Generalise some AES* cipherstrings to inlclude GCM and
        +     add a special AESGCM string for GCM only.
        +     [Steve Henson]
        +
        +  *) Expand range of ctrls for AES GCM. Permit setting invocation
        +     field on decrypt and retrieval of invocation field only on encrypt.
        +     [Steve Henson]
        +
        +  *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support.
        +     As required by RFC5289 these ciphersuites cannot be used if for
        +     versions of TLS earlier than 1.2.
        +     [Steve Henson]
        +
        +  *) For FIPS capable OpenSSL interpret a NULL default public key method
        +     as unset and return the appopriate default but do *not* set the default.
        +     This means we can return the appopriate method in applications that
        +     swicth between FIPS and non-FIPS modes.
        +     [Steve Henson]
        +
        +  *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an
        +     ENGINE is used then we cannot handle that in the FIPS module so we
        +     keep original code iff non-FIPS operations are allowed.
        +     [Steve Henson]
        +
        +  *) Add -attime option to openssl utilities.
        +     [Peter Eckersley <pde@eff.org>, Ben Laurie and Steve Henson]
        +
        +  *) Redirect DSA and DH operations to FIPS module in FIPS mode.
        +     [Steve Henson]
        +
        +  *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use
        +     FIPS EC methods unconditionally for now.
        +     [Steve Henson]
        +
        +  *) New build option no-ec2m to disable characteristic 2 code.
        +     [Steve Henson]
        +
        +  *) Backport libcrypto audit of return value checking from 1.1.0-dev; not
        +     all cases can be covered as some introduce binary incompatibilities.
        +     [Steve Henson]
        +
        +  *) Redirect RSA operations to FIPS module including keygen,
        +     encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods.
        +     [Steve Henson]
        +
        +  *) Add similar low level API blocking to ciphers.
        +     [Steve Henson]
        +
        +  *) Low level digest APIs are not approved in FIPS mode: any attempt
        +     to use these will cause a fatal error. Applications that *really* want
        +     to use them can use the private_* version instead.
        +     [Steve Henson]
        +
        +  *) Redirect cipher operations to FIPS module for FIPS builds. 
        +     [Steve Henson]
        +
        +  *) Redirect digest operations to FIPS module for FIPS builds. 
        +     [Steve Henson]
        +
        +  *) Update build system to add "fips" flag which will link in fipscanister.o
        +     for static and shared library builds embedding a signature if needed.
        +     [Steve Henson]
        +
        +  *) Output TLS supported curves in preference order instead of numerical
        +     order. This is currently hardcoded for the highest order curves first.
        +     This should be configurable so applications can judge speed vs strength.
        +     [Steve Henson]
        +
        +  *) Add TLS v1.2 server support for client authentication. 
        +     [Steve Henson]
        +
        +  *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
        +     and enable MD5.
        +     [Steve Henson]
        +
        +  *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
        +     FIPS modules versions.
        +     [Steve Henson]
        +
        +  *) Add TLS v1.2 client side support for client authentication. Keep cache
        +     of handshake records longer as we don't know the hash algorithm to use
        +     until after the certificate request message is received.
        +     [Steve Henson]
        +
        +  *) Initial TLS v1.2 client support. Add a default signature algorithms
        +     extension including all the algorithms we support. Parse new signature
        +     format in client key exchange. Relax some ECC signing restrictions for
        +     TLS v1.2 as indicated in RFC5246.
        +     [Steve Henson]
        +
        +  *) Add server support for TLS v1.2 signature algorithms extension. Switch
        +     to new signature format when needed using client digest preference.
        +     All server ciphersuites should now work correctly in TLS v1.2. No client
        +     support yet and no support for client certificates.
        +     [Steve Henson]
        +
        +  *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch
        +     to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based
        +     ciphersuites. At present only RSA key exchange ciphersuites work with
        +     TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete
        +     SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods
        +     and version checking.
        +     [Steve Henson]
        +
        +  *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled
        +     with this defined it will not be affected by any changes to ssl internal
        +     structures. Add several utility functions to allow openssl application
        +     to work with OPENSSL_NO_SSL_INTERN defined.
        +     [Steve Henson]
        +
        +  *) Add SRP support.
        +     [Tom Wu <tjw@cs.stanford.edu> and Ben Laurie]
        +
        +  *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id.
        +     [Steve Henson]
        +
        +  *) Permit abbreviated handshakes when renegotiating using the function
        +     SSL_renegotiate_abbreviated().
        +     [Robin Seggelmann <seggelmann@fh-muenster.de>]
        +
        +  *) Add call to ENGINE_register_all_complete() to
        +     ENGINE_load_builtin_engines(), so some implementations get used
        +     automatically instead of needing explicit application support.
        +     [Steve Henson]
        +
        +  *) Add support for TLS key exporter as described in RFC5705.
        +     [Robin Seggelmann <seggelmann@fh-muenster.de>, Steve Henson]
        +
        +  *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only
        +     a few changes are required:
        +
        +       Add SSL_OP_NO_TLSv1_1 flag.
        +       Add TLSv1_1 methods.
        +       Update version checking logic to handle version 1.1.
        +       Add explicit IV handling (ported from DTLS code).
        +       Add command line options to s_client/s_server.
        +     [Steve Henson]
        +
        + Changes between 1.0.0g and 1.0.0h [12 Mar 2012]
        +
        +  *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness
        +     in CMS and PKCS7 code. When RSA decryption fails use a random key for
        +     content decryption and always return the same error. Note: this attack
        +     needs on average 2^20 messages so it only affects automated senders. The
        +     old behaviour can be reenabled in the CMS code by setting the
        +     CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where
        +     an MMA defence is not necessary.
        +     Thanks to Ivan Nestlerode <inestlerode@us.ibm.com> for discovering
        +     this issue. (CVE-2012-0884)
        +     [Steve Henson]
        +
        +  *) Fix CVE-2011-4619: make sure we really are receiving a 
        +     client hello before rejecting multiple SGC restarts. Thanks to
        +     Ivan Nestlerode <inestlerode@us.ibm.com> for discovering this bug.
        +     [Steve Henson]
        +
        + Changes between 1.0.0f and 1.0.0g [18 Jan 2012]
        +
        +  *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109.
        +     Thanks to Antonio Martin, Enterprise Secure Access Research and
        +     Development, Cisco Systems, Inc. for discovering this bug and
        +     preparing a fix. (CVE-2012-0050)
        +     [Antonio Martin]
        +
        + Changes between 1.0.0e and 1.0.0f [4 Jan 2012]
        +
        +  *) Nadhem Alfardan and Kenny Paterson have discovered an extension
        +     of the Vaudenay padding oracle attack on CBC mode encryption
        +     which enables an efficient plaintext recovery attack against
        +     the OpenSSL implementation of DTLS. Their attack exploits timing
        +     differences arising during decryption processing. A research
        +     paper describing this attack can be found at:
        +                  http://www.isg.rhul.ac.uk/~kp/dtls.pdf
        +     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
        +     Security Group at Royal Holloway, University of London
        +     (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
        +     <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
        +     for preparing the fix. (CVE-2011-4108)
        +     [Robin Seggelmann, Michael Tuexen]
        +
        +  *) Clear bytes used for block padding of SSL 3.0 records.
        +     (CVE-2011-4576)
        +     [Adam Langley (Google)]
        +
        +  *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George
        +     Kadianakis <desnacked@gmail.com> for discovering this issue and
        +     Adam Langley for preparing the fix. (CVE-2011-4619)
        +     [Adam Langley (Google)]
        +
        +  *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
        +     [Andrey Kulikov <amdeich@gmail.com>]
        +
        +  *) Prevent malformed RFC3779 data triggering an assertion failure.
        +     Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
        +     and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
        +     [Rob Austein <sra@hactrn.net>]
        +
        +  *) Improved PRNG seeding for VOS.
        +     [Paul Green <Paul.Green@stratus.com>]
        +
        +  *) Fix ssl_ciph.c set-up race.
        +     [Adam Langley (Google)]
        +
        +  *) Fix spurious failures in ecdsatest.c.
        +     [Emilia Käsper (Google)]
        +
        +  *) Fix the BIO_f_buffer() implementation (which was mixing different
        +     interpretations of the '..._len' fields).
        +     [Adam Langley (Google)]
        +
        +  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
        +     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
        +     threads won't reuse the same blinding coefficients.
        +
        +     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
        +     lock to call BN_BLINDING_invert_ex, and avoids one use of
        +     BN_BLINDING_update for each BN_BLINDING structure (previously,
        +     the last update always remained unused).
        +     [Emilia Käsper (Google)]
        +
        +  *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf.
        +     [Bob Buckholz (Google)]
        +
        + Changes between 1.0.0d and 1.0.0e [6 Sep 2011]
        +
        +  *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted
        +     by initialising X509_STORE_CTX properly. (CVE-2011-3207)
        +     [Kaspar Brand <ossl@velox.ch>]
        +
        +  *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
        +     for multi-threaded use of ECDH. (CVE-2011-3210)
        +     [Adam Langley (Google)]
        +
        +  *) Fix x509_name_ex_d2i memory leak on bad inputs.
        +     [Bodo Moeller]
        +
        +  *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check
        +     signature public key algorithm by using OID xref utilities instead.
        +     Before this you could only use some ECC ciphersuites with SHA1 only.
        +     [Steve Henson]
        +
        +  *) Add protection against ECDSA timing attacks as mentioned in the paper
        +     by Billy Bob Brumley and Nicola Tuveri, see:
        +
        +	http://eprint.iacr.org/2011/232.pdf
        +
        +     [Billy Bob Brumley and Nicola Tuveri]
        +
        + Changes between 1.0.0c and 1.0.0d [8 Feb 2011]
        +
        +  *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
        +     [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
        +
        +  *) Fix bug in string printing code: if *any* escaping is enabled we must
        +     escape the escape character (backslash) or the resulting string is
        +     ambiguous.
        +     [Steve Henson]
        +
        + Changes between 1.0.0b and 1.0.0c  [2 Dec 2010]
        +
        +  *) Disable code workaround for ancient and obsolete Netscape browsers
        +     and servers: an attacker can use it in a ciphersuite downgrade attack.
        +     Thanks to Martin Rex for discovering this bug. CVE-2010-4180
        +     [Steve Henson]
        +
        +  *) Fixed J-PAKE implementation error, originally discovered by
        +     Sebastien Martini, further info and confirmation from Stefan
        +     Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
        +     [Ben Laurie]
        +
        + Changes between 1.0.0a and 1.0.0b  [16 Nov 2010]
        +
        +  *) Fix extension code to avoid race conditions which can result in a buffer
        +     overrun vulnerability: resumed sessions must not be modified as they can
        +     be shared by multiple threads. CVE-2010-3864
        +     [Steve Henson]
        +
        +  *) Fix WIN32 build system to correctly link an ENGINE directory into
        +     a DLL. 
        +     [Steve Henson]
        +
        + Changes between 1.0.0 and 1.0.0a  [01 Jun 2010]
        +
        +  *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover 
        +     (CVE-2010-1633)
        +     [Steve Henson, Peter-Michael Hager <hager@dortmund.net>]
        +
        + Changes between 0.9.8n and 1.0.0  [29 Mar 2010]
        +
        +  *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher
        +     context. The operation can be customised via the ctrl mechanism in
        +     case ENGINEs want to include additional functionality.
        +     [Steve Henson]
        +
        +  *) Tolerate yet another broken PKCS#8 key format: private key value negative.
        +     [Steve Henson]
        +
        +  *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
        +     output hashes compatible with older versions of OpenSSL.
        +     [Willy Weisz <weisz@vcpc.univie.ac.at>]
        +
        +  *) Fix compression algorithm handling: if resuming a session use the
        +     compression algorithm of the resumed session instead of determining
        +     it from client hello again. Don't allow server to change algorithm.
        +     [Steve Henson]
        +
        +  *) Add load_crls() function to apps tidying load_certs() too. Add option
        +     to verify utility to allow additional CRLs to be included.
        +     [Steve Henson]
        +
        +  *) Update OCSP request code to permit adding custom headers to the request:
        +     some responders need this.
        +     [Steve Henson]
        +
        +  *) The function EVP_PKEY_sign() returns <=0 on error: check return code
        +     correctly.
        +     [Julia Lawall <julia@diku.dk>]
        +
        +  *) Update verify callback code in apps/s_cb.c and apps/verify.c, it
        +     needlessly dereferenced structures, used obsolete functions and
        +     didn't handle all updated verify codes correctly.
        +     [Steve Henson]
        +
        +  *) Disable MD2 in the default configuration.
        +     [Steve Henson]
        +
        +  *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to
        +     indicate the initial BIO being pushed or popped. This makes it possible
        +     to determine whether the BIO is the one explicitly called or as a result
        +     of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so
        +     it handles reference counts correctly and doesn't zero out the I/O bio
        +     when it is not being explicitly popped. WARNING: applications which
        +     included workarounds for the old buggy behaviour will need to be modified
        +     or they could free up already freed BIOs.
        +     [Steve Henson]
        +
        +  *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni
        +     renaming to all platforms (within the 0.9.8 branch, this was
        +     done conditionally on Netware platforms to avoid a name clash).
        +     [Guenter <lists@gknw.net>]
        +
        +  *) Add ECDHE and PSK support to DTLS.
        +     [Michael Tuexen <tuexen@fh-muenster.de>]
        +
        +  *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't
        +     be used on C++.
        +     [Steve Henson]
        +
        +  *) Add "missing" function EVP_MD_flags() (without this the only way to
        +     retrieve a digest flags is by accessing the structure directly. Update
        +     EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest
        +     or cipher is registered as in the "from" argument. Print out all
        +     registered digests in the dgst usage message instead of manually 
        +     attempting to work them out.
        +     [Steve Henson]
        +
        +  *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello:
        +     this allows the use of compression and extensions. Change default cipher
        +     string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2
        +     by default unless an application cipher string requests it.
        +     [Steve Henson]
        +
        +  *) Alter match criteria in PKCS12_parse(). It used to try to use local
        +     key ids to find matching certificates and keys but some PKCS#12 files
        +     don't follow the (somewhat unwritten) rules and this strategy fails.
        +     Now just gather all certificates together and the first private key
        +     then look for the first certificate that matches the key.
        +     [Steve Henson]
        +
        +  *) Support use of registered digest and cipher names for dgst and cipher
        +     commands instead of having to add each one as a special case. So now
        +     you can do:
        +
        +        openssl sha256 foo
        +
        +     as well as:
        +
        +        openssl dgst -sha256 foo
        +
        +     and this works for ENGINE based algorithms too.
        +
        +     [Steve Henson]
        +
        +  *) Update Gost ENGINE to support parameter files.
        +     [Victor B. Wagner <vitus@cryptocom.ru>]
        +
        +  *) Support GeneralizedTime in ca utility. 
        +     [Oliver Martin <oliver@volatilevoid.net>, Steve Henson]
        +
        +  *) Enhance the hash format used for certificate directory links. The new
        +     form uses the canonical encoding (meaning equivalent names will work
        +     even if they aren't identical) and uses SHA1 instead of MD5. This form
        +     is incompatible with the older format and as a result c_rehash should
        +     be used to rebuild symbolic links.
        +     [Steve Henson]
        +
        +  *) Make PKCS#8 the default write format for private keys, replacing the
        +     traditional format. This form is standardised, more secure and doesn't
        +     include an implicit MD5 dependency.
        +     [Steve Henson]
        +
        +  *) Add a $gcc_devteam_warn option to Configure. The idea is that any code
        +     committed to OpenSSL should pass this lot as a minimum.
        +     [Steve Henson]
        +
        +  *) Add session ticket override functionality for use by EAP-FAST.
        +     [Jouni Malinen <j@w1.fi>]
        +
        +  *) Modify HMAC functions to return a value. Since these can be implemented
        +     in an ENGINE errors can occur.
        +     [Steve Henson]
        +
        +  *) Type-checked OBJ_bsearch_ex.
        +     [Ben Laurie]
        +
        +  *) Type-checked OBJ_bsearch. Also some constification necessitated
        +     by type-checking.  Still to come: TXT_DB, bsearch(?),
        +     OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING,
        +     CONF_VALUE.
        +     [Ben Laurie]
        +
        +  *) New function OPENSSL_gmtime_adj() to add a specific number of days and
        +     seconds to a tm structure directly, instead of going through OS
        +     specific date routines. This avoids any issues with OS routines such
        +     as the year 2038 bug. New *_adj() functions for ASN1 time structures
        +     and X509_time_adj_ex() to cover the extended range. The existing
        +     X509_time_adj() is still usable and will no longer have any date issues.
        +     [Steve Henson]
        +
        +  *) Delta CRL support. New use deltas option which will attempt to locate
        +     and search any appropriate delta CRLs available.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Support for CRLs partitioned by reason code. Reorganise CRL processing
        +     code and add additional score elements. Validate alternate CRL paths
        +     as part of the CRL checking and indicate a new error "CRL path validation
        +     error" in this case. Applications wanting additional details can use
        +     the verify callback and check the new "parent" field. If this is not
        +     NULL CRL path validation is taking place. Existing applications wont
        +     see this because it requires extended CRL support which is off by
        +     default.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Support for freshest CRL extension.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Initial indirect CRL support. Currently only supported in the CRLs
        +     passed directly and not via lookup. Process certificate issuer
        +     CRL entry extension and lookup CRL entries by bother issuer name
        +     and serial number. Check and process CRL issuer entry in IDP extension.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Add support for distinct certificate and CRL paths. The CRL issuer
        +     certificate is validated separately in this case. Only enabled if
        +     an extended CRL support flag is set: this flag will enable additional
        +     CRL functionality in future.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Add support for policy mappings extension.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Fixes to pathlength constraint, self issued certificate handling,
        +     policy processing to align with RFC3280 and PKITS tests.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Support for name constraints certificate extension. DN, email, DNS
        +     and URI types are currently supported.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) To cater for systems that provide a pointer-based thread ID rather
        +     than numeric, deprecate the current numeric thread ID mechanism and
        +     replace it with a structure and associated callback type. This
        +     mechanism allows a numeric "hash" to be extracted from a thread ID in
        +     either case, and on platforms where pointers are larger than 'long',
        +     mixing is done to help ensure the numeric 'hash' is usable even if it
        +     can't be guaranteed unique. The default mechanism is to use "&errno"
        +     as a pointer-based thread ID to distinguish between threads.
        +
        +     Applications that want to provide their own thread IDs should now use
        +     CRYPTO_THREADID_set_callback() to register a callback that will call
        +     either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
        +
        +     Note that ERR_remove_state() is now deprecated, because it is tied
        +     to the assumption that thread IDs are numeric.  ERR_remove_state(0)
        +     to free the current thread's error state should be replaced by
        +     ERR_remove_thread_state(NULL).
        +
        +     (This new approach replaces the functions CRYPTO_set_idptr_callback(),
        +     CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
        +     OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
        +     application was previously providing a numeric thread callback that
        +     was inappropriate for distinguishing threads, then uniqueness might
        +     have been obtained with &errno that happened immediately in the
        +     intermediate development versions of OpenSSL; this is no longer the
        +     case, the numeric thread callback will now override the automatic use
        +     of &errno.)
        +     [Geoff Thorpe, with help from Bodo Moeller]
        +
        +  *) Initial support for different CRL issuing certificates. This covers a
        +     simple case where the self issued certificates in the chain exist and
        +     the real CRL issuer is higher in the existing chain.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Removed effectively defunct crypto/store from the build.
        +     [Ben Laurie]
        +
        +  *) Revamp of STACK to provide stronger type-checking. Still to come:
        +     TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE,
        +     ASN1_STRING, CONF_VALUE.
        +     [Ben Laurie]
        +
        +  *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer
        +     RAM on SSL connections.  This option can save about 34k per idle SSL.
        +     [Nick Mathewson]
        +
        +  *) Revamp of LHASH to provide stronger type-checking. Still to come:
        +     STACK, TXT_DB, bsearch, qsort.
        +     [Ben Laurie]
        +
        +  *) Initial support for Cryptographic Message Syntax (aka CMS) based
        +     on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
        +     support for data, signedData, compressedData, digestedData and
        +     encryptedData, envelopedData types included. Scripts to check against
        +     RFC4134 examples draft and interop and consistency checks of many
        +     content types and variants.
        +     [Steve Henson]
        +
        +  *) Add options to enc utility to support use of zlib compression BIO.
        +     [Steve Henson]
        +
        +  *) Extend mk1mf to support importing of options and assembly language
        +     files from Configure script, currently only included in VC-WIN32.
        +     The assembly language rules can now optionally generate the source
        +     files from the associated perl scripts.
        +     [Steve Henson]
        +
        +  *) Implement remaining functionality needed to support GOST ciphersuites.
        +     Interop testing has been performed using CryptoPro implementations.
        +     [Victor B. Wagner <vitus@cryptocom.ru>]
        +
        +  *) s390x assembler pack.
        +     [Andy Polyakov]
        +
        +  *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU
        +     "family."
        +     [Andy Polyakov]
        +
        +  *) Implement Opaque PRF Input TLS extension as specified in
        +     draft-rescorla-tls-opaque-prf-input-00.txt.  Since this is not an
        +     official specification yet and no extension type assignment by
        +     IANA exists, this extension (for now) will have to be explicitly
        +     enabled when building OpenSSL by providing the extension number
        +     to use.  For example, specify an option
        +
        +         -DTLSEXT_TYPE_opaque_prf_input=0x9527
        +
        +     to the "config" or "Configure" script to enable the extension,
        +     assuming extension number 0x9527 (which is a completely arbitrary
        +     and unofficial assignment based on the MD5 hash of the Internet
        +     Draft).  Note that by doing so, you potentially lose
        +     interoperability with other TLS implementations since these might
        +     be using the same extension number for other purposes.
        +
        +     SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the
        +     opaque PRF input value to use in the handshake.  This will create
        +     an interal copy of the length-'len' string at 'src', and will
        +     return non-zero for success.
        +
        +     To get more control and flexibility, provide a callback function
        +     by using
        +
        +          SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb)
        +          SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg)
        +
        +     where
        +
        +          int (*cb)(SSL *, void *peerinput, size_t len, void *arg);
        +          void *arg;
        +
        +     Callback function 'cb' will be called in handshakes, and is
        +     expected to use SSL_set_tlsext_opaque_prf_input() as appropriate.
        +     Argument 'arg' is for application purposes (the value as given to
        +     SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly
        +     be provided to the callback function).  The callback function
        +     has to return non-zero to report success: usually 1 to use opaque
        +     PRF input just if possible, or 2 to enforce use of the opaque PRF
        +     input.  In the latter case, the library will abort the handshake
        +     if opaque PRF input is not successfully negotiated.
        +
        +     Arguments 'peerinput' and 'len' given to the callback function
        +     will always be NULL and 0 in the case of a client.  A server will
        +     see the client's opaque PRF input through these variables if
        +     available (NULL and 0 otherwise).  Note that if the server
        +     provides an opaque PRF input, the length must be the same as the
        +     length of the client's opaque PRF input.
        +
        +     Note that the callback function will only be called when creating
        +     a new session (session resumption can resume whatever was
        +     previously negotiated), and will not be called in SSL 2.0
        +     handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or
        +     SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended
        +     for applications that need to enforce opaque PRF input.
        +
        +     [Bodo Moeller]
        +
        +  *) Update ssl code to support digests other than SHA1+MD5 for handshake
        +     MAC. 
        +
        +     [Victor B. Wagner <vitus@cryptocom.ru>]
        +
        +  *) Add RFC4507 support to OpenSSL. This includes the corrections in
        +     RFC4507bis. The encrypted ticket format is an encrypted encoded
        +     SSL_SESSION structure, that way new session features are automatically
        +     supported.
        +
        +     If a client application caches session in an SSL_SESSION structure
        +     support is transparent because tickets are now stored in the encoded
        +     SSL_SESSION.
        +     
        +     The SSL_CTX structure automatically generates keys for ticket
        +     protection in servers so again support should be possible
        +     with no application modification.
        +
        +     If a client or server wishes to disable RFC4507 support then the option
        +     SSL_OP_NO_TICKET can be set.
        +
        +     Add a TLS extension debugging callback to allow the contents of any client
        +     or server extensions to be examined.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Final changes to avoid use of pointer pointer casts in OpenSSL.
        +     OpenSSL should now compile cleanly on gcc 4.2
        +     [Peter Hartley <pdh@utter.chaos.org.uk>, Steve Henson]
        +
        +  *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC
        +     support including streaming MAC support: this is required for GOST
        +     ciphersuite support.
        +     [Victor B. Wagner <vitus@cryptocom.ru>, Steve Henson]
        +
        +  *) Add option -stream to use PKCS#7 streaming in smime utility. New
        +     function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream()
        +     to output in BER and PEM format.
        +     [Steve Henson]
        +
        +  *) Experimental support for use of HMAC via EVP_PKEY interface. This
        +     allows HMAC to be handled via the EVP_DigestSign*() interface. The
        +     EVP_PKEY "key" in this case is the HMAC key, potentially allowing
        +     ENGINE support for HMAC keys which are unextractable. New -mac and
        +     -macopt options to dgst utility.
        +     [Steve Henson]
        +
        +  *) New option -sigopt to dgst utility. Update dgst to use
        +     EVP_Digest{Sign,Verify}*. These two changes make it possible to use
        +     alternative signing paramaters such as X9.31 or PSS in the dgst 
        +     utility.
        +     [Steve Henson]
        +
        +  *) Change ssl_cipher_apply_rule(), the internal function that does
        +     the work each time a ciphersuite string requests enabling
        +     ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or
        +     removing ("!foo+bar") a class of ciphersuites: Now it maintains
        +     the order of disabled ciphersuites such that those ciphersuites
        +     that most recently went from enabled to disabled not only stay
        +     in order with respect to each other, but also have higher priority
        +     than other disabled ciphersuites the next time ciphersuites are
        +     enabled again.
        +
        +     This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable
        +     the same ciphersuites as with "HIGH" alone, but in a specific
        +     order where the PSK ciphersuites come first (since they are the
        +     most recently disabled ciphersuites when "HIGH" is parsed).
        +
        +     Also, change ssl_create_cipher_list() (using this new
        +     funcionality) such that between otherwise identical
        +     cihpersuites, ephemeral ECDH is preferred over ephemeral DH in
        +     the default order.
        +     [Bodo Moeller]
        +
        +  *) Change ssl_create_cipher_list() so that it automatically
        +     arranges the ciphersuites in reasonable order before starting
        +     to process the rule string.  Thus, the definition for "DEFAULT"
        +     (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but
        +     remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH".
        +     This makes it much easier to arrive at a reasonable default order
        +     in applications for which anonymous ciphers are OK (meaning
        +     that you can't actually use DEFAULT).
        +     [Bodo Moeller; suggested by Victor Duchovni]
        +
        +  *) Split the SSL/TLS algorithm mask (as used for ciphersuite string
        +     processing) into multiple integers instead of setting
        +     "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK",
        +     "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer.
        +     (These masks as well as the individual bit definitions are hidden
        +     away into the non-exported interface ssl/ssl_locl.h, so this
        +     change to the definition of the SSL_CIPHER structure shouldn't
        +     affect applications.)  This give us more bits for each of these
        +     categories, so there is no longer a need to coagulate AES128 and
        +     AES256 into a single algorithm bit, and to coagulate Camellia128
        +     and Camellia256 into a single algorithm bit, which has led to all
        +     kinds of kludges.
        +
        +     Thus, among other things, the kludge introduced in 0.9.7m and
        +     0.9.8e for masking out AES256 independently of AES128 or masking
        +     out Camellia256 independently of AES256 is not needed here in 0.9.9.
        +
        +     With the change, we also introduce new ciphersuite aliases that
        +     so far were missing: "AES128", "AES256", "CAMELLIA128", and
        +     "CAMELLIA256".
        +     [Bodo Moeller]
        +
        +  *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
        +     Use the leftmost N bytes of the signature input if the input is
        +     larger than the prime q (with N being the size in bytes of q).
        +     [Nils Larsch]
        +
        +  *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses
        +     it yet and it is largely untested.
        +     [Steve Henson]
        +
        +  *) Add support for the ecdsa-with-SHA224/256/384/512 signature types.
        +     [Nils Larsch]
        +
        +  *) Initial incomplete changes to avoid need for function casts in OpenSSL
        +     some compilers (gcc 4.2 and later) reject their use. Safestack is
        +     reimplemented.  Update ASN1 to avoid use of legacy functions. 
        +     [Steve Henson]
        +
        +  *) Win32/64 targets are linked with Winsock2.
        +     [Andy Polyakov]
        +
        +  *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected
        +     to external functions. This can be used to increase CRL handling 
        +     efficiency especially when CRLs are very large by (for example) storing
        +     the CRL revoked certificates in a database.
        +     [Steve Henson]
        +
        +  *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so
        +     new CRLs added to a directory can be used. New command line option
        +     -verify_return_error to s_client and s_server. This causes real errors
        +     to be returned by the verify callback instead of carrying on no matter
        +     what. This reflects the way a "real world" verify callback would behave.
        +     [Steve Henson]
        +
        +  *) GOST engine, supporting several GOST algorithms and public key formats.
        +     Kindly donated by Cryptocom.
        +     [Cryptocom]
        +
        +  *) Partial support for Issuing Distribution Point CRL extension. CRLs
        +     partitioned by DP are handled but no indirect CRL or reason partitioning
        +     (yet). Complete overhaul of CRL handling: now the most suitable CRL is
        +     selected via a scoring technique which handles IDP and AKID in CRLs.
        +     [Steve Henson]
        +
        +  *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which
        +     will ultimately be used for all verify operations: this will remove the
        +     X509_STORE dependency on certificate verification and allow alternative
        +     lookup methods.  X509_STORE based implementations of these two callbacks.
        +     [Steve Henson]
        +
        +  *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names.
        +     Modify get_crl() to find a valid (unexpired) CRL if possible.
        +     [Steve Henson]
        +
        +  *) New function X509_CRL_match() to check if two CRLs are identical. Normally
        +     this would be called X509_CRL_cmp() but that name is already used by
        +     a function that just compares CRL issuer names. Cache several CRL 
        +     extensions in X509_CRL structure and cache CRLDP in X509.
        +     [Steve Henson]
        +
        +  *) Store a "canonical" representation of X509_NAME structure (ASN1 Name)
        +     this maps equivalent X509_NAME structures into a consistent structure.
        +     Name comparison can then be performed rapidly using memcmp().
        +     [Steve Henson]
        +
        +  *) Non-blocking OCSP request processing. Add -timeout option to ocsp 
        +     utility.
        +     [Steve Henson]
        +
        +  *) Allow digests to supply their own micalg string for S/MIME type using
        +     the ctrl EVP_MD_CTRL_MICALG.
        +     [Steve Henson]
        +
        +  *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the
        +     EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN
        +     ctrl. It can then customise the structure before and/or after signing
        +     if necessary.
        +     [Steve Henson]
        +
        +  *) New function OBJ_add_sigid() to allow application defined signature OIDs
        +     to be added to OpenSSLs internal tables. New function OBJ_sigid_free()
        +     to free up any added signature OIDs.
        +     [Steve Henson]
        +
        +  *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(),
        +     EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal
        +     digest and cipher tables. New options added to openssl utility:
        +     list-message-digest-algorithms and list-cipher-algorithms.
        +     [Steve Henson]
        +
        +  *) Change the array representation of binary polynomials: the list
        +     of degrees of non-zero coefficients is now terminated with -1.
        +     Previously it was terminated with 0, which was also part of the
        +     value; thus, the array representation was not applicable to
        +     polynomials where t^0 has coefficient zero.  This change makes
        +     the array representation useful in a more general context.
        +     [Douglas Stebila]
        +
        +  *) Various modifications and fixes to SSL/TLS cipher string
        +     handling.  For ECC, the code now distinguishes between fixed ECDH
        +     with RSA certificates on the one hand and with ECDSA certificates
        +     on the other hand, since these are separate ciphersuites.  The
        +     unused code for Fortezza ciphersuites has been removed.
        +
        +     For consistency with EDH, ephemeral ECDH is now called "EECDH"
        +     (not "ECDHE").  For consistency with the code for DH
        +     certificates, use of ECDH certificates is now considered ECDH
        +     authentication, not RSA or ECDSA authentication (the latter is
        +     merely the CA's signing algorithm and not actively used in the
        +     protocol).
        +
        +     The temporary ciphersuite alias "ECCdraft" is no longer
        +     available, and ECC ciphersuites are no longer excluded from "ALL"
        +     and "DEFAULT".  The following aliases now exist for RFC 4492
        +     ciphersuites, most of these by analogy with the DH case:
        +
        +         kECDHr   - ECDH cert, signed with RSA
        +         kECDHe   - ECDH cert, signed with ECDSA
        +         kECDH    - ECDH cert (signed with either RSA or ECDSA)
        +         kEECDH   - ephemeral ECDH
        +         ECDH     - ECDH cert or ephemeral ECDH
        +
        +         aECDH    - ECDH cert
        +         aECDSA   - ECDSA cert
        +         ECDSA    - ECDSA cert
        +
        +         AECDH    - anonymous ECDH
        +         EECDH    - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH")
        +
        +     [Bodo Moeller]
        +
        +  *) Add additional S/MIME capabilities for AES and GOST ciphers if supported.
        +     Use correct micalg parameters depending on digest(s) in signed message.
        +     [Steve Henson]
        +
        +  *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process
        +     an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code.
        +     [Steve Henson]
        +
        +  *) Initial engine support for EVP_PKEY_METHOD. New functions to permit
        +     an engine to register a method. Add ENGINE lookups for methods and
        +     functional reference processing.
        +     [Steve Henson]
        +
        +  *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of
        +     EVP_{Sign,Verify}* which allow an application to customise the signature
        +     process.
        +     [Steve Henson]
        +
        +  *) New -resign option to smime utility. This adds one or more signers
        +     to an existing PKCS#7 signedData structure. Also -md option to use an
        +     alternative message digest algorithm for signing.
        +     [Steve Henson]
        +
        +  *) Tidy up PKCS#7 routines and add new functions to make it easier to
        +     create PKCS7 structures containing multiple signers. Update smime
        +     application to support multiple signers.
        +     [Steve Henson]
        +
        +  *) New -macalg option to pkcs12 utility to allow setting of an alternative
        +     digest MAC.
        +     [Steve Henson]
        +
        +  *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
        +     Reorganize PBE internals to lookup from a static table using NIDs,
        +     add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl:
        +     EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative
        +     PRF which will be automatically used with PBES2.
        +     [Steve Henson]
        +
        +  *) Replace the algorithm specific calls to generate keys in "req" with the
        +     new API.
        +     [Steve Henson]
        +
        +  *) Update PKCS#7 enveloped data routines to use new API. This is now
        +     supported by any public key method supporting the encrypt operation. A
        +     ctrl is added to allow the public key algorithm to examine or modify
        +     the PKCS#7 RecipientInfo structure if it needs to: for RSA this is
        +     a no op.
        +     [Steve Henson]
        +
        +  *) Add a ctrl to asn1 method to allow a public key algorithm to express
        +     a default digest type to use. In most cases this will be SHA1 but some
        +     algorithms (such as GOST) need to specify an alternative digest. The
        +     return value indicates how strong the prefernce is 1 means optional and
        +     2 is mandatory (that is it is the only supported type). Modify
        +     ASN1_item_sign() to accept a NULL digest argument to indicate it should
        +     use the default md. Update openssl utilities to use the default digest
        +     type for signing if it is not explicitly indicated.
        +     [Steve Henson]
        +
        +  *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New 
        +     EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
        +     signing method from the key type. This effectively removes the link
        +     between digests and public key types.
        +     [Steve Henson]
        +
        +  *) Add an OID cross reference table and utility functions. Its purpose is to
        +     translate between signature OIDs such as SHA1WithrsaEncryption and SHA1,
        +     rsaEncryption. This will allow some of the algorithm specific hackery
        +     needed to use the correct OID to be removed. 
        +     [Steve Henson]
        +
        +  *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO
        +     structures for PKCS7_sign(). They are now set up by the relevant public
        +     key ASN1 method.
        +     [Steve Henson]
        +
        +  *) Add provisional EC pkey method with support for ECDSA and ECDH.
        +     [Steve Henson]
        +
        +  *) Add support for key derivation (agreement) in the API, DH method and
        +     pkeyutl.
        +     [Steve Henson]
        +
        +  *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support
        +     public and private key formats. As a side effect these add additional 
        +     command line functionality not previously available: DSA signatures can be
        +     generated and verified using pkeyutl and DH key support and generation in
        +     pkey, genpkey.
        +     [Steve Henson]
        +
        +  *) BeOS support.
        +     [Oliver Tappe <zooey@hirschkaefer.de>]
        +
        +  *) New make target "install_html_docs" installs HTML renditions of the
        +     manual pages.
        +     [Oliver Tappe <zooey@hirschkaefer.de>]
        +
        +  *) New utility "genpkey" this is analagous to "genrsa" etc except it can
        +     generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to
        +     support key and parameter generation and add initial key generation
        +     functionality for RSA.
        +     [Steve Henson]
        +
        +  *) Add functions for main EVP_PKEY_method operations. The undocumented
        +     functions EVP_PKEY_{encrypt,decrypt} have been renamed to
        +     EVP_PKEY_{encrypt,decrypt}_old. 
        +     [Steve Henson]
        +
        +  *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public
        +     key API, doesn't do much yet.
        +     [Steve Henson]
        +
        +  *) New function EVP_PKEY_asn1_get0_info() to retrieve information about
        +     public key algorithms. New option to openssl utility:
        +     "list-public-key-algorithms" to print out info.
        +     [Steve Henson]
        +
        +  *) Implement the Supported Elliptic Curves Extension for
        +     ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
        +     [Douglas Stebila]
        +
        +  *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or
        +     EVP_CIPHER structures to avoid later problems in EVP_cleanup().
        +     [Steve Henson]
        +
        +  *) New utilities pkey and pkeyparam. These are similar to algorithm specific
        +     utilities such as rsa, dsa, dsaparam etc except they process any key
        +     type.
        +     [Steve Henson]
        +
        +  *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New 
        +     functions EVP_PKEY_print_public(), EVP_PKEY_print_private(),
        +     EVP_PKEY_print_param() to print public key data from an EVP_PKEY
        +     structure.
        +     [Steve Henson]
        +
        +  *) Initial support for pluggable public key ASN1.
        +     De-spaghettify the public key ASN1 handling. Move public and private
        +     key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate
        +     algorithm specific handling to a single module within the relevant
        +     algorithm directory. Add functions to allow (near) opaque processing
        +     of public and private key structures.
        +     [Steve Henson]
        +
        +  *) Implement the Supported Point Formats Extension for
        +     ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
        +     [Douglas Stebila]
        +
        +  *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members
        +     for the psk identity [hint] and the psk callback functions to the
        +     SSL_SESSION, SSL and SSL_CTX structure.
        +     
        +     New ciphersuites:
        +         PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA,
        +         PSK-AES256-CBC-SHA
        + 
        +     New functions:
        +         SSL_CTX_use_psk_identity_hint
        +         SSL_get_psk_identity_hint
        +         SSL_get_psk_identity
        +         SSL_use_psk_identity_hint
        +
        +     [Mika Kousa and Pasi Eronen of Nokia Corporation]
        +
        +  *) Add RFC 3161 compliant time stamp request creation, response generation
        +     and response verification functionality.
        +     [Zoltán Glózik <zglozik@opentsa.org>, The OpenTSA Project]
        +
        +  *) Add initial support for TLS extensions, specifically for the server_name
        +     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
        +     have new members for a host name.  The SSL data structure has an
        +     additional member SSL_CTX *initial_ctx so that new sessions can be
        +     stored in that context to allow for session resumption, even after the
        +     SSL has been switched to a new SSL_CTX in reaction to a client's
        +     server_name extension.
        +
        +     New functions (subject to change):
        +
        +         SSL_get_servername()
        +         SSL_get_servername_type()
        +         SSL_set_SSL_CTX()
        +
        +     New CTRL codes and macros (subject to change):
        +
        +         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
        +                                 - SSL_CTX_set_tlsext_servername_callback()
        +         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
        +                                      - SSL_CTX_set_tlsext_servername_arg()
        +         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
        +
        +     openssl s_client has a new '-servername ...' option.
        +
        +     openssl s_server has new options '-servername_host ...', '-cert2 ...',
        +     '-key2 ...', '-servername_fatal' (subject to change).  This allows
        +     testing the HostName extension for a specific single host name ('-cert'
        +     and '-key' remain fallbacks for handshakes without HostName
        +     negotiation).  If the unrecogninzed_name alert has to be sent, this by
        +     default is a warning; it becomes fatal with the '-servername_fatal'
        +     option.
        +
        +     [Peter Sylvester,  Remy Allais, Christophe Renou]
        +
        +  *) Whirlpool hash implementation is added.
        +     [Andy Polyakov]
        +
        +  *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to
        +     bn(64,32). Because of instruction set limitations it doesn't have
        +     any negative impact on performance. This was done mostly in order
        +     to make it possible to share assembler modules, such as bn_mul_mont
        +     implementations, between 32- and 64-bit builds without hassle.
        +     [Andy Polyakov]
        +
        +  *) Move code previously exiled into file crypto/ec/ec2_smpt.c
        +     to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP
        +     macro.
        +     [Bodo Moeller]
        +
        +  *) New candidate for BIGNUM assembler implementation, bn_mul_mont,
        +     dedicated Montgomery multiplication procedure, is introduced.
        +     BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher
        +     "64-bit" performance on certain 32-bit targets.
        +     [Andy Polyakov]
        +
        +  *) New option SSL_OP_NO_COMP to disable use of compression selectively
        +     in SSL structures. New SSL ctrl to set maximum send fragment size. 
        +     Save memory by seeting the I/O buffer sizes dynamically instead of
        +     using the maximum available value.
        +     [Steve Henson]
        +
        +  *) New option -V for 'openssl ciphers'. This prints the ciphersuite code
        +     in addition to the text details.
        +     [Bodo Moeller]
        +
        +  *) Very, very preliminary EXPERIMENTAL support for printing of general
        +     ASN1 structures. This currently produces rather ugly output and doesn't
        +     handle several customised structures at all.
        +     [Steve Henson]
        +
        +  *) Integrated support for PVK file format and some related formats such
        +     as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support
        +     these in the 'rsa' and 'dsa' utilities.
        +     [Steve Henson]
        +
        +  *) Support for PKCS#1 RSAPublicKey format on rsa utility command line.
        +     [Steve Henson]
        +
        +  *) Remove the ancient ASN1_METHOD code. This was only ever used in one
        +     place for the (very old) "NETSCAPE" format certificates which are now
        +     handled using new ASN1 code equivalents.
        +     [Steve Henson]
        +
        +  *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD
        +     pointer and make the SSL_METHOD parameter in SSL_CTX_new,
        +     SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'.
        +     [Nils Larsch]
        +
        +  *) Modify CRL distribution points extension code to print out previously
        +     unsupported fields. Enhance extension setting code to allow setting of
        +     all fields.
        +     [Steve Henson]
        +
        +  *) Add print and set support for Issuing Distribution Point CRL extension.
        +     [Steve Henson]
        +
        +  *) Change 'Configure' script to enable Camellia by default.
        +     [NTT]
        +
        + Changes between 0.9.8s and 0.9.8t [18 Jan 2012]
        +
        +  *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109.
        +     Thanks to Antonio Martin, Enterprise Secure Access Research and
        +     Development, Cisco Systems, Inc. for discovering this bug and
        +     preparing a fix. (CVE-2012-0050)
        +     [Antonio Martin]
        +  
        + Changes between 0.9.8r and 0.9.8s [4 Jan 2012]
        +
        +  *) Nadhem Alfardan and Kenny Paterson have discovered an extension
        +     of the Vaudenay padding oracle attack on CBC mode encryption
        +     which enables an efficient plaintext recovery attack against
        +     the OpenSSL implementation of DTLS. Their attack exploits timing
        +     differences arising during decryption processing. A research
        +     paper describing this attack can be found at:
        +                  http://www.isg.rhul.ac.uk/~kp/dtls.pdf
        +     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
        +     Security Group at Royal Holloway, University of London
        +     (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
        +     <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
        +     for preparing the fix. (CVE-2011-4108)
        +     [Robin Seggelmann, Michael Tuexen]
        +
        +  *) Stop policy check failure freeing same buffer twice. (CVE-2011-4109)
        +     [Ben Laurie, Kasper <ekasper@google.com>]
        +
        +  *) Clear bytes used for block padding of SSL 3.0 records.
        +     (CVE-2011-4576)
        +     [Adam Langley (Google)]
        +
        +  *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George
        +     Kadianakis <desnacked@gmail.com> for discovering this issue and
        +     Adam Langley for preparing the fix. (CVE-2011-4619)
        +     [Adam Langley (Google)]
        + 
        +  *) Prevent malformed RFC3779 data triggering an assertion failure.
        +     Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
        +     and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
        +     [Rob Austein <sra@hactrn.net>]
        +
        +  *) Fix ssl_ciph.c set-up race.
        +     [Adam Langley (Google)]
        +
        +  *) Fix spurious failures in ecdsatest.c.
        +     [Emilia Käsper (Google)]
        +
        +  *) Fix the BIO_f_buffer() implementation (which was mixing different
        +     interpretations of the '..._len' fields).
        +     [Adam Langley (Google)]
        +
        +  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
        +     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
        +     threads won't reuse the same blinding coefficients.
        +
        +     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
        +     lock to call BN_BLINDING_invert_ex, and avoids one use of
        +     BN_BLINDING_update for each BN_BLINDING structure (previously,
        +     the last update always remained unused).
        +     [Emilia Käsper (Google)]
        +
        +  *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
        +     for multi-threaded use of ECDH.
        +     [Adam Langley (Google)]
        +
        +  *) Fix x509_name_ex_d2i memory leak on bad inputs.
        +     [Bodo Moeller]
        +
        +  *) Add protection against ECDSA timing attacks as mentioned in the paper
        +     by Billy Bob Brumley and Nicola Tuveri, see:
        +
        +	http://eprint.iacr.org/2011/232.pdf
        +
        +     [Billy Bob Brumley and Nicola Tuveri]
        +
        + Changes between 0.9.8q and 0.9.8r [8 Feb 2011]
        +
        +  *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
        +     [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
        +
        +  *) Fix bug in string printing code: if *any* escaping is enabled we must
        +     escape the escape character (backslash) or the resulting string is
        +     ambiguous.
        +     [Steve Henson]
        +
        + Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
        +
        +  *) Disable code workaround for ancient and obsolete Netscape browsers
        +     and servers: an attacker can use it in a ciphersuite downgrade attack.
        +     Thanks to Martin Rex for discovering this bug. CVE-2010-4180
        +     [Steve Henson]
        +
        +  *) Fixed J-PAKE implementation error, originally discovered by
        +     Sebastien Martini, further info and confirmation from Stefan
        +     Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
        +     [Ben Laurie]
        +
        + Changes between 0.9.8o and 0.9.8p [16 Nov 2010]
        +
        +  *) Fix extension code to avoid race conditions which can result in a buffer
        +     overrun vulnerability: resumed sessions must not be modified as they can
        +     be shared by multiple threads. CVE-2010-3864
        +     [Steve Henson]
        +
        +  *) Fix for double free bug in ssl/s3_clnt.c CVE-2010-2939
        +     [Steve Henson]
        +
        +  *) Don't reencode certificate when calculating signature: cache and use
        +     the original encoding instead. This makes signature verification of
        +     some broken encodings work correctly.
        +     [Steve Henson]
        +
        +  *) ec2_GF2m_simple_mul bugfix: compute correct result if the output EC_POINT
        +     is also one of the inputs.
        +     [Emilia Käsper <emilia.kasper@esat.kuleuven.be> (Google)]
        +
        +  *) Don't repeatedly append PBE algorithms to table if they already exist.
        +     Sort table on each new add. This effectively makes the table read only
        +     after all algorithms are added and subsequent calls to PKCS12_pbe_add
        +     etc are non-op.
        +     [Steve Henson]
        +
        + Changes between 0.9.8n and 0.9.8o [01 Jun 2010]
        +
        +  [NB: OpenSSL 0.9.8o and later 0.9.8 patch levels were released after
        +  OpenSSL 1.0.0.]
        +
        +  *) Correct a typo in the CMS ASN1 module which can result in invalid memory
        +     access or freeing data twice (CVE-2010-0742)
        +     [Steve Henson, Ronald Moesbergen <intercommit@gmail.com>]
        +
        +  *) Add SHA2 algorithms to SSL_library_init(). SHA2 is becoming far more
        +     common in certificates and some applications which only call
        +     SSL_library_init and not OpenSSL_add_all_algorithms() will fail.
        +     [Steve Henson]
        +
        +  *) VMS fixes: 
        +     Reduce copying into .apps and .test in makevms.com
        +     Don't try to use blank CA certificate in CA.com
        +     Allow use of C files from original directories in maketests.com
        +     [Steven M. Schweda" <sms@antinode.info>]
        +
        + Changes between 0.9.8m and 0.9.8n [24 Mar 2010]
        +
        +  *) When rejecting SSL/TLS records due to an incorrect version number, never
        +     update s->server with a new major version number.  As of
        +     - OpenSSL 0.9.8m if 'short' is a 16-bit type,
        +     - OpenSSL 0.9.8f if 'short' is longer than 16 bits,
        +     the previous behavior could result in a read attempt at NULL when
        +     receiving specific incorrect SSL/TLS records once record payload
        +     protection is active.  (CVE-2010-0740)
        +     [Bodo Moeller, Adam Langley <agl@chromium.org>]
        +
        +  *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL 
        +     could be crashed if the relevant tables were not present (e.g. chrooted).
        +     [Tomas Hoger <thoger@redhat.com>]
        +
        + Changes between 0.9.8l and 0.9.8m [25 Feb 2010]
        +
        +  *) Always check bn_wexpend() return values for failure.  (CVE-2009-3245)
        +     [Martin Olsson, Neel Mehta]
        +
        +  *) Fix X509_STORE locking: Every 'objs' access requires a lock (to
        +     accommodate for stack sorting, always a write lock!).
        +     [Bodo Moeller]
        +
        +  *) On some versions of WIN32 Heap32Next is very slow. This can cause
        +     excessive delays in the RAND_poll(): over a minute. As a workaround
        +     include a time check in the inner Heap32Next loop too.
        +     [Steve Henson]
        +
        +  *) The code that handled flushing of data in SSL/TLS originally used the
        +     BIO_CTRL_INFO ctrl to see if any data was pending first. This caused
        +     the problem outlined in PR#1949. The fix suggested there however can
        +     trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions
        +     of Apache). So instead simplify the code to flush unconditionally.
        +     This should be fine since flushing with no data to flush is a no op.
        +     [Steve Henson]
        +
        +  *) Handle TLS versions 2.0 and later properly and correctly use the
        +     highest version of TLS/SSL supported. Although TLS >= 2.0 is some way
        +     off ancient servers have a habit of sticking around for a while...
        +     [Steve Henson]
        +
        +  *) Modify compression code so it frees up structures without using the
        +     ex_data callbacks. This works around a problem where some applications
        +     call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when
        +     restarting) then use compression (e.g. SSL with compression) later.
        +     This results in significant per-connection memory leaks and
        +     has caused some security issues including CVE-2008-1678 and
        +     CVE-2009-4355.
        +     [Steve Henson]
        +
        +  *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
        +     change when encrypting or decrypting.
        +     [Bodo Moeller]
        +
        +  *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
        +     connect and renegotiate with servers which do not support RI.
        +     Until RI is more widely deployed this option is enabled by default.
        +     [Steve Henson]
        +
        +  *) Add "missing" ssl ctrls to clear options and mode.
        +     [Steve Henson]
        +
        +  *) If client attempts to renegotiate and doesn't support RI respond with
        +     a no_renegotiation alert as required by RFC5746.  Some renegotiating
        +     TLS clients will continue a connection gracefully when they receive
        +     the alert. Unfortunately OpenSSL mishandled this alert and would hang
        +     waiting for a server hello which it will never receive. Now we treat a
        +     received no_renegotiation alert as a fatal error. This is because
        +     applications requesting a renegotiation might well expect it to succeed
        +     and would have no code in place to handle the server denying it so the
        +     only safe thing to do is to terminate the connection.
        +     [Steve Henson]
        +
        +  *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if
        +     peer supports secure renegotiation and 0 otherwise. Print out peer
        +     renegotiation support in s_client/s_server.
        +     [Steve Henson]
        +
        +  *) Replace the highly broken and deprecated SPKAC certification method with
        +     the updated NID creation version. This should correctly handle UTF8.
        +     [Steve Henson]
        +
        +  *) Implement RFC5746. Re-enable renegotiation but require the extension
        +     as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
        +     turns out to be a bad idea. It has been replaced by
        +     SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
        +     SSL_CTX_set_options(). This is really not recommended unless you
        +     know what you are doing.
        +     [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
        +
        +  *) Fixes to stateless session resumption handling. Use initial_ctx when
        +     issuing and attempting to decrypt tickets in case it has changed during
        +     servername handling. Use a non-zero length session ID when attempting
        +     stateless session resumption: this makes it possible to determine if
        +     a resumption has occurred immediately after receiving server hello
        +     (several places in OpenSSL subtly assume this) instead of later in
        +     the handshake.
        +     [Steve Henson]
        +
        +  *) The functions ENGINE_ctrl(), OPENSSL_isservice(),
        +     CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error
        +     fixes for a few places where the return code is not checked
        +     correctly.
        +     [Julia Lawall <julia@diku.dk>]
        +
        +  *) Add --strict-warnings option to Configure script to include devteam
        +     warnings in other configurations.
        +     [Steve Henson]
        +
        +  *) Add support for --libdir option and LIBDIR variable in makefiles. This
        +     makes it possible to install openssl libraries in locations which
        +     have names other than "lib", for example "/usr/lib64" which some
        +     systems need.
        +     [Steve Henson, based on patch from Jeremy Utley]
        +
        +  *) Don't allow the use of leading 0x80 in OIDs. This is a violation of
        +     X690 8.9.12 and can produce some misleading textual output of OIDs.
        +     [Steve Henson, reported by Dan Kaminsky]
        +
        +  *) Delete MD2 from algorithm tables. This follows the recommendation in
        +     several standards that it is not used in new applications due to
        +     several cryptographic weaknesses. For binary compatibility reasons
        +     the MD2 API is still compiled in by default.
        +     [Steve Henson]
        +
        +  *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved
        +     and restored.
        +     [Steve Henson]
        +
        +  *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and
        +     OPENSSL_asc2uni conditionally on Netware platforms to avoid a name
        +     clash.
        +     [Guenter <lists@gknw.net>]
        +
        +  *) Fix the server certificate chain building code to use X509_verify_cert(),
        +     it used to have an ad-hoc builder which was unable to cope with anything
        +     other than a simple chain.
        +     [David Woodhouse <dwmw2@infradead.org>, Steve Henson]
        +
        +  *) Don't check self signed certificate signatures in X509_verify_cert()
        +     by default (a flag can override this): it just wastes time without
        +     adding any security. As a useful side effect self signed root CAs
        +     with non-FIPS digests are now usable in FIPS mode.
        +     [Steve Henson]
        +
        +  *) In dtls1_process_out_of_seq_message() the check if the current message
        +     is already buffered was missing. For every new message was memory
        +     allocated, allowing an attacker to perform an denial of service attack
        +     with sending out of seq handshake messages until there is no memory
        +     left. Additionally every future messege was buffered, even if the
        +     sequence number made no sense and would be part of another handshake.
        +     So only messages with sequence numbers less than 10 in advance will be
        +     buffered.  (CVE-2009-1378)
        +     [Robin Seggelmann, discovered by Daniel Mentz] 	
        +
        +  *) Records are buffered if they arrive with a future epoch to be
        +     processed after finishing the corresponding handshake. There is
        +     currently no limitation to this buffer allowing an attacker to perform
        +     a DOS attack with sending records with future epochs until there is no
        +     memory left. This patch adds the pqueue_size() function to detemine
        +     the size of a buffer and limits the record buffer to 100 entries.
        +     (CVE-2009-1377)
        +     [Robin Seggelmann, discovered by Daniel Mentz] 	
        +
        +  *) Keep a copy of frag->msg_header.frag_len so it can be used after the
        +     parent structure is freed.  (CVE-2009-1379)
        +     [Daniel Mentz] 	
        +
        +  *) Handle non-blocking I/O properly in SSL_shutdown() call.
        +     [Darryl Miles <darryl-mailinglists@netbauds.net>]
        +
        +  *) Add 2.5.4.* OIDs
        +     [Ilya O. <vrghost@gmail.com>]
        +
        + Changes between 0.9.8k and 0.9.8l  [5 Nov 2009]
        +
        +  *) Disable renegotiation completely - this fixes a severe security
        +     problem (CVE-2009-3555) at the cost of breaking all
        +     renegotiation. Renegotiation can be re-enabled by setting
        +     SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at
        +     run-time. This is really not recommended unless you know what
        +     you're doing.
        +     [Ben Laurie]
        +
        + Changes between 0.9.8j and 0.9.8k  [25 Mar 2009]
        +
        +  *) Don't set val to NULL when freeing up structures, it is freed up by
        +     underlying code. If sizeof(void *) > sizeof(long) this can result in
        +     zeroing past the valid field. (CVE-2009-0789)
        +     [Paolo Ganci <Paolo.Ganci@AdNovum.CH>]
        +
        +  *) Fix bug where return value of CMS_SignerInfo_verify_content() was not
        +     checked correctly. This would allow some invalid signed attributes to
        +     appear to verify correctly. (CVE-2009-0591)
        +     [Ivan Nestlerode <inestlerode@us.ibm.com>]
        +
        +  *) Reject UniversalString and BMPString types with invalid lengths. This
        +     prevents a crash in ASN1_STRING_print_ex() which assumes the strings have
        +     a legal length. (CVE-2009-0590)
        +     [Steve Henson]
        +
        +  *) Set S/MIME signing as the default purpose rather than setting it 
        +     unconditionally. This allows applications to override it at the store
        +     level.
        +     [Steve Henson]
        +
        +  *) Permit restricted recursion of ASN1 strings. This is needed in practice
        +     to handle some structures.
        +     [Steve Henson]
        +
        +  *) Improve efficiency of mem_gets: don't search whole buffer each time
        +     for a '\n'
        +     [Jeremy Shapiro <jnshapir@us.ibm.com>]
        +
        +  *) New -hex option for openssl rand.
        +     [Matthieu Herrb]
        +
        +  *) Print out UTF8String and NumericString when parsing ASN1.
        +     [Steve Henson]
        +
        +  *) Support NumericString type for name components.
        +     [Steve Henson]
        +
        +  *) Allow CC in the environment to override the automatically chosen
        +     compiler. Note that nothing is done to ensure flags work with the
        +     chosen compiler.
        +     [Ben Laurie]
        +
        + Changes between 0.9.8i and 0.9.8j  [07 Jan 2009]
        +
        +  *) Properly check EVP_VerifyFinal() and similar return values
        +     (CVE-2008-5077).
        +     [Ben Laurie, Bodo Moeller, Google Security Team]
        +
        +  *) Enable TLS extensions by default.
        +     [Ben Laurie]
        +
        +  *) Allow the CHIL engine to be loaded, whether the application is
        +     multithreaded or not. (This does not release the developer from the
        +     obligation to set up the dynamic locking callbacks.)
        +     [Sander Temme <sander@temme.net>]
        +
        +  *) Use correct exit code if there is an error in dgst command.
        +     [Steve Henson; problem pointed out by Roland Dirlewanger]
        +
        +  *) Tweak Configure so that you need to say "experimental-jpake" to enable
        +     JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications.
        +     [Bodo Moeller]
        +
        +  *) Add experimental JPAKE support, including demo authentication in
        +     s_client and s_server.
        +     [Ben Laurie]
        +
        +  *) Set the comparison function in v3_addr_canonize().
        +     [Rob Austein <sra@hactrn.net>]
        +
        +  *) Add support for XMPP STARTTLS in s_client.
        +     [Philip Paeps <philip@freebsd.org>]
        +
        +  *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior
        +     to ensure that even with this option, only ciphersuites in the
        +     server's preference list will be accepted.  (Note that the option
        +     applies only when resuming a session, so the earlier behavior was
        +     just about the algorithm choice for symmetric cryptography.)
        +     [Bodo Moeller]
        +
        + Changes between 0.9.8h and 0.9.8i  [15 Sep 2008]
        +
        +  *) Fix NULL pointer dereference if a DTLS server received
        +     ChangeCipherSpec as first record (CVE-2009-1386).
        +     [PR #1679]
        +
        +  *) Fix a state transitition in s3_srvr.c and d1_srvr.c
        +     (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...).
        +     [Nagendra Modadugu]
        +
        +  *) The fix in 0.9.8c that supposedly got rid of unsafe
        +     double-checked locking was incomplete for RSA blinding,
        +     addressing just one layer of what turns out to have been
        +     doubly unsafe triple-checked locking.
        +
        +     So now fix this for real by retiring the MONT_HELPER macro
        +     in crypto/rsa/rsa_eay.c.
        +
        +     [Bodo Moeller; problem pointed out by Marius Schilder]
        +
        +  *) Various precautionary measures:
        +
        +     - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h).
        +
        +     - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c).
        +       (NB: This would require knowledge of the secret session ticket key
        +       to exploit, in which case you'd be SOL either way.)
        +
        +     - Change bn_nist.c so that it will properly handle input BIGNUMs
        +       outside the expected range.
        +
        +     - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG
        +       builds.
        +
        +     [Neel Mehta, Bodo Moeller]
        +
        +  *) Allow engines to be "soft loaded" - i.e. optionally don't die if
        +     the load fails. Useful for distros.
        +     [Ben Laurie and the FreeBSD team]
        +
        +  *) Add support for Local Machine Keyset attribute in PKCS#12 files.
        +     [Steve Henson]
        +
        +  *) Fix BN_GF2m_mod_arr() top-bit cleanup code.
        +     [Huang Ying]
        +
        +  *) Expand ENGINE to support engine supplied SSL client certificate functions.
        +
        +     This work was sponsored by Logica.
        +     [Steve Henson]
        +
        +  *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows
        +     keystores. Support for SSL/TLS client authentication too.
        +     Not compiled unless enable-capieng specified to Configure.
        +
        +     This work was sponsored by Logica.
        +     [Steve Henson]
        +
        +  *) Fix bug in X509_ATTRIBUTE creation: dont set attribute using
        +     ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain
        +     attribute creation routines such as certifcate requests and PKCS#12
        +     files.
        +     [Steve Henson]
        +
        + Changes between 0.9.8g and 0.9.8h  [28 May 2008]
        +
        +  *) Fix flaw if 'Server Key exchange message' is omitted from a TLS
        +     handshake which could lead to a cilent crash as found using the
        +     Codenomicon TLS test suite (CVE-2008-1672) 
        +     [Steve Henson, Mark Cox]
        +
        +  *) Fix double free in TLS server name extensions which could lead to
        +     a remote crash found by Codenomicon TLS test suite (CVE-2008-0891) 
        +     [Joe Orton]
        +
        +  *) Clear error queue in SSL_CTX_use_certificate_chain_file()
        +
        +     Clear the error queue to ensure that error entries left from
        +     older function calls do not interfere with the correct operation.
        +     [Lutz Jaenicke, Erik de Castro Lopo]
        +
        +  *) Remove root CA certificates of commercial CAs:
        +
        +     The OpenSSL project does not recommend any specific CA and does not
        +     have any policy with respect to including or excluding any CA.
        +     Therefore it does not make any sense to ship an arbitrary selection
        +     of root CA certificates with the OpenSSL software.
        +     [Lutz Jaenicke]
        +
        +  *) RSA OAEP patches to fix two separate invalid memory reads.
        +     The first one involves inputs when 'lzero' is greater than
        +     'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes
        +     before the beginning of from). The second one involves inputs where
        +     the 'db' section contains nothing but zeroes (there is a one-byte
        +     invalid read after the end of 'db').
        +     [Ivan Nestlerode <inestlerode@us.ibm.com>]
        +
        +  *) Partial backport from 0.9.9-dev:
        +
        +     Introduce bn_mul_mont (dedicated Montgomery multiplication
        +     procedure) as a candidate for BIGNUM assembler implementation.
        +     While 0.9.9-dev uses assembler for various architectures, only
        +     x86_64 is available by default here in the 0.9.8 branch, and
        +     32-bit x86 is available through a compile-time setting.
        +
        +     To try the 32-bit x86 assembler implementation, use Configure
        +     option "enable-montasm" (which exists only for this backport).
        +
        +     As "enable-montasm" for 32-bit x86 disclaims code stability
        +     anyway, in this constellation we activate additional code
        +     backported from 0.9.9-dev for further performance improvements,
        +     namely BN_from_montgomery_word.  (To enable this otherwise,
        +     e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".)
        +
        +     [Andy Polyakov (backport partially by Bodo Moeller)]
        +
        +  *) Add TLS session ticket callback. This allows an application to set
        +     TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
        +     values. This is useful for key rollover for example where several key
        +     sets may exist with different names.
        +     [Steve Henson]
        +
        +  *) Reverse ENGINE-internal logic for caching default ENGINE handles.
        +     This was broken until now in 0.9.8 releases, such that the only way
        +     a registered ENGINE could be used (assuming it initialises
        +     successfully on the host) was to explicitly set it as the default
        +     for the relevant algorithms. This is in contradiction with 0.9.7
        +     behaviour and the documentation. With this fix, when an ENGINE is
        +     registered into a given algorithm's table of implementations, the
        +     'uptodate' flag is reset so that auto-discovery will be used next
        +     time a new context for that algorithm attempts to select an
        +     implementation.
        +     [Ian Lister (tweaked by Geoff Thorpe)]
        +
        +  *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9
        +     implemention in the following ways:
        +
        +     Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be
        +     hard coded.
        +
        +     Lack of BER streaming support means one pass streaming processing is
        +     only supported if data is detached: setting the streaming flag is
        +     ignored for embedded content.
        +
        +     CMS support is disabled by default and must be explicitly enabled
        +     with the enable-cms configuration option.
        +     [Steve Henson]
        +
        +  *) Update the GMP engine glue to do direct copies between BIGNUM and
        +     mpz_t when openssl and GMP use the same limb size. Otherwise the
        +     existing "conversion via a text string export" trick is still used.
        +     [Paul Sheer <paulsheer@gmail.com>]
        +
        +  *) Zlib compression BIO. This is a filter BIO which compressed and
        +     uncompresses any data passed through it.
        +     [Steve Henson]
        +
        +  *) Add AES_wrap_key() and AES_unwrap_key() functions to implement
        +     RFC3394 compatible AES key wrapping.
        +     [Steve Henson]
        +
        +  *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0():
        +     sets string data without copying. X509_ALGOR_set0() and
        +     X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier)
        +     data. Attribute function X509at_get0_data_by_OBJ(): retrieves data
        +     from an X509_ATTRIBUTE structure optionally checking it occurs only
        +     once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied
        +     data.
        +     [Steve Henson]
        +
        +  *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set()
        +     to get the expected BN_FLG_CONSTTIME behavior.
        +     [Bodo Moeller (Google)]
        +  
        +  *) Netware support:
        +
        +     - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets
        +     - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT)
        +     - added some more tests to do_tests.pl
        +     - fixed RunningProcess usage so that it works with newer LIBC NDKs too
        +     - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency
        +     - added new Configure targets netware-clib-bsdsock, netware-clib-gcc,
        +       netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc
        +     - various changes to netware.pl to enable gcc-cross builds on Win32
        +       platform
        +     - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD)
        +     - various changes to fix missing prototype warnings
        +     - fixed x86nasm.pl to create correct asm files for NASM COFF output
        +     - added AES, WHIRLPOOL and CPUID assembler code to build files
        +     - added missing AES assembler make rules to mk1mf.pl
        +     - fixed order of includes in apps/ocsp.c so that e_os.h settings apply
        +     [Guenter Knauf <eflash@gmx.net>]
        +
        +  *) Implement certificate status request TLS extension defined in RFC3546.
        +     A client can set the appropriate parameters and receive the encoded
        +     OCSP response via a callback. A server can query the supplied parameters
        +     and set the encoded OCSP response in the callback. Add simplified examples
        +     to s_client and s_server.
        +     [Steve Henson]
        +
        + Changes between 0.9.8f and 0.9.8g  [19 Oct 2007]
        +
        +  *) Fix various bugs:
        +     + Binary incompatibility of ssl_ctx_st structure
        +     + DTLS interoperation with non-compliant servers
        +     + Don't call get_session_cb() without proposed session
        +     + Fix ia64 assembler code
        +     [Andy Polyakov, Steve Henson]
        +
        + Changes between 0.9.8e and 0.9.8f  [11 Oct 2007]
        +
        +  *) DTLS Handshake overhaul. There were longstanding issues with
        +     OpenSSL DTLS implementation, which were making it impossible for
        +     RFC 4347 compliant client to communicate with OpenSSL server.
        +     Unfortunately just fixing these incompatibilities would "cut off"
        +     pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e
        +     server keeps tolerating non RFC compliant syntax. The opposite is
        +     not true, 0.9.8f client can not communicate with earlier server.
        +     This update even addresses CVE-2007-4995.
        +     [Andy Polyakov]
        +
        +  *) Changes to avoid need for function casts in OpenSSL: some compilers
        +     (gcc 4.2 and later) reject their use.
        +     [Kurt Roeckx <kurt@roeckx.be>, Peter Hartley <pdh@utter.chaos.org.uk>,
        +      Steve Henson]
        +  
        +  *) Add RFC4507 support to OpenSSL. This includes the corrections in
        +     RFC4507bis. The encrypted ticket format is an encrypted encoded
        +     SSL_SESSION structure, that way new session features are automatically
        +     supported.
        +
        +     If a client application caches session in an SSL_SESSION structure
        +     support is transparent because tickets are now stored in the encoded
        +     SSL_SESSION.
        +     
        +     The SSL_CTX structure automatically generates keys for ticket
        +     protection in servers so again support should be possible
        +     with no application modification.
        +
        +     If a client or server wishes to disable RFC4507 support then the option
        +     SSL_OP_NO_TICKET can be set.
        +
        +     Add a TLS extension debugging callback to allow the contents of any client
        +     or server extensions to be examined.
        +
        +     This work was sponsored by Google.
        +     [Steve Henson]
        +
        +  *) Add initial support for TLS extensions, specifically for the server_name
        +     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
        +     have new members for a host name.  The SSL data structure has an
        +     additional member SSL_CTX *initial_ctx so that new sessions can be
        +     stored in that context to allow for session resumption, even after the
        +     SSL has been switched to a new SSL_CTX in reaction to a client's
        +     server_name extension.
        +
        +     New functions (subject to change):
        +
        +         SSL_get_servername()
        +         SSL_get_servername_type()
        +         SSL_set_SSL_CTX()
        +
        +     New CTRL codes and macros (subject to change):
        +
        +         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
        +                                 - SSL_CTX_set_tlsext_servername_callback()
        +         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
        +                                      - SSL_CTX_set_tlsext_servername_arg()
        +         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
        +
        +     openssl s_client has a new '-servername ...' option.
        +
        +     openssl s_server has new options '-servername_host ...', '-cert2 ...',
        +     '-key2 ...', '-servername_fatal' (subject to change).  This allows
        +     testing the HostName extension for a specific single host name ('-cert'
        +     and '-key' remain fallbacks for handshakes without HostName
        +     negotiation).  If the unrecogninzed_name alert has to be sent, this by
        +     default is a warning; it becomes fatal with the '-servername_fatal'
        +     option.
        +
        +     [Peter Sylvester,  Remy Allais, Christophe Renou, Steve Henson]
        +
        +  *) Add AES and SSE2 assembly language support to VC++ build.
        +     [Steve Henson]
        +
        +  *) Mitigate attack on final subtraction in Montgomery reduction.
        +     [Andy Polyakov]
        +
        +  *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0
        +     (which previously caused an internal error).
        +     [Bodo Moeller]
        +
        +  *) Squeeze another 10% out of IGE mode when in != out.
        +     [Ben Laurie]
        +
        +  *) AES IGE mode speedup.
        +     [Dean Gaudet (Google)]
        +
        +  *) Add the Korean symmetric 128-bit cipher SEED (see
        +     http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and
        +     add SEED ciphersuites from RFC 4162:
        +
        +        TLS_RSA_WITH_SEED_CBC_SHA      =  "SEED-SHA"
        +        TLS_DHE_DSS_WITH_SEED_CBC_SHA  =  "DHE-DSS-SEED-SHA"
        +        TLS_DHE_RSA_WITH_SEED_CBC_SHA  =  "DHE-RSA-SEED-SHA"
        +        TLS_DH_anon_WITH_SEED_CBC_SHA  =  "ADH-SEED-SHA"
        +
        +     To minimize changes between patchlevels in the OpenSSL 0.9.8
        +     series, SEED remains excluded from compilation unless OpenSSL
        +     is configured with 'enable-seed'.
        +     [KISA, Bodo Moeller]
        +
        +  *) Mitigate branch prediction attacks, which can be practical if a
        +     single processor is shared, allowing a spy process to extract
        +     information.  For detailed background information, see
        +     http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
        +     J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
        +     and Necessary Software Countermeasures").  The core of the change
        +     are new versions BN_div_no_branch() and
        +     BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
        +     respectively, which are slower, but avoid the security-relevant
        +     conditional branches.  These are automatically called by BN_div()
        +     and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one
        +     of the input BIGNUMs.  Also, BN_is_bit_set() has been changed to
        +     remove a conditional branch.
        +
        +     BN_FLG_CONSTTIME is the new name for the previous
        +     BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
        +     modular exponentiation.  (Since OpenSSL 0.9.7h, setting this flag
        +     in the exponent causes BN_mod_exp_mont() to use the alternative
        +     implementation in BN_mod_exp_mont_consttime().)  The old name
        +     remains as a deprecated alias.
        +
        +     Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
        +     RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
        +     constant-time implementations for more than just exponentiation.
        +     Here too the old name is kept as a deprecated alias.
        +
        +     BN_BLINDING_new() will now use BN_dup() for the modulus so that
        +     the BN_BLINDING structure gets an independent copy of the
        +     modulus.  This means that the previous "BIGNUM *m" argument to
        +     BN_BLINDING_new() and to BN_BLINDING_create_param() now
        +     essentially becomes "const BIGNUM *m", although we can't actually
        +     change this in the header file before 0.9.9.  It allows
        +     RSA_setup_blinding() to use BN_with_flags() on the modulus to
        +     enable BN_FLG_CONSTTIME.
        +
        +     [Matthew D Wood (Intel Corp)]
        +
        +  *) In the SSL/TLS server implementation, be strict about session ID
        +     context matching (which matters if an application uses a single
        +     external cache for different purposes).  Previously,
        +     out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
        +     set.  This did ensure strict client verification, but meant that,
        +     with applications using a single external cache for quite
        +     different requirements, clients could circumvent ciphersuite
        +     restrictions for a given session ID context by starting a session
        +     in a different context.
        +     [Bodo Moeller]
        +
        +  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
        +     a ciphersuite string such as "DEFAULT:RSA" cannot enable
        +     authentication-only ciphersuites.
        +     [Bodo Moeller]
        +
        +  *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was
        +     not complete and could lead to a possible single byte overflow
        +     (CVE-2007-5135) [Ben Laurie]
        +
        + Changes between 0.9.8d and 0.9.8e  [23 Feb 2007]
        +
        +  *) Since AES128 and AES256 (and similarly Camellia128 and
        +     Camellia256) share a single mask bit in the logic of
        +     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
        +     kludge to work properly if AES128 is available and AES256 isn't
        +     (or if Camellia128 is available and Camellia256 isn't).
        +     [Victor Duchovni]
        +
        +  *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
        +     (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
        +     When a point or a seed is encoded in a BIT STRING, we need to
        +     prevent the removal of trailing zero bits to get the proper DER
        +     encoding.  (By default, crypto/asn1/a_bitstr.c assumes the case
        +     of a NamedBitList, for which trailing 0 bits need to be removed.)
        +     [Bodo Moeller]
        +
        +  *) Have SSL/TLS server implementation tolerate "mismatched" record
        +     protocol version while receiving ClientHello even if the
        +     ClientHello is fragmented.  (The server can't insist on the
        +     particular protocol version it has chosen before the ServerHello
        +     message has informed the client about his choice.)
        +     [Bodo Moeller]
        +
        +  *) Add RFC 3779 support.
        +     [Rob Austein for ARIN, Ben Laurie]
        +
        +  *) Load error codes if they are not already present instead of using a
        +     static variable. This allows them to be cleanly unloaded and reloaded.
        +     Improve header file function name parsing.
        +     [Steve Henson]
        +
        +  *) extend SMTP and IMAP protocol emulation in s_client to use EHLO
        +     or CAPABILITY handshake as required by RFCs.
        +     [Goetz Babin-Ebell]
        +
        + Changes between 0.9.8c and 0.9.8d  [28 Sep 2006]
        +
        +  *) Introduce limits to prevent malicious keys being able to
        +     cause a denial of service.  (CVE-2006-2940)
        +     [Steve Henson, Bodo Moeller]
        +
        +  *) Fix ASN.1 parsing of certain invalid structures that can result
        +     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
        +
        +  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
        +     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
        +
        +  *) Fix SSL client code which could crash if connecting to a
        +     malicious SSLv2 server.  (CVE-2006-4343)
        +     [Tavis Ormandy and Will Drewry, Google Security Team]
        +
        +  *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites
        +     match only those.  Before that, "AES256-SHA" would be interpreted
        +     as a pattern and match "AES128-SHA" too (since AES128-SHA got
        +     the same strength classification in 0.9.7h) as we currently only
        +     have a single AES bit in the ciphersuite description bitmap.
        +     That change, however, also applied to ciphersuite strings such as
        +     "RC4-MD5" that intentionally matched multiple ciphersuites --
        +     namely, SSL 2.0 ciphersuites in addition to the more common ones
        +     from SSL 3.0/TLS 1.0.
        +
        +     So we change the selection algorithm again: Naming an explicit
        +     ciphersuite selects this one ciphersuite, and any other similar
        +     ciphersuite (same bitmap) from *other* protocol versions.
        +     Thus, "RC4-MD5" again will properly select both the SSL 2.0
        +     ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite.
        +
        +     Since SSL 2.0 does not have any ciphersuites for which the
        +     128/256 bit distinction would be relevant, this works for now.
        +     The proper fix will be to use different bits for AES128 and
        +     AES256, which would have avoided the problems from the beginning;
        +     however, bits are scarce, so we can only do this in a new release
        +     (not just a patchlevel) when we can change the SSL_CIPHER
        +     definition to split the single 'unsigned long mask' bitmap into
        +     multiple values to extend the available space.
        +
        +     [Bodo Moeller]
        +
        + Changes between 0.9.8b and 0.9.8c  [05 Sep 2006]
        +
        +  *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
        +     (CVE-2006-4339)  [Ben Laurie and Google Security Team]
        +
        +  *) Add AES IGE and biIGE modes.
        +     [Ben Laurie]
        +
        +  *) Change the Unix randomness entropy gathering to use poll() when
        +     possible instead of select(), since the latter has some
        +     undesirable limitations.
        +     [Darryl Miles via Richard Levitte and Bodo Moeller]
        +
        +  *) Disable "ECCdraft" ciphersuites more thoroughly.  Now special
        +     treatment in ssl/ssl_ciph.s makes sure that these ciphersuites
        +     cannot be implicitly activated as part of, e.g., the "AES" alias.
        +     However, please upgrade to OpenSSL 0.9.9[-dev] for
        +     non-experimental use of the ECC ciphersuites to get TLS extension
        +     support, which is required for curve and point format negotiation
        +     to avoid potential handshake problems.
        +     [Bodo Moeller]
        +
        +  *) Disable rogue ciphersuites:
        +
        +      - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
        +      - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
        +      - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
        +
        +     The latter two were purportedly from
        +     draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
        +     appear there.
        +
        +     Also deactivate the remaining ciphersuites from
        +     draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
        +     unofficial, and the ID has long expired.
        +     [Bodo Moeller]
        +
        +  *) Fix RSA blinding Heisenbug (problems sometimes occured on
        +     dual-core machines) and other potential thread-safety issues.
        +     [Bodo Moeller]
        +
        +  *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key
        +     versions), which is now available for royalty-free use
        +     (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html).
        +     Also, add Camellia TLS ciphersuites from RFC 4132.
        +
        +     To minimize changes between patchlevels in the OpenSSL 0.9.8
        +     series, Camellia remains excluded from compilation unless OpenSSL
        +     is configured with 'enable-camellia'.
        +     [NTT]
        +
        +  *) Disable the padding bug check when compression is in use. The padding
        +     bug check assumes the first packet is of even length, this is not
        +     necessarily true if compresssion is enabled and can result in false
        +     positives causing handshake failure. The actual bug test is ancient
        +     code so it is hoped that implementations will either have fixed it by
        +     now or any which still have the bug do not support compression.
        +     [Steve Henson]
        +
        + Changes between 0.9.8a and 0.9.8b  [04 May 2006]
        +
        +  *) When applying a cipher rule check to see if string match is an explicit
        +     cipher suite and only match that one cipher suite if it is.
        +     [Steve Henson]
        +
        +  *) Link in manifests for VC++ if needed.
        +     [Austin Ziegler <halostatue@gmail.com>]
        +
        +  *) Update support for ECC-based TLS ciphersuites according to
        +     draft-ietf-tls-ecc-12.txt with proposed changes (but without
        +     TLS extensions, which are supported starting with the 0.9.9
        +     branch, not in the OpenSSL 0.9.8 branch).
        +     [Douglas Stebila]
        +
        +  *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support
        +     opaque EVP_CIPHER_CTX handling.
        +     [Steve Henson]
        +
        +  *) Fixes and enhancements to zlib compression code. We now only use
        +     "zlib1.dll" and use the default __cdecl calling convention on Win32
        +     to conform with the standards mentioned here:
        +           http://www.zlib.net/DLL_FAQ.txt
        +     Static zlib linking now works on Windows and the new --with-zlib-include
        +     --with-zlib-lib options to Configure can be used to supply the location
        +     of the headers and library. Gracefully handle case where zlib library
        +     can't be loaded.
        +     [Steve Henson]
        +
        +  *) Several fixes and enhancements to the OID generation code. The old code
        +     sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
        +     handle numbers larger than ULONG_MAX, truncated printing and had a
        +     non standard OBJ_obj2txt() behaviour.
        +     [Steve Henson]
        +
        +  *) Add support for building of engines under engine/ as shared libraries
        +     under VC++ build system.
        +     [Steve Henson]
        +
        +  *) Corrected the numerous bugs in the Win32 path splitter in DSO.
        +     Hopefully, we will not see any false combination of paths any more.
        +     [Richard Levitte]
        +
        + Changes between 0.9.8 and 0.9.8a  [11 Oct 2005]
        +
        +  *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
        +     (part of SSL_OP_ALL).  This option used to disable the
        +     countermeasure against man-in-the-middle protocol-version
        +     rollback in the SSL 2.0 server implementation, which is a bad
        +     idea.  (CVE-2005-2969)
        +
        +     [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
        +     for Information Security, National Institute of Advanced Industrial
        +     Science and Technology [AIST], Japan)]
        +
        +  *) Add two function to clear and return the verify parameter flags.
        +     [Steve Henson]
        +
        +  *) Keep cipherlists sorted in the source instead of sorting them at
        +     runtime, thus removing the need for a lock.
        +     [Nils Larsch]
        +
        +  *) Avoid some small subgroup attacks in Diffie-Hellman.
        +     [Nick Mathewson and Ben Laurie]
        +
        +  *) Add functions for well-known primes.
        +     [Nick Mathewson]
        +
        +  *) Extended Windows CE support.
        +     [Satoshi Nakamura and Andy Polyakov]
        +
        +  *) Initialize SSL_METHOD structures at compile time instead of during
        +     runtime, thus removing the need for a lock.
        +     [Steve Henson]
        +
        +  *) Make PKCS7_decrypt() work even if no certificate is supplied by
        +     attempting to decrypt each encrypted key in turn. Add support to
        +     smime utility.
        +     [Steve Henson]
        +
        + Changes between 0.9.7h and 0.9.8  [05 Jul 2005]
        +
        +  [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after
        +  OpenSSL 0.9.8.]
        +
        +  *) Add libcrypto.pc and libssl.pc for those who feel they need them.
        +     [Richard Levitte]
        +
        +  *) Change CA.sh and CA.pl so they don't bundle the CSR and the private
        +     key into the same file any more.
        +     [Richard Levitte]
        +
        +  *) Add initial support for Win64, both IA64 and AMD64/x64 flavors.
        +     [Andy Polyakov]
        +
        +  *) Add -utf8 command line and config file option to 'ca'.
        +     [Stefan <stf@udoma.org]
        +
        +  *) Removed the macro des_crypt(), as it seems to conflict with some
        +     libraries.  Use DES_crypt().
        +     [Richard Levitte]
        +
        +  *) Correct naming of the 'chil' and '4758cca' ENGINEs. This
        +     involves renaming the source and generated shared-libs for
        +     both. The engines will accept the corrected or legacy ids
        +     ('ncipher' and '4758_cca' respectively) when binding. NB,
        +     this only applies when building 'shared'.
        +     [Corinna Vinschen <vinschen@redhat.com> and Geoff Thorpe]
        +
        +  *) Add attribute functions to EVP_PKEY structure. Modify
        +     PKCS12_create() to recognize a CSP name attribute and
        +     use it. Make -CSP option work again in pkcs12 utility.
        +     [Steve Henson]
        +
        +  *) Add new functionality to the bn blinding code:
        +     - automatic re-creation of the BN_BLINDING parameters after
        +       a fixed number of uses (currently 32)
        +     - add new function for parameter creation
        +     - introduce flags to control the update behaviour of the
        +       BN_BLINDING parameters
        +     - hide BN_BLINDING structure
        +     Add a second BN_BLINDING slot to the RSA structure to improve
        +     performance when a single RSA object is shared among several
        +     threads.
        +     [Nils Larsch]
        +
        +  *) Add support for DTLS.
        +     [Nagendra Modadugu <nagendra@cs.stanford.edu> and Ben Laurie]
        +
        +  *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1)
        +     to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file()
        +     [Walter Goulet]
        +
        +  *) Remove buggy and incompletet DH cert support from
        +     ssl/ssl_rsa.c and ssl/s3_both.c
        +     [Nils Larsch]
        +
        +  *) Use SHA-1 instead of MD5 as the default digest algorithm for
        +     the apps/openssl applications.
        +     [Nils Larsch]
        +
        +  *) Compile clean with "-Wall -Wmissing-prototypes
        +     -Wstrict-prototypes -Wmissing-declarations -Werror". Currently
        +     DEBUG_SAFESTACK must also be set.
        +     [Ben Laurie]
        +
        +  *) Change ./Configure so that certain algorithms can be disabled by default.
        +     The new counterpiece to "no-xxx" is "enable-xxx".
        +
        +     The patented RC5 and MDC2 algorithms will now be disabled unless
        +     "enable-rc5" and "enable-mdc2", respectively, are specified.
        +
        +     (IDEA remains enabled despite being patented.  This is because IDEA
        +     is frequently required for interoperability, and there is no license
        +     fee for non-commercial use.  As before, "no-idea" can be used to
        +     avoid this algorithm.)
        +
        +     [Bodo Moeller]
        +
        +  *) Add processing of proxy certificates (see RFC 3820).  This work was
        +     sponsored by KTH (The Royal Institute of Technology in Stockholm) and
        +     EGEE (Enabling Grids for E-science in Europe).
        +     [Richard Levitte]
        +
        +  *) RC4 performance overhaul on modern architectures/implementations, such
        +     as Intel P4, IA-64 and AMD64.
        +     [Andy Polyakov]
        +
        +  *) New utility extract-section.pl. This can be used specify an alternative
        +     section number in a pod file instead of having to treat each file as
        +     a separate case in Makefile. This can be done by adding two lines to the
        +     pod file:
        +
        +     =for comment openssl_section:XXX
        +
        +     The blank line is mandatory.
        +
        +     [Steve Henson]
        +
        +  *) New arguments -certform, -keyform and -pass for s_client and s_server
        +     to allow alternative format key and certificate files and passphrase
        +     sources.
        +     [Steve Henson]
        +
        +  *) New structure X509_VERIFY_PARAM which combines current verify parameters,
        +     update associated structures and add various utility functions.
        +
        +     Add new policy related verify parameters, include policy checking in 
        +     standard verify code. Enhance 'smime' application with extra parameters
        +     to support policy checking and print out.
        +     [Steve Henson]
        +
        +  *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3
        +     Nehemiah processors. These extensions support AES encryption in hardware
        +     as well as RNG (though RNG support is currently disabled).
        +     [Michal Ludvig <michal@logix.cz>, with help from Andy Polyakov]
        +
        +  *) Deprecate BN_[get|set]_params() functions (they were ignored internally).
        +     [Geoff Thorpe]
        +
        +  *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented.
        +     [Andy Polyakov and a number of other people]
        +
        +  *) Improved PowerPC platform support. Most notably BIGNUM assembler
        +     implementation contributed by IBM.
        +     [Suresh Chari, Peter Waltenberg, Andy Polyakov]
        +
        +  *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public
        +     exponent rather than 'unsigned long'. There is a corresponding change to
        +     the new 'rsa_keygen' element of the RSA_METHOD structure.
        +     [Jelte Jansen, Geoff Thorpe]
        +
        +  *) Functionality for creating the initial serial number file is now
        +     moved from CA.pl to the 'ca' utility with a new option -create_serial.
        +
        +     (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial
        +     number file to 1, which is bound to cause problems.  To avoid
        +     the problems while respecting compatibility between different 0.9.7
        +     patchlevels, 0.9.7e  employed 'openssl x509 -next_serial' in
        +     CA.pl for serial number initialization.  With the new release 0.9.8,
        +     we can fix the problem directly in the 'ca' utility.)
        +     [Steve Henson]
        +
        +  *) Reduced header interdepencies by declaring more opaque objects in
        +     ossl_typ.h. As a consequence, including some headers (eg. engine.h) will
        +     give fewer recursive includes, which could break lazy source code - so
        +     this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always,
        +     developers should define this symbol when building and using openssl to
        +     ensure they track the recommended behaviour, interfaces, [etc], but
        +     backwards-compatible behaviour prevails when this isn't defined.
        +     [Geoff Thorpe]
        +
        +  *) New function X509_POLICY_NODE_print() which prints out policy nodes.
        +     [Steve Henson]
        +
        +  *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality.
        +     This will generate a random key of the appropriate length based on the 
        +     cipher context. The EVP_CIPHER can provide its own random key generation
        +     routine to support keys of a specific form. This is used in the des and 
        +     3des routines to generate a key of the correct parity. Update S/MIME
        +     code to use new functions and hence generate correct parity DES keys.
        +     Add EVP_CHECK_DES_KEY #define to return an error if the key is not 
        +     valid (weak or incorrect parity).
        +     [Steve Henson]
        +
        +  *) Add a local set of CRLs that can be used by X509_verify_cert() as well
        +     as looking them up. This is useful when the verified structure may contain
        +     CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs
        +     present unless the new PKCS7_NO_CRL flag is asserted.
        +     [Steve Henson]
        +
        +  *) Extend ASN1 oid configuration module. It now additionally accepts the
        +     syntax:
        +
        +     shortName = some long name, 1.2.3.4
        +     [Steve Henson]
        +
        +  *) Reimplemented the BN_CTX implementation. There is now no more static
        +     limitation on the number of variables it can handle nor the depth of the
        +     "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack
        +     information can now expand as required, and rather than having a single
        +     static array of bignums, BN_CTX now uses a linked-list of such arrays
        +     allowing it to expand on demand whilst maintaining the usefulness of
        +     BN_CTX's "bundling".
        +     [Geoff Thorpe]
        +
        +  *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD
        +     to allow all RSA operations to function using a single BN_CTX.
        +     [Geoff Thorpe]
        +
        +  *) Preliminary support for certificate policy evaluation and checking. This
        +     is initially intended to pass the tests outlined in "Conformance Testing
        +     of Relying Party Client Certificate Path Processing Logic" v1.07.
        +     [Steve Henson]
        +
        +  *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and
        +     remained unused and not that useful. A variety of other little bignum
        +     tweaks and fixes have also been made continuing on from the audit (see
        +     below).
        +     [Geoff Thorpe]
        +
        +  *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with
        +     associated ASN1, EVP and SSL functions and old ASN1 macros.
        +     [Richard Levitte]
        +
        +  *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results,
        +     and this should never fail. So the return value from the use of
        +     BN_set_word() (which can fail due to needless expansion) is now deprecated;
        +     if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro.
        +     [Geoff Thorpe]
        +
        +  *) BN_CTX_get() should return zero-valued bignums, providing the same
        +     initialised value as BN_new().
        +     [Geoff Thorpe, suggested by Ulf Möller]
        +
        +  *) Support for inhibitAnyPolicy certificate extension.
        +     [Steve Henson]
        +
        +  *) An audit of the BIGNUM code is underway, for which debugging code is
        +     enabled when BN_DEBUG is defined. This makes stricter enforcements on what
        +     is considered valid when processing BIGNUMs, and causes execution to
        +     assert() when a problem is discovered. If BN_DEBUG_RAND is defined,
        +     further steps are taken to deliberately pollute unused data in BIGNUM
        +     structures to try and expose faulty code further on. For now, openssl will
        +     (in its default mode of operation) continue to tolerate the inconsistent
        +     forms that it has tolerated in the past, but authors and packagers should
        +     consider trying openssl and their own applications when compiled with
        +     these debugging symbols defined. It will help highlight potential bugs in
        +     their own code, and will improve the test coverage for OpenSSL itself. At
        +     some point, these tighter rules will become openssl's default to improve
        +     maintainability, though the assert()s and other overheads will remain only
        +     in debugging configurations. See bn.h for more details.
        +     [Geoff Thorpe, Nils Larsch, Ulf Möller]
        +
        +  *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure
        +     that can only be obtained through BN_CTX_new() (which implicitly
        +     initialises it). The presence of this function only made it possible
        +     to overwrite an existing structure (and cause memory leaks).
        +     [Geoff Thorpe]
        +
        +  *) Because of the callback-based approach for implementing LHASH as a
        +     template type, lh_insert() adds opaque objects to hash-tables and
        +     lh_doall() or lh_doall_arg() are typically used with a destructor callback
        +     to clean up those corresponding objects before destroying the hash table
        +     (and losing the object pointers). So some over-zealous constifications in
        +     LHASH have been relaxed so that lh_insert() does not take (nor store) the
        +     objects as "const" and the lh_doall[_arg] callback wrappers are not
        +     prototyped to have "const" restrictions on the object pointers they are
        +     given (and so aren't required to cast them away any more).
        +     [Geoff Thorpe]
        +
        +  *) The tmdiff.h API was so ugly and minimal that our own timing utility
        +     (speed) prefers to use its own implementation. The two implementations
        +     haven't been consolidated as yet (volunteers?) but the tmdiff API has had
        +     its object type properly exposed (MS_TM) instead of casting to/from "char
        +     *". This may still change yet if someone realises MS_TM and "ms_time_***"
        +     aren't necessarily the greatest nomenclatures - but this is what was used
        +     internally to the implementation so I've used that for now.
        +     [Geoff Thorpe]
        +
        +  *) Ensure that deprecated functions do not get compiled when
        +     OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of
        +     the self-tests were still using deprecated key-generation functions so
        +     these have been updated also.
        +     [Geoff Thorpe]
        +
        +  *) Reorganise PKCS#7 code to separate the digest location functionality
        +     into PKCS7_find_digest(), digest addtion into PKCS7_bio_add_digest().
        +     New function PKCS7_set_digest() to set the digest type for PKCS#7
        +     digestedData type. Add additional code to correctly generate the
        +     digestedData type and add support for this type in PKCS7 initialization
        +     functions.
        +     [Steve Henson]
        +
        +  *) New function PKCS7_set0_type_other() this initializes a PKCS7 
        +     structure of type "other".
        +     [Steve Henson]
        +
        +  *) Fix prime generation loop in crypto/bn/bn_prime.pl by making
        +     sure the loop does correctly stop and breaking ("division by zero")
        +     modulus operations are not performed. The (pre-generated) prime
        +     table crypto/bn/bn_prime.h was already correct, but it could not be
        +     re-generated on some platforms because of the "division by zero"
        +     situation in the script.
        +     [Ralf S. Engelschall]
        +
        +  *) Update support for ECC-based TLS ciphersuites according to
        +     draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with
        +     SHA-1 now is only used for "small" curves (where the
        +     representation of a field element takes up to 24 bytes); for
        +     larger curves, the field element resulting from ECDH is directly
        +     used as premaster secret.
        +     [Douglas Stebila (Sun Microsystems Laboratories)]
        +
        +  *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2
        +     curve secp160r1 to the tests.
        +     [Douglas Stebila (Sun Microsystems Laboratories)]
        +
        +  *) Add the possibility to load symbols globally with DSO.
        +     [Götz Babin-Ebell <babin-ebell@trustcenter.de> via Richard Levitte]
        +
        +  *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better
        +     control of the error stack.
        +     [Richard Levitte]
        +
        +  *) Add support for STORE in ENGINE.
        +     [Richard Levitte]
        +
        +  *) Add the STORE type.  The intention is to provide a common interface
        +     to certificate and key stores, be they simple file-based stores, or
        +     HSM-type store, or LDAP stores, or...
        +     NOTE: The code is currently UNTESTED and isn't really used anywhere.
        +     [Richard Levitte]
        +
        +  *) Add a generic structure called OPENSSL_ITEM.  This can be used to
        +     pass a list of arguments to any function as well as provide a way
        +     for a function to pass data back to the caller.
        +     [Richard Levitte]
        +
        +  *) Add the functions BUF_strndup() and BUF_memdup().  BUF_strndup()
        +     works like BUF_strdup() but can be used to duplicate a portion of
        +     a string.  The copy gets NUL-terminated.  BUF_memdup() duplicates
        +     a memory area.
        +     [Richard Levitte]
        +
        +  *) Add the function sk_find_ex() which works like sk_find(), but will
        +     return an index to an element even if an exact match couldn't be
        +     found.  The index is guaranteed to point at the element where the
        +     searched-for key would be inserted to preserve sorting order.
        +     [Richard Levitte]
        +
        +  *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but
        +     takes an extra flags argument for optional functionality.  Currently,
        +     the following flags are defined:
        +
        +	OBJ_BSEARCH_VALUE_ON_NOMATCH
        +	This one gets OBJ_bsearch_ex() to return a pointer to the first
        +	element where the comparing function returns a negative or zero
        +	number.
        +
        +	OBJ_BSEARCH_FIRST_VALUE_ON_MATCH
        +	This one gets OBJ_bsearch_ex() to return a pointer to the first
        +	element where the comparing function returns zero.  This is useful
        +	if there are more than one element where the comparing function
        +	returns zero.
        +     [Richard Levitte]
        +
        +  *) Make it possible to create self-signed certificates with 'openssl ca'
        +     in such a way that the self-signed certificate becomes part of the
        +     CA database and uses the same mechanisms for serial number generation
        +     as all other certificate signing.  The new flag '-selfsign' enables
        +     this functionality.  Adapt CA.sh and CA.pl.in.
        +     [Richard Levitte]
        +
        +  *) Add functionality to check the public key of a certificate request
        +     against a given private.  This is useful to check that a certificate
        +     request can be signed by that key (self-signing).
        +     [Richard Levitte]
        +
        +  *) Make it possible to have multiple active certificates with the same
        +     subject in the CA index file.  This is done only if the keyword
        +     'unique_subject' is set to 'no' in the main CA section (default
        +     if 'CA_default') of the configuration file.  The value is saved
        +     with the database itself in a separate index attribute file,
        +     named like the index file with '.attr' appended to the name.
        +     [Richard Levitte]
        +
        +  *) Generate muti valued AVAs using '+' notation in config files for
        +     req and dirName.
        +     [Steve Henson]
        +
        +  *) Support for nameConstraints certificate extension.
        +     [Steve Henson]
        +
        +  *) Support for policyConstraints certificate extension.
        +     [Steve Henson]
        +
        +  *) Support for policyMappings certificate extension.
        +     [Steve Henson]
        +
        +  *) Make sure the default DSA_METHOD implementation only uses its
        +     dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL,
        +     and change its own handlers to be NULL so as to remove unnecessary
        +     indirection. This lets alternative implementations fallback to the
        +     default implementation more easily.
        +     [Geoff Thorpe]
        +
        +  *) Support for directoryName in GeneralName related extensions
        +     in config files.
        +     [Steve Henson]
        +
        +  *) Make it possible to link applications using Makefile.shared.
        +     Make that possible even when linking against static libraries!
        +     [Richard Levitte]
        +
        +  *) Support for single pass processing for S/MIME signing. This now
        +     means that S/MIME signing can be done from a pipe, in addition
        +     cleartext signing (multipart/signed type) is effectively streaming
        +     and the signed data does not need to be all held in memory.
        +
        +     This is done with a new flag PKCS7_STREAM. When this flag is set
        +     PKCS7_sign() only initializes the PKCS7 structure and the actual signing
        +     is done after the data is output (and digests calculated) in
        +     SMIME_write_PKCS7().
        +     [Steve Henson]
        +
        +  *) Add full support for -rpath/-R, both in shared libraries and
        +     applications, at least on the platforms where it's known how
        +     to do it.
        +     [Richard Levitte]
        +
        +  *) In crypto/ec/ec_mult.c, implement fast point multiplication with
        +     precomputation, based on wNAF splitting: EC_GROUP_precompute_mult()
        +     will now compute a table of multiples of the generator that
        +     makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul()
        +     faster (notably in the case of a single point multiplication,
        +     scalar * generator).
        +     [Nils Larsch, Bodo Moeller]
        +
        +  *) IPv6 support for certificate extensions. The various extensions
        +     which use the IP:a.b.c.d can now take IPv6 addresses using the
        +     formats of RFC1884 2.2 . IPv6 addresses are now also displayed
        +     correctly.
        +     [Steve Henson]
        +
        +  *) Added an ENGINE that implements RSA by performing private key
        +     exponentiations with the GMP library. The conversions to and from
        +     GMP's mpz_t format aren't optimised nor are any montgomery forms
        +     cached, and on x86 it appears OpenSSL's own performance has caught up.
        +     However there are likely to be other architectures where GMP could
        +     provide a boost. This ENGINE is not built in by default, but it can be
        +     specified at Configure time and should be accompanied by the necessary
        +     linker additions, eg;
        +         ./config -DOPENSSL_USE_GMP -lgmp
        +     [Geoff Thorpe]
        +
        +  *) "openssl engine" will not display ENGINE/DSO load failure errors when
        +     testing availability of engines with "-t" - the old behaviour is
        +     produced by increasing the feature's verbosity with "-tt".
        +     [Geoff Thorpe]
        +
        +  *) ECDSA routines: under certain error conditions uninitialized BN objects
        +     could be freed. Solution: make sure initialization is performed early
        +     enough. (Reported and fix supplied by Nils Larsch <nla@trustcenter.de>
        +     via PR#459)
        +     [Lutz Jaenicke]
        +
        +  *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD
        +     and DH_METHOD (eg. by ENGINE implementations) to override the normal
        +     software implementations. For DSA and DH, parameter generation can
        +     also be overriden by providing the appropriate method callbacks.
        +     [Geoff Thorpe]
        +
        +  *) Change the "progress" mechanism used in key-generation and
        +     primality testing to functions that take a new BN_GENCB pointer in
        +     place of callback/argument pairs. The new API functions have "_ex"
        +     postfixes and the older functions are reimplemented as wrappers for
        +     the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide
        +     declarations of the old functions to help (graceful) attempts to
        +     migrate to the new functions. Also, the new key-generation API
        +     functions operate on a caller-supplied key-structure and return
        +     success/failure rather than returning a key or NULL - this is to
        +     help make "keygen" another member function of RSA_METHOD etc.
        +
        +     Example for using the new callback interface:
        +
        +          int (*my_callback)(int a, int b, BN_GENCB *cb) = ...;
        +          void *my_arg = ...;
        +          BN_GENCB my_cb;
        +
        +          BN_GENCB_set(&my_cb, my_callback, my_arg);
        +
        +          return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb);
        +          /* For the meaning of a, b in calls to my_callback(), see the
        +           * documentation of the function that calls the callback.
        +           * cb will point to my_cb; my_arg can be retrieved as cb->arg.
        +           * my_callback should return 1 if it wants BN_is_prime_ex()
        +           * to continue, or 0 to stop.
        +           */
        +
        +     [Geoff Thorpe]
        +
        +  *) Change the ZLIB compression method to be stateful, and make it
        +     available to TLS with the number defined in 
        +     draft-ietf-tls-compression-04.txt.
        +     [Richard Levitte]
        +
        +  *) Add the ASN.1 structures and functions for CertificatePair, which
        +     is defined as follows (according to X.509_4thEditionDraftV6.pdf):
        +
        +     CertificatePair ::= SEQUENCE {
        +        forward		[0]	Certificate OPTIONAL,
        +        reverse		[1]	Certificate OPTIONAL,
        +        -- at least one of the pair shall be present -- }
        +
        +     Also implement the PEM functions to read and write certificate
        +     pairs, and defined the PEM tag as "CERTIFICATE PAIR".
        +
        +     This needed to be defined, mostly for the sake of the LDAP
        +     attribute crossCertificatePair, but may prove useful elsewhere as
        +     well.
        +     [Richard Levitte]
        +
        +  *) Make it possible to inhibit symlinking of shared libraries in
        +     Makefile.shared, for Cygwin's sake.
        +     [Richard Levitte]
        +
        +  *) Extend the BIGNUM API by creating a function 
        +          void BN_set_negative(BIGNUM *a, int neg);
        +     and a macro that behave like
        +          int  BN_is_negative(const BIGNUM *a);
        +
        +     to avoid the need to access 'a->neg' directly in applications.
        +     [Nils Larsch]
        +
        +  *) Implement fast modular reduction for pseudo-Mersenne primes
        +     used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
        +     EC_GROUP_new_curve_GFp() will now automatically use this
        +     if applicable.
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Add new lock type (CRYPTO_LOCK_BN).
        +     [Bodo Moeller]
        +
        +  *) Change the ENGINE framework to automatically load engines
        +     dynamically from specific directories unless they could be
        +     found to already be built in or loaded.  Move all the
        +     current engines except for the cryptodev one to a new
        +     directory engines/.
        +     The engines in engines/ are built as shared libraries if
        +     the "shared" options was given to ./Configure or ./config.
        +     Otherwise, they are inserted in libcrypto.a.
        +     /usr/local/ssl/engines is the default directory for dynamic
        +     engines, but that can be overriden at configure time through
        +     the usual use of --prefix and/or --openssldir, and at run
        +     time with the environment variable OPENSSL_ENGINES.
        +     [Geoff Thorpe and Richard Levitte]
        +
        +  *) Add Makefile.shared, a helper makefile to build shared
        +     libraries.  Addapt Makefile.org.
        +     [Richard Levitte]
        +
        +  *) Add version info to Win32 DLLs.
        +     [Peter 'Luna' Runestig" <peter@runestig.com>]
        +
        +  *) Add new 'medium level' PKCS#12 API. Certificates and keys
        +     can be added using this API to created arbitrary PKCS#12
        +     files while avoiding the low level API.
        +
        +     New options to PKCS12_create(), key or cert can be NULL and
        +     will then be omitted from the output file. The encryption
        +     algorithm NIDs can be set to -1 for no encryption, the mac
        +     iteration count can be set to 0 to omit the mac.
        +
        +     Enhance pkcs12 utility by making the -nokeys and -nocerts
        +     options work when creating a PKCS#12 file. New option -nomac
        +     to omit the mac, NONE can be set for an encryption algorithm.
        +     New code is modified to use the enhanced PKCS12_create()
        +     instead of the low level API.
        +     [Steve Henson]
        +
        +  *) Extend ASN1 encoder to support indefinite length constructed
        +     encoding. This can output sequences tags and octet strings in
        +     this form. Modify pk7_asn1.c to support indefinite length
        +     encoding. This is experimental and needs additional code to
        +     be useful, such as an ASN1 bio and some enhanced streaming
        +     PKCS#7 code.
        +
        +     Extend template encode functionality so that tagging is passed
        +     down to the template encoder.
        +     [Steve Henson]
        +
        +  *) Let 'openssl req' fail if an argument to '-newkey' is not
        +     recognized instead of using RSA as a default.
        +     [Bodo Moeller]
        +
        +  *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt.
        +     As these are not official, they are not included in "ALL";
        +     the "ECCdraft" ciphersuite group alias can be used to select them.
        +     [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)]
        +
        +  *) Add ECDH engine support.
        +     [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]
        +
        +  *) Add ECDH in new directory crypto/ecdh/.
        +     [Douglas Stebila (Sun Microsystems Laboratories)]
        +
        +  *) Let BN_rand_range() abort with an error after 100 iterations
        +     without success (which indicates a broken PRNG).
        +     [Bodo Moeller]
        +
        +  *) Change BN_mod_sqrt() so that it verifies that the input value
        +     is really the square of the return value.  (Previously,
        +     BN_mod_sqrt would show GIGO behaviour.)
        +     [Bodo Moeller]
        +
        +  *) Add named elliptic curves over binary fields from X9.62, SECG,
        +     and WAP/WTLS; add OIDs that were still missing.
        +
        +     [Sheueling Chang Shantz and Douglas Stebila
        +     (Sun Microsystems Laboratories)]
        +
        +  *) Extend the EC library for elliptic curves over binary fields
        +     (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/).
        +     New EC_METHOD:
        +
        +          EC_GF2m_simple_method
        +
        +     New API functions:
        +
        +          EC_GROUP_new_curve_GF2m
        +          EC_GROUP_set_curve_GF2m
        +          EC_GROUP_get_curve_GF2m
        +          EC_POINT_set_affine_coordinates_GF2m
        +          EC_POINT_get_affine_coordinates_GF2m
        +          EC_POINT_set_compressed_coordinates_GF2m
        +
        +     Point compression for binary fields is disabled by default for
        +     patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to
        +     enable it).
        +
        +     As binary polynomials are represented as BIGNUMs, various members
        +     of the EC_GROUP and EC_POINT data structures can be shared
        +     between the implementations for prime fields and binary fields;
        +     the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m)
        +     are essentially identical to their ..._GFp counterparts.
        +     (For simplicity, the '..._GFp' prefix has been dropped from
        +     various internal method names.)
        +
        +     An internal 'field_div' method (similar to 'field_mul' and
        +     'field_sqr') has been added; this is used only for binary fields.
        +
        +     [Sheueling Chang Shantz and Douglas Stebila
        +     (Sun Microsystems Laboratories)]
        +
        +  *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult()
        +     through methods ('mul', 'precompute_mult').
        +
        +     The generic implementations (now internally called 'ec_wNAF_mul'
        +     and 'ec_wNAF_precomputed_mult') remain the default if these
        +     methods are undefined.
        +
        +     [Sheueling Chang Shantz and Douglas Stebila
        +     (Sun Microsystems Laboratories)]
        +
        +  *) New function EC_GROUP_get_degree, which is defined through
        +     EC_METHOD.  For curves over prime fields, this returns the bit
        +     length of the modulus.
        +
        +     [Sheueling Chang Shantz and Douglas Stebila
        +     (Sun Microsystems Laboratories)]
        +
        +  *) New functions EC_GROUP_dup, EC_POINT_dup.
        +     (These simply call ..._new  and ..._copy).
        +
        +     [Sheueling Chang Shantz and Douglas Stebila
        +     (Sun Microsystems Laboratories)]
        +
        +  *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
        +     Polynomials are represented as BIGNUMs (where the sign bit is not
        +     used) in the following functions [macros]:  
        +
        +          BN_GF2m_add
        +          BN_GF2m_sub             [= BN_GF2m_add]
        +          BN_GF2m_mod             [wrapper for BN_GF2m_mod_arr]
        +          BN_GF2m_mod_mul         [wrapper for BN_GF2m_mod_mul_arr]
        +          BN_GF2m_mod_sqr         [wrapper for BN_GF2m_mod_sqr_arr]
        +          BN_GF2m_mod_inv
        +          BN_GF2m_mod_exp         [wrapper for BN_GF2m_mod_exp_arr]
        +          BN_GF2m_mod_sqrt        [wrapper for BN_GF2m_mod_sqrt_arr]
        +          BN_GF2m_mod_solve_quad  [wrapper for BN_GF2m_mod_solve_quad_arr]
        +          BN_GF2m_cmp             [= BN_ucmp]
        +
        +     (Note that only the 'mod' functions are actually for fields GF(2^m).
        +     BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
        +
        +     For some functions, an the irreducible polynomial defining a
        +     field can be given as an 'unsigned int[]' with strictly
        +     decreasing elements giving the indices of those bits that are set;
        +     i.e., p[] represents the polynomial
        +          f(t) = t^p[0] + t^p[1] + ... + t^p[k]
        +     where
        +          p[0] > p[1] > ... > p[k] = 0.
        +     This applies to the following functions:
        +
        +          BN_GF2m_mod_arr
        +          BN_GF2m_mod_mul_arr
        +          BN_GF2m_mod_sqr_arr
        +          BN_GF2m_mod_inv_arr        [wrapper for BN_GF2m_mod_inv]
        +          BN_GF2m_mod_div_arr        [wrapper for BN_GF2m_mod_div]
        +          BN_GF2m_mod_exp_arr
        +          BN_GF2m_mod_sqrt_arr
        +          BN_GF2m_mod_solve_quad_arr
        +          BN_GF2m_poly2arr
        +          BN_GF2m_arr2poly
        +
        +     Conversion can be performed by the following functions:
        +
        +          BN_GF2m_poly2arr
        +          BN_GF2m_arr2poly
        +
        +     bntest.c has additional tests for binary polynomial arithmetic.
        +
        +     Two implementations for BN_GF2m_mod_div() are available.
        +     The default algorithm simply uses BN_GF2m_mod_inv() and
        +     BN_GF2m_mod_mul().  The alternative algorithm is compiled in only
        +     if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the
        +     copyright notice in crypto/bn/bn_gf2m.c before enabling it).
        +
        +     [Sheueling Chang Shantz and Douglas Stebila
        +     (Sun Microsystems Laboratories)]
        +
        +  *) Add new error code 'ERR_R_DISABLED' that can be used when some
        +     functionality is disabled at compile-time.
        +     [Douglas Stebila <douglas.stebila@sun.com>]
        +
        +  *) Change default behaviour of 'openssl asn1parse' so that more
        +     information is visible when viewing, e.g., a certificate:
        +
        +     Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump'
        +     mode the content of non-printable OCTET STRINGs is output in a
        +     style similar to INTEGERs, but with '[HEX DUMP]' prepended to
        +     avoid the appearance of a printable string.
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access
        +     functions
        +          EC_GROUP_set_asn1_flag()
        +          EC_GROUP_get_asn1_flag()
        +          EC_GROUP_set_point_conversion_form()
        +          EC_GROUP_get_point_conversion_form()
        +     These control ASN1 encoding details:
        +     - Curves (i.e., groups) are encoded explicitly unless asn1_flag
        +       has been set to OPENSSL_EC_NAMED_CURVE.
        +     - Points are encoded in uncompressed form by default; options for
        +       asn1_for are as for point2oct, namely
        +          POINT_CONVERSION_COMPRESSED
        +          POINT_CONVERSION_UNCOMPRESSED
        +          POINT_CONVERSION_HYBRID
        +
        +     Also add 'seed' and 'seed_len' members to EC_GROUP with access
        +     functions
        +          EC_GROUP_set_seed()
        +          EC_GROUP_get0_seed()
        +          EC_GROUP_get_seed_len()
        +     This is used only for ASN1 purposes (so far).
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Add 'field_type' member to EC_METHOD, which holds the NID
        +     of the appropriate field type OID.  The new function
        +     EC_METHOD_get_field_type() returns this value.
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Add functions 
        +          EC_POINT_point2bn()
        +          EC_POINT_bn2point()
        +          EC_POINT_point2hex()
        +          EC_POINT_hex2point()
        +     providing useful interfaces to EC_POINT_point2oct() and
        +     EC_POINT_oct2point().
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Change internals of the EC library so that the functions
        +          EC_GROUP_set_generator()
        +          EC_GROUP_get_generator()
        +          EC_GROUP_get_order()
        +          EC_GROUP_get_cofactor()
        +     are implemented directly in crypto/ec/ec_lib.c and not dispatched
        +     to methods, which would lead to unnecessary code duplication when
        +     adding different types of curves.
        +     [Nils Larsch <nla@trustcenter.de> with input by Bodo Moeller]
        +
        +  *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
        +     arithmetic, and such that modified wNAFs are generated
        +     (which avoid length expansion in many cases).
        +     [Bodo Moeller]
        +
        +  *) Add a function EC_GROUP_check_discriminant() (defined via
        +     EC_METHOD) that verifies that the curve discriminant is non-zero.
        +
        +     Add a function EC_GROUP_check() that makes some sanity tests
        +     on a EC_GROUP, its generator and order.  This includes
        +     EC_GROUP_check_discriminant().
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Add ECDSA in new directory crypto/ecdsa/.
        +
        +     Add applications 'openssl ecparam' and 'openssl ecdsa'
        +     (these are based on 'openssl dsaparam' and 'openssl dsa').
        +
        +     ECDSA support is also included in various other files across the
        +     library.  Most notably,
        +     - 'openssl req' now has a '-newkey ecdsa:file' option;
        +     - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA;
        +     - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
        +       d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
        +       them suitable for ECDSA where domain parameters must be
        +       extracted before the specific public key;
        +     - ECDSA engine support has been added.
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Include some named elliptic curves, and add OIDs from X9.62,
        +     SECG, and WAP/WTLS.  Each curve can be obtained from the new
        +     function
        +          EC_GROUP_new_by_curve_name(),
        +     and the list of available named curves can be obtained with
        +          EC_get_builtin_curves().
        +     Also add a 'curve_name' member to EC_GROUP objects, which can be
        +     accessed via
        +         EC_GROUP_set_curve_name()
        +         EC_GROUP_get_curve_name()
        +     [Nils Larsch <larsch@trustcenter.de, Bodo Moeller]
        + 
        +  *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
        +     was actually never needed) and in BN_mul().  The removal in BN_mul()
        +     required a small change in bn_mul_part_recursive() and the addition
        +     of the functions bn_cmp_part_words(), bn_sub_part_words() and
        +     bn_add_part_words(), which do the same thing as bn_cmp_words(),
        +     bn_sub_words() and bn_add_words() except they take arrays with
        +     differing sizes.
        +     [Richard Levitte]
        +
        + Changes between 0.9.7l and 0.9.7m  [23 Feb 2007]
        +
        +  *) Cleanse PEM buffers before freeing them since they may contain 
        +     sensitive data.
        +     [Benjamin Bennett <ben@psc.edu>]
        +
        +  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
        +     a ciphersuite string such as "DEFAULT:RSA" cannot enable
        +     authentication-only ciphersuites.
        +     [Bodo Moeller]
        +
        +  *) Since AES128 and AES256 share a single mask bit in the logic of
        +     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
        +     kludge to work properly if AES128 is available and AES256 isn't.
        +     [Victor Duchovni]
        +
        +  *) Expand security boundary to match 1.1.1 module.
        +     [Steve Henson]
        +
        +  *) Remove redundant features: hash file source, editing of test vectors
        +     modify fipsld to use external fips_premain.c signature.
        +     [Steve Henson]
        +
        +  *) New perl script mkfipsscr.pl to create shell scripts or batch files to
        +     run algorithm test programs.
        +     [Steve Henson]
        +
        +  *) Make algorithm test programs more tolerant of whitespace.
        +     [Steve Henson]
        +
        +  *) Have SSL/TLS server implementation tolerate "mismatched" record
        +     protocol version while receiving ClientHello even if the
        +     ClientHello is fragmented.  (The server can't insist on the
        +     particular protocol version it has chosen before the ServerHello
        +     message has informed the client about his choice.)
        +     [Bodo Moeller]
        +
        +  *) Load error codes if they are not already present instead of using a
        +     static variable. This allows them to be cleanly unloaded and reloaded.
        +     [Steve Henson]
        +
        + Changes between 0.9.7k and 0.9.7l  [28 Sep 2006]
        +
        +  *) Introduce limits to prevent malicious keys being able to
        +     cause a denial of service.  (CVE-2006-2940)
        +     [Steve Henson, Bodo Moeller]
        +
        +  *) Fix ASN.1 parsing of certain invalid structures that can result
        +     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
        +
        +  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
        +     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
        +
        +  *) Fix SSL client code which could crash if connecting to a
        +     malicious SSLv2 server.  (CVE-2006-4343)
        +     [Tavis Ormandy and Will Drewry, Google Security Team]
        +
        +  *) Change ciphersuite string processing so that an explicit
        +     ciphersuite selects this one ciphersuite (so that "AES256-SHA"
        +     will no longer include "AES128-SHA"), and any other similar
        +     ciphersuite (same bitmap) from *other* protocol versions (so that
        +     "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the
        +     SSL 3.0/TLS 1.0 ciphersuite).  This is a backport combining
        +     changes from 0.9.8b and 0.9.8d.
        +     [Bodo Moeller]
        +
        + Changes between 0.9.7j and 0.9.7k  [05 Sep 2006]
        +
        +  *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
        +     (CVE-2006-4339)  [Ben Laurie and Google Security Team]
        +
        +  *) Change the Unix randomness entropy gathering to use poll() when
        +     possible instead of select(), since the latter has some
        +     undesirable limitations.
        +     [Darryl Miles via Richard Levitte and Bodo Moeller]
        +
        +  *) Disable rogue ciphersuites:
        +
        +      - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
        +      - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
        +      - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
        +
        +     The latter two were purportedly from
        +     draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
        +     appear there.
        +
        +     Also deactive the remaining ciphersuites from
        +     draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
        +     unofficial, and the ID has long expired.
        +     [Bodo Moeller]
        +
        +  *) Fix RSA blinding Heisenbug (problems sometimes occured on
        +     dual-core machines) and other potential thread-safety issues.
        +     [Bodo Moeller]
        +
        + Changes between 0.9.7i and 0.9.7j  [04 May 2006]
        +
        +  *) Adapt fipsld and the build system to link against the validated FIPS
        +     module in FIPS mode.
        +     [Steve Henson]
        +
        +  *) Fixes for VC++ 2005 build under Windows.
        +     [Steve Henson]
        +
        +  *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make 
        +     from a Windows bash shell such as MSYS. It is autodetected from the
        +     "config" script when run from a VC++ environment. Modify standard VC++
        +     build to use fipscanister.o from the GNU make build. 
        +     [Steve Henson]
        +
        + Changes between 0.9.7h and 0.9.7i  [14 Oct 2005]
        +
        +  *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS.
        +     The value now differs depending on if you build for FIPS or not.
        +     BEWARE!  A program linked with a shared FIPSed libcrypto can't be
        +     safely run with a non-FIPSed libcrypto, as it may crash because of
        +     the difference induced by this change.
        +     [Andy Polyakov]
        +
        + Changes between 0.9.7g and 0.9.7h  [11 Oct 2005]
        +
        +  *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
        +     (part of SSL_OP_ALL).  This option used to disable the
        +     countermeasure against man-in-the-middle protocol-version
        +     rollback in the SSL 2.0 server implementation, which is a bad
        +     idea.  (CVE-2005-2969)
        +
        +     [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
        +     for Information Security, National Institute of Advanced Industrial
        +     Science and Technology [AIST], Japan)]
        +
        +  *) Minimal support for X9.31 signatures and PSS padding modes. This is
        +     mainly for FIPS compliance and not fully integrated at this stage.
        +     [Steve Henson]
        +
        +  *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform
        +     the exponentiation using a fixed-length exponent.  (Otherwise,
        +     the information leaked through timing could expose the secret key
        +     after many signatures; cf. Bleichenbacher's attack on DSA with
        +     biased k.)
        +     [Bodo Moeller]
        +
        +  *) Make a new fixed-window mod_exp implementation the default for
        +     RSA, DSA, and DH private-key operations so that the sequence of
        +     squares and multiplies and the memory access pattern are
        +     independent of the particular secret key.  This will mitigate
        +     cache-timing and potential related attacks.
        +
        +     BN_mod_exp_mont_consttime() is the new exponentiation implementation,
        +     and this is automatically used by BN_mod_exp_mont() if the new flag
        +     BN_FLG_EXP_CONSTTIME is set for the exponent.  RSA, DSA, and DH
        +     will use this BN flag for private exponents unless the flag
        +     RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or
        +     DH_FLAG_NO_EXP_CONSTTIME, respectively, is set.
        +
        +     [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller]
        +
        +  *) Change the client implementation for SSLv23_method() and
        +     SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0
        +     Client Hello message format if the SSL_OP_NO_SSLv2 option is set.
        +     (Previously, the SSL 2.0 backwards compatible Client Hello
        +     message format would be used even with SSL_OP_NO_SSLv2.)
        +     [Bodo Moeller]
        +
        +  *) Add support for smime-type MIME parameter in S/MIME messages which some
        +     clients need.
        +     [Steve Henson]
        +
        +  *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in
        +     a threadsafe manner. Modify rsa code to use new function and add calls
        +     to dsa and dh code (which had race conditions before).
        +     [Steve Henson]
        +
        +  *) Include the fixed error library code in the C error file definitions
        +     instead of fixing them up at runtime. This keeps the error code
        +     structures constant.
        +     [Steve Henson]
        +
        + Changes between 0.9.7f and 0.9.7g  [11 Apr 2005]
        +
        +  [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after
        +  OpenSSL 0.9.8.]
        +
        +  *) Fixes for newer kerberos headers. NB: the casts are needed because
        +     the 'length' field is signed on one version and unsigned on another
        +     with no (?) obvious way to tell the difference, without these VC++
        +     complains. Also the "definition" of FAR (blank) is no longer included
        +     nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up
        +     some needed definitions.
        +     [Steve Henson]
        +
        +  *) Undo Cygwin change.
        +     [Ulf Möller]
        +
        +  *) Added support for proxy certificates according to RFC 3820.
        +     Because they may be a security thread to unaware applications,
        +     they must be explicitely allowed in run-time.  See
        +     docs/HOWTO/proxy_certificates.txt for further information.
        +     [Richard Levitte]
        +
        + Changes between 0.9.7e and 0.9.7f  [22 Mar 2005]
        +
        +  *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
        +     server and client random values. Previously
        +     (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in
        +     less random data when sizeof(time_t) > 4 (some 64 bit platforms).
        +
        +     This change has negligible security impact because:
        +
        +     1. Server and client random values still have 24 bytes of pseudo random
        +        data.
        +
        +     2. Server and client random values are sent in the clear in the initial
        +        handshake.
        +
        +     3. The master secret is derived using the premaster secret (48 bytes in
        +        size for static RSA ciphersuites) as well as client server and random
        +        values.
        +
        +     The OpenSSL team would like to thank the UK NISCC for bringing this issue
        +     to our attention. 
        +
        +     [Stephen Henson, reported by UK NISCC]
        +
        +  *) Use Windows randomness collection on Cygwin.
        +     [Ulf Möller]
        +
        +  *) Fix hang in EGD/PRNGD query when communication socket is closed
        +     prematurely by EGD/PRNGD.
        +     [Darren Tucker <dtucker@zip.com.au> via Lutz Jänicke, resolves #1014]
        +
        +  *) Prompt for pass phrases when appropriate for PKCS12 input format.
        +     [Steve Henson]
        +
        +  *) Back-port of selected performance improvements from development
        +     branch, as well as improved support for PowerPC platforms.
        +     [Andy Polyakov]
        +
        +  *) Add lots of checks for memory allocation failure, error codes to indicate
        +     failure and freeing up memory if a failure occurs.
        +     [Nauticus Networks SSL Team <openssl@nauticusnet.com>, Steve Henson]
        +
        +  *) Add new -passin argument to dgst.
        +     [Steve Henson]
        +
        +  *) Perform some character comparisons of different types in X509_NAME_cmp:
        +     this is needed for some certificates that reencode DNs into UTF8Strings
        +     (in violation of RFC3280) and can't or wont issue name rollover
        +     certificates.
        +     [Steve Henson]
        +
        +  *) Make an explicit check during certificate validation to see that
        +     the CA setting in each certificate on the chain is correct.  As a
        +     side effect always do the following basic checks on extensions,
        +     not just when there's an associated purpose to the check:
        +
        +      - if there is an unhandled critical extension (unless the user
        +        has chosen to ignore this fault)
        +      - if the path length has been exceeded (if one is set at all)
        +      - that certain extensions fit the associated purpose (if one has
        +        been given)
        +     [Richard Levitte]
        +
        + Changes between 0.9.7d and 0.9.7e  [25 Oct 2004]
        +
        +  *) Avoid a race condition when CRLs are checked in a multi threaded 
        +     environment. This would happen due to the reordering of the revoked
        +     entries during signature checking and serial number lookup. Now the
        +     encoding is cached and the serial number sort performed under a lock.
        +     Add new STACK function sk_is_sorted().
        +     [Steve Henson]
        +
        +  *) Add Delta CRL to the extension code.
        +     [Steve Henson]
        +
        +  *) Various fixes to s3_pkt.c so alerts are sent properly.
        +     [David Holmes <d.holmes@f5.com>]
        +
        +  *) Reduce the chances of duplicate issuer name and serial numbers (in
        +     violation of RFC3280) using the OpenSSL certificate creation utilities.
        +     This is done by creating a random 64 bit value for the initial serial
        +     number when a serial number file is created or when a self signed
        +     certificate is created using 'openssl req -x509'. The initial serial
        +     number file is created using 'openssl x509 -next_serial' in CA.pl
        +     rather than being initialized to 1.
        +     [Steve Henson]
        +
        + Changes between 0.9.7c and 0.9.7d  [17 Mar 2004]
        +
        +  *) Fix null-pointer assignment in do_change_cipher_spec() revealed           
        +     by using the Codenomicon TLS Test Tool (CVE-2004-0079)                    
        +     [Joe Orton, Steve Henson]   
        +
        +  *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites
        +     (CVE-2004-0112)
        +     [Joe Orton, Steve Henson]   
        +
        +  *) Make it possible to have multiple active certificates with the same
        +     subject in the CA index file.  This is done only if the keyword
        +     'unique_subject' is set to 'no' in the main CA section (default
        +     if 'CA_default') of the configuration file.  The value is saved
        +     with the database itself in a separate index attribute file,
        +     named like the index file with '.attr' appended to the name.
        +     [Richard Levitte]
        +
        +  *) X509 verify fixes. Disable broken certificate workarounds when 
        +     X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if
        +     keyUsage extension present. Don't accept CRLs with unhandled critical
        +     extensions: since verify currently doesn't process CRL extensions this
        +     rejects a CRL with *any* critical extensions. Add new verify error codes
        +     for these cases.
        +     [Steve Henson]
        +
        +  *) When creating an OCSP nonce use an OCTET STRING inside the extnValue.
        +     A clarification of RFC2560 will require the use of OCTET STRINGs and 
        +     some implementations cannot handle the current raw format. Since OpenSSL
        +     copies and compares OCSP nonces as opaque blobs without any attempt at
        +     parsing them this should not create any compatibility issues.
        +     [Steve Henson]
        +
        +  *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when
        +     calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without
        +     this HMAC (and other) operations are several times slower than OpenSSL
        +     < 0.9.7.
        +     [Steve Henson]
        +
        +  *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex().
        +     [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
        +
        +  *) Use the correct content when signing type "other".
        +     [Steve Henson]
        +
        + Changes between 0.9.7b and 0.9.7c  [30 Sep 2003]
        +
        +  *) Fix various bugs revealed by running the NISCC test suite:
        +
        +     Stop out of bounds reads in the ASN1 code when presented with
        +     invalid tags (CVE-2003-0543 and CVE-2003-0544).
        +     
        +     Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545).
        +
        +     If verify callback ignores invalid public key errors don't try to check
        +     certificate signature with the NULL public key.
        +
        +     [Steve Henson]
        +
        +  *) New -ignore_err option in ocsp application to stop the server
        +     exiting on the first error in a request.
        +     [Steve Henson]
        +
        +  *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
        +     if the server requested one: as stated in TLS 1.0 and SSL 3.0
        +     specifications.
        +     [Steve Henson]
        +
        +  *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
        +     extra data after the compression methods not only for TLS 1.0
        +     but also for SSL 3.0 (as required by the specification).
        +     [Bodo Moeller; problem pointed out by Matthias Loepfe]
        +
        +  *) Change X509_certificate_type() to mark the key as exported/exportable
        +     when it's 512 *bits* long, not 512 bytes.
        +     [Richard Levitte]
        +
        +  *) Change AES_cbc_encrypt() so it outputs exact multiple of
        +     blocks during encryption.
        +     [Richard Levitte]
        +
        +  *) Various fixes to base64 BIO and non blocking I/O. On write 
        +     flushes were not handled properly if the BIO retried. On read
        +     data was not being buffered properly and had various logic bugs.
        +     This also affects blocking I/O when the data being decoded is a
        +     certain size.
        +     [Steve Henson]
        +
        +  *) Various S/MIME bugfixes and compatibility changes:
        +     output correct application/pkcs7 MIME type if
        +     PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures.
        +     Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening
        +     of files as .eml work). Correctly handle very long lines in MIME
        +     parser.
        +     [Steve Henson]
        +
        + Changes between 0.9.7a and 0.9.7b  [10 Apr 2003]
        +
        +  *) Countermeasure against the Klima-Pokorny-Rosa extension of
        +     Bleichbacher's attack on PKCS #1 v1.5 padding: treat
        +     a protocol version number mismatch like a decryption error
        +     in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
        +     [Bodo Moeller]
        +
        +  *) Turn on RSA blinding by default in the default implementation
        +     to avoid a timing attack. Applications that don't want it can call
        +     RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
        +     They would be ill-advised to do so in most cases.
        +     [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
        +
        +  *) Change RSA blinding code so that it works when the PRNG is not
        +     seeded (in this case, the secret RSA exponent is abused as
        +     an unpredictable seed -- if it is not unpredictable, there
        +     is no point in blinding anyway).  Make RSA blinding thread-safe
        +     by remembering the creator's thread ID in rsa->blinding and
        +     having all other threads use local one-time blinding factors
        +     (this requires more computation than sharing rsa->blinding, but
        +     avoids excessive locking; and if an RSA object is not shared
        +     between threads, blinding will still be very fast).
        +     [Bodo Moeller]
        +
        +  *) Fixed a typo bug that would cause ENGINE_set_default() to set an
        +     ENGINE as defaults for all supported algorithms irrespective of
        +     the 'flags' parameter. 'flags' is now honoured, so applications
        +     should make sure they are passing it correctly.
        +     [Geoff Thorpe]
        +
        +  *) Target "mingw" now allows native Windows code to be generated in
        +     the Cygwin environment as well as with the MinGW compiler.
        +     [Ulf Moeller] 
        +
        + Changes between 0.9.7 and 0.9.7a  [19 Feb 2003]
        +
        +  *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
        +     via timing by performing a MAC computation even if incorrrect
        +     block cipher padding has been found.  This is a countermeasure
        +     against active attacks where the attacker has to distinguish
        +     between bad padding and a MAC verification error. (CVE-2003-0078)
        +
        +     [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
        +     Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
        +     Martin Vuagnoux (EPFL, Ilion)]
        +
        +  *) Make the no-err option work as intended.  The intention with no-err
        +     is not to have the whole error stack handling routines removed from
        +     libcrypto, it's only intended to remove all the function name and
        +     reason texts, thereby removing some of the footprint that may not
        +     be interesting if those errors aren't displayed anyway.
        +
        +     NOTE: it's still possible for any application or module to have it's
        +     own set of error texts inserted.  The routines are there, just not
        +     used by default when no-err is given.
        +     [Richard Levitte]
        +
        +  *) Add support for FreeBSD on IA64.
        +     [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454]
        +
        +  *) Adjust DES_cbc_cksum() so it returns the same value as the MIT
        +     Kerberos function mit_des_cbc_cksum().  Before this change,
        +     the value returned by DES_cbc_cksum() was like the one from
        +     mit_des_cbc_cksum(), except the bytes were swapped.
        +     [Kevin Greaney <Kevin.Greaney@hp.com> and Richard Levitte]
        +
        +  *) Allow an application to disable the automatic SSL chain building.
        +     Before this a rather primitive chain build was always performed in
        +     ssl3_output_cert_chain(): an application had no way to send the 
        +     correct chain if the automatic operation produced an incorrect result.
        +
        +     Now the chain builder is disabled if either:
        +
        +     1. Extra certificates are added via SSL_CTX_add_extra_chain_cert().
        +
        +     2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set.
        +
        +     The reasoning behind this is that an application would not want the
        +     auto chain building to take place if extra chain certificates are
        +     present and it might also want a means of sending no additional
        +     certificates (for example the chain has two certificates and the
        +     root is omitted).
        +     [Steve Henson]
        +
        +  *) Add the possibility to build without the ENGINE framework.
        +     [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
        +
        +  *) Under Win32 gmtime() can return NULL: check return value in
        +     OPENSSL_gmtime(). Add error code for case where gmtime() fails.
        +     [Steve Henson]
        +
        +  *) DSA routines: under certain error conditions uninitialized BN objects
        +     could be freed. Solution: make sure initialization is performed early
        +     enough. (Reported and fix supplied by Ivan D Nestlerode <nestler@MIT.EDU>,
        +     Nils Larsch <nla@trustcenter.de> via PR#459)
        +     [Lutz Jaenicke]
        +
        +  *) Another fix for SSLv2 session ID handling: the session ID was incorrectly
        +     checked on reconnect on the client side, therefore session resumption
        +     could still fail with a "ssl session id is different" error. This
        +     behaviour is masked when SSL_OP_ALL is used due to
        +     SSL_OP_MICROSOFT_SESS_ID_BUG being set.
        +     Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
        +     followup to PR #377.
        +     [Lutz Jaenicke]
        +
        +  *) IA-32 assembler support enhancements: unified ELF targets, support
        +     for SCO/Caldera platforms, fix for Cygwin shared build.
        +     [Andy Polyakov]
        +
        +  *) Add support for FreeBSD on sparc64.  As a consequence, support for
        +     FreeBSD on non-x86 processors is separate from x86 processors on
        +     the config script, much like the NetBSD support.
        +     [Richard Levitte & Kris Kennaway <kris@obsecurity.org>]
        +
        + Changes between 0.9.6h and 0.9.7  [31 Dec 2002]
        +
        +  [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after
        +  OpenSSL 0.9.7.]
        +
        +  *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED
        +     code (06) was taken as the first octet of the session ID and the last
        +     octet was ignored consequently. As a result SSLv2 client side session
        +     caching could not have worked due to the session ID mismatch between
        +     client and server.
        +     Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
        +     PR #377.
        +     [Lutz Jaenicke]
        +
        +  *) Change the declaration of needed Kerberos libraries to use EX_LIBS
        +     instead of the special (and badly supported) LIBKRB5.  LIBKRB5 is
        +     removed entirely.
        +     [Richard Levitte]
        +
        +  *) The hw_ncipher.c engine requires dynamic locks.  Unfortunately, it
        +     seems that in spite of existing for more than a year, many application
        +     author have done nothing to provide the necessary callbacks, which
        +     means that this particular engine will not work properly anywhere.
        +     This is a very unfortunate situation which forces us, in the name
        +     of usability, to give the hw_ncipher.c a static lock, which is part
        +     of libcrypto.
        +     NOTE: This is for the 0.9.7 series ONLY.  This hack will never
        +     appear in 0.9.8 or later.  We EXPECT application authors to have
        +     dealt properly with this when 0.9.8 is released (unless we actually
        +     make such changes in the libcrypto locking code that changes will
        +     have to be made anyway).
        +     [Richard Levitte]
        +
        +  *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content
        +     octets have been read, EOF or an error occurs. Without this change
        +     some truncated ASN1 structures will not produce an error.
        +     [Steve Henson]
        +
        +  *) Disable Heimdal support, since it hasn't been fully implemented.
        +     Still give the possibility to force the use of Heimdal, but with
        +     warnings and a request that patches get sent to openssl-dev.
        +     [Richard Levitte]
        +
        +  *) Add the VC-CE target, introduce the WINCE sysname, and add
        +     INSTALL.WCE and appropriate conditionals to make it build.
        +     [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
        +
        +  *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and
        +     cygssl-x.y.z.dll, where x, y and z are the major, minor and
        +     edit numbers of the version.
        +     [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
        +
        +  *) Introduce safe string copy and catenation functions
        +     (BUF_strlcpy() and BUF_strlcat()).
        +     [Ben Laurie (CHATS) and Richard Levitte]
        +
        +  *) Avoid using fixed-size buffers for one-line DNs.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Add BUF_MEM_grow_clean() to avoid information leakage when
        +     resizing buffers containing secrets, and use where appropriate.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Avoid using fixed size buffers for configuration file location.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Avoid filename truncation for various CA files.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Use sizeof in preference to magic numbers.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Avoid filename truncation in cert requests.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Add assertions to check for (supposedly impossible) buffer
        +     overflows.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Don't cache truncated DNS entries in the local cache (this could
        +     potentially lead to a spoofing attack).
        +     [Ben Laurie (CHATS)]
        +
        +  *) Fix various buffers to be large enough for hex/decimal
        +     representations in a platform independent manner.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Add CRYPTO_realloc_clean() to avoid information leakage when
        +     resizing buffers containing secrets, and use where appropriate.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Add BIO_indent() to avoid much slightly worrying code to do
        +     indents.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Convert sprintf()/BIO_puts() to BIO_printf().
        +     [Ben Laurie (CHATS)]
        +
        +  *) buffer_gets() could terminate with the buffer only half
        +     full. Fixed.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Add assertions to prevent user-supplied crypto functions from
        +     overflowing internal buffers by having large block sizes, etc.
        +     [Ben Laurie (CHATS)]
        +
        +  *) New OPENSSL_assert() macro (similar to assert(), but enabled
        +     unconditionally).
        +     [Ben Laurie (CHATS)]
        +
        +  *) Eliminate unused copy of key in RC4.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Eliminate unused and incorrectly sized buffers for IV in pem.h.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Fix off-by-one error in EGD path.
        +     [Ben Laurie (CHATS)]
        +
        +  *) If RANDFILE path is too long, ignore instead of truncating.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Eliminate unused and incorrectly sized X.509 structure
        +     CBCParameter.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Eliminate unused and dangerous function knumber().
        +     [Ben Laurie (CHATS)]
        +
        +  *) Eliminate unused and dangerous structure, KSSL_ERR.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Protect against overlong session ID context length in an encoded
        +     session object. Since these are local, this does not appear to be
        +     exploitable.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Change from security patch (see 0.9.6e below) that did not affect
        +     the 0.9.6 release series:
        +
        +     Remote buffer overflow in SSL3 protocol - an attacker could
        +     supply an oversized master key in Kerberos-enabled versions.
        +     (CVE-2002-0657)
        +     [Ben Laurie (CHATS)]
        +
        +  *) Change the SSL kerb5 codes to match RFC 2712.
        +     [Richard Levitte]
        +
        +  *) Make -nameopt work fully for req and add -reqopt switch.
        +     [Michael Bell <michael.bell@rz.hu-berlin.de>, Steve Henson]
        +
        +  *) The "block size" for block ciphers in CFB and OFB mode should be 1.
        +     [Steve Henson, reported by Yngve Nysaeter Pettersen <yngve@opera.com>]
        +
        +  *) Make sure tests can be performed even if the corresponding algorithms
        +     have been removed entirely.  This was also the last step to make
        +     OpenSSL compilable with DJGPP under all reasonable conditions.
        +     [Richard Levitte, Doug Kaufman <dkaufman@rahul.net>]
        +
        +  *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT
        +     to allow version independent disabling of normally unselected ciphers,
        +     which may be activated as a side-effect of selecting a single cipher.
        +
        +     (E.g., cipher list string "RSA" enables ciphersuites that are left
        +     out of "ALL" because they do not provide symmetric encryption.
        +     "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.)
        +     [Lutz Jaenicke, Bodo Moeller]
        +
        +  *) Add appropriate support for separate platform-dependent build
        +     directories.  The recommended way to make a platform-dependent
        +     build directory is the following (tested on Linux), maybe with
        +     some local tweaks:
        +
        +	# Place yourself outside of the OpenSSL source tree.  In
        +	# this example, the environment variable OPENSSL_SOURCE
        +	# is assumed to contain the absolute OpenSSL source directory.
        +	mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
        +	cd objtree/"`uname -s`-`uname -r`-`uname -m`"
        +	(cd $OPENSSL_SOURCE; find . -type f) | while read F; do
        +		mkdir -p `dirname $F`
        +		ln -s $OPENSSL_SOURCE/$F $F
        +	done
        +
        +     To be absolutely sure not to disturb the source tree, a "make clean"
        +     is a good thing.  If it isn't successfull, don't worry about it,
        +     it probably means the source directory is very clean.
        +     [Richard Levitte]
        +
        +  *) Make sure any ENGINE control commands make local copies of string
        +     pointers passed to them whenever necessary. Otherwise it is possible
        +     the caller may have overwritten (or deallocated) the original string
        +     data when a later ENGINE operation tries to use the stored values.
        +     [Götz Babin-Ebell <babinebell@trustcenter.de>]
        +
        +  *) Improve diagnostics in file reading and command-line digests.
        +     [Ben Laurie aided and abetted by Solar Designer <solar@openwall.com>]
        +
        +  *) Add AES modes CFB and OFB to the object database.  Correct an
        +     error in AES-CFB decryption.
        +     [Richard Levitte]
        +
        +  *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this 
        +     allows existing EVP_CIPHER_CTX structures to be reused after
        +     calling EVP_*Final(). This behaviour is used by encryption
        +     BIOs and some applications. This has the side effect that
        +     applications must explicitly clean up cipher contexts with
        +     EVP_CIPHER_CTX_cleanup() or they will leak memory.
        +     [Steve Henson]
        +
        +  *) Check the values of dna and dnb in bn_mul_recursive before calling
        +     bn_mul_comba (a non zero value means the a or b arrays do not contain
        +     n2 elements) and fallback to bn_mul_normal if either is not zero.
        +     [Steve Henson]
        +
        +  *) Fix escaping of non-ASCII characters when using the -subj option
        +     of the "openssl req" command line tool. (Robert Joop <joop@fokus.gmd.de>)
        +     [Lutz Jaenicke]
        +
        +  *) Make object definitions compliant to LDAP (RFC2256): SN is the short
        +     form for "surname", serialNumber has no short form.
        +     Use "mail" as the short name for "rfc822Mailbox" according to RFC2798;
        +     therefore remove "mail" short name for "internet 7".
        +     The OID for unique identifiers in X509 certificates is
        +     x500UniqueIdentifier, not uniqueIdentifier.
        +     Some more OID additions. (Michael Bell <michael.bell@rz.hu-berlin.de>)
        +     [Lutz Jaenicke]
        +
        +  *) Add an "init" command to the ENGINE config module and auto initialize
        +     ENGINEs. Without any "init" command the ENGINE will be initialized 
        +     after all ctrl commands have been executed on it. If init=1 the 
        +     ENGINE is initailized at that point (ctrls before that point are run
        +     on the uninitialized ENGINE and after on the initialized one). If
        +     init=0 then the ENGINE will not be iniatialized at all.
        +     [Steve Henson]
        +
        +  *) Fix the 'app_verify_callback' interface so that the user-defined
        +     argument is actually passed to the callback: In the
        +     SSL_CTX_set_cert_verify_callback() prototype, the callback
        +     declaration has been changed from
        +          int (*cb)()
        +     into
        +          int (*cb)(X509_STORE_CTX *,void *);
        +     in ssl_verify_cert_chain (ssl/ssl_cert.c), the call
        +          i=s->ctx->app_verify_callback(&ctx)
        +     has been changed into
        +          i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg).
        +
        +     To update applications using SSL_CTX_set_cert_verify_callback(),
        +     a dummy argument can be added to their callback functions.
        +     [D. K. Smetters <smetters@parc.xerox.com>]
        +
        +  *) Added the '4758cca' ENGINE to support IBM 4758 cards.
        +     [Maurice Gittens <maurice@gittens.nl>, touchups by Geoff Thorpe]
        +
        +  *) Add and OPENSSL_LOAD_CONF define which will cause
        +     OpenSSL_add_all_algorithms() to load the openssl.cnf config file.
        +     This allows older applications to transparently support certain
        +     OpenSSL features: such as crypto acceleration and dynamic ENGINE loading.
        +     Two new functions OPENSSL_add_all_algorithms_noconf() which will never
        +     load the config file and OPENSSL_add_all_algorithms_conf() which will
        +     always load it have also been added.
        +     [Steve Henson]
        +
        +  *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES.
        +     Adjust NIDs and EVP layer.
        +     [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
        +
        +  *) Config modules support in openssl utility.
        +
        +     Most commands now load modules from the config file,
        +     though in a few (such as version) this isn't done 
        +     because it couldn't be used for anything.
        +
        +     In the case of ca and req the config file used is
        +     the same as the utility itself: that is the -config
        +     command line option can be used to specify an
        +     alternative file.
        +     [Steve Henson]
        +
        +  *) Move default behaviour from OPENSSL_config(). If appname is NULL
        +     use "openssl_conf" if filename is NULL use default openssl config file.
        +     [Steve Henson]
        +
        +  *) Add an argument to OPENSSL_config() to allow the use of an alternative
        +     config section name. Add a new flag to tolerate a missing config file
        +     and move code to CONF_modules_load_file().
        +     [Steve Henson]
        +
        +  *) Support for crypto accelerator cards from Accelerated Encryption
        +     Processing, www.aep.ie.  (Use engine 'aep')
        +     The support was copied from 0.9.6c [engine] and adapted/corrected
        +     to work with the new engine framework.
        +     [AEP Inc. and Richard Levitte]
        +
        +  *) Support for SureWare crypto accelerator cards from Baltimore
        +     Technologies.  (Use engine 'sureware')
        +     The support was copied from 0.9.6c [engine] and adapted
        +     to work with the new engine framework.
        +     [Richard Levitte]
        +
        +  *) Have the CHIL engine fork-safe (as defined by nCipher) and actually
        +     make the newer ENGINE framework commands for the CHIL engine work.
        +     [Toomas Kiisk <vix@cyber.ee> and Richard Levitte]
        +
        +  *) Make it possible to produce shared libraries on ReliantUNIX.
        +     [Robert Dahlem <Robert.Dahlem@ffm2.siemens.de> via Richard Levitte]
        +
        +  *) Add the configuration target debug-linux-ppro.
        +     Make 'openssl rsa' use the general key loading routines
        +     implemented in apps.c, and make those routines able to
        +     handle the key format FORMAT_NETSCAPE and the variant
        +     FORMAT_IISSGC.
        +     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
        +
        + *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
        +     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
        +
        +  *) Add -keyform to rsautl, and document -engine.
        +     [Richard Levitte, inspired by Toomas Kiisk <vix@cyber.ee>]
        +
        +  *) Change BIO_new_file (crypto/bio/bss_file.c) to use new
        +     BIO_R_NO_SUCH_FILE error code rather than the generic
        +     ERR_R_SYS_LIB error code if fopen() fails with ENOENT.
        +     [Ben Laurie]
        +
        +  *) Add new functions
        +          ERR_peek_last_error
        +          ERR_peek_last_error_line
        +          ERR_peek_last_error_line_data.
        +     These are similar to
        +          ERR_peek_error
        +          ERR_peek_error_line
        +          ERR_peek_error_line_data,
        +     but report on the latest error recorded rather than the first one
        +     still in the error queue.
        +     [Ben Laurie, Bodo Moeller]
        +        
        +  *) default_algorithms option in ENGINE config module. This allows things
        +     like:
        +     default_algorithms = ALL
        +     default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS
        +     [Steve Henson]
        +
        +  *) Prelminary ENGINE config module.
        +     [Steve Henson]
        +
        +  *) New experimental application configuration code.
        +     [Steve Henson]
        +
        +  *) Change the AES code to follow the same name structure as all other
        +     symmetric ciphers, and behave the same way.  Move everything to
        +     the directory crypto/aes, thereby obsoleting crypto/rijndael.
        +     [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
        +
        +  *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c.
        +     [Ben Laurie and Theo de Raadt]
        +
        +  *) Add option to output public keys in req command.
        +     [Massimiliano Pala madwolf@openca.org]
        +
        +  *) Use wNAFs in EC_POINTs_mul() for improved efficiency
        +     (up to about 10% better than before for P-192 and P-224).
        +     [Bodo Moeller]
        +
        +  *) New functions/macros
        +
        +          SSL_CTX_set_msg_callback(ctx, cb)
        +          SSL_CTX_set_msg_callback_arg(ctx, arg)
        +          SSL_set_msg_callback(ssl, cb)
        +          SSL_set_msg_callback_arg(ssl, arg)
        +
        +     to request calling a callback function
        +
        +          void cb(int write_p, int version, int content_type,
        +                  const void *buf, size_t len, SSL *ssl, void *arg)
        +
        +     whenever a protocol message has been completely received
        +     (write_p == 0) or sent (write_p == 1).  Here 'version' is the
        +     protocol version  according to which the SSL library interprets
        +     the current protocol message (SSL2_VERSION, SSL3_VERSION, or
        +     TLS1_VERSION).  'content_type' is 0 in the case of SSL 2.0, or
        +     the content type as defined in the SSL 3.0/TLS 1.0 protocol
        +     specification (change_cipher_spec(20), alert(21), handshake(22)).
        +     'buf' and 'len' point to the actual message, 'ssl' to the
        +     SSL object, and 'arg' is the application-defined value set by
        +     SSL[_CTX]_set_msg_callback_arg().
        +
        +     'openssl s_client' and 'openssl s_server' have new '-msg' options
        +     to enable a callback that displays all protocol messages.
        +     [Bodo Moeller]
        +
        +  *) Change the shared library support so shared libraries are built as
        +     soon as the corresponding static library is finished, and thereby get
        +     openssl and the test programs linked against the shared library.
        +     This still only happens when the keyword "shard" has been given to
        +     the configuration scripts.
        +
        +     NOTE: shared library support is still an experimental thing, and
        +     backward binary compatibility is still not guaranteed.
        +     ["Maciej W. Rozycki" <macro@ds2.pg.gda.pl> and Richard Levitte]
        +
        +  *) Add support for Subject Information Access extension.
        +     [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
        +
        +  *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero
        +     additional bytes when new memory had to be allocated, not just
        +     when reusing an existing buffer.
        +     [Bodo Moeller]
        +
        +  *) New command line and configuration option 'utf8' for the req command.
        +     This allows field values to be specified as UTF8 strings.
        +     [Steve Henson]
        +
        +  *) Add -multi and -mr options to "openssl speed" - giving multiple parallel
        +     runs for the former and machine-readable output for the latter.
        +     [Ben Laurie]
        +
        +  *) Add '-noemailDN' option to 'openssl ca'.  This prevents inclusion
        +     of the e-mail address in the DN (i.e., it will go into a certificate
        +     extension only).  The new configuration file option 'email_in_dn = no'
        +     has the same effect.
        +     [Massimiliano Pala madwolf@openca.org]
        +
        +  *) Change all functions with names starting with des_ to be starting
        +     with DES_ instead.  Add wrappers that are compatible with libdes,
        +     but are named _ossl_old_des_*.  Finally, add macros that map the
        +     des_* symbols to the corresponding _ossl_old_des_* if libdes
        +     compatibility is desired.  If OpenSSL 0.9.6c compatibility is
        +     desired, the des_* symbols will be mapped to DES_*, with one
        +     exception.
        +
        +     Since we provide two compatibility mappings, the user needs to
        +     define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes
        +     compatibility is desired.  The default (i.e., when that macro
        +     isn't defined) is OpenSSL 0.9.6c compatibility.
        +
        +     There are also macros that enable and disable the support of old
        +     des functions altogether.  Those are OPENSSL_ENABLE_OLD_DES_SUPPORT
        +     and OPENSSL_DISABLE_OLD_DES_SUPPORT.  If none or both of those
        +     are defined, the default will apply: to support the old des routines.
        +
        +     In either case, one must include openssl/des.h to get the correct
        +     definitions.  Do not try to just include openssl/des_old.h, that
        +     won't work.
        +
        +     NOTE: This is a major break of an old API into a new one.  Software
        +     authors are encouraged to switch to the DES_ style functions.  Some
        +     time in the future, des_old.h and the libdes compatibility functions
        +     will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the
        +     default), and then completely removed.
        +     [Richard Levitte]
        +
        +  *) Test for certificates which contain unsupported critical extensions.
        +     If such a certificate is found during a verify operation it is 
        +     rejected by default: this behaviour can be overridden by either
        +     handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or
        +     by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function
        +     X509_supported_extension() has also been added which returns 1 if a
        +     particular extension is supported.
        +     [Steve Henson]
        +
        +  *) Modify the behaviour of EVP cipher functions in similar way to digests
        +     to retain compatibility with existing code.
        +     [Steve Henson]
        +
        +  *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain
        +     compatibility with existing code. In particular the 'ctx' parameter does
        +     not have to be to be initialized before the call to EVP_DigestInit() and
        +     it is tidied up after a call to EVP_DigestFinal(). New function
        +     EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function
        +     EVP_MD_CTX_copy() changed to not require the destination to be
        +     initialized valid and new function EVP_MD_CTX_copy_ex() added which
        +     requires the destination to be valid.
        +
        +     Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(),
        +     EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex().
        +     [Steve Henson]
        +
        +  *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it
        +     so that complete 'Handshake' protocol structures are kept in memory
        +     instead of overwriting 'msg_type' and 'length' with 'body' data.
        +     [Bodo Moeller]
        +
        +  *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32.
        +     [Massimo Santin via Richard Levitte]
        +
        +  *) Major restructuring to the underlying ENGINE code. This includes
        +     reduction of linker bloat, separation of pure "ENGINE" manipulation
        +     (initialisation, etc) from functionality dealing with implementations
        +     of specific crypto iterfaces. This change also introduces integrated
        +     support for symmetric ciphers and digest implementations - so ENGINEs
        +     can now accelerate these by providing EVP_CIPHER and EVP_MD
        +     implementations of their own. This is detailed in crypto/engine/README
        +     as it couldn't be adequately described here. However, there are a few
        +     API changes worth noting - some RSA, DSA, DH, and RAND functions that
        +     were changed in the original introduction of ENGINE code have now
        +     reverted back - the hooking from this code to ENGINE is now a good
        +     deal more passive and at run-time, operations deal directly with
        +     RSA_METHODs, DSA_METHODs (etc) as they did before, rather than
        +     dereferencing through an ENGINE pointer any more. Also, the ENGINE
        +     functions dealing with BN_MOD_EXP[_CRT] handlers have been removed -
        +     they were not being used by the framework as there is no concept of a
        +     BIGNUM_METHOD and they could not be generalised to the new
        +     'ENGINE_TABLE' mechanism that underlies the new code. Similarly,
        +     ENGINE_cpy() has been removed as it cannot be consistently defined in
        +     the new code.
        +     [Geoff Thorpe]
        +
        +  *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds.
        +     [Steve Henson]
        +
        +  *) Change mkdef.pl to sort symbols that get the same entry number,
        +     and make sure the automatically generated functions ERR_load_*
        +     become part of libeay.num as well.
        +     [Richard Levitte]
        +
        +  *) New function SSL_renegotiate_pending().  This returns true once
        +     renegotiation has been requested (either SSL_renegotiate() call
        +     or HelloRequest/ClientHello receveived from the peer) and becomes
        +     false once a handshake has been completed.
        +     (For servers, SSL_renegotiate() followed by SSL_do_handshake()
        +     sends a HelloRequest, but does not ensure that a handshake takes
        +     place.  SSL_renegotiate_pending() is useful for checking if the
        +     client has followed the request.)
        +     [Bodo Moeller]
        +
        +  *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION.
        +     By default, clients may request session resumption even during
        +     renegotiation (if session ID contexts permit); with this option,
        +     session resumption is possible only in the first handshake.
        +
        +     SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL.  This makes
        +     more bits available for options that should not be part of
        +     SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION).
        +     [Bodo Moeller]
        +
        +  *) Add some demos for certificate and certificate request creation.
        +     [Steve Henson]
        +
        +  *) Make maximum certificate chain size accepted from the peer application
        +     settable (SSL*_get/set_max_cert_list()), as proposed by
        +     "Douglas E. Engert" <deengert@anl.gov>.
        +     [Lutz Jaenicke]
        +
        +  *) Add support for shared libraries for Unixware-7
        +     (Boyd Lynn Gerber <gerberb@zenez.com>).
        +     [Lutz Jaenicke]
        +
        +  *) Add a "destroy" handler to ENGINEs that allows structural cleanup to
        +     be done prior to destruction. Use this to unload error strings from
        +     ENGINEs that load their own error strings. NB: This adds two new API
        +     functions to "get" and "set" this destroy handler in an ENGINE.
        +     [Geoff Thorpe]
        +
        +  *) Alter all existing ENGINE implementations (except "openssl" and
        +     "openbsd") to dynamically instantiate their own error strings. This
        +     makes them more flexible to be built both as statically-linked ENGINEs
        +     and self-contained shared-libraries loadable via the "dynamic" ENGINE.
        +     Also, add stub code to each that makes building them as self-contained
        +     shared-libraries easier (see README.ENGINE).
        +     [Geoff Thorpe]
        +
        +  *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE
        +     implementations into applications that are completely implemented in
        +     self-contained shared-libraries. The "dynamic" ENGINE exposes control
        +     commands that can be used to configure what shared-library to load and
        +     to control aspects of the way it is handled. Also, made an update to
        +     the README.ENGINE file that brings its information up-to-date and
        +     provides some information and instructions on the "dynamic" ENGINE
        +     (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc).
        +     [Geoff Thorpe]
        +
        +  *) Make it possible to unload ranges of ERR strings with a new
        +     "ERR_unload_strings" function.
        +     [Geoff Thorpe]
        +
        +  *) Add a copy() function to EVP_MD.
        +     [Ben Laurie]
        +
        +  *) Make EVP_MD routines take a context pointer instead of just the
        +     md_data void pointer.
        +     [Ben Laurie]
        +
        +  *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates
        +     that the digest can only process a single chunk of data
        +     (typically because it is provided by a piece of
        +     hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application
        +     is only going to provide a single chunk of data, and hence the
        +     framework needn't accumulate the data for oneshot drivers.
        +     [Ben Laurie]
        +
        +  *) As with "ERR", make it possible to replace the underlying "ex_data"
        +     functions. This change also alters the storage and management of global
        +     ex_data state - it's now all inside ex_data.c and all "class" code (eg.
        +     RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class
        +     index counters. The API functions that use this state have been changed
        +     to take a "class_index" rather than pointers to the class's local STACK
        +     and counter, and there is now an API function to dynamically create new
        +     classes. This centralisation allows us to (a) plug a lot of the
        +     thread-safety problems that existed, and (b) makes it possible to clean
        +     up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b)
        +     such data would previously have always leaked in application code and
        +     workarounds were in place to make the memory debugging turn a blind eye
        +     to it. Application code that doesn't use this new function will still
        +     leak as before, but their memory debugging output will announce it now
        +     rather than letting it slide.
        +
        +     Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change
        +     induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now
        +     has a return value to indicate success or failure.
        +     [Geoff Thorpe]
        +
        +  *) Make it possible to replace the underlying "ERR" functions such that the
        +     global state (2 LHASH tables and 2 locks) is only used by the "default"
        +     implementation. This change also adds two functions to "get" and "set"
        +     the implementation prior to it being automatically set the first time
        +     any other ERR function takes place. Ie. an application can call "get",
        +     pass the return value to a module it has just loaded, and that module
        +     can call its own "set" function using that value. This means the
        +     module's "ERR" operations will use (and modify) the error state in the
        +     application and not in its own statically linked copy of OpenSSL code.
        +     [Geoff Thorpe]
        +
        +  *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment
        +     reference counts. This performs normal REF_PRINT/REF_CHECK macros on
        +     the operation, and provides a more encapsulated way for external code
        +     (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code
        +     to use these functions rather than manually incrementing the counts.
        +
        +     Also rename "DSO_up()" function to more descriptive "DSO_up_ref()".
        +     [Geoff Thorpe]
        +
        +  *) Add EVP test program.
        +     [Ben Laurie]
        +
        +  *) Add symmetric cipher support to ENGINE. Expect the API to change!
        +     [Ben Laurie]
        +
        +  *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name()
        +     X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(),
        +     X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate().
        +     These allow a CRL to be built without having to access X509_CRL fields
        +     directly. Modify 'ca' application to use new functions.
        +     [Steve Henson]
        +
        +  *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended
        +     bug workarounds. Rollback attack detection is a security feature.
        +     The problem will only arise on OpenSSL servers when TLSv1 is not
        +     available (sslv3_server_method() or SSL_OP_NO_TLSv1).
        +     Software authors not wanting to support TLSv1 will have special reasons
        +     for their choice and can explicitly enable this option.
        +     [Bodo Moeller, Lutz Jaenicke]
        +
        +  *) Rationalise EVP so it can be extended: don't include a union of
        +     cipher/digest structures, add init/cleanup functions for EVP_MD_CTX
        +     (similar to those existing for EVP_CIPHER_CTX).
        +     Usage example:
        +
        +         EVP_MD_CTX md;
        +
        +         EVP_MD_CTX_init(&md);             /* new function call */
        +         EVP_DigestInit(&md, EVP_sha1());
        +         EVP_DigestUpdate(&md, in, len);
        +         EVP_DigestFinal(&md, out, NULL);
        +         EVP_MD_CTX_cleanup(&md);          /* new function call */
        +
        +     [Ben Laurie]
        +
        +  *) Make DES key schedule conform to the usual scheme, as well as
        +     correcting its structure. This means that calls to DES functions
        +     now have to pass a pointer to a des_key_schedule instead of a
        +     plain des_key_schedule (which was actually always a pointer
        +     anyway): E.g.,
        +
        +         des_key_schedule ks;
        +
        +	 des_set_key_checked(..., &ks);
        +	 des_ncbc_encrypt(..., &ks, ...);
        +
        +     (Note that a later change renames 'des_...' into 'DES_...'.)
        +     [Ben Laurie]
        +
        +  *) Initial reduction of linker bloat: the use of some functions, such as
        +     PEM causes large amounts of unused functions to be linked in due to
        +     poor organisation. For example pem_all.c contains every PEM function
        +     which has a knock on effect of linking in large amounts of (unused)
        +     ASN1 code. Grouping together similar functions and splitting unrelated
        +     functions prevents this.
        +     [Steve Henson]
        +
        +  *) Cleanup of EVP macros.
        +     [Ben Laurie]
        +
        +  *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the
        +     correct _ecb suffix.
        +     [Ben Laurie]
        +
        +  *) Add initial OCSP responder support to ocsp application. The
        +     revocation information is handled using the text based index
        +     use by the ca application. The responder can either handle
        +     requests generated internally, supplied in files (for example
        +     via a CGI script) or using an internal minimal server.
        +     [Steve Henson]
        +
        +  *) Add configuration choices to get zlib compression for TLS.
        +     [Richard Levitte]
        +
        +  *) Changes to Kerberos SSL for RFC 2712 compliance:
        +     1.  Implemented real KerberosWrapper, instead of just using
        +         KRB5 AP_REQ message.  [Thanks to Simon Wilkinson <sxw@sxw.org.uk>]
        +     2.  Implemented optional authenticator field of KerberosWrapper.
        +
        +     Added openssl-style ASN.1 macros for Kerberos ticket, ap_req,
        +     and authenticator structs; see crypto/krb5/.
        +
        +     Generalized Kerberos calls to support multiple Kerberos libraries.
        +     [Vern Staats <staatsvr@asc.hpc.mil>,
        +      Jeffrey Altman <jaltman@columbia.edu>
        +      via Richard Levitte]
        +
        +  *) Cause 'openssl speed' to use fully hard-coded DSA keys as it
        +     already does with RSA. testdsa.h now has 'priv_key/pub_key'
        +     values for each of the key sizes rather than having just
        +     parameters (and 'speed' generating keys each time).
        +     [Geoff Thorpe]
        +
        +  *) Speed up EVP routines.
        +     Before:
        +encrypt
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +des-cbc           4408.85k     5560.51k     5778.46k     5862.20k     5825.16k
        +des-cbc           4389.55k     5571.17k     5792.23k     5846.91k     5832.11k
        +des-cbc           4394.32k     5575.92k     5807.44k     5848.37k     5841.30k
        +decrypt
        +des-cbc           3482.66k     5069.49k     5496.39k     5614.16k     5639.28k
        +des-cbc           3480.74k     5068.76k     5510.34k     5609.87k     5635.52k
        +des-cbc           3483.72k     5067.62k     5504.60k     5708.01k     5724.80k
        +     After:
        +encrypt
        +des-cbc           4660.16k     5650.19k     5807.19k     5827.13k     5783.32k
        +decrypt
        +des-cbc           3624.96k     5258.21k     5530.91k     5624.30k     5628.26k
        +     [Ben Laurie]
        +
        +  *) Added the OS2-EMX target.
        +     ["Brian Havard" <brianh@kheldar.apana.org.au> and Richard Levitte]
        +
        +  *) Rewrite apps to use NCONF routines instead of the old CONF. New functions
        +     to support NCONF routines in extension code. New function CONF_set_nconf()
        +     to allow functions which take an NCONF to also handle the old LHASH
        +     structure: this means that the old CONF compatible routines can be
        +     retained (in particular wrt extensions) without having to duplicate the
        +     code. New function X509V3_add_ext_nconf_sk to add extensions to a stack.
        +     [Steve Henson]
        +
        +  *) Enhance the general user interface with mechanisms for inner control
        +     and with possibilities to have yes/no kind of prompts.
        +     [Richard Levitte]
        +
        +  *) Change all calls to low level digest routines in the library and
        +     applications to use EVP. Add missing calls to HMAC_cleanup() and
        +     don't assume HMAC_CTX can be copied using memcpy().
        +     [Verdon Walker <VWalker@novell.com>, Steve Henson]
        +
        +  *) Add the possibility to control engines through control names but with
        +     arbitrary arguments instead of just a string.
        +     Change the key loaders to take a UI_METHOD instead of a callback
        +     function pointer.  NOTE: this breaks binary compatibility with earlier
        +     versions of OpenSSL [engine].
        +     Adapt the nCipher code for these new conditions and add a card insertion
        +     callback.
        +     [Richard Levitte]
        +
        +  *) Enhance the general user interface with mechanisms to better support
        +     dialog box interfaces, application-defined prompts, the possibility
        +     to use defaults (for example default passwords from somewhere else)
        +     and interrupts/cancellations.
        +     [Richard Levitte]
        +
        +  *) Tidy up PKCS#12 attribute handling. Add support for the CSP name
        +     attribute in PKCS#12 files, add new -CSP option to pkcs12 utility.
        +     [Steve Henson]
        +
        +  *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also
        +     tidy up some unnecessarily weird code in 'sk_new()').
        +     [Geoff, reported by Diego Tartara <dtartara@novamens.com>]
        +
        +  *) Change the key loading routines for ENGINEs to use the same kind
        +     callback (pem_password_cb) as all other routines that need this
        +     kind of callback.
        +     [Richard Levitte]
        +
        +  *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with
        +     256 bit (=32 byte) keys. Of course seeding with more entropy bytes
        +     than this minimum value is recommended.
        +     [Lutz Jaenicke]
        +
        +  *) New random seeder for OpenVMS, using the system process statistics
        +     that are easily reachable.
        +     [Richard Levitte]
        +
        +  *) Windows apparently can't transparently handle global
        +     variables defined in DLLs. Initialisations such as:
        +
        +        const ASN1_ITEM *it = &ASN1_INTEGER_it;
        +
        +     wont compile. This is used by the any applications that need to
        +     declare their own ASN1 modules. This was fixed by adding the option
        +     EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly
        +     needed for static libraries under Win32.
        +     [Steve Henson]
        +
        +  *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle
        +     setting of purpose and trust fields. New X509_STORE trust and
        +     purpose functions and tidy up setting in other SSL functions.
        +     [Steve Henson]
        +
        +  *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE
        +     structure. These are inherited by X509_STORE_CTX when it is 
        +     initialised. This allows various defaults to be set in the
        +     X509_STORE structure (such as flags for CRL checking and custom
        +     purpose or trust settings) for functions which only use X509_STORE_CTX
        +     internally such as S/MIME.
        +
        +     Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and
        +     trust settings if they are not set in X509_STORE. This allows X509_STORE
        +     purposes and trust (in S/MIME for example) to override any set by default.
        +
        +     Add command line options for CRL checking to smime, s_client and s_server
        +     applications.
        +     [Steve Henson]
        +
        +  *) Initial CRL based revocation checking. If the CRL checking flag(s)
        +     are set then the CRL is looked up in the X509_STORE structure and
        +     its validity and signature checked, then if the certificate is found
        +     in the CRL the verify fails with a revoked error.
        +
        +     Various new CRL related callbacks added to X509_STORE_CTX structure.
        +
        +     Command line options added to 'verify' application to support this.
        +
        +     This needs some additional work, such as being able to handle multiple
        +     CRLs with different times, extension based lookup (rather than just
        +     by subject name) and ultimately more complete V2 CRL extension
        +     handling.
        +     [Steve Henson]
        +
        +  *) Add a general user interface API (crypto/ui/).  This is designed
        +     to replace things like des_read_password and friends (backward
        +     compatibility functions using this new API are provided).
        +     The purpose is to remove prompting functions from the DES code
        +     section as well as provide for prompting through dialog boxes in
        +     a window system and the like.
        +     [Richard Levitte]
        +
        +  *) Add "ex_data" support to ENGINE so implementations can add state at a
        +     per-structure level rather than having to store it globally.
        +     [Geoff]
        +
        +  *) Make it possible for ENGINE structures to be copied when retrieved by
        +     ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY.
        +     This causes the "original" ENGINE structure to act like a template,
        +     analogous to the RSA vs. RSA_METHOD type of separation. Because of this
        +     operational state can be localised to each ENGINE structure, despite the
        +     fact they all share the same "methods". New ENGINE structures returned in
        +     this case have no functional references and the return value is the single
        +     structural reference. This matches the single structural reference returned
        +     by ENGINE_by_id() normally, when it is incremented on the pre-existing
        +     ENGINE structure.
        +     [Geoff]
        +
        +  *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this
        +     needs to match any other type at all we need to manually clear the
        +     tag cache.
        +     [Steve Henson]
        +
        +  *) Changes to the "openssl engine" utility to include;
        +     - verbosity levels ('-v', '-vv', and '-vvv') that provide information
        +       about an ENGINE's available control commands.
        +     - executing control commands from command line arguments using the
        +       '-pre' and '-post' switches. '-post' is only used if '-t' is
        +       specified and the ENGINE is successfully initialised. The syntax for
        +       the individual commands are colon-separated, for example;
        +	 openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so
        +     [Geoff]
        +
        +  *) New dynamic control command support for ENGINEs. ENGINEs can now
        +     declare their own commands (numbers), names (strings), descriptions,
        +     and input types for run-time discovery by calling applications. A
        +     subset of these commands are implicitly classed as "executable"
        +     depending on their input type, and only these can be invoked through
        +     the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this
        +     can be based on user input, config files, etc). The distinction is
        +     that "executable" commands cannot return anything other than a boolean
        +     result and can only support numeric or string input, whereas some
        +     discoverable commands may only be for direct use through
        +     ENGINE_ctrl(), eg. supporting the exchange of binary data, function
        +     pointers, or other custom uses. The "executable" commands are to
        +     support parameterisations of ENGINE behaviour that can be
        +     unambiguously defined by ENGINEs and used consistently across any
        +     OpenSSL-based application. Commands have been added to all the
        +     existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow
        +     control over shared-library paths without source code alterations.
        +     [Geoff]
        +
        +  *) Changed all ENGINE implementations to dynamically allocate their
        +     ENGINEs rather than declaring them statically. Apart from this being
        +     necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction,
        +     this also allows the implementations to compile without using the
        +     internal engine_int.h header.
        +     [Geoff]
        +
        +  *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a
        +     'const' value. Any code that should be able to modify a RAND_METHOD
        +     should already have non-const pointers to it (ie. they should only
        +     modify their own ones).
        +     [Geoff]
        +
        +  *) Made a variety of little tweaks to the ENGINE code.
        +     - "atalla" and "ubsec" string definitions were moved from header files
        +       to C code. "nuron" string definitions were placed in variables
        +       rather than hard-coded - allowing parameterisation of these values
        +       later on via ctrl() commands.
        +     - Removed unused "#if 0"'d code.
        +     - Fixed engine list iteration code so it uses ENGINE_free() to release
        +       structural references.
        +     - Constified the RAND_METHOD element of ENGINE structures.
        +     - Constified various get/set functions as appropriate and added
        +       missing functions (including a catch-all ENGINE_cpy that duplicates
        +       all ENGINE values onto a new ENGINE except reference counts/state).
        +     - Removed NULL parameter checks in get/set functions. Setting a method
        +       or function to NULL is a way of cancelling out a previously set
        +       value.  Passing a NULL ENGINE parameter is just plain stupid anyway
        +       and doesn't justify the extra error symbols and code.
        +     - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for
        +       flags from engine_int.h to engine.h.
        +     - Changed prototypes for ENGINE handler functions (init(), finish(),
        +       ctrl(), key-load functions, etc) to take an (ENGINE*) parameter.
        +     [Geoff]
        +
        +  *) Implement binary inversion algorithm for BN_mod_inverse in addition
        +     to the algorithm using long division.  The binary algorithm can be
        +     used only if the modulus is odd.  On 32-bit systems, it is faster
        +     only for relatively small moduli (roughly 20-30% for 128-bit moduli,
        +     roughly 5-15% for 256-bit moduli), so we use it only for moduli
        +     up to 450 bits.  In 64-bit environments, the binary algorithm
        +     appears to be advantageous for much longer moduli; here we use it
        +     for moduli up to 2048 bits.
        +     [Bodo Moeller]
        +
        +  *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code
        +     could not support the combine flag in choice fields.
        +     [Steve Henson]
        +
        +  *) Add a 'copy_extensions' option to the 'ca' utility. This copies
        +     extensions from a certificate request to the certificate.
        +     [Steve Henson]
        +
        +  *) Allow multiple 'certopt' and 'nameopt' options to be separated
        +     by commas. Add 'namopt' and 'certopt' options to the 'ca' config
        +     file: this allows the display of the certificate about to be
        +     signed to be customised, to allow certain fields to be included
        +     or excluded and extension details. The old system didn't display
        +     multicharacter strings properly, omitted fields not in the policy
        +     and couldn't display additional details such as extensions.
        +     [Steve Henson]
        +
        +  *) Function EC_POINTs_mul for multiple scalar multiplication
        +     of an arbitrary number of elliptic curve points
        +          \sum scalars[i]*points[i],
        +     optionally including the generator defined for the EC_GROUP:
        +          scalar*generator +  \sum scalars[i]*points[i].
        +
        +     EC_POINT_mul is a simple wrapper function for the typical case
        +     that the point list has just one item (besides the optional
        +     generator).
        +     [Bodo Moeller]
        +
        +  *) First EC_METHODs for curves over GF(p):
        +
        +     EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr
        +     operations and provides various method functions that can also
        +     operate with faster implementations of modular arithmetic.     
        +
        +     EC_GFp_mont_method() reuses most functions that are part of
        +     EC_GFp_simple_method, but uses Montgomery arithmetic.
        +
        +     [Bodo Moeller; point addition and point doubling
        +     implementation directly derived from source code provided by
        +     Lenka Fibikova <fibikova@exp-math.uni-essen.de>]
        +
        +  *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h,
        +     crypto/ec/ec_lib.c):
        +
        +     Curves are EC_GROUP objects (with an optional group generator)
        +     based on EC_METHODs that are built into the library.
        +
        +     Points are EC_POINT objects based on EC_GROUP objects.
        +
        +     Most of the framework would be able to handle curves over arbitrary
        +     finite fields, but as there are no obvious types for fields other
        +     than GF(p), some functions are limited to that for now.
        +     [Bodo Moeller]
        +
        +  *) Add the -HTTP option to s_server.  It is similar to -WWW, but requires
        +     that the file contains a complete HTTP response.
        +     [Richard Levitte]
        +
        +  *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl
        +     change the def and num file printf format specifier from "%-40sXXX"
        +     to "%-39s XXX". The latter will always guarantee a space after the
        +     field while the former will cause them to run together if the field
        +     is 40 of more characters long.
        +     [Steve Henson]
        +
        +  *) Constify the cipher and digest 'method' functions and structures
        +     and modify related functions to take constant EVP_MD and EVP_CIPHER
        +     pointers.
        +     [Steve Henson]
        +
        +  *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them
        +     in <openssl/bn.h>.  Also further increase BN_CTX_NUM to 32.
        +     [Bodo Moeller]
        +
        +  *) Modify EVP_Digest*() routines so they now return values. Although the
        +     internal software routines can never fail additional hardware versions
        +     might.
        +     [Steve Henson]
        +
        +  *) Clean up crypto/err/err.h and change some error codes to avoid conflicts:
        +
        +     Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7
        +     (= ERR_R_PKCS7_LIB); it is now 64 instead of 32.
        +
        +     ASN1 error codes
        +          ERR_R_NESTED_ASN1_ERROR
        +          ...
        +          ERR_R_MISSING_ASN1_EOS
        +     were 4 .. 9, conflicting with
        +          ERR_LIB_RSA (= ERR_R_RSA_LIB)
        +          ...
        +          ERR_LIB_PEM (= ERR_R_PEM_LIB).
        +     They are now 58 .. 63 (i.e., just below ERR_R_FATAL).
        +
        +     Add new error code 'ERR_R_INTERNAL_ERROR'.
        +     [Bodo Moeller]
        +
        +  *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock
        +     suffices.
        +     [Bodo Moeller]
        +
        +  *) New option '-subj arg' for 'openssl req' and 'openssl ca'.  This
        +     sets the subject name for a new request or supersedes the
        +     subject name in a given request. Formats that can be parsed are
        +          'CN=Some Name, OU=myOU, C=IT'
        +     and
        +          'CN=Some Name/OU=myOU/C=IT'.
        +
        +     Add options '-batch' and '-verbose' to 'openssl req'.
        +     [Massimiliano Pala <madwolf@hackmasters.net>]
        +
        +  *) Introduce the possibility to access global variables through
        +     functions on platform were that's the best way to handle exporting
        +     global variables in shared libraries.  To enable this functionality,
        +     one must configure with "EXPORT_VAR_AS_FN" or defined the C macro
        +     "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter
        +     is normally done by Configure or something similar).
        +
        +     To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL
        +     in the source file (foo.c) like this:
        +
        +	OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1;
        +	OPENSSL_IMPLEMENT_GLOBAL(double,bar);
        +
        +     To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL
        +     and OPENSSL_GLOBAL_REF in the header file (foo.h) like this:
        +
        +	OPENSSL_DECLARE_GLOBAL(int,foo);
        +	#define foo OPENSSL_GLOBAL_REF(foo)
        +	OPENSSL_DECLARE_GLOBAL(double,bar);
        +	#define bar OPENSSL_GLOBAL_REF(bar)
        +
        +     The #defines are very important, and therefore so is including the
        +     header file everywhere where the defined globals are used.
        +
        +     The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition
        +     of ASN.1 items, but that structure is a bit different.
        +
        +     The largest change is in util/mkdef.pl which has been enhanced with
        +     better and easier to understand logic to choose which symbols should
        +     go into the Windows .def files as well as a number of fixes and code
        +     cleanup (among others, algorithm keywords are now sorted
        +     lexicographically to avoid constant rewrites).
        +     [Richard Levitte]
        +
        +  *) In BN_div() keep a copy of the sign of 'num' before writing the
        +     result to 'rm' because if rm==num the value will be overwritten
        +     and produce the wrong result if 'num' is negative: this caused
        +     problems with BN_mod() and BN_nnmod().
        +     [Steve Henson]
        +
        +  *) Function OCSP_request_verify(). This checks the signature on an
        +     OCSP request and verifies the signer certificate. The signer
        +     certificate is just checked for a generic purpose and OCSP request
        +     trust settings.
        +     [Steve Henson]
        +
        +  *) Add OCSP_check_validity() function to check the validity of OCSP
        +     responses. OCSP responses are prepared in real time and may only
        +     be a few seconds old. Simply checking that the current time lies
        +     between thisUpdate and nextUpdate max reject otherwise valid responses
        +     caused by either OCSP responder or client clock inaccuracy. Instead
        +     we allow thisUpdate and nextUpdate to fall within a certain period of
        +     the current time. The age of the response can also optionally be
        +     checked. Two new options -validity_period and -status_age added to
        +     ocsp utility.
        +     [Steve Henson]
        +
        +  *) If signature or public key algorithm is unrecognized print out its
        +     OID rather that just UNKNOWN.
        +     [Steve Henson]
        +
        +  *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and
        +     OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate
        +     ID to be generated from the issuer certificate alone which can then be
        +     passed to OCSP_id_issuer_cmp().
        +     [Steve Henson]
        +
        +  *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new
        +     ASN1 modules to export functions returning ASN1_ITEM pointers
        +     instead of the ASN1_ITEM structures themselves. This adds several
        +     new macros which allow the underlying ASN1 function/structure to
        +     be accessed transparently. As a result code should not use ASN1_ITEM
        +     references directly (such as &X509_it) but instead use the relevant
        +     macros (such as ASN1_ITEM_rptr(X509)). This option is to allow
        +     use of the new ASN1 code on platforms where exporting structures
        +     is problematical (for example in shared libraries) but exporting
        +     functions returning pointers to structures is not.
        +     [Steve Henson]
        +
        +  *) Add support for overriding the generation of SSL/TLS session IDs.
        +     These callbacks can be registered either in an SSL_CTX or per SSL.
        +     The purpose of this is to allow applications to control, if they wish,
        +     the arbitrary values chosen for use as session IDs, particularly as it
        +     can be useful for session caching in multiple-server environments. A
        +     command-line switch for testing this (and any client code that wishes
        +     to use such a feature) has been added to "s_server".
        +     [Geoff Thorpe, Lutz Jaenicke]
        +
        +  *) Modify mkdef.pl to recognise and parse preprocessor conditionals
        +     of the form '#if defined(...) || defined(...) || ...' and
        +     '#if !defined(...) && !defined(...) && ...'.  This also avoids
        +     the growing number of special cases it was previously handling.
        +     [Richard Levitte]
        +
        +  *) Make all configuration macros available for application by making
        +     sure they are available in opensslconf.h, by giving them names starting
        +     with "OPENSSL_" to avoid conflicts with other packages and by making
        +     sure e_os2.h will cover all platform-specific cases together with
        +     opensslconf.h.
        +     Additionally, it is now possible to define configuration/platform-
        +     specific names (called "system identities").  In the C code, these
        +     are prefixed with "OPENSSL_SYSNAME_".  e_os2.h will create another
        +     macro with the name beginning with "OPENSSL_SYS_", which is determined
        +     from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on
        +     what is available.
        +     [Richard Levitte]
        +
        +  *) New option -set_serial to 'req' and 'x509' this allows the serial
        +     number to use to be specified on the command line. Previously self
        +     signed certificates were hard coded with serial number 0 and the 
        +     CA options of 'x509' had to use a serial number in a file which was
        +     auto incremented.
        +     [Steve Henson]
        +
        +  *) New options to 'ca' utility to support V2 CRL entry extensions.
        +     Currently CRL reason, invalidity date and hold instruction are
        +     supported. Add new CRL extensions to V3 code and some new objects.
        +     [Steve Henson]
        +
        +  *) New function EVP_CIPHER_CTX_set_padding() this is used to
        +     disable standard block padding (aka PKCS#5 padding) in the EVP
        +     API, which was previously mandatory. This means that the data is
        +     not padded in any way and so the total length much be a multiple
        +     of the block size, otherwise an error occurs.
        +     [Steve Henson]
        +
        +  *) Initial (incomplete) OCSP SSL support.
        +     [Steve Henson]
        +
        +  *) New function OCSP_parse_url(). This splits up a URL into its host,
        +     port and path components: primarily to parse OCSP URLs. New -url
        +     option to ocsp utility.
        +     [Steve Henson]
        +
        +  *) New nonce behavior. The return value of OCSP_check_nonce() now 
        +     reflects the various checks performed. Applications can decide
        +     whether to tolerate certain situations such as an absent nonce
        +     in a response when one was present in a request: the ocsp application
        +     just prints out a warning. New function OCSP_add1_basic_nonce()
        +     this is to allow responders to include a nonce in a response even if
        +     the request is nonce-less.
        +     [Steve Henson]
        +
        +  *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are
        +     skipped when using openssl x509 multiple times on a single input file,
        +     e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) <certs".
        +     [Bodo Moeller]
        +
        +  *) Make ASN1_UTCTIME_set_string() and ASN1_GENERALIZEDTIME_set_string()
        +     set string type: to handle setting ASN1_TIME structures. Fix ca
        +     utility to correctly initialize revocation date of CRLs.
        +     [Steve Henson]
        +
        +  *) New option SSL_OP_CIPHER_SERVER_PREFERENCE allows the server to override
        +     the clients preferred ciphersuites and rather use its own preferences.
        +     Should help to work around M$ SGC (Server Gated Cryptography) bug in
        +     Internet Explorer by ensuring unchanged hash method during stepup.
        +     (Also replaces the broken/deactivated SSL_OP_NON_EXPORT_FIRST option.)
        +     [Lutz Jaenicke]
        +
        +  *) Make mkdef.pl recognise all DECLARE_ASN1 macros, change rijndael
        +     to aes and add a new 'exist' option to print out symbols that don't
        +     appear to exist.
        +     [Steve Henson]
        +
        +  *) Additional options to ocsp utility to allow flags to be set and
        +     additional certificates supplied.
        +     [Steve Henson]
        +
        +  *) Add the option -VAfile to 'openssl ocsp', so the user can give the
        +     OCSP client a number of certificate to only verify the response
        +     signature against.
        +     [Richard Levitte]
        +
        +  *) Update Rijndael code to version 3.0 and change EVP AES ciphers to
        +     handle the new API. Currently only ECB, CBC modes supported. Add new
        +     AES OIDs.
        +
        +     Add TLS AES ciphersuites as described in RFC3268, "Advanced
        +     Encryption Standard (AES) Ciphersuites for Transport Layer
        +     Security (TLS)".  (In beta versions of OpenSSL 0.9.7, these were
        +     not enabled by default and were not part of the "ALL" ciphersuite
        +     alias because they were not yet official; they could be
        +     explicitly requested by specifying the "AESdraft" ciphersuite
        +     group alias.  In the final release of OpenSSL 0.9.7, the group
        +     alias is called "AES" and is part of "ALL".)
        +     [Ben Laurie, Steve  Henson, Bodo Moeller]
        +
        +  *) New function OCSP_copy_nonce() to copy nonce value (if present) from
        +     request to response.
        +     [Steve Henson]
        +
        +  *) Functions for OCSP responders. OCSP_request_onereq_count(),
        +     OCSP_request_onereq_get0(), OCSP_onereq_get0_id() and OCSP_id_get0_info()
        +     extract information from a certificate request. OCSP_response_create()
        +     creates a response and optionally adds a basic response structure.
        +     OCSP_basic_add1_status() adds a complete single response to a basic
        +     response and returns the OCSP_SINGLERESP structure just added (to allow
        +     extensions to be included for example). OCSP_basic_add1_cert() adds a
        +     certificate to a basic response and OCSP_basic_sign() signs a basic
        +     response with various flags. New helper functions ASN1_TIME_check()
        +     (checks validity of ASN1_TIME structure) and ASN1_TIME_to_generalizedtime()
        +     (converts ASN1_TIME to GeneralizedTime).
        +     [Steve Henson]
        +
        +  *) Various new functions. EVP_Digest() combines EVP_Digest{Init,Update,Final}()
        +     in a single operation. X509_get0_pubkey_bitstr() extracts the public_key
        +     structure from a certificate. X509_pubkey_digest() digests the public_key
        +     contents: this is used in various key identifiers. 
        +     [Steve Henson]
        +
        +  *) Make sk_sort() tolerate a NULL argument.
        +     [Steve Henson reported by Massimiliano Pala <madwolf@comune.modena.it>]
        +
        +  *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates
        +     passed by the function are trusted implicitly. If any of them signed the
        +     response then it is assumed to be valid and is not verified.
        +     [Steve Henson]
        +
        +  *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT
        +     to data. This was previously part of the PKCS7 ASN1 code. This
        +     was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures.
        +     [Steve Henson, reported by Kenneth R. Robinette
        +				<support@securenetterm.com>]
        +
        +  *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1
        +     routines: without these tracing memory leaks is very painful.
        +     Fix leaks in PKCS12 and PKCS7 routines.
        +     [Steve Henson]
        +
        +  *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new().
        +     Previously it initialised the 'type' argument to V_ASN1_UTCTIME which
        +     effectively meant GeneralizedTime would never be used. Now it
        +     is initialised to -1 but X509_time_adj() now has to check the value
        +     and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or
        +     V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime.
        +     [Steve Henson, reported by Kenneth R. Robinette
        +				<support@securenetterm.com>]
        +
        +  *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously
        +     result in a zero length in the ASN1_INTEGER structure which was
        +     not consistent with the structure when d2i_ASN1_INTEGER() was used
        +     and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER()
        +     to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER()
        +     where it did not print out a minus for negative ASN1_INTEGER.
        +     [Steve Henson]
        +
        +  *) Add summary printout to ocsp utility. The various functions which
        +     convert status values to strings have been renamed to:
        +     OCSP_response_status_str(), OCSP_cert_status_str() and
        +     OCSP_crl_reason_str() and are no longer static. New options
        +     to verify nonce values and to disable verification. OCSP response
        +     printout format cleaned up.
        +     [Steve Henson]
        +
        +  *) Add additional OCSP certificate checks. These are those specified
        +     in RFC2560. This consists of two separate checks: the CA of the
        +     certificate being checked must either be the OCSP signer certificate
        +     or the issuer of the OCSP signer certificate. In the latter case the
        +     OCSP signer certificate must contain the OCSP signing extended key
        +     usage. This check is performed by attempting to match the OCSP
        +     signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash
        +     in the OCSP_CERTID structures of the response.
        +     [Steve Henson]
        +
        +  *) Initial OCSP certificate verification added to OCSP_basic_verify()
        +     and related routines. This uses the standard OpenSSL certificate
        +     verify routines to perform initial checks (just CA validity) and
        +     to obtain the certificate chain. Then additional checks will be
        +     performed on the chain. Currently the root CA is checked to see
        +     if it is explicitly trusted for OCSP signing. This is used to set
        +     a root CA as a global signing root: that is any certificate that
        +     chains to that CA is an acceptable OCSP signing certificate.
        +     [Steve Henson]
        +
        +  *) New '-extfile ...' option to 'openssl ca' for reading X.509v3
        +     extensions from a separate configuration file.
        +     As when reading extensions from the main configuration file,
        +     the '-extensions ...' option may be used for specifying the
        +     section to use.
        +     [Massimiliano Pala <madwolf@comune.modena.it>]
        +
        +  *) New OCSP utility. Allows OCSP requests to be generated or
        +     read. The request can be sent to a responder and the output
        +     parsed, outputed or printed in text form. Not complete yet:
        +     still needs to check the OCSP response validity.
        +     [Steve Henson]
        +
        +  *) New subcommands for 'openssl ca':
        +     'openssl ca -status <serial>' prints the status of the cert with
        +     the given serial number (according to the index file).
        +     'openssl ca -updatedb' updates the expiry status of certificates
        +     in the index file.
        +     [Massimiliano Pala <madwolf@comune.modena.it>]
        +
        +  *) New '-newreq-nodes' command option to CA.pl.  This is like
        +     '-newreq', but calls 'openssl req' with the '-nodes' option
        +     so that the resulting key is not encrypted.
        +     [Damien Miller <djm@mindrot.org>]
        +
        +  *) New configuration for the GNU Hurd.
        +     [Jonathan Bartlett <johnnyb@wolfram.com> via Richard Levitte]
        +
        +  *) Initial code to implement OCSP basic response verify. This
        +     is currently incomplete. Currently just finds the signer's
        +     certificate and verifies the signature on the response.
        +     [Steve Henson]
        +
        +  *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in
        +     value of OPENSSLDIR.  This is available via the new '-d' option
        +     to 'openssl version', and is also included in 'openssl version -a'.
        +     [Bodo Moeller]
        +
        +  *) Allowing defining memory allocation callbacks that will be given
        +     file name and line number information in additional arguments
        +     (a const char* and an int).  The basic functionality remains, as
        +     well as the original possibility to just replace malloc(),
        +     realloc() and free() by functions that do not know about these
        +     additional arguments.  To register and find out the current
        +     settings for extended allocation functions, the following
        +     functions are provided:
        +
        +	CRYPTO_set_mem_ex_functions
        +	CRYPTO_set_locked_mem_ex_functions
        +	CRYPTO_get_mem_ex_functions
        +	CRYPTO_get_locked_mem_ex_functions
        +
        +     These work the same way as CRYPTO_set_mem_functions and friends.
        +     CRYPTO_get_[locked_]mem_functions now writes 0 where such an
        +     extended allocation function is enabled.
        +     Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where
        +     a conventional allocation function is enabled.
        +     [Richard Levitte, Bodo Moeller]
        +
        +  *) Finish off removing the remaining LHASH function pointer casts.
        +     There should no longer be any prototype-casting required when using
        +     the LHASH abstraction, and any casts that remain are "bugs". See
        +     the callback types and macros at the head of lhash.h for details
        +     (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
        +     [Geoff Thorpe]
        +
        +  *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
        +     If /dev/[u]random devices are not available or do not return enough
        +     entropy, EGD style sockets (served by EGD or PRNGD) will automatically
        +     be queried.
        +     The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and
        +     /etc/entropy will be queried once each in this sequence, quering stops
        +     when enough entropy was collected without querying more sockets.
        +     [Lutz Jaenicke]
        +
        +  *) Change the Unix RAND_poll() variant to be able to poll several
        +     random devices, as specified by DEVRANDOM, until a sufficient amount
        +     of data has been collected.   We spend at most 10 ms on each file
        +     (select timeout) and read in non-blocking mode.  DEVRANDOM now
        +     defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom"
        +     (previously it was just the string "/dev/urandom"), so on typical
        +     platforms the 10 ms delay will never occur.
        +     Also separate out the Unix variant to its own file, rand_unix.c.
        +     For VMS, there's a currently-empty rand_vms.c.
        +     [Richard Levitte]
        +
        +  *) Move OCSP client related routines to ocsp_cl.c. These
        +     provide utility functions which an application needing
        +     to issue a request to an OCSP responder and analyse the
        +     response will typically need: as opposed to those which an
        +     OCSP responder itself would need which will be added later.
        +
        +     OCSP_request_sign() signs an OCSP request with an API similar
        +     to PKCS7_sign(). OCSP_response_status() returns status of OCSP
        +     response. OCSP_response_get1_basic() extracts basic response
        +     from response. OCSP_resp_find_status(): finds and extracts status
        +     information from an OCSP_CERTID structure (which will be created
        +     when the request structure is built). These are built from lower
        +     level functions which work on OCSP_SINGLERESP structures but
        +     wont normally be used unless the application wishes to examine
        +     extensions in the OCSP response for example.
        +
        +     Replace nonce routines with a pair of functions.
        +     OCSP_request_add1_nonce() adds a nonce value and optionally
        +     generates a random value. OCSP_check_nonce() checks the
        +     validity of the nonce in an OCSP response.
        +     [Steve Henson]
        +
        +  *) Change function OCSP_request_add() to OCSP_request_add0_id().
        +     This doesn't copy the supplied OCSP_CERTID and avoids the
        +     need to free up the newly created id. Change return type
        +     to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure.
        +     This can then be used to add extensions to the request.
        +     Deleted OCSP_request_new(), since most of its functionality
        +     is now in OCSP_REQUEST_new() (and the case insensitive name
        +     clash) apart from the ability to set the request name which
        +     will be added elsewhere.
        +     [Steve Henson]
        +
        +  *) Update OCSP API. Remove obsolete extensions argument from
        +     various functions. Extensions are now handled using the new
        +     OCSP extension code. New simple OCSP HTTP function which 
        +     can be used to send requests and parse the response.
        +     [Steve Henson]
        +
        +  *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new
        +     ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN
        +     uses the special reorder version of SET OF to sort the attributes
        +     and reorder them to match the encoded order. This resolves a long
        +     standing problem: a verify on a PKCS7 structure just after signing
        +     it used to fail because the attribute order did not match the
        +     encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes:
        +     it uses the received order. This is necessary to tolerate some broken
        +     software that does not order SET OF. This is handled by encoding
        +     as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class)
        +     to produce the required SET OF.
        +     [Steve Henson]
        +
        +  *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and
        +     OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header
        +     files to get correct declarations of the ASN.1 item variables.
        +     [Richard Levitte]
        +
        +  *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many
        +     PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs:
        +     asn1_check_tlen() would sometimes attempt to use 'ctx' when it was
        +     NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i().
        +     New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant
        +     ASN1_ITEM and no wrapper functions.
        +     [Steve Henson]
        +
        +  *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These
        +     replace the old function pointer based I/O routines. Change most of
        +     the *_d2i_bio() and *_d2i_fp() functions to use these.
        +     [Steve Henson]
        +
        +  *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor
        +     lines, recognice more "algorithms" that can be deselected, and make
        +     it complain about algorithm deselection that isn't recognised.
        +     [Richard Levitte]
        +
        +  *) New ASN1 functions to handle dup, sign, verify, digest, pack and
        +     unpack operations in terms of ASN1_ITEM. Modify existing wrappers
        +     to use new functions. Add NO_ASN1_OLD which can be set to remove
        +     some old style ASN1 functions: this can be used to determine if old
        +     code will still work when these eventually go away.
        +     [Steve Henson]
        +
        +  *) New extension functions for OCSP structures, these follow the
        +     same conventions as certificates and CRLs.
        +     [Steve Henson]
        +
        +  *) New function X509V3_add1_i2d(). This automatically encodes and
        +     adds an extension. Its behaviour can be customised with various
        +     flags to append, replace or delete. Various wrappers added for
        +     certifcates and CRLs.
        +     [Steve Henson]
        +
        +  *) Fix to avoid calling the underlying ASN1 print routine when
        +     an extension cannot be parsed. Correct a typo in the
        +     OCSP_SERVICELOC extension. Tidy up print OCSP format.
        +     [Steve Henson]
        +
        +  *) Make mkdef.pl parse some of the ASN1 macros and add apropriate
        +     entries for variables.
        +     [Steve Henson]
        +
        +  *) Add functionality to apps/openssl.c for detecting locking
        +     problems: As the program is single-threaded, all we have
        +     to do is register a locking callback using an array for
        +     storing which locks are currently held by the program.
        +     [Bodo Moeller]
        +
        +  *) Use a lock around the call to CRYPTO_get_ex_new_index() in
        +     SSL_get_ex_data_X509_STORE_idx(), which is used in
        +     ssl_verify_cert_chain() and thus can be called at any time
        +     during TLS/SSL handshakes so that thread-safety is essential.
        +     Unfortunately, the ex_data design is not at all suited
        +     for multi-threaded use, so it probably should be abolished.
        +     [Bodo Moeller]
        +
        +  *) Added Broadcom "ubsec" ENGINE to OpenSSL.
        +     [Broadcom, tweaked and integrated by Geoff Thorpe]
        +
        +  *) Move common extension printing code to new function
        +     X509V3_print_extensions(). Reorganise OCSP print routines and
        +     implement some needed OCSP ASN1 functions. Add OCSP extensions.
        +     [Steve Henson]
        +
        +  *) New function X509_signature_print() to remove duplication in some
        +     print routines.
        +     [Steve Henson]
        +
        +  *) Add a special meaning when SET OF and SEQUENCE OF flags are both
        +     set (this was treated exactly the same as SET OF previously). This
        +     is used to reorder the STACK representing the structure to match the
        +     encoding. This will be used to get round a problem where a PKCS7
        +     structure which was signed could not be verified because the STACK
        +     order did not reflect the encoded order.
        +     [Steve Henson]
        +
        +  *) Reimplement the OCSP ASN1 module using the new code.
        +     [Steve Henson]
        +
        +  *) Update the X509V3 code to permit the use of an ASN1_ITEM structure
        +     for its ASN1 operations. The old style function pointers still exist
        +     for now but they will eventually go away.
        +     [Steve Henson]
        +
        +  *) Merge in replacement ASN1 code from the ASN1 branch. This almost
        +     completely replaces the old ASN1 functionality with a table driven
        +     encoder and decoder which interprets an ASN1_ITEM structure describing
        +     the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is
        +     largely maintained. Almost all of the old asn1_mac.h macro based ASN1
        +     has also been converted to the new form.
        +     [Steve Henson]
        +
        +  *) Change BN_mod_exp_recp so that negative moduli are tolerated
        +     (the sign is ignored).  Similarly, ignore the sign in BN_MONT_CTX_set
        +     so that BN_mod_exp_mont and BN_mod_exp_mont_word work
        +     for negative moduli.
        +     [Bodo Moeller]
        +
        +  *) Fix BN_uadd and BN_usub: Always return non-negative results instead
        +     of not touching the result's sign bit.
        +     [Bodo Moeller]
        +
        +  *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be
        +     set.
        +     [Bodo Moeller]
        +
        +  *) Changed the LHASH code to use prototypes for callbacks, and created
        +     macros to declare and implement thin (optionally static) functions
        +     that provide type-safety and avoid function pointer casting for the
        +     type-specific callbacks.
        +     [Geoff Thorpe]
        +
        +  *) Added Kerberos Cipher Suites to be used with TLS, as written in
        +     RFC 2712.
        +     [Veers Staats <staatsvr@asc.hpc.mil>,
        +      Jeffrey Altman <jaltman@columbia.edu>, via Richard Levitte]
        +
        +  *) Reformat the FAQ so the different questions and answers can be divided
        +     in sections depending on the subject.
        +     [Richard Levitte]
        +
        +  *) Have the zlib compression code load ZLIB.DLL dynamically under
        +     Windows.
        +     [Richard Levitte]
        +
        +  *) New function BN_mod_sqrt for computing square roots modulo a prime
        +     (using the probabilistic Tonelli-Shanks algorithm unless
        +     p == 3 (mod 4)  or  p == 5 (mod 8),  which are cases that can
        +     be handled deterministically).
        +     [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
        +
        +  *) Make BN_mod_inverse faster by explicitly handling small quotients
        +     in the Euclid loop. (Speed gain about 20% for small moduli [256 or
        +     512 bits], about 30% for larger ones [1024 or 2048 bits].)
        +     [Bodo Moeller]
        +
        +  *) New function BN_kronecker.
        +     [Bodo Moeller]
        +
        +  *) Fix BN_gcd so that it works on negative inputs; the result is
        +     positive unless both parameters are zero.
        +     Previously something reasonably close to an infinite loop was
        +     possible because numbers could be growing instead of shrinking
        +     in the implementation of Euclid's algorithm.
        +     [Bodo Moeller]
        +
        +  *) Fix BN_is_word() and BN_is_one() macros to take into account the
        +     sign of the number in question.
        +
        +     Fix BN_is_word(a,w) to work correctly for w == 0.
        +
        +     The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w)
        +     because its test if the absolute value of 'a' equals 'w'.
        +     Note that BN_abs_is_word does *not* handle w == 0 reliably;
        +     it exists mostly for use in the implementations of BN_is_zero(),
        +     BN_is_one(), and BN_is_word().
        +     [Bodo Moeller]
        +
        +  *) New function BN_swap.
        +     [Bodo Moeller]
        +
        +  *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that
        +     the exponentiation functions are more likely to produce reasonable
        +     results on negative inputs.
        +     [Bodo Moeller]
        +
        +  *) Change BN_mod_mul so that the result is always non-negative.
        +     Previously, it could be negative if one of the factors was negative;
        +     I don't think anyone really wanted that behaviour.
        +     [Bodo Moeller]
        +
        +  *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c
        +     (except for exponentiation, which stays in crypto/bn/bn_exp.c,
        +     and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c)
        +     and add new functions:
        +
        +          BN_nnmod
        +          BN_mod_sqr
        +          BN_mod_add
        +          BN_mod_add_quick
        +          BN_mod_sub
        +          BN_mod_sub_quick
        +          BN_mod_lshift1
        +          BN_mod_lshift1_quick
        +          BN_mod_lshift
        +          BN_mod_lshift_quick
        +
        +     These functions always generate non-negative results.
        +
        +     BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder  r
        +     such that  |m| < r < 0,  BN_nnmod will output  rem + |m|  instead).
        +
        +     BN_mod_XXX_quick(r, a, [b,] m) generates the same result as
        +     BN_mod_XXX(r, a, [b,] m, ctx), but requires that  a  [and  b]
        +     be reduced modulo  m.
        +     [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
        +
        +#if 0
        +     The following entry accidentily appeared in the CHANGES file
        +     distributed with OpenSSL 0.9.7.  The modifications described in
        +     it do *not* apply to OpenSSL 0.9.7.
        +
        +  *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
        +     was actually never needed) and in BN_mul().  The removal in BN_mul()
        +     required a small change in bn_mul_part_recursive() and the addition
        +     of the functions bn_cmp_part_words(), bn_sub_part_words() and
        +     bn_add_part_words(), which do the same thing as bn_cmp_words(),
        +     bn_sub_words() and bn_add_words() except they take arrays with
        +     differing sizes.
        +     [Richard Levitte]
        +#endif
        +
        +  *) In 'openssl passwd', verify passwords read from the terminal
        +     unless the '-salt' option is used (which usually means that
        +     verification would just waste user's time since the resulting
        +     hash is going to be compared with some given password hash)
        +     or the new '-noverify' option is used.
        +
        +     This is an incompatible change, but it does not affect
        +     non-interactive use of 'openssl passwd' (passwords on the command
        +     line, '-stdin' option, '-in ...' option) and thus should not
        +     cause any problems.
        +     [Bodo Moeller]
        +
        +  *) Remove all references to RSAref, since there's no more need for it.
        +     [Richard Levitte]
        +
        +  *) Make DSO load along a path given through an environment variable
        +     (SHLIB_PATH) with shl_load().
        +     [Richard Levitte]
        +
        +  *) Constify the ENGINE code as a result of BIGNUM constification.
        +     Also constify the RSA code and most things related to it.  In a
        +     few places, most notable in the depth of the ASN.1 code, ugly
        +     casts back to non-const were required (to be solved at a later
        +     time)
        +     [Richard Levitte]
        +
        +  *) Make it so the openssl application has all engines loaded by default.
        +     [Richard Levitte]
        +
        +  *) Constify the BIGNUM routines a little more.
        +     [Richard Levitte]
        +
        +  *) Add the following functions:
        +
        +	ENGINE_load_cswift()
        +	ENGINE_load_chil()
        +	ENGINE_load_atalla()
        +	ENGINE_load_nuron()
        +	ENGINE_load_builtin_engines()
        +
        +     That way, an application can itself choose if external engines that
        +     are built-in in OpenSSL shall ever be used or not.  The benefit is
        +     that applications won't have to be linked with libdl or other dso
        +     libraries unless it's really needed.
        +
        +     Changed 'openssl engine' to load all engines on demand.
        +     Changed the engine header files to avoid the duplication of some
        +     declarations (they differed!).
        +     [Richard Levitte]
        +
        +  *) 'openssl engine' can now list capabilities.
        +     [Richard Levitte]
        +
        +  *) Better error reporting in 'openssl engine'.
        +     [Richard Levitte]
        +
        +  *) Never call load_dh_param(NULL) in s_server.
        +     [Bodo Moeller]
        +
        +  *) Add engine application.  It can currently list engines by name and
        +     identity, and test if they are actually available.
        +     [Richard Levitte]
        +
        +  *) Improve RPM specification file by forcing symbolic linking and making
        +     sure the installed documentation is also owned by root.root.
        +     [Damien Miller <djm@mindrot.org>]
        +
        +  *) Give the OpenSSL applications more possibilities to make use of
        +     keys (public as well as private) handled by engines.
        +     [Richard Levitte]
        +
        +  *) Add OCSP code that comes from CertCo.
        +     [Richard Levitte]
        +
        +  *) Add VMS support for the Rijndael code.
        +     [Richard Levitte]
        +
        +  *) Added untested support for Nuron crypto accelerator.
        +     [Ben Laurie]
        +
        +  *) Add support for external cryptographic devices.  This code was
        +     previously distributed separately as the "engine" branch.
        +     [Geoff Thorpe, Richard Levitte]
        +
        +  *) Rework the filename-translation in the DSO code. It is now possible to
        +     have far greater control over how a "name" is turned into a filename
        +     depending on the operating environment and any oddities about the
        +     different shared library filenames on each system.
        +     [Geoff Thorpe]
        +
        +  *) Support threads on FreeBSD-elf in Configure.
        +     [Richard Levitte]
        +
        +  *) Fix for SHA1 assembly problem with MASM: it produces
        +     warnings about corrupt line number information when assembling
        +     with debugging information. This is caused by the overlapping
        +     of two sections.
        +     [Bernd Matthes <mainbug@celocom.de>, Steve Henson]
        +
        +  *) NCONF changes.
        +     NCONF_get_number() has no error checking at all.  As a replacement,
        +     NCONF_get_number_e() is defined (_e for "error checking") and is
        +     promoted strongly.  The old NCONF_get_number is kept around for
        +     binary backward compatibility.
        +     Make it possible for methods to load from something other than a BIO,
        +     by providing a function pointer that is given a name instead of a BIO.
        +     For example, this could be used to load configuration data from an
        +     LDAP server.
        +     [Richard Levitte]
        +
        +  *) Fix for non blocking accept BIOs. Added new I/O special reason
        +     BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs
        +     with non blocking I/O was not possible because no retry code was
        +     implemented. Also added new SSL code SSL_WANT_ACCEPT to cover
        +     this case.
        +     [Steve Henson]
        +
        +  *) Added the beginnings of Rijndael support.
        +     [Ben Laurie]
        +
        +  *) Fix for bug in DirectoryString mask setting. Add support for
        +     X509_NAME_print_ex() in 'req' and X509_print_ex() function
        +     to allow certificate printing to more controllable, additional
        +     'certopt' option to 'x509' to allow new printing options to be
        +     set.
        +     [Steve Henson]
        +
        +  *) Clean old EAY MD5 hack from e_os.h.
        +     [Richard Levitte]
        +
        + Changes between 0.9.6l and 0.9.6m  [17 Mar 2004]
        +
        +  *) Fix null-pointer assignment in do_change_cipher_spec() revealed
        +     by using the Codenomicon TLS Test Tool (CVE-2004-0079)
        +     [Joe Orton, Steve Henson]
        +
        + Changes between 0.9.6k and 0.9.6l  [04 Nov 2003]
        +
        +  *) Fix additional bug revealed by the NISCC test suite:
        +
        +     Stop bug triggering large recursion when presented with
        +     certain ASN.1 tags (CVE-2003-0851)
        +     [Steve Henson]
        +
        + Changes between 0.9.6j and 0.9.6k  [30 Sep 2003]
        +
        +  *) Fix various bugs revealed by running the NISCC test suite:
        +
        +     Stop out of bounds reads in the ASN1 code when presented with
        +     invalid tags (CVE-2003-0543 and CVE-2003-0544).
        +     
        +     If verify callback ignores invalid public key errors don't try to check
        +     certificate signature with the NULL public key.
        +
        +     [Steve Henson]
        +
        +  *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
        +     if the server requested one: as stated in TLS 1.0 and SSL 3.0
        +     specifications.
        +     [Steve Henson]
        +
        +  *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
        +     extra data after the compression methods not only for TLS 1.0
        +     but also for SSL 3.0 (as required by the specification).
        +     [Bodo Moeller; problem pointed out by Matthias Loepfe]
        +
        +  *) Change X509_certificate_type() to mark the key as exported/exportable
        +     when it's 512 *bits* long, not 512 bytes.
        +     [Richard Levitte]
        +
        + Changes between 0.9.6i and 0.9.6j  [10 Apr 2003]
        +
        +  *) Countermeasure against the Klima-Pokorny-Rosa extension of
        +     Bleichbacher's attack on PKCS #1 v1.5 padding: treat
        +     a protocol version number mismatch like a decryption error
        +     in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
        +     [Bodo Moeller]
        +
        +  *) Turn on RSA blinding by default in the default implementation
        +     to avoid a timing attack. Applications that don't want it can call
        +     RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
        +     They would be ill-advised to do so in most cases.
        +     [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
        +
        +  *) Change RSA blinding code so that it works when the PRNG is not
        +     seeded (in this case, the secret RSA exponent is abused as
        +     an unpredictable seed -- if it is not unpredictable, there
        +     is no point in blinding anyway).  Make RSA blinding thread-safe
        +     by remembering the creator's thread ID in rsa->blinding and
        +     having all other threads use local one-time blinding factors
        +     (this requires more computation than sharing rsa->blinding, but
        +     avoids excessive locking; and if an RSA object is not shared
        +     between threads, blinding will still be very fast).
        +     [Bodo Moeller]
        +
        + Changes between 0.9.6h and 0.9.6i  [19 Feb 2003]
        +
        +  *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
        +     via timing by performing a MAC computation even if incorrrect
        +     block cipher padding has been found.  This is a countermeasure
        +     against active attacks where the attacker has to distinguish
        +     between bad padding and a MAC verification error. (CVE-2003-0078)
        +
        +     [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
        +     Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
        +     Martin Vuagnoux (EPFL, Ilion)]
        +
        + Changes between 0.9.6g and 0.9.6h  [5 Dec 2002]
        +
        +  *) New function OPENSSL_cleanse(), which is used to cleanse a section of
        +     memory from it's contents.  This is done with a counter that will
        +     place alternating values in each byte.  This can be used to solve
        +     two issues: 1) the removal of calls to memset() by highly optimizing
        +     compilers, and 2) cleansing with other values than 0, since those can
        +     be read through on certain media, for example a swap space on disk.
        +     [Geoff Thorpe]
        +
        +  *) Bugfix: client side session caching did not work with external caching,
        +     because the session->cipher setting was not restored when reloading
        +     from the external cache. This problem was masked, when
        +     SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set.
        +     (Found by Steve Haslam <steve@araqnid.ddts.net>.)
        +     [Lutz Jaenicke]
        +
        +  *) Fix client_certificate (ssl/s2_clnt.c): The permissible total
        +     length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33.
        +     [Zeev Lieber <zeev-l@yahoo.com>]
        +
        +  *) Undo an undocumented change introduced in 0.9.6e which caused
        +     repeated calls to OpenSSL_add_all_ciphers() and 
        +     OpenSSL_add_all_digests() to be ignored, even after calling
        +     EVP_cleanup().
        +     [Richard Levitte]
        +
        +  *) Change the default configuration reader to deal with last line not
        +     being properly terminated.
        +     [Richard Levitte]
        +
        +  *) Change X509_NAME_cmp() so it applies the special rules on handling
        +     DN values that are of type PrintableString, as well as RDNs of type
        +     emailAddress where the value has the type ia5String.
        +     [stefank@valicert.com via Richard Levitte]
        +
        +  *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half
        +     the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently
        +     doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be
        +     the bitwise-OR of the two for use by the majority of applications
        +     wanting this behaviour, and update the docs. The documented
        +     behaviour and actual behaviour were inconsistent and had been
        +     changing anyway, so this is more a bug-fix than a behavioural
        +     change.
        +     [Geoff Thorpe, diagnosed by Nadav Har'El]
        +
        +  *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c
        +     (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes).
        +     [Bodo Moeller]
        +
        +  *) Fix initialization code race conditions in
        +        SSLv23_method(),  SSLv23_client_method(),   SSLv23_server_method(),
        +        SSLv2_method(),   SSLv2_client_method(),    SSLv2_server_method(),
        +        SSLv3_method(),   SSLv3_client_method(),    SSLv3_server_method(),
        +        TLSv1_method(),   TLSv1_client_method(),    TLSv1_server_method(),
        +        ssl2_get_cipher_by_char(),
        +        ssl3_get_cipher_by_char().
        +     [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
        +
        +  *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
        +     the cached sessions are flushed, as the remove_cb() might use ex_data
        +     contents. Bug found by Sam Varshavchik <mrsam@courier-mta.com>
        +     (see [openssl.org #212]).
        +     [Geoff Thorpe, Lutz Jaenicke]
        +
        +  *) Fix typo in OBJ_txt2obj which incorrectly passed the content
        +     length, instead of the encoding length to d2i_ASN1_OBJECT.
        +     [Steve Henson]
        +
        + Changes between 0.9.6f and 0.9.6g  [9 Aug 2002]
        +
        +  *) [In 0.9.6g-engine release:]
        +     Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall').
        +     [Lynn Gazis <lgazis@rainbow.com>]
        +
        + Changes between 0.9.6e and 0.9.6f  [8 Aug 2002]
        +
        +  *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX
        +     and get fix the header length calculation.
        +     [Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE>,
        +	Alon Kantor <alonk@checkpoint.com> (and others),
        +	Steve Henson]
        +
        +  *) Use proper error handling instead of 'assertions' in buffer
        +     overflow checks added in 0.9.6e.  This prevents DoS (the
        +     assertions could call abort()).
        +     [Arne Ansper <arne@ats.cyber.ee>, Bodo Moeller]
        +
        + Changes between 0.9.6d and 0.9.6e  [30 Jul 2002]
        +
        +  *) Add various sanity checks to asn1_get_length() to reject
        +     the ASN1 length bytes if they exceed sizeof(long), will appear
        +     negative or the content length exceeds the length of the
        +     supplied buffer.
        +     [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
        +
        +  *) Fix cipher selection routines: ciphers without encryption had no flags
        +     for the cipher strength set and where therefore not handled correctly
        +     by the selection routines (PR #130).
        +     [Lutz Jaenicke]
        +
        +  *) Fix EVP_dsa_sha macro.
        +     [Nils Larsch]
        +
        +  *) New option
        +          SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
        +     for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure
        +     that was added in OpenSSL 0.9.6d.
        +
        +     As the countermeasure turned out to be incompatible with some
        +     broken SSL implementations, the new option is part of SSL_OP_ALL.
        +     SSL_OP_ALL is usually employed when compatibility with weird SSL
        +     implementations is desired (e.g. '-bugs' option to 's_client' and
        +     's_server'), so the new option is automatically set in many
        +     applications.
        +     [Bodo Moeller]
        +
        +  *) Changes in security patch:
        +
        +     Changes marked "(CHATS)" were sponsored by the Defense Advanced
        +     Research Projects Agency (DARPA) and Air Force Research Laboratory,
        +     Air Force Materiel Command, USAF, under agreement number
        +     F30602-01-2-0537.
        +
        +  *) Add various sanity checks to asn1_get_length() to reject
        +     the ASN1 length bytes if they exceed sizeof(long), will appear
        +     negative or the content length exceeds the length of the
        +     supplied buffer. (CVE-2002-0659)
        +     [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
        +
        +  *) Assertions for various potential buffer overflows, not known to
        +     happen in practice.
        +     [Ben Laurie (CHATS)]
        +
        +  *) Various temporary buffers to hold ASCII versions of integers were
        +     too small for 64 bit platforms. (CVE-2002-0655)
        +     [Matthew Byng-Maddick <mbm@aldigital.co.uk> and Ben Laurie (CHATS)>
        +
        +  *) Remote buffer overflow in SSL3 protocol - an attacker could
        +     supply an oversized session ID to a client. (CVE-2002-0656)
        +     [Ben Laurie (CHATS)]
        +
        +  *) Remote buffer overflow in SSL2 protocol - an attacker could
        +     supply an oversized client master key. (CVE-2002-0656)
        +     [Ben Laurie (CHATS)]
        +
        + Changes between 0.9.6c and 0.9.6d  [9 May 2002]
        +
        +  *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not
        +     encoded as NULL) with id-dsa-with-sha1.
        +     [Nils Larsch <nla@trustcenter.de>; problem pointed out by Bodo Moeller]
        +
        +  *) Check various X509_...() return values in apps/req.c.
        +     [Nils Larsch <nla@trustcenter.de>]
        +
        +  *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines:
        +     an end-of-file condition would erronously be flagged, when the CRLF
        +     was just at the end of a processed block. The bug was discovered when
        +     processing data through a buffering memory BIO handing the data to a
        +     BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov
        +     <ptsekov@syntrex.com> and Nedelcho Stanev.
        +     [Lutz Jaenicke]
        +
        +  *) Implement a countermeasure against a vulnerability recently found
        +     in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment
        +     before application data chunks to avoid the use of known IVs
        +     with data potentially chosen by the attacker.
        +     [Bodo Moeller]
        +
        +  *) Fix length checks in ssl3_get_client_hello().
        +     [Bodo Moeller]
        +
        +  *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently
        +     to prevent ssl3_read_internal() from incorrectly assuming that
        +     ssl3_read_bytes() found application data while handshake
        +     processing was enabled when in fact s->s3->in_read_app_data was
        +     merely automatically cleared during the initial handshake.
        +     [Bodo Moeller; problem pointed out by Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) Fix object definitions for Private and Enterprise: they were not
        +     recognized in their shortname (=lowercase) representation. Extend
        +     obj_dat.pl to issue an error when using undefined keywords instead
        +     of silently ignoring the problem (Svenning Sorensen
        +     <sss@sss.dnsalias.net>).
        +     [Lutz Jaenicke]
        +
        +  *) Fix DH_generate_parameters() so that it works for 'non-standard'
        +     generators, i.e. generators other than 2 and 5.  (Previously, the
        +     code did not properly initialise the 'add' and 'rem' values to
        +     BN_generate_prime().)
        +
        +     In the new general case, we do not insist that 'generator' is
        +     actually a primitive root: This requirement is rather pointless;
        +     a generator of the order-q subgroup is just as good, if not
        +     better.
        +     [Bodo Moeller]
        + 
        +  *) Map new X509 verification errors to alerts. Discovered and submitted by
        +     Tom Wu <tom@arcot.com>.
        +     [Lutz Jaenicke]
        +
        +  *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from
        +     returning non-zero before the data has been completely received
        +     when using non-blocking I/O.
        +     [Bodo Moeller; problem pointed out by John Hughes]
        +
        +  *) Some of the ciphers missed the strength entry (SSL_LOW etc).
        +     [Ben Laurie, Lutz Jaenicke]
        +
        +  *) Fix bug in SSL_clear(): bad sessions were not removed (found by
        +     Yoram Zahavi <YoramZ@gilian.com>).
        +     [Lutz Jaenicke]
        +
        +  *) Add information about CygWin 1.3 and on, and preserve proper
        +     configuration for the versions before that.
        +     [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
        +
        +  *) Make removal from session cache (SSL_CTX_remove_session()) more robust:
        +     check whether we deal with a copy of a session and do not delete from
        +     the cache in this case. Problem reported by "Izhar Shoshani Levi"
        +     <izhar@checkpoint.com>.
        +     [Lutz Jaenicke]
        +
        +  *) Do not store session data into the internal session cache, if it
        +     is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
        +     flag is set). Proposed by Aslam <aslam@funk.com>.
        +     [Lutz Jaenicke]
        +
        +  *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested
        +     value is 0.
        +     [Richard Levitte]
        +
        +  *) [In 0.9.6d-engine release:]
        +     Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
        +     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
        +
        +  *) Add the configuration target linux-s390x.
        +     [Neale Ferguson <Neale.Ferguson@SoftwareAG-USA.com> via Richard Levitte]
        +
        +  *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of
        +     ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag
        +     variable as an indication that a ClientHello message has been
        +     received.  As the flag value will be lost between multiple
        +     invocations of ssl3_accept when using non-blocking I/O, the
        +     function may not be aware that a handshake has actually taken
        +     place, thus preventing a new session from being added to the
        +     session cache.
        +
        +     To avoid this problem, we now set s->new_session to 2 instead of
        +     using a local variable.
        +     [Lutz Jaenicke, Bodo Moeller]
        +
        +  *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c)
        +     if the SSL_R_LENGTH_MISMATCH error is detected.
        +     [Geoff Thorpe, Bodo Moeller]
        +
        +  *) New 'shared_ldflag' column in Configure platform table.
        +     [Richard Levitte]
        +
        +  *) Fix EVP_CIPHER_mode macro.
        +     ["Dan S. Camper" <dan@bti.net>]
        +
        +  *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown
        +     type, we must throw them away by setting rr->length to 0.
        +     [D P Chang <dpc@qualys.com>]
        +
        + Changes between 0.9.6b and 0.9.6c  [21 dec 2001]
        +
        +  *) Fix BN_rand_range bug pointed out by Dominikus Scherkl
        +     <Dominikus.Scherkl@biodata.com>.  (The previous implementation
        +     worked incorrectly for those cases where  range = 10..._2  and
        +     3*range  is two bits longer than  range.)
        +     [Bodo Moeller]
        +
        +  *) Only add signing time to PKCS7 structures if it is not already
        +     present.
        +     [Steve Henson]
        +
        +  *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce",
        +     OBJ_ld_ce should be OBJ_id_ce.
        +     Also some ip-pda OIDs in crypto/objects/objects.txt were
        +     incorrect (cf. RFC 3039).
        +     [Matt Cooper, Frederic Giudicelli, Bodo Moeller]
        +
        +  *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid()
        +     returns early because it has nothing to do.
        +     [Andy Schneider <andy.schneider@bjss.co.uk>]
        +
        +  *) [In 0.9.6c-engine release:]
        +     Fix mutex callback return values in crypto/engine/hw_ncipher.c.
        +     [Andy Schneider <andy.schneider@bjss.co.uk>]
        +
        +  *) [In 0.9.6c-engine release:]
        +     Add support for Cryptographic Appliance's keyserver technology.
        +     (Use engine 'keyclient')
        +     [Cryptographic Appliances and Geoff Thorpe]
        +
        +  *) Add a configuration entry for OS/390 Unix.  The C compiler 'c89'
        +     is called via tools/c89.sh because arguments have to be
        +     rearranged (all '-L' options must appear before the first object
        +     modules).
        +     [Richard Shapiro <rshapiro@abinitio.com>]
        +
        +  *) [In 0.9.6c-engine release:]
        +     Add support for Broadcom crypto accelerator cards, backported
        +     from 0.9.7.
        +     [Broadcom, Nalin Dahyabhai <nalin@redhat.com>, Mark Cox]
        +
        +  *) [In 0.9.6c-engine release:]
        +     Add support for SureWare crypto accelerator cards from 
        +     Baltimore Technologies.  (Use engine 'sureware')
        +     [Baltimore Technologies and Mark Cox]
        +
        +  *) [In 0.9.6c-engine release:]
        +     Add support for crypto accelerator cards from Accelerated
        +     Encryption Processing, www.aep.ie.  (Use engine 'aep')
        +     [AEP Inc. and Mark Cox]
        +
        +  *) Add a configuration entry for gcc on UnixWare.
        +     [Gary Benson <gbenson@redhat.com>]
        +
        +  *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake
        +     messages are stored in a single piece (fixed-length part and
        +     variable-length part combined) and fix various bugs found on the way.
        +     [Bodo Moeller]
        +
        +  *) Disable caching in BIO_gethostbyname(), directly use gethostbyname()
        +     instead.  BIO_gethostbyname() does not know what timeouts are
        +     appropriate, so entries would stay in cache even when they have
        +     become invalid.
        +     [Bodo Moeller; problem pointed out by Rich Salz <rsalz@zolera.com>
        +
        +  *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when
        +     faced with a pathologically small ClientHello fragment that does
        +     not contain client_version: Instead of aborting with an error,
        +     simply choose the highest available protocol version (i.e.,
        +     TLS 1.0 unless it is disabled).  In practice, ClientHello
        +     messages are never sent like this, but this change gives us
        +     strictly correct behaviour at least for TLS.
        +     [Bodo Moeller]
        +
        +  *) Fix SSL handshake functions and SSL_clear() such that SSL_clear()
        +     never resets s->method to s->ctx->method when called from within
        +     one of the SSL handshake functions.
        +     [Bodo Moeller; problem pointed out by Niko Baric]
        +
        +  *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert
        +     (sent using the client's version number) if client_version is
        +     smaller than the protocol version in use.  Also change
        +     ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if
        +     the client demanded SSL 3.0 but only TLS 1.0 is enabled; then
        +     the client will at least see that alert.
        +     [Bodo Moeller]
        +
        +  *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation
        +     correctly.
        +     [Bodo Moeller]
        +
        +  *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a
        +     client receives HelloRequest while in a handshake.
        +     [Bodo Moeller; bug noticed by Andy Schneider <andy.schneider@bjss.co.uk>]
        +
        +  *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C
        +     should end in 'break', not 'goto end' which circuments various
        +     cleanups done in state SSL_ST_OK.   But session related stuff
        +     must be disabled for SSL_ST_OK in the case that we just sent a
        +     HelloRequest.
        +
        +     Also avoid some overhead by not calling ssl_init_wbio_buffer()
        +     before just sending a HelloRequest.
        +     [Bodo Moeller, Eric Rescorla <ekr@rtfm.com>]
        +
        +  *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't
        +     reveal whether illegal block cipher padding was found or a MAC
        +     verification error occured.  (Neither SSLerr() codes nor alerts
        +     are directly visible to potential attackers, but the information
        +     may leak via logfiles.)
        +
        +     Similar changes are not required for the SSL 2.0 implementation
        +     because the number of padding bytes is sent in clear for SSL 2.0,
        +     and the extra bytes are just ignored.  However ssl/s2_pkt.c
        +     failed to verify that the purported number of padding bytes is in
        +     the legal range.
        +     [Bodo Moeller]
        +
        +  *) Add OpenUNIX-8 support including shared libraries
        +     (Boyd Lynn Gerber <gerberb@zenez.com>).
        +     [Lutz Jaenicke]
        +
        +  *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid
        +     'wristwatch attack' using huge encoding parameters (cf.
        +     James H. Manger's CRYPTO 2001 paper).  Note that the
        +     RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use
        +     encoding parameters and hence was not vulnerable.
        +     [Bodo Moeller]
        +
        +  *) BN_sqr() bug fix.
        +     [Ulf Möller, reported by Jim Ellis <jim.ellis@cavium.com>]
        +
        +  *) Rabin-Miller test analyses assume uniformly distributed witnesses,
        +     so use BN_pseudo_rand_range() instead of using BN_pseudo_rand()
        +     followed by modular reduction.
        +     [Bodo Moeller; pointed out by Adam Young <AYoung1@NCSUS.JNJ.COM>]
        +
        +  *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range()
        +     equivalent based on BN_pseudo_rand() instead of BN_rand().
        +     [Bodo Moeller]
        +
        +  *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB).
        +     This function was broken, as the check for a new client hello message
        +     to handle SGC did not allow these large messages.
        +     (Tracked down by "Douglas E. Engert" <deengert@anl.gov>.)
        +     [Lutz Jaenicke]
        +
        +  *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long]().
        +     [Lutz Jaenicke]
        +
        +  *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl()
        +     for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" <shinton@netopia.com>).
        +     [Lutz Jaenicke]
        +
        +  *) Rework the configuration and shared library support for Tru64 Unix.
        +     The configuration part makes use of modern compiler features and
        +     still retains old compiler behavior for those that run older versions
        +     of the OS.  The shared library support part includes a variant that
        +     uses the RPATH feature, and is available through the special
        +     configuration target "alpha-cc-rpath", which will never be selected
        +     automatically.
        +     [Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu> via Richard Levitte]
        +
        +  *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message()
        +     with the same message size as in ssl3_get_certificate_request().
        +     Otherwise, if no ServerKeyExchange message occurs, CertificateRequest
        +     messages might inadvertently be reject as too long.
        +     [Petr Lampa <lampa@fee.vutbr.cz>]
        +
        +  *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX).
        +     [Andy Polyakov]
        +
        +  *) Modified SSL library such that the verify_callback that has been set
        +     specificly for an SSL object with SSL_set_verify() is actually being
        +     used. Before the change, a verify_callback set with this function was
        +     ignored and the verify_callback() set in the SSL_CTX at the time of
        +     the call was used. New function X509_STORE_CTX_set_verify_cb() introduced
        +     to allow the necessary settings.
        +     [Lutz Jaenicke]
        +
        +  *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c
        +     explicitly to NULL, as at least on Solaris 8 this seems not always to be
        +     done automatically (in contradiction to the requirements of the C
        +     standard). This made problems when used from OpenSSH.
        +     [Lutz Jaenicke]
        +
        +  *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored
        +     dh->length and always used
        +
        +          BN_rand_range(priv_key, dh->p).
        +
        +     BN_rand_range() is not necessary for Diffie-Hellman, and this
        +     specific range makes Diffie-Hellman unnecessarily inefficient if
        +     dh->length (recommended exponent length) is much smaller than the
        +     length of dh->p.  We could use BN_rand_range() if the order of
        +     the subgroup was stored in the DH structure, but we only have
        +     dh->length.
        +
        +     So switch back to
        +
        +          BN_rand(priv_key, l, ...)
        +
        +     where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1
        +     otherwise.
        +     [Bodo Moeller]
        +
        +  *) In
        +
        +          RSA_eay_public_encrypt
        +          RSA_eay_private_decrypt
        +          RSA_eay_private_encrypt (signing)
        +          RSA_eay_public_decrypt (signature verification)
        +
        +     (default implementations for RSA_public_encrypt,
        +     RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt),
        +     always reject numbers >= n.
        +     [Bodo Moeller]
        +
        +  *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2
        +     to synchronize access to 'locking_thread'.  This is necessary on
        +     systems where access to 'locking_thread' (an 'unsigned long'
        +     variable) is not atomic.
        +     [Bodo Moeller]
        +
        +  *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID
        +     *before* setting the 'crypto_lock_rand' flag.  The previous code had
        +     a race condition if 0 is a valid thread ID.
        +     [Travis Vitek <vitek@roguewave.com>]
        +
        +  *) Add support for shared libraries under Irix.
        +     [Albert Chin-A-Young <china@thewrittenword.com>]
        +
        +  *) Add configuration option to build on Linux on both big-endian and
        +     little-endian MIPS.
        +     [Ralf Baechle <ralf@uni-koblenz.de>]
        +
        +  *) Add the possibility to create shared libraries on HP-UX.
        +     [Richard Levitte]
        +
        + Changes between 0.9.6a and 0.9.6b  [9 Jul 2001]
        +
        +  *) Change ssleay_rand_bytes (crypto/rand/md_rand.c)
        +     to avoid a SSLeay/OpenSSL PRNG weakness pointed out by
        +     Markku-Juhani O. Saarinen <markku-juhani.saarinen@nokia.com>:
        +     PRNG state recovery was possible based on the output of
        +     one PRNG request appropriately sized to gain knowledge on
        +     'md' followed by enough consecutive 1-byte PRNG requests
        +     to traverse all of 'state'.
        +
        +     1. When updating 'md_local' (the current thread's copy of 'md')
        +        during PRNG output generation, hash all of the previous
        +        'md_local' value, not just the half used for PRNG output.
        +
        +     2. Make the number of bytes from 'state' included into the hash
        +        independent from the number of PRNG bytes requested.
        +
        +     The first measure alone would be sufficient to avoid
        +     Markku-Juhani's attack.  (Actually it had never occurred
        +     to me that the half of 'md_local' used for chaining was the
        +     half from which PRNG output bytes were taken -- I had always
        +     assumed that the secret half would be used.)  The second
        +     measure makes sure that additional data from 'state' is never
        +     mixed into 'md_local' in small portions; this heuristically
        +     further strengthens the PRNG.
        +     [Bodo Moeller]
        +
        +  *) Fix crypto/bn/asm/mips3.s.
        +     [Andy Polyakov]
        +
        +  *) When only the key is given to "enc", the IV is undefined. Print out
        +     an error message in this case.
        +     [Lutz Jaenicke]
        +
        +  *) Handle special case when X509_NAME is empty in X509 printing routines.
        +     [Steve Henson]
        +
        +  *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are
        +     positive and less than q.
        +     [Bodo Moeller]
        +
        +  *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is
        +     used: it isn't thread safe and the add_lock_callback should handle
        +     that itself.
        +     [Paul Rose <Paul.Rose@bridge.com>]
        +
        +  *) Verify that incoming data obeys the block size in
        +     ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c).
        +     [Bodo Moeller]
        +
        +  *) Fix OAEP check.
        +     [Ulf Möller, Bodo Möller]
        +
        +  *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5
        +     RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5
        +     when fixing the server behaviour for backwards-compatible 'client
        +     hello' messages.  (Note that the attack is impractical against
        +     SSL 3.0 and TLS 1.0 anyway because length and version checking
        +     means that the probability of guessing a valid ciphertext is
        +     around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98
        +     paper.)
        +
        +     Before 0.9.5, the countermeasure (hide the error by generating a
        +     random 'decryption result') did not work properly because
        +     ERR_clear_error() was missing, meaning that SSL_get_error() would
        +     detect the supposedly ignored error.
        +
        +     Both problems are now fixed.
        +     [Bodo Moeller]
        +
        +  *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096
        +     (previously it was 1024).
        +     [Bodo Moeller]
        +
        +  *) Fix for compatibility mode trust settings: ignore trust settings
        +     unless some valid trust or reject settings are present.
        +     [Steve Henson]
        +
        +  *) Fix for blowfish EVP: its a variable length cipher.
        +     [Steve Henson]
        +
        +  *) Fix various bugs related to DSA S/MIME verification. Handle missing
        +     parameters in DSA public key structures and return an error in the
        +     DSA routines if parameters are absent.
        +     [Steve Henson]
        +
        +  *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd"
        +     in the current directory if neither $RANDFILE nor $HOME was set.
        +     RAND_file_name() in 0.9.6a returned NULL in this case.  This has
        +     caused some confusion to Windows users who haven't defined $HOME.
        +     Thus RAND_file_name() is changed again: e_os.h can define a
        +     DEFAULT_HOME, which will be used if $HOME is not set.
        +     For Windows, we use "C:"; on other platforms, we still require
        +     environment variables.
        +
        +  *) Move 'if (!initialized) RAND_poll()' into regions protected by
        +     CRYPTO_LOCK_RAND.  This is not strictly necessary, but avoids
        +     having multiple threads call RAND_poll() concurrently.
        +     [Bodo Moeller]
        +
        +  *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a
        +     combination of a flag and a thread ID variable.
        +     Otherwise while one thread is in ssleay_rand_bytes (which sets the
        +     flag), *other* threads can enter ssleay_add_bytes without obeying
        +     the CRYPTO_LOCK_RAND lock (and may even illegally release the lock
        +     that they do not hold after the first thread unsets add_do_not_lock).
        +     [Bodo Moeller]
        +
        +  *) Change bctest again: '-x' expressions are not available in all
        +     versions of 'test'.
        +     [Bodo Moeller]
        +
        + Changes between 0.9.6 and 0.9.6a  [5 Apr 2001]
        +
        +  *) Fix a couple of memory leaks in PKCS7_dataDecode()
        +     [Steve Henson, reported by Heyun Zheng <hzheng@atdsprint.com>]
        +
        +  *) Change Configure and Makefiles to provide EXE_EXT, which will contain
        +     the default extension for executables, if any.  Also, make the perl
        +     scripts that use symlink() to test if it really exists and use "cp"
        +     if it doesn't.  All this made OpenSSL compilable and installable in
        +     CygWin.
        +     [Richard Levitte]
        +
        +  *) Fix for asn1_GetSequence() for indefinite length constructed data.
        +     If SEQUENCE is length is indefinite just set c->slen to the total
        +     amount of data available.
        +     [Steve Henson, reported by shige@FreeBSD.org]
        +     [This change does not apply to 0.9.7.]
        +
        +  *) Change bctest to avoid here-documents inside command substitution
        +     (workaround for FreeBSD /bin/sh bug).
        +     For compatibility with Ultrix, avoid shell functions (introduced
        +     in the bctest version that searches along $PATH).
        +     [Bodo Moeller]
        +
        +  *) Rename 'des_encrypt' to 'des_encrypt1'.  This avoids the clashes
        +     with des_encrypt() defined on some operating systems, like Solaris
        +     and UnixWare.
        +     [Richard Levitte]
        +
        +  *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton:
        +     On the Importance of Eliminating Errors in Cryptographic
        +     Computations, J. Cryptology 14 (2001) 2, 101-119,
        +     http://theory.stanford.edu/~dabo/papers/faults.ps.gz).
        +     [Ulf Moeller]
        +  
        +  *) MIPS assembler BIGNUM division bug fix. 
        +     [Andy Polyakov]
        +
        +  *) Disabled incorrect Alpha assembler code.
        +     [Richard Levitte]
        +
        +  *) Fix PKCS#7 decode routines so they correctly update the length
        +     after reading an EOC for the EXPLICIT tag.
        +     [Steve Henson]
        +     [This change does not apply to 0.9.7.]
        +
        +  *) Fix bug in PKCS#12 key generation routines. This was triggered
        +     if a 3DES key was generated with a 0 initial byte. Include
        +     PKCS12_BROKEN_KEYGEN compilation option to retain the old
        +     (but broken) behaviour.
        +     [Steve Henson]
        +
        +  *) Enhance bctest to search for a working bc along $PATH and print
        +     it when found.
        +     [Tim Rice <tim@multitalents.net> via Richard Levitte]
        +
        +  *) Fix memory leaks in err.c: free err_data string if necessary;
        +     don't write to the wrong index in ERR_set_error_data.
        +     [Bodo Moeller]
        +
        +  *) Implement ssl23_peek (analogous to ssl23_read), which previously
        +     did not exist.
        +     [Bodo Moeller]
        +
        +  *) Replace rdtsc with _emit statements for VC++ version 5.
        +     [Jeremy Cooper <jeremy@baymoo.org>]
        +
        +  *) Make it possible to reuse SSLv2 sessions.
        +     [Richard Levitte]
        +
        +  *) In copy_email() check for >= 0 as a return value for
        +     X509_NAME_get_index_by_NID() since 0 is a valid index.
        +     [Steve Henson reported by Massimiliano Pala <madwolf@opensca.org>]
        +
        +  *) Avoid coredump with unsupported or invalid public keys by checking if
        +     X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when
        +     PKCS7_verify() fails with non detached data.
        +     [Steve Henson]
        +
        +  *) Don't use getenv in library functions when run as setuid/setgid.
        +     New function OPENSSL_issetugid().
        +     [Ulf Moeller]
        +
        +  *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c)
        +     due to incorrect handling of multi-threading:
        +
        +     1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl().
        +
        +     2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on().
        +
        +     3. Count how many times MemCheck_off() has been called so that
        +        nested use can be treated correctly.  This also avoids 
        +        inband-signalling in the previous code (which relied on the
        +        assumption that thread ID 0 is impossible).
        +     [Bodo Moeller]
        +
        +  *) Add "-rand" option also to s_client and s_server.
        +     [Lutz Jaenicke]
        +
        +  *) Fix CPU detection on Irix 6.x.
        +     [Kurt Hockenbury <khockenb@stevens-tech.edu> and
        +      "Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
        +
        +  *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME
        +     was empty.
        +     [Steve Henson]
        +     [This change does not apply to 0.9.7.]
        +
        +  *) Use the cached encoding of an X509_NAME structure rather than
        +     copying it. This is apparently the reason for the libsafe "errors"
        +     but the code is actually correct.
        +     [Steve Henson]
        +
        +  *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent
        +     Bleichenbacher's DSA attack.
        +     Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits
        +     to be set and top=0 forces the highest bit to be set; top=-1 is new
        +     and leaves the highest bit random.
        +     [Ulf Moeller, Bodo Moeller]
        +
        +  *) In the NCONF_...-based implementations for CONF_... queries
        +     (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using
        +     a temporary CONF structure with the data component set to NULL
        +     (which gives segmentation faults in lh_retrieve).
        +     Instead, use NULL for the CONF pointer in CONF_get_string and
        +     CONF_get_number (which may use environment variables) and directly
        +     return NULL from CONF_get_section.
        +     [Bodo Moeller]
        +
        +  *) Fix potential buffer overrun for EBCDIC.
        +     [Ulf Moeller]
        +
        +  *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
        +     keyUsage if basicConstraints absent for a CA.
        +     [Steve Henson]
        +
        +  *) Make SMIME_write_PKCS7() write mail header values with a format that
        +     is more generally accepted (no spaces before the semicolon), since
        +     some programs can't parse those values properly otherwise.  Also make
        +     sure BIO's that break lines after each write do not create invalid
        +     headers.
        +     [Richard Levitte]
        +
        +  *) Make the CRL encoding routines work with empty SEQUENCE OF. The
        +     macros previously used would not encode an empty SEQUENCE OF
        +     and break the signature.
        +     [Steve Henson]
        +     [This change does not apply to 0.9.7.]
        +
        +  *) Zero the premaster secret after deriving the master secret in
        +     DH ciphersuites.
        +     [Steve Henson]
        +
        +  *) Add some EVP_add_digest_alias registrations (as found in
        +     OpenSSL_add_all_digests()) to SSL_library_init()
        +     aka OpenSSL_add_ssl_algorithms().  This provides improved
        +     compatibility with peers using X.509 certificates
        +     with unconventional AlgorithmIdentifier OIDs.
        +     [Bodo Moeller]
        +
        +  *) Fix for Irix with NO_ASM.
        +     ["Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
        +
        +  *) ./config script fixes.
        +     [Ulf Moeller, Richard Levitte]
        +
        +  *) Fix 'openssl passwd -1'.
        +     [Bodo Moeller]
        +
        +  *) Change PKCS12_key_gen_asc() so it can cope with non null
        +     terminated strings whose length is passed in the passlen
        +     parameter, for example from PEM callbacks. This was done
        +     by adding an extra length parameter to asc2uni().
        +     [Steve Henson, reported by <oddissey@samsung.co.kr>]
        +
        +  *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn
        +     call failed, free the DSA structure.
        +     [Bodo Moeller]
        +
        +  *) Fix to uni2asc() to cope with zero length Unicode strings.
        +     These are present in some PKCS#12 files.
        +     [Steve Henson]
        +
        +  *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c).
        +     Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits
        +     when writing a 32767 byte record.
        +     [Bodo Moeller; problem reported by Eric Day <eday@concentric.net>]
        +
        +  *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c),
        +     obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}.
        +
        +     (RSA objects have a reference count access to which is protected
        +     by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c],
        +     so they are meant to be shared between threads.)
        +     [Bodo Moeller, Geoff Thorpe; original patch submitted by
        +     "Reddie, Steven" <Steven.Reddie@ca.com>]
        +
        +  *) Fix a deadlock in CRYPTO_mem_leaks().
        +     [Bodo Moeller]
        +
        +  *) Use better test patterns in bntest.
        +     [Ulf Möller]
        +
        +  *) rand_win.c fix for Borland C.
        +     [Ulf Möller]
        + 
        +  *) BN_rshift bugfix for n == 0.
        +     [Bodo Moeller]
        +
        +  *) Add a 'bctest' script that checks for some known 'bc' bugs
        +     so that 'make test' does not abort just because 'bc' is broken.
        +     [Bodo Moeller]
        +
        +  *) Store verify_result within SSL_SESSION also for client side to
        +     avoid potential security hole. (Re-used sessions on the client side
        +     always resulted in verify_result==X509_V_OK, not using the original
        +     result of the server certificate verification.)
        +     [Lutz Jaenicke]
        +
        +  *) Fix ssl3_pending: If the record in s->s3->rrec is not of type
        +     SSL3_RT_APPLICATION_DATA, return 0.
        +     Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true.
        +     [Bodo Moeller]
        +
        +  *) Fix SSL_peek:
        +     Both ssl2_peek and ssl3_peek, which were totally broken in earlier
        +     releases, have been re-implemented by renaming the previous
        +     implementations of ssl2_read and ssl3_read to ssl2_read_internal
        +     and ssl3_read_internal, respectively, and adding 'peek' parameters
        +     to them.  The new ssl[23]_{read,peek} functions are calls to
        +     ssl[23]_read_internal with the 'peek' flag set appropriately.
        +     A 'peek' parameter has also been added to ssl3_read_bytes, which
        +     does the actual work for ssl3_read_internal.
        +     [Bodo Moeller]
        +
        +  *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling
        +     the method-specific "init()" handler. Also clean up ex_data after
        +     calling the method-specific "finish()" handler. Previously, this was
        +     happening the other way round.
        +     [Geoff Thorpe]
        +
        +  *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16.
        +     The previous value, 12, was not always sufficient for BN_mod_exp().
        +     [Bodo Moeller]
        +
        +  *) Make sure that shared libraries get the internal name engine with
        +     the full version number and not just 0.  This should mark the
        +     shared libraries as not backward compatible.  Of course, this should
        +     be changed again when we can guarantee backward binary compatibility.
        +     [Richard Levitte]
        +
        +  *) Fix typo in get_cert_by_subject() in by_dir.c
        +     [Jean-Marc Desperrier <jean-marc.desperrier@certplus.com>]
        +
        +  *) Rework the system to generate shared libraries:
        +
        +     - Make note of the expected extension for the shared libraries and
        +       if there is a need for symbolic links from for example libcrypto.so.0
        +       to libcrypto.so.0.9.7.  There is extended info in Configure for
        +       that.
        +
        +     - Make as few rebuilds of the shared libraries as possible.
        +
        +     - Still avoid linking the OpenSSL programs with the shared libraries.
        +
        +     - When installing, install the shared libraries separately from the
        +       static ones.
        +     [Richard Levitte]
        +
        +  *) Fix SSL_CTX_set_read_ahead macro to actually use its argument.
        +
        +     Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new
        +     and not in SSL_clear because the latter is also used by the
        +     accept/connect functions; previously, the settings made by
        +     SSL_set_read_ahead would be lost during the handshake.
        +     [Bodo Moeller; problems reported by Anders Gertz <gertz@epact.se>]     
        +
        +  *) Correct util/mkdef.pl to be selective about disabled algorithms.
        +     Previously, it would create entries for disableed algorithms no
        +     matter what.
        +     [Richard Levitte]
        +
        +  *) Added several new manual pages for SSL_* function.
        +     [Lutz Jaenicke]
        +
        + Changes between 0.9.5a and 0.9.6  [24 Sep 2000]
        +
        +  *) In ssl23_get_client_hello, generate an error message when faced
        +     with an initial SSL 3.0/TLS record that is too small to contain the
        +     first two bytes of the ClientHello message, i.e. client_version.
        +     (Note that this is a pathologic case that probably has never happened
        +     in real life.)  The previous approach was to use the version number
        +     from the record header as a substitute; but our protocol choice
        +     should not depend on that one because it is not authenticated
        +     by the Finished messages.
        +     [Bodo Moeller]
        +
        +  *) More robust randomness gathering functions for Windows.
        +     [Jeffrey Altman <jaltman@columbia.edu>]
        +
        +  *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is
        +     not set then we don't setup the error code for issuer check errors
        +     to avoid possibly overwriting other errors which the callback does
        +     handle. If an application does set the flag then we assume it knows
        +     what it is doing and can handle the new informational codes
        +     appropriately.
        +     [Steve Henson]
        +
        +  *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for
        +     a general "ANY" type, as such it should be able to decode anything
        +     including tagged types. However it didn't check the class so it would
        +     wrongly interpret tagged types in the same way as their universal
        +     counterpart and unknown types were just rejected. Changed so that the
        +     tagged and unknown types are handled in the same way as a SEQUENCE:
        +     that is the encoding is stored intact. There is also a new type
        +     "V_ASN1_OTHER" which is used when the class is not universal, in this
        +     case we have no idea what the actual type is so we just lump them all
        +     together.
        +     [Steve Henson]
        +
        +  *) On VMS, stdout may very well lead to a file that is written to
        +     in a record-oriented fashion.  That means that every write() will
        +     write a separate record, which will be read separately by the
        +     programs trying to read from it.  This can be very confusing.
        +
        +     The solution is to put a BIO filter in the way that will buffer
        +     text until a linefeed is reached, and then write everything a
        +     line at a time, so every record written will be an actual line,
        +     not chunks of lines and not (usually doesn't happen, but I've
        +     seen it once) several lines in one record.  BIO_f_linebuffer() is
        +     the answer.
        +
        +     Currently, it's a VMS-only method, because that's where it has
        +     been tested well enough.
        +     [Richard Levitte]
        +
        +  *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery,
        +     it can return incorrect results.
        +     (Note: The buggy variant was not enabled in OpenSSL 0.9.5a,
        +     but it was in 0.9.6-beta[12].)
        +     [Bodo Moeller]
        +
        +  *) Disable the check for content being present when verifying detached
        +     signatures in pk7_smime.c. Some versions of Netscape (wrongly)
        +     include zero length content when signing messages.
        +     [Steve Henson]
        +
        +  *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR
        +     BIO_ctrl (for BIO pairs).
        +     [Bodo Möller]
        +
        +  *) Add DSO method for VMS.
        +     [Richard Levitte]
        +
        +  *) Bug fix: Montgomery multiplication could produce results with the
        +     wrong sign.
        +     [Ulf Möller]
        +
        +  *) Add RPM specification openssl.spec and modify it to build three
        +     packages.  The default package contains applications, application
        +     documentation and run-time libraries.  The devel package contains
        +     include files, static libraries and function documentation.  The
        +     doc package contains the contents of the doc directory.  The original
        +     openssl.spec was provided by Damien Miller <djm@mindrot.org>.
        +     [Richard Levitte]
        +     
        +  *) Add a large number of documentation files for many SSL routines.
        +     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
        +
        +  *) Add a configuration entry for Sony News 4.
        +     [NAKAJI Hiroyuki <nakaji@tutrp.tut.ac.jp>]
        +
        +  *) Don't set the two most significant bits to one when generating a
        +     random number < q in the DSA library.
        +     [Ulf Möller]
        +
        +  *) New SSL API mode 'SSL_MODE_AUTO_RETRY'.  This disables the default
        +     behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if
        +     the underlying transport is blocking) if a handshake took place.
        +     (The default behaviour is needed by applications such as s_client
        +     and s_server that use select() to determine when to use SSL_read;
        +     but for applications that know in advance when to expect data, it
        +     just makes things more complicated.)
        +     [Bodo Moeller]
        +
        +  *) Add RAND_egd_bytes(), which gives control over the number of bytes read
        +     from EGD.
        +     [Ben Laurie]
        +
        +  *) Add a few more EBCDIC conditionals that make `req' and `x509'
        +     work better on such systems.
        +     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
        +
        +  *) Add two demo programs for PKCS12_parse() and PKCS12_create().
        +     Update PKCS12_parse() so it copies the friendlyName and the
        +     keyid to the certificates aux info.
        +     [Steve Henson]
        +
        +  *) Fix bug in PKCS7_verify() which caused an infinite loop
        +     if there was more than one signature.
        +     [Sven Uszpelkat <su@celocom.de>]
        +
        +  *) Major change in util/mkdef.pl to include extra information
        +     about each symbol, as well as presentig variables as well
        +     as functions.  This change means that there's n more need
        +     to rebuild the .num files when some algorithms are excluded.
        +     [Richard Levitte]
        +
        +  *) Allow the verify time to be set by an application,
        +     rather than always using the current time.
        +     [Steve Henson]
        +  
        +  *) Phase 2 verify code reorganisation. The certificate
        +     verify code now looks up an issuer certificate by a
        +     number of criteria: subject name, authority key id
        +     and key usage. It also verifies self signed certificates
        +     by the same criteria. The main comparison function is
        +     X509_check_issued() which performs these checks.
        + 
        +     Lot of changes were necessary in order to support this
        +     without completely rewriting the lookup code.
        + 
        +     Authority and subject key identifier are now cached.
        + 
        +     The LHASH 'certs' is X509_STORE has now been replaced
        +     by a STACK_OF(X509_OBJECT). This is mainly because an
        +     LHASH can't store or retrieve multiple objects with
        +     the same hash value.
        +
        +     As a result various functions (which were all internal
        +     use only) have changed to handle the new X509_STORE
        +     structure. This will break anything that messed round
        +     with X509_STORE internally.
        + 
        +     The functions X509_STORE_add_cert() now checks for an
        +     exact match, rather than just subject name.
        + 
        +     The X509_STORE API doesn't directly support the retrieval
        +     of multiple certificates matching a given criteria, however
        +     this can be worked round by performing a lookup first
        +     (which will fill the cache with candidate certificates)
        +     and then examining the cache for matches. This is probably
        +     the best we can do without throwing out X509_LOOKUP
        +     entirely (maybe later...).
        + 
        +     The X509_VERIFY_CTX structure has been enhanced considerably.
        + 
        +     All certificate lookup operations now go via a get_issuer()
        +     callback. Although this currently uses an X509_STORE it
        +     can be replaced by custom lookups. This is a simple way
        +     to bypass the X509_STORE hackery necessary to make this
        +     work and makes it possible to use more efficient techniques
        +     in future. A very simple version which uses a simple
        +     STACK for its trusted certificate store is also provided
        +     using X509_STORE_CTX_trusted_stack().
        + 
        +     The verify_cb() and verify() callbacks now have equivalents
        +     in the X509_STORE_CTX structure.
        + 
        +     X509_STORE_CTX also has a 'flags' field which can be used
        +     to customise the verify behaviour.
        +     [Steve Henson]
        + 
        +  *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which 
        +     excludes S/MIME capabilities.
        +     [Steve Henson]
        +
        +  *) When a certificate request is read in keep a copy of the
        +     original encoding of the signed data and use it when outputing
        +     again. Signatures then use the original encoding rather than
        +     a decoded, encoded version which may cause problems if the
        +     request is improperly encoded.
        +     [Steve Henson]
        +
        +  *) For consistency with other BIO_puts implementations, call
        +     buffer_write(b, ...) directly in buffer_puts instead of calling
        +     BIO_write(b, ...).
        +
        +     In BIO_puts, increment b->num_write as in BIO_write.
        +     [Peter.Sylvester@EdelWeb.fr]
        +
        +  *) Fix BN_mul_word for the case where the word is 0. (We have to use
        +     BN_zero, we may not return a BIGNUM with an array consisting of
        +     words set to zero.)
        +     [Bodo Moeller]
        +
        +  *) Avoid calling abort() from within the library when problems are
        +     detected, except if preprocessor symbols have been defined
        +     (such as REF_CHECK, BN_DEBUG etc.).
        +     [Bodo Moeller]
        +
        +  *) New openssl application 'rsautl'. This utility can be
        +     used for low level RSA operations. DER public key
        +     BIO/fp routines also added.
        +     [Steve Henson]
        +
        +  *) New Configure entry and patches for compiling on QNX 4.
        +     [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
        +
        +  *) A demo state-machine implementation was sponsored by
        +     Nuron (http://www.nuron.com/) and is now available in
        +     demos/state_machine.
        +     [Ben Laurie]
        +
        +  *) New options added to the 'dgst' utility for signature
        +     generation and verification.
        +     [Steve Henson]
        +
        +  *) Unrecognized PKCS#7 content types are now handled via a
        +     catch all ASN1_TYPE structure. This allows unsupported
        +     types to be stored as a "blob" and an application can
        +     encode and decode it manually.
        +     [Steve Henson]
        +
        +  *) Fix various signed/unsigned issues to make a_strex.c
        +     compile under VC++.
        +     [Oscar Jacobsson <oscar.jacobsson@celocom.com>]
        +
        +  *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct
        +     length if passed a buffer. ASN1_INTEGER_to_BN failed
        +     if passed a NULL BN and its argument was negative.
        +     [Steve Henson, pointed out by Sven Heiberg <sven@tartu.cyber.ee>]
        +
        +  *) Modification to PKCS#7 encoding routines to output definite
        +     length encoding. Since currently the whole structures are in
        +     memory there's not real point in using indefinite length 
        +     constructed encoding. However if OpenSSL is compiled with
        +     the flag PKCS7_INDEFINITE_ENCODING the old form is used.
        +     [Steve Henson]
        +
        +  *) Added BIO_vprintf() and BIO_vsnprintf().
        +     [Richard Levitte]
        +
        +  *) Added more prefixes to parse for in the the strings written
        +     through a logging bio, to cover all the levels that are available
        +     through syslog.  The prefixes are now:
        +
        +	PANIC, EMERG, EMR	=>	LOG_EMERG
        +	ALERT, ALR		=>	LOG_ALERT
        +	CRIT, CRI		=>	LOG_CRIT
        +	ERROR, ERR		=>	LOG_ERR
        +	WARNING, WARN, WAR	=>	LOG_WARNING
        +	NOTICE, NOTE, NOT	=>	LOG_NOTICE
        +	INFO, INF		=>	LOG_INFO
        +	DEBUG, DBG		=>	LOG_DEBUG
        +
        +     and as before, if none of those prefixes are present at the
        +     beginning of the string, LOG_ERR is chosen.
        +
        +     On Win32, the LOG_* levels are mapped according to this:
        +
        +	LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR	=> EVENTLOG_ERROR_TYPE
        +	LOG_WARNING				=> EVENTLOG_WARNING_TYPE
        +	LOG_NOTICE, LOG_INFO, LOG_DEBUG		=> EVENTLOG_INFORMATION_TYPE
        +
        +     [Richard Levitte]
        +
        +  *) Made it possible to reconfigure with just the configuration
        +     argument "reconf" or "reconfigure".  The command line arguments
        +     are stored in Makefile.ssl in the variable CONFIGURE_ARGS,
        +     and are retrieved from there when reconfiguring.
        +     [Richard Levitte]
        +
        +  *) MD4 implemented.
        +     [Assar Westerlund <assar@sics.se>, Richard Levitte]
        +
        +  *) Add the arguments -CAfile and -CApath to the pkcs12 utility.
        +     [Richard Levitte]
        +
        +  *) The obj_dat.pl script was messing up the sorting of object
        +     names. The reason was that it compared the quoted version
        +     of strings as a result "OCSP" > "OCSP Signing" because
        +     " > SPACE. Changed script to store unquoted versions of
        +     names and add quotes on output. It was also omitting some
        +     names from the lookup table if they were given a default
        +     value (that is if SN is missing it is given the same
        +     value as LN and vice versa), these are now added on the
        +     grounds that if an object has a name we should be able to
        +     look it up. Finally added warning output when duplicate
        +     short or long names are found.
        +     [Steve Henson]
        +
        +  *) Changes needed for Tandem NSK.
        +     [Scott Uroff <scott@xypro.com>]
        +
        +  *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in
        +     RSA_padding_check_SSLv23(), special padding was never detected
        +     and thus the SSL 3.0/TLS 1.0 countermeasure against protocol
        +     version rollback attacks was not effective.
        +
        +     In s23_clnt.c, don't use special rollback-attack detection padding
        +     (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
        +     client; similarly, in s23_srvr.c, don't do the rollback check if
        +     SSL 2.0 is the only protocol enabled in the server.
        +     [Bodo Moeller]
        +
        +  *) Make it possible to get hexdumps of unprintable data with 'openssl
        +     asn1parse'.  By implication, the functions ASN1_parse_dump() and
        +     BIO_dump_indent() are added.
        +     [Richard Levitte]
        +
        +  *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex()
        +     these print out strings and name structures based on various
        +     flags including RFC2253 support and proper handling of
        +     multibyte characters. Added options to the 'x509' utility 
        +     to allow the various flags to be set.
        +     [Steve Henson]
        +
        +  *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME.
        +     Also change the functions X509_cmp_current_time() and
        +     X509_gmtime_adj() work with an ASN1_TIME structure,
        +     this will enable certificates using GeneralizedTime in validity
        +     dates to be checked.
        +     [Steve Henson]
        +
        +  *) Make the NEG_PUBKEY_BUG code (which tolerates invalid
        +     negative public key encodings) on by default,
        +     NO_NEG_PUBKEY_BUG can be set to disable it.
        +     [Steve Henson]
        +
        +  *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT
        +     content octets. An i2c_ASN1_OBJECT is unnecessary because
        +     the encoding can be trivially obtained from the structure.
        +     [Steve Henson]
        +
        +  *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock),
        +     not read locks (CRYPTO_r_[un]lock).
        +     [Bodo Moeller]
        +
        +  *) A first attempt at creating official support for shared
        +     libraries through configuration.  I've kept it so the
        +     default is static libraries only, and the OpenSSL programs
        +     are always statically linked for now, but there are
        +     preparations for dynamic linking in place.
        +     This has been tested on Linux and Tru64.
        +     [Richard Levitte]
        +
        +  *) Randomness polling function for Win9x, as described in:
        +     Peter Gutmann, Software Generation of Practically Strong
        +     Random Numbers.
        +     [Ulf Möller]
        +
        +  *) Fix so PRNG is seeded in req if using an already existing
        +     DSA key.
        +     [Steve Henson]
        +
        +  *) New options to smime application. -inform and -outform
        +     allow alternative formats for the S/MIME message including
        +     PEM and DER. The -content option allows the content to be
        +     specified separately. This should allow things like Netscape
        +     form signing output easier to verify.
        +     [Steve Henson]
        +
        +  *) Fix the ASN1 encoding of tags using the 'long form'.
        +     [Steve Henson]
        +
        +  *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT
        +     STRING types. These convert content octets to and from the
        +     underlying type. The actual tag and length octets are
        +     already assumed to have been read in and checked. These
        +     are needed because all other string types have virtually
        +     identical handling apart from the tag. By having versions
        +     of the ASN1 functions that just operate on content octets
        +     IMPLICIT tagging can be handled properly. It also allows
        +     the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED
        +     and ASN1_INTEGER are identical apart from the tag.
        +     [Steve Henson]
        +
        +  *) Change the handling of OID objects as follows:
        +
        +     - New object identifiers are inserted in objects.txt, following
        +       the syntax given in objects.README.
        +     - objects.pl is used to process obj_mac.num and create a new
        +       obj_mac.h.
        +     - obj_dat.pl is used to create a new obj_dat.h, using the data in
        +       obj_mac.h.
        +
        +     This is currently kind of a hack, and the perl code in objects.pl
        +     isn't very elegant, but it works as I intended.  The simplest way
        +     to check that it worked correctly is to look in obj_dat.h and
        +     check the array nid_objs and make sure the objects haven't moved
        +     around (this is important!).  Additions are OK, as well as
        +     consistent name changes. 
        +     [Richard Levitte]
        +
        +  *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1').
        +     [Bodo Moeller]
        +
        +  *) Addition of the command line parameter '-rand file' to 'openssl req'.
        +     The given file adds to whatever has already been seeded into the
        +     random pool through the RANDFILE configuration file option or
        +     environment variable, or the default random state file.
        +     [Richard Levitte]
        +
        +  *) mkstack.pl now sorts each macro group into lexical order.
        +     Previously the output order depended on the order the files
        +     appeared in the directory, resulting in needless rewriting
        +     of safestack.h .
        +     [Steve Henson]
        +
        +  *) Patches to make OpenSSL compile under Win32 again. Mostly
        +     work arounds for the VC++ problem that it treats func() as
        +     func(void). Also stripped out the parts of mkdef.pl that
        +     added extra typesafe functions: these no longer exist.
        +     [Steve Henson]
        +
        +  *) Reorganisation of the stack code. The macros are now all 
        +     collected in safestack.h . Each macro is defined in terms of
        +     a "stack macro" of the form SKM_<name>(type, a, b). The 
        +     DEBUG_SAFESTACK is now handled in terms of function casts,
        +     this has the advantage of retaining type safety without the
        +     use of additional functions. If DEBUG_SAFESTACK is not defined
        +     then the non typesafe macros are used instead. Also modified the
        +     mkstack.pl script to handle the new form. Needs testing to see
        +     if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK
        +     the default if no major problems. Similar behaviour for ASN1_SET_OF
        +     and PKCS12_STACK_OF.
        +     [Steve Henson]
        +
        +  *) When some versions of IIS use the 'NET' form of private key the
        +     key derivation algorithm is different. Normally MD5(password) is
        +     used as a 128 bit RC4 key. In the modified case
        +     MD5(MD5(password) + "SGCKEYSALT")  is used insted. Added some
        +     new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same
        +     as the old Netscape_RSA functions except they have an additional
        +     'sgckey' parameter which uses the modified algorithm. Also added
        +     an -sgckey command line option to the rsa utility. Thanks to 
        +     Adrian Peck <bertie@ncipher.com> for posting details of the modified
        +     algorithm to openssl-dev.
        +     [Steve Henson]
        +
        +  *) The evp_local.h macros were using 'c.##kname' which resulted in
        +     invalid expansion on some systems (SCO 5.0.5 for example).
        +     Corrected to 'c.kname'.
        +     [Phillip Porch <root@theporch.com>]
        +
        +  *) New X509_get1_email() and X509_REQ_get1_email() functions that return
        +     a STACK of email addresses from a certificate or request, these look
        +     in the subject name and the subject alternative name extensions and 
        +     omit any duplicate addresses.
        +     [Steve Henson]
        +
        +  *) Re-implement BN_mod_exp2_mont using independent (and larger) windows.
        +     This makes DSA verification about 2 % faster.
        +     [Bodo Moeller]
        +
        +  *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5
        +     (meaning that now 2^5 values will be precomputed, which is only 4 KB
        +     plus overhead for 1024 bit moduli).
        +     This makes exponentiations about 0.5 % faster for 1024 bit
        +     exponents (as measured by "openssl speed rsa2048").
        +     [Bodo Moeller]
        +
        +  *) Rename memory handling macros to avoid conflicts with other
        +     software:
        +          Malloc         =>  OPENSSL_malloc
        +          Malloc_locked  =>  OPENSSL_malloc_locked
        +          Realloc        =>  OPENSSL_realloc
        +          Free           =>  OPENSSL_free
        +     [Richard Levitte]
        +
        +  *) New function BN_mod_exp_mont_word for small bases (roughly 15%
        +     faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange).
        +     [Bodo Moeller]
        +
        +  *) CygWin32 support.
        +     [John Jarvie <jjarvie@newsguy.com>]
        +
        +  *) The type-safe stack code has been rejigged. It is now only compiled
        +     in when OpenSSL is configured with the DEBUG_SAFESTACK option and
        +     by default all type-specific stack functions are "#define"d back to
        +     standard stack functions. This results in more streamlined output
        +     but retains the type-safety checking possibilities of the original
        +     approach.
        +     [Geoff Thorpe]
        +
        +  *) The STACK code has been cleaned up, and certain type declarations
        +     that didn't make a lot of sense have been brought in line. This has
        +     also involved a cleanup of sorts in safestack.h to more correctly
        +     map type-safe stack functions onto their plain stack counterparts.
        +     This work has also resulted in a variety of "const"ifications of
        +     lots of the code, especially "_cmp" operations which should normally
        +     be prototyped with "const" parameters anyway.
        +     [Geoff Thorpe]
        +
        +  *) When generating bytes for the first time in md_rand.c, 'stir the pool'
        +     by seeding with STATE_SIZE dummy bytes (with zero entropy count).
        +     (The PRNG state consists of two parts, the large pool 'state' and 'md',
        +     where all of 'md' is used each time the PRNG is used, but 'state'
        +     is used only indexed by a cyclic counter. As entropy may not be
        +     well distributed from the beginning, 'md' is important as a
        +     chaining variable. However, the output function chains only half
        +     of 'md', i.e. 80 bits.  ssleay_rand_add, on the other hand, chains
        +     all of 'md', and seeding with STATE_SIZE dummy bytes will result
        +     in all of 'state' being rewritten, with the new values depending
        +     on virtually all of 'md'.  This overcomes the 80 bit limitation.)
        +     [Bodo Moeller]
        +
        +  *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
        +     the handshake is continued after ssl_verify_cert_chain();
        +     otherwise, if SSL_VERIFY_NONE is set, remaining error codes
        +     can lead to 'unexplainable' connection aborts later.
        +     [Bodo Moeller; problem tracked down by Lutz Jaenicke]
        +
        +  *) Major EVP API cipher revision.
        +     Add hooks for extra EVP features. This allows various cipher
        +     parameters to be set in the EVP interface. Support added for variable
        +     key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and
        +     setting of RC2 and RC5 parameters.
        +
        +     Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length
        +     ciphers.
        +
        +     Remove lots of duplicated code from the EVP library. For example *every*
        +     cipher init() function handles the 'iv' in the same way according to the
        +     cipher mode. They also all do nothing if the 'key' parameter is NULL and
        +     for CFB and OFB modes they zero ctx->num.
        +
        +     New functionality allows removal of S/MIME code RC2 hack.
        +
        +     Most of the routines have the same form and so can be declared in terms
        +     of macros.
        +
        +     By shifting this to the top level EVP_CipherInit() it can be removed from
        +     all individual ciphers. If the cipher wants to handle IVs or keys
        +     differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT
        +     flags.
        +
        +     Change lots of functions like EVP_EncryptUpdate() to now return a
        +     value: although software versions of the algorithms cannot fail
        +     any installed hardware versions can.
        +     [Steve Henson]
        +
        +  *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if
        +     this option is set, tolerate broken clients that send the negotiated
        +     protocol version number instead of the requested protocol version
        +     number.
        +     [Bodo Moeller]
        +
        +  *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag;
        +     i.e. non-zero for export ciphersuites, zero otherwise.
        +     Previous versions had this flag inverted, inconsistent with
        +     rsa_tmp_cb (..._TMP_RSA_CB).
        +     [Bodo Moeller; problem reported by Amit Chopra]
        +
        +  *) Add missing DSA library text string. Work around for some IIS
        +     key files with invalid SEQUENCE encoding.
        +     [Steve Henson]
        +
        +  *) Add a document (doc/standards.txt) that list all kinds of standards
        +     and so on that are implemented in OpenSSL.
        +     [Richard Levitte]
        +
        +  *) Enhance c_rehash script. Old version would mishandle certificates
        +     with the same subject name hash and wouldn't handle CRLs at all.
        +     Added -fingerprint option to crl utility, to support new c_rehash
        +     features.
        +     [Steve Henson]
        +
        +  *) Eliminate non-ANSI declarations in crypto.h and stack.h.
        +     [Ulf Möller]
        +
        +  *) Fix for SSL server purpose checking. Server checking was
        +     rejecting certificates which had extended key usage present
        +     but no ssl client purpose.
        +     [Steve Henson, reported by Rene Grosser <grosser@hisolutions.com>]
        +
        +  *) Make PKCS#12 code work with no password. The PKCS#12 spec
        +     is a little unclear about how a blank password is handled.
        +     Since the password in encoded as a BMPString with terminating
        +     double NULL a zero length password would end up as just the
        +     double NULL. However no password at all is different and is
        +     handled differently in the PKCS#12 key generation code. NS
        +     treats a blank password as zero length. MSIE treats it as no
        +     password on export: but it will try both on import. We now do
        +     the same: PKCS12_parse() tries zero length and no password if
        +     the password is set to "" or NULL (NULL is now a valid password:
        +     it wasn't before) as does the pkcs12 application.
        +     [Steve Henson]
        +
        +  *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use
        +     perror when PEM_read_bio_X509_REQ fails, the error message must
        +     be obtained from the error queue.
        +     [Bodo Moeller]
        +
        +  *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing
        +     it in ERR_remove_state if appropriate, and change ERR_get_state
        +     accordingly to avoid race conditions (this is necessary because
        +     thread_hash is no longer constant once set).
        +     [Bodo Moeller]
        +
        +  *) Bugfix for linux-elf makefile.one.
        +     [Ulf Möller]
        +
        +  *) RSA_get_default_method() will now cause a default
        +     RSA_METHOD to be chosen if one doesn't exist already.
        +     Previously this was only set during a call to RSA_new()
        +     or RSA_new_method(NULL) meaning it was possible for
        +     RSA_get_default_method() to return NULL.
        +     [Geoff Thorpe]
        +
        +  *) Added native name translation to the existing DSO code
        +     that will convert (if the flag to do so is set) filenames
        +     that are sufficiently small and have no path information
        +     into a canonical native form. Eg. "blah" converted to
        +     "libblah.so" or "blah.dll" etc.
        +     [Geoff Thorpe]
        +
        +  *) New function ERR_error_string_n(e, buf, len) which is like
        +     ERR_error_string(e, buf), but writes at most 'len' bytes
        +     including the 0 terminator.  For ERR_error_string_n, 'buf'
        +     may not be NULL.
        +     [Damien Miller <djm@mindrot.org>, Bodo Moeller]
        +
        +  *) CONF library reworked to become more general.  A new CONF
        +     configuration file reader "class" is implemented as well as a
        +     new functions (NCONF_*, for "New CONF") to handle it.  The now
        +     old CONF_* functions are still there, but are reimplemented to
        +     work in terms of the new functions.  Also, a set of functions
        +     to handle the internal storage of the configuration data is
        +     provided to make it easier to write new configuration file
        +     reader "classes" (I can definitely see something reading a
        +     configuration file in XML format, for example), called _CONF_*,
        +     or "the configuration storage API"...
        +
        +     The new configuration file reading functions are:
        +
        +        NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio,
        +        NCONF_get_section, NCONF_get_string, NCONF_get_numbre
        +
        +        NCONF_default, NCONF_WIN32
        +
        +        NCONF_dump_fp, NCONF_dump_bio
        +
        +     NCONF_default and NCONF_WIN32 are method (or "class") choosers,
        +     NCONF_new creates a new CONF object.  This works in the same way
        +     as other interfaces in OpenSSL, like the BIO interface.
        +     NCONF_dump_* dump the internal storage of the configuration file,
        +     which is useful for debugging.  All other functions take the same
        +     arguments as the old CONF_* functions wth the exception of the
        +     first that must be a `CONF *' instead of a `LHASH *'.
        +
        +     To make it easer to use the new classes with the old CONF_* functions,
        +     the function CONF_set_default_method is provided.
        +     [Richard Levitte]
        +
        +  *) Add '-tls1' option to 'openssl ciphers', which was already
        +     mentioned in the documentation but had not been implemented.
        +     (This option is not yet really useful because even the additional
        +     experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.)
        +     [Bodo Moeller]
        +
        +  *) Initial DSO code added into libcrypto for letting OpenSSL (and
        +     OpenSSL-based applications) load shared libraries and bind to
        +     them in a portable way.
        +     [Geoff Thorpe, with contributions from Richard Levitte]
        +
        + Changes between 0.9.5 and 0.9.5a  [1 Apr 2000]
        +
        +  *) Make sure _lrotl and _lrotr are only used with MSVC.
        +
        +  *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status
        +     (the default implementation of RAND_status).
        +
        +  *) Rename openssl x509 option '-crlext', which was added in 0.9.5,
        +     to '-clrext' (= clear extensions), as intended and documented.
        +     [Bodo Moeller; inconsistency pointed out by Michael Attili
        +     <attili@amaxo.com>]
        +
        +  *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length
        +     was larger than the MD block size.      
        +     [Steve Henson, pointed out by Yost William <YostW@tce.com>]
        +
        +  *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument
        +     fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set()
        +     using the passed key: if the passed key was a private key the result
        +     of X509_print(), for example, would be to print out all the private key
        +     components.
        +     [Steve Henson]
        +
        +  *) des_quad_cksum() byte order bug fix.
        +     [Ulf Möller, using the problem description in krb4-0.9.7, where
        +      the solution is attributed to Derrick J Brashear <shadow@DEMENTIA.ORG>]
        +
        +  *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly
        +     discouraged.
        +     [Steve Henson, pointed out by Brian Korver <briank@cs.stanford.edu>]
        +
        +  *) For easily testing in shell scripts whether some command
        +     'openssl XXX' exists, the new pseudo-command 'openssl no-XXX'
        +     returns with exit code 0 iff no command of the given name is available.
        +     'no-XXX' is printed in this case, 'XXX' otherwise.  In both cases,
        +     the output goes to stdout and nothing is printed to stderr.
        +     Additional arguments are always ignored.
        +
        +     Since for each cipher there is a command of the same name,
        +     the 'no-cipher' compilation switches can be tested this way.
        +
        +     ('openssl no-XXX' is not able to detect pseudo-commands such
        +     as 'quit', 'list-XXX-commands', or 'no-XXX' itself.)
        +     [Bodo Moeller]
        +
        +  *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration.
        +     [Bodo Moeller]
        +
        +  *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE
        +     is set; it will be thrown away anyway because each handshake creates
        +     its own key.
        +     ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition
        +     to parameters -- in previous versions (since OpenSSL 0.9.3) the
        +     'default key' from SSL_CTX_set_tmp_dh would always be lost, meanining
        +     you effectivly got SSL_OP_SINGLE_DH_USE when using this macro.
        +     [Bodo Moeller]
        +
        +  *) New s_client option -ign_eof: EOF at stdin is ignored, and
        +     'Q' and 'R' lose their special meanings (quit/renegotiate).
        +     This is part of what -quiet does; unlike -quiet, -ign_eof
        +     does not suppress any output.
        +     [Richard Levitte]
        +
        +  *) Add compatibility options to the purpose and trust code. The
        +     purpose X509_PURPOSE_ANY is "any purpose" which automatically
        +     accepts a certificate or CA, this was the previous behaviour,
        +     with all the associated security issues.
        +
        +     X509_TRUST_COMPAT is the old trust behaviour: only and
        +     automatically trust self signed roots in certificate store. A
        +     new trust setting X509_TRUST_DEFAULT is used to specify that
        +     a purpose has no associated trust setting and it should instead
        +     use the value in the default purpose.
        +     [Steve Henson]
        +
        +  *) Fix the PKCS#8 DSA private key code so it decodes keys again
        +     and fix a memory leak.
        +     [Steve Henson]
        +
        +  *) In util/mkerr.pl (which implements 'make errors'), preserve
        +     reason strings from the previous version of the .c file, as
        +     the default to have only downcase letters (and digits) in
        +     automatically generated reasons codes is not always appropriate.
        +     [Bodo Moeller]
        +
        +  *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table
        +     using strerror.  Previously, ERR_reason_error_string() returned
        +     library names as reason strings for SYSerr; but SYSerr is a special
        +     case where small numbers are errno values, not library numbers.
        +     [Bodo Moeller]
        +
        +  *) Add '-dsaparam' option to 'openssl dhparam' application.  This
        +     converts DSA parameters into DH parameters. (When creating parameters,
        +     DSA_generate_parameters is used.)
        +     [Bodo Moeller]
        +
        +  *) Include 'length' (recommended exponent length) in C code generated
        +     by 'openssl dhparam -C'.
        +     [Bodo Moeller]
        +
        +  *) The second argument to set_label in perlasm was already being used
        +     so couldn't be used as a "file scope" flag. Moved to third argument
        +     which was free.
        +     [Steve Henson]
        +
        +  *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes
        +     instead of RAND_bytes for encryption IVs and salts.
        +     [Bodo Moeller]
        +
        +  *) Include RAND_status() into RAND_METHOD instead of implementing
        +     it only for md_rand.c  Otherwise replacing the PRNG by calling
        +     RAND_set_rand_method would be impossible.
        +     [Bodo Moeller]
        +
        +  *) Don't let DSA_generate_key() enter an infinite loop if the random
        +     number generation fails.
        +     [Bodo Moeller]
        +
        +  *) New 'rand' application for creating pseudo-random output.
        +     [Bodo Moeller]
        +
        +  *) Added configuration support for Linux/IA64
        +     [Rolf Haberrecker <rolf@suse.de>]
        +
        +  *) Assembler module support for Mingw32.
        +     [Ulf Möller]
        +
        +  *) Shared library support for HPUX (in shlib/).
        +     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> and Anonymous]
        +
        +  *) Shared library support for Solaris gcc.
        +     [Lutz Behnke <behnke@trustcenter.de>]
        +
        + Changes between 0.9.4 and 0.9.5  [28 Feb 2000]
        +
        +  *) PKCS7_encrypt() was adding text MIME headers twice because they
        +     were added manually and by SMIME_crlf_copy().
        +     [Steve Henson]
        +
        +  *) In bntest.c don't call BN_rand with zero bits argument.
        +     [Steve Henson, pointed out by Andrew W. Gray <agray@iconsinc.com>]
        +
        +  *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n]
        +     case was implemented. This caused BN_div_recp() to fail occasionally.
        +     [Ulf Möller]
        +
        +  *) Add an optional second argument to the set_label() in the perl
        +     assembly language builder. If this argument exists and is set
        +     to 1 it signals that the assembler should use a symbol whose 
        +     scope is the entire file, not just the current function. This
        +     is needed with MASM which uses the format label:: for this scope.
        +     [Steve Henson, pointed out by Peter Runestig <peter@runestig.com>]
        +
        +  *) Change the ASN1 types so they are typedefs by default. Before
        +     almost all types were #define'd to ASN1_STRING which was causing
        +     STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING)
        +     for example.
        +     [Steve Henson]
        +
        +  *) Change names of new functions to the new get1/get0 naming
        +     convention: After 'get1', the caller owns a reference count
        +     and has to call ..._free; 'get0' returns a pointer to some
        +     data structure without incrementing reference counters.
        +     (Some of the existing 'get' functions increment a reference
        +     counter, some don't.)
        +     Similarly, 'set1' and 'add1' functions increase reference
        +     counters or duplicate objects.
        +     [Steve Henson]
        +
        +  *) Allow for the possibility of temp RSA key generation failure:
        +     the code used to assume it always worked and crashed on failure.
        +     [Steve Henson]
        +
        +  *) Fix potential buffer overrun problem in BIO_printf().
        +     [Ulf Möller, using public domain code by Patrick Powell; problem
        +      pointed out by David Sacerdote <das33@cornell.edu>]
        +
        +  *) Support EGD <http://www.lothar.com/tech/crypto/>.  New functions
        +     RAND_egd() and RAND_status().  In the command line application,
        +     the EGD socket can be specified like a seed file using RANDFILE
        +     or -rand.
        +     [Ulf Möller]
        +
        +  *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures.
        +     Some CAs (e.g. Verisign) distribute certificates in this form.
        +     [Steve Henson]
        +
        +  *) Remove the SSL_ALLOW_ADH compile option and set the default cipher
        +     list to exclude them. This means that no special compilation option
        +     is needed to use anonymous DH: it just needs to be included in the
        +     cipher list.
        +     [Steve Henson]
        +
        +  *) Change the EVP_MD_CTX_type macro so its meaning consistent with
        +     EVP_MD_type. The old functionality is available in a new macro called
        +     EVP_MD_md(). Change code that uses it and update docs.
        +     [Steve Henson]
        +
        +  *) ..._ctrl functions now have corresponding ..._callback_ctrl functions
        +     where the 'void *' argument is replaced by a function pointer argument.
        +     Previously 'void *' was abused to point to functions, which works on
        +     many platforms, but is not correct.  As these functions are usually
        +     called by macros defined in OpenSSL header files, most source code
        +     should work without changes.
        +     [Richard Levitte]
        +
        +  *) <openssl/opensslconf.h> (which is created by Configure) now contains
        +     sections with information on -D... compiler switches used for
        +     compiling the library so that applications can see them.  To enable
        +     one of these sections, a pre-processor symbol OPENSSL_..._DEFINES
        +     must be defined.  E.g.,
        +        #define OPENSSL_ALGORITHM_DEFINES
        +        #include <openssl/opensslconf.h>
        +     defines all pertinent NO_<algo> symbols, such as NO_IDEA, NO_RSA, etc.
        +     [Richard Levitte, Ulf and Bodo Möller]
        +
        +  *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS
        +     record layer.
        +     [Bodo Moeller]
        +
        +  *) Change the 'other' type in certificate aux info to a STACK_OF
        +     X509_ALGOR. Although not an AlgorithmIdentifier as such it has
        +     the required ASN1 format: arbitrary types determined by an OID.
        +     [Steve Henson]
        +
        +  *) Add some PEM_write_X509_REQ_NEW() functions and a command line
        +     argument to 'req'. This is not because the function is newer or
        +     better than others it just uses the work 'NEW' in the certificate
        +     request header lines. Some software needs this.
        +     [Steve Henson]
        +
        +  *) Reorganise password command line arguments: now passwords can be
        +     obtained from various sources. Delete the PEM_cb function and make
        +     it the default behaviour: i.e. if the callback is NULL and the
        +     usrdata argument is not NULL interpret it as a null terminated pass
        +     phrase. If usrdata and the callback are NULL then the pass phrase
        +     is prompted for as usual.
        +     [Steve Henson]
        +
        +  *) Add support for the Compaq Atalla crypto accelerator. If it is installed,
        +     the support is automatically enabled. The resulting binaries will
        +     autodetect the card and use it if present.
        +     [Ben Laurie and Compaq Inc.]
        +
        +  *) Work around for Netscape hang bug. This sends certificate request
        +     and server done in one record. Since this is perfectly legal in the
        +     SSL/TLS protocol it isn't a "bug" option and is on by default. See
        +     the bugs/SSLv3 entry for more info.
        +     [Steve Henson]
        +
        +  *) HP-UX tune-up: new unified configs, HP C compiler bug workaround.
        +     [Andy Polyakov]
        +
        +  *) Add -rand argument to smime and pkcs12 applications and read/write
        +     of seed file.
        +     [Steve Henson]
        +
        +  *) New 'passwd' tool for crypt(3) and apr1 password hashes.
        +     [Bodo Moeller]
        +
        +  *) Add command line password options to the remaining applications.
        +     [Steve Henson]
        +
        +  *) Bug fix for BN_div_recp() for numerators with an even number of
        +     bits.
        +     [Ulf Möller]
        +
        +  *) More tests in bntest.c, and changed test_bn output.
        +     [Ulf Möller]
        +
        +  *) ./config recognizes MacOS X now.
        +     [Andy Polyakov]
        +
        +  *) Bug fix for BN_div() when the first words of num and divsor are
        +     equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0).
        +     [Ulf Möller]
        +
        +  *) Add support for various broken PKCS#8 formats, and command line
        +     options to produce them.
        +     [Steve Henson]
        +
        +  *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
        +     get temporary BIGNUMs from a BN_CTX.
        +     [Ulf Möller]
        +
        +  *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont()
        +     for p == 0.
        +     [Ulf Möller]
        +
        +  *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and
        +     include a #define from the old name to the new. The original intent
        +     was that statically linked binaries could for example just call
        +     SSLeay_add_all_ciphers() to just add ciphers to the table and not
        +     link with digests. This never worked becayse SSLeay_add_all_digests()
        +     and SSLeay_add_all_ciphers() were in the same source file so calling
        +     one would link with the other. They are now in separate source files.
        +     [Steve Henson]
        +
        +  *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'.
        +     [Steve Henson]
        +
        +  *) Use a less unusual form of the Miller-Rabin primality test (it used
        +     a binary algorithm for exponentiation integrated into the Miller-Rabin
        +     loop, our standard modexp algorithms are faster).
        +     [Bodo Moeller]
        +
        +  *) Support for the EBCDIC character set completed.
        +     [Martin Kraemer <Martin.Kraemer@Mch.SNI.De>]
        +
        +  *) Source code cleanups: use const where appropriate, eliminate casts,
        +     use void * instead of char * in lhash.
        +     [Ulf Möller] 
        +
        +  *) Bugfix: ssl3_send_server_key_exchange was not restartable
        +     (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of
        +     this the server could overwrite ephemeral keys that the client
        +     has already seen).
        +     [Bodo Moeller]
        +
        +  *) Turn DSA_is_prime into a macro that calls BN_is_prime,
        +     using 50 iterations of the Rabin-Miller test.
        +
        +     DSA_generate_parameters now uses BN_is_prime_fasttest (with 50
        +     iterations of the Rabin-Miller test as required by the appendix
        +     to FIPS PUB 186[-1]) instead of DSA_is_prime.
        +     As BN_is_prime_fasttest includes trial division, DSA parameter
        +     generation becomes much faster.
        +
        +     This implies a change for the callback functions in DSA_is_prime
        +     and DSA_generate_parameters: The callback function is called once
        +     for each positive witness in the Rabin-Miller test, not just
        +     occasionally in the inner loop; and the parameters to the
        +     callback function now provide an iteration count for the outer
        +     loop rather than for the current invocation of the inner loop.
        +     DSA_generate_parameters additionally can call the callback
        +     function with an 'iteration count' of -1, meaning that a
        +     candidate has passed the trial division test (when q is generated 
        +     from an application-provided seed, trial division is skipped).
        +     [Bodo Moeller]
        +
        +  *) New function BN_is_prime_fasttest that optionally does trial
        +     division before starting the Rabin-Miller test and has
        +     an additional BN_CTX * argument (whereas BN_is_prime always
        +     has to allocate at least one BN_CTX).
        +     'callback(1, -1, cb_arg)' is called when a number has passed the
        +     trial division stage.
        +     [Bodo Moeller]
        +
        +  *) Fix for bug in CRL encoding. The validity dates weren't being handled
        +     as ASN1_TIME.
        +     [Steve Henson]
        +
        +  *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file.
        +     [Steve Henson]
        +
        +  *) New function BN_pseudo_rand().
        +     [Ulf Möller]
        +
        +  *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable)
        +     bignum version of BN_from_montgomery() with the working code from
        +     SSLeay 0.9.0 (the word based version is faster anyway), and clean up
        +     the comments.
        +     [Ulf Möller]
        +
        +  *) Avoid a race condition in s2_clnt.c (function get_server_hello) that
        +     made it impossible to use the same SSL_SESSION data structure in
        +     SSL2 clients in multiple threads.
        +     [Bodo Moeller]
        +
        +  *) The return value of RAND_load_file() no longer counts bytes obtained
        +     by stat().  RAND_load_file(..., -1) is new and uses the complete file
        +     to seed the PRNG (previously an explicit byte count was required).
        +     [Ulf Möller, Bodo Möller]
        +
        +  *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes
        +     used (char *) instead of (void *) and had casts all over the place.
        +     [Steve Henson]
        +
        +  *) Make BN_generate_prime() return NULL on error if ret!=NULL.
        +     [Ulf Möller]
        +
        +  *) Retain source code compatibility for BN_prime_checks macro:
        +     BN_is_prime(..., BN_prime_checks, ...) now uses
        +     BN_prime_checks_for_size to determine the appropriate number of
        +     Rabin-Miller iterations.
        +     [Ulf Möller]
        +
        +  *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
        +     DH_CHECK_P_NOT_SAFE_PRIME.
        +     (Check if this is true? OpenPGP calls them "strong".)
        +     [Ulf Möller]
        +
        +  *) Merge the functionality of "dh" and "gendh" programs into a new program
        +     "dhparam". The old programs are retained for now but will handle DH keys
        +     (instead of parameters) in future.
        +     [Steve Henson]
        +
        +  *) Make the ciphers, s_server and s_client programs check the return values
        +     when a new cipher list is set.
        +     [Steve Henson]
        +
        +  *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit
        +     ciphers. Before when the 56bit ciphers were enabled the sorting was
        +     wrong.
        +
        +     The syntax for the cipher sorting has been extended to support sorting by
        +     cipher-strength (using the strength_bits hard coded in the tables).
        +     The new command is "@STRENGTH" (see also doc/apps/ciphers.pod).
        +
        +     Fix a bug in the cipher-command parser: when supplying a cipher command
        +     string with an "undefined" symbol (neither command nor alphanumeric
        +     [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now
        +     an error is flagged.
        +
        +     Due to the strength-sorting extension, the code of the
        +     ssl_create_cipher_list() function was completely rearranged. I hope that
        +     the readability was also increased :-)
        +     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
        +
        +  *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1
        +     for the first serial number and places 2 in the serial number file. This
        +     avoids problems when the root CA is created with serial number zero and
        +     the first user certificate has the same issuer name and serial number
        +     as the root CA.
        +     [Steve Henson]
        +
        +  *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses
        +     the new code. Add documentation for this stuff.
        +     [Steve Henson]
        +
        +  *) Changes to X509_ATTRIBUTE utilities. These have been renamed from
        +     X509_*() to X509at_*() on the grounds that they don't handle X509
        +     structures and behave in an analagous way to the X509v3 functions:
        +     they shouldn't be called directly but wrapper functions should be used
        +     instead.
        +
        +     So we also now have some wrapper functions that call the X509at functions
        +     when passed certificate requests. (TO DO: similar things can be done with
        +     PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other
        +     things. Some of these need some d2i or i2d and print functionality
        +     because they handle more complex structures.)
        +     [Steve Henson]
        +
        +  *) Add missing #ifndefs that caused missing symbols when building libssl
        +     as a shared library without RSA.  Use #ifndef NO_SSL2 instead of
        +     NO_RSA in ssl/s2*.c. 
        +     [Kris Kennaway <kris@hub.freebsd.org>, modified by Ulf Möller]
        +
        +  *) Precautions against using the PRNG uninitialized: RAND_bytes() now
        +     has a return value which indicates the quality of the random data
        +     (1 = ok, 0 = not seeded).  Also an error is recorded on the thread's
        +     error queue. New function RAND_pseudo_bytes() generates output that is
        +     guaranteed to be unique but not unpredictable. RAND_add is like
        +     RAND_seed, but takes an extra argument for an entropy estimate
        +     (RAND_seed always assumes full entropy).
        +     [Ulf Möller]
        +
        +  *) Do more iterations of Rabin-Miller probable prime test (specifically,
        +     3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
        +     instead of only 2 for all lengths; see BN_prime_checks_for_size definition
        +     in crypto/bn/bn_prime.c for the complete table).  This guarantees a
        +     false-positive rate of at most 2^-80 for random input.
        +     [Bodo Moeller]
        +
        +  *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs.
        +     [Bodo Moeller]
        +
        +  *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain
        +     in the 0.9.5 release), this returns the chain
        +     from an X509_CTX structure with a dup of the stack and all
        +     the X509 reference counts upped: so the stack will exist
        +     after X509_CTX_cleanup() has been called. Modify pkcs12.c
        +     to use this.
        +
        +     Also make SSL_SESSION_print() print out the verify return
        +     code.
        +     [Steve Henson]
        +
        +  *) Add manpage for the pkcs12 command. Also change the default
        +     behaviour so MAC iteration counts are used unless the new
        +     -nomaciter option is used. This improves file security and
        +     only older versions of MSIE (4.0 for example) need it.
        +     [Steve Henson]
        +
        +  *) Honor the no-xxx Configure options when creating .DEF files.
        +     [Ulf Möller]
        +
        +  *) Add PKCS#10 attributes to field table: challengePassword, 
        +     unstructuredName and unstructuredAddress. These are taken from
        +     draft PKCS#9 v2.0 but are compatible with v1.2 provided no 
        +     international characters are used.
        +
        +     More changes to X509_ATTRIBUTE code: allow the setting of types
        +     based on strings. Remove the 'loc' parameter when adding
        +     attributes because these will be a SET OF encoding which is sorted
        +     in ASN1 order.
        +     [Steve Henson]
        +
        +  *) Initial changes to the 'req' utility to allow request generation
        +     automation. This will allow an application to just generate a template
        +     file containing all the field values and have req construct the
        +     request.
        +
        +     Initial support for X509_ATTRIBUTE handling. Stacks of these are
        +     used all over the place including certificate requests and PKCS#7
        +     structures. They are currently handled manually where necessary with
        +     some primitive wrappers for PKCS#7. The new functions behave in a
        +     manner analogous to the X509 extension functions: they allow
        +     attributes to be looked up by NID and added.
        +
        +     Later something similar to the X509V3 code would be desirable to
        +     automatically handle the encoding, decoding and printing of the
        +     more complex types. The string types like challengePassword can
        +     be handled by the string table functions.
        +
        +     Also modified the multi byte string table handling. Now there is
        +     a 'global mask' which masks out certain types. The table itself
        +     can use the flag STABLE_NO_MASK to ignore the mask setting: this
        +     is useful when for example there is only one permissible type
        +     (as in countryName) and using the mask might result in no valid
        +     types at all.
        +     [Steve Henson]
        +
        +  *) Clean up 'Finished' handling, and add functions SSL_get_finished and
        +     SSL_get_peer_finished to allow applications to obtain the latest
        +     Finished messages sent to the peer or expected from the peer,
        +     respectively.  (SSL_get_peer_finished is usually the Finished message
        +     actually received from the peer, otherwise the protocol will be aborted.)
        +
        +     As the Finished message are message digests of the complete handshake
        +     (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can
        +     be used for external authentication procedures when the authentication
        +     provided by SSL/TLS is not desired or is not enough.
        +     [Bodo Moeller]
        +
        +  *) Enhanced support for Alpha Linux is added. Now ./config checks if
        +     the host supports BWX extension and if Compaq C is present on the
        +     $PATH. Just exploiting of the BWX extension results in 20-30%
        +     performance kick for some algorithms, e.g. DES and RC4 to mention
        +     a couple. Compaq C in turn generates ~20% faster code for MD5 and
        +     SHA1.
        +     [Andy Polyakov]
        +
        +  *) Add support for MS "fast SGC". This is arguably a violation of the
        +     SSL3/TLS protocol. Netscape SGC does two handshakes: the first with
        +     weak crypto and after checking the certificate is SGC a second one
        +     with strong crypto. MS SGC stops the first handshake after receiving
        +     the server certificate message and sends a second client hello. Since
        +     a server will typically do all the time consuming operations before
        +     expecting any further messages from the client (server key exchange
        +     is the most expensive) there is little difference between the two.
        +
        +     To get OpenSSL to support MS SGC we have to permit a second client
        +     hello message after we have sent server done. In addition we have to
        +     reset the MAC if we do get this second client hello.
        +     [Steve Henson]
        +
        +  *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide
        +     if a DER encoded private key is RSA or DSA traditional format. Changed
        +     d2i_PrivateKey_bio() to use it. This is only needed for the "traditional"
        +     format DER encoded private key. Newer code should use PKCS#8 format which
        +     has the key type encoded in the ASN1 structure. Added DER private key
        +     support to pkcs8 application.
        +     [Steve Henson]
        +
        +  *) SSL 3/TLS 1 servers now don't request certificates when an anonymous
        +     ciphersuites has been selected (as required by the SSL 3/TLS 1
        +     specifications).  Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT
        +     is set, we interpret this as a request to violate the specification
        +     (the worst that can happen is a handshake failure, and 'correct'
        +     behaviour would result in a handshake failure anyway).
        +     [Bodo Moeller]
        +
        +  *) In SSL_CTX_add_session, take into account that there might be multiple
        +     SSL_SESSION structures with the same session ID (e.g. when two threads
        +     concurrently obtain them from an external cache).
        +     The internal cache can handle only one SSL_SESSION with a given ID,
        +     so if there's a conflict, we now throw out the old one to achieve
        +     consistency.
        +     [Bodo Moeller]
        +
        +  *) Add OIDs for idea and blowfish in CBC mode. This will allow both
        +     to be used in PKCS#5 v2.0 and S/MIME.  Also add checking to
        +     some routines that use cipher OIDs: some ciphers do not have OIDs
        +     defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for
        +     example.
        +     [Steve Henson]
        +
        +  *) Simplify the trust setting structure and code. Now we just have
        +     two sequences of OIDs for trusted and rejected settings. These will
        +     typically have values the same as the extended key usage extension
        +     and any application specific purposes.
        +
        +     The trust checking code now has a default behaviour: it will just
        +     check for an object with the same NID as the passed id. Functions can
        +     be provided to override either the default behaviour or the behaviour
        +     for a given id. SSL client, server and email already have functions
        +     in place for compatibility: they check the NID and also return "trusted"
        +     if the certificate is self signed.
        +     [Steve Henson]
        +
        +  *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the
        +     traditional format into an EVP_PKEY structure.
        +     [Steve Henson]
        +
        +  *) Add a password callback function PEM_cb() which either prompts for
        +     a password if usr_data is NULL or otherwise assumes it is a null
        +     terminated password. Allow passwords to be passed on command line
        +     environment or config files in a few more utilities.
        +     [Steve Henson]
        +
        +  *) Add a bunch of DER and PEM functions to handle PKCS#8 format private
        +     keys. Add some short names for PKCS#8 PBE algorithms and allow them
        +     to be specified on the command line for the pkcs8 and pkcs12 utilities.
        +     Update documentation.
        +     [Steve Henson]
        +
        +  *) Support for ASN1 "NULL" type. This could be handled before by using
        +     ASN1_TYPE but there wasn't any function that would try to read a NULL
        +     and produce an error if it couldn't. For compatibility we also have
        +     ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and
        +     don't allocate anything because they don't need to.
        +     [Steve Henson]
        +
        +  *) Initial support for MacOS is now provided. Examine INSTALL.MacOS
        +     for details.
        +     [Andy Polyakov, Roy Woods <roy@centicsystems.ca>]
        +
        +  *) Rebuild of the memory allocation routines used by OpenSSL code and
        +     possibly others as well.  The purpose is to make an interface that
        +     provide hooks so anyone can build a separate set of allocation and
        +     deallocation routines to be used by OpenSSL, for example memory
        +     pool implementations, or something else, which was previously hard
        +     since Malloc(), Realloc() and Free() were defined as macros having
        +     the values malloc, realloc and free, respectively (except for Win32
        +     compilations).  The same is provided for memory debugging code.
        +     OpenSSL already comes with functionality to find memory leaks, but
        +     this gives people a chance to debug other memory problems.
        +
        +     With these changes, a new set of functions and macros have appeared:
        +
        +       CRYPTO_set_mem_debug_functions()	        [F]
        +       CRYPTO_get_mem_debug_functions()         [F]
        +       CRYPTO_dbg_set_options()	                [F]
        +       CRYPTO_dbg_get_options()                 [F]
        +       CRYPTO_malloc_debug_init()               [M]
        +
        +     The memory debug functions are NULL by default, unless the library
        +     is compiled with CRYPTO_MDEBUG or friends is defined.  If someone
        +     wants to debug memory anyway, CRYPTO_malloc_debug_init() (which
        +     gives the standard debugging functions that come with OpenSSL) or
        +     CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions
        +     provided by the library user) must be used.  When the standard
        +     debugging functions are used, CRYPTO_dbg_set_options can be used to
        +     request additional information:
        +     CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting
        +     the CRYPTO_MDEBUG_xxx macro when compiling the library.   
        +
        +     Also, things like CRYPTO_set_mem_functions will always give the
        +     expected result (the new set of functions is used for allocation
        +     and deallocation) at all times, regardless of platform and compiler
        +     options.
        +
        +     To finish it up, some functions that were never use in any other
        +     way than through macros have a new API and new semantic:
        +
        +       CRYPTO_dbg_malloc()
        +       CRYPTO_dbg_realloc()
        +       CRYPTO_dbg_free()
        +
        +     All macros of value have retained their old syntax.
        +     [Richard Levitte and Bodo Moeller]
        +
        +  *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the
        +     ordering of SMIMECapabilities wasn't in "strength order" and there
        +     was a missing NULL in the AlgorithmIdentifier for the SHA1 signature
        +     algorithm.
        +     [Steve Henson]
        +
        +  *) Some ASN1 types with illegal zero length encoding (INTEGER,
        +     ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines.
        +     [Frans Heymans <fheymans@isaserver.be>, modified by Steve Henson]
        +
        +  *) Merge in my S/MIME library for OpenSSL. This provides a simple
        +     S/MIME API on top of the PKCS#7 code, a MIME parser (with enough
        +     functionality to handle multipart/signed properly) and a utility
        +     called 'smime' to call all this stuff. This is based on code I
        +     originally wrote for Celo who have kindly allowed it to be
        +     included in OpenSSL.
        +     [Steve Henson]
        +
        +  *) Add variants des_set_key_checked and des_set_key_unchecked of
        +     des_set_key (aka des_key_sched).  Global variable des_check_key
        +     decides which of these is called by des_set_key; this way
        +     des_check_key behaves as it always did, but applications and
        +     the library itself, which was buggy for des_check_key == 1,
        +     have a cleaner way to pick the version they need.
        +     [Bodo Moeller]
        +
        +  *) New function PKCS12_newpass() which changes the password of a
        +     PKCS12 structure.
        +     [Steve Henson]
        +
        +  *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and
        +     dynamic mix. In both cases the ids can be used as an index into the
        +     table. Also modified the X509_TRUST_add() and X509_PURPOSE_add()
        +     functions so they accept a list of the field values and the
        +     application doesn't need to directly manipulate the X509_TRUST
        +     structure.
        +     [Steve Henson]
        +
        +  *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't
        +     need initialising.
        +     [Steve Henson]
        +
        +  *) Modify the way the V3 extension code looks up extensions. This now
        +     works in a similar way to the object code: we have some "standard"
        +     extensions in a static table which is searched with OBJ_bsearch()
        +     and the application can add dynamic ones if needed. The file
        +     crypto/x509v3/ext_dat.h now has the info: this file needs to be
        +     updated whenever a new extension is added to the core code and kept
        +     in ext_nid order. There is a simple program 'tabtest.c' which checks
        +     this. New extensions are not added too often so this file can readily
        +     be maintained manually.
        +
        +     There are two big advantages in doing things this way. The extensions
        +     can be looked up immediately and no longer need to be "added" using
        +     X509V3_add_standard_extensions(): this function now does nothing.
        +     [Side note: I get *lots* of email saying the extension code doesn't
        +      work because people forget to call this function]
        +     Also no dynamic allocation is done unless new extensions are added:
        +     so if we don't add custom extensions there is no need to call
        +     X509V3_EXT_cleanup().
        +     [Steve Henson]
        +
        +  *) Modify enc utility's salting as follows: make salting the default. Add a
        +     magic header, so unsalted files fail gracefully instead of just decrypting
        +     to garbage. This is because not salting is a big security hole, so people
        +     should be discouraged from doing it.
        +     [Ben Laurie]
        +
        +  *) Fixes and enhancements to the 'x509' utility. It allowed a message
        +     digest to be passed on the command line but it only used this
        +     parameter when signing a certificate. Modified so all relevant
        +     operations are affected by the digest parameter including the
        +     -fingerprint and -x509toreq options. Also -x509toreq choked if a
        +     DSA key was used because it didn't fix the digest.
        +     [Steve Henson]
        +
        +  *) Initial certificate chain verify code. Currently tests the untrusted
        +     certificates for consistency with the verify purpose (which is set
        +     when the X509_STORE_CTX structure is set up) and checks the pathlength.
        +
        +     There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour:
        +     this is because it will reject chains with invalid extensions whereas
        +     every previous version of OpenSSL and SSLeay made no checks at all.
        +
        +     Trust code: checks the root CA for the relevant trust settings. Trust
        +     settings have an initial value consistent with the verify purpose: e.g.
        +     if the verify purpose is for SSL client use it expects the CA to be
        +     trusted for SSL client use. However the default value can be changed to
        +     permit custom trust settings: one example of this would be to only trust
        +     certificates from a specific "secure" set of CAs.
        +
        +     Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
        +     which should be used for version portability: especially since the
        +     verify structure is likely to change more often now.
        +
        +     SSL integration. Add purpose and trust to SSL_CTX and SSL and functions
        +     to set them. If not set then assume SSL clients will verify SSL servers
        +     and vice versa.
        +
        +     Two new options to the verify program: -untrusted allows a set of
        +     untrusted certificates to be passed in and -purpose which sets the
        +     intended purpose of the certificate. If a purpose is set then the
        +     new chain verify code is used to check extension consistency.
        +     [Steve Henson]
        +
        +  *) Support for the authority information access extension.
        +     [Steve Henson]
        +
        +  *) Modify RSA and DSA PEM read routines to transparently handle
        +     PKCS#8 format private keys. New *_PUBKEY_* functions that handle
        +     public keys in a format compatible with certificate
        +     SubjectPublicKeyInfo structures. Unfortunately there were already
        +     functions called *_PublicKey_* which used various odd formats so
        +     these are retained for compatibility: however the DSA variants were
        +     never in a public release so they have been deleted. Changed dsa/rsa
        +     utilities to handle the new format: note no releases ever handled public
        +     keys so we should be OK.
        +
        +     The primary motivation for this change is to avoid the same fiasco
        +     that dogs private keys: there are several incompatible private key
        +     formats some of which are standard and some OpenSSL specific and
        +     require various evil hacks to allow partial transparent handling and
        +     even then it doesn't work with DER formats. Given the option anything
        +     other than PKCS#8 should be dumped: but the other formats have to
        +     stay in the name of compatibility.
        +
        +     With public keys and the benefit of hindsight one standard format 
        +     is used which works with EVP_PKEY, RSA or DSA structures: though
        +     it clearly returns an error if you try to read the wrong kind of key.
        +
        +     Added a -pubkey option to the 'x509' utility to output the public key.
        +     Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*()
        +     (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add
        +     EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*())
        +     that do the same as the EVP_PKEY_assign_*() except they up the
        +     reference count of the added key (they don't "swallow" the
        +     supplied key).
        +     [Steve Henson]
        +
        +  *) Fixes to crypto/x509/by_file.c the code to read in certificates and
        +     CRLs would fail if the file contained no certificates or no CRLs:
        +     added a new function to read in both types and return the number
        +     read: this means that if none are read it will be an error. The
        +     DER versions of the certificate and CRL reader would always fail
        +     because it isn't possible to mix certificates and CRLs in DER format
        +     without choking one or the other routine. Changed this to just read
        +     a certificate: this is the best we can do. Also modified the code
        +     in apps/verify.c to take notice of return codes: it was previously
        +     attempting to read in certificates from NULL pointers and ignoring
        +     any errors: this is one reason why the cert and CRL reader seemed
        +     to work. It doesn't check return codes from the default certificate
        +     routines: these may well fail if the certificates aren't installed.
        +     [Steve Henson]
        +
        +  *) Code to support otherName option in GeneralName.
        +     [Steve Henson]
        +
        +  *) First update to verify code. Change the verify utility
        +     so it warns if it is passed a self signed certificate:
        +     for consistency with the normal behaviour. X509_verify
        +     has been modified to it will now verify a self signed
        +     certificate if *exactly* the same certificate appears
        +     in the store: it was previously impossible to trust a
        +     single self signed certificate. This means that:
        +     openssl verify ss.pem
        +     now gives a warning about a self signed certificate but
        +     openssl verify -CAfile ss.pem ss.pem
        +     is OK.
        +     [Steve Henson]
        +
        +  *) For servers, store verify_result in SSL_SESSION data structure
        +     (and add it to external session representation).
        +     This is needed when client certificate verifications fails,
        +     but an application-provided verification callback (set by
        +     SSL_CTX_set_cert_verify_callback) allows accepting the session
        +     anyway (i.e. leaves x509_store_ctx->error != X509_V_OK
        +     but returns 1): When the session is reused, we have to set
        +     ssl->verify_result to the appropriate error code to avoid
        +     security holes.
        +     [Bodo Moeller, problem pointed out by Lutz Jaenicke]
        +
        +  *) Fix a bug in the new PKCS#7 code: it didn't consider the
        +     case in PKCS7_dataInit() where the signed PKCS7 structure
        +     didn't contain any existing data because it was being created.
        +     [Po-Cheng Chen <pocheng@nst.com.tw>, slightly modified by Steve Henson]
        +
        +  *) Add a salt to the key derivation routines in enc.c. This
        +     forms the first 8 bytes of the encrypted file. Also add a
        +     -S option to allow a salt to be input on the command line.
        +     [Steve Henson]
        +
        +  *) New function X509_cmp(). Oddly enough there wasn't a function
        +     to compare two certificates. We do this by working out the SHA1
        +     hash and comparing that. X509_cmp() will be needed by the trust
        +     code.
        +     [Steve Henson]
        +
        +  *) SSL_get1_session() is like SSL_get_session(), but increments
        +     the reference count in the SSL_SESSION returned.
        +     [Geoff Thorpe <geoff@eu.c2.net>]
        +
        +  *) Fix for 'req': it was adding a null to request attributes.
        +     Also change the X509_LOOKUP and X509_INFO code to handle
        +     certificate auxiliary information.
        +     [Steve Henson]
        +
        +  *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document
        +     the 'enc' command.
        +     [Steve Henson]
        +
        +  *) Add the possibility to add extra information to the memory leak
        +     detecting output, to form tracebacks, showing from where each
        +     allocation was originated: CRYPTO_push_info("constant string") adds
        +     the string plus current file name and line number to a per-thread
        +     stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info()
        +     is like calling CYRPTO_pop_info() until the stack is empty.
        +     Also updated memory leak detection code to be multi-thread-safe.
        +     [Richard Levitte]
        +
        +  *) Add options -text and -noout to pkcs7 utility and delete the
        +     encryption options which never did anything. Update docs.
        +     [Steve Henson]
        +
        +  *) Add options to some of the utilities to allow the pass phrase
        +     to be included on either the command line (not recommended on
        +     OSes like Unix) or read from the environment. Update the
        +     manpages and fix a few bugs.
        +     [Steve Henson]
        +
        +  *) Add a few manpages for some of the openssl commands.
        +     [Steve Henson]
        +
        +  *) Fix the -revoke option in ca. It was freeing up memory twice,
        +     leaking and not finding already revoked certificates.
        +     [Steve Henson]
        +
        +  *) Extensive changes to support certificate auxiliary information.
        +     This involves the use of X509_CERT_AUX structure and X509_AUX
        +     functions. An X509_AUX function such as PEM_read_X509_AUX()
        +     can still read in a certificate file in the usual way but it
        +     will also read in any additional "auxiliary information". By
        +     doing things this way a fair degree of compatibility can be
        +     retained: existing certificates can have this information added
        +     using the new 'x509' options. 
        +
        +     Current auxiliary information includes an "alias" and some trust
        +     settings. The trust settings will ultimately be used in enhanced
        +     certificate chain verification routines: currently a certificate
        +     can only be trusted if it is self signed and then it is trusted
        +     for all purposes.
        +     [Steve Henson]
        +
        +  *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD).
        +     The problem was that one of the replacement routines had not been working
        +     since SSLeay releases.  For now the offending routine has been replaced
        +     with non-optimised assembler.  Even so, this now gives around 95%
        +     performance improvement for 1024 bit RSA signs.
        +     [Mark Cox]
        +
        +  *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2 
        +     handling. Most clients have the effective key size in bits equal to
        +     the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key.
        +     A few however don't do this and instead use the size of the decrypted key
        +     to determine the RC2 key length and the AlgorithmIdentifier to determine
        +     the effective key length. In this case the effective key length can still
        +     be 40 bits but the key length can be 168 bits for example. This is fixed
        +     by manually forcing an RC2 key into the EVP_PKEY structure because the
        +     EVP code can't currently handle unusual RC2 key sizes: it always assumes
        +     the key length and effective key length are equal.
        +     [Steve Henson]
        +
        +  *) Add a bunch of functions that should simplify the creation of 
        +     X509_NAME structures. Now you should be able to do:
        +     X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0);
        +     and have it automatically work out the correct field type and fill in
        +     the structures. The more adventurous can try:
        +     X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0);
        +     and it will (hopefully) work out the correct multibyte encoding.
        +     [Steve Henson]
        +
        +  *) Change the 'req' utility to use the new field handling and multibyte
        +     copy routines. Before the DN field creation was handled in an ad hoc
        +     way in req, ca, and x509 which was rather broken and didn't support
        +     BMPStrings or UTF8Strings. Since some software doesn't implement
        +     BMPStrings or UTF8Strings yet, they can be enabled using the config file
        +     using the dirstring_type option. See the new comment in the default
        +     openssl.cnf for more info.
        +     [Steve Henson]
        +
        +  *) Make crypto/rand/md_rand.c more robust:
        +     - Assure unique random numbers after fork().
        +     - Make sure that concurrent threads access the global counter and
        +       md serializably so that we never lose entropy in them
        +       or use exactly the same state in multiple threads.
        +       Access to the large state is not always serializable because
        +       the additional locking could be a performance killer, and
        +       md should be large enough anyway.
        +     [Bodo Moeller]
        +
        +  *) New file apps/app_rand.c with commonly needed functionality
        +     for handling the random seed file.
        +
        +     Use the random seed file in some applications that previously did not:
        +          ca,
        +          dsaparam -genkey (which also ignored its '-rand' option), 
        +          s_client,
        +          s_server,
        +          x509 (when signing).
        +     Except on systems with /dev/urandom, it is crucial to have a random
        +     seed file at least for key creation, DSA signing, and for DH exchanges;
        +     for RSA signatures we could do without one.
        +
        +     gendh and gendsa (unlike genrsa) used to read only the first byte
        +     of each file listed in the '-rand' option.  The function as previously
        +     found in genrsa is now in app_rand.c and is used by all programs
        +     that support '-rand'.
        +     [Bodo Moeller]
        +
        +  *) In RAND_write_file, use mode 0600 for creating files;
        +     don't just chmod when it may be too late.
        +     [Bodo Moeller]
        +
        +  *) Report an error from X509_STORE_load_locations
        +     when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed.
        +     [Bill Perry]
        +
        +  *) New function ASN1_mbstring_copy() this copies a string in either
        +     ASCII, Unicode, Universal (4 bytes per character) or UTF8 format
        +     into an ASN1_STRING type. A mask of permissible types is passed
        +     and it chooses the "minimal" type to use or an error if not type
        +     is suitable.
        +     [Steve Henson]
        +
        +  *) Add function equivalents to the various macros in asn1.h. The old
        +     macros are retained with an M_ prefix. Code inside the library can
        +     use the M_ macros. External code (including the openssl utility)
        +     should *NOT* in order to be "shared library friendly".
        +     [Steve Henson]
        +
        +  *) Add various functions that can check a certificate's extensions
        +     to see if it usable for various purposes such as SSL client,
        +     server or S/MIME and CAs of these types. This is currently 
        +     VERY EXPERIMENTAL but will ultimately be used for certificate chain
        +     verification. Also added a -purpose flag to x509 utility to
        +     print out all the purposes.
        +     [Steve Henson]
        +
        +  *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated
        +     functions.
        +     [Steve Henson]
        +
        +  *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search
        +     for, obtain and decode and extension and obtain its critical flag.
        +     This allows all the necessary extension code to be handled in a
        +     single function call.
        +     [Steve Henson]
        +
        +  *) RC4 tune-up featuring 30-40% performance improvement on most RISC
        +     platforms. See crypto/rc4/rc4_enc.c for further details.
        +     [Andy Polyakov]
        +
        +  *) New -noout option to asn1parse. This causes no output to be produced
        +     its main use is when combined with -strparse and -out to extract data
        +     from a file (which may not be in ASN.1 format).
        +     [Steve Henson]
        +
        +  *) Fix for pkcs12 program. It was hashing an invalid certificate pointer
        +     when producing the local key id.
        +     [Richard Levitte <levitte@stacken.kth.se>]
        +
        +  *) New option -dhparam in s_server. This allows a DH parameter file to be
        +     stated explicitly. If it is not stated then it tries the first server
        +     certificate file. The previous behaviour hard coded the filename
        +     "server.pem".
        +     [Steve Henson]
        +
        +  *) Add -pubin and -pubout options to the rsa and dsa commands. These allow
        +     a public key to be input or output. For example:
        +     openssl rsa -in key.pem -pubout -out pubkey.pem
        +     Also added necessary DSA public key functions to handle this.
        +     [Steve Henson]
        +
        +  *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained
        +     in the message. This was handled by allowing
        +     X509_find_by_issuer_and_serial() to tolerate a NULL passed to it.
        +     [Steve Henson, reported by Sampo Kellomaki <sampo@mail.neuronio.pt>]
        +
        +  *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null
        +     to the end of the strings whereas this didn't. This would cause problems
        +     if strings read with d2i_ASN1_bytes() were later modified.
        +     [Steve Henson, reported by Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) Fix for base64 decode bug. When a base64 bio reads only one line of
        +     data and it contains EOF it will end up returning an error. This is
        +     caused by input 46 bytes long. The cause is due to the way base64
        +     BIOs find the start of base64 encoded data. They do this by trying a
        +     trial decode on each line until they find one that works. When they
        +     do a flag is set and it starts again knowing it can pass all the
        +     data directly through the decoder. Unfortunately it doesn't reset
        +     the context it uses. This means that if EOF is reached an attempt
        +     is made to pass two EOFs through the context and this causes the
        +     resulting error. This can also cause other problems as well. As is
        +     usual with these problems it takes *ages* to find and the fix is
        +     trivial: move one line.
        +     [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ]
        +
        +  *) Ugly workaround to get s_client and s_server working under Windows. The
        +     old code wouldn't work because it needed to select() on sockets and the
        +     tty (for keypresses and to see if data could be written). Win32 only
        +     supports select() on sockets so we select() with a 1s timeout on the
        +     sockets and then see if any characters are waiting to be read, if none
        +     are present then we retry, we also assume we can always write data to
        +     the tty. This isn't nice because the code then blocks until we've
        +     received a complete line of data and it is effectively polling the
        +     keyboard at 1s intervals: however it's quite a bit better than not
        +     working at all :-) A dedicated Windows application might handle this
        +     with an event loop for example.
        +     [Steve Henson]
        +
        +  *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign
        +     and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions
        +     will be called when RSA_sign() and RSA_verify() are used. This is useful
        +     if rsa_pub_dec() and rsa_priv_enc() equivalents are not available.
        +     For this to work properly RSA_public_decrypt() and RSA_private_encrypt()
        +     should *not* be used: RSA_sign() and RSA_verify() must be used instead.
        +     This necessitated the support of an extra signature type NID_md5_sha1
        +     for SSL signatures and modifications to the SSL library to use it instead
        +     of calling RSA_public_decrypt() and RSA_private_encrypt().
        +     [Steve Henson]
        +
        +  *) Add new -verify -CAfile and -CApath options to the crl program, these
        +     will lookup a CRL issuers certificate and verify the signature in a
        +     similar way to the verify program. Tidy up the crl program so it
        +     no longer accesses structures directly. Make the ASN1 CRL parsing a bit
        +     less strict. It will now permit CRL extensions even if it is not
        +     a V2 CRL: this will allow it to tolerate some broken CRLs.
        +     [Steve Henson]
        +
        +  *) Initialize all non-automatic variables each time one of the openssl
        +     sub-programs is started (this is necessary as they may be started
        +     multiple times from the "OpenSSL>" prompt).
        +     [Lennart Bang, Bodo Moeller]
        +
        +  *) Preliminary compilation option RSA_NULL which disables RSA crypto without
        +     removing all other RSA functionality (this is what NO_RSA does). This
        +     is so (for example) those in the US can disable those operations covered
        +     by the RSA patent while allowing storage and parsing of RSA keys and RSA
        +     key generation.
        +     [Steve Henson]
        +
        +  *) Non-copying interface to BIO pairs.
        +     (still largely untested)
        +     [Bodo Moeller]
        +
        +  *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive
        +     ASCII string. This was handled independently in various places before.
        +     [Steve Henson]
        +
        +  *) New functions UTF8_getc() and UTF8_putc() that parse and generate
        +     UTF8 strings a character at a time.
        +     [Steve Henson]
        +
        +  *) Use client_version from client hello to select the protocol
        +     (s23_srvr.c) and for RSA client key exchange verification
        +     (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications.
        +     [Bodo Moeller]
        +
        +  *) Add various utility functions to handle SPKACs, these were previously
        +     handled by poking round in the structure internals. Added new function
        +     NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to
        +     print, verify and generate SPKACs. Based on an original idea from
        +     Massimiliano Pala <madwolf@comune.modena.it> but extensively modified.
        +     [Steve Henson]
        +
        +  *) RIPEMD160 is operational on all platforms and is back in 'make test'.
        +     [Andy Polyakov]
        +
        +  *) Allow the config file extension section to be overwritten on the
        +     command line. Based on an original idea from Massimiliano Pala
        +     <madwolf@comune.modena.it>. The new option is called -extensions
        +     and can be applied to ca, req and x509. Also -reqexts to override
        +     the request extensions in req and -crlexts to override the crl extensions
        +     in ca.
        +     [Steve Henson]
        +
        +  *) Add new feature to the SPKAC handling in ca.  Now you can include
        +     the same field multiple times by preceding it by "XXXX." for example:
        +     1.OU="Unit name 1"
        +     2.OU="Unit name 2"
        +     this is the same syntax as used in the req config file.
        +     [Steve Henson]
        +
        +  *) Allow certificate extensions to be added to certificate requests. These
        +     are specified in a 'req_extensions' option of the req section of the
        +     config file. They can be printed out with the -text option to req but
        +     are otherwise ignored at present.
        +     [Steve Henson]
        +
        +  *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first
        +     data read consists of only the final block it would not decrypted because
        +     EVP_CipherUpdate() would correctly report zero bytes had been decrypted.
        +     A misplaced 'break' also meant the decrypted final block might not be
        +     copied until the next read.
        +     [Steve Henson]
        +
        +  *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added
        +     a few extra parameters to the DH structure: these will be useful if
        +     for example we want the value of 'q' or implement X9.42 DH.
        +     [Steve Henson]
        +
        +  *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and
        +     provides hooks that allow the default DSA functions or functions on a
        +     "per key" basis to be replaced. This allows hardware acceleration and
        +     hardware key storage to be handled without major modification to the
        +     library. Also added low level modexp hooks and CRYPTO_EX structure and 
        +     associated functions.
        +     [Steve Henson]
        +
        +  *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO
        +     as "read only": it can't be written to and the buffer it points to will
        +     not be freed. Reading from a read only BIO is much more efficient than
        +     a normal memory BIO. This was added because there are several times when
        +     an area of memory needs to be read from a BIO. The previous method was
        +     to create a memory BIO and write the data to it, this results in two
        +     copies of the data and an O(n^2) reading algorithm. There is a new
        +     function BIO_new_mem_buf() which creates a read only memory BIO from
        +     an area of memory. Also modified the PKCS#7 routines to use read only
        +     memory BIOs.
        +     [Steve Henson]
        +
        +  *) Bugfix: ssl23_get_client_hello did not work properly when called in
        +     state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of
        +     a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read,
        +     but a retry condition occured while trying to read the rest.
        +     [Bodo Moeller]
        +
        +  *) The PKCS7_ENC_CONTENT_new() function was setting the content type as
        +     NID_pkcs7_encrypted by default: this was wrong since this should almost
        +     always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle
        +     the encrypted data type: this is a more sensible place to put it and it
        +     allows the PKCS#12 code to be tidied up that duplicated this
        +     functionality.
        +     [Steve Henson]
        +
        +  *) Changed obj_dat.pl script so it takes its input and output files on
        +     the command line. This should avoid shell escape redirection problems
        +     under Win32.
        +     [Steve Henson]
        +
        +  *) Initial support for certificate extension requests, these are included
        +     in things like Xenroll certificate requests. Included functions to allow
        +     extensions to be obtained and added.
        +     [Steve Henson]
        +
        +  *) -crlf option to s_client and s_server for sending newlines as
        +     CRLF (as required by many protocols).
        +     [Bodo Moeller]
        +
        + Changes between 0.9.3a and 0.9.4  [09 Aug 1999]
        +  
        +  *) Install libRSAglue.a when OpenSSL is built with RSAref.
        +     [Ralf S. Engelschall]
        +
        +  *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency.
        +     [Andrija Antonijevic <TheAntony2@bigfoot.com>]
        +
        +  *) Fix -startdate and -enddate (which was missing) arguments to 'ca'
        +     program.
        +     [Steve Henson]
        +
        +  *) New function DSA_dup_DH, which duplicates DSA parameters/keys as
        +     DH parameters/keys (q is lost during that conversion, but the resulting
        +     DH parameters contain its length).
        +
        +     For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is
        +     much faster than DH_generate_parameters (which creates parameters
        +     where p = 2*q + 1), and also the smaller q makes DH computations
        +     much more efficient (160-bit exponentiation instead of 1024-bit
        +     exponentiation); so this provides a convenient way to support DHE
        +     ciphersuites in SSL/TLS servers (see ssl/ssltest.c).  It is of
        +     utter importance to use
        +         SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
        +     or
        +         SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
        +     when such DH parameters are used, because otherwise small subgroup
        +     attacks may become possible!
        +     [Bodo Moeller]
        +
        +  *) Avoid memory leak in i2d_DHparams.
        +     [Bodo Moeller]
        +
        +  *) Allow the -k option to be used more than once in the enc program:
        +     this allows the same encrypted message to be read by multiple recipients.
        +     [Steve Henson]
        +
        +  *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts
        +     an ASN1_OBJECT to a text string. If the "no_name" parameter is set then
        +     it will always use the numerical form of the OID, even if it has a short
        +     or long name.
        +     [Steve Henson]
        +
        +  *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp
        +     method only got called if p,q,dmp1,dmq1,iqmp components were present,
        +     otherwise bn_mod_exp was called. In the case of hardware keys for example
        +     no private key components need be present and it might store extra data
        +     in the RSA structure, which cannot be accessed from bn_mod_exp.
        +     By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for
        +     private key operations.
        +     [Steve Henson]
        +
        +  *) Added support for SPARC Linux.
        +     [Andy Polyakov]
        +
        +  *) pem_password_cb function type incompatibly changed from
        +          typedef int pem_password_cb(char *buf, int size, int rwflag);
        +     to
        +          ....(char *buf, int size, int rwflag, void *userdata);
        +     so that applications can pass data to their callbacks:
        +     The PEM[_ASN1]_{read,write}... functions and macros now take an
        +     additional void * argument, which is just handed through whenever
        +     the password callback is called.
        +     [Damien Miller <dmiller@ilogic.com.au>; tiny changes by Bodo Moeller]
        +
        +     New function SSL_CTX_set_default_passwd_cb_userdata.
        +
        +     Compatibility note: As many C implementations push function arguments
        +     onto the stack in reverse order, the new library version is likely to
        +     interoperate with programs that have been compiled with the old
        +     pem_password_cb definition (PEM_whatever takes some data that
        +     happens to be on the stack as its last argument, and the callback
        +     just ignores this garbage); but there is no guarantee whatsoever that
        +     this will work.
        +
        +  *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=...
        +     (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused
        +     problems not only on Windows, but also on some Unix platforms.
        +     To avoid problematic command lines, these definitions are now in an
        +     auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl
        +     for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds).
        +     [Bodo Moeller]
        +
        +  *) MIPS III/IV assembler module is reimplemented.
        +     [Andy Polyakov]
        +
        +  *) More DES library cleanups: remove references to srand/rand and
        +     delete an unused file.
        +     [Ulf Möller]
        +
        +  *) Add support for the the free Netwide assembler (NASM) under Win32,
        +     since not many people have MASM (ml) and it can be hard to obtain.
        +     This is currently experimental but it seems to work OK and pass all
        +     the tests. Check out INSTALL.W32 for info.
        +     [Steve Henson]
        +
        +  *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections
        +     without temporary keys kept an extra copy of the server key,
        +     and connections with temporary keys did not free everything in case
        +     of an error.
        +     [Bodo Moeller]
        +
        +  *) New function RSA_check_key and new openssl rsa option -check
        +     for verifying the consistency of RSA keys.
        +     [Ulf Moeller, Bodo Moeller]
        +
        +  *) Various changes to make Win32 compile work: 
        +     1. Casts to avoid "loss of data" warnings in p5_crpt2.c
        +     2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned
        +        comparison" warnings.
        +     3. Add sk_<TYPE>_sort to DEF file generator and do make update.
        +     [Steve Henson]
        +
        +  *) Add a debugging option to PKCS#5 v2 key generation function: when
        +     you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and
        +     derived keys are printed to stderr.
        +     [Steve Henson]
        +
        +  *) Copy the flags in ASN1_STRING_dup().
        +     [Roman E. Pavlov <pre@mo.msk.ru>]
        +
        +  *) The x509 application mishandled signing requests containing DSA
        +     keys when the signing key was also DSA and the parameters didn't match.
        +
        +     It was supposed to omit the parameters when they matched the signing key:
        +     the verifying software was then supposed to automatically use the CA's
        +     parameters if they were absent from the end user certificate.
        +
        +     Omitting parameters is no longer recommended. The test was also
        +     the wrong way round! This was probably due to unusual behaviour in
        +     EVP_cmp_parameters() which returns 1 if the parameters match. 
        +     This meant that parameters were omitted when they *didn't* match and
        +     the certificate was useless. Certificates signed with 'ca' didn't have
        +     this bug.
        +     [Steve Henson, reported by Doug Erickson <Doug.Erickson@Part.NET>]
        +
        +  *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems.
        +     The interface is as follows:
        +     Applications can use
        +         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(),
        +         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop();
        +     "off" is now the default.
        +     The library internally uses
        +         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(),
        +         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on()
        +     to disable memory-checking temporarily.
        +
        +     Some inconsistent states that previously were possible (and were
        +     even the default) are now avoided.
        +
        +     -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time
        +     with each memory chunk allocated; this is occasionally more helpful
        +     than just having a counter.
        +
        +     -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID.
        +
        +     -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future
        +     extensions.
        +     [Bodo Moeller]
        +
        +  *) Introduce "mode" for SSL structures (with defaults in SSL_CTX),
        +     which largely parallels "options", but is for changing API behaviour,
        +     whereas "options" are about protocol behaviour.
        +     Initial "mode" flags are:
        +
        +     SSL_MODE_ENABLE_PARTIAL_WRITE   Allow SSL_write to report success when
        +                                     a single record has been written.
        +     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER  Don't insist that SSL_write
        +                                     retries use the same buffer location.
        +                                     (But all of the contents must be
        +                                     copied!)
        +     [Bodo Moeller]
        +
        +  *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options
        +     worked.
        +
        +  *) Fix problems with no-hmac etc.
        +     [Ulf Möller, pointed out by Brian Wellington <bwelling@tislabs.com>]
        +
        +  *) New functions RSA_get_default_method(), RSA_set_method() and
        +     RSA_get_method(). These allows replacement of RSA_METHODs without having
        +     to mess around with the internals of an RSA structure.
        +     [Steve Henson]
        +
        +  *) Fix memory leaks in DSA_do_sign and DSA_is_prime.
        +     Also really enable memory leak checks in openssl.c and in some
        +     test programs.
        +     [Chad C. Mulligan, Bodo Moeller]
        +
        +  *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess
        +     up the length of negative integers. This has now been simplified to just
        +     store the length when it is first determined and use it later, rather
        +     than trying to keep track of where data is copied and updating it to
        +     point to the end.
        +     [Steve Henson, reported by Brien Wheeler
        +      <bwheeler@authentica-security.com>]
        +
        +  *) Add a new function PKCS7_signatureVerify. This allows the verification
        +     of a PKCS#7 signature but with the signing certificate passed to the
        +     function itself. This contrasts with PKCS7_dataVerify which assumes the
        +     certificate is present in the PKCS#7 structure. This isn't always the
        +     case: certificates can be omitted from a PKCS#7 structure and be
        +     distributed by "out of band" means (such as a certificate database).
        +     [Steve Henson]
        +
        +  *) Complete the PEM_* macros with DECLARE_PEM versions to replace the
        +     function prototypes in pem.h, also change util/mkdef.pl to add the
        +     necessary function names. 
        +     [Steve Henson]
        +
        +  *) mk1mf.pl (used by Windows builds) did not properly read the
        +     options set by Configure in the top level Makefile, and Configure
        +     was not even able to write more than one option correctly.
        +     Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended.
        +     [Bodo Moeller]
        +
        +  *) New functions CONF_load_bio() and CONF_load_fp() to allow a config
        +     file to be loaded from a BIO or FILE pointer. The BIO version will
        +     for example allow memory BIOs to contain config info.
        +     [Steve Henson]
        +
        +  *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS.
        +     Whoever hopes to achieve shared-library compatibility across versions
        +     must use this, not the compile-time macro.
        +     (Exercise 0.9.4: Which is the minimum library version required by
        +     such programs?)
        +     Note: All this applies only to multi-threaded programs, others don't
        +     need locks.
        +     [Bodo Moeller]
        +
        +  *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests
        +     through a BIO pair triggered the default case, i.e.
        +     SSLerr(...,SSL_R_UNKNOWN_STATE).
        +     [Bodo Moeller]
        +
        +  *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications
        +     can use the SSL library even if none of the specific BIOs is
        +     appropriate.
        +     [Bodo Moeller]
        +
        +  *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value
        +     for the encoded length.
        +     [Jeon KyoungHo <khjeon@sds.samsung.co.kr>]
        +
        +  *) Add initial documentation of the X509V3 functions.
        +     [Steve Henson]
        +
        +  *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and 
        +     PEM_write_bio_PKCS8PrivateKey() that are equivalent to
        +     PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more
        +     secure PKCS#8 private key format with a high iteration count.
        +     [Steve Henson]
        +
        +  *) Fix determination of Perl interpreter: A perl or perl5
        +     _directory_ in $PATH was also accepted as the interpreter.
        +     [Ralf S. Engelschall]
        +
        +  *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking
        +     wrong with it but it was very old and did things like calling
        +     PEM_ASN1_read() directly and used MD5 for the hash not to mention some
        +     unusual formatting.
        +     [Steve Henson]
        +
        +  *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed
        +     to use the new extension code.
        +     [Steve Henson]
        +
        +  *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c
        +     with macros. This should make it easier to change their form, add extra
        +     arguments etc. Fix a few PEM prototypes which didn't have cipher as a
        +     constant.
        +     [Steve Henson]
        +
        +  *) Add to configuration table a new entry that can specify an alternative
        +     name for unistd.h (for pre-POSIX systems); we need this for NeXTstep,
        +     according to Mark Crispin <MRC@Panda.COM>.
        +     [Bodo Moeller]
        +
        +#if 0
        +  *) DES CBC did not update the IV. Weird.
        +     [Ben Laurie]
        +#else
        +     des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does.
        +     Changing the behaviour of the former might break existing programs --
        +     where IV updating is needed, des_ncbc_encrypt can be used.
        +#endif
        +
        +  *) When bntest is run from "make test" it drives bc to check its
        +     calculations, as well as internally checking them. If an internal check
        +     fails, it needs to cause bc to give a non-zero result or make test carries
        +     on without noticing the failure. Fixed.
        +     [Ben Laurie]
        +
        +  *) DES library cleanups.
        +     [Ulf Möller]
        +
        +  *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be
        +     used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit
        +     ciphers. NOTE: although the key derivation function has been verified
        +     against some published test vectors it has not been extensively tested
        +     yet. Added a -v2 "cipher" option to pkcs8 application to allow the use
        +     of v2.0.
        +     [Steve Henson]
        +
        +  *) Instead of "mkdir -p", which is not fully portable, use new
        +     Perl script "util/mkdir-p.pl".
        +     [Bodo Moeller]
        +
        +  *) Rewrite the way password based encryption (PBE) is handled. It used to
        +     assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter
        +     structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms
        +     but doesn't apply to PKCS#5 v2.0 where it can be something else. Now
        +     the 'parameter' field of the AlgorithmIdentifier is passed to the
        +     underlying key generation function so it must do its own ASN1 parsing.
        +     This has also changed the EVP_PBE_CipherInit() function which now has a
        +     'parameter' argument instead of literal salt and iteration count values
        +     and the function EVP_PBE_ALGOR_CipherInit() has been deleted.
        +     [Steve Henson]
        +
        +  *) Support for PKCS#5 v1.5 compatible password based encryption algorithms
        +     and PKCS#8 functionality. New 'pkcs8' application linked to openssl.
        +     Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE
        +     KEY" because this clashed with PKCS#8 unencrypted string. Since this
        +     value was just used as a "magic string" and not used directly its
        +     value doesn't matter.
        +     [Steve Henson]
        +
        +  *) Introduce some semblance of const correctness to BN. Shame C doesn't
        +     support mutable.
        +     [Ben Laurie]
        +
        +  *) "linux-sparc64" configuration (ultrapenguin).
        +     [Ray Miller <ray.miller@oucs.ox.ac.uk>]
        +     "linux-sparc" configuration.
        +     [Christian Forster <fo@hawo.stw.uni-erlangen.de>]
        +
        +  *) config now generates no-xxx options for missing ciphers.
        +     [Ulf Möller]
        +
        +  *) Support the EBCDIC character set (work in progress).
        +     File ebcdic.c not yet included because it has a different license.
        +     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
        +
        +  *) Support BS2000/OSD-POSIX.
        +     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
        +
        +  *) Make callbacks for key generation use void * instead of char *.
        +     [Ben Laurie]
        +
        +  *) Make S/MIME samples compile (not yet tested).
        +     [Ben Laurie]
        +
        +  *) Additional typesafe stacks.
        +     [Ben Laurie]
        +
        +  *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x).
        +     [Bodo Moeller]
        +
        +
        + Changes between 0.9.3 and 0.9.3a  [29 May 1999]
        +
        +  *) New configuration variant "sco5-gcc".
        +
        +  *) Updated some demos.
        +     [Sean O Riordain, Wade Scholine]
        +
        +  *) Add missing BIO_free at exit of pkcs12 application.
        +     [Wu Zhigang]
        +
        +  *) Fix memory leak in conf.c.
        +     [Steve Henson]
        +
        +  *) Updates for Win32 to assembler version of MD5.
        +     [Steve Henson]
        +
        +  *) Set #! path to perl in apps/der_chop to where we found it
        +     instead of using a fixed path.
        +     [Bodo Moeller]
        +
        +  *) SHA library changes for irix64-mips4-cc.
        +     [Andy Polyakov]
        +
        +  *) Improvements for VMS support.
        +     [Richard Levitte]
        +
        +
        + Changes between 0.9.2b and 0.9.3  [24 May 1999]
        +
        +  *) Bignum library bug fix. IRIX 6 passes "make test" now!
        +     This also avoids the problems with SC4.2 and unpatched SC5.  
        +     [Andy Polyakov <appro@fy.chalmers.se>]
        +
        +  *) New functions sk_num, sk_value and sk_set to replace the previous macros.
        +     These are required because of the typesafe stack would otherwise break 
        +     existing code. If old code used a structure member which used to be STACK
        +     and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with
        +     sk_num or sk_value it would produce an error because the num, data members
        +     are not present in STACK_OF. Now it just produces a warning. sk_set
        +     replaces the old method of assigning a value to sk_value
        +     (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code
        +     that does this will no longer work (and should use sk_set instead) but
        +     this could be regarded as a "questionable" behaviour anyway.
        +     [Steve Henson]
        +
        +  *) Fix most of the other PKCS#7 bugs. The "experimental" code can now
        +     correctly handle encrypted S/MIME data.
        +     [Steve Henson]
        +
        +  *) Change type of various DES function arguments from des_cblock
        +     (which means, in function argument declarations, pointer to char)
        +     to des_cblock * (meaning pointer to array with 8 char elements),
        +     which allows the compiler to do more typechecking; it was like
        +     that back in SSLeay, but with lots of ugly casts.
        +
        +     Introduce new type const_des_cblock.
        +     [Bodo Moeller]
        +
        +  *) Reorganise the PKCS#7 library and get rid of some of the more obvious
        +     problems: find RecipientInfo structure that matches recipient certificate
        +     and initialise the ASN1 structures properly based on passed cipher.
        +     [Steve Henson]
        +
        +  *) Belatedly make the BN tests actually check the results.
        +     [Ben Laurie]
        +
        +  *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion
        +     to and from BNs: it was completely broken. New compilation option
        +     NEG_PUBKEY_BUG to allow for some broken certificates that encode public
        +     key elements as negative integers.
        +     [Steve Henson]
        +
        +  *) Reorganize and speed up MD5.
        +     [Andy Polyakov <appro@fy.chalmers.se>]
        +
        +  *) VMS support.
        +     [Richard Levitte <richard@levitte.org>]
        +
        +  *) New option -out to asn1parse to allow the parsed structure to be
        +     output to a file. This is most useful when combined with the -strparse
        +     option to examine the output of things like OCTET STRINGS.
        +     [Steve Henson]
        +
        +  *) Make SSL library a little more fool-proof by not requiring any longer
        +     that SSL_set_{accept,connect}_state be called before
        +     SSL_{accept,connect} may be used (SSL_set_..._state is omitted
        +     in many applications because usually everything *appeared* to work as
        +     intended anyway -- now it really works as intended).
        +     [Bodo Moeller]
        +
        +  *) Move openssl.cnf out of lib/.
        +     [Ulf Möller]
        +
        +  *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall
        +     -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes
        +     -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+ 
        +     [Ralf S. Engelschall]
        +
        +  *) Various fixes to the EVP and PKCS#7 code. It may now be able to
        +     handle PKCS#7 enveloped data properly.
        +     [Sebastian Akerman <sak@parallelconsulting.com>, modified by Steve]
        +
        +  *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
        +     copying pointers.  The cert_st handling is changed by this in
        +     various ways (and thus what used to be known as ctx->default_cert
        +     is now called ctx->cert, since we don't resort to s->ctx->[default_]cert
        +     any longer when s->cert does not give us what we need).
        +     ssl_cert_instantiate becomes obsolete by this change.
        +     As soon as we've got the new code right (possibly it already is?),
        +     we have solved a couple of bugs of the earlier code where s->cert
        +     was used as if it could not have been shared with other SSL structures.
        +
        +     Note that using the SSL API in certain dirty ways now will result
        +     in different behaviour than observed with earlier library versions:
        +     Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
        +     does not influence s as it used to.
        +     
        +     In order to clean up things more thoroughly, inside SSL_SESSION
        +     we don't use CERT any longer, but a new structure SESS_CERT
        +     that holds per-session data (if available); currently, this is
        +     the peer's certificate chain and, for clients, the server's certificate
        +     and temporary key.  CERT holds only those values that can have
        +     meaningful defaults in an SSL_CTX.
        +     [Bodo Moeller]
        +
        +  *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
        +     from the internal representation. Various PKCS#7 fixes: remove some
        +     evil casts and set the enc_dig_alg field properly based on the signing
        +     key type.
        +     [Steve Henson]
        +
        +  *) Allow PKCS#12 password to be set from the command line or the
        +     environment. Let 'ca' get its config file name from the environment
        +     variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req'
        +     and 'x509').
        +     [Steve Henson]
        +
        +  *) Allow certificate policies extension to use an IA5STRING for the
        +     organization field. This is contrary to the PKIX definition but
        +     VeriSign uses it and IE5 only recognises this form. Document 'x509'
        +     extension option.
        +     [Steve Henson]
        +
        +  *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic,
        +     without disallowing inline assembler and the like for non-pedantic builds.
        +     [Ben Laurie]
        +
        +  *) Support Borland C++ builder.
        +     [Janez Jere <jj@void.si>, modified by Ulf Möller]
        +
        +  *) Support Mingw32.
        +     [Ulf Möller]
        +
        +  *) SHA-1 cleanups and performance enhancements.
        +     [Andy Polyakov <appro@fy.chalmers.se>]
        +
        +  *) Sparc v8plus assembler for the bignum library.
        +     [Andy Polyakov <appro@fy.chalmers.se>]
        +
        +  *) Accept any -xxx and +xxx compiler options in Configure.
        +     [Ulf Möller]
        +
        +  *) Update HPUX configuration.
        +     [Anonymous]
        +  
        +  *) Add missing sk_<type>_unshift() function to safestack.h
        +     [Ralf S. Engelschall]
        +
        +  *) New function SSL_CTX_use_certificate_chain_file that sets the
        +     "extra_cert"s in addition to the certificate.  (This makes sense
        +     only for "PEM" format files, as chains as a whole are not
        +     DER-encoded.)
        +     [Bodo Moeller]
        +
        +  *) Support verify_depth from the SSL API.
        +     x509_vfy.c had what can be considered an off-by-one-error:
        +     Its depth (which was not part of the external interface)
        +     was actually counting the number of certificates in a chain;
        +     now it really counts the depth.
        +     [Bodo Moeller]
        +
        +  *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used
        +     instead of X509err, which often resulted in confusing error
        +     messages since the error codes are not globally unique
        +     (e.g. an alleged error in ssl3_accept when a certificate
        +     didn't match the private key).
        +
        +  *) New function SSL_CTX_set_session_id_context that allows to set a default
        +     value (so that you don't need SSL_set_session_id_context for each
        +     connection using the SSL_CTX).
        +     [Bodo Moeller]
        +
        +  *) OAEP decoding bug fix.
        +     [Ulf Möller]
        +
        +  *) Support INSTALL_PREFIX for package builders, as proposed by
        +     David Harris.
        +     [Bodo Moeller]
        +
        +  *) New Configure options "threads" and "no-threads".  For systems
        +     where the proper compiler options are known (currently Solaris
        +     and Linux), "threads" is the default.
        +     [Bodo Moeller]
        +
        +  *) New script util/mklink.pl as a faster substitute for util/mklink.sh.
        +     [Bodo Moeller]
        +
        +  *) Install various scripts to $(OPENSSLDIR)/misc, not to
        +     $(INSTALLTOP)/bin -- they shouldn't clutter directories
        +     such as /usr/local/bin.
        +     [Bodo Moeller]
        +
        +  *) "make linux-shared" to build shared libraries.
        +     [Niels Poppe <niels@netbox.org>]
        +
        +  *) New Configure option no-<cipher> (rsa, idea, rc5, ...).
        +     [Ulf Möller]
        +
        +  *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for
        +     extension adding in x509 utility.
        +     [Steve Henson]
        +
        +  *) Remove NOPROTO sections and error code comments.
        +     [Ulf Möller]
        +
        +  *) Partial rewrite of the DEF file generator to now parse the ANSI
        +     prototypes.
        +     [Steve Henson]
        +
        +  *) New Configure options --prefix=DIR and --openssldir=DIR.
        +     [Ulf Möller]
        +
        +  *) Complete rewrite of the error code script(s). It is all now handled
        +     by one script at the top level which handles error code gathering,
        +     header rewriting and C source file generation. It should be much better
        +     than the old method: it now uses a modified version of Ulf's parser to
        +     read the ANSI prototypes in all header files (thus the old K&R definitions
        +     aren't needed for error creation any more) and do a better job of
        +     translating function codes into names. The old 'ASN1 error code imbedded
        +     in a comment' is no longer necessary and it doesn't use .err files which
        +     have now been deleted. Also the error code call doesn't have to appear all
        +     on one line (which resulted in some large lines...).
        +     [Steve Henson]
        +
        +  *) Change #include filenames from <foo.h> to <openssl/foo.h>.
        +     [Bodo Moeller]
        +
        +  *) Change behaviour of ssl2_read when facing length-0 packets: Don't return
        +     0 (which usually indicates a closed connection), but continue reading.
        +     [Bodo Moeller]
        +
        +  *) Fix some race conditions.
        +     [Bodo Moeller]
        +
        +  *) Add support for CRL distribution points extension. Add Certificate
        +     Policies and CRL distribution points documentation.
        +     [Steve Henson]
        +
        +  *) Move the autogenerated header file parts to crypto/opensslconf.h.
        +     [Ulf Möller]
        +
        +  *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of
        +     8 of keying material. Merlin has also confirmed interop with this fix
        +     between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0.
        +     [Merlin Hughes <merlin@baltimore.ie>]
        +
        +  *) Fix lots of warnings.
        +     [Richard Levitte <levitte@stacken.kth.se>]
        + 
        +  *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if
        +     the directory spec didn't end with a LIST_SEPARATOR_CHAR.
        +     [Richard Levitte <levitte@stacken.kth.se>]
        + 
        +  *) Fix problems with sizeof(long) == 8.
        +     [Andy Polyakov <appro@fy.chalmers.se>]
        +
        +  *) Change functions to ANSI C.
        +     [Ulf Möller]
        +
        +  *) Fix typos in error codes.
        +     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>, Ulf Möller]
        +
        +  *) Remove defunct assembler files from Configure.
        +     [Ulf Möller]
        +
        +  *) SPARC v8 assembler BIGNUM implementation.
        +     [Andy Polyakov <appro@fy.chalmers.se>]
        +
        +  *) Support for Certificate Policies extension: both print and set.
        +     Various additions to support the r2i method this uses.
        +     [Steve Henson]
        +
        +  *) A lot of constification, and fix a bug in X509_NAME_oneline() that could
        +     return a const string when you are expecting an allocated buffer.
        +     [Ben Laurie]
        +
        +  *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE
        +     types DirectoryString and DisplayText.
        +     [Steve Henson]
        +
        +  *) Add code to allow r2i extensions to access the configuration database,
        +     add an LHASH database driver and add several ctx helper functions.
        +     [Steve Henson]
        +
        +  *) Fix an evil bug in bn_expand2() which caused various BN functions to
        +     fail when they extended the size of a BIGNUM.
        +     [Steve Henson]
        +
        +  *) Various utility functions to handle SXNet extension. Modify mkdef.pl to
        +     support typesafe stack.
        +     [Steve Henson]
        +
        +  *) Fix typo in SSL_[gs]et_options().
        +     [Nils Frostberg <nils@medcom.se>]
        +
        +  *) Delete various functions and files that belonged to the (now obsolete)
        +     old X509V3 handling code.
        +     [Steve Henson]
        +
        +  *) New Configure option "rsaref".
        +     [Ulf Möller]
        +
        +  *) Don't auto-generate pem.h.
        +     [Bodo Moeller]
        +
        +  *) Introduce type-safe ASN.1 SETs.
        +     [Ben Laurie]
        +
        +  *) Convert various additional casted stacks to type-safe STACK_OF() variants.
        +     [Ben Laurie, Ralf S. Engelschall, Steve Henson]
        +
        +  *) Introduce type-safe STACKs. This will almost certainly break lots of code
        +     that links with OpenSSL (well at least cause lots of warnings), but fear
        +     not: the conversion is trivial, and it eliminates loads of evil casts. A
        +     few STACKed things have been converted already. Feel free to convert more.
        +     In the fullness of time, I'll do away with the STACK type altogether.
        +     [Ben Laurie]
        +
        +  *) Add `openssl ca -revoke <certfile>' facility which revokes a certificate
        +     specified in <certfile> by updating the entry in the index.txt file.
        +     This way one no longer has to edit the index.txt file manually for
        +     revoking a certificate. The -revoke option does the gory details now.
        +     [Massimiliano Pala <madwolf@openca.org>, Ralf S. Engelschall]
        +
        +  *) Fix `openssl crl -noout -text' combination where `-noout' killed the
        +     `-text' option at all and this way the `-noout -text' combination was
        +     inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'.
        +     [Ralf S. Engelschall]
        +
        +  *) Make sure a corresponding plain text error message exists for the
        +     X509_V_ERR_CERT_REVOKED/23 error number which can occur when a
        +     verify callback function determined that a certificate was revoked.
        +     [Ralf S. Engelschall]
        +
        +  *) Bugfix: In test/testenc, don't test "openssl <cipher>" for
        +     ciphers that were excluded, e.g. by -DNO_IDEA.  Also, test
        +     all available cipers including rc5, which was forgotten until now.
        +     In order to let the testing shell script know which algorithms
        +     are available, a new (up to now undocumented) command
        +     "openssl list-cipher-commands" is used.
        +     [Bodo Moeller]
        +
        +  *) Bugfix: s_client occasionally would sleep in select() when
        +     it should have checked SSL_pending() first.
        +     [Bodo Moeller]
        +
        +  *) New functions DSA_do_sign and DSA_do_verify to provide access to
        +     the raw DSA values prior to ASN.1 encoding.
        +     [Ulf Möller]
        +
        +  *) Tweaks to Configure
        +     [Niels Poppe <niels@netbox.org>]
        +
        +  *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support,
        +     yet...
        +     [Steve Henson]
        +
        +  *) New variables $(RANLIB) and $(PERL) in the Makefiles.
        +     [Ulf Möller]
        +
        +  *) New config option to avoid instructions that are illegal on the 80386.
        +     The default code is faster, but requires at least a 486.
        +     [Ulf Möller]
        +  
        +  *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and
        +     SSL2_SERVER_VERSION (not used at all) macros, which are now the
        +     same as SSL2_VERSION anyway.
        +     [Bodo Moeller]
        +
        +  *) New "-showcerts" option for s_client.
        +     [Bodo Moeller]
        +
        +  *) Still more PKCS#12 integration. Add pkcs12 application to openssl
        +     application. Various cleanups and fixes.
        +     [Steve Henson]
        +
        +  *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and
        +     modify error routines to work internally. Add error codes and PBE init
        +     to library startup routines.
        +     [Steve Henson]
        +
        +  *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and
        +     packing functions to asn1 and evp. Changed function names and error
        +     codes along the way.
        +     [Steve Henson]
        +
        +  *) PKCS12 integration: and so it begins... First of several patches to
        +     slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12
        +     objects to objects.h
        +     [Steve Henson]
        +
        +  *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1
        +     and display support for Thawte strong extranet extension.
        +     [Steve Henson]
        +
        +  *) Add LinuxPPC support.
        +     [Jeff Dubrule <igor@pobox.org>]
        +
        +  *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to
        +     bn_div_words in alpha.s.
        +     [Hannes Reinecke <H.Reinecke@hw.ac.uk> and Ben Laurie]
        +
        +  *) Make sure the RSA OAEP test is skipped under -DRSAref because
        +     OAEP isn't supported when OpenSSL is built with RSAref.
        +     [Ulf Moeller <ulf@fitug.de>]
        +
        +  *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h 
        +     so they no longer are missing under -DNOPROTO. 
        +     [Soren S. Jorvang <soren@t.dk>]
        +
        +
        + Changes between 0.9.1c and 0.9.2b  [22 Mar 1999]
        +
        +  *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still
        +     doesn't work when the session is reused. Coming soon!
        +     [Ben Laurie]
        +
        +  *) Fix a security hole, that allows sessions to be reused in the wrong
        +     context thus bypassing client cert protection! All software that uses
        +     client certs and session caches in multiple contexts NEEDS PATCHING to
        +     allow session reuse! A fuller solution is in the works.
        +     [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)]
        +
        +  *) Some more source tree cleanups (removed obsolete files
        +     crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed
        +     permission on "config" script to be executable) and a fix for the INSTALL
        +     document.
        +     [Ulf Moeller <ulf@fitug.de>]
        +
        +  *) Remove some legacy and erroneous uses of malloc, free instead of
        +     Malloc, Free.
        +     [Lennart Bang <lob@netstream.se>, with minor changes by Steve]
        +
        +  *) Make rsa_oaep_test return non-zero on error.
        +     [Ulf Moeller <ulf@fitug.de>]
        +
        +  *) Add support for native Solaris shared libraries. Configure
        +     solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice
        +     if someone would make that last step automatic.
        +     [Matthias Loepfe <Matthias.Loepfe@AdNovum.CH>]
        +
        +  *) ctx_size was not built with the right compiler during "make links". Fixed.
        +     [Ben Laurie]
        +
        +  *) Change the meaning of 'ALL' in the cipher list. It now means "everything
        +     except NULL ciphers". This means the default cipher list will no longer
        +     enable NULL ciphers. They need to be specifically enabled e.g. with
        +     the string "DEFAULT:eNULL".
        +     [Steve Henson]
        +
        +  *) Fix to RSA private encryption routines: if p < q then it would
        +     occasionally produce an invalid result. This will only happen with
        +     externally generated keys because OpenSSL (and SSLeay) ensure p > q.
        +     [Steve Henson]
        +
        +  *) Be less restrictive and allow also `perl util/perlpath.pl
        +     /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin',
        +     because this way one can also use an interpreter named `perl5' (which is
        +     usually the name of Perl 5.xxx on platforms where an Perl 4.x is still
        +     installed as `perl').
        +     [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
        +
        +  *) Let util/clean-depend.pl work also with older Perl 5.00x versions.
        +     [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
        +
        +  *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add
        +     advapi32.lib to Win32 build and change the pem test comparision
        +     to fc.exe (thanks to Ulrich Kroener <kroneru@yahoo.com> for the
        +     suggestion). Fix misplaced ASNI prototypes and declarations in evp.h
        +     and crypto/des/ede_cbcm_enc.c.
        +     [Steve Henson]
        +
        +  *) DES quad checksum was broken on big-endian architectures. Fixed.
        +     [Ben Laurie]
        +
        +  *) Comment out two functions in bio.h that aren't implemented. Fix up the
        +     Win32 test batch file so it (might) work again. The Win32 test batch file
        +     is horrible: I feel ill....
        +     [Steve Henson]
        +
        +  *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected
        +     in e_os.h. Audit of header files to check ANSI and non ANSI
        +     sections: 10 functions were absent from non ANSI section and not exported
        +     from Windows DLLs. Fixed up libeay.num for new functions.
        +     [Steve Henson]
        +
        +  *) Make `openssl version' output lines consistent.
        +     [Ralf S. Engelschall]
        +
        +  *) Fix Win32 symbol export lists for BIO functions: Added
        +     BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data
        +     to ms/libeay{16,32}.def.
        +     [Ralf S. Engelschall]
        +
        +  *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled
        +     fine under Unix and passes some trivial tests I've now added. But the
        +     whole stuff is horribly incomplete, so a README.1ST with a disclaimer was
        +     added to make sure no one expects that this stuff really works in the
        +     OpenSSL 0.9.2 release.  Additionally I've started to clean the XS sources
        +     up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and
        +     openssl_bio.xs.
        +     [Ralf S. Engelschall]
        +
        +  *) Fix the generation of two part addresses in perl.
        +     [Kenji Miyake <kenji@miyake.org>, integrated by Ben Laurie]
        +
        +  *) Add config entry for Linux on MIPS.
        +     [John Tobey <jtobey@channel1.com>]
        +
        +  *) Make links whenever Configure is run, unless we are on Windoze.
        +     [Ben Laurie]
        +
        +  *) Permit extensions to be added to CRLs using crl_section in openssl.cnf.
        +     Currently only issuerAltName and AuthorityKeyIdentifier make any sense
        +     in CRLs.
        +     [Steve Henson]
        +
        +  *) Add a useful kludge to allow package maintainers to specify compiler and
        +     other platforms details on the command line without having to patch the
        +     Configure script everytime: One now can use ``perl Configure
        +     <id>:<details>'', i.e. platform ids are allowed to have details appended
        +     to them (seperated by colons). This is treated as there would be a static
        +     pre-configured entry in Configure's %table under key <id> with value
        +     <details> and ``perl Configure <id>'' is called.  So, when you want to
        +     perform a quick test-compile under FreeBSD 3.1 with pgcc and without
        +     assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"''
        +     now, which overrides the FreeBSD-elf entry on-the-fly.
        +     [Ralf S. Engelschall]
        +
        +  *) Disable new TLS1 ciphersuites by default: they aren't official yet.
        +     [Ben Laurie]
        +
        +  *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified
        +     on the `perl Configure ...' command line. This way one can compile
        +     OpenSSL libraries with Position Independent Code (PIC) which is needed
        +     for linking it into DSOs.
        +     [Ralf S. Engelschall]
        +
        +  *) Remarkably, export ciphers were totally broken and no-one had noticed!
        +     Fixed.
        +     [Ben Laurie]
        +
        +  *) Cleaned up the LICENSE document: The official contact for any license
        +     questions now is the OpenSSL core team under openssl-core@openssl.org.
        +     And add a paragraph about the dual-license situation to make sure people
        +     recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply
        +     to the OpenSSL toolkit.
        +     [Ralf S. Engelschall]
        +
        +  *) General source tree makefile cleanups: Made `making xxx in yyy...'
        +     display consistent in the source tree and replaced `/bin/rm' by `rm'.
        +     Additonally cleaned up the `make links' target: Remove unnecessary
        +     semicolons, subsequent redundant removes, inline point.sh into mklink.sh
        +     to speed processing and no longer clutter the display with confusing
        +     stuff. Instead only the actually done links are displayed.
        +     [Ralf S. Engelschall]
        +
        +  *) Permit null encryption ciphersuites, used for authentication only. It used
        +     to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this.
        +     It is now necessary to set SSL_FORBID_ENULL to prevent the use of null
        +     encryption.
        +     [Ben Laurie]
        +
        +  *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder
        +     signed attributes when verifying signatures (this would break them), 
        +     the detached data encoding was wrong and public keys obtained using
        +     X509_get_pubkey() weren't freed.
        +     [Steve Henson]
        +
        +  *) Add text documentation for the BUFFER functions. Also added a work around
        +     to a Win95 console bug. This was triggered by the password read stuff: the
        +     last character typed gets carried over to the next fread(). If you were 
        +     generating a new cert request using 'req' for example then the last
        +     character of the passphrase would be CR which would then enter the first
        +     field as blank.
        +     [Steve Henson]
        +
        +  *) Added the new `Includes OpenSSL Cryptography Software' button as
        +     doc/openssl_button.{gif,html} which is similar in style to the old SSLeay
        +     button and can be used by applications based on OpenSSL to show the
        +     relationship to the OpenSSL project.  
        +     [Ralf S. Engelschall]
        +
        +  *) Remove confusing variables in function signatures in files
        +     ssl/ssl_lib.c and ssl/ssl.h.
        +     [Lennart Bong <lob@kulthea.stacken.kth.se>]
        +
        +  *) Don't install bss_file.c under PREFIX/include/
        +     [Lennart Bong <lob@kulthea.stacken.kth.se>]
        +
        +  *) Get the Win32 compile working again. Modify mkdef.pl so it can handle
        +     functions that return function pointers and has support for NT specific
        +     stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various
        +     #ifdef WIN32 and WINNTs sprinkled about the place and some changes from
        +     unsigned to signed types: this was killing the Win32 compile.
        +     [Steve Henson]
        +
        +  *) Add new certificate file to stack functions,
        +     SSL_add_dir_cert_subjects_to_stack() and
        +     SSL_add_file_cert_subjects_to_stack().  These largely supplant
        +     SSL_load_client_CA_file(), and can be used to add multiple certs easily
        +     to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()).
        +     This means that Apache-SSL and similar packages don't have to mess around
        +     to add as many CAs as they want to the preferred list.
        +     [Ben Laurie]
        +
        +  *) Experiment with doxygen documentation. Currently only partially applied to
        +     ssl/ssl_lib.c.
        +     See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with
        +     openssl.doxy as the configuration file.
        +     [Ben Laurie]
        +  
        +  *) Get rid of remaining C++-style comments which strict C compilers hate.
        +     [Ralf S. Engelschall, pointed out by Carlos Amengual]
        +
        +  *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not
        +     compiled in by default: it has problems with large keys.
        +     [Steve Henson]
        +
        +  *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and
        +     DH private keys and/or callback functions which directly correspond to
        +     their SSL_CTX_xxx() counterparts but work on a per-connection basis. This
        +     is needed for applications which have to configure certificates on a
        +     per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis
        +     (e.g. s_server). 
        +        For the RSA certificate situation is makes no difference, but
        +     for the DSA certificate situation this fixes the "no shared cipher"
        +     problem where the OpenSSL cipher selection procedure failed because the
        +     temporary keys were not overtaken from the context and the API provided
        +     no way to reconfigure them. 
        +        The new functions now let applications reconfigure the stuff and they
        +     are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh,
        +     SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback.  Additionally a new
        +     non-public-API function ssl_cert_instantiate() is used as a helper
        +     function and also to reduce code redundancy inside ssl_rsa.c.
        +     [Ralf S. Engelschall]
        +
        +  *) Move s_server -dcert and -dkey options out of the undocumented feature
        +     area because they are useful for the DSA situation and should be
        +     recognized by the users.
        +     [Ralf S. Engelschall]
        +
        +  *) Fix the cipher decision scheme for export ciphers: the export bits are
        +     *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within
        +     SSL_EXP_MASK.  So, the original variable has to be used instead of the
        +     already masked variable.
        +     [Richard Levitte <levitte@stacken.kth.se>]
        +
        +  *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c
        +     [Richard Levitte <levitte@stacken.kth.se>]
        +
        +  *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal()
        +     from `int' to `unsigned int' because it's a length and initialized by
        +     EVP_DigestFinal() which expects an `unsigned int *'.
        +     [Richard Levitte <levitte@stacken.kth.se>]
        +
        +  *) Don't hard-code path to Perl interpreter on shebang line of Configure
        +     script. Instead use the usual Shell->Perl transition trick.
        +     [Ralf S. Engelschall]
        +
        +  *) Make `openssl x509 -noout -modulus' functional also for DSA certificates
        +     (in addition to RSA certificates) to match the behaviour of `openssl dsa
        +     -noout -modulus' as it's already the case for `openssl rsa -noout
        +     -modulus'.  For RSA the -modulus is the real "modulus" while for DSA
        +     currently the public key is printed (a decision which was already done by
        +     `openssl dsa -modulus' in the past) which serves a similar purpose.
        +     Additionally the NO_RSA no longer completely removes the whole -modulus
        +     option; it now only avoids using the RSA stuff. Same applies to NO_DSA
        +     now, too.
        +     [Ralf S.  Engelschall]
        +
        +  *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested
        +     BIO. See the source (crypto/evp/bio_ok.c) for more info.
        +     [Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) Dump the old yucky req code that tried (and failed) to allow raw OIDs
        +     to be added. Now both 'req' and 'ca' can use new objects defined in the
        +     config file.
        +     [Steve Henson]
        +
        +  *) Add cool BIO that does syslog (or event log on NT).
        +     [Arne Ansper <arne@ats.cyber.ee>, integrated by Ben Laurie]
        +
        +  *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5,
        +     TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and
        +     TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher
        +     Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt.
        +     [Ben Laurie]
        +
        +  *) Add preliminary config info for new extension code.
        +     [Steve Henson]
        +
        +  *) Make RSA_NO_PADDING really use no padding.
        +     [Ulf Moeller <ulf@fitug.de>]
        +
        +  *) Generate errors when private/public key check is done.
        +     [Ben Laurie]
        +
        +  *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support
        +     for some CRL extensions and new objects added.
        +     [Steve Henson]
        +
        +  *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private
        +     key usage extension and fuller support for authority key id.
        +     [Steve Henson]
        +
        +  *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved
        +     padding method for RSA, which is recommended for new applications in PKCS
        +     #1 v2.0 (RFC 2437, October 1998).
        +     OAEP (Optimal Asymmetric Encryption Padding) has better theoretical
        +     foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure
        +     against Bleichbacher's attack on RSA.
        +     [Ulf Moeller <ulf@fitug.de>, reformatted, corrected and integrated by
        +      Ben Laurie]
        +
        +  *) Updates to the new SSL compression code
        +     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
        +
        +  *) Fix so that the version number in the master secret, when passed
        +     via RSA, checks that if TLS was proposed, but we roll back to SSLv3
        +     (because the server will not accept higher), that the version number
        +     is 0x03,0x01, not 0x03,0x00
        +     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
        +
        +  *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory
        +     leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes
        +     in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c
        +     [Steve Henson]
        +
        +  *) Support for RAW extensions where an arbitrary extension can be
        +     created by including its DER encoding. See apps/openssl.cnf for
        +     an example.
        +     [Steve Henson]
        +
        +  *) Make sure latest Perl versions don't interpret some generated C array
        +     code as Perl array code in the crypto/err/err_genc.pl script.
        +     [Lars Weber <3weber@informatik.uni-hamburg.de>]
        +
        +  *) Modify ms/do_ms.bat to not generate assembly language makefiles since
        +     not many people have the assembler. Various Win32 compilation fixes and
        +     update to the INSTALL.W32 file with (hopefully) more accurate Win32
        +     build instructions.
        +     [Steve Henson]
        +
        +  *) Modify configure script 'Configure' to automatically create crypto/date.h
        +     file under Win32 and also build pem.h from pem.org. New script
        +     util/mkfiles.pl to create the MINFO file on environments that can't do a
        +     'make files': perl util/mkfiles.pl >MINFO should work.
        +     [Steve Henson]
        +
        +  *) Major rework of DES function declarations, in the pursuit of correctness
        +     and purity. As a result, many evil casts evaporated, and some weirdness,
        +     too. You may find this causes warnings in your code. Zapping your evil
        +     casts will probably fix them. Mostly.
        +     [Ben Laurie]
        +
        +  *) Fix for a typo in asn1.h. Bug fix to object creation script
        +     obj_dat.pl. It considered a zero in an object definition to mean
        +     "end of object": none of the objects in objects.h have any zeros
        +     so it wasn't spotted.
        +     [Steve Henson, reported by Erwann ABALEA <eabalea@certplus.com>]
        +
        +  *) Add support for Triple DES Cipher Block Chaining with Output Feedback
        +     Masking (CBCM). In the absence of test vectors, the best I have been able
        +     to do is check that the decrypt undoes the encrypt, so far. Send me test
        +     vectors if you have them.
        +     [Ben Laurie]
        +
        +  *) Correct calculation of key length for export ciphers (too much space was
        +     allocated for null ciphers). This has not been tested!
        +     [Ben Laurie]
        +
        +  *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage
        +     message is now correct (it understands "crypto" and "ssl" on its
        +     command line). There is also now an "update" option. This will update
        +     the util/ssleay.num and util/libeay.num files with any new functions.
        +     If you do a: 
        +     perl util/mkdef.pl crypto ssl update
        +     it will update them.
        +     [Steve Henson]
        +
        +  *) Overhauled the Perl interface (perl/*):
        +     - ported BN stuff to OpenSSL's different BN library
        +     - made the perl/ source tree CVS-aware
        +     - renamed the package from SSLeay to OpenSSL (the files still contain
        +       their history because I've copied them in the repository)
        +     - removed obsolete files (the test scripts will be replaced
        +       by better Test::Harness variants in the future)
        +     [Ralf S. Engelschall]
        +
        +  *) First cut for a very conservative source tree cleanup:
        +     1. merge various obsolete readme texts into doc/ssleay.txt
        +     where we collect the old documents and readme texts.
        +     2. remove the first part of files where I'm already sure that we no
        +     longer need them because of three reasons: either they are just temporary
        +     files which were left by Eric or they are preserved original files where
        +     I've verified that the diff is also available in the CVS via "cvs diff
        +     -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for
        +     the crypto/md/ stuff).
        +     [Ralf S. Engelschall]
        +
        +  *) More extension code. Incomplete support for subject and issuer alt
        +     name, issuer and authority key id. Change the i2v function parameters
        +     and add an extra 'crl' parameter in the X509V3_CTX structure: guess
        +     what that's for :-) Fix to ASN1 macro which messed up
        +     IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.
        +     [Steve Henson]
        +
        +  *) Preliminary support for ENUMERATED type. This is largely copied from the
        +     INTEGER code.
        +     [Steve Henson]
        +
        +  *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy.
        +     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
        +
        +  *) Make sure `make rehash' target really finds the `openssl' program.
        +     [Ralf S. Engelschall, Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
        +
        +  *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd
        +     like to hear about it if this slows down other processors.
        +     [Ben Laurie]
        +
        +  *) Add CygWin32 platform information to Configure script.
        +     [Alan Batie <batie@aahz.jf.intel.com>]
        +
        +  *) Fixed ms/32all.bat script: `no_asm' -> `no-asm'
        +     [Rainer W. Gerling <gerling@mpg-gv.mpg.de>]
        +  
        +  *) New program nseq to manipulate netscape certificate sequences
        +     [Steve Henson]
        +
        +  *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a
        +     few typos.
        +     [Steve Henson]
        +
        +  *) Fixes to BN code.  Previously the default was to define BN_RECURSION
        +     but the BN code had some problems that would cause failures when
        +     doing certificate verification and some other functions.
        +     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
        +
        +  *) Add ASN1 and PEM code to support netscape certificate sequences.
        +     [Steve Henson]
        +
        +  *) Add ASN1 and PEM code to support netscape certificate sequences.
        +     [Steve Henson]
        +
        +  *) Add several PKIX and private extended key usage OIDs.
        +     [Steve Henson]
        +
        +  *) Modify the 'ca' program to handle the new extension code. Modify
        +     openssl.cnf for new extension format, add comments.
        +     [Steve Henson]
        +
        +  *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req'
        +     and add a sample to openssl.cnf so req -x509 now adds appropriate
        +     CA extensions.
        +     [Steve Henson]
        +
        +  *) Continued X509 V3 changes. Add to other makefiles, integrate with the
        +     error code, add initial support to X509_print() and x509 application.
        +     [Steve Henson]
        +
        +  *) Takes a deep breath and start addding X509 V3 extension support code. Add
        +     files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this
        +     stuff is currently isolated and isn't even compiled yet.
        +     [Steve Henson]
        +
        +  *) Continuing patches for GeneralizedTime. Fix up certificate and CRL
        +     ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print.
        +     Removed the versions check from X509 routines when loading extensions:
        +     this allows certain broken certificates that don't set the version
        +     properly to be processed.
        +     [Steve Henson]
        +
        +  *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another
        +     Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which
        +     can still be regenerated with "make depend".
        +     [Ben Laurie]
        +
        +  *) Spelling mistake in C version of CAST-128.
        +     [Ben Laurie, reported by Jeremy Hylton <jeremy@cnri.reston.va.us>]
        +
        +  *) Changes to the error generation code. The perl script err-code.pl 
        +     now reads in the old error codes and retains the old numbers, only
        +     adding new ones if necessary. It also only changes the .err files if new
        +     codes are added. The makefiles have been modified to only insert errors
        +     when needed (to avoid needlessly modifying header files). This is done
        +     by only inserting errors if the .err file is newer than the auto generated
        +     C file. To rebuild all the error codes from scratch (the old behaviour)
        +     either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl
        +     or delete all the .err files.
        +     [Steve Henson]
        +
        +  *) CAST-128 was incorrectly implemented for short keys. The C version has
        +     been fixed, but is untested. The assembler versions are also fixed, but
        +     new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing
        +     to regenerate it if needed.
        +     [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun
        +      Hagino <itojun@kame.net>]
        +
        +  *) File was opened incorrectly in randfile.c.
        +     [Ulf Möller <ulf@fitug.de>]
        +
        +  *) Beginning of support for GeneralizedTime. d2i, i2d, check and print
        +     functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or
        +     GeneralizedTime. ASN1_TIME is the proper type used in certificates et
        +     al: it's just almost always a UTCTime. Note this patch adds new error
        +     codes so do a "make errors" if there are problems.
        +     [Steve Henson]
        +
        +  *) Correct Linux 1 recognition in config.
        +     [Ulf Möller <ulf@fitug.de>]
        +
        +  *) Remove pointless MD5 hash when using DSA keys in ca.
        +     [Anonymous <nobody@replay.com>]
        +
        +  *) Generate an error if given an empty string as a cert directory. Also
        +     generate an error if handed NULL (previously returned 0 to indicate an
        +     error, but didn't set one).
        +     [Ben Laurie, reported by Anonymous <nobody@replay.com>]
        +
        +  *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last.
        +     [Ben Laurie]
        +
        +  *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct
        +     parameters. This was causing a warning which killed off the Win32 compile.
        +     [Steve Henson]
        +
        +  *) Remove C++ style comments from crypto/bn/bn_local.h.
        +     [Neil Costigan <neil.costigan@celocom.com>]
        +
        +  *) The function OBJ_txt2nid was broken. It was supposed to return a nid
        +     based on a text string, looking up short and long names and finally
        +     "dot" format. The "dot" format stuff didn't work. Added new function
        +     OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote 
        +     OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the
        +     OID is not part of the table.
        +     [Steve Henson]
        +
        +  *) Add prototypes to X509 lookup/verify methods, fixing a bug in
        +     X509_LOOKUP_by_alias().
        +     [Ben Laurie]
        +
        +  *) Sort openssl functions by name.
        +     [Ben Laurie]
        +
        +  *) Get the gendsa program working (hopefully) and add it to app list. Remove
        +     encryption from sample DSA keys (in case anyone is interested the password
        +     was "1234").
        +     [Steve Henson]
        +
        +  *) Make _all_ *_free functions accept a NULL pointer.
        +     [Frans Heymans <fheymans@isaserver.be>]
        +
        +  *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use
        +     NULL pointers.
        +     [Anonymous <nobody@replay.com>]
        +
        +  *) s_server should send the CAfile as acceptable CAs, not its own cert.
        +     [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
        +
        +  *) Don't blow it for numeric -newkey arguments to apps/req.
        +     [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
        +
        +  *) Temp key "for export" tests were wrong in s3_srvr.c.
        +     [Anonymous <nobody@replay.com>]
        +
        +  *) Add prototype for temp key callback functions
        +     SSL_CTX_set_tmp_{rsa,dh}_callback().
        +     [Ben Laurie]
        +
        +  *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and
        +     DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey().
        +     [Steve Henson]
        +
        +  *) X509_name_add_entry() freed the wrong thing after an error.
        +     [Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) rsa_eay.c would attempt to free a NULL context.
        +     [Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) BIO_s_socket() had a broken should_retry() on Windoze.
        +     [Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH.
        +     [Arne Ansper <arne@ats.cyber.ee>]
        +
        +  *) Make sure the already existing X509_STORE->depth variable is initialized
        +     in X509_STORE_new(), but document the fact that this variable is still
        +     unused in the certificate verification process.
        +     [Ralf S. Engelschall]
        +
        +  *) Fix the various library and apps files to free up pkeys obtained from
        +     X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions.
        +     [Steve Henson]
        +
        +  *) Fix reference counting in X509_PUBKEY_get(). This makes
        +     demos/maurice/example2.c work, amongst others, probably.
        +     [Steve Henson and Ben Laurie]
        +
        +  *) First cut of a cleanup for apps/. First the `ssleay' program is now named
        +     `openssl' and second, the shortcut symlinks for the `openssl <command>'
        +     are no longer created. This way we have a single and consistent command
        +     line interface `openssl <command>', similar to `cvs <command>'.
        +     [Ralf S. Engelschall, Paul Sutton and Ben Laurie]
        +
        +  *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey
        +     BIT STRING wrapper always have zero unused bits.
        +     [Steve Henson]
        +
        +  *) Add CA.pl, perl version of CA.sh, add extended key usage OID.
        +     [Steve Henson]
        +
        +  *) Make the top-level INSTALL documentation easier to understand.
        +     [Paul Sutton]
        +
        +  *) Makefiles updated to exit if an error occurs in a sub-directory
        +     make (including if user presses ^C) [Paul Sutton]
        +
        +  *) Make Montgomery context stuff explicit in RSA data structure.
        +     [Ben Laurie]
        +
        +  *) Fix build order of pem and err to allow for generated pem.h.
        +     [Ben Laurie]
        +
        +  *) Fix renumbering bug in X509_NAME_delete_entry().
        +     [Ben Laurie]
        +
        +  *) Enhanced the err-ins.pl script so it makes the error library number 
        +     global and can add a library name. This is needed for external ASN1 and
        +     other error libraries.
        +     [Steve Henson]
        +
        +  *) Fixed sk_insert which never worked properly.
        +     [Steve Henson]
        +
        +  *) Fix ASN1 macros so they can handle indefinite length construted 
        +     EXPLICIT tags. Some non standard certificates use these: they can now
        +     be read in.
        +     [Steve Henson]
        +
        +  *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc)
        +     into a single doc/ssleay.txt bundle. This way the information is still
        +     preserved but no longer messes up this directory. Now it's new room for
        +     the new set of documenation files.
        +     [Ralf S. Engelschall]
        +
        +  *) SETs were incorrectly DER encoded. This was a major pain, because they
        +     shared code with SEQUENCEs, which aren't coded the same. This means that
        +     almost everything to do with SETs or SEQUENCEs has either changed name or
        +     number of arguments.
        +     [Ben Laurie, based on a partial fix by GP Jayan <gp@nsj.co.jp>]
        +
        +  *) Fix test data to work with the above.
        +     [Ben Laurie]
        +
        +  *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but
        +     was already fixed by Eric for 0.9.1 it seems.
        +     [Ben Laurie - pointed out by Ulf Möller <ulf@fitug.de>]
        +
        +  *) Autodetect FreeBSD3.
        +     [Ben Laurie]
        +
        +  *) Fix various bugs in Configure. This affects the following platforms:
        +     nextstep
        +     ncr-scde
        +     unixware-2.0
        +     unixware-2.0-pentium
        +     sco5-cc.
        +     [Ben Laurie]
        +
        +  *) Eliminate generated files from CVS. Reorder tests to regenerate files
        +     before they are needed.
        +     [Ben Laurie]
        +
        +  *) Generate Makefile.ssl from Makefile.org (to keep CVS happy).
        +     [Ben Laurie]
        +
        +
        + Changes between 0.9.1b and 0.9.1c  [23-Dec-1998]
        +
        +  *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and 
        +     changed SSLeay to OpenSSL in version strings.
        +     [Ralf S. Engelschall]
        +  
        +  *) Some fixups to the top-level documents.
        +     [Paul Sutton]
        +
        +  *) Fixed the nasty bug where rsaref.h was not found under compile-time
        +     because the symlink to include/ was missing.
        +     [Ralf S. Engelschall]
        +
        +  *) Incorporated the popular no-RSA/DSA-only patches 
        +     which allow to compile a RSA-free SSLeay.
        +     [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall]
        +
        +  *) Fixed nasty rehash problem under `make -f Makefile.ssl links'
        +     when "ssleay" is still not found.
        +     [Ralf S. Engelschall]
        +
        +  *) Added more platforms to Configure: Cray T3E, HPUX 11, 
        +     [Ralf S. Engelschall, Beckmann <beckman@acl.lanl.gov>]
        +
        +  *) Updated the README file.
        +     [Ralf S. Engelschall]
        +
        +  *) Added various .cvsignore files in the CVS repository subdirs
        +     to make a "cvs update" really silent.
        +     [Ralf S. Engelschall]
        +
        +  *) Recompiled the error-definition header files and added
        +     missing symbols to the Win32 linker tables.
        +     [Ralf S. Engelschall]
        +
        +  *) Cleaned up the top-level documents;
        +     o new files: CHANGES and LICENSE
        +     o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay 
        +     o merged COPYRIGHT into LICENSE
        +     o removed obsolete TODO file
        +     o renamed MICROSOFT to INSTALL.W32
        +     [Ralf S. Engelschall]
        +
        +  *) Removed dummy files from the 0.9.1b source tree: 
        +     crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi
        +     crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f
        +     crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f
        +     crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f
        +     util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f
        +     [Ralf S. Engelschall]
        +
        +  *) Added various platform portability fixes.
        +     [Mark J. Cox]
        +
        +  *) The Genesis of the OpenSSL rpject:
        +     We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A.
        +     Young and Tim J. Hudson created while they were working for C2Net until
        +     summer 1998.
        +     [The OpenSSL Project]
        + 
        +
        + Changes between 0.9.0b and 0.9.1b  [not released]
        +
        +  *) Updated a few CA certificates under certs/
        +     [Eric A. Young]
        +
        +  *) Changed some BIGNUM api stuff.
        +     [Eric A. Young]
        +
        +  *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, 
        +     DGUX x86, Linux Alpha, etc.
        +     [Eric A. Young]
        +
        +  *) New COMP library [crypto/comp/] for SSL Record Layer Compression: 
        +     RLE (dummy implemented) and ZLIB (really implemented when ZLIB is
        +     available).
        +     [Eric A. Young]
        +
        +  *) Add -strparse option to asn1pars program which parses nested 
        +     binary structures 
        +     [Dr Stephen Henson <shenson@bigfoot.com>]
        +
        +  *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs.
        +     [Eric A. Young]
        +
        +  *) DSA fix for "ca" program.
        +     [Eric A. Young]
        +
        +  *) Added "-genkey" option to "dsaparam" program.
        +     [Eric A. Young]
        +
        +  *) Added RIPE MD160 (rmd160) message digest.
        +     [Eric A. Young]
        +
        +  *) Added -a (all) option to "ssleay version" command.
        +     [Eric A. Young]
        +
        +  *) Added PLATFORM define which is the id given to Configure.
        +     [Eric A. Young]
        +
        +  *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking.
        +     [Eric A. Young]
        +
        +  *) Extended the ASN.1 parser routines.
        +     [Eric A. Young]
        +
        +  *) Extended BIO routines to support REUSEADDR, seek, tell, etc.
        +     [Eric A. Young]
        +
        +  *) Added a BN_CTX to the BN library.
        +     [Eric A. Young]
        +
        +  *) Fixed the weak key values in DES library
        +     [Eric A. Young]
        +
        +  *) Changed API in EVP library for cipher aliases.
        +     [Eric A. Young]
        +
        +  *) Added support for RC2/64bit cipher.
        +     [Eric A. Young]
        +
        +  *) Converted the lhash library to the crypto/mem.c functions.
        +     [Eric A. Young]
        +
        +  *) Added more recognized ASN.1 object ids.
        +     [Eric A. Young]
        +
        +  *) Added more RSA padding checks for SSL/TLS.
        +     [Eric A. Young]
        +
        +  *) Added BIO proxy/filter functionality.
        +     [Eric A. Young]
        +
        +  *) Added extra_certs to SSL_CTX which can be used
        +     send extra CA certificates to the client in the CA cert chain sending
        +     process. It can be configured with SSL_CTX_add_extra_chain_cert().
        +     [Eric A. Young]
        +
        +  *) Now Fortezza is denied in the authentication phase because
        +     this is key exchange mechanism is not supported by SSLeay at all.
        +     [Eric A. Young]
        +
        +  *) Additional PKCS1 checks.
        +     [Eric A. Young]
        +
        +  *) Support the string "TLSv1" for all TLS v1 ciphers.
        +     [Eric A. Young]
        +
        +  *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the
        +     ex_data index of the SSL context in the X509_STORE_CTX ex_data.
        +     [Eric A. Young]
        +
        +  *) Fixed a few memory leaks.
        +     [Eric A. Young]
        +
        +  *) Fixed various code and comment typos.
        +     [Eric A. Young]
        +
        +  *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 
        +     bytes sent in the client random.
        +     [Edward Bishop <ebishop@spyglass.com>]
        +
        diff --git a/vendor/openssl/openssl/CHANGES.SSLeay b/vendor/openssl/openssl/CHANGES.SSLeay
        new file mode 100644
        index 000000000..ca5cd7297
        --- /dev/null
        +++ b/vendor/openssl/openssl/CHANGES.SSLeay
        @@ -0,0 +1,968 @@
        +This file contains the changes for the SSLeay library up to version
        +0.9.0b. For later changes, see the file "CHANGES".
        +
        +  SSLeay CHANGES
        +  ______________
        +
        +Changes between 0.8.x and 0.9.0b
        +
        +10-Apr-1998
        +
        +I said the next version would go out at easter, and so it shall.
        +I expect a 0.9.1 will follow with portability fixes in the next few weeks.
        +
        +This is a quick, meet the deadline.  Look to ssl-users for comments on what
        +is new etc.
        +
        +eric (about to go bushwalking for the 4 day easter break :-)
        +
        +16-Mar-98
        +    - Patch for Cray T90 from Wayne Schroeder <schroede@SDSC.EDU>
        +    - Lots and lots of changes
        +
        +29-Jan-98
        +    - ASN1_BIT_STRING_set_bit()/ASN1_BIT_STRING_get_bit() from
        +      Goetz Babin-Ebell <babinebell@trustcenter.de>.
        +    - SSL_version() now returns SSL2_VERSION, SSL3_VERSION or
        +      TLS1_VERSION.
        +
        +7-Jan-98
        +    - Finally reworked the cipher string to ciphers again, so it
        +      works correctly
        +    - All the app_data stuff is now ex_data with funcion calls to access.
        +      The index is supplied by a function and 'methods' can be setup
        +      for the types that are called on XXX_new/XXX_free.  This lets
        +      applications get notified on creation and destruction.  Some of
        +      the RSA methods could be implemented this way and I may do so.
        +    - Oh yes, SSL under perl5 is working at the basic level.
        +
        +15-Dec-97
        +    - Warning - the gethostbyname cache is not fully thread safe,
        +      but it should work well enough.
        +    - Major internal reworking of the app_data stuff.  More functions
        +      but if you were accessing ->app_data directly, things will
        +      stop working.
        +    - The perlv5 stuff is working.  Currently on message digests,
        +      ciphers and the bignum library.
        +
        +9-Dec-97
        +    - Modified re-negotiation so that server initated re-neg
        +      will cause a SSL_read() to return -1 should retry.
        +      The danger otherwise was that the server and the
        +      client could end up both trying to read when using non-blocking
        +      sockets.
        +
        +4-Dec-97
        +    - Lots of small changes
        +    - Fix for binaray mode in Windows for the FILE BIO, thanks to
        +      Bob Denny <rdenny@dc3.com>
        +
        +17-Nov-97
        +    - Quite a few internal cleanups, (removal of errno, and using macros
        +      defined in e_os.h).
        +    - A bug in ca.c, pointed out by yasuyuki-ito@d-cruise.co.jp, where
        +      the automactic naming out output files was being stuffed up.
        +
        +29-Oct-97
        +    - The Cast5 cipher has been added.  MD5 and SHA-1 are now in assember
        +      for x86.
        +
        +21-Oct-97
        +    - Fixed a bug in the BIO_gethostbyname() cache.
        +
        +15-Oct-97
        +    - cbc mode for blowfish/des/3des is now in assember.  Blowfish asm
        +      has also been improved.  At this point in time, on the pentium,
        +      md5 is %80 faster, the unoptimesed sha-1 is %79 faster,
        +      des-cbc is %28 faster, des-ede3-cbc is %9 faster and blowfish-cbc
        +      is %62 faster.
        +
        +12-Oct-97
        +    - MEM_BUF_grow() has been fixed so that it always sets the buf->length
        +      to the value we are 'growing' to.  Think of MEM_BUF_grow() as the
        +      way to set the length value correctly.
        +
        +10-Oct-97
        +    - I now hash for certificate lookup on the raw DER encoded RDN (md5).
        +      This breaks things again :-(.  This is efficent since I cache
        +      the DER encoding of the RDN.
        +    - The text DN now puts in the numeric OID instead of UNKNOWN.
        +    - req can now process arbitary OIDs in the config file.
        +    - I've been implementing md5 in x86 asm, much faster :-).
        +    - Started sha1 in x86 asm, needs more work.
        +    - Quite a few speedups in the BN stuff.  RSA public operation
        +      has been made faster by caching the BN_MONT_CTX structure.
        +      The calulating of the Ai where A*Ai === 1 mod m was rather
        +      expensive.  Basically a 40-50% speedup on public operations.
        +      The RSA speedup is now 15% on pentiums and %20 on pentium
        +      pro.
        +
        +30-Sep-97
        +    - After doing some profiling, I added x86 adm for bn_add_words(),
        +      which just adds 2 arrays of longs together.  A %10 speedup
        +      for 512 and 1024 bit RSA on the pentium pro.
        +
        +29-Sep-97
        +    - Converted the x86 bignum assembler to us the perl scripts
        +      for generation.
        +
        +23-Sep-97
        +    - If SSL_set_session() is passed a NULL session, it now clears the
        +      current session-id.
        +
        +22-Sep-97
        +    - Added a '-ss_cert file' to apps/ca.c.  This will sign selfsigned
        +      certificates.
        +    - Bug in crypto/evp/encode.c where by decoding of 65 base64
        +      encoded lines, one line at a time (via a memory BIO) would report
        +      EOF after the first line was decoded.
        +    - Fix in X509_find_by_issuer_and_serial() from
        +      Dr Stephen Henson <shenson@bigfoot.com>
        +
        +19-Sep-97
        +    - NO_FP_API and NO_STDIO added.
        +    - Put in sh config command.  It auto runs Configure with the correct
        +      parameters.
        +
        +18-Sep-97
        +    - Fix x509.c so if a DSA cert has different parameters to its parent,
        +      they are left in place.  Not tested yet.
        +
        +16-Sep-97
        +    - ssl_create_cipher_list() had some bugs, fixes from
        +      Patrick Eisenacher <eisenach@stud.uni-frankfurt.de>
        +    - Fixed a bug in the Base64 BIO, where it would return 1 instead
        +      of -1 when end of input was encountered but should retry.
        +      Basically a Base64/Memory BIO interaction problem.
        +    - Added a HMAC set of functions in preporarion for TLS work.
        +
        +15-Sep-97
        +    - Top level makefile tweak - Cameron Simpson <cs@zip.com.au>
        +    - Prime generation spead up %25 (512 bit prime, pentium pro linux)
        +      by using montgomery multiplication in the prime number test.
        +
        +11-Sep-97
        +    - Ugly bug in ssl3_write_bytes().  Basically if application land
        +      does a SSL_write(ssl,buf,len) where len > 16k, the SSLv3 write code
        +      did not check the size and tried to copy the entire buffer.
        +      This would tend to cause memory overwrites since SSLv3 has
        +      a maximum packet size of 16k.  If your program uses
        +      buffers <= 16k, you would probably never see this problem.
        +    - Fixed a few errors that were cause by malloc() not returning
        +      0 initialised memory..
        +    - SSL_OP_NETSCAPE_CA_DN_BUG was being switched on when using
        +      SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL); which was a bad thing
        +      since this flags stops SSLeay being able to handle client
        +      cert requests correctly.
        +
        +08-Sep-97
        +    - SSL_SESS_CACHE_NO_INTERNAL_LOOKUP option added.  When switched
        +      on, the SSL server routines will not use a SSL_SESSION that is
        +      held in it's cache.  This in intended to be used with the session-id
        +      callbacks so that while the session-ids are still stored in the
        +      cache, the decision to use them and how to look them up can be
        +      done by the callbacks.  The are the 'new', 'get' and 'remove'
        +      callbacks.  This can be used to determine the session-id
        +      to use depending on information like which port/host the connection
        +      is coming from.  Since the are also SSL_SESSION_set_app_data() and
        +      SSL_SESSION_get_app_data() functions, the application can hold
        +      information against the session-id as well.
        +
        +03-Sep-97
        +    - Added lookup of CRLs to the by_dir method,
        +      X509_load_crl_file() also added.  Basically it means you can
        +      lookup CRLs via the same system used to lookup certificates.
        +    - Changed things so that the X509_NAME structure can contain
        +      ASN.1 BIT_STRINGS which is required for the unique
        +      identifier OID.
        +    - Fixed some problems with the auto flushing of the session-id
        +      cache.  It was not occuring on the server side.
        +
        +02-Sep-97
        +    - Added SSL_CTX_sess_cache_size(SSL_CTX *ctx,unsigned long size)
        +      which is the maximum number of entries allowed in the
        +      session-id cache.  This is enforced with a simple FIFO list.
        +      The default size is 20*1024 entries which is rather large :-).
        +      The Timeout code is still always operating.
        +
        +01-Sep-97
        +    - Added an argument to all the 'generate private key/prime`
        +      callbacks.  It is the last parameter so this should not
        +      break existing code but it is needed for C++.
        +    - Added the BIO_FLAGS_BASE64_NO_NL flag for the BIO_f_base64()
        +      BIO.  This lets the BIO read and write base64 encoded data
        +      without inserting or looking for '\n' characters.  The '-A'
        +      flag turns this on when using apps/enc.c.
        +    - RSA_NO_PADDING added to help BSAFE functionality.  This is a
        +      very dangerous thing to use, since RSA private key
        +      operations without random padding bytes (as PKCS#1 adds) can
        +      be attacked such that the private key can be revealed.
        +    - ASN.1 bug and rc2-40-cbc and rc4-40 added by
        +      Dr Stephen Henson <shenson@bigfoot.com>
        +
        +31-Aug-97 (stuff added while I was away)    
        +    - Linux pthreads by Tim Hudson (tjh@cryptsoft.com).
        +    - RSA_flags() added allowing bypass of pub/priv match check
        +      in ssl/ssl_rsa.c - Tim Hudson.
        +    - A few minor bugs.
        +
        +SSLeay 0.8.1 released.
        +
        +19-Jul-97
        +    - Server side initated dynamic renegotiation is broken.  I will fix
        +      it when I get back from holidays.
        +
        +15-Jul-97
        +    - Quite a few small changes.
        +    - INVALID_SOCKET usage cleanups from Alex Kiernan <alex@hisoft.co.uk>
        +
        +09-Jul-97
        +    - Added 2 new values to the SSL info callback.
        +      SSL_CB_START which is passed when the SSL protocol is started
        +      and SSL_CB_DONE when it has finished sucsessfully.
        +
        +08-Jul-97
        +    - Fixed a few bugs problems in apps/req.c and crypto/asn1/x_pkey.c
        +      that related to DSA public/private keys.
        +    - Added all the relevent PEM and normal IO functions to support
        +      reading and writing RSAPublic keys.
        +    - Changed makefiles to use ${AR} instead of 'ar r'
        +
        +07-Jul-97
        +    - Error in ERR_remove_state() that would leave a dangling reference
        +      to a free()ed location - thanks to Alex Kiernan <alex@hisoft.co.uk>
        +    - s_client now prints the X509_NAMEs passed from the server
        +      when requesting a client cert.
        +    - Added a ssl->type, which is one of SSL_ST_CONNECT or
        +      SSL_ST_ACCEPT.  I had to add it so I could tell if I was
        +      a connect or an accept after the handshake had finished.
        +    - SSL_get_client_CA_list(SSL *s) now returns the CA names
        +      passed by the server if called by a client side SSL.
        +
        +05-Jul-97
        +    - Bug in X509_NAME_get_text_by_OBJ(), looking starting at index
        +      0, not -1 :-(  Fix from Tim Hudson (tjh@cryptsoft.com).
        +
        +04-Jul-97
        +    - Fixed some things in X509_NAME_add_entry(), thanks to
        +      Matthew Donald <matthew@world.net>.
        +    - I had a look at the cipher section and though that it was a
        +      bit confused, so I've changed it.
        +    - I was not setting up the RC4-64-MD5 cipher correctly.  It is
        +      a MS special that appears in exported MS Money.
        +    - Error in all my DH ciphers.  Section 7.6.7.3 of the SSLv3
        +      spec.  I was missing the two byte length header for the
        +      ClientDiffieHellmanPublic value.  This is a packet sent from
        +      the client to the server.  The SSL_OP_SSLEAY_080_CLIENT_DH_BUG
        +      option will enable SSLeay server side SSLv3 accept either
        +      the correct or my 080 packet format.
        +    - Fixed a few typos in crypto/pem.org.
        +
        +02-Jul-97
        +    - Alias mapping for EVP_get_(digest|cipher)byname is now
        +      performed before a lookup for actual cipher.  This means
        +      that an alias can be used to 're-direct' a cipher or a
        +      digest.
        +    - ASN1_read_bio() had a bug that only showed up when using a
        +      memory BIO.  When EOF is reached in the memory BIO, it is
        +      reported as a -1 with BIO_should_retry() set to true.
        +
        +01-Jul-97
        +    - Fixed an error in X509_verify_cert() caused by my
        +      miss-understanding how 'do { contine } while(0);' works.
        +      Thanks to Emil Sit <sit@mit.edu> for educating me :-)
        +
        +30-Jun-97
        +    - Base64 decoding error.  If the last data line did not end with
        +      a '=', sometimes extra data would be returned.
        +    - Another 'cut and paste' bug in x509.c related to setting up the
        +      STDout BIO.
        +
        +27-Jun-97
        +    - apps/ciphers.c was not printing due to an editing error.
        +    - Alex Kiernan <alex@hisoft.co.uk> send in a nice fix for
        +      a library build error in util/mk1mf.pl
        +
        +26-Jun-97
        +    - Still did not have the auto 'experimental' code removal
        +      script correct.
        +    - A few header tweaks for Watcom 11.0 under Win32 from
        +      Rolf Lindemann <Lindemann@maz-hh.de>
        +    - 0 length OCTET_STRING bug in asn1_parse
        +    - A minor fix with an non-existent function in the MS .def files.
        +    - A few changes to the PKCS7 stuff.
        +
        +25-Jun-97
        +    SSLeay 0.8.0 finally it gets released.
        +
        +24-Jun-97
        +    Added a SSL_OP_EPHEMERAL_RSA option which causes all SSLv3 RSA keys to
        +    use a temporary RSA key.  This is experimental and needs some more work.
        +    Fixed a few Win16 build problems.
        +
        +23-Jun-97
        +    SSLv3 bug. I was not doing the 'lookup' of the CERT structure
        +    correctly. I was taking the SSL->ctx->default_cert when I should
        +    have been using SSL->cert. The bug was in ssl/s3_srvr.c
        +
        +20-Jun-97
        +    X509_ATTRIBUTES were being encoded wrongly by apps/reg.c and the
        +    rest of the library. Even though I had the code required to do
        +    it correctly, apps/req.c was doing the wrong thing.  I have fixed
        +    and tested everything.
        +
        +    Missing a few #ifdef FIONBIO sections in crypto/bio/bss_acpt.c.
        +
        +19-Jun-97
        +    Fixed a bug in the SSLv2 server side first packet handling. When
        +    using the non-blocking test BIO, the ssl->s2->first_packet flag
        +    was being reset when a would-block failure occurred when reading
        +    the first 5 bytes of the first packet. This caused the checking
        +    logic to run at the wrong time and cause an error.
        +
        +    Fixed a problem with specifying cipher. If RC4-MD5 were used,
        +    only the SSLv3 version would be picked up.  Now this will pick
        +    up both SSLv2 and SSLv3 versions. This required changing the
        +    SSL_CIPHER->mask values so that they only mask the ciphers,
        +    digests, authentication, export type and key-exchange algorithms.
        +
        +    I found that when a SSLv23 session is established, a reused
        +    session, of type SSLv3 was attempting to write the SSLv2 
        +    ciphers, which were invalid. The SSL_METHOD->put_cipher_by_char 
        +    method has been modified so it will only write out cipher which
        +    that method knows about.  
        +
        +
        + Changes between 0.8.0 and 0.8.1
        +
        +  *) Mostly bug fixes. 
        +     There is an Ephemeral DH cipher problem which is fixed.
        +
        + SSLeay 0.8.0
        +
        +This version of SSLeay has quite a lot of things different from the
        +previous version.
        +
        +Basically check all callback parameters, I will be producing documentation
        +about how to use things in th future.  Currently I'm just getting 080 out
        +the door.  Please not that there are several ways to do everything, and
        +most of the applications in the apps directory are hybrids, some using old
        +methods and some using new methods.
        +
        +Have a look in demos/bio for some very simple programs and
        +apps/s_client.c and apps/s_server.c for some more advanced versions.
        +Notes are definitly needed but they are a week or so away.
        +
        +Anyway, some quick nots from Tim Hudson (tjh@cryptsoft.com)
        +---
        +Quick porting notes for moving from SSLeay-0.6.x to SSLeay-0.8.x to
        +get those people that want to move to using the new code base off to
        +a quick start.
        +
        +Note that Eric has tidied up a lot of the areas of the API that were
        +less than desirable and renamed quite a few things (as he had to break
        +the API in lots of places anyrate). There are a whole pile of additional
        +functions for making dealing with (and creating) certificates a lot
        +cleaner.
        +
        +01-Jul-97
        +Tim Hudson
        +tjh@cryptsoft.com
        +
        +---8<---
        +
        +To maintain code that uses both SSLeay-0.6.x and SSLeay-0.8.x you could
        +use something like the following (assuming you #include "crypto.h" which
        +is something that you really should be doing).
        +
        +#if SSLEAY_VERSION_NUMBER >= 0x0800
        +#define SSLEAY8
        +#endif
        +
        +buffer.h -> splits into buffer.h and bio.h so you need to include bio.h
        +            too if you are working with BIO internal stuff (as distinct
        +        from simply using the interface in an opaque manner)
        +
        +#include "bio.h"    - required along with "buffer.h" if you write
        +              your own BIO routines as the buffer and bio
        +              stuff that was intermixed has been separated
        +              out 
        +            
        +envelope.h -> evp.h  (which should have been done ages ago)
        +
        +Initialisation ... don't forget these or you end up with code that
        +is missing the bits required to do useful things (like ciphers):
        +
        +SSLeay_add_ssl_algorithms()
        +(probably also want SSL_load_error_strings() too but you should have
        + already had that call in place)
        +
        +SSL_CTX_new()   - requires an extra method parameter
        +              SSL_CTX_new(SSLv23_method()) 
        +              SSL_CTX_new(SSLv2_method()) 
        +              SSL_CTX_new(SSLv3_method()) 
        +
        +          OR to only have the server or the client code
        +              SSL_CTX_new(SSLv23_server_method()) 
        +              SSL_CTX_new(SSLv2_server_method()) 
        +              SSL_CTX_new(SSLv3_server_method()) 
        +          or  
        +              SSL_CTX_new(SSLv23_client_method()) 
        +              SSL_CTX_new(SSLv2_client_method()) 
        +              SSL_CTX_new(SSLv3_client_method()) 
        +
        +SSL_set_default_verify_paths() ... renamed to the more appropriate
        +SSL_CTX_set_default_verify_paths()
        +
        +If you want to use client certificates then you have to add in a bit
        +of extra stuff in that a SSLv3 server sends a list of those CAs that
        +it will accept certificates from ... so you have to provide a list to
        +SSLeay otherwise certain browsers will not send client certs.
        +
        +SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(s_cert_file));
        +
        +
        +X509_NAME_oneline(X)    -> X509_NAME_oneline(X,NULL,0)  
        +               or provide a buffer and size to copy the
        +               result into
        +
        +X509_add_cert ->  X509_STORE_add_cert (and you might want to read the
        +          notes on X509_NAME structure changes too)
        +
        +
        +VERIFICATION CODE
        +=================
        +
        +The codes have all be renamed from VERIFY_ERR_* to X509_V_ERR_* to
        +more accurately reflect things.
        +
        +The verification callback args are now packaged differently so that
        +extra fields for verification can be added easily in future without
        +having to break things by adding extra parameters each release :-)
        +
        +X509_cert_verify_error_string -> X509_verify_cert_error_string
        +
        +
        +BIO INTERNALS
        +=============
        +
        +Eric has fixed things so that extra flags can be introduced in
        +the BIO layer in future without having to play with all the BIO
        +modules by adding in some macros.
        +
        +The ugly stuff using 
        +    b->flags ~= (BIO_FLAGS_RW|BIO_FLAGS_SHOULD_RETRY)
        +becomes
        +    BIO_clear_retry_flags(b)
        +
        +    b->flags |= (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)
        +becomes
        +    BIO_set_retry_read(b)
        +
        +Also ... BIO_get_retry_flags(b), BIO_set_flags(b)
        +
        +
        +
        +OTHER THINGS
        +============
        +
        +X509_NAME has been altered so that it isn't just a STACK ... the STACK
        +is now in the "entries" field ... and there are a pile of nice functions
        +for getting at the details in a much cleaner manner.
        +
        +SSL_CTX has been altered ... "cert" is no longer a direct member of this
        +structure ... things are now down under "cert_store" (see x509_vfy.h) and
        +things are no longer in a CERTIFICATE_CTX but instead in a X509_STORE.
        +If your code "knows" about this level of detail then it will need some 
        +surgery.
        +
        +If you depending on the incorrect spelling of a number of the error codes
        +then you will have to change your code as these have been fixed.
        +
        +ENV_CIPHER "type" got renamed to "nid" and as that is what it actually
        +has been all along so this makes things clearer.
        +ify_cert_error_string(ctx->error));
        +
        +SSL_R_NO_CIPHER_WE_TRUST -> SSL_R_NO_CIPHER_LIST
        +            and SSL_R_REUSE_CIPHER_LIST_NOT_ZERO
        +
        +
        +
        + Changes between 0.7.x and 0.8.0
        +  
        +  *) There have been lots of changes, mostly the addition of SSLv3.
        +     There have been many additions from people and amongst
        +     others, C2Net has assisted greatly.
        + 
        + Changes between 0.7.x and 0.7.x
        +
        +  *) Internal development version only
        +
        +SSLeay 0.6.6 13-Jan-1997
        +
        +The main additions are
        +
        +- assember for x86 DES improvments.
        +  From 191,000 per second on a pentium 100, I now get 281,000.  The inner
        +  loop and the IP/FP modifications are from
        +  Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>.  Many thanks for his
        +  contribution.
        +- The 'DES macros' introduced in 0.6.5 now have 3 types.
        +  DES_PTR1, DES_PTR2 and 'normal'.  As per before, des_opts reports which
        +  is best and there is a summery of mine in crypto/des/options.txt
        +- A few bug fixes.
        +- Added blowfish.  It is not used by SSL but all the other stuff that
        +  deals with ciphers can use it in either ecb, cbc, cfb64 or ofb64 modes.
        +  There are 3 options for optimising Blowfish.  BF_PTR, BF_PTR2 and 'normal'.
        +  BF_PTR2 is pentium/x86 specific.  The correct option is setup in
        +  the 'Configure' script.
        +- There is now a 'get client certificate' callback which can be
        +  'non-blocking'.  If more details are required, let me know.  It will
        +  documented more in SSLv3 when I finish it.
        +- Bug fixes from 0.6.5 including the infamous 'ca' bug.  The 'make test'
        +  now tests the ca program.
        +- Lots of little things modified and tweaked.
        +
        + SSLeay 0.6.5
        +
        +After quite some time (3 months), the new release.  I have been very busy
        +for the last few months and so this is mostly bug fixes and improvments.
        +
        +The main additions are
        +
        +- assember for x86 DES.  For all those gcc based systems, this is a big
        +  improvement.  From 117,000 DES operation a second on a pentium 100,
        +  I now get 191,000.  I have also reworked the C version so it
        +  now gives 148,000 DESs per second.  
        +- As mentioned above, the inner DES macros now have some more variant that
        +  sometimes help, sometimes hinder performance.  There are now 3 options
        +  DES_PTR (ptr vs array lookup), DES_UNROLL (full vs partial loop unrolling)
        +  and DES_RISC (a more register intensive version of the inner macro).
        +  The crypto/des/des_opts.c program, when compiled and run, will give
        +  an indication of the correct options to use.
        +- The BIO stuff has been improved.  Read doc/bio.doc.  There are now
        +  modules for encryption and base64 encoding and a BIO_printf() function.
        +- The CA program will accept simple one line X509v3 extensions in the
        +  ssleay.cnf file.  Have a look at the example.  Currently this just
        +  puts the text into the certificate as an OCTET_STRING so currently
        +  the more advanced X509v3 data types are not handled but this is enough
        +  for the netscape extensions.
        +- There is the start of a nicer higher level interface to the X509
        +  strucutre.
        +- Quite a lot of bug fixes.
        +- CRYPTO_malloc_init()  (or CRYPTO_set_mem_functions()) can be used
        +  to define the malloc(), free() and realloc() routines to use
        +  (look in crypto/crypto.h).  This is mostly needed for Windows NT/95 when
        +  using DLLs and mixing CRT libraries.
        +
        +In general, read the 'VERSION' file for changes and be aware that some of
        +the new stuff may not have been tested quite enough yet, so don't just plonk
        +in SSLeay 0.6.5 when 0.6.4 used to work and expect nothing to break.
        +
        +SSLeay 0.6.4 30/08/96 eay
        +
        +I've just finished some test builds on Windows NT, Windows 3.1, Solaris 2.3,
        +Solaris 2.5, Linux, IRIX, HPUX 10 and everthing seems to work :-).
        +
        +The main changes in this release
        +
        +- Thread safe.  have a read of doc/threads.doc and play in the mt directory.
        +  For anyone using 0.6.3 with threads, I found 2 major errors so consider
        +  moving to 0.6.4.  I have a test program that builds under NT and
        +  solaris.
        +- The get session-id callback has changed.  Have a read of doc/callback.doc.
        +- The X509_cert_verify callback (the SSL_verify callback) now
        +  has another argument.  Have a read of doc/callback.doc
        +- 'ca -preserve', sign without re-ordering the DN.  Not tested much.
        +- VMS support.
        +- Compile time memory leak detection can now be built into SSLeay.
        +  Read doc/memory.doc
        +- CONF routines now understand '\', '\n', '\r' etc.  What this means is that
        +  the  SPKAC object mentioned in doc/ns-ca.doc can be on multiple lines.
        +- 'ssleay ciphers' added, lists the default cipher list for SSLeay.
        +- RC2 key setup is now compatable with Netscape.
        +- Modifed server side of SSL implementation, big performance difference when
        +      using session-id reuse.
        +
        +0.6.3
        +
        +Bug fixes and the addition of some nice stuff to the 'ca' program.
        +Have a read of doc/ns-ca.doc for how hit has been modified so
        +it can be driven from a CGI script.  The CGI script is not provided,
        +but that is just being left as an excersize for the reader :-).
        +
        +0.6.2
        +
        +This is most bug fixes and functionality improvements.
        +
        +Additions are
        +- More thread debugging patches, the thread stuff is still being
        +  tested, but for those keep to play with stuff, have a look in
        +  crypto/cryptlib.c.  The application needs to define 1 (or optionaly
        +  a second) callback that is used to implement locking.  Compiling
        +  with LOCK_DEBUG spits out lots of locking crud :-).
        +  This is what I'm currently working on.
        +- SSL_CTX_set_default_passwd_cb() can be used to define the callback
        +  function used in the SSL*_file() functions used to load keys.  I was
        +  always of the opinion that people should call
        +  PEM_read_RSAPrivateKey() and pass the callback they want to use, but
        +  it appears they just want to use the SSL_*_file() function() :-(.
        +- 'enc' now has a -kfile so a key can be read from a file.  This is
        +  mostly used so that the passwd does not appear when using 'ps',
        +  which appears imposible to stop under solaris.
        +- X509v3 certificates now work correctly.  I even have more examples
        +  in my tests :-).  There is now a X509_EXTENSION type that is used in
        +  X509v3 certificates and CRLv2.
        +- Fixed that signature type error :-(
        +- Fixed quite a few potential memory leaks and problems when reusing
        +  X509, CRL and REQ structures.
        +- EVP_set_pw_prompt() now sets the library wide default password
        +  prompt.
        +- The 'pkcs7' command will now, given the -print_certs flag, output in
        +  pem format, all certificates and CRL contained within.  This is more
        +  of a pre-emtive thing for the new verisign distribution method.  I
        +  should also note, that this also gives and example in code, of how
        +  to do this :-), or for that matter, what is involved in going the
        +  other way (list of certs and crl -> pkcs7).
        +- Added RSA's DESX to the DES library.  It is also available via the
        +  EVP_desx_cbc() method and via 'enc desx'. 
        +
        +SSLeay 0.6.1
        +
        +The main functional changes since 0.6.0 are as follows
        +- Bad news, the Microsoft 060 DLL's are not compatable, but the good news is
        +  that from now on, I'll keep the .def numbers the same so they will be.
        +- RSA private key operations are about 2 times faster that 0.6.0
        +- The SSL_CTX now has more fields so default values can be put against
        +  it.  When an SSL structure is created, these default values are used
        +  but can be overwritten.  There are defaults for cipher, certificate,
        +  private key, verify mode and callback.  This means SSL session
        +  creation can now be
        +  ssl=SSL_new()
        +  SSL_set_fd(ssl,sock);
        +  SSL_accept(ssl)
        +  ....
        +  All the other uglyness with having to keep a global copy of the
        +  private key and certificate/verify mode in the server is now gone.
        +- ssl/ssltest.c - one process talking SSL to its self for testing.
        +- Storage of Session-id's can be controled via a session_cache_mode
        +  flag.  There is also now an automatic default flushing of 
        +  old session-id's.
        +- The X509_cert_verify() function now has another parameter, this
        +  should not effect most people but it now means that the reason for
        +  the failure to verify is now available via SSL_get_verify_result(ssl).
        +  You don't have to use a global variable.
        +- SSL_get_app_data() and SSL_set_app_data() can be used to keep some
        +  application data against the SSL structure.  It is upto the application
        +  to free the data.  I don't use it, but it is available.
        +- SSL_CTX_set_cert_verify_callback() can be used to specify a
        +  verify callback function that completly replaces my certificate
        +  verification code.  Xcert should be able to use this :-).
        +  The callback is of the form int app_verify_callback(arg,ssl,cert).
        +  This needs to be documented more.
        +- I have started playing with shared library builds, have a look in
        +  the shlib directory.  It is very simple.  If you need a numbered
        +  list of functions, have a look at misc/crypto.num and misc/ssl.num.
        +- There is some stuff to do locking to make the library thread safe.
        +  I have only started this stuff and have not finished.  If anyone is
        +  keen to do so, please send me the patches when finished.
        +
        +So I have finally made most of the additions to the SSL interface that
        +I thought were needed.
        +
        +There will probably be a pause before I make any non-bug/documentation
        +related changes to SSLeay since I'm feeling like a bit of a break.
        +
        +eric - 12 Jul 1996
        +I saw recently a comment by some-one that we now seem to be entering
        +the age of perpetual Beta software.
        +Pioneered by packages like linux but refined to an art form by
        +netscape.
        +
        +I too wish to join this trend with the anouncement of SSLeay 0.6.0 :-).
        +
        +There are quite a large number of sections that are 'works in
        +progress' in this package.  I will also list the major changes and
        +what files you should read.
        +
        +BIO - this is the new IO structure being used everywhere in SSLeay.  I
        +started out developing this because of microsoft, I wanted a mechanism
        +to callback to the application for all IO, so Windows 3.1 DLL
        +perversion could be hidden from me and the 15 different ways to write
        +to a file under NT would also not be dictated by me at library build
        +time.  What the 'package' is is an API for a data structure containing
        +functions.  IO interfaces can be written to conform to the
        +specification.  This in not intended to hide the underlying data type
        +from the application, but to hide it from SSLeay :-).
        +I have only really finished testing the FILE * and socket/fd modules.
        +There are also 'filter' BIO's.  Currently I have only implemented
        +message digests, and it is in use in the dgst application.  This
        +functionality will allow base64/encrypto/buffering modules to be
        +'push' into a BIO without it affecting the semantics.  I'm also
        +working on an SSL BIO which will hide the SSL_accept()/SLL_connet()
        +from an event loop which uses the interface.
        +It is also possible to 'attach' callbacks to a BIO so they get called
        +before and after each operation, alowing extensive debug output
        +to be generated (try running dgst with -d).
        +
        +Unfortunaly in the conversion from 0.5.x to 0.6.0, quite a few
        +functions that used to take FILE *, now take BIO *.
        +The wrappers are easy to write
        +
        +function_fp(fp,x)
        +FILE *fp;
        +    {
        +    BIO *b;
        +    int ret;
        +
        +    if ((b=BIO_new(BIO_s_file())) == NULL) error.....
        +    BIO_set_fp(b,fp,BIO_NOCLOSE);
        +    ret=function_bio(b,x);
        +    BIO_free(b);
        +    return(ret);
        +    }
        +Remember, there are no functions that take FILE * in SSLeay when
        +compiled for Windows 3.1 DLL's.
        +
        +--
        +I have added a general EVP_PKEY type that can hold a public/private
        +key.  This is now what is used by the EVP_ functions and is passed
        +around internally.  I still have not done the PKCS#8 stuff, but
        +X509_PKEY is defined and waiting :-)
        +
        +--
        +For a full function name listings, have a look at ms/crypt32.def and
        +ms/ssl32.def.  These are auto-generated but are complete.
        +Things like ASN1_INTEGER_get() have been added and are in here if you
        +look.  I have renamed a few things, again, have a look through the
        +function list and you will probably find what you are after.  I intend
        +to at least put a one line descrition for each one.....
        +
        +--
        +Microsoft - thats what this release is about, read the MICROSOFT file.
        +
        +--
        +Multi-threading support.  I have started hunting through the code and
        +flaging where things need to be done.  In a state of work but high on
        +the list.
        +
        +--
        +For random numbers, edit e_os.h and set DEVRANDOM (it's near the top)
        +be be you random data device, otherwise 'RFILE' in e_os.h
        +will be used, in your home directory.  It will be updated
        +periodically.  The environment variable RANDFILE will override this
        +choice and read/write to that file instead.  DEVRANDOM is used in
        +conjunction to the RFILE/RANDFILE.  If you wish to 'seed' the random
        +number generator, pick on one of these files.
        +
        +--
        +
        +The list of things to read and do
        +
        +dgst -d
        +s_client -state (this uses a callback placed in the SSL state loop and
        +        will be used else-where to help debug/monitor what
        +        is happening.)
        +
        +doc/why.doc
        +doc/bio.doc <- hmmm, needs lots of work.
        +doc/bss_file.doc <- one that is working :-)
        +doc/session.doc <- it has changed
        +doc/speed.doc
        + also play with ssleay version -a.  I have now added a SSLeay()
        + function that returns a version number, eg 0600 for this release
        + which is primarily to be used to check DLL version against the
        + application.
        +util/*  Quite a few will not interest people, but some may, like
        + mk1mf.pl, mkdef.pl,
        +util/do_ms.sh
        +
        +try
        +cc -Iinclude -Icrypto -c crypto/crypto.c
        +cc -Iinclude -Issl -c ssl/ssl.c
        +You have just built the SSLeay libraries as 2 object files :-)
        +
        +Have a general rummage around in the bin stall directory and look at
        +what is in there, like CA.sh and c_rehash
        +
        +There are lots more things but it is 12:30am on a Friday night and I'm
        +heading home :-).
        +
        +eric 22-Jun-1996
        +This version has quite a few major bug fixes and improvements.  It DOES NOT
        +do SSLv3 yet.
        +
        +The main things changed
        +- A Few days ago I added the s_mult application to ssleay which is
        +  a demo of an SSL server running in an event loop type thing.
        +  It supports non-blocking IO, I have finally gotten it right, SSL_accept()
        +  can operate in non-blocking IO mode, look at the code to see how :-).
        +  Have a read of doc/s_mult as well.  This program leaks memory and
        +  file descriptors everywhere but I have not cleaned it up yet.
        +  This is a demo of how to do non-blocking IO.
        +- The SSL session management has been 'worked over' and there is now
        +  quite an expansive set of functions to manipulate them.  Have a read of
        +  doc/session.doc for some-things I quickly whipped up about how it now works.
        +  This assume you know the SSLv2 protocol :-)
        +- I can now read/write the netscape certificate format, use the
        +  -inform/-outform  'net' options to the x509 command.  I have not put support
        +  for this type in the other demo programs, but it would be easy to add.
        +- asn1parse and 'enc' have been modified so that when reading base64
        +  encoded files (pem format), they do not require '-----BEGIN' header lines.
        +  The 'enc' program had a buffering bug fixed, it can be used as a general
        +  base64 -> binary -> base64 filter by doing 'enc -a -e' and 'enc -a -d'
        +  respecivly.  Leaving out the '-a' flag in this case makes the 'enc' command
        +  into a form of 'cat'.
        +- The 'x509' and 'req' programs have been fixed and modified a little so
        +  that they generate self-signed certificates correctly.  The test
        +  script actually generates a 'CA' certificate and then 'signs' a
        +  'user' certificate.  Have a look at this shell script (test/sstest)
        +  to see how things work, it tests most possible combinations of what can
        +  be done.
        +- The 'SSL_set_pref_cipher()' function has been 'fixed' and the prefered name
        +  of SSL_set_cipher_list() is now the correct API (stops confusion :-).
        +  If this function is used in the client, only the specified ciphers can
        +  be used, with preference given to the order the ciphers were listed.
        +  For the server, if this is used, only the specified ciphers will be used
        +  to accept connections.  If this 'option' is not used, a default set of
        +  ciphers will be used.  The SSL_CTX_set_cipher_list(SSL_CTX *ctx) sets this
        +  list for all ciphers started against the SSL_CTX.  So the order is
        +  SSL cipher_list, if not present, SSL_CTX cipher list, if not
        +  present, then the library default.
        +  What this means is that normally ciphers like
        +  NULL-MD5 will never be used.  The only way this cipher can be used
        +  for both ends to specify to use it.
        +  To enable or disable ciphers in the library at build time, modify the
        +  first field for the cipher in the ssl_ciphers array in ssl/ssl_lib.c.
        +  This file also contains the 'pref_cipher' list which is the default
        +  cipher preference order.
        +- I'm not currently sure if the 'rsa -inform net' and the 'rsa -outform net'
        +  options work.  They should, and they enable loading and writing the
        +  netscape rsa private key format.  I will be re-working this section of
        +  SSLeay for the next version.  What is currently in place is a quick and
        +  dirty hack.
        +- I've re-written parts of the bignum library.  This gives speedups
        +  for all platforms.  I now provide assembler for use under Windows NT.
        +  I have not tested the Windows 3.1 assembler but it is quite simple code.
        +  This gives RSAprivate_key operation encryption times of 0.047s (512bit key)
        +  and 0.230s (1024bit key) on a pentium 100 which I consider reasonable.
        +  Basically the times available under linux/solaris x86 can be achieve under
        +  Windows NT.  I still don't know how these times compare to RSA's BSAFE
        +  library but I have been emailing with people and with their help, I should
        +  be able to get my library's quite a bit faster still (more algorithm changes).
        +  The object file crypto/bn/asm/x86-32.obj should be used when linking
        +  under NT.
        +- 'make makefile.one' in the top directory will generate a single makefile
        +  called 'makefile.one'  This makefile contains no perl references and
        +  will build the SSLeay library into the 'tmp' and 'out' directories.
        +  util/mk1mf.pl >makefile.one is how this makefile is
        +  generated.  The mk1mf.pl command take several option to generate the
        +  makefile for use with cc, gcc, Visual C++ and Borland C++.  This is
        +  still under development.  I have only build .lib's for NT and MSDOS
        +  I will be working on this more.  I still need to play with the
        +  correct compiler setups for these compilers and add some more stuff but
        +  basically if you just want to compile the library
        +  on a 'non-unix' platform, this is a very very good file to start with :-).
        +  Have a look in the 'microsoft' directory for my current makefiles.
        +  I have not yet modified things to link with sockets under Windows NT.
        +  You guys should be able to do this since this is actually outside of the
        +  SSLeay scope :-).  I will be doing it for myself soon.
        +  util/mk1mf.pl takes quite a few options including no-rc, rsaref  and no-sock
        +  to build without RC2/RC4, to require RSAref for linking, and to
        +  build with no socket code.
        +
        +- Oh yes, the cipher that was reported to be compatible with RSA's RC2 cipher
        +  that was posted to sci.crypt has been added to the library and SSL.
        +  I take the view that if RC2 is going to be included in a standard,
        +  I'll include the cipher to make my package complete.
        +  There are NO_RC2, NO_RC4 and NO_IDEA macros to remove these ciphers
        +  at compile time.  I have not tested this recently but it should all work
        +  and if you are in the USA and don't want RSA threatening to sue you,
        +  you could probably remove the RC4/RC2 code inside these sections.
        +  I may in the future include a perl script that does this code
        +  removal automatically for those in the USA :-).
        +- I have removed all references to sed in the makefiles.  So basically,
        +  the development environment requires perl and sh.  The build environment
        +  does not (use the makefile.one makefile).
        +  The Configure script still requires perl, this will probably stay that way
        +  since I have perl for Windows NT :-).
        +
        +eric (03-May-1996)
        +
        +PS Have a look in the VERSION file for more details on the changes and
        +   bug fixes.
        +I have fixed a few bugs, added alpha and x86 assembler and generally cleaned
        +things up.  This version will be quite stable, mostly because I'm on
        +holidays until 10-March-1996.  For any problems in the interum, send email
        +to Tim Hudson <tjh@mincom.oz.au>.
        +
        +SSLeay 0.5.0
        +
        +12-12-95
        +This is going out before it should really be released.
        +
        +I leave for 11 weeks holidays on the 22-12-95 and so I either sit on
        +this for 11 weeks or get things out.  It is still going to change a
        +lot in the next week so if you do grab this version, please test and
        +give me feed back ASAP, inculuding questions on how to do things with
        +the library.  This will prompt me to write documentation so I don't
        +have to answer the same question again :-).
        +
        +This 'pre' release version is for people who are interested in the
        +library.  The applications will have to be changed to use
        +the new version of the SSL interface.  I intend to finish more
        +documentation before I leave but until then, look at the programs in
        +the apps directory.  As far as code goes, it is much much nicer than
        +the old version.
        +
        +The current library works, has no memory leaks (as far as I can tell)
        +and is far more bug free that 0.4.5d.  There are no global variable of
        +consequence (I believe) and I will produce some documentation that
        +tell where to look for those people that do want to do multi-threaded
        +stuff.
        +
        +There should be more documentation.  Have a look in the
        +doc directory.  I'll be adding more before I leave, it is a start
        +by mostly documents the crypto library.  Tim Hudson will update
        +the web page ASAP.  The spelling and grammar are crap but
        +it is better than nothing :-)
        +
        +Reasons to start playing with version 0.5.0
        +- All the programs in the apps directory build into one ssleay binary.
        +- There is a new version of the 'req' program that generates certificate
        +  requests, there is even documentation for this one :-)
        +- There is a demo certification authorithy program.  Currently it will
        +  look at the simple database and update it.  It will generate CRL from
        +  the data base.  You need to edit the database by hand to revoke a
        +  certificate, it is my aim to use perl5/Tk but I don't have time to do
        +  this right now.  It will generate the certificates but the management
        +  scripts still need to be written.  This is not a hard task.
        +- Things have been cleaned up alot.
        +- Have a look at the enc and dgst programs in the apps directory.
        +- It supports v3 of x509 certiticates.
        +
        +
        +Major things missing.
        +- I have been working on (and thinging about) the distributed x509
        +  hierachy problem.  I have not had time to put my solution in place.
        +  It will have to wait until I come back.
        +- I have not put in CRL checking in the certificate verification but
        +  it would not be hard to do.  I was waiting until I could generate my
        +  own CRL (which has only been in the last week) and I don't have time
        +  to put it in correctly.
        +- Montgomery multiplication need to be implemented.  I know the
        +  algorithm, just ran out of time.
        +- PKCS#7.  I can load and write the DER version.  I need to re-work
        +  things to support BER (if that means nothing, read the ASN1 spec :-).
        +- Testing of the higher level digital envelope routines.  I have not
        +  played with the *_seal() and *_open() type functions.  They are
        +  written but need testing.  The *_sign() and *_verify() functions are
        +  rock solid. 
        +- PEM.  Doing this and PKCS#7 have been dependant on the distributed
        +  x509 heirachy problem.  I started implementing my ideas, got
        +  distracted writing a CA program and then ran out of time.  I provide
        +  the functionality of RSAref at least.
        +- Re work the asm. code for the x86.  I've changed by low level bignum
        +  interface again, so I really need to tweak the x86 stuff.  gcc is
        +  good enough for the other boxes.
        +
        diff --git a/vendor/openssl/openssl/Configure b/vendor/openssl/openssl/Configure
        new file mode 100644
        index 000000000..9c803dc06
        --- /dev/null
        +++ b/vendor/openssl/openssl/Configure
        @@ -0,0 +1,2176 @@
        +:
        +eval 'exec perl -S $0 ${1+"$@"}'
        +    if $running_under_some_shell;
        +##
        +##  Configure -- OpenSSL source tree configuration script
        +##
        +
        +require 5.000;
        +use strict;
        +
        +# see INSTALL for instructions.
        +
        +my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
        +
        +# Options:
        +#
        +# --openssldir  install OpenSSL in OPENSSLDIR (Default: DIR/ssl if the
        +#               --prefix option is given; /usr/local/ssl otherwise)
        +# --prefix      prefix for the OpenSSL include, lib and bin directories
        +#               (Default: the OPENSSLDIR directory)
        +#
        +# --install_prefix  Additional prefix for package builders (empty by
        +#               default).  This needn't be set in advance, you can
        +#               just as well use "make INSTALL_PREFIX=/whatever install".
        +#
        +# --with-krb5-dir  Declare where Kerberos 5 lives.  The libraries are expected
        +#		to live in the subdirectory lib/ and the header files in
        +#		include/.  A value is required.
        +# --with-krb5-lib  Declare where the Kerberos 5 libraries live.  A value is
        +#		required.
        +#		(Default: KRB5_DIR/lib)
        +# --with-krb5-include  Declare where the Kerberos 5 header files live.  A
        +#		value is required.
        +#		(Default: KRB5_DIR/include)
        +# --with-krb5-flavor  Declare what flavor of Kerberos 5 is used.  Currently
        +#		supported values are "MIT" and "Heimdal".  A value is required.
        +#
        +# --test-sanity Make a number of sanity checks on the data in this file.
        +#               This is a debugging tool for OpenSSL developers.
        +#
        +# --cross-compile-prefix Add specified prefix to binutils components.
        +#
        +# no-hw-xxx     do not compile support for specific crypto hardware.
        +#               Generic OpenSSL-style methods relating to this support
        +#               are always compiled but return NULL if the hardware
        +#               support isn't compiled.
        +# no-hw         do not compile support for any crypto hardware.
        +# [no-]threads  [don't] try to create a library that is suitable for
        +#               multithreaded applications (default is "threads" if we
        +#               know how to do it)
        +# [no-]shared	[don't] try to create shared libraries when supported.
        +# no-asm        do not use assembler
        +# no-dso        do not compile in any native shared-library methods. This
        +#               will ensure that all methods just return NULL.
        +# no-krb5       do not compile in any KRB5 library or code.
        +# [no-]zlib     [don't] compile support for zlib compression.
        +# zlib-dynamic	Like "zlib", but the zlib library is expected to be a shared
        +#		library and will be loaded in run-time by the OpenSSL library.
        +# sctp          include SCTP support
        +# 386           generate 80386 code
        +# no-sse2	disables IA-32 SSE2 code, above option implies no-sse2
        +# no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
        +# -<xxx> +<xxx> compiler options are passed through 
        +#
        +# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
        +#		provided to stack calls. Generates unique stack functions for
        +#		each possible stack type.
        +# DES_PTR	use pointer lookup vs arrays in the DES in crypto/des/des_locl.h
        +# DES_RISC1	use different DES_ENCRYPT macro that helps reduce register
        +#		dependancies but needs to more registers, good for RISC CPU's
        +# DES_RISC2	A different RISC variant.
        +# DES_UNROLL	unroll the inner DES loop, sometimes helps, somtimes hinders.
        +# DES_INT	use 'int' instead of 'long' for DES_LONG in crypto/des/des.h
        +#		This is used on the DEC Alpha where long is 8 bytes
        +#		and int is 4
        +# BN_LLONG	use the type 'long long' in crypto/bn/bn.h
        +# MD2_CHAR	use 'char' instead of 'int' for MD2_INT in crypto/md2/md2.h
        +# MD2_LONG	use 'long' instead of 'int' for MD2_INT in crypto/md2/md2.h
        +# IDEA_SHORT	use 'short' instead of 'int' for IDEA_INT in crypto/idea/idea.h
        +# IDEA_LONG	use 'long' instead of 'int' for IDEA_INT in crypto/idea/idea.h
        +# RC2_SHORT	use 'short' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
        +# RC2_LONG	use 'long' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
        +# RC4_CHAR	use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
        +# RC4_LONG	use 'long' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
        +# RC4_INDEX	define RC4_INDEX in crypto/rc4/rc4_locl.h.  This turns on
        +#		array lookups instead of pointer use.
        +# RC4_CHUNK	enables code that handles data aligned at long (natural CPU
        +#		word) boundary.
        +# RC4_CHUNK_LL	enables code that handles data aligned at long long boundary
        +#		(intended for 64-bit CPUs running 32-bit OS).
        +# BF_PTR	use 'pointer arithmatic' for Blowfish (unsafe on Alpha).
        +# BF_PTR2	intel specific version (generic version is more efficient).
        +#
        +# Following are set automatically by this script
        +#
        +# MD5_ASM	use some extra md5 assember,
        +# SHA1_ASM	use some extra sha1 assember, must define L_ENDIAN for x86
        +# RMD160_ASM	use some extra ripemd160 assember,
        +# SHA256_ASM	sha256_block is implemented in assembler
        +# SHA512_ASM	sha512_block is implemented in assembler
        +# AES_ASM	ASE_[en|de]crypt is implemented in assembler
        +
        +# Minimum warning options... any contributions to OpenSSL should at least get
        +# past these. 
        +
        +my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED";
        +
        +my $strict_warnings = 0;
        +
        +my $x86_gcc_des="DES_PTR DES_RISC1 DES_UNROLL";
        +
        +# MD2_CHAR slags pentium pros
        +my $x86_gcc_opts="RC4_INDEX MD2_INT";
        +
        +# MODIFY THESE PARAMETERS IF YOU ARE GOING TO USE THE 'util/speed.sh SCRIPT
        +# Don't worry about these normally
        +
        +my $tcc="cc";
        +my $tflags="-fast -Xa";
        +my $tbn_mul="";
        +my $tlib="-lnsl -lsocket";
        +#$bits1="SIXTEEN_BIT ";
        +#$bits2="THIRTY_TWO_BIT ";
        +my $bits1="THIRTY_TWO_BIT ";
        +my $bits2="SIXTY_FOUR_BIT ";
        +
        +my $x86_asm="x86cpuid.o:bn-586.o co-586.o x86-mont.o x86-gf2m.o:des-586.o crypt586.o:aes-586.o vpaes-x86.o aesni-x86.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o:cmll-x86.o:ghash-x86.o:";
        +
        +my $x86_elf_asm="$x86_asm:elf";
        +
        +my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:";
        +my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
        +my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
        +my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void";
        +my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
        +my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::";
        +my $mips64_asm=":bn-mips.o mips-mont.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o sha512-mips.o::::::::";
        +my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o s390x-gf2m.o::aes-s390x.o aes-ctr.o aes-xts.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::ghash-s390x.o:";
        +my $armv4_asm="armcap.o armv4cpuid.o:bn_asm.o armv4-mont.o armv4-gf2m.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::ghash-armv4.o::void";
        +my $parisc11_asm="pariscid.o:bn_asm.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::32";
        +my $parisc20_asm="pariscid.o:pa-risc2W.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::64";
        +my $ppc32_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::::";
        +my $ppc64_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::::";
        +my $no_asm=":::::::::::::::void";
        +
        +# As for $BSDthreads. Idea is to maintain "collective" set of flags,
        +# which would cover all BSD flavors. -pthread applies to them all, 
        +# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
        +# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
        +# which has to be accompanied by explicit -D_THREAD_SAFE and
        +# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
        +# seems to be sufficient?
        +my $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
        +
        +#config-string	$cc : $cflags : $unistd : $thread_cflag : $sys_id : $lflags : $bn_ops : $cpuid_obj : $bn_obj : $des_obj : $aes_obj : $bf_obj : $md5_obj : $sha1_obj : $cast_obj : $rc4_obj : $rmd160_obj : $rc5_obj : $wp_obj : $cmll_obj : $modes_obj : $engines_obj : $dso_scheme : $shared_target : $shared_cflag : $shared_ldflag : $shared_extension : $ranlib : $arflags : $multilib
        +
        +my %table=(
        +# File 'TABLE' (created by 'make TABLE') contains the data from this list,
        +# formatted for better readability.
        +
        +
        +#"b",		"${tcc}:${tflags}::${tlib}:${bits1}:${tbn_mul}::",
        +#"bl-4c-2c",	"${tcc}:${tflags}::${tlib}:${bits1}BN_LLONG RC4_CHAR MD2_CHAR:${tbn_mul}::",
        +#"bl-4c-ri",	"${tcc}:${tflags}::${tlib}:${bits1}BN_LLONG RC4_CHAR RC4_INDEX:${tbn_mul}::",
        +#"b2-is-ri-dp",	"${tcc}:${tflags}::${tlib}:${bits2}IDEA_SHORT RC4_INDEX DES_PTR:${tbn_mul}::",
        +
        +# Our development configs
        +"purify",	"purify gcc:-g -DPURIFY -Wall::(unknown)::-lsocket -lnsl::::",
        +"debug",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror::(unknown)::-lefence::::",
        +"debug-ben",	"gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DDEBUG_SAFESTACK -O2 -pipe::(unknown):::::",
        +"debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
        +"debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
        +"debug-ben-debug",	"gcc44:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O2 -pipe::(unknown)::::::",
        +"debug-ben-debug-64",	"gcc:$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-ben-macos",	"cc:$gcc_devteam_warn -arch i386 -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O3 -DL_ENDIAN -g3 -pipe::(unknown)::-Wl,-search_paths_first::::",
        +"debug-ben-macos-gcc46",	"gcc-mp-4.6:$gcc_devteam_warn -Wconversion -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O3 -DL_ENDIAN -g3 -pipe::(unknown)::::::",
        +"debug-ben-darwin64","cc:$gcc_devteam_warn -Wno-language-extension-token -Wno-extended-offsetof -arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +"debug-ben-no-opt",	"gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::",
        +"debug-ben-strict",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
        +"debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
        +"debug-bodo",	"gcc:$gcc_devteam_warn -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -DBIO_PAIR_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +"debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll",
        +"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -Wno-overlength-strings -g::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-geoff32","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:BN_LLONG:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-geoff64","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-linux-pentium","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentium -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
        +"debug-linux-ppro","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
        +"debug-linux-elf","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-lefence -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-linux-elf-noefence","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-linux-ia32-aes", "gcc:-DAES_EXPERIMENTAL -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes_x86core.o aes_cbc.o aesni-x86.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o::ghash-x86.o::elf:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-linux-generic32","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-linux-generic64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DTERMIO -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-linux-x86_64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -DTERMIO -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +"dist",		"cc:-O::(unknown)::::::",
        +
        +# Basic configs that should work on any (32 and less bit) box
        +"gcc",		"gcc:-O3::(unknown):::BN_LLONG:::",
        +"cc",		"cc:-O::(unknown)::::::",
        +
        +####VOS Configurations
        +"vos-gcc","gcc:-O3 -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
        +"debug-vos-gcc","gcc:-O0 -g -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
        +
        +#### Solaris x86 with GNU C setups
        +# -DOPENSSL_NO_INLINE_ASM switches off inline assembler. We have to do it
        +# here because whenever GNU C instantiates an assembler template it
        +# surrounds it with #APP #NO_APP comment pair which (at least Solaris
        +# 7_x86) /usr/ccs/bin/as fails to assemble with "Illegal mnemonic"
        +# error message.
        +"solaris-x86-gcc","gcc:-O3 -fomit-frame-pointer -march=pentium -Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# -shared -static-libgcc might appear controversial, but modules taken
        +# from static libgcc do not have relocations and linking them into our
        +# shared objects doesn't have any negative side-effects. On the contrary,
        +# doing so makes it possible to use gcc shared build with Sun C. Given
        +# that gcc generates faster code [thanks to inline assembler], I would
        +# actually recommend to consider using gcc shared build even with vendor
        +# compiler:-)
        +#						<appro@fy.chalmers.se>
        +"solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
        + 
        +#### Solaris x86 with Sun C setups
        +"solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"solaris64-x86_64-cc","cc:-fast -xarch=amd64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-xarch=amd64 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
        +
        +#### SPARC Solaris with GNU C setups
        +"solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"solaris-sparcv8-gcc","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# -m32 should be safe to add as long as driver recognizes -mcpu=ultrasparc
        +"solaris-sparcv9-gcc","gcc:-m32 -mcpu=ultrasparc -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"solaris64-sparcv9-gcc","gcc:-m64 -mcpu=ultrasparc -O3 -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-m64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
        +####
        +"debug-solaris-sparcv8-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mv8 -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-solaris-sparcv9-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -DPEDANTIC -O -g -mcpu=ultrasparc -pedantic -ansi -Wall -Wshadow -Wno-long-long -D__EXTENSIONS__ -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +#### SPARC Solaris with Sun C setups
        +# SC4.0 doesn't pass 'make test', upgrade to SC5.0 or SC4.2.
        +# SC4.2 is ok, better than gcc even on bn as long as you tell it -xarch=v8
        +# SC5.0 note: Compiler common patch 107357-01 or later is required!
        +"solaris-sparcv7-cc","cc:-xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"solaris-sparcv8-cc","cc:-xarch=v8 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"solaris-sparcv9-cc","cc:-xtarget=ultra -xarch=v8plus -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"solaris64-sparcv9-cc","cc:-xtarget=ultra -xarch=v9 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-xarch=v9 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
        +####
        +"debug-solaris-sparcv8-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xarch=v8 -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-solaris-sparcv9-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xtarget=ultra -xarch=v8plus -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", 
        +
        +#### SunOS configs, assuming sparc for the gcc one.
        +#"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
        +"sunos-gcc","gcc:-O3 -mv8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
        +
        +#### IRIX 5.x configs
        +# -mips2 flag is added by ./config when appropriate.
        +"irix-gcc","gcc:-O3 -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"irix-cc", "cc:-O2 -use_readonly_const -DTERMIOS -DB_ENDIAN::(unknown):::BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +#### IRIX 6.x configs
        +# Only N32 and N64 ABIs are supported. If you need O32 ABI build, invoke
        +# './Configure irix-cc -o32' manually.
        +"irix-mips3-gcc","gcc:-mabi=n32 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK_LL DES_UNROLL DES_RISC2 DES_PTR BF_PTR SIXTY_FOUR_BIT:${mips64_asm}:n32:dlfcn:irix-shared::-mabi=n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
        +"irix-mips3-cc", "cc:-n32 -mips3 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::DES_PTR RC4_CHAR RC4_CHUNK_LL DES_RISC2 DES_UNROLL BF_PTR SIXTY_FOUR_BIT:${mips64_asm}:n32:dlfcn:irix-shared::-n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
        +# N64 ABI builds.
        +"irix64-mips4-gcc","gcc:-mabi=64 -mips4 -O3 -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips64_asm}:64:dlfcn:irix-shared::-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +"irix64-mips4-cc", "cc:-64 -mips4 -O2 -use_readonly_const -G0 -rdata_shared -DTERMIOS -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips64_asm}:64:dlfcn:irix-shared::-64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +
        +#### Unified HP-UX ANSI C configs.
        +# Special notes:
        +# - Originally we were optimizing at +O4 level. It should be noted
        +#   that the only difference between +O3 and +O4 is global inter-
        +#   procedural analysis. As it has to be performed during the link
        +#   stage the compiler leaves behind certain pseudo-code in lib*.a
        +#   which might be release or even patch level specific. Generating
        +#   the machine code for and analyzing the *whole* program appears
        +#   to be *extremely* memory demanding while the performance gain is
        +#   actually questionable. The situation is intensified by the default
        +#   HP-UX data set size limit (infamous 'maxdsiz' tunable) of 64MB
        +#   which is way too low for +O4. In other words, doesn't +O3 make
        +#   more sense?
        +# - Keep in mind that the HP compiler by default generates code
        +#   suitable for execution on the host you're currently compiling at.
        +#   If the toolkit is ment to be used on various PA-RISC processors
        +#   consider './config +DAportable'.
        +# - +DD64 is chosen in favour of +DA2.0W because it's meant to be
        +#   compatible with *future* releases.
        +# - If you run ./Configure hpux-parisc-[g]cc manually don't forget to
        +#   pass -D_REENTRANT on HP-UX 10 and later.
        +# - -DMD32_XARRAY triggers workaround for compiler bug we ran into in
        +#   32-bit message digests. (For the moment of this writing) HP C
        +#   doesn't seem to "digest" too many local variables (they make "him"
        +#   chew forever:-). For more details look-up MD32_XARRAY comment in
        +#   crypto/sha/sha_lcl.h.
        +#					<appro@fy.chalmers.se>
        +#
        +# Since there is mention of this in shlib/hpux10-cc.sh
        +"hpux-parisc-cc-o4","cc:-Ae +O4 +ESlit -z -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"hpux-parisc-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"hpux-parisc1_1-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${parisc11_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa1.1",
        +"hpux-parisc2-gcc","gcc:-march=2.0 -O3 -DB_ENDIAN -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL DES_RISC1:".eval{my $asm=$parisc20_asm;$asm=~s/2W\./2\./;$asm=~s/:64/:32/;$asm}.":dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_32",
        +"hpux64-parisc2-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::::void:dlfcn:hpux-shared:-fpic:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
        +
        +# More attempts at unified 10.X and 11.X targets for HP C compiler.
        +#
        +# Chris Ruemmler <ruemmler@cup.hp.com>
        +# Kevin Steves <ks@hp.se>
        +"hpux-parisc-cc","cc:+O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"hpux-parisc1_1-cc","cc:+DA1.1 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${parisc11_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa1.1",
        +"hpux-parisc2-cc","cc:+DA2.0 +DS2.0 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:".eval{my $asm=$parisc20_asm;$asm=~s/2W\./2\./;$asm=~s/:64/:32/;$asm}.":dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_32",
        +"hpux64-parisc2-cc","cc:+DD64 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${parisc20_asm}:dlfcn:hpux-shared:+Z:+DD64 -b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
        +
        +# HP/UX IA-64 targets
        +"hpux-ia64-cc","cc:-Ae +DD32 +O2 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD32 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
        +# Frank Geurts <frank.geurts@nl.abnamro.com> has patiently assisted with
        +# with debugging of the following config.
        +"hpux64-ia64-cc","cc:-Ae +DD64 +O3 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD64 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux64",
        +# GCC builds...
        +"hpux-ia64-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:-fpic:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
        +"hpux64-ia64-gcc","gcc:-mlp64 -O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:-fpic:-mlp64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux64", 
        +
        +# Legacy HPUX 9.X configs...
        +"hpux-cc",	"cc:-DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY -Ae +ESlit +O2 -z::(unknown)::-Wl,+s -ldld:DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"hpux-gcc",	"gcc:-DB_ENDIAN -DBN_DIV2W -O3::(unknown)::-Wl,+s -ldld:DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +#### HP MPE/iX http://jazz.external.hp.com/src/openssl/
        +"MPE/iX-gcc",	"gcc:-D_ENDIAN -DBN_DIV2W -O3 -D_POSIX_SOURCE -D_SOCKET_SOURCE -I/SYSLOG/PUB::(unknown):MPE:-L/SYSLOG/PUB -lsyslog -lsocket -lcurses:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:::",
        +
        +# DEC Alpha OSF/1/Tru64 targets.
        +#
        +#	"What's in a name? That which we call a rose
        +#	 By any other word would smell as sweet."
        +#
        +# - William Shakespeare, "Romeo & Juliet", Act II, scene II.
        +#
        +# For gcc, the following gave a %50 speedup on a 164 over the 'DES_INT' version
        +#
        +"osf1-alpha-gcc", "gcc:-O3::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_RISC1:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so",
        +"osf1-alpha-cc",  "cc:-std1 -tune host -O4 -readonly_strings::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so",
        +"tru64-alpha-cc", "cc:-std1 -tune host -fast -readonly_strings::-pthread:::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared::-msym:.so",
        +
        +####
        +#### Variety of LINUX:-)
        +####
        +# *-generic* is endian-neutral target, but ./config is free to
        +# throw in -D[BL]_ENDIAN, whichever appropriate...
        +"linux-generic32","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-ppc",	"gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc32_asm}:linux32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# It's believed that majority of ARM toolchains predefine appropriate -march.
        +# If you compiler does not, do complement config command line with one!
        +"linux-armv4",	"gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +#### IA-32 targets...
        +"linux-ia32-icc",	"icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-elf",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-aout",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out",
        +####
        +"linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-ppc64",	"gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc64_asm}:linux64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +"linux-ia64",	"gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-x86_64",	"gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +"linux64-s390x",	"gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +#### So called "highgprs" target for z/Architecture CPUs
        +# "Highgprs" is kernel feature first implemented in Linux 2.6.32, see
        +# /proc/cpuinfo. The idea is to preserve most significant bits of
        +# general purpose registers not only upon 32-bit process context
        +# switch, but even on asynchronous signal delivery to such process.
        +# This makes it possible to deploy 64-bit instructions even in legacy
        +# application context and achieve better [or should we say adequate]
        +# performance. The build is binary compatible with linux-generic32,
        +# and the idea is to be able to install the resulting libcrypto.so
        +# alongside generic one, e.g. as /lib/highgprs/libcrypto.so.x.y, for
        +# ldconfig and run-time linker to autodiscover. Unfortunately it
        +# doesn't work just yet, because of couple of bugs in glibc
        +# sysdeps/s390/dl-procinfo.c affecting ldconfig and ld.so.1...
        +"linux32-s390x",	"gcc:-m31 -Wa,-mzarch -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$s390x_asm;$asm=~s/bn\-s390x\.o/bn_asm.o/;$asm}.":31:dlfcn:linux-shared:-fPIC:-m31:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/highgprs",
        +#### SPARC Linux setups
        +# Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
        +# assisted with debugging of following two configs.
        +"linux-sparcv8","gcc:-mv8 -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# it's a real mess with -mcpu=ultrasparc option under Linux, but
        +# -Wa,-Av8plus should do the trick no matter what.
        +"linux-sparcv9","gcc:-m32 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -Wa,-Av8plus -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# GCC 3.1 is a requirement
        +"linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
        +#### Alpha Linux with GNU C and Compaq C setups
        +# Special notes:
        +# - linux-alpha+bwx-gcc is ment to be used from ./config only. If you
        +#   ought to run './Configure linux-alpha+bwx-gcc' manually, do
        +#   complement the command line with -mcpu=ev56, -mcpu=ev6 or whatever
        +#   which is appropriate.
        +# - If you use ccc keep in mind that -fast implies -arch host and the
        +#   compiler is free to issue instructions which gonna make elder CPU
        +#   choke. If you wish to build "blended" toolkit, add -arch generic
        +#   *after* -fast and invoke './Configure linux-alpha-ccc' manually.
        +#
        +#					<appro@fy.chalmers.se>
        +#
        +"linux-alpha-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-alpha+bwx-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
        +"linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
        +
        +# Android: linux-* but without -DTERMIO and pointers to headers and libs.
        +"android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +#### *BSD [do see comment about ${BSDthreads} above!]
        +"BSD-generic32","gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"BSD-x86",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"BSD-x86-elf",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"debug-BSD-x86-elf",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall -g::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"BSD-sparcv8",	"gcc:-DB_ENDIAN -DTERMIOS -O3 -mv8 -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${sparcv8_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +"BSD-generic64","gcc:-DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
        +# simply *happens* to work around a compiler bug in gcc 3.3.3,
        +# triggered by RIPEMD160 code.
        +"BSD-sparc64",	"gcc:-DB_ENDIAN -DTERMIOS -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC2 BF_PTR:${sparcv9_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"BSD-ia64",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"BSD-x86_64",	"gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +"bsdi-elf-gcc",     "gcc:-DPERL5 -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall::(unknown)::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +"nextstep",	"cc:-O -Wall:<libc.h>:(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:::",
        +"nextstep3.3",	"cc:-O3 -Wall:<libc.h>:(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:::",
        +
        +# NCR MP-RAS UNIX ver 02.03.01
        +"ncr-scde","cc:-O6 -Xa -Hoff=BEHAVED -686 -Hwide -Hiw::(unknown)::-lsocket -lnsl -lc89:${x86_gcc_des} ${x86_gcc_opts}:::",
        +
        +# QNX
        +"qnx4",	"cc:-DL_ENDIAN -DTERMIO::(unknown):::${x86_gcc_des} ${x86_gcc_opts}:",
        +"QNX6",       "gcc:-DTERMIOS::::-lsocket::${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"QNX6-i386",  "gcc:-DL_ENDIAN -DTERMIOS -O2 -Wall::::-lsocket:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +# BeOS
        +"beos-x86-r5",   "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT:BEOS:-lbe -lnet:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:beos:beos-shared:-fPIC -DPIC:-shared:.so",
        +"beos-x86-bone", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT:BEOS:-lbe -lbind -lsocket:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:beos:beos-shared:-fPIC:-shared:.so",
        +
        +#### SCO/Caldera targets.
        +#
        +# Originally we had like unixware-*, unixware-*-pentium, unixware-*-p6, etc.
        +# Now we only have blended unixware-* as it's the only one used by ./config.
        +# If you want to optimize for particular microarchitecture, bypass ./config
        +# and './Configure unixware-7 -Kpentium_pro' or whatever appropriate.
        +# Note that not all targets include assembler support. Mostly because of
        +# lack of motivation to support out-of-date platforms with out-of-date
        +# compiler drivers and assemblers. Tim Rice <tim@multitalents.net> has
        +# patiently assisted to debug most of it.
        +#
        +# UnixWare 2.0x fails destest with -O.
        +"unixware-2.0","cc:-DFILIO_H -DNO_STRINGS_H::-Kthread::-lsocket -lnsl -lresolv -lx:${x86_gcc_des} ${x86_gcc_opts}:::",
        +"unixware-2.1","cc:-O -DFILIO_H::-Kthread::-lsocket -lnsl -lresolv -lx:${x86_gcc_des} ${x86_gcc_opts}:::",
        +"unixware-7","cc:-O -DFILIO_H -Kalloca::-Kthread::-lsocket -lnsl:BN_LLONG MD2_CHAR RC4_INDEX ${x86_gcc_des}:${x86_elf_asm}:dlfcn:svr5-shared:-Kpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"unixware-7-gcc","gcc:-DL_ENDIAN -DFILIO_H -O3 -fomit-frame-pointer -march=pentium -Wall::-D_REENTRANT::-lsocket -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:gnu-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +# SCO 5 - Ben Laurie <ben@algroup.co.uk> says the -O breaks the SCO cc.
        +"sco5-cc",  "cc:-belf::(unknown)::-lsocket -lnsl:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-Kpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"sco5-gcc",  "gcc:-O3 -fomit-frame-pointer::(unknown)::-lsocket -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +
        +#### IBM's AIX.
        +"aix3-cc",  "cc:-O -DB_ENDIAN -qmaxmem=16384::(unknown):AIX::BN_LLONG RC4_CHAR:::",
        +"aix-gcc",  "gcc:-O -DB_ENDIAN::-pthread:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X32",
        +"aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64",
        +# Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE
        +# at build time. $OBJECT_MODE is respected at ./config stage!
        +"aix-cc",   "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
        +"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
        +
        +#
        +# Cray T90 and similar (SDSC)
        +# It's Big-endian, but the algorithms work properly when B_ENDIAN is NOT
        +# defined.  The T90 ints and longs are 8 bytes long, and apparently the
        +# B_ENDIAN code assumes 4 byte ints.  Fortunately, the non-B_ENDIAN and
        +# non L_ENDIAN code aligns the bytes in each word correctly.
        +#
        +# The BIT_FIELD_LIMITS define is to avoid two fatal compiler errors:
        +#'Taking the address of a bit field is not allowed. '
        +#'An expression with bit field exists as the operand of "sizeof" '
        +# (written by Wayne Schroeder <schroede@SDSC.EDU>)
        +#
        +# j90 is considered the base machine type for unicos machines,
        +# so this configuration is now called "cray-j90" ...
        +"cray-j90", "cc: -DBIT_FIELD_LIMITS -DTERMIOS::(unknown):CRAY::SIXTY_FOUR_BIT_LONG DES_INT:::",
        +
        +#
        +# Cray T3E (Research Center Juelich, beckman@acl.lanl.gov)
        +#
        +# The BIT_FIELD_LIMITS define was written for the C90 (it seems).  I added
        +# another use.  Basically, the problem is that the T3E uses some bit fields
        +# for some st_addr stuff, and then sizeof and address-of fails
        +# I could not use the ams/alpha.o option because the Cray assembler, 'cam'
        +# did not like it.
        +"cray-t3e", "cc: -DBIT_FIELD_LIMITS -DTERMIOS::(unknown):CRAY::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:::",
        +
        +# DGUX, 88100.
        +"dgux-R3-gcc",	"gcc:-O3 -fomit-frame-pointer::(unknown):::RC4_INDEX DES_UNROLL:::",
        +"dgux-R4-gcc",	"gcc:-O3 -fomit-frame-pointer::(unknown)::-lnsl -lsocket:RC4_INDEX DES_UNROLL:::",
        +"dgux-R4-x86-gcc",	"gcc:-O3 -fomit-frame-pointer -DL_ENDIAN::(unknown)::-lnsl -lsocket:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
        +
        +# Sinix/ReliantUNIX RM400
        +# NOTE: The CDS++ Compiler up to V2.0Bsomething has the IRIX_CC_BUG optimizer problem. Better use -g  */
        +"ReliantUNIX","cc:-KPIC -g -DTERMIOS -DB_ENDIAN::-Kthread:SNI:-lsocket -lnsl -lc -L/usr/ucblib -lucb:BN_LLONG DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${no_asm}:dlfcn:reliantunix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
        +"SINIX","cc:-O::(unknown):SNI:-lsocket -lnsl -lc -L/usr/ucblib -lucb:RC4_INDEX RC4_CHAR:::",
        +"SINIX-N","/usr/ucb/cc:-O2 -misaligned::(unknown)::-lucb:RC4_INDEX RC4_CHAR:::",
        +
        +# SIEMENS BS2000/OSD: an EBCDIC-based mainframe
        +"BS2000-OSD","c89:-O -XLLML -XLLMK -XL -DB_ENDIAN -DTERMIOS -DCHARSET_EBCDIC::(unknown)::-lsocket -lnsl:THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
        +
        +# OS/390 Unix an EBCDIC-based Unix system on IBM mainframe
        +# You need to compile using the c89.sh wrapper in the tools directory, because the
        +# IBM compiler does not like the -L switch after any object modules.
        +#
        +"OS390-Unix","c89.sh:-O -DB_ENDIAN -DCHARSET_EBCDIC -DNO_SYS_PARAM_H  -D_ALL_SOURCE::(unknown):::THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
        +
        +# Visual C targets
        +#
        +# Win64 targets, WIN64I denotes IA-64 and WIN64A - AMD64
        +"VC-WIN64I","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ghash-ia64.o::ias:win32",
        +"VC-WIN64A","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:".eval{my $asm=$x86_64_asm;$asm=~s/x86_64-gcc\.o/bn_asm.o/;$asm}.":auto:win32",
        +"debug-VC-WIN64I","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ghash-ia64.o::ias:win32",
        +"debug-VC-WIN64A","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:".eval{my $asm=$x86_64_asm;$asm=~s/x86_64-gcc\.o/bn_asm.o/;$asm}.":auto:win32",
        +# x86 Win32 target defaults to ANSI API, if you want UNICODE, complement
        +# 'perl Configure VC-WIN32' with '-DUNICODE -D_UNICODE'
        +"VC-WIN32","cl:-W3 -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
        +# Unified CE target
        +"debug-VC-WIN32","cl:-W3 -WX -Gs0 -GF -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
        +"VC-CE","cl::::WINCE::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${no_asm}:win32",
        +
        +# Borland C++ 4.5
        +"BC-32","bcc32::::WIN32::BN_LLONG DES_PTR RC4_INDEX EXPORT_VAR_AS_FN:${no_asm}:win32",
        +
        +# MinGW
        +"mingw", "gcc:-mno-cygwin -DL_ENDIAN -DWIN32_LEAN_AND_MEAN -fomit-frame-pointer -O3 -march=i486 -Wall::-D_MT:MINGW32:-lws2_32 -lgdi32 -lcrypt32:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts} EXPORT_VAR_AS_FN:${x86_asm}:coff:win32:cygwin-shared:-D_WINDLL -DOPENSSL_USE_APPLINK:-mno-cygwin:.dll.a",
        +# As for OPENSSL_USE_APPLINK. Applink makes it possible to use .dll
        +# compiled with one compiler with application compiled with another
        +# compiler. It's possible to engage Applink support in mingw64 build,
        +# but it's not done, because till mingw64 supports structured exception
        +# handling, one can't seriously consider its binaries for using with
        +# non-mingw64 run-time environment. And as mingw64 is always consistent
        +# with itself, Applink is never engaged and can as well be omitted.
        +"mingw64", "gcc:-mno-cygwin -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE::-D_MT:MINGW64:-lws2_32 -lgdi32 -lcrypt32:SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:${x86_64_asm}:mingw64:win32:cygwin-shared:-D_WINDLL:-mno-cygwin:.dll.a",
        +
        +# UWIN 
        +"UWIN", "cc:-DTERMIOS -DL_ENDIAN -O -Wall:::UWIN::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32",
        +
        +# Cygwin
        +"Cygwin-pre1.3", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::(unknown):CYGWIN32::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32",
        +"Cygwin", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall:::CYGWIN32::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:coff:dlfcn:cygwin-shared:-D_WINDLL:-shared:.dll.a",
        +"debug-Cygwin", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror:::CYGWIN32:::${no_asm}:dlfcn:cygwin-shared:-D_WINDLL:-shared:.dll.a",
        +
        +# NetWare from David Ward (dsward@novell.com)
        +# requires either MetroWerks NLM development tools, or gcc / nlmconv
        +# NetWare defaults socket bio to WinSock sockets. However,
        +# the builds can be configured to use BSD sockets instead.
        +# netware-clib => legacy CLib c-runtime support
        +"netware-clib", "mwccnlm::::::${x86_gcc_opts}::",
        +"netware-clib-bsdsock", "mwccnlm::::::${x86_gcc_opts}::",
        +"netware-clib-gcc", "i586-netware-gcc:-nostdinc -I/ndk/nwsdk/include/nlm -I/ndk/ws295sdk/include -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYSNAME_NETWARE -O2 -Wall:::::${x86_gcc_opts}::",
        +"netware-clib-bsdsock-gcc", "i586-netware-gcc:-nostdinc -I/ndk/nwsdk/include/nlm -DNETWARE_BSDSOCK -DNETDB_USE_INTERNET -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYSNAME_NETWARE -O2 -Wall:::::${x86_gcc_opts}::",
        +# netware-libc => LibC/NKS support
        +"netware-libc", "mwccnlm::::::BN_LLONG ${x86_gcc_opts}::",
        +"netware-libc-bsdsock", "mwccnlm::::::BN_LLONG ${x86_gcc_opts}::",
        +"netware-libc-gcc", "i586-netware-gcc:-nostdinc -I/ndk/libc/include -I/ndk/libc/include/winsock -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYSNAME_NETWARE -DTERMIO -O2 -Wall:::::BN_LLONG ${x86_gcc_opts}::",
        +"netware-libc-bsdsock-gcc", "i586-netware-gcc:-nostdinc -I/ndk/libc/include -DNETWARE_BSDSOCK -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYSNAME_NETWARE -DTERMIO -O2 -Wall:::::BN_LLONG ${x86_gcc_opts}::",
        +
        +# DJGPP
        +"DJGPP", "gcc:-I/dev/env/WATT_ROOT/inc -DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O2 -Wall:::MSDOS:-L/dev/env/WATT_ROOT/lib -lwatt:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:",
        +
        +# Ultrix from Bernhard Simon <simon@zid.tuwien.ac.at>
        +"ultrix-cc","cc:-std1 -O -Olimit 2500 -DL_ENDIAN::(unknown):::::::",
        +"ultrix-gcc","gcc:-O3 -DL_ENDIAN::(unknown):::BN_LLONG::::",
        +# K&R C is no longer supported; you need gcc on old Ultrix installations
        +##"ultrix","cc:-O2 -DNOPROTO -DNOCONST -DL_ENDIAN::(unknown):::::::",
        +
        +##### MacOS X (a.k.a. Rhapsody or Darwin) setup
        +"rhapsody-ppc-cc","cc:-O3 -DB_ENDIAN::(unknown):MACOSX_RHAPSODY::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}::",
        +"darwin-ppc-cc","cc:-arch ppc -O3 -DB_ENDIAN -Wa,-force_cpusubtype_ALL::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +# iPhoneOS/iOS
        +"iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
        +
        +##### A/UX
        +"aux3-gcc","gcc:-O2 -DTERMIO::(unknown):AUX:-lbsd:RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::",
        +
        +##### Sony NEWS-OS 4.x
        +"newsos4-gcc","gcc:-O -DB_ENDIAN::(unknown):NEWS4:-lmld -liberty:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::",
        +
        +##### GNU Hurd
        +"hurd-x86",  "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC",
        +
        +##### OS/2 EMX
        +"OS2-EMX", "gcc::::::::",
        +
        +##### VxWorks for various targets
        +"vxworks-ppc60x","ccppc:-D_REENTRANT -mrtp -mhard-float -mstrict-align -fno-implicit-fp -DPPC32_fp60x -O2 -fstrength-reduce -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common:::::",
        +"vxworks-ppcgen","ccppc:-D_REENTRANT -mrtp -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon:::::",
        +"vxworks-ppc405","ccppc:-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
        +"vxworks-ppc750","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG):::VXWORKS:-r:::::",
        +"vxworks-ppc750-debug","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG -g:::VXWORKS:-r:::::",
        +"vxworks-ppc860","ccppc:-nostdinc -msoft-float -DCPU=PPC860 -DNO_STRINGS_H -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
        +"vxworks-simlinux","ccpentium:-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DL_ENDIAN -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/h -I\$(WIND_BASE)/target/h/wrn/coreip -DOPENSSL_NO_HW_PADLOCK:::VXWORKS:-r::${no_asm}::::::ranlibpentium:",
        +"vxworks-mips","ccmips:-mrtp -mips2 -O -G 0 -B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DCPU=MIPS32 -msoft-float -mno-branch-likely -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/h/wrn/coreip::-D_REENTRANT:VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/mips/MIPSI32/sfcommon::${mips32_asm}:o32::::::ranlibmips:",
        +
        +##### Compaq Non-Stop Kernel (Tandem)
        +"tandem-c89","c89:-Ww -D__TANDEM -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D_TANDEM_SOURCE -DB_ENDIAN::(unknown):::THIRTY_TWO_BIT:::",
        +
        +# uClinux
        +"uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
        +"uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
        +
        +);
        +
        +my @MK1MF_Builds=qw(VC-WIN64I VC-WIN64A
        +		    debug-VC-WIN64I debug-VC-WIN64A
        +		    VC-NT VC-CE VC-WIN32 debug-VC-WIN32
        +		    BC-32 
        +		    netware-clib netware-clib-bsdsock
        +		    netware-libc netware-libc-bsdsock);
        +
        +my $idx = 0;
        +my $idx_cc = $idx++;
        +my $idx_cflags = $idx++;
        +my $idx_unistd = $idx++;
        +my $idx_thread_cflag = $idx++;
        +my $idx_sys_id = $idx++;
        +my $idx_lflags = $idx++;
        +my $idx_bn_ops = $idx++;
        +my $idx_cpuid_obj = $idx++;
        +my $idx_bn_obj = $idx++;
        +my $idx_des_obj = $idx++;
        +my $idx_aes_obj = $idx++;
        +my $idx_bf_obj = $idx++;
        +my $idx_md5_obj = $idx++;
        +my $idx_sha1_obj = $idx++;
        +my $idx_cast_obj = $idx++;
        +my $idx_rc4_obj = $idx++;
        +my $idx_rmd160_obj = $idx++;
        +my $idx_rc5_obj = $idx++;
        +my $idx_wp_obj = $idx++;
        +my $idx_cmll_obj = $idx++;
        +my $idx_modes_obj = $idx++;
        +my $idx_engines_obj = $idx++;
        +my $idx_perlasm_scheme = $idx++;
        +my $idx_dso_scheme = $idx++;
        +my $idx_shared_target = $idx++;
        +my $idx_shared_cflag = $idx++;
        +my $idx_shared_ldflag = $idx++;
        +my $idx_shared_extension = $idx++;
        +my $idx_ranlib = $idx++;
        +my $idx_arflags = $idx++;
        +my $idx_multilib = $idx++;
        +
        +my $prefix="";
        +my $libdir="";
        +my $openssldir="";
        +my $exe_ext="";
        +my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
        +my $cross_compile_prefix="";
        +my $fipsdir="/usr/local/ssl/fips-2.0";
        +my $fipslibdir="";
        +my $baseaddr="0xFB00000";
        +my $no_threads=0;
        +my $threads=0;
        +my $no_shared=0; # but "no-shared" is default
        +my $zlib=1;      # but "no-zlib" is default
        +my $no_krb5=0;   # but "no-krb5" is implied unless "--with-krb5-..." is used
        +my $no_rfc3779=1; # but "no-rfc3779" is default
        +my $no_asm=0;
        +my $no_dso=0;
        +my $no_gmp=0;
        +my @skip=();
        +my $Makefile="Makefile";
        +my $des_locl="crypto/des/des_locl.h";
        +my $des	="crypto/des/des.h";
        +my $bn	="crypto/bn/bn.h";
        +my $md2	="crypto/md2/md2.h";
        +my $rc4	="crypto/rc4/rc4.h";
        +my $rc4_locl="crypto/rc4/rc4_locl.h";
        +my $idea	="crypto/idea/idea.h";
        +my $rc2	="crypto/rc2/rc2.h";
        +my $bf	="crypto/bf/bf_locl.h";
        +my $bn_asm	="bn_asm.o";
        +my $des_enc="des_enc.o fcrypt_b.o";
        +my $aes_enc="aes_core.o aes_cbc.o";
        +my $bf_enc	="bf_enc.o";
        +my $cast_enc="c_enc.o";
        +my $rc4_enc="rc4_enc.o rc4_skey.o";
        +my $rc5_enc="rc5_enc.o";
        +my $md5_obj="";
        +my $sha1_obj="";
        +my $rmd160_obj="";
        +my $cmll_enc="camellia.o cmll_misc.o cmll_cbc.o";
        +my $processor="";
        +my $default_ranlib;
        +my $perl;
        +my $fips=0;
        +
        +if (exists $ENV{FIPSDIR})
        +	{
        +	$fipsdir = $ENV{FIPSDIR};
        +	$fipsdir =~ s/\/$//;
        +	}
        +
        +# All of the following is disabled by default (RC5 was enabled before 0.9.8):
        +
        +my %disabled = ( # "what"         => "comment" [or special keyword "experimental"]
        +		 "ec_nistp_64_gcc_128" => "default",
        +		 "gmp"		  => "default",
        +		 "jpake"          => "experimental",
        +		 "md2"            => "default",
        +		 "rc5"            => "default",
        +		 "rfc3779"	  => "default",
        +		 "sctp"       => "default",
        +		 "shared"         => "default",
        +		 "store"	  => "experimental",
        +		 "zlib"           => "default",
        +		 "zlib-dynamic"   => "default"
        +	       );
        +my @experimental = ();
        +
        +# This is what $depflags will look like with the above defaults
        +# (we need this to see if we should advise the user to run "make depend"):
        +my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE";
        +
        +# Explicit "no-..." options will be collected in %disabled along with the defaults.
        +# To remove something from %disabled, use "enable-foo" (unless it's experimental).
        +# For symmetry, "disable-foo" is a synonym for "no-foo".
        +
        +# For features called "experimental" here, a more explicit "experimental-foo" is needed to enable.
        +# We will collect such requests in @experimental.
        +# To avoid accidental use of experimental features, applications will have to use -DOPENSSL_EXPERIMENTAL_FOO.
        +
        +
        +my $no_sse2=0;
        +
        +&usage if ($#ARGV < 0);
        +
        +my $flags;
        +my $depflags;
        +my $openssl_experimental_defines;
        +my $openssl_algorithm_defines;
        +my $openssl_thread_defines;
        +my $openssl_sys_defines="";
        +my $openssl_other_defines;
        +my $libs;
        +my $libkrb5="";
        +my $target;
        +my $options;
        +my $symlink;
        +my $make_depend=0;
        +my %withargs=();
        +
        +my @argvcopy=@ARGV;
        +my $argvstring="";
        +my $argv_unprocessed=1;
        +
        +while($argv_unprocessed)
        +	{
        +	$flags="";
        +	$depflags="";
        +	$openssl_experimental_defines="";
        +	$openssl_algorithm_defines="";
        +	$openssl_thread_defines="";
        +	$openssl_sys_defines="";
        +	$openssl_other_defines="";
        +	$libs="";
        +	$target="";
        +	$options="";
        +	$symlink=1;
        +
        +	$argv_unprocessed=0;
        +	$argvstring=join(' ',@argvcopy);
        +
        +PROCESS_ARGS:
        +	foreach (@argvcopy)
        +		{
        +		s /^-no-/no-/; # some people just can't read the instructions
        +
        +		# rewrite some options in "enable-..." form
        +		s /^-?-?shared$/enable-shared/;
        +		s /^sctp$/enable-sctp/;
        +		s /^threads$/enable-threads/;
        +		s /^zlib$/enable-zlib/;
        +		s /^zlib-dynamic$/enable-zlib-dynamic/;
        +
        +		if (/^no-(.+)$/ || /^disable-(.+)$/)
        +			{
        +			if (!($disabled{$1} eq "experimental"))
        +				{
        +				if ($1 eq "ssl")
        +					{
        +					$disabled{"ssl2"} = "option(ssl)";
        +					$disabled{"ssl3"} = "option(ssl)";
        +					}
        +				elsif ($1 eq "tls")
        +					{
        +					$disabled{"tls1"} = "option(tls)"
        +					}
        +				else
        +					{
        +					$disabled{$1} = "option";
        +					}
        +				}			
        +			}
        +		elsif (/^enable-(.+)$/ || /^experimental-(.+)$/)
        +			{
        +			my $algo = $1;
        +			if ($disabled{$algo} eq "experimental")
        +				{
        +				die "You are requesting an experimental feature; please say 'experimental-$algo' if you are sure\n"
        +					unless (/^experimental-/);
        +				push @experimental, $algo;
        +				}
        +			delete $disabled{$algo};
        +
        +			$threads = 1 if ($algo eq "threads");
        +			}
        +		elsif (/^--test-sanity$/)
        +			{
        +			exit(&test_sanity());
        +			}
        +		elsif (/^--strict-warnings/)
        +			{
        +			$strict_warnings = 1;
        +			}
        +		elsif (/^reconfigure/ || /^reconf/)
        +			{
        +			if (open(IN,"<$Makefile"))
        +				{
        +				while (<IN>)
        +					{
        +					chomp;
        +					if (/^CONFIGURE_ARGS=(.*)/)
        +						{
        +						$argvstring=$1;
        +						@argvcopy=split(' ',$argvstring);
        +						die "Incorrect data to reconfigure, please do a normal configuration\n"
        +							if (grep(/^reconf/,@argvcopy));
        +						print "Reconfiguring with: $argvstring\n";
        +						$argv_unprocessed=1;
        +						close(IN);
        +						last PROCESS_ARGS;
        +						}
        +					}
        +				close(IN);
        +				}
        +			die "Insufficient data to reconfigure, please do a normal configuration\n";
        +			}
        +		elsif (/^386$/)
        +			{ $processor=386; }
        +		elsif (/^fips$/)
        +			{
        +			$fips=1;
        +			}
        +		elsif (/^rsaref$/)
        +			{
        +			# No RSAref support any more since it's not needed.
        +			# The check for the option is there so scripts aren't
        +			# broken
        +			}
        +		elsif (/^[-+]/)
        +			{
        +			if (/^-[lL](.*)$/ or /^-Wl,/)
        +				{
        +				$libs.=$_." ";
        +				}
        +			elsif (/^-[^-]/ or /^\+/)
        +				{
        +				$_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
        +				$flags.=$_." ";
        +				}
        +			elsif (/^--prefix=(.*)$/)
        +				{
        +				$prefix=$1;
        +				}
        +			elsif (/^--libdir=(.*)$/)
        +				{
        +				$libdir=$1;
        +				}
        +			elsif (/^--openssldir=(.*)$/)
        +				{
        +				$openssldir=$1;
        +				}
        +			elsif (/^--install.prefix=(.*)$/)
        +				{
        +				$install_prefix=$1;
        +				}
        +			elsif (/^--with-krb5-(dir|lib|include|flavor)=(.*)$/)
        +				{
        +				$withargs{"krb5-".$1}=$2;
        +				}
        +			elsif (/^--with-zlib-lib=(.*)$/)
        +				{
        +				$withargs{"zlib-lib"}=$1;
        +				}
        +			elsif (/^--with-zlib-include=(.*)$/)
        +				{
        +				$withargs{"zlib-include"}="-I$1";
        +				}
        +			elsif (/^--with-fipsdir=(.*)$/)
        +				{
        +				$fipsdir="$1";
        +				}
        +			elsif (/^--with-fipslibdir=(.*)$/)
        +				{
        +				$fipslibdir="$1";
        +				}
        +			elsif (/^--with-baseaddr=(.*)$/)
        +				{
        +				$baseaddr="$1";
        +				}
        +			elsif (/^--cross-compile-prefix=(.*)$/)
        +				{
        +				$cross_compile_prefix=$1;
        +				}
        +			else
        +				{
        +				print STDERR $usage;
        +				exit(1);
        +				}
        +			}
        +		elsif ($_ =~ /^([^:]+):(.+)$/)
        +			{
        +			eval "\$table{\$1} = \"$2\""; # allow $xxx constructs in the string
        +			$target=$1;
        +			}
        +		else
        +			{
        +			die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
        +			$target=$_;
        +			}
        +
        +		unless ($_ eq $target || /^no-/ || /^disable-/)
        +			{
        +			# "no-..." follows later after implied disactivations
        +			# have been derived.  (Don't take this too seroiusly,
        +			# we really only write OPTIONS to the Makefile out of
        +			# nostalgia.)
        +
        +			if ($options eq "")
        +				{ $options = $_; }
        +			else
        +				{ $options .= " ".$_; }
        +			}
        +		}
        +	}
        +
        +
        +
        +if ($processor eq "386")
        +	{
        +	$disabled{"sse2"} = "forced";
        +	}
        +
        +if (!defined($withargs{"krb5-flavor"}) || $withargs{"krb5-flavor"} eq "")
        +	{
        +	$disabled{"krb5"} = "krb5-flavor not specified";
        +	}
        +
        +if (!defined($disabled{"zlib-dynamic"}))
        +	{
        +	# "zlib-dynamic" was specifically enabled, so enable "zlib"
        +	delete $disabled{"zlib"};
        +	}
        +
        +if (defined($disabled{"rijndael"}))
        +	{
        +	$disabled{"aes"} = "forced";
        +	}
        +if (defined($disabled{"des"}))
        +	{
        +	$disabled{"mdc2"} = "forced";
        +	}
        +if (defined($disabled{"ec"}))
        +	{
        +	$disabled{"ecdsa"} = "forced";
        +	$disabled{"ecdh"} = "forced";
        +	}
        +
        +# SSL 2.0 requires MD5 and RSA
        +if (defined($disabled{"md5"}) || defined($disabled{"rsa"}))
        +	{
        +	$disabled{"ssl2"} = "forced";
        +	}
        +
        +if ($fips && $fipslibdir eq "")
        +	{
        +	$fipslibdir = $fipsdir . "/lib/";
        +	}
        +
        +# RSAX ENGINE sets default non-FIPS RSA method.
        +if ($fips)
        +	{
        +	$disabled{"rsax"} = "forced";
        +	}
        +
        +# SSL 3.0 and TLS requires MD5 and SHA and either RSA or DSA+DH
        +if (defined($disabled{"md5"}) || defined($disabled{"sha"})
        +    || (defined($disabled{"rsa"})
        +        && (defined($disabled{"dsa"}) || defined($disabled{"dh"}))))
        +	{
        +	$disabled{"ssl3"} = "forced";
        +	$disabled{"tls1"} = "forced";
        +	}
        +
        +if (defined($disabled{"tls1"}))
        +	{
        +	$disabled{"tlsext"} = "forced";
        +	}
        +
        +if (defined($disabled{"ec"}) || defined($disabled{"dsa"})
        +    || defined($disabled{"dh"}))
        +	{
        +	$disabled{"gost"} = "forced";
        +	}
        +
        +# SRP and HEARTBEATS require TLSEXT
        +if (defined($disabled{"tlsext"}))
        +	{
        +	$disabled{"srp"} = "forced";
        +	$disabled{"heartbeats"} = "forced";
        +	}
        +
        +if ($target eq "TABLE") {
        +	foreach $target (sort keys %table) {
        +		print_table_entry($target);
        +	}
        +	exit 0;
        +}
        +
        +if ($target eq "LIST") {
        +	foreach (sort keys %table) {
        +		print;
        +		print "\n";
        +	}
        +	exit 0;
        +}
        +
        +if ($target =~ m/^CygWin32(-.*)$/) {
        +	$target = "Cygwin".$1;
        +}
        +
        +print "Configuring for $target\n";
        +
        +&usage if (!defined($table{$target}));
        +
        +
        +foreach (sort (keys %disabled))
        +	{
        +	$options .= " no-$_";
        +
        +	printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
        +
        +	if (/^dso$/)
        +		{ $no_dso = 1; }
        +	elsif (/^threads$/)
        +		{ $no_threads = 1; }
        +	elsif (/^shared$/)
        +		{ $no_shared = 1; }
        +	elsif (/^zlib$/)
        +		{ $zlib = 0; }
        +	elsif (/^static-engine$/)
        +		{ }
        +	elsif (/^zlib-dynamic$/)
        +		{ }
        +	elsif (/^symlinks$/)
        +		{ $symlink = 0; }
        +	elsif (/^sse2$/)
        +		{ $no_sse2 = 1; }
        +	else
        +		{
        +		my ($ALGO, $algo);
        +		($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
        +
        +		if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/)
        +			{
        +			$openssl_other_defines .= "#define OPENSSL_NO_$ALGO\n";
        +			print " OPENSSL_NO_$ALGO";
        +		
        +			if (/^err$/)	{ $flags .= "-DOPENSSL_NO_ERR "; }
        +			elsif (/^asm$/)	{ $no_asm = 1; }
        +			}
        +		else
        +			{
        +			$openssl_algorithm_defines .= "#define OPENSSL_NO_$ALGO\n";
        +			print " OPENSSL_NO_$ALGO";
        +
        +			if (/^krb5$/)
        +				{ $no_krb5 = 1; }
        +			else
        +				{
        +				push @skip, $algo;
        +				# fix-up crypto/directory name(s)
        +				@skip[$#skip]="whrlpool" if $algo eq "whirlpool";
        +				print " (skip dir)";
        +
        +				$depflags .= " -DOPENSSL_NO_$ALGO";
        +				}
        +			}
        +		}
        +
        +	print "\n";
        +	}
        +
        +my $exp_cflags = "";
        +foreach (sort @experimental)
        +	{
        +	my $ALGO;
        +	($ALGO = $_) =~ tr/[a-z]/[A-Z]/;
        +
        +	# opensslconf.h will set OPENSSL_NO_... unless OPENSSL_EXPERIMENTAL_... is defined
        +	$openssl_experimental_defines .= "#define OPENSSL_NO_$ALGO\n";
        +	$exp_cflags .= " -DOPENSSL_EXPERIMENTAL_$ALGO";
        +	}
        +
        +my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
        +
        +$exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
        +$exe_ext=".nlm" if ($target =~ /netware/);
        +$exe_ext=".pm"  if ($target =~ /vos/);
        +$openssldir="/usr/local/ssl" if ($openssldir eq "" and $prefix eq "");
        +$prefix=$openssldir if $prefix eq "";
        +
        +$default_ranlib= &which("ranlib") or $default_ranlib="true";
        +$perl=$ENV{'PERL'} or $perl=&which("perl5") or $perl=&which("perl")
        +  or $perl="perl";
        +my $make = $ENV{'MAKE'} || "make";
        +
        +$cross_compile_prefix=$ENV{'CROSS_COMPILE'} if $cross_compile_prefix eq "";
        +
        +chop $openssldir if $openssldir =~ /\/$/;
        +chop $prefix if $prefix =~ /.\/$/;
        +
        +$openssldir=$prefix . "/ssl" if $openssldir eq "";
        +$openssldir=$prefix . "/" . $openssldir if $openssldir !~ /(^\/|^[a-zA-Z]:[\\\/])/;
        +
        +
        +print "IsMK1MF=$IsMK1MF\n";
        +
        +my @fields = split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
        +my $cc = $fields[$idx_cc];
        +# Allow environment CC to override compiler...
        +if($ENV{CC}) {
        +    $cc = $ENV{CC};
        +}
        +my $cflags = $fields[$idx_cflags];
        +my $unistd = $fields[$idx_unistd];
        +my $thread_cflag = $fields[$idx_thread_cflag];
        +my $sys_id = $fields[$idx_sys_id];
        +my $lflags = $fields[$idx_lflags];
        +my $bn_ops = $fields[$idx_bn_ops];
        +my $cpuid_obj = $fields[$idx_cpuid_obj];
        +my $bn_obj = $fields[$idx_bn_obj];
        +my $des_obj = $fields[$idx_des_obj];
        +my $aes_obj = $fields[$idx_aes_obj];
        +my $bf_obj = $fields[$idx_bf_obj];
        +my $md5_obj = $fields[$idx_md5_obj];
        +my $sha1_obj = $fields[$idx_sha1_obj];
        +my $cast_obj = $fields[$idx_cast_obj];
        +my $rc4_obj = $fields[$idx_rc4_obj];
        +my $rmd160_obj = $fields[$idx_rmd160_obj];
        +my $rc5_obj = $fields[$idx_rc5_obj];
        +my $wp_obj = $fields[$idx_wp_obj];
        +my $cmll_obj = $fields[$idx_cmll_obj];
        +my $modes_obj = $fields[$idx_modes_obj];
        +my $engines_obj = $fields[$idx_engines_obj];
        +my $perlasm_scheme = $fields[$idx_perlasm_scheme];
        +my $dso_scheme = $fields[$idx_dso_scheme];
        +my $shared_target = $fields[$idx_shared_target];
        +my $shared_cflag = $fields[$idx_shared_cflag];
        +my $shared_ldflag = $fields[$idx_shared_ldflag];
        +my $shared_extension = $fields[$idx_shared_extension];
        +my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib];
        +my $ar = $ENV{'AR'} || "ar";
        +my $arflags = $fields[$idx_arflags];
        +my $multilib = $fields[$idx_multilib];
        +
        +# if $prefix/lib$multilib is not an existing directory, then
        +# assume that it's not searched by linker automatically, in
        +# which case adding $multilib suffix causes more grief than
        +# we're ready to tolerate, so don't...
        +$multilib="" if !-d "$prefix/lib$multilib";
        +
        +$libdir="lib$multilib" if $libdir eq "";
        +
        +$cflags = "$cflags$exp_cflags";
        +
        +# '%' in $lflags is used to split flags to "pre-" and post-flags
        +my ($prelflags,$postlflags)=split('%',$lflags);
        +if (defined($postlflags))	{ $lflags=$postlflags;	}
        +else				{ $lflags=$prelflags; undef $prelflags;	}
        +
        +if ($target =~ /^mingw/ && `$cc --target-help 2>&1` !~ m/\-mno\-cygwin/m)
        +	{
        +	$cflags =~ s/\-mno\-cygwin\s*//;
        +	$shared_ldflag =~ s/\-mno\-cygwin\s*//;
        +	}
        +
        +my $no_shared_warn=0;
        +my $no_user_cflags=0;
        +
        +if ($flags ne "")	{ $cflags="$flags$cflags"; }
        +else			{ $no_user_cflags=1;       }
        +
        +# Kerberos settings.  The flavor must be provided from outside, either through
        +# the script "config" or manually.
        +if (!$no_krb5)
        +	{
        +	my ($lresolv, $lpath, $lext);
        +	if ($withargs{"krb5-flavor"} =~ /^[Hh]eimdal$/)
        +		{
        +		die "Sorry, Heimdal is currently not supported\n";
        +		}
        +	##### HACK to force use of Heimdal.
        +	##### WARNING: Since we don't really have adequate support for Heimdal,
        +	#####          using this will break the build.  You'll have to make
        +	#####          changes to the source, and if you do, please send
        +	#####          patches to openssl-dev@openssl.org
        +	if ($withargs{"krb5-flavor"} =~ /^force-[Hh]eimdal$/)
        +		{
        +		warn "Heimdal isn't really supported.  Your build WILL break\n";
        +		warn "If you fix the problems, please send a patch to openssl-dev\@openssl.org\n";
        +		$withargs{"krb5-dir"} = "/usr/heimdal"
        +			if $withargs{"krb5-dir"} eq "";
        +		$withargs{"krb5-lib"} = "-L".$withargs{"krb5-dir"}.
        +			"/lib -lgssapi -lkrb5 -lcom_err"
        +			if $withargs{"krb5-lib"} eq "" && !$IsMK1MF;
        +		$cflags="-DKRB5_HEIMDAL $cflags";
        +		}
        +	if ($withargs{"krb5-flavor"} =~ /^[Mm][Ii][Tt]/)
        +		{
        +		$withargs{"krb5-dir"} = "/usr/kerberos"
        +			if $withargs{"krb5-dir"} eq "";
        +		$withargs{"krb5-lib"} = "-L".$withargs{"krb5-dir"}.
        +			"/lib -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto"
        +			if $withargs{"krb5-lib"} eq "" && !$IsMK1MF;
        +		$cflags="-DKRB5_MIT $cflags";
        +		$withargs{"krb5-flavor"} =~ s/^[Mm][Ii][Tt][._-]*//;
        +		if ($withargs{"krb5-flavor"} =~ /^1[._-]*[01]/)
        +			{
        +			$cflags="-DKRB5_MIT_OLD11 $cflags";
        +			}
        +		}
        +	LRESOLV:
        +	foreach $lpath ("/lib", "/usr/lib")
        +		{
        +		foreach $lext ("a", "so")
        +			{
        +			$lresolv = "$lpath/libresolv.$lext";
        +			last LRESOLV	if (-r "$lresolv");
        +			$lresolv = "";
        +			}
        +		}
        +	$withargs{"krb5-lib"} .= " -lresolv"
        +		if ("$lresolv" ne "");
        +	$withargs{"krb5-include"} = "-I".$withargs{"krb5-dir"}."/include"
        +		if $withargs{"krb5-include"} eq "" &&
        +		   $withargs{"krb5-dir"} ne "";
        +	}
        +
        +# The DSO code currently always implements all functions so that no
        +# applications will have to worry about that from a compilation point
        +# of view. However, the "method"s may return zero unless that platform
        +# has support compiled in for them. Currently each method is enabled
        +# by a define "DSO_<name>" ... we translate the "dso_scheme" config
        +# string entry into using the following logic;
        +my $dso_cflags;
        +if (!$no_dso && $dso_scheme ne "")
        +	{
        +	$dso_scheme =~ tr/[a-z]/[A-Z]/;
        +	if ($dso_scheme eq "DLFCN")
        +		{
        +		$dso_cflags = "-DDSO_DLFCN -DHAVE_DLFCN_H";
        +		}
        +	elsif ($dso_scheme eq "DLFCN_NO_H")
        +		{
        +		$dso_cflags = "-DDSO_DLFCN";
        +		}
        +	else
        +		{
        +		$dso_cflags = "-DDSO_$dso_scheme";
        +		}
        +	$cflags = "$dso_cflags $cflags";
        +	}
        +
        +my $thread_cflags;
        +my $thread_defines;
        +if ($thread_cflag ne "(unknown)" && !$no_threads)
        +	{
        +	# If we know how to do it, support threads by default.
        +	$threads = 1;
        +	}
        +if ($thread_cflag eq "(unknown)" && $threads)
        +	{
        +	# If the user asked for "threads", [s]he is also expected to
        +	# provide any system-dependent compiler options that are
        +	# necessary.
        +	if ($no_user_cflags)
        +		{
        +		print "You asked for multi-threading support, but didn't\n";
        +		print "provide any system-specific compiler options\n";
        +		exit(1);
        +		}
        +	$thread_cflags="-DOPENSSL_THREADS $cflags" ;
        +	$thread_defines .= "#define OPENSSL_THREADS\n";
        +	}
        +else
        +	{
        +	$thread_cflags="-DOPENSSL_THREADS $thread_cflag $cflags";
        +	$thread_defines .= "#define OPENSSL_THREADS\n";
        +#	my $def;
        +#	foreach $def (split ' ',$thread_cflag)
        +#		{
        +#		if ($def =~ s/^-D// && $def !~ /^_/)
        +#			{
        +#			$thread_defines .= "#define $def\n";
        +#			}
        +#		}
        +	}	
        +
        +$lflags="$libs$lflags" if ($libs ne "");
        +
        +if ($no_asm)
        +	{
        +	$cpuid_obj=$bn_obj=
        +	$des_obj=$aes_obj=$bf_obj=$cast_obj=$rc4_obj=$rc5_obj=$cmll_obj=
        +	$modes_obj=$sha1_obj=$md5_obj=$rmd160_obj=$wp_obj=$engines_obj="";
        +	}
        +
        +if (!$no_shared)
        +	{
        +	$cast_obj="";	# CAST assembler is not PIC
        +	}
        +
        +if ($threads)
        +	{
        +	$cflags=$thread_cflags;
        +	$openssl_thread_defines .= $thread_defines;
        +	}
        +
        +if ($zlib)
        +	{
        +	$cflags = "-DZLIB $cflags";
        +	if (defined($disabled{"zlib-dynamic"}))
        +		{
        +		if (defined($withargs{"zlib-lib"}))
        +			{
        +			$lflags = "$lflags -L" . $withargs{"zlib-lib"} . " -lz";
        +			}
        +		else
        +			{
        +			$lflags = "$lflags -lz";
        +			}
        +		}
        +	else
        +		{
        +		$cflags = "-DZLIB_SHARED $cflags";
        +		}
        +	}
        +
        +# You will find shlib_mark1 and shlib_mark2 explained in Makefile.org
        +my $shared_mark = "";
        +if ($shared_target eq "")
        +	{
        +	$no_shared_warn = 1 if !$no_shared;
        +	$no_shared = 1;
        +	}
        +if (!$no_shared)
        +	{
        +	if ($shared_cflag ne "")
        +		{
        +		$cflags = "$shared_cflag -DOPENSSL_PIC $cflags";
        +		}
        +	}
        +
        +if (!$IsMK1MF)
        +	{
        +	# add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
        +	if ($no_shared)
        +		{
        +		$openssl_other_defines.="#define OPENSSL_NO_DYNAMIC_ENGINE\n";
        +		$options.=" static-engine";
        +		}
        +	else
        +		{
        +		$openssl_other_defines.="#define OPENSSL_NO_STATIC_ENGINE\n";
        +		$options.=" no-static-engine";
        +		}
        +	}
        +
        +$cpuid_obj.=" uplink.o uplink-x86.o" if ($cflags =~ /\-DOPENSSL_USE_APPLINK/);
        +
        +#
        +# Platform fix-ups
        +#
        +if ($target =~ /\-icc$/)	# Intel C compiler
        +	{
        +	my $iccver=0;
        +	if (open(FD,"$cc -V 2>&1 |"))
        +		{
        +		while(<FD>) { $iccver=$1 if (/Version ([0-9]+)\./); }
        +		close(FD);
        +		}
        +	if ($iccver>=8)
        +		{
        +		# Eliminate unnecessary dependency from libirc.a. This is
        +		# essential for shared library support, as otherwise
        +		# apps/openssl can end up in endless loop upon startup...
        +		$cflags.=" -Dmemcpy=__builtin_memcpy -Dmemset=__builtin_memset";
        +		}
        +	if ($iccver>=9)
        +		{
        +		$cflags.=" -i-static";
        +		$cflags=~s/\-no_cpprt/-no-cpprt/;
        +		}
        +	if ($iccver>=10)
        +		{
        +		$cflags=~s/\-i\-static/-static-intel/;
        +		}
        +	}
        +
        +# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
        +# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
        +# .so objects. Apparently application RPATH is not global and does
        +# not apply to .so linked with other .so. Problem manifests itself
        +# when libssl.so fails to load libcrypto.so. One can argue that we
        +# should engrave this into Makefile.shared rules or into BSD-* config
        +# lines above. Meanwhile let's try to be cautious and pass -rpath to
        +# linker only when --prefix is not /usr.
        +if ($target =~ /^BSD\-/)
        +	{
        +	$shared_ldflag.=" -Wl,-rpath,\$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
        +	}
        +
        +if ($sys_id ne "")
        +	{
        +	#$cflags="-DOPENSSL_SYSNAME_$sys_id $cflags";
        +	$openssl_sys_defines="#define OPENSSL_SYSNAME_$sys_id\n";
        +	}
        +
        +if ($ranlib eq "")
        +	{
        +	$ranlib = $default_ranlib;
        +	}
        +
        +#my ($bn1)=split(/\s+/,$bn_obj);
        +#$bn1 = "" unless defined $bn1;
        +#$bn1=$bn_asm unless ($bn1 =~ /\.o$/);
        +#$bn_obj="$bn1";
        +
        +$cpuid_obj="" if ($processor eq "386");
        +
        +$bn_obj = $bn_asm unless $bn_obj ne "";
        +# bn-586 is the only one implementing bn_*_part_words
        +$cflags.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($bn_obj =~ /bn-586/);
        +$cflags.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $bn_obj =~ /86/);
        +
        +$cflags.=" -DOPENSSL_BN_ASM_MONT" if ($bn_obj =~ /-mont/);
        +$cflags.=" -DOPENSSL_BN_ASM_MONT5" if ($bn_obj =~ /-mont5/);
        +$cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($bn_obj =~ /-gf2m/);
        +
        +if ($fips)
        +	{
        +	$openssl_other_defines.="#define OPENSSL_FIPS\n";
        +	$cflags .= " -I\$(FIPSDIR)/include";
        +	}
        +
        +$cpuid_obj="mem_clr.o"	unless ($cpuid_obj =~ /\.o$/);
        +$des_obj=$des_enc	unless ($des_obj =~ /\.o$/);
        +$bf_obj=$bf_enc		unless ($bf_obj =~ /\.o$/);
        +$cast_obj=$cast_enc	unless ($cast_obj =~ /\.o$/);
        +$rc4_obj=$rc4_enc	unless ($rc4_obj =~ /\.o$/);
        +$rc5_obj=$rc5_enc	unless ($rc5_obj =~ /\.o$/);
        +if ($sha1_obj =~ /\.o$/)
        +	{
        +#	$sha1_obj=$sha1_enc;
        +	$cflags.=" -DSHA1_ASM"   if ($sha1_obj =~ /sx86/ || $sha1_obj =~ /sha1/);
        +	$cflags.=" -DSHA256_ASM" if ($sha1_obj =~ /sha256/);
        +	$cflags.=" -DSHA512_ASM" if ($sha1_obj =~ /sha512/);
        +	if ($sha1_obj =~ /sse2/)
        +	    {	if ($no_sse2)
        +		{   $sha1_obj =~ s/\S*sse2\S+//;        }
        +		elsif ($cflags !~ /OPENSSL_IA32_SSE2/)
        +		{   $cflags.=" -DOPENSSL_IA32_SSE2";    }
        +	    }
        +	}
        +if ($md5_obj =~ /\.o$/)
        +	{
        +#	$md5_obj=$md5_enc;
        +	$cflags.=" -DMD5_ASM";
        +	}
        +if ($rmd160_obj =~ /\.o$/)
        +	{
        +#	$rmd160_obj=$rmd160_enc;
        +	$cflags.=" -DRMD160_ASM";
        +	}
        +if ($aes_obj =~ /\.o$/)
        +	{
        +	$cflags.=" -DAES_ASM";
        +	# aes-ctr.o is not a real file, only indication that assembler
        +	# module implements AES_ctr32_encrypt...
        +	$cflags.=" -DAES_CTR_ASM" if ($aes_obj =~ s/\s*aes\-ctr\.o//);
        +	# aes-xts.o indicates presense of AES_xts_[en|de]crypt...
        +	$cflags.=" -DAES_XTS_ASM" if ($aes_obj =~ s/\s*aes\-xts\.o//);
        +	$aes_obj =~ s/\s*(vpaes|aesni)\-x86\.o//g if ($no_sse2);
        +	$cflags.=" -DVPAES_ASM" if ($aes_obj =~ m/vpaes/);
        +	$cflags.=" -DBSAES_ASM" if ($aes_obj =~ m/bsaes/);
        +	}
        +else	{
        +	$aes_obj=$aes_enc;
        +	}
        +$wp_obj="" if ($wp_obj =~ /mmx/ && $processor eq "386");
        +if ($wp_obj =~ /\.o$/ && !$disabled{"whirlpool"})
        +	{
        +	$cflags.=" -DWHIRLPOOL_ASM";
        +	}
        +else	{
        +	$wp_obj="wp_block.o";
        +	}
        +$cmll_obj=$cmll_enc	unless ($cmll_obj =~ /.o$/);
        +if ($modes_obj =~ /ghash/)
        +	{
        +	$cflags.=" -DGHASH_ASM";
        +	}
        +
        +# "Stringify" the C flags string.  This permits it to be made part of a string
        +# and works as well on command lines.
        +$cflags =~ s/([\\\"])/\\\1/g;
        +
        +my $version = "unknown";
        +my $version_num = "unknown";
        +my $major = "unknown";
        +my $minor = "unknown";
        +my $shlib_version_number = "unknown";
        +my $shlib_version_history = "unknown";
        +my $shlib_major = "unknown";
        +my $shlib_minor = "unknown";
        +
        +open(IN,'<crypto/opensslv.h') || die "unable to read opensslv.h:$!\n";
        +while (<IN>)
        +	{
        +	$version=$1 if /OPENSSL.VERSION.TEXT.*OpenSSL (\S+) /;
        +	$version_num=$1 if /OPENSSL.VERSION.NUMBER.*0x(\S+)/;
        +	$shlib_version_number=$1 if /SHLIB_VERSION_NUMBER *"([^"]+)"/;
        +	$shlib_version_history=$1 if /SHLIB_VERSION_HISTORY *"([^"]*)"/;
        +	}
        +close(IN);
        +if ($shlib_version_history ne "") { $shlib_version_history .= ":"; }
        +
        +if ($version =~ /(^[0-9]*)\.([0-9\.]*)/)
        +	{
        +	$major=$1;
        +	$minor=$2;
        +	}
        +
        +if ($shlib_version_number =~ /(^[0-9]*)\.([0-9\.]*)/)
        +	{
        +	$shlib_major=$1;
        +	$shlib_minor=$2;
        +	}
        +
        +if ($strict_warnings)
        +	{
        +	my $wopt;
        +	die "ERROR --strict-warnings requires gcc" unless ($cc =~ /gcc$/);
        +	foreach $wopt (split /\s+/, $gcc_devteam_warn)
        +		{
        +		$cflags .= " $wopt" unless ($cflags =~ /$wopt/)
        +		}
        +	}
        +
        +open(IN,'<Makefile.org') || die "unable to read Makefile.org:$!\n";
        +unlink("$Makefile.new") || die "unable to remove old $Makefile.new:$!\n" if -e "$Makefile.new";
        +open(OUT,">$Makefile.new") || die "unable to create $Makefile.new:$!\n";
        +print OUT "### Generated automatically from Makefile.org by Configure.\n\n";
        +my $sdirs=0;
        +while (<IN>)
        +	{
        +	chomp;
        +	$sdirs = 1 if /^SDIRS=/;
        +	if ($sdirs) {
        +		my $dir;
        +		foreach $dir (@skip) {
        +			s/(\s)$dir /$1/;
        +			s/\s$dir$//;
        +			}
        +		}
        +	$sdirs = 0 unless /\\$/;
        +        s/engines // if (/^DIRS=/ && $disabled{"engine"});
        +	s/ccgost// if (/^ENGDIRS=/ && $disabled{"gost"});
        +	s/^VERSION=.*/VERSION=$version/;
        +	s/^MAJOR=.*/MAJOR=$major/;
        +	s/^MINOR=.*/MINOR=$minor/;
        +	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
        +	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
        +	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
        +	s/^SHLIB_MINOR=.*/SHLIB_MINOR=$shlib_minor/;
        +	s/^SHLIB_EXT=.*/SHLIB_EXT=$shared_extension/;
        +	s/^INSTALLTOP=.*$/INSTALLTOP=$prefix/;
        +	s/^MULTILIB=.*$/MULTILIB=$multilib/;
        +	s/^OPENSSLDIR=.*$/OPENSSLDIR=$openssldir/;
        +	s/^LIBDIR=.*$/LIBDIR=$libdir/;
        +	s/^INSTALL_PREFIX=.*$/INSTALL_PREFIX=$install_prefix/;
        +	s/^PLATFORM=.*$/PLATFORM=$target/;
        +	s/^OPTIONS=.*$/OPTIONS=$options/;
        +	s/^CONFIGURE_ARGS=.*$/CONFIGURE_ARGS=$argvstring/;
        +	if ($cross_compile_prefix)
        +		{
        +		s/^CC=.*$/CROSS_COMPILE= $cross_compile_prefix\nCC= \$\(CROSS_COMPILE\)$cc/;
        +		s/^AR=\s*/AR= \$\(CROSS_COMPILE\)/;
        +		s/^NM=\s*/NM= \$\(CROSS_COMPILE\)/;
        +		s/^RANLIB=\s*/RANLIB= \$\(CROSS_COMPILE\)/;
        +		s/^MAKEDEPPROG=.*$/MAKEDEPPROG= \$\(CROSS_COMPILE\)$cc/ if $cc eq "gcc";
        +		}
        +	else	{
        +		s/^CC=.*$/CC= $cc/;
        +		s/^AR=\s*ar/AR= $ar/;
        +		s/^RANLIB=.*/RANLIB= $ranlib/;
        +		s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc";
        +		}
        +	s/^CFLAG=.*$/CFLAG= $cflags/;
        +	s/^DEPFLAG=.*$/DEPFLAG=$depflags/;
        +	s/^PEX_LIBS=.*$/PEX_LIBS= $prelflags/;
        +	s/^EX_LIBS=.*$/EX_LIBS= $lflags/;
        +	s/^EXE_EXT=.*$/EXE_EXT= $exe_ext/;
        +	s/^CPUID_OBJ=.*$/CPUID_OBJ= $cpuid_obj/;
        +	s/^BN_ASM=.*$/BN_ASM= $bn_obj/;
        +	s/^DES_ENC=.*$/DES_ENC= $des_obj/;
        +	s/^AES_ENC=.*$/AES_ENC= $aes_obj/;
        +	s/^BF_ENC=.*$/BF_ENC= $bf_obj/;
        +	s/^CAST_ENC=.*$/CAST_ENC= $cast_obj/;
        +	s/^RC4_ENC=.*$/RC4_ENC= $rc4_obj/;
        +	s/^RC5_ENC=.*$/RC5_ENC= $rc5_obj/;
        +	s/^MD5_ASM_OBJ=.*$/MD5_ASM_OBJ= $md5_obj/;
        +	s/^SHA1_ASM_OBJ=.*$/SHA1_ASM_OBJ= $sha1_obj/;
        +	s/^RMD160_ASM_OBJ=.*$/RMD160_ASM_OBJ= $rmd160_obj/;
        +	s/^WP_ASM_OBJ=.*$/WP_ASM_OBJ= $wp_obj/;
        +	s/^CMLL_ENC=.*$/CMLL_ENC= $cmll_obj/;
        +	s/^MODES_ASM_OBJ.=*$/MODES_ASM_OBJ= $modes_obj/;
        +	s/^ENGINES_ASM_OBJ.=*$/ENGINES_ASM_OBJ= $engines_obj/;
        +	s/^PERLASM_SCHEME=.*$/PERLASM_SCHEME= $perlasm_scheme/;
        +	s/^PROCESSOR=.*/PROCESSOR= $processor/;
        +	s/^ARFLAGS=.*/ARFLAGS= $arflags/;
        +	s/^PERL=.*/PERL= $perl/;
        +	s/^KRB5_INCLUDES=.*/KRB5_INCLUDES=$withargs{"krb5-include"}/;
        +	s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/;
        +	s/^LIBZLIB=.*/LIBZLIB=$withargs{"zlib-lib"}/;
        +	s/^ZLIB_INCLUDE=.*/ZLIB_INCLUDE=$withargs{"zlib-include"}/;
        +
        +	s/^FIPSDIR=.*/FIPSDIR=$fipsdir/;
        +	s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/;
        +	s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips;
        +	s/^BASEADDR=.*/BASEADDR=$baseaddr/;
        +
        +	s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
        +	s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
        +	s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
        +	if ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*$/)
        +		{
        +		my $sotmp = $1;
        +		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp/;
        +		}
        +	elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.dylib$/)
        +		{
        +		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.dylib/;
        +		}
        +	elsif ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*\.[^\.]*$/)
        +		{
        +		my $sotmp = $1;
        +		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_MAJOR) .s$sotmp/;
        +		}
        +	elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.[^\.]*\.dylib$/)
        +		{
        +		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.\$(SHLIB_MAJOR).dylib .dylib/;
        +		}
        +	s/^SHARED_LDFLAGS=.*/SHARED_LDFLAGS=$shared_ldflag/;
        +	print OUT $_."\n";
        +	}
        +close(IN);
        +close(OUT);
        +rename($Makefile,"$Makefile.bak") || die "unable to rename $Makefile\n" if -e $Makefile;
        +rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
        +
        +print "CC            =$cc\n";
        +print "CFLAG         =$cflags\n";
        +print "EX_LIBS       =$lflags\n";
        +print "CPUID_OBJ     =$cpuid_obj\n";
        +print "BN_ASM        =$bn_obj\n";
        +print "DES_ENC       =$des_obj\n";
        +print "AES_ENC       =$aes_obj\n";
        +print "BF_ENC        =$bf_obj\n";
        +print "CAST_ENC      =$cast_obj\n";
        +print "RC4_ENC       =$rc4_obj\n";
        +print "RC5_ENC       =$rc5_obj\n";
        +print "MD5_OBJ_ASM   =$md5_obj\n";
        +print "SHA1_OBJ_ASM  =$sha1_obj\n";
        +print "RMD160_OBJ_ASM=$rmd160_obj\n";
        +print "CMLL_ENC      =$cmll_obj\n";
        +print "MODES_OBJ     =$modes_obj\n";
        +print "ENGINES_OBJ   =$engines_obj\n";
        +print "PROCESSOR     =$processor\n";
        +print "RANLIB        =$ranlib\n";
        +print "ARFLAGS       =$arflags\n";
        +print "PERL          =$perl\n";
        +print "KRB5_INCLUDES =",$withargs{"krb5-include"},"\n"
        +	if $withargs{"krb5-include"} ne "";
        +
        +my $des_ptr=0;
        +my $des_risc1=0;
        +my $des_risc2=0;
        +my $des_unroll=0;
        +my $bn_ll=0;
        +my $def_int=2;
        +my $rc4_int=$def_int;
        +my $md2_int=$def_int;
        +my $idea_int=$def_int;
        +my $rc2_int=$def_int;
        +my $rc4_idx=0;
        +my $rc4_chunk=0;
        +my $bf_ptr=0;
        +my @type=("char","short","int","long");
        +my ($b64l,$b64,$b32,$b16,$b8)=(0,0,1,0,0);
        +my $export_var_as_fn=0;
        +
        +my $des_int;
        +
        +foreach (sort split(/\s+/,$bn_ops))
        +	{
        +	$des_ptr=1 if /DES_PTR/;
        +	$des_risc1=1 if /DES_RISC1/;
        +	$des_risc2=1 if /DES_RISC2/;
        +	$des_unroll=1 if /DES_UNROLL/;
        +	$des_int=1 if /DES_INT/;
        +	$bn_ll=1 if /BN_LLONG/;
        +	$rc4_int=0 if /RC4_CHAR/;
        +	$rc4_int=3 if /RC4_LONG/;
        +	$rc4_idx=1 if /RC4_INDEX/;
        +	$rc4_chunk=1 if /RC4_CHUNK/;
        +	$rc4_chunk=2 if /RC4_CHUNK_LL/;
        +	$md2_int=0 if /MD2_CHAR/;
        +	$md2_int=3 if /MD2_LONG/;
        +	$idea_int=1 if /IDEA_SHORT/;
        +	$idea_int=3 if /IDEA_LONG/;
        +	$rc2_int=1 if /RC2_SHORT/;
        +	$rc2_int=3 if /RC2_LONG/;
        +	$bf_ptr=1 if $_ eq "BF_PTR";
        +	$bf_ptr=2 if $_ eq "BF_PTR2";
        +	($b64l,$b64,$b32,$b16,$b8)=(0,1,0,0,0) if /SIXTY_FOUR_BIT/;
        +	($b64l,$b64,$b32,$b16,$b8)=(1,0,0,0,0) if /SIXTY_FOUR_BIT_LONG/;
        +	($b64l,$b64,$b32,$b16,$b8)=(0,0,1,0,0) if /THIRTY_TWO_BIT/;
        +	($b64l,$b64,$b32,$b16,$b8)=(0,0,0,1,0) if /SIXTEEN_BIT/;
        +	($b64l,$b64,$b32,$b16,$b8)=(0,0,0,0,1) if /EIGHT_BIT/;
        +	$export_var_as_fn=1 if /EXPORT_VAR_AS_FN/;
        +	}
        +
        +open(IN,'<crypto/opensslconf.h.in') || die "unable to read crypto/opensslconf.h.in:$!\n";
        +unlink("crypto/opensslconf.h.new") || die "unable to remove old crypto/opensslconf.h.new:$!\n" if -e "crypto/opensslconf.h.new";
        +open(OUT,'>crypto/opensslconf.h.new') || die "unable to create crypto/opensslconf.h.new:$!\n";
        +print OUT "/* opensslconf.h */\n";
        +print OUT "/* WARNING: Generated automatically from opensslconf.h.in by Configure. */\n\n";
        +
        +print OUT "/* OpenSSL was configured with the following options: */\n";
        +my $openssl_algorithm_defines_trans = $openssl_algorithm_defines;
        +$openssl_experimental_defines =~ s/^\s*#\s*define\s+OPENSSL_NO_(.*)/#ifndef OPENSSL_EXPERIMENTAL_$1\n# ifndef OPENSSL_NO_$1\n#  define OPENSSL_NO_$1\n# endif\n#endif/mg;
        +$openssl_algorithm_defines_trans =~ s/^\s*#\s*define\s+OPENSSL_(.*)/# if defined(OPENSSL_$1) \&\& !defined($1)\n#  define $1\n# endif/mg;
        +$openssl_algorithm_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
        +$openssl_algorithm_defines = "   /* no ciphers excluded */\n" if $openssl_algorithm_defines eq "";
        +$openssl_thread_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
        +$openssl_sys_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
        +$openssl_other_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
        +print OUT $openssl_sys_defines;
        +print OUT "#ifndef OPENSSL_DOING_MAKEDEPEND\n\n";
        +print OUT $openssl_experimental_defines;
        +print OUT "\n";
        +print OUT $openssl_algorithm_defines;
        +print OUT "\n#endif /* OPENSSL_DOING_MAKEDEPEND */\n\n";
        +print OUT $openssl_thread_defines;
        +print OUT $openssl_other_defines,"\n";
        +
        +print OUT "/* The OPENSSL_NO_* macros are also defined as NO_* if the application\n";
        +print OUT "   asks for it.  This is a transient feature that is provided for those\n";
        +print OUT "   who haven't had the time to do the appropriate changes in their\n";
        +print OUT "   applications.  */\n";
        +print OUT "#ifdef OPENSSL_ALGORITHM_DEFINES\n";
        +print OUT $openssl_algorithm_defines_trans;
        +print OUT "#endif\n\n";
        +
        +print OUT "#define OPENSSL_CPUID_OBJ\n\n" if ($cpuid_obj ne "mem_clr.o");
        +
        +while (<IN>)
        +	{
        +	if	(/^#define\s+OPENSSLDIR/)
        +		{
        +		my $foo = $openssldir;
        +		$foo =~ s/\\/\\\\/g;
        +		print OUT "#define OPENSSLDIR \"$foo\"\n";
        +		}
        +	elsif	(/^#define\s+ENGINESDIR/)
        +		{
        +		my $foo = "$prefix/$libdir/engines";
        +		$foo =~ s/\\/\\\\/g;
        +		print OUT "#define ENGINESDIR \"$foo\"\n";
        +		}
        +	elsif	(/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/)
        +		{ printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n"
        +			if $export_var_as_fn;
        +		  printf OUT "#%s OPENSSL_EXPORT_VAR_AS_FUNCTION\n",
        +			($export_var_as_fn)?"define":"undef"; }
        +	elsif	(/^#define\s+OPENSSL_UNISTD/)
        +		{
        +		$unistd = "<unistd.h>" if $unistd eq "";
        +		print OUT "#define OPENSSL_UNISTD $unistd\n";
        +		}
        +	elsif	(/^#((define)|(undef))\s+SIXTY_FOUR_BIT_LONG/)
        +		{ printf OUT "#%s SIXTY_FOUR_BIT_LONG\n",($b64l)?"define":"undef"; }
        +	elsif	(/^#((define)|(undef))\s+SIXTY_FOUR_BIT/)
        +		{ printf OUT "#%s SIXTY_FOUR_BIT\n",($b64)?"define":"undef"; }
        +	elsif	(/^#((define)|(undef))\s+THIRTY_TWO_BIT/)
        +		{ printf OUT "#%s THIRTY_TWO_BIT\n",($b32)?"define":"undef"; }
        +	elsif	(/^#((define)|(undef))\s+SIXTEEN_BIT/)
        +		{ printf OUT "#%s SIXTEEN_BIT\n",($b16)?"define":"undef"; }
        +	elsif	(/^#((define)|(undef))\s+EIGHT_BIT/)
        +		{ printf OUT "#%s EIGHT_BIT\n",($b8)?"define":"undef"; }
        +	elsif	(/^#((define)|(undef))\s+BN_LLONG\s*$/)
        +		{ printf OUT "#%s BN_LLONG\n",($bn_ll)?"define":"undef"; }
        +	elsif	(/^\#define\s+DES_LONG\s+.*/)
        +		{ printf OUT "#define DES_LONG unsigned %s\n",
        +			($des_int)?'int':'long'; }
        +	elsif	(/^\#(define|undef)\s+DES_PTR/)
        +		{ printf OUT "#%s DES_PTR\n",($des_ptr)?'define':'undef'; }
        +	elsif	(/^\#(define|undef)\s+DES_RISC1/)
        +		{ printf OUT "#%s DES_RISC1\n",($des_risc1)?'define':'undef'; }
        +	elsif	(/^\#(define|undef)\s+DES_RISC2/)
        +		{ printf OUT "#%s DES_RISC2\n",($des_risc2)?'define':'undef'; }
        +	elsif	(/^\#(define|undef)\s+DES_UNROLL/)
        +		{ printf OUT "#%s DES_UNROLL\n",($des_unroll)?'define':'undef'; }
        +	elsif	(/^#define\s+RC4_INT\s/)
        +		{ printf OUT "#define RC4_INT unsigned %s\n",$type[$rc4_int]; }
        +	elsif	(/^#undef\s+RC4_CHUNK/)
        +		{
        +		printf OUT "#undef RC4_CHUNK\n" if $rc4_chunk==0;
        +		printf OUT "#define RC4_CHUNK unsigned long\n" if $rc4_chunk==1;
        +		printf OUT "#define RC4_CHUNK unsigned long long\n" if $rc4_chunk==2;
        +		}
        +	elsif	(/^#((define)|(undef))\s+RC4_INDEX/)
        +		{ printf OUT "#%s RC4_INDEX\n",($rc4_idx)?"define":"undef"; }
        +	elsif (/^#(define|undef)\s+I386_ONLY/)
        +		{ printf OUT "#%s I386_ONLY\n", ($processor eq "386")?
        +			"define":"undef"; }
        +	elsif	(/^#define\s+MD2_INT\s/)
        +		{ printf OUT "#define MD2_INT unsigned %s\n",$type[$md2_int]; }
        +	elsif	(/^#define\s+IDEA_INT\s/)
        +		{printf OUT "#define IDEA_INT unsigned %s\n",$type[$idea_int];}
        +	elsif	(/^#define\s+RC2_INT\s/)
        +		{printf OUT "#define RC2_INT unsigned %s\n",$type[$rc2_int];}
        +	elsif (/^#(define|undef)\s+BF_PTR/)
        +		{
        +		printf OUT "#undef BF_PTR\n" if $bf_ptr == 0;
        +		printf OUT "#define BF_PTR\n" if $bf_ptr == 1;
        +		printf OUT "#define BF_PTR2\n" if $bf_ptr == 2;
        +	        }
        +	else
        +		{ print OUT $_; }
        +	}
        +close(IN);
        +close(OUT);
        +rename("crypto/opensslconf.h","crypto/opensslconf.h.bak") || die "unable to rename crypto/opensslconf.h\n" if -e "crypto/opensslconf.h";
        +rename("crypto/opensslconf.h.new","crypto/opensslconf.h") || die "unable to rename crypto/opensslconf.h.new\n";
        +
        +
        +# Fix the date
        +
        +print "SIXTY_FOUR_BIT_LONG mode\n" if $b64l;
        +print "SIXTY_FOUR_BIT mode\n" if $b64;
        +print "THIRTY_TWO_BIT mode\n" if $b32;
        +print "SIXTEEN_BIT mode\n" if $b16;
        +print "EIGHT_BIT mode\n" if $b8;
        +print "DES_PTR used\n" if $des_ptr;
        +print "DES_RISC1 used\n" if $des_risc1;
        +print "DES_RISC2 used\n" if $des_risc2;
        +print "DES_UNROLL used\n" if $des_unroll;
        +print "DES_INT used\n" if $des_int;
        +print "BN_LLONG mode\n" if $bn_ll;
        +print "RC4 uses u$type[$rc4_int]\n" if $rc4_int != $def_int;
        +print "RC4_INDEX mode\n" if $rc4_idx;
        +print "RC4_CHUNK is undefined\n" if $rc4_chunk==0;
        +print "RC4_CHUNK is unsigned long\n" if $rc4_chunk==1;
        +print "RC4_CHUNK is unsigned long long\n" if $rc4_chunk==2;
        +print "MD2 uses u$type[$md2_int]\n" if $md2_int != $def_int;
        +print "IDEA uses u$type[$idea_int]\n" if $idea_int != $def_int;
        +print "RC2 uses u$type[$rc2_int]\n" if $rc2_int != $def_int;
        +print "BF_PTR used\n" if $bf_ptr == 1; 
        +print "BF_PTR2 used\n" if $bf_ptr == 2; 
        +
        +if($IsMK1MF) {
        +	open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
        +	printf OUT <<EOF;
        +#ifndef MK1MF_BUILD
        +  /* auto-generated by Configure for crypto/cversion.c:
        +   * for Unix builds, crypto/Makefile.ssl generates functional definitions;
        +   * Windows builds (and other mk1mf builds) compile cversion.c with
        +   * -DMK1MF_BUILD and use definitions added to this file by util/mk1mf.pl. */
        +  #error "Windows builds (PLATFORM=$target) use mk1mf.pl-created Makefiles"
        +#endif
        +EOF
        +	close(OUT);
        +} else {
        +	my $make_command = "$make PERL=\'$perl\'";
        +	my $make_targets = "";
        +	$make_targets .= " links" if $symlink;
        +	$make_targets .= " depend" if $depflags ne $default_depflags && $make_depend;
        +	$make_targets .= " gentests" if $symlink;
        +	(system $make_command.$make_targets) == 0 or exit $?
        +		if $make_targets ne "";
        +	if ( $perl =~ m@^/@) {
        +	    &dofile("tools/c_rehash",$perl,'^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";', '^my \$prefix;$', 'my $prefix = "' . $prefix . '";');
        +	    &dofile("apps/CA.pl",$perl,'^#!/', '#!%s');
        +	} else {
        +	    # No path for Perl known ...
        +	    &dofile("tools/c_rehash",'/usr/local/bin/perl','^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";',  '^my \$prefix;$', 'my $prefix = "' . $prefix . '";');
        +	    &dofile("apps/CA.pl",'/usr/local/bin/perl','^#!/', '#!%s');
        +	}
        +	if ($depflags ne $default_depflags && !$make_depend) {
        +		print <<EOF;
        +
        +Since you've disabled or enabled at least one algorithm, you need to do
        +the following before building:
        +
        +	make depend
        +EOF
        +	}
        +}
        +
        +# create the ms/version32.rc file if needed
        +if ($IsMK1MF && ($target !~ /^netware/)) {
        +	my ($v1, $v2, $v3, $v4);
        +	if ($version_num =~ /(^[0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i) {
        +		$v1=hex $1;
        +		$v2=hex $2;
        +		$v3=hex $3;
        +		$v4=hex $4;
        +	}
        +	open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
        +	print OUT <<EOF;
        +#include <winver.h>
        +
        +LANGUAGE 0x09,0x01
        +
        +1 VERSIONINFO
        +  FILEVERSION $v1,$v2,$v3,$v4
        +  PRODUCTVERSION $v1,$v2,$v3,$v4
        +  FILEFLAGSMASK 0x3fL
        +#ifdef _DEBUG
        +  FILEFLAGS 0x01L
        +#else
        +  FILEFLAGS 0x00L
        +#endif
        +  FILEOS VOS__WINDOWS32
        +  FILETYPE VFT_DLL
        +  FILESUBTYPE 0x0L
        +BEGIN
        +    BLOCK "StringFileInfo"
        +    BEGIN
        +	BLOCK "040904b0"
        +	BEGIN
        +	    // Required:	    
        +	    VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
        +	    VALUE "FileDescription", "OpenSSL Shared Library\\0"
        +	    VALUE "FileVersion", "$version\\0"
        +#if defined(CRYPTO)
        +	    VALUE "InternalName", "libeay32\\0"
        +	    VALUE "OriginalFilename", "libeay32.dll\\0"
        +#elif defined(SSL)
        +	    VALUE "InternalName", "ssleay32\\0"
        +	    VALUE "OriginalFilename", "ssleay32.dll\\0"
        +#endif
        +	    VALUE "ProductName", "The OpenSSL Toolkit\\0"
        +	    VALUE "ProductVersion", "$version\\0"
        +	    // Optional:
        +	    //VALUE "Comments", "\\0"
        +	    VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
        +	    //VALUE "LegalTrademarks", "\\0"
        +	    //VALUE "PrivateBuild", "\\0"
        +	    //VALUE "SpecialBuild", "\\0"
        +	END
        +    END
        +    BLOCK "VarFileInfo"
        +    BEGIN
        +        VALUE "Translation", 0x409, 0x4b0
        +    END
        +END
        +EOF
        +	close(OUT);
        +  }
        +  
        +print <<EOF;
        +
        +Configured for $target.
        +EOF
        +
        +print <<\EOF if (!$no_threads && !$threads);
        +
        +The library could not be configured for supporting multi-threaded
        +applications as the compiler options required on this system are not known.
        +See file INSTALL for details if you need multi-threading.
        +EOF
        +
        +print <<\EOF if ($no_shared_warn);
        +
        +You gave the option 'shared'.  Normally, that would give you shared libraries.
        +Unfortunately, the OpenSSL configuration doesn't include shared library support
        +for this platform yet, so it will pretend you gave the option 'no-shared'.  If
        +you can inform the developpers (openssl-dev\@openssl.org) how to support shared
        +libraries on this platform, they will at least look at it and try their best
        +(but please first make sure you have tried with a current version of OpenSSL).
        +EOF
        +
        +exit(0);
        +
        +sub usage
        +	{
        +	print STDERR $usage;
        +	print STDERR "\npick os/compiler from:\n";
        +	my $j=0;
        +	my $i;
        +        my $k=0;
        +	foreach $i (sort keys %table)
        +		{
        +		next if $i =~ /^debug/;
        +		$k += length($i) + 1;
        +		if ($k > 78)
        +			{
        +			print STDERR "\n";
        +			$k=length($i);
        +			}
        +		print STDERR $i . " ";
        +		}
        +	foreach $i (sort keys %table)
        +		{
        +		next if $i !~ /^debug/;
        +		$k += length($i) + 1;
        +		if ($k > 78)
        +			{
        +			print STDERR "\n";
        +			$k=length($i);
        +			}
        +		print STDERR $i . " ";
        +		}
        +	print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
        +	exit(1);
        +	}
        +
        +sub which
        +	{
        +	my($name)=@_;
        +	my $path;
        +	foreach $path (split /:/, $ENV{PATH})
        +		{
        +		if (-f "$path/$name$exe_ext" and -x _)
        +			{
        +			return "$path/$name$exe_ext" unless ($name eq "perl" and
        +			 system("$path/$name$exe_ext -e " . '\'exit($]<5.0);\''));
        +			}
        +		}
        +	}
        +
        +sub dofile
        +	{
        +	my $f; my $p; my %m; my @a; my $k; my $ff;
        +	($f,$p,%m)=@_;
        +
        +	open(IN,"<$f.in") || open(IN,"<$f") || die "unable to open $f:$!\n";
        +	@a=<IN>;
        +	close(IN);
        +	foreach $k (keys %m)
        +		{
        +		grep(/$k/ && ($_=sprintf($m{$k}."\n",$p)),@a);
        +		}
        +	open(OUT,">$f.new") || die "unable to open $f.new:$!\n";
        +	print OUT @a;
        +	close(OUT);
        +	rename($f,"$f.bak") || die "unable to rename $f\n" if -e $f;
        +	rename("$f.new",$f) || die "unable to rename $f.new\n";
        +	}
        +
        +sub print_table_entry
        +	{
        +	my $target = shift;
        +
        +	(my $cc,my $cflags,my $unistd,my $thread_cflag,my $sys_id,my $lflags,
        +	my $bn_ops,my $cpuid_obj,my $bn_obj,my $des_obj,my $aes_obj, my $bf_obj,
        +	my $md5_obj,my $sha1_obj,my $cast_obj,my $rc4_obj,my $rmd160_obj,
        +	my $rc5_obj,my $wp_obj,my $cmll_obj,my $modes_obj, my $engines_obj,
        +	my $perlasm_scheme,my $dso_scheme,my $shared_target,my $shared_cflag,
        +	my $shared_ldflag,my $shared_extension,my $ranlib,my $arflags,my $multilib)=
        +	split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
        +			
        +	print <<EOF
        +
        +*** $target
        +\$cc           = $cc
        +\$cflags       = $cflags
        +\$unistd       = $unistd
        +\$thread_cflag = $thread_cflag
        +\$sys_id       = $sys_id
        +\$lflags       = $lflags
        +\$bn_ops       = $bn_ops
        +\$cpuid_obj    = $cpuid_obj
        +\$bn_obj       = $bn_obj
        +\$des_obj      = $des_obj
        +\$aes_obj      = $aes_obj
        +\$bf_obj       = $bf_obj
        +\$md5_obj      = $md5_obj
        +\$sha1_obj     = $sha1_obj
        +\$cast_obj     = $cast_obj
        +\$rc4_obj      = $rc4_obj
        +\$rmd160_obj   = $rmd160_obj
        +\$rc5_obj      = $rc5_obj
        +\$wp_obj       = $wp_obj
        +\$cmll_obj     = $cmll_obj
        +\$modes_obj    = $modes_obj
        +\$engines_obj  = $engines_obj
        +\$perlasm_scheme = $perlasm_scheme
        +\$dso_scheme   = $dso_scheme
        +\$shared_target= $shared_target
        +\$shared_cflag = $shared_cflag
        +\$shared_ldflag = $shared_ldflag
        +\$shared_extension = $shared_extension
        +\$ranlib       = $ranlib
        +\$arflags      = $arflags
        +\$multilib     = $multilib
        +EOF
        +	}
        +
        +sub test_sanity
        +	{
        +	my $errorcnt = 0;
        +
        +	print STDERR "=" x 70, "\n";
        +	print STDERR "=== SANITY TESTING!\n";
        +	print STDERR "=== No configuration will be done, all other arguments will be ignored!\n";
        +	print STDERR "=" x 70, "\n";
        +
        +	foreach $target (sort keys %table)
        +		{
        +		@fields = split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
        +
        +		if ($fields[$idx_dso_scheme-1] =~ /^(beos|dl|dlfcn|win32|vms)$/)
        +			{
        +			$errorcnt++;
        +			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] values\n";
        +			print STDERR "              in the previous field\n";
        +			}
        +		elsif ($fields[$idx_dso_scheme+1] =~ /^(beos|dl|dlfcn|win32|vms)$/)
        +			{
        +			$errorcnt++;
        +			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] values\n";
        +			print STDERR "              in the following field\n";
        +			}
        +		elsif ($fields[$idx_dso_scheme] !~ /^(beos|dl|dlfcn|win32|vms|)$/)
        +			{
        +			$errorcnt++;
        +			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] field = ",$fields[$idx_dso_scheme],"\n";
        +			print STDERR "              valid values are 'beos', 'dl', 'dlfcn', 'win32' and 'vms'\n";
        +			}
        +		}
        +	print STDERR "No sanity errors detected!\n" if $errorcnt == 0;
        +	return $errorcnt;
        +	}
        diff --git a/vendor/openssl/openssl/FAQ b/vendor/openssl/openssl/FAQ
        new file mode 100644
        index 000000000..35780f807
        --- /dev/null
        +++ b/vendor/openssl/openssl/FAQ
        @@ -0,0 +1,1041 @@
        +OpenSSL  -  Frequently Asked Questions
        +--------------------------------------
        +
        +[MISC] Miscellaneous questions
        +
        +* Which is the current version of OpenSSL?
        +* Where is the documentation?
        +* How can I contact the OpenSSL developers?
        +* Where can I get a compiled version of OpenSSL?
        +* Why aren't tools like 'autoconf' and 'libtool' used?
        +* What is an 'engine' version?
        +* How do I check the authenticity of the OpenSSL distribution?
        +* How does the versioning scheme work?
        +
        +[LEGAL] Legal questions
        +
        +* Do I need patent licenses to use OpenSSL?
        +* Can I use OpenSSL with GPL software? 
        +
        +[USER] Questions on using the OpenSSL applications
        +
        +* Why do I get a "PRNG not seeded" error message?
        +* Why do I get an "unable to write 'random state'" error message?
        +* How do I create certificates or certificate requests?
        +* Why can't I create certificate requests?
        +* Why does <SSL program> fail with a certificate verify error?
        +* Why can I only use weak ciphers when I connect to a server using OpenSSL?
        +* How can I create DSA certificates?
        +* Why can't I make an SSL connection using a DSA certificate?
        +* How can I remove the passphrase on a private key?
        +* Why can't I use OpenSSL certificates with SSL client authentication?
        +* Why does my browser give a warning about a mismatched hostname?
        +* How do I install a CA certificate into a browser?
        +* Why is OpenSSL x509 DN output not conformant to RFC2253?
        +* What is a "128 bit certificate"? Can I create one with OpenSSL?
        +* Why does OpenSSL set the authority key identifier extension incorrectly?
        +* How can I set up a bundle of commercial root CA certificates?
        +
        +[BUILD] Questions about building and testing OpenSSL
        +
        +* Why does the linker complain about undefined symbols?
        +* Why does the OpenSSL test fail with "bc: command not found"?
        +* Why does the OpenSSL test fail with "bc: 1 no implemented"?
        +* Why does the OpenSSL test fail with "bc: stack empty"?
        +* Why does the OpenSSL compilation fail on Alpha Tru64 Unix?
        +* Why does the OpenSSL compilation fail with "ar: command not found"?
        +* Why does the OpenSSL compilation fail on Win32 with VC++?
        +* What is special about OpenSSL on Redhat?
        +* Why does the OpenSSL compilation fail on MacOS X?
        +* Why does the OpenSSL test suite fail on MacOS X?
        +* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
        +* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
        +* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
        +* Why does compiler fail to compile sha512.c?
        +* Test suite still fails, what to do?
        +* I think I've found a bug, what should I do?
        +* I'm SURE I've found a bug, how do I report it?
        +* I've found a security issue, how do I report it?
        +
        +[PROG] Questions about programming with OpenSSL
        +
        +* Is OpenSSL thread-safe?
        +* I've compiled a program under Windows and it crashes: why?
        +* How do I read or write a DER encoded buffer using the ASN1 functions?
        +* OpenSSL uses DER but I need BER format: does OpenSSL support BER?
        +* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
        +* I've called <some function> and it fails, why?
        +* I just get a load of numbers for the error output, what do they mean?
        +* Why do I get errors about unknown algorithms?
        +* Why can't the OpenSSH configure script detect OpenSSL?
        +* Can I use OpenSSL's SSL library with non-blocking I/O?
        +* Why doesn't my server application receive a client certificate?
        +* Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?
        +* I think I've detected a memory leak, is this a bug?
        +* Why does Valgrind complain about the use of uninitialized data?
        +* Why doesn't a memory BIO work when a file does?
        +* Where are the declarations and implementations of d2i_X509() etc?
        +
        +===============================================================================
        +
        +[MISC] ========================================================================
        +
        +* Which is the current version of OpenSSL?
        +
        +The current version is available from <URL: http://www.openssl.org>.
        +OpenSSL 1.0.1e was released on Feb 11th, 2013.
        +
        +In addition to the current stable release, you can also access daily
        +snapshots of the OpenSSL development version at <URL:
        +ftp://ftp.openssl.org/snapshot/>, or get it by anonymous Git access.
        +
        +
        +* Where is the documentation?
        +
        +OpenSSL is a library that provides cryptographic functionality to
        +applications such as secure web servers.  Be sure to read the
        +documentation of the application you want to use.  The INSTALL file
        +explains how to install this library.
        +
        +OpenSSL includes a command line utility that can be used to perform a
        +variety of cryptographic functions.  It is described in the openssl(1)
        +manpage.  Documentation for developers is currently being written. Many
        +manual pages are available; overviews over libcrypto and
        +libssl are given in the crypto(3) and ssl(3) manpages.
        +
        +The OpenSSL manpages are installed in /usr/local/ssl/man/ (or a
        +different directory if you specified one as described in INSTALL).
        +In addition, you can read the most current versions at
        +<URL: http://www.openssl.org/docs/>. Note that the online documents refer
        +to the very latest development versions of OpenSSL and may include features
        +not present in released versions. If in doubt refer to the documentation
        +that came with the version of OpenSSL you are using. The pod format
        +documentation is included in each OpenSSL distribution under the docs
        +directory.
        +
        +For information on parts of libcrypto that are not yet documented, you
        +might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's
        +predecessor, at <URL: http://www.columbia.edu/~ariel/ssleay/>.  Much
        +of this still applies to OpenSSL.
        +
        +There is some documentation about certificate extensions and PKCS#12
        +in doc/openssl.txt
        +
        +The original SSLeay documentation is included in OpenSSL as
        +doc/ssleay.txt.  It may be useful when none of the other resources
        +help, but please note that it reflects the obsolete version SSLeay
        +0.6.6.
        +
        +
        +* How can I contact the OpenSSL developers?
        +
        +The README file describes how to submit bug reports and patches to
        +OpenSSL.  Information on the OpenSSL mailing lists is available from
        +<URL: http://www.openssl.org>.
        +
        +
        +* Where can I get a compiled version of OpenSSL?
        +
        +You can finder pointers to binary distributions in
        +<URL: http://www.openssl.org/related/binaries.html> .
        +
        +Some applications that use OpenSSL are distributed in binary form.
        +When using such an application, you don't need to install OpenSSL
        +yourself; the application will include the required parts (e.g. DLLs).
        +
        +If you want to build OpenSSL on a Windows system and you don't have
        +a C compiler, read the "Mingw32" section of INSTALL.W32 for information
        +on how to obtain and install the free GNU C compiler.
        +
        +A number of Linux and *BSD distributions include OpenSSL.
        +
        +
        +* Why aren't tools like 'autoconf' and 'libtool' used?
        +
        +autoconf will probably be used in future OpenSSL versions. If it was
        +less Unix-centric, it might have been used much earlier.
        +
        +* What is an 'engine' version?
        +
        +With version 0.9.6 OpenSSL was extended to interface to external crypto
        +hardware. This was realized in a special release '0.9.6-engine'. With
        +version 0.9.7 the changes were merged into the main development line,
        +so that the special release is no longer necessary.
        +
        +* How do I check the authenticity of the OpenSSL distribution?
        +
        +We provide MD5 digests and ASC signatures of each tarball.
        +Use MD5 to check that a tarball from a mirror site is identical:
        +
        +   md5sum TARBALL | awk '{print $1;}' | cmp - TARBALL.md5
        +
        +You can check authenticity using pgp or gpg. You need the OpenSSL team
        +member public key used to sign it (download it from a key server, see a
        +list of keys at <URL: http://www.openssl.org/about/>). Then
        +just do:
        +
        +   pgp TARBALL.asc
        +
        +* How does the versioning scheme work?
        +
        +After the release of OpenSSL 1.0.0 the versioning scheme changed. Letter 
        +releases (e.g. 1.0.1a) can only contain bug and security fixes and no
        +new features. Minor releases change the last number (e.g. 1.0.2) and 
        +can contain new features that retain binary compatibility. Changes to
        +the middle number are considered major releases and neither source nor
        +binary compatibility is guaranteed.
        +
        +Therefore the answer to the common question "when will feature X be
        +backported to OpenSSL 1.0.0/0.9.8?" is "never" but it could appear
        +in the next minor release.
        +
        +[LEGAL] =======================================================================
        +
        +* Do I need patent licenses to use OpenSSL?
        +
        +The patents section of the README file lists patents that may apply to
        +you if you want to use OpenSSL.  For information on intellectual
        +property rights, please consult a lawyer.  The OpenSSL team does not
        +offer legal advice.
        +
        +You can configure OpenSSL so as not to use IDEA, MDC2 and RC5 by using
        + ./config no-idea no-mdc2 no-rc5
        +
        +
        +* Can I use OpenSSL with GPL software?
        +
        +On many systems including the major Linux and BSD distributions, yes (the
        +GPL does not place restrictions on using libraries that are part of the
        +normal operating system distribution).
        +
        +On other systems, the situation is less clear. Some GPL software copyright
        +holders claim that you infringe on their rights if you use OpenSSL with
        +their software on operating systems that don't normally include OpenSSL.
        +
        +If you develop open source software that uses OpenSSL, you may find it
        +useful to choose an other license than the GPL, or state explicitly that
        +"This program is released under the GPL with the additional exemption that
        +compiling, linking, and/or using OpenSSL is allowed."  If you are using
        +GPL software developed by others, you may want to ask the copyright holder
        +for permission to use their software with OpenSSL.
        +
        +
        +[USER] ========================================================================
        +
        +* Why do I get a "PRNG not seeded" error message?
        +
        +Cryptographic software needs a source of unpredictable data to work
        +correctly.  Many open source operating systems provide a "randomness
        +device" (/dev/urandom or /dev/random) that serves this purpose.
        +All OpenSSL versions try to use /dev/urandom by default; starting with
        +version 0.9.7, OpenSSL also tries /dev/random if /dev/urandom is not
        +available.
        +
        +On other systems, applications have to call the RAND_add() or
        +RAND_seed() function with appropriate data before generating keys or
        +performing public key encryption. (These functions initialize the
        +pseudo-random number generator, PRNG.)  Some broken applications do
        +not do this.  As of version 0.9.5, the OpenSSL functions that need
        +randomness report an error if the random number generator has not been
        +seeded with at least 128 bits of randomness.  If this error occurs and
        +is not discussed in the documentation of the application you are
        +using, please contact the author of that application; it is likely
        +that it never worked correctly.  OpenSSL 0.9.5 and later make the
        +error visible by refusing to perform potentially insecure encryption.
        +
        +If you are using Solaris 8, you can add /dev/urandom and /dev/random
        +devices by installing patch 112438 (Sparc) or 112439 (x86), which are
        +available via the Patchfinder at <URL: http://sunsolve.sun.com>
        +(Solaris 9 includes these devices by default). For /dev/random support
        +for earlier Solaris versions, see Sun's statement at
        +<URL: http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsrdb/27606&zone_32=SUNWski>
        +(the SUNWski package is available in patch 105710).
        +
        +On systems without /dev/urandom and /dev/random, it is a good idea to
        +use the Entropy Gathering Demon (EGD); see the RAND_egd() manpage for
        +details.  Starting with version 0.9.7, OpenSSL will automatically look
        +for an EGD socket at /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool and
        +/etc/entropy.
        +
        +Most components of the openssl command line utility automatically try
        +to seed the random number generator from a file.  The name of the
        +default seeding file is determined as follows: If environment variable
        +RANDFILE is set, then it names the seeding file.  Otherwise if
        +environment variable HOME is set, then the seeding file is $HOME/.rnd.
        +If neither RANDFILE nor HOME is set, versions up to OpenSSL 0.9.6 will
        +use file .rnd in the current directory while OpenSSL 0.9.6a uses no
        +default seeding file at all.  OpenSSL 0.9.6b and later will behave
        +similarly to 0.9.6a, but will use a default of "C:\" for HOME on
        +Windows systems if the environment variable has not been set.
        +
        +If the default seeding file does not exist or is too short, the "PRNG
        +not seeded" error message may occur.
        +
        +The openssl command line utility will write back a new state to the
        +default seeding file (and create this file if necessary) unless
        +there was no sufficient seeding.
        +
        +Pointing $RANDFILE to an Entropy Gathering Daemon socket does not work.
        +Use the "-rand" option of the OpenSSL command line tools instead.
        +The $RANDFILE environment variable and $HOME/.rnd are only used by the
        +OpenSSL command line tools. Applications using the OpenSSL library
        +provide their own configuration options to specify the entropy source,
        +please check out the documentation coming the with application.
        +
        +
        +* Why do I get an "unable to write 'random state'" error message?
        +
        +
        +Sometimes the openssl command line utility does not abort with
        +a "PRNG not seeded" error message, but complains that it is
        +"unable to write 'random state'".  This message refers to the
        +default seeding file (see previous answer).  A possible reason
        +is that no default filename is known because neither RANDFILE
        +nor HOME is set.  (Versions up to 0.9.6 used file ".rnd" in the
        +current directory in this case, but this has changed with 0.9.6a.)
        +
        +
        +* How do I create certificates or certificate requests?
        +
        +Check out the CA.pl(1) manual page. This provides a simple wrapper round
        +the 'req', 'verify', 'ca' and 'pkcs12' utilities. For finer control check
        +out the manual pages for the individual utilities and the certificate
        +extensions documentation (in ca(1), req(1), x509v3_config(5) )
        +
        +
        +* Why can't I create certificate requests?
        +
        +You typically get the error:
        +
        +	unable to find 'distinguished_name' in config
        +	problems making Certificate Request
        +
        +This is because it can't find the configuration file. Check out the
        +DIAGNOSTICS section of req(1) for more information.
        +
        +
        +* Why does <SSL program> fail with a certificate verify error?
        +
        +This problem is usually indicated by log messages saying something like
        +"unable to get local issuer certificate" or "self signed certificate".
        +When a certificate is verified its root CA must be "trusted" by OpenSSL
        +this typically means that the CA certificate must be placed in a directory
        +or file and the relevant program configured to read it. The OpenSSL program
        +'verify' behaves in a similar way and issues similar error messages: check
        +the verify(1) program manual page for more information.
        +
        +
        +* Why can I only use weak ciphers when I connect to a server using OpenSSL?
        +
        +This is almost certainly because you are using an old "export grade" browser
        +which only supports weak encryption. Upgrade your browser to support 128 bit
        +ciphers.
        +
        +
        +* How can I create DSA certificates?
        +
        +Check the CA.pl(1) manual page for a DSA certificate example.
        +
        +
        +* Why can't I make an SSL connection to a server using a DSA certificate?
        +
        +Typically you'll see a message saying there are no shared ciphers when
        +the same setup works fine with an RSA certificate. There are two possible
        +causes. The client may not support connections to DSA servers most web
        +browsers (including Netscape and MSIE) only support connections to servers
        +supporting RSA cipher suites. The other cause is that a set of DH parameters
        +has not been supplied to the server. DH parameters can be created with the
        +dhparam(1) command and loaded using the SSL_CTX_set_tmp_dh() for example:
        +check the source to s_server in apps/s_server.c for an example.
        +
        +
        +* How can I remove the passphrase on a private key?
        +
        +Firstly you should be really *really* sure you want to do this. Leaving
        +a private key unencrypted is a major security risk. If you decide that
        +you do have to do this check the EXAMPLES sections of the rsa(1) and
        +dsa(1) manual pages.
        +
        +
        +* Why can't I use OpenSSL certificates with SSL client authentication?
        +
        +What will typically happen is that when a server requests authentication
        +it will either not include your certificate or tell you that you have
        +no client certificates (Netscape) or present you with an empty list box
        +(MSIE). The reason for this is that when a server requests a client
        +certificate it includes a list of CAs names which it will accept. Browsers
        +will only let you select certificates from the list on the grounds that
        +there is little point presenting a certificate which the server will
        +reject.
        +
        +The solution is to add the relevant CA certificate to your servers "trusted
        +CA list". How you do this depends on the server software in uses. You can
        +print out the servers list of acceptable CAs using the OpenSSL s_client tool:
        +
        +openssl s_client -connect www.some.host:443 -prexit
        +
        +If your server only requests certificates on certain URLs then you may need
        +to manually issue an HTTP GET command to get the list when s_client connects:
        +
        +GET /some/page/needing/a/certificate.html
        +
        +If your CA does not appear in the list then this confirms the problem.
        +
        +
        +* Why does my browser give a warning about a mismatched hostname?
        +
        +Browsers expect the server's hostname to match the value in the commonName
        +(CN) field of the certificate. If it does not then you get a warning.
        +
        +
        +* How do I install a CA certificate into a browser?
        +
        +The usual way is to send the DER encoded certificate to the browser as
        +MIME type application/x-x509-ca-cert, for example by clicking on an appropriate
        +link. On MSIE certain extensions such as .der or .cacert may also work, or you
        +can import the certificate using the certificate import wizard.
        +
        +You can convert a certificate to DER form using the command:
        +
        +openssl x509 -in ca.pem -outform DER -out ca.der
        +
        +Occasionally someone suggests using a command such as:
        +
        +openssl pkcs12 -export -out cacert.p12 -in cacert.pem -inkey cakey.pem
        +
        +DO NOT DO THIS! This command will give away your CAs private key and
        +reduces its security to zero: allowing anyone to forge certificates in
        +whatever name they choose.
        +
        +* Why is OpenSSL x509 DN output not conformant to RFC2253?
        +
        +The ways to print out the oneline format of the DN (Distinguished Name) have
        +been extended in version 0.9.7 of OpenSSL. Using the new X509_NAME_print_ex()
        +interface, the "-nameopt" option could be introduded. See the manual
        +page of the "openssl x509" commandline tool for details. The old behaviour
        +has however been left as default for the sake of compatibility.
        +
        +* What is a "128 bit certificate"? Can I create one with OpenSSL?
        +
        +The term "128 bit certificate" is a highly misleading marketing term. It does
        +*not* refer to the size of the public key in the certificate! A certificate
        +containing a 128 bit RSA key would have negligible security.
        +
        +There were various other names such as "magic certificates", "SGC
        +certificates", "step up certificates" etc.
        +
        +You can't generally create such a certificate using OpenSSL but there is no
        +need to any more. Nowadays web browsers using unrestricted strong encryption
        +are generally available.
        +
        +When there were tight restrictions on the export of strong encryption
        +software from the US only weak encryption algorithms could be freely exported
        +(initially 40 bit and then 56 bit). It was widely recognised that this was
        +inadequate. A relaxation of the rules allowed the use of strong encryption but
        +only to an authorised server.
        +
        +Two slighly different techniques were developed to support this, one used by
        +Netscape was called "step up", the other used by MSIE was called "Server Gated
        +Cryptography" (SGC). When a browser initially connected to a server it would
        +check to see if the certificate contained certain extensions and was issued by
        +an authorised authority. If these test succeeded it would reconnect using
        +strong encryption.
        +
        +Only certain (initially one) certificate authorities could issue the
        +certificates and they generally cost more than ordinary certificates.
        +
        +Although OpenSSL can create certificates containing the appropriate extensions
        +the certificate would not come from a permitted authority and so would not
        +be recognized.
        +
        +The export laws were later changed to allow almost unrestricted use of strong
        +encryption so these certificates are now obsolete.
        +
        +
        +* Why does OpenSSL set the authority key identifier (AKID) extension incorrectly?
        +
        +It doesn't: this extension is often the cause of confusion.
        +
        +Consider a certificate chain A->B->C so that A signs B and B signs C. Suppose
        +certificate C contains AKID.
        +
        +The purpose of this extension is to identify the authority certificate B. This
        +can be done either by including the subject key identifier of B or its issuer
        +name and serial number.
        +
        +In this latter case because it is identifying certifcate B it must contain the
        +issuer name and serial number of B.
        +
        +It is often wrongly assumed that it should contain the subject name of B. If it
        +did this would be redundant information because it would duplicate the issuer
        +name of C.
        +
        +
        +* How can I set up a bundle of commercial root CA certificates?
        +
        +The OpenSSL software is shipped without any root CA certificate as the
        +OpenSSL project does not have any policy on including or excluding
        +any specific CA and does not intend to set up such a policy. Deciding
        +about which CAs to support is up to application developers or
        +administrators.
        +
        +Other projects do have other policies so you can for example extract the CA
        +bundle used by Mozilla and/or modssl as described in this article:
        +
        +  <URL: http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html>
        +
        +
        +[BUILD] =======================================================================
        +
        +* Why does the linker complain about undefined symbols?
        +
        +Maybe the compilation was interrupted, and make doesn't notice that
        +something is missing.  Run "make clean; make".
        +
        +If you used ./Configure instead of ./config, make sure that you
        +selected the right target.  File formats may differ slightly between
        +OS versions (for example sparcv8/sparcv9, or a.out/elf).
        +
        +In case you get errors about the following symbols, use the config
        +option "no-asm", as described in INSTALL:
        +
        + BF_cbc_encrypt, BF_decrypt, BF_encrypt, CAST_cbc_encrypt,
        + CAST_decrypt, CAST_encrypt, RC4, RC5_32_cbc_encrypt, RC5_32_decrypt,
        + RC5_32_encrypt, bn_add_words, bn_div_words, bn_mul_add_words,
        + bn_mul_comba4, bn_mul_comba8, bn_mul_words, bn_sqr_comba4,
        + bn_sqr_comba8, bn_sqr_words, bn_sub_words, des_decrypt3,
        + des_ede3_cbc_encrypt, des_encrypt, des_encrypt2, des_encrypt3,
        + des_ncbc_encrypt, md5_block_asm_host_order, sha1_block_asm_data_order
        +
        +If none of these helps, you may want to try using the current snapshot.
        +If the problem persists, please submit a bug report.
        +
        +
        +* Why does the OpenSSL test fail with "bc: command not found"?
        +
        +You didn't install "bc", the Unix calculator.  If you want to run the
        +tests, get GNU bc from ftp://ftp.gnu.org or from your OS distributor.
        +
        +
        +* Why does the OpenSSL test fail with "bc: 1 no implemented"?
        +
        +On some SCO installations or versions, bc has a bug that gets triggered
        +when you run the test suite (using "make test").  The message returned is
        +"bc: 1 not implemented".
        +
        +The best way to deal with this is to find another implementation of bc
        +and compile/install it.  GNU bc (see <URL: http://www.gnu.org/software/software.html>
        +for download instructions) can be safely used, for example.
        +
        +
        +* Why does the OpenSSL test fail with "bc: stack empty"?
        +
        +On some DG/ux versions, bc seems to have a too small stack for calculations
        +that the OpenSSL bntest throws at it.  This gets triggered when you run the
        +test suite (using "make test").  The message returned is "bc: stack empty".
        +
        +The best way to deal with this is to find another implementation of bc
        +and compile/install it.  GNU bc (see <URL: http://www.gnu.org/software/software.html>
        +for download instructions) can be safely used, for example.
        +
        +
        +* Why does the OpenSSL compilation fail on Alpha Tru64 Unix?
        +
        +On some Alpha installations running Tru64 Unix and Compaq C, the compilation
        +of crypto/sha/sha_dgst.c fails with the message 'Fatal:  Insufficient virtual
        +memory to continue compilation.'  As far as the tests have shown, this may be
        +a compiler bug.  What happens is that it eats up a lot of resident memory
        +to build something, probably a table.  The problem is clearly in the
        +optimization code, because if one eliminates optimization completely (-O0),
        +the compilation goes through (and the compiler consumes about 2MB of resident
        +memory instead of 240MB or whatever one's limit is currently).
        +
        +There are three options to solve this problem:
        +
        +1. set your current data segment size soft limit higher.  Experience shows
        +that about 241000 kbytes seems to be enough on an AlphaServer DS10.  You do
        +this with the command 'ulimit -Sd nnnnnn', where 'nnnnnn' is the number of
        +kbytes to set the limit to.
        +
        +2. If you have a hard limit that is lower than what you need and you can't
        +get it changed, you can compile all of OpenSSL with -O0 as optimization
        +level.  This is however not a very nice thing to do for those who expect to
        +get the best result from OpenSSL.  A bit more complicated solution is the
        +following:
        +
        +----- snip:start -----
        +  make DIRS=crypto SDIRS=sha "`grep '^CFLAG=' Makefile.ssl | \
        +       sed -e 's/ -O[0-9] / -O0 /'`"
        +  rm `ls crypto/*.o crypto/sha/*.o | grep -v 'sha_dgst\.o'`
        +  make
        +----- snip:end -----
        +
        +This will only compile sha_dgst.c with -O0, the rest with the optimization
        +level chosen by the configuration process.  When the above is done, do the
        +test and installation and you're set.
        +
        +3. Reconfigure the toolkit with no-sha0 option to leave out SHA0. It 
        +should not be used and is not used in SSL/TLS nor any other recognized
        +protocol in either case.
        +
        +
        +* Why does the OpenSSL compilation fail with "ar: command not found"?
        +
        +Getting this message is quite usual on Solaris 2, because Sun has hidden
        +away 'ar' and other development commands in directories that aren't in
        +$PATH by default.  One of those directories is '/usr/ccs/bin'.  The
        +quickest way to fix this is to do the following (it assumes you use sh
        +or any sh-compatible shell):
        +
        +----- snip:start -----
        +  PATH=${PATH}:/usr/ccs/bin; export PATH
        +----- snip:end -----
        +
        +and then redo the compilation.  What you should really do is make sure
        +'/usr/ccs/bin' is permanently in your $PATH, for example through your
        +'.profile' (again, assuming you use a sh-compatible shell).
        +
        +
        +* Why does the OpenSSL compilation fail on Win32 with VC++?
        +
        +Sometimes, you may get reports from VC++ command line (cl) that it
        +can't find standard include files like stdio.h and other weirdnesses.
        +One possible cause is that the environment isn't correctly set up.
        +To solve that problem for VC++ versions up to 6, one should run
        +VCVARS32.BAT which is found in the 'bin' subdirectory of the VC++
        +installation directory (somewhere under 'Program Files').  For VC++
        +version 7 (and up?), which is also called VS.NET, the file is called
        +VSVARS32.BAT instead.
        +This needs to be done prior to running NMAKE, and the changes are only
        +valid for the current DOS session.
        +
        +
        +* What is special about OpenSSL on Redhat?
        +
        +Red Hat Linux (release 7.0 and later) include a preinstalled limited
        +version of OpenSSL. For patent reasons, support for IDEA, RC5 and MDC2
        +is disabled in this version. The same may apply to other Linux distributions.
        +Users may therefore wish to install more or all of the features left out.
        +
        +To do this you MUST ensure that you do not overwrite the openssl that is in
        +/usr/bin on your Red Hat machine. Several packages depend on this file,
        +including sendmail and ssh. /usr/local/bin is a good alternative choice. The
        +libraries that come with Red Hat 7.0 onwards have different names and so are
        +not affected. (eg For Red Hat 7.2 they are /lib/libssl.so.0.9.6b and
        +/lib/libcrypto.so.0.9.6b with symlinks /lib/libssl.so.2 and
        +/lib/libcrypto.so.2 respectively).
        +
        +Please note that we have been advised by Red Hat attempting to recompile the
        +openssl rpm with all the cryptography enabled will not work. All other
        +packages depend on the original Red Hat supplied openssl package. It is also
        +worth noting that due to the way Red Hat supplies its packages, updates to
        +openssl on each distribution never change the package version, only the
        +build number. For example, on Red Hat 7.1, the latest openssl package has
        +version number 0.9.6 and build number 9 even though it contains all the
        +relevant updates in packages up to and including 0.9.6b.
        +
        +A possible way around this is to persuade Red Hat to produce a non-US
        +version of Red Hat Linux.
        +
        +FYI: Patent numbers and expiry dates of US patents:
        +MDC-2: 4,908,861 13/03/2007
        +IDEA:  5,214,703 25/05/2010
        +RC5:   5,724,428 03/03/2015
        +
        +
        +* Why does the OpenSSL compilation fail on MacOS X?
        +
        +If the failure happens when trying to build the "openssl" binary, with
        +a large number of undefined symbols, it's very probable that you have
        +OpenSSL 0.9.6b delivered with the operating system (you can find out by
        +running '/usr/bin/openssl version') and that you were trying to build
        +OpenSSL 0.9.7 or newer.  The problem is that the loader ('ld') in
        +MacOS X has a misfeature that's quite difficult to go around.
        +Look in the file PROBLEMS for a more detailed explanation and for possible
        +solutions.
        +
        +
        +* Why does the OpenSSL test suite fail on MacOS X?
        +
        +If the failure happens when running 'make test' and the RC4 test fails,
        +it's very probable that you have OpenSSL 0.9.6b delivered with the
        +operating system (you can find out by running '/usr/bin/openssl version')
        +and that you were trying to build OpenSSL 0.9.6d.  The problem is that
        +the loader ('ld') in MacOS X has a misfeature that's quite difficult to
        +go around and has linked the programs "openssl" and the test programs
        +with /usr/lib/libcrypto.dylib and /usr/lib/libssl.dylib instead of the
        +libraries you just built.
        +Look in the file PROBLEMS for a more detailed explanation and for possible
        +solutions.
        +
        +* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
        +
        +Failure in BN_sqr test is most likely caused by a failure to configure the
        +toolkit for current platform or lack of support for the platform in question.
        +Run './config -t' and './apps/openssl version -p'. Do these platform
        +identifiers match? If they don't, then you most likely failed to run
        +./config and you're hereby advised to do so before filing a bug report.
        +If ./config itself fails to run, then it's most likely problem with your
        +local environment and you should turn to your system administrator (or
        +similar). If identifiers match (and/or no alternative identifier is
        +suggested by ./config script), then the platform is unsupported. There might
        +or might not be a workaround. Most notably on SPARC64 platforms with GNU
        +C compiler you should be able to produce a working build by running
        +'./config -m32'. I understand that -m32 might not be what you want/need,
        +but the build should be operational. For further details turn to
        +<openssl-dev@openssl.org>.
        +
        +* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
        +
        +As of 0.9.7 assembler routines were overhauled for position independence
        +of the machine code, which is essential for shared library support. For
        +some reason OpenBSD is equipped with an out-of-date GNU assembler which
        +finds the new code offensive. To work around the problem, configure with
        +no-asm (and sacrifice a great deal of performance) or patch your assembler
        +according to <URL: http://www.openssl.org/~appro/gas-1.92.3.OpenBSD.patch>.
        +For your convenience a pre-compiled replacement binary is provided at
        +<URL: http://www.openssl.org/~appro/gas-1.92.3.static.aout.bin>.
        +Reportedly elder *BSD a.out platforms also suffer from this problem and
        +remedy should be same. Provided binary is statically linked and should be
        +working across wider range of *BSD branches, not just OpenBSD.
        +
        +* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
        +
        +If the test program in question fails withs SIGILL, Illegal Instruction
        +exception, then you more than likely to run SSE2-capable CPU, such as
        +Intel P4, under control of kernel which does not support SSE2
        +instruction extentions. See accompanying INSTALL file and
        +OPENSSL_ia32cap(3) documentation page for further information.
        +
        +* Why does compiler fail to compile sha512.c?
        +
        +OpenSSL SHA-512 implementation depends on compiler support for 64-bit
        +integer type. Few elder compilers [ULTRIX cc, SCO compiler to mention a
        +couple] lack support for this and therefore are incapable of compiling
        +the module in question. The recommendation is to disable SHA-512 by
        +adding no-sha512 to ./config [or ./Configure] command line. Another
        +possible alternative might be to switch to GCC.
        +
        +* Test suite still fails, what to do?
        +
        +Another common reason for failure to complete some particular test is
        +simply bad code generated by a buggy component in toolchain or deficiency
        +in run-time environment. There are few cases documented in PROBLEMS file,
        +consult it for possible workaround before you beat the drum. Even if you
        +don't find solution or even mention there, do reserve for possibility of
        +a compiler bug. Compiler bugs might appear in rather bizarre ways, they
        +never make sense, and tend to emerge when you least expect them. In order
        +to identify one, drop optimization level, e.g. by editing CFLAG line in
        +top-level Makefile, recompile and re-run the test.
        +
        +* I think I've found a bug, what should I do?
        +
        +If you are a new user then it is quite likely you haven't found a bug and
        +something is happening you aren't familiar with. Check this FAQ, the associated
        +documentation and the mailing lists for similar queries. If you are still
        +unsure whether it is a bug or not submit a query to the openssl-users mailing
        +list.
        +
        +
        +* I'm SURE I've found a bug, how do I report it?
        +
        +Bug reports with no security implications should be sent to the request
        +tracker. This can be done by mailing the report to <rt@openssl.org> (or its
        +alias <openssl-bugs@openssl.org>), please note that messages sent to the
        +request tracker also appear in the public openssl-dev mailing list.
        +
        +The report should be in plain text. Any patches should be sent as
        +plain text attachments because some mailers corrupt patches sent inline.
        +If your issue affects multiple versions of OpenSSL check any patches apply
        +cleanly and, if possible include patches to each affected version.
        +
        +The report should be given a meaningful subject line briefly summarising the
        +issue. Just "bug in OpenSSL" or "bug in OpenSSL 0.9.8n" is not very helpful.
        +
        +By sending reports to the request tracker the bug can then be given a priority
        +and assigned to the appropriate maintainer. The history of discussions can be
        +accessed and if the issue has been addressed or a reason why not. If patches
        +are only sent to openssl-dev they can be mislaid if a team member has to
        +wade through months of old messages to review the discussion.
        +
        +See also <URL: http://www.openssl.org/support/rt.html>
        +
        +
        +* I've found a security issue, how do I report it?
        +
        +If you think your bug has security implications then please send it to
        +openssl-security@openssl.org if you don't get a prompt reply at least 
        +acknowledging receipt then resend or mail it directly to one of the
        +more active team members (e.g. Steve).
        +
        +[PROG] ========================================================================
        +
        +* Is OpenSSL thread-safe?
        +
        +Yes (with limitations: an SSL connection may not concurrently be used
        +by multiple threads).  On Windows and many Unix systems, OpenSSL
        +automatically uses the multi-threaded versions of the standard
        +libraries.  If your platform is not one of these, consult the INSTALL
        +file.
        +
        +Multi-threaded applications must provide two callback functions to
        +OpenSSL by calling CRYPTO_set_locking_callback() and
        +CRYPTO_set_id_callback(), for all versions of OpenSSL up to and
        +including 0.9.8[abc...]. As of version 1.0.0, CRYPTO_set_id_callback()
        +and associated APIs are deprecated by CRYPTO_THREADID_set_callback()
        +and friends. This is described in the threads(3) manpage.
        +
        +* I've compiled a program under Windows and it crashes: why?
        +
        +This is usually because you've missed the comment in INSTALL.W32.
        +Your application must link against the same version of the Win32
        +C-Runtime against which your openssl libraries were linked.  The
        +default version for OpenSSL is /MD - "Multithreaded DLL".
        +
        +If you are using Microsoft Visual C++'s IDE (Visual Studio), in
        +many cases, your new project most likely defaulted to "Debug
        +Singlethreaded" - /ML.  This is NOT interchangeable with /MD and your
        +program will crash, typically on the first BIO related read or write
        +operation.
        +
        +For each of the six possible link stage configurations within Win32,
        +your application must link  against the same by which OpenSSL was
        +built.  If you are using MS Visual C++ (Studio) this can be changed
        +by:
        +
        + 1. Select Settings... from the Project Menu.
        + 2. Select the C/C++ Tab.
        + 3. Select "Code Generation from the "Category" drop down list box
        + 4. Select the Appropriate library (see table below) from the "Use
        +    run-time library" drop down list box.  Perform this step for both
        +    your debug and release versions of your application (look at the
        +    top left of the settings panel to change between the two)
        +
        +    Single Threaded           /ML        -  MS VC++ often defaults to
        +                                            this for the release
        +                                            version of a new project.
        +    Debug Single Threaded     /MLd       -  MS VC++ often defaults to
        +                                            this for the debug version
        +                                            of a new project.
        +    Multithreaded             /MT
        +    Debug Multithreaded       /MTd
        +    Multithreaded DLL         /MD        -  OpenSSL defaults to this.
        +    Debug Multithreaded DLL   /MDd
        +
        +Note that debug and release libraries are NOT interchangeable.  If you
        +built OpenSSL with /MD your application must use /MD and cannot use /MDd.
        +
        +As per 0.9.8 the above limitation is eliminated for .DLLs. OpenSSL
        +.DLLs compiled with some specific run-time option [we insist on the
        +default /MD] can be deployed with application compiled with different
        +option or even different compiler. But there is a catch! Instead of
        +re-compiling OpenSSL toolkit, as you would have to with prior versions,
        +you have to compile small C snippet with compiler and/or options of
        +your choice. The snippet gets installed as
        +<install-root>/include/openssl/applink.c and should be either added to
        +your application project or simply #include-d in one [and only one]
        +of your application source files. Failure to link this shim module
        +into your application manifests itself as fatal "no OPENSSL_Applink"
        +run-time error. An explicit reminder is due that in this situation
        +[mixing compiler options] it is as important to add CRYPTO_malloc_init
        +prior first call to OpenSSL.
        +
        +* How do I read or write a DER encoded buffer using the ASN1 functions?
        +
        +You have two options. You can either use a memory BIO in conjunction
        +with the i2d_*_bio() or d2i_*_bio() functions or you can use the
        +i2d_*(), d2i_*() functions directly. Since these are often the
        +cause of grief here are some code fragments using PKCS7 as an example:
        +
        + unsigned char *buf, *p;
        + int len;
        +
        + len = i2d_PKCS7(p7, NULL);
        + buf = OPENSSL_malloc(len); /* or Malloc, error checking omitted */
        + p = buf;
        + i2d_PKCS7(p7, &p);
        +
        +At this point buf contains the len bytes of the DER encoding of
        +p7.
        +
        +The opposite assumes we already have len bytes in buf:
        +
        + unsigned char *p;
        + p = buf;
        + p7 = d2i_PKCS7(NULL, &p, len);
        +
        +At this point p7 contains a valid PKCS7 structure of NULL if an error
        +occurred. If an error occurred ERR_print_errors(bio) should give more
        +information.
        +
        +The reason for the temporary variable 'p' is that the ASN1 functions
        +increment the passed pointer so it is ready to read or write the next
        +structure. This is often a cause of problems: without the temporary
        +variable the buffer pointer is changed to point just after the data
        +that has been read or written. This may well be uninitialized data
        +and attempts to free the buffer will have unpredictable results
        +because it no longer points to the same address.
        +
        +
        +* OpenSSL uses DER but I need BER format: does OpenSSL support BER?
        +
        +The short answer is yes, because DER is a special case of BER and OpenSSL
        +ASN1 decoders can process BER.
        +
        +The longer answer is that ASN1 structures can be encoded in a number of
        +different ways. One set of ways is the Basic Encoding Rules (BER) with various
        +permissible encodings. A restriction of BER is the Distinguished Encoding
        +Rules (DER): these uniquely specify how a given structure is encoded.
        +
        +Therefore, because DER is a special case of BER, DER is an acceptable encoding
        +for BER.
        +
        +
        +* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
        +
        +This usually happens when you try compiling something using the PKCS#12
        +macros with a C++ compiler. There is hardly ever any need to use the
        +PKCS#12 macros in a program, it is much easier to parse and create
        +PKCS#12 files using the PKCS12_parse() and PKCS12_create() functions
        +documented in doc/openssl.txt and with examples in demos/pkcs12. The
        +'pkcs12' application has to use the macros because it prints out 
        +debugging information.
        +
        +
        +* I've called <some function> and it fails, why?
        +
        +Before submitting a report or asking in one of the mailing lists, you
        +should try to determine the cause. In particular, you should call
        +ERR_print_errors() or ERR_print_errors_fp() after the failed call
        +and see if the message helps. Note that the problem may occur earlier
        +than you think -- you should check for errors after every call where
        +it is possible, otherwise the actual problem may be hidden because
        +some OpenSSL functions clear the error state.
        +
        +
        +* I just get a load of numbers for the error output, what do they mean?
        +
        +The actual format is described in the ERR_print_errors() manual page.
        +You should call the function ERR_load_crypto_strings() before hand and
        +the message will be output in text form. If you can't do this (for example
        +it is a pre-compiled binary) you can use the errstr utility on the error
        +code itself (the hex digits after the second colon).
        +
        +
        +* Why do I get errors about unknown algorithms?
        +
        +The cause is forgetting to load OpenSSL's table of algorithms with
        +OpenSSL_add_all_algorithms(). See the manual page for more information. This
        +can cause several problems such as being unable to read in an encrypted
        +PEM file, unable to decrypt a PKCS#12 file or signature failure when
        +verifying certificates.
        +
        +* Why can't the OpenSSH configure script detect OpenSSL?
        +
        +Several reasons for problems with the automatic detection exist.
        +OpenSSH requires at least version 0.9.5a of the OpenSSL libraries.
        +Sometimes the distribution has installed an older version in the system
        +locations that is detected instead of a new one installed. The OpenSSL
        +library might have been compiled for another CPU or another mode (32/64 bits).
        +Permissions might be wrong.
        +
        +The general answer is to check the config.log file generated when running
        +the OpenSSH configure script. It should contain the detailed information
        +on why the OpenSSL library was not detected or considered incompatible.
        +
        +
        +* Can I use OpenSSL's SSL library with non-blocking I/O?
        +
        +Yes; make sure to read the SSL_get_error(3) manual page!
        +
        +A pitfall to avoid: Don't assume that SSL_read() will just read from
        +the underlying transport or that SSL_write() will just write to it --
        +it is also possible that SSL_write() cannot do any useful work until
        +there is data to read, or that SSL_read() cannot do anything until it
        +is possible to send data.  One reason for this is that the peer may
        +request a new TLS/SSL handshake at any time during the protocol,
        +requiring a bi-directional message exchange; both SSL_read() and
        +SSL_write() will try to continue any pending handshake.
        +
        +
        +* Why doesn't my server application receive a client certificate?
        +
        +Due to the TLS protocol definition, a client will only send a certificate,
        +if explicitly asked by the server. Use the SSL_VERIFY_PEER flag of the
        +SSL_CTX_set_verify() function to enable the use of client certificates.
        +
        +
        +* Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?
        +
        +For OpenSSL 0.9.7 the OID table was extended and corrected. In earlier
        +versions, uniqueIdentifier was incorrectly used for X.509 certificates.
        +The correct name according to RFC2256 (LDAP) is x500UniqueIdentifier.
        +Change your code to use the new name when compiling against OpenSSL 0.9.7.
        +
        +
        +* I think I've detected a memory leak, is this a bug?
        +
        +In most cases the cause of an apparent memory leak is an OpenSSL internal table
        +that is allocated when an application starts up. Since such tables do not grow
        +in size over time they are harmless.
        +
        +These internal tables can be freed up when an application closes using various
        +functions.  Currently these include following:
        +
        +Thread-local cleanup functions:
        +
        +  ERR_remove_state()
        +
        +Application-global cleanup functions that are aware of usage (and therefore
        +thread-safe):
        +
        +  ENGINE_cleanup() and CONF_modules_unload()
        +
        +"Brutal" (thread-unsafe) Application-global cleanup functions:
        +
        +  ERR_free_strings(), EVP_cleanup() and CRYPTO_cleanup_all_ex_data().
        +
        +
        +* Why does Valgrind complain about the use of uninitialized data?
        +
        +When OpenSSL's PRNG routines are called to generate random numbers the supplied
        +buffer contents are mixed into the entropy pool: so it technically does not
        +matter whether the buffer is initialized at this point or not.  Valgrind (and
        +other test tools) will complain about this. When using Valgrind, make sure the
        +OpenSSL library has been compiled with the PURIFY macro defined (-DPURIFY)
        +to get rid of these warnings.
        +
        +
        +* Why doesn't a memory BIO work when a file does?
        +
        +This can occur in several cases for example reading an S/MIME email message.
        +The reason is that a memory BIO can do one of two things when all the data
        +has been read from it.
        +
        +The default behaviour is to indicate that no more data is available and that
        +the call should be retried, this is to allow the application to fill up the BIO
        +again if necessary.
        +
        +Alternatively it can indicate that no more data is available and that EOF has
        +been reached.
        +
        +If a memory BIO is to behave in the same way as a file this second behaviour
        +is needed. This must be done by calling:
        +
        +   BIO_set_mem_eof_return(bio, 0);
        +
        +See the manual pages for more details.
        +
        +
        +* Where are the declarations and implementations of d2i_X509() etc?
        +
        +These are defined and implemented by macros of the form:
        +
        +
        + DECLARE_ASN1_FUNCTIONS(X509) and IMPLEMENT_ASN1_FUNCTIONS(X509)
        +
        +The implementation passes an ASN1 "template" defining the structure into an
        +ASN1 interpreter using generalised functions such as ASN1_item_d2i().
        +
        +
        +===============================================================================
        diff --git a/vendor/openssl/openssl/INSTALL b/vendor/openssl/openssl/INSTALL
        new file mode 100644
        index 000000000..1325079f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL
        @@ -0,0 +1,360 @@
        +
        + INSTALLATION ON THE UNIX PLATFORM
        + ---------------------------------
        +
        + [Installation on DOS (with djgpp), Windows, OpenVMS, MacOS (before MacOS X)
        +  and NetWare is described in INSTALL.DJGPP, INSTALL.W32, INSTALL.VMS,
        +  INSTALL.MacOS and INSTALL.NW.
        +  
        +  This document describes installation on operating systems in the Unix
        +  family.]
        +
        + To install OpenSSL, you will need:
        +
        +  * make
        +  * Perl 5
        +  * an ANSI C compiler
        +  * a development environment in form of development libraries and C
        +    header files
        +  * a supported Unix operating system
        +
        + Quick Start
        + -----------
        +
        + If you want to just get on with it, do:
        +
        +  $ ./config
        +  $ make
        +  $ make test
        +  $ make install
        +
        + [If any of these steps fails, see section Installation in Detail below.]
        +
        + This will build and install OpenSSL in the default location, which is (for
        + historical reasons) /usr/local/ssl. If you want to install it anywhere else,
        + run config like this:
        +
        +  $ ./config --prefix=/usr/local --openssldir=/usr/local/openssl
        +
        +
        + Configuration Options
        + ---------------------
        +
        + There are several options to ./config (or ./Configure) to customize
        + the build:
        +
        +  --prefix=DIR  Install in DIR/bin, DIR/lib, DIR/include/openssl.
        +	        Configuration files used by OpenSSL will be in DIR/ssl
        +                or the directory specified by --openssldir.
        +
        +  --openssldir=DIR Directory for OpenSSL files. If no prefix is specified,
        +                the library files and binaries are also installed there.
        +
        +  no-threads    Don't try to build with support for multi-threaded
        +                applications.
        +
        +  threads       Build with support for multi-threaded applications.
        +                This will usually require additional system-dependent options!
        +                See "Note on multi-threading" below.
        +
        +  no-zlib       Don't try to build with support for zlib compression and
        +                decompression.
        +
        +  zlib          Build with support for zlib compression/decompression.
        +
        +  zlib-dynamic  Like "zlib", but has OpenSSL load the zlib library dynamically
        +                when needed.  This is only supported on systems where loading
        +                of shared libraries is supported.  This is the default choice.
        +
        +  no-shared     Don't try to create shared libraries.
        +
        +  shared        In addition to the usual static libraries, create shared
        +                libraries on platforms where it's supported.  See "Note on
        +                shared libraries" below.
        +
        +  no-asm        Do not use assembler code.
        +
        +  386           Use the 80386 instruction set only (the default x86 code is
        +                more efficient, but requires at least a 486). Note: Use
        +                compiler flags for any other CPU specific configuration,
        +                e.g. "-m32" to build x86 code on an x64 system.
        +
        +  no-sse2	Exclude SSE2 code pathes. Normally SSE2 extention is
        +		detected at run-time, but the decision whether or not the
        +		machine code will be executed is taken solely on CPU
        +		capability vector. This means that if you happen to run OS
        +		kernel which does not support SSE2 extension on Intel P4
        +		processor, then your application might be exposed to
        +		"illegal instruction" exception. There might be a way
        +		to enable support in kernel, e.g. FreeBSD kernel can be
        +		compiled with CPU_ENABLE_SSE, and there is a way to
        +		disengage SSE2 code pathes upon application start-up,
        +		but if you aim for wider "audience" running such kernel,
        +		consider no-sse2. Both 386 and no-asm options above imply
        +		no-sse2.
        +
        +  no-<cipher>   Build without the specified cipher (bf, cast, des, dh, dsa,
        +                hmac, md2, md5, mdc2, rc2, rc4, rc5, rsa, sha).
        +                The crypto/<cipher> directory can be removed after running
        +                "make depend".
        +
        +  -Dxxx, -lxxx, -Lxxx, -fxxx, -mXXX, -Kxxx These system specific options will
        +                be passed through to the compiler to allow you to
        +                define preprocessor symbols, specify additional libraries,
        +                library directories or other compiler options.
        +
        +  -DHAVE_CRYPTODEV Enable the BSD cryptodev engine even if we are not using
        +		BSD. Useful if you are running ocf-linux or something
        +		similar. Once enabled you can also enable the use of
        +		cryptodev digests, which is usually slower unless you have
        +		large amounts data. Use -DUSE_CRYPTODEV_DIGESTS to force
        +		it.
        +
        + Installation in Detail
        + ----------------------
        +
        + 1a. Configure OpenSSL for your operation system automatically:
        +
        +       $ ./config [options]
        +
        +     This guesses at your operating system (and compiler, if necessary) and
        +     configures OpenSSL based on this guess. Run ./config -t to see
        +     if it guessed correctly. If you want to use a different compiler, you
        +     are cross-compiling for another platform, or the ./config guess was
        +     wrong for other reasons, go to step 1b. Otherwise go to step 2.
        +
        +     On some systems, you can include debugging information as follows:
        +
        +       $ ./config -d [options]
        +
        + 1b. Configure OpenSSL for your operating system manually
        +
        +     OpenSSL knows about a range of different operating system, hardware and
        +     compiler combinations. To see the ones it knows about, run
        +
        +       $ ./Configure
        +
        +     Pick a suitable name from the list that matches your system. For most
        +     operating systems there is a choice between using "cc" or "gcc".  When
        +     you have identified your system (and if necessary compiler) use this name
        +     as the argument to ./Configure. For example, a "linux-elf" user would
        +     run:
        +
        +       $ ./Configure linux-elf [options]
        +
        +     If your system is not available, you will have to edit the Configure
        +     program and add the correct configuration for your system. The
        +     generic configurations "cc" or "gcc" should usually work on 32 bit
        +     systems.
        +
        +     Configure creates the file Makefile.ssl from Makefile.org and
        +     defines various macros in crypto/opensslconf.h (generated from
        +     crypto/opensslconf.h.in).
        +
        +  2. Build OpenSSL by running:
        +
        +       $ make
        +
        +     This will build the OpenSSL libraries (libcrypto.a and libssl.a) and the
        +     OpenSSL binary ("openssl"). The libraries will be built in the top-level
        +     directory, and the binary will be in the "apps" directory.
        +
        +     If "make" fails, look at the output.  There may be reasons for
        +     the failure that aren't problems in OpenSSL itself (like missing
        +     standard headers).  If it is a problem with OpenSSL itself, please
        +     report the problem to <openssl-bugs@openssl.org> (note that your
        +     message will be recorded in the request tracker publicly readable
        +     via http://www.openssl.org/support/rt.html and will be forwarded to a
        +     public mailing list). Include the output of "make report" in your message.
        +     Please check out the request tracker. Maybe the bug was already
        +     reported or has already been fixed.
        +
        +     [If you encounter assembler error messages, try the "no-asm"
        +     configuration option as an immediate fix.]
        +
        +     Compiling parts of OpenSSL with gcc and others with the system
        +     compiler will result in unresolved symbols on some systems.
        +
        +  3. After a successful build, the libraries should be tested. Run:
        +
        +       $ make test
        +
        +     If a test fails, look at the output.  There may be reasons for
        +     the failure that isn't a problem in OpenSSL itself (like a missing
        +     or malfunctioning bc).  If it is a problem with OpenSSL itself,
        +     try removing any compiler optimization flags from the CFLAG line
        +     in Makefile.ssl and run "make clean; make". Please send a bug
        +     report to <openssl-bugs@openssl.org>, including the output of
        +     "make report" in order to be added to the request tracker at
        +     http://www.openssl.org/support/rt.html.
        +
        +  4. If everything tests ok, install OpenSSL with
        +
        +       $ make install
        +
        +     This will create the installation directory (if it does not exist) and
        +     then the following subdirectories:
        +
        +       certs           Initially empty, this is the default location
        +                       for certificate files.
        +       man/man1        Manual pages for the 'openssl' command line tool
        +       man/man3        Manual pages for the libraries (very incomplete)
        +       misc            Various scripts.
        +       private         Initially empty, this is the default location
        +                       for private key files.
        +
        +     If you didn't choose a different installation prefix, the
        +     following additional subdirectories will be created:
        +
        +       bin             Contains the openssl binary and a few other 
        +                       utility programs. 
        +       include/openssl Contains the header files needed if you want to
        +                       compile programs with libcrypto or libssl.
        +       lib             Contains the OpenSSL library files themselves.
        +
        +     Use "make install_sw" to install the software without documentation,
        +     and "install_docs_html" to install HTML renditions of the manual
        +     pages.
        +
        +     Package builders who want to configure the library for standard
        +     locations, but have the package installed somewhere else so that
        +     it can easily be packaged, can use
        +
        +       $ make INSTALL_PREFIX=/tmp/package-root install
        +
        +     (or specify "--install_prefix=/tmp/package-root" as a configure
        +     option).  The specified prefix will be prepended to all
        +     installation target filenames.
        +
        +
        +  NOTE: The header files used to reside directly in the include
        +  directory, but have now been moved to include/openssl so that
        +  OpenSSL can co-exist with other libraries which use some of the
        +  same filenames.  This means that applications that use OpenSSL
        +  should now use C preprocessor directives of the form
        +
        +       #include <openssl/ssl.h>
        +
        +  instead of "#include <ssl.h>", which was used with library versions
        +  up to OpenSSL 0.9.2b.
        +
        +  If you install a new version of OpenSSL over an old library version,
        +  you should delete the old header files in the include directory.
        +
        +  Compatibility issues:
        +
        +  *  COMPILING existing applications
        +
        +     To compile an application that uses old filenames -- e.g.
        +     "#include <ssl.h>" --, it will usually be enough to find
        +     the CFLAGS definition in the application's Makefile and
        +     add a C option such as
        +
        +          -I/usr/local/ssl/include/openssl
        +
        +     to it.
        +
        +     But don't delete the existing -I option that points to
        +     the ..../include directory!  Otherwise, OpenSSL header files
        +     could not #include each other.
        +
        +  *  WRITING applications
        +
        +     To write an application that is able to handle both the new
        +     and the old directory layout, so that it can still be compiled
        +     with library versions up to OpenSSL 0.9.2b without bothering
        +     the user, you can proceed as follows:
        +
        +     -  Always use the new filename of OpenSSL header files,
        +        e.g. #include <openssl/ssl.h>.
        +
        +     -  Create a directory "incl" that contains only a symbolic
        +        link named "openssl", which points to the "include" directory
        +        of OpenSSL.
        +        For example, your application's Makefile might contain the
        +        following rule, if OPENSSLDIR is a pathname (absolute or
        +        relative) of the directory where OpenSSL resides:
        +
        +        incl/openssl:
        +        	-mkdir incl
        +        	cd $(OPENSSLDIR) # Check whether the directory really exists
        +        	-ln -s `cd $(OPENSSLDIR); pwd`/include incl/openssl
        +
        +        You will have to add "incl/openssl" to the dependencies
        +        of those C files that include some OpenSSL header file.
        +
        +     -  Add "-Iincl" to your CFLAGS.
        +
        +     With these additions, the OpenSSL header files will be available
        +     under both name variants if an old library version is used:
        +     Your application can reach them under names like <openssl/foo.h>,
        +     while the header files still are able to #include each other
        +     with names of the form <foo.h>.
        +
        +
        + Note on multi-threading
        + -----------------------
        +
        + For some systems, the OpenSSL Configure script knows what compiler options
        + are needed to generate a library that is suitable for multi-threaded
        + applications.  On these systems, support for multi-threading is enabled
        + by default; use the "no-threads" option to disable (this should never be
        + necessary).
        +
        + On other systems, to enable support for multi-threading, you will have
        + to specify at least two options: "threads", and a system-dependent option.
        + (The latter is "-D_REENTRANT" on various systems.)  The default in this
        + case, obviously, is not to include support for multi-threading (but
        + you can still use "no-threads" to suppress an annoying warning message
        + from the Configure script.)
        +
        +
        + Note on shared libraries
        + ------------------------
        +
        + Shared libraries have certain caveats.  Binary backward compatibility
        + can't be guaranteed before OpenSSL version 1.0.  The only reason to
        + use them would be to conserve memory on systems where several programs
        + are using OpenSSL.
        +
        + For some systems, the OpenSSL Configure script knows what is needed to
        + build shared libraries for libcrypto and libssl.  On these systems,
        + the shared libraries are currently not created by default, but giving
        + the option "shared" will get them created.  This method supports Makefile
        + targets for shared library creation, like linux-shared.  Those targets
        + can currently be used on their own just as well, but this is expected
        + to change in future versions of OpenSSL.
        +
        + Note on random number generation
        + --------------------------------
        +
        + Availability of cryptographically secure random numbers is required for
        + secret key generation. OpenSSL provides several options to seed the
        + internal PRNG. If not properly seeded, the internal PRNG will refuse
        + to deliver random bytes and a "PRNG not seeded error" will occur.
        + On systems without /dev/urandom (or similar) device, it may be necessary
        + to install additional support software to obtain random seed.
        + Please check out the manual pages for RAND_add(), RAND_bytes(), RAND_egd(),
        + and the FAQ for more information.
        +
        + Note on support for multiple builds
        + -----------------------------------
        +
        + OpenSSL is usually built in its source tree.  Unfortunately, this doesn't
        + support building for multiple platforms from the same source tree very well.
        + It is however possible to build in a separate tree through the use of lots
        + of symbolic links, which should be prepared like this:
        +
        +	mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
        +	cd objtree/"`uname -s`-`uname -r`-`uname -m`"
        +	(cd $OPENSSL_SOURCE; find . -type f) | while read F; do
        +		mkdir -p `dirname $F`
        +		rm -f $F; ln -s $OPENSSL_SOURCE/$F $F
        +		echo $F '->' $OPENSSL_SOURCE/$F
        +	done
        +	make -f Makefile.org clean
        +
        + OPENSSL_SOURCE is an environment variable that contains the absolute (this
        + is important!) path to the OpenSSL source tree.
        +
        + Also, operations like 'make update' should still be made in the source tree.
        diff --git a/vendor/openssl/openssl/INSTALL.DJGPP b/vendor/openssl/openssl/INSTALL.DJGPP
        new file mode 100644
        index 000000000..1047ec90a
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.DJGPP
        @@ -0,0 +1,47 @@
        +
        + 
        + INSTALLATION ON THE DOS PLATFORM WITH DJGPP
        + -------------------------------------------
        +
        + OpenSSL has been ported to DJGPP, a Unix look-alike 32-bit run-time
        + environment for 16-bit DOS, but only with long filename support.
        + If you wish to compile on native DOS with 8+3 filenames, you will
        + have to tweak the installation yourself, including renaming files
        + with illegal or duplicate names.
        +
        + You should have a full DJGPP environment installed, including the
        + latest versions of DJGPP, GCC, BINUTILS, BASH, etc. This package
        + requires that PERL and BC also be installed.
        +
        + All of these can be obtained from the usual DJGPP mirror sites or
        + directly at "http://www.delorie.com/pub/djgpp". For help on which
        + files to download, see the DJGPP "ZIP PICKER" page at
        + "http://www.delorie.com/djgpp/zip-picker.html". You also need to have
        + the WATT-32 networking package installed before you try to compile
        + OpenSSL. This can be obtained from "http://www.bgnett.no/~giva/".
        + The Makefile assumes that the WATT-32 code is in the directory
        + specified by the environment variable WATT_ROOT. If you have watt-32
        + in directory "watt32" under your main DJGPP directory, specify
        + WATT_ROOT="/dev/env/DJDIR/watt32".
        +
        + To compile OpenSSL, start your BASH shell, then configure for DJGPP by
        + running "./Configure" with appropriate arguments:
        +
        +	./Configure no-threads --prefix=/dev/env/DJDIR DJGPP
        + 
        + And finally fire up "make". You may run out of DPMI selectors when
        + running in a DOS box under Windows. If so, just close the BASH
        + shell, go back to Windows, and restart BASH. Then run "make" again.
        +
        + RUN-TIME CAVEAT LECTOR
        + --------------
        +
        + Quoting FAQ:
        +
        +  "Cryptographic software needs a source of unpredictable data to work
        +   correctly.  Many open source operating systems provide a "randomness
        +   device" (/dev/urandom or /dev/random) that serves this purpose."
        +
        + As of version 0.9.7f DJGPP port checks upon /dev/urandom$ for a 3rd
        + party "randomness" DOS driver. One such driver, NOISE.SYS, can be
        + obtained from "http://www.rahul.net/dkaufman/index.html".
        diff --git a/vendor/openssl/openssl/INSTALL.MacOS b/vendor/openssl/openssl/INSTALL.MacOS
        new file mode 100644
        index 000000000..01c60d81f
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.MacOS
        @@ -0,0 +1,72 @@
        +OpenSSL - Port To The Macintosh OS 9 or Earlier
        +===============================================
        +
        +Thanks to Roy Wood <roy@centricsystems.ca> initial support for Mac OS (pre
        +X) is now provided. "Initial" means that unlike other platforms where you
        +get an SDK and a "swiss army" openssl application, on Macintosh you only
        +get one sample application which fetches a page over HTTPS(*) and dumps it
        +in a window. We don't even build the test applications so that we can't
        +guarantee that all algorithms are operational.
        +
        +Required software:
        +
        +- StuffIt Expander 5.5 or later, alternatively MacGzip and SUNtar;
        +- Scriptable Finder;
        +- CodeWarrior Pro 5;
        +
        +Installation procedure:
        +
        +- fetch the source at ftp://ftp.openssl.org/ (well, you probably already
        +  did, huh?)
        +- unpack the .tar.gz file:
        +	- if you have StuffIt Expander then just drag it over it;
        +	- otherwise uncompress it with MacGzip and then unpack with SUNtar;
        +- locate MacOS folder in OpenSSL source tree and open it;
        +- unbinhex mklinks.as.hqx and OpenSSL.mcp.hqx if present (**), do it
        +  "in-place", i.e. unpacked files should end-up in the very same folder;
        +- execute mklinks.as;
        +- open OpenSSL.mcp(***) and build 'GetHTTPS PPC' target(****);
        +- that's it for now;
        +
        +(*)	URL is hardcoded into ./MacOS/GetHTTPS.src/GetHTTPS.cpp, lines 40
        +        to 42, change appropriately.
        +(**)	If you use SUNtar, then it might have already unbinhexed the files
        +	in question.
        +(***)	The project file was saved with CW Pro 5.3. If you have an earlier
        +	version and it refuses to open it, then download
        +	http://www.openssl.org/~appro/OpenSSL.mcp.xml and import it
        +	overwriting the original OpenSSL.mcp.
        +(****)	Other targets are works in progress. If you feel like giving 'em a
        +	shot, then you should know that OpenSSL* and Lib* targets are
        +	supposed to be built with the GUSI, MacOS library which mimics
        +	BSD sockets and some other POSIX APIs. The GUSI distribution is
        +	expected to be found in the same directory as the openssl source tree,
        +	i.e., in the parent directory to the one where this very file,
        +	namely INSTALL.MacOS, resides. For more information about GUSI, see
        +	http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html
        +
        +Finally some essential comments from our generous contributor:-)
        +
        +"I've gotten OpenSSL working on the Macintosh. It's probably a bit of a
        +hack, but it works for what I'm doing. If you don't like the way I've done
        +it, then feel free to change what I've done. I freely admit that I've done
        +some less-than-ideal things in my port, and if you don't like the way I've
        +done something, then feel free to change it-- I won't be offended!
        +
        +... I've tweaked "bss_sock.c" a little to call routines in a "MacSocket"
        +library I wrote. My MacSocket library is a wrapper around OpenTransport,
        +handling stuff like endpoint creation, reading, writing, etc. It is not
        +designed as a high-performance package such as you'd use in a webserver,
        +but is fine for lots of other applications. MacSocket also uses some other
        +code libraries I've written to deal with string manipulations and error
        +handling. Feel free to use these things in your own code, but give me
        +credit and/or send me free stuff in appreciation! :-)
        +
        +...
        +
        +If you have any questions, feel free to email me as the following:
        +
        +roy@centricsystems.ca
        +
        +-Roy Wood"
        +
        diff --git a/vendor/openssl/openssl/INSTALL.NW b/vendor/openssl/openssl/INSTALL.NW
        new file mode 100644
        index 000000000..609a7309e
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.NW
        @@ -0,0 +1,454 @@
        +
        +INSTALLATION ON THE NETWARE PLATFORM
        +------------------------------------
        +
        +Notes about building OpenSSL for NetWare.
        +
        +
        +BUILD PLATFORM:
        +---------------
        +The build scripts (batch files, perl scripts, etc) have been developed and
        +tested on W2K.  The scripts should run fine on other Windows platforms
        +(NT, Win9x, WinXP) but they have not been tested.  They may require some
        +modifications.
        +
        +
        +Supported NetWare Platforms - NetWare 5.x, NetWare 6.x:
        +-------------------------------------------------------
        +OpenSSL can either use the WinSock interfaces introduced in NetWare 5,
        +or the BSD socket interface.  Previous versions of NetWare, 4.x and 3.x,
        +are only supported if OpenSSL is build for CLIB and BSD sockets;
        +WinSock builds only support NetWare 5 and up.
        +
        +On NetWare there are two c-runtime libraries.  There is the legacy CLIB 
        +interfaces and the newer LIBC interfaces.  Being ANSI-C libraries, the 
        +functionality in CLIB and LIBC is similar but the LIBC interfaces are built 
        +using Novell Kernal Services (NKS) which is designed to leverage 
        +multi-processor environments.
        +
        +The NetWare port of OpenSSL can be configured to build using CLIB or LIBC.
        +The CLIB build was developed and tested using NetWare 5.0 sp6.0a.  The LIBC 
        +build was developed and tested using the NetWare 6.0 FCS.  
        +
        +The necessary LIBC functionality ships with NetWare 6.  However, earlier 
        +NetWare 5.x versions will require updates in order to run the OpenSSL LIBC
        +build (NetWare 5.1 SP8 is known to work).
        +
        +As of June 2005, the LIBC build can be configured to use BSD sockets instead
        +of WinSock sockets. Call Configure (usually through netware\build.bat) using
        +a target of "netware-libc-bsdsock" instead of "netware-libc".
        +
        +As of June 2007, support for CLIB and BSD sockets is also now available
        +using a target of "netware-clib-bsdsock" instead of "netware-clib";
        +also gcc builds are now supported on both Linux and Win32 (post 0.9.8e).
        +
        +REQUIRED TOOLS:
        +---------------
        +Based upon the configuration and build options used, some or all of the
        +following tools may be required:
        +
        +* Perl for Win32 - required (http://www.activestate.com/ActivePerl)
        +   Used to run the various perl scripts on the build platform.
        +
        +* Perl 5.8.0 for NetWare v3.20 (or later) - required 
        +   (http://developer.novell.com) Used to run the test script on NetWare 
        +   after building.
        +
        +* Compiler / Linker - required:
        +   Metrowerks CodeWarrior PDK 2.1 (or later) for NetWare (commercial):
        +      Provides command line tools used for building.
        +      Tools:
        +      mwccnlm.exe  - C/C++ Compiler for NetWare
        +      mwldnlm.exe  - Linker for NetWare
        +      mwasmnlm.exe - x86 assembler for NetWare (if using assembly option)
        +
        +   gcc / nlmconv Cross-Compiler, available from Novell Forge (free):
        +         http://forge.novell.com/modules/xfmod/project/?aunixnw
        +
        +* Assemblers - optional:
        +   If you intend to build using the assembly options you will need an
        +   assembler.  Work has been completed to support two assemblers, Metrowerks
        +   and NASM.  However, during development, a bug was found in the Metrowerks
        +   assembler which generates incorrect code.  Until this problem is fixed,
        +   the Metrowerks assembler cannot be used.
        +
        +   mwasmnlm.exe - Metrowerks x86 assembler - part of CodeWarrior tools.
        +         (version 2.2 Built Aug 23, 1999 - not useable due to code
        +          generation bug)
        +
        +   nasmw.exe - Netwide Assembler NASM
        +         version 0.98 was used in development and testing
        +
        +* Make Tool - required:
        +   In order to build you will need a make tool.  Two make tools are
        +   supported, GNU make (gmake.exe) or Microsoft nmake.exe.
        +
        +   make.exe - GNU make for Windows (version 3.75 used for development)
        +         http://gnuwin32.sourceforge.net/packages/make.htm
        +
        +   nmake.exe - Microsoft make (Version 6.00.8168.0 used for development)
        +         http://support.microsoft.com/kb/132084/EN-US/
        +
        +* Novell Developer Kit (NDK) - required: (http://developer.novell.com)
        +
        +   CLIB - BUILDS:
        +
        +      WinSock2 Developer Components for NetWare:
        +         For initial development, the October 27, 2000 version was used.
        +         However, future versions should also work.
        +
        +         NOTE:  The WinSock2 components include headers & import files for
        +         NetWare, but you will also need the winsock2.h and supporting
        +         headers (pshpack4.h, poppack.h, qos.h) delivered in the
        +         Microsoft SDK.  Note: The winsock2.h support headers may change
        +         with various versions of winsock2.h.  Check the dependencies
        +         section on the NDK WinSock2 download page for the latest
        +         information on dependencies. These components are unsupported by
        +         Novell. They are provided as a courtesy, but it is strongly
        +         suggested that all development be done using LIBC, not CLIB.
        +
        +         As of June 2005, the WinSock2 components are available at:
        +         http://forgeftp.novell.com//ws2comp/
        +
        +
        +      NLM and NetWare libraries for C (including CLIB and XPlat):
        +         If you are going to build a CLIB version of OpenSSL, you will
        +         need the CLIB headers and imports.  The March, 2001 NDK release or 
        +         later is recommended.
        +
        +         Earlier versions should work but haven't been tested.  In recent
        +         versions the import files have been consolidated and function
        +         names moved.  This means you may run into link problems
        +         (undefined symbols) when using earlier versions.   The functions
        +         are available in earlier versions, but you will have to modifiy
        +         the make files to include additional import files (see
        +         openssl\util\pl\netware.pl).
        +
        +
        +   LIBC - BUILDS:
        +   
        +      Libraries for C (LIBC) - LIBC headers and import files
        +         If you are going to build a LIBC version of OpenSSL, you will
        +         need the LIBC headers and imports.  The March 14, 2002 NDK release or
        +         later is required.  
        +         
        +         NOTE: The LIBC SDK includes the necessary WinSock2 support.
        +         It is not necessary to download the WinSock2 NDK when building for
        +         LIBC. The LIBC SDK also includes the appropriate BSD socket support
        +         if configuring to use BSD sockets.
        +
        +
        +BUILDING:
        +---------
        +Before building, you will need to set a few environment variables.  You can
        +set them manually or you can modify the "netware\set_env.bat" file.
        +
        +The set_env.bat file is a template you can use to set up the path
        +and environment variables you will need to build.  Modify the
        +various lines to point to YOUR tools and run set_env.bat.
        +
        +   netware\set_env.bat <target> [compiler]
        +
        +      target        - "netware-clib" - CLIB NetWare build
        +                    - "netware-libc" - LIBC NetWare build
        +
        +      compiler      - "gnuc"         - GNU GCC Compiler
        +                    - "codewarrior"  - MetroWerks CodeWarrior (default)
        +
        +If you don't use set_env.bat, you will need to set up the following
        +environment variables:
        +
        +   PATH - Set PATH to point to the tools you will use.
        +
        +   INCLUDE - The location of the NDK include files.
        +         
        +            CLIB ex: set INCLUDE=c:\ndk\nwsdk\include\nlm
        +            LIBC ex: set INCLUDE=c:\ndk\libc\include
        +
        +   PRELUDE - The absolute path of the prelude object to link with.  For
        +            a CLIB build it is recommended you use the "clibpre.o" files shipped
        +            with the Metrowerks PDK for NetWare.  For a LIBC build you should 
        +            use the "libcpre.o" file delivered with the LIBC NDK components.
        +
        +            CLIB ex: set PRELUDE=c:\ndk\nwsdk\imports\clibpre.o
        +            LIBC ex: set PRELUDE=c:\ndk\libc\imports\libcpre.o
        +
        +   IMPORTS - The locaton of the NDK import files.
        +
        +            CLIB ex: set IMPORTS=c:\ndk\nwsdk\imports
        +            LIBC ex: set IMPORTS=c:\ndk\libc\imports
        +
        +
        +In order to build, you need to run the Perl scripts to configure the build
        +process and generate a make file.  There is a batch file,
        +"netware\build.bat", to automate the process.
        +
        +Build.bat runs the build configuration scripts and generates a make file.
        +If an assembly option is specified, it also runs the scripts to generate 
        +the assembly code.  Always run build.bat from the "openssl" directory.
        +
        +   netware\build [target] [debug opts] [assembly opts] [configure opts]
        +
        +      target        - "netware-clib" - CLIB NetWare build (WinSock Sockets)
        +                    - "netware-clib-bsdsock" - CLIB NetWare build (BSD Sockets)
        +                    - "netware-libc" - LIBC NetWare build (WinSock Sockets)
        +                    - "netware-libc-bsdsock" - LIBC NetWare build (BSD Sockets)
        + 
        +      debug opts    - "debug"  - build debug
        +
        +      assembly opts - "nw-mwasm" - use Metrowerks assembler
        +                      "nw-nasm"  - use NASM assembler
        +                      "no-asm"   - don't use assembly
        +
        +      configure opts- all unrecognized arguments are passed to the
        +                      perl 'configure' script. See that script for
        +                      internal documentation regarding options that
        +                      are available.
        +
        +   examples:
        +
        +      CLIB build, debug, without assembly:
        +         netware\build.bat netware-clib debug no-asm
        +
        +      LIBC build, non-debug, using NASM assembly, add mdc2 support:
        +         netware\build.bat netware-libc nw-nasm enable-mdc2
        +
        +      LIBC build, BSD sockets, non-debug, without assembly:
        +         netware\build.bat netware-libc-bsdsock no-asm
        +
        +Running build.bat generates a make file to be processed by your make 
        +tool (gmake or nmake):
        +
        +   CLIB ex: gmake -f netware\nlm_clib_dbg.mak 
        +   LIBC ex: gmake -f netware\nlm_libc.mak 
        +   LIBC ex: gmake -f netware\nlm_libc_bsdsock.mak 
        +
        +
        +You can also run the build scripts manually if you do not want to use the
        +build.bat file.  Run the following scripts in the "\openssl"
        +subdirectory (in the order listed below):
        +
        +   perl configure no-asm [other config opts] [netware-clib|netware-libc|netware-libc-bsdsock]
        +      configures no assembly build for specified netware environment
        +      (CLIB or LIBC).
        +
        +   perl util\mkfiles.pl >MINFO
        +      generates a listing of source files (used by mk1mf)
        +
        +   perl util\mk1mf.pl no-asm [other config opts] [netware-clib|netware-libc|netware-libc-bsdsock >netware\nlm.mak
        +      generates the makefile for NetWare
        +
        +   gmake -f netware\nlm.mak
        +      build with the make tool (nmake.exe also works)
        +
        +NOTE:  If you are building using the assembly option, you must also run the
        +various Perl scripts to generate the assembly files.  See build.bat
        +for an example of running the various assembly scripts.  You must use the
        +"no-asm" option to build without assembly.  The configure and mk1mf scripts
        +also have various other options.  See the scripts for more information.
        +
        +
        +The output from the build is placed in the following directories:
        +
        +   CLIB Debug build:
        +      out_nw_clib.dbg     - static libs & test nlm(s)
        +      tmp_nw_clib.dbg     - temporary build files
        +      outinc_nw_clib      - necessary include files
        +
        +   CLIB Non-debug build:
        +      out_nw_clib         - static libs & test nlm(s)
        +      tmp_nw_clib         - temporary build files
        +      outinc_nw_clib      - necesary include files
        +
        +   LIBC Debug build:
        +      out_nw_libc.dbg     - static libs & test nlm(s)
        +      tmp_nw_libc.dbg     - temporary build files
        +      outinc_nw_libc      - necessary include files
        +
        +   LIBC Non-debug build:
        +      out_nw_libc         - static libs & test nlm(s)
        +      tmp_nw_libc         - temporary build files
        +      outinc_nw_libc      - necesary include files
        +
        +
        +TESTING:
        +--------
        +The build process creates the OpenSSL static libs ( crypto.lib, ssl.lib,
        +rsaglue.lib ) and several test programs.  You should copy the test programs
        +to your NetWare server and run the tests.
        +
        +The batch file "netware\cpy_tests.bat" will copy all the necessary files
        +to your server for testing.  In order to run the batch file, you need a
        +drive mapped to your target server.  It will create an "OpenSSL" directory
        +on the drive and copy the test files to it.  CAUTION: If a directory with the
        +name of "OpenSSL" already exists, it will be deleted.
        +
        +To run cpy_tests.bat:
        +
        +   netware\cpy_tests [output directory] [NetWare drive]
        +
        +      output directory - "out_nw_clib.dbg", "out_nw_libc", etc.
        +      NetWare drive    - drive letter of mapped drive
        +
        +      CLIB ex: netware\cpy_tests out_nw_clib m:
        +      LIBC ex: netware\cpy_tests out_nw_libc m:
        +
        +
        +The Perl script, "do_tests.pl", in the "OpenSSL" directory on the server
        +should be used to execute the tests.  Before running the script, make sure
        +your SEARCH PATH includes the "OpenSSL" directory.  For example, if you
        +copied the files to the "sys:" volume you use the command:
        +
        +   SEARCH ADD SYS:\OPENSSL
        +
        +
        +To run do_tests.pl type (at the console prompt):
        +
        +   perl \openssl\do_tests.pl [options]
        +
        +      options:
        +         -p    - pause after executing each test
        +
        +The do_tests.pl script generates a log file "\openssl\test_out\tests.log"
        +which should be reviewed for errors.  Any errors will be denoted by the word
        +"ERROR" in the log.
        +
        +DEVELOPING WITH THE OPENSSL SDK:
        +--------------------------------
        +Now that everything is built and tested, you are ready to use the OpenSSL
        +libraries in your development.
        +
        +There is no real installation procedure, just copy the static libs and
        +headers to your build location.  The libs (crypto.lib & ssl.lib) are
        +located in the appropriate "out_nw_XXXX" directory 
        +(out_nw_clib, out_nw_libc, etc).  
        +
        +The headers are located in the appropriate "outinc_nw_XXX" directory 
        +(outinc_nw_clib, outinc_nw_libc).  
        +
        +One suggestion is to create the following directory 
        +structure for the OpenSSL SDK:
        +
        +   \openssl
        +      |- bin
        +      |   |- openssl.nlm
        +      |   |- (other tests you want)
        +      |
        +      |- lib
        +      |   | - crypto.lib
        +      |   | - ssl.lib
        +      |
        +      |- include
        +      |   | - openssl
        +      |   |    | - (all the headers in "outinc_nw\openssl")
        +
        +
        +The program "openssl.nlm" can be very useful.  It has dozens of
        +options and you may want to keep it handy for debugging, testing, etc.
        +
        +When building your apps using OpenSSL, define "NETWARE".  It is needed by
        +some of the OpenSSL headers.  One way to do this is with a compile option,
        +for example "-DNETWARE".
        +
        +
        +
        +NOTES:
        +------
        +
        +Resource leaks in Tests
        +------------------------
        +Some OpenSSL tests do not clean up resources and NetWare reports
        +the resource leaks when the tests unload.  If this really bugs you,
        +you can stop the messages by setting the developer option off at the console
        +prompt (set developer option = off).  Or better yet, fix the tests to
        +clean up the resources!
        +
        +
        +Multi-threaded Development
        +---------------------------
        +The NetWare version of OpenSSL is thread-safe, however multi-threaded
        +applications must provide the necessary locking function callbacks.  This
        +is described in doc\threads.doc.  The file "openssl-x.x.x\crypto\threads\mttest.c"
        +is a multi-threaded test program and demonstrates the locking functions.
        +
        +
        +What is openssl2.nlm?
        +---------------------
        +The openssl program has numerous options and can be used for many different
        +things.  Many of the options operate in an interactive mode requiring the
        +user to enter data.  Because of this, a default screen is created for the
        +program.  However, when running the test script it is not desirable to
        +have a seperate screen.  Therefore, the build also creates openssl2.nlm.
        +Openssl2.nlm is functionally identical but uses the console screen.
        +Openssl2 can be used when a non-interactive mode is desired.
        +
        +NOTE:  There are may other possibilities (command line options, etc)
        +which could have been used to address the screen issue.  The openssl2.nlm
        +option was chosen because it impacted only the build not the code.
        +
        +
        +Why only static libraries?
        +--------------------------
        +Globals, globals, and more globals.  The OpenSSL code uses many global
        +variables that are allocated and initialized when used for the first time.
        +
        +On NetWare, most applications (at least historically) run in the kernel.
        +When running in the kernel, there is one instance of global variables.
        +For regular application type NLM(s) this isn't a problem because they are
        +the only ones using the globals.  However, for a library NLM (an NLM which
        +exposes functions and has no threads of execution), the globals cause
        +problems.  Applications could inadvertently step on each other if they
        +change some globals.  Even worse, the first application that triggers a
        +global to be allocated and initialized has the allocated memory charged to
        +itself.  Now when that application unloads, NetWare will clean up all the
        +applicaton's memory.  The global pointer variables inside OpenSSL now
        +point to freed memory.  An abend waiting to happen!
        +
        +To work correctly in the kernel, library NLM(s) that use globals need to
        +provide a set of globals (instance data) for each application.  Another
        +option is to require the library only be loaded in a protected address
        +space along with the application using it.
        +
        +Modifying the OpenSSL code to provide a set of globals (instance data) for
        +each application isn't technically difficult, but due to the large number
        +globals it would require substantial code changes and it wasn't done.  Hence,
        +the build currently only builds static libraries which are then linked
        +into each application.
        +
        +NOTE:  If you are building a library NLM that uses the OpenSSL static
        +libraries, you will still have to deal with the global variable issue.
        +This is because when you link in the OpenSSL code you bring in all the
        +globals.  One possible solution for the global pointer variables is to
        +register memory functions with OpenSSL which allocate memory and charge it
        +to your library NLM (see the function CRYPTO_set_mem_functions).  However,
        +be aware that now all memory allocated by OpenSSL is charged to your NLM.
        +
        +
        +CodeWarrior Tools and W2K
        +---------------------------
        +There have been problems reported with the CodeWarrior Linker
        +(mwldnlm.exe) in the PDK 2.1 for NetWare when running on Windows 2000.  The
        +problems cause the link step to fail.  The only work around is to obtain an
        +updated linker from Metrowerks.  It is expected Metrowerks will release
        +PDK 3.0 (in beta testing at this time - May, 2001) in the near future which
        +will fix these problems.
        +
        +
        +Makefile "vclean"
        +------------------
        +The generated makefile has a "vclean" target which cleans up the build
        +directories.  If you have been building successfully and suddenly
        +experience problems, use "vclean" (gmake -f netware\nlm_xxxx.mak vclean) and retry.
        +
        +
        +"Undefined Symbol" Linker errors
        +--------------------------------
        +There have been linker errors reported when doing a CLIB build.  The problems
        +occur because some versions of the CLIB SDK import files inadvertently 
        +left out some symbols.  One symbol in particular is "_lrotl".  The missing
        +functions are actually delivered in the binaries, but they were left out of
        +the import files.  The issues should be fixed in the September 2001 release 
        +of the NDK.  If you experience the problems you can temporarily
        +work around it by manually adding the missing symbols to your version of 
        +"clib.imp".
        +
        diff --git a/vendor/openssl/openssl/INSTALL.OS2 b/vendor/openssl/openssl/INSTALL.OS2
        new file mode 100644
        index 000000000..530316db1
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.OS2
        @@ -0,0 +1,31 @@
        + 
        + Installation on OS/2
        + --------------------
        +
        + You need to have the following tools installed:
        +
        +  * EMX GCC
        +  * PERL
        +  * GNU make
        +
        +
        + To build the makefile, run
        +
        + > os2\os2-emx
        +
        + This will configure OpenSSL and create OS2-EMX.mak which you then use to 
        + build the OpenSSL libraries & programs by running
        +
        + > make -f os2-emx.mak
        +
        + If that finishes successfully you will find the libraries and programs in the
        + "out" directory.
        +
        + Alternatively, you can make a dynamic build that puts the library code into
        + crypto.dll and ssl.dll by running
        +
        + > make -f os2-emx-dll.mak
        +
        + This will build the above mentioned dlls and a matching pair of import
        + libraries in the "out_dll" directory along with the set of test programs
        + and the openssl application.
        diff --git a/vendor/openssl/openssl/INSTALL.VMS b/vendor/openssl/openssl/INSTALL.VMS
        new file mode 100644
        index 000000000..e5d43a57a
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.VMS
        @@ -0,0 +1,293 @@
        +			VMS Installation instructions
        +			written by Richard Levitte
        +			<richard@levitte.org>
        +
        +
        +Intro:
        +======
        +
        +This file is divided in the following parts:
        +
        +  Requirements			- Mandatory reading.
        +  Checking the distribution	- Mandatory reading.
        +  Compilation			- Mandatory reading.
        +  Logical names			- Mandatory reading.
        +  Test				- Mandatory reading.
        +  Installation			- Mandatory reading.
        +  Backward portability		- Read if it's an issue.
        +  Possible bugs or quirks	- A few warnings on things that
        +				  may go wrong or may surprise you.
        +  TODO				- Things that are to come.
        +
        +
        +Requirements:
        +=============
        +
        +To build and install OpenSSL, you will need:
        +
        + * DEC C or some other ANSI C compiler.  VAX C is *not* supported.
        +   [Note: OpenSSL has only been tested with DEC C.  Compiling with 
        +    a different ANSI C compiler may require some work]
        +
        +Checking the distribution:
        +==========================
        +
        +There have been reports of places where the distribution didn't quite get
        +through, for example if you've copied the tree from a NFS-mounted Unix
        +mount point.
        +
        +The easiest way to check if everything got through as it should is to check
        +for one of the following files:
        +
        +	[.CRYPTO]OPENSSLCONF.H_IN
        +	[.CRYPTO]OPENSSLCONF_H.IN
        +
        +They should never exist both at once, but one of them should (preferably
        +the first variant).  If you can't find any of those two, something went
        +wrong.
        +
        +The best way to get a correct distribution is to download the gzipped tar
        +file from ftp://ftp.openssl.org/source/, use GUNZIP to uncompress it and
        +use VMSTAR to unpack the resulting tar file.
        +
        +GUNZIP is available in many places on the net.  One of the distribution
        +points is the WKU software archive, ftp://ftp.wku.edu/vms/fileserv/ .
        +
        +VMSTAR is also available in many places on the net.  The recommended place
        +to find information about it is http://www.free.lp.se/vmstar/ .
        +
        +
        +Compilation:
        +============
        +
        +I've used the very good command procedures written by Robert Byer
        +<byer@mail.all-net.net>, and just slightly modified them, making
        +them slightly more general and easier to maintain.
        +
        +You can actually compile in almost any directory separately.  Look
        +for a command procedure name xxx-LIB.COM (in the library directories)
        +or MAKExxx.COM (in the program directories) and read the comments at
        +the top to understand how to use them.  However, if you want to
        +compile all you can get, the simplest is to use MAKEVMS.COM in the top
        +directory.  The syntax is the following:
        +
        +  @MAKEVMS <option> <bits> <debug-p> [<compiler>]
        +
        +<option> must be one of the following:
        +
        +      ALL       Just build "everything".
        +      CONFIG    Just build the "[.CRYPTO]OPENSSLCONF.H" file.
        +      BUILDINF  Just build the "[.INCLUDE]BUILDINF.H" file.
        +      SOFTLINKS Just copies some files, to simulate Unix soft links.
        +      BUILDALL  Same as ALL, except CONFIG, BUILDINF and SOFTLINKS aren't done.
        +      RSAREF    Just build the "[.xxx.EXE.RSAREF]LIBRSAGLUE.OLB" library.
        +      CRYPTO    Just build the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
        +      SSL       Just build the "[.xxx.EXE.SSL]LIBSSL.OLB" library.
        +      SSL_TASK  Just build the "[.xxx.EXE.SSL]SSL_TASK.EXE" program.
        +      TEST      Just build the "[.xxx.EXE.TEST]" test programs for OpenSSL.
        +      APPS      Just build the "[.xxx.EXE.APPS]" application programs for OpenSSL.
        +
        +<bits> must be one of the following:
        +
        +      ""        compile using default pointer size
        +      32        compile using 32 bit pointer size
        +      64        compile using 64 bit pointer size
        +
        +<debug-p> must be one of the following:
        +
        +      DEBUG     compile with debugging info (will not optimize)
        +      NODEBUG   compile without debugging info (will optimize)
        +
        +<compiler> must be one of the following:
        +
        +      DECC      For DEC C.
        +      GNUC      For GNU C.
        +
        +
        +You will find the crypto library in [.xxx.EXE.CRYPTO] (where xxx is VAX,
        +ALPHA or IA64), called SSL_LIBCRYPTO32.OLB or SSL_LIBCRYPTO.OLB depending
        +on how it was built.  You will find the SSL library in [.xxx.EXE.SSL],
        +named SSL_LIBSSL32.OLB or SSL_LIBSSL.OLB, and you will find a bunch of
        +useful programs in [.xxx.EXE.APPS].  However, these shouldn't be used
        +right off unless it's just to test them.  For production use, make sure
        +you install first, see Installation below.
        +
        +Note 1: Some programs in this package require a TCP/IP library.
        +
        +Note 2: if you want to compile the crypto library only, please make sure
        +        you have at least done a @MAKEVMS CONFIG, a @MAKEVMS BUILDINF and
        +        a @MAKEVMS SOFTLINKS.  A lot of things will break if you don't.
        +
        +
        +Logical names:
        +==============
        +
        +There are a few things that can't currently be given through the command
        +line.  Instead, logical names are used.
        +
        +Currently, the logical names supported are:
        +
        +      OPENSSL_NO_ASM    with value YES, the assembler parts of OpenSSL will
        +                        not be used.  Instead, plain C implementations are
        +                        used.  This is good to try if something doesn't work.
        +      OPENSSL_NO_'alg'  with value YES, the corresponding crypto algorithm
        +                        will not be implemented.  Supported algorithms to
        +                        do this with are: RSA, DSA, DH, MD2, MD4, MD5, RIPEMD,
        +                        SHA, DES, MDC2, CR2, RC4, RC5, IDEA, BF, CAST, HMAC,
        +                        SSL2.  So, for example, having the logical name
        +                        OPENSSL_NO_RSA with the value YES means that the
        +                        LIBCRYPTO.OLB library will not contain an RSA
        +                        implementation.
        +
        +
        +Test:
        +=====
        +
        +Testing is very simple, just do the following:
        +
        +  @[.TEST]TESTS
        +
        +If a test fails, try with defining the logical name OPENSSL_NO_ASM (yes,
        +it's an ugly hack!) and rebuild. Please send a bug report to
        +<openssl-bugs@openssl.org>, including the output of "openssl version -a"
        +and of the failed test.
        +
        +
        +Installation:
        +=============
        +
        +Installation is easy, just do the following:
        +
        +  @INSTALL <root> <bits>
        +
        +<root> is the directory in which everything will be installed,
        +subdirectories, libraries, header files, programs and startup command
        +procedures.
        +
        +<bits> works the same way as for MAKEVMS.COM
        +
        +N.B.: INSTALL.COM builds a new directory structure, different from
        +the directory tree where you have now build OpenSSL.
        +
        +In the [.VMS] subdirectory of the installation, you will find the
        +following command procedures:
        +
        +  OPENSSL_STARTUP.COM
        +
        +        defines all needed logical names.  Takes one argument that
        +        tells it in what logical name table to insert the logical
        +        names.  If you insert if it SYS$MANAGER:SYSTARTUP_VMS.COM, the
        +        call should look like this: 
        +
        +          @openssldev:[openssldir.VMS]OPENSSL_STARTUP "/SYSTEM"
        +
        +  OPENSSL_UTILS.COM
        +
        +        sets up the symbols to the applications.  Should be called
        +        from for example SYS$MANAGER:SYLOGIN.COM 
        +
        +  OPENSSL_UNDO.COM
        +
        +	deassigns the logical names created with OPENSSL_STARTUP.COM.
        +
        +The logical names that are set up are the following:
        +
        +  SSLROOT       a dotted concealed logical name pointing at the
        +                root directory.
        +
        +  SSLCERTS      Initially an empty directory, this is the default
        +		location for certificate files.
        +  SSLPRIVATE	Initially an empty directory, this is the default
        +		location for private key files.
        +
        +  SSLEXE        Contains the openssl binary and a few other utility
        +		programs.
        +  SSLINCLUDE    Contains the header files needed if you want to
        +		compile programs with libcrypto or libssl.
        +  SSLLIB        Contains the OpenSSL library files themselves:
        +  		- SSL_LIBCRYPTO32.OLB and SSL_LIBSSL32.OLB or
        +		- SSL_LIBCRYPTO.OLB and SSL_LIBSSL.OLB
        +
        +  OPENSSL	Same as SSLINCLUDE.  This is because the standard
        +		way to include OpenSSL header files from version
        +		0.9.3 and on is:
        +
        +			#include <openssl/header.h>
        +
        +		For more info on this issue, see the INSTALL. file
        +		(the NOTE in section 4 of "Installation in Detail").
        +		You don't need to "deleting old header files"!!!
        +
        +
        +Backward portability:
        +=====================
        +
        +One great problem when you build a library is making sure it will work
        +on as many versions of VMS as possible.  Especially, code compiled on
        +OpenVMS version 7.x and above tend to be unusable in version 6.x or
        +lower, because some C library routines have changed names internally
        +(the C programmer won't usually see it, because the old name is
        +maintained through C macros).  One obvious solution is to make sure
        +you have a development machine with an old enough version of OpenVMS.
        +However, if you are stuck with a bunch of Alphas running OpenVMS version
        +7.1, you seem to be out of luck.  Fortunately, the DEC C header files
        +are cluttered with conditionals that make some declarations and definitions
        +dependent on the OpenVMS version or the C library version, *and* you
        +can use those macros to simulate older OpenVMS or C library versions,
        +by defining the macros _VMS_V6_SOURCE, __VMS_VER and __CTRL_VER with
        +correct values.  In the compilation scripts, I've provided the possibility
        +for the user to influence the creation of such macros, through a bunch of
        +symbols, all having names starting with USER_.  Here's the list of them:
        +
        +  USER_CCFLAGS		 - Used to give additional qualifiers to the
        +			   compiler.  It can't be used to define macros
        +			   since the scripts will do such things as well.
        +			   To do such things, use USER_CCDEFS.
        +  USER_CCDEFS		 - Used to define macros on the command line.  The
        +			   value of this symbol will be inserted inside a
        +			   /DEFINE=(...).
        +  USER_CCDISABLEWARNINGS - Used to disable some warnings.  The value is
        +			   inserted inside a /DISABLE=WARNING=(...).
        +
        +So, to maintain backward compatibility with older VMS versions, do the
        +following before you start compiling:
        +
        +  $ USER_CCDEFS := _VMS_V6_SOURCE=1,__VMS_VER=60000000,__CRTL_VER=60000000
        +  $ USER_CCDISABLEWARNINGS := PREOPTW
        +
        +The USER_CCDISABLEWARNINGS is there because otherwise, DEC C will complain
        +that those macros have been changed.
        +
        +Note: Currently, this is only useful for library compilation.  The
        +      programs will still be linked with the current version of the
        +      C library shareable image, and will thus complain if they are
        +      faced with an older version of the same C library shareable image.
        +      This will probably be fixed in a future revision of OpenSSL.
        +
        +
        +Possible bugs or quirks:
        +========================
        +
        +I'm not perfectly sure all the programs will use the SSLCERTS:
        +directory by default, it may very well be that you have to give them
        +extra arguments.  Please experiment.
        +
        +
        +TODO:
        +=====
        +
        +There are a few things that need to be worked out in the VMS version of
        +OpenSSL, still:
        +
        +- Description files. ("Makefile's" :-))
        +- Script code to link an already compiled build tree.
        +- A VMSINSTALlable version (way in the future, unless someone else hacks).
        +- shareable images (DLL for you Windows folks).
        +
        +There may be other things that I have missed and that may be desirable.
        +Please send mail to <openssl-users@openssl.org> or to me directly if you
        +have any ideas.
        +
        +--
        +Richard Levitte <richard@levitte.org>
        +2000-02-27, 2011-03-18
        diff --git a/vendor/openssl/openssl/INSTALL.W32 b/vendor/openssl/openssl/INSTALL.W32
        new file mode 100644
        index 000000000..80e538273
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.W32
        @@ -0,0 +1,325 @@
        + 
        + INSTALLATION ON THE WIN32 PLATFORM
        + ----------------------------------
        +
        + [Instructions for building for Windows CE can be found in INSTALL.WCE]
        + [Instructions for building for Win64 can be found in INSTALL.W64]
        +
        + Here are a few comments about building OpenSSL for Win32 environments,
        + such as Windows NT and Windows 9x. It should be noted though that
        + Windows 9x are not ordinarily tested. Its mention merely means that we
        + attempt to maintain certain programming discipline and pay attention
        + to backward compatibility issues, in other words it's kind of expected
        + to work on Windows 9x, but no regression tests are actually performed.
        +
        + On additional note newer OpenSSL versions are compiled and linked with
        + Winsock 2. This means that minimum OS requirement was elevated to NT 4
        + and Windows 98 [there is Winsock 2 update for Windows 95 though].
        +
        + - you need Perl for Win32.  Unless you will build on Cygwin, you will need
        +   ActiveState Perl, available from http://www.activestate.com/ActivePerl.
        +
        + - one of the following C compilers:
        +
        +  * Visual C++
        +  * Borland C
        +  * GNU C (Cygwin or MinGW)
        +
        +- Netwide Assembler, a.k.a. NASM, available from http://nasm.sourceforge.net/
        +  is required if you intend to utilize assembler modules. Note that NASM
        +  is now the only supported assembler.
        +
        + If you are compiling from a tarball or a Git snapshot then the Win32 files
        + may well be not up to date. This may mean that some "tweaking" is required to
        + get it all to work. See the trouble shooting section later on for if (when?)
        + it goes wrong.
        +
        + Visual C++
        + ----------
        +
        + If you want to compile in the assembly language routines with Visual
        + C++, then you will need already mentioned Netwide Assembler binary,
        + nasmw.exe or nasm.exe, to be available on your %PATH%.
        +
        + Firstly you should run Configure with platform VC-WIN32:
        +
        + > perl Configure VC-WIN32 --prefix=c:\some\openssl\dir
        +
        + Where the prefix argument specifies where OpenSSL will be installed to.
        +
        + Next you need to build the Makefiles and optionally the assembly
        + language files:
        +
        + - If you are using NASM then run:
        +
        +   > ms\do_nasm
        +
        + - If you don't want to use the assembly language files at all then run:
        +
        +   > perl Configure VC-WIN32 no-asm --prefix=c:/some/openssl/dir
        +   > ms\do_ms
        +
        + If you get errors about things not having numbers assigned then check the
        + troubleshooting section: you probably won't be able to compile it as it
        + stands.
        +
        + Then from the VC++ environment at a prompt do:
        +
        + > nmake -f ms\ntdll.mak
        +
        + If all is well it should compile and you will have some DLLs and
        + executables in out32dll. If you want to try the tests then do:
        + 
        + > nmake -f ms\ntdll.mak test
        +
        +
        + To install OpenSSL to the specified location do:
        +
        + > nmake -f ms\ntdll.mak install
        +
        + Tweaks:
        +
        + There are various changes you can make to the Win32 compile
        + environment. By default the library is not compiled with debugging
        + symbols. If you use the platform debug-VC-WIN32 instead of VC-WIN32
        + then debugging symbols will be compiled in.
        +
        + By default in 1.0.0 OpenSSL will compile builtin ENGINES into the
        + separate shared librariesy. If you specify the "enable-static-engine"
        + option on the command line to Configure the shared library build
        + (ms\ntdll.mak) will compile the engines into libeay32.dll instead.
        +
        + The default Win32 environment is to leave out any Windows NT specific
        + features.
        +
        + If you want to enable the NT specific features of OpenSSL (currently
        + only the logging BIO) follow the instructions above but call the batch
        + file do_nt.bat instead of do_ms.bat.
        +
        + You can also build a static version of the library using the Makefile
        + ms\nt.mak
        +
        +
        + Borland C++ builder 5
        + ---------------------
        +
        + * Configure for building with Borland Builder:
        +   > perl Configure BC-32
        +
        + * Create the appropriate makefile
        +   > ms\do_nasm
        +
        + * Build
        +   > make -f ms\bcb.mak
        +
        + Borland C++ builder 3 and 4
        + ---------------------------
        +
        + * Setup PATH. First must be GNU make then bcb4/bin 
        +
        + * Run ms\bcb4.bat
        +
        + * Run make:
        +   > make -f bcb.mak
        +
        + GNU C (Cygwin)
        + --------------
        +
        + Cygwin implements a Posix/Unix runtime system (cygwin1.dll) on top of
        + Win32 subsystem and provides a bash shell and GNU tools environment.
        + Consequently, a make of OpenSSL with Cygwin is virtually identical to
        + Unix procedure. It is also possible to create Win32 binaries that only
        + use the Microsoft C runtime system (msvcrt.dll or crtdll.dll) using
        + MinGW. MinGW can be used in the Cygwin development environment or in a
        + standalone setup as described in the following section.
        +
        + To build OpenSSL using Cygwin:
        +
        + * Install Cygwin (see http://cygwin.com/)
        +
        + * Install Perl and ensure it is in the path. Both Cygwin perl
        +   (5.6.1-2 or newer) and ActivePerl work.
        +
        + * Run the Cygwin bash shell
        +
        + * $ tar zxvf openssl-x.x.x.tar.gz
        +   $ cd openssl-x.x.x
        +
        +   To build the Cygwin version of OpenSSL:
        +
        +   $ ./config
        +   [...]
        +   $ make
        +   [...]
        +   $ make test
        +   $ make install
        +
        +   This will create a default install in /usr/local/ssl.
        +
        +   To build the MinGW version (native Windows) in Cygwin:
        +
        +   $ ./Configure mingw
        +   [...]
        +   $ make
        +   [...]
        +   $ make test
        +   $ make install
        +
        + Cygwin Notes:
        +
        + "make test" and normal file operations may fail in directories
        + mounted as text (i.e. mount -t c:\somewhere /home) due to Cygwin
        + stripping of carriage returns. To avoid this ensure that a binary
        + mount is used, e.g. mount -b c:\somewhere /home.
        +
        + "bc" is not provided in older Cygwin distribution.  This causes a
        + non-fatal error in "make test" but is otherwise harmless.  If
        + desired and needed, GNU bc can be built with Cygwin without change.
        +
        + GNU C (MinGW/MSYS)
        + -------------
        +
        + * Compiler and shell environment installation:
        +
        +   MinGW and MSYS are available from http://www.mingw.org/, both are
        +   required. Run the installers and do whatever magic they say it takes
        +   to start MSYS bash shell with GNU tools on its PATH.
        +
        +   N.B. Since source tar-ball can contain symbolic links, it's essential
        +   that you use accompanying MSYS tar to unpack the source. It will
        +   either handle them in one way or another or fail to extract them,
        +   which does the trick too. Latter means that you may safely ignore all
        +   "cannot create symlink" messages, as they will be "re-created" at
        +   configure stage by copying corresponding files. Alternative programs
        +   were observed to create empty files instead, which results in build
        +   failure.
        +
        + * Compile OpenSSL:
        +
        +   $ ./config
        +   [...]
        +   $ make
        +   [...]
        +   $ make test
        +
        +   This will create the library and binaries in root source directory
        +   and openssl.exe application in apps directory.
        +
        +   It is also possible to cross-compile it on Linux by configuring
        +   with './Configure --cross-compile-prefix=i386-mingw32- mingw ...'.
        +   'make test' is naturally not applicable then.
        +
        +   libcrypto.a and libssl.a are the static libraries. To use the DLLs,
        +   link with libeay32.a and libssl32.a instead.
        +
        +   See troubleshooting if you get error messages about functions not
        +   having a number assigned.
        +
        + Installation
        + ------------
        +
        + If you used the Cygwin procedure above, you have already installed and
        + can skip this section.  For all other procedures, there's currently no real
        + installation procedure for Win32.  There are, however, some suggestions:
        +
        +    - do nothing.  The include files are found in the inc32/ subdirectory,
        +      all binaries are found in out32dll/ or out32/ depending if you built
        +      dynamic or static libraries.
        +
        +    - do as is written in INSTALL.Win32 that comes with modssl:
        +
        +	$ md c:\openssl 
        +	$ md c:\openssl\bin
        +	$ md c:\openssl\lib
        +	$ md c:\openssl\include
        +	$ md c:\openssl\include\openssl
        +	$ copy /b inc32\openssl\*       c:\openssl\include\openssl
        +	$ copy /b out32dll\ssleay32.lib c:\openssl\lib
        +	$ copy /b out32dll\libeay32.lib c:\openssl\lib
        +	$ copy /b out32dll\ssleay32.dll c:\openssl\bin
        +	$ copy /b out32dll\libeay32.dll c:\openssl\bin
        +	$ copy /b out32dll\openssl.exe  c:\openssl\bin
        +
        +      Of course, you can choose another device than c:.  C: is used here
        +      because that's usually the first (and often only) harddisk device.
        +      Note: in the modssl INSTALL.Win32, p: is used rather than c:.
        +
        +
        + Troubleshooting
        + ---------------
        +
        + Since the Win32 build is only occasionally tested it may not always compile
        + cleanly.  If you get an error about functions not having numbers assigned
        + when you run ms\do_ms then this means the Win32 ordinal files are not up to
        + date. You can do:
        +
        + > perl util\mkdef.pl crypto ssl update
        +
        + then ms\do_XXX should not give a warning any more. However the numbers that
        + get assigned by this technique may not match those that eventually get
        + assigned in the Git tree: so anything linked against this version of the
        + library may need to be recompiled.
        +
        + If you get errors about unresolved symbols there are several possible
        + causes.
        +
        + If this happens when the DLL is being linked and you have disabled some
        + ciphers then it is possible the DEF file generator hasn't removed all
        + the disabled symbols: the easiest solution is to edit the DEF files manually
        + to delete them. The DEF files are ms\libeay32.def ms\ssleay32.def.
        +
        + Another cause is if you missed or ignored the errors about missing numbers
        + mentioned above.
        +
        + If you get warnings in the code then the compilation will halt.
        +
        + The default Makefile for Win32 halts whenever any warnings occur. Since VC++
        + has its own ideas about warnings which don't always match up to other
        + environments this can happen. The best fix is to edit the file with the
        + warning in and fix it. Alternatively you can turn off the halt on warnings by
        + editing the CFLAG line in the Makefile and deleting the /WX option.
        +
        + You might get compilation errors. Again you will have to fix these or report
        + them.
        +
        + One final comment about compiling applications linked to the OpenSSL library.
        + If you don't use the multithreaded DLL runtime library (/MD option) your
        + program will almost certainly crash because malloc gets confused -- the
        + OpenSSL DLLs are statically linked to one version, the application must
        + not use a different one.  You might be able to work around such problems
        + by adding CRYPTO_malloc_init() to your program before any calls to the
        + OpenSSL libraries: This tells the OpenSSL libraries to use the same
        + malloc(), free() and realloc() as the application.  However there are many
        + standard library functions used by OpenSSL that call malloc() internally
        + (e.g. fopen()), and OpenSSL cannot change these; so in general you cannot
        + rely on CRYPTO_malloc_init() solving your problem, and you should
        + consistently use the multithreaded library.
        +
        + Linking your application
        + ------------------------
        +
        + If you link with static OpenSSL libraries [those built with ms/nt.mak],
        + then you're expected to additionally link your application with
        + WS2_32.LIB, ADVAPI32.LIB, GDI32.LIB and USER32.LIB. Those developing
        + non-interactive service applications might feel concerned about linking
        + with the latter two, as they are justly associated with interactive
        + desktop, which is not available to service processes. The toolkit is
        + designed to detect in which context it's currently executed, GUI,
        + console app or service, and act accordingly, namely whether or not to
        + actually make GUI calls. Additionally those who wish to
        + /DELAYLOAD:GDI32.DLL and /DELAYLOAD:USER32.DLL and actually keep them
        + off service process should consider implementing and exporting from
        + .exe image in question own _OPENSSL_isservice not relying on USER32.DLL.
        + E.g., on Windows Vista and later you could:
        +
        +	__declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void)
        +	{   DWORD sess;
        +	    if (ProcessIdToSessionId(GetCurrentProcessId(),&sess))
        +	        return sess==0;
        +	    return FALSE;
        +	}
        +
        + If you link with OpenSSL .DLLs, then you're expected to include into
        + your application code small "shim" snippet, which provides glue between
        + OpenSSL BIO layer and your compiler run-time. Look up OPENSSL_Applink
        + reference page for further details.
        diff --git a/vendor/openssl/openssl/INSTALL.W64 b/vendor/openssl/openssl/INSTALL.W64
        new file mode 100644
        index 000000000..9fa7a1920
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.W64
        @@ -0,0 +1,66 @@
        +
        + INSTALLATION ON THE WIN64 PLATFORM
        + ----------------------------------
        +
        + Caveat lector
        + -------------
        +
        + As of moment of this writing Win64 support is classified "initial"
        + for the following reasons.
        +
        + - No assembler modules are engaged upon initial 0.9.8 release.
        + - API might change within 0.9.8 life-span, *but* in a manner which
        +   doesn't break backward binary compatibility. Or in other words,
        +   application programs compiled with initial 0.9.8 headers will
        +   be expected to work with future minor release .DLL without need
        +   to re-compile, even if future minor release features modified API.
        + - Above mentioned API modifications have everything to do with
        +   elimination of a number of limitations, which are normally
        +   considered inherent to 32-bit platforms. Which in turn is why they
        +   are treated as limitations on 64-bit platform such as Win64:-)
        +   The current list comprises [but not necessarily limited to]:
        +
        +   - null-terminated strings may not be longer than 2G-1 bytes,
        +     longer strings are treated as zero-length;
        +   - dynamically and *internally* allocated chunks can't be larger
        +     than 2G-1 bytes;
        +   - inability to encrypt/decrypt chunks of data larger than 4GB
        +     [it's possibly to *hash* chunks of arbitrary size through];
        +
        +   Neither of these is actually big deal and hardly encountered
        +   in real-life applications.
        +
        + Compiling procedure
        + -------------------
        +
        + You will need Perl. You can run under Cygwin or you can download
        + ActiveState Perl from http://www.activestate.com/ActivePerl.
        +
        + You will need Microsoft Platform SDK, available for download at
        + http://www.microsoft.com/msdownload/platformsdk/sdkupdate/. As per
        + April 2005 Platform SDK is equipped with Win64 compilers, as well
        + as assemblers, but it might change in the future.
        +
        + To build for Win64/x64:
        +
        + > perl Configure VC-WIN64A
        + > ms\do_win64a
        + > nmake -f ms\ntdll.mak
        + > cd out32dll
        + > ..\ms\test
        +
        + To build for Win64/IA64:
        +
        + > perl Configure VC-WIN64I
        + > ms\do_win64i
        + > nmake -f ms\ntdll.mak
        + > cd out32dll
        + > ..\ms\test
        +
        + Naturally test-suite itself has to be executed on the target platform.
        +
        + Installation
        + ------------
        +
        + TBD, for now see INSTALL.W32.
        +
        diff --git a/vendor/openssl/openssl/INSTALL.WCE b/vendor/openssl/openssl/INSTALL.WCE
        new file mode 100644
        index 000000000..d78c61afa
        --- /dev/null
        +++ b/vendor/openssl/openssl/INSTALL.WCE
        @@ -0,0 +1,95 @@
        + 
        + INSTALLATION FOR THE WINDOWS CE PLATFORM
        + ----------------------------------------
        +
        + Building OpenSSL for Windows CE requires the following external tools:
        +
        +  * Microsoft eMbedded Visual C++ 3.0 or later
        +  * Appropriate SDK might be required
        +  * Perl for Win32 [commonly recommended ActiveState Perl is available
        +    from http://www.activestate.com/Products/ActivePerl/]
        +
        +  * wcecompat compatibility library available at
        +    http://www.essemer.com.au/windowsce/
        +  * Optionally ceutils for running automated tests (same location)
        +
        +  _or_
        +
        +  * PocketConsole driver and PortSDK available at
        +    http://www.symbolictools.de/public/pocketconsole/
        +  * CMD command interpreter (same location)
        +
        + As Windows CE support in OpenSSL relies on 3rd party compatibility
        + library, it's appropriate to check corresponding URL for updates. For
        + example if you choose wcecompat, note that as for the moment of this
        + writing version 1.2 is available and actually required for WCE 4.2
        + and newer platforms. All wcecompat issues should be directed to
        + www.essemer.com.au.
        +
        + Why compatibility library at all? The C Runtime Library implementation
        + for Windows CE that is included with Microsoft eMbedded Visual C++ is
        + incomplete and in some places incorrect.  Compatibility library plugs
        + the holes and tries to bring the Windows CE CRT to [more] usable level.
        + Most gaping hole in CRT is support for stdin/stdout/stderr IO, which
        + proposed compatibility libraries solve in two different ways: wcecompat
        + redirects IO to active sync link, while PortSDK - to NT-like console
        + driver on the handheld itself.
        +
        + Building
        + --------
        +
        + Setup the eMbedded Visual C++ environment.  There are batch files for doing
        + this installed with eVC++.  For an ARM processor, for example, execute:
        +
        + > "C:\Program Files\Microsoft eMbedded Tools\EVC\WCE300\BIN\WCEARM.BAT"
        +
        + Next pick compatibility library according to your preferences.
        +
        + 1. To choose wcecompat set up WCECOMPAT environment variable pointing
        +    at the location of wcecompat tree "root":
        +
        +    > set WCECOMPAT=C:\wcecompat
        +    > set PORTSDK_LIBPATH=
        +
        + 2. To choose PortSDK set up PORTSDK_LIBPATH to point at hardware-
        +    specific location where your portlib.lib is installed:
        +
        +    > set PORTSDK_LIBPATH=C:\PortSDK\lib\ARM
        +    > set WCECOMPAT=
        +
        + Note that you may not set both variables.
        +
        + Next you should run Configure:
        +
        + > perl Configure VC-CE
        +
        + Next you need to build the Makefiles:
        +
        + > ms\do_ms
        +
        + If you get errors about things not having numbers assigned then check the
        + troubleshooting section in INSTALL.W32: you probably won't be able to compile
        + it as it stands.
        +
        + Then from the VC++ environment at a prompt do:
        +
        +   > nmake -f ms\cedll.mak
        +
        + [note that static builds are not supported under CE]
        +
        + If all is well it should compile and you will have some DLLs and executables
        + in out32dll*. 
        +
        + <<< everyting below needs revision in respect to wcecompat vs. PortSDK >>>
        +
        + If you want
        + to try the tests then make sure the ceutils are in the path and do:
        + 
        + > cd out32
        + > ..\ms\testce
        +
        + This will copy each of the test programs to the Windows CE device and execute
        + them, displaying the output of the tests on this computer.  The output should
        + look similar to the output produced by running the tests for a regular Windows
        + build.
        +
        diff --git a/vendor/openssl/openssl/LICENSE b/vendor/openssl/openssl/LICENSE
        new file mode 100644
        index 000000000..e47d101f1
        --- /dev/null
        +++ b/vendor/openssl/openssl/LICENSE
        @@ -0,0 +1,127 @@
        +
        +  LICENSE ISSUES
        +  ==============
        +
        +  The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
        +  the OpenSSL License and the original SSLeay license apply to the toolkit.
        +  See below for the actual license texts. Actually both licenses are BSD-style
        +  Open Source licenses. In case of any license issues related to OpenSSL
        +  please contact openssl-core@openssl.org.
        +
        +  OpenSSL License
        +  ---------------
        +
        +/* ====================================================================
        + * Copyright (c) 1998-2011 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).
        + *
        + */
        +
        + Original SSLeay License
        + -----------------------
        +
        +/* 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.]
        + */
        +
        diff --git a/vendor/openssl/openssl/MacOS/GUSI_Init.cpp b/vendor/openssl/openssl/MacOS/GUSI_Init.cpp
        new file mode 100644
        index 000000000..d8223dba2
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GUSI_Init.cpp
        @@ -0,0 +1,62 @@
        +/**************** BEGIN GUSI CONFIGURATION ****************************
        + *
        + * GUSI Configuration section generated by GUSI Configurator
        + * last modified: Wed Jan  5 20:33:51 2000
        + *
        + * This section will be overwritten by the next run of Configurator.
        + */
        +
        +#define GUSI_SOURCE
        +#include <GUSIConfig.h>
        +#include <sys/cdefs.h>
        +
        +/* Declarations of Socket Factories */
        +
        +__BEGIN_DECLS
        +void GUSIwithInetSockets();
        +void GUSIwithLocalSockets();
        +void GUSIwithMTInetSockets();
        +void GUSIwithMTTcpSockets();
        +void GUSIwithMTUdpSockets();
        +void GUSIwithOTInetSockets();
        +void GUSIwithOTTcpSockets();
        +void GUSIwithOTUdpSockets();
        +void GUSIwithPPCSockets();
        +void GUSISetupFactories();
        +__END_DECLS
        +
        +/* Configure Socket Factories */
        +
        +void GUSISetupFactories()
        +{
        +#ifdef GUSISetupFactories_BeginHook
        +	GUSISetupFactories_BeginHook
        +#endif
        +	GUSIwithInetSockets();
        +#ifdef GUSISetupFactories_EndHook
        +	GUSISetupFactories_EndHook
        +#endif
        +}
        +
        +/* Declarations of File Devices */
        +
        +__BEGIN_DECLS
        +void GUSIwithDConSockets();
        +void GUSIwithNullSockets();
        +void GUSISetupDevices();
        +__END_DECLS
        +
        +/* Configure File Devices */
        +
        +void GUSISetupDevices()
        +{
        +#ifdef GUSISetupDevices_BeginHook
        +	GUSISetupDevices_BeginHook
        +#endif
        +	GUSIwithNullSockets();
        +#ifdef GUSISetupDevices_EndHook
        +	GUSISetupDevices_EndHook
        +#endif
        +}
        +
        +/**************** END GUSI CONFIGURATION *************************/
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/CPStringUtils.cpp b/vendor/openssl/openssl/MacOS/GetHTTPS.src/CPStringUtils.cpp
        new file mode 100644
        index 000000000..617aae2c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/CPStringUtils.cpp
        @@ -0,0 +1,2753 @@
        +/* ====================================================================
        + * Copyright (c) 1998-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).
        + *
        + */
        + 
        + 
        + 
        + #include "CPStringUtils.hpp"
        +#include "ErrorHandling.hpp"
        +
        +
        +
        +#define kNumberFormatString			"\p########0.00#######;-########0.00#######"
        +
        +
        +
        +//	Useful utility functions which could be optimized a whole lot
        +
        +
        +void CopyPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength)
        +{
        +int		i,numPChars;
        +
        +
        +	if (thePStr != nil && theCStr != nil && maxCStrLength > 0)
        +	{
        +		numPChars = thePStr[0];
        +		
        +		for (i = 0;;i++)
        +		{
        +			if (i >= numPChars || i >= maxCStrLength - 1)
        +			{
        +				theCStr[i] = 0;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theCStr[i] = thePStr[i + 1];
        +			}
        +		}
        +	}
        +}
        +
        +
        +void CopyPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength)
        +{
        +int		theMaxDstStrLength;
        +
        +	
        +	theMaxDstStrLength = maxDstStrLength;
        +	
        +	
        +	if (theDstPStr != nil && theSrcPStr != nil && theMaxDstStrLength > 0)
        +	{
        +		if (theMaxDstStrLength > 255)
        +		{
        +			theMaxDstStrLength = 255;
        +		}
        +		
        +		
        +		if (theMaxDstStrLength - 1 < theSrcPStr[0])
        +		{
        +			BlockMove(theSrcPStr + 1,theDstPStr + 1,theMaxDstStrLength - 1);
        +			
        +			theDstPStr[0] = theMaxDstStrLength - 1;
        +		}
        +		
        +		else
        +		{
        +			BlockMove(theSrcPStr,theDstPStr,theSrcPStr[0] + 1);
        +		}
        +	}
        +}
        +
        +
        +void CopyCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxDstStrLength)
        +{
        +int		i;
        +
        +
        +	if (theDstCStr != nil && theSrcCStr != nil && maxDstStrLength > 0)
        +	{
        +		for (i = 0;;i++)
        +		{
        +			if (theSrcCStr[i] == 0 || i >= maxDstStrLength - 1)
        +			{
        +				theDstCStr[i] = 0;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theDstCStr[i] = theSrcCStr[i];
        +			}
        +		}
        +	}
        +}
        +
        +
        +
        +void CopyCSubstrToCStr(const char *theSrcCStr,const int maxCharsToCopy,char *theDstCStr,const int maxDstStrLength)
        +{
        +int		i;
        +
        +
        +	if (theDstCStr != nil && theSrcCStr != nil && maxDstStrLength > 0)
        +	{
        +		for (i = 0;;i++)
        +		{
        +			if (theSrcCStr[i] == 0 || i >= maxDstStrLength - 1 || i >= maxCharsToCopy)
        +			{
        +				theDstCStr[i] = 0;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theDstCStr[i] = theSrcCStr[i];
        +			}
        +		}
        +	}
        +}
        +
        +
        +
        +void CopyCSubstrToPStr(const char *theSrcCStr,const int maxCharsToCopy,unsigned char *theDstPStr,const int maxDstStrLength)
        +{
        +int		i;
        +int		theMaxDstStrLength;
        +
        +	
        +	theMaxDstStrLength = maxDstStrLength;
        +
        +	if (theDstPStr != nil && theSrcCStr != nil && theMaxDstStrLength > 0)
        +	{
        +		if (theMaxDstStrLength > 255)
        +		{
        +			theMaxDstStrLength = 255;
        +		}
        +		
        +		
        +		for (i = 0;;i++)
        +		{
        +			if (theSrcCStr[i] == 0 || i >= theMaxDstStrLength - 1 || i >= maxCharsToCopy)
        +			{
        +				theDstPStr[0] = i;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theDstPStr[i + 1] = theSrcCStr[i];
        +			}
        +		}
        +	}
        +}
        +
        +
        +
        +void CopyCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength)
        +{
        +int		i;
        +int		theMaxDstStrLength;
        +
        +	
        +	theMaxDstStrLength = maxDstStrLength;
        +
        +	if (theDstPStr != nil && theSrcCStr != nil && theMaxDstStrLength > 0)
        +	{
        +		if (theMaxDstStrLength > 255)
        +		{
        +			theMaxDstStrLength = 255;
        +		}
        +		
        +		
        +		for (i = 0;;i++)
        +		{
        +			if (i >= theMaxDstStrLength - 1 || theSrcCStr[i] == 0)
        +			{
        +				theDstPStr[0] = i;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theDstPStr[i + 1] = theSrcCStr[i];
        +			}
        +		}
        +	}
        +}
        +
        +
        +void ConcatPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength)
        +{
        +int		i,numPChars,cStrLength;
        +
        +
        +	if (thePStr != nil && theCStr != nil && maxCStrLength > 0)
        +	{
        +		for (cStrLength = 0;theCStr[cStrLength] != 0;cStrLength++)
        +		{
        +		
        +		}
        +		
        +
        +		numPChars = thePStr[0];
        +		
        +		
        +		for (i = 0;;i++)
        +		{
        +			if (i >= numPChars || cStrLength >= maxCStrLength - 1)
        +			{
        +				theCStr[cStrLength++] = 0;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theCStr[cStrLength++] = thePStr[i + 1];
        +			}
        +		}
        +	}
        +}
        +
        +
        +
        +void ConcatPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength)
        +{
        +int		theMaxDstStrLength;
        +
        +	
        +	theMaxDstStrLength = maxDstStrLength;
        +	
        +	if (theSrcPStr != nil && theDstPStr != nil && theMaxDstStrLength > 0)
        +	{
        +		if (theMaxDstStrLength > 255)
        +		{
        +			theMaxDstStrLength = 255;
        +		}
        +		
        +		
        +		if (theMaxDstStrLength - theDstPStr[0] - 1 < theSrcPStr[0])
        +		{
        +			BlockMove(theSrcPStr + 1,theDstPStr + theDstPStr[0] + 1,theMaxDstStrLength - 1 - theDstPStr[0]);
        +			
        +			theDstPStr[0] = theMaxDstStrLength - 1;
        +		}
        +		
        +		else
        +		{
        +			BlockMove(theSrcPStr + 1,theDstPStr + theDstPStr[0] + 1,theSrcPStr[0]);
        +			
        +			theDstPStr[0] += theSrcPStr[0];
        +		}
        +	}
        +}
        +
        +
        +
        +void ConcatCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength)
        +{
        +int		i,thePStrLength;
        +int		theMaxDstStrLength;
        +
        +	
        +	theMaxDstStrLength = maxDstStrLength;
        +
        +	if (theSrcCStr != nil && theDstPStr != nil && theMaxDstStrLength > 0)
        +	{
        +		if (theMaxDstStrLength > 255)
        +		{
        +			theMaxDstStrLength = 255;
        +		}
        +		
        +		
        +		thePStrLength = theDstPStr[0];
        +		
        +		for (i = 0;;i++)
        +		{
        +			if (theSrcCStr[i] == 0 || thePStrLength >= theMaxDstStrLength - 1)
        +			{
        +				theDstPStr[0] = thePStrLength;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theDstPStr[thePStrLength + 1] = theSrcCStr[i];
        +				
        +				thePStrLength++;
        +			}
        +		}
        +	}
        +}
        +
        +
        +
        +void ConcatCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxCStrLength)
        +{
        +int		cStrLength;
        +
        +
        +	if (theSrcCStr != nil && theDstCStr != nil && maxCStrLength > 0)
        +	{
        +		for (cStrLength = 0;theDstCStr[cStrLength] != 0;cStrLength++)
        +		{
        +		
        +		}
        +		
        +
        +		for (;;)
        +		{
        +			if (*theSrcCStr == 0 || cStrLength >= maxCStrLength - 1)
        +			{
        +				theDstCStr[cStrLength++] = 0;
        +				
        +				break;
        +			}
        +			
        +			else
        +			{
        +				theDstCStr[cStrLength++] = *theSrcCStr++;
        +			}
        +		}
        +	}
        +}
        +
        +
        +
        +void ConcatCharToCStr(const char theChar,char *theDstCStr,const int maxCStrLength)
        +{
        +int		cStrLength;
        +
        +
        +	if (theDstCStr != nil && maxCStrLength > 0)
        +	{
        +		cStrLength = CStrLength(theDstCStr);
        +		
        +		if (cStrLength < maxCStrLength - 1)
        +		{
        +			theDstCStr[cStrLength++] = theChar;
        +			theDstCStr[cStrLength++] = '\0';
        +		}
        +	}
        +}
        +
        +
        +
        +void ConcatCharToPStr(const char theChar,unsigned char *theDstPStr,const int maxPStrLength)
        +{
        +int		pStrLength;
        +
        +
        +	if (theDstPStr != nil && maxPStrLength > 0)
        +	{
        +		pStrLength = PStrLength(theDstPStr);
        +		
        +		if (pStrLength < maxPStrLength - 1 && pStrLength < 255)
        +		{
        +			theDstPStr[pStrLength + 1] = theChar;
        +			theDstPStr[0] += 1;
        +		}
        +	}
        +}
        +
        +
        +
        +
        +int CompareCStrs(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase)
        +{
        +int		returnValue;
        +char	firstChar,secondChar;
        +
        +	
        +	returnValue = 0;
        +	
        +	
        +	if (theFirstCStr != nil && theSecondCStr != nil)
        +	{
        +		for (;;)
        +		{
        +			firstChar = *theFirstCStr;
        +			secondChar = *theSecondCStr;
        +			
        +			if (ignoreCase == true)
        +			{
        +				if (firstChar >= 'A' && firstChar <= 'Z')
        +				{
        +					firstChar = 'a' + (firstChar - 'A');
        +				}
        +				
        +				if (secondChar >= 'A' && secondChar <= 'Z')
        +				{
        +					secondChar = 'a' + (secondChar - 'A');
        +				}
        +			}
        +			
        +			
        +			if (firstChar == 0 && secondChar != 0)
        +			{
        +				returnValue = -1;
        +				
        +				break;
        +			}
        +			
        +			else if (firstChar != 0 && secondChar == 0)
        +			{
        +				returnValue = 1;
        +				
        +				break;
        +			}
        +			
        +			else if (firstChar == 0 && secondChar == 0)
        +			{
        +				returnValue = 0;
        +				
        +				break;
        +			}
        +			
        +			else if (firstChar < secondChar)
        +			{
        +				returnValue = -1;
        +				
        +				break;
        +			}
        +			
        +			else if (firstChar > secondChar)
        +			{
        +				returnValue = 1;
        +				
        +				break;
        +			}
        +			
        +			theFirstCStr++;
        +			theSecondCStr++;
        +		}
        +	}
        +	
        +	
        +	return(returnValue);
        +}
        +
        +
        +
        +Boolean CStrsAreEqual(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase)
        +{
        +	if (CompareCStrs(theFirstCStr,theSecondCStr,ignoreCase) == 0)
        +	{
        +		return true;
        +	}
        +	
        +	else
        +	{
        +		return false;
        +	}
        +}
        +
        +
        +Boolean PStrsAreEqual(const unsigned char *theFirstPStr,const unsigned char *theSecondPStr,const Boolean ignoreCase)
        +{
        +	if (ComparePStrs(theFirstPStr,theSecondPStr,ignoreCase) == 0)
        +	{
        +		return true;
        +	}
        +	
        +	else
        +	{
        +		return false;
        +	}
        +}
        +
        +
        +
        +int ComparePStrs(const unsigned char *theFirstPStr,const unsigned char *theSecondPStr,const Boolean ignoreCase)
        +{
        +int		i,returnValue;
        +char	firstChar,secondChar;
        +
        +	
        +	returnValue = 0;
        +	
        +	
        +	if (theFirstPStr != nil && theSecondPStr != nil)
        +	{
        +		for (i = 1;;i++)
        +		{
        +			firstChar = theFirstPStr[i];
        +			secondChar = theSecondPStr[i];
        +
        +			if (ignoreCase == true)
        +			{
        +				if (firstChar >= 'A' && firstChar <= 'Z')
        +				{
        +					firstChar = 'a' + (firstChar - 'A');
        +				}
        +				
        +				if (secondChar >= 'A' && secondChar <= 'Z')
        +				{
        +					secondChar = 'a' + (secondChar - 'A');
        +				}
        +			}
        +
        +
        +			if (theFirstPStr[0] < i && theSecondPStr[0] >= i)
        +			{
        +				returnValue = -1;
        +				
        +				break;
        +			}
        +			
        +			else if (theFirstPStr[0] >= i && theSecondPStr[0] < i)
        +			{
        +				returnValue = 1;
        +				
        +				break;
        +			}
        +			
        +			else if (theFirstPStr[0] < i && theSecondPStr[0] < i)
        +			{
        +				returnValue = 0;
        +				
        +				break;
        +			}
        +			
        +			else if (firstChar < secondChar)
        +			{
        +				returnValue = -1;
        +				
        +				break;
        +			}
        +			
        +			else if (firstChar > secondChar)
        +			{
        +				returnValue = 1;
        +				
        +				break;
        +			}
        +		}
        +	}
        +	
        +	
        +	return(returnValue);
        +}
        +
        +
        +
        +int CompareCStrToPStr(const char *theCStr,const unsigned char *thePStr,const Boolean ignoreCase)
        +{
        +int		returnValue;
        +char	tempString[256];
        +
        +	
        +	returnValue = 0;
        +	
        +	if (theCStr != nil && thePStr != nil)
        +	{
        +		CopyPStrToCStr(thePStr,tempString,sizeof(tempString));
        +		
        +		returnValue = CompareCStrs(theCStr,tempString,ignoreCase);
        +	}
        +	
        +	
        +	return(returnValue);
        +}
        +
        +
        +
        +void ConcatLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits)
        +{
        +Str255 		theStr255;
        +
        +
        +	NumToString(theNum,theStr255);
        +
        +
        +	if (numDigits > 0)
        +	{
        +	int 	charsToInsert;
        +	
        +		
        +		charsToInsert = numDigits - PStrLength(theStr255);
        +		
        +		if (charsToInsert > 0)
        +		{
        +		char	tempString[256];
        +			
        +			CopyCStrToCStr("",tempString,sizeof(tempString));
        +			
        +			for (;charsToInsert > 0;charsToInsert--)
        +			{
        +				ConcatCStrToCStr("0",tempString,sizeof(tempString));
        +			}
        +			
        +			ConcatPStrToCStr(theStr255,tempString,sizeof(tempString));
        +			
        +			CopyCStrToPStr(tempString,theStr255,sizeof(theStr255));
        +		}
        +	}
        +
        +
        +	ConcatPStrToCStr(theStr255,theCStr,maxCStrLength);
        +}
        +
        +
        +
        +
        +void ConcatLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits)
        +{
        +Str255 		theStr255;
        +
        +
        +	NumToString(theNum,theStr255);
        +
        +
        +	if (numDigits > 0)
        +	{
        +	int 	charsToInsert;
        +	
        +		
        +		charsToInsert = numDigits - PStrLength(theStr255);
        +		
        +		if (charsToInsert > 0)
        +		{
        +		char	tempString[256];
        +			
        +			CopyCStrToCStr("",tempString,sizeof(tempString));
        +			
        +			for (;charsToInsert > 0;charsToInsert--)
        +			{
        +				ConcatCStrToCStr("0",tempString,sizeof(tempString));
        +			}
        +			
        +			ConcatPStrToCStr(theStr255,tempString,sizeof(tempString));
        +			
        +			CopyCStrToPStr(tempString,theStr255,sizeof(theStr255));
        +		}
        +	}
        +
        +
        +	ConcatPStrToPStr(theStr255,thePStr,maxPStrLength);
        +}
        +
        +
        +
        +void CopyCStrAndConcatLongIntToCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength)
        +{
        +	CopyCStrToCStr(theSrcCStr,theDstCStr,maxDstStrLength);
        +	
        +	ConcatLongIntToCStr(theNum,theDstCStr,maxDstStrLength);
        +}
        +
        +
        +
        +void CopyLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits)
        +{
        +Str255 		theStr255;
        +
        +
        +	NumToString(theNum,theStr255);
        +
        +
        +	if (numDigits > 0)
        +	{
        +	int 	charsToInsert;
        +	
        +		
        +		charsToInsert = numDigits - PStrLength(theStr255);
        +		
        +		if (charsToInsert > 0)
        +		{
        +		char	tempString[256];
        +			
        +			CopyCStrToCStr("",tempString,sizeof(tempString));
        +			
        +			for (;charsToInsert > 0;charsToInsert--)
        +			{
        +				ConcatCStrToCStr("0",tempString,sizeof(tempString));
        +			}
        +			
        +			ConcatPStrToCStr(theStr255,tempString,sizeof(tempString));
        +			
        +			CopyCStrToPStr(tempString,theStr255,sizeof(theStr255));
        +		}
        +	}
        +
        +
        +	CopyPStrToCStr(theStr255,theCStr,maxCStrLength);
        +}
        +
        +
        +
        +
        +
        +void CopyUnsignedLongIntToCStr(const unsigned long theNum,char *theCStr,const int maxCStrLength)
        +{
        +char			tempString[256];
        +int				srcCharIndex,dstCharIndex;
        +unsigned long	tempNum,quotient,remainder;
        +
        +	
        +	if (theNum == 0)
        +	{
        +		CopyCStrToCStr("0",theCStr,maxCStrLength);
        +	}
        +	
        +	else
        +	{
        +		srcCharIndex = 0;
        +		
        +		tempNum = theNum;
        +		
        +		for (;;)
        +		{
        +			if (srcCharIndex >= sizeof(tempString) - 1 || tempNum == 0)
        +			{
        +				for (dstCharIndex = 0;;)
        +				{
        +					if (dstCharIndex >= maxCStrLength - 1 || srcCharIndex <= 0)
        +					{
        +						theCStr[dstCharIndex] = 0;
        +						
        +						break;
        +					}
        +					
        +					theCStr[dstCharIndex++] = tempString[--srcCharIndex];
        +				}
        +				
        +				break;
        +			}
        +			
        +
        +			quotient = tempNum / 10;
        +			
        +			remainder = tempNum - (quotient * 10);
        +			
        +			tempString[srcCharIndex] = '0' + remainder;
        +			
        +			srcCharIndex++;
        +			
        +			tempNum = quotient;
        +		}
        +	}
        +}
        +
        +
        +
        +
        +void CopyLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits)
        +{
        +char	tempString[256];
        +
        +
        +	CopyLongIntToCStr(theNum,tempString,sizeof(tempString),numDigits);
        +	
        +	CopyCStrToPStr(tempString,thePStr,maxPStrLength);
        +}
        +
        +
        +
        +OSErr CopyLongIntToNewHandle(const long inTheLongInt,Handle *theHandle)
        +{
        +OSErr		errCode = noErr;
        +char		tempString[32];
        +	
        +	
        +	CopyLongIntToCStr(inTheLongInt,tempString,sizeof(tempString));
        +	
        +	errCode = CopyCStrToNewHandle(tempString,theHandle);
        +
        +	return(errCode);
        +}
        +
        +
        +OSErr CopyLongIntToExistingHandle(const long inTheLongInt,Handle theHandle)
        +{
        +OSErr		errCode = noErr;
        +char		tempString[32];
        +	
        +	
        +	CopyLongIntToCStr(inTheLongInt,tempString,sizeof(tempString));
        +	
        +	errCode = CopyCStrToExistingHandle(tempString,theHandle);
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +OSErr CopyCStrToExistingHandle(const char *theCString,Handle theHandle)
        +{
        +OSErr	errCode = noErr;
        +long	stringLength;
        +
        +	
        +	if (theCString == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyCStrToExistingHandle: Bad parameter, theCString == nil"));
        +	}
        +
        +	if (theHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyCStrToExistingHandle: Bad parameter, theHandle == nil"));
        +	}
        +
        +	if (*theHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyCStrToExistingHandle: Bad parameter, *theHandle == nil"));
        +	}
        +
        +
        +
        +	stringLength = CStrLength(theCString) + 1;
        +	
        +	SetHandleSize(theHandle,stringLength);
        +	
        +	if (GetHandleSize(theHandle) < stringLength)
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyCStrToExistingHandle: Can't set Handle size, MemError() = ",MemError());
        +	}
        +	
        +	
        +	::BlockMove(theCString,*theHandle,stringLength);
        +	
        +
        +EXITPOINT:
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +
        +
        +OSErr CopyCStrToNewHandle(const char *theCString,Handle *theHandle)
        +{
        +OSErr	errCode = noErr;
        +long	stringLength;
        +
        +	
        +	if (theCString == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyCStrToNewHandle: Bad parameter, theCString == nil"));
        +	}
        +
        +	if (theHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyCStrToNewHandle: Bad parameter, theHandle == nil"));
        +	}
        +
        +
        +
        +	stringLength = CStrLength(theCString) + 1;
        +	
        +	*theHandle = NewHandle(stringLength);
        +	
        +	if (*theHandle == nil)
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyCStrToNewHandle: Can't allocate Handle, MemError() = ",MemError());
        +	}
        +	
        +	
        +	::BlockMove(theCString,**theHandle,stringLength);
        +	
        +
        +EXITPOINT:
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr CopyPStrToNewHandle(const unsigned char *thePString,Handle *theHandle)
        +{
        +OSErr	errCode = noErr;
        +long	stringLength;
        +
        +	
        +	if (thePString == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyPStrToNewHandle: Bad parameter, thePString == nil"));
        +	}
        +
        +	if (theHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyPStrToNewHandle: Bad parameter, theHandle == nil"));
        +	}
        +
        +
        +
        +	stringLength = PStrLength(thePString) + 1;
        +	
        +	*theHandle = NewHandle(stringLength);
        +	
        +	if (*theHandle == nil)
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyPStrToNewHandle: Can't allocate Handle, MemError() = ",MemError());
        +	}
        +	
        +	
        +	if (stringLength > 1)
        +	{
        +		BlockMove(thePString + 1,**theHandle,stringLength - 1);
        +	}
        +	
        +	(**theHandle)[stringLength - 1] = 0;
        +	
        +
        +EXITPOINT:
        +	
        +	return(errCode);
        +}
        +
        +
        +OSErr AppendPStrToHandle(const unsigned char *thePString,Handle theHandle,long *currentLength)
        +{
        +OSErr		errCode = noErr;
        +char		tempString[256];
        +
        +	
        +	CopyPStrToCStr(thePString,tempString,sizeof(tempString));
        +	
        +	errCode = AppendCStrToHandle(tempString,theHandle,currentLength);
        +	
        +
        +EXITPOINT:
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr AppendCStrToHandle(const char *theCString,Handle theHandle,long *currentLength,long *maxLength)
        +{
        +OSErr		errCode = noErr;
        +long		handleMaxLength,handleCurrentLength,stringLength,byteCount;
        +
        +
        +	if (theCString == nil)
        +	{
        +		SetErrorMessageAndBail(("AppendCStrToHandle: Bad parameter, theCString == nil"));
        +	}
        +
        +	if (theHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("AppendCStrToHandle: Bad parameter, theHandle == nil"));
        +	}
        +	
        +	
        +	if (maxLength != nil)
        +	{
        +		handleMaxLength = *maxLength;
        +	}
        +	
        +	else
        +	{
        +		handleMaxLength = GetHandleSize(theHandle);
        +	}
        +	
        +	
        +	if (currentLength != nil && *currentLength >= 0)
        +	{
        +		handleCurrentLength = *currentLength;
        +	}
        +	
        +	else
        +	{
        +		handleCurrentLength = CStrLength(*theHandle);
        +	}
        +	
        +	
        +	stringLength = CStrLength(theCString);
        +	
        +	byteCount = handleCurrentLength + stringLength + 1;
        +	
        +	if (byteCount > handleMaxLength)
        +	{
        +		SetHandleSize(theHandle,handleCurrentLength + stringLength + 1);
        +		
        +		if (maxLength != nil)
        +		{
        +			*maxLength = GetHandleSize(theHandle);
        +			
        +			handleMaxLength = *maxLength;
        +		}
        +		
        +		else
        +		{
        +			handleMaxLength = GetHandleSize(theHandle);
        +		}
        +
        +		if (byteCount > handleMaxLength)
        +		{
        +			SetErrorMessageAndLongIntAndBail("AppendCStrToHandle: Can't increase Handle allocation, MemError() = ",MemError());
        +		}
        +	}
        +	
        +	
        +	BlockMove(theCString,*theHandle + handleCurrentLength,stringLength + 1);
        +	
        +	
        +	if (currentLength != nil)
        +	{
        +		*currentLength += stringLength;
        +	}
        +
        +
        +	errCode = noErr;
        +	
        +	
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr AppendCharsToHandle(const char *theChars,const int numChars,Handle theHandle,long *currentLength,long *maxLength)
        +{
        +OSErr		errCode = noErr;
        +long		handleMaxLength,handleCurrentLength,byteCount;
        +
        +
        +	if (theChars == nil)
        +	{
        +		SetErrorMessageAndBail(("AppendCharsToHandle: Bad parameter, theChars == nil"));
        +	}
        +
        +	if (theHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("AppendCharsToHandle: Bad parameter, theHandle == nil"));
        +	}
        +	
        +	
        +	if (maxLength != nil)
        +	{
        +		handleMaxLength = *maxLength;
        +	}
        +	
        +	else
        +	{
        +		handleMaxLength = GetHandleSize(theHandle);
        +	}
        +	
        +	
        +	if (currentLength != nil && *currentLength >= 0)
        +	{
        +		handleCurrentLength = *currentLength;
        +	}
        +	
        +	else
        +	{
        +		handleCurrentLength = CStrLength(*theHandle);
        +	}
        +	
        +	
        +	byteCount = handleCurrentLength + numChars + 1;
        +	
        +	if (byteCount > handleMaxLength)
        +	{
        +		SetHandleSize(theHandle,handleCurrentLength + numChars + 1);
        +		
        +		if (maxLength != nil)
        +		{
        +			*maxLength = GetHandleSize(theHandle);
        +			
        +			handleMaxLength = *maxLength;
        +		}
        +		
        +		else
        +		{
        +			handleMaxLength = GetHandleSize(theHandle);
        +		}
        +
        +		if (byteCount > handleMaxLength)
        +		{
        +			SetErrorMessageAndLongIntAndBail("AppendCharsToHandle: Can't increase Handle allocation, MemError() = ",MemError());
        +		}
        +	}
        +	
        +	
        +	BlockMove(theChars,*theHandle + handleCurrentLength,numChars);
        +	
        +	(*theHandle)[handleCurrentLength + numChars] = '\0';
        +	
        +	if (currentLength != nil)
        +	{
        +		*currentLength += numChars;
        +	}
        +
        +
        +	errCode = noErr;
        +	
        +	
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr AppendLongIntToHandle(const long inTheLongInt,Handle theHandle,long *currentLength)
        +{
        +OSErr		errCode = noErr;
        +char		tempString[32];
        +	
        +	
        +	CopyLongIntToCStr(inTheLongInt,tempString,sizeof(tempString));
        +	
        +	errCode = AppendCStrToHandle(tempString,theHandle,currentLength);
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +long CStrLength(const char *theCString)
        +{
        +long	cStrLength = 0;
        +
        +	
        +	if (theCString != nil)
        +	{
        +		for (cStrLength = 0;theCString[cStrLength] != 0;cStrLength++)
        +		{
        +		
        +		}
        +	}
        +	
        +	
        +	return(cStrLength);
        +}
        +
        +
        +
        +long PStrLength(const unsigned char *thePString)
        +{
        +long	pStrLength = 0;
        +
        +	
        +	if (thePString != nil)
        +	{
        +		pStrLength = thePString[0];
        +	}
        +	
        +	
        +	return(pStrLength);
        +}
        +
        +
        +
        +
        +
        +void ZeroMem(void *theMemPtr,const unsigned long numBytes)
        +{
        +unsigned char	*theBytePtr;
        +unsigned long	*theLongPtr;
        +unsigned long	numSingleBytes;
        +unsigned long	theNumBytes;
        +
        +	
        +	theNumBytes = numBytes;
        +	
        +	if (theMemPtr != nil && theNumBytes > 0)
        +	{
        +		theBytePtr = (unsigned char	*) theMemPtr;
        +		
        +		numSingleBytes = (unsigned long) theBytePtr & 0x0003;
        +		
        +		while (numSingleBytes > 0)
        +		{
        +			*theBytePtr++ = 0;
        +			
        +			theNumBytes--;
        +			numSingleBytes--;
        +		}
        +		
        +
        +		theLongPtr = (unsigned long	*) theBytePtr;
        +		
        +		while (theNumBytes >= 4)
        +		{
        +			*theLongPtr++ = 0;
        +			
        +			theNumBytes -= 4;
        +		}
        +		
        +		
        +		theBytePtr = (unsigned char	*) theLongPtr;
        +		
        +		while (theNumBytes > 0)
        +		{
        +			*theBytePtr++ = 0;
        +			
        +			theNumBytes--;
        +		}
        +	}
        +}
        +
        +
        +
        +
        +char *FindCharInCStr(const char theChar,const char *theCString)
        +{
        +char	*theStringSearchPtr;
        +
        +	
        +	theStringSearchPtr = (char	*) theCString;
        +	
        +	if (theStringSearchPtr != nil)
        +	{
        +		while (*theStringSearchPtr != '\0' && *theStringSearchPtr != theChar)
        +		{
        +			theStringSearchPtr++;
        +		}
        +		
        +		if (*theStringSearchPtr == '\0')
        +		{
        +			theStringSearchPtr = nil;
        +		}
        +	}
        +	
        +	return(theStringSearchPtr);
        +}
        +
        +
        +
        +long FindCharOffsetInCStr(const char theChar,const char *theCString,const Boolean inIgnoreCase)
        +{
        +long	theOffset = -1;
        +
        +
        +	if (theCString != nil)
        +	{
        +		theOffset = 0;
        +		
        +
        +		if (inIgnoreCase)
        +		{
        +		char	searchChar = theChar;
        +		
        +			if (searchChar >= 'a' && searchChar <= 'z')
        +			{
        +				searchChar = searchChar - 'a' + 'A';
        +			}
        +			
        +			
        +			while (*theCString != 0)
        +			{
        +			char	currentChar = *theCString;
        +			
        +				if (currentChar >= 'a' && currentChar <= 'z')
        +				{
        +					currentChar = currentChar - 'a' + 'A';
        +				}
        +			
        +				if (currentChar == searchChar)
        +				{
        +					break;
        +				}
        +				
        +				theCString++;
        +				theOffset++;
        +			}
        +		}
        +		
        +		else
        +		{
        +			while (*theCString != 0 && *theCString != theChar)
        +			{
        +				theCString++;
        +				theOffset++;
        +			}
        +		}
        +		
        +		if (*theCString == 0)
        +		{
        +			theOffset = -1;
        +		}
        +	}
        +	
        +	return(theOffset);
        +}
        +
        +
        +long FindCStrOffsetInCStr(const char *theCSubstring,const char *theCString,const Boolean inIgnoreCase)
        +{
        +long	theOffset = -1;
        +
        +
        +	if (theCSubstring != nil && theCString != nil)
        +	{
        +		for (theOffset = 0;;theOffset++)
        +		{
        +			if (theCString[theOffset] == 0)
        +			{
        +				theOffset = -1;
        +				
        +				goto EXITPOINT;
        +			}
        +			
        +			
        +			for (const char	*tempSubstringPtr = theCSubstring,*tempCStringPtr = theCString + theOffset;;tempSubstringPtr++,tempCStringPtr++)
        +			{
        +				if (*tempSubstringPtr == 0)
        +				{
        +					goto EXITPOINT;
        +				}
        +				
        +				else if (*tempCStringPtr == 0)
        +				{
        +					break;
        +				}
        +			
        +			char	searchChar = *tempSubstringPtr;
        +			char	currentChar = *tempCStringPtr;
        +			
        +				if (inIgnoreCase && searchChar >= 'a' && searchChar <= 'z')
        +				{
        +					searchChar = searchChar - 'a' + 'A';
        +				}
        +				
        +				if (inIgnoreCase && currentChar >= 'a' && currentChar <= 'z')
        +				{
        +					currentChar = currentChar - 'a' + 'A';
        +				}
        +				
        +				if (currentChar != searchChar)
        +				{
        +					break;
        +				}
        +			}
        +		}
        +		
        +		theOffset = -1;
        +	}
        +
        +
        +EXITPOINT:
        +	
        +	return(theOffset);
        +}
        +
        +
        +
        +void InsertCStrIntoCStr(const char *theSrcCStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength)
        +{
        +int		currentLength;
        +int		insertLength;
        +int		numCharsToInsert;
        +int		numCharsToShift;
        +
        +	
        +	if (theDstCStr != nil && theSrcCStr != nil && maxDstStrLength > 0 && theInsertionOffset < maxDstStrLength - 1)
        +	{
        +		currentLength = CStrLength(theDstCStr);
        +		
        +		insertLength = CStrLength(theSrcCStr);
        +		
        +
        +		if (theInsertionOffset + insertLength < maxDstStrLength - 1)
        +		{
        +			numCharsToInsert = insertLength;
        +		}
        +		
        +		else
        +		{
        +			numCharsToInsert = maxDstStrLength - 1 - theInsertionOffset;
        +		}
        +		
        +
        +		if (numCharsToInsert + currentLength < maxDstStrLength - 1)
        +		{
        +			numCharsToShift = currentLength - theInsertionOffset;
        +		}
        +		
        +		else
        +		{
        +			numCharsToShift = maxDstStrLength - 1 - theInsertionOffset - numCharsToInsert;
        +		}
        +
        +		
        +		if (numCharsToShift > 0)
        +		{
        +			BlockMove(theDstCStr + theInsertionOffset,theDstCStr + theInsertionOffset + numCharsToInsert,numCharsToShift);
        +		}
        +		
        +		if (numCharsToInsert > 0)
        +		{
        +			BlockMove(theSrcCStr,theDstCStr + theInsertionOffset,numCharsToInsert);
        +		}
        +		
        +		theDstCStr[theInsertionOffset + numCharsToInsert + numCharsToShift] = 0;
        +	}
        +}
        +
        +
        +
        +void InsertPStrIntoCStr(const unsigned char *theSrcPStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength)
        +{
        +int		currentLength;
        +int		insertLength;
        +int		numCharsToInsert;
        +int		numCharsToShift;
        +
        +	
        +	if (theDstCStr != nil && theSrcPStr != nil && maxDstStrLength > 0 && theInsertionOffset < maxDstStrLength - 1)
        +	{
        +		currentLength = CStrLength(theDstCStr);
        +		
        +		insertLength = PStrLength(theSrcPStr);
        +		
        +
        +		if (theInsertionOffset + insertLength < maxDstStrLength - 1)
        +		{
        +			numCharsToInsert = insertLength;
        +		}
        +		
        +		else
        +		{
        +			numCharsToInsert = maxDstStrLength - 1 - theInsertionOffset;
        +		}
        +		
        +
        +		if (numCharsToInsert + currentLength < maxDstStrLength - 1)
        +		{
        +			numCharsToShift = currentLength - theInsertionOffset;
        +		}
        +		
        +		else
        +		{
        +			numCharsToShift = maxDstStrLength - 1 - theInsertionOffset - numCharsToInsert;
        +		}
        +
        +		
        +		if (numCharsToShift > 0)
        +		{
        +			BlockMove(theDstCStr + theInsertionOffset,theDstCStr + theInsertionOffset + numCharsToInsert,numCharsToShift);
        +		}
        +		
        +		if (numCharsToInsert > 0)
        +		{
        +			BlockMove(theSrcPStr + 1,theDstCStr + theInsertionOffset,numCharsToInsert);
        +		}
        +		
        +		theDstCStr[theInsertionOffset + numCharsToInsert + numCharsToShift] = 0;
        +	}
        +}
        +
        +
        +
        +OSErr InsertCStrIntoHandle(const char *theCString,Handle theHandle,const long inInsertOffset)
        +{
        +OSErr	errCode;
        +int		currentLength;
        +int		insertLength;
        +
        +	
        +	SetErrorMessageAndBailIfNil(theCString,"InsertCStrIntoHandle: Bad parameter, theCString == nil");
        +
        +	SetErrorMessageAndBailIfNil(theHandle,"InsertCStrIntoHandle: Bad parameter, theHandle == nil");
        +	
        +	currentLength = CStrLength(*theHandle);
        +	
        +	if (currentLength + 1 > ::GetHandleSize(theHandle))
        +	{
        +		SetErrorMessageAndBail("InsertCStrIntoHandle: Handle has been overflowed");
        +	}
        +	
        +	if (inInsertOffset > currentLength)
        +	{
        +		SetErrorMessageAndBail("InsertCStrIntoHandle: Insertion offset is greater than string length");
        +	}
        +	
        +	insertLength = CStrLength(theCString);
        +	
        +	::SetHandleSize(theHandle,currentLength + 1 + insertLength);
        +	
        +	if (::GetHandleSize(theHandle) < currentLength + 1 + insertLength)
        +	{
        +		SetErrorMessageAndLongIntAndBail("InsertCStrIntoHandle: Can't expand storage for Handle, MemError() = ",MemError());
        +	}
        +	
        +	::BlockMove(*theHandle + inInsertOffset,*theHandle + inInsertOffset + insertLength,currentLength - inInsertOffset + 1);
        +	
        +	::BlockMove(theCString,*theHandle + inInsertOffset,insertLength);
        +
        +
        +	errCode = noErr;
        +	
        +	
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +void CopyCStrAndInsert1LongIntIntoCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength)
        +{
        +	CopyCStrAndInsertCStrLongIntIntoCStr(theSrcCStr,nil,theNum,theDstCStr,maxDstStrLength);
        +}
        +
        +
        +void CopyCStrAndInsert2LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,char *theDstCStr,const int maxDstStrLength)
        +{
        +const long	theLongInts[] = { long1,long2 };
        +
        +	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,nil,theLongInts,theDstCStr,maxDstStrLength);
        +}
        +
        +
        +void CopyCStrAndInsert3LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,const long long3,char *theDstCStr,const int maxDstStrLength)
        +{
        +const long	theLongInts[] = { long1,long2,long3 };
        +
        +	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,nil,theLongInts,theDstCStr,maxDstStrLength);
        +}
        +
        +
        +void CopyCStrAndInsertCStrIntoCStr(const char *theSrcCStr,const char *theInsertCStr,char *theDstCStr,const int maxDstStrLength)
        +{
        +const char	*theCStrs[2] = { theInsertCStr,nil };
        +
        +	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,theCStrs,nil,theDstCStr,maxDstStrLength);
        +}
        +
        +
        +
        +void CopyCStrAndInsertCStrLongIntIntoCStr(const char *theSrcCStr,const char *theInsertCStr,const long theNum,char *theDstCStr,const int maxDstStrLength)
        +{
        +const char	*theCStrs[2] = { theInsertCStr,nil };
        +const long	theLongInts[1] = { theNum };
        +
        +	CopyCStrAndInsertCStrsLongIntsIntoCStr(theSrcCStr,theCStrs,theLongInts,theDstCStr,maxDstStrLength);
        +}
        +
        +
        +
        +void CopyCStrAndInsertCStrsLongIntsIntoCStr(const char *theSrcCStr,const char **theInsertCStrs,const long *theLongInts,char *theDstCStr,const int maxDstStrLength)
        +{
        +int			dstCharIndex,srcCharIndex,theMaxDstStrLength;
        +int			theCStrIndex = 0;
        +int			theLongIntIndex = 0;
        +
        +	
        +	theMaxDstStrLength = maxDstStrLength;
        +	
        +	if (theDstCStr != nil && theSrcCStr != nil && theMaxDstStrLength > 0)
        +	{
        +		dstCharIndex = 0;
        +		
        +		srcCharIndex = 0;
        +		
        +		
        +		//	Allow room for NULL at end of string
        +		
        +		theMaxDstStrLength--;
        +		
        +		
        +		for (;;)
        +		{
        +			//	Hit end of buffer?
        +			
        +			if (dstCharIndex >= theMaxDstStrLength)
        +			{
        +				theDstCStr[dstCharIndex++] = 0;
        +				
        +				goto EXITPOINT;
        +			}
        +			
        +			//	End of source string?
        +			
        +			else if (theSrcCStr[srcCharIndex] == 0)
        +			{
        +				theDstCStr[dstCharIndex++] = 0;
        +				
        +				goto EXITPOINT;
        +			}
        +			
        +			//	Did we find a '%s'?
        +			
        +			else if (theInsertCStrs != nil && theInsertCStrs[theCStrIndex] != nil && theSrcCStr[srcCharIndex] == '%' && theSrcCStr[srcCharIndex + 1] == 's')
        +			{
        +				//	Skip over the '%s'
        +				
        +				srcCharIndex += 2;
        +				
        +				
        +				//	Terminate the dest string and then concat the string
        +				
        +				theDstCStr[dstCharIndex] = 0;
        +				
        +				ConcatCStrToCStr(theInsertCStrs[theCStrIndex],theDstCStr,theMaxDstStrLength);
        +				
        +				dstCharIndex = CStrLength(theDstCStr);
        +				
        +				theCStrIndex++;
        +			}
        +			
        +			//	Did we find a '%ld'?
        +			
        +			else if (theLongInts != nil && theSrcCStr[srcCharIndex] == '%' && theSrcCStr[srcCharIndex + 1] == 'l' && theSrcCStr[srcCharIndex + 2] == 'd')
        +			{
        +				//	Skip over the '%ld'
        +				
        +				srcCharIndex += 3;
        +				
        +				
        +				//	Terminate the dest string and then concat the number
        +				
        +				theDstCStr[dstCharIndex] = 0;
        +				
        +				ConcatLongIntToCStr(theLongInts[theLongIntIndex],theDstCStr,theMaxDstStrLength);
        +				
        +				theLongIntIndex++;
        +				
        +				dstCharIndex = CStrLength(theDstCStr);
        +			}
        +			
        +			else
        +			{
        +				theDstCStr[dstCharIndex++] = theSrcCStr[srcCharIndex++];
        +			}
        +		}
        +	}
        +
        +
        +
        +EXITPOINT:
        +
        +	return;
        +}
        +
        +
        +
        +
        +
        +OSErr CopyCStrAndInsertCStrLongIntIntoHandle(const char *theSrcCStr,const char *theInsertCStr,const long theNum,Handle *theHandle)
        +{
        +OSErr	errCode;
        +long	byteCount;
        +
        +	
        +	if (theHandle != nil)
        +	{
        +		byteCount = CStrLength(theSrcCStr) + CStrLength(theInsertCStr) + 32;
        +		
        +		*theHandle = NewHandle(byteCount);
        +		
        +		if (*theHandle == nil)
        +		{
        +			SetErrorMessageAndLongIntAndBail("CopyCStrAndInsertCStrLongIntIntoHandle: Can't allocate Handle, MemError() = ",MemError());
        +		}
        +		
        +		
        +		HLock(*theHandle);
        +		
        +		CopyCStrAndInsertCStrLongIntIntoCStr(theSrcCStr,theInsertCStr,theNum,**theHandle,byteCount);
        +		
        +		HUnlock(*theHandle);
        +	}
        +	
        +	errCode = noErr;
        +	
        +	
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +
        +OSErr CopyIndexedWordToCStr(char *theSrcCStr,int whichWord,char *theDstCStr,int maxDstCStrLength)
        +{
        +OSErr		errCode;
        +char		*srcCharPtr,*dstCharPtr;
        +int			wordCount;
        +int			byteCount;
        +
        +
        +	if (theSrcCStr == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, theSrcCStr == nil"));
        +	}
        +	
        +	if (theDstCStr == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, theDstCStr == nil"));
        +	}
        +	
        +	if (whichWord < 0)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, whichWord < 0"));
        +	}
        +	
        +	if (maxDstCStrLength <= 0)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToCStr: Bad parameter, maxDstCStrLength <= 0"));
        +	}
        +
        +	
        +	*theDstCStr = '\0';
        +	
        +	srcCharPtr = theSrcCStr;
        +
        +	while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
        +	{
        +		srcCharPtr++;
        +	}
        +	
        +
        +	for (wordCount = 0;wordCount < whichWord;wordCount++)
        +	{
        +		while (*srcCharPtr != ' ' && *srcCharPtr != '\t' && *srcCharPtr != '\r' && *srcCharPtr != '\n' && *srcCharPtr != '\0')
        +		{
        +			srcCharPtr++;
        +		}
        +		
        +		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
        +		{
        +			errCode = noErr;
        +			
        +			goto EXITPOINT;
        +		}
        +
        +		while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
        +		{
        +			srcCharPtr++;
        +		}
        +		
        +		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
        +		{
        +			errCode = noErr;
        +			
        +			goto EXITPOINT;
        +		}
        +	}
        +
        +
        +	dstCharPtr = theDstCStr;
        +	byteCount = 0;
        +	
        +	
        +	for(;;)
        +	{
        +		if (byteCount >= maxDstCStrLength - 1 || *srcCharPtr == '\0' || *srcCharPtr == ' ' || *srcCharPtr == '\t' || *srcCharPtr == '\r' || *srcCharPtr == '\n')
        +		{
        +			*dstCharPtr = '\0';
        +			break;
        +		}
        +		
        +		*dstCharPtr++ = *srcCharPtr++;
        +		
        +		byteCount++;
        +	}
        +
        +
        +	errCode = noErr;
        +
        +
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +
        +OSErr CopyIndexedWordToNewHandle(char *theSrcCStr,int whichWord,Handle *outTheHandle)
        +{
        +OSErr		errCode;
        +char		*srcCharPtr;
        +int			wordCount;
        +int			byteCount;
        +
        +
        +	if (theSrcCStr == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToNewHandle: Bad parameter, theSrcCStr == nil"));
        +	}
        +	
        +	if (outTheHandle == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToNewHandle: Bad parameter, outTheHandle == nil"));
        +	}
        +	
        +	if (whichWord < 0)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedWordToNewHandle: Bad parameter, whichWord < 0"));
        +	}
        +
        +	
        +	*outTheHandle = nil;
        +	
        +
        +	srcCharPtr = theSrcCStr;
        +
        +	while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
        +	{
        +		srcCharPtr++;
        +	}
        +	
        +
        +	for (wordCount = 0;wordCount < whichWord;wordCount++)
        +	{
        +		while (*srcCharPtr != ' ' && *srcCharPtr != '\t' && *srcCharPtr != '\r' && *srcCharPtr != '\n' && *srcCharPtr != '\0')
        +		{
        +			srcCharPtr++;
        +		}
        +		
        +		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
        +		{
        +			break;
        +		}
        +
        +		while (*srcCharPtr == ' ' || *srcCharPtr == '\t')
        +		{
        +			srcCharPtr++;
        +		}
        +		
        +		if (*srcCharPtr == '\r' || *srcCharPtr == '\n' || *srcCharPtr == '\0')
        +		{
        +			break;
        +		}
        +	}
        +
        +
        +	for (byteCount = 0;;byteCount++)
        +	{
        +		if (srcCharPtr[byteCount] == ' ' || srcCharPtr[byteCount] == '\t' || srcCharPtr[byteCount] == '\r' || srcCharPtr[byteCount] == '\n' || srcCharPtr[byteCount] == '\0')
        +		{
        +			break;
        +		}
        +	}
        +
        +	
        +	*outTheHandle = NewHandle(byteCount + 1);
        +	
        +	if (*outTheHandle == nil)
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyIndexedWordToNewHandle: Can't allocate Handle, MemError() = ",MemError());
        +	}
        +	
        +	
        +	::BlockMove(srcCharPtr,**outTheHandle,byteCount);
        +	
        +	(**outTheHandle)[byteCount] = '\0';
        +
        +	errCode = noErr;
        +
        +
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr CopyIndexedLineToCStr(const char *theSrcCStr,int inWhichLine,int *lineEndIndex,Boolean *gotLastLine,char *theDstCStr,const int maxDstCStrLength)
        +{
        +OSErr		errCode;
        +int			theCurrentLine;
        +int			theCurrentLineOffset;
        +int			theEOSOffset;
        +
        +
        +	if (theSrcCStr == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, theSrcCStr == nil"));
        +	}
        +	
        +	if (theDstCStr == nil)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, theDstCStr == nil"));
        +	}
        +	
        +	if (inWhichLine < 0)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, inWhichLine < 0"));
        +	}
        +	
        +	if (maxDstCStrLength <= 0)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedLineToCStr: Bad parameter, maxDstCStrLength <= 0"));
        +	}
        +	
        +	
        +	if (gotLastLine != nil)
        +	{
        +		*gotLastLine = false;
        +	}
        +
        +	
        +	*theDstCStr = 0;
        +	
        +	theCurrentLineOffset = 0;
        +	
        +	theCurrentLine = 0;
        +	
        +	
        +	while (theCurrentLine < inWhichLine)
        +	{
        +		while (theSrcCStr[theCurrentLineOffset] != '\r' && theSrcCStr[theCurrentLineOffset] != 0)
        +		{
        +			theCurrentLineOffset++;
        +		}
        +		
        +		if (theSrcCStr[theCurrentLineOffset] == 0)
        +		{
        +			break;
        +		}
        +		
        +		theCurrentLineOffset++;
        +		theCurrentLine++;
        +	}
        +		
        +	if (theSrcCStr[theCurrentLineOffset] == 0)
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyIndexedLineToCStr: Too few lines in source text, can't get line ",inWhichLine);
        +	}
        +
        +
        +	theEOSOffset = FindCharOffsetInCStr('\r',theSrcCStr + theCurrentLineOffset);
        +	
        +	if (theEOSOffset >= 0)
        +	{
        +		CopyCSubstrToCStr(theSrcCStr + theCurrentLineOffset,theEOSOffset,theDstCStr,maxDstCStrLength);
        +		
        +		if (gotLastLine != nil)
        +		{
        +			*gotLastLine = false;
        +		}
        +	
        +		if (lineEndIndex != nil)
        +		{
        +			*lineEndIndex = theEOSOffset;
        +		}
        +	}
        +	
        +	else
        +	{
        +		theEOSOffset = CStrLength(theSrcCStr + theCurrentLineOffset);
        +
        +		CopyCSubstrToCStr(theSrcCStr + theCurrentLineOffset,theEOSOffset,theDstCStr,maxDstCStrLength);
        +		
        +		if (gotLastLine != nil)
        +		{
        +			*gotLastLine = true;
        +		}
        +	
        +		if (lineEndIndex != nil)
        +		{
        +			*lineEndIndex = theEOSOffset;
        +		}
        +	}
        +	
        +
        +	errCode = noErr;
        +
        +
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr CopyIndexedLineToNewHandle(const char *theSrcCStr,int inWhichLine,Handle *outNewHandle)
        +{
        +OSErr		errCode;
        +int			theCurrentLine;
        +int			theCurrentLineOffset;
        +int			byteCount;
        +
        +
        +	SetErrorMessageAndBailIfNil(theSrcCStr,"CopyIndexedLineToNewHandle: Bad parameter, theSrcCStr == nil");
        +	SetErrorMessageAndBailIfNil(outNewHandle,"CopyIndexedLineToNewHandle: Bad parameter, outNewHandle == nil");
        +	
        +	if (inWhichLine < 0)
        +	{
        +		SetErrorMessageAndBail(("CopyIndexedLineToNewHandle: Bad parameter, inWhichLine < 0"));
        +	}
        +	
        +
        +	theCurrentLineOffset = 0;
        +	
        +	theCurrentLine = 0;
        +	
        +	
        +	while (theCurrentLine < inWhichLine)
        +	{
        +		while (theSrcCStr[theCurrentLineOffset] != '\r' && theSrcCStr[theCurrentLineOffset] != '\0')
        +		{
        +			theCurrentLineOffset++;
        +		}
        +		
        +		if (theSrcCStr[theCurrentLineOffset] == '\0')
        +		{
        +			break;
        +		}
        +		
        +		theCurrentLineOffset++;
        +		theCurrentLine++;
        +	}
        +		
        +	if (theSrcCStr[theCurrentLineOffset] == '\0')
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyIndexedLineToNewHandle: Too few lines in source text, can't get line #",inWhichLine);
        +	}
        +
        +	
        +	byteCount = 0;
        +	
        +	while (theSrcCStr[theCurrentLineOffset + byteCount] != '\r' && theSrcCStr[theCurrentLineOffset + byteCount] != '\0')
        +	{
        +		byteCount++;
        +	}
        +		
        +	
        +	*outNewHandle = NewHandle(byteCount + 1);
        +	
        +	if (*outNewHandle == nil)
        +	{
        +		SetErrorMessageAndLongIntAndBail("CopyIndexedLineToNewHandle: Can't allocate Handle, MemError() = ",MemError());
        +	}
        +	
        +	::BlockMove(theSrcCStr + theCurrentLineOffset,**outNewHandle,byteCount);
        +	
        +	(**outNewHandle)[byteCount] = '\0';
        +
        +	errCode = noErr;
        +
        +
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +OSErr CountDigits(const char *inCStr,int *outNumIntegerDigits,int *outNumFractDigits)
        +{
        +OSErr	errCode = noErr;
        +int		numIntDigits = 0;
        +int		numFractDigits = 0;
        +int 	digitIndex = 0;
        +
        +	
        +	SetErrorMessageAndBailIfNil(inCStr,"CountDigits: Bad parameter, theSrcCStr == nil");
        +	SetErrorMessageAndBailIfNil(outNumIntegerDigits,"CountDigits: Bad parameter, outNumIntegerDigits == nil");
        +	SetErrorMessageAndBailIfNil(outNumFractDigits,"CountDigits: Bad parameter, outNumFractDigits == nil");
        +	
        +	digitIndex = 0;
        +	
        +	while (inCStr[digitIndex] >= '0' && inCStr[digitIndex] <= '9')
        +	{
        +		digitIndex++;
        +		numIntDigits++;
        +	}
        +	
        +	if (inCStr[digitIndex] == '.')
        +	{
        +		digitIndex++;
        +		
        +		while (inCStr[digitIndex] >= '0' && inCStr[digitIndex] <= '9')
        +		{
        +			digitIndex++;
        +			numFractDigits++;
        +		}
        +	}
        +	
        +	*outNumIntegerDigits = numIntDigits;
        +	
        +	*outNumFractDigits = numFractDigits;
        +	
        +	errCode = noErr;
        +	
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr ExtractIntFromCStr(const char *theSrcCStr,int *outInt,Boolean skipLeadingSpaces)
        +{
        +OSErr		errCode;
        +int			theCharIndex;
        +
        +
        +	if (theSrcCStr == nil)
        +	{
        +		SetErrorMessageAndBail(("ExtractIntFromCStr: Bad parameter, theSrcCStr == nil"));
        +	}
        +	
        +	if (outInt == nil)
        +	{
        +		SetErrorMessageAndBail(("ExtractIntFromCStr: Bad parameter, outInt == nil"));
        +	}	
        +
        +	
        +	*outInt = 0;
        +	
        +	theCharIndex = 0;
        +	
        +	if (skipLeadingSpaces == true)
        +	{
        +		while (theSrcCStr[theCharIndex] == ' ')
        +		{
        +			theCharIndex++;
        +		}
        +	}
        +	
        +	if (theSrcCStr[theCharIndex] < '0' || theSrcCStr[theCharIndex] > '9')
        +	{
        +		SetErrorMessageAndBail(("ExtractIntFromCStr: Bad parameter, theSrcCStr contains a bogus numeric representation"));
        +	}
        +
        +
        +	while (theSrcCStr[theCharIndex] >= '0' && theSrcCStr[theCharIndex] <= '9')
        +	{
        +		*outInt = (*outInt * 10) + (theSrcCStr[theCharIndex] - '0');
        +		
        +		theCharIndex++;
        +	}
        +	
        +
        +	errCode = noErr;
        +
        +
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr ExtractIntFromPStr(const unsigned char *theSrcPStr,int *outInt,Boolean skipLeadingSpaces)
        +{
        +OSErr		errCode;
        +char		theCStr[256];
        +
        +
        +	if (theSrcPStr == nil)
        +	{
        +		SetErrorMessageAndBail(("ExtractIntFromPStr: Bad parameter, theSrcPStr == nil"));
        +	}
        +	
        +	if (outInt == nil)
        +	{
        +		SetErrorMessageAndBail(("ExtractIntFromPStr: Bad parameter, outInt == nil"));
        +	}
        +	
        +	
        +	CopyPStrToCStr(theSrcPStr,theCStr,sizeof(theCStr));
        +	
        +	
        +	errCode = ExtractIntFromCStr(theCStr,outInt,skipLeadingSpaces);
        +
        +
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +int CountOccurencesOfCharInCStr(const char inChar,const char *inSrcCStr)
        +{
        +int		theSrcCharIndex;
        +int		numOccurrences = -1;
        +
        +
        +	if (inSrcCStr != nil && inChar != '\0')
        +	{
        +		numOccurrences = 0;
        +		
        +		for (theSrcCharIndex = 0;inSrcCStr[theSrcCharIndex] != '\0';theSrcCharIndex++)
        +		{
        +			if (inSrcCStr[theSrcCharIndex] == inChar)
        +			{
        +				numOccurrences++;
        +			}
        +		}
        +	}
        +	
        +	return(numOccurrences);
        +}
        +
        +
        +int CountWordsInCStr(const char *inSrcCStr)
        +{
        +int		numWords = -1;
        +
        +
        +	if (inSrcCStr != nil)
        +	{
        +		numWords = 0;
        +		
        +		//	Skip lead spaces
        +		
        +		while (*inSrcCStr == ' ')
        +		{
        +			inSrcCStr++;
        +		}
        +
        +		while (*inSrcCStr != '\0')
        +		{
        +			numWords++;
        +
        +			while (*inSrcCStr != ' ' && *inSrcCStr != '\0')
        +			{
        +				inSrcCStr++;
        +			}
        +			
        +			while (*inSrcCStr == ' ')
        +			{
        +				inSrcCStr++;
        +			}
        +		}
        +	}
        +	
        +	return(numWords);
        +}
        +
        +
        +
        +
        +void ConvertCStrToUpperCase(char *theSrcCStr)
        +{
        +char		*theCharPtr;
        +
        +
        +	if (theSrcCStr != nil)
        +	{
        +		theCharPtr = theSrcCStr;
        +		
        +		while (*theCharPtr != 0)
        +		{
        +			if (*theCharPtr >= 'a' && *theCharPtr <= 'z')
        +			{
        +				*theCharPtr = *theCharPtr - 'a' + 'A';
        +			}
        +			
        +			theCharPtr++;
        +		}
        +	}
        +}
        +
        +
        +
        +
        +
        +
        +
        +void ExtractCStrItemFromCStr(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,char *outDstCharPtr,const int inDstCharPtrMaxLength,const Boolean inTreatMultipleDelimsAsSingleDelim)
        +{
        +int		theItem;
        +int		theSrcCharIndex;
        +int		theDstCharIndex;
        +
        +
        +	if (foundItem != nil)
        +	{
        +		*foundItem = false;
        +	}
        +	
        +	
        +	if (outDstCharPtr != nil && inDstCharPtrMaxLength > 0 && inItemNumber >= 0 && inItemDelimiter != 0)
        +	{
        +		*outDstCharPtr = 0;
        +		
        +
        +		theSrcCharIndex = 0;
        +		
        +		for (theItem = 0;theItem < inItemNumber;theItem++)
        +		{
        +			while (inSrcCStr[theSrcCharIndex] != inItemDelimiter && inSrcCStr[theSrcCharIndex] != '\0')
        +			{
        +				theSrcCharIndex++;
        +			}
        +			
        +			if (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
        +			{
        +				theSrcCharIndex++;
        +				
        +				if (inTreatMultipleDelimsAsSingleDelim)
        +				{
        +					while (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
        +					{
        +						theSrcCharIndex++;
        +					}
        +				}
        +			}
        +			
        +			
        +			if (inSrcCStr[theSrcCharIndex] == '\0')
        +			{
        +				goto EXITPOINT;
        +			}
        +		}
        +		
        +
        +		if (foundItem != nil)
        +		{
        +			*foundItem = true;
        +		}
        +		
        +		
        +		theDstCharIndex = 0;
        +		
        +		for (;;)
        +		{
        +			if (inSrcCStr[theSrcCharIndex] == 0 || inSrcCStr[theSrcCharIndex] == inItemDelimiter || theDstCharIndex >= inDstCharPtrMaxLength - 1)
        +			{
        +				outDstCharPtr[theDstCharIndex] = 0;
        +				
        +				break;
        +			}
        +			
        +			outDstCharPtr[theDstCharIndex++] = inSrcCStr[theSrcCharIndex++];
        +		}
        +	}
        +	
        +	
        +EXITPOINT:
        +
        +	return;
        +}
        +
        +
        +
        +OSErr ExtractCStrItemFromCStrIntoNewHandle(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,Handle *outNewHandle,const Boolean inTreatMultipleDelimsAsSingleDelim)
        +{
        +OSErr	errCode;
        +int		theItem;
        +int		theSrcCharIndex;
        +int		theItemLength;
        +
        +
        +	if (inSrcCStr == nil)
        +	{
        +		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, inSrcCStr == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	if (outNewHandle == nil)
        +	{
        +		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, outNewHandle == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	if (foundItem == nil)
        +	{
        +		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, foundItem == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	if (inItemNumber < 0)
        +	{
        +		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, inItemNumber < 0");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	if (inItemDelimiter == 0)
        +	{
        +		SetErrorMessage("ExtractCStrItemFromCStrIntoNewHandle: Bad parameter, inItemDelimiter == 0");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +
        +
        +	*foundItem = false;
        +	
        +	theSrcCharIndex = 0;
        +	
        +	for (theItem = 0;theItem < inItemNumber;theItem++)
        +	{
        +		while (inSrcCStr[theSrcCharIndex] != inItemDelimiter && inSrcCStr[theSrcCharIndex] != '\0')
        +		{
        +			theSrcCharIndex++;
        +		}
        +		
        +		if (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
        +		{
        +			theSrcCharIndex++;
        +			
        +			if (inTreatMultipleDelimsAsSingleDelim)
        +			{
        +				while (inSrcCStr[theSrcCharIndex] == inItemDelimiter)
        +				{
        +					theSrcCharIndex++;
        +				}
        +			}
        +		}
        +		
        +		
        +		if (inSrcCStr[theSrcCharIndex] == '\0')
        +		{
        +			errCode = noErr;
        +			
        +			goto EXITPOINT;
        +		}
        +	}
        +	
        +
        +	*foundItem = true;
        +	
        +	
        +	for (theItemLength = 0;;theItemLength++)
        +	{
        +		if (inSrcCStr[theSrcCharIndex + theItemLength] == 0 || inSrcCStr[theSrcCharIndex + theItemLength] == inItemDelimiter)
        +		{
        +			break;
        +		}
        +	}
        +	
        +
        +	*outNewHandle = NewHandle(theItemLength + 1);
        +	
        +	if (*outNewHandle == nil)
        +	{
        +		SetErrorMessageAndLongIntAndBail("ExtractCStrItemFromCStrIntoNewHandle: Can't allocate Handle, MemError() = ",MemError());
        +	}
        +	
        +	
        +	BlockMove(inSrcCStr + theSrcCharIndex,**outNewHandle,theItemLength);
        +	
        +	(**outNewHandle)[theItemLength] = 0;
        +	
        +	errCode = noErr;
        +	
        +	
        +EXITPOINT:
        +
        +	return(errCode);
        +}
        +
        +
        +
        +
        +
        +
        +OSErr ExtractFloatFromCStr(const char *inCString,extended80 *outFloat)
        +{
        +OSErr				errCode;
        +Str255				theStr255;
        +Handle				theNumberPartsTableHandle = nil;
        +long				theNumberPartsOffset,theNumberPartsLength;
        +FormatResultType	theFormatResultType;
        +NumberParts			theNumberPartsTable;
        +NumFormatStringRec	theNumFormatStringRec;
        +
        +
        +	if (inCString == nil)
        +	{
        +		SetErrorMessage("ExtractFloatFromCStr: Bad parameter, inCString == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +
        +	if (outFloat == nil)
        +	{
        +		SetErrorMessage("ExtractFloatFromCStr: Bad parameter, outFloat == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	
        +//	GetIntlResourceTable(smRoman,smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);
        +
        +	GetIntlResourceTable(GetScriptManagerVariable(smSysScript),smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);	
        +	
        +	if (theNumberPartsTableHandle == nil)
        +	{
        +		SetErrorMessage("ExtractFloatFromCStr: Can't get number parts table for converting string representations to/from numeric representations");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	if (theNumberPartsLength > sizeof(theNumberPartsTable))
        +	{
        +		SetErrorMessage("ExtractFloatFromCStr: Number parts table has bad length");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +
        +	BlockMove(*theNumberPartsTableHandle + theNumberPartsOffset,&theNumberPartsTable,theNumberPartsLength);
        +	
        +	
        +	theFormatResultType = (FormatResultType) StringToFormatRec(kNumberFormatString,&theNumberPartsTable,&theNumFormatStringRec);
        +	
        +	if (theFormatResultType != fFormatOK)
        +	{
        +		SetErrorMessage("ExtractFloatFromCStr: StringToFormatRec() != fFormatOK");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +
        +	
        +	CopyCStrToPStr(inCString,theStr255,sizeof(theStr255));
        +
        +
        +	theFormatResultType = (FormatResultType) StringToExtended(theStr255,&theNumFormatStringRec,&theNumberPartsTable,outFloat);
        +	
        +	if (theFormatResultType != fFormatOK && theFormatResultType != fBestGuess)
        +	{
        +		SetErrorMessageAndLongIntAndBail("ExtractFloatFromCStr: StringToExtended() = ",theFormatResultType);
        +	}
        +
        +	
        +	errCode = noErr;
        +	
        +
        +EXITPOINT:
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr CopyFloatToCStr(const extended80 *theFloat,char *theCStr,const int maxCStrLength,const int inMaxNumIntDigits,const int inMaxNumFractDigits)
        +{
        +OSErr				errCode;
        +Str255				theStr255;
        +Handle				theNumberPartsTableHandle = nil;
        +long				theNumberPartsOffset,theNumberPartsLength;
        +FormatResultType	theFormatResultType;
        +NumberParts			theNumberPartsTable;
        +NumFormatStringRec	theNumFormatStringRec;
        +
        +
        +	if (theCStr == nil)
        +	{
        +		SetErrorMessage("CopyFloatToCStr: Bad parameter, theCStr == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +
        +	if (theFloat == nil)
        +	{
        +		SetErrorMessage("CopyFloatToCStr: Bad parameter, theFloat == nil");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +
        +//	GetIntlResourceTable(smRoman,smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);
        +
        +	GetIntlResourceTable(GetScriptManagerVariable(smSysScript),smNumberPartsTable,&theNumberPartsTableHandle,&theNumberPartsOffset,&theNumberPartsLength);	
        +	
        +	if (theNumberPartsTableHandle == nil)
        +	{
        +		SetErrorMessage("CopyFloatToCStr: Can't get number parts table for converting string representations to/from numeric representations");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	if (theNumberPartsLength > sizeof(theNumberPartsTable))
        +	{
        +		SetErrorMessage("CopyFloatToCStr: Number parts table has bad length");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +	
        +	
        +	BlockMove(*theNumberPartsTableHandle + theNumberPartsOffset,&theNumberPartsTable,theNumberPartsLength);
        +	
        +	
        +	if (inMaxNumIntDigits >= 0 || inMaxNumFractDigits >= 0)
        +	{
        +	char	numberFormat[64];
        +	int		numberFormatLength = 0;
        +	
        +		for (int i = 0;i < inMaxNumIntDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
        +		{
        +			numberFormat[numberFormatLength++] = '0';
        +		}
        +		
        +		if (inMaxNumFractDigits > 0 && numberFormatLength < sizeof(numberFormat) - 1)
        +		{
        +			numberFormat[numberFormatLength++] = '.';
        +			
        +			for (int i = 0;i < inMaxNumFractDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
        +			{
        +				numberFormat[numberFormatLength++] = '0';
        +			}
        +		}
        +
        +		
        +		if (numberFormatLength < sizeof(numberFormat) - 1)
        +		{
        +			numberFormat[numberFormatLength++] = ';';
        +		}
        +		
        +		if (numberFormatLength < sizeof(numberFormat) - 1)
        +		{
        +			numberFormat[numberFormatLength++] = '-';
        +		}
        +		
        +
        +		for (int i = 0;i < inMaxNumIntDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
        +		{
        +			numberFormat[numberFormatLength++] = '0';
        +		}
        +		
        +		if (inMaxNumFractDigits > 0 && numberFormatLength < sizeof(numberFormat) - 1)
        +		{
        +			numberFormat[numberFormatLength++] = '.';
        +			
        +			for (int i = 0;i < inMaxNumFractDigits && numberFormatLength < sizeof(numberFormat) - 1;i++)
        +			{
        +				numberFormat[numberFormatLength++] = '0';
        +			}
        +		}
        +		
        +		numberFormat[numberFormatLength] = '\0';
        +
        +
        +	Str255	tempStr255;
        +	
        +		CopyCStrToPStr(numberFormat,tempStr255,sizeof(tempStr255));
        +		
        +		theFormatResultType = (FormatResultType) StringToFormatRec(tempStr255,&theNumberPartsTable,&theNumFormatStringRec);
        +	}
        +	
        +	else
        +	{
        +		theFormatResultType = (FormatResultType) StringToFormatRec(kNumberFormatString,&theNumberPartsTable,&theNumFormatStringRec);
        +	}
        +	
        +	if (theFormatResultType != fFormatOK)
        +	{
        +		SetErrorMessage("CopyFloatToCStr: StringToFormatRec() != fFormatOK");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +
        +
        +	theFormatResultType = (FormatResultType) ExtendedToString(theFloat,&theNumFormatStringRec,&theNumberPartsTable,theStr255);
        +	
        +	if (theFormatResultType != fFormatOK)
        +	{
        +		SetErrorMessage("CopyFloatToCStr: ExtendedToString() != fFormatOK");
        +		errCode = kGenericError;
        +		goto EXITPOINT;
        +	}
        +
        +	
        +	CopyPStrToCStr(theStr255,theCStr,maxCStrLength);
        +	
        +	errCode = noErr;
        +	
        +
        +EXITPOINT:
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +
        +
        +void SkipWhiteSpace(char **ioSrcCharPtr,const Boolean inStopAtEOL)
        +{
        +	if (ioSrcCharPtr != nil && *ioSrcCharPtr != nil)
        +	{
        +		if (inStopAtEOL)
        +		{
        +			while ((**ioSrcCharPtr == ' ' || **ioSrcCharPtr == '\t') && **ioSrcCharPtr != '\r' && **ioSrcCharPtr != '\n')
        +			{
        +				*ioSrcCharPtr++;
        +			}
        +		}
        +		
        +		else
        +		{
        +			while (**ioSrcCharPtr == ' ' || **ioSrcCharPtr == '\t')
        +			{
        +				*ioSrcCharPtr++;
        +			}
        +		}
        +	}
        +}
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/CPStringUtils.hpp b/vendor/openssl/openssl/MacOS/GetHTTPS.src/CPStringUtils.hpp
        new file mode 100644
        index 000000000..5045c4101
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/CPStringUtils.hpp
        @@ -0,0 +1,104 @@
        +#pragma once
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +void CopyPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength);
        +void CopyPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength);
        +void CopyCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxDstStrLength);
        +void CopyCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength);
        +void ConcatPStrToCStr(const unsigned char *thePStr,char *theCStr,const int maxCStrLength);
        +void ConcatPStrToPStr(const unsigned char *theSrcPStr,unsigned char *theDstPStr,const int maxDstStrLength);
        +void ConcatCStrToPStr(const char *theSrcCStr,unsigned char *theDstPStr,const int maxDstStrLength);
        +void ConcatCStrToCStr(const char *theSrcCStr,char *theDstCStr,const int maxCStrLength);
        +
        +void ConcatCharToCStr(const char theChar,char *theDstCStr,const int maxCStrLength);
        +void ConcatCharToPStr(const char theChar,unsigned char *theDstPStr,const int maxPStrLength);
        +
        +int ComparePStrs(const unsigned char *theFirstPStr,const unsigned char *theSecondPStr,const Boolean ignoreCase = true);
        +int CompareCStrs(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase = true);
        +int CompareCStrToPStr(const char *theCStr,const unsigned char *thePStr,const Boolean ignoreCase = true);
        +
        +Boolean CStrsAreEqual(const char *theFirstCStr,const char *theSecondCStr,const Boolean ignoreCase = true);
        +Boolean PStrsAreEqual(const unsigned char *theFirstCStr,const unsigned char *theSecondCStr,const Boolean ignoreCase = true);
        +
        +void CopyLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits = -1);
        +void CopyUnsignedLongIntToCStr(const unsigned long theNum,char *theCStr,const int maxCStrLength);
        +void ConcatLongIntToCStr(const long theNum,char *theCStr,const int maxCStrLength,const int numDigits = -1);
        +void CopyCStrAndConcatLongIntToCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength);
        +
        +void CopyLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits = -1);
        +void ConcatLongIntToPStr(const long theNum,unsigned char *thePStr,const int maxPStrLength,const int numDigits = -1);
        +
        +long CStrLength(const char *theCString);
        +long PStrLength(const unsigned char *thePString);
        +
        +OSErr CopyCStrToExistingHandle(const char *theCString,Handle theHandle);
        +OSErr CopyLongIntToExistingHandle(const long inTheLongInt,Handle theHandle);
        +
        +OSErr CopyCStrToNewHandle(const char *theCString,Handle *theHandle);
        +OSErr CopyPStrToNewHandle(const unsigned char *thePString,Handle *theHandle);
        +OSErr CopyLongIntToNewHandle(const long inTheLongInt,Handle *theHandle);
        +
        +OSErr AppendCStrToHandle(const char *theCString,Handle theHandle,long *currentLength = nil,long *maxLength = nil);
        +OSErr AppendCharsToHandle(const char *theChars,const int numChars,Handle theHandle,long *currentLength = nil,long *maxLength = nil);
        +OSErr AppendPStrToHandle(const unsigned char *thePString,Handle theHandle,long *currentLength = nil);
        +OSErr AppendLongIntToHandle(const long inTheLongInt,Handle theHandle,long *currentLength = nil);
        +
        +void ZeroMem(void *theMemPtr,const unsigned long numBytes);
        +
        +char *FindCharInCStr(const char theChar,const char *theCString);
        +long FindCharOffsetInCStr(const char theChar,const char *theCString,const Boolean inIgnoreCase = false);
        +long FindCStrOffsetInCStr(const char *theCSubstring,const char *theCString,const Boolean inIgnoreCase = false);
        +
        +void CopyCSubstrToCStr(const char *theSrcCStr,const int maxCharsToCopy,char *theDstCStr,const int maxDstStrLength);
        +void CopyCSubstrToPStr(const char *theSrcCStr,const int maxCharsToCopy,unsigned char *theDstPStr,const int maxDstStrLength);
        +
        +void InsertCStrIntoCStr(const char *theSrcCStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength);
        +void InsertPStrIntoCStr(const unsigned char *theSrcPStr,const int theInsertionOffset,char *theDstCStr,const int maxDstStrLength);
        +OSErr InsertCStrIntoHandle(const char *theCString,Handle theHandle,const long inInsertOffset);
        +
        +void CopyCStrAndInsertCStrIntoCStr(const char *theSrcCStr,const char *theInsertCStr,char *theDstCStr,const int maxDstStrLength);
        +
        +void CopyCStrAndInsertCStrsLongIntsIntoCStr(const char *theSrcCStr,const char **theInsertCStrs,const long *theLongInts,char *theDstCStr,const int maxDstStrLength);
        +
        +void CopyCStrAndInsert1LongIntIntoCStr(const char *theSrcCStr,const long theNum,char *theDstCStr,const int maxDstStrLength);
        +void CopyCStrAndInsert2LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,char *theDstCStr,const int maxDstStrLength);
        +void CopyCStrAndInsert3LongIntsIntoCStr(const char *theSrcCStr,const long long1,const long long2,const long long3,char *theDstCStr,const int maxDstStrLength);
        +
        +void CopyCStrAndInsertCStrLongIntIntoCStr(const char *theSrcCStr,const char *theInsertCStr,const long theNum,char *theDstCStr,const int maxDstStrLength);
        +OSErr CopyCStrAndInsertCStrLongIntIntoHandle(const char *theSrcCStr,const char *theInsertCStr,const long theNum,Handle *theHandle);
        +
        +
        +OSErr CopyIndexedWordToCStr(char *theSrcCStr,int whichWord,char *theDstCStr,int maxDstCStrLength);
        +OSErr CopyIndexedWordToNewHandle(char *theSrcCStr,int whichWord,Handle *outTheHandle);
        +
        +OSErr CopyIndexedLineToCStr(const char *theSrcCStr,int inWhichLine,int *lineEndIndex,Boolean *gotLastLine,char *theDstCStr,const int maxDstCStrLength);
        +OSErr CopyIndexedLineToNewHandle(const char *theSrcCStr,int inWhichLine,Handle *outNewHandle);
        +
        +OSErr ExtractIntFromCStr(const char *theSrcCStr,int *outInt,Boolean skipLeadingSpaces = true);
        +OSErr ExtractIntFromPStr(const unsigned char *theSrcPStr,int *outInt,Boolean skipLeadingSpaces = true);
        +
        +
        +void ConvertCStrToUpperCase(char *theSrcCStr);
        +
        +
        +int CountOccurencesOfCharInCStr(const char inChar,const char *inSrcCStr);
        +int CountWordsInCStr(const char *inSrcCStr);
        +
        +OSErr CountDigits(const char *inCStr,int *outNumIntegerDigits,int *outNumFractDigits);
        +
        +void ExtractCStrItemFromCStr(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,char *outDstCharPtr,const int inDstCharPtrMaxLength,const Boolean inTreatMultipleDelimsAsSingleDelim = false);
        +OSErr ExtractCStrItemFromCStrIntoNewHandle(const char *inSrcCStr,const char inItemDelimiter,const int inItemNumber,Boolean *foundItem,Handle *outNewHandle,const Boolean inTreatMultipleDelimsAsSingleDelim = false);
        +
        +
        +OSErr ExtractFloatFromCStr(const char *inCString,extended80 *outFloat);
        +OSErr CopyFloatToCStr(const extended80 *theFloat,char *theCStr,const int maxCStrLength,const int inMaxNumIntDigits = -1,const int inMaxNumFractDigits = -1);
        +
        +void SkipWhiteSpace(char **ioSrcCharPtr,const Boolean inStopAtEOL = false);
        +
        +
        +#ifdef __cplusplus
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/ErrorHandling.cpp b/vendor/openssl/openssl/MacOS/GetHTTPS.src/ErrorHandling.cpp
        new file mode 100644
        index 000000000..80b6a675f
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/ErrorHandling.cpp
        @@ -0,0 +1,170 @@
        +/* ====================================================================
        + * Copyright (c) 1998-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).
        + *
        + */
        + 
        + 
        + 
        + #include "ErrorHandling.hpp"
        +#include "CPStringUtils.hpp"
        +
        +#ifdef __EXCEPTIONS_ENABLED__
        +	#include "CMyException.hpp"
        +#endif
        +
        +
        +static char					gErrorMessageBuffer[512];
        +
        +char 						*gErrorMessage = gErrorMessageBuffer;
        +int							gErrorMessageMaxLength = sizeof(gErrorMessageBuffer);
        +
        +
        +
        +void SetErrorMessage(const char *theErrorMessage)
        +{
        +	if (theErrorMessage != nil)
        +	{
        +		CopyCStrToCStr(theErrorMessage,gErrorMessage,gErrorMessageMaxLength);
        +	}
        +}
        +
        +
        +void SetErrorMessageAndAppendLongInt(const char *theErrorMessage,const long theLongInt)
        +{
        +	if (theErrorMessage != nil)
        +	{
        +		CopyCStrAndConcatLongIntToCStr(theErrorMessage,theLongInt,gErrorMessage,gErrorMessageMaxLength);
        +	}
        +}
        +
        +void SetErrorMessageAndCStrAndLongInt(const char *theErrorMessage,const char * theCStr,const long theLongInt)
        +{
        +	if (theErrorMessage != nil)
        +	{
        +		CopyCStrAndInsertCStrLongIntIntoCStr(theErrorMessage,theCStr,theLongInt,gErrorMessage,gErrorMessageMaxLength);
        +	}
        +
        +}
        +
        +void SetErrorMessageAndCStr(const char *theErrorMessage,const char * theCStr)
        +{
        +	if (theErrorMessage != nil)
        +	{
        +		CopyCStrAndInsertCStrLongIntIntoCStr(theErrorMessage,theCStr,-1,gErrorMessage,gErrorMessageMaxLength);
        +	}
        +}
        +
        +
        +void AppendCStrToErrorMessage(const char *theErrorMessage)
        +{
        +	if (theErrorMessage != nil)
        +	{
        +		ConcatCStrToCStr(theErrorMessage,gErrorMessage,gErrorMessageMaxLength);
        +	}
        +}
        +
        +
        +void AppendLongIntToErrorMessage(const long theLongInt)
        +{
        +	ConcatLongIntToCStr(theLongInt,gErrorMessage,gErrorMessageMaxLength);
        +}
        +
        +
        +
        +char *GetErrorMessage(void)
        +{
        +	return gErrorMessage;
        +}
        +
        +
        +OSErr GetErrorMessageInNewHandle(Handle *inoutHandle)
        +{
        +OSErr		errCode;
        +
        +
        +	errCode = CopyCStrToNewHandle(gErrorMessage,inoutHandle);
        +	
        +	return(errCode);
        +}
        +
        +
        +OSErr GetErrorMessageInExistingHandle(Handle inoutHandle)
        +{
        +OSErr		errCode;
        +
        +
        +	errCode = CopyCStrToExistingHandle(gErrorMessage,inoutHandle);
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +OSErr AppendErrorMessageToHandle(Handle inoutHandle)
        +{
        +OSErr		errCode;
        +
        +
        +	errCode = AppendCStrToHandle(gErrorMessage,inoutHandle,nil);
        +	
        +	return(errCode);
        +}
        +
        +
        +#ifdef __EXCEPTIONS_ENABLED__
        +
        +void ThrowErrorMessageException(void)
        +{
        +	ThrowDescriptiveException(gErrorMessage);
        +}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/ErrorHandling.hpp b/vendor/openssl/openssl/MacOS/GetHTTPS.src/ErrorHandling.hpp
        new file mode 100644
        index 000000000..fbfbe786b
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/ErrorHandling.hpp
        @@ -0,0 +1,147 @@
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifndef kGenericError
        +	#define kGenericError		-1
        +#endif
        +
        +extern char	*gErrorMessage;
        +
        +
        +void SetErrorMessage(const char *theErrorMessage);
        +void SetErrorMessageAndAppendLongInt(const char *theErrorMessage,const long theLongInt);
        +void SetErrorMessageAndCStrAndLongInt(const char *theErrorMessage,const char * theCStr,const long theLongInt);
        +void SetErrorMessageAndCStr(const char *theErrorMessage,const char * theCStr);
        +void AppendCStrToErrorMessage(const char *theErrorMessage);
        +void AppendLongIntToErrorMessage(const long theLongInt);
        +
        +
        +char *GetErrorMessage(void);
        +OSErr GetErrorMessageInNewHandle(Handle *inoutHandle);
        +OSErr GetErrorMessageInExistingHandle(Handle inoutHandle);
        +OSErr AppendErrorMessageToHandle(Handle inoutHandle);
        +
        +
        +#ifdef __EXCEPTIONS_ENABLED__
        +	void ThrowErrorMessageException(void);
        +#endif
        +
        +
        +
        +//	A bunch of evil macros that would be unnecessary if I were always using C++ !
        +
        +#define SetErrorMessageAndBailIfNil(theArg,theMessage)								\
        +{																					\
        +	if (theArg == nil)																\
        +	{																				\
        +		SetErrorMessage(theMessage);												\
        +		errCode = kGenericError;													\
        +		goto EXITPOINT;																\
        +	}																				\
        +}
        +
        +
        +#define SetErrorMessageAndBail(theMessage)											\
        +{																					\
        +		SetErrorMessage(theMessage);												\
        +		errCode = kGenericError;													\
        +		goto EXITPOINT;																\
        +}
        +
        +
        +#define SetErrorMessageAndLongIntAndBail(theMessage,theLongInt)						\
        +{																					\
        +		SetErrorMessageAndAppendLongInt(theMessage,theLongInt);						\
        +		errCode = kGenericError;													\
        +		goto EXITPOINT;																\
        +}
        +
        +
        +#define SetErrorMessageAndLongIntAndBailIfError(theErrCode,theMessage,theLongInt)	\
        +{																					\
        +	if (theErrCode != noErr)														\
        +	{																				\
        +		SetErrorMessageAndAppendLongInt(theMessage,theLongInt);						\
        +		errCode = theErrCode;														\
        +		goto EXITPOINT;																\
        +	}																				\
        +}
        +
        +
        +#define SetErrorMessageCStrLongIntAndBailIfError(theErrCode,theMessage,theCStr,theLongInt)	\
        +{																					\
        +	if (theErrCode != noErr)														\
        +	{																				\
        +		SetErrorMessageAndCStrAndLongInt(theMessage,theCStr,theLongInt);			\
        +		errCode = theErrCode;														\
        +		goto EXITPOINT;																\
        +	}																				\
        +}
        +
        +
        +#define SetErrorMessageAndCStrAndBail(theMessage,theCStr)							\
        +{																					\
        +	SetErrorMessageAndCStr(theMessage,theCStr);										\
        +	errCode = kGenericError;														\
        +	goto EXITPOINT;																	\
        +}
        +
        +
        +#define SetErrorMessageAndBailIfError(theErrCode,theMessage)						\
        +{																					\
        +	if (theErrCode != noErr)														\
        +	{																				\
        +		SetErrorMessage(theMessage);												\
        +		errCode = theErrCode;														\
        +		goto EXITPOINT;																\
        +	}																				\
        +}
        +
        +
        +#define SetErrorMessageAndLongIntAndBailIfNil(theArg,theMessage,theLongInt)			\
        +{																					\
        +	if (theArg == nil)																\
        +	{																				\
        +		SetErrorMessageAndAppendLongInt(theMessage,theLongInt);						\
        +		errCode = kGenericError;													\
        +		goto EXITPOINT;																\
        +	}																				\
        +}
        +
        +
        +#define BailIfError(theErrCode)														\
        +{																					\
        +	if ((theErrCode) != noErr)														\
        +	{																				\
        +		goto EXITPOINT;																\
        +	}																				\
        +}
        +
        +
        +#define SetErrCodeAndBail(theErrCode)												\
        +{																					\
        +	errCode = theErrCode;															\
        +																					\
        +	goto EXITPOINT;																	\
        +}
        +
        +
        +#define SetErrorCodeAndMessageAndBail(theErrCode,theMessage)						\
        +{																					\
        +	SetErrorMessage(theMessage);													\
        +	errCode = theErrCode;															\
        +	goto EXITPOINT;																	\
        +}
        +
        +
        +#define BailNow()																	\
        +{																					\
        +	errCode = kGenericError;														\
        +	goto EXITPOINT;																	\
        +}
        +
        +
        +#ifdef __cplusplus
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/GetHTTPS.cpp b/vendor/openssl/openssl/MacOS/GetHTTPS.src/GetHTTPS.cpp
        new file mode 100644
        index 000000000..3a5e3f018
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/GetHTTPS.cpp
        @@ -0,0 +1,209 @@
        +/*
        + *	An demo illustrating how to retrieve a URI from a secure HTTP server.
        + *
        + *	Author: 	Roy Wood
        + *	Date:		September 7, 1999
        + *	Comments:	This relies heavily on my MacSockets library.
        + *				This project is also set up so that it expects the OpenSSL source folder (0.9.4 as I write this)
        + *				to live in a folder called "OpenSSL-0.9.4" in this project's parent folder.  For example:
        + *
        + *					Macintosh HD:
        + *						Development:
        + *							OpenSSL-0.9.4:
        + *								(OpenSSL sources here)
        + *							OpenSSL Example:
        + *								(OpenSSL example junk here)
        + *
        + *
        + *				Also-- before attempting to compile this, make sure the aliases in "OpenSSL-0.9.4:include:openssl" 
        + *				are installed!  Use the AppleScript applet in the "openssl-0.9.4" folder to do this!
        + */
        +/* modified to seed the PRNG */
        +/* modified to use CRandomizer for seeding */
        +
        +
        +//	Include some funky libs I've developed over time
        +
        +#include "CPStringUtils.hpp"
        +#include "ErrorHandling.hpp"
        +#include "MacSocket.h"
        +#include "Randomizer.h"
        +
        +//	We use the OpenSSL implementation of SSL....
        +//	This was a lot of work to finally get going, though you wouldn't know it by the results!
        +
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +
        +#include <timer.h>
        +
        +//	Let's try grabbing some data from here:
        +
        +#define kHTTPS_DNS		"www.apache-ssl.org"
        +#define kHTTPS_Port		443
        +#define kHTTPS_URI		"/"
        +
        +
        +//	Forward-declare this
        +
        +OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr);
        +
        +//	My idle-wait callback.  Doesn't do much, does it?  Silly cooperative multitasking.
        +
        +OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr)
        +{
        +#pragma unused(inUserRefPtr)
        +
        +EventRecord		theEvent;
        +	::EventAvail(everyEvent,&theEvent);
        +	
        +	CRandomizer *randomizer = (CRandomizer*)inUserRefPtr;
        +	if (randomizer)
        +		randomizer->PeriodicAction();
        +
        +	return(noErr);
        +}
        +
        +
        +//	Finally!
        +
        +void main(void)
        +{
        +	OSErr				errCode;
        +	int					theSocket = -1;
        +	int					theTimeout = 30;
        +
        +	SSL_CTX				*ssl_ctx = nil;
        +	SSL					*ssl = nil;
        +
        +	char				tempString[256];
        +	UnsignedWide		microTickCount;
        +
        +
        +	CRandomizer randomizer;
        +	
        +	printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
        +	
        +	BailIfError(errCode = MacSocket_Startup());
        +
        +
        +
        +	//	Create a socket-like object
        +	
        +	BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,&randomizer));
        +
        +	
        +	//	Set up the connect string and try to connect
        +	
        +	CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString));
        +	
        +	printf("Connecting to %s....\n",tempString);
        +
        +	BailIfError(errCode = MacSocket_connect(theSocket,tempString));
        +	
        +	
        +	//	Init SSL stuff
        +	
        +	SSL_load_error_strings();
        +	
        +	SSLeay_add_ssl_algorithms();
        +	
        +	
        +	//	Pick the SSL method
        +	
        +//	ssl_ctx = SSL_CTX_new(SSLv2_client_method());
        +	ssl_ctx = SSL_CTX_new(SSLv23_client_method());
        +//	ssl_ctx = SSL_CTX_new(SSLv3_client_method());
        +			
        +
        +	//	Create an SSL thingey and try to negotiate the connection
        +	
        +	ssl = SSL_new(ssl_ctx);
        +	
        +	SSL_set_fd(ssl,theSocket);
        +	
        +	errCode = SSL_connect(ssl);
        +	
        +	if (errCode < 0)
        +	{
        +		SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode);
        +	}
        +	
        +	//	Request the URI from the host
        +	
        +	CopyCStrToCStr("GET ",tempString,sizeof(tempString));
        +	ConcatCStrToCStr(kHTTPS_URI,tempString,sizeof(tempString));
        +	ConcatCStrToCStr(" HTTP/1.0\r\n\r\n",tempString,sizeof(tempString));
        +
        +	
        +	errCode = SSL_write(ssl,tempString,CStrLength(tempString));
        +	
        +	if (errCode < 0)
        +	{
        +		SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode);
        +	}
        +	
        +
        +	for (;;)
        +	{
        +	char	tempString[256];
        +	int		bytesRead;
        +		
        +
        +		//	Read some bytes and dump them to the console
        +		
        +		bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1);
        +		
        +		if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket))
        +		{
        +			break;
        +		}
        +		
        +		else if (bytesRead < 0)
        +		{
        +			SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead);
        +		}
        +		
        +		
        +		tempString[bytesRead] = '\0';
        +		
        +		printf("%s", tempString);
        +	}
        +	
        +	printf("\n\n\n");
        +	
        +	//	All done!
        +	
        +	errCode = noErr;
        +	
        +	
        +EXITPOINT:
        +
        +	//	Clean up and go home
        +	
        +	if (theSocket >= 0)
        +	{
        +		MacSocket_close(theSocket);
        +	}
        +	
        +	if (ssl != nil)
        +	{
        +		SSL_free(ssl);
        +	}
        +	
        +	if (ssl_ctx != nil)
        +	{
        +		SSL_CTX_free(ssl_ctx);
        +	}
        +	
        +	
        +	if (errCode != noErr)
        +	{
        +		printf("An error occurred:\n");
        +		
        +		printf("%s",GetErrorMessage());
        +	}
        +	
        +	
        +	MacSocket_Shutdown();
        +}
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/MacSocket.cpp b/vendor/openssl/openssl/MacOS/GetHTTPS.src/MacSocket.cpp
        new file mode 100644
        index 000000000..c95d804d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/MacSocket.cpp
        @@ -0,0 +1,1607 @@
        +/*
        + *	A simple socket-like package.  
        + *	This could undoubtedly be improved, since it does polling and busy-waiting.  
        + *	At least it uses asynch I/O and implements timeouts!
        + *
        + *	Other funkiness includes the use of my own (possibly brain-damaged) error-handling infrastructure.
        + *
        + *	-Roy Wood (roy@centricsystems.ca)
        + *
        + */
        +
        +
        +/* ====================================================================
        + * Copyright (c) 1998-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).
        + *
        + */
        + 
        +
        +
        +
        +
        +#include "MacSocket.h"
        +
        +#include <Threads.h>
        +
        +#include <OpenTransport.h>
        +#include <OpenTpTInternet.h>
        +#include <OpenTptClient.h>
        +
        +
        +
        +#include "CPStringUtils.hpp"
        +#include "ErrorHandling.hpp"
        +
        +
        +//	#define MACSOCKET_DEBUG		1
        +
        +#ifdef MACSOCKET_DEBUG
        +	#include <stdio.h>
        +#endif
        +
        +
        +
        +extern int errno;
        +
        +
        +#define kMaxNumSockets			4
        +
        +
        +struct SocketStruct
        +{
        +	Boolean						mIsInUse;
        +
        +	Boolean						mEndpointIsBound;
        +
        +	Boolean						mLocalEndIsConnected;
        +	Boolean						mRemoteEndIsConnected;
        +
        +	Boolean						mReceivedTOpenComplete;
        +	Boolean						mReceivedTBindComplete;
        +	Boolean						mReceivedTConnect;
        +	Boolean						mReceivedTListen;
        +	Boolean						mReceivedTPassCon;
        +	Boolean						mReceivedTDisconnect;
        +	Boolean						mReceivedTOrdRel;
        +	Boolean						mReceivedTDisconnectComplete;
        +	
        +	long						mTimeoutTicks;
        +	long						mOperationStartTicks;
        +	
        +	MacSocket_IdleWaitCallback	mIdleWaitCallback;
        +	void						*mUserRefPtr;
        +	
        +	OTEventCode					mExpectedCode;
        +	OTResult					mAsyncOperationResult;
        +	
        +	EndpointRef		 			mEndPointRef;
        +	TBind						*mBindRequestedAddrInfo;
        +	TBind						*mAssignedAddrInfo;
        +	TCall						*mRemoteAddrInfo;
        +	
        +	Boolean						mReadyToReadData;
        +	Boolean						mReadyToWriteData;
        +	
        +	Ptr							mReadBuffer;
        +	Ptr							mWriteBuffer;
        +	
        +	int							mLastError;
        +	char						mErrMessage[256];
        +};
        +
        +typedef struct SocketStruct	SocketStruct;
        +
        +
        +static SocketStruct			sSockets[kMaxNumSockets];
        +static Boolean				sSocketsSetup = false;
        +
        +
        +
        +
        +static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag);
        +
        +static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie);
        +
        +static Boolean	SocketIndexIsValid(const int inSocketNum);
        +
        +static void InitSocket(SocketStruct *ioSocket);
        +
        +static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode);
        +
        +static Boolean TimeoutElapsed(const SocketStruct *inSocket);
        +
        +static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP);
        +
        +
        +
        +void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength)
        +{
        +	if (outSocketErrCode != nil)
        +	{
        +		*outSocketErrCode = -1;
        +	}
        +	
        +	if (outSocketErrString != nil)
        +	{
        +		CopyCStrToCStr("",outSocketErrString,inSocketErrStringMaxLength);
        +	}
        +	
        +	
        +	if (SocketIndexIsValid(inSocketNum))
        +	{
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +		
        +		if (outSocketErrCode != nil)
        +		{
        +			*outSocketErrCode = theSocketStruct->mLastError;
        +		}
        +
        +		if (outSocketErrString != nil)
        +		{
        +			CopyCStrToCStr(theSocketStruct->mErrMessage,outSocketErrString,inSocketErrStringMaxLength);
        +		}
        +	}
        +}
        +
        +
        +void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr)
        +{
        +	if (SocketIndexIsValid(inSocketNum))
        +	{
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +
        +		theSocketStruct->mUserRefPtr = inNewRefPtr;
        +	}
        +}
        +
        +
        +
        +void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
        +{
        +	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
        +	{
        +	char			tempString[256];
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +		
        +		CopyCStrToCStr("",tempString,sizeof(tempString));
        +
        +		if (theSocketStruct->mAssignedAddrInfo != nil)
        +		{
        +		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mAssignedAddrInfo->addr.buf;
        +		InetHost		theInetHost = theInetAddress->fHost;
        +			
        +			if (theInetHost == 0)
        +			{
        +			InetInterfaceInfo	theInetInterfaceInfo;
        +				
        +				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
        +				{
        +					theInetHost = theInetInterfaceInfo.fAddress;
        +				}
        +			}
        +		
        +			::OTInetHostToString(theInetHost,tempString);
        +			
        +			ConcatCStrToCStr(":",tempString,sizeof(tempString));
        +			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
        +		}
        +		
        +		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
        +	}
        +}
        +
        +
        +
        +void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
        +{
        +	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
        +	{
        +	char			tempString[256];
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +		
        +		CopyCStrToCStr("",tempString,sizeof(tempString));
        +
        +		if (theSocketStruct->mRemoteAddrInfo != nil)
        +		{
        +		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mRemoteAddrInfo->addr.buf;
        +		InetHost		theInetHost = theInetAddress->fHost;
        +			
        +			if (theInetHost == 0)
        +			{
        +			InetInterfaceInfo	theInetInterfaceInfo;
        +				
        +				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
        +				{
        +					theInetHost = theInetInterfaceInfo.fAddress;
        +				}
        +			}
        +		
        +			::OTInetHostToString(theInetHost,tempString);
        +			
        +			ConcatCStrToCStr(":",tempString,sizeof(tempString));
        +			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
        +		}
        +		
        +		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
        +	}
        +}
        +
        +
        +
        +Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum)
        +{
        +Boolean		theResult = false;
        +
        +	if (SocketIndexIsValid(inSocketNum))
        +	{
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +
        +		theResult = theSocketStruct->mReceivedTOrdRel;
        +	}
        +
        +	return(theResult);
        +}
        +
        +
        +
        +Boolean MacSocket_ListenCompleted(const int inSocketNum)
        +{
        +Boolean		theResult = false;
        +
        +	if (SocketIndexIsValid(inSocketNum))
        +	{
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +
        +		theResult = theSocketStruct->mReceivedTPassCon;
        +	}
        +
        +	return(theResult);
        +}
        +
        +
        +
        +Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum)
        +{
        +	if (SocketIndexIsValid(inSocketNum))
        +	{
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +		return(theSocketStruct->mRemoteEndIsConnected);
        +	}
        +	
        +	else
        +	{
        +		return(false);
        +	}
        +}
        +
        +
        +
        +Boolean MacSocket_LocalEndIsOpen(const int inSocketNum)
        +{
        +	if (SocketIndexIsValid(inSocketNum))
        +	{
        +	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +		return(theSocketStruct->mLocalEndIsConnected);
        +	}
        +	
        +	else
        +	{
        +		return(false);
        +	}
        +}
        +
        +
        +
        +static Boolean TimeoutElapsed(const SocketStruct *inSocket)
        +{
        +Boolean		timeIsUp = false;
        +
        +	if (inSocket != nil && inSocket->mTimeoutTicks > 0 && ::TickCount() > inSocket->mOperationStartTicks + inSocket->mTimeoutTicks)
        +	{
        +		timeIsUp = true;
        +	}
        +	
        +	
        +	return(timeIsUp);
        +}
        +
        +
        +
        +static Boolean SocketIndexIsValid(const int inSocketNum)
        +{
        +	if (inSocketNum >= 0 && inSocketNum < kMaxNumSockets && sSockets[inSocketNum].mEndPointRef != kOTInvalidEndpointRef)
        +	{
        +		return(true);
        +	}
        +	
        +	else
        +	{
        +		return(false);
        +	}
        +}
        +
        +
        +
        +static void InitSocket(SocketStruct *ioSocket)
        +{
        +	ioSocket->mIsInUse = false;
        +	
        +	ioSocket->mEndpointIsBound = false;
        +	
        +	ioSocket->mLocalEndIsConnected = false;
        +	ioSocket->mRemoteEndIsConnected = false;
        +	
        +	ioSocket->mReceivedTOpenComplete = false;
        +	ioSocket->mReceivedTBindComplete = false;
        +	ioSocket->mReceivedTConnect = false;
        +	ioSocket->mReceivedTListen = false;
        +	ioSocket->mReceivedTPassCon = false;
        +	ioSocket->mReceivedTDisconnect = false;
        +	ioSocket->mReceivedTOrdRel = false;
        +	ioSocket->mReceivedTDisconnectComplete = false;
        +	
        +	ioSocket->mTimeoutTicks = 30 * 60;
        +	ioSocket->mOperationStartTicks = -1;
        +	
        +	ioSocket->mIdleWaitCallback = nil;
        +	ioSocket->mUserRefPtr = nil;
        +	
        +	ioSocket->mExpectedCode = 0;
        +	ioSocket->mAsyncOperationResult = noErr;
        +	
        +	ioSocket->mEndPointRef = kOTInvalidEndpointRef;
        +	
        +	ioSocket->mBindRequestedAddrInfo = nil;
        +	ioSocket->mAssignedAddrInfo = nil;
        +	ioSocket->mRemoteAddrInfo = nil;
        +	
        +	ioSocket->mReadyToReadData = false;
        +	ioSocket->mReadyToWriteData = true;
        +	
        +	ioSocket->mReadBuffer = nil;
        +	ioSocket->mWriteBuffer = nil;
        +
        +	ioSocket->mLastError = noErr;
        +	CopyCStrToCStr("",ioSocket->mErrMessage,sizeof(ioSocket->mErrMessage));
        +}
        +
        +
        +
        +static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode)
        +{
        +	ioSocket->mOperationStartTicks = ::TickCount();
        +	
        +	ioSocket->mAsyncOperationResult = noErr;
        +	
        +	ioSocket->mExpectedCode = inExpectedCode;
        +}
        +
        +
        +//	The wait function....
        +
        +static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag)
        +{
        +OSErr 		errCode = noErr;
        +OTResult	theOTResult = noErr;
        +
        +	
        +	SetErrorMessageAndBailIfNil(ioSocket,"MyBusyWait: Bad parameter, ioSocket = nil");
        +	SetErrorMessageAndBailIfNil(inAsyncOperationCompleteFlag,"MyBusyWait: Bad parameter, inAsyncOperationCompleteFlag = nil");
        +	
        +	for (;;) 
        +	{
        +		if (*inAsyncOperationCompleteFlag)
        +		{
        +			theOTResult = ioSocket->mAsyncOperationResult;
        +			
        +			break;
        +		}
        +		
        +		if (ioSocket->mIdleWaitCallback != nil)
        +		{
        +			theOTResult = (*(ioSocket->mIdleWaitCallback))(ioSocket->mUserRefPtr);
        +			
        +			if (theOTResult != noErr && returnImmediatelyOnError)
        +			{
        +				break;
        +			}
        +		}
        +		
        +		if (TimeoutElapsed(ioSocket))
        +		{
        +			theOTResult = kMacSocket_TimeoutErr;
        +			
        +			break;
        +		}
        +	}
        +
        +
        +EXITPOINT:
        +	
        +	if (outOTResult != nil)
        +	{
        +		*outOTResult = theOTResult;
        +	}
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +//	I used to do thread switching, but stopped.  It could easily be rolled back in though....
        +
        +static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie)
        +{
        +SocketStruct *theSocketStruct = (SocketStruct *) contextPtr;
        +	
        +	if (theSocketStruct != nil)
        +	{
        +		if (theSocketStruct->mExpectedCode != 0 && code == theSocketStruct->mExpectedCode)
        +		{
        +			theSocketStruct->mAsyncOperationResult = result;
        +			
        +			theSocketStruct->mExpectedCode = 0;
        +		}
        +		
        +		
        +		switch (code) 
        +		{
        +			case T_OPENCOMPLETE:
        +			{
        +				theSocketStruct->mReceivedTOpenComplete = true;
        +				
        +				theSocketStruct->mEndPointRef = (EndpointRef) cookie;
        +				
        +				break;
        +			}
        +
        +			
        +			case T_BINDCOMPLETE:
        +			{
        +				theSocketStruct->mReceivedTBindComplete = true;
        +				
        +				break;
        +			}
        +			
        +
        +			case T_CONNECT:
        +			{
        +				theSocketStruct->mReceivedTConnect = true;
        +
        +				theSocketStruct->mLocalEndIsConnected = true;
        +				
        +				theSocketStruct->mRemoteEndIsConnected = true;
        +
        +				break;
        +			}
        +			
        +
        +			case T_LISTEN:
        +			{
        +				theSocketStruct->mReceivedTListen = true;
        +				
        +				break;
        +			}
        +			
        +
        +			case T_PASSCON:
        +			{
        +				theSocketStruct->mReceivedTPassCon = true;
        +				
        +				theSocketStruct->mLocalEndIsConnected = true;
        +				
        +				theSocketStruct->mRemoteEndIsConnected = true;
        +
        +				break;
        +			}
        +
        +
        +			case T_DATA:
        +			{
        +				theSocketStruct->mReadyToReadData = true;
        +				
        +				break;
        +			}
        +			
        +			case T_GODATA:
        +			{
        +				theSocketStruct->mReadyToWriteData = true;
        +				
        +				break;
        +			}
        +			
        +			case T_DISCONNECT:
        +			{
        +				theSocketStruct->mReceivedTDisconnect = true;
        +				
        +				theSocketStruct->mRemoteEndIsConnected = false;
        +				
        +				theSocketStruct->mLocalEndIsConnected = false;
        +				
        +				::OTRcvDisconnect(theSocketStruct->mEndPointRef,nil);
        +				
        +				break;
        +			}
        +
        +			case T_ORDREL:
        +			{
        +				theSocketStruct->mReceivedTOrdRel = true;
        +				
        +				//	We can still write data, so don't clear mRemoteEndIsConnected
        +				
        +				::OTRcvOrderlyDisconnect(theSocketStruct->mEndPointRef);
        +				
        +				break;
        +			}
        +			
        +			case T_DISCONNECTCOMPLETE:
        +			{
        +				theSocketStruct->mReceivedTDisconnectComplete = true;
        +				
        +				theSocketStruct->mRemoteEndIsConnected = false;
        +				
        +				theSocketStruct->mLocalEndIsConnected = false;
        +				
        +				break;
        +			}
        +		}
        +	}
        +/*
        +T_LISTEN OTListen
        +T_CONNECT OTRcvConnect
        +T_DATA OTRcv, OTRcvUData
        +T_DISCONNECT OTRcvDisconnect
        +T_ORDREL OTRcvOrderlyDisconnect
        +T_GODATA OTSnd, OTSndUData, OTLook
        +T_PASSCON none
        +
        +T_EXDATA OTRcv
        +T_GOEXDATA OTSnd, OTLook
        +T_UDERR OTRcvUDErr
        +*/
        +}
        +
        +
        +
        +//	Initialize the main socket data structure
        +
        +OSErr MacSocket_Startup(void)
        +{
        +	if (!sSocketsSetup)
        +	{
        +		for (int i = 0;i < kMaxNumSockets;i++)
        +		{
        +			InitSocket(&(sSockets[i]));
        +		}
        +
        +		::InitOpenTransport();
        +		
        +		sSocketsSetup = true;
        +	}
        +	
        +	
        +	return(noErr);
        +}
        +
        +
        +
        +//	Cleanup before exiting
        +
        +OSErr MacSocket_Shutdown(void)
        +{
        +	if (sSocketsSetup)
        +	{
        +		for (int i = 0;i < kMaxNumSockets;i++)
        +		{
        +		SocketStruct *theSocketStruct = &(sSockets[i]);
        +		
        +			if (theSocketStruct->mIsInUse)
        +			{
        +				if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
        +				{
        +				OTResult	theOTResult;
        +				
        +				
        +					//	Since we're killing the endpoint, I don't bother to send the disconnect (sorry!)
        +
        +/*
        +					if (theSocketStruct->mLocalEndIsConnected)
        +					{
        +						//	This is an abortive action, so we do a hard disconnect instead of an OTSndOrderlyDisconnect
        +						
        +						theOTResult = ::OTSndDisconnect(theSocketStruct->mEndPointRef, nil);
        +						
        +						//	Now we have to watch for T_DISCONNECTCOMPLETE event
        +						
        +						theSocketStruct->mLocalEndIsConnected = false;
        +					}
        +*/					
        +					
        +					theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
        +					
        +					
        +					theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
        +				}
        +				
        +				if (theSocketStruct->mBindRequestedAddrInfo != nil)
        +				{
        +					::OTFree((void *) theSocketStruct->mBindRequestedAddrInfo,T_BIND);
        +					
        +					theSocketStruct->mBindRequestedAddrInfo = nil;
        +				}
        +				
        +				if (theSocketStruct->mAssignedAddrInfo != nil)
        +				{
        +					::OTFree((void *) theSocketStruct->mAssignedAddrInfo,T_BIND);
        +					
        +					theSocketStruct->mAssignedAddrInfo = nil;
        +				}
        +				
        +				if (theSocketStruct->mRemoteAddrInfo != nil)
        +				{
        +					::OTFree((void *) theSocketStruct->mRemoteAddrInfo,T_CALL);
        +					
        +					theSocketStruct->mRemoteAddrInfo = nil;
        +				}
        +				
        +				
        +			}
        +		}
        +		
        +		::CloseOpenTransport();
        +
        +		sSocketsSetup = false;
        +	}
        +	
        +	return(noErr);
        +}
        +
        +
        +
        +
        +
        +
        +//	Allocate a socket
        +
        +OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr)
        +{
        +//	Gotta roll support back in for threads eventually.....
        +
        +#pragma unused(inDoThreadSwitching)
        +
        +
        +OSErr	errCode = noErr;
        +
        +	
        +	SetErrorMessageAndBailIfNil(outSocketNum,"MacSocket_socket: Bad parameter, outSocketNum == nil");
        +	
        +	*outSocketNum = -1;
        +	
        +	
        +	//	Find an unused socket
        +	
        +	for (int i = 0;i < kMaxNumSockets;i++)
        +	{
        +		if (sSockets[i].mIsInUse == false)
        +		{
        +		OTResult		theOTResult;
        +		SocketStruct	*theSocketStruct = &(sSockets[i]);
        +		
        +			
        +			InitSocket(theSocketStruct);
        +			
        +			theSocketStruct->mIdleWaitCallback = inIdleWaitCallback;
        +			theSocketStruct->mUserRefPtr = inUserRefPtr;
        +			
        +			theSocketStruct->mTimeoutTicks = inTimeoutTicks;
        +			
        +
        +			//	Set up OT endpoint
        +			
        +			PrepareForAsyncOperation(theSocketStruct,T_OPENCOMPLETE);
        +			
        +			theOTResult = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),0,nil,OTNonYieldingNotifier,(void *) theSocketStruct);
        +			
        +			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
        +			
        +			BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOpenComplete)));
        +																						
        +			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
        +			
        +			
        +			*outSocketNum = i;
        +			
        +			errCode = noErr;
        +			
        +			theSocketStruct->mIsInUse = true;
        +			
        +			break;
        +		}
        +		
        +		else if (i == kMaxNumSockets - 1)
        +		{
        +			SetErrorMessageAndBail("MacSocket_socket: No sockets available");
        +		}
        +	}
        +
        +
        +EXITPOINT:
        +	
        +	errno = errCode;
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +
        +OSErr MacSocket_listen(const int inSocketNum,const int inPortNum)
        +{
        +OSErr			errCode = noErr;
        +SocketStruct	*theSocketStruct = nil;
        +
        +
        +	if (!SocketIndexIsValid(inSocketNum))
        +	{
        +		SetErrorMessageAndBail("MacSocket_listen: Invalid socket number specified");
        +	}
        +
        +
        +	theSocketStruct = &(sSockets[inSocketNum]);
        +
        +
        +OTResult		theOTResult;
        +	
        +	
        +	if (theSocketStruct->mBindRequestedAddrInfo == nil)
        +	{
        +		theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
        +		SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
        +	}
        +	
        +	if (theSocketStruct->mAssignedAddrInfo == nil)
        +	{
        +		theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
        +		SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
        +	}
        +	
        +	if (theSocketStruct->mRemoteAddrInfo == nil)
        +	{
        +		theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
        +		SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
        +	}
        +	
        +
        +	if (!theSocketStruct->mEndpointIsBound)
        +	{
        +	InetInterfaceInfo	theInetInterfaceInfo;
        +		
        +		theOTResult = ::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't determine OT interface info, OTInetGetInterfaceInfo() = ",theOTResult);
        +
        +
        +	InetAddress	*theInetAddress = (InetAddress *) theSocketStruct->mBindRequestedAddrInfo->addr.buf;
        +		
        +//		theInetAddress->fAddressType = AF_INET;
        +//		theInetAddress->fPort = inPortNum;
        +//		theInetAddress->fHost = theInetInterfaceInfo.fAddress;
        +		
        +		::OTInitInetAddress(theInetAddress,inPortNum,theInetInterfaceInfo.fAddress);
        +
        +		theSocketStruct->mBindRequestedAddrInfo->addr.len = sizeof(InetAddress);
        +		
        +		theSocketStruct->mBindRequestedAddrInfo->qlen = 1;
        +		
        +		
        +		theOTResult = ::OTSetSynchronous(theSocketStruct->mEndPointRef);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetSynchronous() = ",theOTResult);
        +		
        +		theOTResult = NegotiateIPReuseAddrOption(theSocketStruct->mEndPointRef,true);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT IP address reuse flag, NegotiateIPReuseAddrOption() = ",theOTResult);
        +		
        +		theOTResult = ::OTSetAsynchronous(theSocketStruct->mEndPointRef);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetAsynchronous() = ",theOTResult);
        +
        +		
        +		PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
        +				
        +		theOTResult = ::OTBind(theSocketStruct->mEndPointRef,theSocketStruct->mBindRequestedAddrInfo,theSocketStruct->mAssignedAddrInfo);
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
        +		
        +		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
        +		
        +		
        +		theSocketStruct->mEndpointIsBound = true;
        +	}
        +
        +
        +	PrepareForAsyncOperation(theSocketStruct,T_LISTEN);
        +
        +	theOTResult = ::OTListen(theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
        +	
        +	if (theOTResult == noErr)
        +	{
        +		PrepareForAsyncOperation(theSocketStruct,T_PASSCON);
        +		
        +		theOTResult = ::OTAccept(theSocketStruct->mEndPointRef,theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
        +		
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't begin OT accept, OTAccept() = ",theOTResult);
        +		
        +		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTPassCon)));
        +																					
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't accept OT connection, OTAccept() = ",theOTResult);
        +	}
        +	
        +	else if (theOTResult == kOTNoDataErr)
        +	{
        +		theOTResult = noErr;
        +	}
        +	
        +	else
        +	{
        +		SetErrorMessageAndLongIntAndBail("MacSocket_listen: Can't begin OT listen, OTListen() = ",theOTResult);
        +	}
        +
        +
        +	errCode = noErr;
        +
        +
        +EXITPOINT:
        +	
        +	if (theSocketStruct != nil)
        +	{
        +		theSocketStruct->mLastError = noErr;
        +		
        +		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +
        +		if (errCode != noErr)
        +		{
        +			theSocketStruct->mLastError = errCode;
        +			
        +			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +		}
        +	}
        +	
        +	errno = errCode;
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +
        +OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort)
        +{
        +OSErr			errCode = noErr;
        +SocketStruct	*theSocketStruct = nil;
        +
        +
        +	if (!SocketIndexIsValid(inSocketNum))
        +	{
        +		SetErrorMessageAndBail("MacSocket_connect: Invalid socket number specified");
        +	}
        +
        +	theSocketStruct = &(sSockets[inSocketNum]);
        +
        +	if (theSocketStruct->mEndpointIsBound)
        +	{
        +		SetErrorMessageAndBail("MacSocket_connect: Socket previously bound");
        +	}
        +
        +	
        +OTResult		theOTResult;
        +
        +	theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
        +																				
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
        +	SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
        +	
        +
        +	theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
        +																				
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
        +	SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
        +
        +
        +	theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
        +																				
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
        +	SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
        +
        +	
        +	PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
        +
        +	theOTResult = ::OTBind(theSocketStruct->mEndPointRef,nil,theSocketStruct->mAssignedAddrInfo);
        +																				
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
        +	
        +	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
        +																				
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
        +	
        +	theSocketStruct->mEndpointIsBound = true;
        +	
        +
        +TCall		sndCall;
        +DNSAddress 	hostDNSAddress;
        +	
        +	//	Set up target address
        +	
        +	sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
        +	sndCall.addr.len = ::OTInitDNSAddress(&hostDNSAddress,inTargetAddressAndPort);
        +	sndCall.opt.buf = nil;
        +	sndCall.opt.len = 0;
        +	sndCall.udata.buf = nil;
        +	sndCall.udata.len = 0;
        +	sndCall.sequence = 0;
        +		
        +	//	Connect!
        +	
        +	PrepareForAsyncOperation(theSocketStruct,T_CONNECT);
        +
        +	theOTResult = ::OTConnect(theSocketStruct->mEndPointRef,&sndCall,nil);
        +	
        +	if (theOTResult == kOTNoDataErr)
        +	{
        +		theOTResult = noErr;
        +	}
        +												
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
        +	
        +	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTConnect)));
        +	
        +	if (theOTResult == kMacSocket_TimeoutErr)
        +	{
        +		SetErrorMessageAndBail("MacSocket_connect: Can't connect OT endpoint, OTConnect() = kMacSocket_TimeoutErr");
        +	}
        +	
        +	else
        +	{
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
        +	}
        +
        +	theOTResult = ::OTRcvConnect(theSocketStruct->mEndPointRef,nil);
        +												
        +	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't complete connect on OT endpoint, OTRcvConnect() = ",theOTResult);
        +
        +
        +	errCode = noErr;
        +
        +
        +#ifdef MACSOCKET_DEBUG
        +	printf("MacSocket_connect: connect completed\n");
        +#endif
        +
        +EXITPOINT:
        +	
        +	if (theSocketStruct != nil)
        +	{
        +		theSocketStruct->mLastError = noErr;
        +		
        +		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +
        +		if (errCode != noErr)
        +		{
        +			theSocketStruct->mLastError = errCode;
        +			
        +			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +		}
        +	}
        +	
        +	errno = errCode;
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +
        +//	Close a connection
        +
        +OSErr MacSocket_close(const int inSocketNum)
        +{
        +OSErr			errCode = noErr;
        +SocketStruct	*theSocketStruct = nil;
        +
        +
        +	if (!SocketIndexIsValid(inSocketNum))
        +	{
        +		SetErrorMessageAndBail("MacSocket_close: Invalid socket number specified");
        +	}
        +
        +
        +	theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +	if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
        +	{
        +	OTResult		theOTResult = noErr;
        +	
        +		//	Try to play nice
        +		
        +		if (theSocketStruct->mReceivedTOrdRel)
        +		{
        +			//	Already did an OTRcvOrderlyDisconnect() in the notifier
        +		
        +			if (theSocketStruct->mLocalEndIsConnected)
        +			{
        +				theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
        +				
        +				theSocketStruct->mLocalEndIsConnected = false;
        +			}
        +		}
        +		
        +		else if (theSocketStruct->mLocalEndIsConnected)
        +		{
        +			theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
        +			
        +			theSocketStruct->mLocalEndIsConnected = false;
        +			
        +			//	Wait for other end to hang up too!
        +			
        +//			PrepareForAsyncOperation(theSocketStruct,T_ORDREL);
        +//
        +//			errCode = MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOrdRel));
        +		}
        +		
        +		
        +		if (theOTResult != noErr)
        +		{
        +			::OTCloseProvider(theSocketStruct->mEndPointRef);
        +		}
        +		
        +		else
        +		{
        +			theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
        +		}
        +
        +		theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
        +		
        +		errCode = theOTResult;
        +	}
        +
        +
        +	theSocketStruct->mIsInUse = false;
        +
        +	
        +EXITPOINT:
        +	
        +	if (theSocketStruct != nil)
        +	{
        +		theSocketStruct->mLastError = noErr;
        +		
        +		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +
        +		if (errCode != noErr)
        +		{
        +			theSocketStruct->mLastError = errCode;
        +			
        +			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +		}
        +	}
        +
        +	errno = errCode;
        +		
        +	return(errCode);
        +}
        +
        +
        +
        +
        +//	Receive some bytes
        +
        +int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock)
        +{
        +OSErr			errCode = noErr;
        +int				totalBytesRead = 0;
        +SocketStruct	*theSocketStruct = nil;
        +
        +	
        +	SetErrorMessageAndBailIfNil(outBuff,"MacSocket_recv: Bad parameter, outBuff = nil");
        +	
        +	if (outBuffLength <= 0)
        +	{
        +		SetErrorMessageAndBail("MacSocket_recv: Bad parameter, outBuffLength <= 0");
        +	}
        +	
        +	if (!SocketIndexIsValid(inSocketNum))
        +	{
        +		SetErrorMessageAndBail("MacSocket_recv: Invalid socket number specified");
        +	}
        +
        +	theSocketStruct = &(sSockets[inSocketNum]);
        +
        +	if (!theSocketStruct->mLocalEndIsConnected)
        +	{
        +		SetErrorMessageAndBail("MacSocket_recv: Socket not connected");
        +	}
        +
        +	if (theSocketStruct->mReceivedTOrdRel)
        +	{
        +		totalBytesRead = 0;
        +		
        +		goto EXITPOINT;
        +	}
        +
        +	
        +	PrepareForAsyncOperation(theSocketStruct,0);
        +	
        +	for (;;)
        +	{
        +	int			bytesRead;
        +	OTResult	theOTResult;
        +	
        +	
        +		theOTResult = ::OTRcv(theSocketStruct->mEndPointRef,(void *) ((unsigned long) outBuff + (unsigned long) totalBytesRead),outBuffLength - totalBytesRead,nil);
        +		
        +		if (theOTResult >= 0)
        +		{
        +			bytesRead = theOTResult;
        +			
        +#ifdef MACSOCKET_DEBUG
        +	printf("MacSocket_recv: read %d bytes in part\n",bytesRead);
        +#endif
        +		}
        +		
        +		else if (theOTResult == kOTNoDataErr)
        +		{
        +			bytesRead = 0;
        +		}
        +		
        +		else
        +		{
        +			SetErrorMessageAndLongIntAndBail("MacSocket_recv: Can't receive OT data, OTRcv() = ",theOTResult);
        +		}
        +		
        +		
        +		totalBytesRead += bytesRead;
        +		
        +		
        +		if (totalBytesRead <= 0)
        +		{
        +			if (theSocketStruct->mReceivedTOrdRel)
        +			{
        +				break;
        +			}
        +			
        +			//	This seems pretty stupid to me now.  Maybe I'll delete this blocking garbage.
        +			
        +			if (inBlock)
        +			{
        +				if (TimeoutElapsed(theSocketStruct))
        +				{
        +					SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_recv: Receive operation timed-out");
        +				}
        +				
        +				if (theSocketStruct->mIdleWaitCallback != nil)
        +				{
        +					theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
        +					
        +					SetErrorMessageAndBailIfError(theOTResult,"MacSocket_recv: User cancelled operation");
        +				}
        +				
        +				continue;
        +			}
        +		}
        +		
        +		
        +		break;
        +	}
        +	
        +	errCode = noErr;
        +
        +
        +#ifdef MACSOCKET_DEBUG
        +	printf("MacSocket_recv: read %d bytes in total\n",totalBytesRead);
        +#endif
        +	
        +	
        +EXITPOINT:
        +	
        +	if (theSocketStruct != nil)
        +	{
        +		theSocketStruct->mLastError = noErr;
        +		
        +		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +
        +		if (errCode != noErr)
        +		{
        +			theSocketStruct->mLastError = errCode;
        +			
        +			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +		}
        +	}
        +
        +	errno = errCode;
        +	
        +	return(totalBytesRead);
        +}
        +
        +
        +
        +//	Send some bytes
        +
        +int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength)
        +{
        +OSErr			errCode = noErr;
        +int				bytesSent = 0;
        +SocketStruct	*theSocketStruct = nil;
        +
        +
        +	SetErrorMessageAndBailIfNil(inBuff,"MacSocket_send: Bad parameter, inBuff = nil");
        +	
        +	if (inBuffLength <= 0)
        +	{
        +		SetErrorMessageAndBail("MacSocket_send: Bad parameter, inBuffLength <= 0");
        +	}
        +
        +	if (!SocketIndexIsValid(inSocketNum))
        +	{
        +		SetErrorMessageAndBail("MacSocket_send: Invalid socket number specified");
        +	}
        +	
        +
        +	theSocketStruct = &(sSockets[inSocketNum]);
        +	
        +	if (!theSocketStruct->mLocalEndIsConnected)
        +	{
        +		SetErrorMessageAndBail("MacSocket_send: Socket not connected");
        +	}
        +
        +
        +OTResult		theOTResult;
        +	
        +
        +	PrepareForAsyncOperation(theSocketStruct,0);
        +
        +	while (bytesSent < inBuffLength)
        +	{
        +		if (theSocketStruct->mIdleWaitCallback != nil)
        +		{
        +			theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
        +			
        +			SetErrorMessageAndBailIfError(theOTResult,"MacSocket_send: User cancelled");
        +		}
        +
        +
        +		theOTResult = ::OTSnd(theSocketStruct->mEndPointRef,(void *) ((unsigned long) inBuff + bytesSent),inBuffLength - bytesSent,0);
        +		
        +		if (theOTResult >= 0)
        +		{
        +			bytesSent += theOTResult;
        +			
        +			theOTResult = noErr;
        +			
        +			//	Reset timer....
        +			
        +			PrepareForAsyncOperation(theSocketStruct,0);
        +		}
        +		
        +		if (theOTResult == kOTFlowErr)
        +		{
        +			if (TimeoutElapsed(theSocketStruct))
        +			{
        +				SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_send: Send timed-out")
        +			}
        +
        +			theOTResult = noErr;
        +		}
        +													
        +		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_send: Can't send OT data, OTSnd() = ",theOTResult);
        +	}
        +
        +	
        +	errCode = noErr;
        +
        +#ifdef MACSOCKET_DEBUG
        +	printf("MacSocket_send: sent %d bytes\n",bytesSent);
        +#endif
        +	
        +	
        +EXITPOINT:
        +	
        +	if (theSocketStruct != nil)
        +	{
        +		theSocketStruct->mLastError = noErr;
        +		
        +		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +
        +		if (errCode != noErr)
        +		{
        +			theSocketStruct->mLastError = errCode;
        +			
        +			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
        +		}
        +	}
        +	
        +	if (errCode != noErr)
        +	{
        +		::SysBeep(1);
        +	}
        +	
        +	errno = errCode;
        +	
        +	return(bytesSent);
        +}
        +
        +
        +
        +
        +
        +static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)
        +{
        +OSStatus	errCode;
        +UInt8		buf[kOTFourByteOptionSize];
        +TOption*	theOTOption;
        +TOptMgmt	theOTRequest;
        +TOptMgmt	theOTResult;
        +	
        +
        +	if (!OTIsSynchronous(inEndpoint))
        +	{
        +		SetErrorMessageAndBail("NegotiateIPReuseAddrOption: Open Transport endpoint is not synchronous");
        +	}
        +	
        +	theOTRequest.opt.buf = buf;
        +	theOTRequest.opt.len = sizeof(buf);
        +	theOTRequest.flags = T_NEGOTIATE;
        +
        +	theOTResult.opt.buf = buf;
        +	theOTResult.opt.maxlen = kOTFourByteOptionSize;
        +
        +
        +	theOTOption = (TOption *) buf;
        +	
        +	theOTOption->level = INET_IP;
        +	theOTOption->name = IP_REUSEADDR;
        +	theOTOption->len = kOTFourByteOptionSize;
        +	theOTOption->status = 0;
        +	*((UInt32 *) (theOTOption->value)) = inEnableReuseIP;
        +
        +	errCode = ::OTOptionManagement(inEndpoint,&theOTRequest,&theOTResult);
        +	
        +	if (errCode == kOTNoError)
        +	{
        +		if (theOTOption->status != T_SUCCESS)
        +		{
        +			errCode = theOTOption->status;
        +		}
        +		
        +		else
        +		{
        +			errCode = kOTNoError;
        +		}
        +	}
        +				
        +
        +EXITPOINT:
        +	
        +	errno = errCode;
        +	
        +	return(errCode);
        +}
        +
        +
        +
        +
        +
        +//	Some rough notes....
        +
        +
        +
        +//	OTAckSends(ep);
        +//	OTAckSends(ep) // enable AckSend option
        +//	......
        +//	buf = OTAllocMem( nbytes); // Allocate nbytes of memory from OT
        +//	OTSnd(ep, buf, nbytes, 0); // send a packet
        +//	......
        +//	NotifyProc( .... void* theParam) // Notifier Proc
        +//	case T_MEMORYRELEASED: // process event
        +//	OTFreeMem( theParam); // free up memory
        +//	break;
        +
        +
        +
        +/*
        +struct InetInterfaceInfo
        +{
        +	InetHost		fAddress;
        +	InetHost		fNetmask;
        +	InetHost		fBroadcastAddr;
        +	InetHost		fDefaultGatewayAddr;
        +	InetHost		fDNSAddr;
        +	UInt16			fVersion;
        +	UInt16			fHWAddrLen;
        +	UInt8*			fHWAddr;
        +	UInt32			fIfMTU;
        +	UInt8*			fReservedPtrs[2];
        +	InetDomainName	fDomainName;
        +	UInt32			fIPSecondaryCount;
        +	UInt8			fReserved[252];			
        +};
        +typedef struct InetInterfaceInfo InetInterfaceInfo;
        +
        +
        +
        +((InetAddress *) addr.buf)->fHost
        +
        +struct TBind
        +{
        +	TNetbuf	addr;
        +	OTQLen	qlen;
        +};
        +
        +typedef struct TBind	TBind;
        +
        +struct TNetbuf
        +{
        +	size_t	maxlen;
        +	size_t	len;
        +	UInt8*	buf;
        +};
        +
        +typedef struct TNetbuf	TNetbuf;
        +
        +	
        +	struct InetAddress
        +{
        +		OTAddressType	fAddressType;	// always AF_INET
        +		InetPort		fPort;			// Port number 
        +		InetHost		fHost;			// Host address in net byte order
        +		UInt8			fUnused[8];		// Traditional unused bytes
        +};
        +typedef struct InetAddress InetAddress;
        +*/
        +
        +
        +
        +/*
        +static pascal void Notifier(void* context, OTEventCode event, OTResult result, void* cookie)
        +{
        +EPInfo* epi = (EPInfo*) context;
        +
        +	switch (event)
        +	{
        +		case T_LISTEN:
        +		{
        +			DoListenAccept();
        +			return;
        +		}
        +		
        +		case T_ACCEPTCOMPLETE:
        +		{
        +			if (result != kOTNoError)
        +				DBAlert1("Notifier: T_ACCEPTCOMPLETE - result %d",result);
        +			return;
        +		}
        +		
        +		case T_PASSCON:
        +		{
        +			if (result != kOTNoError)
        +			{
        +				DBAlert1("Notifier: T_PASSCON result %d", result);
        +				return;
        +			}
        +
        +			OTAtomicAdd32(1, &gCntrConnections);
        +			OTAtomicAdd32(1, &gCntrTotalConnections);
        +			OTAtomicAdd32(1, &gCntrIntervalConnects);
        +			
        +			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
        +			{
        +				ReadData(epi);
        +			}
        +			
        +			return;
        +		}
        +		
        +		case T_DATA:
        +		{
        +			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
        +			{
        +				ReadData(epi);
        +			}
        +			
        +			return;
        +		}
        +		
        +		case T_GODATA:
        +		{
        +			SendData(epi);
        +			return;
        +		}
        +		
        +		case T_DISCONNECT:
        +		{
        +			DoRcvDisconnect(epi);
        +			return;
        +		}
        +		
        +		case T_DISCONNECTCOMPLETE:
        +		{
        +			if (result != kOTNoError)
        +				DBAlert1("Notifier: T_DISCONNECT_COMPLETE result %d",result);
        +				
        +			return;
        +		}
        +		
        +		case T_MEMORYRELEASED:
        +		{
        +			OTAtomicAdd32(-1, &epi->outstandingSends);
        +			return;
        +		}
        +		
        +		default:
        +		{
        +			DBAlert1("Notifier: unknown event <%x>", event);
        +			return;
        +		}
        +	}
        +}
        +*/
        diff --git a/vendor/openssl/openssl/MacOS/GetHTTPS.src/MacSocket.h b/vendor/openssl/openssl/MacOS/GetHTTPS.src/MacSocket.h
        new file mode 100644
        index 000000000..ad59dc9e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/GetHTTPS.src/MacSocket.h
        @@ -0,0 +1,103 @@
        +#pragma once
        +
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +
        +enum
        +{
        +	kMacSocket_TimeoutErr = -2
        +};
        +
        +
        +//	Since MacSocket does busy waiting, I do a callback while waiting
        +
        +typedef OSErr (*MacSocket_IdleWaitCallback)(void *);
        +
        +
        +//	Call this before anything else!
        +
        +OSErr MacSocket_Startup(void);
        +
        +
        +//	Call this to cleanup before quitting
        +
        +OSErr MacSocket_Shutdown(void);
        +
        +
        +//	Call this to allocate a "socket" (reference number is returned in outSocketNum)
        +//	Note that inDoThreadSwitching is pretty much irrelevant right now, since I ignore it
        +//	The inTimeoutTicks parameter is applied during reads/writes of data
        +//	The inIdleWaitCallback parameter specifies a callback which is called during busy-waiting periods
        +//	The inUserRefPtr parameter is passed back to the idle-wait callback
        +
        +OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr);
        +
        +
        +//	Call this to connect to an IP/DNS address
        +//	Note that inTargetAddressAndPort is in "IP:port" format-- e.g. 10.1.1.1:123
        +
        +OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort);
        +
        +
        +//	Call this to listen on a port
        +//	Since this a low-performance implementation, I allow a maximum of 1 (one!) incoming request when I listen
        +
        +OSErr MacSocket_listen(const int inSocketNum,const int inPortNum);
        +
        +
        +//	Call this to close a socket
        +
        +OSErr MacSocket_close(const int inSocketNum);
        +
        +
        +//	Call this to receive data on a socket
        +//	Most parameters' purpose are obvious-- except maybe "inBlock" which controls whether I wait for data or return immediately
        +
        +int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock);
        +
        +
        +//	Call this to send data on a socket
        +
        +int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength);
        +
        +
        +//	If zero bytes were read in a call to MacSocket_recv(), it may be that the remote end has done a half-close
        +//	This function will let you check whether that's true or not
        +
        +Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum);
        +
        +
        +//	Call this to see if the listen has completed after a call to MacSocket_listen()
        +
        +Boolean MacSocket_ListenCompleted(const int inSocketNum);
        +
        +
        +//	These really aren't very useful anymore
        +
        +Boolean MacSocket_LocalEndIsOpen(const int inSocketNum);
        +Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum);
        +
        +
        +//	You may wish to change the userRefPtr for a socket callback-- use this to do it
        +
        +void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr);
        +
        +
        +//	Call these to get the socket's IP:port descriptor
        +
        +void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength);
        +void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength);
        +
        +
        +//	Call this to get error info from a socket
        +
        +void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength);
        +
        +
        +#ifdef __cplusplus
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/MacOS/OpenSSL.mcp.hqx b/vendor/openssl/openssl/MacOS/OpenSSL.mcp.hqx
        new file mode 100644
        index 000000000..c357ea5af
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/OpenSSL.mcp.hqx
        @@ -0,0 +1,4940 @@
        +(This file must be converted with BinHex 4.0)
        +
        +:#dp`C@j68d`ZE@0`!%e08(*$9dP&!!!!!jeU!!!!!0U2Bfp[E!!!!!-!!!%S!!1
        +%3J!$K@S!!"J!!!!"!!%#!3!!!!!!!!!!!%0[C'9ABA*bD@pb)&"bEfTPBh3!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"(CA4)9&4
        +38b"38%-k4'9LG@GRCA)J8R9ZG'PYC3"(CA4)9&438b"38%-k8fpeFQ0P)&4bC@9
        +c!%GPG%K89&"6)&"33cT$GA0dEfdJ5f9jGfpbC(-!4f9d5&488&-J8&"$1N&MBf9
        +cFb"3BA4SF`"(CA4)9&438b"38%-k9'&bCf9d)&0PG(4TEQGc!%GPG%K89&"6)&"
        +33cT'D@aP)%eKF("TEQGc!%GPG%K89&"6)&"33cT#G@PXC#"&H(4bBA-!4f9d5&4
        +88&-J8&"$1N4PBR9RCf9b)&4KFQGPG!"(CA4)9&438b"38%-k0MK,)%0[C'9(C@i
        +!4f9d5&488&-J8&"$1MBi5b"%DA0KFh0PE@*XCA)!4f9d5&488&-J8&"$1MBi5b"
        +(E'pLB@`J6h"dD@eTHQ9b!%GPG%K89&"6)&"33cSf1%XJ6'PZDf9b!%GPG%K89&"
        +6)&"33cSf1%XJ8(*[DQ9MG!"(CA4)9&438b"38%-k3bp$+bXJ3fpYF'PXCA)!4f9
        +d5&488&-J8&"$1N-[3bXV)&GKFQjTEQGc!%GPG%K89&"6)&"33cT$4Ndf1%X!4f9
        +d5&488&-J8&"$1NeKBdp6)%ePFQGP)&"KEQ9X!%GPG%K89&"6)&"33cT38%-J3fp
        +NC8GPEJ"(CA4)9&438b"38%-k8&"$)%4TFf&cFf9YBQaPFJ"(CA4)9&438b"38%-
        +k8&"$)%GXEf*KE#"2F(4TE@PkCA)!4f9d5&488&-J8&"$1P"33b"-D@jVCA)!4f9
        +d5&488&-J8&"$1P"33b"348B!4f9d5&488&-J8&"$1P"33b"3FQpUC@0d!%GPG%K
        +89&"6)&"33cT38%0"FfdJ8'&ZC@`!4f9d5&488&-J8&"$1P*PHL"$Efe`D@aPFJ"
        +2F'9Z8e0-)&"33cT%C@*eCfGPFL"5G@jdD@eP!%p`C@j68d`J8&"$1P0[GA*MC5"
        +8FQ9PF`"2F'9Z8e0-)&"33cT$GA0dEfdJ5f9jGfpbC(-!6h"PEP066#"38%-k3@0
        +MCA0c)&"KG'Kc!%p`C@j68d`J8&"$1P4KFQGPG#"6CA4dD@jRF`"2F'9Z8e0-)&"
        +33cT'D@aP)%eKF("TEQGc!%p`C@j68d`J8&"$1N*eD@aN)%9iG(*KF`"2F'9Z8e0
        +-)&"33cT%C@*eCfGPFL"8BA*RCA3!6h"PEP066#"38%-k0MK,)%0[C'9(C@i!6h"
        +PEP066#"38%-k0MK,)%4TFf&cFf9YBQaPFJ"2F'9Z8e0-)&"33cSf1%XJ4fa[BQ&
        +X)%p`G'PYDATPFJ"2F'9Z8e0-)&"33cSf1%XJ6'PZDf9b!%p`C@j68d`J8&"$1MB
        +i5b"3FQpUC@0d!%p`C@j68d`J8&"$1N-[3bXV)%0[EA"TE'9b!%p`C@j68d`J8&"
        +$1N-[3bXV)&GKFQjTEQGc!%p`C@j68d`J8&"$1N0'66Bi5`"2F'9Z8e0-)&"33cT
        +0B@028b"0CA*RC5"3B@jPE!"2F'9Z8e0-)&"33cT38%-J3fpNC8GPEJ"2F'9Z8e0
        +-)&"33cT38%-J4'PcBA0cC@eLE'9b!%p`C@j68d`J8&"$1P"33b"(E'pLB@`J6h"
        +dD@eTHQ9b!%p`C@j68d`J8&"$1P"33b"-D@jVCA)!6h"PEP066#"38%-k8&"$)&"
        +&4J"2F'9Z8e0-)&"33cT38%-J8(*[DQ9MG!"2F'9Z8e0-)&"33cT38%0"FfdJ8'&
        +ZC@`!6h"PEP066#"38%-k8Q9k)%0[EA"TE'9b!%GPG%K89&"6)$Bi5cT%C@*eCfG
        +PFL"5G@jdD@eP!%GPG%K89&"6)$Bi5cT6Eh9bBf8J9(*PCA-!4f9d5&488&-J0MK
        +,1N0eFh4[E5",CAPhEh*NF`"(CA4)9&438b!f1%Xk3@0MCA0c)&"KG'Kc!%GPG%K
        +89&"6)$Bi5cT8BA*RCA3J8f9dG'PZCh-!4f9d5&488&-J0MK,1NCTE'8J6@&`F'P
        +ZCh-!4f9d5&488&-J0MK,1N*eD@aN)%9iG(*KF`"(CA4)9&438b!f1%Xk4'9LG@G
        +RCA)J9'&bCf9d!%GPG%K89&"6)$Bi5cSf1%XJ3fpNC8GPEJ"(CA4)9&438b!f1%X
        +k0MK,)%4TFf&cFf9YBQaPFJ"(CA4)9&438b!f1%Xk0MK,)%GXEf*KE#"2F(4TE@P
        +kCA)!4f9d5&488&-J0MK,1MBi5b"-D@jVCA)!4f9d5&488&-J0MK,1MBi5b"3FQp
        +UC@0d!%GPG%K89&"6)$Bi5cT$,d-V+b"$Efe`D@aPFJ"(CA4)9&438b!f1%Xk3bp
        +$+bXJ9f&bEQPZCh-!4f9d5&488&-J0MK,1N0'66Bi5`"(CA4)9&438b!f1%Xk6@&
        +M6e-J6@9bCf8J8'&ZC@`!4f9d5&488&-J0MK,1P"33b"$Ef4P4f9Z!%GPG%K89&"
        +6)$Bi5cT38%-J4'PcBA0cC@eLE'9b!%GPG%K89&"6)$Bi5cT38%-J4fa[BQ&X)%p
        +`G'PYDATPFJ"(CA4)9&438b!f1%Xk8&"$)%aTEQYPFJ"(CA4)9&438b!f1%Xk8&"
        +$)&"&4J"(CA4)9&438b!f1%Xk8&"$)&"bEfTPBh3!4f9d5&488&-J0MK,1P"33d&
        +cE5"3B@jPE!"(CA4)9&438b!f1%Xk8Q9k)%0[EA"TE'9b!%aTBP066#!f1%Xk4'9
        +LG@GRCA)J8R9ZG'PYC3"-D@*68d`J0MK,1P0[GA*MC5"8FQ9PF`"-D@*68d`J0MK
        +,1N0eFh4[E5",CAPhEh*NF`"-D@*68d`J0MK,1N&MBf9cFb"3BA4SF`"-D@*68d`
        +J0MK,1P4KFQGPG#"6CA4dD@jRF`"-D@*68d`J0MK,1NCTE'8J6@&`F'PZCh-!6'P
        +L8e0-)$Bi5cT#G@PXC#"&H(4bBA-!6'PL8e0-)$Bi5cT%C@*eCfGPFL"8BA*RCA3
        +!6'PL8e0-)$Bi5cSf1%XJ3fpNC8GPEJ"-D@*68d`J0MK,1MBi5b"%DA0KFh0PE@*
        +XCA)!6'PL8e0-)$Bi5cSf1%XJ4fa[BQ&X)%p`G'PYDATPFJ"-D@*68d`J0MK,1MB
        +i5b"-D@jVCA)!6'PL8e0-)$Bi5cSf1%XJ8(*[DQ9MG!"-D@*68d`J0MK,1N-[3bX
        +V)%0[EA"TE'9b!%aTBP066#!f1%Xk3bp$+bXJ9f&bEQPZCh-!6'PL8e0-)$Bi5cT
        +$4Ndf1%X!6'PL8e0-)$Bi5cT0B@028b"0CA*RC5"3B@jPE!"-D@*68d`J0MK,1P"
        +33b"$Ef4P4f9Z!%aTBP066#!f1%Xk8&"$)%4TFf&cFf9YBQaPFJ"-D@*68d`J0MK
        +,1P"33b"(E'pLB@`J6h"dD@eTHQ9b!%aTBP066#!f1%Xk8&"$)%aTEQYPFJ"-D@*
        +68d`J0MK,1P"33b"348B!6'PL8e0-)$Bi5cT38%-J8(*[DQ9MG!"-D@*68d`J0MK
        +,1P"33d&cE5"3B@jPE!"-D@*68d`J0MK,1P*PHL"$Efe`D@aPFJ"2F'9Z8e0-)$B
        +iDcT%C@*eCfGPFL"5G@jdD@eP!%p`C@j68d`J0MKV1P0[GA*MC5"8FQ9PF`"2F'9
        +Z8e0-)$BiDcT$GA0dEfdJ5f9jGfpbC(-!6h"PEP066#!f1'Xk3@0MCA0c)&"KG'K
        +c!%p`C@j68d`J0MKV1P4KFQGPG#"6CA4dD@jRF`"2F'9Z8e0-)$BiDcT'D@aP)%e
        +KF("TEQGc!%p`C@j68d`J0MKV1N*eD@aN)%9iG(*KF`"2F'9Z8e0-)$BiDcT%C@*
        +eCfGPFL"8BA*RCA3!6h"PEP066#!f1'Xk0MK,)%0[C'9(C@i!6h"PEP066#!f1'X
        +k0MK,)%4TFf&cFf9YBQaPFJ"2F'9Z8e0-)$BiDcSf1%XJ4fa[BQ&X)%p`G'PYDAT
        +PFJ"2F'9Z8e0-)$BiDcSf1%XJ6'PZDf9b!%p`C@j68d`J0MKV1MBi5b"3FQpUC@0
        +d!%p`C@j68d`J0MKV1N-[3bXV)%0[EA"TE'9b!%p`C@j68d`J0MKV1N-[3bXV)&G
        +KFQjTEQGc!%p`C@j68d`J0MKV1N0'66Bi5`"2F'9Z8e0-)$BiDcT0B@028b"0CA*
        +RC5"3B@jPE!"2F'9Z8e0-)$BiDcT38%-J3fpNC8GPEJ"2F'9Z8e0-)$BiDcT38%-
        +J4'PcBA0cC@eLE'9b!%p`C@j68d`J0MKV1P"33b"(E'pLB@`J6h"dD@eTHQ9b!%p
        +`C@j68d`J0MKV1P"33b"-D@jVCA)!6h"PEP066#!f1'Xk8&"$)&"&4J"2F'9Z8e0
        +-)$BiDcT38%-J8(*[DQ9MG!"2F'9Z8e0-)$BiDcT38%0"FfdJ8'&ZC@`!6h"PEP0
        +66#!f1'Xk8Q9k)%0[EA"TE'9b!%aTBP066#"38%-k4'9LG@GRCA)J8R9ZG'PYC3"
        +-D@*68d`J8&"$1P0[GA*MC5"8FQ9PF`"-D@*68d`J8&"$1N0eFh4[E5",CAPhEh*
        +NF`"-D@*68d`J8&"$1N&MBf9cFb"3BA4SF`"-D@*68d`J8&"$1P4KFQGPG#"6CA4
        +dD@jRF`"-D@*68d`J8&"$1NCTE'8J6@&`F'PZCh-!6'PL8e0-)&"33cT#G@PXC#"
        +&H(4bBA-!6'PL8e0-)&"33cT%C@*eCfGPFL"8BA*RCA3!6'PL8e0-)&"33cSf1%X
        +J3fpNC8GPEJ"-D@*68d`J8&"$1MBi5b"%DA0KFh0PE@*XCA)!6'PL8e0-)&"33cS
        +f1%XJ4fa[BQ&X)%p`G'PYDATPFJ"-D@*68d`J8&"$1MBi5b"-D@jVCA)!6'PL8e0
        +-)&"33cSf1%XJ8(*[DQ9MG!"-D@*68d`J8&"$1N-[3bXV)%0[EA"TE'9b!%aTBP0
        +66#"38%-k3bp$+bXJ9f&bEQPZCh-!6'PL8e0-)&"33cT$4Ndf1%X!6'PL8e0-)&"
        +33cT0B@028b"0CA*RC5"3B@jPE!"-D@*68d`J8&"$1P"33b"$Ef4P4f9Z!%aTBP0
        +66#"38%-k8&"$)%4TFf&cFf9YBQaPFJ"-D@*68d`J8&"$1P"33b"(E'pLB@`J6h"
        +dD@eTHQ9b!%aTBP066#"38%-k8&"$)%aTEQYPFJ"-D@*68d`J8&"$1P"33b"348B
        +!6'PL8e0-)&"33cT38%-J8(*[DQ9MG!"-D@*68d`J8&"$1P"33d&cE5"3B@jPE!"
        +-D@*68d`J8&"$1P*PHL"$Efe`D@aPFJ"-D@*$FRP`G'mJ8&"$1N4PBR9RCf9b)&*
        +eER4TE@8!6'PL3h*jF(4[)&"33cT6Eh9bBf8J9(*PCA-!6'PL3h*jF(4[)&"33cT
        +$GA0dEfdJ5f9jGfpbC(-!6'PL3h*jF(4[)&"33cT"Bf0PFh-J8'&dD(-!6'PL3h*
        +jF(4[)&"33cT8BA*RCA3J8f9dG'PZCh-!6'PL3h*jF(4[)&"33cT'D@aP)%eKF("
        +TEQGc!%aTBN0bHA"dEb"38%-k3R9TE'3J4AKdFQ&c!%aTBN0bHA"dEb"38%-k4'9
        +LG@GRCA)J9'&bCf9d!%aTBN0bHA"dEb"38%-k0MK,)%0[C'9(C@i!6'PL3h*jF(4
        +[)&"33cSf1%XJ4'PcBA0cC@eLE'9b!%aTBN0bHA"dEb"38%-k0MK,)%GXEf*KE#"
        +2F(4TE@PkCA)!6'PL3h*jF(4[)&"33cSf1%XJ6'PZDf9b!%aTBN0bHA"dEb"38%-
        +k0MK,)&"bEfTPBh3!6'PL3h*jF(4[)&"33cT$,d-V+b"$Efe`D@aPFJ"-D@*$FRP
        +`G'mJ8&"$1N-[3bXV)&GKFQjTEQGc!%aTBN0bHA"dEb"38%-k3dC00MK,!%aTBN0
        +bHA"dEb"38%-k6@&M6e-J6@9bCf8J8'&ZC@`!6'PL3h*jF(4[)&"33cT38%-J3fp
        +NC8GPEJ"-D@*$FRP`G'mJ8&"$1P"33b"%DA0KFh0PE@*XCA)!6'PL3h*jF(4[)&"
        +33cT38%-J4fa[BQ&X)%p`G'PYDATPFJ"-D@*$FRP`G'mJ8&"$1P"33b"-D@jVCA)
        +!6'PL3h*jF(4[)&"33cT38%-J8%9'!%aTBN0bHA"dEb"38%-k8&"$)&"bEfTPBh3
        +!6'PL3h*jF(4[)&"33cT38%0"FfdJ8'&ZC@`!6'PL3h*jF(4[)&"33cT5CASJ3fp
        +YF'PXCA)!6'PL3h*jF(4[)$Bi5cT%C@*eCfGPFL"5G@jdD@eP!%aTBN0bHA"dEb!
        +f1%Xk8fpeFQ0P)&4bC@9c!%aTBN0bHA"dEb!f1%Xk3h9cG'pY)%YPHAG[FQ4c!%a
        +TBN0bHA"dEb!f1%Xk3@0MCA0c)&"KG'Kc!%aTBN0bHA"dEb!f1%Xk9'&bCf9d)&0
        +PG(4TEQGc!%aTBN0bHA"dEb!f1%Xk4QPXC5"0BA"`D@jRF`"-D@*$FRP`G'mJ0MK
        +,1N*eD@aN)%9iG(*KF`"-D@*$FRP`G'mJ0MK,1N4PBR9RCf9b)&4KFQGPG!"-D@*
        +$FRP`G'mJ0MK,1MBi5b"$Ef4P4f9Z!%aTBN0bHA"dEb!f1%Xk0MK,)%4TFf&cFf9
        +YBQaPFJ"-D@*$FRP`G'mJ0MK,1MBi5b"(E'pLB@`J6h"dD@eTHQ9b!%aTBN0bHA"
        +dEb!f1%Xk0MK,)%aTEQYPFJ"-D@*$FRP`G'mJ0MK,1MBi5b"3FQpUC@0d!%aTBN0
        +bHA"dEb!f1%Xk3bp$+bXJ3fpYF'PXCA)!6'PL3h*jF(4[)$Bi5cT$,d-V+b"ABA*
        +ZD@jRF`"-D@*$FRP`G'mJ0MK,1N0'66Bi5`"-D@*$FRP`G'mJ0MK,1NeKBdp6)%e
        +PFQGP)&"KEQ9X!%aTBN0bHA"dEb!f1%Xk8&"$)%0[C'9(C@i!6'PL3h*jF(4[)$B
        +i5cT38%-J4'PcBA0cC@eLE'9b!%aTBN0bHA"dEb!f1%Xk8&"$)%GXEf*KE#"2F(4
        +TE@PkCA)!6'PL3h*jF(4[)$Bi5cT38%-J6'PZDf9b!%aTBN0bHA"dEb!f1%Xk8&"
        +$)&"&4J"-D@*$FRP`G'mJ0MK,1P"33b"3FQpUC@0d!%aTBN0bHA"dEb!f1%Xk8&"
        +$3A0Y)&"KEQ9X!%aTBN0bHA"dEb!f1%Xk8Q9k)%0[EA"TE'9b!&"bEfTPBh3J4QP
        +XC5"-DA0d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!H!!!!!J!!!!!!!!!i!!!!!`!!!!!!!!"9!!!!"!!!!!!!!!"[!!!
        +!"3!!!!!!!!#-!!!!"J!!!!!!!!#R!!!!"`!!!!!!!!$"!!!!#!!!!!!!!!$H!!!
        +!#3!!!!!!!!$h!!!!#J!!!!!!!!%9!!!!#`!!!!!!!!%h!!!!$!!!!!!!!!&2!!!
        +!$3!!!!!!!!&S!!!!$J!!!!!!!!'%!!!!$`!!!!!!!!'J!!!!%!!!!!!!!!'d!!!
        +!%3!!!!!!!!(6!!!!%J!!!!!!!!(X!!!!%`!!!!!!!!)+!!!!&!!!!!!!!!)X!!!
        +!&3!!!!!!!!*%!!!!&J!!!!!!!!*C!!!!&`!!!!!!!!*b!!!!'!!!!!!!!!+-!!!
        +!'3!!!!!!!!+Q!!!!'J!!!!!!!!,$!!!!'`!!!!!!!!,F!!!!(!!!!!!!!!,i!!!
        +!(3!!!!!!!!-4!!!!(J!!!!!!!!-Y!!!!(`!!!!!!!!0(!!!!)!!!!!!!!!0J!!!
        +!)3!!!!!!!!0m!!!!)J!!!!!!!!18!!!!)`!!!!!!!!1a!!!!*!!!!!!!!!25!!!
        +!*3!!!!!!!!2T!!!!*J!!!!!!!!3"!!!!*`!!!!!!!!3F!!!!+!!!!!!!!!3h!!!
        +!+3!!!!!!!!4+!!!!+J!!!!!!!!4S!!!!+`!!!!!!!!5!!!!!,!!!!!!!!!5G!!!
        +!,3!!!!!!!!5q!!!!,J!!!!!!!!69!!!!,`!!!!!!!!6T!!!!-!!!!!!!!!8"!!!
        +!-3!!!!!!!!8D!!!!-J!!!!!!!!8c!!!!-`!!!!!!!!94!!!!0!!!!!!!!!9V!!!
        +!03!!!!!!!!@)!!!!0J!!!!!!!!@L!!!!0`!!!!!!!!@r!!!!1!!!!!!!!!AD!!!
        +!13!!!!!!!!Ad!!!!1J!!!!!!!!B4!!!!1`!!!!!!!!BU!!!!2!!!!!!!!!C)!!!
        +!23!!!!!!!!CU!!!!2J!!!!!!!!D#!!!!2`!!!!!!!!DE!!!!3!!!!!!!!!Dh!!!
        +!33!!!!!!!!E6!!!!3J!!!!!!!!ER!!!!3`!!!!!!!!F'!!!!4!!!!!!!!!FI!!!
        +!43!!!!!!!!Fp!!!!4J!!!!!!!!GI!!!!4`!!!!!!!!Gh!!!!5!!!!!!!!!H-!!!
        +!53!!!!!!!!HP!!!!5J!!!!!!!!Hr!!!!5`!!!!!!!!IC!!!!6!!!!!!!!!Ie!!!
        +!63!!!!!!!!J0!!!!6J!!!!!!!!JS!!!!6`!!!!!!!!K!!!!!8!!!!!!!!!KE!!!
        +!83!!!!!!!!Kd!!!!8J!!!!!!!!L-!!!!8`!!!!!!!!LR!!!!9!!!!!!!!!Lq!!!
        +!93!!!!!!!!MD!!!!9J!!!!!!!!Mk!!!!9`!!!!!!!!N3!!!!@!!!!!!!!!NR!!!
        +!@3!!!!!!!!P"!!!!@J!!!!!!!!PE!!!!@`!!!!!!!!PY!!!!A!!!!!!!!!Q+!!!
        +!A3!!!!!!!!QK!!!!AJ!!!!!!!!Qp!!!!A`!!!!!!!!RG!!!!B!!!!!!!!!Rc!!!
        +!B3!!!!!!!!S'!!!!BJ!!!!!!!!SG!!!!B`!!!!!!!!Se!!!!C!!!!!!!!!T0!!!
        +!C3!!!!!!!!TU!!!!CJ!!!!!!!!U$!!!!C`!!!!!!!!UI!!!!D!!!!!!!!!Ui!!!
        +!D3!!!!!!!!V8!!!!DJ!!!!!!!!VZ!!!!D`!!!!!!!!X(!!!!E!!!!!!!!!XM!!!
        +!E3!!!!!!!!Xl!!!!EJ!!!!!!!!YB!!!!E`!!!!!!!!Yj!!!!F!!!!!!!!!Z3!!!
        +!!(%!!!!!!!!,U!!!!()!!!!!!!!,``!!!(-!!!!!!!!,hJ!!!(3!!!!!!!!,m3!
        +!!(8!!!!!!!!-$`!!!(B!!!!!!!!-*`!!!(F!!!!!!!!-4!!!!(J!!!!!!!!-C3!
        +!!(N!!!!!!!!-I!!!!(S!!!!!!!!-N!!!!!"l!!!!!!!!$+J!!!"m!!!!!!!!$-%
        +!!!"p!!!!!!!!$0S!!!"q!!!!!!!!$2B!!!"r!!!!!!!!$3i!!!#!!!!!!!!!$5N
        +!!!#"!!!!!!!!$8%!!!##!!!!!!!!$9`!!!#$!!!!!!!!$A8!!!#%!!!!!!!!$Bd
        +!!!#&!!!!!!!!$DJ!!!#'!!!!!!!!$Em!!!#(!!!!!!!!$GX!!!#)!!!!!!!!$IX
        +!!!#*!!!!!!!!$K%!!!#+!!!!!!!!$LJ!!!#,!!!!!!!!$N)!!!#-!!!!!!!!$P`
        +!!!#0!!!!!!!!$Qi!!!#1!!!!!!!!$SX!!!#2!!!!!!!!$U)!!!#3!!!!!!!!!!k
        +q!!!!N3!!!!!!!!lH!!!!NJ!!!!!!!!ld!!!!N`!!!!!!!!m(!!!!P!!!!!!!!!m
        +H!!!!P3!!!!!!!!mf!!!!PJ!!!!!!!!p1!!!!P`!!!!!!!!pY!!!!Q!!!!!!!!!q
        +)!!!!Q3!!!!!!!!qQ!!!!QJ!!!!!!!!r"!!!!Q`!!!!!!!!rI!!!!R!!!!!!!!!r
        +l!!!!R3!!!!!!!"!@!!!!RJ!!!!!!!"!d!!!!R`!!!!!!!""1!!!!S!!!!!!!!""
        +Y!!!!S3!!!!!!!"#3!!!!!+)!!!!!!!!3U3!!!+-!!!!!!!!3``!!!+3!!!!!!!!
        +3i!!!!+8!!!!!!!!3r3!!!+B!!!!!!!!4%J!!!+F!!!!!!!!4-J!!!+J!!!!!!!!
        +46!!!!+N!!!!!!!!4D`!!!+S!!!!!!!!4MJ!!!+X!!!!!!!!4T`!!!+`!!!!!!!!
        +4[3!!!+d!!!!!!!!4e`!!!+i!!!!!!!!4mJ!!!+m!!!!!!!!5$3!!!,!!!!!!!!!
        +5,!!!!,%!!!!!!!!54`!!!,)!!!!!!!!5C3!!!,-!!!!!!!!5J!!!!,3!!!!!!!!
        +5RJ!!!,8!!!!!!!!5ZJ!!!,B!!!!!!!!5e3!!!,F!!!!!!!!5m`!!!,J!!!!!!!!
        +6$3!!!,N!!!!!!!!6,!!!!,S!!!!!!!!66`!!!,X!!!!!!!!6D!!!!,`!!!!!!!!
        +6JJ!!!,d!!!!!!!!6R`!!!,i!!!!!!!!6[!!!!,m!!!!!!!!6d3!!!-!!!!!!!!!
        +6m3!!!-%!!!!!!!!8#`!!!-)!!!!!!!!8+J!!!--!!!!!!!!863!!!-3!!!!!!!!
        +8CJ!!!-8!!!!!!!!8I!!!!-B!!!!!!!!8PJ!!!-F!!!!!!!!8X3!!!-J!!!!!!!!
        +8c!!!!-N!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!1J!!!$X!!!!m!!!!23!!!$i!!!!e!!!!1!!!!$m!!!"!!!!!33!!!$3!!!!b!!!
        +!13!!!$F!!!"#!!!!3`!!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S!!!!c!!!
        +!0J!!!!J!!!!*!!!!#J!!!!X!!!!-!!!!!`!!!!B!!!!0!!!!$J!!!!m!!!!#!!!
        +!!!!!!!F!!!!&!!!!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!
        +!!3!!!!3!!!#h!!!!Z!!!!,N!!!#k!!!!Z`!!!,)!!!#e!!!![!!!!,d!!!#q!!!
        +!X3!!!+m!!!#f!!!!Y!!!!,m!!!$!!!!!`3!!!-)!!!$$!!!!a!!!!-8!!!$'!!!
        +!a`!!!,!!!!#c!!!!RJ!!!*m!!!#J!!!!S3!!!+)!!!#C!!!!R!!!!+-!!!#N!!!
        +!T3!!!*J!!!#@!!!!R3!!!*X!!!#Q!!!!T`!!!+J!!!#T!!!!UJ!!!+X!!!#X!!!
        +!V3!!!+i!!!#A!!!!QJ!!!&-!!!"8!!!!93!!!&B!!!"A!!!!6J!!!&%!!!"B!!!
        +!@3!!!&S!!!"0!!!!5`!!!&)!!!"3!!!!@`!!!&`!!!"G!!!!AJ!!!&m!!!"J!!!
        +!B3!!!')!!!"M!!!!6!!!!%m!!!#&!!!!KJ!!!)F!!!#)!!!!L3!!!)!!!!#$!!!
        +!LJ!!!)X!!!#-!!!!I`!!!(d!!!#%!!!!JJ!!!)d!!!#1!!!!M`!!!*!!!!!!N3!
        +!!*)!!!#6!!!!P!!!!*8!!!"q!!!!J3!!!'`!!!"Y!!!!EJ!!!'m!!!"`!!!!C`!
        +!!'S!!!"a!!!!FJ!!!(-!!!"Q!!!!C!!!!'X!!!"T!!!!G!!!!(8!!!"f!!!!G`!
        +!!(J!!!"j!!!!HJ!!!(X!!!"m!!!!C3!!!'J!!!!K!!!!)J!!!#-!!!!N!!!!*3!
        +!!"`!!!!I!!!!*J!!!#F!!!!S!!!!'`!!!"N!!!!J!!!!(J!!!#N!!!!U!!!!+`!
        +!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!"S!!!!G!!!!b!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!690-)%-Z8&"$,NaTBJ"*ER4
        +PFQCKBf9-D@)!6@&dD%aTBJ"08d`J8R9ZG'PYC9"33bj-D@)!6h"PEP4`G%PZCA4
        +38%-ZE`"2F'9Z9("d5@jdCA*ZCA4-D@)!6h"PEP4bB@jcF'pbG%9iG'j38%-ZE`"
        +2F'9Z9(*KER0`Eh*d6'PL!&4SFQ9KC(0-D@)!BQP[Ah0cE#jM!(-b-epME'jd,Q-
        +!Fc)cAfaTBLjM!(-b-epYCA4S,Q-!Fc)cAh"VG#jM!(-b-epcFRCb,Q-!Fc*IBfa
        +ZG#jM!(-bAf9ZBbjM!(-bAfaTBLjM!(-bAfePG'JZB`"c-Pp`Dh3ZB`"c-PpcFRC
        +b,Q-!Fc0IBQpdD#jM!(-cAf0XER3ZB`"c-epPEQ-ZB`"c-epXD@)ZB`"c-epYCA4
        +S,Q-!Fc0IF'Yd,Q-!Fc0IFh*fFLjM!(0cE&pKE'Gc,Q-!Fh0XAf&cEM%ZB`"cFfa
        +IBf9bG#jM!(0cE&pMDA"S,Q-!Fh0XAf9bFLjM!(0cE&pPFR)b,Q-!Fh0XAfaTBLj
        +M!(0cE&pbFf%ZB`"cFfaIFf9cFbjM!(0cE&pcG'&d,Q-!Fh0XAh4iG#jM!(3aAf0
        +XER3ZB`"d-9pPEQ-ZB`"d-9pXD@)ZB`"d-9pYCA4S,Q-!G$&IFh*fFLjM!'&cEM&
        +ICA*b,Q-!BA0Z-9pXD@)ZB`"KFfiaAh"KFLjM!'&cEPp`B@0V,Q-!B9pLDA4cG()
        +ZB`"KAf*YF#jM!'&IBQp[E#jM!'&IBRPdCA-ZB`"KAf3bD9pQF#jM!'&IC'PRCA0
        +d,Q-!B9pNGA!ZB`"KAf9ZG@dZB`"KAfGPER4Y,Q-!B9pSC()ZB`"KAfNbC&pQF#j
        +M!'&ID@jd,Q-!B9pYCA4S,Q-!B9p[BQTPBh3ZB`"KAfpMG'9d,Q-!B9p`FQPZG#j
        +M!'&IFf9d,Q-!B9pcD@GZ,Q-!B9pdD@eP,Q-!B9pdHA"P,Q-!B9peG'0dE5jM!'&
        +IGA4Q1#jM!'&IGQ9bD@Cj,Q-!B9pfDA-ZB`"N-QPIC'K`,Q-!C$*TAf4cBA!ZB`"
        +N-QPIF()ZB`"N-QPIF(8ZB`"N-QPIFPp`FLjM!'3bD9pbAh"e,Q-!C$*TAh0IF()
        +ZB`"N-QPIFep`G5jM!'9fF&pKFfia,Q-!CPpPER9Y,Q-!CPpTER3ZB`"QAh0dFQP
        +ZCbjM!'NbC&pND(!ZB`"T-Q4IC(0KF#jM!'NbC&p`FLjM!'NbC&p`G5jM!'NbC&p
        +bAh"b,Q-!D6*NAh*IF(8ZB`"T-Q4IFep`FLjM!'NbC&pcAh"e,Q-!ER0cCA%ZB`"
        +ZAh"VCANZB`"`09p`BQ8ZB`"`09p`BQ9f-LjM!(!hAf4RFh3ZB`"`0epPEQ-ZB`"
        +`0epPEQ0IBbjM!(!hAf9fF#jM!(!hAfPIFbjM!(!hAfaTBLjM!(!hAh*PBfP`,Q-
        +!F$GIFfPREQ3ZB`"`0epcD@GZD5jM!(!hAh0IC5jM!(!iAh"VCANZB`"dAf0bE#j
        +M!(4IF'YPH5jM!(4IFQ9a,Q-!G&pi06!j,Q-!H&pKE'G[FLjM!(KIBA4dFQPL,Q-
        +!H&pMD@jQ,Q-!H&pMFQ`ZB`"iAf9iG'9Z,Q-!H&pTEQC[,Q-!H&pZB@eP,Q-!H&p
        +`Df9j,Q-!H&p`G@*VCANZB`"iAh*PF5jM!(KIFfPR,Q-!H&pcF'YT,Q-!H&pfB@`
        +ZB`"iAhJe-$NZB`"LCPpMCQ)f0#jM!'*QAf9MBLjM!'*QAf9ZBbjM!'*QAfpQBMB
        +d,Q-!BQCIFfYPH5jM!'*TEepPFR)ZB`"LD@pIE'PL,Q-!BR0cAh0[BfXZB`"LEPp
        +KC'3ZB`"LEPpKFfdZB`"LEPpLE'PZC#jM!'*ZAf4TGLjM!'*ZAf9bFLjM!'*ZAf9
        +iF#jM!'*ZAf9iF$)ZB`"LEPpRBf3ZB`"LEPpXD@)ZB`"LEPpYEfjd,Q-!BQjIEA"
        +T,Q-!BQjIEA9X,Q-!BQjIF(*TE@8ZB`"LEPp`FQPZG#jM!'*ZAh*KEQ3ZB`"LEPp
        +bC@0`,Q-!BQjIFfKTCR3ZB`"LEPpcFA)ZB`"LEPphEh*N,Q-!BR9QCQ9b,Q-!BR9
        +QAf9bFLjM!'0IBfCL0M3ZB`"MAf9MBLjM!'0IC@jM,Q-!Bep[CQ)f0#jM!'0IFfY
        +PH5jM!'0[EA"IE'PL,Q-!BepbE'8ZB`"MAhTXD@)ZB`"MEfjQ,Q-!BfpZCPpPFR)
        +ZB`"MBQ0IBfYcE5jM!'0LBepPEQ-ZB`"MCQ)f0'9NC5jM!'0QBMBdC@jM,Q-!BfC
        +LAf9ZBbjM!'4PFepPEQ-ZB`"PBf)cAf9ZBbjM!'9MBPpPEQ-ZB`"PC'9IBf*ME9p
        +PEQ-ZB`"PEQ0IFQ9KC#jM!'CMFRP`G#jM!'CMFRP`G&pL,Q-!EfCL0M4PC'8ZB`"
        +[CQ)f0'9ZBbjM!'pQBPpPEQ-ZB`"`Bf*MAf9ZBbjM!(&eC&pMDh0Y,Q-!FQ&ZC&p
        +VCANZB`"bC@&N-R"hC#jM!(*PB@4IF(GN,Q-!FR"MAf9ZBbjM!(0PG&pVCANZB`"
        +cG()bDf9j,Q-!Fh9`F#jM!(KMBQ0IC@jM,Q-!C'KIBfKPBfXZB`"ND&pPFR)ZB`"
        +ND&pRC@iZB`"ND&pVCANZB`"ND&pXD@)ZB`"NFf&IBA0Z-5jM!'4cB9pPFR)ZB`"
        +NFf&ICf9Z,Q-!C(0KAfYPH5jM!'4cB9pXD@)ZB`"NFf&IFfPRELjM!'4cB9pfFQB
        +ZB`"PFR)ZB`"PFR*IB@aX,Q-!CA*bAh"bELjM!'*TEepL0M3ZB`"LD@pIC@jM,Q-
        +!BQP[AfeN,Q-!BQP[AfpV,Q-!BepKE'`ZB`"ND@GPFh3ZB`"PEQ0[C'8ZB`"PGR"
        +IC@jM,Q-!CAC`Af9bFLjM!'9fF&pVCANZB`"PGR"IE'PL,Q-!CAC`Ah"LC5jM!'9
        +fF&p`Df9j,Q-!C9pMBQ0I-f3ZB`"PAf0LBepLCLjM!'9IBf*MAf-ZB`"PAf0LBep
        +N,Q-!C9pMBQ0ID5jM!'9IBf*MAh)b,Q-!C9pMBQ0IFM8ZB`"PAf0QBPmcC#jM!'9
        +IBfCLAf*Q,Q-!C9pMCQ*IBbjM!'9IBfCLAf3ZB`"PAf0QBPpT,Q-!C9pMCQ*IFM)
        +ZB`"PAf0QBPpb05jM!'9IC@0LAc0N,Q-!C9pPBf*IBQBZB`"PAf9MBPpM,Q-!C9p
        +PBf*IC#jM!'9IC@0LAfNZB`"PAf9MBPpb-LjM!'9IC@0LAh)e,Q-!C9pZG@aX,Q-
        +!C9p[CQ*I-f3ZB`"PAfpQBPpLCLjM!'9IEfCLAf-ZB`"PAfpQBPpN,Q-!C9p[CQ*
        +ID5jM!'9IEfCLAh)b,Q-!C9p[CQ*IFM8ZB`"PAh*M0#jM!'9IH'0LBepN,Q-!E9p
        +NFh-ZB`"YAf4cFc%ZB`"YAfeN-LjM!'eIE@3e,Q-!E9pYC'-b,Q-!E9pZG@aX,Q-
        +!E9pbDA"PE@3ZB`"YAh0SB5jM!'eIFfKK-5jM!'jKE@9c,Q-!F&pNC@-ZB`"`Af9
        +ZBbjM!("IE'PL,Q-!F&p[F'9Z,Q-!F&pcC@&X,Q-!F&pcD@GZ,Q-!F&pfCA*TCRN
        +ZB`"SE@&M,Q-!D9pMBQ-ZB`"TAf0QBMBd,Q-!D9pPBf)ZB`"TAfpQBMBd,Q-!D9p
        +cDf9j,Q-!E'KKFfJZB`"XD&pcG'&dFbjM!'eN-PpNCh0d,Q-!E@3bAfpZC5jM!'e
        +N09pNCh0d,Q-!E@3eAfpZC5jM!'eNBc*NCh0d,Q-!E@4M-Pp[EQ8ZB`"[BQTIC'&
        +d,Q-!Ef*UAf9bFLjM!'pLDPpXD@)ZB`"[AfjKE@9c,Q-!F'9YAf&XE#jM!("PE9p
        +PFR)ZB`"`C@eID@jQEbjM!("PE9pXD@)ZB`"`C@eIFf9KE#jM!("PE9pcD@GZ,Q-
        +!F$%bAf&NC#jM!(!a-PpKG(4b,Q-!F$%bAf*KCh-ZB`"`-6*IBh*`G#jM!(!a-Pp
        +MFR3ZB`"`-6*IC'9MFLjM!(!a-PpTEQPd,Q-!F$%bAfYPH5jM!(!a-PpVDA0c,Q-
        +!F$%bAfaTBLjM!(!a-PpYB@-ZB`"`-6*IEA9dE#jM!(!a-PpcBQ&R,Q-!F$%bAh9
        +dE#jM!("V-6*PFR)ZB`"`DcGIC'pTG#jM!("V0epXD@)ZB`"`Df0c0f9bFLjM!'e
        +NAh*KEQ3ZB`"bB@jNCQPXC5jM!(*KEQ4IE'PL,Q-!FQ-bBfCL0M3ZB`"bBc*[CQ)
        +f0#jM!(*M-PpMBQ-ZB`"bBc*IC@0L,Q-!FQ-bAh0VCANZB`"bBc4IC@jM,Q-!FQ-
        +dAh0VCANZB`"bBc9MCQ)f0#jM!(*M0@pQBMBd,Q-!FQ-eAf9MBLjM!(*M09pPEQ-
        +ZB`"bBc9IFfYPH5jM!(*YC&pNCh0d,Q-!FQeNAfpZC5jM!(*cB9pPBANZB`"bFf&
        +ICA*b,Q-!FR0KAfGPELjM!(*cB9pXD@)ZB`"bFf&IEQpZC5jM!(*cB9p[B@9`,Q-
        +!FR0KAh"V-5jM!(*cB9pcB@pc,Q-!FR0KAh0TCfiZB`"bFf&IFh0X,Q-!FfKK-@4
        +RFh3ZB`"cD'%aAfpZC5jM!(0SB9pNCh0d,Q-!FfKKAfpZC5jM!(0dB@0V,Q-!G(K
        +dAf4L,Q-!BRPIC'Pb,Q-!BRPICQPXC5jM!(Je-$PZB@eP,Q-!H$8`1A*cCA3ZB`"
        +i06!jG(P`C5jM!(Je-$PIBfe`,Q-!H$8`19pN-LjM!(Je-$PIC'9Q,Q-!H$8`19p
        +PFR)ZB`"i06!jAf9iG#jM!(Je-$PIE(8ZB`"i06!jAfpLDLjM!(Je-$PIFM*i,Q-
        +!H$8`19pbCA%ZB`"i06!jAh0PG#jM!(Je-$PIG(Kd,Q-!H$8`19pf-bjM!(Je-$P
        +IGQCj,Q-!H&pKE'`ZB`"f-f9bFLjM!(BcAf&VCANZB`"f-epKE(3ZB`"f-epLBfp
        +ZFbjM!(BcAf*TG(0d,Q-!GM0IBfpZCLjM!(BcAf0`Efac,Q-!GM0IBh*XC#jM!(B
        +cAf9ZG@dZB`"f-epPH(4VG5jM!(BcAfGPEQiZB`"f-epTB68ZB`"f-epTER3ZB`"
        +f-epXD@)ZB`"f-ep`Dh8ZB`"f-ep`FQiZB`"f-epcDf9j,Q-!GM0IFhKZCA3ZB`"
        +f-epeG'`ZB`"MF(4ICA*b,Q-!Bh*jF(4XD@)ZB`"PH&pNBA4K,Q-!E@9Y,Q-!690
        +-)&0*6e9B,P"33bj-D@)!BQCIBR9QCLjM!(KIH$8`1@%ZB`"NFf&IEh0cE#jM!(J
        +e-$PcF'YT,Q-!H$8`19pdFR-ZB`"f-ep`GA*`,Q-!GM0ID@jQEbjM!'*IF(*TER3
        +ZB`"KAfeLFh4b,Q-!G&pcF'YT,Q-!G&pi06!jB5jM!(4IBQPdFh3ZB`"KAh0dFQj
        +TC#jM!'*TEepMBLjM!'*cFepYC@dZB`"LFh0ICQ3ZB`"LFh0ICQPXC5jM!'*cFep
        +ZG@aX,Q-!BQCIER9XE#jM!'*QAfjLD@mZB`"LFh0IBQP[,Q-!BPpNG@e`,Q-!C@j
        +MAhGbDA3ZB`"`09pMFR"d,Q-!F$9IBh*`G$)ZB`"`-6*IER"KFbjM!("V0epKG(4
        +b,Q-!F'XhAfeTE@8ZB`"`DcGIFfeTE@8ZB`"bFf&IBfKV,Q-!FR0KAfjeE'`ZB`"
        +MGQ9bFfP[ELjM!%038h4bD@jR9A4TE(-ZBh"`!%9bFQpb5'&ZC'aTEQFZBh"`!%G
        +PG%K89&"6,Q0`F!"0B@06Ef0VCA3ZBh"`!'ePE9pNBQFZB`"36&0dFQPZCdCeEQ0
        +c8&"$,QaTBJ"LEPpMG(JZB`"bB@jNAf9bFLjM!&*KEQ4[E@PkCA)ZBh"`!(J!BA"
        +`FbjM!'&`F&pbB@jN,Q-!BA0Z-A"KFR-ZB`"MB5jM!'0TF'KPFR-ZB`"MFQ`ZB`"
        +MFQ`bF$FZB`"NCh0d,Q-!C'JZB`"NFf%ZB`"NFf&`BA*KE5jM!'9ZBbjM!'9bFR0
        +dFLjM!'GPEQ4S,Q-!Cf9ZC(0K,Q-!Cf9ZFR0K,Q-!ER0PF5jM!'p`C@jcFf`ZB`"
        +`Df0c-6)ZB`"`Df0c0bjM!("VBh-i,Q-!FQ9a,Q-!FR0K,Q-!Ff9cFepTC#jM!(0
        +YD@eP,Q-!Fh"PC@3ZB`"cF'YKBbjM!(0IBf)ZB`"cAf0XD@9ZG#jM!(0IFf9bGQ9
        +b,Q-!FepcEf0VCA3ZB`"fCA*TCRNZB`"fCA*cD@pZ,Q-!H$8`15jM!(0IG'PYC5j
        +M!%G98dPI5@jTG#jMF(!!4e9659p$Eh*P,P"33bj-D@)!4e9659p08d`Z8&"$,Na
        +TBJ"(990*Ae0*6e9B,P"33bj-D@)!1NaTBP066#j38%-Z6'PL!$T-D@*$FRP`G'm
        +Z8&"$,NaTBJ"0B@028bjXD@)!690-)&*eER4TE@8f1%XZ6'PL!%p`C@j8F(4*EQ9
        +d,Qm!6h"PEP4bB@jcF'pbG#j[!%p`C@j8FQ&ZFh"[FR4"F(!ZE`"08d`J8dP299J
        +Z0MK,,NaTBJ"08d`J3bif1%XJ4Q%S0'PI1'3T,NaTBJ"0BA4S6'PL0MK,)%CK+$4
        +TAcKN+5j-D@)!4QPbFh3J8f9RE@9ZG!"(990*Ad0[FQ8Z0MK,,NaTBJ"(990*Ade
        +66#if1%XZ6'PL!%G98dPI8dP299JZ0MK,,NaTBJ!k6'PL3h*jF(4[,MBiDb"'B5J
        +dD9miC#NZ6'PL!%aTBP066#if1%XJ4Q%S0'PI1'3T,NaTBJ"(CA4)9&438b"38%-
        +!6h"PEP066#"38%-!4f9d5&488&-J0MK,!%aTBP066#!f1%X!6h"PEP066#!f1'X
        +!6'PL8e0-)&"33`"-D@*$FRP`G'mJ8&"$!%aTBN0bHA"dEb!f1%X!1NGPG%K89&"
        +6+&"33bN!6'PL)%PYF'pbG#"38%-!3Q&XE'p[EL")C@a`!%eA)%-[3bXV)&"33`"
        +(B@eP3fpNC5"$EfjfCA*dCA)!4QaPH#"3FQ9`FQpMCA0cEh)!69FJ8'&cBf&X)&"
        +33`"5CAS!8&"$3A0Y!%*TFfpZ)&"bCA"bEf0PFh0[FJ"B3dp'4L"*EA"[FR3J8&"
        +$!&"&4L"*EA"[FR3J8&"$!$T2F'9Z8e0-!$T(CA4)9&438bJf1%XT!%aTBL"*EA"
        +[FR3J0MK,!%e39b"*EA"[FR3J0MK,!%eA)%-[3bXV)$Bi5`"09b"3BA0MB@`J0MK
        +,!&"&4L"*EA"[FR3J0MK,!$T-D@*68d`Z0MK,)%CK+$4TAcKN+5j-D@)!1Np`C@j
        +68d`S0MKV+3"0B@028b"38%-J6'PZDf9b!%eKBdp6)$Bi5b"-D@jVCA)!8fpeFQ0
        +P)&4bC@9c!%0eFh4[E5",CAPhEh*NF`""Bf0PFh-J8'&dD(-!9'&bCf9d)&0PG(4
        +TEQGc!%CTE'8J6@&`F'PZCh-!3R9TE'3J4AKdFQ&c!%4PBR9RCf9b)&*eER4TE@8
        +!4'9LG@GRCA)J9'&bCf9d!%-[3bXV)%0[EA"TE'9b!%-[3bXV)&GKFQjTEQGc!&"
        +33b"$Ef4P4f9Z!&"33b"%DA0KFh0PE@*XCA)!8&"$)%GXEf*KE#"2F(4TE@PkCA)
        +!8&"$)%aTEQYPFJ"38%-J8%9'!&"33b"3FQpUC@0d!&"33d&cE5"3B@jPE!"5CAS
        +J3fpYF'PXCA)!0MK,)%0[C'9(C@i!0MK,)%4TFf&cFf9YBQaPFJ!f1%XJ4fa[BQ&
        +X)%p`G'PYDATPFJ!f1%XJ6'PZDf9b!$Bi5b"3FQpUC@0d!%0'66Bi5`!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!!!!!!!$J!
        +!!!)!!!!!!!!!'`!!!!-!!!!!!!!!)`!!!!3!!!!!!!!!0J!!!!8!!!!!!!!!4`!
        +!!!B!!!!!!!!!@J!!!!F!!!!!!!!!F3!!!!J!!!!!!!!!JJ!!!!N!!!!!!!!!M3!
        +!!!S!!!!!!!!!P`!!!!X!!!!!!!!!SJ!!!!`!!!!!!!!!V!!!!!d!!!!!!!!!Y`!
        +!!!i!!!!!!!!!`3!!!!m!!!!!!!!!c!!!!"!!!!!!!!!!eJ!!!"%!!!!!!!!!h`!
        +!!")!!!!!!!!!k!!!!"-!!!!!!!!!mJ!!!"3!!!!!!!!!q`!!!"8!!!!!!!!""3!
        +!!"B!!!!!!!!"$`!!!"F!!!!!!!!"'3!!!"J!!!!!!!!")J!!!"N!!!!!!!!"+`!
        +!!"S!!!!!!!!"03!!!"X!!!!!!!!"2J!!!"`!!!!!!!!"5!!!!"d!!!!!!!!"8`!
        +!!"i!!!!!!!!"AJ!!!"m!!!!!!!!"D3!!!#!!!!!!!!!"G!!!!#%!!!!!!!!"IJ!
        +!!#)!!!!!!!!"L3!!!#-!!!!!!!!"N`!!!#3!!!!!!!!"R3!!!#8!!!!!!!!"U!!
        +!!#B!!!!!!!!"X`!!!#F!!!!!!!!"[3!!!#J!!!!!!!!"a`!!!#N!!!!!!!!"d!!
        +!!#S!!!!!!!!"f3!!!#X!!!!!!!!"i`!!!#`!!!!!!!!"l3!!!#d!!!!!!!!"q!!
        +!!#i!!!!!!!!#!`!!!#m!!!!!!!!#$J!!!$!!!!!!!!!#'3!!!$%!!!!!!!!#*!!
        +!!$)!!!!!!!!#,!!!!$-!!!!!!!!#03!!!$3!!!!!!!!#2`!!!$8!!!!!!!!#5J!
        +!!$B!!!!!!!!#93!!!$F!!!!!!!!#A3!!!$J!!!!!!!!#CJ!!!$N!!!!!!!!#F!!
        +!!$S!!!!!!!!#H!!!!$X!!!!!!!!#J`!!!$`!!!!!!!!#L`!!!$d!!!!!!!!#P!!
        +!!$i!!!!!!!!#R`!!!$m!!!!!!!!#U3!!!%!!!!!!!!!#X`!!!%%!!!!!!!!#Z`!
        +!!%)!!!!!!!!#a!!!!%-!!!!!!!!#c3!!!%3!!!!!!!!#eJ!!!%8!!!!!!!!#i!!
        +!!%B!!!!!!!!#k3!!!%F!!!!!!!!#p!!!!%J!!!!!!!!#r!!!!%N!!!!!!!!$"J!
        +!!%S!!!!!!!!$%3!!!%X!!!!!!!!$'J!!!%`!!!!!!!!$)`!!!%d!!!!!!!!$,J!
        +!!%i!!!!!!!!$13!!!%m!!!!!!!!$4!!!!&!!!!!!!!!$6`!!!&%!!!!!!!!$@J!
        +!!&)!!!!!!!!$B`!!!&-!!!!!!!!$D`!!!&3!!!!!!!!$GJ!!!&8!!!!!!!!$J!!
        +!!&B!!!!!!!!$L`!!!&F!!!!!!!!$P!!!!&J!!!!!!!!$R3!!!&N!!!!!!!!$U!!
        +!!&S!!!!!!!!$X`!!!&X!!!!!!!!$[J!!!&`!!!!!!!!$b3!!!&d!!!!!!!!$d3!
        +!!&i!!!!!!!!$fJ!!!&m!!!!!!!!$i`!!!'!!!!!!!!!$lJ!!!'%!!!!!!!!$q!!
        +!!')!!!!!!!!%!3!!!'-!!!!!!!!%$!!!!'3!!!!!!!!%&3!!!'8!!!!!!!!%(J!
        +!!'B!!!!!!!!%*`!!!'F!!!!!!!!%-J!!!'J!!!!!!!!%23!!!'N!!!!!!!!%5!!
        +!!'S!!!!!!!!%83!!!'X!!!!!!!!%@`!!!'`!!!!!!!!%B`!!!'d!!!!!!!!%E!!
        +!!'i!!!!!!!!%G!!!!'m!!!!!!!!%I3!!!(!!!!!!!!!%K`!!!(%!!!!!!!!%NJ!
        +!!()!!!!!!!!%Q`!!!(-!!!!!!!!%S`!!!(3!!!!!!!!%V3!!!(8!!!!!!!!%YJ!
        +!!(B!!!!!!!!%[`!!!(F!!!!!!!!%b!!!!(J!!!!!!!!%d`!!!(N!!!!!!!!%f`!
        +!!(S!!!!!!!!%i`!!!(X!!!!!!!!%l!!!!(`!!!!!!!!%p!!!!(d!!!!!!!!%r3!
        +!!(i!!!!!!!!&#!!!!(m!!!!!!!!&%3!!!)!!!!!!!!!&'J!!!)%!!!!!!!!&*3!
        +!!))!!!!!!!!&,`!!!)-!!!!!!!!&13!!!)3!!!!!!!!&3`!!!)8!!!!!!!!&6J!
        +!!)B!!!!!!!!&9`!!!)F!!!!!!!!&B!!!!)J!!!!!!!!&D`!!!)N!!!!!!!!&G!!
        +!!)S!!!!!!!!&I3!!!)X!!!!!!!!&KJ!!!)`!!!!!!!!&N!!!!!#0!!!!!!!!"CN
        +!!!#1!!!!!!!!"D)!!!#2!!!!!!!!"D`!!!#3!!!!!!!!!!@e!!!!N3!!!!!!!!@
        +q!!!!NJ!!!!!!!!A*!!!!N`!!!!!!!!A8!!!!P!!!!!!!!!AH!!!!P3!!!!!!!!A
        +S!!!!PJ!!!!!!!!Ac!!!!P`!!!!!!!!Am!!!!Q!!!!!!!!!B'!!!!Q3!!!!!!!!B
        +2!!!!QJ!!!!!!!!BC!!!!Q`!!!!!!!!BM!!!!R!!!!!!!!!BV!!!!R3!!!!!!!!B
        +c!!!!RJ!!!!!!!!Bp!!!!R`!!!!!!!!C'!!!!S!!!!!!!!!C4!!!!S3!!!!!!!!C
        +C!!!!SJ!!!!!!!!CL!!!!S`!!!!!!!!CT!!!!T!!!!!!!!!Cd!!!!T3!!!!!!!!C
        +r!!!!TJ!!!!!!!!D*!!!!T`!!!!!!!!D8!!!!U!!!!!!!!!DI!!!!U3!!!!!!!!D
        +T!!!!UJ!!!!!!!!Dc!!!!U`!!!!!!!!Dq!!!!V!!!!!!!!!E)!!!!V3!!!!!!!!E
        +A!!!!VJ!!!!!!!!EL!!!!V`!!!!!!!!EV!!!!X!!!!!!!!!Ef!!!!X3!!!!!!!!F
        +"!!!!XJ!!!!!!!!F-!!!!X`!!!!!!!!F@!!!!Y!!!!!!!!!FK!!!!Y3!!!!!!!!F
        +X!!!!YJ!!!!!!!!Fh!!!!Y`!!!!!!!!G#!!!!Z!!!!!!!!!G0!!!!Z3!!!!!!!!G
        +A!!!!ZJ!!!!!!!!GK!!!!Z`!!!!!!!!GV!!!![!!!!!!!!!Gb!!!![3!!!!!!!!G
        +p!!!![J!!!!!!!!H)!!!![`!!!!!!!!H4!!!!`!!!!!!!!!HD!!!!`3!!!!!!!!H
        +M!!!!`J!!!!!!!!HX!!!!``!!!!!!!!Hh!!!!a!!!!!!!!!I"!!!!a3!!!!!!!!I
        +,!!!!aJ!!!!!!!!I9!!!!a`!!!!!!!!II!!!!b!!!!!!!!!IU!!!!b3!!!!!!!!I
        +d!!!!bJ!!!!!!!!Ik!!!!b`!!!!!!!!J%!!!!c!!!!!!!!!J1!!!!c3!!!!!!!!J
        +B!!!!cJ!!!!!!!!JL!!!!c`!!!!!!!!JV!!!!d!!!!!!!!!Jd!!!!d3!!!!!!!!J
        +m!!!!dJ!!!!!!!!K&!!!!d`!!!!!!!!K1!!!!e!!!!!!!!!KB!!!!e3!!!!!!!!K
        +L!!!!eJ!!!!!!!!KX!!!!e`!!!!!!!!Kf!!!!f!!!!!!!!!L!!!!!f3!!!!!!!!L
        +,!!!!fJ!!!!!!!!L@!!!!f`!!!!!!!!LK!!!!h!!!!!!!!!LV!!!!h3!!!!!!!!L
        +e!!!!hJ!!!!!!!!Lr!!!!h`!!!!!!!!M+!!!!i!!!!!!!!!M9!!!!i3!!!!!!!!M
        +J!!!!iJ!!!!!!!!MV!!!!i`!!!!!!!!Me!!!!j!!!!!!!!!Mr!!!!j3!!!!!!!!N
        +*!!!!jJ!!!!!!!!N8!!!!j`!!!!!!!!NI!!!!k!!!!!!!!!NU!!!!k3!!!!!!!!N
        +e!!!!kJ!!!!!!!!Nr!!!!k`!!!!!!!!P*!!!!l!!!!!!!!!P6!!!!l3!!!!!!!!P
        +H!!!!lJ!!!!!!!!PT!!!!l`!!!!!!!!Pb!!!!m!!!!!!!!!Pp!!!!m3!!!!!!!!Q
        +)!!!!mJ!!!!!!!!Q5!!!!m`!!!!!!!!QF!!!!p!!!!!!!!!QQ!!!!p3!!!!!!!!Q
        +a!!!!pJ!!!!!!!!Qm!!!!p`!!!!!!!!R%!!!!q!!!!!!!!!R2!!!!q3!!!!!!!!R
        +A!!!!qJ!!!!!!!!RJ!!!!q`!!!!!!!!RS!!!!r!!!!!!!!!R`!!!!r3!!!!!!!!R
        +j!!!!rJ!!!!!!!!S#!!!!r`!!!!!!!!S0!!!"!!!!!!!!!!S9!!!"!3!!!!!!!!S
        +H!!!"!J!!!!!!!!SQ!!!"!`!!!!!!!!SZ!!!""!!!!!!!!!Sf!!!""3!!!!!!!!S
        +q!!!""J!!!!!!!!T(!!!""`!!!!!!!!T3!!!"#!!!!!!!!!TC!!!"#3!!!!!!!!T
        +N!!!"#J!!!!!!!!TV!!!"#`!!!!!!!!Tc!!!"$!!!!!!!!!Tp!!!"$3!!!!!!!!U
        +&!!!"$J!!!!!!!!U2!!!"$`!!!!!!!!UB!!!"%!!!!!!!!!UJ!!!"%3!!!!!!!!U
        +V!!!"%J!!!!!!!!Uf!!!"%`!!!!!!!!V!!!!"&!!!!!!!!!V,!!!"&3!!!!!!!!V
        +9!!!"&J!!!!!!!!VJ!!!"&`!!!!!!!!VV!!!"'!!!!!!!!!Ve!!!"'3!!!!!!!!V
        +r!!!"'J!!!!!!!!X*!!!"'`!!!!!!!!X6!!!"(!!!!!!!!!XG!!!"(3!!!!!!!!X
        +R!!!"(J!!!!!!!!Xb!!!"(`!!!!!!!!Xm!!!")!!!!!!!!!Y(!!!")3!!!!!!!!Y
        +5!!!")J!!!!!!!!YF!!!")`!!!!!!!!YR!!!"*!!!!!!!!!Yb!!!"*3!!!!!!!!Y
        +p!!!"*J!!!!!!!!Z(!!!"*`!!!!!!!!Z5!!!"+!!!!!!!!!ZG!!!"+3!!!!!!!!Z
        +R!!!"+J!!!!!!!!Zb!!!"+`!!!!!!!!Zm!!!",!!!!!!!!!['!!!",3!!!!!!!![
        +4!!!",J!!!!!!!![F!!!",`!!!!!!!![Q!!!"-!!!!!!!!![`!!!"-3!!!!!!!![
        +l!!!"-J!!!!!!!!`&!!!"-`!!!!!!!!`3!!!"0!!!!!!!!!`D!!!"03!!!!!!!!`
        +P!!!"0J!!!!!!!!``!!!"0`!!!!!!!!`l!!!"1!!!!!!!!!a'!!!"13!!!!!!!!a
        +3!!!"1J!!!!!!!!aD!!!"1`!!!!!!!!aP!!!"2!!!!!!!!!a[!!!"23!!!!!!!!a
        +k!!!"2J!!!!!!!!b&!!!"2`!!!!!!!!b3!!!!!8!!!!!!!!!-QJ!!!8%!!!!!!!!
        +-T!!!!8)!!!!!!!!-V`!!!8-!!!!!!!!-ZJ!!!83!!!!!!!!-a!!!!88!!!!!!!!
        +-cJ!!!8B!!!!!!!!-f!!!!8F!!!!!!!!-iJ!!!8J!!!!!!!!-l!!!!8N!!!!!!!!
        +-p`!!!8S!!!!!!!!0!J!!!8X!!!!!!!!0$!!!!8`!!!!!!!!0&`!!!8d!!!!!!!!
        +0)J!!!8i!!!!!!!!0,!!!!8m!!!!!!!!00`!!!9!!!!!!!!!03J!!!9%!!!!!!!!
        +063!!!9)!!!!!!!!09`!!!9-!!!!!!!!0A`!!!93!!!!!!!!0D!!!!98!!!!!!!!
        +0F3!!!9B!!!!!!!!0H`!!!9F!!!!!!!!0KJ!!!9J!!!!!!!!0N3!!!9N!!!!!!!!
        +0R!!!!9S!!!!!!!!0T`!!!9X!!!!!!!!0X3!!!9`!!!!!!!!0[!!!!9d!!!!!!!!
        +0a`!!!9i!!!!!!!!0dJ!!!9m!!!!!!!!0h!!!!@!!!!!!!!!0j`!!!@%!!!!!!!!
        +0mJ!!!@)!!!!!!!!0r3!!!@-!!!!!!!!1#!!!!@3!!!!!!!!1%`!!!@8!!!!!!!!
        +1(3!!!@B!!!!!!!!1+!!!!@F!!!!!!!!1-!!!!@J!!!!!!!!11!!!!@N!!!!!!!!
        +13J!!!@S!!!!!!!!15`!!!@X!!!!!!!!19J!!!@`!!!!!!!!1B3!!!@d!!!!!!!!
        +1D`!!!@i!!!!!!!!1GJ!!!@m!!!!!!!!1J!!!!A!!!!!!!!!1LJ!!!A%!!!!!!!!
        +1P3!!!A)!!!!!!!!1R`!!!A-!!!!!!!!1U!!!!A3!!!!!!!!1X3!!!A8!!!!!!!!
        +1ZJ!!!AB!!!!!!!!1``!!!AF!!!!!!!!1c!!!!AJ!!!!!!!!1eJ!!!AN!!!!!!!!
        +1i3!!!AS!!!!!!!!1kJ!!!AX!!!!!!!!1p!!!!A`!!!!!!!!1r`!!!Ad!!!!!!!!
        +2#3!!!Ai!!!!!!!!2$`!!!Am!!!!!!!!2)3!!!B!!!!!!!!!2+`!!!B%!!!!!!!!
        +203!!!B)!!!!!!!!23!!!!B-!!!!!!!!25`!!!B3!!!!!!!!29J!!!B8!!!!!!!!
        +2B!!!!BB!!!!!!!!2DJ!!!BF!!!!!!!!2G!!!!BJ!!!!!!!!2IJ!!!BN!!!!!!!!
        +2K`!!!BS!!!!!!!!2N3!!!BX!!!!!!!!2Q`!!!B`!!!!!!!!2TJ!!!Bd!!!!!!!!
        +2V`!!!Bi!!!!!!!!2Z3!!!Bm!!!!!!!!2`J!!!C!!!!!!!!!!$md!!!'4!!!!!!!
        +!$pJ!!!'5!!!!!!!!$q)!!!'6!!!!!!!!$q`!!!'8!!!!!!!!$rB!!!'9!!!!!!!
        +!$rm!!!'@!!!!!!!!%!S!!!'A!!!!!!!!%"3!!!'B!!!!!!!!%"m!!!'C!!!!!!!
        +!%#S!!!'D!!!!!!!!%$8!!!'E!!!!!!!!%%!!!!'F!!!!!!!!%%`!!!'G!!!!!!!
        +!%&B!!!'H!!!!!!!!%'%!!!'I!!!!!!!!%'`!!!'J!!!!!!!!%(i!!!'K!!!!!!!
        +!%*!!!!!"SJ!!!!!!!"#G!!!"S`!!!!!!!"#V!!!"T!!!!!!!!"#e!!!"T3!!!!!
        +!!"$+!!!"TJ!!!!!!!"$6!!!"T`!!!!!!!"$H!!!"U!!!!!!!!"$Y!!!"U3!!!!!
        +!!"$[!!!"UJ!!!!!!!"$f!!!"U`!!!!!!!"%"!!!"V!!!!!!!!"%-!!!"V3!!!!!
        +!!"%4!!!"VJ!!!!!!!"%E!!!"V`!!!!!!!"%K!!!"X!!!!!!!!"%U!!!"X3!!!!!
        +!!"%a!!!"XJ!!!!!!!"%f!!!"X`!!!!!!!"%m!!!"Y!!!!!!!!"&(!!!"Y3!!!!!
        +!!"&0!!!"YJ!!!!!!!"&@!!!"Y`!!!!!!!"&H!!!"Z!!!!!!!!"&R!!!"Z3!!!!!
        +!!"&`!!!"ZJ!!!!!!!"&h!!!"Z`!!!!!!!"'"!!!"[!!!!!!!!"'+!!!"[3!!!!!
        +!!"'5!!!"[J!!!!!!!"'D!!!"[`!!!!!!!"'J!!!"`!!!!!!!!"'Q!!!"`3!!!!!
        +!!"'`!!!"`J!!!!!!!"'i!!!"``!!!!!!!"(!!!!"a!!!!!!!!"()!!!"a3!!!!!
        +!!"(2!!!"aJ!!!!!!!"(D!!!"a`!!!!!!!"(P!!!"b!!!!!!!!"(`!!!"b3!!!!!
        +!!"(j!!!"bJ!!!!!!!")$!!!"b`!!!!!!!")+!!!"c!!!!!!!!")6!!!"c3!!!!!
        +!!")K!!!"cJ!!!!!!!")c!!!"c`!!!!!!!"*%!!!"d!!!!!!!!"*A!!!"d3!!!!!
        +!!"*R!!!"dJ!!!!!!!"*k!!!"d`!!!!!!!"+%!!!"e!!!!!!!!"+A!!!"e3!!!!!
        +!!"+P!!!"eJ!!!!!!!"+e!!!"e`!!!!!!!",)!!!"f!!!!!!!!",D!!!"f3!!!!!
        +!!",b!!!"fJ!!!!!!!"-,!!!"f`!!!!!!!"-C!!!"h!!!!!!!!"-V!!!"h3!!!!!
        +!!"-m!!!"hJ!!!!!!!"02!!!"h`!!!!!!!"0X!!!"i!!!!!!!!"1&!!!"i3!!!!!
        +!!"15!!!"iJ!!!!!!!"1H!!!"i`!!!!!!!"1V!!!"j!!!!!!!!"1f!!!"j3!!!!!
        +!!"2#!!!"jJ!!!!!!!"20!!!"j`!!!!!!!"2E!!!"k!!!!!!!!"2T!!!"k3!!!!!
        +!!"2i!!!"kJ!!!!!!!"3(!!!"k`!!!!!!!"38!!!"l!!!!!!!!"3K!!!"l3!!!!!
        +!!"3d!!!"lJ!!!!!!!"4'!!!"l`!!!!!!!"48!!!"m!!!!!!!!"4B!!!"m3!!!!!
        +!!"4I!!!"mJ!!!!!!!"4b!!!"m`!!!!!!!"5$!!!"p!!!!!!!!"55!!!"p3!!!!!
        +!!"5E!!!"pJ!!!!!!!"5U!!!"p`!!!!!!!"5j!!!"q!!!!!!!!"6)!!!"q3!!!!!
        +!!"69!!!"qJ!!!!!!!"6M!!!"q`!!!!!!!"6b!!!"r!!!!!!!!"8-!!!"r3!!!!!
        +!!"8D!!!"rJ!!!!!!!"8V!!!"r`!!!!!!!"8m!!!#!!!!!!!!!"9*!!!#!3!!!!!
        +!!"9C!!!#!J!!!!!!!"9Q!!!#!`!!!!!!!"9f!!!#"!!!!!!!!"@%!!!#"3!!!!!
        +!!"@4!!!#"J!!!!!!!"@L!!!#"`!!!!!!!"@b!!!##!!!!!!!!"A"!!!##3!!!!!
        +!!"A3!!!##J!!!!!!!"AF!!!##`!!!!!!!"AY!!!#$!!!!!!!!"B#!!!#$3!!!!!
        +!!"B0!!!#$J!!!!!!!"B9!!!#$`!!!!!!!"BK!!!#%!!!!!!!!"BZ!!!#%3!!!!!
        +!!"Bl!!!#%J!!!!!!!"C(!!!#%`!!!!!!!"CB!!!#&!!!!!!!!"CY!!!#&3!!!!!
        +!!"Ci!!!#&J!!!!!!!"D%!!!#&`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$!!!!$!!!!!-
        +!!!!-Y0ifDrrrqUS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!#&`!!!L!!!"D,!!!B!!!!!KF!!!!!!!!!!!!!!!!
        +!!!!!9%9B9!!!!!)!!!(q!!!"r`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#`MlJ!!!!!!!!!3!
        +#`NI`!!)!!!!!!!!!!!!!!X)fJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!)!!!%!!!!!"3!!Irm!!!!!Irm!!!!!Irm!!!!!Irm!!!!-!!%!!J!%!!!
        +!"8!!!!B!!3!"1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!%!!!$rrrrr!!!!!`!"!!%k1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!3!!!2rrrrm!!!!%!!%!!6SkD@jME(9NC6S!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!)!!3!"1J!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!`!#!!%k6@&M6e-
        +J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp!!!!%!!)
        +!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrr
        +rrd!!!!8!#J!!6@&M6e-J8&"$)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!4f9d5&488&-J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b"38%-J6'PZDf9b!!!
        +!!!!!!!!!!!!!!!!!!!!H39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"`E!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"-4J!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P053`!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMB`!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF(!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jRB`!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9bG'9b!!!
        +!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9B9#jX!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0cEh)!!!!
        +!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BA-
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`BfJ
        +V+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!
        +!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#jb!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!9%9B9#jc!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!8&"$3A0Y!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jj!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9cFfpb!!!
        +!!!!!!!!!!!!!!!#!!!!!@%024J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!@%024NBJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!C'pMG3!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"J!!!!FR0bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!Fh4eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"3!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!"!!!
        +!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3!"!!!!!3%"!3%!!3%!!!!!!!%"!!!
        +"!3!"!!!"!!%!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!"G0B@028b"8EfpXBQp
        +i)%4&3P9()$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!r2cmr39"36!!!!B"B`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!0!!%!!!!!!""I69G&8NY6Ah"bC@CTH#jS!!!!!!!!!!!!!!!!!!!!!!!
        +"!!!"!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0dBA*d!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$m
        +r2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!"!!!!!!!
        +!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!e(CA4)9&438bK38%-T!!!!!!!
        +!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cmr!!!!!!!
        +!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!R8%P$9#F
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!3!
        +!!!%#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!)!!!!#!J%!!!!
        +!!!%!!3-!!!!!!!!!!!!!!!!%!!!!!!!!!!!"!!!$!!!!!`)"!!!!!!!"!!%$!!!
        +!!!!!!!!!!!!!"!!!!!!!!!!!!3!!"!!!!!3#!3!!!!!!!3!"!`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!%!!!8!!!!&!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!'!!!!"J)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!"3!!!!!!!!!!!3!!"`!
        +!!!F#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!!J!!!!)!J%!!!!
        +!!!%!!3-!!!!!!!!!!!!!!!!&!!!!!!!!!!!"!!!*!!!!#3)"!!!!!!!"!!%$!!!
        +!!!!!!!!!!!!!"3!!!!!!!!!!!3!!#J!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!!X!!!!,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!-!!!!$!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!$3!
        +!!!d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!!i!!!!1!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!2!!!!$`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!%!!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!"%!!!!4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!5!!!!%J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!%`!
        +!!"-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!"3!!!!8!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!9!!!!&3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!&J!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!"F!!!!A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!B!!!!'!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!'3!
        +!!"N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!"S!!!!D!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!E!!!!'`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!(!!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!"d!!!!G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!H!!!!(J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!(`!
        +!!"m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!#!!!!!J!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!K!!!!)3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!)J!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!#-!!!!M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!N!!!!*!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!*3!
        +!!#8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!#B!!!!Q!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!R!!!!*`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!+!!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!#N!!!!T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!U!!!!+J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!+`!
        +!!#X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!#`!!!!X!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!Y!!!!,3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!,J!!!#i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!#m!!!![!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!`!!!!-!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!-3!
        +!!$%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!$)!!!!b!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!c!!!!-`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!0!!!!$3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!$8!!!!e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!f!!!!0J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!0`!
        +!!$F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!$J!!!!i!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!j!!!!13)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!1J!!!$S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!$X!!!!l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!!m!!!!2!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!23!
        +!!$d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!$i!!!!q!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!!r!!!!2`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!3!!!!%!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!%%!!!""!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"#!!!!3J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!3`!
        +!!%-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!%3!!!"%!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"&!!!!43)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!4J!!!%B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!%F!!!"(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!")!!!!5!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!53!
        +!!%N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!%S!!!"+!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!",!!!!5`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!6!!!!%`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!%d!!!"0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"1!!!!6J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!6`!
        +!!%m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!&!!!!"3!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"4!!!!83)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!8J!!!&)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!&-!!!"6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"8!!!!9!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!93!
        +!!&8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!&B!!!"@!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"A!!!!9`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!@!!!!&J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!&N!!!"C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"D!!!!@J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!@`!
        +!!&X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!&`!!!"F!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"G!!!!A3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!AJ!!!&i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!&m!!!"I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"J!!!!B!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!B3!
        +!!'%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!')!!!"L!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"M!!!!B`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!C!!!!'3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!'8!!!"P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"Q!!!!CJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!C`!
        +!!'F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!'J!!!"S!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"T!!!!D3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!DJ!!!'S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!'X!!!"V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"X!!!!E!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!E3!
        +!!'d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!'i!!!"Z!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"[!!!!E`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!F!!!!(!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!(%!!!"a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"b!!!!FJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!F`!
        +!!(-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!(3!!!"d!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"e!!!!G3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!GJ!!!(B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!(F!!!"h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"i!!!!H!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!H3!
        +!!(N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!(S!!!"k!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!"l!!!!H`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!I!!!!(`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!(d!!!"p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!"q!!!!IJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!I`!
        +!!(m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!)!!!!#!!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#"!!!!J3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!JJ!!!))#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!)-!!!#$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!#%!!!!K!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!K3!
        +!!)8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!)B!!!#'!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#(!!!!K`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!L!!!!)J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!)N!!!#*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!#+!!!!LJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!L`!
        +!!)X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!)`!!!#-!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#0!!!!M3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!3!!MJ!!!)i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!%!!)m!!!#2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!"!!#3!!!!!*!!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +4!!!!N3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!NJ!!!*)#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!*-!!!#6!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#8!!!!P!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!P3!!!*8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!*B!!!#@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +A!!!!P`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!Q!!!!*J#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!*N!!!#C!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#D!!!!QJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!Q`!!!*X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!*`!!!#F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +G!!!!R3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!RJ!!!*i#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!*m!!!#I!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#J!!!!S!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!S3!!!+%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!+)!!!#L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +M!!!!S`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!T!!!!+3#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!+8!!!#P!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#Q!!!!TJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!T`!!!+F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!+J!!!#S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +T!!!!U3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!UJ!!!+S#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!+X!!!#V!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#X!!!!V!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!V3!!!+d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!+i!!!#Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +[!!!!V`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!X!!!!,!#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!,%!!!#a!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#b!!!!XJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!X`!!!,-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!,3!!!#d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +e!!!!Y3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!YJ!!!,B#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!,F!!!#h!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#i!!!!Z!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!Z3!!!,N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!,S!!!#k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#
        +l!!!!Z`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!![!!!!,`#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!,d!!!#p!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!#q!!!![J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!![`!!!,m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!-!!!!$!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +"!!!!`3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!`J!!!-)#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!--!!!$$!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$%!!!!a!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!a3!!!-8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!-B!!!$'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +(!!!!a`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!b!!!!-J#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!-N!!!$*!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$+!!!!bJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!b`!!!-X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!-`!!!$-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +0!!!!c3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!cJ!!!-i#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!-m!!!$2!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$3!!!!d!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!d3!!!0%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!0)!!!$5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +6!!!!d`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!e!!!!03#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!08!!!$9!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$@!!!!eJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!e`!!!0F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!0J!!!$B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +C!!!!f3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!fJ!!!0S#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!0X!!!$E!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$F!!!!h!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!h3!!!0d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!0i!!!$H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +I!!!!h`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!i!!!!1!#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!1%!!!$K!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$L!!!!iJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!i`!!!1-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!13!!!$N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +P!!!!j3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!jJ!!!1B#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!1F!!!$R!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$S!!!!k!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!k3!!!1N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!1S!!!$U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +V!!!!k`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!l!!!!1`#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!1d!!!$Y!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$Z!!!!lJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!l`!!!1m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!2!!!!$`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +a!!!!m3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!mJ!!!2)#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!2-!!!$c!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$d!!!!p!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!p3!!!28#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!2B!!!$f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +h!!!!p`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!q!!!!2J#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!2N!!!$j!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$k!!!!qJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!!q`!!!2X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!2`!!!$m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!$
        +p!!!!r3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!!rJ!!!2i#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!2m!!!$r!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%!!!!"!!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"!3!!!3%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!3)!!!%#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +$!!!"!`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!""!!!!33#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!38!!!%&!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%'!!!""J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!""`!!!3F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!3J!!!%)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +*!!!"#3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"#J!!!3S#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!3X!!!%,!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%-!!!"$!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"$3!!!3d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!3i!!!%1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +2!!!"$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"%!!!!4!#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!4%!!!%4!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%5!!!"%J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"%`!!!4-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!43!!!%8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +9!!!"&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"&J!!!4B#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!4F!!!%A!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%B!!!"'!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"'3!!!4N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!4S!!!%D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +E!!!"'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"(!!!!4`#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!4d!!!%G!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%H!!!"(J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"(`!!!4m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!5!!!!%J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +K!!!")3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!")J!!!5)#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!5-!!!%M!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%N!!!"*!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"*3!!!58#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!5B!!!%Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +R!!!"*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"+!!!!5J#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!5N!!!%T!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%U!!!"+J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"+`!!!5X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!5`!!!%X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +Y!!!",3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!",J!!!5i#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!5m!!!%[!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%`!!!"-!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"-3!!!6%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!6)!!!%b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +c!!!"-`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"0!!!!63#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!68!!!%e!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%f!!!"0J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"0`!!!6F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!6J!!!%i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +j!!!"13)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"1J!!!6S#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!6X!!!%l!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%m!!!"2!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"23!!!6d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!6i!!!%q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!%
        +r!!!"2`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"3!!!!8!#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!8%!!!&"!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&#!!!"3J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"3`!!!8-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!83!!!&%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +&!!!"43)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"4J!!!8B#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!8F!!!&(!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&)!!!"5!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"53!!!8N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!8S!!!&+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +,!!!"5`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"6!!!!8`#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!8d!!!&0!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&1!!!"6J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"6`!!!8m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!9!!!!&3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +4!!!"83)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"8J!!!9)#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!9-!!!&6!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&8!!!"9!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"93!!!98#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!9B!!!&@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +A!!!"9`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"@!!!!9J#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!9N!!!&C!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&D!!!"@J)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"@`!!!9X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!9`!!!&F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +G!!!"A3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"AJ!!!9i#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!9m!!!&I!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&J!!!"B!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"B3!!!@%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!@)!!!&L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +M!!!"B`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"C!!!!@3#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!@8!!!&P!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&Q!!!"CJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"C`!!!@F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!@J!!!&S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +T!!!"D3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"DJ!!!@S#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!@X!!!&V!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&X!!!"E!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"E3!!!@d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!@i!!!&Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +[!!!"E`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"F!!!!A!#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!A%!!!&a!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&b!!!"FJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"F`!!!A-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!A3!!!&d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +e!!!"G3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"GJ!!!AB#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!AF!!!&h!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&i!!!"H!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"H3!!!AN#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!AS!!!&k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&
        +l!!!"H`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"I!!!!A`#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!Ad!!!&p!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!&q!!!"IJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"I`!!!Am#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!B!!!!'!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'
        +"!!!"J3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"JJ!!!B)#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!B-!!!'$!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'%!!!"K!)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"K3!!!B8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!BB!!!''!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'
        +(!!!"K`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"L!!!!BJ#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!BN!!!'*!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'+!!!"LJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!3!"L`!!!BX#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!B`!!!'-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'
        +0!!!"M3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"MJ!!!Bi#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!Bm!!!'2!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'3!!!!!C!!!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!"!!'4!!!"N3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!!3!"NJ!!!C)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
        +!!C-!!!'6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'8!!!"P!)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"P3!!!C8#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!CB!!!'@!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!"!!'A!!!"P`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!!3!"Q!!!!CJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
        +!!CN!!!'C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'D!!!"QJ)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"Q`!!!CX#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!C`!!!'F!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!"!!'G!!!"R3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!!3!"RJ!!!Ci#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
        +!!Cm!!!'I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'J!!!"S!)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"S3!!!D%#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!D)!!!'L!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!"!!'M!!!"S`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!!3!"T!!!!D3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%
        +!!D8!!!'P!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!"!!'Q!!!"TJ)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!3!"T`!!!DF#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!%!!DJ!!!'S!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!)!!!!$!!!!"!!!!!8!!!!'!!!!"`!
        +!!!J!!!!*!!!!#J!!!!X!!!!-!!!!$3!!!!i!!!!2!!!!%!!!!"%!!!!5!!!!%`!
        +!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S!!!!E!!!!(!!!!"d!!!!H!!!!(`!
        +!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B!!!!R!!!!+!!!!#N!!!!U!!!!+`!
        +!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!$)!!!!c!!!!0!!!!$8!!!!f!!!!0`!
        +!!$J!!!!j!!!!1J!!!$X!!!!m!!!!23!!!$i!!!!r!!!!3!!!!%%!!!"#!!!!3`!
        +!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S!!!",!!!!6!!!!%d!!!"1!!!!6`!
        +!!&!!!!"4!!!!8J!!!&-!!!"8!!!!93!!!&B!!!"A!!!!@!!!!&N!!!"D!!!!@`!
        +!!&`!!!"G!!!!AJ!!!&m!!!"J!!!!B3!!!')!!!"M!!!!C!!!!'8!!!"Q!!!!C`!
        +!!'J!!!"T!!!!DJ!!!'X!!!"X!!!!E3!!!'i!!!"[!!!!F!!!!(%!!!"b!!!!F`!
        +!!(3!!!"e!!!!GJ!!!(F!!!"i!!!!H3!!!(S!!!"l!!!!I!!!!(d!!!"q!!!!I`!
        +!!)!!!!#"!!!!JJ!!!)-!!!#%!!!!K3!!!)B!!!#(!!!!L!!!!)N!!!#+!!!!L`!
        +!!)`!!!#0!!!!MJ!!!)m!!!#3!!!!!*%!!!#5!!!!N`!!!*3!!!#9!!!!PJ!!!*F
        +!!!#B!!!!Q3!!!*S!!!#E!!!!R!!!!*d!!!#H!!!!R`!!!+!!!!#K!!!!SJ!!!+-
        +!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!+N!!!#U!!!!U`!!!+`!!!#Y!!!!VJ!!!+m
        +!!!#`!!!!X3!!!,)!!!#c!!!!Y!!!!,8!!!#f!!!!Y`!!!,J!!!#j!!!!ZJ!!!,X
        +!!!#m!!!![3!!!,i!!!#r!!!!`!!!!-%!!!$#!!!!``!!!-3!!!$&!!!!aJ!!!-F
        +!!!$)!!!!b3!!!-S!!!$,!!!!c!!!!-d!!!$1!!!!c`!!!0!!!!$4!!!!dJ!!!0-
        +!!!$8!!!!e3!!!0B!!!$A!!!!f!!!!0N!!!$D!!!!f`!!!0`!!!$G!!!!hJ!!!0m
        +!!!$J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$Q!!!!j`!!!1J!!!$T!!!!kJ!!!1X
        +!!!$X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$b!!!!m`!!!23!!!$e!!!!pJ!!!2F
        +!!!$i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$q!!!!r`!!!3!!!!%"!!!"!J!!!3-
        +!!!%%!!!""3!!!3B!!!%(!!!"#!!!!3N!!!%+!!!"#`!!!3`!!!%0!!!"$J!!!3m
        +!!!%3!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%@!!!"&`!!!4J!!!%C!!!"'J!!!4X
        +!!!%F!!!"(3!!!4i!!!%I!!!")!!!!5%!!!%L!!!")`!!!53!!!%P!!!"*J!!!5F
        +!!!%S!!!"+3!!!5S!!!%V!!!",!!!!5d!!!%Z!!!",`!!!6!!!!%a!!!"-J!!!6-
        +!!!%d!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%k!!!"1`!!!6`!!!%p!!!"2J!!!6m
        +!!!&!!!!"33!!!8)!!!&$!!!"4!!!!88!!!&'!!!"4`!!!8J!!!&*!!!"5J!!!8X
        +!!!&-!!!"63!!!8i!!!&2!!!"8!!!!9%!!!&5!!!"8`!!!93!!!&9!!!"9J!!!9F
        +!!!&B!!!"@3!!!9S!!!&E!!!"A!!!!9d!!!&H!!!"A`!!!@!!!!&K!!!"BJ!!!@-
        +!!!&N!!!"C3!!!@B!!!&R!!!"D!!!!@N!!!&U!!!"D`!!!@`!!!&Y!!!"EJ!!!@m
        +!!!&`!!!"F3!!!A)!!!&c!!!"G!!!!A8!!!&f!!!"G`!!!AJ!!!&j!!!"HJ!!!AX
        +!!!&m!!!"I3!!!Ai!!!&r!!!"J!!!!B%!!!'#!!!"J`!!!B3!!!'&!!!"KJ!!!BF
        +!!!')!!!"L3!!!BS!!!',!!!"M!!!!Bd!!!'1!!!"M`!!!C!!!!!"N3!!!C)!!!'
        +6!!!"P!!!!C8!!!'@!!!"P`!!!CJ!!!'C!!!"QJ!!!CX!!!'F!!!"R3!!!Ci!!!'
        +I!!!"S!!!!D%!!!'L!!!"S`!!!D3!!!'P!!!"TJ!!!DF!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'S!!!"`!%!!!!"!!'
        +S!3!"SJ%!!D-"!!'S!3!"S3%!!D!"!!!,!3!!$!%!!!S"!!!0!3!!$J%!!!m"!!!
        +3!3!!%3%!!")"!!!6!3!!&!%!!"8"!!!@!3!!&`%!!"J"!!!C!3!!'J%!!"X"!!!
        +F!3!!(3%!!"i"!!!I!3!!)!%!!#%"!!!L!3!!)`%!!#3"!!!P!3!!*J%!!#F"!!!
        +S!3!!+3%!!#S"!!!V!3!!,!%!!#d"!!!Z!3!!,`%!!$!"!!!a!3!!-J%!!$-"!!!
        +d!3!!03%!!$B"!!!h!3!!1!%!!$N"!!!k!3!!1`%!!$`"!!!p!3!!2J%!!$m"!!"
        +!!3!!33%!!%)"!!"$!3!!4!%!!%8"!!"'!3!!4`%!!%J"!!"*!3!!5J%!!%X"!!"
        +-!3!!63%!!%i"!!"2!3!!8!%!!&%"!!"5!3!!8`%!!&3"!!"9!3!!9J%!!&F"!!"
        +B!3!!@3%!!&S"!!"E!3!!A!%!!&d"!!"H!3!!A`%!!'!"!!"K!3!!BJ%!!'-"!!"
        +N!3!!C3%!!'B"!!"R!3!!D!%!!'N"!!"U!3!!D`%!!'`"!!"Y!3!!EJ%!!'m"!!"
        +`!3!!F3%!!()"!!"c!3!!G!%!!(8"!!"f!3!!G`%!!(J"!!"j!3!!HJ%!!(X"!!"
        +m!3!!I3%!!(i"!!"r!3!!J!%!!)%"!!##!3!!J`%!!)3"!!#&!3!!KJ%!!)F"!!#
        +)!3!!L3%!!)S"!!#,!3!!M!%!!)d"!!#1!3!!M`%!!*!!!3!"TJ%!!*%"!!#5!3!
        +!N`%!!*3"!!#9!3!!PJ%!!*F"!!#B!3!!Q3%!!*S"!!#E!3!!R!%!!*d"!!#H!3!
        +!R`%!!+!"!!#K!3!!SJ%!!+-"!!#N!3!!T3%!!+B"!!#R!3!!U!%!!+N"!!#U!3!
        +!U`%!!+`"!!#Y!3!!VJ%!!+m"!!#`!3!!X3%!!,)"!!#c!3!!Y!%!!,8"!!#f!3!
        +!Y`%!!,J"!!#j!3!!ZJ%!!,X"!!#m!3!![3%!!,i"!!#r!3!!`!%!!-%"!!$#!3!
        +!``%!!-3"!!$&!3!!aJ%!!-F"!!$)!3!!b3%!!-S"!!$,!3!!c!%!!-d"!!$1!3!
        +!c`%!!0!"!!$4!3!!dJ%!!0-"!!$8!3!!e3%!!0B"!!$A!3!!f!%!!0N"!!$D!3!
        +!f`%!!0`"!!$G!3!!hJ%!!0m"!!$J!3!!i3%!!1)"!!$M!3!!j!%!!18"!!$Q!3!
        +!j`%!!1J"!!$T!3!!kJ%!!1X"!!$X!3!!l3%!!1i"!!$[!3!!m!%!!2%"!!$b!3!
        +!m`%!!23"!!$e!3!!pJ%!!2F"!!$i!3!!q3%!!2S"!!$l!3!!r!%!!2d"!!$q!3!
        +!r`%!!3!"!!%"!3!"!J%!!3-"!!%%!3!""3%!!3B"!!%(!3!"#!%!!3N"!!%+!3!
        +"#`%!!3`"!!%0!3!"$J%!!3m"!!%3!3!"%3%!!4)"!!%6!3!"&!%!!48"!!%@!3!
        +"&`%!!4J"!!%C!3!"'J%!!4X"!!%F!3!"(3%!!4i"!!%I!3!")!%!!5%"!!%L!3!
        +")`%!!53"!!%P!3!"*J%!!5F"!!%S!3!"+3%!!5S"!!%V!3!",!%!!5d"!!%Z!3!
        +",`%!!6!"!!%a!3!"-J%!!6-"!!%d!3!"03%!!6B"!!'R!3!"0`%!!6J"!!%j!3!
        +"1J%!!6X"!!%m!3!"23%!!6i"!!%r!3!"3!%!!8%"!!&#!3!"3`%!!83"!!&&!3!
        +"4J%!!8F"!!&)!3!"53%!!8S"!!&,!3!"6!%!!8d"!!&1!3!"6`%!!9!"!!&4!3!
        +"8J%!!9-"!!&8!3!"93%!!9B"!!&A!3!"@!%!!9N"!!&D!3!"@`%!!9`"!!&G!3!
        +"AJ%!!9m"!!&J!3!"B3%!!@)"!!&M!3!"C!%!!@8"!!&Q!3!"C`%!!@J"!!&T!3!
        +"DJ%!!@X"!!&X!3!"E3%!!@i"!!&[!3!"F!%!!A%"!!&b!3!"F`%!!A3"!!&e!3!
        +"GJ%!!AF"!!&i!3!"H3%!!AS"!!&l!3!"I!%!!Ad"!!&q!3!"J!%!!B%"!!'#!3!
        +"J`%!!B3"!!'&!3!"KJ%!!BF"!!')!3!"L3%!!BS"!!',!3!"M!%!!Bd"!!'1!3!
        +"M`%!!C!!!3!"N3%!!C)"!!'6!3!"P!%!!C8"!!'@!3!"P`%!!CJ"!!'C!3!"QJ%
        +!!CX"!!'F!3!"R3%!!Ci"!!'I!3!"T!%!!Am"!!!"!3!!"!%!!!-"!!!#!3!!#3%
        +!!!8"!!!'!3!!"`%!!!J"!!'P!!!"U3!"!#J!!!!JrrrjT!!""!!!!!!!!!!!!!!
        +!!!!!!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!"1NKjF'9
        +b3f&bC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,
        +#4r!!!J!!!!!!!!!!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!J!!!3!!!!!&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!
        +&3!!!#!!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!3!!!2rrrrm!!!!$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!"!!!!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dN
        +kD@jME(9NC6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!
        +"1MSk4e9656TXD@)k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrr
        +r3!!!"3!#!!%k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!3!!!2rrrrp!!!!'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!"!!!!rrrrrd!!!!F!#J!!6@&M6e-J8&"$)%aTEQYPFJ!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6h"PEP066#"38%-!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@0
        +28b"38%-J6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!H39"36!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!"J!!!!3A"`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69"-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%P
        +YF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!"J!!!!8P053`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!9%9B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
        +$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!9%9B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
        +$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!9%9B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
        +$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!9%9B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80
        +[C'8J3fpZGQ9bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!3!!!!9%9B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"
        +3FQ9`FQpMCA0cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!9%9B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&
        +cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!
        +!!!#!!!!!9%9B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp
        +$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!
        +!!!#!!!!!9%9B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jc!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!8&"$3A0Y!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!9%9B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfi
        +J8(*PF(*[Bf9cFfpb!!!!!!!!!!!!!!!!!!#!!!!!@%024J!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!@%024NBJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!
        +!!!!!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FR0bB`!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%P
        +YF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Fh4eBJ!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!!!!8"!3!"!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!"J!!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3!"!!!!!3%
        +"!3%!!3%!!!!!!!%"!!!"!3!"!!!"!!%!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N
        +!!"G0B@028b"8EfpXBQpi)%4&3P9()$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!r2cmr39"36!!!!B"B`!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!$mr2cm!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQP
        +i,QJ!!!!!!!!!!!!!!!!"!!!"!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!
        +!"!!!!!!!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8e
        +PFQGP)%peG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%
        +!!3%!!3%"!!!"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!G2F'9
        +Z8e0-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!
        +!!&M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!%r2cmr!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8
        +R)#G%394"*b!R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!J!!!3!!!!%#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!)!!!)!!!!#!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!%!!!!!!!!!!!#!!!$!!!
        +!!`)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!"!!!!!!!!!!!!J!!"!!!!!3#!3!!!!!
        +!!3!"!`!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!8!!!!&!J%!!!!!!!%!!3-!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!'!!!!"J)"!!!!!!!"!!%$!!!!!!!!!!!!!!!
        +!"3!!!!!!!!!!!J!!"`!!!!F#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!!J!!!!)!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!&!!!!!!!!!!!#!!!*!!!
        +!#3)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!"3!!!!!!!!!!!J!!#J!!!Am#!3!!!!!
        +!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!!X!!!'U!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!-!!!"U`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!$3!!!D`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!!i!!!'Y!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!2!!!
        +"VJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!%!!!!Dm#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!"%!!!'`!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!5!!!"X3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!%`!!!E)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!"3!!!'c!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!9!!!
        +"Y!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!&J!!!E8#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!"F!!!'f!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!B!!!"Y`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!'3!!!EJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!"S!!!'j!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!E!!!
        +"ZJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!(!!!!EX#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!"d!!!'m!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!H!!!"[3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!(`!!!Ei#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!#!!!!'r!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!K!!!
        +"`!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!)J!!!F%#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!#-!!!(#!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!N!!!"``)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!*3!!!F3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!#B!!!(&!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!R!!!
        +"aJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!+!!!!FF#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!#N!!!()!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!U!!!"b3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!+`!!!FS#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!#`!!!(,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!Y!!!
        +"c!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!J!!,J!!!D8#!3!!!!!
        +!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!)!!#m!!!(0!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!#!!!`!!!"cJ)"!!!!!!!"!!%$!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!J!!-3!!!Fm#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!)!!$)!!!(3!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!#!!!c!!!
        +"d33"!!!!!!!!!!%$!!!!!!!!!!!!!!!!J3!!!!!!!!!!!J!!0!!!!G)%!3!!!!!
        +!!!!"!`!!!!!!!!!!!!!!!)%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!
        +!"3!!!!B!!!!(!!!!#!!!!!N!!!!Y!!!!#J!!!!X!!!!-!!!!$3!!!!i!!!!2!!!
        +!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S!!!!E!!!
        +!(!!!!"d!!!!H!!!!(`!!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B!!!!R!!!
        +!+!!!!#N!!!!U!!!!+`!!!#`!!!!Z!!!!,`!!!$!!!!!a!!!!-J!!!$-!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!d!!!
        +!3!)!!!!#!!!d!J!!(!)!!"d#!!!H!J!!(`)!!#!#!!!K!J!!)J)!!#-#!!!N!J!
        +!*3)!!#B#!!!R!J!!+!)!!#N#!!!U!J!!+`)!!#`#!!!Y!J!!#`)!!!`#!!!0!J!
        +!$J)!!!m#!!!3!J!!%3)!!")#!!!6!J!!&!)!!"8#!!!@!J!!&`)!!"J#!!!C!J!
        +!'J)!!"X#!!!c!J!!0!)!!#m#!!!`!J!!-J)!!$%#!!!+!J!!!3)!!!3#!!!$!J!
        +!!J)!!!N#!!!&!J!!"J)!!!F#!!!)!J!!,J!!!DN!!3!S!J!!%`)!!"3#!!!9!J!
        +!&J)!!"F#!!!B!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#`MlJ!!!
        +!!!!!!3!#`NI`!!)!!!!!!!!!!!!!!X)fJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!)!!!%!!!!!"3!!Irm!!!!!Irm!!!!!Irm!!!!!Irm!!!!-!!%
        +!!J!%!!!!"8!!!!B!!3!"1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!%!!!$rrrrr!!!!!`!"!!%k1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrm!!!!%!!%!!6SkD@jME(9NC6S!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!)!!3!"1J!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!`!#!!%
        +k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp
        +!!!!%!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +"!!!!rrrrrd!!!!8!#J!!6@&M6e-J0MK,)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!4f9d5&488&-J0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b!f1%XJ6'P
        +ZDf9b!!!!!!!!!!!!!!!!!!!!!!!J39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"
        +`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"
        +-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!6d*
        ++)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"A)%PYF'pbG#!f1%X
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%a[BJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P0
        +53`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9
        +bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9
        +B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0
        +cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
        +B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
        +B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jcC@F!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9
        +cFfpb!!!!!!!!!!!!!!!!!!#!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FR0
        +bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Fh4
        +eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!!!!!
        +!!#jbFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!
        +!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3%"!!!!!3%"!!!"!3%!!!!
        +!!!%"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!!e(CA4)9&4
        +38bJf1%XT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!r2cmr39"36!!!!J"B`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!0!!%!!!!!!""I69G&8NY6Ah"bC@CTH#jS!!!!!!!!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0
        +dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!
        +"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!K(CA4)9&438`!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cm
        +r!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!
        +R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!`!!!3!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!!)!!!!
        +,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!$!!!!$!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!"!!!!!d#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!!8!!!!1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!'!!!!$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!"`!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!!J!!!!
        +4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!*!!!!%J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!#J!!!"-#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!!X!!!!8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!-!!!!&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!$3!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!!i!!!!
        +A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!2!!!!'!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!%!!!!"N#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!"%!!!!D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!5!!!!'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!%`!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!"3!!!!
        +G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!9!!!!(J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!&J!!!"m#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!"F!!!!J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!B!!!!)3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!'3!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!"S!!!!
        +M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!E!!!!*!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!(!!!!#8#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!"d!!!!Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!H!!!!*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!(`!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!#!!!!!
        +T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!K!!!!+J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!)J!!!#X#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!#-!!!!X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!N!!!!,3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!*3!!!#i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!#B!!!!
        +[!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!R!!!!-!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!+!!!!$%#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!#N!!!!b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!U!!!!-`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!+`!!!$3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!#`!!!!
        +e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!Y!!!!0J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!,J!!!$F#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!#m!!!!i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!`!!!!13)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!-3!!!$S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!$)!!!!
        +l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!c!!!!2!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!0!!!!$d#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!$8!!!!q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!f!!!!2`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!0`!!!%!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!$J!!!"
        +"!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!j!!!!3J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!1J!!!%-#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!$X!!!"%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!!m!!!!43)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!23!!!%B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!$i!!!"
        +(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!!r!!!!5!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!3!!!!%N#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!%%!!!"+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"#!!!!5`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!3`!!!%`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!%3!!!"
        +0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"&!!!!6J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!4J!!!%m#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!%F!!!"3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!")!!!!83)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!53!!!&)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!%S!!!"
        +6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!",!!!!9!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!6!!!!&8#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!%d!!!"@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"1!!!!9`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!6`!!!&J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!&!!!!"
        +C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"4!!!!@J)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!8J!!!&X#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!&-!!!"F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"8!!!!A3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!93!!!&i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!&B!!!"
        +I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"A!!!!B!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!@!!!!'%#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!&N!!!"L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"D!!!!B`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!@`!!!'3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!&`!!!"
        +P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"G!!!!CJ)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!AJ!!!'F#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!&m!!!"S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"J!!!!D3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!B3!!!'S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!')!!!"
        +V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"M!!!!E!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!C!!!!'d#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!'8!!!"Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"Q!!!!E`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!C`!!!(!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!'J!!!"
        +a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"T!!!!FJ)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!DJ!!!(-#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!'X!!!"d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"X!!!!G3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!E3!!!(B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!'i!!!"
        +h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"[!!!!H!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!F!!!!(N#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!(%!!!"k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"b!!!!H`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!F`!!!(`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!(3!!!"
        +p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"e!!!!IJ)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!GJ!!!(m#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!(F!!!#!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"i!!!!J3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!H3!!!))#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!(S!!!#
        +$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!"l!!!!K!)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!I!!!!)8#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!(d!!!#'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!"q!!!!K`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!I`!!!)J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)!!!!#
        +*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#"!!!!LJ)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!JJ!!!)X#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!-!!)-!!!#-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!$!!#%!!!!M3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!!`!!K3!!!)i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)B!!!#
        +2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#(!!!!N!!#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)J!!!#4!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!$!!#*!!!!NJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!`!!LJ!!!*-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!-!!)X!!!#8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#-!!!
        +!P3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!M3!!!*B#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!)i!!!#A!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!$!!#2!!!!Q!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!!`!!N!!!!!#C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#4!!!!QJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!NJ!
        +!!*X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!*-!!!#F!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#8!!!!R3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!P3!!!*i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!*B!!!#I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#A!!!!S!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!Q!!
        +!!+%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!*N!!!#L!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#D!!!!S`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!Q`!!!+3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!*`!!!#P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#G!!!!TJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!RJ!
        +!!+F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!*m!!!#S!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#J!!!!U3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!S3!!!+S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!+)!!!#V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#M!!!!V!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!T!!
        +!!+d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!+8!!!#Z!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#Q!!!!V`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!T`!!!,!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!+J!!!#a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#T!!!!XJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!UJ!
        +!!,-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!+X!!!#d!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#X!!!!Y3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!V3!!!,B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!+i!!!#h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#[!!!!Z!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!X!!
        +!!,N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!,%!!!#k!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#b!!!!Z`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!X`!!!,`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!,3!!!#p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#e!!!![J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!YJ!
        +!!,m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!,F!!!$!!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#i!!!!`3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!Z3!!!-)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!,S!!!$$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!#l!!!!a!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!![!!
        +!!-8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!,d!!!$'!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!#q!!!!a`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!![`!!!-J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!-!!!!$*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$"!!!!bJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!`J!
        +!!-X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!--!!!$-!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$%!!!!c3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!a3!!!-i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!-B!!!$2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$(!!!!d!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!b!!
        +!!0%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!-N!!!$5!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$+!!!!d`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!b`!!!03#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!-`!!!$9!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$0!!!!eJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!cJ!
        +!!0F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!-m!!!$B!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$3!!!!f3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!d3!!!0S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!0)!!!$E!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$6!!!!h!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!e!!
        +!!0d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!08!!!$H!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$@!!!!h`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!e`!!!1!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!0J!!!$K!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$C!!!!iJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!fJ!
        +!!1-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!0X!!!$N!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$F!!!!j3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!h3!!!1B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!0i!!!$R!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$I!!!!k!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!i!!
        +!!1N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!1%!!!$U!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$L!!!!k`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!i`!!!1`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!13!!!$Y!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$P!!!!lJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!jJ!
        +!!1m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!1F!!!$`!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$S!!!!m3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!k3!!!2)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!1S!!!$c!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$V!!!!p!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!l!!
        +!!28#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!1d!!!$f!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$Z!!!!p`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!l`!!!2J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!2!!!!$j!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$a!!!!qJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!mJ!
        +!!2X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!2-!!!$m!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$d!!!!r3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!p3!!!2i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!2B!!!$r!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$h!!!"!!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!q!!
        +!!3%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!2N!!!%#!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!$k!!!"!`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!!q`!!!33#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!2`!!!%&!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!$p!!!""J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!!rJ!
        +!!3F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!2m!!!%)!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%!!!!"#3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"!3!!!3S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!3)!!!%,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%$!!!"$!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!""!!
        +!!3d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!38!!!%1!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%'!!!"$`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!""`!!!4!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!3J!!!%4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%*!!!"%J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"#J!
        +!!4-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!3X!!!%8!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%-!!!"&3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"$3!!!4B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!3i!!!%A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%2!!!"'!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"%!!
        +!!4N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!4%!!!%D!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%5!!!"'`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"%`!!!4`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!43!!!%G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%9!!!"(J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"&J!
        +!!4m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!4F!!!%J!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%B!!!")3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"'3!!!5)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!4S!!!%M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%E!!!"*!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"(!!
        +!!58#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!4d!!!%Q!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%H!!!"*`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"(`!!!5J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!5!!!!%T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%K!!!"+J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!")J!
        +!!5X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!5-!!!%X!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%N!!!",3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"*3!!!5i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!5B!!!%[!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%R!!!"-!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"+!!
        +!!6%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!5N!!!%b!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%U!!!"-`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"+`!!!63#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!5`!!!%e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%Y!!!"0J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!",J!
        +!!6F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!5m!!!%i!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%`!!!"13)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"-3!!!6S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!6)!!!%l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%c!!!"2!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"0!!
        +!!6d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!68!!!%q!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%f!!!"2`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"0`!!!8!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!6J!!!&"!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%j!!!"3J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"1J!
        +!!8-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!6X!!!&%!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!%m!!!"43)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"23!!!8B#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!6i!!!&(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!%r!!!"5!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"3!!
        +!!8N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!8%!!!&+!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&#!!!"5`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"3`!!!8`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!83!!!&0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&&!!!"6J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"4J!
        +!!8m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!8F!!!&3!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&)!!!"83)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"53!!!9)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!8S!!!&6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&,!!!"9!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"6!!
        +!!98#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!8d!!!&@!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&1!!!"9`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"6`!!!9J#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!9!!!!&C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&4!!!"@J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"8J!
        +!!9X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!9-!!!&F!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&8!!!"A3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"93!!!9i#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!9B!!!&I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&A!!!"B!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"@!!
        +!!@%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!9N!!!&L!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&D!!!"B`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"@`!!!@3#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!9`!!!&P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&G!!!"CJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"AJ!
        +!!@F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!9m!!!&S!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&J!!!"D3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"B3!!!@S#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!@)!!!&V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&M!!!"E!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"C!!
        +!!@d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!@8!!!&Z!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&Q!!!"E`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"C`!!!A!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!@J!!!&a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&T!!!"FJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"DJ!
        +!!A-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!@X!!!&d!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&X!!!"G3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"E3!!!AB#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!@i!!!&h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&[!!!"H!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"F!!
        +!!AN#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!A%!!!&k!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&b!!!"H`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"F`!!!A`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!A3!!!&p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&e!!!"IJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"GJ!
        +!!B!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!AF!!!'"!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&i!!!"JJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"H3!!!B-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!AS!!!'%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!&l!!!"K3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"I!!
        +!!BB#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!Ad!!!'(!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!&q!!!"L!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"I`!!!BN#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!B!!!!'+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!$!!'"!!!"L`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"JJ!
        +!!B`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!B-!!!'0!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'%!!!"MJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!!`!"K3!!!Bm#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!-!!BB!!!'3!!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!!`!"K`!!!C%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!BJ
        +!!!'5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'*!!!"N`)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"LJ!!!C3#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!BX!!!'9!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!$!!'-!!!"PJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!!`!"M3!!!CF#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!Bi
        +!!!'B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'2!!!"Q3)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"N!!!!!'D!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'4!!!"Q`)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!`!"NJ!!!C`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!-!!C-!!!'G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'
        +8!!!"RJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"P3!!!Cm#!3!
        +!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!CB!!!'J!J%!!!!!!!%!!3%
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'A!!!"S3)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!`!"Q!!!!D)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!-!!CN!!!'M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'
        +D!!!"d`)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"Q`!!!G3#!3!
        +!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!C`!!!(9!J%!!!!!!!%!!3-
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'G!!!"eJ)"!!!!!!!"!!%$!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!`!"RJ!!!D3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!-!!Cm!!!(A!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'
        +J!!!"f!)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!!!!!!!!!!!`!"S3!!!GN#!3!
        +!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!-!!D)!!!(D!J%!!!!!!!%!!3-
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!$!!'M!!!"TJ)"!!!!!!!"!!%"!!!!!!!!!!!
        +!!!!!!3!!!!!!!!!!!`!"T!!!!DF#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!-!!D8!!!'S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!)!!!!$!!!!"!!!!!8!!!!
        +'!!!!"`!!!!J!!!!*!!!!#J!!!!X!!!!-!!!!$3!!!!i!!!!2!!!!%!!!!"%!!!!
        +5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S!!!!E!!!!(!!!!"d!!!!
        +H!!!!(`!!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B!!!!R!!!!+!!!!#N!!!!
        +U!!!!+`!!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!$)!!!!c!!!!0!!!!$8!!!!
        +f!!!!0`!!!$J!!!!j!!!!1J!!!$X!!!!m!!!!23!!!$i!!!!r!!!!3!!!!%%!!!"
        +#!!!!3`!!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S!!!",!!!!6!!!!%d!!!"
        +1!!!!6`!!!&!!!!"4!!!!8J!!!&-!!!"8!!!!93!!!&B!!!"A!!!!@!!!!&N!!!"
        +D!!!!@`!!!&`!!!"G!!!!AJ!!!&m!!!"J!!!!B3!!!')!!!"M!!!!C!!!!'8!!!"
        +Q!!!!C`!!!'J!!!"T!!!!DJ!!!'X!!!"X!!!!E3!!!'i!!!"[!!!!F!!!!(%!!!"
        +b!!!!F`!!!(3!!!"e!!!!GJ!!!(F!!!"i!!!!H3!!!(S!!!"l!!!!I!!!!(d!!!"
        +q!!!!I`!!!)!!!!#"!!!!JJ!!!)-!!!#%!!!!K3!!!)B!!!#(!!!!L!!!!)N!!!#
        ++!!!!L`!!!)`!!!#0!!!!MJ!!!)m!!!#3!!!!!*%!!!#5!!!!N`!!!*3!!!#9!!!
        +!PJ!!!*F!!!#B!!!!Q3!!!*S!!!#E!!!!R!!!!*d!!!#H!!!!R`!!!+!!!!#K!!!
        +!SJ!!!+-!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!+N!!!#U!!!!U`!!!+`!!!#Y!!!
        +!VJ!!!+m!!!#`!!!!X3!!!,)!!!#c!!!!Y!!!!,8!!!#f!!!!Y`!!!,J!!!#j!!!
        +!ZJ!!!,X!!!#m!!!![3!!!,i!!!#r!!!!`!!!!-%!!!$#!!!!``!!!-3!!!$&!!!
        +!aJ!!!-F!!!$)!!!!b3!!!-S!!!$,!!!!c!!!!-d!!!$1!!!!c`!!!0!!!!$4!!!
        +!dJ!!!0-!!!$8!!!!e3!!!0B!!!$A!!!!f!!!!0N!!!$D!!!!f`!!!0`!!!$G!!!
        +!hJ!!!0m!!!$J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$Q!!!!j`!!!1J!!!$T!!!
        +!kJ!!!1X!!!$X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$b!!!!m`!!!23!!!$e!!!
        +!pJ!!!2F!!!$i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$q!!!!r`!!!3!!!!%"!!!
        +"!J!!!3-!!!%%!!!""3!!!3B!!!%(!!!"#!!!!3N!!!%+!!!"#`!!!3`!!!%0!!!
        +"$J!!!3m!!!%3!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%@!!!"&`!!!4J!!!%C!!!
        +"'J!!!4X!!!%F!!!"(3!!!4i!!!%I!!!")!!!!5%!!!%L!!!")`!!!53!!!%P!!!
        +"*J!!!5F!!!%S!!!"+3!!!5S!!!%V!!!",!!!!5d!!!%Z!!!",`!!!6!!!!%a!!!
        +"-J!!!6-!!!%d!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%k!!!"1`!!!6`!!!%p!!!
        +"2J!!!6m!!!&!!!!"33!!!8)!!!&$!!!"4!!!!88!!!&'!!!"4`!!!8J!!!&*!!!
        +"5J!!!8X!!!&-!!!"63!!!8i!!!&2!!!"8!!!!9%!!!&5!!!"8`!!!93!!!&9!!!
        +"9J!!!9F!!!&B!!!"@3!!!9S!!!&E!!!"A!!!!9d!!!&H!!!"A`!!!@!!!!&K!!!
        +"BJ!!!@-!!!&N!!!"C3!!!@B!!!&R!!!"D!!!!@N!!!&U!!!"D`!!!@`!!!&Y!!!
        +"EJ!!!@m!!!&`!!!"F3!!!A)!!!&c!!!"G!!!!A8!!!&f!!!"G`!!!AJ!!!&j!!!
        +"HJ!!!AX!!!&m!!!"I3!!!Ai!!!&r!!!"J!!!!B%!!!'#!!!"J`!!!B3!!!'&!!!
        +"KJ!!!BF!!!')!!!"L3!!!BS!!!',!!!"M!!!!Bd!!!'1!!!"M`!!!C!!!!!"N3!
        +!!C)!!!'6!!!"P!!!!C8!!!'@!!!"P`!!!CJ!!!'G!!!"SJ!!!D-!!!'N!!!"Q3!
        +!!CS!!!'E!!!"R!!!!Ci!!!'I!!!"S!!!!D%!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'P!!!"`!-
        +!!!!$!!'P!!!"f`!"!"`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$!!'B!`!"Q3-
        +!!D8$!!'A!`!"PJ-!!!)$!!!$!`!!!3-!!!3$!!!&!`!!"J-!!!F$!!!)!`!!#3-
        +!!!S$!!!,!`!!$!-!!!d$!!!1!`!!$`-!!"!$!!!4!`!!%J-!!"-$!!!8!`!!&3-
        +!!"B$!!!A!`!!'!-!!"N$!!!D!`!!'`-!!"`$!!!G!`!!(J-!!"m$!!!J!`!!)3-
        +!!#)$!!!M!`!!*!-!!#8$!!!Q!`!!*`-!!#J$!!!T!`!!+J-!!#X$!!!X!`!!,3-
        +!!#i$!!![!`!!-!-!!$%$!!!b!`!!-`-!!$3$!!!e!`!!0J-!!$F$!!!i!`!!13-
        +!!$S$!!!l!`!!2!-!!$d$!!!q!`!!2`-!!%!$!!""!`!!3J-!!%-$!!"%!`!!43-
        +!!%B$!!"(!`!!5!-!!%N$!!"+!`!!5`-!!%`$!!"0!`!!6J-!!%m$!!"3!`!!83-
        +!!&)$!!"6!`!!9!-!!&8$!!"@!`!!9`-!!&J$!!"C!`!!@J-!!&X$!!"F!`!!A3-
        +!!&i$!!"I!`!!B!-!!'%$!!"L!`!!B`-!!'3$!!"P!`!!CJ-!!'F$!!"S!`!!D3-
        +!!'S$!!"V!`!!E!-!!'d$!!"Z!`!!E`-!!(!$!!"a!`!!FJ-!!(-$!!"d!`!!G3-
        +!!(B$!!"h!`!!H!-!!(N$!!"k!`!!H`-!!(`$!!"p!`!!IJ-!!(m$!!#!!`!!J3-
        +!!))$!!#$!`!!K!-!!)8$!!'M!`!!KJ-!!)F$!!#)!`!!L3-!!)S$!!#,!`!!M!-
        +!!)d$!!#1!`!!M`-!!*!!!`!!N3-!!*)$!!#6!`!!P!-!!*8$!!#@!`!!P`-!!*J
        +$!!#C!`!!QJ-!!*X$!!#F!`!!R3-!!*i$!!#I!`!!S!-!!+%$!!#L!`!!S`-!!+3
        +$!!#P!`!!TJ-!!+F$!!#S!`!!U3-!!+S$!!#V!`!!V!-!!+d$!!#Z!`!!V`-!!,!
        +$!!#a!`!!XJ-!!,-$!!#d!`!!Y3-!!,B$!!#h!`!!Z!-!!,N$!!#k!`!!Z`-!!,`
        +$!!#p!`!![J-!!,m$!!$!!`!!`3-!!-)$!!$$!`!!a!-!!-8$!!$'!`!!a`-!!-J
        +$!!$*!`!!bJ-!!-X$!!$-!`!!c3-!!-i$!!$2!`!!d!-!!0%$!!$5!`!!d`-!!03
        +$!!$9!`!!eJ-!!0F$!!$B!`!!f3-!!0S$!!$E!`!!h!-!!0d$!!$H!`!!h`-!!1!
        +$!!$K!`!!iJ-!!1-$!!$N!`!!j3-!!1B$!!$R!`!!k!-!!1N$!!$U!`!!k`-!!1`
        +$!!$Y!`!!lJ-!!1m$!!$`!`!!m3-!!2)$!!$c!`!!p!-!!28$!!$f!`!!p`-!!2J
        +$!!$j!`!!qJ-!!2X$!!$m!`!!r3-!!2i$!!$r!`!"!!-!!3%$!!%#!`!"!`-!!33
        +$!!%&!`!""J-!!3F$!!%)!`!"#3-!!3S$!!%,!`!"$!-!!3d$!!%1!`!"$`-!!4!
        +$!!%4!`!"%J-!!4-$!!%8!`!"&3-!!4B$!!%A!`!"'!-!!4N$!!%D!`!"'`-!!4`
        +$!!%G!`!"(J-!!4m$!!%J!`!")3-!!5)$!!%M!`!"*!-!!58$!!%Q!`!"*`-!!5J
        +$!!%T!`!"+J-!!5X$!!%X!`!",3-!!D3$!!%Z!`!",`-!!6!$!!%a!`!"-J-!!6-
        +$!!%d!`!"03-!!6B$!!%h!`!"1!-!!6N$!!%k!`!"1`-!!6`$!!%p!`!"2J-!!6m
        +$!!&!!`!"33-!!8)$!!&$!`!"4!-!!88$!!&'!`!"4`-!!8J$!!&*!`!"5J-!!8X
        +$!!&-!`!"63-!!8i$!!&2!`!"8!-!!9%$!!&5!`!"8`-!!93$!!&9!`!"9J-!!9F
        +$!!&B!`!"@3-!!9S$!!&E!`!"A!-!!9d$!!&H!`!"A`-!!@!$!!&K!`!"BJ-!!@-
        +$!!&N!`!"C3-!!@B$!!&R!`!"D!-!!@N$!!&U!`!"D`-!!@`$!!&Y!`!"EJ-!!@m
        +$!!&`!`!"F3-!!A)$!!&c!`!"G!-!!A8$!!&f!`!"G`-!!AJ$!!&j!`!"HJ-!!AX
        +$!!&m!`!"I3-!!Ai$!!&r!`!"J!-!!B%$!!'#!`!"J`-!!B3$!!'&!`!"KJ-!!BF
        +$!!')!`!"L3-!!BS$!!',!`!"M!-!!Bd$!!'1!`!"M`-!!C!!!`!"N3-!!C)$!!'
        +6!`!"P!-!!C8$!!'H!`!"S!-!!D%$!!'E!`!"SJ-!!CS$!!'F!`!"R3-!!Cm!!J!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,#4r!!!J!
        +!!!!!!!!!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!J!
        +!!3!!!!!&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!&3!!!#!!
        +"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2r
        +rrrm!!!!$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!"!!!!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dNkD@jME(9
        +NC6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!"1MSk4e9
        +656TXD@)k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"3!
        +#!!%k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2r
        +rrrp!!!!'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!"!!!!rrrrrd!!!!F!#J!!6@&M6e-J0MK,)%aTEQYPFJ!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!6'PL8e0-)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b!f1%X
        +J6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!J39"36!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
        +!3A"`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!69"-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!
        +f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
        +!6d*+)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"A)%PYF'pbG#!
        +f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%a[BJ!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
        +!8P053`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!9%9B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
        +,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!9%9B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
        +,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!9%9B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
        +,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!9%9B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fp
        +ZGQ9bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!
        +!9%9B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQp
        +MCA0cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!9%9B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$B
        +i5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!
        +!9%9B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK
        +,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!
        +!9%9B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jcC@F!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!9%9B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*
        +[Bf9cFfpb!!!!!!!!!!!!!!!!!!#!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!
        +!FR0bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!Fh4eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!
        +f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!
        +!!!!!!#jbFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!"J!!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3%"!!!!!3%"!!!"!3%
        +!!!!!!!%"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!aK-D@*
        +68d`Z0MK,)%CK+$4TAcKN+5j-D@)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQPi,QJ!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!
        +!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%p
        +eG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%
        +"!!!"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!K(CA4)9&438`!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%
        +r2cmr!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394
        +"*b!R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!"!!!!3!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!)
        +!!!!,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!$!!!!$!)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!"!!!!!d#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!8!!!!1!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!%!!!'!!!!$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"!!!"`!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!J
        +!!!!4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!*!!!!%J)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!#J!!!"-#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!X!!!!8!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!%!!!-!!!!&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"!!!$3!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!!i
        +!!!!A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!2!!!!'!)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!%!!!!"N#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"%!!!!D!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!%!!!5!!!!'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"!!!%`!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"3
        +!!!!G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!9!!!!(J)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!&J!!!"m#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"F!!!!J!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!%!!!B!!!!)3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"!!!'3!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"S
        +!!!!M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!E!!!!*!)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!(!!!!#8#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!"d!!!!Q!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!%!!!H!!!!*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"!!!(`!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!#!
        +!!!!T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!%!!!K!!!!+J)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"!!!)J!!!#X#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!3!!#-!!!!X!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!!"3!!!!B
        +!!!!(!!!!#!!!!!N!!!!+!!!!#`!!!!`!!!!0!!!!$J!!!!m!!!!3!!!!%3!!!")
        +!!!!6!!!!&!!!!"8!!!!@!!!!&`!!!"J!!!!C!!!!'J!!!"X!!!!F!!!!(3!!!"i
        +!!!!I!!!!)!!!!#%!!!!L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!M!!!!3!3!!!!
        +%!!!M!!!"f`!"!"`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!&"!!!"!3!!!-
        +%!!!#"!!!"J3!!!X%!!!+"!!!#33!!!J%!!!("!!!$!3!!")%!!!4"!!!%!3!!!m
        +%!!!0"!!!$J3!!"-%!!!L"!!!)33!!#!%!!!I"!!!)`3!!!%%!!!8"!!!&33!!"B
        +%!!!A"!!!'!3!!"N%!!!D"!!!'`3!!"`%!!!G"!!!(J!#!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!X)qi!!!!!!!!!%!!X*(m!!#!!!!!!!!!!!!!!,#0S!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!"!!!!!!8!!(rr!!!
        +!!(rr!!!!!(rr!!!!!(rr!!!!$!!"!!)!"J!!!!9!!!!)!!%!!6S!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrr`!!!!-!!3!"1MS
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr!!!
        +!"!!"!!%k1QPZBfaeC'8k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!2rrrrp!!!!#!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!rrrrrd!!!!-!!3!"1MSk4e9656TTEQ0XG@4P1J!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"!!"!!%k1MT(990*1QaTBMS!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!&!!)!!6T0B@028b"6GA"
        +`Eh*d1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrrd!!!!B!!J!"1Ne
        +66$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr3!!
        +!"`!+!!"0B@028b!f1%XJ6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"2F'9Z8e0-)$BiD`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!8eKBdp6)$Bi5b"-D@jVCA)!!!!!!!!
        +!!!!!!!!!!!!!!#""8&"-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!""F("X!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!'!!!!"068a#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +-D@)J5@e`Eh*d)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!"08%a'!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"-D@)J5@e`Eh*d)$Bi5`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"09d0%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"23NSJ!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"08&FJ5@e`Eh*d)$Bi5`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"36'pL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"58e*$!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!'!!!!"849K8,Q*S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +#B@aXEfpZ)%KPE(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q-!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"849K8,Q-V+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0M!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"849K8,Q0`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0`F!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"849K8,Q9iF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,QGM!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"(B@eP3fpNC5"$EfjfCA*dCA)!!!!!!!!
        +!!!!!!!!!!%!!!!"849K8,QJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!"849K8,Q`!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"'E'9i)&"bCA"bEf0PFh0[FJ!!!!!!!!!
        +!!!!!!!!!!)!!!!"849K8,R!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +09b"3BA0MB@`J0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,R"KF`!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0MB@`J0MK,!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"849K8,R"MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R"MD#XV!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b!f1%X!!!!!!!!!!!!!!!!
        +!!!!!!!!!!)!!!!"849K8,R"`G3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +09b"3BA0MB@`J0MK,!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R)!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"5CAS!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!"849K8,R0PC`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,RN!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#DA0[EL"3FQ9`FQpMCA0cEh)!!!!!!!!
        +!!!!!!!!!!)!!!!"NEf0e!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"bFh*M!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!'!!!!"cD'aL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +348BJ5@e`Eh*d)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!"cG(9L!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"348BJ5@e`Eh*d)$Bi5`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!,Q4[B`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&!!!!!!!!!!,R*cFQ-!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!'!!!!!!"3%"!!%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!!!%!!!!!"3!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%
        +"!!"YB@PZ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!J"!!%!!!!"!3%!!!%"!3!!!!!!!3%!!!%"!!%
        +!!!%%!!!!!!!!!!!!!!J"!!%"!!%"!!!!!3!!#3!!$%p`C@j68d`S0MKV+3!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$m
        +r2cp"8&"-!!!#!&M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2`!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!d!!3!!!!!!&9p09d955e0I4e9659p`FQ9QDAJZD!!!!!!!!!!!!!!!!!%!!!!
        +!!!!!!!%!!!!!!!!!!!!!"3%"!3!!!3%!!3!!!!!%!!!!!!!!!!!!!!!!!!!!!!%
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4KFR3!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!"!!!*6@9bCf8J6h9d!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&
        +38%`!!3%!!!3J)#!J!jHI8!0fhhJ$"Di3!!8#!3!"!3!"!3%!!!%!!!!!!!!!!3%
        +"!3!"!3!"!!%%!!!!!!!!!!!!!!F"!3!"!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4
        +KFR3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!"dp`C@j68d`!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!r2cmr39"36!!!"!!!!!3!!!!!3!!!@-!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6mr2cm!!!!!!!!!!J!
        +!!!)!!J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!8!!
        +"!!%!!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3R3dp%45FJ*d4"9%%R)#G35808*`!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&!!!"!!!"Z`)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!!J!!!E`#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!!-!!!'p!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!&!!!%!!!"[J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!"3!!"3!!!Em#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
        +!!!B!!!(!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!(!!!"`3)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!#!!!!F)#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!!N!!!($!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!&!!!+!!!"a!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!"3!!#`!!!F8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
        +!!!`!!!('!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!0!!!"a`)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!$J!!!FJ#!3!!!!!!!3!
        +"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!!m!!!(*!J%!!!!!!!%!!3%!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!&!!!3!!!"bJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!"3!!%3!!!FX#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
        +!!")!!!(-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!6!!!"c3)
        +"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!&!!!!G`#!3!!!!!!!3!
        +"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!"8!!!(G!J%!!!!!!!%!!3-!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!&!!!@!!!"hJ)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!"3!!&`!!!G-#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
        +!!"J!!!(D!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!C!!!"e3)
        +"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!!!!!!!!!!"3!!'J!!!GB#!3!!!!!!!3!
        +"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8!!"X!!!(A!J%!!!!!!!%!!3-!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!&!!!F!!!"e!)"!!!!!!!"!!%$!!!!!!!!!!!!!!!!!3!
        +!!!!!!!!!"3!!(3!!!GJ#!3!!!!!!!3!"!`!!!!!!!!!!!!!!!!%!!!!!!!!!!!8
        +!!"i!!!(C!J%!!!!!!!%!!3-!!!!!!!!!!!!!!!!"!!!!!!!!!!!&!!!I!!!"h`3
        +"!!!!!!!!!!%$!!!!!!!!!!!!!!!!J3!!!!!!!!!!"3!!)!!!!H!#!3!!!!!!!3!
        +"!`!!!!!!!!!!!!!!!)%!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!!"3!
        +!!!B!!!!(!!!!#!!!!!N!!!!+!!!!#`!!!!`!!!!0!!!!$J!!!!m!!!!3!!!!%3!
        +!!")!!!!@!!!!'`!!!"J!!!!C!!!!'J!!!"`!!!!G!!!!&`!!!"-!!!!8!!!!&3!
        +!!"i!!!!I!!!!)!!!!#!&!!!!"3!!)!!!!GX!!3!F!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!"3!!!38!!!)&!!!$"3!!"!8!!!8&!!!'"3!!"`8!!!J&!!!*"3!!#J8
        +!!!X&!!!-"3!!$38!!!i&!!!2"3!!%!8!!"%&!!!5"3!!)!8!!"m&!!!6"3!!&!8
        +!!"8&!!!@"3!!(38!!"i&!!!F"3!!'!8!!"F&!!!C"3!!'J8!!"X!!J!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,#4r!!!J!!!!!!!!!
        +!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!J!!!3!!!!!
        +&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!&3!!!#!!"!!%k!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrm!!!!
        +$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!
        +!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dNkD@jME(9NC6S!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!"1MSk4e9656TXD@)
        +k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"3!#!!%k6@&
        +M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp!!!!
        +'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!
        +!rrrrrd!!!!F!#J!!6@&M6e-J8&"$)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!6'PL8e0-)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b"38%-J6'PZDf9
        +b!!!!!!!!!!!!!!!!!!!!!!!H39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"`E!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"-4J!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#"38%-!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P053`!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
        +M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
        +MB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
        +MF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
        +RB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9bG'9
        +b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9B9#j
        +X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0cEh)
        +!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
        +`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j
        +`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ8&"$!!!!!!!
        +!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!69FJ8'&cBf&X)&"33`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j
        +b!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jc!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!8&"$3A0Y!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j
        +j!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9cFfp
        +b!!!!!!!!!!!!!!!!!!#!!!!!@%024J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!@%024NBJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!C'pMG3!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!"J!!!!FR0bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!Fh4eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!8%9')%PYF'pbG#"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#j
        +NEf-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!"3!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!
        +"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3%"!!!!!3%"!!!"!3%!!!!!!!%
        +"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!aK-D@*68d`Z0MK
        +,)%CK+$KTAc4N+5j-D@)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQPi,QJ!!!!!!!!!!!!
        +!!!!"!!!"!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0dBA*
        +d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!"!!!
        +!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!`j-D@*68d`Z8&"$,NaTBJ!
        +!!!!!!!!!!!!!!!!!!!!!2cmr2cmr2cm!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cmr!!!
        +!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!R8%P
        +$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!
        +!!3!!!!S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!!)!!!!,!J%
        +!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!$!!!!$!)"!!!!!!!"!!%
        +"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!"!!!!!d#!3!!!!!!!3!"!3!!!!!!!!!
        +!!!!!!!%!!!!!!!!!!!B!!!8!!!!1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
        +!!!!!!!!'!!!'!!!!$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
        +!"`!!!"!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!!J!!!!4!J%
        +!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!*!!!!%J)"!!!!!!!"!!%
        +"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!#J!!!"-#!3!!!!!!!3!"!3!!!!!!!!!
        +!!!!!!!%!!!!!!!!!!!B!!!X!!!!8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
        +!!!!!!!!'!!!-!!!!&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
        +!$3!!!"B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!!i!!!!A!J%
        +!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!2!!!!'!)"!!!!!!!"!!%
        +"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!%!!!!"N#!3!!!!!!!3!"!3!!!!!!!!!
        +!!!!!!!%!!!!!!!!!!!B!!"%!!!!D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
        +!!!!!!!!'!!!5!!!!'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
        +!%`!!!"`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!"3!!!!G!J%
        +!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!9!!!!(J)"!!!!!!!"!!%
        +"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!&J!!!"m#!3!!!!!!!3!"!3!!!!!!!!!
        +!!!!!!!%!!!!!!!!!!!B!!"F!!!!J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
        +!!!!!!!!'!!!B!!!!)3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
        +!'3!!!#)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!"S!!!!M!J%
        +!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!E!!!!*!)"!!!!!!!"!!%
        +"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!(!!!!#8#!3!!!!!!!3!"!3!!!!!!!!!
        +!!!!!!!%!!!!!!!!!!!B!!"d!!!!Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
        +!!!!!!!!'!!!H!!!!*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!
        +!(`!!!#J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!B!!#!!!!!T!J%
        +!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!'!!!K!!!!+J)"!!!!!!!"!!%
        +"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"J!!)J!!!#X#!3!!!!!!!3!"!3!!!!!!!!!
        +!!!!!!!%!!!!!!!!!!!B!!#-!!!!X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!J!!!!-!!!!%!!!!"3!!!!B!!!!(!!!
        +!#!!!!!N!!!!+!!!!#`!!!!`!!!!0!!!!$J!!!!m!!!!3!!!!%3!!!")!!!!6!!!
        +!&!!!!"8!!!!@!!!!&`!!!"J!!!!C!!!!'J!!!"X!!!!F!!!!(3!!!"i!!!!I!!!
        +!)!!!!#%!!!!L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!M!!!!3!B!!!!'!!!M"J!
        +!"3B!!!3'!!!$"J!!!JB!!!B'!!!,"J!!#JB!!!N'!!!)"J!!"`B!!!`'!!!5"J!
        +!%3B!!"!'!!!2"J!!$3B!!!i'!!!6"J!!)JB!!#%'!!!J"J!!(`B!!#-'!!!""J!
        +!&!B!!"8'!!!@"J!!&`B!!"J'!!!C"J!!'JB!!"X'!!!F"J!!(3B!!"i!!!'T!!%
        +!+!!!!!!$Pj@!!!!!!!!!Irm!!!%!!!"j`!!#!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!X)qi!!!!!!!!!%!!X*(m!!#!!!!!!!!!!!!!!,#0S!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!"!!!!!!8!!(rr!!!!!(rr!!!
        +!!(rr!!!!!(rr!!!!$!!"!!)!"J!!!!9!!!!)!!%!!6S!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrr`!!!!-!!3!"1MS!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr!!!!"!!"!!%
        +k1QPZBfaeC'8k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp
        +!!!!#!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!rrrrrd!!!!-!!3!"1MSk4e9656TTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!$rrrrr3!!!"!!"!!%k1MT(990*1QaTBMS!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!&!!)!!6T0B@028b"6GA"`Eh*d1J!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!rrrrrd!!!!B!!J!"1Ne66$S!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr3!!!"`!+!!"
        +0B@028b"38%-J6'PZDf9b!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        +-D@*$FRP`G'mJ8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!%!!6S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!)!!8eKBdp6)&"33b"-D@jVCA)!!!!!!!!!!!!!!!!
        +!!!!!!"j"8&"-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!""F("X!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!'!!!!"068a#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"-D@)J5@e
        +`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!"08%a'!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"-D@)J5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"09d0%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"58e*$!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!'!!!!"849K8,Q*S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#B@aXEfp
        +Z)%KPE(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q-!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"849K8,Q-V+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
        +V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0M!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"849K8,Q0`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
        +V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,Q0`F!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"849K8,Q9iF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,QGM!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"(B@eP3fpNC5"$EfjfCA*dCA)!!!!!!!!!!!!!!!!
        +!!%!!!!"849K8,QJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
        +V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!"849K8,Q`!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"'E'9i)&"bCA"bEf0PFh0[FJ!!!!!!!!!!!!!!!!!
        +!!)!!!!"849K8,R!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0
        +MB@`J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,R"KF`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0MB@`J8&"$!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"849K8,R"MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-
        +V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R"MD#XV!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"09b"$,d-V+b"38%-!!!!!!!!!!!!!!!!!!!!!!!!
        +!!)!!!!"849K8,R"`G3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"09b"3BA0
        +MB@`J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!"849K8,R)!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"5CAS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"849K8,R-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"38%0"Ffd
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"849K8,RN!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"#DA0[EL"3FQ9`FQpMCA0cEh)!!!!!!!!!!!!!!!!
        +!!)!!!!"B3dp'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"B3dp'4L"
        +*EA"[FR3J8&"$!!!!!!!!!!!!!!!!!!!!!!!!!!"NEf0e!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!'!!!!"bFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!"cD'aL!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"348BJ5@e`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"cG(9L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"348BJ5@e
        +`Eh*d)&"33`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,Q4[B`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!&!!!!!!"3%"!!%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'!!!!!!%!!!!!"3!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%"!!"YB@P
        +Z!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!J"!!%!!!!"!3%"!3!"!3!!!!!!!3%!!!%"!!%!!!%!!3!
        +!!!!!!!!!!!J"!!%"!!%"!!!!!3!!#3!!&deKBdp6)&4[EfaLEhJJ4%9#98FJ0MK
        +,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cp"8&"
        +-!!!"J&M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!d!!3!
        +!!!!!&9p09d955e0I4e9659p`FQ9QDAJZD!!!!!!!!!!!!!!!!!%!!!%!!!!!!!%
        +!!!!!!!!!!!!!"3%"!3!!!3%!!3!!!!!%!!!!!!!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4KFR3!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!3!"!!!*6@9bCf8J6h9d!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!3%
        +!!!3J)#!J!jHI8!0fhhJ$"Di3!!8#!3!"!3!"!3%!!!%!!!!!!!!!!3%"!3!"!3!
        +"!!%%!!!!!!!!!!!!!!F"!3!"!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&pIFh4KFR3!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!"3!$%8aTBN0bHA"dEbj38%-Z6'PL!!!!!!!!!!!!!!!
        +!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6mr2cm!!!!!!!!!!J!!!!)!!J!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!8!!"!!%!!3!
        +"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!"3R3dp%45FJ*d4"9%%R)#G35808*`!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(!!!"!!!!,3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!!J!!!#i#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!!-!!!![!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!%!!!!-!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!"3!!!$%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!!B!!!!
        +b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!(!!!!-`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!#!!!!$3#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!!N!!!!e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!+!!!!0J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!#`!!!$F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!!`!!!!
        +i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!0!!!!13)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!$J!!!$S#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!!m!!!!l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!3!!!!2!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!%3!!!$d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!")!!!!
        +q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!6!!!!2`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!&!!!!%!#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!"8!!!""!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!@!!!!3J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!&`!!!%-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!"J!!!"
        +%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!C!!!!43)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!'J!!!%B#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!"X!!!"(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!F!!!!5!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!(3!!!%N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!"i!!!"
        ++!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!I!!!!5`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!)!!!!%`#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!#%!!!"0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!L!!!!6J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!)`!!!%m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!#3!!!"
        +3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!P!!!!83)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!*J!!!&)#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!#F!!!"6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!S!!!!9!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!+3!!!&8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!#S!!!"
        +@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!V!!!!9`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!,!!!!&J#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!#d!!!"C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!Z!!!!@J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!,`!!!&X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!$!!!!"
        +F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!a!!!!A3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!-J!!!&i#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!$-!!!"I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!d!!!!B!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!03!!!'%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!$B!!!"
        +L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!h!!!!B`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!1!!!!'3#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!$N!!!"P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!!k!!!!CJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!1`!!!'F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!$`!!!"
        +S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!!p!!!!D3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!2J!!!'S#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!$m!!!"V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"!!!!!E!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!33!!!'d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!%)!!!"
        +Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"$!!!!E`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!4!!!!(!#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!%8!!!"a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"'!!!!FJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!4`!!!(-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!%J!!!"
        +d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"*!!!!G3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!5J!!!(B#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!%X!!!"h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"-!!!!H!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!63!!!(N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!%i!!!"
        +k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"2!!!!H`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!8!!!!(`#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!&%!!!"p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"5!!!!IJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!8`!!!(m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!&3!!!#
        +!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"9!!!!J3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!9J!!!))#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!&F!!!#$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"B!!!!K!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!@3!!!)8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!&S!!!#
        +'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"E!!!!K`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!A!!!!)J#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!&d!!!#*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"H!!!!LJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!"`!!A`!!!)X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!'!!!!#
        +-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"K!!!!M3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!BJ!!!)i#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!F!!'-!!!#2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!(!!"N!!!!N!!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!'8!!!#4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"Q!!!
        +!NJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!C`!!!*-#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!'J!!!#8!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!"T!!!!P3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!DJ!!!*B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!'X!!!#A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"X!!!
        +!Q!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!E3!!!*N#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!'i!!!#D!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!"[!!!!Q`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!F!!!!*`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!(%!!!#G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"b!!!
        +!RJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!F`!!!*m#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!(3!!!#J!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!"e!!!!S3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!GJ!!!+)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!(F!!!#M!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"i!!!
        +!T!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!H3!!!+8#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!(S!!!#Q!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!"l!!!!T`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!I!!!!+J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!(d!!!#T!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!"q!!!
        +!UJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!I`!!!+X#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!)!!!!#X!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!#"!!!!V3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!JJ!!!+i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!)-!!!#[!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#%!!!
        +!X!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!K3!!!,%#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!)B!!!#b!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!#(!!!!X`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!L!!!!,3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!)N!!!#e!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#+!!!
        +!YJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!L`!!!,F#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!)`!!!#i!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!(!!#0!!!!Z3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!"`!!MJ!!!,S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!F!!)m!!!#l!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#3!!!
        +!!,`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!*%!!!#p!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#5!!!![J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!N`!!!,m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!*3!!!$!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#9!!!!`3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!PJ!
        +!!-)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!*F!!!$$!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#B!!!!a!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!Q3!!!-8#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!*S!!!$'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#E!!!!a`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!R!!
        +!!-J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!*d!!!$*!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#H!!!!bJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!R`!!!-X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!+!!!!$-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#K!!!!c3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!SJ!
        +!!-i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!+-!!!$2!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#N!!!!d!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!T3!!!0%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!+B!!!$5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#R!!!!d`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!U!!
        +!!03#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!+N!!!$9!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#U!!!!eJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!U`!!!0F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!+`!!!$B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#Y!!!!f3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!VJ!
        +!!0S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!+m!!!$E!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#`!!!!h!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!X3!!!0d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!,)!!!$H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#c!!!!h`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!Y!!
        +!!1!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!,8!!!$K!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#f!!!!iJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!Y`!!!1-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!,J!!!$N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#j!!!!j3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!ZJ!
        +!!1B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!,X!!!$R!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!#m!!!!k!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!![3!!!1N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!,i!!!$U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!#r!!!!k`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!`!!
        +!!1`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!-%!!!$Y!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$#!!!!lJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!``!!!1m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!-3!!!$`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$&!!!!m3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!aJ!
        +!!2)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!-F!!!$c!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$)!!!!p!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!b3!!!28#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!-S!!!$f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$,!!!!p`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!c!!
        +!!2J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!-d!!!$j!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$1!!!!qJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!c`!!!2X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!0!!!!$m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$4!!!!r3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!dJ!
        +!!2i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!0-!!!$r!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$8!!!"!!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!e3!!!3%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!0B!!!%#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$A!!!"!`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!f!!
        +!!33#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!0N!!!%&!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$D!!!""J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!f`!!!3F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!0`!!!%)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$G!!!"#3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!hJ!
        +!!3S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!0m!!!%,!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$J!!!"$!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!i3!!!3d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!1)!!!%1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$M!!!"$`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!j!!
        +!!4!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!18!!!%4!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$Q!!!"%J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!j`!!!4-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!1J!!!%8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$T!!!"&3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!kJ!
        +!!4B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!1X!!!%A!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$X!!!"'!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!l3!!!4N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!1i!!!%D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$[!!!"'`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!m!!
        +!!4`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!2%!!!%G!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$b!!!"(J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!m`!!!4m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!23!!!%J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$e!!!")3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!pJ!
        +!!5)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!2F!!!%M!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$i!!!"*!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!q3!!!58#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!2S!!!%Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!$l!!!"*`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!!r!!
        +!!5J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!2d!!!%T!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!$q!!!"+J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!!r`!!!5X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!3!!!!%X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%"!!!",3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"!J!
        +!!5i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!3-!!!%[!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%%!!!"-!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!""3!!!6%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!3B!!!%b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%(!!!"-`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"#!!
        +!!63#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!3N!!!%e!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%+!!!"0J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"#`!!!6F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!3`!!!%i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%0!!!"13)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"$J!
        +!!6S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!3m!!!%l!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%3!!!"2!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"%3!!!6d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!4)!!!%q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%6!!!"2`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"&!!
        +!!8!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!48!!!&"!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%@!!!"3J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"&`!!!8-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!4J!!!&%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%C!!!"43)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"'J!
        +!!8B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!4X!!!&(!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%F!!!"5!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"(3!!!8N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!4i!!!&+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%I!!!"5`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!")!!
        +!!8`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!5%!!!&0!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%L!!!"6J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!")`!!!8m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!53!!!&3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%P!!!"83)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"*J!
        +!!9)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!5F!!!&6!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%S!!!"9!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"+3!!!98#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!5S!!!&@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%V!!!"9`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!",!!
        +!!9J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!5d!!!&C!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%Z!!!"@J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!",`!!!9X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!6!!!!&F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%a!!!"A3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"-J!
        +!!9i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!6-!!!&I!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%d!!!"B!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"03!!!@%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!6B!!!&L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%h!!!"B`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"1!!
        +!!@3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!6N!!!&P!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!%k!!!"CJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"1`!!!@F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!6`!!!&S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!%p!!!"D3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"2J!
        +!!@S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!6m!!!&V!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&!!!!"E!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"33!!!@d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!8)!!!&Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!&$!!!"E`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"4!!
        +!!A!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!88!!!&a!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&'!!!"FJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"4`!!!A-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!8J!!!&d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!&*!!!"G3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"5J!
        +!!AB#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!8X!!!&h!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&-!!!"H!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"63!!!AN#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!8i!!!&k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!&2!!!"H`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"8!!
        +!!A`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!9%!!!&p!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&5!!!"IJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"8`!!!B!#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!93!!!'"!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!&9!!!"JJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"9J!
        +!!B-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!9F!!!'%!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&B!!!"K3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"@3!!!BB#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!9S!!!'(!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!&E!!!"L!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"A!!
        +!!BN#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!9d!!!'+!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&H!!!"L`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!"`!"A`!!!B`#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!F!!@!!!!'0!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!(!!&K!!!"MJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"BJ!
        +!!Bm#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@-!!!'3!!)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"C!!!!C%#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@8!!!'5!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!(!!&Q!!!"N`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"`!"C`!!!C3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@J
        +!!!'9!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&T!!!"PJ)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"DJ!!!CF#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@X!!!'B!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!(!!&X!!!"Q3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"`!"E3!!!CS#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!@i
        +!!!'E!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&[!!!"R!)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!"`!"F!!!!Cd#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!A%!!!'H!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!(!!&b!!!"R`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!"`!"F`!!!D3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!F!!A3
        +!!!'Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!(!!&e!!!"T`)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!)
        +!!!!$!!!!"!!!!!8!!!!'!!!!"`!!!!J!!!!*!!!!#J!!!!X!!!!-!!!!$3!!!!i
        +!!!!2!!!!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!&J!!!"F!!!!B!!!!'3!!!"S
        +!!!!E!!!!(!!!!"d!!!!H!!!!(`!!!#!!!!!K!!!!)J!!!#-!!!!N!!!!*3!!!#B
        +!!!!R!!!!+!!!!#N!!!!U!!!!+`!!!#`!!!!Y!!!!,J!!!#m!!!!`!!!!-3!!!$)
        +!!!!c!!!!0!!!!$8!!!!f!!!!0`!!!$J!!!!j!!!!1J!!!$X!!!!m!!!!23!!!$i
        +!!!!r!!!!3!!!!%%!!!"#!!!!3`!!!%3!!!"&!!!!4J!!!%F!!!")!!!!53!!!%S
        +!!!",!!!!6!!!!%d!!!"1!!!!6`!!!&!!!!"4!!!!8J!!!&-!!!"8!!!!93!!!&B
        +!!!"A!!!!@!!!!&N!!!"D!!!!@`!!!&`!!!"G!!!!AJ!!!&m!!!"J!!!!B3!!!')
        +!!!"M!!!!C!!!!'8!!!"Q!!!!C`!!!'J!!!"T!!!!DJ!!!'X!!!"X!!!!E3!!!'i
        +!!!"[!!!!F!!!!(%!!!"b!!!!F`!!!(3!!!"e!!!!GJ!!!(F!!!"i!!!!H3!!!(S
        +!!!"l!!!!I!!!!(d!!!"q!!!!I`!!!)!!!!#"!!!!JJ!!!)-!!!#%!!!!K3!!!)B
        +!!!#(!!!!L!!!!)N!!!#+!!!!L`!!!)`!!!#0!!!!MJ!!!)m!!!#3!!!!!*%!!!#
        +5!!!!N`!!!*3!!!#9!!!!PJ!!!*F!!!#B!!!!Q3!!!*S!!!#E!!!!R!!!!*d!!!#
        +H!!!!R`!!!+!!!!#K!!!!SJ!!!+-!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!+N!!!#
        +U!!!!U`!!!+`!!!#Y!!!!VJ!!!+m!!!#`!!!!X3!!!,)!!!#c!!!!Y!!!!,8!!!#
        +f!!!!Y`!!!,J!!!#j!!!!ZJ!!!,X!!!#m!!!![3!!!,i!!!#r!!!!`!!!!-%!!!$
        +#!!!!``!!!-3!!!$&!!!!aJ!!!-F!!!$)!!!!b3!!!-S!!!$,!!!!c!!!!-d!!!$
        +1!!!!c`!!!0!!!!$4!!!!dJ!!!0-!!!$8!!!!e3!!!0B!!!$A!!!!f!!!!0N!!!$
        +D!!!!f`!!!0`!!!$G!!!!hJ!!!0m!!!$J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$
        +Q!!!!j`!!!1J!!!$T!!!!kJ!!!1X!!!$X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$
        +b!!!!m`!!!23!!!$e!!!!pJ!!!2F!!!$i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$
        +q!!!!r`!!!3!!!!%"!!!"!J!!!3-!!!%%!!!""3!!!3B!!!%(!!!"#!!!!3N!!!%
        ++!!!"#`!!!3`!!!%0!!!"$J!!!3m!!!%3!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%
        +@!!!"&`!!!4J!!!%C!!!"'J!!!4X!!!%F!!!"(3!!!4i!!!%I!!!")!!!!5%!!!%
        +L!!!")`!!!53!!!%P!!!"*J!!!5F!!!%S!!!"+3!!!5S!!!%V!!!",!!!!5d!!!%
        +Z!!!",`!!!6!!!!%a!!!"-J!!!6-!!!%d!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%
        +k!!!"1`!!!6`!!!%p!!!"2J!!!6m!!!&!!!!"33!!!8)!!!&$!!!"4!!!!88!!!&
        +'!!!"4`!!!8J!!!&*!!!"5J!!!8X!!!&-!!!"63!!!8i!!!&2!!!"8!!!!9%!!!&
        +5!!!"8`!!!93!!!&9!!!"9J!!!9F!!!&B!!!"@3!!!9S!!!&E!!!"A!!!!9d!!!&
        +H!!!"A`!!!@!!!!&K!!!"BJ!!!@-!!!&N!!!"C3!!!@B!!!&R!!!"D!!!!@N!!!&
        +U!!!"D`!!!@`!!!&Y!!!"EJ!!!@m!!!&`!!!"F3!!!A)!!!&c!!!"G!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"G3!!!B!(!!!
        +!"`!"G3F!!!%(!!!#"`!!!`F!!!3(!!!&"`!!"JF!!!F(!!!)"`!!#3F!!!S(!!!
        +,"`!!$!F!!!d(!!!1"`!!$`F!!"!(!!!4"`!!%JF!!"-(!!!8"`!!&3F!!"B(!!!
        +A"`!!'!F!!"N(!!!D"`!!'`F!!"`(!!!G"`!!(JF!!"m(!!!J"`!!)3F!!#)(!!!
        +M"`!!*!F!!#8(!!!Q"`!!*`F!!#J(!!!T"`!!+JF!!#X(!!!X"`!!,3F!!#i(!!!
        +["`!!-!F!!$%(!!!b"`!!-`F!!$3(!!!e"`!!0JF!!$F(!!!i"`!!13F!!$S(!!!
        +l"`!!2!F!!$d(!!!q"`!!2`F!!%!(!!"""`!!3JF!!%-(!!"%"`!!43F!!%B(!!"
        +("`!!5!F!!%N(!!"+"`!!5`F!!%`(!!"0"`!!6JF!!%m(!!"3"`!!83F!!&)(!!"
        +6"`!!9!F!!&8(!!"@"`!!9`F!!&J(!!"C"`!!@JF!!&X(!!"F"`!!A3F!!&i(!!"
        +I"`!!B!F!!'%(!!"L"`!"G!F!!'-(!!"N"`!!C3F!!'B(!!"R"`!!D!F!!'N(!!"
        +U"`!!D`F!!'`(!!"Y"`!!EJF!!'m(!!"`"`!!F3F!!()(!!"c"`!!G!F!!(8(!!"
        +f"`!!G`F!!(J(!!"j"`!!HJF!!(X(!!"m"`!!I3F!!(i(!!"r"`!!J!F!!)%(!!#
        +#"`!!J`F!!)3(!!#&"`!!KJF!!)F(!!#)"`!!L3F!!)S(!!#,"`!!M!F!!)d(!!#
        +1"`!!M`F!!*!!"`!!N3F!!*)(!!#6"`!!P!F!!*8(!!#@"`!!P`F!!*J(!!#C"`!
        +!QJF!!*X(!!#F"`!!R3F!!*i(!!#I"`!!S!F!!+%(!!#L"`!!S`F!!+3(!!#P"`!
        +!TJF!!+F(!!#S"`!!U3F!!+S(!!#V"`!!V!F!!+d(!!#Z"`!!V`F!!,!(!!#a"`!
        +!XJF!!,-(!!#d"`!!Y3F!!,B(!!#h"`!!Z!F!!,N(!!#k"`!!Z`F!!,`(!!#p"`!
        +![JF!!,m(!!$!"`!!`3F!!-)(!!$$"`!!a!F!!-8(!!$'"`!!a`F!!-J(!!$*"`!
        +!bJF!!-X(!!$-"`!!c3F!!-i(!!$2"`!!d!F!!0%(!!$5"`!!d`F!!03(!!$9"`!
        +!eJF!!0F(!!$B"`!!f3F!!0S(!!$E"`!!h!F!!0d(!!$H"`!!h`F!!1!(!!$K"`!
        +!iJF!!1-(!!$N"`!!j3F!!1B(!!$R"`!!k!F!!1N(!!$U"`!!k`F!!1`(!!$Y"`!
        +!lJF!!1m(!!$`"`!!m3F!!2)(!!$c"`!!p!F!!28(!!$f"`!!p`F!!2J(!!$j"`!
        +!qJF!!2X(!!$m"`!!r3F!!2i(!!$r"`!"!!F!!3%(!!%#"`!"!`F!!33(!!%&"`!
        +""JF!!3F(!!%)"`!"#3F!!3S(!!&e"`!"#`F!!3`(!!%0"`!"$JF!!3m(!!%3"`!
        +"%3F!!4)(!!%6"`!"&!F!!48(!!%@"`!"&`F!!4J(!!%C"`!"'JF!!4X(!!%F"`!
        +"(3F!!4i(!!%I"`!")!F!!5%(!!%L"`!")`F!!53(!!%P"`!"*JF!!5F(!!%S"`!
        +"+3F!!5S(!!%V"`!",!F!!5d(!!%Z"`!",`F!!6!(!!%a"`!"-JF!!6-(!!%d"`!
        +"03F!!6B(!!%h"`!"1!F!!6N(!!%k"`!"1`F!!6`(!!%p"`!"2JF!!6m(!!&!"`!
        +"33F!!8)(!!&$"`!"4!F!!88(!!&'"`!"4`F!!8J(!!&*"`!"5JF!!8X(!!&-"`!
        +"63F!!8i(!!&2"`!"8!F!!9%(!!&5"`!"8`F!!93(!!&9"`!"9JF!!9F(!!&B"`!
        +"@3F!!9S(!!&E"`!"A!F!!9d(!!&H"`!"A`F!!@!(!!&K"`!"BJF!!@-(!!&N"`!
        +"C3F!!@B(!!&R"`!"D!F!!@N(!!&U"`!"D`F!!@`(!!&Y"`!"EJF!!@m(!!&`"`!
        +"F3F!!A)(!!&c!!!"U3!"!#J!!!!!!jH9J!!!!!!!!(rr!!!"!!!!HF!!!J!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,#2Z!!!!!!!!!"!!,#4r!!!J!!!!!
        +!!!!!!!!#`MD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!J!!!3!
        +!!!!&!!"rr`!!!!"rr`!!!!"rr`!!!!"rr`!!!!`!!3!#!!B!!!!&3!!!#!!"!!%
        +k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrm
        +!!!!$!!%!!6Sk!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +"!!!!rrrrr`!!!!3!!3!"1MTTEQ0XG@4P1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!$rrrrr3!!!!J!"!!%k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!2rrrrp!!!!$!!%!!6Sk1NG98dNkD@jME(9NC6S
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rrrrrd!!!!3!!3!"1MSk4e9656T
        +XD@)k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$rrrrr3!!!"3!#!!%
        +k6@&M6e-J8h9`F'pbG$S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!2rrrrp
        +!!!!'!!)!!6T08d`k!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +"!!!!rrrrrd!!!!F!#J!!6@&M6e-J0MK,)%aTEQYPFJ!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!6'PL3h*jF(4[)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!%k!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!&0B@028b!f1%XJ6'P
        +ZDf9b!!!!!!!!!!!!!!!!!!!!!!!J39"36!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!3A"
        +`E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!68e-3J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"
        +-4J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6'PL)%PYF'pbG#!f1%X
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69G$4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!6d*
        ++)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69"A)%PYF'pbG#!f1%X
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%a[BJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!8P0
        +53`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!9%9B9#jLD!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!3Q&XE'p[EL")C@a`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jM+bX!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jMB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jMF!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jMF(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jPH(!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jRB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4f&YC80[C'8J3fpZGQ9
        +bG'9b!!!!!!!!!!!!!!!!!!"!!!!!9%9B9#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!!3!!!!9%9
        +B9#jX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4QaPH#"3FQ9`FQpMCA0
        +cEh)!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#j`BA-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#j`BfJ!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
        +B9#j`BfJV+`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!69FJ3bp$+bXJ0MK,!!!
        +!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9B9#j`F(8!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!69FJ8'&cBf&X)$Bi5`!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!9%9
        +B9#jb!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8Q9k!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9B9#jcC@F!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9%9
        +B9#jj!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3QPcEfiJ8(*PF(*[Bf9
        +cFfpb!!!!!!!!!!!!!!!!!!#!!!!!C'pMG3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FR0
        +bB`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!FfKXBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Fh4
        +eBJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8%9')%PYF'pbG#!f1%X
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#jNEf-!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"3!!!!!!!
        +!!#jbFh*M!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!"J!!!!!!8"!3!"!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"J!
        +!!!!"!!!!!!8!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!"!3!!E@&TEJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!3!"!!!!!3%"!!!"!3%!!!!
        +!!!%"!!!"!3!"!!!""!!!!!!!!!!!!!!)!3!"!3!"!3!!!!%!!!N!!aY-D@*$FRP
        +`G'mZ0MKV)%CK+$4TAcKN+5j-D@)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!r2cmr2cmr2`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$mr2cm!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!0!!%!!!!!!"9I69G&8NY6AdG98dPIF(*PCQPi,QJ!!!!!!!!
        +!!!!!!!!"!!!!!!!!!!!"!!!!!!!!!!!!!!8"!3%!!!%"!!%!!!!!"!!!!!!!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"IAh0
        +dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%!!3!!#8ePFQGP)%peG!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!$mr2cp"8&"-!!%"!!!%)#!J)!1ARe!$GYpi!`@Z%!!&!J%!!3%!!3%"!!!
        +"!!!!!!!!!!%"!3%!!3%!!3!""!!!!!!!!!!!!!!(!3%!!3!!!3!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!"IAh0dBA*d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8!!!G2F'9Z8e0-!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!2cmr2d&38%`!!!3!!!!%!!!!!%!!!&M!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%r2cm
        +r!!!!!!!!!!)!!!!#!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!#!&!!!3!"!!%!!3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8*d024%8R)#G%394"*b!
        +R8%P$9#F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!#!!!!3!!!#d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!!)!!!!
        +Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!$!!!!,`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!"!!!!$!#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!!8!!!!a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!'!!!!-J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!"`!!!$-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!!J!!!!
        +d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!*!!!!03)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!#J!!!$B#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!!X!!!!h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!-!!!!1!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!$3!!!$N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!!i!!!!
        +k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!2!!!!1`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!%!!!!$`#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!"%!!!!p!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!5!!!!2J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!%`!!!$m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!"3!!!"
        +!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!9!!!!33)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!&J!!!%)#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!"F!!!"$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!B!!!!4!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!'3!!!%8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!"S!!!"
        +'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!E!!!!4`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!(!!!!%J#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!"d!!!"*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!H!!!!5J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!(`!!!%X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!#!!!!"
        +-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!K!!!!63)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!)J!!!%i#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!#-!!!"2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!N!!!!8!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!*3!!!&%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!#B!!!"
        +5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!R!!!!8`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!+!!!!&3#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!#N!!!"9!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!U!!!!9J)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!+`!!!&F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!#`!!!"
        +B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!Y!!!!@3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!,J!!!&S#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!#m!!!"E!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!`!!!!A!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!-3!!!&d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!$)!!!"
        +H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!c!!!!A`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!0!!!!'!#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!$8!!!"K!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!f!!!!BJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!0`!!!'-#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!$J!!!"
        +N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!j!!!!C3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!1J!!!'B#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!$X!!!"R!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!!m!!!!D!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!23!!!'N#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!$i!!!"
        +U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!!r!!!!D`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!3!!!!'`#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!%%!!!"Y!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!"#!!!!EJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!3`!!!'m#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!%3!!!"
        +`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"&!!!!F3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!4J!!!()#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!%F!!!"c!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!")!!!!G!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!53!!!(8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!%S!!!"
        +f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!",!!!!G`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!6!!!!(J#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!%d!!!"j!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!"1!!!!HJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!6`!!!(X#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!&!!!!"
        +m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"4!!!!I3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!8J!!!(i#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!&-!!!"r!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!"8!!!!J!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!93!!!)%#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!&B!!!#
        +#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"A!!!!J`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!@!!!!)3#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!&N!!!#&!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!"D!!!!KJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!@`!!!)F#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!&`!!!#
        +)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"G!!!!L3)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!AJ!!!)S#!3!!!!!!!3!"!3!!!!!
        +!!!!!!!!!!!%!!!!!!!!!!!J!!&m!!!#,!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!
        +"!!!!!!!!!!!)!!"J!!!!M!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!
        +!#!!!B3!!!)d#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!')!!!#
        +1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"M!!!!M`)"!!!!!!!
        +"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!C!!!!*!!!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!"P!!!!N3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!CJ!!!*)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!'F!!!#6!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"S!!!
        +!P!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!D3!!!*8#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!'S!!!#@!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!"V!!!!P`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!E!!!!*J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!'d!!!#C!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"Z!!!
        +!QJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!E`!!!*X#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!(!!!!#F!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!"a!!!!R3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!FJ!!!*i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!(-!!!#I!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"d!!!
        +!S!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!G3!!!+%#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!(B!!!#L!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!"h!!!!S`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!H!!!!+3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!(N!!!#P!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!"k!!!
        +!TJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!H`!!!+F#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!(`!!!#S!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!"p!!!!U3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!IJ!!!+S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!(m!!!#V!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#!!!!
        +!V!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!J3!!!+d#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!))!!!#Z!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!#$!!!!V`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!K!!!!,!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!)8!!!#a!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#'!!!
        +!XJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!K`!!!,-#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!)J!!!#d!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!#*!!!!Y3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!LJ!!!,B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!
        +!!!J!!)X!!!#h!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#-!!!
        +!Z!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!M3!!!,N#!3!!!!!
        +!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!)i!!!#k!J%!!!!!!!%!!3%!!!!
        +!!!!!!!!!!!!"!!!!!!!!!!!)!!#2!!!!Z`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!
        +!!3!!!!!!!!!!#!!!N!!!!!#m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#4!!!![3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!NJ!
        +!!,i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!*-!!!#r!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#8!!!!`!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!P3!!!-%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!*B!!!$#!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#A!!!!``)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!Q!!
        +!!-3#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!*N!!!$&!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#D!!!!aJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!Q`!!!-F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!*`!!!$)!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#G!!!!b3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!RJ!
        +!!-S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!*m!!!$,!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#J!!!!c!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!S3!!!-d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!+)!!!$1!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#M!!!!c`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!T!!
        +!!0!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!+8!!!$4!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#Q!!!!dJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!T`!!!0-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!+J!!!$8!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#T!!!!e3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!UJ!
        +!!0B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!+X!!!$A!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#X!!!!f!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!V3!!!0N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!+i!!!$D!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#[!!!!f`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!X!!
        +!!0`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!,%!!!$G!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#b!!!!hJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!X`!!!0m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!,3!!!$J!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#e!!!!i3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!YJ!
        +!!1)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!,F!!!$M!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#i!!!!j!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!Z3!!!18#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!,S!!!$Q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!#l!!!!j`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!![!!
        +!!1J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!,d!!!$T!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!#q!!!!kJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!![`!!!1X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!-!!!!$X!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$"!!!!l3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!`J!
        +!!1i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!--!!!$[!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$%!!!!m!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!a3!!!2%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!-B!!!$b!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$(!!!!m`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!b!!
        +!!23#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!-N!!!$e!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$+!!!!pJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!b`!!!2F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!-`!!!$i!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$0!!!!q3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!cJ!
        +!!2S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!-m!!!$l!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$3!!!!r!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!d3!!!2d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!0)!!!$q!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$6!!!!r`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!e!!
        +!!3!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!08!!!%"!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$@!!!"!J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!e`!!!3-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!0J!!!%%!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$C!!!""3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!fJ!
        +!!3B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!0X!!!%(!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$F!!!"#!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!h3!!!3N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!0i!!!%+!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$I!!!"#`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!i!!
        +!!3`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!1%!!!%0!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$L!!!"$J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!i`!!!3m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!13!!!%3!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$P!!!"%3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!jJ!
        +!!4)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!1F!!!%6!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$S!!!"&!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!k3!!!48#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!1S!!!%@!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$V!!!"&`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!l!!
        +!!4J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!1d!!!%C!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$Z!!!"'J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!l`!!!4X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!2!!!!%F!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$a!!!"(3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!mJ!
        +!!4i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!2-!!!%I!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$d!!!")!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!p3!!!5%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!2B!!!%L!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$h!!!")`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!q!!
        +!!53#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!2N!!!%P!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!$k!!!"*J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!!q`!!!5F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!2`!!!%S!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!$p!!!"+3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!!rJ!
        +!!5S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!2m!!!%V!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%!!!!",!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"!3!!!5d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!3)!!!%Z!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%$!!!",`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!""!!
        +!!6!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!38!!!%a!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%'!!!"-J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!""`!!!6-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!3J!!!%d!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%*!!!"03)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"#J!
        +!!6B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!3X!!!%h!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%-!!!"1!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"$3!!!6N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!3i!!!%k!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%2!!!"1`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"%!!
        +!!6`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!4%!!!%p!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%5!!!"2J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"%`!!!6m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!43!!!&!!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%9!!!"33)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"&J!
        +!!8)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!4F!!!&$!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%B!!!"4!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"'3!!!88#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!4S!!!&'!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%E!!!"4`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"(!!
        +!!8J#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!4d!!!&*!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%H!!!"5J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"(`!!!8X#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!5!!!!&-!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%K!!!"63)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!")J!
        +!!8i#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!5-!!!&2!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%N!!!"8!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"*3!!!9%#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!5B!!!&5!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%R!!!"8`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"+!!
        +!!93#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!5N!!!&9!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%U!!!"9J)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"+`!!!9F#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!5`!!!&B!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%Y!!!"@3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!",J!
        +!!9S#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!5m!!!&E!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%`!!!"A!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"-3!!!9d#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!6)!!!&H!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%c!!!"A`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"0!!
        +!!@!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!68!!!&K!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%f!!!"BJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"0`!!!@-#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!6J!!!&N!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%j!!!"C3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"1J!
        +!!@B#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!6X!!!&R!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!%m!!!"D!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"23!!!@N#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!6i!!!&U!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!%r!!!"D`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"3!!
        +!!@`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!8%!!!&Y!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&#!!!"EJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"3`!!!@m#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!83!!!&`!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!&&!!!"F3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"4J!
        +!!A)#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!8F!!!&c!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&)!!!"G!)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"53!!!A8#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!8S!!!&f!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!&,!!!"G`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"6!!
        +!!AJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!8d!!!&j!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&1!!!"HJ)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"6`!!!AX#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!9!!!!&m!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!&4!!!"I3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"8J!
        +!!Ai#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!9-!!!'!!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&8!!!"J3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"93!!!B)#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!9B!!!'$!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!&A!!!"K!)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"@!!
        +!!B8#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!9N!!!''!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&D!!!"K`)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"@`!!!BJ#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!9`!!!'*!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!&G!!!"LJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"AJ!
        +!!BX#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!9m!!!'-!J%!!!!
        +!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&J!!!"M3)"!!!!!!!"!!%"!!!
        +!!!!!!!!!!!!!!3!!!!!!!!!!#!!"B3!!!Bi#!3!!!!!!!3!"!3!!!!!!!!!!!!!
        +!!!%!!!!!!!!!!!J!!@)!!!'2!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!
        +!!!!)!!&M!!!"N!!#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@3
        +!!!'4!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&P!!!"NJ)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"CJ!!!C-#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@F!!!'8!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!)!!&S!!!"P3)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!#!!"D3!!!CB#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@S
        +!!!'A!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&V!!!"Q!)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"E!!!!CN#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!@d!!!'D!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!)!!&Z!!!"Q`)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!#!!"E`!!!C`#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!A!
        +!!!'G!J%!!!!!!!%!!3%!!!!!!!!!!!!!!!!"!!!!!!!!!!!)!!&a!!!"RJ)"!!!
        +!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!!!!!!#!!"FJ!!!Cm#!3!!!!!!!3!"!3!
        +!!!!!!!!!!!!!!!%!!!!!!!!!!!J!!A-!!!'N!J%!!!!!!!%!!3%!!!!!!!!!!!!
        +!!!!"!!!!!!!!!!!)!!&d!!!"TJ)"!!!!!!!"!!%"!!!!!!!!!!!!!!!!!3!!!!!
        +!!!!!#!!"G3!!!DF#!3!!!!!!!3!"!3!!!!!!!!!!!!!!!!%!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!%!!!!#!!!!!`!!!!3!!!!&!!!!"J!!!!F!!!!)!!!!#3!!!!S
        +!!!!,!!!!$!!!!!d!!!!1!!!!$`!!!"!!!!!4!!!!%J!!!"-!!!!8!!!!&3!!!"B
        +!!!!A!!!!'!!!!"N!!!!D!!!!'`!!!"`!!!!G!!!!(J!!!"m!!!!J!!!!)3!!!#)
        +!!!!M!!!!*!!!!#8!!!!Q!!!!*`!!!#J!!!!T!!!!+J!!!#X!!!!X!!!!,3!!!#i
        +!!!![!!!!-!!!!$%!!!!b!!!!-`!!!$3!!!!e!!!!0J!!!$F!!!!i!!!!13!!!$S
        +!!!!l!!!!2!!!!$d!!!!q!!!!2`!!!%!!!!""!!!!3J!!!%-!!!"%!!!!43!!!%B
        +!!!"(!!!!5!!!!%N!!!"+!!!!5`!!!%`!!!"0!!!!6J!!!%m!!!"3!!!!83!!!&)
        +!!!"6!!!!9!!!!&8!!!"@!!!!9`!!!&J!!!"C!!!!@J!!!&X!!!"F!!!!A3!!!&i
        +!!!"I!!!!B!!!!'%!!!"L!!!!B`!!!'3!!!"P!!!!CJ!!!'F!!!"S!!!!D3!!!'S
        +!!!"V!!!!E!!!!'d!!!"Z!!!!E`!!!(!!!!"a!!!!FJ!!!(-!!!"d!!!!G3!!!(B
        +!!!"h!!!!H!!!!(N!!!"k!!!!H`!!!(`!!!"p!!!!IJ!!!(m!!!#!!!!!J3!!!))
        +!!!#$!!!!K!!!!)8!!!#'!!!!K`!!!)J!!!#*!!!!LJ!!!)X!!!#-!!!!M3!!!)i
        +!!!#2!!!!N!!!!!#4!!!!NJ!!!*-!!!#8!!!!P3!!!*B!!!#A!!!!Q!!!!*N!!!#
        +D!!!!Q`!!!*`!!!#G!!!!RJ!!!*m!!!#J!!!!S3!!!+)!!!#M!!!!T!!!!+8!!!#
        +Q!!!!T`!!!+J!!!#T!!!!UJ!!!+X!!!#X!!!!V3!!!+i!!!#[!!!!X!!!!,%!!!#
        +b!!!!X`!!!,3!!!#e!!!!YJ!!!,F!!!#i!!!!Z3!!!,S!!!#l!!!![!!!!,d!!!#
        +q!!!![`!!!-!!!!$"!!!!`J!!!--!!!$%!!!!a3!!!-B!!!$(!!!!b!!!!-N!!!$
        ++!!!!b`!!!-`!!!$0!!!!cJ!!!-m!!!$3!!!!d3!!!0)!!!$6!!!!e!!!!08!!!$
        +@!!!!e`!!!0J!!!$C!!!!fJ!!!0X!!!$F!!!!h3!!!0i!!!$I!!!!i!!!!1%!!!$
        +L!!!!i`!!!13!!!$P!!!!jJ!!!1F!!!$S!!!!k3!!!1S!!!$V!!!!l!!!!1d!!!$
        +Z!!!!l`!!!2!!!!$a!!!!mJ!!!2-!!!$d!!!!p3!!!2B!!!$h!!!!q!!!!2N!!!$
        +k!!!!q`!!!2`!!!$p!!!!rJ!!!2m!!!%!!!!"!3!!!3)!!!%$!!!""!!!!38!!!%
        +'!!!""`!!!3J!!!%*!!!"#J!!!3X!!!%-!!!"$3!!!3i!!!%2!!!"%!!!!4%!!!%
        +5!!!"%`!!!43!!!%9!!!"&J!!!4F!!!%B!!!"'3!!!4S!!!%E!!!"(!!!!4d!!!%
        +H!!!"(`!!!5!!!!%K!!!")J!!!5-!!!%N!!!"*3!!!5B!!!%R!!!"+!!!!5N!!!%
        +U!!!"+`!!!5`!!!%Y!!!",J!!!5m!!!%`!!!"-3!!!6)!!!%c!!!"0!!!!68!!!%
        +f!!!"0`!!!6J!!!%j!!!"1J!!!6X!!!%m!!!"23!!!6i!!!%r!!!"3!!!!8%!!!&
        +#!!!"3`!!!83!!!&&!!!"4J!!!8F!!!&)!!!"53!!!8S!!!&,!!!"6!!!!8d!!!&
        +1!!!"6`!!!9!!!!&4!!!"8J!!!9-!!!&8!!!"93!!!9B!!!&A!!!"@!!!!9N!!!&
        +D!!!"@`!!!9`!!!&G!!!"AJ!!!9m!!!&J!!!"B3!!!@)!!!&M!!!"C!!!!@8!!!&
        +Q!!!"C`!!!@J!!!&T!!!"DJ!!!@X!!!&X!!!"E3!!!@i!!!&[!!!"F!!!!A%!!!&
        +b!!!"F`!!!A3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!A8!!!'!#!!!!!J!!A8!!!(E!!%!(!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!J!!!%)!!!##!!!!`J!!!3)!!!&#!!!"JJ!!!F)!!!)#!!!#3J!!!S)!!!
        +,#!!!$!J!!!d)!!!1#!!!$`J!!"!)!!!4#!!!%JJ!!"-)!!!8#!!!&3J!!"B)!!!
        +A#!!!'!J!!"N)!!!D#!!!'`J!!"`)!!!G#!!!(JJ!!"m)!!!J#!!!)3J!!#))!!!
        +M#!!!*!J!!#8)!!!Q#!!!*`J!!#J)!!!T#!!!+JJ!!#X)!!!X#!!!,3J!!#i)!!!
        +[#!!!-!J!!$%)!!!b#!!!-`J!!$3)!!!e#!!!0JJ!!$F)!!!i#!!!13J!!$S)!!!
        +l#!!!2!J!!$d)!!!q#!!!2`J!!%!)!!""#!!!3JJ!!%-)!!"%#!!!43J!!%B)!!"
        +(#!!!5!J!!%N)!!"+#!!!5`J!!%`)!!"0#!!!6JJ!!%m)!!"3#!!!83J!!&))!!"
        +6#!!!9!J!!&8)!!"@#!!!9`J!!&J)!!"C#!!!@JJ!!&X)!!"F#!!!A3J!!&i)!!"
        +I#!!!B!J!!'%)!!"L#!!"G!J!!'-)!!"N#!!!C3J!!'B)!!"R#!!!D!J!!'N)!!"
        +U#!!!D`J!!'`)!!"Y#!!!EJJ!!'m)!!"`#!!!F3J!!())!!"c#!!!G!J!!(8)!!"
        +f#!!!G`J!!(J)!!"j#!!!HJJ!!(X)!!"m#!!!I3J!!(i)!!"r#!!!J!J!!)%)!!#
        +##!!!J`J!!)3)!!#&#!!!KJJ!!)F)!!#)#!!!L3J!!)S)!!#,#!!!M!J!!)d)!!#
        +1#!!!M`J!!*!!#!!!N3J!!*))!!#6#!!!P!J!!*8)!!#@#!!!P`J!!*J)!!#C#!!
        +!QJJ!!*X)!!#F#!!!R3J!!*i)!!#I#!!!S!J!!+%)!!#L#!!!S`J!!+3)!!#P#!!
        +!TJJ!!+F)!!#S#!!!U3J!!+S)!!#V#!!!V!J!!+d)!!#Z#!!!V`J!!,!)!!#a#!!
        +!XJJ!!,-)!!#d#!!!Y3J!!,B)!!#h#!!!Z!J!!,N)!!#k#!!!Z`J!!,`)!!#p#!!
        +![JJ!!,m)!!$!#!!!`3J!!-))!!$$#!!!a!J!!-8)!!$'#!!!a`J!!-J)!!$*#!!
        +!bJJ!!-X)!!$-#!!!c3J!!-i)!!$2#!!!d!J!!0%)!!$5#!!!d`J!!03)!!$9#!!
        +!eJJ!!0F)!!$B#!!!f3J!!0S)!!$E#!!!h!J!!0d)!!$H#!!!h`J!!1!)!!$K#!!
        +!iJJ!!1-)!!$N#!!!j3J!!1B)!!$R#!!!k!J!!1N)!!$U#!!!k`J!!1`)!!$Y#!!
        +!lJJ!!1m)!!$`#!!!m3J!!2))!!$c#!!!p!J!!28)!!$f#!!!p`J!!2J)!!$j#!!
        +!qJJ!!2X)!!$m#!!!r3J!!2i)!!$r#!!"!!J!!3%)!!%##!!"!`J!!33)!!%&#!!
        +""JJ!!3F)!!%)#!!"#3J!!3S)!!&e#!!"#`J!!3`)!!%0#!!"$JJ!!3m)!!%3#!!
        +"%3J!!4))!!%6#!!"&!J!!48)!!%@#!!"&`J!!4J)!!%C#!!"'JJ!!4X)!!%F#!!
        +"(3J!!4i)!!%I#!!")!J!!5%)!!%L#!!")`J!!53)!!%P#!!"*JJ!!5F)!!%S#!!
        +"+3J!!5S)!!%V#!!",!J!!5d)!!%Z#!!",`J!!6!)!!%a#!!"-JJ!!6-)!!%d#!!
        +"03J!!6B)!!%h#!!"1!J!!6N)!!%k#!!"1`J!!6`)!!%p#!!"2JJ!!6m)!!&!#!!
        +"33J!!8))!!&$#!!"4!J!!88)!!&'#!!"4`J!!8J)!!&*#!!"5JJ!!8X)!!&-#!!
        +"63J!!8i)!!&2#!!"8!J!!9%)!!&5#!!"8`J!!93)!!&9#!!"9JJ!!9F)!!&B#!!
        +"@3J!!9S)!!&E#!!"A!J!!9d)!!&H#!!"A`J!!@!)!!&K#!!"BJJ!!@-)!!&N#!!
        +"C3J!!@B)!!&R#!!"D!J!!@N)!!&U#!!"D`J!!@`)!!&Y#!!"EJJ!!@m)!!&`#!!
        +"F3J!!A))!!&c!!!!#!!!!H%"!!!"!!!!!!!!!!!!"!!"!!!"kE6H0L[rrmA@!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"iJ)!!!%!!!!!!!!!!!!%!!%!!!(eY0i
        +f,!!!IZ)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(M!`!!!3!!!!!!!!!!!!3
        +!!3!!!IDdhMBX!!!f%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!H3%!!!"!!!
        +!!!!!!!!!"!!"!!!"r,6H0L`!!&C*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +"j38!!!%!!!!!!!!!!!!%!!%!!!(pY0if,2rrp2N!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!(Q"J!!!3!!!!!!!!!!!!3!!3!!!G'dhMBX!!!Si3!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!HF(!!!"!!!!!!!!!!!!"!!"!!!"dV6H0L`!!!ca!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"k!J!!!%!!!!!!!!!!!!%!!%!!!(IY0i
        +f,2rr[fi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)!!!!!H%!!!!"i`!!!!(
        +L!!!!!H8!!!!"jJ!!!!(N!!!!!HF!!!!"k!!"!!!!!&*26e3!!!!!!!!!!!!!!!!
        +'4e*98!!!!!!!!!!!$P*[H5Gc)%GPG%K89&"6!!!!"8C*6%8"!!'L4NP-43%!!D0
        +'58a&!3!"U%C*6%8"!!'K4NP-43%!!D"(8P93!!!!!!!!!!!66h"PEP066#""F("
        +XD@0KG'P[EJ!!!#0'58a&!J!!(%C*6%8#!!!U4NP-43)!!!e'58a&!J!!)%C*6%8
        +#!!!54NP-43)!!"0'58a&!J!!&NC*6%8#!!!B4NP-43)!!"G'58a&!J!!$NC*6%8
        +#!!!H4NP-43)!!"&'58a&!J!!%%C*6%8#!!!K4NP-43)!!"4'58a&!J!!&8C*6%8
        +#!!!X4NP-43)!!"T'58a&!J!!'8C*6%8#!!!S4NP-43)!!#G'58a&!J!!*%C*6%8
        +#!!!Y4NP-43)!!!Y'58a&!J!!*NC*6%8#!!!T4NP-43)!!!a'58a&!J!!+dC*6%8
        +#!!!L4NP-43)!!!p'58a&!J!!'dC*6%8#!!!G4NP-43)!!"p'58a&!J!!*8C*6%8
        +#!!!M4e*98!!!!!!!!!!!%8p`C@j68d`J6'PLFQ&bD@9c!!!!"%G599!!!!!!!!!
        +!!!038%-!!!!#4NP-43)!!$0'58a&!J!!0%G599!!!!!!!!!!!!-f1'X!!!!#4NP
        +-438!!#"'58a&"3!!(dG599!!!!!!!!!!!!CMFRP`G'm!!!!S4NP-43%!!Aa'58a
        +&!3!"INC*6%8"!!'N4NP-43%!!Cp'58a&!3!"I8C*6%8"!!&l4e*98!!!!!!!!!!
        +!"'&cEM%!!!"A4NP-43%!!$j'58a&!3!!-8C*6%8"!!"&4NP-43%!!$P'58a&!3!
        +!3dC*6%8"!!!m4NP-43%!!$p'58a&!3!!3%C*6%8"!!"%4NP-43%!!%&'58a&!3!
        +!0dC*6%8"!!!e4NP-43%!!$Y'58a&!3!!-NC*6%8"!!!i4NP-43%!!%K'58a&!3!
        +!4NC*6%8"!!"#4NP-43%!!$C'58a&!3!!4dC*6%8"!!')4NP-43%!!("'58a&!3!
        +!I%C*6%8"!!"i4NP-43%!!(T'58a&!3!!H8C*6%8"!!"a4NP-43%!!(C'58a&!3!
        +!FNC*6%8"!!"p4NP-43%!!B&'58a&!3!!FdC*6%8"!!"e4NP-43%!!(Y'58a&!3!
        +!A8C*6%8"!!"04NP-43%!!&P'58a&!3!!6NC*6%8"!!"D4NP-43%!!%p'58a&!3!
        +!@dC*6%8"!!"34NP-43%!!&a'58a&!3!!5dC*6%8"!!"A4NP-43%!!%a'58a&!3!
        +!@%C*6%8"!!"Z4NP-43%!!'p'58a&!3!"LNC*6%8"!!"X4NP-43%!!'e'58a&!3!
        +"L8C*6%8"!!',4NP-43%!!'9'58a&!3!!D8C*6%8"!!"S4NP-43%!!'G'58a&!3!
        +!BdC*6%8"!!"N4NP-43%!!'&'58a&!3!!DNC*6%8"!!"L4NP-43%!!'C'58a&!3!
        +!8dC*6%8"!!"84NP-43%!!&9'58a&!3!!9NC*6%8"!!"*4NP-43%!!%T'58a&!3!
        +!ANC*6%8"!!"54NP-43%!!$T'58a&!3!!GdC*6%8"!!!c4NP-43%!!(4'58a&!3!
        +!,dC*6%8"!!!Z4NP-43%!!#e'58a&!3!!28C*6%8"!!!d4NP-43%!!Ba'58a&!3!
        +!88C*6%8"!!!`4NP-43%!!&p'58a&!3!!B%C*6%8"!!"V4e*98!!!!!!!!!!!!Q*
        +Q!!!!"8C*6%8"!!##4NP-43%!!(p'58a&!3!!J%C*6%8"!!"q4NP-43%!!)&(8P9
        +3!!!!!!!!!!!$BQP[!!!!$NC*6%8"!!#%4NP-43%!!Be'58a&!3!!JdC*6%8"!!'
        +14NP-43%!!C&'58a&!3!"MdC*6%8"!!'3!%C*6%8"!!#&4NP-43%!!C*'58a&!3!
        +"J%C*6%8"!!'(4NP-43%!!C9'58a&!3!"NdC*6%8"!!'84e*98!!!!!!!!!!!!Q*
        +Z!!!!&%C*6%8"!!#'4NP-43%!!)P'58a&!3!!LdC*6%8"!!#14NP-43%!!DC'58a
        +&!3!!N8C*6%8"!!#64NP-43%!!*4'58a&!3!!PNC*6%8"!!#B4NP-43%!!)K'58a
        +&!3!!M8C*6%8"!!#54NP-43%!!)T'58a&!3!!PdC*6%8"!!#(4NP-43%!!*9'58a
        +&!3!!MdC*6%8"!!#3!%C*6%8"!!#-4e*98!!!!!!!!!!!"Q*eCQCPFJ!!!!*'58a
        +&!3!!Q8C*6%8"!!#D4e*98!!!!!!!!!!!"'0KFh3!!!!&4NP-43%!!*p'58a&!3!
        +!R%C*6%8"!!#G4NP-43%!!*Y'58a&!3!!RNG599!!!!!!!!!!!!4MEfe`!!!!!dC
        +*6%8"!!#J4NP-43%!!+&'58a&!3!!SNG599!!!!!!!!!!!!4MEfjQ!!!!!NC*6%8
        +"!!#M4NP-43%!!+4(8P93!!!!!!!!!!!$C'9c!!!!'NC*6%8"!!#P4NP-43%!!+C
        +'58a&!3!!U%C*6%8"!!#T4NP-43%!!+Y'58a&!3!!V%C*6%8"!!#Z4NP-43%!!CC
        +'58a&!3!!VdC*6%8"!!#b4NP-43%!!,0'58a&!3!!Y%C*6%8"!!#e4NP-43%!!,C
        +'58a&!3!!Z%C*6%8"!!#j4NP-43%!!,T'58a&!3!!UNC*6%8"!!#`4NP-43%!!,G
        +'58a&!3!![8C*6%8"!!#l4NP-43%!!+G'58a&!3!!X8C*6%8"!!#m4NP-43%!!+e
        +(8P93!!!!!!!!!!!#C'J!!!!&4NP-43%!!-"'58a&!3!!`8C*6%8"!!$#4NP-43%
        +!!,j'58a&!3!![dG599!!!!!!!!!!!!0NFf%!!!!)4NP-43%!!-9'58a&!3!!aNC
        +*6%8"!!$(4NP-43%!!-0'58a&!3!!b8C*6%8"!!$)4NP-43%!!-4'58a&!3!"JNG
        +599!!!!!!!!!!!!0PFR)!!!!$4NP-43%!!-T'58a&!3!!bdC*6%8"!!$-4e*98!!
        +!!!!!!!!!!f9fF!!!!$p'58a&!3!!ddC*6%8"!!$54NP-43%!!04'58a&!3!!eNC
        +*6%8"!!$V4NP-43%!!0e'58a&!3!!j%C*6%8"!!$c4NP-43%!!1a'58a&!3!!hNC
        +*6%8"!!$P4NP-43%!!24'58a&!3!!k%C*6%8"!!$D4NP-43%!!2G'58a&!3!"!NC
        +*6%8"!!$K4NP-43%!!2"'58a&!3!!q%C*6%8"!!$Y4NP-43%!!0p'58a&!3!!jNC
        +*6%8"!!$e4NP-43%!!1P'58a&!3!!fdC*6%8"!!$L4NP-43%!!2&'58a&!3!!kNC
        +*6%8"!!$F4NP-43%!!10'58a&!3!!mNC*6%8"!!$Z4NP-43%!!1"'58a&!3!!jdC
        +*6%8"!!$f4NP-43%!!2j'58a&!3!!qdC*6%8"!!$m4NP-43%!!3"'58a&!3!"!8C
        +*6%8"!!$j4NP-43%!!2T'58a&!3!!r8C*6%8"!!$r4NP-43%!!3C'58a&!3!""dC
        +*6%8"!!%)4NP-43%!!3P'58a&!3!""8C*6%8"!!%%4NP-43%!!30'58a&!3!!cdC
        +*6%8"!!$04NP-43%!!-j'58a&!3!!e8C*6%8"!!$[4NP-43%!!0&'58a&!3!!edC
        +*6%8"!!$34NP-43%!!0P'58a&!3!!f%C*6%8"!!'A4NP-43%!!CK(8P93!!!!!!!
        +!!!!%D'eKB`!!!!&'58a&!3!"#NG599!!!!!!!!!!!!4TC'9K!!!!"8C*6%8"!!%
        +,4NP-43%!!3a'58a&!3!"$NC*6%8"!!%04NP-43%!!3p(8P93!!!!!!!!!!!&E'K
        +KFfJ!!!!#4NP-43%!!4"'58a&!3!"%8G599!!!!!!!!!!!!0YC$)!!!!#4NP-43%
        +!!4*'58a&!3!"%dG599!!!!!!!!!!!!0YC$8!!!!#4NP-43%!!44'58a&!3!"&8G
        +599!!!!!!!!!!!!4YC'-b!!!!!NC*6%8"!!%@4NP-43%!!4G(8P93!!!!!!!!!!!
        +(Ef*UC@0dF`!!!!4'58a&!3!"'dC*6%8"!!%B4NP-43%!!4T'58a&!3!"'8G599!
        +!!!!!!!!!!!0`C@d!!!!'4NP-43%!!5&'58a&!3!")%C*6%8"!!%H4NP-43%!!4p
        +'58a&!3!"(%C*6%8"!!%G4e*98!!!!!!!!!!!"R"VBh-a-J!!!""'58a&!3!")NC
        +*6%8"!!%M4NP-43%!!54'58a&!3!"*8C*6%8"!!%Q4NP-43%!!5G'58a&!3!"+%C
        +*6%8"!!%T4NP-43%!!5T'58a&!3!"+dC*6%8"!!%X4NP-43%!!5e'58a&!3!",NC
        +*6%8"!!%[4NP-43%!!CP'58a&!3!"-%G599!!!!!!!!!!!!9`Df0c0`!!!!C'58a
        +&!3!"-NC*6%8"!!%c4NP-43%!!6&'58a&!3!"R%C*6%8"!!'D4NP-43%!!CY(8P9
        +3!!!!!!!!!!!%FQ&ZC!!!!!4'58a&!3!"0%C*6%8"!!%e4NP-43%!!6C'58a&!3!
        +"TdG599!!!!!!!!!!!!0bBc)!!!!&4NP-43%!!6T'58a&!3!"1dC*6%8"!!%j4NP
        +-43%!!6G'58a&!3!"1%G599!!!!!!!!!!!!0bBc3!!!!#4NP-43%!!6e'58a&!3!
        +"2%G599!!!!!!!!!!!!0bBc8!!!!&4NP-43%!!8*'58a&!3!"3%C*6%8"!!&"4NP
        +-43%!!6j'58a&!3!"2dG599!!!!!!!!!!!!CbDA"PE@3!!!!#4NP-43%!!80'58a
        +&!3!"4%G599!!!!!!!!!!!!0bFf%!!!!-4NP-43%!!89'58a&!3!"4dC*6%8"!!&
        +)4NP-43%!!8e'58a&!3!"6%C*6%8"!!&'4NP-43%!!8Y'58a&!3!"6NC*6%8"!!&
        +*4NP-43%!!8T'58a&!3!"R8C*6%8"!!'H4e*98!!!!!!!!!!!!h0SB3!!!!4'58a
        +&!3!"88C*6%8"!!&24NP-43%!!9*'58a&!3!"8%G599!!!!!!!!!!!!9cG'&MD`!
        +!!!&'58a&!3!"8dG599!!!!!!!!!!!!CdH(4IC')!!!!"4NP-43%!!94(8P93!!!
        +!!!!!!!!%H$8`13!!!"9'58a&!3!"A%C*6%8"!!&E4NP-43%!!@&'58a&!3!"@NC
        +*6%8"!!&J4NP-43%!!@*'58a&!3!"JdC*6%8"!!&Q4NP-43%!!@0'58a&!3!"@%C
        +*6%8"!!&G4NP-43%!!9G'58a&!3!"C8C*6%8"!!&H4NP-43%!!9P'58a&!3!"AdC
        +*6%8"!!&R4NP-43%!!@4'58a&!3!"K%C*6%8"!!&94NP-43%!!9C(8P93!!!!!!!
        +!!!!'H$8`1ABc!!!!&8C*6%8"!!&V4NP-43%!!@a'58a&!3!"E8C*6%8"!!&a4NP
        +-43%!!A0'58a&!3!"G8C*6%8"!!&h4NP-43%!!AT'58a&!3!"D%C*6%8"!!&b4NP
        +-43%!!@T'58a&!3!"H%C*6%8"!!&T4NP-43%!!AC'58a&!3!"G%C*6%8"!!&`4NP
        +-43%!!AP'58a&!3!"ENC*6%8"!!&[4NP-43%!!B9'58a&!3!"KNG599!!!!!!!!!
        +!!!0cFf`!!!!M4NP-43%!!"0'58a&!3!!&8C*6%8"!!!34NP-43%!!"*'58a&!3!
        +!%8C*6%8"!!!84NP-43%!!"T'58a&!3!!(%C*6%8"!!!A4NP-43%!!"P'58a&!3!
        +!'%C*6%8"!!!E4NP-43%!!"C'58a&!3!!$8C*6%8"!!!24NP-43%!!!Y'58a&!3!
        +!$%C*6%8"!!!14NP-43%!!#Y'58a&!3!!,%C*6%8"!!!S4NP-43%!!#T'58a&!3!
        +!+8C*6%8"!!!M4NP-43%!!#*'58a&!3!!(dC*6%8"!!!P4NP-43%!!#"'58a&!3!
        +!*NC*6%8"!!!N4NP-43%!!"j'58a&!3!!*dC*6%8"!!!G4NP-43%!!!T'58a&!3!
        +!)8G599!!!!!!!!!!!!j(990*)%aTBR*KFQPPF`!!!!0'58a&!J!!,dG599!!!!!
        +!!!!!!!038%-!!!!$4NP-43)!!$"'58a&!J!!-8C*6%8#!!!b4e*98!!!!!!!!!!
        +!!cBiD`!!!!0'58a&"3!!&%C*6%8&!!!94NP-438!!"C(8P93!!!!!!!!!!!138j
        +655"-D@*bBA*TCA-!!!!#4e*98!!!!!!!!!!!!e"33`!!!!*'58a&!3!!!8C*6%8
        +"!!&r4e*98!!!!!!!!!!!!cBiD`!!!!*'58a&!`!"S%C*6%8$!!'K4e*98!!!!!!
        +!!!!!$8eKBb"-D@*bBA*TCA-!!!!#4e*98!!!!!!!!!!!!e"33`!!!!P'58a&!3!
        +!"%C*6%8"!!!#4NP-43%!!!0'58a&!3!!#8C*6%8"!!!)4NP-43%!!!G'58a&!3!
        +!"NC*6%8"!!!&4NP-43%!!D9(8P93!!!!!!!!!!!$0MKV!!!!"NC*6%8$!!'D4NP
        +-43-!!D*'58a&!`!"R%C*6%8$!!'G4NP-43-!!Cp'58a&!`!"Q`!!!"J!!!)!!!)
        +!!!!!!J%!"3!!!!!#!J!-!!!!!!)$!!S!!!!!!J3!!J!!!!!#"3!&!!!!!!)'!!)
        +!!!!!!JF!"J!!!!!##!!0!!!!!!)*!!8!!!!!!JS!"3!!!!!##`!"!!!!!!)-!!%
        +!!!!!!Jd!"`!!!!!#$J!)!!!!!!)2!!8!!!!!!K!!!J!!!!!#%3!#!!!!!!)5!!J
        +!!!!!!K-!!3!!!!!#&!!"!!!!!!)9!!J!!!!!!KB!#3!!!!!#&`!%!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!!!!!!!!#"J%#!!!c"`%#!!!d!!!!!J3""3!!)!J""3!
        +!(`!!!HJ!!!)!!!!6k3!!&!!!!!(S!&j1G!!-6PB!!#m+,`-NEJ!35Ui!!!$*!!!
        +!i!!!&0i!!"J!!!!!b3!-,bi!##"U!-JJD!"i6T!!-"mf!!!!!K%!!!)5!!!#%`!
        +!!K3!!!)9!!!"p3!!!HJ!!!(H!!!"d3!!!IX!!!(3!!!"p!!!!I`!!!)"!!!"U3!
        +!!DS!!!'V!!!!,!!!!#d!!!!Z!!!!,`!!!$!!!!!a!!!!-J!!!$-!!!!d!!!!03!
        +!!$B!!!!h!!!!1!!!!$N!!!!k!!!!1`!!!BF!!!!m!!!!23!!!$i!!!!r!!!!3!!
        +!!%%!!!',!!!!3J!!!%-!!!"%!!!!43!!!%B!!!"(!!!"kJ!!!Am!!!"p!!!!IJ!
        +!!(m!!!'5!!!"N3!!!)!!!!#"!!!!c!!!!B`!!!$0!!!!JJ!!!)-!!!$1!!!!c`!
        +!!!N!!!(a!!!!K3!!!)B!!!#(!!!"T3!!!)J!!!#*!!!!LJ!!!)X!!!#-!!!!M3!
        +!!)i!!!#2!!!!N!!!!!#4!!!!NJ!!!*-!!!#8!!!!P3!!!*B!!!#A!!!"N`!!!Bi
        +!!!'2!!!"M3!!!C!!!!!!K!!!!*J!!!#C!!!#"!!!!93!!!&9!!!"P!!!!BB!!!)
        +(!!!##!!!!D`!!!#N!!!!T3!!!+B!!!#R!!!!U!!!!KB!!!'Y!!!!R`!!!+)!!!#
        +M!!!"R`!!!AS!!!'Z!!!"V`!!!AX!!!)!!!!"RJ!!!0!!!!#D!!!!Q`!!!*`!!!#
        +G!!!!S!!!!*i!!!#K!!!!5!!!!%N!!!"+!!!!5`!!!%`!!!"0!!!!6J!!!%m!!!)
        +&!!!#"J!!!+N!!!'`!!!"X3!!!,d!!!#q!!!![`!!!-!!!!$"!!!!d3!!!E)!!!'
        +c!!!!`J!!!--!!!$%!!!!a3!!!-B!!!'"!!!!a`!!!-J!!!#U!!!!U`!!!+`!!!'
        +d!!!!dJ!!!+d!!!'9!!!!b3!!!D!!!!'e!!!!bJ!!!-X!!!"3!!!!d`!!!03!!!$
        +9!!!!eJ!!!0F!!!$B!!!"I!!!!0N!!!$D!!!!f`!!!0`!!!$G!!!!hJ!!!0m!!!$
        +J!!!!i3!!!1)!!!$M!!!!j!!!!18!!!$Q!!!!j`!!!1J!!!$T!!!!kJ!!!1X!!!$
        +X!!!!l3!!!1i!!!$[!!!!m!!!!2%!!!$b!!!!m`!!!23!!!$e!!!!pJ!!!2F!!!#
        +Z!!!!V`!!!J-!!!(D!!!"l3!!!&%!!!"5!!!!8`!!!H`!!!'f!!!"Y`!!!EJ!!!(
        +L!!!"i!!!!D%!!!(E!!!"c3!!!F`!!!(F!!!"cJ!!!Gd!!!(2!!!"#3!!!&3!!!"
        +9!!!!9J!!!&F!!!"B!!!!@3!!!&S!!!"E!!!!!3!!!3S!!!%,!!!"$!!!!3d!!!%
        +1!!!"$`!!!4!!!!(f!!!"k3!!!HF!!!(Q!!!"i`!!!H8!!!(I!!!"rJ!!!Id!!!(
        +5!!!"SJ!!!!)!!!(C!!!"%3!!!4)!!!%6!!!"&!!!!48!!!%@!!!"-`!!!Ad!!!'
        +M!!!"p`!!!GJ!!!!!!!!"d`!!!!-!!!(A!!!"IJ!!!IJ!!!(V!!!"q3!!!Hi!!!$
        +i!!!!q3!!!2S!!!$l!!!!r!!!!2d!!!$q!!!!r`!!!3!!!!%"!!!"Z3!!!&`!!!"
        +G!!!"&`!!!4J!!!%C!!!!X!!!!,%!!!#b!!!"j!!!!H%!!!'k!!!"e!!!!!3!!!!
        +&!!!"e3!!!GB!!!!'!!!!"`!!!4S!!!%K!!!")J!!!5-!!!%N!!!"*3!!!5B!!!%
        +R!!!"+!!!!5N!!!%U!!!"+`!!!5`!!!'B!!!",3!!!5i!!!'@!!!"P`!!!&i!!!"
        +I!!!!B!!!!'%!!!"L!!!!B`!!!'3!!!"P!!!!CJ!!!'F!!!"S!!!!D3!!!'S!!!#
        +c!!!"qJ!!!I-!!!%E!!!"(!!!!4d!!!%H!!!"(`!!!5!!!!%[!!!"Q3!!!6!!!!%
        +a!!!"QJ!!!CX!!!'l!!!"[!!!!6)!!!'p!!!"T!!!!JN!!!)+!!!##`!!!J`!!!)
        +0!!!#$J!!!I!!!!)2!!!"!J!!!3-!!!%%!!!""3!!!3B!!!%(!!!"#!!!!,3!!!%
        +d!!!"T`!!!DB!!!#e!!!"03!!!6B!!!%h!!!"1!!!!6N!!!%k!!!"1`!!!6`!!!%
        +p!!!"2J!!!6m!!!&!!!!"33!!!,B!!!#h!!!"[J!!!Hm!!!)3!!!"3J!!!8-!!!#
        +i!!!"[`!!!C`!!!&%!!!"43!!!8B!!!&(!!!"5!!!!Cd!!!&*!!!"5J!!!8X!!!&
        +-!!!"63!!!!S!!!!,!!!!$!!!!!d!!!!1!!!!$`!!!"!!!!!4!!!!%J!!!"-!!!!
        +8!!!!&3!!!"B!!!!A!!!!'!!!!"N!!!!D!!!!'`!!!F!!!!#j!!!"6J!!!8m!!!&
        +3!!!"83!!!F%!!!(r!!!"`J!!!F-!!!!F!!!!(3!!!"i!!!!I!!!!)!!!!#%!!!!
        +L!!!!)`!!!#3!!!!P!!!!*J!!!9)!!!#k!!!!Z`!!!F3!!!(&!!!"aJ!!!FF!!!(
        +,!!!!*`!!!#J!!!!T!!!!+J!!!#X!!!)#!!!!#!!!!9-!!!'+!!!!D`!!!'`!!!"
        +Y!!!"L!!!!'i!!!'*!!!"C`!!!@J!!!&T!!!"DJ!!!@X!!!&X!!!"E3!!!@i!!!&
        +[!!!"F!!!!A%!!!&b!!!"K3!!!A-!!!&d!!!"G3!!!AB!!!'%!!!"G`!!!AJ!!!&
        +j!!!"b!!!!FN!!!'S!!!"bJ!!!9B!!!&A!!!"JJ!!!9J!!!&C!!!"@J!!!9X!!!&
        +F!!!"A3!!!9i!!!&I!!!"B!!!!@%!!!&L!!!"J`!!!@-!!!&N!!!"C3!!!,`!!!(
        +b!!!!E`!!!@B!!!"`!!!!F3!!!()!!!"c!!!!G!!!!(8!!!"f!!!!G`!!!(J!!!"
        +j!!!!HJ!!!(X!!!"m!!!"J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!"!!!!-P*26e3!!!!!!!!!!!!!!!!'4e*98!!!!!!!!!!"$P*[H5Gc)%G
        +PG%K89&"6!!!!"8C*6%8"!!'L4NP-43%!!D0'58a&!3!"U%C*6%8"!!'K4NP-43%
        +!!D"(8P93!!!!!!!!!!)66h"PEP066#""F("XD@0KG'P[EJ!!!#0'58a&!J!!(%C
        +*6%8#!!!U4NP-43)!!!e'58a&!J!!)%C*6%8#!!!54NP-43)!!"0'58a&!J!!&NC
        +*6%8#!!!B4NP-43)!!"G'58a&!J!!$NC*6%8#!!!H4NP-43)!!"&'58a&!J!!%%C
        +*6%8#!!!K4NP-43)!!"4'58a&!J!!&8C*6%8#!!!X4NP-43)!!"T'58a&!J!!'8C
        +*6%8#!!!S4NP-43)!!#G'58a&!J!!*%C*6%8#!!!Y4NP-43)!!!Y'58a&!J!!*NC
        +*6%8#!!!T4NP-43)!!!a'58a&!J!!+dC*6%8#!!!L4NP-43)!!!p'58a&!J!!'dC
        +*6%8#!!!G4NP-43)!!"p'58a&!J!!*8C*6%8#!!!M4e*98!!!!!!!!!!$%8p`C@j
        +68d`J6'PLFQ&bD@9c!!!!"%G599!!!!!!!!!!"!038%-!!!!#4NP-43)!!$0'58a
        +&!J!!0%G599!!!!!!!!!!"3-f1'X!!!!#4NP-438!!#"'58a&"3!!(dG599!!!!!
        +!!!!!"JCMFRP`G'm!!!!S4NP-43%!!Aa'58a&!3!"INC*6%8"!!'N4NP-43%!!Cp
        +'58a&!3!"I8C*6%8"!!&l4e*98!!!!!!!!!!("'&cEM%!!!"A4NP-43%!!$j'58a
        +&!3!!-8C*6%8"!!"&4NP-43%!!$P'58a&!3!!3dC*6%8"!!!m4NP-43%!!$p'58a
        +&!3!!3%C*6%8"!!"%4NP-43%!!%&'58a&!3!!0dC*6%8"!!!e4NP-43%!!$Y'58a
        +&!3!!-NC*6%8"!!!i4NP-43%!!%K'58a&!3!!4NC*6%8"!!"#4NP-43%!!$C'58a
        +&!3!!4dC*6%8"!!')4NP-43%!!("'58a&!3!!I%C*6%8"!!"i4NP-43%!!(T'58a
        +&!3!!H8C*6%8"!!"a4NP-43%!!(C'58a&!3!!FNC*6%8"!!"p4NP-43%!!B&'58a
        +&!3!!FdC*6%8"!!"e4NP-43%!!(Y'58a&!3!!A8C*6%8"!!"04NP-43%!!&P'58a
        +&!3!!6NC*6%8"!!"D4NP-43%!!%p'58a&!3!!@dC*6%8"!!"34NP-43%!!&a'58a
        +&!3!!5dC*6%8"!!"A4NP-43%!!%a'58a&!3!!@%C*6%8"!!"Z4NP-43%!!'p'58a
        +&!3!"LNC*6%8"!!"X4NP-43%!!'e'58a&!3!"L8C*6%8"!!',4NP-43%!!'9'58a
        +&!3!!D8C*6%8"!!"S4NP-43%!!'G'58a&!3!!BdC*6%8"!!"N4NP-43%!!'&'58a
        +&!3!!DNC*6%8"!!"L4NP-43%!!'C'58a&!3!!8dC*6%8"!!"84NP-43%!!&9'58a
        +&!3!!9NC*6%8"!!"*4NP-43%!!%T'58a&!3!!ANC*6%8"!!"54NP-43%!!$T'58a
        +&!3!!GdC*6%8"!!!c4NP-43%!!(4'58a&!3!!,dC*6%8"!!!Z4NP-43%!!#e'58a
        +&!3!!28C*6%8"!!!d4NP-43%!!Ba'58a&!3!!88C*6%8"!!!`4NP-43%!!&p'58a
        +&!3!!B%C*6%8"!!"V4e*98!!!!!!!!!!)!Q*Q!!!!"8C*6%8"!!##4NP-43%!!(p
        +'58a&!3!!J%C*6%8"!!"q4NP-43%!!)&(8P93!!!!!!!!!!N$BQP[!!!!$NC*6%8
        +"!!#%4NP-43%!!Be'58a&!3!!JdC*6%8"!!'14NP-43%!!C&'58a&!3!"MdC*6%8
        +"!!'3!%C*6%8"!!#&4NP-43%!!C*'58a&!3!"J%C*6%8"!!'(4NP-43%!!C9'58a
        +&!3!"NdC*6%8"!!'84e*98!!!!!!!!!!+!Q*Z!!!!&%C*6%8"!!#'4NP-43%!!)P
        +'58a&!3!!LdC*6%8"!!#14NP-43%!!DC'58a&!3!!N8C*6%8"!!#64NP-43%!!*4
        +'58a&!3!!PNC*6%8"!!#B4NP-43%!!)K'58a&!3!!M8C*6%8"!!#54NP-43%!!)T
        +'58a&!3!!PdC*6%8"!!#(4NP-43%!!*9'58a&!3!!MdC*6%8"!!#3!%C*6%8"!!#
        +-4e*98!!!!!!!!!!,"Q*eCQCPFJ!!!!*'58a&!3!!Q8C*6%8"!!#D4e*98!!!!!!
        +!!!!-"'0KFh3!!!!&4NP-43%!!*p'58a&!3!!R%C*6%8"!!#G4NP-43%!!*Y'58a
        +&!3!!RNG599!!!!!!!!!!$34MEfe`!!!!!dC*6%8"!!#J4NP-43%!!+&'58a&!3!
        +!SNG599!!!!!!!!!!$J4MEfjQ!!!!!NC*6%8"!!#M4NP-43%!!+4(8P93!!!!!!!
        +!!!m$C'9c!!!!'NC*6%8"!!#P4NP-43%!!+C'58a&!3!!U%C*6%8"!!#T4NP-43%
        +!!+Y'58a&!3!!V%C*6%8"!!#Z4NP-43%!!CC'58a&!3!!VdC*6%8"!!#b4NP-43%
        +!!,0'58a&!3!!Y%C*6%8"!!#e4NP-43%!!,C'58a&!3!!Z%C*6%8"!!#j4NP-43%
        +!!,T'58a&!3!!UNC*6%8"!!#`4NP-43%!!,G'58a&!3!![8C*6%8"!!#l4NP-43%
        +!!+G'58a&!3!!X8C*6%8"!!#m4NP-43%!!+e(8P93!!!!!!!!!"!#C'J!!!!&4NP
        +-43%!!-"'58a&!3!!`8C*6%8"!!$#4NP-43%!!,j'58a&!3!![dG599!!!!!!!!!
        +!%30NFf%!!!!)4NP-43%!!-9'58a&!3!!aNC*6%8"!!$(4NP-43%!!-0'58a&!3!
        +!b8C*6%8"!!$)4NP-43%!!-4'58a&!3!"JNG599!!!!!!!!!!%J0PFR)!!!!$4NP
        +-43%!!-T'58a&!3!!bdC*6%8"!!$-4e*98!!!!!!!!!!6!f9fF!!!!$p'58a&!3!
        +!ddC*6%8"!!$54NP-43%!!04'58a&!3!!eNC*6%8"!!$V4NP-43%!!0e'58a&!3!
        +!j%C*6%8"!!$c4NP-43%!!1a'58a&!3!!hNC*6%8"!!$P4NP-43%!!24'58a&!3!
        +!k%C*6%8"!!$D4NP-43%!!2G'58a&!3!"!NC*6%8"!!$K4NP-43%!!2"'58a&!3!
        +!q%C*6%8"!!$Y4NP-43%!!0p'58a&!3!!jNC*6%8"!!$e4NP-43%!!1P'58a&!3!
        +!fdC*6%8"!!$L4NP-43%!!2&'58a&!3!!kNC*6%8"!!$F4NP-43%!!10'58a&!3!
        +!mNC*6%8"!!$Z4NP-43%!!1"'58a&!3!!jdC*6%8"!!$f4NP-43%!!2j'58a&!3!
        +!qdC*6%8"!!$m4NP-43%!!3"'58a&!3!"!8C*6%8"!!$j4NP-43%!!2T'58a&!3!
        +!r8C*6%8"!!$r4NP-43%!!3C'58a&!3!""dC*6%8"!!%)4NP-43%!!3P'58a&!3!
        +""8C*6%8"!!%%4NP-43%!!30'58a&!3!!cdC*6%8"!!$04NP-43%!!-j'58a&!3!
        +!e8C*6%8"!!$[4NP-43%!!0&'58a&!3!!edC*6%8"!!$34NP-43%!!0P'58a&!3!
        +!f%C*6%8"!!'A4NP-43%!!CK(8P93!!!!!!!!!"3%D'eKB`!!!!&'58a&!3!"#NG
        +599!!!!!!!!!!&34TC'9K!!!!"8C*6%8"!!%,4NP-43%!!3a'58a&!3!"$NC*6%8
        +"!!%04NP-43%!!3p(8P93!!!!!!!!!"B&E'KKFfJ!!!!#4NP-43%!!4"'58a&!3!
        +"%8G599!!!!!!!!!!&`0YC$)!!!!#4NP-43%!!4*'58a&!3!"%dG599!!!!!!!!!
        +!'!0YC$8!!!!#4NP-43%!!44'58a&!3!"&8G599!!!!!!!!!!'34YC'-b!!!!!NC
        +*6%8"!!%@4NP-43%!!4G(8P93!!!!!!!!!"S(Ef*UC@0dF`!!!!4'58a&!3!"'dC
        +*6%8"!!%B4NP-43%!!4T'58a&!3!"'8G599!!!!!!!!!!'`0`C@d!!!!'4NP-43%
        +!!5&'58a&!3!")%C*6%8"!!%H4NP-43%!!4p'58a&!3!"(%C*6%8"!!%G4e*98!!
        +!!!!!!!!F"R"VBh-a-J!!!""'58a&!3!")NC*6%8"!!%M4NP-43%!!54'58a&!3!
        +"*8C*6%8"!!%Q4NP-43%!!5G'58a&!3!"+%C*6%8"!!%T4NP-43%!!5T'58a&!3!
        +"+dC*6%8"!!%X4NP-43%!!5e'58a&!3!",NC*6%8"!!%[4NP-43%!!CP'58a&!3!
        +"-%G599!!!!!!!!!!(39`Df0c0`!!!!C'58a&!3!"-NC*6%8"!!%c4NP-43%!!6&
        +'58a&!3!"R%C*6%8"!!'D4NP-43%!!CY(8P93!!!!!!!!!"i%FQ&ZC!!!!!4'58a
        +&!3!"0%C*6%8"!!%e4NP-43%!!6C'58a&!3!"TdG599!!!!!!!!!!(`0bBc)!!!!
        +&4NP-43%!!6T'58a&!3!"1dC*6%8"!!%j4NP-43%!!6G'58a&!3!"1%G599!!!!!
        +!!!!!)!0bBc3!!!!#4NP-43%!!6e'58a&!3!"2%G599!!!!!!!!!!)30bBc8!!!!
        +&4NP-43%!!8*'58a&!3!"3%C*6%8"!!&"4NP-43%!!6j'58a&!3!"2dG599!!!!!
        +!!!!!)JCbDA"PE@3!!!!#4NP-43%!!80'58a&!3!"4%G599!!!!!!!!!!)`0bFf%
        +!!!!-4NP-43%!!89'58a&!3!"4dC*6%8"!!&)4NP-43%!!8e'58a&!3!"6%C*6%8
        +"!!&'4NP-43%!!8Y'58a&!3!"6NC*6%8"!!&*4NP-43%!!8T'58a&!3!"R8C*6%8
        +"!!'H4e*98!!!!!!!!!!N!h0SB3!!!!4'58a&!3!"88C*6%8"!!&24NP-43%!!9*
        +'58a&!3!"8%G599!!!!!!!!!!*39cG'&MD`!!!!&'58a&!3!"8dG599!!!!!!!!!
        +!*JCdH(4IC')!!!!"4NP-43%!!94(8P93!!!!!!!!!#F%H$8`13!!!"9'58a&!3!
        +"A%C*6%8"!!&E4NP-43%!!@&'58a&!3!"@NC*6%8"!!&J4NP-43%!!@*'58a&!3!
        +"JdC*6%8"!!&Q4NP-43%!!@0'58a&!3!"@%C*6%8"!!&G4NP-43%!!9G'58a&!3!
        +"C8C*6%8"!!&H4NP-43%!!9P'58a&!3!"AdC*6%8"!!&R4NP-43%!!@4'58a&!3!
        +"K%C*6%8"!!&94NP-43%!!9C(8P93!!!!!!!!!#J'H$8`1ABc!!!!&8C*6%8"!!&
        +V4NP-43%!!@a'58a&!3!"E8C*6%8"!!&a4NP-43%!!A0'58a&!3!"G8C*6%8"!!&
        +h4NP-43%!!AT'58a&!3!"D%C*6%8"!!&b4NP-43%!!@T'58a&!3!"H%C*6%8"!!&
        +T4NP-43%!!AC'58a&!3!"G%C*6%8"!!&`4NP-43%!!AP'58a&!3!"ENC*6%8"!!&
        +[4NP-43%!!B9'58a&!3!"KNG599!!!!!!!!!!+30cFf`!!!!M4NP-43%!!"0'58a
        +&!3!!&8C*6%8"!!!34NP-43%!!"*'58a&!3!!%8C*6%8"!!!84NP-43%!!"T'58a
        +&!3!!(%C*6%8"!!!A4NP-43%!!"P'58a&!3!!'%C*6%8"!!!E4NP-43%!!"C'58a
        +&!3!!$8C*6%8"!!!24NP-43%!!!Y'58a&!3!!$%C*6%8"!!!14NP-43%!!#Y'58a
        +&!3!!,%C*6%8"!!!S4NP-43%!!#T'58a&!3!!+8C*6%8"!!!M4NP-43%!!#*'58a
        +&!3!!(dC*6%8"!!!P4NP-43%!!#"'58a&!3!!*NC*6%8"!!!N4NP-43%!!"j'58a
        +&!3!!*dC*6%8"!!!G4NP-43%!!!T'58a&!3!!)8G599!!!!!!!!!!+Jj(990*)%a
        +TBR*KFQPPF`!!!!0'58a&!J!!,dG599!!!!!!!!!!+`038%-!!!!$4NP-43)!!$"
        +'58a&!J!!-8C*6%8#!!!b4e*98!!!!!!!!!!X!cBiD`!!!!0'58a&"3!!&%C*6%8
        +&!!!94NP-438!!"C(8P93!!!!!!!!!#d138j655"-D@*bBA*TCA-!!!!#4e*98!!
        +!!!!!!!!Z!e"33`!!!!*'58a&!3!!!8C*6%8"!!&r4e*98!!!!!!!!!![!cBiD`!
        +!!!*'58a&!`!"S%C*6%8$!!'K4e*98!!!!!!!!!!`$8eKBb"-D@*bBA*TCA-!!!!
        +#4e*98!!!!!!!!!!a!e"33`!!!!P'58a&!3!!"%C*6%8"!!!#4NP-43%!!!0'58a
        +&!3!!#8C*6%8"!!!)4NP-43%!!!G'58a&!3!!"NC*6%8"!!!&4NP-43%!!D9(8P9
        +3!!!!!!!!!$)$0MKV!!!!"NC*6%8$!!'D4NP-43-!!D*'58a&!`!"R%C*6%8$!!'
        +G4NP-43-!!Cp'58a&!`!"Q`!!!4#V3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!"+!!!'!"YFh4b!!!!!!!!!!!!!!!!!!!C+!!!#S"YFh4X!!!!!!!
        +!!!!!!!!!!!!MU!!!!i"YFh4Z!!!!!!!!!!!!!!!!!!!R+!!!'!"YFh4b!!!$k!!
        +!!!!!!!!!!!!r+!!!'B"YFh4X!!!$k!!!!!!!!!!!!!0TDJ!!#)"YFh4Z!!!$k!!
        +!!!!!!!!!!!"E+!!!"4"`FQ9Q!!P'eJ!!!!%!!!!!!!"J1!!!!!K`FQ9Q!!L`,3!
        +!!!)!!!!!!!"J3!!!!"T`FQ9Q!!PX2!!!!!-!!!!!!!"J@J!!$+"`FQ9Q!!MrS3!
        +!!!3!!!!!!!"XqJ!!"K4`FQ9Q!!L+i3!!!!8!!!!!!!"c$J!!#*C`FQ9Q!!P5m!!
        +!!!B!!!!!!!"lT!!!!3G`FQ9Q!!Le63!!!!F!!!!!!!"mU`!!!b"`FQ9Q!!N!,`!
        +!!!J!!!!!!!"rb`!!!"4`FQ9Q!!NR4!!!!!N!!!!!!!"rh`!!!!T`FQ9Q!!M`UJ!
        +!!!S!!!!!!!"rk3!!!!a`FQ9Q!!L"hJ!!!!X!!!!!!!"rp3!!!!j`FQ9Q!!M0!!!
        +!!!`!!!!!!!#!!`!!!3C`FQ9Q!!Kpf3!!!!d!!!!!!!#"#3!!!$j`FQ9Q!!N#K!!
        +!!!i!!!!!!!#"4`!!!!j`FQ9Q!!PRC3!!!!m!!!!!!!#"93!!!GT`FQ9Q!!MG@`!
        +!!"!!!!!!!!#$,`!!!'*`FQ9Q!!M*!3!!!"%!!!!!!!#$N3!!!"4`FQ9Q!!MP"`!
        +!!")!!!!!!!#$T3!!!!T`FQ9Q!!LpV!!!!"-!!!!!!!#$V`!!!!a`FQ9Q!!PJK`!
        +!!"3!!!!!!!#$Z`!!!-T`FQ9Q!!L(e!!!!"8!!!!!!!#%K3!!!4K`FQ9Q!!LAh3!
        +!!"B!!!!!!!#&R3!!!+K`FQ9Q!!LpP!!!!"F!!!!!!!#'43!!!#j`FQ9Q!!PBJJ!
        +!!"J!!!!!!!#'F`!!!Ja`FQ9Q!!N()3!!!"N!!!!!!!#)I`!!4J"YG("X!!!!!3!
        +!!!!!!!!!!!$1I`!!"`"YG("c!!!!!3!!!!!!!!!!!!$9I`!!!""YG("T!!!!!3!
        +!!!!!!!!!!!$9M`!!"U"YG'a[!!!!!3!!!!!!!!!!!!$F,`!!!#"YG(0X!!!!!3!
        +!!!!!!!!!!!$F6`!!"4"`FQ9Q!!NN23!!!"S!!!!!!!$KA`!!!!K`FQ9Q!!M6`J!
        +!!"X!!!!!!!$KC`!!!"T`FQ9Q!!KkI3!!!"`!!!!!!!$KJ3!!%0"`FQ9Q!!LKD`!
        +!!"d!!!!!!!$b83!!"K4`FQ9Q!!PS2J!!!"i!!!!!!!$iC3!!#*C`FQ9Q!!M14`!
        +!!"m!!!!!!!%!q`!!!3G`FQ9Q!!P,IJ!!!#!!!!!!!!%#!J!!!b"`FQ9Q!!Mle3!
        +!!#%!!!!!!!%&)J!!!"4`FQ9Q!!NP93!!!#)!!!!!!!%&0J!!!!T`FQ9Q!!LIJJ!
        +!!#-!!!!!!!%&3!!!!!a`FQ9Q!!L8Z!!!!#3!!!!!!!%&6!!!!!j`FQ9Q!!P54!!
        +!!#8!!!!!!!%&@J!!!3C`FQ9Q!!P'2`!!!#B!!!!!!!%'B!!!!$j`FQ9Q!!N63!!
        +!!#F!!!!!!!%'RJ!!!!j`FQ9Q!!MZ(3!!!#J!!!!!!!%'V!!!!GT`FQ9Q!!Lmf!!
        +!!#N!!!!!!!%)KJ!!!'*`FQ9Q!!LrK!!!!#S!!!!!!!%)k!!!!"4`FQ9Q!!NchJ!
        +!!#X!!!!!!!%)r!!!!!T`FQ9Q!!M,S!!!!#`!!!!!!!%*"J!!!!a`FQ9Q!!N%'3!
        +!!#d!!!!!!!%*%J!!!-T`FQ9Q!!NJ2!!!!#i!!!!!!!%*h!!!!4K`FQ9Q!!PIl3!
        +!!#m!!!!!!!%+p!!!!+K`FQ9Q!!Lq%J!!!$!!!!!!!!%,R!!!!#j`FQ9Q!!LM0`!
        +!!$%!!!!!!!%,bJ!!!Ja`FQ9Q!!NG#`!!!$)!!!!!!!%0eJ!!#J"YG("X!!!!!J!
        +!!!!!!!!!!!%AeJ!!!3"YG("c!!!!!J!!!!!!!!!!!!%BeJ!!!""YG("T!!!!!J!
        +!!!!!!!!!!!%BjJ!!!0"YG'a[!!!!!J!!!!!!!!!!!!%CYJ!!!#"YG(0X!!!!!J!
        +!!!!!!!!!!!%CeJ!!"4"`FQ9Q!!PDj!!!!$-!!!!!!!%HjJ!!!!K`FQ9Q!!NN$!!
        +!!$3!!!!!!!%HlJ!!!"T`FQ9Q!!MT*`!!!$8!!!!!!!%I#!!!$+"`FQ9Q!!P`ZJ!
        +!!$B!!!!!!!%VU!!!"K4`FQ9Q!!N$-3!!!$F!!!!!!!%a[!!!#5C`FQ9Q!!L9f`!
        +!!$J!!!!!!!%kiJ!!!3G`FQ9Q!!LI%`!!!$N!!!!!!!%lk3!!!b"`FQ9Q!!Lj$!!
        +!!$S!!!!!!!%r#3!!!"4`FQ9Q!!MhR`!!!$X!!!!!!!%r(3!!!!T`FQ9Q!!M-hJ!
        +!!$`!!!!!!!%r*`!!!!a`FQ9Q!!N&m!!!!$d!!!!!!!%r-`!!!!j`FQ9Q!!P[``!
        +!!$i!!!!!!!%r33!!!3C`FQ9Q!!MmQ!!!!$m!!!!!!!&!4`!!!$j`FQ9Q!!MK!J!
        +!!%!!!!!!!!&!K3!!!!j`FQ9Q!!LfY`!!!%%!!!!!!!&!N`!!!GT`FQ9Q!!MPM!!
        +!!%)!!!!!!!&#E3!!!'*`FQ9Q!!PS+!!!!%-!!!!!!!&#c`!!!"4`FQ9Q!!MH03!
        +!!%3!!!!!!!&#i`!!!!T`FQ9Q!!PH+3!!!%8!!!!!!!&#l3!!!!a`FQ9Q!!L*a3!
        +!!%B!!!!!!!&#q3!!!-T`FQ9Q!!L*,!!!!%F!!!!!!!&$``!!!4K`FQ9Q!!MZ"!!
        +!!%J!!!!!!!&%f`!!!+K`FQ9Q!!L@Q`!!!%N!!!!!!!&&J`!!!#j`FQ9Q!!M8&3!
        +!!%S!!!!!!!&&X3!!!Ja`FQ9Q!!Lj"J!!!%X!!!!!!!&([3!!4J"YG("X!!!!!`!
        +!!!!!!!!!!!'0[3!!"`"YG("c!!!!!`!!!!!!!!!!!!'8[3!!!""YG("T!!!!!`!
        +!!!!!!!!!!!'8c3!!!#"YG(0X!!!!!`!!!!!!!!!!!!'8l3!!"T4YG'a[!!!!!`!
        +!!!!!!!!!!!'EJ3!!"4"`FQ9Q!!N*[!!!!%`!!!!!!!'JN3!!!!K`FQ9Q!!Kq93!
        +!!%d!!!!!!!'JQ3!!!"T`FQ9Q!!M+H`!!!%i!!!!!!!'JX`!!%0"`FQ9Q!!N6p!!
        +!!%m!!!!!!!'aJ`!!"K4`FQ9Q!!M$+3!!!&!!!!!!!!'hP`!!#5C`FQ9Q!!L!9`!
        +!!&%!!!!!!!(![3!!!3G`FQ9Q!!N`BJ!!!&)!!!!!!!("a!!!!b"`FQ9Q!!M3)3!
        +!!&-!!!!!!!(%j!!!!"4`FQ9Q!!L4H3!!!&3!!!!!!!(%q!!!!!T`FQ9Q!!NR0J!
        +!!&8!!!!!!!(&!J!!!!a`FQ9Q!!L'$3!!!&B!!!!!!!(&$J!!!!j`FQ9Q!!MR53!
        +!!&F!!!!!!!(&(!!!!3C`FQ9Q!!PEH!!!!&J!!!!!!!(')J!!!$j`FQ9Q!!MfA3!
        +!!&N!!!!!!!('B!!!!!j`FQ9Q!!N&53!!!&S!!!!!!!('EJ!!!GT`FQ9Q!!LB-`!
        +!!&X!!!!!!!()5!!!!'*`FQ9Q!!L6[3!!!&`!!!!!!!()UJ!!!"4`FQ9Q!!LeT`!
        +!!&d!!!!!!!()[J!!!!T`FQ9Q!!N,D`!!!&i!!!!!!!()b!!!!!a`FQ9Q!!LcY`!
        +!!&m!!!!!!!()e!!!!-T`FQ9Q!!LFj`!!!'!!!!!!!!(*RJ!!!4K`FQ9Q!!N!V3!
        +!!'%!!!!!!!(+YJ!!!+K`FQ9Q!!N(2!!!!')!!!!!!!(,AJ!!!#j`FQ9Q!!LQY!!
        +!!'-!!!!!!!(,M!!!!Ja`FQ9Q!!M053!!!'3!!!!!!!(0Q!!!#J"YG("X!!!!"!!
        +!!!!!!!!!!!(AQ!!!!3"YG("c!!!!"!!!!!!!!!!!!!(BQ!!!!""YG("T!!!!"!!
        +!!!!!!!!!!!(BU!!!!#"YG(0X!!!!"!!!!!!!!!!!!!(Bb!!!!)aYG'a[!!!!"!!
        +!!!!!!!!!!!(C9!!!"4"`FQ9Q!!MM#`!!!'8!!!!!!!(HC!!!!!K`FQ9Q!!M"$!!
        +!!'B!!!!!!!(HE!!!!"T`FQ9Q!!MYHJ!!!'F!!!!!!!(HKJ!!%0"`FQ9Q!!MKm`!
        +!!'J!!!!!!!([9J!!"K4`FQ9Q!!Nre3!!!'N!!!!!!!(eDJ!!#5C`FQ9Q!!LZ3J!
        +!!'S!!!!!!!(qN!!!!!%(F(*PCJ!)KRi!!!"V!!!!!!!"rjF!!!-JF(*PCJ!)PD8
        +!!!"X!!!!!!!#!VF!!!!8F(*PCJ!*0m)!!!"Y!!!!!!!#!XX!!!!+F(*PCJ!*AZd
        +!!!"Z!!!!!!!#!Y8!!!!-F(*PCJ!)Vii!!!"[!!!!!!!#!Z%!!!!1F(*PCJ!*,[d
        +!!!"`!!!!!!!#!Zm!!!%'F(*PCJ!*'EB!!!"a!!!!!!!#!r8!!!!qF(*PCJ!*0P8
        +!!!"b!!!!!!!#"$-!!!!1F(*PCJ!*-D%!!!"c!!!!!!!#"%%!!!(DF(*PCJ!*0"i
        +!!!"d!!!!!!!#"KX!!!"LF(*PCJ!)GH!!!!"e!!!!!!!#"Rd!!!!8F(*PCJ!)Q)S
        +!!!"f!!!!!!!#"T%!!!!+F(*PCJ!*!Pd!!!"h!!!!!!!#"TX!!!!-F(*PCJ!)PR-
        +!!!"i!!!!!!!#"UF!!!$+F(*PCJ!)TC!!!!!!H3!!!!!!!JGa!!!"'("bC@B!#-A
        +9!!!!HJ!!!!!!!JL*!!!!U("bC@B!#86U!!!!H`!!!!!!!JNa!!!!,R"bC@B!#@@
        +8!!!!I!!!!!!!!JPI!!!#$("bC@B!#(ep!!!!I3!!!!!!!JYV!!!&!'edF'`!!!!
        +&!!!!!!!!!!!!!K"V!!!!J'edF(-!!!!&!!!!!!!!!!!!!K$V!!!!%'edF'N!!!!
        +&!!!!!!!!!!!!!K$l!!!!)'edFf`!!!!&!!!!!!!!!!!!!K%E!!!!J'edE'm!!!!
        +&!!!!!!!!!!!!!K'E!!!&%("bC@B!#8UQ!!!!IJ!!!!!!!KDV!!!!#("bC@B!#22
        +(!!!!I`!!!!!!!KDc!!!!'R"bC@B!#3#p!!!!J!!!!!!!!KE0!!!3d("bC@B!#2`
        +[!!!!J3!!!!!!!LHG!!!'&("bC@B!#1[4!!!!JJ!!!!!!!Lfa!!!)PR"bC@B!#(,
        +9!!!!J`!!!!!!!MC(!!!""h"bC@B!#@rk!!!!K!!!!!!!!MG1!!!$)("bC@B!#1G
        +'!!!!K3!!!!!!!MTZ!!!!&("bC@B!#128!!!!KJ!!!!!!!MU#!!!!#R"bC@B!#,1
        +q!!!!K`!!!!!!!MU-!!!!$("bC@B!#)c'!!!!L!!!!!!!!MUB!!!!$R"bC@B!#4S
        +,!!!!L3!!!!!!!MUQ!!!""R"bC@B!#-iX!!!!LJ!!!!!!!MZX!!!!2R"bC@B!#(C
        +#!!!!L`!!!!!!!M[U!!!!$R"bC@B!#@+F!!!!M!!!!!!!!M[i!!!"fR"bC@B!#8(
        +h!!!!M3!!!!!!!Mh5!!!!BR"bC@B!#2!L!!!!MJ!!!!!!!Mid!!!!&("bC@B!#(d
        +@!!!!M`!!!!!!!Mj)!!!!#R"bC@B!#2iC!!!!N!!!!!!!!!)q8J!!!!a`FQ9Q!!M
        +YZ!!!!*%!!!!!!!)qAJ!!!-T`FQ9Q!!Pb83!!!*)!!!!!!!)r+!!!!4K`FQ9Q!!L
        +a"3!!!*-!!!!!!!*!3!!!!+K`FQ9Q!!NZf`!!!*3!!!!!!!*!k!!!!#j`FQ9Q!!K
        +j[`!!!*8!!!!!!!*"&J!!!Ja`FQ9Q!!Mi,3!!!*B!!!!!!!*$)J!!#J"YG("X!!!
        +!"J!!!!!!!!!!!!*0)J!!!3"YG("c!!!!"J!!!!!!!!!!!!*1)J!!!""YG("T!!!
        +!"J!!!!!!!!!!!!*1-J!!!)aYG'a[!!!!"J!!!!!!!!!!!!*1[J!!!#"YG(0X!!!
        +!"J!!!!!!!!!!!!*1hJ!!"4"`FQ9Q!!Kf)J!!!*F!!!!!!!*6lJ!!!!K`FQ9Q!!N
        +bh`!!!*J!!!!!!!*6pJ!!!"T`FQ9Q!!MZB3!!!*N!!!!!!!*8%!!!%0"`FQ9Q!!M
        +[m`!!!*S!!!!!!!*Ni!!!"K4`FQ9Q!!NVZ`!!!*X!!!!!!!*Up!!!#*C`FQ9Q!!M
        +b!J!!!*`!!!!!!!*cLJ!!!3G`FQ9Q!!P083!!!*d!!!!!!!*dN3!!!b"`FQ9Q!!M
        +a13!!!*i!!!!!!!*hX3!!!"4`FQ9Q!!P9h3!!!*m!!!!!!!*ha3!!!!T`FQ9Q!!M
        ++,3!!!+!!!!!!!!*hc`!!!!a`FQ9Q!!L6T`!!!+%!!!!!!!*hf`!!!!j`FQ9Q!!M
        +jB3!!!+)!!!!!!!*hk3!!!3C`FQ9Q!!L0Z`!!!+-!!!!!!!*il`!!!$j`FQ9Q!!M
        +P3J!!!+3!!!!!!!*j,3!!!!j`FQ9Q!!N6hJ!!!+8!!!!!!!*j1`!!!GT`FQ9Q!!N
        +kJ`!!!+B!!!!!!!*l&3!!!'*`FQ9Q!!N&H!!!!+F!!!!!!!*lG`!!!"4`FQ9Q!!L
        +,iJ!!!+J!!!!!!!*lL`!!!!T`FQ9Q!!MDI3!!!+N!!!!!!!*lP3!!!!a`FQ9Q!!K
        +l33!!!+S!!!!!!!*lS3!!!-T`FQ9Q!!MlG3!!!+X!!!!!!!*mD`!!!4K`FQ9Q!!L
        +e&!!!!+`!!!!!!!*pJ`!!!+K`FQ9Q!!MK1`!!!+d!!!!!!!*q+`!!!#j`FQ9Q!!L
        +Y#!!!!+i!!!!!!!*q@3!!!Ja`FQ9Q!!L42`!!!+m!!!!!!!+!C3!!2!"YG("X!!!
        +!"`!!!!!!!!!!!!+mC3!!"J"YG("c!!!!"`!!!!!!!!!!!!,#C3!!!""YG("T!!!
        +!"`!!!!!!!!!!!!,#G3!!"G4YG'a[!!!!"`!!!!!!!!!!!!,)53!!!#"YG(0X!!!
        +!"`!!!!!!!!!!!!,)D3!!"4"`FQ9Q!!NXL3!!!,!!!!!!!!,0H3!!!!K`FQ9Q!!P
        +%U3!!!,%!!!!!!!,0J3!!!"T`FQ9Q!!LT(!!!!,)!!!!!!!,0Q`!!%0"`FQ9Q!!N
        +(M3!!!,-!!!!!!!,HD`!!"K4`FQ9Q!!PH[`!!!,3!!!!!!!,NI`!!#5C`FQ9Q!!M
        +Hh!!!!,8!!!!!!!,YT3!!!3G`FQ9Q!!M`h!!!!,B!!!!!!!,ZV!!!!b"`FQ9Q!!L
        +N03!!!,F!!!!!!!,ac!!!!"4`FQ9Q!!Mb6J!!!,J!!!!!!!,ai!!!!!T`FQ9Q!!N
        +a@!!!!,N!!!!!!!,akJ!!!!a`FQ9Q!!LH1J!!!,S!!!!!!!,apJ!!!!j`FQ9Q!!N
        +"f3!!!,X!!!!!!!,b"!!!!3C`FQ9Q!!P`p!!!!,`!!!!!!!,c#J!!!$j`FQ9Q!!P
        +Qf!!!!,d!!!!!!!,c5!!!!!j`FQ9Q!!PYDJ!!!,i!!!!!!!,c9J!!!GT`FQ9Q!!N
        +#-!!!!,m!!!!!!!,e-!!!!'*`FQ9Q!!ME@!!!!-!!!!!!!!,eNJ!!!"4`FQ9Q!!L
        +j4`!!!-%!!!!!!!,eTJ!!!!T`FQ9Q!!Mf$3!!!-)!!!!!!!,eX!!!!!a`FQ9Q!!M
        +eDJ!!!--!!!!!!!,e[!!!!-T`FQ9Q!!MfF3!!!-3!!!!!!!,fKJ!!!4K`FQ9Q!!N
        +`R`!!!-8!!!!!!!,hRJ!!!+K`FQ9Q!!LqH3!!!-B!!!!!!!,i4J!!!#j`FQ9Q!!L
        +3!*S!!!$(!!!!!!!#q(3!!!)-F(*PCJ!)d'B!!!$)!!!!!!!#qS!!!$`!EA4`E!!
        +!!!J!!!!!!!!!!!!$0S!!!!B!EA4`F`!!!!J!!!!!!!!!!!!$2)!!!!!3EA4`D3!
        +!!!J!!!!!!!!!!!!$2*!!!!!!)'edFf`!!!!)!!!!!!!!!!!!!cb`!!!&e'edE'm
        +!!!!)!!!!!!!!!!!!!d+%!!!3a'edCf`!!!2S!!!!!!!!!!!!!e0)!!!!,'e[G'N
        +!!!!!!!!!!!!!!!!!!h(U!!!6J&"-Fh3!#,"V!!!!b3!!!!!!!&LS!!!#,'e`FfN
        +!!!2S!!!!!!!!!!!!!fMk!!!!%'ecG(!!!!!#!!!!!!!!!!!!!fN+!!!!%'ecG(!
        +!!!!&!!!!!!!!!!!!!&V8!!!!+'ecG'N!!!2S!!!!!!!!!!!!!fP#!!!!+'ecG'N
        +!!!!!!!!!!!!!!!!!!&Vm!!!!$'eKE'`!!!!!!!!!!!!!!!!!!fE1!!!!a'eKF'`
        +!!!!!!!!!!!!!!!$B03!!:
        diff --git a/vendor/openssl/openssl/MacOS/Randomizer.cpp b/vendor/openssl/openssl/MacOS/Randomizer.cpp
        new file mode 100644
        index 000000000..cceb6bde4
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/Randomizer.cpp
        @@ -0,0 +1,476 @@
        +/* 
        +------- Strong random data generation on a Macintosh (pre - OS X) ------
        +		
        +--	GENERAL: We aim to generate unpredictable bits without explicit
        +	user interaction. A general review of the problem may be found
        +	in RFC 1750, "Randomness Recommendations for Security", and some
        +	more discussion, of general and Mac-specific issues has appeared
        +	in "Using and Creating Cryptographic- Quality Random Numbers" by
        +	Jon Callas (www.merrymeet.com/jon/usingrandom.html).
        +
        +	The data and entropy estimates provided below are based on my
        +	limited experimentation and estimates, rather than by any
        +	rigorous study, and the entropy estimates tend to be optimistic.
        +	They should not be considered absolute.
        +
        +	Some of the information being collected may be correlated in
        +	subtle ways. That includes mouse positions, timings, and disk
        +	size measurements. Some obvious correlations will be eliminated
        +	by the programmer, but other, weaker ones may remain. The
        +	reliability of the code depends on such correlations being
        +	poorly understood, both by us and by potential interceptors.
        +
        +	This package has been planned to be used with OpenSSL, v. 0.9.5.
        +	It requires the OpenSSL function RAND_add. 
        +
        +--	OTHER WORK: Some source code and other details have been
        +	published elsewhere, but I haven't found any to be satisfactory
        +	for the Mac per se:
        +
        +	* The Linux random number generator (by Theodore Ts'o, in
        +	  drivers/char/random.c), is a carefully designed open-source
        +	  crypto random number package. It collects data from a variety
        +	  of sources, including mouse, keyboard and other interrupts.
        +	  One nice feature is that it explicitly estimates the entropy
        +	  of the data it collects. Some of its features (e.g. interrupt
        +	  timing) cannot be reliably exported to the Mac without using
        +	  undocumented APIs.
        +
        +	* Truerand by Don P. Mitchell and Matt Blaze uses variations
        +	  between different timing mechanisms on the same system. This
        +	  has not been tested on the Mac, but requires preemptive
        +	  multitasking, and is hardware-dependent, and can't be relied
        +	  on to work well if only one oscillator is present.
        +
        +	* Cryptlib's RNG for the Mac (RNDMAC.C by Peter Gutmann),
        +	  gathers a lot of information about the machine and system
        +	  environment. Unfortunately, much of it is constant from one
        +	  startup to the next. In other words, the random seed could be
        +	  the same from one day to the next. Some of the APIs are
        +	  hardware-dependent, and not all are compatible with Carbon (OS
        +	  X). Incidentally, the EGD library is based on the UNIX entropy
        +	  gathering methods in cryptlib, and isn't suitable for MacOS
        +	  either.
        +
        +	* Mozilla (and perhaps earlier versions of Netscape) uses the
        +	  time of day (in seconds) and an uninitialized local variable
        +	  to seed the random number generator. The time of day is known
        +	  to an outside interceptor (to within the accuracy of the
        +	  system clock). The uninitialized variable could easily be
        +	  identical between subsequent launches of an application, if it
        +	  is reached through the same path.
        +
        +	* OpenSSL provides the function RAND_screen(), by G. van
        +	  Oosten, which hashes the contents of the screen to generate a
        +	  seed. This is not useful for an extension or for an
        +	  application which launches at startup time, since the screen
        +	  is likely to look identical from one launch to the next. This
        +	  method is also rather slow.
        +
        +	* Using variations in disk drive seek times has been proposed
        +	  (Davis, Ihaka and Fenstermacher, world.std.com/~dtd/;
        +	  Jakobsson, Shriver, Hillyer and Juels,
        +	  www.bell-labs.com/user/shriver/random.html). These variations
        +	  appear to be due to air turbulence inside the disk drive
        +	  mechanism, and are very strongly unpredictable. Unfortunately
        +	  this technique is slow, and some implementations of it may be
        +	  patented (see Shriver's page above.) It of course cannot be
        +	  used with a RAM disk.
        +
        +--	TIMING: On the 601 PowerPC the time base register is guaranteed
        +	to change at least once every 10 addi instructions, i.e. 10
        +	cycles. On a 60 MHz machine (slowest PowerPC) this translates to
        +	a resolution of 1/6 usec. Newer machines seem to be using a 10
        +	cycle resolution as well.
        +	
        +	For 68K Macs, the Microseconds() call may be used. See Develop
        +	issue 29 on the Apple developer site
        +	(developer.apple.com/dev/techsupport/develop/issue29/minow.html)
        +	for information on its accuracy and resolution. The code below
        +	has been tested only on PowerPC based machines.
        +
        +	The time from machine startup to the launch of an application in
        +	the startup folder has a variance of about 1.6 msec on a new G4
        +	machine with a defragmented and optimized disk, most extensions
        +	off and no icons on the desktop. This can be reasonably taken as
        +	a lower bound on the variance. Most of this variation is likely
        +	due to disk seek time variability. The distribution of startup
        +	times is probably not entirely even or uncorrelated. This needs
        +	to be investigated, but I am guessing that it not a majpor
        +	problem. Entropy = log2 (1600/0.166) ~= 13 bits on a 60 MHz
        +	machine, ~16 bits for a 450 MHz machine.
        +
        +	User-launched application startup times will have a variance of
        +	a second or more relative to machine startup time. Entropy >~22
        +	bits.
        +
        +	Machine startup time is available with a 1-second resolution. It
        +	is predictable to no better a minute or two, in the case of
        +	people who show up punctually to work at the same time and
        +	immediately start their computer. Using the scheduled startup
        +	feature (when available) will cause the machine to start up at
        +	the same time every day, making the value predictable. Entropy
        +	>~7 bits, or 0 bits with scheduled startup.
        +
        +	The time of day is of course known to an outsider and thus has 0
        +	entropy if the system clock is regularly calibrated.
        +
        +--	KEY TIMING: A  very fast typist (120 wpm) will have a typical
        +	inter-key timing interval of 100 msec. We can assume a variance
        +	of no less than 2 msec -- maybe. Do good typists have a constant
        +	rhythm, like drummers? Since what we measure is not the
        +	key-generated interrupt but the time at which the key event was
        +	taken off the event queue, our resolution is roughly the time
        +	between process switches, at best 1 tick (17 msec). I  therefore
        +	consider this technique questionable and not very useful for
        +	obtaining high entropy data on the Mac.
        +
        +--	MOUSE POSITION AND TIMING: The high bits of the mouse position
        +	are far from arbitrary, since the mouse tends to stay in a few
        +	limited areas of the screen. I am guessing that the position of
        +	the mouse is arbitrary within a 6 pixel square. Since the mouse
        +	stays still for long periods of time, it should be sampled only
        +	after it was moved, to avoid correlated data. This gives an
        +	entropy of log2(6*6) ~= 5 bits per measurement.
        +
        +	The time during which the mouse stays still can vary from zero
        +	to, say, 5 seconds (occasionally longer). If the still time is
        +	measured by sampling the mouse during null events, and null
        +	events are received once per tick, its resolution is 1/60th of a
        +	second, giving an entropy of log2 (60*5) ~= 8 bits per
        +	measurement. Since the distribution of still times is uneven,
        +	this estimate is on the high side.
        +
        +	For simplicity and compatibility across system versions, the
        +	mouse is to be sampled explicitly (e.g. in the event loop),
        +	rather than in a time manager task.
        +
        +--	STARTUP DISK TOTAL FILE SIZE: Varies typically by at least 20k
        +	from one startup to the next, with 'minimal' computer use. Won't
        +	vary at all if machine is started again immediately after
        +	startup (unless virtual memory is on), but any application which
        +	uses the web and caches information to disk is likely to cause
        +	this much variation or more. The variation is probably not
        +	random, but I don't know in what way. File sizes tend to be
        +	divisible by 4 bytes since file format fields are often
        +	long-aligned. Entropy > log2 (20000/4) ~= 12 bits.
        +	
        +--	STARTUP DISK FIRST AVAILABLE ALLOCATION BLOCK: As the volume
        +	gets fragmented this could be anywhere in principle. In a
        +	perfectly unfragmented volume this will be strongly correlated
        +	with the total file size on the disk. With more fragmentation
        +	comes less certainty. I took the variation in this value to be
        +	1/8 of the total file size on the volume.
        +
        +--	SYSTEM REQUIREMENTS: The code here requires System 7.0 and above
        +	(for Gestalt and Microseconds calls). All the calls used are
        +	Carbon-compatible.
        +*/
        +
        +/*------------------------------ Includes ----------------------------*/
        +
        +#include "Randomizer.h"
        +
        +// Mac OS API
        +#include <Files.h>
        +#include <Folders.h>
        +#include <Events.h>
        +#include <Processes.h>
        +#include <Gestalt.h>
        +#include <Resources.h>
        +#include <LowMem.h>
        +
        +// Standard C library
        +#include <stdlib.h>
        +#include <math.h>
        +
        +/*---------------------- Function declarations -----------------------*/
        +
        +// declared in OpenSSL/crypto/rand/rand.h
        +extern "C" void RAND_add (const void *buf, int num, double entropy);
        +
        +unsigned long GetPPCTimer (bool is601);	// Make it global if needed
        +					// elsewhere
        +
        +/*---------------------------- Constants -----------------------------*/
        +
        +#define kMouseResolution 6		// Mouse position has to differ
        +					// from the last one by this
        +					// much to be entered
        +#define kMousePositionEntropy 5.16	// log2 (kMouseResolution**2)
        +#define kTypicalMouseIdleTicks 300.0	// I am guessing that a typical
        +					// amount of time between mouse
        +					// moves is 5 seconds
        +#define kVolumeBytesEntropy 12.0	// about log2 (20000/4),
        +					// assuming a variation of 20K
        +					// in total file size and
        +					// long-aligned file formats.
        +#define kApplicationUpTimeEntropy 6.0	// Variance > 1 second, uptime
        +					// in ticks  
        +#define kSysStartupEntropy 7.0		// Entropy for machine startup
        +					// time
        +
        +
        +/*------------------------ Function definitions ----------------------*/
        +
        +CRandomizer::CRandomizer (void)
        +{
        +	long	result;
        +	
        +	mSupportsLargeVolumes =
        +		(Gestalt(gestaltFSAttr, &result) == noErr) &&
        +		((result & (1L << gestaltFSSupports2TBVols)) != 0);
        +	
        +	if (Gestalt (gestaltNativeCPUtype, &result) != noErr)
        +	{
        +		mIsPowerPC = false;
        +		mIs601 = false;
        +	}
        +	else
        +	{
        +		mIs601 = (result == gestaltCPU601);
        +		mIsPowerPC = (result >= gestaltCPU601);
        +	}
        +	mLastMouse.h = mLastMouse.v = -10;	// First mouse will
        +						// always be recorded
        +	mLastPeriodicTicks = TickCount();
        +	GetTimeBaseResolution ();
        +	
        +	// Add initial entropy
        +	AddTimeSinceMachineStartup ();
        +	AddAbsoluteSystemStartupTime ();
        +	AddStartupVolumeInfo ();
        +	AddFiller ();
        +}
        +
        +void CRandomizer::PeriodicAction (void)
        +{
        +	AddCurrentMouse ();
        +	AddNow (0.0);	// Should have a better entropy estimate here
        +	mLastPeriodicTicks = TickCount();
        +}
        +
        +/*------------------------- Private Methods --------------------------*/
        +
        +void CRandomizer::AddCurrentMouse (void)
        +{
        +	Point mouseLoc;
        +	unsigned long lastCheck;	// Ticks since mouse was last
        +					// sampled
        +
        +#if TARGET_API_MAC_CARBON
        +	GetGlobalMouse (&mouseLoc);
        +#else
        +	mouseLoc = LMGetMouseLocation();
        +#endif
        +	
        +	if (labs (mLastMouse.h - mouseLoc.h) > kMouseResolution/2 &&
        +	    labs (mLastMouse.v - mouseLoc.v) > kMouseResolution/2)
        +		AddBytes (&mouseLoc, sizeof (mouseLoc),
        +				kMousePositionEntropy);
        +	
        +	if (mLastMouse.h == mouseLoc.h && mLastMouse.v == mouseLoc.v)
        +		mMouseStill ++;
        +	else
        +	{
        +		double entropy;
        +		
        +		// Mouse has moved. Add the number of measurements for
        +		// which it's been still. If the resolution is too
        +		// coarse, assume the entropy is 0.
        +
        +		lastCheck = TickCount() - mLastPeriodicTicks;
        +		if (lastCheck <= 0)
        +			lastCheck = 1;
        +		entropy = log2l
        +			(kTypicalMouseIdleTicks/(double)lastCheck);
        +		if (entropy < 0.0)
        +			entropy = 0.0;
        +		AddBytes (&mMouseStill, sizeof (mMouseStill), entropy);
        +		mMouseStill = 0;
        +	}
        +	mLastMouse = mouseLoc;
        +}
        +
        +void CRandomizer::AddAbsoluteSystemStartupTime (void)
        +{
        +	unsigned long	now;		// Time in seconds since
        +					// 1/1/1904
        +	GetDateTime (&now);
        +	now -= TickCount() / 60;	// Time in ticks since machine
        +					// startup
        +	AddBytes (&now, sizeof (now), kSysStartupEntropy);
        +}
        +
        +void CRandomizer::AddTimeSinceMachineStartup (void)
        +{
        +	AddNow (1.5);			// Uncertainty in app startup
        +					// time is > 1.5 msec (for
        +					// automated app startup).
        +}
        +
        +void CRandomizer::AddAppRunningTime (void)
        +{
        +	ProcessSerialNumber PSN;
        +	ProcessInfoRec		ProcessInfo;
        +	
        +	ProcessInfo.processInfoLength = sizeof (ProcessInfoRec);
        +	ProcessInfo.processName = nil;
        +	ProcessInfo.processAppSpec = nil;
        +	
        +	GetCurrentProcess (&PSN);
        +	GetProcessInformation (&PSN, &ProcessInfo);
        +
        +	// Now add the amount of time in ticks that the current process
        +	// has been active
        +
        +	AddBytes (&ProcessInfo, sizeof (ProcessInfoRec),
        +			kApplicationUpTimeEntropy);
        +}
        +
        +void CRandomizer::AddStartupVolumeInfo (void)
        +{
        +	short			vRefNum;
        +	long			dirID;
        +	XVolumeParam	pb;
        +	OSErr			err;
        +	
        +	if (!mSupportsLargeVolumes)
        +		return;
        +		
        +	FindFolder (kOnSystemDisk, kSystemFolderType, kDontCreateFolder,
        +			&vRefNum, &dirID);
        +	pb.ioVRefNum = vRefNum;
        +	pb.ioCompletion = 0;
        +	pb.ioNamePtr = 0;
        +	pb.ioVolIndex = 0;
        +	err = PBXGetVolInfoSync (&pb);
        +	if (err != noErr)
        +		return;
        +		
        +	// Base the entropy on the amount of space used on the disk and
        +	// on the next available allocation block. A lot else might be
        +	// unpredictable, so might as well toss the whole block in. See
        +	// comments for entropy estimate justifications.
        +
        +	AddBytes (&pb, sizeof (pb),
        +		kVolumeBytesEntropy +
        +		log2l (((pb.ioVTotalBytes.hi - pb.ioVFreeBytes.hi)
        +				* 4294967296.0D +
        +			(pb.ioVTotalBytes.lo - pb.ioVFreeBytes.lo))
        +				/ pb.ioVAlBlkSiz - 3.0));
        +}
        +
        +/*
        +	On a typical startup CRandomizer will come up with about 60
        +	bits of good, unpredictable data. Assuming no more input will
        +	be available, we'll need some more lower-quality data to give
        +	OpenSSL the 128 bits of entropy it desires. AddFiller adds some
        +	relatively predictable data into the soup.
        +*/
        +
        +void CRandomizer::AddFiller (void)
        +{
        +	struct
        +	{
        +		ProcessSerialNumber psn;	// Front process serial
        +						// number
        +		RGBColor	hiliteRGBValue;	// User-selected
        +						// highlight color
        +		long		processCount;	// Number of active
        +						// processes
        +		long		cpuSpeed;	// Processor speed
        +		long		totalMemory;	// Total logical memory
        +						// (incl. virtual one)
        +		long		systemVersion;	// OS version
        +		short		resFile;	// Current resource file
        +	} data;
        +	
        +	GetNextProcess ((ProcessSerialNumber*) kNoProcess);
        +	while (GetNextProcess (&data.psn) == noErr)
        +		data.processCount++;
        +	GetFrontProcess (&data.psn);
        +	LMGetHiliteRGB (&data.hiliteRGBValue);
        +	Gestalt (gestaltProcClkSpeed, &data.cpuSpeed);
        +	Gestalt (gestaltLogicalRAMSize, &data.totalMemory);
        +	Gestalt (gestaltSystemVersion, &data.systemVersion);
        +	data.resFile = CurResFile ();
        +	
        +	// Here we pretend to feed the PRNG completely random data. This
        +	// is of course false, as much of the above data is predictable
        +	// by an outsider. At this point we don't have any more
        +	// randomness to add, but with OpenSSL we must have a 128 bit
        +	// seed before we can start. We just add what we can, without a
        +	// real entropy estimate, and hope for the best.
        +
        +	AddBytes (&data, sizeof(data), 8.0 * sizeof(data));
        +	AddCurrentMouse ();
        +	AddNow (1.0);
        +}
        +
        +//-------------------  LOW LEVEL ---------------------
        +
        +void CRandomizer::AddBytes (void *data, long size, double entropy)
        +{
        +	RAND_add (data, size, entropy * 0.125);	// Convert entropy bits
        +						// to bytes
        +}
        +
        +void CRandomizer::AddNow (double millisecondUncertainty)
        +{
        +	long time = SysTimer();
        +	AddBytes (&time, sizeof (time), log2l (millisecondUncertainty *
        +			mTimebaseTicksPerMillisec));
        +}
        +
        +//----------------- TIMING SUPPORT ------------------
        +
        +void CRandomizer::GetTimeBaseResolution (void)
        +{	
        +#ifdef __powerc
        +	long speed;
        +	
        +	// gestaltProcClkSpeed available on System 7.5.2 and above
        +	if (Gestalt (gestaltProcClkSpeed, &speed) != noErr)
        +		// Only PowerPCs running pre-7.5.2 are 60-80 MHz
        +		// machines.
        +		mTimebaseTicksPerMillisec =  6000.0D;
        +	// Assume 10 cycles per clock update, as in 601 spec. Seems true
        +	// for later chips as well.
        +	mTimebaseTicksPerMillisec = speed / 1.0e4D;
        +#else
        +	// 68K VIA-based machines (see Develop Magazine no. 29)
        +	mTimebaseTicksPerMillisec = 783.360D;
        +#endif
        +}
        +
        +unsigned long CRandomizer::SysTimer (void)	// returns the lower 32
        +						// bit of the chip timer
        +{
        +#ifdef __powerc
        +	return GetPPCTimer (mIs601);
        +#else
        +	UnsignedWide usec;
        +	Microseconds (&usec);
        +	return usec.lo;
        +#endif
        +}
        +
        +#ifdef __powerc
        +// The timebase is available through mfspr on 601, mftb on later chips.
        +// Motorola recommends that an 601 implementation map mftb to mfspr
        +// through an exception, but I haven't tested to see if MacOS actually
        +// does this. We only sample the lower 32 bits of the timer (i.e. a
        +// few minutes of resolution)
        +
        +asm unsigned long GetPPCTimer (register bool is601)
        +{
        +	cmplwi	is601, 0	// Check if 601
        +	bne	_601		// if non-zero goto _601
        +	mftb  	r3		// Available on 603 and later.
        +	blr			// return with result in r3
        +_601:
        +	mfspr r3, spr5  	// Available on 601 only.
        +				// blr inserted automatically
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/MacOS/Randomizer.h b/vendor/openssl/openssl/MacOS/Randomizer.h
        new file mode 100644
        index 000000000..565537b15
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/Randomizer.h
        @@ -0,0 +1,43 @@
        +
        +//	Gathers unpredictable system data to be used for generating
        +//	random bits
        +
        +#include <MacTypes.h>
        +
        +class CRandomizer
        +{
        +public:
        +	CRandomizer (void);
        +	void PeriodicAction (void);
        +	
        +private:
        +
        +	// Private calls
        +
        +	void		AddTimeSinceMachineStartup (void);
        +	void		AddAbsoluteSystemStartupTime (void);
        +	void		AddAppRunningTime (void);
        +	void		AddStartupVolumeInfo (void);
        +	void		AddFiller (void);
        +
        +	void		AddCurrentMouse (void);
        +	void		AddNow (double millisecondUncertainty);
        +	void		AddBytes (void *data, long size, double entropy);
        +	
        +	void		GetTimeBaseResolution (void);
        +	unsigned long	SysTimer (void);
        +
        +	// System Info	
        +	bool		mSupportsLargeVolumes;
        +	bool		mIsPowerPC;
        +	bool		mIs601;
        +	
        +	// Time info
        +	double		mTimebaseTicksPerMillisec;
        +	unsigned long	mLastPeriodicTicks;
        +	
        +	// Mouse info
        +	long		mSamplePeriod;
        +	Point		mLastMouse;
        +	long		mMouseStill;
        +};
        diff --git a/vendor/openssl/openssl/MacOS/TODO b/vendor/openssl/openssl/MacOS/TODO
        new file mode 100644
        index 000000000..903eb133d
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/TODO
        @@ -0,0 +1,18 @@
        +-------------------------------------------------------------------
        +Verify server certificate
        +-------------------------------------------------------------------
        +Currently omitted from the project:
        +
        +	crypto/tmdiff.c
        +	crypto/bio/bss_conn.c
        +	crypto/bio/b_sock.c
        +	crypto/bio/bss_acpt.c
        +	crypto/bio/bss_log.h
        +
        +-------------------------------------------------------------------
        +Build libraries to link with...
        +-------------------------------------------------------------------
        +Port openssl application.
        +-------------------------------------------------------------------
        +BN optimizations (currently PPC version is compiled with BN_LLONG)
        +-------------------------------------------------------------------
        diff --git a/vendor/openssl/openssl/MacOS/_MWERKS_GUSI_prefix.h b/vendor/openssl/openssl/MacOS/_MWERKS_GUSI_prefix.h
        new file mode 100644
        index 000000000..fe6b5387d
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/_MWERKS_GUSI_prefix.h
        @@ -0,0 +1,9 @@
        +#include <MacHeaders.h>
        +#define B_ENDIAN
        +#ifdef __POWERPC__
        +#pragma longlong on
        +#endif
        +#if 1
        +#define MAC_OS_GUSI_SOURCE
        +#endif
        +#define MONOLITH
        diff --git a/vendor/openssl/openssl/MacOS/_MWERKS_prefix.h b/vendor/openssl/openssl/MacOS/_MWERKS_prefix.h
        new file mode 100644
        index 000000000..2189da753
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/_MWERKS_prefix.h
        @@ -0,0 +1,9 @@
        +#include <MacHeaders.h>
        +#define B_ENDIAN
        +#ifdef __POWERPC__
        +#pragma longlong on
        +#endif
        +#if 0
        +#define MAC_OS_GUSI_SOURCE
        +#endif
        +#define MONOLITH
        diff --git a/vendor/openssl/openssl/MacOS/buildinf.h b/vendor/openssl/openssl/MacOS/buildinf.h
        new file mode 100644
        index 000000000..90875b6e2
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/buildinf.h
        @@ -0,0 +1,5 @@
        +#ifndef MK1MF_BUILD
        +#  define CFLAGS	"-DB_ENDIAN"
        +#  define PLATFORM	"macos"
        +#  define DATE		"Sun Feb 27 19:44:16 MET 2000"
        +#endif
        diff --git a/vendor/openssl/openssl/MacOS/mklinks.as.hqx b/vendor/openssl/openssl/MacOS/mklinks.as.hqx
        new file mode 100644
        index 000000000..fe3e7d53d
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/mklinks.as.hqx
        @@ -0,0 +1,820 @@
        +(This file must be converted with BinHex 4.0)
        +
        +:#QeVE'PZDh-ZBA-!39"36'&`E(3J!!!!!!!!!*LiI6m!!!!!!3!!!*G#!!#@3J!
        +!!AChFQPd!!!!K3)"!3m(Fh9`F'pbG!!!!)B#!3%$"(0eFQ8!!!#(!J-%"!3("3C
        +cGfPdBfJ!!!#)!J%"#39cH@jMD!!!!)N#"J%$!`-&"3-'FhPcG'9Y!!!!LJ)&"3)
        +%!J8("!-#!`4dB@*X!!!!L`))!3-$!`-$!`-$"(4PE'`!!!#-!J)"#38$G'KP!!!
        +!M3))(J)@!Ki#!J))!K)#!`)B!Kd%G'KPE3!!!)i#!J%&#`4dD'9j!!!!M`)#!J)
        +#$3TdD(*[G@GSEh9d!!!!N!!#!3%&"(4TCQB!!!#4!J%"!`4dD@eP!!!!NJ)"!JS
        +#!h4T!!!!'N!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!H!!!!!!!#!!!!!!
        +!!!!!!!!!!!!!rrrrr`!!!$3!!!!N!!!!!#"[!!5JAb"[!!5K++!M6R9$9'mJFR9
        +Z)(4SDA-JFf0bDA"d)'&`F'aTBf&dD@pZ,#"jEh8JEA9cG#"QDA*cG#"TER0dB@a
        +X)%&`F'aP8f0bDA"d,J!!!)C8D'Pc)(0MFQP`G#"MFQ9KG'9c)#iZ,fPZBfaeC'8
        +[Eh"PER0cE#"KEQ3JCQPXE(-JDA3JGfPdD#"ZC@0PFh0KFRNJB@aTBA0PFbi0$8P
        +d)'eTCfKd)(4KDf8JB5"hD'PXC5"dEb"MEfe`E'9dC5"cEb"`E'9KFf8JBQ8JF'&
        +dD@9ZG$SY+3!!!#S!!J!!!!!!$3!+!"!!!!!-!!!!!!!!!!!!63!0!!S!%!%!!!`
        +!!!!!!!!!!!!B!!!!+!!!!!!!!!!)!!!!)!#N2c`!!DR`!!!!l!!!!!&19[ri,`0
        +f!#m$-$bKVDG'*KmY52ri,`-`2+LITdBQ(b!ZrrLa`'FJ,`-J2'0`ER4"l[rm)NL
        +KV5+)*Kp+3'B)5Ulrr'F#GJ%3!bBZrr41ANje6PB!!#m-@Bm[2%j29%Nr2!#!U"m
        +SAb!-CJK`!cm!UFKJ+#m-UC)J9#!)d+J!'#&!!"JJ9#!)d+J!(#&!!"a9Mbm8)&q
        +JAMk!9%mSE[rm6Pj1G8j@!!![$%kkre4+!'FU@Bm[2'&`E(3[2(0MF(4`)DJU+&m
        +J$'F5@Bm[$#mm!!!!!A!!U#UTp&K26VVrG#KZrra1ANje!!!!('&`E(3!!!!"4P*
        +&4J!!!!!!J%P$6L-!!!!!!*B!!!!"!!!!!!G"8&"-!!!!!!!"!!!"!!!!!S!!!!4
        +!!!"i)!!!K"!!!3))!!)#"!!%"!)!#!J"!"!8!)!J)J"!3%%!)2#!J"#*!%!)KJ!
        +J")3!)!*!!"!")!!3!K!!%!3)!"!)"!!J%!)!3#!"!)"!!S%!J!5#!3!)4!)!#%J
        +%!!KB#!!%C"!!!m)J!!!"3!!!!)!!!!%!!!!$J!!!"m!!!(rJ!!$rm!!"rrJ!!rr
        +m!!IrrJ!2rrm!(rrrJ$rrrm"rrrrJrrrrm2rrrrMrrrrmrrrrrRrrrrmrrrrq(rr
        +rr!rrrrJ(rrr`!rrri!(rrm!$rrq!"rrr!!rrrJ!2rr`!$rri!!IRm!!$`q!!!!(
        +!!!!!J!!!!!)!!!!!!!!!!!m!!!!!!!!!!!!!!!!!!!$`m!!!!!!!!!!!!!!!!!!
        +2!!m!!!!!!!!!!!!!!!rrm!!!m!!!!!!!!!!!!!$`c0m!!!m!!!!!!!!!!!!2!!c
        +-m!!!m!!!!!!!!!!!m!$-cI!!!!m!!!!!!!!!$`!-c0m!!!!!m!!!!!!!!2!!c-h
        +`!!!!!!m!!!!!!!m!$-cIh`!!!!!!m!!!!!$`!-c0rGh`!!!!!!m!!!!2!!c-hph
        +-h`!!!!!!m!!!rrr-cIhF`-h`!!!!!!m!!2lFr0rGc!`-h`!!!!!!m!$pc-rph-$
        +!`-h`!!!!!!m!r-`2cF`-$!!-r3!!!!!!m!m!`-c!`-!!$0m!!!!!$-m!m!`-$!`
        +!!-cI!!!!!-c`!!m!`-$!!!`-h`!!!!c2!!!!m!`-!!$!c0m!!!$-m!!!!!m!`!!
        +-$-hm!!!-c`!!!!!!m!!!`-cIc!!!c2!!!!!!!!m!$!c0r-`!$-m!!!!!!!$pm-$
        +-hmc!!-c`!!!!!!!2hI`-cIc-!!c2!!!!!!!!rGc2c0r-`!$-m!!!!!!!!2h-cmh
        +mc!!-c`!!!!!!!!$mc!rIr-!!c2!!!!!!!!!!$m$2m!r-$-m!!!!!!!!!!!$rr`!
        +!r-c`!!!!!!!!!!!!!!!!!!r2!!!!!!!!!!!!!!!!!!!!m!!!!!!!!!!!!!"!!B!
        +13"%J)4"##18%Q)+3!%&!)5!L%%3BL#83*L!G3!#!!B!2`"rJ2r"rq2rmrrlrrhr
        +r2riIr"ri2r!ri"h!!)!!!!#!!!!!$r!!!!!!!2r`$`!!!!!2$!m!m!!!!2$!c`!
        +2!!!2$!c`!!$`!2r`cpm!!!m!rGrpc2!!!2$p$p`-c`!!$`m!`-$0m!$2!2!-$-h
        +`$2!!$`$-hm$2!!!2m-hm$2!!!2h2hm$2!!!!r-rm$2!!!!!2r`r2!!!!!!!!!2!
        +!!!!!!!#D8f0bDA"d)%&`F'aTBf&dD@pZ$3e8D'Pc)(0MFQP`G#"MFQ9KG'9c)#i
        +Z,fPZBfaeC'8[Eh"PER0cE#"KEQ3JCQPXE(-JDA3JGfPdD#"ZC@0PFh0KFRNJB@a
        +TBA0PFbi0$8Pd)'eTCfKd)(4KDf8JB5"hD'PXC5"dEb"MEfe`E'9dC5"cEb"`E'9
        +KFf8JBQ8JF'&dD@9ZG$SY+3!!!")!!J!!!!!!!!!!!!%!"J!'%iN!!!!+@1!!!b!
        +!!!-J!!!!!"3!+`!(!Cm#@!!V!!F"f!*B!!!!!3!!M`C'BA0N98&6)$%Z-6!a,M%
        +`$J!!!!32rrm!!3!#!!-"rrm!!!d!!3!"D`!!!!!!!!!%!J!%!!)!"3!'$3!&!!*
        +X!!)!!!U`!!IrrJd!"`!#6`!!!!!+X!!)!!N0!!J!!@X!!!!%#Um!#J)!#J!#!!X
        +!$!d!#`!#E!!#!!3!"2rprr`"rrd!!!(rr!!!!J!-!!)!$3!1$3!0!!*X!!%!"!!
        +%rrX!$`(rq`!!$!!2!&N!8b"(CA3JF'&dD#"dEb"dD'Pc)%&`F'aP8f0bDA"d)'&
        +`F'aPG$XJGA0P)'Pd)(4[)'C[FQdJG'KP)("KG'JJG'mJG'KP)'PZBfaeC'8JCQp
        +XC'9b!!)!!!)!$J!#!"!!%3d!%!!#E!!"!!3!"2rk!")"rrS!!!`!%J!Q!#!JB@j
        +N)(4SC5"[G'KPFL"bC@aPGQ&ZG#"QEfaNCA*c,J!#!!!#!"%!!J!6!"30!"-!!R-
        +!!!!%!"%!&3!@$3!9!!*M!!!!"!!1!"F!'!d!&`!#E!!&!!3!$!!CrrN0!"N!!Qi
        +!!!!%!!`!'J!E$3!D!!)d!!!!"3!-rrJ!(!Vrq!!%#Q0[BQS0!"`!!Q`!"3!'!!X
        +!(Irh$3!G!!0*!!)!"J!,rrB!([re#[rf!"JZC@&bFfCQC(*KE'Pc!!!!!!!!)!"
        +KCQ4b$3!H!!"Q!!!!"J!(![re!!!"rrF!!!d!'`!"E3!!!!3!"3!I$`!I!6J)ER9
        +XE!!!!!!!!Gq!rrm!!!!A"NCTEQ4PFJ!!(`*[Me!!ASfm!Qq,i!"HA[!!I&M!!!!
        +!!!!!'mi!!JN#!Qq-1!!!Kb%#Ei`J!!!!!%C14&*038e"3e-!!"%!B@aTF`!!!!!
        +!fJ!#!!!-6@&MD@jdEh0S)%K%!!!!!!!!!!!!!!!!!!!!XSA5h%*%!!!!!!!A"NC
        +TEQ4PFJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        +!!!!!!!!!!!!!!!!!!!!!3rLc#@a!4Nj%8Ne"3e2rrrrr!!!!!!!!!!!!!!!!!!!
        +!!!!!!!e6HA0dC@dJ4QpXC'9b!!!"!!3!!!!A!!)!)8eKBfPZG'pcD#")4$T6HA0
        +dC@dJ4QpXC'9b1NCTEQ4PFJ$rr`!!!Irj!!!0!"J!!@d!!!!-!!hrp!Vrp!!%#Q0
        +dH(30!"B!!@m!!!!!!!$rm`[rm`!5-!!(G'KPF'&dD!!(G'KP8'&dD!)!&!!#!#!
        +!)3d!)!!#E!!#!")!%[rbrr%"rr)!!!(rm3!!!J!K!!)!)J!M$3!L!!*b!!!!%J!
        +A!#3!*3d!*!!#EJ!$!")!&3!Q!#F0!#B!!6%!!!!6!"Arm!Vrm!!%#R4iC'`0!#F
        +!!6%!!!!5!"2rl`Vrl`!%#Q&cBh)0!#8!!@m!!!!!!!$rlJ[rlJ!F-!!-G'KPEfa
        +NC'9XD@ec!!adD'92E'4%C@aTEA-#!#-!!J!S!#N0!#J!!R)!!!!B!"d!+J!V$3!
        +U!!&Y!!!!'!!C!#`-!#`!"`!"1J!#!!!0!#X!!Qi!!`!!!!!!,3!Z$3!Y!!%a!!!
        +!'J!Frqd+rqd!"!TdH'4X$3!Z!!%a!!!!'3!Drq`+rq`!"!TKFf0b!J!T!!)!,`!
        +`$3![!!*X!!)!(J!Hrq[rkJ(rk`!!!IrU!!!#!$!!!J!a!$)0!$%!!R)!!!!H!#X
        +!-`!d$3!c!!*X!!8!(J!T!$Ark3d!03!#EJ!!!"i!+3!f!$F0!$B!!cF"!!!I!#R
        +rk!!i!$N+rqJ!"!TMDA4Y$3!i!!&Y!!!!)`!PrqF$rqF!!3d!13!"E3!!!#B!+2r
        +Q!rrQrrd0!$F!!@m!!!!H!"rrj3[rj3!5-!!(G'KPF'&dD!!(G'KP8'&dD!(rk3!
        +!$3!d!!&[!!!!!!!!rq3,rq3!)$!!$R4SCA"bEfTPBh4`BA4S!!jdD'93FQpUC@0
        +d8'&dD!)!-J!#!$S!1`d!1J!#FJ!!!#`!1`!m!$d0!$`!!Q-!!!!X!$N!2J!r$3!
        +q!!*X!!8!,!!h!%$ri`d!3!!#EJ!!!#`!0`""!%)0!%%!!cF"!!!Y!$IriJ"$!%3
        ++rq)!"!TMDA4Y$3"$!!&Y!!!!-3!crq%$rq%!!3d!4!!"E3!!!$3!0[rJ!rrJrri
        +0!%)!!@m!!!!X!#hrh`[rh`!5-!!(G'KPF'&dD!!(G'KP8'&dD!(ri`!!$3!r!!&
        +Y!!!!0`!irpi+rpi!"!T849K8$3!p!!&[!!!!!!!!rpd,rpd!&M!!#A4SC@ePF'&
        +dD!!*G'KP6@93BA4S!J!l!!)!43"'$3"&!!*X!!)!2!!mrpcrf`(rh!!!!IrE!!!
        +#!%B!!J"(!%J0!%F!!R)!!!!m!%8!53"+$3"*!!*M!!!!2!""!%X!6!d!5`!#BJ!
        +!!$`!2`"0!%i0!%d!!@m!!!!m!$hrfJ[rfJ!J-!!1G'KPF(*[DQ9MG("KG'J!$R4
        +SC9"bEfTPBh43BA4S$3"1!!&Y!!!!23!q!%m-!%m!$3!(D@jME(9NC3!#!!!0!%`
        +!!@d!!!!r!%$rf3Vrf3!%#P4&@&30!%S!!@m!!!!!!!$rf![rf!!Q-!!4D@jME(9
        +NC@C[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S!J")!!)!8!"4$3"3!!*b!!!
        +!4J"9!&)!8`d!8J!#B`!!!%B!83"8!&80!&3!!Q)!!!"'!%m!9J"A$3"@!!*L!!!
        +!4J",!&J!@3d!@!!"E`!!!%B!4rrA#rrA!#!`!!jdD'9`FQpUC@0dF'&dD!!1G'K
        +P8(*[DQ9MG&"KG'J0!&N!!@d!!!"(!%S!@J`!@J!0!!GTEQ0XG@4P!!)!!!d!9`!
        +"E3!!!%X!6J"E$!"E!!d!"fp`C@jcFf`!!J!!$3"9!!&Y!!!!6`"3rpB+rpB!"!T
        +849K8$3"6!!&[!!!!!!!!rp8,rp8!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&
        +dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S!J"4!!)!A!"G$3"F!!*b!!!!9J"
        +K!&i!A`d!AJ!#B`!!!&B!A3"J!'%0!'!!!Q)!!!"@!&X!BJ"M$3"L!!&[!!!!9J"
        +Arp3,rp3!)$!!$R4SCA"bEfTPBh4`BA4S!!jdD'93FQpUC@0d8'&dD!d!B`!"E3!
        +!!&F!@J"N$!"N!!`!"Q0bHA"dE`!#!!!0!'%!!@d!!!"E!&crd`Vrd`!%#P4&@&3
        +0!&m!!@m!!!!!!!$rdJ[rdJ!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4Qp
        +XC'9b8'&dD!)!A3!#!'8!CJd!C3!#FJ!!!')!E3"R!'J0!'F!!Q-!!!"L!'N!D3"
        +U$3"T!!*L!!!!BJ"R!'X!E!d!D`!"E`!!!')!Brr4#rr4!#!`!!jdD'9`FQpUC@0
        +dF'&dD!!1G'KP8(*[DQ9MG&"KG'J0!'`!!@d!!!"M!'B!E3`!E3!*!!0cFf`!!J!
        +!$3"U!!&Y!!!!C`"Srp!+rp!!"!T849K8$3"S!!&[!!!!!!!!rmm,rmm!(M!!$A0
        +cE'C[E'4PFR"KG'J!$A0cE%C[E'4PFP"KG'J#!'B!!J"Z!'m0!'i!!R)!!!"Z!(8
        +!F!"a$3"`!!*M!!!!EJ"a!()!F`d!FJ!"E`!!!'i!Err1#rr1!#!`!!jdD'9`FQp
        +UC@0dF'&dD!!1G'KP8(*[DQ9MG&"KG'J0!(-!!@d!!!"[!($rc3Vrc3!%#P4&@&3
        +0!(%!!@m!!!!!!!$rc![rc!!Q-!!4Eh"PER0cE'C[E'4PFR"KG'J!%@p`C@jcFfa
        +'EfaNCA*3BA4S!J"[!!)!G!"e$3"d!!*X!!)!GJ"frm[rbJ(rb`!!!Ir+!!!#!(8
        +!!J"f!(F0!(B!!R)!!!"f!(X!H!"j$3"i!!&[!!!!GJ"hrmN,rmN!($!!$(4SC@p
        +XC'4PE'PYF`!-G'KP6faN4'9XD@ec$3"j!!*Z!!-!!!!!!(S!H`d!HJ!"-3!!!(J
        +!H[r)#[r)!!3+G(KNE!d!H`!"-3!!!(F!H2r(#[r(!!3+BA0MFJ)!G`!#!(`!I3d
        +!I!!#E!!#!(`!I2r'rm8"rmB!!!(ra3!!!J"p!!)!IJ"r$3"q!!*X!!%!I!"mrm3
        +!J!(ra!!!$!#!!%!!1L"NC@aPG'8JEfaN)'PZBfaeC'8kEh"PER0cE#"QEfaNCA)
        +JB@jN)(*PBh*PBA4P)'Pd)'0XC@&ZE(N!!J!!!J"r!!)!J3##$3#"!!*X!!)!I!"
        +mrm2r`J(r``!!!Ir#!!!#!))!!J#$!)30!)-!!e%!!!"m!+8!K3#'!)F0!)8!!@X
        +!!!"r!*`!L!)!L!!#!)N!LJd!L3!$53!#!(m!N[r"!)[r`!Vr`3!B,QeTFf0cE'0
        +d+LSU+J!!!!!!!*!!!#SU+LS0!)X!!Qi!!!"r!)i!M!#0$3#-!!)d!!!!K`#1rlm
        +!MJVr[`!%#Q0QEf`0!)i!!@d!!!#+!)d!M``!M`!0!!G[F'9ZFh0X!!)!!!d!M3!
        +#0!!!!(m!Krqq!*!!#[qq!!3+BfC[E!d!N!!!!@m!!!#$!)Er[3[r[3!Q-!!4D@j
        +ME(9NC@C[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S![r!!!!#!)S!!J#4rl`
        +0!*%!!dN!!J#6!*crZ`#5rlS+rlX!'#jMEh*PC'9XEbSU+LS!!!!!!!#3!!!U+LS
        +U$3#5!!%a!!!!N`#BrlN+rlN!"!TcC@aP![qk!!!#rl`!!!d!KJ!$8J!!!!!!!2q
        +irlIrYJVrZ!!B,Q&cBh*PFR)J+LSU+J!!!!!!!*!!!#SU+LS"rlF!!!,rYJ!!$3#
        +(!!*X!!%!T!#Nrl8!N`(rY3!!$!#6!"-!$5"TCfj[FQ8JCA*bEh)!!J!!!J#%!!)
        +!P!#9$3#8!!*X!!)!TJ#Qrl6rX`(rY!!!!Iqc!!!#!*8!!J#@!*F0!*B!!dN!!J#
        +Q!,lrX[qa!*J+rl)!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Iqa!!!'!*J
        +!!rq`!*N!QJVrX!!%#QY[Bf`0!*N!!@d!!!#U!+hrV`VrV`!%#Q0QEf`'!*S!!rq
        +Z!*[rV3VrVJ!%#QPZFfJ0!*X!!M3!!!#`!,MrV!#F#[qX!!3+BfC[E!d!R!!"E`!
        +!!,3!YrqV#rqV!#B`!"&TEQ0XG@4PCQpXC'9bF'&dD!!4D@jME(9NC8C[E'4PFP"
        +KG'J'rkd!!!)!P`!#!*d!RJd!R3!#FJ!!!,m!aJ#I!+!0!*m!!Q`"!!#r!-)!SIq
        +U$3#K!!%a!!!![`$#rkN+rkN!"!TbFfad!IqU!!!0!+!!!@m!!!!!!!$rU![rU!!
        +Z-!!9G'KPEQ9hCQpXC'9bFQ9QCA*PEQ0P!"9dD'91CAG'EfaNCA*5C@CPFQ9ZBf8
        +#!*i!!J#L!+-0!+)!!dN!!J$(!-lrT`#NrkB+rkF!'#jYDA0MFfaMG#SU+LS!!!!
        +!!!#3!!!U+LSU$3#N!!&[!!!!a`$+rk8,rk8!,M!!&A4SC@jPGfC[E'4PFR*PCQ9
        +bC@jMC3!9G'KP6Q9h4QpXC'9b8Q9QCA*PEQ0P![qQ!!!#!+-!!J#P!+B0!+8!!R)
        +!!!$2!0`!T`#S$3#R!!&Y!!!!c`$5!+N-!+N!$3!(Eh"PER0cE!!#!!!0!+J!!Qi
        +!!!!!!!!!UJ#V$3#U!!%a!!!!e`$Erk3+rk3!"!T`EQ&Y$3#V!!%a!!!!dJ$Ark-
        ++rk-!"!TcC@aP!J#Q!!)!V!#Y$3#X!!*X!!)!h3$Grk,rS3(rSJ!!!IqK!!!#!+d
        +!!J#Z!+m0!+i!!Q`!!3$G!0hrS!#`!IqJ!!!-!,!!(`!C)&0dBA*d)'eKDfPZCb"
        +dD'8JB@aTBA0PF`!#!!!#!+m!!J#a!,)0!,%!!dN!!J$G!3ArRrqH!,-+rjm!'#j
        +MEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!IqH!!!'!,-!!rqG!,3!Y3VrR3!%#QY
        +[Bf`0!,3!!@d!!!$K!16rR!VrR!!%#Q&XD@%'!,8!!rqE!,B!Y`VrQ`!%#QPZFfJ
        +0!,B!!M3!!!$R!1rrQJ#i#[qD!!3+BfC[E!d!Z!!"E`!!!1X!l[qC#rqC!$3`!"K
        +[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&
        +dD!B!Y`!$rjJ!ZIqA#[qB!!3+G'mJ)!d!Z3!#EJ!!!2)!r`#k!,X0!,S!!M3!!!$
        +i!2rrPJ#m#[q@!!3+CQPXC3d![!!"E3!!!2X!rJ#p$!#p!"-!$@p`C@jcFfaMEfj
        +Q,QJ!!J!!$3#l!!)d!!!!mJ$irj8![JVrP3!%#Q0QEf`0!,i!!@m!!!$f!2IrP![
        +rP!!@-!!*G'KPE@9`BA4S!!PdD'90C9"KG'J'rjF!!!)!XJ!#!,m!`!d![`!#E!!
        +#!3B""[q6rj)"rj-!!!(rNJ!!!J$!!!)!`3$#$3$"!!*b!!!""J%4!--!a!d!``!
        +#BJ!!!3B"$3$&!-B0!-8!!@m!!!%'!3RrN3[rN3!N-!!3Bh*jF(4[CQpXC'9bF'&
        +dD!!3Bh*jF(4[4QpXC'9b8'&dD!d!aJ!"E3!!!3N"$!$($!$(!!X!"6TKFfia!!)
        +!!!d!a!!"E`!!!!!!!2q3!![rN!!!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)!`J!
        +#!-J!b3d!b!!$53!#!4)"22q2rii!bJVrM`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!
        +!!'jeE'`"rii!!!B!bJ!$rid!b`$-#[q0!!3+DfpME!d!b`!"E3!!!4B"'Iq-#[q
        +-!!3+B@aTB3B!c!!$riX!c3$1#[q,!!3+D@jcD!d!c3!#0!!!!4`"*2q+!-m+riS
        +!"!TMCQpX$3$2!!&[!!!")!%MriN,riN!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9
        +bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J$1!!2rL!$3riF+riJ!"!T
        +dEb!J$3$3!!*Z!!!"*`%f!0%!dJd!d3!#0!!!!5m"0[q'!0-+riB!"!TQD@aP$3$
        +6!!&Y!!!"-J%e!03-!03!$!!'BA0Z-5jS!!)!!!d!dJ!#0!!!!5F",rq&!08+ri8
        +!"!TMCQpX$3$9!!&[!!!"+`%Zri3,ri3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!E
        +rK`!!!J$*!!)!eJ$A$3$@!!0*!!)"23&Rri2rJJ$B#[q$!"JZBfpbC@0bC@`U+LS
        +U!!!!!!!!N!!!ER9XE!(rJJ!!"J$B!!2rJ3$C!0S+ri%!"!TVEf0X$3$C!!&Y!!!
        +"33&%ri!+ri!!"!TKE'PK"J$D!!2rI`$E!0`+rhm!"!TTER0S$3$E!!)d!!!"4`&
        +2rhi!h3VrIJ!%#Q0QEf`0!0d!!@m!!!&,!8lrI3[rI3!d-!!BEh"PER0cE'PZBfa
        +eC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!0`!!rpm!0l
        +rH`VrI!!%#R4[)#!0!0i!!Qi!!!&5!@%!h`$J$3$I!!)d!!!"@J&KrhS!i3VrHJ!
        +%#QCTE'80!1%!!@d!!!&G!@!!iJ`!iJ!3!!TKFfiaAfeKBbjS!!)!!!d!i!!#0!!
        +!!9)"@[pj!1-+rhN!"!TMCQpX$3$M!!&[!!!"9J&CrhJ,rhJ!&$!!#(4PEA"`BA4
        +S!!KdC@e`8'&dD!ErH`!!!J$A!!)!j!$P$3$N!!*X!!)"D!&SrhIrGJ(rG`!!!Ip
        +f!!!#!18!!J$Q!1F0!1B!!R)!!!&S!A-!k!$T$3$S!!*L!!!"D!&[!1S!k`d!kJ!
        +"E`!!!@J"Drpe#rpe!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*
        +3BA4S$3$V!!&Y!!!"D`&Z!1`-!1`!#J!%1Q*TE`!#!!!0!1N!!@m!!!!!!!$rG![
        +rG!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J$R!!)!l3$Z$3$Y!!0*!!)"G!'Hrh2
        +rFJ$[#[pc!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(rFJ!!"J$[!!2rF3$
        +`!2%+rh%!"!TVEf0X$3$`!!&Y!!!"H!&lrh!+rh!!"!TKE'PK"J$a!!2rE`$b!2-
        ++rfm!"!TTER0S$3$b!!)d!!!"IJ''rfi!p!VrEJ!%#Q0QEf`0!23!!@m!!!'#!BA
        +rE3[rE3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
        +NC8C[E'4PFP"KG'J'!2-!!rpX!2ArD`VrE!!%#R4[)#!0!28!!Qi!!!'*!CJ!pJ$
        +h$3$f!!)d!!!"N3'BrfS!q!VrDJ!%#QCTE'80!2J!!@d!!!'8!CF!q3`!q3!,!!9
        +LD@mZD!!#!!!0!2F!!M3!!!'*!C(rD3$k#[pT!!3+BfC[E!d!qJ!"E`!!!Bd"N!$
        +rD![rD!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[pV!!!#!1i!!J$l!2`0!2X!!Q`
        +!!J'I!CrrCrpQ!IpR!!!"rfB!!!)!r!!#!2d!rJd!r3!#FJ!!!Cm"UJ$r!3!0!2m
        +!!Q)!!!'I!DB"!3%#$3%"!!&[!!!"R`'Lrf8,rf8!*$!!%'0bHA"dEfC[E'4PFR"
        +KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!3)!!@d!!!'L!D8"!``"!`!*!!-kBQB!!J!
        +!$3%!!!&[!!!!!!!!rf3,rf3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)!rJ!#!33
        +""3d""!!$53!#!DX"eIpMrf)""JVrB`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'j
        +eE'`"rf)!!!B""J!$rf%""`%)#[pK!!3+DfpME!d""`!"E3!!!Dm"X[pJ#[pJ!!3
        ++B@aTB3B"#!!$rem"#3%+#[pI!!3+D@jcD!d"#3!#0!!!!E8"[IpH!3X+rei!"!T
        +MCQpX$3%,!!&[!!!"Z3'mred,red!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&
        +dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J%+!!2rA!%-reX+re`!"!TdEb!
        +J$3%-!!*Z!!!"`!(2!3d"$Jd"$3!#0!!!!FJ"crpD!3m+reS!"!TQD@aP$3%2!!&
        +Y!!!"b`(1!4!-!4!!%!!+BQa[GfCTFfJZD!!#!!!0!3i!!M3!!!(!!FMr@3%4#[p
        +C!!3+BfC[E!d"%3!"E`!!!F3"arpB#rpB!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J
        +'reX!!!)""3!#!4)"%`d"%J!#E!!#!GB"e[pAreB"reF!!!(r9J!!!J%6!!)"&!%
        +9$3%8!!*b!!!"eJ(K!4B"&`d"&J!#BJ!!!GB"h3%B!4N0!4J!!@m!!!(@!GRr93[
        +r93!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"'3!"E3!
        +!!GN"h!%D$!%D!!N!!cTLEJ!#!!!0!4F!!@m!!!!!!!$r9![r9!!8-!!)G'9YF("
        +KG'J!#(4PEA"3BA4S!J%9!!)"'`%F$3%E!!0*!!)"iJ)-re2r8J%G#[p6!"JZBfp
        +bC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(r8J!!"J%G!!2r83%H!4m+re%!"!TVEf0
        +X$3%H!!&Y!!!"jJ(Tre!+re!!"!TKE'PK"J%I!!2r6`%J!5%+rdm!"!TTER0S$3%
        +J!!)d!!!"l!(drdi")JVr6J!%#Q0QEf`0!5)!!@m!!!(`!I2r63[r63!d-!!BEh"
        +PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J
        +'!5%!!rp-!52r5`Vr6!!%#R4[)#!0!5-!!Qi!!!(h!JB"*!%P$3%N!!)d!!!"r`)
        +'rdS"*JVr5J!%#QCTE'80!5B!!@d!!!)#!J8"*``"*`!+!!4LELjS!!)!!!d"*3!
        +#0!!!!IF"rrp*!5J+rdN!"!TMCQpX$3%S!!&[!!!"q`(qrdJ,rdJ!&$!!#(4PEA"
        +`BA4S!!KdC@e`8'&dD!Er5`!!!J%F!!)"+3%U$3%T!!*X!!)#$3)0rdIr4J(r4`!
        +!!Ip'!!!#!5S!!J%V!5`0!5X!!R)!!!)0!KJ",3%Z$3%Y!!*L!!!#$3)8!5m"-!d
        +",`!"E`!!!Jd#%2p&#rp&!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'Efa
        +NCA*3BA4S$3%`!!&Y!!!#%!)6!6%-!6%!$3!(1Q*eCQCPFJ!#!!!0!5i!!@m!!!!
        +!!!$r4![r4!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J%X!!)"-J%c$3%b!!0*!!)
        +#'3*$rd2r3J%d#[p$!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(r3J!!"J%
        +d!!2r33%e!6B+rd%!"!TVEf0X$3%e!!&Y!!!#(3)Jrd!+rd!!"!TKE'PK"J%f!!2
        +r2`%h!6J+rcm!"!TTER0S$3%h!!)d!!!#)`)Vrci"13Vr2J!%#Q0QEf`0!6N!!@m
        +!!!)R!LVr23[r23!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0
        +-5@jME(9NC8C[E'4PFP"KG'J'!6J!!rmm!6Vr1`Vr2!!%#R4[)#!0!6S!!Qi!!!)
        +Z!Md"1`%m$3%l!!)d!!!#0J)prcS"23Vr1J!%#QCTE'80!6d!!@d!!!)j!M`"2J`
        +"2J!1!!KLG@CQCA)ZD!!#!!!0!6`!!M3!!!)Z!MEr13%r#[mj!!3+BfC[E!d"2`!
        +"E`!!!M)#0Imi#rmi!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rcX!!!)"-`!#!8!
        +"33d"3!!#E!!#!N3#42mhrcB"rcF!!!(r0J!!!J&"!!)"3J&$$3&#!!*b!!!#4!*
        +2!83"43d"4!!#BJ!!!N3#5`&'!8F0!8B!!@m!!!*%!NIr03[r03!N-!!3Bh*jF(4
        +[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"4`!"E3!!!NF#5J&)$!&)!!X
        +!"6TMBA0d!!)!!!d"43!"E`!!!!!!!2md#rmd!"3`!!KdC@e`F'&dD!!)G'9YF&"
        +KG'J#!8-!!J&*!8S0!8N!!dN!!J*3!RVr-rmb!8X+rc-!'#jMEh*PBh*PE#SU+LS
        +!!!!!!!#3!!"ZG@aX!Imb!!!'!8X!!rma!8`"63Vr-3!%#QY[Bf`0!8`!!@d!!!*
        +8!PIr-!Vr-!!%#Q&XD@%'!8d!!rm[!8i"6`Vr,`!%#QPZFfJ0!8i!!M3!!!*D!Q,
        +r,J&3#[mZ!!3+BfC[E!d"8!!"E`!!!Pi#BImY#rmY!$3`!"K[F'9ZFh0XD@jME(9
        +NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B"6`!$rb`"8Im
        +V#[mX!!3+G'mJ)!d"83!#EJ!!!Q8#G!&5!9-0!9)!!M3!!!*Y!R6r+J&8#[mU!!3
        ++CQPXC3d"9!!"E3!!!R!#F`&9$!&9!!`!"Q0KFh3ZD!!#!!!0!9-!!M3!!!*P!Qh
        +r+3&@#[mT!!3+BfC[E!d"9J!"E`!!!QN#E2mS#rmS!"3`!!KdC@e`F'&dD!!)G'9
        +YF&"KG'J'rbX!!!)"5J!#!9F"@!d"9`!#E!!#!RX#HrmRrbB"rbF!!!(r*J!!!J&
        +B!!)"@3&D$3&C!!*b!!!#H`+'!9X"A!d"@`!#BJ!!!RX#JJ&G!9i0!9d!!@m!!!*
        +l!Rlr*3[r*3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d
        +"AJ!"E3!!!Ri#J3&I$!&I!!X!"6TMEfe`!!)!!!d"A!!"E`!!!!!!!2mN#rmN!"3
        +`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!9S!!J&J!@%0!@!!!dN!!J+(!V(r)rmL!@)
        ++rb-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!ImL!!!'!@)!!rmK!@-"C!V
        +r)3!%#QY[Bf`0!@-!!@d!!!+,!Slr)!Vr)!!%#Q&XD@%'!@3!!rmI!@8"CJVr(`!
        +%#QPZFfJ0!@8!!M3!!!+4!TRr(J&R#[mH!!3+BfC[E!d"C`!"E`!!!T8#Q2mG#rm
        +G!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4Qp
        +XC'9b8'&dD!B"CJ!$ra`"D2mE#[mF!!3+G'mJ)!d"D!!#EJ!!!T`#U`&T!@S0!@N
        +!!M3!!!+N!U[r'J&V#[mD!!3+CQPXC3d"D`!"E3!!!UF#UJ&X$!&X!!`!"Q0[EA!
        +ZD!!#!!!0!@S!!M3!!!+F!U6r'3&Y#[mC!!3+BfC[E!d"E3!"E`!!!U!#SrmB#rm
        +B!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'raX!!!)"B3!#!@i"E`d"EJ!#E!!#!V)
        +#X[mAraB"raF!!!(r&J!!!J&[!!)"F!&a$3&`!!*b!!!#XJ+p!A)"F`d"FJ!#BJ!
        +!!V)#Z3&d!A80!A3!!@m!!!+b!VAr&3[r&3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!
        +3Bh*jF(4[4QpXC'9b8'&dD!d"G3!"E3!!!V8#Z!&f$!&f!!X!"6TMEfjQ!!)!!!d
        +"F`!"E`!!!!!!!2m8#rm8!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!A%!!J&h!AJ
        +0!AF!!dN!!J+q!ZMr%rm5!AN+ra-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@a
        +X!Im5!!!'!AN!!rm4!AS"H`Vr%3!%#QY[Bf`0!AS!!@d!!!,#!XAr%!Vr%!!%#Q&
        +XD@%'!AX!!rm2!A`"I3Vr$`!%#QPZFfJ0!A`!!M3!!!,)!Y$r$J&q#[m1!!3+BfC
        +[E!d"IJ!"E`!!!X`#crm0#rm0!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J
        +!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B"I3!$r``"Irm,#[m-!!3+G'mJ)!d
        +"I`!#EJ!!!Y-#iJ'!!B%0!B!!!M3!!!,E!Z,r#J'##[m+!!3+CQPXC3d"JJ!"E3!
        +!!Yi#i3'$$!'$!!`!"Q0[EQBZD!!#!!!0!B%!!M3!!!,6!Y[r#3'%#[m*!!3+BfC
        +[E!d"K!!"E`!!!YF#f[m)#rm)!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'r`X!!!)
        +"H!!#!B8"KJd"K3!#E!!#!ZN#kIm(r`B"r`F!!!(r"J!!!J''!!)"K`')$3'(!!*
        +b!!!#k3,d!BN"LJd"L3!#BJ!!!ZN#m!',!B`0!BX!!@m!!!,T!Zcr"3[r"3!N-!!
        +3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"M!!"E3!!!Z`#l`'
        +0$!'0!!S!"$TNCA-!!J!!$3'+!!&[!!!!!!!!r`3,r`3!&$!!#(4PEA"`BA4S!!K
        +dC@e`8'&dD!)"L!!#!Bi"M`d"MJ!$53!#![8$(rm$r`)"N!!+r`-!'#jMEh*PBh*
        +PE#SU+LS!!!!!!!#3!!"ZG@aX!Im#!!!'!C!!!!2r!3'4!C)+r`%!"!TVEf0X$3'
        +4!!&Y!!!#q3,mr`!+r`!!"!TKE'PK"J'5!!2qr`'6!C3+r[m!"!TTER0S$3'6!!)
        +d!!!#r`-(r[i"P3VqrJ!%#Q0QEf`0!C8!!@m!!!-$!`Eqr3[qr3!d-!!BEh"PER0
        +cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!C3
        +!!rlm!CEqq`Vqr!!%#R4[)#!0!CB!!Qi!!!-+!aN"P`'B$3'A!!)d!!!$%J-Cr[S
        +"Q3VqqJ!%#QCTE'80!CN!!@d!!!-9!aJ"QJ`"QJ!,!!9NCA-ZD!!#!!!0!CJ!!M3
        +!!!-+!a,qq3'E#[lj!!3+BfC[E!d"Q`!"E`!!!`i$%Ili#rli!"3`!!KdC@e`F'&
        +dD!!)G'9YF&"KG'J'r[X!!!)"M`!#!C`"R3d"R!!#E!!#!b!$)2lhr[B"r[F!!!(
        +qpJ!!!J'G!!)"RJ'I$3'H!!*b!!!$)!-V!D!"S3d"S!!#BJ!!!b!$*`'L!D-0!D)
        +!!@m!!!-J!b2qp3[qp3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9
        +b8'&dD!d"S`!"E3!!!b-$*J'N$!'N!!N!!cTND!!#!!!0!D%!!@m!!!!!!!$qp![
        +qp!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J'I!!)"T3'Q$3'P!!0*!!)$,!0@r[2
        +qmJ'R#[lc!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(qmJ!!"J'R!!2qm3'
        +S!DN+r[%!"!TVEf0X$3'S!!&Y!!!$-!-cr[!+r[!!"!TKE'PK"J'T!!2ql`'U!DX
        ++rZm!"!TTER0S$3'U!!)d!!!$0J-qrZi"V!VqlJ!%#Q0QEf`0!D`!!@m!!!-k!ch
        +ql3[ql3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
        +NC8C[E'4PFP"KG'J'!DX!!rlX!Dhqk`Vql!!%#R4[)#!0!Dd!!Qi!!!0"!e!"VJ'
        +[$3'Z!!)d!!!$5303rZS"X!VqkJ!%#QCTE'80!E!!!@d!!!0-!dm"X3`"X3!+!!4
        +ND#jS!!)!!!d"V`!#0!!!!d%$5IlT!E)+rZN!"!TMCQpX$3'b!!&[!!!$430)rZJ
        +,rZJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eqk`!!!J'Q!!)"X`'d$3'c!!*X!!)
        +$9`0ArZIqjJ(qj`!!!IlQ!!!#!E3!!J'e!EB0!E8!!R)!!!0A!f)"Y`'i$3'h!!*
        +L!!!$9`0H!EN"ZJd"Z3!"E`!!!eF$@[lP#rlP!#3`!""MFRP`G'pQEfaNCA*`BA4
        +S!""MFRP`G'p'EfaNCA*3BA4S$3'k!!&Y!!!$@J0G!EX-!EX!#J!%1Q4cB3!#!!!
        +0!EJ!!@m!!!!!!!$qj![qj!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J'f!!)"[!'
        +p$3'm!!0*!!)$B`10rZ2qiJ'q#[lM!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9
        +XE!(qiJ!!"J'q!!2qi3'r!F!+rZ%!"!TVEf0X$3'r!!&Y!!!$C`0UrZ!+rZ!!"!T
        +KE'PK"J(!!!2qh`("!F)+rYm!"!TTER0S$3("!!)d!!!$E30erYi"``VqhJ!%#Q0
        +QEf`0!F-!!@m!!!0a!h6qh3[qh3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4
        +S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!F)!!rlF!F6qf`Vqh!!%#R4[)#!
        +0!F3!!Qi!!!0i!iF"a3('$3(&!!)d!!!$J!1(rYS"a`VqfJ!%#QCTE'80!FF!!@d
        +!!!1$!iB"b!`"b!!,!!9NFf%ZD!!#!!!0!FB!!M3!!!0i!i$qf3(*#[lC!!3+BfC
        +[E!d"b3!"E`!!!h`$IrlB#rlB!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rYX!!!)
        +"[3!#!FS"b`d"bJ!#E!!#!ii$M[lArYB"rYF!!!(qeJ!!!J(,!!)"c!(0$3(-!!*
        +b!!!$MJ1C!Fi"c`d"cJ!#BJ!!!ii$P3(3!G%0!G!!!@m!!!11!j(qe3[qe3!N-!!
        +3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d"d3!"E3!!!j%$P!(
        +5$!(5!!S!"$TPFR)!!J!!$3(2!!&[!!!!!!!!rY3,rY3!&$!!#(4PEA"`BA4S!!K
        +dC@e`8'&dD!)"c3!#!G-"e!d"d`!$53!#!jS$a2l6rY)"e3Vqd`!B,Q0[FQ9MFQ9
        +X+LSU+J!!!!!!!*!!!'jeE'`"rY)!!!B"e3!$rY%"eJ(A#[l4!!3+DfpME!d"eJ!
        +"E3!!!ji$SIl3#[l3!!3+B@aTB3B"e`!$rXm"f!(C#[l2!!3+D@jcD!d"f!!#0!!
        +!!k3$V2l1!GS+rXi!"!TMCQpX$3(D!!&[!!!$U!1VrXd,rXd!0$!!''p`C@jcFfa
        +TEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J(C!!2
        +qc!(ErXX+rX`!"!TdEb!J$3(E!!*Z!!!$V`1q!G`"h3d"h!!#0!!!!lF$[[l+!Gi
        ++rXS!"!TQD@aP$3(H!!&Y!!!$ZJ1p!Gm-!Gm!#`!&CA*b,QJ!!J!!$3(G!!)d!!!
        +$V`1hrXN"i!Vqb3!%#Q0QEf`0!H!!!@m!!!1c!lEqb![qb!!8-!!)G'9YF("KG'J
        +!#(4PEA"3BA4S"[l,!!!#!G3!!J(K!H)0!H%!!Q`!!J2&!mAqarl'!Il(!!!"rXB
        +!!!)"iJ!#!H-"j!d"i`!#FJ!!!m8$d!(P!HB0!H8!!Q)!!!2&!m`"j`(S$3(R!!&
        +[!!!$a32)rX8,rX8!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC[E'4PFP"
        +KG'J0!HJ!!@d!!!2)!mX"k3`"k3!+!!3kCAC`!!)!!!d"jJ!"E`!!!!!!!2l%#rl
        +%!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!H3!!J(U!HX0!HS!!dN!!J24!r[q`rl
        +#!H`+rX-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Il#!!!'!H`!!rl"!Hd
        +"lJVq`3!%#QY[Bf`0!Hd!!@d!!!29!pMq`!Vq`!!%#Q&XD@%'!Hi!!rkr!Hm"m!V
        +q[`!%#QPZFfJ0!Hm!!M3!!!2E!q2q[J(a#[kq!!3+BfC[E!d"m3!"E`!!!pm$i[k
        +p#rkp!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4
        +P4QpXC'9b8'&dD!B"m!!$rV`"m[kl#[km!!3+G'mJ)!d"mJ!#EJ!!!qB$p3(c!I3
        +0!I-!!M3!!!2Z!rAqZJ(e#[kk!!3+CQPXC3d"p3!"E3!!!r%$p!(f$!(f!!X!"@9
        +fF#jS!!)!!!d"p!!#0!!!!qB$l[kj!IF+rVN!"!TMCQpX$3(h!!&[!!!$kJ2YrVJ
        +,rVJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!EqZ`!!!J(V!!)"q!(j$3(i!!*X!!)
        +$r!2mrVIqYJ(qY`!!!Ikf!!!#!IN!!J(k!IX0!IS!!R)!!!2m"!F"r!(p$3(m!!*
        +L!!!$r!3$!Ii"r`d"rJ!"E`!!!r`$rrke#rke!#3`!""MFRP`G'pQEfaNCA*`BA4
        +S!""MFRP`G'p'EfaNCA*3BA4S$3(r!!&Y!!!$r`3#!J!-!J!!#`!&1QKYB@-!!J!
        +!$3(p!!&[!!!!!!!!rV3,rV3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)"q`!#!J%
        +#!Jd#!3!$53!#"!J%-[kcrV)#!`VqX`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'j
        +eE'`"rV)!!!B#!`!$rV%#"!)&#[ka!!3+DfpME!d#"!!"E3!!"!`%$rk`#[k`!!3
        ++B@aTB3B#"3!$rUm#"J)(#[k[!!3+D@jcD!d#"J!#0!!!"")%'[kZ!JJ+rUi!"!T
        +MCQpX$3))!!&[!!!%&J3CrUd,rUd!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&
        +dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J)(!!2qV!)*rUX+rU`!"!TdEb!
        +J$3)*!!*Z!!!%(33X!JS##`d##J!#0!!!"#8%,2kU!J`+rUS!"!TQD@aP$3)-!!&
        +Y!!!%+!3V!Jd-!Jd!$!!'D'eKBbjS!!)!!!d##`!#0!!!""d%*IkT!Ji+rUN!"!T
        +MCQpX$3)1!!&[!!!%)33NrUJ,rUJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!EqU`!
        +!!J)#!!)#$`)3$3)2!!*X!!)%-`3crUIqTJ(qT`!!!IkQ!!!#!K!!!J)4!K)0!K%
        +!!R)!!!3c"$i#%`)8$3)6!!*L!!!%-`3k!K8#&Jd#&3!"E`!!"$-%0[kP#rkP!#3
        +`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3)@!!&Y!!!%0J3
        +j!KF-!KF!#`!&1QPNC@%!!J!!$3)8!!&[!!!!!!!!rU3,rU3!&$!!#(4PEA"`BA4
        +S!!KdC@e`8'&dD!)#%J!#!KJ#'3d#'!!$53!#"$m%DIkMrU)#'JVqS`!B,Q0[FQ9
        +MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rU)!!!B#'J!$rU%#'`)F#[kK!!3+DfpME!d
        +#'`!"E3!!"%-%4[kJ#[kJ!!3+B@aTB3B#(!!$rTm#(3)H#[kI!!3+D@jcD!d#(3!
        +#0!!!"%N%8IkH!Km+rTi!"!TMCQpX$3)I!!&[!!!%6343rTd,rTd!0$!!''p`C@j
        +cFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J)
        +H!!2qR!)JrTX+rT`!"!TdEb!J$3)J!!*Z!!!%9!4M!L%#)Jd#)3!#0!!!"&`%Brk
        +D!L-+rTS!"!TQD@aP$3)M!!&Y!!!%A`4L!L3-!L3!$!!'D@4PB5jS!!)!!!d#)J!
        +#0!!!"&3%A2kC!L8+rTN!"!TMCQpX$3)P!!&[!!!%@!4ErTJ,rTJ!&$!!#(4PEA"
        +`BA4S!!KdC@e`8'&dD!EqQ`!!!J)C!!)#*J)R$3)Q!!*X!!)%DJ4UrTIqPJ(qP`!
        +!!Ik@!!!#!LF!!J)S!LN0!LJ!!R)!!!4U"(8#+J)V$3)U!!*L!!!%DJ4a!L`#,3d
        +#,!!"E`!!"'S%EIk9#rk9!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'Efa
        +NCA*3BA4S$3)Y!!&Y!!!%E34`!Li-!Li!$!!'1QaSBA0S!!)!!!d#+`!"E`!!!!!
        +!!2k8#rk8!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!LN!!J)[!M!0!Lm!!dN!!J4
        +f"+$qNrk5!M%+rT-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ik5!!!'!M%
        +!!rk4!M)#-`VqN3!%#QY[Bf`0!M)!!@d!!!4k"(hqN!!+rT!!!!3+B@aTB3B#-`!
        +$rSm#0!)e#[k2!!3+D@jcD!d#0!!#0!!!")!%L2k1!MB+rSi!"!TMCQpX$3)f!!&
        +[!!!%K!5(rSd,rSd!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP0
        +66%PZBfaeC'9'EfaNCA*3BA4S"J)e!!2qM!)hrSX+rS`!"!TdEb!J$3)h!!*Z!!!
        +%L`5D!MJ#13d#1!!#0!!!"*-%Q[k+!MS+rSS!"!TQD@aP$3)k!!&Y!!!%PJ5C!MX
        +-!MX!$3!(E'KKFfJZD!!#!!!0!MN!!M3!!!5,"*2qL3)m#[k*!!3+BfC[E!d#2!!
        +"E`!!")m%N[k)#rk)!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rSX!!!)#-!!#!Md
        +#2Jd#23!#E!!#"+%%SIk(rSB"rSF!!!(qKJ!!!J)q!!)#2`*!$3)r!!*b!!!%S35
        +X!N%#3Jd#33!#BJ!!"+%%U!*$!N30!N-!!@m!!!5K"+6qK3[qK3!N-!!3Bh*jF(4
        +[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d#4!!"E3!!"+3%T`*&$!*&!!S
        +!"$TYC$)!!J!!$3*#!!&[!!!!!!!!rS3,rS3!&$!!#(4PEA"`BA4S!!KdC@e`8'&
        +dD!)#3!!#!NB#4`d#4J!$53!#"+d%erk$rS)#5!VqJ`!B,Q0[FQ9MFQ9X+LSU+J!
        +!!!!!!*!!!'jeE'`"rS)!!!B#5!!$rS%#53*+#[k"!!3+DfpME!d#53!"E3!!",%
        +%Y2k!#[k!!!3+B@aTB3B#5J!$rRm#5`*-#[jr!!3+D@jcD!d#5`!#0!!!",F%[rj
        +q!Nd+rRi!"!TMCQpX$3*0!!&[!!!%Z`5qrRd,rRd!0$!!''p`C@jcFfaTEQ0XG@4
        +PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J*-!!2qI!*1rRX
        ++rR`!"!TdEb!J$3*1!!*Z!!!%`J64!Nm#8!d#6`!#0!!!"-S%dIjk!P%+rRS!"!T
        +QD@aP$3*4!!&Y!!!%c363!P)-!P)!#`!&E@3b,QJ!!J!!$3*3!!)d!!!%`J6+rRN
        +#8`VqH3!%#Q0QEf`0!P-!!@m!!!6'"-RqH![qH!!8-!!)G'9YF("KG'J!#(4PEA"
        +3BA4S"[jl!!!#!NF!!J*8!P80!P3!!Q`!!J6B"0MqGrjf!Ijh!!!"rRB!!!)#93!
        +#!PB#9`d#9J!#FJ!!"0J%i`*B!PN0!PJ!!Q)!!!6B"0m#@J*E$3*D!!&[!!!%f!6
        +ErR8,rR8!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!PX
        +!!@d!!!6E"0i#A!`#A!!+!!3kE@3e!!)!!!d#@3!"E`!!!!!!!2jd#rjd!"3`!!K
        +dC@e`F'&dD!!)G'9YF&"KG'J#!PF!!J*G!Pi0!Pd!!dN!!J6N"3lqFrjb!Pm+rR-
        +!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ijb!!!'!Pm!!rja!Q!#B3VqF3!
        +%#QY[Bf`0!Q!!!@d!!!6S"1[qF!VqF!!%#Q&XD@%'!Q%!!rj[!Q)#B`VqE`!%#QP
        +ZFfJ0!Q)!!M3!!!6Z"2EqEJ*N#[jZ!!3+BfC[E!d#C!!"E`!!"2)%pIjY#rjY!$3
        +`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9
        +b8'&dD!B#B`!$rQ`#CIjV#[jX!!3+G'mJ)!d#C3!#EJ!!"2N&#!*Q!QF0!QB!!M3
        +!!!8""3MqDJ*S#[jU!!3+CQPXC3d#D!!"E3!!"33&"`*T$!*T!!X!"@eN05jS!!)
        +!!!d#C`!#0!!!"2N&!IjT!QS+rQN!"!TMCQpX$3*U!!&[!!!%r38!rQJ,rQJ!&$!
        +!#(4PEA"`BA4S!!KdC@e`8'&dD!EqD`!!!J*H!!)#D`*X$3*V!!*X!!)&$`82rQI
        +qCJ(qC`!!!IjQ!!!#!Q`!!J*Y!Qi0!Qd!!R)!!!82"4S#E`*`$3*[!!*L!!!&$`8
        +@!R%#FJd#F3!"E`!!"3m&%[jP#rjP!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP
        +`G'p'EfaNCA*3BA4S$3*b!!&Y!!!&%J89!R--!R-!#`!&1QeNBc)!!J!!$3*`!!&
        +[!!!!!!!!rQ3,rQ3!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)#EJ!#!R3#G3d#G!!
        +$53!#"4X&4IjMrQ)#GJVqB`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rQ)
        +!!!B#GJ!$rQ%#G`*i#[jK!!3+DfpME!d#G`!"E3!!"4m&)[jJ#[jJ!!3+B@aTB3B
        +#H!!$rPm#H3*k#[jI!!3+D@jcD!d#H3!#0!!!"58&,IjH!RX+rPi!"!TMCQpX$3*
        +l!!&[!!!&+38XrPd,rPd!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"
        +PEP066%PZBfaeC'9'EfaNCA*3BA4S"J*k!!2qA!*mrPX+rP`!"!TdEb!J$3*m!!*
        +Z!!!&-!8r!Rd#IJd#I3!#0!!!"6J&2rjD!Rm+rPS!"!TQD@aP$3*r!!&Y!!!&1`8
        +q!S!-!S!!$!!'E@4M-LjS!!)!!!d#IJ!#0!!!"6!&12jC!S%+rPN!"!TMCQpX$3+
        +"!!&[!!!&0!8hrPJ,rPJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eq@`!!!J*e!!)
        +#JJ+$$3+#!!*X!!)&4J9'rPIq9J(q9`!!!Ij@!!!#!S-!!J+%!S80!S3!!R)!!!9
        +'"9%#KJ+($3+'!!*L!!!&4J90!SJ#L3d#L!!"E`!!"8B&5Ij9#rj9!#3`!""MFRP
        +`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3+*!!&Y!!!&539-!SS-!SS
        +!$J!)1QpLDQ9MG(-!!J!!$3+(!!&[!!!!!!!!rP3,rP3!&$!!#(4PEA"`BA4S!!K
        +dC@e`8'&dD!)#K3!#!SX#M!d#L`!$53!#"9)&I2j6rP)#M3Vq8`!B,Q0[FQ9MFQ9
        +X+LSU+J!!!!!!!*!!!'jeE'`"rP)!!!B#M3!$rP%#MJ+2#[j4!!3+DfpME!d#MJ!
        +"E3!!"9B&@Ij3#[j3!!3+B@aTB3B#M`!$rNm#N!!#N3Vq6`!%#QPZFfJ0!T!!!!)
        +d!!!&A!9NrNi#NJVq6J!%#Q0QEf`0!T)!!@m!!!9J"@2q63[q63!d-!!BEh"PER0
        +cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!T%
        +!!rj-!T2q5`Vq6!!%#R4[)#!0!T-!!Qi!!!9R"AB#P!+9$3+8!!)d!!!&E`9frNS
        +#PJVq5J!%#QCTE'80!TB!!@d!!!9b"A8#P``#P`!2!!P[BQTPBh4c,QJ!!J!!$3+
        +9!!)d!!!&C`9[rNN#Q!Vq53!%#Q0QEf`0!TJ!!@m!!!9V"@lq5![q5!!8-!!)G'9
        +YF("KG'J!#(4PEA"3BA4S"[j,!!!#!S`!!J+C!TS0!TN!!Q`!!J9p"Ahq4rj'!Ij
        +(!!!"rNB!!!)#QJ!#!TX#R!d#Q`!#FJ!!"Ad&L!+G!Ti0!Td!!Q)!!!9p"B3#R`+
        +J$3+I!!&[!!!&I3@!rN8,rN8!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC
        +[E'4PFP"KG'J0!U!!!@d!!!@!"B-#S3`#S3!+!!3kF'9Y!!)!!!d#RJ!"E`!!!!!
        +!!2j%#rj%!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!T`!!J+L!U-0!U)!!dN!!J@
        +*"E2q3rj#!U3+rN-!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ij#!!!'!U3
        +!!rj"!U8#TJVq33!%#QY[Bf`0!U8!!@d!!!@0"C!!rN!+rN!!"!TKE'PK"J+Q!!2
        +q2`+R!UJ+rMm!"!TTER0S$3+R!!)d!!!&N`@ErMi#U3Vq2J!%#Q0QEf`0!UN!!@m
        +!!!@A"CVq23[q23!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0
        +-5@jME(9NC8C[E'4PFP"KG'J'!UJ!!rim!UVq1`Vq2!!%#R4[)#!0!US!!Qi!!!@
        +H"Dd#U`+X$3+V!!)d!!!&TJ@YrMS#V3Vq1J!%#QCTE'80!Ud!!@d!!!@T"D`#VJ`
        +#VJ!,!!9`C@dZD!!#!!!0!U`!!M3!!!@H"DEq13+[#[ij!!3+BfC[E!d#V`!"E`!
        +!"D)&TIii#rii!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'rMX!!!)#S`!#!V!#X3d
        +#X!!$53!#"E3&h[ihrMB#XJVq0`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`
        +"rMB!!!B#XJ!$rM8#X`+d#[ie!!3+DfpME!d#X`!"E3!!"EJ&Zrid#[id!!3+B@a
        +TB3B#Y!!$rM-#Y3+f#[ic!!3+D@jcD!d#Y3!#0!!!"Ei&a[ib!VF+rM)!"!TMCQp
        +X$3+h!!&[!!!&`JA&rM%,rM%!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!
        +BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J+f!!2q-!+irLm+rM!!"!TdEb!J$3+
        +i!!*Z!!!&b3AB!VN#ZJd#Z3!#0!!!"G%&f2iZ!VX+rLi!"!TQD@aP$3+l!!&Y!!!
        +&e!AA!V`-!V`!$!!'F'9Y-LjS!!)!!!d#ZJ!#0!!!"FN&dIiY!Vd+rLd!"!TMCQp
        +X$3+p!!&[!!!&c3A3rL`,rL`!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eq,`!!!J+
        +a!!)#[J+r$3+q!!*X!!)&h`AIrL[q+J(q+`!!!IiU!!!#!Vm!!J,!!X%0!X!!!R)
        +!!!AI"HS#`J,$$3,#!!*L!!!&h`AQ!X3#a3d#a!!"E`!!"Gm&i[iT#riT!#3`!""
        +MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3,&!!&Y!!!&iJAP!XB
        +-!XB!$3!(1R"VBh-a-J!#!!!0!X-!!@m!!!!!!!$q+![q+!!8-!!)G'9YF("KG'J
        +!#(4PEA"3BA4S!J,"!!)#a`,)$3,(!!0*!!)&k`B9rLIq*J,*#[iR!"JZBfpbC@0
        +bC@`U+LSU!!!!!!!!N!!!ER9XE!(q*J!!"J,*!!2q*3,+!XX+rL8!"!TVEf0X$3,
        ++!!&Y!!!&l`AbrL3+rL3!"!TKE'PK"J,,!!2q)`,-!Xd+rL-!"!TTER0S$3,-!!)
        +d!!!&p3AprL)#cJVq)J!%#Q0QEf`0!Xi!!@m!!!Aj"Icq)3[q)3!d-!!BEh"PER0
        +cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!Xd
        +!!riJ!Xrq(`Vq)!!%#R4[)#!0!Xm!!Qi!!!B!"Jm#d!,4$3,3!!)d!!!'#!B2rKi
        +#dJVq(J!%#QCTE'80!Y)!!@d!!!B,"Ji#d``#d`!1!!K`Df0c-6)ZD!!#!!!0!Y%
        +!!M3!!!B!"JMq(3,8#[iG!!3+BfC[E!d#e!!"E`!!"J3'"riF#riF!"3`!!KdC@e
        +`F'&dD!!)G'9YF&"KG'J'rKm!!!)#b!!#!Y8#eJd#e3!#E!!#"KB'&[iErKS"rKX
        +!!!(q'J!!!J,@!!)#e`,B$3,A!!*b!!!'&JBK!YN#fJd#f3!#BJ!!"KB'(3,E!Y`
        +0!YX!!@m!!!B@"KRq'3[q'3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4Qp
        +XC'9b8'&dD!d#h!!"E3!!"KN'(!,G$!,G!!`!"MT`Df0c0`!#!!!0!YS!!@m!!!!
        +!!!$q'![q'!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J,B!!)#hJ,I$3,H!!0*!!)
        +')JC-rKIq&J,J#[iA!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!(q&J!!"J,
        +J!!2q&3,K!Z)+rK8!"!TVEf0X$3,K!!&Y!!!'*JBTrK3+rK3!"!TKE'PK"J,L!!2
        +q%`,M!Z3+rK-!"!TTER0S$3,M!!)d!!!',!BdrK)#j3Vq%J!%#Q0QEf`0!Z8!!@m
        +!!!B`"M2q%3[q%3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0
        +-5@jME(9NC8C[E'4PFP"KG'J'!Z3!!ri3!ZEq$`Vq%!!%#R4[)#!0!ZB!!Qi!!!B
        +h"NB#j`,S$3,R!!)d!!!'2`C'rJi#k3Vq$J!%#QCTE'80!ZN!!@d!!!C#"N8#kJ`
        +#kJ!0!!G`Df0c0bjS!!)!!!d#k!!#0!!!"MF'2ri0!ZX+rJd!"!TMCQpX$3,V!!&
        +[!!!'1`BqrJ`,rJ`!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eq$`!!!J,I!!)#l!,
        +Y$3,X!!*X!!)'63C0rJ[q#J(q#`!!!Ii+!!!#!Zd!!J,Z!Zm0!Zi!!R)!!!C0"PJ
        +#m!,a$3,`!!*L!!!'63C8![)#m`d#mJ!"E`!!"Nd'82i*#ri*!#3`!""MFRP`G'p
        +QEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3,c!!&Y!!!'8!C6![3-![3!#`!
        +&1R*KEQ3!!J!!$3,a!!&[!!!!!!!!rJJ,rJJ!&$!!#(4PEA"`BA4S!!KdC@e`8'&
        +dD!)#l`!#![8#pJd#p3!$53!#"PN'Jri(rJB#p`Vq"`!B,Q0[FQ9MFQ9X+LSU+J!
        +!!!!!!*!!!'jeE'`"rJB!!!B#p`!$rJ8#q!,j#[i&!!3+DfpME!d#q!!"E3!!"Pd
        +'B2i%#[i%!!3+B@aTB3B#q3!$rJ-#qJ,l#[i$!!3+D@jcD!d#qJ!#0!!!"Q-'Dri
        +#![`+rJ)!"!TMCQpX$3,m!!&[!!!'C`CUrJ%,rJ%!0$!!''p`C@jcFfaTEQ0XG@4
        +PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J,l!!2q!!,prIm
        ++rJ!!"!TdEb!J$3,p!!*Z!!!'EJCp![i#r`d#rJ!#0!!!"RB'IIhq!`!+rIi!"!T
        +QD@aP$3-!!!&Y!!!'H3Cm!`%-!`%!$!!'FQ&ZC#jS!!)!!!d#r`!#0!!!"Qi'G[h
        +p!`)+rId!"!TMCQpX$3-#!!&[!!!'FJCerI`,rI`!&$!!#(4PEA"`BA4S!!KdC@e
        +`8'&dD!Epr`!!!J,f!!)$!`-%$3-$!!*X!!)'K!D%rI[pqJ(pq`!!!Ihk!!!#!`3
        +!!J-&!`B0!`8!!R)!!!D%"Sm$"`-)$3-(!!*L!!!'K!D,!`N$#Jd$#3!"E`!!"S3
        +'Krhj#rhj!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3-
        ++!!&Y!!!'K`D+!`X-!`X!#J!%1R*M-J!#!!!0!`J!!@m!!!!!!!$pq![pq!!8-!!
        +)G'9YF("KG'J!#(4PEA"3BA4S!J-'!!)$$!-0$3--!!0*!!)'N!!'Z[hhrIB$$JV
        +pp`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rIB!!!B$$J!$rI8$$`-3#[h
        +e!!3+DfpME!d$$`!"E3!!"T3'Prhd#[hd!!3+B@aTB3B$%!!$rI-$%3-5#[hc!!3
        ++D@jcD!d$%3!#0!!!"TS'S[hb!a-+rI)!"!TMCQpX$3-6!!&[!!!'RJDKrI%,rI%
        +!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'Efa
        +NCA*3BA4S"J-5!!2pm!-8rHm+rI!!"!TdEb!J$3-8!!*Z!!!'T3Dd!a8$&Jd$&3!
        +#0!!!"Ud'Y2hZ!aF+rHi!"!TQD@aP$3-A!!&Y!!!'X!Dc!aJ-!aJ!#`!&FQ-b,QJ
        +!!J!!$3-@!!)d!!!'T3DYrHd$'3Vpl3!%#Q0QEf`0!aN!!@m!!!DT"Ucpl![pl!!
        +8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[h[!!!#!`d!!J-D!aX0!aS!!Q`!!JDl"V[
        +pkrhU!IhV!!!"rHS!!!)$'`!#!a`$(3d$(!!#FJ!!"VX'aJ-H!am0!ai!!Q)!!!D
        +l"X)$)!-K$3-J!!&[!!!'Z`DqrHN,rHN!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0
        +bHA"dEdC[E'4PFP"KG'J0!b%!!@d!!!Dq"X%$)J`$)J!+!!3kFQ-d!!)!!!d$(`!
        +"E`!!!!!!!2hS#rhS!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!ad!!J-M!b30!b-
        +!!dN!!JE("[(pjrhQ!b8+rHF!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"ZG@aX!Ih
        +Q!!!'!b8!!rhP!bB$*`Vpj3!%#QY[Bf`0!bB!!@d!!!E,"Xlpj!Vpj!!%#Q&XD@%
        +'!bF!!rhM!bJ$+3Vpi`!%#QPZFfJ0!bJ!!M3!!!E4"YRpiJ-U#[hL!!3+BfC[E!d
        +$+J!"E`!!"Y8'f2hK#rhK!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p
        +`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B$+3!$rH!$+rhI#[hJ!!3+G'mJ)!d$+`!
        +#EJ!!"Y`'k`-X!bd0!b`!!M3!!!EN"Z[phJ-Z#[hH!!3+CQPXC3d$,J!"E3!!"ZF
        +'kJ-[$!-[!!X!"A*M0#jS!!)!!!d$,3!#0!!!"Y`'j2hG!c!+rGd!"!TMCQpX$3-
        +`!!&[!!!'i!EMrG`,rG`!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!Eph`!!!J-N!!)
        +$-3-b$3-a!!*X!!)'mJEbrG[pfJ(pf`!!!IhD!!!#!c)!!J-c!c30!c-!!R)!!!E
        +b"[d$03-f$3-e!!*L!!!'mJEj!cF$1!d$0`!"E`!!"[)'pIhC#rhC!#3`!""MFRP
        +`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$3-i!!&Y!!!'p3Ei!cN-!cN
        +!#J!%1R*M03!#!!!0!cB!!@m!!!!!!!$pf![pf!!8-!!)G'9YF("KG'J!#(4PEA"
        +3BA4S!J-d!!)$1J-l$3-k!!0*!!)'rJFSrGIpeJ-m#[hA!"JZBfpbC@0bC@`U+LS
        +U!!!!!!!!N!!!ER9XE!(peJ!!"J-m!!2pe3-p!ci+rG8!"!TVEf0X$3-p!!&Y!!!
        +(!JF&rG3+rG3!"!TKE'PK"J-q!!2pd`-r!d!+rG-!"!TTER0S$3-r!!)d!!!(#!F
        +3rG)$33VpdJ!%#Q0QEf`0!d%!!@m!!!F-"`rpd3[pd3!d-!!BEh"PER0cE'PZBfa
        +eC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!d!!!rh3!d,
        +pc`Vpd!!%#R4[)#!0!d)!!Qi!!!F6"b)$3`0%$30$!!)d!!!('`FLrFi$43VpcJ!
        +%#QCTE'80!d8!!@d!!!FH"b%$4J`$4J!,!!9bBc8ZD!!#!!!0!d3!!M3!!!F6"a[
        +pc30(#[h0!!3+BfC[E!d$4`!"E`!!"aF('[h-#rh-!"3`!!KdC@e`F'&dD!!)G'9
        +YF&"KG'J'rFm!!!)$1`!#!dJ$53d$5!!#E!!#"bN(+Ih,rFS"rFX!!!(pbJ!!!J0
        +*!!)$5J0,$30+!!*b!!!(+3Fd!d`$63d$6!!#BJ!!"bN(-!01!dm0!di!!@m!!!F
        +T"bcpb3[pb3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d
        +$6`!"E3!!"b`(,`03$!03!!d!"cTbDA"PE@3!!J!!$300!!&[!!!!!!!!rFJ,rFJ
        +!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)$5`!#!e%$8Jd$83!$53!#"c8(Arh(rFB
        +$8`Vpa`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rFB!!!B$8`!$rF8$9!0
        +9#[h&!!3+DfpME!d$9!!"E3!!"cN(22h%#[h%!!3+B@aTB3B$93!$rF-$9J0A#[h
        +$!!3+D@jcD!d$9J!#0!!!"cm(4rh#!eJ+rF)!"!TMCQpX$30B!!&[!!!(3`G'rF%
        +,rF%!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9
        +'EfaNCA*3BA4S"J0A!!2p`!0CrEm+rF!!"!TdEb!J$30C!!*Z!!!(5JGC!eS$@`d
        +$@J!#0!!!"e)(@Ifq!e`+rEi!"!TQD@aP$30F!!&Y!!!(93GB!ed-!ed!$J!)FQP
        +`C@eN,QJ!!J!!$30E!!)d!!!(5JG5rEd$AJVp[3!%#Q0QEf`0!ei!!@m!!!G1"e(
        +p[![p[!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[fr!!!#!e)!!J0I!f!0!em!!Q`
        +!!JGJ"f$pZrfk!Ifl!!!"rES!!!)$B!!#!f%$BJd$B3!#FJ!!"f!(D`0M!f30!f-
        +!!Q)!!!GJ"fF$C30Q$30P!!&[!!!(B!GMrEN,rEN!*$!!%'0bHA"dEfC[E'4PFR"
        +KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!fB!!@d!!!GM"fB$C``$C`!+!!3kFR0K!!)
        +!!!d$C!!"E`!!!!!!!2fi#rfi!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J#!f)!!J0
        +S!fN0!fJ!!dN!!JGX"jEpYrff!fS+rEF!'#jMEh*PBh*PE#SU+LS!!!!!!!#3!!"
        +ZG@aX!Iff!!!'!fS!!rfe!fX$E!VpY3!%#QY[Bf`0!fX!!@d!!!G`"h2pY!VpY!!
        +%#Q&XD@%'!f`!!rfc!fd$EJVpX`!%#QPZFfJ0!fd!!M3!!!Gf"hlpXJ0[#[fb!!3
        ++BfC[E!d$E`!"E`!!"hS(IIfa#rfa!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4PFR"
        +KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B$EJ!$rE!$F2f[#[f`!!3+G'm
        +J)!d$F!!#EJ!!"i%(N!!$F30b$30a!!)d!!!(L3H3!2fZ!h-+rDi!"!TQD@aP$30
        +c!!&Y!!!(M!H2!h3-!h3!#`!&FR0K,QJ!!J!!$30b!!)d!!!(J3H*rDd$G3VpV3!
        +%#Q0QEf`0!h8!!@m!!!H&"iMpV![pV!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[f
        +[!!!#!fN!!J0f!hF0!hB!!Q`!!JHA"jIpUrfU!IfV!!!"rDS!!!)$G`!#!hJ$H3d
        +$H!!#FJ!!"jF(SJ0k!hX0!hS!!Q)!!!HA"ji$I!0p$30m!!&[!!!(P`HDrDN,rDN
        +!*$!!%'0bHA"dEfC[E'4PFR"KG'J!%'0bHA"dEdC[E'4PFP"KG'J0!hd!!@d!!!H
        +D"jd$IJ`$IJ!-!!BkFh4KBfX!!J!!$30l!!&[!!!!!!!!rDJ,rDJ!&$!!#(4PEA"
        +`BA4S!!KdC@e`8'&dD!)$H3!#!hm$J!d$I`!$53!#"k-(cIfRrDB$J3VpT`!B,Q0
        +[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rDB!!!B$J3!$rD8$JJ1$#[fP!!3+Dfp
        +ME!d$JJ!"E3!!"kF(U[fN#[fN!!3+B@aTB3B$J`!$rD-$K!1&#[fM!!3+D@jcD!d
        +$K!!#0!!!"kd(YIfL!iB+rD)!"!TMCQpX$31'!!&[!!!(X3HdrD%,rD%!0$!!''p
        +`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4
        +S"J1&!!2pS!1(rCm+rD!!"!TdEb!J$31(!!*Z!!!(Z!I(!iJ$L3d$L!!#0!!!"m!
        +(arfH!iS+rCi!"!TQD@aP$31+!!&Y!!!(``I'!iX-!iX!$3!(Fh4KBfXZD!!#!!!
        +0!iN!!M3!!!Hi"m$pR31-#[fG!!3+BfC[E!d$M!!"E`!!"l`([rfF#rfF!"3`!!K
        +dC@e`F'&dD!!)G'9YF&"KG'J'rCm!!!)$J!!#!id$MJd$M3!$53!#"mi(q2fErCS
        +$M`VpQ`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rCS!!!B$M`!$rCN$N!!
        +$N3VpQ3!%#QY[Bf`0!j!!!!&Y!!!(dJI9rCJ+rCJ!"!TKE'PK"J14!!2pP`15!j-
        ++rCF!"!TTER0S$315!!)d!!!(f!IJrCB$P!VpPJ!%#Q0QEf`0!j3!!@m!!!IF"pr
        +pP3[pP3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
        +NC8C[E'4PFP"KG'J'!j-!!rf8!jApN`VpP!!%#R4[)#!0!j8!!Qi!!!IM"r)$PJ1
        +A$31@!!)d!!!(k`IbrC)$Q!VpNJ!%#QCTE'80!jJ!!@d!!!IZ"r%$Q3`$Q3!4!!Y
        +cB@CPFh4KBfXZD!!#!!!0!jF!!M3!!!IM"q[pN31D#[f4!!3+BfC[E!d$QJ!"E`!
        +!"qF(k[f3!![pN!!!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!EpN`!!!J11!!)$Q`1
        +F$31E!!*X!!)(q3IjrBrpMJ(pM`!!!If1!!!#!j`!!J1G!ji0!jd!!R)!!!Ij#!3
        +$R`1J$31I!!*L!!!(q3J!!k%$SJd$S3!"E`!!"rN(r2f0#rf0!#3`!""MFRP`G'p
        +QEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S$31L!!&Y!!!(r!Ir!k--!k-!#J!
        +%1R0SB3!#!!!0!k!!!@m!!!!!!!$pM![pM!!8-!!)G'9YF("KG'J!#(4PEA"3BA4
        +S!J1H!!)$T!1P$31N!!0*!!))"3J[rB[pLJ1Q#[f,!"JZBfpbC@0bC@`U+LSU!!!
        +!!!!!N!!!ER9XE!(pLJ!!"J1Q!!2pL31R!kJ+rBN!"!TVEf0X$31R!!&Y!!!)#3J
        +-rBJ+rBJ!"!TKE'PK"J1S!!2pK`1T!kS+rBF!"!TTER0S$31T!!)d!!!)$`JArBB
        +$U`VpKJ!%#Q0QEf`0!kX!!@m!!!J6#"EpK3[pK3!d-!!BEh"PER0cE'PZBfaeC'9
        +QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!kS!!rf%!kcpJ`V
        +pK!!%#R4[)#!0!k`!!Qi!!!JD##N$V31Z$31Y!!)d!!!))JJTrB)$V`VpJJ!%#QC
        +TE'80!km!!@d!!!JP##J$X!`$X!!,!!9cD'%ZD!!#!!!0!ki!!M3!!!JD##,pJ31
        +a#[f"!!3+BfC[E!d$X3!"E`!!#"i))If!#rf!!"3`!!KdC@e`F'&dD!!)G'9YF&"
        +KG'J'rB-!!!)$T3!#!l)$X`d$XJ!#E!!##$!)-2errAi"rAm!!!(pIJ!!!J1c!!)
        +$Y!1e$31d!!*b!!!)-!Jl!lB$Y`d$YJ!#BJ!!#$!)0`1i!lN0!lJ!!@m!!!J`#$2
        +pI3[pI3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD!d$Z3!
        +"E3!!#$-)0J1k$!1k!!d!"cTdH(4IC')!!J!!$31h!!&[!!!!!!!!rA`,rA`!&$!
        +!#(4PEA"`BA4S!!KdC@e`8'&dD!)$Y3!#!lX$[!d$Z`!$53!##$`)C[elrAS$[3V
        +pH`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"rAS!!!B$[3!$rAN$[J1r#[e
        +j!!3+DfpME!d$[J!"E3!!#%!)3rei#[ei!!3+B@aTB3B$[`!$rAF$`!2"#[eh!!3
        ++D@jcD!d$`!!#0!!!#%B)6[ef!m)+rAB!"!TMCQpX$32#!!&[!!!)5JK0rA8,rA8
        +!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'Efa
        +NCA*3BA4S"J2"!!2pG!2$rA-+rA3!"!TdEb!J$32$!!*Z!!!)83KJ!m3$a3d$a!!
        +#0!!!#&N)B2eb!mB+rA)!"!TQD@aP$32'!!&Y!!!)A!KI!mF-!mF!$J!)G(KdAf4
        +L,QJ!!J!!$32&!!)d!!!)83KCrA%$b!VpF3!%#Q0QEf`0!mJ!!@m!!!K9#&MpF![
        +pF!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[ec!!!#!l`!!J2*!mS0!mN!!Q`!!JK
        +R#'IpEreZ!Ie[!!!"r@i!!!)$bJ!#!mX$c!d$b`!#FJ!!#'F)FJ20!mi0!md!!Q)
        +!!!KR#'i$c`23$322!!&[!!!)C`KUr@d,r@d!*$!!%'0bHA"dEfC[E'4PFR"KG'J
        +!%'0bHA"dEdC[E'4PFP"KG'J0!p!!!@d!!!KU#'d$d3`$d3!,!!8kH$8`13!#!!!
        +0!mi!!@m!!!!!!!$pE![pE!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!J2-!!)$dJ2
        +6$325!!0*!!))F`LGr@[pDJ28#[eV!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9
        +XE!(pDJ!!"J28!!2pD329!pB+r@N!"!TVEf0X$329!!&Y!!!)G`Kkr@J+r@J!"!T
        +KE'PK"J2@!!2pC`2A!pJ+r@F!"!TTER0S$32A!!)d!!!)I3L&r@B$f3VpCJ!%#Q0
        +QEf`0!pN!!@m!!!L"#)6pC3[pC3!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4
        +S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'!pJ!!reN!pVpB`VpC!!%#R4[)#!
        +0!pS!!Qi!!!L)#*F$f`2F$32E!!)d!!!)N!!)PreL!pd+r@)!"!TQD@aP$32G!!&
        +Y!!!)N`L@!pi-!pi!$!!'H$8`15jS!!)!!!d$h!!#0!!!#)J)N!$pB32I#[eK!!3
        ++BfC[E!d$h`!"E`!!#)`)MreJ#reJ!"3`!!KdC@e`F'&dD!!)G'9YF&"KG'J'r@-
        +!!!)$d`!#!q!$i3d$i!!$53!##*i)b2eIr9i$iJVpA`!B,Q0[FQ9MFQ9X+LSU+J!
        +!!!!!!*!!!'jeE'`"r9i!!!B$iJ!$r9d$i`2N#[eG!!3+DfpME!d$i`!"E3!!#+)
        +)TIeF#[eF!!3+B@aTB3B$j!!$r9X$j32Q#[eE!!3+D@jcD!d$j3!#0!!!#+J)X2e
        +D!qF+r9S!"!TMCQpX$32R!!&[!!!)V!L[r9N,r9N!0$!!''p`C@jcFfaTEQ0XG@4
        +PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J2Q!!2p@!2Sr9F
        ++r9J!"!TdEb!J$32S!!*Z!!!)X`M#!qN$kJd$k3!#0!!!#,X)`[e@!qX+r9B!"!T
        +QD@aP$32V!!&Y!!!)[JM"!q`-!q`!%!!+H$8`19pfCRNZD!!#!!!0!qS!!M3!!!L
        +c#,[p932Y#[e9!!3+BfC[E!d$l3!"E`!!#,F)Z[e8#re8!"3`!!KdC@e`F'&dD!!
        +)G'9YF&"KG'J'r9F!!!)$i3!#!qi$l`d$lJ!#E!!##-N)bIe6r9)"r9-!!!(p8J!
        +!!J2[!!)$m!2a$32`!!*b!!!)b3M8!r)$m`d$mJ!#BJ!!#-N)d!2d!r80!r3!!@m
        +!!!M*#-cp83[p83!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&
        +dD!d$p3!"E3!!#-`)c`2f$!2f!!d!"cTi06!jGM-!!J!!$32c!!&[!!!!!!!!r9!
        +,r9!!&$!!#(4PEA"`BA4S!!KdC@e`8'&dD!)$m3!#!rF$q!d$p`!$53!##08)rre
        +2r8i$q3Vp6`!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r8i!!!B$q3!$r8d
        +$qJ2l#[e0!!3+DfpME!d$qJ!"E3!!#0N)h2e-#[e-!!3+B@aTB3B$q`!$r8X$r!2
        +p#[e,!!3+D@jcD!d$r!!#0!!!#0m)jre+!ri+r8S!"!TMCQpX$32q!!&[!!!)i`M
        +Qr8N,r8N!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfa
        +eC'9'EfaNCA*3BA4S"J2p!!2p5!2rr8F+r8J!"!TdEb!J$32r!!*Z!!!)kJMj"!!
        +%!3d%!!!#0!!!#2))qIe'"!)+r8B!"!TQD@aP$33#!!&Y!!!)p3Mi"!--"!-!$J!
        +)H$8`1ABc,QJ!!J!!$33"!!)d!!!)kJMbr88%"!Vp43!%#Q0QEf`0"!3!!@m!!!M
        +Z#2(p4![p4!!8-!!)G'9YF("KG'J!#(4PEA"3BA4S"[e(!!!#!rJ!!J3&"!B0"!8
        +!!Q`!!JN!#3$p3re#!Ie$!!!"r8)!!!)%"J!#"!F%#!d%"`!$53!##3!*+[e"r8!
        +%#3Vp33!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r8!!!!B%#3!$r6m%#J3
        +,#[dr!!3+DfpME!d%#J!"E3!!#33*"rdq#[dq!!3+B@aTB3B%#`!$r6d%$!30#[d
        +p!!3+D@jcD!d%$!!#0!!!#3S*%[dm"!i+r6`!"!TMCQpX$331!!&[!!!*$JN4r6X
        +,r6X!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9
        +'EfaNCA*3BA4S"J30!!2p1J32r6N+r6S!"!TdEb!J$332!!*Z!!!*&3NN""!%%3d
        +%%!!#0!!!#4d**2di"")+r6J!"!TQD@aP$335!!&Y!!!*)!NM""--""-!#`!&Fh0
        +X,QJ!!J!!$334!!)d!!!*&3NGr6F%&!Vp0`!%#Q0QEf`0""3!!@m!!!NC#4cp0J[
        +p0J!H-!!0Fh0XCQpXC'9bF'&dD!!0Fh0X4QpXC'9b8'&dD!Ep13!!!J3)!!)%&33
        +@$339!!0*!!)*+`P9r6Ap0!3A#[de!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9
        +XE!(p0!!!"J3A!!2p-`3B""N+r6-!"!TVEf0X$33B!!&Y!!!*,`Nbr6)+r6)!"!T
        +KE'PK"J3C!!2p-33D""X+r6%!"!TTER0S$33D!!)d!!!*03Npr6!%(!Vp-!!%#Q0
        +QEf`0""`!!@m!!!Nj#6cp,`[p,`!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4
        +S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'""X!!rdZ""hp,3Vp,J!%#R4[)#!
        +0""d!!Qi!!!P!#8m%(J3I$33H!!)d!!!*5!P2r5`%)!Vp,!!%#QCTE'80"#!!!@d
        +!!!P,#8i%)3`%)3!-!!CcFf`b,QJ!!J!!$33I!!)d!!!*3!P)r5X%)JVp+`!%#Q0
        +QEf`0"#)!!@m!!!P%#8Ip+J[p+J!H-!!0Fh0XCQpXC'9bF'&dD!!0Fh0X4QpXC'9
        +b8'&dD!Ep,3!!!J3@!!)%)`3N$33M!!0*!!)*9JQ!r5Rp+!3P#[dT!"JZBfpbC@0
        +bC@`U+LSU!!!!!!!!N!!!ER9XE!(p+!!!"J3P!!2p*`3Q"#F+r5F!"!TVEf0X$33
        +Q!!&Y!!!*@JPGr5B+r5B!"!TKE'PK"J3R!!2p*33S"#N+r58!"!TTER0S$33S!!)
        +d!!!*B!PSr53%+JVp*!!%#Q0QEf`0"#S!!@m!!!PN#@Ip)`[p)`!d-!!BEh"PER0
        +cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'"#N
        +!!rdL"#[p)3Vp)J!%#R4[)#!0"#X!!Qi!!!PV#AS%,!3Y$33X!!)d!!!*F`Pkr5!
        +%,JVp)!!%#QCTE'80"#i!!@d!!!Pf#AN%,``%,`!0!!GcFf`b-bjS!!)!!!d%,3!
        +#0!!!#@X*FrdI"$!+r4m!"!TMCQpX$33`!!&[!!!*E`Pbr4i,r4i!(M!!$A0cE'C
        +[E'4PFR"KG'J!$A0cE%C[E'4PFP"KG'J'r5%!!!)%*!!#"$%%-Jd%-3!$53!##B%
        +*UrdGr4`%-`Vp(3!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r4`!!!B%-`!
        +$r4X%0!3e#[dE!!3+DfpME!d%0!!"E3!!#B8*L2dD#[dD!!3+B@aTB3B%03!$r4N
        +%0J3h#[dC!!3+D@jcD!d%0J!#0!!!#BX*NrdB"$J+r4J!"!TMCQpX$33i!!&[!!!
        +*M`Q5r4F,r4F!0$!!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%P
        +ZBfaeC'9'EfaNCA*3BA4S"J3h!!2p&J3jr48+r4B!"!TdEb!J$33j!!*Z!!!*PJQ
        +P"$S%1`d%1J!#0!!!#Ci*TId8"$`+r43!"!TQD@aP$33m!!&Y!!!*S3QN"$d-"$d
        +!$!!'Fh0X-bjS!!)!!!d%1`!#0!!!#CB*R[d6"$i+r4-!"!TMCQpX$33q!!&[!!!
        +*QJQGr4),r4)!(M!!$A0cE'C[E'4PFR"KG'J!$A0cE%C[E'4PFP"KG'J'r48!!!)
        +%-J!#"$m%3!d%2`!$53!##D`*e[d4r4!%33Vp%3!B,Q0[FQ9MFQ9X+LSU+J!!!!!
        +!!*!!!'jeE'`"r4!!!!B%33!$r3m%3J4$#[d2!!3+DfpME!d%3J!"E3!!#E!*Xrd
        +1#[d1!!3+B@aTB3B%3`!$r3d%4!4&#[d0!!3+D@jcD!d%4!!#0!!!#EB*[[d-"%B
        ++r3`!"!TMCQpX$34'!!&[!!!*ZJQpr3X,r3X!0$!!''p`C@jcFfaTEQ0XG@4PCQp
        +XC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*3BA4S"J4&!!2p#J4(r3N+r3S
        +!"!TdEb!J$34(!!*Z!!!*`3R3"%J%53d%5!!#0!!!#FN*d2d)"%S+r3J!"!TQD@a
        +P$34+!!&Y!!!*c!R2"%X-"%X!$!!'G'ac-5jS!!)!!!d%53!#0!!!#F%*bId("%`
        ++r3F!"!TMCQpX$34-!!&[!!!*a3R)r3B,r3B!(M!!$A0cE'C[E'4PFR"KG'J!$A0
        +cE%C[E'4PFP"KG'J'r3N!!!)%3!!#"%d%6Jd%63!#E!!##GF*erd&r33"r38!!!(
        +p"!!!!J41!!)%6`43$342!!0*!!)*e`S"r32p!J44#[d$!"JZBfpbC@0bC@`U+LS
        +U!!!!!!!!N!!!ER9XE!(p!J!!"J44!!2p!345"&-+r3%!"!TVEf0X$345!!&Y!!!
        +*f`RHr3!+r3!!"!TKE'PK"J46!!2mr`48"&8+r2m!"!TTER0S$348!!)d!!!*i3R
        +Tr2i%9JVmrJ!%#Q0QEf`0"&B!!@m!!!RP#HMmr3[mr3!d-!!BEh"PER0cE'PZBfa
        +eC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9NC8C[E'4PFP"KG'J'"&8!!rcm"&I
        +mq`Vmr!!%#R4[)#!0"&F!!Qi!!!RX#IX%@!4C$34B!!)d!!!*p!Rlr2S%@JVmqJ!
        +%#QCTE'80"&S!!@d!!!Rh#IS%@``%@`!1!!KMFRP`G'mZD!!#!!!0"&N!!M3!!!R
        +X#I6mq34F#[cj!!3+BfC[E!d%A!!"E`!!#I!*mrci#rci!#3`!""MFRP`G'pQEfa
        +NCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S"[cl!!!#"&!!!J4G"&i0"&d!!Q`!!JS
        +##J,mprcf!Ich!!!"r2B!!!)%AJ!#"&m%B!d%A`!$53!##J)+,2cer23%B3Vmp3!
        +B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r23!!!B%B3!$r2-%BJ4M#[cc!!3
        ++DfpME!d%BJ!"E3!!#JB+#Icb#[cb!!3+B@aTB3B%B`!$r2%%C!4P#[ca!!3+D@j
        +cD!d%C!!#0!!!#J`+&2c`"'B+r2!!"!TMCQpX$34Q!!&[!!!+%!S6r1m,r1m!0$!
        +!''p`C@jcFfaTEQ0XG@4PCQpXC'9bF'&dD!!BEh"PEP066%PZBfaeC'9'EfaNCA*
        +3BA4S"J4P!!2mlJ4Rr1d+r1i!"!TdEb!J$34R!!*Z!!!+&`SQ"'J%D3d%D!!#0!!
        +!#Km+*[cX"'S+r1`!"!TQD@aP$34U!!&Y!!!+)JSP"'X-"'X!%!!+Eh"PER0cE(B
        +ZD!!#!!!0"'N!!M3!!!SA#Krmk`4X#[cV!!3+BfC[E!d%E!!"E`!!#KX+([cU#rc
        +U!#3`!""MFRP`G'pQEfaNCA*`BA4S!""MFRP`G'p'EfaNCA*3BA4S"[cY!!!#"'!
        +!!J4Y"'i0"'d!!dN!!JSY#PImkIcS"'m+r1N!'#jMEh*PBh*PE#SU+LS!!!!!!!#
        +3!!"ZG@aX!IcS!!!'"'m!!rcR"(!%F3Vmj`!%#QY[Bf`0"(!!!@d!!!Sa#M6mjJV
        +mjJ!%#Q&XD@%'"(%!!rcP"()%F`Vmj3!%#QPZFfJ0"()!!M3!!!Sh#Mrmj!4d#[c
        +N!!3+BfC[E!d%G!!"E`!!#MX+2[cM#rcM!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4
        +PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B%F`!$r1)%GIcK#[cL!!3
        ++G'mJ)!d%G3!#EJ!!#N)+834f"(F0"(B!!M3!!!T+#P(mi!4i#[cJ!!3+CQPXC3d
        +%H!!"E3!!#Nd+8!4j$!4j!!i!#(4YC'PQCLjS!!)!!!d%G`!#0!!!#N)+5[cI"(S
        ++r0m!"!TMCQpX$34k!!&[!!!+4JT*r0i,r0i!*$!!%'0bHA"dEfC[E'4PFR"KG'J
        +!%'0bHA"dEdC[E'4PFP"KG'J'r1%!!!)%EJ!#"(X%I!d%H`!#E!!##PJ+@2cGr0`
        +"r0d!!!(mh!!!!J4m!!)%I34q$34p!!*X!!)+@!TBr0[mfJ(mf`!!!IcD!!!#"(i
        +!!J4r")!0"(m!!dN!!JTB#S,mfIcB")%+r0N!'#jMEh*PBh*PE#SU+LS!!!!!!!#
        +3!!"ZG@aX!IcB!!!'")%!!rcA"))%J`Vme`!%#QY[Bf`0"))!!@d!!!TF#PrmeJV
        +meJ!%#Q&XD@%'")-!!rc9")3%K3Vme3!%#QPZFfJ0")3!!M3!!!TL#QVme!5'#[c
        +8!!3+BfC[E!d%KJ!"E`!!#QB+DIc6#rc6!$3`!"K[F'9ZFh0XD@jME(9NC@C[E'4
        +PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD!B%K3!$r0)%Krc4#[c5!!3
        ++G'mJ)!d%K`!#EJ!!#Qd+I!5)")N0")J!!M3!!!Te#Rcmd!5+#[c3!!3+CQPXC3d
        +%LJ!"E3!!#RJ+H`5,$!5,!!`!"Q9IEh-ZD!!#!!!0")N!!M3!!!TY#RAmc`5-#[c
        +2!!3+BfC[E!d%M!!"E`!!#R%+G2c1#rc1!#B`!"&[F'9ZFh0XCQpXC'9bF'&dD!!
        +4Eh"PER0cE%C[E'4PFP"KG'J'r0%!!!)%J!!#")d%MJd%M3!$53!##S-+VIc0r-`
        +%M`Vmc3!B,Q0[FQ9MFQ9X+LSU+J!!!!!!!*!!!'jeE'`"r-`!!!B%M`!$r-X%N!!
        +%N3Vmb`!%#QY[Bf`0"*!!!!&Y!!!+K`U+r-S+r-S!"!TKE'PK"J54!!2mb355"*-
        ++r-N!"!TTER0S$355!!)d!!!+M3U9r-J%P!Vmb!!%#Q0QEf`0"*3!!@m!!!U4#T6
        +ma`[ma`!d-!!BEh"PER0cE'PZBfaeC'9QEfaNCA*`BA4S!"K[F'9Z8e0-5@jME(9
        +NC8C[E'4PFP"KG'J'"*-!!rc'"*Ama3VmaJ!%#R4[)#!0"*8!!Qi!!!UB#UF%PJ5
        +A$35@!!)d!!!+S!URr-3%Q!Vma!!%#QCTE'80"*J!!@d!!!UM#UB%Q3`%Q3!0!!G
        +PAfpc-LjS!!)!!!d%P`!#0!!!#TJ+S2c$"*S+r--!"!TMCQpX$35D!!&[!!!+R!U
        +Ir-),r-)!*M!!%@p`C@jcFfaQEfaNCA*`BA4S!"&[F'9ZFh0X4QpXC'9b8'&dD!E
        +ma3!!!J51!!)%Qrc"$35E!!*X!!)+VJUZr-$m[`(m`!!!!Ibr!!!#r-%!!!d!#3!
        +"E3!!!!!!!3!I!Irq!!!#!!B!!J5F"*d0"*`!!Q`!!J!!!!$m[[bp!Ibq!!!"r,d
        +!!!)%R3!#"*i%R`d%RJ!#E!!##V%+b!5Jr,`0"+!!!dN!!JUa#XMmZ`5K"+)+r,X
        +!'#jcHA0[C'a[Cf&cDh)!!!!!!!!!!&4&@&30"+%!!@d!!!Ua#V3%S``%S`!'!!!
        +!!J!!"J5L!!2mZJ5N"+8+r,S!"!TLG'jc$35N!!&+!!!+Y`Um"+B#"+B!!J5Rr,N
        +0"+F!!@d!!!Uh#VS%U!`%U!!+!!4%EfjP!!)!!!,mZ3!!"J5P!!2mZ!5Tr,F+r,J
        +!"!TRDACe$35T!!&Y!!!+[`V#r,B$r,B!"3EmY`!!!Ibm!!!#"*m!!J5Ur,80"+S
        +!!Q`!!J!!!!$mY2bc!Ibd!!!"r,-!!!,mY3!!$J!#!!!2%!!$!",mXJ5V"+`%V35
        +Z"+m%X!5a",)%X`5d",8%YJ5hr,(mX2b[r+i"r,)!!"!%U`!3r+hmV2bVr+VmUIb
        +Sr+ImT[bPr+6mSrbLr+(mS2bIr*i+r+d!'#jKCACdEf&`F'jeE'`!!)!!!!#3!!!
        +U+LSU#rbX!")`!!GdD'9`BA4S!!GdD'93BA4S#rbV!"``!!adD'9[E'4NC@aTEA-
        +!$(4SC8pXC%4PE'PYF`[mUJ!J-!!1G'KPF(*[DQ9MG("KG'J!$R4SC9"bEfTPBh4
        +3BA4S#rbT!"B`!!PdD'9YCA"KG'J!#A4SC8eP8'&dD![mU!!Q-!!4D@jME(9NC@C
        +[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S#rbR!$3`!"K[F'9ZFh0XD@jME(9
        +NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&dD![mTJ!N-!!3Bh*
        +jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD![mT3!H-!!0Fh0XCQpXC'9
        +bF'&dD!!0Fh0X4QpXC'9b8'&dD![mT!!Q-!!4Eh"PER0cE'C[E'4PFR"KG'J!%@p
        +`C@jcFfa'EfaNCA*3BA4S#rbM!#i`!"9dD'9ZCAGQEfaNCA*bC@CPFQ9ZBf8!&A4
        +SC8jPGdC[E'4PFP*PCQ9bC@jMC3[mSJ!8-!!)G'9YF("KG'J!#(4PEA"3BA4S!Ib
        +K!!!"r+!!!!(mR`!!!IbH!!!1"+`!"a$mR35ir*cmQ`5j",VmQJVmR3!B,Q&PGR4
        +[BA"`ER9XE!!!J!!!!*!!!#SU+LS0",J!!@X!!!!!#XJ%Z`)%Z`!#!!8%[!)%[!!
        +#"*lmQ3,mQ3!!!IbF!!!#r*X!!"!%Z3!!%!5k!)B!(rbBr*ImP[b9r*6mNrb5!#c
        +mNIb3!2b2r)lmMIb-!%rmL`"D!&[mLJ"Nr)N!EIb)r)ImKJ#2r)AmK2b$r),mJIb
        +!r(rmI[apr(cmH`#Tr(VmHIair(F![Iaf!-ImG3$8!1)!l!$j!3-"%!%D!5F"-3%
        +q!8J"93&I!@`"GJ'$!Bd"QJ'N!E%"Z`()!G)"h`(T!IB#!!)0!KF#*!)Z!MX#43*
        +5!P`#D3*c!S!#LJ+A!U%#VJ+m!XB#d`,G!ZS#p!-"!`X$'!-L!bm$130'!e!$A30
        +R!h3$IJ1,!jN$S`1`!lS$a`24!pi$l!2f"!-%%`3K"#m%234,"&X%D`4j")X%Q35
        +Mr(3%U2acr(,mF3VmQ!!%#Q0[BQS+r*F!'#jPBA*cCQCNFQ&XDA-!!!!!!!!J!'&
        +QC()+r*B!"!TMG(Kd#rb9!")`!!GdD'9`BA4S!!GdD'93BA4S#[b8!!3+BA0MFJV
        +mN`!%#R4iC'`,r*)!($!!$(4SC@pXC'4PE'PYF`!-G'KP6faN4'9XD@ec#[b4!!3
        ++BfPdE32mN!$rr3[mM`!J-!!1G'KPF(*[DQ9MG("KG'J!$R4SC9"bEfTPBh43BA4
        +S!rb1rri+r)d!"!T849K8#rb-!"B`!!PdD'9YCA"KG'J!#A4SC8eP8'&dD![mL`!
        +Q-!!4D@jME(9NC@C[E'4PFR"KG'J!%@PZBfaeC'9'EfaNCA*3BA4S#rb+!$3`!"K
        +[F'9ZFh0XD@jME(9NC@C[E'4PFR"KG'J!''p`C@j68da*EQ0XG@4P4QpXC'9b8'&
        +dD![mL3!N-!!3Bh*jF(4[CQpXC'9bF'&dD!!3Bh*jF(4[4QpXC'9b8'&dD![mL!!
        +H-!!0Fh0XCQpXC'9bF'&dD!!0Fh0X4QpXC'9b8'&dD![mK`!Q-!!4Eh"PER0cE'C
        +[E'4PFR"KG'J!%@p`C@jcFfa'EfaNCA*3BA4S#[b'!!3+BfC[E!VmK3!B,QeTFf0
        +cE'0d+LSU+J!!!!!!!*!!!#SU+LS+r)3!"!TcC@aP#[b$!"JZBfpbC@4PE'mU+LS
        +U!!!!!!!!N!!!+LSU+J(mJJ!!![b"!!!+r)!!"!TVEf0X#[ar!!3+D@jcD!2mIJ!
        +%#[ap!"JZBfpbC@0bC@`U+LSU!!!!!!!!N!!!ER9XE!VmI!!%#R*cE(3,r(X!,M!
        +!&A4SC@jPGfC[E'4PFR*PCQ9bC@jMC3!9G'KP6Q9h4QpXC'9b8Q9QCA*PEQ0P#[a
        +k!!3+F'jKE3VmH3!%#Q&XD@%+r(J!"!TdEb!J#[ah!!3+CQPXC32mGJ!'#rae!"3
        +`!!KdC@e`F'&dD!!)G'9YF&"KG'J+r(3!"!TLG'jc#[ac!!3+CfPfG32mFJ!&#[a
        +a!"JZFhPcEf4XEfGKFfYb!!!!!!!!!!"849K8%IbD#XRJ%JUYi1%TDJ`!!LrM*N9
        +4e%r&jLa&edrSaHBX4Nr%@qPF@eTVA&VU-NAE6m4Ek9aE@QYF@Z`bl5C&hNr,lbA
        +Y*N9J!""2bf%!%59K!")Pl5C&B!!66mYK!"3Pl5C&B!!96mYK!"BPl5C&B!!A6m[
        +Y*N9J!"K2amAQ,%C2&!!L+Q%!'9m!%#pK!"PK!"S[DJ`!'dmUB3!F,'S-!"eA!!K
        +B!"i!(fK2+Q%!)'%!'@%!)5TK!"PI!"![B3!L$!!M6em!*%9J!#92A`!PDJ`!'dp
        +K!#BUB3!F,'%!*ba'6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"R1,f%!+Q%!+bp
        +K!#`-!#02A`!9B3!Y*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,Lp
        +K!#TK!#m[B3!X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3!
        +`,f%!,!`!)dpI!"9K!$%P4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!
        +Z,f%!+Q%!-LpK!#`-!#02A`!9B3!c*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!
        +T+Q%!'9m!,LpK!#TK!$3[B3!X$!!M6em!&@%!059&B!!Z6bTK!#"K!#KK!#%UB3!
        +CA`!6,f%!+5TK!"PI!#i[B3!UB3!f,f%!,!`!)dpI!"9K!$FP4@!!,NmUB3!JB3!
        +SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!1#pK!#`-!#02A`!9B3!j*89J!#j
        +2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!$S[B3!X$!!M6em!&@%
        +!1b9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3!m,f%!,!`
        +!)dpI!"9K!$dP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%
        +!2LpK!#`-!#02A`!9B3!r*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m
        +!,LpK!#TK!%![B3!X$!!M6em!&@%!359&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%
        +!+5TK!"PI!#i[B3!UB3"#,f%!,!`!)dpI!"9K!%-P4@!!,NmUB3!JB3!SB3!K+Q%
        +!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!4#pK!#`-!#02A`!9B3"&*89J!#j2+Q%!)'%
        +!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!%B[B3!X$!!M6em!&@%!4b9&B!!
        +Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"),f%!,!`!)dpI!"9
        +K!%NP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!5LpK!#`
        +-!#02A`!9B3",*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#T
        +K!%`[B3!X$!!M6em!&@%!659&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"P
        +I!#i[B3!UB3"1,f%!,!`!)dpI!"9K!%mP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bp
        +K!#NUB3!CA`!Z,f%!+Q%!8#pK!#`-!#02A`!9B3"4*89J!#j2+Q%!)'%!+'%!)5T
        +K!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!&)[B3!X$!!M6em!&@%!8b9&B!!Z6bTK!#"
        +K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"8,f%!,!`!)dpI!"9K!&8P4@!
        +!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!9LpK!#`-!#02A`!
        +9B3"A*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!&J[B3!
        +X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"C,f%!,!`!)dp
        +I!"9K!&SP4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!@bp
        +K!#`-!#02A`!9B3"F*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,Lp
        +K!#TK!&d[B3!X$!!M6em!&@%!AL9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5T
        +K!"PI!#i[B3!UB3"I,f%!,!`!)dpI!"9K!'!P4@!!,NmUB3!JB3!SB3!K+Q%!'9m
        +!%bpK!#NUB3!CA`!Z,f%!+Q%!B5pK!#`-!#02A`!9B3"L*89J!#j2+Q%!)'%!+'%
        +!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!'-[B3!X$!!M6em!&@%!C#9&B!!Z6bT
        +K!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"P,f%!,!`!)dpI!"9K!'B
        +P4@!!,NmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!CbpK!#`-!#0
        +2A`!9B3"S*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!,LpK!#TK!'N
        +[B3!X$!!M6em!&@%!DL9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!#i
        +[B3!UB3"V,f%!,!`!)dmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%
        +!E#pK!#`-!#02A`!9B3"Y*89J!#j2+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m
        +!,LpK!#TK!'i[B3!X$!!M6em!&@%!Eb9&B!!Z6bTK!#"K!#KK!#%UB3!CA`!6,f%
        +!+5TK!"PI!#i[B3!UB3"`,f%!,!`!)dpI!"9K!(%P4@!!,NmUB3!JB3!SB3!K+Q%
        +!'9m!%bpK!#NUB3!CA`!Z,f%!+Q%!FLpK!#`-!#02+Q%!)'%!+'%!)5TK!"PI!"-
        +[B3!T+Q%!'9m!,LpK!#TK!(-[B3!X$!!M6em!&@%!G#9&B!!Z6bTK!#"K!#KK!#%
        +UB3!CA`!6,f%!+5TK!"PI!#i[B3!UB3"e,f%!,!`!)dmUB3!JB3!SB3!K+Q%!'9m
        +!%bpK!#NUB3!CA`!A,f%!+Q%!GLpK!#`-!#02+Q%!)'%!+'%!)5TK!"PI!"-[B3!
        +T+Q%!'9m!&bpK!#TK!(F[B3!X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"P
        +I!"F[B3!UB3"i,f%!,!`!)dmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!A,f%
        +!+Q%!H5pK!#`-!#02+Q%!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!&bpK!#TK!(S
        +[B3!X$!!M6bTK!#"K!#KK!#%UB3!CA`!6,f%!+5TK!"PI!"8[B3!UB3"l,f%!,!`
        +!)dmUB3!JB3!SB3!K+Q%!'9m!%bpK!#NUB3!CA`!9,f%!+Q%!I#pK!#`-!#02+Q%
        +!)'%!+'%!)5TK!"PI!"-[B3!T+Q%!'9m!&5pK!#TK!(d[B3!X$!!M6bTK!#"K!#K
        +K!#%UB3!CA`!6,f%!+5TK!"PI!"J[B3!UB3"q,f%!,!`!)dmUB3!JB3!SB3!K+Q%
        +!'9m!%bpK!#NUB3!CA`!B,f%!+Q%!IbpK!#`-!#028&92B3#!B3#"B3##DhCK!)0
        +K!)4K!#)-!)82$!5Y!&%!5deKBfPZG'pcD#")4$T%CA0VG'p`)%C[E'4PFMT*EQ0
        +[E@PZCcT[F'9ZFh0X,90139!Y-6Nj16%b-6%k6@&M6e-kE@YXD@jVFbjKF`!#!!!
        +1"+i!!J6mF!5p!ra`!!%1",d!!3!%[J`%[J!'!!!!!J!!$J5[!!)%r'm%[`2mE`!
        +%$J5r!!3!"-!%`36#"---"-!!%J!-6@&MD@jdEh0S)%K%!!)!!!`%`3!8!!j%CA0
        +VG'p`)%C[E'4PFJ!#!!!-"-)!$J!)5@jMEfeTEQF!!J!!$!6$!"X!&@p`C@jcFf`
        +Y8dj"8#da16Nj-6)a-3!#!!!-",!!4J"!6@&MD@jdEh0S)%K%1N4PFfYdEh!J4Qp
        +XC'9b1NPZBfpYD@jR1Qp`C@jcFf`Y8dj"8#da16Nj-6)a-6T0B@028`!#!!!-",%
        +!5!"#6@&MD@jdEh0S)%K%1N4PFfYdEh!J4QpXC'9b1NPZBfpYD@jR1Qp`C@jcFf`
        +Y8dj"8#da16Nj-6)a-6TTEQ0XG@4P!!)!!!`%XJ"3!%T0B@0TER4[FfJJ5%3k4'9
        +cDh4[F#"'EfaNCA)k5@jMEfeTEQFkEh"PER0cE#e66N&3,6%j16Na-M%a1QPZBfa
        +eC'8kEh"PER0cE!!#!!!-",-!4`""6@&MD@jdEh0S)%K%1N4PFfYdEh!J4QpXC'9
        +b1NPZBfpYD@jR1Qp`C@jcFf`Y8dj"8#da16Nj-6)a-6TMFRP`G'm!!J!!$!5d!%3
        +!2NeKBfPZG'pcD#")4$T%CA0VG'p`)%C[E'4PFMT*EQ0[E@PZCcT[F'9ZFh0X,90
        +139!Y-6Nj16%b-6%kFh0X!!)!!!`%Y3"!!$T0B@0TER4[FfJJ5%3k4'9cDh4[F#"
        +'EfaNCA)k5@jMEfeTEQFkEh"PER0cE#e66N&3,6%j16Na-M%a!!)!!!i%YJ!"&!6
        +%$J6%!!-B"-AmEJ6'$J6&!!-B"-ImE36)$J6(!!-B"-RmE!6+$J6*!!-B!"rmD`6
        +,#[aV!!3+BfC[E!`%b`!1!!K*EQ0[E@PZC`!#!!!+r'`!"!TMCQpX$!6+!"X!&@p
        +`C@jcFf`Y8dj"8#da16Nj-6)a-3!#!!!+r'd!"!TMCQpX$!6)!!d!"fPZBfaeC'8
        +!!J!!#[aZ!!3+BfC[E!`%aJ!9!!peER4TG'aPC#"QEfaNCA)!!J!!$!5h!%i!5%e
        +KBfPZG'pcD#")4$T%CA0VG'p`)%C[E'4PFMT*EQ0[E@PZCcT[F'9ZFh0X,90139!
        +Y-6Nj16%b-6%kBh*jF(4[1RJe-$Pf-`!#!!!"r,%!!!(mX!!!!Ib[!!!"r+i!!'&
        +cBh)!!3!-qYlHV3!!!3!!!*G#!!#@3J!!!AB!!$-8-0J!!!!F!AB!$h0MFhS!!!#
        +#6Np853!!!)jcBh"d!!!!QP4&@&3!!3#QFh4jE!!!!,j$6d4&!!%!bN*14%`!!!$
        +LBA"XG!!!!1j'8N9'!!!!qNP$6L-!!!%'D@0X0!!!!4*TBh-M!!!"(QPMFc3!!!%
        +UD'CNFJ!!!6C659T&!!!"3PG3Eh-!!!&1!!$rr`!!!!!!!!!!!)$rre!!!"i!!!!
        +!!)$rr`!!"cJ#DH#m"'Mrr`!!!*S!!!!!%iRrr`!!"Pi!!!!!"'Mrr`!!!53!!!!
        +!!!$rrb!!!9)!!!!!!!(rra3!!@i#DG`%!)$rr`!!!Pi#DH"X!!$rr`!!!Ri!!!!
        +!!)$rr`!!!S-#DH"d!*Err`!!!Si!!!!!!*Err`!!!j)!!!!!!*Err`!!"CB#DH%
        +i!*Err`!!"GS#DH%dkF$rr`!!"[`!!!!!rrrrr`!!"a)!!!!!!)$rr`!!"b!!!!!
        +!*4S:
        diff --git a/vendor/openssl/openssl/MacOS/opensslconf.h b/vendor/openssl/openssl/MacOS/opensslconf.h
        new file mode 100644
        index 000000000..ad557cc06
        --- /dev/null
        +++ b/vendor/openssl/openssl/MacOS/opensslconf.h
        @@ -0,0 +1,116 @@
        +/* MacOS/opensslconf.h */
        +
        +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
        +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
        +#define OPENSSLDIR "/usr/local/ssl"
        +#endif
        +#endif
        +
        +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
        +#define IDEA_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_MD2_H) && !defined(MD2_INT)
        +#define MD2_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_RC2_H) && !defined(RC2_INT)
        +/* I need to put in a mod for the alpha - eay */
        +#define RC2_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_RC4_H)
        +#if !defined(RC4_INT)
        +/* using int types make the structure larger but make the code faster
        + * on most boxes I have tested - up to %20 faster. */
        +/*
        + * I don't know what does "most" mean, but declaring "int" is a must on:
        + * - Intel P6 because partial register stalls are very expensive;
        + * - elder Alpha because it lacks byte load/store instructions;
        + */
        +#define RC4_INT unsigned char
        +#endif
        +#if !defined(RC4_CHUNK)
        +/*
        + * This enables code handling data aligned at natural CPU word
        + * boundary. See crypto/rc4/rc4_enc.c for further details.
        + */
        +#define RC4_CHUNK unsigned long
        +#endif
        +#endif
        +
        +#if defined(HEADER_DES_H) && !defined(DES_LONG)
        +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
        + * %20 speed up (longs are 8 bytes, int's are 4). */
        +#ifndef DES_LONG
        +#define DES_LONG unsigned long
        +#endif
        +#endif
        +
        +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
        +#define CONFIG_HEADER_BN_H
        +#if __option(longlong)
        +#  define BN_LLONG
        +#else
        +#  undef BN_LLONG
        +#endif
        +
        +/* Should we define BN_DIV2W here? */
        +
        +/* Only one for the following should be defined */
        +/* The prime number generation stuff may not work when
        + * EIGHT_BIT but I don't care since I've only used this mode
        + * for debuging the bignum libraries */
        +#undef SIXTY_FOUR_BIT_LONG
        +#undef SIXTY_FOUR_BIT
        +#define THIRTY_TWO_BIT
        +#undef SIXTEEN_BIT
        +#undef EIGHT_BIT
        +#endif
        +
        +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
        +#define CONFIG_HEADER_RC4_LOCL_H
        +/* if this is defined data[i] is used instead of *data, this is a %20
        + * speedup on x86 */
        +#undef RC4_INDEX
        +#endif
        +
        +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
        +#define CONFIG_HEADER_BF_LOCL_H
        +#define BF_PTR
        +#endif /* HEADER_BF_LOCL_H */
        +
        +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
        +#define CONFIG_HEADER_DES_LOCL_H
        +/* the following is tweaked from a config script, that is why it is a
        + * protected undef/define */
        +#ifndef DES_PTR
        +#define DES_PTR
        +#endif
        +
        +/* This helps C compiler generate the correct code for multiple functional
        + * units.  It reduces register dependancies at the expense of 2 more
        + * registers */
        +#ifndef DES_RISC1
        +#define DES_RISC1
        +#endif
        +
        +#ifndef DES_RISC2
        +#undef DES_RISC2
        +#endif
        +
        +#if defined(DES_RISC1) && defined(DES_RISC2)
        +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
        +#endif
        +
        +/* Unroll the inner loop, this sometimes helps, sometimes hinders.
        + * Very mucy CPU dependant */
        +#ifndef DES_UNROLL
        +#define DES_UNROLL
        +#endif
        +
        +#endif /* HEADER_DES_LOCL_H */
        +
        +#ifndef __POWERPC__
        +#define MD32_XARRAY
        +#endif
        diff --git a/vendor/openssl/openssl/Makefile b/vendor/openssl/openssl/Makefile
        new file mode 100644
        index 000000000..54e354161
        --- /dev/null
        +++ b/vendor/openssl/openssl/Makefile
        @@ -0,0 +1,685 @@
        +### Generated automatically from Makefile.org by Configure.
        +
        +##
        +## Makefile for OpenSSL
        +##
        +
        +VERSION=1.0.1e
        +MAJOR=1
        +MINOR=0.1
        +SHLIB_VERSION_NUMBER=1.0.0
        +SHLIB_VERSION_HISTORY=
        +SHLIB_MAJOR=1
        +SHLIB_MINOR=0.0
        +SHLIB_EXT=
        +PLATFORM=dist
        +OPTIONS= no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-store no-zlib no-zlib-dynamic static-engine
        +CONFIGURE_ARGS=dist
        +SHLIB_TARGET=
        +
        +# HERE indicates where this Makefile lives.  This can be used to indicate
        +# where sub-Makefiles are expected to be.  Currently has very limited usage,
        +# and should probably not be bothered with at all.
        +HERE=.
        +
        +# INSTALL_PREFIX is for package builders so that they can configure
        +# for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/.
        +# Normally it is left empty.
        +INSTALL_PREFIX=
        +INSTALLTOP=/usr/local/ssl
        +
        +# Do not edit this manually. Use Configure --openssldir=DIR do change this!
        +OPENSSLDIR=/usr/local/ssl
        +
        +# NO_IDEA - Define to build without the IDEA algorithm
        +# NO_RC4  - Define to build without the RC4 algorithm
        +# NO_RC2  - Define to build without the RC2 algorithm
        +# THREADS - Define when building with threads, you will probably also need any
        +#           system defines as well, i.e. _REENTERANT for Solaris 2.[34]
        +# TERMIO  - Define the termio terminal subsystem, needed if sgtty is missing.
        +# TERMIOS - Define the termios terminal subsystem, Silicon Graphics.
        +# LONGCRYPT - Define to use HPUX 10.x's long password modification to crypt(3).
        +# DEVRANDOM - Give this the value of the 'random device' if your OS supports
        +#           one.  32 bytes will be read from this when the random
        +#           number generator is initalised.
        +# SSL_FORBID_ENULL - define if you want the server to be not able to use the
        +#           NULL encryption ciphers.
        +#
        +# LOCK_DEBUG - turns on lots of lock debug output :-)
        +# REF_CHECK - turn on some xyz_free() assertions.
        +# REF_PRINT - prints some stuff on structure free.
        +# CRYPTO_MDEBUG - turns on my 'memory leak' detecting stuff
        +# MFUNC - Make all Malloc/Free/Realloc calls call
        +#       CRYPTO_malloc/CRYPTO_free/CRYPTO_realloc which can be setup to
        +#       call application defined callbacks via CRYPTO_set_mem_functions()
        +# MD5_ASM needs to be defined to use the x86 assembler for MD5
        +# SHA1_ASM needs to be defined to use the x86 assembler for SHA1
        +# RMD160_ASM needs to be defined to use the x86 assembler for RIPEMD160
        +# Do not define B_ENDIAN or L_ENDIAN if 'unsigned long' == 8.  It must
        +# equal 4.
        +# PKCS1_CHECK - pkcs1 tests.
        +
        +CC= cc
        +CFLAG= -O
        +DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE
        +PEX_LIBS= 
        +EX_LIBS= 
        +EXE_EXT= 
        +ARFLAGS= 
        +AR= ar $(ARFLAGS) r
        +RANLIB= /usr/bin/ranlib
        +NM= nm
        +PERL= /usr/bin/perl
        +TAR= tar
        +TARFLAGS= --no-recursion --record-size=10240
        +MAKEDEPPROG=makedepend
        +LIBDIR=lib
        +
        +# We let the C compiler driver to take care of .s files. This is done in
        +# order to be excused from maintaining a separate set of architecture
        +# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC
        +# gcc, then the driver will automatically translate it to -xarch=v8plus
        +# and pass it down to assembler.
        +AS=$(CC) -c
        +ASFLAG=$(CFLAG)
        +
        +# For x86 assembler: Set PROCESSOR to 386 if you want to support
        +# the 80386.
        +PROCESSOR= 
        +
        +# CPUID module collects small commonly used assembler snippets
        +CPUID_OBJ= mem_clr.o
        +BN_ASM= bn_asm.o
        +DES_ENC= des_enc.o fcrypt_b.o
        +AES_ENC= aes_core.o aes_cbc.o
        +BF_ENC= bf_enc.o
        +CAST_ENC= c_enc.o
        +RC4_ENC= rc4_enc.o rc4_skey.o
        +RC5_ENC= rc5_enc.o
        +MD5_ASM_OBJ= 
        +SHA1_ASM_OBJ= 
        +RMD160_ASM_OBJ= 
        +WP_ASM_OBJ= wp_block.o
        +CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o
        +MODES_ASM_OBJ= 
        +ENGINES_ASM_OBJ= 
        +PERLASM_SCHEME= 
        +
        +# KRB5 stuff
        +KRB5_INCLUDES=
        +LIBKRB5=
        +
        +# Zlib stuff
        +ZLIB_INCLUDE=
        +LIBZLIB=
        +
        +# TOP level FIPS install directory.
        +FIPSDIR=/usr/local/ssl/fips-2.0
        +
        +# This is the location of fipscanister.o and friends.
        +# The FIPS module build will place it $(INSTALLTOP)/lib
        +# but since $(INSTALLTOP) can only take the default value
        +# when the module is built it will be in /usr/local/ssl/lib
        +# $(INSTALLTOP) for this build may be different so hard
        +# code the path.
        +
        +FIPSLIBDIR=
        +
        +# The location of the library which contains fipscanister.o
        +# normally it will be libcrypto unless fipsdso is set in which
        +# case it will be libfips. If not compiling in FIPS mode at all
        +# this is empty making it a useful test for a FIPS compile.
        +
        +FIPSCANLIB=
        +
        +# Shared library base address. Currently only used on Windows.
        +#
        +
        +BASEADDR=0xFB00000
        +
        +DIRS=   crypto ssl engines apps test tools
        +ENGDIRS= ccgost
        +SHLIBDIRS= crypto ssl
        +
        +# dirs in crypto to build
        +SDIRS=  \
        +	objects \
        +	md4 md5 sha mdc2 hmac ripemd whrlpool \
        +	des aes rc2 rc4 idea bf cast camellia seed modes \
        +	bn ec rsa dsa ecdsa dh ecdh dso engine \
        +	buffer bio stack lhash rand err \
        +	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
        +	cms pqueue ts srp cmac
        +# keep in mind that the above list is adjusted by ./Configure
        +# according to no-xxx arguments...
        +
        +# tests to perform.  "alltests" is a special word indicating that all tests
        +# should be performed.
        +TESTS = alltests
        +
        +MAKEFILE= Makefile
        +
        +MANDIR=$(OPENSSLDIR)/man
        +MAN1=1
        +MAN3=3
        +MANSUFFIX=
        +HTMLSUFFIX=html
        +HTMLDIR=$(OPENSSLDIR)/html
        +SHELL=/bin/sh
        +
        +TOP=    .
        +ONEDIRS=out tmp
        +EDIRS=  times doc bugs util include certs ms shlib mt demos perl sf dep VMS
        +WDIRS=  windows
        +LIBS=   libcrypto.a libssl.a
        +SHARED_CRYPTO=libcrypto$(SHLIB_EXT)
        +SHARED_SSL=libssl$(SHLIB_EXT)
        +SHARED_LIBS=
        +SHARED_LIBS_LINK_EXTS=
        +SHARED_LDFLAGS=
        +
        +GENERAL=        Makefile
        +BASENAME=       openssl
        +NAME=           $(BASENAME)-$(VERSION)
        +TARFILE=        $(NAME).tar
        +WTARFILE=       $(NAME)-win.tar
        +EXHEADER=       e_os2.h
        +HEADER=         e_os.h
        +
        +all: Makefile build_all openssl.pc libssl.pc libcrypto.pc
        +
        +# as we stick to -e, CLEARENV ensures that local variables in lower
        +# Makefiles remain local and variable. $${VAR+VAR} is tribute to Korn
        +# shell, which [annoyingly enough] terminates unset with error if VAR
        +# is not present:-( TOP= && unset TOP is tribute to HP-UX /bin/sh,
        +# which terminates unset with error if no variable was present:-(
        +CLEARENV=	TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS}	\
        +		$${INCLUDE+INCLUDE} $${INCLUDES+INCLUDES}	\
        +		$${DIR+DIR} $${DIRS+DIRS} $${SRC+SRC}		\
        +		$${LIBSRC+LIBSRC} $${LIBOBJ+LIBOBJ} $${ALL+ALL}	\
        +		$${EXHEADER+EXHEADER} $${HEADER+HEADER}		\
        +		$${GENERAL+GENERAL} $${CFLAGS+CFLAGS}		\
        +		$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS}		\
        +		$${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS}	\
        +		$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS}	\
        +		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
        +
        +BUILDENV=	PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
        +		CC='$(CC)' CFLAG='$(CFLAG)' 			\
        +		AS='$(CC)' ASFLAG='$(CFLAG) -c'			\
        +		AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)'	\
        +		CROSS_COMPILE='$(CROSS_COMPILE)'	\
        +		PERL='$(PERL)' ENGDIRS='$(ENGDIRS)'		\
        +		SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)'	\
        +		INSTALL_PREFIX='$(INSTALL_PREFIX)'		\
        +		INSTALLTOP='$(INSTALLTOP)' OPENSSLDIR='$(OPENSSLDIR)'	\
        +		LIBDIR='$(LIBDIR)'				\
        +		MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD $(MAKEDEPPROG)' \
        +		DEPFLAG='-DOPENSSL_NO_DEPRECATED $(DEPFLAG)'	\
        +		MAKEDEPPROG='$(MAKEDEPPROG)'			\
        +		SHARED_LDFLAGS='$(SHARED_LDFLAGS)'		\
        +		KRB5_INCLUDES='$(KRB5_INCLUDES)' LIBKRB5='$(LIBKRB5)'	\
        +		ZLIB_INCLUDE='$(ZLIB_INCLUDE)' LIBZLIB='$(LIBZLIB)'	\
        +		EXE_EXT='$(EXE_EXT)' SHARED_LIBS='$(SHARED_LIBS)'	\
        +		SHLIB_EXT='$(SHLIB_EXT)' SHLIB_TARGET='$(SHLIB_TARGET)'	\
        +		PEX_LIBS='$(PEX_LIBS)' EX_LIBS='$(EX_LIBS)'	\
        +		CPUID_OBJ='$(CPUID_OBJ)'			\
        +		BN_ASM='$(BN_ASM)' DES_ENC='$(DES_ENC)' 	\
        +		AES_ENC='$(AES_ENC)' CMLL_ENC='$(CMLL_ENC)'	\
        +		BF_ENC='$(BF_ENC)' CAST_ENC='$(CAST_ENC)'	\
        +		RC4_ENC='$(RC4_ENC)' RC5_ENC='$(RC5_ENC)'	\
        +		SHA1_ASM_OBJ='$(SHA1_ASM_OBJ)'			\
        +		MD5_ASM_OBJ='$(MD5_ASM_OBJ)'			\
        +		RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)'		\
        +		WP_ASM_OBJ='$(WP_ASM_OBJ)'			\
        +		MODES_ASM_OBJ='$(MODES_ASM_OBJ)'		\
        +		ENGINES_ASM_OBJ='$(ENGINES_ASM_OBJ)'		\
        +		PERLASM_SCHEME='$(PERLASM_SCHEME)'		\
        +		FIPSLIBDIR='${FIPSLIBDIR}'			\
        +		FIPSDIR='${FIPSDIR}'				\
        +		FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}"	\
        +		THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
        +# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
        +# which in turn eliminates ambiguities in variable treatment with -e.
        +
        +# BUILD_CMD is a generic macro to build a given target in a given
        +# subdirectory.  The target must be given through the shell variable
        +# `target' and the subdirectory to build in must be given through `dir'.
        +# This macro shouldn't be used directly, use RECURSIVE_BUILD_CMD or
        +# BUILD_ONE_CMD instead.
        +#
        +# BUILD_ONE_CMD is a macro to build a given target in a given
        +# subdirectory if that subdirectory is part of $(DIRS).  It requires
        +# exactly the same shell variables as BUILD_CMD.
        +#
        +# RECURSIVE_BUILD_CMD is a macro to build a given target in all
        +# subdirectories defined in $(DIRS).  It requires that the target
        +# is given through the shell variable `target'.
        +BUILD_CMD=  if [ -d "$$dir" ]; then \
        +	    (	cd $$dir && echo "making $$target in $$dir..." && \
        +		$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. DIR=$$dir $$target \
        +	    ) || exit 1; \
        +	    fi
        +RECURSIVE_BUILD_CMD=for dir in $(DIRS); do $(BUILD_CMD); done
        +BUILD_ONE_CMD=\
        +	if expr " $(DIRS) " : ".* $$dir " >/dev/null 2>&1; then \
        +		$(BUILD_CMD); \
        +	fi
        +
        +reflect:
        +	@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
        +
        +sub_all: build_all
        +build_all: build_libs build_apps build_tests build_tools
        +
        +build_libs: build_crypto build_ssl build_engines
        +
        +build_crypto:
        +	@dir=crypto; target=all; $(BUILD_ONE_CMD)
        +build_ssl:
        +	@dir=ssl; target=all; $(BUILD_ONE_CMD)
        +build_engines:
        +	@dir=engines; target=all; $(BUILD_ONE_CMD)
        +build_apps:
        +	@dir=apps; target=all; $(BUILD_ONE_CMD)
        +build_tests:
        +	@dir=test; target=all; $(BUILD_ONE_CMD)
        +build_tools:
        +	@dir=tools; target=all; $(BUILD_ONE_CMD)
        +
        +all_testapps: build_libs build_testapps
        +build_testapps:
        +	@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
        +
        +fips_premain_dso$(EXE_EXT): libcrypto.a
        +	[ -z "$(FIPSCANLIB)" ] || $(CC) $(CFLAG) -Iinclude \
        +		-DFINGERPRINT_PREMAIN_DSO_LOAD -o $@  \
        +		$(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fipscanister.o \
        +		libcrypto.a $(EX_LIBS)
        +
        +libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT)
        +	@if [ "$(SHLIB_TARGET)" != "" ]; then \
        +		if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
        +			FIPSLD_LIBCRYPTO=libcrypto.a ; \
        +			FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; \
        +			export CC FIPSLD_CC FIPSLD_LIBCRYPTO; \
        +		fi; \
        +		$(MAKE) -e SHLIBDIRS=crypto build-shared; \
        +	else \
        +		echo "There's no support for shared libraries on this platform" >&2; \
        +		exit 1; \
        +	fi
        +
        +libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
        +	@if [ "$(SHLIB_TARGET)" != "" ]; then \
        +		$(MAKE) SHLIBDIRS=ssl SHLIBDEPS='-lcrypto' build-shared; \
        +	else \
        +		echo "There's no support for shared libraries on this platform" >&2; \
        +		exit 1; \
        +	fi
        +
        +clean-shared:
        +	@set -e; for i in $(SHLIBDIRS); do \
        +		if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \
        +			tmp="$(SHARED_LIBS_LINK_EXTS)"; \
        +			for j in $${tmp:-x}; do \
        +				( set -x; rm -f lib$$i$$j ); \
        +			done; \
        +		fi; \
        +		( set -x; rm -f lib$$i$(SHLIB_EXT) ); \
        +		if [ "$(PLATFORM)" = "Cygwin" ]; then \
        +			( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
        +		fi; \
        +	done
        +
        +link-shared:
        +	@ set -e; for i in $(SHLIBDIRS); do \
        +		$(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \
        +			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
        +			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
        +			symlink.$(SHLIB_TARGET); \
        +		libs="$$libs -l$$i"; \
        +	done
        +
        +build-shared: do_$(SHLIB_TARGET) link-shared
        +
        +do_$(SHLIB_TARGET):
        +	@ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \
        +		if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \
        +			libs="$(LIBKRB5) $$libs"; \
        +		fi; \
        +		$(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \
        +			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
        +			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
        +			LIBDEPS="$$libs $(EX_LIBS)" \
        +			link_a.$(SHLIB_TARGET); \
        +		libs="-l$$i $$libs"; \
        +	done
        +
        +libcrypto.pc: Makefile
        +	@ ( echo 'prefix=$(INSTALLTOP)'; \
        +	    echo 'exec_prefix=$${prefix}'; \
        +	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
        +	    echo 'includedir=$${prefix}/include'; \
        +	    echo ''; \
        +	    echo 'Name: OpenSSL-libcrypto'; \
        +	    echo 'Description: OpenSSL cryptography library'; \
        +	    echo 'Version: '$(VERSION); \
        +	    echo 'Requires: '; \
        +	    echo 'Libs: -L$${libdir} -lcrypto'; \
        +	    echo 'Libs.private: $(EX_LIBS)'; \
        +	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
        +
        +libssl.pc: Makefile
        +	@ ( echo 'prefix=$(INSTALLTOP)'; \
        +	    echo 'exec_prefix=$${prefix}'; \
        +	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
        +	    echo 'includedir=$${prefix}/include'; \
        +	    echo ''; \
        +	    echo 'Name: OpenSSL'; \
        +	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
        +	    echo 'Version: '$(VERSION); \
        +	    echo 'Requires: '; \
        +	    echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
        +	    echo 'Libs.private: $(EX_LIBS)'; \
        +	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
        +
        +openssl.pc: Makefile
        +	@ ( echo 'prefix=$(INSTALLTOP)'; \
        +	    echo 'exec_prefix=$${prefix}'; \
        +	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
        +	    echo 'includedir=$${prefix}/include'; \
        +	    echo ''; \
        +	    echo 'Name: OpenSSL'; \
        +	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
        +	    echo 'Version: '$(VERSION); \
        +	    echo 'Requires: '; \
        +	    echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
        +	    echo 'Libs.private: $(EX_LIBS)'; \
        +	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
        +
        +Makefile: Makefile.org Configure config
        +	@echo "Makefile is older than Makefile.org, Configure or config."
        +	@echo "Reconfigure the source tree (via './config' or 'perl Configure'), please."
        +	@false
        +
        +libclean:
        +	rm -f *.map *.so *.so.* *.dylib *.dll engines/*.so engines/*.dll engines/*.dylib *.a engines/*.a */lib */*/lib
        +
        +clean:	libclean
        +	rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
        +	@set -e; target=clean; $(RECURSIVE_BUILD_CMD)
        +	rm -f $(LIBS)
        +	rm -f openssl.pc libssl.pc libcrypto.pc
        +	rm -f speed.* .pure
        +	rm -f $(TARFILE)
        +	@set -e; for i in $(ONEDIRS) ;\
        +	do \
        +	rm -fr $$i/*; \
        +	done
        +
        +makefile.one: files
        +	$(PERL) util/mk1mf.pl >makefile.one; \
        +	sh util/do_ms.sh
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile > $(TOP)/MINFO
        +	@set -e; target=files; $(RECURSIVE_BUILD_CMD)
        +
        +links:
        +	@$(PERL) $(TOP)/util/mkdir-p.pl include/openssl
        +	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER)
        +	@set -e; target=links; $(RECURSIVE_BUILD_CMD)
        +
        +gentests:
        +	@(cd test && echo "generating dummy tests (if needed)..." && \
        +	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on generate );
        +
        +dclean:
        +	rm -rf *.bak include/openssl certs/.0
        +	@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
        +
        +rehash: rehash.time
        +rehash.time: certs apps
        +	@if [ -z "$(CROSS_COMPILE)" ]; then \
        +		(OPENSSL="`pwd`/util/opensslwrap.sh"; \
        +		[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
        +		OPENSSL_DEBUG_MEMORY=on; \
        +		export OPENSSL OPENSSL_DEBUG_MEMORY; \
        +		$(PERL) tools/c_rehash certs/demo) && \
        +		touch rehash.time; \
        +	else :; fi
        +
        +test:   tests
        +
        +tests: rehash
        +	@(cd test && echo "testing..." && \
        +	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on OPENSSL_CONF=../apps/openssl.cnf tests );
        +	OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh version -a
        +
        +report:
        +	@$(PERL) util/selftest.pl
        +
        +depend:
        +	@set -e; target=depend; $(RECURSIVE_BUILD_CMD)
        +
        +lint:
        +	@set -e; target=lint; $(RECURSIVE_BUILD_CMD)
        +
        +tags:
        +	rm -f TAGS
        +	find . -name '[^.]*.[ch]' | xargs etags -a
        +
        +errors:
        +	$(PERL) util/ck_errf.pl -strict */*.c */*/*.c
        +	$(PERL) util/mkerr.pl -recurse -write
        +	(cd engines; $(MAKE) PERL=$(PERL) errors)
        +
        +stacks:
        +	$(PERL) util/mkstack.pl -write
        +
        +util/libeay.num::
        +	$(PERL) util/mkdef.pl crypto update
        +
        +util/ssleay.num::
        +	$(PERL) util/mkdef.pl ssl update
        +
        +crypto/objects/obj_dat.h: crypto/objects/obj_dat.pl crypto/objects/obj_mac.h
        +	$(PERL) crypto/objects/obj_dat.pl crypto/objects/obj_mac.h crypto/objects/obj_dat.h
        +crypto/objects/obj_mac.h: crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num
        +	$(PERL) crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num crypto/objects/obj_mac.h
        +crypto/objects/obj_xref.h: crypto/objects/objxref.pl crypto/objects/obj_xref.txt crypto/objects/obj_mac.num
        +	$(PERL) crypto/objects/objxref.pl crypto/objects/obj_mac.num crypto/objects/obj_xref.txt >crypto/objects/obj_xref.h
        +
        +apps/openssl-vms.cnf: apps/openssl.cnf
        +	$(PERL) VMS/VMSify-conf.pl < apps/openssl.cnf > apps/openssl-vms.cnf
        +
        +crypto/bn/bn_prime.h: crypto/bn/bn_prime.pl
        +	$(PERL) crypto/bn/bn_prime.pl >crypto/bn/bn_prime.h
        +
        +
        +TABLE: Configure
        +	(echo 'Output of `Configure TABLE'"':"; \
        +	$(PERL) Configure TABLE) > TABLE
        +
        +update: errors stacks util/libeay.num util/ssleay.num crypto/objects/obj_dat.h crypto/objects/obj_xref.h apps/openssl-vms.cnf crypto/bn/bn_prime.h TABLE depend
        +
        +# Build distribution tar-file. As the list of files returned by "find" is
        +# pretty long, on several platforms a "too many arguments" error or similar
        +# would occur. Therefore the list of files is temporarily stored into a file
        +# and read directly, requiring GNU-Tar. Call "make TAR=gtar dist" if the normal
        +# tar does not support the --files-from option.
        +tar:
        +	find . -type d -print | xargs chmod 755
        +	find . -type f -print | xargs chmod a+r
        +	find . -type f -perm -0100 -print | xargs chmod a+x
        +	find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE | sort > ../$(TARFILE).list; \
        +	$(TAR) $(TARFLAGS) --files-from ../$(TARFILE).list -cvf - | \
        +	tardy --user_number=0  --user_name=openssl \
        +	      --group_number=0 --group_name=openssl \
        +	      --prefix=openssl-$(VERSION) - |\
        +	gzip --best >../$(TARFILE).gz; \
        +	rm -f ../$(TARFILE).list; \
        +	ls -l ../$(TARFILE).gz
        +
        +tar-snap:
        +	@$(TAR) $(TARFLAGS) -cvf - \
        +		`find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE \! -name '*.o' \! -name '*.a' \! -name '*.so' \! -name '*.so.*'  \! -name 'openssl' \! -name '*test' \! -name '.#*' \! -name '*~' | sort` |\
        +	tardy --user_number=0  --user_name=openssl \
        +	      --group_number=0 --group_name=openssl \
        +	      --prefix=openssl-$(VERSION) - > ../$(TARFILE);\
        +	ls -l ../$(TARFILE)
        +
        +dist:   
        +	$(PERL) Configure dist
        +	@$(MAKE) dist_pem_h
        +	@$(MAKE) SDIRS='$(SDIRS)' clean
        +	@$(MAKE) TAR='$(TAR)' TARFLAGS='$(TARFLAGS)' tar
        +
        +dist_pem_h:
        +	(cd crypto/pem; $(MAKE) -e $(BUILDENV) pem.h; $(MAKE) clean)
        +
        +install: all install_docs install_sw
        +
        +install_sw:
        +	@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
        +		$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
        +		$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
        +		$(INSTALL_PREFIX)$(OPENSSLDIR)/private
        +	@set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\
        +	do \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +	@set -e; target=install; $(RECURSIVE_BUILD_CMD)
        +	@set -e; liblist="$(LIBS)"; for i in $$liblist ;\
        +	do \
        +		if [ -f "$$i" ]; then \
        +		(       echo installing $$i; \
        +			cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +			$(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +			chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +			mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
        +		fi; \
        +	done;
        +	@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
        +		tmp="$(SHARED_LIBS)"; \
        +		for i in $${tmp:-x}; \
        +		do \
        +			if [ -f "$$i" -o -f "$$i.a" ]; then \
        +			(       echo installing $$i; \
        +				if [ "$(PLATFORM)" != "Cygwin" ]; then \
        +					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
        +				else \
        +					c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
        +					cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
        +					chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
        +					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
        +					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
        +				fi ); \
        +				if expr $(PLATFORM) : 'mingw' > /dev/null; then \
        +				(	case $$i in \
        +						*crypto*) i=libeay32.dll;; \
        +						*ssl*)    i=ssleay32.dll;; \
        +					esac; \
        +					echo installing $$i; \
        +	 				cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	 				chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	 				mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
        +				fi; \
        +			fi; \
        +		done; \
        +		(	here="`pwd`"; \
        +			cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
        +			$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
        +		if [ "$(INSTALLTOP)" != "/usr" ]; then \
        +			echo 'OpenSSL shared libraries have been installed in:'; \
        +			echo '  $(INSTALLTOP)'; \
        +			echo ''; \
        +			sed -e '1,/^$$/d' doc/openssl-shared.txt; \
        +		fi; \
        +	fi
        +	cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
        +	cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
        +	cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
        +
        +install_html_docs:
        +	here="`pwd`"; \
        +	for subdir in apps crypto ssl; do \
        +		mkdir -p $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
        +		for i in doc/$$subdir/*.pod; do \
        +			fn=`basename $$i .pod`; \
        +			echo "installing html/$$fn.$(HTMLSUFFIX)"; \
        +			cat $$i \
        +			| sed -r 's/L<([^)]*)(\([0-9]\))?\|([^)]*)(\([0-9]\))?>/L<\1|\3>/g' \
        +			| pod2html --podroot=doc --htmlroot=.. --podpath=apps:crypto:ssl \
        +			| sed -r 's/<!DOCTYPE.*//g' \
        +			> $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir/$$fn.$(HTMLSUFFIX); \
        +			$(PERL) util/extract-names.pl < $$i | \
        +				grep -v $$filecase "^$$fn\$$" | \
        +				(cd $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
        +				 while read n; do \
        +					PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$(HTMLSUFFIX) "$$n".$(HTMLSUFFIX); \
        +				 done); \
        +		done; \
        +	done
        +
        +install_docs:
        +	@$(PERL) $(TOP)/util/mkdir-p.pl \
        +		$(INSTALL_PREFIX)$(MANDIR)/man1 \
        +		$(INSTALL_PREFIX)$(MANDIR)/man3 \
        +		$(INSTALL_PREFIX)$(MANDIR)/man5 \
        +		$(INSTALL_PREFIX)$(MANDIR)/man7
        +	@pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
        +	here="`pwd`"; \
        +	filecase=; \
        +	if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
        +		filecase=-i; \
        +	fi; \
        +	set -e; for i in doc/apps/*.pod; do \
        +		fn=`basename $$i .pod`; \
        +		sec=`$(PERL) util/extract-section.pl 1 < $$i`; \
        +		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
        +		(cd `$(PERL) util/dirname.pl $$i`; \
        +		sh -c "$$pod2man \
        +			--section=$$sec --center=OpenSSL \
        +			--release=$(VERSION) `basename $$i`") \
        +			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
        +		$(PERL) util/extract-names.pl < $$i | \
        +			(grep -v $$filecase "^$$fn\$$"; true) | \
        +			(grep -v "[	]"; true) | \
        +			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
        +			 while read n; do \
        +				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
        +			 done); \
        +	done; \
        +	set -e; for i in doc/crypto/*.pod doc/ssl/*.pod; do \
        +		fn=`basename $$i .pod`; \
        +		sec=`$(PERL) util/extract-section.pl 3 < $$i`; \
        +		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
        +		(cd `$(PERL) util/dirname.pl $$i`; \
        +		sh -c "$$pod2man \
        +			--section=$$sec --center=OpenSSL \
        +			--release=$(VERSION) `basename $$i`") \
        +			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
        +		$(PERL) util/extract-names.pl < $$i | \
        +			(grep -v $$filecase "^$$fn\$$"; true) | \
        +			(grep -v "[	]"; true) | \
        +			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
        +			 while read n; do \
        +				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
        +			 done); \
        +	done
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        diff --git a/vendor/openssl/openssl/Makefile.org b/vendor/openssl/openssl/Makefile.org
        new file mode 100644
        index 000000000..2db31ead6
        --- /dev/null
        +++ b/vendor/openssl/openssl/Makefile.org
        @@ -0,0 +1,683 @@
        +##
        +## Makefile for OpenSSL
        +##
        +
        +VERSION=
        +MAJOR=
        +MINOR=
        +SHLIB_VERSION_NUMBER=
        +SHLIB_VERSION_HISTORY=
        +SHLIB_MAJOR=
        +SHLIB_MINOR=
        +SHLIB_EXT=
        +PLATFORM=dist
        +OPTIONS=
        +CONFIGURE_ARGS=
        +SHLIB_TARGET=
        +
        +# HERE indicates where this Makefile lives.  This can be used to indicate
        +# where sub-Makefiles are expected to be.  Currently has very limited usage,
        +# and should probably not be bothered with at all.
        +HERE=.
        +
        +# INSTALL_PREFIX is for package builders so that they can configure
        +# for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/.
        +# Normally it is left empty.
        +INSTALL_PREFIX=
        +INSTALLTOP=/usr/local/ssl
        +
        +# Do not edit this manually. Use Configure --openssldir=DIR do change this!
        +OPENSSLDIR=/usr/local/ssl
        +
        +# NO_IDEA - Define to build without the IDEA algorithm
        +# NO_RC4  - Define to build without the RC4 algorithm
        +# NO_RC2  - Define to build without the RC2 algorithm
        +# THREADS - Define when building with threads, you will probably also need any
        +#           system defines as well, i.e. _REENTERANT for Solaris 2.[34]
        +# TERMIO  - Define the termio terminal subsystem, needed if sgtty is missing.
        +# TERMIOS - Define the termios terminal subsystem, Silicon Graphics.
        +# LONGCRYPT - Define to use HPUX 10.x's long password modification to crypt(3).
        +# DEVRANDOM - Give this the value of the 'random device' if your OS supports
        +#           one.  32 bytes will be read from this when the random
        +#           number generator is initalised.
        +# SSL_FORBID_ENULL - define if you want the server to be not able to use the
        +#           NULL encryption ciphers.
        +#
        +# LOCK_DEBUG - turns on lots of lock debug output :-)
        +# REF_CHECK - turn on some xyz_free() assertions.
        +# REF_PRINT - prints some stuff on structure free.
        +# CRYPTO_MDEBUG - turns on my 'memory leak' detecting stuff
        +# MFUNC - Make all Malloc/Free/Realloc calls call
        +#       CRYPTO_malloc/CRYPTO_free/CRYPTO_realloc which can be setup to
        +#       call application defined callbacks via CRYPTO_set_mem_functions()
        +# MD5_ASM needs to be defined to use the x86 assembler for MD5
        +# SHA1_ASM needs to be defined to use the x86 assembler for SHA1
        +# RMD160_ASM needs to be defined to use the x86 assembler for RIPEMD160
        +# Do not define B_ENDIAN or L_ENDIAN if 'unsigned long' == 8.  It must
        +# equal 4.
        +# PKCS1_CHECK - pkcs1 tests.
        +
        +CC= cc
        +CFLAG= -O
        +DEPFLAG= 
        +PEX_LIBS= 
        +EX_LIBS= 
        +EXE_EXT= 
        +ARFLAGS=
        +AR=ar $(ARFLAGS) r
        +RANLIB= ranlib
        +NM= nm
        +PERL= perl
        +TAR= tar
        +TARFLAGS= --no-recursion --record-size=10240
        +MAKEDEPPROG=makedepend
        +LIBDIR=lib
        +
        +# We let the C compiler driver to take care of .s files. This is done in
        +# order to be excused from maintaining a separate set of architecture
        +# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC
        +# gcc, then the driver will automatically translate it to -xarch=v8plus
        +# and pass it down to assembler.
        +AS=$(CC) -c
        +ASFLAG=$(CFLAG)
        +
        +# For x86 assembler: Set PROCESSOR to 386 if you want to support
        +# the 80386.
        +PROCESSOR=
        +
        +# CPUID module collects small commonly used assembler snippets
        +CPUID_OBJ= 
        +BN_ASM= bn_asm.o
        +DES_ENC= des_enc.o fcrypt_b.o
        +AES_ENC= aes_core.o aes_cbc.o
        +BF_ENC= bf_enc.o
        +CAST_ENC= c_enc.o
        +RC4_ENC= rc4_enc.o
        +RC5_ENC= rc5_enc.o
        +MD5_ASM_OBJ= 
        +SHA1_ASM_OBJ= 
        +RMD160_ASM_OBJ= 
        +WP_ASM_OBJ=
        +CMLL_ENC=
        +MODES_ASM_OBJ=
        +ENGINES_ASM_OBJ=
        +PERLASM_SCHEME=
        +
        +# KRB5 stuff
        +KRB5_INCLUDES=
        +LIBKRB5=
        +
        +# Zlib stuff
        +ZLIB_INCLUDE=
        +LIBZLIB=
        +
        +# TOP level FIPS install directory.
        +FIPSDIR=
        +
        +# This is the location of fipscanister.o and friends.
        +# The FIPS module build will place it $(INSTALLTOP)/lib
        +# but since $(INSTALLTOP) can only take the default value
        +# when the module is built it will be in /usr/local/ssl/lib
        +# $(INSTALLTOP) for this build may be different so hard
        +# code the path.
        +
        +FIPSLIBDIR=
        +
        +# The location of the library which contains fipscanister.o
        +# normally it will be libcrypto unless fipsdso is set in which
        +# case it will be libfips. If not compiling in FIPS mode at all
        +# this is empty making it a useful test for a FIPS compile.
        +
        +FIPSCANLIB=
        +
        +# Shared library base address. Currently only used on Windows.
        +#
        +
        +BASEADDR=
        +
        +DIRS=   crypto ssl engines apps test tools
        +ENGDIRS= ccgost
        +SHLIBDIRS= crypto ssl
        +
        +# dirs in crypto to build
        +SDIRS=  \
        +	objects \
        +	md2 md4 md5 sha mdc2 hmac ripemd whrlpool \
        +	des aes rc2 rc4 rc5 idea bf cast camellia seed modes \
        +	bn ec rsa dsa ecdsa dh ecdh dso engine \
        +	buffer bio stack lhash rand err \
        +	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
        +	cms pqueue ts jpake srp store cmac
        +# keep in mind that the above list is adjusted by ./Configure
        +# according to no-xxx arguments...
        +
        +# tests to perform.  "alltests" is a special word indicating that all tests
        +# should be performed.
        +TESTS = alltests
        +
        +MAKEFILE= Makefile
        +
        +MANDIR=$(OPENSSLDIR)/man
        +MAN1=1
        +MAN3=3
        +MANSUFFIX=
        +HTMLSUFFIX=html
        +HTMLDIR=$(OPENSSLDIR)/html
        +SHELL=/bin/sh
        +
        +TOP=    .
        +ONEDIRS=out tmp
        +EDIRS=  times doc bugs util include certs ms shlib mt demos perl sf dep VMS
        +WDIRS=  windows
        +LIBS=   libcrypto.a libssl.a
        +SHARED_CRYPTO=libcrypto$(SHLIB_EXT)
        +SHARED_SSL=libssl$(SHLIB_EXT)
        +SHARED_LIBS=
        +SHARED_LIBS_LINK_EXTS=
        +SHARED_LDFLAGS=
        +
        +GENERAL=        Makefile
        +BASENAME=       openssl
        +NAME=           $(BASENAME)-$(VERSION)
        +TARFILE=        $(NAME).tar
        +WTARFILE=       $(NAME)-win.tar
        +EXHEADER=       e_os2.h
        +HEADER=         e_os.h
        +
        +all: Makefile build_all openssl.pc libssl.pc libcrypto.pc
        +
        +# as we stick to -e, CLEARENV ensures that local variables in lower
        +# Makefiles remain local and variable. $${VAR+VAR} is tribute to Korn
        +# shell, which [annoyingly enough] terminates unset with error if VAR
        +# is not present:-( TOP= && unset TOP is tribute to HP-UX /bin/sh,
        +# which terminates unset with error if no variable was present:-(
        +CLEARENV=	TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS}	\
        +		$${INCLUDE+INCLUDE} $${INCLUDES+INCLUDES}	\
        +		$${DIR+DIR} $${DIRS+DIRS} $${SRC+SRC}		\
        +		$${LIBSRC+LIBSRC} $${LIBOBJ+LIBOBJ} $${ALL+ALL}	\
        +		$${EXHEADER+EXHEADER} $${HEADER+HEADER}		\
        +		$${GENERAL+GENERAL} $${CFLAGS+CFLAGS}		\
        +		$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS}		\
        +		$${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS}	\
        +		$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS}	\
        +		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
        +
        +BUILDENV=	PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
        +		CC='$(CC)' CFLAG='$(CFLAG)' 			\
        +		AS='$(CC)' ASFLAG='$(CFLAG) -c'			\
        +		AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)'	\
        +		CROSS_COMPILE='$(CROSS_COMPILE)'	\
        +		PERL='$(PERL)' ENGDIRS='$(ENGDIRS)'		\
        +		SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)'	\
        +		INSTALL_PREFIX='$(INSTALL_PREFIX)'		\
        +		INSTALLTOP='$(INSTALLTOP)' OPENSSLDIR='$(OPENSSLDIR)'	\
        +		LIBDIR='$(LIBDIR)'				\
        +		MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD $(MAKEDEPPROG)' \
        +		DEPFLAG='-DOPENSSL_NO_DEPRECATED $(DEPFLAG)'	\
        +		MAKEDEPPROG='$(MAKEDEPPROG)'			\
        +		SHARED_LDFLAGS='$(SHARED_LDFLAGS)'		\
        +		KRB5_INCLUDES='$(KRB5_INCLUDES)' LIBKRB5='$(LIBKRB5)'	\
        +		ZLIB_INCLUDE='$(ZLIB_INCLUDE)' LIBZLIB='$(LIBZLIB)'	\
        +		EXE_EXT='$(EXE_EXT)' SHARED_LIBS='$(SHARED_LIBS)'	\
        +		SHLIB_EXT='$(SHLIB_EXT)' SHLIB_TARGET='$(SHLIB_TARGET)'	\
        +		PEX_LIBS='$(PEX_LIBS)' EX_LIBS='$(EX_LIBS)'	\
        +		CPUID_OBJ='$(CPUID_OBJ)'			\
        +		BN_ASM='$(BN_ASM)' DES_ENC='$(DES_ENC)' 	\
        +		AES_ENC='$(AES_ENC)' CMLL_ENC='$(CMLL_ENC)'	\
        +		BF_ENC='$(BF_ENC)' CAST_ENC='$(CAST_ENC)'	\
        +		RC4_ENC='$(RC4_ENC)' RC5_ENC='$(RC5_ENC)'	\
        +		SHA1_ASM_OBJ='$(SHA1_ASM_OBJ)'			\
        +		MD5_ASM_OBJ='$(MD5_ASM_OBJ)'			\
        +		RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)'		\
        +		WP_ASM_OBJ='$(WP_ASM_OBJ)'			\
        +		MODES_ASM_OBJ='$(MODES_ASM_OBJ)'		\
        +		ENGINES_ASM_OBJ='$(ENGINES_ASM_OBJ)'		\
        +		PERLASM_SCHEME='$(PERLASM_SCHEME)'		\
        +		FIPSLIBDIR='${FIPSLIBDIR}'			\
        +		FIPSDIR='${FIPSDIR}'				\
        +		FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}"	\
        +		THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
        +# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
        +# which in turn eliminates ambiguities in variable treatment with -e.
        +
        +# BUILD_CMD is a generic macro to build a given target in a given
        +# subdirectory.  The target must be given through the shell variable
        +# `target' and the subdirectory to build in must be given through `dir'.
        +# This macro shouldn't be used directly, use RECURSIVE_BUILD_CMD or
        +# BUILD_ONE_CMD instead.
        +#
        +# BUILD_ONE_CMD is a macro to build a given target in a given
        +# subdirectory if that subdirectory is part of $(DIRS).  It requires
        +# exactly the same shell variables as BUILD_CMD.
        +#
        +# RECURSIVE_BUILD_CMD is a macro to build a given target in all
        +# subdirectories defined in $(DIRS).  It requires that the target
        +# is given through the shell variable `target'.
        +BUILD_CMD=  if [ -d "$$dir" ]; then \
        +	    (	cd $$dir && echo "making $$target in $$dir..." && \
        +		$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. DIR=$$dir $$target \
        +	    ) || exit 1; \
        +	    fi
        +RECURSIVE_BUILD_CMD=for dir in $(DIRS); do $(BUILD_CMD); done
        +BUILD_ONE_CMD=\
        +	if expr " $(DIRS) " : ".* $$dir " >/dev/null 2>&1; then \
        +		$(BUILD_CMD); \
        +	fi
        +
        +reflect:
        +	@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
        +
        +sub_all: build_all
        +build_all: build_libs build_apps build_tests build_tools
        +
        +build_libs: build_crypto build_ssl build_engines
        +
        +build_crypto:
        +	@dir=crypto; target=all; $(BUILD_ONE_CMD)
        +build_ssl:
        +	@dir=ssl; target=all; $(BUILD_ONE_CMD)
        +build_engines:
        +	@dir=engines; target=all; $(BUILD_ONE_CMD)
        +build_apps:
        +	@dir=apps; target=all; $(BUILD_ONE_CMD)
        +build_tests:
        +	@dir=test; target=all; $(BUILD_ONE_CMD)
        +build_tools:
        +	@dir=tools; target=all; $(BUILD_ONE_CMD)
        +
        +all_testapps: build_libs build_testapps
        +build_testapps:
        +	@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
        +
        +fips_premain_dso$(EXE_EXT): libcrypto.a
        +	[ -z "$(FIPSCANLIB)" ] || $(CC) $(CFLAG) -Iinclude \
        +		-DFINGERPRINT_PREMAIN_DSO_LOAD -o $@  \
        +		$(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fipscanister.o \
        +		libcrypto.a $(EX_LIBS)
        +
        +libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT)
        +	@if [ "$(SHLIB_TARGET)" != "" ]; then \
        +		if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
        +			FIPSLD_LIBCRYPTO=libcrypto.a ; \
        +			FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; \
        +			export CC FIPSLD_CC FIPSLD_LIBCRYPTO; \
        +		fi; \
        +		$(MAKE) -e SHLIBDIRS=crypto build-shared; \
        +	else \
        +		echo "There's no support for shared libraries on this platform" >&2; \
        +		exit 1; \
        +	fi
        +
        +libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
        +	@if [ "$(SHLIB_TARGET)" != "" ]; then \
        +		$(MAKE) SHLIBDIRS=ssl SHLIBDEPS='-lcrypto' build-shared; \
        +	else \
        +		echo "There's no support for shared libraries on this platform" >&2; \
        +		exit 1; \
        +	fi
        +
        +clean-shared:
        +	@set -e; for i in $(SHLIBDIRS); do \
        +		if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \
        +			tmp="$(SHARED_LIBS_LINK_EXTS)"; \
        +			for j in $${tmp:-x}; do \
        +				( set -x; rm -f lib$$i$$j ); \
        +			done; \
        +		fi; \
        +		( set -x; rm -f lib$$i$(SHLIB_EXT) ); \
        +		if [ "$(PLATFORM)" = "Cygwin" ]; then \
        +			( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
        +		fi; \
        +	done
        +
        +link-shared:
        +	@ set -e; for i in $(SHLIBDIRS); do \
        +		$(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \
        +			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
        +			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
        +			symlink.$(SHLIB_TARGET); \
        +		libs="$$libs -l$$i"; \
        +	done
        +
        +build-shared: do_$(SHLIB_TARGET) link-shared
        +
        +do_$(SHLIB_TARGET):
        +	@ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \
        +		if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \
        +			libs="$(LIBKRB5) $$libs"; \
        +		fi; \
        +		$(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \
        +			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
        +			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
        +			LIBDEPS="$$libs $(EX_LIBS)" \
        +			link_a.$(SHLIB_TARGET); \
        +		libs="-l$$i $$libs"; \
        +	done
        +
        +libcrypto.pc: Makefile
        +	@ ( echo 'prefix=$(INSTALLTOP)'; \
        +	    echo 'exec_prefix=$${prefix}'; \
        +	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
        +	    echo 'includedir=$${prefix}/include'; \
        +	    echo ''; \
        +	    echo 'Name: OpenSSL-libcrypto'; \
        +	    echo 'Description: OpenSSL cryptography library'; \
        +	    echo 'Version: '$(VERSION); \
        +	    echo 'Requires: '; \
        +	    echo 'Libs: -L$${libdir} -lcrypto'; \
        +	    echo 'Libs.private: $(EX_LIBS)'; \
        +	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
        +
        +libssl.pc: Makefile
        +	@ ( echo 'prefix=$(INSTALLTOP)'; \
        +	    echo 'exec_prefix=$${prefix}'; \
        +	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
        +	    echo 'includedir=$${prefix}/include'; \
        +	    echo ''; \
        +	    echo 'Name: OpenSSL'; \
        +	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
        +	    echo 'Version: '$(VERSION); \
        +	    echo 'Requires: '; \
        +	    echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
        +	    echo 'Libs.private: $(EX_LIBS)'; \
        +	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
        +
        +openssl.pc: Makefile
        +	@ ( echo 'prefix=$(INSTALLTOP)'; \
        +	    echo 'exec_prefix=$${prefix}'; \
        +	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
        +	    echo 'includedir=$${prefix}/include'; \
        +	    echo ''; \
        +	    echo 'Name: OpenSSL'; \
        +	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
        +	    echo 'Version: '$(VERSION); \
        +	    echo 'Requires: '; \
        +	    echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
        +	    echo 'Libs.private: $(EX_LIBS)'; \
        +	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
        +
        +Makefile: Makefile.org Configure config
        +	@echo "Makefile is older than Makefile.org, Configure or config."
        +	@echo "Reconfigure the source tree (via './config' or 'perl Configure'), please."
        +	@false
        +
        +libclean:
        +	rm -f *.map *.so *.so.* *.dylib *.dll engines/*.so engines/*.dll engines/*.dylib *.a engines/*.a */lib */*/lib
        +
        +clean:	libclean
        +	rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
        +	@set -e; target=clean; $(RECURSIVE_BUILD_CMD)
        +	rm -f $(LIBS)
        +	rm -f openssl.pc libssl.pc libcrypto.pc
        +	rm -f speed.* .pure
        +	rm -f $(TARFILE)
        +	@set -e; for i in $(ONEDIRS) ;\
        +	do \
        +	rm -fr $$i/*; \
        +	done
        +
        +makefile.one: files
        +	$(PERL) util/mk1mf.pl >makefile.one; \
        +	sh util/do_ms.sh
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile > $(TOP)/MINFO
        +	@set -e; target=files; $(RECURSIVE_BUILD_CMD)
        +
        +links:
        +	@$(PERL) $(TOP)/util/mkdir-p.pl include/openssl
        +	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER)
        +	@set -e; target=links; $(RECURSIVE_BUILD_CMD)
        +
        +gentests:
        +	@(cd test && echo "generating dummy tests (if needed)..." && \
        +	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on generate );
        +
        +dclean:
        +	rm -rf *.bak include/openssl certs/.0
        +	@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
        +
        +rehash: rehash.time
        +rehash.time: certs apps
        +	@if [ -z "$(CROSS_COMPILE)" ]; then \
        +		(OPENSSL="`pwd`/util/opensslwrap.sh"; \
        +		[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
        +		OPENSSL_DEBUG_MEMORY=on; \
        +		export OPENSSL OPENSSL_DEBUG_MEMORY; \
        +		$(PERL) tools/c_rehash certs/demo) && \
        +		touch rehash.time; \
        +	else :; fi
        +
        +test:   tests
        +
        +tests: rehash
        +	@(cd test && echo "testing..." && \
        +	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on OPENSSL_CONF=../apps/openssl.cnf tests );
        +	OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh version -a
        +
        +report:
        +	@$(PERL) util/selftest.pl
        +
        +depend:
        +	@set -e; target=depend; $(RECURSIVE_BUILD_CMD)
        +
        +lint:
        +	@set -e; target=lint; $(RECURSIVE_BUILD_CMD)
        +
        +tags:
        +	rm -f TAGS
        +	find . -name '[^.]*.[ch]' | xargs etags -a
        +
        +errors:
        +	$(PERL) util/ck_errf.pl -strict */*.c */*/*.c
        +	$(PERL) util/mkerr.pl -recurse -write
        +	(cd engines; $(MAKE) PERL=$(PERL) errors)
        +
        +stacks:
        +	$(PERL) util/mkstack.pl -write
        +
        +util/libeay.num::
        +	$(PERL) util/mkdef.pl crypto update
        +
        +util/ssleay.num::
        +	$(PERL) util/mkdef.pl ssl update
        +
        +crypto/objects/obj_dat.h: crypto/objects/obj_dat.pl crypto/objects/obj_mac.h
        +	$(PERL) crypto/objects/obj_dat.pl crypto/objects/obj_mac.h crypto/objects/obj_dat.h
        +crypto/objects/obj_mac.h: crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num
        +	$(PERL) crypto/objects/objects.pl crypto/objects/objects.txt crypto/objects/obj_mac.num crypto/objects/obj_mac.h
        +crypto/objects/obj_xref.h: crypto/objects/objxref.pl crypto/objects/obj_xref.txt crypto/objects/obj_mac.num
        +	$(PERL) crypto/objects/objxref.pl crypto/objects/obj_mac.num crypto/objects/obj_xref.txt >crypto/objects/obj_xref.h
        +
        +apps/openssl-vms.cnf: apps/openssl.cnf
        +	$(PERL) VMS/VMSify-conf.pl < apps/openssl.cnf > apps/openssl-vms.cnf
        +
        +crypto/bn/bn_prime.h: crypto/bn/bn_prime.pl
        +	$(PERL) crypto/bn/bn_prime.pl >crypto/bn/bn_prime.h
        +
        +
        +TABLE: Configure
        +	(echo 'Output of `Configure TABLE'"':"; \
        +	$(PERL) Configure TABLE) > TABLE
        +
        +update: errors stacks util/libeay.num util/ssleay.num crypto/objects/obj_dat.h crypto/objects/obj_xref.h apps/openssl-vms.cnf crypto/bn/bn_prime.h TABLE depend
        +
        +# Build distribution tar-file. As the list of files returned by "find" is
        +# pretty long, on several platforms a "too many arguments" error or similar
        +# would occur. Therefore the list of files is temporarily stored into a file
        +# and read directly, requiring GNU-Tar. Call "make TAR=gtar dist" if the normal
        +# tar does not support the --files-from option.
        +tar:
        +	find . -type d -print | xargs chmod 755
        +	find . -type f -print | xargs chmod a+r
        +	find . -type f -perm -0100 -print | xargs chmod a+x
        +	find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE | sort > ../$(TARFILE).list; \
        +	$(TAR) $(TARFLAGS) --files-from ../$(TARFILE).list -cvf - | \
        +	tardy --user_number=0  --user_name=openssl \
        +	      --group_number=0 --group_name=openssl \
        +	      --prefix=openssl-$(VERSION) - |\
        +	gzip --best >../$(TARFILE).gz; \
        +	rm -f ../$(TARFILE).list; \
        +	ls -l ../$(TARFILE).gz
        +
        +tar-snap:
        +	@$(TAR) $(TARFLAGS) -cvf - \
        +		`find * \! -path CVS/\* \! -path \*/CVS/\* \! -name CVS \! -name .cvsignore \! -name STATUS \! -name TABLE \! -name '*.o' \! -name '*.a' \! -name '*.so' \! -name '*.so.*'  \! -name 'openssl' \! -name '*test' \! -name '.#*' \! -name '*~' | sort` |\
        +	tardy --user_number=0  --user_name=openssl \
        +	      --group_number=0 --group_name=openssl \
        +	      --prefix=openssl-$(VERSION) - > ../$(TARFILE);\
        +	ls -l ../$(TARFILE)
        +
        +dist:   
        +	$(PERL) Configure dist
        +	@$(MAKE) dist_pem_h
        +	@$(MAKE) SDIRS='$(SDIRS)' clean
        +	@$(MAKE) TAR='$(TAR)' TARFLAGS='$(TARFLAGS)' tar
        +
        +dist_pem_h:
        +	(cd crypto/pem; $(MAKE) -e $(BUILDENV) pem.h; $(MAKE) clean)
        +
        +install: all install_docs install_sw
        +
        +install_sw:
        +	@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
        +		$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
        +		$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
        +		$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
        +		$(INSTALL_PREFIX)$(OPENSSLDIR)/private
        +	@set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\
        +	do \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +	@set -e; target=install; $(RECURSIVE_BUILD_CMD)
        +	@set -e; liblist="$(LIBS)"; for i in $$liblist ;\
        +	do \
        +		if [ -f "$$i" ]; then \
        +		(       echo installing $$i; \
        +			cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +			$(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +			chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +			mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
        +		fi; \
        +	done;
        +	@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
        +		tmp="$(SHARED_LIBS)"; \
        +		for i in $${tmp:-x}; \
        +		do \
        +			if [ -f "$$i" -o -f "$$i.a" ]; then \
        +			(       echo installing $$i; \
        +				if [ "$(PLATFORM)" != "Cygwin" ]; then \
        +					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
        +				else \
        +					c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
        +					cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
        +					chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
        +					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
        +					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
        +					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
        +				fi ); \
        +				if expr $(PLATFORM) : 'mingw' > /dev/null; then \
        +				(	case $$i in \
        +						*crypto*) i=libeay32.dll;; \
        +						*ssl*)    i=ssleay32.dll;; \
        +					esac; \
        +					echo installing $$i; \
        +	 				cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	 				chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	 				mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
        +				fi; \
        +			fi; \
        +		done; \
        +		(	here="`pwd`"; \
        +			cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
        +			$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
        +		if [ "$(INSTALLTOP)" != "/usr" ]; then \
        +			echo 'OpenSSL shared libraries have been installed in:'; \
        +			echo '  $(INSTALLTOP)'; \
        +			echo ''; \
        +			sed -e '1,/^$$/d' doc/openssl-shared.txt; \
        +		fi; \
        +	fi
        +	cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
        +	cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
        +	cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
        +
        +install_html_docs:
        +	here="`pwd`"; \
        +	for subdir in apps crypto ssl; do \
        +		mkdir -p $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
        +		for i in doc/$$subdir/*.pod; do \
        +			fn=`basename $$i .pod`; \
        +			echo "installing html/$$fn.$(HTMLSUFFIX)"; \
        +			cat $$i \
        +			| sed -r 's/L<([^)]*)(\([0-9]\))?\|([^)]*)(\([0-9]\))?>/L<\1|\3>/g' \
        +			| pod2html --podroot=doc --htmlroot=.. --podpath=apps:crypto:ssl \
        +			| sed -r 's/<!DOCTYPE.*//g' \
        +			> $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir/$$fn.$(HTMLSUFFIX); \
        +			$(PERL) util/extract-names.pl < $$i | \
        +				grep -v $$filecase "^$$fn\$$" | \
        +				(cd $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
        +				 while read n; do \
        +					PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$(HTMLSUFFIX) "$$n".$(HTMLSUFFIX); \
        +				 done); \
        +		done; \
        +	done
        +
        +install_docs:
        +	@$(PERL) $(TOP)/util/mkdir-p.pl \
        +		$(INSTALL_PREFIX)$(MANDIR)/man1 \
        +		$(INSTALL_PREFIX)$(MANDIR)/man3 \
        +		$(INSTALL_PREFIX)$(MANDIR)/man5 \
        +		$(INSTALL_PREFIX)$(MANDIR)/man7
        +	@pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
        +	here="`pwd`"; \
        +	filecase=; \
        +	if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
        +		filecase=-i; \
        +	fi; \
        +	set -e; for i in doc/apps/*.pod; do \
        +		fn=`basename $$i .pod`; \
        +		sec=`$(PERL) util/extract-section.pl 1 < $$i`; \
        +		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
        +		(cd `$(PERL) util/dirname.pl $$i`; \
        +		sh -c "$$pod2man \
        +			--section=$$sec --center=OpenSSL \
        +			--release=$(VERSION) `basename $$i`") \
        +			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
        +		$(PERL) util/extract-names.pl < $$i | \
        +			(grep -v $$filecase "^$$fn\$$"; true) | \
        +			(grep -v "[	]"; true) | \
        +			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
        +			 while read n; do \
        +				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
        +			 done); \
        +	done; \
        +	set -e; for i in doc/crypto/*.pod doc/ssl/*.pod; do \
        +		fn=`basename $$i .pod`; \
        +		sec=`$(PERL) util/extract-section.pl 3 < $$i`; \
        +		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
        +		(cd `$(PERL) util/dirname.pl $$i`; \
        +		sh -c "$$pod2man \
        +			--section=$$sec --center=OpenSSL \
        +			--release=$(VERSION) `basename $$i`") \
        +			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
        +		$(PERL) util/extract-names.pl < $$i | \
        +			(grep -v $$filecase "^$$fn\$$"; true) | \
        +			(grep -v "[	]"; true) | \
        +			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
        +			 while read n; do \
        +				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
        +			 done); \
        +	done
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        diff --git a/vendor/openssl/openssl/Makefile.shared b/vendor/openssl/openssl/Makefile.shared
        new file mode 100644
        index 000000000..e753f44e1
        --- /dev/null
        +++ b/vendor/openssl/openssl/Makefile.shared
        @@ -0,0 +1,655 @@
        +#
        +# Helper makefile to link shared libraries in a portable way.
        +# This is much simpler than libtool, and hopefully not too error-prone.
        +#
        +# The following variables need to be set on the command line to build
        +# properly
        +
        +# CC contains the current compiler.  This one MUST be defined
        +CC=cc
        +CFLAGS=$(CFLAG)
        +# LDFLAGS contains flags to be used when temporary object files (when building
        +# shared libraries) are created, or when an application is linked.
        +# SHARED_LDFLAGS contains flags to be used when the shared library is created.
        +LDFLAGS=
        +SHARED_LDFLAGS=
        +
        +NM=nm
        +
        +# LIBNAME contains just the name of the library, without prefix ("lib"
        +# on Unix, "cyg" for certain forms under Cygwin...) or suffix (.a, .so,
        +# .dll, ...).  This one MUST have a value when using this makefile to
        +# build shared libraries.
        +# For example, to build libfoo.so, you need to do the following:
        +#LIBNAME=foo
        +LIBNAME=
        +
        +# APPNAME contains just the name of the application, without suffix (""
        +# on Unix, ".exe" on Windows, ...).  This one MUST have a value when using
        +# this makefile to build applications.
        +# For example, to build foo, you need to do the following:
        +#APPNAME=foo
        +APPNAME=
        +
        +# OBJECTS contains all the object files to link together into the application.
        +# This must contain at least one object file.
        +#OBJECTS=foo.o
        +OBJECTS=
        +
        +# LIBEXTRAS contains extra modules to link together with the library.
        +# For example, if a second library, say libbar.a needs to be linked into
        +# libfoo.so, you need to do the following:
        +#LIBEXTRAS=libbar.a
        +# Note that this MUST be used when using the link_o targets, to hold the
        +# names of all object files that go into the target library.
        +LIBEXTRAS=
        +
        +# LIBVERSION contains the current version of the library.
        +# For example, to build libfoo.so.1.2, you need to do the following:
        +#LIBVERSION=1.2
        +LIBVERSION=
        +
        +# LIBCOMPATVERSIONS contains the compatibility versions (a list) of
        +# the library.  They MUST be in decreasing order.
        +# For example, if libfoo.so.1.2.1 is backward compatible with libfoo.so.1.2
        +# and libfoo.so.1, you need to do the following:
        +#LIBCOMPATVERSIONS=1.2 1
        +# Note that on systems that use sonames, the last number will appear as
        +# part of it.
        +# It's also possible, for systems that support it (Tru64, for example),
        +# to add extra compatibility info with more precision, by adding a second
        +# list of versions, separated from the first with a semicolon, like this:
        +#LIBCOMPATVERSIONS=1.2 1;1.2.0 1.1.2 1.1.1 1.1.0 1.0.0
        +LIBCOMPATVERSIONS=
        +
        +# LIBDEPS contains all the flags necessary to cover all necessary
        +# dependencies to other libraries.
        +LIBDEPS=
        +
        +#------------------------------------------------------------------------------
        +# The rest is private to this makefile.
        +
        +SET_X=:
        +#SET_X=set -x
        +
        +top:
        +	echo "Trying to use this makefile interactively?  Don't."
        +
        +CALC_VERSIONS=	\
        +	SHLIB_COMPAT=; SHLIB_SOVER=; \
        +	if [ -n "$(LIBVERSION)$(LIBCOMPATVERSIONS)" ]; then \
        +		prev=""; \
        +		for v in `echo "$(LIBVERSION) $(LIBCOMPATVERSIONS)" | cut -d';' -f1`; do \
        +			SHLIB_SOVER_NODOT=$$v; \
        +			SHLIB_SOVER=.$$v; \
        +			if [ -n "$$prev" ]; then \
        +				SHLIB_COMPAT="$$SHLIB_COMPAT .$$prev"; \
        +			fi; \
        +			prev=$$v; \
        +		done; \
        +	fi
        +
        +LINK_APP=	\
        +  ( $(SET_X);   \
        +    LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \
        +    LDCMD="$${LDCMD:-$(CC)}"; LDFLAGS="$${LDFLAGS:-$(CFLAGS)}"; \
        +    LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \
        +    LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \
        +    LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \
        +    $${LDCMD} $${LDFLAGS} -o $${APPNAME:=$(APPNAME)} $(OBJECTS) $${LIBDEPS} )
        +
        +LINK_SO=	\
        +  ( $(SET_X);   \
        +    LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \
        +    SHAREDCMD="$${SHAREDCMD:-$(CC)}"; \
        +    SHAREDFLAGS="$${SHAREDFLAGS:-$(CFLAGS) $(SHARED_LDFLAGS)}"; \
        +    LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \
        +    LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \
        +    LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \
        +    $${SHAREDCMD} $${SHAREDFLAGS} \
        +	-o $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \
        +	$$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \
        +  ) && $(SYMLINK_SO)
        +
        +SYMLINK_SO=	\
        +	if [ -n "$$INHIBIT_SYMLINKS" ]; then :; else \
        +		prev=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \
        +		if [ -n "$$SHLIB_COMPAT" ]; then \
        +			for x in $$SHLIB_COMPAT; do \
        +				( $(SET_X); rm -f $$SHLIB$$x$$SHLIB_SUFFIX; \
        +				  ln -s $$prev $$SHLIB$$x$$SHLIB_SUFFIX ); \
        +				prev=$$SHLIB$$x$$SHLIB_SUFFIX; \
        +			done; \
        +		fi; \
        +		if [ -n "$$SHLIB_SOVER" ]; then \
        +			( $(SET_X); rm -f $$SHLIB$$SHLIB_SUFFIX; \
        +			  ln -s $$prev $$SHLIB$$SHLIB_SUFFIX ); \
        +		fi; \
        +	fi
        +
        +LINK_SO_A=	SHOBJECTS="lib$(LIBNAME).a $(LIBEXTRAS)"; $(LINK_SO)
        +LINK_SO_O=	SHOBJECTS="$(LIBEXTRAS)"; $(LINK_SO)
        +
        +LINK_SO_A_VIA_O=	\
        +  SHOBJECTS=lib$(LIBNAME).o; \
        +  ALL=$$ALLSYMSFLAGS; ALLSYMSFLAGS=; NOALLSYMSFLAGS=; \
        +  ( $(SET_X); \
        +    ld $(LDFLAGS) -r -o lib$(LIBNAME).o $$ALL lib$(LIBNAME).a $(LIBEXTRAS) ); \
        +  $(LINK_SO) && rm -f lib$(LIBNAME).o
        +
        +LINK_SO_A_UNPACKED=	\
        +  UNPACKDIR=link_tmp.$$$$; rm -rf $$UNPACKDIR; mkdir $$UNPACKDIR; \
        +  (cd $$UNPACKDIR; ar x ../lib$(LIBNAME).a) && \
        +  ([ -z "$(LIBEXTRAS)" ] || cp $(LIBEXTRAS) $$UNPACKDIR) && \
        +  SHOBJECTS=$$UNPACKDIR/*.o; \
        +  $(LINK_SO) && rm -rf $$UNPACKDIR
        +
        +DETECT_GNU_LD=($(CC) -Wl,-V /dev/null 2>&1 | grep '^GNU ld' )>/dev/null
        +
        +DO_GNU_SO=$(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS='-Wl,--whole-archive'; \
        +	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"
        +
        +DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"
        +
        +#This is rather special.  It's a special target with which one can link
        +#applications without bothering with any features that have anything to
        +#do with shared libraries, for example when linking against static
        +#libraries.  It's mostly here to avoid a lot of conditionals everywhere
        +#else...
        +link_app.:
        +	$(LINK_APP)
        +
        +link_o.gnu:
        +	@ $(DO_GNU_SO); $(LINK_SO_O)
        +link_a.gnu:
        +	@ $(DO_GNU_SO); $(LINK_SO_A)
        +link_app.gnu:
        +	@ $(DO_GNU_APP); $(LINK_APP)
        +
        +DO_BEOS_SO=	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS='-Wl,--whole-archive'; \
        +	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SUFFIX"
        +
        +link_o.beos:
        +	@ $(DO_BEOS_SO); $(LINK_SO_O)
        +link_a.beos:
        +	@ $(DO_BEOS_SO); $(LINK_SO_A)
        +
        +link_o.bsd:
        +	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
        +	$(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	LIBDEPS=" "; \
        +	ALLSYMSFLAGS="-Wl,-Bforcearchive"; \
        +	NOALLSYMSFLAGS=; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -nostdlib"; \
        +	fi; $(LINK_SO_O)
        +link_a.bsd:
        +	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
        +	$(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	LIBDEPS=" "; \
        +	ALLSYMSFLAGS="-Wl,-Bforcearchive"; \
        +	NOALLSYMSFLAGS=; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -nostdlib"; \
        +	fi; $(LINK_SO_A)
        +link_app.bsd:
        +	@if $(DETECT_GNU_LD); then $(DO_GNU_APP); else \
        +	LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBPATH)"; \
        +	fi; $(LINK_APP)
        +
        +# For Darwin AKA Mac OS/X (dyld)
        +# Originally link_o.darwin produced .so, because it was hard-coded
        +# in dso_dlfcn module. At later point dso_dlfcn switched to .dylib
        +# extension in order to allow for run-time linking with vendor-
        +# supplied shared libraries such as libz, so that link_o.darwin had
        +# to be harmonized with it. This caused minor controversy, because
        +# it was believed that dlopen can't be used to dynamically load
        +# .dylib-s, only so called bundle modules (ones linked with -bundle
        +# flag). The belief seems to be originating from pre-10.4 release,
        +# where dlfcn functionality was emulated by dlcompat add-on. In
        +# 10.4 dlopen was rewritten as native part of dyld and is documented
        +# to be capable of loading both dynamic libraries and bundles. In
        +# order to provide compatibility with pre-10.4 dlopen, modules are
        +# linked with -bundle flag, which makes .dylib extension misleading.
        +# It works, because dlopen is [and always was] extension-agnostic.
        +# Alternative to this heuristic approach is to develop specific
        +# MacOS X dso module relying on whichever "native" dyld interface.
        +link_o.darwin:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME); \
        +	SHLIB_SUFFIX=.dylib; \
        +	ALLSYMSFLAGS='-all_load'; \
        +	NOALLSYMSFLAGS=''; \
        +	SHAREDFLAGS="$(CFLAGS) `echo $(SHARED_LDFLAGS) | sed s/dynamiclib/bundle/`"; \
        +	if [ -n "$(LIBVERSION)" ]; then \
        +		SHAREDFLAGS="$$SHAREDFLAGS -current_version $(LIBVERSION)"; \
        +	fi; \
        +	if [ -n "$$SHLIB_SOVER_NODOT" ]; then \
        +		SHAREDFLAGS="$$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \
        +	fi; \
        +	$(LINK_SO_O)
        +link_a.darwin:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME); \
        +	SHLIB_SUFFIX=.dylib; \
        +	ALLSYMSFLAGS='-all_load'; \
        +	NOALLSYMSFLAGS=''; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS)"; \
        +	if [ -n "$(LIBVERSION)" ]; then \
        +		SHAREDFLAGS="$$SHAREDFLAGS -current_version $(LIBVERSION)"; \
        +	fi; \
        +	if [ -n "$$SHLIB_SOVER_NODOT" ]; then \
        +		SHAREDFLAGS="$$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \
        +	fi; \
        +	SHAREDFLAGS="$$SHAREDFLAGS -install_name $(INSTALLTOP)/$(LIBDIR)/$$SHLIB$(SHLIB_EXT)"; \
        +	$(LINK_SO_A)
        +link_app.darwin:	# is there run-path on darwin?
        +	$(LINK_APP)
        +
        +link_o.cygwin:
        +	@ $(CALC_VERSIONS); \
        +	INHIBIT_SYMLINKS=yes; \
        +	SHLIB=cyg$(LIBNAME); \
        +	base=-Wl,--enable-auto-image-base; \
        +	deffile=; \
        +	if expr $(PLATFORM) : 'mingw' > /dev/null; then \
        +		SHLIB=$(LIBNAME)eay32; base=; \
        +		if test -f $(LIBNAME)eay32.def; then \
        +			deffile=$(LIBNAME)eay32.def; \
        +		fi; \
        +	fi; \
        +	SHLIB_SUFFIX=.dll; \
        +	LIBVERSION="$(LIBVERSION)"; \
        +	SHLIB_SOVER=${LIBVERSION:+"-$(LIBVERSION)"}; \
        +	ALLSYMSFLAGS='-Wl,--whole-archive'; \
        +	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared $$base $$deffile -Wl,-s,-Bsymbolic"; \
        +	$(LINK_SO_O)
        +#for mingw target if def-file is in use dll-name should match library-name
        +link_a.cygwin:
        +	@ $(CALC_VERSIONS); \
        +	INHIBIT_SYMLINKS=yes; \
        +	SHLIB=cyg$(LIBNAME); SHLIB_SOVER=-$(LIBVERSION); SHLIB_SUFFIX=.dll; \
        +	dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; extras=; \
        +	base=-Wl,--enable-auto-image-base; \
        +	if expr $(PLATFORM) : 'mingw' > /dev/null; then \
        +		case $(LIBNAME) in \
        +			crypto) SHLIB=libeay;; \
        +			ssl) SHLIB=ssleay;; \
        +		esac; \
        +		SHLIB_SOVER=32; \
        +		extras="$(LIBNAME).def"; \
        +		$(PERL) util/mkdef.pl 32 $$SHLIB > $$extras; \
        +		base=; [ $(LIBNAME) = "crypto" ] && base=-Wl,--image-base,0x63000000; \
        +	fi; \
        +	dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \
        +	$(PERL) util/mkrc.pl $$dll_name | \
        +		$(CROSS_COMPILE)windres -o rc.o; \
        +	extras="$$extras rc.o"; \
        +	ALLSYMSFLAGS='-Wl,--whole-archive'; \
        +	NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared $$base -Wl,-s,-Bsymbolic -Wl,--out-implib,lib$(LIBNAME).dll.a $$extras"; \
        +	[ -f apps/$$dll_name ] && rm apps/$$dll_name; \
        +	[ -f test/$$dll_name ] && rm test/$$dll_name; \
        +	$(LINK_SO_A) || exit 1; \
        +	rm $$extras; \
        +	cp -p $$dll_name apps/; \
        +	cp -p $$dll_name test/
        +link_app.cygwin:
        +	@if expr "$(CFLAGS)" : '.*OPENSSL_USE_APPLINK' > /dev/null; then \
        +		LIBDEPS="$(TOP)/crypto/applink.o $${LIBDEPS:-$(LIBDEPS)}"; \
        +		export LIBDEPS; \
        +	fi; \
        +	$(LINK_APP)
        +
        +link_o.alpha-osf1:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
        +		if [ -n "$$SHLIB_HIST" ]; then \
        +			SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
        +		else \
        +			SHLIB_HIST="$(LIBVERSION)"; \
        +		fi; \
        +		SHLIB_SOVER=; \
        +		ALLSYMSFLAGS='-all'; \
        +		NOALLSYMSFLAGS='-none'; \
        +		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-B,symbolic"; \
        +		if [ -n "$$SHLIB_HIST" ]; then \
        +			SHAREDFLAGS="$$SHAREDFLAGS -set_version $$SHLIB_HIST"; \
        +		fi; \
        +	fi; \
        +	$(LINK_SO_O)
        +link_a.alpha-osf1:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
        +		if [ -n "$$SHLIB_HIST" ]; then \
        +			SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
        +		else \
        +			SHLIB_HIST="$(LIBVERSION)"; \
        +		fi; \
        +		SHLIB_SOVER=; \
        +		ALLSYMSFLAGS='-all'; \
        +		NOALLSYMSFLAGS='-none'; \
        +		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-B,symbolic"; \
        +		if [ -n "$$SHLIB_HIST" ]; then \
        +			SHAREDFLAGS="$$SHAREDFLAGS -set_version $$SHLIB_HIST"; \
        +		fi; \
        +	fi; \
        +	$(LINK_SO_A)
        +link_app.alpha-osf1:
        +	@if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_APP); \
        +	else \
        +		LDFLAGS="$(CFLAGS) -rpath $(LIBRPATH)"; \
        +	fi; \
        +	$(LINK_APP)
        +
        +link_o.solaris:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		MINUSZ='-z '; \
        +		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSZ='-Wl,-z,'; \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
        +		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
        +		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
        +	fi; \
        +	$(LINK_SO_O)
        +link_a.solaris:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		MINUSZ='-z '; \
        +		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSZ='-Wl,-z,'; \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=;\
        +		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
        +		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
        +		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
        +	fi; \
        +	$(LINK_SO_A)
        +link_app.solaris:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_APP); \
        +	else \
        +		LDFLAGS="$(CFLAGS) -R $(LIBRPATH)"; \
        +	fi; \
        +	$(LINK_APP)
        +
        +# OpenServer 5 native compilers used
        +link_o.svr3:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		ALLSYMSFLAGS=''; \
        +		NOALLSYMSFLAGS=''; \
        +		SHAREDFLAGS="$(CFLAGS) -G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
        +	fi; \
        +	$(LINK_SO_O)
        +link_a.svr3:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		ALLSYMSFLAGS=''; \
        +		NOALLSYMSFLAGS=''; \
        +		SHAREDFLAGS="$(CFLAGS) -G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
        +	fi; \
        +	$(LINK_SO_A_UNPACKED)
        +link_app.svr3:
        +	@$(DETECT_GNU_LD) && $(DO_GNU_APP); \
        +	$(LINK_APP)
        +
        +# UnixWare 7 and OpenUNIX 8 native compilers used
        +link_o.svr5:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		SHARE_FLAG='-G'; \
        +		($(CC) -v 2>&1 | grep gcc) > /dev/null && SHARE_FLAG='-shared'; \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		ALLSYMSFLAGS=''; \
        +		NOALLSYMSFLAGS=''; \
        +		SHAREDFLAGS="$(CFLAGS) $${SHARE_FLAG} -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
        +	fi; \
        +	$(LINK_SO_O)
        +link_a.svr5:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		SHARE_FLAG='-G'; \
        +		($(CC) -v 2>&1 | grep gcc) > /dev/null && SHARE_FLAG='-shared'; \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		ALLSYMSFLAGS=''; \
        +		NOALLSYMSFLAGS=''; \
        +		SHAREDFLAGS="$(CFLAGS) $${SHARE_FLAG} -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \
        +	fi; \
        +	$(LINK_SO_A_UNPACKED)
        +link_app.svr5:
        +	@$(DETECT_GNU_LD) && $(DO_GNU_APP); \
        +	$(LINK_APP)
        +
        +link_o.irix:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		MINUSWL=""; \
        +		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSWL="-Wl,"; \
        +		ALLSYMSFLAGS="$${MINUSWL}-all"; \
        +		NOALLSYMSFLAGS="$${MINUSWL}-none"; \
        +		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,-B,symbolic"; \
        +	fi; \
        +	$(LINK_SO_O)
        +link_a.irix:
        +	@ if $(DETECT_GNU_LD); then \
        +		$(DO_GNU_SO); \
        +	else \
        +		$(CALC_VERSIONS); \
        +		SHLIB=lib$(LIBNAME).so; \
        +		SHLIB_SUFFIX=; \
        +		MINUSWL=""; \
        +		($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSWL="-Wl,"; \
        +		ALLSYMSFLAGS="$${MINUSWL}-all"; \
        +		NOALLSYMSFLAGS="$${MINUSWL}-none"; \
        +		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,-B,symbolic"; \
        +	fi; \
        +	$(LINK_SO_A)
        +link_app.irix:
        +	@LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"; \
        +	$(LINK_APP)
        +
        +# 32-bit PA-RISC HP-UX embeds the -L pathname of libs we link with, so
        +# we compensate for it with +cdp ../: and +cdp ./:. Yes, these rewrite
        +# rules imply that we can only link one level down in catalog structure,
        +# but that's what takes place for the moment of this writing. +cdp option
        +# was introduced in HP-UX 11.x and applies in 32-bit PA-RISC link
        +# editor context only [it's simply ignored in other cases, which are all
        +# ELFs by the way].
        +#
        +link_o.hpux:
        +	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
        +	$(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).sl; \
        +	expr "$(CFLAGS)" : '.*DSO_DLFCN' > /dev/null && SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS='-Wl,-Fl'; \
        +	NOALLSYMSFLAGS=''; \
        +	expr $(PLATFORM) : 'hpux64' > /dev/null && ALLSYMSFLAGS='-Wl,+forceload'; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-B,symbolic,+vnocompatwarnings,-z,+s,+h,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,+cdp,../:,+cdp,./:"; \
        +	fi; \
        +	rm -f $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX || :; \
        +	$(LINK_SO_O) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
        +link_a.hpux:
        +	@if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \
        +	$(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).sl; \
        +	expr $(PLATFORM) : '.*ia64' > /dev/null && SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS='-Wl,-Fl'; \
        +	NOALLSYMSFLAGS=''; \
        +	expr $(PLATFORM) : 'hpux64' > /dev/null && ALLSYMSFLAGS='-Wl,+forceload'; \
        +	SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-B,symbolic,+vnocompatwarnings,-z,+s,+h,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,+cdp,../:,+cdp,./:"; \
        +	fi; \
        +	rm -f $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX || :; \
        +	$(LINK_SO_A) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
        +link_app.hpux:
        +	@if $(DETECT_GNU_LD); then $(DO_GNU_APP); else \
        +	LDFLAGS="$(CFLAGS) -Wl,+s,+cdp,../:,+cdp,./:,+b,$(LIBRPATH)"; \
        +	fi; \
        +	$(LINK_APP)
        +
        +link_o.aix:
        +	@ $(CALC_VERSIONS); \
        +	OBJECT_MODE=`expr "x$(SHARED_LDFLAGS)" : 'x\-[a-z]*\(64\)'` || :; \
        +	OBJECT_MODE=$${OBJECT_MODE:-32}; export OBJECT_MODE; \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS=''; \
        +	NOALLSYMSFLAGS=''; \
        +	SHAREDFLAGS='$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-bexpall,-bnolibpath,-bM:SRE'; \
        +	$(LINK_SO_O);
        +link_a.aix:
        +	@ $(CALC_VERSIONS); \
        +	OBJECT_MODE=`expr "x$(SHARED_LDFLAGS)" : 'x\-[a-z]*\(64\)'` || : ; \
        +	OBJECT_MODE=$${OBJECT_MODE:-32}; export OBJECT_MODE; \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS='-bnogc'; \
        +	NOALLSYMSFLAGS=''; \
        +	SHAREDFLAGS='$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-bexpall,-bnolibpath,-bM:SRE'; \
        +	$(LINK_SO_A_VIA_O)
        +link_app.aix:
        +	LDFLAGS="$(CFLAGS) -Wl,-brtl,-blibpath:$(LIBRPATH):$${LIBPATH:-/usr/lib:/lib}"; \
        +	$(LINK_APP)
        +
        +link_o.reliantunix:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS=; \
        +	NOALLSYMSFLAGS=''; \
        +	SHAREDFLAGS='$(CFLAGS) -G'; \
        +	$(LINK_SO_O)
        +link_a.reliantunix:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).so; \
        +	SHLIB_SUFFIX=; \
        +	ALLSYMSFLAGS=; \
        +	NOALLSYMSFLAGS=''; \
        +	SHAREDFLAGS='$(CFLAGS) -G'; \
        +	$(LINK_SO_A_UNPACKED)
        +link_app.reliantunix:
        +	$(LINK_APP)
        +
        +# Targets to build symbolic links when needed
        +symlink.gnu symlink.solaris symlink.svr3 symlink.svr5 symlink.irix \
        +symlink.aix symlink.reliantunix:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).so; \
        +	$(SYMLINK_SO)
        +symlink.darwin:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME); \
        +	SHLIB_SUFFIX=.dylib; \
        +	$(SYMLINK_SO)
        +symlink.hpux:
        +	@ $(CALC_VERSIONS); \
        +	SHLIB=lib$(LIBNAME).sl; \
        +	expr $(PLATFORM) : '.*ia64' > /dev/null && SHLIB=lib$(LIBNAME).so; \
        +	$(SYMLINK_SO)
        +# The following lines means those specific architectures do no symlinks
        +symlink.cygwin symlink.alpha-osf1 symlink.tru64 symlink.tru64-rpath symlink.beos:
        +
        +# Compatibility targets
        +link_o.bsd-gcc-shared link_o.linux-shared link_o.gnu-shared: link_o.gnu
        +link_a.bsd-gcc-shared link_a.linux-shared link_a.gnu-shared: link_a.gnu
        +link_app.bsd-gcc-shared link_app.linux-shared link_app.gnu-shared: link_app.gnu
        +symlink.bsd-gcc-shared symlink.bsd-shared symlink.linux-shared symlink.gnu-shared: symlink.gnu
        +link_o.bsd-shared: link_o.bsd
        +link_a.bsd-shared: link_a.bsd
        +link_app.bsd-shared: link_app.bsd
        +link_o.darwin-shared: link_o.darwin
        +link_a.darwin-shared: link_a.darwin
        +link_app.darwin-shared: link_app.darwin
        +symlink.darwin-shared: symlink.darwin
        +link_o.cygwin-shared: link_o.cygwin
        +link_a.cygwin-shared: link_a.cygwin
        +link_app.cygwin-shared: link_app.cygwin
        +symlink.cygwin-shared: symlink.cygwin
        +link_o.alpha-osf1-shared: link_o.alpha-osf1
        +link_a.alpha-osf1-shared: link_a.alpha-osf1
        +link_app.alpha-osf1-shared: link_app.alpha-osf1
        +symlink.alpha-osf1-shared: symlink.alpha-osf1
        +link_o.tru64-shared: link_o.tru64
        +link_a.tru64-shared: link_a.tru64
        +link_app.tru64-shared: link_app.tru64
        +symlink.tru64-shared: symlink.tru64
        +link_o.tru64-shared-rpath: link_o.tru64-rpath
        +link_a.tru64-shared-rpath: link_a.tru64-rpath
        +link_app.tru64-shared-rpath: link_app.tru64-rpath
        +symlink.tru64-shared-rpath: symlink.tru64-rpath
        +link_o.solaris-shared: link_o.solaris
        +link_a.solaris-shared: link_a.solaris
        +link_app.solaris-shared: link_app.solaris
        +symlink.solaris-shared: symlink.solaris
        +link_o.svr3-shared: link_o.svr3
        +link_a.svr3-shared: link_a.svr3
        +link_app.svr3-shared: link_app.svr3
        +symlink.svr3-shared: symlink.svr3
        +link_o.svr5-shared: link_o.svr5
        +link_a.svr5-shared: link_a.svr5
        +link_app.svr5-shared: link_app.svr5
        +symlink.svr5-shared: symlink.svr5
        +link_o.irix-shared: link_o.irix
        +link_a.irix-shared: link_a.irix
        +link_app.irix-shared: link_app.irix
        +symlink.irix-shared: symlink.irix
        +link_o.hpux-shared: link_o.hpux
        +link_a.hpux-shared: link_a.hpux
        +link_app.hpux-shared: link_app.hpux
        +symlink.hpux-shared: symlink.hpux
        +link_o.aix-shared: link_o.aix
        +link_a.aix-shared: link_a.aix
        +link_app.aix-shared: link_app.aix
        +symlink.aix-shared: symlink.aix
        +link_o.reliantunix-shared: link_o.reliantunix
        +link_a.reliantunix-shared: link_a.reliantunix
        +link_app.reliantunix-shared: link_app.reliantunix
        +symlink.reliantunix-shared: symlink.reliantunix
        +link_o.beos-shared: link_o.beos
        +link_a.beos-shared: link_a.beos
        +link_app.beos-shared: link_app.gnu
        +symlink.beos-shared: symlink.beos
        diff --git a/vendor/openssl/openssl/NEWS b/vendor/openssl/openssl/NEWS
        new file mode 100644
        index 000000000..0269f2277
        --- /dev/null
        +++ b/vendor/openssl/openssl/NEWS
        @@ -0,0 +1,656 @@
        +
        +  NEWS
        +  ====
        +
        +  This file gives a brief overview of the major changes between each OpenSSL
        +  release. For more details please read the CHANGES file.
        +
        +  Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e:
        +
        +      o Corrected fix for CVE-2013-0169
        +
        +  Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d:
        +
        +      o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version.
        +      o Include the fips configuration module.
        +      o Fix OCSP bad key DoS attack CVE-2013-0166
        +      o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169
        +      o Fix for TLS AESNI record handling flaw CVE-2012-2686
        +
        +  Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c:
        +
        +      o Fix TLS/DTLS record length checking bug CVE-2012-2333
        +      o Don't attempt to use non-FIPS composite ciphers in FIPS mode.
        +
        +  Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b:
        +
        +      o Fix compilation error on non-x86 platforms.
        +      o Make FIPS capable OpenSSL ciphers work in non-FIPS mode.
        +      o Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0
        +
        +  Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a:
        +
        +      o Fix for ASN1 overflow bug CVE-2012-2110
        +      o Workarounds for some servers that hang on long client hellos.
        +      o Fix SEGV in AES code.
        +
        +  Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1:
        +
        +      o TLS/DTLS heartbeat support.
        +      o SCTP support.
        +      o RFC 5705 TLS key material exporter.
        +      o RFC 5764 DTLS-SRTP negotiation.
        +      o Next Protocol Negotiation.
        +      o PSS signatures in certificates, requests and CRLs.
        +      o Support for password based recipient info for CMS.
        +      o Support TLS v1.2 and TLS v1.1.
        +      o Preliminary FIPS capability for unvalidated 2.0 FIPS module.
        +      o SRP support.
        +
        +  Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h:
        +
        +      o Fix for CMS/PKCS#7 MMA CVE-2012-0884
        +      o Corrected fix for CVE-2011-4619
        +      o Various DTLS fixes.
        +
        +  Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g:
        +
        +      o Fix for DTLS DoS issue CVE-2012-0050
        +
        +  Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f:
        +
        +      o Fix for DTLS plaintext recovery attack CVE-2011-4108
        +      o Clear block padding bytes of SSL 3.0 records CVE-2011-4576
        +      o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619
        +      o Check parameters are not NULL in GOST ENGINE CVE-2012-0027
        +      o Check for malformed RFC3779 data CVE-2011-4577
        +
        +  Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e:
        +
        +      o Fix for CRL vulnerability issue CVE-2011-3207
        +      o Fix for ECDH crashes CVE-2011-3210
        +      o Protection against EC timing attacks.
        +      o Support ECDH ciphersuites for certificates using SHA2 algorithms.
        +      o Various DTLS fixes.
        +
        +  Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d:
        +
        +      o Fix for security issue CVE-2011-0014
        +
        +  Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c:
        +
        +      o Fix for security issue CVE-2010-4180
        +      o Fix for CVE-2010-4252
        +      o Fix mishandling of absent EC point format extension.
        +      o Fix various platform compilation issues.
        +      o Corrected fix for security issue CVE-2010-3864.
        +
        +  Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b:
        +
        +      o Fix for security issue CVE-2010-3864.
        +      o Fix for CVE-2010-2939
        +      o Fix WIN32 build system for GOST ENGINE.
        +
        +  Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a:
        +
        +      o Fix for security issue CVE-2010-1633.
        +      o GOST MAC and CFB fixes.
        +
        +  Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0:
        +
        +      o RFC3280 path validation: sufficient to process PKITS tests.
        +      o Integrated support for PVK files and keyblobs.
        +      o Change default private key format to PKCS#8.
        +      o CMS support: able to process all examples in RFC4134
        +      o Streaming ASN1 encode support for PKCS#7 and CMS.
        +      o Multiple signer and signer add support for PKCS#7 and CMS.
        +      o ASN1 printing support.
        +      o Whirlpool hash algorithm added.
        +      o RFC3161 time stamp support.
        +      o New generalised public key API supporting ENGINE based algorithms.
        +      o New generalised public key API utilities.
        +      o New ENGINE supporting GOST algorithms.
        +      o SSL/TLS GOST ciphersuite support.
        +      o PKCS#7 and CMS GOST support.
        +      o RFC4279 PSK ciphersuite support.
        +      o Supported points format extension for ECC ciphersuites.
        +      o ecdsa-with-SHA224/256/384/512 signature types.
        +      o dsa-with-SHA224 and dsa-with-SHA256 signature types.
        +      o Opaque PRF Input TLS extension support.
        +      o Updated time routines to avoid OS limitations.
        +
        +  Major changes between OpenSSL 0.9.8q and OpenSSL 0.9.8r:
        +
        +      o Fix for security issue CVE-2011-0014
        +
        +  Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
        +
        +      o Fix for security issue CVE-2010-4180
        +      o Fix for CVE-2010-4252
        +
        +  Major changes between OpenSSL 0.9.8o and OpenSSL 0.9.8p:
        +
        +      o Fix for security issue CVE-2010-3864.
        +
        +  Major changes between OpenSSL 0.9.8n and OpenSSL 0.9.8o:
        +
        +      o Fix for security issue CVE-2010-0742.
        +      o Various DTLS fixes.
        +      o Recognise SHA2 certificates if only SSL algorithms added.
        +      o Fix for no-rc4 compilation.
        +      o Chil ENGINE unload workaround.
        +
        +  Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n:
        +
        +      o CFB cipher definition fixes.
        +      o Fix security issues CVE-2010-0740 and CVE-2010-0433.
        +
        +  Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m:
        +
        +      o Cipher definition fixes.
        +      o Workaround for slow RAND_poll() on some WIN32 versions.
        +      o Remove MD2 from algorithm tables.
        +      o SPKAC handling fixes.
        +      o Support for RFC5746 TLS renegotiation extension.
        +      o Compression memory leak fixed.
        +      o Compression session resumption fixed.
        +      o Ticket and SNI coexistence fixes.
        +      o Many fixes to DTLS handling. 
        +
        +  Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l:
        +
        +      o Temporary work around for CVE-2009-3555: disable renegotiation.
        +
        +  Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k:
        +
        +      o Fix various build issues.
        +      o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789)
        +
        +  Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j:
        +
        +      o Fix security issue (CVE-2008-5077)
        +      o Merge FIPS 140-2 branch code.
        +
        +  Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h:
        +
        +      o CryptoAPI ENGINE support.
        +      o Various precautionary measures.
        +      o Fix for bugs affecting certificate request creation.
        +      o Support for local machine keyset attribute in PKCS#12 files.
        +
        +  Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g:
        +
        +      o Backport of CMS functionality to 0.9.8.
        +      o Fixes for bugs introduced with 0.9.8f.
        +
        +  Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f:
        +
        +      o Add gcc 4.2 support.
        +      o Add support for AES and SSE2 assembly lanugauge optimization
        +        for VC++ build.
        +      o Support for RFC4507bis and server name extensions if explicitly 
        +        selected at compile time.
        +      o DTLS improvements.
        +      o RFC4507bis support.
        +      o TLS Extensions support.
        +
        +  Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e:
        +
        +      o Various ciphersuite selection fixes.
        +      o RFC3779 support.
        +
        +  Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d:
        +
        +      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
        +      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
        +      o Changes to ciphersuite selection algorithm
        +
        +  Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c:
        +
        +      o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
        +      o New cipher Camellia
        +
        +  Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b:
        +
        +      o Cipher string fixes.
        +      o Fixes for VC++ 2005.
        +      o Updated ECC cipher suite support.
        +      o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free().
        +      o Zlib compression usage fixes.
        +      o Built in dynamic engine compilation support on Win32.
        +      o Fixes auto dynamic engine loading in Win32.
        +
        +  Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a:
        +
        +      o Fix potential SSL 2.0 rollback, CVE-2005-2969
        +      o Extended Windows CE support
        +
        +  Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8:
        +
        +      o Major work on the BIGNUM library for higher efficiency and to
        +        make operations more streamlined and less contradictory.  This
        +        is the result of a major audit of the BIGNUM library.
        +      o Addition of BIGNUM functions for fields GF(2^m) and NIST
        +        curves, to support the Elliptic Crypto functions.
        +      o Major work on Elliptic Crypto; ECDH and ECDSA added, including
        +        the use through EVP, X509 and ENGINE.
        +      o New ASN.1 mini-compiler that's usable through the OpenSSL
        +        configuration file.
        +      o Added support for ASN.1 indefinite length constructed encoding.
        +      o New PKCS#12 'medium level' API to manipulate PKCS#12 files.
        +      o Complete rework of shared library construction and linking
        +        programs with shared or static libraries, through a separate
        +        Makefile.shared.
        +      o Rework of the passing of parameters from one Makefile to another.
        +      o Changed ENGINE framework to load dynamic engine modules
        +        automatically from specifically given directories.
        +      o New structure and ASN.1 functions for CertificatePair.
        +      o Changed the ZLIB compression method to be stateful.
        +      o Changed the key-generation and primality testing "progress"
        +        mechanism to take a structure that contains the ticker
        +        function and an argument.
        +      o New engine module: GMP (performs private key exponentiation).
        +      o New engine module: VIA PadLOck ACE extension in VIA C3
        +        Nehemiah processors.
        +      o Added support for IPv6 addresses in certificate extensions.
        +        See RFC 1884, section 2.2.
        +      o Added support for certificate policy mappings, policy
        +        constraints and name constraints.
        +      o Added support for multi-valued AVAs in the OpenSSL
        +        configuration file.
        +      o Added support for multiple certificates with the same subject
        +        in the 'openssl ca' index file.
        +      o Make it possible to create self-signed certificates using
        +        'openssl ca -selfsign'.
        +      o Make it possible to generate a serial number file with
        +        'openssl ca -create_serial'.
        +      o New binary search functions with extended functionality.
        +      o New BUF functions.
        +      o New STORE structure and library to provide an interface to all
        +        sorts of data repositories.  Supports storage of public and
        +        private keys, certificates, CRLs, numbers and arbitrary blobs.
        +	This library is unfortunately unfinished and unused withing
        +	OpenSSL.
        +      o New control functions for the error stack.
        +      o Changed the PKCS#7 library to support one-pass S/MIME
        +        processing.
        +      o Added the possibility to compile without old deprecated
        +        functionality with the OPENSSL_NO_DEPRECATED macro or the
        +        'no-deprecated' argument to the config and Configure scripts.
        +      o Constification of all ASN.1 conversion functions, and other
        +        affected functions.
        +      o Improved platform support for PowerPC.
        +      o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512).
        +      o New X509_VERIFY_PARAM structure to support parametrisation
        +        of X.509 path validation.
        +      o Major overhaul of RC4 performance on Intel P4, IA-64 and
        +        AMD64.
        +      o Changed the Configure script to have some algorithms disabled
        +        by default.  Those can be explicitely enabled with the new
        +        argument form 'enable-xxx'.
        +      o Change the default digest in 'openssl' commands from MD5 to
        +        SHA-1.
        +      o Added support for DTLS.
        +      o New BIGNUM blinding.
        +      o Added support for the RSA-PSS encryption scheme
        +      o Added support for the RSA X.931 padding.
        +      o Added support for BSD sockets on NetWare.
        +      o Added support for files larger than 2GB.
        +      o Added initial support for Win64.
        +      o Added alternate pkg-config files.
        +
        +  Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m:
        +
        +      o FIPS 1.1.1 module linking.
        +      o Various ciphersuite selection fixes.
        +
        +  Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l:
        +
        +      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
        +      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
        +
        +  Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k:
        +
        +      o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
        +
        +  Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j:
        +
        +      o Visual C++ 2005 fixes.
        +      o Update Windows build system for FIPS.
        +
        +  Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i:
        +
        +      o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
        +
        +  Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h:
        +
        +      o Fix SSL 2.0 Rollback, CVE-2005-2969
        +      o Allow use of fixed-length exponent on DSA signing
        +      o Default fixed-window RSA, DSA, DH private-key operations
        +
        +  Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g:
        +
        +      o More compilation issues fixed.
        +      o Adaptation to more modern Kerberos API.
        +      o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin.
        +      o Enhanced x86_64 assembler BIGNUM module.
        +      o More constification.
        +      o Added processing of proxy certificates (RFC 3820).
        +
        +  Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f:
        +
        +      o Several compilation issues fixed.
        +      o Many memory allocation failure checks added.
        +      o Improved comparison of X509 Name type.
        +      o Mandatory basic checks on certificates.
        +      o Performance improvements.
        +
        +  Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e:
        +
        +      o Fix race condition in CRL checking code.
        +      o Fixes to PKCS#7 (S/MIME) code.
        +
        +  Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d:
        +
        +      o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug
        +      o Security: Fix null-pointer assignment in do_change_cipher_spec()
        +      o Allow multiple active certificates with same subject in CA index
        +      o Multiple X509 verification fixes
        +      o Speed up HMAC and other operations
        +
        +  Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c:
        +
        +      o Security: fix various ASN1 parsing bugs.
        +      o New -ignore_err option to OCSP utility.
        +      o Various interop and bug fixes in S/MIME code.
        +      o SSL/TLS protocol fix for unrequested client certificates.
        +
        +  Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b:
        +
        +      o Security: counter the Klima-Pokorny-Rosa extension of
        +        Bleichbacher's attack 
        +      o Security: make RSA blinding default.
        +      o Configuration: Irix fixes, AIX fixes, better mingw support.
        +      o Support for new platforms: linux-ia64-ecc.
        +      o Build: shared library support fixes.
        +      o ASN.1: treat domainComponent correctly.
        +      o Documentation: fixes and additions.
        +
        +  Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a:
        +
        +      o Security: Important security related bugfixes.
        +      o Enhanced compatibility with MIT Kerberos.
        +      o Can be built without the ENGINE framework.
        +      o IA32 assembler enhancements.
        +      o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64.
        +      o Configuration: the no-err option now works properly.
        +      o SSL/TLS: now handles manual certificate chain building.
        +      o SSL/TLS: certain session ID malfunctions corrected.
        +
        +  Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7:
        +
        +      o New library section OCSP.
        +      o Complete rewrite of ASN1 code.
        +      o CRL checking in verify code and openssl utility.
        +      o Extension copying in 'ca' utility.
        +      o Flexible display options in 'ca' utility.
        +      o Provisional support for international characters with UTF8.
        +      o Support for external crypto devices ('engine') is no longer
        +        a separate distribution.
        +      o New elliptic curve library section.
        +      o New AES (Rijndael) library section.
        +      o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit,
        +        Linux x86_64, Linux 64-bit on Sparc v9
        +      o Extended support for some platforms: VxWorks
        +      o Enhanced support for shared libraries.
        +      o Now only builds PIC code when shared library support is requested.
        +      o Support for pkg-config.
        +      o Lots of new manuals.
        +      o Makes symbolic links to or copies of manuals to cover all described
        +        functions.
        +      o Change DES API to clean up the namespace (some applications link also
        +        against libdes providing similar functions having the same name).
        +        Provide macros for backward compatibility (will be removed in the
        +        future).
        +      o Unify handling of cryptographic algorithms (software and engine)
        +        to be available via EVP routines for asymmetric and symmetric ciphers.
        +      o NCONF: new configuration handling routines.
        +      o Change API to use more 'const' modifiers to improve error checking
        +        and help optimizers.
        +      o Finally remove references to RSAref.
        +      o Reworked parts of the BIGNUM code.
        +      o Support for new engines: Broadcom ubsec, Accelerated Encryption
        +        Processing, IBM 4758.
        +      o A few new engines added in the demos area.
        +      o Extended and corrected OID (object identifier) table.
        +      o PRNG: query at more locations for a random device, automatic query for
        +        EGD style random sources at several locations.
        +      o SSL/TLS: allow optional cipher choice according to server's preference.
        +      o SSL/TLS: allow server to explicitly set new session ids.
        +      o SSL/TLS: support Kerberos cipher suites (RFC2712).
        +	Only supports MIT Kerberos for now.
        +      o SSL/TLS: allow more precise control of renegotiations and sessions.
        +      o SSL/TLS: add callback to retrieve SSL/TLS messages.
        +      o SSL/TLS: support AES cipher suites (RFC3268).
        +
        +  Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k:
        +
        +      o Security: fix various ASN1 parsing bugs.
        +      o SSL/TLS protocol fix for unrequested client certificates.
        +
        +  Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j:
        +
        +      o Security: counter the Klima-Pokorny-Rosa extension of
        +        Bleichbacher's attack 
        +      o Security: make RSA blinding default.
        +      o Build: shared library support fixes.
        +
        +  Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i:
        +
        +      o Important security related bugfixes.
        +
        +  Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h:
        +
        +      o New configuration targets for Tandem OSS and A/UX.
        +      o New OIDs for Microsoft attributes.
        +      o Better handling of SSL session caching.
        +      o Better comparison of distinguished names.
        +      o Better handling of shared libraries in a mixed GNU/non-GNU environment.
        +      o Support assembler code with Borland C.
        +      o Fixes for length problems.
        +      o Fixes for uninitialised variables.
        +      o Fixes for memory leaks, some unusual crashes and some race conditions.
        +      o Fixes for smaller building problems.
        +      o Updates of manuals, FAQ and other instructive documents.
        +
        +  Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g:
        +
        +      o Important building fixes on Unix.
        +
        +  Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f:
        +
        +      o Various important bugfixes.
        +
        +  Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e:
        +
        +      o Important security related bugfixes.
        +      o Various SSL/TLS library bugfixes.
        +
        +  Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d:
        +
        +      o Various SSL/TLS library bugfixes.
        +      o Fix DH parameter generation for 'non-standard' generators.
        +
        +  Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c:
        +
        +      o Various SSL/TLS library bugfixes.
        +      o BIGNUM library fixes.
        +      o RSA OAEP and random number generation fixes.
        +      o Object identifiers corrected and added.
        +      o Add assembler BN routines for IA64.
        +      o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8,
        +        MIPS Linux; shared library support for Irix, HP-UX.
        +      o Add crypto accelerator support for AEP, Baltimore SureWare,
        +        Broadcom and Cryptographic Appliance's keyserver
        +        [in 0.9.6c-engine release].
        +
        +  Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b:
        +
        +      o Security fix: PRNG improvements.
        +      o Security fix: RSA OAEP check.
        +      o Security fix: Reinsert and fix countermeasure to Bleichbacher's
        +        attack.
        +      o MIPS bug fix in BIGNUM.
        +      o Bug fix in "openssl enc".
        +      o Bug fix in X.509 printing routine.
        +      o Bug fix in DSA verification routine and DSA S/MIME verification.
        +      o Bug fix to make PRNG thread-safe.
        +      o Bug fix in RAND_file_name().
        +      o Bug fix in compatibility mode trust settings.
        +      o Bug fix in blowfish EVP.
        +      o Increase default size for BIO buffering filter.
        +      o Compatibility fixes in some scripts.
        +
        +  Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a:
        +
        +      o Security fix: change behavior of OpenSSL to avoid using
        +        environment variables when running as root.
        +      o Security fix: check the result of RSA-CRT to reduce the
        +        possibility of deducing the private key from an incorrectly
        +        calculated signature.
        +      o Security fix: prevent Bleichenbacher's DSA attack.
        +      o Security fix: Zero the premaster secret after deriving the
        +        master secret in DH ciphersuites.
        +      o Reimplement SSL_peek(), which had various problems.
        +      o Compatibility fix: the function des_encrypt() renamed to
        +        des_encrypt1() to avoid clashes with some Unixen libc.
        +      o Bug fixes for Win32, HP/UX and Irix.
        +      o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and
        +        memory checking routines.
        +      o Bug fixes for RSA operations in threaded environments.
        +      o Bug fixes in misc. openssl applications.
        +      o Remove a few potential memory leaks.
        +      o Add tighter checks of BIGNUM routines.
        +      o Shared library support has been reworked for generality.
        +      o More documentation.
        +      o New function BN_rand_range().
        +      o Add "-rand" option to openssl s_client and s_server.
        +
        +  Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6:
        +
        +      o Some documentation for BIO and SSL libraries.
        +      o Enhanced chain verification using key identifiers.
        +      o New sign and verify options to 'dgst' application.
        +      o Support for DER and PEM encoded messages in 'smime' application.
        +      o New 'rsautl' application, low level RSA utility.
        +      o MD4 now included.
        +      o Bugfix for SSL rollback padding check.
        +      o Support for external crypto devices [1].
        +      o Enhanced EVP interface.
        +
        +    [1] The support for external crypto devices is currently a separate
        +        distribution.  See the file README.ENGINE.
        +
        +  Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a:
        +
        +      o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8 
        +      o Shared library support for HPUX and Solaris-gcc
        +      o Support of Linux/IA64
        +      o Assembler support for Mingw32
        +      o New 'rand' application
        +      o New way to check for existence of algorithms from scripts
        +
        +  Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5:
        +
        +      o S/MIME support in new 'smime' command
        +      o Documentation for the OpenSSL command line application
        +      o Automation of 'req' application
        +      o Fixes to make s_client, s_server work under Windows
        +      o Support for multiple fieldnames in SPKACs
        +      o New SPKAC command line utilty and associated library functions
        +      o Options to allow passwords to be obtained from various sources
        +      o New public key PEM format and options to handle it
        +      o Many other fixes and enhancements to command line utilities
        +      o Usable certificate chain verification
        +      o Certificate purpose checking
        +      o Certificate trust settings
        +      o Support of authority information access extension
        +      o Extensions in certificate requests
        +      o Simplified X509 name and attribute routines
        +      o Initial (incomplete) support for international character sets
        +      o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD
        +      o Read only memory BIOs and simplified creation function
        +      o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0
        +        record; allow fragmentation and interleaving of handshake and other
        +        data
        +      o TLS/SSL code now "tolerates" MS SGC
        +      o Work around for Netscape client certificate hang bug
        +      o RSA_NULL option that removes RSA patent code but keeps other
        +        RSA functionality
        +      o Memory leak detection now allows applications to add extra information
        +        via a per-thread stack
        +      o PRNG robustness improved
        +      o EGD support
        +      o BIGNUM library bug fixes
        +      o Faster DSA parameter generation
        +      o Enhanced support for Alpha Linux
        +      o Experimental MacOS support
        +
        +  Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4:
        +
        +      o Transparent support for PKCS#8 format private keys: these are used
        +        by several software packages and are more secure than the standard
        +        form
        +      o PKCS#5 v2.0 implementation
        +      o Password callbacks have a new void * argument for application data
        +      o Avoid various memory leaks
        +      o New pipe-like BIO that allows using the SSL library when actual I/O
        +        must be handled by the application (BIO pair)
        +
        +  Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3:
        +      o Lots of enhancements and cleanups to the Configuration mechanism
        +      o RSA OEAP related fixes
        +      o Added `openssl ca -revoke' option for revoking a certificate
        +      o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs
        +      o Source tree cleanups: removed lots of obsolete files
        +      o Thawte SXNet, certificate policies and CRL distribution points
        +        extension support
        +      o Preliminary (experimental) S/MIME support
        +      o Support for ASN.1 UTF8String and VisibleString
        +      o Full integration of PKCS#12 code
        +      o Sparc assembler bignum implementation, optimized hash functions
        +      o Option to disable selected ciphers
        +
        +  Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b:
        +      o Fixed a security hole related to session resumption
        +      o Fixed RSA encryption routines for the p < q case
        +      o "ALL" in cipher lists now means "everything except NULL ciphers"
        +      o Support for Triple-DES CBCM cipher
        +      o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA
        +      o First support for new TLSv1 ciphers
        +      o Added a few new BIOs (syslog BIO, reliable BIO)
        +      o Extended support for DSA certificate/keys.
        +      o Extended support for Certificate Signing Requests (CSR)
        +      o Initial support for X.509v3 extensions
        +      o Extended support for compression inside the SSL record layer
        +      o Overhauled Win32 builds
        +      o Cleanups and fixes to the Big Number (BN) library
        +      o Support for ASN.1 GeneralizedTime
        +      o Splitted ASN.1 SETs from SEQUENCEs
        +      o ASN1 and PEM support for Netscape Certificate Sequences
        +      o Overhauled Perl interface
        +      o Lots of source tree cleanups.
        +      o Lots of memory leak fixes.
        +      o Lots of bug fixes.
        +
        +  Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c:
        +      o Integration of the popular NO_RSA/NO_DSA patches
        +      o Initial support for compression inside the SSL record layer
        +      o Added BIO proxy and filtering functionality
        +      o Extended Big Number (BN) library
        +      o Added RIPE MD160 message digest
        +      o Addeed support for RC2/64bit cipher
        +      o Extended ASN.1 parser routines
        +      o Adjustations of the source tree for CVS
        +      o Support for various new platforms
        +
        diff --git a/vendor/openssl/openssl/Netware/build.bat b/vendor/openssl/openssl/Netware/build.bat
        new file mode 100644
        index 000000000..3125c2a48
        --- /dev/null
        +++ b/vendor/openssl/openssl/Netware/build.bat
        @@ -0,0 +1,235 @@
        +@echo off
        +
        +rem ========================================================================
        +rem   Batch file to automate building OpenSSL for NetWare.
        +rem
        +rem   usage:
        +rem      build [target] [debug opts] [assembly opts] [configure opts]
        +rem
        +rem      target        - "netware-clib" - CLib NetWare build (WinSock Sockets)
        +rem                    - "netware-clib-bsdsock" - CLib NetWare build (BSD Sockets)
        +rem                    - "netware-libc" - LibC NetWare build (WinSock Sockets)
        +rem                    - "netware-libc-bsdsock" - LibC NetWare build (BSD Sockets)
        +rem 
        +rem      debug opts    - "debug"  - build debug
        +rem
        +rem      assembly opts - "nw-mwasm" - use Metrowerks assembler
        +rem                    - "nw-nasm"  - use NASM assembler
        +rem                    - "no-asm"   - don't use assembly
        +rem
        +rem      configure opts- all unrecognized arguments are passed to the
        +rem                       perl configure script
        +rem
        +rem   If no arguments are specified the default is to build non-debug with
        +rem   no assembly.  NOTE: there is no default BLD_TARGET.
        +rem
        +
        +
        +
        +rem   No assembly is the default - Uncomment section below to change
        +rem   the assembler default
        +set ASM_MODE=
        +set ASSEMBLER=
        +set NO_ASM=no-asm
        +
        +rem   Uncomment to default to the Metrowerks assembler
        +rem set ASM_MODE=nw-mwasm
        +rem set ASSEMBLER=Metrowerks
        +rem set NO_ASM=
        +
        +rem   Uncomment to default to the NASM assembler
        +rem set ASM_MODE=nw-nasm
        +rem set ASSEMBLER=NASM
        +rem set NO_ASM=
        +
        +rem   No default Bld target
        +set BLD_TARGET=no_target
        +rem set BLD_TARGET=netware-clib
        +rem set BLD_TARGET=netware-libc
        +
        +
        +rem   Default to build non-debug
        +set DEBUG=
        +                                    
        +rem   Uncomment to default to debug build
        +rem set DEBUG=debug
        +
        +
        +set CONFIG_OPTS=
        +set ARG_PROCESSED=NO
        +
        +
        +rem   Process command line args
        +:opts
        +if "a%1" == "a" goto endopt
        +if "%1" == "no-asm"   set NO_ASM=no-asm
        +if "%1" == "no-asm"   set ARG_PROCESSED=YES
        +if "%1" == "debug"    set DEBUG=debug
        +if "%1" == "debug"    set ARG_PROCESSED=YES
        +if "%1" == "nw-nasm"  set ASM_MODE=nw-nasm
        +if "%1" == "nw-nasm"  set ASSEMBLER=NASM
        +if "%1" == "nw-nasm"  set NO_ASM=
        +if "%1" == "nw-nasm"  set ARG_PROCESSED=YES
        +if "%1" == "nw-mwasm" set ASM_MODE=nw-mwasm
        +if "%1" == "nw-mwasm" set ASSEMBLER=Metrowerks
        +if "%1" == "nw-mwasm" set NO_ASM=
        +if "%1" == "nw-mwasm" set ARG_PROCESSED=YES
        +if "%1" == "netware-clib" set BLD_TARGET=netware-clib
        +if "%1" == "netware-clib" set ARG_PROCESSED=YES
        +if "%1" == "netware-clib-bsdsock" set BLD_TARGET=netware-clib-bsdsock
        +if "%1" == "netware-clib-bsdsock" set ARG_PROCESSED=YES
        +if "%1" == "netware-libc" set BLD_TARGET=netware-libc
        +if "%1" == "netware-libc" set ARG_PROCESSED=YES
        +if "%1" == "netware-libc-bsdsock" set BLD_TARGET=netware-libc-bsdsock
        +if "%1" == "netware-libc-bsdsock" set ARG_PROCESSED=YES
        +
        +rem   If we didn't recognize the argument, consider it an option for config
        +if "%ARG_PROCESSED%" == "NO" set CONFIG_OPTS=%CONFIG_OPTS% %1
        +if "%ARG_PROCESSED%" == "YES" set ARG_PROCESSED=NO
        +
        +shift
        +goto opts
        +:endopt
        +
        +rem make sure a valid BLD_TARGET was specified
        +if "%BLD_TARGET%" == "no_target" goto no_target
        +
        +rem build the nlm make file name which includes target and debug info
        +set NLM_MAKE=
        +if "%BLD_TARGET%" == "netware-clib" set NLM_MAKE=netware\nlm_clib
        +if "%BLD_TARGET%" == "netware-clib-bsdsock" set NLM_MAKE=netware\nlm_clib_bsdsock
        +if "%BLD_TARGET%" == "netware-libc" set NLM_MAKE=netware\nlm_libc
        +if "%BLD_TARGET%" == "netware-libc-bsdsock" set NLM_MAKE=netware\nlm_libc_bsdsock
        +if "%DEBUG%" == "" set NLM_MAKE=%NLM_MAKE%.mak
        +if "%DEBUG%" == "debug" set NLM_MAKE=%NLM_MAKE%_dbg.mak
        +
        +if "%NO_ASM%" == "no-asm" set ASM_MODE=
        +if "%NO_ASM%" == "no-asm" set ASSEMBLER=
        +if "%NO_ASM%" == "no-asm" set CONFIG_OPTS=%CONFIG_OPTS% no-asm
        +if "%NO_ASM%" == "no-asm" goto do_config
        +
        +
        +rem ==================================================
        +echo Generating x86 for %ASSEMBLER% assembler
        +
        +echo Bignum
        +cd crypto\bn\asm
        +rem perl x86.pl %ASM_MODE% > bn-nw.asm
        +perl bn-586.pl %ASM_MODE% > bn-nw.asm
        +perl co-586.pl %ASM_MODE% > co-nw.asm
        +cd ..\..\..
        +
        +echo AES
        +cd crypto\aes\asm
        +perl aes-586.pl %ASM_MODE% > a-nw.asm
        +cd ..\..\..
        +
        +echo DES
        +cd crypto\des\asm
        +perl des-586.pl %ASM_MODE% > d-nw.asm
        +cd ..\..\..
        +
        +echo "crypt(3)"
        +
        +cd crypto\des\asm
        +perl crypt586.pl %ASM_MODE% > y-nw.asm
        +cd ..\..\..
        +
        +echo Blowfish
        +
        +cd crypto\bf\asm
        +perl bf-586.pl %ASM_MODE% > b-nw.asm
        +cd ..\..\..
        +
        +echo CAST5
        +cd crypto\cast\asm
        +perl cast-586.pl %ASM_MODE% > c-nw.asm
        +cd ..\..\..
        +
        +echo RC4
        +cd crypto\rc4\asm
        +perl rc4-586.pl %ASM_MODE% > r4-nw.asm
        +cd ..\..\..
        +
        +echo MD5
        +cd crypto\md5\asm
        +perl md5-586.pl %ASM_MODE% > m5-nw.asm
        +cd ..\..\..
        +
        +echo SHA1
        +cd crypto\sha\asm
        +perl sha1-586.pl %ASM_MODE% > s1-nw.asm
        +perl sha256-586.pl %ASM_MODE% > sha256-nw.asm
        +perl sha512-586.pl %ASM_MODE% > sha512-nw.asm
        +cd ..\..\..
        +
        +echo RIPEMD160
        +cd crypto\ripemd\asm
        +perl rmd-586.pl %ASM_MODE% > rm-nw.asm
        +cd ..\..\..
        +
        +echo RC5\32
        +cd crypto\rc5\asm
        +perl rc5-586.pl %ASM_MODE% > r5-nw.asm
        +cd ..\..\..
        +
        +echo WHIRLPOOL
        +cd crypto\whrlpool\asm
        +perl wp-mmx.pl %ASM_MODE% > wp-nw.asm
        +cd ..\..\..
        +
        +echo CPUID
        +cd crypto
        +perl x86cpuid.pl %ASM_MODE% > x86cpuid-nw.asm
        +cd ..\
        +
        +rem ===============================================================
        +rem
        +:do_config
        +
        +echo .
        +echo configure options: %CONFIG_OPTS% %BLD_TARGET%
        +echo .
        +perl configure %CONFIG_OPTS% %BLD_TARGET%
        +
        +perl util\mkfiles.pl >MINFO
        +
        +echo .
        +echo mk1mf.pl options: %DEBUG% %ASM_MODE% %CONFIG_OPTS% %BLD_TARGET%
        +echo .
        +perl util\mk1mf.pl %DEBUG% %ASM_MODE% %CONFIG_OPTS% %BLD_TARGET% >%NLM_MAKE%
        +
        +make -f %NLM_MAKE% vclean
        +echo .
        +echo The makefile "%NLM_MAKE%" has been created use your maketool to
        +echo build (ex: make -f %NLM_MAKE%)
        +goto end
        +
        +rem ===============================================================
        +rem
        +:no_target
        +echo .
        +echo .  No build target specified!!!
        +echo .
        +echo .  usage: build [target] [debug opts] [assembly opts] [configure opts]
        +echo .
        +echo .     target        - "netware-clib" - CLib NetWare build (WinSock Sockets)
        +echo .                   - "netware-clib-bsdsock" - CLib NetWare build (BSD Sockets)
        +echo .                   - "netware-libc" - LibC NetWare build (WinSock Sockets)
        +echo .                   - "netware-libc-bsdsock" - LibC NetWare build (BSD Sockets)
        +echo .
        +echo .     debug opts    - "debug"  - build debug
        +echo .
        +echo .     assembly opts - "nw-mwasm" - use Metrowerks assembler
        +echo .                     "nw-nasm"  - use NASM assembler
        +echo .                     "no-asm"   - don't use assembly
        +echo .
        +echo .     configure opts- all unrecognized arguments are passed to the
        +echo .                      perl configure script
        +echo .
        +echo .  If no debug or assembly opts are specified the default is to build
        +echo .  non-debug without assembly
        +echo .
        +
        +        
        +:end        
        diff --git a/vendor/openssl/openssl/Netware/cpy_tests.bat b/vendor/openssl/openssl/Netware/cpy_tests.bat
        new file mode 100644
        index 000000000..1583f2806
        --- /dev/null
        +++ b/vendor/openssl/openssl/Netware/cpy_tests.bat
        @@ -0,0 +1,113 @@
        +@echo off
        +
        +rem   Batch file to copy OpenSSL stuff to a NetWare server for testing
        +
        +rem   This batch file will create an "opensssl" directory at the root of the
        +rem   specified NetWare drive and copy the required files to run the tests.
        +rem   It should be run from inside the "openssl\netware" subdirectory.
        +
        +rem   Usage:
        +rem      cpy_tests.bat <test subdirectory> <NetWare drive>
        +rem          <test subdirectory> - out_nw.dbg | out_nw
        +rem          <NetWare drive> - any mapped drive letter
        +rem
        +rem      example ( copy from debug build to m: dirve ):
        +rem              cpy_tests.bat out_nw.dbg m:
        +rem
        +rem      CAUTION:  If a directory named OpenSSL exists on the target drive
        +rem                it will be deleted first.
        +
        +
        +if "%1" == "" goto usage
        +if "%2" == "" goto usage
        +
        +rem   Assume running in \openssl directory unless cpy_tests.bat exists then
        +rem   it must be the \openssl\netware directory
        +set loc=.
        +if exist cpy_tests.bat set loc=..
        +
        +rem   make sure the local build subdirectory specified is valid
        +if not exist %loc%\%1\NUL goto invalid_dir
        +
        +rem   make sure target drive is valid
        +if not exist %2\NUL goto invalid_drive
        +
        +rem   If an OpenSSL directory exists on the target drive, remove it
        +if exist %2\openssl\NUL goto remove_openssl
        +goto do_copy
        +
        +:remove_openssl
        +echo .
        +echo OpenSSL directory exists on %2 - it will be removed!
        +pause
        +rmdir %2\openssl /s /q
        +
        +:do_copy
        +rem   make an "openssl" directory and others at the root of the NetWare drive
        +mkdir %2\openssl
        +mkdir %2\openssl\test_out
        +mkdir %2\openssl\apps
        +mkdir %2\openssl\certs
        +mkdir %2\openssl\test
        +
        +
        +rem   copy the test nlms
        +copy %loc%\%1\*.nlm %2\openssl\
        +
        +rem   copy the test perl script
        +copy %loc%\netware\do_tests.pl %2\openssl\
        +
        +rem   copy the certs directory stuff
        +xcopy %loc%\certs\*.*         %2\openssl\certs\ /s
        +
        +rem   copy the test directory stuff
        +copy %loc%\test\CAss.cnf      %2\openssl\test\
        +copy %loc%\test\Uss.cnf       %2\openssl\test\
        +copy %loc%\test\pkcs7.pem     %2\openssl\test\
        +copy %loc%\test\pkcs7-1.pem   %2\openssl\test\
        +copy %loc%\test\testcrl.pem   %2\openssl\test\
        +copy %loc%\test\testp7.pem    %2\openssl\test\
        +copy %loc%\test\testreq2.pem  %2\openssl\test\
        +copy %loc%\test\testrsa.pem   %2\openssl\test\
        +copy %loc%\test\testsid.pem   %2\openssl\test\
        +copy %loc%\test\testx509.pem  %2\openssl\test\
        +copy %loc%\test\v3-cert1.pem  %2\openssl\test\
        +copy %loc%\test\v3-cert2.pem  %2\openssl\test\
        +copy %loc%\crypto\evp\evptests.txt %2\openssl\test\
        +
        +rem   copy the apps directory stuff
        +copy %loc%\apps\client.pem    %2\openssl\apps\
        +copy %loc%\apps\server.pem    %2\openssl\apps\
        +copy %loc%\apps\openssl.cnf   %2\openssl\apps\
        +
        +echo .
        +echo Tests copied
        +echo Run the test script at the console by typing:
        +echo     "Perl \openssl\do_tests.pl"
        +echo .
        +echo Make sure the Search path includes the OpenSSL subdirectory
        +
        +goto end
        +
        +:invalid_dir
        +echo.
        +echo Invalid build directory specified: %1
        +echo.
        +goto usage
        +
        +:invalid_drive
        +echo.
        +echo Invalid drive: %2
        +echo.
        +goto usage
        +
        +:usage
        +echo.
        +echo usage: cpy_tests.bat [test subdirectory] [NetWare drive]
        +echo     [test subdirectory] - out_nw_clib.dbg, out_nw_libc.dbg, etc. 
        +echo     [NetWare drive]     - any mapped drive letter
        +echo.
        +echo example: cpy_test out_nw_clib.dbg M:
        +echo  (copy from clib debug build area to M: drive)
        +
        +:end
        diff --git a/vendor/openssl/openssl/Netware/do_tests.pl b/vendor/openssl/openssl/Netware/do_tests.pl
        new file mode 100644
        index 000000000..ac482dbe2
        --- /dev/null
        +++ b/vendor/openssl/openssl/Netware/do_tests.pl
        @@ -0,0 +1,624 @@
        +# perl script to run OpenSSL tests
        +
        +
        +my $base_path      = "\\openssl";
        +
        +my $output_path    = "$base_path\\test_out";
        +my $cert_path      = "$base_path\\certs";
        +my $test_path      = "$base_path\\test";
        +my $app_path       = "$base_path\\apps";
        +
        +my $tmp_cert       = "$output_path\\cert.tmp";
        +my $OpenSSL_config = "$app_path\\openssl.cnf";
        +my $log_file       = "$output_path\\tests.log";
        +
        +my $pause = 0;
        +
        +
        +#  process the command line args to see if they wanted us to pause
        +#  between executing each command
        +foreach $i (@ARGV)
        +{
        +   if ($i =~ /^-p$/)
        +   { $pause=1; }
        +}
        +
        +
        +
        +main();
        +
        +
        +############################################################################
        +sub main()
        +{
        +   # delete all the output files in the output directory
        +   unlink <$output_path\\*.*>;
        +
        +   # open the main log file
        +   open(OUT, ">$log_file") || die "unable to open $log_file\n";
        +
        +   print( OUT "========================================================\n");
        +   my $outFile = "$output_path\\version.out";
        +   system("openssl2 version (CLIB_OPT)/>$outFile");
        +   log_output("CHECKING FOR OPENSSL VERSION:", $outFile);
        +
        +   algorithm_tests();
        +   encryption_tests();
        +   evp_tests();
        +   pem_tests();
        +   verify_tests();
        +   ca_tests();
        +   ssl_tests();
        +
        +   close(OUT);
        +
        +   print("\nCompleted running tests.\n\n");
        +   print("Check log file for errors: $log_file\n");
        +}
        +
        +############################################################################
        +sub algorithm_tests
        +{
        +   my $i;
        +   my $outFile;
        +   my @tests = ( rsa_test, destest, ideatest, bftest, bntest, shatest, sha1test,
        +                 sha256t, sha512t, dsatest, md2test, md4test, md5test, mdc2test,
        +                 rc2test, rc4test, rc5test, randtest, rmdtest, dhtest, ecdhtest,
        +                 ecdsatest, ectest, exptest, casttest, hmactest );
        +
        +   print( "\nRUNNING CRYPTO ALGORITHM TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "CRYPTO ALGORITHM TESTS:\n\n");
        +
        +   foreach $i (@tests)
        +   {
        +      if (-e "$base_path\\$i.nlm")
        +      {
        +         $outFile = "$output_path\\$i.out";
        +         system("$i (CLIB_OPT)/>$outFile");
        +         log_desc("Test: $i\.nlm:");
        +         log_output("", $outFile );
        +      }
        +      else
        +      {
        +         log_desc("Test: $i\.nlm: file not found");
        +      }
        +   }
        +}
        +
        +############################################################################
        +sub encryption_tests
        +{
        +   my $i;
        +   my $outFile;
        +   my @enc_tests = ( "enc", "rc4", "des-cfb", "des-ede-cfb", "des-ede3-cfb",
        +                     "des-ofb", "des-ede-ofb", "des-ede3-ofb",
        +                     "des-ecb", "des-ede", "des-ede3", "des-cbc",
        +                     "des-ede-cbc", "des-ede3-cbc", "idea-ecb", "idea-cfb",
        +                     "idea-ofb", "idea-cbc", "rc2-ecb", "rc2-cfb",
        +                     "rc2-ofb", "rc2-cbc", "bf-ecb", "bf-cfb",
        +                     "bf-ofb", "bf-cbc" );
        +
        +   my $input = "$base_path\\do_tests.pl";
        +   my $cipher = "$output_path\\cipher.out";
        +   my $clear = "$output_path\\clear.out";
        +
        +   print( "\nRUNNING ENCRYPTION & DECRYPTION TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "FILE ENCRYPTION & DECRYPTION TESTS:\n\n");
        +
        +   foreach $i (@enc_tests)
        +   {
        +      log_desc("Testing: $i");
        +
        +      # do encryption
        +      $outFile = "$output_path\\enc.out";
        +      system("openssl2 $i -e -bufsize 113 -k test -in $input -out $cipher (CLIB_OPT)/>$outFile" );
        +      log_output("Encrypting: $input --> $cipher", $outFile);
        +
        +      # do decryption
        +      $outFile = "$output_path\\dec.out";
        +      system("openssl2 $i -d -bufsize 157 -k test -in $cipher -out $clear (CLIB_OPT)/>$outFile");
        +      log_output("Decrypting: $cipher --> $clear", $outFile);
        +
        +      # compare files
        +      $x = compare_files( $input, $clear, 1);
        +      if ( $x == 0 )
        +      {
        +         print( "\rSUCCESS - files match: $input, $clear\n");
        +         print( OUT "SUCCESS - files match: $input, $clear\n");
        +      }
        +      else
        +      {
        +         print( "\rERROR: files don't match\n");
        +         print( OUT "ERROR: files don't match\n");
        +      }
        +
        +      do_wait();
        +
        +      # Now do the same encryption but use Base64
        +
        +      # do encryption B64
        +      $outFile = "$output_path\\B64enc.out";
        +      system("openssl2 $i -a -e -bufsize 113 -k test -in $input -out $cipher (CLIB_OPT)/>$outFile");
        +      log_output("Encrypting(B64): $cipher --> $clear", $outFile);
        +
        +      # do decryption B64
        +      $outFile = "$output_path\\B64dec.out";
        +      system("openssl2 $i -a -d -bufsize 157 -k test -in $cipher -out $clear (CLIB_OPT)/>$outFile");
        +      log_output("Decrypting(B64): $cipher --> $clear", $outFile);
        +
        +      # compare files
        +      $x = compare_files( $input, $clear, 1);
        +      if ( $x == 0 )
        +      {
        +         print( "\rSUCCESS - files match: $input, $clear\n");
        +         print( OUT "SUCCESS - files match: $input, $clear\n");
        +      }
        +      else
        +      {
        +         print( "\rERROR: files don't match\n");
        +         print( OUT "ERROR: files don't match\n");
        +      }
        +
        +      do_wait();
        +
        +   } # end foreach
        +
        +   # delete the temporary files
        +   unlink($cipher);
        +   unlink($clear);
        +}
        +
        +
        +############################################################################
        +sub pem_tests
        +{
        +   my $i;
        +   my $tmp_out;
        +   my $outFile = "$output_path\\pem.out";
        +
        +   my %pem_tests = (
        +         "crl"      => "testcrl.pem",
        +          "pkcs7"   => "testp7.pem",
        +          "req"     => "testreq2.pem",
        +          "rsa"     => "testrsa.pem",
        +          "x509"    => "testx509.pem",
        +          "x509"    => "v3-cert1.pem",
        +          "sess_id" => "testsid.pem"  );
        +
        +
        +   print( "\nRUNNING PEM TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "PEM TESTS:\n\n");
        +
        +   foreach $i (keys(%pem_tests))
        +   {
        +      log_desc( "Testing: $i");
        +
        +      my $input = "$test_path\\$pem_tests{$i}";
        +
        +      $tmp_out = "$output_path\\$pem_tests{$i}";
        +
        +      if ($i ne "req" )
        +      {
        +         system("openssl2 $i -in $input -out $tmp_out (CLIB_OPT)/>$outFile");
        +         log_output( "openssl2 $i -in $input -out $tmp_out", $outFile);
        +      }
        +      else
        +      {
        +         system("openssl2 $i -in $input -out $tmp_out -config $OpenSSL_config (CLIB_OPT)/>$outFile");
        +         log_output( "openssl2 $i -in $input -out $tmp_out -config $OpenSSL_config", $outFile );
        +      }
        +
        +      $x = compare_files( $input, $tmp_out);
        +      if ( $x == 0 )
        +      {
        +         print( "\rSUCCESS - files match: $input, $tmp_out\n");
        +         print( OUT "SUCCESS - files match: $input, $tmp_out\n");
        +      }
        +      else
        +      {
        +         print( "\rERROR: files don't match\n");
        +         print( OUT "ERROR: files don't match\n");
        +      }
        +      do_wait();
        +
        +   } # end foreach
        +}
        +
        +
        +############################################################################
        +sub verify_tests
        +{
        +   my $i;
        +   my $outFile = "$output_path\\verify.out";
        +
        +   $cert_path =~ s/\\/\//g;
        +   my @cert_files = <$cert_path/*.pem>;
        +
        +   print( "\nRUNNING VERIFY TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "VERIFY TESTS:\n\n");
        +
        +   make_tmp_cert_file();
        +
        +   foreach $i (@cert_files)
        +   {
        +      system("openssl2 verify -CAfile $tmp_cert $i (CLIB_OPT)/>$outFile");
        +      log_desc("Verifying cert: $i");
        +      log_output("openssl2 verify -CAfile $tmp_cert $i", $outFile);
        +   }
        +}
        +
        +
        +############################################################################
        +sub ssl_tests
        +{
        +   my $outFile = "$output_path\\ssl_tst.out";
        +   my($CAcert) = "$output_path\\certCA.ss";
        +   my($Ukey)   = "$output_path\\keyU.ss";
        +   my($Ucert)  = "$output_path\\certU.ss";
        +   my($ssltest)= "ssltest -key $Ukey -cert $Ucert -c_key $Ukey -c_cert $Ucert -CAfile $CAcert";
        +
        +   print( "\nRUNNING SSL TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "SSL TESTS:\n\n");
        +
        +   system("ssltest -ssl2 (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2:");
        +   log_output("ssltest -ssl2", $outFile);
        +
        +   system("$ssltest -ssl2 -server_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 with server authentication:");
        +   log_output("$ssltest -ssl2 -server_auth", $outFile);
        +
        +   system("$ssltest -ssl2 -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 with client authentication:");
        +   log_output("$ssltest -ssl2 -client_auth", $outFile);
        +
        +   system("$ssltest -ssl2 -server_auth -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 with both client and server authentication:");
        +   log_output("$ssltest -ssl2 -server_auth -client_auth", $outFile);
        +
        +   system("ssltest -ssl3 (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3:");
        +   log_output("ssltest -ssl3", $outFile);
        +
        +   system("$ssltest -ssl3 -server_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 with server authentication:");
        +   log_output("$ssltest -ssl3 -server_auth", $outFile);
        +
        +   system("$ssltest -ssl3 -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 with client authentication:");
        +   log_output("$ssltest -ssl3 -client_auth", $outFile);
        +
        +   system("$ssltest -ssl3 -server_auth -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 with both client and server authentication:");
        +   log_output("$ssltest -ssl3 -server_auth -client_auth", $outFile);
        +
        +   system("ssltest (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3:");
        +   log_output("ssltest", $outFile);
        +
        +   system("$ssltest -server_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with server authentication:");
        +   log_output("$ssltest -server_auth", $outFile);
        +
        +   system("$ssltest -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with client authentication:");
        +   log_output("$ssltest -client_auth ", $outFile);
        +
        +   system("$ssltest -server_auth -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with both client and server authentication:");
        +   log_output("$ssltest -server_auth -client_auth", $outFile);
        +
        +   system("ssltest -bio_pair -ssl2 (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 via BIO pair:");
        +   log_output("ssltest -bio_pair -ssl2", $outFile);
        +
        +   system("ssltest -bio_pair -dhe1024dsa -v (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with 1024 bit DHE via BIO pair:");
        +   log_output("ssltest -bio_pair -dhe1024dsa -v", $outFile);
        +
        +   system("$ssltest -bio_pair -ssl2 -server_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 with server authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -ssl2 -server_auth", $outFile);
        +
        +   system("$ssltest -bio_pair -ssl2 -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 with client authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -ssl2 -client_auth", $outFile);
        +
        +   system("$ssltest -bio_pair -ssl2 -server_auth -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2 with both client and server authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -ssl2 -server_auth -client_auth", $outFile);
        +
        +   system("ssltest -bio_pair -ssl3 (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 via BIO pair:");
        +   log_output("ssltest -bio_pair -ssl3", $outFile);
        +
        +   system("$ssltest -bio_pair -ssl3 -server_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 with server authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -ssl3 -server_auth", $outFile);
        +
        +   system("$ssltest -bio_pair -ssl3 -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 with client authentication  via BIO pair:");
        +   log_output("$ssltest -bio_pair -ssl3 -client_auth", $outFile);
        +
        +   system("$ssltest -bio_pair -ssl3 -server_auth -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv3 with both client and server authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -ssl3 -server_auth -client_auth", $outFile);
        +
        +   system("ssltest -bio_pair (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 via BIO pair:");
        +   log_output("ssltest -bio_pair", $outFile);
        +
        +   system("$ssltest -bio_pair -server_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with server authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -server_auth", $outFile);
        +
        +   system("$ssltest -bio_pair -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with client authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -client_auth", $outFile);
        +
        +   system("$ssltest -bio_pair -server_auth -client_auth (CLIB_OPT)/>$outFile");
        +   log_desc("Testing sslv2/sslv3 with both client and server authentication via BIO pair:");
        +   log_output("$ssltest -bio_pair -server_auth -client_auth", $outFile);
        +}
        +
        +
        +############################################################################
        +sub ca_tests
        +{
        +   my $outFile = "$output_path\\ca_tst.out";
        +
        +   my($CAkey)     = "$output_path\\keyCA.ss";
        +   my($CAcert)    = "$output_path\\certCA.ss";
        +   my($CAserial)  = "$output_path\\certCA.srl";
        +   my($CAreq)     = "$output_path\\reqCA.ss";
        +   my($CAreq2)    = "$output_path\\req2CA.ss";
        +
        +   my($CAconf)    = "$test_path\\CAss.cnf";
        +
        +   my($Uconf)     = "$test_path\\Uss.cnf";
        +
        +   my($Ukey)      = "$output_path\\keyU.ss";
        +   my($Ureq)      = "$output_path\\reqU.ss";
        +   my($Ucert)     = "$output_path\\certU.ss";
        +
        +   print( "\nRUNNING CA TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "CA TESTS:\n");
        +
        +   system("openssl2 req -config $CAconf -out $CAreq -keyout $CAkey -new (CLIB_OPT)/>$outFile");
        +   log_desc("Make a certificate request using req:");
        +   log_output("openssl2 req -config $CAconf -out $CAreq -keyout $CAkey -new", $outFile);
        +
        +   system("openssl2 x509 -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey (CLIB_OPT)/>$outFile");
        +   log_desc("Convert the certificate request into a self signed certificate using x509:");
        +   log_output("openssl2 x509 -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey", $outFile);
        +
        +   system("openssl2 x509 -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2 (CLIB_OPT)/>$outFile");
        +   log_desc("Convert a certificate into a certificate request using 'x509':");
        +   log_output("openssl2 x509 -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2", $outFile);
        +
        +   system("openssl2 req -config $OpenSSL_config -verify -in $CAreq -noout (CLIB_OPT)/>$outFile");
        +   log_output("openssl2 req -config $OpenSSL_config -verify -in $CAreq -noout", $outFile);
        +
        +   system("openssl2 req -config $OpenSSL_config -verify -in $CAreq2 -noout (CLIB_OPT)/>$outFile");
        +   log_output( "openssl2 req -config $OpenSSL_config -verify -in $CAreq2 -noout", $outFile);
        +
        +   system("openssl2 verify -CAfile $CAcert $CAcert (CLIB_OPT)/>$outFile");
        +   log_output("openssl2 verify -CAfile $CAcert $CAcert", $outFile);
        +
        +   system("openssl2 req -config $Uconf -out $Ureq -keyout $Ukey -new (CLIB_OPT)/>$outFile");
        +   log_desc("Make another certificate request using req:");
        +   log_output("openssl2 req -config $Uconf -out $Ureq -keyout $Ukey -new", $outFile);
        +
        +   system("openssl2 x509 -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -CAserial $CAserial (CLIB_OPT)/>$outFile");
        +   log_desc("Sign certificate request with the just created CA via x509:");
        +   log_output("openssl2 x509 -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -CAserial $CAserial", $outFile);
        +
        +   system("openssl2 verify -CAfile $CAcert $Ucert (CLIB_OPT)/>$outFile");
        +   log_output("openssl2 verify -CAfile $CAcert $Ucert", $outFile);
        +
        +   system("openssl2 x509 -subject -issuer -startdate -enddate -noout -in $Ucert (CLIB_OPT)/>$outFile");
        +   log_desc("Certificate details");
        +   log_output("openssl2 x509 -subject -issuer -startdate -enddate -noout -in $Ucert", $outFile);
        +
        +   print(OUT "--\n");
        +   print(OUT "The generated CA certificate is $CAcert\n");
        +   print(OUT "The generated CA private key is $CAkey\n");
        +   print(OUT "The current CA signing serial number is in $CAserial\n");
        +
        +   print(OUT "The generated user certificate is $Ucert\n");
        +   print(OUT "The generated user private key is $Ukey\n");
        +   print(OUT "--\n");
        +}
        +
        +############################################################################
        +sub evp_tests
        +{
        +   my $i = 'evp_test';
        +
        +   print( "\nRUNNING EVP TESTS:\n\n");
        +
        +   print( OUT "\n========================================================\n");
        +   print( OUT "EVP TESTS:\n\n");
        +
        +   if (-e "$base_path\\$i.nlm")
        +   {
        +       my $outFile = "$output_path\\$i.out";
        +       system("$i $test_path\\evptests.txt (CLIB_OPT)/>$outFile");
        +       log_desc("Test: $i\.nlm:");
        +       log_output("", $outFile );
        +   }
        +   else
        +   {
        +       log_desc("Test: $i\.nlm: file not found");
        +   }
        +}
        +
        +############################################################################
        +sub log_output( $ $ )
        +{
        +   my( $desc, $file ) = @_;
        +   my($error) = 0;
        +   my($key);
        +   my($msg);
        +
        +   if ($desc)
        +   {
        +      print("\r$desc\n");
        +      print(OUT "$desc\n");
        +   }
        +
        +      # loop waiting for test program to complete
        +   while ( stat($file) == 0)
        +      { print(". "); sleep(1); }
        +
        +
        +      # copy test output to log file
        +   open(IN, "<$file");
        +   while (<IN>)
        +   {
        +      print(OUT $_);
        +      if ( $_ =~ /ERROR/ )
        +      {
        +         $error = 1;
        +      }
        +   }
        +      # close and delete the temporary test output file
        +   close(IN);
        +   unlink($file);
        +
        +   if ( $error == 0 )
        +   {
        +      $msg = "Test Succeeded";
        +   }
        +   else
        +   {
        +      $msg = "Test Failed";
        +   }
        +
        +   print(OUT "$msg\n");
        +
        +   if ($pause)
        +   {
        +      print("$msg - press ENTER to continue...");
        +      $key = getc;
        +      print("\n");
        +   }
        +
        +      # Several of the testing scripts run a loop loading the
        +      # same NLM with different options.
        +      # On slow NetWare machines there appears to be some delay in the
        +      # OS actually unloading the test nlms and the OS complains about.
        +      # the NLM already being loaded.  This additional pause is to
        +      # to help provide a little more time for unloading before trying to
        +      # load again.
        +   sleep(1);
        +}
        +
        +
        +############################################################################
        +sub log_desc( $ )
        +{
        +   my( $desc ) = @_;
        +
        +   print("\n");
        +   print("$desc\n");
        +
        +   print(OUT "\n");
        +   print(OUT "$desc\n");
        +   print(OUT "======================================\n");
        +}
        +
        +############################################################################
        +sub compare_files( $ $ $ )
        +{
        +   my( $file1, $file2, $binary ) = @_;
        +   my( $n1, $n2, $b1, $b2 );
        +   my($ret) = 1;
        +
        +   open(IN0, $file1) || die "\nunable to open $file1\n";
        +   open(IN1, $file2) || die "\nunable to open $file2\n";
        +
        +  if ($binary)
        +  {
        +      binmode IN0;
        +      binmode IN1;
        +  }
        +
        +   for (;;)
        +   {
        +      $n1 = read(IN0, $b1, 512);
        +      $n2 = read(IN1, $b2, 512);
        +
        +      if ($n1 != $n2) {last;}
        +      if ($b1 != $b2) {last;}
        +
        +      if ($n1 == 0)
        +      {
        +         $ret = 0;
        +         last;
        +      }
        +   }
        +   close(IN0);
        +   close(IN1);
        +   return($ret);
        +}
        +
        +############################################################################
        +sub do_wait()
        +{
        +   my($key);
        +
        +   if ($pause)
        +   {
        +      print("Press ENTER to continue...");
        +      $key = getc;
        +      print("\n");
        +   }
        +}
        +
        +
        +############################################################################
        +sub make_tmp_cert_file()
        +{
        +   my @cert_files = <$cert_path/*.pem>;
        +
        +      # delete the file if it already exists
        +   unlink($tmp_cert);
        +
        +   open( TMP_CERT, ">$tmp_cert") || die "\nunable to open $tmp_cert\n";
        +
        +   print("building temporary cert file\n");
        +
        +   # create a temporary cert file that contains all the certs
        +   foreach $i (@cert_files)
        +   {
        +      open( IN_CERT, $i ) || die "\nunable to open $i\n";
        +
        +      for(;;)
        +      {
        +         $n = sysread(IN_CERT, $data, 1024);
        +
        +         if ($n == 0)
        +         {
        +            close(IN_CERT);
        +            last;
        +         };
        +
        +         syswrite(TMP_CERT, $data, $n);
        +      }
        +   }
        +
        +   close( TMP_CERT );
        +}
        diff --git a/vendor/openssl/openssl/Netware/globals.txt b/vendor/openssl/openssl/Netware/globals.txt
        new file mode 100644
        index 000000000..fe05d390c
        --- /dev/null
        +++ b/vendor/openssl/openssl/Netware/globals.txt
        @@ -0,0 +1,254 @@
        +An initial review of the OpenSSL code was done to determine how many 
        +global variables where present.  The idea was to determine the amount of 
        +work required to pull the globals into an instance data structure in 
        +order to build a Library NLM for NetWare.  This file contains the results 
        +of the review.  Each file is listed along with the globals in the file.  
        +The initial review was done very quickly so this list is probably
        +not a comprehensive list.
        +
        +
        +cryptlib.c
        +===========================================
        +
        +static STACK *app_locks=NULL;
        +
        +static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
        +
        +static void (MS_FAR *locking_callback)(int mode,int type,
        +   const char *file,int line)=NULL;
        +static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
        +   int type,const char *file,int line)=NULL;
        +static unsigned long (MS_FAR *id_callback)(void)=NULL;
        +static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
        +   (const char *file,int line)=NULL;
        +static void (MS_FAR *dynlock_lock_callback)(int mode,
        +   struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
        +static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
        +   const char *file,int line)=NULL;
        +
        +
        +mem.c
        +===========================================
        +static int allow_customize = 1;      /* we provide flexible functions for */
        +static int allow_customize_debug = 1;/* exchanging memory-related functions at
        +
        +/* may be changed as long as `allow_customize' is set */
        +static void *(*malloc_locked_func)(size_t)  = malloc;
        +static void (*free_locked_func)(void *)     = free;
        +static void *(*malloc_func)(size_t)         = malloc;
        +static void *(*realloc_func)(void *, size_t)= realloc;
        +static void (*free_func)(void *)            = free;
        +
        +/* use default functions from mem_dbg.c */
        +static void (*malloc_debug_func)(void *,int,const char *,int,int)
        +   = CRYPTO_dbg_malloc;
        +static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
        +   = CRYPTO_dbg_realloc;
        +static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
        +static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
        +static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
        +
        +
        +mem_dbg.c
        +===========================================
        +static int mh_mode=CRYPTO_MEM_CHECK_OFF;
        +static unsigned long order = 0; /* number of memory requests */
        +static LHASH *mh=NULL; /* hash-table of memory requests (address as key) */
        +
        +static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's */
        +static long options =             /* extra information to be recorded */
        +static unsigned long disabling_thread = 0;
        +
        +
        +err.c
        +===========================================
        +static LHASH *error_hash=NULL;
        +static LHASH *thread_hash=NULL;
        +
        +several files have routines with static "init" to track if error strings
        +   have been loaded ( may not want seperate error strings for each process )
        +   The "init" variable can't be left "global" because the error has is a ptr
        +   that is malloc'ed.  The malloc'ed error has is dependant on the "init"
        +   vars.
        +
        +   files:
        +      pem_err.c
        +      cpt_err.c
        +      pk12err.c
        +      asn1_err.c
        +      bio_err.c
        +      bn_err.c
        +      buf_err.c
        +      comp_err.c
        +      conf_err.c
        +      cpt_err.c
        +      dh_err.c
        +      dsa_err.c
        +      dso_err.c
        +      evp_err.c
        +      obj_err.c
        +      pkcs7err.c
        +      rand_err.c
        +      rsa_err.c
        +      rsar_err.c
        +      ssl_err.c
        +      x509_err.c
        +      v3err.c
        +		err.c
        +
        +These file have similar "init" globals but they are for other stuff not
        +error strings:
        +
        +		bn_lib.c
        +		ecc_enc.c
        +		s23_clnt.c
        +		s23_meth.c
        +		s23_srvr.c
        +		s2_clnt.c
        +		s2_lib.c
        +		s2_meth.c
        +		s2_srvr.c
        +		s3_clnt.c
        +		s3_lib.c
        +		s3_srvr.c
        +		t1_clnt.c
        +		t1_meth.c
        +		t1_srvr.c
        +
        +rand_lib.c
        +===========================================
        +static RAND_METHOD *rand_meth= &rand_ssleay_meth;
        +
        +md_rand.c
        +===========================================
        +static int state_num=0,state_index=0;
        +static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
        +static unsigned char md[MD_DIGEST_LENGTH];
        +static long md_count[2]={0,0};
        +static double entropy=0;
        +static int initialized=0;
        +
        +/* This should be set to 1 only when ssleay_rand_add() is called inside
        +   an already locked state, so it doesn't try to lock and thereby cause
        +   a hang.  And it should always be reset back to 0 before unlocking. */
        +static int add_do_not_lock=0;
        +
        +obj_dat.c
        +============================================
        +static int new_nid=NUM_NID;
        +static LHASH *added=NULL;
        +
        +b_sock.c
        +===========================================
        +static unsigned long BIO_ghbn_hits=0L;
        +static unsigned long BIO_ghbn_miss=0L;
        +static struct ghbn_cache_st
        +   {
        +   char name[129];
        +   struct hostent *ent;
        +   unsigned long order;
        +   } ghbn_cache[GHBN_NUM];
        +
        +static int wsa_init_done=0;
        +
        +
        +bio_lib.c
        +===========================================
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *bio_meth=NULL;
        +static int bio_meth_num=0;
        +
        +
        +bn_lib.c
        +========================================
        +static int bn_limit_bits=0;
        +static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
        +static int bn_limit_bits_low=0;
        +static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
        +static int bn_limit_bits_high=0;
        +static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
        +static int bn_limit_bits_mont=0;
        +static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
        +
        +conf_lib.c
        +========================================
        +static CONF_METHOD *default_CONF_method=NULL;
        +
        +dh_lib.c
        +========================================
        +static DH_METHOD *default_DH_method;
        +static int dh_meth_num = 0;
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dh_meth = NULL;
        +
        +dsa_lib.c
        +========================================
        +static DSA_METHOD *default_DSA_method;
        +static int dsa_meth_num = 0;
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dsa_meth = NULL;
        +
        +dso_lib.c
        +========================================
        +static DSO_METHOD *default_DSO_meth = NULL;
        +
        +rsa_lib.c
        +========================================
        +static RSA_METHOD *default_RSA_meth=NULL;
        +static int rsa_meth_num=0;
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *rsa_meth=NULL;
        +
        +x509_trs.c
        +=======================================
        +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
        +static STACK_OF(X509_TRUST) *trtable = NULL;
        +
        +x509_req.c
        +=======================================
        +static int *ext_nids = ext_nid_list;
        +
        +o_names.c
        +======================================
        +static LHASH *names_lh=NULL;
        +static STACK_OF(NAME_FUNCS) *name_funcs_stack;
        +static int free_type;
        +static int names_type_num=OBJ_NAME_TYPE_NUM;
        +
        +
        +th-lock.c - NEED to add support for locking for NetWare
        +==============================================
        +static long *lock_count;
        +(other platform specific globals)
        +
        +x_x509.c
        +==============================================
        +static int x509_meth_num = 0;
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_meth = NULL;
        +
        +
        +evp_pbe.c
        +============================================
        +static STACK *pbe_algs;
        +
        +evp_key.c
        +============================================
        +static char prompt_string[80];
        +
        +ssl_ciph.c
        +============================================
        +static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
        +
        +ssl_lib.c
        +=============================================
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_meth=NULL;
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_ctx_meth=NULL;
        +static int ssl_meth_num=0;
        +static int ssl_ctx_meth_num=0;
        +
        +ssl_sess.c
        +=============================================
        +static int ssl_session_num=0;
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *ssl_session_meth=NULL;
        +
        +x509_vfy.c
        +============================================
        +static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_ctx_method=NULL;
        +static int x509_store_ctx_num=0;
        +
        diff --git a/vendor/openssl/openssl/Netware/readme.txt b/vendor/openssl/openssl/Netware/readme.txt
        new file mode 100644
        index 000000000..a5b5faae3
        --- /dev/null
        +++ b/vendor/openssl/openssl/Netware/readme.txt
        @@ -0,0 +1,19 @@
        +
        +Contents of the openssl\netware directory
        +==========================================
        +
        +Regular files:
        +
        +readme.txt     - this file
        +do_tests.pl    - perl script used to run the OpenSSL tests on NetWare
        +cpy_tests.bat  - batch to to copy test stuff to NetWare server
        +build.bat      - batch file to help with builds
        +set_env.bat    - batch file to help setup build environments
        +globals.txt    - results of initial code review to identify OpenSSL global variables
        +
        +
        +The following files are generated by the various scripts.  They are
        +recreated each time and it is okay to delete them.
        +
        +*.def - command files used by Metrowerks linker
        +*.mak - make files generated by mk1mf.pl
        diff --git a/vendor/openssl/openssl/Netware/set_env.bat b/vendor/openssl/openssl/Netware/set_env.bat
        new file mode 100644
        index 000000000..ace024e52
        --- /dev/null
        +++ b/vendor/openssl/openssl/Netware/set_env.bat
        @@ -0,0 +1,112 @@
        +@echo off
        +
        +rem ========================================================================
        +rem   Batch file to assist in setting up the necessary enviroment for
        +rem   building OpenSSL for NetWare.
        +rem
        +rem   usage:
        +rem      set_env [target]
        +rem
        +rem      target      - "netware-clib" - Clib build
        +rem                  - "netware-libc" - LibC build
        +rem
        +rem
        +
        +if "a%1" == "a" goto usage
        +               
        +set LIBC_BUILD=
        +set CLIB_BUILD=
        +set GNUC=
        +
        +if "%1" == "netware-clib" set CLIB_BUILD=Y
        +if "%1" == "netware-clib" set LIBC_BUILD=
        +
        +if "%1" == "netware-libc" set LIBC_BUILD=Y
        +if "%1" == "netware-libc" set CLIB_BUILD=
        +
        +if "%2" == "gnuc" set GNUC=Y
        +if "%2" == "codewarrior" set GNUC=
        +
        +rem   Location of tools (compiler, linker, etc)
        +if "%NDKBASE%" == "" set NDKBASE=c:\Novell
        +
        +rem   If Perl for Win32 is not already in your path, add it here
        +set PERL_PATH=
        +
        +rem   Define path to the Metrowerks command line tools
        +rem   or GNU Crosscompiler gcc / nlmconv
        +rem   ( compiler, assembler, linker)
        +if "%GNUC%" == "Y" set COMPILER_PATH=c:\usr\i586-netware\bin;c:\usr\bin
        +if "%GNUC%" == "" set COMPILER_PATH=c:\prg\cwcmdl40
        +
        +rem   If using gnu make define path to utility
        +rem set GNU_MAKE_PATH=%NDKBASE%\gnu
        +set GNU_MAKE_PATH=c:\prg\tools
        +
        +rem   If using ms nmake define path to nmake
        +rem set MS_NMAKE_PATH=%NDKBASE%\msvc\600\bin
        +
        +rem   If using NASM assembler define path
        +rem set NASM_PATH=%NDKBASE%\nasm
        +set NASM_PATH=c:\prg\tools
        +
        +rem   Update path to include tool paths
        +set path=%path%;%COMPILER_PATH%
        +if not "%GNU_MAKE_PATH%" == "" set path=%path%;%GNU_MAKE_PATH%
        +if not "%MS_NMAKE_PATH%" == "" set path=%path%;%MS_NMAKE_PATH%
        +if not "%NASM_PATH%"     == "" set path=%path%;%NASM_PATH%
        +if not "%PERL_PATH%"     == "" set path=%path%;%PERL_PATH%
        +
        +rem   Set INCLUDES to location of Novell NDK includes
        +if "%LIBC_BUILD%" == "Y" set INCLUDE=%NDKBASE%\ndk\libc\include;%NDKBASE%\ndk\libc\include\winsock
        +if "%CLIB_BUILD%" == "Y" set INCLUDE=%NDKBASE%\ndk\nwsdk\include\nlm;%NDKBASE%\ws295sdk\include
        +
        +rem   Set Imports to location of Novell NDK import files
        +if "%LIBC_BUILD%" == "Y" set IMPORTS=%NDKBASE%\ndk\libc\imports
        +if "%CLIB_BUILD%" == "Y" set IMPORTS=%NDKBASE%\ndk\nwsdk\imports
        +
        +rem   Set PRELUDE to the absolute path of the prelude object to link with in
        +rem   the Metrowerks NetWare PDK - NOTE: for Clib builds "clibpre.o" is 
        +rem   recommended, for LibC NKS builds libcpre.o must be used
        +if "%GNUC%" == "Y" goto gnuc
        +if "%LIBC_BUILD%" == "Y" set PRELUDE=%IMPORTS%\libcpre.o
        +rem if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\clibpre.o
        +if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\prelude.o
        +echo using MetroWerks CodeWarrior 
        +goto info
        +
        +:gnuc
        +if "%LIBC_BUILD%" == "Y" set PRELUDE=%IMPORTS%\libcpre.gcc.o
        +rem if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\clibpre.gcc.o
        +if "%CLIB_BUILD%" == "Y" set PRELUDE=%IMPORTS%\prelude.gcc.o
        +echo using GNU GCC Compiler 
        +
        +:info
        +echo.
        +
        +if "%LIBC_BUILD%" == "Y" echo Enviroment configured for LibC build
        +if "%LIBC_BUILD%" == "Y" echo use "netware\build.bat netware-libc ..." 
        +
        +if "%CLIB_BUILD%" == "Y" echo Enviroment configured for CLib build
        +if "%CLIB_BUILD%" == "Y" echo use "netware\build.bat netware-clib ..." 
        +
        +goto end
        +
        +:usage
        +rem ===============================================================
        +echo.
        +echo No target build specified!
        +echo.
        +echo usage: set_env [target] [compiler]
        +echo.
        +echo target      - "netware-clib" - Clib build
        +echo             - "netware-libc" - LibC build
        +echo.
        +echo compiler    - "gnuc"         - GNU GCC Compiler
        +echo             - "codewarrior"  - MetroWerks CodeWarrior (default)
        +echo.
        +
        +:end
        +echo.
        +
        +
        diff --git a/vendor/openssl/openssl/PROBLEMS b/vendor/openssl/openssl/PROBLEMS
        new file mode 100644
        index 000000000..3eaab01f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/PROBLEMS
        @@ -0,0 +1,213 @@
        +* System libcrypto.dylib and libssl.dylib are used by system ld on MacOS X.
        +
        +
        +    NOTE: The problem described here only applies when OpenSSL isn't built
        +    with shared library support (i.e. without the "shared" configuration
        +    option).  If you build with shared library support, you will have no
        +    problems as long as you set up DYLD_LIBRARY_PATH properly at all times.
        +
        +
        +This is really a misfeature in ld, which seems to look for .dylib libraries
        +along the whole library path before it bothers looking for .a libraries.  This
        +means that -L switches won't matter unless OpenSSL is built with shared
        +library support.
        +
        +The workaround may be to change the following lines in apps/Makefile and
        +test/Makefile:
        +
        +  LIBCRYPTO=-L.. -lcrypto
        +  LIBSSL=-L.. -lssl
        +
        +to:
        +
        +  LIBCRYPTO=../libcrypto.a
        +  LIBSSL=../libssl.a
        +
        +It's possible that something similar is needed for shared library support
        +as well.  That hasn't been well tested yet.
        +
        +
        +Another solution that many seem to recommend is to move the libraries
        +/usr/lib/libcrypto.0.9.dylib, /usr/lib/libssl.0.9.dylib to a different
        +directory, build and install OpenSSL and anything that depends on your
        +build, then move libcrypto.0.9.dylib and libssl.0.9.dylib back to their
        +original places.  Note that the version numbers on those two libraries
        +may differ on your machine.
        +
        +
        +As long as Apple doesn't fix the problem with ld, this problem building
        +OpenSSL will remain as is. Well, the problem was addressed in 0.9.8f by
        +passing -Wl,-search_paths_first, but it's unknown if the flag was
        +supported from the initial MacOS X release.
        +
        +
        +* Parallell make leads to errors
        +
        +While running tests, running a parallell make is a bad idea.  Many test
        +scripts use the same name for output and input files, which means different
        +will interfere with each other and lead to test failure.
        +
        +The solution is simple for now: don't run parallell make when testing.
        +
        +
        +* Bugs in gcc triggered
        +
        +- According to a problem report, there are bugs in gcc 3.0 that are
        +  triggered by some of the code in OpenSSL, more specifically in
        +  PEM_get_EVP_CIPHER_INFO().  The triggering code is the following:
        +
        +	header+=11;
        +	if (*header != '4') return(0); header++;
        +	if (*header != ',') return(0); header++;
        +
        +  What happens is that gcc might optimize a little too agressively, and
        +  you end up with an extra incrementation when *header != '4'.
        +
        +  We recommend that you upgrade gcc to as high a 3.x version as you can.
        +
        +- According to multiple problem reports, some of our message digest
        +  implementations trigger bug[s] in code optimizer in gcc 3.3 for sparc64
        +  and gcc 2.96 for ppc. Former fails to complete RIPEMD160 test, while
        +  latter - SHA one.
        +
        +  The recomendation is to upgrade your compiler. This naturally applies to
        +  other similar cases.
        +
        +- There is a subtle Solaris x86-specific gcc run-time environment bug, which
        +  "falls between" OpenSSL [0.9.8 and later], Solaris ld and GCC. The bug
        +  manifests itself as Segmentation Fault upon early application start-up.
        +  The problem can be worked around by patching the environment according to
        +  http://www.openssl.org/~appro/values.c.
        +
        +* solaris64-sparcv9-cc SHA-1 performance with WorkShop 6 compiler.
        +
        +As subject suggests SHA-1 might perform poorly (4 times slower)
        +if compiled with WorkShop 6 compiler and -xarch=v9. The cause for
        +this seems to be the fact that compiler emits multiplication to
        +perform shift operations:-( To work the problem around configure
        +with './Configure solaris64-sparcv9-cc -DMD32_REG_T=int'.
        +
        +* Problems with hp-parisc2-cc target when used with "no-asm" flag
        +
        +When using the hp-parisc2-cc target, wrong bignum code is generated.
        +This is due to the SIXTY_FOUR_BIT build being compiled with the +O3
        +aggressive optimization.
        +The problem manifests itself by the BN_kronecker test hanging in an
        +endless loop. Reason: the BN_kronecker test calls BN_generate_prime()
        +which itself hangs. The reason could be tracked down to the bn_mul_comba8()
        +function in bn_asm.c. At some occasions the higher 32bit value of r[7]
        +is off by 1 (meaning: calculated=shouldbe+1). Further analysis failed,
        +as no debugger support possible at +O3 and additional fprintf()'s
        +introduced fixed the bug, therefore it is most likely a bug in the
        +optimizer.
        +The bug was found in the BN_kronecker test but may also lead to
        +failures in other parts of the code.
        +(See Ticket #426.)
        +
        +Workaround: modify the target to +O2 when building with no-asm.
        +
        +* Problems building shared libraries on SCO OpenServer Release 5.0.6
        +  with gcc 2.95.3
        +
        +The symptoms appear when running the test suite, more specifically
        +test/ectest, with the following result:
        +
        +OSSL_LIBPATH="`cd ..; pwd`"; LD_LIBRARY_PATH="$OSSL_LIBPATH:$LD_LIBRARY_PATH"; DYLD_LIBRARY_PATH="$OSSL_LIBPATH:$DYLD_LIBRARY_PATH"; SHLIB_PATH="$OSSL_LIBPATH:$SHLIB_PATH"; LIBPATH="$OSSL_LIBPATH:$LIBPATH"; if [ "debug-sco5-gcc" = "Cygwin" ]; then PATH="${LIBPATH}:$PATH"; fi; export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH PATH; ./ectest
        +ectest.c:186: ABORT
        +
        +The cause of the problem seems to be that isxdigit(), called from
        +BN_hex2bn(), returns 0 on a perfectly legitimate hex digit.  Further
        +investigation shows that any of the isxxx() macros return 0 on any
        +input.  A direct look in the information array that the isxxx() use,
        +called __ctype, shows that it contains all zeroes...
        +
        +Taking a look at the newly created libcrypto.so with nm, one can see
        +that the variable __ctype is defined in libcrypto's .bss (which
        +explains why it is filled with zeroes):
        +
        +$ nm -Pg libcrypto.so | grep __ctype
        +__ctype B 0011659c
        +__ctype2 U         
        +
        +Curiously, __ctype2 is undefined, in spite of being declared in
        +/usr/include/ctype.h in exactly the same way as __ctype.
        +
        +Any information helping to solve this issue would be deeply
        +appreciated.
        +
        +NOTE: building non-shared doesn't come with this problem.
        +
        +* ULTRIX build fails with shell errors, such as "bad substitution"
        +  and "test: argument expected"
        +
        +The problem is caused by ULTRIX /bin/sh supporting only original
        +Bourne shell syntax/semantics, and the trouble is that the vast
        +majority is so accustomed to more modern syntax, that very few
        +people [if any] would recognize the ancient syntax even as valid.
        +This inevitably results in non-trivial scripts breaking on ULTRIX,
        +and OpenSSL isn't an exclusion. Fortunately there is workaround,
        +hire /bin/ksh to do the job /bin/sh fails to do.
        +
        +1. Trick make(1) to use /bin/ksh by setting up following environ-
        +   ment variables *prior* you execute ./Configure and make:
        +
        +	PROG_ENV=POSIX
        +	MAKESHELL=/bin/ksh
        +	export PROG_ENV MAKESHELL
        +
        +   or if your shell is csh-compatible:
        +
        +	setenv PROG_ENV POSIX
        +	setenv MAKESHELL /bin/ksh
        +
        +2. Trick /bin/sh to use alternative expression evaluator. Create
        +   following 'test' script for example in /tmp:
        +
        +	#!/bin/ksh
        +	${0##*/} "$@"
        +
        +   Then 'chmod a+x /tmp/test; ln /tmp/test /tmp/[' and *prepend*
        +   your $PATH with chosen location, e.g. PATH=/tmp:$PATH. Alter-
        +   natively just replace system /bin/test and /bin/[ with the
        +   above script.
        +
        +* hpux64-ia64-cc fails blowfish test.
        +
        +Compiler bug, presumably at particular patch level. It should be noted
        +that same compiler generates correct 32-bit code, a.k.a. hpux-ia64-cc
        +target. Drop optimization level to +O2 when compiling 64-bit bf_skey.o.
        +
        +* no-engines generates errors.
        +
        +Unfortunately, the 'no-engines' configuration option currently doesn't
        +work properly.  Use 'no-hw' and you'll will at least get no hardware
        +support.  We'll see how we fix that on OpenSSL versions past 0.9.8.
        +
        +* 'make test' fails in BN_sqr [commonly with "error 139" denoting SIGSEGV]
        +  if elder GNU binutils were deployed to link shared libcrypto.so.
        +
        +As subject suggests the failure is caused by a bug in elder binutils,
        +either as or ld, and was observed on FreeBSD and Linux. There are two
        +options. First is naturally to upgrade binutils, the second one - to
        +reconfigure with additional no-sse2 [or 386] option passed to ./config.
        +
        +* If configured with ./config no-dso, toolkit still gets linked with -ldl,
        +  which most notably poses a problem when linking with dietlibc.
        +
        +We don't have framework to associate -ldl with no-dso, therefore the only
        +way is to edit Makefile right after ./config no-dso and remove -ldl from
        +EX_LIBS line.
        +
        +* hpux-parisc2-cc no-asm build fails with SEGV in ECDSA/DH.
        +
        +Compiler bug, presumably at particular patch level. Remaining
        +hpux*-parisc*-cc configurations can be affected too. Drop optimization
        +level to +O2 when compiling bn_nist.o.
        +
        +* solaris64-sparcv9-cc link failure
        +
        +Solaris 8 ar can fail to maintain symbol table in .a, which results in
        +link failures. Apply 109147-09 or later or modify Makefile generated
        +by ./Configure solaris64-sparcv9-cc and replace RANLIB assignment with
        +
        +	RANLIB= /usr/ccs/bin/ar rs
        diff --git a/vendor/openssl/openssl/README b/vendor/openssl/openssl/README
        new file mode 100644
        index 000000000..ad2d90f0d
        --- /dev/null
        +++ b/vendor/openssl/openssl/README
        @@ -0,0 +1,218 @@
        +
        + OpenSSL 1.0.1e 11 Feb 2013
        +
        + Copyright (c) 1998-2011 The OpenSSL Project
        + Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
        + All rights reserved.
        +
        + 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 toolkit 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 a dual-license (the
        + OpenSSL license plus the SSLeay license) situation, which basically means
        + that you are free to get and use it for commercial and non-commercial
        + purposes as long as you fulfill the conditions of both licenses.
        +
        + OVERVIEW
        + --------
        +
        + The OpenSSL toolkit includes:
        +
        + libssl.a:
        +     Implementation of SSLv2, SSLv3, TLSv1 and the required code to support
        +     both SSLv2, SSLv3 and TLSv1 in the one server and client.
        +
        + libcrypto.a:
        +     General encryption and X.509 v1/v3 stuff needed by SSL/TLS but not
        +     actually logically part of it. It includes routines for the following:
        +
        +     Ciphers
        +        libdes - EAY's libdes DES encryption package which was floating
        +                 around the net for a few years, and was then relicensed by
        +                 him as part of SSLeay.  It includes 15 'modes/variations'
        +                 of DES (1, 2 and 3 key versions of ecb, cbc, cfb and ofb;
        +                 pcbc and a more general form of cfb and ofb) including desx
        +                 in cbc mode, a fast crypt(3), and routines to read
        +                 passwords from the keyboard.
        +        RC4 encryption,
        +        RC2 encryption      - 4 different modes, ecb, cbc, cfb and ofb.
        +        Blowfish encryption - 4 different modes, ecb, cbc, cfb and ofb.
        +        IDEA encryption     - 4 different modes, ecb, cbc, cfb and ofb.
        +
        +     Digests
        +        MD5 and MD2 message digest algorithms, fast implementations,
        +        SHA (SHA-0) and SHA-1 message digest algorithms,
        +        MDC2 message digest. A DES based hash that is popular on smart cards.
        +
        +     Public Key
        +        RSA encryption/decryption/generation.
        +            There is no limit on the number of bits.
        +        DSA encryption/decryption/generation.
        +            There is no limit on the number of bits.
        +        Diffie-Hellman key-exchange/key generation.
        +            There is no limit on the number of bits.
        +
        +     X.509v3 certificates
        +        X509 encoding/decoding into/from binary ASN1 and a PEM
        +             based ASCII-binary encoding which supports encryption with a
        +             private key.  Program to generate RSA and DSA certificate
        +             requests and to generate RSA and DSA certificates.
        +
        +     Systems
        +        The normal digital envelope routines and base64 encoding.  Higher
        +        level access to ciphers and digests by name.  New ciphers can be
        +        loaded at run time.  The BIO io system which is a simple non-blocking
        +        IO abstraction.  Current methods supported are file descriptors,
        +        sockets, socket accept, socket connect, memory buffer, buffering, SSL
        +        client/server, file pointer, encryption, digest, non-blocking testing
        +        and null.
        +
        +     Data structures
        +        A dynamically growing hashing system
        +        A simple stack.
        +        A Configuration loader that uses a format similar to MS .ini files.
        +
        + openssl:
        +     A command line tool that can be used for:
        +        Creation of RSA, DH and DSA key parameters
        +        Creation of X.509 certificates, CSRs and CRLs
        +        Calculation of Message Digests
        +        Encryption and Decryption with Ciphers
        +        SSL/TLS Client and Server Tests
        +        Handling of S/MIME signed or encrypted mail
        +
        +
        + PATENTS
        + -------
        +
        + Various companies hold various patents for various algorithms in various
        + locations around the world. _YOU_ are responsible for ensuring that your use
        + of any algorithms is legal by checking if there are any patents in your
        + country.  The file contains some of the patents that we know about or are
        + rumored to exist. This is not a definitive list.
        +
        + RSA Security holds software patents on the RC5 algorithm.  If you
        + intend to use this cipher, you must contact RSA Security for
        + licensing conditions. Their web page is http://www.rsasecurity.com/.
        +
        + RC4 is a trademark of RSA Security, so use of this label should perhaps
        + only be used with RSA Security's permission.
        +
        + The IDEA algorithm is patented by Ascom in Austria, France, Germany, Italy,
        + Japan, the Netherlands, Spain, Sweden, Switzerland, UK and the USA.  They
        + should be contacted if that algorithm is to be used; their web page is
        + http://www.ascom.ch/.
        +
        + NTT and Mitsubishi have patents and pending patents on the Camellia
        + algorithm, but allow use at no charge without requiring an explicit
        + licensing agreement: http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
        +
        + INSTALLATION
        + ------------
        +
        + To install this package under a Unix derivative, read the INSTALL file.  For
        + a Win32 platform, read the INSTALL.W32 file.  For OpenVMS systems, read
        + INSTALL.VMS.
        +
        + Read the documentation in the doc/ directory.  It is quite rough, but it
        + lists the functions; you will probably have to look at the code to work out
        + how to use them. Look at the example programs.
        +
        + PROBLEMS
        + --------
        +
        + For some platforms, there are some known problems that may affect the user
        + or application author.  We try to collect those in doc/PROBLEMS, with current
        + thoughts on how they should be solved in a future of OpenSSL.
        +
        + SUPPORT
        + -------
        +
        + See the OpenSSL website www.openssl.org for details of how to obtain
        + commercial technical support.
        +
        + If you have any problems with OpenSSL then please take the following steps
        + first:
        +
        +    - Download the current snapshot from ftp://ftp.openssl.org/snapshot/
        +      to see if the problem has already been addressed
        +    - Remove ASM versions of libraries
        +    - Remove compiler optimisation flags
        +
        + If you wish to report a bug then please include the following information in
        + any bug report:
        +
        +    - On Unix systems:
        +        Self-test report generated by 'make report'
        +    - On other systems:
        +        OpenSSL version: output of 'openssl version -a'
        +        OS Name, Version, Hardware platform
        +        Compiler Details (name, version)
        +    - Application Details (name, version)
        +    - Problem Description (steps that will reproduce the problem, if known)
        +    - Stack Traceback (if the application dumps core)
        +
        + Report the bug to the OpenSSL project via the Request Tracker
        + (http://www.openssl.org/support/rt.html) by mail to:
        +
        +    openssl-bugs@openssl.org
        +
        + Note that the request tracker should NOT be used for general assistance
        + or support queries. Just because something doesn't work the way you expect
        + does not mean it is necessarily a bug in OpenSSL.
        +
        + Note that mail to openssl-bugs@openssl.org is recorded in the publicly
        + readable request tracker database and is forwarded to a public
        + mailing list. Confidential mail may be sent to openssl-security@openssl.org
        + (PGP key available from the key servers).
        +
        + HOW TO CONTRIBUTE TO OpenSSL
        + ----------------------------
        +
        + Development is coordinated on the openssl-dev mailing list (see
        + http://www.openssl.org for information on subscribing). If you
        + would like to submit a patch, send it to openssl-bugs@openssl.org with
        + the string "[PATCH]" in the subject. Please be sure to include a
        + textual explanation of what your patch does.
        +
        + If you are unsure as to whether a feature will be useful for the general
        + OpenSSL community please discuss it on the openssl-dev mailing list first.
        + Someone may be already working on the same thing or there may be a good
        + reason as to why that feature isn't implemented.
        +
        + Patches should be as up to date as possible, preferably relative to the
        + current Git or the last snapshot. They should follow the coding style of
        + OpenSSL and compile without warnings. Some of the core team developer targets
        + can be used for testing purposes, (debug-steve64, debug-geoff etc). OpenSSL
        + compiles on many varied platforms: try to ensure you only use portable
        + features.
        +
        + Note: For legal reasons, contributions from the US can be accepted only
        + if a TSU notification and a copy of the patch are sent to crypt@bis.doc.gov
        + (formerly BXA) with a copy to the ENC Encryption Request Coordinator;
        + please take some time to look at
        +    http://www.bis.doc.gov/Encryption/PubAvailEncSourceCodeNofify.html [sic]
        + and
        +    http://w3.access.gpo.gov/bis/ear/pdf/740.pdf (EAR Section 740.13(e))
        + for the details. If "your encryption source code is too large to serve as
        + an email attachment", they are glad to receive it by fax instead; hope you
        + have a cheap long-distance plan.
        +
        + Our preferred format for changes is "diff -u" output. You might
        + generate it like this:
        +
        + # cd openssl-work
        + # [your changes]
        + # ./Configure dist; make clean
        + # cd ..
        + # diff -ur openssl-orig openssl-work > mydiffs.patch
        +
        diff --git a/vendor/openssl/openssl/README.ASN1 b/vendor/openssl/openssl/README.ASN1
        new file mode 100644
        index 000000000..11bcfaf4d
        --- /dev/null
        +++ b/vendor/openssl/openssl/README.ASN1
        @@ -0,0 +1,187 @@
        +
        +OpenSSL ASN1 Revision
        +=====================
        +
        +This document describes some of the issues relating to the new ASN1 code.
        +
        +Previous OpenSSL ASN1 problems
        +=============================
        +
        +OK why did the OpenSSL ASN1 code need revising in the first place? Well
        +there are lots of reasons some of which are included below...
        +
        +1. The code is difficult to read and write. For every single ASN1 structure
        +(e.g. SEQUENCE) four functions need to be written for new, free, encode and
        +decode operations. This is a very painful and error prone operation. Very few
        +people have ever written any OpenSSL ASN1 and those that have usually wish
        +they hadn't.
        +
        +2. Partly because of 1. the code is bloated and takes up a disproportionate
        +amount of space. The SEQUENCE encoder is particularly bad: it essentially
        +contains two copies of the same operation, one to compute the SEQUENCE length
        +and the other to encode it.
        +
        +3. The code is memory based: that is it expects to be able to read the whole
        +structure from memory. This is fine for small structures but if you have a
        +(say) 1Gb PKCS#7 signedData structure it isn't such a good idea...
        +
        +4. The code for the ASN1 IMPLICIT tag is evil. It is handled by temporarily
        +changing the tag to the expected one, attempting to read it, then changing it
        +back again. This means that decode buffers have to be writable even though they
        +are ultimately unchanged. This gets in the way of constification.
        +
        +5. The handling of EXPLICIT isn't much better. It adds a chunk of code into 
        +the decoder and encoder for every EXPLICIT tag.
        +
        +6. APPLICATION and PRIVATE tags aren't even supported at all.
        +
        +7. Even IMPLICIT isn't complete: there is no support for implicitly tagged
        +types that are not OPTIONAL.
        +
        +8. Much of the code assumes that a tag will fit in a single octet. This is
        +only true if the tag is 30 or less (mercifully tags over 30 are rare).
        +
        +9. The ASN1 CHOICE type has to be largely handled manually, there aren't any
        +macros that properly support it.
        +
        +10. Encoders have no concept of OPTIONAL and have no error checking. If the
        +passed structure contains a NULL in a mandatory field it will not be encoded,
        +resulting in an invalid structure.
        +
        +11. It is tricky to add ASN1 encoders and decoders to external applications.
        +
        +Template model
        +==============
        +
        +One of the major problems with revision is the sheer volume of the ASN1 code.
        +Attempts to change (for example) the IMPLICIT behaviour would result in a
        +modification of *every* single decode function. 
        +
        +I decided to adopt a template based approach. I'm using the term 'template'
        +in a manner similar to SNACC templates: it has nothing to do with C++
        +templates.
        +
        +A template is a description of an ASN1 module as several constant C structures.
        +It describes in a machine readable way exactly how the ASN1 structure should
        +behave. If this template contains enough detail then it is possible to write
        +versions of new, free, encode, decode (and possibly others operations) that
        +operate on templates.
        +
        +Instead of having to write code to handle each operation only a single
        +template needs to be written. If new operations are needed (such as a 'print'
        +operation) only a single new template based function needs to be written 
        +which will then automatically handle all existing templates.
        +
        +Plans for revision
        +==================
        +
        +The revision will consist of the following steps. Other than the first two
        +these can be handled in any order.
        + 
        +o Design and write template new, free, encode and decode operations, initially
        +memory based. *DONE*
        +
        +o Convert existing ASN1 code to template form. *IN PROGRESS*
        +
        +o Convert an existing ASN1 compiler (probably SNACC) to output templates
        +in OpenSSL form.
        +
        +o Add support for BIO based ASN1 encoders and decoders to handle large
        +structures, initially blocking I/O.
        +
        +o Add support for non blocking I/O: this is quite a bit harder than blocking
        +I/O.
        +
        +o Add new ASN1 structures, such as OCSP, CRMF, S/MIME v3 (CMS), attribute
        +certificates etc etc.
        +
        +Description of major changes
        +============================
        +
        +The BOOLEAN type now takes three values. 0xff is TRUE, 0 is FALSE and -1 is
        +absent. The meaning of absent depends on the context. If for example the
        +boolean type is DEFAULT FALSE (as in the case of the critical flag for
        +certificate extensions) then -1 is FALSE, if DEFAULT TRUE then -1 is TRUE.
        +Usually the value will only ever be read via an API which will hide this from
        +an application.
        +
        +There is an evil bug in the old ASN1 code that mishandles OPTIONAL with
        +SEQUENCE OF or SET OF. These are both implemented as a STACK structure. The
        +old code would omit the structure if the STACK was NULL (which is fine) or if
        +it had zero elements (which is NOT OK). This causes problems because an empty
        +SEQUENCE OF or SET OF will result in an empty STACK when it is decoded but when
        +it is encoded it will be omitted resulting in different encodings. The new code
        +only omits the encoding if the STACK is NULL, if it contains zero elements it
        +is encoded and empty. There is an additional problem though: because an empty
        +STACK was omitted, sometimes the corresponding *_new() function would
        +initialize the STACK to empty so an application could immediately use it, if
        +this is done with the new code (i.e. a NULL) it wont work. Therefore a new
        +STACK should be allocated first. One instance of this is the X509_CRL list of
        +revoked certificates: a helper function X509_CRL_add0_revoked() has been added
        +for this purpose.
        +
        +The X509_ATTRIBUTE structure used to have an element called 'set' which took
        +the value 1 if the attribute value was a SET OF or 0 if it was a single. Due
        +to the behaviour of CHOICE in the new code this has been changed to a field
        +called 'single' which is 0 for a SET OF and 1 for single. The old field has
        +been deleted to deliberately break source compatibility. Since this structure
        +is normally accessed via higher level functions this shouldn't break too much.
        +
        +The X509_REQ_INFO certificate request info structure no longer has a field
        +called 'req_kludge'. This used to be set to 1 if the attributes field was
        +(incorrectly) omitted. You can check to see if the field is omitted now by
        +checking if the attributes field is NULL. Similarly if you need to omit
        +the field then free attributes and set it to NULL.
        +
        +The top level 'detached' field in the PKCS7 structure is no longer set when
        +a PKCS#7 structure is read in. PKCS7_is_detached() should be called instead.
        +The behaviour of PKCS7_get_detached() is unaffected.
        +
        +The values of 'type' in the GENERAL_NAME structure have changed. This is
        +because the old code use the ASN1 initial octet as the selector. The new
        +code uses the index in the ASN1_CHOICE template.
        +
        +The DIST_POINT_NAME structure has changed to be a true CHOICE type.
        +
        +typedef struct DIST_POINT_NAME_st {
        +int type;
        +union {
        +	STACK_OF(GENERAL_NAME) *fullname;
        +	STACK_OF(X509_NAME_ENTRY) *relativename;
        +} name;
        +} DIST_POINT_NAME;
        +
        +This means that name.fullname or name.relativename should be set
        +and type reflects the option. That is if name.fullname is set then
        +type is 0 and if name.relativename is set type is 1.
        +
        +With the old code using the i2d functions would typically involve:
        +
        +unsigned char *buf, *p;
        +int len;
        +/* Find length of encoding */
        +len = i2d_SOMETHING(x, NULL);
        +/* Allocate buffer */
        +buf = OPENSSL_malloc(len);
        +if(buf == NULL) {
        +	/* Malloc error */
        +}
        +/* Use temp variable because &p gets updated to point to end of
        + * encoding.
        + */
        +p = buf;
        +i2d_SOMETHING(x, &p);
        +
        +
        +Using the new i2d you can also do:
        +
        +unsigned char *buf = NULL;
        +int len;
        +len = i2d_SOMETHING(x, &buf);
        +if(len < 0) {
        +	/* Malloc error */
        +}
        +
        +and it will automatically allocate and populate a buffer with the
        +encoding. After this call 'buf' will point to the start of the
        +encoding which is len bytes long.
        diff --git a/vendor/openssl/openssl/README.ENGINE b/vendor/openssl/openssl/README.ENGINE
        new file mode 100644
        index 000000000..0ff833370
        --- /dev/null
        +++ b/vendor/openssl/openssl/README.ENGINE
        @@ -0,0 +1,289 @@
        +  ENGINE
        +  ======
        +
        +  With OpenSSL 0.9.6, a new component was added to support alternative
        +  cryptography implementations, most commonly for interfacing with external
        +  crypto devices (eg. accelerator cards). This component is called ENGINE,
        +  and its presence in OpenSSL 0.9.6 (and subsequent bug-fix releases)
        +  caused a little confusion as 0.9.6** releases were rolled in two
        +  versions, a "standard" and an "engine" version. In development for 0.9.7,
        +  the ENGINE code has been merged into the main branch and will be present
        +  in the standard releases from 0.9.7 forwards.
        +
        +  There are currently built-in ENGINE implementations for the following
        +  crypto devices:
        +
        +      o CryptoSwift
        +      o Compaq Atalla
        +      o nCipher CHIL
        +      o Nuron
        +      o Broadcom uBSec
        +
        +  In addition, dynamic binding to external ENGINE implementations is now
        +  provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE"
        +  section below for details.
        +
        +  At this stage, a number of things are still needed and are being worked on:
        +
        +      1 Integration of EVP support.
        +      2 Configuration support.
        +      3 Documentation!
        +
        +1 With respect to EVP, this relates to support for ciphers and digests in
        +  the ENGINE model so that alternative implementations of existing
        +  algorithms/modes (or previously unimplemented ones) can be provided by
        +  ENGINE implementations.
        +
        +2 Configuration support currently exists in the ENGINE API itself, in the
        +  form of "control commands". These allow an application to expose to the
        +  user/admin the set of commands and parameter types a given ENGINE
        +  implementation supports, and for an application to directly feed string
        +  based input to those ENGINEs, in the form of name-value pairs. This is an
        +  extensible way for ENGINEs to define their own "configuration" mechanisms
        +  that are specific to a given ENGINE (eg. for a particular hardware
        +  device) but that should be consistent across *all* OpenSSL-based
        +  applications when they use that ENGINE. Work is in progress (or at least
        +  in planning) for supporting these control commands from the CONF (or
        +  NCONF) code so that applications using OpenSSL's existing configuration
        +  file format can have ENGINE settings specified in much the same way.
        +  Presently however, applications must use the ENGINE API itself to provide
        +  such functionality. To see first hand the types of commands available
        +  with the various compiled-in ENGINEs (see further down for dynamic
        +  ENGINEs), use the "engine" openssl utility with full verbosity, ie;
        +       openssl engine -vvvv
        +
        +3 Documentation? Volunteers welcome! The source code is reasonably well
        +  self-documenting, but some summaries and usage instructions are needed -
        +  moreover, they are needed in the same POD format the existing OpenSSL
        +  documentation is provided in. Any complete or incomplete contributions
        +  would help make this happen.
        +
        +  STABILITY & BUG-REPORTS
        +  =======================
        +
        +  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. For the most part,
        +  the vendors of the devices these ENGINEs support have contributed to the
        +  development and/or testing of the implementations, and *usually* (with no
        +  guarantees) have experience in using the ENGINE support to drive their
        +  devices from common OpenSSL-based applications. Bugs and/or inexplicable
        +  behaviour in using a specific ENGINE implementation should be sent to the
        +  author of that implementation (if it is mentioned in the corresponding C
        +  file), and in the case of implementations for commercial hardware
        +  devices, also through whatever vendor support channels are available.  If
        +  none of this is possible, or the problem seems to be something about the
        +  ENGINE API itself (ie. not necessarily specific to a particular ENGINE
        +  implementation) then you should mail complete details to the relevant
        +  OpenSSL mailing list. For a definition of "complete details", refer to
        +  the OpenSSL "README" file. As for which list to send it to;
        +
        +     openssl-users: if you are *using* the ENGINE abstraction, either in an
        +          pre-compiled application or in your own application code.
        +
        +     openssl-dev: if you are discussing problems with OpenSSL source code.
        +
        +  USAGE
        +  =====
        +
        +  The default "openssl" ENGINE is always chosen when performing crypto
        +  operations unless you specify otherwise. You must actively tell the
        +  openssl utility commands to use anything else through a new command line
        +  switch called "-engine". Also, if you want to use the ENGINE support in
        +  your own code to do something similar, you must likewise explicitly
        +  select the ENGINE implementation you want.
        +
        +  Depending on the type of hardware, system, and configuration, "settings"
        +  may need to be applied to an ENGINE for it to function as expected/hoped.
        +  The recommended way of doing this is for the application to support
        +  ENGINE "control commands" so that each ENGINE implementation can provide
        +  whatever configuration primitives it might require and the application
        +  can allow the user/admin (and thus the hardware vendor's support desk
        +  also) to provide any such input directly to the ENGINE implementation.
        +  This way, applications do not need to know anything specific to any
        +  device, they only need to provide the means to carry such user/admin
        +  input through to the ENGINE in question. Ie. this connects *you* (and
        +  your helpdesk) to the specific ENGINE implementation (and device), and
        +  allows application authors to not get buried in hassle supporting
        +  arbitrary devices they know (and care) nothing about.
        +
        +  A new "openssl" utility, "openssl engine", has been added in that allows
        +  for testing and examination of ENGINE implementations. Basic usage
        +  instructions are available by specifying the "-?" command line switch.
        +
        +  DYNAMIC ENGINES
        +  ===============
        +
        +  The new "dynamic" ENGINE provides a low-overhead way to support ENGINE
        +  implementations that aren't pre-compiled and linked into OpenSSL-based
        +  applications. This could be because existing compiled-in implementations
        +  have known problems and you wish to use a newer version with an existing
        +  application. It could equally be because the application (or OpenSSL
        +  library) you are using simply doesn't have support for the ENGINE you
        +  wish to use, and the ENGINE provider (eg. hardware vendor) is providing
        +  you with a self-contained implementation in the form of a shared-library.
        +  The other use-case for "dynamic" is with applications that wish to
        +  maintain the smallest foot-print possible and so do not link in various
        +  ENGINE implementations from OpenSSL, but instead leaves you to provide
        +  them, if you want them, in the form of "dynamic"-loadable
        +  shared-libraries. It should be possible for hardware vendors to provide
        +  their own shared-libraries to support arbitrary hardware to work with
        +  applications based on OpenSSL 0.9.7 or later. If you're using an
        +  application based on 0.9.7 (or later) and the support you desire is only
        +  announced for versions later than the one you need, ask the vendor to
        +  backport their ENGINE to the version you need.
        +
        +  How does "dynamic" work?
        +  ------------------------
        +    The dynamic ENGINE has a special flag in its implementation such that
        +    every time application code asks for the 'dynamic' ENGINE, it in fact
        +    gets its own copy of it. As such, multi-threaded code (or code that
        +    multiplexes multiple uses of 'dynamic' in a single application in any
        +    way at all) does not get confused by 'dynamic' being used to do many
        +    independent things. Other ENGINEs typically don't do this so there is
        +    only ever 1 ENGINE structure of its type (and reference counts are used
        +    to keep order). The dynamic ENGINE itself provides absolutely no
        +    cryptographic functionality, and any attempt to "initialise" the ENGINE
        +    automatically fails. All it does provide are a few "control commands"
        +    that can be used to control how it will load an external ENGINE
        +    implementation from a shared-library. To see these control commands,
        +    use the command-line;
        +
        +       openssl engine -vvvv dynamic
        +
        +    The "SO_PATH" control command should be used to identify the
        +    shared-library that contains the ENGINE implementation, and "NO_VCHECK"
        +    might possibly be useful if there is a minor version conflict and you
        +    (or a vendor helpdesk) is convinced you can safely ignore it.
        +    "ID" is probably only needed if a shared-library implements
        +    multiple ENGINEs, but if you know the engine id you expect to be using,
        +    it doesn't hurt to specify it (and this provides a sanity check if
        +    nothing else). "LIST_ADD" is only required if you actually wish the
        +    loaded ENGINE to be discoverable by application code later on using the
        +    ENGINE's "id". For most applications, this isn't necessary - but some
        +    application authors may have nifty reasons for using it. The "LOAD"
        +    command is the only one that takes no parameters and is the command
        +    that uses the settings from any previous commands to actually *load*
        +    the shared-library ENGINE implementation. If this command succeeds, the
        +    (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE
        +    that has been loaded from the shared-library. As such, any control
        +    commands supported by the loaded ENGINE could then be executed as per
        +    normal. Eg. if ENGINE "foo" is implemented in the shared-library
        +    "libfoo.so" and it supports some special control command "CMD_FOO", the
        +    following code would load and use it (NB: obviously this code has no
        +    error checking);
        +
        +       ENGINE *e = ENGINE_by_id("dynamic");
        +       ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0);
        +       ENGINE_ctrl_cmd_string(e, "ID", "foo", 0);
        +       ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0);
        +       ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0);
        +
        +    For testing, the "openssl engine" utility can be useful for this sort
        +    of thing. For example the above code excerpt would achieve much the
        +    same result as;
        +
        +       openssl engine dynamic \
        +                 -pre SO_PATH:/lib/libfoo.so \
        +                 -pre ID:foo \
        +                 -pre LOAD \
        +                 -pre "CMD_FOO:some input data"
        +
        +    Or to simply see the list of commands supported by the "foo" ENGINE;
        +
        +       openssl engine -vvvv dynamic \
        +                 -pre SO_PATH:/lib/libfoo.so \
        +                 -pre ID:foo \
        +                 -pre LOAD
        +
        +    Applications that support the ENGINE API and more specifically, the
        +    "control commands" mechanism, will provide some way for you to pass
        +    such commands through to ENGINEs. As such, you would select "dynamic"
        +    as the ENGINE to use, and the parameters/commands you pass would
        +    control the *actual* ENGINE used. Each command is actually a name-value
        +    pair and the value can sometimes be omitted (eg. the "LOAD" command).
        +    Whilst the syntax demonstrated in "openssl engine" uses a colon to
        +    separate the command name from the value, applications may provide
        +    their own syntax for making that separation (eg. a win32 registry
        +    key-value pair may be used by some applications). The reason for the
        +    "-pre" syntax in the "openssl engine" utility is that some commands
        +    might be issued to an ENGINE *after* it has been initialised for use.
        +    Eg. if an ENGINE implementation requires a smart-card to be inserted
        +    during initialisation (or a PIN to be typed, or whatever), there may be
        +    a control command you can issue afterwards to "forget" the smart-card
        +    so that additional initialisation is no longer possible. In
        +    applications such as web-servers, where potentially volatile code may
        +    run on the same host system, this may provide some arguable security
        +    value. In such a case, the command would be passed to the ENGINE after
        +    it has been initialised for use, and so the "-post" switch would be
        +    used instead. Applications may provide a different syntax for
        +    supporting this distinction, and some may simply not provide it at all
        +    ("-pre" is almost always what you're after, in reality).
        +
        +  How do I build a "dynamic" ENGINE?
        +  ----------------------------------
        +    This question is trickier - currently OpenSSL bundles various ENGINE
        +    implementations that are statically built in, and any application that
        +    calls the "ENGINE_load_builtin_engines()" function will automatically
        +    have all such ENGINEs available (and occupying memory). Applications
        +    that don't call that function have no ENGINEs available like that and
        +    would have to use "dynamic" to load any such ENGINE - but on the other
        +    hand such applications would only have the memory footprint of any
        +    ENGINEs explicitly loaded using user/admin provided control commands.
        +    The main advantage of not statically linking ENGINEs and only using
        +    "dynamic" for hardware support is that any installation using no
        +    "external" ENGINE suffers no unnecessary memory footprint from unused
        +    ENGINEs. Likewise, installations that do require an ENGINE incur the
        +    overheads from only *that* ENGINE once it has been loaded.
        +
        +    Sounds good? Maybe, but currently building an ENGINE implementation as
        +    a shared-library that can be loaded by "dynamic" isn't automated in
        +    OpenSSL's build process. It can be done manually quite easily however.
        +    Such a shared-library can either be built with any OpenSSL code it
        +    needs statically linked in, or it can link dynamically against OpenSSL
        +    if OpenSSL itself is built as a shared library. The instructions are
        +    the same in each case, but in the former (statically linked any
        +    dependencies on OpenSSL) you must ensure OpenSSL is built with
        +    position-independent code ("PIC"). The default OpenSSL compilation may
        +    already specify the relevant flags to do this, but you should consult
        +    with your compiler documentation if you are in any doubt.
        +
        +    This example will show building the "atalla" ENGINE in the
        +    crypto/engine/ directory as a shared-library for use via the "dynamic"
        +    ENGINE.
        +    1) "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL
        +       source tree.
        +    2) Recompile at least one source file so you can see all the compiler
        +       flags (and syntax) being used to build normally. Eg;
        +           touch hw_atalla.c ; make
        +       will rebuild "hw_atalla.o" using all such flags.
        +    3) Manually enter the same compilation line to compile the
        +       "hw_atalla.c" file but with the following two changes;
        +         (a) add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches,
        +	 (b) change the output file from "hw_atalla.o" to something new,
        +             eg. "tmp_atalla.o"
        +    4) Link "tmp_atalla.o" into a shared-library using the top-level
        +       OpenSSL libraries to resolve any dependencies. The syntax for doing
        +       this depends heavily on your system/compiler and is a nightmare
        +       known well to anyone who has worked with shared-library portability
        +       before. 'gcc' on Linux, for example, would use the following syntax;
        +          gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto
        +    5) Test your shared library using "openssl engine" as explained in the
        +       previous section. Eg. from the top-level directory, you might try;
        +          apps/openssl engine -vvvv dynamic \
        +              -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD
        +       If the shared-library loads successfully, you will see both "-pre"
        +       commands marked as "SUCCESS" and the list of control commands
        +       displayed (because of "-vvvv") will be the control commands for the
        +       *atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add
        +       the "-t" switch to the utility if you want it to try and initialise
        +       the atalla ENGINE for use to test any possible hardware/driver
        +       issues.
        +
        +  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/vendor/openssl/openssl/VMS/TODO b/vendor/openssl/openssl/VMS/TODO
        new file mode 100644
        index 000000000..359e06919
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/TODO
        @@ -0,0 +1,18 @@
        +TODO:
        +=====
        +
        +There are a few things that need to be worked out in the VMS version of
        +OpenSSL, still:
        +
        +- Description files. ("Makefile's" :-))
        +- Script code to link an already compiled build tree.
        +- A VMSINSTALlable version (way in the future, unless someone else hacks).
        +- shareable images (DLL for you Windows folks).
        +
        +There may be other things that I have missed and that may be desirable.
        +Please send mail to <openssl-users@openssl.org> or to me directly if you
        +have any ideas.
        +
        +--
        +Richard Levitte <richard@levitte.org>
        +1999-05-24
        diff --git a/vendor/openssl/openssl/VMS/VMSify-conf.pl b/vendor/openssl/openssl/VMS/VMSify-conf.pl
        new file mode 100644
        index 000000000..d3be6a29e
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/VMSify-conf.pl
        @@ -0,0 +1,34 @@
        +#! /usr/bin/perl
        +
        +use strict;
        +use warnings;
        +
        +my @directory_vars = ( "dir", "certs", "crl_dir", "new_certs_dir" );
        +my @file_vars = ( "database", "certificate", "serial", "crlnumber",
        +		  "crl", "private_key", "RANDFILE" );
        +while(<STDIN>) {
        +    chomp;
        +    foreach my $d (@directory_vars) {
        +	if (/^(\s*\#?\s*${d}\s*=\s*)\.\/([^\s\#]*)([\s\#].*)$/) {
        +	    $_ = "$1sys\\\$disk:\[.$2$3";
        +	} elsif (/^(\s*\#?\s*${d}\s*=\s*)(\w[^\s\#]*)([\s\#].*)$/) {
        +	    $_ = "$1sys\\\$disk:\[.$2$3";
        +	}
        +	s/^(\s*\#?\s*${d}\s*=\s*\$\w+)\/([^\s\#]*)([\s\#].*)$/$1.$2\]$3/;
        +	while(/^(\s*\#?\s*${d}\s*=\s*(\$\w+\.|sys\\\$disk:\[\.)[\w\.]+)\/([^\]]*)\](.*)$/) {
        +	    $_ = "$1.$3]$4";
        +	}
        +    }
        +    foreach my $f (@file_vars) {
        +	s/^(\s*\#?\s*${f}\s*=\s*)\.\/(.*)$/$1sys\\\$disk:\[\/$2/;
        +	while(/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/(\w+\/[^\s\#]*)([\s\#].*)$/) {
        +	    $_ = "$1.$3$4";
        +	}
        +	if (/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/(\w+)([\s\#].*)$/) {
        +	    $_ = "$1]$3.$4";
        +	} elsif  (/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/([^\s\#]*)([\s\#].*)$/) {
        +	    $_ = "$1]$3$4";
        +	}
        +   }
        +    print $_,"\n";
        +}
        diff --git a/vendor/openssl/openssl/VMS/WISHLIST.TXT b/vendor/openssl/openssl/VMS/WISHLIST.TXT
        new file mode 100644
        index 000000000..c151fc8ea
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/WISHLIST.TXT
        @@ -0,0 +1,4 @@
        +* Have the building procedure contain a LINK-only possibility.
        +  Wished by Mark Daniel <mark.daniel@dsto.defence.gov.au>
        +
        +  One way to enable that is also to go over to DESCRIP.MMS files.
        diff --git a/vendor/openssl/openssl/VMS/install-vms.com b/vendor/openssl/openssl/VMS/install-vms.com
        new file mode 100644
        index 000000000..7da8b2153
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/install-vms.com
        @@ -0,0 +1,67 @@
        +$! install-vms.com -- Installs the files in a given directory tree
        +$!
        +$! Author: Richard Levitte <richard@levitte.org>
        +$! Time of creation: 23-MAY-1998 19:22
        +$!
        +$! P1	root of the directory tree
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ on error then goto tidy
        +$ on control_c then goto tidy
        +$!
        +$ if p1 .eqs. ""
        +$ then
        +$   write sys$output "First argument missing."
        +$   write sys$output -
        +     "Should be the directory where you want things installed."
        +$   exit
        +$ endif
        +$
        +$ if (f$getsyi( "cpu") .lt. 128)
        +$ then
        +$   arch = "VAX"
        +$ else
        +$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
        +$   if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$
        +$ root = f$parse( P1, "[]A.;0", , , "SYNTAX_ONLY, NO_CONCEAL")- "A.;0"
        +$ root_dev = f$parse( root, , , "device", "syntax_only")
        +$ root_dir = f$parse( root, , , "directory", "syntax_only") - -
        +   "[000000." - "][" - "[" - "]"
        +$ root = root_dev + "[" + root_dir
        +$
        +$ define /nolog wrk_sslroot 'root'.] /translation_attributes = concealed
        +$ define /nolog wrk_sslinclude wrk_sslroot:[include]
        +$
        +$ if f$parse( "wrk_sslroot:[000000]") .eqs. "" then -
        +   create /directory /log wrk_sslroot:[000000]
        +$ if f$parse( "wrk_sslinclude:") .eqs. "" then -
        +   create /directory /log wrk_sslinclude:
        +$ if f$parse( "wrk_sslroot:[vms]") .eqs. "" then -
        +   create /directory /log wrk_sslroot:[vms]
        +$!
        +$ copy /log /protection = world:re openssl_startup.com wrk_sslroot:[vms]
        +$ copy /log /protection = world:re openssl_undo.com wrk_sslroot:[vms]
        +$ copy /log /protection = world:re openssl_utils.com wrk_sslroot:[vms]
        +$!
        +$ tidy:
        +$!
        +$ call deass wrk_sslroot
        +$ call deass wrk_sslinclude
        +$!
        +$ exit
        +$!
        +$ deass: subroutine
        +$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
        +$ then
        +$   deassign /process 'p1'
        +$ endif
        +$ endsubroutine
        +$!
        diff --git a/vendor/openssl/openssl/VMS/mkshared.com b/vendor/openssl/openssl/VMS/mkshared.com
        new file mode 100644
        index 000000000..b0d1fdaac
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/mkshared.com
        @@ -0,0 +1,476 @@
        +$! MKSHARED.COM -- Create shareable images.
        +$!
        +$! P1: "64" for 64-bit pointers.
        +$!
        +$! P2: Zlib object library path (optional).
        +$!
        +$! Input:	[.UTIL]LIBEAY.NUM,[.xxx.EXE.CRYPTO]SSL_LIBCRYPTO[32].OLB
        +$!		[.UTIL]SSLEAY.NUM,[.xxx.EXE.SSL]SSL_LIBSSL[32].OLB
        +$!		[.CRYPTO.xxx]OPENSSLCONF.H
        +$! Output:	[.xxx.EXE.CRYPTO]SSL_LIBCRYPTO_SHR[32].OPT,.MAP,.EXE
        +$!		[.xxx.EXE.SSL]SSL_LIBSSL_SRH[32].OPT,.MAP,.EXE
        +$!
        +$! So far, tests have only been made on VMS for Alpha.  VAX will come in time.
        +$! ===========================================================================
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$! Save the original default device:[directory].
        +$!
        +$ def_orig = f$environment( "default")
        +$ on error then goto tidy
        +$ on control_c then goto tidy
        +$!
        +$! SET DEFAULT to the main kit directory.
        +$!
        +$ proc = f$environment("procedure")
        +$ proc = f$parse( "A.;", proc)- "A.;"
        +$ set default 'proc'
        +$ set default [-]
        +$!
        +$! ----- Prepare info for processing: version number and file info
        +$ gosub read_version_info
        +$ if libver .eqs. ""
        +$ then
        +$   write sys$error "ERROR: Couldn't find any library version info..."
        +$   go to tidy:
        +$ endif
        +$
        +$ if (f$getsyi("cpu") .lt. 128)
        +$ then
        +$   arch_vax = 1
        +$   arch = "VAX"
        +$ else
        +$   arch_vax = 0
        +$   arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$   if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$!
        +$ archd = arch
        +$ lib32 = "32"
        +$ shr = "SHR32"
        +$!
        +$ if (p1 .nes. "")
        +$ then
        +$   if (p1 .eqs. "64")
        +$   then
        +$     archd = arch+ "_64"
        +$     lib32 = ""
        +$     shr = "SHR"
        +$   else
        +$     if (p1 .nes. "32")
        +$     then
        +$       write sys$output "Second argument invalid."
        +$       write sys$output "It should be "32", "64", or nothing."
        +$       exit
        +$     endif
        +$   endif
        +$ endif
        +$!
        +$! ----- Prepare info for processing: disabled algorithms info
        +$ gosub read_disabled_algorithms_info
        +$!
        +$ ZLIB = p2
        +$ zlib_lib = ""
        +$ if (ZLIB .nes. "")
        +$ then
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "syntax_only")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     write sys$output ""
        +$     write sys$output "The Option ", ZLIB, " Is Invalid."
        +$     write sys$output "    Can't find library: ''file2'"
        +$     write sys$output ""
        +$     goto tidy
        +$   endif
        +$   zlib_lib = ", ''file2' /library"
        +$ endif
        +$!
        +$ if (arch_vax)
        +$ then
        +$   libtit = "CRYPTO_TRANSFER_VECTOR"
        +$   libid  = "Crypto"
        +$   libnum = "[.UTIL]LIBEAY.NUM"
        +$   libdir = "[.''ARCHD'.EXE.CRYPTO]"
        +$   libmar = "''libdir'SSL_LIBCRYPTO_''shr'.MAR"
        +$   libolb = "''libdir'SSL_LIBCRYPTO''lib32'.OLB"
        +$   libopt = "''libdir'SSL_LIBCRYPTO_''shr'.OPT"
        +$   libobj = "''libdir'SSL_LIBCRYPTO_''shr'.OBJ"
        +$   libmap = "''libdir'SSL_LIBCRYPTO_''shr'.MAP"
        +$   libgoal= "''libdir'SSL_LIBCRYPTO_''shr'.EXE"
        +$   libref = ""
        +$   libvec = "LIBCRYPTO"
        +$   if f$search( libolb) .nes. "" then gosub create_vax_shr
        +$   libtit = "SSL_TRANSFER_VECTOR"
        +$   libid  = "SSL"
        +$   libnum = "[.UTIL]SSLEAY.NUM"
        +$   libdir = "[.''ARCHD'.EXE.SSL]"
        +$   libmar = "''libdir'SSL_LIBSSL_''shr'.MAR"
        +$   libolb = "''libdir'SSL_LIBSSL''lib32'.OLB"
        +$   libopt = "''libdir'SSL_LIBSSL_''shr'.OPT"
        +$   libobj = "''libdir'SSL_LIBSSL_''shr'.OBJ"
        +$   libmap = "''libdir'SSL_LIBSSL_''shr'.MAP"
        +$   libgoal= "''libdir'SSL_LIBSSL_''shr'.EXE"
        +$   libref = "[.''ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO_''shr'.EXE"
        +$   libvec = "LIBSSL"
        +$   if f$search( libolb) .nes. "" then gosub create_vax_shr
        +$ else
        +$   libid  = "Crypto"
        +$   libnum = "[.UTIL]LIBEAY.NUM"
        +$   libdir = "[.''ARCHD'.EXE.CRYPTO]"
        +$   libolb = "''libdir'SSL_LIBCRYPTO''lib32'.OLB"
        +$   libopt = "''libdir'SSL_LIBCRYPTO_''shr'.OPT"
        +$   libmap = "''libdir'SSL_LIBCRYPTO_''shr'.MAP"
        +$   libgoal= "''libdir'SSL_LIBCRYPTO_''shr'.EXE"
        +$   libref = ""
        +$   if f$search( libolb) .nes. "" then gosub create_nonvax_shr
        +$   libid  = "SSL"
        +$   libnum = "[.UTIL]SSLEAY.NUM"
        +$   libdir = "[.''ARCHD'.EXE.SSL]"
        +$   libolb = "''libdir'SSL_LIBSSL''lib32'.OLB"
        +$   libopt = "''libdir'SSL_LIBSSL_''shr'.OPT"
        +$   libmap = "''libdir'SSL_LIBSSL_''shr'.MAP"
        +$   libgoal= "''libdir'SSL_LIBSSL_''shr'.EXE"
        +$   libref = "[.''ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO_''shr'.EXE"
        +$   if f$search( libolb) .nes. "" then gosub create_nonvax_shr
        +$ endif
        +$!
        +$ tidy:
        +$!
        +$! Close any open files.
        +$!
        +$ if (f$trnlnm( "libnum", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close libnum
        +$!
        +$ if (f$trnlnm( "mar", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close mar
        +$!
        +$ if (f$trnlnm( "opt", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close opt
        +$!
        +$ if (f$trnlnm( "vf", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close vf
        +$!
        +$! Restore the original default device:[directory].
        +$!
        +$ set default 'def_orig'
        +$ exit
        +$
        +$! ----- Subroutines to build the shareable libraries
        +$! For each supported architecture, there's a main shareable library
        +$! creator, which is called from the main code above.
        +$! The creator will define a number of variables to tell the next levels of
        +$! subroutines what routines to use to write to the option files, call the
        +$! main processor, read_func_num, and when that is done, it will write version
        +$! data at the end of the .opt file, close it, and link the library.
        +$!
        +$! read_func_num reads through a .num file and calls the writer routine for
        +$! each line.  It's also responsible for checking that order is properly kept
        +$! in the .num file, check that each line applies to VMS and the architecture,
        +$! and to fill in "holes" with dummy entries.
        +$!
        +$! The creator routines depend on the following variables:
        +$! libnum	The name of the .num file to use as input
        +$! libolb	The name of the object library to build from
        +$! libid	The identification string of the shareable library
        +$! libopt	The name of the .opt file to write
        +$! libtit	The title of the assembler transfer vector file (VAX only)
        +$! libmar	The name of the assembler transfer vector file (VAX only)
        +$! libmap	The name of the map file to write
        +$! libgoal	The name of the shareable library to write
        +$! libref	The name of a shareable library to link in
        +$!
        +$! read_func_num depends on the following variables from the creator:
        +$! libwriter	The name of the writer routine to call for each .num file line
        +$! -----
        +$
        +$! ----- Subroutines for non-VAX
        +$! -----
        +$! The creator routine
        +$ create_nonvax_shr:
        +$   open /write opt 'libopt'
        +$   write opt "identification=""",libid," ",libverstr,""""
        +$   write opt libolb, " /library"
        +$   if libref .nes. "" then write opt libref,"/SHARE"
        +$   write opt "SYMBOL_VECTOR=(-"
        +$   libfirstentry := true
        +$   libwrch   := opt
        +$   libwriter := write_nonvax_transfer_entry
        +$   textcount = 0
        +$   gosub read_func_num
        +$   write opt ")"
        +$   write opt "GSMATCH=",libvmatch,",",libver
        +$   close opt
        +$   link /map = 'libmap' /full /share = 'libgoal' 'libopt' /options -
        +     'zlib_lib'
        +$   return
        +$
        +$! The record writer routine
        +$ write_nonvax_transfer_entry:
        +$   if libentry .eqs. ".dummy" then return
        +$   if info_kind .eqs. "VARIABLE"
        +$   then
        +$     pr:=DATA
        +$   else
        +$     pr:=PROCEDURE
        +$   endif
        +$   textcount_this = f$length(pr) + f$length(libentry) + 5
        +$   if textcount + textcount_this .gt. 1024
        +$   then
        +$     write opt ")"
        +$     write opt "SYMBOL_VECTOR=(-"
        +$     textcount = 16
        +$     libfirstentry := true
        +$   endif
        +$   if libfirstentry
        +$   then
        +$     write 'libwrch' "    ",libentry,"=",pr," -"
        +$   else
        +$     write 'libwrch' "    ,",libentry,"=",pr," -"
        +$   endif
        +$   libfirstentry := false
        +$   textcount = textcount + textcount_this
        +$   return
        +$
        +$! ----- Subroutines for VAX
        +$! -----
        +$! The creator routine
        +$ create_vax_shr:
        +$   open /write mar 'libmar'
        +$   type sys$input:/out=mar:
        +;
        +; Transfer vector for VAX shareable image
        +;
        +$   write mar "	.TITLE ",libtit
        +$   write mar "	.IDENT /",libid,"/"
        +$   type sys$input:/out=mar:
        +;
        +; Define macro to assist in building transfer vector entries.  Each entry
        +; should take no more than 8 bytes.
        +;
        +	.MACRO FTRANSFER_ENTRY routine
        +	.ALIGN QUAD
        +	.TRANSFER routine
        +	.MASK	routine
        +	JMP	routine+2
        +	.ENDM FTRANSFER_ENTRY
        +;
        +; Place entries in own program section.
        +;
        +$   write mar "	.PSECT $$",libvec,",QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT"
        +$   write mar libvec,"_xfer:"
        +$   libwrch   := mar
        +$   libwriter := write_vax_ftransfer_entry
        +$   gosub read_func_num
        +$   type sys$input:/out=mar:
        +;
        +; Allocate extra storage at end of vector to allow for expansion.
        +;
        +$   write mar "	.BLKB 32768-<.-",libvec,"_xfer>	; 64 pages total."
        +$!   libwriter := write_vax_vtransfer_entry
        +$!   gosub read_func_num
        +$   write mar "	.END"
        +$   close mar
        +$   open /write opt 'libopt'
        +$   write opt "identification=""",libid," ",libverstr,""""
        +$   write opt libobj
        +$   write opt libolb, " /library"
        +$   if libref .nes. "" then write opt libref,"/SHARE"
        +$   type sys$input:/out=opt:
        +!
        +! Ensure transfer vector is at beginning of image
        +!
        +CLUSTER=FIRST
        +$   write opt "COLLECT=FIRST,$$",libvec
        +$   write opt "GSMATCH=",libvmatch,",",libver
        +$   type sys$input:/out=opt:
        +!
        +! make psects nonshareable so image can be installed.
        +!
        +PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
        +$   libwrch   := opt
        +$   libwriter := write_vax_psect_attr
        +$   gosub read_func_num
        +$   close opt
        +$   macro/obj='libobj' 'libmar'
        +$   link /map = 'libmap' /full /share = 'libgoal' 'libopt' /options -
        +     'zlib_lib'
        +$   return
        +$
        +$! The record writer routine for VAX functions
        +$ write_vax_ftransfer_entry:
        +$   if info_kind .nes. "FUNCTION" then return
        +$   if libentry .eqs ".dummy"
        +$   then
        +$     write 'libwrch' "	.BLKB 8" ! Dummy is zeroes...
        +$   else
        +$     write 'libwrch' "	FTRANSFER_ENTRY ",libentry
        +$   endif
        +$   return
        +$! The record writer routine for VAX variables (should never happen!)
        +$ write_vax_psect_attr:
        +$   if info_kind .nes. "VARIABLE" then return
        +$   if libentry .eqs ".dummy" then return
        +$   write 'libwrch' "PSECT_ATTR=",libentry,",NOSHR"
        +$   return
        +$
        +$! ----- Common subroutines
        +$! -----
        +$! The .num file reader.  This one has great responsibility.
        +$ read_func_num:
        +$   open /read libnum 'libnum'
        +$   goto read_nums
        +$
        +$ read_nums:
        +$   libentrynum=0
        +$   liblastentry:=false
        +$   entrycount=0
        +$   loop:
        +$     read /end=loop_end /err=loop_end libnum line
        +$     lin = f$edit( line, "COMPRESS,TRIM")
        +$!    Skip a "#" comment line.
        +$     if (f$extract( 0, 1, lin) .eqs. "#") then goto loop
        +$     entrynum = f$int(f$element( 1, " ", lin))
        +$     entryinfo = f$element( 2, " ", lin)
        +$     curentry = f$element( 0, " ", lin)
        +$     info_exist = f$element( 0, ":", entryinfo)
        +$     info_platforms = ","+ f$element(1, ":", entryinfo)+ ","
        +$     info_kind = f$element( 2, ":", entryinfo)
        +$     info_algorithms = ","+ f$element( 3, ":", entryinfo)+ ","
        +$     if info_exist .eqs. "NOEXIST" then goto loop
        +$     truesum = 0
        +$     falsesum = 0
        +$     negatives = 1
        +$     plat_i = 0
        +$     loop1:
        +$       plat_entry = f$element( plat_i, ",", info_platforms)
        +$       plat_i = plat_i + 1
        +$       if plat_entry .eqs. "" then goto loop1
        +$       if plat_entry .nes. ","
        +$       then
        +$         if f$extract(0,1,plat_entry) .nes. "!" then negatives = 0
        +$         if (arch_vax)
        +$         then
        +$           if plat_entry .eqs. "EXPORT_VAR_AS_FUNCTION" then -
        +$             truesum = truesum + 1
        +$           if plat_entry .eqs. "!EXPORT_VAR_AS_FUNCTION" then -
        +$             falsesum = falsesum + 1
        +$         endif
        +$!
        +$         if ((plat_entry .eqs. "VMS") .or. -
        +            ((plat_entry .eqs. "ZLIB") .and. (ZLIB .nes. "")) .or. -
        +            (arch_vax .and. (plat_entry .eqs. "VMSVAX"))) then -
        +            truesum = truesum + 1
        +$!
        +$         if ((plat_entry .eqs. "!VMS") .or. -
        +            (arch_vax .and. (plat_entry .eqs. "!VMSVAX"))) then -
        +            falsesum = falsesum + 1
        +$!
        +$	  goto loop1
        +$       endif
        +$     endloop1:
        +$!DEBUG!$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
        +$!DEBUG!$     then
        +$!DEBUG!$       write sys$output line
        +$!DEBUG!$       write sys$output "        truesum = ",truesum,-
        +$!DEBUG!		", negatives = ",negatives,", falsesum = ",falsesum
        +$!DEBUG!$     endif
        +$     if falsesum .ne. 0 then goto loop
        +$     if truesum+negatives .eq. 0 then goto loop
        +$     alg_i = 0
        +$     loop2:
        +$       alg_entry = f$element(alg_i,",",info_algorithms)
        +$	alg_i = alg_i + 1
        +$       if alg_entry .eqs. "" then goto loop2
        +$       if alg_entry .nes. ","
        +$       then
        +$	  if disabled_algorithms - ("," + alg_entry + ",") .nes disabled_algorithms then goto loop
        +$         if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop
        +$	  goto loop2
        +$       endif
        +$     endloop2:
        +$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
        +$     then
        +$!DEBUG!$     write sys$output curentry," ; ",entrynum," ; ",entryinfo
        +$     endif
        +$   redo:
        +$     next:=loop
        +$     tolibentry=curentry
        +$     if libentrynum .ne. entrynum
        +$     then
        +$       entrycount=entrycount+1
        +$       if entrycount .lt. entrynum
        +$       then
        +$!DEBUG!$         write sys$output "Info: entrycount: ''entrycount', entrynum: ''entrynum' => 0"
        +$         tolibentry=".dummy"
        +$         next:=redo
        +$       endif
        +$       if entrycount .gt. entrynum
        +$       then
        +$         write sys$error "Decreasing library entry numbers!  Can't continue"
        +$         write sys$error """",line,""""
        +$         close libnum
        +$         return
        +$       endif
        +$       libentry=tolibentry
        +$!DEBUG!$       write sys$output entrycount," ",libentry," ",entryinfo
        +$       if libentry .nes. "" .and. libwriter .nes. "" then gosub 'libwriter'
        +$     else
        +$       write sys$error "Info: ""''curentry'"" is an alias for ""''libentry'"".  Overriding..."
        +$     endif
        +$     libentrynum=entrycount
        +$     goto 'next'
        +$   loop_end:
        +$   close libnum
        +$   return
        +$
        +$! The version number reader
        +$ read_version_info:
        +$   libver = ""
        +$   open /read vf [.CRYPTO]OPENSSLV.H
        +$   loop_rvi:
        +$     read/err=endloop_rvi/end=endloop_rvi vf rvi_line
        +$     if rvi_line - "SHLIB_VERSION_NUMBER """ .eqs. rvi_line then -
        +	goto loop_rvi
        +$     libverstr = f$element(1,"""",rvi_line)
        +$     libvmajor = f$element(0,".",libverstr)
        +$     libvminor = f$element(1,".",libverstr)
        +$     libvedit = f$element(2,".",libverstr)
        +$     libvpatch = f$cvui(0,8,f$extract(1,1,libvedit)+"@")-f$cvui(0,8,"@")
        +$     libvedit = f$extract(0,1,libvedit)
        +$     libver = f$string(f$int(libvmajor)*100)+","+-
        +	f$string(f$int(libvminor)*100+f$int(libvedit)*10+f$int(libvpatch))
        +$     if libvmajor .eqs. "0"
        +$     then
        +$       libvmatch = "EQUAL"
        +$     else
        +$       ! Starting with the 1.0 release, backward compatibility should be
        +$       ! kept, so switch over to the following
        +$       libvmatch = "LEQUAL"
        +$     endif
        +$   endloop_rvi:
        +$   close vf
        +$   return
        +$
        +$! The disabled algorithms reader
        +$ read_disabled_algorithms_info:
        +$   disabled_algorithms = ","
        +$   open /read cf [.CRYPTO.'ARCH']OPENSSLCONF.H
        +$   loop_rci:
        +$     read/err=endloop_rci/end=endloop_rci cf rci_line
        +$     rci_line = f$edit(rci_line,"TRIM,COMPRESS")
        +$     rci_ei = 0
        +$     if f$extract(0,9,rci_line) .eqs. "# define " then rci_ei = 2
        +$     if f$extract(0,8,rci_line) .eqs. "#define " then rci_ei = 1
        +$     if rci_ei .eq. 0 then goto loop_rci
        +$     rci_e = f$element(rci_ei," ",rci_line)
        +$     if f$extract(0,11,rci_e) .nes. "OPENSSL_NO_" then goto loop_rci
        +$     disabled_algorithms = disabled_algorithms + f$extract(11,999,rci_e) + ","
        +$     goto loop_rci
        +$   endloop_rci:
        +$   close cf
        +$   return
        diff --git a/vendor/openssl/openssl/VMS/multinet_shr.opt b/vendor/openssl/openssl/VMS/multinet_shr.opt
        new file mode 100644
        index 000000000..610f42ddd
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/multinet_shr.opt
        @@ -0,0 +1 @@
        +multinet:multinet_socket_library.exe/share
        diff --git a/vendor/openssl/openssl/VMS/openssl_startup.com b/vendor/openssl/openssl/VMS/openssl_startup.com
        new file mode 100644
        index 000000000..04bbbde88
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/openssl_startup.com
        @@ -0,0 +1,108 @@
        +$!
        +$! Startup file for OpenSSL 1.x.
        +$!
        +$! 2011-03-05 SMS.
        +$!
        +$! This procedure must reside in the OpenSSL installation directory.
        +$! It will fail if it is copied to a different location.
        +$!
        +$! P1  qualifier(s) for DEFINE.  For example, "/SYSTEM" to get the
        +$!     logical names defined in the system logical name table.
        +$!
        +$! P2  "64", to use executables which were built with 64-bit pointers.
        +$!
        +$! Good (default) and bad status values.
        +$!
        +$ status =    %x00010001 ! RMS$_NORMAL, normal successful completion.
        +$ rms_e_fnf = %x00018292 ! RMS$_FNF, file not found.
        +$!
        +$! Prepare for problems.
        +$!
        +$ orig_dev_dir = f$environment( "DEFAULT")
        +$ on control_y then goto clean_up
        +$ on error then goto clean_up
        +$!
        +$! Determine hardware architecture.
        +$!
        +$ if (f$getsyi( "cpu") .lt. 128)
        +$ then
        +$   arch_name = "VAX"
        +$ else
        +$   arch_name = f$edit( f$getsyi( "arch_name"), "upcase")
        +$   if (arch_name .eqs. "") then arch_name = "UNK"
        +$ endif
        +$!
        +$ if (p2 .eqs. "64")
        +$ then
        +$   arch_name_exe = arch_name+ "_64"
        +$ else
        +$   arch_name_exe = arch_name
        +$ endif
        +$!
        +$! Derive the OpenSSL installation device:[directory] from the location
        +$! of this command procedure.
        +$!
        +$ proc = f$environment( "procedure")
        +$ proc_dev_dir = f$parse( "A.;", proc, , , "no_conceal") - "A.;"
        +$ proc_dev = f$parse( proc_dev_dir, , , "device", "syntax_only")
        +$ proc_dir = f$parse( proc_dev_dir, , , "directory", "syntax_only") - -
        +   ".][000000"- "[000000."- "]["- "["- "]"
        +$ proc_dev_dir = proc_dev+ "["+ proc_dir+ "]"
        +$ set default 'proc_dev_dir'
        +$ set default [-]
        +$ ossl_dev_dir = f$environment( "default")
        +$!
        +$! Check existence of expected directories (to see if this procedure has
        +$! been moved away from its proper place).
        +$!
        +$ if ((f$search( "certs.dir;1") .eqs. "") .or. -
        +   (f$search( "include.dir;1") .eqs. "") .or. -
        +   (f$search( "private.dir;1") .eqs. "") .or. -
        +   (f$search( "vms.dir;1") .eqs. ""))
        +$ then
        +$    write sys$output -
        +      "   Can't find expected common OpenSSL directories in:"
        +$    write sys$output "   ''ossl_dev_dir'"
        +$    status = rms_e_fnf
        +$    goto clean_up
        +$ endif
        +$!
        +$ if ((f$search( "''arch_name_exe'_exe.dir;1") .eqs. "") .or. -
        +   (f$search( "''arch_name'_lib.dir;1") .eqs. ""))
        +$ then
        +$    write sys$output -
        +      "   Can't find expected architecture-specific OpenSSL directories in:"
        +$    write sys$output "   ''ossl_dev_dir'"
        +$    status = rms_e_fnf
        +$    goto clean_up
        +$ endif
        +$!
        +$! All seems well (enough).  Define the OpenSSL logical names.
        +$!
        +$ ossl_root = ossl_dev_dir- "]"+ ".]"
        +$ define /translation_attributes = concealed /nolog'p1 SSLROOT 'ossl_root'
        +$ define /nolog 'p1' SSLCERTS     sslroot:[certs]
        +$ define /nolog 'p1' SSLINCLUDE   sslroot:[include]
        +$ define /nolog 'p1' SSLPRIVATE   sslroot:[private]
        +$ define /nolog 'p1' SSLEXE       sslroot:['arch_name_exe'_exe]
        +$ define /nolog 'p1' SSLLIB       sslroot:['arch_name'_lib]
        +$!
        +$! Defining OPENSSL lets a C program use "#include <openssl/{foo}.h>":
        +$ define /nolog 'p1' OPENSSL      SSLINCLUDE:
        +$!
        +$! Run a site-specific procedure, if it exists.
        +$!
        +$ if f$search( "sslroot:[vms]openssl_systartup.com") .nes."" then -
        +   @ sslroot:[vms]openssl_systartup.com
        +$!
        +$! Restore the original default dev:[dir] (if known).
        +$!
        +$ clean_up:
        +$!
        +$ if (f$type( orig_dev_dir) .nes. "")
        +$ then
        +$    set default 'orig_dev_dir'
        +$ endif
        +$!
        +$ EXIT 'status'
        +$!
        diff --git a/vendor/openssl/openssl/VMS/openssl_undo.com b/vendor/openssl/openssl/VMS/openssl_undo.com
        new file mode 100644
        index 000000000..d1623a316
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/openssl_undo.com
        @@ -0,0 +1,20 @@
        +$!
        +$! Deassign OpenSSL logical names.
        +$!
        +$ call deass "OPENSSL" "''p1'"
        +$ call deass "SSLCERTS" "''p1'"
        +$ call deass "SSLEXE" "''p1'"
        +$ call deass "SSLINCLUDE" "''p1'"
        +$ call deass "SSLLIB" "''p1'"
        +$ call deass "SSLPRIVATE" "''p1'"
        +$ call deass "SSLROOT" "''p1'"
        +$!
        +$ exit
        +$!
        +$deass: subroutine
        +$ if (f$trnlnm( p1) .nes. "")
        +$ then
        +$    deassign 'p2' 'p1'
        +$ endif
        +$ endsubroutine
        +$!
        diff --git a/vendor/openssl/openssl/VMS/openssl_utils.com b/vendor/openssl/openssl/VMS/openssl_utils.com
        new file mode 100644
        index 000000000..64f491510
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/openssl_utils.com
        @@ -0,0 +1,46 @@
        +$!
        +$!  APPS.COM
        +$!  Written By:  Robert Byer
        +$!               Vice-President
        +$!               A-Com Computing, Inc.
        +$!               byer@mail.all-net.net
        +$!
        +$!
        +$! Slightly modified by Richard Levitte <richard@levitte.org>
        +$!
        +$!
        +$! Always define OPENSSL.  Others are optional (non-null P1).
        +$!
        +$ OPENSSL  :== $SSLEXE:OPENSSL
        +$
        +$ IF (P1 .NES. "")
        +$ THEN
        +$     VERIFY   :== $SSLEXE:OPENSSL VERIFY
        +$     ASN1PARSE:== $SSLEXE:OPENSSL ASN1PARS
        +$! REQ could conflict with REQUEST.
        +$     OREQ     :== $SSLEXE:OPENSSL REQ
        +$     DGST     :== $SSLEXE:OPENSSL DGST
        +$     DH       :== $SSLEXE:OPENSSL DH
        +$     ENC      :== $SSLEXE:OPENSSL ENC
        +$     GENDH    :== $SSLEXE:OPENSSL GENDH
        +$     ERRSTR   :== $SSLEXE:OPENSSL ERRSTR
        +$     CA       :== $SSLEXE:OPENSSL CA
        +$     CRL      :== $SSLEXE:OPENSSL CRL
        +$     RSA      :== $SSLEXE:OPENSSL RSA
        +$     DSA      :== $SSLEXE:OPENSSL DSA
        +$     DSAPARAM :== $SSLEXE:OPENSSL DSAPARAM
        +$     X509     :== $SSLEXE:OPENSSL X509
        +$     GENRSA   :== $SSLEXE:OPENSSL GENRSA
        +$     GENDSA   :== $SSLEXE:OPENSSL GENDSA
        +$     S_SERVER :== $SSLEXE:OPENSSL S_SERVER
        +$     S_CLIENT :== $SSLEXE:OPENSSL S_CLIENT
        +$     SPEED    :== $SSLEXE:OPENSSL SPEED
        +$     S_TIME   :== $SSLEXE:OPENSSL S_TIME
        +$     VERSION  :== $SSLEXE:OPENSSL VERSION
        +$     PKCS7    :== $SSLEXE:OPENSSL PKCS7
        +$     CRL2PKCS7:== $SSLEXE:OPENSSL CRL2P7
        +$     SESS_ID  :== $SSLEXE:OPENSSL SESS_ID
        +$     CIPHERS  :== $SSLEXE:OPENSSL CIPHERS
        +$     NSEQ     :== $SSLEXE:OPENSSL NSEQ
        +$     PKCS12   :== $SSLEXE:OPENSSL PKCS12
        +$ ENDIF
        diff --git a/vendor/openssl/openssl/VMS/socketshr_shr.opt b/vendor/openssl/openssl/VMS/socketshr_shr.opt
        new file mode 100644
        index 000000000..f6e313162
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/socketshr_shr.opt
        @@ -0,0 +1 @@
        +socketshr/share
        diff --git a/vendor/openssl/openssl/VMS/tcpip_shr_decc.opt b/vendor/openssl/openssl/VMS/tcpip_shr_decc.opt
        new file mode 100644
        index 000000000..33b159e5f
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/tcpip_shr_decc.opt
        @@ -0,0 +1 @@
        +sys$share:tcpip$ipc_shr.exe/share
        diff --git a/vendor/openssl/openssl/VMS/test-includes.com b/vendor/openssl/openssl/VMS/test-includes.com
        new file mode 100644
        index 000000000..c1d7ccd0e
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/test-includes.com
        @@ -0,0 +1,28 @@
        +$! Quick script to check how well including individual header files works
        +$! on VMS, even when the VMS macro isn't defined.
        +$
        +$	sav_def = f$env("DEFAULT")
        +$	here = f$parse("A.;0",f$ENV("PROCEDURE")) - "A.;0"
        +$	set default 'here'
        +$	set default [-.include.openssl]
        +$	define openssl 'f$env("DEFAULT")'
        +$	set default [--]
        +$
        +$ loop:
        +$	f = f$search("openssl:*.h")
        +$	if f .eqs. "" then goto loop_end
        +$	write sys$output "Checking ",f
        +$	open/write foo foo.c
        +$	write foo "#undef VMS"
        +$	write foo "#include <stdio.h>"
        +$	write foo "#include <openssl/",f$parse(f,,,"NAME"),".h>"
        +$	write foo "main()"
        +$	write foo "{printf(""foo\n"");}"
        +$	close foo
        +$	cc/STANDARD=ANSI89/NOLIST/PREFIX=ALL foo.c
        +$	delete foo.c;
        +$	goto loop
        +$ loop_end:
        +$	set default 'save_def'
        +$	exit
        +
        diff --git a/vendor/openssl/openssl/VMS/ucx_shr_decc.opt b/vendor/openssl/openssl/VMS/ucx_shr_decc.opt
        new file mode 100644
        index 000000000..28d84f4af
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/ucx_shr_decc.opt
        @@ -0,0 +1 @@
        +sys$share:ucx$ipc_shr.exe/share
        diff --git a/vendor/openssl/openssl/VMS/ucx_shr_decc_log.opt b/vendor/openssl/openssl/VMS/ucx_shr_decc_log.opt
        new file mode 100644
        index 000000000..c9d9a96d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/ucx_shr_decc_log.opt
        @@ -0,0 +1 @@
        +ucx$ipc_shr/share
        diff --git a/vendor/openssl/openssl/VMS/ucx_shr_vaxc.opt b/vendor/openssl/openssl/VMS/ucx_shr_vaxc.opt
        new file mode 100644
        index 000000000..86bfaf0d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/VMS/ucx_shr_vaxc.opt
        @@ -0,0 +1 @@
        +sys$library:ucx$ipc.olb/library
        diff --git a/vendor/openssl/openssl/apps/CA.com b/vendor/openssl/openssl/apps/CA.com
        new file mode 100644
        index 000000000..2c0d46527
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/CA.com
        @@ -0,0 +1,236 @@
        +$! CA - wrapper around ca to make it easier to use ... basically ca requires
        +$!      some setup stuff to be done before you can use it and this makes
        +$!      things easier between now and when Eric is convinced to fix it :-)
        +$!
        +$! CA -newca ... will setup the right stuff
        +$! CA -newreq ... will generate a certificate request 
        +$! CA -sign ... will sign the generated request and output 
        +$!
        +$! At the end of that grab newreq.pem and newcert.pem (one has the key 
        +$! and the other the certificate) and cat them together and that is what
        +$! you want/need ... I'll make even this a little cleaner later.
        +$!
        +$!
        +$! 12-Jan-96 tjh    Added more things ... including CA -signcert which
        +$!                  converts a certificate to a request and then signs it.
        +$! 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
        +$!                 environment variable so this can be driven from
        +$!                 a script.
        +$! 25-Jul-96 eay    Cleaned up filenames some more.
        +$! 11-Jun-96 eay    Fixed a few filename missmatches.
        +$! 03-May-96 eay    Modified to use 'openssl cmd' instead of 'cmd'.
        +$! 18-Apr-96 tjh    Original hacking
        +$!
        +$! Tim Hudson
        +$! tjh@cryptsoft.com
        +$!
        +$!
        +$! default ssleay.cnf file has setup as per the following
        +$! demoCA ... where everything is stored
        +$
        +$ IF F$TYPE(SSLEAY_CONFIG) .EQS. "" THEN SSLEAY_CONFIG := SSLLIB:SSLEAY.CNF
        +$
        +$ DAYS   = "-days 365"
        +$ REQ    = openssl + " req " + SSLEAY_CONFIG
        +$ CA     = openssl + " ca " + SSLEAY_CONFIG
        +$ VERIFY = openssl + " verify"
        +$ X509   = openssl + " x509"
        +$ PKCS12 = openssl + " pkcs12"
        +$ echo   = "write sys$Output"
        +$ RET = 1
        +$!
        +$! 2010-12-20 SMS.
        +$! Use a concealed logical name to reduce command line lengths, to
        +$! avoid DCL errors on VAX:
        +$!     %DCL-W-TKNOVF, command element is too long - shorten
        +$! (Path segments like "openssl-1_0_1-stable-SNAP-20101217" accumulate
        +$! quickly.)
        +$!
        +$ CATOP = F$PARSE( F$ENVIRONMENT( "DEFAULT"), "[]")- "].;"+ ".demoCA.]"
        +$ define /translation_attributes = concealed CATOP 'CATOP'
        +$!
        +$ on error then goto clean_up
        +$ on control_y then goto clean_up
        +$!
        +$ CAKEY  = "CATOP:[private]cakey.pem"
        +$ CACERT = "CATOP:[000000]cacert.pem"
        +$
        +$ __INPUT := SYS$COMMAND
        +$!
        +$ i = 1
        +$opt_loop:
        +$ if i .gt. 8 then goto opt_loop_end
        +$
        +$ prog_opt = F$EDIT(P'i',"lowercase")
        +$
        +$ IF (prog_opt .EQS. "?" .OR. prog_opt .EQS. "-h" .OR. prog_opt .EQS. "-help") 
        +$ THEN
        +$   echo "usage: CA -newcert|-newreq|-newca|-sign|-verify" 
        +$   goto clean_up
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-input")
        +$ THEN
        +$   ! Get input from somewhere other than SYS$COMMAND
        +$   i = i + 1
        +$   __INPUT = P'i'
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-newcert")
        +$ THEN
        +$   ! Create a certificate.
        +$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$   REQ -new -x509 -keyout newreq.pem -out newreq.pem 'DAYS'
        +$   RET=$STATUS
        +$   echo "Certificate (and private key) is in newreq.pem"
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-newreq")
        +$ THEN
        +$   ! Create a certificate request
        +$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$   REQ -new -keyout newreq.pem -out newreq.pem 'DAYS'
        +$   RET=$STATUS
        +$   echo "Request (and private key) is in newreq.pem"
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-newca")
        +$ THEN
        +$   ! If explicitly asked for or it doesn't exist then setup the directory
        +$   ! structure that Eric likes to manage things.
        +$   IF F$SEARCH( "CATOP:[000000]serial.") .EQS. ""
        +$   THEN
        +$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[000000]
        +$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[certs]
        +$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[crl]
        +$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[newcerts]
        +$     CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[private]
        +$
        +$     OPEN /WRITE ser_file CATOP:[000000]serial. 
        +$     WRITE ser_file "01"
        +$     CLOSE ser_file
        +$     APPEND /NEW_VERSION NL: CATOP:[000000]index.txt
        +$
        +$     ! The following is to make sure access() doesn't get confused.  It
        +$     ! really needs one file in the directory to give correct answers...
        +$     COPY NLA0: CATOP:[certs].;
        +$     COPY NLA0: CATOP:[crl].;
        +$     COPY NLA0: CATOP:[newcerts].;
        +$     COPY NLA0: CATOP:[private].;
        +$   ENDIF
        +$!
        +$   IF F$SEARCH( CAKEY) .EQS. ""
        +$   THEN
        +$     READ '__INPUT' FILE -
        +       /PROMPT="CA certificate filename (or enter to create): "
        +$     IF (FILE .NES. "") .AND. (F$SEARCH(FILE) .NES. "")
        +$     THEN
        +$       COPY 'FILE' 'CAKEY'
        +$       RET=$STATUS
        +$     ELSE
        +$       echo "Making CA certificate ..."
        +$       DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$       REQ -new -x509 -keyout 'CAKEY' -out 'CACERT' 'DAYS'
        +$       RET=$STATUS
        +$     ENDIF
        +$   ENDIF
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-pkcs12")
        +$ THEN
        +$   i = i + 1
        +$   cname = P'i'
        +$   IF cname .EQS. "" THEN cname = "My certificate"
        +$   PKCS12 -in newcert.pem -inkey newreq.pem -certfile 'CACERT' -
        +     -out newcert.p12 -export -name "''cname'"
        +$   RET=$STATUS
        +$   goto clean_up
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-xsign")
        +$ THEN
        +$!
        +$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$   CA -policy policy_anything -infiles newreq.pem
        +$   RET=$STATUS
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF ((prog_opt .EQS. "-sign") .OR. (prog_opt .EQS. "-signreq"))
        +$ THEN
        +$!   
        +$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$   CA -policy policy_anything -out newcert.pem -infiles newreq.pem
        +$   RET=$STATUS
        +$   type newcert.pem
        +$   echo "Signed certificate is in newcert.pem"
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-signcert")
        +$  THEN
        +$!   
        +$   echo "Cert passphrase will be requested twice - bug?"
        +$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$   X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
        +$   DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$   CA -policy policy_anything -out newcert.pem -infiles tmp.pem
        +y
        +y
        +$   type newcert.pem
        +$   echo "Signed certificate is in newcert.pem"
        +$   GOTO opt_loop_continue
        +$ ENDIF
        +$!
        +$ IF (prog_opt .EQS. "-verify")
        +$ THEN
        +$!   
        +$   i = i + 1
        +$   IF (p'i' .EQS. "")
        +$   THEN
        +$     DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$     VERIFY "-CAfile" 'CACERT' newcert.pem
        +$   ELSE
        +$     j = i
        +$    verify_opt_loop:
        +$     IF j .GT. 8 THEN GOTO verify_opt_loop_end
        +$     IF p'j' .NES. ""
        +$     THEN 
        +$       DEFINE /USER_MODE SYS$INPUT '__INPUT'
        +$       __tmp = p'j'
        +$       VERIFY "-CAfile" 'CACERT' '__tmp'
        +$       tmp=$STATUS
        +$       IF tmp .NE. 0 THEN RET=tmp
        +$     ENDIF
        +$     j = j + 1
        +$     GOTO verify_opt_loop
        +$    verify_opt_loop_end:
        +$   ENDIF
        +$   
        +$   GOTO opt_loop_end
        +$ ENDIF
        +$!
        +$ IF (prog_opt .NES. "")
        +$ THEN
        +$!   
        +$   echo "Unknown argument ''prog_opt'"
        +$   RET = 3
        +$   goto clean_up
        +$ ENDIF
        +$
        +$opt_loop_continue:
        +$ i = i + 1
        +$ GOTO opt_loop
        +$
        +$opt_loop_end:
        +$!
        +$clean_up:
        +$!
        +$ if f$trnlnm( "CATOP", "LNM$PROCESS") .nes. "" then -
        +   deassign /process CATOP
        +$!
        +$ EXIT 'RET'
        diff --git a/vendor/openssl/openssl/apps/CA.pl b/vendor/openssl/openssl/apps/CA.pl
        new file mode 100644
        index 000000000..a3965ecea
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/CA.pl
        @@ -0,0 +1,189 @@
        +#!/usr/bin/perl
        +#
        +# CA - wrapper around ca to make it easier to use ... basically ca requires
        +#      some setup stuff to be done before you can use it and this makes
        +#      things easier between now and when Eric is convinced to fix it :-)
        +#
        +# CA -newca ... will setup the right stuff
        +# CA -newreq[-nodes] ... will generate a certificate request 
        +# CA -sign ... will sign the generated request and output 
        +#
        +# At the end of that grab newreq.pem and newcert.pem (one has the key 
        +# and the other the certificate) and cat them together and that is what
        +# you want/need ... I'll make even this a little cleaner later.
        +#
        +#
        +# 12-Jan-96 tjh    Added more things ... including CA -signcert which
        +#                  converts a certificate to a request and then signs it.
        +# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
        +#		   environment variable so this can be driven from
        +#		   a script.
        +# 25-Jul-96 eay    Cleaned up filenames some more.
        +# 11-Jun-96 eay    Fixed a few filename missmatches.
        +# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'.
        +# 18-Apr-96 tjh    Original hacking
        +#
        +# Tim Hudson
        +# tjh@cryptsoft.com
        +#
        +
        +# 27-Apr-98 snh    Translation into perl, fix existing CA bug.
        +#
        +#
        +# Steve Henson
        +# shenson@bigfoot.com
        +
        +# default openssl.cnf file has setup as per the following
        +# demoCA ... where everything is stored
        +
        +my $openssl;
        +if(defined $ENV{OPENSSL}) {
        +	$openssl = $ENV{OPENSSL};
        +} else {
        +	$openssl = "openssl";
        +	$ENV{OPENSSL} = $openssl;
        +}
        +
        +$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
        +$DAYS="-days 365";	# 1 year
        +$CADAYS="-days 1095";	# 3 years
        +$REQ="$openssl req $SSLEAY_CONFIG";
        +$CA="$openssl ca $SSLEAY_CONFIG";
        +$VERIFY="$openssl verify";
        +$X509="$openssl x509";
        +$PKCS12="$openssl pkcs12";
        +
        +$CATOP="./demoCA";
        +$CAKEY="cakey.pem";
        +$CAREQ="careq.pem";
        +$CACERT="cacert.pem";
        +
        +$DIRMODE = 0777;
        +
        +$RET = 0;
        +
        +foreach (@ARGV) {
        +	if ( /^(-\?|-h|-help)$/ ) {
        +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
        +	    exit 0;
        +	} elsif (/^-newcert$/) {
        +	    # create a certificate
        +	    system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
        +	    $RET=$?;
        +	    print "Certificate is in newcert.pem, private key is in newkey.pem\n"
        +	} elsif (/^-newreq$/) {
        +	    # create a certificate request
        +	    system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
        +	    $RET=$?;
        +	    print "Request is in newreq.pem, private key is in newkey.pem\n";
        +	} elsif (/^-newreq-nodes$/) {
        +	    # create a certificate request
        +	    system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
        +	    $RET=$?;
        +	    print "Request is in newreq.pem, private key is in newkey.pem\n";
        +	} elsif (/^-newca$/) {
        +		# if explicitly asked for or it doesn't exist then setup the
        +		# directory structure that Eric likes to manage things 
        +	    $NEW="1";
        +	    if ( "$NEW" || ! -f "${CATOP}/serial" ) {
        +		# create the directory hierarchy
        +		mkdir $CATOP, $DIRMODE;
        +		mkdir "${CATOP}/certs", $DIRMODE;
        +		mkdir "${CATOP}/crl", $DIRMODE ;
        +		mkdir "${CATOP}/newcerts", $DIRMODE;
        +		mkdir "${CATOP}/private", $DIRMODE;
        +		open OUT, ">${CATOP}/index.txt";
        +		close OUT;
        +		open OUT, ">${CATOP}/crlnumber";
        +		print OUT "01\n";
        +		close OUT;
        +	    }
        +	    if ( ! -f "${CATOP}/private/$CAKEY" ) {
        +		print "CA certificate filename (or enter to create)\n";
        +		$FILE = <STDIN>;
        +
        +		chop $FILE;
        +
        +		# ask user for existing CA certificate
        +		if ($FILE) {
        +		    cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
        +		    cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
        +		    $RET=$?;
        +		} else {
        +		    print "Making CA certificate ...\n";
        +		    system ("$REQ -new -keyout " .
        +			"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
        +		    system ("$CA -create_serial " .
        +			"-out ${CATOP}/$CACERT $CADAYS -batch " . 
        +			"-keyfile ${CATOP}/private/$CAKEY -selfsign " .
        +			"-extensions v3_ca " .
        +			"-infiles ${CATOP}/$CAREQ ");
        +		    $RET=$?;
        +		}
        +	    }
        +	} elsif (/^-pkcs12$/) {
        +	    my $cname = $ARGV[1];
        +	    $cname = "My Certificate" unless defined $cname;
        +	    system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
        +			"-certfile ${CATOP}/$CACERT -out newcert.p12 " .
        +			"-export -name \"$cname\"");
        +	    $RET=$?;
        +	    print "PKCS #12 file is in newcert.p12\n";
        +	    exit $RET;
        +	} elsif (/^-xsign$/) {
        +	    system ("$CA -policy policy_anything -infiles newreq.pem");
        +	    $RET=$?;
        +	} elsif (/^(-sign|-signreq)$/) {
        +	    system ("$CA -policy policy_anything -out newcert.pem " .
        +							"-infiles newreq.pem");
        +	    $RET=$?;
        +	    print "Signed certificate is in newcert.pem\n";
        +	} elsif (/^(-signCA)$/) {
        +	    system ("$CA -policy policy_anything -out newcert.pem " .
        +					"-extensions v3_ca -infiles newreq.pem");
        +	    $RET=$?;
        +	    print "Signed CA certificate is in newcert.pem\n";
        +	} elsif (/^-signcert$/) {
        +	    system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
        +								"-out tmp.pem");
        +	    system ("$CA -policy policy_anything -out newcert.pem " .
        +							"-infiles tmp.pem");
        +	    $RET = $?;
        +	    print "Signed certificate is in newcert.pem\n";
        +	} elsif (/^-verify$/) {
        +	    if (shift) {
        +		foreach $j (@ARGV) {
        +		    system ("$VERIFY -CAfile $CATOP/$CACERT $j");
        +		    $RET=$? if ($? != 0);
        +		}
        +		exit $RET;
        +	    } else {
        +		    system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
        +		    $RET=$?;
        +	    	    exit 0;
        +	    }
        +	} else {
        +	    print STDERR "Unknown arg $_\n";
        +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
        +	    exit 1;
        +	}
        +}
        +
        +exit $RET;
        +
        +sub cp_pem {
        +my ($infile, $outfile, $bound) = @_;
        +open IN, $infile;
        +open OUT, ">$outfile";
        +my $flag = 0;
        +while (<IN>) {
        +	$flag = 1 if (/^-----BEGIN.*$bound/) ;
        +	print OUT $_ if ($flag);
        +	if (/^-----END.*$bound/) {
        +		close IN;
        +		close OUT;
        +		return;
        +	}
        +}
        +}
        +
        diff --git a/vendor/openssl/openssl/apps/CA.pl.in b/vendor/openssl/openssl/apps/CA.pl.in
        new file mode 100644
        index 000000000..c783a6e6a
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/CA.pl.in
        @@ -0,0 +1,189 @@
        +#!/usr/local/bin/perl
        +#
        +# CA - wrapper around ca to make it easier to use ... basically ca requires
        +#      some setup stuff to be done before you can use it and this makes
        +#      things easier between now and when Eric is convinced to fix it :-)
        +#
        +# CA -newca ... will setup the right stuff
        +# CA -newreq[-nodes] ... will generate a certificate request 
        +# CA -sign ... will sign the generated request and output 
        +#
        +# At the end of that grab newreq.pem and newcert.pem (one has the key 
        +# and the other the certificate) and cat them together and that is what
        +# you want/need ... I'll make even this a little cleaner later.
        +#
        +#
        +# 12-Jan-96 tjh    Added more things ... including CA -signcert which
        +#                  converts a certificate to a request and then signs it.
        +# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
        +#		   environment variable so this can be driven from
        +#		   a script.
        +# 25-Jul-96 eay    Cleaned up filenames some more.
        +# 11-Jun-96 eay    Fixed a few filename missmatches.
        +# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'.
        +# 18-Apr-96 tjh    Original hacking
        +#
        +# Tim Hudson
        +# tjh@cryptsoft.com
        +#
        +
        +# 27-Apr-98 snh    Translation into perl, fix existing CA bug.
        +#
        +#
        +# Steve Henson
        +# shenson@bigfoot.com
        +
        +# default openssl.cnf file has setup as per the following
        +# demoCA ... where everything is stored
        +
        +my $openssl;
        +if(defined $ENV{OPENSSL}) {
        +	$openssl = $ENV{OPENSSL};
        +} else {
        +	$openssl = "openssl";
        +	$ENV{OPENSSL} = $openssl;
        +}
        +
        +$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
        +$DAYS="-days 365";	# 1 year
        +$CADAYS="-days 1095";	# 3 years
        +$REQ="$openssl req $SSLEAY_CONFIG";
        +$CA="$openssl ca $SSLEAY_CONFIG";
        +$VERIFY="$openssl verify";
        +$X509="$openssl x509";
        +$PKCS12="$openssl pkcs12";
        +
        +$CATOP="./demoCA";
        +$CAKEY="cakey.pem";
        +$CAREQ="careq.pem";
        +$CACERT="cacert.pem";
        +
        +$DIRMODE = 0777;
        +
        +$RET = 0;
        +
        +foreach (@ARGV) {
        +	if ( /^(-\?|-h|-help)$/ ) {
        +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
        +	    exit 0;
        +	} elsif (/^-newcert$/) {
        +	    # create a certificate
        +	    system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
        +	    $RET=$?;
        +	    print "Certificate is in newcert.pem, private key is in newkey.pem\n"
        +	} elsif (/^-newreq$/) {
        +	    # create a certificate request
        +	    system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
        +	    $RET=$?;
        +	    print "Request is in newreq.pem, private key is in newkey.pem\n";
        +	} elsif (/^-newreq-nodes$/) {
        +	    # create a certificate request
        +	    system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
        +	    $RET=$?;
        +	    print "Request is in newreq.pem, private key is in newkey.pem\n";
        +	} elsif (/^-newca$/) {
        +		# if explicitly asked for or it doesn't exist then setup the
        +		# directory structure that Eric likes to manage things 
        +	    $NEW="1";
        +	    if ( "$NEW" || ! -f "${CATOP}/serial" ) {
        +		# create the directory hierarchy
        +		mkdir $CATOP, $DIRMODE;
        +		mkdir "${CATOP}/certs", $DIRMODE;
        +		mkdir "${CATOP}/crl", $DIRMODE ;
        +		mkdir "${CATOP}/newcerts", $DIRMODE;
        +		mkdir "${CATOP}/private", $DIRMODE;
        +		open OUT, ">${CATOP}/index.txt";
        +		close OUT;
        +		open OUT, ">${CATOP}/crlnumber";
        +		print OUT "01\n";
        +		close OUT;
        +	    }
        +	    if ( ! -f "${CATOP}/private/$CAKEY" ) {
        +		print "CA certificate filename (or enter to create)\n";
        +		$FILE = <STDIN>;
        +
        +		chop $FILE;
        +
        +		# ask user for existing CA certificate
        +		if ($FILE) {
        +		    cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
        +		    cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
        +		    $RET=$?;
        +		} else {
        +		    print "Making CA certificate ...\n";
        +		    system ("$REQ -new -keyout " .
        +			"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
        +		    system ("$CA -create_serial " .
        +			"-out ${CATOP}/$CACERT $CADAYS -batch " . 
        +			"-keyfile ${CATOP}/private/$CAKEY -selfsign " .
        +			"-extensions v3_ca " .
        +			"-infiles ${CATOP}/$CAREQ ");
        +		    $RET=$?;
        +		}
        +	    }
        +	} elsif (/^-pkcs12$/) {
        +	    my $cname = $ARGV[1];
        +	    $cname = "My Certificate" unless defined $cname;
        +	    system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
        +			"-certfile ${CATOP}/$CACERT -out newcert.p12 " .
        +			"-export -name \"$cname\"");
        +	    $RET=$?;
        +	    print "PKCS #12 file is in newcert.p12\n";
        +	    exit $RET;
        +	} elsif (/^-xsign$/) {
        +	    system ("$CA -policy policy_anything -infiles newreq.pem");
        +	    $RET=$?;
        +	} elsif (/^(-sign|-signreq)$/) {
        +	    system ("$CA -policy policy_anything -out newcert.pem " .
        +							"-infiles newreq.pem");
        +	    $RET=$?;
        +	    print "Signed certificate is in newcert.pem\n";
        +	} elsif (/^(-signCA)$/) {
        +	    system ("$CA -policy policy_anything -out newcert.pem " .
        +					"-extensions v3_ca -infiles newreq.pem");
        +	    $RET=$?;
        +	    print "Signed CA certificate is in newcert.pem\n";
        +	} elsif (/^-signcert$/) {
        +	    system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
        +								"-out tmp.pem");
        +	    system ("$CA -policy policy_anything -out newcert.pem " .
        +							"-infiles tmp.pem");
        +	    $RET = $?;
        +	    print "Signed certificate is in newcert.pem\n";
        +	} elsif (/^-verify$/) {
        +	    if (shift) {
        +		foreach $j (@ARGV) {
        +		    system ("$VERIFY -CAfile $CATOP/$CACERT $j");
        +		    $RET=$? if ($? != 0);
        +		}
        +		exit $RET;
        +	    } else {
        +		    system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
        +		    $RET=$?;
        +	    	    exit 0;
        +	    }
        +	} else {
        +	    print STDERR "Unknown arg $_\n";
        +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
        +	    exit 1;
        +	}
        +}
        +
        +exit $RET;
        +
        +sub cp_pem {
        +my ($infile, $outfile, $bound) = @_;
        +open IN, $infile;
        +open OUT, ">$outfile";
        +my $flag = 0;
        +while (<IN>) {
        +	$flag = 1 if (/^-----BEGIN.*$bound/) ;
        +	print OUT $_ if ($flag);
        +	if (/^-----END.*$bound/) {
        +		close IN;
        +		close OUT;
        +		return;
        +	}
        +}
        +}
        +
        diff --git a/vendor/openssl/openssl/apps/CA.sh b/vendor/openssl/openssl/apps/CA.sh
        new file mode 100644
        index 000000000..7ad6b8c52
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/CA.sh
        @@ -0,0 +1,198 @@
        +#!/bin/sh
        +#
        +# CA - wrapper around ca to make it easier to use ... basically ca requires
        +#      some setup stuff to be done before you can use it and this makes
        +#      things easier between now and when Eric is convinced to fix it :-)
        +#
        +# CA -newca ... will setup the right stuff
        +# CA -newreq ... will generate a certificate request
        +# CA -sign ... will sign the generated request and output
        +#
        +# At the end of that grab newreq.pem and newcert.pem (one has the key
        +# and the other the certificate) and cat them together and that is what
        +# you want/need ... I'll make even this a little cleaner later.
        +#
        +#
        +# 12-Jan-96 tjh    Added more things ... including CA -signcert which
        +#                  converts a certificate to a request and then signs it.
        +# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG
        +#                  environment variable so this can be driven from
        +#                  a script.
        +# 25-Jul-96 eay    Cleaned up filenames some more.
        +# 11-Jun-96 eay    Fixed a few filename missmatches.
        +# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'.
        +# 18-Apr-96 tjh    Original hacking
        +#
        +# Tim Hudson
        +# tjh@cryptsoft.com
        +#
        +
        +# default openssl.cnf file has setup as per the following
        +# demoCA ... where everything is stored
        +cp_pem() {
        +    infile=$1
        +    outfile=$2
        +    bound=$3
        +    flag=0
        +    exec <$infile;
        +    while read line; do
        +	if [ $flag -eq 1 ]; then
        +		echo $line|grep "^-----END.*$bound"  2>/dev/null 1>/dev/null
        +		if [ $? -eq 0 ] ; then
        +			echo $line >>$outfile
        +			break
        +		else
        +			echo $line >>$outfile
        +		fi
        +	fi
        +
        +	echo $line|grep "^-----BEGIN.*$bound"  2>/dev/null 1>/dev/null
        +	if [ $? -eq 0 ]; then
        +		echo $line >$outfile
        +		flag=1
        +	fi
        +    done
        +}
        +
        +usage() {
        + echo "usage: $0 -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify" >&2
        +}
        +
        +if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi
        +
        +if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi	# 1 year
        +CADAYS="-days 1095"	# 3 years
        +REQ="$OPENSSL req $SSLEAY_CONFIG"
        +CA="$OPENSSL ca $SSLEAY_CONFIG"
        +VERIFY="$OPENSSL verify"
        +X509="$OPENSSL x509"
        +PKCS12="openssl pkcs12"
        +
        +if [ -z "$CATOP" ] ; then CATOP=./demoCA ; fi
        +CAKEY=./cakey.pem
        +CAREQ=./careq.pem
        +CACERT=./cacert.pem
        +
        +RET=0
        +
        +while [ "$1" != "" ] ; do
        +case $1 in
        +-\?|-h|-help)
        +    usage
        +    exit 0
        +    ;;
        +-newcert)
        +    # create a certificate
        +    $REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS
        +    RET=$?
        +    echo "Certificate is in newcert.pem, private key is in newkey.pem"
        +    ;;
        +-newreq)
        +    # create a certificate request
        +    $REQ -new -keyout newkey.pem -out newreq.pem $DAYS
        +    RET=$?
        +    echo "Request is in newreq.pem, private key is in newkey.pem"
        +    ;;
        +-newreq-nodes) 
        +    # create a certificate request
        +    $REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
        +    RET=$?
        +    echo "Request (and private key) is in newreq.pem"
        +    ;;
        +-newca)
        +    # if explicitly asked for or it doesn't exist then setup the directory
        +    # structure that Eric likes to manage things
        +    NEW="1"
        +    if [ "$NEW" -o ! -f ${CATOP}/serial ]; then
        +	# create the directory hierarchy
        +	mkdir -p ${CATOP}
        +	mkdir -p ${CATOP}/certs
        +	mkdir -p ${CATOP}/crl
        +	mkdir -p ${CATOP}/newcerts
        +	mkdir -p ${CATOP}/private
        +	touch ${CATOP}/index.txt
        +    fi
        +    if [ ! -f ${CATOP}/private/$CAKEY ]; then
        +	echo "CA certificate filename (or enter to create)"
        +	read FILE
        +
        +	# ask user for existing CA certificate
        +	if [ "$FILE" ]; then
        +	    cp_pem $FILE ${CATOP}/private/$CAKEY PRIVATE
        +	    cp_pem $FILE ${CATOP}/$CACERT CERTIFICATE
        +	    RET=$?
        +	    if [ ! -f "${CATOP}/serial" ]; then
        +		$X509 -in ${CATOP}/$CACERT -noout -next_serial \
        +		      -out ${CATOP}/serial
        +	    fi
        +	else
        +	    echo "Making CA certificate ..."
        +	    $REQ -new -keyout ${CATOP}/private/$CAKEY \
        +			   -out ${CATOP}/$CAREQ
        +	    $CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \
        +			   -keyfile ${CATOP}/private/$CAKEY -selfsign \
        +			   -extensions v3_ca \
        +			   -infiles ${CATOP}/$CAREQ
        +	    RET=$?
        +	fi
        +    fi
        +    ;;
        +-xsign)
        +    $CA -policy policy_anything -infiles newreq.pem
        +    RET=$?
        +    ;;
        +-pkcs12)
        +    if [ -z "$2" ] ; then
        +	CNAME="My Certificate"
        +    else
        +	CNAME="$2"
        +    fi
        +    $PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \
        +	    -out newcert.p12 -export -name "$CNAME"
        +    RET=$?
        +    exit $RET
        +    ;;
        +-sign|-signreq)
        +    $CA -policy policy_anything -out newcert.pem -infiles newreq.pem
        +    RET=$?
        +    cat newcert.pem
        +    echo "Signed certificate is in newcert.pem"
        +    ;;
        +-signCA)
        +    $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
        +    RET=$?
        +    echo "Signed CA certificate is in newcert.pem"
        +    ;;
        +-signcert)
        +    echo "Cert passphrase will be requested twice - bug?"
        +    $X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
        +    $CA -policy policy_anything -out newcert.pem -infiles tmp.pem
        +    RET=$?
        +    cat newcert.pem
        +    echo "Signed certificate is in newcert.pem"
        +    ;;
        +-verify)
        +    shift
        +    if [ -z "$1" ]; then
        +	    $VERIFY -CAfile $CATOP/$CACERT newcert.pem
        +	    RET=$?
        +    else
        +	for j
        +	do
        +	    $VERIFY -CAfile $CATOP/$CACERT $j
        +	    if [ $? != 0 ]; then
        +		    RET=$?
        +	    fi
        +	done
        +    fi
        +    exit $RET
        +    ;;
        +*)
        +    echo "Unknown arg $i" >&2
        +    usage
        +    exit 1
        +    ;;
        +esac
        +shift
        +done
        +exit $RET
        diff --git a/vendor/openssl/openssl/apps/Makefile b/vendor/openssl/openssl/apps/Makefile
        new file mode 100644
        index 000000000..95f499e33
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/Makefile
        @@ -0,0 +1,1055 @@
        +#
        +#  apps/Makefile
        +#
        +
        +DIR=		apps
        +TOP=		..
        +CC=		cc
        +INCLUDES=	-I$(TOP) -I../include $(KRB5_INCLUDES)
        +CFLAG=		-g -static
        +MAKEFILE=	Makefile
        +PERL=		perl
        +RM=		rm -f
        +# KRB5 stuff
        +KRB5_INCLUDES=
        +LIBKRB5=
        +
        +PEX_LIBS=
        +EX_LIBS= 
        +EXE_EXT= 
        +
        +SHLIB_TARGET=
        +
        +CFLAGS= -DMONOLITH $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile makeapps.com install.com
        +
        +DLIBCRYPTO=../libcrypto.a
        +DLIBSSL=../libssl.a
        +LIBCRYPTO=-L.. -lcrypto
        +LIBSSL=-L.. -lssl
        +
        +PROGRAM= openssl
        +
        +SCRIPTS=CA.sh CA.pl tsget
        +
        +EXE= $(PROGRAM)$(EXE_EXT)
        +
        +E_EXE=	verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
        +	ca crl rsa rsautl dsa dsaparam ec ecparam \
        +	x509 genrsa gendsa genpkey s_server s_client speed \
        +	s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
        +	pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp
        +
        +PROGS= $(PROGRAM).c
        +
        +A_OBJ=apps.o
        +A_SRC=apps.c
        +S_OBJ=	s_cb.o s_socket.o
        +S_SRC=	s_cb.c s_socket.c
        +RAND_OBJ=app_rand.o
        +RAND_SRC=app_rand.c
        +
        +E_OBJ=	verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
        +	ca.o pkcs7.o crl2p7.o crl.o \
        +	rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
        +	x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
        +	s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
        +	ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \
        +	spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o
        +
        +E_SRC=	verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
        +	pkcs7.c crl2p7.c crl.c \
        +	rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \
        +	x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \
        +	s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
        +	ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \
        +	spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c srp.c
        +
        +SRC=$(E_SRC)
        +
        +EXHEADER=
        +HEADER=	apps.h progs.h s_apps.h \
        +	testdsa.h testrsa.h \
        +	$(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	@(cd ..; $(MAKE) DIRS=$(DIR) all)
        +
        +all:	exe
        +
        +exe:	$(EXE)
        +
        +req: sreq.o $(A_OBJ) $(DLIBCRYPTO)
        +	shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
        +		shlib_target="$(SHLIB_TARGET)"; \
        +	fi; \
        +	$(MAKE) -f $(TOP)/Makefile.shared -e \
        +		APPNAME=req OBJECTS="sreq.o $(A_OBJ) $(RAND_OBJ)" \
        +		LIBDEPS="$(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)" \
        +		link_app.$${shlib_target}
        +
        +sreq.o: req.c 
        +	$(CC) -c $(INCLUDES) $(CFLAG) -o sreq.o req.c
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@set -e; for i in $(EXE); \
        +	do  \
        +	(echo installing $$i; \
        +	 cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	 chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	 mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
        +	 done;
        +	@set -e; for i in $(SCRIPTS); \
        +	do  \
        +	(echo installing $$i; \
        +	 cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
        +	 chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
        +	 mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
        +	 done
        +	@cp openssl.cnf $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
        +	chmod 644 $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
        +	mv -f  $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf
        +
        +tags:
        +	ctags $(SRC)
        +
        +tests:
        +
        +links:
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +
        +depend:
        +	@if [ -z "$(THIS)" ]; then \
        +	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
        +	else \
        +	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
        +	fi
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +	rm -f CA.pl
        +
        +clean:
        +	rm -f *.o *.obj *.dll lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
        +	rm -f req
        +
        +$(DLIBSSL):
        +	(cd ..; $(MAKE) DIRS=ssl all)
        +
        +$(DLIBCRYPTO):
        +	(cd ..; $(MAKE) DIRS=crypto all)
        +
        +$(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
        +	$(RM) $(EXE)
        +	shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
        +		shlib_target="$(SHLIB_TARGET)"; \
        +	elif [ -n "$(FIPSCANLIB)" ]; then \
        +	  FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; export CC FIPSLD_CC; \
        +	fi; \
        +	LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \
        +	$(MAKE) -f $(TOP)/Makefile.shared -e \
        +		APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
        +		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
        +		link_app.$${shlib_target}
        +	@(cd ..; $(MAKE) rehash)
        +
        +progs.h: progs.pl
        +	$(PERL) progs.pl $(E_EXE) >progs.h
        +	$(RM) $(PROGRAM).o
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +app_rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +app_rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +app_rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +app_rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +app_rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +app_rand.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +app_rand.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +app_rand.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +app_rand.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +app_rand.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +app_rand.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +app_rand.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +app_rand.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +app_rand.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
        +app_rand.o: app_rand.c apps.h
        +apps.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +apps.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +apps.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +apps.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +apps.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +apps.o: ../include/openssl/engine.h ../include/openssl/err.h
        +apps.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +apps.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +apps.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +apps.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +apps.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +apps.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h
        +apps.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +apps.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +apps.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +apps.o: ../include/openssl/ui.h ../include/openssl/x509.h
        +apps.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.c apps.h
        +asn1pars.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +asn1pars.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +asn1pars.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +asn1pars.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +asn1pars.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +asn1pars.o: ../include/openssl/err.h ../include/openssl/evp.h
        +asn1pars.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +asn1pars.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +asn1pars.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +asn1pars.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +asn1pars.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +asn1pars.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +asn1pars.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +asn1pars.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +asn1pars.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +asn1pars.o: asn1pars.c
        +ca.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ca.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +ca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ca.o: ../include/openssl/engine.h ../include/openssl/err.h
        +ca.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +ca.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ca.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +ca.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ca.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ca.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +ca.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +ca.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +ca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +ca.o: ../include/openssl/x509v3.h apps.h ca.c
        +ciphers.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ciphers.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ciphers.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +ciphers.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ciphers.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ciphers.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ciphers.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ciphers.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ciphers.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ciphers.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +ciphers.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ciphers.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ciphers.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ciphers.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +ciphers.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +ciphers.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +ciphers.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +ciphers.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ciphers.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +ciphers.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +ciphers.o: ../include/openssl/x509v3.h apps.h ciphers.c
        +cms.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +cms.o: ../include/openssl/buffer.h ../include/openssl/cms.h
        +cms.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +cms.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +cms.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +cms.o: ../include/openssl/engine.h ../include/openssl/err.h
        +cms.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +cms.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +cms.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +cms.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +cms.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +cms.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +cms.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +cms.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +cms.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +cms.o: ../include/openssl/x509v3.h apps.h cms.c
        +crl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +crl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +crl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +crl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +crl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +crl.o: ../include/openssl/err.h ../include/openssl/evp.h
        +crl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +crl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +crl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +crl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +crl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +crl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +crl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +crl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +crl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h crl.c
        +crl2p7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +crl2p7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +crl2p7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +crl2p7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +crl2p7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +crl2p7.o: ../include/openssl/err.h ../include/openssl/evp.h
        +crl2p7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +crl2p7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +crl2p7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +crl2p7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +crl2p7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +crl2p7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +crl2p7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +crl2p7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +crl2p7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +crl2p7.o: crl2p7.c
        +dgst.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +dgst.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +dgst.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +dgst.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +dgst.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +dgst.o: ../include/openssl/err.h ../include/openssl/evp.h
        +dgst.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
        +dgst.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +dgst.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +dgst.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +dgst.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +dgst.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +dgst.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +dgst.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +dgst.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +dgst.o: ../include/openssl/x509v3.h apps.h dgst.c
        +dh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +dh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +dh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +dh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h
        +dh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +dh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +dh.o: ../include/openssl/err.h ../include/openssl/evp.h
        +dh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +dh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +dh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +dh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +dh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +dh.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +dh.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +dh.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +dh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dh.c
        +dsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +dsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +dsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +dsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
        +dsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +dsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +dsa.o: ../include/openssl/err.h ../include/openssl/evp.h
        +dsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +dsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +dsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +dsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +dsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +dsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +dsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +dsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +dsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dsa.c
        +dsaparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +dsaparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +dsaparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +dsaparam.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +dsaparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +dsaparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +dsaparam.o: ../include/openssl/engine.h ../include/openssl/err.h
        +dsaparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +dsaparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +dsaparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +dsaparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +dsaparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +dsaparam.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +dsaparam.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +dsaparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +dsaparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +dsaparam.o: ../include/openssl/ui.h ../include/openssl/x509.h
        +dsaparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +dsaparam.o: dsaparam.c
        +ec.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ec.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +ec.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +ec.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ec.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ec.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ec.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ec.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +ec.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ec.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ec.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ec.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ec.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ec.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +ec.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ec.c
        +ecparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ecparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ecparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +ecparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ecparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ecparam.o: ../include/openssl/engine.h ../include/openssl/err.h
        +ecparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +ecparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ecparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +ecparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ecparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ecparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +ecparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +ecparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +ecparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +ecparam.o: ../include/openssl/x509v3.h apps.h ecparam.c
        +enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +enc.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +enc.o: ../include/openssl/engine.h ../include/openssl/err.h
        +enc.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +enc.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +enc.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +enc.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +enc.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h enc.c
        +engine.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +engine.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +engine.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +engine.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +engine.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +engine.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +engine.o: ../include/openssl/err.h ../include/openssl/evp.h
        +engine.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +engine.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +engine.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +engine.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +engine.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +engine.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +engine.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +engine.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +engine.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +engine.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +engine.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +engine.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +engine.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +engine.o: ../include/openssl/x509v3.h apps.h engine.c
        +errstr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +errstr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +errstr.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +errstr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +errstr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +errstr.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +errstr.o: ../include/openssl/err.h ../include/openssl/evp.h
        +errstr.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +errstr.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +errstr.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +errstr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +errstr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +errstr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +errstr.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +errstr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +errstr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +errstr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +errstr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +errstr.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +errstr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +errstr.o: ../include/openssl/x509v3.h apps.h errstr.c
        +gendh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +gendh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +gendh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +gendh.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +gendh.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +gendh.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +gendh.o: ../include/openssl/engine.h ../include/openssl/err.h
        +gendh.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +gendh.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +gendh.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +gendh.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +gendh.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +gendh.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +gendh.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +gendh.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +gendh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +gendh.o: ../include/openssl/ui.h ../include/openssl/x509.h
        +gendh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +gendh.o: gendh.c
        +gendsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +gendsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +gendsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +gendsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
        +gendsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +gendsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +gendsa.o: ../include/openssl/err.h ../include/openssl/evp.h
        +gendsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +gendsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +gendsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +gendsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +gendsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +gendsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +gendsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +gendsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +gendsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +gendsa.o: gendsa.c
        +genpkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +genpkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +genpkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +genpkey.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +genpkey.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +genpkey.o: ../include/openssl/err.h ../include/openssl/evp.h
        +genpkey.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +genpkey.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +genpkey.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +genpkey.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +genpkey.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +genpkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +genpkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +genpkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +genpkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +genpkey.o: genpkey.c
        +genrsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +genrsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +genrsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +genrsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +genrsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +genrsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +genrsa.o: ../include/openssl/engine.h ../include/openssl/err.h
        +genrsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +genrsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +genrsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +genrsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +genrsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +genrsa.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +genrsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +genrsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +genrsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +genrsa.o: ../include/openssl/ui.h ../include/openssl/x509.h
        +genrsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +genrsa.o: genrsa.c
        +nseq.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +nseq.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +nseq.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +nseq.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +nseq.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +nseq.o: ../include/openssl/err.h ../include/openssl/evp.h
        +nseq.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +nseq.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +nseq.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +nseq.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +nseq.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +nseq.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +nseq.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +nseq.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +nseq.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h nseq.c
        +ocsp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ocsp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ocsp.o: ../include/openssl/comp.h ../include/openssl/conf.h
        +ocsp.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +ocsp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ocsp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ocsp.o: ../include/openssl/engine.h ../include/openssl/err.h
        +ocsp.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ocsp.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ocsp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ocsp.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +ocsp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ocsp.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ocsp.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +ocsp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ocsp.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ocsp.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ocsp.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ocsp.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ocsp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +ocsp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ocsp.c
        +openssl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +openssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +openssl.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +openssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +openssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +openssl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +openssl.o: ../include/openssl/err.h ../include/openssl/evp.h
        +openssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +openssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +openssl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +openssl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +openssl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +openssl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +openssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +openssl.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +openssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +openssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +openssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +openssl.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +openssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +openssl.o: ../include/openssl/x509v3.h apps.h openssl.c progs.h s_apps.h
        +passwd.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +passwd.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +passwd.o: ../include/openssl/crypto.h ../include/openssl/des.h
        +passwd.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
        +passwd.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +passwd.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +passwd.o: ../include/openssl/err.h ../include/openssl/evp.h
        +passwd.o: ../include/openssl/lhash.h ../include/openssl/md5.h
        +passwd.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +passwd.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +passwd.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +passwd.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +passwd.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +passwd.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +passwd.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
        +passwd.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
        +passwd.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +passwd.o: passwd.c
        +pkcs12.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +pkcs12.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +pkcs12.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +pkcs12.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +pkcs12.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +pkcs12.o: ../include/openssl/err.h ../include/openssl/evp.h
        +pkcs12.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +pkcs12.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +pkcs12.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +pkcs12.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +pkcs12.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
        +pkcs12.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +pkcs12.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +pkcs12.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +pkcs12.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +pkcs12.o: ../include/openssl/x509v3.h apps.h pkcs12.c
        +pkcs7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +pkcs7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +pkcs7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +pkcs7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +pkcs7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +pkcs7.o: ../include/openssl/err.h ../include/openssl/evp.h
        +pkcs7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +pkcs7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +pkcs7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +pkcs7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +pkcs7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +pkcs7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +pkcs7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +pkcs7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +pkcs7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +pkcs7.o: pkcs7.c
        +pkcs8.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +pkcs8.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +pkcs8.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +pkcs8.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +pkcs8.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +pkcs8.o: ../include/openssl/err.h ../include/openssl/evp.h
        +pkcs8.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +pkcs8.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +pkcs8.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +pkcs8.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +pkcs8.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
        +pkcs8.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +pkcs8.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +pkcs8.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +pkcs8.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +pkcs8.o: ../include/openssl/x509v3.h apps.h pkcs8.c
        +pkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +pkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +pkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +pkey.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +pkey.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +pkey.o: ../include/openssl/err.h ../include/openssl/evp.h
        +pkey.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +pkey.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +pkey.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +pkey.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +pkey.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +pkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +pkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +pkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +pkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h pkey.c
        +pkeyparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +pkeyparam.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +pkeyparam.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +pkeyparam.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +pkeyparam.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +pkeyparam.o: ../include/openssl/err.h ../include/openssl/evp.h
        +pkeyparam.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +pkeyparam.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +pkeyparam.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +pkeyparam.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +pkeyparam.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +pkeyparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +pkeyparam.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +pkeyparam.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +pkeyparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +pkeyparam.o: pkeyparam.c
        +pkeyutl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +pkeyutl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +pkeyutl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +pkeyutl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +pkeyutl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +pkeyutl.o: ../include/openssl/err.h ../include/openssl/evp.h
        +pkeyutl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +pkeyutl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +pkeyutl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +pkeyutl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +pkeyutl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +pkeyutl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +pkeyutl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +pkeyutl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +pkeyutl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +pkeyutl.o: pkeyutl.c
        +prime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +prime.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +prime.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +prime.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +prime.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +prime.o: ../include/openssl/engine.h ../include/openssl/evp.h
        +prime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +prime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +prime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +prime.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +prime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +prime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +prime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +prime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +prime.o: prime.c
        +rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +rand.o: ../include/openssl/err.h ../include/openssl/evp.h
        +rand.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +rand.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +rand.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +rand.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +rand.o: ../include/openssl/rand.h ../include/openssl/safestack.h
        +rand.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +rand.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +rand.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +rand.o: ../include/openssl/x509v3.h apps.h rand.c
        +req.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +req.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +req.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +req.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +req.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +req.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +req.o: ../include/openssl/engine.h ../include/openssl/err.h
        +req.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +req.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +req.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +req.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +req.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +req.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +req.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +req.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +req.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +req.o: ../include/openssl/ui.h ../include/openssl/x509.h
        +req.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h req.c
        +rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +rsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +rsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +rsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +rsa.o: ../include/openssl/engine.h ../include/openssl/err.h
        +rsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +rsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +rsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +rsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +rsa.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
        +rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +rsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rsa.c
        +rsautl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +rsautl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +rsautl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +rsautl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +rsautl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +rsautl.o: ../include/openssl/err.h ../include/openssl/evp.h
        +rsautl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +rsautl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +rsautl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +rsautl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +rsautl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +rsautl.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +rsautl.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +rsautl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +rsautl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +rsautl.o: ../include/openssl/x509v3.h apps.h rsautl.c
        +s_cb.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s_cb.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s_cb.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +s_cb.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s_cb.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s_cb.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +s_cb.o: ../include/openssl/err.h ../include/openssl/evp.h
        +s_cb.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +s_cb.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +s_cb.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +s_cb.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s_cb.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s_cb.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s_cb.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s_cb.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s_cb.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s_cb.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s_cb.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s_cb.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s_cb.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +s_cb.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +s_cb.o: s_apps.h s_cb.c
        +s_client.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s_client.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +s_client.o: ../include/openssl/comp.h ../include/openssl/conf.h
        +s_client.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +s_client.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +s_client.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +s_client.o: ../include/openssl/engine.h ../include/openssl/err.h
        +s_client.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s_client.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s_client.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s_client.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +s_client.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +s_client.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +s_client.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +s_client.o: ../include/openssl/rand.h ../include/openssl/safestack.h
        +s_client.o: ../include/openssl/sha.h ../include/openssl/srp.h
        +s_client.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s_client.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +s_client.o: s_apps.h s_client.c timeouts.h
        +s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s_server.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +s_server.o: ../include/openssl/comp.h ../include/openssl/conf.h
        +s_server.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +s_server.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
        +s_server.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +s_server.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +s_server.o: ../include/openssl/engine.h ../include/openssl/err.h
        +s_server.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s_server.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s_server.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s_server.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +s_server.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +s_server.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +s_server.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +s_server.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +s_server.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s_server.o: ../include/openssl/srp.h ../include/openssl/srtp.h
        +s_server.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s_server.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s_server.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s_server.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +s_server.o: ../include/openssl/ui.h ../include/openssl/x509.h
        +s_server.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +s_server.o: s_apps.h s_server.c timeouts.h
        +s_socket.o: ../e_os.h ../e_os2.h ../include/openssl/asn1.h
        +s_socket.o: ../include/openssl/bio.h ../include/openssl/buffer.h
        +s_socket.o: ../include/openssl/comp.h ../include/openssl/conf.h
        +s_socket.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +s_socket.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +s_socket.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +s_socket.o: ../include/openssl/engine.h ../include/openssl/evp.h
        +s_socket.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +s_socket.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +s_socket.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +s_socket.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s_socket.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s_socket.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s_socket.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +s_socket.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s_socket.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s_socket.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s_socket.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s_socket.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +s_socket.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +s_socket.o: ../include/openssl/x509v3.h apps.h s_apps.h s_socket.c
        +s_time.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s_time.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s_time.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +s_time.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s_time.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s_time.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +s_time.o: ../include/openssl/err.h ../include/openssl/evp.h
        +s_time.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +s_time.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +s_time.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +s_time.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s_time.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s_time.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s_time.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +s_time.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s_time.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s_time.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s_time.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s_time.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +s_time.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +s_time.o: ../include/openssl/x509v3.h apps.h s_apps.h s_time.c
        +sess_id.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +sess_id.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +sess_id.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +sess_id.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +sess_id.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +sess_id.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +sess_id.o: ../include/openssl/err.h ../include/openssl/evp.h
        +sess_id.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +sess_id.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +sess_id.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +sess_id.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +sess_id.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +sess_id.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +sess_id.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
        +sess_id.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +sess_id.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +sess_id.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +sess_id.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +sess_id.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
        +sess_id.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +sess_id.o: ../include/openssl/x509v3.h apps.h sess_id.c
        +smime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +smime.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +smime.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +smime.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +smime.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +smime.o: ../include/openssl/err.h ../include/openssl/evp.h
        +smime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +smime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +smime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +smime.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +smime.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +smime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +smime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +smime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +smime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +smime.o: smime.c
        +speed.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h
        +speed.o: ../include/openssl/bio.h ../include/openssl/blowfish.h
        +speed.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +speed.o: ../include/openssl/camellia.h ../include/openssl/cast.h
        +speed.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +speed.o: ../include/openssl/des.h ../include/openssl/des_old.h
        +speed.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
        +speed.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +speed.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +speed.o: ../include/openssl/err.h ../include/openssl/evp.h
        +speed.o: ../include/openssl/hmac.h ../include/openssl/idea.h
        +speed.o: ../include/openssl/lhash.h ../include/openssl/md4.h
        +speed.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
        +speed.o: ../include/openssl/modes.h ../include/openssl/obj_mac.h
        +speed.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +speed.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +speed.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +speed.o: ../include/openssl/rand.h ../include/openssl/rc2.h
        +speed.o: ../include/openssl/rc4.h ../include/openssl/ripemd.h
        +speed.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +speed.o: ../include/openssl/seed.h ../include/openssl/sha.h
        +speed.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +speed.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
        +speed.o: ../include/openssl/ui_compat.h ../include/openssl/whrlpool.h
        +speed.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +speed.o: ../include/openssl/x509v3.h apps.h speed.c testdsa.h testrsa.h
        +spkac.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +spkac.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +spkac.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +spkac.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +spkac.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +spkac.o: ../include/openssl/err.h ../include/openssl/evp.h
        +spkac.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +spkac.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +spkac.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +spkac.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +spkac.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +spkac.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +spkac.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +spkac.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +spkac.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +spkac.o: spkac.c
        +srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +srp.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +srp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +srp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +srp.o: ../include/openssl/engine.h ../include/openssl/err.h
        +srp.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +srp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +srp.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +srp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +srp.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +srp.o: ../include/openssl/sha.h ../include/openssl/srp.h
        +srp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +srp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +srp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h srp.c
        +ts.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ts.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ts.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +ts.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +ts.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ts.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ts.o: ../include/openssl/engine.h ../include/openssl/err.h
        +ts.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +ts.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ts.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
        +ts.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ts.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ts.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +ts.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +ts.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +ts.o: ../include/openssl/symhacks.h ../include/openssl/ts.h
        +ts.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +ts.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ts.c
        +verify.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +verify.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +verify.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +verify.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +verify.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +verify.o: ../include/openssl/err.h ../include/openssl/evp.h
        +verify.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +verify.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +verify.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +verify.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +verify.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +verify.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +verify.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +verify.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
        +verify.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
        +verify.o: verify.c
        +version.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
        +version.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +version.o: ../include/openssl/crypto.h ../include/openssl/des.h
        +version.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
        +version.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +version.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +version.o: ../include/openssl/evp.h ../include/openssl/idea.h
        +version.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +version.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +version.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +version.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +version.o: ../include/openssl/rc4.h ../include/openssl/safestack.h
        +version.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +version.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +version.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
        +version.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +version.o: ../include/openssl/x509v3.h apps.h version.c
        +x509.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +x509.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +x509.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +x509.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
        +x509.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +x509.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +x509.o: ../include/openssl/err.h ../include/openssl/evp.h
        +x509.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +x509.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +x509.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +x509.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +x509.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +x509.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +x509.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +x509.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
        +x509.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +x509.o: ../include/openssl/x509v3.h apps.h x509.c
        diff --git a/vendor/openssl/openssl/apps/app_rand.c b/vendor/openssl/openssl/apps/app_rand.c
        new file mode 100644
        index 000000000..b7b6128c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/app_rand.c
        @@ -0,0 +1,218 @@
        +/* apps/app_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).
        + *
        + */
        +
        +#define NON_MAIN
        +#include "apps.h"
        +#undef NON_MAIN
        +#include <openssl/bio.h>
        +#include <openssl/rand.h>
        +
        +
        +static int seeded = 0;
        +static int egdsocket = 0;
        +
        +int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn)
        +	{
        +	int consider_randfile = (file == NULL);
        +	char buffer[200];
        +	
        +#ifdef OPENSSL_SYS_WINDOWS
        +	BIO_printf(bio_e,"Loading 'screen' into random state -");
        +	BIO_flush(bio_e);
        +	RAND_screen();
        +	BIO_printf(bio_e," done\n");
        +#endif
        +
        +	if (file == NULL)
        +		file = RAND_file_name(buffer, sizeof buffer);
        +	else if (RAND_egd(file) > 0)
        +		{
        +		/* we try if the given filename is an EGD socket.
        +		   if it is, we don't write anything back to the file. */
        +		egdsocket = 1;
        +		return 1;
        +		}
        +	if (file == NULL || !RAND_load_file(file, -1))
        +		{
        +		if (RAND_status() == 0)
        +			{
        +			if (!dont_warn)
        +				{
        +				BIO_printf(bio_e,"unable to load 'random state'\n");
        +				BIO_printf(bio_e,"This means that the random number generator has not been seeded\n");
        +				BIO_printf(bio_e,"with much random data.\n");
        +				if (consider_randfile) /* explanation does not apply when a file is explicitly named */
        +					{
        +					BIO_printf(bio_e,"Consider setting the RANDFILE environment variable to point at a file that\n");
        +					BIO_printf(bio_e,"'random' data can be kept in (the file will be overwritten).\n");
        +					}
        +				}
        +			return 0;
        +			}
        +		}
        +	seeded = 1;
        +	return 1;
        +	}
        +
        +long app_RAND_load_files(char *name)
        +	{
        +	char *p,*n;
        +	int last;
        +	long tot=0;
        +	int egd;
        +	
        +	for (;;)
        +		{
        +		last=0;
        +		for (p=name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++);
        +		if (*p == '\0') last=1;
        +		*p='\0';
        +		n=name;
        +		name=p+1;
        +		if (*n == '\0') break;
        +
        +		egd=RAND_egd(n);
        +		if (egd > 0)
        +			tot+=egd;
        +		else
        +			tot+=RAND_load_file(n,-1);
        +		if (last) break;
        +		}
        +	if (tot > 512)
        +		app_RAND_allow_write_file();
        +	return(tot);
        +	}
        +
        +int app_RAND_write_file(const char *file, BIO *bio_e)
        +	{
        +	char buffer[200];
        +	
        +	if (egdsocket || !seeded)
        +		/* If we did not manage to read the seed file,
        +		 * we should not write a low-entropy seed file back --
        +		 * it would suppress a crucial warning the next time
        +		 * we want to use it. */
        +		return 0;
        +
        +	if (file == NULL)
        +		file = RAND_file_name(buffer, sizeof buffer);
        +	if (file == NULL || !RAND_write_file(file))
        +		{
        +		BIO_printf(bio_e,"unable to write 'random state'\n");
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +void app_RAND_allow_write_file(void)
        +	{
        +	seeded = 1;
        +	}
        diff --git a/vendor/openssl/openssl/apps/apps.c b/vendor/openssl/openssl/apps/apps.c
        new file mode 100644
        index 000000000..1096eee4c
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/apps.c
        @@ -0,0 +1,3094 @@
        +/* apps/apps.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
        +#define _POSIX_C_SOURCE 2	/* On VMS, you need to define this to get
        +				   the declaration of fileno().  The value
        +				   2 is to make sure no function defined
        +				   in POSIX-2 is left undefined. */
        +#endif
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB)
        +#include <strings.h>
        +#endif
        +#include <sys/types.h>
        +#include <ctype.h>
        +#include <errno.h>
        +#include <assert.h>
        +#include <openssl/err.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/pem.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/ui.h>
        +#include <openssl/safestack.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_JPAKE
        +#include <openssl/jpake.h>
        +#endif
        +
        +#define NON_MAIN
        +#include "apps.h"
        +#undef NON_MAIN
        +
        +#ifdef _WIN32
        +static int WIN32_rename(const char *from, const char *to);
        +#define rename(from,to) WIN32_rename((from),(to))
        +#endif
        +
        +typedef struct {
        +	const char *name;
        +	unsigned long flag;
        +	unsigned long mask;
        +} NAME_EX_TBL;
        +
        +static UI_METHOD *ui_method = NULL;
        +
        +static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
        +static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
        +
        +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
        +/* Looks like this stuff is worth moving into separate function */
        +static EVP_PKEY *
        +load_netscape_key(BIO *err, BIO *key, const char *file,
        +		const char *key_descrip, int format);
        +#endif
        +
        +int app_init(long mesgwin);
        +#ifdef undef /* never finished - probably never will be :-) */
        +int args_from_file(char *file, int *argc, char **argv[])
        +	{
        +	FILE *fp;
        +	int num,i;
        +	unsigned int len;
        +	static char *buf=NULL;
        +	static char **arg=NULL;
        +	char *p;
        +
        +	fp=fopen(file,"r");
        +	if (fp == NULL)
        +		return(0);
        +
        +	if (fseek(fp,0,SEEK_END)==0)
        +		len=ftell(fp), rewind(fp);
        +	else	len=-1;
        +	if (len<=0)
        +		{
        +		fclose(fp);
        +		return(0);
        +		}
        +
        +	*argc=0;
        +	*argv=NULL;
        +
        +	if (buf != NULL) OPENSSL_free(buf);
        +	buf=(char *)OPENSSL_malloc(len+1);
        +	if (buf == NULL) return(0);
        +
        +	len=fread(buf,1,len,fp);
        +	if (len <= 1) return(0);
        +	buf[len]='\0';
        +
        +	i=0;
        +	for (p=buf; *p; p++)
        +		if (*p == '\n') i++;
        +	if (arg != NULL) OPENSSL_free(arg);
        +	arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
        +
        +	*argv=arg;
        +	num=0;
        +	p=buf;
        +	for (;;)
        +		{
        +		if (!*p) break;
        +		if (*p == '#') /* comment line */
        +			{
        +			while (*p && (*p != '\n')) p++;
        +			continue;
        +			}
        +		/* else we have a line */
        +		*(arg++)=p;
        +		num++;
        +		while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
        +			p++;
        +		if (!*p) break;
        +		if (*p == '\n')
        +			{
        +			*(p++)='\0';
        +			continue;
        +			}
        +		/* else it is a tab or space */
        +		p++;
        +		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
        +			p++;
        +		if (!*p) break;
        +		if (*p == '\n')
        +			{
        +			p++;
        +			continue;
        +			}
        +		*(arg++)=p++;
        +		num++;
        +		while (*p && (*p != '\n')) p++;
        +		if (!*p) break;
        +		/* else *p == '\n' */
        +		*(p++)='\0';
        +		}
        +	*argc=num;
        +	return(1);
        +	}
        +#endif
        +
        +int str2fmt(char *s)
        +	{
        +	if (s == NULL)
        +		return FORMAT_UNDEF;
        +	if 	((*s == 'D') || (*s == 'd'))
        +		return(FORMAT_ASN1);
        +	else if ((*s == 'T') || (*s == 't'))
        +		return(FORMAT_TEXT);
        +  	else if ((*s == 'N') || (*s == 'n'))
        +  		return(FORMAT_NETSCAPE);
        +  	else if ((*s == 'S') || (*s == 's'))
        +  		return(FORMAT_SMIME);
        + 	else if ((*s == 'M') || (*s == 'm'))
        + 		return(FORMAT_MSBLOB);
        +	else if ((*s == '1')
        +		|| (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
        +		|| (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
        +		return(FORMAT_PKCS12);
        +	else if ((*s == 'E') || (*s == 'e'))
        +		return(FORMAT_ENGINE);
        +	else if ((*s == 'P') || (*s == 'p'))
        + 		{
        + 		if (s[1] == 'V' || s[1] == 'v')
        + 			return FORMAT_PVK;
        + 		else
        +  			return(FORMAT_PEM);
        + 		}
        +	else
        +		return(FORMAT_UNDEF);
        +	}
        +
        +#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
        +void program_name(char *in, char *out, int size)
        +	{
        +	int i,n;
        +	char *p=NULL;
        +
        +	n=strlen(in);
        +	/* find the last '/', '\' or ':' */
        +	for (i=n-1; i>0; i--)
        +		{
        +		if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
        +			{
        +			p= &(in[i+1]);
        +			break;
        +			}
        +		}
        +	if (p == NULL)
        +		p=in;
        +	n=strlen(p);
        +
        +#if defined(OPENSSL_SYS_NETWARE)
        +   /* strip off trailing .nlm if present. */
        +   if ((n > 4) && (p[n-4] == '.') &&
        +      ((p[n-3] == 'n') || (p[n-3] == 'N')) &&
        +      ((p[n-2] == 'l') || (p[n-2] == 'L')) &&
        +      ((p[n-1] == 'm') || (p[n-1] == 'M')))
        +      n-=4;
        +#else
        +	/* strip off trailing .exe if present. */
        +	if ((n > 4) && (p[n-4] == '.') &&
        +		((p[n-3] == 'e') || (p[n-3] == 'E')) &&
        +		((p[n-2] == 'x') || (p[n-2] == 'X')) &&
        +		((p[n-1] == 'e') || (p[n-1] == 'E')))
        +		n-=4;
        +#endif
        +
        +	if (n > size-1)
        +		n=size-1;
        +
        +	for (i=0; i<n; i++)
        +		{
        +		if ((p[i] >= 'A') && (p[i] <= 'Z'))
        +			out[i]=p[i]-'A'+'a';
        +		else
        +			out[i]=p[i];
        +		}
        +	out[n]='\0';
        +	}
        +#else
        +#ifdef OPENSSL_SYS_VMS
        +void program_name(char *in, char *out, int size)
        +	{
        +	char *p=in, *q;
        +	char *chars=":]>";
        +
        +	while(*chars != '\0')
        +		{
        +		q=strrchr(p,*chars);
        +		if (q > p)
        +			p = q + 1;
        +		chars++;
        +		}
        +
        +	q=strrchr(p,'.');
        +	if (q == NULL)
        +		q = p + strlen(p);
        +	strncpy(out,p,size-1);
        +	if (q-p >= size)
        +		{
        +		out[size-1]='\0';
        +		}
        +	else
        +		{
        +		out[q-p]='\0';
        +		}
        +	}
        +#else
        +void program_name(char *in, char *out, int size)
        +	{
        +	char *p;
        +
        +	p=strrchr(in,'/');
        +	if (p != NULL)
        +		p++;
        +	else
        +		p=in;
        +	BUF_strlcpy(out,p,size);
        +	}
        +#endif
        +#endif
        +
        +int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
        +	{
        +	int num,i;
        +	char *p;
        +
        +	*argc=0;
        +	*argv=NULL;
        +
        +	i=0;
        +	if (arg->count == 0)
        +		{
        +		arg->count=20;
        +		arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
        +		}
        +	for (i=0; i<arg->count; i++)
        +		arg->data[i]=NULL;
        +
        +	num=0;
        +	p=buf;
        +	for (;;)
        +		{
        +		/* first scan over white space */
        +		if (!*p) break;
        +		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
        +			p++;
        +		if (!*p) break;
        +
        +		/* The start of something good :-) */
        +		if (num >= arg->count)
        +			{
        +			char **tmp_p;
        +			int tlen = arg->count + 20;
        +			tmp_p = (char **)OPENSSL_realloc(arg->data,
        +				sizeof(char *)*tlen);
        +			if (tmp_p == NULL)
        +				return 0;
        +			arg->data  = tmp_p;
        +			arg->count = tlen;
        +			/* initialize newly allocated data */
        +			for (i = num; i < arg->count; i++)
        +				arg->data[i] = NULL;
        +			}
        +		arg->data[num++]=p;
        +
        +		/* now look for the end of this */
        +		if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */
        +			{
        +			i= *(p++);
        +			arg->data[num-1]++; /* jump over quote */
        +			while (*p && (*p != i))
        +				p++;
        +			*p='\0';
        +			}
        +		else
        +			{
        +			while (*p && ((*p != ' ') &&
        +				(*p != '\t') && (*p != '\n')))
        +				p++;
        +
        +			if (*p == '\0')
        +				p--;
        +			else
        +				*p='\0';
        +			}
        +		p++;
        +		}
        +	*argc=num;
        +	*argv=arg->data;
        +	return(1);
        +	}
        +
        +#ifndef APP_INIT
        +int app_init(long mesgwin)
        +	{
        +	return(1);
        +	}
        +#endif
        +
        +
        +int dump_cert_text (BIO *out, X509 *x)
        +{
        +	char *p;
        +
        +	p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0);
        +	BIO_puts(out,"subject=");
        +	BIO_puts(out,p);
        +	OPENSSL_free(p);
        +
        +	p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0);
        +	BIO_puts(out,"\nissuer=");
        +	BIO_puts(out,p);
        +	BIO_puts(out,"\n");
        +	OPENSSL_free(p);
        +
        +	return 0;
        +}
        +
        +static int ui_open(UI *ui)
        +	{
        +	return UI_method_get_opener(UI_OpenSSL())(ui);
        +	}
        +static int ui_read(UI *ui, UI_STRING *uis)
        +	{
        +	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
        +		&& UI_get0_user_data(ui))
        +		{
        +		switch(UI_get_string_type(uis))
        +			{
        +		case UIT_PROMPT:
        +		case UIT_VERIFY:
        +			{
        +			const char *password =
        +				((PW_CB_DATA *)UI_get0_user_data(ui))->password;
        +			if (password && password[0] != '\0')
        +				{
        +				UI_set_result(ui, uis, password);
        +				return 1;
        +				}
        +			}
        +		default:
        +			break;
        +			}
        +		}
        +	return UI_method_get_reader(UI_OpenSSL())(ui, uis);
        +	}
        +static int ui_write(UI *ui, UI_STRING *uis)
        +	{
        +	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
        +		&& UI_get0_user_data(ui))
        +		{
        +		switch(UI_get_string_type(uis))
        +			{
        +		case UIT_PROMPT:
        +		case UIT_VERIFY:
        +			{
        +			const char *password =
        +				((PW_CB_DATA *)UI_get0_user_data(ui))->password;
        +			if (password && password[0] != '\0')
        +				return 1;
        +			}
        +		default:
        +			break;
        +			}
        +		}
        +	return UI_method_get_writer(UI_OpenSSL())(ui, uis);
        +	}
        +static int ui_close(UI *ui)
        +	{
        +	return UI_method_get_closer(UI_OpenSSL())(ui);
        +	}
        +int setup_ui_method(void)
        +	{
        +	ui_method = UI_create_method("OpenSSL application user interface");
        +	UI_method_set_opener(ui_method, ui_open);
        +	UI_method_set_reader(ui_method, ui_read);
        +	UI_method_set_writer(ui_method, ui_write);
        +	UI_method_set_closer(ui_method, ui_close);
        +	return 0;
        +	}
        +void destroy_ui_method(void)
        +	{
        +	if(ui_method)
        +		{
        +		UI_destroy_method(ui_method);
        +		ui_method = NULL;
        +		}
        +	}
        +int password_callback(char *buf, int bufsiz, int verify,
        +	PW_CB_DATA *cb_tmp)
        +	{
        +	UI *ui = NULL;
        +	int res = 0;
        +	const char *prompt_info = NULL;
        +	const char *password = NULL;
        +	PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
        +
        +	if (cb_data)
        +		{
        +		if (cb_data->password)
        +			password = cb_data->password;
        +		if (cb_data->prompt_info)
        +			prompt_info = cb_data->prompt_info;
        +		}
        +
        +	if (password)
        +		{
        +		res = strlen(password);
        +		if (res > bufsiz)
        +			res = bufsiz;
        +		memcpy(buf, password, res);
        +		return res;
        +		}
        +
        +	ui = UI_new_method(ui_method);
        +	if (ui)
        +		{
        +		int ok = 0;
        +		char *buff = NULL;
        +		int ui_flags = 0;
        +		char *prompt = NULL;
        +
        +		prompt = UI_construct_prompt(ui, "pass phrase",
        +			prompt_info);
        +
        +		ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
        +		UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
        +
        +		if (ok >= 0)
        +			ok = UI_add_input_string(ui,prompt,ui_flags,buf,
        +				PW_MIN_LENGTH,BUFSIZ-1);
        +		if (ok >= 0 && verify)
        +			{
        +			buff = (char *)OPENSSL_malloc(bufsiz);
        +			ok = UI_add_verify_string(ui,prompt,ui_flags,buff,
        +				PW_MIN_LENGTH,BUFSIZ-1, buf);
        +			}
        +		if (ok >= 0)
        +			do
        +				{
        +				ok = UI_process(ui);
        +				}
        +			while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
        +
        +		if (buff)
        +			{
        +			OPENSSL_cleanse(buff,(unsigned int)bufsiz);
        +			OPENSSL_free(buff);
        +			}
        +
        +		if (ok >= 0)
        +			res = strlen(buf);
        +		if (ok == -1)
        +			{
        +			BIO_printf(bio_err, "User interface error\n");
        +			ERR_print_errors(bio_err);
        +			OPENSSL_cleanse(buf,(unsigned int)bufsiz);
        +			res = 0;
        +			}
        +		if (ok == -2)
        +			{
        +			BIO_printf(bio_err,"aborted!\n");
        +			OPENSSL_cleanse(buf,(unsigned int)bufsiz);
        +			res = 0;
        +			}
        +		UI_free(ui);
        +		OPENSSL_free(prompt);
        +		}
        +	return res;
        +	}
        +
        +static char *app_get_pass(BIO *err, char *arg, int keepbio);
        +
        +int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
        +{
        +	int same;
        +	if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
        +	else same = 1;
        +	if(arg1) {
        +		*pass1 = app_get_pass(err, arg1, same);
        +		if(!*pass1) return 0;
        +	} else if(pass1) *pass1 = NULL;
        +	if(arg2) {
        +		*pass2 = app_get_pass(err, arg2, same ? 2 : 0);
        +		if(!*pass2) return 0;
        +	} else if(pass2) *pass2 = NULL;
        +	return 1;
        +}
        +
        +static char *app_get_pass(BIO *err, char *arg, int keepbio)
        +{
        +	char *tmp, tpass[APP_PASS_LEN];
        +	static BIO *pwdbio = NULL;
        +	int i;
        +	if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
        +	if(!strncmp(arg, "env:", 4)) {
        +		tmp = getenv(arg + 4);
        +		if(!tmp) {
        +			BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
        +			return NULL;
        +		}
        +		return BUF_strdup(tmp);
        +	}
        +	if(!keepbio || !pwdbio) {
        +		if(!strncmp(arg, "file:", 5)) {
        +			pwdbio = BIO_new_file(arg + 5, "r");
        +			if(!pwdbio) {
        +				BIO_printf(err, "Can't open file %s\n", arg + 5);
        +				return NULL;
        +			}
        +#if !defined(_WIN32)
        +		/*
        +		 * Under _WIN32, which covers even Win64 and CE, file
        +		 * descriptors referenced by BIO_s_fd are not inherited
        +		 * by child process and therefore below is not an option.
        +		 * It could have been an option if bss_fd.c was operating
        +		 * on real Windows descriptors, such as those obtained
        +		 * with CreateFile.
        +		 */
        +		} else if(!strncmp(arg, "fd:", 3)) {
        +			BIO *btmp;
        +			i = atoi(arg + 3);
        +			if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
        +			if((i < 0) || !pwdbio) {
        +				BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
        +				return NULL;
        +			}
        +			/* Can't do BIO_gets on an fd BIO so add a buffering BIO */
        +			btmp = BIO_new(BIO_f_buffer());
        +			pwdbio = BIO_push(btmp, pwdbio);
        +#endif
        +		} else if(!strcmp(arg, "stdin")) {
        +			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
        +			if(!pwdbio) {
        +				BIO_printf(err, "Can't open BIO for stdin\n");
        +				return NULL;
        +			}
        +		} else {
        +			BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
        +			return NULL;
        +		}
        +	}
        +	i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
        +	if(keepbio != 1) {
        +		BIO_free_all(pwdbio);
        +		pwdbio = NULL;
        +	}
        +	if(i <= 0) {
        +		BIO_printf(err, "Error reading password from BIO\n");
        +		return NULL;
        +	}
        +	tmp = strchr(tpass, '\n');
        +	if(tmp) *tmp = 0;
        +	return BUF_strdup(tpass);
        +}
        +
        +int add_oid_section(BIO *err, CONF *conf)
        +{	
        +	char *p;
        +	STACK_OF(CONF_VALUE) *sktmp;
        +	CONF_VALUE *cnf;
        +	int i;
        +	if(!(p=NCONF_get_string(conf,NULL,"oid_section")))
        +		{
        +		ERR_clear_error();
        +		return 1;
        +		}
        +	if(!(sktmp = NCONF_get_section(conf, p))) {
        +		BIO_printf(err, "problem loading oid section %s\n", p);
        +		return 0;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
        +		cnf = sk_CONF_VALUE_value(sktmp, i);
        +		if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
        +			BIO_printf(err, "problem creating object %s=%s\n",
        +							 cnf->name, cnf->value);
        +			return 0;
        +		}
        +	}
        +	return 1;
        +}
        +
        +static int load_pkcs12(BIO *err, BIO *in, const char *desc,
        +		pem_password_cb *pem_cb,  void *cb_data,
        +		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
        +	{
        + 	const char *pass;
        +	char tpass[PEM_BUFSIZE];
        +	int len, ret = 0;
        +	PKCS12 *p12;
        +	p12 = d2i_PKCS12_bio(in, NULL);
        +	if (p12 == NULL)
        +		{
        +		BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);	
        +		goto die;
        +		}
        +	/* See if an empty password will do */
        +	if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
        +		pass = "";
        +	else
        +		{
        +		if (!pem_cb)
        +			pem_cb = (pem_password_cb *)password_callback;
        +		len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
        +		if (len < 0) 
        +			{
        +			BIO_printf(err, "Passpharse callback error for %s\n",
        +					desc);
        +			goto die;
        +			}
        +		if (len < PEM_BUFSIZE)
        +			tpass[len] = 0;
        +		if (!PKCS12_verify_mac(p12, tpass, len))
        +			{
        +			BIO_printf(err,
        +	"Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);	
        +			goto die;
        +			}
        +		pass = tpass;
        +		}
        +	ret = PKCS12_parse(p12, pass, pkey, cert, ca);
        +	die:
        +	if (p12)
        +		PKCS12_free(p12);
        +	return ret;
        +	}
        +
        +X509 *load_cert(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *cert_descrip)
        +	{
        +	X509 *x=NULL;
        +	BIO *cert;
        +
        +	if ((cert=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ERR_print_errors(err);
        +		goto end;
        +		}
        +
        +	if (file == NULL)
        +		{
        +#ifdef _IONBF
        +# ifndef OPENSSL_NO_SETVBUF_IONBF
        +		setvbuf(stdin, NULL, _IONBF, 0);
        +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
        +#endif
        +		BIO_set_fp(cert,stdin,BIO_NOCLOSE);
        +		}
        +	else
        +		{
        +		if (BIO_read_filename(cert,file) <= 0)
        +			{
        +			BIO_printf(err, "Error opening %s %s\n",
        +				cert_descrip, file);
        +			ERR_print_errors(err);
        +			goto end;
        +			}
        +		}
        +
        +	if 	(format == FORMAT_ASN1)
        +		x=d2i_X509_bio(cert,NULL);
        +	else if (format == FORMAT_NETSCAPE)
        +		{
        +		NETSCAPE_X509 *nx;
        +		nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
        +		if (nx == NULL)
        +				goto end;
        +
        +		if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
        +			nx->header->length) != 0))
        +			{
        +			NETSCAPE_X509_free(nx);
        +			BIO_printf(err,"Error reading header on certificate\n");
        +			goto end;
        +			}
        +		x=nx->cert;
        +		nx->cert = NULL;
        +		NETSCAPE_X509_free(nx);
        +		}
        +	else if (format == FORMAT_PEM)
        +		x=PEM_read_bio_X509_AUX(cert,NULL,
        +			(pem_password_cb *)password_callback, NULL);
        +	else if (format == FORMAT_PKCS12)
        +		{
        +		if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL,
        +					NULL, &x, NULL))
        +			goto end;
        +		}
        +	else	{
        +		BIO_printf(err,"bad input format specified for %s\n",
        +			cert_descrip);
        +		goto end;
        +		}
        +end:
        +	if (x == NULL)
        +		{
        +		BIO_printf(err,"unable to load certificate\n");
        +		ERR_print_errors(err);
        +		}
        +	if (cert != NULL) BIO_free(cert);
        +	return(x);
        +	}
        +
        +EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
        +	const char *pass, ENGINE *e, const char *key_descrip)
        +	{
        +	BIO *key=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	PW_CB_DATA cb_data;
        +
        +	cb_data.password = pass;
        +	cb_data.prompt_info = file;
        +
        +	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
        +		{
        +		BIO_printf(err,"no keyfile specified\n");
        +		goto end;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	if (format == FORMAT_ENGINE)
        +		{
        +		if (!e)
        +			BIO_printf(err,"no engine specified\n");
        +		else
        +			{
        +			pkey = ENGINE_load_private_key(e, file,
        +				ui_method, &cb_data);
        +			if (!pkey) 
        +				{
        +				BIO_printf(err,"cannot load %s from engine\n",key_descrip);
        +				ERR_print_errors(err);
        +				}	
        +			}
        +		goto end;
        +		}
        +#endif
        +	key=BIO_new(BIO_s_file());
        +	if (key == NULL)
        +		{
        +		ERR_print_errors(err);
        +		goto end;
        +		}
        +	if (file == NULL && maybe_stdin)
        +		{
        +#ifdef _IONBF
        +# ifndef OPENSSL_NO_SETVBUF_IONBF
        +		setvbuf(stdin, NULL, _IONBF, 0);
        +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
        +#endif
        +		BIO_set_fp(key,stdin,BIO_NOCLOSE);
        +		}
        +	else
        +		if (BIO_read_filename(key,file) <= 0)
        +			{
        +			BIO_printf(err, "Error opening %s %s\n",
        +				key_descrip, file);
        +			ERR_print_errors(err);
        +			goto end;
        +			}
        +	if (format == FORMAT_ASN1)
        +		{
        +		pkey=d2i_PrivateKey_bio(key, NULL);
        +		}
        +	else if (format == FORMAT_PEM)
        +		{
        +		pkey=PEM_read_bio_PrivateKey(key,NULL,
        +			(pem_password_cb *)password_callback, &cb_data);
        +		}
        +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
        +	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
        +		pkey = load_netscape_key(err, key, file, key_descrip, format);
        +#endif
        +	else if (format == FORMAT_PKCS12)
        +		{
        +		if (!load_pkcs12(err, key, key_descrip,
        +				(pem_password_cb *)password_callback, &cb_data,
        +				&pkey, NULL, NULL))
        +			goto end;
        +		}
        +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
        +	else if (format == FORMAT_MSBLOB)
        +		pkey = b2i_PrivateKey_bio(key);
        +	else if (format == FORMAT_PVK)
        +		pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
        +								&cb_data);
        +#endif
        +	else
        +		{
        +		BIO_printf(err,"bad input format specified for key file\n");
        +		goto end;
        +		}
        + end:
        +	if (key != NULL) BIO_free(key);
        +	if (pkey == NULL) 
        +		{
        +		BIO_printf(err,"unable to load %s\n", key_descrip);
        +		ERR_print_errors(err);
        +		}	
        +	return(pkey);
        +	}
        +
        +EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
        +	const char *pass, ENGINE *e, const char *key_descrip)
        +	{
        +	BIO *key=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	PW_CB_DATA cb_data;
        +
        +	cb_data.password = pass;
        +	cb_data.prompt_info = file;
        +
        +	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
        +		{
        +		BIO_printf(err,"no keyfile specified\n");
        +		goto end;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	if (format == FORMAT_ENGINE)
        +		{
        +		if (!e)
        +			BIO_printf(bio_err,"no engine specified\n");
        +		else
        +			pkey = ENGINE_load_public_key(e, file,
        +				ui_method, &cb_data);
        +		goto end;
        +		}
        +#endif
        +	key=BIO_new(BIO_s_file());
        +	if (key == NULL)
        +		{
        +		ERR_print_errors(err);
        +		goto end;
        +		}
        +	if (file == NULL && maybe_stdin)
        +		{
        +#ifdef _IONBF
        +# ifndef OPENSSL_NO_SETVBUF_IONBF
        +		setvbuf(stdin, NULL, _IONBF, 0);
        +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
        +#endif
        +		BIO_set_fp(key,stdin,BIO_NOCLOSE);
        +		}
        +	else
        +		if (BIO_read_filename(key,file) <= 0)
        +			{
        +			BIO_printf(err, "Error opening %s %s\n",
        +				key_descrip, file);
        +			ERR_print_errors(err);
        +			goto end;
        +		}
        +	if (format == FORMAT_ASN1)
        +		{
        +		pkey=d2i_PUBKEY_bio(key, NULL);
        +		}
        +#ifndef OPENSSL_NO_RSA
        +	else if (format == FORMAT_ASN1RSA)
        +		{
        +		RSA *rsa;
        +		rsa = d2i_RSAPublicKey_bio(key, NULL);
        +		if (rsa)
        +			{
        +			pkey = EVP_PKEY_new();
        +			if (pkey)
        +				EVP_PKEY_set1_RSA(pkey, rsa);
        +			RSA_free(rsa);
        +			}
        +		else
        +			pkey = NULL;
        +		}
        +	else if (format == FORMAT_PEMRSA)
        +		{
        +		RSA *rsa;
        +		rsa = PEM_read_bio_RSAPublicKey(key, NULL, 
        +			(pem_password_cb *)password_callback, &cb_data);
        +		if (rsa)
        +			{
        +			pkey = EVP_PKEY_new();
        +			if (pkey)
        +				EVP_PKEY_set1_RSA(pkey, rsa);
        +			RSA_free(rsa);
        +			}
        +		else
        +			pkey = NULL;
        +		}
        +#endif
        +	else if (format == FORMAT_PEM)
        +		{
        +		pkey=PEM_read_bio_PUBKEY(key,NULL,
        +			(pem_password_cb *)password_callback, &cb_data);
        +		}
        +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
        +	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
        +		pkey = load_netscape_key(err, key, file, key_descrip, format);
        +#endif
        +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
        +	else if (format == FORMAT_MSBLOB)
        +		pkey = b2i_PublicKey_bio(key);
        +#endif
        +	else
        +		{
        +		BIO_printf(err,"bad input format specified for key file\n");
        +		goto end;
        +		}
        + end:
        +	if (key != NULL) BIO_free(key);
        +	if (pkey == NULL)
        +		BIO_printf(err,"unable to load %s\n", key_descrip);
        +	return(pkey);
        +	}
        +
        +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
        +static EVP_PKEY *
        +load_netscape_key(BIO *err, BIO *key, const char *file,
        +		const char *key_descrip, int format)
        +	{
        +	EVP_PKEY *pkey;
        +	BUF_MEM *buf;
        +	RSA	*rsa;
        +	const unsigned char *p;
        +	int size, i;
        +
        +	buf=BUF_MEM_new();
        +	pkey = EVP_PKEY_new();
        +	size = 0;
        +	if (buf == NULL || pkey == NULL)
        +		goto error;
        +	for (;;)
        +		{
        +		if (!BUF_MEM_grow_clean(buf,size+1024*10))
        +			goto error;
        +		i = BIO_read(key, &(buf->data[size]), 1024*10);
        +		size += i;
        +		if (i == 0)
        +			break;
        +		if (i < 0)
        +			{
        +				BIO_printf(err, "Error reading %s %s",
        +					key_descrip, file);
        +				goto error;
        +			}
        +		}
        +	p=(unsigned char *)buf->data;
        +	rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL,
        +		(format == FORMAT_IISSGC ? 1 : 0));
        +	if (rsa == NULL)
        +		goto error;
        +	BUF_MEM_free(buf);
        +	EVP_PKEY_set1_RSA(pkey, rsa);
        +	return pkey;
        +error:
        +	BUF_MEM_free(buf);
        +	EVP_PKEY_free(pkey);
        +	return NULL;
        +	}
        +#endif /* ndef OPENSSL_NO_RC4 */
        +
        +static int load_certs_crls(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *desc,
        +	STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
        +	{
        +	int i;
        +	BIO *bio;
        +	STACK_OF(X509_INFO) *xis = NULL;
        +	X509_INFO *xi;
        +	PW_CB_DATA cb_data;
        +	int rv = 0;
        +
        +	cb_data.password = pass;
        +	cb_data.prompt_info = file;
        +
        +	if (format != FORMAT_PEM)
        +		{
        +		BIO_printf(err,"bad input format specified for %s\n", desc);
        +		return 0;
        +		}
        +
        +	if (file == NULL)
        +		bio = BIO_new_fp(stdin,BIO_NOCLOSE);
        +	else
        +		bio = BIO_new_file(file, "r");
        +
        +	if (bio == NULL)
        +		{
        +		BIO_printf(err, "Error opening %s %s\n",
        +				desc, file ? file : "stdin");
        +		ERR_print_errors(err);
        +		return 0;
        +		}
        +
        +	xis = PEM_X509_INFO_read_bio(bio, NULL,
        +				(pem_password_cb *)password_callback, &cb_data);
        +
        +	BIO_free(bio);
        +
        +	if (pcerts)
        +		{
        +		*pcerts = sk_X509_new_null();
        +		if (!*pcerts)
        +			goto end;
        +		}
        +
        +	if (pcrls)
        +		{
        +		*pcrls = sk_X509_CRL_new_null();
        +		if (!*pcrls)
        +			goto end;
        +		}
        +
        +	for(i = 0; i < sk_X509_INFO_num(xis); i++)
        +		{
        +		xi = sk_X509_INFO_value (xis, i);
        +		if (xi->x509 && pcerts)
        +			{
        +			if (!sk_X509_push(*pcerts, xi->x509))
        +				goto end;
        +			xi->x509 = NULL;
        +			}
        +		if (xi->crl && pcrls)
        +			{
        +			if (!sk_X509_CRL_push(*pcrls, xi->crl))
        +				goto end;
        +			xi->crl = NULL;
        +			}
        +		}
        +
        +	if (pcerts && sk_X509_num(*pcerts) > 0)
        +		rv = 1;
        +
        +	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
        +		rv = 1;
        +
        +	end:
        +
        +	if (xis)
        +		sk_X509_INFO_pop_free(xis, X509_INFO_free);
        +
        +	if (rv == 0)
        +		{
        +		if (pcerts)
        +			{
        +			sk_X509_pop_free(*pcerts, X509_free);
        +			*pcerts = NULL;
        +			}
        +		if (pcrls)
        +			{
        +			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
        +			*pcrls = NULL;
        +			}
        +		BIO_printf(err,"unable to load %s\n",
        +				pcerts ? "certificates" : "CRLs");
        +		ERR_print_errors(err);
        +		}
        +	return rv;
        +	}
        +
        +STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *desc)
        +	{
        +	STACK_OF(X509) *certs;
        +	if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
        +		return NULL;
        +	return certs;
        +	}	
        +
        +STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *desc)
        +	{
        +	STACK_OF(X509_CRL) *crls;
        +	if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
        +		return NULL;
        +	return crls;
        +	}	
        +
        +#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
        +/* Return error for unknown extensions */
        +#define X509V3_EXT_DEFAULT		0
        +/* Print error for unknown extensions */
        +#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
        +/* ASN1 parse unknown extensions */
        +#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
        +/* BIO_dump unknown extensions */
        +#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
        +
        +#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
        +			 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
        +
        +int set_cert_ex(unsigned long *flags, const char *arg)
        +{
        +	static const NAME_EX_TBL cert_tbl[] = {
        +		{ "compatible", X509_FLAG_COMPAT, 0xffffffffl},
        +		{ "ca_default", X509_FLAG_CA, 0xffffffffl},
        +		{ "no_header", X509_FLAG_NO_HEADER, 0},
        +		{ "no_version", X509_FLAG_NO_VERSION, 0},
        +		{ "no_serial", X509_FLAG_NO_SERIAL, 0},
        +		{ "no_signame", X509_FLAG_NO_SIGNAME, 0},
        +		{ "no_validity", X509_FLAG_NO_VALIDITY, 0},
        +		{ "no_subject", X509_FLAG_NO_SUBJECT, 0},
        +		{ "no_issuer", X509_FLAG_NO_ISSUER, 0},
        +		{ "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
        +		{ "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
        +		{ "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
        +		{ "no_aux", X509_FLAG_NO_AUX, 0},
        +		{ "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
        +		{ "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
        +		{ "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
        +		{ "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
        +		{ "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
        +		{ NULL, 0, 0}
        +	};
        +	return set_multi_opts(flags, arg, cert_tbl);
        +}
        +
        +int set_name_ex(unsigned long *flags, const char *arg)
        +{
        +	static const NAME_EX_TBL ex_tbl[] = {
        +		{ "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
        +		{ "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
        +		{ "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
        +		{ "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
        +		{ "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
        +		{ "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
        +		{ "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
        +		{ "dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
        +		{ "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
        +		{ "dump_der", ASN1_STRFLGS_DUMP_DER, 0},
        +		{ "compat", XN_FLAG_COMPAT, 0xffffffffL},
        +		{ "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
        +		{ "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
        +		{ "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
        +		{ "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
        +		{ "dn_rev", XN_FLAG_DN_REV, 0},
        +		{ "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
        +		{ "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
        +		{ "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
        +		{ "align", XN_FLAG_FN_ALIGN, 0},
        +		{ "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
        +		{ "space_eq", XN_FLAG_SPC_EQ, 0},
        +		{ "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
        +		{ "RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
        +		{ "oneline", XN_FLAG_ONELINE, 0xffffffffL},
        +		{ "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
        +		{ "ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
        +		{ NULL, 0, 0}
        +	};
        +	return set_multi_opts(flags, arg, ex_tbl);
        +}
        +
        +int set_ext_copy(int *copy_type, const char *arg)
        +{
        +	if (!strcasecmp(arg, "none"))
        +		*copy_type = EXT_COPY_NONE;
        +	else if (!strcasecmp(arg, "copy"))
        +		*copy_type = EXT_COPY_ADD;
        +	else if (!strcasecmp(arg, "copyall"))
        +		*copy_type = EXT_COPY_ALL;
        +	else
        +		return 0;
        +	return 1;
        +}
        +
        +int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
        +{
        +	STACK_OF(X509_EXTENSION) *exts = NULL;
        +	X509_EXTENSION *ext, *tmpext;
        +	ASN1_OBJECT *obj;
        +	int i, idx, ret = 0;
        +	if (!x || !req || (copy_type == EXT_COPY_NONE))
        +		return 1;
        +	exts = X509_REQ_get_extensions(req);
        +
        +	for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
        +		ext = sk_X509_EXTENSION_value(exts, i);
        +		obj = X509_EXTENSION_get_object(ext);
        +		idx = X509_get_ext_by_OBJ(x, obj, -1);
        +		/* Does extension exist? */
        +		if (idx != -1) {
        +			/* If normal copy don't override existing extension */
        +			if (copy_type == EXT_COPY_ADD)
        +				continue;
        +			/* Delete all extensions of same type */
        +			do {
        +				tmpext = X509_get_ext(x, idx);
        +				X509_delete_ext(x, idx);
        +				X509_EXTENSION_free(tmpext);
        +				idx = X509_get_ext_by_OBJ(x, obj, -1);
        +			} while (idx != -1);
        +		}
        +		if (!X509_add_ext(x, ext, -1))
        +			goto end;
        +	}
        +
        +	ret = 1;
        +
        +	end:
        +
        +	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        +
        +	return ret;
        +}
        +		
        +		
        +			
        +
        +static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
        +{
        +	STACK_OF(CONF_VALUE) *vals;
        +	CONF_VALUE *val;
        +	int i, ret = 1;
        +	if(!arg) return 0;
        +	vals = X509V3_parse_list(arg);
        +	for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
        +		val = sk_CONF_VALUE_value(vals, i);
        +		if (!set_table_opts(flags, val->name, in_tbl))
        +			ret = 0;
        +	}
        +	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
        +	return ret;
        +}
        +
        +static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
        +{
        +	char c;
        +	const NAME_EX_TBL *ptbl;
        +	c = arg[0];
        +
        +	if(c == '-') {
        +		c = 0;
        +		arg++;
        +	} else if (c == '+') {
        +		c = 1;
        +		arg++;
        +	} else c = 1;
        +
        +	for(ptbl = in_tbl; ptbl->name; ptbl++) {
        +		if(!strcasecmp(arg, ptbl->name)) {
        +			*flags &= ~ptbl->mask;
        +			if(c) *flags |= ptbl->flag;
        +			else *flags &= ~ptbl->flag;
        +			return 1;
        +		}
        +	}
        +	return 0;
        +}
        +
        +void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
        +{
        +	char *buf;
        +	char mline = 0;
        +	int indent = 0;
        +
        +	if(title) BIO_puts(out, title);
        +	if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        +		mline = 1;
        +		indent = 4;
        +	}
        +	if(lflags == XN_FLAG_COMPAT) {
        +		buf = X509_NAME_oneline(nm, 0, 0);
        +		BIO_puts(out, buf);
        +		BIO_puts(out, "\n");
        +		OPENSSL_free(buf);
        +	} else {
        +		if(mline) BIO_puts(out, "\n");
        +		X509_NAME_print_ex(out, nm, indent, lflags);
        +		BIO_puts(out, "\n");
        +	}
        +}
        +
        +X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
        +{
        +	X509_STORE *store;
        +	X509_LOOKUP *lookup;
        +	if(!(store = X509_STORE_new())) goto end;
        +	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
        +	if (lookup == NULL) goto end;
        +	if (CAfile) {
        +		if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
        +			BIO_printf(bp, "Error loading file %s\n", CAfile);
        +			goto end;
        +		}
        +	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
        +		
        +	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
        +	if (lookup == NULL) goto end;
        +	if (CApath) {
        +		if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
        +			BIO_printf(bp, "Error loading directory %s\n", CApath);
        +			goto end;
        +		}
        +	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
        +
        +	ERR_clear_error();
        +	return store;
        +	end:
        +	X509_STORE_free(store);
        +	return NULL;
        +}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +/* Try to load an engine in a shareable library */
        +static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
        +	{
        +	ENGINE *e = ENGINE_by_id("dynamic");
        +	if (e)
        +		{
        +		if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
        +			|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
        +			{
        +			ENGINE_free(e);
        +			e = NULL;
        +			}
        +		}
        +	return e;
        +	}
        +
        +ENGINE *setup_engine(BIO *err, const char *engine, int debug)
        +        {
        +        ENGINE *e = NULL;
        +
        +        if (engine)
        +                {
        +		if(strcmp(engine, "auto") == 0)
        +			{
        +			BIO_printf(err,"enabling auto ENGINE support\n");
        +			ENGINE_register_all_complete();
        +			return NULL;
        +			}
        +		if((e = ENGINE_by_id(engine)) == NULL
        +			&& (e = try_load_engine(err, engine, debug)) == NULL)
        +			{
        +			BIO_printf(err,"invalid engine \"%s\"\n", engine);
        +			ERR_print_errors(err);
        +			return NULL;
        +			}
        +		if (debug)
        +			{
        +			ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
        +				0, err, 0);
        +			}
        +                ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
        +		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
        +			{
        +			BIO_printf(err,"can't use that engine\n");
        +			ERR_print_errors(err);
        +			ENGINE_free(e);
        +			return NULL;
        +			}
        +
        +		BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e));
        +
        +		/* Free our "structural" reference. */
        +		ENGINE_free(e);
        +		}
        +        return e;
        +        }
        +#endif
        +
        +int load_config(BIO *err, CONF *cnf)
        +	{
        +	static int load_config_called = 0;
        +	if (load_config_called)
        +		return 1;
        +	load_config_called = 1;
        +	if (!cnf)
        +		cnf = config;
        +	if (!cnf)
        +		return 1;
        +
        +	OPENSSL_load_builtin_modules();
        +
        +	if (CONF_modules_load(cnf, NULL, 0) <= 0)
        +		{
        +		BIO_printf(err, "Error configuring OpenSSL\n");
        +		ERR_print_errors(err);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +char *make_config_name()
        +	{
        +	const char *t=X509_get_default_cert_area();
        +	size_t len;
        +	char *p;
        +
        +	len=strlen(t)+strlen(OPENSSL_CONF)+2;
        +	p=OPENSSL_malloc(len);
        +	BUF_strlcpy(p,t,len);
        +#ifndef OPENSSL_SYS_VMS
        +	BUF_strlcat(p,"/",len);
        +#endif
        +	BUF_strlcat(p,OPENSSL_CONF,len);
        +
        +	return p;
        +	}
        +
        +static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
        +	{
        +	const char *n;
        +
        +	n=a[DB_serial];
        +	while (*n == '0') n++;
        +	return(lh_strhash(n));
        +	}
        +
        +static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
        +	{
        +	const char *aa,*bb;
        +
        +	for (aa=a[DB_serial]; *aa == '0'; aa++);
        +	for (bb=b[DB_serial]; *bb == '0'; bb++);
        +	return(strcmp(aa,bb));
        +	}
        +
        +static int index_name_qual(char **a)
        +	{ return(a[0][0] == 'V'); }
        +
        +static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
        +	{ return(lh_strhash(a[DB_name])); }
        +
        +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
        +	{ return(strcmp(a[DB_name], b[DB_name])); }
        +
        +static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
        +static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
        +static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
        +static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
        +
        +#undef BSIZE
        +#define BSIZE 256
        +
        +BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
        +	{
        +	BIO *in=NULL;
        +	BIGNUM *ret=NULL;
        +	MS_STATIC char buf[1024];
        +	ASN1_INTEGER *ai=NULL;
        +
        +	ai=ASN1_INTEGER_new();
        +	if (ai == NULL) goto err;
        +
        +	if ((in=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	if (BIO_read_filename(in,serialfile) <= 0)
        +		{
        +		if (!create)
        +			{
        +			perror(serialfile);
        +			goto err;
        +			}
        +		else
        +			{
        +			ret=BN_new();
        +			if (ret == NULL || !rand_serial(ret, ai))
        +				BIO_printf(bio_err, "Out of memory\n");
        +			}
        +		}
        +	else
        +		{
        +		if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
        +			{
        +			BIO_printf(bio_err,"unable to load number from %s\n",
        +				serialfile);
        +			goto err;
        +			}
        +		ret=ASN1_INTEGER_to_BN(ai,NULL);
        +		if (ret == NULL)
        +			{
        +			BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
        +			goto err;
        +			}
        +		}
        +
        +	if (ret && retai)
        +		{
        +		*retai = ai;
        +		ai = NULL;
        +		}
        + err:
        +	if (in != NULL) BIO_free(in);
        +	if (ai != NULL) ASN1_INTEGER_free(ai);
        +	return(ret);
        +	}
        +
        +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai)
        +	{
        +	char buf[1][BSIZE];
        +	BIO *out = NULL;
        +	int ret=0;
        +	ASN1_INTEGER *ai=NULL;
        +	int j;
        +
        +	if (suffix == NULL)
        +		j = strlen(serialfile);
        +	else
        +		j = strlen(serialfile) + strlen(suffix) + 1;
        +	if (j >= BSIZE)
        +		{
        +		BIO_printf(bio_err,"file name too long\n");
        +		goto err;
        +		}
        +
        +	if (suffix == NULL)
        +		BUF_strlcpy(buf[0], serialfile, BSIZE);
        +	else
        +		{
        +#ifndef OPENSSL_SYS_VMS
        +		j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
        +#else
        +		j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
        +#endif
        +		}
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
        +#endif
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +	if (BIO_write_filename(out,buf[0]) <= 0)
        +		{
        +		perror(serialfile);
        +		goto err;
        +		}
        +
        +	if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
        +		{
        +		BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
        +		goto err;
        +		}
        +	i2a_ASN1_INTEGER(out,ai);
        +	BIO_puts(out,"\n");
        +	ret=1;
        +	if (retai)
        +		{
        +		*retai = ai;
        +		ai = NULL;
        +		}
        +err:
        +	if (out != NULL) BIO_free_all(out);
        +	if (ai != NULL) ASN1_INTEGER_free(ai);
        +	return(ret);
        +	}
        +
        +int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
        +	{
        +	char buf[5][BSIZE];
        +	int i,j;
        +
        +	i = strlen(serialfile) + strlen(old_suffix);
        +	j = strlen(serialfile) + strlen(new_suffix);
        +	if (i > j) j = i;
        +	if (j + 1 >= BSIZE)
        +		{
        +		BIO_printf(bio_err,"file name too long\n");
        +		goto err;
        +		}
        +
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
        +		serialfile, new_suffix);
        +#else
        +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
        +		serialfile, new_suffix);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
        +		serialfile, old_suffix);
        +#else
        +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
        +		serialfile, old_suffix);
        +#endif
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
        +		serialfile, buf[1]);
        +#endif
        +	if (rename(serialfile,buf[1]) < 0 && errno != ENOENT
        +#ifdef ENOTDIR
        +			&& errno != ENOTDIR
        +#endif
        +	   )		{
        +			BIO_printf(bio_err,
        +				"unable to rename %s to %s\n",
        +				serialfile, buf[1]);
        +			perror("reason");
        +			goto err;
        +			}
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
        +		buf[0],serialfile);
        +#endif
        +	if (rename(buf[0],serialfile) < 0)
        +		{
        +		BIO_printf(bio_err,
        +			"unable to rename %s to %s\n",
        +			buf[0],serialfile);
        +		perror("reason");
        +		rename(buf[1],serialfile);
        +		goto err;
        +		}
        +	return 1;
        + err:
        +	return 0;
        +	}
        +
        +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
        +	{
        +	BIGNUM *btmp;
        +	int ret = 0;
        +	if (b)
        +		btmp = b;
        +	else
        +		btmp = BN_new();
        +
        +	if (!btmp)
        +		return 0;
        +
        +	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
        +		goto error;
        +	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
        +		goto error;
        +
        +	ret = 1;
        +	
        +	error:
        +
        +	if (!b)
        +		BN_free(btmp);
        +	
        +	return ret;
        +	}
        +
        +CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
        +	{
        +	CA_DB *retdb = NULL;
        +	TXT_DB *tmpdb = NULL;
        +	BIO *in = BIO_new(BIO_s_file());
        +	CONF *dbattr_conf = NULL;
        +	char buf[1][BSIZE];
        +	long errorline= -1;
        +
        +	if (in == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +	if (BIO_read_filename(in,dbfile) <= 0)
        +		{
        +		perror(dbfile);
        +		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
        +		goto err;
        +		}
        +	if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
        +		goto err;
        +
        +#ifndef OPENSSL_SYS_VMS
        +	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
        +#else
        +	BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
        +#endif
        +	dbattr_conf = NCONF_new(NULL);
        +	if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
        +		{
        +		if (errorline > 0)
        +			{
        +			BIO_printf(bio_err,
        +				"error on line %ld of db attribute file '%s'\n"
        +				,errorline,buf[0]);
        +			goto err;
        +			}
        +		else
        +			{
        +			NCONF_free(dbattr_conf);
        +			dbattr_conf = NULL;
        +			}
        +		}
        +
        +	if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
        +		{
        +		fprintf(stderr, "Out of memory\n");
        +		goto err;
        +		}
        +
        +	retdb->db = tmpdb;
        +	tmpdb = NULL;
        +	if (db_attr)
        +		retdb->attributes = *db_attr;
        +	else
        +		{
        +		retdb->attributes.unique_subject = 1;
        +		}
        +
        +	if (dbattr_conf)
        +		{
        +		char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
        +		if (p)
        +			{
        +#ifdef RL_DEBUG
        +			BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
        +#endif
        +			retdb->attributes.unique_subject = parse_yesno(p,1);
        +			}
        +		}
        +
        + err:
        +	if (dbattr_conf) NCONF_free(dbattr_conf);
        +	if (tmpdb) TXT_DB_free(tmpdb);
        +	if (in) BIO_free_all(in);
        +	return retdb;
        +	}
        +
        +int index_index(CA_DB *db)
        +	{
        +	if (!TXT_DB_create_index(db->db, DB_serial, NULL,
        +				LHASH_HASH_FN(index_serial),
        +				LHASH_COMP_FN(index_serial)))
        +		{
        +		BIO_printf(bio_err,
        +		  "error creating serial number index:(%ld,%ld,%ld)\n",
        +		  			db->db->error,db->db->arg1,db->db->arg2);
        +			return 0;
        +		}
        +
        +	if (db->attributes.unique_subject
        +		&& !TXT_DB_create_index(db->db, DB_name, index_name_qual,
        +			LHASH_HASH_FN(index_name),
        +			LHASH_COMP_FN(index_name)))
        +		{
        +		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
        +			db->db->error,db->db->arg1,db->db->arg2);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int save_index(const char *dbfile, const char *suffix, CA_DB *db)
        +	{
        +	char buf[3][BSIZE];
        +	BIO *out = BIO_new(BIO_s_file());
        +	int j;
        +
        +	if (out == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	j = strlen(dbfile) + strlen(suffix);
        +	if (j + 6 >= BSIZE)
        +		{
        +		BIO_printf(bio_err,"file name too long\n");
        +		goto err;
        +		}
        +
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
        +#else
        +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
        +#else
        +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
        +#else
        +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
        +#endif
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
        +#endif
        +	if (BIO_write_filename(out,buf[0]) <= 0)
        +		{
        +		perror(dbfile);
        +		BIO_printf(bio_err,"unable to open '%s'\n", dbfile);
        +		goto err;
        +		}
        +	j=TXT_DB_write(out,db->db);
        +	if (j <= 0) goto err;
        +			
        +	BIO_free(out);
        +
        +	out = BIO_new(BIO_s_file());
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
        +#endif
        +	if (BIO_write_filename(out,buf[1]) <= 0)
        +		{
        +		perror(buf[2]);
        +		BIO_printf(bio_err,"unable to open '%s'\n", buf[2]);
        +		goto err;
        +		}
        +	BIO_printf(out,"unique_subject = %s\n",
        +		db->attributes.unique_subject ? "yes" : "no");
        +	BIO_free(out);
        +
        +	return 1;
        + err:
        +	return 0;
        +	}
        +
        +int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
        +	{
        +	char buf[5][BSIZE];
        +	int i,j;
        +
        +	i = strlen(dbfile) + strlen(old_suffix);
        +	j = strlen(dbfile) + strlen(new_suffix);
        +	if (i > j) j = i;
        +	if (j + 6 >= BSIZE)
        +		{
        +		BIO_printf(bio_err,"file name too long\n");
        +		goto err;
        +		}
        +
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
        +#else
        +	j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s",
        +		dbfile, new_suffix);
        +#else
        +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s",
        +		dbfile, new_suffix);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
        +		dbfile, new_suffix);
        +#else
        +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
        +		dbfile, new_suffix);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
        +		dbfile, old_suffix);
        +#else
        +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
        +		dbfile, old_suffix);
        +#endif
        +#ifndef OPENSSL_SYS_VMS
        +	j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s",
        +		dbfile, old_suffix);
        +#else
        +	j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
        +		dbfile, old_suffix);
        +#endif
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
        +		dbfile, buf[1]);
        +#endif
        +	if (rename(dbfile,buf[1]) < 0 && errno != ENOENT
        +#ifdef ENOTDIR
        +		&& errno != ENOTDIR
        +#endif
        +	   )		{
        +			BIO_printf(bio_err,
        +				"unable to rename %s to %s\n",
        +				dbfile, buf[1]);
        +			perror("reason");
        +			goto err;
        +			}
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
        +		buf[0],dbfile);
        +#endif
        +	if (rename(buf[0],dbfile) < 0)
        +		{
        +		BIO_printf(bio_err,
        +			"unable to rename %s to %s\n",
        +			buf[0],dbfile);
        +		perror("reason");
        +		rename(buf[1],dbfile);
        +		goto err;
        +		}
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
        +		buf[4],buf[3]);
        +#endif
        +	if (rename(buf[4],buf[3]) < 0 && errno != ENOENT
        +#ifdef ENOTDIR
        +		&& errno != ENOTDIR
        +#endif
        +	   )		{
        +			BIO_printf(bio_err,
        +				"unable to rename %s to %s\n",
        +				buf[4], buf[3]);
        +			perror("reason");
        +			rename(dbfile,buf[0]);
        +			rename(buf[1],dbfile);
        +			goto err;
        +			}
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
        +		buf[2],buf[4]);
        +#endif
        +	if (rename(buf[2],buf[4]) < 0)
        +		{
        +		BIO_printf(bio_err,
        +			"unable to rename %s to %s\n",
        +			buf[2],buf[4]);
        +		perror("reason");
        +		rename(buf[3],buf[4]);
        +		rename(dbfile,buf[0]);
        +		rename(buf[1],dbfile);
        +		goto err;
        +		}
        +	return 1;
        + err:
        +	return 0;
        +	}
        +
        +void free_index(CA_DB *db)
        +	{
        +	if (db)
        +		{
        +		if (db->db) TXT_DB_free(db->db);
        +		OPENSSL_free(db);
        +		}
        +	}
        +
        +int parse_yesno(const char *str, int def)
        +	{
        +	int ret = def;
        +	if (str)
        +		{
        +		switch (*str)
        +			{
        +		case 'f': /* false */
        +		case 'F': /* FALSE */
        +		case 'n': /* no */
        +		case 'N': /* NO */
        +		case '0': /* 0 */
        +			ret = 0;
        +			break;
        +		case 't': /* true */
        +		case 'T': /* TRUE */
        +		case 'y': /* yes */
        +		case 'Y': /* YES */
        +		case '1': /* 1 */
        +			ret = 1;
        +			break;
        +		default:
        +			ret = def;
        +			break;
        +			}
        +		}
        +	return ret;
        +	}
        +
        +/*
        + * subject is expected to be in the format /type0=value0/type1=value1/type2=...
        + * where characters may be escaped by \
        + */
        +X509_NAME *parse_name(char *subject, long chtype, int multirdn)
        +	{
        +	size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
        +	char *buf = OPENSSL_malloc(buflen);
        +	size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
        +	char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
        +	char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
        +	int *mval = OPENSSL_malloc (max_ne * sizeof (int));
        +
        +	char *sp = subject, *bp = buf;
        +	int i, ne_num = 0;
        +
        +	X509_NAME *n = NULL;
        +	int nid;
        +
        +	if (!buf || !ne_types || !ne_values || !mval)
        +		{
        +		BIO_printf(bio_err, "malloc error\n");
        +		goto error;
        +		}	
        +
        +	if (*subject != '/')
        +		{
        +		BIO_printf(bio_err, "Subject does not start with '/'.\n");
        +		goto error;
        +		}
        +	sp++; /* skip leading / */
        +
        +	/* no multivalued RDN by default */
        +	mval[ne_num] = 0;
        +
        +	while (*sp)
        +		{
        +		/* collect type */
        +		ne_types[ne_num] = bp;
        +		while (*sp)
        +			{
        +			if (*sp == '\\') /* is there anything to escape in the type...? */
        +				{
        +				if (*++sp)
        +					*bp++ = *sp++;
        +				else	
        +					{
        +					BIO_printf(bio_err, "escape character at end of string\n");
        +					goto error;
        +					}
        +				}	
        +			else if (*sp == '=')
        +				{
        +				sp++;
        +				*bp++ = '\0';
        +				break;
        +				}
        +			else
        +				*bp++ = *sp++;
        +			}
        +		if (!*sp)
        +			{
        +			BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
        +			goto error;
        +			}
        +		ne_values[ne_num] = bp;
        +		while (*sp)
        +			{
        +			if (*sp == '\\')
        +				{
        +				if (*++sp)
        +					*bp++ = *sp++;
        +				else
        +					{
        +					BIO_printf(bio_err, "escape character at end of string\n");
        +					goto error;
        +					}
        +				}
        +			else if (*sp == '/')
        +				{
        +				sp++;
        +				/* no multivalued RDN by default */
        +				mval[ne_num+1] = 0;
        +				break;
        +				}
        +			else if (*sp == '+' && multirdn)
        +				{
        +				/* a not escaped + signals a mutlivalued RDN */
        +				sp++;
        +				mval[ne_num+1] = -1;
        +				break;
        +				}
        +			else
        +				*bp++ = *sp++;
        +			}
        +		*bp++ = '\0';
        +		ne_num++;
        +		}	
        +
        +	if (!(n = X509_NAME_new()))
        +		goto error;
        +
        +	for (i = 0; i < ne_num; i++)
        +		{
        +		if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
        +			{
        +			BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
        +			continue;
        +			}
        +
        +		if (!*ne_values[i])
        +			{
        +			BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
        +			continue;
        +			}
        +
        +		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))
        +			goto error;
        +		}
        +
        +	OPENSSL_free(ne_values);
        +	OPENSSL_free(ne_types);
        +	OPENSSL_free(buf);
        +	OPENSSL_free(mval);
        +	return n;
        +
        +error:
        +	X509_NAME_free(n);
        +	if (ne_values)
        +		OPENSSL_free(ne_values);
        +	if (ne_types)
        +		OPENSSL_free(ne_types);
        +	if (mval)
        +		OPENSSL_free(mval);
        +	if (buf)
        +		OPENSSL_free(buf);
        +	return NULL;
        +}
        +
        +int args_verify(char ***pargs, int *pargc,
        +			int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
        +	{
        +	ASN1_OBJECT *otmp = NULL;
        +	unsigned long flags = 0;
        +	int i;
        +	int purpose = 0, depth = -1;
        +	char **oldargs = *pargs;
        +	char *arg = **pargs, *argn = (*pargs)[1];
        +	time_t at_time = 0;
        +	if (!strcmp(arg, "-policy"))
        +		{
        +		if (!argn)
        +			*badarg = 1;
        +		else
        +			{
        +			otmp = OBJ_txt2obj(argn, 0);
        +			if (!otmp)
        +				{
        +				BIO_printf(err, "Invalid Policy \"%s\"\n",
        +									argn);
        +				*badarg = 1;
        +				}
        +			}
        +		(*pargs)++;
        +		}
        +	else if (strcmp(arg,"-purpose") == 0)
        +		{
        +		X509_PURPOSE *xptmp;
        +		if (!argn)
        +			*badarg = 1;
        +		else
        +			{
        +			i = X509_PURPOSE_get_by_sname(argn);
        +			if(i < 0)
        +				{
        +				BIO_printf(err, "unrecognized purpose\n");
        +				*badarg = 1;
        +				}
        +			else
        +				{
        +				xptmp = X509_PURPOSE_get0(i);
        +				purpose = X509_PURPOSE_get_id(xptmp);
        +				}
        +			}
        +		(*pargs)++;
        +		}
        +	else if (strcmp(arg,"-verify_depth") == 0)
        +		{
        +		if (!argn)
        +			*badarg = 1;
        +		else
        +			{
        +			depth = atoi(argn);
        +			if(depth < 0)
        +				{
        +				BIO_printf(err, "invalid depth\n");
        +				*badarg = 1;
        +				}
        +			}
        +		(*pargs)++;
        +		}
        +	else if (strcmp(arg,"-attime") == 0)
        +		{
        +		if (!argn)
        +			*badarg = 1;
        +		else
        +			{
        +			long timestamp;
        +			/* interpret the -attime argument as seconds since
        +			 * Epoch */
        +			if (sscanf(argn, "%li", &timestamp) != 1)
        +				{
        +				BIO_printf(bio_err,
        +						"Error parsing timestamp %s\n",
        +					   	argn);
        +				*badarg = 1;
        +				}
        +			/* on some platforms time_t may be a float */
        +			at_time = (time_t) timestamp;
        +			}
        +		(*pargs)++;
        +		}
        +	else if (!strcmp(arg, "-ignore_critical"))
        +		flags |= X509_V_FLAG_IGNORE_CRITICAL;
        +	else if (!strcmp(arg, "-issuer_checks"))
        +		flags |= X509_V_FLAG_CB_ISSUER_CHECK;
        +	else if (!strcmp(arg, "-crl_check"))
        +		flags |=  X509_V_FLAG_CRL_CHECK;
        +	else if (!strcmp(arg, "-crl_check_all"))
        +		flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
        +	else if (!strcmp(arg, "-policy_check"))
        +		flags |= X509_V_FLAG_POLICY_CHECK;
        +	else if (!strcmp(arg, "-explicit_policy"))
        +		flags |= X509_V_FLAG_EXPLICIT_POLICY;
        +	else if (!strcmp(arg, "-inhibit_any"))
        +		flags |= X509_V_FLAG_INHIBIT_ANY;
        +	else if (!strcmp(arg, "-inhibit_map"))
        +		flags |= X509_V_FLAG_INHIBIT_MAP;
        +	else if (!strcmp(arg, "-x509_strict"))
        +		flags |= X509_V_FLAG_X509_STRICT;
        +	else if (!strcmp(arg, "-extended_crl"))
        +		flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
        +	else if (!strcmp(arg, "-use_deltas"))
        +		flags |= X509_V_FLAG_USE_DELTAS;
        +	else if (!strcmp(arg, "-policy_print"))
        +		flags |= X509_V_FLAG_NOTIFY_POLICY;
        +	else if (!strcmp(arg, "-check_ss_sig"))
        +		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
        +	else
        +		return 0;
        +
        +	if (*badarg)
        +		{
        +		if (*pm)
        +			X509_VERIFY_PARAM_free(*pm);
        +		*pm = NULL;
        +		goto end;
        +		}
        +
        +	if (!*pm && !(*pm = X509_VERIFY_PARAM_new()))
        +		{
        +		*badarg = 1;
        +		goto end;
        +		}
        +
        +	if (otmp)
        +		X509_VERIFY_PARAM_add0_policy(*pm, otmp);
        +	if (flags)
        +		X509_VERIFY_PARAM_set_flags(*pm, flags);
        +
        +	if (purpose)
        +		X509_VERIFY_PARAM_set_purpose(*pm, purpose);
        +
        +	if (depth >= 0)
        +		X509_VERIFY_PARAM_set_depth(*pm, depth);
        +
        +	if (at_time) 
        +		X509_VERIFY_PARAM_set_time(*pm, at_time);
        +
        +	end:
        +
        +	(*pargs)++;
        +
        +	if (pargc)
        +		*pargc -= *pargs - oldargs;
        +
        +	return 1;
        +
        +	}
        +
        +/* Read whole contents of a BIO into an allocated memory buffer and
        + * return it.
        + */
        +
        +int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
        +	{
        +	BIO *mem;
        +	int len, ret;
        +	unsigned char tbuf[1024];
        +	mem = BIO_new(BIO_s_mem());
        +	if (!mem)
        +		return -1;
        +	for(;;)
        +		{
        +		if ((maxlen != -1) && maxlen < 1024)
        +			len = maxlen;
        +		else
        +			len = 1024;
        +		len = BIO_read(in, tbuf, len);
        +		if (len <= 0)
        +			break;
        +		if (BIO_write(mem, tbuf, len) != len)
        +			{
        +			BIO_free(mem);
        +			return -1;
        +			}
        +		maxlen -= len;
        +
        +		if (maxlen == 0)
        +			break;
        +		}
        +	ret = BIO_get_mem_data(mem, (char **)out);
        +	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
        +	BIO_free(mem);
        +	return ret;
        +	}
        +
        +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
        +	{
        +	int rv;
        +	char *stmp, *vtmp = NULL;
        +	stmp = BUF_strdup(value);
        +	if (!stmp)
        +		return -1;
        +	vtmp = strchr(stmp, ':');
        +	if (vtmp)
        +		{
        +		*vtmp = 0;
        +		vtmp++;
        +		}
        +	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
        +	OPENSSL_free(stmp);
        +	return rv;
        +	}
        +
        +static void nodes_print(BIO *out, const char *name,
        +	STACK_OF(X509_POLICY_NODE) *nodes)
        +	{
        +	X509_POLICY_NODE *node;
        +	int i;
        +	BIO_printf(out, "%s Policies:", name);
        +	if (nodes)
        +		{
        +		BIO_puts(out, "\n");
        +		for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++)
        +			{
        +			node = sk_X509_POLICY_NODE_value(nodes, i);
        +			X509_POLICY_NODE_print(out, node, 2);
        +			}
        +		}
        +	else
        +		BIO_puts(out, " <empty>\n");
        +	}
        +
        +void policies_print(BIO *out, X509_STORE_CTX *ctx)
        +	{
        +	X509_POLICY_TREE *tree;
        +	int explicit_policy;
        +	int free_out = 0;
        +	if (out == NULL)
        +		{
        +		out = BIO_new_fp(stderr, BIO_NOCLOSE);
        +		free_out = 1;
        +		}
        +	tree = X509_STORE_CTX_get0_policy_tree(ctx);
        +	explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
        +
        +	BIO_printf(out, "Require explicit Policy: %s\n",
        +				explicit_policy ? "True" : "False");
        +
        +	nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
        +	nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
        +	if (free_out)
        +		BIO_free(out);
        +	}
        +
        +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
        +
        +static JPAKE_CTX *jpake_init(const char *us, const char *them,
        +							 const char *secret)
        +	{
        +	BIGNUM *p = NULL;
        +	BIGNUM *g = NULL;
        +	BIGNUM *q = NULL;
        +	BIGNUM *bnsecret = BN_new();
        +	JPAKE_CTX *ctx;
        +
        +	/* Use a safe prime for p (that we found earlier) */
        +	BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
        +	g = BN_new();
        +	BN_set_word(g, 2);
        +	q = BN_new();
        +	BN_rshift1(q, p);
        +
        +	BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
        +
        +	ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
        +	BN_free(bnsecret);
        +	BN_free(q);
        +	BN_free(g);
        +	BN_free(p);
        +
        +	return ctx;
        +	}
        +
        +static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
        +	{
        +	BN_print(conn, p->gx);
        +	BIO_puts(conn, "\n");
        +	BN_print(conn, p->zkpx.gr);
        +	BIO_puts(conn, "\n");
        +	BN_print(conn, p->zkpx.b);
        +	BIO_puts(conn, "\n");
        +	}
        +
        +static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
        +	{
        +	JPAKE_STEP1 s1;
        +
        +	JPAKE_STEP1_init(&s1);
        +	JPAKE_STEP1_generate(&s1, ctx);
        +	jpake_send_part(bconn, &s1.p1);
        +	jpake_send_part(bconn, &s1.p2);
        +	(void)BIO_flush(bconn);
        +	JPAKE_STEP1_release(&s1);
        +	}
        +
        +static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
        +	{
        +	JPAKE_STEP2 s2;
        +
        +	JPAKE_STEP2_init(&s2);
        +	JPAKE_STEP2_generate(&s2, ctx);
        +	jpake_send_part(bconn, &s2);
        +	(void)BIO_flush(bconn);
        +	JPAKE_STEP2_release(&s2);
        +	}
        +
        +static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
        +	{
        +	JPAKE_STEP3A s3a;
        +
        +	JPAKE_STEP3A_init(&s3a);
        +	JPAKE_STEP3A_generate(&s3a, ctx);
        +	BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
        +	(void)BIO_flush(bconn);
        +	JPAKE_STEP3A_release(&s3a);
        +	}
        +
        +static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
        +	{
        +	JPAKE_STEP3B s3b;
        +
        +	JPAKE_STEP3B_init(&s3b);
        +	JPAKE_STEP3B_generate(&s3b, ctx);
        +	BIO_write(bconn, s3b.hk, sizeof s3b.hk);
        +	(void)BIO_flush(bconn);
        +	JPAKE_STEP3B_release(&s3b);
        +	}
        +
        +static void readbn(BIGNUM **bn, BIO *bconn)
        +	{
        +	char buf[10240];
        +	int l;
        +
        +	l = BIO_gets(bconn, buf, sizeof buf);
        +	assert(l > 0);
        +	assert(buf[l-1] == '\n');
        +	buf[l-1] = '\0';
        +	BN_hex2bn(bn, buf);
        +	}
        +
        +static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
        +	{
        +	readbn(&p->gx, bconn);
        +	readbn(&p->zkpx.gr, bconn);
        +	readbn(&p->zkpx.b, bconn);
        +	}
        +
        +static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
        +	{
        +	JPAKE_STEP1 s1;
        +
        +	JPAKE_STEP1_init(&s1);
        +	jpake_receive_part(&s1.p1, bconn);
        +	jpake_receive_part(&s1.p2, bconn);
        +	if(!JPAKE_STEP1_process(ctx, &s1))
        +		{
        +		ERR_print_errors(bio_err);
        +		exit(1);
        +		}
        +	JPAKE_STEP1_release(&s1);
        +	}
        +
        +static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
        +	{
        +	JPAKE_STEP2 s2;
        +
        +	JPAKE_STEP2_init(&s2);
        +	jpake_receive_part(&s2, bconn);
        +	if(!JPAKE_STEP2_process(ctx, &s2))
        +		{
        +		ERR_print_errors(bio_err);
        +		exit(1);
        +		}
        +	JPAKE_STEP2_release(&s2);
        +	}
        +
        +static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
        +	{
        +	JPAKE_STEP3A s3a;
        +	int l;
        +
        +	JPAKE_STEP3A_init(&s3a);
        +	l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
        +	assert(l == sizeof s3a.hhk);
        +	if(!JPAKE_STEP3A_process(ctx, &s3a))
        +		{
        +		ERR_print_errors(bio_err);
        +		exit(1);
        +		}
        +	JPAKE_STEP3A_release(&s3a);
        +	}
        +
        +static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
        +	{
        +	JPAKE_STEP3B s3b;
        +	int l;
        +
        +	JPAKE_STEP3B_init(&s3b);
        +	l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
        +	assert(l == sizeof s3b.hk);
        +	if(!JPAKE_STEP3B_process(ctx, &s3b))
        +		{
        +		ERR_print_errors(bio_err);
        +		exit(1);
        +		}
        +	JPAKE_STEP3B_release(&s3b);
        +	}
        +
        +void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
        +	{
        +	JPAKE_CTX *ctx;
        +	BIO *bconn;
        +
        +	BIO_puts(out, "Authenticating with JPAKE\n");
        +
        +	ctx = jpake_init("client", "server", secret);
        +
        +	bconn = BIO_new(BIO_f_buffer());
        +	BIO_push(bconn, conn);
        +
        +	jpake_send_step1(bconn, ctx);
        +	jpake_receive_step1(ctx, bconn);
        +	jpake_send_step2(bconn, ctx);
        +	jpake_receive_step2(ctx, bconn);
        +	jpake_send_step3a(bconn, ctx);
        +	jpake_receive_step3b(ctx, bconn);
        +
        +	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
        +
        +	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
        +
        +	BIO_pop(bconn);
        +	BIO_free(bconn);
        +
        +	JPAKE_CTX_free(ctx);
        +	}
        +
        +void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
        +	{
        +	JPAKE_CTX *ctx;
        +	BIO *bconn;
        +
        +	BIO_puts(out, "Authenticating with JPAKE\n");
        +
        +	ctx = jpake_init("server", "client", secret);
        +
        +	bconn = BIO_new(BIO_f_buffer());
        +	BIO_push(bconn, conn);
        +
        +	jpake_receive_step1(ctx, bconn);
        +	jpake_send_step1(bconn, ctx);
        +	jpake_receive_step2(ctx, bconn);
        +	jpake_send_step2(bconn, ctx);
        +	jpake_receive_step3a(ctx, bconn);
        +	jpake_send_step3b(bconn, ctx);
        +
        +	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
        +
        +	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
        +
        +	BIO_pop(bconn);
        +	BIO_free(bconn);
        +
        +	JPAKE_CTX_free(ctx);
        +	}
        +
        +#endif
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +/* next_protos_parse parses a comma separated list of strings into a string
        + * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
        + *   outlen: (output) set to the length of the resulting buffer on success.
        + *   err: (maybe NULL) on failure, an error message line is written to this BIO.
        + *   in: a NUL termianted string like "abc,def,ghi"
        + *
        + *   returns: a malloced buffer or NULL on failure.
        + */
        +unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
        +	{
        +	size_t len;
        +	unsigned char *out;
        +	size_t i, start = 0;
        +
        +	len = strlen(in);
        +	if (len >= 65535)
        +		return NULL;
        +
        +	out = OPENSSL_malloc(strlen(in) + 1);
        +	if (!out)
        +		return NULL;
        +
        +	for (i = 0; i <= len; ++i)
        +		{
        +		if (i == len || in[i] == ',')
        +			{
        +			if (i - start > 255)
        +				{
        +				OPENSSL_free(out);
        +				return NULL;
        +				}
        +			out[start] = i - start;
        +			start = i + 1;
        +			}
        +		else
        +			out[i+1] = in[i];
        +		}
        +
        +	*outlen = len + 1;
        +	return out;
        +	}
        +#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
        +
        +/*
        + * Platform-specific sections
        + */
        +#if defined(_WIN32)
        +# ifdef fileno
        +#  undef fileno
        +#  define fileno(a) (int)_fileno(a)
        +# endif
        +
        +# include <windows.h>
        +# include <tchar.h>
        +
        +static int WIN32_rename(const char *from, const char *to)
        +	{
        +	TCHAR  *tfrom=NULL,*tto;
        +	DWORD	err;
        +	int	ret=0;
        +
        +	if (sizeof(TCHAR) == 1)
        +		{
        +		tfrom = (TCHAR *)from;
        +		tto   = (TCHAR *)to;
        +		}
        +	else	/* UNICODE path */
        +		{
        +		size_t i,flen=strlen(from)+1,tlen=strlen(to)+1;
        +		tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen));
        +		if (tfrom==NULL) goto err;
        +		tto=tfrom+flen;
        +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
        +		if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen))
        +#endif
        +			for (i=0;i<flen;i++)	tfrom[i]=(TCHAR)from[i];
        +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
        +		if (!MultiByteToWideChar(CP_ACP,0,to,  tlen,(WCHAR *)tto,  tlen))
        +#endif
        +			for (i=0;i<tlen;i++)	tto[i]  =(TCHAR)to[i];
        +		}
        +
        +	if (MoveFile(tfrom,tto))	goto ok;
        +	err=GetLastError();
        +	if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS)
        +		{
        +		if (DeleteFile(tto) && MoveFile(tfrom,tto))
        +			goto ok;
        +		err=GetLastError();
        +		}
        +	if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND)
        +		errno = ENOENT;
        +	else if (err==ERROR_ACCESS_DENIED)
        +		errno = EACCES;
        +	else
        +		errno = EINVAL;	/* we could map more codes... */
        +err:
        +	ret=-1;
        +ok:
        +	if (tfrom!=NULL && tfrom!=(TCHAR *)from)	free(tfrom);
        +	return ret;
        +	}
        +#endif
        +
        +/* app_tminterval section */
        +#if defined(_WIN32)
        +double app_tminterval(int stop,int usertime)
        +	{
        +	FILETIME		now;
        +	double			ret=0;
        +	static ULARGE_INTEGER	tmstart;
        +	static int		warning=1;
        +#ifdef _WIN32_WINNT
        +	static HANDLE		proc=NULL;
        +
        +	if (proc==NULL)
        +		{
        +		if (GetVersion() < 0x80000000)
        +			proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,
        +						GetCurrentProcessId());
        +		if (proc==NULL) proc = (HANDLE)-1;
        +		}
        +
        +	if (usertime && proc!=(HANDLE)-1)
        +		{
        +		FILETIME junk;
        +		GetProcessTimes(proc,&junk,&junk,&junk,&now);
        +		}
        +	else
        +#endif
        +		{
        +		SYSTEMTIME systime;
        +
        +		if (usertime && warning)
        +			{
        +			BIO_printf(bio_err,"To get meaningful results, run "
        +					   "this program on idle system.\n");
        +			warning=0;
        +			}
        +		GetSystemTime(&systime);
        +		SystemTimeToFileTime(&systime,&now);
        +		}
        +
        +	if (stop==TM_START)
        +		{
        +		tmstart.u.LowPart  = now.dwLowDateTime;
        +		tmstart.u.HighPart = now.dwHighDateTime;
        +		}
        +	else	{
        +		ULARGE_INTEGER tmstop;
        +
        +		tmstop.u.LowPart   = now.dwLowDateTime;
        +		tmstop.u.HighPart  = now.dwHighDateTime;
        +
        +		ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7;
        +		}
        +
        +	return (ret);
        +	}
        +
        +#elif defined(OPENSSL_SYS_NETWARE)
        +#include <time.h>
        +
        +double app_tminterval(int stop,int usertime)
        +	{
        +	double		ret=0;
        +	static clock_t	tmstart;
        +	static int	warning=1;
        +
        +	if (usertime && warning)
        +		{
        +		BIO_printf(bio_err,"To get meaningful results, run "
        +				   "this program on idle system.\n");
        +		warning=0;
        +		}
        +
        +	if (stop==TM_START)	tmstart = clock();
        +	else			ret     = (clock()-tmstart)/(double)CLOCKS_PER_SEC;
        +
        +	return (ret);
        +	}
        +
        +#elif defined(OPENSSL_SYSTEM_VXWORKS)
        +#include <time.h>
        +
        +double app_tminterval(int stop,int usertime)
        +	{
        +	double ret=0;
        +#ifdef CLOCK_REALTIME
        +	static struct timespec	tmstart;
        +	struct timespec		now;
        +#else
        +	static unsigned long	tmstart;
        +	unsigned long		now;
        +#endif
        +	static int warning=1;
        +
        +	if (usertime && warning)
        +		{
        +		BIO_printf(bio_err,"To get meaningful results, run "
        +				   "this program on idle system.\n");
        +		warning=0;
        +		}
        +
        +#ifdef CLOCK_REALTIME
        +	clock_gettime(CLOCK_REALTIME,&now);
        +	if (stop==TM_START)	tmstart = now;
        +	else	ret = ( (now.tv_sec+now.tv_nsec*1e-9)
        +			- (tmstart.tv_sec+tmstart.tv_nsec*1e-9) );
        +#else
        +	now = tickGet();
        +	if (stop==TM_START)	tmstart = now;
        +	else			ret = (now - tmstart)/(double)sysClkRateGet();
        +#endif
        +	return (ret);
        +	}
        +
        +#elif defined(OPENSSL_SYSTEM_VMS)
        +#include <time.h>
        +#include <times.h>
        +
        +double app_tminterval(int stop,int usertime)
        +	{
        +	static clock_t	tmstart;
        +	double		ret = 0;
        +	clock_t		now;
        +#ifdef __TMS
        +	struct tms	rus;
        +
        +	now = times(&rus);
        +	if (usertime)	now = rus.tms_utime;
        +#else
        +	if (usertime)
        +		now = clock(); /* sum of user and kernel times */
        +	else	{
        +		struct timeval tv;
        +		gettimeofday(&tv,NULL);
        +		now = (clock_t)(
        +			(unsigned long long)tv.tv_sec*CLK_TCK +
        +			(unsigned long long)tv.tv_usec*(1000000/CLK_TCK)
        +			);
        +		}
        +#endif
        +	if (stop==TM_START)	tmstart = now;
        +	else			ret = (now - tmstart)/(double)(CLK_TCK);
        +
        +	return (ret);
        +	}
        +
        +#elif defined(_SC_CLK_TCK)	/* by means of unistd.h */
        +#include <sys/times.h>
        +
        +double app_tminterval(int stop,int usertime)
        +	{
        +	double		ret = 0;
        +	struct tms	rus;
        +	clock_t		now = times(&rus);
        +	static clock_t	tmstart;
        +
        +	if (usertime)		now = rus.tms_utime;
        +
        +	if (stop==TM_START)	tmstart = now;
        +	else
        +		{
        +		long int tck = sysconf(_SC_CLK_TCK);
        +		ret = (now - tmstart)/(double)tck;
        +		}
        +
        +	return (ret);
        +	}
        +
        +#else
        +#include <sys/time.h>
        +#include <sys/resource.h>
        +
        +double app_tminterval(int stop,int usertime)
        +	{
        +	double		ret = 0;
        +	struct rusage	rus;
        +	struct timeval	now;
        +	static struct timeval tmstart;
        +
        +	if (usertime)		getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime;
        +	else			gettimeofday(&now,NULL);
        +
        +	if (stop==TM_START)	tmstart = now;
        +	else			ret = ( (now.tv_sec+now.tv_usec*1e-6)
        +					- (tmstart.tv_sec+tmstart.tv_usec*1e-6) );
        +
        +	return ret;
        +	}
        +#endif
        +
        +/* app_isdir section */
        +#ifdef _WIN32
        +int app_isdir(const char *name)
        +	{
        +	HANDLE		hList;
        +	WIN32_FIND_DATA	FileData;
        +#if defined(UNICODE) || defined(_UNICODE)
        +	size_t i, len_0 = strlen(name)+1;
        +
        +	if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0]))
        +		return -1;
        +
        +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
        +	if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0))
        +#endif
        +		for (i=0;i<len_0;i++)
        +			FileData.cFileName[i] = (WCHAR)name[i];
        +
        +	hList = FindFirstFile(FileData.cFileName,&FileData);
        +#else
        +	hList = FindFirstFile(name,&FileData);
        +#endif
        +	if (hList == INVALID_HANDLE_VALUE)	return -1;
        +	FindClose(hList);
        +	return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);
        +	}
        +#else
        +#include <sys/stat.h>
        +#ifndef S_ISDIR
        +# if defined(_S_IFMT) && defined(_S_IFDIR)
        +#  define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
        +# else 
        +#  define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
        +# endif 
        +#endif 
        +
        +int app_isdir(const char *name)
        +	{
        +#if defined(S_ISDIR)
        +	struct stat st;
        +
        +	if (stat(name,&st)==0)	return S_ISDIR(st.st_mode);
        +	else			return -1;
        +#else
        +	return -1;
        +#endif
        +	}
        +#endif
        +
        +/* raw_read|write section */
        +#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
        +int raw_read_stdin(void *buf,int siz)
        +	{
        +	DWORD n;
        +	if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL))
        +		return (n);
        +	else	return (-1);
        +	}
        +#else
        +int raw_read_stdin(void *buf,int siz)
        +	{	return read(fileno(stdin),buf,siz);	}
        +#endif
        +
        +#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
        +int raw_write_stdout(const void *buf,int siz)
        +	{
        +	DWORD n;
        +	if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))
        +		return (n);
        +	else	return (-1);
        +	}
        +#else
        +int raw_write_stdout(const void *buf,int siz)
        +	{	return write(fileno(stdout),buf,siz);	}
        +#endif
        diff --git a/vendor/openssl/openssl/apps/apps.h b/vendor/openssl/openssl/apps/apps.h
        new file mode 100644
        index 000000000..c1ca99da1
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/apps.h
        @@ -0,0 +1,373 @@
        +/* apps/apps.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_APPS_H
        +#define HEADER_APPS_H
        +
        +#include "e_os.h"
        +
        +#include <openssl/bio.h>
        +#include <openssl/x509.h>
        +#include <openssl/lhash.h>
        +#include <openssl/conf.h>
        +#include <openssl/txt_db.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#ifndef OPENSSL_NO_OCSP
        +#include <openssl/ocsp.h>
        +#endif
        +#include <openssl/ossl_typ.h>
        +
        +int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn);
        +int app_RAND_write_file(const char *file, BIO *bio_e);
        +/* When `file' is NULL, use defaults.
        + * `bio_e' is for error messages. */
        +void app_RAND_allow_write_file(void);
        +long app_RAND_load_files(char *file); /* `file' is a list of files to read,
        +                                       * separated by LIST_SEPARATOR_CHAR
        +                                       * (see e_os.h).  The string is
        +                                       * destroyed! */
        +
        +#ifndef MONOLITH
        +
        +#define MAIN(a,v)	main(a,v)
        +
        +#ifndef NON_MAIN
        +CONF *config=NULL;
        +BIO *bio_err=NULL;
        +#else
        +extern CONF *config;
        +extern BIO *bio_err;
        +#endif
        +
        +#else
        +
        +#define MAIN(a,v)	PROG(a,v)
        +extern CONF *config;
        +extern char *default_config_file;
        +extern BIO *bio_err;
        +
        +#endif
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifdef SIGPIPE
        +#define do_pipe_sig()	signal(SIGPIPE,SIG_IGN)
        +#else
        +#define do_pipe_sig()
        +#endif
        +
        +#ifdef OPENSSL_NO_COMP
        +#define zlib_cleanup() 
        +#else
        +#define zlib_cleanup() COMP_zlib_cleanup()
        +#endif
        +
        +#if defined(MONOLITH) && !defined(OPENSSL_C)
        +#  define apps_startup() \
        +		do_pipe_sig()
        +#  define apps_shutdown()
        +#else
        +#  ifndef OPENSSL_NO_ENGINE
        +#    define apps_startup() \
        +			do { do_pipe_sig(); CRYPTO_malloc_init(); \
        +			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
        +			ENGINE_load_builtin_engines(); setup_ui_method(); } while(0)
        +#    define apps_shutdown() \
        +			do { CONF_modules_unload(1); destroy_ui_method(); \
        +			OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
        +			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
        +			ERR_free_strings(); zlib_cleanup();} while(0)
        +#  else
        +#    define apps_startup() \
        +			do { do_pipe_sig(); CRYPTO_malloc_init(); \
        +			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
        +			setup_ui_method(); } while(0)
        +#    define apps_shutdown() \
        +			do { CONF_modules_unload(1); destroy_ui_method(); \
        +			OBJ_cleanup(); EVP_cleanup(); \
        +			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
        +			ERR_free_strings(); zlib_cleanup(); } while(0)
        +#  endif
        +#endif
        +
        +#ifdef OPENSSL_SYSNAME_WIN32
        +#  define openssl_fdset(a,b) FD_SET((unsigned int)a, b)
        +#else
        +#  define openssl_fdset(a,b) FD_SET(a, b)
        +#endif
        +
        +
        +typedef struct args_st
        +	{
        +	char **data;
        +	int count;
        +	} ARGS;
        +
        +#define PW_MIN_LENGTH 4
        +typedef struct pw_cb_data
        +	{
        +	const void *password;
        +	const char *prompt_info;
        +	} PW_CB_DATA;
        +
        +int password_callback(char *buf, int bufsiz, int verify,
        +	PW_CB_DATA *cb_data);
        +
        +int setup_ui_method(void);
        +void destroy_ui_method(void);
        +
        +int should_retry(int i);
        +int args_from_file(char *file, int *argc, char **argv[]);
        +int str2fmt(char *s);
        +void program_name(char *in,char *out,int size);
        +int chopup_args(ARGS *arg,char *buf, int *argc, char **argv[]);
        +#ifdef HEADER_X509_H
        +int dump_cert_text(BIO *out, X509 *x);
        +void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags);
        +#endif
        +int set_cert_ex(unsigned long *flags, const char *arg);
        +int set_name_ex(unsigned long *flags, const char *arg);
        +int set_ext_copy(int *copy_type, const char *arg);
        +int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
        +int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
        +int add_oid_section(BIO *err, CONF *conf);
        +X509 *load_cert(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *cert_descrip);
        +EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
        +	const char *pass, ENGINE *e, const char *key_descrip);
        +EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
        +	const char *pass, ENGINE *e, const char *key_descrip);
        +STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *cert_descrip);
        +STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
        +	const char *pass, ENGINE *e, const char *cert_descrip);
        +X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
        +#ifndef OPENSSL_NO_ENGINE
        +ENGINE *setup_engine(BIO *err, const char *engine, int debug);
        +#endif
        +
        +#ifndef OPENSSL_NO_OCSP
        +OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
        +			char *host, char *path, char *port, int use_ssl,
        +			STACK_OF(CONF_VALUE) *headers,
        +			int req_timeout);
        +#endif
        +
        +int load_config(BIO *err, CONF *cnf);
        +char *make_config_name(void);
        +
        +/* Functions defined in ca.c and also used in ocsp.c */
        +int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
        +			ASN1_GENERALIZEDTIME **pinvtm, const char *str);
        +
        +#define DB_type         0
        +#define DB_exp_date     1
        +#define DB_rev_date     2
        +#define DB_serial       3       /* index - unique */
        +#define DB_file         4       
        +#define DB_name         5       /* index - unique when active and not disabled */
        +#define DB_NUMBER       6
        +
        +#define DB_TYPE_REV	'R'
        +#define DB_TYPE_EXP	'E'
        +#define DB_TYPE_VAL	'V'
        +
        +typedef struct db_attr_st
        +	{
        +	int unique_subject;
        +	} DB_ATTR;
        +typedef struct ca_db_st
        +	{
        +	DB_ATTR attributes;
        +	TXT_DB *db;
        +	} CA_DB;
        +
        +BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai);
        +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai);
        +int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix);
        +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
        +CA_DB *load_index(char *dbfile, DB_ATTR *dbattr);
        +int index_index(CA_DB *db);
        +int save_index(const char *dbfile, const char *suffix, CA_DB *db);
        +int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix);
        +void free_index(CA_DB *db);
        +#define index_name_cmp_noconst(a, b) \
        +	index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
        +	(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
        +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
        +int parse_yesno(const char *str, int def);
        +
        +X509_NAME *parse_name(char *str, long chtype, int multirdn);
        +int args_verify(char ***pargs, int *pargc,
        +			int *badarg, BIO *err, X509_VERIFY_PARAM **pm);
        +void policies_print(BIO *out, X509_STORE_CTX *ctx);
        +int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
        +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
        +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
        +			const char *algname, ENGINE *e, int do_param);
        +int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
        +			STACK_OF(OPENSSL_STRING) *sigopts);
        +int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
        +			STACK_OF(OPENSSL_STRING) *sigopts);
        +int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
        +			STACK_OF(OPENSSL_STRING) *sigopts);
        +#ifndef OPENSSL_NO_PSK
        +extern char *psk_key;
        +#endif
        +#ifndef OPENSSL_NO_JPAKE
        +void jpake_client_auth(BIO *out, BIO *conn, const char *secret);
        +void jpake_server_auth(BIO *out, BIO *conn, const char *secret);
        +#endif
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
        +#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
        +
        +#define FORMAT_UNDEF    0
        +#define FORMAT_ASN1     1
        +#define FORMAT_TEXT     2
        +#define FORMAT_PEM      3
        +#define FORMAT_NETSCAPE 4
        +#define FORMAT_PKCS12   5
        +#define FORMAT_SMIME    6
        +#define FORMAT_ENGINE   7
        +#define FORMAT_IISSGC	8	/* XXX this stupid macro helps us to avoid
        +				 * adding yet another param to load_*key() */
        +#define FORMAT_PEMRSA	9	/* PEM RSAPubicKey format */
        +#define FORMAT_ASN1RSA	10	/* DER RSAPubicKey format */
        +#define FORMAT_MSBLOB	11	/* MS Key blob format */
        +#define FORMAT_PVK	12	/* MS PVK file format */
        +
        +#define EXT_COPY_NONE	0
        +#define EXT_COPY_ADD	1
        +#define EXT_COPY_ALL	2
        +
        +#define NETSCAPE_CERT_HDR	"certificate"
        +
        +#define APP_PASS_LEN	1024
        +
        +#define SERIAL_RAND_BITS	64
        +
        +int app_isdir(const char *);
        +int raw_read_stdin(void *,int);
        +int raw_write_stdout(const void *,int);
        +
        +#define TM_START	0
        +#define TM_STOP		1
        +double app_tminterval (int stop,int usertime);
        +
        +#define OPENSSL_NO_SSL_INTERN
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/asn1pars.c b/vendor/openssl/openssl/apps/asn1pars.c
        new file mode 100644
        index 000000000..0d6607071
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/asn1pars.c
        @@ -0,0 +1,445 @@
        +/* apps/asn1pars.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.]
        + */
        +
        +/* A nice addition from Dr Stephen Henson <steve@openssl.org> to 
        + * add the -strparse option which parses nested binary structures
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -in arg	- input file - default stdin
        + * -i		- indent the details by depth
        + * -offset	- where in the file to start
        + * -length	- how many bytes to use
        + * -oid file	- extra oid description file
        + */
        +
        +#undef PROG
        +#define PROG	asn1parse_main
        +
        +int MAIN(int, char **);
        +
        +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int i,badops=0,offset=0,ret=1,j;
        +	unsigned int length=0;
        +	long num,tmplen;
        +	BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
        +	int informat,indent=0, noout = 0, dump = 0;
        +	char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
        +	char *genstr=NULL, *genconf=NULL;
        +	unsigned char *tmpbuf;
        +	const unsigned char *ctmpbuf;
        +	BUF_MEM *buf=NULL;
        +	STACK_OF(OPENSSL_STRING) *osk=NULL;
        +	ASN1_TYPE *at=NULL;
        +
        +	informat=FORMAT_PEM;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	if ((osk=sk_OPENSSL_STRING_new_null()) == NULL)
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		goto end;
        +		}
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			derfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-i") == 0)
        +			{
        +			indent=1;
        +			}
        +		else if (strcmp(*argv,"-noout") == 0) noout = 1;
        +		else if (strcmp(*argv,"-oid") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			oidfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-offset") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			offset= atoi(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-length") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			length= atoi(*(++argv));
        +			if (length == 0) goto bad;
        +			}
        +		else if (strcmp(*argv,"-dump") == 0)
        +			{
        +			dump= -1;
        +			}
        +		else if (strcmp(*argv,"-dlimit") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			dump= atoi(*(++argv));
        +			if (dump <= 0) goto bad;
        +			}
        +		else if (strcmp(*argv,"-strparse") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			sk_OPENSSL_STRING_push(osk,*(++argv));
        +			}
        +		else if (strcmp(*argv,"-genstr") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			genstr= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-genconf") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			genconf= *(++argv);
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
        +		BIO_printf(bio_err," -in arg       input file\n");
        +		BIO_printf(bio_err," -out arg      output file (output format is always DER\n");
        +		BIO_printf(bio_err," -noout arg    don't produce any output\n");
        +		BIO_printf(bio_err," -offset arg   offset into file\n");
        +		BIO_printf(bio_err," -length arg   length of section in file\n");
        +		BIO_printf(bio_err," -i            indent entries\n");
        +		BIO_printf(bio_err," -dump         dump unknown data in hex form\n");
        +		BIO_printf(bio_err," -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
        +		BIO_printf(bio_err," -oid file     file of extra oid definitions\n");
        +		BIO_printf(bio_err," -strparse offset\n");
        +		BIO_printf(bio_err,"               a series of these can be used to 'dig' into multiple\n");
        +		BIO_printf(bio_err,"               ASN1 blob wrappings\n");
        +		BIO_printf(bio_err," -genstr str   string to generate ASN1 structure from\n");
        +		BIO_printf(bio_err," -genconf file file to generate ASN1 structure from\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
        +#ifdef OPENSSL_SYS_VMS
        +	{
        +	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	out = BIO_push(tmpbio, out);
        +	}
        +#endif
        +
        +	if (oidfile != NULL)
        +		{
        +		if (BIO_read_filename(in,oidfile) <= 0)
        +			{
        +			BIO_printf(bio_err,"problems opening %s\n",oidfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		OBJ_create_objects(in);
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +
        +	if (derfile) {
        +		if(!(derout = BIO_new_file(derfile, "wb"))) {
        +			BIO_printf(bio_err,"problems opening %s\n",derfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +	}
        +
        +	if ((buf=BUF_MEM_new()) == NULL) goto end;
        +	if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */
        +
        +	if (genstr || genconf)
        +		{
        +		num = do_generate(bio_err, genstr, genconf, buf);
        +		if (num < 0)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	else
        +		{
        +
        +		if (informat == FORMAT_PEM)
        +			{
        +			BIO *tmp;
        +
        +			if ((b64=BIO_new(BIO_f_base64())) == NULL)
        +				goto end;
        +			BIO_push(b64,in);
        +			tmp=in;
        +			in=b64;
        +			b64=tmp;
        +			}
        +
        +		num=0;
        +		for (;;)
        +			{
        +			if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
        +			i=BIO_read(in,&(buf->data[num]),BUFSIZ);
        +			if (i <= 0) break;
        +			num+=i;
        +			}
        +		}
        +	str=buf->data;
        +
        +	/* If any structs to parse go through in sequence */
        +
        +	if (sk_OPENSSL_STRING_num(osk))
        +		{
        +		tmpbuf=(unsigned char *)str;
        +		tmplen=num;
        +		for (i=0; i<sk_OPENSSL_STRING_num(osk); i++)
        +			{
        +			ASN1_TYPE *atmp;
        +			int typ;
        +			j=atoi(sk_OPENSSL_STRING_value(osk,i));
        +			if (j == 0)
        +				{
        +				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_OPENSSL_STRING_value(osk,i));
        +				continue;
        +				}
        +			tmpbuf+=j;
        +			tmplen-=j;
        +			atmp = at;
        +			ctmpbuf = tmpbuf;
        +			at = d2i_ASN1_TYPE(NULL,&ctmpbuf,tmplen);
        +			ASN1_TYPE_free(atmp);
        +			if(!at)
        +				{
        +				BIO_printf(bio_err,"Error parsing structure\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			typ = ASN1_TYPE_get(at);
        +			if ((typ == V_ASN1_OBJECT)
        +				|| (typ == V_ASN1_NULL))
        +				{
        +				BIO_printf(bio_err, "Can't parse %s type\n",
        +					typ == V_ASN1_NULL ? "NULL" : "OBJECT");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			/* hmm... this is a little evil but it works */
        +			tmpbuf=at->value.asn1_string->data;
        +			tmplen=at->value.asn1_string->length;
        +			}
        +		str=(char *)tmpbuf;
        +		num=tmplen;
        +		}
        +
        +	if (offset >= num)
        +		{
        +		BIO_printf(bio_err, "Error: offset too large\n");
        +		goto end;
        +		}
        +
        +	num -= offset;
        +
        +	if ((length == 0) || ((long)length > num)) length=(unsigned int)num;
        +	if(derout) {
        +		if(BIO_write(derout, str + offset, length) != (int)length) {
        +			BIO_printf(bio_err, "Error writing output\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +	}
        +	if (!noout &&
        +	    !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
        +		    indent,dump))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	ret=0;
        +end:
        +	BIO_free(derout);
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (b64 != NULL) BIO_free(b64);
        +	if (ret != 0)
        +		ERR_print_errors(bio_err);
        +	if (buf != NULL) BUF_MEM_free(buf);
        +	if (at != NULL) ASN1_TYPE_free(at);
        +	if (osk != NULL) sk_OPENSSL_STRING_free(osk);
        +	OBJ_cleanup();
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
        +	{
        +	CONF *cnf = NULL;
        +	int len;
        +	long errline;
        +	unsigned char *p;
        +	ASN1_TYPE *atyp = NULL;
        +
        +	if (genconf)
        +		{
        +		cnf = NCONF_new(NULL);
        +		if (!NCONF_load(cnf, genconf, &errline))
        +			goto conferr;
        +		if (!genstr)
        +			genstr = NCONF_get_string(cnf, "default", "asn1");
        +		if (!genstr)
        +			{
        +			BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
        +			goto err;
        +			}
        +		}
        +
        +	atyp = ASN1_generate_nconf(genstr, cnf);
        +	NCONF_free(cnf);
        +	cnf = NULL;
        +
        +	if (!atyp)
        +		return -1;
        +
        +	len = i2d_ASN1_TYPE(atyp, NULL);
        +
        +	if (len <= 0)
        +		goto err;
        +
        +	if (!BUF_MEM_grow(buf,len))
        +		goto err;
        +
        +	p=(unsigned char *)buf->data;
        +
        +	i2d_ASN1_TYPE(atyp, &p);
        +
        +	ASN1_TYPE_free(atyp);
        +	return len;
        +
        +	conferr:
        +
        +	if (errline > 0)
        +		BIO_printf(bio, "Error on line %ld of config file '%s'\n",
        +							errline, genconf);
        +	else
        +		BIO_printf(bio, "Error loading config file '%s'\n", genconf);
        +
        +	err:
        +	NCONF_free(cnf);
        +	ASN1_TYPE_free(atyp);
        +
        +	return -1;
        +
        +	}
        diff --git a/vendor/openssl/openssl/apps/ca-cert.srl b/vendor/openssl/openssl/apps/ca-cert.srl
        new file mode 100644
        index 000000000..2c7456e3e
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ca-cert.srl
        @@ -0,0 +1 @@
        +07
        diff --git a/vendor/openssl/openssl/apps/ca-key.pem b/vendor/openssl/openssl/apps/ca-key.pem
        new file mode 100644
        index 000000000..3a520b238
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ca-key.pem
        @@ -0,0 +1,15 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
        +gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
        +2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
        +AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
        +hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
        +J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
        +HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
        +21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
        +nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
        +MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
        +pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
        +KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
        +XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/ca-req.pem b/vendor/openssl/openssl/apps/ca-req.pem
        new file mode 100644
        index 000000000..77bf7ec30
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ca-req.pem
        @@ -0,0 +1,11 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBmTCCAQICAQAwWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
        +GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgx
        +MDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgy
        +bTsZDCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/d
        +FXSv1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUe
        +cQU2mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAKlk7
        +cxu9gCJN3/iQFyJXQ6YphaiQAT5VBXTx9ftRrQIjA3vxlDzPWGDy+V5Tqa7h8PtR
        +5Bn00JShII2zf0hjyjKils6x/UkWmjEiwSiFp4hR70iE8XwSNEHY2P6j6nQEIpgW
        +kbfgmmUqk7dl2V+ossTJ80B8SBpEhrn81V/cHxA=
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/apps/ca.c b/vendor/openssl/openssl/apps/ca.c
        new file mode 100644
        index 000000000..1cf50e002
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ca.c
        @@ -0,0 +1,3010 @@
        +/* apps/ca.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.]
        + */
        +
        +/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include <sys/types.h>
        +#include <openssl/conf.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/txt_db.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/objects.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/pem.h>
        +
        +#ifndef W_OK
        +#  ifdef OPENSSL_SYS_VMS
        +#    if defined(__DECC)
        +#      include <unistd.h>
        +#    else
        +#      include <unixlib.h>
        +#    endif
        +#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
        +#    include <sys/file.h>
        +#  endif
        +#endif
        +
        +#include "apps.h"
        +
        +#ifndef W_OK
        +#  define F_OK 0
        +#  define X_OK 1
        +#  define W_OK 2
        +#  define R_OK 4
        +#endif
        +
        +#undef PROG
        +#define PROG ca_main
        +
        +#define BASE_SECTION	"ca"
        +#define CONFIG_FILE "openssl.cnf"
        +
        +#define ENV_DEFAULT_CA		"default_ca"
        +
        +#define STRING_MASK	"string_mask"
        +#define UTF8_IN			"utf8"
        +
        +#define ENV_DIR			"dir"
        +#define ENV_CERTS		"certs"
        +#define ENV_CRL_DIR		"crl_dir"
        +#define ENV_CA_DB		"CA_DB"
        +#define ENV_NEW_CERTS_DIR	"new_certs_dir"
        +#define ENV_CERTIFICATE 	"certificate"
        +#define ENV_SERIAL		"serial"
        +#define ENV_CRLNUMBER		"crlnumber"
        +#define ENV_CRL			"crl"
        +#define ENV_PRIVATE_KEY		"private_key"
        +#define ENV_RANDFILE		"RANDFILE"
        +#define ENV_DEFAULT_DAYS 	"default_days"
        +#define ENV_DEFAULT_STARTDATE 	"default_startdate"
        +#define ENV_DEFAULT_ENDDATE 	"default_enddate"
        +#define ENV_DEFAULT_CRL_DAYS 	"default_crl_days"
        +#define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours"
        +#define ENV_DEFAULT_MD		"default_md"
        +#define ENV_DEFAULT_EMAIL_DN	"email_in_dn"
        +#define ENV_PRESERVE		"preserve"
        +#define ENV_POLICY      	"policy"
        +#define ENV_EXTENSIONS      	"x509_extensions"
        +#define ENV_CRLEXT      	"crl_extensions"
        +#define ENV_MSIE_HACK		"msie_hack"
        +#define ENV_NAMEOPT		"name_opt"
        +#define ENV_CERTOPT		"cert_opt"
        +#define ENV_EXTCOPY		"copy_extensions"
        +#define ENV_UNIQUE_SUBJECT	"unique_subject"
        +
        +#define ENV_DATABASE		"database"
        +
        +/* Additional revocation information types */
        +
        +#define REV_NONE		0	/* No addditional information */
        +#define REV_CRL_REASON		1	/* Value is CRL reason code */
        +#define REV_HOLD		2	/* Value is hold instruction */
        +#define REV_KEY_COMPROMISE	3	/* Value is cert key compromise time */
        +#define REV_CA_COMPROMISE	4	/* Value is CA key compromise time */
        +
        +static const char *ca_usage[]={
        +"usage: ca args\n",
        +"\n",
        +" -verbose        - Talk alot while doing things\n",
        +" -config file    - A config file\n",
        +" -name arg       - The particular CA definition to use\n",
        +" -gencrl         - Generate a new CRL\n",
        +" -crldays days   - Days is when the next CRL is due\n",
        +" -crlhours hours - Hours is when the next CRL is due\n",
        +" -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
        +" -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
        +" -days arg       - number of days to certify the certificate for\n",
        +" -md arg         - md to use, one of md2, md5, sha or sha1\n",
        +" -policy arg     - The CA 'policy' to support\n",
        +" -keyfile arg    - private key file\n",
        +" -keyform arg    - private key file format (PEM or ENGINE)\n",
        +" -key arg        - key to decode the private key if it is encrypted\n",
        +" -cert file      - The CA certificate\n",
        +" -selfsign       - sign a certificate with the key associated with it\n",
        +" -in file        - The input PEM encoded certificate request(s)\n",
        +" -out file       - Where to put the output file(s)\n",
        +" -outdir dir     - Where to put output certificates\n",
        +" -infiles ....   - The last argument, requests to process\n",
        +" -spkac file     - File contains DN and signed public key and challenge\n",
        +" -ss_cert file   - File contains a self signed cert to sign\n",
        +" -preserveDN     - Don't re-order the DN\n",
        +" -noemailDN      - Don't add the EMAIL field into certificate' subject\n",
        +" -batch          - Don't ask questions\n",
        +" -msie_hack      - msie modifications to handle all those universal strings\n",
        +" -revoke file    - Revoke a certificate (given in file)\n",
        +" -subj arg       - Use arg instead of request's subject\n",
        +" -utf8           - input characters are UTF8 (default ASCII)\n",
        +" -multivalue-rdn - enable support for multivalued RDNs\n",
        +" -extensions ..  - Extension section (override value in config file)\n",
        +" -extfile file   - Configuration file with X509v3 extentions to add\n",
        +" -crlexts ..     - CRL extension section (override value in config file)\n",
        +#ifndef OPENSSL_NO_ENGINE
        +" -engine e       - use engine e, possibly a hardware device.\n",
        +#endif
        +" -status serial  - Shows certificate status given the serial number\n",
        +" -updatedb       - Updates db for expired certificates\n",
        +NULL
        +};
        +
        +#ifdef EFENCE
        +extern int EF_PROTECT_FREE;
        +extern int EF_PROTECT_BELOW;
        +extern int EF_ALIGNMENT;
        +#endif
        +
        +static void lookup_fail(const char *name, const char *tag);
        +static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
        +		   const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
        +		   STACK_OF(CONF_VALUE) *policy,CA_DB *db,
        +		   BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate,
        +		   char *enddate, long days, int batch, char *ext_sect, CONF *conf,
        +		   int verbose, unsigned long certopt, unsigned long nameopt,
        +		   int default_op, int ext_copy, int selfsign);
        +static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
        +			const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
        +			STACK_OF(CONF_VALUE) *policy,
        +			CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn,
        +			char *startdate, char *enddate, long days, int batch,
        +			char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
        +			unsigned long nameopt, int default_op, int ext_copy,
        +			ENGINE *e);
        +static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
        +			 const EVP_MD *dgst,STACK_OF(OPENSSL_STRING) *sigopts,
        +			 STACK_OF(CONF_VALUE) *policy,
        +			 CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn,
        +			 char *startdate, char *enddate, long days, char *ext_sect,
        +			 CONF *conf, int verbose, unsigned long certopt, 
        +			 unsigned long nameopt, int default_op, int ext_copy);
        +static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
        +static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
        +	STACK_OF(OPENSSL_STRING) *sigopts,
        +	STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
        +	int email_dn, char *startdate, char *enddate, long days, int batch,
        +       	int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
        +	unsigned long certopt, unsigned long nameopt, int default_op,
        +	int ext_copy, int selfsign);
        +static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
        +static int get_certificate_status(const char *ser_status, CA_DB *db);
        +static int do_updatedb(CA_DB *db);
        +static int check_time_format(const char *str);
        +char *make_revocation_str(int rev_type, char *rev_arg);
        +int make_revoked(X509_REVOKED *rev, const char *str);
        +int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
        +static CONF *conf=NULL;
        +static CONF *extconf=NULL;
        +static char *section=NULL;
        +
        +static int preserve=0;
        +static int msie_hack=0;
        +
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	char *key=NULL,*passargin=NULL;
        +	int create_ser = 0;
        +	int free_key = 0;
        +	int total=0;
        +	int total_done=0;
        +	int badops=0;
        +	int ret=1;
        +	int email_dn=1;
        +	int req=0;
        +	int verbose=0;
        +	int gencrl=0;
        +	int dorevoke=0;
        +	int doupdatedb=0;
        +	long crldays=0;
        +	long crlhours=0;
        +	long crlsec=0;
        +	long errorline= -1;
        +	char *configfile=NULL;
        +	char *md=NULL;
        +	char *policy=NULL;
        +	char *keyfile=NULL;
        +	char *certfile=NULL;
        +	int keyform=FORMAT_PEM;
        +	char *infile=NULL;
        +	char *spkac_file=NULL;
        +	char *ss_cert_file=NULL;
        +	char *ser_status=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	int output_der = 0;
        +	char *outfile=NULL;
        +	char *outdir=NULL;
        +	char *serialfile=NULL;
        +	char *crlnumberfile=NULL;
        +	char *extensions=NULL;
        +	char *extfile=NULL;
        +	char *subj=NULL;
        +	unsigned long chtype = MBSTRING_ASC;
        +	int multirdn = 0;
        +	char *tmp_email_dn=NULL;
        +	char *crl_ext=NULL;
        +	int rev_type = REV_NONE;
        +	char *rev_arg = NULL;
        +	BIGNUM *serial=NULL;
        +	BIGNUM *crlnumber=NULL;
        +	char *startdate=NULL;
        +	char *enddate=NULL;
        +	long days=0;
        +	int batch=0;
        +	int notext=0;
        +	unsigned long nameopt = 0, certopt = 0;
        +	int default_op = 1;
        +	int ext_copy = EXT_COPY_NONE;
        +	int selfsign = 0;
        +	X509 *x509=NULL, *x509p = NULL;
        +	X509 *x=NULL;
        +	BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
        +	char *dbfile=NULL;
        +	CA_DB *db=NULL;
        +	X509_CRL *crl=NULL;
        +	X509_REVOKED *r=NULL;
        +	ASN1_TIME *tmptm;
        +	ASN1_INTEGER *tmpser;
        +	char *f;
        +	const char *p;
        +	char * const *pp;
        +	int i,j;
        +	const EVP_MD *dgst=NULL;
        +	STACK_OF(CONF_VALUE) *attribs=NULL;
        +	STACK_OF(X509) *cert_sk=NULL;
        +	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
        +#undef BSIZE
        +#define BSIZE 256
        +	MS_STATIC char buf[3][BSIZE];
        +	char *randfile=NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine = NULL;
        +#endif
        +	char *tofree=NULL;
        +	DB_ATTR db_attr;
        +
        +#ifdef EFENCE
        +EF_PROTECT_FREE=1;
        +EF_PROTECT_BELOW=1;
        +EF_ALIGNMENT=0;
        +#endif
        +
        +	apps_startup();
        +
        +	conf = NULL;
        +	key = NULL;
        +	section = NULL;
        +
        +	preserve=0;
        +	msie_hack=0;
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if	(strcmp(*argv,"-verbose") == 0)
        +			verbose=1;
        +		else if	(strcmp(*argv,"-config") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			configfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-name") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			section= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-subj") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			subj= *(++argv);
        +			/* preserve=1; */
        +			}
        +		else if (strcmp(*argv,"-utf8") == 0)
        +			chtype = MBSTRING_UTF8;
        +		else if (strcmp(*argv,"-create_serial") == 0)
        +			create_ser = 1;
        +		else if (strcmp(*argv,"-multivalue-rdn") == 0)
        +			multirdn=1;
        +		else if (strcmp(*argv,"-startdate") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			startdate= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-enddate") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			enddate= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-days") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			days=atoi(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-md") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			md= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-policy") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			policy= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keyfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyform=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			key= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			certfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-selfsign") == 0)
        +			selfsign=1;
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			req=1;
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-outdir") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outdir= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-sigopt") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			if (!sigopts)
        +				sigopts = sk_OPENSSL_STRING_new_null();
        +			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
        +				goto bad;
        +			}
        +		else if (strcmp(*argv,"-notext") == 0)
        +			notext=1;
        +		else if (strcmp(*argv,"-batch") == 0)
        +			batch=1;
        +		else if (strcmp(*argv,"-preserveDN") == 0)
        +			preserve=1;
        +		else if (strcmp(*argv,"-noemailDN") == 0)
        +			email_dn=0;
        +		else if (strcmp(*argv,"-gencrl") == 0)
        +			gencrl=1;
        +		else if (strcmp(*argv,"-msie_hack") == 0)
        +			msie_hack=1;
        +		else if (strcmp(*argv,"-crldays") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			crldays= atol(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-crlhours") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			crlhours= atol(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-crlsec") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			crlsec = atol(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-infiles") == 0)
        +			{
        +			argc--;
        +			argv++;
        +			req=1;
        +			break;
        +			}
        +		else if (strcmp(*argv, "-ss_cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			ss_cert_file = *(++argv);
        +			req=1;
        +			}
        +		else if (strcmp(*argv, "-spkac") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			spkac_file = *(++argv);
        +			req=1;
        +			}
        +		else if (strcmp(*argv,"-revoke") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			dorevoke=1;
        +			}
        +		else if (strcmp(*argv,"-extensions") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			extensions= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-extfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			extfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-status") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			ser_status= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-updatedb") == 0)
        +			{
        +			doupdatedb=1;
        +			}
        +		else if (strcmp(*argv,"-crlexts") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			crl_ext= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-crl_reason") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			rev_arg = *(++argv);
        +			rev_type = REV_CRL_REASON;
        +			}
        +		else if (strcmp(*argv,"-crl_hold") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			rev_arg = *(++argv);
        +			rev_type = REV_HOLD;
        +			}
        +		else if (strcmp(*argv,"-crl_compromise") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			rev_arg = *(++argv);
        +			rev_type = REV_KEY_COMPROMISE;
        +			}
        +		else if (strcmp(*argv,"-crl_CA_compromise") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			rev_arg = *(++argv);
        +			rev_type = REV_CA_COMPROMISE;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else
        +			{
        +bad:
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +		const char **pp2;
        +
        +		for (pp2=ca_usage; (*pp2 != NULL); pp2++)
        +			BIO_printf(bio_err,"%s",*pp2);
        +		goto err;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +	/*****************************************************************/
        +	tofree=NULL;
        +	if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
        +	if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
        +	if (configfile == NULL)
        +		{
        +		const char *s=X509_get_default_cert_area();
        +		size_t len;
        +
        +#ifdef OPENSSL_SYS_VMS
        +		len = strlen(s)+sizeof(CONFIG_FILE);
        +		tofree=OPENSSL_malloc(len);
        +		strcpy(tofree,s);
        +#else
        +		len = strlen(s)+sizeof(CONFIG_FILE)+1;
        +		tofree=OPENSSL_malloc(len);
        +		BUF_strlcpy(tofree,s,len);
        +		BUF_strlcat(tofree,"/",len);
        +#endif
        +		BUF_strlcat(tofree,CONFIG_FILE,len);
        +		configfile=tofree;
        +		}
        +
        +	BIO_printf(bio_err,"Using configuration from %s\n",configfile);
        +	conf = NCONF_new(NULL);
        +	if (NCONF_load(conf,configfile,&errorline) <= 0)
        +		{
        +		if (errorline <= 0)
        +			BIO_printf(bio_err,"error loading the config file '%s'\n",
        +				configfile);
        +		else
        +			BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
        +				,errorline,configfile);
        +		goto err;
        +		}
        +	if(tofree)
        +		{
        +		OPENSSL_free(tofree);
        +		tofree = NULL;
        +		}
        +
        +	if (!load_config(bio_err, conf))
        +		goto err;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	/* Lets get the config section we are using */
        +	if (section == NULL)
        +		{
        +		section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
        +		if (section == NULL)
        +			{
        +			lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
        +			goto err;
        +			}
        +		}
        +
        +	if (conf != NULL)
        +		{
        +		p=NCONF_get_string(conf,NULL,"oid_file");
        +		if (p == NULL)
        +			ERR_clear_error();
        +		if (p != NULL)
        +			{
        +			BIO *oid_bio;
        +
        +			oid_bio=BIO_new_file(p,"r");
        +			if (oid_bio == NULL) 
        +				{
        +				/*
        +				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
        +				ERR_print_errors(bio_err);
        +				*/
        +				ERR_clear_error();
        +				}
        +			else
        +				{
        +				OBJ_create_objects(oid_bio);
        +				BIO_free(oid_bio);
        +				}
        +			}
        +		if (!add_oid_section(bio_err,conf)) 
        +			{
        +			ERR_print_errors(bio_err);
        +			goto err;
        +			}
        +		}
        +
        +	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
        +	if (randfile == NULL)
        +		ERR_clear_error();
        +	app_RAND_load_file(randfile, bio_err, 0);
        +
        +	f = NCONF_get_string(conf, section, STRING_MASK);
        +	if (!f)
        +		ERR_clear_error();
        +
        +	if(f && !ASN1_STRING_set_default_mask_asc(f)) {
        +		BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
        +		goto err;
        +	}
        +
        +	if (chtype != MBSTRING_UTF8){
        +		f = NCONF_get_string(conf, section, UTF8_IN);
        +		if (!f)
        +			ERR_clear_error();
        +		else if (!strcmp(f, "yes"))
        +			chtype = MBSTRING_UTF8;
        +	}
        +
        +	db_attr.unique_subject = 1;
        +	p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
        +	if (p)
        +		{
        +#ifdef RL_DEBUG
        +		BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
        +#endif
        +		db_attr.unique_subject = parse_yesno(p,1);
        +		}
        +	else
        +		ERR_clear_error();
        +#ifdef RL_DEBUG
        +	if (!p)
        +		BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
        +#endif
        +#ifdef RL_DEBUG
        +	BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
        +		db_attr.unique_subject);
        +#endif
        +	
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	Sout=BIO_new(BIO_s_file());
        +	Cout=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	/*****************************************************************/
        +	/* report status of cert with serial number given on command line */
        +	if (ser_status)
        +	{
        +		if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
        +			{
        +			lookup_fail(section,ENV_DATABASE);
        +			goto err;
        +			}
        +		db = load_index(dbfile,&db_attr);
        +		if (db == NULL) goto err;
        +
        +		if (!index_index(db)) goto err;
        +
        +		if (get_certificate_status(ser_status,db) != 1)
        +			BIO_printf(bio_err,"Error verifying serial %s!\n",
        +				 ser_status);
        +		goto err;
        +	}
        +
        +	/*****************************************************************/
        +	/* we definitely need a private key, so let's get it */
        +
        +	if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
        +		section,ENV_PRIVATE_KEY)) == NULL))
        +		{
        +		lookup_fail(section,ENV_PRIVATE_KEY);
        +		goto err;
        +		}
        +	if (!key)
        +		{
        +		free_key = 1;
        +		if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
        +			{
        +			BIO_printf(bio_err,"Error getting password\n");
        +			goto err;
        +			}
        +		}
        +	pkey = load_key(bio_err, keyfile, keyform, 0, key, e, 
        +		"CA private key");
        +	if (key) OPENSSL_cleanse(key,strlen(key));
        +	if (pkey == NULL)
        +		{
        +		/* load_key() has already printed an appropriate message */
        +		goto err;
        +		}
        +
        +	/*****************************************************************/
        +	/* we need a certificate */
        +	if (!selfsign || spkac_file || ss_cert_file || gencrl)
        +		{
        +		if ((certfile == NULL)
        +			&& ((certfile=NCONF_get_string(conf,
        +				     section,ENV_CERTIFICATE)) == NULL))
        +			{
        +			lookup_fail(section,ENV_CERTIFICATE);
        +			goto err;
        +			}
        +		x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
        +			"CA certificate");
        +		if (x509 == NULL)
        +			goto err;
        +
        +		if (!X509_check_private_key(x509,pkey))
        +			{
        +			BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
        +			goto err;
        +			}
        +		}
        +	if (!selfsign) x509p = x509;
        +
        +	f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
        +	if (f == NULL)
        +		ERR_clear_error();
        +	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
        +		preserve=1;
        +	f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
        +	if (f == NULL)
        +		ERR_clear_error();
        +	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
        +		msie_hack=1;
        +
        +	f=NCONF_get_string(conf,section,ENV_NAMEOPT);
        +
        +	if (f)
        +		{
        +		if (!set_name_ex(&nameopt, f))
        +			{
        +			BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
        +			goto err;
        +			}
        +		default_op = 0;
        +		}
        +	else
        +		ERR_clear_error();
        +
        +	f=NCONF_get_string(conf,section,ENV_CERTOPT);
        +
        +	if (f)
        +		{
        +		if (!set_cert_ex(&certopt, f))
        +			{
        +			BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
        +			goto err;
        +			}
        +		default_op = 0;
        +		}
        +	else
        +		ERR_clear_error();
        +
        +	f=NCONF_get_string(conf,section,ENV_EXTCOPY);
        +
        +	if (f)
        +		{
        +		if (!set_ext_copy(&ext_copy, f))
        +			{
        +			BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
        +			goto err;
        +			}
        +		}
        +	else
        +		ERR_clear_error();
        +
        +	/*****************************************************************/
        +	/* lookup where to write new certificates */
        +	if ((outdir == NULL) && (req))
        +		{
        +
        +		if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
        +			== NULL)
        +			{
        +			BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
        +			goto err;
        +			}
        +#ifndef OPENSSL_SYS_VMS
        +	    /* outdir is a directory spec, but access() for VMS demands a
        +	       filename.  In any case, stat(), below, will catch the problem
        +	       if outdir is not a directory spec, and the fopen() or open()
        +	       will catch an error if there is no write access.
        +
        +	       Presumably, this problem could also be solved by using the DEC
        +	       C routines to convert the directory syntax to Unixly, and give
        +	       that to access().  However, time's too short to do that just
        +	       now.
        +	    */
        +#ifndef _WIN32
        +		if (access(outdir,R_OK|W_OK|X_OK) != 0)
        +#else
        +		if (_access(outdir,R_OK|W_OK|X_OK) != 0)
        +#endif
        +			{
        +			BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
        +			perror(outdir);
        +			goto err;
        +			}
        +
        +		if (app_isdir(outdir)<=0)
        +			{
        +			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
        +			perror(outdir);
        +			goto err;
        +			}
        +#endif
        +		}
        +
        +	/*****************************************************************/
        +	/* we need to load the database file */
        +	if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
        +		{
        +		lookup_fail(section,ENV_DATABASE);
        +		goto err;
        +		}
        +	db = load_index(dbfile, &db_attr);
        +	if (db == NULL) goto err;
        +
        +	/* Lets check some fields */
        +	for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +		{
        +		pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
        +		if ((pp[DB_type][0] != DB_TYPE_REV) &&
        +			(pp[DB_rev_date][0] != '\0'))
        +			{
        +			BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
        +			goto err;
        +			}
        +		if ((pp[DB_type][0] == DB_TYPE_REV) &&
        +			!make_revoked(NULL, pp[DB_rev_date]))
        +			{
        +			BIO_printf(bio_err," in entry %d\n", i+1);
        +			goto err;
        +			}
        +		if (!check_time_format((char *)pp[DB_exp_date]))
        +			{
        +			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
        +			goto err;
        +			}
        +		p=pp[DB_serial];
        +		j=strlen(p);
        +		if (*p == '-')
        +			{
        +			p++;
        +			j--;
        +			}
        +		if ((j&1) || (j < 2))
        +			{
        +			BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
        +			goto err;
        +			}
        +		while (*p)
        +			{
        +			if (!(	((*p >= '0') && (*p <= '9')) ||
        +				((*p >= 'A') && (*p <= 'F')) ||
        +				((*p >= 'a') && (*p <= 'f')))  )
        +				{
        +				BIO_printf(bio_err,"entry %d: bad serial number characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
        +				goto err;
        +				}
        +			p++;
        +			}
        +		}
        +	if (verbose)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		TXT_DB_write(out,db->db);
        +		BIO_printf(bio_err,"%d entries loaded from the database\n",
        +			   sk_OPENSSL_PSTRING_num(db->db->data));
        +		BIO_printf(bio_err,"generating index\n");
        +		}
        +	
        +	if (!index_index(db)) goto err;
        +
        +	/*****************************************************************/
        +	/* Update the db file for expired certificates */
        +	if (doupdatedb)
        +		{
        +		if (verbose)
        +			BIO_printf(bio_err, "Updating %s ...\n",
        +							dbfile);
        +
        +		i = do_updatedb(db);
        +		if (i == -1)
        +			{
        +			BIO_printf(bio_err,"Malloc failure\n");
        +			goto err;
        +			}
        +		else if (i == 0)
        +			{
        +			if (verbose) BIO_printf(bio_err,
        +					"No entries found to mark expired\n"); 
        +			}
        +	    	else
        +			{
        +			if (!save_index(dbfile,"new",db)) goto err;
        +				
        +			if (!rotate_index(dbfile,"new","old")) goto err;
        +				
        +			if (verbose) BIO_printf(bio_err,
        +				"Done. %d entries marked as expired\n",i); 
        +	      		}
        +	  	}
        +
        + 	/*****************************************************************/
        +	/* Read extentions config file                                   */
        +	if (extfile)
        +		{
        +		extconf = NCONF_new(NULL);
        +		if (NCONF_load(extconf,extfile,&errorline) <= 0)
        +			{
        +			if (errorline <= 0)
        +				BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
        +					extfile);
        +			else
        +				BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
        +					errorline,extfile);
        +			ret = 1;
        +			goto err;
        +			}
        +
        +		if (verbose)
        +			BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
        +
        +		/* We can have sections in the ext file */
        +		if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
        +			extensions = "default";
        +		}
        +
        +	/*****************************************************************/
        +	if (req || gencrl)
        +		{
        +		if (outfile != NULL)
        +			{
        +			if (BIO_write_filename(Sout,outfile) <= 0)
        +				{
        +				perror(outfile);
        +				goto err;
        +				}
        +			}
        +		else
        +			{
        +			BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			Sout = BIO_push(tmpbio, Sout);
        +			}
        +#endif
        +			}
        +		}
        +
        +	if ((md == NULL) && ((md=NCONF_get_string(conf,
        +		section,ENV_DEFAULT_MD)) == NULL))
        +		{
        +		lookup_fail(section,ENV_DEFAULT_MD);
        +		goto err;
        +		}
        +
        +	if (!strcmp(md, "default"))
        +		{
        +		int def_nid;
        +		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
        +			{
        +			BIO_puts(bio_err,"no default digest\n");
        +			goto err;
        +			}
        +		md = (char *)OBJ_nid2sn(def_nid);
        +		}
        +
        +	if ((dgst=EVP_get_digestbyname(md)) == NULL)
        +		{
        +		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
        +		goto err;
        +		}
        +
        +	if (req)
        +		{
        +		if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
        +			section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
        +			{
        +			if(strcmp(tmp_email_dn,"no") == 0)
        +				email_dn=0;
        +			}
        +		if (verbose)
        +			BIO_printf(bio_err,"message digest is %s\n",
        +				OBJ_nid2ln(dgst->type));
        +		if ((policy == NULL) && ((policy=NCONF_get_string(conf,
        +			section,ENV_POLICY)) == NULL))
        +			{
        +			lookup_fail(section,ENV_POLICY);
        +			goto err;
        +			}
        +		if (verbose)
        +			BIO_printf(bio_err,"policy is %s\n",policy);
        +
        +		if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
        +			== NULL)
        +			{
        +			lookup_fail(section,ENV_SERIAL);
        +			goto err;
        +			}
        +
        +		if (!extconf)
        +			{
        +			/* no '-extfile' option, so we look for extensions
        +			 * in the main configuration file */
        +			if (!extensions)
        +				{
        +				extensions=NCONF_get_string(conf,section,
        +								ENV_EXTENSIONS);
        +				if (!extensions)
        +					ERR_clear_error();
        +				}
        +			if (extensions)
        +				{
        +				/* Check syntax of file */
        +				X509V3_CTX ctx;
        +				X509V3_set_ctx_test(&ctx);
        +				X509V3_set_nconf(&ctx, conf);
        +				if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
        +								NULL))
        +					{
        +					BIO_printf(bio_err,
        +				 	"Error Loading extension section %s\n",
        +								 extensions);
        +					ret = 1;
        +					goto err;
        +					}
        +				}
        +			}
        +
        +		if (startdate == NULL)
        +			{
        +			startdate=NCONF_get_string(conf,section,
        +				ENV_DEFAULT_STARTDATE);
        +			if (startdate == NULL)
        +				ERR_clear_error();
        +			}
        +		if (startdate && !ASN1_TIME_set_string(NULL, startdate))
        +			{
        +			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
        +			goto err;
        +			}
        +		if (startdate == NULL) startdate="today";
        +
        +		if (enddate == NULL)
        +			{
        +			enddate=NCONF_get_string(conf,section,
        +				ENV_DEFAULT_ENDDATE);
        +			if (enddate == NULL)
        +				ERR_clear_error();
        +			}
        +		if (enddate && !ASN1_TIME_set_string(NULL, enddate))
        +			{
        +			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
        +			goto err;
        +			}
        +
        +		if (days == 0)
        +			{
        +			if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
        +				days = 0;
        +			}
        +		if (!enddate && (days == 0))
        +			{
        +			BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
        +			goto err;
        +			}
        +
        +		if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
        +			{
        +			BIO_printf(bio_err,"error while loading serial number\n");
        +			goto err;
        +			}
        +		if (verbose)
        +			{
        +			if (BN_is_zero(serial))
        +				BIO_printf(bio_err,"next serial number is 00\n");
        +			else
        +				{
        +				if ((f=BN_bn2hex(serial)) == NULL) goto err;
        +				BIO_printf(bio_err,"next serial number is %s\n",f);
        +				OPENSSL_free(f);
        +				}
        +			}
        +
        +		if ((attribs=NCONF_get_section(conf,policy)) == NULL)
        +			{
        +			BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
        +			goto err;
        +			}
        +
        +		if ((cert_sk=sk_X509_new_null()) == NULL)
        +			{
        +			BIO_printf(bio_err,"Memory allocation failure\n");
        +			goto err;
        +			}
        +		if (spkac_file != NULL)
        +			{
        +			total++;
        +			j=certify_spkac(&x,spkac_file,pkey,x509,dgst,sigopts,
        +				attribs,db, serial,subj,chtype,multirdn,
        +				email_dn,startdate,enddate,days,extensions,
        +				conf,verbose,certopt,nameopt,default_op,ext_copy);
        +			if (j < 0) goto err;
        +			if (j > 0)
        +				{
        +				total_done++;
        +				BIO_printf(bio_err,"\n");
        +				if (!BN_add_word(serial,1)) goto err;
        +				if (!sk_X509_push(cert_sk,x))
        +					{
        +					BIO_printf(bio_err,"Memory allocation failure\n");
        +					goto err;
        +					}
        +				if (outfile)
        +					{
        +					output_der = 1;
        +					batch = 1;
        +					}
        +				}
        +			}
        +		if (ss_cert_file != NULL)
        +			{
        +			total++;
        +			j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,sigopts,
        +				attribs,
        +				db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
        +				extensions,conf,verbose, certopt, nameopt,
        +				default_op, ext_copy, e);
        +			if (j < 0) goto err;
        +			if (j > 0)
        +				{
        +				total_done++;
        +				BIO_printf(bio_err,"\n");
        +				if (!BN_add_word(serial,1)) goto err;
        +				if (!sk_X509_push(cert_sk,x))
        +					{
        +					BIO_printf(bio_err,"Memory allocation failure\n");
        +					goto err;
        +					}
        +				}
        +			}
        +		if (infile != NULL)
        +			{
        +			total++;
        +			j=certify(&x,infile,pkey,x509p,dgst,sigopts, attribs,db,
        +				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
        +				extensions,conf,verbose, certopt, nameopt,
        +				default_op, ext_copy, selfsign);
        +			if (j < 0) goto err;
        +			if (j > 0)
        +				{
        +				total_done++;
        +				BIO_printf(bio_err,"\n");
        +				if (!BN_add_word(serial,1)) goto err;
        +				if (!sk_X509_push(cert_sk,x))
        +					{
        +					BIO_printf(bio_err,"Memory allocation failure\n");
        +					goto err;
        +					}
        +				}
        +			}
        +		for (i=0; i<argc; i++)
        +			{
        +			total++;
        +			j=certify(&x,argv[i],pkey,x509p,dgst,sigopts,attribs,db,
        +				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
        +				extensions,conf,verbose, certopt, nameopt,
        +				default_op, ext_copy, selfsign);
        +			if (j < 0) goto err;
        +			if (j > 0)
        +				{
        +				total_done++;
        +				BIO_printf(bio_err,"\n");
        +				if (!BN_add_word(serial,1)) goto err;
        +				if (!sk_X509_push(cert_sk,x))
        +					{
        +					BIO_printf(bio_err,"Memory allocation failure\n");
        +					goto err;
        +					}
        +				}
        +			}	
        +		/* we have a stack of newly certified certificates
        +		 * and a data base and serial number that need
        +		 * updating */
        +
        +		if (sk_X509_num(cert_sk) > 0)
        +			{
        +			if (!batch)
        +				{
        +				BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
        +				(void)BIO_flush(bio_err);
        +				buf[0][0]='\0';
        +				if (!fgets(buf[0],10,stdin))
        +					{
        +					BIO_printf(bio_err,"CERTIFICATION CANCELED: I/O error\n"); 
        +					ret=0;
        +					goto err;
        +					}
        +				if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
        +					{
        +					BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
        +					ret=0;
        +					goto err;
        +					}
        +				}
        +
        +			BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
        +
        +			if (!save_serial(serialfile,"new",serial,NULL)) goto err;
        +
        +			if (!save_index(dbfile, "new", db)) goto err;
        +			}
        +	
        +		if (verbose)
        +			BIO_printf(bio_err,"writing new certificates\n");
        +		for (i=0; i<sk_X509_num(cert_sk); i++)
        +			{
        +			int k;
        +			char *n;
        +
        +			x=sk_X509_value(cert_sk,i);
        +
        +			j=x->cert_info->serialNumber->length;
        +			p=(const char *)x->cert_info->serialNumber->data;
        +			
        +			if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
        +				{
        +				BIO_printf(bio_err,"certificate file name too long\n");
        +				goto err;
        +				}
        +
        +			strcpy(buf[2],outdir);
        +
        +#ifndef OPENSSL_SYS_VMS
        +			BUF_strlcat(buf[2],"/",sizeof(buf[2]));
        +#endif
        +
        +			n=(char *)&(buf[2][strlen(buf[2])]);
        +			if (j > 0)
        +				{
        +				for (k=0; k<j; k++)
        +					{
        +					if (n >= &(buf[2][sizeof(buf[2])]))
        +						break;
        +					BIO_snprintf(n,
        +						     &buf[2][0] + sizeof(buf[2]) - n,
        +						     "%02X",(unsigned char)*(p++));
        +					n+=2;
        +					}
        +				}
        +			else
        +				{
        +				*(n++)='0';
        +				*(n++)='0';
        +				}
        +			*(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
        +			*n='\0';
        +			if (verbose)
        +				BIO_printf(bio_err,"writing %s\n",buf[2]);
        +
        +			if (BIO_write_filename(Cout,buf[2]) <= 0)
        +				{
        +				perror(buf[2]);
        +				goto err;
        +				}
        +			write_new_certificate(Cout,x, 0, notext);
        +			write_new_certificate(Sout,x, output_der, notext);
        +			}
        +
        +		if (sk_X509_num(cert_sk))
        +			{
        +			/* Rename the database and the serial file */
        +			if (!rotate_serial(serialfile,"new","old")) goto err;
        +
        +			if (!rotate_index(dbfile,"new","old")) goto err;
        +
        +			BIO_printf(bio_err,"Data Base Updated\n");
        +			}
        +		}
        +	
        +	/*****************************************************************/
        +	if (gencrl)
        +		{
        +		int crl_v2 = 0;
        +		if (!crl_ext)
        +			{
        +			crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
        +			if (!crl_ext)
        +				ERR_clear_error();
        +			}
        +		if (crl_ext)
        +			{
        +			/* Check syntax of file */
        +			X509V3_CTX ctx;
        +			X509V3_set_ctx_test(&ctx);
        +			X509V3_set_nconf(&ctx, conf);
        +			if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
        +				{
        +				BIO_printf(bio_err,
        +				 "Error Loading CRL extension section %s\n",
        +								 crl_ext);
        +				ret = 1;
        +				goto err;
        +				}
        +			}
        +
        +		if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
        +			!= NULL)
        +			if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
        +				{
        +				BIO_printf(bio_err,"error while loading CRL number\n");
        +				goto err;
        +				}
        +
        +		if (!crldays && !crlhours && !crlsec)
        +			{
        +			if (!NCONF_get_number(conf,section,
        +				ENV_DEFAULT_CRL_DAYS, &crldays))
        +				crldays = 0;
        +			if (!NCONF_get_number(conf,section,
        +				ENV_DEFAULT_CRL_HOURS, &crlhours))
        +				crlhours = 0;
        +			ERR_clear_error();
        +			}
        +		if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
        +			{
        +			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
        +			goto err;
        +			}
        +
        +		if (verbose) BIO_printf(bio_err,"making CRL\n");
        +		if ((crl=X509_CRL_new()) == NULL) goto err;
        +		if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
        +
        +		tmptm = ASN1_TIME_new();
        +		if (!tmptm) goto err;
        +		X509_gmtime_adj(tmptm,0);
        +		X509_CRL_set_lastUpdate(crl, tmptm);	
        +		if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec,
        +			NULL))
        +			{
        +			BIO_puts(bio_err, "error setting CRL nextUpdate\n");
        +			goto err;
        +			}
        +		X509_CRL_set_nextUpdate(crl, tmptm);	
        +
        +		ASN1_TIME_free(tmptm);
        +
        +		for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +			{
        +			pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
        +			if (pp[DB_type][0] == DB_TYPE_REV)
        +				{
        +				if ((r=X509_REVOKED_new()) == NULL) goto err;
        +				j = make_revoked(r, pp[DB_rev_date]);
        +				if (!j) goto err;
        +				if (j == 2) crl_v2 = 1;
        +				if (!BN_hex2bn(&serial, pp[DB_serial]))
        +					goto err;
        +				tmpser = BN_to_ASN1_INTEGER(serial, NULL);
        +				BN_free(serial);
        +				serial = NULL;
        +				if (!tmpser)
        +					goto err;
        +				X509_REVOKED_set_serialNumber(r, tmpser);
        +				ASN1_INTEGER_free(tmpser);
        +				X509_CRL_add0_revoked(crl,r);
        +				}
        +			}
        +
        +		/* sort the data so it will be written in serial
        +		 * number order */
        +		X509_CRL_sort(crl);
        +
        +		/* we now have a CRL */
        +		if (verbose) BIO_printf(bio_err,"signing CRL\n");
        +
        +		/* Add any extensions asked for */
        +
        +		if (crl_ext || crlnumberfile != NULL)
        +			{
        +			X509V3_CTX crlctx;
        +			X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
        +			X509V3_set_nconf(&crlctx, conf);
        +
        +			if (crl_ext)
        +				if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
        +					crl_ext, crl)) goto err;
        +			if (crlnumberfile != NULL)
        +				{
        +				tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
        +				if (!tmpser) goto err;
        +				X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
        +				ASN1_INTEGER_free(tmpser);
        +				crl_v2 = 1;
        +				if (!BN_add_word(crlnumber,1)) goto err;
        +				}
        +			}
        +		if (crl_ext || crl_v2)
        +			{
        +			if (!X509_CRL_set_version(crl, 1))
        +				goto err; /* version 2 CRL */
        +			}
        +
        +		
        +		if (crlnumberfile != NULL)	/* we have a CRL number that need updating */
        +			if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
        +
        +		if (crlnumber)
        +			{
        +			BN_free(crlnumber);
        +			crlnumber = NULL;
        +			}
        +
        +		if (!do_X509_CRL_sign(bio_err,crl,pkey,dgst,sigopts)) goto err;
        +
        +		PEM_write_bio_X509_CRL(Sout,crl);
        +
        +		if (crlnumberfile != NULL)	/* Rename the crlnumber file */
        +			if (!rotate_serial(crlnumberfile,"new","old")) goto err;
        +
        +		}
        +	/*****************************************************************/
        +	if (dorevoke)
        +		{
        +		if (infile == NULL) 
        +			{
        +			BIO_printf(bio_err,"no input files\n");
        +			goto err;
        +			}
        +		else
        +			{
        +			X509 *revcert;
        +			revcert=load_cert(bio_err, infile, FORMAT_PEM,
        +				NULL, e, infile);
        +			if (revcert == NULL)
        +				goto err;
        +			j=do_revoke(revcert,db, rev_type, rev_arg);
        +			if (j <= 0) goto err;
        +			X509_free(revcert);
        +
        +			if (!save_index(dbfile, "new", db)) goto err;
        +
        +			if (!rotate_index(dbfile, "new", "old")) goto err;
        +
        +			BIO_printf(bio_err,"Data Base Updated\n"); 
        +			}
        +		}
        +	/*****************************************************************/
        +	ret=0;
        +err:
        +	if(tofree)
        +		OPENSSL_free(tofree);
        +	BIO_free_all(Cout);
        +	BIO_free_all(Sout);
        +	BIO_free_all(out);
        +	BIO_free_all(in);
        +
        +	if (cert_sk)
        +		sk_X509_pop_free(cert_sk,X509_free);
        +
        +	if (ret) ERR_print_errors(bio_err);
        +	app_RAND_write_file(randfile, bio_err);
        +	if (free_key && key)
        +		OPENSSL_free(key);
        +	BN_free(serial);
        +	BN_free(crlnumber);
        +	free_index(db);
        +	if (sigopts)
        +		sk_OPENSSL_STRING_free(sigopts);
        +	EVP_PKEY_free(pkey);
        +	if (x509) X509_free(x509);
        +	X509_CRL_free(crl);
        +	NCONF_free(conf);
        +	NCONF_free(extconf);
        +	OBJ_cleanup();
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static void lookup_fail(const char *name, const char *tag)
        +	{
        +	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
        +	}
        +
        +static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        +	     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
        +	     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
        +	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn,
        +	     int email_dn, char *startdate, char *enddate,
        +	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
        +	     unsigned long certopt, unsigned long nameopt, int default_op,
        +	     int ext_copy, int selfsign)
        +	{
        +	X509_REQ *req=NULL;
        +	BIO *in=NULL;
        +	EVP_PKEY *pktmp=NULL;
        +	int ok= -1,i;
        +
        +	in=BIO_new(BIO_s_file());
        +
        +	if (BIO_read_filename(in,infile) <= 0)
        +		{
        +		perror(infile);
        +		goto err;
        +		}
        +	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
        +		{
        +		BIO_printf(bio_err,"Error reading certificate request in %s\n",
        +			infile);
        +		goto err;
        +		}
        +	if (verbose)
        +		X509_REQ_print(bio_err,req);
        +
        +	BIO_printf(bio_err,"Check that the request matches the signature\n");
        +
        +	if (selfsign && !X509_REQ_check_private_key(req,pkey))
        +		{
        +		BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
        +		ok=0;
        +		goto err;
        +		}
        +	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
        +		{
        +		BIO_printf(bio_err,"error unpacking public key\n");
        +		goto err;
        +		}
        +	i=X509_REQ_verify(req,pktmp);
        +	EVP_PKEY_free(pktmp);
        +	if (i < 0)
        +		{
        +		ok=0;
        +		BIO_printf(bio_err,"Signature verification problems....\n");
        +		goto err;
        +		}
        +	if (i == 0)
        +		{
        +		ok=0;
        +		BIO_printf(bio_err,"Signature did not match the certificate request\n");
        +		goto err;
        +		}
        +	else
        +		BIO_printf(bio_err,"Signature ok\n");
        +
        +	ok=do_body(xret,pkey,x509,dgst,sigopts, policy,db,serial,subj,chtype,
        +		multirdn, email_dn,
        +		startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
        +		certopt, nameopt, default_op, ext_copy, selfsign);
        +
        +err:
        +	if (req != NULL) X509_REQ_free(req);
        +	if (in != NULL) BIO_free(in);
        +	return(ok);
        +	}
        +
        +static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        +	     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
        +	     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
        +	     BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
        +	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
        +	     unsigned long certopt, unsigned long nameopt, int default_op,
        +	     int ext_copy, ENGINE *e)
        +	{
        +	X509 *req=NULL;
        +	X509_REQ *rreq=NULL;
        +	EVP_PKEY *pktmp=NULL;
        +	int ok= -1,i;
        +
        +	if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
        +		goto err;
        +	if (verbose)
        +		X509_print(bio_err,req);
        +
        +	BIO_printf(bio_err,"Check that the request matches the signature\n");
        +
        +	if ((pktmp=X509_get_pubkey(req)) == NULL)
        +		{
        +		BIO_printf(bio_err,"error unpacking public key\n");
        +		goto err;
        +		}
        +	i=X509_verify(req,pktmp);
        +	EVP_PKEY_free(pktmp);
        +	if (i < 0)
        +		{
        +		ok=0;
        +		BIO_printf(bio_err,"Signature verification problems....\n");
        +		goto err;
        +		}
        +	if (i == 0)
        +		{
        +		ok=0;
        +		BIO_printf(bio_err,"Signature did not match the certificate\n");
        +		goto err;
        +		}
        +	else
        +		BIO_printf(bio_err,"Signature ok\n");
        +
        +	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
        +		goto err;
        +
        +	ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
        +		days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
        +		ext_copy, 0);
        +
        +err:
        +	if (rreq != NULL) X509_REQ_free(rreq);
        +	if (req != NULL) X509_free(req);
        +	return(ok);
        +	}
        +
        +static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
        +	     STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy,
        +             CA_DB *db, BIGNUM *serial, char *subj,
        +	     unsigned long chtype, int multirdn,
        +	     int email_dn, char *startdate, char *enddate, long days, int batch,
        +	     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
        +	     unsigned long certopt, unsigned long nameopt, int default_op,
        +	     int ext_copy, int selfsign)
        +	{
        +	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
        +	ASN1_UTCTIME *tm,*tmptm;
        +	ASN1_STRING *str,*str2;
        +	ASN1_OBJECT *obj;
        +	X509 *ret=NULL;
        +	X509_CINF *ci;
        +	X509_NAME_ENTRY *ne;
        +	X509_NAME_ENTRY *tne,*push;
        +	EVP_PKEY *pktmp;
        +	int ok= -1,i,j,last,nid;
        +	const char *p;
        +	CONF_VALUE *cv;
        +	OPENSSL_STRING row[DB_NUMBER];
        +	OPENSSL_STRING *irow=NULL;
        +	OPENSSL_STRING *rrow=NULL;
        +	char buf[25];
        +
        +	tmptm=ASN1_UTCTIME_new();
        +	if (tmptm == NULL)
        +		{
        +		BIO_printf(bio_err,"malloc error\n");
        +		return(0);
        +		}
        +
        +	for (i=0; i<DB_NUMBER; i++)
        +		row[i]=NULL;
        +
        +	if (subj)
        +		{
        +		X509_NAME *n = parse_name(subj, chtype, multirdn);
        +
        +		if (!n)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto err;
        +			}
        +		X509_REQ_set_subject_name(req,n);
        +		req->req_info->enc.modified = 1;
        +		X509_NAME_free(n);
        +		}
        +
        +	if (default_op)
        +		BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
        +
        +	name=X509_REQ_get_subject_name(req);
        +	for (i=0; i<X509_NAME_entry_count(name); i++)
        +		{
        +		ne= X509_NAME_get_entry(name,i);
        +		str=X509_NAME_ENTRY_get_data(ne);
        +		obj=X509_NAME_ENTRY_get_object(ne);
        +
        +		if (msie_hack)
        +			{
        +			/* assume all type should be strings */
        +			nid=OBJ_obj2nid(ne->object);
        +
        +			if (str->type == V_ASN1_UNIVERSALSTRING)
        +				ASN1_UNIVERSALSTRING_to_string(str);
        +
        +			if ((str->type == V_ASN1_IA5STRING) &&
        +				(nid != NID_pkcs9_emailAddress))
        +				str->type=V_ASN1_T61STRING;
        +
        +			if ((nid == NID_pkcs9_emailAddress) &&
        +				(str->type == V_ASN1_PRINTABLESTRING))
        +				str->type=V_ASN1_IA5STRING;
        +			}
        +
        +		/* If no EMAIL is wanted in the subject */
        +		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
        +			continue;
        +
        +		/* check some things */
        +		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
        +			(str->type != V_ASN1_IA5STRING))
        +			{
        +			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
        +			goto err;
        +			}
        +		if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
        +			{
        +			j=ASN1_PRINTABLE_type(str->data,str->length);
        +			if (	((j == V_ASN1_T61STRING) &&
        +				 (str->type != V_ASN1_T61STRING)) ||
        +				((j == V_ASN1_IA5STRING) &&
        +				 (str->type == V_ASN1_PRINTABLESTRING)))
        +				{
        +				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
        +				goto err;
        +				}
        +			}
        +
        +		if (default_op)
        +			old_entry_print(bio_err, obj, str);
        +		}
        +
        +	/* Ok, now we check the 'policy' stuff. */
        +	if ((subject=X509_NAME_new()) == NULL)
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		goto err;
        +		}
        +
        +	/* take a copy of the issuer name before we mess with it. */
        +	if (selfsign)
        +		CAname=X509_NAME_dup(name);
        +	else
        +		CAname=X509_NAME_dup(x509->cert_info->subject);
        +	if (CAname == NULL) goto err;
        +	str=str2=NULL;
        +
        +	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
        +		{
        +		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
        +		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
        +			{
        +			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
        +			goto err;
        +			}
        +		obj=OBJ_nid2obj(j);
        +
        +		last= -1;
        +		for (;;)
        +			{
        +			/* lookup the object in the supplied name list */
        +			j=X509_NAME_get_index_by_OBJ(name,obj,last);
        +			if (j < 0)
        +				{
        +				if (last != -1) break;
        +				tne=NULL;
        +				}
        +			else
        +				{
        +				tne=X509_NAME_get_entry(name,j);
        +				}
        +			last=j;
        +
        +			/* depending on the 'policy', decide what to do. */
        +			push=NULL;
        +			if (strcmp(cv->value,"optional") == 0)
        +				{
        +				if (tne != NULL)
        +					push=tne;
        +				}
        +			else if (strcmp(cv->value,"supplied") == 0)
        +				{
        +				if (tne == NULL)
        +					{
        +					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
        +					goto err;
        +					}
        +				else
        +					push=tne;
        +				}
        +			else if (strcmp(cv->value,"match") == 0)
        +				{
        +				int last2;
        +
        +				if (tne == NULL)
        +					{
        +					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
        +					goto err;
        +					}
        +
        +				last2= -1;
        +
        +again2:
        +				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
        +				if ((j < 0) && (last2 == -1))
        +					{
        +					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
        +					goto err;
        +					}
        +				if (j >= 0)
        +					{
        +					push=X509_NAME_get_entry(CAname,j);
        +					str=X509_NAME_ENTRY_get_data(tne);
        +					str2=X509_NAME_ENTRY_get_data(push);
        +					last2=j;
        +					if (ASN1_STRING_cmp(str,str2) != 0)
        +						goto again2;
        +					}
        +				if (j < 0)
        +					{
        +					BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data));
        +					goto err;
        +					}
        +				}
        +			else
        +				{
        +				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
        +				goto err;
        +				}
        +
        +			if (push != NULL)
        +				{
        +				if (!X509_NAME_add_entry(subject,push, -1, 0))
        +					{
        +					if (push != NULL)
        +						X509_NAME_ENTRY_free(push);
        +					BIO_printf(bio_err,"Memory allocation failure\n");
        +					goto err;
        +					}
        +				}
        +			if (j < 0) break;
        +			}
        +		}
        +
        +	if (preserve)
        +		{
        +		X509_NAME_free(subject);
        +		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
        +		subject=X509_NAME_dup(name);
        +		if (subject == NULL) goto err;
        +		}
        +
        +	if (verbose)
        +		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
        +
        +	/* Build the correct Subject if no e-mail is wanted in the subject */
        +	/* and add it later on because of the method extensions are added (altName) */
        +	 
        +	if (email_dn)
        +		dn_subject = subject;
        +	else
        +		{
        +		X509_NAME_ENTRY *tmpne;
        +		/* Its best to dup the subject DN and then delete any email
        +		 * addresses because this retains its structure.
        +		 */
        +		if (!(dn_subject = X509_NAME_dup(subject)))
        +			{
        +			BIO_printf(bio_err,"Memory allocation failure\n");
        +			goto err;
        +			}
        +		while((i = X509_NAME_get_index_by_NID(dn_subject,
        +					NID_pkcs9_emailAddress, -1)) >= 0)
        +			{
        +			tmpne = X509_NAME_get_entry(dn_subject, i);
        +			X509_NAME_delete_entry(dn_subject, i);
        +			X509_NAME_ENTRY_free(tmpne);
        +			}
        +		}
        +
        +	if (BN_is_zero(serial))
        +		row[DB_serial]=BUF_strdup("00");
        +	else
        +		row[DB_serial]=BN_bn2hex(serial);
        +	if (row[DB_serial] == NULL)
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		goto err;
        +		}
        +
        +	if (db->attributes.unique_subject)
        +		{
        +		OPENSSL_STRING *crow=row;
        +
        +		rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
        +		if (rrow != NULL)
        +			{
        +			BIO_printf(bio_err,
        +				"ERROR:There is already a certificate for %s\n",
        +				row[DB_name]);
        +			}
        +		}
        +	if (rrow == NULL)
        +		{
        +		rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
        +		if (rrow != NULL)
        +			{
        +			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
        +				row[DB_serial]);
        +			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
        +			}
        +		}
        +
        +	if (rrow != NULL)
        +		{
        +		BIO_printf(bio_err,
        +			"The matching entry has the following details\n");
        +		if (rrow[DB_type][0] == 'E')
        +			p="Expired";
        +		else if (rrow[DB_type][0] == 'R')
        +			p="Revoked";
        +		else if (rrow[DB_type][0] == 'V')
        +			p="Valid";
        +		else
        +			p="\ninvalid type, Data base error\n";
        +		BIO_printf(bio_err,"Type	  :%s\n",p);;
        +		if (rrow[DB_type][0] == 'R')
        +			{
        +			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
        +			BIO_printf(bio_err,"Was revoked on:%s\n",p);
        +			}
        +		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
        +		BIO_printf(bio_err,"Expires on    :%s\n",p);
        +		p=rrow[DB_serial]; if (p == NULL) p="undef";
        +		BIO_printf(bio_err,"Serial Number :%s\n",p);
        +		p=rrow[DB_file]; if (p == NULL) p="undef";
        +		BIO_printf(bio_err,"File name     :%s\n",p);
        +		p=rrow[DB_name]; if (p == NULL) p="undef";
        +		BIO_printf(bio_err,"Subject Name  :%s\n",p);
        +		ok= -1; /* This is now a 'bad' error. */
        +		goto err;
        +		}
        +
        +	/* We are now totally happy, lets make and sign the certificate */
        +	if (verbose)
        +		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
        +
        +	if ((ret=X509_new()) == NULL) goto err;
        +	ci=ret->cert_info;
        +
        +#ifdef X509_V3
        +	/* Make it an X509 v3 certificate. */
        +	if (!X509_set_version(ret,2)) goto err;
        +#endif
        +
        +	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
        +		goto err;
        +	if (selfsign)
        +		{
        +		if (!X509_set_issuer_name(ret,subject))
        +			goto err;
        +		}
        +	else
        +		{
        +		if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
        +			goto err;
        +		}
        +
        +	if (strcmp(startdate,"today") == 0)
        +		X509_gmtime_adj(X509_get_notBefore(ret),0);
        +	else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
        +
        +	if (enddate == NULL)
        +		X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
        +	else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
        +
        +	if (!X509_set_subject_name(ret,subject)) goto err;
        +
        +	pktmp=X509_REQ_get_pubkey(req);
        +	i = X509_set_pubkey(ret,pktmp);
        +	EVP_PKEY_free(pktmp);
        +	if (!i) goto err;
        +
        +	/* Lets add the extensions, if there are any */
        +	if (ext_sect)
        +		{
        +		X509V3_CTX ctx;
        +		if (ci->version == NULL)
        +			if ((ci->version=ASN1_INTEGER_new()) == NULL)
        +				goto err;
        +		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
        +
        +		/* Free the current entries if any, there should not
        +		 * be any I believe */
        +		if (ci->extensions != NULL)
        +			sk_X509_EXTENSION_pop_free(ci->extensions,
        +						   X509_EXTENSION_free);
        +
        +		ci->extensions = NULL;
        +
        +		/* Initialize the context structure */
        +		if (selfsign)
        +			X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
        +		else
        +			X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
        +
        +		if (extconf)
        +			{
        +			if (verbose)
        +				BIO_printf(bio_err, "Extra configuration file found\n");
        + 
        +			/* Use the extconf configuration db LHASH */
        +			X509V3_set_nconf(&ctx, extconf);
        + 
        +			/* Test the structure (needed?) */
        +			/* X509V3_set_ctx_test(&ctx); */
        +
        +			/* Adds exts contained in the configuration file */
        +			if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
        +				{
        +				BIO_printf(bio_err,
        +				    "ERROR: adding extensions in section %s\n",
        +								ext_sect);
        +				ERR_print_errors(bio_err);
        +				goto err;
        +				}
        +			if (verbose)
        +				BIO_printf(bio_err, "Successfully added extensions from file.\n");
        +			}
        +		else if (ext_sect)
        +			{
        +			/* We found extensions to be set from config file */
        +			X509V3_set_nconf(&ctx, lconf);
        +
        +			if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
        +				{
        +				BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
        +				ERR_print_errors(bio_err);
        +				goto err;
        +				}
        +
        +			if (verbose) 
        +				BIO_printf(bio_err, "Successfully added extensions from config\n");
        +			}
        +		}
        +
        +	/* Copy extensions from request (if any) */
        +
        +	if (!copy_extensions(ret, req, ext_copy))
        +		{
        +		BIO_printf(bio_err, "ERROR: adding extensions from request\n");
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	/* Set the right value for the noemailDN option */
        +	if( email_dn == 0 )
        +		{
        +		if (!X509_set_subject_name(ret,dn_subject)) goto err;
        +		}
        +
        +	if (!default_op)
        +		{
        +		BIO_printf(bio_err, "Certificate Details:\n");
        +		/* Never print signature details because signature not present */
        +		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
        +		X509_print_ex(bio_err, ret, nameopt, certopt); 
        +		}
        +
        +	BIO_printf(bio_err,"Certificate is to be certified until ");
        +	ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
        +	if (days) BIO_printf(bio_err," (%ld days)",days);
        +	BIO_printf(bio_err, "\n");
        +
        +	if (!batch)
        +		{
        +
        +		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
        +		(void)BIO_flush(bio_err);
        +		buf[0]='\0';
        +		if (!fgets(buf,sizeof(buf)-1,stdin))
        +			{
        +			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
        +			ok=0;
        +			goto err;
        +			}
        +		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
        +			{
        +			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
        +			ok=0;
        +			goto err;
        +			}
        +		}
        +
        +	pktmp=X509_get_pubkey(ret);
        +	if (EVP_PKEY_missing_parameters(pktmp) &&
        +		!EVP_PKEY_missing_parameters(pkey))
        +		EVP_PKEY_copy_parameters(pktmp,pkey);
        +	EVP_PKEY_free(pktmp);
        +
        +	if (!do_X509_sign(bio_err, ret,pkey,dgst, sigopts))
        +		goto err;
        +
        +	/* We now just add it to the database */
        +	row[DB_type]=(char *)OPENSSL_malloc(2);
        +
        +	tm=X509_get_notAfter(ret);
        +	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
        +	memcpy(row[DB_exp_date],tm->data,tm->length);
        +	row[DB_exp_date][tm->length]='\0';
        +
        +	row[DB_rev_date]=NULL;
        +
        +	/* row[DB_serial] done already */
        +	row[DB_file]=(char *)OPENSSL_malloc(8);
        +	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
        +
        +	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
        +		(row[DB_file] == NULL) || (row[DB_name] == NULL))
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		goto err;
        +		}
        +	BUF_strlcpy(row[DB_file],"unknown",8);
        +	row[DB_type][0]='V';
        +	row[DB_type][1]='\0';
        +
        +	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		goto err;
        +		}
        +
        +	for (i=0; i<DB_NUMBER; i++)
        +		{
        +		irow[i]=row[i];
        +		row[i]=NULL;
        +		}
        +	irow[DB_NUMBER]=NULL;
        +
        +	if (!TXT_DB_insert(db->db,irow))
        +		{
        +		BIO_printf(bio_err,"failed to update database\n");
        +		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
        +		goto err;
        +		}
        +	ok=1;
        +err:
        +	for (i=0; i<DB_NUMBER; i++)
        +		if (row[i] != NULL) OPENSSL_free(row[i]);
        +
        +	if (CAname != NULL)
        +		X509_NAME_free(CAname);
        +	if (subject != NULL)
        +		X509_NAME_free(subject);
        +	if ((dn_subject != NULL) && !email_dn)
        +		X509_NAME_free(dn_subject);
        +	if (tmptm != NULL)
        +		ASN1_UTCTIME_free(tmptm);
        +	if (ok <= 0)
        +		{
        +		if (ret != NULL) X509_free(ret);
        +		ret=NULL;
        +		}
        +	else
        +		*xret=ret;
        +	return(ok);
        +	}
        +
        +static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
        +	{
        +
        +	if (output_der)
        +		{
        +		(void)i2d_X509_bio(bp,x);
        +		return;
        +		}
        +#if 0
        +	/* ??? Not needed since X509_print prints all this stuff anyway */
        +	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
        +	BIO_printf(bp,"issuer :%s\n",f);
        +
        +	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
        +	BIO_printf(bp,"subject:%s\n",f);
        +
        +	BIO_puts(bp,"serial :");
        +	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
        +	BIO_puts(bp,"\n\n");
        +#endif
        +	if (!notext)X509_print(bp,x);
        +	PEM_write_bio_X509(bp,x);
        +	}
        +
        +static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        +	     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
        +	     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
        +	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
        +	     long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
        +	     unsigned long nameopt, int default_op, int ext_copy)
        +	{
        +	STACK_OF(CONF_VALUE) *sk=NULL;
        +	LHASH_OF(CONF_VALUE) *parms=NULL;
        +	X509_REQ *req=NULL;
        +	CONF_VALUE *cv=NULL;
        +	NETSCAPE_SPKI *spki = NULL;
        +	X509_REQ_INFO *ri;
        +	char *type,*buf;
        +	EVP_PKEY *pktmp=NULL;
        +	X509_NAME *n=NULL;
        +	X509_NAME_ENTRY *ne=NULL;
        +	int ok= -1,i,j;
        +	long errline;
        +	int nid;
        +
        +	/*
        +	 * Load input file into a hash table.  (This is just an easy
        +	 * way to read and parse the file, then put it into a convenient
        +	 * STACK format).
        +	 */
        +	parms=CONF_load(NULL,infile,&errline);
        +	if (parms == NULL)
        +		{
        +		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	sk=CONF_get_section(parms, "default");
        +	if (sk_CONF_VALUE_num(sk) == 0)
        +		{
        +		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
        +		CONF_free(parms);
        +		goto err;
        +		}
        +
        +	/*
        +	 * Now create a dummy X509 request structure.  We don't actually
        +	 * have an X509 request, but we have many of the components
        +	 * (a public key, various DN components).  The idea is that we
        +	 * put these components into the right X509 request structure
        +	 * and we can use the same code as if you had a real X509 request.
        +	 */
        +	req=X509_REQ_new();
        +	if (req == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	/*
        +	 * Build up the subject name set.
        +	 */
        +	ri=req->req_info;
        +	n = ri->subject;
        +
        +	for (i = 0; ; i++)
        +		{
        +		if (sk_CONF_VALUE_num(sk) <= i) break;
        +
        +		cv=sk_CONF_VALUE_value(sk,i);
        +		type=cv->name;
        +		/* Skip past any leading X. X: X, etc to allow for
        +		 * multiple instances
        +		 */
        +		for (buf = cv->name; *buf ; buf++)
        +			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
        +				{
        +				buf++;
        +				if (*buf) type = buf;
        +				break;
        +				}
        +
        +		buf=cv->value;
        +		if ((nid=OBJ_txt2nid(type)) == NID_undef)
        +			{
        +			if (strcmp(type, "SPKAC") == 0)
        +				{
        +				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
        +				if (spki == NULL)
        +					{
        +					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
        +					ERR_print_errors(bio_err);
        +					goto err;
        +					}
        +				}
        +			continue;
        +			}
        +
        +		if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
        +				(unsigned char *)buf, -1, -1, 0))
        +			goto err;
        +		}
        +	if (spki == NULL)
        +		{
        +		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
        +			infile);
        +		goto err;
        +		}
        +
        +	/*
        +	 * Now extract the key from the SPKI structure.
        +	 */
        +
        +	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
        +
        +	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
        +		{
        +		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
        +		goto err;
        +		}
        +
        +	j = NETSCAPE_SPKI_verify(spki, pktmp);
        +	if (j <= 0)
        +		{
        +		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
        +		goto err;
        +		}
        +	BIO_printf(bio_err,"Signature ok\n");
        +
        +	X509_REQ_set_pubkey(req,pktmp);
        +	EVP_PKEY_free(pktmp);
        +	ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,
        +		   multirdn,email_dn,startdate,enddate, days,1,verbose,req,
        +		   ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0);
        +err:
        +	if (req != NULL) X509_REQ_free(req);
        +	if (parms != NULL) CONF_free(parms);
        +	if (spki != NULL) NETSCAPE_SPKI_free(spki);
        +	if (ne != NULL) X509_NAME_ENTRY_free(ne);
        +
        +	return(ok);
        +	}
        +
        +static int check_time_format(const char *str)
        +	{
        +	return ASN1_TIME_set_string(NULL, str);
        +	}
        +
        +static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
        +	{
        +	ASN1_UTCTIME *tm=NULL;
        +	char *row[DB_NUMBER],**rrow,**irow;
        +	char *rev_str = NULL;
        +	BIGNUM *bn = NULL;
        +	int ok=-1,i;
        +
        +	for (i=0; i<DB_NUMBER; i++)
        +		row[i]=NULL;
        +	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
        +	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
        +	if (!bn)
        +		goto err;
        +	if (BN_is_zero(bn))
        +		row[DB_serial]=BUF_strdup("00");
        +	else
        +		row[DB_serial]=BN_bn2hex(bn);
        +	BN_free(bn);
        +	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		goto err;
        +		}
        +	/* We have to lookup by serial number because name lookup
        +	 * skips revoked certs
        + 	 */
        +	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
        +	if (rrow == NULL)
        +		{
        +		BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
        +
        +		/* We now just add it to the database */
        +		row[DB_type]=(char *)OPENSSL_malloc(2);
        +
        +		tm=X509_get_notAfter(x509);
        +		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
        +		memcpy(row[DB_exp_date],tm->data,tm->length);
        +		row[DB_exp_date][tm->length]='\0';
        +
        +		row[DB_rev_date]=NULL;
        +
        +		/* row[DB_serial] done already */
        +		row[DB_file]=(char *)OPENSSL_malloc(8);
        +
        +		/* row[DB_name] done already */
        +
        +		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
        +			(row[DB_file] == NULL))
        +			{
        +			BIO_printf(bio_err,"Memory allocation failure\n");
        +			goto err;
        +			}
        +		BUF_strlcpy(row[DB_file],"unknown",8);
        +		row[DB_type][0]='V';
        +		row[DB_type][1]='\0';
        +
        +		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
        +			{
        +			BIO_printf(bio_err,"Memory allocation failure\n");
        +			goto err;
        +			}
        +
        +		for (i=0; i<DB_NUMBER; i++)
        +			{
        +			irow[i]=row[i];
        +			row[i]=NULL;
        +			}
        +		irow[DB_NUMBER]=NULL;
        +
        +		if (!TXT_DB_insert(db->db,irow))
        +			{
        +			BIO_printf(bio_err,"failed to update database\n");
        +			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
        +			goto err;
        +			}
        +
        +		/* Revoke Certificate */
        +		ok = do_revoke(x509,db, type, value);
        +
        +		goto err;
        +
        +		}
        +	else if (index_name_cmp_noconst(row, rrow))
        +		{
        +		BIO_printf(bio_err,"ERROR:name does not match %s\n",
        +			   row[DB_name]);
        +		goto err;
        +		}
        +	else if (rrow[DB_type][0]=='R')
        +		{
        +		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
        +			   row[DB_serial]);
        +		goto err;
        +		}
        +	else
        +		{
        +		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
        +		rev_str = make_revocation_str(type, value);
        +		if (!rev_str)
        +			{
        +			BIO_printf(bio_err, "Error in revocation arguments\n");
        +			goto err;
        +			}
        +		rrow[DB_type][0]='R';
        +		rrow[DB_type][1]='\0';
        +		rrow[DB_rev_date] = rev_str;
        +		}
        +	ok=1;
        +err:
        +	for (i=0; i<DB_NUMBER; i++)
        +		{
        +		if (row[i] != NULL) 
        +			OPENSSL_free(row[i]);
        +		}
        +	return(ok);
        +	}
        +
        +static int get_certificate_status(const char *serial, CA_DB *db)
        +	{
        +	char *row[DB_NUMBER],**rrow;
        +	int ok=-1,i;
        +
        +	/* Free Resources */
        +	for (i=0; i<DB_NUMBER; i++)
        +		row[i]=NULL;
        +
        +	/* Malloc needed char spaces */
        +	row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
        +	if (row[DB_serial] == NULL)
        +		{
        +		BIO_printf(bio_err,"Malloc failure\n");
        +		goto err;
        +		}
        +
        +	if (strlen(serial) % 2)
        +		{
        +		/* Set the first char to 0 */;
        +		row[DB_serial][0]='0';
        +
        +		/* Copy String from serial to row[DB_serial] */
        +		memcpy(row[DB_serial]+1, serial, strlen(serial));
        +		row[DB_serial][strlen(serial)+1]='\0';
        +		}
        +	else
        +		{
        +		/* Copy String from serial to row[DB_serial] */
        +		memcpy(row[DB_serial], serial, strlen(serial));
        +		row[DB_serial][strlen(serial)]='\0';
        +		}
        +			
        +	/* Make it Upper Case */
        +	for (i=0; row[DB_serial][i] != '\0'; i++)
        +		row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
        +	
        +
        +	ok=1;
        +
        +	/* Search for the certificate */
        +	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
        +	if (rrow == NULL)
        +		{
        +		BIO_printf(bio_err,"Serial %s not present in db.\n",
        +				 row[DB_serial]);
        +		ok=-1;
        +		goto err;
        +		}
        +	else if (rrow[DB_type][0]=='V')
        +		{
        +		BIO_printf(bio_err,"%s=Valid (%c)\n",
        +			row[DB_serial], rrow[DB_type][0]);
        +		goto err;
        +		}
        +	else if (rrow[DB_type][0]=='R')
        +		{
        +		BIO_printf(bio_err,"%s=Revoked (%c)\n",
        +			row[DB_serial], rrow[DB_type][0]);
        +		goto err;
        +		}
        +	else if (rrow[DB_type][0]=='E')
        +		{
        +		BIO_printf(bio_err,"%s=Expired (%c)\n",
        +			row[DB_serial], rrow[DB_type][0]);
        +		goto err;
        +		}
        +	else if (rrow[DB_type][0]=='S')
        +		{
        +		BIO_printf(bio_err,"%s=Suspended (%c)\n",
        +			row[DB_serial], rrow[DB_type][0]);
        +		goto err;
        +		}
        +	else
        +		{
        +		BIO_printf(bio_err,"%s=Unknown (%c).\n",
        +			row[DB_serial], rrow[DB_type][0]);
        +		ok=-1;
        +		}
        +err:
        +	for (i=0; i<DB_NUMBER; i++)
        +		{
        +		if (row[i] != NULL)
        +			OPENSSL_free(row[i]);
        +		}
        +	return(ok);
        +	}
        +
        +static int do_updatedb (CA_DB *db)
        +	{
        +	ASN1_UTCTIME	*a_tm = NULL;
        +	int i, cnt = 0;
        +	int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
        +	char **rrow, *a_tm_s;
        +
        +	a_tm = ASN1_UTCTIME_new();
        +
        +	/* get actual time and make a string */
        +	a_tm = X509_gmtime_adj(a_tm, 0);
        +	a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
        +	if (a_tm_s == NULL)
        +		{
        +		cnt = -1;
        +		goto err;
        +		}
        +
        +	memcpy(a_tm_s, a_tm->data, a_tm->length);
        +	a_tm_s[a_tm->length] = '\0';
        +
        +	if (strncmp(a_tm_s, "49", 2) <= 0)
        +		a_y2k = 1;
        +	else
        +		a_y2k = 0;
        +
        +	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +		{
        +		rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
        +
        +		if (rrow[DB_type][0] == 'V')
        +		 	{
        +			/* ignore entries that are not valid */
        +			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
        +				db_y2k = 1;
        +			else
        +				db_y2k = 0;
        +
        +			if (db_y2k == a_y2k)
        +				{
        +				/* all on the same y2k side */
        +				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
        +				       	{
        +				       	rrow[DB_type][0]  = 'E';
        +				       	rrow[DB_type][1]  = '\0';
        +	  				cnt++;
        +
        +					BIO_printf(bio_err, "%s=Expired\n",
        +							rrow[DB_serial]);
        +					}
        +				}
        +			else if (db_y2k < a_y2k)
        +				{
        +		  		rrow[DB_type][0]  = 'E';
        +		  		rrow[DB_type][1]  = '\0';
        +	  			cnt++;
        +
        +				BIO_printf(bio_err, "%s=Expired\n",
        +							rrow[DB_serial]);
        +				}
        +
        +			}
        +    		}
        +
        +err:
        +
        +	ASN1_UTCTIME_free(a_tm);
        +	OPENSSL_free(a_tm_s);
        +
        +	return (cnt);
        +	}
        +
        +static const char *crl_reasons[] = {
        +	/* CRL reason strings */
        +	"unspecified",
        +	"keyCompromise",
        +	"CACompromise",
        +	"affiliationChanged",
        +	"superseded", 
        +	"cessationOfOperation",
        +	"certificateHold",
        +	"removeFromCRL",
        +	/* Additional pseudo reasons */
        +	"holdInstruction",
        +	"keyTime",
        +	"CAkeyTime"
        +};
        +
        +#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
        +
        +/* Given revocation information convert to a DB string.
        + * The format of the string is:
        + * revtime[,reason,extra]. Where 'revtime' is the
        + * revocation time (the current time). 'reason' is the
        + * optional CRL reason and 'extra' is any additional
        + * argument
        + */
        +
        +char *make_revocation_str(int rev_type, char *rev_arg)
        +	{
        +	char *other = NULL, *str;
        +	const char *reason = NULL;
        +	ASN1_OBJECT *otmp;
        +	ASN1_UTCTIME *revtm = NULL;
        +	int i;
        +	switch (rev_type)
        +		{
        +	case REV_NONE:
        +		break;
        +
        +	case REV_CRL_REASON:
        +		for (i = 0; i < 8; i++)
        +			{
        +			if (!strcasecmp(rev_arg, crl_reasons[i]))
        +				{
        +				reason = crl_reasons[i];
        +				break;
        +				}
        +			}
        +		if (reason == NULL)
        +			{
        +			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
        +			return NULL;
        +			}
        +		break;
        +
        +	case REV_HOLD:
        +		/* Argument is an OID */
        +
        +		otmp = OBJ_txt2obj(rev_arg, 0);
        +		ASN1_OBJECT_free(otmp);
        +
        +		if (otmp == NULL)
        +			{
        +			BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
        +			return NULL;
        +			}
        +
        +		reason = "holdInstruction";
        +		other = rev_arg;
        +		break;
        +		
        +	case REV_KEY_COMPROMISE:
        +	case REV_CA_COMPROMISE:
        +
        +		/* Argument is the key compromise time  */
        +		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
        +			{	
        +			BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
        +			return NULL;
        +			}
        +		other = rev_arg;
        +		if (rev_type == REV_KEY_COMPROMISE)
        +			reason = "keyTime";
        +		else 
        +			reason = "CAkeyTime";
        +
        +		break;
        +
        +		}
        +
        +	revtm = X509_gmtime_adj(NULL, 0);
        +
        +	i = revtm->length + 1;
        +
        +	if (reason) i += strlen(reason) + 1;
        +	if (other) i += strlen(other) + 1;
        +
        +	str = OPENSSL_malloc(i);
        +
        +	if (!str) return NULL;
        +
        +	BUF_strlcpy(str, (char *)revtm->data, i);
        +	if (reason)
        +		{
        +		BUF_strlcat(str, ",", i);
        +		BUF_strlcat(str, reason, i);
        +		}
        +	if (other)
        +		{
        +		BUF_strlcat(str, ",", i);
        +		BUF_strlcat(str, other, i);
        +		}
        +	ASN1_UTCTIME_free(revtm);
        +	return str;
        +	}
        +
        +/* Convert revocation field to X509_REVOKED entry 
        + * return code:
        + * 0 error
        + * 1 OK
        + * 2 OK and some extensions added (i.e. V2 CRL)
        + */
        +
        +
        +int make_revoked(X509_REVOKED *rev, const char *str)
        +	{
        +	char *tmp = NULL;
        +	int reason_code = -1;
        +	int i, ret = 0;
        +	ASN1_OBJECT *hold = NULL;
        +	ASN1_GENERALIZEDTIME *comp_time = NULL;
        +	ASN1_ENUMERATED *rtmp = NULL;
        +
        +	ASN1_TIME *revDate = NULL;
        +
        +	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
        +
        +	if (i == 0)
        +		goto err;
        +
        +	if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
        +		goto err;
        +
        +	if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
        +		{
        +		rtmp = ASN1_ENUMERATED_new();
        +		if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
        +			goto err;
        +		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
        +			goto err;
        +		}
        +
        +	if (rev && comp_time)
        +		{
        +		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
        +			goto err;
        +		}
        +	if (rev && hold)
        +		{
        +		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
        +			goto err;
        +		}
        +
        +	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
        +		ret = 2;
        +	else ret = 1;
        +
        +	err:
        +
        +	if (tmp) OPENSSL_free(tmp);
        +	ASN1_OBJECT_free(hold);
        +	ASN1_GENERALIZEDTIME_free(comp_time);
        +	ASN1_ENUMERATED_free(rtmp);
        +	ASN1_TIME_free(revDate);
        +
        +	return ret;
        +	}
        +
        +int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
        +	{
        +	char buf[25],*pbuf, *p;
        +	int j;
        +	j=i2a_ASN1_OBJECT(bp,obj);
        +	pbuf=buf;
        +	for (j=22-j; j>0; j--)
        +		*(pbuf++)=' ';
        +	*(pbuf++)=':';
        +	*(pbuf++)='\0';
        +	BIO_puts(bp,buf);
        +
        +	if (str->type == V_ASN1_PRINTABLESTRING)
        +		BIO_printf(bp,"PRINTABLE:'");
        +	else if (str->type == V_ASN1_T61STRING)
        +		BIO_printf(bp,"T61STRING:'");
        +	else if (str->type == V_ASN1_IA5STRING)
        +		BIO_printf(bp,"IA5STRING:'");
        +	else if (str->type == V_ASN1_UNIVERSALSTRING)
        +		BIO_printf(bp,"UNIVERSALSTRING:'");
        +	else
        +		BIO_printf(bp,"ASN.1 %2d:'",str->type);
        +			
        +	p=(char *)str->data;
        +	for (j=str->length; j>0; j--)
        +		{
        +		if ((*p >= ' ') && (*p <= '~'))
        +			BIO_printf(bp,"%c",*p);
        +		else if (*p & 0x80)
        +			BIO_printf(bp,"\\0x%02X",*p);
        +		else if ((unsigned char)*p == 0xf7)
        +			BIO_printf(bp,"^?");
        +		else	BIO_printf(bp,"^%c",*p+'@');
        +		p++;
        +		}
        +	BIO_printf(bp,"'\n");
        +	return 1;
        +	}
        +
        +int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
        +	{
        +	char *tmp = NULL;
        +	char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
        +	int reason_code = -1;
        +	int ret = 0;
        +	unsigned int i;
        +	ASN1_OBJECT *hold = NULL;
        +	ASN1_GENERALIZEDTIME *comp_time = NULL;
        +	tmp = BUF_strdup(str);
        +
        +	p = strchr(tmp, ',');
        +
        +	rtime_str = tmp;
        +
        +	if (p)
        +		{
        +		*p = '\0';
        +		p++;
        +		reason_str = p;
        +		p = strchr(p, ',');
        +		if (p)
        +			{
        +			*p = '\0';
        +			arg_str = p + 1;
        +			}
        +		}
        +
        +	if (prevtm)
        +		{
        +		*prevtm = ASN1_UTCTIME_new();
        +		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
        +			{
        +			BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
        +			goto err;
        +			}
        +		}
        +	if (reason_str)
        +		{
        +		for (i = 0; i < NUM_REASONS; i++)
        +			{
        +			if(!strcasecmp(reason_str, crl_reasons[i]))
        +				{
        +				reason_code = i;
        +				break;
        +				}
        +			}
        +		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
        +			{
        +			BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
        +			goto err;
        +			}
        +
        +		if (reason_code == 7)
        +			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
        +		else if (reason_code == 8)		/* Hold instruction */
        +			{
        +			if (!arg_str)
        +				{	
        +				BIO_printf(bio_err, "missing hold instruction\n");
        +				goto err;
        +				}
        +			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
        +			hold = OBJ_txt2obj(arg_str, 0);
        +
        +			if (!hold)
        +				{
        +				BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
        +				goto err;
        +				}
        +			if (phold) *phold = hold;
        +			}
        +		else if ((reason_code == 9) || (reason_code == 10))
        +			{
        +			if (!arg_str)
        +				{	
        +				BIO_printf(bio_err, "missing compromised time\n");
        +				goto err;
        +				}
        +			comp_time = ASN1_GENERALIZEDTIME_new();
        +			if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
        +				{	
        +				BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
        +				goto err;
        +				}
        +			if (reason_code == 9)
        +				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
        +			else
        +				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
        +			}
        +		}
        +
        +	if (preason) *preason = reason_code;
        +	if (pinvtm) *pinvtm = comp_time;
        +	else ASN1_GENERALIZEDTIME_free(comp_time);
        +
        +	ret = 1;
        +
        +	err:
        +
        +	if (tmp) OPENSSL_free(tmp);
        +	if (!phold) ASN1_OBJECT_free(hold);
        +	if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/apps/cert.pem b/vendor/openssl/openssl/apps/cert.pem
        new file mode 100644
        index 000000000..de4a77ac6
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/cert.pem
        @@ -0,0 +1,11 @@
        +-----BEGIN CERTIFICATE-----
        +MIIBoDCCAUoCAQAwDQYJKoZIhvcNAQEEBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV
        +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD
        +VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw05NzA5MDkwMzQxMjZa
        +Fw05NzEwMDkwMzQxMjZaMF4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
        +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMT
        +DkVyaWMgdGhlIFlvdW5nMFEwCQYFKw4DAgwFAANEAAJBALVEqPODnpI4rShlY8S7
        +tB713JNvabvn6Gned7zylwLLiXQAo/PAT6mfdWPTyCX9RlId/Aroh1ou893BA32Q
        +sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJoX+CpCvFy+JVh9HpSjCpSNKO
        +19raHv98hKAUJuP9HyM+SUsffO6mAIgitUaqW8/wDMePhEC3
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/ciphers.c b/vendor/openssl/openssl/apps/ciphers.c
        new file mode 100644
        index 000000000..5f2b73970
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ciphers.c
        @@ -0,0 +1,231 @@
        +/* apps/ciphers.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +#include "apps.h"
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +#undef PROG
        +#define PROG	ciphers_main
        +
        +static const char *ciphers_usage[]={
        +"usage: ciphers args\n",
        +" -v          - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n",
        +" -V          - even more verbose\n",
        +" -ssl2       - SSL2 mode\n",
        +" -ssl3       - SSL3 mode\n",
        +" -tls1       - TLS1 mode\n",
        +NULL
        +};
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int ret=1,i;
        +	int verbose=0,Verbose=0;
        +	const char **pp;
        +	const char *p;
        +	int badops=0;
        +	SSL_CTX *ctx=NULL;
        +	SSL *ssl=NULL;
        +	char *ciphers=NULL;
        +	const SSL_METHOD *meth=NULL;
        +	STACK_OF(SSL_CIPHER) *sk;
        +	char buf[512];
        +	BIO *STDout=NULL;
        +
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +	meth=SSLv23_server_method();
        +#elif !defined(OPENSSL_NO_SSL3)
        +	meth=SSLv3_server_method();
        +#elif !defined(OPENSSL_NO_SSL2)
        +	meth=SSLv2_server_method();
        +#endif
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +	{
        +	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	STDout = BIO_push(tmpbio, STDout);
        +	}
        +#endif
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if (strcmp(*argv,"-v") == 0)
        +			verbose=1;
        +		else if (strcmp(*argv,"-V") == 0)
        +			verbose=Verbose=1;
        +#ifndef OPENSSL_NO_SSL2
        +		else if (strcmp(*argv,"-ssl2") == 0)
        +			meth=SSLv2_client_method();
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +		else if (strcmp(*argv,"-ssl3") == 0)
        +			meth=SSLv3_client_method();
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +		else if (strcmp(*argv,"-tls1") == 0)
        +			meth=TLSv1_client_method();
        +#endif
        +		else if ((strncmp(*argv,"-h",2) == 0) ||
        +			 (strcmp(*argv,"-?") == 0))
        +			{
        +			badops=1;
        +			break;
        +			}
        +		else
        +			{
        +			ciphers= *argv;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +		for (pp=ciphers_usage; (*pp != NULL); pp++)
        +			BIO_printf(bio_err,"%s",*pp);
        +		goto end;
        +		}
        +
        +	OpenSSL_add_ssl_algorithms();
        +
        +	ctx=SSL_CTX_new(meth);
        +	if (ctx == NULL) goto err;
        +	if (ciphers != NULL) {
        +		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
        +			BIO_printf(bio_err, "Error in cipher list\n");
        +			goto err;
        +		}
        +	}
        +	ssl=SSL_new(ctx);
        +	if (ssl == NULL) goto err;
        +
        +
        +	if (!verbose)
        +		{
        +		for (i=0; ; i++)
        +			{
        +			p=SSL_get_cipher_list(ssl,i);
        +			if (p == NULL) break;
        +			if (i != 0) BIO_printf(STDout,":");
        +			BIO_printf(STDout,"%s",p);
        +			}
        +		BIO_printf(STDout,"\n");
        +		}
        +	else /* verbose */
        +		{
        +		sk=SSL_get_ciphers(ssl);
        +
        +		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
        +			{
        +			SSL_CIPHER *c;
        +
        +			c = sk_SSL_CIPHER_value(sk,i);
        +			
        +			if (Verbose)
        +				{
        +				unsigned long id = SSL_CIPHER_get_id(c);
        +				int id0 = (int)(id >> 24);
        +				int id1 = (int)((id >> 16) & 0xffL);
        +				int id2 = (int)((id >> 8) & 0xffL);
        +				int id3 = (int)(id & 0xffL);
        +				
        +				if ((id & 0xff000000L) == 0x02000000L)
        +					BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */
        +				else if ((id & 0xff000000L) == 0x03000000L)
        +					BIO_printf(STDout, "          0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */
        +				else
        +					BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
        +				}
        +
        +			BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf));
        +			}
        +		}
        +
        +	ret=0;
        +	if (0)
        +		{
        +err:
        +		SSL_load_error_strings();
        +		ERR_print_errors(bio_err);
        +		}
        +end:
        +	if (ctx != NULL) SSL_CTX_free(ctx);
        +	if (ssl != NULL) SSL_free(ssl);
        +	if (STDout != NULL) BIO_free_all(STDout);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/client.pem b/vendor/openssl/openssl/apps/client.pem
        new file mode 100644
        index 000000000..e7a47a73f
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/client.pem
        @@ -0,0 +1,52 @@
        +subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Client Cert
        +issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
        +-----BEGIN CERTIFICATE-----
        +MIID5zCCAs+gAwIBAgIJALnu1NlVpZ6yMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
        +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
        +ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZDELMAkG
        +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
        +RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw
        +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY
        ++yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs
        +lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D
        +nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2
        +x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2
        +bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9
        +AgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJYIZI
        +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
        +BBSZHKyLoTh7Mb409Zn/mK1ceSDAjDAfBgNVHSMEGDAWgBQ2w2yI55X+sL3szj49
        +hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEAD0mL7PtPYgCEuDyOQSbLpeND5hVS
        +curxQdGnrJ6Acrhodb7E9ccATokeb0PLx6HBLQUicxhTZIQ9FbO43YkQcOU6C3BB
        +IlwskqmtN6+VmrQzNolHCDzvxNZs9lYL2VbGPGqVRyjZeHpoAlf9cQr8PgDb4d4b
        +vUx2KAhHQvV2nkmYvKyXcgnRuHggumF87mkxidriGAEFwH4qfOqetUg64WyxP7P2
        +QLipm04SyQa7ONtIApfVXgHcE42Py4/f4arzCzMjKe3VyhGkS7nsT55X/fWgTaRm
        +CQPkO+H94P958WTvQDt77bQ+D3IvYaVvfil8n6HJMOJfFT0LJuSUbpSXJg==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIEpQIBAAKCAQEAtK2p2x0S3C1ajftAc3GaWPsji6scw1k9Sw/XltbLQuDc11/f
        +wwrUiFcje2CB3Ri6yD6+uCA3V12jEc4GdqzirJZhwgIhaTv42vfYBgiUcR9McEGr
        +agFC3yVR3lIbOzhBjmXNp1on46irxnzU4pT+w58IuvYqUBavaEtfRZocFR5NsIOy
        +mRhyNag8htOFK3wmTEYrb0vflFYT6SD47ogYtsd/xWSKS+YFyb7xSusR2Ot6Ktmr
        +MswQE57QYJz+KiRVlnL0cduMBdT52Wm8blaC9mz50PyrzjQ68NyHapCoWDU7pe4x
        +HLtzpXGSDMPuw4miiSwMym/2wReYJv6cFugLPQIDAQABAoIBAAZOyc9MhIwLSU4L
        +p4RgQvM4UVVe8/Id+3XTZ8NsXExJbWxXfIhiqGjaIfL8u4vsgRjcl+v1s/jo2/iT
        +KMab4o4D8gXD7UavQVDjtjb/ta79WL3SjRl2Uc9YjjMkyq6WmDNQeo2NKDdafCTB
        +1uzSJtLNipB8Z53ELPuHJhxX9QMHrMnuha49riQgXZ7buP9iQrHJFhImBjSzbxJx
        +L+TI6rkyLSf9Wi0Pd3L27Ob3QWNfNRYNSeTE+08eSRChkur5W0RuXAcuAICdQlCl
        +LBvWO/LmmvbzCqiDcgy/TliSb6CGGwgiNG7LJZmlkYNj8laGwalNlYZs3UrVv6NO
        +Br2loAECgYEA2kvCvPGj0Dg/6g7WhXDvAkEbcaL1tSeCxBbNH+6HS2UWMWvyTtCn
        +/bbD519QIdkvayy1QjEf32GV/UjUVmlULMLBcDy0DGjtL3+XpIhLKWDNxN1v1/ai
        +1oz23ZJCOgnk6K4qtFtlRS1XtynjA+rBetvYvLP9SKeFrnpzCgaA2r0CgYEA0+KX
        +1ACXDTNH5ySX3kMjSS9xdINf+OOw4CvPHFwbtc9aqk2HePlEsBTz5I/W3rKwXva3
        +NqZ/bRqVVeZB/hHKFywgdUQk2Uc5z/S7Lw70/w1HubNTXGU06Ngb6zOFAo/o/TwZ
        +zTP1BMIKSOB6PAZPS3l+aLO4FRIRotfFhgRHOoECgYEAmiZbqt8cJaJDB/5YYDzC
        +mp3tSk6gIb936Q6M5VqkMYp9pIKsxhk0N8aDCnTU+kIK6SzWBpr3/d9Ecmqmfyq7
        +5SvWO3KyVf0WWK9KH0abhOm2BKm2HBQvI0DB5u8sUx2/hsvOnjPYDISbZ11t0MtK
        +u35Zy89yMYcSsIYJjG/ROCUCgYEAgI2P9G5PNxEP5OtMwOsW84Y3Xat/hPAQFlI+
        +HES+AzbFGWJkeT8zL2nm95tVkFP1sggZ7Kxjz3w7cpx7GX0NkbWSE9O+T51pNASV
        +tN1sQ3p5M+/a+cnlqgfEGJVvc7iAcXQPa3LEi5h2yPR49QYXAgG6cifn3dDSpmwn
        +SUI7PQECgYEApGCIIpSRPLAEHTGmP87RBL1smurhwmy2s/pghkvUkWehtxg0sGHh
        +kuaqDWcskogv+QC0sVdytiLSz8G0DwcEcsHK1Fkyb8A+ayiw6jWJDo2m9+IF4Fww
        +1Te6jFPYDESnbhq7+TLGgHGhtwcu5cnb4vSuYXGXKupZGzoLOBbv1Zw=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/cms.c b/vendor/openssl/openssl/apps/cms.c
        new file mode 100644
        index 000000000..5f77f8fbb
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/cms.c
        @@ -0,0 +1,1397 @@
        +/* apps/cms.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +/* CMS utility function */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +
        +#ifndef OPENSSL_NO_CMS
        +
        +#include <openssl/crypto.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/x509_vfy.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/cms.h>
        +
        +#undef PROG
        +#define PROG cms_main
        +static int save_certs(char *signerfile, STACK_OF(X509) *signers);
        +static int cms_cb(int ok, X509_STORE_CTX *ctx);
        +static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
        +static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
        +						int rr_allorfirst,
        +					STACK_OF(OPENSSL_STRING) *rr_from);
        +
        +#define SMIME_OP	0x10
        +#define SMIME_IP	0x20
        +#define SMIME_SIGNERS	0x40
        +#define SMIME_ENCRYPT		(1 | SMIME_OP)
        +#define SMIME_DECRYPT		(2 | SMIME_IP)
        +#define SMIME_SIGN		(3 | SMIME_OP | SMIME_SIGNERS)
        +#define SMIME_VERIFY		(4 | SMIME_IP)
        +#define SMIME_CMSOUT		(5 | SMIME_IP | SMIME_OP)
        +#define SMIME_RESIGN		(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
        +#define SMIME_DATAOUT		(7 | SMIME_IP)
        +#define SMIME_DATA_CREATE	(8 | SMIME_OP)
        +#define SMIME_DIGEST_VERIFY	(9 | SMIME_IP)
        +#define SMIME_DIGEST_CREATE	(10 | SMIME_OP)
        +#define SMIME_UNCOMPRESS	(11 | SMIME_IP)
        +#define SMIME_COMPRESS		(12 | SMIME_OP)
        +#define SMIME_ENCRYPTED_DECRYPT	(13 | SMIME_IP)
        +#define SMIME_ENCRYPTED_ENCRYPT	(14 | SMIME_OP)
        +#define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
        +#define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)
        +
        +int verify_err = 0;
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int operation = 0;
        +	int ret = 0;
        +	char **args;
        +	const char *inmode = "r", *outmode = "w";
        +	char *infile = NULL, *outfile = NULL, *rctfile = NULL;
        +	char *signerfile = NULL, *recipfile = NULL;
        +	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
        +	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
        +	char *certsoutfile = NULL;
        +	const EVP_CIPHER *cipher = NULL;
        +	CMS_ContentInfo *cms = NULL, *rcms = NULL;
        +	X509_STORE *store = NULL;
        +	X509 *cert = NULL, *recip = NULL, *signer = NULL;
        +	EVP_PKEY *key = NULL;
        +	STACK_OF(X509) *encerts = NULL, *other = NULL;
        +	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
        +	int badarg = 0;
        +	int flags = CMS_DETACHED, noout = 0, print = 0;
        +	int verify_retcode = 0;
        +	int rr_print = 0, rr_allorfirst = -1;
        +	STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
        +	CMS_ReceiptRequest *rr = NULL;
        +	char *to = NULL, *from = NULL, *subject = NULL;
        +	char *CAfile = NULL, *CApath = NULL;
        +	char *passargin = NULL, *passin = NULL;
        +	char *inrand = NULL;
        +	int need_rand = 0;
        +	const EVP_MD *sign_md = NULL;
        +	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
        +        int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	unsigned char *secret_key = NULL, *secret_keyid = NULL;
        +	unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
        +	size_t secret_keylen = 0, secret_keyidlen = 0;
        +
        +	ASN1_OBJECT *econtent_type = NULL;
        +
        +	X509_VERIFY_PARAM *vpm = NULL;
        +
        +	args = argv + 1;
        +	ret = 1;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		{
        +		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
        +		}
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp (*args, "-encrypt"))
        +			operation = SMIME_ENCRYPT;
        +		else if (!strcmp (*args, "-decrypt"))
        +			operation = SMIME_DECRYPT;
        +		else if (!strcmp (*args, "-sign"))
        +			operation = SMIME_SIGN;
        +		else if (!strcmp (*args, "-sign_receipt"))
        +			operation = SMIME_SIGN_RECEIPT;
        +		else if (!strcmp (*args, "-resign"))
        +			operation = SMIME_RESIGN;
        +		else if (!strcmp (*args, "-verify"))
        +			operation = SMIME_VERIFY;
        +		else if (!strcmp (*args, "-verify_retcode"))
        +			verify_retcode = 1;
        +		else if (!strcmp(*args,"-verify_receipt"))
        +			{
        +			operation = SMIME_VERIFY_RECEIPT;
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			rctfile = *args;
        +			}
        +		else if (!strcmp (*args, "-cmsout"))
        +			operation = SMIME_CMSOUT;
        +		else if (!strcmp (*args, "-data_out"))
        +			operation = SMIME_DATAOUT;
        +		else if (!strcmp (*args, "-data_create"))
        +			operation = SMIME_DATA_CREATE;
        +		else if (!strcmp (*args, "-digest_verify"))
        +			operation = SMIME_DIGEST_VERIFY;
        +		else if (!strcmp (*args, "-digest_create"))
        +			operation = SMIME_DIGEST_CREATE;
        +		else if (!strcmp (*args, "-compress"))
        +			operation = SMIME_COMPRESS;
        +		else if (!strcmp (*args, "-uncompress"))
        +			operation = SMIME_UNCOMPRESS;
        +		else if (!strcmp (*args, "-EncryptedData_decrypt"))
        +			operation = SMIME_ENCRYPTED_DECRYPT;
        +		else if (!strcmp (*args, "-EncryptedData_encrypt"))
        +			operation = SMIME_ENCRYPTED_ENCRYPT;
        +#ifndef OPENSSL_NO_DES
        +		else if (!strcmp (*args, "-des3")) 
        +				cipher = EVP_des_ede3_cbc();
        +		else if (!strcmp (*args, "-des")) 
        +				cipher = EVP_des_cbc();
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		else if (!strcmp (*args, "-seed")) 
        +				cipher = EVP_seed_cbc();
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +		else if (!strcmp (*args, "-rc2-40")) 
        +				cipher = EVP_rc2_40_cbc();
        +		else if (!strcmp (*args, "-rc2-128")) 
        +				cipher = EVP_rc2_cbc();
        +		else if (!strcmp (*args, "-rc2-64")) 
        +				cipher = EVP_rc2_64_cbc();
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		else if (!strcmp(*args,"-aes128"))
        +				cipher = EVP_aes_128_cbc();
        +		else if (!strcmp(*args,"-aes192"))
        +				cipher = EVP_aes_192_cbc();
        +		else if (!strcmp(*args,"-aes256"))
        +				cipher = EVP_aes_256_cbc();
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		else if (!strcmp(*args,"-camellia128"))
        +				cipher = EVP_camellia_128_cbc();
        +		else if (!strcmp(*args,"-camellia192"))
        +				cipher = EVP_camellia_192_cbc();
        +		else if (!strcmp(*args,"-camellia256"))
        +				cipher = EVP_camellia_256_cbc();
        +#endif
        +		else if (!strcmp (*args, "-debug_decrypt")) 
        +				flags |= CMS_DEBUG_DECRYPT;
        +		else if (!strcmp (*args, "-text")) 
        +				flags |= CMS_TEXT;
        +		else if (!strcmp (*args, "-nointern")) 
        +				flags |= CMS_NOINTERN;
        +		else if (!strcmp (*args, "-noverify") 
        +			|| !strcmp (*args, "-no_signer_cert_verify")) 
        +				flags |= CMS_NO_SIGNER_CERT_VERIFY;
        +		else if (!strcmp (*args, "-nocerts")) 
        +				flags |= CMS_NOCERTS;
        +		else if (!strcmp (*args, "-noattr")) 
        +				flags |= CMS_NOATTR;
        +		else if (!strcmp (*args, "-nodetach")) 
        +				flags &= ~CMS_DETACHED;
        +		else if (!strcmp (*args, "-nosmimecap"))
        +				flags |= CMS_NOSMIMECAP;
        +		else if (!strcmp (*args, "-binary"))
        +				flags |= CMS_BINARY;
        +		else if (!strcmp (*args, "-keyid"))
        +				flags |= CMS_USE_KEYID;
        +		else if (!strcmp (*args, "-nosigs"))
        +				flags |= CMS_NOSIGS;
        +		else if (!strcmp (*args, "-no_content_verify"))
        +				flags |= CMS_NO_CONTENT_VERIFY;
        +		else if (!strcmp (*args, "-no_attr_verify"))
        +				flags |= CMS_NO_ATTR_VERIFY;
        +		else if (!strcmp (*args, "-stream"))
        +				flags |= CMS_STREAM;
        +		else if (!strcmp (*args, "-indef"))
        +				flags |= CMS_STREAM;
        +		else if (!strcmp (*args, "-noindef"))
        +				flags &= ~CMS_STREAM;
        +		else if (!strcmp (*args, "-nooldmime"))
        +				flags |= CMS_NOOLDMIMETYPE;
        +		else if (!strcmp (*args, "-crlfeol"))
        +				flags |= CMS_CRLFEOL;
        +		else if (!strcmp (*args, "-noout"))
        +				noout = 1;
        +		else if (!strcmp (*args, "-receipt_request_print"))
        +				rr_print = 1;
        +		else if (!strcmp (*args, "-receipt_request_all"))
        +				rr_allorfirst = 0;
        +		else if (!strcmp (*args, "-receipt_request_first"))
        +				rr_allorfirst = 1;
        +		else if (!strcmp(*args,"-receipt_request_from"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			if (!rr_from)
        +				rr_from = sk_OPENSSL_STRING_new_null();
        +			sk_OPENSSL_STRING_push(rr_from, *args);
        +			}
        +		else if (!strcmp(*args,"-receipt_request_to"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			if (!rr_to)
        +				rr_to = sk_OPENSSL_STRING_new_null();
        +			sk_OPENSSL_STRING_push(rr_to, *args);
        +			}
        +		else if (!strcmp (*args, "-print"))
        +				{
        +				noout = 1;
        +				print = 1;
        +				}
        +		else if (!strcmp(*args,"-secretkey"))
        +			{
        +			long ltmp;
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			secret_key = string_to_hex(*args, &ltmp);
        +			if (!secret_key)
        +				{
        +				BIO_printf(bio_err, "Invalid key %s\n", *args);
        +				goto argerr;
        +				}
        +			secret_keylen = (size_t)ltmp;
        +			}
        +		else if (!strcmp(*args,"-secretkeyid"))
        +			{
        +			long ltmp;
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			secret_keyid = string_to_hex(*args, &ltmp);
        +			if (!secret_keyid)
        +				{
        +				BIO_printf(bio_err, "Invalid id %s\n", *args);
        +				goto argerr;
        +				}
        +			secret_keyidlen = (size_t)ltmp;
        +			}
        +		else if (!strcmp(*args,"-pwri_password"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			pwri_pass = (unsigned char *)*args;
        +			}
        +		else if (!strcmp(*args,"-econtent_type"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			econtent_type = OBJ_txt2obj(*args, 0);
        +			if (!econtent_type)
        +				{
        +				BIO_printf(bio_err, "Invalid OID %s\n", *args);
        +				goto argerr;
        +				}
        +			}
        +		else if (!strcmp(*args,"-rand"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			inrand = *args;
        +			need_rand = 1;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (!strcmp(*args,"-engine"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			engine = *++args;
        +			}
        +#endif
        +		else if (!strcmp(*args,"-passin"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			passargin = *++args;
        +			}
        +		else if (!strcmp (*args, "-to"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			to = *++args;
        +			}
        +		else if (!strcmp (*args, "-from"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			from = *++args;
        +			}
        +		else if (!strcmp (*args, "-subject"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			subject = *++args;
        +			}
        +		else if (!strcmp (*args, "-signer"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			/* If previous -signer argument add signer to list */
        +
        +			if (signerfile)
        +				{
        +				if (!sksigners)
        +					sksigners = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(sksigners, signerfile);
        +				if (!keyfile)
        +					keyfile = signerfile;
        +				if (!skkeys)
        +					skkeys = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(skkeys, keyfile);
        +				keyfile = NULL;
        +				}
        +			signerfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-recip"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			recipfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-certsout"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			certsoutfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-md"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			sign_md = EVP_get_digestbyname(*++args);
        +			if (sign_md == NULL)
        +				{
        +				BIO_printf(bio_err, "Unknown digest %s\n",
        +							*args);
        +				goto argerr;
        +				}
        +			}
        +		else if (!strcmp (*args, "-inkey"))
        +			{
        +			if (!args[1])	
        +				goto argerr;
        +			/* If previous -inkey arument add signer to list */
        +			if (keyfile)
        +				{
        +				if (!signerfile)
        +					{
        +					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
        +					goto argerr;
        +					}
        +				if (!sksigners)
        +					sksigners = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(sksigners, signerfile);
        +				signerfile = NULL;
        +				if (!skkeys)
        +					skkeys = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(skkeys, keyfile);
        +				}
        +			keyfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-keyform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			keyform = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-rctform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			rctformat = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-certfile"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			certfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-CAfile"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			CAfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-CApath"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			CApath = *++args;
        +			}
        +		else if (!strcmp (*args, "-in"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			infile = *++args;
        +			}
        +		else if (!strcmp (*args, "-inform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			informat = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-outform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			outformat = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-out"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			outfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-content"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			contfile = *++args;
        +			}
        +		else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
        +			continue;
        +		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
        +			badarg = 1;
        +		args++;
        +		}
        +
        +	if (((rr_allorfirst != -1) || rr_from) && !rr_to)
        +		{
        +		BIO_puts(bio_err, "No Signed Receipts Recipients\n");
        +		goto argerr;
        +		}
        +
        +	if (!(operation & SMIME_SIGNERS)  && (rr_to || rr_from))
        +		{
        +		BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
        +		goto argerr;
        +		}
        +	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
        +		{
        +		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
        +		goto argerr;
        +		}
        +
        +	if (operation & SMIME_SIGNERS)
        +		{
        +		if (keyfile && !signerfile)
        +			{
        +			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
        +			goto argerr;
        +			}
        +		/* Check to see if any final signer needs to be appended */
        +		if (signerfile)
        +			{
        +			if (!sksigners)
        +				sksigners = sk_OPENSSL_STRING_new_null();
        +			sk_OPENSSL_STRING_push(sksigners, signerfile);
        +			if (!skkeys)
        +				skkeys = sk_OPENSSL_STRING_new_null();
        +			if (!keyfile)
        +				keyfile = signerfile;
        +			sk_OPENSSL_STRING_push(skkeys, keyfile);
        +			}
        +		if (!sksigners)
        +			{
        +			BIO_printf(bio_err, "No signer certificate specified\n");
        +			badarg = 1;
        +			}
        +		signerfile = NULL;
        +		keyfile = NULL;
        +		need_rand = 1;
        +		}
        +
        +	else if (operation == SMIME_DECRYPT)
        +		{
        +		if (!recipfile && !keyfile && !secret_key && !pwri_pass)
        +			{
        +			BIO_printf(bio_err, "No recipient certificate or key specified\n");
        +			badarg = 1;
        +			}
        +		}
        +	else if (operation == SMIME_ENCRYPT)
        +		{
        +		if (!*args && !secret_key && !pwri_pass)
        +			{
        +			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
        +			badarg = 1;
        +			}
        +		need_rand = 1;
        +		}
        +	else if (!operation)
        +		badarg = 1;
        +
        +	if (badarg)
        +		{
        +		argerr:
        +		BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n");
        +		BIO_printf (bio_err, "where options are\n");
        +		BIO_printf (bio_err, "-encrypt       encrypt message\n");
        +		BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
        +		BIO_printf (bio_err, "-sign          sign message\n");
        +		BIO_printf (bio_err, "-verify        verify signed message\n");
        +		BIO_printf (bio_err, "-cmsout        output CMS structure\n");
        +#ifndef OPENSSL_NO_DES
        +		BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
        +		BIO_printf (bio_err, "-des           encrypt with DES\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		BIO_printf (bio_err, "-seed          encrypt with SEED\n");
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +		BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
        +		BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
        +		BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
        +		BIO_printf (bio_err, "               encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
        +		BIO_printf (bio_err, "               encrypt PEM output with cbc camellia\n");
        +#endif
        +		BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
        +		BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
        +		BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
        +		BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
        +		BIO_printf (bio_err, "-nodetach      use opaque signing\n");
        +		BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
        +		BIO_printf (bio_err, "-binary        don't translate message to text\n");
        +		BIO_printf (bio_err, "-certfile file other certificates file\n");
        +		BIO_printf (bio_err, "-certsout file certificate output file\n");
        +		BIO_printf (bio_err, "-signer file   signer certificate file\n");
        +		BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
        +		BIO_printf (bio_err, "-keyid         use subject key identifier\n");
        +		BIO_printf (bio_err, "-in file       input file\n");
        +		BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
        +		BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
        +		BIO_printf (bio_err, "-keyform arg   input private key format (PEM or ENGINE)\n");
        +		BIO_printf (bio_err, "-out file      output file\n");
        +		BIO_printf (bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
        +		BIO_printf (bio_err, "-content file  supply or override content for detached signature\n");
        +		BIO_printf (bio_err, "-to addr       to address\n");
        +		BIO_printf (bio_err, "-from ad       from address\n");
        +		BIO_printf (bio_err, "-subject s     subject\n");
        +		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
        +		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
        +		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
        +		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
        +		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf (bio_err, "-engine e      use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf (bio_err, "-passin arg    input file pass phrase source\n");
        +		BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,  "               the random number generator\n");
        +		BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
        +		goto end;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +	if (need_rand)
        +		{
        +		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        +		if (inrand != NULL)
        +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +				app_RAND_load_files(inrand));
        +		}
        +
        +	ret = 2;
        +
        +	if (!(operation & SMIME_SIGNERS))
        +		flags &= ~CMS_DETACHED;
        +
        +	if (operation & SMIME_OP)
        +		{
        +		if (outformat == FORMAT_ASN1)
        +			outmode = "wb";
        +		}
        +	else
        +		{
        +		if (flags & CMS_BINARY)
        +			outmode = "wb";
        +		}
        +
        +	if (operation & SMIME_IP)
        +		{
        +		if (informat == FORMAT_ASN1)
        +			inmode = "rb";
        +		}
        +	else
        +		{
        +		if (flags & CMS_BINARY)
        +			inmode = "rb";
        +		}
        +
        +	if (operation == SMIME_ENCRYPT)
        +		{
        +		if (!cipher)
        +			{
        +#ifndef OPENSSL_NO_DES			
        +			cipher = EVP_des_ede3_cbc();
        +#else
        +			BIO_printf(bio_err, "No cipher selected\n");
        +			goto end;
        +#endif
        +			}
        +
        +		if (secret_key && !secret_keyid)
        +			{
        +			BIO_printf(bio_err, "No secret key id\n");
        +			goto end;
        +			}
        +
        +		if (*args)
        +			encerts = sk_X509_new_null();
        +		while (*args)
        +			{
        +			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
        +				NULL, e, "recipient certificate file")))
        +				goto end;
        +			sk_X509_push(encerts, cert);
        +			cert = NULL;
        +			args++;
        +			}
        +		}
        +
        +	if (certfile)
        +		{
        +		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
        +			e, "certificate file")))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (recipfile && (operation == SMIME_DECRYPT))
        +		{
        +		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
        +			e, "recipient certificate file")))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (operation == SMIME_SIGN_RECEIPT)
        +		{
        +		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL,
        +			e, "receipt signer certificate file")))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (operation == SMIME_DECRYPT)
        +		{
        +		if (!keyfile)
        +			keyfile = recipfile;
        +		}
        +	else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT))
        +		{
        +		if (!keyfile)
        +			keyfile = signerfile;
        +		}
        +	else keyfile = NULL;
        +
        +	if (keyfile)
        +		{
        +		key = load_key(bio_err, keyfile, keyform, 0, passin, e,
        +			       "signing key file");
        +		if (!key)
        +			goto end;
        +		}
        +
        +	if (infile)
        +		{
        +		if (!(in = BIO_new_file(infile, inmode)))
        +			{
        +			BIO_printf (bio_err,
        +				 "Can't open input file %s\n", infile);
        +			goto end;
        +			}
        +		}
        +	else
        +		in = BIO_new_fp(stdin, BIO_NOCLOSE);
        +
        +	if (operation & SMIME_IP)
        +		{
        +		if (informat == FORMAT_SMIME) 
        +			cms = SMIME_read_CMS(in, &indata);
        +		else if (informat == FORMAT_PEM) 
        +			cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
        +		else if (informat == FORMAT_ASN1) 
        +			cms = d2i_CMS_bio(in, NULL);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad input format for CMS file\n");
        +			goto end;
        +			}
        +
        +		if (!cms)
        +			{
        +			BIO_printf(bio_err, "Error reading S/MIME message\n");
        +			goto end;
        +			}
        +		if (contfile)
        +			{
        +			BIO_free(indata);
        +			if (!(indata = BIO_new_file(contfile, "rb")))
        +				{
        +				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
        +				goto end;
        +				}
        +			}
        +		if (certsoutfile)
        +			{
        +			STACK_OF(X509) *allcerts;
        +			allcerts = CMS_get1_certs(cms);
        +			if (!save_certs(certsoutfile, allcerts))
        +				{
        +				BIO_printf(bio_err,
        +						"Error writing certs to %s\n",
        +								certsoutfile);
        +				ret = 5;
        +				goto end;
        +				}
        +			sk_X509_pop_free(allcerts, X509_free);
        +			}
        +		}
        +
        +	if (rctfile)
        +		{
        +		char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
        +		if (!(rctin = BIO_new_file(rctfile, rctmode)))
        +			{
        +			BIO_printf (bio_err,
        +				 "Can't open receipt file %s\n", rctfile);
        +			goto end;
        +			}
        +		
        +		if (rctformat == FORMAT_SMIME) 
        +			rcms = SMIME_read_CMS(rctin, NULL);
        +		else if (rctformat == FORMAT_PEM) 
        +			rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
        +		else if (rctformat == FORMAT_ASN1) 
        +			rcms = d2i_CMS_bio(rctin, NULL);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad input format for receipt\n");
        +			goto end;
        +			}
        +
        +		if (!rcms)
        +			{
        +			BIO_printf(bio_err, "Error reading receipt\n");
        +			goto end;
        +			}
        +		}
        +
        +	if (outfile)
        +		{
        +		if (!(out = BIO_new_file(outfile, outmode)))
        +			{
        +			BIO_printf (bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		    out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +
        +	if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
        +		{
        +		if (!(store = setup_verify(bio_err, CAfile, CApath)))
        +			goto end;
        +		X509_STORE_set_verify_cb(store, cms_cb);
        +		if (vpm)
        +			X509_STORE_set1_param(store, vpm);
        +		}
        +
        +
        +	ret = 3;
        +
        +	if (operation == SMIME_DATA_CREATE)
        +		{
        +		cms = CMS_data_create(in, flags);
        +		}
        +	else if (operation == SMIME_DIGEST_CREATE)
        +		{
        +		cms = CMS_digest_create(in, sign_md, flags);
        +		}
        +	else if (operation == SMIME_COMPRESS)
        +		{
        +		cms = CMS_compress(in, -1, flags);
        +		}
        +	else if (operation == SMIME_ENCRYPT)
        +		{
        +		flags |= CMS_PARTIAL;
        +		cms = CMS_encrypt(encerts, in, cipher, flags);
        +		if (!cms)
        +			goto end;
        +		if (secret_key)
        +			{
        +			if (!CMS_add0_recipient_key(cms, NID_undef, 
        +						secret_key, secret_keylen,
        +						secret_keyid, secret_keyidlen,
        +						NULL, NULL, NULL))
        +				goto end;
        +			/* NULL these because call absorbs them */
        +			secret_key = NULL;
        +			secret_keyid = NULL;
        +			}
        +		if (pwri_pass)
        +			{
        +			pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass);
        +			if (!pwri_tmp)
        +				goto end;
        +			if (!CMS_add0_recipient_password(cms,
        +						-1, NID_undef, NID_undef,
        +						 pwri_tmp, -1, NULL))
        +				goto end;
        +			pwri_tmp = NULL;
        +			}
        +		if (!(flags & CMS_STREAM))
        +			{
        +			if (!CMS_final(cms, in, NULL, flags))
        +				goto end;
        +			}
        +		}
        +	else if (operation == SMIME_ENCRYPTED_ENCRYPT)
        +		{
        +		cms = CMS_EncryptedData_encrypt(in, cipher,
        +						secret_key, secret_keylen,
        +						flags);
        +
        +		}
        +	else if (operation == SMIME_SIGN_RECEIPT)
        +		{
        +		CMS_ContentInfo *srcms = NULL;
        +		STACK_OF(CMS_SignerInfo) *sis;
        +		CMS_SignerInfo *si;
        +		sis = CMS_get0_SignerInfos(cms);
        +		if (!sis)
        +			goto end;
        +		si = sk_CMS_SignerInfo_value(sis, 0);
        +		srcms = CMS_sign_receipt(si, signer, key, other, flags);
        +		if (!srcms)
        +			goto end;
        +		CMS_ContentInfo_free(cms);
        +		cms = srcms;
        +		}
        +	else if (operation & SMIME_SIGNERS)
        +		{
        +		int i;
        +		/* If detached data content we enable streaming if
        +		 * S/MIME output format.
        +		 */
        +		if (operation == SMIME_SIGN)
        +			{
        +				
        +			if (flags & CMS_DETACHED)
        +				{
        +				if (outformat == FORMAT_SMIME)
        +					flags |= CMS_STREAM;
        +				}
        +			flags |= CMS_PARTIAL;
        +			cms = CMS_sign(NULL, NULL, other, in, flags);
        +			if (!cms)
        +				goto end;
        +			if (econtent_type)
        +				CMS_set1_eContentType(cms, econtent_type);
        +
        +			if (rr_to)
        +				{
        +				rr = make_receipt_request(rr_to, rr_allorfirst,
        +								rr_from);
        +				if (!rr)
        +					{
        +					BIO_puts(bio_err,
        +				"Signed Receipt Request Creation Error\n");
        +					goto end;
        +					}
        +				}
        +			}
        +		else
        +			flags |= CMS_REUSE_DIGEST;
        +		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
        +			{
        +			CMS_SignerInfo *si;
        +			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
        +			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
        +			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
        +					e, "signer certificate");
        +			if (!signer)
        +				goto end;
        +			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
        +			       "signing key file");
        +			if (!key)
        +				goto end;
        +			si = CMS_add1_signer(cms, signer, key, sign_md, flags);
        +			if (!si)
        +				goto end;
        +			if (rr && !CMS_add1_ReceiptRequest(si, rr))
        +				goto end;
        +			X509_free(signer);
        +			signer = NULL;
        +			EVP_PKEY_free(key);
        +			key = NULL;
        +			}
        +		/* If not streaming or resigning finalize structure */
        +		if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM))
        +			{
        +			if (!CMS_final(cms, in, NULL, flags))
        +				goto end;
        +			}
        +		}
        +
        +	if (!cms)
        +		{
        +		BIO_printf(bio_err, "Error creating CMS structure\n");
        +		goto end;
        +		}
        +
        +	ret = 4;
        +	if (operation == SMIME_DECRYPT)
        +		{
        +		if (flags & CMS_DEBUG_DECRYPT)
        +			CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
        +
        +		if (secret_key)
        +			{
        +			if (!CMS_decrypt_set1_key(cms,
        +						secret_key, secret_keylen,
        +						secret_keyid, secret_keyidlen))
        +				{
        +				BIO_puts(bio_err,
        +					"Error decrypting CMS using secret key\n");
        +				goto end;
        +				}
        +			}
        +
        +		if (key)
        +			{
        +			if (!CMS_decrypt_set1_pkey(cms, key, recip))
        +				{
        +				BIO_puts(bio_err,
        +					"Error decrypting CMS using private key\n");
        +				goto end;
        +				}
        +			}
        +
        +		if (pwri_pass)
        +			{
        +			if (!CMS_decrypt_set1_password(cms, pwri_pass, -1))
        +				{
        +				BIO_puts(bio_err,
        +					"Error decrypting CMS using password\n");
        +				goto end;
        +				}
        +			}
        +
        +		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
        +			{
        +			BIO_printf(bio_err, "Error decrypting CMS structure\n");
        +			goto end;
        +			}
        +		}
        +	else if (operation == SMIME_DATAOUT)
        +		{
        +		if (!CMS_data(cms, out, flags))
        +			goto end;
        +		}
        +	else if (operation == SMIME_UNCOMPRESS)
        +		{
        +		if (!CMS_uncompress(cms, indata, out, flags))
        +			goto end;
        +		}
        +	else if (operation == SMIME_DIGEST_VERIFY)
        +		{
        +		if (CMS_digest_verify(cms, indata, out, flags) > 0)
        +			BIO_printf(bio_err, "Verification successful\n");
        +		else
        +			{
        +			BIO_printf(bio_err, "Verification failure\n");
        +			goto end;
        +			}
        +		}
        +	else if (operation == SMIME_ENCRYPTED_DECRYPT)
        +		{
        +		if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
        +						indata, out, flags))
        +			goto end;
        +		}
        +	else if (operation == SMIME_VERIFY)
        +		{
        +		if (CMS_verify(cms, other, store, indata, out, flags) > 0)
        +			BIO_printf(bio_err, "Verification successful\n");
        +		else
        +			{
        +			BIO_printf(bio_err, "Verification failure\n");
        +			if (verify_retcode)
        +				ret = verify_err + 32;
        +			goto end;
        +			}
        +		if (signerfile)
        +			{
        +			STACK_OF(X509) *signers;
        +			signers = CMS_get0_signers(cms);
        +			if (!save_certs(signerfile, signers))
        +				{
        +				BIO_printf(bio_err,
        +						"Error writing signers to %s\n",
        +								signerfile);
        +				ret = 5;
        +				goto end;
        +				}
        +			sk_X509_free(signers);
        +			}
        +		if (rr_print)
        +			receipt_request_print(bio_err, cms);
        +					
        +		}
        +	else if (operation == SMIME_VERIFY_RECEIPT)
        +		{
        +		if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
        +			BIO_printf(bio_err, "Verification successful\n");
        +		else
        +			{
        +			BIO_printf(bio_err, "Verification failure\n");
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		if (noout)
        +			{
        +			if (print)
        +				CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
        +			}
        +		else if (outformat == FORMAT_SMIME)
        +			{
        +			if (to)
        +				BIO_printf(out, "To: %s\n", to);
        +			if (from)
        +				BIO_printf(out, "From: %s\n", from);
        +			if (subject)
        +				BIO_printf(out, "Subject: %s\n", subject);
        +			if (operation == SMIME_RESIGN)
        +				ret = SMIME_write_CMS(out, cms, indata, flags);
        +			else
        +				ret = SMIME_write_CMS(out, cms, in, flags);
        +			}
        +		else if (outformat == FORMAT_PEM) 
        +			ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
        +		else if (outformat == FORMAT_ASN1) 
        +			ret = i2d_CMS_bio_stream(out,cms, in, flags);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad output format for CMS file\n");
        +			goto end;
        +			}
        +		if (ret <= 0)
        +			{
        +			ret = 6;
        +			goto end;
        +			}
        +		}
        +	ret = 0;
        +end:
        +	if (ret)
        +		ERR_print_errors(bio_err);
        +	if (need_rand)
        +		app_RAND_write_file(NULL, bio_err);
        +	sk_X509_pop_free(encerts, X509_free);
        +	sk_X509_pop_free(other, X509_free);
        +	if (vpm)
        +		X509_VERIFY_PARAM_free(vpm);
        +	if (sksigners)
        +		sk_OPENSSL_STRING_free(sksigners);
        +	if (skkeys)
        +		sk_OPENSSL_STRING_free(skkeys);
        +	if (secret_key)
        +		OPENSSL_free(secret_key);
        +	if (secret_keyid)
        +		OPENSSL_free(secret_keyid);
        +	if (pwri_tmp)
        +		OPENSSL_free(pwri_tmp);
        +	if (econtent_type)
        +		ASN1_OBJECT_free(econtent_type);
        +	if (rr)
        +		CMS_ReceiptRequest_free(rr);
        +	if (rr_to)
        +		sk_OPENSSL_STRING_free(rr_to);
        +	if (rr_from)
        +		sk_OPENSSL_STRING_free(rr_from);
        +	X509_STORE_free(store);
        +	X509_free(cert);
        +	X509_free(recip);
        +	X509_free(signer);
        +	EVP_PKEY_free(key);
        +	CMS_ContentInfo_free(cms);
        +	CMS_ContentInfo_free(rcms);
        +	BIO_free(rctin);
        +	BIO_free(in);
        +	BIO_free(indata);
        +	BIO_free_all(out);
        +	if (passin) OPENSSL_free(passin);
        +	return (ret);
        +}
        +
        +static int save_certs(char *signerfile, STACK_OF(X509) *signers)
        +	{
        +	int i;
        +	BIO *tmp;
        +	if (!signerfile)
        +		return 1;
        +	tmp = BIO_new_file(signerfile, "w");
        +	if (!tmp) return 0;
        +	for(i = 0; i < sk_X509_num(signers); i++)
        +		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
        +	BIO_free(tmp);
        +	return 1;
        +	}
        +	
        +
        +/* Minimal callback just to output policy info (if any) */
        +
        +static int cms_cb(int ok, X509_STORE_CTX *ctx)
        +	{
        +	int error;
        +
        +	error = X509_STORE_CTX_get_error(ctx);
        +
        +	verify_err = error;
        +
        +	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
        +		&& ((error != X509_V_OK) || (ok != 2)))
        +		return ok;
        +
        +	policies_print(NULL, ctx);
        +
        +	return ok;
        +
        +	}
        +
        +static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
        +	{
        +	STACK_OF(GENERAL_NAME) *gens;
        +	GENERAL_NAME *gen;
        +	int i, j;
        +	for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++)
        +		{
        +		gens = sk_GENERAL_NAMES_value(gns, i);
        +		for (j = 0; j < sk_GENERAL_NAME_num(gens); j++)
        +			{
        +			gen = sk_GENERAL_NAME_value(gens, j);
        +			BIO_puts(out, "    ");
        +			GENERAL_NAME_print(out, gen);
        +			BIO_puts(out, "\n");
        +			}
        +		}
        +	return;
        +	}
        +
        +static void receipt_request_print(BIO *out, CMS_ContentInfo *cms)
        +	{
        +	STACK_OF(CMS_SignerInfo) *sis;
        +	CMS_SignerInfo *si;
        +	CMS_ReceiptRequest *rr;
        +	int allorfirst;
        +	STACK_OF(GENERAL_NAMES) *rto, *rlist;
        +	ASN1_STRING *scid;
        +	int i, rv;
        +	sis = CMS_get0_SignerInfos(cms);
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++)
        +		{
        +		si = sk_CMS_SignerInfo_value(sis, i);
        +		rv = CMS_get1_ReceiptRequest(si, &rr);
        +		BIO_printf(bio_err, "Signer %d:\n", i + 1);
        +		if (rv == 0)
        +			BIO_puts(bio_err, "  No Receipt Request\n");
        +		else if (rv < 0)
        +			{
        +			BIO_puts(bio_err, "  Receipt Request Parse Error\n");
        +			ERR_print_errors(bio_err);
        +			}
        +		else
        +			{
        +			char *id;
        +			int idlen;
        +			CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
        +							&rlist, &rto);
        +			BIO_puts(out, "  Signed Content ID:\n");
        +			idlen = ASN1_STRING_length(scid);
        +			id = (char *)ASN1_STRING_data(scid);
        +			BIO_dump_indent(out, id, idlen, 4);
        +			BIO_puts(out, "  Receipts From");
        +			if (rlist)
        +				{
        +				BIO_puts(out, " List:\n");
        +				gnames_stack_print(out, rlist);
        +				}
        +			else if (allorfirst == 1)
        +				BIO_puts(out, ": First Tier\n");
        +			else if (allorfirst == 0)
        +				BIO_puts(out, ": All\n");
        +			else
        +				BIO_printf(out, " Unknown (%d)\n", allorfirst);
        +			BIO_puts(out, "  Receipts To:\n");
        +			gnames_stack_print(out, rto);
        +			}
        +		if (rr)
        +			CMS_ReceiptRequest_free(rr);
        +		}
        +	}
        +
        +static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
        +	{
        +	int i;
        +	STACK_OF(GENERAL_NAMES) *ret;
        +	GENERAL_NAMES *gens = NULL;
        +	GENERAL_NAME *gen = NULL;
        +	ret = sk_GENERAL_NAMES_new_null();
        +	if (!ret)
        +		goto err;
        +	for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++)
        +		{
        +		char *str = sk_OPENSSL_STRING_value(ns, i);
        +		gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
        +		if (!gen)
        +			goto err;
        +		gens = GENERAL_NAMES_new();
        +		if (!gens)
        +			goto err;
        +		if (!sk_GENERAL_NAME_push(gens, gen))
        +			goto err;
        +		gen = NULL;
        +		if (!sk_GENERAL_NAMES_push(ret, gens))
        +			goto err;
        +		gens = NULL;
        +		}
        +
        +	return ret;
        +
        +	err:
        +	if (ret)
        +		sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
        +	if (gens)
        +		GENERAL_NAMES_free(gens);
        +	if (gen)
        +		GENERAL_NAME_free(gen);
        +	return NULL;
        +	}
        +
        +
        +static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
        +						int rr_allorfirst,
        +						STACK_OF(OPENSSL_STRING) *rr_from)
        +	{
        +	STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
        +	CMS_ReceiptRequest *rr;
        +	rct_to = make_names_stack(rr_to);
        +	if (!rct_to)
        +		goto err;
        +	if (rr_from)
        +		{
        +		rct_from = make_names_stack(rr_from);
        +		if (!rct_from)
        +			goto err;
        +		}
        +	else
        +		rct_from = NULL;
        +	rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
        +						rct_to);
        +	return rr;
        +	err:
        +	return NULL;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/crl.c b/vendor/openssl/openssl/apps/crl.c
        new file mode 100644
        index 000000000..c395b2afd
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/crl.c
        @@ -0,0 +1,446 @@
        +/* apps/crl.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	crl_main
        +
        +#undef POSTFIX
        +#define	POSTFIX	".rvk"
        +
        +static const char *crl_usage[]={
        +"usage: crl args\n",
        +"\n",
        +" -inform arg     - input format - default PEM (DER or PEM)\n",
        +" -outform arg    - output format - default PEM\n",
        +" -text           - print out a text format version\n",
        +" -in arg         - input file - default stdin\n",
        +" -out arg        - output file - default stdout\n",
        +" -hash           - print hash value\n",
        +" -fingerprint    - print the crl fingerprint\n",
        +" -issuer         - print issuer DN\n",
        +" -lastupdate     - lastUpdate field\n",
        +" -nextupdate     - nextUpdate field\n",
        +" -crlnumber      - print CRL number\n",
        +" -noout          - no CRL output\n",
        +" -CAfile  name   - verify CRL using certificates in file \"name\"\n",
        +" -CApath  dir    - verify CRL using certificates in \"dir\"\n",
        +" -nameopt arg    - various certificate name options\n",
        +NULL
        +};
        +
        +static X509_CRL *load_crl(char *file, int format);
        +static BIO *bio_out=NULL;
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	unsigned long nmflag = 0;
        +	X509_CRL *x=NULL;
        +	char *CAfile = NULL, *CApath = NULL;
        +	int ret=1,i,num,badops=0;
        +	BIO *out=NULL;
        +	int informat,outformat;
        +	char *infile=NULL,*outfile=NULL;
        +	int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
        +	int fingerprint = 0, crlnumber = 0;
        +	const char **pp;
        +	X509_STORE *store = NULL;
        +	X509_STORE_CTX ctx;
        +	X509_LOOKUP *lookup = NULL;
        +	X509_OBJECT xobj;
        +	EVP_PKEY *pkey;
        +	int do_ver = 0;
        +	const EVP_MD *md_alg,*digest=EVP_sha1();
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	if (bio_out == NULL)
        +		if ((bio_out=BIO_new(BIO_s_file())) != NULL)
        +			{
        +			BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			bio_out = BIO_push(tmpbio, bio_out);
        +			}
        +#endif
        +			}
        +
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	argc--;
        +	argv++;
        +	num=0;
        +	while (argc >= 1)
        +		{
        +#ifdef undef
        +		if	(strcmp(*argv,"-p") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
        +			}
        +#endif
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-CApath") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CApath = *(++argv);
        +			do_ver = 1;
        +			}
        +		else if (strcmp(*argv,"-CAfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile = *(++argv);
        +			do_ver = 1;
        +			}
        +		else if (strcmp(*argv,"-verify") == 0)
        +			do_ver = 1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text = 1;
        +		else if (strcmp(*argv,"-hash") == 0)
        +			hash= ++num;
        +		else if (strcmp(*argv,"-nameopt") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
        +			}
        +		else if (strcmp(*argv,"-issuer") == 0)
        +			issuer= ++num;
        +		else if (strcmp(*argv,"-lastupdate") == 0)
        +			lastupdate= ++num;
        +		else if (strcmp(*argv,"-nextupdate") == 0)
        +			nextupdate= ++num;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout= ++num;
        +		else if (strcmp(*argv,"-fingerprint") == 0)
        +			fingerprint= ++num;
        +		else if (strcmp(*argv,"-crlnumber") == 0)
        +			crlnumber= ++num;
        +		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
        +			{
        +			/* ok */
        +			digest=md_alg;
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		for (pp=crl_usage; (*pp != NULL); pp++)
        +			BIO_printf(bio_err,"%s",*pp);
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +	x=load_crl(infile,informat);
        +	if (x == NULL) { goto end; }
        +
        +	if(do_ver) {
        +		store = X509_STORE_new();
        +		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
        +		if (lookup == NULL) goto end;
        +		if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
        +			X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
        +			
        +		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
        +		if (lookup == NULL) goto end;
        +		if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
        +			X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
        +		ERR_clear_error();
        +
        +		if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
        +			BIO_printf(bio_err,
        +				"Error initialising X509 store\n");
        +			goto end;
        +		}
        +
        +		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, 
        +					X509_CRL_get_issuer(x), &xobj);
        +		if(i <= 0) {
        +			BIO_printf(bio_err,
        +				"Error getting CRL issuer certificate\n");
        +			goto end;
        +		}
        +		pkey = X509_get_pubkey(xobj.data.x509);
        +		X509_OBJECT_free_contents(&xobj);
        +		if(!pkey) {
        +			BIO_printf(bio_err,
        +				"Error getting CRL issuer public key\n");
        +			goto end;
        +		}
        +		i = X509_CRL_verify(x, pkey);
        +		EVP_PKEY_free(pkey);
        +		if(i < 0) goto end;
        +		if(i == 0) BIO_printf(bio_err, "verify failure\n");
        +		else BIO_printf(bio_err, "verify OK\n");
        +	}
        +
        +	if (num)
        +		{
        +		for (i=1; i<=num; i++)
        +			{
        +			if (issuer == i)
        +				{
        +				print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
        +				}
        +			if (crlnumber == i)
        +				{
        +				ASN1_INTEGER *crlnum;
        +				crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number,
        +							      NULL, NULL);
        +				BIO_printf(bio_out,"crlNumber=");
        +				if (crlnum)
        +					{
        +					i2a_ASN1_INTEGER(bio_out, crlnum);
        +					ASN1_INTEGER_free(crlnum);
        +					}
        +				else
        +					BIO_puts(bio_out, "<NONE>");
        +				BIO_printf(bio_out,"\n");
        +				}
        +			if (hash == i)
        +				{
        +				BIO_printf(bio_out,"%08lx\n",
        +					X509_NAME_hash(X509_CRL_get_issuer(x)));
        +				}
        +			if (lastupdate == i)
        +				{
        +				BIO_printf(bio_out,"lastUpdate=");
        +				ASN1_TIME_print(bio_out,
        +						X509_CRL_get_lastUpdate(x));
        +				BIO_printf(bio_out,"\n");
        +				}
        +			if (nextupdate == i)
        +				{
        +				BIO_printf(bio_out,"nextUpdate=");
        +				if (X509_CRL_get_nextUpdate(x)) 
        +					ASN1_TIME_print(bio_out,
        +						X509_CRL_get_nextUpdate(x));
        +				else
        +					BIO_printf(bio_out,"NONE");
        +				BIO_printf(bio_out,"\n");
        +				}
        +			if (fingerprint == i)
        +				{
        +				int j;
        +				unsigned int n;
        +				unsigned char md[EVP_MAX_MD_SIZE];
        +
        +				if (!X509_CRL_digest(x,digest,md,&n))
        +					{
        +					BIO_printf(bio_err,"out of memory\n");
        +					goto end;
        +					}
        +				BIO_printf(bio_out,"%s Fingerprint=",
        +						OBJ_nid2sn(EVP_MD_type(digest)));
        +				for (j=0; j<(int)n; j++)
        +					{
        +					BIO_printf(bio_out,"%02X%c",md[j],
        +						(j+1 == (int)n)
        +						?'\n':':');
        +					}
        +				}
        +			}
        +		}
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (text) X509_CRL_print(out, x);
        +
        +	if (noout) 
        +		{
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	if 	(outformat == FORMAT_ASN1)
        +		i=(int)i2d_X509_CRL_bio(out,x);
        +	else if (outformat == FORMAT_PEM)
        +		i=PEM_write_bio_X509_CRL(out,x);
        +	else	
        +		{
        +		BIO_printf(bio_err,"bad output format specified for outfile\n");
        +		goto end;
        +		}
        +	if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
        +	ret=0;
        +end:
        +	BIO_free_all(out);
        +	BIO_free_all(bio_out);
        +	bio_out=NULL;
        +	X509_CRL_free(x);
        +	if(store) {
        +		X509_STORE_CTX_cleanup(&ctx);
        +		X509_STORE_free(store);
        +	}
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static X509_CRL *load_crl(char *infile, int format)
        +	{
        +	X509_CRL *x=NULL;
        +	BIO *in=NULL;
        +
        +	in=BIO_new(BIO_s_file());
        +	if (in == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +	if 	(format == FORMAT_ASN1)
        +		x=d2i_X509_CRL_bio(in,NULL);
        +	else if (format == FORMAT_PEM)
        +		x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
        +	else	{
        +		BIO_printf(bio_err,"bad input format specified for input crl\n");
        +		goto end;
        +		}
        +	if (x == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load CRL\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	
        +end:
        +	BIO_free(in);
        +	return(x);
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/crl2p7.c b/vendor/openssl/openssl/apps/crl2p7.c
        new file mode 100644
        index 000000000..bbc83774d
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/crl2p7.c
        @@ -0,0 +1,337 @@
        +/* apps/crl2p7.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.]
        + */
        +
        +/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
        + * and donated 'to the cause' along with lots and lots of other fixes to
        + * the library. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include "apps.h"
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/pem.h>
        +#include <openssl/objects.h>
        +
        +static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile);
        +#undef PROG
        +#define PROG	crl2pkcs7_main
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int i,badops=0;
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat;
        +	char *infile,*outfile,*prog,*certfile;
        +	PKCS7 *p7 = NULL;
        +	PKCS7_SIGNED *p7s = NULL;
        +	X509_CRL *crl=NULL;
        +	STACK_OF(OPENSSL_STRING) *certflst=NULL;
        +	STACK_OF(X509_CRL) *crl_stack=NULL;
        +	STACK_OF(X509) *cert_stack=NULL;
        +	int ret=1,nocrl=0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-nocrl") == 0)
        +			{
        +			nocrl=1;
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-certfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if(!certflst) certflst = sk_OPENSSL_STRING_new_null();
        +			sk_OPENSSL_STRING_push(certflst,*(++argv));
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
        +		BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
        +		BIO_printf(bio_err," -in arg        input file\n");
        +		BIO_printf(bio_err," -out arg       output file\n");
        +		BIO_printf(bio_err," -certfile arg  certificates file of chain to a trusted CA\n");
        +		BIO_printf(bio_err,"                (can be used more than once)\n");
        +		BIO_printf(bio_err," -nocrl         no crl to load, just certs from '-certfile'\n");
        +		ret = 1;
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (!nocrl)
        +		{
        +		if (infile == NULL)
        +			BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +		else
        +			{
        +			if (BIO_read_filename(in,infile) <= 0)
        +				{
        +				perror(infile);
        +				goto end;
        +				}
        +			}
        +
        +		if 	(informat == FORMAT_ASN1)
        +			crl=d2i_X509_CRL_bio(in,NULL);
        +		else if (informat == FORMAT_PEM)
        +			crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
        +		else	{
        +			BIO_printf(bio_err,"bad input format specified for input crl\n");
        +			goto end;
        +			}
        +		if (crl == NULL)
        +			{
        +			BIO_printf(bio_err,"unable to load CRL\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	
        +	if ((p7=PKCS7_new()) == NULL) goto end;
        +	if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;
        +	p7->type=OBJ_nid2obj(NID_pkcs7_signed);
        +	p7->d.sign=p7s;
        +	p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);
        +
        +	if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
        +	if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
        +	p7s->crl=crl_stack;
        +	if (crl != NULL)
        +		{
        +		sk_X509_CRL_push(crl_stack,crl);
        +		crl=NULL; /* now part of p7 for OPENSSL_freeing */
        +		}
        +
        +	if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
        +	p7s->cert=cert_stack;
        +
        +	if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
        +		certfile = sk_OPENSSL_STRING_value(certflst, i);
        +		if (add_certs_from_file(cert_stack,certfile) < 0)
        +			{
        +			BIO_printf(bio_err, "error loading certificates\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +	}
        +
        +	sk_OPENSSL_STRING_free(certflst);
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if 	(outformat == FORMAT_ASN1)
        +		i=i2d_PKCS7_bio(out,p7);
        +	else if (outformat == FORMAT_PEM)
        +		i=PEM_write_bio_PKCS7(out,p7);
        +	else	{
        +		BIO_printf(bio_err,"bad output format specified for outfile\n");
        +		goto end;
        +		}
        +	if (!i)
        +		{
        +		BIO_printf(bio_err,"unable to write pkcs7 object\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	ret=0;
        +end:
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (p7 != NULL) PKCS7_free(p7);
        +	if (crl != NULL) X509_CRL_free(crl);
        +
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +/*
        + *----------------------------------------------------------------------
        + * int add_certs_from_file
        + *
        + *	Read a list of certificates to be checked from a file.
        + *
        + * Results:
        + *	number of certs added if successful, -1 if not.
        + *----------------------------------------------------------------------
        + */
        +static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
        +	{
        +	BIO *in=NULL;
        +	int count=0;
        +	int ret= -1;
        +	STACK_OF(X509_INFO) *sk=NULL;
        +	X509_INFO *xi;
        +
        +	in=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0))
        +		{
        +		BIO_printf(bio_err,"error opening the file, %s\n",certfile);
        +		goto end;
        +		}
        +
        +	/* This loads from a file, a stack of x509/crl/pkey sets */
        +	sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL);
        +	if (sk == NULL) {
        +		BIO_printf(bio_err,"error reading the file, %s\n",certfile);
        +		goto end;
        +	}
        +
        +	/* scan over it and pull out the CRL's */
        +	while (sk_X509_INFO_num(sk))
        +		{
        +		xi=sk_X509_INFO_shift(sk);
        +		if (xi->x509 != NULL)
        +			{
        +			sk_X509_push(stack,xi->x509);
        +			xi->x509=NULL;
        +			count++;
        +			}
        +		X509_INFO_free(xi);
        +		}
        +
        +	ret=count;
        +end:
        + 	/* never need to OPENSSL_free x */
        +	if (in != NULL) BIO_free(in);
        +	if (sk != NULL) sk_X509_INFO_free(sk);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/demoCA/cacert.pem b/vendor/openssl/openssl/apps/demoCA/cacert.pem
        new file mode 100644
        index 000000000..affbce3bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/demoCA/cacert.pem
        @@ -0,0 +1,14 @@
        +subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +-----BEGIN X509 CERTIFICATE-----
        +
        +MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
        +BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
        +MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
        +RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
        +BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
        +LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
        +/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
        +DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
        +IMs6ZOZB
        +-----END X509 CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/demoCA/index.txt b/vendor/openssl/openssl/apps/demoCA/index.txt
        new file mode 100644
        index 000000000..2cdd252d6
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/demoCA/index.txt
        @@ -0,0 +1,39 @@
        +R	980705233205Z	951009233205Z	01	certs/00000001	/CN=Eric Young
        +E	951009233205Z		02	certs/00000002	/CN=Duncan Young
        +R	980705233205Z	951201010000Z	03	certs/00000003	/CN=Tim Hudson
        +V	980705233205Z		04	certs/00000004	/CN=Eric Young4
        +V	980705233205Z		05	certs/00000004	/CN=Eric Young5
        +V	980705233205Z		06	certs/00000004	/CN=Eric Young6
        +V	980705233205Z		07	certs/00000004	/CN=Eric Young7
        +V	980705233205Z		08	certs/00000004	/CN=Eric Young8
        +V	980705233205Z		09	certs/00000004	/CN=Eric Young9
        +V	980705233205Z		0A	certs/00000004	/CN=Eric YoungA
        +V	980705233205Z		0B	certs/00000004	/CN=Eric YoungB
        +V	980705233205Z		0C	certs/00000004	/CN=Eric YoungC
        +V	980705233205Z		0D	certs/00000004	/CN=Eric YoungD
        +V	980705233205Z		0E	certs/00000004	/CN=Eric YoungE
        +V	980705233205Z		0F	certs/00000004	/CN=Eric YoungF
        +V	980705233205Z		10	certs/00000004	/CN=Eric Young10
        +V	980705233205Z		11	certs/00000004	/CN=Eric Young11
        +V	980705233205Z		12	certs/00000004	/CN=Eric Young12
        +V	980705233205Z		13	certs/00000004	/CN=Eric Young13
        +V	980705233205Z		14	certs/00000004	/CN=Eric Young14
        +V	980705233205Z		15	certs/00000004	/CN=Eric Young15
        +V	980705233205Z		16	certs/00000004	/CN=Eric Young16
        +V	980705233205Z		17	certs/00000004	/CN=Eric Young17
        +V	961206150305Z		010C	unknown	/C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
        +V	961206153245Z		010D	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
        +V	970322074816Z		010E	unknown	/CN=Eric Young/Email=eay@mincom.oz.au
        +V	970322075152Z		010F	unknown	/CN=Eric Young
        +V	970322075906Z		0110	unknown	/CN=Eric Youngg
        +V	970324092238Z		0111	unknown	/C=AU/SP=Queensland/CN=Eric Young
        +V	970324221931Z		0112	unknown	/CN=Fred
        +V	970324224934Z		0113	unknown	/C=AU/CN=eay
        +V	971001005237Z		0114	unknown	/C=AU/SP=QLD/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
        +V	971001010331Z		0115	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test again - x509v3
        +V	971001013945Z		0117	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
        +V	971014225415Z		0118	unknown	/C=AU/SP=Queensland/CN=test
        +V	971015004448Z		0119	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test2
        +V	971016035001Z		011A	unknown	/C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test64
        +V	971016080129Z		011B	unknown	/C=FR/O=ALCATEL/OU=Alcatel Mobile Phones/CN=bourque/Email=bourque@art.alcatel.fr
        +V	971016224000Z		011D	unknown	/L=Bedford/O=Cranfield University/OU=Computer Centre/CN=Peter R Lister/Email=P.Lister@cranfield.ac.uk
        diff --git a/vendor/openssl/openssl/apps/demoCA/private/cakey.pem b/vendor/openssl/openssl/apps/demoCA/private/cakey.pem
        new file mode 100644
        index 000000000..48fb18c7d
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/demoCA/private/cakey.pem
        @@ -0,0 +1,24 @@
        +issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +-----BEGIN X509 CERTIFICATE-----
        +
        +MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
        +BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
        +MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
        +RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
        +BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
        +LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
        +/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
        +DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
        +IMs6ZOZB
        +-----END X509 CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +
        +MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
        +Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
        +hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
        +sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
        +tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
        +agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
        +g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/demoCA/serial b/vendor/openssl/openssl/apps/demoCA/serial
        new file mode 100644
        index 000000000..69fa0ffe2
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/demoCA/serial
        @@ -0,0 +1 @@
        +011E
        diff --git a/vendor/openssl/openssl/apps/demoSRP/srp_verifier.txt b/vendor/openssl/openssl/apps/demoSRP/srp_verifier.txt
        new file mode 100644
        index 000000000..ccae62924
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/demoSRP/srp_verifier.txt
        @@ -0,0 +1,6 @@
        +# This is a file that will be filled by the openssl srp routine.
        +# You can initialize the file with additional groups, these are
        +# records starting with a I followed by the g and N values and the id.
        +# The exact values ... you have to dig this out from the source of srp.c
        +# or srp_vfy.c
        +# The last value of an I is used as the default group for new users.  
        diff --git a/vendor/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr b/vendor/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr
        new file mode 100644
        index 000000000..8f7e63a34
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/demoSRP/srp_verifier.txt.attr
        @@ -0,0 +1 @@
        +unique_subject = yes
        diff --git a/vendor/openssl/openssl/apps/dgst.c b/vendor/openssl/openssl/apps/dgst.c
        new file mode 100644
        index 000000000..81bd870f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dgst.c
        @@ -0,0 +1,644 @@
        +/* apps/dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/hmac.h>
        +
        +#undef BUFSIZE
        +#define BUFSIZE	1024*8
        +
        +#undef PROG
        +#define PROG	dgst_main
        +
        +int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
        +	  EVP_PKEY *key, unsigned char *sigin, int siglen,
        +	  const char *sig_name, const char *md_name,
        +	  const char *file,BIO *bmd);
        +
        +static void list_md_fn(const EVP_MD *m,
        +			const char *from, const char *to, void *arg)
        +	{
        +	const char *mname;
        +	/* Skip aliases */
        +	if (!m)
        +		return;
        +	mname = OBJ_nid2ln(EVP_MD_type(m));
        +	/* Skip shortnames */
        +	if (strcmp(from, mname))
        +		return;
        +	/* Skip clones */
        +	if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST)
        +		return;
        +	if (strchr(mname, ' '))
        +		mname= EVP_MD_name(m);
        +	BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n",
        +			mname, mname);
        +	}
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	unsigned char *buf=NULL;
        +	int i,err=1;
        +	const EVP_MD *md=NULL,*m;
        +	BIO *in=NULL,*inp;
        +	BIO *bmd=NULL;
        +	BIO *out = NULL;
        +#define PROG_NAME_SIZE  39
        +	char pname[PROG_NAME_SIZE+1];
        +	int separator=0;
        +	int debug=0;
        +	int keyform=FORMAT_PEM;
        +	const char *outfile = NULL, *keyfile = NULL;
        +	const char *sigfile = NULL, *randfile = NULL;
        +	int out_bin = -1, want_pub = 0, do_verify = 0;
        +	EVP_PKEY *sigkey = NULL;
        +	unsigned char *sigbuf = NULL;
        +	int siglen = 0;
        +	char *passargin = NULL, *passin = NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	char *hmac_key=NULL;
        +	char *mac_name=NULL;
        +	int non_fips_allow = 0;
        +	STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
        +
        +	apps_startup();
        +
        +	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		goto end;
        +		}
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	/* first check the program name */
        +	program_name(argv[0],pname,sizeof pname);
        +
        +	md=EVP_get_digestbyname(pname);
        +
        +	argc--;
        +	argv++;
        +	while (argc > 0)
        +		{
        +		if ((*argv)[0] != '-') break;
        +		if (strcmp(*argv,"-c") == 0)
        +			separator=1;
        +		else if (strcmp(*argv,"-r") == 0)
        +			separator=2;
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) break;
        +			randfile=*(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) break;
        +			outfile=*(++argv);
        +			}
        +		else if (strcmp(*argv,"-sign") == 0)
        +			{
        +			if (--argc < 1) break;
        +			keyfile=*(++argv);
        +			}
        +		else if (!strcmp(*argv,"-passin"))
        +			{
        +			if (--argc < 1)
        +				break;
        +			passargin=*++argv;
        +			}
        +		else if (strcmp(*argv,"-verify") == 0)
        +			{
        +			if (--argc < 1) break;
        +			keyfile=*(++argv);
        +			want_pub = 1;
        +			do_verify = 1;
        +			}
        +		else if (strcmp(*argv,"-prverify") == 0)
        +			{
        +			if (--argc < 1) break;
        +			keyfile=*(++argv);
        +			do_verify = 1;
        +			}
        +		else if (strcmp(*argv,"-signature") == 0)
        +			{
        +			if (--argc < 1) break;
        +			sigfile=*(++argv);
        +			}
        +		else if (strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) break;
        +			keyform=str2fmt(*(++argv));
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) break;
        +			engine= *(++argv);
        +        		e = setup_engine(bio_err, engine, 0);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-hex") == 0)
        +			out_bin = 0;
        +		else if (strcmp(*argv,"-binary") == 0)
        +			out_bin = 1;
        +		else if (strcmp(*argv,"-d") == 0)
        +			debug=1;
        +		else if (!strcmp(*argv,"-fips-fingerprint"))
        +			hmac_key = "etaonrishdlcupfm";
        +		else if (strcmp(*argv,"-non-fips-allow") == 0)
        +			non_fips_allow=1;
        +		else if (!strcmp(*argv,"-hmac"))
        +			{
        +			if (--argc < 1)
        +				break;
        +			hmac_key=*++argv;
        +			}
        +		else if (!strcmp(*argv,"-mac"))
        +			{
        +			if (--argc < 1)
        +				break;
        +			mac_name=*++argv;
        +			}
        +		else if (strcmp(*argv,"-sigopt") == 0)
        +			{
        +			if (--argc < 1)
        +				break;
        +			if (!sigopts)
        +				sigopts = sk_OPENSSL_STRING_new_null();
        +			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
        +				break;
        +			}
        +		else if (strcmp(*argv,"-macopt") == 0)
        +			{
        +			if (--argc < 1)
        +				break;
        +			if (!macopts)
        +				macopts = sk_OPENSSL_STRING_new_null();
        +			if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
        +				break;
        +			}
        +		else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
        +			md=m;
        +		else
        +			break;
        +		argc--;
        +		argv++;
        +		}
        +
        +
        +	if(do_verify && !sigfile) {
        +		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
        +		goto end;
        +	}
        +
        +	if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
        +		{
        +		BIO_printf(bio_err,"unknown option '%s'\n",*argv);
        +		BIO_printf(bio_err,"options are\n");
        +		BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
        +		BIO_printf(bio_err,"-r              to output the digest in coreutils format\n");
        +		BIO_printf(bio_err,"-d              to output debug info\n");
        +		BIO_printf(bio_err,"-hex            output as hex dump\n");
        +		BIO_printf(bio_err,"-binary         output in binary form\n");
        +		BIO_printf(bio_err,"-sign   file    sign digest using private key in file\n");
        +		BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
        +		BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
        +		BIO_printf(bio_err,"-keyform arg    key file format (PEM or ENGINE)\n");
        +		BIO_printf(bio_err,"-out filename   output to filename rather than stdout\n");
        +		BIO_printf(bio_err,"-signature file signature to verify\n");
        +		BIO_printf(bio_err,"-sigopt nm:v    signature parameter\n");
        +		BIO_printf(bio_err,"-hmac key       create hashed MAC with key\n");
        +		BIO_printf(bio_err,"-mac algorithm  create MAC (not neccessarily HMAC)\n"); 
        +		BIO_printf(bio_err,"-macopt nm:v    MAC algorithm parameters or key\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +
        +		EVP_MD_do_all_sorted(list_md_fn, bio_err);
        +		goto end;
        +		}
        +
        +	in=BIO_new(BIO_s_file());
        +	bmd=BIO_new(BIO_f_md());
        +	if (debug)
        +		{
        +		BIO_set_callback(in,BIO_debug_callback);
        +		/* needed for windows 3.1 */
        +		BIO_set_callback_arg(in,(char *)bio_err);
        +		}
        +
        +	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +	if ((in == NULL) || (bmd == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if(out_bin == -1) {
        +		if(keyfile)
        +			out_bin = 1;
        +		else
        +			out_bin = 0;
        +	}
        +
        +	if(randfile)
        +		app_RAND_load_file(randfile, bio_err, 0);
        +
        +	if(outfile) {
        +		if(out_bin)
        +			out = BIO_new_file(outfile, "wb");
        +		else    out = BIO_new_file(outfile, "w");
        +	} else {
        +		out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +	}
        +
        +	if(!out) {
        +		BIO_printf(bio_err, "Error opening output file %s\n", 
        +					outfile ? outfile : "(stdout)");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +	if ((!!mac_name + !!keyfile + !!hmac_key) > 1)
        +		{
        +		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        +		goto end;
        +		}
        +
        +	if(keyfile)
        +		{
        +		if (want_pub)
        +			sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
        +				e, "key file");
        +		else
        +			sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
        +				e, "key file");
        +		if (!sigkey)
        +			{
        +			/* load_[pub]key() has already printed an appropriate
        +			   message */
        +			goto end;
        +			}
        +		}
        +
        +	if (mac_name)
        +		{
        +		EVP_PKEY_CTX *mac_ctx = NULL;
        +		int r = 0;
        +		if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0))
        +			goto mac_end;
        +		if (macopts)
        +			{
        +			char *macopt;
        +			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++)
        +				{
        +				macopt = sk_OPENSSL_STRING_value(macopts, i);
        +				if (pkey_ctrl_string(mac_ctx, macopt) <= 0)
        +					{
        +					BIO_printf(bio_err,
        +						"MAC parameter error \"%s\"\n",
        +						macopt);
        +					ERR_print_errors(bio_err);
        +					goto mac_end;
        +					}
        +				}
        +			}
        +		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0)
        +			{
        +			BIO_puts(bio_err, "Error generating key\n");
        +			ERR_print_errors(bio_err);
        +			goto mac_end;
        +			}
        +		r = 1;
        +		mac_end:
        +		if (mac_ctx)
        +			EVP_PKEY_CTX_free(mac_ctx);
        +		if (r == 0)
        +			goto end;
        +		}
        +
        +	if (non_fips_allow)
        +		{
        +		EVP_MD_CTX *md_ctx;
        +		BIO_get_md_ctx(bmd,&md_ctx);
        +		EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +		}
        +
        +	if (hmac_key)
        +		{
        +		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
        +					(unsigned char *)hmac_key, -1);
        +		if (!sigkey)
        +			goto end;
        +		}
        +
        +	if (sigkey)
        +		{
        +		EVP_MD_CTX *mctx = NULL;
        +		EVP_PKEY_CTX *pctx = NULL;
        +		int r;
        +		if (!BIO_get_md_ctx(bmd, &mctx))
        +			{
        +			BIO_printf(bio_err, "Error getting context\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (do_verify)
        +			r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey);
        +		else
        +			r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey);
        +		if (!r)
        +			{
        +			BIO_printf(bio_err, "Error setting context\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (sigopts)
        +			{
        +			char *sigopt;
        +			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
        +				{
        +				sigopt = sk_OPENSSL_STRING_value(sigopts, i);
        +				if (pkey_ctrl_string(pctx, sigopt) <= 0)
        +					{
        +					BIO_printf(bio_err,
        +						"parameter error \"%s\"\n",
        +						sigopt);
        +					ERR_print_errors(bio_err);
        +					goto end;
        +					}
        +				}
        +			}
        +		}
        +	/* we use md as a filter, reading from 'in' */
        +	else
        +		{
        +		if (md == NULL)
        +			md = EVP_md5(); 
        +		if (!BIO_set_md(bmd,md))
        +			{
        +			BIO_printf(bio_err, "Error setting digest %s\n", pname);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if(sigfile && sigkey) {
        +		BIO *sigbio;
        +		sigbio = BIO_new_file(sigfile, "rb");
        +		siglen = EVP_PKEY_size(sigkey);
        +		sigbuf = OPENSSL_malloc(siglen);
        +		if(!sigbio) {
        +			BIO_printf(bio_err, "Error opening signature file %s\n",
        +								sigfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +		siglen = BIO_read(sigbio, sigbuf, siglen);
        +		BIO_free(sigbio);
        +		if(siglen <= 0) {
        +			BIO_printf(bio_err, "Error reading signature file %s\n",
        +								sigfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +	}
        +	inp=BIO_push(bmd,in);
        +
        +	if (md == NULL)
        +		{
        +		EVP_MD_CTX *tctx;
        +		BIO_get_md_ctx(bmd, &tctx);
        +		md = EVP_MD_CTX_md(tctx);
        +		}
        +
        +	if (argc == 0)
        +		{
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +		err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
        +			  siglen,NULL,NULL,"stdin",bmd);
        +		}
        +	else
        +		{
        +		const char *md_name = NULL, *sig_name = NULL;
        +		if(!out_bin)
        +			{
        +			if (sigkey)
        +				{
        +				const EVP_PKEY_ASN1_METHOD *ameth;
        +				ameth = EVP_PKEY_get0_asn1(sigkey);
        +				if (ameth)
        +					EVP_PKEY_asn1_get0_info(NULL, NULL,
        +						NULL, NULL, &sig_name, ameth);
        +				}
        +			md_name = EVP_MD_name(md);
        +			}
        +		err = 0;
        +		for (i=0; i<argc; i++)
        +			{
        +			int r;
        +			if (BIO_read_filename(in,argv[i]) <= 0)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			else
        +			r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
        +				siglen,sig_name,md_name, argv[i],bmd);
        +			if(r)
        +			    err=r;
        +			(void)BIO_reset(bmd);
        +			}
        +		}
        +end:
        +	if (buf != NULL)
        +		{
        +		OPENSSL_cleanse(buf,BUFSIZE);
        +		OPENSSL_free(buf);
        +		}
        +	if (in != NULL) BIO_free(in);
        +	if (passin)
        +		OPENSSL_free(passin);
        +	BIO_free_all(out);
        +	EVP_PKEY_free(sigkey);
        +	if (sigopts)
        +		sk_OPENSSL_STRING_free(sigopts);
        +	if (macopts)
        +		sk_OPENSSL_STRING_free(macopts);
        +	if(sigbuf) OPENSSL_free(sigbuf);
        +	if (bmd != NULL) BIO_free(bmd);
        +	apps_shutdown();
        +	OPENSSL_EXIT(err);
        +	}
        +
        +int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
        +	  EVP_PKEY *key, unsigned char *sigin, int siglen,
        +	  const char *sig_name, const char *md_name,
        +	  const char *file,BIO *bmd)
        +	{
        +	size_t len;
        +	int i;
        +
        +	for (;;)
        +		{
        +		i=BIO_read(bp,(char *)buf,BUFSIZE);
        +		if(i < 0)
        +			{
        +			BIO_printf(bio_err, "Read Error in %s\n",file);
        +			ERR_print_errors(bio_err);
        +			return 1;
        +			}
        +		if (i == 0) break;
        +		}
        +	if(sigin)
        +		{
        +		EVP_MD_CTX *ctx;
        +		BIO_get_md_ctx(bp, &ctx);
        +		i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 
        +		if(i > 0)
        +			BIO_printf(out, "Verified OK\n");
        +		else if(i == 0)
        +			{
        +			BIO_printf(out, "Verification Failure\n");
        +			return 1;
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err, "Error Verifying Data\n");
        +			ERR_print_errors(bio_err);
        +			return 1;
        +			}
        +		return 0;
        +		}
        +	if(key)
        +		{
        +		EVP_MD_CTX *ctx;
        +		BIO_get_md_ctx(bp, &ctx);
        +		len = BUFSIZE;
        +		if(!EVP_DigestSignFinal(ctx, buf, &len)) 
        +			{
        +			BIO_printf(bio_err, "Error Signing Data\n");
        +			ERR_print_errors(bio_err);
        +			return 1;
        +			}
        +		}
        +	else
        +		{
        +		len=BIO_gets(bp,(char *)buf,BUFSIZE);
        +		if ((int)len <0)
        +			{
        +			ERR_print_errors(bio_err);
        +			return 1;
        +			}
        +		}
        +
        +	if(binout) BIO_write(out, buf, len);
        +	else if (sep == 2)
        +		{
        +		for (i=0; i<(int)len; i++)
        +			BIO_printf(out, "%02x",buf[i]);
        +		BIO_printf(out, " *%s\n", file);
        +		}
        +	else 
        +		{
        +		if (sig_name)
        +			BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
        +		else if (md_name)
        +			BIO_printf(out, "%s(%s)= ", md_name, file);
        +		else
        +			BIO_printf(out, "(%s)= ", file);
        +		for (i=0; i<(int)len; i++)
        +			{
        +			if (sep && (i != 0))
        +				BIO_printf(out, ":");
        +			BIO_printf(out, "%02x",buf[i]);
        +			}
        +		BIO_printf(out, "\n");
        +		}
        +	return 0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/dh.c b/vendor/openssl/openssl/apps/dh.c
        new file mode 100644
        index 000000000..dee9c01fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dh.c
        @@ -0,0 +1,355 @@
        +/* apps/dh.c */
        +/* obsoleted by dhparam.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 <openssl/opensslconf.h>	/* for OPENSSL_NO_DH */
        +#ifndef OPENSSL_NO_DH
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <time.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	dh_main
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -check	- check the parameters are ok
        + * -noout
        + * -text
        + * -C
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	DH *dh=NULL;
        +	int i,badops=0,text=0;
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat,check=0,noout=0,C=0,ret=1;
        +	char *infile,*outfile,*prog;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine;
        +#endif
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	engine=NULL;
        +#endif
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-check") == 0)
        +			check=1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*argv,"-C") == 0)
        +			C=1;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
        +		BIO_printf(bio_err," -outform arg  output format - one of DER PEM\n");
        +		BIO_printf(bio_err," -in arg       input file\n");
        +		BIO_printf(bio_err," -out arg      output file\n");
        +		BIO_printf(bio_err," -check        check the DH parameters\n");
        +		BIO_printf(bio_err," -text         print a text form of the DH parameters\n");
        +		BIO_printf(bio_err," -C            Output C code\n");
        +		BIO_printf(bio_err," -noout        no output\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
        +#endif
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if	(informat == FORMAT_ASN1)
        +		dh=d2i_DHparams_bio(in,NULL);
        +	else if (informat == FORMAT_PEM)
        +		dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
        +	else
        +		{
        +		BIO_printf(bio_err,"bad input format specified\n");
        +		goto end;
        +		}
        +	if (dh == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load DH parameters\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	
        +
        +	if (text)
        +		{
        +		DHparams_print(out,dh);
        +#ifdef undef
        +		printf("p=");
        +		BN_print(stdout,dh->p);
        +		printf("\ng=");
        +		BN_print(stdout,dh->g);
        +		printf("\n");
        +		if (dh->length != 0)
        +			printf("recommended private length=%ld\n",dh->length);
        +#endif
        +		}
        +	
        +	if (check)
        +		{
        +		if (!DH_check(dh,&i))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (i & DH_CHECK_P_NOT_PRIME)
        +			printf("p value is not prime\n");
        +		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        +			printf("p value is not a safe prime\n");
        +		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        +			printf("unable to check the generator value\n");
        +		if (i & DH_NOT_SUITABLE_GENERATOR)
        +			printf("the g value is not a generator\n");
        +		if (i == 0)
        +			printf("DH parameters appear to be ok.\n");
        +		}
        +	if (C)
        +		{
        +		unsigned char *data;
        +		int len,l,bits;
        +
        +		len=BN_num_bytes(dh->p);
        +		bits=BN_num_bits(dh->p);
        +		data=(unsigned char *)OPENSSL_malloc(len);
        +		if (data == NULL)
        +			{
        +			perror("OPENSSL_malloc");
        +			goto end;
        +			}
        +		l=BN_bn2bin(dh->p,data);
        +		printf("static unsigned char dh%d_p[]={",bits);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t};\n");
        +
        +		l=BN_bn2bin(dh->g,data);
        +		printf("static unsigned char dh%d_g[]={",bits);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t};\n\n");
        +
        +		printf("DH *get_dh%d()\n\t{\n",bits);
        +		printf("\tDH *dh;\n\n");
        +		printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
        +		printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
        +			bits,bits);
        +		printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
        +			bits,bits);
        +		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
        +		printf("\t\treturn(NULL);\n");
        +		printf("\treturn(dh);\n\t}\n");
        +		OPENSSL_free(data);
        +		}
        +
        +
        +	if (!noout)
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_DHparams_bio(out,dh);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_DHparams(out,dh);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i)
        +			{
        +			BIO_printf(bio_err,"unable to write DH parameters\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	ret=0;
        +end:
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (dh != NULL) DH_free(dh);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +#else /* !OPENSSL_NO_DH */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/dh1024.pem b/vendor/openssl/openssl/apps/dh1024.pem
        new file mode 100644
        index 000000000..6eaeca9b8
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dh1024.pem
        @@ -0,0 +1,10 @@
        +-----BEGIN DH PARAMETERS-----
        +MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY
        +jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6
        +ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC
        +-----END DH PARAMETERS-----
        +
        +These are the 1024 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/vendor/openssl/openssl/apps/dh2048.pem b/vendor/openssl/openssl/apps/dh2048.pem
        new file mode 100644
        index 000000000..dcd0b8d01
        --- /dev/null
        +++ b/vendor/openssl/openssl/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/vendor/openssl/openssl/apps/dh4096.pem b/vendor/openssl/openssl/apps/dh4096.pem
        new file mode 100644
        index 000000000..1b35ad8e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/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/vendor/openssl/openssl/apps/dh512.pem b/vendor/openssl/openssl/apps/dh512.pem
        new file mode 100644
        index 000000000..200d16cd8
        --- /dev/null
        +++ b/vendor/openssl/openssl/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/vendor/openssl/openssl/apps/dhparam.c b/vendor/openssl/openssl/apps/dhparam.c
        new file mode 100644
        index 000000000..1297d6fb5
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dhparam.c
        @@ -0,0 +1,559 @@
        +/* apps/dhparam.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 <openssl/opensslconf.h>	/* for OPENSSL_NO_DH */
        +#ifndef OPENSSL_NO_DH
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <time.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#undef PROG
        +#define PROG	dhparam_main
        +
        +#define DEFBITS	512
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -dsaparam  - read or generate DSA parameters, convert to DH
        + * -check	- check the parameters are ok
        + * -noout
        + * -text
        + * -C
        + */
        +
        +static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	DH *dh=NULL;
        +	int i,badops=0,text=0;
        +#ifndef OPENSSL_NO_DSA
        +	int dsaparam=0;
        +#endif
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat,check=0,noout=0,C=0,ret=1;
        +	char *infile,*outfile,*prog;
        +	char *inrand=NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	int num = 0, g = 0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-check") == 0)
        +			check=1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +#ifndef OPENSSL_NO_DSA
        +		else if (strcmp(*argv,"-dsaparam") == 0)
        +			dsaparam=1;
        +#endif
        +		else if (strcmp(*argv,"-C") == 0)
        +			C=1;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-2") == 0)
        +			g=2;
        +		else if (strcmp(*argv,"-5") == 0)
        +			g=5;
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +		else if (((sscanf(*argv,"%d",&num) == 0) || (num <= 0)))
        +			goto bad;
        +		argv++;
        +		argc--;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] [numbits]\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
        +		BIO_printf(bio_err," -outform arg  output format - one of DER PEM\n");
        +		BIO_printf(bio_err," -in arg       input file\n");
        +		BIO_printf(bio_err," -out arg      output file\n");
        +#ifndef OPENSSL_NO_DSA
        +		BIO_printf(bio_err," -dsaparam     read or generate DSA parameters, convert to DH\n");
        +#endif
        +		BIO_printf(bio_err," -check        check the DH parameters\n");
        +		BIO_printf(bio_err," -text         print a text form of the DH parameters\n");
        +		BIO_printf(bio_err," -C            Output C code\n");
        +		BIO_printf(bio_err," -2            generate parameters using  2 as the generator value\n");
        +		BIO_printf(bio_err," -5            generate parameters using  5 as the generator value\n");
        +		BIO_printf(bio_err," numbits       number of bits in to generate (default 512)\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,"               - load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,"               the random number generator\n");
        +		BIO_printf(bio_err," -noout        no output\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (g && !num)
        +		num = DEFBITS;
        +
        +#ifndef OPENSSL_NO_DSA
        +	if (dsaparam)
        +		{
        +		if (g)
        +			{
        +			BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
        +			goto end;
        +			}
        +		}
        +	else
        +#endif
        +		{
        +		/* DH parameters */
        +		if (num && !g)
        +			g = 2;
        +		}
        +
        +	if(num) {
        +
        +		BN_GENCB cb;
        +		BN_GENCB_set(&cb, dh_cb, bio_err);
        +		if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
        +			{
        +			BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
        +			}
        +		if (inrand != NULL)
        +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +				app_RAND_load_files(inrand));
        +
        +#ifndef OPENSSL_NO_DSA
        +		if (dsaparam)
        +			{
        +			DSA *dsa = DSA_new();
        +			
        +			BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
        +			if(!dsa || !DSA_generate_parameters_ex(dsa, num,
        +						NULL, 0, NULL, NULL, &cb))
        +				{
        +				if(dsa) DSA_free(dsa);
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +
        +			dh = DSA_dup_DH(dsa);
        +			DSA_free(dsa);
        +			if (dh == NULL)
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		else
        +#endif
        +			{
        +			dh = DH_new();
        +			BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
        +			BIO_printf(bio_err,"This is going to take a long time\n");
        +			if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb))
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +
        +		app_RAND_write_file(NULL, bio_err);
        +	} else {
        +
        +		in=BIO_new(BIO_s_file());
        +		if (in == NULL)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (infile == NULL)
        +			BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +		else
        +			{
        +			if (BIO_read_filename(in,infile) <= 0)
        +				{
        +				perror(infile);
        +				goto end;
        +				}
        +			}
        +
        +		if	(informat != FORMAT_ASN1 && informat != FORMAT_PEM)
        +			{
        +			BIO_printf(bio_err,"bad input format specified\n");
        +			goto end;
        +			}
        +
        +#ifndef OPENSSL_NO_DSA
        +		if (dsaparam)
        +			{
        +			DSA *dsa;
        +			
        +			if (informat == FORMAT_ASN1)
        +				dsa=d2i_DSAparams_bio(in,NULL);
        +			else /* informat == FORMAT_PEM */
        +				dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
        +			
        +			if (dsa == NULL)
        +				{
        +				BIO_printf(bio_err,"unable to load DSA parameters\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			
        +			dh = DSA_dup_DH(dsa);
        +			DSA_free(dsa);
        +			if (dh == NULL)
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		else
        +#endif
        +			{
        +			if (informat == FORMAT_ASN1)
        +				dh=d2i_DHparams_bio(in,NULL);
        +			else /* informat == FORMAT_PEM */
        +				dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
        +			
        +			if (dh == NULL)
        +				{
        +				BIO_printf(bio_err,"unable to load DH parameters\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		
        +		/* dh != NULL */
        +	}
        +	
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +
        +	if (text)
        +		{
        +		DHparams_print(out,dh);
        +		}
        +	
        +	if (check)
        +		{
        +		if (!DH_check(dh,&i))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (i & DH_CHECK_P_NOT_PRIME)
        +			printf("p value is not prime\n");
        +		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        +			printf("p value is not a safe prime\n");
        +		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        +			printf("unable to check the generator value\n");
        +		if (i & DH_NOT_SUITABLE_GENERATOR)
        +			printf("the g value is not a generator\n");
        +		if (i == 0)
        +			printf("DH parameters appear to be ok.\n");
        +		}
        +	if (C)
        +		{
        +		unsigned char *data;
        +		int len,l,bits;
        +
        +		len=BN_num_bytes(dh->p);
        +		bits=BN_num_bits(dh->p);
        +		data=(unsigned char *)OPENSSL_malloc(len);
        +		if (data == NULL)
        +			{
        +			perror("OPENSSL_malloc");
        +			goto end;
        +			}
        +		printf("#ifndef HEADER_DH_H\n"
        +		       "#include <openssl/dh.h>\n"
        +		       "#endif\n");
        +		printf("DH *get_dh%d()\n\t{\n",bits);
        +
        +		l=BN_bn2bin(dh->p,data);
        +		printf("\tstatic unsigned char dh%d_p[]={",bits);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t\t};\n");
        +
        +		l=BN_bn2bin(dh->g,data);
        +		printf("\tstatic unsigned char dh%d_g[]={",bits);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t\t};\n");
        +
        +		printf("\tDH *dh;\n\n");
        +		printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
        +		printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
        +			bits,bits);
        +		printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
        +			bits,bits);
        +		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
        +		printf("\t\t{ DH_free(dh); return(NULL); }\n");
        +		if (dh->length)
        +			printf("\tdh->length = %ld;\n", dh->length);
        +		printf("\treturn(dh);\n\t}\n");
        +		OPENSSL_free(data);
        +		}
        +
        +
        +	if (!noout)
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_DHparams_bio(out,dh);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_DHparams(out,dh);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i)
        +			{
        +			BIO_printf(bio_err,"unable to write DH parameters\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	ret=0;
        +end:
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (dh != NULL) DH_free(dh);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
        +static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(cb->arg,&c,1);
        +	(void)BIO_flush(cb->arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        +
        +#else /* !OPENSSL_NO_DH */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/dsa-ca.pem b/vendor/openssl/openssl/apps/dsa-ca.pem
        new file mode 100644
        index 000000000..cccc14208
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsa-ca.pem
        @@ -0,0 +1,40 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +MIIBugIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ
        +PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel
        +u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH
        +Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso
        +hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu
        +SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y
        +Mu0OArgCgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuHvSLw9YUrJahcBHmbpvt4
        +94lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUqAylOVFJJJXuirVJ+o+0T
        +tOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u3enxhqnDGQIUB78dhW77
        +J6zsFbSEHaQGUmfSeoM=
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIICUjCCAhECAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
        +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew
        +ggG0MIIBKQYFKw4DAgwwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaW
        +sxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5m
        +rmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHk
        +cJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVo
        +bzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqR
        +CZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxB
        +F5WS6wG1c6Vqftgy7Q4CuAOBhAACgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuH
        +vSLw9YUrJahcBHmbpvt494lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUq
        +AylOVFJJJXuirVJ+o+0TtOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u
        +3enxhqnDGaAAMAkGBSsOAwIbBQADMAAwLQIVAJGVuFsG/0DBuSZ0jF7ypdU0/G0v
        +AhQfeF5BoMMDbX/kidUVpQ6gadPlZA==
        +-----END CERTIFICATE REQUEST-----
        +-----BEGIN CERTIFICATE-----
        +MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
        +CgYDVQQDEwNQQ0EwHhcNOTcwNjE1MDIxNDI5WhcNOTcwNzE1MDIxNDI5WjBSMQsw
        +CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
        +ZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCBkjAJBgUrDgMCDAUAA4GE
        +AAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfsi4e9IvD1hSslqFwEeZum+3j3iUXi
        +ALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj25SoDKU5UUkkle6KtUn6j7RO04UMh
        +MQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17ry7d6fGGqcMZMAkGBSsOAwIbBQAD
        +MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa
        +C1Q=
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/apps/dsa-pca.pem b/vendor/openssl/openssl/apps/dsa-pca.pem
        new file mode 100644
        index 000000000..d23774edd
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsa-pca.pem
        @@ -0,0 +1,46 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +MIIBvAIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ
        +PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel
        +u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH
        +Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso
        +hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu
        +SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y
        +Mu0OArgCgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
        +umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
        +29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUCFQDNvrBz
        +6TicfImU7UFRn9h00j0lJQ==
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
        +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB
        +MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G
        +lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O
        +Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR
        +5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl
        +aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6
        +kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als
        +QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe
        +6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ
        +yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0
        +z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB
        +nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==
        +-----END CERTIFICATE REQUEST-----
        +-----BEGIN CERTIFICATE-----
        +MIIC0zCCApECAQAwCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
        +CgYDVQQDEwNQQ0EwHhcNOTcwNjE0MjI1NDQ1WhcNOTcwNzE0MjI1NDQ1WjBTMQsw
        +CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
        +ZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNQQ0EwggG1MIIBKQYFKw4DAgww
        +ggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaWsxXgUy6P4FmCc5A+dTGZ
        +R3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5mrmuINvvsKNzC16W75Sw5
        +JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHkcJVbUM1JAhUA9wcx7fps
        +BgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVobzDjaeHls12YuyiGSPze
        +mQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqRCZ228U2cVA9YBu5JdAfO
        +VX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxBF5WS6wG1c6Vqftgy7Q4C
        +uAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
        +umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
        +29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUwCQYFKw4D
        +AhsFAAMxADAuAhUAvtv6AkMolix1Jvy3UnVEIUqdCUICFQC+jq8P49mwrY9oJ24n
        +5rKUjNBhSg==
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/apps/dsa.c b/vendor/openssl/openssl/apps/dsa.c
        new file mode 100644
        index 000000000..5222487ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsa.c
        @@ -0,0 +1,376 @@
        +/* apps/dsa.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 <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
        +#ifndef OPENSSL_NO_DSA
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/dsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/bn.h>
        +
        +#undef PROG
        +#define PROG	dsa_main
        +
        +/* -inform arg	- input format - default PEM (one of DER, NET or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -des		- encrypt output if PEM format with DES in cbc mode
        + * -des3	- encrypt output if PEM format
        + * -idea	- encrypt output if PEM format
        + * -aes128	- encrypt output if PEM format
        + * -aes192	- encrypt output if PEM format
        + * -aes256	- encrypt output if PEM format
        + * -camellia128 - encrypt output if PEM format
        + * -camellia192 - encrypt output if PEM format
        + * -camellia256 - encrypt output if PEM format
        + * -seed        - encrypt output if PEM format
        + * -text	- print a text version
        + * -modulus	- print the DSA public key
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int ret=1;
        +	DSA *dsa=NULL;
        +	int i,badops=0;
        +	const EVP_CIPHER *enc=NULL;
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat,text=0,noout=0;
        +	int pubin = 0, pubout = 0;
        +	char *infile,*outfile,*prog;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine;
        +#endif
        +	char *passargin = NULL, *passargout = NULL;
        +	char *passin = NULL, *passout = NULL;
        +	int modulus=0;
        +
        +	int pvk_encr = 2;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	engine=NULL;
        +#endif
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-pvk-strong") == 0)
        +			pvk_encr=2;
        +		else if (strcmp(*argv,"-pvk-weak") == 0)
        +			pvk_encr=1;
        +		else if (strcmp(*argv,"-pvk-none") == 0)
        +			pvk_encr=0;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*argv,"-modulus") == 0)
        +			modulus=1;
        +		else if (strcmp(*argv,"-pubin") == 0)
        +			pubin=1;
        +		else if (strcmp(*argv,"-pubout") == 0)
        +			pubout=1;
        +		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg     input format - DER or PEM\n");
        +		BIO_printf(bio_err," -outform arg    output format - DER or PEM\n");
        +		BIO_printf(bio_err," -in arg         input file\n");
        +		BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
        +		BIO_printf(bio_err," -out arg        output file\n");
        +		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
        +		BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
        +#ifndef OPENSSL_NO_IDEA
        +		BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
        +#endif
        +		BIO_printf(bio_err," -text           print the key in text\n");
        +		BIO_printf(bio_err," -noout          don't print key out\n");
        +		BIO_printf(bio_err," -modulus        print the DSA public value\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto end;
        +	}
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +
        +	BIO_printf(bio_err,"read DSA key\n");
        +
        +		{
        +		EVP_PKEY	*pkey;
        +
        +		if (pubin)
        +			pkey = load_pubkey(bio_err, infile, informat, 1,
        +				passin, e, "Public Key");
        +		else
        +			pkey = load_key(bio_err, infile, informat, 1,
        +				passin, e, "Private Key");
        +
        +		if (pkey)
        +			{
        +			dsa = EVP_PKEY_get1_DSA(pkey);
        +			EVP_PKEY_free(pkey);
        +			}
        +		}
        +	if (dsa == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load Key\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (text) 
        +		if (!DSA_print(out,dsa,0))
        +			{
        +			perror(outfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +	if (modulus)
        +		{
        +		fprintf(stdout,"Public Key=");
        +		BN_print(out,dsa->pub_key);
        +		fprintf(stdout,"\n");
        +		}
        +
        +	if (noout) goto end;
        +	BIO_printf(bio_err,"writing DSA key\n");
        +	if 	(outformat == FORMAT_ASN1) {
        +		if(pubin || pubout) i=i2d_DSA_PUBKEY_bio(out,dsa);
        +		else i=i2d_DSAPrivateKey_bio(out,dsa);
        +	} else if (outformat == FORMAT_PEM) {
        +		if(pubin || pubout)
        +			i=PEM_write_bio_DSA_PUBKEY(out,dsa);
        +		else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,
        +							NULL,0,NULL, passout);
        +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
        +	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
        +		EVP_PKEY *pk;
        +		pk = EVP_PKEY_new();
        +		EVP_PKEY_set1_DSA(pk, dsa);
        +		if (outformat == FORMAT_PVK)
        +			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
        +		else if (pubin || pubout)
        +			i = i2b_PublicKey_bio(out, pk);
        +		else
        +			i = i2b_PrivateKey_bio(out, pk);
        +		EVP_PKEY_free(pk);
        +#endif
        +	} else {
        +		BIO_printf(bio_err,"bad output format specified for outfile\n");
        +		goto end;
        +		}
        +	if (i <= 0)
        +		{
        +		BIO_printf(bio_err,"unable to write private key\n");
        +		ERR_print_errors(bio_err);
        +		}
        +	else
        +		ret=0;
        +end:
        +	if(in != NULL) BIO_free(in);
        +	if(out != NULL) BIO_free_all(out);
        +	if(dsa != NULL) DSA_free(dsa);
        +	if(passin) OPENSSL_free(passin);
        +	if(passout) OPENSSL_free(passout);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +#else /* !OPENSSL_NO_DSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/dsa1024.pem b/vendor/openssl/openssl/apps/dsa1024.pem
        new file mode 100644
        index 000000000..082dec389
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsa1024.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN DSA PARAMETERS-----
        +MIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQPnUx
        +mUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtelu+Us
        +OSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcHMe36
        +bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLsohkj8
        +3pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbuSXQH
        +zlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7YMu0O
        +Arg=
        +-----END DSA PARAMETERS-----
        diff --git a/vendor/openssl/openssl/apps/dsa512.pem b/vendor/openssl/openssl/apps/dsa512.pem
        new file mode 100644
        index 000000000..5f86d1a6e
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsa512.pem
        @@ -0,0 +1,6 @@
        +-----BEGIN DSA PARAMETERS-----
        +MIGdAkEAnRtpjibb8isRcBmG9hnI+BnyGFOURgbQYlAzSwI8UjADizv5X9EkBk97
        +TLqqQJv9luQ3M7stWtdaEUBmonZ9MQIVAPtT71C0QJIxVoZTeuiLIppJ+3GPAkEA
        +gz6I5cWJc847bAFJv7PHnwrqRJHlMKrZvltftxDXibeOdPvPKR7rqCxUUbgQ3qDO
        +L8wka5B33qJoplISogOdIA==
        +-----END DSA PARAMETERS-----
        diff --git a/vendor/openssl/openssl/apps/dsap.pem b/vendor/openssl/openssl/apps/dsap.pem
        new file mode 100644
        index 000000000..d4dfdb305
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsap.pem
        @@ -0,0 +1,6 @@
        +-----BEGIN DSA PARAMETERS-----
        +MIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZS4J1PHvPrm9MXj5ntVheDPkdmBDTncya
        +GAJcMjwsyB/GvLDGd6yGCw/8eF+09wIVAK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2
        +t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjgtWiJc/tpvcuzeuAayH89UofjAGueKjXD
        +ADiRffvSdhrNw5dkqdql
        +-----END DSA PARAMETERS-----
        diff --git a/vendor/openssl/openssl/apps/dsaparam.c b/vendor/openssl/openssl/apps/dsaparam.c
        new file mode 100644
        index 000000000..683d51391
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/dsaparam.c
        @@ -0,0 +1,486 @@
        +/* apps/dsaparam.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 <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +#include <assert.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <time.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/dsa.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	dsaparam_main
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -noout
        + * -text
        + * -C
        + * -noout
        + * -genkey
        + *  #ifdef GENCB_TEST
        + * -timebomb n  - interrupt keygen after <n> seconds
        + *  #endif
        + */
        +
        +#ifdef GENCB_TEST
        +
        +static int stop_keygen_flag = 0;
        +
        +static void timebomb_sigalarm(int foo)
        +	{
        +	stop_keygen_flag = 1;
        +	}
        +
        +#endif
        +
        +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	DSA *dsa=NULL;
        +	int i,badops=0,text=0;
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat,noout=0,C=0,ret=1;
        +	char *infile,*outfile,*prog,*inrand=NULL;
        +	int numbits= -1,num,genkey=0;
        +	int need_rand=0;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +#ifdef GENCB_TEST
        +	int timebomb=0;
        +#endif
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if(strcmp(*argv, "-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine = *(++argv);
        +			}
        +#endif
        +#ifdef GENCB_TEST
        +		else if(strcmp(*argv, "-timebomb") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			timebomb = atoi(*(++argv));
        +			}
        +#endif
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*argv,"-C") == 0)
        +			C=1;
        +		else if (strcmp(*argv,"-genkey") == 0)
        +			{
        +			genkey=1;
        +			need_rand=1;
        +			}
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			need_rand=1;
        +			}
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (sscanf(*argv,"%d",&num) == 1)
        +			{
        +			/* generate a key */
        +			numbits=num;
        +			need_rand=1;
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg   input format - DER or PEM\n");
        +		BIO_printf(bio_err," -outform arg  output format - DER or PEM\n");
        +		BIO_printf(bio_err," -in arg       input file\n");
        +		BIO_printf(bio_err," -out arg      output file\n");
        +		BIO_printf(bio_err," -text         print as text\n");
        +		BIO_printf(bio_err," -C            Output C code\n");
        +		BIO_printf(bio_err," -noout        no output\n");
        +		BIO_printf(bio_err," -genkey       generate a DSA key\n");
        +		BIO_printf(bio_err," -rand         files to use for random number input\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
        +#endif
        +#ifdef GENCB_TEST
        +		BIO_printf(bio_err," -timebomb n   interrupt keygen after <n> seconds\n");
        +#endif
        +		BIO_printf(bio_err," number        number of bits to use for generating private key\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (need_rand)
        +		{
        +		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        +		if (inrand != NULL)
        +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +				app_RAND_load_files(inrand));
        +		}
        +
        +	if (numbits > 0)
        +		{
        +		BN_GENCB cb;
        +		BN_GENCB_set(&cb, dsa_cb, bio_err);
        +		assert(need_rand);
        +		dsa = DSA_new();
        +		if(!dsa)
        +			{
        +			BIO_printf(bio_err,"Error allocating DSA object\n");
        +			goto end;
        +			}
        +		BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
        +	        BIO_printf(bio_err,"This could take some time\n");
        +#ifdef GENCB_TEST
        +		if(timebomb > 0)
        +	{
        +		struct sigaction act;
        +		act.sa_handler = timebomb_sigalarm;
        +		act.sa_flags = 0;
        +		BIO_printf(bio_err,"(though I'll stop it if not done within %d secs)\n",
        +				timebomb);
        +		if(sigaction(SIGALRM, &act, NULL) != 0)
        +			{
        +			BIO_printf(bio_err,"Error, couldn't set SIGALRM handler\n");
        +			goto end;
        +			}
        +		alarm(timebomb);
        +	}
        +#endif
        +	        if(!DSA_generate_parameters_ex(dsa,num,NULL,0,NULL,NULL, &cb))
        +			{
        +#ifdef GENCB_TEST
        +			if(stop_keygen_flag)
        +				{
        +				BIO_printf(bio_err,"DSA key generation time-stopped\n");
        +				/* This is an asked-for behaviour! */
        +				ret = 0;
        +				goto end;
        +				}
        +#endif
        +			ERR_print_errors(bio_err);
        +			BIO_printf(bio_err,"Error, DSA key generation failed\n");
        +			goto end;
        +			}
        +		}
        +	else if	(informat == FORMAT_ASN1)
        +		dsa=d2i_DSAparams_bio(in,NULL);
        +	else if (informat == FORMAT_PEM)
        +		dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
        +	else
        +		{
        +		BIO_printf(bio_err,"bad input format specified\n");
        +		goto end;
        +		}
        +	if (dsa == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load DSA parameters\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (text)
        +		{
        +		DSAparams_print(out,dsa);
        +		}
        +	
        +	if (C)
        +		{
        +		unsigned char *data;
        +		int l,len,bits_p;
        +
        +		len=BN_num_bytes(dsa->p);
        +		bits_p=BN_num_bits(dsa->p);
        +		data=(unsigned char *)OPENSSL_malloc(len+20);
        +		if (data == NULL)
        +			{
        +			perror("OPENSSL_malloc");
        +			goto end;
        +			}
        +		l=BN_bn2bin(dsa->p,data);
        +		printf("static unsigned char dsa%d_p[]={",bits_p);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t};\n");
        +
        +		l=BN_bn2bin(dsa->q,data);
        +		printf("static unsigned char dsa%d_q[]={",bits_p);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t};\n");
        +
        +		l=BN_bn2bin(dsa->g,data);
        +		printf("static unsigned char dsa%d_g[]={",bits_p);
        +		for (i=0; i<l; i++)
        +			{
        +			if ((i%12) == 0) printf("\n\t");
        +			printf("0x%02X,",data[i]);
        +			}
        +		printf("\n\t};\n\n");
        +
        +		printf("DSA *get_dsa%d()\n\t{\n",bits_p);
        +		printf("\tDSA *dsa;\n\n");
        +		printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n");
        +		printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n",
        +			bits_p,bits_p);
        +		printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n",
        +			bits_p,bits_p);
        +		printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n",
        +			bits_p,bits_p);
        +		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
        +		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
        +		printf("\treturn(dsa);\n\t}\n");
        +		}
        +
        +
        +	if (!noout)
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_DSAparams_bio(out,dsa);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_DSAparams(out,dsa);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i)
        +			{
        +			BIO_printf(bio_err,"unable to write DSA parameters\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	if (genkey)
        +		{
        +		DSA *dsakey;
        +
        +		assert(need_rand);
        +		if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
        +		if (!DSA_generate_key(dsakey))
        +			{
        +			ERR_print_errors(bio_err);
        +			DSA_free(dsakey);
        +			goto end;
        +			}
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_DSAPrivateKey_bio(out,dsakey);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			DSA_free(dsakey);
        +			goto end;
        +			}
        +		DSA_free(dsakey);
        +		}
        +	if (need_rand)
        +		app_RAND_write_file(NULL, bio_err);
        +	ret=0;
        +end:
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (dsa != NULL) DSA_free(dsa);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(cb->arg,&c,1);
        +	(void)BIO_flush(cb->arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +#ifdef GENCB_TEST
        +	if(stop_keygen_flag)
        +		return 0;
        +#endif
        +	return 1;
        +	}
        +#else /* !OPENSSL_NO_DSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/ec.c b/vendor/openssl/openssl/apps/ec.c
        new file mode 100644
        index 000000000..896eabc13
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ec.c
        @@ -0,0 +1,406 @@
        +/* apps/ec.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 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 <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_EC
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	ec_main
        +
        +/* -inform arg    - input format - default PEM (one of DER, NET or PEM)
        + * -outform arg   - output format - default PEM
        + * -in arg        - input file - default stdin
        + * -out arg       - output file - default stdout
        + * -des           - encrypt output if PEM format with DES in cbc mode
        + * -text          - print a text version
        + * -param_out     - print the elliptic curve parameters
        + * -conv_form arg - specifies the point encoding form
        + * -param_enc arg - specifies the parameter encoding
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +{
        +	int 	ret = 1;
        +	EC_KEY 	*eckey = NULL;
        +	const EC_GROUP *group;
        +	int 	i, badops = 0;
        +	const EVP_CIPHER *enc = NULL;
        +	BIO 	*in = NULL, *out = NULL;
        +	int 	informat, outformat, text=0, noout=0;
        +	int  	pubin = 0, pubout = 0, param_out = 0;
        +	char 	*infile, *outfile, *prog, *engine;
        +	char 	*passargin = NULL, *passargout = NULL;
        +	char 	*passin = NULL, *passout = NULL;
        +	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
        +	int	new_form = 0;
        +	int	asn1_flag = OPENSSL_EC_NAMED_CURVE;
        +	int 	new_asn1_flag = 0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	engine = NULL;
        +	infile = NULL;
        +	outfile = NULL;
        +	informat = FORMAT_PEM;
        +	outformat = FORMAT_PEM;
        +
        +	prog = argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if (strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +		else if (strcmp(*argv, "-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +		else if (strcmp(*argv, "-noout") == 0)
        +			noout = 1;
        +		else if (strcmp(*argv, "-text") == 0)
        +			text = 1;
        +		else if (strcmp(*argv, "-conv_form") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			++argv;
        +			new_form = 1;
        +			if (strcmp(*argv, "compressed") == 0)
        +				form = POINT_CONVERSION_COMPRESSED;
        +			else if (strcmp(*argv, "uncompressed") == 0)
        +				form = POINT_CONVERSION_UNCOMPRESSED;
        +			else if (strcmp(*argv, "hybrid") == 0)
        +				form = POINT_CONVERSION_HYBRID;
        +			else
        +				goto bad;
        +			}
        +		else if (strcmp(*argv, "-param_enc") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			++argv;
        +			new_asn1_flag = 1;
        +			if (strcmp(*argv, "named_curve") == 0)
        +				asn1_flag = OPENSSL_EC_NAMED_CURVE;
        +			else if (strcmp(*argv, "explicit") == 0)
        +				asn1_flag = 0;
        +			else
        +				goto bad;
        +			}
        +		else if (strcmp(*argv, "-param_out") == 0)
        +			param_out = 1;
        +		else if (strcmp(*argv, "-pubin") == 0)
        +			pubin=1;
        +		else if (strcmp(*argv, "-pubout") == 0)
        +			pubout=1;
        +		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
        +			{
        +			BIO_printf(bio_err, "unknown option %s\n", *argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
        +		BIO_printf(bio_err, "where options are\n");
        +		BIO_printf(bio_err, " -inform arg     input format - "
        +				"DER or PEM\n");
        +		BIO_printf(bio_err, " -outform arg    output format - "
        +				"DER or PEM\n");
        +		BIO_printf(bio_err, " -in arg         input file\n");
        +		BIO_printf(bio_err, " -passin arg     input file pass "
        +				"phrase source\n");
        +		BIO_printf(bio_err, " -out arg        output file\n");
        +		BIO_printf(bio_err, " -passout arg    output file pass "
        +				"phrase source\n");
        +		BIO_printf(bio_err, " -engine e       use engine e, "
        +				"possibly a hardware device.\n");
        +		BIO_printf(bio_err, " -des            encrypt PEM output, "
        +				"instead of 'des' every other \n"
        +				"                 cipher "
        +				"supported by OpenSSL can be used\n");
        +		BIO_printf(bio_err, " -text           print the key\n");
        +		BIO_printf(bio_err, " -noout          don't print key out\n");
        +		BIO_printf(bio_err, " -param_out      print the elliptic "
        +				"curve parameters\n");
        +		BIO_printf(bio_err, " -conv_form arg  specifies the "
        +				"point conversion form \n");
        +		BIO_printf(bio_err, "                 possible values:"
        +				" compressed\n");
        +		BIO_printf(bio_err, "                                 "
        +				" uncompressed (default)\n");
        +		BIO_printf(bio_err, "                                  "
        +				" hybrid\n");
        +		BIO_printf(bio_err, " -param_enc arg  specifies the way"
        +				" the ec parameters are encoded\n");
        +		BIO_printf(bio_err, "                 in the asn1 der "
        +				"encoding\n");
        +		BIO_printf(bio_err, "                 possible values:"
        +				" named_curve (default)\n");
        +		BIO_printf(bio_err,"                                  "
        +				"explicit\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) 
        +		{
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto end;
        +		}
        +
        +	in = BIO_new(BIO_s_file());
        +	out = BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in, stdin, BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in, infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +
        +	BIO_printf(bio_err, "read EC key\n");
        +	if (informat == FORMAT_ASN1) 
        +		{
        +		if (pubin) 
        +			eckey = d2i_EC_PUBKEY_bio(in, NULL);
        +		else 
        +			eckey = d2i_ECPrivateKey_bio(in, NULL);
        +		} 
        +	else if (informat == FORMAT_PEM) 
        +		{
        +		if (pubin) 
        +			eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, 
        +				NULL);
        +		else 
        +			eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
        +				passin);
        +		} 
        +	else
        +		{
        +		BIO_printf(bio_err, "bad input format specified for key\n");
        +		goto end;
        +		}
        +	if (eckey == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load Key\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out, stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out, outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	group = EC_KEY_get0_group(eckey);
        +
        +	if (new_form)
        +		EC_KEY_set_conv_form(eckey, form);
        +
        +	if (new_asn1_flag)
        +		EC_KEY_set_asn1_flag(eckey, asn1_flag);
        +
        +	if (text) 
        +		if (!EC_KEY_print(out, eckey, 0))
        +			{
        +			perror(outfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +	if (noout) 
        +		{
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	BIO_printf(bio_err, "writing EC key\n");
        +	if (outformat == FORMAT_ASN1) 
        +		{
        +		if (param_out)
        +			i = i2d_ECPKParameters_bio(out, group);
        +		else if (pubin || pubout) 
        +			i = i2d_EC_PUBKEY_bio(out, eckey);
        +		else 
        +			i = i2d_ECPrivateKey_bio(out, eckey);
        +		} 
        +	else if (outformat == FORMAT_PEM) 
        +		{
        +		if (param_out)
        +			i = PEM_write_bio_ECPKParameters(out, group);
        +		else if (pubin || pubout)
        +			i = PEM_write_bio_EC_PUBKEY(out, eckey);
        +		else 
        +			i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
        +						NULL, 0, NULL, passout);
        +		} 
        +	else 
        +		{
        +		BIO_printf(bio_err, "bad output format specified for "
        +			"outfile\n");
        +		goto end;
        +		}
        +
        +	if (!i)
        +		{
        +		BIO_printf(bio_err, "unable to write private key\n");
        +		ERR_print_errors(bio_err);
        +		}
        +	else
        +		ret=0;
        +end:
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free_all(out);
        +	if (eckey)
        +		EC_KEY_free(eckey);
        +	if (passin)
        +		OPENSSL_free(passin);
        +	if (passout)
        +		OPENSSL_free(passout);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +}
        +#else /* !OPENSSL_NO_EC */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/ecparam.c b/vendor/openssl/openssl/apps/ecparam.c
        new file mode 100644
        index 000000000..465480bed
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ecparam.c
        @@ -0,0 +1,731 @@
        +/* apps/ecparam.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_EC
        +#include <assert.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <time.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/ec.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	ecparam_main
        +
        +/* -inform arg      - input format - default PEM (DER or PEM)
        + * -outform arg     - output format - default PEM
        + * -in  arg         - input file  - default stdin
        + * -out arg         - output file - default stdout
        + * -noout           - do not print the ec parameter
        + * -text            - print the ec parameters in text form
        + * -check           - validate the ec parameters
        + * -C               - print a 'C' function creating the parameters
        + * -name arg        - use the ec parameters with 'short name' name
        + * -list_curves     - prints a list of all currently available curve 'short names'
        + * -conv_form arg   - specifies the point conversion form 
        + *                  - possible values: compressed
        + *                                     uncompressed (default)
        + *                                     hybrid
        + * -param_enc arg   - specifies the way the ec parameters are encoded
        + *                    in the asn1 der encoding
        + *                    possible values: named_curve (default)
        + *                                     explicit
        + * -no_seed         - if 'explicit' parameters are choosen do not use the seed
        + * -genkey          - generate ec key
        + * -rand file       - files to use for random number input
        + * -engine e        - use engine e, possibly a hardware device
        + */
        +
        +
        +static int ecparam_print_var(BIO *,BIGNUM *,const char *,int,unsigned char *);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	EC_GROUP *group = NULL;
        +	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; 
        +	int 	new_form = 0;
        +	int 	asn1_flag = OPENSSL_EC_NAMED_CURVE;
        +	int 	new_asn1_flag = 0;
        +	char 	*curve_name = NULL, *inrand = NULL;
        +	int	list_curves = 0, no_seed = 0, check = 0,
        +		badops = 0, text = 0, i, need_rand = 0, genkey = 0;
        +	char	*infile = NULL, *outfile = NULL, *prog;
        +	BIO 	*in = NULL, *out = NULL;
        +	int 	informat, outformat, noout = 0, C = 0, ret = 1;
        +	char	*engine = NULL;
        +
        +	BIGNUM	*ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
        +		*ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
        +	unsigned char *buffer = NULL;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-text") == 0)
        +			text = 1;
        +		else if (strcmp(*argv,"-C") == 0)
        +			C = 1;
        +		else if (strcmp(*argv,"-check") == 0)
        +			check = 1;
        +		else if (strcmp (*argv, "-name") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			curve_name = *(++argv);
        +			}
        +		else if (strcmp(*argv, "-list_curves") == 0)
        +			list_curves = 1;
        +		else if (strcmp(*argv, "-conv_form") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			++argv;
        +			new_form = 1;
        +			if (strcmp(*argv, "compressed") == 0)
        +				form = POINT_CONVERSION_COMPRESSED;
        +			else if (strcmp(*argv, "uncompressed") == 0)
        +				form = POINT_CONVERSION_UNCOMPRESSED;
        +			else if (strcmp(*argv, "hybrid") == 0)
        +				form = POINT_CONVERSION_HYBRID;
        +			else
        +				goto bad;
        +			}
        +		else if (strcmp(*argv, "-param_enc") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			++argv;
        +			new_asn1_flag = 1;
        +			if (strcmp(*argv, "named_curve") == 0)
        +				asn1_flag = OPENSSL_EC_NAMED_CURVE;
        +			else if (strcmp(*argv, "explicit") == 0)
        +				asn1_flag = 0;
        +			else
        +				goto bad;
        +			}
        +		else if (strcmp(*argv, "-no_seed") == 0)
        +			no_seed = 1;
        +		else if (strcmp(*argv, "-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-genkey") == 0)
        +			{
        +			genkey=1;
        +			need_rand=1;
        +			}
        +		else if (strcmp(*argv, "-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			need_rand=1;
        +			}
        +		else if(strcmp(*argv, "-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine = *(++argv);
        +			}	
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err, "where options are\n");
        +		BIO_printf(bio_err, " -inform arg       input format - "
        +				"default PEM (DER or PEM)\n");
        +		BIO_printf(bio_err, " -outform arg      output format - "
        +				"default PEM\n");
        +		BIO_printf(bio_err, " -in  arg          input file  - "
        +				"default stdin\n");
        +		BIO_printf(bio_err, " -out arg          output file - "
        +				"default stdout\n");
        +		BIO_printf(bio_err, " -noout            do not print the "
        +				"ec parameter\n");
        +		BIO_printf(bio_err, " -text             print the ec "
        +				"parameters in text form\n");
        +		BIO_printf(bio_err, " -check            validate the ec "
        +				"parameters\n");
        +		BIO_printf(bio_err, " -C                print a 'C' "
        +				"function creating the parameters\n");
        +		BIO_printf(bio_err, " -name arg         use the "
        +				"ec parameters with 'short name' name\n");
        +		BIO_printf(bio_err, " -list_curves      prints a list of "
        +				"all currently available curve 'short names'\n");
        +		BIO_printf(bio_err, " -conv_form arg    specifies the "
        +				"point conversion form \n");
        +		BIO_printf(bio_err, "                   possible values:"
        +				" compressed\n");
        +		BIO_printf(bio_err, "                                   "
        +				" uncompressed (default)\n");
        +		BIO_printf(bio_err, "                                   "
        +				" hybrid\n");
        +		BIO_printf(bio_err, " -param_enc arg    specifies the way"
        +				" the ec parameters are encoded\n");
        +		BIO_printf(bio_err, "                   in the asn1 der "
        +				"encoding\n");
        +		BIO_printf(bio_err, "                   possible values:"
        +				" named_curve (default)\n");
        +		BIO_printf(bio_err, "                                   "
        +				" explicit\n");
        +		BIO_printf(bio_err, " -no_seed          if 'explicit'"
        +				" parameters are choosen do not"
        +				" use the seed\n");
        +		BIO_printf(bio_err, " -genkey           generate ec"
        +				" key\n");
        +		BIO_printf(bio_err, " -rand file        files to use for"
        +				" random number input\n");
        +		BIO_printf(bio_err, " -engine e         use engine e, "
        +				"possibly a hardware device\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (list_curves)
        +		{
        +		EC_builtin_curve *curves = NULL;
        +		size_t crv_len = 0;
        +		size_t n = 0;
        +
        +		crv_len = EC_get_builtin_curves(NULL, 0);
        +
        +		curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
        +
        +		if (curves == NULL)
        +			goto end;
        +
        +		if (!EC_get_builtin_curves(curves, crv_len))
        +			{
        +			OPENSSL_free(curves);
        +			goto end;
        +			}
        +
        +		
        +		for (n = 0; n < crv_len; n++)
        +			{
        +			const char *comment;
        +			const char *sname;
        +			comment = curves[n].comment;
        +			sname   = OBJ_nid2sn(curves[n].nid);
        +			if (comment == NULL)
        +				comment = "CURVE DESCRIPTION NOT AVAILABLE";
        +			if (sname == NULL)
        +				sname = "";
        +
        +			BIO_printf(out, "  %-10s: ", sname);
        +			BIO_printf(out, "%s\n", comment);
        +			} 
        +
        +		OPENSSL_free(curves);
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	if (curve_name != NULL)
        +		{
        +		int nid;
        +
        +		/* workaround for the SECG curve names secp192r1
        +		 * and secp256r1 (which are the same as the curves
        +		 * prime192v1 and prime256v1 defined in X9.62)
        +		 */
        +		if (!strcmp(curve_name, "secp192r1"))
        +			{
        +			BIO_printf(bio_err, "using curve name prime192v1 "
        +				"instead of secp192r1\n");
        +			nid = NID_X9_62_prime192v1;
        +			}
        +		else if (!strcmp(curve_name, "secp256r1"))
        +			{
        +			BIO_printf(bio_err, "using curve name prime256v1 "
        +				"instead of secp256r1\n");
        +			nid = NID_X9_62_prime256v1;
        +			}
        +		else
        +			nid = OBJ_sn2nid(curve_name);
        +	
        +		if (nid == 0)
        +			{
        +			BIO_printf(bio_err, "unknown curve name (%s)\n", 
        +				curve_name);
        +			goto end;
        +			}
        +
        +		group = EC_GROUP_new_by_curve_name(nid);
        +		if (group == NULL)
        +			{
        +			BIO_printf(bio_err, "unable to create curve (%s)\n", 
        +				curve_name);
        +			goto end;
        +			}
        +		EC_GROUP_set_asn1_flag(group, asn1_flag);
        +		EC_GROUP_set_point_conversion_form(group, form);
        +		}
        +	else if (informat == FORMAT_ASN1)
        +		{
        +		group = d2i_ECPKParameters_bio(in, NULL);
        +		}
        +	else if (informat == FORMAT_PEM)
        +		{
        +		group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
        +		}
        +	else
        +		{
        +		BIO_printf(bio_err, "bad input format specified\n");
        +		goto end;
        +		}
        +
        +	if (group == NULL)
        +		{
        +		BIO_printf(bio_err, 
        +			"unable to load elliptic curve parameters\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (new_form)
        +		EC_GROUP_set_point_conversion_form(group, form);
        +
        +	if (new_asn1_flag)
        +		EC_GROUP_set_asn1_flag(group, asn1_flag);
        +
        +	if (no_seed)
        +		{
        +		EC_GROUP_set_seed(group, NULL, 0);
        +		}
        +
        +	if (text)
        +		{
        +		if (!ECPKParameters_print(out, group, 0))
        +			goto end;
        +		}
        +
        +	if (check)
        +		{
        +		if (group == NULL)
        +			BIO_printf(bio_err, "no elliptic curve parameters\n");
        +		BIO_printf(bio_err, "checking elliptic curve parameters: ");
        +		if (!EC_GROUP_check(group, NULL))
        +			{
        +			BIO_printf(bio_err, "failed\n");
        +			ERR_print_errors(bio_err);
        +			}
        +		else
        +			BIO_printf(bio_err, "ok\n");
        +			
        +		}
        +
        +	if (C)
        +		{
        +		size_t	buf_len = 0, tmp_len = 0;
        +		const EC_POINT *point;
        +		int	is_prime, len = 0;
        +		const EC_METHOD *meth = EC_GROUP_method_of(group);
        +
        +		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
        +		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
        +		    (ec_order = BN_new()) == NULL || 
        +		    (ec_cofactor = BN_new()) == NULL )
        +			{
        +			perror("OPENSSL_malloc");
        +			goto end;
        +			}
        +
        +		is_prime = (EC_METHOD_get_field_type(meth) == 
        +			NID_X9_62_prime_field);
        +
        +		if (is_prime)
        +			{
        +			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
        +				ec_b, NULL))
        +				goto end;
        +			}
        +		else
        +			{
        +			/* TODO */
        +			goto end;
        +			}
        +
        +		if ((point = EC_GROUP_get0_generator(group)) == NULL)
        +			goto end;
        +		if (!EC_POINT_point2bn(group, point, 
        +			EC_GROUP_get_point_conversion_form(group), ec_gen, 
        +			NULL))
        +			goto end;
        +		if (!EC_GROUP_get_order(group, ec_order, NULL))
        +			goto end;
        +		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
        +			goto end;
        +
        +		if (!ec_p || !ec_a || !ec_b || !ec_gen || 
        +			!ec_order || !ec_cofactor)
        +			goto end;
        +
        +		len = BN_num_bits(ec_order);
        +
        +		if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
        +			buf_len = tmp_len;
        +		if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
        +			buf_len = tmp_len;
        +		if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
        +			buf_len = tmp_len;
        +		if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
        +			buf_len = tmp_len;
        +		if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
        +			buf_len = tmp_len;
        +		if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
        +			buf_len = tmp_len;
        +
        +		buffer = (unsigned char *)OPENSSL_malloc(buf_len);
        +
        +		if (buffer == NULL)
        +			{
        +			perror("OPENSSL_malloc");
        +			goto end;
        +			}
        +
        +		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
        +		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
        +		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
        +		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
        +		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
        +		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len, 
        +			buffer);
        +
        +		BIO_printf(out, "\n\n");
        +
        +		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
        +		BIO_printf(out, "\tint ok=0;\n");
        +		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
        +		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
        +		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
        +				"*tmp_3 = NULL;\n\n");
        +		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
        +				"sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
        +				"goto err;\n", len, len);
        +		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
        +				"sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
        +				"goto err;\n", len, len);
        +		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
        +				"sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
        +				"goto err;\n", len, len);
        +		if (is_prime)
        +			{
        +			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
        +				"GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
        +				"\n\t\tgoto err;\n\n");
        +			}
        +		else
        +			{
        +			/* TODO */
        +			goto end;
        +			}
        +		BIO_printf(out, "\t/* build generator */\n");
        +		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
        +				"sizeof(ec_gen_%d), tmp_1)) == NULL)"
        +				"\n\t\tgoto err;\n", len, len);
        +		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
        +				"NULL, NULL);\n");
        +		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
        +		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
        +				"sizeof(ec_order_%d), tmp_2)) == NULL)"
        +				"\n\t\tgoto err;\n", len, len);
        +		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
        +				"sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
        +				"\n\t\tgoto err;\n", len, len);
        +		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
        +				" tmp_2, tmp_3))\n\t\tgoto err;\n");
        +		BIO_printf(out, "\n\tok=1;\n");
        +		BIO_printf(out, "err:\n");
        +		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
        +		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
        +		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
        +		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
        +		BIO_printf(out, "\tif (!ok)\n");
        +		BIO_printf(out, "\t\t{\n");
        +		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
        +		BIO_printf(out, "\t\tgroup = NULL;\n");
        +		BIO_printf(out, "\t\t}\n");
        +		BIO_printf(out, "\treturn(group);\n\t}\n");
        +	}
        +
        +	if (!noout)
        +		{
        +		if (outformat == FORMAT_ASN1)
        +			i = i2d_ECPKParameters_bio(out, group);
        +		else if (outformat == FORMAT_PEM)
        +			i = PEM_write_bio_ECPKParameters(out, group);
        +		else	
        +			{
        +			BIO_printf(bio_err,"bad output format specified for"
        +				" outfile\n");
        +			goto end;
        +			}
        +		if (!i)
        +			{
        +			BIO_printf(bio_err, "unable to write elliptic "
        +				"curve parameters\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	
        +	if (need_rand)
        +		{
        +		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        +		if (inrand != NULL)
        +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +				app_RAND_load_files(inrand));
        +		}
        +
        +	if (genkey)
        +		{
        +		EC_KEY *eckey = EC_KEY_new();
        +
        +		if (eckey == NULL)
        +			goto end;
        +
        +		assert(need_rand);
        +
        +		if (EC_KEY_set_group(eckey, group) == 0)
        +			goto end;
        +		
        +		if (!EC_KEY_generate_key(eckey))
        +			{
        +			EC_KEY_free(eckey);
        +			goto end;
        +			}
        +		if (outformat == FORMAT_ASN1)
        +			i = i2d_ECPrivateKey_bio(out, eckey);
        +		else if (outformat == FORMAT_PEM)
        +			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
        +				NULL, 0, NULL, NULL);
        +		else	
        +			{
        +			BIO_printf(bio_err, "bad output format specified "
        +				"for outfile\n");
        +			EC_KEY_free(eckey);
        +			goto end;
        +			}
        +		EC_KEY_free(eckey);
        +		}
        +
        +	if (need_rand)
        +		app_RAND_write_file(NULL, bio_err);
        +
        +	ret=0;
        +end:
        +	if (ec_p)
        +		BN_free(ec_p);
        +	if (ec_a)
        +		BN_free(ec_a);
        +	if (ec_b)
        +		BN_free(ec_b);
        +	if (ec_gen)
        +		BN_free(ec_gen);
        +	if (ec_order)
        +		BN_free(ec_order);
        +	if (ec_cofactor)
        +		BN_free(ec_cofactor);
        +	if (buffer)
        +		OPENSSL_free(buffer);
        +	if (in != NULL)
        +		BIO_free(in);
        +	if (out != NULL)
        +		BIO_free_all(out);
        +	if (group != NULL)
        +		EC_GROUP_free(group);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +}
        +
        +static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
        +	int len, unsigned char *buffer)
        +	{
        +	BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
        +	if (BN_is_zero(in))
        +		BIO_printf(out, "\n\t0x00");
        +	else 
        +		{
        +		int i, l;
        +
        +		l = BN_bn2bin(in, buffer);
        +		for (i=0; i<l-1; i++)
        +			{
        +			if ((i%12) == 0) 
        +				BIO_printf(out, "\n\t");
        +			BIO_printf(out, "0x%02X,", buffer[i]);
        +			}
        +		if ((i%12) == 0) 
        +			BIO_printf(out, "\n\t");
        +		BIO_printf(out, "0x%02X", buffer[i]);
        +		}
        +	BIO_printf(out, "\n\t};\n\n");
        +	return 1;
        +	}
        +#else /* !OPENSSL_NO_EC */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/enc.c b/vendor/openssl/openssl/apps/enc.c
        new file mode 100644
        index 000000000..719acc325
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/enc.c
        @@ -0,0 +1,732 @@
        +/* apps/enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/rand.h>
        +#include <openssl/pem.h>
        +#include <openssl/comp.h>
        +#include <ctype.h>
        +
        +int set_hex(char *in,unsigned char *out,int size);
        +#undef SIZE
        +#undef BSIZE
        +#undef PROG
        +
        +#define SIZE	(512)
        +#define BSIZE	(8*1024)
        +#define	PROG	enc_main
        +
        +static void show_ciphers(const OBJ_NAME *name,void *bio_)
        +	{
        +	BIO *bio=bio_;
        +	static int n;
        +
        +	if(!islower((unsigned char)*name->name))
        +		return;
        +
        +	BIO_printf(bio,"-%-25s",name->name);
        +	if(++n == 3)
        +		{
        +		BIO_printf(bio,"\n");
        +		n=0;
        +		}
        +	else
        +		BIO_printf(bio," ");
        +	}
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	static const char magic[]="Salted__";
        +	char mbuf[sizeof magic-1];
        +	char *strbuf=NULL;
        +	unsigned char *buff=NULL,*bufsize=NULL;
        +	int bsize=BSIZE,verbose=0;
        +	int ret=1,inl;
        +	int nopad = 0;
        +	unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
        +	unsigned char salt[PKCS5_SALT_LEN];
        +	char *str=NULL, *passarg = NULL, *pass = NULL;
        +	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
        +	char *md=NULL;
        +	int enc=1,printkey=0,i,base64=0;
        +#ifdef ZLIB
        +	int do_zlib=0;
        +	BIO *bzl = NULL;
        +#endif
        +	int debug=0,olb64=0,nosalt=0;
        +	const EVP_CIPHER *cipher=NULL,*c;
        +	EVP_CIPHER_CTX *ctx = NULL;
        +	char *inf=NULL,*outf=NULL;
        +	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
        +#define PROG_NAME_SIZE  39
        +	char pname[PROG_NAME_SIZE+1];
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine = NULL;
        +#endif
        +	const EVP_MD *dgst=NULL;
        +	int non_fips_allow = 0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	/* first check the program name */
        +	program_name(argv[0],pname,sizeof pname);
        +	if (strcmp(pname,"base64") == 0)
        +		base64=1;
        +#ifdef ZLIB
        +	if (strcmp(pname,"zlib") == 0)
        +		do_zlib=1;
        +#endif
        +
        +	cipher=EVP_get_cipherbyname(pname);
        +#ifdef ZLIB
        +	if (!do_zlib && !base64 && (cipher == NULL)
        +				&& (strcmp(pname,"enc") != 0))
        +#else
        +	if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
        +#endif
        +		{
        +		BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
        +		goto bad;
        +		}
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if	(strcmp(*argv,"-e") == 0)
        +			enc=1;
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inf= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outf= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-pass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passarg= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if	(strcmp(*argv,"-d") == 0)
        +			enc=0;
        +		else if	(strcmp(*argv,"-p") == 0)
        +			printkey=1;
        +		else if	(strcmp(*argv,"-v") == 0)
        +			verbose=1;
        +		else if	(strcmp(*argv,"-nopad") == 0)
        +			nopad=1;
        +		else if	(strcmp(*argv,"-salt") == 0)
        +			nosalt=0;
        +		else if	(strcmp(*argv,"-nosalt") == 0)
        +			nosalt=1;
        +		else if	(strcmp(*argv,"-debug") == 0)
        +			debug=1;
        +		else if	(strcmp(*argv,"-P") == 0)
        +			printkey=2;
        +		else if	(strcmp(*argv,"-A") == 0)
        +			olb64=1;
        +		else if	(strcmp(*argv,"-a") == 0)
        +			base64=1;
        +		else if	(strcmp(*argv,"-base64") == 0)
        +			base64=1;
        +#ifdef ZLIB
        +		else if	(strcmp(*argv,"-z") == 0)
        +			do_zlib=1;
        +#endif
        +		else if (strcmp(*argv,"-bufsize") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			bufsize=(unsigned char *)*(++argv);
        +			}
        +		else if (strcmp(*argv,"-k") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			str= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-kfile") == 0)
        +			{
        +			static char buf[128];
        +			FILE *infile;
        +			char *file;
        +
        +			if (--argc < 1) goto bad;
        +			file= *(++argv);
        +			infile=fopen(file,"r");
        +			if (infile == NULL)
        +				{
        +				BIO_printf(bio_err,"unable to read key from '%s'\n",
        +					file);
        +				goto bad;
        +				}
        +			buf[0]='\0';
        +			if (!fgets(buf,sizeof buf,infile))
        +				{
        +				BIO_printf(bio_err,"unable to read key from '%s'\n",
        +					file);
        +				goto bad;
        +				}
        +			fclose(infile);
        +			i=strlen(buf);
        +			if ((i > 0) &&
        +				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
        +				buf[--i]='\0';
        +			if ((i > 0) &&
        +				((buf[i-1] == '\n') || (buf[i-1] == '\r')))
        +				buf[--i]='\0';
        +			if (i < 1)
        +				{
        +				BIO_printf(bio_err,"zero length password\n");
        +				goto bad;
        +				}
        +			str=buf;
        +			}
        +		else if (strcmp(*argv,"-K") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			hkey= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-S") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			hsalt= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-iv") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			hiv= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-md") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			md= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-non-fips-allow") == 0)
        +			non_fips_allow = 1;
        +		else if	((argv[0][0] == '-') &&
        +			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
        +			{
        +			cipher=c;
        +			}
        +		else if (strcmp(*argv,"-none") == 0)
        +			cipher=NULL;
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
        +bad:
        +			BIO_printf(bio_err,"options are\n");
        +			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
        +			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
        +			BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
        +			BIO_printf(bio_err,"%-14s encrypt\n","-e");
        +			BIO_printf(bio_err,"%-14s decrypt\n","-d");
        +			BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
        +			BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
        +			BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
        +			BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
        +			BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
        +			BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S");
        +			BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
        +			BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
        +			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
        +			BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad");
        +#ifndef OPENSSL_NO_ENGINE
        +			BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
        +#endif
        +
        +			BIO_printf(bio_err,"Cipher Types\n");
        +			OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
        +					       show_ciphers,
        +					       bio_err);
        +			BIO_printf(bio_err,"\n");
        +
        +			goto end;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
        +		{
        +		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
        +		goto end;
        +		}
        +
        +	if (dgst == NULL)
        +		{
        +		dgst = EVP_md5();
        +		}
        +
        +	if (bufsize != NULL)
        +		{
        +		unsigned long n;
        +
        +		for (n=0; *bufsize; bufsize++)
        +			{
        +			i= *bufsize;
        +			if ((i <= '9') && (i >= '0'))
        +				n=n*10+i-'0';
        +			else if (i == 'k')
        +				{
        +				n*=1024;
        +				bufsize++;
        +				break;
        +				}
        +			}
        +		if (*bufsize != '\0')
        +			{
        +			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
        +			goto end;
        +			}
        +
        +		/* It must be large enough for a base64 encoded line */
        +		if (base64 && n < 80) n=80;
        +
        +		bsize=(int)n;
        +		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
        +		}
        +
        +	strbuf=OPENSSL_malloc(SIZE);
        +	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
        +	if ((buff == NULL) || (strbuf == NULL))
        +		{
        +		BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
        +		goto end;
        +		}
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	if (debug)
        +		{
        +		BIO_set_callback(in,BIO_debug_callback);
        +		BIO_set_callback(out,BIO_debug_callback);
        +		BIO_set_callback_arg(in,(char *)bio_err);
        +		BIO_set_callback_arg(out,(char *)bio_err);
        +		}
        +
        +	if (inf == NULL)
        +	        {
        +#ifndef OPENSSL_NO_SETVBUF_IONBF
        +		if (bufsize != NULL)
        +			setvbuf(stdin, (char *)NULL, _IONBF, 0);
        +#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	        }
        +	else
        +		{
        +		if (BIO_read_filename(in,inf) <= 0)
        +			{
        +			perror(inf);
        +			goto end;
        +			}
        +		}
        +
        +	if(!str && passarg) {
        +		if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
        +			BIO_printf(bio_err, "Error getting password\n");
        +			goto end;
        +		}
        +		str = pass;
        +	}
        +
        +	if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
        +		{
        +		for (;;)
        +			{
        +			char buf[200];
        +
        +			BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
        +				     OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
        +				     (enc)?"encryption":"decryption");
        +			strbuf[0]='\0';
        +			i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
        +			if (i == 0)
        +				{
        +				if (strbuf[0] == '\0')
        +					{
        +					ret=1;
        +					goto end;
        +					}
        +				str=strbuf;
        +				break;
        +				}
        +			if (i < 0)
        +				{
        +				BIO_printf(bio_err,"bad password read\n");
        +				goto end;
        +				}
        +			}
        +		}
        +
        +
        +	if (outf == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifndef OPENSSL_NO_SETVBUF_IONBF
        +		if (bufsize != NULL)
        +			setvbuf(stdout, (char *)NULL, _IONBF, 0);
        +#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outf) <= 0)
        +			{
        +			perror(outf);
        +			goto end;
        +			}
        +		}
        +
        +	rbio=in;
        +	wbio=out;
        +
        +#ifdef ZLIB
        +
        +	if (do_zlib)
        +		{
        +		if ((bzl=BIO_new(BIO_f_zlib())) == NULL)
        +			goto end;
        +		if (enc)
        +			wbio=BIO_push(bzl,wbio);
        +		else
        +			rbio=BIO_push(bzl,rbio);
        +		}
        +#endif
        +
        +	if (base64)
        +		{
        +		if ((b64=BIO_new(BIO_f_base64())) == NULL)
        +			goto end;
        +		if (debug)
        +			{
        +			BIO_set_callback(b64,BIO_debug_callback);
        +			BIO_set_callback_arg(b64,(char *)bio_err);
        +			}
        +		if (olb64)
        +			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
        +		if (enc)
        +			wbio=BIO_push(b64,wbio);
        +		else
        +			rbio=BIO_push(b64,rbio);
        +		}
        +
        +	if (cipher != NULL)
        +		{
        +		/* Note that str is NULL if a key was passed on the command
        +		 * line, so we get no salt in that case. Is this a bug?
        +		 */
        +		if (str != NULL)
        +			{
        +			/* Salt handling: if encrypting generate a salt and
        +			 * write to output BIO. If decrypting read salt from
        +			 * input BIO.
        +			 */
        +			unsigned char *sptr;
        +			if(nosalt) sptr = NULL;
        +			else {
        +				if(enc) {
        +					if(hsalt) {
        +						if(!set_hex(hsalt,salt,sizeof salt)) {
        +							BIO_printf(bio_err,
        +								"invalid hex salt value\n");
        +							goto end;
        +						}
        +					} else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
        +						goto end;
        +					/* If -P option then don't bother writing */
        +					if((printkey != 2)
        +					   && (BIO_write(wbio,magic,
        +							 sizeof magic-1) != sizeof magic-1
        +					       || BIO_write(wbio,
        +							    (char *)salt,
        +							    sizeof salt) != sizeof salt)) {
        +						BIO_printf(bio_err,"error writing output file\n");
        +						goto end;
        +					}
        +				} else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
        +					  || BIO_read(rbio,
        +						      (unsigned char *)salt,
        +				    sizeof salt) != sizeof salt) {
        +					BIO_printf(bio_err,"error reading input file\n");
        +					goto end;
        +				} else if(memcmp(mbuf,magic,sizeof magic-1)) {
        +				    BIO_printf(bio_err,"bad magic number\n");
        +				    goto end;
        +				}
        +
        +				sptr = salt;
        +			}
        +
        +			EVP_BytesToKey(cipher,dgst,sptr,
        +				(unsigned char *)str,
        +				strlen(str),1,key,iv);
        +			/* zero the complete buffer or the string
        +			 * passed from the command line
        +			 * bug picked up by
        +			 * Larry J. Hughes Jr. <hughes@indiana.edu> */
        +			if (str == strbuf)
        +				OPENSSL_cleanse(str,SIZE);
        +			else
        +				OPENSSL_cleanse(str,strlen(str));
        +			}
        +		if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
        +			{
        +			BIO_printf(bio_err,"invalid hex iv value\n");
        +			goto end;
        +			}
        +		if ((hiv == NULL) && (str == NULL)
        +		    && EVP_CIPHER_iv_length(cipher) != 0)
        +			{
        +			/* No IV was explicitly set and no IV was generated
        +			 * during EVP_BytesToKey. Hence the IV is undefined,
        +			 * making correct decryption impossible. */
        +			BIO_printf(bio_err, "iv undefined\n");
        +			goto end;
        +			}
        +		if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
        +			{
        +			BIO_printf(bio_err,"invalid hex key value\n");
        +			goto end;
        +			}
        +
        +		if ((benc=BIO_new(BIO_f_cipher())) == NULL)
        +			goto end;
        +
        +		/* Since we may be changing parameters work on the encryption
        +		 * context rather than calling BIO_set_cipher().
        +		 */
        +
        +		BIO_get_cipher_ctx(benc, &ctx);
        +
        +		if (non_fips_allow)
        +			EVP_CIPHER_CTX_set_flags(ctx,
        +				EVP_CIPH_FLAG_NON_FIPS_ALLOW);
        +
        +		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
        +			{
        +			BIO_printf(bio_err, "Error setting cipher %s\n",
        +				EVP_CIPHER_name(cipher));
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		if (nopad)
        +			EVP_CIPHER_CTX_set_padding(ctx, 0);
        +
        +		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
        +			{
        +			BIO_printf(bio_err, "Error setting cipher %s\n",
        +				EVP_CIPHER_name(cipher));
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		if (debug)
        +			{
        +			BIO_set_callback(benc,BIO_debug_callback);
        +			BIO_set_callback_arg(benc,(char *)bio_err);
        +			}
        +
        +		if (printkey)
        +			{
        +			if (!nosalt)
        +				{
        +				printf("salt=");
        +				for (i=0; i<(int)sizeof(salt); i++)
        +					printf("%02X",salt[i]);
        +				printf("\n");
        +				}
        +			if (cipher->key_len > 0)
        +				{
        +				printf("key=");
        +				for (i=0; i<cipher->key_len; i++)
        +					printf("%02X",key[i]);
        +				printf("\n");
        +				}
        +			if (cipher->iv_len > 0)
        +				{
        +				printf("iv =");
        +				for (i=0; i<cipher->iv_len; i++)
        +					printf("%02X",iv[i]);
        +				printf("\n");
        +				}
        +			if (printkey == 2)
        +				{
        +				ret=0;
        +				goto end;
        +				}
        +			}
        +		}
        +
        +	/* Only encrypt/decrypt as we write the file */
        +	if (benc != NULL)
        +		wbio=BIO_push(benc,wbio);
        +
        +	for (;;)
        +		{
        +		inl=BIO_read(rbio,(char *)buff,bsize);
        +		if (inl <= 0) break;
        +		if (BIO_write(wbio,(char *)buff,inl) != inl)
        +			{
        +			BIO_printf(bio_err,"error writing output file\n");
        +			goto end;
        +			}
        +		}
        +	if (!BIO_flush(wbio))
        +		{
        +		BIO_printf(bio_err,"bad decrypt\n");
        +		goto end;
        +		}
        +
        +	ret=0;
        +	if (verbose)
        +		{
        +		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
        +		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
        +		}
        +end:
        +	ERR_print_errors(bio_err);
        +	if (strbuf != NULL) OPENSSL_free(strbuf);
        +	if (buff != NULL) OPENSSL_free(buff);
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (benc != NULL) BIO_free(benc);
        +	if (b64 != NULL) BIO_free(b64);
        +#ifdef ZLIB
        +	if (bzl != NULL) BIO_free(bzl);
        +#endif
        +	if(pass) OPENSSL_free(pass);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +int set_hex(char *in, unsigned char *out, int size)
        +	{
        +	int i,n;
        +	unsigned char j;
        +
        +	n=strlen(in);
        +	if (n > (size*2))
        +		{
        +		BIO_printf(bio_err,"hex string is too long\n");
        +		return(0);
        +		}
        +	memset(out,0,size);
        +	for (i=0; i<n; i++)
        +		{
        +		j=(unsigned char)*in;
        +		*(in++)='\0';
        +		if (j == 0) break;
        +		if ((j >= '0') && (j <= '9'))
        +			j-='0';
        +		else if ((j >= 'A') && (j <= 'F'))
        +			j=j-'A'+10;
        +		else if ((j >= 'a') && (j <= 'f'))
        +			j=j-'a'+10;
        +		else
        +			{
        +			BIO_printf(bio_err,"non-hex digit\n");
        +			return(0);
        +			}
        +		if (i&1)
        +			out[i/2]|=j;
        +		else
        +			out[i/2]=(j<<4);
        +		}
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/apps/engine.c b/vendor/openssl/openssl/apps/engine.c
        new file mode 100644
        index 000000000..9a0294398
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/engine.c
        @@ -0,0 +1,549 @@
        +/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */
        +/* 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 <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +#include "apps.h"
        +#include <openssl/err.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#include <openssl/ssl.h>
        +
        +#undef PROG
        +#define PROG	engine_main
        +
        +static const char *engine_usage[]={
        +"usage: engine opts [engine ...]\n",
        +" -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n",
        +"               -vv will additionally display each command's description\n",
        +"               -vvv will also add the input flags for each command\n",
        +"               -vvvv will also show internal input flags\n",
        +" -c          - for each engine, also list the capabilities\n",
        +" -t[t]       - for each engine, check that they are really available\n",
        +"               -tt will display error trace for unavailable engines\n",
        +" -pre <cmd>  - runs command 'cmd' against the ENGINE before any attempts\n",
        +"               to load it (if -t is used)\n",
        +" -post <cmd> - runs command 'cmd' against the ENGINE after loading it\n",
        +"               (only used if -t is also provided)\n",
        +" NB: -pre and -post will be applied to all ENGINEs supplied on the command\n",
        +" line, or all supported ENGINEs if none are specified.\n",
        +" Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n",
        +" argument \"/lib/libdriver.so\".\n",
        +NULL
        +};
        +
        +static void identity(char *ptr)
        +	{
        +	return;
        +	}
        +
        +static int append_buf(char **buf, const char *s, int *size, int step)
        +	{
        +	int l = strlen(s);
        +
        +	if (*buf == NULL)
        +		{
        +		*size = step;
        +		*buf = OPENSSL_malloc(*size);
        +		if (*buf == NULL)
        +			return 0;
        +		**buf = '\0';
        +		}
        +
        +	if (**buf != '\0')
        +		l += 2;		/* ", " */
        +
        +	if (strlen(*buf) + strlen(s) >= (unsigned int)*size)
        +		{
        +		*size += step;
        +		*buf = OPENSSL_realloc(*buf, *size);
        +		}
        +
        +	if (*buf == NULL)
        +		return 0;
        +
        +	if (**buf != '\0')
        +		BUF_strlcat(*buf, ", ", *size);
        +	BUF_strlcat(*buf, s, *size);
        +
        +	return 1;
        +	}
        +
        +static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
        +	{
        +	int started = 0, err = 0;
        +	/* Indent before displaying input flags */
        +	BIO_printf(bio_out, "%s%s(input flags): ", indent, indent);
        +	if(flags == 0)
        +		{
        +		BIO_printf(bio_out, "<no flags>\n");
        +		return 1;
        +		}
        +        /* If the object is internal, mark it in a way that shows instead of
        +         * having it part of all the other flags, even if it really is. */
        +	if(flags & ENGINE_CMD_FLAG_INTERNAL)
        +		{
        +		BIO_printf(bio_out, "[Internal] ");
        +		}
        +
        +	if(flags & ENGINE_CMD_FLAG_NUMERIC)
        +		{
        +		BIO_printf(bio_out, "NUMERIC");
        +		started = 1;
        +		}
        +	/* Now we check that no combinations of the mutually exclusive NUMERIC,
        +	 * STRING, and NO_INPUT flags have been used. Future flags that can be
        +	 * OR'd together with these would need to added after these to preserve
        +	 * the testing logic. */
        +	if(flags & ENGINE_CMD_FLAG_STRING)
        +		{
        +		if(started)
        +			{
        +			BIO_printf(bio_out, "|");
        +			err = 1;
        +			}
        +		BIO_printf(bio_out, "STRING");
        +		started = 1;
        +		}
        +	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
        +		{
        +		if(started)
        +			{
        +			BIO_printf(bio_out, "|");
        +			err = 1;
        +			}
        +		BIO_printf(bio_out, "NO_INPUT");
        +		started = 1;
        +		}
        +	/* Check for unknown flags */
        +	flags = flags & ~ENGINE_CMD_FLAG_NUMERIC &
        +			~ENGINE_CMD_FLAG_STRING &
        +			~ENGINE_CMD_FLAG_NO_INPUT &
        +			~ENGINE_CMD_FLAG_INTERNAL;
        +	if(flags)
        +		{
        +		if(started) BIO_printf(bio_out, "|");
        +		BIO_printf(bio_out, "<0x%04X>", flags);
        +		}
        +	if(err)
        +		BIO_printf(bio_out, "  <illegal flags!>");
        +	BIO_printf(bio_out, "\n");
        +	return 1;
        +	}
        +
        +static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent)
        +	{
        +	static const int line_wrap = 78;
        +	int num;
        +	int ret = 0;
        +	char *name = NULL;
        +	char *desc = NULL;
        +	int flags;
        +	int xpos = 0;
        +	STACK_OF(OPENSSL_STRING) *cmds = NULL;
        +	if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
        +			((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
        +					0, NULL, NULL)) <= 0))
        +		{
        +#if 0
        +		BIO_printf(bio_out, "%s<no control commands>\n", indent);
        +#endif
        +		return 1;
        +		}
        +
        +	cmds = sk_OPENSSL_STRING_new_null();
        +
        +	if(!cmds)
        +		goto err;
        +	do {
        +		int len;
        +		/* Get the command input flags */
        +		if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
        +					NULL, NULL)) < 0)
        +			goto err;
        +                if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4)
        +                        {
        +                        /* Get the command name */
        +                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num,
        +                                NULL, NULL)) <= 0)
        +                                goto err;
        +                        if((name = OPENSSL_malloc(len + 1)) == NULL)
        +                                goto err;
        +                        if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name,
        +                                NULL) <= 0)
        +                                goto err;
        +                        /* Get the command description */
        +                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num,
        +                                NULL, NULL)) < 0)
        +                                goto err;
        +                        if(len > 0)
        +                                {
        +                                if((desc = OPENSSL_malloc(len + 1)) == NULL)
        +                                        goto err;
        +                                if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc,
        +                                        NULL) <= 0)
        +                                        goto err;
        +                                }
        +                        /* Now decide on the output */
        +                        if(xpos == 0)
        +                                /* Do an indent */
        +                                xpos = BIO_puts(bio_out, indent);
        +                        else
        +                                /* Otherwise prepend a ", " */
        +                                xpos += BIO_printf(bio_out, ", ");
        +                        if(verbose == 1)
        +                                {
        +                                /* We're just listing names, comma-delimited */
        +                                if((xpos > (int)strlen(indent)) &&
        +					(xpos + (int)strlen(name) > line_wrap))
        +                                        {
        +                                        BIO_printf(bio_out, "\n");
        +                                        xpos = BIO_puts(bio_out, indent);
        +                                        }
        +                                xpos += BIO_printf(bio_out, "%s", name);
        +                                }
        +                        else
        +                                {
        +                                /* We're listing names plus descriptions */
        +                                BIO_printf(bio_out, "%s: %s\n", name,
        +                                        (desc == NULL) ? "<no description>" : desc);
        +                                /* ... and sometimes input flags */
        +                                if((verbose >= 3) && !util_flags(bio_out, flags,
        +                                        indent))
        +                                        goto err;
        +                                xpos = 0;
        +                                }
        +                        }
        +		OPENSSL_free(name); name = NULL;
        +		if(desc) { OPENSSL_free(desc); desc = NULL; }
        +		/* Move to the next command */
        +		num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE,
        +					num, NULL, NULL);
        +		} while(num > 0);
        +	if(xpos > 0)
        +		BIO_printf(bio_out, "\n");
        +	ret = 1;
        +err:
        +	if(cmds) sk_OPENSSL_STRING_pop_free(cmds, identity);
        +	if(name) OPENSSL_free(name);
        +	if(desc) OPENSSL_free(desc);
        +	return ret;
        +	}
        +
        +static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
        +			BIO *bio_out, const char *indent)
        +	{
        +	int loop, res, num = sk_OPENSSL_STRING_num(cmds);
        +
        +	if(num < 0)
        +		{
        +		BIO_printf(bio_out, "[Error]: internal stack error\n");
        +		return;
        +		}
        +	for(loop = 0; loop < num; loop++)
        +		{
        +		char buf[256];
        +		const char *cmd, *arg;
        +		cmd = sk_OPENSSL_STRING_value(cmds, loop);
        +		res = 1; /* assume success */
        +		/* Check if this command has no ":arg" */
        +		if((arg = strstr(cmd, ":")) == NULL)
        +			{
        +			if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
        +				res = 0;
        +			}
        +		else
        +			{
        +			if((int)(arg - cmd) > 254)
        +				{
        +				BIO_printf(bio_out,"[Error]: command name too long\n");
        +				return;
        +				}
        +			memcpy(buf, cmd, (int)(arg - cmd));
        +			buf[arg-cmd] = '\0';
        +			arg++; /* Move past the ":" */
        +			/* Call the command with the argument */
        +			if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
        +				res = 0;
        +			}
        +		if(res)
        +			BIO_printf(bio_out, "[Success]: %s\n", cmd);
        +		else
        +			{
        +			BIO_printf(bio_out, "[Failure]: %s\n", cmd);
        +			ERR_print_errors(bio_out);
        +			}
        +		}
        +	}
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int ret=1,i;
        +	const char **pp;
        +	int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0;
        +	ENGINE *e;
        +	STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null();
        +	STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
        +	STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
        +	int badops=1;
        +	BIO *bio_out=NULL;
        +	const char *indent = "     ";
        +
        +	apps_startup();
        +	SSL_load_error_strings();
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +	bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +	{
        +	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	bio_out = BIO_push(tmpbio, bio_out);
        +	}
        +#endif
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if (strncmp(*argv,"-v",2) == 0)
        +			{
        +			if(strspn(*argv + 1, "v") < strlen(*argv + 1))
        +				goto skip_arg_loop;
        +			if((verbose=strlen(*argv + 1)) > 4)
        +				goto skip_arg_loop;
        +			}
        +		else if (strcmp(*argv,"-c") == 0)
        +			list_cap=1;
        +		else if (strncmp(*argv,"-t",2) == 0)
        +			{
        +			test_avail=1;
        +			if(strspn(*argv + 1, "t") < strlen(*argv + 1))
        +				goto skip_arg_loop;
        +			if((test_avail_noise = strlen(*argv + 1) - 1) > 1)
        +				goto skip_arg_loop;
        +			}
        +		else if (strcmp(*argv,"-pre") == 0)
        +			{
        +			argc--; argv++;
        +			if (argc == 0)
        +				goto skip_arg_loop;
        +			sk_OPENSSL_STRING_push(pre_cmds,*argv);
        +			}
        +		else if (strcmp(*argv,"-post") == 0)
        +			{
        +			argc--; argv++;
        +			if (argc == 0)
        +				goto skip_arg_loop;
        +			sk_OPENSSL_STRING_push(post_cmds,*argv);
        +			}
        +		else if ((strncmp(*argv,"-h",2) == 0) ||
        +				(strcmp(*argv,"-?") == 0))
        +			goto skip_arg_loop;
        +		else
        +			sk_OPENSSL_STRING_push(engines,*argv);
        +		argc--;
        +		argv++;
        +		}
        +	/* Looks like everything went OK */
        +	badops = 0;
        +skip_arg_loop:
        +
        +	if (badops)
        +		{
        +		for (pp=engine_usage; (*pp != NULL); pp++)
        +			BIO_printf(bio_err,"%s",*pp);
        +		goto end;
        +		}
        +
        +	if (sk_OPENSSL_STRING_num(engines) == 0)
        +		{
        +		for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
        +			{
        +			sk_OPENSSL_STRING_push(engines,(char *)ENGINE_get_id(e));
        +			}
        +		}
        +
        +	for (i=0; i<sk_OPENSSL_STRING_num(engines); i++)
        +		{
        +		const char *id = sk_OPENSSL_STRING_value(engines,i);
        +		if ((e = ENGINE_by_id(id)) != NULL)
        +			{
        +			const char *name = ENGINE_get_name(e);
        +			/* Do "id" first, then "name". Easier to auto-parse. */
        +			BIO_printf(bio_out, "(%s) %s\n", id, name);
        +			util_do_cmds(e, pre_cmds, bio_out, indent);
        +			if (strcmp(ENGINE_get_id(e), id) != 0)
        +				{
        +				BIO_printf(bio_out, "Loaded: (%s) %s\n",
        +					ENGINE_get_id(e), ENGINE_get_name(e));
        +				}
        +			if (list_cap)
        +				{
        +				int cap_size = 256;
        +				char *cap_buf = NULL;
        +				int k,n;
        +				const int *nids;
        +				ENGINE_CIPHERS_PTR fn_c;
        +				ENGINE_DIGESTS_PTR fn_d;
        +				ENGINE_PKEY_METHS_PTR fn_pk;
        +
        +				if (ENGINE_get_RSA(e) != NULL
        +					&& !append_buf(&cap_buf, "RSA",
        +						&cap_size, 256))
        +					goto end;
        +				if (ENGINE_get_DSA(e) != NULL
        +					&& !append_buf(&cap_buf, "DSA",
        +						&cap_size, 256))
        +					goto end;
        +				if (ENGINE_get_DH(e) != NULL
        +					&& !append_buf(&cap_buf, "DH",
        +						&cap_size, 256))
        +					goto end;
        +				if (ENGINE_get_RAND(e) != NULL
        +					&& !append_buf(&cap_buf, "RAND",
        +						&cap_size, 256))
        +					goto end;
        +
        +				fn_c = ENGINE_get_ciphers(e);
        +				if(!fn_c) goto skip_ciphers;
        +				n = fn_c(e, NULL, &nids, 0);
        +				for(k=0 ; k < n ; ++k)
        +					if(!append_buf(&cap_buf,
        +						       OBJ_nid2sn(nids[k]),
        +						       &cap_size, 256))
        +						goto end;
        +
        +skip_ciphers:
        +				fn_d = ENGINE_get_digests(e);
        +				if(!fn_d) goto skip_digests;
        +				n = fn_d(e, NULL, &nids, 0);
        +				for(k=0 ; k < n ; ++k)
        +					if(!append_buf(&cap_buf,
        +						       OBJ_nid2sn(nids[k]),
        +						       &cap_size, 256))
        +						goto end;
        +
        +skip_digests:
        +				fn_pk = ENGINE_get_pkey_meths(e);
        +				if(!fn_pk) goto skip_pmeths;
        +				n = fn_pk(e, NULL, &nids, 0);
        +				for(k=0 ; k < n ; ++k)
        +					if(!append_buf(&cap_buf,
        +						       OBJ_nid2sn(nids[k]),
        +						       &cap_size, 256))
        +						goto end;
        +skip_pmeths:
        +				if (cap_buf && (*cap_buf != '\0'))
        +					BIO_printf(bio_out, " [%s]\n", cap_buf);
        +
        +				OPENSSL_free(cap_buf);
        +				}
        +			if(test_avail)
        +				{
        +				BIO_printf(bio_out, "%s", indent);
        +				if (ENGINE_init(e))
        +					{
        +					BIO_printf(bio_out, "[ available ]\n");
        +					util_do_cmds(e, post_cmds, bio_out, indent);
        +					ENGINE_finish(e);
        +					}
        +				else
        +					{
        +					BIO_printf(bio_out, "[ unavailable ]\n");
        +					if(test_avail_noise)
        +						ERR_print_errors_fp(stdout);
        +					ERR_clear_error();
        +					}
        +				}
        +			if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent))
        +				goto end;
        +			ENGINE_free(e);
        +			}
        +		else
        +			ERR_print_errors(bio_err);
        +		}
        +
        +	ret=0;
        +end:
        +
        +	ERR_print_errors(bio_err);
        +	sk_OPENSSL_STRING_pop_free(engines, identity);
        +	sk_OPENSSL_STRING_pop_free(pre_cmds, identity);
        +	sk_OPENSSL_STRING_pop_free(post_cmds, identity);
        +	if (bio_out != NULL) BIO_free_all(bio_out);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +#else
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/errstr.c b/vendor/openssl/openssl/apps/errstr.c
        new file mode 100644
        index 000000000..fe3b98077
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/errstr.c
        @@ -0,0 +1,128 @@
        +/* apps/errstr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/lhash.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +#undef PROG
        +#define PROG	errstr_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int i,ret=0;
        +	char buf[256];
        +	unsigned long l;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	SSL_load_error_strings();
        +
        +	if ((argc > 1) && (strcmp(argv[1],"-stats") == 0))
        +		{
        +		BIO *out=NULL;
        +
        +		out=BIO_new(BIO_s_file());
        +		if ((out != NULL) && BIO_set_fp(out,stdout,BIO_NOCLOSE))
        +			{
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +			lh_ERR_STRING_DATA_node_stats_bio(
        +						  ERR_get_string_table(), out);
        +			lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(),
        +						     out);
        +			lh_ERR_STRING_DATA_node_usage_stats_bio(
        +						    ERR_get_string_table(),out);
        +			}
        +		if (out != NULL) BIO_free_all(out);
        +		argc--;
        +		argv++;
        +		}
        +
        +	for (i=1; i<argc; i++)
        +		{
        +		if (sscanf(argv[i],"%lx",&l))
        +			{
        +			ERR_error_string_n(l, buf, sizeof buf);
        +			printf("%s\n",buf);
        +			}
        +		else
        +			{
        +			printf("%s: bad error code\n",argv[i]);
        +			printf("usage: errstr [-stats] <errno> ...\n");
        +			ret++;
        +			}
        +		}
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        diff --git a/vendor/openssl/openssl/apps/gendh.c b/vendor/openssl/openssl/apps/gendh.c
        new file mode 100644
        index 000000000..4ec776ba9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/gendh.c
        @@ -0,0 +1,241 @@
        +/* apps/gendh.c */
        +/* obsoleted by dhparam.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 <openssl/opensslconf.h>
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +#include <stdio.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include <sys/stat.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#define DEFBITS	512
        +#undef PROG
        +#define PROG gendh_main
        +
        +static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	BN_GENCB cb;
        +	DH *dh=NULL;
        +	int ret=1,num=DEFBITS;
        +	int g=2;
        +	char *outfile=NULL;
        +	char *inrand=NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	BIO *out=NULL;
        +
        +	apps_startup();
        +
        +	BN_GENCB_set(&cb, dh_cb, bio_err);
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	argv++;
        +	argc--;
        +	for (;;)
        +		{
        +		if (argc <= 0) break;
        +		if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-2") == 0)
        +			g=2;
        +	/*	else if (strcmp(*argv,"-3") == 0)
        +			g=3; */
        +		else if (strcmp(*argv,"-5") == 0)
        +			g=5;
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +		else
        +			break;
        +		argv++;
        +		argc--;
        +		}
        +	if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
        +		{
        +bad:
        +		BIO_printf(bio_err,"usage: gendh [args] [numbits]\n");
        +		BIO_printf(bio_err," -out file - output the key to 'file\n");
        +		BIO_printf(bio_err," -2        - use 2 as the generator value\n");
        +	/*	BIO_printf(bio_err," -3        - use 3 as the generator value\n"); */
        +		BIO_printf(bio_err," -5        - use 5 as the generator value\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,"           - load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,"             the random number generator\n");
        +		goto end;
        +		}
        +		
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
        +		{
        +		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
        +		}
        +	if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +
        +	BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
        +	BIO_printf(bio_err,"This is going to take a long time\n");
        +
        +	if(((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb))
        +		goto end;
        +		
        +	app_RAND_write_file(NULL, bio_err);
        +
        +	if (!PEM_write_bio_DHparams(out,dh))
        +		goto end;
        +	ret=0;
        +end:
        +	if (ret != 0)
        +		ERR_print_errors(bio_err);
        +	if (out != NULL) BIO_free_all(out);
        +	if (dh != NULL) DH_free(dh);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(cb->arg,&c,1);
        +	(void)BIO_flush(cb->arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        +#else /* !OPENSSL_NO_DH */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/gendsa.c b/vendor/openssl/openssl/apps/gendsa.c
        new file mode 100644
        index 000000000..62ea97790
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/gendsa.c
        @@ -0,0 +1,285 @@
        +/* apps/gendsa.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 <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
        +#ifndef OPENSSL_NO_DSA
        +#include <stdio.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include <sys/stat.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/dsa.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#define DEFBITS	512
        +#undef PROG
        +#define PROG gendsa_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	DSA *dsa=NULL;
        +	int ret=1;
        +	char *outfile=NULL;
        +	char *inrand=NULL,*dsaparams=NULL;
        +	char *passargout = NULL, *passout = NULL;
        +	BIO *out=NULL,*in=NULL;
        +	const EVP_CIPHER *enc=NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	argv++;
        +	argc--;
        +	for (;;)
        +		{
        +		if (argc <= 0) break;
        +		if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-") == 0)
        +			goto bad;
        +#ifndef OPENSSL_NO_DES
        +		else if (strcmp(*argv,"-des") == 0)
        +			enc=EVP_des_cbc();
        +		else if (strcmp(*argv,"-des3") == 0)
        +			enc=EVP_des_ede3_cbc();
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +		else if (strcmp(*argv,"-idea") == 0)
        +			enc=EVP_idea_cbc();
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		else if (strcmp(*argv,"-seed") == 0)
        +			enc=EVP_seed_cbc();
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		else if (strcmp(*argv,"-aes128") == 0)
        +			enc=EVP_aes_128_cbc();
        +		else if (strcmp(*argv,"-aes192") == 0)
        +			enc=EVP_aes_192_cbc();
        +		else if (strcmp(*argv,"-aes256") == 0)
        +			enc=EVP_aes_256_cbc();
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		else if (strcmp(*argv,"-camellia128") == 0)
        +			enc=EVP_camellia_128_cbc();
        +		else if (strcmp(*argv,"-camellia192") == 0)
        +			enc=EVP_camellia_192_cbc();
        +		else if (strcmp(*argv,"-camellia256") == 0)
        +			enc=EVP_camellia_256_cbc();
        +#endif
        +		else if (**argv != '-' && dsaparams == NULL)
        +			{
        +			dsaparams = *argv;
        +			}
        +		else
        +			goto bad;
        +		argv++;
        +		argc--;
        +		}
        +
        +	if (dsaparams == NULL)
        +		{
        +bad:
        +		BIO_printf(bio_err,"usage: gendsa [args] dsaparam-file\n");
        +		BIO_printf(bio_err," -out file - output the key to 'file'\n");
        +#ifndef OPENSSL_NO_DES
        +		BIO_printf(bio_err," -des      - encrypt the generated key with DES in cbc mode\n");
        +		BIO_printf(bio_err," -des3     - encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +		BIO_printf(bio_err," -idea     - encrypt the generated key with IDEA in cbc mode\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		BIO_printf(bio_err," -seed\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc seed\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,"           - load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,"             the random number generator\n");
        +		BIO_printf(bio_err," dsaparam-file\n");
        +		BIO_printf(bio_err,"           - a DSA parameter file as generated by the dsaparam command\n");
        +		goto end;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +	}
        +
        +
        +	in=BIO_new(BIO_s_file());
        +	if (!(BIO_read_filename(in,dsaparams)))
        +		{
        +		perror(dsaparams);
        +		goto end;
        +		}
        +
        +	if ((dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load DSA parameter file\n");
        +		goto end;
        +		}
        +	BIO_free(in);
        +	in = NULL;
        +		
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) goto end;
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
        +		{
        +		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
        +		}
        +	if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +
        +	BIO_printf(bio_err,"Generating DSA key, %d bits\n",
        +							BN_num_bits(dsa->p));
        +	if (!DSA_generate_key(dsa)) goto end;
        +
        +	app_RAND_write_file(NULL, bio_err);
        +
        +	if (!PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL, passout))
        +		goto end;
        +	ret=0;
        +end:
        +	if (ret != 0)
        +		ERR_print_errors(bio_err);
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	if (dsa != NULL) DSA_free(dsa);
        +	if(passout) OPENSSL_free(passout);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +#else /* !OPENSSL_NO_DSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/genpkey.c b/vendor/openssl/openssl/apps/genpkey.c
        new file mode 100644
        index 000000000..6dfda08b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/genpkey.c
        @@ -0,0 +1,440 @@
        +/* apps/genpkey.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
        +				const char *file, ENGINE *e);
        +static int genpkey_cb(EVP_PKEY_CTX *ctx);
        +
        +#define PROG genpkey_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	char **args, *outfile = NULL;
        +	char *passarg = NULL;
        +	BIO *in = NULL, *out = NULL;
        +	const EVP_CIPHER *cipher = NULL;
        +	int outformat;
        +	int text = 0;
        +	EVP_PKEY *pkey=NULL;
        +	EVP_PKEY_CTX *ctx = NULL;
        +	char *pass = NULL;
        +	int badarg = 0;
        +	int ret = 1, rv;
        +
        +	int do_param = 0;
        +
        +	if (bio_err == NULL)
        +		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	outformat=FORMAT_PEM;
        +
        +	ERR_load_crypto_strings();
        +	OpenSSL_add_all_algorithms();
        +	args = argv + 1;
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp(*args,"-outform"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outformat=str2fmt(*args);
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args,"-pass"))
        +			{
        +			if (!args[1]) goto bad;
        +			passarg= *(++args);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*args,"-engine") == 0)
        +			{
        +			if (!args[1])
        +				goto bad;
        +        		e = setup_engine(bio_err, *(++args), 0);
        +			}
        +#endif
        +		else if (!strcmp (*args, "-paramfile"))
        +			{
        +			if (!args[1])
        +				goto bad;
        +			args++;
        +			if (do_param == 1)
        +				goto bad;
        +			if (!init_keygen_file(bio_err, &ctx, *args, e))
        +				goto end;
        +			}
        +		else if (!strcmp (*args, "-out"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (strcmp(*args,"-algorithm") == 0)
        +			{
        +			if (!args[1])
        +				goto bad;
        +			if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
        +				goto end;
        +			}
        +		else if (strcmp(*args,"-pkeyopt") == 0)
        +			{
        +			if (!args[1])
        +				goto bad;
        +			if (!ctx)
        +				{
        +				BIO_puts(bio_err, "No keytype specified\n");
        +				goto bad;
        +				}
        +			else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
        +				{
        +				BIO_puts(bio_err, "parameter setting error\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		else if (strcmp(*args,"-genparam") == 0)
        +			{
        +			if (ctx)
        +				goto bad;
        +			do_param = 1;
        +			}
        +		else if (strcmp(*args,"-text") == 0)
        +			text=1;
        +		else
        +			{
        +			cipher = EVP_get_cipherbyname(*args + 1);
        +			if (!cipher)
        +				{
        +				BIO_printf(bio_err, "Unknown cipher %s\n",
        +								*args + 1);
        +				badarg = 1;
        +				}
        +			if (do_param == 1)
        +				badarg = 1;
        +			}
        +		args++;
        +		}
        +
        +	if (!ctx)
        +		badarg = 1;
        +
        +	if (badarg)
        +		{
        +		bad:
        +		BIO_printf(bio_err, "Usage: genpkey [options]\n");
        +		BIO_printf(bio_err, "where options may be\n");
        +		BIO_printf(bio_err, "-out file          output file\n");
        +		BIO_printf(bio_err, "-outform X         output format (DER or PEM)\n");
        +		BIO_printf(bio_err, "-pass arg          output file pass phrase source\n");
        +		BIO_printf(bio_err, "-<cipher>          use cipher <cipher> to encrypt the key\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err, "-engine e          use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err, "-paramfile file    parameters file\n");
        +		BIO_printf(bio_err, "-algorithm alg     the public key algorithm\n");
        +		BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
        +				            "                   to value <value>\n");
        +		BIO_printf(bio_err, "-genparam          generate parameters, not key\n");
        +		BIO_printf(bio_err, "-text              print the in text\n");
        +		BIO_printf(bio_err, "NB: options order may be important!  See the manual page.\n");
        +		goto end;
        +		}
        +
        +	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
        +		{
        +		BIO_puts(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +	if (outfile)
        +		{
        +		if (!(out = BIO_new_file (outfile, "wb")))
        +			{
        +			BIO_printf(bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp (stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +		}
        +
        +	EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
        +	EVP_PKEY_CTX_set_app_data(ctx, bio_err);
        +
        +	if (do_param)
        +		{
        +		if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
        +			{
        +			BIO_puts(bio_err, "Error generating parameters\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
        +			{
        +			BIO_puts(bio_err, "Error generating key\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (do_param)
        +		rv = PEM_write_bio_Parameters(out, pkey);
        +	else if (outformat == FORMAT_PEM) 
        +		rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
        +								NULL, pass);
        +	else if (outformat == FORMAT_ASN1)
        +		rv = i2d_PrivateKey_bio(out, pkey);
        +	else
        +		{
        +		BIO_printf(bio_err, "Bad format specified for key\n");
        +		goto end;
        +		}
        +
        +	if (rv <= 0)
        +		{
        +		BIO_puts(bio_err, "Error writing key\n");
        +		ERR_print_errors(bio_err);
        +		}
        +
        +	if (text)
        +		{
        +		if (do_param)
        +			rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
        +		else
        +			rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
        +
        +		if (rv <= 0)
        +			{
        +			BIO_puts(bio_err, "Error printing key\n");
        +			ERR_print_errors(bio_err);
        +			}
        +		}
        +
        +	ret = 0;
        +
        +	end:
        +	if (pkey)
        +		EVP_PKEY_free(pkey);
        +	if (ctx)
        +		EVP_PKEY_CTX_free(ctx);
        +	if (out)
        +		BIO_free_all(out);
        +	BIO_free(in);
        +	if (pass)
        +		OPENSSL_free(pass);
        +
        +	return ret;
        +	}
        +
        +static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
        +				const char *file, ENGINE *e)
        +	{
        +	BIO *pbio;
        +	EVP_PKEY *pkey = NULL;
        +	EVP_PKEY_CTX *ctx = NULL;
        +	if (*pctx)
        +		{
        +		BIO_puts(err, "Parameters already set!\n");
        +		return 0;
        +		}
        +
        +	pbio = BIO_new_file(file, "r");
        +	if (!pbio)
        +		{
        +		BIO_printf(err, "Can't open parameter file %s\n", file);
        +		return 0;
        +		}
        +
        +	pkey = PEM_read_bio_Parameters(pbio, NULL);
        +	BIO_free(pbio);
        +
        +	if (!pkey)
        +		{
        +		BIO_printf(bio_err, "Error reading parameter file %s\n", file);
        +		return 0;
        +		}
        +
        +	ctx = EVP_PKEY_CTX_new(pkey, e);
        +	if (!ctx)
        +		goto err;
        +	if (EVP_PKEY_keygen_init(ctx) <= 0)
        +		goto err;
        +	EVP_PKEY_free(pkey);
        +	*pctx = ctx;
        +	return 1;
        +
        +	err:
        +	BIO_puts(err, "Error initializing context\n");
        +	ERR_print_errors(err);
        +	if (ctx)
        +		EVP_PKEY_CTX_free(ctx);
        +	if (pkey)
        +		EVP_PKEY_free(pkey);
        +	return 0;
        +
        +	}
        +
        +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
        +			const char *algname, ENGINE *e, int do_param)
        +	{
        +	EVP_PKEY_CTX *ctx = NULL;
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	ENGINE *tmpeng = NULL;
        +	int pkey_id;
        +
        +	if (*pctx)
        +		{
        +		BIO_puts(err, "Algorithm already set!\n");
        +		return 0;
        +		}
        +
        +	ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	if (!ameth && e)
        +		ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
        +#endif
        +
        +	if (!ameth)
        +		{
        +		BIO_printf(bio_err, "Algorithm %s not found\n", algname);
        +		return 0;
        +		}
        +
        +	ERR_clear_error();
        +
        +	EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (tmpeng)
        +		ENGINE_finish(tmpeng);
        +#endif
        +	ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
        +
        +	if (!ctx)
        +		goto err;
        +	if (do_param)
        +		{
        +		if (EVP_PKEY_paramgen_init(ctx) <= 0)
        +			goto err;
        +		}
        +	else
        +		{
        +		if (EVP_PKEY_keygen_init(ctx) <= 0)
        +			goto err;
        +		}
        +
        +	*pctx = ctx;
        +	return 1;
        +
        +	err:
        +	BIO_printf(err, "Error initializing %s context\n", algname);
        +	ERR_print_errors(err);
        +	if (ctx)
        +		EVP_PKEY_CTX_free(ctx);
        +	return 0;
        +
        +	}
        +
        +static int genpkey_cb(EVP_PKEY_CTX *ctx)
        +	{
        +	char c='*';
        +	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
        +	int p;
        +	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(b,&c,1);
        +	(void)BIO_flush(b);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/apps/genrsa.c b/vendor/openssl/openssl/apps/genrsa.c
        new file mode 100644
        index 000000000..ece114c87
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/genrsa.c
        @@ -0,0 +1,335 @@
        +/* apps/genrsa.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 <openssl/opensslconf.h>
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +#include <stdio.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include <sys/stat.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/rand.h>
        +
        +#define DEFBITS	1024
        +#undef PROG
        +#define PROG genrsa_main
        +
        +static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	BN_GENCB cb;
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE *e = NULL;
        +#endif
        +	int ret=1;
        +	int i,num=DEFBITS;
        +	long l;
        +	const EVP_CIPHER *enc=NULL;
        +	unsigned long f4=RSA_F4;
        +	char *outfile=NULL;
        +	char *passargout = NULL, *passout = NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	char *inrand=NULL;
        +	BIO *out=NULL;
        +	BIGNUM *bn = BN_new();
        +	RSA *rsa = NULL;
        +
        +	if(!bn) goto err;
        +
        +	apps_startup();
        +	BN_GENCB_set(&cb, genrsa_cb, bio_err);
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto err;
        +	if ((out=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to create BIO for output\n");
        +		goto err;
        +		}
        +
        +	argv++;
        +	argc--;
        +	for (;;)
        +		{
        +		if (argc <= 0) break;
        +		if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-3") == 0)
        +			f4=3;
        +		else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0)
        +			f4=RSA_F4;
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_DES
        +		else if (strcmp(*argv,"-des") == 0)
        +			enc=EVP_des_cbc();
        +		else if (strcmp(*argv,"-des3") == 0)
        +			enc=EVP_des_ede3_cbc();
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +		else if (strcmp(*argv,"-idea") == 0)
        +			enc=EVP_idea_cbc();
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		else if (strcmp(*argv,"-seed") == 0)
        +			enc=EVP_seed_cbc();
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		else if (strcmp(*argv,"-aes128") == 0)
        +			enc=EVP_aes_128_cbc();
        +		else if (strcmp(*argv,"-aes192") == 0)
        +			enc=EVP_aes_192_cbc();
        +		else if (strcmp(*argv,"-aes256") == 0)
        +			enc=EVP_aes_256_cbc();
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		else if (strcmp(*argv,"-camellia128") == 0)
        +			enc=EVP_camellia_128_cbc();
        +		else if (strcmp(*argv,"-camellia192") == 0)
        +			enc=EVP_camellia_192_cbc();
        +		else if (strcmp(*argv,"-camellia256") == 0)
        +			enc=EVP_camellia_256_cbc();
        +#endif
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +		else
        +			break;
        +		argv++;
        +		argc--;
        +		}
        +	if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
        +		{
        +bad:
        +		BIO_printf(bio_err,"usage: genrsa [args] [numbits]\n");
        +		BIO_printf(bio_err," -des            encrypt the generated key with DES in cbc mode\n");
        +		BIO_printf(bio_err," -des3           encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
        +#ifndef OPENSSL_NO_IDEA
        +		BIO_printf(bio_err," -idea           encrypt the generated key with IDEA in cbc mode\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		BIO_printf(bio_err," -seed\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc seed\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
        +#endif
        +		BIO_printf(bio_err," -out file       output the key to 'file\n");
        +		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
        +		BIO_printf(bio_err," -f4             use F4 (0x10001) for the E value\n");
        +		BIO_printf(bio_err," -3              use 3 for the E value\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,"                 load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,"                 the random number generator\n");
        +		goto err;
        +		}
        +		
        +	ERR_load_crypto_strings();
        +
        +	if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto err;
        +	}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto err;
        +			}
        +		}
        +
        +	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
        +		&& !RAND_status())
        +		{
        +		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
        +		}
        +	if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +
        +	BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
        +		num);
        +#ifdef OPENSSL_NO_ENGINE
        +	rsa = RSA_new();
        +#else
        +	rsa = RSA_new_method(e);
        +#endif
        +	if (!rsa)
        +		goto err;
        +
        +	if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
        +		goto err;
        +		
        +	app_RAND_write_file(NULL, bio_err);
        +
        +	/* We need to do the following for when the base number size is <
        +	 * long, esp windows 3.1 :-(. */
        +	l=0L;
        +	for (i=0; i<rsa->e->top; i++)
        +		{
        +#ifndef SIXTY_FOUR_BIT
        +		l<<=BN_BITS4;
        +		l<<=BN_BITS4;
        +#endif
        +		l+=rsa->e->d[i];
        +		}
        +	BIO_printf(bio_err,"e is %ld (0x%lX)\n",l,l);
        +	{
        +	PW_CB_DATA cb_data;
        +	cb_data.password = passout;
        +	cb_data.prompt_info = outfile;
        +	if (!PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0,
        +		(pem_password_cb *)password_callback,&cb_data))
        +		goto err;
        +	}
        +
        +	ret=0;
        +err:
        +	if (bn) BN_free(bn);
        +	if (rsa) RSA_free(rsa);
        +	if (out) BIO_free_all(out);
        +	if(passout) OPENSSL_free(passout);
        +	if (ret != 0)
        +		ERR_print_errors(bio_err);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(cb->arg,&c,1);
        +	(void)BIO_flush(cb->arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        +#else /* !OPENSSL_NO_RSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/install-apps.com b/vendor/openssl/openssl/apps/install-apps.com
        new file mode 100644
        index 000000000..7a553aa12
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/install-apps.com
        @@ -0,0 +1,107 @@
        +$! INSTALL.COM -- Installs the files in a given directory tree
        +$!
        +$! Author: Richard Levitte <richard@levitte.org>
        +$! Time of creation: 22-MAY-1998 10:13
        +$!
        +$! P1  root of the directory tree
        +$! P2  "64" for 64-bit pointers.
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ on error then goto tidy
        +$ on control_c then goto tidy
        +$!
        +$ if (p1 .eqs. "")
        +$ then
        +$   write sys$output "First argument missing."
        +$   write sys$output -
        +     "It should be the directory where you want things installed."
        +$   exit
        +$ endif
        +$!
        +$ if (f$getsyi("cpu") .lt. 128)
        +$ then
        +$   arch = "VAX"
        +$ else
        +$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
        +$   if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$!
        +$ archd = arch
        +$!
        +$ if (p2 .nes. "")
        +$ then
        +$   if (p2 .eqs. "64")
        +$   then
        +$     archd = arch+ "_64"
        +$   else
        +$     if (p2 .nes. "32")
        +$     then
        +$       write sys$output "Second argument invalid."
        +$       write sys$output "It should be "32", "64", or nothing."
        +$       exit
        +$     endif
        +$   endif
        +$ endif
        +$!
        +$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
        +$ root_dev = f$parse(root,,,"device","syntax_only")
        +$ root_dir = f$parse(root,,,"directory","syntax_only") - -
        +   "[000000." - "][" - "[" - "]"
        +$ root = root_dev + "[" + root_dir
        +$!
        +$ define /nolog wrk_sslroot 'root'.] /trans=conc
        +$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
        +$!
        +$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
        +   create /directory /log wrk_sslroot:[000000]
        +$ if f$parse("wrk_sslxexe:") .eqs. "" then -
        +   create /directory /log wrk_sslxexe:
        +$!
        +$ exe := openssl
        +$!
        +$ exe_dir := [-.'archd'.exe.apps]
        +$!
        +$! Executables.
        +$!
        +$ i = 0
        +$ loop_exe:
        +$   e = f$edit(f$element( i, ",", exe), "trim")
        +$   i = i + 1
        +$   if e .eqs. "," then goto loop_exe_end
        +$   set noon
        +$   file = exe_dir+ e+ ".exe"
        +$   if f$search( file) .nes. ""
        +$   then
        +$     copy /protection = w:re 'file' wrk_sslxexe: /log
        +$   endif
        +$   set on
        +$ goto loop_exe
        +$ loop_exe_end:
        +$!
        +$! Miscellaneous.
        +$!
        +$ set noon
        +$ copy /protection = w:re ca.com wrk_sslxexe:ca.com /log
        +$ copy /protection = w:re openssl-vms.cnf wrk_sslroot:[000000]openssl.cnf /log
        +$ set on
        +$!
        +$ tidy:
        +$!
        +$ call deass wrk_sslroot
        +$ call deass wrk_sslxexe
        +$!
        +$ exit
        +$!
        +$ deass: subroutine
        +$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
        +$ then
        +$   deassign /process 'p1'
        +$ endif
        +$ endsubroutine
        +$!
        diff --git a/vendor/openssl/openssl/apps/makeapps.com b/vendor/openssl/openssl/apps/makeapps.com
        new file mode 100644
        index 000000000..efc213c8e
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/makeapps.com
        @@ -0,0 +1,1169 @@
        +$!
        +$!  MAKEAPPS.COM
        +$!  Written By:  Robert Byer
        +$!               Vice-President
        +$!               A-Com Computing, Inc.
        +$!               byer@mail.all-net.net
        +$!
        +$!  Changes by Richard Levitte <richard@levitte.org>
        +$!             Zoltan Arpadffy <zoli@polarhome.com>   
        +$!
        +$!  This command files compiles and creates all the various different
        +$!  "application" programs for the different types of encryption for OpenSSL.
        +$!  The EXE's are placed in the directory [.xxx.EXE.APPS] where "xxx" denotes
        +$!  ALPHA, IA64 or VAX, depending on your machine architecture.
        +$!
        +$!  It was written so it would try to determine what "C" compiler to
        +$!  use or you can specify which "C" compiler to use.
        +$!
        +$!  Specify DEBUG or NODEBUG as P1 to compile with or without debugger
        +$!  information.
        +$!
        +$!  Specify which compiler at P2 to try to compile under.
        +$!
        +$!	   VAXC	 For VAX C.
        +$!	   DECC	 For DEC C.
        +$!	   GNUC	 For GNU C.
        +$!
        +$!  If you don't specify a compiler, it will try to determine which
        +$!  "C" compiler to use.
        +$!
        +$!  P3, if defined, sets a TCP/IP library to use, through one of the following
        +$!  keywords:
        +$!
        +$!	UCX		for UCX
        +$!	SOCKETSHR	for SOCKETSHR+NETLIB
        +$!	TCPIP		for TCPIP (post UCX)
        +$!
        +$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
        +$!
        +$!  P5, if defined, sets a choice of programs to compile.
        +$!
        +$!  P6, if defined, specifies the C pointer size.  Ignored on VAX.
        +$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
        +$!      Supported values are:
        +$!
        +$!      ""       Compile with default (/NOPOINTER_SIZE)
        +$!      32       Compile with /POINTER_SIZE=32 (SHORT)
        +$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
        +$!               (Automatically select ARGV if compiler supports it.)
        +$!      64=      Compile with /POINTER_SIZE=64 (LONG).
        +$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
        +$!
        +$!  P7, if defined, specifies a directory where ZLIB files (zlib.h,
        +$!  libz.olb) may be found.  Optionally, a non-default object library
        +$!  name may be included ("dev:[dir]libz_64.olb", for example).
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ on control_c then goto exit
        +$!
        +$! Define A TCP/IP Library That We Will Need To Link To.
        +$! (That Is, If We Need To Link To One.)
        +$!
        +$ TCPIP_LIB = ""
        +$ ZLIB_LIB = ""
        +$!
        +$! Check What Architecture We Are Using.
        +$!
        +$ IF (F$GETSYI("CPU").LT.128)
        +$ THEN
        +$!
        +$!  The Architecture Is VAX.
        +$!
        +$   ARCH = "VAX"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
        +$!
        +$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
        +$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
        +$!
        +$! End The Architecture Check.
        +$!
        +$ ENDIF
        +$!
        +$ ARCHD = ARCH
        +$ LIB32 = "32"
        +$ OPT_FILE = ""
        +$ POINTER_SIZE = ""
        +$!
        +$! Define what programs should be compiled
        +$!
        +$ PROGRAMS := OPENSSL
        +$!
        +$! Check To Make Sure We Have Valid Command Line Parameters.
        +$!
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Define The CRYPTO Library.
        +$!
        +$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
        +$!
        +$! Define The SSL Library.
        +$!
        +$ SSL_LIB := SYS$DISK:[-.'ARCHD'.EXE.SSL]SSL_LIBSSL'LIB32'.OLB
        +$!
        +$! Define The OBJ and EXE Directories.
        +$!
        +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.APPS]
        +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.APPS]
        +$!
        +$! Specify the destination directory in any /MAP option.
        +$!
        +$ if (LINKMAP .eqs. "MAP")
        +$ then
        +$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
        +$ endif
        +$!
        +$! Add the location prefix to the linker options file name.
        +$!
        +$ if (OPT_FILE .nes. "")
        +$ then
        +$   OPT_FILE = EXE_DIR+ OPT_FILE
        +$ endif
        +$!
        +$! Initialise logical names and such
        +$!
        +$ GOSUB INITIALISE
        +$!
        +$! Tell The User What Kind of Machine We Run On.
        +$!
        +$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
        +$!
        +$! Check To See If The OBJ Directory Exists.
        +$!
        +$ IF (F$PARSE(OBJ_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIRECTORY 'OBJ_DIR'
        +$!
        +$! End The OBJ Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If The EXE Directory Exists.
        +$!
        +$ IF (F$PARSE(EXE_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIRECTORY 'EXE_DIR'
        +$!
        +$! End The EXE Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Define The Application Files.
        +$! NOTE: Some might think this list ugly.  However, it's made this way to
        +$! reflect the E_OBJ variable in Makefile as closely as possible, thereby
        +$! making it fairly easy to verify that the lists are the same.
        +$!
        +$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
        +	     	"CA,PKCS7,CRL2P7,CRL,"+-
        +	      	"RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
        +	      	"X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
        +	      	"S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
        +	      	"CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
        +	      	"SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS,SRP"
        +$!
        +$ LIB_OPENSSL = LIB_OPENSSL+ ",VMS_DECC_INIT"
        +$!
        +$ TCPIP_PROGRAMS = ",,"
        +$ IF COMPILER .EQS. "VAXC" THEN -
        +     TCPIP_PROGRAMS = ",OPENSSL,"
        +$!
        +$! Setup exceptional compilations
        +$!
        +$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
        +$!
        +$ PHASE := LIB
        +$!
        +$ RESTART: 
        +$!
        +$!  Define An App Counter And Set It To "0".
        +$!
        +$ APP_COUNTER = 0
        +$!
        +$!  Top Of The App Loop.
        +$!
        +$ NEXT_APP:
        +$!
        +$!  Make The Application File Name
        +$!
        +$ CURRENT_APP = F$EDIT(F$ELEMENT(APP_COUNTER,",",PROGRAMS),"TRIM")
        +$!
        +$!  Create The Executable File Name.
        +$!
        +$   EXE_FILE = EXE_DIR + CURRENT_APP + ".EXE"
        +$!
        +$!  Check To See If We Are At The End Of The File List.
        +$!
        +$ IF (CURRENT_APP.EQS.",")
        +$ THEN
        +$   IF (PHASE.EQS."LIB")
        +$   THEN
        +$     PHASE := APP
        +$     GOTO RESTART
        +$   ELSE
        +$     GOTO APP_DONE
        +$   ENDIF
        +$ ENDIF
        +$!
        +$!  Increment The Counter.
        +$!
        +$ APP_COUNTER = APP_COUNTER + 1
        +$!
        +$!  Decide if we're building the object files or not.
        +$!
        +$ IF (PHASE.EQS."LIB")
        +$ THEN
        +$!
        +$!  Define A Library File Counter And Set It To "-1".
        +$!  -1 Means The Application File Name Is To Be Used.
        +$!
        +$   LIB_COUNTER = -1
        +$!
        +$!  Create a .OPT file for the object files
        +$!
        +$   OPEN /WRITE OBJECTS 'EXE_DIR''CURRENT_APP'.OPT
        +$!
        +$!  Top Of The File Loop.
        +$!
        +$  NEXT_LIB:
        +$!
        +$!  O.K, Extract The File Name From The File List.
        +$!
        +$   IF LIB_COUNTER .GE. 0
        +$   THEN
        +$     FILE_NAME = F$EDIT(F$ELEMENT(LIB_COUNTER,",",LIB_'CURRENT_APP'),"TRIM")
        +$   ELSE
        +$     FILE_NAME = CURRENT_APP
        +$   ENDIF
        +$!
        +$!  Check To See If We Are At The End Of The File List.
        +$!
        +$   IF (FILE_NAME.EQS.",")
        +$   THEN
        +$     CLOSE OBJECTS
        +$     GOTO NEXT_APP
        +$   ENDIF
        +$!
        +$!  Increment The Counter.
        +$!
        +$   LIB_COUNTER = LIB_COUNTER + 1
        +$!
        +$!  Create The Source File Name.
        +$!
        +$   SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
        +$!
        +$!  Create The Object File Name.
        +$!
        +$   OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
        +$   ON WARNING THEN GOTO NEXT_LIB
        +$!
        +$!  Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$   IF (F$SEARCH(SOURCE_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Tell The User That The File Dosen't Exist.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Exit The Build.
        +$!
        +$     GOTO EXIT
        +$!
        +$!  End The File Exist Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Tell The User What We Are Building.
        +$!
        +$   IF (PHASE.EQS."LIB")
        +$   THEN
        +$     WRITE SYS$OUTPUT "Compiling The ",FILE_NAME,".C File."
        +$   ELSE
        +$     WRITE SYS$OUTPUT "Building The ",FILE_NAME," Application Program."
        +$   ENDIF
        +$!
        +$!  Compile The File.
        +$!
        +$   ON ERROR THEN GOTO NEXT_LIB
        +$   IF COMPILEWITH_CC2 - FILE_NAME .NES. COMPILEWITH_CC2
        +$   THEN
        +$     CC2/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$   ELSE
        +$     CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$   ENDIF
        +$   WRITE OBJECTS OBJECT_FILE
        +$!
        +$   GOTO NEXT_LIB
        +$ ENDIF
        +$!
        +$!  Check if this program works well without a TCPIP library
        +$!
        +$ IF TCPIP_LIB .EQS. "" .AND. TCPIP_PROGRAMS - CURRENT_APP .NES. TCPIP_PROGRAMS
        +$ THEN
        +$   WRITE SYS$OUTPUT CURRENT_APP," needs a TCP/IP library.  Can't link.  Skipping..."
        +$   GOTO NEXT_APP
        +$ ENDIF
        +$!
        +$! Link The Program.
        +$!
        +$ ON WARNING THEN GOTO NEXT_APP
        +$!
        +$! Don't Link With The RSAREF Routines And TCP/IP Library.
        +$!
        +$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_FILE' -
        +  'EXE_DIR''CURRENT_APP'.OPT /OPTIONS, -
        +  'SSL_LIB' /LIBRARY, -
        +  'CRYPTO_LIB' /LIBRARY -
        +  'TCPIP_LIB' -
        +  'ZLIB_LIB' -
        +  ,'OPT_FILE' /OPTIONS
        +$!
        +$! Go Back And Do It Again.
        +$!
        +$ GOTO NEXT_APP
        +$!
        +$! All Done With This File.
        +$!
        +$ APP_DONE:
        +$ EXIT:
        +$!
        +$! All Done, Time To Clean Up And Exit.
        +$!
        +$ GOSUB CLEANUP
        +$ EXIT
        +$!
        +$! Check For The Link Option FIle.
        +$!
        +$ CHECK_OPT_FILE:
        +$!
        +$! Check To See If We Need To Make A VAX C Option File.
        +$!
        +$ IF (COMPILER.EQS."VAXC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A VAX C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A VAX C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable VAX C Runtime Library.
        +!
        +SYS$SHARE:VAXCRTL.EXE/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The VAXC Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A GNU C Option File.
        +$!
        +$ IF (COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A GNU C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A GNU C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +GNU_CC:[000000]GCCLIB/LIBRARY
        +SYS$SHARE:VAXCRTL/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The GNU C Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A DEC C Option File.
        +$!
        +$ IF (COMPILER.EQS."DECC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A DEC C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Figure Out If We Need An AXP Or A VAX Linker Option File.
        +$!
        +$     IF ARCH.EQS."VAX"
        +$     THEN
        +$!
        +$!      We Need A DEC C Linker Option File For VAX.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable DEC C Runtime Library.
        +!
        +SYS$SHARE:DECC$SHR.EXE/SHARE
        +$EOD
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Create The non-VAX Linker Option File.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File For non-VAX To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
        +SYS$SHARE:CMA$OPEN_RTL/SHARE
        +$EOD
        +$!
        +$!    End The DEC C Option File Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The Option File Search.
        +$!
        +$   ENDIF
        +$!
        +$! End The DEC C Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What Linker Option File We Are Using.
        +$!
        +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Check To See If We Have The Appropiate Libraries.
        +$!
        +$ LIB_CHECK:
        +$!
        +$! Look For The Library LIBCRYPTO.OLB.
        +$!
        +$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
        +$   WRITE SYS$OUTPUT "We Can't Link Without It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$!
        +$! End The Crypto Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Look For The Library LIBSSL.OLB.
        +$!
        +$ IF (F$SEARCH(SSL_LIB).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User We Can't Find The LIBSSL.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
        +$   WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$!
        +$! End The SSL Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Time To Return.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Check To See If P1 Is Blank.
        +$!
        +$ IF (P1.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!  P1 Is NODEBUG, So Compile Without Debugger Information.
        +$!
        +$   DEBUGGER  = "NODEBUG"
        +$   LINKMAP = "NOMAP"
        +$   TRACEBACK = "NOTRACEBACK" 
        +$   GCC_OPTIMIZE = "OPTIMIZE"
        +$   CC_OPTIMIZE = "OPTIMIZE"
        +$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
        +$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (P1.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER  = "DEBUG"
        +$     LINKMAP = "MAP"
        +$     TRACEBACK = "TRACEBACK"
        +$     GCC_OPTIMIZE = "NOOPTIMIZE"
        +$     CC_OPTIMIZE = "NOOPTIMIZE"
        +$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
        +$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
        +$   ELSE
        +$!
        +$!    Tell The User Entered An Invalid Option.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P1 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check P6 (POINTER_SIZE).
        +$!
        +$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX")
        +$ THEN
        +$!
        +$   IF (P6 .EQS. "32")
        +$   THEN
        +$     POINTER_SIZE = " /POINTER_SIZE=32"
        +$   ELSE
        +$     POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE")
        +$     IF ((POINTER_SIZE .EQS. "64") .OR. -
        +       (POINTER_SIZE .EQS. "64=") .OR. -
        +       (POINTER_SIZE .EQS. "64=ARGV"))
        +$     THEN
        +$       ARCHD = ARCH+ "_64"
        +$       LIB32 = ""
        +$       IF (F$EXTRACT( 2, 1, POINTER_SIZE) .EQS. "=")
        +$       THEN
        +$!        Explicit user choice: "64" or "64=ARGV".
        +$         IF (POINTER_SIZE .EQS. "64=") THEN POINTER_SIZE = "64"
        +$       ELSE
        +$         SET NOON
        +$         DEFINE /USER_MODE SYS$OUTPUT NL:
        +$         DEFINE /USER_MODE SYS$ERROR NL:
        +$         CC /NOLIST /NOOBJECT /POINTER_SIZE=64=ARGV NL:
        +$         IF ($STATUS .AND. %X0FFF0000) .EQ. %X00030000
        +$         THEN
        +$           ! If we got here, it means DCL complained like this:
        +$           ! %DCL-W-NOVALU, value not allowed - remove value specification
        +$           !  \64=\
        +$           !
        +$           ! If the compiler was run, logicals defined in /USER would
        +$           ! have been deassigned automatically.  However, when DCL
        +$           ! complains, they aren't, so we do it here (it might be
        +$           ! unnecessary, but just in case there will be another error
        +$           ! message further on that we don't want to miss)
        +$           DEASSIGN /USER_MODE SYS$ERROR
        +$           DEASSIGN /USER_MODE SYS$OUTPUT
        +$         ELSE
        +$           POINTER_SIZE = POINTER_SIZE + "=ARGV"
        +$         ENDIF
        +$         SET ON
        +$       ENDIF
        +$       POINTER_SIZE = " /POINTER_SIZE=''POINTER_SIZE'"
        +$!
        +$     ELSE
        +$!
        +$!      Tell The User Entered An Invalid Option.
        +$!
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", P6, -
        +         " Is Invalid.  The Valid Options Are:"
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT -
        +         "    """"  :  Compile with default (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    32  :  Compile with 32-bit (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
        +$       WRITE SYS$OUTPUT ""
        +$! 
        +$!      Time To EXIT.
        +$!
        +$       EXIT
        +$!
        +$     ENDIF
        +$!
        +$   ENDIF
        +$!
        +$! End The P6 (POINTER_SIZE) Check.
        +$!
        +$ ENDIF
        +$!
        +$! Set basic C compiler /INCLUDE directories.
        +$!
        +$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
        +$!
        +$! Check To See If P2 Is Blank.
        +$!
        +$ IF (P2.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     P2 = "GNUC"
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!  Check To See If We Have VAXC Or DECC.
        +$!
        +$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
        +$     THEN 
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       P2 = "DECC"
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       P2 = "VAXC"
        +$!
        +$!    End The VAXC Compiler Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  End The Compiler Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Have A Option For P3.
        +$!
        +$ IF (P3.EQS."")
        +$ THEN
        +$!
        +$!  Find out what socket library we have available
        +$!
        +$   IF F$PARSE("SOCKETSHR:") .NES. ""
        +$   THEN
        +$!
        +$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
        +$!
        +$     P3 = "SOCKETSHR"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
        +$!
        +$!    Else, let's look for something else
        +$!
        +$   ELSE
        +$!
        +$!    Like UCX (the reason to do this before Multinet is that the UCX
        +$!    emulation is easier to use...)
        +$!
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
        +	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
        +	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
        +$     THEN
        +$!
        +$!	Last resort: a UCX or UCX-compatible library
        +$!
        +$	P3 = "UCX"
        +$!
        +$!      Tell the user
        +$!
        +$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
        +$!
        +$!	That was all...
        +$!
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Set Up Initial CC Definitions, Possibly With User Ones
        +$!
        +$ CCDEFS = "MONOLITH"
        +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
        +$ CCEXTRAFLAGS = ""
        +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
        +$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
        +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
        +	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
        +$!
        +$! Check To See If We Have A ZLIB Option.
        +$!
        +$ ZLIB = P7
        +$ IF (ZLIB .NES. "")
        +$ THEN
        +$!
        +$!  Check for expected ZLIB files.
        +$!
        +$   err = 0
        +$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
        +$   if (f$search( file1) .eqs. "")
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
        +$     err = 1
        +$   endif
        +$   file1 = f$parse( "A.;", ZLIB)- "A.;"
        +$!
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     if (err .eq. 0)
        +$     then
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     endif
        +$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
        +$     WRITE SYS$OUTPUT ""
        +$     err = err+ 2
        +$   endif
        +$   if (err .eq. 1)
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$   endif
        +$!
        +$   if (err .ne. 0)
        +$   then
        +$     EXIT
        +$   endif
        +$!
        +$   CCDEFS = """ZLIB=1"", "+ CCDEFS
        +$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
        +$   ZLIB_LIB = ", ''file2' /library"
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
        +$!
        +$! End The ZLIB Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Check To See If The User Entered A Valid Parameter.
        +$!
        +$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If The User Wanted DECC.
        +$!
        +$   IF (P2.EQS."DECC")
        +$   THEN
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    Use DECC...
        +$!
        +$     CC = "CC"
        +$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
        +	 THEN CC = "CC/DECC"
        +$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
        +       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
        +       " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
        +$!
        +$!  End DECC Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use VAXC.
        +$!
        +$   IF (P2.EQS."VAXC")
        +$   THEN
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    Compile Using VAXC.
        +$!
        +$     CC = "CC"
        +$     IF ARCH.NES."VAX"
        +$     THEN
        +$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
        +$	EXIT
        +$     ENDIF
        +$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
        +$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
        +$     CCDEFS = CCDEFS + ",""VAXC"""
        +$!
        +$!    Define <sys> As SYS$COMMON:[SYSLIB]
        +$!
        +$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
        +$!
        +$!  End VAXC Check
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use GNU C.
        +$!
        +$   IF (P2.EQS."GNUC")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    Use GNU C...
        +$!
        +$     IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
        +$     CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
        +$!
        +$!  End The GNU C Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Set up default defines
        +$!
        +$   CCDEFS = """FLAT_INC=1""," + CCDEFS
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$ ENDIF
        +$!
        +$! Time to check the contents, and to make sure we get the correct library.
        +$!
        +$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
        +     .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
        +$ THEN
        +$!
        +$!  Check to see if SOCKETSHR was chosen
        +$!
        +$   IF P3.EQS."SOCKETSHR"
        +$   THEN
        +$!
        +$!    Set the library to use SOCKETSHR
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
        +$!
        +$!    Done with SOCKETSHR
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if MULTINET was chosen
        +$!
        +$   IF P3.EQS."MULTINET"
        +$   THEN
        +$!
        +$!    Set the library to use UCX emulation.
        +$!
        +$     P3 = "UCX"
        +$!
        +$!    Done with MULTINET
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if UCX was chosen
        +$!
        +$   IF P3.EQS."UCX"
        +$   THEN
        +$!
        +$!    Set the library to use UCX.
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
        +$     THEN
        +$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
        +$     ELSE
        +$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
        +	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
        +$     ENDIF
        +$!
        +$!    Done with UCX
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if TCPIP (post UCX) was chosen
        +$!
        +$   IF P3.EQS."TCPIP"
        +$   THEN
        +$!
        +$!    Set the library to use TCPIP.
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if NONE was chosen
        +$!
        +$   IF P3.EQS."NONE"
        +$   THEN
        +$!
        +$!    Do not use TCPIP.
        +$!
        +$     TCPIP_LIB = ""
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Add TCP/IP type to CC definitions.
        +$!
        +$   CCDEFS = CCDEFS + ",TCPIP_TYPE_''P3'"
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
        +$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
        +$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$!  Done with TCP/IP libraries
        +$!
        +$ ENDIF
        +$!
        +$! Finish up the definition of CC.
        +$!
        +$ IF COMPILER .EQS. "DECC"
        +$ THEN
        +$   IF CCDISABLEWARNINGS .NES. ""
        +$   THEN
        +$     CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
        +$   ENDIF
        +$ ELSE
        +$   CCDISABLEWARNINGS = ""
        +$ ENDIF
        +$ CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
        +$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
        +$!
        +$! Show user the result
        +$!
        +$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For P4.
        +$!
        +$ IF (P4.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN :=
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P4 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check if the user wanted to compile just a subset of all the programs.
        +$!
        +$ IF P5 .NES. ""
        +$ THEN
        +$   PROGRAMS = P5
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        +$!
        +$ INITIALISE:
        +$!
        +$! Save old value of the logical name OPENSSL
        +$!
        +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
        +$!
        +$! Save directory information
        +$!
        +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
        +$ __HERE = F$EDIT(__HERE,"UPCASE")
        +$ __TOP = __HERE - "APPS]"
        +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
        +$!
        +$! Set up the logical name OPENSSL to point at the include directory
        +$!
        +$ DEFINE OPENSSL /NOLOG '__INCLUDE'
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        +$ CLEANUP:
        +$!
        +$! Restore the saved logical name OPENSSL, if it had a value.
        +$!
        +$ if (f$type( __SAVE_OPENSSL) .nes. "")
        +$ then
        +$   IF __SAVE_OPENSSL .EQS. ""
        +$   THEN
        +$     DEASSIGN OPENSSL
        +$   ELSE
        +$     DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
        +$   ENDIF
        +$ endif
        +$!
        +$! Close any open files.
        +$!
        +$ if (f$trnlnm( "objects", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close objects
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        diff --git a/vendor/openssl/openssl/apps/md4.c b/vendor/openssl/openssl/apps/md4.c
        new file mode 100644
        index 000000000..141415ad4
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md4.h>
        +
        +#define BUFSIZE	1024*16
        +
        +void do_fp(FILE *f);
        +void pt(unsigned char *md);
        +#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
        +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<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("MD4(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	MD4_CTX c;
        +	unsigned char md[MD4_DIGEST_LENGTH];
        +	int fd;
        +	int i;
        +	static unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	MD4_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,sizeof buf);
        +		if (i <= 0) break;
        +		MD4_Update(&c,buf,(unsigned long)i);
        +		}
        +	MD4_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<MD4_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/nseq.c b/vendor/openssl/openssl/apps/nseq.c
        new file mode 100644
        index 000000000..e3c4dba54
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/nseq.c
        @@ -0,0 +1,167 @@
        +/* nseq.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +
        +#undef PROG
        +#define PROG nseq_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +{
        +	char **args, *infile = NULL, *outfile = NULL;
        +	BIO *in = NULL, *out = NULL;
        +	int toseq = 0;
        +	X509 *x509 = NULL;
        +	NETSCAPE_CERT_SEQUENCE *seq = NULL;
        +	int i, ret = 1;
        +	int badarg = 0;
        +	if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
        +	ERR_load_crypto_strings();
        +	args = argv + 1;
        +	while (!badarg && *args && *args[0] == '-') {
        +		if (!strcmp (*args, "-toseq")) toseq = 1;
        +		else if (!strcmp (*args, "-in")) {
        +			if (args[1]) {
        +				args++;
        +				infile = *args;
        +			} else badarg = 1;
        +		} else if (!strcmp (*args, "-out")) {
        +			if (args[1]) {
        +				args++;
        +				outfile = *args;
        +			} else badarg = 1;
        +		} else badarg = 1;
        +		args++;
        +	}
        +
        +	if (badarg) {
        +		BIO_printf (bio_err, "Netscape certificate sequence utility\n");
        +		BIO_printf (bio_err, "Usage nseq [options]\n");
        +		BIO_printf (bio_err, "where options are\n");
        +		BIO_printf (bio_err, "-in file  input file\n");
        +		BIO_printf (bio_err, "-out file output file\n");
        +		BIO_printf (bio_err, "-toseq    output NS Sequence file\n");
        +		OPENSSL_EXIT(1);
        +	}
        +
        +	if (infile) {
        +		if (!(in = BIO_new_file (infile, "r"))) {
        +			BIO_printf (bio_err,
        +				 "Can't open input file %s\n", infile);
        +			goto end;
        +		}
        +	} else in = BIO_new_fp(stdin, BIO_NOCLOSE);
        +
        +	if (outfile) {
        +		if (!(out = BIO_new_file (outfile, "w"))) {
        +			BIO_printf (bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +		}
        +	} else {
        +		out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +	}
        +	if (toseq) {
        +		seq = NETSCAPE_CERT_SEQUENCE_new();
        +		seq->certs = sk_X509_new_null();
        +		while((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) 
        +		    sk_X509_push(seq->certs,x509);
        +
        +		if(!sk_X509_num(seq->certs))
        +		{
        +			BIO_printf (bio_err, "Error reading certs file %s\n", infile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +		PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq);
        +		ret = 0;
        +		goto end;
        +	}
        +
        +	if (!(seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL))) {
        +		BIO_printf (bio_err, "Error reading sequence file %s\n", infile);
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +
        +	for(i = 0; i < sk_X509_num(seq->certs); i++) {
        +		x509 = sk_X509_value(seq->certs, i);
        +		dump_cert_text(out, x509);
        +		PEM_write_bio_X509(out, x509);
        +	}
        +	ret = 0;
        +end:
        +	BIO_free(in);
        +	BIO_free_all(out);
        +	NETSCAPE_CERT_SEQUENCE_free(seq);
        +
        +	OPENSSL_EXIT(ret);
        +}
        +
        diff --git a/vendor/openssl/openssl/apps/ocsp.c b/vendor/openssl/openssl/apps/ocsp.c
        new file mode 100644
        index 000000000..83c5a7670
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ocsp.c
        @@ -0,0 +1,1421 @@
        +/* ocsp.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) 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 OPENSSL_NO_OCSP
        +
        +#ifdef OPENSSL_SYS_VMS
        +#define _XOPEN_SOURCE_EXTENDED	/* So fd_set and friends get properly defined
        +				   on OpenVMS */
        +#endif
        +
        +#define USE_SOCKETS
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +#include "apps.h" /* needs to be included before the openssl headers! */
        +#include <openssl/e_os2.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/x509v3.h>
        +
        +#if defined(NETWARE_CLIB)
        +#  ifdef NETWARE_BSDSOCK
        +#    include <sys/socket.h>
        +#    include <sys/bsdskt.h>
        +#  else
        +#    include <novsock2.h>
        +#  endif
        +#elif defined(NETWARE_LIBC)
        +#  ifdef NETWARE_BSDSOCK
        +#    include <sys/select.h>
        +#  else
        +#    include <novsock2.h>
        +#  endif
        +#endif
        +  
        +/* Maximum leeway in validity period: default 5 minutes */
        +#define MAX_VALIDITY_PERIOD	(5 * 60)
        +
        +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
        +				STACK_OF(OCSP_CERTID) *ids);
        +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
        +				STACK_OF(OCSP_CERTID) *ids);
        +static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
        +			      STACK_OF(OPENSSL_STRING) *names,
        +			      STACK_OF(OCSP_CERTID) *ids, long nsec,
        +			      long maxage);
        +
        +static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
        +			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
        +			STACK_OF(X509) *rother, unsigned long flags,
        +			int nmin, int ndays);
        +
        +static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
        +static BIO *init_responder(char *port);
        +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
        +static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
        +static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
        +				STACK_OF(CONF_VALUE) *headers,
        +				OCSP_REQUEST *req, int req_timeout);
        +
        +#undef PROG
        +#define PROG ocsp_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	char **args;
        +	char *host = NULL, *port = NULL, *path = "/";
        +	char *reqin = NULL, *respin = NULL;
        +	char *reqout = NULL, *respout = NULL;
        +	char *signfile = NULL, *keyfile = NULL;
        +	char *rsignfile = NULL, *rkeyfile = NULL;
        +	char *outfile = NULL;
        +	int add_nonce = 1, noverify = 0, use_ssl = -1;
        +	STACK_OF(CONF_VALUE) *headers = NULL;
        +	OCSP_REQUEST *req = NULL;
        +	OCSP_RESPONSE *resp = NULL;
        +	OCSP_BASICRESP *bs = NULL;
        +	X509 *issuer = NULL, *cert = NULL;
        +	X509 *signer = NULL, *rsigner = NULL;
        +	EVP_PKEY *key = NULL, *rkey = NULL;
        +	BIO *acbio = NULL, *cbio = NULL;
        +	BIO *derbio = NULL;
        +	BIO *out = NULL;
        +	int req_timeout = -1;
        +	int req_text = 0, resp_text = 0;
        +	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
        +	char *CAfile = NULL, *CApath = NULL;
        +	X509_STORE *store = NULL;
        +	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
        +	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
        +	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
        +	int ret = 1;
        +	int accept_count = -1;
        +	int badarg = 0;
        +	int i;
        +	int ignore_err = 0;
        +	STACK_OF(OPENSSL_STRING) *reqnames = NULL;
        +	STACK_OF(OCSP_CERTID) *ids = NULL;
        +
        +	X509 *rca_cert = NULL;
        +	char *ridx_filename = NULL;
        +	char *rca_filename = NULL;
        +	CA_DB *rdb = NULL;
        +	int nmin = 0, ndays = -1;
        +	const EVP_MD *cert_id_md = NULL;
        +
        +	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +	SSL_load_error_strings();
        +	OpenSSL_add_ssl_algorithms();
        +	args = argv + 1;
        +	reqnames = sk_OPENSSL_STRING_new_null();
        +	ids = sk_OCSP_CERTID_new_null();
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp(*args, "-out"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-timeout"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				req_timeout = atol(*args);
        +				if (req_timeout < 0)
        +					{
        +					BIO_printf(bio_err,
        +						"Illegal timeout value %s\n",
        +						*args);
        +					badarg = 1;
        +					}
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-url"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
        +					{
        +					BIO_printf(bio_err, "Error parsing URL\n");
        +					badarg = 1;
        +					}
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-host"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				host = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-port"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				port = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-header"))
        +			{
        +			if (args[1] && args[2])
        +				{
        +				if (!X509V3_add_value(args[1], args[2], &headers))
        +					goto end;
        +				args += 2;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-ignore_err"))
        +			ignore_err = 1;
        +		else if (!strcmp(*args, "-noverify"))
        +			noverify = 1;
        +		else if (!strcmp(*args, "-nonce"))
        +			add_nonce = 2;
        +		else if (!strcmp(*args, "-no_nonce"))
        +			add_nonce = 0;
        +		else if (!strcmp(*args, "-resp_no_certs"))
        +			rflags |= OCSP_NOCERTS;
        +		else if (!strcmp(*args, "-resp_key_id"))
        +			rflags |= OCSP_RESPID_KEY;
        +		else if (!strcmp(*args, "-no_certs"))
        +			sign_flags |= OCSP_NOCERTS;
        +		else if (!strcmp(*args, "-no_signature_verify"))
        +			verify_flags |= OCSP_NOSIGS;
        +		else if (!strcmp(*args, "-no_cert_verify"))
        +			verify_flags |= OCSP_NOVERIFY;
        +		else if (!strcmp(*args, "-no_chain"))
        +			verify_flags |= OCSP_NOCHAIN;
        +		else if (!strcmp(*args, "-no_cert_checks"))
        +			verify_flags |= OCSP_NOCHECKS;
        +		else if (!strcmp(*args, "-no_explicit"))
        +			verify_flags |= OCSP_NOEXPLICIT;
        +		else if (!strcmp(*args, "-trust_other"))
        +			verify_flags |= OCSP_TRUSTOTHER;
        +		else if (!strcmp(*args, "-no_intern"))
        +			verify_flags |= OCSP_NOINTERN;
        +		else if (!strcmp(*args, "-text"))
        +			{
        +			req_text = 1;
        +			resp_text = 1;
        +			}
        +		else if (!strcmp(*args, "-req_text"))
        +			req_text = 1;
        +		else if (!strcmp(*args, "-resp_text"))
        +			resp_text = 1;
        +		else if (!strcmp(*args, "-reqin"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				reqin = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-respin"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				respin = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-signer"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				signfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-VAfile"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				verify_certfile = *args;
        +				verify_flags |= OCSP_TRUSTOTHER;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-sign_other"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				sign_certfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-verify_other"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				verify_certfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-CAfile"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				CAfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-CApath"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				CApath = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-validity_period"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				nsec = atol(*args);
        +				if (nsec < 0)
        +					{
        +					BIO_printf(bio_err,
        +						"Illegal validity period %s\n",
        +						*args);
        +					badarg = 1;
        +					}
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-status_age"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				maxage = atol(*args);
        +				if (maxage < 0)
        +					{
        +					BIO_printf(bio_err,
        +						"Illegal validity age %s\n",
        +						*args);
        +					badarg = 1;
        +					}
        +				}
        +			else badarg = 1;
        +			}
        +		 else if (!strcmp(*args, "-signkey"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				keyfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-reqout"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				reqout = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-respout"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				respout = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		 else if (!strcmp(*args, "-path"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				path = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-issuer"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				X509_free(issuer);
        +				issuer = load_cert(bio_err, *args, FORMAT_PEM,
        +					NULL, e, "issuer certificate");
        +				if(!issuer) goto end;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-cert"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				X509_free(cert);
        +				cert = load_cert(bio_err, *args, FORMAT_PEM,
        +					NULL, e, "certificate");
        +				if(!cert) goto end;
        +				if (!cert_id_md) cert_id_md = EVP_sha1();
        +				if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
        +					goto end;
        +				if(!sk_OPENSSL_STRING_push(reqnames, *args))
        +					goto end;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-serial"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				if (!cert_id_md) cert_id_md = EVP_sha1();
        +				if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
        +					goto end;
        +				if(!sk_OPENSSL_STRING_push(reqnames, *args))
        +					goto end;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-index"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				ridx_filename = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-CA"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				rca_filename = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-nmin"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				nmin = atol(*args);
        +				if (nmin < 0)
        +					{
        +					BIO_printf(bio_err,
        +						"Illegal update period %s\n",
        +						*args);
        +					badarg = 1;
        +					}
        +				}
        +				if (ndays == -1)
        +					ndays = 0;
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-nrequest"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				accept_count = atol(*args);
        +				if (accept_count < 0)
        +					{
        +					BIO_printf(bio_err,
        +						"Illegal accept count %s\n",
        +						*args);
        +					badarg = 1;
        +					}
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-ndays"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				ndays = atol(*args);
        +				if (ndays < 0)
        +					{
        +					BIO_printf(bio_err,
        +						"Illegal update period %s\n",
        +						*args);
        +					badarg = 1;
        +					}
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-rsigner"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				rsignfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-rkey"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				rkeyfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args, "-rother"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				rcertfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
        +			{
        +			badarg = 1;
        +			}
        +		args++;
        +		}
        +
        +	/* Have we anything to do? */
        +	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
        +
        +	if (badarg)
        +		{
        +		BIO_printf (bio_err, "OCSP utility\n");
        +		BIO_printf (bio_err, "Usage ocsp [options]\n");
        +		BIO_printf (bio_err, "where options are\n");
        +		BIO_printf (bio_err, "-out file          output filename\n");
        +		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
        +		BIO_printf (bio_err, "-cert file         certificate to check\n");
        +		BIO_printf (bio_err, "-serial n          serial number to check\n");
        +		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
        +		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
        +		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
        +		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
        +		BIO_printf (bio_err, "-req_text          print text form of request\n");
        +		BIO_printf (bio_err, "-resp_text         print text form of response\n");
        +		BIO_printf (bio_err, "-text              print text form of request and response\n");
        +		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
        +		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
        +		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
        +		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
        +		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
        +		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
        +		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
        +		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
        +		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
        +		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
        +		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
        +		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
        +		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
        +		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
        +		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
        +		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
        +		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
        +		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
        +		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
        +		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
        +		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
        +		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
        +		BIO_printf (bio_err, "-port num		 port to run responder on\n");
        +		BIO_printf (bio_err, "-index file	 certificate status index file\n");
        +		BIO_printf (bio_err, "-CA file		 CA certificate\n");
        +		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
        +		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
        +		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
        +		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
        +		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
        +		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
        +		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
        +		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
        +		BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request\n");
        +		goto end;
        +		}
        +
        +	if(outfile) out = BIO_new_file(outfile, "w");
        +	else out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +
        +	if(!out)
        +		{
        +		BIO_printf(bio_err, "Error opening output file\n");
        +		goto end;
        +		}
        +
        +	if (!req && (add_nonce != 2)) add_nonce = 0;
        +
        +	if (!req && reqin)
        +		{
        +		derbio = BIO_new_file(reqin, "rb");
        +		if (!derbio)
        +			{
        +			BIO_printf(bio_err, "Error Opening OCSP request file\n");
        +			goto end;
        +			}
        +		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
        +		BIO_free(derbio);
        +		if(!req)
        +			{
        +			BIO_printf(bio_err, "Error reading OCSP request\n");
        +			goto end;
        +			}
        +		}
        +
        +	if (!req && port)
        +		{
        +		acbio = init_responder(port);
        +		if (!acbio)
        +			goto end;
        +		}
        +
        +	if (rsignfile && !rdb)
        +		{
        +		if (!rkeyfile) rkeyfile = rsignfile;
        +		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
        +			NULL, e, "responder certificate");
        +		if (!rsigner)
        +			{
        +			BIO_printf(bio_err, "Error loading responder certificate\n");
        +			goto end;
        +			}
        +		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
        +			NULL, e, "CA certificate");
        +		if (rcertfile)
        +			{
        +			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
        +				NULL, e, "responder other certificates");
        +			if (!rother) goto end;
        +			}
        +		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
        +			"responder private key");
        +		if (!rkey)
        +			goto end;
        +		}
        +	if(acbio)
        +		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
        +
        +	redo_accept:
        +
        +	if (acbio)
        +		{
        +		if (!do_responder(&req, &cbio, acbio, port))
        +			goto end;
        +		if (!req)
        +			{
        +			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
        +			send_ocsp_response(cbio, resp);
        +			goto done_resp;
        +			}
        +		}
        +
        +	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
        +		{
        +		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
        +		goto end;
        +		}
        +
        +	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
        +
        +	if (signfile)
        +		{
        +		if (!keyfile) keyfile = signfile;
        +		signer = load_cert(bio_err, signfile, FORMAT_PEM,
        +			NULL, e, "signer certificate");
        +		if (!signer)
        +			{
        +			BIO_printf(bio_err, "Error loading signer certificate\n");
        +			goto end;
        +			}
        +		if (sign_certfile)
        +			{
        +			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
        +				NULL, e, "signer certificates");
        +			if (!sign_other) goto end;
        +			}
        +		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
        +			"signer private key");
        +		if (!key)
        +			goto end;
        +
        +		if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
        +			{
        +			BIO_printf(bio_err, "Error signing OCSP request\n");
        +			goto end;
        +			}
        +		}
        +
        +	if (req_text && req) OCSP_REQUEST_print(out, req, 0);
        +
        +	if (reqout)
        +		{
        +		derbio = BIO_new_file(reqout, "wb");
        +		if(!derbio)
        +			{
        +			BIO_printf(bio_err, "Error opening file %s\n", reqout);
        +			goto end;
        +			}
        +		i2d_OCSP_REQUEST_bio(derbio, req);
        +		BIO_free(derbio);
        +		}
        +
        +	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
        +		{
        +		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
        +		goto end;
        +		}
        +
        +	if (ridx_filename && !rdb)
        +		{
        +		rdb = load_index(ridx_filename, NULL);
        +		if (!rdb) goto end;
        +		if (!index_index(rdb)) goto end;
        +		}
        +
        +	if (rdb)
        +		{
        +		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
        +		if (cbio)
        +			send_ocsp_response(cbio, resp);
        +		}
        +	else if (host)
        +		{
        +#ifndef OPENSSL_NO_SOCK
        +		resp = process_responder(bio_err, req, host, path,
        +					port, use_ssl, headers, req_timeout);
        +		if (!resp)
        +			goto end;
        +#else
        +		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
        +		goto end;
        +#endif
        +		}
        +	else if (respin)
        +		{
        +		derbio = BIO_new_file(respin, "rb");
        +		if (!derbio)
        +			{
        +			BIO_printf(bio_err, "Error Opening OCSP response file\n");
        +			goto end;
        +			}
        +		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
        +		BIO_free(derbio);
        +		if(!resp)
        +			{
        +			BIO_printf(bio_err, "Error reading OCSP response\n");
        +			goto end;
        +			}
        +	
        +		}
        +	else
        +		{
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	done_resp:
        +
        +	if (respout)
        +		{
        +		derbio = BIO_new_file(respout, "wb");
        +		if(!derbio)
        +			{
        +			BIO_printf(bio_err, "Error opening file %s\n", respout);
        +			goto end;
        +			}
        +		i2d_OCSP_RESPONSE_bio(derbio, resp);
        +		BIO_free(derbio);
        +		}
        +
        +	i = OCSP_response_status(resp);
        +
        +	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
        +		{
        +		BIO_printf(out, "Responder Error: %s (%d)\n",
        +				OCSP_response_status_str(i), i);
        +		if (ignore_err)
        +			goto redo_accept;
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
        +
        +	/* If running as responder don't verify our own response */
        +	if (cbio)
        +		{
        +		if (accept_count > 0)
        +			accept_count--;
        +		/* Redo if more connections needed */
        +		if (accept_count)
        +			{
        +			BIO_free_all(cbio);
        +			cbio = NULL;
        +			OCSP_REQUEST_free(req);
        +			req = NULL;
        +			OCSP_RESPONSE_free(resp);
        +			resp = NULL;
        +			goto redo_accept;
        +			}
        +		goto end;
        +		}
        +
        +	if (!store)
        +		store = setup_verify(bio_err, CAfile, CApath);
        +	if (!store)
        +		goto end;
        +	if (verify_certfile)
        +		{
        +		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
        +			NULL, e, "validator certificate");
        +		if (!verify_other) goto end;
        +		}
        +
        +	bs = OCSP_response_get1_basic(resp);
        +
        +	if (!bs)
        +		{
        +		BIO_printf(bio_err, "Error parsing response\n");
        +		goto end;
        +		}
        +
        +	if (!noverify)
        +		{
        +		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
        +			{
        +			if (i == -1)
        +				BIO_printf(bio_err, "WARNING: no nonce in response\n");
        +			else
        +				{
        +				BIO_printf(bio_err, "Nonce Verify error\n");
        +				goto end;
        +				}
        +			}
        +
        +		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
        +                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
        +
        +		if(i <= 0)
        +			{
        +			BIO_printf(bio_err, "Response Verify Failure\n");
        +			ERR_print_errors(bio_err);
        +			}
        +		else
        +			BIO_printf(bio_err, "Response verify OK\n");
        +
        +		}
        +
        +	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
        +		goto end;
        +
        +	ret = 0;
        +
        +end:
        +	ERR_print_errors(bio_err);
        +	X509_free(signer);
        +	X509_STORE_free(store);
        +	EVP_PKEY_free(key);
        +	EVP_PKEY_free(rkey);
        +	X509_free(issuer);
        +	X509_free(cert);
        +	X509_free(rsigner);
        +	X509_free(rca_cert);
        +	free_index(rdb);
        +	BIO_free_all(cbio);
        +	BIO_free_all(acbio);
        +	BIO_free(out);
        +	OCSP_REQUEST_free(req);
        +	OCSP_RESPONSE_free(resp);
        +	OCSP_BASICRESP_free(bs);
        +	sk_OPENSSL_STRING_free(reqnames);
        +	sk_OCSP_CERTID_free(ids);
        +	sk_X509_pop_free(sign_other, X509_free);
        +	sk_X509_pop_free(verify_other, X509_free);
        +	sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
        +
        +	if (use_ssl != -1)
        +		{
        +		OPENSSL_free(host);
        +		OPENSSL_free(port);
        +		OPENSSL_free(path);
        +		}
        +
        +	OPENSSL_EXIT(ret);
        +}
        +
        +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
        +				STACK_OF(OCSP_CERTID) *ids)
        +	{
        +	OCSP_CERTID *id;
        +	if(!issuer)
        +		{
        +		BIO_printf(bio_err, "No issuer certificate specified\n");
        +		return 0;
        +		}
        +	if(!*req) *req = OCSP_REQUEST_new();
        +	if(!*req) goto err;
        +	id = OCSP_cert_to_id(cert_id_md, cert, issuer);
        +	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
        +	if(!OCSP_request_add0_id(*req, id)) goto err;
        +	return 1;
        +
        +	err:
        +	BIO_printf(bio_err, "Error Creating OCSP request\n");
        +	return 0;
        +	}
        +
        +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
        +				STACK_OF(OCSP_CERTID) *ids)
        +	{
        +	OCSP_CERTID *id;
        +	X509_NAME *iname;
        +	ASN1_BIT_STRING *ikey;
        +	ASN1_INTEGER *sno;
        +	if(!issuer)
        +		{
        +		BIO_printf(bio_err, "No issuer certificate specified\n");
        +		return 0;
        +		}
        +	if(!*req) *req = OCSP_REQUEST_new();
        +	if(!*req) goto err;
        +	iname = X509_get_subject_name(issuer);
        +	ikey = X509_get0_pubkey_bitstr(issuer);
        +	sno = s2i_ASN1_INTEGER(NULL, serial);
        +	if(!sno)
        +		{
        +		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
        +		return 0;
        +		}
        +	id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
        +	ASN1_INTEGER_free(sno);
        +	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
        +	if(!OCSP_request_add0_id(*req, id)) goto err;
        +	return 1;
        +
        +	err:
        +	BIO_printf(bio_err, "Error Creating OCSP request\n");
        +	return 0;
        +	}
        +
        +static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
        +			      STACK_OF(OPENSSL_STRING) *names,
        +			      STACK_OF(OCSP_CERTID) *ids, long nsec,
        +			      long maxage)
        +	{
        +	OCSP_CERTID *id;
        +	char *name;
        +	int i;
        +
        +	int status, reason;
        +
        +	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
        +
        +	if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
        +		return 1;
        +
        +	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
        +		{
        +		id = sk_OCSP_CERTID_value(ids, i);
        +		name = sk_OPENSSL_STRING_value(names, i);
        +		BIO_printf(out, "%s: ", name);
        +
        +		if(!OCSP_resp_find_status(bs, id, &status, &reason,
        +					&rev, &thisupd, &nextupd))
        +			{
        +			BIO_puts(out, "ERROR: No Status found.\n");
        +			continue;
        +			}
        +
        +		/* Check validity: if invalid write to output BIO so we
        +		 * know which response this refers to.
        +		 */
        +		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
        +			{
        +			BIO_puts(out, "WARNING: Status times invalid.\n");
        +			ERR_print_errors(out);
        +			}
        +		BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
        +
        +		BIO_puts(out, "\tThis Update: ");
        +		ASN1_GENERALIZEDTIME_print(out, thisupd);
        +		BIO_puts(out, "\n");
        +
        +		if(nextupd)
        +			{
        +			BIO_puts(out, "\tNext Update: ");
        +			ASN1_GENERALIZEDTIME_print(out, nextupd);
        +			BIO_puts(out, "\n");
        +			}
        +
        +		if (status != V_OCSP_CERTSTATUS_REVOKED)
        +			continue;
        +
        +		if (reason != -1)
        +			BIO_printf(out, "\tReason: %s\n",
        +				OCSP_crl_reason_str(reason));
        +
        +		BIO_puts(out, "\tRevocation Time: ");
        +		ASN1_GENERALIZEDTIME_print(out, rev);
        +		BIO_puts(out, "\n");
        +		}
        +
        +	return 1;
        +	}
        +
        +
        +static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
        +			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
        +			STACK_OF(X509) *rother, unsigned long flags,
        +			int nmin, int ndays)
        +	{
        +	ASN1_TIME *thisupd = NULL, *nextupd = NULL;
        +	OCSP_CERTID *cid, *ca_id = NULL;
        +	OCSP_BASICRESP *bs = NULL;
        +	int i, id_count, ret = 1;
        +
        +	id_count = OCSP_request_onereq_count(req);
        +
        +	if (id_count <= 0)
        +		{
        +		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
        +		goto end;
        +		}
        +
        +
        +	bs = OCSP_BASICRESP_new();
        +	thisupd = X509_gmtime_adj(NULL, 0);
        +	if (ndays != -1)
        +		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
        +
        +	/* Examine each certificate id in the request */
        +	for (i = 0; i < id_count; i++)
        +		{
        +		OCSP_ONEREQ *one;
        +		ASN1_INTEGER *serial;
        +		char **inf;
        +		ASN1_OBJECT *cert_id_md_oid;
        +		const EVP_MD *cert_id_md;
        +		one = OCSP_request_onereq_get0(req, i);
        +		cid = OCSP_onereq_get0_id(one);
        +
        +		OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
        +
        +		cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);	
        +		if (! cert_id_md) 
        +			{
        +			*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
        +				NULL);
        +				goto end;
        +			}	
        +		if (ca_id) OCSP_CERTID_free(ca_id);
        +		ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
        +
        +		/* Is this request about our CA? */
        +		if (OCSP_id_issuer_cmp(ca_id, cid))
        +			{
        +			OCSP_basic_add1_status(bs, cid,
        +						V_OCSP_CERTSTATUS_UNKNOWN,
        +						0, NULL,
        +						thisupd, nextupd);
        +			continue;
        +			}
        +		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
        +		inf = lookup_serial(db, serial);
        +		if (!inf)
        +			OCSP_basic_add1_status(bs, cid,
        +						V_OCSP_CERTSTATUS_UNKNOWN,
        +						0, NULL,
        +						thisupd, nextupd);
        +		else if (inf[DB_type][0] == DB_TYPE_VAL)
        +			OCSP_basic_add1_status(bs, cid,
        +						V_OCSP_CERTSTATUS_GOOD,
        +						0, NULL,
        +						thisupd, nextupd);
        +		else if (inf[DB_type][0] == DB_TYPE_REV)
        +			{
        +			ASN1_OBJECT *inst = NULL;
        +			ASN1_TIME *revtm = NULL;
        +			ASN1_GENERALIZEDTIME *invtm = NULL;
        +			OCSP_SINGLERESP *single;
        +			int reason = -1;
        +			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
        +			single = OCSP_basic_add1_status(bs, cid,
        +						V_OCSP_CERTSTATUS_REVOKED,
        +						reason, revtm,
        +						thisupd, nextupd);
        +			if (invtm)
        +				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
        +			else if (inst)
        +				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
        +			ASN1_OBJECT_free(inst);
        +			ASN1_TIME_free(revtm);
        +			ASN1_GENERALIZEDTIME_free(invtm);
        +			}
        +		}
        +
        +	OCSP_copy_nonce(bs, req);
        +	
        +	OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
        +
        +	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
        +
        +	end:
        +	ASN1_TIME_free(thisupd);
        +	ASN1_TIME_free(nextupd);
        +	OCSP_CERTID_free(ca_id);
        +	OCSP_BASICRESP_free(bs);
        +	return ret;
        +
        +	}
        +
        +static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
        +	{
        +	int i;
        +	BIGNUM *bn = NULL;
        +	char *itmp, *row[DB_NUMBER],**rrow;
        +	for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
        +	bn = ASN1_INTEGER_to_BN(ser,NULL);
        +	OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */
        +	if (BN_is_zero(bn))
        +		itmp = BUF_strdup("00");
        +	else
        +		itmp = BN_bn2hex(bn);
        +	row[DB_serial] = itmp;
        +	BN_free(bn);
        +	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
        +	OPENSSL_free(itmp);
        +	return rrow;
        +	}
        +
        +/* Quick and dirty OCSP server: read in and parse input request */
        +
        +static BIO *init_responder(char *port)
        +	{
        +	BIO *acbio = NULL, *bufbio = NULL;
        +	bufbio = BIO_new(BIO_f_buffer());
        +	if (!bufbio) 
        +		goto err;
        +#ifndef OPENSSL_NO_SOCK
        +	acbio = BIO_new_accept(port);
        +#else
        +	BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
        +#endif
        +	if (!acbio)
        +		goto err;
        +	BIO_set_accept_bios(acbio, bufbio);
        +	bufbio = NULL;
        +
        +	if (BIO_do_accept(acbio) <= 0)
        +		{
        +			BIO_printf(bio_err, "Error setting up accept BIO\n");
        +			ERR_print_errors(bio_err);
        +			goto err;
        +		}
        +
        +	return acbio;
        +
        +	err:
        +	BIO_free_all(acbio);
        +	BIO_free(bufbio);
        +	return NULL;
        +	}
        +
        +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
        +	{
        +	int have_post = 0, len;
        +	OCSP_REQUEST *req = NULL;
        +	char inbuf[1024];
        +	BIO *cbio = NULL;
        +
        +	if (BIO_do_accept(acbio) <= 0)
        +		{
        +			BIO_printf(bio_err, "Error accepting connection\n");
        +			ERR_print_errors(bio_err);
        +			return 0;
        +		}
        +
        +	cbio = BIO_pop(acbio);
        +	*pcbio = cbio;
        +
        +	for(;;)
        +		{
        +		len = BIO_gets(cbio, inbuf, sizeof inbuf);
        +		if (len <= 0)
        +			return 1;
        +		/* Look for "POST" signalling start of query */
        +		if (!have_post)
        +			{
        +			if(strncmp(inbuf, "POST", 4))
        +				{
        +				BIO_printf(bio_err, "Invalid request\n");
        +				return 1;
        +				}
        +			have_post = 1;
        +			}
        +		/* Look for end of headers */
        +		if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
        +			break;
        +		}
        +
        +	/* Try to read OCSP request */
        +
        +	req = d2i_OCSP_REQUEST_bio(cbio, NULL);
        +
        +	if (!req)
        +		{
        +		BIO_printf(bio_err, "Error parsing OCSP request\n");
        +		ERR_print_errors(bio_err);
        +		}
        +
        +	*preq = req;
        +
        +	return 1;
        +
        +	}
        +
        +static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
        +	{
        +	char http_resp[] = 
        +		"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
        +		"Content-Length: %d\r\n\r\n";
        +	if (!cbio)
        +		return 0;
        +	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
        +	i2d_OCSP_RESPONSE_bio(cbio, resp);
        +	(void)BIO_flush(cbio);
        +	return 1;
        +	}
        +
        +static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
        +				STACK_OF(CONF_VALUE) *headers,
        +				OCSP_REQUEST *req, int req_timeout)
        +	{
        +	int fd;
        +	int rv;
        +	int i;
        +	OCSP_REQ_CTX *ctx = NULL;
        +	OCSP_RESPONSE *rsp = NULL;
        +	fd_set confds;
        +	struct timeval tv;
        +
        +	if (req_timeout != -1)
        +		BIO_set_nbio(cbio, 1);
        +
        +	rv = BIO_do_connect(cbio);
        +
        +	if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
        +		{
        +		BIO_puts(err, "Error connecting BIO\n");
        +		return NULL;
        +		}
        +
        +	if (BIO_get_fd(cbio, &fd) <= 0)
        +		{
        +		BIO_puts(err, "Can't get connection fd\n");
        +		goto err;
        +		}
        +
        +	if (req_timeout != -1 && rv <= 0)
        +		{
        +		FD_ZERO(&confds);
        +		openssl_fdset(fd, &confds);
        +		tv.tv_usec = 0;
        +		tv.tv_sec = req_timeout;
        +		rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
        +		if (rv == 0)
        +			{
        +			BIO_puts(err, "Timeout on connect\n");
        +			return NULL;
        +			}
        +		}
        +
        +
        +	ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
        +	if (!ctx)
        +		return NULL;
        +
        +	for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
        +		{
        +		CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
        +		if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
        +			goto err;
        +		}
        +
        +	if (!OCSP_REQ_CTX_set1_req(ctx, req))
        +		goto err;
        +	
        +	for (;;)
        +		{
        +		rv = OCSP_sendreq_nbio(&rsp, ctx);
        +		if (rv != -1)
        +			break;
        +		if (req_timeout == -1)
        +			continue;
        +		FD_ZERO(&confds);
        +		openssl_fdset(fd, &confds);
        +		tv.tv_usec = 0;
        +		tv.tv_sec = req_timeout;
        +		if (BIO_should_read(cbio))
        +			rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
        +		else if (BIO_should_write(cbio))
        +			rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
        +		else
        +			{
        +			BIO_puts(err, "Unexpected retry condition\n");
        +			goto err;
        +			}
        +		if (rv == 0)
        +			{
        +			BIO_puts(err, "Timeout on request\n");
        +			break;
        +			}
        +		if (rv == -1)
        +			{
        +			BIO_puts(err, "Select error\n");
        +			break;
        +			}
        +
        +		}
        +	err:
        +	if (ctx)
        +		OCSP_REQ_CTX_free(ctx);
        +
        +	return rsp;
        +	}
        +
        +OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
        +			char *host, char *path, char *port, int use_ssl,
        +			STACK_OF(CONF_VALUE) *headers,
        +			int req_timeout)
        +	{
        +	BIO *cbio = NULL;
        +	SSL_CTX *ctx = NULL;
        +	OCSP_RESPONSE *resp = NULL;
        +	cbio = BIO_new_connect(host);
        +	if (!cbio)
        +		{
        +		BIO_printf(err, "Error creating connect BIO\n");
        +		goto end;
        +		}
        +	if (port) BIO_set_conn_port(cbio, port);
        +	if (use_ssl == 1)
        +		{
        +		BIO *sbio;
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +		ctx = SSL_CTX_new(SSLv23_client_method());
        +#elif !defined(OPENSSL_NO_SSL3)
        +		ctx = SSL_CTX_new(SSLv3_client_method());
        +#elif !defined(OPENSSL_NO_SSL2)
        +		ctx = SSL_CTX_new(SSLv2_client_method());
        +#else
        +		BIO_printf(err, "SSL is disabled\n");
        +			goto end;
        +#endif
        +		if (ctx == NULL)
        +			{
        +			BIO_printf(err, "Error creating SSL context.\n");
        +			goto end;
        +			}
        +		SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
        +		sbio = BIO_new_ssl(ctx, 1);
        +		cbio = BIO_push(sbio, cbio);
        +		}
        +	resp = query_responder(err, cbio, path, headers, req, req_timeout);
        +	if (!resp)
        +		BIO_printf(bio_err, "Error querying OCSP responsder\n");
        +	end:
        +	if (cbio)
        +		BIO_free_all(cbio);
        +	if (ctx)
        +		SSL_CTX_free(ctx);
        +	return resp;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/oid.cnf b/vendor/openssl/openssl/apps/oid.cnf
        new file mode 100644
        index 000000000..faf425a15
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/oid.cnf
        @@ -0,0 +1,6 @@
        +2.99999.1       SET.ex1         SET x509v3 extension 1
        +2.99999.2       SET.ex2         SET x509v3 extension 2
        +2.99999.3       SET.ex3         SET x509v3 extension 3
        +2.99999.4       SET.ex4         SET x509v3 extension 4
        +2.99999.5       SET.ex5         SET x509v3 extension 5
        +2.99999.6       SET.ex6         SET x509v3 extension 6
        diff --git a/vendor/openssl/openssl/apps/openssl-vms.cnf b/vendor/openssl/openssl/apps/openssl-vms.cnf
        new file mode 100644
        index 000000000..45e46a0fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/openssl-vms.cnf
        @@ -0,0 +1,350 @@
        +#
        +# OpenSSL example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +# This definition stops the following lines choking if HOME isn't
        +# defined.
        +HOME			= .
        +RANDFILE		= $ENV::HOME/.rnd
        +
        +# Extra OBJECT IDENTIFIER info:
        +#oid_file		= $ENV::HOME/.oid
        +oid_section		= new_oids
        +
        +# To use this configuration file with the "-extfile" option of the
        +# "openssl x509" utility, name here the section containing the
        +# X.509v3 extensions to use:
        +# extensions		= 
        +# (Alternatively, use a configuration file that has only
        +# X.509v3 extensions in its main [= default] section.)
        +
        +[ new_oids ]
        +
        +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
        +# Add a simple OID like this:
        +# testoid1=1.2.3.4
        +# Or use config file substitution like this:
        +# testoid2=${testoid1}.5.6
        +
        +# Policies used by the TSA examples.
        +tsa_policy1 = 1.2.3.4.1
        +tsa_policy2 = 1.2.3.4.5.6
        +tsa_policy3 = 1.2.3.4.5.7
        +
        +####################################################################
        +[ ca ]
        +default_ca	= CA_default		# The default ca section
        +
        +####################################################################
        +[ CA_default ]
        +
        +dir		= sys\$disk:[.demoCA		# Where everything is kept
        +certs		= $dir.certs]		# Where the issued certs are kept
        +crl_dir		= $dir.crl]		# Where the issued crl are kept
        +database	= $dir]index.txt	# database index file.
        +#unique_subject	= no			# Set to 'no' to allow creation of
        +					# several ctificates with same subject.
        +new_certs_dir	= $dir.newcerts]		# default place for new certs.
        +
        +certificate	= $dir]cacert.pem 	# The CA certificate
        +serial		= $dir]serial. 		# The current serial number
        +crlnumber	= $dir]crlnumber.	# the current crl number
        +					# must be commented out to leave a V1 CRL
        +crl		= $dir]crl.pem 		# The current CRL
        +private_key	= $dir.private]cakey.pem# The private key
        +RANDFILE	= $dir.private].rand	# private random number file
        +
        +x509_extensions	= usr_cert		# The extentions to add to the cert
        +
        +# Comment out the following two lines for the "traditional"
        +# (and highly broken) format.
        +name_opt 	= ca_default		# Subject Name options
        +cert_opt 	= ca_default		# Certificate field options
        +
        +# Extension copying option: use with caution.
        +# copy_extensions = copy
        +
        +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
        +# so this is commented out by default to leave a V1 CRL.
        +# crlnumber must also be commented out to leave a V1 CRL.
        +# crl_extensions	= crl_ext
        +
        +default_days	= 365			# how long to certify for
        +default_crl_days= 30			# how long before next CRL
        +default_md	= default		# use public key default MD
        +preserve	= no			# keep passed DN ordering
        +
        +# A few difference way of specifying how similar the request should look
        +# For type CA, the listed attributes must be the same, and the optional
        +# and supplied fields are just that :-)
        +policy		= policy_match
        +
        +# For the CA policy
        +[ policy_match ]
        +countryName		= match
        +stateOrProvinceName	= match
        +organizationName	= match
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +# For the 'anything' policy
        +# At this point in time, you must list all acceptable 'object'
        +# types.
        +[ policy_anything ]
        +countryName		= optional
        +stateOrProvinceName	= optional
        +localityName		= optional
        +organizationName	= optional
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +####################################################################
        +[ req ]
        +default_bits		= 1024
        +default_keyfile 	= privkey.pem
        +distinguished_name	= req_distinguished_name
        +attributes		= req_attributes
        +x509_extensions	= v3_ca	# The extentions to add to the self signed cert
        +
        +# Passwords for private keys if not present they will be prompted for
        +# input_password = secret
        +# output_password = secret
        +
        +# This sets a mask for permitted string types. There are several options. 
        +# default: PrintableString, T61String, BMPString.
        +# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004)
        +# utf8only: only UTF8Strings (PKIX recommendation after 2004).
        +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
        +# MASK:XXXX a literal mask value.
        +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
        +string_mask = utf8only
        +
        +# req_extensions = v3_req # The extensions to add to a certificate request
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_min			= 2
        +countryName_max			= 2
        +
        +stateOrProvinceName		= State or Province Name (full name)
        +stateOrProvinceName_default	= Some-State
        +
        +localityName			= Locality Name (eg, city)
        +
        +0.organizationName		= Organization Name (eg, company)
        +0.organizationName_default	= Internet Widgits Pty Ltd
        +
        +# we can do this but it is not needed normally :-)
        +#1.organizationName		= Second Organization Name (eg, company)
        +#1.organizationName_default	= World Wide Web Pty Ltd
        +
        +organizationalUnitName		= Organizational Unit Name (eg, section)
        +#organizationalUnitName_default	=
        +
        +commonName			= Common Name (e.g. server FQDN or YOUR name)
        +commonName_max			= 64
        +
        +emailAddress			= Email Address
        +emailAddress_max		= 64
        +
        +# SET-ex3			= SET extension number 3
        +
        +[ req_attributes ]
        +challengePassword		= A challenge password
        +challengePassword_min		= 4
        +challengePassword_max		= 20
        +
        +unstructuredName		= An optional company name
        +
        +[ usr_cert ]
        +
        +# These extensions are added when 'ca' signs a request.
        +
        +# This goes against PKIX guidelines but some CAs do it and some software
        +# requires this to avoid interpreting an end user certificate as a CA.
        +
        +basicConstraints=CA:FALSE
        +
        +# Here are some examples of the usage of nsCertType. If it is omitted
        +# the certificate can be used for anything *except* object signing.
        +
        +# This is OK for an SSL server.
        +# nsCertType			= server
        +
        +# For an object signing certificate this would be used.
        +# nsCertType = objsign
        +
        +# For normal client use this is typical
        +# nsCertType = client, email
        +
        +# and for everything including object signing:
        +# nsCertType = client, email, objsign
        +
        +# This is typical in keyUsage for a client certificate.
        +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +
        +# This will be displayed in Netscape's comment listbox.
        +nsComment			= "OpenSSL Generated Certificate"
        +
        +# PKIX recommendations harmless if included in all certificates.
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer
        +
        +# This stuff is for subjectAltName and issuerAltname.
        +# Import the email address.
        +# subjectAltName=email:copy
        +# An alternative to produce certificates that aren't
        +# deprecated according to PKIX.
        +# subjectAltName=email:move
        +
        +# Copy subject details
        +# issuerAltName=issuer:copy
        +
        +#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
        +#nsBaseUrl
        +#nsRevocationUrl
        +#nsRenewalUrl
        +#nsCaPolicyUrl
        +#nsSslServerName
        +
        +# This is required for TSA certificates.
        +# extendedKeyUsage = critical,timeStamping
        +
        +[ v3_req ]
        +
        +# Extensions to add to a certificate request
        +
        +basicConstraints = CA:FALSE
        +keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +
        +[ v3_ca ]
        +
        +
        +# Extensions for a typical CA
        +
        +
        +# PKIX recommendation.
        +
        +subjectKeyIdentifier=hash
        +
        +authorityKeyIdentifier=keyid:always,issuer
        +
        +# This is what PKIX recommends but some broken software chokes on critical
        +# extensions.
        +#basicConstraints = critical,CA:true
        +# So we do this instead.
        +basicConstraints = CA:true
        +
        +# Key usage: this is typical for a CA certificate. However since it will
        +# prevent it being used as an test self-signed certificate it is best
        +# left out by default.
        +# keyUsage = cRLSign, keyCertSign
        +
        +# Some might want this also
        +# nsCertType = sslCA, emailCA
        +
        +# Include email address in subject alt name: another PKIX recommendation
        +# subjectAltName=email:copy
        +# Copy issuer details
        +# issuerAltName=issuer:copy
        +
        +# DER hex encoding of an extension: beware experts only!
        +# obj=DER:02:03
        +# Where 'obj' is a standard or added object
        +# You can even override a supported extension:
        +# basicConstraints= critical, DER:30:03:01:01:FF
        +
        +[ crl_ext ]
        +
        +# CRL extensions.
        +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
        +
        +# issuerAltName=issuer:copy
        +authorityKeyIdentifier=keyid:always
        +
        +[ proxy_cert_ext ]
        +# These extensions should be added when creating a proxy certificate
        +
        +# This goes against PKIX guidelines but some CAs do it and some software
        +# requires this to avoid interpreting an end user certificate as a CA.
        +
        +basicConstraints=CA:FALSE
        +
        +# Here are some examples of the usage of nsCertType. If it is omitted
        +# the certificate can be used for anything *except* object signing.
        +
        +# This is OK for an SSL server.
        +# nsCertType			= server
        +
        +# For an object signing certificate this would be used.
        +# nsCertType = objsign
        +
        +# For normal client use this is typical
        +# nsCertType = client, email
        +
        +# and for everything including object signing:
        +# nsCertType = client, email, objsign
        +
        +# This is typical in keyUsage for a client certificate.
        +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +
        +# This will be displayed in Netscape's comment listbox.
        +nsComment			= "OpenSSL Generated Certificate"
        +
        +# PKIX recommendations harmless if included in all certificates.
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer
        +
        +# This stuff is for subjectAltName and issuerAltname.
        +# Import the email address.
        +# subjectAltName=email:copy
        +# An alternative to produce certificates that aren't
        +# deprecated according to PKIX.
        +# subjectAltName=email:move
        +
        +# Copy subject details
        +# issuerAltName=issuer:copy
        +
        +#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
        +#nsBaseUrl
        +#nsRevocationUrl
        +#nsRenewalUrl
        +#nsCaPolicyUrl
        +#nsSslServerName
        +
        +# This really needs to be in place for it to be a proxy certificate.
        +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
        +
        +####################################################################
        +[ tsa ]
        +
        +default_tsa = tsa_config1	# the default TSA section
        +
        +[ tsa_config1 ]
        +
        +# These are used by the TSA reply generation only.
        +dir		= sys\$disk:[.demoCA		# TSA root directory
        +serial		= $dir]tsaserial.	# The current serial number (mandatory)
        +crypto_device	= builtin		# OpenSSL engine to use for signing
        +signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate
        +					# (optional)
        +certs		= $dir.cacert.pem]	# Certificate chain to include in reply
        +					# (optional)
        +signer_key	= $dir/private/tsakey.pem # The TSA private key (optional)
        +
        +default_policy	= tsa_policy1		# Policy if request did not specify it
        +					# (optional)
        +other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
        +digests		= md5, sha1		# Acceptable message digests (mandatory)
        +accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
        +clock_precision_digits  = 0	# number of digits after dot. (optional)
        +ordering		= yes	# Is ordering defined for timestamps?
        +				# (optional, default: no)
        +tsa_name		= yes	# Must the TSA name be included in the reply?
        +				# (optional, default: no)
        +ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
        +				# (optional, default: no)
        diff --git a/vendor/openssl/openssl/apps/openssl.c b/vendor/openssl/openssl/apps/openssl.c
        new file mode 100644
        index 000000000..1c880d90b
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/openssl.c
        @@ -0,0 +1,728 @@
        +/* apps/openssl.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-2006 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 <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#define OPENSSL_C /* tells apps.h to use complete apps_startup() */
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/lhash.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
        +#include "progs.h"
        +#include "s_apps.h"
        +#include <openssl/err.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
        + * base prototypes (we cast each variable inside the function to the required
        + * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
        + * functions. */
        +
        +static LHASH_OF(FUNCTION) *prog_init(void );
        +static int do_cmd(LHASH_OF(FUNCTION) *prog,int argc,char *argv[]);
        +static void list_pkey(BIO *out);
        +static void list_cipher(BIO *out);
        +static void list_md(BIO *out);
        +char *default_config_file=NULL;
        +
        +/* Make sure there is only one when MONOLITH is defined */
        +#ifdef MONOLITH
        +CONF *config=NULL;
        +BIO *bio_err=NULL;
        +#endif
        +
        +
        +static void lock_dbg_cb(int mode, int type, const char *file, int line)
        +	{
        +	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
        +	const char *errstr = NULL;
        +	int rw;
        +	
        +	rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
        +	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
        +		{
        +		errstr = "invalid mode";
        +		goto err;
        +		}
        +
        +	if (type < 0 || type >= CRYPTO_NUM_LOCKS)
        +		{
        +		errstr = "type out of bounds";
        +		goto err;
        +		}
        +
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		if (modes[type])
        +			{
        +			errstr = "already locked";
        +			/* must not happen in a single-threaded program
        +			 * (would deadlock) */
        +			goto err;
        +			}
        +
        +		modes[type] = rw;
        +		}
        +	else if (mode & CRYPTO_UNLOCK)
        +		{
        +		if (!modes[type])
        +			{
        +			errstr = "not locked";
        +			goto err;
        +			}
        +		
        +		if (modes[type] != rw)
        +			{
        +			errstr = (rw == CRYPTO_READ) ?
        +				"CRYPTO_r_unlock on write lock" :
        +				"CRYPTO_w_unlock on read lock";
        +			}
        +
        +		modes[type] = 0;
        +		}
        +	else
        +		{
        +		errstr = "invalid mode";
        +		goto err;
        +		}
        +
        + err:
        +	if (errstr)
        +		{
        +		/* we cannot use bio_err here */
        +		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
        +			errstr, mode, type, file, line);
        +		}
        +	}
        +
        +#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
        +# define ARGV _Argv
        +#else
        +# define ARGV Argv
        +#endif
        +
        +int main(int Argc, char *ARGV[])
        +	{
        +	ARGS arg;
        +#define PROG_NAME_SIZE	39
        +	char pname[PROG_NAME_SIZE+1];
        +	FUNCTION f,*fp;
        +	MS_STATIC const char *prompt;
        +	MS_STATIC char buf[1024];
        +	char *to_free=NULL;
        +	int n,i,ret=0;
        +	int argc;
        +	char **argv,*p;
        +	LHASH_OF(FUNCTION) *prog=NULL;
        +	long errline;
        +
        +#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
        +	/* 2011-03-22 SMS.
        +	 * If we have 32-bit pointers everywhere, then we're safe, and
        +	 * we bypass this mess, as on non-VMS systems.  (See ARGV,
        +	 * above.)
        +	 * Problem 1: Compaq/HP C before V7.3 always used 32-bit
        +	 * pointers for argv[].
        +	 * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
        +	 * everywhere else, we always allocate and use a 64-bit
        +	 * duplicate of argv[].
        +	 * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
        +	 * to NULL-terminate a 64-bit argv[].  (As this was written, the
        +	 * compiler ECO was available only on IA64.)
        +	 * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
        +	 * 64-bit argv[argc] for NULL, and, if necessary, use a
        +	 * (properly) NULL-terminated (64-bit) duplicate of argv[].
        +	 * The same code is used in either case to duplicate argv[].
        +	 * Some of these decisions could be handled in preprocessing,
        +	 * but the code tends to get even uglier, and the penalty for
        +	 * deciding at compile- or run-time is tiny.
        +	 */
        +	char **Argv = NULL;
        +	int free_Argv = 0;
        +
        +	if ((sizeof( _Argv) < 8)        /* 32-bit argv[]. */
        +# if !defined( VMS_TRUST_ARGV)
        +	 || (_Argv[ Argc] != NULL)      /* Untrusted argv[argc] not NULL. */
        +# endif
        +		)
        +		{
        +		int i;
        +		Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *));
        +		if (Argv == NULL)
        +			{ ret = -1; goto end; }
        +		for(i = 0; i < Argc; i++)
        +			Argv[i] = _Argv[i];
        +		Argv[ Argc] = NULL;     /* Certain NULL termination. */
        +		free_Argv = 1;
        +		}
        +	else
        +		{
        +		/* Use the known-good 32-bit argv[] (which needs the
        +		 * type cast to satisfy the compiler), or the trusted or
        +		 * tested-good 64-bit argv[] as-is. */
        +		Argv = (char **)_Argv;
        +		}
        +#endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */
        +
        +	arg.data=NULL;
        +	arg.count=0;
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */
        +		{
        +		if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))
        +			{
        +			CRYPTO_malloc_debug_init();
        +			CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +			}
        +		else
        +			{
        +			/* OPENSSL_DEBUG_MEMORY=off */
        +			CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +			}
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +#if 0
        +	if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
        +#endif
        +		{
        +		CRYPTO_set_locking_callback(lock_dbg_cb);
        +		}
        +
        +	if(getenv("OPENSSL_FIPS")) {
        +#ifdef OPENSSL_FIPS
        +		if (!FIPS_mode_set(1)) {
        +			ERR_load_crypto_strings();
        +			ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
        +			EXIT(1);
        +		}
        +#else
        +		fprintf(stderr, "FIPS mode not supported.\n");
        +		EXIT(1);
        +#endif
        +		}
        +
        +	apps_startup();
        +
        +	/* Lets load up our environment a little */
        +	p=getenv("OPENSSL_CONF");
        +	if (p == NULL)
        +		p=getenv("SSLEAY_CONF");
        +	if (p == NULL)
        +		p=to_free=make_config_name();
        +
        +	default_config_file=p;
        +
        +	config=NCONF_new(NULL);
        +	i=NCONF_load(config,p,&errline);
        +	if (i == 0)
        +		{
        +		if (ERR_GET_REASON(ERR_peek_last_error())
        +		    == CONF_R_NO_SUCH_FILE)
        +			{
        +			BIO_printf(bio_err,
        +				   "WARNING: can't open config file: %s\n",p);
        +			ERR_clear_error();
        +			NCONF_free(config);
        +			config = NULL;
        +			}
        +		else
        +			{
        +			ERR_print_errors(bio_err);
        +			NCONF_free(config);
        +			exit(1);
        +			}
        +		}
        +
        +	prog=prog_init();
        +
        +	/* first check the program name */
        +	program_name(Argv[0],pname,sizeof pname);
        +
        +	f.name=pname;
        +	fp=lh_FUNCTION_retrieve(prog,&f);
        +	if (fp != NULL)
        +		{
        +		Argv[0]=pname;
        +		ret=fp->func(Argc,Argv);
        +		goto end;
        +		}
        +
        +	/* ok, now check that there are not arguments, if there are,
        +	 * run with them, shifting the ssleay off the front */
        +	if (Argc != 1)
        +		{
        +		Argc--;
        +		Argv++;
        +		ret=do_cmd(prog,Argc,Argv);
        +		if (ret < 0) ret=0;
        +		goto end;
        +		}
        +
        +	/* ok, lets enter the old 'OpenSSL>' mode */
        +	
        +	for (;;)
        +		{
        +		ret=0;
        +		p=buf;
        +		n=sizeof buf;
        +		i=0;
        +		for (;;)
        +			{
        +			p[0]='\0';
        +			if (i++)
        +				prompt=">";
        +			else	prompt="OpenSSL> ";
        +			fputs(prompt,stdout);
        +			fflush(stdout);
        +			if (!fgets(p,n,stdin))
        +				goto end;
        +			if (p[0] == '\0') goto end;
        +			i=strlen(p);
        +			if (i <= 1) break;
        +			if (p[i-2] != '\\') break;
        +			i-=2;
        +			p+=i;
        +			n-=i;
        +			}
        +		if (!chopup_args(&arg,buf,&argc,&argv)) break;
        +
        +		ret=do_cmd(prog,argc,argv);
        +		if (ret < 0)
        +			{
        +			ret=0;
        +			goto end;
        +			}
        +		if (ret != 0)
        +			BIO_printf(bio_err,"error in %s\n",argv[0]);
        +		(void)BIO_flush(bio_err);
        +		}
        +	BIO_printf(bio_err,"bad exit\n");
        +	ret=1;
        +end:
        +	if (to_free)
        +		OPENSSL_free(to_free);
        +	if (config != NULL)
        +		{
        +		NCONF_free(config);
        +		config=NULL;
        +		}
        +	if (prog != NULL) lh_FUNCTION_free(prog);
        +	if (arg.data != NULL) OPENSSL_free(arg.data);
        +
        +	apps_shutdown();
        +
        +	CRYPTO_mem_leaks(bio_err);
        +	if (bio_err != NULL)
        +		{
        +		BIO_free(bio_err);
        +		bio_err=NULL;
        +		}
        +#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
        +	/* Free any duplicate Argv[] storage. */
        +	if (free_Argv)
        +		{
        +		OPENSSL_free(Argv);
        +		}
        +#endif
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +#define LIST_STANDARD_COMMANDS "list-standard-commands"
        +#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
        +#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
        +#define LIST_CIPHER_COMMANDS "list-cipher-commands"
        +#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
        +#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
        +
        +
        +static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
        +	{
        +	FUNCTION f,*fp;
        +	int i,ret=1,tp,nl;
        +
        +	if ((argc <= 0) || (argv[0] == NULL))
        +		{ ret=0; goto end; }
        +	f.name=argv[0];
        +	fp=lh_FUNCTION_retrieve(prog,&f);
        +	if (fp == NULL)
        +		{
        +		if (EVP_get_digestbyname(argv[0]))
        +			{
        +			f.type = FUNC_TYPE_MD;
        +			f.func = dgst_main;
        +			fp = &f;
        +			}
        +		else if (EVP_get_cipherbyname(argv[0]))
        +			{
        +			f.type = FUNC_TYPE_CIPHER;
        +			f.func = enc_main;
        +			fp = &f;
        +			}
        +		}
        +	if (fp != NULL)
        +		{
        +		ret=fp->func(argc,argv);
        +		}
        +	else if ((strncmp(argv[0],"no-",3)) == 0)
        +		{
        +		BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		bio_stdout = BIO_push(tmpbio, bio_stdout);
        +		}
        +#endif
        +		f.name=argv[0]+3;
        +		ret = (lh_FUNCTION_retrieve(prog,&f) != NULL);
        +		if (!ret)
        +			BIO_printf(bio_stdout, "%s\n", argv[0]);
        +		else
        +			BIO_printf(bio_stdout, "%s\n", argv[0]+3);
        +		BIO_free_all(bio_stdout);
        +		goto end;
        +		}
        +	else if ((strcmp(argv[0],"quit") == 0) ||
        +		(strcmp(argv[0],"q") == 0) ||
        +		(strcmp(argv[0],"exit") == 0) ||
        +		(strcmp(argv[0],"bye") == 0))
        +		{
        +		ret= -1;
        +		goto end;
        +		}
        +	else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) ||
        +		(strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
        +		(strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
        +		(strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) ||
        +		(strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) ||
        +		(strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0))
        +		{
        +		int list_type;
        +		BIO *bio_stdout;
        +
        +		if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0)
        +			list_type = FUNC_TYPE_GENERAL;
        +		else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0)
        +			list_type = FUNC_TYPE_MD;
        +		else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
        +			list_type = FUNC_TYPE_MD_ALG;
        +		else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)
        +			list_type = FUNC_TYPE_PKEY;
        +		else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0)
        +			list_type = FUNC_TYPE_CIPHER_ALG;
        +		else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
        +			list_type = FUNC_TYPE_CIPHER;
        +		bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		bio_stdout = BIO_push(tmpbio, bio_stdout);
        +		}
        +#endif
        +
        +		if (!load_config(bio_err, NULL))
        +			goto end;
        +
        +		if (list_type == FUNC_TYPE_PKEY)
        +			list_pkey(bio_stdout);	
        +		if (list_type == FUNC_TYPE_MD_ALG)
        +			list_md(bio_stdout);	
        +		if (list_type == FUNC_TYPE_CIPHER_ALG)
        +			list_cipher(bio_stdout);	
        +		else
        +			{
        +			for (fp=functions; fp->name != NULL; fp++)
        +				if (fp->type == list_type)
        +					BIO_printf(bio_stdout, "%s\n",
        +								fp->name);
        +			}
        +		BIO_free_all(bio_stdout);
        +		ret=0;
        +		goto end;
        +		}
        +	else
        +		{
        +		BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n",
        +			argv[0]);
        +		BIO_printf(bio_err, "\nStandard commands");
        +		i=0;
        +		tp=0;
        +		for (fp=functions; fp->name != NULL; fp++)
        +			{
        +			nl=0;
        +#ifdef OPENSSL_NO_CAMELLIA
        +			if (((i++) % 5) == 0)
        +#else
        +			if (((i++) % 4) == 0)
        +#endif
        +				{
        +				BIO_printf(bio_err,"\n");
        +				nl=1;
        +				}
        +			if (fp->type != tp)
        +				{
        +				tp=fp->type;
        +				if (!nl) BIO_printf(bio_err,"\n");
        +				if (tp == FUNC_TYPE_MD)
        +					{
        +					i=1;
        +					BIO_printf(bio_err,
        +						"\nMessage Digest commands (see the `dgst' command for more details)\n");
        +					}
        +				else if (tp == FUNC_TYPE_CIPHER)
        +					{
        +					i=1;
        +					BIO_printf(bio_err,"\nCipher commands (see the `enc' command for more details)\n");
        +					}
        +				}
        +#ifdef OPENSSL_NO_CAMELLIA
        +			BIO_printf(bio_err,"%-15s",fp->name);
        +#else
        +			BIO_printf(bio_err,"%-18s",fp->name);
        +#endif
        +			}
        +		BIO_printf(bio_err,"\n\n");
        +		ret=0;
        +		}
        +end:
        +	return(ret);
        +	}
        +
        +static int SortFnByName(const void *_f1,const void *_f2)
        +    {
        +    const FUNCTION *f1=_f1;
        +    const FUNCTION *f2=_f2;
        +
        +    if(f1->type != f2->type)
        +	return f1->type-f2->type;
        +    return strcmp(f1->name,f2->name);
        +    }
        +
        +static void list_pkey(BIO *out)
        +	{
        +	int i;
        +	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
        +		{
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +		int pkey_id, pkey_base_id, pkey_flags;
        +		const char *pinfo, *pem_str;
        +		ameth = EVP_PKEY_asn1_get0(i);
        +		EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
        +						&pinfo, &pem_str, ameth);
        +		if (pkey_flags & ASN1_PKEY_ALIAS)
        +			{
        +			BIO_printf(out, "Name: %s\n", 
        +					OBJ_nid2ln(pkey_id));
        +			BIO_printf(out, "\tType: Alias to %s\n",
        +					OBJ_nid2ln(pkey_base_id));
        +			}
        +		else
        +			{
        +			BIO_printf(out, "Name: %s\n", pinfo);
        +			BIO_printf(out, "\tType: %s Algorithm\n", 
        +				pkey_flags & ASN1_PKEY_DYNAMIC ?
        +					"External" : "Builtin");
        +			BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
        +			if (pem_str == NULL)
        +				pem_str = "(none)";
        +			BIO_printf(out, "\tPEM string: %s\n", pem_str);
        +			}
        +					
        +		}
        +	}
        +
        +static void list_cipher_fn(const EVP_CIPHER *c,
        +			const char *from, const char *to, void *arg)
        +	{
        +	if (c)
        +		BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
        +	else
        +		{
        +		if (!from)
        +			from = "<undefined>";
        +		if (!to)
        +			to = "<undefined>";
        +		BIO_printf(arg, "%s => %s\n", from, to);
        +		}
        +	}
        +
        +static void list_cipher(BIO *out)
        +	{
        +	EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
        +	}
        +
        +static void list_md_fn(const EVP_MD *m,
        +			const char *from, const char *to, void *arg)
        +	{
        +	if (m)
        +		BIO_printf(arg, "%s\n", EVP_MD_name(m));
        +	else
        +		{
        +		if (!from)
        +			from = "<undefined>";
        +		if (!to)
        +			to = "<undefined>";
        +		BIO_printf(arg, "%s => %s\n", from, to);
        +		}
        +	}
        +
        +static void list_md(BIO *out)
        +	{
        +	EVP_MD_do_all_sorted(list_md_fn, out);
        +	}
        +
        +static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b)
        +	{
        +	return strncmp(a->name,b->name,8);
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
        +
        +static unsigned long MS_CALLBACK function_hash(const FUNCTION *a)
        +	{
        +	return lh_strhash(a->name);
        +	}	
        +static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
        +
        +static LHASH_OF(FUNCTION) *prog_init(void)
        +	{
        +	LHASH_OF(FUNCTION) *ret;
        +	FUNCTION *f;
        +	size_t i;
        +
        +	/* Purely so it looks nice when the user hits ? */
        +	for(i=0,f=functions ; f->name != NULL ; ++f,++i)
        +	    ;
        +	qsort(functions,i,sizeof *functions,SortFnByName);
        +
        +	if ((ret=lh_FUNCTION_new()) == NULL)
        +		return(NULL);
        +
        +	for (f=functions; f->name != NULL; f++)
        +		(void)lh_FUNCTION_insert(ret,f);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/openssl.cnf b/vendor/openssl/openssl/apps/openssl.cnf
        new file mode 100644
        index 000000000..18760c6e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/openssl.cnf
        @@ -0,0 +1,350 @@
        +#
        +# OpenSSL example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +# This definition stops the following lines choking if HOME isn't
        +# defined.
        +HOME			= .
        +RANDFILE		= $ENV::HOME/.rnd
        +
        +# Extra OBJECT IDENTIFIER info:
        +#oid_file		= $ENV::HOME/.oid
        +oid_section		= new_oids
        +
        +# To use this configuration file with the "-extfile" option of the
        +# "openssl x509" utility, name here the section containing the
        +# X.509v3 extensions to use:
        +# extensions		= 
        +# (Alternatively, use a configuration file that has only
        +# X.509v3 extensions in its main [= default] section.)
        +
        +[ new_oids ]
        +
        +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
        +# Add a simple OID like this:
        +# testoid1=1.2.3.4
        +# Or use config file substitution like this:
        +# testoid2=${testoid1}.5.6
        +
        +# Policies used by the TSA examples.
        +tsa_policy1 = 1.2.3.4.1
        +tsa_policy2 = 1.2.3.4.5.6
        +tsa_policy3 = 1.2.3.4.5.7
        +
        +####################################################################
        +[ ca ]
        +default_ca	= CA_default		# The default ca section
        +
        +####################################################################
        +[ CA_default ]
        +
        +dir		= ./demoCA		# Where everything is kept
        +certs		= $dir/certs		# Where the issued certs are kept
        +crl_dir		= $dir/crl		# Where the issued crl are kept
        +database	= $dir/index.txt	# database index file.
        +#unique_subject	= no			# Set to 'no' to allow creation of
        +					# several ctificates with same subject.
        +new_certs_dir	= $dir/newcerts		# default place for new certs.
        +
        +certificate	= $dir/cacert.pem 	# The CA certificate
        +serial		= $dir/serial 		# The current serial number
        +crlnumber	= $dir/crlnumber	# the current crl number
        +					# must be commented out to leave a V1 CRL
        +crl		= $dir/crl.pem 		# The current CRL
        +private_key	= $dir/private/cakey.pem# The private key
        +RANDFILE	= $dir/private/.rand	# private random number file
        +
        +x509_extensions	= usr_cert		# The extentions to add to the cert
        +
        +# Comment out the following two lines for the "traditional"
        +# (and highly broken) format.
        +name_opt 	= ca_default		# Subject Name options
        +cert_opt 	= ca_default		# Certificate field options
        +
        +# Extension copying option: use with caution.
        +# copy_extensions = copy
        +
        +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
        +# so this is commented out by default to leave a V1 CRL.
        +# crlnumber must also be commented out to leave a V1 CRL.
        +# crl_extensions	= crl_ext
        +
        +default_days	= 365			# how long to certify for
        +default_crl_days= 30			# how long before next CRL
        +default_md	= default		# use public key default MD
        +preserve	= no			# keep passed DN ordering
        +
        +# A few difference way of specifying how similar the request should look
        +# For type CA, the listed attributes must be the same, and the optional
        +# and supplied fields are just that :-)
        +policy		= policy_match
        +
        +# For the CA policy
        +[ policy_match ]
        +countryName		= match
        +stateOrProvinceName	= match
        +organizationName	= match
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +# For the 'anything' policy
        +# At this point in time, you must list all acceptable 'object'
        +# types.
        +[ policy_anything ]
        +countryName		= optional
        +stateOrProvinceName	= optional
        +localityName		= optional
        +organizationName	= optional
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +####################################################################
        +[ req ]
        +default_bits		= 1024
        +default_keyfile 	= privkey.pem
        +distinguished_name	= req_distinguished_name
        +attributes		= req_attributes
        +x509_extensions	= v3_ca	# The extentions to add to the self signed cert
        +
        +# Passwords for private keys if not present they will be prompted for
        +# input_password = secret
        +# output_password = secret
        +
        +# This sets a mask for permitted string types. There are several options. 
        +# default: PrintableString, T61String, BMPString.
        +# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004)
        +# utf8only: only UTF8Strings (PKIX recommendation after 2004).
        +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
        +# MASK:XXXX a literal mask value.
        +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
        +string_mask = utf8only
        +
        +# req_extensions = v3_req # The extensions to add to a certificate request
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_min			= 2
        +countryName_max			= 2
        +
        +stateOrProvinceName		= State or Province Name (full name)
        +stateOrProvinceName_default	= Some-State
        +
        +localityName			= Locality Name (eg, city)
        +
        +0.organizationName		= Organization Name (eg, company)
        +0.organizationName_default	= Internet Widgits Pty Ltd
        +
        +# we can do this but it is not needed normally :-)
        +#1.organizationName		= Second Organization Name (eg, company)
        +#1.organizationName_default	= World Wide Web Pty Ltd
        +
        +organizationalUnitName		= Organizational Unit Name (eg, section)
        +#organizationalUnitName_default	=
        +
        +commonName			= Common Name (e.g. server FQDN or YOUR name)
        +commonName_max			= 64
        +
        +emailAddress			= Email Address
        +emailAddress_max		= 64
        +
        +# SET-ex3			= SET extension number 3
        +
        +[ req_attributes ]
        +challengePassword		= A challenge password
        +challengePassword_min		= 4
        +challengePassword_max		= 20
        +
        +unstructuredName		= An optional company name
        +
        +[ usr_cert ]
        +
        +# These extensions are added when 'ca' signs a request.
        +
        +# This goes against PKIX guidelines but some CAs do it and some software
        +# requires this to avoid interpreting an end user certificate as a CA.
        +
        +basicConstraints=CA:FALSE
        +
        +# Here are some examples of the usage of nsCertType. If it is omitted
        +# the certificate can be used for anything *except* object signing.
        +
        +# This is OK for an SSL server.
        +# nsCertType			= server
        +
        +# For an object signing certificate this would be used.
        +# nsCertType = objsign
        +
        +# For normal client use this is typical
        +# nsCertType = client, email
        +
        +# and for everything including object signing:
        +# nsCertType = client, email, objsign
        +
        +# This is typical in keyUsage for a client certificate.
        +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +
        +# This will be displayed in Netscape's comment listbox.
        +nsComment			= "OpenSSL Generated Certificate"
        +
        +# PKIX recommendations harmless if included in all certificates.
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer
        +
        +# This stuff is for subjectAltName and issuerAltname.
        +# Import the email address.
        +# subjectAltName=email:copy
        +# An alternative to produce certificates that aren't
        +# deprecated according to PKIX.
        +# subjectAltName=email:move
        +
        +# Copy subject details
        +# issuerAltName=issuer:copy
        +
        +#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
        +#nsBaseUrl
        +#nsRevocationUrl
        +#nsRenewalUrl
        +#nsCaPolicyUrl
        +#nsSslServerName
        +
        +# This is required for TSA certificates.
        +# extendedKeyUsage = critical,timeStamping
        +
        +[ v3_req ]
        +
        +# Extensions to add to a certificate request
        +
        +basicConstraints = CA:FALSE
        +keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +
        +[ v3_ca ]
        +
        +
        +# Extensions for a typical CA
        +
        +
        +# PKIX recommendation.
        +
        +subjectKeyIdentifier=hash
        +
        +authorityKeyIdentifier=keyid:always,issuer
        +
        +# This is what PKIX recommends but some broken software chokes on critical
        +# extensions.
        +#basicConstraints = critical,CA:true
        +# So we do this instead.
        +basicConstraints = CA:true
        +
        +# Key usage: this is typical for a CA certificate. However since it will
        +# prevent it being used as an test self-signed certificate it is best
        +# left out by default.
        +# keyUsage = cRLSign, keyCertSign
        +
        +# Some might want this also
        +# nsCertType = sslCA, emailCA
        +
        +# Include email address in subject alt name: another PKIX recommendation
        +# subjectAltName=email:copy
        +# Copy issuer details
        +# issuerAltName=issuer:copy
        +
        +# DER hex encoding of an extension: beware experts only!
        +# obj=DER:02:03
        +# Where 'obj' is a standard or added object
        +# You can even override a supported extension:
        +# basicConstraints= critical, DER:30:03:01:01:FF
        +
        +[ crl_ext ]
        +
        +# CRL extensions.
        +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
        +
        +# issuerAltName=issuer:copy
        +authorityKeyIdentifier=keyid:always
        +
        +[ proxy_cert_ext ]
        +# These extensions should be added when creating a proxy certificate
        +
        +# This goes against PKIX guidelines but some CAs do it and some software
        +# requires this to avoid interpreting an end user certificate as a CA.
        +
        +basicConstraints=CA:FALSE
        +
        +# Here are some examples of the usage of nsCertType. If it is omitted
        +# the certificate can be used for anything *except* object signing.
        +
        +# This is OK for an SSL server.
        +# nsCertType			= server
        +
        +# For an object signing certificate this would be used.
        +# nsCertType = objsign
        +
        +# For normal client use this is typical
        +# nsCertType = client, email
        +
        +# and for everything including object signing:
        +# nsCertType = client, email, objsign
        +
        +# This is typical in keyUsage for a client certificate.
        +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +
        +# This will be displayed in Netscape's comment listbox.
        +nsComment			= "OpenSSL Generated Certificate"
        +
        +# PKIX recommendations harmless if included in all certificates.
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer
        +
        +# This stuff is for subjectAltName and issuerAltname.
        +# Import the email address.
        +# subjectAltName=email:copy
        +# An alternative to produce certificates that aren't
        +# deprecated according to PKIX.
        +# subjectAltName=email:move
        +
        +# Copy subject details
        +# issuerAltName=issuer:copy
        +
        +#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
        +#nsBaseUrl
        +#nsRevocationUrl
        +#nsRenewalUrl
        +#nsCaPolicyUrl
        +#nsSslServerName
        +
        +# This really needs to be in place for it to be a proxy certificate.
        +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
        +
        +####################################################################
        +[ tsa ]
        +
        +default_tsa = tsa_config1	# the default TSA section
        +
        +[ tsa_config1 ]
        +
        +# These are used by the TSA reply generation only.
        +dir		= ./demoCA		# TSA root directory
        +serial		= $dir/tsaserial	# The current serial number (mandatory)
        +crypto_device	= builtin		# OpenSSL engine to use for signing
        +signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate
        +					# (optional)
        +certs		= $dir/cacert.pem	# Certificate chain to include in reply
        +					# (optional)
        +signer_key	= $dir/private/tsakey.pem # The TSA private key (optional)
        +
        +default_policy	= tsa_policy1		# Policy if request did not specify it
        +					# (optional)
        +other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
        +digests		= md5, sha1		# Acceptable message digests (mandatory)
        +accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
        +clock_precision_digits  = 0	# number of digits after dot. (optional)
        +ordering		= yes	# Is ordering defined for timestamps?
        +				# (optional, default: no)
        +tsa_name		= yes	# Must the TSA name be included in the reply?
        +				# (optional, default: no)
        +ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
        +				# (optional, default: no)
        diff --git a/vendor/openssl/openssl/apps/passwd.c b/vendor/openssl/openssl/apps/passwd.c
        new file mode 100644
        index 000000000..9ca25dd1d
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/passwd.c
        @@ -0,0 +1,512 @@
        +/* apps/passwd.c */
        +
        +#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
        +# define NO_MD5CRYPT_1
        +#endif
        +
        +#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
        +
        +#include <assert.h>
        +#include <string.h>
        +
        +#include "apps.h"
        +
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_DES
        +# include <openssl/des.h>
        +#endif
        +#ifndef NO_MD5CRYPT_1
        +# include <openssl/md5.h>
        +#endif
        +
        +
        +#undef PROG
        +#define PROG passwd_main
        +
        +
        +static unsigned const char cov_2char[64]={
        +	/* from crypto/des/fcrypt.c */
        +	0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
        +	0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
        +	0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
        +	0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
        +	0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
        +	0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
        +	0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
        +	0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
        +};
        +
        +static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
        +	char *passwd, BIO *out, int quiet, int table, int reverse,
        +	size_t pw_maxlen, int usecrypt, int use1, int useapr1);
        +
        +/* -crypt        - standard Unix password algorithm (default)
        + * -1            - MD5-based password algorithm
        + * -apr1         - MD5-based password algorithm, Apache variant
        + * -salt string  - salt
        + * -in file      - read passwords from file
        + * -stdin        - read passwords from stdin
        + * -noverify     - never verify when reading password from terminal
        + * -quiet        - no warnings
        + * -table        - format output as table
        + * -reverse      - switch table columns
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int ret = 1;
        +	char *infile = NULL;
        +	int in_stdin = 0;
        +	int in_noverify = 0;
        +	char *salt = NULL, *passwd = NULL, **passwds = NULL;
        +	char *salt_malloc = NULL, *passwd_malloc = NULL;
        +	size_t passwd_malloc_size = 0;
        +	int pw_source_defined = 0;
        +	BIO *in = NULL, *out = NULL;
        +	int i, badopt, opt_done;
        +	int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
        +	int usecrypt = 0, use1 = 0, useapr1 = 0;
        +	size_t pw_maxlen = 0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto err;
        +	out = BIO_new(BIO_s_file());
        +	if (out == NULL)
        +		goto err;
        +	BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
        +#ifdef OPENSSL_SYS_VMS
        +	{
        +	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	out = BIO_push(tmpbio, out);
        +	}
        +#endif
        +
        +	badopt = 0, opt_done = 0;
        +	i = 0;
        +	while (!badopt && !opt_done && argv[++i] != NULL)
        +		{
        +		if (strcmp(argv[i], "-crypt") == 0)
        +			usecrypt = 1;
        +		else if (strcmp(argv[i], "-1") == 0)
        +			use1 = 1;
        +		else if (strcmp(argv[i], "-apr1") == 0)
        +			useapr1 = 1;
        +		else if (strcmp(argv[i], "-salt") == 0)
        +			{
        +			if ((argv[i+1] != NULL) && (salt == NULL))
        +				{
        +				passed_salt = 1;
        +				salt = argv[++i];
        +				}
        +			else
        +				badopt = 1;
        +			}
        +		else if (strcmp(argv[i], "-in") == 0)
        +			{
        +			if ((argv[i+1] != NULL) && !pw_source_defined)
        +				{
        +				pw_source_defined = 1;
        +				infile = argv[++i];
        +				}
        +			else
        +				badopt = 1;
        +			}
        +		else if (strcmp(argv[i], "-stdin") == 0)
        +			{
        +			if (!pw_source_defined)
        +				{
        +				pw_source_defined = 1;
        +				in_stdin = 1;
        +				}
        +			else
        +				badopt = 1;
        +			}
        +		else if (strcmp(argv[i], "-noverify") == 0)
        +			in_noverify = 1;
        +		else if (strcmp(argv[i], "-quiet") == 0)
        +			quiet = 1;
        +		else if (strcmp(argv[i], "-table") == 0)
        +			table = 1;
        +		else if (strcmp(argv[i], "-reverse") == 0)
        +			reverse = 1;
        +		else if (argv[i][0] == '-')
        +			badopt = 1;
        +		else if (!pw_source_defined)
        +			/* non-option arguments, use as passwords */
        +			{
        +			pw_source_defined = 1;
        +			passwds = &argv[i];
        +			opt_done = 1;
        +			}
        +		else
        +			badopt = 1;
        +		}
        +
        +	if (!usecrypt && !use1 && !useapr1) /* use default */
        +		usecrypt = 1;
        +	if (usecrypt + use1 + useapr1 > 1) /* conflict */
        +		badopt = 1;
        +
        +	/* reject unsupported algorithms */
        +#ifdef OPENSSL_NO_DES
        +	if (usecrypt) badopt = 1;
        +#endif
        +#ifdef NO_MD5CRYPT_1
        +	if (use1 || useapr1) badopt = 1;
        +#endif
        +
        +	if (badopt) 
        +		{
        +		BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n");
        +		BIO_printf(bio_err, "where options are\n");
        +#ifndef OPENSSL_NO_DES
        +		BIO_printf(bio_err, "-crypt             standard Unix password algorithm (default)\n");
        +#endif
        +#ifndef NO_MD5CRYPT_1
        +		BIO_printf(bio_err, "-1                 MD5-based password algorithm\n");
        +		BIO_printf(bio_err, "-apr1              MD5-based password algorithm, Apache variant\n");
        +#endif
        +		BIO_printf(bio_err, "-salt string       use provided salt\n");
        +		BIO_printf(bio_err, "-in file           read passwords from file\n");
        +		BIO_printf(bio_err, "-stdin             read passwords from stdin\n");
        +		BIO_printf(bio_err, "-noverify          never verify when reading password from terminal\n");
        +		BIO_printf(bio_err, "-quiet             no warnings\n");
        +		BIO_printf(bio_err, "-table             format output as table\n");
        +		BIO_printf(bio_err, "-reverse           switch table columns\n");
        +		
        +		goto err;
        +		}
        +
        +	if ((infile != NULL) || in_stdin)
        +		{
        +		in = BIO_new(BIO_s_file());
        +		if (in == NULL)
        +			goto err;
        +		if (infile != NULL)
        +			{
        +			assert(in_stdin == 0);
        +			if (BIO_read_filename(in, infile) <= 0)
        +				goto err;
        +			}
        +		else
        +			{
        +			assert(in_stdin);
        +			BIO_set_fp(in, stdin, BIO_NOCLOSE);
        +			}
        +		}
        +	
        +	if (usecrypt)
        +		pw_maxlen = 8;
        +	else if (use1 || useapr1)
        +		pw_maxlen = 256; /* arbitrary limit, should be enough for most passwords */
        +
        +	if (passwds == NULL)
        +		{
        +		/* no passwords on the command line */
        +
        +		passwd_malloc_size = pw_maxlen + 2;
        +		/* longer than necessary so that we can warn about truncation */
        +		passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size);
        +		if (passwd_malloc == NULL)
        +			goto err;
        +		}
        +
        +	if ((in == NULL) && (passwds == NULL))
        +		{
        +		/* build a null-terminated list */
        +		static char *passwds_static[2] = {NULL, NULL};
        +		
        +		passwds = passwds_static;
        +		if (in == NULL)
        +			if (EVP_read_pw_string(passwd_malloc, passwd_malloc_size, "Password: ", !(passed_salt || in_noverify)) != 0)
        +				goto err;
        +		passwds[0] = passwd_malloc;
        +		}
        +
        +	if (in == NULL)
        +		{
        +		assert(passwds != NULL);
        +		assert(*passwds != NULL);
        +		
        +		do /* loop over list of passwords */
        +			{
        +			passwd = *passwds++;
        +			if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
        +				quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
        +				goto err;
        +			}
        +		while (*passwds != NULL);
        +		}
        +	else
        +		/* in != NULL */
        +		{
        +		int done;
        +
        +		assert (passwd != NULL);
        +		do
        +			{
        +			int r = BIO_gets(in, passwd, pw_maxlen + 1);
        +			if (r > 0)
        +				{
        +				char *c = (strchr(passwd, '\n')) ;
        +				if (c != NULL)
        +					*c = 0; /* truncate at newline */
        +				else
        +					{
        +					/* ignore rest of line */
        +					char trash[BUFSIZ];
        +					do
        +						r = BIO_gets(in, trash, sizeof trash);
        +					while ((r > 0) && (!strchr(trash, '\n')));
        +					}
        +				
        +				if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
        +					quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
        +					goto err;
        +				}
        +			done = (r <= 0);
        +			}
        +		while (!done);
        +		}
        +	ret = 0;
        +
        +err:
        +	ERR_print_errors(bio_err);
        +	if (salt_malloc)
        +		OPENSSL_free(salt_malloc);
        +	if (passwd_malloc)
        +		OPENSSL_free(passwd_malloc);
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free_all(out);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +
        +#ifndef NO_MD5CRYPT_1
        +/* MD5-based password algorithm (should probably be available as a library
        + * function; then the static buffer would not be acceptable).
        + * For magic string "1", this should be compatible to the MD5-based BSD
        + * password algorithm.
        + * For 'magic' string "apr1", this is compatible to the MD5-based Apache
        + * password algorithm.
        + * (Apparently, the Apache password algorithm is identical except that the
        + * 'magic' string was changed -- the laziest application of the NIH principle
        + * I've ever encountered.)
        + */
        +static char *md5crypt(const char *passwd, const char *magic, const char *salt)
        +	{
        +	static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5hash..........\0" */
        +	unsigned char buf[MD5_DIGEST_LENGTH];
        +	char *salt_out;
        +	int n;
        +	unsigned int i;
        +	EVP_MD_CTX md,md2;
        +	size_t passwd_len, salt_len;
        +
        +	passwd_len = strlen(passwd);
        +	out_buf[0] = '$';
        +	out_buf[1] = 0;
        +	assert(strlen(magic) <= 4); /* "1" or "apr1" */
        +	strncat(out_buf, magic, 4);
        +	strncat(out_buf, "$", 1);
        +	strncat(out_buf, salt, 8);
        +	assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
        +	salt_out = out_buf + 2 + strlen(magic);
        +	salt_len = strlen(salt_out);
        +	assert(salt_len <= 8);
        +	
        +	EVP_MD_CTX_init(&md);
        +	EVP_DigestInit_ex(&md,EVP_md5(), NULL);
        +	EVP_DigestUpdate(&md, passwd, passwd_len);
        +	EVP_DigestUpdate(&md, "$", 1);
        +	EVP_DigestUpdate(&md, magic, strlen(magic));
        +	EVP_DigestUpdate(&md, "$", 1);
        +	EVP_DigestUpdate(&md, salt_out, salt_len);
        +	
        +	EVP_MD_CTX_init(&md2);
        +	EVP_DigestInit_ex(&md2,EVP_md5(), NULL);
        +	EVP_DigestUpdate(&md2, passwd, passwd_len);
        +	EVP_DigestUpdate(&md2, salt_out, salt_len);
        +	EVP_DigestUpdate(&md2, passwd, passwd_len);
        +	EVP_DigestFinal_ex(&md2, buf, NULL);
        +
        +	for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
        +		EVP_DigestUpdate(&md, buf, sizeof buf);
        +	EVP_DigestUpdate(&md, buf, i);
        +	
        +	n = passwd_len;
        +	while (n)
        +		{
        +		EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1);
        +		n >>= 1;
        +		}
        +	EVP_DigestFinal_ex(&md, buf, NULL);
        +
        +	for (i = 0; i < 1000; i++)
        +		{
        +		EVP_DigestInit_ex(&md2,EVP_md5(), NULL);
        +		EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *) passwd : buf,
        +		                       (i & 1) ? passwd_len : sizeof buf);
        +		if (i % 3)
        +			EVP_DigestUpdate(&md2, salt_out, salt_len);
        +		if (i % 7)
        +			EVP_DigestUpdate(&md2, passwd, passwd_len);
        +		EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *) passwd,
        +		                       (i & 1) ? sizeof buf : passwd_len);
        +		EVP_DigestFinal_ex(&md2, buf, NULL);
        +		}
        +	EVP_MD_CTX_cleanup(&md2);
        +	
        +	 {
        +		/* transform buf into output string */
        +	
        +		unsigned char buf_perm[sizeof buf];
        +		int dest, source;
        +		char *output;
        +
        +		/* silly output permutation */
        +		for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17)
        +			buf_perm[dest] = buf[source];
        +		buf_perm[14] = buf[5];
        +		buf_perm[15] = buf[11];
        +#ifndef PEDANTIC /* Unfortunately, this generates a "no effect" warning */
        +		assert(16 == sizeof buf_perm);
        +#endif
        +		
        +		output = salt_out + salt_len;
        +		assert(output == out_buf + strlen(out_buf));
        +		
        +		*output++ = '$';
        +
        +		for (i = 0; i < 15; i += 3)
        +			{
        +			*output++ = cov_2char[buf_perm[i+2] & 0x3f];
        +			*output++ = cov_2char[((buf_perm[i+1] & 0xf) << 2) |
        +				                  (buf_perm[i+2] >> 6)];
        +			*output++ = cov_2char[((buf_perm[i] & 3) << 4) |
        +				                  (buf_perm[i+1] >> 4)];
        +			*output++ = cov_2char[buf_perm[i] >> 2];
        +			}
        +		assert(i == 15);
        +		*output++ = cov_2char[buf_perm[i] & 0x3f];
        +		*output++ = cov_2char[buf_perm[i] >> 6];
        +		*output = 0;
        +		assert(strlen(out_buf) < sizeof(out_buf));
        +	 }
        +	EVP_MD_CTX_cleanup(&md);
        +
        +	return out_buf;
        +	}
        +#endif
        +
        +
        +static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
        +	char *passwd, BIO *out,	int quiet, int table, int reverse,
        +	size_t pw_maxlen, int usecrypt, int use1, int useapr1)
        +	{
        +	char *hash = NULL;
        +
        +	assert(salt_p != NULL);
        +	assert(salt_malloc_p != NULL);
        +
        +	/* first make sure we have a salt */
        +	if (!passed_salt)
        +		{
        +#ifndef OPENSSL_NO_DES
        +		if (usecrypt)
        +			{
        +			if (*salt_malloc_p == NULL)
        +				{
        +				*salt_p = *salt_malloc_p = OPENSSL_malloc(3);
        +				if (*salt_malloc_p == NULL)
        +					goto err;
        +				}
        +			if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0)
        +				goto err;
        +			(*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
        +			(*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
        +			(*salt_p)[2] = 0;
        +#ifdef CHARSET_EBCDIC
        +			ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert
        +			                                    * back to ASCII */
        +#endif
        +			}
        +#endif /* !OPENSSL_NO_DES */
        +
        +#ifndef NO_MD5CRYPT_1
        +		if (use1 || useapr1)
        +			{
        +			int i;
        +			
        +			if (*salt_malloc_p == NULL)
        +				{
        +				*salt_p = *salt_malloc_p = OPENSSL_malloc(9);
        +				if (*salt_malloc_p == NULL)
        +					goto err;
        +				}
        +			if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0)
        +				goto err;
        +			
        +			for (i = 0; i < 8; i++)
        +				(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
        +			(*salt_p)[8] = 0;
        +			}
        +#endif /* !NO_MD5CRYPT_1 */
        +		}
        +	
        +	assert(*salt_p != NULL);
        +	
        +	/* truncate password if necessary */
        +	if ((strlen(passwd) > pw_maxlen))
        +		{
        +		if (!quiet)
        +			/* XXX: really we should know how to print a size_t, not cast it */
        +			BIO_printf(bio_err, "Warning: truncating password to %u characters\n", (unsigned)pw_maxlen);
        +		passwd[pw_maxlen] = 0;
        +		}
        +	assert(strlen(passwd) <= pw_maxlen);
        +	
        +	/* now compute password hash */
        +#ifndef OPENSSL_NO_DES
        +	if (usecrypt)
        +		hash = DES_crypt(passwd, *salt_p);
        +#endif
        +#ifndef NO_MD5CRYPT_1
        +	if (use1 || useapr1)
        +		hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
        +#endif
        +	assert(hash != NULL);
        +
        +	if (table && !reverse)
        +		BIO_printf(out, "%s\t%s\n", passwd, hash);
        +	else if (table && reverse)
        +		BIO_printf(out, "%s\t%s\n", hash, passwd);
        +	else
        +		BIO_printf(out, "%s\n", hash);
        +	return 1;
        +	
        +err:
        +	return 0;
        +	}
        +#else
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	fputs("Program not available.\n", stderr)
        +	OPENSSL_EXIT(1);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/apps/pca-cert.srl b/vendor/openssl/openssl/apps/pca-cert.srl
        new file mode 100644
        index 000000000..2c7456e3e
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pca-cert.srl
        @@ -0,0 +1 @@
        +07
        diff --git a/vendor/openssl/openssl/apps/pca-key.pem b/vendor/openssl/openssl/apps/pca-key.pem
        new file mode 100644
        index 000000000..20029ab77
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pca-key.pem
        @@ -0,0 +1,15 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
        +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
        +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
        +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
        +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
        +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
        +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
        +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
        +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
        +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
        +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
        +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
        +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/pca-req.pem b/vendor/openssl/openssl/apps/pca-req.pem
        new file mode 100644
        index 000000000..33f155337
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pca-req.pem
        @@ -0,0 +1,11 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBmjCCAQMCAQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
        +GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAo
        +MTAyNCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfj
        +Irkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUX
        +MRsp22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3
        +vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAEzz
        +IG8NnfpnPTQSCN5zJhOfy6p9AcDyQzuJirYv1HR/qoYWalPh/U2uiK0lAim7qMcv
        +wOlK3I7A8B7/4dLqvIqgtUj9b1WT8zIrnwdvJI4osLI2BY+c1pVlp174DHLMol1L
        +Cl1e3N5BTm7lCitTYjuUhsw6hiA8IcdNKDo6sktV
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/apps/pkcs12.c b/vendor/openssl/openssl/apps/pkcs12.c
        new file mode 100644
        index 000000000..b54c6f84a
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pkcs12.c
        @@ -0,0 +1,977 @@
        +/* pkcs12.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <openssl/opensslconf.h>
        +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/pkcs12.h>
        +
        +#define PROG pkcs12_main
        +
        +const EVP_CIPHER *enc;
        +
        +
        +#define NOKEYS		0x1
        +#define NOCERTS 	0x2
        +#define INFO		0x4
        +#define CLCERTS		0x8
        +#define CACERTS		0x10
        +
        +int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
        +int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
        +int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
        +			  int passlen, int options, char *pempass);
        +int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
        +int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
        +void hex_prin(BIO *out, unsigned char *buf, int len);
        +int alg_print(BIO *x, X509_ALGOR *alg);
        +int cert_load(BIO *in, STACK_OF(X509) *sk);
        +static int set_pbe(BIO *err, int *ppbe, const char *str);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +{
        +    ENGINE *e = NULL;
        +    char *infile=NULL, *outfile=NULL, *keyname = NULL;	
        +    char *certfile=NULL;
        +    BIO *in=NULL, *out = NULL;
        +    char **args;
        +    char *name = NULL;
        +    char *csp_name = NULL;
        +    int add_lmk = 0;
        +    PKCS12 *p12 = NULL;
        +    char pass[50], macpass[50];
        +    int export_cert = 0;
        +    int options = 0;
        +    int chain = 0;
        +    int badarg = 0;
        +    int iter = PKCS12_DEFAULT_ITER;
        +    int maciter = PKCS12_DEFAULT_ITER;
        +    int twopass = 0;
        +    int keytype = 0;
        +    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
        +    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
        +    int ret = 1;
        +    int macver = 1;
        +    int noprompt = 0;
        +    STACK_OF(OPENSSL_STRING) *canames = NULL;
        +    char *cpass = NULL, *mpass = NULL;
        +    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
        +    char *passin = NULL, *passout = NULL;
        +    char *inrand = NULL;
        +    char *macalg = NULL;
        +    char *CApath = NULL, *CAfile = NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +    char *engine=NULL;
        +#endif
        +
        +    apps_startup();
        +
        +    enc = EVP_des_ede3_cbc();
        +    if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +    args = argv + 1;
        +
        +
        +    while (*args) {
        +	if (*args[0] == '-') {
        +		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
        +		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
        +		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
        +		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
        +		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
        +		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
        +		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
        +		else if (!strcmp (*args, "-info")) options |= INFO;
        +		else if (!strcmp (*args, "-chain")) chain = 1;
        +		else if (!strcmp (*args, "-twopass")) twopass = 1;
        +		else if (!strcmp (*args, "-nomacver")) macver = 0;
        +		else if (!strcmp (*args, "-descert"))
        +    			cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
        +		else if (!strcmp (*args, "-export")) export_cert = 1;
        +		else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
        +		else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
        +#ifndef OPENSSL_NO_IDEA
        +		else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc();
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
        +		else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
        +		else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc();
        +		else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc();
        +		else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc();
        +#endif
        +		else if (!strcmp (*args, "-noiter")) iter = 1;
        +		else if (!strcmp (*args, "-maciter"))
        +					 maciter = PKCS12_DEFAULT_ITER;
        +		else if (!strcmp (*args, "-nomaciter"))
        +					 maciter = 1;
        +		else if (!strcmp (*args, "-nomac"))
        +					 maciter = -1;
        +		else if (!strcmp (*args, "-macalg"))
        +		    if (args[1]) {
        +			args++;	
        +			macalg = *args;
        +		    } else badarg = 1;
        +		else if (!strcmp (*args, "-nodes")) enc=NULL;
        +		else if (!strcmp (*args, "-certpbe")) {
        +			if (!set_pbe(bio_err, &cert_pbe, *++args))
        +				badarg = 1;
        +		} else if (!strcmp (*args, "-keypbe")) {
        +			if (!set_pbe(bio_err, &key_pbe, *++args))
        +				badarg = 1;
        +		} else if (!strcmp (*args, "-rand")) {
        +		    if (args[1]) {
        +			args++;	
        +			inrand = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-inkey")) {
        +		    if (args[1]) {
        +			args++;	
        +			keyname = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-certfile")) {
        +		    if (args[1]) {
        +			args++;	
        +			certfile = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-name")) {
        +		    if (args[1]) {
        +			args++;	
        +			name = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-LMK"))
        +			add_lmk = 1;
        +		else if (!strcmp (*args, "-CSP")) {
        +		    if (args[1]) {
        +			args++;	
        +			csp_name = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-caname")) {
        +		    if (args[1]) {
        +			args++;	
        +			if (!canames) canames = sk_OPENSSL_STRING_new_null();
        +			sk_OPENSSL_STRING_push(canames, *args);
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-in")) {
        +		    if (args[1]) {
        +			args++;	
        +			infile = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-out")) {
        +		    if (args[1]) {
        +			args++;	
        +			outfile = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp(*args,"-passin")) {
        +		    if (args[1]) {
        +			args++;	
        +			passargin = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp(*args,"-passout")) {
        +		    if (args[1]) {
        +			args++;	
        +			passargout = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp (*args, "-password")) {
        +		    if (args[1]) {
        +			args++;	
        +			passarg = *args;
        +		    	noprompt = 1;
        +		    } else badarg = 1;
        +		} else if (!strcmp(*args,"-CApath")) {
        +		    if (args[1]) {
        +			args++;	
        +			CApath = *args;
        +		    } else badarg = 1;
        +		} else if (!strcmp(*args,"-CAfile")) {
        +		    if (args[1]) {
        +			args++;	
        +			CAfile = *args;
        +		    } else badarg = 1;
        +#ifndef OPENSSL_NO_ENGINE
        +		} else if (!strcmp(*args,"-engine")) {
        +		    if (args[1]) {
        +			args++;	
        +			engine = *args;
        +		    } else badarg = 1;
        +#endif
        +		} else badarg = 1;
        +
        +	} else badarg = 1;
        +	args++;
        +    }
        +
        +    if (badarg) {
        +	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
        +	BIO_printf (bio_err, "where options are\n");
        +	BIO_printf (bio_err, "-export       output PKCS12 file\n");
        +	BIO_printf (bio_err, "-chain        add certificate chain\n");
        +	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
        +	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
        +	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
        +	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
        +	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
        +	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
        +	BIO_printf (bio_err, "-in  infile   input filename\n");
        +	BIO_printf (bio_err, "-out outfile  output filename\n");
        +	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
        +	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
        +	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
        +	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
        +	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
        +	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
        +	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
        +	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
        +	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
        +#ifndef OPENSSL_NO_IDEA
        +	BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	BIO_printf (bio_err, "-seed         encrypt private keys with seed\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
        +	BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
        +	BIO_printf (bio_err, "              encrypt PEM output with cbc camellia\n");
        +#endif
        +	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
        +	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
        +	BIO_printf (bio_err, "-nomaciter    don't use MAC iteration\n");
        +	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
        +	BIO_printf (bio_err, "-nomac        don't generate MAC\n");
        +	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
        +	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
        +	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
        +	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
        +	BIO_printf (bio_err, "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
        +	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
        +	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
        +	BIO_printf (bio_err, "-password p   set import/export password source\n");
        +	BIO_printf (bio_err, "-passin p     input file pass phrase source\n");
        +	BIO_printf (bio_err, "-passout p    output file pass phrase source\n");
        +#ifndef OPENSSL_NO_ENGINE
        +	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
        +#endif
        +	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
        +	BIO_printf(bio_err,  "              the random number generator\n");
        +	BIO_printf(bio_err,  "-CSP name     Microsoft CSP name\n");
        +	BIO_printf(bio_err,  "-LMK          Add local machine keyset attribute to private key\n");
        +    	goto end;
        +    }
        +
        +#ifndef OPENSSL_NO_ENGINE
        +    e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +    if(passarg) {
        +	if(export_cert) passargout = passarg;
        +	else passargin = passarg;
        +    }
        +
        +    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
        +	BIO_printf(bio_err, "Error getting passwords\n");
        +	goto end;
        +    }
        +
        +    if(!cpass) {
        +    	if(export_cert) cpass = passout;
        +    	else cpass = passin;
        +    }
        +
        +    if(cpass) {
        +	mpass = cpass;
        +	noprompt = 1;
        +    } else {
        +	cpass = pass;
        +	mpass = macpass;
        +    }
        +
        +    if(export_cert || inrand) {
        +    	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        +        if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +    }
        +    ERR_load_crypto_strings();
        +
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_push_info("read files");
        +#endif
        +
        +    if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
        +    else in = BIO_new_file(infile, "rb");
        +    if (!in) {
        +	    BIO_printf(bio_err, "Error opening input file %s\n",
        +						infile ? infile : "<stdin>");
        +	    perror (infile);
        +	    goto end;
        +   }
        +
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_pop_info();
        +    CRYPTO_push_info("write files");
        +#endif
        +
        +    if (!outfile) {
        +	out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +	{
        +	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	    out = BIO_push(tmpbio, out);
        +	}
        +#endif
        +    } else out = BIO_new_file(outfile, "wb");
        +    if (!out) {
        +	BIO_printf(bio_err, "Error opening output file %s\n",
        +						outfile ? outfile : "<stdout>");
        +	perror (outfile);
        +	goto end;
        +    }
        +    if (twopass) {
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_push_info("read MAC password");
        +#endif
        +	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
        +	{
        +    	    BIO_printf (bio_err, "Can't read Password\n");
        +    	    goto end;
        +       	}
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_pop_info();
        +#endif
        +    }
        +
        +    if (export_cert) {
        +	EVP_PKEY *key = NULL;
        +	X509 *ucert = NULL, *x = NULL;
        +	STACK_OF(X509) *certs=NULL;
        +	const EVP_MD *macmd = NULL;
        +	unsigned char *catmp = NULL;
        +	int i;
        +
        +	if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
        +		{	
        +		BIO_printf(bio_err, "Nothing to do!\n");
        +		goto export_end;
        +		}
        +
        +	if (options & NOCERTS)
        +		chain = 0;
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_push_info("process -export_cert");
        +	CRYPTO_push_info("reading private key");
        +#endif
        +	if (!(options & NOKEYS))
        +		{
        +		key = load_key(bio_err, keyname ? keyname : infile,
        +				FORMAT_PEM, 1, passin, e, "private key");
        +		if (!key)
        +			goto export_end;
        +		}
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("reading certs from input");
        +#endif
        +
        +	/* Load in all certs in input file */
        +	if(!(options & NOCERTS))
        +		{
        +		certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
        +							"certificates");
        +		if (!certs)
        +			goto export_end;
        +
        +		if (key)
        +			{
        +			/* Look for matching private key */
        +			for(i = 0; i < sk_X509_num(certs); i++)
        +				{
        +				x = sk_X509_value(certs, i);
        +				if(X509_check_private_key(x, key))
        +					{
        +					ucert = x;
        +					/* Zero keyid and alias */
        +					X509_keyid_set1(ucert, NULL, 0);
        +					X509_alias_set1(ucert, NULL, 0);
        +					/* Remove from list */
        +					(void)sk_X509_delete(certs, i);
        +					break;
        +					}
        +				}
        +			if (!ucert)
        +				{
        +				BIO_printf(bio_err, "No certificate matches private key\n");
        +				goto export_end;
        +				}
        +			}
        +
        +		}
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("reading certs from input 2");
        +#endif
        +
        +	/* Add any more certificates asked for */
        +	if(certfile)
        +		{
        +		STACK_OF(X509) *morecerts=NULL;
        +		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
        +					    NULL, e,
        +					    "certificates from certfile")))
        +			goto export_end;
        +		while(sk_X509_num(morecerts) > 0)
        +			sk_X509_push(certs, sk_X509_shift(morecerts));
        +		sk_X509_free(morecerts);
        + 		}
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("reading certs from certfile");
        +#endif
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("building chain");
        +#endif
        +
        +	/* If chaining get chain from user cert */
        +	if (chain) {
        +        	int vret;
        +		STACK_OF(X509) *chain2;
        +		X509_STORE *store = X509_STORE_new();
        +		if (!store)
        +			{
        +			BIO_printf (bio_err, "Memory allocation error\n");
        +			goto export_end;
        +			}
        +		if (!X509_STORE_load_locations(store, CAfile, CApath))
        +			X509_STORE_set_default_paths (store);
        +
        +		vret = get_cert_chain (ucert, store, &chain2);
        +		X509_STORE_free(store);
        +
        +		if (!vret) {
        +		    /* Exclude verified certificate */
        +		    for (i = 1; i < sk_X509_num (chain2) ; i++) 
        +			sk_X509_push(certs, sk_X509_value (chain2, i));
        +		    /* Free first certificate */
        +		    X509_free(sk_X509_value(chain2, 0));
        +		    sk_X509_free(chain2);
        +		} else {
        +			if (vret >= 0)
        +				BIO_printf (bio_err, "Error %s getting chain.\n",
        +					X509_verify_cert_error_string(vret));
        +			else
        +				ERR_print_errors(bio_err);
        +			goto export_end;
        +		}			
        +    	}
        +
        +	/* Add any CA names */
        +
        +	for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++)
        +		{
        +		catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
        +		X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
        +		}
        +
        +	if (csp_name && key)
        +		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
        +				MBSTRING_ASC, (unsigned char *)csp_name, -1);
        +
        +	if (add_lmk && key)
        +		EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("reading password");
        +#endif
        +
        +	if(!noprompt &&
        +		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
        +		{
        +	    	BIO_printf (bio_err, "Can't read Password\n");
        +	    	goto export_end;
        +        	}
        +	if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("creating PKCS#12 structure");
        +#endif
        +
        +	p12 = PKCS12_create(cpass, name, key, ucert, certs,
        +				key_pbe, cert_pbe, iter, -1, keytype);
        +
        +	if (!p12)
        +		{
        +	    	ERR_print_errors (bio_err);
        +		goto export_end;
        +		}
        +
        +	if (macalg)
        +		{
        +		macmd = EVP_get_digestbyname(macalg);
        +		if (!macmd)
        +			{
        +			BIO_printf(bio_err, "Unknown digest algorithm %s\n", 
        +						macalg);
        +			}
        +		}
        +
        +	if (maciter != -1)
        +		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("writing pkcs12");
        +#endif
        +
        +	i2d_PKCS12_bio(out, p12);
        +
        +	ret = 0;
        +
        +    export_end:
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +	CRYPTO_pop_info();
        +	CRYPTO_push_info("process -export_cert: freeing");
        +#endif
        +
        +	if (key) EVP_PKEY_free(key);
        +	if (certs) sk_X509_pop_free(certs, X509_free);
        +	if (ucert) X509_free(ucert);
        +
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +#endif
        +	goto end;
        +	
        +    }
        +
        +    if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
        +	ERR_print_errors(bio_err);
        +	goto end;
        +    }
        +
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_push_info("read import password");
        +#endif
        +    if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
        +	BIO_printf (bio_err, "Can't read Password\n");
        +	goto end;
        +    }
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_pop_info();
        +#endif
        +
        +    if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
        +
        +    if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
        +    if(macver) {
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_push_info("verify MAC");
        +#endif
        +	/* If we enter empty password try no password first */
        +	if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
        +		/* If mac and crypto pass the same set it to NULL too */
        +		if(!twopass) cpass = NULL;
        +	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
        +	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
        +	    ERR_print_errors (bio_err);
        +	    goto end;
        +	}
        +	BIO_printf (bio_err, "MAC verified OK\n");
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_pop_info();
        +#endif
        +    }
        +
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_push_info("output keys and certificates");
        +#endif
        +    if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
        +	BIO_printf(bio_err, "Error outputting keys and certificates\n");
        +	ERR_print_errors (bio_err);
        +	goto end;
        +    }
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_pop_info();
        +#endif
        +    ret = 0;
        + end:
        +    if (p12) PKCS12_free(p12);
        +    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
        +#ifdef CRYPTO_MDEBUG
        +    CRYPTO_remove_all_info();
        +#endif
        +    BIO_free(in);
        +    BIO_free_all(out);
        +    if (canames) sk_OPENSSL_STRING_free(canames);
        +    if(passin) OPENSSL_free(passin);
        +    if(passout) OPENSSL_free(passout);
        +    apps_shutdown();
        +    OPENSSL_EXIT(ret);
        +}
        +
        +int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
        +	     int passlen, int options, char *pempass)
        +{
        +	STACK_OF(PKCS7) *asafes = NULL;
        +	STACK_OF(PKCS12_SAFEBAG) *bags;
        +	int i, bagnid;
        +	int ret = 0;
        +	PKCS7 *p7;
        +
        +	if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
        +	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
        +		p7 = sk_PKCS7_value (asafes, i);
        +		bagnid = OBJ_obj2nid (p7->type);
        +		if (bagnid == NID_pkcs7_data) {
        +			bags = PKCS12_unpack_p7data(p7);
        +			if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
        +		} else if (bagnid == NID_pkcs7_encrypted) {
        +			if (options & INFO) {
        +				BIO_printf(bio_err, "PKCS7 Encrypted data: ");
        +				alg_print(bio_err, 
        +					p7->d.encrypted->enc_data->algorithm);
        +			}
        +			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
        +		} else continue;
        +		if (!bags) goto err;
        +	    	if (!dump_certs_pkeys_bags (out, bags, pass, passlen, 
        +						 options, pempass)) {
        +			sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
        +			goto err;
        +		}
        +		sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
        +		bags = NULL;
        +	}
        +	ret = 1;
        +
        +	err:
        +
        +	if (asafes)
        +		sk_PKCS7_pop_free (asafes, PKCS7_free);
        +	return ret;
        +}
        +
        +int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
        +			   char *pass, int passlen, int options, char *pempass)
        +{
        +	int i;
        +	for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
        +		if (!dump_certs_pkeys_bag (out,
        +					   sk_PKCS12_SAFEBAG_value (bags, i),
        +					   pass, passlen,
        +					   options, pempass))
        +		    return 0;
        +	}
        +	return 1;
        +}
        +
        +int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
        +	     int passlen, int options, char *pempass)
        +{
        +	EVP_PKEY *pkey;
        +	PKCS8_PRIV_KEY_INFO *p8;
        +	X509 *x509;
        +	
        +	switch (M_PKCS12_bag_type(bag))
        +	{
        +	case NID_keyBag:
        +		if (options & INFO) BIO_printf (bio_err, "Key bag\n");
        +		if (options & NOKEYS) return 1;
        +		print_attribs (out, bag->attrib, "Bag Attributes");
        +		p8 = bag->value.keybag;
        +		if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
        +		print_attribs (out, p8->attributes, "Key Attributes");
        +		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
        +		EVP_PKEY_free(pkey);
        +	break;
        +
        +	case NID_pkcs8ShroudedKeyBag:
        +		if (options & INFO) {
        +			BIO_printf (bio_err, "Shrouded Keybag: ");
        +			alg_print (bio_err, bag->value.shkeybag->algor);
        +		}
        +		if (options & NOKEYS) return 1;
        +		print_attribs (out, bag->attrib, "Bag Attributes");
        +		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
        +				return 0;
        +		if (!(pkey = EVP_PKCS82PKEY (p8))) {
        +			PKCS8_PRIV_KEY_INFO_free(p8);
        +			return 0;
        +		}
        +		print_attribs (out, p8->attributes, "Key Attributes");
        +		PKCS8_PRIV_KEY_INFO_free(p8);
        +		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
        +		EVP_PKEY_free(pkey);
        +	break;
        +
        +	case NID_certBag:
        +		if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
        +		if (options & NOCERTS) return 1;
        +                if (PKCS12_get_attr(bag, NID_localKeyID)) {
        +			if (options & CACERTS) return 1;
        +		} else if (options & CLCERTS) return 1;
        +		print_attribs (out, bag->attrib, "Bag Attributes");
        +		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
        +								 return 1;
        +		if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
        +		dump_cert_text (out, x509);
        +		PEM_write_bio_X509 (out, x509);
        +		X509_free(x509);
        +	break;
        +
        +	case NID_safeContentsBag:
        +		if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
        +		print_attribs (out, bag->attrib, "Bag Attributes");
        +		return dump_certs_pkeys_bags (out, bag->value.safes, pass,
        +							    passlen, options, pempass);
        +					
        +	default:
        +		BIO_printf (bio_err, "Warning unsupported bag type: ");
        +		i2a_ASN1_OBJECT (bio_err, bag->type);
        +		BIO_printf (bio_err, "\n");
        +		return 1;
        +	break;
        +	}
        +	return 1;
        +}
        +
        +/* Given a single certificate return a verified chain or NULL if error */
        +
        +/* Hope this is OK .... */
        +
        +int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
        +{
        +	X509_STORE_CTX store_ctx;
        +	STACK_OF(X509) *chn;
        +	int i = 0;
        +
        +	/* FIXME: Should really check the return status of X509_STORE_CTX_init
        +	 * for an error, but how that fits into the return value of this
        +	 * function is less obvious. */
        +	X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
        +	if (X509_verify_cert(&store_ctx) <= 0) {
        +		i = X509_STORE_CTX_get_error (&store_ctx);
        +		if (i == 0)
        +			/* avoid returning 0 if X509_verify_cert() did not
        +			 * set an appropriate error value in the context */
        +			i = -1;
        +		chn = NULL;
        +		goto err;
        +	} else
        +		chn = X509_STORE_CTX_get1_chain(&store_ctx);
        +err:
        +	X509_STORE_CTX_cleanup(&store_ctx);
        +	*chain = chn;
        +	
        +	return i;
        +}	
        +
        +int alg_print (BIO *x, X509_ALGOR *alg)
        +{
        +	PBEPARAM *pbe;
        +	const unsigned char *p;
        +	p = alg->parameter->value.sequence->data;
        +	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
        +	if (!pbe)
        +		return 1;
        +	BIO_printf (bio_err, "%s, Iteration %ld\n", 
        +		OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
        +		ASN1_INTEGER_get(pbe->iter));
        +	PBEPARAM_free (pbe);
        +	return 1;
        +}
        +
        +/* Load all certificates from a given file */
        +
        +int cert_load(BIO *in, STACK_OF(X509) *sk)
        +{
        +	int ret;
        +	X509 *cert;
        +	ret = 0;
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_push_info("cert_load(): reading one cert");
        +#endif
        +	while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
        +#ifdef CRYPTO_MDEBUG
        +		CRYPTO_pop_info();
        +#endif
        +		ret = 1;
        +		sk_X509_push(sk, cert);
        +#ifdef CRYPTO_MDEBUG
        +		CRYPTO_push_info("cert_load(): reading one cert");
        +#endif
        +	}
        +#ifdef CRYPTO_MDEBUG
        +	CRYPTO_pop_info();
        +#endif
        +	if(ret) ERR_clear_error();
        +	return ret;
        +}
        +
        +/* Generalised attribute print: handle PKCS#8 and bag attributes */
        +
        +int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
        +{
        +	X509_ATTRIBUTE *attr;
        +	ASN1_TYPE *av;
        +	char *value;
        +	int i, attr_nid;
        +	if(!attrlst) {
        +		BIO_printf(out, "%s: <No Attributes>\n", name);
        +		return 1;
        +	}
        +	if(!sk_X509_ATTRIBUTE_num(attrlst)) {
        +		BIO_printf(out, "%s: <Empty Attributes>\n", name);
        +		return 1;
        +	}
        +	BIO_printf(out, "%s\n", name);
        +	for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
        +		attr = sk_X509_ATTRIBUTE_value(attrlst, i);
        +		attr_nid = OBJ_obj2nid(attr->object);
        +		BIO_printf(out, "    ");
        +		if(attr_nid == NID_undef) {
        +			i2a_ASN1_OBJECT (out, attr->object);
        +			BIO_printf(out, ": ");
        +		} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
        +
        +		if(sk_ASN1_TYPE_num(attr->value.set)) {
        +			av = sk_ASN1_TYPE_value(attr->value.set, 0);
        +			switch(av->type) {
        +				case V_ASN1_BMPSTRING:
        +        			value = OPENSSL_uni2asc(av->value.bmpstring->data,
        +                                	       av->value.bmpstring->length);
        +				BIO_printf(out, "%s\n", value);
        +				OPENSSL_free(value);
        +				break;
        +
        +				case V_ASN1_OCTET_STRING:
        +				hex_prin(out, av->value.octet_string->data,
        +					av->value.octet_string->length);
        +				BIO_printf(out, "\n");	
        +				break;
        +
        +				case V_ASN1_BIT_STRING:
        +				hex_prin(out, av->value.bit_string->data,
        +					av->value.bit_string->length);
        +				BIO_printf(out, "\n");	
        +				break;
        +
        +				default:
        +					BIO_printf(out, "<Unsupported tag %d>\n", av->type);
        +				break;
        +			}
        +		} else BIO_printf(out, "<No Values>\n");
        +	}
        +	return 1;
        +}
        +
        +void hex_prin(BIO *out, unsigned char *buf, int len)
        +{
        +	int i;
        +	for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
        +}
        +
        +static int set_pbe(BIO *err, int *ppbe, const char *str)
        +	{
        +	if (!str)
        +		return 0;
        +	if (!strcmp(str, "NONE"))
        +		{
        +		*ppbe = -1;
        +		return 1;
        +		}
        +	*ppbe=OBJ_txt2nid(str);
        +	if (*ppbe == NID_undef)
        +		{
        +		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +			
        +#endif
        diff --git a/vendor/openssl/openssl/apps/pkcs7.c b/vendor/openssl/openssl/apps/pkcs7.c
        new file mode 100644
        index 000000000..ae6cd33f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pkcs7.c
        @@ -0,0 +1,320 @@
        +/* apps/pkcs7.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +#include "apps.h"
        +#include <openssl/err.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	pkcs7_main
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -print_certs
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	PKCS7 *p7=NULL;
        +	int i,badops=0;
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat;
        +	char *infile,*outfile,*prog;
        +	int print_certs=0,text=0,noout=0,p7_print=0;
        +	int ret=1;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*argv,"-print") == 0)
        +			p7_print=1;
        +		else if (strcmp(*argv,"-print_certs") == 0)
        +			print_certs=1;
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg   input format - DER or PEM\n");
        +		BIO_printf(bio_err," -outform arg  output format - DER or PEM\n");
        +		BIO_printf(bio_err," -in arg       input file\n");
        +		BIO_printf(bio_err," -out arg      output file\n");
        +		BIO_printf(bio_err," -print_certs  print any certs or crl in the input\n");
        +		BIO_printf(bio_err," -text         print full details of certificates\n");
        +		BIO_printf(bio_err," -noout        don't output encoded data\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
        +#endif
        +		ret = 1;
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +                goto end;
        +                }
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +		if (in == NULL)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +
        +	if	(informat == FORMAT_ASN1)
        +		p7=d2i_PKCS7_bio(in,NULL);
        +	else if (informat == FORMAT_PEM)
        +		p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
        +	else
        +		{
        +		BIO_printf(bio_err,"bad input format specified for pkcs7 object\n");
        +		goto end;
        +		}
        +	if (p7 == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load PKCS7 object\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (p7_print)
        +		PKCS7_print_ctx(out, p7, 0, NULL);
        +
        +	if (print_certs)
        +		{
        +		STACK_OF(X509) *certs=NULL;
        +		STACK_OF(X509_CRL) *crls=NULL;
        +
        +		i=OBJ_obj2nid(p7->type);
        +		switch (i)
        +			{
        +		case NID_pkcs7_signed:
        +			certs=p7->d.sign->cert;
        +			crls=p7->d.sign->crl;
        +			break;
        +		case NID_pkcs7_signedAndEnveloped:
        +			certs=p7->d.signed_and_enveloped->cert;
        +			crls=p7->d.signed_and_enveloped->crl;
        +			break;
        +		default:
        +			break;
        +			}
        +
        +		if (certs != NULL)
        +			{
        +			X509 *x;
        +
        +			for (i=0; i<sk_X509_num(certs); i++)
        +				{
        +				x=sk_X509_value(certs,i);
        +				if(text) X509_print(out, x);
        +				else dump_cert_text(out, x);
        +
        +				if(!noout) PEM_write_bio_X509(out,x);
        +				BIO_puts(out,"\n");
        +				}
        +			}
        +		if (crls != NULL)
        +			{
        +			X509_CRL *crl;
        +
        +			for (i=0; i<sk_X509_CRL_num(crls); i++)
        +				{
        +				crl=sk_X509_CRL_value(crls,i);
        +
        +				X509_CRL_print(out, crl);
        +
        +				if(!noout)PEM_write_bio_X509_CRL(out,crl);
        +				BIO_puts(out,"\n");
        +				}
        +			}
        +
        +		ret=0;
        +		goto end;
        +		}
        +
        +	if(!noout) {
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_PKCS7_bio(out,p7);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_PKCS7(out,p7);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +
        +		if (!i)
        +			{
        +			BIO_printf(bio_err,"unable to write pkcs7 object\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +	}
        +	ret=0;
        +end:
        +	if (p7 != NULL) PKCS7_free(p7);
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free_all(out);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        diff --git a/vendor/openssl/openssl/apps/pkcs8.c b/vendor/openssl/openssl/apps/pkcs8.c
        new file mode 100644
        index 000000000..7edeb179d
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pkcs8.c
        @@ -0,0 +1,439 @@
        +/* pkcs8.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999-2004.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/pkcs12.h>
        +
        +#define PROG pkcs8_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	char **args, *infile = NULL, *outfile = NULL;
        +	char *passargin = NULL, *passargout = NULL;
        +	BIO *in = NULL, *out = NULL;
        +	int topk8 = 0;
        +	int pbe_nid = -1;
        +	const EVP_CIPHER *cipher = NULL;
        +	int iter = PKCS12_DEFAULT_ITER;
        +	int informat, outformat;
        +	int p8_broken = PKCS8_OK;
        +	int nocrypt = 0;
        +	X509_SIG *p8 = NULL;
        +	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
        +	EVP_PKEY *pkey=NULL;
        +	char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
        +	int badarg = 0;
        +	int ret = 1;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	ERR_load_crypto_strings();
        +	OpenSSL_add_all_algorithms();
        +	args = argv + 1;
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp(*args,"-v2"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				cipher=EVP_get_cipherbyname(*args);
        +				if (!cipher)
        +					{
        +					BIO_printf(bio_err,
        +						 "Unknown cipher %s\n", *args);
        +					badarg = 1;
        +					}
        +				}
        +			else
        +				badarg = 1;
        +			}
        +		else if (!strcmp(*args,"-v1"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				pbe_nid=OBJ_txt2nid(*args);
        +				if (pbe_nid == NID_undef)
        +					{
        +					BIO_printf(bio_err,
        +						 "Unknown PBE algorithm %s\n", *args);
        +					badarg = 1;
        +					}
        +				}
        +			else
        +				badarg = 1;
        +			}
        +		else if (!strcmp(*args,"-inform"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				informat=str2fmt(*args);
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args,"-outform"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outformat=str2fmt(*args);
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-topk8"))
        +			topk8 = 1;
        +		else if (!strcmp (*args, "-noiter"))
        +			iter = 1;
        +		else if (!strcmp (*args, "-nocrypt"))
        +			nocrypt = 1;
        +		else if (!strcmp (*args, "-nooct"))
        +			p8_broken = PKCS8_NO_OCTET;
        +		else if (!strcmp (*args, "-nsdb"))
        +			p8_broken = PKCS8_NS_DB;
        +		else if (!strcmp (*args, "-embed"))
        +			p8_broken = PKCS8_EMBEDDED_PARAM;
        +		else if (!strcmp(*args,"-passin"))
        +			{
        +			if (!args[1]) goto bad;
        +			passargin= *(++args);
        +			}
        +		else if (!strcmp(*args,"-passout"))
        +			{
        +			if (!args[1]) goto bad;
        +			passargout= *(++args);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*args,"-engine") == 0)
        +			{
        +			if (!args[1]) goto bad;
        +			engine= *(++args);
        +			}
        +#endif
        +		else if (!strcmp (*args, "-in"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				infile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-out"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else badarg = 1;
        +		args++;
        +		}
        +
        +	if (badarg)
        +		{
        +		bad:
        +		BIO_printf(bio_err, "Usage pkcs8 [options]\n");
        +		BIO_printf(bio_err, "where options are\n");
        +		BIO_printf(bio_err, "-in file        input file\n");
        +		BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
        +		BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
        +		BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
        +		BIO_printf(bio_err, "-out file       output file\n");
        +		BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
        +		BIO_printf(bio_err, "-topk8          output PKCS8 file\n");
        +		BIO_printf(bio_err, "-nooct          use (nonstandard) no octet format\n");
        +		BIO_printf(bio_err, "-embed          use (nonstandard) embedded DSA parameters format\n");
        +		BIO_printf(bio_err, "-nsdb           use (nonstandard) DSA Netscape DB format\n");
        +		BIO_printf(bio_err, "-noiter         use 1 as iteration count\n");
        +		BIO_printf(bio_err, "-nocrypt        use or expect unencrypted private key\n");
        +		BIO_printf(bio_err, "-v2 alg         use PKCS#5 v2.0 and cipher \"alg\"\n");
        +		BIO_printf(bio_err, "-v1 obj         use PKCS#5 v1.5 and cipher \"alg\"\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +		goto end;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
        +		{
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto end;
        +		}
        +
        +	if ((pbe_nid == -1) && !cipher)
        +		pbe_nid = NID_pbeWithMD5AndDES_CBC;
        +
        +	if (infile)
        +		{
        +		if (!(in = BIO_new_file(infile, "rb")))
        +			{
        +			BIO_printf(bio_err,
        +				 "Can't open input file %s\n", infile);
        +			goto end;
        +			}
        +		}
        +	else
        +		in = BIO_new_fp (stdin, BIO_NOCLOSE);
        +
        +	if (outfile)
        +		{
        +		if (!(out = BIO_new_file (outfile, "wb")))
        +			{
        +			BIO_printf(bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp (stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +		}
        +	if (topk8)
        +		{
        +		pkey = load_key(bio_err, infile, informat, 1,
        +			passin, e, "key");
        +		if (!pkey)
        +			goto end;
        +		if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
        +			{
        +			BIO_printf(bio_err, "Error converting key\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (nocrypt)
        +			{
        +			if (outformat == FORMAT_PEM) 
        +				PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
        +			else if (outformat == FORMAT_ASN1)
        +				i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
        +			else
        +				{
        +				BIO_printf(bio_err, "Bad format specified for key\n");
        +				goto end;
        +				}
        +			}
        +		else
        +			{
        +			if (passout)
        +				p8pass = passout;
        +			else
        +				{
        +				p8pass = pass;
        +				if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
        +					goto end;
        +				}
        +			app_RAND_load_file(NULL, bio_err, 0);
        +			if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
        +					p8pass, strlen(p8pass),
        +					NULL, 0, iter, p8inf)))
        +				{
        +				BIO_printf(bio_err, "Error encrypting key\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			app_RAND_write_file(NULL, bio_err);
        +			if (outformat == FORMAT_PEM) 
        +				PEM_write_bio_PKCS8(out, p8);
        +			else if (outformat == FORMAT_ASN1)
        +				i2d_PKCS8_bio(out, p8);
        +			else
        +				{
        +				BIO_printf(bio_err, "Bad format specified for key\n");
        +				goto end;
        +				}
        +			}
        +
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	if (nocrypt)
        +		{
        +		if (informat == FORMAT_PEM) 
        +			p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
        +		else if (informat == FORMAT_ASN1)
        +			p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad format specified for key\n");
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		if (informat == FORMAT_PEM) 
        +			p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
        +		else if (informat == FORMAT_ASN1)
        +			p8 = d2i_PKCS8_bio(in, NULL);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad format specified for key\n");
        +			goto end;
        +			}
        +
        +		if (!p8)
        +			{
        +			BIO_printf (bio_err, "Error reading key\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (passin)
        +			p8pass = passin;
        +		else
        +			{
        +			p8pass = pass;
        +			EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
        +			}
        +		p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
        +		}
        +
        +	if (!p8inf)
        +		{
        +		BIO_printf(bio_err, "Error decrypting key\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (!(pkey = EVP_PKCS82PKEY(p8inf)))
        +		{
        +		BIO_printf(bio_err, "Error converting key\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	
        +	if (p8inf->broken)
        +		{
        +		BIO_printf(bio_err, "Warning: broken key encoding: ");
        +		switch (p8inf->broken)
        +			{
        +			case PKCS8_NO_OCTET:
        +			BIO_printf(bio_err, "No Octet String in PrivateKey\n");
        +			break;
        +
        +			case PKCS8_EMBEDDED_PARAM:
        +			BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
        +			break;
        +
        +			case PKCS8_NS_DB:
        +			BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
        +			break;
        +
        +			case PKCS8_NEG_PRIVKEY:
        +			BIO_printf(bio_err, "DSA private key value is negative\n");
        +			break;
        +
        +			default:
        +			BIO_printf(bio_err, "Unknown broken type\n");
        +			break;
        +		}
        +	}
        +	
        +	if (outformat == FORMAT_PEM) 
        +		PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
        +	else if (outformat == FORMAT_ASN1)
        +		i2d_PrivateKey_bio(out, pkey);
        +	else
        +		{
        +		BIO_printf(bio_err, "Bad format specified for key\n");
        +			goto end;
        +		}
        +	ret = 0;
        +
        +	end:
        +	X509_SIG_free(p8);
        +	PKCS8_PRIV_KEY_INFO_free(p8inf);
        +	EVP_PKEY_free(pkey);
        +	BIO_free_all(out);
        +	BIO_free(in);
        +	if (passin)
        +		OPENSSL_free(passin);
        +	if (passout)
        +		OPENSSL_free(passout);
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/apps/pkey.c b/vendor/openssl/openssl/apps/pkey.c
        new file mode 100644
        index 000000000..17e6702fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pkey.c
        @@ -0,0 +1,284 @@
        +/* apps/pkey.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +
        +#define PROG pkey_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	char **args, *infile = NULL, *outfile = NULL;
        +	char *passargin = NULL, *passargout = NULL;
        +	BIO *in = NULL, *out = NULL;
        +	const EVP_CIPHER *cipher = NULL;
        +	int informat, outformat;
        +	int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
        +	EVP_PKEY *pkey=NULL;
        +	char *passin = NULL, *passout = NULL;
        +	int badarg = 0;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	int ret = 1;
        +
        +	if (bio_err == NULL)
        +		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	ERR_load_crypto_strings();
        +	OpenSSL_add_all_algorithms();
        +	args = argv + 1;
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp(*args,"-inform"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				informat=str2fmt(*args);
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args,"-outform"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outformat=str2fmt(*args);
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp(*args,"-passin"))
        +			{
        +			if (!args[1]) goto bad;
        +			passargin= *(++args);
        +			}
        +		else if (!strcmp(*args,"-passout"))
        +			{
        +			if (!args[1]) goto bad;
        +			passargout= *(++args);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*args,"-engine") == 0)
        +			{
        +			if (!args[1]) goto bad;
        +			engine= *(++args);
        +			}
        +#endif
        +		else if (!strcmp (*args, "-in"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				infile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-out"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (strcmp(*args,"-pubin") == 0)
        +			{
        +			pubin=1;
        +			pubout=1;
        +			pubtext=1;
        +			}
        +		else if (strcmp(*args,"-pubout") == 0)
        +			pubout=1;
        +		else if (strcmp(*args,"-text_pub") == 0)
        +			{
        +			pubtext=1;
        +			text=1;
        +			}
        +		else if (strcmp(*args,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*args,"-noout") == 0)
        +			noout=1;
        +		else
        +			{
        +			cipher = EVP_get_cipherbyname(*args + 1);
        +			if (!cipher)
        +				{
        +				BIO_printf(bio_err, "Unknown cipher %s\n",
        +								*args + 1);
        +				badarg = 1;
        +				}
        +			}
        +		args++;
        +		}
        +
        +	if (badarg)
        +		{
        +		bad:
        +		BIO_printf(bio_err, "Usage pkey [options]\n");
        +		BIO_printf(bio_err, "where options are\n");
        +		BIO_printf(bio_err, "-in file        input file\n");
        +		BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
        +		BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
        +		BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
        +		BIO_printf(bio_err, "-out file       output file\n");
        +		BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +		return 1;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
        +		{
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto end;
        +		}
        +
        +	if (outfile)
        +		{
        +		if (!(out = BIO_new_file (outfile, "wb")))
        +			{
        +			BIO_printf(bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp (stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +		}
        +
        +	if (pubin)
        +		pkey = load_pubkey(bio_err, infile, informat, 1,
        +			passin, e, "Public Key");
        +	else
        +		pkey = load_key(bio_err, infile, informat, 1,
        +			passin, e, "key");
        +	if (!pkey)
        +		goto end;
        +
        +	if (!noout)
        +		{
        +		if (outformat == FORMAT_PEM) 
        +			{
        +			if (pubout)
        +				PEM_write_bio_PUBKEY(out,pkey);
        +			else
        +				PEM_write_bio_PrivateKey(out, pkey, cipher,
        +							NULL, 0, NULL, passout);
        +			}
        +		else if (outformat == FORMAT_ASN1)
        +			{
        +			if (pubout)
        +				i2d_PUBKEY_bio(out, pkey);
        +			else
        +				i2d_PrivateKey_bio(out, pkey);
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad format specified for key\n");
        +			goto end;
        +			}
        +
        +		}
        +
        +	if (text)
        +		{
        +		if (pubtext)
        +			EVP_PKEY_print_public(out, pkey, 0, NULL);
        +		else
        +			EVP_PKEY_print_private(out, pkey, 0, NULL);
        +		}
        +
        +	ret = 0;
        +
        +	end:
        +	EVP_PKEY_free(pkey);
        +	BIO_free_all(out);
        +	BIO_free(in);
        +	if (passin)
        +		OPENSSL_free(passin);
        +	if (passout)
        +		OPENSSL_free(passout);
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/apps/pkeyparam.c b/vendor/openssl/openssl/apps/pkeyparam.c
        new file mode 100644
        index 000000000..6f7a357a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pkeyparam.c
        @@ -0,0 +1,200 @@
        +/* apps/pkeyparam.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +
        +#define PROG pkeyparam_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	char **args, *infile = NULL, *outfile = NULL;
        +	BIO *in = NULL, *out = NULL;
        +	int text = 0, noout = 0;
        +	EVP_PKEY *pkey=NULL;
        +	int badarg = 0;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	int ret = 1;
        +
        +	if (bio_err == NULL)
        +		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	ERR_load_crypto_strings();
        +	OpenSSL_add_all_algorithms();
        +	args = argv + 1;
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp (*args, "-in"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				infile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +		else if (!strcmp (*args, "-out"))
        +			{
        +			if (args[1])
        +				{
        +				args++;
        +				outfile = *args;
        +				}
        +			else badarg = 1;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*args,"-engine") == 0)
        +			{
        +			if (!args[1]) goto bad;
        +			engine= *(++args);
        +			}
        +#endif
        +
        +		else if (strcmp(*args,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*args,"-noout") == 0)
        +			noout=1;
        +		args++;
        +		}
        +
        +	if (badarg)
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		bad:
        +#endif
        +		BIO_printf(bio_err, "Usage pkeyparam [options]\n");
        +		BIO_printf(bio_err, "where options are\n");
        +		BIO_printf(bio_err, "-in file        input file\n");
        +		BIO_printf(bio_err, "-out file       output file\n");
        +		BIO_printf(bio_err, "-text           print parameters as text\n");
        +		BIO_printf(bio_err, "-noout          don't output encoded parameters\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +		return 1;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (infile)
        +		{
        +		if (!(in = BIO_new_file (infile, "r")))
        +			{
        +			BIO_printf(bio_err,
        +				 "Can't open input file %s\n", infile);
        +			goto end;
        +			}
        +		}
        +	else
        +		in = BIO_new_fp (stdin, BIO_NOCLOSE);
        +
        +	if (outfile)
        +		{
        +		if (!(out = BIO_new_file (outfile, "w")))
        +			{
        +			BIO_printf(bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp (stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +		}
        +
        +	pkey = PEM_read_bio_Parameters(in, NULL);
        +	if (!pkey)
        +		{
        +		BIO_printf(bio_err, "Error reading parameters\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (!noout)
        +		PEM_write_bio_Parameters(out,pkey);
        +
        +	if (text)
        +		EVP_PKEY_print_params(out, pkey, 0, NULL);
        +
        +	ret = 0;
        +
        +	end:
        +	EVP_PKEY_free(pkey);
        +	BIO_free_all(out);
        +	BIO_free(in);
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/apps/pkeyutl.c b/vendor/openssl/openssl/apps/pkeyutl.c
        new file mode 100644
        index 000000000..7eb3f5c54
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/pkeyutl.c
        @@ -0,0 +1,570 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <string.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/evp.h>
        +
        +#define KEY_PRIVKEY	1
        +#define KEY_PUBKEY	2
        +#define KEY_CERT	3
        +
        +static void usage(void);
        +
        +#undef PROG
        +
        +#define PROG pkeyutl_main
        +
        +static EVP_PKEY_CTX *init_ctx(int *pkeysize,
        +				char *keyfile, int keyform, int key_type,
        +				char *passargin, int pkey_op, ENGINE *e);
        +
        +static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
        +							const char *file);
        +
        +static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
        +		unsigned char *out, size_t *poutlen,
        +		unsigned char *in, size_t inlen);
        +
        +int MAIN(int argc, char **);
        +
        +int MAIN(int argc, char **argv)
        +{
        +	BIO *in = NULL, *out = NULL;
        +	char *infile = NULL, *outfile = NULL, *sigfile = NULL;
        +	ENGINE *e = NULL;
        +	int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
        +	int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
        +	char badarg = 0, rev = 0;
        +	char hexdump = 0, asn1parse = 0;
        +	EVP_PKEY_CTX *ctx = NULL;
        +	char *passargin = NULL;
        +	int keysize = -1;
        +
        +	unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
        +	size_t buf_outlen;
        +	int buf_inlen = 0, siglen = -1;
        +
        +	int ret = 1, rv = -1;
        +
        +	argc--;
        +	argv++;
        +
        +	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +	ERR_load_crypto_strings();
        +	OpenSSL_add_all_algorithms();
        +	
        +	while(argc >= 1)
        +		{
        +		if (!strcmp(*argv,"-in"))
        +			{
        +			if (--argc < 1) badarg = 1;
        +                        else infile= *(++argv);
        +			}
        +		else if (!strcmp(*argv,"-out"))
        +			{
        +			if (--argc < 1) badarg = 1;
        +			else outfile= *(++argv);
        +			}
        +		else if (!strcmp(*argv,"-sigfile"))
        +			{
        +			if (--argc < 1) badarg = 1;
        +			else sigfile= *(++argv);
        +			}
        +		else if(!strcmp(*argv, "-inkey"))
        +			{
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				{
        +				ctx = init_ctx(&keysize,
        +						*(++argv), keyform, key_type,
        +						passargin, pkey_op, e);
        +				if (!ctx)
        +					{
        +					BIO_puts(bio_err,
        +						"Error initializing context\n");
        +					ERR_print_errors(bio_err);
        +					badarg = 1;
        +					}
        +				}
        +			}
        +		else if (!strcmp(*argv,"-peerkey"))
        +			{
        +			if (--argc < 1)
        +				badarg = 1;
        +			else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
        +				badarg = 1;
        +			}
        +		else if (!strcmp(*argv,"-passin"))
        +			{
        +			if (--argc < 1) badarg = 1;
        +			else passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-peerform") == 0)
        +			{
        +			if (--argc < 1) badarg = 1;
        +			else peerform=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) badarg = 1;
        +			else keyform=str2fmt(*(++argv));
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if(!strcmp(*argv, "-engine"))
        +			{
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				e = setup_engine(bio_err, *(++argv), 0);
        +			}
        +#endif
        +		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, "-sign"))
        +			pkey_op = EVP_PKEY_OP_SIGN;
        +		else if(!strcmp(*argv, "-verify"))
        +			pkey_op = EVP_PKEY_OP_VERIFY;
        +		else if(!strcmp(*argv, "-verifyrecover"))
        +			pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
        +		else if(!strcmp(*argv, "-rev"))
        +			rev = 1;
        +		else if(!strcmp(*argv, "-encrypt"))
        +			pkey_op = EVP_PKEY_OP_ENCRYPT;
        +		else if(!strcmp(*argv, "-decrypt"))
        +			pkey_op = EVP_PKEY_OP_DECRYPT;
        +		else if(!strcmp(*argv, "-derive"))
        +			pkey_op = EVP_PKEY_OP_DERIVE;
        +		else if (strcmp(*argv,"-pkeyopt") == 0)
        +			{
        +			if (--argc < 1)
        +				badarg = 1;
        +			else if (!ctx)
        +				{
        +				BIO_puts(bio_err,
        +					"-pkeyopt command before -inkey\n");
        +				badarg = 1;
        +				}
        +			else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
        +				{
        +				BIO_puts(bio_err, "parameter setting error\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		else badarg = 1;
        +		if(badarg)
        +			{
        +			usage();
        +			goto end;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (!ctx)
        +		{
        +		usage();
        +		goto end;
        +		}
        +
        +	if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
        +		{
        +		BIO_puts(bio_err, "Signature file specified for non verify\n");
        +		goto end;
        +		}
        +
        +	if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
        +		{
        +		BIO_puts(bio_err, "No signature file specified for verify\n");
        +		goto end;
        +		}
        +
        +/* FIXME: seed PRNG only if needed */
        +	app_RAND_load_file(NULL, bio_err, 0);
        +
        +	if (pkey_op != EVP_PKEY_OP_DERIVE)
        +		{
        +		if(infile)
        +			{
        +			if(!(in = BIO_new_file(infile, "rb")))
        +				{
        +				BIO_puts(bio_err,
        +					"Error Opening 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 Creating Output File\n");
        +			ERR_print_errors(bio_err);	
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		    out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +	}
        +
        +	if (sigfile)
        +		{
        +		BIO *sigbio = BIO_new_file(sigfile, "rb");
        +		if (!sigbio)
        +			{
        +			BIO_printf(bio_err, "Can't open signature file %s\n",
        +								sigfile);
        +			goto end;
        +			}
        +		siglen = bio_to_mem(&sig, keysize * 10, sigbio);
        +		BIO_free(sigbio);
        +		if (siglen <= 0)
        +			{
        +			BIO_printf(bio_err, "Error reading signature data\n");
        +			goto end;
        +			}
        +		}
        +	
        +	if (in)
        +		{
        +		/* Read the input data */
        +		buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
        +		if(buf_inlen <= 0)
        +			{
        +			BIO_printf(bio_err, "Error reading input Data\n");
        +			exit(1);
        +			}
        +		if(rev)
        +			{
        +			size_t i;
        +			unsigned char ctmp;
        +			size_t l = (size_t)buf_inlen;
        +			for(i = 0; i < l/2; i++)
        +				{
        +				ctmp = buf_in[i];
        +				buf_in[i] = buf_in[l - 1 - i];
        +				buf_in[l - 1 - i] = ctmp;
        +				}
        +			}
        +		}
        +
        +	if(pkey_op == EVP_PKEY_OP_VERIFY)
        +		{
        +		rv  = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
        +				      buf_in, (size_t)buf_inlen);
        +		if (rv == 0)
        +			BIO_puts(out, "Signature Verification Failure\n");
        +		else if (rv == 1)
        +			BIO_puts(out, "Signature Verified Successfully\n");
        +		if (rv >= 0)
        +			goto end;
        +		}
        +	else
        +		{	
        +		rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
        +			      buf_in, (size_t)buf_inlen);
        +		if (rv > 0)
        +			{
        +			buf_out = OPENSSL_malloc(buf_outlen);
        +			if (!buf_out)
        +				rv = -1;
        +			else
        +				rv = do_keyop(ctx, pkey_op,
        +						buf_out, (size_t *)&buf_outlen,
        +						buf_in, (size_t)buf_inlen);
        +			}
        +		}
        +
        +	if(rv <= 0)
        +		{
        +		BIO_printf(bio_err, "Public Key operation error\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	ret = 0;
        +	if(asn1parse)
        +		{
        +		if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
        +			ERR_print_errors(bio_err);
        +		}
        +	else if(hexdump)
        +		BIO_dump(out, (char *)buf_out, buf_outlen);
        +	else
        +		BIO_write(out, buf_out, buf_outlen);
        +
        +	end:
        +	if (ctx)
        +		EVP_PKEY_CTX_free(ctx);
        +	BIO_free(in);
        +	BIO_free_all(out);
        +	if (buf_in)
        +		OPENSSL_free(buf_in);
        +	if (buf_out)
        +		OPENSSL_free(buf_out);
        +	if (sig)
        +		OPENSSL_free(sig);
        +	return ret;
        +}
        +
        +static void usage()
        +{
        +	BIO_printf(bio_err, "Usage: pkeyutl [options]\n");
        +	BIO_printf(bio_err, "-in file        input file\n");
        +	BIO_printf(bio_err, "-out file       output file\n");
        +	BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n");
        +	BIO_printf(bio_err, "-inkey file     input key\n");
        +	BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
        +	BIO_printf(bio_err, "-pubin          input is a public key\n");
        +	BIO_printf(bio_err, "-certin         input is a certificate carrying a public key\n");
        +	BIO_printf(bio_err, "-pkeyopt X:Y    public key options\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, "-verifyrecover  verify with public key, recover original data\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, "-derive         derive shared secret\n");
        +	BIO_printf(bio_err, "-hexdump        hex dump output\n");
        +#ifndef OPENSSL_NO_ENGINE
        +	BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +	BIO_printf(bio_err, "-passin arg     pass phrase source\n");
        +
        +}
        +
        +static EVP_PKEY_CTX *init_ctx(int *pkeysize,
        +				char *keyfile, int keyform, int key_type,
        +				char *passargin, int pkey_op, ENGINE *e)
        +	{
        +	EVP_PKEY *pkey = NULL;
        +	EVP_PKEY_CTX *ctx = NULL;
        +	char *passin = NULL;
        +	int rv = -1;
        +	X509 *x;
        +	if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 
        +		|| (pkey_op == EVP_PKEY_OP_DERIVE))
        +		&& (key_type != KEY_PRIVKEY))
        +		{
        +		BIO_printf(bio_err, "A private key is needed for this operation\n");
        +		goto end;
        +		}
        +	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +	switch(key_type)
        +		{
        +		case KEY_PRIVKEY:
        +		pkey = load_key(bio_err, keyfile, keyform, 0,
        +			passin, e, "Private Key");
        +		break;
        +
        +		case KEY_PUBKEY:
        +		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
        +			NULL, e, "Public Key");
        +		break;
        +
        +		case KEY_CERT:
        +		x = load_cert(bio_err, keyfile, keyform,
        +			NULL, e, "Certificate");
        +		if(x)
        +			{
        +			pkey = X509_get_pubkey(x);
        +			X509_free(x);
        +			}
        +		break;
        +
        +		}
        +
        +	*pkeysize = EVP_PKEY_size(pkey);
        +
        +	if (!pkey)
        +		goto end;
        +
        +	ctx = EVP_PKEY_CTX_new(pkey, e);
        +
        +	EVP_PKEY_free(pkey);
        +
        +	if (!ctx)
        +		goto end;
        +
        +	switch(pkey_op)
        +		{
        +		case EVP_PKEY_OP_SIGN:
        +		rv = EVP_PKEY_sign_init(ctx);
        +		break;
        +
        +		case EVP_PKEY_OP_VERIFY:
        +		rv = EVP_PKEY_verify_init(ctx);
        +		break;
        +
        +		case EVP_PKEY_OP_VERIFYRECOVER:
        +		rv = EVP_PKEY_verify_recover_init(ctx);
        +		break;
        +
        +		case EVP_PKEY_OP_ENCRYPT:
        +		rv = EVP_PKEY_encrypt_init(ctx);
        +		break;
        +
        +		case EVP_PKEY_OP_DECRYPT:
        +		rv = EVP_PKEY_decrypt_init(ctx);
        +		break;
        +
        +		case EVP_PKEY_OP_DERIVE:
        +		rv = EVP_PKEY_derive_init(ctx);
        +		break;
        +		}
        +
        +	if (rv <= 0)
        +		{
        +		EVP_PKEY_CTX_free(ctx);
        +		ctx = NULL;
        +		}
        +
        +	end:
        +
        +	if (passin)
        +		OPENSSL_free(passin);
        +
        +	return ctx;
        +
        +
        +	}
        +
        +static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
        +							const char *file)
        +	{
        +	EVP_PKEY *peer = NULL;
        +	int ret;
        +	if (!ctx)
        +		{
        +		BIO_puts(err, "-peerkey command before -inkey\n");
        +		return 0;
        +		}
        +		
        +	peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
        +
        +	if (!peer)
        +		{
        +		BIO_printf(bio_err, "Error reading peer key %s\n", file);
        +		ERR_print_errors(err);
        +		return 0;
        +		}
        +
        +	ret = EVP_PKEY_derive_set_peer(ctx, peer);
        +
        +	EVP_PKEY_free(peer);
        +	if (ret <= 0)
        +		ERR_print_errors(err);
        +	return ret;
        +	}
        +
        +static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
        +		unsigned char *out, size_t *poutlen,
        +		unsigned char *in, size_t inlen)
        +	{
        +	int rv = 0;
        +	switch(pkey_op)
        +		{
        +		case EVP_PKEY_OP_VERIFYRECOVER:
        +		rv  = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
        +		break;
        +
        +		case EVP_PKEY_OP_SIGN:
        +		rv  = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
        +		break;
        +
        +		case EVP_PKEY_OP_ENCRYPT:
        +		rv  = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
        +		break;
        +
        +		case EVP_PKEY_OP_DECRYPT:
        +		rv  = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
        +		break; 
        +
        +		case EVP_PKEY_OP_DERIVE:
        +		rv  = EVP_PKEY_derive(ctx, out, poutlen);
        +		break;
        +
        +		}
        +	return rv;
        +	}
        diff --git a/vendor/openssl/openssl/apps/prime.c b/vendor/openssl/openssl/apps/prime.c
        new file mode 100644
        index 000000000..f1aaef872
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/prime.c
        @@ -0,0 +1,160 @@
        +/* ====================================================================
        + * Copyright (c) 2004 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.
        + *
        + */
        +
        +#include <string.h>
        +
        +#include "apps.h"
        +#include <openssl/bn.h>
        +
        +
        +#undef PROG
        +#define PROG prime_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +    {
        +    int hex=0;
        +    int checks=20;
        +    int generate=0;
        +    int bits=0;
        +    int safe=0;
        +    BIGNUM *bn=NULL;
        +    BIO *bio_out;
        +
        +    apps_startup();
        +
        +    if (bio_err == NULL)
        +	if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +	    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +    --argc;
        +    ++argv;
        +    while (argc >= 1 && **argv == '-')
        +	{
        +	if(!strcmp(*argv,"-hex"))
        +	    hex=1;
        +	else if(!strcmp(*argv,"-generate"))
        +	    generate=1;
        +	else if(!strcmp(*argv,"-bits"))
        +	    if(--argc < 1)
        +		goto bad;
        +	    else
        +		bits=atoi(*++argv);
        +	else if(!strcmp(*argv,"-safe"))
        +	    safe=1;
        +	else if(!strcmp(*argv,"-checks"))
        +	    if(--argc < 1)
        +		goto bad;
        +	    else
        +		checks=atoi(*++argv);
        +	else
        +	    {
        +	    BIO_printf(bio_err,"Unknown option '%s'\n",*argv);
        +	    goto bad;
        +	    }
        +	--argc;
        +	++argv;
        +	}
        +
        +    if (argv[0] == NULL && !generate)
        +	{
        +	BIO_printf(bio_err,"No prime specified\n");
        +	goto bad;
        +	}
        +
        +    if ((bio_out=BIO_new(BIO_s_file())) != NULL)
        +	{
        +	BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +	    {
        +	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	    bio_out = BIO_push(tmpbio, bio_out);
        +	    }
        +#endif
        +	}
        +
        +    if(generate)
        +	{
        +	char *s;
        +
        +	if(!bits)
        +	    {
        +	    BIO_printf(bio_err,"Specifiy the number of bits.\n");
        +	    return 1;
        +	    }
        +	bn=BN_new();
        +	BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL);
        +	s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
        +	BIO_printf(bio_out,"%s\n",s);
        +	OPENSSL_free(s);
        +	}
        +    else
        +	{
        +	if(hex)
        +	    BN_hex2bn(&bn,argv[0]);
        +	else
        +	    BN_dec2bn(&bn,argv[0]);
        +
        +	BN_print(bio_out,bn);
        +	BIO_printf(bio_out," is %sprime\n",
        +		   BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not ");
        +	}
        +
        +    BN_free(bn);
        +    BIO_free_all(bio_out);
        +
        +    return 0;
        +
        +    bad:
        +    BIO_printf(bio_err,"options are\n");
        +    BIO_printf(bio_err,"%-14s hex\n","-hex");
        +    BIO_printf(bio_err,"%-14s number of checks\n","-checks <n>");
        +    return 1;
        +    }
        diff --git a/vendor/openssl/openssl/apps/privkey.pem b/vendor/openssl/openssl/apps/privkey.pem
        new file mode 100644
        index 000000000..0af46474a
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/privkey.pem
        @@ -0,0 +1,18 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +Proc-Type: 4,ENCRYPTED
        +DEK-Info: DES-EDE3-CBC,BA26229A1653B7FF
        +
        +6nhWG8PKhTPO/s3ZvjUa6226NlKdvPDZFsNXOOoSUs9ejxpb/aj5huhs6qRYzsz9
        +Year47uaAZYhGD0vAagnNiBnYmjWEpN9G/wQxG7pgZThK1ZxDi63qn8aQ8UjuGHo
        +F6RpnnBQIAnWTWqr/Qsybtc5EoNkrj/Cpx0OfbSr6gZsFBCxwX1R1hT3/mhJ45f3
        +XMofY32Vdfx9/vtw1O7HmlHXQnXaqnbd9/nn1EpvFJG9+UjPoW7gV4jCOLuR4deE
        +jS8hm+cpkwXmFtk3VGjT9tQXPpMv3JpYfBqgGQoMAJ5Toq0DWcHi6Wg08PsD8lgy
        +vmTioPsRg+JGkJkJ8GnusgLpQdlQJbjzd7wGE6ElUFLfOxLo8bLlRHoriHNdWYhh
        +JjY0LyeTkovcmWxVjImc6ZyBz5Ly4t0BYf1gq3OkjsV91Q1taBxnhiavfizqMCAf
        +PPB3sLQnlXG77TOXkNxpqbZfEYrVZW2Nsqqdn8s07Uj4IMONZyq2odYKWFPMJBiM
        +POYwXjMAOcmFMTHYsVlhcUJuV6LOuipw/FEbTtPH/MYMxLe4zx65dYo1rb4iLKLS
        +gMtB0o/Wl4Xno3ZXh1ucicYnV2J7NpVcjVq+3SFiCRu2SrSkZHZ23EPS13Ec6fcz
        +8X/YGA2vTJ8MAOozAzQUwHQYvLk7bIoQVekqDq4p0AZQbhdspHpArCk0Ifqqzg/v
        +Uyky/zZiQYanzDenTSRVI/8wac3olxpU8QvbySxYqmbkgq6bTpXJfYFQfnAttEsC
        +dA4S5UFgyOPZluxCAM4yaJF3Ft6neutNwftuJQMbgCUi9vYg2tGdSw==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/progs.h b/vendor/openssl/openssl/apps/progs.h
        new file mode 100644
        index 000000000..949e78066
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/progs.h
        @@ -0,0 +1,366 @@
        +/* apps/progs.h */
        +/* automatically generated by progs.pl for openssl.c */
        +
        +extern int verify_main(int argc,char *argv[]);
        +extern int asn1parse_main(int argc,char *argv[]);
        +extern int req_main(int argc,char *argv[]);
        +extern int dgst_main(int argc,char *argv[]);
        +extern int dh_main(int argc,char *argv[]);
        +extern int dhparam_main(int argc,char *argv[]);
        +extern int enc_main(int argc,char *argv[]);
        +extern int passwd_main(int argc,char *argv[]);
        +extern int gendh_main(int argc,char *argv[]);
        +extern int errstr_main(int argc,char *argv[]);
        +extern int ca_main(int argc,char *argv[]);
        +extern int crl_main(int argc,char *argv[]);
        +extern int rsa_main(int argc,char *argv[]);
        +extern int rsautl_main(int argc,char *argv[]);
        +extern int dsa_main(int argc,char *argv[]);
        +extern int dsaparam_main(int argc,char *argv[]);
        +extern int ec_main(int argc,char *argv[]);
        +extern int ecparam_main(int argc,char *argv[]);
        +extern int x509_main(int argc,char *argv[]);
        +extern int genrsa_main(int argc,char *argv[]);
        +extern int gendsa_main(int argc,char *argv[]);
        +extern int genpkey_main(int argc,char *argv[]);
        +extern int s_server_main(int argc,char *argv[]);
        +extern int s_client_main(int argc,char *argv[]);
        +extern int speed_main(int argc,char *argv[]);
        +extern int s_time_main(int argc,char *argv[]);
        +extern int version_main(int argc,char *argv[]);
        +extern int pkcs7_main(int argc,char *argv[]);
        +extern int cms_main(int argc,char *argv[]);
        +extern int crl2pkcs7_main(int argc,char *argv[]);
        +extern int sess_id_main(int argc,char *argv[]);
        +extern int ciphers_main(int argc,char *argv[]);
        +extern int nseq_main(int argc,char *argv[]);
        +extern int pkcs12_main(int argc,char *argv[]);
        +extern int pkcs8_main(int argc,char *argv[]);
        +extern int pkey_main(int argc,char *argv[]);
        +extern int pkeyparam_main(int argc,char *argv[]);
        +extern int pkeyutl_main(int argc,char *argv[]);
        +extern int spkac_main(int argc,char *argv[]);
        +extern int smime_main(int argc,char *argv[]);
        +extern int rand_main(int argc,char *argv[]);
        +extern int engine_main(int argc,char *argv[]);
        +extern int ocsp_main(int argc,char *argv[]);
        +extern int prime_main(int argc,char *argv[]);
        +extern int ts_main(int argc,char *argv[]);
        +extern int srp_main(int argc,char *argv[]);
        +
        +#define FUNC_TYPE_GENERAL	1
        +#define FUNC_TYPE_MD		2
        +#define FUNC_TYPE_CIPHER	3
        +#define FUNC_TYPE_PKEY		4
        +#define FUNC_TYPE_MD_ALG	5
        +#define FUNC_TYPE_CIPHER_ALG	6
        +
        +typedef struct {
        +	int type;
        +	const char *name;
        +	int (*func)(int argc,char *argv[]);
        +	} FUNCTION;
        +DECLARE_LHASH_OF(FUNCTION);
        +
        +FUNCTION functions[] = {
        +	{FUNC_TYPE_GENERAL,"verify",verify_main},
        +	{FUNC_TYPE_GENERAL,"asn1parse",asn1parse_main},
        +	{FUNC_TYPE_GENERAL,"req",req_main},
        +	{FUNC_TYPE_GENERAL,"dgst",dgst_main},
        +#ifndef OPENSSL_NO_DH
        +	{FUNC_TYPE_GENERAL,"dh",dh_main},
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	{FUNC_TYPE_GENERAL,"dhparam",dhparam_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"enc",enc_main},
        +	{FUNC_TYPE_GENERAL,"passwd",passwd_main},
        +#ifndef OPENSSL_NO_DH
        +	{FUNC_TYPE_GENERAL,"gendh",gendh_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"errstr",errstr_main},
        +	{FUNC_TYPE_GENERAL,"ca",ca_main},
        +	{FUNC_TYPE_GENERAL,"crl",crl_main},
        +#ifndef OPENSSL_NO_RSA
        +	{FUNC_TYPE_GENERAL,"rsa",rsa_main},
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	{FUNC_TYPE_GENERAL,"rsautl",rsautl_main},
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	{FUNC_TYPE_GENERAL,"dsa",dsa_main},
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	{FUNC_TYPE_GENERAL,"dsaparam",dsaparam_main},
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	{FUNC_TYPE_GENERAL,"ec",ec_main},
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	{FUNC_TYPE_GENERAL,"ecparam",ecparam_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"x509",x509_main},
        +#ifndef OPENSSL_NO_RSA
        +	{FUNC_TYPE_GENERAL,"genrsa",genrsa_main},
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
        +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
        +	{FUNC_TYPE_GENERAL,"s_server",s_server_main},
        +#endif
        +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
        +	{FUNC_TYPE_GENERAL,"s_client",s_client_main},
        +#endif
        +#ifndef OPENSSL_NO_SPEED
        +	{FUNC_TYPE_GENERAL,"speed",speed_main},
        +#endif
        +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
        +	{FUNC_TYPE_GENERAL,"s_time",s_time_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"version",version_main},
        +	{FUNC_TYPE_GENERAL,"pkcs7",pkcs7_main},
        +#ifndef OPENSSL_NO_CMS
        +	{FUNC_TYPE_GENERAL,"cms",cms_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"crl2pkcs7",crl2pkcs7_main},
        +	{FUNC_TYPE_GENERAL,"sess_id",sess_id_main},
        +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
        +	{FUNC_TYPE_GENERAL,"ciphers",ciphers_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"nseq",nseq_main},
        +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
        +	{FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
        +	{FUNC_TYPE_GENERAL,"pkey",pkey_main},
        +	{FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
        +	{FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
        +	{FUNC_TYPE_GENERAL,"spkac",spkac_main},
        +	{FUNC_TYPE_GENERAL,"smime",smime_main},
        +	{FUNC_TYPE_GENERAL,"rand",rand_main},
        +#ifndef OPENSSL_NO_ENGINE
        +	{FUNC_TYPE_GENERAL,"engine",engine_main},
        +#endif
        +#ifndef OPENSSL_NO_OCSP
        +	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
        +#endif
        +	{FUNC_TYPE_GENERAL,"prime",prime_main},
        +	{FUNC_TYPE_GENERAL,"ts",ts_main},
        +#ifndef OPENSSL_NO_SRP
        +	{FUNC_TYPE_GENERAL,"srp",srp_main},
        +#endif
        +#ifndef OPENSSL_NO_MD2
        +	{FUNC_TYPE_MD,"md2",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_MD4
        +	{FUNC_TYPE_MD,"md4",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +	{FUNC_TYPE_MD,"md5",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	{FUNC_TYPE_MD,"sha",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_SHA1
        +	{FUNC_TYPE_MD,"sha1",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +	{FUNC_TYPE_MD,"mdc2",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_RMD160
        +	{FUNC_TYPE_MD,"rmd160",dgst_main},
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	{FUNC_TYPE_CIPHER,"aes-128-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	{FUNC_TYPE_CIPHER,"aes-128-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	{FUNC_TYPE_CIPHER,"aes-192-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	{FUNC_TYPE_CIPHER,"aes-192-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	{FUNC_TYPE_CIPHER,"aes-256-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	{FUNC_TYPE_CIPHER,"aes-256-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	{FUNC_TYPE_CIPHER,"camellia-128-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	{FUNC_TYPE_CIPHER,"camellia-128-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	{FUNC_TYPE_CIPHER,"camellia-192-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	{FUNC_TYPE_CIPHER,"camellia-192-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	{FUNC_TYPE_CIPHER,"camellia-256-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	{FUNC_TYPE_CIPHER,"camellia-256-ecb",enc_main},
        +#endif
        +	{FUNC_TYPE_CIPHER,"base64",enc_main},
        +#ifdef ZLIB
        +	{FUNC_TYPE_CIPHER,"zlib",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des3",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"desx",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	{FUNC_TYPE_CIPHER,"idea",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	{FUNC_TYPE_CIPHER,"seed",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +	{FUNC_TYPE_CIPHER,"rc4",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +	{FUNC_TYPE_CIPHER,"rc4-40",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	{FUNC_TYPE_CIPHER,"bf",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	{FUNC_TYPE_CIPHER,"cast",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	{FUNC_TYPE_CIPHER,"rc5",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede3",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede3-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede3-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	{FUNC_TYPE_CIPHER,"des-ede3-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	{FUNC_TYPE_CIPHER,"idea-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	{FUNC_TYPE_CIPHER,"idea-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	{FUNC_TYPE_CIPHER,"idea-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	{FUNC_TYPE_CIPHER,"idea-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	{FUNC_TYPE_CIPHER,"seed-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	{FUNC_TYPE_CIPHER,"seed-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	{FUNC_TYPE_CIPHER,"seed-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	{FUNC_TYPE_CIPHER,"seed-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2-64-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	{FUNC_TYPE_CIPHER,"rc2-40-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	{FUNC_TYPE_CIPHER,"bf-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	{FUNC_TYPE_CIPHER,"bf-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	{FUNC_TYPE_CIPHER,"bf-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	{FUNC_TYPE_CIPHER,"bf-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	{FUNC_TYPE_CIPHER,"cast5-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	{FUNC_TYPE_CIPHER,"cast5-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	{FUNC_TYPE_CIPHER,"cast5-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	{FUNC_TYPE_CIPHER,"cast5-ofb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	{FUNC_TYPE_CIPHER,"cast-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	{FUNC_TYPE_CIPHER,"rc5-cbc",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	{FUNC_TYPE_CIPHER,"rc5-ecb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	{FUNC_TYPE_CIPHER,"rc5-cfb",enc_main},
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	{FUNC_TYPE_CIPHER,"rc5-ofb",enc_main},
        +#endif
        +	{0,NULL,NULL}
        +	};
        diff --git a/vendor/openssl/openssl/apps/progs.pl b/vendor/openssl/openssl/apps/progs.pl
        new file mode 100644
        index 000000000..39ca8f71f
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/progs.pl
        @@ -0,0 +1,104 @@
        +#!/usr/local/bin/perl
        +
        +print "/* apps/progs.h */\n";
        +print "/* automatically generated by progs.pl for openssl.c */\n\n";
        +
        +grep(s/^asn1pars$/asn1parse/,@ARGV);
        +
        +foreach (@ARGV)
        +	{ printf "extern int %s_main(int argc,char *argv[]);\n",$_; }
        +
        +print <<'EOF';
        +
        +#define FUNC_TYPE_GENERAL	1
        +#define FUNC_TYPE_MD		2
        +#define FUNC_TYPE_CIPHER	3
        +#define FUNC_TYPE_PKEY		4
        +#define FUNC_TYPE_MD_ALG	5
        +#define FUNC_TYPE_CIPHER_ALG	6
        +
        +typedef struct {
        +	int type;
        +	const char *name;
        +	int (*func)(int argc,char *argv[]);
        +	} FUNCTION;
        +DECLARE_LHASH_OF(FUNCTION);
        +
        +FUNCTION functions[] = {
        +EOF
        +
        +foreach (@ARGV)
        +	{
        +	push(@files,$_);
        +	$str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n";
        +	if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/))
        +		{ print "#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))\n${str}#endif\n"; } 
        +	elsif ( ($_ =~ /^speed$/))
        +		{ print "#ifndef OPENSSL_NO_SPEED\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^engine$/))
        +		{ print "#ifndef OPENSSL_NO_ENGINE\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^rsa$/) || ($_ =~ /^genrsa$/) || ($_ =~ /^rsautl$/)) 
        +		{ print "#ifndef OPENSSL_NO_RSA\n${str}#endif\n";  }
        +	elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/))
        +		{ print "#ifndef OPENSSL_NO_DSA\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^ec$/) || ($_ =~ /^ecparam$/))
        +		{ print "#ifndef OPENSSL_NO_EC\n${str}#endif\n";}
        +	elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/) || ($_ =~ /^dhparam$/))
        +		{ print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^pkcs12$/))
        +		{ print "#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^cms$/))
        +		{ print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^ocsp$/))
        +		{ print "#ifndef OPENSSL_NO_OCSP\n${str}#endif\n"; }
        +	elsif ( ($_ =~ /^srp$/))
        +		{ print "#ifndef OPENSSL_NO_SRP\n${str}#endif\n"; }
        +	else
        +		{ print $str; }
        +	}
        +
        +foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160")
        +	{
        +	push(@files,$_);
        +	printf "#ifndef OPENSSL_NO_".uc($_)."\n\t{FUNC_TYPE_MD,\"".$_."\",dgst_main},\n#endif\n";
        +	}
        +
        +foreach (
        +	"aes-128-cbc", "aes-128-ecb",
        +	"aes-192-cbc", "aes-192-ecb",
        +	"aes-256-cbc", "aes-256-ecb",
        +	"camellia-128-cbc", "camellia-128-ecb",
        +	"camellia-192-cbc", "camellia-192-ecb",
        +	"camellia-256-cbc", "camellia-256-ecb",
        +	"base64", "zlib",
        +	"des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
        +	"rc2", "bf", "cast", "rc5",
        +	"des-ecb", "des-ede",    "des-ede3",
        +	"des-cbc", "des-ede-cbc","des-ede3-cbc",
        +	"des-cfb", "des-ede-cfb","des-ede3-cfb",
        +	"des-ofb", "des-ede-ofb","des-ede3-ofb",
        +	"idea-cbc","idea-ecb",    "idea-cfb", "idea-ofb",
        +	"seed-cbc","seed-ecb",    "seed-cfb", "seed-ofb",
        +	"rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc",
        +	"bf-cbc",  "bf-ecb",     "bf-cfb",   "bf-ofb",
        +	"cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb",
        +	"cast-cbc", "rc5-cbc",   "rc5-ecb",  "rc5-cfb",  "rc5-ofb")
        +	{
        +	push(@files,$_);
        +
        +	$t=sprintf("\t{FUNC_TYPE_CIPHER,\"%s\",enc_main},\n",$_);
        +	if    ($_ =~ /des/)  { $t="#ifndef OPENSSL_NO_DES\n${t}#endif\n"; }
        +	elsif ($_ =~ /aes/)  { $t="#ifndef OPENSSL_NO_AES\n${t}#endif\n"; }
        +	elsif ($_ =~ /camellia/)  { $t="#ifndef OPENSSL_NO_CAMELLIA\n${t}#endif\n"; }
        +	elsif ($_ =~ /idea/) { $t="#ifndef OPENSSL_NO_IDEA\n${t}#endif\n"; }
        +	elsif ($_ =~ /seed/) { $t="#ifndef OPENSSL_NO_SEED\n${t}#endif\n"; }
        +	elsif ($_ =~ /rc4/)  { $t="#ifndef OPENSSL_NO_RC4\n${t}#endif\n"; }
        +	elsif ($_ =~ /rc2/)  { $t="#ifndef OPENSSL_NO_RC2\n${t}#endif\n"; }
        +	elsif ($_ =~ /bf/)   { $t="#ifndef OPENSSL_NO_BF\n${t}#endif\n"; }
        +	elsif ($_ =~ /cast/) { $t="#ifndef OPENSSL_NO_CAST\n${t}#endif\n"; }
        +	elsif ($_ =~ /rc5/)  { $t="#ifndef OPENSSL_NO_RC5\n${t}#endif\n"; }
        +	elsif ($_ =~ /zlib/)  { $t="#ifdef ZLIB\n${t}#endif\n"; }
        +	print $t;
        +	}
        +
        +print "\t{0,NULL,NULL}\n\t};\n";
        diff --git a/vendor/openssl/openssl/apps/rand.c b/vendor/openssl/openssl/apps/rand.c
        new file mode 100644
        index 000000000..790e79592
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/rand.c
        @@ -0,0 +1,245 @@
        +/* apps/rand.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "apps.h"
        +
        +#include <ctype.h>
        +#include <stdio.h>
        +#include <string.h>
        +
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +
        +#undef PROG
        +#define PROG rand_main
        +
        +/* -out file         - write to file
        + * -rand file:file   - PRNG seed files
        + * -base64           - base64 encode output
        + * -hex              - hex encode output
        + * num               - write 'num' bytes
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int i, r, ret = 1;
        +	int badopt;
        +	char *outfile = NULL;
        +	char *inrand = NULL;
        +	int base64 = 0;
        +	int hex = 0;
        +	BIO *out = NULL;
        +	int num = -1;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto err;
        +
        +	badopt = 0;
        +	i = 0;
        +	while (!badopt && argv[++i] != NULL)
        +		{
        +		if (strcmp(argv[i], "-out") == 0)
        +			{
        +			if ((argv[i+1] != NULL) && (outfile == NULL))
        +				outfile = argv[++i];
        +			else
        +				badopt = 1;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(argv[i], "-engine") == 0)
        +			{
        +			if ((argv[i+1] != NULL) && (engine == NULL))
        +				engine = argv[++i];
        +			else
        +				badopt = 1;
        +			}
        +#endif
        +		else if (strcmp(argv[i], "-rand") == 0)
        +			{
        +			if ((argv[i+1] != NULL) && (inrand == NULL))
        +				inrand = argv[++i];
        +			else
        +				badopt = 1;
        +			}
        +		else if (strcmp(argv[i], "-base64") == 0)
        +			{
        +			if (!base64)
        +				base64 = 1;
        +			else
        +				badopt = 1;
        +			}
        +		else if (strcmp(argv[i], "-hex") == 0)
        +			{
        +			if (!hex)
        +				hex = 1;
        +			else
        +				badopt = 1;
        +			}
        +		else if (isdigit((unsigned char)argv[i][0]))
        +			{
        +			if (num < 0)
        +				{
        +				r = sscanf(argv[i], "%d", &num);
        +				if (r == 0 || num < 0)
        +					badopt = 1;
        +				}
        +			else
        +				badopt = 1;
        +			}
        +		else
        +			badopt = 1;
        +		}
        +
        +	if (hex && base64)
        +		badopt = 1;
        +
        +	if (num < 0)
        +		badopt = 1;
        +	
        +	if (badopt) 
        +		{
        +		BIO_printf(bio_err, "Usage: rand [options] num\n");
        +		BIO_printf(bio_err, "where options are\n");
        +		BIO_printf(bio_err, "-out file             - write to file\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err, "-engine e             - use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err, "-base64               - base64 encode output\n");
        +		BIO_printf(bio_err, "-hex                  - hex encode output\n");
        +		goto err;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        +	if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +
        +	out = BIO_new(BIO_s_file());
        +	if (out == NULL)
        +		goto err;
        +	if (outfile != NULL)
        +		r = BIO_write_filename(out, outfile);
        +	else
        +		{
        +		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	if (r <= 0)
        +		goto err;
        +
        +	if (base64)
        +		{
        +		BIO *b64 = BIO_new(BIO_f_base64());
        +		if (b64 == NULL)
        +			goto err;
        +		out = BIO_push(b64, out);
        +		}
        +	
        +	while (num > 0) 
        +		{
        +		unsigned char buf[4096];
        +		int chunk;
        +
        +		chunk = num;
        +		if (chunk > (int)sizeof(buf))
        +			chunk = sizeof buf;
        +		r = RAND_bytes(buf, chunk);
        +		if (r <= 0)
        +			goto err;
        +		if (!hex) 
        +			BIO_write(out, buf, chunk);
        +		else
        +			{
        +			for (i = 0; i < chunk; i++)
        +				BIO_printf(out, "%02x", buf[i]);
        +			}
        +		num -= chunk;
        +		}
        +	if (hex)
        +		BIO_puts(out, "\n");
        +	(void)BIO_flush(out);
        +
        +	app_RAND_write_file(NULL, bio_err);
        +	ret = 0;
        +	
        +err:
        +	ERR_print_errors(bio_err);
        +	if (out)
        +		BIO_free_all(out);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        diff --git a/vendor/openssl/openssl/apps/req.c b/vendor/openssl/openssl/apps/req.c
        new file mode 100644
        index 000000000..85526581c
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/req.c
        @@ -0,0 +1,1836 @@
        +/* apps/req.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.]
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <time.h>
        +#include <string.h>
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/conf.h>
        +#include <openssl/err.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/objects.h>
        +#include <openssl/pem.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#define SECTION		"req"
        +
        +#define BITS		"default_bits"
        +#define KEYFILE		"default_keyfile"
        +#define PROMPT		"prompt"
        +#define DISTINGUISHED_NAME	"distinguished_name"
        +#define ATTRIBUTES	"attributes"
        +#define V3_EXTENSIONS	"x509_extensions"
        +#define REQ_EXTENSIONS	"req_extensions"
        +#define STRING_MASK	"string_mask"
        +#define UTF8_IN		"utf8"
        +
        +#define DEFAULT_KEY_LENGTH	512
        +#define MIN_KEY_LENGTH		384
        +
        +#undef PROG
        +#define PROG	req_main
        +
        +/* -inform arg	- input format - default PEM (DER or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -verify	- check request signature
        + * -noout	- don't print stuff out.
        + * -text	- print out human readable text.
        + * -nodes	- no des encryption
        + * -config file	- Load configuration file.
        + * -key file	- make a request using key in file (or use it for verification).
        + * -keyform arg	- key file format.
        + * -rand file(s) - load the file(s) into the PRNG.
        + * -newkey	- make a key and a request.
        + * -modulus	- print RSA modulus.
        + * -pubkey	- output Public Key.
        + * -x509	- output a self signed X509 structure instead.
        + * -asn1-kludge	- output new certificate request in a format that some CA's
        + *		  require.  This format is wrong
        + */
        +
        +static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,char *dn,int mutlirdn,
        +		int attribs,unsigned long chtype);
        +static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
        +		int multirdn);
        +static int prompt_info(X509_REQ *req,
        +		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
        +		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
        +		unsigned long chtype);
        +static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
        +				STACK_OF(CONF_VALUE) *attr, int attribs,
        +				unsigned long chtype);
        +static int add_attribute_object(X509_REQ *req, char *text, const char *def,
        +				char *value, int nid, int n_min,
        +				int n_max, unsigned long chtype);
        +static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
        +	int nid,int n_min,int n_max, unsigned long chtype, int mval);
        +static int genpkey_cb(EVP_PKEY_CTX *ctx);
        +static int req_check_len(int len,int n_min,int n_max);
        +static int check_end(const char *str, const char *end);
        +static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
        +					long *pkeylen, char **palgnam,
        +					ENGINE *keygen_engine);
        +#ifndef MONOLITH
        +static char *default_config_file=NULL;
        +#endif
        +static CONF *req_conf=NULL;
        +static int batch=0;
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL, *gen_eng = NULL;
        +	unsigned long nmflag = 0, reqflag = 0;
        +	int ex=1,x509=0,days=30;
        +	X509 *x509ss=NULL;
        +	X509_REQ *req=NULL;
        +	EVP_PKEY_CTX *genctx = NULL;
        +	const char *keyalg = NULL;
        +	char *keyalgstr = NULL;
        +	STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
        +	EVP_PKEY *pkey=NULL;
        +	int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1;
        +	long newkey = -1;
        +	BIO *in=NULL,*out=NULL;
        +	int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
        +	int nodes=0,kludge=0,newhdr=0,subject=0,pubkey=0;
        +	char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	char *extensions = NULL;
        +	char *req_exts = NULL;
        +	const EVP_CIPHER *cipher=NULL;
        +	ASN1_INTEGER *serial = NULL;
        +	int modulus=0;
        +	char *inrand=NULL;
        +	char *passargin = NULL, *passargout = NULL;
        +	char *passin = NULL, *passout = NULL;
        +	char *p;
        +	char *subj = NULL;
        +	int multirdn = 0;
        +	const EVP_MD *md_alg=NULL,*digest=NULL;
        +	unsigned long chtype = MBSTRING_ASC;
        +#ifndef MONOLITH
        +	char *to_free;
        +	long errline;
        +#endif
        +
        +	req_conf = NULL;
        +#ifndef OPENSSL_NO_DES
        +	cipher=EVP_des_ede3_cbc();
        +#endif
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keygen_engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			gen_eng = ENGINE_by_id(*(++argv));
        +			if (gen_eng == NULL)
        +				{
        +				BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
        +				goto end;
        +				}
        +			}
        +#endif
        +		else if (strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-pubkey") == 0)
        +			{
        +			pubkey=1;
        +			}
        +		else if (strcmp(*argv,"-new") == 0)
        +			{
        +			newreq=1;
        +			}
        +		else if (strcmp(*argv,"-config") == 0)
        +			{	
        +			if (--argc < 1) goto bad;
        +			template= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyform=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keyout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyout= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-newkey") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			keyalg = *(++argv);
        +			newreq=1;
        +			}
        +		else if (strcmp(*argv,"-pkeyopt") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			if (!pkeyopts)
        +				pkeyopts = sk_OPENSSL_STRING_new_null();
        +			if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
        +				goto bad;
        +			}
        +		else if (strcmp(*argv,"-sigopt") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			if (!sigopts)
        +				sigopts = sk_OPENSSL_STRING_new_null();
        +			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
        +				goto bad;
        +			}
        +		else if (strcmp(*argv,"-batch") == 0)
        +			batch=1;
        +		else if (strcmp(*argv,"-newhdr") == 0)
        +			newhdr=1;
        +		else if (strcmp(*argv,"-modulus") == 0)
        +			modulus=1;
        +		else if (strcmp(*argv,"-verify") == 0)
        +			verify=1;
        +		else if (strcmp(*argv,"-nodes") == 0)
        +			nodes=1;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-verbose") == 0)
        +			verbose=1;
        +		else if (strcmp(*argv,"-utf8") == 0)
        +			chtype = MBSTRING_UTF8;
        +		else if (strcmp(*argv,"-nameopt") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
        +			}
        +		else if (strcmp(*argv,"-reqopt") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!set_cert_ex(&reqflag, *(++argv))) goto bad;
        +			}
        +		else if (strcmp(*argv,"-subject") == 0)
        +			subject=1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*argv,"-x509") == 0)
        +			x509=1;
        +		else if (strcmp(*argv,"-asn1-kludge") == 0)
        +			kludge=1;
        +		else if (strcmp(*argv,"-no-asn1-kludge") == 0)
        +			kludge=0;
        +		else if (strcmp(*argv,"-subj") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			subj= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-multivalue-rdn") == 0)
        +			multirdn=1;
        +		else if (strcmp(*argv,"-days") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			days= atoi(*(++argv));
        +			if (days == 0) days=30;
        +			}
        +		else if (strcmp(*argv,"-set_serial") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			serial = s2i_ASN1_INTEGER(NULL, *(++argv));
        +			if (!serial) goto bad;
        +			}
        +		else if (strcmp(*argv,"-extensions") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			extensions = *(++argv);
        +			}
        +		else if (strcmp(*argv,"-reqexts") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			req_exts = *(++argv);
        +			}
        +		else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
        +			{
        +			/* ok */
        +			digest=md_alg;
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options  are\n");
        +		BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
        +		BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
        +		BIO_printf(bio_err," -in arg        input file\n");
        +		BIO_printf(bio_err," -out arg       output file\n");
        +		BIO_printf(bio_err," -text          text form of request\n");
        +		BIO_printf(bio_err," -pubkey        output public key\n");
        +		BIO_printf(bio_err," -noout         do not output REQ\n");
        +		BIO_printf(bio_err," -verify        verify signature on REQ\n");
        +		BIO_printf(bio_err," -modulus       RSA modulus\n");
        +		BIO_printf(bio_err," -nodes         don't encrypt the output key\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e      use engine e, possibly a hardware device\n");
        +#endif
        +		BIO_printf(bio_err," -subject       output the request's subject\n");
        +		BIO_printf(bio_err," -passin        private key password source\n");
        +		BIO_printf(bio_err," -key file      use the private key contained in file\n");
        +		BIO_printf(bio_err," -keyform arg   key file format\n");
        +		BIO_printf(bio_err," -keyout arg    file to send the key to\n");
        +		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,"                load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,"                the random number generator\n");
        +		BIO_printf(bio_err," -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
        +		BIO_printf(bio_err," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
        +#ifndef OPENSSL_NO_ECDSA
        +		BIO_printf(bio_err," -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
        +#endif
        +		BIO_printf(bio_err," -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
        +		BIO_printf(bio_err," -config file   request template file.\n");
        +		BIO_printf(bio_err," -subj arg      set or modify request subject\n");
        +		BIO_printf(bio_err," -multivalue-rdn enable support for multivalued RDNs\n");
        +		BIO_printf(bio_err," -new           new request.\n");
        +		BIO_printf(bio_err," -batch         do not ask anything during request generation\n");
        +		BIO_printf(bio_err," -x509          output a x509 structure instead of a cert. req.\n");
        +		BIO_printf(bio_err," -days          number of days a certificate generated by -x509 is valid for.\n");
        +		BIO_printf(bio_err," -set_serial    serial number to use for a certificate generated by -x509.\n");
        +		BIO_printf(bio_err," -newhdr        output \"NEW\" in the header lines\n");
        +		BIO_printf(bio_err," -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
        +		BIO_printf(bio_err,"                have been reported as requiring\n");
        +		BIO_printf(bio_err," -extensions .. specify certificate extension section (override value in config file)\n");
        +		BIO_printf(bio_err," -reqexts ..    specify request extension section (override value in config file)\n");
        +		BIO_printf(bio_err," -utf8          input characters are UTF8 (default ASCII)\n");
        +		BIO_printf(bio_err," -nameopt arg    - various certificate name options\n");
        +		BIO_printf(bio_err," -reqopt arg    - various request text options\n\n");
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto end;
        +	}
        +
        +#ifndef MONOLITH /* else this has happened in openssl.c (global `config') */
        +	/* Lets load up our environment a little */
        +	p=getenv("OPENSSL_CONF");
        +	if (p == NULL)
        +		p=getenv("SSLEAY_CONF");
        +	if (p == NULL)
        +		p=to_free=make_config_name();
        +	default_config_file=p;
        +	config=NCONF_new(NULL);
        +	i=NCONF_load(config, p, &errline);
        +#endif
        +
        +	if (template != NULL)
        +		{
        +		long errline = -1;
        +
        +		if( verbose )
        +			BIO_printf(bio_err,"Using configuration from %s\n",template);
        +		req_conf=NCONF_new(NULL);
        +		i=NCONF_load(req_conf,template,&errline);
        +		if (i == 0)
        +			{
        +			BIO_printf(bio_err,"error on line %ld of %s\n",errline,template);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		req_conf=config;
        +
        +		if (req_conf == NULL)
        +			{
        +			BIO_printf(bio_err,"Unable to load config info from %s\n", default_config_file);
        +			if (newreq)
        +				goto end;
        +			}
        +		else if( verbose )
        +			BIO_printf(bio_err,"Using configuration from %s\n",
        +			default_config_file);
        +		}
        +
        +	if (req_conf != NULL)
        +		{
        +		if (!load_config(bio_err, req_conf))
        +			goto end;
        +		p=NCONF_get_string(req_conf,NULL,"oid_file");
        +		if (p == NULL)
        +			ERR_clear_error();
        +		if (p != NULL)
        +			{
        +			BIO *oid_bio;
        +
        +			oid_bio=BIO_new_file(p,"r");
        +			if (oid_bio == NULL) 
        +				{
        +				/*
        +				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
        +				ERR_print_errors(bio_err);
        +				*/
        +				}
        +			else
        +				{
        +				OBJ_create_objects(oid_bio);
        +				BIO_free(oid_bio);
        +				}
        +			}
        +		}
        +	if(!add_oid_section(bio_err, req_conf)) goto end;
        +
        +	if (md_alg == NULL)
        +		{
        +		p=NCONF_get_string(req_conf,SECTION,"default_md");
        +		if (p == NULL)
        +			ERR_clear_error();
        +		if (p != NULL)
        +			{
        +			if ((md_alg=EVP_get_digestbyname(p)) != NULL)
        +				digest=md_alg;
        +			}
        +		}
        +
        +	if (!extensions)
        +		{
        +		extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
        +		if (!extensions)
        +			ERR_clear_error();
        +		}
        +	if (extensions) {
        +		/* Check syntax of file */
        +		X509V3_CTX ctx;
        +		X509V3_set_ctx_test(&ctx);
        +		X509V3_set_nconf(&ctx, req_conf);
        +		if(!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
        +			BIO_printf(bio_err,
        +			 "Error Loading extension section %s\n", extensions);
        +			goto end;
        +		}
        +	}
        +
        +	if(!passin)
        +		{
        +		passin = NCONF_get_string(req_conf, SECTION, "input_password");
        +		if (!passin)
        +			ERR_clear_error();
        +		}
        +	
        +	if(!passout)
        +		{
        +		passout = NCONF_get_string(req_conf, SECTION, "output_password");
        +		if (!passout)
        +			ERR_clear_error();
        +		}
        +
        +	p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
        +	if (!p)
        +		ERR_clear_error();
        +
        +	if(p && !ASN1_STRING_set_default_mask_asc(p)) {
        +		BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
        +		goto end;
        +	}
        +
        +	if (chtype != MBSTRING_UTF8)
        +		{
        +		p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
        +		if (!p)
        +			ERR_clear_error();
        +		else if (!strcmp(p, "yes"))
        +			chtype = MBSTRING_UTF8;
        +		}
        +
        +
        +	if(!req_exts)
        +		{
        +		req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
        +		if (!req_exts)
        +			ERR_clear_error();
        +		}
        +	if(req_exts) {
        +		/* Check syntax of file */
        +		X509V3_CTX ctx;
        +		X509V3_set_ctx_test(&ctx);
        +		X509V3_set_nconf(&ctx, req_conf);
        +		if(!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
        +			BIO_printf(bio_err,
        +			 "Error Loading request extension section %s\n",
        +								req_exts);
        +			goto end;
        +		}
        +	}
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		goto end;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (keyfile != NULL)
        +		{
        +		pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
        +			"Private Key");
        +		if (!pkey)
        +			{
        +			/* load_key() has already printed an appropriate
        +			   message */
        +			goto end;
        +			}
        +		else
        +			{
        +			char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
        +			if (randfile == NULL)
        +				ERR_clear_error();
        +			app_RAND_load_file(randfile, bio_err, 0);
        +			}
        +		}
        +
        +	if (newreq && (pkey == NULL))
        +		{
        +		char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
        +		if (randfile == NULL)
        +			ERR_clear_error();
        +		app_RAND_load_file(randfile, bio_err, 0);
        +		if (inrand)
        +			app_RAND_load_files(inrand);
        +
        +		if (keyalg)
        +			{
        +			genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
        +							&keyalgstr, gen_eng);
        +			if (!genctx)
        +				goto end;
        +			}
        +	
        +		if (newkey <= 0)
        +			{
        +			if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
        +				newkey=DEFAULT_KEY_LENGTH;
        +			}
        +
        +		if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA))
        +			{
        +			BIO_printf(bio_err,"private key length is too short,\n");
        +			BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey);
        +			goto end;
        +			}
        +
        +		if (!genctx)
        +			{
        +			genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
        +							&keyalgstr, gen_eng);
        +			if (!genctx)
        +				goto end;
        +			}
        +
        +		if (pkeyopts)
        +			{
        +			char *genopt;
        +			for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++)
        +				{
        +				genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
        +				if (pkey_ctrl_string(genctx, genopt) <= 0)
        +					{
        +					BIO_printf(bio_err,
        +						"parameter error \"%s\"\n",
        +						genopt);
        +					ERR_print_errors(bio_err);
        +					goto end;
        +					}
        +				}
        +			}
        +
        +		BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
        +				newkey, keyalgstr);
        +
        +		EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
        +		EVP_PKEY_CTX_set_app_data(genctx, bio_err);
        +
        +		if (EVP_PKEY_keygen(genctx, &pkey) <= 0)
        +			{
        +			BIO_puts(bio_err, "Error Generating Key\n");
        +			goto end;
        +			}
        +
        +		EVP_PKEY_CTX_free(genctx);
        +		genctx = NULL;
        +
        +		app_RAND_write_file(randfile, bio_err);
        +
        +		if (keyout == NULL)
        +			{
        +			keyout=NCONF_get_string(req_conf,SECTION,KEYFILE);
        +			if (keyout == NULL)
        +				ERR_clear_error();
        +			}
        +		
        +		if (keyout == NULL)
        +			{
        +			BIO_printf(bio_err,"writing new private key to stdout\n");
        +			BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"writing new private key to '%s'\n",keyout);
        +			if (BIO_write_filename(out,keyout) <= 0)
        +				{
        +				perror(keyout);
        +				goto end;
        +				}
        +			}
        +
        +		p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key");
        +		if (p == NULL)
        +			{
        +			ERR_clear_error();
        +			p=NCONF_get_string(req_conf,SECTION,"encrypt_key");
        +			if (p == NULL)
        +				ERR_clear_error();
        +			}
        +		if ((p != NULL) && (strcmp(p,"no") == 0))
        +			cipher=NULL;
        +		if (nodes) cipher=NULL;
        +		
        +		i=0;
        +loop:
        +		if (!PEM_write_bio_PrivateKey(out,pkey,cipher,
        +			NULL,0,NULL,passout))
        +			{
        +			if ((ERR_GET_REASON(ERR_peek_error()) ==
        +				PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3))
        +				{
        +				ERR_clear_error();
        +				i++;
        +				goto loop;
        +				}
        +			goto end;
        +			}
        +		BIO_printf(bio_err,"-----\n");
        +		}
        +
        +	if (!newreq)
        +		{
        +		/* Since we are using a pre-existing certificate
        +		 * request, the kludge 'format' info should not be
        +		 * changed. */
        +		kludge= -1;
        +		if (infile == NULL)
        +			BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +		else
        +			{
        +			if (BIO_read_filename(in,infile) <= 0)
        +				{
        +				perror(infile);
        +				goto end;
        +				}
        +			}
        +
        +		if	(informat == FORMAT_ASN1)
        +			req=d2i_X509_REQ_bio(in,NULL);
        +		else if (informat == FORMAT_PEM)
        +			req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
        +		else
        +			{
        +			BIO_printf(bio_err,"bad input format specified for X509 request\n");
        +			goto end;
        +			}
        +		if (req == NULL)
        +			{
        +			BIO_printf(bio_err,"unable to load X509 request\n");
        +			goto end;
        +			}
        +		}
        +
        +	if (newreq || x509)
        +		{
        +		if (pkey == NULL)
        +			{
        +			BIO_printf(bio_err,"you need to specify a private key\n");
        +			goto end;
        +			}
        +
        +		if (req == NULL)
        +			{
        +			req=X509_REQ_new();
        +			if (req == NULL)
        +				{
        +				goto end;
        +				}
        +
        +			i=make_REQ(req,pkey,subj,multirdn,!x509, chtype);
        +			subj=NULL; /* done processing '-subj' option */
        +			if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes))
        +				{
        +				sk_X509_ATTRIBUTE_free(req->req_info->attributes);
        +				req->req_info->attributes = NULL;
        +				}
        +			if (!i)
        +				{
        +				BIO_printf(bio_err,"problems making Certificate Request\n");
        +				goto end;
        +				}
        +			}
        +		if (x509)
        +			{
        +			EVP_PKEY *tmppkey;
        +			X509V3_CTX ext_ctx;
        +			if ((x509ss=X509_new()) == NULL) goto end;
        +
        +			/* Set version to V3 */
        +			if(extensions && !X509_set_version(x509ss, 2)) goto end;
        +			if (serial)
        +				{
        +				if (!X509_set_serialNumber(x509ss, serial)) goto end;
        +				}
        +			else
        +				{
        +				if (!rand_serial(NULL,
        +					X509_get_serialNumber(x509ss)))
        +						goto end;
        +				}
        +
        +			if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
        +			if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
        +			if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end;
        +			if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
        +			tmppkey = X509_REQ_get_pubkey(req);
        +			if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
        +			EVP_PKEY_free(tmppkey);
        +
        +			/* Set up V3 context struct */
        +
        +			X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
        +			X509V3_set_nconf(&ext_ctx, req_conf);
        +
        +			/* Add extensions */
        +			if(extensions && !X509V3_EXT_add_nconf(req_conf, 
        +				 	&ext_ctx, extensions, x509ss))
        +				{
        +				BIO_printf(bio_err,
        +					"Error Loading extension section %s\n",
        +					extensions);
        +				goto end;
        +				}
        +
        +			i=do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
        +			if (!i)
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		else
        +			{
        +			X509V3_CTX ext_ctx;
        +
        +			/* Set up V3 context struct */
        +
        +			X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
        +			X509V3_set_nconf(&ext_ctx, req_conf);
        +
        +			/* Add extensions */
        +			if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, 
        +				 	&ext_ctx, req_exts, req))
        +				{
        +				BIO_printf(bio_err,
        +					"Error Loading extension section %s\n",
        +					req_exts);
        +				goto end;
        +				}
        +			i=do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
        +			if (!i)
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +		}
        +
        +	if (subj && x509)
        +		{
        +		BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
        +		goto end;
        +		}
        +
        +	if (subj && !x509)
        +		{
        +		if (verbose)
        +			{
        +			BIO_printf(bio_err, "Modifying Request's Subject\n");
        +			print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag);
        +			}
        +
        +		if (build_subject(req, subj, chtype, multirdn) == 0)
        +			{
        +			BIO_printf(bio_err, "ERROR: cannot modify subject\n");
        +			ex=1;
        +			goto end;
        +			}
        +
        +		req->req_info->enc.modified = 1;
        +
        +		if (verbose)
        +			{
        +			print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag);
        +			}
        +		}
        +
        +	if (verify && !x509)
        +		{
        +		int tmp=0;
        +
        +		if (pkey == NULL)
        +			{
        +			pkey=X509_REQ_get_pubkey(req);
        +			tmp=1;
        +			if (pkey == NULL) goto end;
        +			}
        +
        +		i=X509_REQ_verify(req,pkey);
        +		if (tmp) {
        +			EVP_PKEY_free(pkey);
        +			pkey=NULL;
        +		}
        +
        +		if (i < 0)
        +			{
        +			goto end;
        +			}
        +		else if (i == 0)
        +			{
        +			BIO_printf(bio_err,"verify failure\n");
        +			ERR_print_errors(bio_err);
        +			}
        +		else /* if (i > 0) */
        +			BIO_printf(bio_err,"verify OK\n");
        +		}
        +
        +	if (noout && !text && !modulus && !subject && !pubkey)
        +		{
        +		ex=0;
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if ((keyout != NULL) && (strcmp(outfile,keyout) == 0))
        +			i=(int)BIO_append_filename(out,outfile);
        +		else
        +			i=(int)BIO_write_filename(out,outfile);
        +		if (!i)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (pubkey)
        +		{
        +		EVP_PKEY *tpubkey; 
        +		tpubkey=X509_REQ_get_pubkey(req);
        +		if (tpubkey == NULL)
        +			{
        +			BIO_printf(bio_err,"Error getting public key\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		PEM_write_bio_PUBKEY(out, tpubkey);
        +		EVP_PKEY_free(tpubkey);
        +		}
        +
        +	if (text)
        +		{
        +		if (x509)
        +			X509_print_ex(out, x509ss, nmflag, reqflag);
        +		else	
        +			X509_REQ_print_ex(out, req, nmflag, reqflag);
        +		}
        +
        +	if(subject) 
        +		{
        +		if(x509)
        +			print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag);
        +		else
        +			print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag);
        +		}
        +
        +	if (modulus)
        +		{
        +		EVP_PKEY *tpubkey;
        +
        +		if (x509)
        +			tpubkey=X509_get_pubkey(x509ss);
        +		else
        +			tpubkey=X509_REQ_get_pubkey(req);
        +		if (tpubkey == NULL)
        +			{
        +			fprintf(stdout,"Modulus=unavailable\n");
        +			goto end; 
        +			}
        +		fprintf(stdout,"Modulus=");
        +#ifndef OPENSSL_NO_RSA
        +		if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
        +			BN_print(out,tpubkey->pkey.rsa->n);
        +		else
        +#endif
        +			fprintf(stdout,"Wrong Algorithm type");
        +		EVP_PKEY_free(tpubkey);
        +		fprintf(stdout,"\n");
        +		}
        +
        +	if (!noout && !x509)
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_X509_REQ_bio(out,req);
        +		else if (outformat == FORMAT_PEM) {
        +			if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req);
        +			else i=PEM_write_bio_X509_REQ(out,req);
        +		} else {
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i)
        +			{
        +			BIO_printf(bio_err,"unable to write X509 request\n");
        +			goto end;
        +			}
        +		}
        +	if (!noout && x509 && (x509ss != NULL))
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_X509_bio(out,x509ss);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_X509(out,x509ss);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i)
        +			{
        +			BIO_printf(bio_err,"unable to write X509 certificate\n");
        +			goto end;
        +			}
        +		}
        +	ex=0;
        +end:
        +#ifndef MONOLITH
        +	if(to_free)
        +		OPENSSL_free(to_free);
        +#endif
        +	if (ex)
        +		{
        +		ERR_print_errors(bio_err);
        +		}
        +	if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf);
        +	BIO_free(in);
        +	BIO_free_all(out);
        +	EVP_PKEY_free(pkey);
        +	if (genctx)
        +		EVP_PKEY_CTX_free(genctx);
        +	if (pkeyopts)
        +		sk_OPENSSL_STRING_free(pkeyopts);
        +	if (sigopts)
        +		sk_OPENSSL_STRING_free(sigopts);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (gen_eng)
        +		ENGINE_free(gen_eng);
        +#endif
        +	if (keyalgstr)
        +		OPENSSL_free(keyalgstr);
        +	X509_REQ_free(req);
        +	X509_free(x509ss);
        +	ASN1_INTEGER_free(serial);
        +	if(passargin && passin) OPENSSL_free(passin);
        +	if(passargout && passout) OPENSSL_free(passout);
        +	OBJ_cleanup();
        +	apps_shutdown();
        +	OPENSSL_EXIT(ex);
        +	}
        +
        +static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
        +			int attribs, unsigned long chtype)
        +	{
        +	int ret=0,i;
        +	char no_prompt = 0;
        +	STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
        +	char *tmp, *dn_sect,*attr_sect;
        +
        +	tmp=NCONF_get_string(req_conf,SECTION,PROMPT);
        +	if (tmp == NULL)
        +		ERR_clear_error();
        +	if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
        +
        +	dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
        +	if (dn_sect == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to find '%s' in config\n",
        +			DISTINGUISHED_NAME);
        +		goto err;
        +		}
        +	dn_sk=NCONF_get_section(req_conf,dn_sect);
        +	if (dn_sk == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
        +		goto err;
        +		}
        +
        +	attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES);
        +	if (attr_sect == NULL)
        +		{
        +		ERR_clear_error();		
        +		attr_sk=NULL;
        +		}
        +	else
        +		{
        +		attr_sk=NCONF_get_section(req_conf,attr_sect);
        +		if (attr_sk == NULL)
        +			{
        +			BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect);
        +			goto err;
        +			}
        +		}
        +
        +	/* setup version number */
        +	if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
        +
        +	if (no_prompt) 
        +		i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
        +	else 
        +		{
        +		if (subj)
        +			i = build_subject(req, subj, chtype, multirdn);
        +		else
        +			i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
        +		}
        +	if(!i) goto err;
        +
        +	if (!X509_REQ_set_pubkey(req,pkey)) goto err;
        +
        +	ret=1;
        +err:
        +	return(ret);
        +	}
        +
        +/*
        + * subject is expected to be in the format /type0=value0/type1=value1/type2=...
        + * where characters may be escaped by \
        + */
        +static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn)
        +	{
        +	X509_NAME *n;
        +
        +	if (!(n = parse_name(subject, chtype, multirdn)))
        +		return 0;
        +
        +	if (!X509_REQ_set_subject_name(req, n))
        +		{
        +		X509_NAME_free(n);
        +		return 0;
        +		}
        +	X509_NAME_free(n);
        +	return 1;
        +}
        +
        +
        +static int prompt_info(X509_REQ *req,
        +		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
        +		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
        +		unsigned long chtype)
        +	{
        +	int i;
        +	char *p,*q;
        +	char buf[100];
        +	int nid, mval;
        +	long n_min,n_max;
        +	char *type, *value;
        +	const char *def;
        +	CONF_VALUE *v;
        +	X509_NAME *subj;
        +	subj = X509_REQ_get_subject_name(req);
        +
        +	if(!batch)
        +		{
        +		BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
        +		BIO_printf(bio_err,"into your certificate request.\n");
        +		BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
        +		BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
        +		BIO_printf(bio_err,"For some fields there will be a default value,\n");
        +		BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
        +		BIO_printf(bio_err,"-----\n");
        +		}
        +
        +
        +	if (sk_CONF_VALUE_num(dn_sk))
        +		{
        +		i= -1;
        +start:		for (;;)
        +			{
        +			i++;
        +			if (sk_CONF_VALUE_num(dn_sk) <= i) break;
        +
        +			v=sk_CONF_VALUE_value(dn_sk,i);
        +			p=q=NULL;
        +			type=v->name;
        +			if(!check_end(type,"_min") || !check_end(type,"_max") ||
        +				!check_end(type,"_default") ||
        +					 !check_end(type,"_value")) continue;
        +			/* Skip past any leading X. X: X, etc to allow for
        +			 * multiple instances 
        +			 */
        +			for(p = v->name; *p ; p++) 
        +				if ((*p == ':') || (*p == ',') ||
        +							 (*p == '.')) {
        +					p++;
        +					if(*p) type = p;
        +					break;
        +				}
        +			if (*type == '+')
        +				{
        +				mval = -1;
        +				type++;
        +				}
        +			else
        +				mval = 0;
        +			/* If OBJ not recognised ignore it */
        +			if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
        +			if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
        +				>= (int)sizeof(buf))
        +			   {
        +			   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
        +			   return 0;
        +			   }
        +
        +			if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
        +				{
        +				ERR_clear_error();
        +				def="";
        +				}
        +				
        +			BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
        +			if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
        +				{
        +				ERR_clear_error();
        +				value=NULL;
        +				}
        +
        +			BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
        +			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
        +				{
        +				ERR_clear_error();
        +				n_min = -1;
        +				}
        +
        +			BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
        +			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
        +				{
        +				ERR_clear_error();
        +				n_max = -1;
        +				}
        +
        +			if (!add_DN_object(subj,v->value,def,value,nid,
        +				n_min,n_max, chtype, mval))
        +				return 0;
        +			}
        +		if (X509_NAME_entry_count(subj) == 0)
        +			{
        +			BIO_printf(bio_err,"error, no objects specified in config file\n");
        +			return 0;
        +			}
        +
        +		if (attribs)
        +			{
        +			if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch))
        +				{
        +				BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
        +				BIO_printf(bio_err,"to be sent with your certificate request\n");
        +				}
        +
        +			i= -1;
        +start2:			for (;;)
        +				{
        +				i++;
        +				if ((attr_sk == NULL) ||
        +					    (sk_CONF_VALUE_num(attr_sk) <= i))
        +					break;
        +
        +				v=sk_CONF_VALUE_value(attr_sk,i);
        +				type=v->name;
        +				if ((nid=OBJ_txt2nid(type)) == NID_undef)
        +					goto start2;
        +
        +				if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
        +					>= (int)sizeof(buf))
        +				   {
        +				   BIO_printf(bio_err,"Name '%s' too long\n",v->name);
        +				   return 0;
        +				   }
        +
        +				if ((def=NCONF_get_string(req_conf,attr_sect,buf))
        +					== NULL)
        +					{
        +					ERR_clear_error();
        +					def="";
        +					}
        +				
        +				
        +				BIO_snprintf(buf,sizeof buf,"%s_value",type);
        +				if ((value=NCONF_get_string(req_conf,attr_sect,buf))
        +					== NULL)
        +					{
        +					ERR_clear_error();
        +					value=NULL;
        +					}
        +
        +				BIO_snprintf(buf,sizeof buf,"%s_min",type);
        +				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
        +					{
        +					ERR_clear_error();
        +					n_min = -1;
        +					}
        +
        +				BIO_snprintf(buf,sizeof buf,"%s_max",type);
        +				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
        +					{
        +					ERR_clear_error();
        +					n_max = -1;
        +					}
        +
        +				if (!add_attribute_object(req,
        +					v->value,def,value,nid,n_min,n_max, chtype))
        +					return 0;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		BIO_printf(bio_err,"No template, please set one up.\n");
        +		return 0;
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
        +			STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype)
        +	{
        +	int i;
        +	char *p,*q;
        +	char *type;
        +	CONF_VALUE *v;
        +	X509_NAME *subj;
        +
        +	subj = X509_REQ_get_subject_name(req);
        +
        +	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
        +		{
        +		int mval;
        +		v=sk_CONF_VALUE_value(dn_sk,i);
        +		p=q=NULL;
        +		type=v->name;
        +		/* Skip past any leading X. X: X, etc to allow for
        +		 * multiple instances 
        +		 */
        +		for(p = v->name; *p ; p++) 
        +#ifndef CHARSET_EBCDIC
        +			if ((*p == ':') || (*p == ',') || (*p == '.')) {
        +#else
        +			if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) {
        +#endif
        +				p++;
        +				if(*p) type = p;
        +				break;
        +			}
        +#ifndef CHARSET_EBCDIC
        +		if (*p == '+')
        +#else
        +		if (*p == os_toascii['+'])
        +#endif
        +			{
        +			p++;
        +			mval = -1;
        +			}
        +		else
        +			mval = 0;
        +		if (!X509_NAME_add_entry_by_txt(subj,type, chtype,
        +				(unsigned char *) v->value,-1,-1,mval)) return 0;
        +
        +		}
        +
        +		if (!X509_NAME_entry_count(subj))
        +			{
        +			BIO_printf(bio_err,"error, no objects specified in config file\n");
        +			return 0;
        +			}
        +		if (attribs)
        +			{
        +			for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
        +				{
        +				v=sk_CONF_VALUE_value(attr_sk,i);
        +				if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
        +					(unsigned char *)v->value, -1)) return 0;
        +				}
        +			}
        +	return 1;
        +	}
        +
        +
        +static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
        +	     int nid, int n_min, int n_max, unsigned long chtype, int mval)
        +	{
        +	int i,ret=0;
        +	MS_STATIC char buf[1024];
        +start:
        +	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
        +	(void)BIO_flush(bio_err);
        +	if(value != NULL)
        +		{
        +		BUF_strlcpy(buf,value,sizeof buf);
        +		BUF_strlcat(buf,"\n",sizeof buf);
        +		BIO_printf(bio_err,"%s\n",value);
        +		}
        +	else
        +		{
        +		buf[0]='\0';
        +		if (!batch)
        +			{
        +			if (!fgets(buf,sizeof buf,stdin))
        +				return 0;
        +			}
        +		else
        +			{
        +			buf[0] = '\n';
        +			buf[1] = '\0';
        +			}
        +		}
        +
        +	if (buf[0] == '\0') return(0);
        +	else if (buf[0] == '\n')
        +		{
        +		if ((def == NULL) || (def[0] == '\0'))
        +			return(1);
        +		BUF_strlcpy(buf,def,sizeof buf);
        +		BUF_strlcat(buf,"\n",sizeof buf);
        +		}
        +	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
        +
        +	i=strlen(buf);
        +	if (buf[i-1] != '\n')
        +		{
        +		BIO_printf(bio_err,"weird input :-(\n");
        +		return(0);
        +		}
        +	buf[--i]='\0';
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(buf, buf, i);
        +#endif
        +	if(!req_check_len(i, n_min, n_max)) goto start;
        +	if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
        +				(unsigned char *) buf, -1,-1,mval)) goto err;
        +	ret=1;
        +err:
        +	return(ret);
        +	}
        +
        +static int add_attribute_object(X509_REQ *req, char *text, const char *def,
        +				char *value, int nid, int n_min,
        +				int n_max, unsigned long chtype)
        +	{
        +	int i;
        +	static char buf[1024];
        +
        +start:
        +	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
        +	(void)BIO_flush(bio_err);
        +	if (value != NULL)
        +		{
        +		BUF_strlcpy(buf,value,sizeof buf);
        +		BUF_strlcat(buf,"\n",sizeof buf);
        +		BIO_printf(bio_err,"%s\n",value);
        +		}
        +	else
        +		{
        +		buf[0]='\0';
        +		if (!batch)
        +			{
        +			if (!fgets(buf,sizeof buf,stdin))
        +				return 0;
        +			}
        +		else
        +			{
        +			buf[0] = '\n';
        +			buf[1] = '\0';
        +			}
        +		}
        +
        +	if (buf[0] == '\0') return(0);
        +	else if (buf[0] == '\n')
        +		{
        +		if ((def == NULL) || (def[0] == '\0'))
        +			return(1);
        +		BUF_strlcpy(buf,def,sizeof buf);
        +		BUF_strlcat(buf,"\n",sizeof buf);
        +		}
        +	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
        +
        +	i=strlen(buf);
        +	if (buf[i-1] != '\n')
        +		{
        +		BIO_printf(bio_err,"weird input :-(\n");
        +		return(0);
        +		}
        +	buf[--i]='\0';
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(buf, buf, i);
        +#endif
        +	if(!req_check_len(i, n_min, n_max)) goto start;
        +
        +	if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
        +					(unsigned char *)buf, -1)) {
        +		BIO_printf(bio_err, "Error adding attribute\n");
        +		ERR_print_errors(bio_err);
        +		goto err;
        +	}
        +
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +static int req_check_len(int len, int n_min, int n_max)
        +	{
        +	if ((n_min > 0) && (len < n_min))
        +		{
        +		BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min);
        +		return(0);
        +		}
        +	if ((n_max >= 0) && (len > n_max))
        +		{
        +		BIO_printf(bio_err,"string is too long, it needs to be less than  %d bytes long\n",n_max);
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +/* Check if the end of a string matches 'end' */
        +static int check_end(const char *str, const char *end)
        +{
        +	int elen, slen;	
        +	const char *tmp;
        +	elen = strlen(end);
        +	slen = strlen(str);
        +	if(elen > slen) return 1;
        +	tmp = str + slen - elen;
        +	return strcmp(tmp, end);
        +}
        +
        +static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
        +					long *pkeylen, char **palgnam,
        +					ENGINE *keygen_engine)
        +	{
        +	EVP_PKEY_CTX *gctx = NULL;
        +	EVP_PKEY *param = NULL;
        +	long keylen = -1;
        +	BIO *pbio = NULL;
        +	const char *paramfile = NULL;
        +
        +	if (gstr == NULL)
        +		{
        +		*pkey_type = EVP_PKEY_RSA;
        +		keylen = *pkeylen;
        +		}
        +	else if (gstr[0] >= '0' && gstr[0] <= '9')
        +		{
        +		*pkey_type = EVP_PKEY_RSA;
        +		keylen = atol(gstr);
        +		*pkeylen = keylen;
        +		}
        +	else if (!strncmp(gstr, "param:", 6))
        +		paramfile = gstr + 6;
        +	else
        +		{
        +		const char *p = strchr(gstr, ':');
        +		int len;
        +		ENGINE *tmpeng;
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +
        +		if (p)
        +			len = p - gstr;
        +		else
        +			len = strlen(gstr);
        +		/* The lookup of a the string will cover all engines so
        +		 * keep a note of the implementation.
        +		 */
        +
        +		ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
        +
        +		if (!ameth)
        +			{
        +			BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
        +			return NULL;
        +			}
        +
        +		EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
        +									ameth);
        +#ifndef OPENSSL_NO_ENGINE
        +		if (tmpeng)
        +			ENGINE_finish(tmpeng);
        +#endif
        +		if (*pkey_type == EVP_PKEY_RSA)
        +			{
        +			if (p)
        +				{
        +				keylen = atol(p + 1);
        +				*pkeylen = keylen;
        +				}
        +			}
        +		else if (p)
        +			paramfile = p + 1;
        +		}
        +
        +	if (paramfile)
        +		{
        +		pbio = BIO_new_file(paramfile, "r");
        +		if (!pbio)
        +			{
        +			BIO_printf(err, "Can't open parameter file %s\n",
        +					paramfile);
        +			return NULL;
        +			}
        +		param = PEM_read_bio_Parameters(pbio, NULL);
        +
        +		if (!param)
        +			{
        +			X509 *x;
        +			(void)BIO_reset(pbio);
        +			x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
        +			if (x)
        +				{
        +				param = X509_get_pubkey(x);
        +				X509_free(x);
        +				}
        +			}
        +
        +		BIO_free(pbio);
        +
        +		if (!param)
        +			{
        +			BIO_printf(err, "Error reading parameter file %s\n",
        +					paramfile);
        +			return NULL;
        +			}
        +		if (*pkey_type == -1)
        +			*pkey_type = EVP_PKEY_id(param);
        +		else if (*pkey_type != EVP_PKEY_base_id(param))
        +			{
        +			BIO_printf(err, "Key Type does not match parameters\n");
        +			EVP_PKEY_free(param);
        +			return NULL;
        +			}
        +		}
        +
        +	if (palgnam)
        +		{
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +		ENGINE *tmpeng;
        +		const char *anam;
        +		ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
        +		if (!ameth)
        +			{
        +			BIO_puts(err, "Internal error: can't find key algorithm\n");
        +			return NULL;
        +			}
        +		EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
        +		*palgnam = BUF_strdup(anam);
        +#ifndef OPENSSL_NO_ENGINE
        +		if (tmpeng)
        +			ENGINE_finish(tmpeng);
        +#endif
        +		}
        +
        +	if (param)
        +		{
        +		gctx = EVP_PKEY_CTX_new(param, keygen_engine);
        +		*pkeylen = EVP_PKEY_bits(param);
        +		EVP_PKEY_free(param);
        +		}
        +	else
        +		gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
        +
        +	if (!gctx)
        +		{
        +		BIO_puts(err, "Error allocating keygen context\n");
        +		ERR_print_errors(err);
        +		return NULL;
        +		}
        +
        +	if (EVP_PKEY_keygen_init(gctx) <= 0)
        +		{
        +		BIO_puts(err, "Error initializing keygen context\n");
        +		ERR_print_errors(err);
        +		return NULL;
        +		}
        +#ifndef OPENSSL_NO_RSA
        +	if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1))
        +		{
        +		if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0)
        +			{
        +			BIO_puts(err, "Error setting RSA keysize\n");
        +			ERR_print_errors(err);
        +			EVP_PKEY_CTX_free(gctx);
        +			return NULL;
        +			}
        +		}
        +#endif
        +
        +	return gctx;
        +	}
        +
        +static int genpkey_cb(EVP_PKEY_CTX *ctx)
        +	{
        +	char c='*';
        +	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
        +	int p;
        +	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(b,&c,1);
        +	(void)BIO_flush(b);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        +
        +static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
        +			const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
        +	{
        +	EVP_PKEY_CTX *pkctx = NULL;
        +	int i;
        +	EVP_MD_CTX_init(ctx);
        +	if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
        +		return 0;
        +	for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
        +		{
        +		char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
        +		if (pkey_ctrl_string(pkctx, sigopt) <= 0)
        +			{
        +			BIO_printf(err, "parameter error \"%s\"\n", sigopt);
        +			ERR_print_errors(bio_err);
        +			return 0;
        +			}
        +		}
        +	return 1;
        +	}
        +
        +int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
        +			STACK_OF(OPENSSL_STRING) *sigopts)
        +	{
        +	int rv;
        +	EVP_MD_CTX mctx;
        +	EVP_MD_CTX_init(&mctx);
        +	rv = do_sign_init(err, &mctx, pkey, md, sigopts);
        +	if (rv > 0)
        +		rv = X509_sign_ctx(x, &mctx);
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return rv > 0 ? 1 : 0;
        +	}
        +
        +
        +int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
        +			STACK_OF(OPENSSL_STRING) *sigopts)
        +	{
        +	int rv;
        +	EVP_MD_CTX mctx;
        +	EVP_MD_CTX_init(&mctx);
        +	rv = do_sign_init(err, &mctx, pkey, md, sigopts);
        +	if (rv > 0)
        +		rv = X509_REQ_sign_ctx(x, &mctx);
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return rv > 0 ? 1 : 0;
        +	}
        +		
        +	
        +
        +int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
        +			STACK_OF(OPENSSL_STRING) *sigopts)
        +	{
        +	int rv;
        +	EVP_MD_CTX mctx;
        +	EVP_MD_CTX_init(&mctx);
        +	rv = do_sign_init(err, &mctx, pkey, md, sigopts);
        +	if (rv > 0)
        +		rv = X509_CRL_sign_ctx(x, &mctx);
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return rv > 0 ? 1 : 0;
        +	}
        +		
        +	
        diff --git a/vendor/openssl/openssl/apps/req.pem b/vendor/openssl/openssl/apps/req.pem
        new file mode 100644
        index 000000000..5537df601
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/req.pem
        @@ -0,0 +1,11 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBlzCCAVcCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
        +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMORXJp
        +YyB0aGUgWW91bmcwge8wgaYGBSsOAwIMMIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZ
        +S4J1PHvPrm9MXj5ntVheDPkdmBDTncyaGAJcMjwsyB/GvLDGd6yGCw/8eF+09wIV
        +AK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjg
        +tWiJc/tpvcuzeuAayH89UofjAGueKjXDADiRffvSdhrNw5dkqdqlA0QAAkEAtUSo
        +84OekjitKGVjxLu0HvXck29pu+foad53vPKXAsuJdACj88BPqZ91Y9PIJf1GUh38
        +CuiHWi7z3cEDfZCyCKAAMAkGBSsOAwIbBQADLwAwLAIUTg8amKVBE9oqC5B75dDQ
        +Chy3LdQCFHKodGEj3LjuTzdm/RTe2KZL9Uzf
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/apps/rsa.c b/vendor/openssl/openssl/apps/rsa.c
        new file mode 100644
        index 000000000..a17708fe9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/rsa.c
        @@ -0,0 +1,450 @@
        +/* apps/rsa.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 <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/bn.h>
        +
        +#undef PROG
        +#define PROG	rsa_main
        +
        +/* -inform arg	- input format - default PEM (one of DER, NET or PEM)
        + * -outform arg - output format - default PEM
        + * -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + * -des		- encrypt output if PEM format with DES in cbc mode
        + * -des3	- encrypt output if PEM format
        + * -idea	- encrypt output if PEM format
        + * -seed	- encrypt output if PEM format
        + * -aes128	- encrypt output if PEM format
        + * -aes192	- encrypt output if PEM format
        + * -aes256	- encrypt output if PEM format
        + * -camellia128 - encrypt output if PEM format
        + * -camellia192 - encrypt output if PEM format
        + * -camellia256 - encrypt output if PEM format
        + * -text	- print a text version
        + * -modulus	- print the RSA key modulus
        + * -check	- verify key consistency
        + * -pubin	- Expect a public key in input file.
        + * -pubout	- Output a public key.
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int ret=1;
        +	RSA *rsa=NULL;
        +	int i,badops=0, sgckey=0;
        +	const EVP_CIPHER *enc=NULL;
        +	BIO *out=NULL;
        +	int informat,outformat,text=0,check=0,noout=0;
        +	int pubin = 0, pubout = 0;
        +	char *infile,*outfile,*prog;
        +	char *passargin = NULL, *passargout = NULL;
        +	char *passin = NULL, *passout = NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +	int modulus=0;
        +
        +	int pvk_encr = 2;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	infile=NULL;
        +	outfile=NULL;
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-sgckey") == 0)
        +			sgckey=1;
        +		else if (strcmp(*argv,"-pubin") == 0)
        +			pubin=1;
        +		else if (strcmp(*argv,"-pubout") == 0)
        +			pubout=1;
        +		else if (strcmp(*argv,"-RSAPublicKey_in") == 0)
        +			pubin = 2;
        +		else if (strcmp(*argv,"-RSAPublicKey_out") == 0)
        +			pubout = 2;
        +		else if (strcmp(*argv,"-pvk-strong") == 0)
        +			pvk_encr=2;
        +		else if (strcmp(*argv,"-pvk-weak") == 0)
        +			pvk_encr=1;
        +		else if (strcmp(*argv,"-pvk-none") == 0)
        +			pvk_encr=0;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text=1;
        +		else if (strcmp(*argv,"-modulus") == 0)
        +			modulus=1;
        +		else if (strcmp(*argv,"-check") == 0)
        +			check=1;
        +		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -inform arg     input format - one of DER NET PEM\n");
        +		BIO_printf(bio_err," -outform arg    output format - one of DER NET PEM\n");
        +		BIO_printf(bio_err," -in arg         input file\n");
        +		BIO_printf(bio_err," -sgckey         Use IIS SGC key format\n");
        +		BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
        +		BIO_printf(bio_err," -out arg        output file\n");
        +		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
        +		BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
        +		BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
        +#ifndef OPENSSL_NO_IDEA
        +		BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
        +		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
        +#endif
        +		BIO_printf(bio_err," -text           print the key in text\n");
        +		BIO_printf(bio_err," -noout          don't print key out\n");
        +		BIO_printf(bio_err," -modulus        print the RSA key modulus\n");
        +		BIO_printf(bio_err," -check          verify key consistency\n");
        +		BIO_printf(bio_err," -pubin          expect a public key in input file\n");
        +		BIO_printf(bio_err," -pubout         output a public key\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto end;
        +	}
        +
        +	if(check && pubin) {
        +		BIO_printf(bio_err, "Only private keys can be checked\n");
        +		goto end;
        +	}
        +
        +	out=BIO_new(BIO_s_file());
        +
        +	{
        +		EVP_PKEY	*pkey;
        +
        +		if (pubin)
        +			{
        +			int tmpformat=-1;
        +			if (pubin == 2)
        +				{
        +				if (informat == FORMAT_PEM)
        +					tmpformat = FORMAT_PEMRSA;
        +				else if (informat == FORMAT_ASN1)
        +					tmpformat = FORMAT_ASN1RSA;
        +				}
        +			else if (informat == FORMAT_NETSCAPE && sgckey)
        +				tmpformat = FORMAT_IISSGC;
        +			else
        +				tmpformat = informat;
        +					
        +			pkey = load_pubkey(bio_err, infile, tmpformat, 1,
        +				passin, e, "Public Key");
        +			}
        +		else
        +			pkey = load_key(bio_err, infile,
        +				(informat == FORMAT_NETSCAPE && sgckey ?
        +					FORMAT_IISSGC : informat), 1,
        +				passin, e, "Private Key");
        +
        +		if (pkey != NULL)
        +			rsa = EVP_PKEY_get1_RSA(pkey);
        +		EVP_PKEY_free(pkey);
        +	}
        +
        +	if (rsa == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		if (BIO_write_filename(out,outfile) <= 0)
        +			{
        +			perror(outfile);
        +			goto end;
        +			}
        +		}
        +
        +	if (text) 
        +		if (!RSA_print(out,rsa,0))
        +			{
        +			perror(outfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +	if (modulus)
        +		{
        +		BIO_printf(out,"Modulus=");
        +		BN_print(out,rsa->n);
        +		BIO_printf(out,"\n");
        +		}
        +
        +	if (check)
        +		{
        +		int r = RSA_check_key(rsa);
        +
        +		if (r == 1)
        +			BIO_printf(out,"RSA key ok\n");
        +		else if (r == 0)
        +			{
        +			unsigned long err;
        +
        +			while ((err = ERR_peek_error()) != 0 &&
        +				ERR_GET_LIB(err) == ERR_LIB_RSA &&
        +				ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
        +				ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE)
        +				{
        +				BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err));
        +				ERR_get_error(); /* remove e from error stack */
        +				}
        +			}
        +		
        +		if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +		
        +	if (noout)
        +		{
        +		ret = 0;
        +		goto end;
        +		}
        +	BIO_printf(bio_err,"writing RSA key\n");
        +	if 	(outformat == FORMAT_ASN1) {
        +		if(pubout || pubin) 
        +			{
        +			if (pubout == 2)
        +				i=i2d_RSAPublicKey_bio(out,rsa);
        +			else
        +				i=i2d_RSA_PUBKEY_bio(out,rsa);
        +			}
        +		else i=i2d_RSAPrivateKey_bio(out,rsa);
        +	}
        +#ifndef OPENSSL_NO_RC4
        +	else if (outformat == FORMAT_NETSCAPE)
        +		{
        +		unsigned char *p,*pp;
        +		int size;
        +
        +		i=1;
        +		size=i2d_RSA_NET(rsa,NULL,NULL, sgckey);
        +		if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL)
        +			{
        +			BIO_printf(bio_err,"Memory allocation failure\n");
        +			goto end;
        +			}
        +		pp=p;
        +		i2d_RSA_NET(rsa,&p,NULL, sgckey);
        +		BIO_write(out,(char *)pp,size);
        +		OPENSSL_free(pp);
        +		}
        +#endif
        +	else if (outformat == FORMAT_PEM) {
        +		if(pubout || pubin)
        +			{
        +			if (pubout == 2)
        +		    		i=PEM_write_bio_RSAPublicKey(out,rsa);
        +			else
        +		    		i=PEM_write_bio_RSA_PUBKEY(out,rsa);
        +			}
        +		else i=PEM_write_bio_RSAPrivateKey(out,rsa,
        +						enc,NULL,0,NULL,passout);
        +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
        +	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
        +		EVP_PKEY *pk;
        +		pk = EVP_PKEY_new();
        +		EVP_PKEY_set1_RSA(pk, rsa);
        +		if (outformat == FORMAT_PVK)
        +			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
        +		else if (pubin || pubout)
        +			i = i2b_PublicKey_bio(out, pk);
        +		else
        +			i = i2b_PrivateKey_bio(out, pk);
        +		EVP_PKEY_free(pk);
        +#endif
        +	} else	{
        +		BIO_printf(bio_err,"bad output format specified for outfile\n");
        +		goto end;
        +		}
        +	if (i <= 0)
        +		{
        +		BIO_printf(bio_err,"unable to write key\n");
        +		ERR_print_errors(bio_err);
        +		}
        +	else
        +		ret=0;
        +end:
        +	if(out != NULL) BIO_free_all(out);
        +	if(rsa != NULL) RSA_free(rsa);
        +	if(passin) OPENSSL_free(passin);
        +	if(passout) OPENSSL_free(passout);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +#else /* !OPENSSL_NO_RSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/rsa8192.pem b/vendor/openssl/openssl/apps/rsa8192.pem
        new file mode 100644
        index 000000000..946a6e543
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/rsa8192.pem
        @@ -0,0 +1,101 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +
        +MIISKAIBAAKCBAEAiQ2f1X6Bte1DKD0OoCBKEikzPW+5w3oXk3WwnE97Wxzy6wJZ
        +ebbZC3CZKKBnJeBMrysPf+lK+9+fP6Vm8bp1wvbcSIA59BDrX6irFSuM/bdnkbuF
        +MFlDjt+uVrxwoyqfPi2IPot1HQg3l5mdyBqcTWvbOnU2L9HZxJfPUCjfzdTMPrMY
        +55/A20XL7tlV2opEfwhy3uVlveQBM0DnZ3MUQfrk+lRRNWv7yE4ScbOfER9fjvOm
        +yJc3ZbOa3e+AMGGU9OqJ/fyOl0SGYyP2k23omy/idBV4uOs8QWdnAvq8UOzDdua3
        +tuf5Tn17XBurPJ8juwyPBNispkwwn8BjxAZVPhwUIcxFBg339IxJ9cW0WdVy4nNA
        +LWo/8Ahlf+kZNnFNGCPFytU9gGMLMhab9w/rLrwa9qNe4L8Fmu1JxONn1WfhMOKE
        +aFmycf2olJsYLgUIGYZrjnYu0p/7P3yhTOv8JIhmK+SzmA/I0xiQoF84rpaQzH2d
        +PvxICOA9oQSowou0gLuBSZWm6LiXirg1DZCziU46v33ErQlWM1dSyNaUSzihcV59
        +mVD0nmzboXH75lGiyiZlp8cLbozzoCwvk9rYqpUGSBzbAy0ECCpabGpzO2Ug+oDi
        +71e5z4WMpeoR4IS8MaOG/GsJnwaXhiB/gNYfK+8pRADVk5StEAZDE2alSuCbDs0z
        +d9zYr4/em5T9VZsLetxRE7pm/Es9yELuViz8/Tm0/8MVdmNYc/xZU1t6qYYFdyQ2
        +wlGDTiNPsjR8yXCkmBjKwqnuleu1X6LaZu3VPhEkXGcyFAquQUkSiMv0Yu74qAe0
        +bQ2v+jjZzP6AM9LUo89cW4Kd8SGD96BdNlAVPNMXoBcIOsZBwsOtETBd4KAyvkXE
        +Ob17u+PLl4UPnSxm9ypKZunUNFRPxtKUyjySYnvlGL+kTjAXrIrZwKJqIn0uhnfa
        +Ck3o7bU6yVMK22ODxy2/Vi3E0P6k5JLwnrF0VIOBqGhts66qo6mWDP8l6MZHARFd
        +pU+nofssVmr8tLKmMmjYGMM5GmKIXRNBs0ksTwFnKRs9AmpE5owC8tTSVdTAkGuS
        +os7QwLvyvNzq7BGJiVr0Iy3Dhsl1vzR35acNOrCsDl3DcCQONKJ2sVXV4pD3dBah
        +mG3sR/jHgjasffJJ35uiGoAua9dbT7HG/+D0z1SHYaVqH8zO4VZSOnGJh/P9rtxx
        +cckFDbiag/JMWig2lbnCjebTtp/BcUsK3TNaDOb7vb0LvbAeRJadd1EFu6PSlH3K
        +LykSUPm4UedvUU3cWjqkSY5lITFJkVaIYOv/EljYtK7p7kFZFTaEwMAWxgsXU3pQ
        +tTzVmq1gZ4vXPwcUq0zK50Frq0F7SQc21ZsunwIDAQABAoIEADuQAkDEpBausJsS
        +PgL1RXuzECPJJJCBxTE+2qx0FoY4hJICCWTORHGmU8nGPE3Ht0wBiNDsULw6KXl9
        +psmzYW6D3qRbpdQebky6fu/KZ5H0XTyGpJGomaXELH5hkwo2gdKB805LSXB+m7p0
        +9o96kSdMkpBLVGtf5iZ8W4rY2LsZmlI9f7taQHSLVt/M8HTz1mTnBRU92QO3zZW6
        +xVa+OrWaFl18u3ZeIaSh2X40tBK68cqstXVD0r2OWuXNKobcQeJW8/XABzBShZ0c
        +ihL0lzyqiN4uXrLu+Nbr22b+FU2OODy6dGk3U6/69NvI4piMCPlHsfhHOnFjd1ZW
        +RIVywyUlCtLNdcn11CchuRro+0J3c2Ba+i9Cl9r3qzT11xFEGF8/XLyUBBCB+uGf
        +1dR/xJQhCA7cXWWLXyI/semxcvTaGpImP6kiIl1MAjHjXZTSdvyw4JmfXyYGhSjI
        +P0mw3Xn7FXxJ/os9gOfNKz2nZHjr0q4sgWRYO+4vllkeL0GteZrg4oVaVpmZb7LH
        +77afhodLylhijlEtV5skfkPujbBLQk6E5Ez3U/huEt2NLg6guADmwxMxfBRliZO4
        +4Ex/td4cuggpEj3FGJV74qRvdvj/MF/uF7IxC/3WapPIsFBFH4zrJsUYt6u3L68I
        +/KC/bfioDeUR/8ANw1DNh+UsnPV3GJIwDkIJKdppi2uXPahJyJQQ8Inps53nn8Gg
        +GifS+HnOXNgMoKOJnZ9IDGjXpfjIs8dJNrGfDHF0mH30N2WARq2v/a3cNUC+f8Bq
        +HSKQ9YrZopktMunsut8u7ZYbTmjIqJpXCaM0CCrSlzSMTDHFSj2tzLk6+qnxeGxB
        +ZwIdShbdeK+0ETG91lE1e9RPQs/uXQP9+uCHJV0YpqQcA6pkCLYJfYpoSMu/Bafy
        +AgfVZz6l5tyEnV0wCcbopsQShc1k9xtTbYNF1h9AQHknj6zeDW4iZMvmVeh3RovT
        +52OA2R8oLyauF+QaG6x2wUjEx13SJlaBarJZ4seZIOJ+a8+oNzKsbgokXc2cyC9p
        +5FAZz1OsOb68o93qD1Xvl7bY97fq2q55L7G1XHPPLtZE5lGiLGDtnAuwY8UPrdpr
        +7Mv2yIxB7xVGurXyHb5PvusR88XED6HMPfLBG/55ENHTal7G5mRix+IWSBAIkxA5
        +KZ0j8r5Ng4+wELZhqFQai39799bIAyiV6CEz4kyDXlo0kSSexp8o4iz5sPq5vp6h
        +cCb7rdRw7uRnbXrHmXahxoB+ibXaurgV/6B2yurrU/UFoxEp2sHp8LXZGfF6ztY1
        +dMhSQAACK2vGy5yNagbkTHLgVaHicG5zavJBqzCE+lbPlCqhOUQPdOIwvjHNjdS/
        +DL3WV/ECggIBAMbW65wPk/i43nSyeZeYwcHtR1SUJqDXavYfBPC0VRhKz+7DVMFw
        +Nwnocn6gITABc445W1yl7U3uww+LGuDlSlFnd8WuiXpVYud9/jeNu6Mu4wvNsnWr
        +f4f4ua8CcS03GmqmcbROD2Z6by1AblCZ2UL1kv9cUX1FLVjPP1ESAGKoePt3BmZQ
        +J1uJfK8HilNT8dcUlj/5CBi2uHxttDhoG0sxXE/SVsG9OD/Pjme0mj7gdzc6Ztd+
        +TALuvpNQR4pRzfo5XWDZBcEYntcEE3PxYJB1+vnZ8509ew5/yLHTbLjFxIcx71zY
        +fhH0gM36Sz7mz37r0+E/QkRkc5bVIDC4LDnWmjpAde6QUx0d218ShNx6sJo4kt5c
        +Dd7tEVx8nuX8AIZYgwsOb382anLyFRkkmEdK3gRvwQ6SWR36Ez5L7/mHWODpLAX5
        +mVBKSG4/ccFbc633/g0xHw0Nwajir/klckdakuYPlwF0yAxJSKDLhmNctDhRmxjC
        +YP+fISkl5oTvFRzJH6HEyNu8M3ybRvmpPIjM5J5JpnB2IYbohYBR+T6/97C1DKrd
        +mzL5PjlrWm0c1/d7LlDoP65fOShDMmj2zCiBAHHOM0Alokx+v5LmMd8NJumZIwGJ
        +Rt5OpeMOhowz6j1AjYxYgV7PmJL6Ovpfb775od/aLaUbbwHz2uWIvfF7AoICAQCw
        +c7NaO7oJVLJClhYw6OCvjT6oqtgNVWaennnDiJgzY9lv5HEgV0MAG0eYuB3hvj+w
        +Y1P9DJxP1D+R+cshYrAFg8yU/3kaYVNI0Bl3ygX0eW1b/0HZTdocs+8kM/9PZQDR
        +WrKQoU5lHvqRt99dXlD4NWGI2YQtzdZ8iet9QLqnjwRZabgE96mF01qKisMnFcsh
        +KjT7ieheU4J15TZj/mdZRNK126d7e3q/rNj73e5EJ9tkYLcolSr4gpknUMJULSEi
        +JH1/Qx7C/mTAMRsN5SkOthnGq0djCNWfPv/3JV0H67Uf5krFlnwLebrgfTYoPPdo
        +yO7iBUNJzv6Qh22malLp4P8gzACkD7DGlSTnoB5cLwcjmDGg+i9WrUBbOiVTeQfZ
        +kOj1o+Tz35ndpq/DDUVlqliB9krcxva+QHeJPH53EGI+YVg1nD+s/vUDZ3mQMGX9
        +DQou2L8uU6RnWNv/BihGcL8QvS4Ty6QyPOUPpD3zc70JQAEcQk9BxQNaELgJX0IN
        +22cYn22tYvElew9G41OpDqzBRcfbdJmKXQ2HcroShutYJQRGUpAXHk24fy6JVkIU
        +ojF5U6cwextMja1ZIIZgh9eugIRUeIE7319nQNDzuXWjRCcoBLA25P7wnpHWDRpz
        +D9ovXCIvdja74lL5psqobV6L5+fbLPkSgXoImKR0LQKCAgAIC9Jk8kxumCyIVGCP
        +PeM5Uby9M3GMuKrfYsn0Y5e97+kSJF1dpojTodBgR2KQar6eVrvXt+8uZCcIjfx8
        +dUrYmHNEUJfHl4T1ESgkX1vkcpVFeQFruZDjk7EP3+1sgvpSroGTZkVBRFsTXbQZ
        +FuCv0Pgt1TKG+zGmklxhj3TsiRy8MEjWAxBUp++ftZJnZNI4feDGnfEx7tLwVhAg
        +6DWSiWDO6hgQpvOLwX5lu+0x9itc1MQsnDO/OqIDnBAJDN5k7cVVkfKlqbVjxgpz
        +eqUJs3yAd81f44kDQTCB4ahYocgeIGsrOqd/WoGL1EEPPo/O9wQP7VtlIRt8UwuG
        +bS18+a4sBUfAa56xYu/pnPo7YcubsgZfcSIujzFQqMpVTClJRnOnEuJ4J1+PXzRz
        +XAO9fs4VJ+CMEmgAyonUz4Xadxulnknlw//sO9VKgM69oFHCDHL/XamAAbqAdwvf
        +7R/+uy+Ol7romC0wMhb6SsIZazrvvH2mNtduAKZ638nAP1x/WbQp+6iVG7yJok7w
        +82Q7tO7baOePTXh12Rrt4mNPor0HLYxhra4GFgfqkumJ2Mz0esuZAozxJXFOq8ly
        +beo9CVtXP5zbT6qNpeNismX6PLICaev8t+1iOZSE56WSLtefuuj/cOVrTMNDz1Rr
        +pUkEVV2zjUSjlcScM538A9iL2QKCAgBLbBk0r6T0ihRsK9UucMxhnYEz/Vq+UEu9
        +70Vi1AciqEJv9nh4d3Q3HnH7EHANZxG4Jqzm1DYYVUQa9GfkTFeq88xFv/GW2hUM
        +YY8RSfRDrIeXNEOETCe37x2AHw25dRXlZtw+wARPau91y9+Y/FCl18NqCHfcUEin
        +ERjsf/eI2bPlODAlR2tZvZ7M60VBdqpN8cmV3zvI3e88z43xLfQlDyr1+v7a5Evy
        +lEJnXlSTI2o+vKxtl103vjMSwA1gh63K90gBVsJWXQDZueOzi8mB9UqNRfcMmOEe
        +4YHttTXPxeu0x+4cCRfam9zKShsVFgI28vRQ/ijl6qmbQ5gV8wqf18GV1j1L4z0P
        +lP6iVynDA4MMrug/w9DqPsHsfK0pwekeETfSj4y0xVXyjWZBfHG2ZBrS6mDTf+RG
        +LC4sJgR0hjdILLnUqIX7PzuhieBHRrjBcopwvcryVWRHnI7kslAS0+yHjiWc5oW3
        +x5mtlum4HzelNYuD9cAE/95P6CeSMfp9CyIE/KSX4VvsRm6gQVkoQRKMxnQIFQ3w
        +O5gl1l88vhjoo2HxYScgCp70BsDwiUNTqIR3NM+ZBHYFweVf3Gwz5LzHZT2rEZtD
        +6VXRP75Q/2wOLnqCO4bK4BUs6sqxcQZmOldruPkPynrY0oPfHHExjxZDvQu4/r80
        +Ls3n0L8yvQKCAgEAnYWS6EikwaQNpJEfiUnOlglgFz4EE1eVkrDbBY4J3oPU+doz
        +DrqmsvgpSZIAfd2MUbkN4pOMsMTjbeIYWDnZDa1RoctKs3FhwFPHwAjQpznab4mn
        +Bp81FMHM40qyb0NaNuFRwghdXvoQvBBX1p8oEnFzDRvTiuS/vTPTA8KDY8IeRp8R
        +oGzKHpfziNwq/URpqj7pwi9odNjGZvR2IwYw9jCLPIqaEbMoSOdI0mg4MoYyqP4q
        +nm7d4wqSDwrYxiXZ6f3nYpkhEY1lb0Wbksp1ig8sKSF4nDZRGK1RSfE+6gjBp94H
        +X/Wog6Zb6NC9ZpusTiDLvuIUXcyUJvmHiWjSNqiTv8jurlwEsgSwhziEQfqLrtdV
        +QI3PRMolBkD1iCk+HFE53r05LMf1bp3r4MS+naaQrLbIrl1kgDNGwVdgS+SCM7Bg
        +TwEgE67iOb2iIoUpon/NyP4LesMzvdpsu2JFlfz13PmmQ34mFI7tWvOb3NA5DP3c
        +46C6SaWI0TD9B11nJbHGTYN3Si9n0EBgoDJEXUKeh3km9O47dgvkSug4WzhYsvrE
        +rMlMLtKfp2w8HlMZpsUlToNCx6CI+tJrohzcs3BAVAbjFAXRKWGijB1rxwyDdHPv
        +I+/wJTNaRNPQ1M0SwtEL/zJd21y3KSPn4eL+GP3efhlDSjtlDvZqkdAUsU8=
        +-----END RSA PRIVATE KEY-----
        +
        diff --git a/vendor/openssl/openssl/apps/rsautl.c b/vendor/openssl/openssl/apps/rsautl.c
        new file mode 100644
        index 000000000..b01f004eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/rsautl.c
        @@ -0,0 +1,351 @@
        +/* rsautl.c */
        +/* Written by Dr Stephen N Henson (steve@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 <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_RSA
        +
        +#include "apps.h"
        +#include <string.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/rsa.h>
        +
        +#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;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine = NULL;
        +#endif
        +	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;
        +	char *passargin = NULL, *passin = NULL;
        +	int rsa_inlen, rsa_outlen = 0;
        +	int keysize;
        +
        +	int ret = 1;
        +
        +	argc--;
        +	argv++;
        +
        +	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +	ERR_load_crypto_strings();
        +	OpenSSL_add_all_algorithms();
        +	pad = RSA_PKCS1_PADDING;
        +	
        +	while(argc >= 1)
        +	{
        +		if (!strcmp(*argv,"-in")) {
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				infile= *(++argv);
        +		} else if (!strcmp(*argv,"-out")) {
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				outfile= *(++argv);
        +		} else if(!strcmp(*argv, "-inkey")) {
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				keyfile = *(++argv);
        +		} else if (!strcmp(*argv,"-passin")) {
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				passargin= *(++argv);
        +		} else if (strcmp(*argv,"-keyform") == 0) {
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				keyform=str2fmt(*(++argv));
        +#ifndef OPENSSL_NO_ENGINE
        +		} else if(!strcmp(*argv, "-engine")) {
        +			if (--argc < 1)
        +				badarg = 1;
        +			else
        +				engine = *(++argv);
        +#endif
        +		} 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, "-x931")) pad = RSA_X931_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;
        +	}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +	}
        +
        +/* 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, 0,
        +			passin, e, "Private Key");
        +		break;
        +
        +		case KEY_PUBKEY:
        +		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
        +			NULL, e, "Public Key");
        +		break;
        +
        +		case KEY_CERT:
        +		x = load_cert(bio_err, keyfile, keyform,
        +			NULL, e, "Certificate");
        +		if(x) {
        +			pkey = X509_get_pubkey(x);
        +			X509_free(x);
        +		}
        +		break;
        +	}
        +
        +	if(!pkey) {
        +		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 OPENSSL_SYS_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);
        +	if(passin) OPENSSL_free(passin);
        +	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, "-keyform arg    private key format - default PEM\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, "-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");
        +#ifndef OPENSSL_NO_ENGINE
        +	BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
        +	BIO_printf (bio_err, "-passin arg    pass phrase source\n");
        +#endif
        +
        +}
        +
        +#else /* !OPENSSL_NO_RSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/s1024key.pem b/vendor/openssl/openssl/apps/s1024key.pem
        new file mode 100644
        index 000000000..19e040357
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s1024key.pem
        @@ -0,0 +1,15 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV
        +S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP
        +pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB
        +AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0
        +dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY
        +bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E
        +Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq
        +zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM
        +6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf
        +QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD
        +dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M
        +0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv
        +nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/s1024req.pem b/vendor/openssl/openssl/apps/s1024req.pem
        new file mode 100644
        index 000000000..bb75e7eeb
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s1024req.pem
        @@ -0,0 +1,11 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBojCCAQsCAQAwZDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
        +GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSQwIgYDVQQDExtTZXJ2ZXIgdGVz
        +dCBjZXJ0ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALMR
        +9TwT5kZMa0ddXleG8zYuDfZ9dQiPJ1dvfgEZU9fqg3v5o1VL15ZrK9b/73+9RvRo
        +KqKUmukV6yAi1XZPxWGGM4T75dTPjq42lwxTvAcwQBdS58+nO2kWbxkSTa0Uq9p2
        +RJKg3yVvXWO69lWRKQ+UHrmkWFJ7hApKnongeuRjAgMBAAEwDQYJKoZIhvcNAQEE
        +BQADgYEAStHlk4pBbwiNeQ2/PKTPPXzITYC8Gn0XMbrU94e/6JIKiO7aArq9Espq
        +nrBSvC14dHcNl6NNvnkEKdQ7hAkcACfBbnOXA/oQvMBd4GD78cH3k0jVDoVUEjil
        +frLfWlckW6WzpTktt0ZPDdAjJCmKVh0ABHimi7Bo9FC3wIGIe5M=
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/apps/s512-key.pem b/vendor/openssl/openssl/apps/s512-key.pem
        new file mode 100644
        index 000000000..0e3ff2d37
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s512-key.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
        +TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
        +OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
        +gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
        +rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
        +PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
        +vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/s512-req.pem b/vendor/openssl/openssl/apps/s512-req.pem
        new file mode 100644
        index 000000000..ea314be55
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s512-req.pem
        @@ -0,0 +1,8 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBGzCBxgIBADBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEa
        +MBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0
        +IGNlcnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8S
        +MVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8E
        +y2//Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAANBAAB+uQi+qwn6qRSHB8EUTvsm
        +5TNTHzYDeN39nyIbZNX2s0se3Srn2Bxft5YCwD3moFZ9QoyDHxE0h6qLX5yjD+8=
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/apps/s_apps.h b/vendor/openssl/openssl/apps/s_apps.h
        new file mode 100644
        index 000000000..820e5c581
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s_apps.h
        @@ -0,0 +1,176 @@
        +/* apps/s_apps.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */
        +#include <sys/types.h>
        +#endif
        +#include <openssl/opensslconf.h>
        +
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
        +#include <conio.h>
        +#endif
        +
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
        +#define _kbhit kbhit
        +#endif
        +
        +#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET)
        +/* VAX C does not defined fd_set and friends, but it's actually quite simple */
        +/* These definitions are borrowed from SOCKETSHR.	/Richard Levitte */
        +#define MAX_NOFILE	32
        +#define	NBBY		 8		/* number of bits in a byte	*/
        +
        +#ifndef	FD_SETSIZE
        +#define	FD_SETSIZE	MAX_NOFILE
        +#endif	/* FD_SETSIZE */
        +
        +/* How many things we'll allow select to use. 0 if unlimited */
        +#define MAXSELFD	MAX_NOFILE
        +typedef int	fd_mask;	/* int here! VMS prototypes int, not long */
        +#define NFDBITS	(sizeof(fd_mask) * NBBY)	/* bits per mask (power of 2!)*/
        +#define NFDSHIFT 5				/* Shift based on above */
        +
        +typedef fd_mask fd_set;
        +#define	FD_SET(n, p)	(*(p) |= (1 << ((n) % NFDBITS)))
        +#define	FD_CLR(n, p)	(*(p) &= ~(1 << ((n) % NFDBITS)))
        +#define	FD_ISSET(n, p)	(*(p) & (1 << ((n) % NFDBITS)))
        +#define FD_ZERO(p)	memset((char *)(p), 0, sizeof(*(p)))
        +#endif
        +
        +#define PORT            4433
        +#define PORT_STR        "4433"
        +#define PROTOCOL        "tcp"
        +
        +int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context);
        +#ifdef HEADER_X509_H
        +int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
        +#endif
        +#ifdef HEADER_SSL_H
        +int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
        +int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
        +#endif
        +int init_client(int *sock, char *server, int port, int type);
        +int should_retry(int i);
        +int extract_port(char *str, short *port_ptr);
        +int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p);
        +
        +long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
        +				   int argi, long argl, long ret);
        +
        +#ifdef HEADER_SSL_H
        +void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret);
        +void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
        +void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
        +					unsigned char *data, int len,
        +					void *arg);
        +#endif
        +
        +int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len);
        +int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len);
        diff --git a/vendor/openssl/openssl/apps/s_cb.c b/vendor/openssl/openssl/apps/s_cb.c
        new file mode 100644
        index 000000000..84c3b447c
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s_cb.c
        @@ -0,0 +1,930 @@
        +/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
        +/* 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-2006 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 <stdio.h>
        +#include <stdlib.h>
        +#define USE_SOCKETS
        +#define NON_MAIN
        +#include "apps.h"
        +#undef NON_MAIN
        +#undef USE_SOCKETS
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include "s_apps.h"
        +
        +#define	COOKIE_SECRET_LENGTH	16
        +
        +int verify_depth=0;
        +int verify_error=X509_V_OK;
        +int verify_return_error=0;
        +unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
        +int cookie_initialized=0;
        +
        +int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	X509 *err_cert;
        +	int err,depth;
        +
        +	err_cert=X509_STORE_CTX_get_current_cert(ctx);
        +	err=	X509_STORE_CTX_get_error(ctx);
        +	depth=	X509_STORE_CTX_get_error_depth(ctx);
        +
        +	BIO_printf(bio_err,"depth=%d ",depth);
        +	if (err_cert)
        +		{
        +		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
        +					0, XN_FLAG_ONELINE);
        +		BIO_puts(bio_err, "\n");
        +		}
        +	else
        +		BIO_puts(bio_err, "<no cert>\n");
        +	if (!ok)
        +		{
        +		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
        +			X509_verify_cert_error_string(err));
        +		if (verify_depth >= depth)
        +			{
        +			if (!verify_return_error)
        +				ok=1;
        +			verify_error=X509_V_OK;
        +			}
        +		else
        +			{
        +			ok=0;
        +			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
        +			}
        +		}
        +	switch (err)
        +		{
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +		BIO_puts(bio_err,"issuer= ");
        +		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
        +					0, XN_FLAG_ONELINE);
        +		BIO_puts(bio_err, "\n");
        +		break;
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +		BIO_printf(bio_err,"notBefore=");
        +		ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +		BIO_printf(bio_err,"notAfter=");
        +		ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +	case X509_V_ERR_NO_EXPLICIT_POLICY:
        +		policies_print(bio_err, ctx);
        +		break;
        +		}
        +	if (err == X509_V_OK && ok == 2)
        +		policies_print(bio_err, ctx);
        +
        +	BIO_printf(bio_err,"verify return:%d\n",ok);
        +	return(ok);
        +	}
        +
        +int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
        +	{
        +	if (cert_file != NULL)
        +		{
        +		/*
        +		SSL *ssl;
        +		X509 *x509;
        +		*/
        +
        +		if (SSL_CTX_use_certificate_file(ctx,cert_file,
        +			SSL_FILETYPE_PEM) <= 0)
        +			{
        +			BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
        +			ERR_print_errors(bio_err);
        +			return(0);
        +			}
        +		if (key_file == NULL) key_file=cert_file;
        +		if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
        +			SSL_FILETYPE_PEM) <= 0)
        +			{
        +			BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
        +			ERR_print_errors(bio_err);
        +			return(0);
        +			}
        +
        +		/*
        +		In theory this is no longer needed 
        +		ssl=SSL_new(ctx);
        +		x509=SSL_get_certificate(ssl);
        +
        +		if (x509 != NULL) {
        +			EVP_PKEY *pktmp;
        +			pktmp = X509_get_pubkey(x509);
        +			EVP_PKEY_copy_parameters(pktmp,
        +						SSL_get_privatekey(ssl));
        +			EVP_PKEY_free(pktmp);
        +		}
        +		SSL_free(ssl);
        +		*/
        +
        +		/* If we are using DSA, we can copy the parameters from
        +		 * the private key */
        +
        +
        +		/* Now we know that a key and cert have been set against
        +		 * the SSL context */
        +		if (!SSL_CTX_check_private_key(ctx))
        +			{
        +			BIO_printf(bio_err,"Private key does not match the certificate public key\n");
        +			return(0);
        +			}
        +		}
        +	return(1);
        +	}
        +
        +int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
        +	{
        +	if (cert ==  NULL)
        +		return 1;
        +	if (SSL_CTX_use_certificate(ctx,cert) <= 0)
        +		{
        +		BIO_printf(bio_err,"error setting certificate\n");
        +		ERR_print_errors(bio_err);
        +		return 0;
        +		}
        +	if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
        +		{
        +		BIO_printf(bio_err,"error setting private key\n");
        +		ERR_print_errors(bio_err);
        +		return 0;
        +		}
        +
        +		
        +		/* Now we know that a key and cert have been set against
        +		 * the SSL context */
        +	if (!SSL_CTX_check_private_key(ctx))
        +		{
        +		BIO_printf(bio_err,"Private key does not match the certificate public key\n");
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
        +				   int argi, long argl, long ret)
        +	{
        +	BIO *out;
        +
        +	out=(BIO *)BIO_get_callback_arg(bio);
        +	if (out == NULL) return(ret);
        +
        +	if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
        +		{
        +		BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
        + 			(void *)bio,argp,(unsigned long)argi,ret,ret);
        +		BIO_dump(out,argp,(int)ret);
        +		return(ret);
        +		}
        +	else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
        +		{
        +		BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
        +			(void *)bio,argp,(unsigned long)argi,ret,ret);
        +		BIO_dump(out,argp,(int)ret);
        +		}
        +	return(ret);
        +	}
        +
        +void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
        +	{
        +	const char *str;
        +	int w;
        +
        +	w=where& ~SSL_ST_MASK;
        +
        +	if (w & SSL_ST_CONNECT) str="SSL_connect";
        +	else if (w & SSL_ST_ACCEPT) str="SSL_accept";
        +	else str="undefined";
        +
        +	if (where & SSL_CB_LOOP)
        +		{
        +		BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
        +		}
        +	else if (where & SSL_CB_ALERT)
        +		{
        +		str=(where & SSL_CB_READ)?"read":"write";
        +		BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
        +			str,
        +			SSL_alert_type_string_long(ret),
        +			SSL_alert_desc_string_long(ret));
        +		}
        +	else if (where & SSL_CB_EXIT)
        +		{
        +		if (ret == 0)
        +			BIO_printf(bio_err,"%s:failed in %s\n",
        +				str,SSL_state_string_long(s));
        +		else if (ret < 0)
        +			{
        +			BIO_printf(bio_err,"%s:error in %s\n",
        +				str,SSL_state_string_long(s));
        +			}
        +		}
        +	}
        +
        +
        +void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
        +	{
        +	BIO *bio = arg;
        +	const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= "";
        +	
        +	str_write_p = write_p ? ">>>" : "<<<";
        +
        +	switch (version)
        +		{
        +	case SSL2_VERSION:
        +		str_version = "SSL 2.0";
        +		break;
        +	case SSL3_VERSION:
        +		str_version = "SSL 3.0 ";
        +		break;
        +	case TLS1_VERSION:
        +		str_version = "TLS 1.0 ";
        +		break;
        +	case TLS1_1_VERSION:
        +		str_version = "TLS 1.1 ";
        +		break;
        +	case TLS1_2_VERSION:
        +		str_version = "TLS 1.2 ";
        +		break;
        +	case DTLS1_VERSION:
        +		str_version = "DTLS 1.0 ";
        +		break;
        +	case DTLS1_BAD_VER:
        +		str_version = "DTLS 1.0 (bad) ";
        +		break;
        +	default:
        +		str_version = "???";
        +		}
        +
        +	if (version == SSL2_VERSION)
        +		{
        +		str_details1 = "???";
        +
        +		if (len > 0)
        +			{
        +			switch (((const unsigned char*)buf)[0])
        +				{
        +				case 0:
        +					str_details1 = ", ERROR:";
        +					str_details2 = " ???";
        +					if (len >= 3)
        +						{
        +						unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2];
        +						
        +						switch (err)
        +							{
        +						case 0x0001:
        +							str_details2 = " NO-CIPHER-ERROR";
        +							break;
        +						case 0x0002:
        +							str_details2 = " NO-CERTIFICATE-ERROR";
        +							break;
        +						case 0x0004:
        +							str_details2 = " BAD-CERTIFICATE-ERROR";
        +							break;
        +						case 0x0006:
        +							str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
        +							break;
        +							}
        +						}
        +
        +					break;
        +				case 1:
        +					str_details1 = ", CLIENT-HELLO";
        +					break;
        +				case 2:
        +					str_details1 = ", CLIENT-MASTER-KEY";
        +					break;
        +				case 3:
        +					str_details1 = ", CLIENT-FINISHED";
        +					break;
        +				case 4:
        +					str_details1 = ", SERVER-HELLO";
        +					break;
        +				case 5:
        +					str_details1 = ", SERVER-VERIFY";
        +					break;
        +				case 6:
        +					str_details1 = ", SERVER-FINISHED";
        +					break;
        +				case 7:
        +					str_details1 = ", REQUEST-CERTIFICATE";
        +					break;
        +				case 8:
        +					str_details1 = ", CLIENT-CERTIFICATE";
        +					break;
        +				}
        +			}
        +		}
        +
        +	if (version == SSL3_VERSION ||
        +	    version == TLS1_VERSION ||
        +	    version == TLS1_1_VERSION ||
        +	    version == TLS1_2_VERSION ||
        +	    version == DTLS1_VERSION ||
        +	    version == DTLS1_BAD_VER)
        +		{
        +		switch (content_type)
        +			{
        +		case 20:
        +			str_content_type = "ChangeCipherSpec";
        +			break;
        +		case 21:
        +			str_content_type = "Alert";
        +			break;
        +		case 22:
        +			str_content_type = "Handshake";
        +			break;
        +			}
        +
        +		if (content_type == 21) /* Alert */
        +			{
        +			str_details1 = ", ???";
        +			
        +			if (len == 2)
        +				{
        +				switch (((const unsigned char*)buf)[0])
        +					{
        +				case 1:
        +					str_details1 = ", warning";
        +					break;
        +				case 2:
        +					str_details1 = ", fatal";
        +					break;
        +					}
        +
        +				str_details2 = " ???";
        +				switch (((const unsigned char*)buf)[1])
        +					{
        +				case 0:
        +					str_details2 = " close_notify";
        +					break;
        +				case 10:
        +					str_details2 = " unexpected_message";
        +					break;
        +				case 20:
        +					str_details2 = " bad_record_mac";
        +					break;
        +				case 21:
        +					str_details2 = " decryption_failed";
        +					break;
        +				case 22:
        +					str_details2 = " record_overflow";
        +					break;
        +				case 30:
        +					str_details2 = " decompression_failure";
        +					break;
        +				case 40:
        +					str_details2 = " handshake_failure";
        +					break;
        +				case 42:
        +					str_details2 = " bad_certificate";
        +					break;
        +				case 43:
        +					str_details2 = " unsupported_certificate";
        +					break;
        +				case 44:
        +					str_details2 = " certificate_revoked";
        +					break;
        +				case 45:
        +					str_details2 = " certificate_expired";
        +					break;
        +				case 46:
        +					str_details2 = " certificate_unknown";
        +					break;
        +				case 47:
        +					str_details2 = " illegal_parameter";
        +					break;
        +				case 48:
        +					str_details2 = " unknown_ca";
        +					break;
        +				case 49:
        +					str_details2 = " access_denied";
        +					break;
        +				case 50:
        +					str_details2 = " decode_error";
        +					break;
        +				case 51:
        +					str_details2 = " decrypt_error";
        +					break;
        +				case 60:
        +					str_details2 = " export_restriction";
        +					break;
        +				case 70:
        +					str_details2 = " protocol_version";
        +					break;
        +				case 71:
        +					str_details2 = " insufficient_security";
        +					break;
        +				case 80:
        +					str_details2 = " internal_error";
        +					break;
        +				case 90:
        +					str_details2 = " user_canceled";
        +					break;
        +				case 100:
        +					str_details2 = " no_renegotiation";
        +					break;
        +				case 110:
        +					str_details2 = " unsupported_extension";
        +					break;
        +				case 111:
        +					str_details2 = " certificate_unobtainable";
        +					break;
        +				case 112:
        +					str_details2 = " unrecognized_name";
        +					break;
        +				case 113:
        +					str_details2 = " bad_certificate_status_response";
        +					break;
        +				case 114:
        +					str_details2 = " bad_certificate_hash_value";
        +					break;
        +				case 115:
        +					str_details2 = " unknown_psk_identity";
        +					break;
        +					}
        +				}
        +			}
        +		
        +		if (content_type == 22) /* Handshake */
        +			{
        +			str_details1 = "???";
        +
        +			if (len > 0)
        +				{
        +				switch (((const unsigned char*)buf)[0])
        +					{
        +				case 0:
        +					str_details1 = ", HelloRequest";
        +					break;
        +				case 1:
        +					str_details1 = ", ClientHello";
        +					break;
        +				case 2:
        +					str_details1 = ", ServerHello";
        +					break;
        +				case 3:
        +					str_details1 = ", HelloVerifyRequest";
        +					break;
        +				case 11:
        +					str_details1 = ", Certificate";
        +					break;
        +				case 12:
        +					str_details1 = ", ServerKeyExchange";
        +					break;
        +				case 13:
        +					str_details1 = ", CertificateRequest";
        +					break;
        +				case 14:
        +					str_details1 = ", ServerHelloDone";
        +					break;
        +				case 15:
        +					str_details1 = ", CertificateVerify";
        +					break;
        +				case 16:
        +					str_details1 = ", ClientKeyExchange";
        +					break;
        +				case 20:
        +					str_details1 = ", Finished";
        +					break;
        +					}
        +				}
        +			}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +		if (content_type == 24) /* Heartbeat */
        +			{
        +			str_details1 = ", Heartbeat";
        +			
        +			if (len > 0)
        +				{
        +				switch (((const unsigned char*)buf)[0])
        +					{
        +				case 1:
        +					str_details1 = ", HeartbeatRequest";
        +					break;
        +				case 2:
        +					str_details1 = ", HeartbeatResponse";
        +					break;
        +					}
        +				}
        +			}
        +#endif
        +		}
        +
        +	BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2);
        +
        +	if (len > 0)
        +		{
        +		size_t num, i;
        +		
        +		BIO_printf(bio, "   ");
        +		num = len;
        +#if 0
        +		if (num > 16)
        +			num = 16;
        +#endif
        +		for (i = 0; i < num; i++)
        +			{
        +			if (i % 16 == 0 && i > 0)
        +				BIO_printf(bio, "\n   ");
        +			BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]);
        +			}
        +		if (i < len)
        +			BIO_printf(bio, " ...");
        +		BIO_printf(bio, "\n");
        +		}
        +	(void)BIO_flush(bio);
        +	}
        +
        +void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
        +					unsigned char *data, int len,
        +					void *arg)
        +	{
        +	BIO *bio = arg;
        +	char *extname;
        +
        +	switch(type)
        +		{
        +		case TLSEXT_TYPE_server_name:
        +		extname = "server name";
        +		break;
        +
        +		case TLSEXT_TYPE_max_fragment_length:
        +		extname = "max fragment length";
        +		break;
        +
        +		case TLSEXT_TYPE_client_certificate_url:
        +		extname = "client certificate URL";
        +		break;
        +
        +		case TLSEXT_TYPE_trusted_ca_keys:
        +		extname = "trusted CA keys";
        +		break;
        +
        +		case TLSEXT_TYPE_truncated_hmac:
        +		extname = "truncated HMAC";
        +		break;
        +
        +		case TLSEXT_TYPE_status_request:
        +		extname = "status request";
        +		break;
        +
        +		case TLSEXT_TYPE_user_mapping:
        +		extname = "user mapping";
        +		break;
        +
        +		case TLSEXT_TYPE_client_authz:
        +		extname = "client authz";
        +		break;
        +
        +		case TLSEXT_TYPE_server_authz:
        +		extname = "server authz";
        +		break;
        +
        +		case TLSEXT_TYPE_cert_type:
        +		extname = "cert type";
        +		break;
        +
        +		case TLSEXT_TYPE_elliptic_curves:
        +		extname = "elliptic curves";
        +		break;
        +
        +		case TLSEXT_TYPE_ec_point_formats:
        +		extname = "EC point formats";
        +		break;
        +
        +		case TLSEXT_TYPE_srp:
        +		extname = "SRP";
        +		break;
        +
        +		case TLSEXT_TYPE_signature_algorithms:
        +		extname = "signature algorithms";
        +		break;
        +
        +		case TLSEXT_TYPE_use_srtp:
        +		extname = "use SRTP";
        +		break;
        +
        +		case TLSEXT_TYPE_heartbeat:
        +		extname = "heartbeat";
        +		break;
        +
        +		case TLSEXT_TYPE_session_ticket:
        +		extname = "session ticket";
        +		break;
        +
        +		case TLSEXT_TYPE_renegotiate: 
        +		extname = "renegotiation info";
        +		break;
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +		case TLSEXT_TYPE_opaque_prf_input:
        +		extname = "opaque PRF input";
        +		break;
        +#endif
        +#ifdef TLSEXT_TYPE_next_proto_neg
        +		case TLSEXT_TYPE_next_proto_neg:
        +		extname = "next protocol";
        +		break;
        +#endif
        +
        +		default:
        +		extname = "unknown";
        +		break;
        +
        +		}
        +	
        +	BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
        +			client_server ? "server": "client",
        +			extname, type, len);
        +	BIO_dump(bio, (char *)data, len);
        +	(void)BIO_flush(bio);
        +	}
        +
        +int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
        +	{
        +	unsigned char *buffer, result[EVP_MAX_MD_SIZE];
        +	unsigned int length, resultlength;
        +	union {
        +		struct sockaddr sa;
        +		struct sockaddr_in s4;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 s6;
        +#endif
        +	} peer;
        +
        +	/* Initialize a random secret */
        +	if (!cookie_initialized)
        +		{
        +		if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH))
        +			{
        +			BIO_printf(bio_err,"error setting random cookie secret\n");
        +			return 0;
        +			}
        +		cookie_initialized = 1;
        +		}
        +
        +	/* Read peer information */
        +	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
        +
        +	/* Create buffer with peer's address and port */
        +	length = 0;
        +	switch (peer.sa.sa_family)
        +		{
        +	case AF_INET:
        +		length += sizeof(struct in_addr);
        +		length += sizeof(peer.s4.sin_port);
        +		break;
        +#if OPENSSL_USE_IPV6
        +	case AF_INET6:
        +		length += sizeof(struct in6_addr);
        +		length += sizeof(peer.s6.sin6_port);
        +		break;
        +#endif
        +	default:
        +		OPENSSL_assert(0);
        +		break;
        +		}
        +	buffer = OPENSSL_malloc(length);
        +
        +	if (buffer == NULL)
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		return 0;
        +		}
        +
        +	switch (peer.sa.sa_family)
        +		{
        +	case AF_INET:
        +		memcpy(buffer,
        +		       &peer.s4.sin_port,
        +		       sizeof(peer.s4.sin_port));
        +		memcpy(buffer + sizeof(peer.s4.sin_port),
        +		       &peer.s4.sin_addr,
        +		       sizeof(struct in_addr));
        +		break;
        +#if OPENSSL_USE_IPV6
        +	case AF_INET6:
        +		memcpy(buffer,
        +		       &peer.s6.sin6_port,
        +		       sizeof(peer.s6.sin6_port));
        +		memcpy(buffer + sizeof(peer.s6.sin6_port),
        +		       &peer.s6.sin6_addr,
        +		       sizeof(struct in6_addr));
        +		break;
        +#endif
        +	default:
        +		OPENSSL_assert(0);
        +		break;
        +		}
        +
        +	/* Calculate HMAC of buffer using the secret */
        +	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
        +	     buffer, length, result, &resultlength);
        +	OPENSSL_free(buffer);
        +
        +	memcpy(cookie, result, resultlength);
        +	*cookie_len = resultlength;
        +
        +	return 1;
        +	}
        +
        +int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
        +	{
        +	unsigned char *buffer, result[EVP_MAX_MD_SIZE];
        +	unsigned int length, resultlength;
        +	union {
        +		struct sockaddr sa;
        +		struct sockaddr_in s4;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 s6;
        +#endif
        +	} peer;
        +
        +	/* If secret isn't initialized yet, the cookie can't be valid */
        +	if (!cookie_initialized)
        +		return 0;
        +
        +	/* Read peer information */
        +	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
        +
        +	/* Create buffer with peer's address and port */
        +	length = 0;
        +	switch (peer.sa.sa_family)
        +		{
        +	case AF_INET:
        +		length += sizeof(struct in_addr);
        +		length += sizeof(peer.s4.sin_port);
        +		break;
        +#if OPENSSL_USE_IPV6
        +	case AF_INET6:
        +		length += sizeof(struct in6_addr);
        +		length += sizeof(peer.s6.sin6_port);
        +		break;
        +#endif
        +	default:
        +		OPENSSL_assert(0);
        +		break;
        +		}
        +	buffer = OPENSSL_malloc(length);
        +	
        +	if (buffer == NULL)
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		return 0;
        +		}
        +
        +	switch (peer.sa.sa_family)
        +		{
        +	case AF_INET:
        +		memcpy(buffer,
        +		       &peer.s4.sin_port,
        +		       sizeof(peer.s4.sin_port));
        +		memcpy(buffer + sizeof(peer.s4.sin_port),
        +		       &peer.s4.sin_addr,
        +		       sizeof(struct in_addr));
        +		break;
        +#if OPENSSL_USE_IPV6
        +	case AF_INET6:
        +		memcpy(buffer,
        +		       &peer.s6.sin6_port,
        +		       sizeof(peer.s6.sin6_port));
        +		memcpy(buffer + sizeof(peer.s6.sin6_port),
        +		       &peer.s6.sin6_addr,
        +		       sizeof(struct in6_addr));
        +		break;
        +#endif
        +	default:
        +		OPENSSL_assert(0);
        +		break;
        +		}
        +
        +	/* Calculate HMAC of buffer using the secret */
        +	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
        +	     buffer, length, result, &resultlength);
        +	OPENSSL_free(buffer);
        +
        +	if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
        +		return 1;
        +
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/apps/s_client.c b/vendor/openssl/openssl/apps/s_client.c
        new file mode 100644
        index 000000000..3ba660560
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s_client.c
        @@ -0,0 +1,2151 @@
        +/* apps/s_client.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-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <assert.h>
        +#include <ctype.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/e_os2.h>
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +
        +/* With IPv6, it looks like Digital has mixed up the proper order of
        +   recursive header file inclusion, resulting in the compiler complaining
        +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
        +   is needed to have fileno() declared correctly...  So let's define u_int */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
        +#define __U_INT
        +typedef unsigned int u_int;
        +#endif
        +
        +#define USE_SOCKETS
        +#include "apps.h"
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/rand.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_SRP
        +#include <openssl/srp.h>
        +#endif
        +#include "s_apps.h"
        +#include "timeouts.h"
        +
        +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
        +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
        +#undef FIONBIO
        +#endif
        +
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +#include <fcntl.h>
        +#endif
        +
        +#undef PROG
        +#define PROG	s_client_main
        +
        +/*#define SSL_HOST_NAME	"www.netscape.com" */
        +/*#define SSL_HOST_NAME	"193.118.187.102" */
        +#define SSL_HOST_NAME	"localhost"
        +
        +/*#define TEST_CERT "client.pem" */ /* no default cert. */
        +
        +#undef BUFSIZZ
        +#define BUFSIZZ 1024*8
        +
        +extern int verify_depth;
        +extern int verify_error;
        +extern int verify_return_error;
        +
        +#ifdef FIONBIO
        +static int c_nbio=0;
        +#endif
        +static int c_Pause=0;
        +static int c_debug=0;
        +#ifndef OPENSSL_NO_TLSEXT
        +static int c_tlsextdebug=0;
        +static int c_status_req=0;
        +#endif
        +static int c_msg=0;
        +static int c_showcerts=0;
        +
        +static char *keymatexportlabel=NULL;
        +static int keymatexportlen=20;
        +
        +static void sc_usage(void);
        +static void print_stuff(BIO *berr,SSL *con,int full);
        +#ifndef OPENSSL_NO_TLSEXT
        +static int ocsp_resp_cb(SSL *s, void *arg);
        +#endif
        +static BIO *bio_c_out=NULL;
        +static int c_quiet=0;
        +static int c_ign_eof=0;
        +
        +#ifndef OPENSSL_NO_PSK
        +/* Default PSK identity and key */
        +static char *psk_identity="Client_identity";
        +/*char *psk_key=NULL;  by default PSK is not used */
        +
        +static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
        +	unsigned int max_identity_len, unsigned char *psk,
        +	unsigned int max_psk_len)
        +	{
        +	unsigned int psk_len = 0;
        +	int ret;
        +        BIGNUM *bn=NULL;
        +
        +	if (c_debug)
        +		BIO_printf(bio_c_out, "psk_client_cb\n");
        +	if (!hint)
        +                {
        +                /* no ServerKeyExchange message*/
        +		if (c_debug)
        +			BIO_printf(bio_c_out,"NULL received PSK identity hint, continuing anyway\n");
        +                }
        +        else if (c_debug)
        +		BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
        +
        +	/* lookup PSK identity and PSK key based on the given identity hint here */
        +	ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
        +	if (ret < 0 || (unsigned int)ret > max_identity_len)
        +		goto out_err;
        +	if (c_debug)
        +		BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret);
        +        ret=BN_hex2bn(&bn, psk_key);
        +        if (!ret)
        +                {
        +                BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
        +                if (bn)
        +                        BN_free(bn);
        +                return 0;
        +                }
        +
        +        if ((unsigned int)BN_num_bytes(bn) > max_psk_len)
        +                {
        +                BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
        +                        max_psk_len, BN_num_bytes(bn));
        +                BN_free(bn);
        +                return 0;
        +                }
        +
        +        psk_len=BN_bn2bin(bn, psk);
        +        BN_free(bn);
        +        if (psk_len == 0)
        +                goto out_err;
        +
        +	if (c_debug)
        +		BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
        +
        +        return psk_len;
        + out_err:
        +	if (c_debug)
        +		BIO_printf(bio_err, "Error in PSK client callback\n");
        +        return 0;
        +	}
        +#endif
        +
        +static void sc_usage(void)
        +	{
        +	BIO_printf(bio_err,"usage: s_client args\n");
        +	BIO_printf(bio_err,"\n");
        +	BIO_printf(bio_err," -host host     - use -connect instead\n");
        +	BIO_printf(bio_err," -port port     - use -connect instead\n");
        +	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
        +
        +	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
        +	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
        +	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
        +	BIO_printf(bio_err," -key arg      - Private key file to use, in cert file if\n");
        +	BIO_printf(bio_err,"                 not specified but cert file is.\n");
        +	BIO_printf(bio_err," -keyform arg  - key format (PEM or DER) PEM default\n");
        +	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
        +	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
        +	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
        +	BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
        +	BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
        +	BIO_printf(bio_err," -showcerts    - show all certificates in the chain\n");
        +	BIO_printf(bio_err," -debug        - extra output\n");
        +#ifdef WATT32
        +	BIO_printf(bio_err," -wdebug       - WATT-32 tcp debugging\n");
        +#endif
        +	BIO_printf(bio_err," -msg          - Show protocol messages\n");
        +	BIO_printf(bio_err," -nbio_test    - more ssl protocol testing\n");
        +	BIO_printf(bio_err," -state        - print the 'ssl' states\n");
        +#ifdef FIONBIO
        +	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
        +#endif
        +	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
        +	BIO_printf(bio_err," -quiet        - no s_client output\n");
        +	BIO_printf(bio_err," -ign_eof      - ignore input eof (default when -quiet)\n");
        +	BIO_printf(bio_err," -no_ign_eof   - don't ignore input eof\n");
        +#ifndef OPENSSL_NO_PSK
        +	BIO_printf(bio_err," -psk_identity arg - PSK identity\n");
        +	BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
        +# ifndef OPENSSL_NO_JPAKE
        +	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
        +# endif
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	BIO_printf(bio_err," -srpuser user     - SRP authentification for 'user'\n");
        +	BIO_printf(bio_err," -srppass arg      - password for 'user'\n");
        +	BIO_printf(bio_err," -srp_lateuser     - SRP username into second ClientHello message\n");
        +	BIO_printf(bio_err," -srp_moregroups   - Tolerate other than the known g N values.\n");
        +	BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N);
        +#endif
        +	BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
        +	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
        +	BIO_printf(bio_err," -tls1_2       - just use TLSv1.2\n");
        +	BIO_printf(bio_err," -tls1_1       - just use TLSv1.1\n");
        +	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
        +	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");    
        +	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
        +	BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
        +	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
        +	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences (only SSLv2)\n");
        +	BIO_printf(bio_err," -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
        +	BIO_printf(bio_err,"                 command to see what is available\n");
        +	BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
        +	BIO_printf(bio_err,"                 for those protocols that support it, where\n");
        +	BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
        +	BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
        +	BIO_printf(bio_err,"                 are supported.\n");
        +#ifndef OPENSSL_NO_ENGINE
        +	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
        +#endif
        +	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +	BIO_printf(bio_err," -sess_out arg - file to write SSL session to\n");
        +	BIO_printf(bio_err," -sess_in arg  - file to read SSL session from\n");
        +#ifndef OPENSSL_NO_TLSEXT
        +	BIO_printf(bio_err," -servername host  - Set TLS extension servername in ClientHello\n");
        +	BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
        +	BIO_printf(bio_err," -status           - request certificate status from server\n");
        +	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
        +# endif
        +#endif
        +	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
        +#ifndef OPENSSL_NO_SRTP
        +	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
        +#endif
        + 	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
        + 	BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
        +	}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +
        +/* This is a context that we pass to callbacks */
        +typedef struct tlsextctx_st {
        +   BIO * biodebug;
        +   int ack;
        +} tlsextctx;
        +
        +
        +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
        +	{
        +	tlsextctx * p = (tlsextctx *) arg;
        +	const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
        +	if (SSL_get_servername_type(s) != -1) 
        + 	        p->ack = !SSL_session_reused(s) && hn != NULL;
        +	else 
        +		BIO_printf(bio_err,"Can't use SSL_get_servername\n");
        +	
        +	return SSL_TLSEXT_ERR_OK;
        +	}
        +
        +#ifndef OPENSSL_NO_SRP
        +
        +/* This is a context that we pass to all callbacks */
        +typedef struct srp_arg_st
        +	{
        +	char *srppassin;
        +	char *srplogin;
        +	int msg;   /* copy from c_msg */
        +	int debug; /* copy from c_debug */
        +	int amp;   /* allow more groups */
        +	int strength /* minimal size for N */ ;
        +	} SRP_ARG;
        +
        +#define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
        +
        +static int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
        +	{
        +	BN_CTX *bn_ctx = BN_CTX_new();
        +	BIGNUM *p = BN_new();
        +	BIGNUM *r = BN_new();
        +	int ret =
        +		g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
        +		BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
        +		p != NULL && BN_rshift1(p, N) &&
        +
        +		/* p = (N-1)/2 */
        +		BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
        +		r != NULL &&
        +
        +		/* verify g^((N-1)/2) == -1 (mod N) */
        +		BN_mod_exp(r, g, p, N, bn_ctx) &&
        +		BN_add_word(r, 1) &&
        +		BN_cmp(r, N) == 0;
        +
        +	if(r)
        +		BN_free(r);
        +	if(p)
        +		BN_free(p);
        +	if(bn_ctx)
        +		BN_CTX_free(bn_ctx);
        +	return ret;
        +	}
        +
        +/* This callback is used here for two purposes:
        +   - extended debugging
        +   - making some primality tests for unknown groups
        +   The callback is only called for a non default group.
        +
        +   An application does not need the call back at all if
        +   only the stanard groups are used.  In real life situations, 
        +   client and server already share well known groups, 
        +   thus there is no need to verify them. 
        +   Furthermore, in case that a server actually proposes a group that
        +   is not one of those defined in RFC 5054, it is more appropriate 
        +   to add the group to a static list and then compare since 
        +   primality tests are rather cpu consuming.
        +*/
        +
        +static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
        +	{
        +	SRP_ARG *srp_arg = (SRP_ARG *)arg;
        +	BIGNUM *N = NULL, *g = NULL;
        +	if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
        +		return 0;
        +	if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1)
        +		{
        +    		BIO_printf(bio_err, "SRP parameters:\n"); 
        +		BIO_printf(bio_err,"\tN="); BN_print(bio_err,N);
        +		BIO_printf(bio_err,"\n\tg="); BN_print(bio_err,g);
        +		BIO_printf(bio_err,"\n");
        +		}
        +
        +	if (SRP_check_known_gN_param(g,N))
        +		return 1;
        +
        +	if (srp_arg->amp == 1)
        +		{
        +		if (srp_arg->debug)
        +			BIO_printf(bio_err, "SRP param N and g are not known params, going to check deeper.\n");
        +
        +/* The srp_moregroups is a real debugging feature.
        +   Implementors should rather add the value to the known ones.
        +   The minimal size has already been tested.
        +*/
        +		if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N,g))
        +			return 1;
        +		}	
        +	BIO_printf(bio_err, "SRP param N and g rejected.\n");
        +	return 0;
        +	}
        +
        +#define PWD_STRLEN 1024
        +
        +static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
        +	{
        +	SRP_ARG *srp_arg = (SRP_ARG *)arg;
        +	char *pass = (char *)OPENSSL_malloc(PWD_STRLEN+1);
        +	PW_CB_DATA cb_tmp;
        +	int l;
        +
        +	cb_tmp.password = (char *)srp_arg->srppassin;
        +	cb_tmp.prompt_info = "SRP user";
        +	if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp))<0)
        +		{
        +		BIO_printf (bio_err, "Can't read Password\n");
        +		OPENSSL_free(pass);
        +		return NULL;
        +		}
        +	*(pass+l)= '\0';
        +
        +	return pass;
        +	}
        +
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +	char *srtp_profiles = NULL;
        +#endif
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +/* This the context that we pass to next_proto_cb */
        +typedef struct tlsextnextprotoctx_st {
        +	unsigned char *data;
        +	unsigned short len;
        +	int status;
        +} tlsextnextprotoctx;
        +
        +static tlsextnextprotoctx next_proto;
        +
        +static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
        +	{
        +	tlsextnextprotoctx *ctx = arg;
        +
        +	if (!c_quiet)
        +		{
        +		/* We can assume that |in| is syntactically valid. */
        +		unsigned i;
        +		BIO_printf(bio_c_out, "Protocols advertised by server: ");
        +		for (i = 0; i < inlen; )
        +			{
        +			if (i)
        +				BIO_write(bio_c_out, ", ", 2);
        +			BIO_write(bio_c_out, &in[i + 1], in[i]);
        +			i += in[i] + 1;
        +			}
        +		BIO_write(bio_c_out, "\n", 1);
        +		}
        +
        +	ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
        +	return SSL_TLSEXT_ERR_OK;
        +	}
        +# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
        +#endif
        +
        +enum
        +{
        +	PROTO_OFF	= 0,
        +	PROTO_SMTP,
        +	PROTO_POP3,
        +	PROTO_IMAP,
        +	PROTO_FTP,
        +	PROTO_XMPP
        +};
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	unsigned int off=0, clr=0;
        +	SSL *con=NULL;
        +#ifndef OPENSSL_NO_KRB5
        +	KSSL_CTX *kctx;
        +#endif
        +	int s,k,width,state=0;
        +	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
        +	int cbuf_len,cbuf_off;
        +	int sbuf_len,sbuf_off;
        +	fd_set readfds,writefds;
        +	short port=PORT;
        +	int full_log=1;
        +	char *host=SSL_HOST_NAME;
        +	char *cert_file=NULL,*key_file=NULL;
        +	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
        +	char *passarg = NULL, *pass = NULL;
        +	X509 *cert = NULL;
        +	EVP_PKEY *key = NULL;
        +	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
        +	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
        +	int crlf=0;
        +	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
        +	SSL_CTX *ctx=NULL;
        +	int ret=1,in_init=1,i,nbio_test=0;
        +	int starttls_proto = PROTO_OFF;
        +	int prexit = 0;
        +	X509_VERIFY_PARAM *vpm = NULL;
        +	int badarg = 0;
        +	const SSL_METHOD *meth=NULL;
        +	int socket_type=SOCK_STREAM;
        +	BIO *sbio;
        +	char *inrand=NULL;
        +	int mbuf_len=0;
        +	struct timeval timeout, *timeoutp;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine_id=NULL;
        +	char *ssl_client_engine_id=NULL;
        +	ENGINE *ssl_client_engine=NULL;
        +#endif
        +	ENGINE *e=NULL;
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
        +	struct timeval tv;
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +	int stdin_set = 0;
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_TLSEXT
        +	char *servername = NULL; 
        +        tlsextctx tlsextcbp = 
        +        {NULL,0};
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	const char *next_proto_neg_in = NULL;
        +# endif
        +#endif
        +	char *sess_in = NULL;
        +	char *sess_out = NULL;
        +	struct sockaddr peer;
        +	int peerlen = sizeof(peer);
        +	int enable_timeouts = 0 ;
        +	long socket_mtu = 0;
        +#ifndef OPENSSL_NO_JPAKE
        +	char *jpake_secret = NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	char * srppass = NULL;
        +	int srp_lateuser = 0;
        +	SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
        +#endif
        +
        +	meth=SSLv23_client_method();
        +
        +	apps_startup();
        +	c_Pause=0;
        +	c_quiet=0;
        +	c_ign_eof=0;
        +	c_debug=0;
        +	c_msg=0;
        +	c_showcerts=0;
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
        +		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
        +		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		goto end;
        +		}
        +
        +	verify_depth=0;
        +	verify_error=X509_V_OK;
        +#ifdef FIONBIO
        +	c_nbio=0;
        +#endif
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if	(strcmp(*argv,"-host") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			host= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-port") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			port=atoi(*(++argv));
        +			if (port == 0) goto bad;
        +			}
        +		else if (strcmp(*argv,"-connect") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!extract_host_port(*(++argv),&host,NULL,&port))
        +				goto bad;
        +			}
        +		else if	(strcmp(*argv,"-verify") == 0)
        +			{
        +			verify=SSL_VERIFY_PEER;
        +			if (--argc < 1) goto bad;
        +			verify_depth=atoi(*(++argv));
        +			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
        +			}
        +		else if	(strcmp(*argv,"-cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			cert_file= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-sess_out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			sess_out = *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-sess_in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			sess_in = *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-certform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			cert_format = str2fmt(*(++argv));
        +			}
        +		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
        +			{
        +			if (badarg)
        +				goto bad;
        +			continue;
        +			}
        +		else if (strcmp(*argv,"-verify_return_error") == 0)
        +			verify_return_error = 1;
        +		else if	(strcmp(*argv,"-prexit") == 0)
        +			prexit=1;
        +		else if	(strcmp(*argv,"-crlf") == 0)
        +			crlf=1;
        +		else if	(strcmp(*argv,"-quiet") == 0)
        +			{
        +			c_quiet=1;
        +			c_ign_eof=1;
        +			}
        +		else if	(strcmp(*argv,"-ign_eof") == 0)
        +			c_ign_eof=1;
        +		else if	(strcmp(*argv,"-no_ign_eof") == 0)
        +			c_ign_eof=0;
        +		else if	(strcmp(*argv,"-pause") == 0)
        +			c_Pause=1;
        +		else if	(strcmp(*argv,"-debug") == 0)
        +			c_debug=1;
        +#ifndef OPENSSL_NO_TLSEXT
        +		else if	(strcmp(*argv,"-tlsextdebug") == 0)
        +			c_tlsextdebug=1;
        +		else if	(strcmp(*argv,"-status") == 0)
        +			c_status_req=1;
        +#endif
        +#ifdef WATT32
        +		else if (strcmp(*argv,"-wdebug") == 0)
        +			dbug_init();
        +#endif
        +		else if	(strcmp(*argv,"-msg") == 0)
        +			c_msg=1;
        +		else if	(strcmp(*argv,"-showcerts") == 0)
        +			c_showcerts=1;
        +		else if	(strcmp(*argv,"-nbio_test") == 0)
        +			nbio_test=1;
        +		else if	(strcmp(*argv,"-state") == 0)
        +			state=1;
        +#ifndef OPENSSL_NO_PSK
        +                else if (strcmp(*argv,"-psk_identity") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			psk_identity=*(++argv);
        +			}
        +                else if (strcmp(*argv,"-psk") == 0)
        +			{
        +                        size_t j;
        +
        +			if (--argc < 1) goto bad;
        +			psk_key=*(++argv);
        +			for (j = 0; j < strlen(psk_key); j++)
        +                                {
        +                                if (isxdigit((unsigned char)psk_key[j]))
        +                                        continue;
        +                                BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
        +                                goto bad;
        +                                }
        +			}
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +		else if (strcmp(*argv,"-srpuser") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_arg.srplogin= *(++argv);
        +			meth=TLSv1_client_method();
        +			}
        +		else if (strcmp(*argv,"-srppass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srppass= *(++argv);
        +			meth=TLSv1_client_method();
        +			}
        +		else if (strcmp(*argv,"-srp_strength") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_arg.strength=atoi(*(++argv));
        +			BIO_printf(bio_err,"SRP minimal length for N is %d\n",srp_arg.strength);
        +			meth=TLSv1_client_method();
        +			}
        +		else if (strcmp(*argv,"-srp_lateuser") == 0)
        +			{
        +			srp_lateuser= 1;
        +			meth=TLSv1_client_method();
        +			}
        +		else if	(strcmp(*argv,"-srp_moregroups") == 0)
        +			{
        +			srp_arg.amp=1;
        +			meth=TLSv1_client_method();
        +			}
        +#endif
        +#ifndef OPENSSL_NO_SSL2
        +		else if	(strcmp(*argv,"-ssl2") == 0)
        +			meth=SSLv2_client_method();
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +		else if	(strcmp(*argv,"-ssl3") == 0)
        +			meth=SSLv3_client_method();
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +		else if	(strcmp(*argv,"-tls1_2") == 0)
        +			meth=TLSv1_2_client_method();
        +		else if	(strcmp(*argv,"-tls1_1") == 0)
        +			meth=TLSv1_1_client_method();
        +		else if	(strcmp(*argv,"-tls1") == 0)
        +			meth=TLSv1_client_method();
        +#endif
        +#ifndef OPENSSL_NO_DTLS1
        +		else if	(strcmp(*argv,"-dtls1") == 0)
        +			{
        +			meth=DTLSv1_client_method();
        +			socket_type=SOCK_DGRAM;
        +			}
        +		else if (strcmp(*argv,"-timeout") == 0)
        +			enable_timeouts=1;
        +		else if (strcmp(*argv,"-mtu") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			socket_mtu = atol(*(++argv));
        +			}
        +#endif
        +		else if (strcmp(*argv,"-bugs") == 0)
        +			bugs=1;
        +		else if	(strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			key_format = str2fmt(*(++argv));
        +			}
        +		else if	(strcmp(*argv,"-pass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passarg = *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			key_file= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-reconnect") == 0)
        +			{
        +			reconnect=5;
        +			}
        +		else if	(strcmp(*argv,"-CApath") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CApath= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CAfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-no_tls1_2") == 0)
        +			off|=SSL_OP_NO_TLSv1_2;
        +		else if (strcmp(*argv,"-no_tls1_1") == 0)
        +			off|=SSL_OP_NO_TLSv1_1;
        +		else if (strcmp(*argv,"-no_tls1") == 0)
        +			off|=SSL_OP_NO_TLSv1;
        +		else if (strcmp(*argv,"-no_ssl3") == 0)
        +			off|=SSL_OP_NO_SSLv3;
        +		else if (strcmp(*argv,"-no_ssl2") == 0)
        +			off|=SSL_OP_NO_SSLv2;
        +		else if	(strcmp(*argv,"-no_comp") == 0)
        +			{ off|=SSL_OP_NO_COMPRESSION; }
        +#ifndef OPENSSL_NO_TLSEXT
        +		else if	(strcmp(*argv,"-no_ticket") == 0)
        +			{ off|=SSL_OP_NO_TICKET; }
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +		else if (strcmp(*argv,"-nextprotoneg") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			next_proto_neg_in = *(++argv);
        +			}
        +# endif
        +#endif
        +		else if (strcmp(*argv,"-serverpref") == 0)
        +			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
        +		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
        +			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
        +		else if	(strcmp(*argv,"-legacy_server_connect") == 0)
        +			{ off|=SSL_OP_LEGACY_SERVER_CONNECT; }
        +		else if	(strcmp(*argv,"-no_legacy_server_connect") == 0)
        +			{ clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
        +		else if	(strcmp(*argv,"-cipher") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			cipher= *(++argv);
        +			}
        +#ifdef FIONBIO
        +		else if (strcmp(*argv,"-nbio") == 0)
        +			{ c_nbio=1; }
        +#endif
        +		else if	(strcmp(*argv,"-starttls") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			++argv;
        +			if (strcmp(*argv,"smtp") == 0)
        +				starttls_proto = PROTO_SMTP;
        +			else if (strcmp(*argv,"pop3") == 0)
        +				starttls_proto = PROTO_POP3;
        +			else if (strcmp(*argv,"imap") == 0)
        +				starttls_proto = PROTO_IMAP;
        +			else if (strcmp(*argv,"ftp") == 0)
        +				starttls_proto = PROTO_FTP;
        +			else if (strcmp(*argv, "xmpp") == 0)
        +				starttls_proto = PROTO_XMPP;
        +			else
        +				goto bad;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if	(strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine_id = *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-ssl_client_engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			ssl_client_engine_id = *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_TLSEXT
        +		else if (strcmp(*argv,"-servername") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			servername= *(++argv);
        +			/* meth=TLSv1_client_method(); */
        +			}
        +#endif
        +#ifndef OPENSSL_NO_JPAKE
        +		else if (strcmp(*argv,"-jpake") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			jpake_secret = *++argv;
        +			}
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +		else if (strcmp(*argv,"-use_srtp") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srtp_profiles = *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-keymatexport") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keymatexportlabel= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keymatexportlen") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keymatexportlen=atoi(*(++argv));
        +			if (keymatexportlen == 0) goto bad;
        +			}
        +                else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badop=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +	if (badop)
        +		{
        +bad:
        +		sc_usage();
        +		goto end;
        +		}
        +
        +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
        +	if (jpake_secret)
        +		{
        +		if (psk_key)
        +			{
        +			BIO_printf(bio_err,
        +				   "Can't use JPAKE and PSK together\n");
        +			goto end;
        +			}
        +		psk_identity = "JPAKE";
        +		if (cipher)
        +			{
        +			BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
        +			goto end;
        +			}
        +		cipher = "PSK";
        +		}
        +#endif
        +
        +	OpenSSL_add_ssl_algorithms();
        +	SSL_load_error_strings();
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	next_proto.status = -1;
        +	if (next_proto_neg_in)
        +		{
        +		next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
        +		if (next_proto.data == NULL)
        +			{
        +			BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
        +			goto end;
        +			}
        +		}
        +	else
        +		next_proto.data = NULL;
        +#endif
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine_id, 1);
        +	if (ssl_client_engine_id)
        +		{
        +		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
        +		if (!ssl_client_engine)
        +			{
        +			BIO_printf(bio_err,
        +					"Error getting client auth engine\n");
        +			goto end;
        +			}
        +		}
        +
        +#endif
        +	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +	if (key_file == NULL)
        +		key_file = cert_file;
        +
        +
        +	if (key_file)
        +
        +		{
        +
        +		key = load_key(bio_err, key_file, key_format, 0, pass, e,
        +			       "client certificate private key file");
        +		if (!key)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		}
        +
        +	if (cert_file)
        +
        +		{
        +		cert = load_cert(bio_err,cert_file,cert_format,
        +				NULL, e, "client certificate file");
        +
        +		if (!cert)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
        +		&& !RAND_status())
        +		{
        +		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
        +		}
        +	if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +
        +	if (bio_c_out == NULL)
        +		{
        +		if (c_quiet && !c_debug && !c_msg)
        +			{
        +			bio_c_out=BIO_new(BIO_s_null());
        +			}
        +		else
        +			{
        +			if (bio_c_out == NULL)
        +				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
        +			}
        +		}
        +
        +#ifndef OPENSSL_NO_SRP
        +	if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +#endif
        +
        +	ctx=SSL_CTX_new(meth);
        +	if (ctx == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (vpm)
        +		SSL_CTX_set1_param(ctx, vpm);
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	if (ssl_client_engine)
        +		{
        +		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
        +			{
        +			BIO_puts(bio_err, "Error setting client auth engine\n");
        +			ERR_print_errors(bio_err);
        +			ENGINE_free(ssl_client_engine);
        +			goto end;
        +			}
        +		ENGINE_free(ssl_client_engine);
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +#ifdef OPENSSL_NO_JPAKE
        +	if (psk_key != NULL)
        +#else
        +	if (psk_key != NULL || jpake_secret)
        +#endif
        +		{
        +		if (c_debug)
        +			BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
        +		SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
        +		}
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +	if (srtp_profiles != NULL)
        +		SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
        +#endif
        +	if (bugs)
        +		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
        +	else
        +		SSL_CTX_set_options(ctx,off);
        +
        +	if (clr)
        +		SSL_CTX_clear_options(ctx, clr);
        +	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
        +	 * Setting read ahead solves this problem.
        +	 */
        +	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	if (next_proto.data)
        +		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
        +#endif
        +
        +	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
        +	if (cipher != NULL)
        +		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
        +		BIO_printf(bio_err,"error setting cipher list\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +#if 0
        +	else
        +		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
        +#endif
        +
        +	SSL_CTX_set_verify(ctx,verify,verify_callback);
        +	if (!set_cert_key_stuff(ctx,cert,key))
        +		goto end;
        +
        +	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(ctx)))
        +		{
        +		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
        +		ERR_print_errors(bio_err);
        +		/* goto end; */
        +		}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (servername != NULL)
        +		{
        +		tlsextcbp.biodebug = bio_err;
        +		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
        +		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
        +		}
        +#ifndef OPENSSL_NO_SRP
        +        if (srp_arg.srplogin)
        +		{
        +		if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
        +			{
        +			BIO_printf(bio_err,"Unable to set SRP username\n");
        +			goto end;
        +			}
        +		srp_arg.msg = c_msg;
        +		srp_arg.debug = c_debug ;
        +		SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
        +		SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
        +		SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
        +		if (c_msg || c_debug || srp_arg.amp == 0)
        +			SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
        +		}
        +
        +#endif
        +#endif
        +
        +	con=SSL_new(ctx);
        +	if (sess_in)
        +		{
        +		SSL_SESSION *sess;
        +		BIO *stmp = BIO_new_file(sess_in, "r");
        +		if (!stmp)
        +			{
        +			BIO_printf(bio_err, "Can't open session file %s\n",
        +						sess_in);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
        +		BIO_free(stmp);
        +		if (!sess)
        +			{
        +			BIO_printf(bio_err, "Can't open session file %s\n",
        +						sess_in);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		SSL_set_session(con, sess);
        +		SSL_SESSION_free(sess);
        +		}
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (servername != NULL)
        +		{
        +		if (!SSL_set_tlsext_host_name(con,servername))
        +			{
        +			BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +	if (con  &&  (kctx = kssl_ctx_new()) != NULL)
        +                {
        +		SSL_set0_kssl_ctx(con, kctx);
        +                kssl_ctx_setstring(kctx, KSSL_SERVER, host);
        +		}
        +#endif	/* OPENSSL_NO_KRB5  */
        +/*	SSL_set_cipher_list(con,"RC4-MD5"); */
        +#if 0
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
        +#endif
        +#endif
        +
        +re_start:
        +
        +	if (init_client(&s,host,port,socket_type) == 0)
        +		{
        +		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
        +		SHUTDOWN(s);
        +		goto end;
        +		}
        +	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
        +
        +#ifdef FIONBIO
        +	if (c_nbio)
        +		{
        +		unsigned long l=1;
        +		BIO_printf(bio_c_out,"turning on non blocking io\n");
        +		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +#endif                                              
        +	if (c_Pause & 0x01) SSL_set_debug(con, 1);
        +
        +	if ( SSL_version(con) == DTLS1_VERSION)
        +		{
        +
        +		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
        +		if (getsockname(s, &peer, (void *)&peerlen) < 0)
        +			{
        +			BIO_printf(bio_err, "getsockname:errno=%d\n",
        +				get_last_socket_error());
        +			SHUTDOWN(s);
        +			goto end;
        +			}
        +
        +		(void)BIO_ctrl_set_connected(sbio, 1, &peer);
        +
        +		if (enable_timeouts)
        +			{
        +			timeout.tv_sec = 0;
        +			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
        +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
        +			
        +			timeout.tv_sec = 0;
        +			timeout.tv_usec = DGRAM_SND_TIMEOUT;
        +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
        +			}
        +
        +		if (socket_mtu > 28)
        +			{
        +			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
        +			SSL_set_mtu(con, socket_mtu - 28);
        +			}
        +		else
        +			/* want to do MTU discovery */
        +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
        +		}
        +	else
        +		sbio=BIO_new_socket(s,BIO_NOCLOSE);
        +
        +	if (nbio_test)
        +		{
        +		BIO *test;
        +
        +		test=BIO_new(BIO_f_nbio_test());
        +		sbio=BIO_push(test,sbio);
        +		}
        +
        +	if (c_debug)
        +		{
        +		SSL_set_debug(con, 1);
        +		BIO_set_callback(sbio,bio_dump_callback);
        +		BIO_set_callback_arg(sbio,(char *)bio_c_out);
        +		}
        +	if (c_msg)
        +		{
        +		SSL_set_msg_callback(con, msg_cb);
        +		SSL_set_msg_callback_arg(con, bio_c_out);
        +		}
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (c_tlsextdebug)
        +		{
        +		SSL_set_tlsext_debug_callback(con, tlsext_cb);
        +		SSL_set_tlsext_debug_arg(con, bio_c_out);
        +		}
        +	if (c_status_req)
        +		{
        +		SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
        +		SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
        +		SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
        +#if 0
        +{
        +STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
        +OCSP_RESPID *id = OCSP_RESPID_new();
        +id->value.byKey = ASN1_OCTET_STRING_new();
        +id->type = V_OCSP_RESPID_KEY;
        +ASN1_STRING_set(id->value.byKey, "Hello World", -1);
        +sk_OCSP_RESPID_push(ids, id);
        +SSL_set_tlsext_status_ids(con, ids);
        +}
        +#endif
        +		}
        +#endif
        +#ifndef OPENSSL_NO_JPAKE
        +	if (jpake_secret)
        +		jpake_client_auth(bio_c_out, sbio, jpake_secret);
        +#endif
        +
        +	SSL_set_bio(con,sbio,sbio);
        +	SSL_set_connect_state(con);
        +
        +	/* ok, lets connect */
        +	width=SSL_get_fd(con)+1;
        +
        +	read_tty=1;
        +	write_tty=0;
        +	tty_on=0;
        +	read_ssl=1;
        +	write_ssl=1;
        +	
        +	cbuf_len=0;
        +	cbuf_off=0;
        +	sbuf_len=0;
        +	sbuf_off=0;
        +
        +	/* This is an ugly hack that does a lot of assumptions */
        +	/* We do have to handle multi-line responses which may come
        + 	   in a single packet or not. We therefore have to use
        +	   BIO_gets() which does need a buffering BIO. So during
        +	   the initial chitchat we do push a buffering BIO into the
        +	   chain that is removed again later on to not disturb the
        +	   rest of the s_client operation. */
        +	if (starttls_proto == PROTO_SMTP)
        +		{
        +		int foundit=0;
        +		BIO *fbio = BIO_new(BIO_f_buffer());
        +		BIO_push(fbio, sbio);
        +		/* wait for multi-line response to end from SMTP */
        +		do
        +			{
        +			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
        +			}
        +		while (mbuf_len>3 && mbuf[3]=='-');
        +		/* STARTTLS command requires EHLO... */
        +		BIO_printf(fbio,"EHLO openssl.client.net\r\n");
        +		(void)BIO_flush(fbio);
        +		/* wait for multi-line response to end EHLO SMTP response */
        +		do
        +			{
        +			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
        +			if (strstr(mbuf,"STARTTLS"))
        +				foundit=1;
        +			}
        +		while (mbuf_len>3 && mbuf[3]=='-');
        +		(void)BIO_flush(fbio);
        +		BIO_pop(fbio);
        +		BIO_free(fbio);
        +		if (!foundit)
        +			BIO_printf(bio_err,
        +				   "didn't found starttls in server response,"
        +				   " try anyway...\n");
        +		BIO_printf(sbio,"STARTTLS\r\n");
        +		BIO_read(sbio,sbuf,BUFSIZZ);
        +		}
        +	else if (starttls_proto == PROTO_POP3)
        +		{
        +		BIO_read(sbio,mbuf,BUFSIZZ);
        +		BIO_printf(sbio,"STLS\r\n");
        +		BIO_read(sbio,sbuf,BUFSIZZ);
        +		}
        +	else if (starttls_proto == PROTO_IMAP)
        +		{
        +		int foundit=0;
        +		BIO *fbio = BIO_new(BIO_f_buffer());
        +		BIO_push(fbio, sbio);
        +		BIO_gets(fbio,mbuf,BUFSIZZ);
        +		/* STARTTLS command requires CAPABILITY... */
        +		BIO_printf(fbio,". CAPABILITY\r\n");
        +		(void)BIO_flush(fbio);
        +		/* wait for multi-line CAPABILITY response */
        +		do
        +			{
        +			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
        +			if (strstr(mbuf,"STARTTLS"))
        +				foundit=1;
        +			}
        +		while (mbuf_len>3 && mbuf[0]!='.');
        +		(void)BIO_flush(fbio);
        +		BIO_pop(fbio);
        +		BIO_free(fbio);
        +		if (!foundit)
        +			BIO_printf(bio_err,
        +				   "didn't found STARTTLS in server response,"
        +				   " try anyway...\n");
        +		BIO_printf(sbio,". STARTTLS\r\n");
        +		BIO_read(sbio,sbuf,BUFSIZZ);
        +		}
        +	else if (starttls_proto == PROTO_FTP)
        +		{
        +		BIO *fbio = BIO_new(BIO_f_buffer());
        +		BIO_push(fbio, sbio);
        +		/* wait for multi-line response to end from FTP */
        +		do
        +			{
        +			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
        +			}
        +		while (mbuf_len>3 && mbuf[3]=='-');
        +		(void)BIO_flush(fbio);
        +		BIO_pop(fbio);
        +		BIO_free(fbio);
        +		BIO_printf(sbio,"AUTH TLS\r\n");
        +		BIO_read(sbio,sbuf,BUFSIZZ);
        +		}
        +	if (starttls_proto == PROTO_XMPP)
        +		{
        +		int seen = 0;
        +		BIO_printf(sbio,"<stream:stream "
        +		    "xmlns:stream='http://etherx.jabber.org/streams' "
        +		    "xmlns='jabber:client' to='%s' version='1.0'>", host);
        +		seen = BIO_read(sbio,mbuf,BUFSIZZ);
        +		mbuf[seen] = 0;
        +		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
        +			{
        +			if (strstr(mbuf, "/stream:features>"))
        +				goto shut;
        +			seen = BIO_read(sbio,mbuf,BUFSIZZ);
        +			mbuf[seen] = 0;
        +			}
        +		BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
        +		seen = BIO_read(sbio,sbuf,BUFSIZZ);
        +		sbuf[seen] = 0;
        +		if (!strstr(sbuf, "<proceed"))
        +			goto shut;
        +		mbuf[0] = 0;
        +		}
        +
        +	for (;;)
        +		{
        +		FD_ZERO(&readfds);
        +		FD_ZERO(&writefds);
        +
        +		if ((SSL_version(con) == DTLS1_VERSION) &&
        +			DTLSv1_get_timeout(con, &timeout))
        +			timeoutp = &timeout;
        +		else
        +			timeoutp = NULL;
        +
        +		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
        +			{
        +			in_init=1;
        +			tty_on=0;
        +			}
        +		else
        +			{
        +			tty_on=1;
        +			if (in_init)
        +				{
        +				in_init=0;
        +#if 0 /* This test doesn't really work as intended (needs to be fixed) */
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (servername != NULL && !SSL_session_reused(con))
        +					{
        +					BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
        +					}
        +#endif
        +#endif
        +				if (sess_out)
        +					{
        +					BIO *stmp = BIO_new_file(sess_out, "w");
        +					if (stmp)
        +						{
        +						PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
        +						BIO_free(stmp);
        +						}
        +					else 
        +						BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
        +					}
        +				print_stuff(bio_c_out,con,full_log);
        +				if (full_log > 0) full_log--;
        +
        +				if (starttls_proto)
        +					{
        +					BIO_printf(bio_err,"%s",mbuf);
        +					/* We don't need to know any more */
        +					starttls_proto = PROTO_OFF;
        +					}
        +
        +				if (reconnect)
        +					{
        +					reconnect--;
        +					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
        +					SSL_shutdown(con);
        +					SSL_set_connect_state(con);
        +					SHUTDOWN(SSL_get_fd(con));
        +					goto re_start;
        +					}
        +				}
        +			}
        +
        +		ssl_pending = read_ssl && SSL_pending(con);
        +
        +		if (!ssl_pending)
        +			{
        +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
        +			if (tty_on)
        +				{
        +				if (read_tty)  openssl_fdset(fileno(stdin),&readfds);
        +				if (write_tty) openssl_fdset(fileno(stdout),&writefds);
        +				}
        +			if (read_ssl)
        +				openssl_fdset(SSL_get_fd(con),&readfds);
        +			if (write_ssl)
        +				openssl_fdset(SSL_get_fd(con),&writefds);
        +#else
        +			if(!tty_on || !write_tty) {
        +				if (read_ssl)
        +					openssl_fdset(SSL_get_fd(con),&readfds);
        +				if (write_ssl)
        +					openssl_fdset(SSL_get_fd(con),&writefds);
        +			}
        +#endif
        +/*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
        +				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
        +
        +			/* Note: under VMS with SOCKETSHR the second parameter
        +			 * is currently of type (int *) whereas under other
        +			 * systems it is (void *) if you don't have a cast it
        +			 * will choke the compiler: if you do have a cast then
        +			 * you can either go for (int *) or (void *).
        +			 */
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
        +                        /* Under Windows/DOS we make the assumption that we can
        +			 * always write to the tty: therefore if we need to
        +			 * write to the tty we just fall through. Otherwise
        +			 * we timeout the select every second and see if there
        +			 * are any keypresses. Note: this is a hack, in a proper
        +			 * Windows application we wouldn't do this.
        +			 */
        +			i=0;
        +			if(!write_tty) {
        +				if(read_tty) {
        +					tv.tv_sec = 1;
        +					tv.tv_usec = 0;
        +					i=select(width,(void *)&readfds,(void *)&writefds,
        +						 NULL,&tv);
        +#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
        +					if(!i && (!_kbhit() || !read_tty) ) continue;
        +#else
        +					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
        +#endif
        +				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
        +					 NULL,timeoutp);
        +			}
        +#elif defined(OPENSSL_SYS_NETWARE)
        +			if(!write_tty) {
        +				if(read_tty) {
        +					tv.tv_sec = 1;
        +					tv.tv_usec = 0;
        +					i=select(width,(void *)&readfds,(void *)&writefds,
        +						NULL,&tv);
        +				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
        +					NULL,timeoutp);
        +			}
        +#elif defined(OPENSSL_SYS_BEOS_R5)
        +			/* Under BeOS-R5 the situation is similar to DOS */
        +			i=0;
        +			stdin_set = 0;
        +			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
        +			if(!write_tty) {
        +				if(read_tty) {
        +					tv.tv_sec = 1;
        +					tv.tv_usec = 0;
        +					i=select(width,(void *)&readfds,(void *)&writefds,
        +						 NULL,&tv);
        +					if (read(fileno(stdin), sbuf, 0) >= 0)
        +						stdin_set = 1;
        +					if (!i && (stdin_set != 1 || !read_tty))
        +						continue;
        +				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
        +					 NULL,timeoutp);
        +			}
        +			(void)fcntl(fileno(stdin), F_SETFL, 0);
        +#else
        +			i=select(width,(void *)&readfds,(void *)&writefds,
        +				 NULL,timeoutp);
        +#endif
        +			if ( i < 0)
        +				{
        +				BIO_printf(bio_err,"bad select %d\n",
        +				get_last_socket_error());
        +				goto shut;
        +				/* goto end; */
        +				}
        +			}
        +
        +		if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
        +			{
        +			BIO_printf(bio_err,"TIMEOUT occured\n");
        +			}
        +
        +		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
        +			{
        +			k=SSL_write(con,&(cbuf[cbuf_off]),
        +				(unsigned int)cbuf_len);
        +			switch (SSL_get_error(con,k))
        +				{
        +			case SSL_ERROR_NONE:
        +				cbuf_off+=k;
        +				cbuf_len-=k;
        +				if (k <= 0) goto end;
        +				/* we have done a  write(con,NULL,0); */
        +				if (cbuf_len <= 0)
        +					{
        +					read_tty=1;
        +					write_ssl=0;
        +					}
        +				else /* if (cbuf_len > 0) */
        +					{
        +					read_tty=0;
        +					write_ssl=1;
        +					}
        +				break;
        +			case SSL_ERROR_WANT_WRITE:
        +				BIO_printf(bio_c_out,"write W BLOCK\n");
        +				write_ssl=1;
        +				read_tty=0;
        +				break;
        +			case SSL_ERROR_WANT_READ:
        +				BIO_printf(bio_c_out,"write R BLOCK\n");
        +				write_tty=0;
        +				read_ssl=1;
        +				write_ssl=0;
        +				break;
        +			case SSL_ERROR_WANT_X509_LOOKUP:
        +				BIO_printf(bio_c_out,"write X BLOCK\n");
        +				break;
        +			case SSL_ERROR_ZERO_RETURN:
        +				if (cbuf_len != 0)
        +					{
        +					BIO_printf(bio_c_out,"shutdown\n");
        +					ret = 0;
        +					goto shut;
        +					}
        +				else
        +					{
        +					read_tty=1;
        +					write_ssl=0;
        +					break;
        +					}
        +				
        +			case SSL_ERROR_SYSCALL:
        +				if ((k != 0) || (cbuf_len != 0))
        +					{
        +					BIO_printf(bio_err,"write:errno=%d\n",
        +						get_last_socket_error());
        +					goto shut;
        +					}
        +				else
        +					{
        +					read_tty=1;
        +					write_ssl=0;
        +					}
        +				break;
        +			case SSL_ERROR_SSL:
        +				ERR_print_errors(bio_err);
        +				goto shut;
        +				}
        +			}
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
        +		/* Assume Windows/DOS/BeOS can always write */
        +		else if (!ssl_pending && write_tty)
        +#else
        +		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
        +#endif
        +			{
        +#ifdef CHARSET_EBCDIC
        +			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
        +#endif
        +			i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
        +
        +			if (i <= 0)
        +				{
        +				BIO_printf(bio_c_out,"DONE\n");
        +				ret = 0;
        +				goto shut;
        +				/* goto end; */
        +				}
        +
        +			sbuf_len-=i;;
        +			sbuf_off+=i;
        +			if (sbuf_len <= 0)
        +				{
        +				read_ssl=1;
        +				write_tty=0;
        +				}
        +			}
        +		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
        +			{
        +#ifdef RENEG
        +{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
        +#endif
        +#if 1
        +			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
        +#else
        +/* Demo for pending and peek :-) */
        +			k=SSL_read(con,sbuf,16);
        +{ char zbuf[10240]; 
        +printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
        +}
        +#endif
        +
        +			switch (SSL_get_error(con,k))
        +				{
        +			case SSL_ERROR_NONE:
        +				if (k <= 0)
        +					goto end;
        +				sbuf_off=0;
        +				sbuf_len=k;
        +
        +				read_ssl=0;
        +				write_tty=1;
        +				break;
        +			case SSL_ERROR_WANT_WRITE:
        +				BIO_printf(bio_c_out,"read W BLOCK\n");
        +				write_ssl=1;
        +				read_tty=0;
        +				break;
        +			case SSL_ERROR_WANT_READ:
        +				BIO_printf(bio_c_out,"read R BLOCK\n");
        +				write_tty=0;
        +				read_ssl=1;
        +				if ((read_tty == 0) && (write_ssl == 0))
        +					write_ssl=1;
        +				break;
        +			case SSL_ERROR_WANT_X509_LOOKUP:
        +				BIO_printf(bio_c_out,"read X BLOCK\n");
        +				break;
        +			case SSL_ERROR_SYSCALL:
        +				ret=get_last_socket_error();
        +				BIO_printf(bio_err,"read:errno=%d\n",ret);
        +				goto shut;
        +			case SSL_ERROR_ZERO_RETURN:
        +				BIO_printf(bio_c_out,"closed\n");
        +				ret=0;
        +				goto shut;
        +			case SSL_ERROR_SSL:
        +				ERR_print_errors(bio_err);
        +				goto shut;
        +				/* break; */
        +				}
        +			}
        +
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
        +#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
        +		else if (_kbhit())
        +#else
        +		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
        +#endif
        +#elif defined (OPENSSL_SYS_NETWARE)
        +		else if (_kbhit())
        +#elif defined(OPENSSL_SYS_BEOS_R5)
        +		else if (stdin_set)
        +#else
        +		else if (FD_ISSET(fileno(stdin),&readfds))
        +#endif
        +			{
        +			if (crlf)
        +				{
        +				int j, lf_num;
        +
        +				i=raw_read_stdin(cbuf,BUFSIZZ/2);
        +				lf_num = 0;
        +				/* both loops are skipped when i <= 0 */
        +				for (j = 0; j < i; j++)
        +					if (cbuf[j] == '\n')
        +						lf_num++;
        +				for (j = i-1; j >= 0; j--)
        +					{
        +					cbuf[j+lf_num] = cbuf[j];
        +					if (cbuf[j] == '\n')
        +						{
        +						lf_num--;
        +						i++;
        +						cbuf[j+lf_num] = '\r';
        +						}
        +					}
        +				assert(lf_num == 0);
        +				}
        +			else
        +				i=raw_read_stdin(cbuf,BUFSIZZ);
        +
        +			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
        +				{
        +				BIO_printf(bio_err,"DONE\n");
        +				ret=0;
        +				goto shut;
        +				}
        +
        +			if ((!c_ign_eof) && (cbuf[0] == 'R'))
        +				{
        +				BIO_printf(bio_err,"RENEGOTIATING\n");
        +				SSL_renegotiate(con);
        +				cbuf_len=0;
        +				}
        +#ifndef OPENSSL_NO_HEARTBEATS
        +			else if ((!c_ign_eof) && (cbuf[0] == 'B'))
        + 				{
        +				BIO_printf(bio_err,"HEARTBEATING\n");
        +				SSL_heartbeat(con);
        +				cbuf_len=0;
        +				}
        +#endif
        +			else
        +				{
        +				cbuf_len=i;
        +				cbuf_off=0;
        +#ifdef CHARSET_EBCDIC
        +				ebcdic2ascii(cbuf, cbuf, i);
        +#endif
        +				}
        +
        +			write_ssl=1;
        +			read_tty=0;
        +			}
        +		}
        +
        +	ret=0;
        +shut:
        +	if (in_init)
        +		print_stuff(bio_c_out,con,full_log);
        +	SSL_shutdown(con);
        +	SHUTDOWN(SSL_get_fd(con));
        +end:
        +	if (con != NULL)
        +		{
        +		if (prexit != 0)
        +			print_stuff(bio_c_out,con,1);
        +		SSL_free(con);
        +		}
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	if (next_proto.data)
        +		OPENSSL_free(next_proto.data);
        +#endif
        +	if (ctx != NULL) SSL_CTX_free(ctx);
        +	if (cert)
        +		X509_free(cert);
        +	if (key)
        +		EVP_PKEY_free(key);
        +	if (pass)
        +		OPENSSL_free(pass);
        +	if (vpm)
        +		X509_VERIFY_PARAM_free(vpm);
        +	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
        +	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
        +	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
        +	if (bio_c_out != NULL)
        +		{
        +		BIO_free(bio_c_out);
        +		bio_c_out=NULL;
        +		}
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +
        +static void print_stuff(BIO *bio, SSL *s, int full)
        +	{
        +	X509 *peer=NULL;
        +	char *p;
        +	static const char *space="                ";
        +	char buf[BUFSIZ];
        +	STACK_OF(X509) *sk;
        +	STACK_OF(X509_NAME) *sk2;
        +	const SSL_CIPHER *c;
        +	X509_NAME *xn;
        +	int j,i;
        +#ifndef OPENSSL_NO_COMP
        +	const COMP_METHOD *comp, *expansion;
        +#endif
        +	unsigned char *exportedkeymat;
        +
        +	if (full)
        +		{
        +		int got_a_chain = 0;
        +
        +		sk=SSL_get_peer_cert_chain(s);
        +		if (sk != NULL)
        +			{
        +			got_a_chain = 1; /* we don't have it for SSL2 (yet) */
        +
        +			BIO_printf(bio,"---\nCertificate chain\n");
        +			for (i=0; i<sk_X509_num(sk); i++)
        +				{
        +				X509_NAME_oneline(X509_get_subject_name(
        +					sk_X509_value(sk,i)),buf,sizeof buf);
        +				BIO_printf(bio,"%2d s:%s\n",i,buf);
        +				X509_NAME_oneline(X509_get_issuer_name(
        +					sk_X509_value(sk,i)),buf,sizeof buf);
        +				BIO_printf(bio,"   i:%s\n",buf);
        +				if (c_showcerts)
        +					PEM_write_bio_X509(bio,sk_X509_value(sk,i));
        +				}
        +			}
        +
        +		BIO_printf(bio,"---\n");
        +		peer=SSL_get_peer_certificate(s);
        +		if (peer != NULL)
        +			{
        +			BIO_printf(bio,"Server certificate\n");
        +			if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
        +				PEM_write_bio_X509(bio,peer);
        +			X509_NAME_oneline(X509_get_subject_name(peer),
        +				buf,sizeof buf);
        +			BIO_printf(bio,"subject=%s\n",buf);
        +			X509_NAME_oneline(X509_get_issuer_name(peer),
        +				buf,sizeof buf);
        +			BIO_printf(bio,"issuer=%s\n",buf);
        +			}
        +		else
        +			BIO_printf(bio,"no peer certificate available\n");
        +
        +		sk2=SSL_get_client_CA_list(s);
        +		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
        +			{
        +			BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
        +			for (i=0; i<sk_X509_NAME_num(sk2); i++)
        +				{
        +				xn=sk_X509_NAME_value(sk2,i);
        +				X509_NAME_oneline(xn,buf,sizeof(buf));
        +				BIO_write(bio,buf,strlen(buf));
        +				BIO_write(bio,"\n",1);
        +				}
        +			}
        +		else
        +			{
        +			BIO_printf(bio,"---\nNo client certificate CA names sent\n");
        +			}
        +		p=SSL_get_shared_ciphers(s,buf,sizeof buf);
        +		if (p != NULL)
        +			{
        +			/* This works only for SSL 2.  In later protocol
        +			 * versions, the client does not know what other
        +			 * ciphers (in addition to the one to be used
        +			 * in the current connection) the server supports. */
        +
        +			BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
        +			j=i=0;
        +			while (*p)
        +				{
        +				if (*p == ':')
        +					{
        +					BIO_write(bio,space,15-j%25);
        +					i++;
        +					j=0;
        +					BIO_write(bio,((i%3)?" ":"\n"),1);
        +					}
        +				else
        +					{
        +					BIO_write(bio,p,1);
        +					j++;
        +					}
        +				p++;
        +				}
        +			BIO_write(bio,"\n",1);
        +			}
        +
        +		BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
        +			BIO_number_read(SSL_get_rbio(s)),
        +			BIO_number_written(SSL_get_wbio(s)));
        +		}
        +	BIO_printf(bio,(SSL_cache_hit(s)?"---\nReused, ":"---\nNew, "));
        +	c=SSL_get_current_cipher(s);
        +	BIO_printf(bio,"%s, Cipher is %s\n",
        +		SSL_CIPHER_get_version(c),
        +		SSL_CIPHER_get_name(c));
        +	if (peer != NULL) {
        +		EVP_PKEY *pktmp;
        +		pktmp = X509_get_pubkey(peer);
        +		BIO_printf(bio,"Server public key is %d bit\n",
        +							 EVP_PKEY_bits(pktmp));
        +		EVP_PKEY_free(pktmp);
        +	}
        +	BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
        +			SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
        +#ifndef OPENSSL_NO_COMP
        +	comp=SSL_get_current_compression(s);
        +	expansion=SSL_get_current_expansion(s);
        +	BIO_printf(bio,"Compression: %s\n",
        +		comp ? SSL_COMP_get_name(comp) : "NONE");
        +	BIO_printf(bio,"Expansion: %s\n",
        +		expansion ? SSL_COMP_get_name(expansion) : "NONE");
        +#endif
        + 
        +#ifdef SSL_DEBUG
        +	{
        +	/* Print out local port of connection: useful for debugging */
        +	int sock;
        +	struct sockaddr_in ladd;
        +	socklen_t ladd_size = sizeof(ladd);
        +	sock = SSL_get_fd(s);
        +	getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
        +	BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
        +	}
        +#endif
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	if (next_proto.status != -1) {
        +		const unsigned char *proto;
        +		unsigned int proto_len;
        +		SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
        +		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
        +		BIO_write(bio, proto, proto_len);
        +		BIO_write(bio, "\n", 1);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_SRTP
        + 	{
        + 	SRTP_PROTECTION_PROFILE *srtp_profile=SSL_get_selected_srtp_profile(s);
        + 
        +	if(srtp_profile)
        +		BIO_printf(bio,"SRTP Extension negotiated, profile=%s\n",
        +			   srtp_profile->name);
        +	}
        +#endif
        + 
        +	SSL_SESSION_print(bio,SSL_get_session(s));
        +	if (keymatexportlabel != NULL)
        +		{
        +		BIO_printf(bio, "Keying material exporter:\n");
        +		BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
        +		BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
        +		exportedkeymat = OPENSSL_malloc(keymatexportlen);
        +		if (exportedkeymat != NULL)
        +			{
        +			if (!SSL_export_keying_material(s, exportedkeymat,
        +						        keymatexportlen,
        +						        keymatexportlabel,
        +						        strlen(keymatexportlabel),
        +						        NULL, 0, 0))
        +				{
        +				BIO_printf(bio, "    Error\n");
        +				}
        +			else
        +				{
        +				BIO_printf(bio, "    Keying material: ");
        +				for (i=0; i<keymatexportlen; i++)
        +					BIO_printf(bio, "%02X",
        +						   exportedkeymat[i]);
        +				BIO_printf(bio, "\n");
        +				}
        +			OPENSSL_free(exportedkeymat);
        +			}
        +		}
        +	BIO_printf(bio,"---\n");
        +	if (peer != NULL)
        +		X509_free(peer);
        +	/* flush, or debugging output gets mixed with http response */
        +	(void)BIO_flush(bio);
        +	}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +
        +static int ocsp_resp_cb(SSL *s, void *arg)
        +	{
        +	const unsigned char *p;
        +	int len;
        +	OCSP_RESPONSE *rsp;
        +	len = SSL_get_tlsext_status_ocsp_resp(s, &p);
        +	BIO_puts(arg, "OCSP response: ");
        +	if (!p)
        +		{
        +		BIO_puts(arg, "no response sent\n");
        +		return 1;
        +		}
        +	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
        +	if (!rsp)
        +		{
        +		BIO_puts(arg, "response parse error\n");
        +		BIO_dump_indent(arg, (char *)p, len, 4);
        +		return 0;
        +		}
        +	BIO_puts(arg, "\n======================================\n");
        +	OCSP_RESPONSE_print(arg, rsp, 0);
        +	BIO_puts(arg, "======================================\n");
        +	OCSP_RESPONSE_free(rsp);
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/s_server.c b/vendor/openssl/openssl/apps/s_server.c
        new file mode 100644
        index 000000000..8198d7f06
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s_server.c
        @@ -0,0 +1,3011 @@
        +/* apps/s_server.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-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <assert.h>
        +#include <ctype.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/e_os2.h>
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +
        +#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */
        +#include <sys/types.h>
        +#endif
        +
        +/* With IPv6, it looks like Digital has mixed up the proper order of
        +   recursive header file inclusion, resulting in the compiler complaining
        +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
        +   is needed to have fileno() declared correctly...  So let's define u_int */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
        +#define __U_INT
        +typedef unsigned int u_int;
        +#endif
        +
        +#include <openssl/lhash.h>
        +#include <openssl/bn.h>
        +#define USE_SOCKETS
        +#include "apps.h"
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include <openssl/rand.h>
        +#include <openssl/ocsp.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +#include <openssl/srp.h>
        +#endif
        +#include "s_apps.h"
        +#include "timeouts.h"
        +
        +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
        +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
        +#undef FIONBIO
        +#endif
        +
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +#include <fcntl.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
        +#endif
        +static int sv_body(char *hostname, int s, unsigned char *context);
        +static int www_body(char *hostname, int s, unsigned char *context);
        +static void close_accept_socket(void );
        +static void sv_usage(void);
        +static int init_ssl_connection(SSL *s);
        +static void print_stats(BIO *bp,SSL_CTX *ctx);
        +static int generate_session_id(const SSL *ssl, unsigned char *id,
        +				unsigned int *id_len);
        +#ifndef OPENSSL_NO_DH
        +static DH *load_dh_param(const char *dhfile);
        +static DH *get_dh512(void);
        +#endif
        +
        +#ifdef MONOLITH
        +static void s_server_init(void);
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +static unsigned char dh512_p[]={
        +	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
        +	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
        +	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
        +	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
        +	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
        +	0x47,0x74,0xE8,0x33,
        +	};
        +static unsigned char dh512_g[]={
        +	0x02,
        +	};
        +
        +static DH *get_dh512(void)
        +	{
        +	DH *dh=NULL;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
        +	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		return(NULL);
        +	return(dh);
        +	}
        +#endif
        +
        +
        +/* static int load_CA(SSL_CTX *ctx, char *file);*/
        +
        +#undef BUFSIZZ
        +#define BUFSIZZ	16*1024
        +static int bufsize=BUFSIZZ;
        +static int accept_socket= -1;
        +
        +#define TEST_CERT	"server.pem"
        +#ifndef OPENSSL_NO_TLSEXT
        +#define TEST_CERT2	"server2.pem"
        +#endif
        +#undef PROG
        +#define PROG		s_server_main
        +
        +extern int verify_depth, verify_return_error;
        +
        +static char *cipher=NULL;
        +static int s_server_verify=SSL_VERIFY_NONE;
        +static int s_server_session_id_context = 1; /* anything will do */
        +static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
        +#ifndef OPENSSL_NO_TLSEXT
        +static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
        +#endif
        +static char *s_dcert_file=NULL,*s_dkey_file=NULL;
        +#ifdef FIONBIO
        +static int s_nbio=0;
        +#endif
        +static int s_nbio_test=0;
        +int s_crlf=0;
        +static SSL_CTX *ctx=NULL;
        +#ifndef OPENSSL_NO_TLSEXT
        +static SSL_CTX *ctx2=NULL;
        +#endif
        +static int www=0;
        +
        +static BIO *bio_s_out=NULL;
        +static int s_debug=0;
        +#ifndef OPENSSL_NO_TLSEXT
        +static int s_tlsextdebug=0;
        +static int s_tlsextstatus=0;
        +static int cert_status_cb(SSL *s, void *arg);
        +#endif
        +static int s_msg=0;
        +static int s_quiet=0;
        +
        +static char *keymatexportlabel=NULL;
        +static int keymatexportlen=20;
        +
        +static int hack=0;
        +#ifndef OPENSSL_NO_ENGINE
        +static char *engine_id=NULL;
        +#endif
        +static const char *session_id_prefix=NULL;
        +
        +static int enable_timeouts = 0;
        +static long socket_mtu;
        +#ifndef OPENSSL_NO_DTLS1
        +static int cert_chain = 0;
        +#endif
        +
        +
        +#ifndef OPENSSL_NO_PSK
        +static char *psk_identity="Client_identity";
        +char *psk_key=NULL; /* by default PSK is not used */
        +
        +static unsigned int psk_server_cb(SSL *ssl, const char *identity,
        +	unsigned char *psk, unsigned int max_psk_len)
        +	{
        +	unsigned int psk_len = 0;
        +	int ret;
        +	BIGNUM *bn = NULL;
        +
        +	if (s_debug)
        +		BIO_printf(bio_s_out,"psk_server_cb\n");
        +	if (!identity)
        +		{
        +		BIO_printf(bio_err,"Error: client did not send PSK identity\n");
        +		goto out_err;
        +		}
        +	if (s_debug)
        +		BIO_printf(bio_s_out,"identity_len=%d identity=%s\n",
        +			identity ? (int)strlen(identity) : 0, identity);
        +
        +	/* here we could lookup the given identity e.g. from a database */
        +  	if (strcmp(identity, psk_identity) != 0)
        +		{
        +                BIO_printf(bio_s_out, "PSK error: client identity not found"
        +			   " (got '%s' expected '%s')\n", identity,
        +			   psk_identity);
        +		goto out_err;
        +                }
        +	if (s_debug)
        +		BIO_printf(bio_s_out, "PSK client identity found\n");
        +
        +	/* convert the PSK key to binary */
        +	ret = BN_hex2bn(&bn, psk_key);
        +	if (!ret)
        +		{
        +		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
        +		if (bn)
        +			BN_free(bn);
        +		return 0;
        +		}
        +	if (BN_num_bytes(bn) > (int)max_psk_len)
        +		{
        +		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
        +			max_psk_len, BN_num_bytes(bn));
        +		BN_free(bn);
        +		return 0;
        +		}
        +
        +	ret = BN_bn2bin(bn, psk);
        +	BN_free(bn);
        +
        +	if (ret < 0)
        +		goto out_err;
        +	psk_len = (unsigned int)ret;
        +
        +	if (s_debug)
        +		BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
        +        return psk_len;
        + out_err:
        +	if (s_debug)
        +		BIO_printf(bio_err, "Error in PSK server callback\n");
        +	return 0;
        +        }
        +#endif
        +
        +#ifndef OPENSSL_NO_SRP
        +/* This is a context that we pass to callbacks */
        +typedef struct srpsrvparm_st
        +	{
        +	char *login;
        +	SRP_VBASE *vb;
        +	SRP_user_pwd *user;
        +	} srpsrvparm;
        +
        +/* This callback pretends to require some asynchronous logic in order to obtain
        +   a verifier. When the callback is called for a new connection we return
        +   with a negative value. This will provoke the accept etc to return with
        +   an LOOKUP_X509. The main logic of the reinvokes the suspended call 
        +   (which would normally occur after a worker has finished) and we
        +   set the user parameters. 
        +*/
        +static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
        +	{
        +	srpsrvparm *p = (srpsrvparm *)arg;
        +	if (p->login == NULL && p->user == NULL )
        +		{
        +		p->login = SSL_get_srp_username(s);
        +		BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
        +		return (-1) ;
        +		}
        +
        +	if (p->user == NULL)
        +		{
        +		BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
        +		return SSL3_AL_FATAL;
        +		}
        +	if (SSL_set_srp_server_param(s, p->user->N, p->user->g, p->user->s, p->user->v,
        +				     p->user->info) < 0)
        +		{
        +		*ad = SSL_AD_INTERNAL_ERROR;
        +		return SSL3_AL_FATAL;
        +		}
        +	BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
        +	/* need to check whether there are memory leaks */
        +	p->user = NULL;
        +	p->login = NULL;
        +	return SSL_ERROR_NONE;
        +	}
        +
        +#endif
        +
        +#ifdef MONOLITH
        +static void s_server_init(void)
        +	{
        +	accept_socket=-1;
        +	cipher=NULL;
        +	s_server_verify=SSL_VERIFY_NONE;
        +	s_dcert_file=NULL;
        +	s_dkey_file=NULL;
        +	s_cert_file=TEST_CERT;
        +	s_key_file=NULL;
        +#ifndef OPENSSL_NO_TLSEXT
        +	s_cert_file2=TEST_CERT2;
        +	s_key_file2=NULL;
        +	ctx2=NULL;
        +#endif
        +#ifdef FIONBIO
        +	s_nbio=0;
        +#endif
        +	s_nbio_test=0;
        +	ctx=NULL;
        +	www=0;
        +
        +	bio_s_out=NULL;
        +	s_debug=0;
        +	s_msg=0;
        +	s_quiet=0;
        +	hack=0;
        +#ifndef OPENSSL_NO_ENGINE
        +	engine_id=NULL;
        +#endif
        +	}
        +#endif
        +
        +static void sv_usage(void)
        +	{
        +	BIO_printf(bio_err,"usage: s_server [args ...]\n");
        +	BIO_printf(bio_err,"\n");
        +	BIO_printf(bio_err," -accept arg   - port to accept on (default is %d)\n",PORT);
        +	BIO_printf(bio_err," -context arg  - set session ID context\n");
        +	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
        +	BIO_printf(bio_err," -Verify arg   - turn on peer certificate verification, must have a cert.\n");
        +	BIO_printf(bio_err," -cert arg     - certificate file to use\n");
        +	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
        +	BIO_printf(bio_err," -crl_check    - check the peer certificate has not been revoked by its CA.\n" \
        +	                   "                 The CRL(s) are appended to the certificate file\n");
        +	BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
        +	                   "                 or any other CRL in the CA chain. CRL(s) are appened to the\n" \
        +	                   "                 the certificate file.\n");
        +	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
        +	BIO_printf(bio_err," -key arg      - Private Key file to use, in cert file if\n");
        +	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT);
        +	BIO_printf(bio_err," -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
        +	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
        +	BIO_printf(bio_err," -dcert arg    - second certificate file to use (usually for DSA)\n");
        +	BIO_printf(bio_err," -dcertform x  - second certificate format (PEM or DER) PEM default\n");
        +	BIO_printf(bio_err," -dkey arg     - second private key file to use (usually for DSA)\n");
        +	BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
        +	BIO_printf(bio_err," -dpass arg    - second private key file pass phrase source\n");
        +	BIO_printf(bio_err," -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
        +	BIO_printf(bio_err,"                 or a default set of parameters is used\n");
        +#ifndef OPENSSL_NO_ECDH
        +	BIO_printf(bio_err," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
        +	                   "                 Use \"openssl ecparam -list_curves\" for all names\n" \
        +	                   "                 (default is nistp256).\n");
        +#endif
        +#ifdef FIONBIO
        +	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
        +#endif
        +	BIO_printf(bio_err," -nbio_test    - test with the non-blocking test bio\n");
        +	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
        +	BIO_printf(bio_err," -debug        - Print more output\n");
        +	BIO_printf(bio_err," -msg          - Show protocol messages\n");
        +	BIO_printf(bio_err," -state        - Print the SSL states\n");
        +	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
        +	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
        +	BIO_printf(bio_err," -nocert       - Don't use any certificates (Anon-DH)\n");
        +	BIO_printf(bio_err," -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
        +	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences\n");
        +	BIO_printf(bio_err," -quiet        - No server output\n");
        +	BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
        +#ifndef OPENSSL_NO_PSK
        +	BIO_printf(bio_err," -psk_hint arg - PSK identity hint to use\n");
        +	BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
        +# ifndef OPENSSL_NO_JPAKE
        +	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
        +# endif
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	BIO_printf(bio_err," -srpvfile file      - The verifier file for SRP\n");
        +	BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n");
        +#endif
        +	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
        +	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
        +	BIO_printf(bio_err," -tls1_2       - Just talk TLSv1.2\n");
        +	BIO_printf(bio_err," -tls1_1       - Just talk TLSv1.1\n");
        +	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
        +	BIO_printf(bio_err," -dtls1        - Just talk DTLSv1\n");
        +	BIO_printf(bio_err," -timeout      - Enable timeouts\n");
        +	BIO_printf(bio_err," -mtu          - Set link layer MTU\n");
        +	BIO_printf(bio_err," -chain        - Read a certificate chain\n");
        +	BIO_printf(bio_err," -no_ssl2      - Just disable SSLv2\n");
        +	BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n");
        +	BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n");
        +	BIO_printf(bio_err," -no_tls1_1    - Just disable TLSv1.1\n");
        +	BIO_printf(bio_err," -no_tls1_2    - Just disable TLSv1.2\n");
        +#ifndef OPENSSL_NO_DH
        +	BIO_printf(bio_err," -no_dhe       - Disable ephemeral DH\n");
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	BIO_printf(bio_err," -no_ecdhe     - Disable ephemeral ECDH\n");
        +#endif
        +	BIO_printf(bio_err," -bugs         - Turn on SSL bug compatibility\n");
        +	BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
        +	BIO_printf(bio_err," -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
        +	BIO_printf(bio_err," -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
        +        BIO_printf(bio_err,"                 with the assumption it contains a complete HTTP response.\n");
        +#ifndef OPENSSL_NO_ENGINE
        +	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
        +#endif
        +	BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
        +	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +#ifndef OPENSSL_NO_TLSEXT
        +	BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
        +	BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
        +	BIO_printf(bio_err," -cert2 arg    - certificate file to use for servername\n");
        +	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT2);
        +	BIO_printf(bio_err," -key2 arg     - Private Key file to use for servername, in cert file if\n");
        +	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT2);
        +	BIO_printf(bio_err," -tlsextdebug  - hex dump of all TLS extensions received\n");
        +	BIO_printf(bio_err," -no_ticket    - disable use of RFC4507bis session tickets\n");
        +	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
        +# endif
        +# ifndef OPENSSL_NO_SRTP
        +        BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
        +# endif
        +#endif
        +	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
        +	BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
        +	}
        +
        +static int local_argc=0;
        +static char **local_argv;
        +
        +#ifdef CHARSET_EBCDIC
        +static int ebcdic_new(BIO *bi);
        +static int ebcdic_free(BIO *a);
        +static int ebcdic_read(BIO *b, char *out, int outl);
        +static int ebcdic_write(BIO *b, const char *in, int inl);
        +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
        +static int ebcdic_gets(BIO *bp, char *buf, int size);
        +static int ebcdic_puts(BIO *bp, const char *str);
        +
        +#define BIO_TYPE_EBCDIC_FILTER	(18|0x0200)
        +static BIO_METHOD methods_ebcdic=
        +	{
        +	BIO_TYPE_EBCDIC_FILTER,
        +	"EBCDIC/ASCII filter",
        +	ebcdic_write,
        +	ebcdic_read,
        +	ebcdic_puts,
        +	ebcdic_gets,
        +	ebcdic_ctrl,
        +	ebcdic_new,
        +	ebcdic_free,
        +	};
        +
        +typedef struct
        +{
        +	size_t	alloced;
        +	char	buff[1];
        +} EBCDIC_OUTBUFF;
        +
        +BIO_METHOD *BIO_f_ebcdic_filter()
        +{
        +	return(&methods_ebcdic);
        +}
        +
        +static int ebcdic_new(BIO *bi)
        +{
        +	EBCDIC_OUTBUFF *wbuf;
        +
        +	wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
        +	wbuf->alloced = 1024;
        +	wbuf->buff[0] = '\0';
        +
        +	bi->ptr=(char *)wbuf;
        +	bi->init=1;
        +	bi->flags=0;
        +	return(1);
        +}
        +
        +static int ebcdic_free(BIO *a)
        +{
        +	if (a == NULL) return(0);
        +	if (a->ptr != NULL)
        +		OPENSSL_free(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +}
        +	
        +static int ebcdic_read(BIO *b, char *out, int outl)
        +{
        +	int ret=0;
        +
        +	if (out == NULL || outl == 0) return(0);
        +	if (b->next_bio == NULL) return(0);
        +
        +	ret=BIO_read(b->next_bio,out,outl);
        +	if (ret > 0)
        +		ascii2ebcdic(out,out,ret);
        +	return(ret);
        +}
        +
        +static int ebcdic_write(BIO *b, const char *in, int inl)
        +{
        +	EBCDIC_OUTBUFF *wbuf;
        +	int ret=0;
        +	int num;
        +	unsigned char n;
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +	if (b->next_bio == NULL) return(0);
        +
        +	wbuf=(EBCDIC_OUTBUFF *)b->ptr;
        +
        +	if (inl > (num = wbuf->alloced))
        +	{
        +		num = num + num;  /* double the size */
        +		if (num < inl)
        +			num = inl;
        +		OPENSSL_free(wbuf);
        +		wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
        +
        +		wbuf->alloced = num;
        +		wbuf->buff[0] = '\0';
        +
        +		b->ptr=(char *)wbuf;
        +	}
        +
        +	ebcdic2ascii(wbuf->buff, in, inl);
        +
        +	ret=BIO_write(b->next_bio, wbuf->buff, inl);
        +
        +	return(ret);
        +}
        +
        +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
        +{
        +	long ret;
        +
        +	if (b->next_bio == NULL) return(0);
        +	switch (cmd)
        +	{
        +	case BIO_CTRL_DUP:
        +		ret=0L;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	}
        +	return(ret);
        +}
        +
        +static int ebcdic_gets(BIO *bp, char *buf, int size)
        +{
        +	int i, ret=0;
        +	if (bp->next_bio == NULL) return(0);
        +/*	return(BIO_gets(bp->next_bio,buf,size));*/
        +	for (i=0; i<size-1; ++i)
        +	{
        +		ret = ebcdic_read(bp,&buf[i],1);
        +		if (ret <= 0)
        +			break;
        +		else if (buf[i] == '\n')
        +		{
        +			++i;
        +			break;
        +		}
        +	}
        +	if (i < size)
        +		buf[i] = '\0';
        +	return (ret < 0 && i == 0) ? ret : i;
        +}
        +
        +static int ebcdic_puts(BIO *bp, const char *str)
        +{
        +	if (bp->next_bio == NULL) return(0);
        +	return ebcdic_write(bp, str, strlen(str));
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +
        +/* This is a context that we pass to callbacks */
        +typedef struct tlsextctx_st {
        +   char * servername;
        +   BIO * biodebug;
        +   int extension_error;
        +} tlsextctx;
        +
        +
        +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
        +	{
        +	tlsextctx * p = (tlsextctx *) arg;
        +	const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
        +        if (servername && p->biodebug) 
        +		BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
        +        
        +	if (!p->servername)
        +		return SSL_TLSEXT_ERR_NOACK;
        +	
        +	if (servername)
        +		{
        +    		if (strcmp(servername,p->servername)) 
        +			return p->extension_error;
        +		if (ctx2)
        +			{
        +			BIO_printf(p->biodebug,"Switching server context.\n");
        +			SSL_set_SSL_CTX(s,ctx2);
        +			}     
        +		}
        +	return SSL_TLSEXT_ERR_OK;
        +}
        +
        +/* Structure passed to cert status callback */
        +
        +typedef struct tlsextstatusctx_st {
        +   /* Default responder to use */
        +   char *host, *path, *port;
        +   int use_ssl;
        +   int timeout;
        +   BIO *err;
        +   int verbose;
        +} tlsextstatusctx;
        +
        +static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0};
        +
        +/* Certificate Status callback. This is called when a client includes a
        + * certificate status request extension.
        + *
        + * This is a simplified version. It examines certificates each time and
        + * makes one OCSP responder query for each request.
        + *
        + * A full version would store details such as the OCSP certificate IDs and
        + * minimise the number of OCSP responses by caching them until they were
        + * considered "expired".
        + */
        +
        +static int cert_status_cb(SSL *s, void *arg)
        +	{
        +	tlsextstatusctx *srctx = arg;
        +	BIO *err = srctx->err;
        +	char *host, *port, *path;
        +	int use_ssl;
        +	unsigned char *rspder = NULL;
        +	int rspderlen;
        +	STACK_OF(OPENSSL_STRING) *aia = NULL;
        +	X509 *x = NULL;
        +	X509_STORE_CTX inctx;
        +	X509_OBJECT obj;
        +	OCSP_REQUEST *req = NULL;
        +	OCSP_RESPONSE *resp = NULL;
        +	OCSP_CERTID *id = NULL;
        +	STACK_OF(X509_EXTENSION) *exts;
        +	int ret = SSL_TLSEXT_ERR_NOACK;
        +	int i;
        +#if 0
        +STACK_OF(OCSP_RESPID) *ids;
        +SSL_get_tlsext_status_ids(s, &ids);
        +BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids));
        +#endif
        +	if (srctx->verbose)
        +		BIO_puts(err, "cert_status: callback called\n");
        +	/* Build up OCSP query from server certificate */
        +	x = SSL_get_certificate(s);
        +	aia = X509_get1_ocsp(x);
        +	if (aia)
        +		{
        +		if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
        +			&host, &port, &path, &use_ssl))
        +			{
        +			BIO_puts(err, "cert_status: can't parse AIA URL\n");
        +			goto err;
        +			}
        +		if (srctx->verbose)
        +			BIO_printf(err, "cert_status: AIA URL: %s\n",
        +					sk_OPENSSL_STRING_value(aia, 0));
        +		}
        +	else
        +		{
        +		if (!srctx->host)
        +			{
        +			BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
        +			goto done;
        +			}
        +		host = srctx->host;
        +		path = srctx->path;
        +		port = srctx->port;
        +		use_ssl = srctx->use_ssl;
        +		}
        +		
        +	if (!X509_STORE_CTX_init(&inctx,
        +				SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
        +				NULL, NULL))
        +		goto err;
        +	if (X509_STORE_get_by_subject(&inctx,X509_LU_X509,
        +				X509_get_issuer_name(x),&obj) <= 0)
        +		{
        +		BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
        +		X509_STORE_CTX_cleanup(&inctx);
        +		goto done;
        +		}
        +	req = OCSP_REQUEST_new();
        +	if (!req)
        +		goto err;
        +	id = OCSP_cert_to_id(NULL, x, obj.data.x509);
        +	X509_free(obj.data.x509);
        +	X509_STORE_CTX_cleanup(&inctx);
        +	if (!id)
        +		goto err;
        +	if (!OCSP_request_add0_id(req, id))
        +		goto err;
        +	id = NULL;
        +	/* Add any extensions to the request */
        +	SSL_get_tlsext_status_exts(s, &exts);
        +	for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
        +		{
        +		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
        +		if (!OCSP_REQUEST_add_ext(req, ext, -1))
        +			goto err;
        +		}
        +	resp = process_responder(err, req, host, path, port, use_ssl, NULL,
        +					srctx->timeout);
        +	if (!resp)
        +		{
        +		BIO_puts(err, "cert_status: error querying responder\n");
        +		goto done;
        +		}
        +	rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
        +	if (rspderlen <= 0)
        +		goto err;
        +	SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
        +	if (srctx->verbose)
        +		{
        +		BIO_puts(err, "cert_status: ocsp response sent:\n");
        +		OCSP_RESPONSE_print(err, resp, 2);
        +		}
        +	ret = SSL_TLSEXT_ERR_OK;
        +	done:
        +	if (ret != SSL_TLSEXT_ERR_OK)
        +		ERR_print_errors(err);
        +	if (aia)
        +		{
        +		OPENSSL_free(host);
        +		OPENSSL_free(path);
        +		OPENSSL_free(port);
        +		X509_email_free(aia);
        +		}
        +	if (id)
        +		OCSP_CERTID_free(id);
        +	if (req)
        +		OCSP_REQUEST_free(req);
        +	if (resp)
        +		OCSP_RESPONSE_free(resp);
        +	return ret;
        +	err:
        +	ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +	goto done;
        +	}
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +/* This is the context that we pass to next_proto_cb */
        +typedef struct tlsextnextprotoctx_st {
        +	unsigned char *data;
        +	unsigned int len;
        +} tlsextnextprotoctx;
        +
        +static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
        +	{
        +	tlsextnextprotoctx *next_proto = arg;
        +
        +	*data = next_proto->data;
        +	*len = next_proto->len;
        +
        +	return SSL_TLSEXT_ERR_OK;
        +	}
        +# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
        +
        +
        +#endif
        +
        +int MAIN(int, char **);
        +
        +#ifndef OPENSSL_NO_JPAKE
        +static char *jpake_secret = NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	static srpsrvparm srp_callback_parm;
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +static char *srtp_profiles = NULL;
        +#endif
        +
        +int MAIN(int argc, char *argv[])
        +	{
        +	X509_VERIFY_PARAM *vpm = NULL;
        +	int badarg = 0;
        +	short port=PORT;
        +	char *CApath=NULL,*CAfile=NULL;
        +	unsigned char *context = NULL;
        +	char *dhfile = NULL;
        +#ifndef OPENSSL_NO_ECDH
        +	char *named_curve = NULL;
        +#endif
        +	int badop=0,bugs=0;
        +	int ret=1;
        +	int off=0;
        +	int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
        +	int state=0;
        +	const SSL_METHOD *meth=NULL;
        +	int socket_type=SOCK_STREAM;
        +	ENGINE *e=NULL;
        +	char *inrand=NULL;
        +	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
        +	char *passarg = NULL, *pass = NULL;
        +	char *dpassarg = NULL, *dpass = NULL;
        +	int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
        +	X509 *s_cert = NULL, *s_dcert = NULL;
        +	EVP_PKEY *s_key = NULL, *s_dkey = NULL;
        +	int no_cache = 0;
        +#ifndef OPENSSL_NO_TLSEXT
        +	EVP_PKEY *s_key2 = NULL;
        +	X509 *s_cert2 = NULL;
        +        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	const char *next_proto_neg_in = NULL;
        +	tlsextnextprotoctx next_proto;
        +# endif
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +	/* by default do not send a PSK identity hint */
        +	static char *psk_identity_hint=NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	char *srpuserseed = NULL;
        +	char *srp_verifier_file = NULL;
        +#endif
        +	meth=SSLv23_server_method();
        +
        +	local_argc=argc;
        +	local_argv=argv;
        +
        +	apps_startup();
        +#ifdef MONOLITH
        +	s_server_init();
        +#endif
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	verify_depth=0;
        +#ifdef FIONBIO
        +	s_nbio=0;
        +#endif
        +	s_nbio_test=0;
        +
        +	argc--;
        +	argv++;
        +
        +	while (argc >= 1)
        +		{
        +		if	((strcmp(*argv,"-port") == 0) ||
        +			 (strcmp(*argv,"-accept") == 0))
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!extract_port(*(++argv),&port))
        +				goto bad;
        +			}
        +		else if	(strcmp(*argv,"-verify") == 0)
        +			{
        +			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
        +			if (--argc < 1) goto bad;
        +			verify_depth=atoi(*(++argv));
        +			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
        +			}
        +		else if	(strcmp(*argv,"-Verify") == 0)
        +			{
        +			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
        +				SSL_VERIFY_CLIENT_ONCE;
        +			if (--argc < 1) goto bad;
        +			verify_depth=atoi(*(++argv));
        +			BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
        +			}
        +		else if	(strcmp(*argv,"-context") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			context= (unsigned char *)*(++argv);
        +			}
        +		else if	(strcmp(*argv,"-cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_cert_file= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-certform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_cert_format = str2fmt(*(++argv));
        +			}
        +		else if	(strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_key_file= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_key_format = str2fmt(*(++argv));
        +			}
        +		else if	(strcmp(*argv,"-pass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passarg = *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-dhparam") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			dhfile = *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ECDH		
        +		else if	(strcmp(*argv,"-named_curve") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			named_curve = *(++argv);
        +			}
        +#endif
        +		else if	(strcmp(*argv,"-dcertform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_dcert_format = str2fmt(*(++argv));
        +			}
        +		else if	(strcmp(*argv,"-dcert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_dcert_file= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-dkeyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_dkey_format = str2fmt(*(++argv));
        +			}
        +		else if	(strcmp(*argv,"-dpass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			dpassarg = *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-dkey") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_dkey_file= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-nocert") == 0)
        +			{
        +			nocert=1;
        +			}
        +		else if	(strcmp(*argv,"-CApath") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CApath= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-no_cache") == 0)
        +			no_cache = 1;
        +		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
        +			{
        +			if (badarg)
        +				goto bad;
        +			continue;
        +			}
        +		else if (strcmp(*argv,"-verify_return_error") == 0)
        +			verify_return_error = 1;
        +		else if	(strcmp(*argv,"-serverpref") == 0)
        +			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
        +		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
        +			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
        +		else if	(strcmp(*argv,"-cipher") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			cipher= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CAfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile= *(++argv);
        +			}
        +#ifdef FIONBIO	
        +		else if	(strcmp(*argv,"-nbio") == 0)
        +			{ s_nbio=1; }
        +#endif
        +		else if	(strcmp(*argv,"-nbio_test") == 0)
        +			{
        +#ifdef FIONBIO	
        +			s_nbio=1;
        +#endif
        +			s_nbio_test=1;
        +			}
        +		else if	(strcmp(*argv,"-debug") == 0)
        +			{ s_debug=1; }
        +#ifndef OPENSSL_NO_TLSEXT
        +		else if	(strcmp(*argv,"-tlsextdebug") == 0)
        +			s_tlsextdebug=1;
        +		else if	(strcmp(*argv,"-status") == 0)
        +			s_tlsextstatus=1;
        +		else if	(strcmp(*argv,"-status_verbose") == 0)
        +			{
        +			s_tlsextstatus=1;
        +			tlscstatp.verbose = 1;
        +			}
        +		else if (!strcmp(*argv, "-status_timeout"))
        +			{
        +			s_tlsextstatus=1;
        +                        if (--argc < 1) goto bad;
        +			tlscstatp.timeout = atoi(*(++argv));
        +			}
        +		else if (!strcmp(*argv, "-status_url"))
        +			{
        +			s_tlsextstatus=1;
        +                        if (--argc < 1) goto bad;
        +			if (!OCSP_parse_url(*(++argv),
        +					&tlscstatp.host,
        +					&tlscstatp.port,
        +					&tlscstatp.path,
        +					&tlscstatp.use_ssl))
        +				{
        +				BIO_printf(bio_err, "Error parsing URL\n");
        +				goto bad;
        +				}
        +			}
        +#endif
        +		else if	(strcmp(*argv,"-msg") == 0)
        +			{ s_msg=1; }
        +		else if	(strcmp(*argv,"-hack") == 0)
        +			{ hack=1; }
        +		else if	(strcmp(*argv,"-state") == 0)
        +			{ state=1; }
        +		else if	(strcmp(*argv,"-crlf") == 0)
        +			{ s_crlf=1; }
        +		else if	(strcmp(*argv,"-quiet") == 0)
        +			{ s_quiet=1; }
        +		else if	(strcmp(*argv,"-bugs") == 0)
        +			{ bugs=1; }
        +		else if	(strcmp(*argv,"-no_tmp_rsa") == 0)
        +			{ no_tmp_rsa=1; }
        +		else if	(strcmp(*argv,"-no_dhe") == 0)
        +			{ no_dhe=1; }
        +		else if	(strcmp(*argv,"-no_ecdhe") == 0)
        +			{ no_ecdhe=1; }
        +#ifndef OPENSSL_NO_PSK
        +                else if (strcmp(*argv,"-psk_hint") == 0)
        +			{
        +                        if (--argc < 1) goto bad;
        +                        psk_identity_hint= *(++argv);
        +                        }
        +                else if (strcmp(*argv,"-psk") == 0)
        +			{
        +			size_t i;
        +
        +			if (--argc < 1) goto bad;
        +			psk_key=*(++argv);
        +			for (i=0; i<strlen(psk_key); i++)
        +				{
        +				if (isxdigit((unsigned char)psk_key[i]))
        +					continue;
        +				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
        +				goto bad;
        +				}
        +			}
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +		else if (strcmp(*argv, "-srpvfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_verifier_file = *(++argv);
        +			meth = TLSv1_server_method();
        +			}
        +		else if (strcmp(*argv, "-srpuserseed") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srpuserseed = *(++argv);
        +			meth = TLSv1_server_method();
        +			}
        +#endif
        +		else if	(strcmp(*argv,"-www") == 0)
        +			{ www=1; }
        +		else if	(strcmp(*argv,"-WWW") == 0)
        +			{ www=2; }
        +		else if	(strcmp(*argv,"-HTTP") == 0)
        +			{ www=3; }
        +		else if	(strcmp(*argv,"-no_ssl2") == 0)
        +			{ off|=SSL_OP_NO_SSLv2; }
        +		else if	(strcmp(*argv,"-no_ssl3") == 0)
        +			{ off|=SSL_OP_NO_SSLv3; }
        +		else if	(strcmp(*argv,"-no_tls1") == 0)
        +			{ off|=SSL_OP_NO_TLSv1; }
        +		else if	(strcmp(*argv,"-no_tls1_1") == 0)
        +			{ off|=SSL_OP_NO_TLSv1_1; }
        +		else if	(strcmp(*argv,"-no_tls1_2") == 0)
        +			{ off|=SSL_OP_NO_TLSv1_2; }
        +		else if	(strcmp(*argv,"-no_comp") == 0)
        +			{ off|=SSL_OP_NO_COMPRESSION; }
        +#ifndef OPENSSL_NO_TLSEXT
        +		else if	(strcmp(*argv,"-no_ticket") == 0)
        +			{ off|=SSL_OP_NO_TICKET; }
        +#endif
        +#ifndef OPENSSL_NO_SSL2
        +		else if	(strcmp(*argv,"-ssl2") == 0)
        +			{ meth=SSLv2_server_method(); }
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +		else if	(strcmp(*argv,"-ssl3") == 0)
        +			{ meth=SSLv3_server_method(); }
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +		else if	(strcmp(*argv,"-tls1") == 0)
        +			{ meth=TLSv1_server_method(); }
        +		else if	(strcmp(*argv,"-tls1_1") == 0)
        +			{ meth=TLSv1_1_server_method(); }
        +		else if	(strcmp(*argv,"-tls1_2") == 0)
        +			{ meth=TLSv1_2_server_method(); }
        +#endif
        +#ifndef OPENSSL_NO_DTLS1
        +		else if	(strcmp(*argv,"-dtls1") == 0)
        +			{ 
        +			meth=DTLSv1_server_method();
        +			socket_type = SOCK_DGRAM;
        +			}
        +		else if (strcmp(*argv,"-timeout") == 0)
        +			enable_timeouts = 1;
        +		else if (strcmp(*argv,"-mtu") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			socket_mtu = atol(*(++argv));
        +			}
        +		else if (strcmp(*argv, "-chain") == 0)
        +			cert_chain = 1;
        +#endif
        +		else if (strcmp(*argv, "-id_prefix") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			session_id_prefix = *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine_id= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-rand") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inrand= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_TLSEXT
        +		else if (strcmp(*argv,"-servername") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			tlsextcbp.servername= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-servername_fatal") == 0)
        +			{ tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }
        +		else if	(strcmp(*argv,"-cert2") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_cert_file2= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-key2") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			s_key_file2= *(++argv);
        +			}
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +		else if	(strcmp(*argv,"-nextprotoneg") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			next_proto_neg_in = *(++argv);
        +			}
        +# endif
        +#endif
        +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
        +		else if (strcmp(*argv,"-jpake") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			jpake_secret = *(++argv);
        +			}
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +		else if (strcmp(*argv,"-use_srtp") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srtp_profiles = *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-keymatexport") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keymatexportlabel= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-keymatexportlen") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keymatexportlen=atoi(*(++argv));
        +			if (keymatexportlen == 0) goto bad;
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badop=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +	if (badop)
        +		{
        +bad:
        +		sv_usage();
        +		goto end;
        +		}
        +
        +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
        +	if (jpake_secret)
        +		{
        +		if (psk_key)
        +			{
        +			BIO_printf(bio_err,
        +				   "Can't use JPAKE and PSK together\n");
        +			goto end;
        +			}
        +		psk_identity = "JPAKE";
        +		if (cipher)
        +			{
        +			BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
        +			goto end;
        +			}
        +		cipher = "PSK";
        +		}
        +
        +#endif
        +
        +	SSL_load_error_strings();
        +	OpenSSL_add_ssl_algorithms();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine_id, 1);
        +#endif
        +
        +	if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +
        +	if (s_key_file == NULL)
        +		s_key_file = s_cert_file;
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (s_key_file2 == NULL)
        +		s_key_file2 = s_cert_file2;
        +#endif
        +
        +	if (nocert == 0)
        +		{
        +		s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
        +		       "server certificate private key file");
        +		if (!s_key)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
        +			NULL, e, "server certificate file");
        +
        +		if (!s_cert)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (tlsextcbp.servername) 
        +			{
        +			s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
        +				"second server certificate private key file");
        +			if (!s_key2)
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			
        +			s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,
        +				NULL, e, "second server certificate file");
        +			
        +			if (!s_cert2)
        +				{
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			}
        +#endif
        +		}
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 
        +	if (next_proto_neg_in)
        +		{
        +		unsigned short len;
        +		next_proto.data = next_protos_parse(&len, next_proto_neg_in);
        +		if (next_proto.data == NULL)
        +			goto end;
        +		next_proto.len = len;
        +		}
        +	else
        +		{
        +		next_proto.data = NULL;
        +		}
        +#endif
        +
        +
        +	if (s_dcert_file)
        +		{
        +
        +		if (s_dkey_file == NULL)
        +			s_dkey_file = s_dcert_file;
        +
        +		s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
        +				0, dpass, e,
        +			       "second certificate private key file");
        +		if (!s_dkey)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
        +				NULL, e, "second server certificate file");
        +
        +		if (!s_dcert)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		}
        +
        +	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
        +		&& !RAND_status())
        +		{
        +		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
        +		}
        +	if (inrand != NULL)
        +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +			app_RAND_load_files(inrand));
        +
        +	if (bio_s_out == NULL)
        +		{
        +		if (s_quiet && !s_debug && !s_msg)
        +			{
        +			bio_s_out=BIO_new(BIO_s_null());
        +			}
        +		else
        +			{
        +			if (bio_s_out == NULL)
        +				bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
        +			}
        +		}
        +
        +#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
        +	if (nocert)
        +#endif
        +		{
        +		s_cert_file=NULL;
        +		s_key_file=NULL;
        +		s_dcert_file=NULL;
        +		s_dkey_file=NULL;
        +#ifndef OPENSSL_NO_TLSEXT
        +		s_cert_file2=NULL;
        +		s_key_file2=NULL;
        +#endif
        +		}
        +
        +	ctx=SSL_CTX_new(meth);
        +	if (ctx == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	if (session_id_prefix)
        +		{
        +		if(strlen(session_id_prefix) >= 32)
        +			BIO_printf(bio_err,
        +"warning: id_prefix is too long, only one new session will be possible\n");
        +		else if(strlen(session_id_prefix) >= 16)
        +			BIO_printf(bio_err,
        +"warning: id_prefix is too long if you use SSLv2\n");
        +		if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
        +			{
        +			BIO_printf(bio_err,"error setting 'id_prefix'\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
        +		}
        +	SSL_CTX_set_quiet_shutdown(ctx,1);
        +	if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
        +	if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
        +	SSL_CTX_set_options(ctx,off);
        +	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
        +	 * Setting read ahead solves this problem.
        +	 */
        +	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
        +
        +	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
        +	if (no_cache)
        +		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
        +	else
        +		SSL_CTX_sess_set_cache_size(ctx,128);
        +
        +#ifndef OPENSSL_NO_SRTP
        +	if (srtp_profiles != NULL)
        +		SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
        +#endif
        +
        +#if 0
        +	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
        +#endif
        +
        +#if 0
        +	if (s_cert_file == NULL)
        +		{
        +		BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
        +		goto end;
        +		}
        +#endif
        +
        +	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(ctx)))
        +		{
        +		/* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
        +		ERR_print_errors(bio_err);
        +		/* goto end; */
        +		}
        +	if (vpm)
        +		SSL_CTX_set1_param(ctx, vpm);
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (s_cert2)
        +		{
        +		ctx2=SSL_CTX_new(meth);
        +		if (ctx2 == NULL)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +	
        +	if (ctx2)
        +		{
        +		BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
        +
        +		if (session_id_prefix)
        +			{
        +			if(strlen(session_id_prefix) >= 32)
        +				BIO_printf(bio_err,
        +					"warning: id_prefix is too long, only one new session will be possible\n");
        +			else if(strlen(session_id_prefix) >= 16)
        +				BIO_printf(bio_err,
        +					"warning: id_prefix is too long if you use SSLv2\n");
        +			if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id))
        +				{
        +				BIO_printf(bio_err,"error setting 'id_prefix'\n");
        +				ERR_print_errors(bio_err);
        +				goto end;
        +				}
        +			BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
        +			}
        +		SSL_CTX_set_quiet_shutdown(ctx2,1);
        +		if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
        +		if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
        +		SSL_CTX_set_options(ctx2,off);
        +		/* DTLS: partial reads end up discarding unread UDP bytes :-( 
        +		 * Setting read ahead solves this problem.
        +		 */
        +		if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
        +
        +		if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
        +
        +		if (no_cache)
        +			SSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF);
        +		else
        +			SSL_CTX_sess_set_cache_size(ctx2,128);
        +
        +		if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
        +			(!SSL_CTX_set_default_verify_paths(ctx2)))
        +			{
        +			ERR_print_errors(bio_err);
        +			}
        +		if (vpm)
        +			SSL_CTX_set1_param(ctx2, vpm);
        +		}
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	if (next_proto.data)
        +		SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
        +# endif
        +#endif 
        +
        +#ifndef OPENSSL_NO_DH
        +	if (!no_dhe)
        +		{
        +		DH *dh=NULL;
        +
        +		if (dhfile)
        +			dh = load_dh_param(dhfile);
        +		else if (s_cert_file)
        +			dh = load_dh_param(s_cert_file);
        +
        +		if (dh != NULL)
        +			{
        +			BIO_printf(bio_s_out,"Setting temp DH parameters\n");
        +			}
        +		else
        +			{
        +			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
        +			dh=get_dh512();
        +			}
        +		(void)BIO_flush(bio_s_out);
        +
        +		SSL_CTX_set_tmp_dh(ctx,dh);
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (ctx2)
        +			{
        +			if (!dhfile)
        +				{ 
        +				DH *dh2=load_dh_param(s_cert_file2);
        +				if (dh2 != NULL)
        +					{
        +					BIO_printf(bio_s_out,"Setting temp DH parameters\n");
        +					(void)BIO_flush(bio_s_out);
        +
        +					DH_free(dh);
        +					dh = dh2;
        +					}
        +				}
        +			SSL_CTX_set_tmp_dh(ctx2,dh);
        +			}
        +#endif
        +		DH_free(dh);
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	if (!no_ecdhe)
        +		{
        +		EC_KEY *ecdh=NULL;
        +
        +		if (named_curve)
        +			{
        +			int nid = OBJ_sn2nid(named_curve);
        +
        +			if (nid == 0)
        +				{
        +				BIO_printf(bio_err, "unknown curve name (%s)\n", 
        +					named_curve);
        +				goto end;
        +				}
        +			ecdh = EC_KEY_new_by_curve_name(nid);
        +			if (ecdh == NULL)
        +				{
        +				BIO_printf(bio_err, "unable to create curve (%s)\n", 
        +					named_curve);
        +				goto end;
        +				}
        +			}
        +
        +		if (ecdh != NULL)
        +			{
        +			BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
        +			}
        +		else
        +			{
        +			BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
        +			ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
        +			if (ecdh == NULL) 
        +				{
        +				BIO_printf(bio_err, "unable to create curve (nistp256)\n");
        +				goto end;
        +				}
        +			}
        +		(void)BIO_flush(bio_s_out);
        +
        +		SSL_CTX_set_tmp_ecdh(ctx,ecdh);
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (ctx2) 
        +			SSL_CTX_set_tmp_ecdh(ctx2,ecdh);
        +#endif
        +		EC_KEY_free(ecdh);
        +		}
        +#endif
        +	
        +	if (!set_cert_key_stuff(ctx, s_cert, s_key))
        +		goto end;
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2))
        +		goto end; 
        +#endif
        +	if (s_dcert != NULL)
        +		{
        +		if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
        +			goto end;
        +		}
        +
        +#ifndef OPENSSL_NO_RSA
        +#if 1
        +	if (!no_tmp_rsa)
        +		{
        +		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (ctx2) 
        +			SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
        +#endif		
        +		}
        +#else
        +	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
        +		{
        +		RSA *rsa;
        +
        +		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
        +		BIO_flush(bio_s_out);
        +
        +		rsa=RSA_generate_key(512,RSA_F4,NULL);
        +
        +		if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +#ifndef OPENSSL_NO_TLSEXT
        +			if (ctx2)
        +				{
        +				if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
        +					{
        +					ERR_print_errors(bio_err);
        +					goto end;
        +					}
        +				}
        +#endif
        +		RSA_free(rsa);
        +		BIO_printf(bio_s_out,"\n");
        +		}
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +#ifdef OPENSSL_NO_JPAKE
        +	if (psk_key != NULL)
        +#else
        +	if (psk_key != NULL || jpake_secret)
        +#endif
        +		{
        +		if (s_debug)
        +			BIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\n");
        +		SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
        +		}
        +
        +	if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint))
        +		{
        +		BIO_printf(bio_err,"error setting PSK identity hint to context\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +#endif
        +
        +	if (cipher != NULL)
        +		{
        +		if(!SSL_CTX_set_cipher_list(ctx,cipher))
        +			{
        +			BIO_printf(bio_err,"error setting cipher list\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
        +			{
        +			BIO_printf(bio_err,"error setting cipher list\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +#endif
        +		}
        +	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
        +	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
        +		sizeof s_server_session_id_context);
        +
        +	/* Set DTLS cookie generation and verification callbacks */
        +	SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
        +	SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (ctx2)
        +		{
        +		SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);
        +		SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,
        +			sizeof s_server_session_id_context);
        +
        +		tlsextcbp.biodebug = bio_s_out;
        +		SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
        +		SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
        +		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
        +		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_SRP
        +	if (srp_verifier_file != NULL)
        +		{
        +		srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
        +		srp_callback_parm.user = NULL;
        +		srp_callback_parm.login = NULL;
        +		if ((ret = SRP_VBASE_init(srp_callback_parm.vb, srp_verifier_file)) != SRP_NO_ERROR)
        +			{
        +			BIO_printf(bio_err,
        +				   "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
        +				   srp_verifier_file, ret);
        +				goto end;
        +			}
        +		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
        +		SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);  			
        +		SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
        +		}
        +	else
        +#endif
        +	if (CAfile != NULL)
        +		{
        +		SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (ctx2) 
        +			SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
        +#endif
        +		}
        +
        +	BIO_printf(bio_s_out,"ACCEPT\n");
        +	(void)BIO_flush(bio_s_out);
        +	if (www)
        +		do_server(port,socket_type,&accept_socket,www_body, context);
        +	else
        +		do_server(port,socket_type,&accept_socket,sv_body, context);
        +	print_stats(bio_s_out,ctx);
        +	ret=0;
        +end:
        +	if (ctx != NULL) SSL_CTX_free(ctx);
        +	if (s_cert)
        +		X509_free(s_cert);
        +	if (s_dcert)
        +		X509_free(s_dcert);
        +	if (s_key)
        +		EVP_PKEY_free(s_key);
        +	if (s_dkey)
        +		EVP_PKEY_free(s_dkey);
        +	if (pass)
        +		OPENSSL_free(pass);
        +	if (dpass)
        +		OPENSSL_free(dpass);
        +	if (vpm)
        +		X509_VERIFY_PARAM_free(vpm);
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (tlscstatp.host)
        +		OPENSSL_free(tlscstatp.host);
        +	if (tlscstatp.port)
        +		OPENSSL_free(tlscstatp.port);
        +	if (tlscstatp.path)
        +		OPENSSL_free(tlscstatp.path);
        +	if (ctx2 != NULL) SSL_CTX_free(ctx2);
        +	if (s_cert2)
        +		X509_free(s_cert2);
        +	if (s_key2)
        +		EVP_PKEY_free(s_key2);
        +#endif
        +	if (bio_s_out != NULL)
        +		{
        +        BIO_free(bio_s_out);
        +		bio_s_out=NULL;
        +		}
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
        +	{
        +	BIO_printf(bio,"%4ld items in the session cache\n",
        +		SSL_CTX_sess_number(ssl_ctx));
        +	BIO_printf(bio,"%4ld client connects (SSL_connect())\n",
        +		SSL_CTX_sess_connect(ssl_ctx));
        +	BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
        +		SSL_CTX_sess_connect_renegotiate(ssl_ctx));
        +	BIO_printf(bio,"%4ld client connects that finished\n",
        +		SSL_CTX_sess_connect_good(ssl_ctx));
        +	BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
        +		SSL_CTX_sess_accept(ssl_ctx));
        +	BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
        +		SSL_CTX_sess_accept_renegotiate(ssl_ctx));
        +	BIO_printf(bio,"%4ld server accepts that finished\n",
        +		SSL_CTX_sess_accept_good(ssl_ctx));
        +	BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
        +	BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
        +	BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
        +	BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
        +	BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",
        +		SSL_CTX_sess_cache_full(ssl_ctx),
        +		SSL_CTX_sess_get_cache_size(ssl_ctx));
        +	}
        +
        +static int sv_body(char *hostname, int s, unsigned char *context)
        +	{
        +	char *buf=NULL;
        +	fd_set readfds;
        +	int ret=1,width;
        +	int k,i;
        +	unsigned long l;
        +	SSL *con=NULL;
        +	BIO *sbio;
        +#ifndef OPENSSL_NO_KRB5
        +	KSSL_CTX *kctx;
        +#endif
        +	struct timeval timeout;
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
        +	struct timeval tv;
        +#else
        +	struct timeval *timeoutp;
        +#endif
        +
        +	if ((buf=OPENSSL_malloc(bufsize)) == NULL)
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		goto err;
        +		}
        +#ifdef FIONBIO	
        +	if (s_nbio)
        +		{
        +		unsigned long sl=1;
        +
        +		if (!s_quiet)
        +			BIO_printf(bio_err,"turning on non blocking io\n");
        +		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
        +			ERR_print_errors(bio_err);
        +		}
        +#endif
        +
        +	if (con == NULL) {
        +		con=SSL_new(ctx);
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (s_tlsextdebug)
        +		{
        +		SSL_set_tlsext_debug_callback(con, tlsext_cb);
        +		SSL_set_tlsext_debug_arg(con, bio_s_out);
        +		}
        +	if (s_tlsextstatus)
        +		{
        +		SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
        +		tlscstatp.err = bio_err;
        +		SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
        +		}
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +		if ((kctx = kssl_ctx_new()) != NULL)
        +                        {
        +			SSL_set0_kssl_ctx(con, kctx);
        +                        kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
        +                        kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
        +                        }
        +#endif	/* OPENSSL_NO_KRB5 */
        +		if(context)
        +		      SSL_set_session_id_context(con, context,
        +						 strlen((char *)context));
        +	}
        +	SSL_clear(con);
        +#if 0
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
        +#endif
        +#endif
        +
        +	if (SSL_version(con) == DTLS1_VERSION)
        +		{
        +
        +		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
        +
        +		if (enable_timeouts)
        +			{
        +			timeout.tv_sec = 0;
        +			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
        +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
        +			
        +			timeout.tv_sec = 0;
        +			timeout.tv_usec = DGRAM_SND_TIMEOUT;
        +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
        +			}
        +
        +		if (socket_mtu > 28)
        +			{
        +			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
        +			SSL_set_mtu(con, socket_mtu - 28);
        +			}
        +		else
        +			/* want to do MTU discovery */
        +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
        +
        +        /* turn on cookie exchange */
        +        SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
        +		}
        +	else
        +		sbio=BIO_new_socket(s,BIO_NOCLOSE);
        +
        +	if (s_nbio_test)
        +		{
        +		BIO *test;
        +
        +		test=BIO_new(BIO_f_nbio_test());
        +		sbio=BIO_push(test,sbio);
        +		}
        +#ifndef OPENSSL_NO_JPAKE
        +	if(jpake_secret)
        +		jpake_server_auth(bio_s_out, sbio, jpake_secret);
        +#endif
        +
        +	SSL_set_bio(con,sbio,sbio);
        +	SSL_set_accept_state(con);
        +	/* SSL_set_fd(con,s); */
        +
        +	if (s_debug)
        +		{
        +		SSL_set_debug(con, 1);
        +		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
        +		BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
        +		}
        +	if (s_msg)
        +		{
        +		SSL_set_msg_callback(con, msg_cb);
        +		SSL_set_msg_callback_arg(con, bio_s_out);
        +		}
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (s_tlsextdebug)
        +		{
        +		SSL_set_tlsext_debug_callback(con, tlsext_cb);
        +		SSL_set_tlsext_debug_arg(con, bio_s_out);
        +		}
        +#endif
        +
        +	width=s+1;
        +	for (;;)
        +		{
        +		int read_from_terminal;
        +		int read_from_sslcon;
        +
        +		read_from_terminal = 0;
        +		read_from_sslcon = SSL_pending(con);
        +
        +		if (!read_from_sslcon)
        +			{
        +			FD_ZERO(&readfds);
        +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
        +			openssl_fdset(fileno(stdin),&readfds);
        +#endif
        +			openssl_fdset(s,&readfds);
        +			/* Note: under VMS with SOCKETSHR the second parameter is
        +			 * currently of type (int *) whereas under other systems
        +			 * it is (void *) if you don't have a cast it will choke
        +			 * the compiler: if you do have a cast then you can either
        +			 * go for (int *) or (void *).
        +			 */
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
        +                        /* Under DOS (non-djgpp) and Windows we can't select on stdin: only
        +			 * on sockets. As a workaround we timeout the select every
        +			 * second and check for any keypress. In a proper Windows
        +			 * application we wouldn't do this because it is inefficient.
        +			 */
        +			tv.tv_sec = 1;
        +			tv.tv_usec = 0;
        +			i=select(width,(void *)&readfds,NULL,NULL,&tv);
        +			if((i < 0) || (!i && !_kbhit() ) )continue;
        +			if(_kbhit())
        +				read_from_terminal = 1;
        +#elif defined(OPENSSL_SYS_BEOS_R5)
        +			/* Under BeOS-R5 the situation is similar to DOS */
        +			tv.tv_sec = 1;
        +			tv.tv_usec = 0;
        +			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
        +			i=select(width,(void *)&readfds,NULL,NULL,&tv);
        +			if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
        +				continue;
        +			if (read(fileno(stdin), buf, 0) >= 0)
        +				read_from_terminal = 1;
        +			(void)fcntl(fileno(stdin), F_SETFL, 0);
        +#else
        +			if ((SSL_version(con) == DTLS1_VERSION) &&
        +				DTLSv1_get_timeout(con, &timeout))
        +				timeoutp = &timeout;
        +			else
        +				timeoutp = NULL;
        +
        +			i=select(width,(void *)&readfds,NULL,NULL,timeoutp);
        +
        +			if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
        +				{
        +				BIO_printf(bio_err,"TIMEOUT occured\n");
        +				}
        +
        +			if (i <= 0) continue;
        +			if (FD_ISSET(fileno(stdin),&readfds))
        +				read_from_terminal = 1;
        +#endif
        +			if (FD_ISSET(s,&readfds))
        +				read_from_sslcon = 1;
        +			}
        +		if (read_from_terminal)
        +			{
        +			if (s_crlf)
        +				{
        +				int j, lf_num;
        +
        +				i=raw_read_stdin(buf, bufsize/2);
        +				lf_num = 0;
        +				/* both loops are skipped when i <= 0 */
        +				for (j = 0; j < i; j++)
        +					if (buf[j] == '\n')
        +						lf_num++;
        +				for (j = i-1; j >= 0; j--)
        +					{
        +					buf[j+lf_num] = buf[j];
        +					if (buf[j] == '\n')
        +						{
        +						lf_num--;
        +						i++;
        +						buf[j+lf_num] = '\r';
        +						}
        +					}
        +				assert(lf_num == 0);
        +				}
        +			else
        +				i=raw_read_stdin(buf,bufsize);
        +			if (!s_quiet)
        +				{
        +				if ((i <= 0) || (buf[0] == 'Q'))
        +					{
        +					BIO_printf(bio_s_out,"DONE\n");
        +					SHUTDOWN(s);
        +					close_accept_socket();
        +					ret= -11;
        +					goto err;
        +					}
        +				if ((i <= 0) || (buf[0] == 'q'))
        +					{
        +					BIO_printf(bio_s_out,"DONE\n");
        +					if (SSL_version(con) != DTLS1_VERSION)
        +                        SHUTDOWN(s);
        +	/*				close_accept_socket();
        +					ret= -11;*/
        +					goto err;
        +					}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +				if ((buf[0] == 'B') &&
        +					((buf[1] == '\n') || (buf[1] == '\r')))
        +					{
        +					BIO_printf(bio_err,"HEARTBEATING\n");
        +					SSL_heartbeat(con);
        +					i=0;
        +					continue;
        +					}
        +#endif
        +				if ((buf[0] == 'r') && 
        +					((buf[1] == '\n') || (buf[1] == '\r')))
        +					{
        +					SSL_renegotiate(con);
        +					i=SSL_do_handshake(con);
        +					printf("SSL_do_handshake -> %d\n",i);
        +					i=0; /*13; */
        +					continue;
        +					/* strcpy(buf,"server side RE-NEGOTIATE\n"); */
        +					}
        +				if ((buf[0] == 'R') &&
        +					((buf[1] == '\n') || (buf[1] == '\r')))
        +					{
        +					SSL_set_verify(con,
        +						SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
        +					SSL_renegotiate(con);
        +					i=SSL_do_handshake(con);
        +					printf("SSL_do_handshake -> %d\n",i);
        +					i=0; /* 13; */
        +					continue;
        +					/* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
        +					}
        +				if (buf[0] == 'P')
        +					{
        +					static const char *str="Lets print some clear text\n";
        +					BIO_write(SSL_get_wbio(con),str,strlen(str));
        +					}
        +				if (buf[0] == 'S')
        +					{
        +					print_stats(bio_s_out,SSL_get_SSL_CTX(con));
        +					}
        +				}
        +#ifdef CHARSET_EBCDIC
        +			ebcdic2ascii(buf,buf,i);
        +#endif
        +			l=k=0;
        +			for (;;)
        +				{
        +				/* should do a select for the write */
        +#ifdef RENEG
        +{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
        +#endif
        +				k=SSL_write(con,&(buf[l]),(unsigned int)i);
        +#ifndef OPENSSL_NO_SRP
        +				while (SSL_get_error(con,k) == SSL_ERROR_WANT_X509_LOOKUP)
        +					{
        +					BIO_printf(bio_s_out,"LOOKUP renego during write\n");
        +					srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login); 
        +					if (srp_callback_parm.user) 
        +						BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
        +					else 
        +						BIO_printf(bio_s_out,"LOOKUP not successful\n");
        +						k=SSL_write(con,&(buf[l]),(unsigned int)i);
        +					}
        +#endif
        +				switch (SSL_get_error(con,k))
        +					{
        +				case SSL_ERROR_NONE:
        +					break;
        +				case SSL_ERROR_WANT_WRITE:
        +				case SSL_ERROR_WANT_READ:
        +				case SSL_ERROR_WANT_X509_LOOKUP:
        +					BIO_printf(bio_s_out,"Write BLOCK\n");
        +					break;
        +				case SSL_ERROR_SYSCALL:
        +				case SSL_ERROR_SSL:
        +					BIO_printf(bio_s_out,"ERROR\n");
        +					ERR_print_errors(bio_err);
        +					ret=1;
        +					goto err;
        +					/* break; */
        +				case SSL_ERROR_ZERO_RETURN:
        +					BIO_printf(bio_s_out,"DONE\n");
        +					ret=1;
        +					goto err;
        +					}
        +				l+=k;
        +				i-=k;
        +				if (i <= 0) break;
        +				}
        +			}
        +		if (read_from_sslcon)
        +			{
        +			if (!SSL_is_init_finished(con))
        +				{
        +				i=init_ssl_connection(con);
        +				
        +				if (i < 0)
        +					{
        +					ret=0;
        +					goto err;
        +					}
        +				else if (i == 0)
        +					{
        +					ret=1;
        +					goto err;
        +					}
        +				}
        +			else
        +				{
        +again:	
        +				i=SSL_read(con,(char *)buf,bufsize);
        +#ifndef OPENSSL_NO_SRP
        +				while (SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
        +					{
        +					BIO_printf(bio_s_out,"LOOKUP renego during read\n");
        +					srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login); 
        +					if (srp_callback_parm.user) 
        +						BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
        +					else 
        +						BIO_printf(bio_s_out,"LOOKUP not successful\n");
        +					i=SSL_read(con,(char *)buf,bufsize);
        +					}
        +#endif
        +				switch (SSL_get_error(con,i))
        +					{
        +				case SSL_ERROR_NONE:
        +#ifdef CHARSET_EBCDIC
        +					ascii2ebcdic(buf,buf,i);
        +#endif
        +					raw_write_stdout(buf,
        +						(unsigned int)i);
        +					if (SSL_pending(con)) goto again;
        +					break;
        +				case SSL_ERROR_WANT_WRITE:
        +				case SSL_ERROR_WANT_READ:
        +					BIO_printf(bio_s_out,"Read BLOCK\n");
        +					break;
        +				case SSL_ERROR_SYSCALL:
        +				case SSL_ERROR_SSL:
        +					BIO_printf(bio_s_out,"ERROR\n");
        +					ERR_print_errors(bio_err);
        +					ret=1;
        +					goto err;
        +				case SSL_ERROR_ZERO_RETURN:
        +					BIO_printf(bio_s_out,"DONE\n");
        +					ret=1;
        +					goto err;
        +					}
        +				}
        +			}
        +		}
        +err:
        +	if (con != NULL)
        +		{
        +		BIO_printf(bio_s_out,"shutting down SSL\n");
        +#if 1
        +		SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +#else
        +		SSL_shutdown(con);
        +#endif
        +		SSL_free(con);
        +		}
        +	BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
        +	if (buf != NULL)
        +		{
        +		OPENSSL_cleanse(buf,bufsize);
        +		OPENSSL_free(buf);
        +		}
        +	if (ret >= 0)
        +		BIO_printf(bio_s_out,"ACCEPT\n");
        +	return(ret);
        +	}
        +
        +static void close_accept_socket(void)
        +	{
        +	BIO_printf(bio_err,"shutdown accept socket\n");
        +	if (accept_socket >= 0)
        +		{
        +		SHUTDOWN2(accept_socket);
        +		}
        +	}
        +
        +static int init_ssl_connection(SSL *con)
        +	{
        +	int i;
        +	const char *str;
        +	X509 *peer;
        +	long verify_error;
        +	MS_STATIC char buf[BUFSIZ];
        +#ifndef OPENSSL_NO_KRB5
        +	char *client_princ;
        +#endif
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	const unsigned char *next_proto_neg;
        +	unsigned next_proto_neg_len;
        +#endif
        +	unsigned char *exportedkeymat;
        +
        +
        +	i=SSL_accept(con);
        +#ifndef OPENSSL_NO_SRP
        +	while (i <= 0 &&  SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP) 
        +		{
        +			BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
        +			srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login); 
        +			if (srp_callback_parm.user) 
        +				BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
        +			else 
        +				BIO_printf(bio_s_out,"LOOKUP not successful\n");
        +			i=SSL_accept(con);
        +		}
        +#endif
        +	if (i <= 0)
        +		{
        +		if (BIO_sock_should_retry(i))
        +			{
        +			BIO_printf(bio_s_out,"DELAY\n");
        +			return(1);
        +			}
        +
        +		BIO_printf(bio_err,"ERROR\n");
        +		verify_error=SSL_get_verify_result(con);
        +		if (verify_error != X509_V_OK)
        +			{
        +			BIO_printf(bio_err,"verify error:%s\n",
        +				X509_verify_cert_error_string(verify_error));
        +			}
        +		else
        +			ERR_print_errors(bio_err);
        +		return(0);
        +		}
        +
        +	PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
        +
        +	peer=SSL_get_peer_certificate(con);
        +	if (peer != NULL)
        +		{
        +		BIO_printf(bio_s_out,"Client certificate\n");
        +		PEM_write_bio_X509(bio_s_out,peer);
        +		X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
        +		BIO_printf(bio_s_out,"subject=%s\n",buf);
        +		X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
        +		BIO_printf(bio_s_out,"issuer=%s\n",buf);
        +		X509_free(peer);
        +		}
        +
        +	if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
        +		BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
        +	str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
        +	BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
        +	if (next_proto_neg)
        +		{
        +		BIO_printf(bio_s_out,"NEXTPROTO is ");
        +		BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
        +		BIO_printf(bio_s_out, "\n");
        +		}
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +	{
        +	SRTP_PROTECTION_PROFILE *srtp_profile
        +	  = SSL_get_selected_srtp_profile(con);
        +
        +	if(srtp_profile)
        +		BIO_printf(bio_s_out,"SRTP Extension negotiated, profile=%s\n",
        +			   srtp_profile->name);
        +	}
        +#endif
        +	if (SSL_cache_hit(con)) BIO_printf(bio_s_out,"Reused session-id\n");
        +	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
        +		TLS1_FLAGS_TLS_PADDING_BUG)
        +		BIO_printf(bio_s_out,
        +			   "Peer has incorrect TLSv1 block padding\n");
        +#ifndef OPENSSL_NO_KRB5
        +	client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
        +	if (client_princ != NULL)
        +		{
        +		BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
        +								client_princ);
        +		}
        +#endif /* OPENSSL_NO_KRB5 */
        +	BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
        +		      SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
        +	if (keymatexportlabel != NULL)
        +		{
        +		BIO_printf(bio_s_out, "Keying material exporter:\n");
        +		BIO_printf(bio_s_out, "    Label: '%s'\n", keymatexportlabel);
        +		BIO_printf(bio_s_out, "    Length: %i bytes\n",
        +			   keymatexportlen);
        +		exportedkeymat = OPENSSL_malloc(keymatexportlen);
        +		if (exportedkeymat != NULL)
        +			{
        +			if (!SSL_export_keying_material(con, exportedkeymat,
        +						        keymatexportlen,
        +						        keymatexportlabel,
        +						        strlen(keymatexportlabel),
        +						        NULL, 0, 0))
        +				{
        +				BIO_printf(bio_s_out, "    Error\n");
        +				}
        +			else
        +				{
        +				BIO_printf(bio_s_out, "    Keying material: ");
        +				for (i=0; i<keymatexportlen; i++)
        +					BIO_printf(bio_s_out, "%02X",
        +						   exportedkeymat[i]);
        +				BIO_printf(bio_s_out, "\n");
        +				}
        +			OPENSSL_free(exportedkeymat);
        +			}
        +		}
        +
        +	return(1);
        +	}
        +
        +#ifndef OPENSSL_NO_DH
        +static DH *load_dh_param(const char *dhfile)
        +	{
        +	DH *ret=NULL;
        +	BIO *bio;
        +
        +	if ((bio=BIO_new_file(dhfile,"r")) == NULL)
        +		goto err;
        +	ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
        +err:
        +	if (bio != NULL) BIO_free(bio);
        +	return(ret);
        +	}
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +	char *client_princ;
        +#endif
        +
        +#if 0
        +static int load_CA(SSL_CTX *ctx, char *file)
        +	{
        +	FILE *in;
        +	X509 *x=NULL;
        +
        +	if ((in=fopen(file,"r")) == NULL)
        +		return(0);
        +
        +	for (;;)
        +		{
        +		if (PEM_read_X509(in,&x,NULL) == NULL)
        +			break;
        +		SSL_CTX_add_client_CA(ctx,x);
        +		}
        +	if (x != NULL) X509_free(x);
        +	fclose(in);
        +	return(1);
        +	}
        +#endif
        +
        +static int www_body(char *hostname, int s, unsigned char *context)
        +	{
        +	char *buf=NULL;
        +	int ret=1;
        +	int i,j,k,dot;
        +	SSL *con;
        +	const SSL_CIPHER *c;
        +	BIO *io,*ssl_bio,*sbio;
        +#ifndef OPENSSL_NO_KRB5
        +	KSSL_CTX *kctx;
        +#endif
        +
        +	buf=OPENSSL_malloc(bufsize);
        +	if (buf == NULL) return(0);
        +	io=BIO_new(BIO_f_buffer());
        +	ssl_bio=BIO_new(BIO_f_ssl());
        +	if ((io == NULL) || (ssl_bio == NULL)) goto err;
        +
        +#ifdef FIONBIO	
        +	if (s_nbio)
        +		{
        +		unsigned long sl=1;
        +
        +		if (!s_quiet)
        +			BIO_printf(bio_err,"turning on non blocking io\n");
        +		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
        +			ERR_print_errors(bio_err);
        +		}
        +#endif
        +
        +	/* lets make the output buffer a reasonable size */
        +	if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
        +
        +	if ((con=SSL_new(ctx)) == NULL) goto err;
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (s_tlsextdebug)
        +			{
        +			SSL_set_tlsext_debug_callback(con, tlsext_cb);
        +			SSL_set_tlsext_debug_arg(con, bio_s_out);
        +			}
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +	if ((kctx = kssl_ctx_new()) != NULL)
        +		{
        +		kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
        +		kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
        +		}
        +#endif	/* OPENSSL_NO_KRB5 */
        +	if(context) SSL_set_session_id_context(con, context,
        +					       strlen((char *)context));
        +
        +	sbio=BIO_new_socket(s,BIO_NOCLOSE);
        +	if (s_nbio_test)
        +		{
        +		BIO *test;
        +
        +		test=BIO_new(BIO_f_nbio_test());
        +		sbio=BIO_push(test,sbio);
        +		}
        +	SSL_set_bio(con,sbio,sbio);
        +	SSL_set_accept_state(con);
        +
        +	/* SSL_set_fd(con,s); */
        +	BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
        +	BIO_push(io,ssl_bio);
        +#ifdef CHARSET_EBCDIC
        +	io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
        +#endif
        +
        +	if (s_debug)
        +		{
        +		SSL_set_debug(con, 1);
        +		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
        +		BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
        +		}
        +	if (s_msg)
        +		{
        +		SSL_set_msg_callback(con, msg_cb);
        +		SSL_set_msg_callback_arg(con, bio_s_out);
        +		}
        +
        +	for (;;)
        +		{
        +		if (hack)
        +			{
        +			i=SSL_accept(con);
        +#ifndef OPENSSL_NO_SRP
        +			while (i <= 0 &&  SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP) 
        +		{
        +			BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
        +			srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login); 
        +			if (srp_callback_parm.user) 
        +				BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
        +			else 
        +				BIO_printf(bio_s_out,"LOOKUP not successful\n");
        +			i=SSL_accept(con);
        +		}
        +#endif
        +			switch (SSL_get_error(con,i))
        +				{
        +			case SSL_ERROR_NONE:
        +				break;
        +			case SSL_ERROR_WANT_WRITE:
        +			case SSL_ERROR_WANT_READ:
        +			case SSL_ERROR_WANT_X509_LOOKUP:
        +				continue;
        +			case SSL_ERROR_SYSCALL:
        +			case SSL_ERROR_SSL:
        +			case SSL_ERROR_ZERO_RETURN:
        +				ret=1;
        +				goto err;
        +				/* break; */
        +				}
        +
        +			SSL_renegotiate(con);
        +			SSL_write(con,NULL,0);
        +			}
        +
        +		i=BIO_gets(io,buf,bufsize-1);
        +		if (i < 0) /* error */
        +			{
        +			if (!BIO_should_retry(io))
        +				{
        +				if (!s_quiet)
        +					ERR_print_errors(bio_err);
        +				goto err;
        +				}
        +			else
        +				{
        +				BIO_printf(bio_s_out,"read R BLOCK\n");
        +#if defined(OPENSSL_SYS_NETWARE)
        +            delay(1000);
        +#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
        +				sleep(1);
        +#endif
        +				continue;
        +				}
        +			}
        +		else if (i == 0) /* end of input */
        +			{
        +			ret=1;
        +			goto end;
        +			}
        +
        +		/* else we have data */
        +		if (	((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
        +			((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
        +			{
        +			char *p;
        +			X509 *peer;
        +			STACK_OF(SSL_CIPHER) *sk;
        +			static const char *space="                          ";
        +
        +			BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
        +			BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
        +			BIO_puts(io,"<pre>\n");
        +/*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
        +			BIO_puts(io,"\n");
        +			for (i=0; i<local_argc; i++)
        +				{
        +				BIO_puts(io,local_argv[i]);
        +				BIO_write(io," ",1);
        +				}
        +			BIO_puts(io,"\n");
        +
        +			BIO_printf(io,
        +				"Secure Renegotiation IS%s supported\n",
        +		      		SSL_get_secure_renegotiation_support(con) ?
        +							"" : " NOT");
        +
        +			/* The following is evil and should not really
        +			 * be done */
        +			BIO_printf(io,"Ciphers supported in s_server binary\n");
        +			sk=SSL_get_ciphers(con);
        +			j=sk_SSL_CIPHER_num(sk);
        +			for (i=0; i<j; i++)
        +				{
        +				c=sk_SSL_CIPHER_value(sk,i);
        +				BIO_printf(io,"%-11s:%-25s",
        +					SSL_CIPHER_get_version(c),
        +					SSL_CIPHER_get_name(c));
        +				if ((((i+1)%2) == 0) && (i+1 != j))
        +					BIO_puts(io,"\n");
        +				}
        +			BIO_puts(io,"\n");
        +			p=SSL_get_shared_ciphers(con,buf,bufsize);
        +			if (p != NULL)
        +				{
        +				BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
        +				j=i=0;
        +				while (*p)
        +					{
        +					if (*p == ':')
        +						{
        +						BIO_write(io,space,26-j);
        +						i++;
        +						j=0;
        +						BIO_write(io,((i%3)?" ":"\n"),1);
        +						}
        +					else
        +						{
        +						BIO_write(io,p,1);
        +						j++;
        +						}
        +					p++;
        +					}
        +				BIO_puts(io,"\n");
        +				}
        +			BIO_printf(io,(SSL_cache_hit(con)
        +				?"---\nReused, "
        +				:"---\nNew, "));
        +			c=SSL_get_current_cipher(con);
        +			BIO_printf(io,"%s, Cipher is %s\n",
        +				SSL_CIPHER_get_version(c),
        +				SSL_CIPHER_get_name(c));
        +			SSL_SESSION_print(io,SSL_get_session(con));
        +			BIO_printf(io,"---\n");
        +			print_stats(io,SSL_get_SSL_CTX(con));
        +			BIO_printf(io,"---\n");
        +			peer=SSL_get_peer_certificate(con);
        +			if (peer != NULL)
        +				{
        +				BIO_printf(io,"Client certificate\n");
        +				X509_print(io,peer);
        +				PEM_write_bio_X509(io,peer);
        +				}
        +			else
        +				BIO_puts(io,"no client certificate available\n");
        +			BIO_puts(io,"</BODY></HTML>\r\n\r\n");
        +			break;
        +			}
        +		else if ((www == 2 || www == 3)
        +                         && (strncmp("GET /",buf,5) == 0))
        +			{
        +			BIO *file;
        +			char *p,*e;
        +			static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
        +
        +			/* skip the '/' */
        +			p= &(buf[5]);
        +
        +			dot = 1;
        +			for (e=p; *e != '\0'; e++)
        +				{
        +				if (e[0] == ' ')
        +					break;
        +
        +				switch (dot)
        +					{
        +				case 1:
        +					dot = (e[0] == '.') ? 2 : 0;
        +					break;
        +				case 2:
        +					dot = (e[0] == '.') ? 3 : 0;
        +					break;
        +				case 3:
        +					dot = (e[0] == '/') ? -1 : 0;
        +					break;
        +					}
        +				if (dot == 0)
        +					dot = (e[0] == '/') ? 1 : 0;
        +				}
        +			dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
        +
        +			if (*e == '\0')
        +				{
        +				BIO_puts(io,text);
        +				BIO_printf(io,"'%s' is an invalid file name\r\n",p);
        +				break;
        +				}
        +			*e='\0';
        +
        +			if (dot)
        +				{
        +				BIO_puts(io,text);
        +				BIO_printf(io,"'%s' contains '..' reference\r\n",p);
        +				break;
        +				}
        +
        +			if (*p == '/')
        +				{
        +				BIO_puts(io,text);
        +				BIO_printf(io,"'%s' is an invalid path\r\n",p);
        +				break;
        +				}
        +
        +#if 0
        +			/* append if a directory lookup */
        +			if (e[-1] == '/')
        +				strcat(p,"index.html");
        +#endif
        +
        +			/* if a directory, do the index thang */
        +			if (app_isdir(p)>0)
        +				{
        +#if 0 /* must check buffer size */
        +				strcat(p,"/index.html");
        +#else
        +				BIO_puts(io,text);
        +				BIO_printf(io,"'%s' is a directory\r\n",p);
        +				break;
        +#endif
        +				}
        +
        +			if ((file=BIO_new_file(p,"r")) == NULL)
        +				{
        +				BIO_puts(io,text);
        +				BIO_printf(io,"Error opening '%s'\r\n",p);
        +				ERR_print_errors(io);
        +				break;
        +				}
        +
        +			if (!s_quiet)
        +				BIO_printf(bio_err,"FILE:%s\n",p);
        +
        +                        if (www == 2)
        +                                {
        +                                i=strlen(p);
        +                                if (	((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
        +                                        ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
        +                                        ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
        +                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
        +                                else
        +                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
        +                                }
        +			/* send the file */
        +			for (;;)
        +				{
        +				i=BIO_read(file,buf,bufsize);
        +				if (i <= 0) break;
        +
        +#ifdef RENEG
        +				total_bytes+=i;
        +				fprintf(stderr,"%d\n",i);
        +				if (total_bytes > 3*1024)
        +					{
        +					total_bytes=0;
        +					fprintf(stderr,"RENEGOTIATE\n");
        +					SSL_renegotiate(con);
        +					}
        +#endif
        +
        +				for (j=0; j<i; )
        +					{
        +#ifdef RENEG
        +{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }
        +#endif
        +					k=BIO_write(io,&(buf[j]),i-j);
        +					if (k <= 0)
        +						{
        +						if (!BIO_should_retry(io))
        +							goto write_error;
        +						else
        +							{
        +							BIO_printf(bio_s_out,"rwrite W BLOCK\n");
        +							}
        +						}
        +					else
        +						{
        +						j+=k;
        +						}
        +					}
        +				}
        +write_error:
        +			BIO_free(file);
        +			break;
        +			}
        +		}
        +
        +	for (;;)
        +		{
        +		i=(int)BIO_flush(io);
        +		if (i <= 0)
        +			{
        +			if (!BIO_should_retry(io))
        +				break;
        +			}
        +		else
        +			break;
        +		}
        +end:
        +#if 1
        +	/* make sure we re-use sessions */
        +	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +#else
        +	/* This kills performance */
        +/*	SSL_shutdown(con); A shutdown gets sent in the
        + *	BIO_free_all(io) procession */
        +#endif
        +
        +err:
        +
        +	if (ret >= 0)
        +		BIO_printf(bio_s_out,"ACCEPT\n");
        +
        +	if (buf != NULL) OPENSSL_free(buf);
        +	if (io != NULL) BIO_free_all(io);
        +/*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
        +	{
        +	BIGNUM *bn = NULL;
        +	static RSA *rsa_tmp=NULL;
        +
        +	if (!rsa_tmp && ((bn = BN_new()) == NULL))
        +		BIO_printf(bio_err,"Allocation error in generating RSA key\n");
        +	if (!rsa_tmp && bn)
        +		{
        +		if (!s_quiet)
        +			{
        +			BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
        +			(void)BIO_flush(bio_err);
        +			}
        +		if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
        +				!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
        +			{
        +			if(rsa_tmp) RSA_free(rsa_tmp);
        +			rsa_tmp = NULL;
        +			}
        +		if (!s_quiet)
        +			{
        +			BIO_printf(bio_err,"\n");
        +			(void)BIO_flush(bio_err);
        +			}
        +		BN_free(bn);
        +		}
        +	return(rsa_tmp);
        +	}
        +#endif
        +
        +#define MAX_SESSION_ID_ATTEMPTS 10
        +static int generate_session_id(const SSL *ssl, unsigned char *id,
        +				unsigned int *id_len)
        +	{
        +	unsigned int count = 0;
        +	do	{
        +		RAND_pseudo_bytes(id, *id_len);
        +		/* Prefix the session_id with the required prefix. NB: If our
        +		 * prefix is too long, clip it - but there will be worse effects
        +		 * anyway, eg. the server could only possibly create 1 session
        +		 * ID (ie. the prefix!) so all future session negotiations will
        +		 * fail due to conflicts. */
        +		memcpy(id, session_id_prefix,
        +			(strlen(session_id_prefix) < *id_len) ?
        +			strlen(session_id_prefix) : *id_len);
        +		}
        +	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
        +		(++count < MAX_SESSION_ID_ATTEMPTS));
        +	if(count >= MAX_SESSION_ID_ATTEMPTS)
        +		return 0;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/apps/s_socket.c b/vendor/openssl/openssl/apps/s_socket.c
        new file mode 100644
        index 000000000..380efdb1b
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s_socket.c
        @@ -0,0 +1,619 @@
        +/* apps/s_socket.c -  socket-related functions used by s_client and s_server */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <errno.h>
        +#include <signal.h>
        +
        +#ifdef FLAT_INC
        +#include "e_os2.h"
        +#else
        +#include "../e_os2.h"
        +#endif
        +
        +/* With IPv6, it looks like Digital has mixed up the proper order of
        +   recursive header file inclusion, resulting in the compiler complaining
        +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
        +   is needed to have fileno() declared correctly...  So let's define u_int */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
        +#define __U_INT
        +typedef unsigned int u_int;
        +#endif
        +
        +#define USE_SOCKETS
        +#define NON_MAIN
        +#include "apps.h"
        +#undef USE_SOCKETS
        +#undef NON_MAIN
        +#include "s_apps.h"
        +#include <openssl/ssl.h>
        +
        +#ifdef FLAT_INC
        +#include "e_os.h"
        +#else
        +#include "../e_os.h"
        +#endif
        +
        +#ifndef OPENSSL_NO_SOCK
        +
        +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
        +#include "netdb.h"
        +#endif
        +
        +static struct hostent *GetHostByName(char *name);
        +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
        +static void ssl_sock_cleanup(void);
        +#endif
        +static int ssl_sock_init(void);
        +static int init_client_ip(int *sock,unsigned char ip[4], int port, int type);
        +static int init_server(int *sock, int port, int type);
        +static int init_server_long(int *sock, int port,char *ip, int type);
        +static int do_accept(int acc_sock, int *sock, char **host);
        +static int host_ip(char *str, unsigned char ip[4]);
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define SOCKET_PROTOCOL	0 /* more microsoft stupidity */
        +#else
        +#define SOCKET_PROTOCOL	IPPROTO_TCP
        +#endif
        +
        +#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
        +static int wsa_init_done=0;
        +#endif
        +
        +#ifdef OPENSSL_SYS_WINDOWS
        +static struct WSAData wsa_state;
        +static int wsa_init_done=0;
        +
        +#ifdef OPENSSL_SYS_WIN16
        +static HWND topWnd=0;
        +static FARPROC lpTopWndProc=NULL;
        +static FARPROC lpTopHookProc=NULL;
        +extern HINSTANCE _hInstance;  /* nice global CRT provides */
        +
        +static LONG FAR PASCAL topHookProc(HWND hwnd, UINT message, WPARAM wParam,
        +	     LPARAM lParam)
        +	{
        +	if (hwnd == topWnd)
        +		{
        +		switch(message)
        +			{
        +		case WM_DESTROY:
        +		case WM_CLOSE:
        +			SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopWndProc);
        +			ssl_sock_cleanup();
        +			break;
        +			}
        +		}
        +	return CallWindowProc(lpTopWndProc,hwnd,message,wParam,lParam);
        +	}
        +
        +static BOOL CALLBACK enumproc(HWND hwnd,LPARAM lParam)
        +	{
        +	topWnd=hwnd;
        +	return(FALSE);
        +	}
        +
        +#endif /* OPENSSL_SYS_WIN32 */
        +#endif /* OPENSSL_SYS_WINDOWS */
        +
        +#ifdef OPENSSL_SYS_WINDOWS
        +static void ssl_sock_cleanup(void)
        +	{
        +	if (wsa_init_done)
        +		{
        +		wsa_init_done=0;
        +#ifndef OPENSSL_SYS_WINCE
        +		WSACancelBlockingCall();
        +#endif
        +		WSACleanup();
        +		}
        +	}
        +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
        +static void sock_cleanup(void)
        +    {
        +    if (wsa_init_done)
        +        {
        +        wsa_init_done=0;
        +		WSACleanup();
        +		}
        +	}
        +#endif
        +
        +static int ssl_sock_init(void)
        +	{
        +#ifdef WATT32
        +	extern int _watt_do_exit;
        +	_watt_do_exit = 0;
        +	if (sock_init())
        +		return (0);
        +#elif defined(OPENSSL_SYS_WINDOWS)
        +	if (!wsa_init_done)
        +		{
        +		int err;
        +	  
        +#ifdef SIGINT
        +		signal(SIGINT,(void (*)(int))ssl_sock_cleanup);
        +#endif
        +		wsa_init_done=1;
        +		memset(&wsa_state,0,sizeof(wsa_state));
        +		if (WSAStartup(0x0101,&wsa_state)!=0)
        +			{
        +			err=WSAGetLastError();
        +			BIO_printf(bio_err,"unable to start WINSOCK, error code=%d\n",err);
        +			return(0);
        +			}
        +
        +#ifdef OPENSSL_SYS_WIN16
        +		EnumTaskWindows(GetCurrentTask(),enumproc,0L);
        +		lpTopWndProc=(FARPROC)GetWindowLong(topWnd,GWL_WNDPROC);
        +		lpTopHookProc=MakeProcInstance((FARPROC)topHookProc,_hInstance);
        +
        +		SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc);
        +#endif /* OPENSSL_SYS_WIN16 */
        +		}
        +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
        +   WORD wVerReq;
        +   WSADATA wsaData;
        +   int err;
        +
        +   if (!wsa_init_done)
        +      {
        +   
        +# ifdef SIGINT
        +      signal(SIGINT,(void (*)(int))sock_cleanup);
        +# endif
        +
        +      wsa_init_done=1;
        +      wVerReq = MAKEWORD( 2, 0 );
        +      err = WSAStartup(wVerReq,&wsaData);
        +      if (err != 0)
        +         {
        +         BIO_printf(bio_err,"unable to start WINSOCK2, error code=%d\n",err);
        +         return(0);
        +         }
        +      }
        +#endif /* OPENSSL_SYS_WINDOWS */
        +	return(1);
        +	}
        +
        +int init_client(int *sock, char *host, int port, int type)
        +	{
        +	unsigned char ip[4];
        +
        +	memset(ip, '\0', sizeof ip);
        +	if (!host_ip(host,&(ip[0])))
        +		return 0;
        +	return init_client_ip(sock,ip,port,type);
        +	}
        +
        +static int init_client_ip(int *sock, unsigned char ip[4], int port, int type)
        +	{
        +	unsigned long addr;
        +	struct sockaddr_in them;
        +	int s,i;
        +
        +	if (!ssl_sock_init()) return(0);
        +
        +	memset((char *)&them,0,sizeof(them));
        +	them.sin_family=AF_INET;
        +	them.sin_port=htons((unsigned short)port);
        +	addr=(unsigned long)
        +		((unsigned long)ip[0]<<24L)|
        +		((unsigned long)ip[1]<<16L)|
        +		((unsigned long)ip[2]<< 8L)|
        +		((unsigned long)ip[3]);
        +	them.sin_addr.s_addr=htonl(addr);
        +
        +	if (type == SOCK_STREAM)
        +		s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
        +	else /* ( type == SOCK_DGRAM) */
        +		s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        +			
        +	if (s == INVALID_SOCKET) { perror("socket"); return(0); }
        +
        +#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
        +	if (type == SOCK_STREAM)
        +		{
        +		i=0;
        +		i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
        +		if (i < 0) { perror("keepalive"); return(0); }
        +		}
        +#endif
        +
        +	if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
        +		{ closesocket(s); perror("connect"); return(0); }
        +	*sock=s;
        +	return(1);
        +	}
        +
        +int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context)
        +	{
        +	int sock;
        +	char *name = NULL;
        +	int accept_socket = 0;
        +	int i;
        +
        +	if (!init_server(&accept_socket,port,type)) return(0);
        +
        +	if (ret != NULL)
        +		{
        +		*ret=accept_socket;
        +		/* return(1);*/
        +		}
        +  	for (;;)
        +  		{
        +		if (type==SOCK_STREAM)
        +			{
        +			if (do_accept(accept_socket,&sock,&name) == 0)
        +				{
        +				SHUTDOWN(accept_socket);
        +				return(0);
        +				}
        +			}
        +		else
        +			sock = accept_socket;
        +		i=(*cb)(name,sock, context);
        +		if (name != NULL) OPENSSL_free(name);
        +		if (type==SOCK_STREAM)
        +			SHUTDOWN2(sock);
        +		if (i < 0)
        +			{
        +			SHUTDOWN2(accept_socket);
        +			return(i);
        +			}
        +		}
        +	}
        +
        +static int init_server_long(int *sock, int port, char *ip, int type)
        +	{
        +	int ret=0;
        +	struct sockaddr_in server;
        +	int s= -1;
        +
        +	if (!ssl_sock_init()) return(0);
        +
        +	memset((char *)&server,0,sizeof(server));
        +	server.sin_family=AF_INET;
        +	server.sin_port=htons((unsigned short)port);
        +	if (ip == NULL)
        +		server.sin_addr.s_addr=INADDR_ANY;
        +	else
        +/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */
        +#ifndef BIT_FIELD_LIMITS
        +		memcpy(&server.sin_addr.s_addr,ip,4);
        +#else
        +		memcpy(&server.sin_addr,ip,4);
        +#endif
        +	
        +		if (type == SOCK_STREAM)
        +			s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
        +		else /* type == SOCK_DGRAM */
        +			s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
        +
        +	if (s == INVALID_SOCKET) goto err;
        +#if defined SOL_SOCKET && defined SO_REUSEADDR
        +		{
        +		int j = 1;
        +		setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
        +			   (void *) &j, sizeof j);
        +		}
        +#endif
        +	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
        +		{
        +#ifndef OPENSSL_SYS_WINDOWS
        +		perror("bind");
        +#endif
        +		goto err;
        +		}
        +	/* Make it 128 for linux */
        +	if (type==SOCK_STREAM && listen(s,128) == -1) goto err;
        +	*sock=s;
        +	ret=1;
        +err:
        +	if ((ret == 0) && (s != -1))
        +		{
        +		SHUTDOWN(s);
        +		}
        +	return(ret);
        +	}
        +
        +static int init_server(int *sock, int port, int type)
        +	{
        +	return(init_server_long(sock, port, NULL, type));
        +	}
        +
        +static int do_accept(int acc_sock, int *sock, char **host)
        +	{
        +	int ret;
        +	struct hostent *h1,*h2;
        +	static struct sockaddr_in from;
        +	int len;
        +/*	struct linger ling; */
        +
        +	if (!ssl_sock_init()) return(0);
        +
        +#ifndef OPENSSL_SYS_WINDOWS
        +redoit:
        +#endif
        +
        +	memset((char *)&from,0,sizeof(from));
        +	len=sizeof(from);
        +	/* Note: under VMS with SOCKETSHR the fourth parameter is currently
        +	 * of type (int *) whereas under other systems it is (void *) if
        +	 * you don't have a cast it will choke the compiler: if you do
        +	 * have a cast then you can either go for (int *) or (void *).
        +	 */
        +	ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len);
        +	if (ret == INVALID_SOCKET)
        +		{
        +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
        +		int i;
        +		i=WSAGetLastError();
        +		BIO_printf(bio_err,"accept error %d\n",i);
        +#else
        +		if (errno == EINTR)
        +			{
        +			/*check_timeout(); */
        +			goto redoit;
        +			}
        +		fprintf(stderr,"errno=%d ",errno);
        +		perror("accept");
        +#endif
        +		return(0);
        +		}
        +
        +/*
        +	ling.l_onoff=1;
        +	ling.l_linger=0;
        +	i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
        +	if (i < 0) { perror("linger"); return(0); }
        +	i=0;
        +	i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
        +	if (i < 0) { perror("keepalive"); return(0); }
        +*/
        +
        +	if (host == NULL) goto end;
        +#ifndef BIT_FIELD_LIMITS
        +	/* I should use WSAAsyncGetHostByName() under windows */
        +	h1=gethostbyaddr((char *)&from.sin_addr.s_addr,
        +		sizeof(from.sin_addr.s_addr),AF_INET);
        +#else
        +	h1=gethostbyaddr((char *)&from.sin_addr,
        +		sizeof(struct in_addr),AF_INET);
        +#endif
        +	if (h1 == NULL)
        +		{
        +		BIO_printf(bio_err,"bad gethostbyaddr\n");
        +		*host=NULL;
        +		/* return(0); */
        +		}
        +	else
        +		{
        +		if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL)
        +			{
        +			perror("OPENSSL_malloc");
        +			return(0);
        +			}
        +		BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
        +
        +		h2=GetHostByName(*host);
        +		if (h2 == NULL)
        +			{
        +			BIO_printf(bio_err,"gethostbyname failure\n");
        +			return(0);
        +			}
        +		if (h2->h_addrtype != AF_INET)
        +			{
        +			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
        +			return(0);
        +			}
        +		}
        +end:
        +	*sock=ret;
        +	return(1);
        +	}
        +
        +int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
        +	     short *port_ptr)
        +	{
        +	char *h,*p;
        +
        +	h=str;
        +	p=strchr(str,':');
        +	if (p == NULL)
        +		{
        +		BIO_printf(bio_err,"no port defined\n");
        +		return(0);
        +		}
        +	*(p++)='\0';
        +
        +	if ((ip != NULL) && !host_ip(str,ip))
        +		goto err;
        +	if (host_ptr != NULL) *host_ptr=h;
        +
        +	if (!extract_port(p,port_ptr))
        +		goto err;
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +static int host_ip(char *str, unsigned char ip[4])
        +	{
        +	unsigned int in[4]; 
        +	int i;
        +
        +	if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
        +		{
        +		for (i=0; i<4; i++)
        +			if (in[i] > 255)
        +				{
        +				BIO_printf(bio_err,"invalid IP address\n");
        +				goto err;
        +				}
        +		ip[0]=in[0];
        +		ip[1]=in[1];
        +		ip[2]=in[2];
        +		ip[3]=in[3];
        +		}
        +	else
        +		{ /* do a gethostbyname */
        +		struct hostent *he;
        +
        +		if (!ssl_sock_init()) return(0);
        +
        +		he=GetHostByName(str);
        +		if (he == NULL)
        +			{
        +			BIO_printf(bio_err,"gethostbyname failure\n");
        +			goto err;
        +			}
        +		/* cast to short because of win16 winsock definition */
        +		if ((short)he->h_addrtype != AF_INET)
        +			{
        +			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
        +			return(0);
        +			}
        +		ip[0]=he->h_addr_list[0][0];
        +		ip[1]=he->h_addr_list[0][1];
        +		ip[2]=he->h_addr_list[0][2];
        +		ip[3]=he->h_addr_list[0][3];
        +		}
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +int extract_port(char *str, short *port_ptr)
        +	{
        +	int i;
        +	struct servent *s;
        +
        +	i=atoi(str);
        +	if (i != 0)
        +		*port_ptr=(unsigned short)i;
        +	else
        +		{
        +		s=getservbyname(str,"tcp");
        +		if (s == NULL)
        +			{
        +			BIO_printf(bio_err,"getservbyname failure for %s\n",str);
        +			return(0);
        +			}
        +		*port_ptr=ntohs((unsigned short)s->s_port);
        +		}
        +	return(1);
        +	}
        +
        +#define GHBN_NUM	4
        +static struct ghbn_cache_st
        +	{
        +	char name[128];
        +	struct hostent ent;
        +	unsigned long order;
        +	} ghbn_cache[GHBN_NUM];
        +
        +static unsigned long ghbn_hits=0L;
        +static unsigned long ghbn_miss=0L;
        +
        +static struct hostent *GetHostByName(char *name)
        +	{
        +	struct hostent *ret;
        +	int i,lowi=0;
        +	unsigned long low= (unsigned long)-1;
        +
        +	for (i=0; i<GHBN_NUM; i++)
        +		{
        +		if (low > ghbn_cache[i].order)
        +			{
        +			low=ghbn_cache[i].order;
        +			lowi=i;
        +			}
        +		if (ghbn_cache[i].order > 0)
        +			{
        +			if (strncmp(name,ghbn_cache[i].name,128) == 0)
        +				break;
        +			}
        +		}
        +	if (i == GHBN_NUM) /* no hit*/
        +		{
        +		ghbn_miss++;
        +		ret=gethostbyname(name);
        +		if (ret == NULL) return(NULL);
        +		/* else add to cache */
        +		if(strlen(name) < sizeof ghbn_cache[0].name)
        +			{
        +			strcpy(ghbn_cache[lowi].name,name);
        +			memcpy((char *)&(ghbn_cache[lowi].ent),ret,sizeof(struct hostent));
        +			ghbn_cache[lowi].order=ghbn_miss+ghbn_hits;
        +			}
        +		return(ret);
        +		}
        +	else
        +		{
        +		ghbn_hits++;
        +		ret= &(ghbn_cache[i].ent);
        +		ghbn_cache[i].order=ghbn_miss+ghbn_hits;
        +		return(ret);
        +		}
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/apps/s_time.c b/vendor/openssl/openssl/apps/s_time.c
        new file mode 100644
        index 000000000..b823c33c5
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/s_time.c
        @@ -0,0 +1,632 @@
        +/* apps/s_time.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.]
        + */
        +
        +#define NO_SHUTDOWN
        +
        +/*-----------------------------------------
        +   s_time - SSL client connection timer program
        +   Written and donated by Larry Streepy <streepy@healthcare.com>
        +  -----------------------------------------*/
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#define USE_SOCKETS
        +#include "apps.h"
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include <openssl/pem.h>
        +#include "s_apps.h"
        +#include <openssl/err.h>
        +#ifdef WIN32_STUFF
        +#include "winmain.h"
        +#include "wintext.h"
        +#endif
        +#if !defined(OPENSSL_SYS_MSDOS)
        +#include OPENSSL_UNISTD
        +#endif
        +
        +#undef PROG
        +#define PROG s_time_main
        +
        +#undef ioctl
        +#define ioctl ioctlsocket
        +
        +#define SSL_CONNECT_NAME	"localhost:4433"
        +
        +/*#define TEST_CERT "client.pem" */ /* no default cert. */
        +
        +#undef BUFSIZZ
        +#define BUFSIZZ 1024*10
        +
        +#define MYBUFSIZ 1024*8
        +
        +#undef min
        +#undef max
        +#define min(a,b) (((a) < (b)) ? (a) : (b))
        +#define max(a,b) (((a) > (b)) ? (a) : (b))
        +
        +#undef SECONDS
        +#define SECONDS	30
        +extern int verify_depth;
        +extern int verify_error;
        +
        +static void s_time_usage(void);
        +static int parseArgs( int argc, char **argv );
        +static SSL *doConnection( SSL *scon );
        +static void s_time_init(void);
        +
        +/***********************************************************************
        + * Static data declarations
        + */
        +
        +/* static char *port=PORT_STR;*/
        +static char *host=SSL_CONNECT_NAME;
        +static char *t_cert_file=NULL;
        +static char *t_key_file=NULL;
        +static char *CApath=NULL;
        +static char *CAfile=NULL;
        +static char *tm_cipher=NULL;
        +static int tm_verify = SSL_VERIFY_NONE;
        +static int maxTime = SECONDS;
        +static SSL_CTX *tm_ctx=NULL;
        +static const SSL_METHOD *s_time_meth=NULL;
        +static char *s_www_path=NULL;
        +static long bytes_read=0; 
        +static int st_bugs=0;
        +static int perform=0;
        +#ifdef FIONBIO
        +static int t_nbio=0;
        +#endif
        +#ifdef OPENSSL_SYS_WIN32
        +static int exitNow = 0;		/* Set when it's time to exit main */
        +#endif
        +
        +static void s_time_init(void)
        +	{
        +	host=SSL_CONNECT_NAME;
        +	t_cert_file=NULL;
        +	t_key_file=NULL;
        +	CApath=NULL;
        +	CAfile=NULL;
        +	tm_cipher=NULL;
        +	tm_verify = SSL_VERIFY_NONE;
        +	maxTime = SECONDS;
        +	tm_ctx=NULL;
        +	s_time_meth=NULL;
        +	s_www_path=NULL;
        +	bytes_read=0; 
        +	st_bugs=0;
        +	perform=0;
        +
        +#ifdef FIONBIO
        +	t_nbio=0;
        +#endif
        +#ifdef OPENSSL_SYS_WIN32
        +	exitNow = 0;		/* Set when it's time to exit main */
        +#endif
        +	}
        +
        +/***********************************************************************
        + * usage - display usage message
        + */
        +static void s_time_usage(void)
        +{
        +	static char umsg[] = "\
        +-time arg     - max number of seconds to collect data, default %d\n\
        +-verify arg   - turn on peer certificate verification, arg == depth\n\
        +-cert arg     - certificate file to use, PEM format assumed\n\
        +-key arg      - RSA file to use, PEM format assumed, key is in cert file\n\
        +                file if not specified by this option\n\
        +-CApath arg   - PEM format directory of CA's\n\
        +-CAfile arg   - PEM format file of CA's\n\
        +-cipher       - preferred cipher to use, play with 'openssl ciphers'\n\n";
        +
        +	printf( "usage: s_time <args>\n\n" );
        +
        +	printf("-connect host:port - host:port to connect to (default is %s)\n",SSL_CONNECT_NAME);
        +#ifdef FIONBIO
        +	printf("-nbio         - Run with non-blocking IO\n");
        +	printf("-ssl2         - Just use SSLv2\n");
        +	printf("-ssl3         - Just use SSLv3\n");
        +	printf("-bugs         - Turn on SSL bug compatibility\n");
        +	printf("-new          - Just time new connections\n");
        +	printf("-reuse        - Just time connection reuse\n");
        +	printf("-www page     - Retrieve 'page' from the site\n");
        +#endif
        +	printf( umsg,SECONDS );
        +}
        +
        +/***********************************************************************
        + * parseArgs - Parse command line arguments and initialize data
        + *
        + * Returns 0 if ok, -1 on bad args
        + */
        +static int parseArgs(int argc, char **argv)
        +{
        +    int badop = 0;
        +
        +    verify_depth=0;
        +    verify_error=X509_V_OK;
        +
        +    argc--;
        +    argv++;
        +
        +    while (argc >= 1) {
        +	if (strcmp(*argv,"-connect") == 0)
        +		{
        +		if (--argc < 1) goto bad;
        +		host= *(++argv);
        +		}
        +#if 0
        +	else if( strcmp(*argv,"-host") == 0)
        +		{
        +		if (--argc < 1) goto bad;
        +		host= *(++argv);
        +		}
        +	else if( strcmp(*argv,"-port") == 0)
        +		{
        +		if (--argc < 1) goto bad;
        +		port= *(++argv);
        +		}
        +#endif
        +	else if (strcmp(*argv,"-reuse") == 0)
        +		perform=2;
        +	else if (strcmp(*argv,"-new") == 0)
        +		perform=1;
        +	else if( strcmp(*argv,"-verify") == 0) {
        +
        +	    tm_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
        +	    if (--argc < 1) goto bad;
        +	    verify_depth=atoi(*(++argv));
        +	    BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
        +
        +	} else if( strcmp(*argv,"-cert") == 0) {
        +
        +	    if (--argc < 1) goto bad;
        +	    t_cert_file= *(++argv);
        +
        +	} else if( strcmp(*argv,"-key") == 0) {
        +
        +	    if (--argc < 1) goto bad;
        +	    t_key_file= *(++argv);
        +
        +	} else if( strcmp(*argv,"-CApath") == 0) {
        +
        +	    if (--argc < 1) goto bad;
        +	    CApath= *(++argv);
        +
        +	} else if( strcmp(*argv,"-CAfile") == 0) {
        +
        +	    if (--argc < 1) goto bad;
        +	    CAfile= *(++argv);
        +
        +	} else if( strcmp(*argv,"-cipher") == 0) {
        +
        +	    if (--argc < 1) goto bad;
        +	    tm_cipher= *(++argv);
        +	}
        +#ifdef FIONBIO
        +	else if(strcmp(*argv,"-nbio") == 0) {
        +	    t_nbio=1;
        +	}
        +#endif
        +	else if(strcmp(*argv,"-www") == 0)
        +		{
        +		if (--argc < 1) goto bad;
        +		s_www_path= *(++argv);
        +		if(strlen(s_www_path) > MYBUFSIZ-100)
        +			{
        +			BIO_printf(bio_err,"-www option too long\n");
        +			badop=1;
        +			}
        +		}
        +	else if(strcmp(*argv,"-bugs") == 0)
        +	    st_bugs=1;
        +#ifndef OPENSSL_NO_SSL2
        +	else if(strcmp(*argv,"-ssl2") == 0)
        +	    s_time_meth=SSLv2_client_method();
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +	else if(strcmp(*argv,"-ssl3") == 0)
        +	    s_time_meth=SSLv3_client_method();
        +#endif
        +	else if( strcmp(*argv,"-time") == 0) {
        +
        +	    if (--argc < 1) goto bad;
        +	    maxTime= atoi(*(++argv));
        +	}
        +	else {
        +	    BIO_printf(bio_err,"unknown option %s\n",*argv);
        +	    badop=1;
        +	    break;
        +	}
        +
        +	argc--;
        +	argv++;
        +    }
        +
        +    if (perform == 0) perform=3;
        +
        +    if(badop) {
        +bad:
        +		s_time_usage();
        +		return -1;
        +    }
        +
        +	return 0;			/* Valid args */
        +}
        +
        +/***********************************************************************
        + * TIME - time functions
        + */
        +#define START	0
        +#define STOP	1
        +
        +static double tm_Time_F(int s)
        +	{
        +	return app_tminterval(s,1);
        +	}
        +
        +/***********************************************************************
        + * MAIN - main processing area for client
        + *			real name depends on MONOLITH
        + */
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	double totalTime = 0.0;
        +	int nConn = 0;
        +	SSL *scon=NULL;
        +	long finishtime=0;
        +	int ret=1,i;
        +	MS_STATIC char buf[1024*8];
        +	int ver;
        +
        +	apps_startup();
        +	s_time_init();
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +	s_time_meth=SSLv23_client_method();
        +#elif !defined(OPENSSL_NO_SSL3)
        +	s_time_meth=SSLv3_client_method();
        +#elif !defined(OPENSSL_NO_SSL2)
        +	s_time_meth=SSLv2_client_method();
        +#endif
        +
        +	/* parse the command line arguments */
        +	if( parseArgs( argc, argv ) < 0 )
        +		goto end;
        +
        +	OpenSSL_add_ssl_algorithms();
        +	if ((tm_ctx=SSL_CTX_new(s_time_meth)) == NULL) return(1);
        +
        +	SSL_CTX_set_quiet_shutdown(tm_ctx,1);
        +
        +	if (st_bugs) SSL_CTX_set_options(tm_ctx,SSL_OP_ALL);
        +	SSL_CTX_set_cipher_list(tm_ctx,tm_cipher);
        +	if(!set_cert_stuff(tm_ctx,t_cert_file,t_key_file)) 
        +		goto end;
        +
        +	SSL_load_error_strings();
        +
        +	if ((!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(tm_ctx)))
        +		{
        +		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
        +		ERR_print_errors(bio_err);
        +		/* goto end; */
        +		}
        +
        +	if (tm_cipher == NULL)
        +		tm_cipher = getenv("SSL_CIPHER");
        +
        +	if (tm_cipher == NULL ) {
        +		fprintf( stderr, "No CIPHER specified\n" );
        +	}
        +
        +	if (!(perform & 1)) goto next;
        +	printf( "Collecting connection statistics for %d seconds\n", maxTime );
        +
        +	/* Loop and time how long it takes to make connections */
        +
        +	bytes_read=0;
        +	finishtime=(long)time(NULL)+maxTime;
        +	tm_Time_F(START);
        +	for (;;)
        +		{
        +		if (finishtime < (long)time(NULL)) break;
        +#ifdef WIN32_STUFF
        +
        +		if( flushWinMsgs(0) == -1 )
        +			goto end;
        +
        +		if( waitingToDie || exitNow )		/* we're dead */
        +			goto end;
        +#endif
        +
        +		if( (scon = doConnection( NULL )) == NULL )
        +			goto end;
        +
        +		if (s_www_path != NULL)
        +			{
        +			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
        +			SSL_write(scon,buf,strlen(buf));
        +			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
        +				bytes_read+=i;
        +			}
        +
        +#ifdef NO_SHUTDOWN
        +		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +#else
        +		SSL_shutdown(scon);
        +#endif
        +		SHUTDOWN2(SSL_get_fd(scon));
        +
        +		nConn += 1;
        +		if (SSL_session_reused(scon))
        +			ver='r';
        +		else
        +			{
        +			ver=SSL_version(scon);
        +			if (ver == TLS1_VERSION)
        +				ver='t';
        +			else if (ver == SSL3_VERSION)
        +				ver='3';
        +			else if (ver == SSL2_VERSION)
        +				ver='2';
        +			else
        +				ver='*';
        +			}
        +		fputc(ver,stdout);
        +		fflush(stdout);
        +
        +		SSL_free( scon );
        +		scon=NULL;
        +		}
        +	totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
        +
        +	i=(int)((long)time(NULL)-finishtime+maxTime);
        +	printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
        +	printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);
        +
        +	/* Now loop and time connections using the same session id over and over */
        +
        +next:
        +	if (!(perform & 2)) goto end;
        +	printf( "\n\nNow timing with session id reuse.\n" );
        +
        +	/* Get an SSL object so we can reuse the session id */
        +	if( (scon = doConnection( NULL )) == NULL )
        +		{
        +		fprintf( stderr, "Unable to get connection\n" );
        +		goto end;
        +		}
        +
        +	if (s_www_path != NULL)
        +		{
        +		BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
        +		SSL_write(scon,buf,strlen(buf));
        +		while (SSL_read(scon,buf,sizeof(buf)) > 0)
        +			;
        +		}
        +#ifdef NO_SHUTDOWN
        +	SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +#else
        +	SSL_shutdown(scon);
        +#endif
        +	SHUTDOWN2(SSL_get_fd(scon));
        +
        +	nConn = 0;
        +	totalTime = 0.0;
        +
        +	finishtime=(long)time(NULL)+maxTime;
        +
        +	printf( "starting\n" );
        +	bytes_read=0;
        +	tm_Time_F(START);
        +		
        +	for (;;)
        +		{
        +		if (finishtime < (long)time(NULL)) break;
        +
        +#ifdef WIN32_STUFF
        +		if( flushWinMsgs(0) == -1 )
        +			goto end;
        +
        +		if( waitingToDie || exitNow )	/* we're dead */
        +			goto end;
        +#endif
        +
        +	 	if( (doConnection( scon )) == NULL )
        +			goto end;
        +
        +		if (s_www_path)
        +			{
        +			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
        +			SSL_write(scon,buf,strlen(buf));
        +			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
        +				bytes_read+=i;
        +			}
        +
        +#ifdef NO_SHUTDOWN
        +		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +#else
        +		SSL_shutdown(scon);
        +#endif
        +		SHUTDOWN2(SSL_get_fd(scon));
        +	
        +		nConn += 1;
        +		if (SSL_session_reused(scon))
        +			ver='r';
        +		else
        +			{
        +			ver=SSL_version(scon);
        +			if (ver == TLS1_VERSION)
        +				ver='t';
        +			else if (ver == SSL3_VERSION)
        +				ver='3';
        +			else if (ver == SSL2_VERSION)
        +				ver='2';
        +			else
        +				ver='*';
        +			}
        +		fputc(ver,stdout);
        +		fflush(stdout);
        +		}
        +	totalTime += tm_Time_F(STOP); /* Add the time for this iteration*/
        +
        +
        +	printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
        +	printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);
        +
        +	ret=0;
        +end:
        +	if (scon != NULL) SSL_free(scon);
        +
        +	if (tm_ctx != NULL)
        +		{
        +		SSL_CTX_free(tm_ctx);
        +		tm_ctx=NULL;
        +		}
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +/***********************************************************************
        + * doConnection - make a connection
        + * Args:
        + *		scon	= earlier ssl connection for session id, or NULL
        + * Returns:
        + *		SSL *	= the connection pointer.
        + */
        +static SSL *doConnection(SSL *scon)
        +	{
        +	BIO *conn;
        +	SSL *serverCon;
        +	int width, i;
        +	fd_set readfds;
        +
        +	if ((conn=BIO_new(BIO_s_connect())) == NULL)
        +		return(NULL);
        +
        +/*	BIO_set_conn_port(conn,port);*/
        +	BIO_set_conn_hostname(conn,host);
        +
        +	if (scon == NULL)
        +		serverCon=SSL_new(tm_ctx);
        +	else
        +		{
        +		serverCon=scon;
        +		SSL_set_connect_state(serverCon);
        +		}
        +
        +	SSL_set_bio(serverCon,conn,conn);
        +
        +#if 0
        +	if( scon != NULL )
        +		SSL_set_session(serverCon,SSL_get_session(scon));
        +#endif
        +
        +	/* ok, lets connect */
        +	for(;;) {
        +		i=SSL_connect(serverCon);
        +		if (BIO_sock_should_retry(i))
        +			{
        +			BIO_printf(bio_err,"DELAY\n");
        +
        +			i=SSL_get_fd(serverCon);
        +			width=i+1;
        +			FD_ZERO(&readfds);
        +			openssl_fdset(i,&readfds);
        +			/* Note: under VMS with SOCKETSHR the 2nd parameter
        +			 * is currently of type (int *) whereas under other
        +			 * systems it is (void *) if you don't have a cast it
        +			 * will choke the compiler: if you do have a cast then
        +			 * you can either go for (int *) or (void *).
        +			 */
        +			select(width,(void *)&readfds,NULL,NULL,NULL);
        +			continue;
        +			}
        +		break;
        +		}
        +	if(i <= 0)
        +		{
        +		BIO_printf(bio_err,"ERROR\n");
        +		if (verify_error != X509_V_OK)
        +			BIO_printf(bio_err,"verify error:%s\n",
        +				X509_verify_cert_error_string(verify_error));
        +		else
        +			ERR_print_errors(bio_err);
        +		if (scon == NULL)
        +			SSL_free(serverCon);
        +		return NULL;
        +		}
        +
        +	return serverCon;
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/apps/server.pem b/vendor/openssl/openssl/apps/server.pem
        new file mode 100644
        index 000000000..d0fc265f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/server.pem
        @@ -0,0 +1,52 @@
        +subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert
        +issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
        +-----BEGIN CERTIFICATE-----
        +MIID5zCCAs+gAwIBAgIJALnu1NlVpZ6zMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
        +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
        +ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZDELMAkG
        +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
        +RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQw
        +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJ
        +KCLTuf7g3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfi
        +R7bfSdI/+qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMv
        +vPQGuI+OEAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7
        +TVcGVSEiJdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU
        +41NEWAsu/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8R
        +AgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJYIZI
        +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
        +BBSCvM8AABPR9zklmifnr9LvIBturDAfBgNVHSMEGDAWgBQ2w2yI55X+sL3szj49
        +hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEAqb1NV0B0/pbpK9Z4/bNjzPQLTRLK
        +WnSNm/Jh5v0GEUOE/Beg7GNjNrmeNmqxAlpqWz9qoeoFZax+QBpIZYjROU3TS3fp
        +yLsrnlr0CDQ5R7kCCDGa8dkXxemmpZZLbUCpW2Uoy8sAA4JjN9OtsZY7dvUXFgJ7
        +vVNTRnI01ghknbtD+2SxSQd3CWF6QhcRMAzZJ1z1cbbwGDDzfvGFPzJ+Sq+zEPds
        +xoVLLSetCiBc+40ZcDS5dV98h9XD7JMTQfxzA7mNGv73JoZJA6nFgj+ADSlJsY/t
        +JBv+z1iQRueoh9Qeee+ZbRifPouCB8FDx+AltvHTANdAq0t/K3o+pplMVA==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv
        +h4VZS2axxfV6hV3CD9MuKVg2zEhroqK1Js5n4ke230nSP/qiELfCl0R+hzRtbfKL
        +tFUr1iHeU0uQ6v3q+Tg1K/Tmmg72uxKrhyHDL7z0BriPjhAHJ5XlQsvR1RCMkqzu
        +D9wjSInJxpMMIgLndOclAKv4D1wQtYU7ZpTw+01XBlUhIiXb86qpYL9NqnnRq5JI
        +uhmOEuxo2ca63+xaHNhD/udSyc8C0Md/yX6wlONTRFgLLv0pdLUGm1xEjfsydaQ6
        +qGd7hzIKUI3hohNKJa/mHLElv7SZolPTogK/EQIDAQABAoIBAADq9FwNtuE5IRQn
        +zGtO4q7Y5uCzZ8GDNYr9RKp+P2cbuWDbvVAecYq2NV9QoIiWJOAYZKklOvekIju3
        +r0UZLA0PRiIrTg6NrESx3JrjWDK8QNlUO7CPTZ39/K+FrmMkV9lem9yxjJjyC34D
        +AQB+YRTx+l14HppjdxNwHjAVQpIx/uO2F5xAMuk32+3K+pq9CZUtrofe1q4Agj9R
        +5s8mSy9pbRo9kW9wl5xdEotz1LivFOEiqPUJTUq5J5PeMKao3vdK726XI4Z455Nm
        +W2/MA0YV0ug2FYinHcZdvKM6dimH8GLfa3X8xKRfzjGjTiMSwsdjgMa4awY3tEHH
        +674jhAECgYEA/zqMrc0zsbNk83sjgaYIug5kzEpN4ic020rSZsmQxSCerJTgNhmg
        +utKSCt0Re09Jt3LqG48msahX8ycqDsHNvlEGPQSbMu9IYeO3Wr3fAm75GEtFWePY
        +BhM73I7gkRt4s8bUiUepMG/wY45c5tRF23xi8foReHFFe9MDzh8fJFECgYEA9EFX
        +4qAik1pOJGNei9BMwmx0I0gfVEIgu0tzeVqT45vcxbxr7RkTEaDoAG6PlbWP6D9a
        +WQNLp4gsgRM90ZXOJ4up5DsAWDluvaF4/omabMA+MJJ5kGZ0gCj5rbZbKqUws7x8
        +bp+6iBfUPJUbcqNqFmi/08Yt7vrDnMnyMw2A/sECgYEAiiuRMxnuzVm34hQcsbhH
        +6ymVqf7j0PW2qK0F4H1ocT9qhzWFd+RB3kHWrCjnqODQoI6GbGr/4JepHUpre1ex
        +4UEN5oSS3G0ru0rC3U4C59dZ5KwDHFm7ffZ1pr52ljfQDUsrjjIMRtuiwNK2OoRa
        +WSsqiaL+SDzSB+nBmpnAizECgYBdt/y6rerWUx4MhDwwtTnel7JwHyo2MDFS6/5g
        +n8qC2Lj6/fMDRE22w+CA2esp7EJNQJGv+b27iFpbJEDh+/Lf5YzIT4MwVskQ5bYB
        +JFcmRxUVmf4e09D7o705U/DjCgMH09iCsbLmqQ38ONIRSHZaJtMDtNTHD1yi+jF+
        +OT43gQKBgQC/2OHZoko6iRlNOAQ/tMVFNq7fL81GivoQ9F1U0Qr+DH3ZfaH8eIkX
        +xT0ToMPJUzWAn8pZv0snA0um6SIgvkCuxO84OkANCVbttzXImIsL7pFzfcwV/ERK
        +UM6j0ZuSMFOCr/lGPAoOQU0fskidGEHi1/kW+suSr28TqsyYZpwBDQ==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/server.srl b/vendor/openssl/openssl/apps/server.srl
        new file mode 100644
        index 000000000..8a0f05e16
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/server.srl
        @@ -0,0 +1 @@
        +01
        diff --git a/vendor/openssl/openssl/apps/server2.pem b/vendor/openssl/openssl/apps/server2.pem
        new file mode 100644
        index 000000000..a3927cf78
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/server2.pem
        @@ -0,0 +1,52 @@
        +subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert #2
        +issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
        +-----BEGIN CERTIFICATE-----
        +MIID6jCCAtKgAwIBAgIJALnu1NlVpZ60MA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
        +VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
        +ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZzELMAkG
        +A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
        +RVNUSU5HIFBVUlBPU0VTIE9OTFkxHDAaBgNVBAMME1Rlc3QgU2VydmVyIENlcnQg
        +IzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrdi7j9yctG+L4EjBy
        +gjPmEqZzOJEQba26MoQGzglU7e5Xf59Rb/hgVQuKAoiZe7/R8rK4zJ4W7iXdXw0L
        +qBpyG8B5aGKeI32w+A9TcBApoXXL2CrYQEQjZwUIpLlYBIi2NkJj3nVkq5dgl1gO
        +ALiQ+W8jg3kzg5Ec9rimp9r93N8wsSL3awsafurmYCvOf7leHaMP1WJ/zDRGUNHG
        +/WtDjXc8ZUG1+6EXU9Jc2Fs+2Omf7fcN0l00AK/wPg8OaNS0rKyGq9JdIT9FRGV1
        +bXe/rx58FaE5CItdwCSYhJvF/O95LWQoxJXye5bCFLmvDTEyVq9FMSCptfsmbXjE
        +ZGsXAgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJ
        +YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud
        +DgQWBBR52UaWWTKzZGDH/X4mWNcuqeQVazAfBgNVHSMEGDAWgBQ2w2yI55X+sL3s
        +zj49hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEANBW+XYLlHBqVY/31ie+3gRlS
        +LPfy4SIqn0t3RJjagT29MXprblBO2cbMO8VGjkQdKGpmMXjxbht2arOOUXRHX4n/
        +XTyn/QHEf0bcwIITMReO3DZUPAEw8hSjn9xEOM0IRVOCP+mH5fi74QzzQaZVCyYg
        +5VtLKdww/+sc0nCbKl2KWgDluriH0nfVx95qgW3mg9dhXRr0zmf1w2zkBHYpARYL
        +Dew6Z8EE4tS3HJu8/qM6meWzNtrfonQ3eiiMxjZBxzV46jchBwa2z9XYhP6AmpPb
        +oeTSzcQNbWsxaGYzWo46oLDUZmJOwSBawbS31bZNMCoPIY6ukoesCzFSsUKZww==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIEowIBAAKCAQEA63Yu4/cnLRvi+BIwcoIz5hKmcziREG2tujKEBs4JVO3uV3+f
        +UW/4YFULigKImXu/0fKyuMyeFu4l3V8NC6gachvAeWhiniN9sPgPU3AQKaF1y9gq
        +2EBEI2cFCKS5WASItjZCY951ZKuXYJdYDgC4kPlvI4N5M4ORHPa4pqfa/dzfMLEi
        +92sLGn7q5mArzn+5Xh2jD9Vif8w0RlDRxv1rQ413PGVBtfuhF1PSXNhbPtjpn+33
        +DdJdNACv8D4PDmjUtKyshqvSXSE/RURldW13v68efBWhOQiLXcAkmISbxfzveS1k
        +KMSV8nuWwhS5rw0xMlavRTEgqbX7Jm14xGRrFwIDAQABAoIBAHLsTPihIfLnYIE5
        +x4GsQQ5zXeBw5ITDM37ktwHnQDC+rIzyUl1aLD1AZRBoKinXd4lOTqLZ4/NHKx4A
        +DYr58mZtWyUmqLOMmQVuHXTZBlp7XtYuXMMNovQwjQlp9LicBeoBU6gQ5PVMtubD
        +F4xGF89Sn0cTHW3iMkqTtQ5KcR1j57OcJO0FEb1vPvk2MXI5ZyAatUYE7YacbEzd
        +rg02uIwx3FqNSkuSI79uz4hMdV5TPtuhxx9nTwj9aLUhXFeZ0mn2PVgVzEnnMoJb
        ++znlsZDgzDlJqdaD744YGWh8Z3OEssB35KfzFcdOeO6yH8lmv2Zfznk7pNPT7LTb
        +Lae9VgkCgYEA92p1qnAB3NtJtNcaW53i0S5WJgS1hxWKvUDx3lTB9s8X9fHpqL1a
        +E94fDfWzp/hax6FefUKIvBOukPLQ6bYjTMiFoOHzVirghAIuIUoMI5VtLhwD1hKs
        +Lr7l/dptMgKb1nZHyXoKHRBthsy3K4+udsPi8TzMvYElgEqyQIe/Rk0CgYEA86GL
        +8HC6zLszzKERDPBxrboRmoFvVUCTQDhsfj1M8aR3nQ8V5LkdIJc7Wqm/Ggfk9QRf
        +rJ8M2WUMlU5CNnCn/KCrKzCNZIReze3fV+HnKdbcXGLvgbHPrhnz8yYehUFG+RGq
        +bVyDWRU94T38izy2s5qMYrMJWZEYyXncSPbfcPMCgYAtaXfxcZ+V5xYPQFARMtiX
        +5nZfggvDoJuXgx0h3tK/N2HBfcaSdzbaYLG4gTmZggc/jwnl2dl5E++9oSPhUdIG
        +3ONSFUbxsOsGr9PBvnKd8WZZyUCXAVRjPBzAzF+whzQNWCZy/5htnz9LN7YDI9s0
        +5113Q96cheDZPFydZY0hHQKBgQDVbEhNukM5xCiNcu+f2SaMnLp9EjQ4h5g3IvaP
        +5B16daw/Dw8LzcohWboqIxeAsze0GD/D1ZUJAEd0qBjC3g+a9BjefervCjKOzXng
        +38mEUm+6EwVjJSQcjSmycEs+Sr/kwr/8i5WYvU32+jk4tFgMoC+o6tQe/Uesf68k
        +z/dPVwKBgGbF7Vv1/3SmhlOy+zYyvJ0CrWtKxH9QP6tLIEgEpd8x7YTSuCH94yok
        +kToMXYA3sWNPt22GbRDZ+rcp4c7HkDx6I6vpdP9aQEwJTp0EPy0sgWr2XwYmreIQ
        +NFmkk8Itn9EY2R9VBaP7GLv5kvwxDdLAnmwGmzVtbmaVdxCaBwUk
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/apps/sess_id.c b/vendor/openssl/openssl/apps/sess_id.c
        new file mode 100644
        index 000000000..b16686c26
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/sess_id.c
        @@ -0,0 +1,322 @@
        +/* apps/sess_id.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +
        +#undef PROG
        +#define PROG	sess_id_main
        +
        +static const char *sess_id_usage[]={
        +"usage: sess_id args\n",
        +"\n",
        +" -inform arg     - input format - default PEM (DER or PEM)\n",
        +" -outform arg    - output format - default PEM\n",
        +" -in arg         - input file - default stdin\n",
        +" -out arg        - output file - default stdout\n",
        +" -text           - print ssl session id details\n",
        +" -cert           - output certificate \n",
        +" -noout          - no CRL output\n",
        +" -context arg    - set the session ID context\n",
        +NULL
        +};
        +
        +static SSL_SESSION *load_sess_id(char *file, int format);
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	SSL_SESSION *x=NULL;
        +	X509 *peer = NULL;
        +	int ret=1,i,num,badops=0;
        +	BIO *out=NULL;
        +	int informat,outformat;
        +	char *infile=NULL,*outfile=NULL,*context=NULL;
        +	int cert=0,noout=0,text=0;
        +	const char **pp;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +
        +	argc--;
        +	argv++;
        +	num=0;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-text") == 0)
        +			text= ++num;
        +		else if (strcmp(*argv,"-cert") == 0)
        +			cert= ++num;
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout= ++num;
        +		else if (strcmp(*argv,"-context") == 0)
        +		    {
        +		    if(--argc < 1) goto bad;
        +		    context=*++argv;
        +		    }
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		for (pp=sess_id_usage; (*pp != NULL); pp++)
        +			BIO_printf(bio_err,"%s",*pp);
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +	x=load_sess_id(infile,informat);
        +	if (x == NULL) { goto end; }
        +	peer = SSL_SESSION_get0_peer(x);
        +
        +	if(context)
        +	    {
        +	    size_t ctx_len = strlen(context);
        +	    if(ctx_len > SSL_MAX_SID_CTX_LENGTH)
        +		{
        +		BIO_printf(bio_err,"Context too long\n");
        +		goto end;
        +		}
        +	    SSL_SESSION_set1_id_context(x, (unsigned char *)context, ctx_len);
        +	    }
        +
        +#ifdef undef
        +	/* just testing for memory leaks :-) */
        +	{
        +	SSL_SESSION *s;
        +	char buf[1024*10],*p;
        +	int i;
        +
        +	s=SSL_SESSION_new();
        +
        +	p= &buf;
        +	i=i2d_SSL_SESSION(x,&p);
        +	p= &buf;
        +	d2i_SSL_SESSION(&s,&p,(long)i);
        +	p= &buf;
        +	d2i_SSL_SESSION(&s,&p,(long)i);
        +	p= &buf;
        +	d2i_SSL_SESSION(&s,&p,(long)i);
        +	SSL_SESSION_free(s);
        +	}
        +#endif
        +
        +	if (!noout || text)
        +		{
        +		out=BIO_new(BIO_s_file());
        +		if (out == NULL)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		if (outfile == NULL)
        +			{
        +			BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +			}
        +		else
        +			{
        +			if (BIO_write_filename(out,outfile) <= 0)
        +				{
        +				perror(outfile);
        +				goto end;
        +				}
        +			}
        +		}
        +
        +	if (text)
        +		{
        +		SSL_SESSION_print(out,x);
        +
        +		if (cert)
        +			{
        +			if (peer == NULL)
        +				BIO_puts(out,"No certificate present\n");
        +			else
        +				X509_print(out,peer);
        +			}
        +		}
        +
        +	if (!noout && !cert)
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=i2d_SSL_SESSION_bio(out,x);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_SSL_SESSION(out,x);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i) {
        +			BIO_printf(bio_err,"unable to write SSL_SESSION\n");
        +			goto end;
        +			}
        +		}
        +	else if (!noout && (peer != NULL)) /* just print the certificate */
        +		{
        +		if 	(outformat == FORMAT_ASN1)
        +			i=(int)i2d_X509_bio(out,peer);
        +		else if (outformat == FORMAT_PEM)
        +			i=PEM_write_bio_X509(out,peer);
        +		else	{
        +			BIO_printf(bio_err,"bad output format specified for outfile\n");
        +			goto end;
        +			}
        +		if (!i) {
        +			BIO_printf(bio_err,"unable to write X509\n");
        +			goto end;
        +			}
        +		}
        +	ret=0;
        +end:
        +	if (out != NULL) BIO_free_all(out);
        +	if (x != NULL) SSL_SESSION_free(x);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static SSL_SESSION *load_sess_id(char *infile, int format)
        +	{
        +	SSL_SESSION *x=NULL;
        +	BIO *in=NULL;
        +
        +	in=BIO_new(BIO_s_file());
        +	if (in == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (infile == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,infile) <= 0)
        +			{
        +			perror(infile);
        +			goto end;
        +			}
        +		}
        +	if 	(format == FORMAT_ASN1)
        +		x=d2i_SSL_SESSION_bio(in,NULL);
        +	else if (format == FORMAT_PEM)
        +		x=PEM_read_bio_SSL_SESSION(in,NULL,NULL,NULL);
        +	else	{
        +		BIO_printf(bio_err,"bad input format specified for input crl\n");
        +		goto end;
        +		}
        +	if (x == NULL)
        +		{
        +		BIO_printf(bio_err,"unable to load SSL_SESSION\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	
        +end:
        +	if (in != NULL) BIO_free(in);
        +	return(x);
        +	}
        +
        diff --git a/vendor/openssl/openssl/apps/set/set-g-ca.pem b/vendor/openssl/openssl/apps/set/set-g-ca.pem
        new file mode 100644
        index 000000000..78499f057
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/set/set-g-ca.pem
        @@ -0,0 +1,21 @@
        +-----BEGIN CERTIFICATE-----
        +MIIDeDCCAuGgAwIBAgIgYCYUeg8NJ9kO1q3z6vGCkAmPRfu5+Nur0FyGF79MADMw
        +DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
        +MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
        +MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtQ
        +Q0ExMDIxMTgyODEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
        +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJyi5V7l1HohY6hN/2N9x6mvWeMy8rD1
        +6lfXjgmiuGmhpaszWYaalesMcS2OGuG8Lq3PkaSzpVzqASKfIOjxLMsdpYyYJRub
        +vRPDWi3xd8wlp9xUwWHKqn+ki8mPo0yN4eONwZZ4rcZr6K+tWd+5EJZSjuENJoQ/
        +SRRmGRzdcS7XAgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
        +EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
        +aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
        +MTAyMjAxMjIwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
        +SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwICBDB5
        +BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
        +Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
        +ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBn19R2
        +AgGvpJDmfXrHTDdCoYyMkaP2MPzw0hFRwh+wqnw0/pqUXa7MrLXMqtD3rUyOWaNR
        +9fYpJZd0Bh/1OeIc2+U+VNfUovLLuZ8nNemdxyq2KMYnHtnh7UdO7atZ+PFLVu8x
        +a+J2Mtj8MGy12CJNTJcjLSrJ/1f3AuVrwELjlQ==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/set/set-m-ca.pem b/vendor/openssl/openssl/apps/set/set-m-ca.pem
        new file mode 100644
        index 000000000..0e74caff6
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/set/set-m-ca.pem
        @@ -0,0 +1,21 @@
        +-----BEGIN CERTIFICATE-----
        +MIIDeDCCAuGgAwIBAgIgEGvcf5aUnufALdVMa/dmPdflq1CoORGeK5DUwbqhVYcw
        +DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
        +MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
        +MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtN
        +Q0ExMDIxMTgyNzEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
        +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALuWwr63YrT1GIZpYKfIeiVFHESG/FZO
        +7RAJKml/p12ZyZ7D5YPP4BBXVsa1H8e8arR1LKC4rdCArrtKKlBeBiMo9+NB+u35
        +FnLnTmfzM4iZ2Syw35DXY8+Xn/LM7RJ1RG+vMNcTqpoUg7QPye7flq2Pt7vVROPn
        +SZxPyVxmILe3AgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
        +EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
        +aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
        +MTAyMjAxMjEwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
        +SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwIDCDB5
        +BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
        +Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
        +ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQApaj0W
        +GgyR47URZEZ7z83yivvnVErqtodub/nR1fMgJ4bDC0ofjA0SzXBP1/3eDq9VkPuS
        +EKUw9BpM2XrSUKhJ6F1CbBjWpM0M7GC1nTSxMxmV+XL+Ab/Gn2SwozUApWtht29/
        +x9VLB8qsi6wN2aOsVdQMl5iVCjGQYfEkyuoIgA==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/set/set_b_ca.pem b/vendor/openssl/openssl/apps/set/set_b_ca.pem
        new file mode 100644
        index 000000000..eba7d5cf5
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/set/set_b_ca.pem
        @@ -0,0 +1,23 @@
        +-----BEGIN CERTIFICATE-----
        +MIID1zCCAr+gAwIBAgIgYClSzXgB3u31VMarY+lXwPKU9DtoBMzaaivuVzV9a9kw
        +DQYJKoZIhvcNAQEFBQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1JDQTEwMTEx
        +ODI5MB4XDTk2MTAxNzAwMDAwMFoXDTk2MTExNjIzNTk1OVowRTELMAkGA1UEBhMC
        +VVMxFDASBgNVBAoTC0JDQTEwMTcxMTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlBy
        +b2R1Y3QgVHlwZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApPewvR0BwV02
        +9E12ic48pMY/aMB6SkMEWPDx2hURr0DKYGJ6qMvzZn2pSfaVH1BqDtK6oK4Ye5Mj
        +ItywwQIdXXO9Ut8+TLnvtzq9ByCJ0YThjZJBc7ZcpJxSV7QAoBON/lzxZuAVq3+L
        +3uc39MgRwmBpRllZEpWrkojxs6166X0CAwEAAaOCAVcwggFTMFQGA1UdIwRNMEuh
        +J6QlMCMxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtSQ0ExMDExMTgyOYIgVqenwCYv
        +mmxUIvi9gUMCa+uJGJ60mZecw9HrISXnLaYwDgYDVR0PAQH/BAQDAgEGMC4GA1Ud
        +EAEB/wQkMCKADzE5OTYxMDE3MTc1NzAwWoEPMTk5NjExMTYyMzU5NTlaMBsGA1Ud
        +IAEB/wQRMA8wDQYLYIZIAYb4RQEHAQEwEgYDVR0TAQH/BAgwBgEB/wIBATAPBgSG
        +jW8DAQH/BAQDAgABMHkGBIaNbwcBAf8EbjBsMCQCAQAwCQYFKw4DAhoFAAQUMmY3
        +NGIxYWY0ZmNjMDYwZjc2NzYTD3RlcnNlIHN0YXRlbWVudIAXaHR0cDovL3d3dy52
        +ZXJpc2lnbi5jb22BGmdldHNldC1jZW50ZXJAdmVyaXNpZ24uY29tMA0GCSqGSIb3
        +DQEBBQUAA4IBAQAWoMS8Aj2sO0LDxRoMcnWTKY8nd8Jw2vl2Mgsm+0qCvcndICM5
        +43N0y9uHlP8WeCZULbFz95gTL8mfP/QTu4EctMUkQgRHJnx80f0XSF3HE/X6zBbI
        +9rit/bF6yP1mhkdss/vGanReDpki7q8pLx+VIIcxWst/366HP3dW1Fb7ECW/WmVV
        +VMN93f/xqk9I4sXchVZcVKQT3W4tzv+qQvugrEi1dSEkbAy1CITEAEGiaFhGUyCe
        +WPox3guRXaEHoINNeajGrISe6d//alsz5EEroBoLnM2ryqWfLAtRsf4rjNzTgklw
        +lbiz0fw7bNkXKp5ZVr0wlnOjQnoSM6dTI0AV
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/set/set_c_ca.pem b/vendor/openssl/openssl/apps/set/set_c_ca.pem
        new file mode 100644
        index 000000000..48b2cbdc7
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/set/set_c_ca.pem
        @@ -0,0 +1,21 @@
        +-----BEGIN CERTIFICATE-----
        +MIIDeDCCAuGgAwIBAgIgOnl8J6lAYNDdTWtIojWCGnloNf4ufHjOZ4Fkxwg5xOsw
        +DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0JDQTEwMTcx
        +MTA0MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjIw
        +MDAwMDBaFw05NjExMjEyMzU5NTlaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKEwtD
        +Q0ExMDIxMTYxNjEgMB4GA1UEAxMXQnJhbmQgTmFtZTpQcm9kdWN0IFR5cGUwgZ8w
        +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANA3a9+U8oXU3Dv1wJf8g0A7HjCRZAXc
        +Y8E4OLOdye5aUssxifCE05qTPVqHMXo6cnCYcfroMdURhjQlswyTGtjQybgUnXjp
        +pchw+V4D1DkN0ThErrMCh9ZFSykC0lUhQTRLESvbIb4Gal/HMAFAF5sj0GoOFi2H
        +RRj7gpzBIU3xAgMBAAGjggFXMIIBUzBUBgNVHSMETTBLoSekJTAjMQswCQYDVQQG
        +EwJVUzEUMBIGA1UEChMLUkNBMTAxMTE4MjmCIGApUs14Ad7t9VTGq2PpV8DylPQ7
        +aATM2mor7lc1fWvZMA4GA1UdDwEB/wQEAwIBBjAuBgNVHRABAf8EJDAigA8xOTk2
        +MTAyMjAxMTAwMFqBDzE5OTYxMTIxMjM1OTU5WjAbBgNVHSABAf8EETAPMA0GC2CG
        +SAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYBAf8CAQAwDwYEho1vAwEB/wQEAwIEEDB5
        +BgSGjW8HAQH/BG4wbDAkAgEAMAkGBSsOAwIaBQAEFDJmNzRiMWFmNGZjYzA2MGY3
        +Njc2Ew90ZXJzZSBzdGF0ZW1lbnSAF2h0dHA6Ly93d3cudmVyaXNpZ24uY29tgRpn
        +ZXRzZXQtY2VudGVyQHZlcmlzaWduLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBteLaZ
        +u/TASC64UWPfhxYAUdys9DQ1pG/J1qPWNTkjOmpXFvW+7l/3nkxyRPgUoFNwx1e7
        +XVVPr6zhy8LaaXppwfIZvVryzAUdbtijiUf/MO0hvV3w7e9NlCVProdU5H9EvCXr
        ++IV8rH8fdEkirIVyw0JGHkuWhkmtS1HEwai9vg==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/set/set_d_ct.pem b/vendor/openssl/openssl/apps/set/set_d_ct.pem
        new file mode 100644
        index 000000000..9f8c7d8b0
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/set/set_d_ct.pem
        @@ -0,0 +1,21 @@
        +-----BEGIN CERTIFICATE-----
        +MIIDdjCCAt+gAwIBAgIgRU5t24v72xVDpZ4iHpyoOAQaQmfio1yhTZAOkBfT2uUw
        +DQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0NDQTEwMjEx
        +NjE2MSAwHgYDVQQDExdCcmFuZCBOYW1lOlByb2R1Y3QgVHlwZTAeFw05NjEwMjQw
        +MDAwMDBaFw05NjExMjMyMzU5NTlaMG4xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdC
        +cmFuZElEMSYwJAYDVQQLEx1Jc3N1aW5nIEZpbmFuY2lhbCBJbnN0aXR1dGlvbjEl
        +MCMGA1UEAxMcR2lYb0t0VjViN1V0MHZKa2hkSG5RYmNzc2JrPTBcMA0GCSqGSIb3
        +DQEBAQUAA0sAMEgCQQDIUxgpNB1aoSW585WErtN8WInCRWCqDj3RGT2mJye0F4SM
        +/iT5ywdWMasmw18vpEpDlMypfZnRkUAdfyHcRABVAgMBAAGjggFwMIIBbDB2BgNV
        +HSMEbzBtoUmkRzBFMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLQkNBMTAxNzExMDQx
        +IDAeBgNVBAMTF0JyYW5kIE5hbWU6UHJvZHVjdCBUeXBlgiA6eXwnqUBg0N1Na0ii
        +NYIaeWg1/i58eM5ngWTHCDnE6zAOBgNVHQ8BAf8EBAMCB4AwLgYDVR0QAQH/BCQw
        +IoAPMTk5NjEwMjQwMTA0MDBagQ8xOTk2MTEyMzIzNTk1OVowGAYDVR0gBBEwDzAN
        +BgtghkgBhvhFAQcBATAMBgNVHRMBAf8EAjAAMA8GBIaNbwMBAf8EBAMCB4AweQYE
        +ho1vBwEB/wRuMGwwJAIBADAJBgUrDgMCGgUABBQzOTgyMzk4NzIzNzg5MTM0OTc4
        +MhMPdGVyc2Ugc3RhdGVtZW50gBdodHRwOi8vd3d3LnZlcmlzaWduLmNvbYEaZ2V0
        +c2V0LWNlbnRlckB2ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAVHCjhxeD
        +mIFSkm3DpQAq7pGfcAFPWvSM9I9bK8qeFT1M5YQ+5fbPqaWlNcQlGKIe3cHd4+0P
        +ndL5lb6UBhhA0kTzEYA38+HtBxPe/lokCv0bYfyWY9asUmvfbUrTYta0yjN7ixnV
        +UqvxxHQHOAwhf6bcc7xNHapOxloWzGUU0RQ=
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/set/set_root.pem b/vendor/openssl/openssl/apps/set/set_root.pem
        new file mode 100644
        index 000000000..8dd104f05
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/set/set_root.pem
        @@ -0,0 +1,21 @@
        +-----BEGIN CERTIFICATE-----
        +MIIDZzCCAk+gAwIBAgIgVqenwCYvmmxUIvi9gUMCa+uJGJ60mZecw9HrISXnLaYw
        +DQYJKoZIhvcNAQEFBQAwIzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1JDQTEwMTEx
        +ODI5MB4XDTk2MTAxMjAwMDAwMFoXDTk2MTExMTIzNTk1OVowIzELMAkGA1UEBhMC
        +VVMxFDASBgNVBAoTC1JDQTEwMTExODI5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
        +MIIBCgKCAQEAukca0PVUGFIYX7EyrShi+dVi9GTNzG0V2Wtdw6DqFzKfedba/KpE
        +zqnRDV/wRZlBn3oXPS6kNCFiBPRV9mEFXI7y2W+q8/vPurjRDIXMsqQ+dAhKwf4q
        +rofJBTiET4NUN0YTtpx6aYuoVubjiOgKdbqnUArxAWWP2Dkco17ipEYyUtd4sTAe
        +/xKR02AHpbYGYPSHjMDS/nzUJ7uX4d51phs0rt7If48ExJSnDV/KoHMfm42mdmH2
        +g23005qdHKY3UXeh10tZmb3QtGTSvF6OqpRZ+e9/ALklu7ZcIjqbb944ci4QWemb
        +ZNWiDFrWWUoO1k942BI/iZ8Fh8pETYSDBQIDAQABo4GGMIGDMA4GA1UdDwEB/wQE
        +AwIBBjAuBgNVHRABAf8EJDAigA8xOTk2MTAxMjAxMzQwMFqBDzE5OTYxMTExMjM1
        +OTU5WjAbBgNVHSABAf8EETAPMA0GC2CGSAGG+EUBBwEBMBIGA1UdEwEB/wQIMAYB
        +Af8CAQIwEAYEho1vAwEB/wQFAwMHAIAwDQYJKoZIhvcNAQEFBQADggEBAK4tntea
        +y+ws7PdULwfqAS5osaoNvw73uBn5lROTpx91uhQbJyf0oZ3XG9GUuHZBpqG9qmr9
        +vIL40RsvRpNMYgaNHKTxF716yx6rZmruAYZsrE3SpV63tQJCckKLPSge2E5uDhSQ
        +O8UjusG+IRT9fKMXUHLv4OmZPOQVOSl1qTCN2XoJFqEPtC3Y9P4YR4xHL0P2jb1l
        +DLdIbruuh+6omH+0XUZd5fKnQZTTi6gjl0iunj3wGnkcqGZtwr3j87ONiB/8tDwY
        +vz8ceII4YYdX12PrNzn+fu3R5rChvPW4/ah/SaYQ2VQ0AupaIF4xrNJ/gLYYw0YO
        +bxCrVJLd8tu9WgA=
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/apps/smime.c b/vendor/openssl/openssl/apps/smime.c
        new file mode 100644
        index 000000000..c583f8a0e
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/smime.c
        @@ -0,0 +1,857 @@
        +/* smime.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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).
        + *
        + */
        +
        +/* S/MIME utility function */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/crypto.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/x509_vfy.h>
        +#include <openssl/x509v3.h>
        +
        +#undef PROG
        +#define PROG smime_main
        +static int save_certs(char *signerfile, STACK_OF(X509) *signers);
        +static int smime_cb(int ok, X509_STORE_CTX *ctx);
        +
        +#define SMIME_OP	0x10
        +#define SMIME_IP	0x20
        +#define SMIME_SIGNERS	0x40
        +#define SMIME_ENCRYPT	(1 | SMIME_OP)
        +#define SMIME_DECRYPT	(2 | SMIME_IP)
        +#define SMIME_SIGN	(3 | SMIME_OP | SMIME_SIGNERS)
        +#define SMIME_VERIFY	(4 | SMIME_IP)
        +#define SMIME_PK7OUT	(5 | SMIME_IP | SMIME_OP)
        +#define SMIME_RESIGN	(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int operation = 0;
        +	int ret = 0;
        +	char **args;
        +	const char *inmode = "r", *outmode = "w";
        +	char *infile = NULL, *outfile = NULL;
        +	char *signerfile = NULL, *recipfile = NULL;
        +	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
        +	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
        +	const EVP_CIPHER *cipher = NULL;
        +	PKCS7 *p7 = NULL;
        +	X509_STORE *store = NULL;
        +	X509 *cert = NULL, *recip = NULL, *signer = NULL;
        +	EVP_PKEY *key = NULL;
        +	STACK_OF(X509) *encerts = NULL, *other = NULL;
        +	BIO *in = NULL, *out = NULL, *indata = NULL;
        +	int badarg = 0;
        +	int flags = PKCS7_DETACHED;
        +	char *to = NULL, *from = NULL, *subject = NULL;
        +	char *CAfile = NULL, *CApath = NULL;
        +	char *passargin = NULL, *passin = NULL;
        +	char *inrand = NULL;
        +	int need_rand = 0;
        +	int indef = 0;
        +	const EVP_MD *sign_md = NULL;
        +	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
        +        int keyform = FORMAT_PEM;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	X509_VERIFY_PARAM *vpm = NULL;
        +
        +	args = argv + 1;
        +	ret = 1;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		{
        +		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
        +		}
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	while (!badarg && *args && *args[0] == '-')
        +		{
        +		if (!strcmp (*args, "-encrypt"))
        +			operation = SMIME_ENCRYPT;
        +		else if (!strcmp (*args, "-decrypt"))
        +			operation = SMIME_DECRYPT;
        +		else if (!strcmp (*args, "-sign"))
        +			operation = SMIME_SIGN;
        +		else if (!strcmp (*args, "-resign"))
        +			operation = SMIME_RESIGN;
        +		else if (!strcmp (*args, "-verify"))
        +			operation = SMIME_VERIFY;
        +		else if (!strcmp (*args, "-pk7out"))
        +			operation = SMIME_PK7OUT;
        +#ifndef OPENSSL_NO_DES
        +		else if (!strcmp (*args, "-des3")) 
        +				cipher = EVP_des_ede3_cbc();
        +		else if (!strcmp (*args, "-des")) 
        +				cipher = EVP_des_cbc();
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		else if (!strcmp (*args, "-seed")) 
        +				cipher = EVP_seed_cbc();
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +		else if (!strcmp (*args, "-rc2-40")) 
        +				cipher = EVP_rc2_40_cbc();
        +		else if (!strcmp (*args, "-rc2-128")) 
        +				cipher = EVP_rc2_cbc();
        +		else if (!strcmp (*args, "-rc2-64")) 
        +				cipher = EVP_rc2_64_cbc();
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		else if (!strcmp(*args,"-aes128"))
        +				cipher = EVP_aes_128_cbc();
        +		else if (!strcmp(*args,"-aes192"))
        +				cipher = EVP_aes_192_cbc();
        +		else if (!strcmp(*args,"-aes256"))
        +				cipher = EVP_aes_256_cbc();
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		else if (!strcmp(*args,"-camellia128"))
        +				cipher = EVP_camellia_128_cbc();
        +		else if (!strcmp(*args,"-camellia192"))
        +				cipher = EVP_camellia_192_cbc();
        +		else if (!strcmp(*args,"-camellia256"))
        +				cipher = EVP_camellia_256_cbc();
        +#endif
        +		else if (!strcmp (*args, "-text")) 
        +				flags |= PKCS7_TEXT;
        +		else if (!strcmp (*args, "-nointern")) 
        +				flags |= PKCS7_NOINTERN;
        +		else if (!strcmp (*args, "-noverify")) 
        +				flags |= PKCS7_NOVERIFY;
        +		else if (!strcmp (*args, "-nochain")) 
        +				flags |= PKCS7_NOCHAIN;
        +		else if (!strcmp (*args, "-nocerts")) 
        +				flags |= PKCS7_NOCERTS;
        +		else if (!strcmp (*args, "-noattr")) 
        +				flags |= PKCS7_NOATTR;
        +		else if (!strcmp (*args, "-nodetach")) 
        +				flags &= ~PKCS7_DETACHED;
        +		else if (!strcmp (*args, "-nosmimecap"))
        +				flags |= PKCS7_NOSMIMECAP;
        +		else if (!strcmp (*args, "-binary"))
        +				flags |= PKCS7_BINARY;
        +		else if (!strcmp (*args, "-nosigs"))
        +				flags |= PKCS7_NOSIGS;
        +		else if (!strcmp (*args, "-stream"))
        +				indef = 1;
        +		else if (!strcmp (*args, "-indef"))
        +				indef = 1;
        +		else if (!strcmp (*args, "-noindef"))
        +				indef = 0;
        +		else if (!strcmp (*args, "-nooldmime"))
        +				flags |= PKCS7_NOOLDMIMETYPE;
        +		else if (!strcmp (*args, "-crlfeol"))
        +				flags |= PKCS7_CRLFEOL;
        +		else if (!strcmp(*args,"-rand"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			args++;
        +			inrand = *args;
        +			need_rand = 1;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (!strcmp(*args,"-engine"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			engine = *++args;
        +			}
        +#endif
        +		else if (!strcmp(*args,"-passin"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			passargin = *++args;
        +			}
        +		else if (!strcmp (*args, "-to"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			to = *++args;
        +			}
        +		else if (!strcmp (*args, "-from"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			from = *++args;
        +			}
        +		else if (!strcmp (*args, "-subject"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			subject = *++args;
        +			}
        +		else if (!strcmp (*args, "-signer"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			/* If previous -signer argument add signer to list */
        +
        +			if (signerfile)
        +				{
        +				if (!sksigners)
        +					sksigners = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(sksigners, signerfile);
        +				if (!keyfile)
        +					keyfile = signerfile;
        +				if (!skkeys)
        +					skkeys = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(skkeys, keyfile);
        +				keyfile = NULL;
        +				}
        +			signerfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-recip"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			recipfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-md"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			sign_md = EVP_get_digestbyname(*++args);
        +			if (sign_md == NULL)
        +				{
        +				BIO_printf(bio_err, "Unknown digest %s\n",
        +							*args);
        +				goto argerr;
        +				}
        +			}
        +		else if (!strcmp (*args, "-inkey"))
        +			{
        +			if (!args[1])	
        +				goto argerr;
        +			/* If previous -inkey arument add signer to list */
        +			if (keyfile)
        +				{
        +				if (!signerfile)
        +					{
        +					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
        +					goto argerr;
        +					}
        +				if (!sksigners)
        +					sksigners = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(sksigners, signerfile);
        +				signerfile = NULL;
        +				if (!skkeys)
        +					skkeys = sk_OPENSSL_STRING_new_null();
        +				sk_OPENSSL_STRING_push(skkeys, keyfile);
        +				}
        +			keyfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-keyform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			keyform = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-certfile"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			certfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-CAfile"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			CAfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-CApath"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			CApath = *++args;
        +			}
        +		else if (!strcmp (*args, "-in"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			infile = *++args;
        +			}
        +		else if (!strcmp (*args, "-inform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			informat = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-outform"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			outformat = str2fmt(*++args);
        +			}
        +		else if (!strcmp (*args, "-out"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			outfile = *++args;
        +			}
        +		else if (!strcmp (*args, "-content"))
        +			{
        +			if (!args[1])
        +				goto argerr;
        +			contfile = *++args;
        +			}
        +		else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
        +			continue;
        +		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
        +			badarg = 1;
        +		args++;
        +		}
        +
        +	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
        +		{
        +		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
        +		goto argerr;
        +		}
        +
        +	if (operation & SMIME_SIGNERS)
        +		{
        +		/* Check to see if any final signer needs to be appended */
        +		if (keyfile && !signerfile)
        +			{
        +			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
        +			goto argerr;
        +			}
        +		if (signerfile)
        +			{
        +			if (!sksigners)
        +				sksigners = sk_OPENSSL_STRING_new_null();
        +			sk_OPENSSL_STRING_push(sksigners, signerfile);
        +			if (!skkeys)
        +				skkeys = sk_OPENSSL_STRING_new_null();
        +			if (!keyfile)
        +				keyfile = signerfile;
        +			sk_OPENSSL_STRING_push(skkeys, keyfile);
        +			}
        +		if (!sksigners)
        +			{
        +			BIO_printf(bio_err, "No signer certificate specified\n");
        +			badarg = 1;
        +			}
        +		signerfile = NULL;
        +		keyfile = NULL;
        +		need_rand = 1;
        +		}
        +	else if (operation == SMIME_DECRYPT)
        +		{
        +		if (!recipfile && !keyfile)
        +			{
        +			BIO_printf(bio_err, "No recipient certificate or key specified\n");
        +			badarg = 1;
        +			}
        +		}
        +	else if (operation == SMIME_ENCRYPT)
        +		{
        +		if (!*args)
        +			{
        +			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
        +			badarg = 1;
        +			}
        +		need_rand = 1;
        +		}
        +	else if (!operation)
        +		badarg = 1;
        +
        +	if (badarg)
        +		{
        +		argerr:
        +		BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n");
        +		BIO_printf (bio_err, "where options are\n");
        +		BIO_printf (bio_err, "-encrypt       encrypt message\n");
        +		BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
        +		BIO_printf (bio_err, "-sign          sign message\n");
        +		BIO_printf (bio_err, "-verify        verify signed message\n");
        +		BIO_printf (bio_err, "-pk7out        output PKCS#7 structure\n");
        +#ifndef OPENSSL_NO_DES
        +		BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
        +		BIO_printf (bio_err, "-des           encrypt with DES\n");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		BIO_printf (bio_err, "-seed          encrypt with SEED\n");
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +		BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
        +		BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
        +		BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
        +		BIO_printf (bio_err, "               encrypt PEM output with cbc aes\n");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +		BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
        +		BIO_printf (bio_err, "               encrypt PEM output with cbc camellia\n");
        +#endif
        +		BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
        +		BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
        +		BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
        +		BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
        +		BIO_printf (bio_err, "-nodetach      use opaque signing\n");
        +		BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
        +		BIO_printf (bio_err, "-binary        don't translate message to text\n");
        +		BIO_printf (bio_err, "-certfile file other certificates file\n");
        +		BIO_printf (bio_err, "-signer file   signer certificate file\n");
        +		BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
        +		BIO_printf (bio_err, "-in file       input file\n");
        +		BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
        +		BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
        +		BIO_printf (bio_err, "-keyform arg   input private key format (PEM or ENGINE)\n");
        +		BIO_printf (bio_err, "-out file      output file\n");
        +		BIO_printf (bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
        +		BIO_printf (bio_err, "-content file  supply or override content for detached signature\n");
        +		BIO_printf (bio_err, "-to addr       to address\n");
        +		BIO_printf (bio_err, "-from ad       from address\n");
        +		BIO_printf (bio_err, "-subject s     subject\n");
        +		BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
        +		BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
        +		BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
        +		BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
        +		BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf (bio_err, "-engine e      use engine e, possibly a hardware device.\n");
        +#endif
        +		BIO_printf (bio_err, "-passin arg    input file pass phrase source\n");
        +		BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,  "               the random number generator\n");
        +		BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
        +		goto end;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +	if (need_rand)
        +		{
        +		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        +		if (inrand != NULL)
        +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +				app_RAND_load_files(inrand));
        +		}
        +
        +	ret = 2;
        +
        +	if (!(operation & SMIME_SIGNERS))
        +		flags &= ~PKCS7_DETACHED;
        +
        +	if (operation & SMIME_OP)
        +		{
        +		if (outformat == FORMAT_ASN1)
        +			outmode = "wb";
        +		}
        +	else
        +		{
        +		if (flags & PKCS7_BINARY)
        +			outmode = "wb";
        +		}
        +
        +	if (operation & SMIME_IP)
        +		{
        +		if (informat == FORMAT_ASN1)
        +			inmode = "rb";
        +		}
        +	else
        +		{
        +		if (flags & PKCS7_BINARY)
        +			inmode = "rb";
        +		}
        +
        +	if (operation == SMIME_ENCRYPT)
        +		{
        +		if (!cipher)
        +			{
        +#ifndef OPENSSL_NO_RC2			
        +			cipher = EVP_rc2_40_cbc();
        +#else
        +			BIO_printf(bio_err, "No cipher selected\n");
        +			goto end;
        +#endif
        +			}
        +		encerts = sk_X509_new_null();
        +		while (*args)
        +			{
        +			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
        +				NULL, e, "recipient certificate file")))
        +				{
        +#if 0				/* An appropriate message is already printed */
        +				BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args);
        +#endif
        +				goto end;
        +				}
        +			sk_X509_push(encerts, cert);
        +			cert = NULL;
        +			args++;
        +			}
        +		}
        +
        +	if (certfile)
        +		{
        +		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
        +			e, "certificate file")))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (recipfile && (operation == SMIME_DECRYPT))
        +		{
        +		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
        +			e, "recipient certificate file")))
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +	if (operation == SMIME_DECRYPT)
        +		{
        +		if (!keyfile)
        +			keyfile = recipfile;
        +		}
        +	else if (operation == SMIME_SIGN)
        +		{
        +		if (!keyfile)
        +			keyfile = signerfile;
        +		}
        +	else keyfile = NULL;
        +
        +	if (keyfile)
        +		{
        +		key = load_key(bio_err, keyfile, keyform, 0, passin, e,
        +			       "signing key file");
        +		if (!key)
        +			goto end;
        +		}
        +
        +	if (infile)
        +		{
        +		if (!(in = BIO_new_file(infile, inmode)))
        +			{
        +			BIO_printf (bio_err,
        +				 "Can't open input file %s\n", infile);
        +			goto end;
        +			}
        +		}
        +	else
        +		in = BIO_new_fp(stdin, BIO_NOCLOSE);
        +
        +	if (operation & SMIME_IP)
        +		{
        +		if (informat == FORMAT_SMIME) 
        +			p7 = SMIME_read_PKCS7(in, &indata);
        +		else if (informat == FORMAT_PEM) 
        +			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
        +		else if (informat == FORMAT_ASN1) 
        +			p7 = d2i_PKCS7_bio(in, NULL);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
        +			goto end;
        +			}
        +
        +		if (!p7)
        +			{
        +			BIO_printf(bio_err, "Error reading S/MIME message\n");
        +			goto end;
        +			}
        +		if (contfile)
        +			{
        +			BIO_free(indata);
        +			if (!(indata = BIO_new_file(contfile, "rb")))
        +				{
        +				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
        +				goto end;
        +				}
        +			}
        +		}
        +
        +	if (outfile)
        +		{
        +		if (!(out = BIO_new_file(outfile, outmode)))
        +			{
        +			BIO_printf (bio_err,
        +				 "Can't open output file %s\n", outfile);
        +			goto end;
        +			}
        +		}
        +	else
        +		{
        +		out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		    out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +		}
        +
        +	if (operation == SMIME_VERIFY)
        +		{
        +		if (!(store = setup_verify(bio_err, CAfile, CApath)))
        +			goto end;
        +		X509_STORE_set_verify_cb(store, smime_cb);
        +		if (vpm)
        +			X509_STORE_set1_param(store, vpm);
        +		}
        +
        +
        +	ret = 3;
        +
        +	if (operation == SMIME_ENCRYPT)
        +		{
        +		if (indef)
        +			flags |= PKCS7_STREAM;
        +		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
        +		}
        +	else if (operation & SMIME_SIGNERS)
        +		{
        +		int i;
        +		/* If detached data content we only enable streaming if
        +		 * S/MIME output format.
        +		 */
        +		if (operation == SMIME_SIGN)
        +			{
        +			if (flags & PKCS7_DETACHED)
        +				{
        +				if (outformat == FORMAT_SMIME)
        +					flags |= PKCS7_STREAM;
        +				}
        +			else if (indef)
        +				flags |= PKCS7_STREAM;
        +			flags |= PKCS7_PARTIAL;
        +			p7 = PKCS7_sign(NULL, NULL, other, in, flags);
        +			if (!p7)
        +				goto end;
        +			}
        +		else
        +			flags |= PKCS7_REUSE_DIGEST;
        +		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
        +			{
        +			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
        +			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
        +			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
        +					e, "signer certificate");
        +			if (!signer)
        +				goto end;
        +			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
        +			       "signing key file");
        +			if (!key)
        +				goto end;
        +			if (!PKCS7_sign_add_signer(p7, signer, key,
        +						sign_md, flags))
        +				goto end;
        +			X509_free(signer);
        +			signer = NULL;
        +			EVP_PKEY_free(key);
        +			key = NULL;
        +			}
        +		/* If not streaming or resigning finalize structure */
        +		if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM))
        +			{
        +			if (!PKCS7_final(p7, in, flags))
        +				goto end;
        +			}
        +		}
        +
        +	if (!p7)
        +		{
        +		BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
        +		goto end;
        +		}
        +
        +	ret = 4;
        +	if (operation == SMIME_DECRYPT)
        +		{
        +		if (!PKCS7_decrypt(p7, key, recip, out, flags))
        +			{
        +			BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
        +			goto end;
        +			}
        +		}
        +	else if (operation == SMIME_VERIFY)
        +		{
        +		STACK_OF(X509) *signers;
        +		if (PKCS7_verify(p7, other, store, indata, out, flags))
        +			BIO_printf(bio_err, "Verification successful\n");
        +		else
        +			{
        +			BIO_printf(bio_err, "Verification failure\n");
        +			goto end;
        +			}
        +		signers = PKCS7_get0_signers(p7, other, flags);
        +		if (!save_certs(signerfile, signers))
        +			{
        +			BIO_printf(bio_err, "Error writing signers to %s\n",
        +								signerfile);
        +			ret = 5;
        +			goto end;
        +			}
        +		sk_X509_free(signers);
        +		}
        +	else if (operation == SMIME_PK7OUT)
        +		PEM_write_bio_PKCS7(out, p7);
        +	else
        +		{
        +		if (to)
        +			BIO_printf(out, "To: %s\n", to);
        +		if (from)
        +			BIO_printf(out, "From: %s\n", from);
        +		if (subject)
        +			BIO_printf(out, "Subject: %s\n", subject);
        +		if (outformat == FORMAT_SMIME) 
        +			{
        +			if (operation == SMIME_RESIGN)
        +				SMIME_write_PKCS7(out, p7, indata, flags);
        +			else
        +				SMIME_write_PKCS7(out, p7, in, flags);
        +			}
        +		else if (outformat == FORMAT_PEM) 
        +			PEM_write_bio_PKCS7_stream(out, p7, in, flags);
        +		else if (outformat == FORMAT_ASN1) 
        +			i2d_PKCS7_bio_stream(out,p7, in, flags);
        +		else
        +			{
        +			BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
        +			goto end;
        +			}
        +		}
        +	ret = 0;
        +end:
        +	if (need_rand)
        +		app_RAND_write_file(NULL, bio_err);
        +	if (ret) ERR_print_errors(bio_err);
        +	sk_X509_pop_free(encerts, X509_free);
        +	sk_X509_pop_free(other, X509_free);
        +	if (vpm)
        +		X509_VERIFY_PARAM_free(vpm);
        +	if (sksigners)
        +		sk_OPENSSL_STRING_free(sksigners);
        +	if (skkeys)
        +		sk_OPENSSL_STRING_free(skkeys);
        +	X509_STORE_free(store);
        +	X509_free(cert);
        +	X509_free(recip);
        +	X509_free(signer);
        +	EVP_PKEY_free(key);
        +	PKCS7_free(p7);
        +	BIO_free(in);
        +	BIO_free(indata);
        +	BIO_free_all(out);
        +	if (passin) OPENSSL_free(passin);
        +	return (ret);
        +}
        +
        +static int save_certs(char *signerfile, STACK_OF(X509) *signers)
        +	{
        +	int i;
        +	BIO *tmp;
        +	if (!signerfile)
        +		return 1;
        +	tmp = BIO_new_file(signerfile, "w");
        +	if (!tmp) return 0;
        +	for(i = 0; i < sk_X509_num(signers); i++)
        +		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
        +	BIO_free(tmp);
        +	return 1;
        +	}
        +	
        +
        +/* Minimal callback just to output policy info (if any) */
        +
        +static int smime_cb(int ok, X509_STORE_CTX *ctx)
        +	{
        +	int error;
        +
        +	error = X509_STORE_CTX_get_error(ctx);
        +
        +	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
        +		&& ((error != X509_V_OK) || (ok != 2)))
        +		return ok;
        +
        +	policies_print(NULL, ctx);
        +
        +	return ok;
        +
        +	}
        diff --git a/vendor/openssl/openssl/apps/speed.c b/vendor/openssl/openssl/apps/speed.c
        new file mode 100644
        index 000000000..9886ca376
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/speed.c
        @@ -0,0 +1,2842 @@
        +/* apps/speed.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The ECDH and ECDSA speed test software is originally written by 
        + * Sumit Gupta of Sun Microsystems Laboratories.
        + *
        + */
        +
        +/* most of this code has been pilfered from my libdes speed.c program */
        +
        +#ifndef OPENSSL_NO_SPEED
        +
        +#undef SECONDS
        +#define SECONDS		3	
        +#define RSA_SECONDS	10
        +#define DSA_SECONDS	10
        +#define ECDSA_SECONDS   10
        +#define ECDH_SECONDS    10
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#undef PROG
        +#define PROG speed_main
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include <string.h>
        +#include <math.h>
        +#include "apps.h"
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +#include <openssl/crypto.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#if !defined(OPENSSL_SYS_MSDOS)
        +#include OPENSSL_UNISTD
        +#endif
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#if defined(_WIN32) || defined(__CYGWIN__)
        +#include <windows.h>
        +# if defined(__CYGWIN__) && !defined(_WIN32)
        +  /* <windows.h> should define _WIN32, which normally is mutually
        +   * exclusive with __CYGWIN__, but if it didn't... */
        +#  define _WIN32
        +  /* this is done because Cygwin alarm() fails sometimes. */
        +# endif
        +#endif
        +
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_DES
        +#include <openssl/des.h>
        +#endif
        +#ifndef OPENSSL_NO_AES
        +#include <openssl/aes.h>
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +#include <openssl/camellia.h>
        +#endif
        +#ifndef OPENSSL_NO_MD2
        +#include <openssl/md2.h>
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +#include <openssl/mdc2.h>
        +#endif
        +#ifndef OPENSSL_NO_MD4
        +#include <openssl/md4.h>
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +#include <openssl/md5.h>
        +#endif
        +#ifndef OPENSSL_NO_HMAC
        +#include <openssl/hmac.h>
        +#endif
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_SHA
        +#include <openssl/sha.h>
        +#endif
        +#ifndef OPENSSL_NO_RIPEMD
        +#include <openssl/ripemd.h>
        +#endif
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +#include <openssl/whrlpool.h>
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +#include <openssl/rc4.h>
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +#include <openssl/rc5.h>
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +#include <openssl/rc2.h>
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +#include <openssl/idea.h>
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +#include <openssl/seed.h>
        +#endif
        +#ifndef OPENSSL_NO_BF
        +#include <openssl/blowfish.h>
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +#include <openssl/cast.h>
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#include "./testrsa.h"
        +#endif
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#include "./testdsa.h"
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +#include <openssl/ecdsa.h>
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +#include <openssl/ecdh.h>
        +#endif
        +#include <openssl/modes.h>
        +
        +#ifdef OPENSSL_FIPS
        +#ifdef OPENSSL_DOING_MAKEDEPEND
        +#undef AES_set_encrypt_key
        +#undef AES_set_decrypt_key
        +#undef DES_set_key_unchecked
        +#endif
        +#define BF_set_key	private_BF_set_key
        +#define CAST_set_key	private_CAST_set_key
        +#define idea_set_encrypt_key	private_idea_set_encrypt_key
        +#define SEED_set_key	private_SEED_set_key
        +#define RC2_set_key	private_RC2_set_key
        +#define RC4_set_key	private_RC4_set_key
        +#define DES_set_key_unchecked	private_DES_set_key_unchecked
        +#define AES_set_encrypt_key	private_AES_set_encrypt_key
        +#define AES_set_decrypt_key	private_AES_set_decrypt_key
        +#define Camellia_set_key	private_Camellia_set_key
        +#endif
        +
        +#ifndef HAVE_FORK
        +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
        +#  define HAVE_FORK 0
        +# else
        +#  define HAVE_FORK 1
        +# endif
        +#endif
        +
        +#if HAVE_FORK
        +#undef NO_FORK
        +#else
        +#define NO_FORK
        +#endif
        +
        +#undef BUFSIZE
        +#define BUFSIZE	((long)1024*8+1)
        +int run=0;
        +
        +static int mr=0;
        +static int usertime=1;
        +
        +static double Time_F(int s);
        +static void print_message(const char *s,long num,int length);
        +static void pkey_print_message(const char *str, const char *str2,
        +	long num, int bits, int sec);
        +static void print_result(int alg,int run_no,int count,double time_used);
        +#ifndef NO_FORK
        +static int do_multi(int multi);
        +#endif
        +
        +#define ALGOR_NUM	30
        +#define SIZE_NUM	5
        +#define RSA_NUM		4
        +#define DSA_NUM		3
        +
        +#define EC_NUM       16
        +#define MAX_ECDH_SIZE 256
        +
        +static const char *names[ALGOR_NUM]={
        +  "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
        +  "des cbc","des ede3","idea cbc","seed cbc",
        +  "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc",
        +  "aes-128 cbc","aes-192 cbc","aes-256 cbc",
        +  "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
        +  "evp","sha256","sha512","whirlpool",
        +  "aes-128 ige","aes-192 ige","aes-256 ige","ghash" };
        +static double results[ALGOR_NUM][SIZE_NUM];
        +static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
        +#ifndef OPENSSL_NO_RSA
        +static double rsa_results[RSA_NUM][2];
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +static double dsa_results[DSA_NUM][2];
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +static double ecdsa_results[EC_NUM][2];
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +static double ecdh_results[EC_NUM][1];
        +#endif
        +
        +#if defined(OPENSSL_NO_DSA) && !(defined(OPENSSL_NO_ECDSA) && defined(OPENSSL_NO_ECDH))
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +static int rnd_fake = 0;
        +#endif
        +
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif 
        +
        +static SIGRETTYPE sig_done(int sig);
        +static SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +#if defined(_WIN32)
        +
        +#if !defined(SIGALRM)
        +# define SIGALRM
        +#endif
        +static unsigned int lapse,schlock;
        +static void alarm_win32(unsigned int secs) { lapse = secs*1000; }
        +#define alarm alarm_win32
        +
        +static DWORD WINAPI sleepy(VOID *arg)
        +	{
        +	schlock = 1;
        +	Sleep(lapse);
        +	run = 0;
        +	return 0;
        +	}
        +
        +static double Time_F(int s)
        +	{
        +	if (s == START)
        +		{
        +		HANDLE	thr;
        +		schlock = 0;
        +		thr = CreateThread(NULL,4096,sleepy,NULL,0,NULL);
        +		if (thr==NULL)
        +			{
        +			DWORD ret=GetLastError();
        +			BIO_printf(bio_err,"unable to CreateThread (%d)",ret);
        +			ExitProcess(ret);
        +			}
        +		CloseHandle(thr);		/* detach the thread	*/
        +		while (!schlock) Sleep(0);	/* scheduler spinlock	*/
        +		}
        +
        +	return app_tminterval(s,usertime);
        +	}
        +#else
        +
        +static double Time_F(int s)
        +	{
        +	return app_tminterval(s,usertime);
        +	}
        +#endif
        +
        +
        +#ifndef OPENSSL_NO_ECDH
        +static const int KDF1_SHA1_len = 20;
        +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
        +	{
        +#ifndef OPENSSL_NO_SHA
        +	if (*outlen < SHA_DIGEST_LENGTH)
        +		return NULL;
        +	else
        +		*outlen = SHA_DIGEST_LENGTH;
        +	return SHA1(in, inlen, out);
        +#else
        +	return NULL;
        +#endif	/* OPENSSL_NO_SHA */
        +	}
        +#endif	/* OPENSSL_NO_ECDH */
        +
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	unsigned char *buf=NULL,*buf2=NULL;
        +	int mret=1;
        +	long count=0,save_count=0;
        +	int i,j,k;
        +#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
        +	long rsa_count;
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	unsigned rsa_num;
        +#endif
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +#ifndef OPENSSL_NO_MD2
        +	unsigned char md2[MD2_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +	unsigned char mdc2[MDC2_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_MD4
        +	unsigned char md4[MD4_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +	unsigned char md5[MD5_DIGEST_LENGTH];
        +	unsigned char hmac[MD5_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	unsigned char sha[SHA_DIGEST_LENGTH];
        +#ifndef OPENSSL_NO_SHA256
        +	unsigned char sha256[SHA256_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +	unsigned char sha512[SHA512_DIGEST_LENGTH];
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +	unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_RIPEMD
        +	unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +	RC4_KEY rc4_ks;
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	RC5_32_KEY rc5_ks;
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	RC2_KEY rc2_ks;
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	IDEA_KEY_SCHEDULE idea_ks;
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	SEED_KEY_SCHEDULE seed_ks;
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	BF_KEY bf_ks;
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	CAST_KEY cast_ks;
        +#endif
        +	static const unsigned char key16[16]=
        +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
        +#ifndef OPENSSL_NO_AES
        +	static const unsigned char key24[24]=
        +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
        +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
        +	static const unsigned char key32[32]=
        +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
        +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
        +		 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	static const unsigned char ckey24[24]=
        +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
        +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
        +	static const unsigned char ckey32[32]=
        +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
        +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
        +		 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
        +#endif
        +#ifndef OPENSSL_NO_AES
        +#define MAX_BLOCK_SIZE 128
        +#else
        +#define MAX_BLOCK_SIZE 64
        +#endif
        +	unsigned char DES_iv[8];
        +	unsigned char iv[2*MAX_BLOCK_SIZE/8];
        +#ifndef OPENSSL_NO_DES
        +	static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
        +	static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
        +	static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
        +	DES_key_schedule sch;
        +	DES_key_schedule sch2;
        +	DES_key_schedule sch3;
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	AES_KEY aes_ks1, aes_ks2, aes_ks3;
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
        +#endif
        +#define	D_MD2		0
        +#define	D_MDC2		1
        +#define	D_MD4		2
        +#define	D_MD5		3
        +#define	D_HMAC		4
        +#define	D_SHA1		5
        +#define D_RMD160	6
        +#define	D_RC4		7
        +#define	D_CBC_DES	8
        +#define	D_EDE3_DES	9
        +#define	D_CBC_IDEA	10
        +#define	D_CBC_SEED	11
        +#define	D_CBC_RC2	12
        +#define	D_CBC_RC5	13
        +#define	D_CBC_BF	14
        +#define	D_CBC_CAST	15
        +#define D_CBC_128_AES	16
        +#define D_CBC_192_AES	17
        +#define D_CBC_256_AES	18
        +#define D_CBC_128_CML   19 
        +#define D_CBC_192_CML   20
        +#define D_CBC_256_CML   21 
        +#define D_EVP		22
        +#define D_SHA256	23	
        +#define D_SHA512	24
        +#define D_WHIRLPOOL	25
        +#define D_IGE_128_AES   26
        +#define D_IGE_192_AES   27
        +#define D_IGE_256_AES   28
        +#define D_GHASH		29
        +	double d=0.0;
        +	long c[ALGOR_NUM][SIZE_NUM];
        +#define	R_DSA_512	0
        +#define	R_DSA_1024	1
        +#define	R_DSA_2048	2
        +#define	R_RSA_512	0
        +#define	R_RSA_1024	1
        +#define	R_RSA_2048	2
        +#define	R_RSA_4096	3
        +
        +#define R_EC_P160    0
        +#define R_EC_P192    1	
        +#define R_EC_P224    2
        +#define R_EC_P256    3
        +#define R_EC_P384    4
        +#define R_EC_P521    5
        +#define R_EC_K163    6
        +#define R_EC_K233    7
        +#define R_EC_K283    8
        +#define R_EC_K409    9
        +#define R_EC_K571    10
        +#define R_EC_B163    11
        +#define R_EC_B233    12
        +#define R_EC_B283    13
        +#define R_EC_B409    14
        +#define R_EC_B571    15
        +
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rsa_key[RSA_NUM];
        +	long rsa_c[RSA_NUM][2];
        +	static unsigned int rsa_bits[RSA_NUM]={512,1024,2048,4096};
        +	static unsigned char *rsa_data[RSA_NUM]=
        +		{test512,test1024,test2048,test4096};
        +	static int rsa_data_length[RSA_NUM]={
        +		sizeof(test512),sizeof(test1024),
        +		sizeof(test2048),sizeof(test4096)};
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	DSA *dsa_key[DSA_NUM];
        +	long dsa_c[DSA_NUM][2];
        +	static unsigned int dsa_bits[DSA_NUM]={512,1024,2048};
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	/* We only test over the following curves as they are representative, 
        +	 * To add tests over more curves, simply add the curve NID
        +	 * and curve name to the following arrays and increase the 
        +	 * EC_NUM value accordingly. 
        +	 */
        +	static unsigned int test_curves[EC_NUM] = 
        +	{	
        +	/* Prime Curves */
        +	NID_secp160r1,
        +	NID_X9_62_prime192v1,
        +	NID_secp224r1,
        +	NID_X9_62_prime256v1,
        +	NID_secp384r1,
        +	NID_secp521r1,
        +	/* Binary Curves */
        +	NID_sect163k1,
        +	NID_sect233k1,
        +	NID_sect283k1,
        +	NID_sect409k1,
        +	NID_sect571k1,
        +	NID_sect163r2,
        +	NID_sect233r1,
        +	NID_sect283r1,
        +	NID_sect409r1,
        +	NID_sect571r1
        +	}; 
        +	static const char * test_curves_names[EC_NUM] = 
        +	{
        +	/* Prime Curves */
        +	"secp160r1",
        +	"nistp192",
        +	"nistp224",
        +	"nistp256",
        +	"nistp384",
        +	"nistp521",
        +	/* Binary Curves */
        +	"nistk163",
        +	"nistk233",
        +	"nistk283",
        +	"nistk409",
        +	"nistk571",
        +	"nistb163",
        +	"nistb233",
        +	"nistb283",
        +	"nistb409",
        +	"nistb571"
        +	};
        +	static int test_curves_bits[EC_NUM] =
        +        {
        +        160, 192, 224, 256, 384, 521,
        +        163, 233, 283, 409, 571,
        +        163, 233, 283, 409, 571
        +        };
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +	unsigned char ecdsasig[256];
        +	unsigned int ecdsasiglen;
        +	EC_KEY *ecdsa[EC_NUM];
        +	long ecdsa_c[EC_NUM][2];
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
        +	unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
        +	int secret_size_a, secret_size_b;
        +	int ecdh_checks = 0;
        +	int secret_idx = 0;
        +	long ecdh_c[EC_NUM][2];
        +#endif
        +
        +	int rsa_doit[RSA_NUM];
        +	int dsa_doit[DSA_NUM];
        +#ifndef OPENSSL_NO_ECDSA
        +	int ecdsa_doit[EC_NUM];
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +        int ecdh_doit[EC_NUM];
        +#endif
        +	int doit[ALGOR_NUM];
        +	int pr_header=0;
        +	const EVP_CIPHER *evp_cipher=NULL;
        +	const EVP_MD *evp_md=NULL;
        +	int decrypt=0;
        +#ifndef NO_FORK
        +	int multi=0;
        +#endif
        +
        +#ifndef TIMES
        +	usertime=-1;
        +#endif
        +
        +	apps_startup();
        +	memset(results, 0, sizeof(results));
        +#ifndef OPENSSL_NO_DSA
        +	memset(dsa_key,0,sizeof(dsa_key));
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	for (i=0; i<EC_NUM; i++) ecdsa[i] = NULL;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	for (i=0; i<EC_NUM; i++)
        +		{
        +		ecdh_a[i] = NULL;
        +		ecdh_b[i] = NULL;
        +		}
        +#endif
        +
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +#ifndef OPENSSL_NO_RSA
        +	memset(rsa_key,0,sizeof(rsa_key));
        +	for (i=0; i<RSA_NUM; i++)
        +		rsa_key[i]=NULL;
        +#endif
        +
        +	if ((buf=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		goto end;
        +		}
        +	if ((buf2=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
        +		{
        +		BIO_printf(bio_err,"out of memory\n");
        +		goto end;
        +		}
        +
        +	memset(c,0,sizeof(c));
        +	memset(DES_iv,0,sizeof(DES_iv));
        +	memset(iv,0,sizeof(iv));
        +
        +	for (i=0; i<ALGOR_NUM; i++)
        +		doit[i]=0;
        +	for (i=0; i<RSA_NUM; i++)
        +		rsa_doit[i]=0;
        +	for (i=0; i<DSA_NUM; i++)
        +		dsa_doit[i]=0;
        +#ifndef OPENSSL_NO_ECDSA
        +	for (i=0; i<EC_NUM; i++)
        +		ecdsa_doit[i]=0;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	for (i=0; i<EC_NUM; i++)
        +		ecdh_doit[i]=0;
        +#endif
        +
        +	
        +	j=0;
        +	argc--;
        +	argv++;
        +	while (argc)
        +		{
        +		if	((argc > 0) && (strcmp(*argv,"-elapsed") == 0))
        +			{
        +			usertime = 0;
        +			j--;	/* Otherwise, -elapsed gets confused with
        +				   an algorithm. */
        +			}
        +		else if	((argc > 0) && (strcmp(*argv,"-evp") == 0))
        +			{
        +			argc--;
        +			argv++;
        +			if(argc == 0)
        +				{
        +				BIO_printf(bio_err,"no EVP given\n");
        +				goto end;
        +				}
        +			evp_cipher=EVP_get_cipherbyname(*argv);
        +			if(!evp_cipher)
        +				{
        +				evp_md=EVP_get_digestbyname(*argv);
        +				}
        +			if(!evp_cipher && !evp_md)
        +				{
        +				BIO_printf(bio_err,"%s is an unknown cipher or digest\n",*argv);
        +				goto end;
        +				}
        +			doit[D_EVP]=1;
        +			}
        +		else if (argc > 0 && !strcmp(*argv,"-decrypt"))
        +			{
        +			decrypt=1;
        +			j--;	/* Otherwise, -elapsed gets confused with
        +				   an algorithm. */
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if	((argc > 0) && (strcmp(*argv,"-engine") == 0))
        +			{
        +			argc--;
        +			argv++;
        +			if(argc == 0)
        +				{
        +				BIO_printf(bio_err,"no engine given\n");
        +				goto end;
        +				}
        +                        setup_engine(bio_err, *argv, 0);
        +			/* j will be increased again further down.  We just
        +			   don't want speed to confuse an engine with an
        +			   algorithm, especially when none is given (which
        +			   means all of them should be run) */
        +			j--;
        +			}
        +#endif
        +#ifndef NO_FORK
        +		else if	((argc > 0) && (strcmp(*argv,"-multi") == 0))
        +			{
        +			argc--;
        +			argv++;
        +			if(argc == 0)
        +				{
        +				BIO_printf(bio_err,"no multi count given\n");
        +				goto end;
        +				}
        +			multi=atoi(argv[0]);
        +			if(multi <= 0)
        +			    {
        +				BIO_printf(bio_err,"bad multi count\n");
        +				goto end;
        +				}				
        +			j--;	/* Otherwise, -mr gets confused with
        +				   an algorithm. */
        +			}
        +#endif
        +		else if (argc > 0 && !strcmp(*argv,"-mr"))
        +			{
        +			mr=1;
        +			j--;	/* Otherwise, -mr gets confused with
        +				   an algorithm. */
        +			}
        +		else
        +#ifndef OPENSSL_NO_MD2
        +		if	(strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +			if (strcmp(*argv,"mdc2") == 0) doit[D_MDC2]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_MD4
        +			if (strcmp(*argv,"md4") == 0) doit[D_MD4]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +			if (strcmp(*argv,"md5") == 0) doit[D_MD5]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +			if (strcmp(*argv,"hmac") == 0) doit[D_HMAC]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +			if (strcmp(*argv,"sha1") == 0) doit[D_SHA1]=1;
        +		else
        +			if (strcmp(*argv,"sha") == 0)	doit[D_SHA1]=1,
        +							doit[D_SHA256]=1,
        +							doit[D_SHA512]=1;
        +		else
        +#ifndef OPENSSL_NO_SHA256
        +			if (strcmp(*argv,"sha256") == 0) doit[D_SHA256]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +			if (strcmp(*argv,"sha512") == 0) doit[D_SHA512]=1;
        +		else
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +			if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_RIPEMD
        +			if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1;
        +		else
        +			if (strcmp(*argv,"rmd160") == 0) doit[D_RMD160]=1;
        +		else
        +			if (strcmp(*argv,"ripemd160") == 0) doit[D_RMD160]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +			if (strcmp(*argv,"rc4") == 0) doit[D_RC4]=1;
        +		else 
        +#endif
        +#ifndef OPENSSL_NO_DES
        +			if (strcmp(*argv,"des-cbc") == 0) doit[D_CBC_DES]=1;
        +		else	if (strcmp(*argv,"des-ede3") == 0) doit[D_EDE3_DES]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_AES
        +			if (strcmp(*argv,"aes-128-cbc") == 0) doit[D_CBC_128_AES]=1;
        +		else	if (strcmp(*argv,"aes-192-cbc") == 0) doit[D_CBC_192_AES]=1;
        +		else	if (strcmp(*argv,"aes-256-cbc") == 0) doit[D_CBC_256_AES]=1;
        +		else    if (strcmp(*argv,"aes-128-ige") == 0) doit[D_IGE_128_AES]=1;
        +		else	if (strcmp(*argv,"aes-192-ige") == 0) doit[D_IGE_192_AES]=1;
        +		else	if (strcmp(*argv,"aes-256-ige") == 0) doit[D_IGE_256_AES]=1;
        +                else
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +			if (strcmp(*argv,"camellia-128-cbc") == 0) doit[D_CBC_128_CML]=1;
        +		else    if (strcmp(*argv,"camellia-192-cbc") == 0) doit[D_CBC_192_CML]=1;
        +		else    if (strcmp(*argv,"camellia-256-cbc") == 0) doit[D_CBC_256_CML]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +#if 0 /* was: #ifdef RSAref */
        +			if (strcmp(*argv,"rsaref") == 0) 
        +			{
        +			RSA_set_default_openssl_method(RSA_PKCS1_RSAref());
        +			j--;
        +			}
        +		else
        +#endif
        +#ifndef RSA_NULL
        +			if (strcmp(*argv,"openssl") == 0) 
        +			{
        +			RSA_set_default_method(RSA_PKCS1_SSLeay());
        +			j--;
        +			}
        +		else
        +#endif
        +#endif /* !OPENSSL_NO_RSA */
        +		     if (strcmp(*argv,"dsa512") == 0) dsa_doit[R_DSA_512]=2;
        +		else if (strcmp(*argv,"dsa1024") == 0) dsa_doit[R_DSA_1024]=2;
        +		else if (strcmp(*argv,"dsa2048") == 0) dsa_doit[R_DSA_2048]=2;
        +		else if (strcmp(*argv,"rsa512") == 0) rsa_doit[R_RSA_512]=2;
        +		else if (strcmp(*argv,"rsa1024") == 0) rsa_doit[R_RSA_1024]=2;
        +		else if (strcmp(*argv,"rsa2048") == 0) rsa_doit[R_RSA_2048]=2;
        +		else if (strcmp(*argv,"rsa4096") == 0) rsa_doit[R_RSA_4096]=2;
        +		else
        +#ifndef OPENSSL_NO_RC2
        +		     if (strcmp(*argv,"rc2-cbc") == 0) doit[D_CBC_RC2]=1;
        +		else if (strcmp(*argv,"rc2") == 0) doit[D_CBC_RC2]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +		     if (strcmp(*argv,"rc5-cbc") == 0) doit[D_CBC_RC5]=1;
        +		else if (strcmp(*argv,"rc5") == 0) doit[D_CBC_RC5]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +		     if (strcmp(*argv,"idea-cbc") == 0) doit[D_CBC_IDEA]=1;
        +		else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +		     if (strcmp(*argv,"seed-cbc") == 0) doit[D_CBC_SEED]=1;
        +		else if (strcmp(*argv,"seed") == 0) doit[D_CBC_SEED]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_BF
        +		     if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1;
        +		else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1;
        +		else if (strcmp(*argv,"bf") == 0) doit[D_CBC_BF]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +		     if (strcmp(*argv,"cast-cbc") == 0) doit[D_CBC_CAST]=1;
        +		else if (strcmp(*argv,"cast") == 0) doit[D_CBC_CAST]=1;
        +		else if (strcmp(*argv,"cast5") == 0) doit[D_CBC_CAST]=1;
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DES
        +			if (strcmp(*argv,"des") == 0)
        +			{
        +			doit[D_CBC_DES]=1;
        +			doit[D_EDE3_DES]=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_AES
        +			if (strcmp(*argv,"aes") == 0)
        +			{
        +			doit[D_CBC_128_AES]=1;
        +			doit[D_CBC_192_AES]=1;
        +			doit[D_CBC_256_AES]=1;
        +			}
        +		else if (strcmp(*argv,"ghash") == 0)
        +			{
        +			doit[D_GHASH]=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +			if (strcmp(*argv,"camellia") == 0)
        +			{
        +			doit[D_CBC_128_CML]=1;
        +			doit[D_CBC_192_CML]=1;
        +			doit[D_CBC_256_CML]=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +			if (strcmp(*argv,"rsa") == 0)
        +			{
        +			rsa_doit[R_RSA_512]=1;
        +			rsa_doit[R_RSA_1024]=1;
        +			rsa_doit[R_RSA_2048]=1;
        +			rsa_doit[R_RSA_4096]=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			if (strcmp(*argv,"dsa") == 0)
        +			{
        +			dsa_doit[R_DSA_512]=1;
        +			dsa_doit[R_DSA_1024]=1;
        +			dsa_doit[R_DSA_2048]=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +		     if (strcmp(*argv,"ecdsap160") == 0) ecdsa_doit[R_EC_P160]=2;
        +		else if (strcmp(*argv,"ecdsap192") == 0) ecdsa_doit[R_EC_P192]=2;
        +		else if (strcmp(*argv,"ecdsap224") == 0) ecdsa_doit[R_EC_P224]=2;
        +		else if (strcmp(*argv,"ecdsap256") == 0) ecdsa_doit[R_EC_P256]=2;
        +		else if (strcmp(*argv,"ecdsap384") == 0) ecdsa_doit[R_EC_P384]=2;
        +		else if (strcmp(*argv,"ecdsap521") == 0) ecdsa_doit[R_EC_P521]=2;
        +		else if (strcmp(*argv,"ecdsak163") == 0) ecdsa_doit[R_EC_K163]=2;
        +		else if (strcmp(*argv,"ecdsak233") == 0) ecdsa_doit[R_EC_K233]=2;
        +		else if (strcmp(*argv,"ecdsak283") == 0) ecdsa_doit[R_EC_K283]=2;
        +		else if (strcmp(*argv,"ecdsak409") == 0) ecdsa_doit[R_EC_K409]=2;
        +		else if (strcmp(*argv,"ecdsak571") == 0) ecdsa_doit[R_EC_K571]=2;
        +		else if (strcmp(*argv,"ecdsab163") == 0) ecdsa_doit[R_EC_B163]=2;
        +		else if (strcmp(*argv,"ecdsab233") == 0) ecdsa_doit[R_EC_B233]=2;
        +		else if (strcmp(*argv,"ecdsab283") == 0) ecdsa_doit[R_EC_B283]=2;
        +		else if (strcmp(*argv,"ecdsab409") == 0) ecdsa_doit[R_EC_B409]=2;
        +		else if (strcmp(*argv,"ecdsab571") == 0) ecdsa_doit[R_EC_B571]=2;
        +		else if (strcmp(*argv,"ecdsa") == 0)
        +			{
        +			for (i=0; i < EC_NUM; i++)
        +				ecdsa_doit[i]=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +		     if (strcmp(*argv,"ecdhp160") == 0) ecdh_doit[R_EC_P160]=2;
        +		else if (strcmp(*argv,"ecdhp192") == 0) ecdh_doit[R_EC_P192]=2;
        +		else if (strcmp(*argv,"ecdhp224") == 0) ecdh_doit[R_EC_P224]=2;
        +		else if (strcmp(*argv,"ecdhp256") == 0) ecdh_doit[R_EC_P256]=2;
        +		else if (strcmp(*argv,"ecdhp384") == 0) ecdh_doit[R_EC_P384]=2;
        +		else if (strcmp(*argv,"ecdhp521") == 0) ecdh_doit[R_EC_P521]=2;
        +		else if (strcmp(*argv,"ecdhk163") == 0) ecdh_doit[R_EC_K163]=2;
        +		else if (strcmp(*argv,"ecdhk233") == 0) ecdh_doit[R_EC_K233]=2;
        +		else if (strcmp(*argv,"ecdhk283") == 0) ecdh_doit[R_EC_K283]=2;
        +		else if (strcmp(*argv,"ecdhk409") == 0) ecdh_doit[R_EC_K409]=2;
        +		else if (strcmp(*argv,"ecdhk571") == 0) ecdh_doit[R_EC_K571]=2;
        +		else if (strcmp(*argv,"ecdhb163") == 0) ecdh_doit[R_EC_B163]=2;
        +		else if (strcmp(*argv,"ecdhb233") == 0) ecdh_doit[R_EC_B233]=2;
        +		else if (strcmp(*argv,"ecdhb283") == 0) ecdh_doit[R_EC_B283]=2;
        +		else if (strcmp(*argv,"ecdhb409") == 0) ecdh_doit[R_EC_B409]=2;
        +		else if (strcmp(*argv,"ecdhb571") == 0) ecdh_doit[R_EC_B571]=2;
        +		else if (strcmp(*argv,"ecdh") == 0)
        +			{
        +			for (i=0; i < EC_NUM; i++)
        +				ecdh_doit[i]=1;
        +			}
        +		else
        +#endif
        +			{
        +			BIO_printf(bio_err,"Error: bad option or value\n");
        +			BIO_printf(bio_err,"\n");
        +			BIO_printf(bio_err,"Available values:\n");
        +#ifndef OPENSSL_NO_MD2
        +			BIO_printf(bio_err,"md2      ");
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +			BIO_printf(bio_err,"mdc2     ");
        +#endif
        +#ifndef OPENSSL_NO_MD4
        +			BIO_printf(bio_err,"md4      ");
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +			BIO_printf(bio_err,"md5      ");
        +#ifndef OPENSSL_NO_HMAC
        +			BIO_printf(bio_err,"hmac     ");
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_SHA1
        +			BIO_printf(bio_err,"sha1     ");
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +			BIO_printf(bio_err,"sha256   ");
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +			BIO_printf(bio_err,"sha512   ");
        +#endif
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +			BIO_printf(bio_err,"whirlpool");
        +#endif
        +#ifndef OPENSSL_NO_RIPEMD160
        +			BIO_printf(bio_err,"rmd160");
        +#endif
        +#if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \
        +    !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
        +    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
        +    !defined(OPENSSL_NO_WHIRLPOOL)
        +			BIO_printf(bio_err,"\n");
        +#endif
        +
        +#ifndef OPENSSL_NO_IDEA
        +			BIO_printf(bio_err,"idea-cbc ");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +			BIO_printf(bio_err,"seed-cbc ");
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +			BIO_printf(bio_err,"rc2-cbc  ");
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +			BIO_printf(bio_err,"rc5-cbc  ");
        +#endif
        +#ifndef OPENSSL_NO_BF
        +			BIO_printf(bio_err,"bf-cbc");
        +#endif
        +#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \
        +    !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5)
        +			BIO_printf(bio_err,"\n");
        +#endif
        +#ifndef OPENSSL_NO_DES
        +			BIO_printf(bio_err,"des-cbc  des-ede3 ");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +			BIO_printf(bio_err,"aes-128-cbc aes-192-cbc aes-256-cbc ");
        +			BIO_printf(bio_err,"aes-128-ige aes-192-ige aes-256-ige ");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +			BIO_printf(bio_err,"\n");
        +			BIO_printf(bio_err,"camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +			BIO_printf(bio_err,"rc4");
        +#endif
        +			BIO_printf(bio_err,"\n");
        +
        +#ifndef OPENSSL_NO_RSA
        +			BIO_printf(bio_err,"rsa512   rsa1024  rsa2048  rsa4096\n");
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +			BIO_printf(bio_err,"dsa512   dsa1024  dsa2048\n");
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +			BIO_printf(bio_err,"ecdsap160 ecdsap192 ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
        +			BIO_printf(bio_err,"ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n");
        +			BIO_printf(bio_err,"ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n");
        +			BIO_printf(bio_err,"ecdsa\n");
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +			BIO_printf(bio_err,"ecdhp160  ecdhp192  ecdhp224  ecdhp256  ecdhp384  ecdhp521\n");
        +			BIO_printf(bio_err,"ecdhk163  ecdhk233  ecdhk283  ecdhk409  ecdhk571\n");
        +			BIO_printf(bio_err,"ecdhb163  ecdhb233  ecdhb283  ecdhb409  ecdhb571\n");
        +			BIO_printf(bio_err,"ecdh\n");
        +#endif
        +
        +#ifndef OPENSSL_NO_IDEA
        +			BIO_printf(bio_err,"idea     ");
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +			BIO_printf(bio_err,"seed     ");
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +			BIO_printf(bio_err,"rc2      ");
        +#endif
        +#ifndef OPENSSL_NO_DES
        +			BIO_printf(bio_err,"des      ");
        +#endif
        +#ifndef OPENSSL_NO_AES
        +			BIO_printf(bio_err,"aes      ");
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +			BIO_printf(bio_err,"camellia ");
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +			BIO_printf(bio_err,"rsa      ");
        +#endif
        +#ifndef OPENSSL_NO_BF
        +			BIO_printf(bio_err,"blowfish");
        +#endif
        +#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
        +    !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
        +    !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
        +    !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
        +			BIO_printf(bio_err,"\n");
        +#endif
        +
        +			BIO_printf(bio_err,"\n");
        +			BIO_printf(bio_err,"Available options:\n");
        +#if defined(TIMES) || defined(USE_TOD)
        +			BIO_printf(bio_err,"-elapsed        measure time in real time instead of CPU user time.\n");
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +			BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
        +#endif
        +			BIO_printf(bio_err,"-evp e          use EVP e.\n");
        +			BIO_printf(bio_err,"-decrypt        time decryption instead of encryption (only EVP).\n");
        +			BIO_printf(bio_err,"-mr             produce machine readable output.\n");
        +#ifndef NO_FORK
        +			BIO_printf(bio_err,"-multi n        run n benchmarks in parallel.\n");
        +#endif
        +			goto end;
        +			}
        +		argc--;
        +		argv++;
        +		j++;
        +		}
        +
        +#ifndef NO_FORK
        +	if(multi && do_multi(multi))
        +		goto show_res;
        +#endif
        +
        +	if (j == 0)
        +		{
        +		for (i=0; i<ALGOR_NUM; i++)
        +			{
        +			if (i != D_EVP)
        +				doit[i]=1;
        +			}
        +		for (i=0; i<RSA_NUM; i++)
        +			rsa_doit[i]=1;
        +		for (i=0; i<DSA_NUM; i++)
        +			dsa_doit[i]=1;
        +#ifndef OPENSSL_NO_ECDSA
        +		for (i=0; i<EC_NUM; i++)
        +			ecdsa_doit[i]=1;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +		for (i=0; i<EC_NUM; i++)
        +			ecdh_doit[i]=1;
        +#endif
        +		}
        +	for (i=0; i<ALGOR_NUM; i++)
        +		if (doit[i]) pr_header++;
        +
        +	if (usertime == 0 && !mr)
        +		BIO_printf(bio_err,"You have chosen to measure elapsed time instead of user CPU time.\n");
        +
        +#ifndef OPENSSL_NO_RSA
        +	for (i=0; i<RSA_NUM; i++)
        +		{
        +		const unsigned char *p;
        +
        +		p=rsa_data[i];
        +		rsa_key[i]=d2i_RSAPrivateKey(NULL,&p,rsa_data_length[i]);
        +		if (rsa_key[i] == NULL)
        +			{
        +			BIO_printf(bio_err,"internal error loading RSA key number %d\n",i);
        +			goto end;
        +			}
        +#if 0
        +		else
        +			{
        +			BIO_printf(bio_err,mr ? "+RK:%d:"
        +				   : "Loaded RSA key, %d bit modulus and e= 0x",
        +				   BN_num_bits(rsa_key[i]->n));
        +			BN_print(bio_err,rsa_key[i]->e);
        +			BIO_printf(bio_err,"\n");
        +			}
        +#endif
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	dsa_key[0]=get_dsa512();
        +	dsa_key[1]=get_dsa1024();
        +	dsa_key[2]=get_dsa2048();
        +#endif
        +
        +#ifndef OPENSSL_NO_DES
        +	DES_set_key_unchecked(&key,&sch);
        +	DES_set_key_unchecked(&key2,&sch2);
        +	DES_set_key_unchecked(&key3,&sch3);
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	AES_set_encrypt_key(key16,128,&aes_ks1);
        +	AES_set_encrypt_key(key24,192,&aes_ks2);
        +	AES_set_encrypt_key(key32,256,&aes_ks3);
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	Camellia_set_key(key16,128,&camellia_ks1);
        +	Camellia_set_key(ckey24,192,&camellia_ks2);
        +	Camellia_set_key(ckey32,256,&camellia_ks3);
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	idea_set_encrypt_key(key16,&idea_ks);
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	SEED_set_key(key16,&seed_ks);
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +	RC4_set_key(&rc4_ks,16,key16);
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	RC2_set_key(&rc2_ks,16,key16,128);
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	RC5_32_set_key(&rc5_ks,16,key16,12);
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	BF_set_key(&bf_ks,16,key16);
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	CAST_set_key(&cast_ks,16,key16);
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	memset(rsa_c,0,sizeof(rsa_c));
        +#endif
        +#ifndef SIGALRM
        +#ifndef OPENSSL_NO_DES
        +	BIO_printf(bio_err,"First we calculate the approximate speed ...\n");
        +	count=10;
        +	do	{
        +		long it;
        +		count*=2;
        +		Time_F(START);
        +		for (it=count; it; it--)
        +			DES_ecb_encrypt((DES_cblock *)buf,
        +				(DES_cblock *)buf,
        +				&sch,DES_ENCRYPT);
        +		d=Time_F(STOP);
        +		} while (d <3);
        +	save_count=count;
        +	c[D_MD2][0]=count/10;
        +	c[D_MDC2][0]=count/10;
        +	c[D_MD4][0]=count;
        +	c[D_MD5][0]=count;
        +	c[D_HMAC][0]=count;
        +	c[D_SHA1][0]=count;
        +	c[D_RMD160][0]=count;
        +	c[D_RC4][0]=count*5;
        +	c[D_CBC_DES][0]=count;
        +	c[D_EDE3_DES][0]=count/3;
        +	c[D_CBC_IDEA][0]=count;
        +	c[D_CBC_SEED][0]=count;
        +	c[D_CBC_RC2][0]=count;
        +	c[D_CBC_RC5][0]=count;
        +	c[D_CBC_BF][0]=count;
        +	c[D_CBC_CAST][0]=count;
        +	c[D_CBC_128_AES][0]=count;
        +	c[D_CBC_192_AES][0]=count;
        +	c[D_CBC_256_AES][0]=count;
        +	c[D_CBC_128_CML][0]=count;
        +	c[D_CBC_192_CML][0]=count;
        +	c[D_CBC_256_CML][0]=count;
        +	c[D_SHA256][0]=count;
        +	c[D_SHA512][0]=count;
        +	c[D_WHIRLPOOL][0]=count;
        +	c[D_IGE_128_AES][0]=count;
        +	c[D_IGE_192_AES][0]=count;
        +	c[D_IGE_256_AES][0]=count;
        +	c[D_GHASH][0]=count;
        +
        +	for (i=1; i<SIZE_NUM; i++)
        +		{
        +		c[D_MD2][i]=c[D_MD2][0]*4*lengths[0]/lengths[i];
        +		c[D_MDC2][i]=c[D_MDC2][0]*4*lengths[0]/lengths[i];
        +		c[D_MD4][i]=c[D_MD4][0]*4*lengths[0]/lengths[i];
        +		c[D_MD5][i]=c[D_MD5][0]*4*lengths[0]/lengths[i];
        +		c[D_HMAC][i]=c[D_HMAC][0]*4*lengths[0]/lengths[i];
        +		c[D_SHA1][i]=c[D_SHA1][0]*4*lengths[0]/lengths[i];
        +		c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
        +		c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i];
        +		c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i];
        +		c[D_WHIRLPOOL][i]=c[D_WHIRLPOOL][0]*4*lengths[0]/lengths[i];
        +		}
        +	for (i=1; i<SIZE_NUM; i++)
        +		{
        +		long l0,l1;
        +
        +		l0=(long)lengths[i-1];
        +		l1=(long)lengths[i];
        +		c[D_RC4][i]=c[D_RC4][i-1]*l0/l1;
        +		c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1;
        +		c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1;
        +		c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1;
        +		c[D_CBC_SEED][i]=c[D_CBC_SEED][i-1]*l0/l1;
        +		c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1;
        +		c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1;
        +		c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1;
        +		c[D_CBC_CAST][i]=c[D_CBC_CAST][i-1]*l0/l1;
        +		c[D_CBC_128_AES][i]=c[D_CBC_128_AES][i-1]*l0/l1;
        +		c[D_CBC_192_AES][i]=c[D_CBC_192_AES][i-1]*l0/l1;
        +		c[D_CBC_256_AES][i]=c[D_CBC_256_AES][i-1]*l0/l1;
        + 		c[D_CBC_128_CML][i]=c[D_CBC_128_CML][i-1]*l0/l1;
        +		c[D_CBC_192_CML][i]=c[D_CBC_192_CML][i-1]*l0/l1;
        +		c[D_CBC_256_CML][i]=c[D_CBC_256_CML][i-1]*l0/l1;
        +		c[D_IGE_128_AES][i]=c[D_IGE_128_AES][i-1]*l0/l1;
        +		c[D_IGE_192_AES][i]=c[D_IGE_192_AES][i-1]*l0/l1;
        +		c[D_IGE_256_AES][i]=c[D_IGE_256_AES][i-1]*l0/l1;
        +		}
        +#ifndef OPENSSL_NO_RSA
        +	rsa_c[R_RSA_512][0]=count/2000;
        +	rsa_c[R_RSA_512][1]=count/400;
        +	for (i=1; i<RSA_NUM; i++)
        +		{
        +		rsa_c[i][0]=rsa_c[i-1][0]/8;
        +		rsa_c[i][1]=rsa_c[i-1][1]/4;
        +		if ((rsa_doit[i] <= 1) && (rsa_c[i][0] == 0))
        +			rsa_doit[i]=0;
        +		else
        +			{
        +			if (rsa_c[i][0] == 0)
        +				{
        +				rsa_c[i][0]=1;
        +				rsa_c[i][1]=20;
        +				}
        +			}				
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	dsa_c[R_DSA_512][0]=count/1000;
        +	dsa_c[R_DSA_512][1]=count/1000/2;
        +	for (i=1; i<DSA_NUM; i++)
        +		{
        +		dsa_c[i][0]=dsa_c[i-1][0]/4;
        +		dsa_c[i][1]=dsa_c[i-1][1]/4;
        +		if ((dsa_doit[i] <= 1) && (dsa_c[i][0] == 0))
        +			dsa_doit[i]=0;
        +		else
        +			{
        +			if (dsa_c[i] == 0)
        +				{
        +				dsa_c[i][0]=1;
        +				dsa_c[i][1]=1;
        +				}
        +			}				
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +	ecdsa_c[R_EC_P160][0]=count/1000;
        +	ecdsa_c[R_EC_P160][1]=count/1000/2;
        +	for (i=R_EC_P192; i<=R_EC_P521; i++)
        +		{
        +		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
        +		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
        +		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
        +			ecdsa_doit[i]=0;
        +		else
        +			{
        +			if (ecdsa_c[i] == 0)
        +				{
        +				ecdsa_c[i][0]=1;
        +				ecdsa_c[i][1]=1;
        +				}
        +			}
        +		}
        +	ecdsa_c[R_EC_K163][0]=count/1000;
        +	ecdsa_c[R_EC_K163][1]=count/1000/2;
        +	for (i=R_EC_K233; i<=R_EC_K571; i++)
        +		{
        +		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
        +		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
        +		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
        +			ecdsa_doit[i]=0;
        +		else
        +			{
        +			if (ecdsa_c[i] == 0)
        +				{
        +				ecdsa_c[i][0]=1;
        +				ecdsa_c[i][1]=1;
        +				}
        +			}
        +		}
        +	ecdsa_c[R_EC_B163][0]=count/1000;
        +	ecdsa_c[R_EC_B163][1]=count/1000/2;
        +	for (i=R_EC_B233; i<=R_EC_B571; i++)
        +		{
        +		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
        +		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
        +		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
        +			ecdsa_doit[i]=0;
        +		else
        +			{
        +			if (ecdsa_c[i] == 0)
        +				{
        +				ecdsa_c[i][0]=1;
        +				ecdsa_c[i][1]=1;
        +				}
        +			}
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	ecdh_c[R_EC_P160][0]=count/1000;
        +	ecdh_c[R_EC_P160][1]=count/1000;
        +	for (i=R_EC_P192; i<=R_EC_P521; i++)
        +		{
        +		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
        +		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
        +		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
        +			ecdh_doit[i]=0;
        +		else
        +			{
        +			if (ecdh_c[i] == 0)
        +				{
        +				ecdh_c[i][0]=1;
        +				ecdh_c[i][1]=1;
        +				}
        +			}
        +		}
        +	ecdh_c[R_EC_K163][0]=count/1000;
        +	ecdh_c[R_EC_K163][1]=count/1000;
        +	for (i=R_EC_K233; i<=R_EC_K571; i++)
        +		{
        +		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
        +		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
        +		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
        +			ecdh_doit[i]=0;
        +		else
        +			{
        +			if (ecdh_c[i] == 0)
        +				{
        +				ecdh_c[i][0]=1;
        +				ecdh_c[i][1]=1;
        +				}
        +			}
        +		}
        +	ecdh_c[R_EC_B163][0]=count/1000;
        +	ecdh_c[R_EC_B163][1]=count/1000;
        +	for (i=R_EC_B233; i<=R_EC_B571; i++)
        +		{
        +		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
        +		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
        +		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
        +			ecdh_doit[i]=0;
        +		else
        +			{
        +			if (ecdh_c[i] == 0)
        +				{
        +				ecdh_c[i][0]=1;
        +				ecdh_c[i][1]=1;
        +				}
        +			}
        +		}
        +#endif
        +
        +#define COND(d)	(count < (d))
        +#define COUNT(d) (d)
        +#else
        +/* not worth fixing */
        +# error "You cannot disable DES on systems without SIGALRM."
        +#endif /* OPENSSL_NO_DES */
        +#else
        +#define COND(c)	(run && count<0x7fffffff)
        +#define COUNT(d) (count)
        +#ifndef _WIN32
        +	signal(SIGALRM,sig_done);
        +#endif
        +#endif /* SIGALRM */
        +
        +#ifndef OPENSSL_NO_MD2
        +	if (doit[D_MD2])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_MD2],c[D_MD2][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_MD2][j]); count++)
        +				EVP_Digest(buf,(unsigned long)lengths[j],&(md2[0]),NULL,EVP_md2(),NULL);
        +			d=Time_F(STOP);
        +			print_result(D_MD2,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +	if (doit[D_MDC2])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_MDC2][j]); count++)
        +				EVP_Digest(buf,(unsigned long)lengths[j],&(mdc2[0]),NULL,EVP_mdc2(),NULL);
        +			d=Time_F(STOP);
        +			print_result(D_MDC2,j,count,d);
        +			}
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_MD4
        +	if (doit[D_MD4])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_MD4],c[D_MD4][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_MD4][j]); count++)
        +				EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md4[0]),NULL,EVP_md4(),NULL);
        +			d=Time_F(STOP);
        +			print_result(D_MD4,j,count,d);
        +			}
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_MD5
        +	if (doit[D_MD5])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_MD5],c[D_MD5][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_MD5][j]); count++)
        +				EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL);
        +			d=Time_F(STOP);
        +			print_result(D_MD5,j,count,d);
        +			}
        +		}
        +#endif
        +
        +#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC)
        +	if (doit[D_HMAC])
        +		{
        +		HMAC_CTX hctx;
        +
        +		HMAC_CTX_init(&hctx);
        +		HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...",
        +			16,EVP_md5(), NULL);
        +
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_HMAC][j]); count++)
        +				{
        +				HMAC_Init_ex(&hctx,NULL,0,NULL,NULL);
        +				HMAC_Update(&hctx,buf,lengths[j]);
        +				HMAC_Final(&hctx,&(hmac[0]),NULL);
        +				}
        +			d=Time_F(STOP);
        +			print_result(D_HMAC,j,count,d);
        +			}
        +		HMAC_CTX_cleanup(&hctx);
        +		}
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	if (doit[D_SHA1])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_SHA1][j]); count++)
        +				EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL);
        +			d=Time_F(STOP);
        +			print_result(D_SHA1,j,count,d);
        +			}
        +		}
        +
        +#ifndef OPENSSL_NO_SHA256
        +	if (doit[D_SHA256])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_SHA256],c[D_SHA256][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_SHA256][j]); count++)
        +				SHA256(buf,lengths[j],sha256);
        +			d=Time_F(STOP);
        +			print_result(D_SHA256,j,count,d);
        +			}
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA512
        +	if (doit[D_SHA512])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_SHA512],c[D_SHA512][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_SHA512][j]); count++)
        +				SHA512(buf,lengths[j],sha512);
        +			d=Time_F(STOP);
        +			print_result(D_SHA512,j,count,d);
        +			}
        +		}
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +	if (doit[D_WHIRLPOOL])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_WHIRLPOOL],c[D_WHIRLPOOL][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_WHIRLPOOL][j]); count++)
        +				WHIRLPOOL(buf,lengths[j],whirlpool);
        +			d=Time_F(STOP);
        +			print_result(D_WHIRLPOOL,j,count,d);
        +			}
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_RIPEMD
        +	if (doit[D_RMD160])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_RMD160][j]); count++)
        +				EVP_Digest(buf,(unsigned long)lengths[j],&(rmd160[0]),NULL,EVP_ripemd160(),NULL);
        +			d=Time_F(STOP);
        +			print_result(D_RMD160,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +	if (doit[D_RC4])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_RC4],c[D_RC4][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_RC4][j]); count++)
        +				RC4(&rc4_ks,(unsigned int)lengths[j],
        +					buf,buf);
        +			d=Time_F(STOP);
        +			print_result(D_RC4,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_DES
        +	if (doit[D_CBC_DES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_DES],c[D_CBC_DES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_DES][j]); count++)
        +				DES_ncbc_encrypt(buf,buf,lengths[j],&sch,
        +						 &DES_iv,DES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_DES,j,count,d);
        +			}
        +		}
        +
        +	if (doit[D_EDE3_DES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_EDE3_DES],c[D_EDE3_DES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_EDE3_DES][j]); count++)
        +				DES_ede3_cbc_encrypt(buf,buf,lengths[j],
        +						     &sch,&sch2,&sch3,
        +						     &DES_iv,DES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_EDE3_DES,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	if (doit[D_CBC_128_AES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_128_AES],c[D_CBC_128_AES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_128_AES][j]); count++)
        +				AES_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&aes_ks1,
        +					iv,AES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_128_AES,j,count,d);
        +			}
        +		}
        +	if (doit[D_CBC_192_AES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_192_AES],c[D_CBC_192_AES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_192_AES][j]); count++)
        +				AES_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&aes_ks2,
        +					iv,AES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_192_AES,j,count,d);
        +			}
        +		}
        +	if (doit[D_CBC_256_AES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_256_AES],c[D_CBC_256_AES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_256_AES][j]); count++)
        +				AES_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&aes_ks3,
        +					iv,AES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_256_AES,j,count,d);
        +			}
        +		}
        +
        +	if (doit[D_IGE_128_AES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_IGE_128_AES],c[D_IGE_128_AES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_IGE_128_AES][j]); count++)
        +				AES_ige_encrypt(buf,buf2,
        +					(unsigned long)lengths[j],&aes_ks1,
        +					iv,AES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_IGE_128_AES,j,count,d);
        +			}
        +		}
        +	if (doit[D_IGE_192_AES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_IGE_192_AES],c[D_IGE_192_AES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_IGE_192_AES][j]); count++)
        +				AES_ige_encrypt(buf,buf2,
        +					(unsigned long)lengths[j],&aes_ks2,
        +					iv,AES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_IGE_192_AES,j,count,d);
        +			}
        +		}
        +	if (doit[D_IGE_256_AES])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_IGE_256_AES],c[D_IGE_256_AES][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_IGE_256_AES][j]); count++)
        +				AES_ige_encrypt(buf,buf2,
        +					(unsigned long)lengths[j],&aes_ks3,
        +					iv,AES_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_IGE_256_AES,j,count,d);
        +			}
        +		}
        +	if (doit[D_GHASH])
        +		{
        +		GCM128_CONTEXT *ctx = CRYPTO_gcm128_new(&aes_ks1,(block128_f)AES_encrypt);
        +		CRYPTO_gcm128_setiv (ctx,(unsigned char *)"0123456789ab",12);
        +
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_GHASH],c[D_GHASH][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_GHASH][j]); count++)
        +				CRYPTO_gcm128_aad(ctx,buf,lengths[j]);
        +			d=Time_F(STOP);
        +			print_result(D_GHASH,j,count,d);
        +			}
        +		CRYPTO_gcm128_release(ctx);
        +		}
        +
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	if (doit[D_CBC_128_CML])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_128_CML],c[D_CBC_128_CML][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_128_CML][j]); count++)
        +				Camellia_cbc_encrypt(buf,buf,
        +				        (unsigned long)lengths[j],&camellia_ks1,
        +				        iv,CAMELLIA_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_128_CML,j,count,d);
        +			}
        +		}
        +	if (doit[D_CBC_192_CML])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_192_CML],c[D_CBC_192_CML][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_192_CML][j]); count++)
        +				Camellia_cbc_encrypt(buf,buf,
        +				        (unsigned long)lengths[j],&camellia_ks2,
        +				        iv,CAMELLIA_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_192_CML,j,count,d);
        +			}
        +		}
        +	if (doit[D_CBC_256_CML])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_256_CML],c[D_CBC_256_CML][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_256_CML][j]); count++)
        +				Camellia_cbc_encrypt(buf,buf,
        +				        (unsigned long)lengths[j],&camellia_ks3,
        +				        iv,CAMELLIA_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_256_CML,j,count,d);
        +			}
        +		}
        +
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	if (doit[D_CBC_IDEA])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_IDEA],c[D_CBC_IDEA][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_IDEA][j]); count++)
        +				idea_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&idea_ks,
        +					iv,IDEA_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_IDEA,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_SEED
        +	if (doit[D_CBC_SEED])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_SEED],c[D_CBC_SEED][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_SEED][j]); count++)
        +				SEED_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&seed_ks,iv,1);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_SEED,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +	if (doit[D_CBC_RC2])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_RC2],c[D_CBC_RC2][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_RC2][j]); count++)
        +				RC2_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&rc2_ks,
        +					iv,RC2_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_RC2,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +	if (doit[D_CBC_RC5])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_RC5],c[D_CBC_RC5][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_RC5][j]); count++)
        +				RC5_32_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&rc5_ks,
        +					iv,RC5_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_RC5,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_BF
        +	if (doit[D_CBC_BF])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_BF],c[D_CBC_BF][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_BF][j]); count++)
        +				BF_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&bf_ks,
        +					iv,BF_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_BF,j,count,d);
        +			}
        +		}
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +	if (doit[D_CBC_CAST])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			print_message(names[D_CBC_CAST],c[D_CBC_CAST][j],lengths[j]);
        +			Time_F(START);
        +			for (count=0,run=1; COND(c[D_CBC_CAST][j]); count++)
        +				CAST_cbc_encrypt(buf,buf,
        +					(unsigned long)lengths[j],&cast_ks,
        +					iv,CAST_ENCRYPT);
        +			d=Time_F(STOP);
        +			print_result(D_CBC_CAST,j,count,d);
        +			}
        +		}
        +#endif
        +
        +	if (doit[D_EVP])
        +		{
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			if (evp_cipher)
        +				{
        +				EVP_CIPHER_CTX ctx;
        +				int outl;
        +
        +				names[D_EVP]=OBJ_nid2ln(evp_cipher->nid);
        +				/* -O3 -fschedule-insns messes up an
        +				 * optimization here!  names[D_EVP]
        +				 * somehow becomes NULL */
        +				print_message(names[D_EVP],save_count,
        +					lengths[j]);
        +
        +				EVP_CIPHER_CTX_init(&ctx);
        +				if(decrypt)
        +					EVP_DecryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
        +				else
        +					EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
        +				EVP_CIPHER_CTX_set_padding(&ctx, 0);
        +
        +				Time_F(START);
        +				if(decrypt)
        +					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
        +						EVP_DecryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
        +				else
        +					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
        +						EVP_EncryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
        +				if(decrypt)
        +					EVP_DecryptFinal_ex(&ctx,buf,&outl);
        +				else
        +					EVP_EncryptFinal_ex(&ctx,buf,&outl);
        +				d=Time_F(STOP);
        +				EVP_CIPHER_CTX_cleanup(&ctx);
        +				}
        +			if (evp_md)
        +				{
        +				names[D_EVP]=OBJ_nid2ln(evp_md->type);
        +				print_message(names[D_EVP],save_count,
        +					lengths[j]);
        +
        +				Time_F(START);
        +				for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
        +					EVP_Digest(buf,lengths[j],&(md[0]),NULL,evp_md,NULL);
        +
        +				d=Time_F(STOP);
        +				}
        +			print_result(D_EVP,j,count,d);
        +			}
        +		}
        +
        +	RAND_pseudo_bytes(buf,36);
        +#ifndef OPENSSL_NO_RSA
        +	for (j=0; j<RSA_NUM; j++)
        +		{
        +		int ret;
        +		if (!rsa_doit[j]) continue;
        +		ret=RSA_sign(NID_md5_sha1, buf,36, buf2, &rsa_num, rsa_key[j]);
        +		if (ret == 0)
        +			{
        +			BIO_printf(bio_err,"RSA sign failure.  No RSA sign will be done.\n");
        +			ERR_print_errors(bio_err);
        +			rsa_count=1;
        +			}
        +		else
        +			{
        +			pkey_print_message("private","rsa",
        +				rsa_c[j][0],rsa_bits[j],
        +				RSA_SECONDS);
        +/*			RSA_blinding_on(rsa_key[j],NULL); */
        +			Time_F(START);
        +			for (count=0,run=1; COND(rsa_c[j][0]); count++)
        +				{
        +				ret=RSA_sign(NID_md5_sha1, buf,36, buf2,
        +					&rsa_num, rsa_key[j]);
        +				if (ret == 0)
        +					{
        +					BIO_printf(bio_err,
        +						"RSA sign failure\n");
        +					ERR_print_errors(bio_err);
        +					count=1;
        +					break;
        +					}
        +				}
        +			d=Time_F(STOP);
        +			BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n"
        +				   : "%ld %d bit private RSA's in %.2fs\n",
        +				   count,rsa_bits[j],d);
        +			rsa_results[j][0]=d/(double)count;
        +			rsa_count=count;
        +			}
        +
        +#if 1
        +		ret=RSA_verify(NID_md5_sha1, buf,36, buf2, rsa_num, rsa_key[j]);
        +		if (ret <= 0)
        +			{
        +			BIO_printf(bio_err,"RSA verify failure.  No RSA verify will be done.\n");
        +			ERR_print_errors(bio_err);
        +			rsa_doit[j] = 0;
        +			}
        +		else
        +			{
        +			pkey_print_message("public","rsa",
        +				rsa_c[j][1],rsa_bits[j],
        +				RSA_SECONDS);
        +			Time_F(START);
        +			for (count=0,run=1; COND(rsa_c[j][1]); count++)
        +				{
        +				ret=RSA_verify(NID_md5_sha1, buf,36, buf2,
        +					rsa_num, rsa_key[j]);
        +				if (ret <= 0)
        +					{
        +					BIO_printf(bio_err,
        +						"RSA verify failure\n");
        +					ERR_print_errors(bio_err);
        +					count=1;
        +					break;
        +					}
        +				}
        +			d=Time_F(STOP);
        +			BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n"
        +				   : "%ld %d bit public RSA's in %.2fs\n",
        +				   count,rsa_bits[j],d);
        +			rsa_results[j][1]=d/(double)count;
        +			}
        +#endif
        +
        +		if (rsa_count <= 1)
        +			{
        +			/* if longer than 10s, don't do any more */
        +			for (j++; j<RSA_NUM; j++)
        +				rsa_doit[j]=0;
        +			}
        +		}
        +#endif
        +
        +	RAND_pseudo_bytes(buf,20);
        +#ifndef OPENSSL_NO_DSA
        +	if (RAND_status() != 1)
        +		{
        +		RAND_seed(rnd_seed, sizeof rnd_seed);
        +		rnd_fake = 1;
        +		}
        +	for (j=0; j<DSA_NUM; j++)
        +		{
        +		unsigned int kk;
        +		int ret;
        +
        +		if (!dsa_doit[j]) continue;
        +/*		DSA_generate_key(dsa_key[j]); */
        +/*		DSA_sign_setup(dsa_key[j],NULL); */
        +		ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
        +			&kk,dsa_key[j]);
        +		if (ret == 0)
        +			{
        +			BIO_printf(bio_err,"DSA sign failure.  No DSA sign will be done.\n");
        +			ERR_print_errors(bio_err);
        +			rsa_count=1;
        +			}
        +		else
        +			{
        +			pkey_print_message("sign","dsa",
        +				dsa_c[j][0],dsa_bits[j],
        +				DSA_SECONDS);
        +			Time_F(START);
        +			for (count=0,run=1; COND(dsa_c[j][0]); count++)
        +				{
        +				ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
        +					&kk,dsa_key[j]);
        +				if (ret == 0)
        +					{
        +					BIO_printf(bio_err,
        +						"DSA sign failure\n");
        +					ERR_print_errors(bio_err);
        +					count=1;
        +					break;
        +					}
        +				}
        +			d=Time_F(STOP);
        +			BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n"
        +				   : "%ld %d bit DSA signs in %.2fs\n",
        +				   count,dsa_bits[j],d);
        +			dsa_results[j][0]=d/(double)count;
        +			rsa_count=count;
        +			}
        +
        +		ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
        +			kk,dsa_key[j]);
        +		if (ret <= 0)
        +			{
        +			BIO_printf(bio_err,"DSA verify failure.  No DSA verify will be done.\n");
        +			ERR_print_errors(bio_err);
        +			dsa_doit[j] = 0;
        +			}
        +		else
        +			{
        +			pkey_print_message("verify","dsa",
        +				dsa_c[j][1],dsa_bits[j],
        +				DSA_SECONDS);
        +			Time_F(START);
        +			for (count=0,run=1; COND(dsa_c[j][1]); count++)
        +				{
        +				ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
        +					kk,dsa_key[j]);
        +				if (ret <= 0)
        +					{
        +					BIO_printf(bio_err,
        +						"DSA verify failure\n");
        +					ERR_print_errors(bio_err);
        +					count=1;
        +					break;
        +					}
        +				}
        +			d=Time_F(STOP);
        +			BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n"
        +				   : "%ld %d bit DSA verify in %.2fs\n",
        +				   count,dsa_bits[j],d);
        +			dsa_results[j][1]=d/(double)count;
        +			}
        +
        +		if (rsa_count <= 1)
        +			{
        +			/* if longer than 10s, don't do any more */
        +			for (j++; j<DSA_NUM; j++)
        +				dsa_doit[j]=0;
        +			}
        +		}
        +	if (rnd_fake) RAND_cleanup();
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +	if (RAND_status() != 1) 
        +		{
        +		RAND_seed(rnd_seed, sizeof rnd_seed);
        +		rnd_fake = 1;
        +		}
        +	for (j=0; j<EC_NUM; j++) 
        +		{
        +		int ret;
        +
        +		if (!ecdsa_doit[j]) continue; /* Ignore Curve */ 
        +		ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]);
        +		if (ecdsa[j] == NULL) 
        +			{
        +			BIO_printf(bio_err,"ECDSA failure.\n");
        +			ERR_print_errors(bio_err);
        +			rsa_count=1;
        +			} 
        +		else 
        +			{
        +#if 1
        +			EC_KEY_precompute_mult(ecdsa[j], NULL);
        +#endif
        +			/* Perform ECDSA signature test */
        +			EC_KEY_generate_key(ecdsa[j]);
        +			ret = ECDSA_sign(0, buf, 20, ecdsasig, 
        +				&ecdsasiglen, ecdsa[j]);
        +			if (ret == 0) 
        +				{
        +				BIO_printf(bio_err,"ECDSA sign failure.  No ECDSA sign will be done.\n");
        +				ERR_print_errors(bio_err);
        +				rsa_count=1;
        +				} 
        +			else 
        +				{
        +				pkey_print_message("sign","ecdsa",
        +					ecdsa_c[j][0], 
        +					test_curves_bits[j],
        +					ECDSA_SECONDS);
        +
        +				Time_F(START);
        +				for (count=0,run=1; COND(ecdsa_c[j][0]);
        +					count++) 
        +					{
        +					ret=ECDSA_sign(0, buf, 20, 
        +						ecdsasig, &ecdsasiglen,
        +						ecdsa[j]);
        +					if (ret == 0) 
        +						{
        +						BIO_printf(bio_err, "ECDSA sign failure\n");
        +						ERR_print_errors(bio_err);
        +						count=1;
        +						break;
        +						}
        +					}
        +				d=Time_F(STOP);
        +
        +				BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
        +					"%ld %d bit ECDSA signs in %.2fs \n", 
        +					count, test_curves_bits[j], d);
        +				ecdsa_results[j][0]=d/(double)count;
        +				rsa_count=count;
        +				}
        +
        +			/* Perform ECDSA verification test */
        +			ret=ECDSA_verify(0, buf, 20, ecdsasig, 
        +				ecdsasiglen, ecdsa[j]);
        +			if (ret != 1) 
        +				{
        +				BIO_printf(bio_err,"ECDSA verify failure.  No ECDSA verify will be done.\n");
        +				ERR_print_errors(bio_err);
        +				ecdsa_doit[j] = 0;
        +				} 
        +			else 
        +				{
        +				pkey_print_message("verify","ecdsa",
        +				ecdsa_c[j][1],
        +				test_curves_bits[j],
        +				ECDSA_SECONDS);
        +				Time_F(START);
        +				for (count=0,run=1; COND(ecdsa_c[j][1]); count++) 
        +					{
        +					ret=ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
        +					if (ret != 1) 
        +						{
        +						BIO_printf(bio_err, "ECDSA verify failure\n");
        +						ERR_print_errors(bio_err);
        +						count=1;
        +						break;
        +						}
        +					}
        +				d=Time_F(STOP);
        +				BIO_printf(bio_err, mr? "+R6:%ld:%d:%.2f\n"
        +						: "%ld %d bit ECDSA verify in %.2fs\n",
        +				count, test_curves_bits[j], d);
        +				ecdsa_results[j][1]=d/(double)count;
        +				}
        +
        +			if (rsa_count <= 1) 
        +				{
        +				/* if longer than 10s, don't do any more */
        +				for (j++; j<EC_NUM; j++)
        +				ecdsa_doit[j]=0;
        +				}
        +			}
        +		}
        +	if (rnd_fake) RAND_cleanup();
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	if (RAND_status() != 1)
        +		{
        +		RAND_seed(rnd_seed, sizeof rnd_seed);
        +		rnd_fake = 1;
        +		}
        +	for (j=0; j<EC_NUM; j++)
        +		{
        +		if (!ecdh_doit[j]) continue;
        +		ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]);
        +		ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]);
        +		if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL))
        +			{
        +			BIO_printf(bio_err,"ECDH failure.\n");
        +			ERR_print_errors(bio_err);
        +			rsa_count=1;
        +			}
        +		else
        +			{
        +			/* generate two ECDH key pairs */
        +			if (!EC_KEY_generate_key(ecdh_a[j]) ||
        +				!EC_KEY_generate_key(ecdh_b[j]))
        +				{
        +				BIO_printf(bio_err,"ECDH key generation failure.\n");
        +				ERR_print_errors(bio_err);
        +				rsa_count=1;		
        +				}
        +			else
        +				{
        +				/* If field size is not more than 24 octets, then use SHA-1 hash of result;
        +				 * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
        +				 */
        +				int field_size, outlen;
        +				void *(*kdf)(const void *in, size_t inlen, void *out, size_t *xoutlen);
        +				field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j]));
        +				if (field_size <= 24 * 8)
        +					{
        +					outlen = KDF1_SHA1_len;
        +					kdf = KDF1_SHA1;
        +					}
        +				else
        +					{
        +					outlen = (field_size+7)/8;
        +					kdf = NULL;
        +					}
        +				secret_size_a = ECDH_compute_key(secret_a, outlen,
        +					EC_KEY_get0_public_key(ecdh_b[j]),
        +					ecdh_a[j], kdf);
        +				secret_size_b = ECDH_compute_key(secret_b, outlen,
        +					EC_KEY_get0_public_key(ecdh_a[j]),
        +					ecdh_b[j], kdf);
        +				if (secret_size_a != secret_size_b) 
        +					ecdh_checks = 0;
        +				else
        +					ecdh_checks = 1;
        +
        +				for (secret_idx = 0; 
        +				    (secret_idx < secret_size_a)
        +					&& (ecdh_checks == 1);
        +				    secret_idx++)
        +					{
        +					if (secret_a[secret_idx] != secret_b[secret_idx])
        +					ecdh_checks = 0;
        +					}
        +
        +				if (ecdh_checks == 0)
        +					{
        +					BIO_printf(bio_err,"ECDH computations don't match.\n");
        +					ERR_print_errors(bio_err);
        +					rsa_count=1;		
        +					}
        +
        +				pkey_print_message("","ecdh",
        +				ecdh_c[j][0], 
        +				test_curves_bits[j],
        +				ECDH_SECONDS);
        +				Time_F(START);
        +				for (count=0,run=1; COND(ecdh_c[j][0]); count++)
        +					{
        +					ECDH_compute_key(secret_a, outlen,
        +					EC_KEY_get0_public_key(ecdh_b[j]),
        +					ecdh_a[j], kdf);
        +					}
        +				d=Time_F(STOP);
        +				BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" :"%ld %d-bit ECDH ops in %.2fs\n",
        +				count, test_curves_bits[j], d);
        +				ecdh_results[j][0]=d/(double)count;
        +				rsa_count=count;
        +				}
        +			}
        +
        +
        +		if (rsa_count <= 1)
        +			{
        +			/* if longer than 10s, don't do any more */
        +			for (j++; j<EC_NUM; j++)
        +			ecdh_doit[j]=0;
        +			}
        +		}
        +	if (rnd_fake) RAND_cleanup();
        +#endif
        +#ifndef NO_FORK
        +show_res:
        +#endif
        +	if(!mr)
        +		{
        +		fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_VERSION));
        +        fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_BUILT_ON));
        +		printf("options:");
        +		printf("%s ",BN_options());
        +#ifndef OPENSSL_NO_MD2
        +		printf("%s ",MD2_options());
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +		printf("%s ",RC4_options());
        +#endif
        +#ifndef OPENSSL_NO_DES
        +		printf("%s ",DES_options());
        +#endif
        +#ifndef OPENSSL_NO_AES
        +		printf("%s ",AES_options());
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +		printf("%s ",idea_options());
        +#endif
        +#ifndef OPENSSL_NO_BF
        +		printf("%s ",BF_options());
        +#endif
        +		fprintf(stdout,"\n%s\n",SSLeay_version(SSLEAY_CFLAGS));
        +		}
        +
        +	if (pr_header)
        +		{
        +		if(mr)
        +			fprintf(stdout,"+H");
        +		else
        +			{
        +			fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n"); 
        +			fprintf(stdout,"type        ");
        +			}
        +		for (j=0;  j<SIZE_NUM; j++)
        +			fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]);
        +		fprintf(stdout,"\n");
        +		}
        +
        +	for (k=0; k<ALGOR_NUM; k++)
        +		{
        +		if (!doit[k]) continue;
        +		if(mr)
        +			fprintf(stdout,"+F:%d:%s",k,names[k]);
        +		else
        +			fprintf(stdout,"%-13s",names[k]);
        +		for (j=0; j<SIZE_NUM; j++)
        +			{
        +			if (results[k][j] > 10000 && !mr)
        +				fprintf(stdout," %11.2fk",results[k][j]/1e3);
        +			else
        +				fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]);
        +			}
        +		fprintf(stdout,"\n");
        +		}
        +#ifndef OPENSSL_NO_RSA
        +	j=1;
        +	for (k=0; k<RSA_NUM; k++)
        +		{
        +		if (!rsa_doit[k]) continue;
        +		if (j && !mr)
        +			{
        +			printf("%18ssign    verify    sign/s verify/s\n"," ");
        +			j=0;
        +			}
        +		if(mr)
        +			fprintf(stdout,"+F2:%u:%u:%f:%f\n",
        +				k,rsa_bits[k],rsa_results[k][0],
        +				rsa_results[k][1]);
        +		else
        +			fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
        +				rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
        +				1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
        +		}
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	j=1;
        +	for (k=0; k<DSA_NUM; k++)
        +		{
        +		if (!dsa_doit[k]) continue;
        +		if (j && !mr)
        +			{
        +			printf("%18ssign    verify    sign/s verify/s\n"," ");
        +			j=0;
        +			}
        +		if(mr)
        +			fprintf(stdout,"+F3:%u:%u:%f:%f\n",
        +				k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
        +		else
        +			fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
        +				dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
        +				1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
        +		}
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	j=1;
        +	for (k=0; k<EC_NUM; k++)
        +		{
        +		if (!ecdsa_doit[k]) continue;
        +		if (j && !mr)
        +			{
        +			printf("%30ssign    verify    sign/s verify/s\n"," ");
        +			j=0;
        +			}
        +
        +		if (mr)
        +			fprintf(stdout,"+F4:%u:%u:%f:%f\n", 
        +				k, test_curves_bits[k],
        +				ecdsa_results[k][0],ecdsa_results[k][1]);
        +		else
        +			fprintf(stdout,
        +				"%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", 
        +				test_curves_bits[k],
        +				test_curves_names[k],
        +				ecdsa_results[k][0],ecdsa_results[k][1], 
        +				1.0/ecdsa_results[k][0],1.0/ecdsa_results[k][1]);
        +		}
        +#endif
        +
        +
        +#ifndef OPENSSL_NO_ECDH
        +	j=1;
        +	for (k=0; k<EC_NUM; k++)
        +		{
        +		if (!ecdh_doit[k]) continue;
        +		if (j && !mr)
        +			{
        +			printf("%30sop      op/s\n"," ");
        +			j=0;
        +			}
        +		if (mr)
        +			fprintf(stdout,"+F5:%u:%u:%f:%f\n",
        +				k, test_curves_bits[k],
        +				ecdh_results[k][0], 1.0/ecdh_results[k][0]);
        +
        +		else
        +			fprintf(stdout,"%4u bit ecdh (%s) %8.4fs %8.1f\n",
        +				test_curves_bits[k],
        +				test_curves_names[k],
        +				ecdh_results[k][0], 1.0/ecdh_results[k][0]);
        +		}
        +#endif
        +
        +	mret=0;
        +
        +end:
        +	ERR_print_errors(bio_err);
        +	if (buf != NULL) OPENSSL_free(buf);
        +	if (buf2 != NULL) OPENSSL_free(buf2);
        +#ifndef OPENSSL_NO_RSA
        +	for (i=0; i<RSA_NUM; i++)
        +		if (rsa_key[i] != NULL)
        +			RSA_free(rsa_key[i]);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	for (i=0; i<DSA_NUM; i++)
        +		if (dsa_key[i] != NULL)
        +			DSA_free(dsa_key[i]);
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +	for (i=0; i<EC_NUM; i++)
        +		if (ecdsa[i] != NULL)
        +			EC_KEY_free(ecdsa[i]);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	for (i=0; i<EC_NUM; i++)
        +	{
        +		if (ecdh_a[i] != NULL)
        +			EC_KEY_free(ecdh_a[i]);
        +		if (ecdh_b[i] != NULL)
        +			EC_KEY_free(ecdh_b[i]);
        +	}
        +#endif
        +
        +	apps_shutdown();
        +	OPENSSL_EXIT(mret);
        +	}
        +
        +static void print_message(const char *s, long num, int length)
        +	{
        +#ifdef SIGALRM
        +	BIO_printf(bio_err,mr ? "+DT:%s:%d:%d\n"
        +		   : "Doing %s for %ds on %d size blocks: ",s,SECONDS,length);
        +	(void)BIO_flush(bio_err);
        +	alarm(SECONDS);
        +#else
        +	BIO_printf(bio_err,mr ? "+DN:%s:%ld:%d\n"
        +		   : "Doing %s %ld times on %d size blocks: ",s,num,length);
        +	(void)BIO_flush(bio_err);
        +#endif
        +#ifdef LINT
        +	num=num;
        +#endif
        +	}
        +
        +static void pkey_print_message(const char *str, const char *str2, long num,
        +	int bits, int tm)
        +	{
        +#ifdef SIGALRM
        +	BIO_printf(bio_err,mr ? "+DTP:%d:%s:%s:%d\n"
        +			   : "Doing %d bit %s %s's for %ds: ",bits,str,str2,tm);
        +	(void)BIO_flush(bio_err);
        +	alarm(tm);
        +#else
        +	BIO_printf(bio_err,mr ? "+DNP:%ld:%d:%s:%s\n"
        +			   : "Doing %ld %d bit %s %s's: ",num,bits,str,str2);
        +	(void)BIO_flush(bio_err);
        +#endif
        +#ifdef LINT
        +	num=num;
        +#endif
        +	}
        +
        +static void print_result(int alg,int run_no,int count,double time_used)
        +	{
        +	BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
        +		   : "%d %s's in %.2fs\n",count,names[alg],time_used);
        +	results[alg][run_no]=((double)count)/time_used*lengths[run_no];
        +	}
        +
        +#ifndef NO_FORK
        +static char *sstrsep(char **string, const char *delim)
        +    {
        +    char isdelim[256];
        +    char *token = *string;
        +
        +    if (**string == 0)
        +        return NULL;
        +
        +    memset(isdelim, 0, sizeof isdelim);
        +    isdelim[0] = 1;
        +
        +    while (*delim)
        +        {
        +        isdelim[(unsigned char)(*delim)] = 1;
        +        delim++;
        +        }
        +
        +    while (!isdelim[(unsigned char)(**string)])
        +        {
        +        (*string)++;
        +        }
        +
        +    if (**string)
        +        {
        +        **string = 0;
        +        (*string)++;
        +        }
        +
        +    return token;
        +    }
        +
        +static int do_multi(int multi)
        +	{
        +	int n;
        +	int fd[2];
        +	int *fds;
        +	static char sep[]=":";
        +
        +	fds=malloc(multi*sizeof *fds);
        +	for(n=0 ; n < multi ; ++n)
        +		{
        +		if (pipe(fd) == -1)
        +			{
        +			fprintf(stderr, "pipe failure\n");
        +			exit(1);
        +			}
        +		fflush(stdout);
        +		fflush(stderr);
        +		if(fork())
        +			{
        +			close(fd[1]);
        +			fds[n]=fd[0];
        +			}
        +		else
        +			{
        +			close(fd[0]);
        +			close(1);
        +			if (dup(fd[1]) == -1)
        +				{
        +				fprintf(stderr, "dup failed\n");
        +				exit(1);
        +				}
        +			close(fd[1]);
        +			mr=1;
        +			usertime=0;
        +			free(fds);
        +			return 0;
        +			}
        +		printf("Forked child %d\n",n);
        +		}
        +
        +	/* for now, assume the pipe is long enough to take all the output */
        +	for(n=0 ; n < multi ; ++n)
        +		{
        +		FILE *f;
        +		char buf[1024];
        +		char *p;
        +
        +		f=fdopen(fds[n],"r");
        +		while(fgets(buf,sizeof buf,f))
        +			{
        +			p=strchr(buf,'\n');
        +			if(p)
        +				*p='\0';
        +			if(buf[0] != '+')
        +				{
        +				fprintf(stderr,"Don't understand line '%s' from child %d\n",
        +						buf,n);
        +				continue;
        +				}
        +			printf("Got: %s from %d\n",buf,n);
        +			if(!strncmp(buf,"+F:",3))
        +				{
        +				int alg;
        +				int j;
        +
        +				p=buf+3;
        +				alg=atoi(sstrsep(&p,sep));
        +				sstrsep(&p,sep);
        +				for(j=0 ; j < SIZE_NUM ; ++j)
        +					results[alg][j]+=atof(sstrsep(&p,sep));
        +				}
        +			else if(!strncmp(buf,"+F2:",4))
        +				{
        +				int k;
        +				double d;
        +				
        +				p=buf+4;
        +				k=atoi(sstrsep(&p,sep));
        +				sstrsep(&p,sep);
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
        +				else
        +					rsa_results[k][0]=d;
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
        +				else
        +					rsa_results[k][1]=d;
        +				}
        +			else if(!strncmp(buf,"+F2:",4))
        +				{
        +				int k;
        +				double d;
        +				
        +				p=buf+4;
        +				k=atoi(sstrsep(&p,sep));
        +				sstrsep(&p,sep);
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
        +				else
        +					rsa_results[k][0]=d;
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
        +				else
        +					rsa_results[k][1]=d;
        +				}
        +#ifndef OPENSSL_NO_DSA
        +			else if(!strncmp(buf,"+F3:",4))
        +				{
        +				int k;
        +				double d;
        +				
        +				p=buf+4;
        +				k=atoi(sstrsep(&p,sep));
        +				sstrsep(&p,sep);
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d);
        +				else
        +					dsa_results[k][0]=d;
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d);
        +				else
        +					dsa_results[k][1]=d;
        +				}
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +			else if(!strncmp(buf,"+F4:",4))
        +				{
        +				int k;
        +				double d;
        +				
        +				p=buf+4;
        +				k=atoi(sstrsep(&p,sep));
        +				sstrsep(&p,sep);
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					ecdsa_results[k][0]=1/(1/ecdsa_results[k][0]+1/d);
        +				else
        +					ecdsa_results[k][0]=d;
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					ecdsa_results[k][1]=1/(1/ecdsa_results[k][1]+1/d);
        +				else
        +					ecdsa_results[k][1]=d;
        +				}
        +#endif 
        +
        +#ifndef OPENSSL_NO_ECDH
        +			else if(!strncmp(buf,"+F5:",4))
        +				{
        +				int k;
        +				double d;
        +				
        +				p=buf+4;
        +				k=atoi(sstrsep(&p,sep));
        +				sstrsep(&p,sep);
        +
        +				d=atof(sstrsep(&p,sep));
        +				if(n)
        +					ecdh_results[k][0]=1/(1/ecdh_results[k][0]+1/d);
        +				else
        +					ecdh_results[k][0]=d;
        +
        +				}
        +#endif
        +
        +			else if(!strncmp(buf,"+H:",3))
        +				{
        +				}
        +			else
        +				fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n);
        +			}
        +
        +		fclose(f);
        +		}
        +	free(fds);
        +	return 1;
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/apps/spkac.c b/vendor/openssl/openssl/apps/spkac.c
        new file mode 100644
        index 000000000..0e01ea994
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/spkac.c
        @@ -0,0 +1,308 @@
        +/* apps/spkac.c */
        +
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999. Based on an original idea by Massimiliano Pala
        + * (madwolf@openca.org).
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/conf.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/lhash.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	spkac_main
        +
        +/* -in arg	- input file - default stdin
        + * -out arg	- output file - default stdout
        + */
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int i,badops=0, ret = 1;
        +	BIO *in = NULL,*out = NULL;
        +	int verify=0,noout=0,pubkey=0;
        +	char *infile = NULL,*outfile = NULL,*prog;
        +	char *passargin = NULL, *passin = NULL;
        +	const char *spkac = "SPKAC", *spksect = "default";
        +	char *spkstr = NULL;
        +	char *challenge = NULL, *keyfile = NULL;
        +	CONF *conf = NULL;
        +	NETSCAPE_SPKI *spki = NULL;
        +	EVP_PKEY *pkey = NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	apps_startup();
        +
        +	if (!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	prog=argv[0];
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-challenge") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			challenge= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-spkac") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			spkac= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-spksect") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			spksect= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout=1;
        +		else if (strcmp(*argv,"-pubkey") == 0)
        +			pubkey=1;
        +		else if (strcmp(*argv,"-verify") == 0)
        +			verify=1;
        +		else badops = 1;
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		BIO_printf(bio_err,"%s [options]\n",prog);
        +		BIO_printf(bio_err,"where options are\n");
        +		BIO_printf(bio_err," -in arg        input file\n");
        +		BIO_printf(bio_err," -out arg       output file\n");
        +		BIO_printf(bio_err," -key arg       create SPKAC using private key\n");
        +		BIO_printf(bio_err," -passin arg    input file pass phrase source\n");
        +		BIO_printf(bio_err," -challenge arg challenge string\n");
        +		BIO_printf(bio_err," -spkac arg     alternative SPKAC name\n");
        +		BIO_printf(bio_err," -noout         don't print SPKAC\n");
        +		BIO_printf(bio_err," -pubkey        output public key\n");
        +		BIO_printf(bio_err," -verify        verify SPKAC signature\n");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," -engine e      use engine e, possibly a hardware device.\n");
        +#endif
        +		goto end;
        +		}
        +
        +	ERR_load_crypto_strings();
        +	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +	}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if(keyfile) {
        +		pkey = load_key(bio_err,
        +				strcmp(keyfile, "-") ? keyfile : NULL,
        +				FORMAT_PEM, 1, passin, e, "private key");
        +		if(!pkey) {
        +			goto end;
        +		}
        +		spki = NETSCAPE_SPKI_new();
        +		if(challenge) ASN1_STRING_set(spki->spkac->challenge,
        +						 challenge, (int)strlen(challenge));
        +		NETSCAPE_SPKI_set_pubkey(spki, pkey);
        +		NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
        +		spkstr = NETSCAPE_SPKI_b64_encode(spki);
        +
        +		if (outfile) out = BIO_new_file(outfile, "w");
        +		else {
        +			out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			    out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +		}
        +
        +		if(!out) {
        +			BIO_printf(bio_err, "Error opening output file\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +		BIO_printf(out, "SPKAC=%s\n", spkstr);
        +		OPENSSL_free(spkstr);
        +		ret = 0;
        +		goto end;
        +	}
        +
        +	
        +
        +	if (infile) in = BIO_new_file(infile, "r");
        +	else in = BIO_new_fp(stdin, BIO_NOCLOSE);
        +
        +	if(!in) {
        +		BIO_printf(bio_err, "Error opening input file\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +
        +	conf = NCONF_new(NULL);
        +	i = NCONF_load_bio(conf, in, NULL);
        +
        +	if(!i) {
        +		BIO_printf(bio_err, "Error parsing config file\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +
        +	spkstr = NCONF_get_string(conf, spksect, spkac);
        +		
        +	if(!spkstr) {
        +		BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +
        +	spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
        +	
        +	if(!spki) {
        +		BIO_printf(bio_err, "Error loading SPKAC\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +
        +	if (outfile) out = BIO_new_file(outfile, "w");
        +	else {
        +		out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +		{
        +		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +		    out = BIO_push(tmpbio, out);
        +		}
        +#endif
        +	}
        +
        +	if(!out) {
        +		BIO_printf(bio_err, "Error opening output file\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +	}
        +
        +	if(!noout) NETSCAPE_SPKI_print(out, spki);
        +	pkey = NETSCAPE_SPKI_get_pubkey(spki);
        +	if(verify) {
        +		i = NETSCAPE_SPKI_verify(spki, pkey);
        +		if (i > 0) BIO_printf(bio_err, "Signature OK\n");
        +		else {
        +			BIO_printf(bio_err, "Signature Failure\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +	}
        +	if(pubkey) PEM_write_bio_PUBKEY(out, pkey);
        +
        +	ret = 0;
        +
        +end:
        +	NCONF_free(conf);
        +	NETSCAPE_SPKI_free(spki);
        +	BIO_free(in);
        +	BIO_free_all(out);
        +	EVP_PKEY_free(pkey);
        +	if(passin) OPENSSL_free(passin);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        diff --git a/vendor/openssl/openssl/apps/srp.c b/vendor/openssl/openssl/apps/srp.c
        new file mode 100644
        index 000000000..9c7ae184d
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/srp.c
        @@ -0,0 +1,756 @@
        +/* apps/srp.c */
        +/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)  
        + * for the EdelKey project and contributed to the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 <openssl/opensslconf.h>
        +
        +#ifndef OPENSSL_NO_SRP
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/conf.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/txt_db.h>
        +#include <openssl/buffer.h>
        +#include <openssl/srp.h>
        +
        +#include "apps.h"
        +
        +#undef PROG
        +#define PROG srp_main
        +
        +#define BASE_SECTION	"srp"
        +#define CONFIG_FILE "openssl.cnf"
        +
        +#define ENV_RANDFILE		"RANDFILE"
        +
        +#define ENV_DATABASE		"srpvfile"
        +#define ENV_DEFAULT_SRP		"default_srp"
        +
        +static char *srp_usage[]={
        +"usage: srp [args] [user] \n",
        +"\n",
        +" -verbose        Talk alot while doing things\n",
        +" -config file    A config file\n",
        +" -name arg       The particular srp definition to use\n",
        +" -srpvfile arg   The srp verifier file name\n",
        +" -add            add an user and srp verifier\n",
        +" -modify         modify the srp verifier of an existing user\n",
        +" -delete         delete user from verifier file\n",
        +" -list           list user\n",
        +" -gn arg         g and N values to be used for new verifier\n",
        +" -userinfo arg   additional info to be set for user\n",
        +" -passin arg     input file pass phrase source\n",
        +" -passout arg    output file pass phrase source\n",
        +#ifndef OPENSSL_NO_ENGINE
        +" -engine e         - use engine e, possibly a hardware device.\n",
        +#endif
        +NULL
        +};
        +
        +#ifdef EFENCE
        +extern int EF_PROTECT_FREE;
        +extern int EF_PROTECT_BELOW;
        +extern int EF_ALIGNMENT;
        +#endif
        +
        +static CONF *conf=NULL;
        +static char *section=NULL;
        +
        +#define VERBOSE if (verbose) 
        +#define VVERBOSE if (verbose>1) 
        +
        +
        +int MAIN(int, char **);
        +
        +static int get_index(CA_DB *db, char* id, char type)
        +	{
        +	char ** pp;
        +	int i;
        +	if (id == NULL) return -1;
        +	if (type == DB_SRP_INDEX) 
        +	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +		{
        +		pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
        +		if (pp[DB_srptype][0] == DB_SRP_INDEX  && !strcmp(id,pp[DB_srpid])) 
        +			return i;
        +		}
        +	else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +		{
        +		pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
        +
        +		if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) 
        +			return i;
        +		}
        +
        +	return -1 ; 
        +	}
        +
        +static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s)
        +	{
        +	if (indx >= 0 && verbose)
        +		{
        +		int j;
        +		char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx);
        +		BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]);
        +		for (j = 0; j < DB_NUMBER; j++)
        +			{
        +			BIO_printf(bio_err,"  %d = \"%s\"\n", j, pp[j]);
        +			}
        +		}
        +	}
        +
        +static void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose)
        +	{
        +	print_entry(db, bio, indexindex, verbose, "g N entry") ;
        +	}
        +
        +static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose)
        +	{
        +	if (verbose > 0)
        +		{
        +		char **pp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
        +
        +		if (pp[DB_srptype][0] != 'I')
        +			{
        +			print_entry(db, bio, userindex, verbose, "User entry");
        +			print_entry(db, bio, get_index(db, pp[DB_srpgN], 'I'), verbose, "g N entry");
        +			}
        +
        +		}
        +	}
        +
        +static int update_index(CA_DB *db, BIO *bio, char **row)
        +	{
        +	char ** irow;
        +	int i;
        +
        +	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
        +		{
        +		BIO_printf(bio_err,"Memory allocation failure\n");
        +		return 0;
        +		}
        +
        +	for (i=0; i<DB_NUMBER; i++)
        +		{
        +		irow[i]=row[i];
        +		row[i]=NULL;
        +		}
        +	irow[DB_NUMBER]=NULL;
        +
        +	if (!TXT_DB_insert(db->db,irow))
        +		{
        +		BIO_printf(bio,"failed to update srpvfile\n");
        +		BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error);
        +		OPENSSL_free(irow);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +static void lookup_fail(const char *name, char *tag)
        +	{
        +	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
        +	}
        +
        +
        +static char *srp_verify_user(const char *user, const char *srp_verifier,
        +			     char *srp_usersalt, const char *g, const char *N,
        +			     const char *passin, BIO *bio, int verbose)
        +	{
        +	char password[1024];
        +	PW_CB_DATA cb_tmp;
        +	char *verifier = NULL;
        +	char *gNid = NULL;
        +
        +	cb_tmp.prompt_info = user;
        +	cb_tmp.password = passin;
        +
        + 	if (password_callback(password, 1024, 0, &cb_tmp) >0)
        +		{
        +		VERBOSE BIO_printf(bio,"Validating\n   user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,srp_verifier,srp_usersalt, g, N);
        +		BIO_printf(bio, "Pass %s\n", password);
        +
        +		if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, g)))
        +			{
        +			BIO_printf(bio, "Internal error validating SRP verifier\n");
        +			}
        +		else
        +			{
        +			if (strcmp(verifier, srp_verifier))
        +				gNid = NULL;
        +			OPENSSL_free(verifier);
        +			}
        +		}
        +	return gNid;
        +	}
        +
        +static char *srp_create_user(char *user, char **srp_verifier,
        +			     char **srp_usersalt, char *g, char *N,
        +			     char *passout, BIO *bio, int verbose)
        +	{
        + 	char password[1024];
        +        PW_CB_DATA cb_tmp;
        +	char *gNid = NULL;
        +	char *salt = NULL;
        +        cb_tmp.prompt_info = user;
        +        cb_tmp.password = passout;
        +
        +	if (password_callback(password,1024,1,&cb_tmp) >0)
        +		{
        +		VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N);
        +		if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g)))
        +			{
        +			BIO_printf(bio,"Internal error creating SRP verifier\n");
        +			}
        +		else 
        +			*srp_usersalt = salt;
        +		VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier);
        +
        +		}
        +	return gNid;
        +	}
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int add_user = 0;
        +	int list_user= 0;
        +	int delete_user= 0;
        +	int modify_user= 0;
        +	char * user = NULL;
        +
        +	char *passargin = NULL, *passargout = NULL;
        +	char *passin = NULL, *passout = NULL;
        +        char * gN = NULL;
        +	int gNindex = -1;
        +	char ** gNrow = NULL;
        +	int maxgN = -1;
        +
        +	char * userinfo = NULL;
        +
        +	int badops=0;
        +	int ret=1;
        +	int errors=0;
        +	int verbose=0;
        +	int doupdatedb=0;
        +	char *configfile=NULL;
        +	char *dbfile=NULL;
        +	CA_DB *db=NULL;
        +	char **pp ;
        +	int i;
        +	long errorline = -1;
        +	char *randfile=NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine = NULL;
        +#endif
        +	char *tofree=NULL;
        +	DB_ATTR db_attr;
        +
        +#ifdef EFENCE
        +EF_PROTECT_FREE=1;
        +EF_PROTECT_BELOW=1;
        +EF_ALIGNMENT=0;
        +#endif
        +
        +	apps_startup();
        +
        +	conf = NULL;
        +	section = NULL;
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1 && badops == 0)
        +		{
        +		if	(strcmp(*argv,"-verbose") == 0)
        +			verbose++;
        +		else if	(strcmp(*argv,"-config") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			configfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-name") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			section= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-srpvfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			dbfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-add") == 0)
        +			add_user=1;
        +		else if (strcmp(*argv,"-delete") == 0)
        +			delete_user=1;
        +		else if (strcmp(*argv,"-modify") == 0)
        +			modify_user=1;
        +		else if (strcmp(*argv,"-list") == 0)
        +			list_user=1;
        +		else if (strcmp(*argv,"-gn") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			gN= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-userinfo") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			userinfo= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-passout") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargout= *(++argv);
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +
        +		else if (**argv == '-')
        +			{
        +bad:
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		else 
        +			break;
        +	
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (dbfile && configfile)
        +		{
        +		BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n");
        +		badops = 1;
        +		}
        +	if (add_user+delete_user+modify_user+list_user != 1)
        +		{
        +		BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n");
        +		badops = 1;
        +		}
        +	if (delete_user+modify_user+delete_user== 1 && argc <= 0)
        +		{
        +		BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n");
        +		badops = 1;
        +		}
        +	if ((passin || passout) && argc != 1 )
        +		{
        +		BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n");
        +		badops = 1;
        +		}
        +
        +	if (badops)
        +		{
        +		for (pp=srp_usage; (*pp != NULL); pp++)
        +			BIO_printf(bio_err,"%s",*pp);
        +
        +		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +		BIO_printf(bio_err,"                 load the file (or the files in the directory) into\n");
        +		BIO_printf(bio_err,"                 the random number generator\n");
        +		goto err;
        +		}
        +
        +	ERR_load_crypto_strings();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
        +		{
        +		BIO_printf(bio_err, "Error getting passwords\n");
        +		goto err;
        +		}
        +
        +        if (!dbfile)
        +		{
        +
        +
        +	/*****************************************************************/
        +		tofree=NULL;
        +		if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
        +		if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
        +		if (configfile == NULL)
        +			{
        +			const char *s=X509_get_default_cert_area();
        +			size_t len;
        +
        +#ifdef OPENSSL_SYS_VMS
        +			len = strlen(s)+sizeof(CONFIG_FILE);
        +			tofree=OPENSSL_malloc(len);
        +			strcpy(tofree,s);
        +#else
        +			len = strlen(s)+sizeof(CONFIG_FILE)+1;
        +			tofree=OPENSSL_malloc(len);
        +			BUF_strlcpy(tofree,s,len);
        +			BUF_strlcat(tofree,"/",len);
        +#endif
        +			BUF_strlcat(tofree,CONFIG_FILE,len);
        +			configfile=tofree;
        +			}
        +
        +		VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile);
        +		conf = NCONF_new(NULL);
        +		if (NCONF_load(conf,configfile,&errorline) <= 0)
        +			{
        +			if (errorline <= 0)
        +				BIO_printf(bio_err,"error loading the config file '%s'\n",
        +					configfile);
        +			else
        +				BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
        +					,errorline,configfile);
        +			goto err;
        +			}
        +		if(tofree)
        +			{
        +			OPENSSL_free(tofree);
        +			tofree = NULL;
        +			}
        +
        +		if (!load_config(bio_err, conf))
        +			goto err;
        +
        +	/* Lets get the config section we are using */
        +		if (section == NULL)
        +			{
        +			VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n");
        +
        +			section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP);
        +			if (section == NULL)
        +				{
        +				lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP);
        +				goto err;
        +				}
        +			}
        +         
        +		if (randfile == NULL && conf)
        +	        	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
        +
        +	
        +		VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section);
        +
        +		if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
        +			{
        +			lookup_fail(section,ENV_DATABASE);
        +			goto err;
        +			}
        +
        +        	}
        +	if (randfile == NULL)
        +		ERR_clear_error();
        +       	else 
        +		app_RAND_load_file(randfile, bio_err, 0);
        +
        +	VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile);
        +
        +	db = load_index(dbfile, &db_attr);
        +	if (db == NULL) goto err;
        +
        +	/* Lets check some fields */
        +	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +		{
        +		pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
        +	
        +		if (pp[DB_srptype][0] == DB_SRP_INDEX)
        +			{
        +			maxgN = i;
        +			if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
        +				gNindex = i;
        +
        +			print_index(db, bio_err, i, verbose > 1);
        +			}
        +		}
        +	
        +	VERBOSE BIO_printf(bio_err, "Database initialised\n");
        +
        +	if (gNindex >= 0)
        +		{
        +		gNrow = sk_OPENSSL_PSTRING_value(db->db->data,gNindex);
        +		print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N");
        +		}
        +	else if (maxgN > 0 && !SRP_get_default_gN(gN))
        +		{
        +		BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
        +		goto err;
        +		}
        +	else
        +		{
        +		VERBOSE BIO_printf(bio_err, "Database has no g N information.\n");
        +		gNrow = NULL;
        +		}
        +	
        +
        +	VVERBOSE BIO_printf(bio_err,"Starting user processing\n");
        +
        +	if (argc > 0)
        +		user = *(argv++) ;
        +
        +	while (list_user || user)
        +		{
        +		int userindex = -1;
        +		if (user) 
        +			VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user);
        +		if ((userindex = get_index(db, user, 'U')) >= 0)
        +			{
        +			print_user(db, bio_err, userindex, (verbose > 0) || list_user);
        +			}
        +		
        +		if (list_user)
        +			{
        +			if (user == NULL)
        +				{
        +				BIO_printf(bio_err,"List all users\n");
        +
        +				for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +					{
        +					print_user(db,bio_err, i, 1);
        +					}
        +				list_user = 0;
        +				}
        +			else if (userindex < 0)
        +				{
        +				BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n",
        +					   user);
        +				errors++;
        +				}
        +			}
        +		else if (add_user)
        +			{
        +			if (userindex >= 0)
        +				{
        +				/* reactivation of a new user */
        +				char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
        +				BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
        +				row[DB_srptype][0] = 'V';
        +
        +				doupdatedb = 1;
        +				}
        +			else
        +				{
        +				char *row[DB_NUMBER] ; char *gNid;
        +				row[DB_srpverifier] = NULL;
        +				row[DB_srpsalt] = NULL;
        +				row[DB_srpinfo] = NULL;
        +				if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
        +					{
        +						BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user);
        +						errors++;
        +						goto err;
        +					}
        +				row[DB_srpid] = BUF_strdup(user);
        +				row[DB_srptype] = BUF_strdup("v");
        +				row[DB_srpgN] = BUF_strdup(gNid);
        +
        +				if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
        +					(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) || 
        +					!update_index(db, bio_err, row))
        +					{
        +					if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]);
        +					if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]);
        +					if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]);
        +					if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]);
        +					if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]);
        +					if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]);
        +					goto err;
        +					}
        +				doupdatedb = 1;
        +				}
        +			}
        +		else if (modify_user)
        +			{
        +			if (userindex < 0)
        +				{
        +				BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user);
        +				errors++;
        +				}
        +			else
        +				{
        +
        +				char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
        +				char type = row[DB_srptype][0];
        +				if (type == 'v')
        +					{
        +					BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user);
        +					errors++;
        +					}
        +				else
        +					{
        +					char *gNid;
        +
        +					if (row[DB_srptype][0] == 'V')
        +						{
        +						int user_gN;
        +						char **irow = NULL;
        +						VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user);
        +						if ( (user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
        +							irow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
        +
        + 						if (!srp_verify_user(user, row[DB_srpverifier], row[DB_srpsalt], irow ? irow[DB_srpsalt] : row[DB_srpgN], irow ? irow[DB_srpverifier] : NULL, passin, bio_err, verbose))
        +							{
        +							BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user);
        +							errors++;
        +							goto err;
        +							}
        +						} 
        +					VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user);
        +
        +					if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
        +						{
        +						BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user);
        +						errors++;
        +						goto err;
        +						}
        +
        +					row[DB_srptype][0] = 'v';
        +					row[DB_srpgN] = BUF_strdup(gNid);
        + 
        +					if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
        +						(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))  
        +						goto err;
        +
        +					doupdatedb = 1;
        +					}
        +				}
        +			}
        +		else if (delete_user)
        +			{
        +			if (userindex < 0)
        +				{
        +				BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user);
        +				errors++;
        +				}
        +			else
        +				{
        +				char **xpp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
        +				BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
        +
        +				xpp[DB_srptype][0] = 'R';
        +				
        +				doupdatedb = 1;
        +				}
        +			}
        +		if (--argc > 0)
        +			user = *(argv++) ;
        +		else
        +			{
        +			user = NULL;
        +			list_user = 0;
        +			}
        +		}
        +
        +	VERBOSE BIO_printf(bio_err,"User procession done.\n");
        +
        +
        +	if (doupdatedb)
        +		{
        +		/* Lets check some fields */
        +		for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
        +			{
        +			pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
        +	
        +			if (pp[DB_srptype][0] == 'v')
        +				{
        +				pp[DB_srptype][0] = 'V';
        +				print_user(db, bio_err, i, verbose);
        +				}
        +			}
        +
        +		VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n");
        +		if (!save_index(dbfile, "new", db)) goto err;
        +				
        +		VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n");
        +		if (!rotate_index(dbfile, "new", "old")) goto err;
        +
        +		VERBOSE BIO_printf(bio_err, "srpvfile updated.\n");
        +		}
        +
        +	ret = (errors != 0);
        +err:
        +	if (errors != 0)
        +	VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors);
        +
        +	VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret);
        +	if(tofree)
        +		OPENSSL_free(tofree);
        +	if (ret) ERR_print_errors(bio_err);
        +	if (randfile) app_RAND_write_file(randfile, bio_err);
        +	if (conf) NCONF_free(conf);
        +	if (db) free_index(db);
        +
        +	OBJ_cleanup();
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/apps/testCA.pem b/vendor/openssl/openssl/apps/testCA.pem
        new file mode 100644
        index 000000000..dcb710aa9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/testCA.pem
        @@ -0,0 +1,8 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBBzCBsgIBADBNMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEX
        +MBUGA1UEChMOTWluY29tIFB0eSBMdGQxEDAOBgNVBAMTB1RFU1QgQ0EwXDANBgkq
        +hkiG9w0BAQEFAANLADBIAkEAzW9brgA8efT2ODB+NrsflJZj3KKqKsm4OrXTRqfL
        +VETj1ws/zCXl42XJAxdWQMCP0liKfc9Ut4xi1qCVI7N07wIDAQABoAAwDQYJKoZI
        +hvcNAQEEBQADQQBjZZ42Det9Uw0AFwJy4ufUEy5Cv74pxBp5SZnljgHY+Az0Hs2S
        +uNkIegr2ITX5azKi9nOkg9ZmsmGG13FIjiC/
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/apps/testdsa.h b/vendor/openssl/openssl/apps/testdsa.h
        new file mode 100644
        index 000000000..9e84e31c9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/testdsa.h
        @@ -0,0 +1,217 @@
        +/* NOCW */
        +/* used by apps/speed.c */
        +DSA *get_dsa512(void );
        +DSA *get_dsa1024(void );
        +DSA *get_dsa2048(void );
        +static unsigned char dsa512_priv[] = {
        +	0x65,0xe5,0xc7,0x38,0x60,0x24,0xb5,0x89,0xd4,0x9c,0xeb,0x4c,
        +	0x9c,0x1d,0x7a,0x22,0xbd,0xd1,0xc2,0xd2,
        +	};
        +static unsigned char dsa512_pub[] = {
        +	0x00,0x95,0xa7,0x0d,0xec,0x93,0x68,0xba,0x5f,0xf7,0x5f,0x07,
        +	0xf2,0x3b,0xad,0x6b,0x01,0xdc,0xbe,0xec,0xde,0x04,0x7a,0x3a,
        +	0x27,0xb3,0xec,0x49,0xfd,0x08,0x43,0x3d,0x7e,0xa8,0x2c,0x5e,
        +	0x7b,0xbb,0xfc,0xf4,0x6e,0xeb,0x6c,0xb0,0x6e,0xf8,0x02,0x12,
        +	0x8c,0x38,0x5d,0x83,0x56,0x7d,0xee,0x53,0x05,0x3e,0x24,0x84,
        +	0xbe,0xba,0x0a,0x6b,0xc8,
        +	};
        +static unsigned char dsa512_p[]={
        +	0x9D,0x1B,0x69,0x8E,0x26,0xDB,0xF2,0x2B,0x11,0x70,0x19,0x86,
        +	0xF6,0x19,0xC8,0xF8,0x19,0xF2,0x18,0x53,0x94,0x46,0x06,0xD0,
        +	0x62,0x50,0x33,0x4B,0x02,0x3C,0x52,0x30,0x03,0x8B,0x3B,0xF9,
        +	0x5F,0xD1,0x24,0x06,0x4F,0x7B,0x4C,0xBA,0xAA,0x40,0x9B,0xFD,
        +	0x96,0xE4,0x37,0x33,0xBB,0x2D,0x5A,0xD7,0x5A,0x11,0x40,0x66,
        +	0xA2,0x76,0x7D,0x31,
        +	};
        +static unsigned char dsa512_q[]={
        +	0xFB,0x53,0xEF,0x50,0xB4,0x40,0x92,0x31,0x56,0x86,0x53,0x7A,
        +	0xE8,0x8B,0x22,0x9A,0x49,0xFB,0x71,0x8F,
        +	};
        +static unsigned char dsa512_g[]={
        +	0x83,0x3E,0x88,0xE5,0xC5,0x89,0x73,0xCE,0x3B,0x6C,0x01,0x49,
        +	0xBF,0xB3,0xC7,0x9F,0x0A,0xEA,0x44,0x91,0xE5,0x30,0xAA,0xD9,
        +	0xBE,0x5B,0x5F,0xB7,0x10,0xD7,0x89,0xB7,0x8E,0x74,0xFB,0xCF,
        +	0x29,0x1E,0xEB,0xA8,0x2C,0x54,0x51,0xB8,0x10,0xDE,0xA0,0xCE,
        +	0x2F,0xCC,0x24,0x6B,0x90,0x77,0xDE,0xA2,0x68,0xA6,0x52,0x12,
        +	0xA2,0x03,0x9D,0x20,
        +	};
        +
        +DSA *get_dsa512()
        +	{
        +	DSA *dsa;
        +
        +	if ((dsa=DSA_new()) == NULL) return(NULL);
        +	dsa->priv_key=BN_bin2bn(dsa512_priv,sizeof(dsa512_priv),NULL);
        +	dsa->pub_key=BN_bin2bn(dsa512_pub,sizeof(dsa512_pub),NULL);
        +	dsa->p=BN_bin2bn(dsa512_p,sizeof(dsa512_p),NULL);
        +	dsa->q=BN_bin2bn(dsa512_q,sizeof(dsa512_q),NULL);
        +	dsa->g=BN_bin2bn(dsa512_g,sizeof(dsa512_g),NULL);
        +	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
        +				(dsa->q == NULL) || (dsa->g == NULL))
        +		return(NULL);
        +	return(dsa);
        +	}
        +
        +static unsigned char dsa1024_priv[]={
        +	0x7d,0x21,0xda,0xbb,0x62,0x15,0x47,0x36,0x07,0x67,0x12,0xe8,
        +	0x8c,0xaa,0x1c,0xcd,0x38,0x12,0x61,0x18,
        +	};
        +static unsigned char dsa1024_pub[]={
        +	0x3c,0x4e,0x9c,0x2a,0x7f,0x16,0xc1,0x25,0xeb,0xac,0x78,0x63,
        +	0x90,0x14,0x8c,0x8b,0xf4,0x68,0x43,0x3c,0x2d,0xee,0x65,0x50,
        +	0x7d,0x9c,0x8f,0x8c,0x8a,0x51,0xd6,0x11,0x2b,0x99,0xaf,0x1e,
        +	0x90,0x97,0xb5,0xd3,0xa6,0x20,0x25,0xd6,0xfe,0x43,0x02,0xd5,
        +	0x91,0x7d,0xa7,0x8c,0xdb,0xc9,0x85,0xa3,0x36,0x48,0xf7,0x68,
        +	0xaa,0x60,0xb1,0xf7,0x05,0x68,0x3a,0xa3,0x3f,0xd3,0x19,0x82,
        +	0xd8,0x82,0x7a,0x77,0xfb,0xef,0xf4,0x15,0x0a,0xeb,0x06,0x04,
        +	0x7f,0x53,0x07,0x0c,0xbc,0xcb,0x2d,0x83,0xdb,0x3e,0xd1,0x28,
        +	0xa5,0xa1,0x31,0xe0,0x67,0xfa,0x50,0xde,0x9b,0x07,0x83,0x7e,
        +	0x2c,0x0b,0xc3,0x13,0x50,0x61,0xe5,0xad,0xbd,0x36,0xb8,0x97,
        +	0x4e,0x40,0x7d,0xe8,0x83,0x0d,0xbc,0x4b
        +	};
        +static unsigned char dsa1024_p[]={
        +	0xA7,0x3F,0x6E,0x85,0xBF,0x41,0x6A,0x29,0x7D,0xF0,0x9F,0x47,
        +	0x19,0x30,0x90,0x9A,0x09,0x1D,0xDA,0x6A,0x33,0x1E,0xC5,0x3D,
        +	0x86,0x96,0xB3,0x15,0xE0,0x53,0x2E,0x8F,0xE0,0x59,0x82,0x73,
        +	0x90,0x3E,0x75,0x31,0x99,0x47,0x7A,0x52,0xFB,0x85,0xE4,0xD9,
        +	0xA6,0x7B,0x38,0x9B,0x68,0x8A,0x84,0x9B,0x87,0xC6,0x1E,0xB5,
        +	0x7E,0x86,0x4B,0x53,0x5B,0x59,0xCF,0x71,0x65,0x19,0x88,0x6E,
        +	0xCE,0x66,0xAE,0x6B,0x88,0x36,0xFB,0xEC,0x28,0xDC,0xC2,0xD7,
        +	0xA5,0xBB,0xE5,0x2C,0x39,0x26,0x4B,0xDA,0x9A,0x70,0x18,0x95,
        +	0x37,0x95,0x10,0x56,0x23,0xF6,0x15,0xED,0xBA,0x04,0x5E,0xDE,
        +	0x39,0x4F,0xFD,0xB7,0x43,0x1F,0xB5,0xA4,0x65,0x6F,0xCD,0x80,
        +	0x11,0xE4,0x70,0x95,0x5B,0x50,0xCD,0x49,
        +	};
        +static unsigned char dsa1024_q[]={
        +	0xF7,0x07,0x31,0xED,0xFA,0x6C,0x06,0x03,0xD5,0x85,0x8A,0x1C,
        +	0xAC,0x9C,0x65,0xE7,0x50,0x66,0x65,0x6F,
        +	};
        +static unsigned char dsa1024_g[]={
        +	0x4D,0xDF,0x4C,0x03,0xA6,0x91,0x8A,0xF5,0x19,0x6F,0x50,0x46,
        +	0x25,0x99,0xE5,0x68,0x6F,0x30,0xE3,0x69,0xE1,0xE5,0xB3,0x5D,
        +	0x98,0xBB,0x28,0x86,0x48,0xFC,0xDE,0x99,0x04,0x3F,0x5F,0x88,
        +	0x0C,0x9C,0x73,0x24,0x0D,0x20,0x5D,0xB9,0x2A,0x9A,0x3F,0x18,
        +	0x96,0x27,0xE4,0x62,0x87,0xC1,0x7B,0x74,0x62,0x53,0xFC,0x61,
        +	0x27,0xA8,0x7A,0x91,0x09,0x9D,0xB6,0xF1,0x4D,0x9C,0x54,0x0F,
        +	0x58,0x06,0xEE,0x49,0x74,0x07,0xCE,0x55,0x7E,0x23,0xCE,0x16,
        +	0xF6,0xCA,0xDC,0x5A,0x61,0x01,0x7E,0xC9,0x71,0xB5,0x4D,0xF6,
        +	0xDC,0x34,0x29,0x87,0x68,0xF6,0x5E,0x20,0x93,0xB3,0xDB,0xF5,
        +	0xE4,0x09,0x6C,0x41,0x17,0x95,0x92,0xEB,0x01,0xB5,0x73,0xA5,
        +	0x6A,0x7E,0xD8,0x32,0xED,0x0E,0x02,0xB8,
        +	};
        +
        +DSA *get_dsa1024()
        +	{
        +	DSA *dsa;
        +
        +	if ((dsa=DSA_new()) == NULL) return(NULL);
        +	dsa->priv_key=BN_bin2bn(dsa1024_priv,sizeof(dsa1024_priv),NULL);
        +	dsa->pub_key=BN_bin2bn(dsa1024_pub,sizeof(dsa1024_pub),NULL);
        +	dsa->p=BN_bin2bn(dsa1024_p,sizeof(dsa1024_p),NULL);
        +	dsa->q=BN_bin2bn(dsa1024_q,sizeof(dsa1024_q),NULL);
        +	dsa->g=BN_bin2bn(dsa1024_g,sizeof(dsa1024_g),NULL);
        +	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
        +				(dsa->q == NULL) || (dsa->g == NULL))
        +		return(NULL);
        +	return(dsa);
        +	}
        +
        +static unsigned char dsa2048_priv[]={
        +	0x32,0x67,0x92,0xf6,0xc4,0xe2,0xe2,0xe8,0xa0,0x8b,0x6b,0x45,
        +	0x0c,0x8a,0x76,0xb0,0xee,0xcf,0x91,0xa7,
        +	};
        +static unsigned char dsa2048_pub[]={
        +	0x17,0x8f,0xa8,0x11,0x84,0x92,0xec,0x83,0x47,0xc7,0x6a,0xb0,
        +	0x92,0xaf,0x5a,0x20,0x37,0xa3,0x64,0x79,0xd2,0xd0,0x3d,0xcd,
        +	0xe0,0x61,0x88,0x88,0x21,0xcc,0x74,0x5d,0xce,0x4c,0x51,0x47,
        +	0xf0,0xc5,0x5c,0x4c,0x82,0x7a,0xaf,0x72,0xad,0xb9,0xe0,0x53,
        +	0xf2,0x78,0xb7,0xf0,0xb5,0x48,0x7f,0x8a,0x3a,0x18,0xd1,0x9f,
        +	0x8b,0x7d,0xa5,0x47,0xb7,0x95,0xab,0x98,0xf8,0x7b,0x74,0x50,
        +	0x56,0x8e,0x57,0xf0,0xee,0xf5,0xb7,0xba,0xab,0x85,0x86,0xf9,
        +	0x2b,0xef,0x41,0x56,0xa0,0xa4,0x9f,0xb7,0x38,0x00,0x46,0x0a,
        +	0xa6,0xf1,0xfc,0x1f,0xd8,0x4e,0x85,0x44,0x92,0x43,0x21,0x5d,
        +	0x6e,0xcc,0xc2,0xcb,0x26,0x31,0x0d,0x21,0xc4,0xbd,0x8d,0x24,
        +	0xbc,0xd9,0x18,0x19,0xd7,0xdc,0xf1,0xe7,0x93,0x50,0x48,0x03,
        +	0x2c,0xae,0x2e,0xe7,0x49,0x88,0x5f,0x93,0x57,0x27,0x99,0x36,
        +	0xb4,0x20,0xab,0xfc,0xa7,0x2b,0xf2,0xd9,0x98,0xd7,0xd4,0x34,
        +	0x9d,0x96,0x50,0x58,0x9a,0xea,0x54,0xf3,0xee,0xf5,0x63,0x14,
        +	0xee,0x85,0x83,0x74,0x76,0xe1,0x52,0x95,0xc3,0xf7,0xeb,0x04,
        +	0x04,0x7b,0xa7,0x28,0x1b,0xcc,0xea,0x4a,0x4e,0x84,0xda,0xd8,
        +	0x9c,0x79,0xd8,0x9b,0x66,0x89,0x2f,0xcf,0xac,0xd7,0x79,0xf9,
        +	0xa9,0xd8,0x45,0x13,0x78,0xb9,0x00,0x14,0xc9,0x7e,0x22,0x51,
        +	0x86,0x67,0xb0,0x9f,0x26,0x11,0x23,0xc8,0x38,0xd7,0x70,0x1d,
        +	0x15,0x8e,0x4d,0x4f,0x95,0x97,0x40,0xa1,0xc2,0x7e,0x01,0x18,
        +	0x72,0xf4,0x10,0xe6,0x8d,0x52,0x16,0x7f,0xf2,0xc9,0xf8,0x33,
        +	0x8b,0x33,0xb7,0xce,
        +	};
        +static unsigned char dsa2048_p[]={
        +	0xA0,0x25,0xFA,0xAD,0xF4,0x8E,0xB9,0xE5,0x99,0xF3,0x5D,0x6F,
        +	0x4F,0x83,0x34,0xE2,0x7E,0xCF,0x6F,0xBF,0x30,0xAF,0x6F,0x81,
        +	0xEB,0xF8,0xC4,0x13,0xD9,0xA0,0x5D,0x8B,0x5C,0x8E,0xDC,0xC2,
        +	0x1D,0x0B,0x41,0x32,0xB0,0x1F,0xFE,0xEF,0x0C,0xC2,0xA2,0x7E,
        +	0x68,0x5C,0x28,0x21,0xE9,0xF5,0xB1,0x58,0x12,0x63,0x4C,0x19,
        +	0x4E,0xFF,0x02,0x4B,0x92,0xED,0xD2,0x07,0x11,0x4D,0x8C,0x58,
        +	0x16,0x5C,0x55,0x8E,0xAD,0xA3,0x67,0x7D,0xB9,0x86,0x6E,0x0B,
        +	0xE6,0x54,0x6F,0x40,0xAE,0x0E,0x67,0x4C,0xF9,0x12,0x5B,0x3C,
        +	0x08,0x7A,0xF7,0xFC,0x67,0x86,0x69,0xE7,0x0A,0x94,0x40,0xBF,
        +	0x8B,0x76,0xFE,0x26,0xD1,0xF2,0xA1,0x1A,0x84,0xA1,0x43,0x56,
        +	0x28,0xBC,0x9A,0x5F,0xD7,0x3B,0x69,0x89,0x8A,0x36,0x2C,0x51,
        +	0xDF,0x12,0x77,0x2F,0x57,0x7B,0xA0,0xAA,0xDD,0x7F,0xA1,0x62,
        +	0x3B,0x40,0x7B,0x68,0x1A,0x8F,0x0D,0x38,0xBB,0x21,0x5D,0x18,
        +	0xFC,0x0F,0x46,0xF7,0xA3,0xB0,0x1D,0x23,0xC3,0xD2,0xC7,0x72,
        +	0x51,0x18,0xDF,0x46,0x95,0x79,0xD9,0xBD,0xB5,0x19,0x02,0x2C,
        +	0x87,0xDC,0xE7,0x57,0x82,0x7E,0xF1,0x8B,0x06,0x3D,0x00,0xA5,
        +	0x7B,0x6B,0x26,0x27,0x91,0x0F,0x6A,0x77,0xE4,0xD5,0x04,0xE4,
        +	0x12,0x2C,0x42,0xFF,0xD2,0x88,0xBB,0xD3,0x92,0xA0,0xF9,0xC8,
        +	0x51,0x64,0x14,0x5C,0xD8,0xF9,0x6C,0x47,0x82,0xB4,0x1C,0x7F,
        +	0x09,0xB8,0xF0,0x25,0x83,0x1D,0x3F,0x3F,0x05,0xB3,0x21,0x0A,
        +	0x5D,0xA7,0xD8,0x54,0xC3,0x65,0x7D,0xC3,0xB0,0x1D,0xBF,0xAE,
        +	0xF8,0x68,0xCF,0x9B,
        +	};
        +static unsigned char dsa2048_q[]={
        +	0x97,0xE7,0x33,0x4D,0xD3,0x94,0x3E,0x0B,0xDB,0x62,0x74,0xC6,
        +	0xA1,0x08,0xDD,0x19,0xA3,0x75,0x17,0x1B,
        +	};
        +static unsigned char dsa2048_g[]={
        +	0x2C,0x78,0x16,0x59,0x34,0x63,0xF4,0xF3,0x92,0xFC,0xB5,0xA5,
        +	0x4F,0x13,0xDE,0x2F,0x1C,0xA4,0x3C,0xAE,0xAD,0x38,0x3F,0x7E,
        +	0x90,0xBF,0x96,0xA6,0xAE,0x25,0x90,0x72,0xF5,0x8E,0x80,0x0C,
        +	0x39,0x1C,0xD9,0xEC,0xBA,0x90,0x5B,0x3A,0xE8,0x58,0x6C,0x9E,
        +	0x30,0x42,0x37,0x02,0x31,0x82,0xBC,0x6A,0xDF,0x6A,0x09,0x29,
        +	0xE3,0xC0,0x46,0xD1,0xCB,0x85,0xEC,0x0C,0x30,0x5E,0xEA,0xC8,
        +	0x39,0x8E,0x22,0x9F,0x22,0x10,0xD2,0x34,0x61,0x68,0x37,0x3D,
        +	0x2E,0x4A,0x5B,0x9A,0xF5,0xC1,0x48,0xC6,0xF6,0xDC,0x63,0x1A,
        +	0xD3,0x96,0x64,0xBA,0x34,0xC9,0xD1,0xA0,0xD1,0xAE,0x6C,0x2F,
        +	0x48,0x17,0x93,0x14,0x43,0xED,0xF0,0x21,0x30,0x19,0xC3,0x1B,
        +	0x5F,0xDE,0xA3,0xF0,0x70,0x78,0x18,0xE1,0xA8,0xE4,0xEE,0x2E,
        +	0x00,0xA5,0xE4,0xB3,0x17,0xC8,0x0C,0x7D,0x6E,0x42,0xDC,0xB7,
        +	0x46,0x00,0x36,0x4D,0xD4,0x46,0xAA,0x3D,0x3C,0x46,0x89,0x40,
        +	0xBF,0x1D,0x84,0x77,0x0A,0x75,0xF3,0x87,0x1D,0x08,0x4C,0xA6,
        +	0xD1,0xA9,0x1C,0x1E,0x12,0x1E,0xE1,0xC7,0x30,0x28,0x76,0xA5,
        +	0x7F,0x6C,0x85,0x96,0x2B,0x6F,0xDB,0x80,0x66,0x26,0xAE,0xF5,
        +	0x93,0xC7,0x8E,0xAE,0x9A,0xED,0xE4,0xCA,0x04,0xEA,0x3B,0x72,
        +	0xEF,0xDC,0x87,0xED,0x0D,0xA5,0x4C,0x4A,0xDD,0x71,0x22,0x64,
        +	0x59,0x69,0x4E,0x8E,0xBF,0x43,0xDC,0xAB,0x8E,0x66,0xBB,0x01,
        +	0xB6,0xF4,0xE7,0xFD,0xD2,0xAD,0x9F,0x36,0xC1,0xA0,0x29,0x99,
        +	0xD1,0x96,0x70,0x59,0x06,0x78,0x35,0xBD,0x65,0x55,0x52,0x9E,
        +	0xF8,0xB2,0xE5,0x38,
        +	};
        + 
        +DSA *get_dsa2048()
        +	{
        +	DSA *dsa;
        + 
        +	if ((dsa=DSA_new()) == NULL) return(NULL);
        +	dsa->priv_key=BN_bin2bn(dsa2048_priv,sizeof(dsa2048_priv),NULL);
        +	dsa->pub_key=BN_bin2bn(dsa2048_pub,sizeof(dsa2048_pub),NULL);
        +	dsa->p=BN_bin2bn(dsa2048_p,sizeof(dsa2048_p),NULL);
        +	dsa->q=BN_bin2bn(dsa2048_q,sizeof(dsa2048_q),NULL);
        +	dsa->g=BN_bin2bn(dsa2048_g,sizeof(dsa2048_g),NULL);
        +	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) ||
        +				(dsa->q == NULL) || (dsa->g == NULL))
        +		return(NULL);
        +	return(dsa);
        +	}
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +static int rnd_fake = 0;
        diff --git a/vendor/openssl/openssl/apps/testrsa.h b/vendor/openssl/openssl/apps/testrsa.h
        new file mode 100644
        index 000000000..3007d792b
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/testrsa.h
        @@ -0,0 +1,518 @@
        +/* apps/testrsa.h */
        +/* used by apps/speed.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.]
        + */
        +
        +static unsigned char test512[]={
        +	0x30,0x82,0x01,0x3a,0x02,0x01,0x00,0x02,0x41,0x00,
        +	0xd6,0x33,0xb9,0xc8,0xfb,0x4f,0x3c,0x7d,0xc0,0x01,
        +	0x86,0xd0,0xe7,0xa0,0x55,0xf2,0x95,0x93,0xcc,0x4f,
        +	0xb7,0x5b,0x67,0x5b,0x94,0x68,0xc9,0x34,0x15,0xde,
        +	0xa5,0x2e,0x1c,0x33,0xc2,0x6e,0xfc,0x34,0x5e,0x71,
        +	0x13,0xb7,0xd6,0xee,0xd8,0xa5,0x65,0x05,0x72,0x87,
        +	0xa8,0xb0,0x77,0xfe,0x57,0xf5,0xfc,0x5f,0x55,0x83,
        +	0x87,0xdd,0x57,0x49,0x02,0x03,0x01,0x00,0x01,0x02,
        +	0x41,0x00,0xa7,0xf7,0x91,0xc5,0x0f,0x84,0x57,0xdc,
        +	0x07,0xf7,0x6a,0x7f,0x60,0x52,0xb3,0x72,0xf1,0x66,
        +	0x1f,0x7d,0x97,0x3b,0x9e,0xb6,0x0a,0x8f,0x8c,0xcf,
        +	0x42,0x23,0x00,0x04,0xd4,0x28,0x0e,0x1c,0x90,0xc4,
        +	0x11,0x25,0x25,0xa5,0x93,0xa5,0x2f,0x70,0x02,0xdf,
        +	0x81,0x9c,0x49,0x03,0xa0,0xf8,0x6d,0x54,0x2e,0x26,
        +	0xde,0xaa,0x85,0x59,0xa8,0x31,0x02,0x21,0x00,0xeb,
        +	0x47,0xd7,0x3b,0xf6,0xc3,0xdd,0x5a,0x46,0xc5,0xb9,
        +	0x2b,0x9a,0xa0,0x09,0x8f,0xa6,0xfb,0xf3,0x78,0x7a,
        +	0x33,0x70,0x9d,0x0f,0x42,0x6b,0x13,0x68,0x24,0xd3,
        +	0x15,0x02,0x21,0x00,0xe9,0x10,0xb0,0xb3,0x0d,0xe2,
        +	0x82,0x68,0x77,0x8a,0x6e,0x7c,0xda,0xbc,0x3e,0x53,
        +	0x83,0xfb,0xd6,0x22,0xe7,0xb5,0xae,0x6e,0x80,0xda,
        +	0x00,0x55,0x97,0xc1,0xd0,0x65,0x02,0x20,0x4c,0xf8,
        +	0x73,0xb1,0x6a,0x49,0x29,0x61,0x1f,0x46,0x10,0x0d,
        +	0xf3,0xc7,0xe7,0x58,0xd7,0x88,0x15,0x5e,0x94,0x9b,
        +	0xbf,0x7b,0xa2,0x42,0x58,0x45,0x41,0x0c,0xcb,0x01,
        +	0x02,0x20,0x12,0x11,0xba,0x31,0x57,0x9d,0x3d,0x11,
        +	0x0e,0x5b,0x8c,0x2f,0x5f,0xe2,0x02,0x4f,0x05,0x47,
        +	0x8c,0x15,0x8e,0xb3,0x56,0x3f,0xb8,0xfb,0xad,0xd4,
        +	0xf4,0xfc,0x10,0xc5,0x02,0x20,0x18,0xa1,0x29,0x99,
        +	0x5b,0xd9,0xc8,0xd4,0xfc,0x49,0x7a,0x2a,0x21,0x2c,
        +	0x49,0xe4,0x4f,0xeb,0xef,0x51,0xf1,0xab,0x6d,0xfb,
        +	0x4b,0x14,0xe9,0x4b,0x52,0xb5,0x82,0x2c,
        +	};
        +
        +static unsigned char test1024[]={
        +	0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,
        +	0x00,0xdc,0x98,0x43,0xe8,0x3d,0x43,0x5b,0xe4,0x05,
        +	0xcd,0xd0,0xa9,0x3e,0xcb,0x83,0x75,0xf6,0xb5,0xa5,
        +	0x9f,0x6b,0xe9,0x34,0x41,0x29,0x18,0xfa,0x6a,0x55,
        +	0x4d,0x70,0xfc,0xec,0xae,0x87,0x38,0x0a,0x20,0xa9,
        +	0xc0,0x45,0x77,0x6e,0x57,0x60,0x57,0xf4,0xed,0x96,
        +	0x22,0xcb,0x8f,0xe1,0x33,0x3a,0x17,0x1f,0xed,0x37,
        +	0xa5,0x6f,0xeb,0xa6,0xbc,0x12,0x80,0x1d,0x53,0xbd,
        +	0x70,0xeb,0x21,0x76,0x3e,0xc9,0x2f,0x1a,0x45,0x24,
        +	0x82,0xff,0xcd,0x59,0x32,0x06,0x2e,0x12,0x3b,0x23,
        +	0x78,0xed,0x12,0x3d,0xe0,0x8d,0xf9,0x67,0x4f,0x37,
        +	0x4e,0x47,0x02,0x4c,0x2d,0xc0,0x4f,0x1f,0xb3,0x94,
        +	0xe1,0x41,0x2e,0x2d,0x90,0x10,0xfc,0x82,0x91,0x8b,
        +	0x0f,0x22,0xd4,0xf2,0xfc,0x2c,0xab,0x53,0x55,0x02,
        +	0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x2b,0xcc,0x3f,
        +	0x8f,0x58,0xba,0x8b,0x00,0x16,0xf6,0xea,0x3a,0xf0,
        +	0x30,0xd0,0x05,0x17,0xda,0xb0,0xeb,0x9a,0x2d,0x4f,
        +	0x26,0xb0,0xd6,0x38,0xc1,0xeb,0xf5,0xd8,0x3d,0x1f,
        +	0x70,0xf7,0x7f,0xf4,0xe2,0xcf,0x51,0x51,0x79,0x88,
        +	0xfa,0xe8,0x32,0x0e,0x7b,0x2d,0x97,0xf2,0xfa,0xba,
        +	0x27,0xc5,0x9c,0xd9,0xc5,0xeb,0x8a,0x79,0x52,0x3c,
        +	0x64,0x34,0x7d,0xc2,0xcf,0x28,0xc7,0x4e,0xd5,0x43,
        +	0x0b,0xd1,0xa6,0xca,0x6d,0x03,0x2d,0x72,0x23,0xbc,
        +	0x6d,0x05,0xfa,0x16,0x09,0x2f,0x2e,0x5c,0xb6,0xee,
        +	0x74,0xdd,0xd2,0x48,0x8e,0x36,0x0c,0x06,0x3d,0x4d,
        +	0xe5,0x10,0x82,0xeb,0x6a,0xf3,0x4b,0x9f,0xd6,0xed,
        +	0x11,0xb1,0x6e,0xec,0xf4,0xfe,0x8e,0x75,0x94,0x20,
        +	0x2f,0xcb,0xac,0x46,0xf1,0x02,0x41,0x00,0xf9,0x8c,
        +	0xa3,0x85,0xb1,0xdd,0x29,0xaf,0x65,0xc1,0x33,0xf3,
        +	0x95,0xc5,0x52,0x68,0x0b,0xd4,0xf1,0xe5,0x0e,0x02,
        +	0x9f,0x4f,0xfa,0x77,0xdc,0x46,0x9e,0xc7,0xa6,0xe4,
        +	0x16,0x29,0xda,0xb0,0x07,0xcf,0x5b,0xa9,0x12,0x8a,
        +	0xdd,0x63,0x0a,0xde,0x2e,0x8c,0x66,0x8b,0x8c,0xdc,
        +	0x19,0xa3,0x7e,0xf4,0x3b,0xd0,0x1a,0x8c,0xa4,0xc2,
        +	0xe1,0xd3,0x02,0x41,0x00,0xe2,0x4c,0x05,0xf2,0x04,
        +	0x86,0x4e,0x61,0x43,0xdb,0xb0,0xb9,0x96,0x86,0x52,
        +	0x2c,0xca,0x8d,0x7b,0xab,0x0b,0x13,0x0d,0x7e,0x38,
        +	0x5b,0xe2,0x2e,0x7b,0x0e,0xe7,0x19,0x99,0x38,0xe7,
        +	0xf2,0x21,0xbd,0x85,0x85,0xe3,0xfd,0x28,0x77,0x20,
        +	0x31,0x71,0x2c,0xd0,0xff,0xfb,0x2e,0xaf,0x85,0xb4,
        +	0x86,0xca,0xf3,0xbb,0xca,0xaa,0x0f,0x95,0x37,0x02,
        +	0x40,0x0e,0x41,0x9a,0x95,0xe8,0xb3,0x59,0xce,0x4b,
        +	0x61,0xde,0x35,0xec,0x38,0x79,0x9c,0xb8,0x10,0x52,
        +	0x41,0x63,0xab,0x82,0xae,0x6f,0x00,0xa9,0xf4,0xde,
        +	0xdd,0x49,0x0b,0x7e,0xb8,0xa5,0x65,0xa9,0x0c,0x8f,
        +	0x8f,0xf9,0x1f,0x35,0xc6,0x92,0xb8,0x5e,0xb0,0x66,
        +	0xab,0x52,0x40,0xc0,0xb6,0x36,0x6a,0x7d,0x80,0x46,
        +	0x04,0x02,0xe5,0x9f,0x41,0x02,0x41,0x00,0xc0,0xad,
        +	0xcc,0x4e,0x21,0xee,0x1d,0x24,0x91,0xfb,0xa7,0x80,
        +	0x8d,0x9a,0xb6,0xb3,0x2e,0x8f,0xc2,0xe1,0x82,0xdf,
        +	0x69,0x18,0xb4,0x71,0xff,0xa6,0x65,0xde,0xed,0x84,
        +	0x8d,0x42,0xb7,0xb3,0x21,0x69,0x56,0x1c,0x07,0x60,
        +	0x51,0x29,0x04,0xff,0x34,0x06,0xdd,0xb9,0x67,0x2c,
        +	0x7c,0x04,0x93,0x0e,0x46,0x15,0xbb,0x2a,0xb7,0x1b,
        +	0xe7,0x87,0x02,0x40,0x78,0xda,0x5d,0x07,0x51,0x0c,
        +	0x16,0x7a,0x9f,0x29,0x20,0x84,0x0d,0x42,0xfa,0xd7,
        +	0x00,0xd8,0x77,0x7e,0xb0,0xb0,0x6b,0xd6,0x5b,0x53,
        +	0xb8,0x9b,0x7a,0xcd,0xc7,0x2b,0xb8,0x6a,0x63,0xa9,
        +	0xfb,0x6f,0xa4,0x72,0xbf,0x4c,0x5d,0x00,0x14,0xba,
        +	0xfa,0x59,0x88,0xed,0xe4,0xe0,0x8c,0xa2,0xec,0x14,
        +	0x7e,0x2d,0xe2,0xf0,0x46,0x49,0x95,0x45,
        +	};
        +
        +static unsigned char test2048[]={
        +	0x30,0x82,0x04,0xa3,0x02,0x01,0x00,0x02,0x82,0x01,
        +	0x01,0x00,0xc0,0xc0,0xce,0x3e,0x3c,0x53,0x67,0x3f,
        +	0x4f,0xc5,0x2f,0xa4,0xc2,0x5a,0x2f,0x58,0xfd,0x27,
        +	0x52,0x6a,0xe8,0xcf,0x4a,0x73,0x47,0x8d,0x25,0x0f,
        +	0x5f,0x03,0x26,0x78,0xef,0xf0,0x22,0x12,0xd3,0xde,
        +	0x47,0xb2,0x1c,0x0b,0x38,0x63,0x1a,0x6c,0x85,0x7a,
        +	0x80,0xc6,0x8f,0xa0,0x41,0xaf,0x62,0xc4,0x67,0x32,
        +	0x88,0xf8,0xa6,0x9c,0xf5,0x23,0x1d,0xe4,0xac,0x3f,
        +	0x29,0xf9,0xec,0xe1,0x8b,0x26,0x03,0x2c,0xb2,0xab,
        +	0xf3,0x7d,0xb5,0xca,0x49,0xc0,0x8f,0x1c,0xdf,0x33,
        +	0x3a,0x60,0xda,0x3c,0xb0,0x16,0xf8,0xa9,0x12,0x8f,
        +	0x64,0xac,0x23,0x0c,0x69,0x64,0x97,0x5d,0x99,0xd4,
        +	0x09,0x83,0x9b,0x61,0xd3,0xac,0xf0,0xde,0xdd,0x5e,
        +	0x9f,0x44,0x94,0xdb,0x3a,0x4d,0x97,0xe8,0x52,0x29,
        +	0xf7,0xdb,0x94,0x07,0x45,0x90,0x78,0x1e,0x31,0x0b,
        +	0x80,0xf7,0x57,0xad,0x1c,0x79,0xc5,0xcb,0x32,0xb0,
        +	0xce,0xcd,0x74,0xb3,0xe2,0x94,0xc5,0x78,0x2f,0x34,
        +	0x1a,0x45,0xf7,0x8c,0x52,0xa5,0xbc,0x8d,0xec,0xd1,
        +	0x2f,0x31,0x3b,0xf0,0x49,0x59,0x5e,0x88,0x9d,0x15,
        +	0x92,0x35,0x32,0xc1,0xe7,0x61,0xec,0x50,0x48,0x7c,
        +	0xba,0x05,0xf9,0xf8,0xf8,0xa7,0x8c,0x83,0xe8,0x66,
        +	0x5b,0xeb,0xfe,0xd8,0x4f,0xdd,0x6d,0x36,0xc0,0xb2,
        +	0x90,0x0f,0xb8,0x52,0xf9,0x04,0x9b,0x40,0x2c,0x27,
        +	0xd6,0x36,0x8e,0xc2,0x1b,0x44,0xf3,0x92,0xd5,0x15,
        +	0x9e,0x9a,0xbc,0xf3,0x7d,0x03,0xd7,0x02,0x14,0x20,
        +	0xe9,0x10,0x92,0xfd,0xf9,0xfc,0x8f,0xe5,0x18,0xe1,
        +	0x95,0xcc,0x9e,0x60,0xa6,0xfa,0x38,0x4d,0x02,0x03,
        +	0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x00,0xc3,0xc3,
        +	0x0d,0xb4,0x27,0x90,0x8d,0x4b,0xbf,0xb8,0x84,0xaa,
        +	0xd0,0xb8,0xc7,0x5d,0x99,0xbe,0x55,0xf6,0x3e,0x7c,
        +	0x49,0x20,0xcb,0x8a,0x8e,0x19,0x0e,0x66,0x24,0xac,
        +	0xaf,0x03,0x33,0x97,0xeb,0x95,0xd5,0x3b,0x0f,0x40,
        +	0x56,0x04,0x50,0xd1,0xe6,0xbe,0x84,0x0b,0x25,0xd3,
        +	0x9c,0xe2,0x83,0x6c,0xf5,0x62,0x5d,0xba,0x2b,0x7d,
        +	0x3d,0x7a,0x6c,0xe1,0xd2,0x0e,0x54,0x93,0x80,0x01,
        +	0x91,0x51,0x09,0xe8,0x5b,0x8e,0x47,0xbd,0x64,0xe4,
        +	0x0e,0x03,0x83,0x55,0xcf,0x5a,0x37,0xf0,0x25,0xb5,
        +	0x7d,0x21,0xd7,0x69,0xdf,0x6f,0xc2,0xcf,0x10,0xc9,
        +	0x8a,0x40,0x9f,0x7a,0x70,0xc0,0xe8,0xe8,0xc0,0xe6,
        +	0x9a,0x15,0x0a,0x8d,0x4e,0x46,0xcb,0x7a,0xdb,0xb3,
        +	0xcb,0x83,0x02,0xc4,0xf0,0xab,0xeb,0x02,0x01,0x0e,
        +	0x23,0xfc,0x1d,0xc4,0xbd,0xd4,0xaa,0x5d,0x31,0x46,
        +	0x99,0xce,0x9e,0xf8,0x04,0x75,0x10,0x67,0xc4,0x53,
        +	0x47,0x44,0xfa,0xc2,0x25,0x73,0x7e,0xd0,0x8e,0x59,
        +	0xd1,0xb2,0x5a,0xf4,0xc7,0x18,0x92,0x2f,0x39,0xab,
        +	0xcd,0xa3,0xb5,0xc2,0xb9,0xc7,0xb9,0x1b,0x9f,0x48,
        +	0xfa,0x13,0xc6,0x98,0x4d,0xca,0x84,0x9c,0x06,0xca,
        +	0xe7,0x89,0x01,0x04,0xc4,0x6c,0xfd,0x29,0x59,0x35,
        +	0xe7,0xf3,0xdd,0xce,0x64,0x59,0xbf,0x21,0x13,0xa9,
        +	0x9f,0x0e,0xc5,0xff,0xbd,0x33,0x00,0xec,0xac,0x6b,
        +	0x11,0xef,0x51,0x5e,0xad,0x07,0x15,0xde,0xb8,0x5f,
        +	0xc6,0xb9,0xa3,0x22,0x65,0x46,0x83,0x14,0xdf,0xd0,
        +	0xf1,0x44,0x8a,0xe1,0x9c,0x23,0x33,0xb4,0x97,0x33,
        +	0xe6,0x6b,0x81,0x02,0x81,0x81,0x00,0xec,0x12,0xa7,
        +	0x59,0x74,0x6a,0xde,0x3e,0xad,0xd8,0x36,0x80,0x50,
        +	0xa2,0xd5,0x21,0x81,0x07,0xf1,0xd0,0x91,0xf2,0x6c,
        +	0x12,0x2f,0x9d,0x1a,0x26,0xf8,0x30,0x65,0xdf,0xe8,
        +	0xc0,0x9b,0x6a,0x30,0x98,0x82,0x87,0xec,0xa2,0x56,
        +	0x87,0x62,0x6f,0xe7,0x9f,0xf6,0x56,0xe6,0x71,0x8f,
        +	0x49,0x86,0x93,0x5a,0x4d,0x34,0x58,0xfe,0xd9,0x04,
        +	0x13,0xaf,0x79,0xb7,0xad,0x11,0xd1,0x30,0x9a,0x14,
        +	0x06,0xa0,0xfa,0xb7,0x55,0xdc,0x6c,0x5a,0x4c,0x2c,
        +	0x59,0x56,0xf6,0xe8,0x9d,0xaf,0x0a,0x78,0x99,0x06,
        +	0x06,0x9e,0xe7,0x9c,0x51,0x55,0x43,0xfc,0x3b,0x6c,
        +	0x0b,0xbf,0x2d,0x41,0xa7,0xaf,0xb7,0xe0,0xe8,0x28,
        +	0x18,0xb4,0x13,0xd1,0xe6,0x97,0xd0,0x9f,0x6a,0x80,
        +	0xca,0xdd,0x1a,0x7e,0x15,0x02,0x81,0x81,0x00,0xd1,
        +	0x06,0x0c,0x1f,0xe3,0xd0,0xab,0xd6,0xca,0x7c,0xbc,
        +	0x7d,0x13,0x35,0xce,0x27,0xcd,0xd8,0x49,0x51,0x63,
        +	0x64,0x0f,0xca,0x06,0x12,0xfc,0x07,0x3e,0xaf,0x61,
        +	0x6d,0xe2,0x53,0x39,0x27,0xae,0xc3,0x11,0x9e,0x94,
        +	0x01,0x4f,0xe3,0xf3,0x67,0xf9,0x77,0xf9,0xe7,0x95,
        +	0x3a,0x6f,0xe2,0x20,0x73,0x3e,0xa4,0x7a,0x28,0xd4,
        +	0x61,0x97,0xf6,0x17,0xa0,0x23,0x10,0x2b,0xce,0x84,
        +	0x57,0x7e,0x25,0x1f,0xf4,0xa8,0x54,0xd2,0x65,0x94,
        +	0xcc,0x95,0x0a,0xab,0x30,0xc1,0x59,0x1f,0x61,0x8e,
        +	0xb9,0x6b,0xd7,0x4e,0xb9,0x83,0x43,0x79,0x85,0x11,
        +	0xbc,0x0f,0xae,0x25,0x20,0x05,0xbc,0xd2,0x48,0xa1,
        +	0x68,0x09,0x84,0xf6,0x12,0x9a,0x66,0xb9,0x2b,0xbb,
        +	0x76,0x03,0x17,0x46,0x4e,0x97,0x59,0x02,0x81,0x80,
        +	0x09,0x4c,0xfa,0xd6,0xe5,0x65,0x48,0x78,0x43,0xb5,
        +	0x1f,0x00,0x93,0x2c,0xb7,0x24,0xe8,0xc6,0x7d,0x5a,
        +	0x70,0x45,0x92,0xc8,0x6c,0xa3,0xcd,0xe1,0xf7,0x29,
        +	0x40,0xfa,0x3f,0x5b,0x47,0x44,0x39,0xc1,0xe8,0x72,
        +	0x9e,0x7a,0x0e,0xda,0xaa,0xa0,0x2a,0x09,0xfd,0x54,
        +	0x93,0x23,0xaa,0x37,0x85,0x5b,0xcc,0xd4,0xf9,0xd8,
        +	0xff,0xc1,0x61,0x0d,0xbd,0x7e,0x18,0x24,0x73,0x6d,
        +	0x40,0x72,0xf1,0x93,0x09,0x48,0x97,0x6c,0x84,0x90,
        +	0xa8,0x46,0x14,0x01,0x39,0x11,0xe5,0x3c,0x41,0x27,
        +	0x32,0x75,0x24,0xed,0xa1,0xd9,0x12,0x29,0x8a,0x28,
        +	0x71,0x89,0x8d,0xca,0x30,0xb0,0x01,0xc4,0x2f,0x82,
        +	0x19,0x14,0x4c,0x70,0x1c,0xb8,0x23,0x2e,0xe8,0x90,
        +	0x49,0x97,0x92,0x97,0x6b,0x7a,0x9d,0xb9,0x02,0x81,
        +	0x80,0x0f,0x0e,0xa1,0x76,0xf6,0xa1,0x44,0x8f,0xaf,
        +	0x7c,0x76,0xd3,0x87,0xbb,0xbb,0x83,0x10,0x88,0x01,
        +	0x18,0x14,0xd1,0xd3,0x75,0x59,0x24,0xaa,0xf5,0x16,
        +	0xa5,0xe9,0x9d,0xd1,0xcc,0xee,0xf4,0x15,0xd9,0xc5,
        +	0x7e,0x27,0xe9,0x44,0x49,0x06,0x72,0xb9,0xfc,0xd3,
        +	0x8a,0xc4,0x2c,0x36,0x7d,0x12,0x9b,0x5a,0xaa,0xdc,
        +	0x85,0xee,0x6e,0xad,0x54,0xb3,0xf4,0xfc,0x31,0xa1,
        +	0x06,0x3a,0x70,0x57,0x0c,0xf3,0x95,0x5b,0x3e,0xe8,
        +	0xfd,0x1a,0x4f,0xf6,0x78,0x93,0x46,0x6a,0xd7,0x31,
        +	0xb4,0x84,0x64,0x85,0x09,0x38,0x89,0x92,0x94,0x1c,
        +	0xbf,0xe2,0x3c,0x2a,0xe0,0xff,0x99,0xa3,0xf0,0x2b,
        +	0x31,0xc2,0x36,0xcd,0x60,0xbf,0x9d,0x2d,0x74,0x32,
        +	0xe8,0x9c,0x93,0x6e,0xbb,0x91,0x7b,0xfd,0xd9,0x02,
        +	0x81,0x81,0x00,0xa2,0x71,0x25,0x38,0xeb,0x2a,0xe9,
        +	0x37,0xcd,0xfe,0x44,0xce,0x90,0x3f,0x52,0x87,0x84,
        +	0x52,0x1b,0xae,0x8d,0x22,0x94,0xce,0x38,0xe6,0x04,
        +	0x88,0x76,0x85,0x9a,0xd3,0x14,0x09,0xe5,0x69,0x9a,
        +	0xff,0x58,0x92,0x02,0x6a,0x7d,0x7c,0x1e,0x2c,0xfd,
        +	0xa8,0xca,0x32,0x14,0x4f,0x0d,0x84,0x0d,0x37,0x43,
        +	0xbf,0xe4,0x5d,0x12,0xc8,0x24,0x91,0x27,0x8d,0x46,
        +	0xd9,0x54,0x53,0xe7,0x62,0x71,0xa8,0x2b,0x71,0x41,
        +	0x8d,0x75,0xf8,0x3a,0xa0,0x61,0x29,0x46,0xa6,0xe5,
        +	0x82,0xfa,0x3a,0xd9,0x08,0xfa,0xfc,0x63,0xfd,0x6b,
        +	0x30,0xbc,0xf4,0x4e,0x9e,0x8c,0x25,0x0c,0xb6,0x55,
        +	0xe7,0x3c,0xd4,0x4e,0x0b,0xfd,0x8b,0xc3,0x0e,0x1d,
        +	0x9c,0x44,0x57,0x8f,0x1f,0x86,0xf7,0xd5,0x1b,0xe4,
        +	0x95,
        +	};
        +
        +static unsigned char test4096[]={
        +	0x30,0x82,0x09,0x29,0x02,0x01,0x00,0x02,0x82,0x02,
        +	0x01,0x00,0xc0,0x71,0xac,0x1a,0x13,0x88,0x82,0x43,
        +	0x3b,0x51,0x57,0x71,0x8d,0xb6,0x2b,0x82,0x65,0x21,
        +	0x53,0x5f,0x28,0x29,0x4f,0x8d,0x7c,0x8a,0xb9,0x44,
        +	0xb3,0x28,0x41,0x4f,0xd3,0xfa,0x6a,0xf8,0xb9,0x28,
        +	0x50,0x39,0x67,0x53,0x2c,0x3c,0xd7,0xcb,0x96,0x41,
        +	0x40,0x32,0xbb,0xeb,0x70,0xae,0x1f,0xb0,0x65,0xf7,
        +	0x3a,0xd9,0x22,0xfd,0x10,0xae,0xbd,0x02,0xe2,0xdd,
        +	0xf3,0xc2,0x79,0x3c,0xc6,0xfc,0x75,0xbb,0xaf,0x4e,
        +	0x3a,0x36,0xc2,0x4f,0xea,0x25,0xdf,0x13,0x16,0x4b,
        +	0x20,0xfe,0x4b,0x69,0x16,0xc4,0x7f,0x1a,0x43,0xa6,
        +	0x17,0x1b,0xb9,0x0a,0xf3,0x09,0x86,0x28,0x89,0xcf,
        +	0x2c,0xd0,0xd4,0x81,0xaf,0xc6,0x6d,0xe6,0x21,0x8d,
        +	0xee,0xef,0xea,0xdc,0xb7,0xc6,0x3b,0x63,0x9f,0x0e,
        +	0xad,0x89,0x78,0x23,0x18,0xbf,0x70,0x7e,0x84,0xe0,
        +	0x37,0xec,0xdb,0x8e,0x9c,0x3e,0x6a,0x19,0xcc,0x99,
        +	0x72,0xe6,0xb5,0x7d,0x6d,0xfa,0xe5,0xd3,0xe4,0x90,
        +	0xb5,0xb2,0xb2,0x12,0x70,0x4e,0xca,0xf8,0x10,0xf8,
        +	0xa3,0x14,0xc2,0x48,0x19,0xeb,0x60,0x99,0xbb,0x2a,
        +	0x1f,0xb1,0x7a,0xb1,0x3d,0x24,0xfb,0xa0,0x29,0xda,
        +	0xbd,0x1b,0xd7,0xa4,0xbf,0xef,0x60,0x2d,0x22,0xca,
        +	0x65,0x98,0xf1,0xc4,0xe1,0xc9,0x02,0x6b,0x16,0x28,
        +	0x2f,0xa1,0xaa,0x79,0x00,0xda,0xdc,0x7c,0x43,0xf7,
        +	0x42,0x3c,0xa0,0xef,0x68,0xf7,0xdf,0xb9,0x69,0xfb,
        +	0x8e,0x01,0xed,0x01,0x42,0xb5,0x4e,0x57,0xa6,0x26,
        +	0xb8,0xd0,0x7b,0x56,0x6d,0x03,0xc6,0x40,0x8c,0x8c,
        +	0x2a,0x55,0xd7,0x9c,0x35,0x00,0x94,0x93,0xec,0x03,
        +	0xeb,0x22,0xef,0x77,0xbb,0x79,0x13,0x3f,0x15,0xa1,
        +	0x8f,0xca,0xdf,0xfd,0xd3,0xb8,0xe1,0xd4,0xcc,0x09,
        +	0x3f,0x3c,0x2c,0xdb,0xd1,0x49,0x7f,0x38,0x07,0x83,
        +	0x6d,0xeb,0x08,0x66,0xe9,0x06,0x44,0x12,0xac,0x95,
        +	0x22,0x90,0x23,0x67,0xd4,0x08,0xcc,0xf4,0xb7,0xdc,
        +	0xcc,0x87,0xd4,0xac,0x69,0x35,0x4c,0xb5,0x39,0x36,
        +	0xcd,0xa4,0xd2,0x95,0xca,0x0d,0xc5,0xda,0xc2,0xc5,
        +	0x22,0x32,0x28,0x08,0xe3,0xd2,0x8b,0x38,0x30,0xdc,
        +	0x8c,0x75,0x4f,0x6a,0xec,0x7a,0xac,0x16,0x3e,0xa8,
        +	0xd4,0x6a,0x45,0xe1,0xa8,0x4f,0x2e,0x80,0x34,0xaa,
        +	0x54,0x1b,0x02,0x95,0x7d,0x8a,0x6d,0xcc,0x79,0xca,
        +	0xf2,0xa4,0x2e,0x8d,0xfb,0xfe,0x15,0x51,0x10,0x0e,
        +	0x4d,0x88,0xb1,0xc7,0xf4,0x79,0xdb,0xf0,0xb4,0x56,
        +	0x44,0x37,0xca,0x5a,0xc1,0x8c,0x48,0xac,0xae,0x48,
        +	0x80,0x83,0x01,0x3f,0xde,0xd9,0xd3,0x2c,0x51,0x46,
        +	0xb1,0x41,0xb6,0xc6,0x91,0x72,0xf9,0x83,0x55,0x1b,
        +	0x8c,0xba,0xf3,0x73,0xe5,0x2c,0x74,0x50,0x3a,0xbe,
        +	0xc5,0x2f,0xa7,0xb2,0x6d,0x8c,0x9e,0x13,0x77,0xa3,
        +	0x13,0xcd,0x6d,0x8c,0x45,0xe1,0xfc,0x0b,0xb7,0x69,
        +	0xe9,0x27,0xbc,0x65,0xc3,0xfa,0x9b,0xd0,0xef,0xfe,
        +	0xe8,0x1f,0xb3,0x5e,0x34,0xf4,0x8c,0xea,0xfc,0xd3,
        +	0x81,0xbf,0x3d,0x30,0xb2,0xb4,0x01,0xe8,0x43,0x0f,
        +	0xba,0x02,0x23,0x42,0x76,0x82,0x31,0x73,0x91,0xed,
        +	0x07,0x46,0x61,0x0d,0x39,0x83,0x40,0xce,0x7a,0xd4,
        +	0xdb,0x80,0x2c,0x1f,0x0d,0xd1,0x34,0xd4,0x92,0xe3,
        +	0xd4,0xf1,0xc2,0x01,0x02,0x03,0x01,0x00,0x01,0x02,
        +	0x82,0x02,0x01,0x00,0x97,0x6c,0xda,0x6e,0xea,0x4f,
        +	0xcf,0xaf,0xf7,0x4c,0xd9,0xf1,0x90,0x00,0x77,0xdb,
        +	0xf2,0x97,0x76,0x72,0xb9,0xb7,0x47,0xd1,0x9c,0xdd,
        +	0xcb,0x4a,0x33,0x6e,0xc9,0x75,0x76,0xe6,0xe4,0xa5,
        +	0x31,0x8c,0x77,0x13,0xb4,0x29,0xcd,0xf5,0x52,0x17,
        +	0xef,0xf3,0x08,0x00,0xe3,0xbd,0x2e,0xbc,0xd4,0x52,
        +	0x88,0xe9,0x30,0x75,0x0b,0x02,0xf5,0xcd,0x89,0x0c,
        +	0x6c,0x57,0x19,0x27,0x3d,0x1e,0x85,0xb4,0xc1,0x2f,
        +	0x1d,0x92,0x00,0x5c,0x76,0x29,0x4b,0xa4,0xe1,0x12,
        +	0xb3,0xc8,0x09,0xfe,0x0e,0x78,0x72,0x61,0xcb,0x61,
        +	0x6f,0x39,0x91,0x95,0x4e,0xd5,0x3e,0xc7,0x8f,0xb8,
        +	0xf6,0x36,0xfe,0x9c,0x93,0x9a,0x38,0x25,0x7a,0xf4,
        +	0x4a,0x12,0xd4,0xa0,0x13,0xbd,0xf9,0x1d,0x12,0x3e,
        +	0x21,0x39,0xfb,0x72,0xe0,0x05,0x3d,0xc3,0xe5,0x50,
        +	0xa8,0x5d,0x85,0xa3,0xea,0x5f,0x1c,0xb2,0x3f,0xea,
        +	0x6d,0x03,0x91,0x55,0xd8,0x19,0x0a,0x21,0x12,0x16,
        +	0xd9,0x12,0xc4,0xe6,0x07,0x18,0x5b,0x26,0xa4,0xae,
        +	0xed,0x2b,0xb7,0xa6,0xed,0xf8,0xad,0xec,0x77,0xe6,
        +	0x7f,0x4f,0x76,0x00,0xc0,0xfa,0x15,0x92,0xb4,0x2c,
        +	0x22,0xc2,0xeb,0x6a,0xad,0x14,0x05,0xb2,0xe5,0x8a,
        +	0x9e,0x85,0x83,0xcc,0x04,0xf1,0x56,0x78,0x44,0x5e,
        +	0xde,0xe0,0x60,0x1a,0x65,0x79,0x31,0x23,0x05,0xbb,
        +	0x01,0xff,0xdd,0x2e,0xb7,0xb3,0xaa,0x74,0xe0,0xa5,
        +	0x94,0xaf,0x4b,0xde,0x58,0x0f,0x55,0xde,0x33,0xf6,
        +	0xe3,0xd6,0x34,0x36,0x57,0xd6,0x79,0x91,0x2e,0xbe,
        +	0x3b,0xd9,0x4e,0xb6,0x9d,0x21,0x5c,0xd3,0x48,0x14,
        +	0x7f,0x4a,0xc4,0x60,0xa9,0x29,0xf8,0x53,0x7f,0x88,
        +	0x11,0x2d,0xb5,0xc5,0x2d,0x6f,0xee,0x85,0x0b,0xf7,
        +	0x8d,0x9a,0xbe,0xb0,0x42,0xf2,0x2e,0x71,0xaf,0x19,
        +	0x31,0x6d,0xec,0xcd,0x6f,0x2b,0x23,0xdf,0xb4,0x40,
        +	0xaf,0x2c,0x0a,0xc3,0x1b,0x7d,0x7d,0x03,0x1d,0x4b,
        +	0xf3,0xb5,0xe0,0x85,0xd8,0xdf,0x91,0x6b,0x0a,0x69,
        +	0xf7,0xf2,0x69,0x66,0x5b,0xf1,0xcf,0x46,0x7d,0xe9,
        +	0x70,0xfa,0x6d,0x7e,0x75,0x4e,0xa9,0x77,0xe6,0x8c,
        +	0x02,0xf7,0x14,0x4d,0xa5,0x41,0x8f,0x3f,0xc1,0x62,
        +	0x1e,0x71,0x5e,0x38,0xb4,0xd6,0xe6,0xe1,0x4b,0xc2,
        +	0x2c,0x30,0x83,0x81,0x6f,0x49,0x2e,0x96,0xe6,0xc9,
        +	0x9a,0xf7,0x5d,0x09,0xa0,0x55,0x02,0xa5,0x3a,0x25,
        +	0x23,0xd0,0x92,0xc3,0xa3,0xe3,0x0e,0x12,0x2f,0x4d,
        +	0xef,0xf3,0x55,0x5a,0xbe,0xe6,0x19,0x86,0x31,0xab,
        +	0x75,0x9a,0xd3,0xf0,0x2c,0xc5,0x41,0x92,0xd9,0x1f,
        +	0x5f,0x11,0x8c,0x75,0x1c,0x63,0xd0,0x02,0x80,0x2c,
        +	0x68,0xcb,0x93,0xfb,0x51,0x73,0x49,0xb4,0x60,0xda,
        +	0xe2,0x26,0xaf,0xa9,0x46,0x12,0xb8,0xec,0x50,0xdd,
        +	0x12,0x06,0x5f,0xce,0x59,0xe6,0xf6,0x1c,0xe0,0x54,
        +	0x10,0xad,0xf6,0xcd,0x98,0xcc,0x0f,0xfb,0xcb,0x41,
        +	0x14,0x9d,0xed,0xe4,0xb4,0x74,0x5f,0x09,0x60,0xc7,
        +	0x12,0xf6,0x7b,0x3c,0x8f,0xa7,0x20,0xbc,0xe4,0xb1,
        +	0xef,0xeb,0xa4,0x93,0xc5,0x06,0xca,0x9a,0x27,0x9d,
        +	0x87,0xf3,0xde,0xca,0xe5,0xe7,0xf6,0x1c,0x01,0x65,
        +	0x5b,0xfb,0x19,0x79,0x6e,0x08,0x26,0xc5,0xc8,0x28,
        +	0x0e,0xb6,0x3b,0x07,0x08,0xc1,0x02,0x82,0x01,0x01,
        +	0x00,0xe8,0x1c,0x73,0xa6,0xb8,0xe0,0x0e,0x6d,0x8d,
        +	0x1b,0xb9,0x53,0xed,0x58,0x94,0xe6,0x1d,0x60,0x14,
        +	0x5c,0x76,0x43,0xc4,0x58,0x19,0xc4,0x24,0xe8,0xbc,
        +	0x1b,0x3b,0x0b,0x13,0x24,0x45,0x54,0x0e,0xcc,0x37,
        +	0xf0,0xe0,0x63,0x7d,0xc3,0xf7,0xfb,0x81,0x74,0x81,
        +	0xc4,0x0f,0x1a,0x21,0x48,0xaf,0xce,0xc1,0xc4,0x94,
        +	0x18,0x06,0x44,0x8d,0xd3,0xd2,0x22,0x2d,0x2d,0x3e,
        +	0x5a,0x31,0xdc,0x95,0x8e,0xf4,0x41,0xfc,0x58,0xc9,
        +	0x40,0x92,0x17,0x5f,0xe3,0xda,0xac,0x9e,0x3f,0x1c,
        +	0x2a,0x6b,0x58,0x5f,0x48,0x78,0x20,0xb1,0xaf,0x24,
        +	0x9b,0x3c,0x20,0x8b,0x93,0x25,0x9e,0xe6,0x6b,0xbc,
        +	0x13,0x42,0x14,0x6c,0x36,0x31,0xff,0x7a,0xd1,0xc1,
        +	0x1a,0x26,0x14,0x7f,0xa9,0x76,0xa7,0x0c,0xf8,0xcc,
        +	0xed,0x07,0x6a,0xd2,0xdf,0x62,0xee,0x0a,0x7c,0x84,
        +	0xcb,0x49,0x90,0xb2,0x03,0x0d,0xa2,0x82,0x06,0x77,
        +	0xf1,0xcd,0x67,0xf2,0x47,0x21,0x02,0x3f,0x43,0x21,
        +	0xf0,0x46,0x30,0x62,0x51,0x72,0xb1,0xe7,0x48,0xc6,
        +	0x67,0x12,0xcd,0x9e,0xd6,0x15,0xe5,0x21,0xed,0xfa,
        +	0x8f,0x30,0xa6,0x41,0xfe,0xb6,0xfa,0x8f,0x34,0x14,
        +	0x19,0xe8,0x11,0xf7,0xa5,0x77,0x3e,0xb7,0xf9,0x39,
        +	0x07,0x8c,0x67,0x2a,0xab,0x7b,0x08,0xf8,0xb0,0x06,
        +	0xa8,0xea,0x2f,0x8f,0xfa,0xcc,0xcc,0x40,0xce,0xf3,
        +	0x70,0x4f,0x3f,0x7f,0xe2,0x0c,0xea,0x76,0x4a,0x35,
        +	0x4e,0x47,0xad,0x2b,0xa7,0x97,0x5d,0x74,0x43,0x97,
        +	0x90,0xd2,0xfb,0xd9,0xf9,0x96,0x01,0x33,0x05,0xed,
        +	0x7b,0x03,0x05,0xad,0xf8,0x49,0x03,0x02,0x82,0x01,
        +	0x01,0x00,0xd4,0x40,0x17,0x66,0x10,0x92,0x95,0xc8,
        +	0xec,0x62,0xa9,0x7a,0xcb,0x93,0x8e,0xe6,0x53,0xd4,
        +	0x80,0x48,0x27,0x4b,0x41,0xce,0x61,0xdf,0xbf,0x94,
        +	0xa4,0x3d,0x71,0x03,0x0b,0xed,0x25,0x71,0x98,0xa4,
        +	0xd6,0xd5,0x4a,0x57,0xf5,0x6c,0x1b,0xda,0x21,0x7d,
        +	0x35,0x45,0xb3,0xf3,0x6a,0xd9,0xd3,0x43,0xe8,0x5c,
        +	0x54,0x1c,0x83,0x1b,0xb4,0x5f,0xf2,0x97,0x24,0x2e,
        +	0xdc,0x40,0xde,0x92,0x23,0x59,0x8e,0xbc,0xd2,0xa1,
        +	0xf2,0xe0,0x4c,0xdd,0x0b,0xd1,0xe7,0xae,0x65,0xbc,
        +	0xb5,0xf5,0x5b,0x98,0xe9,0xd7,0xc2,0xb7,0x0e,0x55,
        +	0x71,0x0e,0x3c,0x0a,0x24,0x6b,0xa6,0xe6,0x14,0x61,
        +	0x11,0xfd,0x33,0x42,0x99,0x2b,0x84,0x77,0x74,0x92,
        +	0x91,0xf5,0x79,0x79,0xcf,0xad,0x8e,0x04,0xef,0x80,
        +	0x1e,0x57,0xf4,0x14,0xf5,0x35,0x09,0x74,0xb2,0x13,
        +	0x71,0x58,0x6b,0xea,0x32,0x5d,0xf3,0xd3,0x76,0x48,
        +	0x39,0x10,0x23,0x84,0x9d,0xbe,0x92,0x77,0x4a,0xed,
        +	0x70,0x3e,0x1a,0xa2,0x6c,0xb3,0x81,0x00,0xc3,0xc9,
        +	0xe4,0x52,0xc8,0x24,0x88,0x0c,0x41,0xad,0x87,0x5a,
        +	0xea,0xa3,0x7a,0x85,0x1c,0x5e,0x31,0x7f,0xc3,0x35,
        +	0xc6,0xfa,0x10,0xc8,0x75,0x10,0xc4,0x96,0x99,0xe7,
        +	0xfe,0x01,0xb4,0x74,0xdb,0xb4,0x11,0xc3,0xc8,0x8c,
        +	0xf6,0xf7,0x3b,0x66,0x50,0xfc,0xdb,0xeb,0xca,0x47,
        +	0x85,0x89,0xe1,0x65,0xd9,0x62,0x34,0x3c,0x70,0xd8,
        +	0x2e,0xb4,0x2f,0x65,0x3c,0x4a,0xa6,0x2a,0xe7,0xc7,
        +	0xd8,0x41,0x8f,0x8a,0x43,0xbf,0x42,0xf2,0x4d,0xbc,
        +	0xfc,0x9e,0x27,0x95,0xfb,0x75,0xff,0xab,0x02,0x82,
        +	0x01,0x00,0x41,0x2f,0x44,0x57,0x6d,0x12,0x17,0x5b,
        +	0x32,0xc6,0xb7,0x6c,0x57,0x7a,0x8a,0x0e,0x79,0xef,
        +	0x72,0xa8,0x68,0xda,0x2d,0x38,0xe4,0xbb,0x8d,0xf6,
        +	0x02,0x65,0xcf,0x56,0x13,0xe1,0x1a,0xcb,0x39,0x80,
        +	0xa6,0xb1,0x32,0x03,0x1e,0xdd,0xbb,0x35,0xd9,0xac,
        +	0x43,0x89,0x31,0x08,0x90,0x92,0x5e,0x35,0x3d,0x7b,
        +	0x9c,0x6f,0x86,0xcb,0x17,0xdd,0x85,0xe4,0xed,0x35,
        +	0x08,0x8e,0xc1,0xf4,0x05,0xd8,0x68,0xc6,0x63,0x3c,
        +	0xf7,0xff,0xf7,0x47,0x33,0x39,0xc5,0x3e,0xb7,0x0e,
        +	0x58,0x35,0x9d,0x81,0xea,0xf8,0x6a,0x2c,0x1c,0x5a,
        +	0x68,0x78,0x64,0x11,0x6b,0xc1,0x3e,0x4e,0x7a,0xbd,
        +	0x84,0xcb,0x0f,0xc2,0xb6,0x85,0x1d,0xd3,0x76,0xc5,
        +	0x93,0x6a,0x69,0x89,0x56,0x34,0xdc,0x4a,0x9b,0xbc,
        +	0xff,0xa8,0x0d,0x6e,0x35,0x9c,0x60,0xa7,0x23,0x30,
        +	0xc7,0x06,0x64,0x39,0x8b,0x94,0x89,0xee,0xba,0x7f,
        +	0x60,0x8d,0xfa,0xb6,0x97,0x76,0xdc,0x51,0x4a,0x3c,
        +	0xeb,0x3a,0x14,0x2c,0x20,0x60,0x69,0x4a,0x86,0xfe,
        +	0x8c,0x21,0x84,0x49,0x54,0xb3,0x20,0xe1,0x01,0x7f,
        +	0x58,0xdf,0x7f,0xb5,0x21,0x51,0x8c,0x47,0x9f,0x91,
        +	0xeb,0x97,0x3e,0xf2,0x54,0xcf,0x16,0x46,0xf9,0xd9,
        +	0xb6,0xe7,0x64,0xc9,0xd0,0x54,0xea,0x2f,0xa1,0xcf,
        +	0xa5,0x7f,0x28,0x8d,0x84,0xec,0xd5,0x39,0x03,0x76,
        +	0x5b,0x2d,0x8e,0x43,0xf2,0x01,0x24,0xc9,0x6f,0xc0,
        +	0xf5,0x69,0x6f,0x7d,0xb5,0x85,0xd2,0x5f,0x7f,0x78,
        +	0x40,0x07,0x7f,0x09,0x15,0xb5,0x1f,0x28,0x65,0x10,
        +	0xe4,0x19,0xa8,0xc6,0x9e,0x8d,0xdc,0xcb,0x02,0x82,
        +	0x01,0x00,0x13,0x01,0xee,0x56,0x80,0x93,0x70,0x00,
        +	0x7f,0x52,0xd2,0x94,0xa1,0x98,0x84,0x4a,0x92,0x25,
        +	0x4c,0x9b,0xa9,0x91,0x2e,0xc2,0x79,0xb7,0x5c,0xe3,
        +	0xc5,0xd5,0x8e,0xc2,0x54,0x16,0x17,0xad,0x55,0x9b,
        +	0x25,0x76,0x12,0x63,0x50,0x22,0x2f,0x58,0x58,0x79,
        +	0x6b,0x04,0xe3,0xf9,0x9f,0x8f,0x04,0x41,0x67,0x94,
        +	0xa5,0x1f,0xac,0x8a,0x15,0x9c,0x26,0x10,0x6c,0xf8,
        +	0x19,0x57,0x61,0xd7,0x3a,0x7d,0x31,0xb0,0x2d,0x38,
        +	0xbd,0x94,0x62,0xad,0xc4,0xfa,0x36,0x42,0x42,0xf0,
        +	0x24,0x67,0x65,0x9d,0x8b,0x0b,0x7c,0x6f,0x82,0x44,
        +	0x1a,0x8c,0xc8,0xc9,0xab,0xbb,0x4c,0x45,0xfc,0x7b,
        +	0x38,0xee,0x30,0xe1,0xfc,0xef,0x8d,0xbc,0x58,0xdf,
        +	0x2b,0x5d,0x0d,0x54,0xe0,0x49,0x4d,0x97,0x99,0x8f,
        +	0x22,0xa8,0x83,0xbe,0x40,0xbb,0x50,0x2e,0x78,0x28,
        +	0x0f,0x95,0x78,0x8c,0x8f,0x98,0x24,0x56,0xc2,0x97,
        +	0xf3,0x2c,0x43,0xd2,0x03,0x82,0x66,0x81,0x72,0x5f,
        +	0x53,0x16,0xec,0xb1,0xb1,0x04,0x5e,0x40,0x20,0x48,
        +	0x7b,0x3f,0x02,0x97,0x6a,0xeb,0x96,0x12,0x21,0x35,
        +	0xfe,0x1f,0x47,0xc0,0x95,0xea,0xc5,0x8a,0x08,0x84,
        +	0x4f,0x5e,0x63,0x94,0x60,0x0f,0x71,0x5b,0x7f,0x4a,
        +	0xec,0x4f,0x60,0xc6,0xba,0x4a,0x24,0xf1,0x20,0x8b,
        +	0xa7,0x2e,0x3a,0xce,0x8d,0xe0,0x27,0x1d,0xb5,0x8e,
        +	0xb4,0x21,0xc5,0xe2,0xa6,0x16,0x0a,0x51,0x83,0x55,
        +	0x88,0xd1,0x30,0x11,0x63,0xd5,0xd7,0x8d,0xae,0x16,
        +	0x12,0x82,0xc4,0x85,0x00,0x4e,0x27,0x83,0xa5,0x7c,
        +	0x90,0x2e,0xe5,0xa2,0xa3,0xd3,0x4c,0x63,0x02,0x82,
        +	0x01,0x01,0x00,0x86,0x08,0x98,0x98,0xa5,0x00,0x05,
        +	0x39,0x77,0xd9,0x66,0xb3,0xcf,0xca,0xa0,0x71,0xb3,
        +	0x50,0xce,0x3d,0xb1,0x93,0x95,0x35,0xc4,0xd4,0x2e,
        +	0x90,0xdf,0x0f,0xfc,0x60,0xc1,0x94,0x68,0x61,0x43,
        +	0xca,0x9a,0x23,0x4a,0x1e,0x45,0x72,0x99,0xb5,0x1e,
        +	0x61,0x8d,0x77,0x0f,0xa0,0xbb,0xd7,0x77,0xb4,0x2a,
        +	0x15,0x11,0x88,0x2d,0xb3,0x56,0x61,0x5e,0x6a,0xed,
        +	0xa4,0x46,0x4a,0x3f,0x50,0x11,0xd6,0xba,0xb6,0xd7,
        +	0x95,0x65,0x53,0xc3,0xa1,0x8f,0xe0,0xa3,0xf5,0x1c,
        +	0xfd,0xaf,0x6e,0x43,0xd7,0x17,0xa7,0xd3,0x81,0x1b,
        +	0xa4,0xdf,0xe0,0x97,0x8a,0x46,0x03,0xd3,0x46,0x0e,
        +	0x83,0x48,0x4e,0xd2,0x02,0xcb,0xc0,0xad,0x79,0x95,
        +	0x8c,0x96,0xba,0x40,0x34,0x11,0x71,0x5e,0xe9,0x11,
        +	0xf9,0xc5,0x4a,0x5e,0x91,0x9d,0xf5,0x92,0x4f,0xeb,
        +	0xc6,0x70,0x02,0x2d,0x3d,0x04,0xaa,0xe9,0x3a,0x8e,
        +	0xd5,0xa8,0xad,0xf7,0xce,0x0d,0x16,0xb2,0xec,0x0a,
        +	0x9c,0xf5,0x94,0x39,0xb9,0x8a,0xfc,0x1e,0xf9,0xcc,
        +	0xf2,0x5f,0x21,0x31,0x74,0x72,0x6b,0x64,0xae,0x35,
        +	0x61,0x8d,0x0d,0xcb,0xe7,0xda,0x39,0xca,0xf3,0x21,
        +	0x66,0x0b,0x95,0xd7,0x0a,0x7c,0xca,0xa1,0xa9,0x5a,
        +	0xe8,0xac,0xe0,0x71,0x54,0xaf,0x28,0xcf,0xd5,0x70,
        +	0x89,0xe0,0xf3,0x9e,0x43,0x6c,0x8d,0x7b,0x99,0x01,
        +	0x68,0x4d,0xa1,0x45,0x46,0x0c,0x43,0xbc,0xcc,0x2c,
        +	0xdd,0xc5,0x46,0xc8,0x4e,0x0e,0xbe,0xed,0xb9,0x26,
        +	0xab,0x2e,0xdb,0xeb,0x8f,0xff,0xdb,0xb0,0xc6,0x55,
        +	0xaf,0xf8,0x2a,0x91,0x9d,0x50,0x44,0x21,0x17,
        +	};
        diff --git a/vendor/openssl/openssl/apps/timeouts.h b/vendor/openssl/openssl/apps/timeouts.h
        new file mode 100644
        index 000000000..89b5dc76f
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/timeouts.h
        @@ -0,0 +1,67 @@
        +/* apps/timeouts.h */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 INCLUDED_TIMEOUTS_H
        +#define INCLUDED_TIMEOUTS_H
        +
        +/* numbers in us */
        +#define DGRAM_RCV_TIMEOUT         250000
        +#define DGRAM_SND_TIMEOUT         250000
        +
        +#endif /* ! INCLUDED_TIMEOUTS_H */
        diff --git a/vendor/openssl/openssl/apps/ts.c b/vendor/openssl/openssl/apps/ts.c
        new file mode 100644
        index 000000000..5fa9f7fda
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/ts.c
        @@ -0,0 +1,1147 @@
        +/* apps/ts.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/rand.h>
        +#include <openssl/ts.h>
        +#include <openssl/bn.h>
        +
        +#undef PROG
        +#define PROG	ts_main
        +
        +/* Length of the nonce of the request in bits (must be a multiple of 8). */
        +#define	NONCE_LENGTH		64
        +
        +/* Macro definitions for the configuration file. */
        +#define	ENV_OID_FILE		"oid_file"
        +
        +/* Local function declarations. */
        +
        +static ASN1_OBJECT *txt2obj(const char *oid);
        +static CONF *load_config_file(const char *configfile);
        +
        +/* Query related functions. */
        +static int query_command(const char *data, char *digest,
        +			 const EVP_MD *md, const char *policy, int no_nonce, 
        +			 int cert, const char *in, const char *out, int text);
        +static BIO *BIO_open_with_default(const char *file, const char *mode, 
        +				  FILE *default_fp);
        +static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
        +			    const char *policy, int no_nonce, int cert);
        +static int create_digest(BIO *input, char *digest,
        +			 const EVP_MD *md, unsigned char **md_value);
        +static ASN1_INTEGER *create_nonce(int bits);
        +
        +/* Reply related functions. */
        +static int reply_command(CONF *conf, char *section, char *engine, 
        +			 char *queryfile, char *passin, char *inkey, 
        +			 char *signer, char *chain, const char *policy, 
        +			 char *in, int token_in, char *out, int token_out,
        +			 int text);
        +static TS_RESP *read_PKCS7(BIO *in_bio);
        +static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
        +				char *queryfile, char *passin, char *inkey,
        +				char *signer, char *chain, const char *policy);
        +static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
        +static ASN1_INTEGER *next_serial(const char *serialfile);
        +static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
        +
        +/* Verify related functions. */
        +static int verify_command(char *data, char *digest, char *queryfile,
        +			  char *in, int token_in,
        +			  char *ca_path, char *ca_file, char *untrusted);
        +static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 
        +					char *queryfile, 
        +					char *ca_path, char *ca_file,
        +					char *untrusted);
        +static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
        +static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx);
        +
        +/* Main function definition. */
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int ret = 1;
        +	char *configfile = NULL;
        +	char *section = NULL;
        +	CONF *conf = NULL;
        +	enum mode {
        +	CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 
        +	} mode = CMD_NONE;
        +	char *data = NULL;
        +	char *digest = NULL;
        +	const EVP_MD *md = NULL;
        +	char *rnd = NULL;
        +	char *policy = NULL;
        +	int no_nonce = 0;
        +	int cert = 0;
        +	char *in = NULL;
        +	char *out = NULL;
        +	int text = 0;
        +	char *queryfile = NULL;
        +	char *passin = NULL;	/* Password source. */
        +	char *password =NULL;	/* Password itself. */
        +	char *inkey = NULL;
        +	char *signer = NULL;
        +	char *chain = NULL;
        +	char *ca_path = NULL;
        +	char *ca_file = NULL;
        +	char *untrusted = NULL;
        +	char *engine = NULL;
        +	/* Input is ContentInfo instead of TimeStampResp. */
        +	int token_in = 0;	
        +	/* Output is ContentInfo instead of TimeStampResp. */
        +	int token_out = 0;
        +	int free_bio_err = 0;
        +
        +	ERR_load_crypto_strings();
        +	apps_startup();
        +
        +	if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
        +		{
        +		free_bio_err = 1;
        +		BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
        +		}
        +
        +	if (!load_config(bio_err, NULL))
        +		goto cleanup;
        +
        +	for (argc--, argv++; argc > 0; argc--, argv++)
        +		{
        +		if (strcmp(*argv, "-config") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			configfile = *++argv;
        +			}
        +		else if (strcmp(*argv, "-section") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			section = *++argv;
        +			}
        +		else if (strcmp(*argv, "-query") == 0)
        +			{
        +			if (mode != CMD_NONE) goto usage;
        +			mode = CMD_QUERY;
        +			}
        +		else if (strcmp(*argv, "-data") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			data = *++argv;
        +			}
        +		else if (strcmp(*argv, "-digest") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			digest = *++argv;
        +			}
        +		else if (strcmp(*argv, "-rand") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			rnd = *++argv;
        +			}
        +		else if (strcmp(*argv, "-policy") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			policy = *++argv;
        +			}
        +		else if (strcmp(*argv, "-no_nonce") == 0)
        +			{
        +			no_nonce = 1;
        +			}
        +		else if (strcmp(*argv, "-cert") == 0)
        +			{
        +			cert = 1;
        +			}
        +		else if (strcmp(*argv, "-in") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			in = *++argv;
        +			}
        +		else if (strcmp(*argv, "-token_in") == 0)
        +			{
        +			token_in = 1;
        +			}
        +		else if (strcmp(*argv, "-out") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			out = *++argv;
        +			}
        +		else if (strcmp(*argv, "-token_out") == 0)
        +			{
        +			token_out = 1;
        +			}
        +		else if (strcmp(*argv, "-text") == 0)
        +			{
        +			text = 1;
        +			}
        +		else if (strcmp(*argv, "-reply") == 0)
        +			{
        +			if (mode != CMD_NONE) goto usage;
        +			mode = CMD_REPLY;
        +			}
        +		else if (strcmp(*argv, "-queryfile") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			queryfile = *++argv;
        +			}
        +		else if (strcmp(*argv, "-passin") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			passin = *++argv;
        +			}
        +		else if (strcmp(*argv, "-inkey") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			inkey = *++argv;
        +			}
        +		else if (strcmp(*argv, "-signer") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			signer = *++argv;
        +			}
        +		else if (strcmp(*argv, "-chain") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			chain = *++argv;
        +			}
        +		else if (strcmp(*argv, "-verify") == 0)
        +			{
        +			if (mode != CMD_NONE) goto usage;
        +			mode = CMD_VERIFY;
        +			}
        +		else if (strcmp(*argv, "-CApath") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			ca_path = *++argv;
        +			}
        +		else if (strcmp(*argv, "-CAfile") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			ca_file = *++argv;
        +			}
        +		else if (strcmp(*argv, "-untrusted") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			untrusted = *++argv;
        +			}
        +		else if (strcmp(*argv, "-engine") == 0)
        +			{
        +			if (argc-- < 1) goto usage;
        +			engine = *++argv;
        +			}
        +		else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
        +			{
        +			/* empty. */
        +			}
        +		else
        +			goto usage;
        +		}
        +	
        +	/* Seed the random number generator if it is going to be used. */
        +	if (mode == CMD_QUERY && !no_nonce)
        +		{
        +		if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
        +			BIO_printf(bio_err, "warning, not much extra random "
        +				   "data, consider using the -rand option\n");
        +		if (rnd != NULL)
        +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
        +				   app_RAND_load_files(rnd));
        +		}
        +
        +	/* Get the password if required. */
        +	if(mode == CMD_REPLY && passin &&
        +	   !app_passwd(bio_err, passin, NULL, &password, NULL))
        +		{
        +		BIO_printf(bio_err,"Error getting password.\n");
        +		goto cleanup;
        +		}
        +
        +	/* Check consistency of parameters and execute 
        +	   the appropriate function. */
        +	switch (mode)
        +		{
        +	case CMD_NONE:
        +		goto usage;
        +	case CMD_QUERY:
        +		/* Data file and message imprint cannot be specified
        +		   at the same time. */
        +		ret = data != NULL && digest != NULL;
        +		if (ret) goto usage;
        +		/* Load the config file for possible policy OIDs. */
        +		conf = load_config_file(configfile);
        +		ret = !query_command(data, digest, md, policy, no_nonce, cert,
        +				     in, out, text);
        +		break;
        +	case CMD_REPLY:
        +		conf = load_config_file(configfile);
        +		if (in == NULL)
        +			{
        +			ret = !(queryfile != NULL && conf != NULL && !token_in);
        +			if (ret) goto usage;
        +			}
        +		else
        +			{
        +			/* 'in' and 'queryfile' are exclusive. */
        +			ret = !(queryfile == NULL);
        +			if (ret) goto usage;
        +			}
        +
        +		ret = !reply_command(conf, section, engine, queryfile, 
        +				     password, inkey, signer, chain, policy, 
        +				     in, token_in, out, token_out, text);
        +		break;
        +	case CMD_VERIFY:
        +		ret = !(((queryfile && !data && !digest)
        +			 || (!queryfile && data && !digest)
        +			 || (!queryfile && !data && digest))
        +			&& in != NULL);
        +		if (ret) goto usage;
        +
        +		ret = !verify_command(data, digest, queryfile, in, token_in,
        +				      ca_path, ca_file, untrusted);
        +		}
        +
        +	goto cleanup;
        +
        + usage:
        +	BIO_printf(bio_err, "usage:\n"
        +		   "ts -query [-rand file%cfile%c...] [-config configfile] "
        +		   "[-data file_to_hash] [-digest digest_bytes]"
        +		   "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
        +		   "[-policy object_id] [-no_nonce] [-cert] "
        +		   "[-in request.tsq] [-out request.tsq] [-text]\n",
        +		   LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
        +	BIO_printf(bio_err, "or\n"
        +		   "ts -reply [-config configfile] [-section tsa_section] "
        +		   "[-queryfile request.tsq] [-passin password] "
        +		   "[-signer tsa_cert.pem] [-inkey private_key.pem] "
        +		   "[-chain certs_file.pem] [-policy object_id] "
        +		   "[-in response.tsr] [-token_in] "
        +		   "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
        +	BIO_printf(bio_err, "or\n"
        +		   "ts -verify [-data file_to_hash] [-digest digest_bytes] "
        +		   "[-queryfile request.tsq] "
        +		   "-in response.tsr [-token_in] "
        +		   "-CApath ca_path -CAfile ca_file.pem "
        +		   "-untrusted cert_file.pem\n");
        + cleanup:
        +	/* Clean up. */
        +	app_RAND_write_file(NULL, bio_err);
        +	NCONF_free(conf);
        +	OPENSSL_free(password);
        +	OBJ_cleanup();
        +	if (free_bio_err)
        +		{
        +		BIO_free_all(bio_err);
        +		bio_err = NULL;
        +		}
        +
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +/*
        + * Configuration file-related function definitions.
        + */
        +
        +static ASN1_OBJECT *txt2obj(const char *oid)
        +	{
        +	ASN1_OBJECT *oid_obj = NULL;
        +
        +	if (!(oid_obj = OBJ_txt2obj(oid, 0)))
        +		BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
        +
        +	return oid_obj;
        +	}
        +
        +static CONF *load_config_file(const char *configfile)
        +	{
        +	CONF *conf = NULL;
        +	long errorline = -1;
        +
        +	if (!configfile) configfile = getenv("OPENSSL_CONF");
        +	if (!configfile) configfile = getenv("SSLEAY_CONF");
        +
        +	if (configfile &&
        +	    (!(conf = NCONF_new(NULL)) ||
        +	     NCONF_load(conf, configfile, &errorline) <= 0))
        +		{
        +		if (errorline <= 0)
        +			BIO_printf(bio_err, "error loading the config file "
        +				   "'%s'\n", configfile);
        +		else
        +			BIO_printf(bio_err, "error on line %ld of config file "
        +				   "'%s'\n", errorline, configfile);
        +		}
        +
        +	if (conf != NULL)
        +		{
        +		const char *p;
        +
        +		BIO_printf(bio_err,"Using configuration from %s\n", configfile);
        +		p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
        +		if (p != NULL)
        +			{
        +			BIO *oid_bio = BIO_new_file(p, "r");
        +			if (!oid_bio) 
        +				ERR_print_errors(bio_err);
        +			else
        +				{
        +				OBJ_create_objects(oid_bio);
        +				BIO_free_all(oid_bio);
        +				}
        +			}
        +		else
        +			ERR_clear_error();
        +		if(!add_oid_section(bio_err, conf)) 
        +			ERR_print_errors(bio_err);
        +		}
        +	return conf;
        +	}
        +
        +/*
        + * Query-related method definitions.
        + */
        +
        +static int query_command(const char *data, char *digest, const EVP_MD *md,
        +			 const char *policy, int no_nonce, 
        +			 int cert, const char *in, const char *out, int text)
        +	{
        +	int ret = 0;
        +	TS_REQ *query = NULL;
        +	BIO *in_bio = NULL;
        +	BIO *data_bio = NULL;
        +	BIO *out_bio = NULL;
        +
        +	/* Build query object either from file or from scratch. */
        +	if (in != NULL)
        +		{
        +		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
        +		query = d2i_TS_REQ_bio(in_bio, NULL);
        +		}
        +	else
        +		{
        +		/* Open the file if no explicit digest bytes were specified. */
        +		if (!digest 
        +		    && !(data_bio = BIO_open_with_default(data, "rb", stdin)))
        +			goto end;
        +		/* Creating the query object. */
        +		query = create_query(data_bio, digest, md,
        +				     policy, no_nonce, cert);
        +		/* Saving the random number generator state. */
        +		}
        +	if (query == NULL) goto end;
        +
        +	/* Write query either in ASN.1 or in text format. */
        +	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
        +		goto end;
        +	if (text)
        +		{
        +		/* Text output. */
        +		if (!TS_REQ_print_bio(out_bio, query))
        +			goto end;
        +		}
        +	else
        +		{
        +		/* ASN.1 output. */
        +		if (!i2d_TS_REQ_bio(out_bio, query))
        +			goto end;
        +		}
        +
        +	ret = 1;
        +
        + end:
        +	ERR_print_errors(bio_err);
        +
        +	/* Clean up. */
        +	BIO_free_all(in_bio);
        +	BIO_free_all(data_bio);
        +	BIO_free_all(out_bio);
        +	TS_REQ_free(query);
        +
        +	return ret;
        +	}
        +
        +static BIO *BIO_open_with_default(const char *file, const char *mode, 
        +				  FILE *default_fp)
        +	{
        +	return file == NULL ? 
        +		BIO_new_fp(default_fp, BIO_NOCLOSE) 
        +		: BIO_new_file(file, mode);
        +	}
        +
        +static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
        +			    const char *policy, int no_nonce, int cert)
        +	{
        +	int ret = 0;
        +	TS_REQ *ts_req = NULL;
        +	int len;
        +	TS_MSG_IMPRINT *msg_imprint = NULL;
        +	X509_ALGOR *algo = NULL;
        +	unsigned char *data = NULL;
        +	ASN1_OBJECT *policy_obj = NULL;
        +	ASN1_INTEGER *nonce_asn1 = NULL;
        +
        +	/* Setting default message digest. */
        +	if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err;
        +
        +	/* Creating request object. */
        +	if (!(ts_req = TS_REQ_new())) goto err;
        +
        +	/* Setting version. */
        +	if (!TS_REQ_set_version(ts_req, 1)) goto err;
        +
        +	/* Creating and adding MSG_IMPRINT object. */
        +	if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err;
        +
        +	/* Adding algorithm. */
        +	if (!(algo = X509_ALGOR_new())) goto err;
        +	if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err;
        +	if (!(algo->parameter = ASN1_TYPE_new())) goto err;
        +	algo->parameter->type = V_ASN1_NULL;
        +	if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err;
        +
        +	/* Adding message digest. */
        +	if ((len = create_digest(data_bio, digest, md, &data)) == 0)
        +		goto err;
        +	if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err;
        +
        +	if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;
        +	
        +	/* Setting policy if requested. */
        +	if (policy && !(policy_obj = txt2obj(policy))) goto err;
        +	if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;
        +
        +	/* Setting nonce if requested. */
        +	if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err;
        +	if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err;
        +
        +	/* Setting certificate request flag if requested. */
        +	if (!TS_REQ_set_cert_req(ts_req, cert)) goto err;
        +
        +	ret = 1;
        + err:
        +	if (!ret)
        +		{
        +		TS_REQ_free(ts_req);
        +		ts_req = NULL;
        +		BIO_printf(bio_err, "could not create query\n");
        +		}
        +	TS_MSG_IMPRINT_free(msg_imprint);
        +	X509_ALGOR_free(algo);
        +	OPENSSL_free(data);
        +	ASN1_OBJECT_free(policy_obj);
        +	ASN1_INTEGER_free(nonce_asn1);
        +	return ts_req;
        +	}
        +
        +static int create_digest(BIO *input, char *digest, const EVP_MD *md,
        +			 unsigned char **md_value)
        +	{
        +	int md_value_len;
        +
        +	md_value_len = EVP_MD_size(md);
        +	if (md_value_len < 0)
        +	    goto err;
        +	if (input)
        +		{
        +		/* Digest must be computed from an input file. */
        +		EVP_MD_CTX md_ctx;
        +		unsigned char buffer[4096];
        +		int length;
        +
        +		*md_value = OPENSSL_malloc(md_value_len);
        +		if (*md_value == 0) goto err;
        +
        +		EVP_DigestInit(&md_ctx, md);
        +		while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0)
        +			{
        +			EVP_DigestUpdate(&md_ctx, buffer, length);
        +			}
        +		EVP_DigestFinal(&md_ctx, *md_value, NULL);
        +		}
        +	else
        +		{
        +		/* Digest bytes are specified with digest. */
        +		long digest_len;
        +		*md_value = string_to_hex(digest, &digest_len);
        +		if (!*md_value || md_value_len != digest_len)
        +			{
        +			OPENSSL_free(*md_value);
        +			*md_value = NULL;
        +			BIO_printf(bio_err, "bad digest, %d bytes "
        +				   "must be specified\n", md_value_len);
        +			goto err;
        +			}
        +		}
        +
        +	return md_value_len;
        + err:
        +	return 0;
        +	}
        +
        +static ASN1_INTEGER *create_nonce(int bits)
        +	{
        +	unsigned char buf[20];
        +	ASN1_INTEGER *nonce = NULL;
        +	int len = (bits - 1) / 8 + 1;
        +	int i;
        +
        +	/* Generating random byte sequence. */
        +	if (len > (int)sizeof(buf)) goto err;
        +	if (RAND_bytes(buf, len) <= 0) goto err;
        +
        +	/* Find the first non-zero byte and creating ASN1_INTEGER object. */
        +	for (i = 0; i < len && !buf[i]; ++i);
        +	if (!(nonce = ASN1_INTEGER_new())) goto err;
        +	OPENSSL_free(nonce->data);
        +	/* Allocate at least one byte. */
        +	nonce->length = len - i;
        +	if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err;
        +	memcpy(nonce->data, buf + i, nonce->length);
        +
        +	return nonce;
        + err:
        +	BIO_printf(bio_err, "could not create nonce\n");
        +	ASN1_INTEGER_free(nonce);
        +	return NULL;
        +	}
        +/*
        + * Reply-related method definitions.
        + */
        +
        +static int reply_command(CONF *conf, char *section, char *engine, 
        +			 char *queryfile, char *passin, char *inkey,
        +			 char *signer, char *chain, const char *policy, 
        +			 char *in, int token_in,
        +			 char *out, int token_out, int text)
        +	{
        +	int ret = 0;
        +	TS_RESP *response = NULL;
        +	BIO *in_bio = NULL;
        +	BIO *query_bio = NULL;
        +	BIO *inkey_bio = NULL;
        +	BIO *signer_bio = NULL;
        +	BIO *out_bio = NULL;
        +
        +	/* Build response object either from response or query. */
        +	if (in != NULL)
        +		{
        +		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
        +		if (token_in)
        +			{
        +			/* We have a ContentInfo (PKCS7) object, add
        +			   'granted' status info around it. */
        +			response = read_PKCS7(in_bio);
        +			}
        +		else
        +			{
        +			/* We have a ready-made TS_RESP object. */
        +			response = d2i_TS_RESP_bio(in_bio, NULL);
        +			}
        +		}
        +	else
        +		{
        +		response = create_response(conf, section, engine, queryfile,
        +					   passin, inkey, signer, chain,
        +					   policy);
        +		if (response)
        +			BIO_printf(bio_err, "Response has been generated.\n");
        +		else
        +			BIO_printf(bio_err, "Response is not generated.\n");
        +		}
        +	if (response == NULL) goto end;
        +
        +	/* Write response either in ASN.1 or text format. */
        +	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
        +		goto end;
        +	if (text)
        +		{
        +		/* Text output. */
        +		if (token_out)
        +			{
        +			TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
        +			if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end;
        +			}
        +		else
        +			{
        +			if (!TS_RESP_print_bio(out_bio, response)) goto end;
        +			}
        +		}
        +	else
        +		{
        +		/* ASN.1 DER output. */
        +		if (token_out)
        +			{
        +			PKCS7 *token = TS_RESP_get_token(response);
        +			if (!i2d_PKCS7_bio(out_bio, token)) goto end;
        +			}
        +		else
        +			{
        +			if (!i2d_TS_RESP_bio(out_bio, response)) goto end;
        +			}
        +		}
        +
        +	ret = 1;
        +
        + end:
        +	ERR_print_errors(bio_err);
        +
        +	/* Clean up. */
        +	BIO_free_all(in_bio);
        +	BIO_free_all(query_bio);
        +	BIO_free_all(inkey_bio);
        +	BIO_free_all(signer_bio);
        +	BIO_free_all(out_bio);
        +	TS_RESP_free(response);
        +
        +	return ret;
        +	}
        +
        +/* Reads a PKCS7 token and adds default 'granted' status info to it. */
        +static TS_RESP *read_PKCS7(BIO *in_bio)
        +	{
        +	int ret = 0;
        +	PKCS7 *token = NULL;
        +	TS_TST_INFO *tst_info = NULL;
        +	TS_RESP *resp = NULL;
        +	TS_STATUS_INFO *si = NULL;
        +
        +	/* Read PKCS7 object and extract the signed time stamp info. */
        +	if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
        +	if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end;
        +
        +	/* Creating response object. */
        +	if (!(resp = TS_RESP_new())) goto end;
        +
        +	/* Create granted status info. */
        +	if (!(si = TS_STATUS_INFO_new())) goto end;
        +	if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end;
        +	if (!TS_RESP_set_status_info(resp, si)) goto end;
        +
        +	/* Setting encapsulated token. */
        +	TS_RESP_set_tst_info(resp, token, tst_info);
        +	token = NULL;		/* Ownership is lost. */
        +	tst_info = NULL;	/* Ownership is lost. */
        +
        +	ret = 1;
        + end:
        +	PKCS7_free(token);
        +	TS_TST_INFO_free(tst_info);
        +	if (!ret)
        +		{
        +		TS_RESP_free(resp);
        +		resp = NULL;
        +		}
        +	TS_STATUS_INFO_free(si);
        +	return resp;
        +	}
        +
        +static TS_RESP *create_response(CONF *conf, const char *section, char *engine, 
        +				char *queryfile, char *passin, char *inkey,
        +				char *signer, char *chain, const char *policy)
        +	{
        +	int ret = 0;
        +	TS_RESP *response = NULL;
        +	BIO *query_bio = NULL;
        +	TS_RESP_CTX *resp_ctx = NULL;
        +
        +	if (!(query_bio = BIO_new_file(queryfile, "rb")))
        +		goto end;
        +
        +	/* Getting TSA configuration section. */
        +	if (!(section = TS_CONF_get_tsa_section(conf, section)))
        +		goto end;
        +
        +	/* Setting up response generation context. */
        +	if (!(resp_ctx = TS_RESP_CTX_new())) goto end;
        +
        +	/* Setting serial number provider callback. */
        +	if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end;
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Setting default OpenSSL engine. */
        +	if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end;
        +#endif
        +
        +	/* Setting TSA signer certificate. */
        +	if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end;
        +
        +	/* Setting TSA signer certificate chain. */
        +	if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;
        +
        +	/* Setting TSA signer private key. */
        +	if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
        +		goto end;
        +
        +	/* Setting default policy OID. */
        +	if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
        +
        +	/* Setting acceptable policy OIDs. */
        +	if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end;
        +
        +	/* Setting the acceptable one-way hash algorithms. */
        +	if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end;
        +
        +	/* Setting guaranteed time stamp accuracy. */
        +	if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end;
        +
        +	/* Setting the precision of the time. */
        +	if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
        +		goto end;
        +
        +	/* Setting the ordering flaf if requested. */
        +	if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end;
        +
        +	/* Setting the TSA name required flag if requested. */
        +	if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end;
        +
        +	/* Setting the ESS cert id chain flag if requested. */
        +	if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end;
        +
        +	/* Creating the response. */
        +	if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
        +		goto end;
        +
        +	ret = 1;
        + end:
        +	if (!ret) 
        +		{
        +		TS_RESP_free(response);
        +		response = NULL;
        +		}
        +	TS_RESP_CTX_free(resp_ctx);
        +	BIO_free_all(query_bio);
        +
        +	return response;
        +	}
        +
        +static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data)
        +	{
        +	const char *serial_file = (const char *) data;
        +	ASN1_INTEGER *serial = next_serial(serial_file);
        +
        +	if (!serial)
        +		{
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Error during serial number "
        +					    "generation.");
        +		TS_RESP_CTX_add_failure_info(ctx,
        +					     TS_INFO_ADD_INFO_NOT_AVAILABLE);
        +		}
        +	else
        +		save_ts_serial(serial_file, serial);
        +
        +	return serial;
        +	}
        +
        +static ASN1_INTEGER *next_serial(const char *serialfile)
        +	{
        +	int ret = 0;
        +	BIO *in = NULL;
        +	ASN1_INTEGER *serial = NULL;
        +	BIGNUM *bn = NULL;
        +
        +	if (!(serial = ASN1_INTEGER_new())) goto err;
        +
        +	if (!(in = BIO_new_file(serialfile, "r"))) 
        +		{
        +		ERR_clear_error();
        +		BIO_printf(bio_err, "Warning: could not open file %s for "
        +			   "reading, using serial number: 1\n", serialfile);
        +		if (!ASN1_INTEGER_set(serial, 1)) goto err;
        +		}
        +	else
        +		{
        +		char buf[1024];
        +		if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf)))
        +			{
        +			BIO_printf(bio_err, "unable to load number from %s\n",
        +				   serialfile);
        +			goto err;
        +			}
        +		if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err;
        +		ASN1_INTEGER_free(serial);
        +		serial = NULL;
        +		if (!BN_add_word(bn, 1)) goto err;
        +		if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err;
        +		}
        +	ret = 1;
        + err:
        +	if (!ret)
        +		{
        +		ASN1_INTEGER_free(serial);
        +		serial = NULL;
        +		}
        +	BIO_free_all(in);
        +	BN_free(bn);
        +	return serial;
        +	}
        +
        +static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
        +	{
        +	int ret = 0;
        +	BIO *out = NULL;
        +
        +	if (!(out = BIO_new_file(serialfile, "w"))) goto err;
        +	if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err;
        +	if (BIO_puts(out, "\n") <= 0) goto err;
        +	ret = 1;
        + err:
        +	if (!ret)
        +		BIO_printf(bio_err, "could not save serial number to %s\n",
        +			   serialfile);
        +	BIO_free_all(out);
        +	return ret;
        +	}
        +
        +/*
        + * Verify-related method definitions.
        + */
        +
        +static int verify_command(char *data, char *digest, char *queryfile,
        +			  char *in, int token_in,
        +			  char *ca_path, char *ca_file, char *untrusted)
        +	{
        +	BIO *in_bio = NULL;
        +	PKCS7 *token = NULL;
        +	TS_RESP *response = NULL;
        +	TS_VERIFY_CTX *verify_ctx = NULL;
        +	int ret = 0;
        +
        +	/* Decode the token (PKCS7) or response (TS_RESP) files. */
        +	if (!(in_bio = BIO_new_file(in, "rb"))) goto end;
        +	if (token_in)
        +		{
        +		if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
        +		}
        +	else
        +		{
        +		if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end;
        +		}
        +
        +	if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, 
        +					     ca_path, ca_file, untrusted)))
        +		goto end;
        +
        +	/* Checking the token or response against the request. */
        +	ret = token_in ?
        +		TS_RESP_verify_token(verify_ctx, token) :
        +		TS_RESP_verify_response(verify_ctx, response);
        +
        + end:
        +	printf("Verification: ");
        +	if (ret)
        +		printf("OK\n");
        +	else
        +		{
        +		printf("FAILED\n");
        +		/* Print errors, if there are any. */
        +		ERR_print_errors(bio_err);
        +		}
        +	
        +	/* Clean up. */
        +	BIO_free_all(in_bio);
        +	PKCS7_free(token);
        +	TS_RESP_free(response);
        +	TS_VERIFY_CTX_free(verify_ctx);
        +	return ret;
        +	}
        +
        +static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 
        +					char *queryfile, 
        +					char *ca_path, char *ca_file,
        +					char *untrusted)
        +	{
        +	TS_VERIFY_CTX *ctx = NULL;
        +	BIO *input = NULL;
        +	TS_REQ *request = NULL;
        +	int ret = 0;
        +
        +	if (data != NULL || digest != NULL)
        +		{
        +		if (!(ctx = TS_VERIFY_CTX_new())) goto err;
        +		ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
        +		if (data != NULL)
        +			{
        +			ctx->flags |= TS_VFY_DATA;
        +			if (!(ctx->data = BIO_new_file(data, "rb"))) goto err;
        +			}
        +		else if (digest != NULL)
        +			{
        +			long imprint_len;
        +			ctx->flags |= TS_VFY_IMPRINT;
        +			if (!(ctx->imprint = string_to_hex(digest,
        +							   &imprint_len)))
        +				{
        +				BIO_printf(bio_err, "invalid digest string\n");
        +				goto err;
        +				}
        +			ctx->imprint_len = imprint_len;
        +			}
        +		
        +		}
        +	else if (queryfile != NULL)
        +		{
        +		/* The request has just to be read, decoded and converted to
        +		   a verify context object. */
        +		if (!(input = BIO_new_file(queryfile, "rb"))) goto err;
        +		if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err;
        +		if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err;
        +		}
        +	else
        +		return NULL;
        +
        +	/* Add the signature verification flag and arguments. */
        +	ctx->flags |= TS_VFY_SIGNATURE;
        +
        +	/* Initialising the X509_STORE object. */
        +	if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err;
        +
        +	/* Loading untrusted certificates. */
        +	if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) 
        +		goto err;
        +
        +	ret = 1;
        + err:
        +	if (!ret)
        +		{
        +		TS_VERIFY_CTX_free(ctx);
        +		ctx = NULL;
        +		}
        +	BIO_free_all(input);
        +	TS_REQ_free(request);
        +	return ctx;
        +	}
        +
        +static X509_STORE *create_cert_store(char *ca_path, char *ca_file)
        +	{
        +	X509_STORE *cert_ctx = NULL;
        +	X509_LOOKUP *lookup = NULL;
        +	int i;
        +
        +	/* Creating the X509_STORE object. */
        +	cert_ctx = X509_STORE_new();
        +
        +	/* Setting the callback for certificate chain verification. */
        +	X509_STORE_set_verify_cb(cert_ctx, verify_cb);
        +
        +	/* Adding a trusted certificate directory source. */
        +	if (ca_path)
        +		{
        +		lookup = X509_STORE_add_lookup(cert_ctx,
        +					       X509_LOOKUP_hash_dir());
        +		if (lookup == NULL)
        +			{
        +			BIO_printf(bio_err, "memory allocation failure\n");
        +			goto err;
        +			}
        +		i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
        +		if (!i)
        +			{
        +			BIO_printf(bio_err, "Error loading directory %s\n",
        +				   ca_path);
        +			goto err;
        +			}
        +		}
        +
        +	/* Adding a trusted certificate file source. */
        +	if (ca_file)
        +		{
        +		lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
        +		if (lookup == NULL)
        +			{
        +			BIO_printf(bio_err, "memory allocation failure\n");
        +			goto err;
        +			}
        +		i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
        +		if (!i)
        +			{
        +			BIO_printf(bio_err, "Error loading file %s\n", ca_file);
        +			goto err;
        +			}
        +		}
        +
        +	return cert_ctx;
        + err:
        +	X509_STORE_free(cert_ctx);
        +	return NULL;
        +	}
        +
        +static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx)
        +	{
        +	/*
        +	char buf[256];
        +
        +	if (!ok)
        +		{
        +		X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
        +				  buf, sizeof(buf));
        +		printf("%s\n", buf);
        +		printf("error %d at %d depth lookup: %s\n",
        +		       ctx->error, ctx->error_depth,
        +			X509_verify_cert_error_string(ctx->error));
        +		}
        +	*/
        +
        +	return ok;
        +	}
        diff --git a/vendor/openssl/openssl/apps/tsget b/vendor/openssl/openssl/apps/tsget
        new file mode 100644
        index 000000000..0d54e9fc9
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/tsget
        @@ -0,0 +1,196 @@
        +#!/usr/bin/perl -w
        +# Written by Zoltan Glozik <zglozik@stones.com>.
        +# Copyright (c) 2002 The OpenTSA Project.  All rights reserved.
        +$::version = '$Id: tsget,v 1.1.2.2 2009/09/07 17:57:02 steve Exp $';
        +
        +use strict;
        +use IO::Handle;
        +use Getopt::Std;
        +use File::Basename;
        +use WWW::Curl::Easy;
        +
        +use vars qw(%options);
        +
        +# Callback for reading the body.
        +sub read_body {
        +    my ($maxlength, $state) = @_;
        +    my $return_data = "";
        +    my $data_len = length ${$state->{data}};
        +    if ($state->{bytes} < $data_len) {
        +	$data_len = $data_len - $state->{bytes};
        +	$data_len = $maxlength if $data_len > $maxlength;
        +	$return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
        +	$state->{bytes} += $data_len;
        +    }
        +    return $return_data;
        +}
        +
        +# Callback for writing the body into a variable.
        +sub write_body {
        +    my ($data, $pointer) = @_;
        +    ${$pointer} .= $data;
        +    return length($data);
        +}
        +
        +# Initialise a new Curl object.
        +sub create_curl {
        +    my $url = shift;
        +
        +    # Create Curl object.
        +    my $curl = WWW::Curl::Easy::new();
        +
        +    # Error-handling related options.
        +    $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
        +    $curl->setopt(CURLOPT_FAILONERROR, 1);
        +    $curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/" . (split / /, $::version)[2]);
        +
        +    # Options for POST method.
        +    $curl->setopt(CURLOPT_UPLOAD, 1);
        +    $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
        +    $curl->setopt(CURLOPT_HTTPHEADER,
        +		["Content-Type: application/timestamp-query",
        +		"Accept: application/timestamp-reply,application/timestamp-response"]);
        +    $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
        +    $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
        +
        +    # Options for getting the result.
        +    $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
        +
        +    # SSL related options.
        +    $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
        +    $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1);	# Verify server's certificate.
        +    $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2);	# Check server's CN.
        +    $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
        +    $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
        +    $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
        +    $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
        +    $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
        +    $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
        +    $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
        +
        +    # Setting destination.
        +    $curl->setopt(CURLOPT_URL, $url);
        +
        +    return $curl;
        +}
        +
        +# Send a request and returns the body back.
        +sub get_timestamp {
        +    my $curl = shift;
        +    my $body = shift;
        +    my $ts_body;
        +    local $::error_buf;
        +
        +    # Error-handling related options.
        +    $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
        +
        +    # Options for POST method.
        +    $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
        +    $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
        +
        +    # Options for getting the result.
        +    $curl->setopt(CURLOPT_FILE, \$ts_body);
        +
        +    # Send the request...
        +    my $error_code = $curl->perform();
        +    my $error_string;
        +    if ($error_code != 0) {
        +        my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
        +	$error_string = "could not get timestamp";
        +	$error_string .= ", http code: $http_code" unless $http_code == 0;
        +	$error_string .= ", curl code: $error_code";
        +	$error_string .= " ($::error_buf)" if defined($::error_buf);
        +    } else {
        +        my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
        +	if (lc($ct) ne "application/timestamp-reply"
        +	    && lc($ct) ne "application/timestamp-response") {
        +	    $error_string = "unexpected content type returned: $ct";
        +        }
        +    }
        +    return ($ts_body, $error_string);
        +
        +}
        +
        +# Print usage information and exists.
        +sub usage {
        +
        +    print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
        +    print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
        +    print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
        +    print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
        +    exit 1;
        +}
        +
        +# ----------------------------------------------------------------------
        +#   Main program
        +# ----------------------------------------------------------------------
        +
        +# Getting command-line options (default comes from TSGET environment variable).
        +my $getopt_arg =  "h:e:o:vdk:p:c:C:P:r:g:";
        +if (exists $ENV{TSGET}) {
        +    my @old_argv = @ARGV;
        +    @ARGV = split /\s+/, $ENV{TSGET};
        +    getopts($getopt_arg, \%options) or usage;
        +    @ARGV = @old_argv;
        +}
        +getopts($getopt_arg, \%options) or usage;
        +
        +# Checking argument consistency.
        +if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
        +    || (@ARGV > 1 && exists($options{o}))) {
        +    print STDERR "Inconsistent command line options.\n";
        +    usage;
        +}
        +# Setting defaults.
        +@ARGV = ("-") unless @ARGV != 0;
        +$options{e} = ".tsr" unless defined($options{e});
        +
        +# Processing requests.
        +my $curl = create_curl $options{h};
        +undef $/;   # For reading whole files.
        +REQUEST: foreach (@ARGV) {
        +    my $input = $_;
        +    my ($base, $path) = fileparse($input, '\.[^.]*');
        +    my $output_base = $base . $options{e};
        +    my $output = defined($options{o}) ? $options{o} : $path . $output_base;
        +
        +    STDERR->printflush("$input: ") if $options{v};
        +    # Read request.
        +    my $body;
        +    if ($input eq "-") {
        +	# Read the request from STDIN;
        +	$body = <STDIN>;
        +    } else {
        +	# Read the request from file.
        +        open INPUT, "<" . $input
        +	    or warn("$input: could not open input file: $!\n"), next REQUEST;
        +        $body = <INPUT>;
        +        close INPUT
        +	    or warn("$input: could not close input file: $!\n"), next REQUEST;
        +    }
        +
        +    # Send request.
        +    STDERR->printflush("sending request") if $options{v};
        +
        +    my ($ts_body, $error) = get_timestamp $curl, \$body;
        +    if (defined($error)) {
        +	die "$input: fatal error: $error\n";
        +    }
        +    STDERR->printflush(", reply received") if $options{v};
        +
        +    # Write response.
        +    if ($output eq "-") {
        +	# Write to STDOUT.
        +        print $ts_body;
        +    } else {
        +	# Write to file.
        +        open OUTPUT, ">", $output
        +	    or warn("$output: could not open output file: $!\n"), next REQUEST;
        +        print OUTPUT $ts_body;
        +        close OUTPUT
        +	    or warn("$output: could not close output file: $!\n"), next REQUEST;
        +    }
        +    STDERR->printflush(", $output written.\n") if $options{v};
        +}
        +$curl->cleanup();
        +WWW::Curl::Easy::global_cleanup();
        diff --git a/vendor/openssl/openssl/apps/verify.c b/vendor/openssl/openssl/apps/verify.c
        new file mode 100644
        index 000000000..893670ff4
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/verify.c
        @@ -0,0 +1,362 @@
        +/* apps/verify.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/pem.h>
        +
        +#undef PROG
        +#define PROG	verify_main
        +
        +static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
        +static int check(X509_STORE *ctx, char *file,
        +		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
        +		STACK_OF(X509_CRL) *crls, ENGINE *e);
        +static int v_verbose=0, vflags = 0;
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int i,ret=1, badarg = 0;
        +	char *CApath=NULL,*CAfile=NULL;
        +	char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
        +	STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
        +	STACK_OF(X509_CRL) *crls = NULL;
        +	X509_STORE *cert_ctx=NULL;
        +	X509_LOOKUP *lookup=NULL;
        +	X509_VERIFY_PARAM *vpm = NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	cert_ctx=X509_STORE_new();
        +	if (cert_ctx == NULL) goto end;
        +	X509_STORE_set_verify_cb(cert_ctx,cb);
        +
        +	ERR_load_crypto_strings();
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +
        +	argc--;
        +	argv++;
        +	for (;;)
        +		{
        +		if (argc >= 1)
        +			{
        +			if (strcmp(*argv,"-CApath") == 0)
        +				{
        +				if (argc-- < 1) goto end;
        +				CApath= *(++argv);
        +				}
        +			else if (strcmp(*argv,"-CAfile") == 0)
        +				{
        +				if (argc-- < 1) goto end;
        +				CAfile= *(++argv);
        +				}
        +			else if (args_verify(&argv, &argc, &badarg, bio_err,
        +									&vpm))
        +				{
        +				if (badarg)
        +					goto end;
        +				continue;
        +				}
        +			else if (strcmp(*argv,"-untrusted") == 0)
        +				{
        +				if (argc-- < 1) goto end;
        +				untfile= *(++argv);
        +				}
        +			else if (strcmp(*argv,"-trusted") == 0)
        +				{
        +				if (argc-- < 1) goto end;
        +				trustfile= *(++argv);
        +				}
        +			else if (strcmp(*argv,"-CRLfile") == 0)
        +				{
        +				if (argc-- < 1) goto end;
        +				crlfile= *(++argv);
        +				}
        +#ifndef OPENSSL_NO_ENGINE
        +			else if (strcmp(*argv,"-engine") == 0)
        +				{
        +				if (--argc < 1) goto end;
        +				engine= *(++argv);
        +				}
        +#endif
        +			else if (strcmp(*argv,"-help") == 0)
        +				goto end;
        +			else if (strcmp(*argv,"-verbose") == 0)
        +				v_verbose=1;
        +			else if (argv[0][0] == '-')
        +				goto end;
        +			else
        +				break;
        +			argc--;
        +			argv++;
        +			}
        +		else
        +			break;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (vpm)
        +		X509_STORE_set1_param(cert_ctx, vpm);
        +
        +	lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
        +	if (lookup == NULL) abort();
        +	if (CAfile) {
        +		i=X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM);
        +		if(!i) {
        +			BIO_printf(bio_err, "Error loading file %s\n", CAfile);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
        +		
        +	lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
        +	if (lookup == NULL) abort();
        +	if (CApath) {
        +		i=X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM);
        +		if(!i) {
        +			BIO_printf(bio_err, "Error loading directory %s\n", CApath);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +		}
        +	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
        +
        +	ERR_clear_error();
        +
        +	if(untfile)
        +		{
        +		untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
        +					NULL, e, "untrusted certificates");
        +		if(!untrusted)
        +			goto end;
        +		}
        +
        +	if(trustfile)
        +		{
        +		trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
        +					NULL, e, "trusted certificates");
        +		if(!trusted)
        +			goto end;
        +		}
        +
        +	if(crlfile)
        +		{
        +		crls = load_crls(bio_err, crlfile, FORMAT_PEM,
        +					NULL, e, "other CRLs");
        +		if(!crls)
        +			goto end;
        +		}
        +
        +	ret = 0;
        +	if (argc < 1)
        +		{ 
        +		if (1 != check(cert_ctx, NULL, untrusted, trusted, crls, e))
        +			ret = -1;
        +		}
        +	else
        +		{
        +		for (i=0; i<argc; i++)
        +			if (1 != check(cert_ctx,argv[i], untrusted, trusted, crls, e))
        +				ret = -1;
        +		}
        +
        +end:
        +	if (ret == 1) {
        +		BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
        +		BIO_printf(bio_err," [-attime timestamp]");
        +#ifndef OPENSSL_NO_ENGINE
        +		BIO_printf(bio_err," [-engine e]");
        +#endif
        +		BIO_printf(bio_err," cert1 cert2 ...\n");
        +
        +		BIO_printf(bio_err,"recognized usages:\n");
        +		for(i = 0; i < X509_PURPOSE_get_count(); i++)
        +			{
        +			X509_PURPOSE *ptmp;
        +			ptmp = X509_PURPOSE_get0(i);
        +			BIO_printf(bio_err, "\t%-10s\t%s\n",
        +				   X509_PURPOSE_get0_sname(ptmp),
        +				   X509_PURPOSE_get0_name(ptmp));
        +			}
        +	}
        +	if (vpm) X509_VERIFY_PARAM_free(vpm);
        +	if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
        +	sk_X509_pop_free(untrusted, X509_free);
        +	sk_X509_pop_free(trusted, X509_free);
        +	sk_X509_CRL_pop_free(crls, X509_CRL_free);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret < 0 ? 2 : ret);
        +	}
        +
        +static int check(X509_STORE *ctx, char *file,
        +		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
        +		STACK_OF(X509_CRL) *crls, ENGINE *e)
        +	{
        +	X509 *x=NULL;
        +	int i=0,ret=0;
        +	X509_STORE_CTX *csc;
        +
        +	x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file");
        +	if (x == NULL)
        +		goto end;
        +	fprintf(stdout,"%s: ",(file == NULL)?"stdin":file);
        +
        +	csc = X509_STORE_CTX_new();
        +	if (csc == NULL)
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	X509_STORE_set_flags(ctx, vflags);
        +	if(!X509_STORE_CTX_init(csc,ctx,x,uchain))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
        +	if (crls)
        +		X509_STORE_CTX_set0_crls(csc, crls);
        +	i=X509_verify_cert(csc);
        +	X509_STORE_CTX_free(csc);
        +
        +	ret=0;
        +end:
        +	if (i > 0)
        +		{
        +		fprintf(stdout,"OK\n");
        +		ret=1;
        +		}
        +	else
        +		ERR_print_errors(bio_err);
        +	if (x != NULL) X509_free(x);
        +
        +	return(ret);
        +	}
        +
        +static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
        +	{
        +	int cert_error = X509_STORE_CTX_get_error(ctx);
        +	X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
        +
        +	if (!ok)
        +		{
        +		if (current_cert)
        +			{
        +			X509_NAME_print_ex_fp(stdout,
        +				X509_get_subject_name(current_cert),
        +				0, XN_FLAG_ONELINE);
        +			printf("\n");
        +			}
        +		printf("%serror %d at %d depth lookup:%s\n",
        +			X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
        +			cert_error,
        +			X509_STORE_CTX_get_error_depth(ctx),
        +			X509_verify_cert_error_string(cert_error));
        +		switch(cert_error)
        +			{
        +			case X509_V_ERR_NO_EXPLICIT_POLICY:
        +				policies_print(NULL, ctx);
        +			case X509_V_ERR_CERT_HAS_EXPIRED:
        +
        +			/* since we are just checking the certificates, it is
        +			 * ok if they are self signed. But we should still warn
        +			 * the user.
        +			 */
        +
        +			case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        +			/* Continue after extension errors too */
        +			case X509_V_ERR_INVALID_CA:
        +			case X509_V_ERR_INVALID_NON_CA:
        +			case X509_V_ERR_PATH_LENGTH_EXCEEDED:
        +			case X509_V_ERR_INVALID_PURPOSE:
        +			case X509_V_ERR_CRL_HAS_EXPIRED:
        +			case X509_V_ERR_CRL_NOT_YET_VALID:
        +			case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
        +			ok = 1;
        +
        +			}
        +
        +		return ok;
        +
        +		}
        +	if (cert_error == X509_V_OK && ok == 2)
        +		policies_print(NULL, ctx);
        +	if (!v_verbose)
        +		ERR_clear_error();
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/apps/version.c b/vendor/openssl/openssl/apps/version.c
        new file mode 100644
        index 000000000..e9555cbde
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/version.c
        @@ -0,0 +1,217 @@
        +/* apps/version.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "apps.h"
        +#include <openssl/evp.h>
        +#include <openssl/crypto.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_MD2
        +# include <openssl/md2.h>
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +# include <openssl/rc4.h>
        +#endif
        +#ifndef OPENSSL_NO_DES
        +# include <openssl/des.h>
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +# include <openssl/idea.h>
        +#endif
        +#ifndef OPENSSL_NO_BF
        +# include <openssl/blowfish.h>
        +#endif
        +
        +#undef PROG
        +#define PROG	version_main
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	int i,ret=0;
        +	int cflags=0,version=0,date=0,options=0,platform=0,dir=0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	if (argc == 1) version=1;
        +	for (i=1; i<argc; i++)
        +		{
        +		if (strcmp(argv[i],"-v") == 0)
        +			version=1;	
        +		else if (strcmp(argv[i],"-b") == 0)
        +			date=1;
        +		else if (strcmp(argv[i],"-f") == 0)
        +			cflags=1;
        +		else if (strcmp(argv[i],"-o") == 0)
        +			options=1;
        +		else if (strcmp(argv[i],"-p") == 0)
        +			platform=1;
        +		else if (strcmp(argv[i],"-d") == 0)
        +			dir=1;
        +		else if (strcmp(argv[i],"-a") == 0)
        +			date=version=cflags=options=platform=dir=1;
        +		else
        +			{
        +			BIO_printf(bio_err,"usage:version -[avbofpd]\n");
        +			ret=1;
        +			goto end;
        +			}
        +		}
        +
        +	if (version)
        +		{
        +		if (SSLeay() == SSLEAY_VERSION_NUMBER)
        +			{
        +			printf("%s\n",SSLeay_version(SSLEAY_VERSION));
        +			}
        +		else
        +			{
        +			printf("%s (Library: %s)\n",
        +				OPENSSL_VERSION_TEXT,
        +				SSLeay_version(SSLEAY_VERSION));
        +			}
        +		}
        +	if (date)    printf("%s\n",SSLeay_version(SSLEAY_BUILT_ON));
        +	if (platform) printf("%s\n",SSLeay_version(SSLEAY_PLATFORM));
        +	if (options) 
        +		{
        +		printf("options:  ");
        +		printf("%s ",BN_options());
        +#ifndef OPENSSL_NO_MD2
        +		printf("%s ",MD2_options());
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +		printf("%s ",RC4_options());
        +#endif
        +#ifndef OPENSSL_NO_DES
        +		printf("%s ",DES_options());
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +		printf("%s ",idea_options());
        +#endif
        +#ifndef OPENSSL_NO_BF
        +		printf("%s ",BF_options());
        +#endif
        +		printf("\n");
        +		}
        +	if (cflags)  printf("%s\n",SSLeay_version(SSLEAY_CFLAGS));
        +	if (dir)  printf("%s\n",SSLeay_version(SSLEAY_DIR));
        +end:
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        diff --git a/vendor/openssl/openssl/apps/vms_decc_init.c b/vendor/openssl/openssl/apps/vms_decc_init.c
        new file mode 100644
        index 000000000..f512c8f1b
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/vms_decc_init.c
        @@ -0,0 +1,188 @@
        +#if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
        + defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
        +# define USE_DECC_INIT 1
        +#endif
        +
        +#ifdef USE_DECC_INIT
        +
        +/*
        + * 2010-04-26 SMS.
        + *
        + *----------------------------------------------------------------------
        + *
        + *       decc_init()
        + *
        + *    On non-VAX systems, uses LIB$INITIALIZE to set a collection of C
        + *    RTL features without using the DECC$* logical name method.
        + *
        + *----------------------------------------------------------------------
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <unixlib.h>
        +
        +
        +/* Global storage. */
        +
        +/* Flag to sense if decc_init() was called. */
        +
        +int decc_init_done = -1;
        +
        +
        +/* Structure to hold a DECC$* feature name and its desired value. */
        +
        +typedef struct
        +{
        +    char *name;
        +    int value;
        +} decc_feat_t;
        +
        +
        +/* Array of DECC$* feature names and their desired values.
        + * Note: DECC$ARGV_PARSE_STYLE is the urgent one.
        + */
        +
        +decc_feat_t decc_feat_array[] =
        +{
        + /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
        + { "DECC$ARGV_PARSE_STYLE", 1 },
        +
        + /* Preserve case for file names on ODS5 disks. */
        + { "DECC$EFS_CASE_PRESERVE", 1 },
        +
        + /* Enable multiple dots (and most characters) in ODS5 file names,
        +  * while preserving VMS-ness of ";version".
        +  */
        + { "DECC$EFS_CHARSET", 1 },
        +
        + /* List terminator. */
        + { (char *)NULL, 0 }
        +};
        +
        +
        +/* LIB$INITIALIZE initialization function. */
        +
        +static void decc_init( void)
        +{
        +    char *openssl_debug_decc_init;
        +    int verbose = 0;
        +    int feat_index;
        +    int feat_value;
        +    int feat_value_max;
        +    int feat_value_min;
        +    int i;
        +    int sts;
        +
        +    /* Get debug option. */
        +    openssl_debug_decc_init = getenv( "OPENSSL_DEBUG_DECC_INIT");
        +    if (openssl_debug_decc_init != NULL)
        +    {
        +        verbose = strtol( openssl_debug_decc_init, NULL, 10);
        +        if (verbose <= 0)
        +        {
        +            verbose = 1;
        +        }
        +    }
        +
        +    /* Set the global flag to indicate that LIB$INITIALIZE worked. */
        +    decc_init_done = 1;
        +
        +    /* Loop through all items in the decc_feat_array[]. */
        +
        +    for (i = 0; decc_feat_array[ i].name != NULL; i++)
        +    {
        +        /* Get the feature index. */
        +        feat_index = decc$feature_get_index( decc_feat_array[ i].name);
        +        if (feat_index >= 0)
        +        {
        +            /* Valid item.  Collect its properties. */
        +            feat_value = decc$feature_get_value( feat_index, 1);
        +            feat_value_min = decc$feature_get_value( feat_index, 2);
        +            feat_value_max = decc$feature_get_value( feat_index, 3);
        +
        +            /* Check the validity of our desired value. */
        +            if ((decc_feat_array[ i].value >= feat_value_min) &&
        +             (decc_feat_array[ i].value <= feat_value_max))
        +            {
        +                /* Valid value.  Set it if necessary. */
        +                if (feat_value != decc_feat_array[ i].value)
        +                {
        +                    sts = decc$feature_set_value( feat_index,
        +                     1,
        +                     decc_feat_array[ i].value);
        +
        +                     if (verbose > 1)
        +                     {
        +                         fprintf( stderr, " %s = %d, sts = %d.\n",
        +                          decc_feat_array[ i].name,
        +                          decc_feat_array[ i].value,
        +                          sts);
        +                     }
        +                }
        +            }
        +            else
        +            {
        +                /* Invalid DECC feature value. */
        +                fprintf( stderr,
        +                 " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
        +                 feat_value,
        +                 feat_value_min, decc_feat_array[ i].name, feat_value_max);
        +            }
        +        }
        +        else
        +        {
        +            /* Invalid DECC feature name. */
        +            fprintf( stderr,
        +             " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[ i].name);
        +        }
        +    }
        +
        +    if (verbose > 0)
        +    {
        +        fprintf( stderr, " DECC_INIT complete.\n");
        +    }
        +}
        +
        +/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
        +
        +#pragma nostandard
        +
        +/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
        + * other attributes.  Note that "nopic" is significant only on VAX.
        + */
        +#pragma extern_model save
        +
        +#if __INITIAL_POINTER_SIZE == 64
        +# define PSECT_ALIGN 3
        +#else
        +# define PSECT_ALIGN 2
        +#endif
        +
        +#pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
        +const int spare[ 8] = { 0 };
        +
        +#pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
        +void (*const x_decc_init)() = decc_init;
        +
        +#pragma extern_model restore
        +
        +/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
        +
        +#pragma extern_model save
        +
        +int LIB$INITIALIZE( void);
        +
        +#pragma extern_model strict_refdef
        +int dmy_lib$initialize = (int) LIB$INITIALIZE;
        +
        +#pragma extern_model restore
        +
        +#pragma standard
        +
        +#else /* def USE_DECC_INIT */
        +
        +/* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
        +int decc_init_dummy( void);
        +
        +#endif /* def USE_DECC_INIT */
        diff --git a/vendor/openssl/openssl/apps/winrand.c b/vendor/openssl/openssl/apps/winrand.c
        new file mode 100644
        index 000000000..59bede3d7
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/winrand.c
        @@ -0,0 +1,148 @@
        +/* apps/winrand.c */
        +/* ====================================================================
        + * 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).
        + *
        + */
        +
        +/* Usage: winrand [filename]
        + *
        + * Collects entropy from mouse movements and other events and writes
        + * random data to filename or .rnd
        + */
        +
        +#include <windows.h>
        +#include <openssl/opensslv.h>
        +#include <openssl/rand.h>
        +
        +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
        +const char *filename;
        +
        +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        +        PSTR cmdline, int iCmdShow)
        +	{
        +	static char appname[] = "OpenSSL";
        +	HWND hwnd;
        +	MSG msg;
        +	WNDCLASSEX wndclass;
        +        char buffer[200];
        +
        +        if (cmdline[0] == '\0')
        +                filename = RAND_file_name(buffer, sizeof buffer);
        +        else
        +                filename = cmdline;
        +
        +        RAND_load_file(filename, -1);
        +
        +	wndclass.cbSize = sizeof(wndclass);
        +	wndclass.style = CS_HREDRAW | CS_VREDRAW;
        +	wndclass.lpfnWndProc = WndProc;
        +	wndclass.cbClsExtra = 0;
        +	wndclass.cbWndExtra = 0;
        +	wndclass.hInstance = hInstance;
        +	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        +	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        +	wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        +	wndclass.lpszMenuName = NULL;
        +        wndclass.lpszClassName = appname;
        +	wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        +	RegisterClassEx(&wndclass);
        +
        +        hwnd = CreateWindow(appname, OPENSSL_VERSION_TEXT,
        +		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        +		CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
        +
        +	ShowWindow(hwnd, iCmdShow);
        +	UpdateWindow(hwnd);
        +
        +
        +	while (GetMessage(&msg, NULL, 0, 0))
        +		{
        +		TranslateMessage(&msg);
        +		DispatchMessage(&msg);
        +		}
        +
        +	return msg.wParam;
        +	}
        +
        +LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
        +	{
        +        HDC hdc;
        +	PAINTSTRUCT ps;
        +        RECT rect;
        +        static int seeded = 0;
        +
        +	switch (iMsg)
        +		{
        +	case WM_PAINT:
        +		hdc = BeginPaint(hwnd, &ps);
        +		GetClientRect(hwnd, &rect);
        +                DrawText(hdc, "Seeding the PRNG. Please move the mouse!", -1,
        +			&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        +		EndPaint(hwnd, &ps);
        +		return 0;
        +		
        +        case WM_DESTROY:
        +                PostQuitMessage(0);
        +                return 0;
        +                }
        +
        +        if (RAND_event(iMsg, wParam, lParam) == 1 && seeded == 0)
        +                {
        +                seeded = 1;
        +                if (RAND_write_file(filename) <= 0)
        +                        MessageBox(hwnd, "Couldn't write random file!",
        +				"OpenSSL", MB_OK | MB_ICONERROR);
        +                PostQuitMessage(0);
        +                }
        +
        +	return DefWindowProc(hwnd, iMsg, wParam, lParam);
        +	}
        diff --git a/vendor/openssl/openssl/apps/x509.c b/vendor/openssl/openssl/apps/x509.c
        new file mode 100644
        index 000000000..3863ab968
        --- /dev/null
        +++ b/vendor/openssl/openssl/apps/x509.c
        @@ -0,0 +1,1310 @@
        +/* apps/x509.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 <assert.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#ifdef OPENSSL_NO_STDIO
        +#define APPS_WIN16
        +#endif
        +#include "apps.h"
        +#include <openssl/bio.h>
        +#include <openssl/asn1.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/objects.h>
        +#include <openssl/pem.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#undef PROG
        +#define PROG x509_main
        +
        +#undef POSTFIX
        +#define	POSTFIX	".srl"
        +#define DEF_DAYS	30
        +
        +static const char *x509_usage[]={
        +"usage: x509 args\n",
        +" -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
        +" -outform arg    - output format - default PEM (one of DER, NET or PEM)\n",
        +" -keyform arg    - private key format - default PEM\n",
        +" -CAform arg     - CA format - default PEM\n",
        +" -CAkeyform arg  - CA key format - default PEM\n",
        +" -in arg         - input file - default stdin\n",
        +" -out arg        - output file - default stdout\n",
        +" -passin arg     - private key password source\n",
        +" -serial         - print serial number value\n",
        +" -subject_hash   - print subject hash value\n",
        +#ifndef OPENSSL_NO_MD5
        +" -subject_hash_old   - print old-style (MD5) subject hash value\n",
        +#endif
        +" -issuer_hash    - print issuer hash value\n",
        +#ifndef OPENSSL_NO_MD5
        +" -issuer_hash_old    - print old-style (MD5) issuer hash value\n",
        +#endif
        +" -hash           - synonym for -subject_hash\n",
        +" -subject        - print subject DN\n",
        +" -issuer         - print issuer DN\n",
        +" -email          - print email address(es)\n",
        +" -startdate      - notBefore field\n",
        +" -enddate        - notAfter field\n",
        +" -purpose        - print out certificate purposes\n",
        +" -dates          - both Before and After dates\n",
        +" -modulus        - print the RSA key modulus\n",
        +" -pubkey         - output the public key\n",
        +" -fingerprint    - print the certificate fingerprint\n",
        +" -alias          - output certificate alias\n",
        +" -noout          - no certificate output\n",
        +" -ocspid         - print OCSP hash values for the subject name and public key\n",
        +" -ocsp_uri       - print OCSP Responder URL(s)\n",
        +" -trustout       - output a \"trusted\" certificate\n",
        +" -clrtrust       - clear all trusted purposes\n",
        +" -clrreject      - clear all rejected purposes\n",
        +" -addtrust arg   - trust certificate for a given purpose\n",
        +" -addreject arg  - reject certificate for a given purpose\n",
        +" -setalias arg   - set certificate alias\n",
        +" -days arg       - How long till expiry of a signed certificate - def 30 days\n",
        +" -checkend arg   - check whether the cert expires in the next arg seconds\n",
        +"                   exit 1 if so, 0 if not\n",
        +" -signkey arg    - self sign cert with arg\n",
        +" -x509toreq      - output a certification request object\n",
        +" -req            - input is a certificate request, sign and output.\n",
        +" -CA arg         - set the CA certificate, must be PEM format.\n",
        +" -CAkey arg      - set the CA key, must be PEM format\n",
        +"                   missing, it is assumed to be in the CA file.\n",
        +" -CAcreateserial - create serial number file if it does not exist\n",
        +" -CAserial arg   - serial file\n",
        +" -set_serial     - serial number to use\n",
        +" -text           - print the certificate in text form\n",
        +" -C              - print out C code forms\n",
        +" -md2/-md5/-sha1/-mdc2 - digest to use\n",
        +" -extfile        - configuration file with X509V3 extensions to add\n",
        +" -extensions     - section from config file with X509V3 extensions to add\n",
        +" -clrext         - delete extensions before signing and input certificate\n",
        +" -nameopt arg    - various certificate name options\n",
        +#ifndef OPENSSL_NO_ENGINE
        +" -engine e       - use engine e, possibly a hardware device.\n",
        +#endif
        +" -certopt arg    - various certificate text options\n",
        +NULL
        +};
        +
        +static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
        +static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
        +						CONF *conf, char *section);
        +static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
        +			 X509 *x,X509 *xca,EVP_PKEY *pkey,
        +			 STACK_OF(OPENSSL_STRING) *sigopts,
        +			 char *serial, int create ,int days, int clrext,
        +			 CONF *conf, char *section, ASN1_INTEGER *sno);
        +static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
        +static int reqfile=0;
        +
        +int MAIN(int, char **);
        +
        +int MAIN(int argc, char **argv)
        +	{
        +	ENGINE *e = NULL;
        +	int ret=1;
        +	X509_REQ *req=NULL;
        +	X509 *x=NULL,*xca=NULL;
        +	ASN1_OBJECT *objtmp;
        +	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
        +	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
        +	ASN1_INTEGER *sno = NULL;
        +	int i,num,badops=0;
        +	BIO *out=NULL;
        +	BIO *STDout=NULL;
        +	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
        +	int informat,outformat,keyformat,CAformat,CAkeyformat;
        +	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
        +	char *CAkeyfile=NULL,*CAserial=NULL;
        +	char *alias=NULL;
        +	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
        +	int next_serial=0;
        +	int subject_hash=0,issuer_hash=0,ocspid=0;
        +#ifndef OPENSSL_NO_MD5
        +	int subject_hash_old=0,issuer_hash_old=0;
        +#endif
        +	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
        +	int ocsp_uri=0;
        +	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
        +	int C=0;
        +	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
        +	int pprint = 0;
        +	const char **pp;
        +	X509_STORE *ctx=NULL;
        +	X509_REQ *rq=NULL;
        +	int fingerprint=0;
        +	char buf[256];
        +	const EVP_MD *md_alg,*digest=NULL;
        +	CONF *extconf = NULL;
        +	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
        +	int need_rand = 0;
        +	int checkend=0,checkoffset=0;
        +	unsigned long nmflag = 0, certflag = 0;
        +#ifndef OPENSSL_NO_ENGINE
        +	char *engine=NULL;
        +#endif
        +
        +	reqfile=0;
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	if (!load_config(bio_err, NULL))
        +		goto end;
        +	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +	{
        +	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +	STDout = BIO_push(tmpbio, STDout);
        +	}
        +#endif
        +
        +	informat=FORMAT_PEM;
        +	outformat=FORMAT_PEM;
        +	keyformat=FORMAT_PEM;
        +	CAformat=FORMAT_PEM;
        +	CAkeyformat=FORMAT_PEM;
        +
        +	ctx=X509_STORE_new();
        +	if (ctx == NULL) goto end;
        +	X509_STORE_set_verify_cb(ctx,callb);
        +
        +	argc--;
        +	argv++;
        +	num=0;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-inform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			informat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-outform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-keyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-req") == 0)
        +			{
        +			reqfile=1;
        +			need_rand = 1;
        +			}
        +		else if (strcmp(*argv,"-CAform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-CAkeyform") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAkeyformat=str2fmt(*(++argv));
        +			}
        +		else if (strcmp(*argv,"-sigopt") == 0)
        +			{
        +			if (--argc < 1)
        +				goto bad;
        +			if (!sigopts)
        +				sigopts = sk_OPENSSL_STRING_new_null();
        +			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
        +				goto bad;
        +			}
        +		else if (strcmp(*argv,"-days") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			days=atoi(*(++argv));
        +			if (days == 0)
        +				{
        +				BIO_printf(bio_err,"bad number of days\n");
        +				goto bad;
        +				}
        +			}
        +		else if (strcmp(*argv,"-passin") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			passargin= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-extfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			extfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-extensions") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			extsect= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-signkey") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keyfile= *(++argv);
        +			sign_flag= ++num;
        +			need_rand = 1;
        +			}
        +		else if (strcmp(*argv,"-CA") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile= *(++argv);
        +			CA_flag= ++num;
        +			need_rand = 1;
        +			}
        +		else if (strcmp(*argv,"-CAkey") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAkeyfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-CAserial") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAserial= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-set_serial") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
        +				goto bad;
        +			}
        +		else if (strcmp(*argv,"-addtrust") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
        +				{
        +				BIO_printf(bio_err,
        +					"Invalid trust object value %s\n", *argv);
        +				goto bad;
        +				}
        +			if (!trust) trust = sk_ASN1_OBJECT_new_null();
        +			sk_ASN1_OBJECT_push(trust, objtmp);
        +			trustout = 1;
        +			}
        +		else if (strcmp(*argv,"-addreject") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
        +				{
        +				BIO_printf(bio_err,
        +					"Invalid reject object value %s\n", *argv);
        +				goto bad;
        +				}
        +			if (!reject) reject = sk_ASN1_OBJECT_new_null();
        +			sk_ASN1_OBJECT_push(reject, objtmp);
        +			trustout = 1;
        +			}
        +		else if (strcmp(*argv,"-setalias") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			alias= *(++argv);
        +			trustout = 1;
        +			}
        +		else if (strcmp(*argv,"-certopt") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
        +			}
        +		else if (strcmp(*argv,"-nameopt") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		else if (strcmp(*argv,"-engine") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			engine= *(++argv);
        +			}
        +#endif
        +		else if (strcmp(*argv,"-C") == 0)
        +			C= ++num;
        +		else if (strcmp(*argv,"-email") == 0)
        +			email= ++num;
        +		else if (strcmp(*argv,"-ocsp_uri") == 0)
        +			ocsp_uri= ++num;
        +		else if (strcmp(*argv,"-serial") == 0)
        +			serial= ++num;
        +		else if (strcmp(*argv,"-next_serial") == 0)
        +			next_serial= ++num;
        +		else if (strcmp(*argv,"-modulus") == 0)
        +			modulus= ++num;
        +		else if (strcmp(*argv,"-pubkey") == 0)
        +			pubkey= ++num;
        +		else if (strcmp(*argv,"-x509toreq") == 0)
        +			x509req= ++num;
        +		else if (strcmp(*argv,"-text") == 0)
        +			text= ++num;
        +		else if (strcmp(*argv,"-hash") == 0
        +			|| strcmp(*argv,"-subject_hash") == 0)
        +			subject_hash= ++num;
        +#ifndef OPENSSL_NO_MD5
        +		else if (strcmp(*argv,"-subject_hash_old") == 0)
        +			subject_hash_old= ++num;
        +#endif
        +		else if (strcmp(*argv,"-issuer_hash") == 0)
        +			issuer_hash= ++num;
        +#ifndef OPENSSL_NO_MD5
        +		else if (strcmp(*argv,"-issuer_hash_old") == 0)
        +			issuer_hash_old= ++num;
        +#endif
        +		else if (strcmp(*argv,"-subject") == 0)
        +			subject= ++num;
        +		else if (strcmp(*argv,"-issuer") == 0)
        +			issuer= ++num;
        +		else if (strcmp(*argv,"-fingerprint") == 0)
        +			fingerprint= ++num;
        +		else if (strcmp(*argv,"-dates") == 0)
        +			{
        +			startdate= ++num;
        +			enddate= ++num;
        +			}
        +		else if (strcmp(*argv,"-purpose") == 0)
        +			pprint= ++num;
        +		else if (strcmp(*argv,"-startdate") == 0)
        +			startdate= ++num;
        +		else if (strcmp(*argv,"-enddate") == 0)
        +			enddate= ++num;
        +		else if (strcmp(*argv,"-checkend") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			checkoffset=atoi(*(++argv));
        +			checkend=1;
        +			}
        +		else if (strcmp(*argv,"-noout") == 0)
        +			noout= ++num;
        +		else if (strcmp(*argv,"-trustout") == 0)
        +			trustout= 1;
        +		else if (strcmp(*argv,"-clrtrust") == 0)
        +			clrtrust= ++num;
        +		else if (strcmp(*argv,"-clrreject") == 0)
        +			clrreject= ++num;
        +		else if (strcmp(*argv,"-alias") == 0)
        +			aliasout= ++num;
        +		else if (strcmp(*argv,"-CAcreateserial") == 0)
        +			CA_createserial= ++num;
        +		else if (strcmp(*argv,"-clrext") == 0)
        +			clrext = 1;
        +#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
        +		else if (strcmp(*argv,"-crlext") == 0)
        +			{
        +			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
        +			clrext = 1;
        +			}
        +#endif
        +		else if (strcmp(*argv,"-ocspid") == 0)
        +			ocspid= ++num;
        +		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
        +			{
        +			/* ok */
        +			digest=md_alg;
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		for (pp=x509_usage; (*pp != NULL); pp++)
        +			BIO_printf(bio_err,"%s",*pp);
        +		goto end;
        +		}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +        e = setup_engine(bio_err, engine, 0);
        +#endif
        +
        +	if (need_rand)
        +		app_RAND_load_file(NULL, bio_err, 0);
        +
        +	ERR_load_crypto_strings();
        +
        +	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
        +		{
        +		BIO_printf(bio_err, "Error getting password\n");
        +		goto end;
        +		}
        +
        +	if (!X509_STORE_set_default_paths(ctx))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
        +		{ CAkeyfile=CAfile; }
        +	else if ((CA_flag) && (CAkeyfile == NULL))
        +		{
        +		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
        +		goto end;
        +		}
        +
        +	if (extfile)
        +		{
        +		long errorline = -1;
        +		X509V3_CTX ctx2;
        +		extconf = NCONF_new(NULL);
        +		if (!NCONF_load(extconf, extfile,&errorline))
        +			{
        +			if (errorline <= 0)
        +				BIO_printf(bio_err,
        +					"error loading the config file '%s'\n",
        +								extfile);
        +                	else
        +                        	BIO_printf(bio_err,
        +				       "error on line %ld of config file '%s'\n"
        +							,errorline,extfile);
        +			goto end;
        +			}
        +		if (!extsect)
        +			{
        +			extsect = NCONF_get_string(extconf, "default", "extensions");
        +			if (!extsect)
        +				{
        +				ERR_clear_error();
        +				extsect = "default";
        +				}
        +			}
        +		X509V3_set_ctx_test(&ctx2);
        +		X509V3_set_nconf(&ctx2, extconf);
        +		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
        +			{
        +			BIO_printf(bio_err,
        +				"Error Loading extension section %s\n",
        +								 extsect);
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		}
        +
        +
        +	if (reqfile)
        +		{
        +		EVP_PKEY *pkey;
        +		BIO *in;
        +
        +		if (!sign_flag && !CA_flag)
        +			{
        +			BIO_printf(bio_err,"We need a private key to sign with\n");
        +			goto end;
        +			}
        +		in=BIO_new(BIO_s_file());
        +		if (in == NULL)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		if (infile == NULL)
        +			BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
        +		else
        +			{
        +			if (BIO_read_filename(in,infile) <= 0)
        +				{
        +				perror(infile);
        +				BIO_free(in);
        +				goto end;
        +				}
        +			}
        +		req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
        +		BIO_free(in);
        +
        +		if (req == NULL)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +
        +		if (	(req->req_info == NULL) ||
        +			(req->req_info->pubkey == NULL) ||
        +			(req->req_info->pubkey->public_key == NULL) ||
        +			(req->req_info->pubkey->public_key->data == NULL))
        +			{
        +			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
        +			BIO_printf(bio_err,"It does not contain a public key\n");
        +			goto end;
        +			}
        +		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
        +	                {
        +	                BIO_printf(bio_err,"error unpacking public key\n");
        +	                goto end;
        +	                }
        +		i=X509_REQ_verify(req,pkey);
        +		EVP_PKEY_free(pkey);
        +		if (i < 0)
        +			{
        +			BIO_printf(bio_err,"Signature verification error\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +	        if (i == 0)
        +			{
        +			BIO_printf(bio_err,"Signature did not match the certificate request\n");
        +			goto end;
        +			}
        +		else
        +			BIO_printf(bio_err,"Signature ok\n");
        +
        +		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);
        +
        +		if ((x=X509_new()) == NULL) goto end;
        +
        +		if (sno == NULL)
        +			{
        +			sno = ASN1_INTEGER_new();
        +			if (!sno || !rand_serial(NULL, sno))
        +				goto end;
        +			if (!X509_set_serialNumber(x, sno)) 
        +				goto end;
        +			ASN1_INTEGER_free(sno);
        +			sno = NULL;
        +			}
        +		else if (!X509_set_serialNumber(x, sno)) 
        +			goto end;
        +
        +		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
        +		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
        +
        +		X509_gmtime_adj(X509_get_notBefore(x),0);
        +	        X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);
        +
        +		pkey = X509_REQ_get_pubkey(req);
        +		X509_set_pubkey(x,pkey);
        +		EVP_PKEY_free(pkey);
        +		}
        +	else
        +		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");
        +
        +	if (x == NULL) goto end;
        +	if (CA_flag)
        +		{
        +		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
        +		if (xca == NULL) goto end;
        +		}
        +
        +	if (!noout || text || next_serial)
        +		{
        +		OBJ_create("2.99999.3",
        +			"SET.ex3","SET x509v3 extension 3");
        +
        +		out=BIO_new(BIO_s_file());
        +		if (out == NULL)
        +			{
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +		if (outfile == NULL)
        +			{
        +			BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +#ifdef OPENSSL_SYS_VMS
        +			{
        +			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        +			out = BIO_push(tmpbio, out);
        +			}
        +#endif
        +			}
        +		else
        +			{
        +			if (BIO_write_filename(out,outfile) <= 0)
        +				{
        +				perror(outfile);
        +				goto end;
        +				}
        +			}
        +		}
        +
        +	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);
        +
        +	if (clrtrust) X509_trust_clear(x);
        +	if (clrreject) X509_reject_clear(x);
        +
        +	if (trust)
        +		{
        +		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
        +			{
        +			objtmp = sk_ASN1_OBJECT_value(trust, i);
        +			X509_add1_trust_object(x, objtmp);
        +			}
        +		}
        +
        +	if (reject)
        +		{
        +		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
        +			{
        +			objtmp = sk_ASN1_OBJECT_value(reject, i);
        +			X509_add1_reject_object(x, objtmp);
        +			}
        +		}
        +
        +	if (num)
        +		{
        +		for (i=1; i<=num; i++)
        +			{
        +			if (issuer == i)
        +				{
        +				print_name(STDout, "issuer= ",
        +					X509_get_issuer_name(x), nmflag);
        +				}
        +			else if (subject == i) 
        +				{
        +				print_name(STDout, "subject= ",
        +					X509_get_subject_name(x), nmflag);
        +				}
        +			else if (serial == i)
        +				{
        +				BIO_printf(STDout,"serial=");
        +				i2a_ASN1_INTEGER(STDout,
        +					X509_get_serialNumber(x));
        +				BIO_printf(STDout,"\n");
        +				}
        +			else if (next_serial == i)
        +				{
        +				BIGNUM *bnser;
        +				ASN1_INTEGER *ser;
        +				ser = X509_get_serialNumber(x);
        +				bnser = ASN1_INTEGER_to_BN(ser, NULL);
        +				if (!bnser)
        +					goto end;
        +				if (!BN_add_word(bnser, 1))
        +					goto end;
        +				ser = BN_to_ASN1_INTEGER(bnser, NULL);
        +				if (!ser)
        +					goto end;
        +				BN_free(bnser);
        +				i2a_ASN1_INTEGER(out, ser);
        +				ASN1_INTEGER_free(ser);
        +				BIO_puts(out, "\n");
        +				}
        +			else if ((email == i) || (ocsp_uri == i))
        +				{
        +				int j;
        +				STACK_OF(OPENSSL_STRING) *emlst;
        +				if (email == i)
        +					emlst = X509_get1_email(x);
        +				else
        +					emlst = X509_get1_ocsp(x);
        +				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
        +					BIO_printf(STDout, "%s\n",
        +						   sk_OPENSSL_STRING_value(emlst, j));
        +				X509_email_free(emlst);
        +				}
        +			else if (aliasout == i)
        +				{
        +				unsigned char *alstr;
        +				alstr = X509_alias_get0(x, NULL);
        +				if (alstr) BIO_printf(STDout,"%s\n", alstr);
        +				else BIO_puts(STDout,"<No Alias>\n");
        +				}
        +			else if (subject_hash == i)
        +				{
        +				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
        +				}
        +#ifndef OPENSSL_NO_MD5
        +			else if (subject_hash_old == i)
        +				{
        +				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
        +				}
        +#endif
        +			else if (issuer_hash == i)
        +				{
        +				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
        +				}
        +#ifndef OPENSSL_NO_MD5
        +			else if (issuer_hash_old == i)
        +				{
        +				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
        +				}
        +#endif
        +			else if (pprint == i)
        +				{
        +				X509_PURPOSE *ptmp;
        +				int j;
        +				BIO_printf(STDout, "Certificate purposes:\n");
        +				for (j = 0; j < X509_PURPOSE_get_count(); j++)
        +					{
        +					ptmp = X509_PURPOSE_get0(j);
        +					purpose_print(STDout, x, ptmp);
        +					}
        +				}
        +			else
        +				if (modulus == i)
        +				{
        +				EVP_PKEY *pkey;
        +
        +				pkey=X509_get_pubkey(x);
        +				if (pkey == NULL)
        +					{
        +					BIO_printf(bio_err,"Modulus=unavailable\n");
        +					ERR_print_errors(bio_err);
        +					goto end;
        +					}
        +				BIO_printf(STDout,"Modulus=");
        +#ifndef OPENSSL_NO_RSA
        +				if (pkey->type == EVP_PKEY_RSA)
        +					BN_print(STDout,pkey->pkey.rsa->n);
        +				else
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +				if (pkey->type == EVP_PKEY_DSA)
        +					BN_print(STDout,pkey->pkey.dsa->pub_key);
        +				else
        +#endif
        +					BIO_printf(STDout,"Wrong Algorithm type");
        +				BIO_printf(STDout,"\n");
        +				EVP_PKEY_free(pkey);
        +				}
        +			else
        +				if (pubkey == i)
        +				{
        +				EVP_PKEY *pkey;
        +
        +				pkey=X509_get_pubkey(x);
        +				if (pkey == NULL)
        +					{
        +					BIO_printf(bio_err,"Error getting public key\n");
        +					ERR_print_errors(bio_err);
        +					goto end;
        +					}
        +				PEM_write_bio_PUBKEY(STDout, pkey);
        +				EVP_PKEY_free(pkey);
        +				}
        +			else
        +				if (C == i)
        +				{
        +				unsigned char *d;
        +				char *m;
        +				int y,z;
        +
        +				X509_NAME_oneline(X509_get_subject_name(x),
        +					buf,sizeof buf);
        +				BIO_printf(STDout,"/* subject:%s */\n",buf);
        +				m=X509_NAME_oneline(
        +					X509_get_issuer_name(x),buf,
        +					sizeof buf);
        +				BIO_printf(STDout,"/* issuer :%s */\n",buf);
        +
        +				z=i2d_X509(x,NULL);
        +				m=OPENSSL_malloc(z);
        +
        +				d=(unsigned char *)m;
        +				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
        +				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
        +				d=(unsigned char *)m;
        +				for (y=0; y<z; y++)
        +					{
        +					BIO_printf(STDout,"0x%02X,",d[y]);
        +					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
        +					}
        +				if (y%16 != 0) BIO_printf(STDout,"\n");
        +				BIO_printf(STDout,"};\n");
        +
        +				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
        +				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
        +				d=(unsigned char *)m;
        +				for (y=0; y<z; y++)
        +					{
        +					BIO_printf(STDout,"0x%02X,",d[y]);
        +					if ((y & 0x0f) == 0x0f)
        +						BIO_printf(STDout,"\n");
        +					}
        +				if (y%16 != 0) BIO_printf(STDout,"\n");
        +				BIO_printf(STDout,"};\n");
        +
        +				z=i2d_X509(x,&d);
        +				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
        +				d=(unsigned char *)m;
        +				for (y=0; y<z; y++)
        +					{
        +					BIO_printf(STDout,"0x%02X,",d[y]);
        +					if ((y & 0x0f) == 0x0f)
        +						BIO_printf(STDout,"\n");
        +					}
        +				if (y%16 != 0) BIO_printf(STDout,"\n");
        +				BIO_printf(STDout,"};\n");
        +
        +				OPENSSL_free(m);
        +				}
        +			else if (text == i)
        +				{
        +				X509_print_ex(STDout,x,nmflag, certflag);
        +				}
        +			else if (startdate == i)
        +				{
        +				BIO_puts(STDout,"notBefore=");
        +				ASN1_TIME_print(STDout,X509_get_notBefore(x));
        +				BIO_puts(STDout,"\n");
        +				}
        +			else if (enddate == i)
        +				{
        +				BIO_puts(STDout,"notAfter=");
        +				ASN1_TIME_print(STDout,X509_get_notAfter(x));
        +				BIO_puts(STDout,"\n");
        +				}
        +			else if (fingerprint == i)
        +				{
        +				int j;
        +				unsigned int n;
        +				unsigned char md[EVP_MAX_MD_SIZE];
        +				const EVP_MD *fdig = digest;
        +
        +				if (!fdig)
        +					fdig = EVP_sha1();
        +
        +				if (!X509_digest(x,fdig,md,&n))
        +					{
        +					BIO_printf(bio_err,"out of memory\n");
        +					goto end;
        +					}
        +				BIO_printf(STDout,"%s Fingerprint=",
        +						OBJ_nid2sn(EVP_MD_type(fdig)));
        +				for (j=0; j<(int)n; j++)
        +					{
        +					BIO_printf(STDout,"%02X%c",md[j],
        +						(j+1 == (int)n)
        +						?'\n':':');
        +					}
        +				}
        +
        +			/* should be in the library */
        +			else if ((sign_flag == i) && (x509req == 0))
        +				{
        +				BIO_printf(bio_err,"Getting Private key\n");
        +				if (Upkey == NULL)
        +					{
        +					Upkey=load_key(bio_err,
        +						keyfile, keyformat, 0,
        +						passin, e, "Private key");
        +					if (Upkey == NULL) goto end;
        +					}
        +
        +				assert(need_rand);
        +				if (!sign(x,Upkey,days,clrext,digest,
        +						 extconf, extsect)) goto end;
        +				}
        +			else if (CA_flag == i)
        +				{
        +				BIO_printf(bio_err,"Getting CA Private Key\n");
        +				if (CAkeyfile != NULL)
        +					{
        +					CApkey=load_key(bio_err,
        +						CAkeyfile, CAkeyformat,
        +						0, passin, e,
        +						"CA Private Key");
        +					if (CApkey == NULL) goto end;
        +					}
        +				
        +				assert(need_rand);
        +				if (!x509_certify(ctx,CAfile,digest,x,xca,
        +					CApkey, sigopts,
        +					CAserial,CA_createserial,days, clrext,
        +					extconf, extsect, sno))
        +					goto end;
        +				}
        +			else if (x509req == i)
        +				{
        +				EVP_PKEY *pk;
        +
        +				BIO_printf(bio_err,"Getting request Private Key\n");
        +				if (keyfile == NULL)
        +					{
        +					BIO_printf(bio_err,"no request key file specified\n");
        +					goto end;
        +					}
        +				else
        +					{
        +					pk=load_key(bio_err,
        +						keyfile, keyformat, 0,
        +						passin, e, "request key");
        +					if (pk == NULL) goto end;
        +					}
        +
        +				BIO_printf(bio_err,"Generating certificate request\n");
        +
        +				rq=X509_to_X509_REQ(x,pk,digest);
        +				EVP_PKEY_free(pk);
        +				if (rq == NULL)
        +					{
        +					ERR_print_errors(bio_err);
        +					goto end;
        +					}
        +				if (!noout)
        +					{
        +					X509_REQ_print(out,rq);
        +					PEM_write_bio_X509_REQ(out,rq);
        +					}
        +				noout=1;
        +				}
        +			else if (ocspid == i)
        +				{
        +				X509_ocspid_print(out, x);
        +				}
        +			}
        +		}
        +
        +	if (checkend)
        +		{
        +		time_t tcheck=time(NULL) + checkoffset;
        +
        +		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
        +			{
        +			BIO_printf(out,"Certificate will expire\n");
        +			ret=1;
        +			}
        +		else
        +			{
        +			BIO_printf(out,"Certificate will not expire\n");
        +			ret=0;
        +			}
        +		goto end;
        +		}
        +
        +	if (noout)
        +		{
        +		ret=0;
        +		goto end;
        +		}
        +
        +	if 	(outformat == FORMAT_ASN1)
        +		i=i2d_X509_bio(out,x);
        +	else if (outformat == FORMAT_PEM)
        +		{
        +		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
        +		else i=PEM_write_bio_X509(out,x);
        +		}
        +	else if (outformat == FORMAT_NETSCAPE)
        +		{
        +		NETSCAPE_X509 nx;
        +		ASN1_OCTET_STRING hdr;
        +
        +		hdr.data=(unsigned char *)NETSCAPE_CERT_HDR;
        +		hdr.length=strlen(NETSCAPE_CERT_HDR);
        +		nx.header= &hdr;
        +		nx.cert=x;
        +
        +		i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx);
        +		}
        +	else	{
        +		BIO_printf(bio_err,"bad output format specified for outfile\n");
        +		goto end;
        +		}
        +	if (!i)
        +		{
        +		BIO_printf(bio_err,"unable to write certificate\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	ret=0;
        +end:
        +	if (need_rand)
        +		app_RAND_write_file(NULL, bio_err);
        +	OBJ_cleanup();
        +	NCONF_free(extconf);
        +	BIO_free_all(out);
        +	BIO_free_all(STDout);
        +	X509_STORE_free(ctx);
        +	X509_REQ_free(req);
        +	X509_free(x);
        +	X509_free(xca);
        +	EVP_PKEY_free(Upkey);
        +	EVP_PKEY_free(CApkey);
        +	if (sigopts)
        +		sk_OPENSSL_STRING_free(sigopts);
        +	X509_REQ_free(rq);
        +	ASN1_INTEGER_free(sno);
        +	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
        +	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
        +	if (passin) OPENSSL_free(passin);
        +	apps_shutdown();
        +	OPENSSL_EXIT(ret);
        +	}
        +
        +static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create)
        +	{
        +	char *buf = NULL, *p;
        +	ASN1_INTEGER *bs = NULL;
        +	BIGNUM *serial = NULL;
        +	size_t len;
        +
        +	len = ((serialfile == NULL)
        +		?(strlen(CAfile)+strlen(POSTFIX)+1)
        +		:(strlen(serialfile)))+1;
        +	buf=OPENSSL_malloc(len);
        +	if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
        +	if (serialfile == NULL)
        +		{
        +		BUF_strlcpy(buf,CAfile,len);
        +		for (p=buf; *p; p++)
        +			if (*p == '.')
        +				{
        +				*p='\0';
        +				break;
        +				}
        +		BUF_strlcat(buf,POSTFIX,len);
        +		}
        +	else
        +		BUF_strlcpy(buf,serialfile,len);
        +
        +	serial = load_serial(buf, create, NULL);
        +	if (serial == NULL) goto end;
        +
        +	if (!BN_add_word(serial,1))
        +		{ BIO_printf(bio_err,"add_word failure\n"); goto end; }
        +
        +	if (!save_serial(buf, NULL, serial, &bs)) goto end;
        +
        + end:
        +	if (buf) OPENSSL_free(buf);
        +	BN_free(serial);
        +	return bs;
        +	}
        +
        +static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
        +	     		X509 *x, X509 *xca, EVP_PKEY *pkey,
        +			STACK_OF(OPENSSL_STRING) *sigopts,
        +	  		char *serialfile, int create,
        +	     		int days, int clrext, CONF *conf, char *section,
        +			ASN1_INTEGER *sno)
        +	{
        +	int ret=0;
        +	ASN1_INTEGER *bs=NULL;
        +	X509_STORE_CTX xsc;
        +	EVP_PKEY *upkey;
        +
        +	upkey = X509_get_pubkey(xca);
        +	EVP_PKEY_copy_parameters(upkey,pkey);
        +	EVP_PKEY_free(upkey);
        +
        +	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
        +		{
        +		BIO_printf(bio_err,"Error initialising X509 store\n");
        +		goto end;
        +		}
        +	if (sno) bs = sno;
        +	else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
        +		goto end;
        +
        +/*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/
        +
        +	/* NOTE: this certificate can/should be self signed, unless it was
        +	 * a certificate request in which case it is not. */
        +	X509_STORE_CTX_set_cert(&xsc,x);
        +	X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
        +	if (!reqfile && X509_verify_cert(&xsc) <= 0)
        +		goto end;
        +
        +	if (!X509_check_private_key(xca,pkey))
        +		{
        +		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
        +		goto end;
        +		}
        +
        +	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
        +	if (!X509_set_serialNumber(x,bs)) goto end;
        +
        +	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
        +		goto end;
        +
        +	/* hardwired expired */
        +	if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL)
        +		goto end;
        +
        +	if (clrext)
        +		{
        +		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
        +		}
        +
        +	if (conf)
        +		{
        +		X509V3_CTX ctx2;
        +		X509_set_version(x,2); /* version 3 certificate */
        +                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
        +                X509V3_set_nconf(&ctx2, conf);
        +                if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
        +		}
        +
        +	if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
        +		goto end;
        +	ret=1;
        +end:
        +	X509_STORE_CTX_cleanup(&xsc);
        +	if (!ret)
        +		ERR_print_errors(bio_err);
        +	if (!sno) ASN1_INTEGER_free(bs);
        +	return ret;
        +	}
        +
        +static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
        +	{
        +	int err;
        +	X509 *err_cert;
        +
        +	/* it is ok to use a self signed certificate
        +	 * This case will catch both the initial ok == 0 and the
        +	 * final ok == 1 calls to this function */
        +	err=X509_STORE_CTX_get_error(ctx);
        +	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
        +		return 1;
        +
        +	/* BAD we should have gotten an error.  Normally if everything
        +	 * worked X509_STORE_CTX_get_error(ctx) will still be set to
        +	 * DEPTH_ZERO_SELF_.... */
        +	if (ok)
        +		{
        +		BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
        +		return 0;
        +		}
        +	else
        +		{
        +		err_cert=X509_STORE_CTX_get_current_cert(ctx);
        +		print_name(bio_err, NULL, X509_get_subject_name(err_cert),0);
        +		BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
        +			err,X509_STORE_CTX_get_error_depth(ctx),
        +			X509_verify_cert_error_string(err));
        +		return 1;
        +		}
        +	}
        +
        +/* self sign */
        +static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 
        +						CONF *conf, char *section)
        +	{
        +
        +	EVP_PKEY *pktmp;
        +
        +	pktmp = X509_get_pubkey(x);
        +	EVP_PKEY_copy_parameters(pktmp,pkey);
        +	EVP_PKEY_save_parameters(pktmp,1);
        +	EVP_PKEY_free(pktmp);
        +
        +	if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
        +	if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;
        +
        +	/* Lets just make it 12:00am GMT, Jan 1 1970 */
        +	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
        +	/* 28 days to be certified */
        +
        +	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
        +		goto err;
        +
        +	if (!X509_set_pubkey(x,pkey)) goto err;
        +	if (clrext)
        +		{
        +		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
        +		}
        +	if (conf)
        +		{
        +		X509V3_CTX ctx;
        +		X509_set_version(x,2); /* version 3 certificate */
        +                X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
        +                X509V3_set_nconf(&ctx, conf);
        +                if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
        +		}
        +	if (!X509_sign(x,pkey,digest)) goto err;
        +	return 1;
        +err:
        +	ERR_print_errors(bio_err);
        +	return 0;
        +	}
        +
        +static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
        +{
        +	int id, i, idret;
        +	char *pname;
        +	id = X509_PURPOSE_get_id(pt);
        +	pname = X509_PURPOSE_get0_name(pt);
        +	for (i = 0; i < 2; i++)
        +		{
        +		idret = X509_check_purpose(cert, id, i);
        +		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : ""); 
        +		if (idret == 1) BIO_printf(bio, "Yes\n");
        +		else if (idret == 0) BIO_printf(bio, "No\n");
        +		else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
        +		}
        +	return 1;
        +}
        diff --git a/vendor/openssl/openssl/bugs/MS b/vendor/openssl/openssl/bugs/MS
        new file mode 100644
        index 000000000..a1dcfb90d
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/MS
        @@ -0,0 +1,7 @@
        +If you use the function that does an fopen inside the DLL, it's malloc
        +will be used and when the function is then written inside, more
        +hassles
        +....
        +
        +
        +think about it.
        diff --git a/vendor/openssl/openssl/bugs/SSLv3 b/vendor/openssl/openssl/bugs/SSLv3
        new file mode 100644
        index 000000000..a75a1652d
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/SSLv3
        @@ -0,0 +1,49 @@
        +So far...
        +
        +ssl3.netscape.com:443 does not support client side dynamic
        +session-renegotiation.
        +
        +ssl3.netscape.com:444 (asks for client cert) sends out all the CA RDN
        +in an invalid format (the outer sequence is removed).
        +
        +Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
        +challenge but then appears to only use 16 bytes when generating the
        +encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
        +According to the SSLv3 spec, one should use 32 bytes for the challenge
        +when opperating in SSLv2/v3 compatablity mode, but as mentioned above,
        +this breaks this server so 16 bytes is the way to go.
        +
        +www.microsoft.com - when talking SSLv2, if session-id reuse is
        +performed, the session-id passed back in the server-finished message
        +is different from the one decided upon.
        +
        +ssl3.netscape.com:443, first a connection is established with RC4-MD5.
        +If it is then resumed, we end up using DES-CBC3-SHA.  It should be
        +RC4-MD5 according to 7.6.1.3, 'cipher_suite'.
        +Netscape-Enterprise/2.01 (https://merchant.netscape.com) has this bug.
        +It only really shows up when connecting via SSLv2/v3 then reconnecting
        +via SSLv3. The cipher list changes....
        +NEW INFORMATION.  Try connecting with a cipher list of just
        +DES-CBC-SHA:RC4-MD5.  For some weird reason, each new connection uses
        +RC4-MD5, but a re-connect tries to use DES-CBC-SHA.  So netscape, when
        +doing a re-connect, always takes the first cipher in the cipher list.
        +
        +If we accept a netscape connection, demand a client cert, have a
        +non-self-signed CA which does not have it's CA in netscape, and the
        +browser has a cert, it will crash/hang.  Works for 3.x and 4.xbeta
        +
        +Netscape browsers do not really notice the server sending a
        +close notify message.  I was sending one, and then some invalid data.
        +netscape complained of an invalid mac. (a fork()ed child doing a
        +SSL_shutdown() and still sharing the socket with its parent).
        +
        +Netscape, when using export ciphers, will accept a 1024 bit temporary
        +RSA key.  It is supposed to only accept 512.
        +
        +If Netscape connects to a server which requests a client certificate
        +it will frequently hang after the user has selected one and never
        +complete the connection. Hitting "Stop" and reload fixes this and
        +all subsequent connections work fine. This appears to be because 
        +Netscape wont read any new records in when it is awaiting a server
        +done message at this point. The fix is to send the certificate request
        +and server done messages in one record.
        diff --git a/vendor/openssl/openssl/bugs/alpha.c b/vendor/openssl/openssl/bugs/alpha.c
        new file mode 100644
        index 000000000..701d6a7c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/alpha.c
        @@ -0,0 +1,91 @@
        +/* bugs/alpha.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.]
        + */
        +
        +/* while not exactly a bug (ASN1 C leaves this undefined) it is
        + * something to watch out for.  This was fine on linux/NT/Solaris but not
        + * Alpha */
        +
        +/* it is basically an example of
        + * func(*(a++),*(a++))
        + * which parameter is evaluated first?  It is not defined in ASN1 C.
        + */
        +
        +#include <stdio.h>
        +
        +#define TYPE    unsigned int
        +
        +void func(a,b)
        +TYPE *a;
        +TYPE b;
        +        {
        +        printf("%ld -1 == %ld\n",a[0],b);
        +        }
        +
        +main()
        +        {
        +        TYPE data[5]={1L,2L,3L,4L,5L};
        +        TYPE *p;
        +        int i;
        +
        +        p=data;
        +
        +        for (i=0; i<4; i++)
        +                {
        +                func(p,*(p++));
        +                }
        +        }
        diff --git a/vendor/openssl/openssl/bugs/dggccbug.c b/vendor/openssl/openssl/bugs/dggccbug.c
        new file mode 100644
        index 000000000..30e07a60e
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/dggccbug.c
        @@ -0,0 +1,45 @@
        +/* NOCW */
        +/* dggccbug.c */
        +/* bug found by Eric Young (eay@cryptsoft.com) - May 1995 */
        +
        +#include <stdio.h>
        +
        +/* There is a bug in
        + * gcc version 2.5.8 (88open OCS/BCS, DG-2.5.8.3, Oct 14 1994)
        + * as shipped with DGUX 5.4R3.10 that can be bypassed by defining
        + * DG_GCC_BUG in my code.
        + * The bug manifests itself by the vaule of a pointer that is
        + * used only by reference, not having it's value change when it is used
        + * to check for exiting the loop.  Probably caused by there being 2
        + * copies of the valiable, one in a register and one being an address
        + * that is passed. */
        +
        +/* compare the out put from
        + * gcc dggccbug.c; ./a.out
        + * and
        + * gcc -O dggccbug.c; ./a.out
        + * compile with -DFIXBUG to remove the bug when optimising.
        + */
        +
        +void inc(a)
        +int *a;
        +	{
        +	(*a)++;
        +	}
        +
        +main()
        +	{
        +	int p=0;
        +#ifdef FIXBUG
        +	int dummy;
        +#endif
        +
        +	while (p<3)
        +		{
        +		fprintf(stderr,"%08X\n",p);
        +		inc(&p);
        +#ifdef FIXBUG
        +		dummy+=p;
        +#endif
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/bugs/sgiccbug.c b/vendor/openssl/openssl/bugs/sgiccbug.c
        new file mode 100644
        index 000000000..178239d49
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/sgiccbug.c
        @@ -0,0 +1,57 @@
        +/* NOCW */
        +/* sgibug.c */
        +/* bug found by Eric Young (eay@mincom.oz.au) May 95 */
        +
        +#include <stdio.h>
        +
        +/* This compiler bug it present on IRIX 5.3, 5.1 and 4.0.5 (these are
        + * the only versions of IRIX I have access to.
        + * defining FIXBUG removes the bug.
        + * (bug is still present in IRIX 6.3 according to
        + * Gage <agage@forgetmenot.Mines.EDU>
        + */
        + 
        +/* Compare the output from
        + * cc sgiccbug.c; ./a.out
        + * and
        + * cc -O sgiccbug.c; ./a.out
        + */
        +
        +static unsigned long a[4]={0x01234567,0x89ABCDEF,0xFEDCBA98,0x76543210};
        +static unsigned long b[4]={0x89ABCDEF,0xFEDCBA98,0x76543210,0x01234567};
        +static unsigned long c[4]={0x77777778,0x8ACF1357,0x88888888,0x7530ECA9};
        +
        +main()
        +	{
        +	unsigned long r[4];
        +	sub(r,a,b);
        +	fprintf(stderr,"input a= %08X %08X %08X %08X\n",a[3],a[2],a[1],a[0]);
        +	fprintf(stderr,"input b= %08X %08X %08X %08X\n",b[3],b[2],b[1],b[0]);
        +	fprintf(stderr,"output = %08X %08X %08X %08X\n",r[3],r[2],r[1],r[0]);
        +	fprintf(stderr,"correct= %08X %08X %08X %08X\n",c[3],c[2],c[1],c[0]);
        +	}
        +
        +int sub(r,a,b)
        +unsigned long *r,*a,*b;
        +	{
        +	register unsigned long t1,t2,*ap,*bp,*rp;
        +	int i,carry;
        +#ifdef FIXBUG
        +	unsigned long dummy;
        +#endif
        +
        +	ap=a;
        +	bp=b;
        +	rp=r;
        +	carry=0;
        +	for (i=0; i<4; i++)
        +		{
        +		t1= *(ap++);
        +		t2= *(bp++);
        +		t1=(t1-t2);
        +#ifdef FIXBUG
        +		dummy=t1;
        +#endif
        +		*(rp++)=t1&0xffffffff;
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/bugs/sslref.dif b/vendor/openssl/openssl/bugs/sslref.dif
        new file mode 100644
        index 000000000..0aa92bfe6
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/sslref.dif
        @@ -0,0 +1,26 @@
        +The February 9th, 1995 version of the SSL document differs from
        +https://www.netscape.com in the following ways.
        +=====
        +The key material for generating a SSL_CK_DES_64_CBC_WITH_MD5 key is
        +KEY-MATERIAL-0 = MD5[MASTER-KEY,"0",CHALLENGE,CONNECTION-ID]
        +not
        +KEY-MATERIAL-0 = MD5[MASTER-KEY,CHALLENGE,CONNECTION-ID]
        +as specified in the documentation.
        +=====
        +From the section 2.6 Server Only Protocol Messages
        +
        +If the SESSION-ID-HIT flag is non-zero then the CERTIFICATE-TYPE,
        +CERTIFICATE-LENGTH and CIPHER-SPECS-LENGTH fields will be zero. 
        +
        +This is not true for https://www.netscape.com.  The CERTIFICATE-TYPE
        +is returned as 1.
        +=====
        +I have not tested the following but it is reported by holtzman@mit.edu.
        +
        +SSLref clients wait to recieve a server-verify before they send a
        +client-finished.  Besides this not being evident from the examples in
        +2.2.1, it makes more sense to always send all packets you can before
        +reading.  SSLeay was waiting in the server to recieve a client-finish
        +before sending the server-verify :-).  I have changed SSLeay to send a
        +server-verify before trying to read the client-finished.
        +
        diff --git a/vendor/openssl/openssl/bugs/stream.c b/vendor/openssl/openssl/bugs/stream.c
        new file mode 100644
        index 000000000..c3b5e867d
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/stream.c
        @@ -0,0 +1,131 @@
        +/* bugs/stream.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/rc4.h>
        +#ifdef OPENSSL_NO_DES
        +#include <des.h>
        +#else
        +#include <openssl/des.h>
        +#endif
        +
        +/* show how stream ciphers are not very good.  The mac has no affect
        + * on RC4 while it does for cfb DES
        + */
        +
        +main()
        +	{
        +	fprintf(stderr,"rc4\n");
        +	rc4();
        +	fprintf(stderr,"cfb des\n");
        +	des();
        +	}
        +
        +int des()
        +	{
        +	des_key_schedule ks;
        +	des_cblock iv,key;
        +	int num;
        +	static char *keystr="01234567";
        +	static char *in1="0123456789ABCEDFdata 12345";
        +	static char *in2="9876543210abcdefdata 12345";
        +	unsigned char out[100];
        +	int i;
        +
        +	des_set_key((des_cblock *)keystr,ks);
        +
        +	num=0;
        +	memset(iv,0,8);
        +	des_cfb64_encrypt(in1,out,26,ks,(des_cblock *)iv,&num,1);
        +	for (i=0; i<26; i++)
        +		fprintf(stderr,"%02X ",out[i]);
        +	fprintf(stderr,"\n");
        +
        +	num=0;
        +	memset(iv,0,8);
        +	des_cfb64_encrypt(in2,out,26,ks,(des_cblock *)iv,&num,1);
        +	for (i=0; i<26; i++)
        +		fprintf(stderr,"%02X ",out[i]);
        +	fprintf(stderr,"\n");
        +	}
        +
        +int rc4()
        +	{
        +	static char *keystr="0123456789abcdef";
        +	RC4_KEY key;
        +	unsigned char in[100],out[100];
        +	int i;
        +
        +	RC4_set_key(&key,16,keystr);
        +	in[0]='\0';
        +	strcpy(in,"0123456789ABCEDFdata 12345");
        +	RC4(key,26,in,out);
        +
        +	for (i=0; i<26; i++)
        +		fprintf(stderr,"%02X ",out[i]);
        +	fprintf(stderr,"\n");
        +
        +	RC4_set_key(&key,16,keystr);
        +	in[0]='\0';
        +	strcpy(in,"9876543210abcdefdata 12345");
        +	RC4(key,26,in,out);
        +
        +	for (i=0; i<26; i++)
        +		fprintf(stderr,"%02X ",out[i]);
        +	fprintf(stderr,"\n");
        +	}
        diff --git a/vendor/openssl/openssl/bugs/ultrixcc.c b/vendor/openssl/openssl/bugs/ultrixcc.c
        new file mode 100644
        index 000000000..7ba75b140
        --- /dev/null
        +++ b/vendor/openssl/openssl/bugs/ultrixcc.c
        @@ -0,0 +1,45 @@
        +#include <stdio.h>
        +
        +/* This is a cc optimiser bug for ultrix 4.3, mips CPU.
        + * What happens is that the compiler, due to the (a)&7,
        + * does
        + * i=a&7;
        + * i--;
        + * i*=4;
        + * Then uses i as the offset into a jump table.
        + * The problem is that a value of 0 generates an offset of
        + * 0xfffffffc.
        + */
        +
        +main()
        +	{
        +	f(5);
        +	f(0);
        +	}
        +
        +int f(a)
        +int a;
        +	{
        +	switch(a&7)
        +		{
        +	case 7:
        +		printf("7\n");
        +	case 6:
        +		printf("6\n");
        +	case 5:
        +		printf("5\n");
        +	case 4:
        +		printf("4\n");
        +	case 3:
        +		printf("3\n");
        +	case 2:
        +		printf("2\n");
        +	case 1:
        +		printf("1\n");
        +#ifdef FIX_BUG
        +	case 0:
        +		;
        +#endif
        +		}
        +	}	
        +
        diff --git a/vendor/openssl/openssl/certs/README.RootCerts b/vendor/openssl/openssl/certs/README.RootCerts
        new file mode 100644
        index 000000000..c760b6103
        --- /dev/null
        +++ b/vendor/openssl/openssl/certs/README.RootCerts
        @@ -0,0 +1,4 @@
        +The OpenSSL project does not (any longer) include root CA certificates.
        +
        +Please check out the FAQ:
        +  * How can I set up a bundle of commercial root CA certificates?
        diff --git a/vendor/openssl/openssl/certs/demo/ca-cert.pem b/vendor/openssl/openssl/certs/demo/ca-cert.pem
        new file mode 100644
        index 000000000..bcba68aef
        --- /dev/null
        +++ b/vendor/openssl/openssl/certs/demo/ca-cert.pem
        @@ -0,0 +1,33 @@
        +-----BEGIN CERTIFICATE-----
        +MIIC5TCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET
        +MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
        +HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzODUxWhcN
        +MDUwNzEwMjEzODUxWjBbMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu
        +ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxGzAZBgNVBAMTElRlc3QgQ0Eg
        +KDEwMjQgYml0KTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo7ujy3XXpU/p
        +yDJtOxkMJmGv3mdiVm7JrdoKLUgqjO2rBaeNuYMUiuI6oYU+tlD6agwRML0Pn2JF
        +b90VdK/UXrmRr9djaEuH17EIKjte5RwOzndCndsjcCYyoeODMTyg7dqPIkDMmRNM
        +5R5xBTabD+Aji0wzQupYxBLuW5PLj7ECAwEAAaOBtzCBtDAdBgNVHQ4EFgQU1WWA
        +U42mkhi3ecgey1dsJjU61+UwgYQGA1UdIwR9MHuAFE0RaEcrj18q1dw+G6nJbsTW
        +R213oWCkXjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
        +A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0
        +IGJpdCmCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBb39BRphHL
        +6aRAQyymsvBvPSCiG9+kR0R1L23aTpNbhXp2BebyFjbEQYZc2kWGiKKcHkNECA35
        +3d4LoqUlVey8DFyafOIJd9hxdZfg+rxlHMxnL7uCJRmx9+xB411Jtsol9/wg1uCK
        +sleGpgB4j8cG2SVCz7V2MNZNK+d5QCnR7A==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425
        +gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd
        +2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB
        +AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6
        +hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2
        +J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs
        +HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL
        +21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s
        +nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz
        +MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa
        +pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb
        +KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2
        +XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/certs/demo/dsa-ca.pem b/vendor/openssl/openssl/certs/demo/dsa-ca.pem
        new file mode 100644
        index 000000000..9eb08f3dd
        --- /dev/null
        +++ b/vendor/openssl/openssl/certs/demo/dsa-ca.pem
        @@ -0,0 +1,43 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +Proc-Type: 4,ENCRYPTED
        +DEK-Info: DES-EDE3-CBC,C5B6C7CC9E1FE2C0
        +
        +svCXBcBRhMuU22UXOfiKZA+thmz6KYXpt1Yg5Rd+TYQcQ1MdvNy0B0tkP1SxzDq0
        +Xh1eMeTML9/9/0rKakgNXXXbpi5RB8t6BmwRSyej89F7nn1mtR3qzoyPRpp15SDl
        +Tn67C+2v+HDF3MFk88hiNCYkNbcmi7TWvChsl8N1r7wdZwtIox56yXdgxw6ZIpa/
        +par0oUCzN7fiavPgCWz1kfPNSaBQSdxwH7TZi5tMHAr0J3C7a7QRnZfE09R59Uqr
        +zslrq+ndIw1BZAxoY0SlBu+iFOVaBVlwToC4AsHkv7j7l8ITtr7f42YbBa44D9TO
        +uOhONmkk/v3Fso4RaOEzdKZC+hnmmzvHs6TiTWm6yzJgSFwyOUK0eGmKEeVxpcH5
        +rUOlHOwzen+FFtocZDZAfdFnb7QY7L/boQvyA5A+ZbRG4DUpmBQeQsSaICHM5Rxx
        +1QaLF413VNPXTLPbW0ilSc2H8x2iZTIVKfd33oSO6NhXPtSYQgfecEF4BvNHY5c4
        +HovjT4mckbK95bcBzoCHu43vuSQkmZzdYo/ydSZt6zoPavbBLueTpgSbdXiDi827
        +MVqOsYxGCb+kez0FoDSTgw==
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIICUjCCAhECAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
        +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew
        +ggG0MIIBKQYFKw4DAgwwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaW
        +sxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5m
        +rmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHk
        +cJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVo
        +bzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqR
        +CZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxB
        +F5WS6wG1c6Vqftgy7Q4CuAOBhAACgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuH
        +vSLw9YUrJahcBHmbpvt494lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUq
        +AylOVFJJJXuirVJ+o+0TtOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u
        +3enxhqnDGaAAMAkGBSsOAwIbBQADMAAwLQIVAJGVuFsG/0DBuSZ0jF7ypdU0/G0v
        +AhQfeF5BoMMDbX/kidUVpQ6gadPlZA==
        +-----END CERTIFICATE REQUEST-----
        +-----BEGIN CERTIFICATE-----
        +MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
        +CgYDVQQDEwNQQ0EwHhcNOTcwNjE1MDIxNDI5WhcNOTcwNzE1MDIxNDI5WjBSMQsw
        +CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
        +ZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCBkjAJBgUrDgMCDAUAA4GE
        +AAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfsi4e9IvD1hSslqFwEeZum+3j3iUXi
        +ALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj25SoDKU5UUkkle6KtUn6j7RO04UMh
        +MQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17ry7d6fGGqcMZMAkGBSsOAwIbBQAD
        +MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa
        +C1Q=
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/certs/demo/dsa-pca.pem b/vendor/openssl/openssl/certs/demo/dsa-pca.pem
        new file mode 100644
        index 000000000..e3641ad47
        --- /dev/null
        +++ b/vendor/openssl/openssl/certs/demo/dsa-pca.pem
        @@ -0,0 +1,49 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +Proc-Type: 4,ENCRYPTED
        +DEK-Info: DES-EDE3-CBC,F80EEEBEEA7386C4
        +
        +GZ9zgFcHOlnhPoiSbVi/yXc9mGoj44A6IveD4UlpSEUt6Xbse3Fr0KHIUyQ3oGnS
        +mClKoAp/eOTb5Frhto85SzdsxYtac+X1v5XwdzAMy2KowHVk1N8A5jmE2OlkNPNt
        +of132MNlo2cyIRYaa35PPYBGNCmUm7YcYS8O90YtkrQZZTf4+2C4kllhMcdkQwkr
        +FWSWC8YOQ7w0LHb4cX1FejHHom9Nd/0PN3vn3UyySvfOqoR7nbXkrpHXmPIr0hxX
        +RcF0aXcV/CzZ1/nfXWQf4o3+oD0T22SDoVcZY60IzI0oIc3pNCbDV3uKNmgekrFd
        +qOUJ+QW8oWp7oefRx62iBfIeC8DZunohMXaWAQCU0sLQOR4yEdeUCnzCSywe0bG1
        +diD0KYaEe+Yub1BQH4aLsBgDjardgpJRTQLq0DUvw0/QGO1irKTJzegEDNVBKrVn
        +V4AHOKT1CUKqvGNRP1UnccUDTF6miOAtaj/qpzra7sSk7dkGBvIEeFoAg84kfh9h
        +hVvF1YyzC9bwZepruoqoUwke/WdNIR5ymOVZ/4Liw0JdIOcq+atbdRX08niqIRkf
        +dsZrUj4leo3zdefYUQ7w4N2Ns37yDFq7
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
        +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB
        +MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G
        +lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O
        +Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR
        +5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl
        +aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6
        +kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als
        +QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe
        +6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ
        +yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0
        +z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB
        +nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==
        +-----END CERTIFICATE REQUEST-----
        +-----BEGIN CERTIFICATE-----
        +MIIC0zCCApECAQAwCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww
        +CgYDVQQDEwNQQ0EwHhcNOTcwNjE0MjI1NDQ1WhcNOTcwNzE0MjI1NDQ1WjBTMQsw
        +CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
        +ZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNQQ0EwggG1MIIBKQYFKw4DAgww
        +ggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaWsxXgUy6P4FmCc5A+dTGZ
        +R3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5mrmuINvvsKNzC16W75Sw5
        +JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHkcJVbUM1JAhUA9wcx7fps
        +BgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVobzDjaeHls12YuyiGSPze
        +mQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqRCZ228U2cVA9YBu5JdAfO
        +VX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxBF5WS6wG1c6Vqftgy7Q4C
        +uAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk
        +umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A
        +29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUwCQYFKw4D
        +AhsFAAMxADAuAhUAvtv6AkMolix1Jvy3UnVEIUqdCUICFQC+jq8P49mwrY9oJ24n
        +5rKUjNBhSg==
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/certs/demo/pca-cert.pem b/vendor/openssl/openssl/certs/demo/pca-cert.pem
        new file mode 100644
        index 000000000..9d754d460
        --- /dev/null
        +++ b/vendor/openssl/openssl/certs/demo/pca-cert.pem
        @@ -0,0 +1,33 @@
        +-----BEGIN CERTIFICATE-----
        +MIIC5jCCAk+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET
        +MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
        +HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzNTQ4WhcN
        +MDUwNzExMjEzNTQ4WjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu
        +ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENB
        +ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ2haT/f5Zwy
        +V+MiuSDjSR62adBoSiBB7Usty44lXqsp9RICw+DCCxpsn/CfxPEDXLLd4olsWXc6
        +JRcxGynbYmnzk+Z6aIPPJQhK3CTvaqGnWKZsA1m+WaUIUqJCuNTK4N+7hMAGaf6S
        +S3e9HVgEQ4a34gXJ7VQFVIBNV1EnZRWHAgMBAAGjgbcwgbQwHQYDVR0OBBYEFE0R
        +aEcrj18q1dw+G6nJbsTWR213MIGEBgNVHSMEfTB7gBRNEWhHK49fKtXcPhupyW7E
        +1kdtd6FgpF4wXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
        +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy
        +NCBiaXQpggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAUa8B3pho
        ++Mvxeq9HsEzJxHIFQla05S5J/e/V+DQTYoKiRFchKPrDAdrzYSEvP3h4QJEtsNqQ
        +JfOxg5M42uLFq7aPGWkF6ZZqZsYS+zA9IVT14g7gNA6Ne+5QtJqQtH9HA24st0T0
        +Tga/lZ9M2ovImovaxSL/kRHbpCWcqWVxpOw=
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
        +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
        +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
        +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
        +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
        +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
        +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
        +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
        +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
        +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
        +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
        +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
        +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/certs/expired/ICE.crl b/vendor/openssl/openssl/certs/expired/ICE.crl
        new file mode 100644
        index 000000000..21939e8cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/certs/expired/ICE.crl
        @@ -0,0 +1,9 @@
        +-----BEGIN X509 CRL-----
        +MIIBNDCBnjANBgkqhkiG9w0BAQIFADBFMSEwHwYDVQQKExhFdXJvcGVhbiBJQ0Ut
        +VEVMIFByb2plY3QxIDAeBgNVBAsTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05
        +NzA2MDkxNDQyNDNaFw05NzA3MDkxNDQyNDNaMCgwEgIBChcNOTcwMzAzMTQ0MjU0
        +WjASAgEJFw05NjEwMDIxMjI5MjdaMA0GCSqGSIb3DQEBAgUAA4GBAH4vgWo2Tej/
        +i7kbiw4Imd30If91iosjClNpBFwvwUDBclPEeMuYimHbLOk4H8Nofc0fw11+U/IO
        +KSNouUDcqG7B64oY7c4SXKn+i1MWOb5OJiWeodX3TehHjBlyWzoNMWCnYA8XqFP1
        +mOKp8Jla1BibEZf14+/HqCi2hnZUiEXh
        +-----END X509 CRL-----
        diff --git a/vendor/openssl/openssl/config b/vendor/openssl/openssl/config
        new file mode 100644
        index 000000000..88b9bc69d
        --- /dev/null
        +++ b/vendor/openssl/openssl/config
        @@ -0,0 +1,967 @@
        +#!/bin/sh
        +#
        +# OpenSSL config: determine the operating system and run ./Configure
        +#
        +# "config -h" for usage information.
        +#
        +#          this is a merge of minarch and GuessOS from the Apache Group.
        +#          Originally written by Tim Hudson <tjh@cryptsoft.com>.
        +
        +# Original Apache Group comments on GuessOS
        +
        +# Simple OS/Platform guesser. Similar to config.guess but
        +# much, much smaller. Since it was developed for use with
        +# Apache, it follows under Apache's regular licensing
        +# with one specific addition: Any changes or additions
        +# to this script should be Emailed to the Apache
        +# group (apache@apache.org) in general and to
        +# Jim Jagielski (jim@jaguNET.com) in specific.
        +#
        +# Be as similar to the output of config.guess/config.sub
        +# as possible.
        +
        +PREFIX=""
        +SUFFIX=""
        +TEST="false"
        +EXE=""
        +
        +# pick up any command line args to config
        +for i
        +do
        +case "$i" in 
        +-d*) PREFIX="debug-";;
        +-t*) TEST="true";;
        +-h*) TEST="true"; cat <<EOF
        +Usage: config [options]
        + -d	Add a debug- prefix to machine choice.
        + -t	Test mode, do not run the Configure perl script.
        + -h	This help.
        +
        +Any other text will be passed to the Configure perl script.
        +See INSTALL for instructions.
        +
        +EOF
        +;;
        +*) options=$options" $i" ;;
        +esac
        +done
        +
        +# First get uname entries that we use below
        +
        +[ "$MACHINE" ] || MACHINE=`(uname -m) 2>/dev/null` || MACHINE="unknown"
        +[ "$RELEASE" ] || RELEASE=`(uname -r) 2>/dev/null` || RELEASE="unknown"
        +[ "$SYSTEM" ] || SYSTEM=`(uname -s) 2>/dev/null`  || SYSTEM="unknown"
        +[ "$BUILD" ] || VERSION=`(uname -v) 2>/dev/null` || VERSION="unknown"
        +
        +
        +# Now test for ISC and SCO, since it is has a braindamaged uname.
        +#
        +# We need to work around FreeBSD 1.1.5.1 
        +(
        +XREL=`uname -X 2>/dev/null | grep "^Release" | awk '{print $3}'`
        +if [ "x$XREL" != "x" ]; then
        +    if [ -f /etc/kconfig ]; then
        +	case "$XREL" in
        +	    4.0|4.1)
        +		    echo "${MACHINE}-whatever-isc4"; exit 0
        +		;;
        +	esac
        +    else
        +	case "$XREL" in
        +	    3.2v4.2)
        +		echo "whatever-whatever-sco3"; exit 0
        +		;;
        +	    3.2v5.0*)
        +		echo "whatever-whatever-sco5"; exit 0
        +		;;
        +	    4.2MP)
        +		case "x${VERSION}" in
        +		    x2.0*) echo "whatever-whatever-unixware20"; exit 0 ;;
        +		    x2.1*) echo "whatever-whatever-unixware21"; exit 0 ;;
        +		    x2*)   echo "whatever-whatever-unixware2";  exit 0 ;;
        +		esac
        +		;;
        +	    4.2)
        +		echo "whatever-whatever-unixware1"; exit 0
        +		;;
        +	    5*)
        +		case "x${VERSION}" in
        +		    # We hardcode i586 in place of ${MACHINE} for the
        +		    # following reason. The catch is that even though Pentium
        +		    # is minimum requirement for platforms in question,
        +		    # ${MACHINE} gets always assigned to i386. Now, problem
        +		    # with i386 is that it makes ./config pass 386 to
        +		    # ./Configure, which in turn makes make generate
        +		    # inefficient SHA-1 (for this moment) code.
        +		    x[678]*)  echo "i586-sco-unixware7"; exit 0 ;;
        +		esac
        +		;;
        +	esac
        +    fi
        +fi
        +# Now we simply scan though... In most cases, the SYSTEM info is enough
        +#
        +case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in
        +    MPE/iX:*)
        +	MACHINE=`echo "$MACHINE" | sed -e 's/-/_/g'`
        +	echo "parisc-hp-MPE/iX"; exit 0
        +	;;
        +    A/UX:*)
        +	echo "m68k-apple-aux3"; exit 0
        +	;;
        +
        +    AIX:[3-9]:4:*)
        +	echo "${MACHINE}-ibm-aix"; exit 0
        +	;;
        +
        +    AIX:*:[5-9]:*)
        +	echo "${MACHINE}-ibm-aix"; exit 0
        +	;;
        +
        +    AIX:*)
        +	echo "${MACHINE}-ibm-aix3"; exit 0
        +	;;
        +
        +    BeOS:*:BePC)
        +    if [ -e /boot/develop/headers/be/bone ]; then
        +		echo "beos-x86-bone"; exit 0
        +	else
        +		echo "beos-x86-r5"; exit 0
        +	fi
        +	;;
        +
        +    dgux:*)
        +	echo "${MACHINE}-dg-dgux"; exit 0
        +	;;
        +
        +    HI-UX:*)
        +	echo "${MACHINE}-hi-hiux"; exit 0
        +	;;
        +
        +    HP-UX:*)
        +	HPUXVER=`echo ${RELEASE}|sed -e 's/[^.]*.[0B]*//'`
        +	case "$HPUXVER" in
        +	    1[0-9].*)	# HPUX 10 and 11 targets are unified
        +		echo "${MACHINE}-hp-hpux1x"; exit 0
        +		;;
        +	    *)
        +		echo "${MACHINE}-hp-hpux"; exit 0
        +		;;
        +	esac
        +	;;
        +
        +    IRIX:5.*)
        +	echo "mips2-sgi-irix"; exit 0
        +	;;
        +
        +    IRIX:6.*)
        +	echo "mips3-sgi-irix"; exit 0
        +	;;
        +
        +    IRIX64:*)
        +	echo "mips4-sgi-irix64"; exit 0
        +	;;
        +
        +    Linux:[2-9].*)
        +	echo "${MACHINE}-whatever-linux2"; exit 0
        +	;;
        +
        +    Linux:1.*)
        +	echo "${MACHINE}-whatever-linux1"; exit 0
        +	;;
        +
        +    GNU*)
        +	echo "hurd-x86"; exit 0;
        +	;;
        +
        +    LynxOS:*)
        +	echo "${MACHINE}-lynx-lynxos"; exit 0
        +	;;
        +
        +    BSD/OS:4.*)  # BSD/OS always says 386
        +	echo "i486-whatever-bsdi4"; exit 0
        +	;;
        +
        +    BSD/386:*:*:*486*|BSD/OS:*:*:*:*486*)
        +        case `/sbin/sysctl -n hw.model` in
        +	    Pentium*)
        +                echo "i586-whatever-bsdi"; exit 0
        +                ;;
        +            *)
        +                echo "i386-whatever-bsdi"; exit 0
        +                ;;
        +            esac;
        +	;;
        +
        +    BSD/386:*|BSD/OS:*)
        +	echo "${MACHINE}-whatever-bsdi"; exit 0
        +	;;
        +
        +    FreeBSD:*:*:*386*)
        +        VERS=`echo ${RELEASE} | sed -e 's/[-(].*//'`
        +        MACH=`sysctl -n hw.model`
        +        ARCH='whatever'
        +        case ${MACH} in
        +           *386*       ) MACH="i386"     ;;
        +           *486*       ) MACH="i486"     ;;
        +           Pentium\ II*) MACH="i686"     ;;
        +           Pentium*    ) MACH="i586"     ;;
        +           *           ) MACH="$MACHINE" ;;
        +        esac
        +        case ${MACH} in
        +           i[0-9]86 ) ARCH="pc" ;;
        +        esac
        +        echo "${MACH}-${ARCH}-freebsd${VERS}"; exit 0
        +        ;;
        +
        +    FreeBSD:*)
        +	echo "${MACHINE}-whatever-freebsd"; exit 0
        +	;;
        +
        +    NetBSD:*:*:*386*)
        +        echo "`(/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model) | sed 's,.*\(.\)86-class.*,i\186,'`-whatever-netbsd"; exit 0
        +	;;
        +
        +    NetBSD:*)
        +	echo "${MACHINE}-whatever-netbsd"; exit 0
        +	;;
        +
        +    OpenBSD:*)
        +	echo "${MACHINE}-whatever-openbsd"; exit 0
        +	;;
        +
        +    OpenUNIX:*)
        +	echo "${MACHINE}-unknown-OpenUNIX${VERSION}"; exit 0
        +	;;
        +
        +    OSF1:*:*:*alpha*)
        +	OSFMAJOR=`echo ${RELEASE}| sed -e 's/^V\([0-9]*\)\..*$/\1/'`
        +	case "$OSFMAJOR" in
        +	    4|5)
        +		echo "${MACHINE}-dec-tru64"; exit 0
        +		;;
        +	    1|2|3)
        +		echo "${MACHINE}-dec-osf"; exit 0
        +		;;
        +	    *)
        +		echo "${MACHINE}-dec-osf"; exit 0
        +		;;
        +	esac
        +	;;
        +
        +    QNX:*)
        +	case "$RELEASE" in
        +	    4*)
        +		echo "${MACHINE}-whatever-qnx4"
        +		;;
        +	    6*)
        +		echo "${MACHINE}-whatever-qnx6"
        +		;;
        +	    *)
        +		echo "${MACHINE}-whatever-qnx"
        +		;;
        +	esac
        +	exit 0
        +	;;
        +
        +    Paragon*:*:*:*)
        +	echo "i860-intel-osf1"; exit 0
        +	;;
        +
        +    Rhapsody:*)
        +	echo "ppc-apple-rhapsody"; exit 0
        +	;;
        +
        +    Darwin:*)
        +	case "$MACHINE" in
        +	    Power*)
        +		echo "ppc-apple-darwin${VERSION}"
        +		;;
        +	    *)
        +		echo "i686-apple-darwin${VERSION}"
        +		;;
        +	esac
        +	exit 0
        +	;;
        +
        +    SunOS:5.*)
        +	echo "${MACHINE}-whatever-solaris2"; exit 0
        +	;;
        +
        +    SunOS:*)
        +	echo "${MACHINE}-sun-sunos4"; exit 0
        +	;;
        +
        +    UNIX_System_V:4.*:*)
        +	echo "${MACHINE}-whatever-sysv4"; exit 0
        +	;;
        +
        +    VOS:*:*:i786)
        +     echo "i386-stratus-vos"; exit 0
        +     ;;
        +
        +    VOS:*:*:*)
        +     echo "hppa1.1-stratus-vos"; exit 0
        +     ;;
        +
        +    *:4*:R4*:m88k)
        +	echo "${MACHINE}-whatever-sysv4"; exit 0
        +	;;
        +
        +    DYNIX/ptx:4*:*)
        +	echo "${MACHINE}-whatever-sysv4"; exit 0
        +	;;
        +
        +    *:4.0:3.0:3[34]?? | *:4.0:3.0:3[34]??,*)
        +	echo "i486-ncr-sysv4"; exit 0
        +	;;
        +
        +    ULTRIX:*)
        +	echo "${MACHINE}-unknown-ultrix"; exit 0
        +	;;
        +
        +    SINIX*|ReliantUNIX*)
        +	echo "${MACHINE}-siemens-sysv4"; exit 0
        +	;;
        +
        +    POSIX-BC*)
        +	echo "${MACHINE}-siemens-sysv4"; exit 0   # Here, $MACHINE == "BS2000"
        +	;;
        +
        +    machten:*)
        +       echo "${MACHINE}-tenon-${SYSTEM}"; exit 0;
        +       ;;
        +
        +    library:*)
        +	echo "${MACHINE}-ncr-sysv4"; exit 0
        +	;;
        +
        +    ConvexOS:*:11.0:*)
        +	echo "${MACHINE}-v11-${SYSTEM}"; exit 0;
        +	;;
        +
        +    NEWS-OS:4.*)
        +	echo "mips-sony-newsos4"; exit 0;
        +	;;
        +
        +    MINGW*)
        +	echo "${MACHINE}-whatever-mingw"; exit 0;
        +	;;
        +    CYGWIN*)
        +	case "$RELEASE" in
        +	    [bB]*|1.0|1.[12].*)
        +		echo "${MACHINE}-whatever-cygwin_pre1.3"
        +		;;
        +	    *)
        +		echo "${MACHINE}-whatever-cygwin"
        +		;;
        +	esac
        +	exit 0
        +	;;
        +
        +    *"CRAY T3E")
        +       echo "t3e-cray-unicosmk"; exit 0;
        +       ;;
        +
        +    *CRAY*)
        +       echo "j90-cray-unicos"; exit 0;
        +       ;;
        +
        +    NONSTOP_KERNEL*)
        +       echo "nsr-tandem-nsk"; exit 0;
        +       ;;
        +
        +    vxworks*)
        +       echo "${MACHINE}-whatever-vxworks"; exit 0;
        +       ;;
        +esac
        +
        +#
        +# Ugg. These are all we can determine by what we know about
        +# the output of uname. Be more creative:
        +#
        +
        +# Do the Apollo stuff first. Here, we just simply assume
        +# that the existance of the /usr/apollo directory is proof
        +# enough
        +if [ -d /usr/apollo ]; then
        +    echo "whatever-apollo-whatever"
        +    exit 0
        +fi
        +
        +# Now NeXT
        +ISNEXT=`hostinfo 2>/dev/null`
        +case "$ISNEXT" in
        +    *'NeXT Mach 3.3'*)
        +	echo "whatever-next-nextstep3.3"; exit 0
        +	;;
        +    *NeXT*)
        +	echo "whatever-next-nextstep"; exit 0
        +	;;
        +esac
        +
        +# At this point we gone through all the one's
        +# we know of: Punt
        +
        +echo "${MACHINE}-whatever-${SYSTEM}" 
        +exit 0
        +) 2>/dev/null | (
        +
        +# ---------------------------------------------------------------------------
        +# this is where the translation occurs into SSLeay terms
        +# ---------------------------------------------------------------------------
        +
        +# Only set CC if not supplied already
        +if [ -z "$CROSS_COMPILE$CC" ]; then
        +  GCCVER=`sh -c "gcc -dumpversion" 2>/dev/null`
        +  if [ "$GCCVER" != "" ]; then
        +    # then strip off whatever prefix egcs prepends the number with...
        +    # Hopefully, this will work for any future prefixes as well.
        +    GCCVER=`echo $GCCVER | LC_ALL=C sed 's/^[a-zA-Z]*\-//'`
        +    # Since gcc 3.1 gcc --version behaviour has changed.  gcc -dumpversion
        +    # does give us what we want though, so we use that.  We just just the
        +    # major and minor version numbers.
        +    # peak single digit before and after first dot, e.g. 2.95.1 gives 29
        +    GCCVER=`echo $GCCVER | sed 's/\([0-9]\)\.\([0-9]\).*/\1\2/'`
        +    CC=gcc
        +  else
        +    CC=cc
        +  fi
        +fi
        +GCCVER=${GCCVER:-0}
        +if [ "$SYSTEM" = "HP-UX" ];then
        +  # By default gcc is a ILP32 compiler (with long long == 64).
        +  GCC_BITS="32"
        +  if [ $GCCVER -ge 30 ]; then
        +    # PA64 support only came in with gcc 3.0.x.
        +    # We check if the preprocessor symbol __LP64__ is defined...
        +    if echo "__LP64__" | gcc -v -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null; then
        +      : # __LP64__ has slipped through, it therefore is not defined
        +    else
        +      GCC_BITS="64"
        +    fi
        +  fi
        +fi
        +if [ "$SYSTEM" = "SunOS" ]; then
        +  if [ $GCCVER -ge 30 ]; then
        +    # 64-bit ABI isn't officially supported in gcc 3.0, but it appears
        +    # to be working, at the very least 'make test' passes...
        +    if gcc -v -E -x c /dev/null 2>&1 | grep __arch64__ > /dev/null; then
        +      GCC_ARCH="-m64"
        +    else
        +      GCC_ARCH="-m32"
        +    fi
        +  fi
        +  # check for WorkShop C, expected output is "cc: blah-blah C x.x"
        +  CCVER=`(cc -V 2>&1) 2>/dev/null | \
        +  	egrep -e '^cc: .* C [0-9]\.[0-9]' | \
        +	sed 's/.* C \([0-9]\)\.\([0-9]\).*/\1\2/'`
        +  CCVER=${CCVER:-0}
        +  if [ $MACHINE != i86pc -a $CCVER -gt 40 ]; then
        +    CC=cc	# overrides gcc!!!
        +    if [ $CCVER -eq 50 ]; then
        +      echo "WARNING! Detected WorkShop C 5.0. Do make sure you have"
        +      echo "         patch #107357-01 or later applied."
        +      sleep 5
        +    fi
        +  fi
        +fi
        +
        +if [ "${SYSTEM}-${MACHINE}" = "Linux-alpha" ]; then
        +  # check for Compaq C, expected output is "blah-blah C Vx.x"
        +  CCCVER=`(ccc -V 2>&1) 2>/dev/null | \
        +	egrep -e '.* C V[0-9]\.[0-9]' | \
        +	sed 's/.* C V\([0-9]\)\.\([0-9]\).*/\1\2/'`
        +  CCCVER=${CCCVER:-0}
        +  if [ $CCCVER -gt 60 ]; then
        +    CC=ccc	# overrides gcc!!! well, ccc outperforms inoticeably
        +		# only on hash routines and des, otherwise gcc (2.95)
        +		# keeps along rather tight...
        +  fi
        +fi
        +
        +if [ "${SYSTEM}" = "AIX" ]; then	# favor vendor cc over gcc
        +    (cc) 2>&1 | grep -iv "not found" > /dev/null && CC=cc
        +fi
        +
        +CCVER=${CCVER:-0}
        +
        +# read the output of the embedded GuessOS 
        +read GUESSOS
        +
        +echo Operating system: $GUESSOS
        +
        +# now map the output into SSLeay terms ... really should hack into the
        +# script above so we end up with values in vars but that would take
        +# more time that I want to waste at the moment
        +case "$GUESSOS" in
        +  uClinux*64*)
        +    OUT=uClinux-dist64
        +	;;
        +  uClinux*)
        +    OUT=uClinux-dist
        +	;;
        +  mips2-sgi-irix)
        +	CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
        +	CPU=${CPU:-0}
        +	if [ $CPU -ge 4000 ]; then
        +		options="$options -mips2"
        +	fi
        +	OUT="irix-$CC"
        +	;;
        +  mips3-sgi-irix)
        +	#CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
        +	#CPU=${CPU:-0}
        +	#if [ $CPU -ge 5000 ]; then
        +	#	options="$options -mips4"
        +	#else
        +	#	options="$options -mips3"
        +	#fi
        +	OUT="irix-mips3-$CC"
        +	;;
        +  mips4-sgi-irix64)
        +	echo "WARNING! If you wish to build 64-bit library, then you have to"
        +	echo "         invoke './Configure irix64-mips4-$CC' *manually*."
        +	if [ "$TEST" = "false" -a -t 1 ]; then
        +	  echo "         You have about 5 seconds to press Ctrl-C to abort."
        +	  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +	fi
        +        #CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
        +        #CPU=${CPU:-0}
        +        #if [ $CPU -ge 5000 ]; then
        +        #        options="$options -mips4"
        +        #else
        +        #        options="$options -mips3"
        +        #fi
        +	OUT="irix-mips3-$CC"
        +	;;
        +  ppc-apple-rhapsody) OUT="rhapsody-ppc-cc" ;;
        +  ppc-apple-darwin*)
        +	ISA64=`(sysctl -n hw.optional.64bitops) 2>/dev/null`
        +	if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then
        +	    echo "WARNING! If you wish to build 64-bit library, then you have to"
        +	    echo "         invoke './Configure darwin64-ppc-cc' *manually*."
        +	    if [ "$TEST" = "false" -a -t 1 ]; then
        +	      echo "         You have about 5 seconds to press Ctrl-C to abort."
        +	      (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +	    fi
        +	fi
        +	if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then
        +	    OUT="darwin64-ppc-cc"
        +	else
        +	    OUT="darwin-ppc-cc"
        +	fi ;;
        +  i?86-apple-darwin*)
        +	ISA64=`(sysctl -n hw.optional.x86_64) 2>/dev/null`
        +	if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then
        +	    echo "WARNING! If you wish to build 64-bit library, then you have to"
        +	    echo "         invoke './Configure darwin64-x86_64-cc' *manually*."
        +	    if [ "$TEST" = "false" -a -t 1 ]; then
        +	      echo "         You have about 5 seconds to press Ctrl-C to abort."
        +	      (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +	    fi
        +	fi
        +	if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then
        +	    OUT="darwin64-x86_64-cc"
        +	else
        +	    OUT="darwin-i386-cc"
        +	fi ;;
        +  armv6+7-*-iphoneos)
        +	options="$options -arch%20armv6 -arch%20armv7"
        +	OUT="iphoneos-cross" ;;
        +  *-*-iphoneos)
        +	options="$options -arch%20${MACHINE}"
        +	OUT="iphoneos-cross" ;;
        +  alpha-*-linux2)
        +        ISA=`awk '/cpu model/{print$4;exit(0);}' /proc/cpuinfo`
        +	case ${ISA:-generic} in
        +	*[678])	OUT="linux-alpha+bwx-$CC" ;;
        +	*)	OUT="linux-alpha-$CC" ;;
        +	esac
        +	if [ "$CC" = "gcc" ]; then
        +	    case ${ISA:-generic} in
        +	    EV5|EV45)		options="$options -mcpu=ev5";;
        +	    EV56|PCA56)		options="$options -mcpu=ev56";;
        +	    *)			options="$options -mcpu=ev6";;
        +	    esac
        +	fi
        +	;;
        +  ppc64-*-linux2)
        +	echo "WARNING! If you wish to build 64-bit library, then you have to"
        +	echo "         invoke './Configure linux-ppc64' *manually*."
        +	if [ "$TEST" = "false" -a -t 1 ]; then
        +	    echo "         You have about 5 seconds to press Ctrl-C to abort."
        +	    (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +	fi
        +	OUT="linux-ppc"
        +	;;
        +  ppc-*-linux2) OUT="linux-ppc" ;;
        +  ppc60x-*-vxworks*) OUT="vxworks-ppc60x" ;;
        +  ppcgen-*-vxworks*) OUT="vxworks-ppcgen" ;;
        +  pentium-*-vxworks*) OUT="vxworks-pentium" ;;
        +  simlinux-*-vxworks*) OUT="vxworks-simlinux" ;;
        +  mips-*-vxworks*) OUT="vxworks-mips";;
        +  ia64-*-linux?) OUT="linux-ia64" ;;
        +  sparc64-*-linux2)
        +	echo "WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI"
        +	echo "         and wish to build 64-bit library, then you have to"
        +	echo "         invoke './Configure linux64-sparcv9' *manually*."
        +	if [ "$TEST" = "false" -a -t 1 ]; then
        +	  echo "          You have about 5 seconds to press Ctrl-C to abort."
        +	  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +	fi
        +	OUT="linux-sparcv9" ;;
        +  sparc-*-linux2)
        +	KARCH=`awk '/^type/{print$3;exit(0);}' /proc/cpuinfo`
        +	case ${KARCH:-sun4} in
        +	sun4u*)	OUT="linux-sparcv9" ;;
        +	sun4m)	OUT="linux-sparcv8" ;;
        +	sun4d)	OUT="linux-sparcv8" ;;
        +	*)	OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
        +	esac ;;
        +  parisc*-*-linux2)
        +	# 64-bit builds under parisc64 linux are not supported and
        +	# compiler is expected to generate 32-bit objects...
        +	CPUARCH=`awk '/cpu family/{print substr($5,1,3); exit(0);}' /proc/cpuinfo`
        +	CPUSCHEDULE=`awk '/^cpu.[ 	]*: PA/{print substr($3,3); exit(0);}' /proc/cpuinfo`
        +
        +	# ??TODO ??  Model transformations
        +	# 0. CPU Architecture for the 1.1 processor has letter suffixes. We strip that off
        +	#    assuming no further arch. identification will ever be used by GCC.
        +	# 1. I'm most concerned about whether is a 7300LC is closer to a 7100 versus a 7100LC.
        +	# 2. The variant 64-bit processors cause concern should GCC support explicit schedulers
        +	#    for these chips in the future.
        +	#         PA7300LC -> 7100LC (1.1)
        +	#         PA8200   -> 8000   (2.0)
        +	#         PA8500   -> 8000   (2.0)
        +	#         PA8600   -> 8000   (2.0)
        +
        +	CPUSCHEDULE=`echo $CPUSCHEDULE|sed -e 's/7300LC/7100LC/' -e 's/8.00/8000/'`
        +	# Finish Model transformations
        +
        +	options="$options -DB_ENDIAN -mschedule=$CPUSCHEDULE -march=$CPUARCH"
        +	OUT="linux-generic32" ;;
        +  armv[1-3]*-*-linux2) OUT="linux-generic32" ;;
        +  armv[7-9]*-*-linux2) OUT="linux-armv4"; options="$options -march=armv7-a" ;;
        +  arm*-*-linux2) OUT="linux-armv4" ;;
        +  sh*b-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
        +  sh*-*-linux2)  OUT="linux-generic32"; options="$options -DL_ENDIAN" ;;
        +  m68k*-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
        +  s390-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
        +  s390x-*-linux2)
        +	# To be uncommented when glibc bug is fixed, see Configure...
        +	#if egrep -e '^features.* highgprs' /proc/cpuinfo >/dev/null ; then
        +	#  echo "WARNING! If you wish to build \"highgprs\" 32-bit library, then you"
        +	#  echo "         have to invoke './Configure linux32-s390x' *manually*."
        +	#  if [ "$TEST" = "false" -a -t -1 ]; then
        +	#    echo "         You have about 5 seconds to press Ctrl-C to abort."
        +	#    (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +	#  fi
        +	#fi
        +	OUT="linux64-s390x"
        +	;;
        +  x86_64-*-linux?) OUT="linux-x86_64" ;;
        +  *86-*-linux2) OUT="linux-elf"
        +	if [ "$GCCVER" -gt 28 ]; then
        +          if grep '^model.*Pentium' /proc/cpuinfo >/dev/null ; then
        +	    options="$options -march=pentium"
        +          fi
        +          if grep '^model.*Pentium Pro' /proc/cpuinfo >/dev/null ; then
        +	    options="$options -march=pentiumpro"
        +          fi
        +          if grep '^model.*K6' /proc/cpuinfo >/dev/null ; then
        +	    options="$options -march=k6"
        +          fi
        +        fi ;;
        +  *-*-linux1) OUT="linux-aout" ;;
        +  *-*-linux2) OUT="linux-generic32" ;;
        +  sun4[uv]*-*-solaris2)
        +	OUT="solaris-sparcv9-$CC"
        +	ISA64=`(isalist) 2>/dev/null | grep sparcv9`
        +	if [ "$ISA64" != "" -a "$KERNEL_BITS" = "" ]; then
        +	    if [ "$CC" = "cc" -a $CCVER -ge 50 ]; then
        +		echo "WARNING! If you wish to build 64-bit library, then you have to"
        +		echo "         invoke './Configure solaris64-sparcv9-cc' *manually*."
        +		if [ "$TEST" = "false" -a -t 1 ]; then
        +		  echo "         You have about 5 seconds to press Ctrl-C to abort."
        +		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +		fi
        +	    elif [ "$CC" = "gcc" -a "$GCC_ARCH" = "-m64" ]; then
        +		# $GCC_ARCH denotes default ABI chosen by compiler driver
        +		# (first one found on the $PATH). I assume that user
        +		# expects certain consistency with the rest of his builds
        +		# and therefore switch over to 64-bit. <appro>
        +		OUT="solaris64-sparcv9-gcc"
        +		echo "WARNING! If you wish to build 32-bit library, then you have to"
        +		echo "         invoke './Configure solaris-sparcv9-gcc' *manually*."
        +		if [ "$TEST" = "false" -a -t 1 ]; then
        +		  echo "         You have about 5 seconds to press Ctrl-C to abort."
        +		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +		fi
        +	    elif [ "$GCC_ARCH" = "-m32" ]; then
        +		echo "NOTICE! If you *know* that your GNU C supports 64-bit/V9 ABI"
        +		echo "        and wish to build 64-bit library, then you have to"
        +		echo "        invoke './Configure solaris64-sparcv9-gcc' *manually*."
        +		if [ "$TEST" = "false" -a -t 1 ]; then
        +		  echo "         You have about 5 seconds to press Ctrl-C to abort."
        +		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +		fi
        +	    fi
        +	fi
        +	if [ "$ISA64" != "" -a "$KERNEL_BITS" = "64" ]; then
        +	    OUT="solaris64-sparcv9-$CC"
        +	fi
        +	;;
        +  sun4m-*-solaris2)	OUT="solaris-sparcv8-$CC" ;;
        +  sun4d-*-solaris2)	OUT="solaris-sparcv8-$CC" ;;
        +  sun4*-*-solaris2)	OUT="solaris-sparcv7-$CC" ;;
        +  *86*-*-solaris2)
        +	ISA64=`(isalist) 2>/dev/null | grep amd64`
        +	if [ "$ISA64" != "" -a ${KERNEL_BITS:-64} -eq 64 ]; then
        +	    OUT="solaris64-x86_64-$CC"
        +	else
        +	    OUT="solaris-x86-$CC"
        +	    if [ `uname -r | sed -e 's/5\.//'` -lt 10 ]; then
        +		options="$options no-sse2"
        +	    fi
        +	fi
        +	;;
        +  *-*-sunos4)		OUT="sunos-$CC" ;;
        +
        +  *86*-*-bsdi4)		OUT="BSD-x86-elf"; options="$options no-sse2 -ldl" ;;
        +  alpha*-*-*bsd*)	OUT="BSD-generic64"; options="$options -DL_ENDIAN" ;;
        +  powerpc64-*-*bsd*)	OUT="BSD-generic64"; options="$options -DB_ENDIAN" ;;
        +  sparc64-*-*bsd*)	OUT="BSD-sparc64" ;;
        +  ia64-*-*bsd*)		OUT="BSD-ia64" ;;
        +  amd64-*-*bsd*)	OUT="BSD-x86_64" ;;
        +  *86*-*-*bsd*)		# mimic ld behaviour when it's looking for libc...
        +			if [ -L /usr/lib/libc.so ]; then	# [Free|Net]BSD
        +			    libc=/usr/lib/libc.so
        +			else					# OpenBSD
        +			    # ld searches for highest libc.so.* and so do we
        +			    libc=`(ls /usr/lib/libc.so.* | tail -1) 2>/dev/null`
        +			fi
        +			case "`(file -L $libc) 2>/dev/null`" in
        +			*ELF*)	OUT="BSD-x86-elf" ;;
        +			*)	OUT="BSD-x86"; options="$options no-sse2" ;;
        +			esac ;;
        +  *-*-*bsd*)		OUT="BSD-generic32" ;;
        +
        +  *-*-osf)		OUT="osf1-alpha-cc" ;;
        +  *-*-tru64)		OUT="tru64-alpha-cc" ;;
        +  *-*-[Uu]nix[Ww]are7)
        +	if [ "$CC" = "gcc" ]; then
        +	  OUT="unixware-7-gcc" ; options="$options no-sse2"
        +	else    
        +	  OUT="unixware-7" ; options="$options no-sse2 -D__i386__"
        +	fi
        +	;;
        +  *-*-[Uu]nix[Ww]are20*) OUT="unixware-2.0"; options="$options no-sse2 no-sha512" ;;
        +  *-*-[Uu]nix[Ww]are21*) OUT="unixware-2.1"; options="$options no-sse2 no-sha512" ;;
        +  *-*-vos)
        +	options="$options no-threads no-shared no-asm no-dso"
        +	EXE=".pm"
        +	OUT="vos-$CC" ;;
        +  BS2000-siemens-sysv4) OUT="BS2000-OSD" ;;
        +  RM*-siemens-sysv4) OUT="ReliantUNIX" ;;
        +  *-siemens-sysv4) OUT="SINIX" ;;
        +  *-hpux1*)
        +	if [ $CC = "gcc" -a $GCC_BITS = "64" ]; then
        +	    OUT="hpux64-parisc2-gcc"
        +	fi
        +	[ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITS) 2>/dev/null`
        +	KERNEL_BITS=${KERNEL_BITS:-32}
        +	CPU_VERSION=`(getconf CPU_VERSION) 2>/dev/null`
        +	CPU_VERSION=${CPU_VERSION:-0}
        +	# See <sys/unistd.h> for further info on CPU_VERSION.
        +	if   [ $CPU_VERSION -ge 768 ]; then	# IA-64 CPU
        +	     if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
        +	        OUT="hpux64-ia64-cc"
        +             else
        +	        OUT="hpux-ia64-cc"
        +             fi
        +	elif [ $CPU_VERSION -ge 532 ]; then	# PA-RISC 2.x CPU
        +	     OUT=${OUT:-"hpux-parisc2-${CC}"}
        +	     if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
        +		echo "WARNING! If you wish to build 64-bit library then you have to"
        +		echo "         invoke './Configure hpux64-parisc2-cc' *manually*."
        +		if [ "$TEST" = "false" -a -t 1 ]; then
        +		  echo "         You have about 5 seconds to press Ctrl-C to abort."
        +		  (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +		fi
        +	     fi
        +	elif [ $CPU_VERSION -ge 528 ]; then	# PA-RISC 1.1+ CPU
        +	     OUT="hpux-parisc-${CC}"
        +	elif [ $CPU_VERSION -ge 523 ]; then	# PA-RISC 1.0 CPU
        +	     OUT="hpux-parisc-${CC}"
        +	else					# Motorola(?) CPU
        +	     OUT="hpux-$CC"
        +	fi
        +	options="$options -D_REENTRANT" ;;
        +  *-hpux)	OUT="hpux-parisc-$CC" ;;
        +  *-aix)
        +	[ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITMODE) 2>/dev/null`
        +	KERNEL_BITS=${KERNEL_BITS:-32}
        +	OBJECT_MODE=${OBJECT_MODE:-32}
        +	if [ "$CC" = "gcc" ]; then
        +	    OUT="aix-gcc"
        +          if [ $OBJECT_MODE -eq 64 ]; then
        +            echo 'Your $OBJECT_MODE was found to be set to 64'
        +            OUT="aix64-gcc"
        +          fi
        +	elif [ $OBJECT_MODE -eq 64 ]; then
        +	    echo 'Your $OBJECT_MODE was found to be set to 64' 
        +	    OUT="aix64-cc"
        +	else
        +	    OUT="aix-cc"
        +	    if [ $KERNEL_BITS -eq 64 ]; then
        +		echo "WARNING! If you wish to build 64-bit kit, then you have to"
        +		echo "         invoke './Configure aix64-cc' *manually*."
        +		if [ "$TEST" = "false" -a -t 1 ]; then
        +		    echo "         You have ~5 seconds to press Ctrl-C to abort."
        +		    (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1
        +		fi
        +	    fi
        +	fi
        +	if (lsattr -E -O -l `lsdev -c processor|awk '{print$1;exit}'` | grep -i powerpc) >/dev/null 2>&1; then
        +	    :	# this applies even to Power3 and later, as they return PowerPC_POWER[345]
        +	else
        +	    options="$options no-asm"
        +	fi
        +	;;
        +  # these are all covered by the catchall below
        +  # *-dgux) OUT="dgux" ;;
        +  mips-sony-newsos4) OUT="newsos4-gcc" ;;
        +  *-*-cygwin_pre1.3) OUT="Cygwin-pre1.3" ;;
        +  *-*-cygwin) OUT="Cygwin" ;;
        +  t3e-cray-unicosmk) OUT="cray-t3e" ;;
        +  j90-cray-unicos) OUT="cray-j90" ;;
        +  nsr-tandem-nsk) OUT="tandem-c89" ;;
        +  beos-*) OUT="$GUESSOS" ;;
        +  x86pc-*-qnx6) OUT="QNX6-i386" ;;
        +  *-*-qnx6) OUT="QNX6" ;;
        +  x86-*-android|i?86-*-android) OUT="android-x86" ;;
        +  armv[7-9]*-*-android) OUT="android-armv7" ;;
        +  *) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
        +esac
        +
        +# NB: This atalla support has been superceded by the ENGINE support
        +# That contains its own header and definitions anyway. Support can
        +# be enabled or disabled on any supported platform without external
        +# headers, eg. by adding the "hw-atalla" switch to ./config or
        +# perl Configure
        +#
        +# See whether we can compile Atalla support
        +#if [ -f /usr/include/atasi.h ]
        +#then
        +#  options="$options -DATALLA"
        +#fi
        +
        +if expr "$options" : '.*no\-asm' > /dev/null; then :; else
        +  sh -c "$CROSS_COMPILE${CC:-gcc} -Wa,--help -c -o /tmp/null.$$.o -x assembler /dev/null && rm /tmp/null.$$.o" 2>&1 | \
        +  grep \\--noexecstack >/dev/null && \
        +  options="$options -Wa,--noexecstack"
        +fi
        +
        +# gcc < 2.8 does not support -march=ultrasparc
        +if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ]
        +then
        +  echo "WARNING! Falling down to 'solaris-sparcv8-gcc'."
        +  echo "         Upgrade to gcc-2.8 or later."
        +  sleep 5
        +  OUT=solaris-sparcv8-gcc
        +fi
        +if [ "$OUT" = "linux-sparcv9" -a $GCCVER -lt 28 ]
        +then
        +  echo "WARNING! Falling down to 'linux-sparcv8'."
        +  echo "         Upgrade to gcc-2.8 or later."
        +  sleep 5
        +  OUT=linux-sparcv8
        +fi
        +
        +case "$GUESSOS" in
        +  i386-*) options="$options 386" ;;
        +esac
        +
        +for i in aes bf camellia cast des dh dsa ec hmac idea md2 md5 mdc2 rc2 rc4 rc5 ripemd rsa seed sha
        +do
        +  if [ ! -d crypto/$i ]
        +  then
        +    options="$options no-$i"
        +  fi
        +done
        +
        +# Discover Kerberos 5 (since it's still a prototype, we don't
        +# do any guesses yet, that's why this section is commented away.
        +#if [ -d /usr/kerberos ]; then
        +#    krb5_dir=/usr/kerberos
        +#    if [ \( -f $krb5_dir/lib/libgssapi_krb5.a -o -f $krb5_dir/lib/libgssapi_krb5.so* \)\
        +#	-a \( -f $krb5_dir/lib/libkrb5.a -o -f $krb5_dir/lib/libkrb5.so* \)\
        +#	-a \( -f $krb5_dir/lib/libcom_err.a -o -f $krb5_dir/lib/libcom_err.so* \)\
        +#	-a \( -f $krb5_dir/lib/libk5crypto.a -o -f $krb5_dir/lib/libk5crypto.so* \)\
        +#	-a \( -f $krb5_dir/include/krb5.h \) ]; then
        +#	options="$options --with-krb5-flavor=MIT"
        +#    fi
        +#elif [ -d /usr/heimdal ]; then
        +#    krb5_dir=/usr/heimdal
        +#    if [ \( -f $krb5_dir/lib/libgssapi.a -o -f $krb5_dir/lib/libgssapi.so* \)\
        +#	-a \( -f $krb5_dir/lib/libkrb5.a -o -f $krb5_dir/lib/libkrb5.so* \)\
        +#	-a \( -f $krb5_dir/lib/libcom_err.a -o -f $krb5_dir/lib/libcom_err.so* \)\
        +#	-a \( -f $krb5_dir/include/krb5.h \) ]; then
        +#	options="$options --with-krb5-flavor=Heimdal"
        +#    fi
        +#fi
        +
        +if [ -z "$OUT" ]; then
        +  OUT="$CC"
        +fi
        +
        +if [ ".$PERL" = . ] ; then
        +	for i in . `echo $PATH | sed 's/:/ /g'`; do
        +		if [ -f "$i/perl5$EXE" ] ; then
        +			PERL="$i/perl5$EXE"
        +			break;
        +		fi;
        +	done
        +fi
        +
        +if [ ".$PERL" = . ] ; then
        +	for i in . `echo $PATH | sed 's/:/ /g'`; do
        +		if [ -f "$i/perl$EXE" ] ; then
        +			if "$i/perl$EXE" -e 'exit($]<5.0)'; then
        +				PERL="$i/perl$EXE"
        +				break;
        +			fi;
        +		fi;
        +	done
        +fi
        +
        +if [ ".$PERL" = . ] ; then
        +	echo "You need Perl 5."
        +	exit 1
        +fi
        +
        +# run Configure to check to see if we need to specify the 
        +# compiler for the platform ... in which case we add it on
        +# the end ... otherwise we leave it off
        +
        +$PERL ./Configure LIST | grep "$OUT-$CC" > /dev/null
        +if [ $? = "0" ]; then
        +  OUT="$OUT-$CC"
        +fi
        +
        +OUT="$PREFIX$OUT"
        +
        +$PERL ./Configure LIST | grep "$OUT" > /dev/null
        +if [ $? = "0" ]; then
        +  echo Configuring for $OUT
        +
        +  if [ "$TEST" = "true" ]; then
        +    echo $PERL ./Configure $OUT $options
        +  else
        +    $PERL ./Configure $OUT $options
        +  fi
        +else
        +  echo "This system ($OUT) is not supported. See file INSTALL for details."
        +fi
        +)
        diff --git a/vendor/openssl/openssl/crypto/LPdir_nyi.c b/vendor/openssl/openssl/crypto/LPdir_nyi.c
        new file mode 100644
        index 000000000..6c1a50e6a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/LPdir_nyi.c
        @@ -0,0 +1,42 @@
        +/* $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + */
        +
        +#ifndef LPDIR_H
        +#include "LPdir.h"
        +#endif
        +
        +struct LP_dir_context_st { void *dummy; };
        +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
        +	{
        +	errno = EINVAL;
        +	return 0;
        +	}
        +int LP_find_file_end(LP_DIR_CTX **ctx)
        +	{
        +	errno = EINVAL;
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/LPdir_unix.c b/vendor/openssl/openssl/crypto/LPdir_unix.c
        new file mode 100644
        index 000000000..b004cd99e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/LPdir_unix.c
        @@ -0,0 +1,127 @@
        +/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 
        + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#include <stddef.h>
        +#include <stdlib.h>
        +#include <limits.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include <dirent.h>
        +#include <errno.h>
        +#ifndef LPDIR_H
        +#include "LPdir.h"
        +#endif
        +
        +/* The POSIXly macro for the maximum number of characters in a file path
        +   is NAME_MAX.  However, some operating systems use PATH_MAX instead.
        +   Therefore, it seems natural to first check for PATH_MAX and use that,
        +   and if it doesn't exist, use NAME_MAX. */
        +#if defined(PATH_MAX)
        +# define LP_ENTRY_SIZE PATH_MAX
        +#elif defined(NAME_MAX)
        +# define LP_ENTRY_SIZE NAME_MAX
        +#endif
        +
        +/* Of course, there's the possibility that neither PATH_MAX nor NAME_MAX
        +   exist.  It's also possible that NAME_MAX exists but is define to a
        +   very small value (HP-UX offers 14), so we need to check if we got a
        +   result, and if it meets a minimum standard, and create or change it
        +   if not. */
        +#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255
        +# undef LP_ENTRY_SIZE
        +# define LP_ENTRY_SIZE 255
        +#endif
        +
        +struct LP_dir_context_st
        +{
        +  DIR *dir;
        +  char entry_name[LP_ENTRY_SIZE+1];
        +};
        +
        +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
        +{
        +  struct dirent *direntry = NULL;
        +
        +  if (ctx == NULL || directory == NULL)
        +    {
        +      errno = EINVAL;
        +      return 0;
        +    }
        +
        +  errno = 0;
        +  if (*ctx == NULL)
        +    {
        +      *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
        +      if (*ctx == NULL)
        +	{
        +	  errno = ENOMEM;
        +	  return 0;
        +	}
        +      memset(*ctx, '\0', sizeof(LP_DIR_CTX));
        +
        +      (*ctx)->dir = opendir(directory);
        +      if ((*ctx)->dir == NULL)
        +	{
        +	  int save_errno = errno; /* Probably not needed, but I'm paranoid */
        +	  free(*ctx);
        +	  *ctx = NULL;
        +	  errno = save_errno;
        +	  return 0;
        +	}
        +    }
        +
        +  direntry = readdir((*ctx)->dir);
        +  if (direntry == NULL)
        +    {
        +      return 0;
        +    }
        +
        +  strncpy((*ctx)->entry_name, direntry->d_name, sizeof((*ctx)->entry_name) - 1);
        +  (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
        +  return (*ctx)->entry_name;
        +}
        +
        +int LP_find_file_end(LP_DIR_CTX **ctx)
        +{
        +  if (ctx != NULL && *ctx != NULL)
        +    {
        +      int ret = closedir((*ctx)->dir);
        +
        +      free(*ctx);
        +      switch (ret)
        +	{
        +	case 0:
        +	  return 1;
        +	case -1:
        +	  return 0;
        +	default:
        +	  break;
        +	}
        +    }
        +  errno = EINVAL;
        +  return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/LPdir_vms.c b/vendor/openssl/openssl/crypto/LPdir_vms.c
        new file mode 100644
        index 000000000..7613bd254
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/LPdir_vms.c
        @@ -0,0 +1,206 @@
        +/* $LP: LPlib/source/LPdir_vms.c,v 1.20 2004/08/26 13:36:05 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 
        + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#include <stddef.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <errno.h>
        +#include <descrip.h>
        +#include <namdef.h>
        +#include <rmsdef.h>
        +#include <libfildef.h>
        +#include <lib$routines.h>
        +#include <strdef.h>
        +#include <str$routines.h>
        +#include <stsdef.h>
        +#ifndef LPDIR_H
        +#include "LPdir.h"
        +#endif
        +#include "vms_rms.h"
        +
        +/* Some compiler options hide EVMSERR. */
        +#ifndef EVMSERR
        +# define EVMSERR	65535  /* error for non-translatable VMS errors */
        +#endif
        +
        +struct LP_dir_context_st
        +{
        +  unsigned long VMS_context;
        +  char filespec[ NAMX_MAXRSS+ 1];
        +  char result[ NAMX_MAXRSS+ 1];
        +  struct dsc$descriptor_d filespec_dsc;
        +  struct dsc$descriptor_d result_dsc;
        +};
        +
        +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
        +{
        +  int status;
        +  char *p, *r;
        +  size_t l;
        +  unsigned long flags = 0;
        +
        +/* Arrange 32-bit pointer to (copied) string storage, if needed. */
        +#if __INITIAL_POINTER_SIZE == 64
        +# pragma pointer_size save
        +# pragma pointer_size 32
        +        char *ctx_filespec_32p;
        +# pragma pointer_size restore
        +        char ctx_filespec_32[ NAMX_MAXRSS+ 1];
        +#endif /* __INITIAL_POINTER_SIZE == 64 */
        +
        +#ifdef NAML$C_MAXRSS
        +  flags |= LIB$M_FIL_LONG_NAMES;
        +#endif
        +
        +  if (ctx == NULL || directory == NULL)
        +    {
        +      errno = EINVAL;
        +      return 0;
        +    }
        +
        +  errno = 0;
        +  if (*ctx == NULL)
        +    {
        +      size_t filespeclen = strlen(directory);
        +      char *filespec = NULL;
        +
        +      /* MUST be a VMS directory specification!  Let's estimate if it is. */
        +      if (directory[filespeclen-1] != ']'
        +	  && directory[filespeclen-1] != '>'
        +	  && directory[filespeclen-1] != ':')
        +	{
        +	  errno = EINVAL;
        +	  return 0;
        +	}
        +
        +      filespeclen += 4;		/* "*.*;" */
        +
        +      if (filespeclen > NAMX_MAXRSS)
        +	{
        +	  errno = ENAMETOOLONG;
        +	  return 0;
        +	}
        +
        +      *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
        +      if (*ctx == NULL)
        +	{
        +	  errno = ENOMEM;
        +	  return 0;
        +	}
        +      memset(*ctx, '\0', sizeof(LP_DIR_CTX));
        +
        +      strcpy((*ctx)->filespec,directory);
        +      strcat((*ctx)->filespec,"*.*;");
        +
        +/* Arrange 32-bit pointer to (copied) string storage, if needed. */
        +#if __INITIAL_POINTER_SIZE == 64
        +# define CTX_FILESPEC ctx_filespec_32p
        +        /* Copy the file name to storage with a 32-bit pointer. */
        +        ctx_filespec_32p = ctx_filespec_32;
        +        strcpy( ctx_filespec_32p, (*ctx)->filespec);
        +#else /* __INITIAL_POINTER_SIZE == 64 */
        +# define CTX_FILESPEC (*ctx)->filespec
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +      (*ctx)->filespec_dsc.dsc$w_length = filespeclen;
        +      (*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
        +      (*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
        +      (*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
        +    }
        +
        +  (*ctx)->result_dsc.dsc$w_length = 0;
        +  (*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
        +  (*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
        +  (*ctx)->result_dsc.dsc$a_pointer = 0;
        +
        +  status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
        +			 &(*ctx)->VMS_context, 0, 0, 0, &flags);
        +
        +  if (status == RMS$_NMF)
        +    {
        +      errno = 0;
        +      vaxc$errno = status;
        +      return NULL;
        +    }
        +
        +  if(!$VMS_STATUS_SUCCESS(status))
        +    {
        +      errno = EVMSERR;
        +      vaxc$errno = status;
        +      return NULL;
        +    }
        +
        +  /* Quick, cheap and dirty way to discard any device and directory,
        +     since we only want file names */
        +  l = (*ctx)->result_dsc.dsc$w_length;
        +  p = (*ctx)->result_dsc.dsc$a_pointer;
        +  r = p;
        +  for (; *p; p++)
        +    {
        +      if (*p == '^' && p[1] != '\0') /* Take care of ODS-5 escapes */
        +	{
        +	  p++;
        +	}
        +      else if (*p == ':' || *p == '>' || *p == ']')
        +	{
        +	  l -= p + 1 - r;
        +	  r = p + 1;
        +	}
        +      else if (*p == ';')
        +	{
        +	  l = p - r;
        +	  break;
        +	}
        +    }
        +
        +  strncpy((*ctx)->result, r, l);
        +  (*ctx)->result[l] = '\0';
        +  str$free1_dx(&(*ctx)->result_dsc);
        +
        +  return (*ctx)->result;
        +}
        +
        +int LP_find_file_end(LP_DIR_CTX **ctx)
        +{
        +  if (ctx != NULL && *ctx != NULL)
        +    {
        +      int status = lib$find_file_end(&(*ctx)->VMS_context);
        +
        +      free(*ctx);
        +
        +      if(!$VMS_STATUS_SUCCESS(status))
        +	{
        +	  errno = EVMSERR;
        +	  vaxc$errno = status;
        +	  return 0;
        +	}
        +      return 1;
        +    }
        +  errno = EINVAL;
        +  return 0;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/LPdir_win.c b/vendor/openssl/openssl/crypto/LPdir_win.c
        new file mode 100644
        index 000000000..702dbc730
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/LPdir_win.c
        @@ -0,0 +1,153 @@
        +/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 
        + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +#include <windows.h>
        +#include <tchar.h>
        +#ifndef LPDIR_H
        +#include "LPdir.h"
        +#endif
        +
        +/* We're most likely overcautious here, but let's reserve for
        +    broken WinCE headers and explicitly opt for UNICODE call.
        +    Keep in mind that our WinCE builds are compiled with -DUNICODE
        +    [as well as -D_UNICODE]. */
        +#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
        +# define FindFirstFile FindFirstFileW
        +#endif
        +#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
        +# define FindNextFile FindNextFileW
        +#endif
        +
        +#ifndef NAME_MAX
        +#define NAME_MAX 255
        +#endif
        +
        +struct LP_dir_context_st
        +{
        +  WIN32_FIND_DATA ctx;
        +  HANDLE handle;
        +  char entry_name[NAME_MAX+1];
        +};
        +
        +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
        +{
        +  if (ctx == NULL || directory == NULL)
        +    {
        +      errno = EINVAL;
        +      return 0;
        +    }
        +
        +  errno = 0;
        +  if (*ctx == NULL)
        +    {
        +      *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
        +      if (*ctx == NULL)
        +	{
        +	  errno = ENOMEM;
        +	  return 0;
        +	}
        +      memset(*ctx, '\0', sizeof(LP_DIR_CTX));
        +
        +      if (sizeof(TCHAR) != sizeof(char))
        +	{
        +	  TCHAR *wdir = NULL;
        +	  /* len_0 denotes string length *with* trailing 0 */ 
        +	  size_t index = 0,len_0 = strlen(directory) + 1;
        +
        +	  wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
        +	  if (wdir == NULL)
        +	    {
        +	      free(*ctx);
        +	      *ctx = NULL;
        +	      errno = ENOMEM;
        +	      return 0;
        +	    }
        +
        +#ifdef LP_MULTIBYTE_AVAILABLE
        +	  if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0))
        +#endif
        +	    for (index = 0; index < len_0; index++)
        +	      wdir[index] = (TCHAR)directory[index];
        +
        +	  (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
        +
        +	  free(wdir);
        +	}
        +      else
        +	(*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
        +
        +      if ((*ctx)->handle == INVALID_HANDLE_VALUE)
        +	{
        +	  free(*ctx);
        +	  *ctx = NULL;
        +	  errno = EINVAL;
        +	  return 0;
        +	}
        +    }
        +  else
        +    {
        +      if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE)
        +	{
        +	  return 0;
        +	}
        +    }
        +
        +  if (sizeof(TCHAR) != sizeof(char))
        +    {
        +      TCHAR *wdir = (*ctx)->ctx.cFileName;
        +      size_t index, len_0 = 0;
        +
        +      while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) len_0++;
        +      len_0++;
        +
        +#ifdef LP_MULTIBYTE_AVAILABLE
        +      if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
        +			       sizeof((*ctx)->entry_name), NULL, 0))
        +#endif
        +	for (index = 0; index < len_0; index++)
        +	  (*ctx)->entry_name[index] = (char)wdir[index];
        +    }
        +  else
        +    strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
        +	    sizeof((*ctx)->entry_name)-1);
        +
        +  (*ctx)->entry_name[sizeof((*ctx)->entry_name)-1] = '\0';
        +
        +  return (*ctx)->entry_name;
        +}
        +
        +int LP_find_file_end(LP_DIR_CTX **ctx)
        +{
        +  if (ctx != NULL && *ctx != NULL)
        +    {
        +      FindClose((*ctx)->handle);
        +      free(*ctx);
        +      *ctx = NULL;
        +      return 1;
        +    }
        +  errno = EINVAL;
        +  return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/LPdir_win32.c b/vendor/openssl/openssl/crypto/LPdir_win32.c
        new file mode 100644
        index 000000000..e39872da5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/LPdir_win32.c
        @@ -0,0 +1,30 @@
        +/* $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 
        + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#define LP_SYS_WIN32
        +#define LP_MULTIBYTE_AVAILABLE
        +#include "LPdir_win.c"
        diff --git a/vendor/openssl/openssl/crypto/LPdir_wince.c b/vendor/openssl/openssl/crypto/LPdir_wince.c
        new file mode 100644
        index 000000000..ab0e1e6f4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/LPdir_wince.c
        @@ -0,0 +1,31 @@
        +/* $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 
        + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#define LP_SYS_WINCE
        +/* We might want to define LP_MULTIBYTE_AVAILABLE here.  It's currently
        +   under investigation what the exact conditions would be */
        +#include "LPdir_win.c"
        diff --git a/vendor/openssl/openssl/crypto/Makefile b/vendor/openssl/openssl/crypto/Makefile
        new file mode 100644
        index 000000000..947dd5d44
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/Makefile
        @@ -0,0 +1,217 @@
        +#
        +# OpenSSL/crypto/Makefile
        +#
        +
        +DIR=		crypto
        +TOP=		..
        +CC=		cc
        +INCLUDE=	-I. -I$(TOP) -I../include $(ZLIB_INCLUDE)
        +# INCLUDES targets sudbirs!
        +INCLUDES=	-I.. -I../.. -I../modes -I../asn1 -I../evp -I../../include $(ZLIB_INCLUDE)
        +CFLAG=		-g
        +MAKEDEPPROG=	makedepend
        +MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
        +MAKEFILE=       Makefile
        +RM=             rm -f
        +AR=		ar r
        +
        +RECURSIVE_MAKE=	[ -n "$(SDIRS)" ] && for i in $(SDIRS) ; do \
        +		    (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
        +		    $(MAKE) -e TOP=../.. DIR=$$i INCLUDES='$(INCLUDES)' $$target ) || exit 1; \
        +		done;
        +
        +PEX_LIBS=
        +EX_LIBS=
        + 
        +CFLAGS= $(INCLUDE) $(CFLAG)
        +ASFLAGS= $(INCLUDE) $(ASFLAG)
        +AFLAGS=$(ASFLAGS)
        +CPUID_OBJ=mem_clr.o
        +
        +LIBS=
        +
        +GENERAL=Makefile README crypto-lib.com install.com
        +
        +LIB= $(TOP)/libcrypto.a
        +SHARED_LIB= libcrypto$(SHLIB_EXT)
        +LIBSRC=	cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
        +	ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c
        +LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \
        +	uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
        +	ossl_typ.h
        +HEADER=	cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	@(cd ..; $(MAKE) DIRS=$(DIR) all)
        +
        +all: shared
        +
        +buildinf.h: ../Makefile
        +	( echo "#ifndef MK1MF_BUILD"; \
        +	echo '  /* auto-generated by crypto/Makefile for crypto/cversion.c */'; \
        +	echo '  #define CFLAGS "$(CC) $(CFLAG)"'; \
        +	echo '  #define PLATFORM "$(PLATFORM)"'; \
        +	echo "  #define DATE \"`LC_ALL=C LC_TIME=C date`\""; \
        +	echo '#endif' ) >buildinf.h
        +
        +x86cpuid.s:	x86cpuid.pl perlasm/x86asm.pl
        +	$(PERL) x86cpuid.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +
        +applink.o:	$(TOP)/ms/applink.c
        +	$(CC) $(CFLAGS) -c -o $@ $(TOP)/ms/applink.c
        +
        +uplink.o:	$(TOP)/ms/uplink.c applink.o
        +	$(CC) $(CFLAGS) -c -o $@ $(TOP)/ms/uplink.c
        +
        +uplink-x86.s:	$(TOP)/ms/uplink-x86.pl
        +	$(PERL) $(TOP)/ms/uplink-x86.pl $(PERLASM_SCHEME) > $@
        +
        +x86_64cpuid.s: x86_64cpuid.pl;	$(PERL) x86_64cpuid.pl $(PERLASM_SCHEME) > $@
        +ia64cpuid.s: ia64cpuid.S;	$(CC) $(CFLAGS) -E ia64cpuid.S > $@
        +ppccpuid.s:	ppccpuid.pl;	$(PERL) ppccpuid.pl $(PERLASM_SCHEME) $@
        +pariscid.s:	pariscid.pl;	$(PERL) pariscid.pl $(PERLASM_SCHEME) $@
        +alphacpuid.s:	alphacpuid.pl
        +	$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
        +
        +testapps:
        +	[ -z "$(THIS)" ] || (	if echo $(SDIRS) | fgrep ' des '; \
        +				then cd des && $(MAKE) -e des; fi )
        +	[ -z "$(THIS)" ] || ( cd pkcs7 && $(MAKE) -e testapps );
        +	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
        +
        +subdirs:
        +	@target=all; $(RECURSIVE_MAKE)
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +	@target=files; $(RECURSIVE_MAKE)
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../apps $(APPS)
        +	@target=links; $(RECURSIVE_MAKE)
        +
        +# lib: $(LIB): are splitted to avoid end-less loop
        +lib:	$(LIB)
        +	@touch lib
        +$(LIB):	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	[ -z "$(FIPSLIBDIR)" ] || $(AR) $(LIB) $(FIPSLIBDIR)fipscanister.o
        +	$(RANLIB) $(LIB) || echo Never mind.
        +
        +shared: buildinf.h lib subdirs
        +	if [ -n "$(SHARED_LIBS)" ]; then \
        +		(cd ..; $(MAKE) $(SHARED_LIB)); \
        +	fi
        +
        +libs:
        +	@target=lib; $(RECURSIVE_MAKE)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ;\
        +	do \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +	@target=install; $(RECURSIVE_MAKE)
        +
        +lint:
        +	@target=lint; $(RECURSIVE_MAKE)
        +
        +depend:
        +	@[ -z "$(THIS)" -o -f buildinf.h ] || touch buildinf.h # fake buildinf.h if it does not exist
        +	@[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
        +	@[ -z "$(THIS)" -o -s buildinf.h ] || rm buildinf.h
        +	@[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
        +	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
        +
        +clean:
        +	rm -f buildinf.h *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +	@target=clean; $(RECURSIVE_MAKE)
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +	rm -f opensslconf.h
        +	@target=dclean; $(RECURSIVE_MAKE)
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +cpt_err.o: ../include/openssl/bio.h ../include/openssl/crypto.h
        +cpt_err.o: ../include/openssl/e_os2.h ../include/openssl/err.h
        +cpt_err.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
        +cpt_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +cpt_err.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +cpt_err.o: ../include/openssl/symhacks.h cpt_err.c
        +cryptlib.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
        +cryptlib.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +cryptlib.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +cryptlib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +cryptlib.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +cryptlib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.c
        +cryptlib.o: cryptlib.h
        +cversion.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
        +cversion.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +cversion.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +cversion.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +cversion.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +cversion.o: ../include/openssl/stack.h ../include/openssl/symhacks.h buildinf.h
        +cversion.o: cryptlib.h cversion.c
        +ebcdic.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h ebcdic.c
        +ex_data.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
        +ex_data.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +ex_data.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +ex_data.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
        +ex_data.o: ex_data.c
        +fips_ers.o: ../include/openssl/opensslconf.h fips_ers.c
        +mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
        +mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +mem.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +mem.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +mem.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +mem.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
        +mem.o: mem.c
        +mem_clr.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +mem_clr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +mem_clr.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +mem_clr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h mem_clr.c
        +mem_dbg.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
        +mem_dbg.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +mem_dbg.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +mem_dbg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +mem_dbg.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +mem_dbg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
        +mem_dbg.o: mem_dbg.c
        +o_dir.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
        +o_dir.o: LPdir_unix.c o_dir.c o_dir.h
        +o_fips.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
        +o_fips.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +o_fips.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +o_fips.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +o_fips.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +o_fips.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
        +o_fips.o: o_fips.c
        +o_init.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/crypto.h
        +o_init.o: ../include/openssl/e_os2.h ../include/openssl/err.h
        +o_init.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
        +o_init.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +o_init.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +o_init.o: ../include/openssl/symhacks.h o_init.c
        +o_str.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
        +o_str.o: o_str.c o_str.h
        +o_time.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_time.c
        +o_time.o: o_time.h
        +uid.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +uid.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +uid.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +uid.o: ../include/openssl/stack.h ../include/openssl/symhacks.h uid.c
        diff --git a/vendor/openssl/openssl/crypto/aes/Makefile b/vendor/openssl/openssl/crypto/aes/Makefile
        new file mode 100644
        index 000000000..45ede0a0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/Makefile
        @@ -0,0 +1,153 @@
        +#
        +# crypto/aes/Makefile
        +#
        +
        +DIR=	aes
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +AES_ENC=aes_core.o aes_cbc.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +#TEST=aestest.c
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=aes_core.c aes_misc.c aes_ecb.c aes_cbc.c aes_cfb.c aes_ofb.c \
        +       aes_ctr.c aes_ige.c aes_wrap.c
        +LIBOBJ=aes_misc.o aes_ecb.o aes_cfb.o aes_ofb.o aes_ctr.o aes_ige.o aes_wrap.o \
        +       $(AES_ENC)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= aes.h
        +HEADER= aes_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) || echo Never mind.
        +	@touch lib
        +
        +aes-ia64.s: asm/aes-ia64.S
        +	$(CC) $(CFLAGS) -E asm/aes-ia64.S > $@
        +
        +aes-586.s:	asm/aes-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/aes-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +vpaes-x86.s:	asm/vpaes-x86.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/vpaes-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +aesni-x86.s:	asm/aesni-x86.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/aesni-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +
        +aes-x86_64.s: asm/aes-x86_64.pl
        +	$(PERL) asm/aes-x86_64.pl $(PERLASM_SCHEME) > $@
        +vpaes-x86_64.s:	asm/vpaes-x86_64.pl
        +	$(PERL) asm/vpaes-x86_64.pl $(PERLASM_SCHEME) > $@
        +bsaes-x86_64.s:	asm/bsaes-x86_64.pl
        +	$(PERL) asm/bsaes-x86_64.pl $(PERLASM_SCHEME) > $@
        +aesni-x86_64.s: asm/aesni-x86_64.pl
        +	$(PERL) asm/aesni-x86_64.pl $(PERLASM_SCHEME) > $@
        +aesni-sha1-x86_64.s:	asm/aesni-sha1-x86_64.pl
        +	$(PERL) asm/aesni-sha1-x86_64.pl $(PERLASM_SCHEME) > $@
        +
        +aes-sparcv9.s: asm/aes-sparcv9.pl
        +	$(PERL) asm/aes-sparcv9.pl $(CFLAGS) > $@
        +
        +aes-ppc.s:	asm/aes-ppc.pl
        +	$(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@
        +
        +aes-parisc.s:	asm/aes-parisc.pl
        +	$(PERL) asm/aes-parisc.pl $(PERLASM_SCHEME) $@
        +
        +aes-mips.S:	asm/aes-mips.pl
        +	$(PERL) asm/aes-mips.pl $(PERLASM_SCHEME) $@
        +
        +# GNU make "catch all"
        +aes-%.S:	asm/aes-%.pl;	$(PERL) $< $(PERLASM_SCHEME) > $@
        +aes-armv4.o:	aes-armv4.S
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +aes_cbc.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
        +aes_cbc.o: ../../include/openssl/opensslconf.h aes_cbc.c
        +aes_cfb.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
        +aes_cfb.o: ../../include/openssl/opensslconf.h aes_cfb.c
        +aes_core.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
        +aes_core.o: ../../include/openssl/opensslconf.h aes_core.c aes_locl.h
        +aes_ctr.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
        +aes_ctr.o: ../../include/openssl/opensslconf.h aes_ctr.c
        +aes_ecb.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
        +aes_ecb.o: ../../include/openssl/opensslconf.h aes_ecb.c aes_locl.h
        +aes_ige.o: ../../e_os.h ../../include/openssl/aes.h ../../include/openssl/bio.h
        +aes_ige.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +aes_ige.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +aes_ige.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +aes_ige.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +aes_ige.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +aes_ige.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_ige.c aes_locl.h
        +aes_misc.o: ../../include/openssl/aes.h ../../include/openssl/crypto.h
        +aes_misc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +aes_misc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +aes_misc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +aes_misc.o: ../../include/openssl/symhacks.h aes_locl.h aes_misc.c
        +aes_ofb.o: ../../include/openssl/aes.h ../../include/openssl/modes.h
        +aes_ofb.o: ../../include/openssl/opensslconf.h aes_ofb.c
        +aes_wrap.o: ../../e_os.h ../../include/openssl/aes.h
        +aes_wrap.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +aes_wrap.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +aes_wrap.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +aes_wrap.o: ../../include/openssl/opensslconf.h
        +aes_wrap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +aes_wrap.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +aes_wrap.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_wrap.c
        diff --git a/vendor/openssl/openssl/crypto/aes/README b/vendor/openssl/openssl/crypto/aes/README
        new file mode 100644
        index 000000000..0f9620a80
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/README
        @@ -0,0 +1,3 @@
        +This is an OpenSSL-compatible version of AES (also called Rijndael).
        +aes_core.c is basically the same as rijndael-alg-fst.c but with an
        +API that looks like the rest of the OpenSSL symmetric cipher suite.
        diff --git a/vendor/openssl/openssl/crypto/aes/aes.h b/vendor/openssl/openssl/crypto/aes/aes.h
        new file mode 100644
        index 000000000..031abf01b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes.h
        @@ -0,0 +1,147 @@
        +/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + */
        +
        +#ifndef HEADER_AES_H
        +#define HEADER_AES_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_AES
        +#error AES is disabled.
        +#endif
        +
        +#include <stddef.h>
        +
        +#define AES_ENCRYPT	1
        +#define AES_DECRYPT	0
        +
        +/* Because array size can't be a const in C, the following two are macros.
        +   Both sizes are in bytes. */
        +#define AES_MAXNR 14
        +#define AES_BLOCK_SIZE 16
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* This should be a hidden type, but EVP requires that the size be known */
        +struct aes_key_st {
        +#ifdef AES_LONG
        +    unsigned long rd_key[4 *(AES_MAXNR + 1)];
        +#else
        +    unsigned int rd_key[4 *(AES_MAXNR + 1)];
        +#endif
        +    int rounds;
        +};
        +typedef struct aes_key_st AES_KEY;
        +
        +const char *AES_options(void);
        +
        +int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +	AES_KEY *key);
        +int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +	AES_KEY *key);
        +
        +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +	AES_KEY *key);
        +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +	AES_KEY *key);
        +
        +void AES_encrypt(const unsigned char *in, unsigned char *out,
        +	const AES_KEY *key);
        +void AES_decrypt(const unsigned char *in, unsigned char *out,
        +	const AES_KEY *key);
        +
        +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	const AES_KEY *key, const int enc);
        +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, const int enc);
        +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, int *num, const int enc);
        +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, int *num, const int enc);
        +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, int *num, const int enc);
        +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, int *num);
        +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char ivec[AES_BLOCK_SIZE],
        +	unsigned char ecount_buf[AES_BLOCK_SIZE],
        +	unsigned int *num);
        +/* NB: the IV is _two_ blocks long */
        +void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
        +		     size_t length, const AES_KEY *key,
        +		     unsigned char *ivec, const int enc);
        +/* NB: the IV is _four_ blocks long */
        +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t length, const AES_KEY *key,
        +			const AES_KEY *key2, const unsigned char *ivec,
        +			const int enc);
        +
        +int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
        +		unsigned char *out,
        +		const unsigned char *in, unsigned int inlen);
        +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
        +		unsigned char *out,
        +		const unsigned char *in, unsigned int inlen);
        +
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* !HEADER_AES_H */
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_cbc.c b/vendor/openssl/openssl/crypto/aes/aes_cbc.c
        new file mode 100644
        index 000000000..227f75625
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_cbc.c
        @@ -0,0 +1,63 @@
        +/* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/aes.h>
        +#include <openssl/modes.h>
        +
        +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +		     size_t len, const AES_KEY *key,
        +		     unsigned char *ivec, const int enc) {
        +
        +	if (enc)
        +		CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt);
        +	else
        +		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt);
        +}
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_cfb.c b/vendor/openssl/openssl/crypto/aes/aes_cfb.c
        new file mode 100644
        index 000000000..0c6d058ce
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_cfb.c
        @@ -0,0 +1,81 @@
        +/* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2002-2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/aes.h>
        +#include <openssl/modes.h>
        +
        +/* The input and output encrypted as though 128bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 128bit block we have used is contained in *num;
        + */
        +
        +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, int *num, const int enc) {
        +
        +	CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
        +}
        +
        +/* N.B. This expects the input to be packed, MS bit first */
        +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
        +		      size_t length, const AES_KEY *key,
        +		      unsigned char *ivec, int *num, const int enc)
        +    {
        +    CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
        +    }
        +
        +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
        +		      size_t length, const AES_KEY *key,
        +		      unsigned char *ivec, int *num, const int enc)
        +    {
        +    CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
        +    }
        +
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_core.c b/vendor/openssl/openssl/crypto/aes/aes_core.c
        new file mode 100644
        index 000000000..8f5210ac7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_core.c
        @@ -0,0 +1,1358 @@
        +/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
        +/**
        + * rijndael-alg-fst.c
        + *
        + * @version 3.0 (December 2000)
        + *
        + * Optimised ANSI C code for the Rijndael cipher (now AES)
        + *
        + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
        + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
        + * @author Paulo Barreto <paulo.barreto@terra.com.br>
        + *
        + * This code is hereby placed in the public domain.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
        + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
        + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
        + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +/* Note: rewritten a little bit to provide error control and an OpenSSL-
        +   compatible API */
        +
        +#ifndef AES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +#include <stdlib.h>
        +#include <openssl/aes.h>
        +#include "aes_locl.h"
        +
        +#ifndef AES_ASM
        +/*
        +Te0[x] = S [x].[02, 01, 01, 03];
        +Te1[x] = S [x].[03, 02, 01, 01];
        +Te2[x] = S [x].[01, 03, 02, 01];
        +Te3[x] = S [x].[01, 01, 03, 02];
        +
        +Td0[x] = Si[x].[0e, 09, 0d, 0b];
        +Td1[x] = Si[x].[0b, 0e, 09, 0d];
        +Td2[x] = Si[x].[0d, 0b, 0e, 09];
        +Td3[x] = Si[x].[09, 0d, 0b, 0e];
        +Td4[x] = Si[x].[01];
        +*/
        +
        +static const u32 Te0[256] = {
        +    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
        +    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
        +    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
        +    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
        +    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
        +    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
        +    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
        +    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
        +    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
        +    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
        +    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
        +    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
        +    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
        +    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
        +    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
        +    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
        +    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
        +    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
        +    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
        +    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
        +    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
        +    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
        +    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
        +    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
        +    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
        +    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
        +    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
        +    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
        +    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
        +    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
        +    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
        +    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
        +    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
        +    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
        +    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
        +    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
        +    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
        +    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
        +    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
        +    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
        +    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
        +    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
        +    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
        +    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
        +    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
        +    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
        +    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
        +    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
        +    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
        +    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
        +    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
        +    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
        +    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
        +    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
        +    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
        +    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
        +    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
        +    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
        +    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
        +    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
        +    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
        +    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
        +    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
        +    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
        +};
        +static const u32 Te1[256] = {
        +    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
        +    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
        +    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
        +    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
        +    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
        +    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
        +    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
        +    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
        +    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
        +    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
        +    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
        +    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
        +    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
        +    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
        +    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
        +    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
        +    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
        +    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
        +    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
        +    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
        +    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
        +    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
        +    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
        +    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
        +    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
        +    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
        +    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
        +    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
        +    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
        +    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
        +    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
        +    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
        +    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
        +    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
        +    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
        +    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
        +    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
        +    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
        +    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
        +    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
        +    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
        +    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
        +    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
        +    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
        +    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
        +    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
        +    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
        +    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
        +    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
        +    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
        +    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
        +    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
        +    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
        +    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
        +    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
        +    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
        +    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
        +    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
        +    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
        +    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
        +    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
        +    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
        +    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
        +    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
        +};
        +static const u32 Te2[256] = {
        +    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
        +    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
        +    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
        +    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
        +    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
        +    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
        +    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
        +    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
        +    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
        +    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
        +    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
        +    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
        +    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
        +    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
        +    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
        +    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
        +    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
        +    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
        +    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
        +    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
        +    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
        +    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
        +    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
        +    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
        +    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
        +    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
        +    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
        +    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
        +    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
        +    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
        +    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
        +    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
        +    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
        +    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
        +    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
        +    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
        +    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
        +    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
        +    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
        +    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
        +    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
        +    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
        +    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
        +    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
        +    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
        +    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
        +    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
        +    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
        +    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
        +    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
        +    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
        +    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
        +    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
        +    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
        +    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
        +    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
        +    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
        +    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
        +    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
        +    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
        +    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
        +    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
        +    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
        +    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
        +};
        +static const u32 Te3[256] = {
        +    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
        +    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
        +    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
        +    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
        +    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
        +    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
        +    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
        +    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
        +    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
        +    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
        +    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
        +    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
        +    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
        +    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
        +    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
        +    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
        +    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
        +    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
        +    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
        +    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
        +    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
        +    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
        +    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
        +    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
        +    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
        +    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
        +    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
        +    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
        +    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
        +    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
        +    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
        +    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
        +    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
        +    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
        +    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
        +    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
        +    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
        +    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
        +    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
        +    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
        +    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
        +    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
        +    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
        +    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
        +    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
        +    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
        +    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
        +    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
        +    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
        +    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
        +    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
        +    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
        +    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
        +    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
        +    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
        +    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
        +    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
        +    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
        +    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
        +    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
        +    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
        +    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
        +    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
        +    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
        +};
        +
        +static const u32 Td0[256] = {
        +    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
        +    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
        +    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
        +    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
        +    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
        +    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
        +    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
        +    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
        +    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
        +    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
        +    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
        +    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
        +    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
        +    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
        +    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
        +    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
        +    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
        +    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
        +    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
        +    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
        +    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
        +    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
        +    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
        +    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
        +    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
        +    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
        +    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
        +    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
        +    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
        +    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
        +    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
        +    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
        +    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
        +    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
        +    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
        +    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
        +    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
        +    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
        +    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
        +    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
        +    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
        +    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
        +    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
        +    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
        +    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
        +    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
        +    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
        +    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
        +    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
        +    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
        +    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
        +    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
        +    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
        +    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
        +    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
        +    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
        +    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
        +    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
        +    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
        +    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
        +    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
        +    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
        +    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
        +    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
        +};
        +static const u32 Td1[256] = {
        +    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
        +    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
        +    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
        +    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
        +    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
        +    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
        +    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
        +    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
        +    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
        +    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
        +    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
        +    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
        +    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
        +    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
        +    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
        +    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
        +    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
        +    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
        +    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
        +    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
        +    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
        +    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
        +    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
        +    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
        +    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
        +    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
        +    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
        +    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
        +    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
        +    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
        +    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
        +    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
        +    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
        +    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
        +    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
        +    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
        +    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
        +    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
        +    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
        +    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
        +    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
        +    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
        +    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
        +    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
        +    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
        +    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
        +    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
        +    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
        +    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
        +    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
        +    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
        +    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
        +    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
        +    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
        +    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
        +    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
        +    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
        +    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
        +    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
        +    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
        +    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
        +    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
        +    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
        +    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
        +};
        +static const u32 Td2[256] = {
        +    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
        +    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
        +    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
        +    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
        +    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
        +    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
        +    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
        +    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
        +    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
        +    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
        +    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
        +    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
        +    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
        +    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
        +    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
        +    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
        +    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
        +    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
        +    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
        +    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
        +    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
        +    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
        +    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
        +    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
        +    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
        +    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
        +    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
        +    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
        +    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
        +    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
        +    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
        +    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
        +    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
        +    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
        +    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
        +    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
        +    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
        +    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
        +    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
        +    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
        +    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
        +    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
        +    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
        +    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
        +    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
        +    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
        +    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
        +    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
        +    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
        +    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
        +    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
        +    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
        +    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
        +    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
        +    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
        +    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
        +    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
        +    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
        +    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
        +    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
        +    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
        +    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
        +    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
        +    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
        +};
        +static const u32 Td3[256] = {
        +    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
        +    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
        +    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
        +    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
        +    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
        +    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
        +    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
        +    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
        +    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
        +    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
        +    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
        +    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
        +    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
        +    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
        +    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
        +    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
        +    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
        +    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
        +    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
        +    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
        +    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
        +    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
        +    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
        +    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
        +    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
        +    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
        +    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
        +    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
        +    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
        +    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
        +    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
        +    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
        +    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
        +    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
        +    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
        +    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
        +    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
        +    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
        +    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
        +    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
        +    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
        +    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
        +    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
        +    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
        +    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
        +    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
        +    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
        +    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
        +    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
        +    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
        +    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
        +    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
        +    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
        +    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
        +    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
        +    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
        +    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
        +    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
        +    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
        +    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
        +    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
        +    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
        +    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
        +    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
        +};
        +static const u8 Td4[256] = {
        +    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
        +    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
        +    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
        +    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
        +    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
        +    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
        +    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
        +    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
        +    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
        +    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
        +    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
        +    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
        +    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
        +    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
        +    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
        +    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
        +    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
        +    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
        +    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
        +    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
        +    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
        +    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
        +    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
        +    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
        +    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
        +    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
        +    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
        +    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
        +    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
        +    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
        +    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
        +    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
        +};
        +static const u32 rcon[] = {
        +	0x01000000, 0x02000000, 0x04000000, 0x08000000,
        +	0x10000000, 0x20000000, 0x40000000, 0x80000000,
        +	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
        +};
        +
        +/**
        + * Expand the cipher key into the encryption key schedule.
        + */
        +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +			AES_KEY *key) {
        +
        +	u32 *rk;
        +   	int i = 0;
        +	u32 temp;
        +
        +	if (!userKey || !key)
        +		return -1;
        +	if (bits != 128 && bits != 192 && bits != 256)
        +		return -2;
        +
        +	rk = key->rd_key;
        +
        +	if (bits==128)
        +		key->rounds = 10;
        +	else if (bits==192)
        +		key->rounds = 12;
        +	else
        +		key->rounds = 14;
        +
        +	rk[0] = GETU32(userKey     );
        +	rk[1] = GETU32(userKey +  4);
        +	rk[2] = GETU32(userKey +  8);
        +	rk[3] = GETU32(userKey + 12);
        +	if (bits == 128) {
        +		while (1) {
        +			temp  = rk[3];
        +			rk[4] = rk[0] ^
        +				(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
        +				(Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
        +				(Te0[(temp      ) & 0xff] & 0x0000ff00) ^
        +				(Te1[(temp >> 24)       ] & 0x000000ff) ^
        +				rcon[i];
        +			rk[5] = rk[1] ^ rk[4];
        +			rk[6] = rk[2] ^ rk[5];
        +			rk[7] = rk[3] ^ rk[6];
        +			if (++i == 10) {
        +				return 0;
        +			}
        +			rk += 4;
        +		}
        +	}
        +	rk[4] = GETU32(userKey + 16);
        +	rk[5] = GETU32(userKey + 20);
        +	if (bits == 192) {
        +		while (1) {
        +			temp = rk[ 5];
        +			rk[ 6] = rk[ 0] ^
        +				(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
        +				(Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
        +				(Te0[(temp      ) & 0xff] & 0x0000ff00) ^
        +				(Te1[(temp >> 24)       ] & 0x000000ff) ^
        +				rcon[i];
        +			rk[ 7] = rk[ 1] ^ rk[ 6];
        +			rk[ 8] = rk[ 2] ^ rk[ 7];
        +			rk[ 9] = rk[ 3] ^ rk[ 8];
        +			if (++i == 8) {
        +				return 0;
        +			}
        +			rk[10] = rk[ 4] ^ rk[ 9];
        +			rk[11] = rk[ 5] ^ rk[10];
        +			rk += 6;
        +		}
        +	}
        +	rk[6] = GETU32(userKey + 24);
        +	rk[7] = GETU32(userKey + 28);
        +	if (bits == 256) {
        +		while (1) {
        +			temp = rk[ 7];
        +			rk[ 8] = rk[ 0] ^
        +				(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
        +				(Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
        +				(Te0[(temp      ) & 0xff] & 0x0000ff00) ^
        +				(Te1[(temp >> 24)       ] & 0x000000ff) ^
        +				rcon[i];
        +			rk[ 9] = rk[ 1] ^ rk[ 8];
        +			rk[10] = rk[ 2] ^ rk[ 9];
        +			rk[11] = rk[ 3] ^ rk[10];
        +			if (++i == 7) {
        +				return 0;
        +			}
        +			temp = rk[11];
        +			rk[12] = rk[ 4] ^
        +				(Te2[(temp >> 24)       ] & 0xff000000) ^
        +				(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
        +				(Te0[(temp >>  8) & 0xff] & 0x0000ff00) ^
        +				(Te1[(temp      ) & 0xff] & 0x000000ff);
        +			rk[13] = rk[ 5] ^ rk[12];
        +			rk[14] = rk[ 6] ^ rk[13];
        +			rk[15] = rk[ 7] ^ rk[14];
        +
        +			rk += 8;
        +        	}
        +	}
        +	return 0;
        +}
        +
        +/**
        + * Expand the cipher key into the decryption key schedule.
        + */
        +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +			 AES_KEY *key) {
        +
        +        u32 *rk;
        +	int i, j, status;
        +	u32 temp;
        +
        +	/* first, start with an encryption schedule */
        +	status = private_AES_set_encrypt_key(userKey, bits, key);
        +	if (status < 0)
        +		return status;
        +
        +	rk = key->rd_key;
        +
        +	/* invert the order of the round keys: */
        +	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
        +		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
        +		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
        +		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
        +		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
        +	}
        +	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
        +	for (i = 1; i < (key->rounds); i++) {
        +		rk += 4;
        +		rk[0] =
        +			Td0[Te1[(rk[0] >> 24)       ] & 0xff] ^
        +			Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
        +			Td2[Te1[(rk[0] >>  8) & 0xff] & 0xff] ^
        +			Td3[Te1[(rk[0]      ) & 0xff] & 0xff];
        +		rk[1] =
        +			Td0[Te1[(rk[1] >> 24)       ] & 0xff] ^
        +			Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
        +			Td2[Te1[(rk[1] >>  8) & 0xff] & 0xff] ^
        +			Td3[Te1[(rk[1]      ) & 0xff] & 0xff];
        +		rk[2] =
        +			Td0[Te1[(rk[2] >> 24)       ] & 0xff] ^
        +			Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
        +			Td2[Te1[(rk[2] >>  8) & 0xff] & 0xff] ^
        +			Td3[Te1[(rk[2]      ) & 0xff] & 0xff];
        +		rk[3] =
        +			Td0[Te1[(rk[3] >> 24)       ] & 0xff] ^
        +			Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
        +			Td2[Te1[(rk[3] >>  8) & 0xff] & 0xff] ^
        +			Td3[Te1[(rk[3]      ) & 0xff] & 0xff];
        +	}
        +	return 0;
        +}
        +
        +/*
        + * Encrypt a single block
        + * in and out can overlap
        + */
        +void AES_encrypt(const unsigned char *in, unsigned char *out,
        +		 const AES_KEY *key) {
        +
        +	const u32 *rk;
        +	u32 s0, s1, s2, s3, t0, t1, t2, t3;
        +#ifndef FULL_UNROLL
        +	int r;
        +#endif /* ?FULL_UNROLL */
        +
        +	assert(in && out && key);
        +	rk = key->rd_key;
        +
        +	/*
        +	 * map byte array block to cipher state
        +	 * and add initial round key:
        +	 */
        +	s0 = GETU32(in     ) ^ rk[0];
        +	s1 = GETU32(in +  4) ^ rk[1];
        +	s2 = GETU32(in +  8) ^ rk[2];
        +	s3 = GETU32(in + 12) ^ rk[3];
        +#ifdef FULL_UNROLL
        +	/* round 1: */
        +   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
        +   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
        +   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
        +   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
        +   	/* round 2: */
        +   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
        +   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
        +   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
        +   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
        +	/* round 3: */
        +   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
        +   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
        +   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
        +   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
        +   	/* round 4: */
        +   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
        +   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
        +   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
        +   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
        +	/* round 5: */
        +   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
        +   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
        +   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
        +   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
        +   	/* round 6: */
        +   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
        +   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
        +   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
        +   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
        +	/* round 7: */
        +   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
        +   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
        +   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
        +   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
        +   	/* round 8: */
        +   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
        +   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
        +   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
        +   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
        +	/* round 9: */
        +   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
        +   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
        +   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
        +   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
        +    if (key->rounds > 10) {
        +        /* round 10: */
        +        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
        +        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
        +        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
        +        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
        +        /* round 11: */
        +        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
        +        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
        +        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
        +        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
        +        if (key->rounds > 12) {
        +            /* round 12: */
        +            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
        +            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
        +            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
        +            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
        +            /* round 13: */
        +            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
        +            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
        +            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
        +            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
        +        }
        +    }
        +    rk += key->rounds << 2;
        +#else  /* !FULL_UNROLL */
        +    /*
        +     * Nr - 1 full rounds:
        +     */
        +    r = key->rounds >> 1;
        +    for (;;) {
        +        t0 =
        +            Te0[(s0 >> 24)       ] ^
        +            Te1[(s1 >> 16) & 0xff] ^
        +            Te2[(s2 >>  8) & 0xff] ^
        +            Te3[(s3      ) & 0xff] ^
        +            rk[4];
        +        t1 =
        +            Te0[(s1 >> 24)       ] ^
        +            Te1[(s2 >> 16) & 0xff] ^
        +            Te2[(s3 >>  8) & 0xff] ^
        +            Te3[(s0      ) & 0xff] ^
        +            rk[5];
        +        t2 =
        +            Te0[(s2 >> 24)       ] ^
        +            Te1[(s3 >> 16) & 0xff] ^
        +            Te2[(s0 >>  8) & 0xff] ^
        +            Te3[(s1      ) & 0xff] ^
        +            rk[6];
        +        t3 =
        +            Te0[(s3 >> 24)       ] ^
        +            Te1[(s0 >> 16) & 0xff] ^
        +            Te2[(s1 >>  8) & 0xff] ^
        +            Te3[(s2      ) & 0xff] ^
        +            rk[7];
        +
        +        rk += 8;
        +        if (--r == 0) {
        +            break;
        +        }
        +
        +        s0 =
        +            Te0[(t0 >> 24)       ] ^
        +            Te1[(t1 >> 16) & 0xff] ^
        +            Te2[(t2 >>  8) & 0xff] ^
        +            Te3[(t3      ) & 0xff] ^
        +            rk[0];
        +        s1 =
        +            Te0[(t1 >> 24)       ] ^
        +            Te1[(t2 >> 16) & 0xff] ^
        +            Te2[(t3 >>  8) & 0xff] ^
        +            Te3[(t0      ) & 0xff] ^
        +            rk[1];
        +        s2 =
        +            Te0[(t2 >> 24)       ] ^
        +            Te1[(t3 >> 16) & 0xff] ^
        +            Te2[(t0 >>  8) & 0xff] ^
        +            Te3[(t1      ) & 0xff] ^
        +            rk[2];
        +        s3 =
        +            Te0[(t3 >> 24)       ] ^
        +            Te1[(t0 >> 16) & 0xff] ^
        +            Te2[(t1 >>  8) & 0xff] ^
        +            Te3[(t2      ) & 0xff] ^
        +            rk[3];
        +    }
        +#endif /* ?FULL_UNROLL */
        +    /*
        +	 * apply last round and
        +	 * map cipher state to byte array block:
        +	 */
        +	s0 =
        +		(Te2[(t0 >> 24)       ] & 0xff000000) ^
        +		(Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
        +		(Te0[(t2 >>  8) & 0xff] & 0x0000ff00) ^
        +		(Te1[(t3      ) & 0xff] & 0x000000ff) ^
        +		rk[0];
        +	PUTU32(out     , s0);
        +	s1 =
        +		(Te2[(t1 >> 24)       ] & 0xff000000) ^
        +		(Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
        +		(Te0[(t3 >>  8) & 0xff] & 0x0000ff00) ^
        +		(Te1[(t0      ) & 0xff] & 0x000000ff) ^
        +		rk[1];
        +	PUTU32(out +  4, s1);
        +	s2 =
        +		(Te2[(t2 >> 24)       ] & 0xff000000) ^
        +		(Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
        +		(Te0[(t0 >>  8) & 0xff] & 0x0000ff00) ^
        +		(Te1[(t1      ) & 0xff] & 0x000000ff) ^
        +		rk[2];
        +	PUTU32(out +  8, s2);
        +	s3 =
        +		(Te2[(t3 >> 24)       ] & 0xff000000) ^
        +		(Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
        +		(Te0[(t1 >>  8) & 0xff] & 0x0000ff00) ^
        +		(Te1[(t2      ) & 0xff] & 0x000000ff) ^
        +		rk[3];
        +	PUTU32(out + 12, s3);
        +}
        +
        +/*
        + * Decrypt a single block
        + * in and out can overlap
        + */
        +void AES_decrypt(const unsigned char *in, unsigned char *out,
        +		 const AES_KEY *key) {
        +
        +	const u32 *rk;
        +	u32 s0, s1, s2, s3, t0, t1, t2, t3;
        +#ifndef FULL_UNROLL
        +	int r;
        +#endif /* ?FULL_UNROLL */
        +
        +	assert(in && out && key);
        +	rk = key->rd_key;
        +
        +	/*
        +	 * map byte array block to cipher state
        +	 * and add initial round key:
        +	 */
        +    s0 = GETU32(in     ) ^ rk[0];
        +    s1 = GETU32(in +  4) ^ rk[1];
        +    s2 = GETU32(in +  8) ^ rk[2];
        +    s3 = GETU32(in + 12) ^ rk[3];
        +#ifdef FULL_UNROLL
        +    /* round 1: */
        +    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
        +    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
        +    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
        +    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
        +    /* round 2: */
        +    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
        +    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
        +    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
        +    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
        +    /* round 3: */
        +    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
        +    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
        +    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
        +    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
        +    /* round 4: */
        +    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
        +    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
        +    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
        +    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
        +    /* round 5: */
        +    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
        +    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
        +    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
        +    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
        +    /* round 6: */
        +    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
        +    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
        +    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
        +    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
        +    /* round 7: */
        +    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
        +    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
        +    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
        +    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
        +    /* round 8: */
        +    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
        +    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
        +    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
        +    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
        +    /* round 9: */
        +    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
        +    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
        +    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
        +    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
        +    if (key->rounds > 10) {
        +        /* round 10: */
        +        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
        +        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
        +        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
        +        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
        +        /* round 11: */
        +        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
        +        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
        +        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
        +        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
        +        if (key->rounds > 12) {
        +            /* round 12: */
        +            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
        +            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
        +            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
        +            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
        +            /* round 13: */
        +            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
        +            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
        +            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
        +            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
        +        }
        +    }
        +	rk += key->rounds << 2;
        +#else  /* !FULL_UNROLL */
        +    /*
        +     * Nr - 1 full rounds:
        +     */
        +    r = key->rounds >> 1;
        +    for (;;) {
        +        t0 =
        +            Td0[(s0 >> 24)       ] ^
        +            Td1[(s3 >> 16) & 0xff] ^
        +            Td2[(s2 >>  8) & 0xff] ^
        +            Td3[(s1      ) & 0xff] ^
        +            rk[4];
        +        t1 =
        +            Td0[(s1 >> 24)       ] ^
        +            Td1[(s0 >> 16) & 0xff] ^
        +            Td2[(s3 >>  8) & 0xff] ^
        +            Td3[(s2      ) & 0xff] ^
        +            rk[5];
        +        t2 =
        +            Td0[(s2 >> 24)       ] ^
        +            Td1[(s1 >> 16) & 0xff] ^
        +            Td2[(s0 >>  8) & 0xff] ^
        +            Td3[(s3      ) & 0xff] ^
        +            rk[6];
        +        t3 =
        +            Td0[(s3 >> 24)       ] ^
        +            Td1[(s2 >> 16) & 0xff] ^
        +            Td2[(s1 >>  8) & 0xff] ^
        +            Td3[(s0      ) & 0xff] ^
        +            rk[7];
        +
        +        rk += 8;
        +        if (--r == 0) {
        +            break;
        +        }
        +
        +        s0 =
        +            Td0[(t0 >> 24)       ] ^
        +            Td1[(t3 >> 16) & 0xff] ^
        +            Td2[(t2 >>  8) & 0xff] ^
        +            Td3[(t1      ) & 0xff] ^
        +            rk[0];
        +        s1 =
        +            Td0[(t1 >> 24)       ] ^
        +            Td1[(t0 >> 16) & 0xff] ^
        +            Td2[(t3 >>  8) & 0xff] ^
        +            Td3[(t2      ) & 0xff] ^
        +            rk[1];
        +        s2 =
        +            Td0[(t2 >> 24)       ] ^
        +            Td1[(t1 >> 16) & 0xff] ^
        +            Td2[(t0 >>  8) & 0xff] ^
        +            Td3[(t3      ) & 0xff] ^
        +            rk[2];
        +        s3 =
        +            Td0[(t3 >> 24)       ] ^
        +            Td1[(t2 >> 16) & 0xff] ^
        +            Td2[(t1 >>  8) & 0xff] ^
        +            Td3[(t0      ) & 0xff] ^
        +            rk[3];
        +    }
        +#endif /* ?FULL_UNROLL */
        +    /*
        +	 * apply last round and
        +	 * map cipher state to byte array block:
        +	 */
        +   	s0 =
        +   		(Td4[(t0 >> 24)       ] << 24) ^
        +   		(Td4[(t3 >> 16) & 0xff] << 16) ^
        +   		(Td4[(t2 >>  8) & 0xff] <<  8) ^
        +   		(Td4[(t1      ) & 0xff])       ^
        +   		rk[0];
        +	PUTU32(out     , s0);
        +   	s1 =
        +   		(Td4[(t1 >> 24)       ] << 24) ^
        +   		(Td4[(t0 >> 16) & 0xff] << 16) ^
        +   		(Td4[(t3 >>  8) & 0xff] <<  8) ^
        +   		(Td4[(t2      ) & 0xff])       ^
        +   		rk[1];
        +	PUTU32(out +  4, s1);
        +   	s2 =
        +   		(Td4[(t2 >> 24)       ] << 24) ^
        +   		(Td4[(t1 >> 16) & 0xff] << 16) ^
        +   		(Td4[(t0 >>  8) & 0xff] <<  8) ^
        +   		(Td4[(t3      ) & 0xff])       ^
        +   		rk[2];
        +	PUTU32(out +  8, s2);
        +   	s3 =
        +   		(Td4[(t3 >> 24)       ] << 24) ^
        +   		(Td4[(t2 >> 16) & 0xff] << 16) ^
        +   		(Td4[(t1 >>  8) & 0xff] <<  8) ^
        +   		(Td4[(t0      ) & 0xff])       ^
        +   		rk[3];
        +	PUTU32(out + 12, s3);
        +}
        +
        +#else /* AES_ASM */
        +
        +static const u8 Te4[256] = {
        +    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
        +    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
        +    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
        +    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
        +    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
        +    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
        +    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
        +    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
        +    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
        +    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
        +    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
        +    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
        +    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
        +    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
        +    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
        +    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
        +    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
        +    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
        +    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
        +    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
        +    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
        +    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
        +    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
        +    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
        +    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
        +    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
        +    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
        +    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
        +    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
        +    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
        +    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
        +    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
        +};
        +static const u32 rcon[] = {
        +	0x01000000, 0x02000000, 0x04000000, 0x08000000,
        +	0x10000000, 0x20000000, 0x40000000, 0x80000000,
        +	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
        +};
        +
        +/**
        + * Expand the cipher key into the encryption key schedule.
        + */
        +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +			AES_KEY *key) {
        +	u32 *rk;
        +   	int i = 0;
        +	u32 temp;
        +
        +	if (!userKey || !key)
        +		return -1;
        +	if (bits != 128 && bits != 192 && bits != 256)
        +		return -2;
        +
        +	rk = key->rd_key;
        +
        +	if (bits==128)
        +		key->rounds = 10;
        +	else if (bits==192)
        +		key->rounds = 12;
        +	else
        +		key->rounds = 14;
        +
        +	rk[0] = GETU32(userKey     );
        +	rk[1] = GETU32(userKey +  4);
        +	rk[2] = GETU32(userKey +  8);
        +	rk[3] = GETU32(userKey + 12);
        +	if (bits == 128) {
        +		while (1) {
        +			temp  = rk[3];
        +			rk[4] = rk[0] ^
        +				(Te4[(temp >> 16) & 0xff] << 24) ^
        +				(Te4[(temp >>  8) & 0xff] << 16) ^
        +				(Te4[(temp      ) & 0xff] << 8) ^
        +				(Te4[(temp >> 24)       ]) ^
        +				rcon[i];
        +			rk[5] = rk[1] ^ rk[4];
        +			rk[6] = rk[2] ^ rk[5];
        +			rk[7] = rk[3] ^ rk[6];
        +			if (++i == 10) {
        +				return 0;
        +			}
        +			rk += 4;
        +		}
        +	}
        +	rk[4] = GETU32(userKey + 16);
        +	rk[5] = GETU32(userKey + 20);
        +	if (bits == 192) {
        +		while (1) {
        +			temp = rk[ 5];
        +			rk[ 6] = rk[ 0] ^
        +				(Te4[(temp >> 16) & 0xff] << 24) ^
        +				(Te4[(temp >>  8) & 0xff] << 16) ^
        +				(Te4[(temp      ) & 0xff] << 8) ^
        +				(Te4[(temp >> 24)       ]) ^
        +				rcon[i];
        +			rk[ 7] = rk[ 1] ^ rk[ 6];
        +			rk[ 8] = rk[ 2] ^ rk[ 7];
        +			rk[ 9] = rk[ 3] ^ rk[ 8];
        +			if (++i == 8) {
        +				return 0;
        +			}
        +			rk[10] = rk[ 4] ^ rk[ 9];
        +			rk[11] = rk[ 5] ^ rk[10];
        +			rk += 6;
        +		}
        +	}
        +	rk[6] = GETU32(userKey + 24);
        +	rk[7] = GETU32(userKey + 28);
        +	if (bits == 256) {
        +		while (1) {
        +			temp = rk[ 7];
        +			rk[ 8] = rk[ 0] ^
        +				(Te4[(temp >> 16) & 0xff] << 24) ^
        +				(Te4[(temp >>  8) & 0xff] << 16) ^
        +				(Te4[(temp      ) & 0xff] << 8) ^
        +				(Te4[(temp >> 24)       ]) ^
        +				rcon[i];
        +			rk[ 9] = rk[ 1] ^ rk[ 8];
        +			rk[10] = rk[ 2] ^ rk[ 9];
        +			rk[11] = rk[ 3] ^ rk[10];
        +			if (++i == 7) {
        +				return 0;
        +			}
        +			temp = rk[11];
        +			rk[12] = rk[ 4] ^
        +				(Te4[(temp >> 24)       ] << 24) ^
        +				(Te4[(temp >> 16) & 0xff] << 16) ^
        +				(Te4[(temp >>  8) & 0xff] << 8) ^
        +				(Te4[(temp      ) & 0xff]);
        +			rk[13] = rk[ 5] ^ rk[12];
        +			rk[14] = rk[ 6] ^ rk[13];
        +			rk[15] = rk[ 7] ^ rk[14];
        +
        +			rk += 8;
        +        	}
        +	}
        +	return 0;
        +}
        +
        +/**
        + * Expand the cipher key into the decryption key schedule.
        + */
        +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +			 AES_KEY *key) {
        +
        +        u32 *rk;
        +	int i, j, status;
        +	u32 temp;
        +
        +	/* first, start with an encryption schedule */
        +	status = private_AES_set_encrypt_key(userKey, bits, key);
        +	if (status < 0)
        +		return status;
        +
        +	rk = key->rd_key;
        +
        +	/* invert the order of the round keys: */
        +	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
        +		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
        +		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
        +		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
        +		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
        +	}
        +	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
        +	for (i = 1; i < (key->rounds); i++) {
        +		rk += 4;
        +		for (j = 0; j < 4; j++) {
        +			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
        +
        +			tp1 = rk[j];
        +			m = tp1 & 0x80808080;
        +			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp2 & 0x80808080;
        +			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp4 & 0x80808080;
        +			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			tp9 = tp8 ^ tp1;
        +			tpb = tp9 ^ tp2;
        +			tpd = tp9 ^ tp4;
        +			tpe = tp8 ^ tp4 ^ tp2;
        +#if defined(ROTATE)
        +			rk[j] = tpe ^ ROTATE(tpd,16) ^
        +				ROTATE(tp9,24) ^ ROTATE(tpb,8);
        +#else
        +			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
        +				(tp9 >> 8) ^ (tp9 << 24) ^
        +				(tpb >> 24) ^ (tpb << 8);
        +#endif
        +		}
        +	}
        +	return 0;
        +}
        +
        +#endif /* AES_ASM */
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_ctr.c b/vendor/openssl/openssl/crypto/aes/aes_ctr.c
        new file mode 100644
        index 000000000..7c9d165d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_ctr.c
        @@ -0,0 +1,61 @@
        +/* crypto/aes/aes_ctr.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/aes.h>
        +#include <openssl/modes.h>
        +
        +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t length, const AES_KEY *key,
        +			unsigned char ivec[AES_BLOCK_SIZE],
        +			unsigned char ecount_buf[AES_BLOCK_SIZE],
        +			unsigned int *num) {
        +	CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)AES_encrypt);
        +}
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_ecb.c b/vendor/openssl/openssl/crypto/aes/aes_ecb.c
        new file mode 100644
        index 000000000..28aa561c2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_ecb.c
        @@ -0,0 +1,73 @@
        +/* crypto/aes/aes_ecb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + */
        +
        +#ifndef AES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +#include <openssl/aes.h>
        +#include "aes_locl.h"
        +
        +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +		     const AES_KEY *key, const int enc) {
        +
        +        assert(in && out && key);
        +	assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
        +
        +	if (AES_ENCRYPT == enc)
        +		AES_encrypt(in, out, key);
        +	else
        +		AES_decrypt(in, out, key);
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_ige.c b/vendor/openssl/openssl/crypto/aes/aes_ige.c
        new file mode 100644
        index 000000000..c161351e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_ige.c
        @@ -0,0 +1,323 @@
        +/* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#include "cryptlib.h"
        +
        +#include <openssl/aes.h>
        +#include "aes_locl.h"
        +
        +#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
        +typedef struct {
        +        unsigned long data[N_WORDS];
        +} aes_block_t;
        +
        +/* XXX: probably some better way to do this */
        +#if defined(__i386__) || defined(__x86_64__)
        +#define UNALIGNED_MEMOPS_ARE_FAST 1
        +#else
        +#define UNALIGNED_MEMOPS_ARE_FAST 0
        +#endif
        +
        +#if UNALIGNED_MEMOPS_ARE_FAST
        +#define load_block(d, s)        (d) = *(const aes_block_t *)(s)
        +#define store_block(d, s)       *(aes_block_t *)(d) = (s)
        +#else
        +#define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
        +#define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
        +#endif
        +
        +/* N.B. The IV for this mode is _twice_ the block size */
        +
        +void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
        +					 size_t length, const AES_KEY *key,
        +					 unsigned char *ivec, const int enc)
        +	{
        +	size_t n;
        +	size_t len = length;
        +
        +	OPENSSL_assert(in && out && key && ivec);
        +	OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
        +	OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
        +
        +	len = length / AES_BLOCK_SIZE;
        +
        +	if (AES_ENCRYPT == enc)
        +		{
        +		if (in != out &&
        +		    (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
        +			{
        +			aes_block_t *ivp = (aes_block_t *)ivec;
        +			aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
        +
        +			while (len)
        +				{
        +				aes_block_t *inp = (aes_block_t *)in;
        +				aes_block_t *outp = (aes_block_t *)out;
        +
        +				for(n=0 ; n < N_WORDS; ++n)
        +					outp->data[n] = inp->data[n] ^ ivp->data[n];
        +				AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
        +				for(n=0 ; n < N_WORDS; ++n)
        +					outp->data[n] ^= iv2p->data[n];
        +				ivp = outp;
        +				iv2p = inp;
        +				--len;
        +				in += AES_BLOCK_SIZE;
        +				out += AES_BLOCK_SIZE;
        +				}
        +			memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
        +			memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
        +			}
        +		else
        +			{
        +			aes_block_t tmp, tmp2;
        +			aes_block_t iv;
        +			aes_block_t iv2;
        +
        +			load_block(iv, ivec);
        +			load_block(iv2, ivec + AES_BLOCK_SIZE);
        +
        +			while (len)
        +				{
        +				load_block(tmp, in);
        +				for(n=0 ; n < N_WORDS; ++n)
        +					tmp2.data[n] = tmp.data[n] ^ iv.data[n];
        +				AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key);
        +				for(n=0 ; n < N_WORDS; ++n)
        +					tmp2.data[n] ^= iv2.data[n];
        +				store_block(out, tmp2);
        +				iv = tmp2;
        +				iv2 = tmp;
        +				--len;
        +				in += AES_BLOCK_SIZE;
        +				out += AES_BLOCK_SIZE;
        +				}
        +			memcpy(ivec, iv.data, AES_BLOCK_SIZE);
        +			memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
        +			}
        +		}
        +	else
        +		{
        +		if (in != out &&
        +		    (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
        +			{
        +			aes_block_t *ivp = (aes_block_t *)ivec;
        +			aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
        +
        +			while (len)
        +				{
        +				aes_block_t tmp;
        +				aes_block_t *inp = (aes_block_t *)in;
        +				aes_block_t *outp = (aes_block_t *)out;
        +
        +				for(n=0 ; n < N_WORDS; ++n)
        +					tmp.data[n] = inp->data[n] ^ iv2p->data[n];
        +				AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key);
        +				for(n=0 ; n < N_WORDS; ++n)
        +					outp->data[n] ^= ivp->data[n];
        +				ivp = inp;
        +				iv2p = outp;
        +				--len;
        +				in += AES_BLOCK_SIZE;
        +				out += AES_BLOCK_SIZE;
        +				}
        +			memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
        +			memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
        +			}
        +		else
        +			{
        +			aes_block_t tmp, tmp2;
        +			aes_block_t iv;
        +			aes_block_t iv2;
        +
        +			load_block(iv, ivec);
        +			load_block(iv2, ivec + AES_BLOCK_SIZE);
        +
        +			while (len)
        +				{
        +				load_block(tmp, in);
        +				tmp2 = tmp;
        +				for(n=0 ; n < N_WORDS; ++n)
        +					tmp.data[n] ^= iv2.data[n];
        +				AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key);
        +				for(n=0 ; n < N_WORDS; ++n)
        +					tmp.data[n] ^= iv.data[n];
        +				store_block(out, tmp);
        +				iv = tmp2;
        +				iv2 = tmp;
        +				--len;
        +				in += AES_BLOCK_SIZE;
        +				out += AES_BLOCK_SIZE;
        +				}
        +			memcpy(ivec, iv.data, AES_BLOCK_SIZE);
        +			memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
        +			}
        +		}
        +	}
        +
        +/*
        + * Note that its effectively impossible to do biIGE in anything other
        + * than a single pass, so no provision is made for chaining.
        + */
        +
        +/* N.B. The IV for this mode is _four times_ the block size */
        +
        +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
        +						size_t length, const AES_KEY *key,
        +						const AES_KEY *key2, const unsigned char *ivec,
        +						const int enc)
        +	{
        +	size_t n;
        +	size_t len = length;
        +	unsigned char tmp[AES_BLOCK_SIZE];
        +	unsigned char tmp2[AES_BLOCK_SIZE];
        +	unsigned char tmp3[AES_BLOCK_SIZE];
        +	unsigned char prev[AES_BLOCK_SIZE];
        +	const unsigned char *iv;
        +	const unsigned char *iv2;
        +
        +	OPENSSL_assert(in && out && key && ivec);
        +	OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
        +	OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
        +
        +	if (AES_ENCRYPT == enc)
        +		{
        +		/* XXX: Do a separate case for when in != out (strictly should
        +		   check for overlap, too) */
        +
        +		/* First the forward pass */ 
        +		iv = ivec;
        +		iv2 = ivec + AES_BLOCK_SIZE;
        +		while (len >= AES_BLOCK_SIZE)
        +			{
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				out[n] = in[n] ^ iv[n];
        +			AES_encrypt(out, out, key);
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				out[n] ^= iv2[n];
        +			iv = out;
        +			memcpy(prev, in, AES_BLOCK_SIZE);
        +			iv2 = prev;
        +			len -= AES_BLOCK_SIZE;
        +			in += AES_BLOCK_SIZE;
        +			out += AES_BLOCK_SIZE;
        +			}
        +
        +		/* And now backwards */
        +		iv = ivec + AES_BLOCK_SIZE*2;
        +		iv2 = ivec + AES_BLOCK_SIZE*3;
        +		len = length;
        +		while(len >= AES_BLOCK_SIZE)
        +			{
        +			out -= AES_BLOCK_SIZE;
        +			/* XXX: reduce copies by alternating between buffers */
        +			memcpy(tmp, out, AES_BLOCK_SIZE);
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				out[n] ^= iv[n];
        +			/*			hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */
        +			AES_encrypt(out, out, key);
        +			/*			hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
        +			/*			hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				out[n] ^= iv2[n];
        +			/*			hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
        +			iv = out;
        +			memcpy(prev, tmp, AES_BLOCK_SIZE);
        +			iv2 = prev;
        +			len -= AES_BLOCK_SIZE;
        +			}
        +		}
        +	else
        +		{
        +		/* First backwards */
        +		iv = ivec + AES_BLOCK_SIZE*2;
        +		iv2 = ivec + AES_BLOCK_SIZE*3;
        +		in += length;
        +		out += length;
        +		while (len >= AES_BLOCK_SIZE)
        +			{
        +			in -= AES_BLOCK_SIZE;
        +			out -= AES_BLOCK_SIZE;
        +			memcpy(tmp, in, AES_BLOCK_SIZE);
        +			memcpy(tmp2, in, AES_BLOCK_SIZE);
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				tmp[n] ^= iv2[n];
        +			AES_decrypt(tmp, out, key);
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				out[n] ^= iv[n];
        +			memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
        +			iv = tmp3;
        +			iv2 = out;
        +			len -= AES_BLOCK_SIZE;
        +			}
        +
        +		/* And now forwards */
        +		iv = ivec;
        +		iv2 = ivec + AES_BLOCK_SIZE;
        +		len = length;
        +		while (len >= AES_BLOCK_SIZE)
        +			{
        +			memcpy(tmp, out, AES_BLOCK_SIZE);
        +			memcpy(tmp2, out, AES_BLOCK_SIZE);
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				tmp[n] ^= iv2[n];
        +			AES_decrypt(tmp, out, key);
        +			for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
        +				out[n] ^= iv[n];
        +			memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
        +			iv = tmp3;
        +			iv2 = out;
        +			len -= AES_BLOCK_SIZE;
        +			in += AES_BLOCK_SIZE;
        +			out += AES_BLOCK_SIZE;
        +			}
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_locl.h b/vendor/openssl/openssl/crypto/aes/aes_locl.h
        new file mode 100644
        index 000000000..054b442d4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_locl.h
        @@ -0,0 +1,89 @@
        +/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + */
        +
        +#ifndef HEADER_AES_LOCL_H
        +#define HEADER_AES_LOCL_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifdef OPENSSL_NO_AES
        +#error AES is disabled.
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
        +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
        +# define GETU32(p) SWAP(*((u32 *)(p)))
        +# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
        +#else
        +# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
        +# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
        +#endif
        +
        +#ifdef AES_LONG
        +typedef unsigned long u32;
        +#else
        +typedef unsigned int u32;
        +#endif
        +typedef unsigned short u16;
        +typedef unsigned char u8;
        +
        +#define MAXKC   (256/32)
        +#define MAXKB   (256/8)
        +#define MAXNR   14
        +
        +/* This controls loop-unrolling in aes_core.c */
        +#undef FULL_UNROLL
        +
        +#endif /* !HEADER_AES_LOCL_H */
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_misc.c b/vendor/openssl/openssl/crypto/aes/aes_misc.c
        new file mode 100644
        index 000000000..f083488ec
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_misc.c
        @@ -0,0 +1,85 @@
        +/* crypto/aes/aes_misc.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +#include <openssl/aes.h>
        +#include "aes_locl.h"
        +
        +const char AES_version[]="AES" OPENSSL_VERSION_PTEXT;
        +
        +const char *AES_options(void) {
        +#ifdef FULL_UNROLL
        +        return "aes(full)";
        +#else   
        +        return "aes(partial)";
        +#endif
        +}
        +
        +/* FIPS wrapper functions to block low level AES calls in FIPS mode */
        +
        +int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +			AES_KEY *key)
        +	{
        +#ifdef OPENSSL_FIPS
        +	fips_cipher_abort(AES);
        +#endif
        +	return private_AES_set_encrypt_key(userKey, bits, key);
        +	}
        +
        +int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +			AES_KEY *key)
        +	{
        +#ifdef OPENSSL_FIPS
        +	fips_cipher_abort(AES);
        +#endif
        +	return private_AES_set_decrypt_key(userKey, bits, key);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_ofb.c b/vendor/openssl/openssl/crypto/aes/aes_ofb.c
        new file mode 100644
        index 000000000..50bf0b832
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_ofb.c
        @@ -0,0 +1,60 @@
        +/* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2002-2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/aes.h>
        +#include <openssl/modes.h>
        +
        +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const AES_KEY *key,
        +	unsigned char *ivec, int *num)
        +{
        +	CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)AES_encrypt);
        +}
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_wrap.c b/vendor/openssl/openssl/crypto/aes/aes_wrap.c
        new file mode 100644
        index 000000000..e2d73d37c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_wrap.c
        @@ -0,0 +1,259 @@
        +/* crypto/aes/aes_wrap.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/aes.h>
        +#include <openssl/bio.h>
        +
        +static const unsigned char default_iv[] = {
        +  0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
        +};
        +
        +int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
        +		unsigned char *out,
        +		const unsigned char *in, unsigned int inlen)
        +	{
        +	unsigned char *A, B[16], *R;
        +	unsigned int i, j, t;
        +	if ((inlen & 0x7) || (inlen < 8))
        +		return -1;
        +	A = B;
        +	t = 1;
        +	memcpy(out + 8, in, inlen);
        +	if (!iv)
        +		iv = default_iv;
        +
        +	memcpy(A, iv, 8);
        +
        +	for (j = 0; j < 6; j++)
        +		{
        +		R = out + 8;
        +		for (i = 0; i < inlen; i += 8, t++, R += 8)
        +			{
        +			memcpy(B + 8, R, 8);
        +			AES_encrypt(B, B, key);
        +			A[7] ^= (unsigned char)(t & 0xff);
        +			if (t > 0xff)	
        +				{
        +				A[6] ^= (unsigned char)((t >> 8) & 0xff);
        +				A[5] ^= (unsigned char)((t >> 16) & 0xff);
        +				A[4] ^= (unsigned char)((t >> 24) & 0xff);
        +				}
        +			memcpy(R, B + 8, 8);
        +			}
        +		}
        +	memcpy(out, A, 8);
        +	return inlen + 8;
        +	}
        +
        +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
        +		unsigned char *out,
        +		const unsigned char *in, unsigned int inlen)
        +	{
        +	unsigned char *A, B[16], *R;
        +	unsigned int i, j, t;
        +	inlen -= 8;
        +	if (inlen & 0x7)
        +		return -1;
        +	if (inlen < 8)
        +		return -1;
        +	A = B;
        +	t =  6 * (inlen >> 3);
        +	memcpy(A, in, 8);
        +	memcpy(out, in + 8, inlen);
        +	for (j = 0; j < 6; j++)
        +		{
        +		R = out + inlen - 8;
        +		for (i = 0; i < inlen; i += 8, t--, R -= 8)
        +			{
        +			A[7] ^= (unsigned char)(t & 0xff);
        +			if (t > 0xff)	
        +				{
        +				A[6] ^= (unsigned char)((t >> 8) & 0xff);
        +				A[5] ^= (unsigned char)((t >> 16) & 0xff);
        +				A[4] ^= (unsigned char)((t >> 24) & 0xff);
        +				}
        +			memcpy(B + 8, R, 8);
        +			AES_decrypt(B, B, key);
        +			memcpy(R, B + 8, 8);
        +			}
        +		}
        +	if (!iv)
        +		iv = default_iv;
        +	if (memcmp(A, iv, 8))
        +		{
        +		OPENSSL_cleanse(out, inlen);
        +		return 0;
        +		}
        +	return inlen;
        +	}
        +
        +#ifdef AES_WRAP_TEST
        +
        +int AES_wrap_unwrap_test(const unsigned char *kek, int keybits,
        +			 const unsigned char *iv,
        +			 const unsigned char *eout,
        +			 const unsigned char *key, int keylen)
        +	{
        +	unsigned char *otmp = NULL, *ptmp = NULL;
        +	int r, ret = 0;
        +	AES_KEY wctx;
        +	otmp = OPENSSL_malloc(keylen + 8);
        +	ptmp = OPENSSL_malloc(keylen);
        +	if (!otmp || !ptmp)
        +		return 0;
        +	if (AES_set_encrypt_key(kek, keybits, &wctx))
        +		goto err;
        +	r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
        +	if (r <= 0)
        +		goto err;
        +
        +	if (eout && memcmp(eout, otmp, keylen))
        +		goto err;
        +		
        +	if (AES_set_decrypt_key(kek, keybits, &wctx))
        +		goto err;
        +	r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
        +
        +	if (memcmp(key, ptmp, keylen))
        +		goto err;
        +
        +	ret = 1;
        +
        +	err:
        +	if (otmp)
        +		OPENSSL_free(otmp);
        +	if (ptmp)
        +		OPENSSL_free(ptmp);
        +
        +	return ret;
        +
        +	}
        +
        +
        +
        +int main(int argc, char **argv)
        +{
        +
        +static const unsigned char kek[] = {
        +  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
        +  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        +  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
        +};
        +
        +static const unsigned char key[] = {
        +  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        +  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
        +  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
        +};
        +
        +static const unsigned char e1[] = {
        +  0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47,
        +  0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82,
        +  0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5
        +};
        +
        +static const unsigned char e2[] = {
        +  0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35,
        +  0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2,
        +  0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d
        +};
        +
        +static const unsigned char e3[] = {
        +  0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2,
        +  0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a,
        +  0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7
        +};
        +
        +static const unsigned char e4[] = {
        +  0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32,
        +  0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc,
        +  0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93,
        +  0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2
        +};
        +
        +static const unsigned char e5[] = {
        +  0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f,
        +  0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4,
        +  0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95,
        +  0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1
        +};
        +
        +static const unsigned char e6[] = {
        +  0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4,
        +  0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26,
        +  0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26,
        +  0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b,
        +  0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21
        +};
        +
        +	AES_KEY wctx, xctx;
        +	int ret;
        +	ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16);
        +	fprintf(stderr, "Key test result %d\n", ret);
        +	ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16);
        +	fprintf(stderr, "Key test result %d\n", ret);
        +	ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16);
        +	fprintf(stderr, "Key test result %d\n", ret);
        +	ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24);
        +	fprintf(stderr, "Key test result %d\n", ret);
        +	ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24);
        +	fprintf(stderr, "Key test result %d\n", ret);
        +	ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32);
        +	fprintf(stderr, "Key test result %d\n", ret);
        +}
        +	
        +	
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/aes/aes_x86core.c b/vendor/openssl/openssl/crypto/aes/aes_x86core.c
        new file mode 100644
        index 000000000..d323e265c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/aes_x86core.c
        @@ -0,0 +1,1063 @@
        +/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
        +/**
        + * rijndael-alg-fst.c
        + *
        + * @version 3.0 (December 2000)
        + *
        + * Optimised ANSI C code for the Rijndael cipher (now AES)
        + *
        + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
        + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
        + * @author Paulo Barreto <paulo.barreto@terra.com.br>
        + *
        + * This code is hereby placed in the public domain.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
        + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
        + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
        + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +/*
        + * This is experimental x86[_64] derivative. It assumes little-endian
        + * byte order and expects CPU to sustain unaligned memory references.
        + * It is used as playground for cache-time attack mitigations and
        + * serves as reference C implementation for x86[_64] assembler.
        + *
        + *					<appro@fy.chalmers.se>
        + */
        +
        +
        +#ifndef AES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +#include <stdlib.h>
        +#include <openssl/aes.h>
        +#include "aes_locl.h"
        +
        +/*
        + * These two parameters control which table, 256-byte or 2KB, is
        + * referenced in outer and respectively inner rounds.
        + */
        +#define AES_COMPACT_IN_OUTER_ROUNDS
        +#ifdef  AES_COMPACT_IN_OUTER_ROUNDS
        +/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
        + * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
        + * by factor of ~2. */
        +# undef  AES_COMPACT_IN_INNER_ROUNDS
        +#endif
        +
        +#if 1
        +static void prefetch256(const void *table)
        +{
        +	volatile unsigned long *t=(void *)table,ret;
        +	unsigned long sum;
        +	int i;
        +
        +	/* 32 is common least cache-line size */
        +	for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0]))	sum ^= t[i];
        +
        +	ret = sum;
        +}
        +#else
        +# define prefetch256(t)
        +#endif
        +
        +#undef GETU32
        +#define GETU32(p) (*((u32*)(p)))
        +
        +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
        +typedef unsigned __int64 u64;
        +#define U64(C)	C##UI64
        +#elif defined(__arch64__)
        +typedef unsigned long u64;
        +#define U64(C)	C##UL
        +#else
        +typedef unsigned long long u64;
        +#define U64(C)	C##ULL
        +#endif
        +
        +#undef ROTATE
        +#if defined(_MSC_VER) || defined(__ICC)
        +# define ROTATE(a,n)	_lrotl(a,n)
        +#elif defined(__GNUC__) && __GNUC__>=2
        +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
        +#   define ROTATE(a,n)	({ register unsigned int ret;	\
        +				asm (			\
        +				"roll %1,%0"		\
        +				: "=r"(ret)		\
        +				: "I"(n), "0"(a)	\
        +				: "cc");		\
        +			   ret;				\
        +			})
        +# endif
        +#endif
        +/*
        +Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
        +Te0[x] = S [x].[02, 01, 01, 03];
        +Te1[x] = S [x].[03, 02, 01, 01];
        +Te2[x] = S [x].[01, 03, 02, 01];
        +Te3[x] = S [x].[01, 01, 03, 02];
        +*/
        +#define Te0 (u32)((u64*)((u8*)Te+0))
        +#define Te1 (u32)((u64*)((u8*)Te+3))
        +#define Te2 (u32)((u64*)((u8*)Te+2))
        +#define Te3 (u32)((u64*)((u8*)Te+1))
        +/*
        +Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
        +Td0[x] = Si[x].[0e, 09, 0d, 0b];
        +Td1[x] = Si[x].[0b, 0e, 09, 0d];
        +Td2[x] = Si[x].[0d, 0b, 0e, 09];
        +Td3[x] = Si[x].[09, 0d, 0b, 0e];
        +Td4[x] = Si[x].[01];
        +*/
        +#define Td0 (u32)((u64*)((u8*)Td+0))
        +#define Td1 (u32)((u64*)((u8*)Td+3))
        +#define Td2 (u32)((u64*)((u8*)Td+2))
        +#define Td3 (u32)((u64*)((u8*)Td+1))
        +
        +static const u64 Te[256] = {
        +    U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
        +    U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
        +    U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
        +    U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
        +    U64(0x5030306050303060), U64(0x0301010203010102),
        +    U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
        +    U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
        +    U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
        +    U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
        +    U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
        +    U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
        +    U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
        +    U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
        +    U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
        +    U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
        +    U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
        +    U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
        +    U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
        +    U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
        +    U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
        +    U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
        +    U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
        +    U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
        +    U64(0x5331316253313162), U64(0x3f15152a3f15152a),
        +    U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
        +    U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
        +    U64(0x2818183028181830), U64(0xa1969637a1969637),
        +    U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
        +    U64(0x0907070e0907070e), U64(0x3612122436121224),
        +    U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
        +    U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
        +    U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
        +    U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
        +    U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
        +    U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
        +    U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
        +    U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
        +    U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
        +    U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
        +    U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
        +    U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
        +    U64(0x0000000000000000), U64(0x2cededc12cededc1),
        +    U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
        +    U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
        +    U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
        +    U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
        +    U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
        +    U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
        +    U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
        +    U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
        +    U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
        +    U64(0x5533336655333366), U64(0x9485851194858511),
        +    U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
        +    U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
        +    U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
        +    U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
        +    U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
        +    U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
        +    U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
        +    U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
        +    U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
        +    U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
        +    U64(0x3010102030101020), U64(0x1affffe51affffe5),
        +    U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
        +    U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
        +    U64(0x3513132635131326), U64(0x2fececc32fececc3),
        +    U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
        +    U64(0xcc444488cc444488), U64(0x3917172e3917172e),
        +    U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
        +    U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
        +    U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
        +    U64(0x2b1919322b191932), U64(0x957373e6957373e6),
        +    U64(0xa06060c0a06060c0), U64(0x9881811998818119),
        +    U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
        +    U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
        +    U64(0xab90903bab90903b), U64(0x8388880b8388880b),
        +    U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
        +    U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
        +    U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
        +    U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
        +    U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
        +    U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
        +    U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
        +    U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
        +    U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
        +    U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
        +    U64(0xa8919139a8919139), U64(0xa4959531a4959531),
        +    U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
        +    U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
        +    U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
        +    U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
        +    U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
        +    U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
        +    U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
        +    U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
        +    U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
        +    U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
        +    U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
        +    U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
        +    U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
        +    U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
        +    U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
        +    U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
        +    U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
        +    U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
        +    U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
        +    U64(0xd8484890d8484890), U64(0x0503030605030306),
        +    U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
        +    U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
        +    U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
        +    U64(0x9186861791868617), U64(0x58c1c19958c1c199),
        +    U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
        +    U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
        +    U64(0xb398982bb398982b), U64(0x3311112233111122),
        +    U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
        +    U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
        +    U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
        +    U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
        +    U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
        +    U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
        +    U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
        +    U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
        +    U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
        +    U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
        +    U64(0xc3414182c3414182), U64(0xb0999929b0999929),
        +    U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
        +    U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
        +    U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
        +};
        +
        +static const u8 Te4[256] = {
        +    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
        +    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
        +    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
        +    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
        +    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
        +    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
        +    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
        +    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
        +    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
        +    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
        +    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
        +    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
        +    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
        +    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
        +    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
        +    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
        +    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
        +    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
        +    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
        +    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
        +    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
        +    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
        +    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
        +    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
        +    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
        +    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
        +    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
        +    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
        +    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
        +    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
        +    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
        +    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
        +};
        +
        +static const u64 Td[256] = {
        +    U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
        +    U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
        +    U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
        +    U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
        +    U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
        +    U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
        +    U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
        +    U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
        +    U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
        +    U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
        +    U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
        +    U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
        +    U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
        +    U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
        +    U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
        +    U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
        +    U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
        +    U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
        +    U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
        +    U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
        +    U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
        +    U64(0x6033519760335197), U64(0x457f5362457f5362),
        +    U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
        +    U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
        +    U64(0x5868487058684870), U64(0x19fd458f19fd458f),
        +    U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
        +    U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
        +    U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
        +    U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
        +    U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
        +    U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
        +    U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
        +    U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
        +    U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
        +    U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
        +    U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
        +    U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
        +    U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
        +    U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
        +    U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
        +    U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
        +    U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
        +    U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
        +    U64(0x6fd406046fd40604), U64(0xff155060ff155060),
        +    U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
        +    U64(0xcc434089cc434089), U64(0x779ed967779ed967),
        +    U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
        +    U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
        +    U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
        +    U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
        +    U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
        +    U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
        +    U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
        +    U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
        +    U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
        +    U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
        +    U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
        +    U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
        +    U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
        +    U64(0x694b775a694b775a), U64(0x161a121c161a121c),
        +    U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
        +    U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
        +    U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
        +    U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
        +    U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
        +    U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
        +    U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
        +    U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
        +    U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
        +    U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
        +    U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
        +    U64(0x4022971340229713), U64(0x2011c6842011c684),
        +    U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
        +    U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
        +    U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
        +    U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
        +    U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
        +    U64(0xfa489411fa489411), U64(0x2264e9472264e947),
        +    U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
        +    U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
        +    U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
        +    U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
        +    U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
        +    U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
        +    U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
        +    U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
        +    U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
        +    U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
        +    U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
        +    U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
        +    U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
        +    U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
        +    U64(0x097826cd097826cd), U64(0xf418596ef418596e),
        +    U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
        +    U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
        +    U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
        +    U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
        +    U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
        +    U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
        +    U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
        +    U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
        +    U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
        +    U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
        +    U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
        +    U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
        +    U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
        +    U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
        +    U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
        +    U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
        +    U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
        +    U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
        +    U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
        +    U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
        +    U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
        +    U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
        +    U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
        +    U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
        +    U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
        +    U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
        +    U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
        +    U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
        +    U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
        +    U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
        +    U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
        +    U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
        +    U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
        +    U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
        +    U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
        +};
        +static const u8 Td4[256] = {
        +    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
        +    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
        +    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
        +    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
        +    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
        +    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
        +    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
        +    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
        +    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
        +    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
        +    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
        +    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
        +    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
        +    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
        +    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
        +    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
        +    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
        +    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
        +    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
        +    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
        +    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
        +    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
        +    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
        +    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
        +    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
        +    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
        +    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
        +    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
        +    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
        +    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
        +    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
        +    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
        +};
        +
        +static const u32 rcon[] = {
        +    0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U,
        +    0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U,
        +    0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
        +};
        +
        +/**
        + * Expand the cipher key into the encryption key schedule.
        + */
        +int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +			AES_KEY *key) {
        +
        +	u32 *rk;
        +   	int i = 0;
        +	u32 temp;
        +
        +	if (!userKey || !key)
        +		return -1;
        +	if (bits != 128 && bits != 192 && bits != 256)
        +		return -2;
        +
        +	rk = key->rd_key;
        +
        +	if (bits==128)
        +		key->rounds = 10;
        +	else if (bits==192)
        +		key->rounds = 12;
        +	else
        +		key->rounds = 14;
        +
        +	rk[0] = GETU32(userKey     );
        +	rk[1] = GETU32(userKey +  4);
        +	rk[2] = GETU32(userKey +  8);
        +	rk[3] = GETU32(userKey + 12);
        +	if (bits == 128) {
        +		while (1) {
        +			temp  = rk[3];
        +			rk[4] = rk[0] ^
        +				(Te4[(temp >>  8) & 0xff]      ) ^
        +				(Te4[(temp >> 16) & 0xff] <<  8) ^
        +				(Te4[(temp >> 24)       ] << 16) ^
        +				(Te4[(temp      ) & 0xff] << 24) ^
        +				rcon[i];
        +			rk[5] = rk[1] ^ rk[4];
        +			rk[6] = rk[2] ^ rk[5];
        +			rk[7] = rk[3] ^ rk[6];
        +			if (++i == 10) {
        +				return 0;
        +			}
        +			rk += 4;
        +		}
        +	}
        +	rk[4] = GETU32(userKey + 16);
        +	rk[5] = GETU32(userKey + 20);
        +	if (bits == 192) {
        +		while (1) {
        +			temp = rk[ 5];
        +			rk[ 6] = rk[ 0] ^
        +				(Te4[(temp >>  8) & 0xff]      ) ^
        +				(Te4[(temp >> 16) & 0xff] <<  8) ^
        +				(Te4[(temp >> 24)       ] << 16) ^
        +				(Te4[(temp      ) & 0xff] << 24) ^
        +				rcon[i];
        +			rk[ 7] = rk[ 1] ^ rk[ 6];
        +			rk[ 8] = rk[ 2] ^ rk[ 7];
        +			rk[ 9] = rk[ 3] ^ rk[ 8];
        +			if (++i == 8) {
        +				return 0;
        +			}
        +			rk[10] = rk[ 4] ^ rk[ 9];
        +			rk[11] = rk[ 5] ^ rk[10];
        +			rk += 6;
        +		}
        +	}
        +	rk[6] = GETU32(userKey + 24);
        +	rk[7] = GETU32(userKey + 28);
        +	if (bits == 256) {
        +		while (1) {
        +			temp = rk[ 7];
        +			rk[ 8] = rk[ 0] ^
        +				(Te4[(temp >>  8) & 0xff]      ) ^
        +				(Te4[(temp >> 16) & 0xff] <<  8) ^
        +				(Te4[(temp >> 24)       ] << 16) ^
        +				(Te4[(temp      ) & 0xff] << 24) ^
        +				rcon[i];
        +			rk[ 9] = rk[ 1] ^ rk[ 8];
        +			rk[10] = rk[ 2] ^ rk[ 9];
        +			rk[11] = rk[ 3] ^ rk[10];
        +			if (++i == 7) {
        +				return 0;
        +			}
        +			temp = rk[11];
        +			rk[12] = rk[ 4] ^
        +				(Te4[(temp      ) & 0xff]      ) ^
        +				(Te4[(temp >>  8) & 0xff] <<  8) ^
        +				(Te4[(temp >> 16) & 0xff] << 16) ^
        +				(Te4[(temp >> 24)       ] << 24);
        +			rk[13] = rk[ 5] ^ rk[12];
        +			rk[14] = rk[ 6] ^ rk[13];
        +			rk[15] = rk[ 7] ^ rk[14];
        +
        +			rk += 8;
        +        	}
        +	}
        +	return 0;
        +}
        +
        +/**
        + * Expand the cipher key into the decryption key schedule.
        + */
        +int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +			 AES_KEY *key) {
        +
        +        u32 *rk;
        +	int i, j, status;
        +	u32 temp;
        +
        +	/* first, start with an encryption schedule */
        +	status = AES_set_encrypt_key(userKey, bits, key);
        +	if (status < 0)
        +		return status;
        +
        +	rk = key->rd_key;
        +
        +	/* invert the order of the round keys: */
        +	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
        +		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
        +		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
        +		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
        +		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
        +	}
        +	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
        +	for (i = 1; i < (key->rounds); i++) {
        +		rk += 4;
        +#if 1
        +		for (j = 0; j < 4; j++) {
        +			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
        +
        +			tp1 = rk[j];
        +			m = tp1 & 0x80808080;
        +			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp2 & 0x80808080;
        +			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp4 & 0x80808080;
        +			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			tp9 = tp8 ^ tp1;
        +			tpb = tp9 ^ tp2;
        +			tpd = tp9 ^ tp4;
        +			tpe = tp8 ^ tp4 ^ tp2;
        +#if defined(ROTATE)
        +			rk[j] = tpe ^ ROTATE(tpd,16) ^
        +				ROTATE(tp9,8) ^ ROTATE(tpb,24);
        +#else
        +			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
        +				(tp9 >> 24) ^ (tp9 << 8) ^
        +				(tpb >> 8) ^ (tpb << 24);
        +#endif
        +		}
        +#else
        +		rk[0] =
        +			Td0[Te2[(rk[0]      ) & 0xff] & 0xff] ^
        +			Td1[Te2[(rk[0] >>  8) & 0xff] & 0xff] ^
        +			Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^
        +			Td3[Te2[(rk[0] >> 24)       ] & 0xff];
        +		rk[1] =
        +			Td0[Te2[(rk[1]      ) & 0xff] & 0xff] ^
        +			Td1[Te2[(rk[1] >>  8) & 0xff] & 0xff] ^
        +			Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^
        +			Td3[Te2[(rk[1] >> 24)       ] & 0xff];
        +		rk[2] =
        +			Td0[Te2[(rk[2]      ) & 0xff] & 0xff] ^
        +			Td1[Te2[(rk[2] >>  8) & 0xff] & 0xff] ^
        +			Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^
        +			Td3[Te2[(rk[2] >> 24)       ] & 0xff];
        +		rk[3] =
        +			Td0[Te2[(rk[3]      ) & 0xff] & 0xff] ^
        +			Td1[Te2[(rk[3] >>  8) & 0xff] & 0xff] ^
        +			Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^
        +			Td3[Te2[(rk[3] >> 24)       ] & 0xff];
        +#endif
        +	}
        +	return 0;
        +}
        +
        +/*
        + * Encrypt a single block
        + * in and out can overlap
        + */
        +void AES_encrypt(const unsigned char *in, unsigned char *out,
        +		 const AES_KEY *key) {
        +
        +	const u32 *rk;
        +	u32 s0, s1, s2, s3, t[4];
        +	int r;
        +
        +	assert(in && out && key);
        +	rk = key->rd_key;
        +
        +	/*
        +	 * map byte array block to cipher state
        +	 * and add initial round key:
        +	 */
        +	s0 = GETU32(in     ) ^ rk[0];
        +	s1 = GETU32(in +  4) ^ rk[1];
        +	s2 = GETU32(in +  8) ^ rk[2];
        +	s3 = GETU32(in + 12) ^ rk[3];
        +
        +#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
        +	prefetch256(Te4);
        +
        +	t[0] =	Te4[(s0      ) & 0xff]       ^
        +		Te4[(s1 >>  8) & 0xff] <<  8 ^
        +		Te4[(s2 >> 16) & 0xff] << 16 ^
        +		Te4[(s3 >> 24)       ] << 24;
        +	t[1] =	Te4[(s1      ) & 0xff]       ^
        +		Te4[(s2 >>  8) & 0xff] <<  8 ^
        +		Te4[(s3 >> 16) & 0xff] << 16 ^
        +		Te4[(s0 >> 24)       ] << 24;
        +	t[2] =	Te4[(s2      ) & 0xff]       ^
        +		Te4[(s3 >>  8) & 0xff] <<  8 ^
        +		Te4[(s0 >> 16) & 0xff] << 16 ^
        +		Te4[(s1 >> 24)       ] << 24;
        +	t[3] =	Te4[(s3      ) & 0xff]       ^
        +		Te4[(s0 >>  8) & 0xff] <<  8 ^
        +		Te4[(s1 >> 16) & 0xff] << 16 ^
        +		Te4[(s2 >> 24)       ] << 24;
        +
        +	/* now do the linear transform using words */
        +	{	int i;
        +		u32 r0, r1, r2;
        +
        +		for (i = 0; i < 4; i++) {
        +			r0 = t[i];
        +			r1 = r0 & 0x80808080;
        +			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
        +				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
        +#if defined(ROTATE)
        +			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
        +				ROTATE(r0,16) ^ ROTATE(r0,8);
        +#else
        +			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
        +				(r0 << 16) ^ (r0 >> 16) ^
        +				(r0 << 8) ^ (r0 >> 24);
        +#endif
        +			t[i] ^= rk[4+i];
        +		}
        +	}
        +#else
        +	t[0] =	Te0[(s0      ) & 0xff] ^
        +		Te1[(s1 >>  8) & 0xff] ^
        +		Te2[(s2 >> 16) & 0xff] ^
        +		Te3[(s3 >> 24)       ] ^
        +		rk[4];
        +	t[1] =	Te0[(s1      ) & 0xff] ^
        +		Te1[(s2 >>  8) & 0xff] ^
        +		Te2[(s3 >> 16) & 0xff] ^
        +		Te3[(s0 >> 24)       ] ^
        +		rk[5];
        +	t[2] =	Te0[(s2      ) & 0xff] ^
        +		Te1[(s3 >>  8) & 0xff] ^
        +		Te2[(s0 >> 16) & 0xff] ^
        +		Te3[(s1 >> 24)       ] ^
        +		rk[6];
        +	t[3] =	Te0[(s3      ) & 0xff] ^
        +		Te1[(s0 >>  8) & 0xff] ^
        +		Te2[(s1 >> 16) & 0xff] ^
        +		Te3[(s2 >> 24)       ] ^
        +		rk[7];
        +#endif
        +	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
        +
        +    /*
        +     * Nr - 2 full rounds:
        +     */
        +    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
        +#if defined(AES_COMPACT_IN_INNER_ROUNDS)
        +	t[0] =	Te4[(s0      ) & 0xff]       ^
        +		Te4[(s1 >>  8) & 0xff] <<  8 ^
        +		Te4[(s2 >> 16) & 0xff] << 16 ^
        +		Te4[(s3 >> 24)       ] << 24;
        +	t[1] =	Te4[(s1      ) & 0xff]       ^
        +		Te4[(s2 >>  8) & 0xff] <<  8 ^
        +		Te4[(s3 >> 16) & 0xff] << 16 ^
        +		Te4[(s0 >> 24)       ] << 24;
        +	t[2] =	Te4[(s2      ) & 0xff]       ^
        +		Te4[(s3 >>  8) & 0xff] <<  8 ^
        +		Te4[(s0 >> 16) & 0xff] << 16 ^
        +		Te4[(s1 >> 24)       ] << 24;
        +	t[3] =	Te4[(s3      ) & 0xff]       ^
        +		Te4[(s0 >>  8) & 0xff] <<  8 ^
        +		Te4[(s1 >> 16) & 0xff] << 16 ^
        +		Te4[(s2 >> 24)       ] << 24;
        +
        +	/* now do the linear transform using words */
        +	{	int i;
        +		u32 r0, r1, r2;
        +
        +		for (i = 0; i < 4; i++) {
        +			r0 = t[i];
        +			r1 = r0 & 0x80808080;
        +			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
        +				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
        +#if defined(ROTATE)
        +			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
        +				ROTATE(r0,16) ^ ROTATE(r0,8);
        +#else
        +			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
        +				(r0 << 16) ^ (r0 >> 16) ^
        +				(r0 << 8) ^ (r0 >> 24);
        +#endif
        +			t[i] ^= rk[i];
        +		}
        +	}
        +#else
        +	t[0] =	Te0[(s0      ) & 0xff] ^
        +		Te1[(s1 >>  8) & 0xff] ^
        +		Te2[(s2 >> 16) & 0xff] ^
        +		Te3[(s3 >> 24)       ] ^
        +		rk[0];
        +	t[1] =	Te0[(s1      ) & 0xff] ^
        +		Te1[(s2 >>  8) & 0xff] ^
        +		Te2[(s3 >> 16) & 0xff] ^
        +		Te3[(s0 >> 24)       ] ^
        +		rk[1];
        +	t[2] =	Te0[(s2      ) & 0xff] ^
        +		Te1[(s3 >>  8) & 0xff] ^
        +		Te2[(s0 >> 16) & 0xff] ^
        +		Te3[(s1 >> 24)       ] ^
        +		rk[2];
        +	t[3] =	Te0[(s3      ) & 0xff] ^
        +		Te1[(s0 >>  8) & 0xff] ^
        +		Te2[(s1 >> 16) & 0xff] ^
        +		Te3[(s2 >> 24)       ] ^
        +		rk[3];
        +#endif
        +	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
        +    }
        +    /*
        +	 * apply last round and
        +	 * map cipher state to byte array block:
        +	 */
        +#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
        +	prefetch256(Te4);
        +
        +	*(u32*)(out+0) =
        +		Te4[(s0      ) & 0xff]       ^
        +		Te4[(s1 >>  8) & 0xff] <<  8 ^
        +		Te4[(s2 >> 16) & 0xff] << 16 ^
        +		Te4[(s3 >> 24)       ] << 24 ^
        +		rk[0];
        +	*(u32*)(out+4) =
        +		Te4[(s1      ) & 0xff]       ^
        +		Te4[(s2 >>  8) & 0xff] <<  8 ^
        +		Te4[(s3 >> 16) & 0xff] << 16 ^
        +		Te4[(s0 >> 24)       ] << 24 ^
        +		rk[1];
        +	*(u32*)(out+8) =
        +		Te4[(s2      ) & 0xff]       ^
        +		Te4[(s3 >>  8) & 0xff] <<  8 ^
        +		Te4[(s0 >> 16) & 0xff] << 16 ^
        +		Te4[(s1 >> 24)       ] << 24 ^
        +		rk[2];
        +	*(u32*)(out+12) =
        +		Te4[(s3      ) & 0xff]       ^
        +		Te4[(s0 >>  8) & 0xff] <<  8 ^
        +		Te4[(s1 >> 16) & 0xff] << 16 ^
        +		Te4[(s2 >> 24)       ] << 24 ^
        +		rk[3];
        +#else
        +	*(u32*)(out+0) =
        +		(Te2[(s0      ) & 0xff] & 0x000000ffU) ^
        +		(Te3[(s1 >>  8) & 0xff] & 0x0000ff00U) ^
        +		(Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^
        +		(Te1[(s3 >> 24)       ] & 0xff000000U) ^
        +		rk[0];
        +	*(u32*)(out+4) =
        +		(Te2[(s1      ) & 0xff] & 0x000000ffU) ^
        +		(Te3[(s2 >>  8) & 0xff] & 0x0000ff00U) ^
        +		(Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^
        +		(Te1[(s0 >> 24)       ] & 0xff000000U) ^
        +		rk[1];
        +	*(u32*)(out+8) =
        +		(Te2[(s2      ) & 0xff] & 0x000000ffU) ^
        +		(Te3[(s3 >>  8) & 0xff] & 0x0000ff00U) ^
        +		(Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^
        +		(Te1[(s1 >> 24)       ] & 0xff000000U) ^
        +		rk[2];
        +	*(u32*)(out+12) =
        +		(Te2[(s3      ) & 0xff] & 0x000000ffU) ^
        +		(Te3[(s0 >>  8) & 0xff] & 0x0000ff00U) ^
        +		(Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^
        +		(Te1[(s2 >> 24)       ] & 0xff000000U) ^
        +		rk[3];
        +#endif
        +}
        +
        +/*
        + * Decrypt a single block
        + * in and out can overlap
        + */
        +void AES_decrypt(const unsigned char *in, unsigned char *out,
        +		 const AES_KEY *key) {
        +
        +	const u32 *rk;
        +	u32 s0, s1, s2, s3, t[4];
        +	int r;
        +
        +	assert(in && out && key);
        +	rk = key->rd_key;
        +
        +	/*
        +	 * map byte array block to cipher state
        +	 * and add initial round key:
        +	 */
        +	s0 = GETU32(in     ) ^ rk[0];
        +	s1 = GETU32(in +  4) ^ rk[1];
        +	s2 = GETU32(in +  8) ^ rk[2];
        +	s3 = GETU32(in + 12) ^ rk[3];
        +
        +#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
        +	prefetch256(Td4);
        +
        +        t[0] =	Td4[(s0      ) & 0xff]       ^
        +		Td4[(s3 >>  8) & 0xff] <<  8 ^
        +		Td4[(s2 >> 16) & 0xff] << 16 ^
        +		Td4[(s1 >> 24)       ] << 24;
        +        t[1] =	Td4[(s1      ) & 0xff]       ^
        +		Td4[(s0 >>  8) & 0xff] <<  8 ^
        +		Td4[(s3 >> 16) & 0xff] << 16 ^
        +		Td4[(s2 >> 24)       ] << 24;
        +        t[2] =	Td4[(s2      ) & 0xff]       ^
        +		Td4[(s1 >>  8) & 0xff] <<  8 ^
        +		Td4[(s0 >> 16) & 0xff] << 16 ^
        +		Td4[(s3 >> 24)       ] << 24;
        +        t[3] =	Td4[(s3      ) & 0xff]       ^
        +		Td4[(s2 >>  8) & 0xff] <<  8 ^
        +		Td4[(s1 >> 16) & 0xff] << 16 ^
        +		Td4[(s0 >> 24)       ] << 24;
        +
        +	/* now do the linear transform using words */ 
        +	{	int i;
        +		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
        +
        +		for (i = 0; i < 4; i++) {
        +			tp1 = t[i];
        +			m = tp1 & 0x80808080;
        +			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp2 & 0x80808080;
        +			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp4 & 0x80808080;
        +			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			tp9 = tp8 ^ tp1;
        +			tpb = tp9 ^ tp2;
        +			tpd = tp9 ^ tp4;
        +			tpe = tp8 ^ tp4 ^ tp2;
        +#if defined(ROTATE)
        +			t[i] = tpe ^ ROTATE(tpd,16) ^
        +				ROTATE(tp9,8) ^ ROTATE(tpb,24);
        +#else
        +			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
        +				(tp9 >> 24) ^ (tp9 << 8) ^
        +				(tpb >> 8) ^ (tpb << 24);
        +#endif
        +			t[i] ^= rk[4+i];
        +		}
        +	}
        +#else
        +	t[0] =	Td0[(s0      ) & 0xff] ^
        +		Td1[(s3 >>  8) & 0xff] ^
        +		Td2[(s2 >> 16) & 0xff] ^
        +		Td3[(s1 >> 24)       ] ^
        +		rk[4];
        +	t[1] =	Td0[(s1      ) & 0xff] ^
        +		Td1[(s0 >>  8) & 0xff] ^
        +		Td2[(s3 >> 16) & 0xff] ^
        +		Td3[(s2 >> 24)       ] ^
        +		rk[5];
        +	t[2] =	Td0[(s2      ) & 0xff] ^
        +		Td1[(s1 >>  8) & 0xff] ^
        +		Td2[(s0 >> 16) & 0xff] ^
        +		Td3[(s3 >> 24)       ] ^
        +		rk[6];
        +	t[3] =	Td0[(s3      ) & 0xff] ^
        +		Td1[(s2 >>  8) & 0xff] ^
        +		Td2[(s1 >> 16) & 0xff] ^
        +		Td3[(s0 >> 24)       ] ^
        +		rk[7];
        +#endif
        +	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
        +
        +    /*
        +     * Nr - 2 full rounds:
        +     */
        +    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
        +#if defined(AES_COMPACT_IN_INNER_ROUNDS)
        +        t[0] =	Td4[(s0      ) & 0xff]       ^
        +		Td4[(s3 >>  8) & 0xff] <<  8 ^
        +		Td4[(s2 >> 16) & 0xff] << 16 ^
        +		Td4[(s1 >> 24)       ] << 24;
        +        t[1] =	Td4[(s1      ) & 0xff]       ^
        +		Td4[(s0 >>  8) & 0xff] <<  8 ^
        +		Td4[(s3 >> 16) & 0xff] << 16 ^
        +		Td4[(s2 >> 24)       ] << 24;
        +        t[2] =	Td4[(s2      ) & 0xff]       ^
        +		Td4[(s1 >>  8) & 0xff] <<  8 ^
        +		Td4[(s0 >> 16) & 0xff] << 16 ^
        +		Td4[(s3 >> 24)       ] << 24;
        +        t[3] =	Td4[(s3      ) & 0xff]       ^
        +		Td4[(s2 >>  8) & 0xff] <<  8 ^
        +		Td4[(s1 >> 16) & 0xff] << 16 ^
        +		Td4[(s0 >> 24)       ] << 24;
        +
        +	/* now do the linear transform using words */ 
        +	{	int i;
        +		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
        +
        +		for (i = 0; i < 4; i++) {
        +			tp1 = t[i];
        +			m = tp1 & 0x80808080;
        +			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp2 & 0x80808080;
        +			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			m = tp4 & 0x80808080;
        +			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
        +				((m - (m >> 7)) & 0x1b1b1b1b);
        +			tp9 = tp8 ^ tp1;
        +			tpb = tp9 ^ tp2;
        +			tpd = tp9 ^ tp4;
        +			tpe = tp8 ^ tp4 ^ tp2;
        +#if defined(ROTATE)
        +			t[i] = tpe ^ ROTATE(tpd,16) ^
        +				ROTATE(tp9,8) ^ ROTATE(tpb,24);
        +#else
        +			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
        +				(tp9 >> 24) ^ (tp9 << 8) ^
        +				(tpb >> 8) ^ (tpb << 24);
        +#endif
        +			t[i] ^= rk[i];
        +		}
        +	}
        +#else
        +	t[0] =	Td0[(s0      ) & 0xff] ^
        +		Td1[(s3 >>  8) & 0xff] ^
        +		Td2[(s2 >> 16) & 0xff] ^
        +		Td3[(s1 >> 24)       ] ^
        +		rk[0];
        +	t[1] =	Td0[(s1      ) & 0xff] ^
        +		Td1[(s0 >>  8) & 0xff] ^
        +		Td2[(s3 >> 16) & 0xff] ^
        +		Td3[(s2 >> 24)       ] ^
        +		rk[1];
        +	t[2] =	Td0[(s2      ) & 0xff] ^
        +		Td1[(s1 >>  8) & 0xff] ^
        +		Td2[(s0 >> 16) & 0xff] ^
        +		Td3[(s3 >> 24)       ] ^
        +		rk[2];
        +	t[3] =	Td0[(s3      ) & 0xff] ^
        +		Td1[(s2 >>  8) & 0xff] ^
        +		Td2[(s1 >> 16) & 0xff] ^
        +		Td3[(s0 >> 24)       ] ^
        +		rk[3];
        +#endif
        +	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
        +    }
        +    /*
        +	 * apply last round and
        +	 * map cipher state to byte array block:
        +	 */
        +	prefetch256(Td4);
        +
        +	*(u32*)(out+0) =
        +		(Td4[(s0      ) & 0xff])	^
        +		(Td4[(s3 >>  8) & 0xff] <<  8) ^
        +		(Td4[(s2 >> 16) & 0xff] << 16) ^
        +		(Td4[(s1 >> 24)       ] << 24) ^
        +		rk[0];
        +	*(u32*)(out+4) =
        +		(Td4[(s1      ) & 0xff])	 ^
        +		(Td4[(s0 >>  8) & 0xff] <<  8) ^
        +		(Td4[(s3 >> 16) & 0xff] << 16) ^
        +		(Td4[(s2 >> 24)       ] << 24) ^
        +		rk[1];
        +	*(u32*)(out+8) =
        +		(Td4[(s2      ) & 0xff])	 ^
        +		(Td4[(s1 >>  8) & 0xff] <<  8) ^
        +		(Td4[(s0 >> 16) & 0xff] << 16) ^
        +		(Td4[(s3 >> 24)       ] << 24) ^
        +		rk[2];
        +	*(u32*)(out+12) =
        +		(Td4[(s3      ) & 0xff])	 ^
        +		(Td4[(s2 >>  8) & 0xff] <<  8) ^
        +		(Td4[(s1 >> 16) & 0xff] << 16) ^
        +		(Td4[(s0 >> 24)       ] << 24) ^
        +		rk[3];
        +}
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-586.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-586.pl
        new file mode 100644
        index 000000000..6eb479035
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-586.pl
        @@ -0,0 +1,2980 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# Version 4.3.
        +#
        +# You might fail to appreciate this module performance from the first
        +# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered
        +# to be *the* best Intel C compiler without -KPIC, performance appears
        +# to be virtually identical... But try to re-configure with shared
        +# library support... Aha! Intel compiler "suddenly" lags behind by 30%
        +# [on P4, more on others]:-) And if compared to position-independent
        +# code generated by GNU C, this code performs *more* than *twice* as
        +# fast! Yes, all this buzz about PIC means that unlike other hand-
        +# coded implementations, this one was explicitly designed to be safe
        +# to use even in shared library context... This also means that this
        +# code isn't necessarily absolutely fastest "ever," because in order
        +# to achieve position independence an extra register has to be
        +# off-loaded to stack, which affects the benchmark result.
        +#
        +# Special note about instruction choice. Do you recall RC4_INT code
        +# performing poorly on P4? It might be the time to figure out why.
        +# RC4_INT code implies effective address calculations in base+offset*4
        +# form. Trouble is that it seems that offset scaling turned to be
        +# critical path... At least eliminating scaling resulted in 2.8x RC4
        +# performance improvement [as you might recall]. As AES code is hungry
        +# for scaling too, I [try to] avoid the latter by favoring off-by-2
        +# shifts and masking the result with 0xFF<<2 instead of "boring" 0xFF.
        +#
        +# As was shown by Dean Gaudet <dean@arctic.org>, the above note turned
        +# void. Performance improvement with off-by-2 shifts was observed on
        +# intermediate implementation, which was spilling yet another register
        +# to stack... Final offset*4 code below runs just a tad faster on P4,
        +# but exhibits up to 10% improvement on other cores.
        +#
        +# Second version is "monolithic" replacement for aes_core.c, which in
        +# addition to AES_[de|en]crypt implements private_AES_set_[de|en]cryption_key.
        +# This made it possible to implement little-endian variant of the
        +# algorithm without modifying the base C code. Motivating factor for
        +# the undertaken effort was that it appeared that in tight IA-32
        +# register window little-endian flavor could achieve slightly higher
        +# Instruction Level Parallelism, and it indeed resulted in up to 15%
        +# better performance on most recent µ-archs...
        +#
        +# Third version adds AES_cbc_encrypt implementation, which resulted in
        +# up to 40% performance imrovement of CBC benchmark results. 40% was
        +# observed on P4 core, where "overall" imrovement coefficient, i.e. if
        +# compared to PIC generated by GCC and in CBC mode, was observed to be
        +# as large as 4x:-) CBC performance is virtually identical to ECB now
        +# and on some platforms even better, e.g. 17.6 "small" cycles/byte on
        +# Opteron, because certain function prologues and epilogues are
        +# effectively taken out of the loop...
        +#
        +# Version 3.2 implements compressed tables and prefetch of these tables
        +# in CBC[!] mode. Former means that 3/4 of table references are now
        +# misaligned, which unfortunately has negative impact on elder IA-32
        +# implementations, Pentium suffered 30% penalty, PIII - 10%.
        +#
        +# Version 3.3 avoids L1 cache aliasing between stack frame and
        +# S-boxes, and 3.4 - L1 cache aliasing even between key schedule. The
        +# latter is achieved by copying the key schedule to controlled place in
        +# stack. This unfortunately has rather strong impact on small block CBC
        +# performance, ~2x deterioration on 16-byte block if compared to 3.3.
        +#
        +# Version 3.5 checks if there is L1 cache aliasing between user-supplied
        +# key schedule and S-boxes and abstains from copying the former if
        +# there is no. This allows end-user to consciously retain small block
        +# performance by aligning key schedule in specific manner.
        +#
        +# Version 3.6 compresses Td4 to 256 bytes and prefetches it in ECB.
        +#
        +# Current ECB performance numbers for 128-bit key in CPU cycles per
        +# processed byte [measure commonly used by AES benchmarkers] are:
        +#
        +#		small footprint		fully unrolled
        +# P4		24			22
        +# AMD K8	20			19
        +# PIII		25			23
        +# Pentium	81			78
        +#
        +# Version 3.7 reimplements outer rounds as "compact." Meaning that
        +# first and last rounds reference compact 256 bytes S-box. This means
        +# that first round consumes a lot more CPU cycles and that encrypt
        +# and decrypt performance becomes asymmetric. Encrypt performance
        +# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is
        +# aggressively pre-fetched.
        +#
        +# Version 4.0 effectively rolls back to 3.6 and instead implements
        +# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact,
        +# which use exclusively 256 byte S-box. These functions are to be
        +# called in modes not concealing plain text, such as ECB, or when
        +# we're asked to process smaller amount of data [or unconditionally
        +# on hyper-threading CPU]. Currently it's called unconditionally from
        +# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine
        +# still needs to be modified to switch between slower and faster
        +# mode when appropriate... But in either case benchmark landscape
        +# changes dramatically and below numbers are CPU cycles per processed
        +# byte for 128-bit key.
        +#
        +#		ECB encrypt	ECB decrypt	CBC large chunk
        +# P4		56[60]		84[100]		23
        +# AMD K8	48[44]		70[79]		18
        +# PIII		41[50]		61[91]		24
        +# Core 2	32[38]		45[70]		18.5
        +# Pentium	120		160		77
        +#
        +# Version 4.1 switches to compact S-box even in key schedule setup.
        +#
        +# Version 4.2 prefetches compact S-box in every SSE round or in other
        +# words every cache-line is *guaranteed* to be accessed within ~50
        +# cycles window. Why just SSE? Because it's needed on hyper-threading
        +# CPU! Which is also why it's prefetched with 64 byte stride. Best
        +# part is that it has no negative effect on performance:-)  
        +#
        +# Version 4.3 implements switch between compact and non-compact block
        +# functions in AES_cbc_encrypt depending on how much data was asked
        +# to be processed in one stroke.
        +#
        +######################################################################
        +# Timing attacks are classified in two classes: synchronous when
        +# attacker consciously initiates cryptographic operation and collects
        +# timing data of various character afterwards, and asynchronous when
        +# malicious code is executed on same CPU simultaneously with AES,
        +# instruments itself and performs statistical analysis of this data.
        +#
        +# As far as synchronous attacks go the root to the AES timing
        +# vulnerability is twofold. Firstly, of 256 S-box elements at most 160
        +# are referred to in single 128-bit block operation. Well, in C
        +# implementation with 4 distinct tables it's actually as little as 40
        +# references per 256 elements table, but anyway... Secondly, even
        +# though S-box elements are clustered into smaller amount of cache-
        +# lines, smaller than 160 and even 40, it turned out that for certain
        +# plain-text pattern[s] or simply put chosen plain-text and given key
        +# few cache-lines remain unaccessed during block operation. Now, if
        +# attacker can figure out this access pattern, he can deduct the key
        +# [or at least part of it]. The natural way to mitigate this kind of
        +# attacks is to minimize the amount of cache-lines in S-box and/or
        +# prefetch them to ensure that every one is accessed for more uniform
        +# timing. But note that *if* plain-text was concealed in such way that
        +# input to block function is distributed *uniformly*, then attack
        +# wouldn't apply. Now note that some encryption modes, most notably
        +# CBC, do mask the plain-text in this exact way [secure cipher output
        +# is distributed uniformly]. Yes, one still might find input that
        +# would reveal the information about given key, but if amount of
        +# candidate inputs to be tried is larger than amount of possible key
        +# combinations then attack becomes infeasible. This is why revised
        +# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
        +# of data is to be processed in one stroke. The current size limit of
        +# 512 bytes is chosen to provide same [diminishigly low] probability
        +# for cache-line to remain untouched in large chunk operation with
        +# large S-box as for single block operation with compact S-box and
        +# surely needs more careful consideration...
        +#
        +# As for asynchronous attacks. There are two flavours: attacker code
        +# being interleaved with AES on hyper-threading CPU at *instruction*
        +# level, and two processes time sharing single core. As for latter.
        +# Two vectors. 1. Given that attacker process has higher priority,
        +# yield execution to process performing AES just before timer fires
        +# off the scheduler, immediately regain control of CPU and analyze the
        +# cache state. For this attack to be efficient attacker would have to
        +# effectively slow down the operation by several *orders* of magnitute,
        +# by ratio of time slice to duration of handful of AES rounds, which
        +# unlikely to remain unnoticed. Not to mention that this also means
        +# that he would spend correspondigly more time to collect enough
        +# statistical data to mount the attack. It's probably appropriate to
        +# say that if adeversary reckons that this attack is beneficial and
        +# risks to be noticed, you probably have larger problems having him
        +# mere opportunity. In other words suggested code design expects you
        +# to preclude/mitigate this attack by overall system security design.
        +# 2. Attacker manages to make his code interrupt driven. In order for
        +# this kind of attack to be feasible, interrupt rate has to be high
        +# enough, again comparable to duration of handful of AES rounds. But
        +# is there interrupt source of such rate? Hardly, not even 1Gbps NIC
        +# generates interrupts at such raging rate...
        +#
        +# And now back to the former, hyper-threading CPU or more specifically
        +# Intel P4. Recall that asynchronous attack implies that malicious
        +# code instruments itself. And naturally instrumentation granularity
        +# has be noticeably lower than duration of codepath accessing S-box.
        +# Given that all cache-lines are accessed during that time that is.
        +# Current implementation accesses *all* cache-lines within ~50 cycles
        +# window, which is actually *less* than RDTSC latency on Intel P4!
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"aes-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
        +&static_label("AES_Te");
        +&static_label("AES_Td");
        +
        +$s0="eax";
        +$s1="ebx";
        +$s2="ecx";
        +$s3="edx";
        +$key="edi";
        +$acc="esi";
        +$tbl="ebp";
        +
        +# stack frame layout in _[x86|sse]_AES_* routines, frame is allocated
        +# by caller
        +$__ra=&DWP(0,"esp");	# return address
        +$__s0=&DWP(4,"esp");	# s0 backing store
        +$__s1=&DWP(8,"esp");	# s1 backing store
        +$__s2=&DWP(12,"esp");	# s2 backing store
        +$__s3=&DWP(16,"esp");	# s3 backing store
        +$__key=&DWP(20,"esp");	# pointer to key schedule
        +$__end=&DWP(24,"esp");	# pointer to end of key schedule
        +$__tbl=&DWP(28,"esp");	# %ebp backing store
        +
        +# stack frame layout in AES_[en|crypt] routines, which differs from
        +# above by 4 and overlaps by %ebp backing store
        +$_tbl=&DWP(24,"esp");
        +$_esp=&DWP(28,"esp");
        +
        +sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
        +
        +$speed_limit=512;	# chunks smaller than $speed_limit are
        +			# processed with compact routine in CBC mode
        +$small_footprint=1;	# $small_footprint=1 code is ~5% slower [on
        +			# recent µ-archs], but ~5 times smaller!
        +			# I favor compact code to minimize cache
        +			# contention and in hope to "collect" 5% back
        +			# in real-life applications...
        +
        +$vertical_spin=0;	# shift "verticaly" defaults to 0, because of
        +			# its proof-of-concept status...
        +# Note that there is no decvert(), as well as last encryption round is
        +# performed with "horizontal" shifts. This is because this "vertical"
        +# implementation [one which groups shifts on a given $s[i] to form a
        +# "column," unlike "horizontal" one, which groups shifts on different
        +# $s[i] to form a "row"] is work in progress. It was observed to run
        +# few percents faster on Intel cores, but not AMD. On AMD K8 core it's
        +# whole 12% slower:-( So we face a trade-off... Shall it be resolved
        +# some day? Till then the code is considered experimental and by
        +# default remains dormant...
        +
        +sub encvert()
        +{ my ($te,@s) = @_;
        +  my $v0 = $acc, $v1 = $key;
        +
        +	&mov	($v0,$s[3]);				# copy s3
        +	&mov	(&DWP(4,"esp"),$s[2]);			# save s2
        +	&mov	($v1,$s[0]);				# copy s0
        +	&mov	(&DWP(8,"esp"),$s[1]);			# save s1
        +
        +	&movz	($s[2],&HB($s[0]));
        +	&and	($s[0],0xFF);
        +	&mov	($s[0],&DWP(0,$te,$s[0],8));		# s0>>0
        +	&shr	($v1,16);
        +	&mov	($s[3],&DWP(3,$te,$s[2],8));		# s0>>8
        +	&movz	($s[1],&HB($v1));
        +	&and	($v1,0xFF);
        +	&mov	($s[2],&DWP(2,$te,$v1,8));		# s0>>16
        +	 &mov	($v1,$v0);
        +	&mov	($s[1],&DWP(1,$te,$s[1],8));		# s0>>24
        +
        +	&and	($v0,0xFF);
        +	&xor	($s[3],&DWP(0,$te,$v0,8));		# s3>>0
        +	&movz	($v0,&HB($v1));
        +	&shr	($v1,16);
        +	&xor	($s[2],&DWP(3,$te,$v0,8));		# s3>>8
        +	&movz	($v0,&HB($v1));
        +	&and	($v1,0xFF);
        +	&xor	($s[1],&DWP(2,$te,$v1,8));		# s3>>16
        +	 &mov	($v1,&DWP(4,"esp"));			# restore s2
        +	&xor	($s[0],&DWP(1,$te,$v0,8));		# s3>>24
        +
        +	&mov	($v0,$v1);
        +	&and	($v1,0xFF);
        +	&xor	($s[2],&DWP(0,$te,$v1,8));		# s2>>0
        +	&movz	($v1,&HB($v0));
        +	&shr	($v0,16);
        +	&xor	($s[1],&DWP(3,$te,$v1,8));		# s2>>8
        +	&movz	($v1,&HB($v0));
        +	&and	($v0,0xFF);
        +	&xor	($s[0],&DWP(2,$te,$v0,8));		# s2>>16
        +	 &mov	($v0,&DWP(8,"esp"));			# restore s1
        +	&xor	($s[3],&DWP(1,$te,$v1,8));		# s2>>24
        +
        +	&mov	($v1,$v0);
        +	&and	($v0,0xFF);
        +	&xor	($s[1],&DWP(0,$te,$v0,8));		# s1>>0
        +	&movz	($v0,&HB($v1));
        +	&shr	($v1,16);
        +	&xor	($s[0],&DWP(3,$te,$v0,8));		# s1>>8
        +	&movz	($v0,&HB($v1));
        +	&and	($v1,0xFF);
        +	&xor	($s[3],&DWP(2,$te,$v1,8));		# s1>>16
        +	 &mov	($key,$__key);				# reincarnate v1 as key
        +	&xor	($s[2],&DWP(1,$te,$v0,8));		# s1>>24
        +}
        +
        +# Another experimental routine, which features "horizontal spin," but
        +# eliminates one reference to stack. Strangely enough runs slower...
        +sub enchoriz()
        +{ my $v0 = $key, $v1 = $acc;
        +
        +	&movz	($v0,&LB($s0));			#  3, 2, 1, 0*
        +	&rotr	($s2,8);			#  8,11,10, 9
        +	&mov	($v1,&DWP(0,$te,$v0,8));	#  0
        +	&movz	($v0,&HB($s1));			#  7, 6, 5*, 4
        +	&rotr	($s3,16);			# 13,12,15,14
        +	&xor	($v1,&DWP(3,$te,$v0,8));	#  5
        +	&movz	($v0,&HB($s2));			#  8,11,10*, 9
        +	&rotr	($s0,16);			#  1, 0, 3, 2
        +	&xor	($v1,&DWP(2,$te,$v0,8));	# 10
        +	&movz	($v0,&HB($s3));			# 13,12,15*,14
        +	&xor	($v1,&DWP(1,$te,$v0,8));	# 15, t[0] collected
        +	&mov	($__s0,$v1);			# t[0] saved
        +
        +	&movz	($v0,&LB($s1));			#  7, 6, 5, 4*
        +	&shr	($s1,16);			#  -, -, 7, 6
        +	&mov	($v1,&DWP(0,$te,$v0,8));	#  4
        +	&movz	($v0,&LB($s3));			# 13,12,15,14*
        +	&xor	($v1,&DWP(2,$te,$v0,8));	# 14
        +	&movz	($v0,&HB($s0));			#  1, 0, 3*, 2
        +	&and	($s3,0xffff0000);		# 13,12, -, -
        +	&xor	($v1,&DWP(1,$te,$v0,8));	#  3
        +	&movz	($v0,&LB($s2));			#  8,11,10, 9*
        +	&or	($s3,$s1);			# 13,12, 7, 6
        +	&xor	($v1,&DWP(3,$te,$v0,8));	#  9, t[1] collected
        +	&mov	($s1,$v1);			#  s[1]=t[1]
        +
        +	&movz	($v0,&LB($s0));			#  1, 0, 3, 2*
        +	&shr	($s2,16);			#  -, -, 8,11
        +	&mov	($v1,&DWP(2,$te,$v0,8));	#  2
        +	&movz	($v0,&HB($s3));			# 13,12, 7*, 6
        +	&xor	($v1,&DWP(1,$te,$v0,8));	#  7
        +	&movz	($v0,&HB($s2));			#  -, -, 8*,11
        +	&xor	($v1,&DWP(0,$te,$v0,8));	#  8
        +	&mov	($v0,$s3);
        +	&shr	($v0,24);			# 13
        +	&xor	($v1,&DWP(3,$te,$v0,8));	# 13, t[2] collected
        +
        +	&movz	($v0,&LB($s2));			#  -, -, 8,11*
        +	&shr	($s0,24);			#  1*
        +	&mov	($s2,&DWP(1,$te,$v0,8));	# 11
        +	&xor	($s2,&DWP(3,$te,$s0,8));	#  1
        +	&mov	($s0,$__s0);			# s[0]=t[0]
        +	&movz	($v0,&LB($s3));			# 13,12, 7, 6*
        +	&shr	($s3,16);			#   ,  ,13,12
        +	&xor	($s2,&DWP(2,$te,$v0,8));	#  6
        +	&mov	($key,$__key);			# reincarnate v0 as key
        +	&and	($s3,0xff);			#   ,  ,13,12*
        +	&mov	($s3,&DWP(0,$te,$s3,8));	# 12
        +	&xor	($s3,$s2);			# s[2]=t[3] collected
        +	&mov	($s2,$v1);			# s[2]=t[2]
        +}
        +
        +# More experimental code... SSE one... Even though this one eliminates
        +# *all* references to stack, it's not faster...
        +sub sse_encbody()
        +{
        +	&movz	($acc,&LB("eax"));		#  0
        +	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  0
        +	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
        +	&movz	("edx",&HB("eax"));		#  1
        +	&mov	("edx",&DWP(3,$tbl,"edx",8));	#  1
        +	&shr	("eax",16);			#  5, 4
        +
        +	&movz	($acc,&LB("ebx"));		# 10
        +	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 10
        +	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
        +	&movz	($acc,&HB("ebx"));		# 11
        +	&xor	("edx",&DWP(1,$tbl,$acc,8));	# 11
        +	&shr	("ebx",16);			# 15,14
        +
        +	&movz	($acc,&HB("eax"));		#  5
        +	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  5
        +	&movq	("mm3",QWP(16,$key));
        +	&movz	($acc,&HB("ebx"));		# 15
        +	&xor	("ecx",&DWP(1,$tbl,$acc,8));	# 15
        +	&movd	("mm0","ecx");			# t[0] collected
        +
        +	&movz	($acc,&LB("eax"));		#  4
        +	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  4
        +	&movd	("eax","mm2");			#  7, 6, 3, 2
        +	&movz	($acc,&LB("ebx"));		# 14
        +	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 14
        +	&movd	("ebx","mm6");			# 13,12, 9, 8
        +
        +	&movz	($acc,&HB("eax"));		#  3
        +	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  3
        +	&movz	($acc,&HB("ebx"));		#  9
        +	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  9
        +	&movd	("mm1","ecx");			# t[1] collected
        +
        +	&movz	($acc,&LB("eax"));		#  2
        +	&mov	("ecx",&DWP(2,$tbl,$acc,8));	#  2
        +	&shr	("eax",16);			#  7, 6
        +	&punpckldq	("mm0","mm1");		# t[0,1] collected
        +	&movz	($acc,&LB("ebx"));		#  8
        +	&xor	("ecx",&DWP(0,$tbl,$acc,8));	#  8
        +	&shr	("ebx",16);			# 13,12
        +
        +	&movz	($acc,&HB("eax"));		#  7
        +	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  7
        +	&pxor	("mm0","mm3");
        +	&movz	("eax",&LB("eax"));		#  6
        +	&xor	("edx",&DWP(2,$tbl,"eax",8));	#  6
        +	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
        +	&movz	($acc,&HB("ebx"));		# 13
        +	&xor	("ecx",&DWP(3,$tbl,$acc,8));	# 13
        +	&xor	("ecx",&DWP(24,$key));		# t[2]
        +	&movd	("mm4","ecx");			# t[2] collected
        +	&movz	("ebx",&LB("ebx"));		# 12
        +	&xor	("edx",&DWP(0,$tbl,"ebx",8));	# 12
        +	&shr	("ecx",16);
        +	&movd	("eax","mm1");			#  5, 4, 1, 0
        +	&mov	("ebx",&DWP(28,$key));		# t[3]
        +	&xor	("ebx","edx");
        +	&movd	("mm5","ebx");			# t[3] collected
        +	&and	("ebx",0xffff0000);
        +	&or	("ebx","ecx");
        +
        +	&punpckldq	("mm4","mm5");		# t[2,3] collected
        +}
        +
        +######################################################################
        +# "Compact" block function
        +######################################################################
        +
        +sub enccompact()
        +{ my $Fn = mov;
        +  while ($#_>5) { pop(@_); $Fn=sub{}; }
        +  my ($i,$te,@s)=@_;
        +  my $tmp = $key;
        +  my $out = $i==3?$s[0]:$acc;
        +
        +	# $Fn is used in first compact round and its purpose is to
        +	# void restoration of some values from stack, so that after
        +	# 4xenccompact with extra argument $key value is left there...
        +	if ($i==3)  {	&$Fn	($key,$__key);			}##%edx
        +	else        {	&mov	($out,$s[0]);			}
        +			&and	($out,0xFF);
        +	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
        +	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
        +			&movz	($out,&BP(-128,$te,$out,1));
        +
        +	if ($i==3)  {	$tmp=$s[1];				}##%eax
        +			&movz	($tmp,&HB($s[1]));
        +			&movz	($tmp,&BP(-128,$te,$tmp,1));
        +			&shl	($tmp,8);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
        +	else        {	&mov	($tmp,$s[2]);
        +			&shr	($tmp,16);			}
        +	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
        +			&and	($tmp,0xFF);
        +			&movz	($tmp,&BP(-128,$te,$tmp,1));
        +			&shl	($tmp,16);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
        +	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
        +	else        {	&mov	($tmp,$s[3]);
        +			&shr	($tmp,24);			}
        +			&movz	($tmp,&BP(-128,$te,$tmp,1));
        +			&shl	($tmp,24);
        +			&xor	($out,$tmp);
        +	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
        +	if ($i==3)  {	&mov	($s[3],$acc);			}
        +	&comment();
        +}
        +
        +sub enctransform()
        +{ my @s = ($s0,$s1,$s2,$s3);
        +  my $i = shift;
        +  my $tmp = $tbl;
        +  my $r2  = $key ;
        +
        +	&mov	($acc,$s[$i]);
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($r2,&DWP(0,$s[$i],$s[$i]));
        +	&sub	($acc,$tmp);
        +	&and	($r2,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	&mov	($tmp,$s[$i]);
        +	&xor	($acc,$r2);	# r2
        +
        +	&xor	($s[$i],$acc);	# r0 ^ r2
        +	&rotl	($s[$i],24);
        +	&xor	($s[$i],$acc)	# ROTATE(r2^r0,24) ^ r2
        +	&rotr	($tmp,16);
        +	&xor	($s[$i],$tmp);
        +	&rotr	($tmp,8);
        +	&xor	($s[$i],$tmp);
        +}
        +
        +&function_begin_B("_x86_AES_encrypt_compact");
        +	# note that caller is expected to allocate stack frame for me!
        +	&mov	($__key,$key);			# save key
        +
        +	&xor	($s0,&DWP(0,$key));		# xor with key
        +	&xor	($s1,&DWP(4,$key));
        +	&xor	($s2,&DWP(8,$key));
        +	&xor	($s3,&DWP(12,$key));
        +
        +	&mov	($acc,&DWP(240,$key));		# load key->rounds
        +	&lea	($acc,&DWP(-2,$acc,$acc));
        +	&lea	($acc,&DWP(0,$key,$acc,8));
        +	&mov	($__end,$acc);			# end of key schedule
        +
        +	# prefetch Te4
        +	&mov	($key,&DWP(0-128,$tbl));
        +	&mov	($acc,&DWP(32-128,$tbl));
        +	&mov	($key,&DWP(64-128,$tbl));
        +	&mov	($acc,&DWP(96-128,$tbl));
        +	&mov	($key,&DWP(128-128,$tbl));
        +	&mov	($acc,&DWP(160-128,$tbl));
        +	&mov	($key,&DWP(192-128,$tbl));
        +	&mov	($acc,&DWP(224-128,$tbl));
        +
        +	&set_label("loop",16);
        +
        +		&enccompact(0,$tbl,$s0,$s1,$s2,$s3,1);
        +		&enccompact(1,$tbl,$s1,$s2,$s3,$s0,1);
        +		&enccompact(2,$tbl,$s2,$s3,$s0,$s1,1);
        +		&enccompact(3,$tbl,$s3,$s0,$s1,$s2,1);
        +		&enctransform(2);
        +		&enctransform(3);
        +		&enctransform(0);
        +		&enctransform(1);
        +		&mov 	($key,$__key);
        +		&mov	($tbl,$__tbl);
        +		&add	($key,16);		# advance rd_key
        +		&xor	($s0,&DWP(0,$key));
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +	&cmp	($key,$__end);
        +	&mov	($__key,$key);
        +	&jb	(&label("loop"));
        +
        +	&enccompact(0,$tbl,$s0,$s1,$s2,$s3);
        +	&enccompact(1,$tbl,$s1,$s2,$s3,$s0);
        +	&enccompact(2,$tbl,$s2,$s3,$s0,$s1);
        +	&enccompact(3,$tbl,$s3,$s0,$s1,$s2);
        +
        +	&xor	($s0,&DWP(16,$key));
        +	&xor	($s1,&DWP(20,$key));
        +	&xor	($s2,&DWP(24,$key));
        +	&xor	($s3,&DWP(28,$key));
        +
        +	&ret	();
        +&function_end_B("_x86_AES_encrypt_compact");
        +
        +######################################################################
        +# "Compact" SSE block function.
        +######################################################################
        +#
        +# Performance is not actually extraordinary in comparison to pure
        +# x86 code. In particular encrypt performance is virtually the same.
        +# Decrypt performance on the other hand is 15-20% better on newer
        +# µ-archs [but we're thankful for *any* improvement here], and ~50%
        +# better on PIII:-) And additionally on the pros side this code
        +# eliminates redundant references to stack and thus relieves/
        +# minimizes the pressure on the memory bus.
        +#
        +# MMX register layout                           lsb
        +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        +# |          mm4          |          mm0          |
        +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        +# |     s3    |     s2    |     s1    |     s0    |    
        +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        +# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
        +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        +#
        +# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8.
        +# In this terms encryption and decryption "compact" permutation
        +# matrices can be depicted as following:
        +#
        +# encryption              lsb	# decryption              lsb
        +# +----++----+----+----+----+	# +----++----+----+----+----+
        +# | t0 || 15 | 10 |  5 |  0 |	# | t0 ||  7 | 10 | 13 |  0 |
        +# +----++----+----+----+----+	# +----++----+----+----+----+
        +# | t1 ||  3 | 14 |  9 |  4 |	# | t1 || 11 | 14 |  1 |  4 |
        +# +----++----+----+----+----+	# +----++----+----+----+----+
        +# | t2 ||  7 |  2 | 13 |  8 |	# | t2 || 15 |  2 |  5 |  8 |
        +# +----++----+----+----+----+	# +----++----+----+----+----+
        +# | t3 || 11 |  6 |  1 | 12 |	# | t3 ||  3 |  6 |  9 | 12 |
        +# +----++----+----+----+----+	# +----++----+----+----+----+
        +#
        +######################################################################
        +# Why not xmm registers? Short answer. It was actually tested and
        +# was not any faster, but *contrary*, most notably on Intel CPUs.
        +# Longer answer. Main advantage of using mm registers is that movd
        +# latency is lower, especially on Intel P4. While arithmetic
        +# instructions are twice as many, they can be scheduled every cycle
        +# and not every second one when they are operating on xmm register,
        +# so that "arithmetic throughput" remains virtually the same. And
        +# finally the code can be executed even on elder SSE-only CPUs:-)
        +
        +sub sse_enccompact()
        +{
        +	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
        +	&pshufw	("mm5","mm4",0x0d);		# 15,14,11,10
        +	&movd	("eax","mm1");			#  5, 4, 1, 0
        +	&movd	("ebx","mm5");			# 15,14,11,10
        +
        +	&movz	($acc,&LB("eax"));		#  0
        +	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
        +	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
        +	&movz	("edx",&HB("eax"));		#  1
        +	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
        +	&shl	("edx",8);			#  1
        +	&shr	("eax",16);			#  5, 4
        +
        +	&movz	($acc,&LB("ebx"));		# 10
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 10
        +	&shl	($acc,16);			# 10
        +	&or	("ecx",$acc);			# 10
        +	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
        +	&movz	($acc,&HB("ebx"));		# 11
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 11
        +	&shl	($acc,24);			# 11
        +	&or	("edx",$acc);			# 11
        +	&shr	("ebx",16);			# 15,14
        +
        +	&movz	($acc,&HB("eax"));		#  5
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  5
        +	&shl	($acc,8);			#  5
        +	&or	("ecx",$acc);			#  5
        +	&movz	($acc,&HB("ebx"));		# 15
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 15
        +	&shl	($acc,24);			# 15
        +	&or	("ecx",$acc);			# 15
        +	&movd	("mm0","ecx");			# t[0] collected
        +
        +	&movz	($acc,&LB("eax"));		#  4
        +	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  4
        +	&movd	("eax","mm2");			#  7, 6, 3, 2
        +	&movz	($acc,&LB("ebx"));		# 14
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 14
        +	&shl	($acc,16);			# 14
        +	&or	("ecx",$acc);			# 14
        +
        +	&movd	("ebx","mm6");			# 13,12, 9, 8
        +	&movz	($acc,&HB("eax"));		#  3
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  3
        +	&shl	($acc,24);			#  3
        +	&or	("ecx",$acc);			#  3
        +	&movz	($acc,&HB("ebx"));		#  9
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  9
        +	&shl	($acc,8);			#  9
        +	&or	("ecx",$acc);			#  9
        +	&movd	("mm1","ecx");			# t[1] collected
        +
        +	&movz	($acc,&LB("ebx"));		#  8
        +	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  8
        +	&shr	("ebx",16);			# 13,12
        +	&movz	($acc,&LB("eax"));		#  2
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  2
        +	&shl	($acc,16);			#  2
        +	&or	("ecx",$acc);			#  2
        +	&shr	("eax",16);			#  7, 6
        +
        +	&punpckldq	("mm0","mm1");		# t[0,1] collected
        +
        +	&movz	($acc,&HB("eax"));		#  7
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  7
        +	&shl	($acc,24);			#  7
        +	&or	("ecx",$acc);			#  7
        +	&and	("eax",0xff);			#  6
        +	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  6
        +	&shl	("eax",16);			#  6
        +	&or	("edx","eax");			#  6
        +	&movz	($acc,&HB("ebx"));		# 13
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 13
        +	&shl	($acc,8);			# 13
        +	&or	("ecx",$acc);			# 13
        +	&movd	("mm4","ecx");			# t[2] collected
        +	&and	("ebx",0xff);			# 12
        +	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	# 12
        +	&or	("edx","ebx");			# 12
        +	&movd	("mm5","edx");			# t[3] collected
        +
        +	&punpckldq	("mm4","mm5");		# t[2,3] collected
        +}
        +
        +					if (!$x86only) {
        +&function_begin_B("_sse_AES_encrypt_compact");
        +	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
        +	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
        +
        +	# note that caller is expected to allocate stack frame for me!
        +	&mov	($acc,&DWP(240,$key));		# load key->rounds
        +	&lea	($acc,&DWP(-2,$acc,$acc));
        +	&lea	($acc,&DWP(0,$key,$acc,8));
        +	&mov	($__end,$acc);			# end of key schedule
        +
        +	&mov	($s0,0x1b1b1b1b);		# magic constant
        +	&mov	(&DWP(8,"esp"),$s0);
        +	&mov	(&DWP(12,"esp"),$s0);
        +
        +	# prefetch Te4
        +	&mov	($s0,&DWP(0-128,$tbl));
        +	&mov	($s1,&DWP(32-128,$tbl));
        +	&mov	($s2,&DWP(64-128,$tbl));
        +	&mov	($s3,&DWP(96-128,$tbl));
        +	&mov	($s0,&DWP(128-128,$tbl));
        +	&mov	($s1,&DWP(160-128,$tbl));
        +	&mov	($s2,&DWP(192-128,$tbl));
        +	&mov	($s3,&DWP(224-128,$tbl));
        +
        +	&set_label("loop",16);
        +		&sse_enccompact();
        +		&add	($key,16);
        +		&cmp	($key,$__end);
        +		&ja	(&label("out"));
        +
        +		&movq	("mm2",&QWP(8,"esp"));
        +		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
        +		&movq	("mm1","mm0");		&movq	("mm5","mm4");	# r0
        +		&pcmpgtb("mm3","mm0");		&pcmpgtb("mm7","mm4");
        +		&pand	("mm3","mm2");		&pand	("mm7","mm2");
        +		&pshufw	("mm2","mm0",0xb1);	&pshufw	("mm6","mm4",0xb1);# ROTATE(r0,16)
        +		&paddb	("mm0","mm0");		&paddb	("mm4","mm4");
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# = r2
        +		&pshufw	("mm3","mm2",0xb1);	&pshufw	("mm7","mm6",0xb1);# r0
        +		&pxor	("mm1","mm0");		&pxor	("mm5","mm4");	# r0^r2
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(r0,16)
        +
        +		&movq	("mm2","mm3");		&movq	("mm6","mm7");
        +		&pslld	("mm3",8);		&pslld	("mm7",8);
        +		&psrld	("mm2",24);		&psrld	("mm6",24);
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= r0<<8
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= r0>>24
        +
        +		&movq	("mm3","mm1");		&movq	("mm7","mm5");
        +		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
        +		&psrld	("mm1",8);		&psrld	("mm5",8);
        +		&mov	($s0,&DWP(0-128,$tbl));
        +		&pslld	("mm3",24);		&pslld	("mm7",24);
        +		&mov	($s1,&DWP(64-128,$tbl));
        +		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= (r2^r0)<<8
        +		&mov	($s2,&DWP(128-128,$tbl));
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= (r2^r0)>>24
        +		&mov	($s3,&DWP(192-128,$tbl));
        +
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
        +	&jmp	(&label("loop"));
        +
        +	&set_label("out",16);
        +	&pxor	("mm0",&QWP(0,$key));
        +	&pxor	("mm4",&QWP(8,$key));
        +
        +	&ret	();
        +&function_end_B("_sse_AES_encrypt_compact");
        +					}
        +
        +######################################################################
        +# Vanilla block function.
        +######################################################################
        +
        +sub encstep()
        +{ my ($i,$te,@s) = @_;
        +  my $tmp = $key;
        +  my $out = $i==3?$s[0]:$acc;
        +
        +	# lines marked with #%e?x[i] denote "reordered" instructions...
        +	if ($i==3)  {	&mov	($key,$__key);			}##%edx
        +	else        {	&mov	($out,$s[0]);
        +			&and	($out,0xFF);			}
        +	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
        +	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
        +			&mov	($out,&DWP(0,$te,$out,8));
        +
        +	if ($i==3)  {	$tmp=$s[1];				}##%eax
        +			&movz	($tmp,&HB($s[1]));
        +			&xor	($out,&DWP(3,$te,$tmp,8));
        +
        +	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
        +	else        {	&mov	($tmp,$s[2]);
        +			&shr	($tmp,16);			}
        +	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
        +			&and	($tmp,0xFF);
        +			&xor	($out,&DWP(2,$te,$tmp,8));
        +
        +	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
        +	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
        +	else        {	&mov	($tmp,$s[3]); 
        +			&shr	($tmp,24)			}
        +			&xor	($out,&DWP(1,$te,$tmp,8));
        +	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
        +	if ($i==3)  {	&mov	($s[3],$acc);			}
        +			&comment();
        +}
        +
        +sub enclast()
        +{ my ($i,$te,@s)=@_;
        +  my $tmp = $key;
        +  my $out = $i==3?$s[0]:$acc;
        +
        +	if ($i==3)  {	&mov	($key,$__key);			}##%edx
        +	else        {	&mov	($out,$s[0]);			}
        +			&and	($out,0xFF);
        +	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
        +	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
        +			&mov	($out,&DWP(2,$te,$out,8));
        +			&and	($out,0x000000ff);
        +
        +	if ($i==3)  {	$tmp=$s[1];				}##%eax
        +			&movz	($tmp,&HB($s[1]));
        +			&mov	($tmp,&DWP(0,$te,$tmp,8));
        +			&and	($tmp,0x0000ff00);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
        +	else        {	&mov	($tmp,$s[2]);
        +			&shr	($tmp,16);			}
        +	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
        +			&and	($tmp,0xFF);
        +			&mov	($tmp,&DWP(0,$te,$tmp,8));
        +			&and	($tmp,0x00ff0000);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
        +	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
        +	else        {	&mov	($tmp,$s[3]);
        +			&shr	($tmp,24);			}
        +			&mov	($tmp,&DWP(2,$te,$tmp,8));
        +			&and	($tmp,0xff000000);
        +			&xor	($out,$tmp);
        +	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
        +	if ($i==3)  {	&mov	($s[3],$acc);			}
        +}
        +
        +&function_begin_B("_x86_AES_encrypt");
        +	if ($vertical_spin) {
        +		# I need high parts of volatile registers to be accessible...
        +		&exch	($s1="edi",$key="ebx");
        +		&mov	($s2="esi",$acc="ecx");
        +	}
        +
        +	# note that caller is expected to allocate stack frame for me!
        +	&mov	($__key,$key);			# save key
        +
        +	&xor	($s0,&DWP(0,$key));		# xor with key
        +	&xor	($s1,&DWP(4,$key));
        +	&xor	($s2,&DWP(8,$key));
        +	&xor	($s3,&DWP(12,$key));
        +
        +	&mov	($acc,&DWP(240,$key));		# load key->rounds
        +
        +	if ($small_footprint) {
        +	    &lea	($acc,&DWP(-2,$acc,$acc));
        +	    &lea	($acc,&DWP(0,$key,$acc,8));
        +	    &mov	($__end,$acc);		# end of key schedule
        +
        +	    &set_label("loop",16);
        +		if ($vertical_spin) {
        +		    &encvert($tbl,$s0,$s1,$s2,$s3);
        +		} else {
        +		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
        +		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
        +		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
        +		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
        +		}
        +		&add	($key,16);		# advance rd_key
        +		&xor	($s0,&DWP(0,$key));
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +	    &cmp	($key,$__end);
        +	    &mov	($__key,$key);
        +	    &jb		(&label("loop"));
        +	}
        +	else {
        +	    &cmp	($acc,10);
        +	    &jle	(&label("10rounds"));
        +	    &cmp	($acc,12);
        +	    &jle	(&label("12rounds"));
        +
        +	&set_label("14rounds",4);
        +	    for ($i=1;$i<3;$i++) {
        +		if ($vertical_spin) {
        +		    &encvert($tbl,$s0,$s1,$s2,$s3);
        +		} else {
        +		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
        +		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
        +		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
        +		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
        +		}
        +		&xor	($s0,&DWP(16*$i+0,$key));
        +		&xor	($s1,&DWP(16*$i+4,$key));
        +		&xor	($s2,&DWP(16*$i+8,$key));
        +		&xor	($s3,&DWP(16*$i+12,$key));
        +	    }
        +	    &add	($key,32);
        +	    &mov	($__key,$key);		# advance rd_key
        +	&set_label("12rounds",4);
        +	    for ($i=1;$i<3;$i++) {
        +		if ($vertical_spin) {
        +		    &encvert($tbl,$s0,$s1,$s2,$s3);
        +		} else {
        +		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
        +		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
        +		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
        +		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
        +		}
        +		&xor	($s0,&DWP(16*$i+0,$key));
        +		&xor	($s1,&DWP(16*$i+4,$key));
        +		&xor	($s2,&DWP(16*$i+8,$key));
        +		&xor	($s3,&DWP(16*$i+12,$key));
        +	    }
        +	    &add	($key,32);
        +	    &mov	($__key,$key);		# advance rd_key
        +	&set_label("10rounds",4);
        +	    for ($i=1;$i<10;$i++) {
        +		if ($vertical_spin) {
        +		    &encvert($tbl,$s0,$s1,$s2,$s3);
        +		} else {
        +		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
        +		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
        +		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
        +		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
        +		}
        +		&xor	($s0,&DWP(16*$i+0,$key));
        +		&xor	($s1,&DWP(16*$i+4,$key));
        +		&xor	($s2,&DWP(16*$i+8,$key));
        +		&xor	($s3,&DWP(16*$i+12,$key));
        +	    }
        +	}
        +
        +	if ($vertical_spin) {
        +	    # "reincarnate" some registers for "horizontal" spin...
        +	    &mov	($s1="ebx",$key="edi");
        +	    &mov	($s2="ecx",$acc="esi");
        +	}
        +	&enclast(0,$tbl,$s0,$s1,$s2,$s3);
        +	&enclast(1,$tbl,$s1,$s2,$s3,$s0);
        +	&enclast(2,$tbl,$s2,$s3,$s0,$s1);
        +	&enclast(3,$tbl,$s3,$s0,$s1,$s2);
        +
        +	&add	($key,$small_footprint?16:160);
        +	&xor	($s0,&DWP(0,$key));
        +	&xor	($s1,&DWP(4,$key));
        +	&xor	($s2,&DWP(8,$key));
        +	&xor	($s3,&DWP(12,$key));
        +
        +	&ret	();
        +
        +&set_label("AES_Te",64);	# Yes! I keep it in the code segment!
        +	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
        +	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
        +	&_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
        +	&_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
        +	&_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
        +	&_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
        +	&_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
        +	&_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
        +	&_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
        +	&_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
        +	&_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
        +	&_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
        +	&_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
        +	&_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
        +	&_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
        +	&_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
        +	&_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
        +	&_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
        +	&_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
        +	&_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
        +	&_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
        +	&_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
        +	&_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
        +	&_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
        +	&_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
        +	&_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
        +	&_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
        +	&_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
        +	&_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
        +	&_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
        +	&_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
        +	&_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
        +	&_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
        +	&_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
        +	&_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
        +	&_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
        +	&_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
        +	&_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
        +	&_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
        +	&_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
        +	&_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
        +	&_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
        +	&_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
        +	&_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
        +	&_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
        +	&_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
        +	&_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
        +	&_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
        +	&_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
        +	&_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
        +	&_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
        +	&_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
        +	&_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
        +	&_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
        +	&_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
        +	&_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
        +	&_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
        +	&_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
        +	&_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
        +	&_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
        +	&_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
        +	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
        +	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
        +	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
        +
        +#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +#rcon:
        +	&data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
        +	&data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
        +	&data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000);
        +	&data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
        +&function_end_B("_x86_AES_encrypt");
        +
        +# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
        +&function_begin("AES_encrypt");
        +	&mov	($acc,&wparam(0));		# load inp
        +	&mov	($key,&wparam(2));		# load key
        +
        +	&mov	($s0,"esp");
        +	&sub	("esp",36);
        +	&and	("esp",-64);			# align to cache-line
        +
        +	# place stack frame just "above" the key schedule
        +	&lea	($s1,&DWP(-64-63,$key));
        +	&sub	($s1,"esp");
        +	&neg	($s1);
        +	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	("esp",$s1);
        +	&add	("esp",4);	# 4 is reserved for caller's return address
        +	&mov	($_esp,$s0);			# save stack pointer
        +
        +	&call   (&label("pic_point"));          # make it PIC!
        +	&set_label("pic_point");
        +	&blindpop($tbl);
        +	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only);
        +	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
        +
        +	# pick Te4 copy which can't "overlap" with stack frame or key schedule
        +	&lea	($s1,&DWP(768-4,"esp"));
        +	&sub	($s1,$tbl);
        +	&and	($s1,0x300);
        +	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
        +
        +					if (!$x86only) {
        +	&bt	(&DWP(0,$s0),25);	# check for SSE bit
        +	&jnc	(&label("x86"));
        +
        +	&movq	("mm0",&QWP(0,$acc));
        +	&movq	("mm4",&QWP(8,$acc));
        +	&call	("_sse_AES_encrypt_compact");
        +	&mov	("esp",$_esp);			# restore stack pointer
        +	&mov	($acc,&wparam(1));		# load out
        +	&movq	(&QWP(0,$acc),"mm0");		# write output data
        +	&movq	(&QWP(8,$acc),"mm4");
        +	&emms	();
        +	&function_end_A();
        +					}
        +	&set_label("x86",16);
        +	&mov	($_tbl,$tbl);
        +	&mov	($s0,&DWP(0,$acc));		# load input data
        +	&mov	($s1,&DWP(4,$acc));
        +	&mov	($s2,&DWP(8,$acc));
        +	&mov	($s3,&DWP(12,$acc));
        +	&call	("_x86_AES_encrypt_compact");
        +	&mov	("esp",$_esp);			# restore stack pointer
        +	&mov	($acc,&wparam(1));		# load out
        +	&mov	(&DWP(0,$acc),$s0);		# write output data
        +	&mov	(&DWP(4,$acc),$s1);
        +	&mov	(&DWP(8,$acc),$s2);
        +	&mov	(&DWP(12,$acc),$s3);
        +&function_end("AES_encrypt");
        +
        +#--------------------------------------------------------------------#
        +
        +######################################################################
        +# "Compact" block function
        +######################################################################
        +
        +sub deccompact()
        +{ my $Fn = mov;
        +  while ($#_>5) { pop(@_); $Fn=sub{}; }
        +  my ($i,$td,@s)=@_;
        +  my $tmp = $key;
        +  my $out = $i==3?$s[0]:$acc;
        +
        +	# $Fn is used in first compact round and its purpose is to
        +	# void restoration of some values from stack, so that after
        +	# 4xdeccompact with extra argument $key, $s0 and $s1 values
        +	# are left there...
        +	if($i==3)   {	&$Fn	($key,$__key);			}
        +	else        {	&mov	($out,$s[0]);			}
        +			&and	($out,0xFF);
        +			&movz	($out,&BP(-128,$td,$out,1));
        +
        +	if ($i==3)  {	$tmp=$s[1];				}
        +			&movz	($tmp,&HB($s[1]));
        +			&movz	($tmp,&BP(-128,$td,$tmp,1));
        +			&shl	($tmp,8);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
        +	else        {	mov	($tmp,$s[2]);			}
        +			&shr	($tmp,16);
        +			&and	($tmp,0xFF);
        +			&movz	($tmp,&BP(-128,$td,$tmp,1));
        +			&shl	($tmp,16);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[3]; &$Fn ($s[2],$__s1);		}
        +	else        {	&mov	($tmp,$s[3]);			}
        +			&shr	($tmp,24);
        +			&movz	($tmp,&BP(-128,$td,$tmp,1));
        +			&shl	($tmp,24);
        +			&xor	($out,$tmp);
        +	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
        +	if ($i==3)  {	&$Fn	($s[3],$__s0);			}
        +}
        +
        +# must be called with 2,3,0,1 as argument sequence!!!
        +sub dectransform()
        +{ my @s = ($s0,$s1,$s2,$s3);
        +  my $i = shift;
        +  my $tmp = $key;
        +  my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1);
        +  my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1);
        +  my $tp8 = $tbl;
        +
        +	&mov	($acc,$s[$i]);
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($tp2,&DWP(0,$s[$i],$s[$i]));
        +	&sub	($acc,$tmp);
        +	&and	($tp2,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	&xor	($acc,$tp2);
        +	&mov	($tp2,$acc);
        +
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($tp4,&DWP(0,$tp2,$tp2));
        +	&sub	($acc,$tmp);
        +	&and	($tp4,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	 &xor	($tp2,$s[$i]);	# tp2^tp1
        +	&xor	($acc,$tp4);
        +	&mov	($tp4,$acc);
        +
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($tp8,&DWP(0,$tp4,$tp4));
        +	&sub	($acc,$tmp);
        +	&and	($tp8,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	 &xor	($tp4,$s[$i]);	# tp4^tp1
        +	 &rotl	($s[$i],8);	# = ROTATE(tp1,8)
        +	&xor	($tp8,$acc);
        +
        +	&xor	($s[$i],$tp2);
        +	&xor	($tp2,$tp8);
        +	&rotl	($tp2,24);
        +	&xor	($s[$i],$tp4);
        +	&xor	($tp4,$tp8);
        +	&rotl	($tp4,16);
        +	&xor	($s[$i],$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
        +	&rotl	($tp8,8);
        +	&xor	($s[$i],$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
        +	&xor	($s[$i],$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
        +	 &mov	($s[0],$__s0)			if($i==2); #prefetch $s0
        +	 &mov	($s[1],$__s1)			if($i==3); #prefetch $s1
        +	 &mov	($s[2],$__s2)			if($i==1);
        +	&xor	($s[$i],$tp8);	# ^= ROTATE(tp8,8)
        +
        +	&mov	($s[3],$__s3)			if($i==1);
        +	&mov	(&DWP(4+4*$i,"esp"),$s[$i])	if($i>=2);
        +}
        +
        +&function_begin_B("_x86_AES_decrypt_compact");
        +	# note that caller is expected to allocate stack frame for me!
        +	&mov	($__key,$key);			# save key
        +
        +	&xor	($s0,&DWP(0,$key));		# xor with key
        +	&xor	($s1,&DWP(4,$key));
        +	&xor	($s2,&DWP(8,$key));
        +	&xor	($s3,&DWP(12,$key));
        +
        +	&mov	($acc,&DWP(240,$key));		# load key->rounds
        +
        +	&lea	($acc,&DWP(-2,$acc,$acc));
        +	&lea	($acc,&DWP(0,$key,$acc,8));
        +	&mov	($__end,$acc);			# end of key schedule
        +
        +	# prefetch Td4
        +	&mov	($key,&DWP(0-128,$tbl));
        +	&mov	($acc,&DWP(32-128,$tbl));
        +	&mov	($key,&DWP(64-128,$tbl));
        +	&mov	($acc,&DWP(96-128,$tbl));
        +	&mov	($key,&DWP(128-128,$tbl));
        +	&mov	($acc,&DWP(160-128,$tbl));
        +	&mov	($key,&DWP(192-128,$tbl));
        +	&mov	($acc,&DWP(224-128,$tbl));
        +
        +	&set_label("loop",16);
        +
        +		&deccompact(0,$tbl,$s0,$s3,$s2,$s1,1);
        +		&deccompact(1,$tbl,$s1,$s0,$s3,$s2,1);
        +		&deccompact(2,$tbl,$s2,$s1,$s0,$s3,1);
        +		&deccompact(3,$tbl,$s3,$s2,$s1,$s0,1);
        +		&dectransform(2);
        +		&dectransform(3);
        +		&dectransform(0);
        +		&dectransform(1);
        +		&mov 	($key,$__key);
        +		&mov	($tbl,$__tbl);
        +		&add	($key,16);		# advance rd_key
        +		&xor	($s0,&DWP(0,$key));
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +	&cmp	($key,$__end);
        +	&mov	($__key,$key);
        +	&jb	(&label("loop"));
        +
        +	&deccompact(0,$tbl,$s0,$s3,$s2,$s1);
        +	&deccompact(1,$tbl,$s1,$s0,$s3,$s2);
        +	&deccompact(2,$tbl,$s2,$s1,$s0,$s3);
        +	&deccompact(3,$tbl,$s3,$s2,$s1,$s0);
        +
        +	&xor	($s0,&DWP(16,$key));
        +	&xor	($s1,&DWP(20,$key));
        +	&xor	($s2,&DWP(24,$key));
        +	&xor	($s3,&DWP(28,$key));
        +
        +	&ret	();
        +&function_end_B("_x86_AES_decrypt_compact");
        +
        +######################################################################
        +# "Compact" SSE block function.
        +######################################################################
        +
        +sub sse_deccompact()
        +{
        +	&pshufw	("mm1","mm0",0x0c);		#  7, 6, 1, 0
        +	&movd	("eax","mm1");			#  7, 6, 1, 0
        +
        +	&pshufw	("mm5","mm4",0x09);		# 13,12,11,10
        +	&movz	($acc,&LB("eax"));		#  0
        +	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
        +	&movd	("ebx","mm5");			# 13,12,11,10
        +	&movz	("edx",&HB("eax"));		#  1
        +	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
        +	&shl	("edx",8);			#  1
        +
        +	&pshufw	("mm2","mm0",0x06);		#  3, 2, 5, 4
        +	&movz	($acc,&LB("ebx"));		# 10
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 10
        +	&shl	($acc,16);			# 10
        +	&or	("ecx",$acc);			# 10
        +	&shr	("eax",16);			#  7, 6
        +	&movz	($acc,&HB("ebx"));		# 11
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 11
        +	&shl	($acc,24);			# 11
        +	&or	("edx",$acc);			# 11
        +	&shr	("ebx",16);			# 13,12
        +
        +	&pshufw	("mm6","mm4",0x03);		# 9, 8,15,14
        +	&movz	($acc,&HB("eax"));		#  7
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  7
        +	&shl	($acc,24);			#  7
        +	&or	("ecx",$acc);			#  7
        +	&movz	($acc,&HB("ebx"));		# 13
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 13
        +	&shl	($acc,8);			# 13
        +	&or	("ecx",$acc);			# 13
        +	&movd	("mm0","ecx");			# t[0] collected
        +
        +	&movz	($acc,&LB("eax"));		#  6
        +	&movd	("eax","mm2");			#  3, 2, 5, 4
        +	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  6
        +	&shl	("ecx",16);			#  6
        +	&movz	($acc,&LB("ebx"));		# 12
        +	&movd	("ebx","mm6");			#  9, 8,15,14
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 12
        +	&or	("ecx",$acc);			# 12
        +
        +	&movz	($acc,&LB("eax"));		#  4
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  4
        +	&or	("edx",$acc);			#  4
        +	&movz	($acc,&LB("ebx"));		# 14
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 14
        +	&shl	($acc,16);			# 14
        +	&or	("edx",$acc);			# 14
        +	&movd	("mm1","edx");			# t[1] collected
        +
        +	&movz	($acc,&HB("eax"));		#  5
        +	&movz	("edx",&BP(-128,$tbl,$acc,1));	#  5
        +	&shl	("edx",8);			#  5
        +	&movz	($acc,&HB("ebx"));		# 15
        +	&shr	("eax",16);			#  3, 2
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 15
        +	&shl	($acc,24);			# 15
        +	&or	("edx",$acc);			# 15
        +	&shr	("ebx",16);			#  9, 8
        +
        +	&punpckldq	("mm0","mm1");		# t[0,1] collected
        +
        +	&movz	($acc,&HB("ebx"));		#  9
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  9
        +	&shl	($acc,8);			#  9
        +	&or	("ecx",$acc);			#  9
        +	&and	("ebx",0xff);			#  8
        +	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	#  8
        +	&or	("edx","ebx");			#  8
        +	&movz	($acc,&LB("eax"));		#  2
        +	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  2
        +	&shl	($acc,16);			#  2
        +	&or	("edx",$acc);			#  2
        +	&movd	("mm4","edx");			# t[2] collected
        +	&movz	("eax",&HB("eax"));		#  3
        +	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  3
        +	&shl	("eax",24);			#  3
        +	&or	("ecx","eax");			#  3
        +	&movd	("mm5","ecx");			# t[3] collected
        +
        +	&punpckldq	("mm4","mm5");		# t[2,3] collected
        +}
        +
        +					if (!$x86only) {
        +&function_begin_B("_sse_AES_decrypt_compact");
        +	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
        +	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
        +
        +	# note that caller is expected to allocate stack frame for me!
        +	&mov	($acc,&DWP(240,$key));		# load key->rounds
        +	&lea	($acc,&DWP(-2,$acc,$acc));
        +	&lea	($acc,&DWP(0,$key,$acc,8));
        +	&mov	($__end,$acc);			# end of key schedule
        +
        +	&mov	($s0,0x1b1b1b1b);		# magic constant
        +	&mov	(&DWP(8,"esp"),$s0);
        +	&mov	(&DWP(12,"esp"),$s0);
        +
        +	# prefetch Td4
        +	&mov	($s0,&DWP(0-128,$tbl));
        +	&mov	($s1,&DWP(32-128,$tbl));
        +	&mov	($s2,&DWP(64-128,$tbl));
        +	&mov	($s3,&DWP(96-128,$tbl));
        +	&mov	($s0,&DWP(128-128,$tbl));
        +	&mov	($s1,&DWP(160-128,$tbl));
        +	&mov	($s2,&DWP(192-128,$tbl));
        +	&mov	($s3,&DWP(224-128,$tbl));
        +
        +	&set_label("loop",16);
        +		&sse_deccompact();
        +		&add	($key,16);
        +		&cmp	($key,$__end);
        +		&ja	(&label("out"));
        +
        +		# ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N)
        +		&movq	("mm3","mm0");		&movq	("mm7","mm4");
        +		&movq	("mm2","mm0",1);	&movq	("mm6","mm4",1);
        +		&movq	("mm1","mm0");		&movq	("mm5","mm4");
        +		&pshufw	("mm0","mm0",0xb1);	&pshufw	("mm4","mm4",0xb1);# = ROTATE(tp0,16)
        +		&pslld	("mm2",8);		&pslld	("mm6",8);
        +		&psrld	("mm3",8);		&psrld	("mm7",8);
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<8
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>8
        +		&pslld	("mm2",16);		&pslld	("mm6",16);
        +		&psrld	("mm3",16);		&psrld	("mm7",16);
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<24
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>24
        +
        +		&movq	("mm3",&QWP(8,"esp"));
        +		&pxor	("mm2","mm2");		&pxor	("mm6","mm6");
        +		&pcmpgtb("mm2","mm1");		&pcmpgtb("mm6","mm5");
        +		&pand	("mm2","mm3");		&pand	("mm6","mm3");
        +		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
        +		&pxor	("mm1","mm2");		&pxor	("mm5","mm6");	# tp2
        +		&movq	("mm3","mm1");		&movq	("mm7","mm5");
        +		&movq	("mm2","mm1");		&movq	("mm6","mm5");
        +		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp2
        +		&pslld	("mm3",24);		&pslld	("mm7",24);
        +		&psrld	("mm2",8);		&psrld	("mm6",8);
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp2<<24
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp2>>8
        +
        +		&movq	("mm2",&QWP(8,"esp"));
        +		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
        +		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
        +		&pand	("mm3","mm2");		&pand	("mm7","mm2");
        +		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
        +		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp4
        +		&pshufw	("mm3","mm1",0xb1);	&pshufw	("mm7","mm5",0xb1);
        +		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp4
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= ROTATE(tp4,16)	
        +
        +		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
        +		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
        +		&pand	("mm3","mm2");		&pand	("mm7","mm2");
        +		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
        +		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp8
        +		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8
        +		&movq	("mm3","mm1");		&movq	("mm7","mm5");
        +		&pshufw	("mm2","mm1",0xb1);	&pshufw	("mm6","mm5",0xb1);
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(tp8,16)
        +		&pslld	("mm1",8);		&pslld	("mm5",8);
        +		&psrld	("mm3",8);		&psrld	("mm7",8);
        +		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
        +		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<8
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>8
        +		&mov	($s0,&DWP(0-128,$tbl));
        +		&pslld	("mm1",16);		&pslld	("mm5",16);
        +		&mov	($s1,&DWP(64-128,$tbl));
        +		&psrld	("mm3",16);		&psrld	("mm7",16);
        +		&mov	($s2,&DWP(128-128,$tbl));
        +		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<24
        +		&mov	($s3,&DWP(192-128,$tbl));
        +		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>24
        +
        +		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
        +	&jmp	(&label("loop"));
        +
        +	&set_label("out",16);
        +	&pxor	("mm0",&QWP(0,$key));
        +	&pxor	("mm4",&QWP(8,$key));
        +
        +	&ret	();
        +&function_end_B("_sse_AES_decrypt_compact");
        +					}
        +
        +######################################################################
        +# Vanilla block function.
        +######################################################################
        +
        +sub decstep()
        +{ my ($i,$td,@s) = @_;
        +  my $tmp = $key;
        +  my $out = $i==3?$s[0]:$acc;
        +
        +	# no instructions are reordered, as performance appears
        +	# optimal... or rather that all attempts to reorder didn't
        +	# result in better performance [which by the way is not a
        +	# bit lower than ecryption].
        +	if($i==3)   {	&mov	($key,$__key);			}
        +	else        {	&mov	($out,$s[0]);			}
        +			&and	($out,0xFF);
        +			&mov	($out,&DWP(0,$td,$out,8));
        +
        +	if ($i==3)  {	$tmp=$s[1];				}
        +			&movz	($tmp,&HB($s[1]));
        +			&xor	($out,&DWP(3,$td,$tmp,8));
        +
        +	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
        +	else        {	&mov	($tmp,$s[2]);			}
        +			&shr	($tmp,16);
        +			&and	($tmp,0xFF);
        +			&xor	($out,&DWP(2,$td,$tmp,8));
        +
        +	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
        +	else        {	&mov	($tmp,$s[3]);			}
        +			&shr	($tmp,24);
        +			&xor	($out,&DWP(1,$td,$tmp,8));
        +	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
        +	if ($i==3)  {	&mov	($s[3],$__s0);			}
        +			&comment();
        +}
        +
        +sub declast()
        +{ my ($i,$td,@s)=@_;
        +  my $tmp = $key;
        +  my $out = $i==3?$s[0]:$acc;
        +
        +	if($i==0)   {	&lea	($td,&DWP(2048+128,$td));
        +			&mov	($tmp,&DWP(0-128,$td));
        +			&mov	($acc,&DWP(32-128,$td));
        +			&mov	($tmp,&DWP(64-128,$td));
        +			&mov	($acc,&DWP(96-128,$td));
        +			&mov	($tmp,&DWP(128-128,$td));
        +			&mov	($acc,&DWP(160-128,$td));
        +			&mov	($tmp,&DWP(192-128,$td));
        +			&mov	($acc,&DWP(224-128,$td));
        +			&lea	($td,&DWP(-128,$td));		}
        +	if($i==3)   {	&mov	($key,$__key);			}
        +	else        {	&mov	($out,$s[0]);			}
        +			&and	($out,0xFF);
        +			&movz	($out,&BP(0,$td,$out,1));
        +
        +	if ($i==3)  {	$tmp=$s[1];				}
        +			&movz	($tmp,&HB($s[1]));
        +			&movz	($tmp,&BP(0,$td,$tmp,1));
        +			&shl	($tmp,8);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
        +	else        {	mov	($tmp,$s[2]);			}
        +			&shr	($tmp,16);
        +			&and	($tmp,0xFF);
        +			&movz	($tmp,&BP(0,$td,$tmp,1));
        +			&shl	($tmp,16);
        +			&xor	($out,$tmp);
        +
        +	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
        +	else        {	&mov	($tmp,$s[3]);			}
        +			&shr	($tmp,24);
        +			&movz	($tmp,&BP(0,$td,$tmp,1));
        +			&shl	($tmp,24);
        +			&xor	($out,$tmp);
        +	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
        +	if ($i==3)  {	&mov	($s[3],$__s0);
        +			&lea	($td,&DWP(-2048,$td));		}
        +}
        +
        +&function_begin_B("_x86_AES_decrypt");
        +	# note that caller is expected to allocate stack frame for me!
        +	&mov	($__key,$key);			# save key
        +
        +	&xor	($s0,&DWP(0,$key));		# xor with key
        +	&xor	($s1,&DWP(4,$key));
        +	&xor	($s2,&DWP(8,$key));
        +	&xor	($s3,&DWP(12,$key));
        +
        +	&mov	($acc,&DWP(240,$key));		# load key->rounds
        +
        +	if ($small_footprint) {
        +	    &lea	($acc,&DWP(-2,$acc,$acc));
        +	    &lea	($acc,&DWP(0,$key,$acc,8));
        +	    &mov	($__end,$acc);		# end of key schedule
        +	    &set_label("loop",16);
        +		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
        +		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
        +		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
        +		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
        +		&add	($key,16);		# advance rd_key
        +		&xor	($s0,&DWP(0,$key));
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +	    &cmp	($key,$__end);
        +	    &mov	($__key,$key);
        +	    &jb		(&label("loop"));
        +	}
        +	else {
        +	    &cmp	($acc,10);
        +	    &jle	(&label("10rounds"));
        +	    &cmp	($acc,12);
        +	    &jle	(&label("12rounds"));
        +
        +	&set_label("14rounds",4);
        +	    for ($i=1;$i<3;$i++) {
        +		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
        +		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
        +		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
        +		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
        +		&xor	($s0,&DWP(16*$i+0,$key));
        +		&xor	($s1,&DWP(16*$i+4,$key));
        +		&xor	($s2,&DWP(16*$i+8,$key));
        +		&xor	($s3,&DWP(16*$i+12,$key));
        +	    }
        +	    &add	($key,32);
        +	    &mov	($__key,$key);		# advance rd_key
        +	&set_label("12rounds",4);
        +	    for ($i=1;$i<3;$i++) {
        +		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
        +		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
        +		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
        +		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
        +		&xor	($s0,&DWP(16*$i+0,$key));
        +		&xor	($s1,&DWP(16*$i+4,$key));
        +		&xor	($s2,&DWP(16*$i+8,$key));
        +		&xor	($s3,&DWP(16*$i+12,$key));
        +	    }
        +	    &add	($key,32);
        +	    &mov	($__key,$key);		# advance rd_key
        +	&set_label("10rounds",4);
        +	    for ($i=1;$i<10;$i++) {
        +		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
        +		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
        +		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
        +		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
        +		&xor	($s0,&DWP(16*$i+0,$key));
        +		&xor	($s1,&DWP(16*$i+4,$key));
        +		&xor	($s2,&DWP(16*$i+8,$key));
        +		&xor	($s3,&DWP(16*$i+12,$key));
        +	    }
        +	}
        +
        +	&declast(0,$tbl,$s0,$s3,$s2,$s1);
        +	&declast(1,$tbl,$s1,$s0,$s3,$s2);
        +	&declast(2,$tbl,$s2,$s1,$s0,$s3);
        +	&declast(3,$tbl,$s3,$s2,$s1,$s0);
        +
        +	&add	($key,$small_footprint?16:160);
        +	&xor	($s0,&DWP(0,$key));
        +	&xor	($s1,&DWP(4,$key));
        +	&xor	($s2,&DWP(8,$key));
        +	&xor	($s3,&DWP(12,$key));
        +
        +	&ret	();
        +
        +&set_label("AES_Td",64);	# Yes! I keep it in the code segment!
        +	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
        +	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
        +	&_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
        +	&_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
        +	&_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
        +	&_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
        +	&_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
        +	&_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
        +	&_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
        +	&_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
        +	&_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
        +	&_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
        +	&_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
        +	&_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
        +	&_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
        +	&_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
        +	&_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
        +	&_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
        +	&_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
        +	&_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
        +	&_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
        +	&_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
        +	&_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
        +	&_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
        +	&_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
        +	&_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
        +	&_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
        +	&_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
        +	&_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
        +	&_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
        +	&_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
        +	&_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
        +	&_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
        +	&_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
        +	&_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
        +	&_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
        +	&_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
        +	&_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
        +	&_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
        +	&_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
        +	&_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
        +	&_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
        +	&_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
        +	&_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
        +	&_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
        +	&_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
        +	&_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
        +	&_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
        +	&_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
        +	&_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
        +	&_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
        +	&_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
        +	&_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
        +	&_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
        +	&_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
        +	&_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
        +	&_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
        +	&_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
        +	&_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
        +	&_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
        +	&_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
        +	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
        +	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
        +	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
        +
        +#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +&function_end_B("_x86_AES_decrypt");
        +
        +# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
        +&function_begin("AES_decrypt");
        +	&mov	($acc,&wparam(0));		# load inp
        +	&mov	($key,&wparam(2));		# load key
        +
        +	&mov	($s0,"esp");
        +	&sub	("esp",36);
        +	&and	("esp",-64);			# align to cache-line
        +
        +	# place stack frame just "above" the key schedule
        +	&lea	($s1,&DWP(-64-63,$key));
        +	&sub	($s1,"esp");
        +	&neg	($s1);
        +	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	("esp",$s1);
        +	&add	("esp",4);	# 4 is reserved for caller's return address
        +	&mov	($_esp,$s0);	# save stack pointer
        +
        +	&call   (&label("pic_point"));          # make it PIC!
        +	&set_label("pic_point");
        +	&blindpop($tbl);
        +	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
        +	&lea    ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl));
        +
        +	# pick Td4 copy which can't "overlap" with stack frame or key schedule
        +	&lea	($s1,&DWP(768-4,"esp"));
        +	&sub	($s1,$tbl);
        +	&and	($s1,0x300);
        +	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
        +
        +					if (!$x86only) {
        +	&bt	(&DWP(0,$s0),25);	# check for SSE bit
        +	&jnc	(&label("x86"));
        +
        +	&movq	("mm0",&QWP(0,$acc));
        +	&movq	("mm4",&QWP(8,$acc));
        +	&call	("_sse_AES_decrypt_compact");
        +	&mov	("esp",$_esp);			# restore stack pointer
        +	&mov	($acc,&wparam(1));		# load out
        +	&movq	(&QWP(0,$acc),"mm0");		# write output data
        +	&movq	(&QWP(8,$acc),"mm4");
        +	&emms	();
        +	&function_end_A();
        +					}
        +	&set_label("x86",16);
        +	&mov	($_tbl,$tbl);
        +	&mov	($s0,&DWP(0,$acc));		# load input data
        +	&mov	($s1,&DWP(4,$acc));
        +	&mov	($s2,&DWP(8,$acc));
        +	&mov	($s3,&DWP(12,$acc));
        +	&call	("_x86_AES_decrypt_compact");
        +	&mov	("esp",$_esp);			# restore stack pointer
        +	&mov	($acc,&wparam(1));		# load out
        +	&mov	(&DWP(0,$acc),$s0);		# write output data
        +	&mov	(&DWP(4,$acc),$s1);
        +	&mov	(&DWP(8,$acc),$s2);
        +	&mov	(&DWP(12,$acc),$s3);
        +&function_end("AES_decrypt");
        +
        +# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
        +#			size_t length, const AES_KEY *key,
        +#			unsigned char *ivp,const int enc);
        +{
        +# stack frame layout
        +#             -4(%esp)		# return address	 0(%esp)
        +#              0(%esp)		# s0 backing store	 4(%esp)	
        +#              4(%esp)		# s1 backing store	 8(%esp)
        +#              8(%esp)		# s2 backing store	12(%esp)
        +#             12(%esp)		# s3 backing store	16(%esp)
        +#             16(%esp)		# key backup		20(%esp)
        +#             20(%esp)		# end of key schedule	24(%esp)
        +#             24(%esp)		# %ebp backup		28(%esp)
        +#             28(%esp)		# %esp backup
        +my $_inp=&DWP(32,"esp");	# copy of wparam(0)
        +my $_out=&DWP(36,"esp");	# copy of wparam(1)
        +my $_len=&DWP(40,"esp");	# copy of wparam(2)
        +my $_key=&DWP(44,"esp");	# copy of wparam(3)
        +my $_ivp=&DWP(48,"esp");	# copy of wparam(4)
        +my $_tmp=&DWP(52,"esp");	# volatile variable
        +#
        +my $ivec=&DWP(60,"esp");	# ivec[16]
        +my $aes_key=&DWP(76,"esp");	# copy of aes_key
        +my $mark=&DWP(76+240,"esp");	# copy of aes_key->rounds
        +
        +&function_begin("AES_cbc_encrypt");
        +	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
        +	&cmp	($s2,0);
        +	&je	(&label("drop_out"));
        +
        +	&call   (&label("pic_point"));		# make it PIC!
        +	&set_label("pic_point");
        +	&blindpop($tbl);
        +	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
        +
        +	&cmp	(&wparam(5),0);
        +	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
        +	&jne	(&label("picked_te"));
        +	&lea	($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl));
        +	&set_label("picked_te");
        +
        +	# one can argue if this is required
        +	&pushf	();
        +	&cld	();
        +
        +	&cmp	($s2,$speed_limit);
        +	&jb	(&label("slow_way"));
        +	&test	($s2,15);
        +	&jnz	(&label("slow_way"));
        +					if (!$x86only) {
        +	#&bt	(&DWP(0,$s0),28);	# check for hyper-threading bit
        +	#&jc	(&label("slow_way"));
        +					}
        +	# pre-allocate aligned stack frame...
        +	&lea	($acc,&DWP(-80-244,"esp"));
        +	&and	($acc,-64);
        +
        +	# ... and make sure it doesn't alias with $tbl modulo 4096
        +	&mov	($s0,$tbl);
        +	&lea	($s1,&DWP(2048+256,$tbl));
        +	&mov	($s3,$acc);
        +	&and	($s0,0xfff);		# s = %ebp&0xfff
        +	&and	($s1,0xfff);		# e = (%ebp+2048+256)&0xfff
        +	&and	($s3,0xfff);		# p = %esp&0xfff
        +
        +	&cmp	($s3,$s1);		# if (p>=e) %esp =- (p-e);
        +	&jb	(&label("tbl_break_out"));
        +	&sub	($s3,$s1);
        +	&sub	($acc,$s3);
        +	&jmp	(&label("tbl_ok"));
        +	&set_label("tbl_break_out",4);	# else %esp -= (p-s)&0xfff + framesz;
        +	&sub	($s3,$s0);
        +	&and	($s3,0xfff);
        +	&add	($s3,384);
        +	&sub	($acc,$s3);
        +	&set_label("tbl_ok",4);
        +
        +	&lea	($s3,&wparam(0));	# obtain pointer to parameter block
        +	&exch	("esp",$acc);		# allocate stack frame
        +	&add	("esp",4);		# reserve for return address!
        +	&mov	($_tbl,$tbl);		# save %ebp
        +	&mov	($_esp,$acc);		# save %esp
        +
        +	&mov	($s0,&DWP(0,$s3));	# load inp
        +	&mov	($s1,&DWP(4,$s3));	# load out
        +	#&mov	($s2,&DWP(8,$s3));	# load len
        +	&mov	($key,&DWP(12,$s3));	# load key
        +	&mov	($acc,&DWP(16,$s3));	# load ivp
        +	&mov	($s3,&DWP(20,$s3));	# load enc flag
        +
        +	&mov	($_inp,$s0);		# save copy of inp
        +	&mov	($_out,$s1);		# save copy of out
        +	&mov	($_len,$s2);		# save copy of len
        +	&mov	($_key,$key);		# save copy of key
        +	&mov	($_ivp,$acc);		# save copy of ivp
        +
        +	&mov	($mark,0);		# copy of aes_key->rounds = 0;
        +	# do we copy key schedule to stack?
        +	&mov	($s1 eq "ebx" ? $s1 : "",$key);
        +	&mov	($s2 eq "ecx" ? $s2 : "",244/4);
        +	&sub	($s1,$tbl);
        +	&mov	("esi",$key);
        +	&and	($s1,0xfff);
        +	&lea	("edi",$aes_key);
        +	&cmp	($s1,2048+256);
        +	&jb	(&label("do_copy"));
        +	&cmp	($s1,4096-244);
        +	&jb	(&label("skip_copy"));
        +	&set_label("do_copy",4);
        +		&mov	($_key,"edi");
        +		&data_word(0xA5F3F689);	# rep movsd
        +	&set_label("skip_copy");
        +
        +	&mov	($key,16);
        +	&set_label("prefetch_tbl",4);
        +		&mov	($s0,&DWP(0,$tbl));
        +		&mov	($s1,&DWP(32,$tbl));
        +		&mov	($s2,&DWP(64,$tbl));
        +		&mov	($acc,&DWP(96,$tbl));
        +		&lea	($tbl,&DWP(128,$tbl));
        +		&sub	($key,1);
        +	&jnz	(&label("prefetch_tbl"));
        +	&sub	($tbl,2048);
        +
        +	&mov	($acc,$_inp);
        +	&mov	($key,$_ivp);
        +
        +	&cmp	($s3,0);
        +	&je	(&label("fast_decrypt"));
        +
        +#----------------------------- ENCRYPT -----------------------------#
        +	&mov	($s0,&DWP(0,$key));		# load iv
        +	&mov	($s1,&DWP(4,$key));
        +
        +	&set_label("fast_enc_loop",16);
        +		&mov	($s2,&DWP(8,$key));
        +		&mov	($s3,&DWP(12,$key));
        +
        +		&xor	($s0,&DWP(0,$acc));	# xor input data
        +		&xor	($s1,&DWP(4,$acc));
        +		&xor	($s2,&DWP(8,$acc));
        +		&xor	($s3,&DWP(12,$acc));
        +
        +		&mov	($key,$_key);		# load key
        +		&call	("_x86_AES_encrypt");
        +
        +		&mov	($acc,$_inp);		# load inp
        +		&mov	($key,$_out);		# load out
        +
        +		&mov	(&DWP(0,$key),$s0);	# save output data
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($s2,$_len);		# load len
        +		&mov	($_inp,$acc);		# save inp
        +		&lea	($s3,&DWP(16,$key));	# advance out
        +		&mov	($_out,$s3);		# save out
        +		&sub	($s2,16);		# decrease len
        +		&mov	($_len,$s2);		# save len
        +	&jnz	(&label("fast_enc_loop"));
        +	&mov	($acc,$_ivp);		# load ivp
        +	&mov	($s2,&DWP(8,$key));	# restore last 2 dwords
        +	&mov	($s3,&DWP(12,$key));
        +	&mov	(&DWP(0,$acc),$s0);	# save ivec
        +	&mov	(&DWP(4,$acc),$s1);
        +	&mov	(&DWP(8,$acc),$s2);
        +	&mov	(&DWP(12,$acc),$s3);
        +
        +	&cmp	($mark,0);		# was the key schedule copied?
        +	&mov	("edi",$_key);
        +	&je	(&label("skip_ezero"));
        +	# zero copy of key schedule
        +	&mov	("ecx",240/4);
        +	&xor	("eax","eax");
        +	&align	(4);
        +	&data_word(0xABF3F689);	# rep stosd
        +	&set_label("skip_ezero")
        +	&mov	("esp",$_esp);
        +	&popf	();
        +    &set_label("drop_out");
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +
        +#----------------------------- DECRYPT -----------------------------#
        +&set_label("fast_decrypt",16);
        +
        +	&cmp	($acc,$_out);
        +	&je	(&label("fast_dec_in_place"));	# in-place processing...
        +
        +	&mov	($_tmp,$key);
        +
        +	&align	(4);
        +	&set_label("fast_dec_loop",16);
        +		&mov	($s0,&DWP(0,$acc));	# read input
        +		&mov	($s1,&DWP(4,$acc));
        +		&mov	($s2,&DWP(8,$acc));
        +		&mov	($s3,&DWP(12,$acc));
        +
        +		&mov	($key,$_key);		# load key
        +		&call	("_x86_AES_decrypt");
        +
        +		&mov	($key,$_tmp);		# load ivp
        +		&mov	($acc,$_len);		# load len
        +		&xor	($s0,&DWP(0,$key));	# xor iv
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +		&mov	($key,$_out);		# load out
        +		&mov	($acc,$_inp);		# load inp
        +
        +		&mov	(&DWP(0,$key),$s0);	# write output
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($s2,$_len);		# load len
        +		&mov	($_tmp,$acc);		# save ivp
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($_inp,$acc);		# save inp
        +		&lea	($key,&DWP(16,$key));	# advance out
        +		&mov	($_out,$key);		# save out
        +		&sub	($s2,16);		# decrease len
        +		&mov	($_len,$s2);		# save len
        +	&jnz	(&label("fast_dec_loop"));
        +	&mov	($key,$_tmp);		# load temp ivp
        +	&mov	($acc,$_ivp);		# load user ivp
        +	&mov	($s0,&DWP(0,$key));	# load iv
        +	&mov	($s1,&DWP(4,$key));
        +	&mov	($s2,&DWP(8,$key));
        +	&mov	($s3,&DWP(12,$key));
        +	&mov	(&DWP(0,$acc),$s0);	# copy back to user
        +	&mov	(&DWP(4,$acc),$s1);
        +	&mov	(&DWP(8,$acc),$s2);
        +	&mov	(&DWP(12,$acc),$s3);
        +	&jmp	(&label("fast_dec_out"));
        +
        +    &set_label("fast_dec_in_place",16);
        +	&set_label("fast_dec_in_place_loop");
        +		&mov	($s0,&DWP(0,$acc));	# read input
        +		&mov	($s1,&DWP(4,$acc));
        +		&mov	($s2,&DWP(8,$acc));
        +		&mov	($s3,&DWP(12,$acc));
        +
        +		&lea	($key,$ivec);
        +		&mov	(&DWP(0,$key),$s0);	# copy to temp
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($key,$_key);		# load key
        +		&call	("_x86_AES_decrypt");
        +
        +		&mov	($key,$_ivp);		# load ivp
        +		&mov	($acc,$_out);		# load out
        +		&xor	($s0,&DWP(0,$key));	# xor iv
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +		&mov	(&DWP(0,$acc),$s0);	# write output
        +		&mov	(&DWP(4,$acc),$s1);
        +		&mov	(&DWP(8,$acc),$s2);
        +		&mov	(&DWP(12,$acc),$s3);
        +
        +		&lea	($acc,&DWP(16,$acc));	# advance out
        +		&mov	($_out,$acc);		# save out
        +
        +		&lea	($acc,$ivec);
        +		&mov	($s0,&DWP(0,$acc));	# read temp
        +		&mov	($s1,&DWP(4,$acc));
        +		&mov	($s2,&DWP(8,$acc));
        +		&mov	($s3,&DWP(12,$acc));
        +
        +		&mov	(&DWP(0,$key),$s0);	# copy iv
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($acc,$_inp);		# load inp
        +		&mov	($s2,$_len);		# load len
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($_inp,$acc);		# save inp
        +		&sub	($s2,16);		# decrease len
        +		&mov	($_len,$s2);		# save len
        +	&jnz	(&label("fast_dec_in_place_loop"));
        +
        +    &set_label("fast_dec_out",4);
        +	&cmp	($mark,0);		# was the key schedule copied?
        +	&mov	("edi",$_key);
        +	&je	(&label("skip_dzero"));
        +	# zero copy of key schedule
        +	&mov	("ecx",240/4);
        +	&xor	("eax","eax");
        +	&align	(4);
        +	&data_word(0xABF3F689);	# rep stosd
        +	&set_label("skip_dzero")
        +	&mov	("esp",$_esp);
        +	&popf	();
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +
        +#--------------------------- SLOW ROUTINE ---------------------------#
        +&set_label("slow_way",16);
        +
        +	&mov	($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap
        +	&mov	($key,&wparam(3));	# load key
        +
        +	# pre-allocate aligned stack frame...
        +	&lea	($acc,&DWP(-80,"esp"));
        +	&and	($acc,-64);
        +
        +	# ... and make sure it doesn't alias with $key modulo 1024
        +	&lea	($s1,&DWP(-80-63,$key));
        +	&sub	($s1,$acc);
        +	&neg	($s1);
        +	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	($acc,$s1);
        +
        +	# pick S-box copy which can't overlap with stack frame or $key
        +	&lea	($s1,&DWP(768,$acc));
        +	&sub	($s1,$tbl);
        +	&and	($s1,0x300);
        +	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
        +
        +	&lea	($s3,&wparam(0));	# pointer to parameter block
        +
        +	&exch	("esp",$acc);
        +	&add	("esp",4);		# reserve for return address!
        +	&mov	($_tbl,$tbl);		# save %ebp
        +	&mov	($_esp,$acc);		# save %esp
        +	&mov	($_tmp,$s0);		# save OPENSSL_ia32cap
        +
        +	&mov	($s0,&DWP(0,$s3));	# load inp
        +	&mov	($s1,&DWP(4,$s3));	# load out
        +	#&mov	($s2,&DWP(8,$s3));	# load len
        +	#&mov	($key,&DWP(12,$s3));	# load key
        +	&mov	($acc,&DWP(16,$s3));	# load ivp
        +	&mov	($s3,&DWP(20,$s3));	# load enc flag
        +
        +	&mov	($_inp,$s0);		# save copy of inp
        +	&mov	($_out,$s1);		# save copy of out
        +	&mov	($_len,$s2);		# save copy of len
        +	&mov	($_key,$key);		# save copy of key
        +	&mov	($_ivp,$acc);		# save copy of ivp
        +
        +	&mov	($key,$acc);
        +	&mov	($acc,$s0);
        +
        +	&cmp	($s3,0);
        +	&je	(&label("slow_decrypt"));
        +
        +#--------------------------- SLOW ENCRYPT ---------------------------#
        +	&cmp	($s2,16);
        +	&mov	($s3,$s1);
        +	&jb	(&label("slow_enc_tail"));
        +
        +					if (!$x86only) {
        +	&bt	($_tmp,25);		# check for SSE bit
        +	&jnc	(&label("slow_enc_x86"));
        +
        +	&movq	("mm0",&QWP(0,$key));	# load iv
        +	&movq	("mm4",&QWP(8,$key));
        +
        +	&set_label("slow_enc_loop_sse",16);
        +		&pxor	("mm0",&QWP(0,$acc));	# xor input data
        +		&pxor	("mm4",&QWP(8,$acc));
        +
        +		&mov	($key,$_key);
        +		&call	("_sse_AES_encrypt_compact");
        +
        +		&mov	($acc,$_inp);		# load inp
        +		&mov	($key,$_out);		# load out
        +		&mov	($s2,$_len);		# load len
        +
        +		&movq	(&QWP(0,$key),"mm0");	# save output data
        +		&movq	(&QWP(8,$key),"mm4");
        +
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($_inp,$acc);		# save inp
        +		&lea	($s3,&DWP(16,$key));	# advance out
        +		&mov	($_out,$s3);		# save out
        +		&sub	($s2,16);		# decrease len
        +		&cmp	($s2,16);
        +		&mov	($_len,$s2);		# save len
        +	&jae	(&label("slow_enc_loop_sse"));
        +	&test	($s2,15);
        +	&jnz	(&label("slow_enc_tail"));
        +	&mov	($acc,$_ivp);		# load ivp
        +	&movq	(&QWP(0,$acc),"mm0");	# save ivec
        +	&movq	(&QWP(8,$acc),"mm4");
        +	&emms	();
        +	&mov	("esp",$_esp);
        +	&popf	();
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +					}
        +    &set_label("slow_enc_x86",16);
        +	&mov	($s0,&DWP(0,$key));	# load iv
        +	&mov	($s1,&DWP(4,$key));
        +
        +	&set_label("slow_enc_loop_x86",4);
        +		&mov	($s2,&DWP(8,$key));
        +		&mov	($s3,&DWP(12,$key));
        +
        +		&xor	($s0,&DWP(0,$acc));	# xor input data
        +		&xor	($s1,&DWP(4,$acc));
        +		&xor	($s2,&DWP(8,$acc));
        +		&xor	($s3,&DWP(12,$acc));
        +
        +		&mov	($key,$_key);		# load key
        +		&call	("_x86_AES_encrypt_compact");
        +
        +		&mov	($acc,$_inp);		# load inp
        +		&mov	($key,$_out);		# load out
        +
        +		&mov	(&DWP(0,$key),$s0);	# save output data
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($s2,$_len);		# load len
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($_inp,$acc);		# save inp
        +		&lea	($s3,&DWP(16,$key));	# advance out
        +		&mov	($_out,$s3);		# save out
        +		&sub	($s2,16);		# decrease len
        +		&cmp	($s2,16);
        +		&mov	($_len,$s2);		# save len
        +	&jae	(&label("slow_enc_loop_x86"));
        +	&test	($s2,15);
        +	&jnz	(&label("slow_enc_tail"));
        +	&mov	($acc,$_ivp);		# load ivp
        +	&mov	($s2,&DWP(8,$key));	# restore last dwords
        +	&mov	($s3,&DWP(12,$key));
        +	&mov	(&DWP(0,$acc),$s0);	# save ivec
        +	&mov	(&DWP(4,$acc),$s1);
        +	&mov	(&DWP(8,$acc),$s2);
        +	&mov	(&DWP(12,$acc),$s3);
        +
        +	&mov	("esp",$_esp);
        +	&popf	();
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +
        +    &set_label("slow_enc_tail",16);
        +	&emms	()	if (!$x86only);
        +	&mov	($key eq "edi"? $key:"",$s3);	# load out to edi
        +	&mov	($s1,16);
        +	&sub	($s1,$s2);
        +	&cmp	($key,$acc eq "esi"? $acc:"");	# compare with inp
        +	&je	(&label("enc_in_place"));
        +	&align	(4);
        +	&data_word(0xA4F3F689);	# rep movsb	# copy input
        +	&jmp	(&label("enc_skip_in_place"));
        +    &set_label("enc_in_place");
        +	&lea	($key,&DWP(0,$key,$s2));
        +    &set_label("enc_skip_in_place");
        +	&mov	($s2,$s1);
        +	&xor	($s0,$s0);
        +	&align	(4);
        +	&data_word(0xAAF3F689);	# rep stosb	# zero tail
        +
        +	&mov	($key,$_ivp);			# restore ivp
        +	&mov	($acc,$s3);			# output as input
        +	&mov	($s0,&DWP(0,$key));
        +	&mov	($s1,&DWP(4,$key));
        +	&mov	($_len,16);			# len=16
        +	&jmp	(&label("slow_enc_loop_x86"));	# one more spin...
        +
        +#--------------------------- SLOW DECRYPT ---------------------------#
        +&set_label("slow_decrypt",16);
        +					if (!$x86only) {
        +	&bt	($_tmp,25);		# check for SSE bit
        +	&jnc	(&label("slow_dec_loop_x86"));
        +
        +	&set_label("slow_dec_loop_sse",4);
        +		&movq	("mm0",&QWP(0,$acc));	# read input
        +		&movq	("mm4",&QWP(8,$acc));
        +
        +		&mov	($key,$_key);
        +		&call	("_sse_AES_decrypt_compact");
        +
        +		&mov	($acc,$_inp);		# load inp
        +		&lea	($s0,$ivec);
        +		&mov	($s1,$_out);		# load out
        +		&mov	($s2,$_len);		# load len
        +		&mov	($key,$_ivp);		# load ivp
        +
        +		&movq	("mm1",&QWP(0,$acc));	# re-read input
        +		&movq	("mm5",&QWP(8,$acc));
        +
        +		&pxor	("mm0",&QWP(0,$key));	# xor iv
        +		&pxor	("mm4",&QWP(8,$key));
        +
        +		&movq	(&QWP(0,$key),"mm1");	# copy input to iv
        +		&movq	(&QWP(8,$key),"mm5");
        +
        +		&sub	($s2,16);		# decrease len
        +		&jc	(&label("slow_dec_partial_sse"));
        +
        +		&movq	(&QWP(0,$s1),"mm0");	# write output
        +		&movq	(&QWP(8,$s1),"mm4");
        +
        +		&lea	($s1,&DWP(16,$s1));	# advance out
        +		&mov	($_out,$s1);		# save out
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($_inp,$acc);		# save inp
        +		&mov	($_len,$s2);		# save len
        +	&jnz	(&label("slow_dec_loop_sse"));
        +	&emms	();
        +	&mov	("esp",$_esp);
        +	&popf	();
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +
        +    &set_label("slow_dec_partial_sse",16);
        +	&movq	(&QWP(0,$s0),"mm0");	# save output to temp
        +	&movq	(&QWP(8,$s0),"mm4");
        +	&emms	();
        +
        +	&add	($s2 eq "ecx" ? "ecx":"",16);
        +	&mov	("edi",$s1);		# out
        +	&mov	("esi",$s0);		# temp
        +	&align	(4);
        +	&data_word(0xA4F3F689);		# rep movsb # copy partial output
        +
        +	&mov	("esp",$_esp);
        +	&popf	();
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +					}
        +	&set_label("slow_dec_loop_x86",16);
        +		&mov	($s0,&DWP(0,$acc));	# read input
        +		&mov	($s1,&DWP(4,$acc));
        +		&mov	($s2,&DWP(8,$acc));
        +		&mov	($s3,&DWP(12,$acc));
        +
        +		&lea	($key,$ivec);
        +		&mov	(&DWP(0,$key),$s0);	# copy to temp
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($key,$_key);		# load key
        +		&call	("_x86_AES_decrypt_compact");
        +
        +		&mov	($key,$_ivp);		# load ivp
        +		&mov	($acc,$_len);		# load len
        +		&xor	($s0,&DWP(0,$key));	# xor iv
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +		&sub	($acc,16);
        +		&jc	(&label("slow_dec_partial_x86"));
        +
        +		&mov	($_len,$acc);		# save len
        +		&mov	($acc,$_out);		# load out
        +
        +		&mov	(&DWP(0,$acc),$s0);	# write output
        +		&mov	(&DWP(4,$acc),$s1);
        +		&mov	(&DWP(8,$acc),$s2);
        +		&mov	(&DWP(12,$acc),$s3);
        +
        +		&lea	($acc,&DWP(16,$acc));	# advance out
        +		&mov	($_out,$acc);		# save out
        +
        +		&lea	($acc,$ivec);
        +		&mov	($s0,&DWP(0,$acc));	# read temp
        +		&mov	($s1,&DWP(4,$acc));
        +		&mov	($s2,&DWP(8,$acc));
        +		&mov	($s3,&DWP(12,$acc));
        +
        +		&mov	(&DWP(0,$key),$s0);	# copy it to iv
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($acc,$_inp);		# load inp
        +		&lea	($acc,&DWP(16,$acc));	# advance inp
        +		&mov	($_inp,$acc);		# save inp
        +	&jnz	(&label("slow_dec_loop_x86"));
        +	&mov	("esp",$_esp);
        +	&popf	();
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +
        +    &set_label("slow_dec_partial_x86",16);
        +	&lea	($acc,$ivec);
        +	&mov	(&DWP(0,$acc),$s0);	# save output to temp
        +	&mov	(&DWP(4,$acc),$s1);
        +	&mov	(&DWP(8,$acc),$s2);
        +	&mov	(&DWP(12,$acc),$s3);
        +
        +	&mov	($acc,$_inp);
        +	&mov	($s0,&DWP(0,$acc));	# re-read input
        +	&mov	($s1,&DWP(4,$acc));
        +	&mov	($s2,&DWP(8,$acc));
        +	&mov	($s3,&DWP(12,$acc));
        +
        +	&mov	(&DWP(0,$key),$s0);	# copy it to iv
        +	&mov	(&DWP(4,$key),$s1);
        +	&mov	(&DWP(8,$key),$s2);
        +	&mov	(&DWP(12,$key),$s3);
        +
        +	&mov	("ecx",$_len);
        +	&mov	("edi",$_out);
        +	&lea	("esi",$ivec);
        +	&align	(4);
        +	&data_word(0xA4F3F689);		# rep movsb # copy partial output
        +
        +	&mov	("esp",$_esp);
        +	&popf	();
        +&function_end("AES_cbc_encrypt");
        +}
        +
        +#------------------------------------------------------------------#
        +
        +sub enckey()
        +{
        +	&movz	("esi",&LB("edx"));		# rk[i]>>0
        +	&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +	&movz	("esi",&HB("edx"));		# rk[i]>>8
        +	&shl	("ebx",24);
        +	&xor	("eax","ebx");
        +
        +	&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +	&shr	("edx",16);
        +	&movz	("esi",&LB("edx"));		# rk[i]>>16
        +	&xor	("eax","ebx");
        +
        +	&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +	&movz	("esi",&HB("edx"));		# rk[i]>>24
        +	&shl	("ebx",8);
        +	&xor	("eax","ebx");
        +
        +	&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +	&shl	("ebx",16);
        +	&xor	("eax","ebx");
        +
        +	&xor	("eax",&DWP(1024-128,$tbl,"ecx",4));	# rcon
        +}
        +
        +&function_begin("_x86_AES_set_encrypt_key");
        +	&mov	("esi",&wparam(1));		# user supplied key
        +	&mov	("edi",&wparam(3));		# private key schedule
        +
        +	&test	("esi",-1);
        +	&jz	(&label("badpointer"));
        +	&test	("edi",-1);
        +	&jz	(&label("badpointer"));
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($tbl);
        +	&lea	($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
        +	&lea	($tbl,&DWP(2048+128,$tbl));
        +
        +	# prefetch Te4
        +	&mov	("eax",&DWP(0-128,$tbl));
        +	&mov	("ebx",&DWP(32-128,$tbl));
        +	&mov	("ecx",&DWP(64-128,$tbl));
        +	&mov	("edx",&DWP(96-128,$tbl));
        +	&mov	("eax",&DWP(128-128,$tbl));
        +	&mov	("ebx",&DWP(160-128,$tbl));
        +	&mov	("ecx",&DWP(192-128,$tbl));
        +	&mov	("edx",&DWP(224-128,$tbl));
        +
        +	&mov	("ecx",&wparam(2));		# number of bits in key
        +	&cmp	("ecx",128);
        +	&je	(&label("10rounds"));
        +	&cmp	("ecx",192);
        +	&je	(&label("12rounds"));
        +	&cmp	("ecx",256);
        +	&je	(&label("14rounds"));
        +	&mov	("eax",-2);			# invalid number of bits
        +	&jmp	(&label("exit"));
        +
        +    &set_label("10rounds");
        +	&mov	("eax",&DWP(0,"esi"));		# copy first 4 dwords
        +	&mov	("ebx",&DWP(4,"esi"));
        +	&mov	("ecx",&DWP(8,"esi"));
        +	&mov	("edx",&DWP(12,"esi"));
        +	&mov	(&DWP(0,"edi"),"eax");
        +	&mov	(&DWP(4,"edi"),"ebx");
        +	&mov	(&DWP(8,"edi"),"ecx");
        +	&mov	(&DWP(12,"edi"),"edx");
        +
        +	&xor	("ecx","ecx");
        +	&jmp	(&label("10shortcut"));
        +
        +	&align	(4);
        +	&set_label("10loop");
        +		&mov	("eax",&DWP(0,"edi"));		# rk[0]
        +		&mov	("edx",&DWP(12,"edi"));		# rk[3]
        +	&set_label("10shortcut");
        +		&enckey	();
        +
        +		&mov	(&DWP(16,"edi"),"eax");		# rk[4]
        +		&xor	("eax",&DWP(4,"edi"));
        +		&mov	(&DWP(20,"edi"),"eax");		# rk[5]
        +		&xor	("eax",&DWP(8,"edi"));
        +		&mov	(&DWP(24,"edi"),"eax");		# rk[6]
        +		&xor	("eax",&DWP(12,"edi"));
        +		&mov	(&DWP(28,"edi"),"eax");		# rk[7]
        +		&inc	("ecx");
        +		&add	("edi",16);
        +		&cmp	("ecx",10);
        +	&jl	(&label("10loop"));
        +
        +	&mov	(&DWP(80,"edi"),10);		# setup number of rounds
        +	&xor	("eax","eax");
        +	&jmp	(&label("exit"));
        +		
        +    &set_label("12rounds");
        +	&mov	("eax",&DWP(0,"esi"));		# copy first 6 dwords
        +	&mov	("ebx",&DWP(4,"esi"));
        +	&mov	("ecx",&DWP(8,"esi"));
        +	&mov	("edx",&DWP(12,"esi"));
        +	&mov	(&DWP(0,"edi"),"eax");
        +	&mov	(&DWP(4,"edi"),"ebx");
        +	&mov	(&DWP(8,"edi"),"ecx");
        +	&mov	(&DWP(12,"edi"),"edx");
        +	&mov	("ecx",&DWP(16,"esi"));
        +	&mov	("edx",&DWP(20,"esi"));
        +	&mov	(&DWP(16,"edi"),"ecx");
        +	&mov	(&DWP(20,"edi"),"edx");
        +
        +	&xor	("ecx","ecx");
        +	&jmp	(&label("12shortcut"));
        +
        +	&align	(4);
        +	&set_label("12loop");
        +		&mov	("eax",&DWP(0,"edi"));		# rk[0]
        +		&mov	("edx",&DWP(20,"edi"));		# rk[5]
        +	&set_label("12shortcut");
        +		&enckey	();
        +
        +		&mov	(&DWP(24,"edi"),"eax");		# rk[6]
        +		&xor	("eax",&DWP(4,"edi"));
        +		&mov	(&DWP(28,"edi"),"eax");		# rk[7]
        +		&xor	("eax",&DWP(8,"edi"));
        +		&mov	(&DWP(32,"edi"),"eax");		# rk[8]
        +		&xor	("eax",&DWP(12,"edi"));
        +		&mov	(&DWP(36,"edi"),"eax");		# rk[9]
        +
        +		&cmp	("ecx",7);
        +		&je	(&label("12break"));
        +		&inc	("ecx");
        +
        +		&xor	("eax",&DWP(16,"edi"));
        +		&mov	(&DWP(40,"edi"),"eax");		# rk[10]
        +		&xor	("eax",&DWP(20,"edi"));
        +		&mov	(&DWP(44,"edi"),"eax");		# rk[11]
        +
        +		&add	("edi",24);
        +	&jmp	(&label("12loop"));
        +
        +	&set_label("12break");
        +	&mov	(&DWP(72,"edi"),12);		# setup number of rounds
        +	&xor	("eax","eax");
        +	&jmp	(&label("exit"));
        +
        +    &set_label("14rounds");
        +	&mov	("eax",&DWP(0,"esi"));		# copy first 8 dwords
        +	&mov	("ebx",&DWP(4,"esi"));
        +	&mov	("ecx",&DWP(8,"esi"));
        +	&mov	("edx",&DWP(12,"esi"));
        +	&mov	(&DWP(0,"edi"),"eax");
        +	&mov	(&DWP(4,"edi"),"ebx");
        +	&mov	(&DWP(8,"edi"),"ecx");
        +	&mov	(&DWP(12,"edi"),"edx");
        +	&mov	("eax",&DWP(16,"esi"));
        +	&mov	("ebx",&DWP(20,"esi"));
        +	&mov	("ecx",&DWP(24,"esi"));
        +	&mov	("edx",&DWP(28,"esi"));
        +	&mov	(&DWP(16,"edi"),"eax");
        +	&mov	(&DWP(20,"edi"),"ebx");
        +	&mov	(&DWP(24,"edi"),"ecx");
        +	&mov	(&DWP(28,"edi"),"edx");
        +
        +	&xor	("ecx","ecx");
        +	&jmp	(&label("14shortcut"));
        +
        +	&align	(4);
        +	&set_label("14loop");
        +		&mov	("edx",&DWP(28,"edi"));		# rk[7]
        +	&set_label("14shortcut");
        +		&mov	("eax",&DWP(0,"edi"));		# rk[0]
        +
        +		&enckey	();
        +
        +		&mov	(&DWP(32,"edi"),"eax");		# rk[8]
        +		&xor	("eax",&DWP(4,"edi"));
        +		&mov	(&DWP(36,"edi"),"eax");		# rk[9]
        +		&xor	("eax",&DWP(8,"edi"));
        +		&mov	(&DWP(40,"edi"),"eax");		# rk[10]
        +		&xor	("eax",&DWP(12,"edi"));
        +		&mov	(&DWP(44,"edi"),"eax");		# rk[11]
        +
        +		&cmp	("ecx",6);
        +		&je	(&label("14break"));
        +		&inc	("ecx");
        +
        +		&mov	("edx","eax");
        +		&mov	("eax",&DWP(16,"edi"));		# rk[4]
        +		&movz	("esi",&LB("edx"));		# rk[11]>>0
        +		&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +		&movz	("esi",&HB("edx"));		# rk[11]>>8
        +		&xor	("eax","ebx");
        +
        +		&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +		&shr	("edx",16);
        +		&shl	("ebx",8);
        +		&movz	("esi",&LB("edx"));		# rk[11]>>16
        +		&xor	("eax","ebx");
        +
        +		&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +		&movz	("esi",&HB("edx"));		# rk[11]>>24
        +		&shl	("ebx",16);
        +		&xor	("eax","ebx");
        +
        +		&movz	("ebx",&BP(-128,$tbl,"esi",1));
        +		&shl	("ebx",24);
        +		&xor	("eax","ebx");
        +
        +		&mov	(&DWP(48,"edi"),"eax");		# rk[12]
        +		&xor	("eax",&DWP(20,"edi"));
        +		&mov	(&DWP(52,"edi"),"eax");		# rk[13]
        +		&xor	("eax",&DWP(24,"edi"));
        +		&mov	(&DWP(56,"edi"),"eax");		# rk[14]
        +		&xor	("eax",&DWP(28,"edi"));
        +		&mov	(&DWP(60,"edi"),"eax");		# rk[15]
        +
        +		&add	("edi",32);
        +	&jmp	(&label("14loop"));
        +
        +	&set_label("14break");
        +	&mov	(&DWP(48,"edi"),14);		# setup number of rounds
        +	&xor	("eax","eax");
        +	&jmp	(&label("exit"));
        +
        +    &set_label("badpointer");
        +	&mov	("eax",-1);
        +    &set_label("exit");
        +&function_end("_x86_AES_set_encrypt_key");
        +
        +# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +#                        AES_KEY *key)
        +&function_begin_B("private_AES_set_encrypt_key");
        +	&call	("_x86_AES_set_encrypt_key");
        +	&ret	();
        +&function_end_B("private_AES_set_encrypt_key");
        +
        +sub deckey()
        +{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
        +  my $tmp = $tbl;
        +
        +	&mov	($acc,$tp1);
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($tp2,&DWP(0,$tp1,$tp1));
        +	&sub	($acc,$tmp);
        +	&and	($tp2,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	&xor	($acc,$tp2);
        +	&mov	($tp2,$acc);
        +
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($tp4,&DWP(0,$tp2,$tp2));
        +	&sub	($acc,$tmp);
        +	&and	($tp4,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	 &xor	($tp2,$tp1);	# tp2^tp1
        +	&xor	($acc,$tp4);
        +	&mov	($tp4,$acc);
        +
        +	&and	($acc,0x80808080);
        +	&mov	($tmp,$acc);
        +	&shr	($tmp,7);
        +	&lea	($tp8,&DWP(0,$tp4,$tp4));
        +	 &xor	($tp4,$tp1);	# tp4^tp1
        +	&sub	($acc,$tmp);
        +	&and	($tp8,0xfefefefe);
        +	&and	($acc,0x1b1b1b1b);
        +	 &rotl	($tp1,8);	# = ROTATE(tp1,8)
        +	&xor	($tp8,$acc);
        +
        +	&mov	($tmp,&DWP(4*($i+1),$key));	# modulo-scheduled load
        +
        +	&xor	($tp1,$tp2);
        +	&xor	($tp2,$tp8);
        +	&xor	($tp1,$tp4);
        +	&rotl	($tp2,24);
        +	&xor	($tp4,$tp8);
        +	&xor	($tp1,$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
        +	&rotl	($tp4,16);
        +	&xor	($tp1,$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
        +	&rotl	($tp8,8);
        +	&xor	($tp1,$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
        +	&mov	($tp2,$tmp);
        +	&xor	($tp1,$tp8);	# ^= ROTATE(tp8,8)
        +
        +	&mov	(&DWP(4*$i,$key),$tp1);
        +}
        +
        +# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +#                        AES_KEY *key)
        +&function_begin_B("private_AES_set_decrypt_key");
        +	&call	("_x86_AES_set_encrypt_key");
        +	&cmp	("eax",0);
        +	&je	(&label("proceed"));
        +	&ret	();
        +
        +    &set_label("proceed");
        +	&push	("ebp");
        +	&push	("ebx");
        +	&push	("esi");
        +	&push	("edi");
        +
        +	&mov	("esi",&wparam(2));
        +	&mov	("ecx",&DWP(240,"esi"));	# pull number of rounds
        +	&lea	("ecx",&DWP(0,"","ecx",4));
        +	&lea	("edi",&DWP(0,"esi","ecx",4));	# pointer to last chunk
        +
        +	&set_label("invert",4);			# invert order of chunks
        +		&mov	("eax",&DWP(0,"esi"));
        +		&mov	("ebx",&DWP(4,"esi"));
        +		&mov	("ecx",&DWP(0,"edi"));
        +		&mov	("edx",&DWP(4,"edi"));
        +		&mov	(&DWP(0,"edi"),"eax");
        +		&mov	(&DWP(4,"edi"),"ebx");
        +		&mov	(&DWP(0,"esi"),"ecx");
        +		&mov	(&DWP(4,"esi"),"edx");
        +		&mov	("eax",&DWP(8,"esi"));
        +		&mov	("ebx",&DWP(12,"esi"));
        +		&mov	("ecx",&DWP(8,"edi"));
        +		&mov	("edx",&DWP(12,"edi"));
        +		&mov	(&DWP(8,"edi"),"eax");
        +		&mov	(&DWP(12,"edi"),"ebx");
        +		&mov	(&DWP(8,"esi"),"ecx");
        +		&mov	(&DWP(12,"esi"),"edx");
        +		&add	("esi",16);
        +		&sub	("edi",16);
        +		&cmp	("esi","edi");
        +	&jne	(&label("invert"));
        +
        +	&mov	($key,&wparam(2));
        +	&mov	($acc,&DWP(240,$key));		# pull number of rounds
        +	&lea	($acc,&DWP(-2,$acc,$acc));
        +	&lea	($acc,&DWP(0,$key,$acc,8));
        +	&mov	(&wparam(2),$acc);
        +
        +	&mov	($s0,&DWP(16,$key));		# modulo-scheduled load
        +	&set_label("permute",4);		# permute the key schedule
        +		&add	($key,16);
        +		&deckey	(0,$key,$s0,$s1,$s2,$s3);
        +		&deckey	(1,$key,$s1,$s2,$s3,$s0);
        +		&deckey	(2,$key,$s2,$s3,$s0,$s1);
        +		&deckey	(3,$key,$s3,$s0,$s1,$s2);
        +		&cmp	($key,&wparam(2));
        +	&jb	(&label("permute"));
        +
        +	&xor	("eax","eax");			# return success
        +&function_end("private_AES_set_decrypt_key");
        +&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-armv4.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-armv4.pl
        new file mode 100644
        index 000000000..86b86c4a0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-armv4.pl
        @@ -0,0 +1,1134 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# AES for ARMv4
        +
        +# January 2007.
        +#
        +# Code uses single 1K S-box and is >2 times faster than code generated
        +# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
        +# allows to merge logical or arithmetic operation with shift or rotate
        +# in one instruction and emit combined result every cycle. The module
        +# is endian-neutral. The performance is ~42 cycles/byte for 128-bit
        +# key [on single-issue Xscale PXA250 core].
        +
        +# May 2007.
        +#
        +# AES_set_[en|de]crypt_key is added.
        +
        +# July 2010.
        +#
        +# Rescheduling for dual-issue pipeline resulted in 12% improvement on
        +# Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
        +
        +# February 2011.
        +#
        +# Profiler-assisted and platform-specific optimization resulted in 16%
        +# improvement on Cortex A8 core and ~21.5 cycles per byte.
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$s0="r0";
        +$s1="r1";
        +$s2="r2";
        +$s3="r3";
        +$t1="r4";
        +$t2="r5";
        +$t3="r6";
        +$i1="r7";
        +$i2="r8";
        +$i3="r9";
        +
        +$tbl="r10";
        +$key="r11";
        +$rounds="r12";
        +
        +$code=<<___;
        +#include "arm_arch.h"
        +.text
        +.code	32
        +
        +.type	AES_Te,%object
        +.align	5
        +AES_Te:
        +.word	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
        +.word	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
        +.word	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
        +.word	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
        +.word	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
        +.word	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
        +.word	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
        +.word	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
        +.word	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
        +.word	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
        +.word	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
        +.word	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
        +.word	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
        +.word	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
        +.word	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
        +.word	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
        +.word	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
        +.word	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
        +.word	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
        +.word	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
        +.word	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
        +.word	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
        +.word	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
        +.word	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
        +.word	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
        +.word	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
        +.word	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
        +.word	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
        +.word	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
        +.word	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
        +.word	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
        +.word	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
        +.word	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
        +.word	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
        +.word	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
        +.word	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
        +.word	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
        +.word	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
        +.word	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
        +.word	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
        +.word	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
        +.word	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
        +.word	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
        +.word	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
        +.word	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
        +.word	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
        +.word	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
        +.word	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
        +.word	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
        +.word	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
        +.word	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
        +.word	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
        +.word	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
        +.word	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
        +.word	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
        +.word	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
        +.word	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
        +.word	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
        +.word	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
        +.word	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
        +.word	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
        +.word	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
        +.word	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
        +.word	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
        +@ Te4[256]
        +.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
        +.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +@ rcon[]
        +.word	0x01000000, 0x02000000, 0x04000000, 0x08000000
        +.word	0x10000000, 0x20000000, 0x40000000, 0x80000000
        +.word	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
        +.size	AES_Te,.-AES_Te
        +
        +@ void AES_encrypt(const unsigned char *in, unsigned char *out,
        +@ 		 const AES_KEY *key) {
        +.global AES_encrypt
        +.type   AES_encrypt,%function
        +.align	5
        +AES_encrypt:
        +	sub	r3,pc,#8		@ AES_encrypt
        +	stmdb   sp!,{r1,r4-r12,lr}
        +	mov	$rounds,r0		@ inp
        +	mov	$key,r2
        +	sub	$tbl,r3,#AES_encrypt-AES_Te	@ Te
        +#if __ARM_ARCH__<7
        +	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
        +	ldrb	$t1,[$rounds,#2]	@ manner...
        +	ldrb	$t2,[$rounds,#1]
        +	ldrb	$t3,[$rounds,#0]
        +	orr	$s0,$s0,$t1,lsl#8
        +	ldrb	$s1,[$rounds,#7]
        +	orr	$s0,$s0,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#6]
        +	orr	$s0,$s0,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#5]
        +	ldrb	$t3,[$rounds,#4]
        +	orr	$s1,$s1,$t1,lsl#8
        +	ldrb	$s2,[$rounds,#11]
        +	orr	$s1,$s1,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#10]
        +	orr	$s1,$s1,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#9]
        +	ldrb	$t3,[$rounds,#8]
        +	orr	$s2,$s2,$t1,lsl#8
        +	ldrb	$s3,[$rounds,#15]
        +	orr	$s2,$s2,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#14]
        +	orr	$s2,$s2,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#13]
        +	ldrb	$t3,[$rounds,#12]
        +	orr	$s3,$s3,$t1,lsl#8
        +	orr	$s3,$s3,$t2,lsl#16
        +	orr	$s3,$s3,$t3,lsl#24
        +#else
        +	ldr	$s0,[$rounds,#0]
        +	ldr	$s1,[$rounds,#4]
        +	ldr	$s2,[$rounds,#8]
        +	ldr	$s3,[$rounds,#12]
        +#ifdef __ARMEL__
        +	rev	$s0,$s0
        +	rev	$s1,$s1
        +	rev	$s2,$s2
        +	rev	$s3,$s3
        +#endif
        +#endif
        +	bl	_armv4_AES_encrypt
        +
        +	ldr	$rounds,[sp],#4		@ pop out
        +#if __ARM_ARCH__>=7
        +#ifdef __ARMEL__
        +	rev	$s0,$s0
        +	rev	$s1,$s1
        +	rev	$s2,$s2
        +	rev	$s3,$s3
        +#endif
        +	str	$s0,[$rounds,#0]
        +	str	$s1,[$rounds,#4]
        +	str	$s2,[$rounds,#8]
        +	str	$s3,[$rounds,#12]
        +#else
        +	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
        +	mov	$t2,$s0,lsr#16		@ manner...
        +	mov	$t3,$s0,lsr#8
        +	strb	$t1,[$rounds,#0]
        +	strb	$t2,[$rounds,#1]
        +	mov	$t1,$s1,lsr#24
        +	strb	$t3,[$rounds,#2]
        +	mov	$t2,$s1,lsr#16
        +	strb	$s0,[$rounds,#3]
        +	mov	$t3,$s1,lsr#8
        +	strb	$t1,[$rounds,#4]
        +	strb	$t2,[$rounds,#5]
        +	mov	$t1,$s2,lsr#24
        +	strb	$t3,[$rounds,#6]
        +	mov	$t2,$s2,lsr#16
        +	strb	$s1,[$rounds,#7]
        +	mov	$t3,$s2,lsr#8
        +	strb	$t1,[$rounds,#8]
        +	strb	$t2,[$rounds,#9]
        +	mov	$t1,$s3,lsr#24
        +	strb	$t3,[$rounds,#10]
        +	mov	$t2,$s3,lsr#16
        +	strb	$s2,[$rounds,#11]
        +	mov	$t3,$s3,lsr#8
        +	strb	$t1,[$rounds,#12]
        +	strb	$t2,[$rounds,#13]
        +	strb	$t3,[$rounds,#14]
        +	strb	$s3,[$rounds,#15]
        +#endif
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r12,pc}
        +#else
        +	ldmia   sp!,{r4-r12,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size	AES_encrypt,.-AES_encrypt
        +
        +.type   _armv4_AES_encrypt,%function
        +.align	2
        +_armv4_AES_encrypt:
        +	str	lr,[sp,#-4]!		@ push lr
        +	ldmia	$key!,{$t1-$i1}
        +	eor	$s0,$s0,$t1
        +	ldr	$rounds,[$key,#240-16]
        +	eor	$s1,$s1,$t2
        +	eor	$s2,$s2,$t3
        +	eor	$s3,$s3,$i1
        +	sub	$rounds,$rounds,#1
        +	mov	lr,#255
        +
        +	and	$i1,lr,$s0
        +	and	$i2,lr,$s0,lsr#8
        +	and	$i3,lr,$s0,lsr#16
        +	mov	$s0,$s0,lsr#24
        +.Lenc_loop:
        +	ldr	$t1,[$tbl,$i1,lsl#2]	@ Te3[s0>>0]
        +	and	$i1,lr,$s1,lsr#16	@ i0
        +	ldr	$t2,[$tbl,$i2,lsl#2]	@ Te2[s0>>8]
        +	and	$i2,lr,$s1
        +	ldr	$t3,[$tbl,$i3,lsl#2]	@ Te1[s0>>16]
        +	and	$i3,lr,$s1,lsr#8
        +	ldr	$s0,[$tbl,$s0,lsl#2]	@ Te0[s0>>24]
        +	mov	$s1,$s1,lsr#24
        +
        +	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te1[s1>>16]
        +	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te3[s1>>0]
        +	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te2[s1>>8]
        +	eor	$s0,$s0,$i1,ror#8
        +	ldr	$s1,[$tbl,$s1,lsl#2]	@ Te0[s1>>24]
        +	and	$i1,lr,$s2,lsr#8	@ i0
        +	eor	$t2,$t2,$i2,ror#8
        +	and	$i2,lr,$s2,lsr#16	@ i1
        +	eor	$t3,$t3,$i3,ror#8
        +	and	$i3,lr,$s2
        +	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te2[s2>>8]
        +	eor	$s1,$s1,$t1,ror#24
        +	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te1[s2>>16]
        +	mov	$s2,$s2,lsr#24
        +
        +	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te3[s2>>0]
        +	eor	$s0,$s0,$i1,ror#16
        +	ldr	$s2,[$tbl,$s2,lsl#2]	@ Te0[s2>>24]
        +	and	$i1,lr,$s3		@ i0
        +	eor	$s1,$s1,$i2,ror#8
        +	and	$i2,lr,$s3,lsr#8	@ i1
        +	eor	$t3,$t3,$i3,ror#16
        +	and	$i3,lr,$s3,lsr#16	@ i2
        +	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te3[s3>>0]
        +	eor	$s2,$s2,$t2,ror#16
        +	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te2[s3>>8]
        +	mov	$s3,$s3,lsr#24
        +
        +	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te1[s3>>16]
        +	eor	$s0,$s0,$i1,ror#24
        +	ldr	$i1,[$key],#16
        +	eor	$s1,$s1,$i2,ror#16
        +	ldr	$s3,[$tbl,$s3,lsl#2]	@ Te0[s3>>24]
        +	eor	$s2,$s2,$i3,ror#8
        +	ldr	$t1,[$key,#-12]
        +	eor	$s3,$s3,$t3,ror#8
        +
        +	ldr	$t2,[$key,#-8]
        +	eor	$s0,$s0,$i1
        +	ldr	$t3,[$key,#-4]
        +	and	$i1,lr,$s0
        +	eor	$s1,$s1,$t1
        +	and	$i2,lr,$s0,lsr#8
        +	eor	$s2,$s2,$t2
        +	and	$i3,lr,$s0,lsr#16
        +	eor	$s3,$s3,$t3
        +	mov	$s0,$s0,lsr#24
        +
        +	subs	$rounds,$rounds,#1
        +	bne	.Lenc_loop
        +
        +	add	$tbl,$tbl,#2
        +
        +	ldrb	$t1,[$tbl,$i1,lsl#2]	@ Te4[s0>>0]
        +	and	$i1,lr,$s1,lsr#16	@ i0
        +	ldrb	$t2,[$tbl,$i2,lsl#2]	@ Te4[s0>>8]
        +	and	$i2,lr,$s1
        +	ldrb	$t3,[$tbl,$i3,lsl#2]	@ Te4[s0>>16]
        +	and	$i3,lr,$s1,lsr#8
        +	ldrb	$s0,[$tbl,$s0,lsl#2]	@ Te4[s0>>24]
        +	mov	$s1,$s1,lsr#24
        +
        +	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s1>>16]
        +	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s1>>0]
        +	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s1>>8]
        +	eor	$s0,$i1,$s0,lsl#8
        +	ldrb	$s1,[$tbl,$s1,lsl#2]	@ Te4[s1>>24]
        +	and	$i1,lr,$s2,lsr#8	@ i0
        +	eor	$t2,$i2,$t2,lsl#8
        +	and	$i2,lr,$s2,lsr#16	@ i1
        +	eor	$t3,$i3,$t3,lsl#8
        +	and	$i3,lr,$s2
        +	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s2>>8]
        +	eor	$s1,$t1,$s1,lsl#24
        +	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s2>>16]
        +	mov	$s2,$s2,lsr#24
        +
        +	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s2>>0]
        +	eor	$s0,$i1,$s0,lsl#8
        +	ldrb	$s2,[$tbl,$s2,lsl#2]	@ Te4[s2>>24]
        +	and	$i1,lr,$s3		@ i0
        +	eor	$s1,$s1,$i2,lsl#16
        +	and	$i2,lr,$s3,lsr#8	@ i1
        +	eor	$t3,$i3,$t3,lsl#8
        +	and	$i3,lr,$s3,lsr#16	@ i2
        +	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s3>>0]
        +	eor	$s2,$t2,$s2,lsl#24
        +	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s3>>8]
        +	mov	$s3,$s3,lsr#24
        +
        +	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s3>>16]
        +	eor	$s0,$i1,$s0,lsl#8
        +	ldr	$i1,[$key,#0]
        +	ldrb	$s3,[$tbl,$s3,lsl#2]	@ Te4[s3>>24]
        +	eor	$s1,$s1,$i2,lsl#8
        +	ldr	$t1,[$key,#4]
        +	eor	$s2,$s2,$i3,lsl#16
        +	ldr	$t2,[$key,#8]
        +	eor	$s3,$t3,$s3,lsl#24
        +	ldr	$t3,[$key,#12]
        +
        +	eor	$s0,$s0,$i1
        +	eor	$s1,$s1,$t1
        +	eor	$s2,$s2,$t2
        +	eor	$s3,$s3,$t3
        +
        +	sub	$tbl,$tbl,#2
        +	ldr	pc,[sp],#4		@ pop and return
        +.size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
        +
        +.global private_AES_set_encrypt_key
        +.type   private_AES_set_encrypt_key,%function
        +.align	5
        +private_AES_set_encrypt_key:
        +_armv4_AES_set_encrypt_key:
        +	sub	r3,pc,#8		@ AES_set_encrypt_key
        +	teq	r0,#0
        +	moveq	r0,#-1
        +	beq	.Labrt
        +	teq	r2,#0
        +	moveq	r0,#-1
        +	beq	.Labrt
        +
        +	teq	r1,#128
        +	beq	.Lok
        +	teq	r1,#192
        +	beq	.Lok
        +	teq	r1,#256
        +	movne	r0,#-1
        +	bne	.Labrt
        +
        +.Lok:	stmdb   sp!,{r4-r12,lr}
        +	sub	$tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024	@ Te4
        +
        +	mov	$rounds,r0		@ inp
        +	mov	lr,r1			@ bits
        +	mov	$key,r2			@ key
        +
        +#if __ARM_ARCH__<7
        +	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
        +	ldrb	$t1,[$rounds,#2]	@ manner...
        +	ldrb	$t2,[$rounds,#1]
        +	ldrb	$t3,[$rounds,#0]
        +	orr	$s0,$s0,$t1,lsl#8
        +	ldrb	$s1,[$rounds,#7]
        +	orr	$s0,$s0,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#6]
        +	orr	$s0,$s0,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#5]
        +	ldrb	$t3,[$rounds,#4]
        +	orr	$s1,$s1,$t1,lsl#8
        +	ldrb	$s2,[$rounds,#11]
        +	orr	$s1,$s1,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#10]
        +	orr	$s1,$s1,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#9]
        +	ldrb	$t3,[$rounds,#8]
        +	orr	$s2,$s2,$t1,lsl#8
        +	ldrb	$s3,[$rounds,#15]
        +	orr	$s2,$s2,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#14]
        +	orr	$s2,$s2,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#13]
        +	ldrb	$t3,[$rounds,#12]
        +	orr	$s3,$s3,$t1,lsl#8
        +	str	$s0,[$key],#16
        +	orr	$s3,$s3,$t2,lsl#16
        +	str	$s1,[$key,#-12]
        +	orr	$s3,$s3,$t3,lsl#24
        +	str	$s2,[$key,#-8]
        +	str	$s3,[$key,#-4]
        +#else
        +	ldr	$s0,[$rounds,#0]
        +	ldr	$s1,[$rounds,#4]
        +	ldr	$s2,[$rounds,#8]
        +	ldr	$s3,[$rounds,#12]
        +#ifdef __ARMEL__
        +	rev	$s0,$s0
        +	rev	$s1,$s1
        +	rev	$s2,$s2
        +	rev	$s3,$s3
        +#endif
        +	str	$s0,[$key],#16
        +	str	$s1,[$key,#-12]
        +	str	$s2,[$key,#-8]
        +	str	$s3,[$key,#-4]
        +#endif
        +
        +	teq	lr,#128
        +	bne	.Lnot128
        +	mov	$rounds,#10
        +	str	$rounds,[$key,#240-16]
        +	add	$t3,$tbl,#256			@ rcon
        +	mov	lr,#255
        +
        +.L128_loop:
        +	and	$t2,lr,$s3,lsr#24
        +	and	$i1,lr,$s3,lsr#16
        +	ldrb	$t2,[$tbl,$t2]
        +	and	$i2,lr,$s3,lsr#8
        +	ldrb	$i1,[$tbl,$i1]
        +	and	$i3,lr,$s3
        +	ldrb	$i2,[$tbl,$i2]
        +	orr	$t2,$t2,$i1,lsl#24
        +	ldrb	$i3,[$tbl,$i3]
        +	orr	$t2,$t2,$i2,lsl#16
        +	ldr	$t1,[$t3],#4			@ rcon[i++]
        +	orr	$t2,$t2,$i3,lsl#8
        +	eor	$t2,$t2,$t1
        +	eor	$s0,$s0,$t2			@ rk[4]=rk[0]^...
        +	eor	$s1,$s1,$s0			@ rk[5]=rk[1]^rk[4]
        +	str	$s0,[$key],#16
        +	eor	$s2,$s2,$s1			@ rk[6]=rk[2]^rk[5]
        +	str	$s1,[$key,#-12]
        +	eor	$s3,$s3,$s2			@ rk[7]=rk[3]^rk[6]
        +	str	$s2,[$key,#-8]
        +	subs	$rounds,$rounds,#1
        +	str	$s3,[$key,#-4]
        +	bne	.L128_loop
        +	sub	r2,$key,#176
        +	b	.Ldone
        +
        +.Lnot128:
        +#if __ARM_ARCH__<7
        +	ldrb	$i2,[$rounds,#19]
        +	ldrb	$t1,[$rounds,#18]
        +	ldrb	$t2,[$rounds,#17]
        +	ldrb	$t3,[$rounds,#16]
        +	orr	$i2,$i2,$t1,lsl#8
        +	ldrb	$i3,[$rounds,#23]
        +	orr	$i2,$i2,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#22]
        +	orr	$i2,$i2,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#21]
        +	ldrb	$t3,[$rounds,#20]
        +	orr	$i3,$i3,$t1,lsl#8
        +	orr	$i3,$i3,$t2,lsl#16
        +	str	$i2,[$key],#8
        +	orr	$i3,$i3,$t3,lsl#24
        +	str	$i3,[$key,#-4]
        +#else
        +	ldr	$i2,[$rounds,#16]
        +	ldr	$i3,[$rounds,#20]
        +#ifdef __ARMEL__
        +	rev	$i2,$i2
        +	rev	$i3,$i3
        +#endif
        +	str	$i2,[$key],#8
        +	str	$i3,[$key,#-4]
        +#endif
        +
        +	teq	lr,#192
        +	bne	.Lnot192
        +	mov	$rounds,#12
        +	str	$rounds,[$key,#240-24]
        +	add	$t3,$tbl,#256			@ rcon
        +	mov	lr,#255
        +	mov	$rounds,#8
        +
        +.L192_loop:
        +	and	$t2,lr,$i3,lsr#24
        +	and	$i1,lr,$i3,lsr#16
        +	ldrb	$t2,[$tbl,$t2]
        +	and	$i2,lr,$i3,lsr#8
        +	ldrb	$i1,[$tbl,$i1]
        +	and	$i3,lr,$i3
        +	ldrb	$i2,[$tbl,$i2]
        +	orr	$t2,$t2,$i1,lsl#24
        +	ldrb	$i3,[$tbl,$i3]
        +	orr	$t2,$t2,$i2,lsl#16
        +	ldr	$t1,[$t3],#4			@ rcon[i++]
        +	orr	$t2,$t2,$i3,lsl#8
        +	eor	$i3,$t2,$t1
        +	eor	$s0,$s0,$i3			@ rk[6]=rk[0]^...
        +	eor	$s1,$s1,$s0			@ rk[7]=rk[1]^rk[6]
        +	str	$s0,[$key],#24
        +	eor	$s2,$s2,$s1			@ rk[8]=rk[2]^rk[7]
        +	str	$s1,[$key,#-20]
        +	eor	$s3,$s3,$s2			@ rk[9]=rk[3]^rk[8]
        +	str	$s2,[$key,#-16]
        +	subs	$rounds,$rounds,#1
        +	str	$s3,[$key,#-12]
        +	subeq	r2,$key,#216
        +	beq	.Ldone
        +
        +	ldr	$i1,[$key,#-32]
        +	ldr	$i2,[$key,#-28]
        +	eor	$i1,$i1,$s3			@ rk[10]=rk[4]^rk[9]
        +	eor	$i3,$i2,$i1			@ rk[11]=rk[5]^rk[10]
        +	str	$i1,[$key,#-8]
        +	str	$i3,[$key,#-4]
        +	b	.L192_loop
        +
        +.Lnot192:
        +#if __ARM_ARCH__<7
        +	ldrb	$i2,[$rounds,#27]
        +	ldrb	$t1,[$rounds,#26]
        +	ldrb	$t2,[$rounds,#25]
        +	ldrb	$t3,[$rounds,#24]
        +	orr	$i2,$i2,$t1,lsl#8
        +	ldrb	$i3,[$rounds,#31]
        +	orr	$i2,$i2,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#30]
        +	orr	$i2,$i2,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#29]
        +	ldrb	$t3,[$rounds,#28]
        +	orr	$i3,$i3,$t1,lsl#8
        +	orr	$i3,$i3,$t2,lsl#16
        +	str	$i2,[$key],#8
        +	orr	$i3,$i3,$t3,lsl#24
        +	str	$i3,[$key,#-4]
        +#else
        +	ldr	$i2,[$rounds,#24]
        +	ldr	$i3,[$rounds,#28]
        +#ifdef __ARMEL__
        +	rev	$i2,$i2
        +	rev	$i3,$i3
        +#endif
        +	str	$i2,[$key],#8
        +	str	$i3,[$key,#-4]
        +#endif
        +
        +	mov	$rounds,#14
        +	str	$rounds,[$key,#240-32]
        +	add	$t3,$tbl,#256			@ rcon
        +	mov	lr,#255
        +	mov	$rounds,#7
        +
        +.L256_loop:
        +	and	$t2,lr,$i3,lsr#24
        +	and	$i1,lr,$i3,lsr#16
        +	ldrb	$t2,[$tbl,$t2]
        +	and	$i2,lr,$i3,lsr#8
        +	ldrb	$i1,[$tbl,$i1]
        +	and	$i3,lr,$i3
        +	ldrb	$i2,[$tbl,$i2]
        +	orr	$t2,$t2,$i1,lsl#24
        +	ldrb	$i3,[$tbl,$i3]
        +	orr	$t2,$t2,$i2,lsl#16
        +	ldr	$t1,[$t3],#4			@ rcon[i++]
        +	orr	$t2,$t2,$i3,lsl#8
        +	eor	$i3,$t2,$t1
        +	eor	$s0,$s0,$i3			@ rk[8]=rk[0]^...
        +	eor	$s1,$s1,$s0			@ rk[9]=rk[1]^rk[8]
        +	str	$s0,[$key],#32
        +	eor	$s2,$s2,$s1			@ rk[10]=rk[2]^rk[9]
        +	str	$s1,[$key,#-28]
        +	eor	$s3,$s3,$s2			@ rk[11]=rk[3]^rk[10]
        +	str	$s2,[$key,#-24]
        +	subs	$rounds,$rounds,#1
        +	str	$s3,[$key,#-20]
        +	subeq	r2,$key,#256
        +	beq	.Ldone
        +
        +	and	$t2,lr,$s3
        +	and	$i1,lr,$s3,lsr#8
        +	ldrb	$t2,[$tbl,$t2]
        +	and	$i2,lr,$s3,lsr#16
        +	ldrb	$i1,[$tbl,$i1]
        +	and	$i3,lr,$s3,lsr#24
        +	ldrb	$i2,[$tbl,$i2]
        +	orr	$t2,$t2,$i1,lsl#8
        +	ldrb	$i3,[$tbl,$i3]
        +	orr	$t2,$t2,$i2,lsl#16
        +	ldr	$t1,[$key,#-48]
        +	orr	$t2,$t2,$i3,lsl#24
        +
        +	ldr	$i1,[$key,#-44]
        +	ldr	$i2,[$key,#-40]
        +	eor	$t1,$t1,$t2			@ rk[12]=rk[4]^...
        +	ldr	$i3,[$key,#-36]
        +	eor	$i1,$i1,$t1			@ rk[13]=rk[5]^rk[12]
        +	str	$t1,[$key,#-16]
        +	eor	$i2,$i2,$i1			@ rk[14]=rk[6]^rk[13]
        +	str	$i1,[$key,#-12]
        +	eor	$i3,$i3,$i2			@ rk[15]=rk[7]^rk[14]
        +	str	$i2,[$key,#-8]
        +	str	$i3,[$key,#-4]
        +	b	.L256_loop
        +
        +.Ldone:	mov	r0,#0
        +	ldmia   sp!,{r4-r12,lr}
        +.Labrt:	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +.size	private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
        +
        +.global private_AES_set_decrypt_key
        +.type   private_AES_set_decrypt_key,%function
        +.align	5
        +private_AES_set_decrypt_key:
        +	str	lr,[sp,#-4]!            @ push lr
        +	bl	_armv4_AES_set_encrypt_key
        +	teq	r0,#0
        +	ldrne	lr,[sp],#4              @ pop lr
        +	bne	.Labrt
        +
        +	stmdb   sp!,{r4-r12}
        +
        +	ldr	$rounds,[r2,#240]	@ AES_set_encrypt_key preserves r2,
        +	mov	$key,r2			@ which is AES_KEY *key
        +	mov	$i1,r2
        +	add	$i2,r2,$rounds,lsl#4
        +
        +.Linv:	ldr	$s0,[$i1]
        +	ldr	$s1,[$i1,#4]
        +	ldr	$s2,[$i1,#8]
        +	ldr	$s3,[$i1,#12]
        +	ldr	$t1,[$i2]
        +	ldr	$t2,[$i2,#4]
        +	ldr	$t3,[$i2,#8]
        +	ldr	$i3,[$i2,#12]
        +	str	$s0,[$i2],#-16
        +	str	$s1,[$i2,#16+4]
        +	str	$s2,[$i2,#16+8]
        +	str	$s3,[$i2,#16+12]
        +	str	$t1,[$i1],#16
        +	str	$t2,[$i1,#-12]
        +	str	$t3,[$i1,#-8]
        +	str	$i3,[$i1,#-4]
        +	teq	$i1,$i2
        +	bne	.Linv
        +___
        +$mask80=$i1;
        +$mask1b=$i2;
        +$mask7f=$i3;
        +$code.=<<___;
        +	ldr	$s0,[$key,#16]!		@ prefetch tp1
        +	mov	$mask80,#0x80
        +	mov	$mask1b,#0x1b
        +	orr	$mask80,$mask80,#0x8000
        +	orr	$mask1b,$mask1b,#0x1b00
        +	orr	$mask80,$mask80,$mask80,lsl#16
        +	orr	$mask1b,$mask1b,$mask1b,lsl#16
        +	sub	$rounds,$rounds,#1
        +	mvn	$mask7f,$mask80
        +	mov	$rounds,$rounds,lsl#2	@ (rounds-1)*4
        +
        +.Lmix:	and	$t1,$s0,$mask80
        +	and	$s1,$s0,$mask7f
        +	sub	$t1,$t1,$t1,lsr#7
        +	and	$t1,$t1,$mask1b
        +	eor	$s1,$t1,$s1,lsl#1	@ tp2
        +
        +	and	$t1,$s1,$mask80
        +	and	$s2,$s1,$mask7f
        +	sub	$t1,$t1,$t1,lsr#7
        +	and	$t1,$t1,$mask1b
        +	eor	$s2,$t1,$s2,lsl#1	@ tp4
        +
        +	and	$t1,$s2,$mask80
        +	and	$s3,$s2,$mask7f
        +	sub	$t1,$t1,$t1,lsr#7
        +	and	$t1,$t1,$mask1b
        +	eor	$s3,$t1,$s3,lsl#1	@ tp8
        +
        +	eor	$t1,$s1,$s2
        +	eor	$t2,$s0,$s3		@ tp9
        +	eor	$t1,$t1,$s3		@ tpe
        +	eor	$t1,$t1,$s1,ror#24
        +	eor	$t1,$t1,$t2,ror#24	@ ^= ROTATE(tpb=tp9^tp2,8)
        +	eor	$t1,$t1,$s2,ror#16
        +	eor	$t1,$t1,$t2,ror#16	@ ^= ROTATE(tpd=tp9^tp4,16)
        +	eor	$t1,$t1,$t2,ror#8	@ ^= ROTATE(tp9,24)
        +
        +	ldr	$s0,[$key,#4]		@ prefetch tp1
        +	str	$t1,[$key],#4
        +	subs	$rounds,$rounds,#1
        +	bne	.Lmix
        +
        +	mov	r0,#0
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r12,pc}
        +#else
        +	ldmia   sp!,{r4-r12,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size	private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
        +
        +.type	AES_Td,%object
        +.align	5
        +AES_Td:
        +.word	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
        +.word	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
        +.word	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
        +.word	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
        +.word	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
        +.word	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
        +.word	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
        +.word	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
        +.word	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
        +.word	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
        +.word	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
        +.word	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
        +.word	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
        +.word	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
        +.word	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
        +.word	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
        +.word	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
        +.word	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
        +.word	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
        +.word	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
        +.word	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
        +.word	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
        +.word	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
        +.word	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
        +.word	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
        +.word	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
        +.word	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
        +.word	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
        +.word	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
        +.word	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
        +.word	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
        +.word	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
        +.word	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
        +.word	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
        +.word	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
        +.word	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
        +.word	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
        +.word	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
        +.word	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
        +.word	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
        +.word	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
        +.word	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
        +.word	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
        +.word	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
        +.word	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
        +.word	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
        +.word	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
        +.word	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
        +.word	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
        +.word	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
        +.word	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
        +.word	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
        +.word	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
        +.word	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
        +.word	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
        +.word	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
        +.word	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
        +.word	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
        +.word	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
        +.word	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
        +.word	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
        +.word	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
        +.word	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
        +.word	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
        +@ Td4[256]
        +.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
        +.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +.size	AES_Td,.-AES_Td
        +
        +@ void AES_decrypt(const unsigned char *in, unsigned char *out,
        +@ 		 const AES_KEY *key) {
        +.global AES_decrypt
        +.type   AES_decrypt,%function
        +.align	5
        +AES_decrypt:
        +	sub	r3,pc,#8		@ AES_decrypt
        +	stmdb   sp!,{r1,r4-r12,lr}
        +	mov	$rounds,r0		@ inp
        +	mov	$key,r2
        +	sub	$tbl,r3,#AES_decrypt-AES_Td		@ Td
        +#if __ARM_ARCH__<7
        +	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
        +	ldrb	$t1,[$rounds,#2]	@ manner...
        +	ldrb	$t2,[$rounds,#1]
        +	ldrb	$t3,[$rounds,#0]
        +	orr	$s0,$s0,$t1,lsl#8
        +	ldrb	$s1,[$rounds,#7]
        +	orr	$s0,$s0,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#6]
        +	orr	$s0,$s0,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#5]
        +	ldrb	$t3,[$rounds,#4]
        +	orr	$s1,$s1,$t1,lsl#8
        +	ldrb	$s2,[$rounds,#11]
        +	orr	$s1,$s1,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#10]
        +	orr	$s1,$s1,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#9]
        +	ldrb	$t3,[$rounds,#8]
        +	orr	$s2,$s2,$t1,lsl#8
        +	ldrb	$s3,[$rounds,#15]
        +	orr	$s2,$s2,$t2,lsl#16
        +	ldrb	$t1,[$rounds,#14]
        +	orr	$s2,$s2,$t3,lsl#24
        +	ldrb	$t2,[$rounds,#13]
        +	ldrb	$t3,[$rounds,#12]
        +	orr	$s3,$s3,$t1,lsl#8
        +	orr	$s3,$s3,$t2,lsl#16
        +	orr	$s3,$s3,$t3,lsl#24
        +#else
        +	ldr	$s0,[$rounds,#0]
        +	ldr	$s1,[$rounds,#4]
        +	ldr	$s2,[$rounds,#8]
        +	ldr	$s3,[$rounds,#12]
        +#ifdef __ARMEL__
        +	rev	$s0,$s0
        +	rev	$s1,$s1
        +	rev	$s2,$s2
        +	rev	$s3,$s3
        +#endif
        +#endif
        +	bl	_armv4_AES_decrypt
        +
        +	ldr	$rounds,[sp],#4		@ pop out
        +#if __ARM_ARCH__>=7
        +#ifdef __ARMEL__
        +	rev	$s0,$s0
        +	rev	$s1,$s1
        +	rev	$s2,$s2
        +	rev	$s3,$s3
        +#endif
        +	str	$s0,[$rounds,#0]
        +	str	$s1,[$rounds,#4]
        +	str	$s2,[$rounds,#8]
        +	str	$s3,[$rounds,#12]
        +#else
        +	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
        +	mov	$t2,$s0,lsr#16		@ manner...
        +	mov	$t3,$s0,lsr#8
        +	strb	$t1,[$rounds,#0]
        +	strb	$t2,[$rounds,#1]
        +	mov	$t1,$s1,lsr#24
        +	strb	$t3,[$rounds,#2]
        +	mov	$t2,$s1,lsr#16
        +	strb	$s0,[$rounds,#3]
        +	mov	$t3,$s1,lsr#8
        +	strb	$t1,[$rounds,#4]
        +	strb	$t2,[$rounds,#5]
        +	mov	$t1,$s2,lsr#24
        +	strb	$t3,[$rounds,#6]
        +	mov	$t2,$s2,lsr#16
        +	strb	$s1,[$rounds,#7]
        +	mov	$t3,$s2,lsr#8
        +	strb	$t1,[$rounds,#8]
        +	strb	$t2,[$rounds,#9]
        +	mov	$t1,$s3,lsr#24
        +	strb	$t3,[$rounds,#10]
        +	mov	$t2,$s3,lsr#16
        +	strb	$s2,[$rounds,#11]
        +	mov	$t3,$s3,lsr#8
        +	strb	$t1,[$rounds,#12]
        +	strb	$t2,[$rounds,#13]
        +	strb	$t3,[$rounds,#14]
        +	strb	$s3,[$rounds,#15]
        +#endif
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r12,pc}
        +#else
        +	ldmia   sp!,{r4-r12,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size	AES_decrypt,.-AES_decrypt
        +
        +.type   _armv4_AES_decrypt,%function
        +.align	2
        +_armv4_AES_decrypt:
        +	str	lr,[sp,#-4]!		@ push lr
        +	ldmia	$key!,{$t1-$i1}
        +	eor	$s0,$s0,$t1
        +	ldr	$rounds,[$key,#240-16]
        +	eor	$s1,$s1,$t2
        +	eor	$s2,$s2,$t3
        +	eor	$s3,$s3,$i1
        +	sub	$rounds,$rounds,#1
        +	mov	lr,#255
        +
        +	and	$i1,lr,$s0,lsr#16
        +	and	$i2,lr,$s0,lsr#8
        +	and	$i3,lr,$s0
        +	mov	$s0,$s0,lsr#24
        +.Ldec_loop:
        +	ldr	$t1,[$tbl,$i1,lsl#2]	@ Td1[s0>>16]
        +	and	$i1,lr,$s1		@ i0
        +	ldr	$t2,[$tbl,$i2,lsl#2]	@ Td2[s0>>8]
        +	and	$i2,lr,$s1,lsr#16
        +	ldr	$t3,[$tbl,$i3,lsl#2]	@ Td3[s0>>0]
        +	and	$i3,lr,$s1,lsr#8
        +	ldr	$s0,[$tbl,$s0,lsl#2]	@ Td0[s0>>24]
        +	mov	$s1,$s1,lsr#24
        +
        +	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td3[s1>>0]
        +	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td1[s1>>16]
        +	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td2[s1>>8]
        +	eor	$s0,$s0,$i1,ror#24
        +	ldr	$s1,[$tbl,$s1,lsl#2]	@ Td0[s1>>24]
        +	and	$i1,lr,$s2,lsr#8	@ i0
        +	eor	$t2,$i2,$t2,ror#8
        +	and	$i2,lr,$s2		@ i1
        +	eor	$t3,$i3,$t3,ror#8
        +	and	$i3,lr,$s2,lsr#16
        +	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td2[s2>>8]
        +	eor	$s1,$s1,$t1,ror#8
        +	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td3[s2>>0]
        +	mov	$s2,$s2,lsr#24
        +
        +	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td1[s2>>16]
        +	eor	$s0,$s0,$i1,ror#16
        +	ldr	$s2,[$tbl,$s2,lsl#2]	@ Td0[s2>>24]
        +	and	$i1,lr,$s3,lsr#16	@ i0
        +	eor	$s1,$s1,$i2,ror#24
        +	and	$i2,lr,$s3,lsr#8	@ i1
        +	eor	$t3,$i3,$t3,ror#8
        +	and	$i3,lr,$s3		@ i2
        +	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td1[s3>>16]
        +	eor	$s2,$s2,$t2,ror#8
        +	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td2[s3>>8]
        +	mov	$s3,$s3,lsr#24
        +
        +	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td3[s3>>0]
        +	eor	$s0,$s0,$i1,ror#8
        +	ldr	$i1,[$key],#16
        +	eor	$s1,$s1,$i2,ror#16
        +	ldr	$s3,[$tbl,$s3,lsl#2]	@ Td0[s3>>24]
        +	eor	$s2,$s2,$i3,ror#24
        +
        +	ldr	$t1,[$key,#-12]
        +	eor	$s0,$s0,$i1
        +	ldr	$t2,[$key,#-8]
        +	eor	$s3,$s3,$t3,ror#8
        +	ldr	$t3,[$key,#-4]
        +	and	$i1,lr,$s0,lsr#16
        +	eor	$s1,$s1,$t1
        +	and	$i2,lr,$s0,lsr#8
        +	eor	$s2,$s2,$t2
        +	and	$i3,lr,$s0
        +	eor	$s3,$s3,$t3
        +	mov	$s0,$s0,lsr#24
        +
        +	subs	$rounds,$rounds,#1
        +	bne	.Ldec_loop
        +
        +	add	$tbl,$tbl,#1024
        +
        +	ldr	$t2,[$tbl,#0]		@ prefetch Td4
        +	ldr	$t3,[$tbl,#32]
        +	ldr	$t1,[$tbl,#64]
        +	ldr	$t2,[$tbl,#96]
        +	ldr	$t3,[$tbl,#128]
        +	ldr	$t1,[$tbl,#160]
        +	ldr	$t2,[$tbl,#192]
        +	ldr	$t3,[$tbl,#224]
        +
        +	ldrb	$s0,[$tbl,$s0]		@ Td4[s0>>24]
        +	ldrb	$t1,[$tbl,$i1]		@ Td4[s0>>16]
        +	and	$i1,lr,$s1		@ i0
        +	ldrb	$t2,[$tbl,$i2]		@ Td4[s0>>8]
        +	and	$i2,lr,$s1,lsr#16
        +	ldrb	$t3,[$tbl,$i3]		@ Td4[s0>>0]
        +	and	$i3,lr,$s1,lsr#8
        +
        +	ldrb	$i1,[$tbl,$i1]		@ Td4[s1>>0]
        +	ldrb	$s1,[$tbl,$s1,lsr#24]	@ Td4[s1>>24]
        +	ldrb	$i2,[$tbl,$i2]		@ Td4[s1>>16]
        +	eor	$s0,$i1,$s0,lsl#24
        +	ldrb	$i3,[$tbl,$i3]		@ Td4[s1>>8]
        +	eor	$s1,$t1,$s1,lsl#8
        +	and	$i1,lr,$s2,lsr#8	@ i0
        +	eor	$t2,$t2,$i2,lsl#8
        +	and	$i2,lr,$s2		@ i1
        +	ldrb	$i1,[$tbl,$i1]		@ Td4[s2>>8]
        +	eor	$t3,$t3,$i3,lsl#8
        +	ldrb	$i2,[$tbl,$i2]		@ Td4[s2>>0]
        +	and	$i3,lr,$s2,lsr#16
        +
        +	ldrb	$s2,[$tbl,$s2,lsr#24]	@ Td4[s2>>24]
        +	eor	$s0,$s0,$i1,lsl#8
        +	ldrb	$i3,[$tbl,$i3]		@ Td4[s2>>16]
        +	eor	$s1,$i2,$s1,lsl#16
        +	and	$i1,lr,$s3,lsr#16	@ i0
        +	eor	$s2,$t2,$s2,lsl#16
        +	and	$i2,lr,$s3,lsr#8	@ i1
        +	ldrb	$i1,[$tbl,$i1]		@ Td4[s3>>16]
        +	eor	$t3,$t3,$i3,lsl#16
        +	ldrb	$i2,[$tbl,$i2]		@ Td4[s3>>8]
        +	and	$i3,lr,$s3		@ i2
        +
        +	ldrb	$i3,[$tbl,$i3]		@ Td4[s3>>0]
        +	ldrb	$s3,[$tbl,$s3,lsr#24]	@ Td4[s3>>24]
        +	eor	$s0,$s0,$i1,lsl#16
        +	ldr	$i1,[$key,#0]
        +	eor	$s1,$s1,$i2,lsl#8
        +	ldr	$t1,[$key,#4]
        +	eor	$s2,$i3,$s2,lsl#8
        +	ldr	$t2,[$key,#8]
        +	eor	$s3,$t3,$s3,lsl#24
        +	ldr	$t3,[$key,#12]
        +
        +	eor	$s0,$s0,$i1
        +	eor	$s1,$s1,$t1
        +	eor	$s2,$s2,$t2
        +	eor	$s3,$s3,$t3
        +
        +	sub	$tbl,$tbl,#1024
        +	ldr	pc,[sp],#4		@ pop and return
        +.size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
        +.asciz	"AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +___
        +
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT;	# enforce flush
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-ia64.S b/vendor/openssl/openssl/crypto/aes/asm/aes-ia64.S
        new file mode 100644
        index 000000000..7f6c4c366
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-ia64.S
        @@ -0,0 +1,1123 @@
        +// ====================================================================
        +// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +// project. Rights for redistribution and usage in source and binary
        +// forms are granted according to the OpenSSL license.
        +// ====================================================================
        +//
        +// What's wrong with compiler generated code? Compiler never uses
        +// variable 'shr' which is pairable with 'extr'/'dep' instructions.
        +// Then it uses 'zxt' which is an I-type, but can be replaced with
        +// 'and' which in turn can be assigned to M-port [there're double as
        +// much M-ports as there're I-ports on Itanium 2]. By sacrificing few
        +// registers for small constants (255, 24 and 16) to be used with
        +// 'shr' and 'and' instructions I can achieve better ILP, Intruction
        +// Level Parallelism, and performance. This code outperforms GCC 3.3
        +// generated code by over factor of 2 (two), GCC 3.4 - by 70% and
        +// HP C - by 40%. Measured best-case scenario, i.e. aligned
        +// big-endian input, ECB timing on Itanium 2 is (18 + 13*rounds)
        +// ticks per block, or 9.25 CPU cycles per byte for 128 bit key.
        +
        +// Version 1.2 mitigates the hazard of cache-timing attacks by
        +// a) compressing S-boxes from 8KB to 2KB+256B, b) scheduling
        +// references to S-boxes for L2 cache latency, c) prefetching T[ed]4
        +// prior last round. As result performance dropped to (26 + 15*rounds)
        +// ticks per block or 11 cycles per byte processed with 128-bit key.
        +// This is ~16% deterioration. For reference Itanium 2 L1 cache has
        +// 64 bytes line size and L2 - 128 bytes...
        +
        +.ident	"aes-ia64.S, version 1.2"
        +.ident	"IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
        +.explicit
        +.text
        +
        +rk0=r8;     rk1=r9;
        +
        +pfssave=r2;
        +lcsave=r10;
        +prsave=r3;
        +maskff=r11;
        +twenty4=r14;
        +sixteen=r15;
        +
        +te00=r16;   te11=r17;   te22=r18;   te33=r19;
        +te01=r20;   te12=r21;   te23=r22;   te30=r23;
        +te02=r24;   te13=r25;   te20=r26;   te31=r27;
        +te03=r28;   te10=r29;   te21=r30;   te32=r31;
        +
        +// these are rotating...
        +t0=r32;     s0=r33;
        +t1=r34;     s1=r35;
        +t2=r36;     s2=r37;
        +t3=r38;     s3=r39;
        +
        +te0=r40;    te1=r41;    te2=r42;    te3=r43;
        +
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +# define ADDP	addp4
        +#else
        +# define ADDP	add
        +#endif
        +
        +// Offsets from Te0
        +#define TE0	0
        +#define TE2	2
        +#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
        +#define TE1	3
        +#define TE3	1
        +#else
        +#define TE1	1
        +#define TE3	3
        +#endif
        +
        +// This implies that AES_KEY comprises 32-bit key schedule elements
        +// even on LP64 platforms.
        +#ifndef	KSZ
        +# define KSZ	4
        +# define LDKEY	ld4
        +#endif
        +
        +.proc	_ia64_AES_encrypt#
        +// Input:	rk0-rk1
        +//		te0
        +//		te3	as AES_KEY->rounds!!!
        +//		s0-s3
        +//		maskff,twenty4,sixteen
        +// Output:	r16,r20,r24,r28 as s0-s3
        +// Clobber:	r16-r31,rk0-rk1,r32-r43
        +.align	32
        +_ia64_AES_encrypt:
        +	.prologue
        +	.altrp	b6
        +	.body
        +{ .mmi;	alloc	r16=ar.pfs,12,0,0,8
        +	LDKEY	t0=[rk0],2*KSZ
        +	mov	pr.rot=1<<16	}
        +{ .mmi;	LDKEY	t1=[rk1],2*KSZ
        +	add	te1=TE1,te0
        +	add	te3=-3,te3	};;
        +{ .mib;	LDKEY	t2=[rk0],2*KSZ
        +	mov	ar.ec=2		}
        +{ .mib;	LDKEY	t3=[rk1],2*KSZ
        +	add	te2=TE2,te0
        +	brp.loop.imp	.Le_top,.Le_end-16	};;
        +
        +{ .mmi;	xor	s0=s0,t0
        +	xor	s1=s1,t1
        +	mov	ar.lc=te3	}
        +{ .mmi;	xor	s2=s2,t2
        +	xor	s3=s3,t3
        +	add	te3=TE3,te0	};;
        +
        +.align	32
        +.Le_top:
        +{ .mmi;	(p0)	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
        +	(p0)	and	te33=s3,maskff		// 0/0:s3&0xff
        +	(p0)	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
        +{ .mmi; (p0)	LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
        +	(p0)	and	te30=s0,maskff		// 0/1:s0&0xff
        +	(p0)	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
        +{ .mmi;	(p0)	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
        +	(p0)	shladd	te33=te33,3,te3		// 1/0:te0+s0>>24
        +	(p0)	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
        +{ .mmi;	(p0)	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
        +	(p0)	shladd	te30=te30,3,te3		// 1/1:te3+s0
        +	(p0)	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
        +{ .mmi;	(p0)	ld4	te33=[te33]		// 2/0:te3[s3&0xff]
        +	(p0)	shladd	te22=te22,3,te2		// 2/0:te2+s2>>8&0xff
        +	(p0)	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
        +{ .mmi;	(p0)	ld4	te30=[te30]		// 2/1:te3[s0]
        +	(p0)	shladd	te23=te23,3,te2		// 2/1:te2+s3>>8
        +	(p0)	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
        +{ .mmi;	(p0)	ld4	te22=[te22]		// 3/0:te2[s2>>8]
        +	(p0)	shladd	te20=te20,3,te2		// 3/2:te2+s0>>8
        +	(p0)	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
        +{ .mmi;	(p0)	ld4	te23=[te23]		// 3/1:te2[s3>>8]
        +	(p0)	shladd	te00=te00,3,te0		// 3/0:te0+s0>>24
        +	(p0)	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
        +{ .mmi;	(p0)	ld4	te20=[te20]		// 4/2:te2[s0>>8]
        +	(p0)	shladd	te21=te21,3,te2		// 4/3:te3+s2
        +	(p0)	extr.u	te11=s1,16,8	}	// 4/0:s1>>16&0xff
        +{ .mmi;	(p0)	ld4	te00=[te00]		// 4/0:te0[s0>>24]
        +	(p0)	shladd	te01=te01,3,te0		// 4/1:te0+s1>>24
        +	(p0)	shr.u	te13=s3,sixteen	};;	// 4/2:s3>>16
        +{ .mmi;	(p0)	ld4	te21=[te21]		// 5/3:te2[s1>>8]
        +	(p0)	shladd	te11=te11,3,te1		// 5/0:te1+s1>>16
        +	(p0)	extr.u	te12=s2,16,8	}	// 5/1:s2>>16&0xff
        +{ .mmi;	(p0)	ld4	te01=[te01]		// 5/1:te0[s1>>24]
        +	(p0)	shladd	te02=te02,3,te0		// 5/2:te0+s2>>24
        +	(p0)	and	te31=s1,maskff	};;	// 5/2:s1&0xff
        +{ .mmi;	(p0)	ld4	te11=[te11]		// 6/0:te1[s1>>16]
        +	(p0)	shladd	te12=te12,3,te1		// 6/1:te1+s2>>16
        +	(p0)	extr.u	te10=s0,16,8	}	// 6/3:s0>>16&0xff
        +{ .mmi;	(p0)	ld4	te02=[te02]		// 6/2:te0[s2>>24]
        +	(p0)	shladd	te03=te03,3,te0		// 6/3:te1+s0>>16
        +	(p0)	and	te32=s2,maskff	};;	// 6/3:s2&0xff
        +
        +{ .mmi;	(p0)	ld4	te12=[te12]		// 7/1:te1[s2>>16]
        +	(p0)	shladd	te31=te31,3,te3		// 7/2:te3+s1&0xff
        +	(p0)	and	te13=te13,maskff}	// 7/2:s3>>16&0xff
        +{ .mmi;	(p0)	ld4	te03=[te03]		// 7/3:te0[s3>>24]
        +	(p0)	shladd	te32=te32,3,te3		// 7/3:te3+s2
        +	(p0)	xor	t0=t0,te33	};;	// 7/0:
        +{ .mmi;	(p0)	ld4	te31=[te31]		// 8/2:te3[s1]
        +	(p0)	shladd	te13=te13,3,te1		// 8/2:te1+s3>>16
        +	(p0)	xor	t0=t0,te22	}	// 8/0:
        +{ .mmi;	(p0)	ld4	te32=[te32]		// 8/3:te3[s2]
        +	(p0)	shladd	te10=te10,3,te1		// 8/3:te1+s0>>16
        +	(p0)	xor	t1=t1,te30	};;	// 8/1:
        +{ .mmi;	(p0)	ld4	te13=[te13]		// 9/2:te1[s3>>16]
        +	(p0)	ld4	te10=[te10]		// 9/3:te1[s0>>16]
        +	(p0)	xor	t0=t0,te00	};;	// 9/0:		!L2 scheduling
        +{ .mmi;	(p0)	xor	t1=t1,te23		// 10[9]/1:	
        +	(p0)	xor	t2=t2,te20		// 10[9]/2:
        +	(p0)	xor	t3=t3,te21	};;	// 10[9]/3:
        +{ .mmi;	(p0)	xor	t0=t0,te11		// 11[10]/0:done!
        +	(p0)	xor	t1=t1,te01		// 11[10]/1:
        +	(p0)	xor	t2=t2,te02	};;	// 11[10]/2:	!L2 scheduling
        +{ .mmi;	(p0)	xor	t3=t3,te03		// 12[10]/3:
        +	(p16)	cmp.eq	p0,p17=r0,r0 	};;	// 12[10]/clear (p17)
        +{ .mmi;	(p0)	xor	t1=t1,te12		// 13[11]/1:done!
        +	(p0)	xor	t2=t2,te31		// 13[11]/2:
        +	(p0)	xor	t3=t3,te32	}	// 13[11]/3:
        +{ .mmi;	(p17)	add	te0=2048,te0		// 13[11]/
        +	(p17)	add	te1=2048+64-TE1,te1};;	// 13[11]/
        +{ .mib;	(p0)	xor	t2=t2,te13		// 14[12]/2:done!
        +	(p17)	add	te2=2048+128-TE2,te2}	// 14[12]/
        +{ .mib;	(p0)	xor	t3=t3,te10		// 14[12]/3:done!
        +	(p17)	add	te3=2048+192-TE3,te3	// 14[12]/
        +	br.ctop.sptk	.Le_top		};;
        +.Le_end:
        +
        +
        +{ .mmi;	ld8	te12=[te0]		// prefetch Te4
        +	ld8	te31=[te1]	}
        +{ .mmi;	ld8	te10=[te2]
        +	ld8	te32=[te3]	}
        +
        +{ .mmi;	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
        +	and	te33=s3,maskff		// 0/0:s3&0xff
        +	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
        +{ .mmi; LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
        +	and	te30=s0,maskff		// 0/1:s0&0xff
        +	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
        +{ .mmi;	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
        +	add	te33=te33,te0		// 1/0:te0+s0>>24
        +	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
        +{ .mmi;	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
        +	add	te30=te30,te0		// 1/1:te0+s0
        +	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
        +{ .mmi;	ld1	te33=[te33]		// 2/0:te0[s3&0xff]
        +	add	te22=te22,te0		// 2/0:te0+s2>>8&0xff
        +	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
        +{ .mmi;	ld1	te30=[te30]		// 2/1:te0[s0]
        +	add	te23=te23,te0		// 2/1:te0+s3>>8
        +	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
        +{ .mmi;	ld1	te22=[te22]		// 3/0:te0[s2>>8]
        +	add	te20=te20,te0		// 3/2:te0+s0>>8
        +	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
        +{ .mmi;	ld1	te23=[te23]		// 3/1:te0[s3>>8]
        +	add	te00=te00,te0		// 3/0:te0+s0>>24
        +	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
        +{ .mmi;	ld1	te20=[te20]		// 4/2:te0[s0>>8]
        +	add	te21=te21,te0		// 4/3:te0+s2
        +	extr.u	te11=s1,16,8	}	// 4/0:s1>>16&0xff
        +{ .mmi;	ld1	te00=[te00]		// 4/0:te0[s0>>24]
        +	add	te01=te01,te0		// 4/1:te0+s1>>24
        +	shr.u	te13=s3,sixteen	};;	// 4/2:s3>>16
        +{ .mmi;	ld1	te21=[te21]		// 5/3:te0[s1>>8]
        +	add	te11=te11,te0		// 5/0:te0+s1>>16
        +	extr.u	te12=s2,16,8	}	// 5/1:s2>>16&0xff
        +{ .mmi;	ld1	te01=[te01]		// 5/1:te0[s1>>24]
        +	add	te02=te02,te0		// 5/2:te0+s2>>24
        +	and	te31=s1,maskff	};;	// 5/2:s1&0xff
        +{ .mmi;	ld1	te11=[te11]		// 6/0:te0[s1>>16]
        +	add	te12=te12,te0		// 6/1:te0+s2>>16
        +	extr.u	te10=s0,16,8	}	// 6/3:s0>>16&0xff
        +{ .mmi;	ld1	te02=[te02]		// 6/2:te0[s2>>24]
        +	add	te03=te03,te0		// 6/3:te0+s0>>16
        +	and	te32=s2,maskff	};;	// 6/3:s2&0xff
        +
        +{ .mmi;	ld1	te12=[te12]		// 7/1:te0[s2>>16]
        +	add	te31=te31,te0		// 7/2:te0+s1&0xff
        +	dep	te33=te22,te33,8,8}	// 7/0:
        +{ .mmi;	ld1	te03=[te03]		// 7/3:te0[s3>>24]
        +	add	te32=te32,te0		// 7/3:te0+s2
        +	and	te13=te13,maskff};;	// 7/2:s3>>16&0xff
        +{ .mmi;	ld1	te31=[te31]		// 8/2:te0[s1]
        +	add	te13=te13,te0		// 8/2:te0+s3>>16
        +	dep	te30=te23,te30,8,8}	// 8/1:
        +{ .mmi;	ld1	te32=[te32]		// 8/3:te0[s2]
        +	add	te10=te10,te0		// 8/3:te0+s0>>16
        +	shl	te00=te00,twenty4};;	// 8/0:
        +{ .mii;	ld1	te13=[te13]		// 9/2:te0[s3>>16]
        +	dep	te33=te11,te33,16,8	// 9/0:
        +	shl	te01=te01,twenty4};;	// 9/1:
        +{ .mii;	ld1	te10=[te10]		// 10/3:te0[s0>>16]
        +	dep	te31=te20,te31,8,8	// 10/2:
        +	shl	te02=te02,twenty4};;	// 10/2:
        +{ .mii;	xor	t0=t0,te33		// 11/0:
        +	dep	te32=te21,te32,8,8	// 11/3:
        +	shl	te12=te12,sixteen};;	// 11/1:
        +{ .mii;	xor	r16=t0,te00		// 12/0:done!
        +	dep	te31=te13,te31,16,8	// 12/2:
        +	shl	te03=te03,twenty4};;	// 12/3:
        +{ .mmi;	xor	t1=t1,te01		// 13/1:
        +	xor	t2=t2,te02		// 13/2:
        +	dep	te32=te10,te32,16,8};;	// 13/3:
        +{ .mmi;	xor	t1=t1,te30		// 14/1:
        +	xor	r24=t2,te31		// 14/2:done!
        +	xor	t3=t3,te32	};;	// 14/3:
        +{ .mib;	xor	r20=t1,te12		// 15/1:done!
        +	xor	r28=t3,te03		// 15/3:done!
        +	br.ret.sptk	b6	};;
        +.endp	_ia64_AES_encrypt#
        +
        +// void AES_encrypt (const void *in,void *out,const AES_KEY *key);
        +.global	AES_encrypt#
        +.proc	AES_encrypt#
        +.align	32
        +AES_encrypt:
        +	.prologue
        +	.save	ar.pfs,pfssave
        +{ .mmi;	alloc	pfssave=ar.pfs,3,1,12,0
        +	and	out0=3,in0
        +	mov	r3=ip			}
        +{ .mmi;	ADDP	in0=0,in0
        +	mov	loc0=psr.um
        +	ADDP	out11=KSZ*60,in2	};;	// &AES_KEY->rounds
        +
        +{ .mmi;	ld4	out11=[out11]			// AES_KEY->rounds
        +	add	out8=(AES_Te#-AES_encrypt#),r3	// Te0
        +	.save	pr,prsave
        +	mov	prsave=pr		}
        +{ .mmi;	rum	1<<3				// clear um.ac
        +	.save	ar.lc,lcsave
        +	mov	lcsave=ar.lc		};;
        +
        +	.body
        +#if defined(_HPUX_SOURCE)	// HPUX is big-endian, cut 15+15 cycles...
        +{ .mib; cmp.ne	p6,p0=out0,r0
        +	add	out0=4,in0
        +(p6)	br.dpnt.many	.Le_i_unaligned	};;
        +
        +{ .mmi;	ld4	out1=[in0],8		// s0
        +	and	out9=3,in1
        +	mov	twenty4=24		}
        +{ .mmi;	ld4	out3=[out0],8		// s1
        +	ADDP	rk0=0,in2
        +	mov	sixteen=16		};;
        +{ .mmi;	ld4	out5=[in0]		// s2
        +	cmp.ne	p6,p0=out9,r0
        +	mov	maskff=0xff		}
        +{ .mmb;	ld4	out7=[out0]		// s3
        +	ADDP	rk1=KSZ,in2
        +	br.call.sptk.many	b6=_ia64_AES_encrypt	};;
        +
        +{ .mib;	ADDP	in0=4,in1
        +	ADDP	in1=0,in1
        +(p6)	br.spnt	.Le_o_unaligned		};;
        +
        +{ .mii;	mov	psr.um=loc0
        +	mov	ar.pfs=pfssave
        +	mov	ar.lc=lcsave		};;
        +{ .mmi;	st4	[in1]=r16,8		// s0
        +	st4	[in0]=r20,8		// s1
        +	mov	pr=prsave,0x1ffff	};;
        +{ .mmb;	st4	[in1]=r24		// s2
        +	st4	[in0]=r28		// s3
        +	br.ret.sptk.many	b0	};;
        +#endif
        +
        +.align	32
        +.Le_i_unaligned:
        +{ .mmi;	add	out0=1,in0
        +	add	out2=2,in0
        +	add	out4=3,in0	};;
        +{ .mmi;	ld1	r16=[in0],4
        +	ld1	r17=[out0],4	}//;;
        +{ .mmi;	ld1	r18=[out2],4
        +	ld1	out1=[out4],4	};;	// s0
        +{ .mmi;	ld1	r20=[in0],4
        +	ld1	r21=[out0],4	}//;;
        +{ .mmi;	ld1	r22=[out2],4
        +	ld1	out3=[out4],4	};;	// s1
        +{ .mmi;	ld1	r24=[in0],4
        +	ld1	r25=[out0],4	}//;;
        +{ .mmi;	ld1	r26=[out2],4
        +	ld1	out5=[out4],4	};;	// s2
        +{ .mmi;	ld1	r28=[in0]
        +	ld1	r29=[out0]	}//;;
        +{ .mmi;	ld1	r30=[out2]
        +	ld1	out7=[out4]	};;	// s3
        +
        +{ .mii;
        +	dep	out1=r16,out1,24,8	//;;
        +	dep	out3=r20,out3,24,8	}//;;
        +{ .mii;	ADDP	rk0=0,in2
        +	dep	out5=r24,out5,24,8	//;;
        +	dep	out7=r28,out7,24,8	};;
        +{ .mii;	ADDP	rk1=KSZ,in2
        +	dep	out1=r17,out1,16,8	//;;
        +	dep	out3=r21,out3,16,8	}//;;
        +{ .mii;	mov	twenty4=24
        +	dep	out5=r25,out5,16,8	//;;
        +	dep	out7=r29,out7,16,8	};;
        +{ .mii;	mov	sixteen=16
        +	dep	out1=r18,out1,8,8	//;;
        +	dep	out3=r22,out3,8,8	}//;;
        +{ .mii;	mov	maskff=0xff
        +	dep	out5=r26,out5,8,8	//;;
        +	dep	out7=r30,out7,8,8	};;
        +
        +{ .mib;	br.call.sptk.many	b6=_ia64_AES_encrypt	};;
        +
        +.Le_o_unaligned:
        +{ .mii;	ADDP	out0=0,in1
        +	extr.u	r17=r16,8,8			// s0
        +	shr.u	r19=r16,twenty4		}//;;
        +{ .mii;	ADDP	out1=1,in1
        +	extr.u	r18=r16,16,8
        +	shr.u	r23=r20,twenty4		}//;;	// s1
        +{ .mii;	ADDP	out2=2,in1
        +	extr.u	r21=r20,8,8
        +	shr.u	r22=r20,sixteen		}//;;
        +{ .mii;	ADDP	out3=3,in1
        +	extr.u	r25=r24,8,8			// s2
        +	shr.u	r27=r24,twenty4		};;
        +{ .mii;	st1	[out3]=r16,4
        +	extr.u	r26=r24,16,8
        +	shr.u	r31=r28,twenty4		}//;;	// s3
        +{ .mii;	st1	[out2]=r17,4
        +	extr.u	r29=r28,8,8
        +	shr.u	r30=r28,sixteen		}//;;
        +
        +{ .mmi;	st1	[out1]=r18,4
        +	st1	[out0]=r19,4		};;
        +{ .mmi;	st1	[out3]=r20,4
        +	st1	[out2]=r21,4		}//;;
        +{ .mmi;	st1	[out1]=r22,4
        +	st1	[out0]=r23,4		};;
        +{ .mmi;	st1	[out3]=r24,4
        +	st1	[out2]=r25,4
        +	mov	pr=prsave,0x1ffff	}//;;
        +{ .mmi;	st1	[out1]=r26,4
        +	st1	[out0]=r27,4
        +	mov	ar.pfs=pfssave		};;
        +{ .mmi;	st1	[out3]=r28
        +	st1	[out2]=r29
        +	mov	ar.lc=lcsave		}//;;
        +{ .mmi;	st1	[out1]=r30
        +	st1	[out0]=r31		}
        +{ .mfb;	mov	psr.um=loc0			// restore user mask
        +	br.ret.sptk.many	b0	};;
        +.endp	AES_encrypt#
        +
        +// *AES_decrypt are autogenerated by the following script:
        +#if 0
        +#!/usr/bin/env perl
        +print "// *AES_decrypt are autogenerated by the following script:\n#if 0\n";
        +open(PROG,'<'.$0); while(<PROG>) { print; } close(PROG);
        +print "#endif\n";
        +while(<>) {
        +	$process=1	if (/\.proc\s+_ia64_AES_encrypt/);
        +	next		if (!$process);
        +
        +	#s/te00=s0/td00=s0/;	s/te00/td00/g;
        +	s/te11=s1/td13=s3/;	s/te11/td13/g;
        +	#s/te22=s2/td22=s2/;	s/te22/td22/g;
        +	s/te33=s3/td31=s1/;	s/te33/td31/g;
        +
        +	#s/te01=s1/td01=s1/;	s/te01/td01/g;
        +	s/te12=s2/td10=s0/;	s/te12/td10/g;
        +	#s/te23=s3/td23=s3/;	s/te23/td23/g;
        +	s/te30=s0/td32=s2/;	s/te30/td32/g;
        +
        +	#s/te02=s2/td02=s2/;	s/te02/td02/g;
        +	s/te13=s3/td11=s1/;	s/te13/td11/g;
        +	#s/te20=s0/td20=s0/;	s/te20/td20/g;
        +	s/te31=s1/td33=s3/;	s/te31/td33/g;
        +
        +	#s/te03=s3/td03=s3/;	s/te03/td03/g;
        +	s/te10=s0/td12=s2/;	s/te10/td12/g;
        +	#s/te21=s1/td21=s1/;	s/te21/td21/g;
        +	s/te32=s2/td30=s0/;	s/te32/td30/g;
        +
        +	s/td/te/g;
        +
        +	s/AES_encrypt/AES_decrypt/g;
        +	s/\.Le_/.Ld_/g;
        +	s/AES_Te#/AES_Td#/g;
        +
        +	print;
        +
        +	exit		if (/\.endp\s+AES_decrypt/);
        +}
        +#endif
        +.proc	_ia64_AES_decrypt#
        +// Input:	rk0-rk1
        +//		te0
        +//		te3	as AES_KEY->rounds!!!
        +//		s0-s3
        +//		maskff,twenty4,sixteen
        +// Output:	r16,r20,r24,r28 as s0-s3
        +// Clobber:	r16-r31,rk0-rk1,r32-r43
        +.align	32
        +_ia64_AES_decrypt:
        +	.prologue
        +	.altrp	b6
        +	.body
        +{ .mmi;	alloc	r16=ar.pfs,12,0,0,8
        +	LDKEY	t0=[rk0],2*KSZ
        +	mov	pr.rot=1<<16	}
        +{ .mmi;	LDKEY	t1=[rk1],2*KSZ
        +	add	te1=TE1,te0
        +	add	te3=-3,te3	};;
        +{ .mib;	LDKEY	t2=[rk0],2*KSZ
        +	mov	ar.ec=2		}
        +{ .mib;	LDKEY	t3=[rk1],2*KSZ
        +	add	te2=TE2,te0
        +	brp.loop.imp	.Ld_top,.Ld_end-16	};;
        +
        +{ .mmi;	xor	s0=s0,t0
        +	xor	s1=s1,t1
        +	mov	ar.lc=te3	}
        +{ .mmi;	xor	s2=s2,t2
        +	xor	s3=s3,t3
        +	add	te3=TE3,te0	};;
        +
        +.align	32
        +.Ld_top:
        +{ .mmi;	(p0)	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
        +	(p0)	and	te31=s1,maskff		// 0/0:s3&0xff
        +	(p0)	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
        +{ .mmi; (p0)	LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
        +	(p0)	and	te32=s2,maskff		// 0/1:s0&0xff
        +	(p0)	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
        +{ .mmi;	(p0)	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
        +	(p0)	shladd	te31=te31,3,te3		// 1/0:te0+s0>>24
        +	(p0)	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
        +{ .mmi;	(p0)	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
        +	(p0)	shladd	te32=te32,3,te3		// 1/1:te3+s0
        +	(p0)	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
        +{ .mmi;	(p0)	ld4	te31=[te31]		// 2/0:te3[s3&0xff]
        +	(p0)	shladd	te22=te22,3,te2		// 2/0:te2+s2>>8&0xff
        +	(p0)	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
        +{ .mmi;	(p0)	ld4	te32=[te32]		// 2/1:te3[s0]
        +	(p0)	shladd	te23=te23,3,te2		// 2/1:te2+s3>>8
        +	(p0)	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
        +{ .mmi;	(p0)	ld4	te22=[te22]		// 3/0:te2[s2>>8]
        +	(p0)	shladd	te20=te20,3,te2		// 3/2:te2+s0>>8
        +	(p0)	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
        +{ .mmi;	(p0)	ld4	te23=[te23]		// 3/1:te2[s3>>8]
        +	(p0)	shladd	te00=te00,3,te0		// 3/0:te0+s0>>24
        +	(p0)	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
        +{ .mmi;	(p0)	ld4	te20=[te20]		// 4/2:te2[s0>>8]
        +	(p0)	shladd	te21=te21,3,te2		// 4/3:te3+s2
        +	(p0)	extr.u	te13=s3,16,8	}	// 4/0:s1>>16&0xff
        +{ .mmi;	(p0)	ld4	te00=[te00]		// 4/0:te0[s0>>24]
        +	(p0)	shladd	te01=te01,3,te0		// 4/1:te0+s1>>24
        +	(p0)	shr.u	te11=s1,sixteen	};;	// 4/2:s3>>16
        +{ .mmi;	(p0)	ld4	te21=[te21]		// 5/3:te2[s1>>8]
        +	(p0)	shladd	te13=te13,3,te1		// 5/0:te1+s1>>16
        +	(p0)	extr.u	te10=s0,16,8	}	// 5/1:s2>>16&0xff
        +{ .mmi;	(p0)	ld4	te01=[te01]		// 5/1:te0[s1>>24]
        +	(p0)	shladd	te02=te02,3,te0		// 5/2:te0+s2>>24
        +	(p0)	and	te33=s3,maskff	};;	// 5/2:s1&0xff
        +{ .mmi;	(p0)	ld4	te13=[te13]		// 6/0:te1[s1>>16]
        +	(p0)	shladd	te10=te10,3,te1		// 6/1:te1+s2>>16
        +	(p0)	extr.u	te12=s2,16,8	}	// 6/3:s0>>16&0xff
        +{ .mmi;	(p0)	ld4	te02=[te02]		// 6/2:te0[s2>>24]
        +	(p0)	shladd	te03=te03,3,te0		// 6/3:te1+s0>>16
        +	(p0)	and	te30=s0,maskff	};;	// 6/3:s2&0xff
        +
        +{ .mmi;	(p0)	ld4	te10=[te10]		// 7/1:te1[s2>>16]
        +	(p0)	shladd	te33=te33,3,te3		// 7/2:te3+s1&0xff
        +	(p0)	and	te11=te11,maskff}	// 7/2:s3>>16&0xff
        +{ .mmi;	(p0)	ld4	te03=[te03]		// 7/3:te0[s3>>24]
        +	(p0)	shladd	te30=te30,3,te3		// 7/3:te3+s2
        +	(p0)	xor	t0=t0,te31	};;	// 7/0:
        +{ .mmi;	(p0)	ld4	te33=[te33]		// 8/2:te3[s1]
        +	(p0)	shladd	te11=te11,3,te1		// 8/2:te1+s3>>16
        +	(p0)	xor	t0=t0,te22	}	// 8/0:
        +{ .mmi;	(p0)	ld4	te30=[te30]		// 8/3:te3[s2]
        +	(p0)	shladd	te12=te12,3,te1		// 8/3:te1+s0>>16
        +	(p0)	xor	t1=t1,te32	};;	// 8/1:
        +{ .mmi;	(p0)	ld4	te11=[te11]		// 9/2:te1[s3>>16]
        +	(p0)	ld4	te12=[te12]		// 9/3:te1[s0>>16]
        +	(p0)	xor	t0=t0,te00	};;	// 9/0:		!L2 scheduling
        +{ .mmi;	(p0)	xor	t1=t1,te23		// 10[9]/1:	
        +	(p0)	xor	t2=t2,te20		// 10[9]/2:
        +	(p0)	xor	t3=t3,te21	};;	// 10[9]/3:
        +{ .mmi;	(p0)	xor	t0=t0,te13		// 11[10]/0:done!
        +	(p0)	xor	t1=t1,te01		// 11[10]/1:
        +	(p0)	xor	t2=t2,te02	};;	// 11[10]/2:	!L2 scheduling
        +{ .mmi;	(p0)	xor	t3=t3,te03		// 12[10]/3:
        +	(p16)	cmp.eq	p0,p17=r0,r0 	};;	// 12[10]/clear (p17)
        +{ .mmi;	(p0)	xor	t1=t1,te10		// 13[11]/1:done!
        +	(p0)	xor	t2=t2,te33		// 13[11]/2:
        +	(p0)	xor	t3=t3,te30	}	// 13[11]/3:
        +{ .mmi;	(p17)	add	te0=2048,te0		// 13[11]/
        +	(p17)	add	te1=2048+64-TE1,te1};;	// 13[11]/
        +{ .mib;	(p0)	xor	t2=t2,te11		// 14[12]/2:done!
        +	(p17)	add	te2=2048+128-TE2,te2}	// 14[12]/
        +{ .mib;	(p0)	xor	t3=t3,te12		// 14[12]/3:done!
        +	(p17)	add	te3=2048+192-TE3,te3	// 14[12]/
        +	br.ctop.sptk	.Ld_top		};;
        +.Ld_end:
        +
        +
        +{ .mmi;	ld8	te10=[te0]		// prefetch Td4
        +	ld8	te33=[te1]	}
        +{ .mmi;	ld8	te12=[te2]
        +	ld8	te30=[te3]	}
        +
        +{ .mmi;	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
        +	and	te31=s1,maskff		// 0/0:s3&0xff
        +	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
        +{ .mmi; LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
        +	and	te32=s2,maskff		// 0/1:s0&0xff
        +	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
        +{ .mmi;	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
        +	add	te31=te31,te0		// 1/0:te0+s0>>24
        +	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
        +{ .mmi;	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
        +	add	te32=te32,te0		// 1/1:te0+s0
        +	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
        +{ .mmi;	ld1	te31=[te31]		// 2/0:te0[s3&0xff]
        +	add	te22=te22,te0		// 2/0:te0+s2>>8&0xff
        +	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
        +{ .mmi;	ld1	te32=[te32]		// 2/1:te0[s0]
        +	add	te23=te23,te0		// 2/1:te0+s3>>8
        +	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
        +{ .mmi;	ld1	te22=[te22]		// 3/0:te0[s2>>8]
        +	add	te20=te20,te0		// 3/2:te0+s0>>8
        +	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
        +{ .mmi;	ld1	te23=[te23]		// 3/1:te0[s3>>8]
        +	add	te00=te00,te0		// 3/0:te0+s0>>24
        +	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
        +{ .mmi;	ld1	te20=[te20]		// 4/2:te0[s0>>8]
        +	add	te21=te21,te0		// 4/3:te0+s2
        +	extr.u	te13=s3,16,8	}	// 4/0:s1>>16&0xff
        +{ .mmi;	ld1	te00=[te00]		// 4/0:te0[s0>>24]
        +	add	te01=te01,te0		// 4/1:te0+s1>>24
        +	shr.u	te11=s1,sixteen	};;	// 4/2:s3>>16
        +{ .mmi;	ld1	te21=[te21]		// 5/3:te0[s1>>8]
        +	add	te13=te13,te0		// 5/0:te0+s1>>16
        +	extr.u	te10=s0,16,8	}	// 5/1:s2>>16&0xff
        +{ .mmi;	ld1	te01=[te01]		// 5/1:te0[s1>>24]
        +	add	te02=te02,te0		// 5/2:te0+s2>>24
        +	and	te33=s3,maskff	};;	// 5/2:s1&0xff
        +{ .mmi;	ld1	te13=[te13]		// 6/0:te0[s1>>16]
        +	add	te10=te10,te0		// 6/1:te0+s2>>16
        +	extr.u	te12=s2,16,8	}	// 6/3:s0>>16&0xff
        +{ .mmi;	ld1	te02=[te02]		// 6/2:te0[s2>>24]
        +	add	te03=te03,te0		// 6/3:te0+s0>>16
        +	and	te30=s0,maskff	};;	// 6/3:s2&0xff
        +
        +{ .mmi;	ld1	te10=[te10]		// 7/1:te0[s2>>16]
        +	add	te33=te33,te0		// 7/2:te0+s1&0xff
        +	dep	te31=te22,te31,8,8}	// 7/0:
        +{ .mmi;	ld1	te03=[te03]		// 7/3:te0[s3>>24]
        +	add	te30=te30,te0		// 7/3:te0+s2
        +	and	te11=te11,maskff};;	// 7/2:s3>>16&0xff
        +{ .mmi;	ld1	te33=[te33]		// 8/2:te0[s1]
        +	add	te11=te11,te0		// 8/2:te0+s3>>16
        +	dep	te32=te23,te32,8,8}	// 8/1:
        +{ .mmi;	ld1	te30=[te30]		// 8/3:te0[s2]
        +	add	te12=te12,te0		// 8/3:te0+s0>>16
        +	shl	te00=te00,twenty4};;	// 8/0:
        +{ .mii;	ld1	te11=[te11]		// 9/2:te0[s3>>16]
        +	dep	te31=te13,te31,16,8	// 9/0:
        +	shl	te01=te01,twenty4};;	// 9/1:
        +{ .mii;	ld1	te12=[te12]		// 10/3:te0[s0>>16]
        +	dep	te33=te20,te33,8,8	// 10/2:
        +	shl	te02=te02,twenty4};;	// 10/2:
        +{ .mii;	xor	t0=t0,te31		// 11/0:
        +	dep	te30=te21,te30,8,8	// 11/3:
        +	shl	te10=te10,sixteen};;	// 11/1:
        +{ .mii;	xor	r16=t0,te00		// 12/0:done!
        +	dep	te33=te11,te33,16,8	// 12/2:
        +	shl	te03=te03,twenty4};;	// 12/3:
        +{ .mmi;	xor	t1=t1,te01		// 13/1:
        +	xor	t2=t2,te02		// 13/2:
        +	dep	te30=te12,te30,16,8};;	// 13/3:
        +{ .mmi;	xor	t1=t1,te32		// 14/1:
        +	xor	r24=t2,te33		// 14/2:done!
        +	xor	t3=t3,te30	};;	// 14/3:
        +{ .mib;	xor	r20=t1,te10		// 15/1:done!
        +	xor	r28=t3,te03		// 15/3:done!
        +	br.ret.sptk	b6	};;
        +.endp	_ia64_AES_decrypt#
        +
        +// void AES_decrypt (const void *in,void *out,const AES_KEY *key);
        +.global	AES_decrypt#
        +.proc	AES_decrypt#
        +.align	32
        +AES_decrypt:
        +	.prologue
        +	.save	ar.pfs,pfssave
        +{ .mmi;	alloc	pfssave=ar.pfs,3,1,12,0
        +	and	out0=3,in0
        +	mov	r3=ip			}
        +{ .mmi;	ADDP	in0=0,in0
        +	mov	loc0=psr.um
        +	ADDP	out11=KSZ*60,in2	};;	// &AES_KEY->rounds
        +
        +{ .mmi;	ld4	out11=[out11]			// AES_KEY->rounds
        +	add	out8=(AES_Td#-AES_decrypt#),r3	// Te0
        +	.save	pr,prsave
        +	mov	prsave=pr		}
        +{ .mmi;	rum	1<<3				// clear um.ac
        +	.save	ar.lc,lcsave
        +	mov	lcsave=ar.lc		};;
        +
        +	.body
        +#if defined(_HPUX_SOURCE)	// HPUX is big-endian, cut 15+15 cycles...
        +{ .mib; cmp.ne	p6,p0=out0,r0
        +	add	out0=4,in0
        +(p6)	br.dpnt.many	.Ld_i_unaligned	};;
        +
        +{ .mmi;	ld4	out1=[in0],8		// s0
        +	and	out9=3,in1
        +	mov	twenty4=24		}
        +{ .mmi;	ld4	out3=[out0],8		// s1
        +	ADDP	rk0=0,in2
        +	mov	sixteen=16		};;
        +{ .mmi;	ld4	out5=[in0]		// s2
        +	cmp.ne	p6,p0=out9,r0
        +	mov	maskff=0xff		}
        +{ .mmb;	ld4	out7=[out0]		// s3
        +	ADDP	rk1=KSZ,in2
        +	br.call.sptk.many	b6=_ia64_AES_decrypt	};;
        +
        +{ .mib;	ADDP	in0=4,in1
        +	ADDP	in1=0,in1
        +(p6)	br.spnt	.Ld_o_unaligned		};;
        +
        +{ .mii;	mov	psr.um=loc0
        +	mov	ar.pfs=pfssave
        +	mov	ar.lc=lcsave		};;
        +{ .mmi;	st4	[in1]=r16,8		// s0
        +	st4	[in0]=r20,8		// s1
        +	mov	pr=prsave,0x1ffff	};;
        +{ .mmb;	st4	[in1]=r24		// s2
        +	st4	[in0]=r28		// s3
        +	br.ret.sptk.many	b0	};;
        +#endif
        +
        +.align	32
        +.Ld_i_unaligned:
        +{ .mmi;	add	out0=1,in0
        +	add	out2=2,in0
        +	add	out4=3,in0	};;
        +{ .mmi;	ld1	r16=[in0],4
        +	ld1	r17=[out0],4	}//;;
        +{ .mmi;	ld1	r18=[out2],4
        +	ld1	out1=[out4],4	};;	// s0
        +{ .mmi;	ld1	r20=[in0],4
        +	ld1	r21=[out0],4	}//;;
        +{ .mmi;	ld1	r22=[out2],4
        +	ld1	out3=[out4],4	};;	// s1
        +{ .mmi;	ld1	r24=[in0],4
        +	ld1	r25=[out0],4	}//;;
        +{ .mmi;	ld1	r26=[out2],4
        +	ld1	out5=[out4],4	};;	// s2
        +{ .mmi;	ld1	r28=[in0]
        +	ld1	r29=[out0]	}//;;
        +{ .mmi;	ld1	r30=[out2]
        +	ld1	out7=[out4]	};;	// s3
        +
        +{ .mii;
        +	dep	out1=r16,out1,24,8	//;;
        +	dep	out3=r20,out3,24,8	}//;;
        +{ .mii;	ADDP	rk0=0,in2
        +	dep	out5=r24,out5,24,8	//;;
        +	dep	out7=r28,out7,24,8	};;
        +{ .mii;	ADDP	rk1=KSZ,in2
        +	dep	out1=r17,out1,16,8	//;;
        +	dep	out3=r21,out3,16,8	}//;;
        +{ .mii;	mov	twenty4=24
        +	dep	out5=r25,out5,16,8	//;;
        +	dep	out7=r29,out7,16,8	};;
        +{ .mii;	mov	sixteen=16
        +	dep	out1=r18,out1,8,8	//;;
        +	dep	out3=r22,out3,8,8	}//;;
        +{ .mii;	mov	maskff=0xff
        +	dep	out5=r26,out5,8,8	//;;
        +	dep	out7=r30,out7,8,8	};;
        +
        +{ .mib;	br.call.sptk.many	b6=_ia64_AES_decrypt	};;
        +
        +.Ld_o_unaligned:
        +{ .mii;	ADDP	out0=0,in1
        +	extr.u	r17=r16,8,8			// s0
        +	shr.u	r19=r16,twenty4		}//;;
        +{ .mii;	ADDP	out1=1,in1
        +	extr.u	r18=r16,16,8
        +	shr.u	r23=r20,twenty4		}//;;	// s1
        +{ .mii;	ADDP	out2=2,in1
        +	extr.u	r21=r20,8,8
        +	shr.u	r22=r20,sixteen		}//;;
        +{ .mii;	ADDP	out3=3,in1
        +	extr.u	r25=r24,8,8			// s2
        +	shr.u	r27=r24,twenty4		};;
        +{ .mii;	st1	[out3]=r16,4
        +	extr.u	r26=r24,16,8
        +	shr.u	r31=r28,twenty4		}//;;	// s3
        +{ .mii;	st1	[out2]=r17,4
        +	extr.u	r29=r28,8,8
        +	shr.u	r30=r28,sixteen		}//;;
        +
        +{ .mmi;	st1	[out1]=r18,4
        +	st1	[out0]=r19,4		};;
        +{ .mmi;	st1	[out3]=r20,4
        +	st1	[out2]=r21,4		}//;;
        +{ .mmi;	st1	[out1]=r22,4
        +	st1	[out0]=r23,4		};;
        +{ .mmi;	st1	[out3]=r24,4
        +	st1	[out2]=r25,4
        +	mov	pr=prsave,0x1ffff	}//;;
        +{ .mmi;	st1	[out1]=r26,4
        +	st1	[out0]=r27,4
        +	mov	ar.pfs=pfssave		};;
        +{ .mmi;	st1	[out3]=r28
        +	st1	[out2]=r29
        +	mov	ar.lc=lcsave		}//;;
        +{ .mmi;	st1	[out1]=r30
        +	st1	[out0]=r31		}
        +{ .mfb;	mov	psr.um=loc0			// restore user mask
        +	br.ret.sptk.many	b0	};;
        +.endp	AES_decrypt#
        +
        +// leave it in .text segment...
        +.align	64
        +.global	AES_Te#
        +.type	AES_Te#,@object
        +AES_Te:	data4	0xc66363a5,0xc66363a5, 0xf87c7c84,0xf87c7c84
        +	data4	0xee777799,0xee777799, 0xf67b7b8d,0xf67b7b8d
        +	data4	0xfff2f20d,0xfff2f20d, 0xd66b6bbd,0xd66b6bbd
        +	data4	0xde6f6fb1,0xde6f6fb1, 0x91c5c554,0x91c5c554
        +	data4	0x60303050,0x60303050, 0x02010103,0x02010103
        +	data4	0xce6767a9,0xce6767a9, 0x562b2b7d,0x562b2b7d
        +	data4	0xe7fefe19,0xe7fefe19, 0xb5d7d762,0xb5d7d762
        +	data4	0x4dababe6,0x4dababe6, 0xec76769a,0xec76769a
        +	data4	0x8fcaca45,0x8fcaca45, 0x1f82829d,0x1f82829d
        +	data4	0x89c9c940,0x89c9c940, 0xfa7d7d87,0xfa7d7d87
        +	data4	0xeffafa15,0xeffafa15, 0xb25959eb,0xb25959eb
        +	data4	0x8e4747c9,0x8e4747c9, 0xfbf0f00b,0xfbf0f00b
        +	data4	0x41adadec,0x41adadec, 0xb3d4d467,0xb3d4d467
        +	data4	0x5fa2a2fd,0x5fa2a2fd, 0x45afafea,0x45afafea
        +	data4	0x239c9cbf,0x239c9cbf, 0x53a4a4f7,0x53a4a4f7
        +	data4	0xe4727296,0xe4727296, 0x9bc0c05b,0x9bc0c05b
        +	data4	0x75b7b7c2,0x75b7b7c2, 0xe1fdfd1c,0xe1fdfd1c
        +	data4	0x3d9393ae,0x3d9393ae, 0x4c26266a,0x4c26266a
        +	data4	0x6c36365a,0x6c36365a, 0x7e3f3f41,0x7e3f3f41
        +	data4	0xf5f7f702,0xf5f7f702, 0x83cccc4f,0x83cccc4f
        +	data4	0x6834345c,0x6834345c, 0x51a5a5f4,0x51a5a5f4
        +	data4	0xd1e5e534,0xd1e5e534, 0xf9f1f108,0xf9f1f108
        +	data4	0xe2717193,0xe2717193, 0xabd8d873,0xabd8d873
        +	data4	0x62313153,0x62313153, 0x2a15153f,0x2a15153f
        +	data4	0x0804040c,0x0804040c, 0x95c7c752,0x95c7c752
        +	data4	0x46232365,0x46232365, 0x9dc3c35e,0x9dc3c35e
        +	data4	0x30181828,0x30181828, 0x379696a1,0x379696a1
        +	data4	0x0a05050f,0x0a05050f, 0x2f9a9ab5,0x2f9a9ab5
        +	data4	0x0e070709,0x0e070709, 0x24121236,0x24121236
        +	data4	0x1b80809b,0x1b80809b, 0xdfe2e23d,0xdfe2e23d
        +	data4	0xcdebeb26,0xcdebeb26, 0x4e272769,0x4e272769
        +	data4	0x7fb2b2cd,0x7fb2b2cd, 0xea75759f,0xea75759f
        +	data4	0x1209091b,0x1209091b, 0x1d83839e,0x1d83839e
        +	data4	0x582c2c74,0x582c2c74, 0x341a1a2e,0x341a1a2e
        +	data4	0x361b1b2d,0x361b1b2d, 0xdc6e6eb2,0xdc6e6eb2
        +	data4	0xb45a5aee,0xb45a5aee, 0x5ba0a0fb,0x5ba0a0fb
        +	data4	0xa45252f6,0xa45252f6, 0x763b3b4d,0x763b3b4d
        +	data4	0xb7d6d661,0xb7d6d661, 0x7db3b3ce,0x7db3b3ce
        +	data4	0x5229297b,0x5229297b, 0xdde3e33e,0xdde3e33e
        +	data4	0x5e2f2f71,0x5e2f2f71, 0x13848497,0x13848497
        +	data4	0xa65353f5,0xa65353f5, 0xb9d1d168,0xb9d1d168
        +	data4	0x00000000,0x00000000, 0xc1eded2c,0xc1eded2c
        +	data4	0x40202060,0x40202060, 0xe3fcfc1f,0xe3fcfc1f
        +	data4	0x79b1b1c8,0x79b1b1c8, 0xb65b5bed,0xb65b5bed
        +	data4	0xd46a6abe,0xd46a6abe, 0x8dcbcb46,0x8dcbcb46
        +	data4	0x67bebed9,0x67bebed9, 0x7239394b,0x7239394b
        +	data4	0x944a4ade,0x944a4ade, 0x984c4cd4,0x984c4cd4
        +	data4	0xb05858e8,0xb05858e8, 0x85cfcf4a,0x85cfcf4a
        +	data4	0xbbd0d06b,0xbbd0d06b, 0xc5efef2a,0xc5efef2a
        +	data4	0x4faaaae5,0x4faaaae5, 0xedfbfb16,0xedfbfb16
        +	data4	0x864343c5,0x864343c5, 0x9a4d4dd7,0x9a4d4dd7
        +	data4	0x66333355,0x66333355, 0x11858594,0x11858594
        +	data4	0x8a4545cf,0x8a4545cf, 0xe9f9f910,0xe9f9f910
        +	data4	0x04020206,0x04020206, 0xfe7f7f81,0xfe7f7f81
        +	data4	0xa05050f0,0xa05050f0, 0x783c3c44,0x783c3c44
        +	data4	0x259f9fba,0x259f9fba, 0x4ba8a8e3,0x4ba8a8e3
        +	data4	0xa25151f3,0xa25151f3, 0x5da3a3fe,0x5da3a3fe
        +	data4	0x804040c0,0x804040c0, 0x058f8f8a,0x058f8f8a
        +	data4	0x3f9292ad,0x3f9292ad, 0x219d9dbc,0x219d9dbc
        +	data4	0x70383848,0x70383848, 0xf1f5f504,0xf1f5f504
        +	data4	0x63bcbcdf,0x63bcbcdf, 0x77b6b6c1,0x77b6b6c1
        +	data4	0xafdada75,0xafdada75, 0x42212163,0x42212163
        +	data4	0x20101030,0x20101030, 0xe5ffff1a,0xe5ffff1a
        +	data4	0xfdf3f30e,0xfdf3f30e, 0xbfd2d26d,0xbfd2d26d
        +	data4	0x81cdcd4c,0x81cdcd4c, 0x180c0c14,0x180c0c14
        +	data4	0x26131335,0x26131335, 0xc3ecec2f,0xc3ecec2f
        +	data4	0xbe5f5fe1,0xbe5f5fe1, 0x359797a2,0x359797a2
        +	data4	0x884444cc,0x884444cc, 0x2e171739,0x2e171739
        +	data4	0x93c4c457,0x93c4c457, 0x55a7a7f2,0x55a7a7f2
        +	data4	0xfc7e7e82,0xfc7e7e82, 0x7a3d3d47,0x7a3d3d47
        +	data4	0xc86464ac,0xc86464ac, 0xba5d5de7,0xba5d5de7
        +	data4	0x3219192b,0x3219192b, 0xe6737395,0xe6737395
        +	data4	0xc06060a0,0xc06060a0, 0x19818198,0x19818198
        +	data4	0x9e4f4fd1,0x9e4f4fd1, 0xa3dcdc7f,0xa3dcdc7f
        +	data4	0x44222266,0x44222266, 0x542a2a7e,0x542a2a7e
        +	data4	0x3b9090ab,0x3b9090ab, 0x0b888883,0x0b888883
        +	data4	0x8c4646ca,0x8c4646ca, 0xc7eeee29,0xc7eeee29
        +	data4	0x6bb8b8d3,0x6bb8b8d3, 0x2814143c,0x2814143c
        +	data4	0xa7dede79,0xa7dede79, 0xbc5e5ee2,0xbc5e5ee2
        +	data4	0x160b0b1d,0x160b0b1d, 0xaddbdb76,0xaddbdb76
        +	data4	0xdbe0e03b,0xdbe0e03b, 0x64323256,0x64323256
        +	data4	0x743a3a4e,0x743a3a4e, 0x140a0a1e,0x140a0a1e
        +	data4	0x924949db,0x924949db, 0x0c06060a,0x0c06060a
        +	data4	0x4824246c,0x4824246c, 0xb85c5ce4,0xb85c5ce4
        +	data4	0x9fc2c25d,0x9fc2c25d, 0xbdd3d36e,0xbdd3d36e
        +	data4	0x43acacef,0x43acacef, 0xc46262a6,0xc46262a6
        +	data4	0x399191a8,0x399191a8, 0x319595a4,0x319595a4
        +	data4	0xd3e4e437,0xd3e4e437, 0xf279798b,0xf279798b
        +	data4	0xd5e7e732,0xd5e7e732, 0x8bc8c843,0x8bc8c843
        +	data4	0x6e373759,0x6e373759, 0xda6d6db7,0xda6d6db7
        +	data4	0x018d8d8c,0x018d8d8c, 0xb1d5d564,0xb1d5d564
        +	data4	0x9c4e4ed2,0x9c4e4ed2, 0x49a9a9e0,0x49a9a9e0
        +	data4	0xd86c6cb4,0xd86c6cb4, 0xac5656fa,0xac5656fa
        +	data4	0xf3f4f407,0xf3f4f407, 0xcfeaea25,0xcfeaea25
        +	data4	0xca6565af,0xca6565af, 0xf47a7a8e,0xf47a7a8e
        +	data4	0x47aeaee9,0x47aeaee9, 0x10080818,0x10080818
        +	data4	0x6fbabad5,0x6fbabad5, 0xf0787888,0xf0787888
        +	data4	0x4a25256f,0x4a25256f, 0x5c2e2e72,0x5c2e2e72
        +	data4	0x381c1c24,0x381c1c24, 0x57a6a6f1,0x57a6a6f1
        +	data4	0x73b4b4c7,0x73b4b4c7, 0x97c6c651,0x97c6c651
        +	data4	0xcbe8e823,0xcbe8e823, 0xa1dddd7c,0xa1dddd7c
        +	data4	0xe874749c,0xe874749c, 0x3e1f1f21,0x3e1f1f21
        +	data4	0x964b4bdd,0x964b4bdd, 0x61bdbddc,0x61bdbddc
        +	data4	0x0d8b8b86,0x0d8b8b86, 0x0f8a8a85,0x0f8a8a85
        +	data4	0xe0707090,0xe0707090, 0x7c3e3e42,0x7c3e3e42
        +	data4	0x71b5b5c4,0x71b5b5c4, 0xcc6666aa,0xcc6666aa
        +	data4	0x904848d8,0x904848d8, 0x06030305,0x06030305
        +	data4	0xf7f6f601,0xf7f6f601, 0x1c0e0e12,0x1c0e0e12
        +	data4	0xc26161a3,0xc26161a3, 0x6a35355f,0x6a35355f
        +	data4	0xae5757f9,0xae5757f9, 0x69b9b9d0,0x69b9b9d0
        +	data4	0x17868691,0x17868691, 0x99c1c158,0x99c1c158
        +	data4	0x3a1d1d27,0x3a1d1d27, 0x279e9eb9,0x279e9eb9
        +	data4	0xd9e1e138,0xd9e1e138, 0xebf8f813,0xebf8f813
        +	data4	0x2b9898b3,0x2b9898b3, 0x22111133,0x22111133
        +	data4	0xd26969bb,0xd26969bb, 0xa9d9d970,0xa9d9d970
        +	data4	0x078e8e89,0x078e8e89, 0x339494a7,0x339494a7
        +	data4	0x2d9b9bb6,0x2d9b9bb6, 0x3c1e1e22,0x3c1e1e22
        +	data4	0x15878792,0x15878792, 0xc9e9e920,0xc9e9e920
        +	data4	0x87cece49,0x87cece49, 0xaa5555ff,0xaa5555ff
        +	data4	0x50282878,0x50282878, 0xa5dfdf7a,0xa5dfdf7a
        +	data4	0x038c8c8f,0x038c8c8f, 0x59a1a1f8,0x59a1a1f8
        +	data4	0x09898980,0x09898980, 0x1a0d0d17,0x1a0d0d17
        +	data4	0x65bfbfda,0x65bfbfda, 0xd7e6e631,0xd7e6e631
        +	data4	0x844242c6,0x844242c6, 0xd06868b8,0xd06868b8
        +	data4	0x824141c3,0x824141c3, 0x299999b0,0x299999b0
        +	data4	0x5a2d2d77,0x5a2d2d77, 0x1e0f0f11,0x1e0f0f11
        +	data4	0x7bb0b0cb,0x7bb0b0cb, 0xa85454fc,0xa85454fc
        +	data4	0x6dbbbbd6,0x6dbbbbd6, 0x2c16163a,0x2c16163a
        +// Te4:
        +	data1	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
        +	data1	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +	data1	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +	data1	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +	data1	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +	data1	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +	data1	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +	data1	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +	data1	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +	data1	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +	data1	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +	data1	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +	data1	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +	data1	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +	data1	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +	data1	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +	data1	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +	data1	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +	data1	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +	data1	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +	data1	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +	data1	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +	data1	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +	data1	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +	data1	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +	data1	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +	data1	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +	data1	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +	data1	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +	data1	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +	data1	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +	data1	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +.size	AES_Te#,2048+256	// HP-UX assembler fails to ".-AES_Te#"
        +
        +.align	64
        +.global	AES_Td#
        +.type	AES_Td#,@object
        +AES_Td:	data4	0x51f4a750,0x51f4a750, 0x7e416553,0x7e416553
        +	data4	0x1a17a4c3,0x1a17a4c3, 0x3a275e96,0x3a275e96
        +	data4	0x3bab6bcb,0x3bab6bcb, 0x1f9d45f1,0x1f9d45f1
        +	data4	0xacfa58ab,0xacfa58ab, 0x4be30393,0x4be30393
        +	data4	0x2030fa55,0x2030fa55, 0xad766df6,0xad766df6
        +	data4	0x88cc7691,0x88cc7691, 0xf5024c25,0xf5024c25
        +	data4	0x4fe5d7fc,0x4fe5d7fc, 0xc52acbd7,0xc52acbd7
        +	data4	0x26354480,0x26354480, 0xb562a38f,0xb562a38f
        +	data4	0xdeb15a49,0xdeb15a49, 0x25ba1b67,0x25ba1b67
        +	data4	0x45ea0e98,0x45ea0e98, 0x5dfec0e1,0x5dfec0e1
        +	data4	0xc32f7502,0xc32f7502, 0x814cf012,0x814cf012
        +	data4	0x8d4697a3,0x8d4697a3, 0x6bd3f9c6,0x6bd3f9c6
        +	data4	0x038f5fe7,0x038f5fe7, 0x15929c95,0x15929c95
        +	data4	0xbf6d7aeb,0xbf6d7aeb, 0x955259da,0x955259da
        +	data4	0xd4be832d,0xd4be832d, 0x587421d3,0x587421d3
        +	data4	0x49e06929,0x49e06929, 0x8ec9c844,0x8ec9c844
        +	data4	0x75c2896a,0x75c2896a, 0xf48e7978,0xf48e7978
        +	data4	0x99583e6b,0x99583e6b, 0x27b971dd,0x27b971dd
        +	data4	0xbee14fb6,0xbee14fb6, 0xf088ad17,0xf088ad17
        +	data4	0xc920ac66,0xc920ac66, 0x7dce3ab4,0x7dce3ab4
        +	data4	0x63df4a18,0x63df4a18, 0xe51a3182,0xe51a3182
        +	data4	0x97513360,0x97513360, 0x62537f45,0x62537f45
        +	data4	0xb16477e0,0xb16477e0, 0xbb6bae84,0xbb6bae84
        +	data4	0xfe81a01c,0xfe81a01c, 0xf9082b94,0xf9082b94
        +	data4	0x70486858,0x70486858, 0x8f45fd19,0x8f45fd19
        +	data4	0x94de6c87,0x94de6c87, 0x527bf8b7,0x527bf8b7
        +	data4	0xab73d323,0xab73d323, 0x724b02e2,0x724b02e2
        +	data4	0xe31f8f57,0xe31f8f57, 0x6655ab2a,0x6655ab2a
        +	data4	0xb2eb2807,0xb2eb2807, 0x2fb5c203,0x2fb5c203
        +	data4	0x86c57b9a,0x86c57b9a, 0xd33708a5,0xd33708a5
        +	data4	0x302887f2,0x302887f2, 0x23bfa5b2,0x23bfa5b2
        +	data4	0x02036aba,0x02036aba, 0xed16825c,0xed16825c
        +	data4	0x8acf1c2b,0x8acf1c2b, 0xa779b492,0xa779b492
        +	data4	0xf307f2f0,0xf307f2f0, 0x4e69e2a1,0x4e69e2a1
        +	data4	0x65daf4cd,0x65daf4cd, 0x0605bed5,0x0605bed5
        +	data4	0xd134621f,0xd134621f, 0xc4a6fe8a,0xc4a6fe8a
        +	data4	0x342e539d,0x342e539d, 0xa2f355a0,0xa2f355a0
        +	data4	0x058ae132,0x058ae132, 0xa4f6eb75,0xa4f6eb75
        +	data4	0x0b83ec39,0x0b83ec39, 0x4060efaa,0x4060efaa
        +	data4	0x5e719f06,0x5e719f06, 0xbd6e1051,0xbd6e1051
        +	data4	0x3e218af9,0x3e218af9, 0x96dd063d,0x96dd063d
        +	data4	0xdd3e05ae,0xdd3e05ae, 0x4de6bd46,0x4de6bd46
        +	data4	0x91548db5,0x91548db5, 0x71c45d05,0x71c45d05
        +	data4	0x0406d46f,0x0406d46f, 0x605015ff,0x605015ff
        +	data4	0x1998fb24,0x1998fb24, 0xd6bde997,0xd6bde997
        +	data4	0x894043cc,0x894043cc, 0x67d99e77,0x67d99e77
        +	data4	0xb0e842bd,0xb0e842bd, 0x07898b88,0x07898b88
        +	data4	0xe7195b38,0xe7195b38, 0x79c8eedb,0x79c8eedb
        +	data4	0xa17c0a47,0xa17c0a47, 0x7c420fe9,0x7c420fe9
        +	data4	0xf8841ec9,0xf8841ec9, 0x00000000,0x00000000
        +	data4	0x09808683,0x09808683, 0x322bed48,0x322bed48
        +	data4	0x1e1170ac,0x1e1170ac, 0x6c5a724e,0x6c5a724e
        +	data4	0xfd0efffb,0xfd0efffb, 0x0f853856,0x0f853856
        +	data4	0x3daed51e,0x3daed51e, 0x362d3927,0x362d3927
        +	data4	0x0a0fd964,0x0a0fd964, 0x685ca621,0x685ca621
        +	data4	0x9b5b54d1,0x9b5b54d1, 0x24362e3a,0x24362e3a
        +	data4	0x0c0a67b1,0x0c0a67b1, 0x9357e70f,0x9357e70f
        +	data4	0xb4ee96d2,0xb4ee96d2, 0x1b9b919e,0x1b9b919e
        +	data4	0x80c0c54f,0x80c0c54f, 0x61dc20a2,0x61dc20a2
        +	data4	0x5a774b69,0x5a774b69, 0x1c121a16,0x1c121a16
        +	data4	0xe293ba0a,0xe293ba0a, 0xc0a02ae5,0xc0a02ae5
        +	data4	0x3c22e043,0x3c22e043, 0x121b171d,0x121b171d
        +	data4	0x0e090d0b,0x0e090d0b, 0xf28bc7ad,0xf28bc7ad
        +	data4	0x2db6a8b9,0x2db6a8b9, 0x141ea9c8,0x141ea9c8
        +	data4	0x57f11985,0x57f11985, 0xaf75074c,0xaf75074c
        +	data4	0xee99ddbb,0xee99ddbb, 0xa37f60fd,0xa37f60fd
        +	data4	0xf701269f,0xf701269f, 0x5c72f5bc,0x5c72f5bc
        +	data4	0x44663bc5,0x44663bc5, 0x5bfb7e34,0x5bfb7e34
        +	data4	0x8b432976,0x8b432976, 0xcb23c6dc,0xcb23c6dc
        +	data4	0xb6edfc68,0xb6edfc68, 0xb8e4f163,0xb8e4f163
        +	data4	0xd731dcca,0xd731dcca, 0x42638510,0x42638510
        +	data4	0x13972240,0x13972240, 0x84c61120,0x84c61120
        +	data4	0x854a247d,0x854a247d, 0xd2bb3df8,0xd2bb3df8
        +	data4	0xaef93211,0xaef93211, 0xc729a16d,0xc729a16d
        +	data4	0x1d9e2f4b,0x1d9e2f4b, 0xdcb230f3,0xdcb230f3
        +	data4	0x0d8652ec,0x0d8652ec, 0x77c1e3d0,0x77c1e3d0
        +	data4	0x2bb3166c,0x2bb3166c, 0xa970b999,0xa970b999
        +	data4	0x119448fa,0x119448fa, 0x47e96422,0x47e96422
        +	data4	0xa8fc8cc4,0xa8fc8cc4, 0xa0f03f1a,0xa0f03f1a
        +	data4	0x567d2cd8,0x567d2cd8, 0x223390ef,0x223390ef
        +	data4	0x87494ec7,0x87494ec7, 0xd938d1c1,0xd938d1c1
        +	data4	0x8ccaa2fe,0x8ccaa2fe, 0x98d40b36,0x98d40b36
        +	data4	0xa6f581cf,0xa6f581cf, 0xa57ade28,0xa57ade28
        +	data4	0xdab78e26,0xdab78e26, 0x3fadbfa4,0x3fadbfa4
        +	data4	0x2c3a9de4,0x2c3a9de4, 0x5078920d,0x5078920d
        +	data4	0x6a5fcc9b,0x6a5fcc9b, 0x547e4662,0x547e4662
        +	data4	0xf68d13c2,0xf68d13c2, 0x90d8b8e8,0x90d8b8e8
        +	data4	0x2e39f75e,0x2e39f75e, 0x82c3aff5,0x82c3aff5
        +	data4	0x9f5d80be,0x9f5d80be, 0x69d0937c,0x69d0937c
        +	data4	0x6fd52da9,0x6fd52da9, 0xcf2512b3,0xcf2512b3
        +	data4	0xc8ac993b,0xc8ac993b, 0x10187da7,0x10187da7
        +	data4	0xe89c636e,0xe89c636e, 0xdb3bbb7b,0xdb3bbb7b
        +	data4	0xcd267809,0xcd267809, 0x6e5918f4,0x6e5918f4
        +	data4	0xec9ab701,0xec9ab701, 0x834f9aa8,0x834f9aa8
        +	data4	0xe6956e65,0xe6956e65, 0xaaffe67e,0xaaffe67e
        +	data4	0x21bccf08,0x21bccf08, 0xef15e8e6,0xef15e8e6
        +	data4	0xbae79bd9,0xbae79bd9, 0x4a6f36ce,0x4a6f36ce
        +	data4	0xea9f09d4,0xea9f09d4, 0x29b07cd6,0x29b07cd6
        +	data4	0x31a4b2af,0x31a4b2af, 0x2a3f2331,0x2a3f2331
        +	data4	0xc6a59430,0xc6a59430, 0x35a266c0,0x35a266c0
        +	data4	0x744ebc37,0x744ebc37, 0xfc82caa6,0xfc82caa6
        +	data4	0xe090d0b0,0xe090d0b0, 0x33a7d815,0x33a7d815
        +	data4	0xf104984a,0xf104984a, 0x41ecdaf7,0x41ecdaf7
        +	data4	0x7fcd500e,0x7fcd500e, 0x1791f62f,0x1791f62f
        +	data4	0x764dd68d,0x764dd68d, 0x43efb04d,0x43efb04d
        +	data4	0xccaa4d54,0xccaa4d54, 0xe49604df,0xe49604df
        +	data4	0x9ed1b5e3,0x9ed1b5e3, 0x4c6a881b,0x4c6a881b
        +	data4	0xc12c1fb8,0xc12c1fb8, 0x4665517f,0x4665517f
        +	data4	0x9d5eea04,0x9d5eea04, 0x018c355d,0x018c355d
        +	data4	0xfa877473,0xfa877473, 0xfb0b412e,0xfb0b412e
        +	data4	0xb3671d5a,0xb3671d5a, 0x92dbd252,0x92dbd252
        +	data4	0xe9105633,0xe9105633, 0x6dd64713,0x6dd64713
        +	data4	0x9ad7618c,0x9ad7618c, 0x37a10c7a,0x37a10c7a
        +	data4	0x59f8148e,0x59f8148e, 0xeb133c89,0xeb133c89
        +	data4	0xcea927ee,0xcea927ee, 0xb761c935,0xb761c935
        +	data4	0xe11ce5ed,0xe11ce5ed, 0x7a47b13c,0x7a47b13c
        +	data4	0x9cd2df59,0x9cd2df59, 0x55f2733f,0x55f2733f
        +	data4	0x1814ce79,0x1814ce79, 0x73c737bf,0x73c737bf
        +	data4	0x53f7cdea,0x53f7cdea, 0x5ffdaa5b,0x5ffdaa5b
        +	data4	0xdf3d6f14,0xdf3d6f14, 0x7844db86,0x7844db86
        +	data4	0xcaaff381,0xcaaff381, 0xb968c43e,0xb968c43e
        +	data4	0x3824342c,0x3824342c, 0xc2a3405f,0xc2a3405f
        +	data4	0x161dc372,0x161dc372, 0xbce2250c,0xbce2250c
        +	data4	0x283c498b,0x283c498b, 0xff0d9541,0xff0d9541
        +	data4	0x39a80171,0x39a80171, 0x080cb3de,0x080cb3de
        +	data4	0xd8b4e49c,0xd8b4e49c, 0x6456c190,0x6456c190
        +	data4	0x7bcb8461,0x7bcb8461, 0xd532b670,0xd532b670
        +	data4	0x486c5c74,0x486c5c74, 0xd0b85742,0xd0b85742
        +// Td4:
        +	data1	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
        +	data1	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +	data1	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +	data1	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +	data1	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +	data1	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +	data1	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +	data1	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +	data1	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +	data1	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +	data1	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +	data1	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +	data1	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +	data1	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +	data1	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +	data1	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +	data1	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +	data1	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +	data1	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +	data1	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +	data1	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +	data1	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +	data1	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +	data1	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +	data1	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +	data1	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +	data1	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +	data1	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +	data1	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +	data1	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +	data1	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +	data1	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +.size	AES_Td#,2048+256	// HP-UX assembler fails to ".-AES_Td#"
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-mips.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-mips.pl
        new file mode 100644
        index 000000000..e52395421
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-mips.pl
        @@ -0,0 +1,1611 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# AES for MIPS
        +
        +# October 2010
        +#
        +# Code uses 1K[+256B] S-box and on single-issue core [such as R5000]
        +# spends ~68 cycles per byte processed with 128-bit key. This is ~16%
        +# faster than gcc-generated code, which is not very impressive. But
        +# recall that compressed S-box requires extra processing, namely
        +# additional rotations. Rotations are implemented with lwl/lwr pairs,
        +# which is normally used for loading unaligned data. Another cool
        +# thing about this module is its endian neutrality, which means that
        +# it processes data without ever changing byte order...
        +
        +######################################################################
        +# There is a number of MIPS ABI in use, O32 and N32/64 are most
        +# widely used. Then there is a new contender: NUBI. It appears that if
        +# one picks the latter, it's possible to arrange code in ABI neutral
        +# manner. Therefore let's stick to NUBI register layout:
        +#
        +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
        +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
        +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
        +#
        +# The return value is placed in $a0. Following coding rules facilitate
        +# interoperability:
        +#
        +# - never ever touch $tp, "thread pointer", former $gp;
        +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
        +#   old code];
        +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
        +#
        +# For reference here is register layout for N32/64 MIPS ABIs:
        +#
        +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
        +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
        +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
        +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
        +#
        +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
        +
        +if ($flavour =~ /64|n32/i) {
        +	$PTR_ADD="dadd";	# incidentally works even on n32
        +	$PTR_SUB="dsub";	# incidentally works even on n32
        +	$REG_S="sd";
        +	$REG_L="ld";
        +	$PTR_SLL="dsll";	# incidentally works even on n32
        +	$SZREG=8;
        +} else {
        +	$PTR_ADD="add";
        +	$PTR_SUB="sub";
        +	$REG_S="sw";
        +	$REG_L="lw";
        +	$PTR_SLL="sll";
        +	$SZREG=4;
        +}
        +$pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
        +#
        +# <appro@openssl.org>
        +#
        +######################################################################
        +
        +$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
        +
        +for (@ARGV) {	$output=$_ if (/^\w[\w\-]*\.\w+$/);	}
        +open STDOUT,">$output";
        +
        +if (!defined($big_endian))
        +{    $big_endian=(unpack('L',pack('N',1))==1);   }
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +my ($MSB,$LSB)=(0,3);	# automatically converted to little-endian
        +
        +$code.=<<___;
        +.text
        +#ifdef OPENSSL_FIPSCANISTER
        +# include <openssl/fipssyms.h>
        +#endif
        +
        +#if !defined(__vxworks) || defined(__pic__)
        +.option	pic2
        +#endif
        +.set	noat
        +___
        +
        +{{{
        +my $FRAMESIZE=16*$SZREG;
        +my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
        +
        +my ($inp,$out,$key,$Tbl,$s0,$s1,$s2,$s3)=($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7);
        +my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
        +my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10,$t11) = map("\$$_",(12..23));
        +my ($key0,$cnt)=($gp,$fp);
        +
        +# instuction ordering is "stolen" from output from MIPSpro assembler
        +# invoked with -mips3 -O3 arguments...
        +$code.=<<___;
        +.align	5
        +.ent	_mips_AES_encrypt
        +_mips_AES_encrypt:
        +	.frame	$sp,0,$ra
        +	.set	reorder
        +	lw	$t0,0($key)
        +	lw	$t1,4($key)
        +	lw	$t2,8($key)
        +	lw	$t3,12($key)
        +	lw	$cnt,240($key)
        +	$PTR_ADD $key0,$key,16
        +
        +	xor	$s0,$t0
        +	xor	$s1,$t1
        +	xor	$s2,$t2
        +	xor	$s3,$t3
        +
        +	sub	$cnt,1
        +	_xtr	$i0,$s1,16-2
        +.Loop_enc:
        +	_xtr	$i1,$s2,16-2
        +	_xtr	$i2,$s3,16-2
        +	_xtr	$i3,$s0,16-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lwl	$t0,3($i0)		# Te1[s1>>16]
        +	lwl	$t1,3($i1)		# Te1[s2>>16]
        +	lwl	$t2,3($i2)		# Te1[s3>>16]
        +	lwl	$t3,3($i3)		# Te1[s0>>16]
        +	lwr	$t0,2($i0)		# Te1[s1>>16]
        +	lwr	$t1,2($i1)		# Te1[s2>>16]
        +	lwr	$t2,2($i2)		# Te1[s3>>16]
        +	lwr	$t3,2($i3)		# Te1[s0>>16]
        +
        +	_xtr	$i0,$s2,8-2
        +	_xtr	$i1,$s3,8-2
        +	_xtr	$i2,$s0,8-2
        +	_xtr	$i3,$s1,8-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lwl	$t4,2($i0)		# Te2[s2>>8]
        +	lwl	$t5,2($i1)		# Te2[s3>>8]
        +	lwl	$t6,2($i2)		# Te2[s0>>8]
        +	lwl	$t7,2($i3)		# Te2[s1>>8]
        +	lwr	$t4,1($i0)		# Te2[s2>>8]
        +	lwr	$t5,1($i1)		# Te2[s3>>8]
        +	lwr	$t6,1($i2)		# Te2[s0>>8]
        +	lwr	$t7,1($i3)		# Te2[s1>>8]
        +
        +	_xtr	$i0,$s3,0-2
        +	_xtr	$i1,$s0,0-2
        +	_xtr	$i2,$s1,0-2
        +	_xtr	$i3,$s2,0-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lwl	$t8,1($i0)		# Te3[s3]
        +	lwl	$t9,1($i1)		# Te3[s0]
        +	lwl	$t10,1($i2)		# Te3[s1]
        +	lwl	$t11,1($i3)		# Te3[s2]
        +	lwr	$t8,0($i0)		# Te3[s3]
        +	lwr	$t9,0($i1)		# Te3[s0]
        +	lwr	$t10,0($i2)		# Te3[s1]
        +	lwr	$t11,0($i3)		# Te3[s2]
        +
        +	_xtr	$i0,$s0,24-2
        +	_xtr	$i1,$s1,24-2
        +	_xtr	$i2,$s2,24-2
        +	_xtr	$i3,$s3,24-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +	lw	$t4,0($i0)		# Te0[s0>>24]
        +	lw	$t5,0($i1)		# Te0[s1>>24]
        +	lw	$t6,0($i2)		# Te0[s2>>24]
        +	lw	$t7,0($i3)		# Te0[s3>>24]
        +
        +	lw	$s0,0($key0)
        +	lw	$s1,4($key0)
        +	lw	$s2,8($key0)
        +	lw	$s3,12($key0)
        +
        +	xor	$t0,$t8
        +	xor	$t1,$t9
        +	xor	$t2,$t10
        +	xor	$t3,$t11
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +	sub	$cnt,1
        +	$PTR_ADD $key0,16
        +	xor	$s0,$t0
        +	xor	$s1,$t1
        +	xor	$s2,$t2
        +	xor	$s3,$t3
        +	.set	noreorder
        +	bnez	$cnt,.Loop_enc
        +	_xtr	$i0,$s1,16-2
        +
        +	.set	reorder
        +	_xtr	$i1,$s2,16-2
        +	_xtr	$i2,$s3,16-2
        +	_xtr	$i3,$s0,16-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t0,2($i0)		# Te4[s1>>16]
        +	lbu	$t1,2($i1)		# Te4[s2>>16]
        +	lbu	$t2,2($i2)		# Te4[s3>>16]
        +	lbu	$t3,2($i3)		# Te4[s0>>16]
        +
        +	_xtr	$i0,$s2,8-2
        +	_xtr	$i1,$s3,8-2
        +	_xtr	$i2,$s0,8-2
        +	_xtr	$i3,$s1,8-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t4,2($i0)		# Te4[s2>>8]
        +	lbu	$t5,2($i1)		# Te4[s3>>8]
        +	lbu	$t6,2($i2)		# Te4[s0>>8]
        +	lbu	$t7,2($i3)		# Te4[s1>>8]
        +
        +	_xtr	$i0,$s0,24-2
        +	_xtr	$i1,$s1,24-2
        +	_xtr	$i2,$s2,24-2
        +	_xtr	$i3,$s3,24-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t8,2($i0)		# Te4[s0>>24]
        +	lbu	$t9,2($i1)		# Te4[s1>>24]
        +	lbu	$t10,2($i2)		# Te4[s2>>24]
        +	lbu	$t11,2($i3)		# Te4[s3>>24]
        +
        +	_xtr	$i0,$s3,0-2
        +	_xtr	$i1,$s0,0-2
        +	_xtr	$i2,$s1,0-2
        +	_xtr	$i3,$s2,0-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +
        +	_ins	$t0,16
        +	_ins	$t1,16
        +	_ins	$t2,16
        +	_ins	$t3,16
        +
        +	_ins	$t4,8
        +	_ins	$t5,8
        +	_ins	$t6,8
        +	_ins	$t7,8
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t4,2($i0)		# Te4[s3]
        +	lbu	$t5,2($i1)		# Te4[s0]
        +	lbu	$t6,2($i2)		# Te4[s1]
        +	lbu	$t7,2($i3)		# Te4[s2]
        +
        +	_ins	$t8,24
        +	_ins	$t9,24
        +	_ins	$t10,24
        +	_ins	$t11,24
        +
        +	lw	$s0,0($key0)
        +	lw	$s1,4($key0)
        +	lw	$s2,8($key0)
        +	lw	$s3,12($key0)
        +
        +	xor	$t0,$t8
        +	xor	$t1,$t9
        +	xor	$t2,$t10
        +	xor	$t3,$t11
        +
        +	_ins	$t4,0
        +	_ins	$t5,0
        +	_ins	$t6,0
        +	_ins	$t7,0
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +	xor	$s0,$t0
        +	xor	$s1,$t1
        +	xor	$s2,$t2
        +	xor	$s3,$t3
        +
        +	jr	$ra
        +.end	_mips_AES_encrypt
        +
        +.align	5
        +.globl	AES_encrypt
        +.ent	AES_encrypt
        +AES_encrypt:
        +	.frame	$sp,$FRAMESIZE,$ra
        +	.mask	$SAVED_REGS_MASK,-$SZREG
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
        +	.cpload	$pf
        +___
        +$code.=<<___;
        +	$PTR_SUB $sp,$FRAMESIZE
        +	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
        +	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
        +	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
        +	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
        +	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
        +	$REG_S	\$15,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_S	\$14,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_S	\$13,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_S	\$12,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
        +	.cplocal	$Tbl
        +	.cpsetup	$pf,$zero,AES_encrypt
        +___
        +$code.=<<___;
        +	.set	reorder
        +	la	$Tbl,AES_Te		# PIC-ified 'load address'
        +
        +	lwl	$s0,0+$MSB($inp)
        +	lwl	$s1,4+$MSB($inp)
        +	lwl	$s2,8+$MSB($inp)
        +	lwl	$s3,12+$MSB($inp)
        +	lwr	$s0,0+$LSB($inp)
        +	lwr	$s1,4+$LSB($inp)
        +	lwr	$s2,8+$LSB($inp)
        +	lwr	$s3,12+$LSB($inp)
        +
        +	bal	_mips_AES_encrypt
        +
        +	swr	$s0,0+$LSB($out)
        +	swr	$s1,4+$LSB($out)
        +	swr	$s2,8+$LSB($out)
        +	swr	$s3,12+$LSB($out)
        +	swl	$s0,0+$MSB($out)
        +	swl	$s1,4+$MSB($out)
        +	swl	$s2,8+$MSB($out)
        +	swl	$s3,12+$MSB($out)
        +
        +	.set	noreorder
        +	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
        +	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
        +	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
        +	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
        +	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	\$15,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_L	\$14,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_L	\$13,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_L	\$12,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE
        +.end	AES_encrypt
        +___
        +
        +$code.=<<___;
        +.align	5
        +.ent	_mips_AES_decrypt
        +_mips_AES_decrypt:
        +	.frame	$sp,0,$ra
        +	.set	reorder
        +	lw	$t0,0($key)
        +	lw	$t1,4($key)
        +	lw	$t2,8($key)
        +	lw	$t3,12($key)
        +	lw	$cnt,240($key)
        +	$PTR_ADD $key0,$key,16
        +
        +	xor	$s0,$t0
        +	xor	$s1,$t1
        +	xor	$s2,$t2
        +	xor	$s3,$t3
        +
        +	sub	$cnt,1
        +	_xtr	$i0,$s3,16-2
        +.Loop_dec:
        +	_xtr	$i1,$s0,16-2
        +	_xtr	$i2,$s1,16-2
        +	_xtr	$i3,$s2,16-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lwl	$t0,3($i0)		# Td1[s3>>16]
        +	lwl	$t1,3($i1)		# Td1[s0>>16]
        +	lwl	$t2,3($i2)		# Td1[s1>>16]
        +	lwl	$t3,3($i3)		# Td1[s2>>16]
        +	lwr	$t0,2($i0)		# Td1[s3>>16]
        +	lwr	$t1,2($i1)		# Td1[s0>>16]
        +	lwr	$t2,2($i2)		# Td1[s1>>16]
        +	lwr	$t3,2($i3)		# Td1[s2>>16]
        +
        +	_xtr	$i0,$s2,8-2
        +	_xtr	$i1,$s3,8-2
        +	_xtr	$i2,$s0,8-2
        +	_xtr	$i3,$s1,8-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lwl	$t4,2($i0)		# Td2[s2>>8]
        +	lwl	$t5,2($i1)		# Td2[s3>>8]
        +	lwl	$t6,2($i2)		# Td2[s0>>8]
        +	lwl	$t7,2($i3)		# Td2[s1>>8]
        +	lwr	$t4,1($i0)		# Td2[s2>>8]
        +	lwr	$t5,1($i1)		# Td2[s3>>8]
        +	lwr	$t6,1($i2)		# Td2[s0>>8]
        +	lwr	$t7,1($i3)		# Td2[s1>>8]
        +
        +	_xtr	$i0,$s1,0-2
        +	_xtr	$i1,$s2,0-2
        +	_xtr	$i2,$s3,0-2
        +	_xtr	$i3,$s0,0-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lwl	$t8,1($i0)		# Td3[s1]
        +	lwl	$t9,1($i1)		# Td3[s2]
        +	lwl	$t10,1($i2)		# Td3[s3]
        +	lwl	$t11,1($i3)		# Td3[s0]
        +	lwr	$t8,0($i0)		# Td3[s1]
        +	lwr	$t9,0($i1)		# Td3[s2]
        +	lwr	$t10,0($i2)		# Td3[s3]
        +	lwr	$t11,0($i3)		# Td3[s0]
        +
        +	_xtr	$i0,$s0,24-2
        +	_xtr	$i1,$s1,24-2
        +	_xtr	$i2,$s2,24-2
        +	_xtr	$i3,$s3,24-2
        +	and	$i0,0x3fc
        +	and	$i1,0x3fc
        +	and	$i2,0x3fc
        +	and	$i3,0x3fc
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +
        +	lw	$t4,0($i0)		# Td0[s0>>24]
        +	lw	$t5,0($i1)		# Td0[s1>>24]
        +	lw	$t6,0($i2)		# Td0[s2>>24]
        +	lw	$t7,0($i3)		# Td0[s3>>24]
        +
        +	lw	$s0,0($key0)
        +	lw	$s1,4($key0)
        +	lw	$s2,8($key0)
        +	lw	$s3,12($key0)
        +
        +	xor	$t0,$t8
        +	xor	$t1,$t9
        +	xor	$t2,$t10
        +	xor	$t3,$t11
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +	sub	$cnt,1
        +	$PTR_ADD $key0,16
        +	xor	$s0,$t0
        +	xor	$s1,$t1
        +	xor	$s2,$t2
        +	xor	$s3,$t3
        +	.set	noreorder
        +	bnez	$cnt,.Loop_dec
        +	_xtr	$i0,$s3,16-2
        +
        +	.set	reorder
        +	lw	$t4,1024($Tbl)		# prefetch Td4
        +	lw	$t5,1024+32($Tbl)
        +	lw	$t6,1024+64($Tbl)
        +	lw	$t7,1024+96($Tbl)
        +	lw	$t8,1024+128($Tbl)
        +	lw	$t9,1024+160($Tbl)
        +	lw	$t10,1024+192($Tbl)
        +	lw	$t11,1024+224($Tbl)
        +
        +	_xtr	$i0,$s3,16
        +	_xtr	$i1,$s0,16
        +	_xtr	$i2,$s1,16
        +	_xtr	$i3,$s2,16
        +	and	$i0,0xff
        +	and	$i1,0xff
        +	and	$i2,0xff
        +	and	$i3,0xff
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t0,1024($i0)		# Td4[s3>>16]
        +	lbu	$t1,1024($i1)		# Td4[s0>>16]
        +	lbu	$t2,1024($i2)		# Td4[s1>>16]
        +	lbu	$t3,1024($i3)		# Td4[s2>>16]
        +
        +	_xtr	$i0,$s2,8
        +	_xtr	$i1,$s3,8
        +	_xtr	$i2,$s0,8
        +	_xtr	$i3,$s1,8
        +	and	$i0,0xff
        +	and	$i1,0xff
        +	and	$i2,0xff
        +	and	$i3,0xff
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t4,1024($i0)		# Td4[s2>>8]
        +	lbu	$t5,1024($i1)		# Td4[s3>>8]
        +	lbu	$t6,1024($i2)		# Td4[s0>>8]
        +	lbu	$t7,1024($i3)		# Td4[s1>>8]
        +
        +	_xtr	$i0,$s0,24
        +	_xtr	$i1,$s1,24
        +	_xtr	$i2,$s2,24
        +	_xtr	$i3,$s3,24
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t8,1024($i0)		# Td4[s0>>24]
        +	lbu	$t9,1024($i1)		# Td4[s1>>24]
        +	lbu	$t10,1024($i2)		# Td4[s2>>24]
        +	lbu	$t11,1024($i3)		# Td4[s3>>24]
        +
        +	_xtr	$i0,$s1,0
        +	_xtr	$i1,$s2,0
        +	_xtr	$i2,$s3,0
        +	_xtr	$i3,$s0,0
        +
        +	_ins	$t0,16
        +	_ins	$t1,16
        +	_ins	$t2,16
        +	_ins	$t3,16
        +
        +	_ins	$t4,8
        +	_ins	$t5,8
        +	_ins	$t6,8
        +	_ins	$t7,8
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$t4,1024($i0)		# Td4[s1]
        +	lbu	$t5,1024($i1)		# Td4[s2]
        +	lbu	$t6,1024($i2)		# Td4[s3]
        +	lbu	$t7,1024($i3)		# Td4[s0]
        +
        +	_ins	$t8,24
        +	_ins	$t9,24
        +	_ins	$t10,24
        +	_ins	$t11,24
        +
        +	lw	$s0,0($key0)
        +	lw	$s1,4($key0)
        +	lw	$s2,8($key0)
        +	lw	$s3,12($key0)
        +
        +	_ins	$t4,0
        +	_ins	$t5,0
        +	_ins	$t6,0
        +	_ins	$t7,0
        +
        +
        +	xor	$t0,$t8
        +	xor	$t1,$t9
        +	xor	$t2,$t10
        +	xor	$t3,$t11
        +
        +	xor	$t0,$t4
        +	xor	$t1,$t5
        +	xor	$t2,$t6
        +	xor	$t3,$t7
        +
        +	xor	$s0,$t0
        +	xor	$s1,$t1
        +	xor	$s2,$t2
        +	xor	$s3,$t3
        +
        +	jr	$ra
        +.end	_mips_AES_decrypt
        +
        +.align	5
        +.globl	AES_decrypt
        +.ent	AES_decrypt
        +AES_decrypt:
        +	.frame	$sp,$FRAMESIZE,$ra
        +	.mask	$SAVED_REGS_MASK,-$SZREG
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
        +	.cpload	$pf
        +___
        +$code.=<<___;
        +	$PTR_SUB $sp,$FRAMESIZE
        +	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
        +	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
        +	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
        +	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
        +	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
        +	$REG_S	\$15,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_S	\$14,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_S	\$13,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_S	\$12,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
        +	.cplocal	$Tbl
        +	.cpsetup	$pf,$zero,AES_decrypt
        +___
        +$code.=<<___;
        +	.set	reorder
        +	la	$Tbl,AES_Td		# PIC-ified 'load address'
        +
        +	lwl	$s0,0+$MSB($inp)
        +	lwl	$s1,4+$MSB($inp)
        +	lwl	$s2,8+$MSB($inp)
        +	lwl	$s3,12+$MSB($inp)
        +	lwr	$s0,0+$LSB($inp)
        +	lwr	$s1,4+$LSB($inp)
        +	lwr	$s2,8+$LSB($inp)
        +	lwr	$s3,12+$LSB($inp)
        +
        +	bal	_mips_AES_decrypt
        +
        +	swr	$s0,0+$LSB($out)
        +	swr	$s1,4+$LSB($out)
        +	swr	$s2,8+$LSB($out)
        +	swr	$s3,12+$LSB($out)
        +	swl	$s0,0+$MSB($out)
        +	swl	$s1,4+$MSB($out)
        +	swl	$s2,8+$MSB($out)
        +	swl	$s3,12+$MSB($out)
        +
        +	.set	noreorder
        +	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
        +	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
        +	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
        +	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
        +	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	\$15,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_L	\$14,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_L	\$13,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_L	\$12,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE
        +.end	AES_decrypt
        +___
        +}}}
        +
        +{{{
        +my $FRAMESIZE=8*$SZREG;
        +my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc000f008 : 0xc0000000;
        +
        +my ($inp,$bits,$key,$Tbl)=($a0,$a1,$a2,$a3);
        +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
        +my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
        +my ($rcon,$cnt)=($gp,$fp);
        +
        +$code.=<<___;
        +.align	5
        +.ent	_mips_AES_set_encrypt_key
        +_mips_AES_set_encrypt_key:
        +	.frame	$sp,0,$ra
        +	.set	noreorder
        +	beqz	$inp,.Lekey_done
        +	li	$t0,-1
        +	beqz	$key,.Lekey_done
        +	$PTR_ADD $rcon,$Tbl,1024+256
        +
        +	.set	reorder
        +	lwl	$rk0,0+$MSB($inp)	# load 128 bits
        +	lwl	$rk1,4+$MSB($inp)
        +	lwl	$rk2,8+$MSB($inp)
        +	lwl	$rk3,12+$MSB($inp)
        +	li	$at,128
        +	lwr	$rk0,0+$LSB($inp)
        +	lwr	$rk1,4+$LSB($inp)
        +	lwr	$rk2,8+$LSB($inp)
        +	lwr	$rk3,12+$LSB($inp)
        +	.set	noreorder
        +	beq	$bits,$at,.L128bits
        +	li	$cnt,10
        +
        +	.set	reorder
        +	lwl	$rk4,16+$MSB($inp)	# load 192 bits
        +	lwl	$rk5,20+$MSB($inp)
        +	li	$at,192
        +	lwr	$rk4,16+$LSB($inp)
        +	lwr	$rk5,20+$LSB($inp)
        +	.set	noreorder
        +	beq	$bits,$at,.L192bits
        +	li	$cnt,8
        +
        +	.set	reorder
        +	lwl	$rk6,24+$MSB($inp)	# load 256 bits
        +	lwl	$rk7,28+$MSB($inp)
        +	li	$at,256
        +	lwr	$rk6,24+$LSB($inp)
        +	lwr	$rk7,28+$LSB($inp)
        +	.set	noreorder
        +	beq	$bits,$at,.L256bits
        +	li	$cnt,7
        +
        +	b	.Lekey_done
        +	li	$t0,-2
        +
        +.align	4
        +.L128bits:
        +	.set	reorder
        +	srl	$i0,$rk3,16
        +	srl	$i1,$rk3,8
        +	and	$i0,0xff
        +	and	$i1,0xff
        +	and	$i2,$rk3,0xff
        +	srl	$i3,$rk3,24
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$i0,1024($i0)
        +	lbu	$i1,1024($i1)
        +	lbu	$i2,1024($i2)
        +	lbu	$i3,1024($i3)
        +
        +	sw	$rk0,0($key)
        +	sw	$rk1,4($key)
        +	sw	$rk2,8($key)
        +	sw	$rk3,12($key)
        +	sub	$cnt,1
        +	$PTR_ADD $key,16
        +
        +	_bias	$i0,24
        +	_bias	$i1,16
        +	_bias	$i2,8
        +	_bias	$i3,0
        +
        +	xor	$rk0,$i0
        +	lw	$i0,0($rcon)
        +	xor	$rk0,$i1
        +	xor	$rk0,$i2
        +	xor	$rk0,$i3
        +	xor	$rk0,$i0
        +
        +	xor	$rk1,$rk0
        +	xor	$rk2,$rk1
        +	xor	$rk3,$rk2
        +
        +	.set	noreorder
        +	bnez	$cnt,.L128bits
        +	$PTR_ADD $rcon,4
        +
        +	sw	$rk0,0($key)
        +	sw	$rk1,4($key)
        +	sw	$rk2,8($key)
        +	li	$cnt,10
        +	sw	$rk3,12($key)
        +	li	$t0,0
        +	sw	$cnt,80($key)
        +	b	.Lekey_done
        +	$PTR_SUB $key,10*16
        +
        +.align	4
        +.L192bits:
        +	.set	reorder
        +	srl	$i0,$rk5,16
        +	srl	$i1,$rk5,8
        +	and	$i0,0xff
        +	and	$i1,0xff
        +	and	$i2,$rk5,0xff
        +	srl	$i3,$rk5,24
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$i0,1024($i0)
        +	lbu	$i1,1024($i1)
        +	lbu	$i2,1024($i2)
        +	lbu	$i3,1024($i3)
        +
        +	sw	$rk0,0($key)
        +	sw	$rk1,4($key)
        +	sw	$rk2,8($key)
        +	sw	$rk3,12($key)
        +	sw	$rk4,16($key)
        +	sw	$rk5,20($key)
        +	sub	$cnt,1
        +	$PTR_ADD $key,24
        +
        +	_bias	$i0,24
        +	_bias	$i1,16
        +	_bias	$i2,8
        +	_bias	$i3,0
        +
        +	xor	$rk0,$i0
        +	lw	$i0,0($rcon)
        +	xor	$rk0,$i1
        +	xor	$rk0,$i2
        +	xor	$rk0,$i3
        +	xor	$rk0,$i0
        +
        +	xor	$rk1,$rk0
        +	xor	$rk2,$rk1
        +	xor	$rk3,$rk2
        +	xor	$rk4,$rk3
        +	xor	$rk5,$rk4
        +
        +	.set	noreorder
        +	bnez	$cnt,.L192bits
        +	$PTR_ADD $rcon,4
        +
        +	sw	$rk0,0($key)
        +	sw	$rk1,4($key)
        +	sw	$rk2,8($key)
        +	li	$cnt,12
        +	sw	$rk3,12($key)
        +	li	$t0,0
        +	sw	$cnt,48($key)
        +	b	.Lekey_done
        +	$PTR_SUB $key,12*16
        +
        +.align	4
        +.L256bits:
        +	.set	reorder
        +	srl	$i0,$rk7,16
        +	srl	$i1,$rk7,8
        +	and	$i0,0xff
        +	and	$i1,0xff
        +	and	$i2,$rk7,0xff
        +	srl	$i3,$rk7,24
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$i0,1024($i0)
        +	lbu	$i1,1024($i1)
        +	lbu	$i2,1024($i2)
        +	lbu	$i3,1024($i3)
        +
        +	sw	$rk0,0($key)
        +	sw	$rk1,4($key)
        +	sw	$rk2,8($key)
        +	sw	$rk3,12($key)
        +	sw	$rk4,16($key)
        +	sw	$rk5,20($key)
        +	sw	$rk6,24($key)
        +	sw	$rk7,28($key)
        +	sub	$cnt,1
        +
        +	_bias	$i0,24
        +	_bias	$i1,16
        +	_bias	$i2,8
        +	_bias	$i3,0
        +
        +	xor	$rk0,$i0
        +	lw	$i0,0($rcon)
        +	xor	$rk0,$i1
        +	xor	$rk0,$i2
        +	xor	$rk0,$i3
        +	xor	$rk0,$i0
        +
        +	xor	$rk1,$rk0
        +	xor	$rk2,$rk1
        +	xor	$rk3,$rk2
        +	beqz	$cnt,.L256bits_done
        +
        +	srl	$i0,$rk3,24
        +	srl	$i1,$rk3,16
        +	srl	$i2,$rk3,8
        +	and	$i3,$rk3,0xff
        +	and	$i1,0xff
        +	and	$i2,0xff
        +	$PTR_ADD $i0,$Tbl
        +	$PTR_ADD $i1,$Tbl
        +	$PTR_ADD $i2,$Tbl
        +	$PTR_ADD $i3,$Tbl
        +	lbu	$i0,1024($i0)
        +	lbu	$i1,1024($i1)
        +	lbu	$i2,1024($i2)
        +	lbu	$i3,1024($i3)
        +	sll	$i0,24
        +	sll	$i1,16
        +	sll	$i2,8
        +
        +	xor	$rk4,$i0
        +	xor	$rk4,$i1
        +	xor	$rk4,$i2
        +	xor	$rk4,$i3
        +
        +	xor	$rk5,$rk4
        +	xor	$rk6,$rk5
        +	xor	$rk7,$rk6
        +
        +	$PTR_ADD $key,32
        +	.set	noreorder
        +	b	.L256bits
        +	$PTR_ADD $rcon,4
        +
        +.L256bits_done:
        +	sw	$rk0,32($key)
        +	sw	$rk1,36($key)
        +	sw	$rk2,40($key)
        +	li	$cnt,14
        +	sw	$rk3,44($key)
        +	li	$t0,0
        +	sw	$cnt,48($key)
        +	$PTR_SUB $key,12*16
        +
        +.Lekey_done:
        +	jr	$ra
        +	nop
        +.end	_mips_AES_set_encrypt_key
        +
        +.globl	private_AES_set_encrypt_key
        +.ent	private_AES_set_encrypt_key
        +private_AES_set_encrypt_key:
        +	.frame	$sp,$FRAMESIZE,$ra
        +	.mask	$SAVED_REGS_MASK,-$SZREG
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
        +	.cpload	$pf
        +___
        +$code.=<<___;
        +	$PTR_SUB $sp,$FRAMESIZE
        +	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
        +	$REG_S	$s3,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_S	$s2,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_S	$s1,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_S	$s0,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_S	$gp,$FRAMESIZE-7*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
        +	.cplocal	$Tbl
        +	.cpsetup	$pf,$zero,private_AES_set_encrypt_key
        +___
        +$code.=<<___;
        +	.set	reorder
        +	la	$Tbl,AES_Te		# PIC-ified 'load address'
        +
        +	bal	_mips_AES_set_encrypt_key
        +
        +	.set	noreorder
        +	move	$a0,$t0
        +	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE
        +.end	private_AES_set_encrypt_key
        +___
        +
        +my ($head,$tail)=($inp,$bits);
        +my ($tp1,$tp2,$tp4,$tp8,$tp9,$tpb,$tpd,$tpe)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
        +my ($m,$x80808080,$x7f7f7f7f,$x1b1b1b1b)=($at,$t0,$t1,$t2);
        +$code.=<<___;
        +.align	5
        +.globl	private_AES_set_decrypt_key
        +.ent	private_AES_set_decrypt_key
        +private_AES_set_decrypt_key:
        +	.frame	$sp,$FRAMESIZE,$ra
        +	.mask	$SAVED_REGS_MASK,-$SZREG
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
        +	.cpload	$pf
        +___
        +$code.=<<___;
        +	$PTR_SUB $sp,$FRAMESIZE
        +	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
        +	$REG_S	$s3,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_S	$s2,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_S	$s1,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_S	$s0,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_S	$gp,$FRAMESIZE-7*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
        +	.cplocal	$Tbl
        +	.cpsetup	$pf,$zero,private_AES_set_decrypt_key
        +___
        +$code.=<<___;
        +	.set	reorder
        +	la	$Tbl,AES_Te		# PIC-ified 'load address'
        +
        +	bal	_mips_AES_set_encrypt_key
        +
        +	bltz	$t0,.Ldkey_done
        +
        +	sll	$at,$cnt,4
        +	$PTR_ADD $head,$key,0
        +	$PTR_ADD $tail,$key,$at
        +.align	4
        +.Lswap:
        +	lw	$rk0,0($head)
        +	lw	$rk1,4($head)
        +	lw	$rk2,8($head)
        +	lw	$rk3,12($head)
        +	lw	$rk4,0($tail)
        +	lw	$rk5,4($tail)
        +	lw	$rk6,8($tail)
        +	lw	$rk7,12($tail)
        +	sw	$rk0,0($tail)
        +	sw	$rk1,4($tail)
        +	sw	$rk2,8($tail)
        +	sw	$rk3,12($tail)
        +	$PTR_ADD $head,16
        +	$PTR_SUB $tail,16
        +	sw	$rk4,-16($head)
        +	sw	$rk5,-12($head)
        +	sw	$rk6,-8($head)
        +	sw	$rk7,-4($head)
        +	bne	$head,$tail,.Lswap
        +
        +	lw	$tp1,16($key)		# modulo-scheduled
        +	lui	$x80808080,0x8080
        +	sub	$cnt,1
        +	or	$x80808080,0x8080
        +	sll	$cnt,2
        +	$PTR_ADD $key,16
        +	lui	$x1b1b1b1b,0x1b1b
        +	nor	$x7f7f7f7f,$zero,$x80808080
        +	or	$x1b1b1b1b,0x1b1b
        +.align	4
        +.Lmix:
        +	and	$m,$tp1,$x80808080
        +	and	$tp2,$tp1,$x7f7f7f7f
        +	srl	$tp4,$m,7
        +	addu	$tp2,$tp2		# tp2<<1
        +	subu	$m,$tp4
        +	and	$m,$x1b1b1b1b
        +	xor	$tp2,$m
        +
        +	and	$m,$tp2,$x80808080
        +	and	$tp4,$tp2,$x7f7f7f7f
        +	srl	$tp8,$m,7
        +	addu	$tp4,$tp4		# tp4<<1
        +	subu	$m,$tp8
        +	and	$m,$x1b1b1b1b
        +	xor	$tp4,$m
        +
        +	and	$m,$tp4,$x80808080
        +	and	$tp8,$tp4,$x7f7f7f7f
        +	srl	$tp9,$m,7
        +	addu	$tp8,$tp8		# tp8<<1
        +	subu	$m,$tp9
        +	and	$m,$x1b1b1b1b
        +	xor	$tp8,$m
        +
        +	xor	$tp9,$tp8,$tp1
        +	xor	$tpe,$tp8,$tp4
        +	xor	$tpb,$tp9,$tp2
        +	xor	$tpd,$tp9,$tp4
        +
        +	_ror	$tp1,$tpd,16
        +	 xor	$tpe,$tp2
        +	_ror	$tp2,$tpd,-16
        +	xor	$tpe,$tp1
        +	_ror	$tp1,$tp9,8
        +	xor	$tpe,$tp2
        +	_ror	$tp2,$tp9,-24
        +	xor	$tpe,$tp1
        +	_ror	$tp1,$tpb,24
        +	xor	$tpe,$tp2
        +	_ror	$tp2,$tpb,-8
        +	xor	$tpe,$tp1
        +	lw	$tp1,4($key)		# modulo-scheduled
        +	xor	$tpe,$tp2
        +	sub	$cnt,1
        +	sw	$tpe,0($key)
        +	$PTR_ADD $key,4
        +	bnez	$cnt,.Lmix
        +
        +	li	$t0,0
        +.Ldkey_done:
        +	.set	noreorder
        +	move	$a0,$t0
        +	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE
        +.end	private_AES_set_decrypt_key
        +___
        +}}}
        +
        +######################################################################
        +# Tables are kept in endian-neutral manner
        +$code.=<<___;
        +.rdata
        +.align	6
        +AES_Te:
        +.byte	0xc6,0x63,0x63,0xa5,	0xf8,0x7c,0x7c,0x84	# Te0
        +.byte	0xee,0x77,0x77,0x99,	0xf6,0x7b,0x7b,0x8d
        +.byte	0xff,0xf2,0xf2,0x0d,	0xd6,0x6b,0x6b,0xbd
        +.byte	0xde,0x6f,0x6f,0xb1,	0x91,0xc5,0xc5,0x54
        +.byte	0x60,0x30,0x30,0x50,	0x02,0x01,0x01,0x03
        +.byte	0xce,0x67,0x67,0xa9,	0x56,0x2b,0x2b,0x7d
        +.byte	0xe7,0xfe,0xfe,0x19,	0xb5,0xd7,0xd7,0x62
        +.byte	0x4d,0xab,0xab,0xe6,	0xec,0x76,0x76,0x9a
        +.byte	0x8f,0xca,0xca,0x45,	0x1f,0x82,0x82,0x9d
        +.byte	0x89,0xc9,0xc9,0x40,	0xfa,0x7d,0x7d,0x87
        +.byte	0xef,0xfa,0xfa,0x15,	0xb2,0x59,0x59,0xeb
        +.byte	0x8e,0x47,0x47,0xc9,	0xfb,0xf0,0xf0,0x0b
        +.byte	0x41,0xad,0xad,0xec,	0xb3,0xd4,0xd4,0x67
        +.byte	0x5f,0xa2,0xa2,0xfd,	0x45,0xaf,0xaf,0xea
        +.byte	0x23,0x9c,0x9c,0xbf,	0x53,0xa4,0xa4,0xf7
        +.byte	0xe4,0x72,0x72,0x96,	0x9b,0xc0,0xc0,0x5b
        +.byte	0x75,0xb7,0xb7,0xc2,	0xe1,0xfd,0xfd,0x1c
        +.byte	0x3d,0x93,0x93,0xae,	0x4c,0x26,0x26,0x6a
        +.byte	0x6c,0x36,0x36,0x5a,	0x7e,0x3f,0x3f,0x41
        +.byte	0xf5,0xf7,0xf7,0x02,	0x83,0xcc,0xcc,0x4f
        +.byte	0x68,0x34,0x34,0x5c,	0x51,0xa5,0xa5,0xf4
        +.byte	0xd1,0xe5,0xe5,0x34,	0xf9,0xf1,0xf1,0x08
        +.byte	0xe2,0x71,0x71,0x93,	0xab,0xd8,0xd8,0x73
        +.byte	0x62,0x31,0x31,0x53,	0x2a,0x15,0x15,0x3f
        +.byte	0x08,0x04,0x04,0x0c,	0x95,0xc7,0xc7,0x52
        +.byte	0x46,0x23,0x23,0x65,	0x9d,0xc3,0xc3,0x5e
        +.byte	0x30,0x18,0x18,0x28,	0x37,0x96,0x96,0xa1
        +.byte	0x0a,0x05,0x05,0x0f,	0x2f,0x9a,0x9a,0xb5
        +.byte	0x0e,0x07,0x07,0x09,	0x24,0x12,0x12,0x36
        +.byte	0x1b,0x80,0x80,0x9b,	0xdf,0xe2,0xe2,0x3d
        +.byte	0xcd,0xeb,0xeb,0x26,	0x4e,0x27,0x27,0x69
        +.byte	0x7f,0xb2,0xb2,0xcd,	0xea,0x75,0x75,0x9f
        +.byte	0x12,0x09,0x09,0x1b,	0x1d,0x83,0x83,0x9e
        +.byte	0x58,0x2c,0x2c,0x74,	0x34,0x1a,0x1a,0x2e
        +.byte	0x36,0x1b,0x1b,0x2d,	0xdc,0x6e,0x6e,0xb2
        +.byte	0xb4,0x5a,0x5a,0xee,	0x5b,0xa0,0xa0,0xfb
        +.byte	0xa4,0x52,0x52,0xf6,	0x76,0x3b,0x3b,0x4d
        +.byte	0xb7,0xd6,0xd6,0x61,	0x7d,0xb3,0xb3,0xce
        +.byte	0x52,0x29,0x29,0x7b,	0xdd,0xe3,0xe3,0x3e
        +.byte	0x5e,0x2f,0x2f,0x71,	0x13,0x84,0x84,0x97
        +.byte	0xa6,0x53,0x53,0xf5,	0xb9,0xd1,0xd1,0x68
        +.byte	0x00,0x00,0x00,0x00,	0xc1,0xed,0xed,0x2c
        +.byte	0x40,0x20,0x20,0x60,	0xe3,0xfc,0xfc,0x1f
        +.byte	0x79,0xb1,0xb1,0xc8,	0xb6,0x5b,0x5b,0xed
        +.byte	0xd4,0x6a,0x6a,0xbe,	0x8d,0xcb,0xcb,0x46
        +.byte	0x67,0xbe,0xbe,0xd9,	0x72,0x39,0x39,0x4b
        +.byte	0x94,0x4a,0x4a,0xde,	0x98,0x4c,0x4c,0xd4
        +.byte	0xb0,0x58,0x58,0xe8,	0x85,0xcf,0xcf,0x4a
        +.byte	0xbb,0xd0,0xd0,0x6b,	0xc5,0xef,0xef,0x2a
        +.byte	0x4f,0xaa,0xaa,0xe5,	0xed,0xfb,0xfb,0x16
        +.byte	0x86,0x43,0x43,0xc5,	0x9a,0x4d,0x4d,0xd7
        +.byte	0x66,0x33,0x33,0x55,	0x11,0x85,0x85,0x94
        +.byte	0x8a,0x45,0x45,0xcf,	0xe9,0xf9,0xf9,0x10
        +.byte	0x04,0x02,0x02,0x06,	0xfe,0x7f,0x7f,0x81
        +.byte	0xa0,0x50,0x50,0xf0,	0x78,0x3c,0x3c,0x44
        +.byte	0x25,0x9f,0x9f,0xba,	0x4b,0xa8,0xa8,0xe3
        +.byte	0xa2,0x51,0x51,0xf3,	0x5d,0xa3,0xa3,0xfe
        +.byte	0x80,0x40,0x40,0xc0,	0x05,0x8f,0x8f,0x8a
        +.byte	0x3f,0x92,0x92,0xad,	0x21,0x9d,0x9d,0xbc
        +.byte	0x70,0x38,0x38,0x48,	0xf1,0xf5,0xf5,0x04
        +.byte	0x63,0xbc,0xbc,0xdf,	0x77,0xb6,0xb6,0xc1
        +.byte	0xaf,0xda,0xda,0x75,	0x42,0x21,0x21,0x63
        +.byte	0x20,0x10,0x10,0x30,	0xe5,0xff,0xff,0x1a
        +.byte	0xfd,0xf3,0xf3,0x0e,	0xbf,0xd2,0xd2,0x6d
        +.byte	0x81,0xcd,0xcd,0x4c,	0x18,0x0c,0x0c,0x14
        +.byte	0x26,0x13,0x13,0x35,	0xc3,0xec,0xec,0x2f
        +.byte	0xbe,0x5f,0x5f,0xe1,	0x35,0x97,0x97,0xa2
        +.byte	0x88,0x44,0x44,0xcc,	0x2e,0x17,0x17,0x39
        +.byte	0x93,0xc4,0xc4,0x57,	0x55,0xa7,0xa7,0xf2
        +.byte	0xfc,0x7e,0x7e,0x82,	0x7a,0x3d,0x3d,0x47
        +.byte	0xc8,0x64,0x64,0xac,	0xba,0x5d,0x5d,0xe7
        +.byte	0x32,0x19,0x19,0x2b,	0xe6,0x73,0x73,0x95
        +.byte	0xc0,0x60,0x60,0xa0,	0x19,0x81,0x81,0x98
        +.byte	0x9e,0x4f,0x4f,0xd1,	0xa3,0xdc,0xdc,0x7f
        +.byte	0x44,0x22,0x22,0x66,	0x54,0x2a,0x2a,0x7e
        +.byte	0x3b,0x90,0x90,0xab,	0x0b,0x88,0x88,0x83
        +.byte	0x8c,0x46,0x46,0xca,	0xc7,0xee,0xee,0x29
        +.byte	0x6b,0xb8,0xb8,0xd3,	0x28,0x14,0x14,0x3c
        +.byte	0xa7,0xde,0xde,0x79,	0xbc,0x5e,0x5e,0xe2
        +.byte	0x16,0x0b,0x0b,0x1d,	0xad,0xdb,0xdb,0x76
        +.byte	0xdb,0xe0,0xe0,0x3b,	0x64,0x32,0x32,0x56
        +.byte	0x74,0x3a,0x3a,0x4e,	0x14,0x0a,0x0a,0x1e
        +.byte	0x92,0x49,0x49,0xdb,	0x0c,0x06,0x06,0x0a
        +.byte	0x48,0x24,0x24,0x6c,	0xb8,0x5c,0x5c,0xe4
        +.byte	0x9f,0xc2,0xc2,0x5d,	0xbd,0xd3,0xd3,0x6e
        +.byte	0x43,0xac,0xac,0xef,	0xc4,0x62,0x62,0xa6
        +.byte	0x39,0x91,0x91,0xa8,	0x31,0x95,0x95,0xa4
        +.byte	0xd3,0xe4,0xe4,0x37,	0xf2,0x79,0x79,0x8b
        +.byte	0xd5,0xe7,0xe7,0x32,	0x8b,0xc8,0xc8,0x43
        +.byte	0x6e,0x37,0x37,0x59,	0xda,0x6d,0x6d,0xb7
        +.byte	0x01,0x8d,0x8d,0x8c,	0xb1,0xd5,0xd5,0x64
        +.byte	0x9c,0x4e,0x4e,0xd2,	0x49,0xa9,0xa9,0xe0
        +.byte	0xd8,0x6c,0x6c,0xb4,	0xac,0x56,0x56,0xfa
        +.byte	0xf3,0xf4,0xf4,0x07,	0xcf,0xea,0xea,0x25
        +.byte	0xca,0x65,0x65,0xaf,	0xf4,0x7a,0x7a,0x8e
        +.byte	0x47,0xae,0xae,0xe9,	0x10,0x08,0x08,0x18
        +.byte	0x6f,0xba,0xba,0xd5,	0xf0,0x78,0x78,0x88
        +.byte	0x4a,0x25,0x25,0x6f,	0x5c,0x2e,0x2e,0x72
        +.byte	0x38,0x1c,0x1c,0x24,	0x57,0xa6,0xa6,0xf1
        +.byte	0x73,0xb4,0xb4,0xc7,	0x97,0xc6,0xc6,0x51
        +.byte	0xcb,0xe8,0xe8,0x23,	0xa1,0xdd,0xdd,0x7c
        +.byte	0xe8,0x74,0x74,0x9c,	0x3e,0x1f,0x1f,0x21
        +.byte	0x96,0x4b,0x4b,0xdd,	0x61,0xbd,0xbd,0xdc
        +.byte	0x0d,0x8b,0x8b,0x86,	0x0f,0x8a,0x8a,0x85
        +.byte	0xe0,0x70,0x70,0x90,	0x7c,0x3e,0x3e,0x42
        +.byte	0x71,0xb5,0xb5,0xc4,	0xcc,0x66,0x66,0xaa
        +.byte	0x90,0x48,0x48,0xd8,	0x06,0x03,0x03,0x05
        +.byte	0xf7,0xf6,0xf6,0x01,	0x1c,0x0e,0x0e,0x12
        +.byte	0xc2,0x61,0x61,0xa3,	0x6a,0x35,0x35,0x5f
        +.byte	0xae,0x57,0x57,0xf9,	0x69,0xb9,0xb9,0xd0
        +.byte	0x17,0x86,0x86,0x91,	0x99,0xc1,0xc1,0x58
        +.byte	0x3a,0x1d,0x1d,0x27,	0x27,0x9e,0x9e,0xb9
        +.byte	0xd9,0xe1,0xe1,0x38,	0xeb,0xf8,0xf8,0x13
        +.byte	0x2b,0x98,0x98,0xb3,	0x22,0x11,0x11,0x33
        +.byte	0xd2,0x69,0x69,0xbb,	0xa9,0xd9,0xd9,0x70
        +.byte	0x07,0x8e,0x8e,0x89,	0x33,0x94,0x94,0xa7
        +.byte	0x2d,0x9b,0x9b,0xb6,	0x3c,0x1e,0x1e,0x22
        +.byte	0x15,0x87,0x87,0x92,	0xc9,0xe9,0xe9,0x20
        +.byte	0x87,0xce,0xce,0x49,	0xaa,0x55,0x55,0xff
        +.byte	0x50,0x28,0x28,0x78,	0xa5,0xdf,0xdf,0x7a
        +.byte	0x03,0x8c,0x8c,0x8f,	0x59,0xa1,0xa1,0xf8
        +.byte	0x09,0x89,0x89,0x80,	0x1a,0x0d,0x0d,0x17
        +.byte	0x65,0xbf,0xbf,0xda,	0xd7,0xe6,0xe6,0x31
        +.byte	0x84,0x42,0x42,0xc6,	0xd0,0x68,0x68,0xb8
        +.byte	0x82,0x41,0x41,0xc3,	0x29,0x99,0x99,0xb0
        +.byte	0x5a,0x2d,0x2d,0x77,	0x1e,0x0f,0x0f,0x11
        +.byte	0x7b,0xb0,0xb0,0xcb,	0xa8,0x54,0x54,0xfc
        +.byte	0x6d,0xbb,0xbb,0xd6,	0x2c,0x16,0x16,0x3a
        +
        +.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5	# Te4
        +.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +
        +.byte	0x01,0x00,0x00,0x00,	0x02,0x00,0x00,0x00	# rcon
        +.byte	0x04,0x00,0x00,0x00,	0x08,0x00,0x00,0x00
        +.byte	0x10,0x00,0x00,0x00,	0x20,0x00,0x00,0x00
        +.byte	0x40,0x00,0x00,0x00,	0x80,0x00,0x00,0x00
        +.byte	0x1B,0x00,0x00,0x00,	0x36,0x00,0x00,0x00
        +
        +.align	6
        +AES_Td:
        +.byte	0x51,0xf4,0xa7,0x50,	0x7e,0x41,0x65,0x53	# Td0
        +.byte	0x1a,0x17,0xa4,0xc3,	0x3a,0x27,0x5e,0x96
        +.byte	0x3b,0xab,0x6b,0xcb,	0x1f,0x9d,0x45,0xf1
        +.byte	0xac,0xfa,0x58,0xab,	0x4b,0xe3,0x03,0x93
        +.byte	0x20,0x30,0xfa,0x55,	0xad,0x76,0x6d,0xf6
        +.byte	0x88,0xcc,0x76,0x91,	0xf5,0x02,0x4c,0x25
        +.byte	0x4f,0xe5,0xd7,0xfc,	0xc5,0x2a,0xcb,0xd7
        +.byte	0x26,0x35,0x44,0x80,	0xb5,0x62,0xa3,0x8f
        +.byte	0xde,0xb1,0x5a,0x49,	0x25,0xba,0x1b,0x67
        +.byte	0x45,0xea,0x0e,0x98,	0x5d,0xfe,0xc0,0xe1
        +.byte	0xc3,0x2f,0x75,0x02,	0x81,0x4c,0xf0,0x12
        +.byte	0x8d,0x46,0x97,0xa3,	0x6b,0xd3,0xf9,0xc6
        +.byte	0x03,0x8f,0x5f,0xe7,	0x15,0x92,0x9c,0x95
        +.byte	0xbf,0x6d,0x7a,0xeb,	0x95,0x52,0x59,0xda
        +.byte	0xd4,0xbe,0x83,0x2d,	0x58,0x74,0x21,0xd3
        +.byte	0x49,0xe0,0x69,0x29,	0x8e,0xc9,0xc8,0x44
        +.byte	0x75,0xc2,0x89,0x6a,	0xf4,0x8e,0x79,0x78
        +.byte	0x99,0x58,0x3e,0x6b,	0x27,0xb9,0x71,0xdd
        +.byte	0xbe,0xe1,0x4f,0xb6,	0xf0,0x88,0xad,0x17
        +.byte	0xc9,0x20,0xac,0x66,	0x7d,0xce,0x3a,0xb4
        +.byte	0x63,0xdf,0x4a,0x18,	0xe5,0x1a,0x31,0x82
        +.byte	0x97,0x51,0x33,0x60,	0x62,0x53,0x7f,0x45
        +.byte	0xb1,0x64,0x77,0xe0,	0xbb,0x6b,0xae,0x84
        +.byte	0xfe,0x81,0xa0,0x1c,	0xf9,0x08,0x2b,0x94
        +.byte	0x70,0x48,0x68,0x58,	0x8f,0x45,0xfd,0x19
        +.byte	0x94,0xde,0x6c,0x87,	0x52,0x7b,0xf8,0xb7
        +.byte	0xab,0x73,0xd3,0x23,	0x72,0x4b,0x02,0xe2
        +.byte	0xe3,0x1f,0x8f,0x57,	0x66,0x55,0xab,0x2a
        +.byte	0xb2,0xeb,0x28,0x07,	0x2f,0xb5,0xc2,0x03
        +.byte	0x86,0xc5,0x7b,0x9a,	0xd3,0x37,0x08,0xa5
        +.byte	0x30,0x28,0x87,0xf2,	0x23,0xbf,0xa5,0xb2
        +.byte	0x02,0x03,0x6a,0xba,	0xed,0x16,0x82,0x5c
        +.byte	0x8a,0xcf,0x1c,0x2b,	0xa7,0x79,0xb4,0x92
        +.byte	0xf3,0x07,0xf2,0xf0,	0x4e,0x69,0xe2,0xa1
        +.byte	0x65,0xda,0xf4,0xcd,	0x06,0x05,0xbe,0xd5
        +.byte	0xd1,0x34,0x62,0x1f,	0xc4,0xa6,0xfe,0x8a
        +.byte	0x34,0x2e,0x53,0x9d,	0xa2,0xf3,0x55,0xa0
        +.byte	0x05,0x8a,0xe1,0x32,	0xa4,0xf6,0xeb,0x75
        +.byte	0x0b,0x83,0xec,0x39,	0x40,0x60,0xef,0xaa
        +.byte	0x5e,0x71,0x9f,0x06,	0xbd,0x6e,0x10,0x51
        +.byte	0x3e,0x21,0x8a,0xf9,	0x96,0xdd,0x06,0x3d
        +.byte	0xdd,0x3e,0x05,0xae,	0x4d,0xe6,0xbd,0x46
        +.byte	0x91,0x54,0x8d,0xb5,	0x71,0xc4,0x5d,0x05
        +.byte	0x04,0x06,0xd4,0x6f,	0x60,0x50,0x15,0xff
        +.byte	0x19,0x98,0xfb,0x24,	0xd6,0xbd,0xe9,0x97
        +.byte	0x89,0x40,0x43,0xcc,	0x67,0xd9,0x9e,0x77
        +.byte	0xb0,0xe8,0x42,0xbd,	0x07,0x89,0x8b,0x88
        +.byte	0xe7,0x19,0x5b,0x38,	0x79,0xc8,0xee,0xdb
        +.byte	0xa1,0x7c,0x0a,0x47,	0x7c,0x42,0x0f,0xe9
        +.byte	0xf8,0x84,0x1e,0xc9,	0x00,0x00,0x00,0x00
        +.byte	0x09,0x80,0x86,0x83,	0x32,0x2b,0xed,0x48
        +.byte	0x1e,0x11,0x70,0xac,	0x6c,0x5a,0x72,0x4e
        +.byte	0xfd,0x0e,0xff,0xfb,	0x0f,0x85,0x38,0x56
        +.byte	0x3d,0xae,0xd5,0x1e,	0x36,0x2d,0x39,0x27
        +.byte	0x0a,0x0f,0xd9,0x64,	0x68,0x5c,0xa6,0x21
        +.byte	0x9b,0x5b,0x54,0xd1,	0x24,0x36,0x2e,0x3a
        +.byte	0x0c,0x0a,0x67,0xb1,	0x93,0x57,0xe7,0x0f
        +.byte	0xb4,0xee,0x96,0xd2,	0x1b,0x9b,0x91,0x9e
        +.byte	0x80,0xc0,0xc5,0x4f,	0x61,0xdc,0x20,0xa2
        +.byte	0x5a,0x77,0x4b,0x69,	0x1c,0x12,0x1a,0x16
        +.byte	0xe2,0x93,0xba,0x0a,	0xc0,0xa0,0x2a,0xe5
        +.byte	0x3c,0x22,0xe0,0x43,	0x12,0x1b,0x17,0x1d
        +.byte	0x0e,0x09,0x0d,0x0b,	0xf2,0x8b,0xc7,0xad
        +.byte	0x2d,0xb6,0xa8,0xb9,	0x14,0x1e,0xa9,0xc8
        +.byte	0x57,0xf1,0x19,0x85,	0xaf,0x75,0x07,0x4c
        +.byte	0xee,0x99,0xdd,0xbb,	0xa3,0x7f,0x60,0xfd
        +.byte	0xf7,0x01,0x26,0x9f,	0x5c,0x72,0xf5,0xbc
        +.byte	0x44,0x66,0x3b,0xc5,	0x5b,0xfb,0x7e,0x34
        +.byte	0x8b,0x43,0x29,0x76,	0xcb,0x23,0xc6,0xdc
        +.byte	0xb6,0xed,0xfc,0x68,	0xb8,0xe4,0xf1,0x63
        +.byte	0xd7,0x31,0xdc,0xca,	0x42,0x63,0x85,0x10
        +.byte	0x13,0x97,0x22,0x40,	0x84,0xc6,0x11,0x20
        +.byte	0x85,0x4a,0x24,0x7d,	0xd2,0xbb,0x3d,0xf8
        +.byte	0xae,0xf9,0x32,0x11,	0xc7,0x29,0xa1,0x6d
        +.byte	0x1d,0x9e,0x2f,0x4b,	0xdc,0xb2,0x30,0xf3
        +.byte	0x0d,0x86,0x52,0xec,	0x77,0xc1,0xe3,0xd0
        +.byte	0x2b,0xb3,0x16,0x6c,	0xa9,0x70,0xb9,0x99
        +.byte	0x11,0x94,0x48,0xfa,	0x47,0xe9,0x64,0x22
        +.byte	0xa8,0xfc,0x8c,0xc4,	0xa0,0xf0,0x3f,0x1a
        +.byte	0x56,0x7d,0x2c,0xd8,	0x22,0x33,0x90,0xef
        +.byte	0x87,0x49,0x4e,0xc7,	0xd9,0x38,0xd1,0xc1
        +.byte	0x8c,0xca,0xa2,0xfe,	0x98,0xd4,0x0b,0x36
        +.byte	0xa6,0xf5,0x81,0xcf,	0xa5,0x7a,0xde,0x28
        +.byte	0xda,0xb7,0x8e,0x26,	0x3f,0xad,0xbf,0xa4
        +.byte	0x2c,0x3a,0x9d,0xe4,	0x50,0x78,0x92,0x0d
        +.byte	0x6a,0x5f,0xcc,0x9b,	0x54,0x7e,0x46,0x62
        +.byte	0xf6,0x8d,0x13,0xc2,	0x90,0xd8,0xb8,0xe8
        +.byte	0x2e,0x39,0xf7,0x5e,	0x82,0xc3,0xaf,0xf5
        +.byte	0x9f,0x5d,0x80,0xbe,	0x69,0xd0,0x93,0x7c
        +.byte	0x6f,0xd5,0x2d,0xa9,	0xcf,0x25,0x12,0xb3
        +.byte	0xc8,0xac,0x99,0x3b,	0x10,0x18,0x7d,0xa7
        +.byte	0xe8,0x9c,0x63,0x6e,	0xdb,0x3b,0xbb,0x7b
        +.byte	0xcd,0x26,0x78,0x09,	0x6e,0x59,0x18,0xf4
        +.byte	0xec,0x9a,0xb7,0x01,	0x83,0x4f,0x9a,0xa8
        +.byte	0xe6,0x95,0x6e,0x65,	0xaa,0xff,0xe6,0x7e
        +.byte	0x21,0xbc,0xcf,0x08,	0xef,0x15,0xe8,0xe6
        +.byte	0xba,0xe7,0x9b,0xd9,	0x4a,0x6f,0x36,0xce
        +.byte	0xea,0x9f,0x09,0xd4,	0x29,0xb0,0x7c,0xd6
        +.byte	0x31,0xa4,0xb2,0xaf,	0x2a,0x3f,0x23,0x31
        +.byte	0xc6,0xa5,0x94,0x30,	0x35,0xa2,0x66,0xc0
        +.byte	0x74,0x4e,0xbc,0x37,	0xfc,0x82,0xca,0xa6
        +.byte	0xe0,0x90,0xd0,0xb0,	0x33,0xa7,0xd8,0x15
        +.byte	0xf1,0x04,0x98,0x4a,	0x41,0xec,0xda,0xf7
        +.byte	0x7f,0xcd,0x50,0x0e,	0x17,0x91,0xf6,0x2f
        +.byte	0x76,0x4d,0xd6,0x8d,	0x43,0xef,0xb0,0x4d
        +.byte	0xcc,0xaa,0x4d,0x54,	0xe4,0x96,0x04,0xdf
        +.byte	0x9e,0xd1,0xb5,0xe3,	0x4c,0x6a,0x88,0x1b
        +.byte	0xc1,0x2c,0x1f,0xb8,	0x46,0x65,0x51,0x7f
        +.byte	0x9d,0x5e,0xea,0x04,	0x01,0x8c,0x35,0x5d
        +.byte	0xfa,0x87,0x74,0x73,	0xfb,0x0b,0x41,0x2e
        +.byte	0xb3,0x67,0x1d,0x5a,	0x92,0xdb,0xd2,0x52
        +.byte	0xe9,0x10,0x56,0x33,	0x6d,0xd6,0x47,0x13
        +.byte	0x9a,0xd7,0x61,0x8c,	0x37,0xa1,0x0c,0x7a
        +.byte	0x59,0xf8,0x14,0x8e,	0xeb,0x13,0x3c,0x89
        +.byte	0xce,0xa9,0x27,0xee,	0xb7,0x61,0xc9,0x35
        +.byte	0xe1,0x1c,0xe5,0xed,	0x7a,0x47,0xb1,0x3c
        +.byte	0x9c,0xd2,0xdf,0x59,	0x55,0xf2,0x73,0x3f
        +.byte	0x18,0x14,0xce,0x79,	0x73,0xc7,0x37,0xbf
        +.byte	0x53,0xf7,0xcd,0xea,	0x5f,0xfd,0xaa,0x5b
        +.byte	0xdf,0x3d,0x6f,0x14,	0x78,0x44,0xdb,0x86
        +.byte	0xca,0xaf,0xf3,0x81,	0xb9,0x68,0xc4,0x3e
        +.byte	0x38,0x24,0x34,0x2c,	0xc2,0xa3,0x40,0x5f
        +.byte	0x16,0x1d,0xc3,0x72,	0xbc,0xe2,0x25,0x0c
        +.byte	0x28,0x3c,0x49,0x8b,	0xff,0x0d,0x95,0x41
        +.byte	0x39,0xa8,0x01,0x71,	0x08,0x0c,0xb3,0xde
        +.byte	0xd8,0xb4,0xe4,0x9c,	0x64,0x56,0xc1,0x90
        +.byte	0x7b,0xcb,0x84,0x61,	0xd5,0x32,0xb6,0x70
        +.byte	0x48,0x6c,0x5c,0x74,	0xd0,0xb8,0x57,0x42
        +
        +.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38	# Td4
        +.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +___
        +
        +foreach (split("\n",$code)) {
        +	s/\`([^\`]*)\`/eval $1/ge;
        +
        +	# made-up _instructions, _xtr, _ins, _ror and _bias, cope
        +	# with byte order dependencies...
        +	if (/^\s+_/) {
        +	    s/(_[a-z]+\s+)(\$[0-9]+),([^,]+)(#.*)*$/$1$2,$2,$3/;
        +
        +	    s/_xtr\s+(\$[0-9]+),(\$[0-9]+),([0-9]+(\-2)*)/
        +		sprintf("srl\t$1,$2,%d",$big_endian ?	eval($3)
        +					:		eval("24-$3"))/e or
        +	    s/_ins\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
        +		sprintf("sll\t$1,$2,%d",$big_endian ?	eval($3)
        +					:		eval("24-$3"))/e or
        +	    s/_ror\s+(\$[0-9]+),(\$[0-9]+),(\-?[0-9]+)/
        +		sprintf("srl\t$1,$2,%d",$big_endian ?	eval($3)
        +					:		eval("$3*-1"))/e or
        +	    s/_bias\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
        +		sprintf("sll\t$1,$2,%d",$big_endian ?	eval($3)
        +					:		eval("($3-16)&31"))/e;
        +
        +	    s/srl\s+(\$[0-9]+),(\$[0-9]+),\-([0-9]+)/
        +		sprintf("sll\t$1,$2,$3")/e				or
        +	    s/srl\s+(\$[0-9]+),(\$[0-9]+),0/
        +		sprintf("and\t$1,$2,0xff")/e				or
        +	    s/(sll\s+\$[0-9]+,\$[0-9]+,0)/#$1/;
        +	}
        +
        +	# convert lwl/lwr and swr/swl to little-endian order
        +	if (!$big_endian && /^\s+[sl]w[lr]\s+/) {
        +	    s/([sl]wl.*)([0-9]+)\((\$[0-9]+)\)/
        +		sprintf("$1%d($3)",eval("$2-$2%4+($2%4-1)&3"))/e	or
        +	    s/([sl]wr.*)([0-9]+)\((\$[0-9]+)\)/
        +		sprintf("$1%d($3)",eval("$2-$2%4+($2%4+1)&3"))/e;
        +	}
        +
        +	print $_,"\n";
        +}
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-parisc.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-parisc.pl
        new file mode 100644
        index 000000000..c36b6a227
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-parisc.pl
        @@ -0,0 +1,1021 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# AES for PA-RISC.
        +#
        +# June 2009.
        +#
        +# The module is mechanical transliteration of aes-sparcv9.pl, but with
        +# a twist: S-boxes are compressed even further down to 1K+256B. On
        +# PA-7100LC performance is ~40% better than gcc 3.2 generated code and
        +# is about 33 cycles per byte processed with 128-bit key. Newer CPUs
        +# perform at 16 cycles per byte. It's not faster than code generated
        +# by vendor compiler, but recall that it has compressed S-boxes, which
        +# requires extra processing.
        +#
        +# Special thanks to polarhome.com for providing HP-UX account.
        +
        +$flavour = shift;
        +$output = shift;
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$FRAME_MARKER	=80;
        +	$SAVED_RP	=16;
        +	$PUSH		="std";
        +	$PUSHMA		="std,ma";
        +	$POP		="ldd";
        +	$POPMB		="ldd,mb";
        +} else {
        +	$LEVEL		="1.0";
        +	$SIZE_T		=4;
        +	$FRAME_MARKER	=48;
        +	$SAVED_RP	=20;
        +	$PUSH		="stw";
        +	$PUSHMA		="stwm";
        +	$POP		="ldw";
        +	$POPMB		="ldwm";
        +}
        +
        +$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker
        +				#                 [+ argument transfer]
        +$inp="%r26";	# arg0
        +$out="%r25";	# arg1
        +$key="%r24";	# arg2
        +
        +($s0,$s1,$s2,$s3) = ("%r1","%r2","%r3","%r4");
        +($t0,$t1,$t2,$t3) = ("%r5","%r6","%r7","%r8");
        +
        +($acc0, $acc1, $acc2, $acc3, $acc4, $acc5, $acc6, $acc7,
        + $acc8, $acc9,$acc10,$acc11,$acc12,$acc13,$acc14,$acc15) =
        +("%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16",
        +"%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r26");
        +
        +$tbl="%r28";
        +$rounds="%r29";
        +
        +$code=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.EXPORT	AES_encrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
        +	.ALIGN	64
        +AES_encrypt
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
        +	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
        +	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
        +	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
        +	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
        +	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
        +	$PUSH	%r17,`-$FRAME+14*$SIZE_T`(%sp)
        +	$PUSH	%r18,`-$FRAME+15*$SIZE_T`(%sp)
        +
        +	blr	%r0,$tbl
        +	ldi	3,$t0
        +L\$enc_pic
        +	andcm	$tbl,$t0,$tbl
        +	ldo	L\$AES_Te-L\$enc_pic($tbl),$tbl
        +
        +	and	$inp,$t0,$t0
        +	sub	$inp,$t0,$inp
        +	ldw	0($inp),$s0
        +	ldw	4($inp),$s1
        +	ldw	8($inp),$s2
        +	comib,=	0,$t0,L\$enc_inp_aligned
        +	ldw	12($inp),$s3
        +
        +	sh3addl	$t0,%r0,$t0
        +	subi	32,$t0,$t0
        +	mtctl	$t0,%cr11
        +	ldw	16($inp),$t1
        +	vshd	$s0,$s1,$s0
        +	vshd	$s1,$s2,$s1
        +	vshd	$s2,$s3,$s2
        +	vshd	$s3,$t1,$s3
        +
        +L\$enc_inp_aligned
        +	bl	_parisc_AES_encrypt,%r31
        +	nop
        +
        +	extru,<> $out,31,2,%r0
        +	b	L\$enc_out_aligned
        +	nop
        +
        +	_srm	$s0,24,$acc0
        +	_srm	$s0,16,$acc1
        +	stb	$acc0,0($out)
        +	_srm	$s0,8,$acc2
        +	stb	$acc1,1($out)
        +	_srm	$s1,24,$acc4
        +	stb	$acc2,2($out)
        +	_srm	$s1,16,$acc5
        +	stb	$s0,3($out)
        +	_srm	$s1,8,$acc6
        +	stb	$acc4,4($out)
        +	_srm	$s2,24,$acc0
        +	stb	$acc5,5($out)
        +	_srm	$s2,16,$acc1
        +	stb	$acc6,6($out)
        +	_srm	$s2,8,$acc2
        +	stb	$s1,7($out)
        +	_srm	$s3,24,$acc4
        +	stb	$acc0,8($out)
        +	_srm	$s3,16,$acc5
        +	stb	$acc1,9($out)
        +	_srm	$s3,8,$acc6
        +	stb	$acc2,10($out)
        +	stb	$s2,11($out)
        +	stb	$acc4,12($out)
        +	stb	$acc5,13($out)
        +	stb	$acc6,14($out)
        +	b	L\$enc_done
        +	stb	$s3,15($out)
        +
        +L\$enc_out_aligned
        +	stw	$s0,0($out)
        +	stw	$s1,4($out)
        +	stw	$s2,8($out)
        +	stw	$s3,12($out)
        +
        +L\$enc_done
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
        +	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
        +	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
        +	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
        +	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
        +	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
        +	$POP	`-$FRAME+14*$SIZE_T`(%sp),%r17
        +	$POP	`-$FRAME+15*$SIZE_T`(%sp),%r18
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +
        +	.ALIGN	16
        +_parisc_AES_encrypt
        +	.PROC
        +	.CALLINFO	MILLICODE
        +	.ENTRY
        +	ldw	240($key),$rounds
        +	ldw	0($key),$t0
        +	ldw	4($key),$t1
        +	ldw	8($key),$t2
        +	_srm	$rounds,1,$rounds
        +	xor	$t0,$s0,$s0
        +	ldw	12($key),$t3
        +	_srm	$s0,24,$acc0
        +	xor	$t1,$s1,$s1
        +	ldw	16($key),$t0
        +	_srm	$s1,16,$acc1
        +	xor	$t2,$s2,$s2
        +	ldw	20($key),$t1
        +	xor	$t3,$s3,$s3
        +	ldw	24($key),$t2
        +	ldw	28($key),$t3
        +L\$enc_loop
        +	_srm	$s2,8,$acc2
        +	ldwx,s	$acc0($tbl),$acc0
        +	_srm	$s3,0,$acc3
        +	ldwx,s	$acc1($tbl),$acc1
        +	_srm	$s1,24,$acc4
        +	ldwx,s	$acc2($tbl),$acc2
        +	_srm	$s2,16,$acc5
        +	ldwx,s	$acc3($tbl),$acc3
        +	_srm	$s3,8,$acc6
        +	ldwx,s	$acc4($tbl),$acc4
        +	_srm	$s0,0,$acc7
        +	ldwx,s	$acc5($tbl),$acc5
        +	_srm	$s2,24,$acc8
        +	ldwx,s	$acc6($tbl),$acc6
        +	_srm	$s3,16,$acc9
        +	ldwx,s	$acc7($tbl),$acc7
        +	_srm	$s0,8,$acc10
        +	ldwx,s	$acc8($tbl),$acc8
        +	_srm	$s1,0,$acc11
        +	ldwx,s	$acc9($tbl),$acc9
        +	_srm	$s3,24,$acc12
        +	ldwx,s	$acc10($tbl),$acc10
        +	_srm	$s0,16,$acc13
        +	ldwx,s	$acc11($tbl),$acc11
        +	_srm	$s1,8,$acc14
        +	ldwx,s	$acc12($tbl),$acc12
        +	_srm	$s2,0,$acc15
        +	ldwx,s	$acc13($tbl),$acc13
        +	ldwx,s	$acc14($tbl),$acc14
        +	ldwx,s	$acc15($tbl),$acc15
        +	addib,= -1,$rounds,L\$enc_last
        +	ldo	32($key),$key
        +
        +		_ror	$acc1,8,$acc1
        +		xor	$acc0,$t0,$t0
        +	ldw	0($key),$s0
        +		_ror	$acc2,16,$acc2
        +		xor	$acc1,$t0,$t0
        +	ldw	4($key),$s1
        +		_ror	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ldw	8($key),$s2
        +		_ror	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ldw	12($key),$s3
        +		_ror	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +		_ror	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		_ror	$acc9,8,$acc9
        +		xor	$acc6,$t1,$t1
        +		_ror	$acc10,16,$acc10
        +		xor	$acc7,$t1,$t1
        +		_ror	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		_ror	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		_ror	$acc14,16,$acc14
        +		xor	$acc10,$t2,$t2
        +		_ror	$acc15,24,$acc15
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	_srm	$t0,24,$acc0
        +		xor	$acc14,$t3,$t3
        +	_srm	$t1,16,$acc1
        +		xor	$acc15,$t3,$t3
        +
        +	_srm	$t2,8,$acc2
        +	ldwx,s	$acc0($tbl),$acc0
        +	_srm	$t3,0,$acc3
        +	ldwx,s	$acc1($tbl),$acc1
        +	_srm	$t1,24,$acc4
        +	ldwx,s	$acc2($tbl),$acc2
        +	_srm	$t2,16,$acc5
        +	ldwx,s	$acc3($tbl),$acc3
        +	_srm	$t3,8,$acc6
        +	ldwx,s	$acc4($tbl),$acc4
        +	_srm	$t0,0,$acc7
        +	ldwx,s	$acc5($tbl),$acc5
        +	_srm	$t2,24,$acc8
        +	ldwx,s	$acc6($tbl),$acc6
        +	_srm	$t3,16,$acc9
        +	ldwx,s	$acc7($tbl),$acc7
        +	_srm	$t0,8,$acc10
        +	ldwx,s	$acc8($tbl),$acc8
        +	_srm	$t1,0,$acc11
        +	ldwx,s	$acc9($tbl),$acc9
        +	_srm	$t3,24,$acc12
        +	ldwx,s	$acc10($tbl),$acc10
        +	_srm	$t0,16,$acc13
        +	ldwx,s	$acc11($tbl),$acc11
        +	_srm	$t1,8,$acc14
        +	ldwx,s	$acc12($tbl),$acc12
        +	_srm	$t2,0,$acc15
        +	ldwx,s	$acc13($tbl),$acc13
        +		_ror	$acc1,8,$acc1
        +	ldwx,s	$acc14($tbl),$acc14
        +
        +		_ror	$acc2,16,$acc2
        +		xor	$acc0,$s0,$s0
        +	ldwx,s	$acc15($tbl),$acc15
        +		_ror	$acc3,24,$acc3
        +		xor	$acc1,$s0,$s0
        +	ldw	16($key),$t0
        +		_ror	$acc5,8,$acc5
        +		xor	$acc2,$s0,$s0
        +	ldw	20($key),$t1
        +		_ror	$acc6,16,$acc6
        +		xor	$acc3,$s0,$s0
        +	ldw	24($key),$t2
        +		_ror	$acc7,24,$acc7
        +		xor	$acc4,$s1,$s1
        +	ldw	28($key),$t3
        +		_ror	$acc9,8,$acc9
        +		xor	$acc5,$s1,$s1
        +	ldw	1024+0($tbl),%r0		; prefetch te4
        +		_ror	$acc10,16,$acc10
        +		xor	$acc6,$s1,$s1
        +	ldw	1024+32($tbl),%r0		; prefetch te4
        +		_ror	$acc11,24,$acc11
        +		xor	$acc7,$s1,$s1
        +	ldw	1024+64($tbl),%r0		; prefetch te4
        +		_ror	$acc13,8,$acc13
        +		xor	$acc8,$s2,$s2
        +	ldw	1024+96($tbl),%r0		; prefetch te4
        +		_ror	$acc14,16,$acc14
        +		xor	$acc9,$s2,$s2
        +	ldw	1024+128($tbl),%r0		; prefetch te4
        +		_ror	$acc15,24,$acc15
        +		xor	$acc10,$s2,$s2
        +	ldw	1024+160($tbl),%r0		; prefetch te4
        +	_srm	$s0,24,$acc0
        +		xor	$acc11,$s2,$s2
        +	ldw	1024+192($tbl),%r0		; prefetch te4
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$s3,$s3
        +	ldw	1024+224($tbl),%r0		; prefetch te4
        +	_srm	$s1,16,$acc1
        +		xor	$acc14,$s3,$s3
        +	b	L\$enc_loop
        +		xor	$acc15,$s3,$s3
        +
        +	.ALIGN	16
        +L\$enc_last
        +	ldo	1024($tbl),$rounds
        +		_ror	$acc1,8,$acc1
        +		xor	$acc0,$t0,$t0
        +	ldw	0($key),$s0
        +		_ror	$acc2,16,$acc2
        +		xor	$acc1,$t0,$t0
        +	ldw	4($key),$s1
        +		_ror	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ldw	8($key),$s2
        +		_ror	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ldw	12($key),$s3
        +		_ror	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +		_ror	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		_ror	$acc9,8,$acc9
        +		xor	$acc6,$t1,$t1
        +		_ror	$acc10,16,$acc10
        +		xor	$acc7,$t1,$t1
        +		_ror	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		_ror	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		_ror	$acc14,16,$acc14
        +		xor	$acc10,$t2,$t2
        +		_ror	$acc15,24,$acc15
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	_srm	$t0,24,$acc0
        +		xor	$acc14,$t3,$t3
        +	_srm	$t1,16,$acc1
        +		xor	$acc15,$t3,$t3
        +
        +	_srm	$t2,8,$acc2
        +	ldbx	$acc0($rounds),$acc0
        +	_srm	$t1,24,$acc4
        +	ldbx	$acc1($rounds),$acc1
        +	_srm	$t2,16,$acc5
        +	_srm	$t3,0,$acc3
        +	ldbx	$acc2($rounds),$acc2
        +	ldbx	$acc3($rounds),$acc3
        +	_srm	$t3,8,$acc6
        +	ldbx	$acc4($rounds),$acc4
        +	_srm	$t2,24,$acc8
        +	ldbx	$acc5($rounds),$acc5
        +	_srm	$t3,16,$acc9
        +	_srm	$t0,0,$acc7
        +	ldbx	$acc6($rounds),$acc6
        +	ldbx	$acc7($rounds),$acc7
        +	_srm	$t0,8,$acc10
        +	ldbx	$acc8($rounds),$acc8
        +	_srm	$t3,24,$acc12
        +	ldbx	$acc9($rounds),$acc9
        +	_srm	$t0,16,$acc13
        +	_srm	$t1,0,$acc11
        +	ldbx	$acc10($rounds),$acc10
        +	_srm	$t1,8,$acc14
        +	ldbx	$acc11($rounds),$acc11
        +	ldbx	$acc12($rounds),$acc12
        +	ldbx	$acc13($rounds),$acc13
        +	_srm	$t2,0,$acc15
        +	ldbx	$acc14($rounds),$acc14
        +
        +		dep	$acc0,7,8,$acc3
        +	ldbx	$acc15($rounds),$acc15
        +		dep	$acc4,7,8,$acc7
        +		dep	$acc1,15,8,$acc3
        +		dep	$acc5,15,8,$acc7
        +		dep	$acc2,23,8,$acc3
        +		dep	$acc6,23,8,$acc7
        +		xor	$acc3,$s0,$s0
        +		xor	$acc7,$s1,$s1
        +		dep	$acc8,7,8,$acc11
        +		dep	$acc12,7,8,$acc15
        +		dep	$acc9,15,8,$acc11
        +		dep	$acc13,15,8,$acc15
        +		dep	$acc10,23,8,$acc11
        +		dep	$acc14,23,8,$acc15
        +		xor	$acc11,$s2,$s2
        +
        +	bv	(%r31)
        +	.EXIT
        +		xor	$acc15,$s3,$s3
        +	.PROCEND
        +
        +	.ALIGN	64
        +L\$AES_Te
        +	.WORD	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
        +	.WORD	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
        +	.WORD	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
        +	.WORD	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
        +	.WORD	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
        +	.WORD	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
        +	.WORD	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
        +	.WORD	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
        +	.WORD	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
        +	.WORD	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
        +	.WORD	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
        +	.WORD	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
        +	.WORD	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
        +	.WORD	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
        +	.WORD	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
        +	.WORD	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
        +	.WORD	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
        +	.WORD	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
        +	.WORD	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
        +	.WORD	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
        +	.WORD	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
        +	.WORD	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
        +	.WORD	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
        +	.WORD	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
        +	.WORD	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
        +	.WORD	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
        +	.WORD	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
        +	.WORD	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
        +	.WORD	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
        +	.WORD	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
        +	.WORD	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
        +	.WORD	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
        +	.WORD	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
        +	.WORD	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
        +	.WORD	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
        +	.WORD	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
        +	.WORD	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
        +	.WORD	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
        +	.WORD	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
        +	.WORD	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
        +	.WORD	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
        +	.WORD	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
        +	.WORD	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
        +	.WORD	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
        +	.WORD	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
        +	.WORD	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
        +	.WORD	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
        +	.WORD	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
        +	.WORD	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
        +	.WORD	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
        +	.WORD	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
        +	.WORD	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
        +	.WORD	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
        +	.WORD	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
        +	.WORD	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
        +	.WORD	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
        +	.WORD	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
        +	.WORD	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
        +	.WORD	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
        +	.WORD	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
        +	.WORD	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
        +	.WORD	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
        +	.WORD	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
        +	.WORD	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
        +	.BYTE	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
        +	.BYTE	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +	.BYTE	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +	.BYTE	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +	.BYTE	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +	.BYTE	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +	.BYTE	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +	.BYTE	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +	.BYTE	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +	.BYTE	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +	.BYTE	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +	.BYTE	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +	.BYTE	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +	.BYTE	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +	.BYTE	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +	.BYTE	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +	.BYTE	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +	.BYTE	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +	.BYTE	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +	.BYTE	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +	.BYTE	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +	.BYTE	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +	.BYTE	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +	.BYTE	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +	.BYTE	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +	.BYTE	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +	.BYTE	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +	.BYTE	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +	.BYTE	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +	.BYTE	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +	.BYTE	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +	.BYTE	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +___
        +
        +$code.=<<___;
        +	.EXPORT	AES_decrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
        +	.ALIGN	16
        +AES_decrypt
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
        +	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
        +	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
        +	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
        +	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
        +	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
        +	$PUSH	%r17,`-$FRAME+14*$SIZE_T`(%sp)
        +	$PUSH	%r18,`-$FRAME+15*$SIZE_T`(%sp)
        +
        +	blr	%r0,$tbl
        +	ldi	3,$t0
        +L\$dec_pic
        +	andcm	$tbl,$t0,$tbl
        +	ldo	L\$AES_Td-L\$dec_pic($tbl),$tbl
        +
        +	and	$inp,$t0,$t0
        +	sub	$inp,$t0,$inp
        +	ldw	0($inp),$s0
        +	ldw	4($inp),$s1
        +	ldw	8($inp),$s2
        +	comib,=	0,$t0,L\$dec_inp_aligned
        +	ldw	12($inp),$s3
        +
        +	sh3addl	$t0,%r0,$t0
        +	subi	32,$t0,$t0
        +	mtctl	$t0,%cr11
        +	ldw	16($inp),$t1
        +	vshd	$s0,$s1,$s0
        +	vshd	$s1,$s2,$s1
        +	vshd	$s2,$s3,$s2
        +	vshd	$s3,$t1,$s3
        +
        +L\$dec_inp_aligned
        +	bl	_parisc_AES_decrypt,%r31
        +	nop
        +
        +	extru,<> $out,31,2,%r0
        +	b	L\$dec_out_aligned
        +	nop
        +
        +	_srm	$s0,24,$acc0
        +	_srm	$s0,16,$acc1
        +	stb	$acc0,0($out)
        +	_srm	$s0,8,$acc2
        +	stb	$acc1,1($out)
        +	_srm	$s1,24,$acc4
        +	stb	$acc2,2($out)
        +	_srm	$s1,16,$acc5
        +	stb	$s0,3($out)
        +	_srm	$s1,8,$acc6
        +	stb	$acc4,4($out)
        +	_srm	$s2,24,$acc0
        +	stb	$acc5,5($out)
        +	_srm	$s2,16,$acc1
        +	stb	$acc6,6($out)
        +	_srm	$s2,8,$acc2
        +	stb	$s1,7($out)
        +	_srm	$s3,24,$acc4
        +	stb	$acc0,8($out)
        +	_srm	$s3,16,$acc5
        +	stb	$acc1,9($out)
        +	_srm	$s3,8,$acc6
        +	stb	$acc2,10($out)
        +	stb	$s2,11($out)
        +	stb	$acc4,12($out)
        +	stb	$acc5,13($out)
        +	stb	$acc6,14($out)
        +	b	L\$dec_done
        +	stb	$s3,15($out)
        +
        +L\$dec_out_aligned
        +	stw	$s0,0($out)
        +	stw	$s1,4($out)
        +	stw	$s2,8($out)
        +	stw	$s3,12($out)
        +
        +L\$dec_done
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
        +	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
        +	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
        +	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
        +	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
        +	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
        +	$POP	`-$FRAME+14*$SIZE_T`(%sp),%r17
        +	$POP	`-$FRAME+15*$SIZE_T`(%sp),%r18
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +
        +	.ALIGN	16
        +_parisc_AES_decrypt
        +	.PROC
        +	.CALLINFO	MILLICODE
        +	.ENTRY
        +	ldw	240($key),$rounds
        +	ldw	0($key),$t0
        +	ldw	4($key),$t1
        +	ldw	8($key),$t2
        +	ldw	12($key),$t3
        +	_srm	$rounds,1,$rounds
        +	xor	$t0,$s0,$s0
        +	ldw	16($key),$t0
        +	xor	$t1,$s1,$s1
        +	ldw	20($key),$t1
        +	_srm	$s0,24,$acc0
        +	xor	$t2,$s2,$s2
        +	ldw	24($key),$t2
        +	xor	$t3,$s3,$s3
        +	ldw	28($key),$t3
        +	_srm	$s3,16,$acc1
        +L\$dec_loop
        +	_srm	$s2,8,$acc2
        +	ldwx,s	$acc0($tbl),$acc0
        +	_srm	$s1,0,$acc3
        +	ldwx,s	$acc1($tbl),$acc1
        +	_srm	$s1,24,$acc4
        +	ldwx,s	$acc2($tbl),$acc2
        +	_srm	$s0,16,$acc5
        +	ldwx,s	$acc3($tbl),$acc3
        +	_srm	$s3,8,$acc6
        +	ldwx,s	$acc4($tbl),$acc4
        +	_srm	$s2,0,$acc7
        +	ldwx,s	$acc5($tbl),$acc5
        +	_srm	$s2,24,$acc8
        +	ldwx,s	$acc6($tbl),$acc6
        +	_srm	$s1,16,$acc9
        +	ldwx,s	$acc7($tbl),$acc7
        +	_srm	$s0,8,$acc10
        +	ldwx,s	$acc8($tbl),$acc8
        +	_srm	$s3,0,$acc11
        +	ldwx,s	$acc9($tbl),$acc9
        +	_srm	$s3,24,$acc12
        +	ldwx,s	$acc10($tbl),$acc10
        +	_srm	$s2,16,$acc13
        +	ldwx,s	$acc11($tbl),$acc11
        +	_srm	$s1,8,$acc14
        +	ldwx,s	$acc12($tbl),$acc12
        +	_srm	$s0,0,$acc15
        +	ldwx,s	$acc13($tbl),$acc13
        +	ldwx,s	$acc14($tbl),$acc14
        +	ldwx,s	$acc15($tbl),$acc15
        +	addib,= -1,$rounds,L\$dec_last
        +	ldo	32($key),$key
        +
        +		_ror	$acc1,8,$acc1
        +		xor	$acc0,$t0,$t0
        +	ldw	0($key),$s0
        +		_ror	$acc2,16,$acc2
        +		xor	$acc1,$t0,$t0
        +	ldw	4($key),$s1
        +		_ror	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ldw	8($key),$s2
        +		_ror	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ldw	12($key),$s3
        +		_ror	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +		_ror	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		_ror	$acc9,8,$acc9
        +		xor	$acc6,$t1,$t1
        +		_ror	$acc10,16,$acc10
        +		xor	$acc7,$t1,$t1
        +		_ror	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		_ror	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		_ror	$acc14,16,$acc14
        +		xor	$acc10,$t2,$t2
        +		_ror	$acc15,24,$acc15
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	_srm	$t0,24,$acc0
        +		xor	$acc14,$t3,$t3
        +		xor	$acc15,$t3,$t3
        +	_srm	$t3,16,$acc1
        +
        +	_srm	$t2,8,$acc2
        +	ldwx,s	$acc0($tbl),$acc0
        +	_srm	$t1,0,$acc3
        +	ldwx,s	$acc1($tbl),$acc1
        +	_srm	$t1,24,$acc4
        +	ldwx,s	$acc2($tbl),$acc2
        +	_srm	$t0,16,$acc5
        +	ldwx,s	$acc3($tbl),$acc3
        +	_srm	$t3,8,$acc6
        +	ldwx,s	$acc4($tbl),$acc4
        +	_srm	$t2,0,$acc7
        +	ldwx,s	$acc5($tbl),$acc5
        +	_srm	$t2,24,$acc8
        +	ldwx,s	$acc6($tbl),$acc6
        +	_srm	$t1,16,$acc9
        +	ldwx,s	$acc7($tbl),$acc7
        +	_srm	$t0,8,$acc10
        +	ldwx,s	$acc8($tbl),$acc8
        +	_srm	$t3,0,$acc11
        +	ldwx,s	$acc9($tbl),$acc9
        +	_srm	$t3,24,$acc12
        +	ldwx,s	$acc10($tbl),$acc10
        +	_srm	$t2,16,$acc13
        +	ldwx,s	$acc11($tbl),$acc11
        +	_srm	$t1,8,$acc14
        +	ldwx,s	$acc12($tbl),$acc12
        +	_srm	$t0,0,$acc15
        +	ldwx,s	$acc13($tbl),$acc13
        +		_ror	$acc1,8,$acc1
        +	ldwx,s	$acc14($tbl),$acc14
        +
        +		_ror	$acc2,16,$acc2
        +		xor	$acc0,$s0,$s0
        +	ldwx,s	$acc15($tbl),$acc15
        +		_ror	$acc3,24,$acc3
        +		xor	$acc1,$s0,$s0
        +	ldw	16($key),$t0
        +		_ror	$acc5,8,$acc5
        +		xor	$acc2,$s0,$s0
        +	ldw	20($key),$t1
        +		_ror	$acc6,16,$acc6
        +		xor	$acc3,$s0,$s0
        +	ldw	24($key),$t2
        +		_ror	$acc7,24,$acc7
        +		xor	$acc4,$s1,$s1
        +	ldw	28($key),$t3
        +		_ror	$acc9,8,$acc9
        +		xor	$acc5,$s1,$s1
        +	ldw	1024+0($tbl),%r0		; prefetch td4
        +		_ror	$acc10,16,$acc10
        +		xor	$acc6,$s1,$s1
        +	ldw	1024+32($tbl),%r0		; prefetch td4
        +		_ror	$acc11,24,$acc11
        +		xor	$acc7,$s1,$s1
        +	ldw	1024+64($tbl),%r0		; prefetch td4
        +		_ror	$acc13,8,$acc13
        +		xor	$acc8,$s2,$s2
        +	ldw	1024+96($tbl),%r0		; prefetch td4
        +		_ror	$acc14,16,$acc14
        +		xor	$acc9,$s2,$s2
        +	ldw	1024+128($tbl),%r0		; prefetch td4
        +		_ror	$acc15,24,$acc15
        +		xor	$acc10,$s2,$s2
        +	ldw	1024+160($tbl),%r0		; prefetch td4
        +	_srm	$s0,24,$acc0
        +		xor	$acc11,$s2,$s2
        +	ldw	1024+192($tbl),%r0		; prefetch td4
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$s3,$s3
        +	ldw	1024+224($tbl),%r0		; prefetch td4
        +		xor	$acc14,$s3,$s3
        +		xor	$acc15,$s3,$s3
        +	b	L\$dec_loop
        +	_srm	$s3,16,$acc1
        +
        +	.ALIGN	16
        +L\$dec_last
        +	ldo	1024($tbl),$rounds
        +		_ror	$acc1,8,$acc1
        +		xor	$acc0,$t0,$t0
        +	ldw	0($key),$s0
        +		_ror	$acc2,16,$acc2
        +		xor	$acc1,$t0,$t0
        +	ldw	4($key),$s1
        +		_ror	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ldw	8($key),$s2
        +		_ror	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ldw	12($key),$s3
        +		_ror	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +		_ror	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		_ror	$acc9,8,$acc9
        +		xor	$acc6,$t1,$t1
        +		_ror	$acc10,16,$acc10
        +		xor	$acc7,$t1,$t1
        +		_ror	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		_ror	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		_ror	$acc14,16,$acc14
        +		xor	$acc10,$t2,$t2
        +		_ror	$acc15,24,$acc15
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	_srm	$t0,24,$acc0
        +		xor	$acc14,$t3,$t3
        +		xor	$acc15,$t3,$t3
        +	_srm	$t3,16,$acc1
        +
        +	_srm	$t2,8,$acc2
        +	ldbx	$acc0($rounds),$acc0
        +	_srm	$t1,24,$acc4
        +	ldbx	$acc1($rounds),$acc1
        +	_srm	$t0,16,$acc5
        +	_srm	$t1,0,$acc3
        +	ldbx	$acc2($rounds),$acc2
        +	ldbx	$acc3($rounds),$acc3
        +	_srm	$t3,8,$acc6
        +	ldbx	$acc4($rounds),$acc4
        +	_srm	$t2,24,$acc8
        +	ldbx	$acc5($rounds),$acc5
        +	_srm	$t1,16,$acc9
        +	_srm	$t2,0,$acc7
        +	ldbx	$acc6($rounds),$acc6
        +	ldbx	$acc7($rounds),$acc7
        +	_srm	$t0,8,$acc10
        +	ldbx	$acc8($rounds),$acc8
        +	_srm	$t3,24,$acc12
        +	ldbx	$acc9($rounds),$acc9
        +	_srm	$t2,16,$acc13
        +	_srm	$t3,0,$acc11
        +	ldbx	$acc10($rounds),$acc10
        +	_srm	$t1,8,$acc14
        +	ldbx	$acc11($rounds),$acc11
        +	ldbx	$acc12($rounds),$acc12
        +	ldbx	$acc13($rounds),$acc13
        +	_srm	$t0,0,$acc15
        +	ldbx	$acc14($rounds),$acc14
        +
        +		dep	$acc0,7,8,$acc3
        +	ldbx	$acc15($rounds),$acc15
        +		dep	$acc4,7,8,$acc7
        +		dep	$acc1,15,8,$acc3
        +		dep	$acc5,15,8,$acc7
        +		dep	$acc2,23,8,$acc3
        +		dep	$acc6,23,8,$acc7
        +		xor	$acc3,$s0,$s0
        +		xor	$acc7,$s1,$s1
        +		dep	$acc8,7,8,$acc11
        +		dep	$acc12,7,8,$acc15
        +		dep	$acc9,15,8,$acc11
        +		dep	$acc13,15,8,$acc15
        +		dep	$acc10,23,8,$acc11
        +		dep	$acc14,23,8,$acc15
        +		xor	$acc11,$s2,$s2
        +
        +	bv	(%r31)
        +	.EXIT
        +		xor	$acc15,$s3,$s3
        +	.PROCEND
        +
        +	.ALIGN	64
        +L\$AES_Td
        +	.WORD	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
        +	.WORD	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
        +	.WORD	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
        +	.WORD	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
        +	.WORD	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
        +	.WORD	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
        +	.WORD	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
        +	.WORD	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
        +	.WORD	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
        +	.WORD	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
        +	.WORD	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
        +	.WORD	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
        +	.WORD	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
        +	.WORD	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
        +	.WORD	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
        +	.WORD	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
        +	.WORD	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
        +	.WORD	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
        +	.WORD	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
        +	.WORD	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
        +	.WORD	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
        +	.WORD	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
        +	.WORD	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
        +	.WORD	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
        +	.WORD	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
        +	.WORD	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
        +	.WORD	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
        +	.WORD	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
        +	.WORD	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
        +	.WORD	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
        +	.WORD	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
        +	.WORD	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
        +	.WORD	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
        +	.WORD	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
        +	.WORD	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
        +	.WORD	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
        +	.WORD	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
        +	.WORD	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
        +	.WORD	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
        +	.WORD	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
        +	.WORD	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
        +	.WORD	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
        +	.WORD	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
        +	.WORD	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
        +	.WORD	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
        +	.WORD	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
        +	.WORD	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
        +	.WORD	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
        +	.WORD	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
        +	.WORD	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
        +	.WORD	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
        +	.WORD	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
        +	.WORD	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
        +	.WORD	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
        +	.WORD	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
        +	.WORD	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
        +	.WORD	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
        +	.WORD	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
        +	.WORD	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
        +	.WORD	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
        +	.WORD	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
        +	.WORD	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
        +	.WORD	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
        +	.WORD	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
        +	.BYTE	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
        +	.BYTE	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +	.BYTE	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +	.BYTE	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +	.BYTE	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +	.BYTE	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +	.BYTE	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +	.BYTE	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +	.BYTE	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +	.BYTE	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +	.BYTE	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +	.BYTE	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +	.BYTE	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +	.BYTE	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +	.BYTE	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +	.BYTE	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +	.BYTE	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +	.BYTE	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +	.BYTE	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +	.BYTE	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +	.BYTE	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +	.BYTE	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +	.BYTE	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +	.BYTE	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +	.BYTE	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +	.BYTE	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +	.BYTE	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +	.BYTE	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +	.BYTE	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +	.BYTE	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +	.BYTE	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +	.BYTE	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +	.STRINGZ "AES for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +foreach (split("\n",$code)) {
        +	s/\`([^\`]*)\`/eval $1/ge;
        +
        +	# translate made up instructons: _ror, _srm
        +	s/_ror(\s+)(%r[0-9]+),/shd$1$2,$2,/				or
        +
        +	s/_srm(\s+%r[0-9]+),([0-9]+),/
        +		$SIZE_T==4 ? sprintf("extru%s,%d,8,",$1,31-$2)
        +		:            sprintf("extrd,u%s,%d,8,",$1,63-$2)/e;
        +
        +	s/,\*/,/ if ($SIZE_T==4);
        +	print $_,"\n";
        +}
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-ppc.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-ppc.pl
        new file mode 100644
        index 000000000..7c52cbe5f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-ppc.pl
        @@ -0,0 +1,1365 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# Needs more work: key setup, CBC routine...
        +#
        +# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
        +# 128-bit key, which is ~40% better than 64-bit code generated by gcc
        +# 4.0. But these are not the ones currently used! Their "compact"
        +# counterparts are, for security reason. ppc_AES_encrypt_compact runs
        +# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
        +# at 1/3 of ppc_AES_decrypt.
        +
        +# February 2010
        +#
        +# Rescheduling instructions to favour Power6 pipeline gave 10%
        +# performance improvement on the platfrom in question (and marginal
        +# improvement even on others). It should be noted that Power6 fails
        +# to process byte in 18 cycles, only in 23, because it fails to issue
        +# 4 load instructions in two cycles, only in 3. As result non-compact
        +# block subroutines are 25% slower than one would expect. Compact
        +# functions scale better, because they have pure computational part,
        +# which scales perfectly with clock frequency. To be specific
        +# ppc_AES_encrypt_compact operates at 42 cycles per byte, while
        +# ppc_AES_decrypt_compact - at 55 (in 64-bit build).
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /64/) {
        +	$SIZE_T	=8;
        +	$LRSAVE	=2*$SIZE_T;
        +	$STU	="stdu";
        +	$POP	="ld";
        +	$PUSH	="std";
        +} elsif ($flavour =~ /32/) {
        +	$SIZE_T	=4;
        +	$LRSAVE	=$SIZE_T;
        +	$STU	="stwu";
        +	$POP	="lwz";
        +	$PUSH	="stw";
        +} else { die "nonsense $flavour"; }
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
        +
        +$FRAME=32*$SIZE_T;
        +
        +sub _data_word()
        +{ my $i;
        +    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
        +}
        +
        +$sp="r1";
        +$toc="r2";
        +$inp="r3";
        +$out="r4";
        +$key="r5";
        +
        +$Tbl0="r3";
        +$Tbl1="r6";
        +$Tbl2="r7";
        +$Tbl3="r2";
        +
        +$s0="r8";
        +$s1="r9";
        +$s2="r10";
        +$s3="r11";
        +
        +$t0="r12";
        +$t1="r13";
        +$t2="r14";
        +$t3="r15";
        +
        +$acc00="r16";
        +$acc01="r17";
        +$acc02="r18";
        +$acc03="r19";
        +
        +$acc04="r20";
        +$acc05="r21";
        +$acc06="r22";
        +$acc07="r23";
        +
        +$acc08="r24";
        +$acc09="r25";
        +$acc10="r26";
        +$acc11="r27";
        +
        +$acc12="r28";
        +$acc13="r29";
        +$acc14="r30";
        +$acc15="r31";
        +
        +# stay away from TLS pointer
        +if ($SIZE_T==8)	{ die if ($t1 ne "r13");  $t1="r0";		}
        +else		{ die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0";	}
        +$mask80=$Tbl2;
        +$mask1b=$Tbl3;
        +
        +$code.=<<___;
        +.machine	"any"
        +.text
        +
        +.align	7
        +LAES_Te:
        +	mflr	r0
        +	bcl	20,31,\$+4
        +	mflr	$Tbl0	;    vvvvv "distance" between . and 1st data entry
        +	addi	$Tbl0,$Tbl0,`128-8`
        +	mtlr	r0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +	.space	`64-9*4`
        +LAES_Td:
        +	mflr	r0
        +	bcl	20,31,\$+4
        +	mflr	$Tbl0	;    vvvvvvvv "distance" between . and 1st data entry
        +	addi	$Tbl0,$Tbl0,`128-64-8+2048+256`
        +	mtlr	r0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +	.space	`128-64-9*4`
        +___
        +&_data_word(
        +	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
        +	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
        +	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
        +	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
        +	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
        +	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
        +	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
        +	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
        +	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
        +	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
        +	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
        +	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
        +	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
        +	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
        +	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
        +	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
        +	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
        +	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
        +	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
        +	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
        +	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
        +	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
        +	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
        +	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
        +	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
        +	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
        +	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
        +	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
        +	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
        +	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
        +	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
        +	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
        +	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
        +	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
        +	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
        +	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
        +	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
        +	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
        +	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
        +	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
        +	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
        +	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
        +	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
        +	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
        +	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
        +	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
        +	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
        +	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
        +	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
        +	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
        +	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
        +	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
        +	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
        +	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
        +	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
        +	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
        +	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
        +	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
        +	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
        +	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
        +	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
        +	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
        +	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
        +	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
        +$code.=<<___;
        +.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
        +.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +___
        +&_data_word(
        +	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
        +	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
        +	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
        +	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
        +	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
        +	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
        +	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
        +	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
        +	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
        +	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
        +	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
        +	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
        +	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
        +	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
        +	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
        +	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
        +	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
        +	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
        +	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
        +	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
        +	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
        +	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
        +	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
        +	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
        +	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
        +	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
        +	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
        +	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
        +	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
        +	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
        +	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
        +	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
        +	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
        +	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
        +	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
        +	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
        +	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
        +	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
        +	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
        +	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
        +	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
        +	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
        +	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
        +	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
        +	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
        +	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
        +	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
        +	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
        +	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
        +	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
        +	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
        +	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
        +	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
        +	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
        +	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
        +	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
        +	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
        +	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
        +	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
        +	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
        +	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
        +	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
        +	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
        +	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
        +$code.=<<___;
        +.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
        +.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +
        +
        +.globl	.AES_encrypt
        +.align	7
        +.AES_encrypt:
        +	$STU	$sp,-$FRAME($sp)
        +	mflr	r0
        +
        +	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
        +	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
        +	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
        +	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
        +	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
        +
        +	andi.	$t0,$inp,3
        +	andi.	$t1,$out,3
        +	or.	$t0,$t0,$t1
        +	bne	Lenc_unaligned
        +
        +Lenc_unaligned_ok:
        +	lwz	$s0,0($inp)
        +	lwz	$s1,4($inp)
        +	lwz	$s2,8($inp)
        +	lwz	$s3,12($inp)
        +	bl	LAES_Te
        +	bl	Lppc_AES_encrypt_compact
        +	stw	$s0,0($out)
        +	stw	$s1,4($out)
        +	stw	$s2,8($out)
        +	stw	$s3,12($out)
        +	b	Lenc_done
        +
        +Lenc_unaligned:
        +	subfic	$t0,$inp,4096
        +	subfic	$t1,$out,4096
        +	andi.	$t0,$t0,4096-16
        +	beq	Lenc_xpage
        +	andi.	$t1,$t1,4096-16
        +	bne	Lenc_unaligned_ok
        +
        +Lenc_xpage:
        +	lbz	$acc00,0($inp)
        +	lbz	$acc01,1($inp)
        +	lbz	$acc02,2($inp)
        +	lbz	$s0,3($inp)
        +	lbz	$acc04,4($inp)
        +	lbz	$acc05,5($inp)
        +	lbz	$acc06,6($inp)
        +	lbz	$s1,7($inp)
        +	lbz	$acc08,8($inp)
        +	lbz	$acc09,9($inp)
        +	lbz	$acc10,10($inp)
        +	insrwi	$s0,$acc00,8,0
        +	lbz	$s2,11($inp)
        +	insrwi	$s1,$acc04,8,0
        +	lbz	$acc12,12($inp)
        +	insrwi	$s0,$acc01,8,8
        +	lbz	$acc13,13($inp)
        +	insrwi	$s1,$acc05,8,8
        +	lbz	$acc14,14($inp)
        +	insrwi	$s0,$acc02,8,16
        +	lbz	$s3,15($inp)
        +	insrwi	$s1,$acc06,8,16
        +	insrwi	$s2,$acc08,8,0
        +	insrwi	$s3,$acc12,8,0
        +	insrwi	$s2,$acc09,8,8
        +	insrwi	$s3,$acc13,8,8
        +	insrwi	$s2,$acc10,8,16
        +	insrwi	$s3,$acc14,8,16
        +
        +	bl	LAES_Te
        +	bl	Lppc_AES_encrypt_compact
        +
        +	extrwi	$acc00,$s0,8,0
        +	extrwi	$acc01,$s0,8,8
        +	stb	$acc00,0($out)
        +	extrwi	$acc02,$s0,8,16
        +	stb	$acc01,1($out)
        +	stb	$acc02,2($out)
        +	extrwi	$acc04,$s1,8,0
        +	stb	$s0,3($out)
        +	extrwi	$acc05,$s1,8,8
        +	stb	$acc04,4($out)
        +	extrwi	$acc06,$s1,8,16
        +	stb	$acc05,5($out)
        +	stb	$acc06,6($out)
        +	extrwi	$acc08,$s2,8,0
        +	stb	$s1,7($out)
        +	extrwi	$acc09,$s2,8,8
        +	stb	$acc08,8($out)
        +	extrwi	$acc10,$s2,8,16
        +	stb	$acc09,9($out)
        +	stb	$acc10,10($out)
        +	extrwi	$acc12,$s3,8,0
        +	stb	$s2,11($out)
        +	extrwi	$acc13,$s3,8,8
        +	stb	$acc12,12($out)
        +	extrwi	$acc14,$s3,8,16
        +	stb	$acc13,13($out)
        +	stb	$acc14,14($out)
        +	stb	$s3,15($out)
        +
        +Lenc_done:
        +	$POP	r0,`$FRAME+$LRSAVE`($sp)
        +	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
        +	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
        +	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
        +	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
        +	mtlr	r0
        +	addi	$sp,$sp,$FRAME
        +	blr
        +	.long	0
        +	.byte	0,12,4,1,0x80,18,3,0
        +	.long	0
        +
        +.align	5
        +Lppc_AES_encrypt:
        +	lwz	$acc00,240($key)
        +	addi	$Tbl1,$Tbl0,3
        +	lwz	$t0,0($key)
        +	addi	$Tbl2,$Tbl0,2
        +	lwz	$t1,4($key)
        +	addi	$Tbl3,$Tbl0,1
        +	lwz	$t2,8($key)
        +	addi	$acc00,$acc00,-1
        +	lwz	$t3,12($key)
        +	addi	$key,$key,16
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	xor	$s2,$s2,$t2
        +	xor	$s3,$s3,$t3
        +	mtctr	$acc00
        +.align	4
        +Lenc_loop:
        +	rlwinm	$acc00,$s0,`32-24+3`,21,28
        +	rlwinm	$acc01,$s1,`32-24+3`,21,28
        +	rlwinm	$acc02,$s2,`32-24+3`,21,28
        +	rlwinm	$acc03,$s3,`32-24+3`,21,28
        +	lwz	$t0,0($key)
        +	rlwinm	$acc04,$s1,`32-16+3`,21,28
        +	lwz	$t1,4($key)
        +	rlwinm	$acc05,$s2,`32-16+3`,21,28
        +	lwz	$t2,8($key)
        +	rlwinm	$acc06,$s3,`32-16+3`,21,28
        +	lwz	$t3,12($key)
        +	rlwinm	$acc07,$s0,`32-16+3`,21,28
        +	lwzx	$acc00,$Tbl0,$acc00
        +	rlwinm	$acc08,$s2,`32-8+3`,21,28
        +	lwzx	$acc01,$Tbl0,$acc01
        +	rlwinm	$acc09,$s3,`32-8+3`,21,28
        +	lwzx	$acc02,$Tbl0,$acc02
        +	rlwinm	$acc10,$s0,`32-8+3`,21,28
        +	lwzx	$acc03,$Tbl0,$acc03
        +	rlwinm	$acc11,$s1,`32-8+3`,21,28
        +	lwzx	$acc04,$Tbl1,$acc04
        +	rlwinm	$acc12,$s3,`0+3`,21,28
        +	lwzx	$acc05,$Tbl1,$acc05
        +	rlwinm	$acc13,$s0,`0+3`,21,28
        +	lwzx	$acc06,$Tbl1,$acc06
        +	rlwinm	$acc14,$s1,`0+3`,21,28
        +	lwzx	$acc07,$Tbl1,$acc07
        +	rlwinm	$acc15,$s2,`0+3`,21,28
        +	lwzx	$acc08,$Tbl2,$acc08
        +	xor	$t0,$t0,$acc00
        +	lwzx	$acc09,$Tbl2,$acc09
        +	xor	$t1,$t1,$acc01
        +	lwzx	$acc10,$Tbl2,$acc10
        +	xor	$t2,$t2,$acc02
        +	lwzx	$acc11,$Tbl2,$acc11
        +	xor	$t3,$t3,$acc03
        +	lwzx	$acc12,$Tbl3,$acc12
        +	xor	$t0,$t0,$acc04
        +	lwzx	$acc13,$Tbl3,$acc13
        +	xor	$t1,$t1,$acc05
        +	lwzx	$acc14,$Tbl3,$acc14
        +	xor	$t2,$t2,$acc06
        +	lwzx	$acc15,$Tbl3,$acc15
        +	xor	$t3,$t3,$acc07
        +	xor	$t0,$t0,$acc08
        +	xor	$t1,$t1,$acc09
        +	xor	$t2,$t2,$acc10
        +	xor	$t3,$t3,$acc11
        +	xor	$s0,$t0,$acc12
        +	xor	$s1,$t1,$acc13
        +	xor	$s2,$t2,$acc14
        +	xor	$s3,$t3,$acc15
        +	addi	$key,$key,16
        +	bdnz-	Lenc_loop
        +
        +	addi	$Tbl2,$Tbl0,2048
        +	nop
        +	lwz	$t0,0($key)
        +	rlwinm	$acc00,$s0,`32-24`,24,31
        +	lwz	$t1,4($key)
        +	rlwinm	$acc01,$s1,`32-24`,24,31
        +	lwz	$t2,8($key)
        +	rlwinm	$acc02,$s2,`32-24`,24,31
        +	lwz	$t3,12($key)
        +	rlwinm	$acc03,$s3,`32-24`,24,31
        +	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Te4
        +	rlwinm	$acc04,$s1,`32-16`,24,31
        +	lwz	$acc09,`2048+32`($Tbl0)
        +	rlwinm	$acc05,$s2,`32-16`,24,31
        +	lwz	$acc10,`2048+64`($Tbl0)
        +	rlwinm	$acc06,$s3,`32-16`,24,31
        +	lwz	$acc11,`2048+96`($Tbl0)
        +	rlwinm	$acc07,$s0,`32-16`,24,31
        +	lwz	$acc12,`2048+128`($Tbl0)
        +	rlwinm	$acc08,$s2,`32-8`,24,31
        +	lwz	$acc13,`2048+160`($Tbl0)
        +	rlwinm	$acc09,$s3,`32-8`,24,31
        +	lwz	$acc14,`2048+192`($Tbl0)
        +	rlwinm	$acc10,$s0,`32-8`,24,31
        +	lwz	$acc15,`2048+224`($Tbl0)
        +	rlwinm	$acc11,$s1,`32-8`,24,31
        +	lbzx	$acc00,$Tbl2,$acc00
        +	rlwinm	$acc12,$s3,`0`,24,31
        +	lbzx	$acc01,$Tbl2,$acc01
        +	rlwinm	$acc13,$s0,`0`,24,31
        +	lbzx	$acc02,$Tbl2,$acc02
        +	rlwinm	$acc14,$s1,`0`,24,31
        +	lbzx	$acc03,$Tbl2,$acc03
        +	rlwinm	$acc15,$s2,`0`,24,31
        +	lbzx	$acc04,$Tbl2,$acc04
        +	rlwinm	$s0,$acc00,24,0,7
        +	lbzx	$acc05,$Tbl2,$acc05
        +	rlwinm	$s1,$acc01,24,0,7
        +	lbzx	$acc06,$Tbl2,$acc06
        +	rlwinm	$s2,$acc02,24,0,7
        +	lbzx	$acc07,$Tbl2,$acc07
        +	rlwinm	$s3,$acc03,24,0,7
        +	lbzx	$acc08,$Tbl2,$acc08
        +	rlwimi	$s0,$acc04,16,8,15
        +	lbzx	$acc09,$Tbl2,$acc09
        +	rlwimi	$s1,$acc05,16,8,15
        +	lbzx	$acc10,$Tbl2,$acc10
        +	rlwimi	$s2,$acc06,16,8,15
        +	lbzx	$acc11,$Tbl2,$acc11
        +	rlwimi	$s3,$acc07,16,8,15
        +	lbzx	$acc12,$Tbl2,$acc12
        +	rlwimi	$s0,$acc08,8,16,23
        +	lbzx	$acc13,$Tbl2,$acc13
        +	rlwimi	$s1,$acc09,8,16,23
        +	lbzx	$acc14,$Tbl2,$acc14
        +	rlwimi	$s2,$acc10,8,16,23
        +	lbzx	$acc15,$Tbl2,$acc15
        +	rlwimi	$s3,$acc11,8,16,23
        +	or	$s0,$s0,$acc12
        +	or	$s1,$s1,$acc13
        +	or	$s2,$s2,$acc14
        +	or	$s3,$s3,$acc15
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	xor	$s2,$s2,$t2
        +	xor	$s3,$s3,$t3
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.align	4
        +Lppc_AES_encrypt_compact:
        +	lwz	$acc00,240($key)
        +	addi	$Tbl1,$Tbl0,2048
        +	lwz	$t0,0($key)
        +	lis	$mask80,0x8080
        +	lwz	$t1,4($key)
        +	lis	$mask1b,0x1b1b
        +	lwz	$t2,8($key)
        +	ori	$mask80,$mask80,0x8080
        +	lwz	$t3,12($key)
        +	ori	$mask1b,$mask1b,0x1b1b
        +	addi	$key,$key,16
        +	mtctr	$acc00
        +.align	4
        +Lenc_compact_loop:
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	rlwinm	$acc00,$s0,`32-24`,24,31
        +	xor	$s2,$s2,$t2
        +	rlwinm	$acc01,$s1,`32-24`,24,31
        +	xor	$s3,$s3,$t3
        +	rlwinm	$acc02,$s2,`32-24`,24,31
        +	rlwinm	$acc03,$s3,`32-24`,24,31
        +	rlwinm	$acc04,$s1,`32-16`,24,31
        +	rlwinm	$acc05,$s2,`32-16`,24,31
        +	rlwinm	$acc06,$s3,`32-16`,24,31
        +	rlwinm	$acc07,$s0,`32-16`,24,31
        +	lbzx	$acc00,$Tbl1,$acc00
        +	rlwinm	$acc08,$s2,`32-8`,24,31
        +	lbzx	$acc01,$Tbl1,$acc01
        +	rlwinm	$acc09,$s3,`32-8`,24,31
        +	lbzx	$acc02,$Tbl1,$acc02
        +	rlwinm	$acc10,$s0,`32-8`,24,31
        +	lbzx	$acc03,$Tbl1,$acc03
        +	rlwinm	$acc11,$s1,`32-8`,24,31
        +	lbzx	$acc04,$Tbl1,$acc04
        +	rlwinm	$acc12,$s3,`0`,24,31
        +	lbzx	$acc05,$Tbl1,$acc05
        +	rlwinm	$acc13,$s0,`0`,24,31
        +	lbzx	$acc06,$Tbl1,$acc06
        +	rlwinm	$acc14,$s1,`0`,24,31
        +	lbzx	$acc07,$Tbl1,$acc07
        +	rlwinm	$acc15,$s2,`0`,24,31
        +	lbzx	$acc08,$Tbl1,$acc08
        +	rlwinm	$s0,$acc00,24,0,7
        +	lbzx	$acc09,$Tbl1,$acc09
        +	rlwinm	$s1,$acc01,24,0,7
        +	lbzx	$acc10,$Tbl1,$acc10
        +	rlwinm	$s2,$acc02,24,0,7
        +	lbzx	$acc11,$Tbl1,$acc11
        +	rlwinm	$s3,$acc03,24,0,7
        +	lbzx	$acc12,$Tbl1,$acc12
        +	rlwimi	$s0,$acc04,16,8,15
        +	lbzx	$acc13,$Tbl1,$acc13
        +	rlwimi	$s1,$acc05,16,8,15
        +	lbzx	$acc14,$Tbl1,$acc14
        +	rlwimi	$s2,$acc06,16,8,15
        +	lbzx	$acc15,$Tbl1,$acc15
        +	rlwimi	$s3,$acc07,16,8,15
        +	rlwimi	$s0,$acc08,8,16,23
        +	rlwimi	$s1,$acc09,8,16,23
        +	rlwimi	$s2,$acc10,8,16,23
        +	rlwimi	$s3,$acc11,8,16,23
        +	lwz	$t0,0($key)
        +	or	$s0,$s0,$acc12
        +	lwz	$t1,4($key)
        +	or	$s1,$s1,$acc13
        +	lwz	$t2,8($key)
        +	or	$s2,$s2,$acc14
        +	lwz	$t3,12($key)
        +	or	$s3,$s3,$acc15
        +
        +	addi	$key,$key,16
        +	bdz	Lenc_compact_done
        +
        +	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
        +	and	$acc01,$s1,$mask80
        +	and	$acc02,$s2,$mask80
        +	and	$acc03,$s3,$mask80
        +	srwi	$acc04,$acc00,7		# r1>>7
        +	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
        +	srwi	$acc05,$acc01,7
        +	andc	$acc09,$s1,$mask80
        +	srwi	$acc06,$acc02,7
        +	andc	$acc10,$s2,$mask80
        +	srwi	$acc07,$acc03,7
        +	andc	$acc11,$s3,$mask80
        +	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
        +	sub	$acc01,$acc01,$acc05
        +	sub	$acc02,$acc02,$acc06
        +	sub	$acc03,$acc03,$acc07
        +	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
        +	add	$acc09,$acc09,$acc09
        +	add	$acc10,$acc10,$acc10
        +	add	$acc11,$acc11,$acc11
        +	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc01,$acc01,$mask1b
        +	and	$acc02,$acc02,$mask1b
        +	and	$acc03,$acc03,$mask1b
        +	xor	$acc00,$acc00,$acc08	# r2
        +	xor	$acc01,$acc01,$acc09
        +	 rotlwi	$acc12,$s0,16		# ROTATE(r0,16)
        +	xor	$acc02,$acc02,$acc10
        +	 rotlwi	$acc13,$s1,16
        +	xor	$acc03,$acc03,$acc11
        +	 rotlwi	$acc14,$s2,16
        +
        +	xor	$s0,$s0,$acc00		# r0^r2
        +	rotlwi	$acc15,$s3,16
        +	xor	$s1,$s1,$acc01
        +	rotrwi	$s0,$s0,24		# ROTATE(r2^r0,24)
        +	xor	$s2,$s2,$acc02
        +	rotrwi	$s1,$s1,24
        +	xor	$s3,$s3,$acc03
        +	rotrwi	$s2,$s2,24
        +	xor	$s0,$s0,$acc00		# ROTATE(r2^r0,24)^r2
        +	rotrwi	$s3,$s3,24
        +	xor	$s1,$s1,$acc01
        +	xor	$s2,$s2,$acc02
        +	xor	$s3,$s3,$acc03
        +	rotlwi	$acc08,$acc12,8		# ROTATE(r0,24)
        +	xor	$s0,$s0,$acc12		#
        +	rotlwi	$acc09,$acc13,8
        +	xor	$s1,$s1,$acc13
        +	rotlwi	$acc10,$acc14,8
        +	xor	$s2,$s2,$acc14
        +	rotlwi	$acc11,$acc15,8
        +	xor	$s3,$s3,$acc15
        +	xor	$s0,$s0,$acc08		#
        +	xor	$s1,$s1,$acc09
        +	xor	$s2,$s2,$acc10
        +	xor	$s3,$s3,$acc11
        +
        +	b	Lenc_compact_loop
        +.align	4
        +Lenc_compact_done:
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	xor	$s2,$s2,$t2
        +	xor	$s3,$s3,$t3
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.globl	.AES_decrypt
        +.align	7
        +.AES_decrypt:
        +	$STU	$sp,-$FRAME($sp)
        +	mflr	r0
        +
        +	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
        +	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
        +	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
        +	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
        +	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
        +
        +	andi.	$t0,$inp,3
        +	andi.	$t1,$out,3
        +	or.	$t0,$t0,$t1
        +	bne	Ldec_unaligned
        +
        +Ldec_unaligned_ok:
        +	lwz	$s0,0($inp)
        +	lwz	$s1,4($inp)
        +	lwz	$s2,8($inp)
        +	lwz	$s3,12($inp)
        +	bl	LAES_Td
        +	bl	Lppc_AES_decrypt_compact
        +	stw	$s0,0($out)
        +	stw	$s1,4($out)
        +	stw	$s2,8($out)
        +	stw	$s3,12($out)
        +	b	Ldec_done
        +
        +Ldec_unaligned:
        +	subfic	$t0,$inp,4096
        +	subfic	$t1,$out,4096
        +	andi.	$t0,$t0,4096-16
        +	beq	Ldec_xpage
        +	andi.	$t1,$t1,4096-16
        +	bne	Ldec_unaligned_ok
        +
        +Ldec_xpage:
        +	lbz	$acc00,0($inp)
        +	lbz	$acc01,1($inp)
        +	lbz	$acc02,2($inp)
        +	lbz	$s0,3($inp)
        +	lbz	$acc04,4($inp)
        +	lbz	$acc05,5($inp)
        +	lbz	$acc06,6($inp)
        +	lbz	$s1,7($inp)
        +	lbz	$acc08,8($inp)
        +	lbz	$acc09,9($inp)
        +	lbz	$acc10,10($inp)
        +	insrwi	$s0,$acc00,8,0
        +	lbz	$s2,11($inp)
        +	insrwi	$s1,$acc04,8,0
        +	lbz	$acc12,12($inp)
        +	insrwi	$s0,$acc01,8,8
        +	lbz	$acc13,13($inp)
        +	insrwi	$s1,$acc05,8,8
        +	lbz	$acc14,14($inp)
        +	insrwi	$s0,$acc02,8,16
        +	lbz	$s3,15($inp)
        +	insrwi	$s1,$acc06,8,16
        +	insrwi	$s2,$acc08,8,0
        +	insrwi	$s3,$acc12,8,0
        +	insrwi	$s2,$acc09,8,8
        +	insrwi	$s3,$acc13,8,8
        +	insrwi	$s2,$acc10,8,16
        +	insrwi	$s3,$acc14,8,16
        +
        +	bl	LAES_Td
        +	bl	Lppc_AES_decrypt_compact
        +
        +	extrwi	$acc00,$s0,8,0
        +	extrwi	$acc01,$s0,8,8
        +	stb	$acc00,0($out)
        +	extrwi	$acc02,$s0,8,16
        +	stb	$acc01,1($out)
        +	stb	$acc02,2($out)
        +	extrwi	$acc04,$s1,8,0
        +	stb	$s0,3($out)
        +	extrwi	$acc05,$s1,8,8
        +	stb	$acc04,4($out)
        +	extrwi	$acc06,$s1,8,16
        +	stb	$acc05,5($out)
        +	stb	$acc06,6($out)
        +	extrwi	$acc08,$s2,8,0
        +	stb	$s1,7($out)
        +	extrwi	$acc09,$s2,8,8
        +	stb	$acc08,8($out)
        +	extrwi	$acc10,$s2,8,16
        +	stb	$acc09,9($out)
        +	stb	$acc10,10($out)
        +	extrwi	$acc12,$s3,8,0
        +	stb	$s2,11($out)
        +	extrwi	$acc13,$s3,8,8
        +	stb	$acc12,12($out)
        +	extrwi	$acc14,$s3,8,16
        +	stb	$acc13,13($out)
        +	stb	$acc14,14($out)
        +	stb	$s3,15($out)
        +
        +Ldec_done:
        +	$POP	r0,`$FRAME+$LRSAVE`($sp)
        +	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
        +	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
        +	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
        +	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
        +	mtlr	r0
        +	addi	$sp,$sp,$FRAME
        +	blr
        +	.long	0
        +	.byte	0,12,4,1,0x80,18,3,0
        +	.long	0
        +
        +.align	5
        +Lppc_AES_decrypt:
        +	lwz	$acc00,240($key)
        +	addi	$Tbl1,$Tbl0,3
        +	lwz	$t0,0($key)
        +	addi	$Tbl2,$Tbl0,2
        +	lwz	$t1,4($key)
        +	addi	$Tbl3,$Tbl0,1
        +	lwz	$t2,8($key)
        +	addi	$acc00,$acc00,-1
        +	lwz	$t3,12($key)
        +	addi	$key,$key,16
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	xor	$s2,$s2,$t2
        +	xor	$s3,$s3,$t3
        +	mtctr	$acc00
        +.align	4
        +Ldec_loop:
        +	rlwinm	$acc00,$s0,`32-24+3`,21,28
        +	rlwinm	$acc01,$s1,`32-24+3`,21,28
        +	rlwinm	$acc02,$s2,`32-24+3`,21,28
        +	rlwinm	$acc03,$s3,`32-24+3`,21,28
        +	lwz	$t0,0($key)
        +	rlwinm	$acc04,$s3,`32-16+3`,21,28
        +	lwz	$t1,4($key)
        +	rlwinm	$acc05,$s0,`32-16+3`,21,28
        +	lwz	$t2,8($key)
        +	rlwinm	$acc06,$s1,`32-16+3`,21,28
        +	lwz	$t3,12($key)
        +	rlwinm	$acc07,$s2,`32-16+3`,21,28
        +	lwzx	$acc00,$Tbl0,$acc00
        +	rlwinm	$acc08,$s2,`32-8+3`,21,28
        +	lwzx	$acc01,$Tbl0,$acc01
        +	rlwinm	$acc09,$s3,`32-8+3`,21,28
        +	lwzx	$acc02,$Tbl0,$acc02
        +	rlwinm	$acc10,$s0,`32-8+3`,21,28
        +	lwzx	$acc03,$Tbl0,$acc03
        +	rlwinm	$acc11,$s1,`32-8+3`,21,28
        +	lwzx	$acc04,$Tbl1,$acc04
        +	rlwinm	$acc12,$s1,`0+3`,21,28
        +	lwzx	$acc05,$Tbl1,$acc05
        +	rlwinm	$acc13,$s2,`0+3`,21,28
        +	lwzx	$acc06,$Tbl1,$acc06
        +	rlwinm	$acc14,$s3,`0+3`,21,28
        +	lwzx	$acc07,$Tbl1,$acc07
        +	rlwinm	$acc15,$s0,`0+3`,21,28
        +	lwzx	$acc08,$Tbl2,$acc08
        +	xor	$t0,$t0,$acc00
        +	lwzx	$acc09,$Tbl2,$acc09
        +	xor	$t1,$t1,$acc01
        +	lwzx	$acc10,$Tbl2,$acc10
        +	xor	$t2,$t2,$acc02
        +	lwzx	$acc11,$Tbl2,$acc11
        +	xor	$t3,$t3,$acc03
        +	lwzx	$acc12,$Tbl3,$acc12
        +	xor	$t0,$t0,$acc04
        +	lwzx	$acc13,$Tbl3,$acc13
        +	xor	$t1,$t1,$acc05
        +	lwzx	$acc14,$Tbl3,$acc14
        +	xor	$t2,$t2,$acc06
        +	lwzx	$acc15,$Tbl3,$acc15
        +	xor	$t3,$t3,$acc07
        +	xor	$t0,$t0,$acc08
        +	xor	$t1,$t1,$acc09
        +	xor	$t2,$t2,$acc10
        +	xor	$t3,$t3,$acc11
        +	xor	$s0,$t0,$acc12
        +	xor	$s1,$t1,$acc13
        +	xor	$s2,$t2,$acc14
        +	xor	$s3,$t3,$acc15
        +	addi	$key,$key,16
        +	bdnz-	Ldec_loop
        +
        +	addi	$Tbl2,$Tbl0,2048
        +	nop
        +	lwz	$t0,0($key)
        +	rlwinm	$acc00,$s0,`32-24`,24,31
        +	lwz	$t1,4($key)
        +	rlwinm	$acc01,$s1,`32-24`,24,31
        +	lwz	$t2,8($key)
        +	rlwinm	$acc02,$s2,`32-24`,24,31
        +	lwz	$t3,12($key)
        +	rlwinm	$acc03,$s3,`32-24`,24,31
        +	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Td4
        +	rlwinm	$acc04,$s3,`32-16`,24,31
        +	lwz	$acc09,`2048+32`($Tbl0)
        +	rlwinm	$acc05,$s0,`32-16`,24,31
        +	lwz	$acc10,`2048+64`($Tbl0)
        +	lbzx	$acc00,$Tbl2,$acc00
        +	lwz	$acc11,`2048+96`($Tbl0)
        +	lbzx	$acc01,$Tbl2,$acc01
        +	lwz	$acc12,`2048+128`($Tbl0)
        +	rlwinm	$acc06,$s1,`32-16`,24,31
        +	lwz	$acc13,`2048+160`($Tbl0)
        +	rlwinm	$acc07,$s2,`32-16`,24,31
        +	lwz	$acc14,`2048+192`($Tbl0)
        +	rlwinm	$acc08,$s2,`32-8`,24,31
        +	lwz	$acc15,`2048+224`($Tbl0)
        +	rlwinm	$acc09,$s3,`32-8`,24,31
        +	lbzx	$acc02,$Tbl2,$acc02
        +	rlwinm	$acc10,$s0,`32-8`,24,31
        +	lbzx	$acc03,$Tbl2,$acc03
        +	rlwinm	$acc11,$s1,`32-8`,24,31
        +	lbzx	$acc04,$Tbl2,$acc04
        +	rlwinm	$acc12,$s1,`0`,24,31
        +	lbzx	$acc05,$Tbl2,$acc05
        +	rlwinm	$acc13,$s2,`0`,24,31
        +	lbzx	$acc06,$Tbl2,$acc06
        +	rlwinm	$acc14,$s3,`0`,24,31
        +	lbzx	$acc07,$Tbl2,$acc07
        +	rlwinm	$acc15,$s0,`0`,24,31
        +	lbzx	$acc08,$Tbl2,$acc08
        +	rlwinm	$s0,$acc00,24,0,7
        +	lbzx	$acc09,$Tbl2,$acc09
        +	rlwinm	$s1,$acc01,24,0,7
        +	lbzx	$acc10,$Tbl2,$acc10
        +	rlwinm	$s2,$acc02,24,0,7
        +	lbzx	$acc11,$Tbl2,$acc11
        +	rlwinm	$s3,$acc03,24,0,7
        +	lbzx	$acc12,$Tbl2,$acc12
        +	rlwimi	$s0,$acc04,16,8,15
        +	lbzx	$acc13,$Tbl2,$acc13
        +	rlwimi	$s1,$acc05,16,8,15
        +	lbzx	$acc14,$Tbl2,$acc14
        +	rlwimi	$s2,$acc06,16,8,15
        +	lbzx	$acc15,$Tbl2,$acc15
        +	rlwimi	$s3,$acc07,16,8,15
        +	rlwimi	$s0,$acc08,8,16,23
        +	rlwimi	$s1,$acc09,8,16,23
        +	rlwimi	$s2,$acc10,8,16,23
        +	rlwimi	$s3,$acc11,8,16,23
        +	or	$s0,$s0,$acc12
        +	or	$s1,$s1,$acc13
        +	or	$s2,$s2,$acc14
        +	or	$s3,$s3,$acc15
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	xor	$s2,$s2,$t2
        +	xor	$s3,$s3,$t3
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.align	4
        +Lppc_AES_decrypt_compact:
        +	lwz	$acc00,240($key)
        +	addi	$Tbl1,$Tbl0,2048
        +	lwz	$t0,0($key)
        +	lis	$mask80,0x8080
        +	lwz	$t1,4($key)
        +	lis	$mask1b,0x1b1b
        +	lwz	$t2,8($key)
        +	ori	$mask80,$mask80,0x8080
        +	lwz	$t3,12($key)
        +	ori	$mask1b,$mask1b,0x1b1b
        +	addi	$key,$key,16
        +___
        +$code.=<<___ if ($SIZE_T==8);
        +	insrdi	$mask80,$mask80,32,0
        +	insrdi	$mask1b,$mask1b,32,0
        +___
        +$code.=<<___;
        +	mtctr	$acc00
        +.align	4
        +Ldec_compact_loop:
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	rlwinm	$acc00,$s0,`32-24`,24,31
        +	xor	$s2,$s2,$t2
        +	rlwinm	$acc01,$s1,`32-24`,24,31
        +	xor	$s3,$s3,$t3
        +	rlwinm	$acc02,$s2,`32-24`,24,31
        +	rlwinm	$acc03,$s3,`32-24`,24,31
        +	rlwinm	$acc04,$s3,`32-16`,24,31
        +	rlwinm	$acc05,$s0,`32-16`,24,31
        +	rlwinm	$acc06,$s1,`32-16`,24,31
        +	rlwinm	$acc07,$s2,`32-16`,24,31
        +	lbzx	$acc00,$Tbl1,$acc00
        +	rlwinm	$acc08,$s2,`32-8`,24,31
        +	lbzx	$acc01,$Tbl1,$acc01
        +	rlwinm	$acc09,$s3,`32-8`,24,31
        +	lbzx	$acc02,$Tbl1,$acc02
        +	rlwinm	$acc10,$s0,`32-8`,24,31
        +	lbzx	$acc03,$Tbl1,$acc03
        +	rlwinm	$acc11,$s1,`32-8`,24,31
        +	lbzx	$acc04,$Tbl1,$acc04
        +	rlwinm	$acc12,$s1,`0`,24,31
        +	lbzx	$acc05,$Tbl1,$acc05
        +	rlwinm	$acc13,$s2,`0`,24,31
        +	lbzx	$acc06,$Tbl1,$acc06
        +	rlwinm	$acc14,$s3,`0`,24,31
        +	lbzx	$acc07,$Tbl1,$acc07
        +	rlwinm	$acc15,$s0,`0`,24,31
        +	lbzx	$acc08,$Tbl1,$acc08
        +	rlwinm	$s0,$acc00,24,0,7
        +	lbzx	$acc09,$Tbl1,$acc09
        +	rlwinm	$s1,$acc01,24,0,7
        +	lbzx	$acc10,$Tbl1,$acc10
        +	rlwinm	$s2,$acc02,24,0,7
        +	lbzx	$acc11,$Tbl1,$acc11
        +	rlwinm	$s3,$acc03,24,0,7
        +	lbzx	$acc12,$Tbl1,$acc12
        +	rlwimi	$s0,$acc04,16,8,15
        +	lbzx	$acc13,$Tbl1,$acc13
        +	rlwimi	$s1,$acc05,16,8,15
        +	lbzx	$acc14,$Tbl1,$acc14
        +	rlwimi	$s2,$acc06,16,8,15
        +	lbzx	$acc15,$Tbl1,$acc15
        +	rlwimi	$s3,$acc07,16,8,15
        +	rlwimi	$s0,$acc08,8,16,23
        +	rlwimi	$s1,$acc09,8,16,23
        +	rlwimi	$s2,$acc10,8,16,23
        +	rlwimi	$s3,$acc11,8,16,23
        +	lwz	$t0,0($key)
        +	or	$s0,$s0,$acc12
        +	lwz	$t1,4($key)
        +	or	$s1,$s1,$acc13
        +	lwz	$t2,8($key)
        +	or	$s2,$s2,$acc14
        +	lwz	$t3,12($key)
        +	or	$s3,$s3,$acc15
        +
        +	addi	$key,$key,16
        +	bdz	Ldec_compact_done
        +___
        +$code.=<<___ if ($SIZE_T==8);
        +	# vectorized permutation improves decrypt performance by 10%
        +	insrdi	$s0,$s1,32,0
        +	insrdi	$s2,$s3,32,0
        +
        +	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
        +	and	$acc02,$s2,$mask80
        +	srdi	$acc04,$acc00,7		# r1>>7
        +	srdi	$acc06,$acc02,7
        +	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
        +	andc	$acc10,$s2,$mask80
        +	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
        +	sub	$acc02,$acc02,$acc06
        +	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
        +	add	$acc10,$acc10,$acc10
        +	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc02,$acc02,$mask1b
        +	xor	$acc00,$acc00,$acc08	# r2
        +	xor	$acc02,$acc02,$acc10
        +
        +	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
        +	and	$acc06,$acc02,$mask80
        +	srdi	$acc08,$acc04,7		# r1>>7
        +	srdi	$acc10,$acc06,7
        +	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
        +	andc	$acc14,$acc02,$mask80
        +	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
        +	sub	$acc06,$acc06,$acc10
        +	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
        +	add	$acc14,$acc14,$acc14
        +	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc06,$acc06,$mask1b
        +	xor	$acc04,$acc04,$acc12	# r4
        +	xor	$acc06,$acc06,$acc14
        +
        +	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
        +	and	$acc10,$acc06,$mask80
        +	srdi	$acc12,$acc08,7		# r1>>7
        +	srdi	$acc14,$acc10,7
        +	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
        +	sub	$acc10,$acc10,$acc14
        +	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
        +	andc	$acc14,$acc06,$mask80
        +	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
        +	add	$acc14,$acc14,$acc14
        +	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc10,$acc10,$mask1b
        +	xor	$acc08,$acc08,$acc12	# r8
        +	xor	$acc10,$acc10,$acc14
        +
        +	xor	$acc00,$acc00,$s0	# r2^r0
        +	xor	$acc02,$acc02,$s2
        +	xor	$acc04,$acc04,$s0	# r4^r0
        +	xor	$acc06,$acc06,$s2
        +
        +	extrdi	$acc01,$acc00,32,0
        +	extrdi	$acc03,$acc02,32,0
        +	extrdi	$acc05,$acc04,32,0
        +	extrdi	$acc07,$acc06,32,0
        +	extrdi	$acc09,$acc08,32,0
        +	extrdi	$acc11,$acc10,32,0
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
        +	and	$acc01,$s1,$mask80
        +	and	$acc02,$s2,$mask80
        +	and	$acc03,$s3,$mask80
        +	srwi	$acc04,$acc00,7		# r1>>7
        +	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
        +	srwi	$acc05,$acc01,7
        +	andc	$acc09,$s1,$mask80
        +	srwi	$acc06,$acc02,7
        +	andc	$acc10,$s2,$mask80
        +	srwi	$acc07,$acc03,7
        +	andc	$acc11,$s3,$mask80
        +	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
        +	sub	$acc01,$acc01,$acc05
        +	sub	$acc02,$acc02,$acc06
        +	sub	$acc03,$acc03,$acc07
        +	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
        +	add	$acc09,$acc09,$acc09
        +	add	$acc10,$acc10,$acc10
        +	add	$acc11,$acc11,$acc11
        +	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc01,$acc01,$mask1b
        +	and	$acc02,$acc02,$mask1b
        +	and	$acc03,$acc03,$mask1b
        +	xor	$acc00,$acc00,$acc08	# r2
        +	xor	$acc01,$acc01,$acc09
        +	xor	$acc02,$acc02,$acc10
        +	xor	$acc03,$acc03,$acc11
        +
        +	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
        +	and	$acc05,$acc01,$mask80
        +	and	$acc06,$acc02,$mask80
        +	and	$acc07,$acc03,$mask80
        +	srwi	$acc08,$acc04,7		# r1>>7
        +	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
        +	srwi	$acc09,$acc05,7
        +	andc	$acc13,$acc01,$mask80
        +	srwi	$acc10,$acc06,7
        +	andc	$acc14,$acc02,$mask80
        +	srwi	$acc11,$acc07,7
        +	andc	$acc15,$acc03,$mask80
        +	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
        +	sub	$acc05,$acc05,$acc09
        +	sub	$acc06,$acc06,$acc10
        +	sub	$acc07,$acc07,$acc11
        +	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
        +	add	$acc13,$acc13,$acc13
        +	add	$acc14,$acc14,$acc14
        +	add	$acc15,$acc15,$acc15
        +	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc05,$acc05,$mask1b
        +	and	$acc06,$acc06,$mask1b
        +	and	$acc07,$acc07,$mask1b
        +	xor	$acc04,$acc04,$acc12	# r4
        +	xor	$acc05,$acc05,$acc13
        +	xor	$acc06,$acc06,$acc14
        +	xor	$acc07,$acc07,$acc15
        +
        +	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
        +	and	$acc09,$acc05,$mask80
        +	srwi	$acc12,$acc08,7		# r1>>7
        +	and	$acc10,$acc06,$mask80
        +	srwi	$acc13,$acc09,7
        +	and	$acc11,$acc07,$mask80
        +	srwi	$acc14,$acc10,7
        +	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
        +	srwi	$acc15,$acc11,7
        +	sub	$acc09,$acc09,$acc13
        +	sub	$acc10,$acc10,$acc14
        +	sub	$acc11,$acc11,$acc15
        +	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
        +	andc	$acc13,$acc05,$mask80
        +	andc	$acc14,$acc06,$mask80
        +	andc	$acc15,$acc07,$mask80
        +	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
        +	add	$acc13,$acc13,$acc13
        +	add	$acc14,$acc14,$acc14
        +	add	$acc15,$acc15,$acc15
        +	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
        +	and	$acc09,$acc09,$mask1b
        +	and	$acc10,$acc10,$mask1b
        +	and	$acc11,$acc11,$mask1b
        +	xor	$acc08,$acc08,$acc12	# r8
        +	xor	$acc09,$acc09,$acc13
        +	xor	$acc10,$acc10,$acc14
        +	xor	$acc11,$acc11,$acc15
        +
        +	xor	$acc00,$acc00,$s0	# r2^r0
        +	xor	$acc01,$acc01,$s1
        +	xor	$acc02,$acc02,$s2
        +	xor	$acc03,$acc03,$s3
        +	xor	$acc04,$acc04,$s0	# r4^r0
        +	xor	$acc05,$acc05,$s1
        +	xor	$acc06,$acc06,$s2
        +	xor	$acc07,$acc07,$s3
        +___
        +$code.=<<___;
        +	rotrwi	$s0,$s0,8		# = ROTATE(r0,8)
        +	rotrwi	$s1,$s1,8
        +	xor	$s0,$s0,$acc00		# ^= r2^r0
        +	rotrwi	$s2,$s2,8
        +	xor	$s1,$s1,$acc01
        +	rotrwi	$s3,$s3,8
        +	xor	$s2,$s2,$acc02
        +	xor	$s3,$s3,$acc03
        +	xor	$acc00,$acc00,$acc08
        +	xor	$acc01,$acc01,$acc09
        +	xor	$acc02,$acc02,$acc10
        +	xor	$acc03,$acc03,$acc11
        +	xor	$s0,$s0,$acc04		# ^= r4^r0
        +	rotrwi	$acc00,$acc00,24
        +	xor	$s1,$s1,$acc05
        +	rotrwi	$acc01,$acc01,24
        +	xor	$s2,$s2,$acc06
        +	rotrwi	$acc02,$acc02,24
        +	xor	$s3,$s3,$acc07
        +	rotrwi	$acc03,$acc03,24
        +	xor	$acc04,$acc04,$acc08
        +	xor	$acc05,$acc05,$acc09
        +	xor	$acc06,$acc06,$acc10
        +	xor	$acc07,$acc07,$acc11
        +	xor	$s0,$s0,$acc08		# ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
        +	rotrwi	$acc04,$acc04,16
        +	xor	$s1,$s1,$acc09
        +	rotrwi	$acc05,$acc05,16
        +	xor	$s2,$s2,$acc10
        +	rotrwi	$acc06,$acc06,16
        +	xor	$s3,$s3,$acc11
        +	rotrwi	$acc07,$acc07,16
        +	xor	$s0,$s0,$acc00		# ^= ROTATE(r8^r2^r0,24)
        +	rotrwi	$acc08,$acc08,8
        +	xor	$s1,$s1,$acc01
        +	rotrwi	$acc09,$acc09,8
        +	xor	$s2,$s2,$acc02
        +	rotrwi	$acc10,$acc10,8
        +	xor	$s3,$s3,$acc03
        +	rotrwi	$acc11,$acc11,8
        +	xor	$s0,$s0,$acc04		# ^= ROTATE(r8^r4^r0,16)
        +	xor	$s1,$s1,$acc05
        +	xor	$s2,$s2,$acc06
        +	xor	$s3,$s3,$acc07
        +	xor	$s0,$s0,$acc08		# ^= ROTATE(r8,8)	
        +	xor	$s1,$s1,$acc09	
        +	xor	$s2,$s2,$acc10	
        +	xor	$s3,$s3,$acc11	
        +
        +	b	Ldec_compact_loop
        +.align	4
        +Ldec_compact_done:
        +	xor	$s0,$s0,$t0
        +	xor	$s1,$s1,$t1
        +	xor	$s2,$s2,$t2
        +	xor	$s3,$s3,$t3
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.asciz	"AES for PPC, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	7
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-s390x.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-s390x.pl
        new file mode 100644
        index 000000000..e75dcd031
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-s390x.pl
        @@ -0,0 +1,2237 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# AES for s390x.
        +
        +# April 2007.
        +#
        +# Software performance improvement over gcc-generated code is ~70% and
        +# in absolute terms is ~73 cycles per byte processed with 128-bit key.
        +# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
        +# *strictly* in-order execution and issued instruction [in this case
        +# load value from memory is critical] has to complete before execution
        +# flow proceeds. S-boxes are compressed to 2KB[+256B].
        +#
        +# As for hardware acceleration support. It's basically a "teaser," as
        +# it can and should be improved in several ways. Most notably support
        +# for CBC is not utilized, nor multiple blocks are ever processed.
        +# Then software key schedule can be postponed till hardware support
        +# detection... Performance improvement over assembler is reportedly
        +# ~2.5x, but can reach >8x [naturally on larger chunks] if proper
        +# support is implemented.
        +
        +# May 2007.
        +#
        +# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
        +# for 128-bit keys, if hardware support is detected.
        +
        +# Januray 2009.
        +#
        +# Add support for hardware AES192/256 and reschedule instructions to
        +# minimize/avoid Address Generation Interlock hazard and to favour
        +# dual-issue z10 pipeline. This gave ~25% improvement on z10 and
        +# almost 50% on z9. The gain is smaller on z10, because being dual-
        +# issue z10 makes it improssible to eliminate the interlock condition:
        +# critial path is not long enough. Yet it spends ~24 cycles per byte
        +# processed with 128-bit key.
        +#
        +# Unlike previous version hardware support detection takes place only
        +# at the moment of key schedule setup, which is denoted in key->rounds.
        +# This is done, because deferred key setup can't be made MT-safe, not
        +# for keys longer than 128 bits.
        +#
        +# Add AES_cbc_encrypt, which gives incredible performance improvement,
        +# it was measured to be ~6.6x. It's less than previously mentioned 8x,
        +# because software implementation was optimized.
        +
        +# May 2010.
        +#
        +# Add AES_ctr32_encrypt. If hardware-assisted, it provides up to 4.3x
        +# performance improvement over "generic" counter mode routine relying
        +# on single-block, also hardware-assisted, AES_encrypt. "Up to" refers
        +# to the fact that exact throughput value depends on current stack
        +# frame alignment within 4KB page. In worst case you get ~75% of the
        +# maximum, but *on average* it would be as much as ~98%. Meaning that
        +# worst case is unlike, it's like hitting ravine on plateau.
        +
        +# November 2010.
        +#
        +# Adapt for -m31 build. If kernel supports what's called "highgprs"
        +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
        +# instructions and achieve "64-bit" performance even in 31-bit legacy
        +# application context. The feature is not specific to any particular
        +# processor, as long as it's "z-CPU". Latter implies that the code
        +# remains z/Architecture specific. On z990 it was measured to perform
        +# 2x better than code generated by gcc 4.3.
        +
        +# December 2010.
        +#
        +# Add support for z196 "cipher message with counter" instruction.
        +# Note however that it's disengaged, because it was measured to
        +# perform ~12% worse than vanilla km-based code...
        +
        +# February 2011.
        +#
        +# Add AES_xts_[en|de]crypt. This includes support for z196 km-xts-aes
        +# instructions, which deliver ~70% improvement at 8KB block size over
        +# vanilla km-based code, 37% - at most like 512-bytes block size.
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +	$SIZE_T=4;
        +	$g="";
        +} else {
        +	$SIZE_T=8;
        +	$g="g";
        +}
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$softonly=0;	# allow hardware support
        +
        +$t0="%r0";	$mask="%r0";
        +$t1="%r1";
        +$t2="%r2";	$inp="%r2";
        +$t3="%r3";	$out="%r3";	$bits="%r3";
        +$key="%r4";
        +$i1="%r5";
        +$i2="%r6";
        +$i3="%r7";
        +$s0="%r8";
        +$s1="%r9";
        +$s2="%r10";
        +$s3="%r11";
        +$tbl="%r12";
        +$rounds="%r13";
        +$ra="%r14";
        +$sp="%r15";
        +
        +$stdframe=16*$SIZE_T+4*8;
        +
        +sub _data_word()
        +{ my $i;
        +    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
        +}
        +
        +$code=<<___;
        +.text
        +
        +.type	AES_Te,\@object
        +.align	256
        +AES_Te:
        +___
        +&_data_word(
        +	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
        +	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
        +	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
        +	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
        +	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
        +	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
        +	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
        +	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
        +	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
        +	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
        +	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
        +	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
        +	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
        +	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
        +	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
        +	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
        +	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
        +	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
        +	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
        +	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
        +	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
        +	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
        +	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
        +	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
        +	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
        +	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
        +	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
        +	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
        +	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
        +	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
        +	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
        +	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
        +	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
        +	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
        +	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
        +	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
        +	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
        +	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
        +	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
        +	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
        +	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
        +	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
        +	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
        +	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
        +	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
        +	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
        +	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
        +	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
        +	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
        +	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
        +	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
        +	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
        +	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
        +	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
        +	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
        +	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
        +	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
        +	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
        +	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
        +	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
        +	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
        +	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
        +	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
        +	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
        +$code.=<<___;
        +# Te4[256]
        +.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
        +.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +# rcon[]
        +.long	0x01000000, 0x02000000, 0x04000000, 0x08000000
        +.long	0x10000000, 0x20000000, 0x40000000, 0x80000000
        +.long	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
        +.align	256
        +.size	AES_Te,.-AES_Te
        +
        +# void AES_encrypt(const unsigned char *inp, unsigned char *out,
        +# 		 const AES_KEY *key) {
        +.globl	AES_encrypt
        +.type	AES_encrypt,\@function
        +AES_encrypt:
        +___
        +$code.=<<___ if (!$softonly);
        +	l	%r0,240($key)
        +	lhi	%r1,16
        +	clr	%r0,%r1
        +	jl	.Lesoft
        +
        +	la	%r1,0($key)
        +	#la	%r2,0($inp)
        +	la	%r4,0($out)
        +	lghi	%r3,16		# single block length
        +	.long	0xb92e0042	# km %r4,%r2
        +	brc	1,.-4		# can this happen?
        +	br	%r14
        +.align	64
        +.Lesoft:
        +___
        +$code.=<<___;
        +	stm${g}	%r3,$ra,3*$SIZE_T($sp)
        +
        +	llgf	$s0,0($inp)
        +	llgf	$s1,4($inp)
        +	llgf	$s2,8($inp)
        +	llgf	$s3,12($inp)
        +
        +	larl	$tbl,AES_Te
        +	bras	$ra,_s390x_AES_encrypt
        +
        +	l${g}	$out,3*$SIZE_T($sp)
        +	st	$s0,0($out)
        +	st	$s1,4($out)
        +	st	$s2,8($out)
        +	st	$s3,12($out)
        +
        +	lm${g}	%r6,$ra,6*$SIZE_T($sp)
        +	br	$ra
        +.size	AES_encrypt,.-AES_encrypt
        +
        +.type   _s390x_AES_encrypt,\@function
        +.align	16
        +_s390x_AES_encrypt:
        +	st${g}	$ra,15*$SIZE_T($sp)
        +	x	$s0,0($key)
        +	x	$s1,4($key)
        +	x	$s2,8($key)
        +	x	$s3,12($key)
        +	l	$rounds,240($key)
        +	llill	$mask,`0xff<<3`
        +	aghi	$rounds,-1
        +	j	.Lenc_loop
        +.align	16
        +.Lenc_loop:
        +	sllg	$t1,$s0,`0+3`
        +	srlg	$t2,$s0,`8-3`
        +	srlg	$t3,$s0,`16-3`
        +	srl	$s0,`24-3`
        +	nr	$s0,$mask
        +	ngr	$t1,$mask
        +	nr	$t2,$mask
        +	nr	$t3,$mask
        +
        +	srlg	$i1,$s1,`16-3`	# i0
        +	sllg	$i2,$s1,`0+3`
        +	srlg	$i3,$s1,`8-3`
        +	srl	$s1,`24-3`
        +	nr	$i1,$mask
        +	nr	$s1,$mask
        +	ngr	$i2,$mask
        +	nr	$i3,$mask
        +
        +	l	$s0,0($s0,$tbl)	# Te0[s0>>24]
        +	l	$t1,1($t1,$tbl)	# Te3[s0>>0]
        +	l	$t2,2($t2,$tbl) # Te2[s0>>8]
        +	l	$t3,3($t3,$tbl)	# Te1[s0>>16]
        +
        +	x	$s0,3($i1,$tbl)	# Te1[s1>>16]
        +	l	$s1,0($s1,$tbl)	# Te0[s1>>24]
        +	x	$t2,1($i2,$tbl)	# Te3[s1>>0]
        +	x	$t3,2($i3,$tbl)	# Te2[s1>>8]
        +
        +	srlg	$i1,$s2,`8-3`	# i0
        +	srlg	$i2,$s2,`16-3`	# i1
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +	sllg	$i3,$s2,`0+3`
        +	srl	$s2,`24-3`
        +	nr	$s2,$mask
        +	ngr	$i3,$mask
        +
        +	xr	$s1,$t1
        +	srlg	$ra,$s3,`8-3`	# i1
        +	sllg	$t1,$s3,`0+3`	# i0
        +	nr	$ra,$mask
        +	la	$key,16($key)
        +	ngr	$t1,$mask
        +
        +	x	$s0,2($i1,$tbl)	# Te2[s2>>8]
        +	x	$s1,3($i2,$tbl)	# Te1[s2>>16]
        +	l	$s2,0($s2,$tbl)	# Te0[s2>>24]
        +	x	$t3,1($i3,$tbl)	# Te3[s2>>0]
        +
        +	srlg	$i3,$s3,`16-3`	# i2
        +	xr	$s2,$t2
        +	srl	$s3,`24-3`
        +	nr	$i3,$mask
        +	nr	$s3,$mask
        +
        +	x	$s0,0($key)
        +	x	$s1,4($key)
        +	x	$s2,8($key)
        +	x	$t3,12($key)
        +
        +	x	$s0,1($t1,$tbl)	# Te3[s3>>0]
        +	x	$s1,2($ra,$tbl)	# Te2[s3>>8]
        +	x	$s2,3($i3,$tbl)	# Te1[s3>>16]
        +	l	$s3,0($s3,$tbl)	# Te0[s3>>24]
        +	xr	$s3,$t3
        +
        +	brct	$rounds,.Lenc_loop
        +	.align	16
        +
        +	sllg	$t1,$s0,`0+3`
        +	srlg	$t2,$s0,`8-3`
        +	ngr	$t1,$mask
        +	srlg	$t3,$s0,`16-3`
        +	srl	$s0,`24-3`
        +	nr	$s0,$mask
        +	nr	$t2,$mask
        +	nr	$t3,$mask
        +
        +	srlg	$i1,$s1,`16-3`	# i0
        +	sllg	$i2,$s1,`0+3`
        +	ngr	$i2,$mask
        +	srlg	$i3,$s1,`8-3`
        +	srl	$s1,`24-3`
        +	nr	$i1,$mask
        +	nr	$s1,$mask
        +	nr	$i3,$mask
        +
        +	llgc	$s0,2($s0,$tbl)	# Te4[s0>>24]
        +	llgc	$t1,2($t1,$tbl)	# Te4[s0>>0]
        +	sll	$s0,24
        +	llgc	$t2,2($t2,$tbl)	# Te4[s0>>8]
        +	llgc	$t3,2($t3,$tbl)	# Te4[s0>>16]
        +	sll	$t2,8
        +	sll	$t3,16
        +
        +	llgc	$i1,2($i1,$tbl)	# Te4[s1>>16]
        +	llgc	$s1,2($s1,$tbl)	# Te4[s1>>24]
        +	llgc	$i2,2($i2,$tbl)	# Te4[s1>>0]
        +	llgc	$i3,2($i3,$tbl)	# Te4[s1>>8]
        +	sll	$i1,16
        +	sll	$s1,24
        +	sll	$i3,8
        +	or	$s0,$i1
        +	or	$s1,$t1
        +	or	$t2,$i2
        +	or	$t3,$i3
        +	
        +	srlg	$i1,$s2,`8-3`	# i0
        +	srlg	$i2,$s2,`16-3`	# i1
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +	sllg	$i3,$s2,`0+3`
        +	srl	$s2,`24-3`
        +	ngr	$i3,$mask
        +	nr	$s2,$mask
        +
        +	sllg	$t1,$s3,`0+3`	# i0
        +	srlg	$ra,$s3,`8-3`	# i1
        +	ngr	$t1,$mask
        +
        +	llgc	$i1,2($i1,$tbl)	# Te4[s2>>8]
        +	llgc	$i2,2($i2,$tbl)	# Te4[s2>>16]
        +	sll	$i1,8
        +	llgc	$s2,2($s2,$tbl)	# Te4[s2>>24]
        +	llgc	$i3,2($i3,$tbl)	# Te4[s2>>0]
        +	sll	$i2,16
        +	nr	$ra,$mask
        +	sll	$s2,24
        +	or	$s0,$i1
        +	or	$s1,$i2
        +	or	$s2,$t2
        +	or	$t3,$i3
        +
        +	srlg	$i3,$s3,`16-3`	# i2
        +	srl	$s3,`24-3`
        +	nr	$i3,$mask
        +	nr	$s3,$mask
        +
        +	l	$t0,16($key)
        +	l	$t2,20($key)
        +
        +	llgc	$i1,2($t1,$tbl)	# Te4[s3>>0]
        +	llgc	$i2,2($ra,$tbl)	# Te4[s3>>8]
        +	llgc	$i3,2($i3,$tbl)	# Te4[s3>>16]
        +	llgc	$s3,2($s3,$tbl)	# Te4[s3>>24]
        +	sll	$i2,8
        +	sll	$i3,16
        +	sll	$s3,24
        +	or	$s0,$i1
        +	or	$s1,$i2
        +	or	$s2,$i3
        +	or	$s3,$t3
        +
        +	l${g}	$ra,15*$SIZE_T($sp)
        +	xr	$s0,$t0
        +	xr	$s1,$t2
        +	x	$s2,24($key)
        +	x	$s3,28($key)
        +
        +	br	$ra	
        +.size	_s390x_AES_encrypt,.-_s390x_AES_encrypt
        +___
        +
        +$code.=<<___;
        +.type	AES_Td,\@object
        +.align	256
        +AES_Td:
        +___
        +&_data_word(
        +	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
        +	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
        +	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
        +	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
        +	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
        +	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
        +	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
        +	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
        +	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
        +	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
        +	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
        +	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
        +	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
        +	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
        +	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
        +	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
        +	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
        +	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
        +	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
        +	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
        +	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
        +	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
        +	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
        +	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
        +	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
        +	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
        +	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
        +	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
        +	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
        +	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
        +	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
        +	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
        +	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
        +	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
        +	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
        +	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
        +	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
        +	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
        +	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
        +	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
        +	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
        +	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
        +	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
        +	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
        +	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
        +	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
        +	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
        +	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
        +	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
        +	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
        +	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
        +	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
        +	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
        +	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
        +	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
        +	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
        +	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
        +	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
        +	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
        +	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
        +	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
        +	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
        +	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
        +	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
        +$code.=<<___;
        +# Td4[256]
        +.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
        +.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +.size	AES_Td,.-AES_Td
        +
        +# void AES_decrypt(const unsigned char *inp, unsigned char *out,
        +# 		 const AES_KEY *key) {
        +.globl	AES_decrypt
        +.type	AES_decrypt,\@function
        +AES_decrypt:
        +___
        +$code.=<<___ if (!$softonly);
        +	l	%r0,240($key)
        +	lhi	%r1,16
        +	clr	%r0,%r1
        +	jl	.Ldsoft
        +
        +	la	%r1,0($key)
        +	#la	%r2,0($inp)
        +	la	%r4,0($out)
        +	lghi	%r3,16		# single block length
        +	.long	0xb92e0042	# km %r4,%r2
        +	brc	1,.-4		# can this happen?
        +	br	%r14
        +.align	64
        +.Ldsoft:
        +___
        +$code.=<<___;
        +	stm${g}	%r3,$ra,3*$SIZE_T($sp)
        +
        +	llgf	$s0,0($inp)
        +	llgf	$s1,4($inp)
        +	llgf	$s2,8($inp)
        +	llgf	$s3,12($inp)
        +
        +	larl	$tbl,AES_Td
        +	bras	$ra,_s390x_AES_decrypt
        +
        +	l${g}	$out,3*$SIZE_T($sp)
        +	st	$s0,0($out)
        +	st	$s1,4($out)
        +	st	$s2,8($out)
        +	st	$s3,12($out)
        +
        +	lm${g}	%r6,$ra,6*$SIZE_T($sp)
        +	br	$ra
        +.size	AES_decrypt,.-AES_decrypt
        +
        +.type   _s390x_AES_decrypt,\@function
        +.align	16
        +_s390x_AES_decrypt:
        +	st${g}	$ra,15*$SIZE_T($sp)
        +	x	$s0,0($key)
        +	x	$s1,4($key)
        +	x	$s2,8($key)
        +	x	$s3,12($key)
        +	l	$rounds,240($key)
        +	llill	$mask,`0xff<<3`
        +	aghi	$rounds,-1
        +	j	.Ldec_loop
        +.align	16
        +.Ldec_loop:
        +	srlg	$t1,$s0,`16-3`
        +	srlg	$t2,$s0,`8-3`
        +	sllg	$t3,$s0,`0+3`
        +	srl	$s0,`24-3`
        +	nr	$s0,$mask
        +	nr	$t1,$mask
        +	nr	$t2,$mask
        +	ngr	$t3,$mask
        +
        +	sllg	$i1,$s1,`0+3`	# i0
        +	srlg	$i2,$s1,`16-3`
        +	srlg	$i3,$s1,`8-3`
        +	srl	$s1,`24-3`
        +	ngr	$i1,$mask
        +	nr	$s1,$mask
        +	nr	$i2,$mask
        +	nr	$i3,$mask
        +
        +	l	$s0,0($s0,$tbl)	# Td0[s0>>24]
        +	l	$t1,3($t1,$tbl)	# Td1[s0>>16]
        +	l	$t2,2($t2,$tbl)	# Td2[s0>>8]
        +	l	$t3,1($t3,$tbl)	# Td3[s0>>0]
        +
        +	x	$s0,1($i1,$tbl)	# Td3[s1>>0]
        +	l	$s1,0($s1,$tbl)	# Td0[s1>>24]
        +	x	$t2,3($i2,$tbl)	# Td1[s1>>16]
        +	x	$t3,2($i3,$tbl)	# Td2[s1>>8]
        +
        +	srlg	$i1,$s2,`8-3`	# i0
        +	sllg	$i2,$s2,`0+3`	# i1
        +	srlg	$i3,$s2,`16-3`
        +	srl	$s2,`24-3`
        +	nr	$i1,$mask
        +	ngr	$i2,$mask
        +	nr	$s2,$mask
        +	nr	$i3,$mask
        +
        +	xr	$s1,$t1
        +	srlg	$ra,$s3,`8-3`	# i1
        +	srlg	$t1,$s3,`16-3`	# i0
        +	nr	$ra,$mask
        +	la	$key,16($key)
        +	nr	$t1,$mask
        +
        +	x	$s0,2($i1,$tbl)	# Td2[s2>>8]
        +	x	$s1,1($i2,$tbl)	# Td3[s2>>0]
        +	l	$s2,0($s2,$tbl)	# Td0[s2>>24]
        +	x	$t3,3($i3,$tbl)	# Td1[s2>>16]
        +
        +	sllg	$i3,$s3,`0+3`	# i2
        +	srl	$s3,`24-3`
        +	ngr	$i3,$mask
        +	nr	$s3,$mask
        +
        +	xr	$s2,$t2
        +	x	$s0,0($key)
        +	x	$s1,4($key)
        +	x	$s2,8($key)
        +	x	$t3,12($key)
        +
        +	x	$s0,3($t1,$tbl)	# Td1[s3>>16]
        +	x	$s1,2($ra,$tbl)	# Td2[s3>>8]
        +	x	$s2,1($i3,$tbl)	# Td3[s3>>0]
        +	l	$s3,0($s3,$tbl)	# Td0[s3>>24]
        +	xr	$s3,$t3
        +
        +	brct	$rounds,.Ldec_loop
        +	.align	16
        +
        +	l	$t1,`2048+0`($tbl)	# prefetch Td4
        +	l	$t2,`2048+64`($tbl)
        +	l	$t3,`2048+128`($tbl)
        +	l	$i1,`2048+192`($tbl)
        +	llill	$mask,0xff
        +
        +	srlg	$i3,$s0,24	# i0
        +	srlg	$t1,$s0,16
        +	srlg	$t2,$s0,8
        +	nr	$s0,$mask	# i3
        +	nr	$t1,$mask
        +
        +	srlg	$i1,$s1,24
        +	nr	$t2,$mask
        +	srlg	$i2,$s1,16
        +	srlg	$ra,$s1,8
        +	nr	$s1,$mask	# i0
        +	nr	$i2,$mask
        +	nr	$ra,$mask
        +
        +	llgc	$i3,2048($i3,$tbl)	# Td4[s0>>24]
        +	llgc	$t1,2048($t1,$tbl)	# Td4[s0>>16]
        +	llgc	$t2,2048($t2,$tbl)	# Td4[s0>>8]
        +	sll	$t1,16
        +	llgc	$t3,2048($s0,$tbl)	# Td4[s0>>0]
        +	sllg	$s0,$i3,24
        +	sll	$t2,8
        +
        +	llgc	$s1,2048($s1,$tbl)	# Td4[s1>>0]
        +	llgc	$i1,2048($i1,$tbl)	# Td4[s1>>24]
        +	llgc	$i2,2048($i2,$tbl)	# Td4[s1>>16]
        +	sll	$i1,24
        +	llgc	$i3,2048($ra,$tbl)	# Td4[s1>>8]
        +	sll	$i2,16
        +	sll	$i3,8
        +	or	$s0,$s1
        +	or	$t1,$i1
        +	or	$t2,$i2
        +	or	$t3,$i3
        +
        +	srlg	$i1,$s2,8	# i0
        +	srlg	$i2,$s2,24
        +	srlg	$i3,$s2,16
        +	nr	$s2,$mask	# i1
        +	nr	$i1,$mask
        +	nr	$i3,$mask
        +	llgc	$i1,2048($i1,$tbl)	# Td4[s2>>8]
        +	llgc	$s1,2048($s2,$tbl)	# Td4[s2>>0]
        +	llgc	$i2,2048($i2,$tbl)	# Td4[s2>>24]
        +	llgc	$i3,2048($i3,$tbl)	# Td4[s2>>16]
        +	sll	$i1,8
        +	sll	$i2,24
        +	or	$s0,$i1
        +	sll	$i3,16
        +	or	$t2,$i2
        +	or	$t3,$i3
        +
        +	srlg	$i1,$s3,16	# i0
        +	srlg	$i2,$s3,8	# i1
        +	srlg	$i3,$s3,24
        +	nr	$s3,$mask	# i2
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +
        +	l${g}	$ra,15*$SIZE_T($sp)
        +	or	$s1,$t1
        +	l	$t0,16($key)
        +	l	$t1,20($key)
        +
        +	llgc	$i1,2048($i1,$tbl)	# Td4[s3>>16]
        +	llgc	$i2,2048($i2,$tbl)	# Td4[s3>>8]
        +	sll	$i1,16
        +	llgc	$s2,2048($s3,$tbl)	# Td4[s3>>0]
        +	llgc	$s3,2048($i3,$tbl)	# Td4[s3>>24]
        +	sll	$i2,8
        +	sll	$s3,24
        +	or	$s0,$i1
        +	or	$s1,$i2
        +	or	$s2,$t2
        +	or	$s3,$t3
        +
        +	xr	$s0,$t0
        +	xr	$s1,$t1
        +	x	$s2,24($key)
        +	x	$s3,28($key)
        +
        +	br	$ra	
        +.size	_s390x_AES_decrypt,.-_s390x_AES_decrypt
        +___
        +
        +$code.=<<___;
        +# void AES_set_encrypt_key(const unsigned char *in, int bits,
        +# 		 AES_KEY *key) {
        +.globl	private_AES_set_encrypt_key
        +.type	private_AES_set_encrypt_key,\@function
        +.align	16
        +private_AES_set_encrypt_key:
        +_s390x_AES_set_encrypt_key:
        +	lghi	$t0,0
        +	cl${g}r	$inp,$t0
        +	je	.Lminus1
        +	cl${g}r	$key,$t0
        +	je	.Lminus1
        +
        +	lghi	$t0,128
        +	clr	$bits,$t0
        +	je	.Lproceed
        +	lghi	$t0,192
        +	clr	$bits,$t0
        +	je	.Lproceed
        +	lghi	$t0,256
        +	clr	$bits,$t0
        +	je	.Lproceed
        +	lghi	%r2,-2
        +	br	%r14
        +
        +.align	16
        +.Lproceed:
        +___
        +$code.=<<___ if (!$softonly);
        +	# convert bits to km code, [128,192,256]->[18,19,20]
        +	lhi	%r5,-128
        +	lhi	%r0,18
        +	ar	%r5,$bits
        +	srl	%r5,6
        +	ar	%r5,%r0
        +
        +	larl	%r1,OPENSSL_s390xcap_P
        +	lg	%r0,0(%r1)
        +	tmhl	%r0,0x4000	# check for message-security assist
        +	jz	.Lekey_internal
        +
        +	lghi	%r0,0		# query capability vector
        +	la	%r1,16($sp)
        +	.long	0xb92f0042	# kmc %r4,%r2
        +
        +	llihh	%r1,0x8000
        +	srlg	%r1,%r1,0(%r5)
        +	ng	%r1,16($sp)
        +	jz	.Lekey_internal
        +
        +	lmg	%r0,%r1,0($inp)	# just copy 128 bits...
        +	stmg	%r0,%r1,0($key)
        +	lhi	%r0,192
        +	cr	$bits,%r0
        +	jl	1f
        +	lg	%r1,16($inp)
        +	stg	%r1,16($key)
        +	je	1f
        +	lg	%r1,24($inp)
        +	stg	%r1,24($key)
        +1:	st	$bits,236($key)	# save bits [for debugging purposes]
        +	lgr	$t0,%r5
        +	st	%r5,240($key)	# save km code
        +	lghi	%r2,0
        +	br	%r14
        +___
        +$code.=<<___;
        +.align	16
        +.Lekey_internal:
        +	stm${g}	%r4,%r13,4*$SIZE_T($sp)	# all non-volatile regs and $key
        +
        +	larl	$tbl,AES_Te+2048
        +
        +	llgf	$s0,0($inp)
        +	llgf	$s1,4($inp)
        +	llgf	$s2,8($inp)
        +	llgf	$s3,12($inp)
        +	st	$s0,0($key)
        +	st	$s1,4($key)
        +	st	$s2,8($key)
        +	st	$s3,12($key)
        +	lghi	$t0,128
        +	cr	$bits,$t0
        +	jne	.Lnot128
        +
        +	llill	$mask,0xff
        +	lghi	$t3,0			# i=0
        +	lghi	$rounds,10
        +	st	$rounds,240($key)
        +
        +	llgfr	$t2,$s3			# temp=rk[3]
        +	srlg	$i1,$s3,8
        +	srlg	$i2,$s3,16
        +	srlg	$i3,$s3,24
        +	nr	$t2,$mask
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +
        +.align	16
        +.L128_loop:
        +	la	$t2,0($t2,$tbl)
        +	la	$i1,0($i1,$tbl)
        +	la	$i2,0($i2,$tbl)
        +	la	$i3,0($i3,$tbl)
        +	icm	$t2,2,0($t2)		# Te4[rk[3]>>0]<<8
        +	icm	$t2,4,0($i1)		# Te4[rk[3]>>8]<<16
        +	icm	$t2,8,0($i2)		# Te4[rk[3]>>16]<<24
        +	icm	$t2,1,0($i3)		# Te4[rk[3]>>24]
        +	x	$t2,256($t3,$tbl)	# rcon[i]
        +	xr	$s0,$t2			# rk[4]=rk[0]^...
        +	xr	$s1,$s0			# rk[5]=rk[1]^rk[4]
        +	xr	$s2,$s1			# rk[6]=rk[2]^rk[5]
        +	xr	$s3,$s2			# rk[7]=rk[3]^rk[6]
        +
        +	llgfr	$t2,$s3			# temp=rk[3]
        +	srlg	$i1,$s3,8
        +	srlg	$i2,$s3,16
        +	nr	$t2,$mask
        +	nr	$i1,$mask
        +	srlg	$i3,$s3,24
        +	nr	$i2,$mask
        +
        +	st	$s0,16($key)
        +	st	$s1,20($key)
        +	st	$s2,24($key)
        +	st	$s3,28($key)
        +	la	$key,16($key)		# key+=4
        +	la	$t3,4($t3)		# i++
        +	brct	$rounds,.L128_loop
        +	lghi	$t0,10
        +	lghi	%r2,0
        +	lm${g}	%r4,%r13,4*$SIZE_T($sp)
        +	br	$ra
        +
        +.align	16
        +.Lnot128:
        +	llgf	$t0,16($inp)
        +	llgf	$t1,20($inp)
        +	st	$t0,16($key)
        +	st	$t1,20($key)
        +	lghi	$t0,192
        +	cr	$bits,$t0
        +	jne	.Lnot192
        +
        +	llill	$mask,0xff
        +	lghi	$t3,0			# i=0
        +	lghi	$rounds,12
        +	st	$rounds,240($key)
        +	lghi	$rounds,8
        +
        +	srlg	$i1,$t1,8
        +	srlg	$i2,$t1,16
        +	srlg	$i3,$t1,24
        +	nr	$t1,$mask
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +
        +.align	16
        +.L192_loop:
        +	la	$t1,0($t1,$tbl)
        +	la	$i1,0($i1,$tbl)
        +	la	$i2,0($i2,$tbl)
        +	la	$i3,0($i3,$tbl)
        +	icm	$t1,2,0($t1)		# Te4[rk[5]>>0]<<8
        +	icm	$t1,4,0($i1)		# Te4[rk[5]>>8]<<16
        +	icm	$t1,8,0($i2)		# Te4[rk[5]>>16]<<24
        +	icm	$t1,1,0($i3)		# Te4[rk[5]>>24]
        +	x	$t1,256($t3,$tbl)	# rcon[i]
        +	xr	$s0,$t1			# rk[6]=rk[0]^...
        +	xr	$s1,$s0			# rk[7]=rk[1]^rk[6]
        +	xr	$s2,$s1			# rk[8]=rk[2]^rk[7]
        +	xr	$s3,$s2			# rk[9]=rk[3]^rk[8]
        +
        +	st	$s0,24($key)
        +	st	$s1,28($key)
        +	st	$s2,32($key)
        +	st	$s3,36($key)
        +	brct	$rounds,.L192_continue
        +	lghi	$t0,12
        +	lghi	%r2,0
        +	lm${g}	%r4,%r13,4*$SIZE_T($sp)
        +	br	$ra
        +
        +.align	16
        +.L192_continue:
        +	lgr	$t1,$s3
        +	x	$t1,16($key)		# rk[10]=rk[4]^rk[9]
        +	st	$t1,40($key)
        +	x	$t1,20($key)		# rk[11]=rk[5]^rk[10]
        +	st	$t1,44($key)
        +
        +	srlg	$i1,$t1,8
        +	srlg	$i2,$t1,16
        +	srlg	$i3,$t1,24
        +	nr	$t1,$mask
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +
        +	la	$key,24($key)		# key+=6
        +	la	$t3,4($t3)		# i++
        +	j	.L192_loop
        +
        +.align	16
        +.Lnot192:
        +	llgf	$t0,24($inp)
        +	llgf	$t1,28($inp)
        +	st	$t0,24($key)
        +	st	$t1,28($key)
        +	llill	$mask,0xff
        +	lghi	$t3,0			# i=0
        +	lghi	$rounds,14
        +	st	$rounds,240($key)
        +	lghi	$rounds,7
        +
        +	srlg	$i1,$t1,8
        +	srlg	$i2,$t1,16
        +	srlg	$i3,$t1,24
        +	nr	$t1,$mask
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +
        +.align	16
        +.L256_loop:
        +	la	$t1,0($t1,$tbl)
        +	la	$i1,0($i1,$tbl)
        +	la	$i2,0($i2,$tbl)
        +	la	$i3,0($i3,$tbl)
        +	icm	$t1,2,0($t1)		# Te4[rk[7]>>0]<<8
        +	icm	$t1,4,0($i1)		# Te4[rk[7]>>8]<<16
        +	icm	$t1,8,0($i2)		# Te4[rk[7]>>16]<<24
        +	icm	$t1,1,0($i3)		# Te4[rk[7]>>24]
        +	x	$t1,256($t3,$tbl)	# rcon[i]
        +	xr	$s0,$t1			# rk[8]=rk[0]^...
        +	xr	$s1,$s0			# rk[9]=rk[1]^rk[8]
        +	xr	$s2,$s1			# rk[10]=rk[2]^rk[9]
        +	xr	$s3,$s2			# rk[11]=rk[3]^rk[10]
        +	st	$s0,32($key)
        +	st	$s1,36($key)
        +	st	$s2,40($key)
        +	st	$s3,44($key)
        +	brct	$rounds,.L256_continue
        +	lghi	$t0,14
        +	lghi	%r2,0
        +	lm${g}	%r4,%r13,4*$SIZE_T($sp)
        +	br	$ra
        +
        +.align	16
        +.L256_continue:
        +	lgr	$t1,$s3			# temp=rk[11]
        +	srlg	$i1,$s3,8
        +	srlg	$i2,$s3,16
        +	srlg	$i3,$s3,24
        +	nr	$t1,$mask
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +	la	$t1,0($t1,$tbl)
        +	la	$i1,0($i1,$tbl)
        +	la	$i2,0($i2,$tbl)
        +	la	$i3,0($i3,$tbl)
        +	llgc	$t1,0($t1)		# Te4[rk[11]>>0]
        +	icm	$t1,2,0($i1)		# Te4[rk[11]>>8]<<8
        +	icm	$t1,4,0($i2)		# Te4[rk[11]>>16]<<16
        +	icm	$t1,8,0($i3)		# Te4[rk[11]>>24]<<24
        +	x	$t1,16($key)		# rk[12]=rk[4]^...
        +	st	$t1,48($key)
        +	x	$t1,20($key)		# rk[13]=rk[5]^rk[12]
        +	st	$t1,52($key)
        +	x	$t1,24($key)		# rk[14]=rk[6]^rk[13]
        +	st	$t1,56($key)
        +	x	$t1,28($key)		# rk[15]=rk[7]^rk[14]
        +	st	$t1,60($key)
        +
        +	srlg	$i1,$t1,8
        +	srlg	$i2,$t1,16
        +	srlg	$i3,$t1,24
        +	nr	$t1,$mask
        +	nr	$i1,$mask
        +	nr	$i2,$mask
        +
        +	la	$key,32($key)		# key+=8
        +	la	$t3,4($t3)		# i++
        +	j	.L256_loop
        +
        +.Lminus1:
        +	lghi	%r2,-1
        +	br	$ra
        +.size	private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
        +
        +# void AES_set_decrypt_key(const unsigned char *in, int bits,
        +# 		 AES_KEY *key) {
        +.globl	private_AES_set_decrypt_key
        +.type	private_AES_set_decrypt_key,\@function
        +.align	16
        +private_AES_set_decrypt_key:
        +	#st${g}	$key,4*$SIZE_T($sp)	# I rely on AES_set_encrypt_key to
        +	st${g}	$ra,14*$SIZE_T($sp)	# save non-volatile registers and $key!
        +	bras	$ra,_s390x_AES_set_encrypt_key
        +	#l${g}	$key,4*$SIZE_T($sp)
        +	l${g}	$ra,14*$SIZE_T($sp)
        +	ltgr	%r2,%r2
        +	bnzr	$ra
        +___
        +$code.=<<___ if (!$softonly);
        +	#l	$t0,240($key)
        +	lhi	$t1,16
        +	cr	$t0,$t1
        +	jl	.Lgo
        +	oill	$t0,0x80	# set "decrypt" bit
        +	st	$t0,240($key)
        +	br	$ra
        +___
        +$code.=<<___;
        +.align	16
        +.Lgo:	lgr	$rounds,$t0	#llgf	$rounds,240($key)
        +	la	$i1,0($key)
        +	sllg	$i2,$rounds,4
        +	la	$i2,0($i2,$key)
        +	srl	$rounds,1
        +	lghi	$t1,-16
        +
        +.align	16
        +.Linv:	lmg	$s0,$s1,0($i1)
        +	lmg	$s2,$s3,0($i2)
        +	stmg	$s0,$s1,0($i2)
        +	stmg	$s2,$s3,0($i1)
        +	la	$i1,16($i1)
        +	la	$i2,0($t1,$i2)
        +	brct	$rounds,.Linv
        +___
        +$mask80=$i1;
        +$mask1b=$i2;
        +$maskfe=$i3;
        +$code.=<<___;
        +	llgf	$rounds,240($key)
        +	aghi	$rounds,-1
        +	sll	$rounds,2	# (rounds-1)*4
        +	llilh	$mask80,0x8080
        +	llilh	$mask1b,0x1b1b
        +	llilh	$maskfe,0xfefe
        +	oill	$mask80,0x8080
        +	oill	$mask1b,0x1b1b
        +	oill	$maskfe,0xfefe
        +
        +.align	16
        +.Lmix:	l	$s0,16($key)	# tp1
        +	lr	$s1,$s0
        +	ngr	$s1,$mask80
        +	srlg	$t1,$s1,7
        +	slr	$s1,$t1
        +	nr	$s1,$mask1b
        +	sllg	$t1,$s0,1
        +	nr	$t1,$maskfe
        +	xr	$s1,$t1		# tp2
        +
        +	lr	$s2,$s1
        +	ngr	$s2,$mask80
        +	srlg	$t1,$s2,7
        +	slr	$s2,$t1
        +	nr	$s2,$mask1b
        +	sllg	$t1,$s1,1
        +	nr	$t1,$maskfe
        +	xr	$s2,$t1		# tp4
        +
        +	lr	$s3,$s2
        +	ngr	$s3,$mask80
        +	srlg	$t1,$s3,7
        +	slr	$s3,$t1
        +	nr	$s3,$mask1b
        +	sllg	$t1,$s2,1
        +	nr	$t1,$maskfe
        +	xr	$s3,$t1		# tp8
        +
        +	xr	$s1,$s0		# tp2^tp1
        +	xr	$s2,$s0		# tp4^tp1
        +	rll	$s0,$s0,24	# = ROTATE(tp1,8)
        +	xr	$s2,$s3		# ^=tp8
        +	xr	$s0,$s1		# ^=tp2^tp1
        +	xr	$s1,$s3		# tp2^tp1^tp8
        +	xr	$s0,$s2		# ^=tp4^tp1^tp8
        +	rll	$s1,$s1,8
        +	rll	$s2,$s2,16
        +	xr	$s0,$s1		# ^= ROTATE(tp8^tp2^tp1,24)
        +	rll	$s3,$s3,24
        +	xr	$s0,$s2    	# ^= ROTATE(tp8^tp4^tp1,16)
        +	xr	$s0,$s3		# ^= ROTATE(tp8,8)
        +
        +	st	$s0,16($key)
        +	la	$key,4($key)
        +	brct	$rounds,.Lmix
        +
        +	lm${g}	%r6,%r13,6*$SIZE_T($sp)# as was saved by AES_set_encrypt_key!
        +	lghi	%r2,0
        +	br	$ra
        +.size	private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
        +___
        +
        +########################################################################
        +# void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +#                     size_t length, const AES_KEY *key,
        +#                     unsigned char *ivec, const int enc)
        +{
        +my $inp="%r2";
        +my $out="%r4";	# length and out are swapped
        +my $len="%r3";
        +my $key="%r5";
        +my $ivp="%r6";
        +
        +$code.=<<___;
        +.globl	AES_cbc_encrypt
        +.type	AES_cbc_encrypt,\@function
        +.align	16
        +AES_cbc_encrypt:
        +	xgr	%r3,%r4		# flip %r3 and %r4, out and len
        +	xgr	%r4,%r3
        +	xgr	%r3,%r4
        +___
        +$code.=<<___ if (!$softonly);
        +	lhi	%r0,16
        +	cl	%r0,240($key)
        +	jh	.Lcbc_software
        +
        +	lg	%r0,0($ivp)	# copy ivec
        +	lg	%r1,8($ivp)
        +	stmg	%r0,%r1,16($sp)
        +	lmg	%r0,%r1,0($key)	# copy key, cover 256 bit
        +	stmg	%r0,%r1,32($sp)
        +	lmg	%r0,%r1,16($key)
        +	stmg	%r0,%r1,48($sp)
        +	l	%r0,240($key)	# load kmc code
        +	lghi	$key,15		# res=len%16, len-=res;
        +	ngr	$key,$len
        +	sl${g}r	$len,$key
        +	la	%r1,16($sp)	# parameter block - ivec || key
        +	jz	.Lkmc_truncated
        +	.long	0xb92f0042	# kmc %r4,%r2
        +	brc	1,.-4		# pay attention to "partial completion"
        +	ltr	$key,$key
        +	jnz	.Lkmc_truncated
        +.Lkmc_done:
        +	lmg	%r0,%r1,16($sp)	# copy ivec to caller
        +	stg	%r0,0($ivp)
        +	stg	%r1,8($ivp)
        +	br	$ra
        +.align	16
        +.Lkmc_truncated:
        +	ahi	$key,-1		# it's the way it's encoded in mvc
        +	tmll	%r0,0x80
        +	jnz	.Lkmc_truncated_dec
        +	lghi	%r1,0
        +	stg	%r1,16*$SIZE_T($sp)
        +	stg	%r1,16*$SIZE_T+8($sp)
        +	bras	%r1,1f
        +	mvc	16*$SIZE_T(1,$sp),0($inp)
        +1:	ex	$key,0(%r1)
        +	la	%r1,16($sp)	# restore parameter block
        +	la	$inp,16*$SIZE_T($sp)
        +	lghi	$len,16
        +	.long	0xb92f0042	# kmc %r4,%r2
        +	j	.Lkmc_done
        +.align	16
        +.Lkmc_truncated_dec:
        +	st${g}	$out,4*$SIZE_T($sp)
        +	la	$out,16*$SIZE_T($sp)
        +	lghi	$len,16
        +	.long	0xb92f0042	# kmc %r4,%r2
        +	l${g}	$out,4*$SIZE_T($sp)
        +	bras	%r1,2f
        +	mvc	0(1,$out),16*$SIZE_T($sp)
        +2:	ex	$key,0(%r1)
        +	j	.Lkmc_done
        +.align	16
        +.Lcbc_software:
        +___
        +$code.=<<___;
        +	stm${g}	$key,$ra,5*$SIZE_T($sp)
        +	lhi	%r0,0
        +	cl	%r0,`$stdframe+$SIZE_T-4`($sp)
        +	je	.Lcbc_decrypt
        +
        +	larl	$tbl,AES_Te
        +
        +	llgf	$s0,0($ivp)
        +	llgf	$s1,4($ivp)
        +	llgf	$s2,8($ivp)
        +	llgf	$s3,12($ivp)
        +
        +	lghi	$t0,16
        +	sl${g}r	$len,$t0
        +	brc	4,.Lcbc_enc_tail	# if borrow
        +.Lcbc_enc_loop:
        +	stm${g}	$inp,$out,2*$SIZE_T($sp)
        +	x	$s0,0($inp)
        +	x	$s1,4($inp)
        +	x	$s2,8($inp)
        +	x	$s3,12($inp)
        +	lgr	%r4,$key
        +
        +	bras	$ra,_s390x_AES_encrypt
        +
        +	lm${g}	$inp,$key,2*$SIZE_T($sp)
        +	st	$s0,0($out)
        +	st	$s1,4($out)
        +	st	$s2,8($out)
        +	st	$s3,12($out)
        +
        +	la	$inp,16($inp)
        +	la	$out,16($out)
        +	lghi	$t0,16
        +	lt${g}r	$len,$len
        +	jz	.Lcbc_enc_done
        +	sl${g}r	$len,$t0
        +	brc	4,.Lcbc_enc_tail	# if borrow
        +	j	.Lcbc_enc_loop
        +.align	16
        +.Lcbc_enc_done:
        +	l${g}	$ivp,6*$SIZE_T($sp)
        +	st	$s0,0($ivp)
        +	st	$s1,4($ivp)	
        +	st	$s2,8($ivp)
        +	st	$s3,12($ivp)
        +
        +	lm${g}	%r7,$ra,7*$SIZE_T($sp)
        +	br	$ra
        +
        +.align	16
        +.Lcbc_enc_tail:
        +	aghi	$len,15
        +	lghi	$t0,0
        +	stg	$t0,16*$SIZE_T($sp)
        +	stg	$t0,16*$SIZE_T+8($sp)
        +	bras	$t1,3f
        +	mvc	16*$SIZE_T(1,$sp),0($inp)
        +3:	ex	$len,0($t1)
        +	lghi	$len,0
        +	la	$inp,16*$SIZE_T($sp)
        +	j	.Lcbc_enc_loop
        +
        +.align	16
        +.Lcbc_decrypt:
        +	larl	$tbl,AES_Td
        +
        +	lg	$t0,0($ivp)
        +	lg	$t1,8($ivp)
        +	stmg	$t0,$t1,16*$SIZE_T($sp)
        +
        +.Lcbc_dec_loop:
        +	stm${g}	$inp,$out,2*$SIZE_T($sp)
        +	llgf	$s0,0($inp)
        +	llgf	$s1,4($inp)
        +	llgf	$s2,8($inp)
        +	llgf	$s3,12($inp)
        +	lgr	%r4,$key
        +
        +	bras	$ra,_s390x_AES_decrypt
        +
        +	lm${g}	$inp,$key,2*$SIZE_T($sp)
        +	sllg	$s0,$s0,32
        +	sllg	$s2,$s2,32
        +	lr	$s0,$s1
        +	lr	$s2,$s3
        +
        +	lg	$t0,0($inp)
        +	lg	$t1,8($inp)
        +	xg	$s0,16*$SIZE_T($sp)
        +	xg	$s2,16*$SIZE_T+8($sp)
        +	lghi	$s1,16
        +	sl${g}r	$len,$s1
        +	brc	4,.Lcbc_dec_tail	# if borrow
        +	brc	2,.Lcbc_dec_done	# if zero
        +	stg	$s0,0($out)
        +	stg	$s2,8($out)
        +	stmg	$t0,$t1,16*$SIZE_T($sp)
        +
        +	la	$inp,16($inp)
        +	la	$out,16($out)
        +	j	.Lcbc_dec_loop
        +
        +.Lcbc_dec_done:
        +	stg	$s0,0($out)
        +	stg	$s2,8($out)
        +.Lcbc_dec_exit:
        +	lm${g}	%r6,$ra,6*$SIZE_T($sp)
        +	stmg	$t0,$t1,0($ivp)
        +
        +	br	$ra
        +
        +.align	16
        +.Lcbc_dec_tail:
        +	aghi	$len,15
        +	stg	$s0,16*$SIZE_T($sp)
        +	stg	$s2,16*$SIZE_T+8($sp)
        +	bras	$s1,4f
        +	mvc	0(1,$out),16*$SIZE_T($sp)
        +4:	ex	$len,0($s1)
        +	j	.Lcbc_dec_exit
        +.size	AES_cbc_encrypt,.-AES_cbc_encrypt
        +___
        +}
        +########################################################################
        +# void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
        +#                     size_t blocks, const AES_KEY *key,
        +#                     const unsigned char *ivec)
        +{
        +my $inp="%r2";
        +my $out="%r4";	# blocks and out are swapped
        +my $len="%r3";
        +my $key="%r5";	my $iv0="%r5";
        +my $ivp="%r6";
        +my $fp ="%r7";
        +
        +$code.=<<___;
        +.globl	AES_ctr32_encrypt
        +.type	AES_ctr32_encrypt,\@function
        +.align	16
        +AES_ctr32_encrypt:
        +	xgr	%r3,%r4		# flip %r3 and %r4, $out and $len
        +	xgr	%r4,%r3
        +	xgr	%r3,%r4
        +	llgfr	$len,$len	# safe in ctr32 subroutine even in 64-bit case
        +___
        +$code.=<<___ if (!$softonly);
        +	l	%r0,240($key)
        +	lhi	%r1,16
        +	clr	%r0,%r1
        +	jl	.Lctr32_software
        +
        +	stm${g}	%r6,$s3,6*$SIZE_T($sp)
        +
        +	slgr	$out,$inp
        +	la	%r1,0($key)	# %r1 is permanent copy of $key
        +	lg	$iv0,0($ivp)	# load ivec
        +	lg	$ivp,8($ivp)
        +
        +	# prepare and allocate stack frame at the top of 4K page
        +	# with 1K reserved for eventual signal handling
        +	lghi	$s0,-1024-256-16# guarantee at least 256-bytes buffer
        +	lghi	$s1,-4096
        +	algr	$s0,$sp
        +	lgr	$fp,$sp
        +	ngr	$s0,$s1		# align at page boundary
        +	slgr	$fp,$s0		# total buffer size
        +	lgr	$s2,$sp
        +	lghi	$s1,1024+16	# sl[g]fi is extended-immediate facility
        +	slgr	$fp,$s1		# deduct reservation to get usable buffer size
        +	# buffer size is at lest 256 and at most 3072+256-16
        +
        +	la	$sp,1024($s0)	# alloca
        +	srlg	$fp,$fp,4	# convert bytes to blocks, minimum 16
        +	st${g}	$s2,0($sp)	# back-chain
        +	st${g}	$fp,$SIZE_T($sp)
        +
        +	slgr	$len,$fp
        +	brc	1,.Lctr32_hw_switch	# not zero, no borrow
        +	algr	$fp,$len	# input is shorter than allocated buffer
        +	lghi	$len,0
        +	st${g}	$fp,$SIZE_T($sp)
        +
        +.Lctr32_hw_switch:
        +___
        +$code.=<<___ if (0);	######### kmctr code was measured to be ~12% slower
        +	larl	$s0,OPENSSL_s390xcap_P
        +	lg	$s0,8($s0)
        +	tmhh	$s0,0x0004	# check for message_security-assist-4
        +	jz	.Lctr32_km_loop
        +
        +	llgfr	$s0,%r0
        +	lgr	$s1,%r1
        +	lghi	%r0,0
        +	la	%r1,16($sp)
        +	.long	0xb92d2042	# kmctr %r4,%r2,%r2
        +
        +	llihh	%r0,0x8000	# check if kmctr supports the function code
        +	srlg	%r0,%r0,0($s0)
        +	ng	%r0,16($sp)
        +	lgr	%r0,$s0
        +	lgr	%r1,$s1
        +	jz	.Lctr32_km_loop
        +
        +####### kmctr code
        +	algr	$out,$inp	# restore $out
        +	lgr	$s1,$len	# $s1 undertakes $len
        +	j	.Lctr32_kmctr_loop
        +.align	16
        +.Lctr32_kmctr_loop:
        +	la	$s2,16($sp)
        +	lgr	$s3,$fp
        +.Lctr32_kmctr_prepare:
        +	stg	$iv0,0($s2)
        +	stg	$ivp,8($s2)
        +	la	$s2,16($s2)
        +	ahi	$ivp,1		# 32-bit increment, preserves upper half
        +	brct	$s3,.Lctr32_kmctr_prepare
        +
        +	#la	$inp,0($inp)	# inp
        +	sllg	$len,$fp,4	# len
        +	#la	$out,0($out)	# out
        +	la	$s2,16($sp)	# iv
        +	.long	0xb92da042	# kmctr $out,$s2,$inp
        +	brc	1,.-4		# pay attention to "partial completion"
        +
        +	slgr	$s1,$fp
        +	brc	1,.Lctr32_kmctr_loop	# not zero, no borrow
        +	algr	$fp,$s1
        +	lghi	$s1,0
        +	brc	4+1,.Lctr32_kmctr_loop	# not zero
        +
        +	l${g}	$sp,0($sp)
        +	lm${g}	%r6,$s3,6*$SIZE_T($sp)
        +	br	$ra
        +.align	16
        +___
        +$code.=<<___;
        +.Lctr32_km_loop:
        +	la	$s2,16($sp)
        +	lgr	$s3,$fp
        +.Lctr32_km_prepare:
        +	stg	$iv0,0($s2)
        +	stg	$ivp,8($s2)
        +	la	$s2,16($s2)
        +	ahi	$ivp,1		# 32-bit increment, preserves upper half
        +	brct	$s3,.Lctr32_km_prepare
        +
        +	la	$s0,16($sp)	# inp
        +	sllg	$s1,$fp,4	# len
        +	la	$s2,16($sp)	# out
        +	.long	0xb92e00a8	# km %r10,%r8
        +	brc	1,.-4		# pay attention to "partial completion"
        +
        +	la	$s2,16($sp)
        +	lgr	$s3,$fp
        +	slgr	$s2,$inp
        +.Lctr32_km_xor:
        +	lg	$s0,0($inp)
        +	lg	$s1,8($inp)
        +	xg	$s0,0($s2,$inp)
        +	xg	$s1,8($s2,$inp)
        +	stg	$s0,0($out,$inp)
        +	stg	$s1,8($out,$inp)
        +	la	$inp,16($inp)
        +	brct	$s3,.Lctr32_km_xor
        +
        +	slgr	$len,$fp
        +	brc	1,.Lctr32_km_loop	# not zero, no borrow
        +	algr	$fp,$len
        +	lghi	$len,0
        +	brc	4+1,.Lctr32_km_loop	# not zero
        +
        +	l${g}	$s0,0($sp)
        +	l${g}	$s1,$SIZE_T($sp)
        +	la	$s2,16($sp)
        +.Lctr32_km_zap:
        +	stg	$s0,0($s2)
        +	stg	$s0,8($s2)
        +	la	$s2,16($s2)
        +	brct	$s1,.Lctr32_km_zap
        +
        +	la	$sp,0($s0)
        +	lm${g}	%r6,$s3,6*$SIZE_T($sp)
        +	br	$ra
        +.align	16
        +.Lctr32_software:
        +___
        +$code.=<<___;
        +	stm${g}	$key,$ra,5*$SIZE_T($sp)
        +	sl${g}r	$inp,$out
        +	larl	$tbl,AES_Te
        +	llgf	$t1,12($ivp)
        +
        +.Lctr32_loop:
        +	stm${g}	$inp,$out,2*$SIZE_T($sp)
        +	llgf	$s0,0($ivp)
        +	llgf	$s1,4($ivp)
        +	llgf	$s2,8($ivp)
        +	lgr	$s3,$t1
        +	st	$t1,16*$SIZE_T($sp)
        +	lgr	%r4,$key
        +
        +	bras	$ra,_s390x_AES_encrypt
        +
        +	lm${g}	$inp,$ivp,2*$SIZE_T($sp)
        +	llgf	$t1,16*$SIZE_T($sp)
        +	x	$s0,0($inp,$out)
        +	x	$s1,4($inp,$out)
        +	x	$s2,8($inp,$out)
        +	x	$s3,12($inp,$out)
        +	stm	$s0,$s3,0($out)
        +
        +	la	$out,16($out)
        +	ahi	$t1,1		# 32-bit increment
        +	brct	$len,.Lctr32_loop
        +
        +	lm${g}	%r6,$ra,6*$SIZE_T($sp)
        +	br	$ra
        +.size	AES_ctr32_encrypt,.-AES_ctr32_encrypt
        +___
        +}
        +
        +########################################################################
        +# void AES_xts_encrypt(const char *inp,char *out,size_t len,
        +#	const AES_KEY *key1, const AES_KEY *key2,
        +#	const unsigned char iv[16]);
        +#
        +{
        +my $inp="%r2";
        +my $out="%r4";	# len and out are swapped
        +my $len="%r3";
        +my $key1="%r5";	# $i1
        +my $key2="%r6";	# $i2
        +my $fp="%r7";	# $i3
        +my $tweak=16*$SIZE_T+16;	# or $stdframe-16, bottom of the frame...
        +
        +$code.=<<___;
        +.type	_s390x_xts_km,\@function
        +.align	16
        +_s390x_xts_km:
        +___
        +$code.=<<___ if(1);
        +	llgfr	$s0,%r0			# put aside the function code
        +	lghi	$s1,0x7f
        +	nr	$s1,%r0
        +	lghi	%r0,0			# query capability vector
        +	la	%r1,$tweak-16($sp)
        +	.long	0xb92e0042		# km %r4,%r2
        +	llihh	%r1,0x8000
        +	srlg	%r1,%r1,32($s1)		# check for 32+function code
        +	ng	%r1,$tweak-16($sp)
        +	lgr	%r0,$s0			# restore the function code
        +	la	%r1,0($key1)		# restore $key1
        +	jz	.Lxts_km_vanilla
        +
        +	lmg	$i2,$i3,$tweak($sp)	# put aside the tweak value
        +	algr	$out,$inp
        +
        +	oill	%r0,32			# switch to xts function code
        +	aghi	$s1,-18			#
        +	sllg	$s1,$s1,3		# (function code - 18)*8, 0 or 16
        +	la	%r1,$tweak-16($sp)
        +	slgr	%r1,$s1			# parameter block position
        +	lmg	$s0,$s3,0($key1)	# load 256 bits of key material,
        +	stmg	$s0,$s3,0(%r1)		# and copy it to parameter block.
        +					# yes, it contains junk and overlaps
        +					# with the tweak in 128-bit case.
        +					# it's done to avoid conditional
        +					# branch.
        +	stmg	$i2,$i3,$tweak($sp)	# "re-seat" the tweak value
        +
        +	.long	0xb92e0042		# km %r4,%r2
        +	brc	1,.-4			# pay attention to "partial completion"
        +
        +	lrvg	$s0,$tweak+0($sp)	# load the last tweak
        +	lrvg	$s1,$tweak+8($sp)
        +	stmg	%r0,%r3,$tweak-32($sp)	# wipe copy of the key
        +
        +	nill	%r0,0xffdf		# switch back to original function code
        +	la	%r1,0($key1)		# restore pointer to $key1
        +	slgr	$out,$inp
        +
        +	llgc	$len,2*$SIZE_T-1($sp)
        +	nill	$len,0x0f		# $len%=16
        +	br	$ra
        +	
        +.align	16
        +.Lxts_km_vanilla:
        +___
        +$code.=<<___;
        +	# prepare and allocate stack frame at the top of 4K page
        +	# with 1K reserved for eventual signal handling
        +	lghi	$s0,-1024-256-16# guarantee at least 256-bytes buffer
        +	lghi	$s1,-4096
        +	algr	$s0,$sp
        +	lgr	$fp,$sp
        +	ngr	$s0,$s1		# align at page boundary
        +	slgr	$fp,$s0		# total buffer size
        +	lgr	$s2,$sp
        +	lghi	$s1,1024+16	# sl[g]fi is extended-immediate facility
        +	slgr	$fp,$s1		# deduct reservation to get usable buffer size
        +	# buffer size is at lest 256 and at most 3072+256-16
        +
        +	la	$sp,1024($s0)	# alloca
        +	nill	$fp,0xfff0	# round to 16*n
        +	st${g}	$s2,0($sp)	# back-chain
        +	nill	$len,0xfff0	# redundant
        +	st${g}	$fp,$SIZE_T($sp)
        +
        +	slgr	$len,$fp
        +	brc	1,.Lxts_km_go	# not zero, no borrow
        +	algr	$fp,$len	# input is shorter than allocated buffer
        +	lghi	$len,0
        +	st${g}	$fp,$SIZE_T($sp)
        +
        +.Lxts_km_go:
        +	lrvg	$s0,$tweak+0($s2)	# load the tweak value in little-endian
        +	lrvg	$s1,$tweak+8($s2)
        +
        +	la	$s2,16($sp)		# vector of ascending tweak values
        +	slgr	$s2,$inp
        +	srlg	$s3,$fp,4
        +	j	.Lxts_km_start
        +
        +.Lxts_km_loop:
        +	la	$s2,16($sp)
        +	slgr	$s2,$inp
        +	srlg	$s3,$fp,4
        +.Lxts_km_prepare:
        +	lghi	$i1,0x87
        +	srag	$i2,$s1,63		# broadcast upper bit
        +	ngr	$i1,$i2			# rem
        +	algr	$s0,$s0
        +	alcgr	$s1,$s1
        +	xgr	$s0,$i1
        +.Lxts_km_start:
        +	lrvgr	$i1,$s0			# flip byte order
        +	lrvgr	$i2,$s1
        +	stg	$i1,0($s2,$inp)
        +	stg	$i2,8($s2,$inp)
        +	xg	$i1,0($inp)
        +	xg	$i2,8($inp)
        +	stg	$i1,0($out,$inp)
        +	stg	$i2,8($out,$inp)
        +	la	$inp,16($inp)
        +	brct	$s3,.Lxts_km_prepare
        +
        +	slgr	$inp,$fp		# rewind $inp
        +	la	$s2,0($out,$inp)
        +	lgr	$s3,$fp
        +	.long	0xb92e00aa		# km $s2,$s2
        +	brc	1,.-4			# pay attention to "partial completion"
        +
        +	la	$s2,16($sp)
        +	slgr	$s2,$inp
        +	srlg	$s3,$fp,4
        +.Lxts_km_xor:
        +	lg	$i1,0($out,$inp)
        +	lg	$i2,8($out,$inp)
        +	xg	$i1,0($s2,$inp)
        +	xg	$i2,8($s2,$inp)
        +	stg	$i1,0($out,$inp)
        +	stg	$i2,8($out,$inp)
        +	la	$inp,16($inp)
        +	brct	$s3,.Lxts_km_xor
        +
        +	slgr	$len,$fp
        +	brc	1,.Lxts_km_loop		# not zero, no borrow
        +	algr	$fp,$len
        +	lghi	$len,0
        +	brc	4+1,.Lxts_km_loop	# not zero
        +
        +	l${g}	$i1,0($sp)		# back-chain
        +	llgf	$fp,`2*$SIZE_T-4`($sp)	# bytes used
        +	la	$i2,16($sp)
        +	srlg	$fp,$fp,4
        +.Lxts_km_zap:
        +	stg	$i1,0($i2)
        +	stg	$i1,8($i2)
        +	la	$i2,16($i2)
        +	brct	$fp,.Lxts_km_zap
        +
        +	la	$sp,0($i1)
        +	llgc	$len,2*$SIZE_T-1($i1)
        +	nill	$len,0x0f		# $len%=16
        +	bzr	$ra
        +
        +	# generate one more tweak...
        +	lghi	$i1,0x87
        +	srag	$i2,$s1,63		# broadcast upper bit
        +	ngr	$i1,$i2			# rem
        +	algr	$s0,$s0
        +	alcgr	$s1,$s1
        +	xgr	$s0,$i1
        +
        +	ltr	$len,$len		# clear zero flag
        +	br	$ra
        +.size	_s390x_xts_km,.-_s390x_xts_km
        +
        +.globl	AES_xts_encrypt
        +.type	AES_xts_encrypt,\@function
        +.align	16
        +AES_xts_encrypt:
        +	xgr	%r3,%r4			# flip %r3 and %r4, $out and $len
        +	xgr	%r4,%r3
        +	xgr	%r3,%r4
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	llgfr	$len,$len
        +___
        +$code.=<<___;
        +	st${g}	$len,1*$SIZE_T($sp)	# save copy of $len
        +	srag	$len,$len,4		# formally wrong, because it expands
        +					# sign byte, but who can afford asking
        +					# to process more than 2^63-1 bytes?
        +					# I use it, because it sets condition
        +					# code...
        +	bcr	8,$ra			# abort if zero (i.e. less than 16)
        +___
        +$code.=<<___ if (!$softonly);
        +	llgf	%r0,240($key2)
        +	lhi	%r1,16
        +	clr	%r0,%r1
        +	jl	.Lxts_enc_software
        +
        +	st${g}	$ra,5*$SIZE_T($sp)
        +	stm${g}	%r6,$s3,6*$SIZE_T($sp)
        +
        +	sllg	$len,$len,4		# $len&=~15
        +	slgr	$out,$inp
        +
        +	# generate the tweak value
        +	l${g}	$s3,$stdframe($sp)	# pointer to iv
        +	la	$s2,$tweak($sp)
        +	lmg	$s0,$s1,0($s3)
        +	lghi	$s3,16
        +	stmg	$s0,$s1,0($s2)
        +	la	%r1,0($key2)		# $key2 is not needed anymore
        +	.long	0xb92e00aa		# km $s2,$s2, generate the tweak
        +	brc	1,.-4			# can this happen?
        +
        +	l	%r0,240($key1)
        +	la	%r1,0($key1)		# $key1 is not needed anymore
        +	bras	$ra,_s390x_xts_km
        +	jz	.Lxts_enc_km_done
        +
        +	aghi	$inp,-16		# take one step back
        +	la	$i3,0($out,$inp)	# put aside real $out
        +.Lxts_enc_km_steal:
        +	llgc	$i1,16($inp)
        +	llgc	$i2,0($out,$inp)
        +	stc	$i1,0($out,$inp)
        +	stc	$i2,16($out,$inp)
        +	la	$inp,1($inp)
        +	brct	$len,.Lxts_enc_km_steal
        +
        +	la	$s2,0($i3)
        +	lghi	$s3,16
        +	lrvgr	$i1,$s0			# flip byte order
        +	lrvgr	$i2,$s1
        +	xg	$i1,0($s2)
        +	xg	$i2,8($s2)
        +	stg	$i1,0($s2)
        +	stg	$i2,8($s2)
        +	.long	0xb92e00aa		# km $s2,$s2
        +	brc	1,.-4			# can this happen?
        +	lrvgr	$i1,$s0			# flip byte order
        +	lrvgr	$i2,$s1
        +	xg	$i1,0($i3)
        +	xg	$i2,8($i3)
        +	stg	$i1,0($i3)
        +	stg	$i2,8($i3)
        +
        +.Lxts_enc_km_done:
        +	stg	$sp,$tweak+0($sp)	# wipe tweak
        +	stg	$sp,$tweak+8($sp)
        +	l${g}	$ra,5*$SIZE_T($sp)
        +	lm${g}	%r6,$s3,6*$SIZE_T($sp)
        +	br	$ra
        +.align	16
        +.Lxts_enc_software:
        +___
        +$code.=<<___;
        +	stm${g}	%r6,$ra,6*$SIZE_T($sp)
        +
        +	slgr	$out,$inp
        +
        +	l${g}	$s3,$stdframe($sp)	# ivp
        +	llgf	$s0,0($s3)		# load iv
        +	llgf	$s1,4($s3)
        +	llgf	$s2,8($s3)
        +	llgf	$s3,12($s3)
        +	stm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	la	$key,0($key2)
        +	larl	$tbl,AES_Te
        +	bras	$ra,_s390x_AES_encrypt	# generate the tweak
        +	lm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	stm	$s0,$s3,$tweak($sp)	# save the tweak
        +	j	.Lxts_enc_enter
        +
        +.align	16
        +.Lxts_enc_loop:
        +	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
        +	lrvg	$s3,$tweak+8($sp)
        +	lghi	%r1,0x87
        +	srag	%r0,$s3,63		# broadcast upper bit
        +	ngr	%r1,%r0			# rem
        +	algr	$s1,$s1
        +	alcgr	$s3,$s3
        +	xgr	$s1,%r1
        +	lrvgr	$s1,$s1			# flip byte order
        +	lrvgr	$s3,$s3
        +	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
        +	stg	$s1,$tweak+0($sp)	# save the tweak
        +	llgfr	$s1,$s1
        +	srlg	$s2,$s3,32
        +	stg	$s3,$tweak+8($sp)
        +	llgfr	$s3,$s3
        +	la	$inp,16($inp)		# $inp+=16
        +.Lxts_enc_enter:
        +	x	$s0,0($inp)		# ^=*($inp)
        +	x	$s1,4($inp)
        +	x	$s2,8($inp)
        +	x	$s3,12($inp)
        +	stm${g}	%r2,%r3,2*$SIZE_T($sp)	# only two registers are changing
        +	la	$key,0($key1)
        +	bras	$ra,_s390x_AES_encrypt
        +	lm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	x	$s0,$tweak+0($sp)	# ^=tweak
        +	x	$s1,$tweak+4($sp)
        +	x	$s2,$tweak+8($sp)
        +	x	$s3,$tweak+12($sp)
        +	st	$s0,0($out,$inp)
        +	st	$s1,4($out,$inp)
        +	st	$s2,8($out,$inp)
        +	st	$s3,12($out,$inp)
        +	brct${g}	$len,.Lxts_enc_loop
        +
        +	llgc	$len,`2*$SIZE_T-1`($sp)
        +	nill	$len,0x0f		# $len%16
        +	jz	.Lxts_enc_done
        +
        +	la	$i3,0($inp,$out)	# put aside real $out
        +.Lxts_enc_steal:
        +	llgc	%r0,16($inp)
        +	llgc	%r1,0($out,$inp)
        +	stc	%r0,0($out,$inp)
        +	stc	%r1,16($out,$inp)
        +	la	$inp,1($inp)
        +	brct	$len,.Lxts_enc_steal
        +	la	$out,0($i3)		# restore real $out
        +
        +	# generate last tweak...
        +	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
        +	lrvg	$s3,$tweak+8($sp)
        +	lghi	%r1,0x87
        +	srag	%r0,$s3,63		# broadcast upper bit
        +	ngr	%r1,%r0			# rem
        +	algr	$s1,$s1
        +	alcgr	$s3,$s3
        +	xgr	$s1,%r1
        +	lrvgr	$s1,$s1			# flip byte order
        +	lrvgr	$s3,$s3
        +	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
        +	stg	$s1,$tweak+0($sp)	# save the tweak
        +	llgfr	$s1,$s1
        +	srlg	$s2,$s3,32
        +	stg	$s3,$tweak+8($sp)
        +	llgfr	$s3,$s3
        +
        +	x	$s0,0($out)		# ^=*(inp)|stolen cipther-text
        +	x	$s1,4($out)
        +	x	$s2,8($out)
        +	x	$s3,12($out)
        +	st${g}	$out,4*$SIZE_T($sp)
        +	la	$key,0($key1)
        +	bras	$ra,_s390x_AES_encrypt
        +	l${g}	$out,4*$SIZE_T($sp)
        +	x	$s0,`$tweak+0`($sp)	# ^=tweak
        +	x	$s1,`$tweak+4`($sp)
        +	x	$s2,`$tweak+8`($sp)
        +	x	$s3,`$tweak+12`($sp)
        +	st	$s0,0($out)
        +	st	$s1,4($out)
        +	st	$s2,8($out)
        +	st	$s3,12($out)
        +
        +.Lxts_enc_done:
        +	stg	$sp,$tweak+0($sp)	# wipe tweak
        +	stg	$sp,$twesk+8($sp)
        +	lm${g}	%r6,$ra,6*$SIZE_T($sp)
        +	br	$ra
        +.size	AES_xts_encrypt,.-AES_xts_encrypt
        +___
        +# void AES_xts_decrypt(const char *inp,char *out,size_t len,
        +#	const AES_KEY *key1, const AES_KEY *key2,
        +#	const unsigned char iv[16]);
        +#
        +$code.=<<___;
        +.globl	AES_xts_decrypt
        +.type	AES_xts_decrypt,\@function
        +.align	16
        +AES_xts_decrypt:
        +	xgr	%r3,%r4			# flip %r3 and %r4, $out and $len
        +	xgr	%r4,%r3
        +	xgr	%r3,%r4
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	llgfr	$len,$len
        +___
        +$code.=<<___;
        +	st${g}	$len,1*$SIZE_T($sp)	# save copy of $len
        +	aghi	$len,-16
        +	bcr	4,$ra			# abort if less than zero. formally
        +					# wrong, because $len is unsigned,
        +					# but who can afford asking to
        +					# process more than 2^63-1 bytes?
        +	tmll	$len,0x0f
        +	jnz	.Lxts_dec_proceed
        +	aghi	$len,16
        +.Lxts_dec_proceed:
        +___
        +$code.=<<___ if (!$softonly);
        +	llgf	%r0,240($key2)
        +	lhi	%r1,16
        +	clr	%r0,%r1
        +	jl	.Lxts_dec_software
        +
        +	st${g}	$ra,5*$SIZE_T($sp)
        +	stm${g}	%r6,$s3,6*$SIZE_T($sp)
        +
        +	nill	$len,0xfff0		# $len&=~15
        +	slgr	$out,$inp
        +
        +	# generate the tweak value
        +	l${g}	$s3,$stdframe($sp)	# pointer to iv
        +	la	$s2,$tweak($sp)
        +	lmg	$s0,$s1,0($s3)
        +	lghi	$s3,16
        +	stmg	$s0,$s1,0($s2)
        +	la	%r1,0($key2)		# $key2 is not needed past this point
        +	.long	0xb92e00aa		# km $s2,$s2, generate the tweak
        +	brc	1,.-4			# can this happen?
        +
        +	l	%r0,240($key1)
        +	la	%r1,0($key1)		# $key1 is not needed anymore
        +
        +	ltgr	$len,$len
        +	jz	.Lxts_dec_km_short
        +	bras	$ra,_s390x_xts_km
        +	jz	.Lxts_dec_km_done
        +
        +	lrvgr	$s2,$s0			# make copy in reverse byte order
        +	lrvgr	$s3,$s1
        +	j	.Lxts_dec_km_2ndtweak
        +
        +.Lxts_dec_km_short:
        +	llgc	$len,`2*$SIZE_T-1`($sp)
        +	nill	$len,0x0f		# $len%=16
        +	lrvg	$s0,$tweak+0($sp)	# load the tweak
        +	lrvg	$s1,$tweak+8($sp)
        +	lrvgr	$s2,$s0			# make copy in reverse byte order
        +	lrvgr	$s3,$s1
        +
        +.Lxts_dec_km_2ndtweak:
        +	lghi	$i1,0x87
        +	srag	$i2,$s1,63		# broadcast upper bit
        +	ngr	$i1,$i2			# rem
        +	algr	$s0,$s0
        +	alcgr	$s1,$s1
        +	xgr	$s0,$i1
        +	lrvgr	$i1,$s0			# flip byte order
        +	lrvgr	$i2,$s1
        +
        +	xg	$i1,0($inp)
        +	xg	$i2,8($inp)
        +	stg	$i1,0($out,$inp)
        +	stg	$i2,8($out,$inp)
        +	la	$i2,0($out,$inp)
        +	lghi	$i3,16
        +	.long	0xb92e0066		# km $i2,$i2
        +	brc	1,.-4			# can this happen?
        +	lrvgr	$i1,$s0
        +	lrvgr	$i2,$s1
        +	xg	$i1,0($out,$inp)
        +	xg	$i2,8($out,$inp)
        +	stg	$i1,0($out,$inp)
        +	stg	$i2,8($out,$inp)
        +
        +	la	$i3,0($out,$inp)	# put aside real $out
        +.Lxts_dec_km_steal:
        +	llgc	$i1,16($inp)
        +	llgc	$i2,0($out,$inp)
        +	stc	$i1,0($out,$inp)
        +	stc	$i2,16($out,$inp)
        +	la	$inp,1($inp)
        +	brct	$len,.Lxts_dec_km_steal
        +
        +	lgr	$s0,$s2
        +	lgr	$s1,$s3
        +	xg	$s0,0($i3)
        +	xg	$s1,8($i3)
        +	stg	$s0,0($i3)
        +	stg	$s1,8($i3)
        +	la	$s0,0($i3)
        +	lghi	$s1,16
        +	.long	0xb92e0088		# km $s0,$s0
        +	brc	1,.-4			# can this happen?
        +	xg	$s2,0($i3)
        +	xg	$s3,8($i3)
        +	stg	$s2,0($i3)
        +	stg	$s3,8($i3)
        +.Lxts_dec_km_done:
        +	stg	$sp,$tweak+0($sp)	# wipe tweak
        +	stg	$sp,$tweak+8($sp)
        +	l${g}	$ra,5*$SIZE_T($sp)
        +	lm${g}	%r6,$s3,6*$SIZE_T($sp)
        +	br	$ra
        +.align	16
        +.Lxts_dec_software:
        +___
        +$code.=<<___;
        +	stm${g}	%r6,$ra,6*$SIZE_T($sp)
        +
        +	srlg	$len,$len,4
        +	slgr	$out,$inp
        +
        +	l${g}	$s3,$stdframe($sp)	# ivp
        +	llgf	$s0,0($s3)		# load iv
        +	llgf	$s1,4($s3)
        +	llgf	$s2,8($s3)
        +	llgf	$s3,12($s3)
        +	stm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	la	$key,0($key2)
        +	larl	$tbl,AES_Te
        +	bras	$ra,_s390x_AES_encrypt	# generate the tweak
        +	lm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	larl	$tbl,AES_Td
        +	lt${g}r	$len,$len
        +	stm	$s0,$s3,$tweak($sp)	# save the tweak
        +	jz	.Lxts_dec_short
        +	j	.Lxts_dec_enter
        +
        +.align	16
        +.Lxts_dec_loop:
        +	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
        +	lrvg	$s3,$tweak+8($sp)
        +	lghi	%r1,0x87
        +	srag	%r0,$s3,63		# broadcast upper bit
        +	ngr	%r1,%r0			# rem
        +	algr	$s1,$s1
        +	alcgr	$s3,$s3
        +	xgr	$s1,%r1
        +	lrvgr	$s1,$s1			# flip byte order
        +	lrvgr	$s3,$s3
        +	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
        +	stg	$s1,$tweak+0($sp)	# save the tweak
        +	llgfr	$s1,$s1
        +	srlg	$s2,$s3,32
        +	stg	$s3,$tweak+8($sp)
        +	llgfr	$s3,$s3
        +.Lxts_dec_enter:
        +	x	$s0,0($inp)		# tweak^=*(inp)
        +	x	$s1,4($inp)
        +	x	$s2,8($inp)
        +	x	$s3,12($inp)
        +	stm${g}	%r2,%r3,2*$SIZE_T($sp)	# only two registers are changing
        +	la	$key,0($key1)
        +	bras	$ra,_s390x_AES_decrypt
        +	lm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	x	$s0,$tweak+0($sp)	# ^=tweak
        +	x	$s1,$tweak+4($sp)
        +	x	$s2,$tweak+8($sp)
        +	x	$s3,$tweak+12($sp)
        +	st	$s0,0($out,$inp)
        +	st	$s1,4($out,$inp)
        +	st	$s2,8($out,$inp)
        +	st	$s3,12($out,$inp)
        +	la	$inp,16($inp)
        +	brct${g}	$len,.Lxts_dec_loop
        +
        +	llgc	$len,`2*$SIZE_T-1`($sp)
        +	nill	$len,0x0f		# $len%16
        +	jz	.Lxts_dec_done
        +
        +	# generate pair of tweaks...
        +	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
        +	lrvg	$s3,$tweak+8($sp)
        +	lghi	%r1,0x87
        +	srag	%r0,$s3,63		# broadcast upper bit
        +	ngr	%r1,%r0			# rem
        +	algr	$s1,$s1
        +	alcgr	$s3,$s3
        +	xgr	$s1,%r1
        +	lrvgr	$i2,$s1			# flip byte order
        +	lrvgr	$i3,$s3
        +	stmg	$i2,$i3,$tweak($sp)	# save the 1st tweak
        +	j	.Lxts_dec_2ndtweak
        +
        +.align	16
        +.Lxts_dec_short:
        +	llgc	$len,`2*$SIZE_T-1`($sp)
        +	nill	$len,0x0f		# $len%16
        +	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
        +	lrvg	$s3,$tweak+8($sp)
        +.Lxts_dec_2ndtweak:
        +	lghi	%r1,0x87
        +	srag	%r0,$s3,63		# broadcast upper bit
        +	ngr	%r1,%r0			# rem
        +	algr	$s1,$s1
        +	alcgr	$s3,$s3
        +	xgr	$s1,%r1
        +	lrvgr	$s1,$s1			# flip byte order
        +	lrvgr	$s3,$s3
        +	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits
        +	stg	$s1,$tweak-16+0($sp)	# save the 2nd tweak
        +	llgfr	$s1,$s1
        +	srlg	$s2,$s3,32
        +	stg	$s3,$tweak-16+8($sp)
        +	llgfr	$s3,$s3
        +
        +	x	$s0,0($inp)		# tweak_the_2nd^=*(inp)
        +	x	$s1,4($inp)
        +	x	$s2,8($inp)
        +	x	$s3,12($inp)
        +	stm${g}	%r2,%r3,2*$SIZE_T($sp)
        +	la	$key,0($key1)
        +	bras	$ra,_s390x_AES_decrypt
        +	lm${g}	%r2,%r5,2*$SIZE_T($sp)
        +	x	$s0,$tweak-16+0($sp)	# ^=tweak_the_2nd
        +	x	$s1,$tweak-16+4($sp)
        +	x	$s2,$tweak-16+8($sp)
        +	x	$s3,$tweak-16+12($sp)
        +	st	$s0,0($out,$inp)
        +	st	$s1,4($out,$inp)
        +	st	$s2,8($out,$inp)
        +	st	$s3,12($out,$inp)
        +
        +	la	$i3,0($out,$inp)	# put aside real $out
        +.Lxts_dec_steal:
        +	llgc	%r0,16($inp)
        +	llgc	%r1,0($out,$inp)
        +	stc	%r0,0($out,$inp)
        +	stc	%r1,16($out,$inp)
        +	la	$inp,1($inp)
        +	brct	$len,.Lxts_dec_steal
        +	la	$out,0($i3)		# restore real $out
        +
        +	lm	$s0,$s3,$tweak($sp)	# load the 1st tweak
        +	x	$s0,0($out)		# tweak^=*(inp)|stolen cipher-text
        +	x	$s1,4($out)
        +	x	$s2,8($out)
        +	x	$s3,12($out)
        +	st${g}	$out,4*$SIZE_T($sp)
        +	la	$key,0($key1)
        +	bras	$ra,_s390x_AES_decrypt
        +	l${g}	$out,4*$SIZE_T($sp)
        +	x	$s0,$tweak+0($sp)	# ^=tweak
        +	x	$s1,$tweak+4($sp)
        +	x	$s2,$tweak+8($sp)
        +	x	$s3,$tweak+12($sp)
        +	st	$s0,0($out)
        +	st	$s1,4($out)
        +	st	$s2,8($out)
        +	st	$s3,12($out)
        +	stg	$sp,$tweak-16+0($sp)	# wipe 2nd tweak
        +	stg	$sp,$tweak-16+8($sp)
        +.Lxts_dec_done:
        +	stg	$sp,$tweak+0($sp)	# wipe tweak
        +	stg	$sp,$twesk+8($sp)
        +	lm${g}	%r6,$ra,6*$SIZE_T($sp)
        +	br	$ra
        +.size	AES_xts_decrypt,.-AES_xts_decrypt
        +___
        +}
        +$code.=<<___;
        +.string	"AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +.comm	OPENSSL_s390xcap_P,16,8
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;	# force flush
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl
        new file mode 100644
        index 000000000..403c4d129
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-sparcv9.pl
        @@ -0,0 +1,1182 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. Rights for redistribution and usage in source and binary
        +# forms are granted according to the OpenSSL license.
        +# ====================================================================
        +#
        +# Version 1.1
        +#
        +# The major reason for undertaken effort was to mitigate the hazard of
        +# cache-timing attack. This is [currently and initially!] addressed in
        +# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each.
        +# 2. References to them are scheduled for L2 cache latency, meaning
        +# that the tables don't have to reside in L1 cache. Once again, this
        +# is an initial draft and one should expect more countermeasures to
        +# be implemented...
        +#
        +# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last
        +# round.
        +#
        +# Even though performance was not the primary goal [on the contrary,
        +# extra shifts "induced" by compressed S-box and longer loop epilogue
        +# "induced" by scheduling for L2 have negative effect on performance],
        +# the code turned out to run in ~23 cycles per processed byte en-/
        +# decrypted with 128-bit key. This is pretty good result for code
        +# with mentioned qualities and UltraSPARC core. Compared to Sun C
        +# generated code my encrypt procedure runs just few percents faster,
        +# while decrypt one - whole 50% faster [yes, Sun C failed to generate
        +# optimal decrypt procedure]. Compared to GNU C generated code both
        +# procedures are more than 60% faster:-)
        +
        +$bits=32;
        +for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +if ($bits==64)	{ $bias=2047; $frame=192; }
        +else		{ $bias=0;    $frame=112; }
        +$locals=16;
        +
        +$acc0="%l0";
        +$acc1="%o0";
        +$acc2="%o1";
        +$acc3="%o2";
        +
        +$acc4="%l1";
        +$acc5="%o3";
        +$acc6="%o4";
        +$acc7="%o5";
        +
        +$acc8="%l2";
        +$acc9="%o7";
        +$acc10="%g1";
        +$acc11="%g2";
        +
        +$acc12="%l3";
        +$acc13="%g3";
        +$acc14="%g4";
        +$acc15="%g5";
        +
        +$t0="%l4";
        +$t1="%l5";
        +$t2="%l6";
        +$t3="%l7";
        +
        +$s0="%i0";
        +$s1="%i1";
        +$s2="%i2";
        +$s3="%i3";
        +$tbl="%i4";
        +$key="%i5";
        +$rounds="%i7";	# aliases with return address, which is off-loaded to stack
        +
        +sub _data_word()
        +{ my $i;
        +    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
        +}
        +
        +$code.=<<___ if ($bits==64);
        +.register	%g2,#scratch
        +.register	%g3,#scratch
        +___
        +$code.=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.align	256
        +AES_Te:
        +___
        +&_data_word(
        +	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
        +	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
        +	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
        +	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
        +	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
        +	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
        +	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
        +	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
        +	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
        +	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
        +	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
        +	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
        +	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
        +	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
        +	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
        +	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
        +	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
        +	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
        +	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
        +	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
        +	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
        +	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
        +	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
        +	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
        +	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
        +	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
        +	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
        +	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
        +	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
        +	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
        +	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
        +	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
        +	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
        +	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
        +	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
        +	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
        +	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
        +	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
        +	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
        +	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
        +	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
        +	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
        +	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
        +	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
        +	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
        +	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
        +	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
        +	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
        +	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
        +	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
        +	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
        +	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
        +	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
        +	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
        +	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
        +	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
        +	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
        +	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
        +	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
        +	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
        +	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
        +	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
        +	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
        +	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
        +$code.=<<___;
        +	.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
        +	.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
        +	.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
        +	.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
        +	.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
        +	.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
        +	.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
        +	.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
        +	.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
        +	.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
        +	.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
        +	.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
        +	.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
        +	.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
        +	.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
        +	.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
        +	.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
        +	.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
        +	.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
        +	.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
        +	.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
        +	.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
        +	.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
        +	.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
        +	.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
        +	.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
        +	.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
        +	.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
        +	.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
        +	.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
        +	.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
        +	.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
        +.type	AES_Te,#object
        +.size	AES_Te,(.-AES_Te)
        +
        +.align	64
        +.skip	16
        +_sparcv9_AES_encrypt:
        +	save	%sp,-$frame-$locals,%sp
        +	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
        +	ld	[$key+240],$rounds
        +	ld	[$key+0],$t0
        +	ld	[$key+4],$t1			!
        +	ld	[$key+8],$t2
        +	srl	$rounds,1,$rounds
        +	xor	$t0,$s0,$s0
        +	ld	[$key+12],$t3
        +	srl	$s0,21,$acc0
        +	xor	$t1,$s1,$s1
        +	ld	[$key+16],$t0
        +	srl	$s1,13,$acc1			!
        +	xor	$t2,$s2,$s2
        +	ld	[$key+20],$t1
        +	xor	$t3,$s3,$s3
        +	ld	[$key+24],$t2
        +	and	$acc0,2040,$acc0
        +	ld	[$key+28],$t3
        +	nop
        +.Lenc_loop:
        +	srl	$s2,5,$acc2			!
        +	and	$acc1,2040,$acc1
        +	ldx	[$tbl+$acc0],$acc0
        +	sll	$s3,3,$acc3
        +	and	$acc2,2040,$acc2
        +	ldx	[$tbl+$acc1],$acc1
        +	srl	$s1,21,$acc4
        +	and	$acc3,2040,$acc3
        +	ldx	[$tbl+$acc2],$acc2		!
        +	srl	$s2,13,$acc5
        +	and	$acc4,2040,$acc4
        +	ldx	[$tbl+$acc3],$acc3
        +	srl	$s3,5,$acc6
        +	and	$acc5,2040,$acc5
        +	ldx	[$tbl+$acc4],$acc4
        +	fmovs	%f0,%f0
        +	sll	$s0,3,$acc7			!
        +	and	$acc6,2040,$acc6
        +	ldx	[$tbl+$acc5],$acc5
        +	srl	$s2,21,$acc8
        +	and	$acc7,2040,$acc7
        +	ldx	[$tbl+$acc6],$acc6
        +	srl	$s3,13,$acc9
        +	and	$acc8,2040,$acc8
        +	ldx	[$tbl+$acc7],$acc7		!
        +	srl	$s0,5,$acc10
        +	and	$acc9,2040,$acc9
        +	ldx	[$tbl+$acc8],$acc8
        +	sll	$s1,3,$acc11
        +	and	$acc10,2040,$acc10
        +	ldx	[$tbl+$acc9],$acc9
        +	fmovs	%f0,%f0
        +	srl	$s3,21,$acc12			!
        +	and	$acc11,2040,$acc11
        +	ldx	[$tbl+$acc10],$acc10
        +	srl	$s0,13,$acc13
        +	and	$acc12,2040,$acc12
        +	ldx	[$tbl+$acc11],$acc11
        +	srl	$s1,5,$acc14
        +	and	$acc13,2040,$acc13
        +	ldx	[$tbl+$acc12],$acc12		!
        +	sll	$s2,3,$acc15
        +	and	$acc14,2040,$acc14
        +	ldx	[$tbl+$acc13],$acc13
        +	and	$acc15,2040,$acc15
        +	add	$key,32,$key
        +	ldx	[$tbl+$acc14],$acc14
        +	fmovs	%f0,%f0
        +	subcc	$rounds,1,$rounds		!
        +	ldx	[$tbl+$acc15],$acc15
        +	bz,a,pn	%icc,.Lenc_last
        +	add	$tbl,2048,$rounds
        +
        +		srlx	$acc1,8,$acc1
        +		xor	$acc0,$t0,$t0
        +	ld	[$key+0],$s0
        +	fmovs	%f0,%f0
        +		srlx	$acc2,16,$acc2		!
        +		xor	$acc1,$t0,$t0
        +	ld	[$key+4],$s1
        +		srlx	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ld	[$key+8],$s2
        +		srlx	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ld	[$key+12],$s3			!
        +		srlx	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +	fmovs	%f0,%f0
        +		srlx	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		srlx	$acc9,8,$acc9
        +		xor	$acc6,$t1,$t1
        +		srlx	$acc10,16,$acc10	!
        +		xor	$acc7,$t1,$t1
        +		srlx	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		srlx	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		srlx	$acc14,16,$acc14
        +		xor	$acc10,$t2,$t2
        +		srlx	$acc15,24,$acc15	!
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	srl	$t0,21,$acc0
        +		xor	$acc14,$t3,$t3
        +	srl	$t1,13,$acc1
        +		xor	$acc15,$t3,$t3
        +
        +	and	$acc0,2040,$acc0		!
        +	srl	$t2,5,$acc2
        +	and	$acc1,2040,$acc1
        +	ldx	[$tbl+$acc0],$acc0
        +	sll	$t3,3,$acc3
        +	and	$acc2,2040,$acc2
        +	ldx	[$tbl+$acc1],$acc1
        +	fmovs	%f0,%f0
        +	srl	$t1,21,$acc4			!
        +	and	$acc3,2040,$acc3
        +	ldx	[$tbl+$acc2],$acc2
        +	srl	$t2,13,$acc5
        +	and	$acc4,2040,$acc4
        +	ldx	[$tbl+$acc3],$acc3
        +	srl	$t3,5,$acc6
        +	and	$acc5,2040,$acc5
        +	ldx	[$tbl+$acc4],$acc4		!
        +	sll	$t0,3,$acc7
        +	and	$acc6,2040,$acc6
        +	ldx	[$tbl+$acc5],$acc5
        +	srl	$t2,21,$acc8
        +	and	$acc7,2040,$acc7
        +	ldx	[$tbl+$acc6],$acc6
        +	fmovs	%f0,%f0
        +	srl	$t3,13,$acc9			!
        +	and	$acc8,2040,$acc8
        +	ldx	[$tbl+$acc7],$acc7
        +	srl	$t0,5,$acc10
        +	and	$acc9,2040,$acc9
        +	ldx	[$tbl+$acc8],$acc8
        +	sll	$t1,3,$acc11
        +	and	$acc10,2040,$acc10
        +	ldx	[$tbl+$acc9],$acc9		!
        +	srl	$t3,21,$acc12
        +	and	$acc11,2040,$acc11
        +	ldx	[$tbl+$acc10],$acc10
        +	srl	$t0,13,$acc13
        +	and	$acc12,2040,$acc12
        +	ldx	[$tbl+$acc11],$acc11
        +	fmovs	%f0,%f0
        +	srl	$t1,5,$acc14			!
        +	and	$acc13,2040,$acc13
        +	ldx	[$tbl+$acc12],$acc12
        +	sll	$t2,3,$acc15
        +	and	$acc14,2040,$acc14
        +	ldx	[$tbl+$acc13],$acc13
        +		srlx	$acc1,8,$acc1
        +	and	$acc15,2040,$acc15
        +	ldx	[$tbl+$acc14],$acc14		!
        +
        +		srlx	$acc2,16,$acc2
        +		xor	$acc0,$s0,$s0
        +	ldx	[$tbl+$acc15],$acc15
        +		srlx	$acc3,24,$acc3
        +		xor	$acc1,$s0,$s0
        +	ld	[$key+16],$t0
        +	fmovs	%f0,%f0
        +		srlx	$acc5,8,$acc5		!
        +		xor	$acc2,$s0,$s0
        +	ld	[$key+20],$t1
        +		srlx	$acc6,16,$acc6
        +		xor	$acc3,$s0,$s0
        +	ld	[$key+24],$t2
        +		srlx	$acc7,24,$acc7
        +		xor	$acc4,$s1,$s1
        +	ld	[$key+28],$t3			!
        +		srlx	$acc9,8,$acc9
        +		xor	$acc5,$s1,$s1
        +	ldx	[$tbl+2048+0],%g0		! prefetch te4
        +		srlx	$acc10,16,$acc10
        +		xor	$acc6,$s1,$s1
        +	ldx	[$tbl+2048+32],%g0		! prefetch te4
        +		srlx	$acc11,24,$acc11
        +		xor	$acc7,$s1,$s1
        +	ldx	[$tbl+2048+64],%g0		! prefetch te4
        +		srlx	$acc13,8,$acc13
        +		xor	$acc8,$s2,$s2
        +	ldx	[$tbl+2048+96],%g0		! prefetch te4
        +		srlx	$acc14,16,$acc14	!
        +		xor	$acc9,$s2,$s2
        +	ldx	[$tbl+2048+128],%g0		! prefetch te4
        +		srlx	$acc15,24,$acc15
        +		xor	$acc10,$s2,$s2
        +	ldx	[$tbl+2048+160],%g0		! prefetch te4
        +	srl	$s0,21,$acc0
        +		xor	$acc11,$s2,$s2
        +	ldx	[$tbl+2048+192],%g0		! prefetch te4
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$s3,$s3
        +	ldx	[$tbl+2048+224],%g0		! prefetch te4
        +	srl	$s1,13,$acc1			!
        +		xor	$acc14,$s3,$s3
        +		xor	$acc15,$s3,$s3
        +	ba	.Lenc_loop
        +	and	$acc0,2040,$acc0
        +
        +.align	32
        +.Lenc_last:
        +		srlx	$acc1,8,$acc1		!
        +		xor	$acc0,$t0,$t0
        +	ld	[$key+0],$s0
        +		srlx	$acc2,16,$acc2
        +		xor	$acc1,$t0,$t0
        +	ld	[$key+4],$s1
        +		srlx	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ld	[$key+8],$s2			!
        +		srlx	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ld	[$key+12],$s3
        +		srlx	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +		srlx	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		srlx	$acc9,8,$acc9		!
        +		xor	$acc6,$t1,$t1
        +		srlx	$acc10,16,$acc10
        +		xor	$acc7,$t1,$t1
        +		srlx	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		srlx	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		srlx	$acc14,16,$acc14	!
        +		xor	$acc10,$t2,$t2
        +		srlx	$acc15,24,$acc15
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	srl	$t0,24,$acc0
        +		xor	$acc14,$t3,$t3
        +	srl	$t1,16,$acc1			!
        +		xor	$acc15,$t3,$t3
        +
        +	srl	$t2,8,$acc2
        +	and	$acc1,255,$acc1
        +	ldub	[$rounds+$acc0],$acc0
        +	srl	$t1,24,$acc4
        +	and	$acc2,255,$acc2
        +	ldub	[$rounds+$acc1],$acc1
        +	srl	$t2,16,$acc5			!
        +	and	$t3,255,$acc3
        +	ldub	[$rounds+$acc2],$acc2
        +	ldub	[$rounds+$acc3],$acc3
        +	srl	$t3,8,$acc6
        +	and	$acc5,255,$acc5
        +	ldub	[$rounds+$acc4],$acc4
        +	fmovs	%f0,%f0
        +	srl	$t2,24,$acc8			!
        +	and	$acc6,255,$acc6
        +	ldub	[$rounds+$acc5],$acc5
        +	srl	$t3,16,$acc9
        +	and	$t0,255,$acc7
        +	ldub	[$rounds+$acc6],$acc6
        +	ldub	[$rounds+$acc7],$acc7
        +	fmovs	%f0,%f0
        +	srl	$t0,8,$acc10			!
        +	and	$acc9,255,$acc9
        +	ldub	[$rounds+$acc8],$acc8
        +	srl	$t3,24,$acc12
        +	and	$acc10,255,$acc10
        +	ldub	[$rounds+$acc9],$acc9
        +	srl	$t0,16,$acc13
        +	and	$t1,255,$acc11
        +	ldub	[$rounds+$acc10],$acc10		!
        +	srl	$t1,8,$acc14
        +	and	$acc13,255,$acc13
        +	ldub	[$rounds+$acc11],$acc11
        +	ldub	[$rounds+$acc12],$acc12
        +	and	$acc14,255,$acc14
        +	ldub	[$rounds+$acc13],$acc13
        +	and	$t2,255,$acc15
        +	ldub	[$rounds+$acc14],$acc14		!
        +
        +		sll	$acc0,24,$acc0
        +		xor	$acc3,$s0,$s0
        +	ldub	[$rounds+$acc15],$acc15
        +		sll	$acc1,16,$acc1
        +		xor	$acc0,$s0,$s0
        +	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
        +	fmovs	%f0,%f0
        +		sll	$acc2,8,$acc2		!
        +		xor	$acc1,$s0,$s0
        +		sll	$acc4,24,$acc4
        +		xor	$acc2,$s0,$s0
        +		sll	$acc5,16,$acc5
        +		xor	$acc7,$s1,$s1
        +		sll	$acc6,8,$acc6
        +		xor	$acc4,$s1,$s1
        +		sll	$acc8,24,$acc8		!
        +		xor	$acc5,$s1,$s1
        +		sll	$acc9,16,$acc9
        +		xor	$acc11,$s2,$s2
        +		sll	$acc10,8,$acc10
        +		xor	$acc6,$s1,$s1
        +		sll	$acc12,24,$acc12
        +		xor	$acc8,$s2,$s2
        +		sll	$acc13,16,$acc13	!
        +		xor	$acc9,$s2,$s2
        +		sll	$acc14,8,$acc14
        +		xor	$acc10,$s2,$s2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$s3,$s3
        +		xor	$acc14,$s3,$s3
        +		xor	$acc15,$s3,$s3
        +
        +	ret
        +	restore
        +.type	_sparcv9_AES_encrypt,#function
        +.size	_sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt)
        +
        +.align	32
        +.globl	AES_encrypt
        +AES_encrypt:
        +	or	%o0,%o1,%g1
        +	andcc	%g1,3,%g0
        +	bnz,pn	%xcc,.Lunaligned_enc
        +	save	%sp,-$frame,%sp
        +
        +	ld	[%i0+0],%o0
        +	ld	[%i0+4],%o1
        +	ld	[%i0+8],%o2
        +	ld	[%i0+12],%o3
        +
        +1:	call	.+8
        +	add	%o7,AES_Te-1b,%o4
        +	call	_sparcv9_AES_encrypt
        +	mov	%i2,%o5
        +
        +	st	%o0,[%i1+0]
        +	st	%o1,[%i1+4]
        +	st	%o2,[%i1+8]
        +	st	%o3,[%i1+12]
        +
        +	ret
        +	restore
        +
        +.align	32
        +.Lunaligned_enc:
        +	ldub	[%i0+0],%l0
        +	ldub	[%i0+1],%l1
        +	ldub	[%i0+2],%l2
        +
        +	sll	%l0,24,%l0
        +	ldub	[%i0+3],%l3
        +	sll	%l1,16,%l1
        +	ldub	[%i0+4],%l4
        +	sll	%l2,8,%l2
        +	or	%l1,%l0,%l0
        +	ldub	[%i0+5],%l5
        +	sll	%l4,24,%l4
        +	or	%l3,%l2,%l2
        +	ldub	[%i0+6],%l6
        +	sll	%l5,16,%l5
        +	or	%l0,%l2,%o0
        +	ldub	[%i0+7],%l7
        +
        +	sll	%l6,8,%l6
        +	or	%l5,%l4,%l4
        +	ldub	[%i0+8],%l0
        +	or	%l7,%l6,%l6
        +	ldub	[%i0+9],%l1
        +	or	%l4,%l6,%o1
        +	ldub	[%i0+10],%l2
        +
        +	sll	%l0,24,%l0
        +	ldub	[%i0+11],%l3
        +	sll	%l1,16,%l1
        +	ldub	[%i0+12],%l4
        +	sll	%l2,8,%l2
        +	or	%l1,%l0,%l0
        +	ldub	[%i0+13],%l5
        +	sll	%l4,24,%l4
        +	or	%l3,%l2,%l2
        +	ldub	[%i0+14],%l6
        +	sll	%l5,16,%l5
        +	or	%l0,%l2,%o2
        +	ldub	[%i0+15],%l7
        +
        +	sll	%l6,8,%l6
        +	or	%l5,%l4,%l4
        +	or	%l7,%l6,%l6
        +	or	%l4,%l6,%o3
        +
        +1:	call	.+8
        +	add	%o7,AES_Te-1b,%o4
        +	call	_sparcv9_AES_encrypt
        +	mov	%i2,%o5
        +
        +	srl	%o0,24,%l0
        +	srl	%o0,16,%l1
        +	stb	%l0,[%i1+0]
        +	srl	%o0,8,%l2
        +	stb	%l1,[%i1+1]
        +	stb	%l2,[%i1+2]
        +	srl	%o1,24,%l4
        +	stb	%o0,[%i1+3]
        +
        +	srl	%o1,16,%l5
        +	stb	%l4,[%i1+4]
        +	srl	%o1,8,%l6
        +	stb	%l5,[%i1+5]
        +	stb	%l6,[%i1+6]
        +	srl	%o2,24,%l0
        +	stb	%o1,[%i1+7]
        +
        +	srl	%o2,16,%l1
        +	stb	%l0,[%i1+8]
        +	srl	%o2,8,%l2
        +	stb	%l1,[%i1+9]
        +	stb	%l2,[%i1+10]
        +	srl	%o3,24,%l4
        +	stb	%o2,[%i1+11]
        +
        +	srl	%o3,16,%l5
        +	stb	%l4,[%i1+12]
        +	srl	%o3,8,%l6
        +	stb	%l5,[%i1+13]
        +	stb	%l6,[%i1+14]
        +	stb	%o3,[%i1+15]
        +
        +	ret
        +	restore
        +.type	AES_encrypt,#function
        +.size	AES_encrypt,(.-AES_encrypt)
        +
        +___
        +
        +$code.=<<___;
        +.align	256
        +AES_Td:
        +___
        +&_data_word(
        +	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
        +	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
        +	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
        +	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
        +	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
        +	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
        +	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
        +	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
        +	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
        +	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
        +	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
        +	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
        +	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
        +	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
        +	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
        +	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
        +	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
        +	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
        +	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
        +	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
        +	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
        +	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
        +	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
        +	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
        +	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
        +	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
        +	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
        +	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
        +	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
        +	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
        +	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
        +	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
        +	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
        +	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
        +	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
        +	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
        +	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
        +	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
        +	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
        +	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
        +	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
        +	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
        +	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
        +	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
        +	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
        +	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
        +	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
        +	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
        +	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
        +	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
        +	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
        +	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
        +	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
        +	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
        +	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
        +	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
        +	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
        +	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
        +	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
        +	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
        +	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
        +	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
        +	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
        +	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
        +$code.=<<___;
        +	.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
        +	.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        +	.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
        +	.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        +	.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
        +	.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        +	.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
        +	.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        +	.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
        +	.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        +	.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
        +	.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        +	.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
        +	.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        +	.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
        +	.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        +	.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
        +	.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        +	.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
        +	.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        +	.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
        +	.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        +	.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
        +	.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        +	.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
        +	.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        +	.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
        +	.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        +	.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
        +	.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        +	.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
        +	.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
        +.type	AES_Td,#object
        +.size	AES_Td,(.-AES_Td)
        +
        +.align	64
        +.skip	16
        +_sparcv9_AES_decrypt:
        +	save	%sp,-$frame-$locals,%sp
        +	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
        +	ld	[$key+240],$rounds
        +	ld	[$key+0],$t0
        +	ld	[$key+4],$t1			!
        +	ld	[$key+8],$t2
        +	ld	[$key+12],$t3
        +	srl	$rounds,1,$rounds
        +	xor	$t0,$s0,$s0
        +	ld	[$key+16],$t0
        +	xor	$t1,$s1,$s1
        +	ld	[$key+20],$t1
        +	srl	$s0,21,$acc0			!
        +	xor	$t2,$s2,$s2
        +	ld	[$key+24],$t2
        +	xor	$t3,$s3,$s3
        +	and	$acc0,2040,$acc0
        +	ld	[$key+28],$t3
        +	srl	$s3,13,$acc1
        +	nop
        +.Ldec_loop:
        +	srl	$s2,5,$acc2			!
        +	and	$acc1,2040,$acc1
        +	ldx	[$tbl+$acc0],$acc0
        +	sll	$s1,3,$acc3
        +	and	$acc2,2040,$acc2
        +	ldx	[$tbl+$acc1],$acc1
        +	srl	$s1,21,$acc4
        +	and	$acc3,2040,$acc3
        +	ldx	[$tbl+$acc2],$acc2		!
        +	srl	$s0,13,$acc5
        +	and	$acc4,2040,$acc4
        +	ldx	[$tbl+$acc3],$acc3
        +	srl	$s3,5,$acc6
        +	and	$acc5,2040,$acc5
        +	ldx	[$tbl+$acc4],$acc4
        +	fmovs	%f0,%f0
        +	sll	$s2,3,$acc7			!
        +	and	$acc6,2040,$acc6
        +	ldx	[$tbl+$acc5],$acc5
        +	srl	$s2,21,$acc8
        +	and	$acc7,2040,$acc7
        +	ldx	[$tbl+$acc6],$acc6
        +	srl	$s1,13,$acc9
        +	and	$acc8,2040,$acc8
        +	ldx	[$tbl+$acc7],$acc7		!
        +	srl	$s0,5,$acc10
        +	and	$acc9,2040,$acc9
        +	ldx	[$tbl+$acc8],$acc8
        +	sll	$s3,3,$acc11
        +	and	$acc10,2040,$acc10
        +	ldx	[$tbl+$acc9],$acc9
        +	fmovs	%f0,%f0
        +	srl	$s3,21,$acc12			!
        +	and	$acc11,2040,$acc11
        +	ldx	[$tbl+$acc10],$acc10
        +	srl	$s2,13,$acc13
        +	and	$acc12,2040,$acc12
        +	ldx	[$tbl+$acc11],$acc11
        +	srl	$s1,5,$acc14
        +	and	$acc13,2040,$acc13
        +	ldx	[$tbl+$acc12],$acc12		!
        +	sll	$s0,3,$acc15
        +	and	$acc14,2040,$acc14
        +	ldx	[$tbl+$acc13],$acc13
        +	and	$acc15,2040,$acc15
        +	add	$key,32,$key
        +	ldx	[$tbl+$acc14],$acc14
        +	fmovs	%f0,%f0
        +	subcc	$rounds,1,$rounds		!
        +	ldx	[$tbl+$acc15],$acc15
        +	bz,a,pn	%icc,.Ldec_last
        +	add	$tbl,2048,$rounds
        +
        +		srlx	$acc1,8,$acc1
        +		xor	$acc0,$t0,$t0
        +	ld	[$key+0],$s0
        +	fmovs	%f0,%f0
        +		srlx	$acc2,16,$acc2		!
        +		xor	$acc1,$t0,$t0
        +	ld	[$key+4],$s1
        +		srlx	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ld	[$key+8],$s2
        +		srlx	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ld	[$key+12],$s3			!
        +		srlx	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +	fmovs	%f0,%f0
        +		srlx	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		srlx	$acc9,8,$acc9
        +		xor	$acc6,$t1,$t1
        +		srlx	$acc10,16,$acc10	!
        +		xor	$acc7,$t1,$t1
        +		srlx	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		srlx	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		srlx	$acc14,16,$acc14
        +		xor	$acc10,$t2,$t2
        +		srlx	$acc15,24,$acc15	!
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	srl	$t0,21,$acc0
        +		xor	$acc14,$t3,$t3
        +		xor	$acc15,$t3,$t3
        +	srl	$t3,13,$acc1
        +
        +	and	$acc0,2040,$acc0		!
        +	srl	$t2,5,$acc2
        +	and	$acc1,2040,$acc1
        +	ldx	[$tbl+$acc0],$acc0
        +	sll	$t1,3,$acc3
        +	and	$acc2,2040,$acc2
        +	ldx	[$tbl+$acc1],$acc1
        +	fmovs	%f0,%f0
        +	srl	$t1,21,$acc4			!
        +	and	$acc3,2040,$acc3
        +	ldx	[$tbl+$acc2],$acc2
        +	srl	$t0,13,$acc5
        +	and	$acc4,2040,$acc4
        +	ldx	[$tbl+$acc3],$acc3
        +	srl	$t3,5,$acc6
        +	and	$acc5,2040,$acc5
        +	ldx	[$tbl+$acc4],$acc4		!
        +	sll	$t2,3,$acc7
        +	and	$acc6,2040,$acc6
        +	ldx	[$tbl+$acc5],$acc5
        +	srl	$t2,21,$acc8
        +	and	$acc7,2040,$acc7
        +	ldx	[$tbl+$acc6],$acc6
        +	fmovs	%f0,%f0
        +	srl	$t1,13,$acc9			!
        +	and	$acc8,2040,$acc8
        +	ldx	[$tbl+$acc7],$acc7
        +	srl	$t0,5,$acc10
        +	and	$acc9,2040,$acc9
        +	ldx	[$tbl+$acc8],$acc8
        +	sll	$t3,3,$acc11
        +	and	$acc10,2040,$acc10
        +	ldx	[$tbl+$acc9],$acc9		!
        +	srl	$t3,21,$acc12
        +	and	$acc11,2040,$acc11
        +	ldx	[$tbl+$acc10],$acc10
        +	srl	$t2,13,$acc13
        +	and	$acc12,2040,$acc12
        +	ldx	[$tbl+$acc11],$acc11
        +	fmovs	%f0,%f0
        +	srl	$t1,5,$acc14			!
        +	and	$acc13,2040,$acc13
        +	ldx	[$tbl+$acc12],$acc12
        +	sll	$t0,3,$acc15
        +	and	$acc14,2040,$acc14
        +	ldx	[$tbl+$acc13],$acc13
        +		srlx	$acc1,8,$acc1
        +	and	$acc15,2040,$acc15
        +	ldx	[$tbl+$acc14],$acc14		!
        +
        +		srlx	$acc2,16,$acc2
        +		xor	$acc0,$s0,$s0
        +	ldx	[$tbl+$acc15],$acc15
        +		srlx	$acc3,24,$acc3
        +		xor	$acc1,$s0,$s0
        +	ld	[$key+16],$t0
        +	fmovs	%f0,%f0
        +		srlx	$acc5,8,$acc5		!
        +		xor	$acc2,$s0,$s0
        +	ld	[$key+20],$t1
        +		srlx	$acc6,16,$acc6
        +		xor	$acc3,$s0,$s0
        +	ld	[$key+24],$t2
        +		srlx	$acc7,24,$acc7
        +		xor	$acc4,$s1,$s1
        +	ld	[$key+28],$t3			!
        +		srlx	$acc9,8,$acc9
        +		xor	$acc5,$s1,$s1
        +	ldx	[$tbl+2048+0],%g0		! prefetch td4
        +		srlx	$acc10,16,$acc10
        +		xor	$acc6,$s1,$s1
        +	ldx	[$tbl+2048+32],%g0		! prefetch td4
        +		srlx	$acc11,24,$acc11
        +		xor	$acc7,$s1,$s1
        +	ldx	[$tbl+2048+64],%g0		! prefetch td4
        +		srlx	$acc13,8,$acc13
        +		xor	$acc8,$s2,$s2
        +	ldx	[$tbl+2048+96],%g0		! prefetch td4
        +		srlx	$acc14,16,$acc14	!
        +		xor	$acc9,$s2,$s2
        +	ldx	[$tbl+2048+128],%g0		! prefetch td4
        +		srlx	$acc15,24,$acc15
        +		xor	$acc10,$s2,$s2
        +	ldx	[$tbl+2048+160],%g0		! prefetch td4
        +	srl	$s0,21,$acc0
        +		xor	$acc11,$s2,$s2
        +	ldx	[$tbl+2048+192],%g0		! prefetch td4
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$s3,$s3
        +	ldx	[$tbl+2048+224],%g0		! prefetch td4
        +	and	$acc0,2040,$acc0		!
        +		xor	$acc14,$s3,$s3
        +		xor	$acc15,$s3,$s3
        +	ba	.Ldec_loop
        +	srl	$s3,13,$acc1
        +
        +.align	32
        +.Ldec_last:
        +		srlx	$acc1,8,$acc1		!
        +		xor	$acc0,$t0,$t0
        +	ld	[$key+0],$s0
        +		srlx	$acc2,16,$acc2
        +		xor	$acc1,$t0,$t0
        +	ld	[$key+4],$s1
        +		srlx	$acc3,24,$acc3
        +		xor	$acc2,$t0,$t0
        +	ld	[$key+8],$s2			!
        +		srlx	$acc5,8,$acc5
        +		xor	$acc3,$t0,$t0
        +	ld	[$key+12],$s3
        +		srlx	$acc6,16,$acc6
        +		xor	$acc4,$t1,$t1
        +		srlx	$acc7,24,$acc7
        +		xor	$acc5,$t1,$t1
        +		srlx	$acc9,8,$acc9		!
        +		xor	$acc6,$t1,$t1
        +		srlx	$acc10,16,$acc10
        +		xor	$acc7,$t1,$t1
        +		srlx	$acc11,24,$acc11
        +		xor	$acc8,$t2,$t2
        +		srlx	$acc13,8,$acc13
        +		xor	$acc9,$t2,$t2
        +		srlx	$acc14,16,$acc14	!
        +		xor	$acc10,$t2,$t2
        +		srlx	$acc15,24,$acc15
        +		xor	$acc11,$t2,$t2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$t3,$t3
        +	srl	$t0,24,$acc0
        +		xor	$acc14,$t3,$t3
        +		xor	$acc15,$t3,$t3		!
        +	srl	$t3,16,$acc1
        +
        +	srl	$t2,8,$acc2
        +	and	$acc1,255,$acc1
        +	ldub	[$rounds+$acc0],$acc0
        +	srl	$t1,24,$acc4
        +	and	$acc2,255,$acc2
        +	ldub	[$rounds+$acc1],$acc1
        +	srl	$t0,16,$acc5			!
        +	and	$t1,255,$acc3
        +	ldub	[$rounds+$acc2],$acc2
        +	ldub	[$rounds+$acc3],$acc3
        +	srl	$t3,8,$acc6
        +	and	$acc5,255,$acc5
        +	ldub	[$rounds+$acc4],$acc4
        +	fmovs	%f0,%f0
        +	srl	$t2,24,$acc8			!
        +	and	$acc6,255,$acc6
        +	ldub	[$rounds+$acc5],$acc5
        +	srl	$t1,16,$acc9
        +	and	$t2,255,$acc7
        +	ldub	[$rounds+$acc6],$acc6
        +	ldub	[$rounds+$acc7],$acc7
        +	fmovs	%f0,%f0
        +	srl	$t0,8,$acc10			!
        +	and	$acc9,255,$acc9
        +	ldub	[$rounds+$acc8],$acc8
        +	srl	$t3,24,$acc12
        +	and	$acc10,255,$acc10
        +	ldub	[$rounds+$acc9],$acc9
        +	srl	$t2,16,$acc13
        +	and	$t3,255,$acc11
        +	ldub	[$rounds+$acc10],$acc10		!
        +	srl	$t1,8,$acc14
        +	and	$acc13,255,$acc13
        +	ldub	[$rounds+$acc11],$acc11
        +	ldub	[$rounds+$acc12],$acc12
        +	and	$acc14,255,$acc14
        +	ldub	[$rounds+$acc13],$acc13
        +	and	$t0,255,$acc15
        +	ldub	[$rounds+$acc14],$acc14		!
        +
        +		sll	$acc0,24,$acc0
        +		xor	$acc3,$s0,$s0
        +	ldub	[$rounds+$acc15],$acc15
        +		sll	$acc1,16,$acc1
        +		xor	$acc0,$s0,$s0
        +	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
        +	fmovs	%f0,%f0
        +		sll	$acc2,8,$acc2		!
        +		xor	$acc1,$s0,$s0
        +		sll	$acc4,24,$acc4
        +		xor	$acc2,$s0,$s0
        +		sll	$acc5,16,$acc5
        +		xor	$acc7,$s1,$s1
        +		sll	$acc6,8,$acc6
        +		xor	$acc4,$s1,$s1
        +		sll	$acc8,24,$acc8		!
        +		xor	$acc5,$s1,$s1
        +		sll	$acc9,16,$acc9
        +		xor	$acc11,$s2,$s2
        +		sll	$acc10,8,$acc10
        +		xor	$acc6,$s1,$s1
        +		sll	$acc12,24,$acc12
        +		xor	$acc8,$s2,$s2
        +		sll	$acc13,16,$acc13	!
        +		xor	$acc9,$s2,$s2
        +		sll	$acc14,8,$acc14
        +		xor	$acc10,$s2,$s2
        +		xor	$acc12,$acc14,$acc14
        +		xor	$acc13,$s3,$s3
        +		xor	$acc14,$s3,$s3
        +		xor	$acc15,$s3,$s3
        +
        +	ret
        +	restore
        +.type	_sparcv9_AES_decrypt,#function
        +.size	_sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt)
        +
        +.align	32
        +.globl	AES_decrypt
        +AES_decrypt:
        +	or	%o0,%o1,%g1
        +	andcc	%g1,3,%g0
        +	bnz,pn	%xcc,.Lunaligned_dec
        +	save	%sp,-$frame,%sp
        +
        +	ld	[%i0+0],%o0
        +	ld	[%i0+4],%o1
        +	ld	[%i0+8],%o2
        +	ld	[%i0+12],%o3
        +
        +1:	call	.+8
        +	add	%o7,AES_Td-1b,%o4
        +	call	_sparcv9_AES_decrypt
        +	mov	%i2,%o5
        +
        +	st	%o0,[%i1+0]
        +	st	%o1,[%i1+4]
        +	st	%o2,[%i1+8]
        +	st	%o3,[%i1+12]
        +
        +	ret
        +	restore
        +
        +.align	32
        +.Lunaligned_dec:
        +	ldub	[%i0+0],%l0
        +	ldub	[%i0+1],%l1
        +	ldub	[%i0+2],%l2
        +
        +	sll	%l0,24,%l0
        +	ldub	[%i0+3],%l3
        +	sll	%l1,16,%l1
        +	ldub	[%i0+4],%l4
        +	sll	%l2,8,%l2
        +	or	%l1,%l0,%l0
        +	ldub	[%i0+5],%l5
        +	sll	%l4,24,%l4
        +	or	%l3,%l2,%l2
        +	ldub	[%i0+6],%l6
        +	sll	%l5,16,%l5
        +	or	%l0,%l2,%o0
        +	ldub	[%i0+7],%l7
        +
        +	sll	%l6,8,%l6
        +	or	%l5,%l4,%l4
        +	ldub	[%i0+8],%l0
        +	or	%l7,%l6,%l6
        +	ldub	[%i0+9],%l1
        +	or	%l4,%l6,%o1
        +	ldub	[%i0+10],%l2
        +
        +	sll	%l0,24,%l0
        +	ldub	[%i0+11],%l3
        +	sll	%l1,16,%l1
        +	ldub	[%i0+12],%l4
        +	sll	%l2,8,%l2
        +	or	%l1,%l0,%l0
        +	ldub	[%i0+13],%l5
        +	sll	%l4,24,%l4
        +	or	%l3,%l2,%l2
        +	ldub	[%i0+14],%l6
        +	sll	%l5,16,%l5
        +	or	%l0,%l2,%o2
        +	ldub	[%i0+15],%l7
        +
        +	sll	%l6,8,%l6
        +	or	%l5,%l4,%l4
        +	or	%l7,%l6,%l6
        +	or	%l4,%l6,%o3
        +
        +1:	call	.+8
        +	add	%o7,AES_Td-1b,%o4
        +	call	_sparcv9_AES_decrypt
        +	mov	%i2,%o5
        +
        +	srl	%o0,24,%l0
        +	srl	%o0,16,%l1
        +	stb	%l0,[%i1+0]
        +	srl	%o0,8,%l2
        +	stb	%l1,[%i1+1]
        +	stb	%l2,[%i1+2]
        +	srl	%o1,24,%l4
        +	stb	%o0,[%i1+3]
        +
        +	srl	%o1,16,%l5
        +	stb	%l4,[%i1+4]
        +	srl	%o1,8,%l6
        +	stb	%l5,[%i1+5]
        +	stb	%l6,[%i1+6]
        +	srl	%o2,24,%l0
        +	stb	%o1,[%i1+7]
        +
        +	srl	%o2,16,%l1
        +	stb	%l0,[%i1+8]
        +	srl	%o2,8,%l2
        +	stb	%l1,[%i1+9]
        +	stb	%l2,[%i1+10]
        +	srl	%o3,24,%l4
        +	stb	%o2,[%i1+11]
        +
        +	srl	%o3,16,%l5
        +	stb	%l4,[%i1+12]
        +	srl	%o3,8,%l6
        +	stb	%l5,[%i1+13]
        +	stb	%l6,[%i1+14]
        +	stb	%o3,[%i1+15]
        +
        +	ret
        +	restore
        +.type	AES_decrypt,#function
        +.size	AES_decrypt,(.-AES_decrypt)
        +___
        +
        +# fmovs instructions substituting for FP nops were originally added
        +# to meet specific instruction alignment requirements to maximize ILP.
        +# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
        +# undesired effect, so just omit them and sacrifice some portion of
        +# percent in performance...
        +$code =~ s/fmovs.*$//gm;
        +
        +print $code;
        +close STDOUT;	# ensure flush
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aes-x86_64.pl b/vendor/openssl/openssl/crypto/aes/asm/aes-x86_64.pl
        new file mode 100644
        index 000000000..9fa4ff5a6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aes-x86_64.pl
        @@ -0,0 +1,2819 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# Version 2.1.
        +#
        +# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on
        +# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version
        +# [you'll notice a lot of resemblance], such as compressed S-boxes
        +# in little-endian byte order, prefetch of these tables in CBC mode,
        +# as well as avoiding L1 cache aliasing between stack frame and key
        +# schedule and already mentioned tables, compressed Td4...
        +#
        +# Performance in number of cycles per processed byte for 128-bit key:
        +#
        +#		ECB encrypt	ECB decrypt	CBC large chunk
        +# AMD64		33		41		13.0
        +# EM64T		38		59		18.6(*)
        +# Core 2	30		43		14.5(*)
        +#
        +# (*) with hyper-threading off
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +$verticalspin=1;	# unlike 32-bit version $verticalspin performs
        +			# ~15% better on both AMD and Intel cores
        +$speed_limit=512;	# see aes-586.pl for details
        +
        +$code=".text\n";
        +
        +$s0="%eax";
        +$s1="%ebx";
        +$s2="%ecx";
        +$s3="%edx";
        +$acc0="%esi";	$mask80="%rsi";
        +$acc1="%edi";	$maskfe="%rdi";
        +$acc2="%ebp";	$mask1b="%rbp";
        +$inp="%r8";
        +$out="%r9";
        +$t0="%r10d";
        +$t1="%r11d";
        +$t2="%r12d";
        +$rnds="%r13d";
        +$sbox="%r14";
        +$key="%r15";
        +
        +sub hi() { my $r=shift;	$r =~ s/%[er]([a-d])x/%\1h/;	$r; }
        +sub lo() { my $r=shift;	$r =~ s/%[er]([a-d])x/%\1l/;
        +			$r =~ s/%[er]([sd]i)/%\1l/;
        +			$r =~ s/%(r[0-9]+)[d]?/%\1b/;	$r; }
        +sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/;
        +			$r =~ s/%r([0-9]+)/%r\1d/;	$r; }
        +sub _data_word()
        +{ my $i;
        +    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
        +}
        +sub data_word()
        +{ my $i;
        +  my $last=pop(@_);
        +    $code.=".long\t";
        +    while(defined($i=shift)) { $code.=sprintf"0x%08x,",$i; }
        +    $code.=sprintf"0x%08x\n",$last;
        +}
        +
        +sub data_byte()
        +{ my $i;
        +  my $last=pop(@_);
        +    $code.=".byte\t";
        +    while(defined($i=shift)) { $code.=sprintf"0x%02x,",$i&0xff; }
        +    $code.=sprintf"0x%02x\n",$last&0xff;
        +}
        +
        +sub encvert()
        +{ my $t3="%r8d";	# zaps $inp!
        +
        +$code.=<<___;
        +	# favor 3-way issue Opteron pipeline...
        +	movzb	`&lo("$s0")`,$acc0
        +	movzb	`&lo("$s1")`,$acc1
        +	movzb	`&lo("$s2")`,$acc2
        +	mov	0($sbox,$acc0,8),$t0
        +	mov	0($sbox,$acc1,8),$t1
        +	mov	0($sbox,$acc2,8),$t2
        +
        +	movzb	`&hi("$s1")`,$acc0
        +	movzb	`&hi("$s2")`,$acc1
        +	movzb	`&lo("$s3")`,$acc2
        +	xor	3($sbox,$acc0,8),$t0
        +	xor	3($sbox,$acc1,8),$t1
        +	mov	0($sbox,$acc2,8),$t3
        +
        +	movzb	`&hi("$s3")`,$acc0
        +	shr	\$16,$s2
        +	movzb	`&hi("$s0")`,$acc2
        +	xor	3($sbox,$acc0,8),$t2
        +	shr	\$16,$s3
        +	xor	3($sbox,$acc2,8),$t3
        +
        +	shr	\$16,$s1
        +	lea	16($key),$key
        +	shr	\$16,$s0
        +
        +	movzb	`&lo("$s2")`,$acc0
        +	movzb	`&lo("$s3")`,$acc1
        +	movzb	`&lo("$s0")`,$acc2
        +	xor	2($sbox,$acc0,8),$t0
        +	xor	2($sbox,$acc1,8),$t1
        +	xor	2($sbox,$acc2,8),$t2
        +
        +	movzb	`&hi("$s3")`,$acc0
        +	movzb	`&hi("$s0")`,$acc1
        +	movzb	`&lo("$s1")`,$acc2
        +	xor	1($sbox,$acc0,8),$t0
        +	xor	1($sbox,$acc1,8),$t1
        +	xor	2($sbox,$acc2,8),$t3
        +
        +	mov	12($key),$s3
        +	movzb	`&hi("$s1")`,$acc1
        +	movzb	`&hi("$s2")`,$acc2
        +	mov	0($key),$s0
        +	xor	1($sbox,$acc1,8),$t2
        +	xor	1($sbox,$acc2,8),$t3
        +
        +	mov	4($key),$s1
        +	mov	8($key),$s2
        +	xor	$t0,$s0
        +	xor	$t1,$s1
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +___
        +}
        +
        +sub enclastvert()
        +{ my $t3="%r8d";	# zaps $inp!
        +
        +$code.=<<___;
        +	movzb	`&lo("$s0")`,$acc0
        +	movzb	`&lo("$s1")`,$acc1
        +	movzb	`&lo("$s2")`,$acc2
        +	movzb	2($sbox,$acc0,8),$t0
        +	movzb	2($sbox,$acc1,8),$t1
        +	movzb	2($sbox,$acc2,8),$t2
        +
        +	movzb	`&lo("$s3")`,$acc0
        +	movzb	`&hi("$s1")`,$acc1
        +	movzb	`&hi("$s2")`,$acc2
        +	movzb	2($sbox,$acc0,8),$t3
        +	mov	0($sbox,$acc1,8),$acc1	#$t0
        +	mov	0($sbox,$acc2,8),$acc2	#$t1
        +
        +	and	\$0x0000ff00,$acc1
        +	and	\$0x0000ff00,$acc2
        +
        +	xor	$acc1,$t0
        +	xor	$acc2,$t1
        +	shr	\$16,$s2
        +
        +	movzb	`&hi("$s3")`,$acc0
        +	movzb	`&hi("$s0")`,$acc1
        +	shr	\$16,$s3
        +	mov	0($sbox,$acc0,8),$acc0	#$t2
        +	mov	0($sbox,$acc1,8),$acc1	#$t3
        +
        +	and	\$0x0000ff00,$acc0
        +	and	\$0x0000ff00,$acc1
        +	shr	\$16,$s1
        +	xor	$acc0,$t2
        +	xor	$acc1,$t3
        +	shr	\$16,$s0
        +
        +	movzb	`&lo("$s2")`,$acc0
        +	movzb	`&lo("$s3")`,$acc1
        +	movzb	`&lo("$s0")`,$acc2
        +	mov	0($sbox,$acc0,8),$acc0	#$t0
        +	mov	0($sbox,$acc1,8),$acc1	#$t1
        +	mov	0($sbox,$acc2,8),$acc2	#$t2
        +
        +	and	\$0x00ff0000,$acc0
        +	and	\$0x00ff0000,$acc1
        +	and	\$0x00ff0000,$acc2
        +
        +	xor	$acc0,$t0
        +	xor	$acc1,$t1
        +	xor	$acc2,$t2
        +
        +	movzb	`&lo("$s1")`,$acc0
        +	movzb	`&hi("$s3")`,$acc1
        +	movzb	`&hi("$s0")`,$acc2
        +	mov	0($sbox,$acc0,8),$acc0	#$t3
        +	mov	2($sbox,$acc1,8),$acc1	#$t0
        +	mov	2($sbox,$acc2,8),$acc2	#$t1
        +
        +	and	\$0x00ff0000,$acc0
        +	and	\$0xff000000,$acc1
        +	and	\$0xff000000,$acc2
        +
        +	xor	$acc0,$t3
        +	xor	$acc1,$t0
        +	xor	$acc2,$t1
        +
        +	movzb	`&hi("$s1")`,$acc0
        +	movzb	`&hi("$s2")`,$acc1
        +	mov	16+12($key),$s3
        +	mov	2($sbox,$acc0,8),$acc0	#$t2
        +	mov	2($sbox,$acc1,8),$acc1	#$t3
        +	mov	16+0($key),$s0
        +
        +	and	\$0xff000000,$acc0
        +	and	\$0xff000000,$acc1
        +
        +	xor	$acc0,$t2
        +	xor	$acc1,$t3
        +
        +	mov	16+4($key),$s1
        +	mov	16+8($key),$s2
        +	xor	$t0,$s0
        +	xor	$t1,$s1
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +___
        +}
        +
        +sub encstep()
        +{ my ($i,@s) = @_;
        +  my $tmp0=$acc0;
        +  my $tmp1=$acc1;
        +  my $tmp2=$acc2;
        +  my $out=($t0,$t1,$t2,$s[0])[$i];
        +
        +	if ($i==3) {
        +		$tmp0=$s[1];
        +		$tmp1=$s[2];
        +		$tmp2=$s[3];
        +	}
        +	$code.="	movzb	".&lo($s[0]).",$out\n";
        +	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
        +	$code.="	lea	16($key),$key\n"	if ($i==0);
        +
        +	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
        +	$code.="	mov	0($sbox,$out,8),$out\n";
        +
        +	$code.="	shr	\$16,$tmp1\n";
        +	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
        +	$code.="	xor	3($sbox,$tmp0,8),$out\n";
        +
        +	$code.="	movzb	".&lo($tmp1).",$tmp1\n";
        +	$code.="	shr	\$24,$tmp2\n";
        +	$code.="	xor	4*$i($key),$out\n";
        +
        +	$code.="	xor	2($sbox,$tmp1,8),$out\n";
        +	$code.="	xor	1($sbox,$tmp2,8),$out\n";
        +
        +	$code.="	mov	$t0,$s[1]\n"		if ($i==3);
        +	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
        +	$code.="	mov	$t2,$s[3]\n"		if ($i==3);
        +	$code.="\n";
        +}
        +
        +sub enclast()
        +{ my ($i,@s)=@_;
        +  my $tmp0=$acc0;
        +  my $tmp1=$acc1;
        +  my $tmp2=$acc2;
        +  my $out=($t0,$t1,$t2,$s[0])[$i];
        +
        +	if ($i==3) {
        +		$tmp0=$s[1];
        +		$tmp1=$s[2];
        +		$tmp2=$s[3];
        +	}
        +	$code.="	movzb	".&lo($s[0]).",$out\n";
        +	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
        +
        +	$code.="	mov	2($sbox,$out,8),$out\n";
        +	$code.="	shr	\$16,$tmp1\n";
        +	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
        +
        +	$code.="	and	\$0x000000ff,$out\n";
        +	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
        +	$code.="	movzb	".&lo($tmp1).",$tmp1\n";
        +	$code.="	shr	\$24,$tmp2\n";
        +
        +	$code.="	mov	0($sbox,$tmp0,8),$tmp0\n";
        +	$code.="	mov	0($sbox,$tmp1,8),$tmp1\n";
        +	$code.="	mov	2($sbox,$tmp2,8),$tmp2\n";
        +
        +	$code.="	and	\$0x0000ff00,$tmp0\n";
        +	$code.="	and	\$0x00ff0000,$tmp1\n";
        +	$code.="	and	\$0xff000000,$tmp2\n";
        +
        +	$code.="	xor	$tmp0,$out\n";
        +	$code.="	mov	$t0,$s[1]\n"		if ($i==3);
        +	$code.="	xor	$tmp1,$out\n";
        +	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
        +	$code.="	xor	$tmp2,$out\n";
        +	$code.="	mov	$t2,$s[3]\n"		if ($i==3);
        +	$code.="\n";
        +}
        +
        +$code.=<<___;
        +.type	_x86_64_AES_encrypt,\@abi-omnipotent
        +.align	16
        +_x86_64_AES_encrypt:
        +	xor	0($key),$s0			# xor with key
        +	xor	4($key),$s1
        +	xor	8($key),$s2
        +	xor	12($key),$s3
        +
        +	mov	240($key),$rnds			# load key->rounds
        +	sub	\$1,$rnds
        +	jmp	.Lenc_loop
        +.align	16
        +.Lenc_loop:
        +___
        +	if ($verticalspin) { &encvert(); }
        +	else {	&encstep(0,$s0,$s1,$s2,$s3);
        +		&encstep(1,$s1,$s2,$s3,$s0);
        +		&encstep(2,$s2,$s3,$s0,$s1);
        +		&encstep(3,$s3,$s0,$s1,$s2);
        +	}
        +$code.=<<___;
        +	sub	\$1,$rnds
        +	jnz	.Lenc_loop
        +___
        +	if ($verticalspin) { &enclastvert(); }
        +	else {	&enclast(0,$s0,$s1,$s2,$s3);
        +		&enclast(1,$s1,$s2,$s3,$s0);
        +		&enclast(2,$s2,$s3,$s0,$s1);
        +		&enclast(3,$s3,$s0,$s1,$s2);
        +		$code.=<<___;
        +		xor	16+0($key),$s0		# xor with key
        +		xor	16+4($key),$s1
        +		xor	16+8($key),$s2
        +		xor	16+12($key),$s3
        +___
        +	}
        +$code.=<<___;
        +	.byte	0xf3,0xc3			# rep ret
        +.size	_x86_64_AES_encrypt,.-_x86_64_AES_encrypt
        +___
        +
        +# it's possible to implement this by shifting tN by 8, filling least
        +# significant byte with byte load and finally bswap-ing at the end,
        +# but such partial register load kills Core 2...
        +sub enccompactvert()
        +{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
        +
        +$code.=<<___;
        +	movzb	`&lo("$s0")`,$t0
        +	movzb	`&lo("$s1")`,$t1
        +	movzb	`&lo("$s2")`,$t2
        +	movzb	($sbox,$t0,1),$t0
        +	movzb	($sbox,$t1,1),$t1
        +	movzb	($sbox,$t2,1),$t2
        +
        +	movzb	`&lo("$s3")`,$t3
        +	movzb	`&hi("$s1")`,$acc0
        +	movzb	`&hi("$s2")`,$acc1
        +	movzb	($sbox,$t3,1),$t3
        +	movzb	($sbox,$acc0,1),$t4	#$t0
        +	movzb	($sbox,$acc1,1),$t5	#$t1
        +
        +	movzb	`&hi("$s3")`,$acc2
        +	movzb	`&hi("$s0")`,$acc0
        +	shr	\$16,$s2
        +	movzb	($sbox,$acc2,1),$acc2	#$t2
        +	movzb	($sbox,$acc0,1),$acc0	#$t3
        +	shr	\$16,$s3
        +
        +	movzb	`&lo("$s2")`,$acc1
        +	shl	\$8,$t4
        +	shl	\$8,$t5
        +	movzb	($sbox,$acc1,1),$acc1	#$t0
        +	xor	$t4,$t0
        +	xor	$t5,$t1
        +
        +	movzb	`&lo("$s3")`,$t4
        +	shr	\$16,$s0
        +	shr	\$16,$s1
        +	movzb	`&lo("$s0")`,$t5
        +	shl	\$8,$acc2
        +	shl	\$8,$acc0
        +	movzb	($sbox,$t4,1),$t4	#$t1
        +	movzb	($sbox,$t5,1),$t5	#$t2
        +	xor	$acc2,$t2
        +	xor	$acc0,$t3
        +
        +	movzb	`&lo("$s1")`,$acc2
        +	movzb	`&hi("$s3")`,$acc0
        +	shl	\$16,$acc1
        +	movzb	($sbox,$acc2,1),$acc2	#$t3
        +	movzb	($sbox,$acc0,1),$acc0	#$t0
        +	xor	$acc1,$t0
        +
        +	movzb	`&hi("$s0")`,$acc1
        +	shr	\$8,$s2
        +	shr	\$8,$s1
        +	movzb	($sbox,$acc1,1),$acc1	#$t1
        +	movzb	($sbox,$s2,1),$s3	#$t3
        +	movzb	($sbox,$s1,1),$s2	#$t2
        +	shl	\$16,$t4
        +	shl	\$16,$t5
        +	shl	\$16,$acc2
        +	xor	$t4,$t1
        +	xor	$t5,$t2
        +	xor	$acc2,$t3
        +
        +	shl	\$24,$acc0
        +	shl	\$24,$acc1
        +	shl	\$24,$s3
        +	xor	$acc0,$t0
        +	shl	\$24,$s2
        +	xor	$acc1,$t1
        +	mov	$t0,$s0
        +	mov	$t1,$s1
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +___
        +}
        +
        +sub enctransform_ref()
        +{ my $sn = shift;
        +  my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d");
        +
        +$code.=<<___;
        +	mov	$sn,$acc
        +	and	\$0x80808080,$acc
        +	mov	$acc,$tmp
        +	shr	\$7,$tmp
        +	lea	($sn,$sn),$r2
        +	sub	$tmp,$acc
        +	and	\$0xfefefefe,$r2
        +	and	\$0x1b1b1b1b,$acc
        +	mov	$sn,$tmp
        +	xor	$acc,$r2
        +
        +	xor	$r2,$sn
        +	rol	\$24,$sn
        +	xor	$r2,$sn
        +	ror	\$16,$tmp
        +	xor	$tmp,$sn
        +	ror	\$8,$tmp
        +	xor	$tmp,$sn
        +___
        +}
        +
        +# unlike decrypt case it does not pay off to parallelize enctransform
        +sub enctransform()
        +{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d");
        +
        +$code.=<<___;
        +	mov	$s0,$acc0
        +	mov	$s1,$acc1
        +	and	\$0x80808080,$acc0
        +	and	\$0x80808080,$acc1
        +	mov	$acc0,$t0
        +	mov	$acc1,$t1
        +	shr	\$7,$t0
        +	lea	($s0,$s0),$r20
        +	shr	\$7,$t1
        +	lea	($s1,$s1),$r21
        +	sub	$t0,$acc0
        +	sub	$t1,$acc1
        +	and	\$0xfefefefe,$r20
        +	and	\$0xfefefefe,$r21
        +	and	\$0x1b1b1b1b,$acc0
        +	and	\$0x1b1b1b1b,$acc1
        +	mov	$s0,$t0
        +	mov	$s1,$t1
        +	xor	$acc0,$r20
        +	xor	$acc1,$r21
        +
        +	xor	$r20,$s0
        +	xor	$r21,$s1
        +	 mov	$s2,$acc0
        +	 mov	$s3,$acc1
        +	rol	\$24,$s0
        +	rol	\$24,$s1
        +	 and	\$0x80808080,$acc0
        +	 and	\$0x80808080,$acc1
        +	xor	$r20,$s0
        +	xor	$r21,$s1
        +	 mov	$acc0,$t2
        +	 mov	$acc1,$t3
        +	ror	\$16,$t0
        +	ror	\$16,$t1
        +	 shr	\$7,$t2
        +	 lea	($s2,$s2),$r20
        +	xor	$t0,$s0
        +	xor	$t1,$s1
        +	 shr	\$7,$t3
        +	 lea	($s3,$s3),$r21
        +	ror	\$8,$t0
        +	ror	\$8,$t1
        +	 sub	$t2,$acc0
        +	 sub	$t3,$acc1
        +	xor	$t0,$s0
        +	xor	$t1,$s1
        +
        +	and	\$0xfefefefe,$r20
        +	and	\$0xfefefefe,$r21
        +	and	\$0x1b1b1b1b,$acc0
        +	and	\$0x1b1b1b1b,$acc1
        +	mov	$s2,$t2
        +	mov	$s3,$t3
        +	xor	$acc0,$r20
        +	xor	$acc1,$r21
        +
        +	xor	$r20,$s2
        +	xor	$r21,$s3
        +	rol	\$24,$s2
        +	rol	\$24,$s3
        +	xor	$r20,$s2
        +	xor	$r21,$s3
        +	mov	0($sbox),$acc0			# prefetch Te4
        +	ror	\$16,$t2
        +	ror	\$16,$t3
        +	mov	64($sbox),$acc1
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +	mov	128($sbox),$r20
        +	ror	\$8,$t2
        +	ror	\$8,$t3
        +	mov	192($sbox),$r21
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +___
        +}
        +
        +$code.=<<___;
        +.type	_x86_64_AES_encrypt_compact,\@abi-omnipotent
        +.align	16
        +_x86_64_AES_encrypt_compact:
        +	lea	128($sbox),$inp			# size optimization
        +	mov	0-128($inp),$acc1		# prefetch Te4
        +	mov	32-128($inp),$acc2
        +	mov	64-128($inp),$t0
        +	mov	96-128($inp),$t1
        +	mov	128-128($inp),$acc1
        +	mov	160-128($inp),$acc2
        +	mov	192-128($inp),$t0
        +	mov	224-128($inp),$t1
        +	jmp	.Lenc_loop_compact
        +.align	16
        +.Lenc_loop_compact:
        +		xor	0($key),$s0		# xor with key
        +		xor	4($key),$s1
        +		xor	8($key),$s2
        +		xor	12($key),$s3
        +		lea	16($key),$key
        +___
        +		&enccompactvert();
        +$code.=<<___;
        +		cmp	16(%rsp),$key
        +		je	.Lenc_compact_done
        +___
        +		&enctransform();
        +$code.=<<___;
        +	jmp	.Lenc_loop_compact
        +.align	16
        +.Lenc_compact_done:
        +	xor	0($key),$s0
        +	xor	4($key),$s1
        +	xor	8($key),$s2
        +	xor	12($key),$s3
        +	.byte	0xf3,0xc3			# rep ret
        +.size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
        +___
        +
        +# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
        +$code.=<<___;
        +.globl	AES_encrypt
        +.type	AES_encrypt,\@function,3
        +.align	16
        +.globl	asm_AES_encrypt
        +.hidden	asm_AES_encrypt
        +asm_AES_encrypt:
        +AES_encrypt:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +
        +	# allocate frame "above" key schedule
        +	mov	%rsp,%r10
        +	lea	-63(%rdx),%rcx	# %rdx is key argument
        +	and	\$-64,%rsp
        +	sub	%rsp,%rcx
        +	neg	%rcx
        +	and	\$0x3c0,%rcx
        +	sub	%rcx,%rsp
        +	sub	\$32,%rsp
        +
        +	mov	%rsi,16(%rsp)	# save out
        +	mov	%r10,24(%rsp)	# save real stack pointer
        +.Lenc_prologue:
        +
        +	mov	%rdx,$key
        +	mov	240($key),$rnds	# load rounds
        +
        +	mov	0(%rdi),$s0	# load input vector
        +	mov	4(%rdi),$s1
        +	mov	8(%rdi),$s2
        +	mov	12(%rdi),$s3
        +
        +	shl	\$4,$rnds
        +	lea	($key,$rnds),%rbp
        +	mov	$key,(%rsp)	# key schedule
        +	mov	%rbp,8(%rsp)	# end of key schedule
        +
        +	# pick Te4 copy which can't "overlap" with stack frame or key schedule
        +	lea	.LAES_Te+2048(%rip),$sbox
        +	lea	768(%rsp),%rbp
        +	sub	$sbox,%rbp
        +	and	\$0x300,%rbp
        +	lea	($sbox,%rbp),$sbox
        +
        +	call	_x86_64_AES_encrypt_compact
        +
        +	mov	16(%rsp),$out	# restore out
        +	mov	24(%rsp),%rsi	# restore saved stack pointer
        +	mov	$s0,0($out)	# write output vector
        +	mov	$s1,4($out)
        +	mov	$s2,8($out)
        +	mov	$s3,12($out)
        +
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lenc_epilogue:
        +	ret
        +.size	AES_encrypt,.-AES_encrypt
        +___
        +
        +#------------------------------------------------------------------#
        +
        +sub decvert()
        +{ my $t3="%r8d";	# zaps $inp!
        +
        +$code.=<<___;
        +	# favor 3-way issue Opteron pipeline...
        +	movzb	`&lo("$s0")`,$acc0
        +	movzb	`&lo("$s1")`,$acc1
        +	movzb	`&lo("$s2")`,$acc2
        +	mov	0($sbox,$acc0,8),$t0
        +	mov	0($sbox,$acc1,8),$t1
        +	mov	0($sbox,$acc2,8),$t2
        +
        +	movzb	`&hi("$s3")`,$acc0
        +	movzb	`&hi("$s0")`,$acc1
        +	movzb	`&lo("$s3")`,$acc2
        +	xor	3($sbox,$acc0,8),$t0
        +	xor	3($sbox,$acc1,8),$t1
        +	mov	0($sbox,$acc2,8),$t3
        +
        +	movzb	`&hi("$s1")`,$acc0
        +	shr	\$16,$s0
        +	movzb	`&hi("$s2")`,$acc2
        +	xor	3($sbox,$acc0,8),$t2
        +	shr	\$16,$s3
        +	xor	3($sbox,$acc2,8),$t3
        +
        +	shr	\$16,$s1
        +	lea	16($key),$key
        +	shr	\$16,$s2
        +
        +	movzb	`&lo("$s2")`,$acc0
        +	movzb	`&lo("$s3")`,$acc1
        +	movzb	`&lo("$s0")`,$acc2
        +	xor	2($sbox,$acc0,8),$t0
        +	xor	2($sbox,$acc1,8),$t1
        +	xor	2($sbox,$acc2,8),$t2
        +
        +	movzb	`&hi("$s1")`,$acc0
        +	movzb	`&hi("$s2")`,$acc1
        +	movzb	`&lo("$s1")`,$acc2
        +	xor	1($sbox,$acc0,8),$t0
        +	xor	1($sbox,$acc1,8),$t1
        +	xor	2($sbox,$acc2,8),$t3
        +
        +	movzb	`&hi("$s3")`,$acc0
        +	mov	12($key),$s3
        +	movzb	`&hi("$s0")`,$acc2
        +	xor	1($sbox,$acc0,8),$t2
        +	mov	0($key),$s0
        +	xor	1($sbox,$acc2,8),$t3
        +
        +	xor	$t0,$s0
        +	mov	4($key),$s1
        +	mov	8($key),$s2
        +	xor	$t2,$s2
        +	xor	$t1,$s1
        +	xor	$t3,$s3
        +___
        +}
        +
        +sub declastvert()
        +{ my $t3="%r8d";	# zaps $inp!
        +
        +$code.=<<___;
        +	lea	2048($sbox),$sbox	# size optimization
        +	movzb	`&lo("$s0")`,$acc0
        +	movzb	`&lo("$s1")`,$acc1
        +	movzb	`&lo("$s2")`,$acc2
        +	movzb	($sbox,$acc0,1),$t0
        +	movzb	($sbox,$acc1,1),$t1
        +	movzb	($sbox,$acc2,1),$t2
        +
        +	movzb	`&lo("$s3")`,$acc0
        +	movzb	`&hi("$s3")`,$acc1
        +	movzb	`&hi("$s0")`,$acc2
        +	movzb	($sbox,$acc0,1),$t3
        +	movzb	($sbox,$acc1,1),$acc1	#$t0
        +	movzb	($sbox,$acc2,1),$acc2	#$t1
        +
        +	shl	\$8,$acc1
        +	shl	\$8,$acc2
        +
        +	xor	$acc1,$t0
        +	xor	$acc2,$t1
        +	shr	\$16,$s3
        +
        +	movzb	`&hi("$s1")`,$acc0
        +	movzb	`&hi("$s2")`,$acc1
        +	shr	\$16,$s0
        +	movzb	($sbox,$acc0,1),$acc0	#$t2
        +	movzb	($sbox,$acc1,1),$acc1	#$t3
        +
        +	shl	\$8,$acc0
        +	shl	\$8,$acc1
        +	shr	\$16,$s1
        +	xor	$acc0,$t2
        +	xor	$acc1,$t3
        +	shr	\$16,$s2
        +
        +	movzb	`&lo("$s2")`,$acc0
        +	movzb	`&lo("$s3")`,$acc1
        +	movzb	`&lo("$s0")`,$acc2
        +	movzb	($sbox,$acc0,1),$acc0	#$t0
        +	movzb	($sbox,$acc1,1),$acc1	#$t1
        +	movzb	($sbox,$acc2,1),$acc2	#$t2
        +
        +	shl	\$16,$acc0
        +	shl	\$16,$acc1
        +	shl	\$16,$acc2
        +
        +	xor	$acc0,$t0
        +	xor	$acc1,$t1
        +	xor	$acc2,$t2
        +
        +	movzb	`&lo("$s1")`,$acc0
        +	movzb	`&hi("$s1")`,$acc1
        +	movzb	`&hi("$s2")`,$acc2
        +	movzb	($sbox,$acc0,1),$acc0	#$t3
        +	movzb	($sbox,$acc1,1),$acc1	#$t0
        +	movzb	($sbox,$acc2,1),$acc2	#$t1
        +
        +	shl	\$16,$acc0
        +	shl	\$24,$acc1
        +	shl	\$24,$acc2
        +
        +	xor	$acc0,$t3
        +	xor	$acc1,$t0
        +	xor	$acc2,$t1
        +
        +	movzb	`&hi("$s3")`,$acc0
        +	movzb	`&hi("$s0")`,$acc1
        +	mov	16+12($key),$s3
        +	movzb	($sbox,$acc0,1),$acc0	#$t2
        +	movzb	($sbox,$acc1,1),$acc1	#$t3
        +	mov	16+0($key),$s0
        +
        +	shl	\$24,$acc0
        +	shl	\$24,$acc1
        +
        +	xor	$acc0,$t2
        +	xor	$acc1,$t3
        +
        +	mov	16+4($key),$s1
        +	mov	16+8($key),$s2
        +	lea	-2048($sbox),$sbox
        +	xor	$t0,$s0
        +	xor	$t1,$s1
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +___
        +}
        +
        +sub decstep()
        +{ my ($i,@s) = @_;
        +  my $tmp0=$acc0;
        +  my $tmp1=$acc1;
        +  my $tmp2=$acc2;
        +  my $out=($t0,$t1,$t2,$s[0])[$i];
        +
        +	$code.="	mov	$s[0],$out\n"		if ($i!=3);
        +			$tmp1=$s[2]			if ($i==3);
        +	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
        +	$code.="	and	\$0xFF,$out\n";
        +
        +	$code.="	mov	0($sbox,$out,8),$out\n";
        +	$code.="	shr	\$16,$tmp1\n";
        +			$tmp2=$s[3]			if ($i==3);
        +	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
        +
        +			$tmp0=$s[1]			if ($i==3);
        +	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
        +	$code.="	and	\$0xFF,$tmp1\n";
        +	$code.="	shr	\$24,$tmp2\n";
        +
        +	$code.="	xor	3($sbox,$tmp0,8),$out\n";
        +	$code.="	xor	2($sbox,$tmp1,8),$out\n";
        +	$code.="	xor	1($sbox,$tmp2,8),$out\n";
        +
        +	$code.="	mov	$t2,$s[1]\n"		if ($i==3);
        +	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
        +	$code.="	mov	$t0,$s[3]\n"		if ($i==3);
        +	$code.="\n";
        +}
        +
        +sub declast()
        +{ my ($i,@s)=@_;
        +  my $tmp0=$acc0;
        +  my $tmp1=$acc1;
        +  my $tmp2=$acc2;
        +  my $out=($t0,$t1,$t2,$s[0])[$i];
        +
        +	$code.="	mov	$s[0],$out\n"		if ($i!=3);
        +			$tmp1=$s[2]			if ($i==3);
        +	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
        +	$code.="	and	\$0xFF,$out\n";
        +
        +	$code.="	movzb	2048($sbox,$out,1),$out\n";
        +	$code.="	shr	\$16,$tmp1\n";
        +			$tmp2=$s[3]			if ($i==3);
        +	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
        +
        +			$tmp0=$s[1]			if ($i==3);
        +	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
        +	$code.="	and	\$0xFF,$tmp1\n";
        +	$code.="	shr	\$24,$tmp2\n";
        +
        +	$code.="	movzb	2048($sbox,$tmp0,1),$tmp0\n";
        +	$code.="	movzb	2048($sbox,$tmp1,1),$tmp1\n";
        +	$code.="	movzb	2048($sbox,$tmp2,1),$tmp2\n";
        +
        +	$code.="	shl	\$8,$tmp0\n";
        +	$code.="	shl	\$16,$tmp1\n";
        +	$code.="	shl	\$24,$tmp2\n";
        +
        +	$code.="	xor	$tmp0,$out\n";
        +	$code.="	mov	$t2,$s[1]\n"		if ($i==3);
        +	$code.="	xor	$tmp1,$out\n";
        +	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
        +	$code.="	xor	$tmp2,$out\n";
        +	$code.="	mov	$t0,$s[3]\n"		if ($i==3);
        +	$code.="\n";
        +}
        +
        +$code.=<<___;
        +.type	_x86_64_AES_decrypt,\@abi-omnipotent
        +.align	16
        +_x86_64_AES_decrypt:
        +	xor	0($key),$s0			# xor with key
        +	xor	4($key),$s1
        +	xor	8($key),$s2
        +	xor	12($key),$s3
        +
        +	mov	240($key),$rnds			# load key->rounds
        +	sub	\$1,$rnds
        +	jmp	.Ldec_loop
        +.align	16
        +.Ldec_loop:
        +___
        +	if ($verticalspin) { &decvert(); }
        +	else {	&decstep(0,$s0,$s3,$s2,$s1);
        +		&decstep(1,$s1,$s0,$s3,$s2);
        +		&decstep(2,$s2,$s1,$s0,$s3);
        +		&decstep(3,$s3,$s2,$s1,$s0);
        +		$code.=<<___;
        +		lea	16($key),$key
        +		xor	0($key),$s0			# xor with key
        +		xor	4($key),$s1
        +		xor	8($key),$s2
        +		xor	12($key),$s3
        +___
        +	}
        +$code.=<<___;
        +	sub	\$1,$rnds
        +	jnz	.Ldec_loop
        +___
        +	if ($verticalspin) { &declastvert(); }
        +	else {	&declast(0,$s0,$s3,$s2,$s1);
        +		&declast(1,$s1,$s0,$s3,$s2);
        +		&declast(2,$s2,$s1,$s0,$s3);
        +		&declast(3,$s3,$s2,$s1,$s0);
        +		$code.=<<___;
        +		xor	16+0($key),$s0			# xor with key
        +		xor	16+4($key),$s1
        +		xor	16+8($key),$s2
        +		xor	16+12($key),$s3
        +___
        +	}
        +$code.=<<___;
        +	.byte	0xf3,0xc3			# rep ret
        +.size	_x86_64_AES_decrypt,.-_x86_64_AES_decrypt
        +___
        +
        +sub deccompactvert()
        +{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
        +
        +$code.=<<___;
        +	movzb	`&lo("$s0")`,$t0
        +	movzb	`&lo("$s1")`,$t1
        +	movzb	`&lo("$s2")`,$t2
        +	movzb	($sbox,$t0,1),$t0
        +	movzb	($sbox,$t1,1),$t1
        +	movzb	($sbox,$t2,1),$t2
        +
        +	movzb	`&lo("$s3")`,$t3
        +	movzb	`&hi("$s3")`,$acc0
        +	movzb	`&hi("$s0")`,$acc1
        +	movzb	($sbox,$t3,1),$t3
        +	movzb	($sbox,$acc0,1),$t4	#$t0
        +	movzb	($sbox,$acc1,1),$t5	#$t1
        +
        +	movzb	`&hi("$s1")`,$acc2
        +	movzb	`&hi("$s2")`,$acc0
        +	shr	\$16,$s2
        +	movzb	($sbox,$acc2,1),$acc2	#$t2
        +	movzb	($sbox,$acc0,1),$acc0	#$t3
        +	shr	\$16,$s3
        +
        +	movzb	`&lo("$s2")`,$acc1
        +	shl	\$8,$t4
        +	shl	\$8,$t5
        +	movzb	($sbox,$acc1,1),$acc1	#$t0
        +	xor	$t4,$t0
        +	xor	$t5,$t1
        +
        +	movzb	`&lo("$s3")`,$t4
        +	shr	\$16,$s0
        +	shr	\$16,$s1
        +	movzb	`&lo("$s0")`,$t5
        +	shl	\$8,$acc2
        +	shl	\$8,$acc0
        +	movzb	($sbox,$t4,1),$t4	#$t1
        +	movzb	($sbox,$t5,1),$t5	#$t2
        +	xor	$acc2,$t2
        +	xor	$acc0,$t3
        +
        +	movzb	`&lo("$s1")`,$acc2
        +	movzb	`&hi("$s1")`,$acc0
        +	shl	\$16,$acc1
        +	movzb	($sbox,$acc2,1),$acc2	#$t3
        +	movzb	($sbox,$acc0,1),$acc0	#$t0
        +	xor	$acc1,$t0
        +
        +	movzb	`&hi("$s2")`,$acc1
        +	shl	\$16,$t4
        +	shl	\$16,$t5
        +	movzb	($sbox,$acc1,1),$s1	#$t1
        +	xor	$t4,$t1
        +	xor	$t5,$t2
        +
        +	movzb	`&hi("$s3")`,$acc1
        +	shr	\$8,$s0
        +	shl	\$16,$acc2
        +	movzb	($sbox,$acc1,1),$s2	#$t2
        +	movzb	($sbox,$s0,1),$s3	#$t3
        +	xor	$acc2,$t3
        +
        +	shl	\$24,$acc0
        +	shl	\$24,$s1
        +	shl	\$24,$s2
        +	xor	$acc0,$t0
        +	shl	\$24,$s3
        +	xor	$t1,$s1
        +	mov	$t0,$s0
        +	xor	$t2,$s2
        +	xor	$t3,$s3
        +___
        +}
        +
        +# parallelized version! input is pair of 64-bit values: %rax=s1.s0
        +# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1,
        +# %ecx=s2 and %edx=s3.
        +sub dectransform()
        +{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx");
        +  my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx");
        +  my $prefetch = shift;
        +
        +$code.=<<___;
        +	mov	$tp10,$acc0
        +	mov	$tp18,$acc8
        +	and	$mask80,$acc0
        +	and	$mask80,$acc8
        +	mov	$acc0,$tp40
        +	mov	$acc8,$tp48
        +	shr	\$7,$tp40
        +	lea	($tp10,$tp10),$tp20
        +	shr	\$7,$tp48
        +	lea	($tp18,$tp18),$tp28
        +	sub	$tp40,$acc0
        +	sub	$tp48,$acc8
        +	and	$maskfe,$tp20
        +	and	$maskfe,$tp28
        +	and	$mask1b,$acc0
        +	and	$mask1b,$acc8
        +	xor	$tp20,$acc0
        +	xor	$tp28,$acc8
        +	mov	$acc0,$tp20
        +	mov	$acc8,$tp28
        +
        +	and	$mask80,$acc0
        +	and	$mask80,$acc8
        +	mov	$acc0,$tp80
        +	mov	$acc8,$tp88
        +	shr	\$7,$tp80
        +	lea	($tp20,$tp20),$tp40
        +	shr	\$7,$tp88
        +	lea	($tp28,$tp28),$tp48
        +	sub	$tp80,$acc0
        +	sub	$tp88,$acc8
        +	and	$maskfe,$tp40
        +	and	$maskfe,$tp48
        +	and	$mask1b,$acc0
        +	and	$mask1b,$acc8
        +	xor	$tp40,$acc0
        +	xor	$tp48,$acc8
        +	mov	$acc0,$tp40
        +	mov	$acc8,$tp48
        +
        +	and	$mask80,$acc0
        +	and	$mask80,$acc8
        +	mov	$acc0,$tp80
        +	mov	$acc8,$tp88
        +	shr	\$7,$tp80
        +	 xor	$tp10,$tp20		# tp2^=tp1
        +	shr	\$7,$tp88
        +	 xor	$tp18,$tp28		# tp2^=tp1
        +	sub	$tp80,$acc0
        +	sub	$tp88,$acc8
        +	lea	($tp40,$tp40),$tp80
        +	lea	($tp48,$tp48),$tp88
        +	 xor	$tp10,$tp40		# tp4^=tp1
        +	 xor	$tp18,$tp48		# tp4^=tp1
        +	and	$maskfe,$tp80
        +	and	$maskfe,$tp88
        +	and	$mask1b,$acc0
        +	and	$mask1b,$acc8
        +	xor	$acc0,$tp80
        +	xor	$acc8,$tp88
        +
        +	xor	$tp80,$tp10		# tp1^=tp8
        +	xor	$tp88,$tp18		# tp1^=tp8
        +	xor	$tp80,$tp20		# tp2^tp1^=tp8
        +	xor	$tp88,$tp28		# tp2^tp1^=tp8
        +	mov	$tp10,$acc0
        +	mov	$tp18,$acc8
        +	xor	$tp80,$tp40		# tp4^tp1^=tp8
        +	xor	$tp88,$tp48		# tp4^tp1^=tp8
        +	shr	\$32,$acc0
        +	shr	\$32,$acc8
        +	xor	$tp20,$tp80		# tp8^=tp8^tp2^tp1=tp2^tp1
        +	xor	$tp28,$tp88		# tp8^=tp8^tp2^tp1=tp2^tp1
        +	rol	\$8,`&LO("$tp10")`	# ROTATE(tp1^tp8,8)
        +	rol	\$8,`&LO("$tp18")`	# ROTATE(tp1^tp8,8)
        +	xor	$tp40,$tp80		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
        +	xor	$tp48,$tp88		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
        +
        +	rol	\$8,`&LO("$acc0")`	# ROTATE(tp1^tp8,8)
        +	rol	\$8,`&LO("$acc8")`	# ROTATE(tp1^tp8,8)
        +	xor	`&LO("$tp80")`,`&LO("$tp10")`
        +	xor	`&LO("$tp88")`,`&LO("$tp18")`
        +	shr	\$32,$tp80
        +	shr	\$32,$tp88
        +	xor	`&LO("$tp80")`,`&LO("$acc0")`
        +	xor	`&LO("$tp88")`,`&LO("$acc8")`
        +
        +	mov	$tp20,$tp80
        +	mov	$tp28,$tp88
        +	shr	\$32,$tp80
        +	shr	\$32,$tp88
        +	rol	\$24,`&LO("$tp20")`	# ROTATE(tp2^tp1^tp8,24)
        +	rol	\$24,`&LO("$tp28")`	# ROTATE(tp2^tp1^tp8,24)
        +	rol	\$24,`&LO("$tp80")`	# ROTATE(tp2^tp1^tp8,24)
        +	rol	\$24,`&LO("$tp88")`	# ROTATE(tp2^tp1^tp8,24)
        +	xor	`&LO("$tp20")`,`&LO("$tp10")`
        +	xor	`&LO("$tp28")`,`&LO("$tp18")`
        +	mov	$tp40,$tp20
        +	mov	$tp48,$tp28
        +	xor	`&LO("$tp80")`,`&LO("$acc0")`
        +	xor	`&LO("$tp88")`,`&LO("$acc8")`
        +
        +	`"mov	0($sbox),$mask80"	if ($prefetch)`
        +	shr	\$32,$tp20
        +	shr	\$32,$tp28
        +	`"mov	64($sbox),$maskfe"	if ($prefetch)`
        +	rol	\$16,`&LO("$tp40")`	# ROTATE(tp4^tp1^tp8,16)
        +	rol	\$16,`&LO("$tp48")`	# ROTATE(tp4^tp1^tp8,16)
        +	`"mov	128($sbox),$mask1b"	if ($prefetch)`
        +	rol	\$16,`&LO("$tp20")`	# ROTATE(tp4^tp1^tp8,16)
        +	rol	\$16,`&LO("$tp28")`	# ROTATE(tp4^tp1^tp8,16)
        +	`"mov	192($sbox),$tp80"	if ($prefetch)`
        +	xor	`&LO("$tp40")`,`&LO("$tp10")`
        +	xor	`&LO("$tp48")`,`&LO("$tp18")`
        +	`"mov	256($sbox),$tp88"	if ($prefetch)`
        +	xor	`&LO("$tp20")`,`&LO("$acc0")`
        +	xor	`&LO("$tp28")`,`&LO("$acc8")`
        +___
        +}
        +
        +$code.=<<___;
        +.type	_x86_64_AES_decrypt_compact,\@abi-omnipotent
        +.align	16
        +_x86_64_AES_decrypt_compact:
        +	lea	128($sbox),$inp			# size optimization
        +	mov	0-128($inp),$acc1		# prefetch Td4
        +	mov	32-128($inp),$acc2
        +	mov	64-128($inp),$t0
        +	mov	96-128($inp),$t1
        +	mov	128-128($inp),$acc1
        +	mov	160-128($inp),$acc2
        +	mov	192-128($inp),$t0
        +	mov	224-128($inp),$t1
        +	jmp	.Ldec_loop_compact
        +
        +.align	16
        +.Ldec_loop_compact:
        +		xor	0($key),$s0		# xor with key
        +		xor	4($key),$s1
        +		xor	8($key),$s2
        +		xor	12($key),$s3
        +		lea	16($key),$key
        +___
        +		&deccompactvert();
        +$code.=<<___;
        +		cmp	16(%rsp),$key
        +		je	.Ldec_compact_done
        +
        +		mov	256+0($sbox),$mask80
        +		shl	\$32,%rbx
        +		shl	\$32,%rdx
        +		mov	256+8($sbox),$maskfe
        +		or	%rbx,%rax
        +		or	%rdx,%rcx
        +		mov	256+16($sbox),$mask1b
        +___
        +		&dectransform(1);
        +$code.=<<___;
        +	jmp	.Ldec_loop_compact
        +.align	16
        +.Ldec_compact_done:
        +	xor	0($key),$s0
        +	xor	4($key),$s1
        +	xor	8($key),$s2
        +	xor	12($key),$s3
        +	.byte	0xf3,0xc3			# rep ret
        +.size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
        +___
        +
        +# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
        +$code.=<<___;
        +.globl	AES_decrypt
        +.type	AES_decrypt,\@function,3
        +.align	16
        +.globl	asm_AES_decrypt
        +.hidden	asm_AES_decrypt
        +asm_AES_decrypt:
        +AES_decrypt:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +
        +	# allocate frame "above" key schedule
        +	mov	%rsp,%r10
        +	lea	-63(%rdx),%rcx	# %rdx is key argument
        +	and	\$-64,%rsp
        +	sub	%rsp,%rcx
        +	neg	%rcx
        +	and	\$0x3c0,%rcx
        +	sub	%rcx,%rsp
        +	sub	\$32,%rsp
        +
        +	mov	%rsi,16(%rsp)	# save out
        +	mov	%r10,24(%rsp)	# save real stack pointer
        +.Ldec_prologue:
        +
        +	mov	%rdx,$key
        +	mov	240($key),$rnds	# load rounds
        +
        +	mov	0(%rdi),$s0	# load input vector
        +	mov	4(%rdi),$s1
        +	mov	8(%rdi),$s2
        +	mov	12(%rdi),$s3
        +
        +	shl	\$4,$rnds
        +	lea	($key,$rnds),%rbp
        +	mov	$key,(%rsp)	# key schedule
        +	mov	%rbp,8(%rsp)	# end of key schedule
        +
        +	# pick Td4 copy which can't "overlap" with stack frame or key schedule
        +	lea	.LAES_Td+2048(%rip),$sbox
        +	lea	768(%rsp),%rbp
        +	sub	$sbox,%rbp
        +	and	\$0x300,%rbp
        +	lea	($sbox,%rbp),$sbox
        +	shr	\$3,%rbp	# recall "magic" constants!
        +	add	%rbp,$sbox
        +
        +	call	_x86_64_AES_decrypt_compact
        +
        +	mov	16(%rsp),$out	# restore out
        +	mov	24(%rsp),%rsi	# restore saved stack pointer
        +	mov	$s0,0($out)	# write output vector
        +	mov	$s1,4($out)
        +	mov	$s2,8($out)
        +	mov	$s3,12($out)
        +
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Ldec_epilogue:
        +	ret
        +.size	AES_decrypt,.-AES_decrypt
        +___
        +#------------------------------------------------------------------#
        +
        +sub enckey()
        +{
        +$code.=<<___;
        +	movz	%dl,%esi		# rk[i]>>0
        +	movzb	-128(%rbp,%rsi),%ebx
        +	movz	%dh,%esi		# rk[i]>>8
        +	shl	\$24,%ebx
        +	xor	%ebx,%eax
        +
        +	movzb	-128(%rbp,%rsi),%ebx
        +	shr	\$16,%edx
        +	movz	%dl,%esi		# rk[i]>>16
        +	xor	%ebx,%eax
        +
        +	movzb	-128(%rbp,%rsi),%ebx
        +	movz	%dh,%esi		# rk[i]>>24
        +	shl	\$8,%ebx
        +	xor	%ebx,%eax
        +
        +	movzb	-128(%rbp,%rsi),%ebx
        +	shl	\$16,%ebx
        +	xor	%ebx,%eax
        +
        +	xor	1024-128(%rbp,%rcx,4),%eax		# rcon
        +___
        +}
        +
        +# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        +#                        AES_KEY *key)
        +$code.=<<___;
        +.globl	private_AES_set_encrypt_key
        +.type	private_AES_set_encrypt_key,\@function,3
        +.align	16
        +private_AES_set_encrypt_key:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12			# redundant, but allows to share 
        +	push	%r13			# exception handler...
        +	push	%r14
        +	push	%r15
        +	sub	\$8,%rsp
        +.Lenc_key_prologue:
        +
        +	call	_x86_64_AES_set_encrypt_key
        +
        +	mov	8(%rsp),%r15
        +	mov	16(%rsp),%r14
        +	mov	24(%rsp),%r13
        +	mov	32(%rsp),%r12
        +	mov	40(%rsp),%rbp
        +	mov	48(%rsp),%rbx
        +	add	\$56,%rsp
        +.Lenc_key_epilogue:
        +	ret
        +.size	private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
        +
        +.type	_x86_64_AES_set_encrypt_key,\@abi-omnipotent
        +.align	16
        +_x86_64_AES_set_encrypt_key:
        +	mov	%esi,%ecx			# %ecx=bits
        +	mov	%rdi,%rsi			# %rsi=userKey
        +	mov	%rdx,%rdi			# %rdi=key
        +
        +	test	\$-1,%rsi
        +	jz	.Lbadpointer
        +	test	\$-1,%rdi
        +	jz	.Lbadpointer
        +
        +	lea	.LAES_Te(%rip),%rbp
        +	lea	2048+128(%rbp),%rbp
        +
        +	# prefetch Te4
        +	mov	0-128(%rbp),%eax
        +	mov	32-128(%rbp),%ebx
        +	mov	64-128(%rbp),%r8d
        +	mov	96-128(%rbp),%edx
        +	mov	128-128(%rbp),%eax
        +	mov	160-128(%rbp),%ebx
        +	mov	192-128(%rbp),%r8d
        +	mov	224-128(%rbp),%edx
        +
        +	cmp	\$128,%ecx
        +	je	.L10rounds
        +	cmp	\$192,%ecx
        +	je	.L12rounds
        +	cmp	\$256,%ecx
        +	je	.L14rounds
        +	mov	\$-2,%rax			# invalid number of bits
        +	jmp	.Lexit
        +
        +.L10rounds:
        +	mov	0(%rsi),%rax			# copy first 4 dwords
        +	mov	8(%rsi),%rdx
        +	mov	%rax,0(%rdi)
        +	mov	%rdx,8(%rdi)
        +
        +	shr	\$32,%rdx
        +	xor	%ecx,%ecx
        +	jmp	.L10shortcut
        +.align	4
        +.L10loop:
        +		mov	0(%rdi),%eax			# rk[0]
        +		mov	12(%rdi),%edx			# rk[3]
        +.L10shortcut:
        +___
        +		&enckey	();
        +$code.=<<___;
        +		mov	%eax,16(%rdi)			# rk[4]
        +		xor	4(%rdi),%eax
        +		mov	%eax,20(%rdi)			# rk[5]
        +		xor	8(%rdi),%eax
        +		mov	%eax,24(%rdi)			# rk[6]
        +		xor	12(%rdi),%eax
        +		mov	%eax,28(%rdi)			# rk[7]
        +		add	\$1,%ecx
        +		lea	16(%rdi),%rdi
        +		cmp	\$10,%ecx
        +	jl	.L10loop
        +
        +	movl	\$10,80(%rdi)			# setup number of rounds
        +	xor	%rax,%rax
        +	jmp	.Lexit
        +
        +.L12rounds:
        +	mov	0(%rsi),%rax			# copy first 6 dwords
        +	mov	8(%rsi),%rbx
        +	mov	16(%rsi),%rdx
        +	mov	%rax,0(%rdi)
        +	mov	%rbx,8(%rdi)
        +	mov	%rdx,16(%rdi)
        +
        +	shr	\$32,%rdx
        +	xor	%ecx,%ecx
        +	jmp	.L12shortcut
        +.align	4
        +.L12loop:
        +		mov	0(%rdi),%eax			# rk[0]
        +		mov	20(%rdi),%edx			# rk[5]
        +.L12shortcut:
        +___
        +		&enckey	();
        +$code.=<<___;
        +		mov	%eax,24(%rdi)			# rk[6]
        +		xor	4(%rdi),%eax
        +		mov	%eax,28(%rdi)			# rk[7]
        +		xor	8(%rdi),%eax
        +		mov	%eax,32(%rdi)			# rk[8]
        +		xor	12(%rdi),%eax
        +		mov	%eax,36(%rdi)			# rk[9]
        +
        +		cmp	\$7,%ecx
        +		je	.L12break
        +		add	\$1,%ecx
        +
        +		xor	16(%rdi),%eax
        +		mov	%eax,40(%rdi)			# rk[10]
        +		xor	20(%rdi),%eax
        +		mov	%eax,44(%rdi)			# rk[11]
        +
        +		lea	24(%rdi),%rdi
        +	jmp	.L12loop
        +.L12break:
        +	movl	\$12,72(%rdi)		# setup number of rounds
        +	xor	%rax,%rax
        +	jmp	.Lexit
        +
        +.L14rounds:		
        +	mov	0(%rsi),%rax			# copy first 8 dwords
        +	mov	8(%rsi),%rbx
        +	mov	16(%rsi),%rcx
        +	mov	24(%rsi),%rdx
        +	mov	%rax,0(%rdi)
        +	mov	%rbx,8(%rdi)
        +	mov	%rcx,16(%rdi)
        +	mov	%rdx,24(%rdi)
        +
        +	shr	\$32,%rdx
        +	xor	%ecx,%ecx
        +	jmp	.L14shortcut
        +.align	4
        +.L14loop:
        +		mov	0(%rdi),%eax			# rk[0]
        +		mov	28(%rdi),%edx			# rk[4]
        +.L14shortcut:
        +___
        +		&enckey	();
        +$code.=<<___;
        +		mov	%eax,32(%rdi)			# rk[8]
        +		xor	4(%rdi),%eax
        +		mov	%eax,36(%rdi)			# rk[9]
        +		xor	8(%rdi),%eax
        +		mov	%eax,40(%rdi)			# rk[10]
        +		xor	12(%rdi),%eax
        +		mov	%eax,44(%rdi)			# rk[11]
        +
        +		cmp	\$6,%ecx
        +		je	.L14break
        +		add	\$1,%ecx
        +
        +		mov	%eax,%edx
        +		mov	16(%rdi),%eax			# rk[4]
        +		movz	%dl,%esi			# rk[11]>>0
        +		movzb	-128(%rbp,%rsi),%ebx
        +		movz	%dh,%esi			# rk[11]>>8
        +		xor	%ebx,%eax
        +
        +		movzb	-128(%rbp,%rsi),%ebx
        +		shr	\$16,%edx
        +		shl	\$8,%ebx
        +		movz	%dl,%esi			# rk[11]>>16
        +		xor	%ebx,%eax
        +
        +		movzb	-128(%rbp,%rsi),%ebx
        +		movz	%dh,%esi			# rk[11]>>24
        +		shl	\$16,%ebx
        +		xor	%ebx,%eax
        +
        +		movzb	-128(%rbp,%rsi),%ebx
        +		shl	\$24,%ebx
        +		xor	%ebx,%eax
        +
        +		mov	%eax,48(%rdi)			# rk[12]
        +		xor	20(%rdi),%eax
        +		mov	%eax,52(%rdi)			# rk[13]
        +		xor	24(%rdi),%eax
        +		mov	%eax,56(%rdi)			# rk[14]
        +		xor	28(%rdi),%eax
        +		mov	%eax,60(%rdi)			# rk[15]
        +
        +		lea	32(%rdi),%rdi
        +	jmp	.L14loop
        +.L14break:
        +	movl	\$14,48(%rdi)		# setup number of rounds
        +	xor	%rax,%rax
        +	jmp	.Lexit
        +
        +.Lbadpointer:
        +	mov	\$-1,%rax
        +.Lexit:
        +	.byte	0xf3,0xc3			# rep ret
        +.size	_x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
        +___
        +
        +sub deckey_ref()
        +{ my ($i,$ptr,$te,$td) = @_;
        +  my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d");
        +$code.=<<___;
        +	mov	$i($ptr),$tp1
        +	mov	$tp1,$acc
        +	and	\$0x80808080,$acc
        +	mov	$acc,$tp4
        +	shr	\$7,$tp4
        +	lea	0($tp1,$tp1),$tp2
        +	sub	$tp4,$acc
        +	and	\$0xfefefefe,$tp2
        +	and	\$0x1b1b1b1b,$acc
        +	xor	$tp2,$acc
        +	mov	$acc,$tp2
        +
        +	and	\$0x80808080,$acc
        +	mov	$acc,$tp8
        +	shr	\$7,$tp8
        +	lea	0($tp2,$tp2),$tp4
        +	sub	$tp8,$acc
        +	and	\$0xfefefefe,$tp4
        +	and	\$0x1b1b1b1b,$acc
        +	 xor	$tp1,$tp2		# tp2^tp1
        +	xor	$tp4,$acc
        +	mov	$acc,$tp4
        +
        +	and	\$0x80808080,$acc
        +	mov	$acc,$tp8
        +	shr	\$7,$tp8
        +	sub	$tp8,$acc
        +	lea	0($tp4,$tp4),$tp8
        +	 xor	$tp1,$tp4		# tp4^tp1
        +	and	\$0xfefefefe,$tp8
        +	and	\$0x1b1b1b1b,$acc
        +	xor	$acc,$tp8
        +
        +	xor	$tp8,$tp1		# tp1^tp8
        +	rol	\$8,$tp1		# ROTATE(tp1^tp8,8)
        +	xor	$tp8,$tp2		# tp2^tp1^tp8
        +	xor	$tp8,$tp4		# tp4^tp1^tp8
        +	xor	$tp2,$tp8
        +	xor	$tp4,$tp8		# tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2
        +
        +	xor	$tp8,$tp1
        +	rol	\$24,$tp2		# ROTATE(tp2^tp1^tp8,24)
        +	xor	$tp2,$tp1
        +	rol	\$16,$tp4		# ROTATE(tp4^tp1^tp8,16)
        +	xor	$tp4,$tp1
        +
        +	mov	$tp1,$i($ptr)
        +___
        +}
        +
        +# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
        +#                        AES_KEY *key)
        +$code.=<<___;
        +.globl	private_AES_set_decrypt_key
        +.type	private_AES_set_decrypt_key,\@function,3
        +.align	16
        +private_AES_set_decrypt_key:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	push	%rdx			# save key schedule
        +.Ldec_key_prologue:
        +
        +	call	_x86_64_AES_set_encrypt_key
        +	mov	(%rsp),%r8		# restore key schedule
        +	cmp	\$0,%eax
        +	jne	.Labort
        +
        +	mov	240(%r8),%r14d		# pull number of rounds
        +	xor	%rdi,%rdi
        +	lea	(%rdi,%r14d,4),%rcx
        +	mov	%r8,%rsi
        +	lea	(%r8,%rcx,4),%rdi	# pointer to last chunk
        +.align	4
        +.Linvert:
        +		mov	0(%rsi),%rax
        +		mov	8(%rsi),%rbx
        +		mov	0(%rdi),%rcx
        +		mov	8(%rdi),%rdx
        +		mov	%rax,0(%rdi)
        +		mov	%rbx,8(%rdi)
        +		mov	%rcx,0(%rsi)
        +		mov	%rdx,8(%rsi)
        +		lea	16(%rsi),%rsi
        +		lea	-16(%rdi),%rdi
        +		cmp	%rsi,%rdi
        +	jne	.Linvert
        +
        +	lea	.LAES_Te+2048+1024(%rip),%rax	# rcon
        +
        +	mov	40(%rax),$mask80
        +	mov	48(%rax),$maskfe
        +	mov	56(%rax),$mask1b
        +
        +	mov	%r8,$key
        +	sub	\$1,%r14d
        +.align	4
        +.Lpermute:
        +		lea	16($key),$key
        +		mov	0($key),%rax
        +		mov	8($key),%rcx
        +___
        +		&dectransform ();
        +$code.=<<___;
        +		mov	%eax,0($key)
        +		mov	%ebx,4($key)
        +		mov	%ecx,8($key)
        +		mov	%edx,12($key)
        +		sub	\$1,%r14d
        +	jnz	.Lpermute
        +
        +	xor	%rax,%rax
        +.Labort:
        +	mov	8(%rsp),%r15
        +	mov	16(%rsp),%r14
        +	mov	24(%rsp),%r13
        +	mov	32(%rsp),%r12
        +	mov	40(%rsp),%rbp
        +	mov	48(%rsp),%rbx
        +	add	\$56,%rsp
        +.Ldec_key_epilogue:
        +	ret
        +.size	private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
        +___
        +
        +# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
        +#			size_t length, const AES_KEY *key,
        +#			unsigned char *ivp,const int enc);
        +{
        +# stack frame layout
        +# -8(%rsp)		return address
        +my $keyp="0(%rsp)";		# one to pass as $key
        +my $keyend="8(%rsp)";		# &(keyp->rd_key[4*keyp->rounds])
        +my $_rsp="16(%rsp)";		# saved %rsp
        +my $_inp="24(%rsp)";		# copy of 1st parameter, inp
        +my $_out="32(%rsp)";		# copy of 2nd parameter, out
        +my $_len="40(%rsp)";		# copy of 3rd parameter, length
        +my $_key="48(%rsp)";		# copy of 4th parameter, key
        +my $_ivp="56(%rsp)";		# copy of 5th parameter, ivp
        +my $ivec="64(%rsp)";		# ivec[16]
        +my $aes_key="80(%rsp)";		# copy of aes_key
        +my $mark="80+240(%rsp)";	# copy of aes_key->rounds
        +
        +$code.=<<___;
        +.globl	AES_cbc_encrypt
        +.type	AES_cbc_encrypt,\@function,6
        +.align	16
        +.extern	OPENSSL_ia32cap_P
        +.globl	asm_AES_cbc_encrypt
        +.hidden	asm_AES_cbc_encrypt
        +asm_AES_cbc_encrypt:
        +AES_cbc_encrypt:
        +	cmp	\$0,%rdx	# check length
        +	je	.Lcbc_epilogue
        +	pushfq
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +.Lcbc_prologue:
        +
        +	cld
        +	mov	%r9d,%r9d	# clear upper half of enc
        +
        +	lea	.LAES_Te(%rip),$sbox
        +	cmp	\$0,%r9
        +	jne	.Lcbc_picked_te
        +	lea	.LAES_Td(%rip),$sbox
        +.Lcbc_picked_te:
        +
        +	mov	OPENSSL_ia32cap_P(%rip),%r10d
        +	cmp	\$$speed_limit,%rdx
        +	jb	.Lcbc_slow_prologue
        +	test	\$15,%rdx
        +	jnz	.Lcbc_slow_prologue
        +	#bt	\$28,%r10d
        +	#jc	.Lcbc_slow_prologue
        +
        +	# allocate aligned stack frame...
        +	lea	-88-248(%rsp),$key
        +	and	\$-64,$key
        +
        +	# ... and make sure it doesn't alias with AES_T[ed] modulo 4096
        +	mov	$sbox,%r10
        +	lea	2304($sbox),%r11
        +	mov	$key,%r12
        +	and	\$0xFFF,%r10	# s = $sbox&0xfff
        +	and	\$0xFFF,%r11	# e = ($sbox+2048)&0xfff
        +	and	\$0xFFF,%r12	# p = %rsp&0xfff
        +
        +	cmp	%r11,%r12	# if (p=>e) %rsp =- (p-e);
        +	jb	.Lcbc_te_break_out
        +	sub	%r11,%r12
        +	sub	%r12,$key
        +	jmp	.Lcbc_te_ok
        +.Lcbc_te_break_out:		# else %rsp -= (p-s)&0xfff + framesz
        +	sub	%r10,%r12
        +	and	\$0xFFF,%r12
        +	add	\$320,%r12
        +	sub	%r12,$key
        +.align	4
        +.Lcbc_te_ok:
        +
        +	xchg	%rsp,$key
        +	#add	\$8,%rsp	# reserve for return address!
        +	mov	$key,$_rsp	# save %rsp
        +.Lcbc_fast_body:
        +	mov	%rdi,$_inp	# save copy of inp
        +	mov	%rsi,$_out	# save copy of out
        +	mov	%rdx,$_len	# save copy of len
        +	mov	%rcx,$_key	# save copy of key
        +	mov	%r8,$_ivp	# save copy of ivp
        +	movl	\$0,$mark	# copy of aes_key->rounds = 0;
        +	mov	%r8,%rbp	# rearrange input arguments
        +	mov	%r9,%rbx
        +	mov	%rsi,$out
        +	mov	%rdi,$inp
        +	mov	%rcx,$key
        +
        +	mov	240($key),%eax		# key->rounds
        +	# do we copy key schedule to stack?
        +	mov	$key,%r10
        +	sub	$sbox,%r10
        +	and	\$0xfff,%r10
        +	cmp	\$2304,%r10
        +	jb	.Lcbc_do_ecopy
        +	cmp	\$4096-248,%r10
        +	jb	.Lcbc_skip_ecopy
        +.align	4
        +.Lcbc_do_ecopy:
        +		mov	$key,%rsi
        +		lea	$aes_key,%rdi
        +		lea	$aes_key,$key
        +		mov	\$240/8,%ecx
        +		.long	0x90A548F3	# rep movsq
        +		mov	%eax,(%rdi)	# copy aes_key->rounds
        +.Lcbc_skip_ecopy:
        +	mov	$key,$keyp	# save key pointer
        +
        +	mov	\$18,%ecx
        +.align	4
        +.Lcbc_prefetch_te:
        +		mov	0($sbox),%r10
        +		mov	32($sbox),%r11
        +		mov	64($sbox),%r12
        +		mov	96($sbox),%r13
        +		lea	128($sbox),$sbox
        +		sub	\$1,%ecx
        +	jnz	.Lcbc_prefetch_te
        +	lea	-2304($sbox),$sbox
        +
        +	cmp	\$0,%rbx
        +	je	.LFAST_DECRYPT
        +
        +#----------------------------- ENCRYPT -----------------------------#
        +	mov	0(%rbp),$s0		# load iv
        +	mov	4(%rbp),$s1
        +	mov	8(%rbp),$s2
        +	mov	12(%rbp),$s3
        +
        +.align	4
        +.Lcbc_fast_enc_loop:
        +		xor	0($inp),$s0
        +		xor	4($inp),$s1
        +		xor	8($inp),$s2
        +		xor	12($inp),$s3
        +		mov	$keyp,$key	# restore key
        +		mov	$inp,$_inp	# if ($verticalspin) save inp
        +
        +		call	_x86_64_AES_encrypt
        +
        +		mov	$_inp,$inp	# if ($verticalspin) restore inp
        +		mov	$_len,%r10
        +		mov	$s0,0($out)
        +		mov	$s1,4($out)
        +		mov	$s2,8($out)
        +		mov	$s3,12($out)
        +
        +		lea	16($inp),$inp
        +		lea	16($out),$out
        +		sub	\$16,%r10
        +		test	\$-16,%r10
        +		mov	%r10,$_len
        +	jnz	.Lcbc_fast_enc_loop
        +	mov	$_ivp,%rbp	# restore ivp
        +	mov	$s0,0(%rbp)	# save ivec
        +	mov	$s1,4(%rbp)
        +	mov	$s2,8(%rbp)
        +	mov	$s3,12(%rbp)
        +
        +	jmp	.Lcbc_fast_cleanup
        +
        +#----------------------------- DECRYPT -----------------------------#
        +.align	16
        +.LFAST_DECRYPT:
        +	cmp	$inp,$out
        +	je	.Lcbc_fast_dec_in_place
        +
        +	mov	%rbp,$ivec
        +.align	4
        +.Lcbc_fast_dec_loop:
        +		mov	0($inp),$s0	# read input
        +		mov	4($inp),$s1
        +		mov	8($inp),$s2
        +		mov	12($inp),$s3
        +		mov	$keyp,$key	# restore key
        +		mov	$inp,$_inp	# if ($verticalspin) save inp
        +
        +		call	_x86_64_AES_decrypt
        +
        +		mov	$ivec,%rbp	# load ivp
        +		mov	$_inp,$inp	# if ($verticalspin) restore inp
        +		mov	$_len,%r10	# load len
        +		xor	0(%rbp),$s0	# xor iv
        +		xor	4(%rbp),$s1
        +		xor	8(%rbp),$s2
        +		xor	12(%rbp),$s3
        +		mov	$inp,%rbp	# current input, next iv
        +
        +		sub	\$16,%r10
        +		mov	%r10,$_len	# update len
        +		mov	%rbp,$ivec	# update ivp
        +
        +		mov	$s0,0($out)	# write output
        +		mov	$s1,4($out)
        +		mov	$s2,8($out)
        +		mov	$s3,12($out)
        +
        +		lea	16($inp),$inp
        +		lea	16($out),$out
        +	jnz	.Lcbc_fast_dec_loop
        +	mov	$_ivp,%r12		# load user ivp
        +	mov	0(%rbp),%r10		# load iv
        +	mov	8(%rbp),%r11
        +	mov	%r10,0(%r12)		# copy back to user
        +	mov	%r11,8(%r12)
        +	jmp	.Lcbc_fast_cleanup
        +
        +.align	16
        +.Lcbc_fast_dec_in_place:
        +	mov	0(%rbp),%r10		# copy iv to stack
        +	mov	8(%rbp),%r11
        +	mov	%r10,0+$ivec
        +	mov	%r11,8+$ivec
        +.align	4
        +.Lcbc_fast_dec_in_place_loop:
        +		mov	0($inp),$s0	# load input
        +		mov	4($inp),$s1
        +		mov	8($inp),$s2
        +		mov	12($inp),$s3
        +		mov	$keyp,$key	# restore key
        +		mov	$inp,$_inp	# if ($verticalspin) save inp
        +
        +		call	_x86_64_AES_decrypt
        +
        +		mov	$_inp,$inp	# if ($verticalspin) restore inp
        +		mov	$_len,%r10
        +		xor	0+$ivec,$s0
        +		xor	4+$ivec,$s1
        +		xor	8+$ivec,$s2
        +		xor	12+$ivec,$s3
        +
        +		mov	0($inp),%r11	# load input
        +		mov	8($inp),%r12
        +		sub	\$16,%r10
        +		jz	.Lcbc_fast_dec_in_place_done
        +
        +		mov	%r11,0+$ivec	# copy input to iv
        +		mov	%r12,8+$ivec
        +
        +		mov	$s0,0($out)	# save output [zaps input]
        +		mov	$s1,4($out)
        +		mov	$s2,8($out)
        +		mov	$s3,12($out)
        +
        +		lea	16($inp),$inp
        +		lea	16($out),$out
        +		mov	%r10,$_len
        +	jmp	.Lcbc_fast_dec_in_place_loop
        +.Lcbc_fast_dec_in_place_done:
        +	mov	$_ivp,%rdi
        +	mov	%r11,0(%rdi)	# copy iv back to user
        +	mov	%r12,8(%rdi)
        +
        +	mov	$s0,0($out)	# save output [zaps input]
        +	mov	$s1,4($out)
        +	mov	$s2,8($out)
        +	mov	$s3,12($out)
        +
        +.align	4
        +.Lcbc_fast_cleanup:
        +	cmpl	\$0,$mark	# was the key schedule copied?
        +	lea	$aes_key,%rdi
        +	je	.Lcbc_exit
        +		mov	\$240/8,%ecx
        +		xor	%rax,%rax
        +		.long	0x90AB48F3	# rep stosq
        +
        +	jmp	.Lcbc_exit
        +
        +#--------------------------- SLOW ROUTINE ---------------------------#
        +.align	16
        +.Lcbc_slow_prologue:
        +	# allocate aligned stack frame...
        +	lea	-88(%rsp),%rbp
        +	and	\$-64,%rbp
        +	# ... just "above" key schedule
        +	lea	-88-63(%rcx),%r10
        +	sub	%rbp,%r10
        +	neg	%r10
        +	and	\$0x3c0,%r10
        +	sub	%r10,%rbp
        +
        +	xchg	%rsp,%rbp
        +	#add	\$8,%rsp	# reserve for return address!
        +	mov	%rbp,$_rsp	# save %rsp
        +.Lcbc_slow_body:
        +	#mov	%rdi,$_inp	# save copy of inp
        +	#mov	%rsi,$_out	# save copy of out
        +	#mov	%rdx,$_len	# save copy of len
        +	#mov	%rcx,$_key	# save copy of key
        +	mov	%r8,$_ivp	# save copy of ivp
        +	mov	%r8,%rbp	# rearrange input arguments
        +	mov	%r9,%rbx
        +	mov	%rsi,$out
        +	mov	%rdi,$inp
        +	mov	%rcx,$key
        +	mov	%rdx,%r10
        +
        +	mov	240($key),%eax
        +	mov	$key,$keyp	# save key pointer
        +	shl	\$4,%eax
        +	lea	($key,%rax),%rax
        +	mov	%rax,$keyend
        +
        +	# pick Te4 copy which can't "overlap" with stack frame or key scdedule
        +	lea	2048($sbox),$sbox
        +	lea	768-8(%rsp),%rax
        +	sub	$sbox,%rax
        +	and	\$0x300,%rax
        +	lea	($sbox,%rax),$sbox
        +
        +	cmp	\$0,%rbx
        +	je	.LSLOW_DECRYPT
        +
        +#--------------------------- SLOW ENCRYPT ---------------------------#
        +	test	\$-16,%r10		# check upon length
        +	mov	0(%rbp),$s0		# load iv
        +	mov	4(%rbp),$s1
        +	mov	8(%rbp),$s2
        +	mov	12(%rbp),$s3
        +	jz	.Lcbc_slow_enc_tail	# short input...
        +
        +.align	4
        +.Lcbc_slow_enc_loop:
        +		xor	0($inp),$s0
        +		xor	4($inp),$s1
        +		xor	8($inp),$s2
        +		xor	12($inp),$s3
        +		mov	$keyp,$key	# restore key
        +		mov	$inp,$_inp	# save inp
        +		mov	$out,$_out	# save out
        +		mov	%r10,$_len	# save len
        +
        +		call	_x86_64_AES_encrypt_compact
        +
        +		mov	$_inp,$inp	# restore inp
        +		mov	$_out,$out	# restore out
        +		mov	$_len,%r10	# restore len
        +		mov	$s0,0($out)
        +		mov	$s1,4($out)
        +		mov	$s2,8($out)
        +		mov	$s3,12($out)
        +
        +		lea	16($inp),$inp
        +		lea	16($out),$out
        +		sub	\$16,%r10
        +		test	\$-16,%r10
        +	jnz	.Lcbc_slow_enc_loop
        +	test	\$15,%r10
        +	jnz	.Lcbc_slow_enc_tail
        +	mov	$_ivp,%rbp	# restore ivp
        +	mov	$s0,0(%rbp)	# save ivec
        +	mov	$s1,4(%rbp)
        +	mov	$s2,8(%rbp)
        +	mov	$s3,12(%rbp)
        +
        +	jmp	.Lcbc_exit
        +
        +.align	4
        +.Lcbc_slow_enc_tail:
        +	mov	%rax,%r11
        +	mov	%rcx,%r12
        +	mov	%r10,%rcx
        +	mov	$inp,%rsi
        +	mov	$out,%rdi
        +	.long	0x9066A4F3		# rep movsb
        +	mov	\$16,%rcx		# zero tail
        +	sub	%r10,%rcx
        +	xor	%rax,%rax
        +	.long	0x9066AAF3		# rep stosb
        +	mov	$out,$inp		# this is not a mistake!
        +	mov	\$16,%r10		# len=16
        +	mov	%r11,%rax
        +	mov	%r12,%rcx
        +	jmp	.Lcbc_slow_enc_loop	# one more spin...
        +#--------------------------- SLOW DECRYPT ---------------------------#
        +.align	16
        +.LSLOW_DECRYPT:
        +	shr	\$3,%rax
        +	add	%rax,$sbox		# recall "magic" constants!
        +
        +	mov	0(%rbp),%r11		# copy iv to stack
        +	mov	8(%rbp),%r12
        +	mov	%r11,0+$ivec
        +	mov	%r12,8+$ivec
        +
        +.align	4
        +.Lcbc_slow_dec_loop:
        +		mov	0($inp),$s0	# load input
        +		mov	4($inp),$s1
        +		mov	8($inp),$s2
        +		mov	12($inp),$s3
        +		mov	$keyp,$key	# restore key
        +		mov	$inp,$_inp	# save inp
        +		mov	$out,$_out	# save out
        +		mov	%r10,$_len	# save len
        +
        +		call	_x86_64_AES_decrypt_compact
        +
        +		mov	$_inp,$inp	# restore inp
        +		mov	$_out,$out	# restore out
        +		mov	$_len,%r10
        +		xor	0+$ivec,$s0
        +		xor	4+$ivec,$s1
        +		xor	8+$ivec,$s2
        +		xor	12+$ivec,$s3
        +
        +		mov	0($inp),%r11	# load input
        +		mov	8($inp),%r12
        +		sub	\$16,%r10
        +		jc	.Lcbc_slow_dec_partial
        +		jz	.Lcbc_slow_dec_done
        +
        +		mov	%r11,0+$ivec	# copy input to iv
        +		mov	%r12,8+$ivec
        +
        +		mov	$s0,0($out)	# save output [can zap input]
        +		mov	$s1,4($out)
        +		mov	$s2,8($out)
        +		mov	$s3,12($out)
        +
        +		lea	16($inp),$inp
        +		lea	16($out),$out
        +	jmp	.Lcbc_slow_dec_loop
        +.Lcbc_slow_dec_done:
        +	mov	$_ivp,%rdi
        +	mov	%r11,0(%rdi)		# copy iv back to user
        +	mov	%r12,8(%rdi)
        +
        +	mov	$s0,0($out)		# save output [can zap input]
        +	mov	$s1,4($out)
        +	mov	$s2,8($out)
        +	mov	$s3,12($out)
        +
        +	jmp	.Lcbc_exit
        +
        +.align	4
        +.Lcbc_slow_dec_partial:
        +	mov	$_ivp,%rdi
        +	mov	%r11,0(%rdi)		# copy iv back to user
        +	mov	%r12,8(%rdi)
        +
        +	mov	$s0,0+$ivec		# save output to stack
        +	mov	$s1,4+$ivec
        +	mov	$s2,8+$ivec
        +	mov	$s3,12+$ivec
        +
        +	mov	$out,%rdi
        +	lea	$ivec,%rsi
        +	lea	16(%r10),%rcx
        +	.long	0x9066A4F3	# rep movsb
        +	jmp	.Lcbc_exit
        +
        +.align	16
        +.Lcbc_exit:
        +	mov	$_rsp,%rsi
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lcbc_popfq:
        +	popfq
        +.Lcbc_epilogue:
        +	ret
        +.size	AES_cbc_encrypt,.-AES_cbc_encrypt
        +___
        +}
        +
        +$code.=<<___;
        +.align	64
        +.LAES_Te:
        +___
        +	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
        +	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
        +	&_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
        +	&_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
        +	&_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
        +	&_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
        +	&_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
        +	&_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
        +	&_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
        +	&_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
        +	&_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
        +	&_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
        +	&_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
        +	&_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
        +	&_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
        +	&_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
        +	&_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
        +	&_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
        +	&_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
        +	&_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
        +	&_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
        +	&_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
        +	&_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
        +	&_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
        +	&_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
        +	&_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
        +	&_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
        +	&_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
        +	&_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
        +	&_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
        +	&_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
        +	&_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
        +	&_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
        +	&_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
        +	&_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
        +	&_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
        +	&_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
        +	&_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
        +	&_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
        +	&_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
        +	&_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
        +	&_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
        +	&_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
        +	&_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
        +	&_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
        +	&_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
        +	&_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
        +	&_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
        +	&_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
        +	&_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
        +	&_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
        +	&_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
        +	&_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
        +	&_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
        +	&_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
        +	&_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
        +	&_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
        +	&_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
        +	&_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
        +	&_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
        +	&_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
        +	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
        +	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
        +	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
        +
        +#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +
        +	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
        +	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
        +	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
        +	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
        +	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
        +	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
        +	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
        +	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
        +	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
        +	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
        +	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
        +	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
        +	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
        +	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
        +	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
        +	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
        +	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
        +	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
        +	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
        +	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
        +	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
        +	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
        +	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
        +	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
        +	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
        +	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
        +	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
        +	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
        +	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
        +	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
        +	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
        +	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
        +#rcon:
        +$code.=<<___;
        +	.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
        +	.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
        +	.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
        +	.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
        +___
        +$code.=<<___;
        +.align	64
        +.LAES_Td:
        +___
        +	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
        +	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
        +	&_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
        +	&_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
        +	&_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
        +	&_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
        +	&_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
        +	&_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
        +	&_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
        +	&_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
        +	&_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
        +	&_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
        +	&_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
        +	&_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
        +	&_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
        +	&_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
        +	&_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
        +	&_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
        +	&_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
        +	&_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
        +	&_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
        +	&_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
        +	&_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
        +	&_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
        +	&_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
        +	&_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
        +	&_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
        +	&_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
        +	&_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
        +	&_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
        +	&_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
        +	&_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
        +	&_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
        +	&_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
        +	&_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
        +	&_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
        +	&_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
        +	&_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
        +	&_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
        +	&_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
        +	&_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
        +	&_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
        +	&_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
        +	&_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
        +	&_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
        +	&_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
        +	&_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
        +	&_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
        +	&_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
        +	&_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
        +	&_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
        +	&_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
        +	&_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
        +	&_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
        +	&_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
        +	&_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
        +	&_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
        +	&_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
        +	&_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
        +	&_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
        +	&_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
        +	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
        +	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
        +	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
        +
        +#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +$code.=<<___;
        +	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +___
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +$code.=<<___;
        +	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +___
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +$code.=<<___;
        +	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +___
        +	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
        +	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
        +	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
        +	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
        +	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
        +	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
        +	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
        +	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
        +	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
        +	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
        +	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
        +	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
        +	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
        +	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
        +	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
        +	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
        +	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
        +	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
        +	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
        +	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
        +	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
        +	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
        +	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
        +	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
        +	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
        +	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
        +	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
        +	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
        +	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
        +	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
        +	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
        +	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
        +$code.=<<___;
        +	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
        +	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
        +.asciz  "AES for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	64
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	block_se_handler,\@abi-omnipotent
        +.align	16
        +block_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_block_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_block_prologue
        +
        +	mov	24(%rax),%rax		# pull saved real stack pointer
        +	lea	48(%rax),%rax		# adjust...
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_block_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	jmp	.Lcommon_seh_exit
        +.size	block_se_handler,.-block_se_handler
        +
        +.type	key_se_handler,\@abi-omnipotent
        +.align	16
        +key_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_key_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_key_prologue
        +
        +	lea	56(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_key_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	jmp	.Lcommon_seh_exit
        +.size	key_se_handler,.-key_se_handler
        +
        +.type	cbc_se_handler,\@abi-omnipotent
        +.align	16
        +cbc_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lcbc_prologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
        +	jb	.Lin_cbc_prologue
        +
        +	lea	.Lcbc_fast_body(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_fast_body
        +	jb	.Lin_cbc_frame_setup
        +
        +	lea	.Lcbc_slow_prologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_prologue
        +	jb	.Lin_cbc_body
        +
        +	lea	.Lcbc_slow_body(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_body
        +	jb	.Lin_cbc_frame_setup
        +
        +.Lin_cbc_body:
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lcbc_epilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lcbc_epilogue
        +	jae	.Lin_cbc_prologue
        +
        +	lea	8(%rax),%rax
        +
        +	lea	.Lcbc_popfq(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lcbc_popfq
        +	jae	.Lin_cbc_prologue
        +
        +	mov	`16-8`(%rax),%rax	# biased $_rsp
        +	lea	56(%rax),%rax
        +
        +.Lin_cbc_frame_setup:
        +	mov	-16(%rax),%rbx
        +	mov	-24(%rax),%rbp
        +	mov	-32(%rax),%r12
        +	mov	-40(%rax),%r13
        +	mov	-48(%rax),%r14
        +	mov	-56(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_cbc_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +.Lcommon_seh_exit:
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	cbc_se_handler,.-cbc_se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_AES_encrypt
        +	.rva	.LSEH_end_AES_encrypt
        +	.rva	.LSEH_info_AES_encrypt
        +
        +	.rva	.LSEH_begin_AES_decrypt
        +	.rva	.LSEH_end_AES_decrypt
        +	.rva	.LSEH_info_AES_decrypt
        +
        +	.rva	.LSEH_begin_private_AES_set_encrypt_key
        +	.rva	.LSEH_end_private_AES_set_encrypt_key
        +	.rva	.LSEH_info_private_AES_set_encrypt_key
        +
        +	.rva	.LSEH_begin_private_AES_set_decrypt_key
        +	.rva	.LSEH_end_private_AES_set_decrypt_key
        +	.rva	.LSEH_info_private_AES_set_decrypt_key
        +
        +	.rva	.LSEH_begin_AES_cbc_encrypt
        +	.rva	.LSEH_end_AES_cbc_encrypt
        +	.rva	.LSEH_info_AES_cbc_encrypt
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_AES_encrypt:
        +	.byte	9,0,0,0
        +	.rva	block_se_handler
        +	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
        +.LSEH_info_AES_decrypt:
        +	.byte	9,0,0,0
        +	.rva	block_se_handler
        +	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
        +.LSEH_info_private_AES_set_encrypt_key:
        +	.byte	9,0,0,0
        +	.rva	key_se_handler
        +	.rva	.Lenc_key_prologue,.Lenc_key_epilogue	# HandlerData[]
        +.LSEH_info_private_AES_set_decrypt_key:
        +	.byte	9,0,0,0
        +	.rva	key_se_handler
        +	.rva	.Ldec_key_prologue,.Ldec_key_epilogue	# HandlerData[]
        +.LSEH_info_AES_cbc_encrypt:
        +	.byte	9,0,0,0
        +	.rva	cbc_se_handler
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl b/vendor/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
        new file mode 100644
        index 000000000..3c8f6c19e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
        @@ -0,0 +1,1250 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# June 2011
        +#
        +# This is AESNI-CBC+SHA1 "stitch" implementation. The idea, as spelled
        +# in http://download.intel.com/design/intarch/papers/323686.pdf, is
        +# that since AESNI-CBC encrypt exhibit *very* low instruction-level
        +# parallelism, interleaving it with another algorithm would allow to
        +# utilize processor resources better and achieve better performance.
        +# SHA1 instruction sequences(*) are taken from sha1-x86_64.pl and
        +# AESNI code is weaved into it. Below are performance numbers in
        +# cycles per processed byte, less is better, for standalone AESNI-CBC
        +# encrypt, sum of the latter and standalone SHA1, and "stitched"
        +# subroutine:
        +#
        +#		AES-128-CBC	+SHA1		stitch      gain
        +# Westmere	3.77[+5.6]	9.37		6.65	    +41%
        +# Sandy Bridge	5.05[+5.2(6.3)]	10.25(11.35)	6.16(7.08)  +67%(+60%)
        +#
        +#		AES-192-CBC
        +# Westmere	4.51		10.11		6.97	    +45%
        +# Sandy Bridge	6.05		11.25(12.35)	6.34(7.27)  +77%(+70%)
        +#
        +#		AES-256-CBC
        +# Westmere	5.25		10.85		7.25	    +50%
        +# Sandy Bridge	7.05		12.25(13.35)	7.06(7.70)  +74%(+73%)
        +#
        +# (*)	There are two code paths: SSSE3 and AVX. See sha1-568.pl for
        +#	background information. Above numbers in parentheses are SSSE3
        +#	results collected on AVX-capable CPU, i.e. apply on OSes that
        +#	don't support AVX.
        +#
        +# Needless to mention that it makes no sense to implement "stitched"
        +# *decrypt* subroutine. Because *both* AESNI-CBC decrypt and SHA1
        +# fully utilize parallelism, so stitching would not give any gain
        +# anyway. Well, there might be some, e.g. because of better cache
        +# locality... For reference, here are performance results for
        +# standalone AESNI-CBC decrypt:
        +#
        +#		AES-128-CBC	AES-192-CBC	AES-256-CBC
        +# Westmere	1.31		1.55		1.80
        +# Sandy Bridge	0.93		1.06		1.22
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
        +		=~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
        +	   $1>=2.19);
        +$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
        +	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
        +	   $1>=2.09);
        +$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
        +	   `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
        +	   $1>=10);
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +# void aesni_cbc_sha1_enc(const void *inp,
        +#			void *out,
        +#			size_t length,
        +#			const AES_KEY *key,
        +#			unsigned char *iv,
        +#			SHA_CTX *ctx,
        +#			const void *in0);
        +
        +$code.=<<___;
        +.text
        +.extern	OPENSSL_ia32cap_P
        +
        +.globl	aesni_cbc_sha1_enc
        +.type	aesni_cbc_sha1_enc,\@abi-omnipotent
        +.align	16
        +aesni_cbc_sha1_enc:
        +	# caller should check for SSSE3 and AES-NI bits
        +	mov	OPENSSL_ia32cap_P+0(%rip),%r10d
        +	mov	OPENSSL_ia32cap_P+4(%rip),%r11d
        +___
        +$code.=<<___ if ($avx);
        +	and	\$`1<<28`,%r11d		# mask AVX bit
        +	and	\$`1<<30`,%r10d		# mask "Intel CPU" bit
        +	or	%r11d,%r10d
        +	cmp	\$`1<<28|1<<30`,%r10d
        +	je	aesni_cbc_sha1_enc_avx
        +___
        +$code.=<<___;
        +	jmp	aesni_cbc_sha1_enc_ssse3
        +	ret
        +.size	aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc
        +___
        +
        +my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
        +
        +my $Xi=4;
        +my @X=map("%xmm$_",(4..7,0..3));
        +my @Tx=map("%xmm$_",(8..10));
        +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
        +my @T=("%esi","%edi");
        +my $j=0; my $jj=0; my $r=0; my $sn=0;
        +my $K_XX_XX="%r11";
        +my ($iv,$in,$rndkey0)=map("%xmm$_",(11..13));
        +my @rndkey=("%xmm14","%xmm15");
        +
        +sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
        +{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
        +  my $arg = pop;
        +    $arg = "\$$arg" if ($arg*1 eq $arg);
        +    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
        +}
        +
        +my $_rol=sub { &rol(@_) };
        +my $_ror=sub { &ror(@_) };
        +
        +$code.=<<___;
        +.type	aesni_cbc_sha1_enc_ssse3,\@function,6
        +.align	16
        +aesni_cbc_sha1_enc_ssse3:
        +	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
        +	#shr	\$6,$len			# debugging artefact
        +	#jz	.Lepilogue_ssse3		# debugging artefact
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	`-104-($win64?10*16:0)`(%rsp),%rsp
        +	#mov	$in0,$inp			# debugging artefact
        +	#lea	64(%rsp),$ctx			# debugging artefact
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,96+0(%rsp)
        +	movaps	%xmm7,96+16(%rsp)
        +	movaps	%xmm8,96+32(%rsp)
        +	movaps	%xmm9,96+48(%rsp)
        +	movaps	%xmm10,96+64(%rsp)
        +	movaps	%xmm11,96+80(%rsp)
        +	movaps	%xmm12,96+96(%rsp)
        +	movaps	%xmm13,96+112(%rsp)
        +	movaps	%xmm14,96+128(%rsp)
        +	movaps	%xmm15,96+144(%rsp)
        +.Lprologue_ssse3:
        +___
        +$code.=<<___;
        +	mov	$in0,%r12			# reassign arguments
        +	mov	$out,%r13
        +	mov	$len,%r14
        +	mov	$key,%r15
        +	movdqu	($ivp),$iv			# load IV
        +	mov	$ivp,88(%rsp)			# save $ivp
        +___
        +my ($in0,$out,$len,$key)=map("%r$_",(12..15));	# reassign arguments
        +my $rounds="${ivp}d";
        +$code.=<<___;
        +	shl	\$6,$len
        +	sub	$in0,$out
        +	mov	240($key),$rounds
        +	add	$inp,$len		# end of input
        +
        +	lea	K_XX_XX(%rip),$K_XX_XX
        +	mov	0($ctx),$A		# load context
        +	mov	4($ctx),$B
        +	mov	8($ctx),$C
        +	mov	12($ctx),$D
        +	mov	$B,@T[0]		# magic seed
        +	mov	16($ctx),$E
        +
        +	movdqa	64($K_XX_XX),@X[2]	# pbswap mask
        +	movdqa	0($K_XX_XX),@Tx[1]	# K_00_19
        +	movdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
        +	movdqu	16($inp),@X[-3&7]
        +	movdqu	32($inp),@X[-2&7]
        +	movdqu	48($inp),@X[-1&7]
        +	pshufb	@X[2],@X[-4&7]		# byte swap
        +	add	\$64,$inp
        +	pshufb	@X[2],@X[-3&7]
        +	pshufb	@X[2],@X[-2&7]
        +	pshufb	@X[2],@X[-1&7]
        +	paddd	@Tx[1],@X[-4&7]		# add K_00_19
        +	paddd	@Tx[1],@X[-3&7]
        +	paddd	@Tx[1],@X[-2&7]
        +	movdqa	@X[-4&7],0(%rsp)	# X[]+K xfer to IALU
        +	psubd	@Tx[1],@X[-4&7]		# restore X[]
        +	movdqa	@X[-3&7],16(%rsp)
        +	psubd	@Tx[1],@X[-3&7]
        +	movdqa	@X[-2&7],32(%rsp)
        +	psubd	@Tx[1],@X[-2&7]
        +	movups	($key),$rndkey0		# $key[0]
        +	movups	16($key),$rndkey[0]	# forward reference
        +	jmp	.Loop_ssse3
        +___
        +
        +my $aesenc=sub {
        +  use integer;
        +  my ($n,$k)=($r/10,$r%10);
        +    if ($k==0) {
        +      $code.=<<___;
        +	movups		`16*$n`($in0),$in		# load input
        +	xorps		$rndkey0,$in
        +___
        +      $code.=<<___ if ($n);
        +	movups		$iv,`16*($n-1)`($out,$in0)	# write output
        +___
        +      $code.=<<___;
        +	xorps		$in,$iv
        +	aesenc		$rndkey[0],$iv
        +	movups		`32+16*$k`($key),$rndkey[1]
        +___
        +    } elsif ($k==9) {
        +      $sn++;
        +      $code.=<<___;
        +	cmp		\$11,$rounds
        +	jb		.Laesenclast$sn
        +	movups		`32+16*($k+0)`($key),$rndkey[1]
        +	aesenc		$rndkey[0],$iv
        +	movups		`32+16*($k+1)`($key),$rndkey[0]
        +	aesenc		$rndkey[1],$iv
        +	je		.Laesenclast$sn
        +	movups		`32+16*($k+2)`($key),$rndkey[1]
        +	aesenc		$rndkey[0],$iv
        +	movups		`32+16*($k+3)`($key),$rndkey[0]
        +	aesenc		$rndkey[1],$iv
        +.Laesenclast$sn:
        +	aesenclast	$rndkey[0],$iv
        +	movups		16($key),$rndkey[1]		# forward reference
        +___
        +    } else {
        +      $code.=<<___;
        +	aesenc		$rndkey[0],$iv
        +	movups		`32+16*$k`($key),$rndkey[1]
        +___
        +    }
        +    $r++;	unshift(@rndkey,pop(@rndkey));
        +};
        +
        +sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&movdqa	(@X[0],@X[-3&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(@Tx[0],@X[-1&7]);
        +	&palignr(@X[0],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &paddd	(@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&psrldq	(@Tx[0],4);		# "X[-3]", 3 dwords
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&pxor	(@X[0],@X[-4&7]);	# "X[0]"^="X[-16]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&movdqa	(@Tx[2],@X[0]);
        +	&movdqa	(@Tx[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pslldq	(@Tx[2],12);		# "X[0]"<<96, extract one dword
        +	&paddd	(@X[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&psrld	(@Tx[0],31);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(@Tx[1],@Tx[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&psrld	(@Tx[2],30);
        +	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=1
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pslld	(@Tx[1],2);
        +	&pxor	(@X[0],@Tx[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)");	# K_XX_XX
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@Tx[1]);		# "X[0]"^=("X[0]">>96)<<<2
        +
        +	 foreach (@insns) { eval; }	# remaining instructions [if any]
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xupdate_ssse3_32_79()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&movdqa	(@Tx[0],@X[-1&7])	if ($Xi==8);
        +	 eval(shift(@insns));		# body_20_39
        +	&pxor	(@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
        +	&palignr(@Tx[0],@X[-2&7],8);	# compose "X[-6]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&pxor	(@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns))	if (@insns[0] !~ /&ro[rl]/);
        +	if ($Xi%5) {
        +	  &movdqa	(@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
        +	} else {			# ... or load next one
        +	  &movdqa	(@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
        +	}
        +	  &paddd	(@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&movdqa	(@Tx[0],@X[0]);
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&pslld	(@X[0],2);
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	&psrld	(@Tx[0],30);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=2
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	  &movdqa	(@Tx[1],@X[0])	if ($Xi<19);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xuplast_ssse3_80()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	  &paddd	(@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
        +
        +	 foreach (@insns) { eval; }		# remaining instructions
        +
        +	&cmp	($inp,$len);
        +	&je	(".Ldone_ssse3");
        +
        +	unshift(@Tx,pop(@Tx));
        +
        +	&movdqa	(@X[2],"64($K_XX_XX)");		# pbswap mask
        +	&movdqa	(@Tx[1],"0($K_XX_XX)");		# K_00_19
        +	&movdqu	(@X[-4&7],"0($inp)");		# load input
        +	&movdqu	(@X[-3&7],"16($inp)");
        +	&movdqu	(@X[-2&7],"32($inp)");
        +	&movdqu	(@X[-1&7],"48($inp)");
        +	&pshufb	(@X[-4&7],@X[2]);		# byte swap
        +	&add	($inp,64);
        +
        +  $Xi=0;
        +}
        +
        +sub Xloop_ssse3()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&pshufb	(@X[($Xi-3)&7],@X[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&paddd	(@X[($Xi-4)&7],@Tx[1]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&psubd	(@X[($Xi-4)&7],@Tx[1]);
        +
        +	foreach (@insns) { eval; }
        +  $Xi++;
        +}
        +
        +sub Xtail_ssse3()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	foreach (@insns) { eval; }
        +}
        +
        +sub body_00_19 () {
        +  use integer;
        +  my ($k,$n);
        +  my @r=(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&add	($e,eval(4*($j&15))."(%rsp)");',	# X[]+K xfer
        +	'&xor	($c,$d);',
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&and	(@T[0],$c);',	# ($b&($c^$d))
        +	'&xor	($c,$d);',	# restore $c
        +	'&xor	(@T[0],$d);',
        +	'&add	($e,$a);',
        +	'&$_ror	($b,$j?7:2);',	# $b>>>2
        +	'&add	($e,@T[0]);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +	$n = scalar(@r);
        +	$k = (($jj+1)*12/20)*20*$n/12;	# 12 aesencs per these 20 rounds
        +	@r[$k%$n].='&$aesenc();'	if ($jj==$k/$n);
        +	$jj++;
        +    return @r;
        +}
        +
        +sub body_20_39 () {
        +  use integer;
        +  my ($k,$n);
        +  my @r=(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&add	($e,eval(4*($j++&15))."(%rsp)");',	# X[]+K xfer
        +	'&xor	(@T[0],$d);',	# ($b^$d)
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&xor	(@T[0],$c);',	# ($b^$d^$c)
        +	'&add	($e,$a);',
        +	'&$_ror	($b,7);',	# $b>>>2
        +	'&add	($e,@T[0]);'	.'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +	$n = scalar(@r);
        +	$k = (($jj+1)*8/20)*20*$n/8;	# 8 aesencs per these 20 rounds
        +	@r[$k%$n].='&$aesenc();'	if ($jj==$k/$n);
        +	$jj++;
        +    return @r;
        +}
        +
        +sub body_40_59 () {
        +  use integer;
        +  my ($k,$n);
        +  my @r=(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&mov	(@T[1],$c);',
        +	'&xor	($c,$d);',
        +	'&add	($e,eval(4*($j++&15))."(%rsp)");',	# X[]+K xfer
        +	'&and	(@T[1],$d);',
        +	'&and	(@T[0],$c);',	# ($b&($c^$d))
        +	'&$_ror	($b,7);',	# $b>>>2
        +	'&add	($e,@T[1]);',
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&add	($e,@T[0]);',
        +	'&xor	($c,$d);',	# restore $c
        +	'&add	($e,$a);'	.'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +	$n = scalar(@r);
        +	$k=(($jj+1)*12/20)*20*$n/12;	# 12 aesencs per these 20 rounds
        +	@r[$k%$n].='&$aesenc();'	if ($jj==$k/$n);
        +	$jj++;
        +    return @r;
        +}
        +$code.=<<___;
        +.align	16
        +.Loop_ssse3:
        +___
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_32_79(\&body_00_19);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xuplast_ssse3_80(\&body_20_39);	# can jump to "done"
        +
        +				$saved_j=$j; @saved_V=@V;
        +				$saved_r=$r; @saved_rndkey=@rndkey;
        +
        +	&Xloop_ssse3(\&body_20_39);
        +	&Xloop_ssse3(\&body_20_39);
        +	&Xloop_ssse3(\&body_20_39);
        +
        +$code.=<<___;
        +	movups	$iv,48($out,$in0)		# write output
        +	lea	64($in0),$in0
        +
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	add	12($ctx),$D
        +	mov	$A,0($ctx)
        +	add	16($ctx),$E
        +	mov	@T[0],4($ctx)
        +	mov	@T[0],$B			# magic seed
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +	jmp	.Loop_ssse3
        +
        +.align	16
        +.Ldone_ssse3:
        +___
        +				$jj=$j=$saved_j; @V=@saved_V;
        +				$r=$saved_r;     @rndkey=@saved_rndkey;
        +
        +	&Xtail_ssse3(\&body_20_39);
        +	&Xtail_ssse3(\&body_20_39);
        +	&Xtail_ssse3(\&body_20_39);
        +
        +$code.=<<___;
        +	movups	$iv,48($out,$in0)		# write output
        +	mov	88(%rsp),$ivp			# restore $ivp
        +
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	mov	$A,0($ctx)
        +	add	12($ctx),$D
        +	mov	@T[0],4($ctx)
        +	add	16($ctx),$E
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +	movups	$iv,($ivp)			# write IV
        +___
        +$code.=<<___ if ($win64);
        +	movaps	96+0(%rsp),%xmm6
        +	movaps	96+16(%rsp),%xmm7
        +	movaps	96+32(%rsp),%xmm8
        +	movaps	96+48(%rsp),%xmm9
        +	movaps	96+64(%rsp),%xmm10
        +	movaps	96+80(%rsp),%xmm11
        +	movaps	96+96(%rsp),%xmm12
        +	movaps	96+112(%rsp),%xmm13
        +	movaps	96+128(%rsp),%xmm14
        +	movaps	96+144(%rsp),%xmm15
        +___
        +$code.=<<___;
        +	lea	`104+($win64?10*16:0)`(%rsp),%rsi
        +	mov	0(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lepilogue_ssse3:
        +	ret
        +.size	aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3
        +___
        +
        +$j=$jj=$r=$sn=0;
        +
        +if ($avx) {
        +my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
        +
        +my $Xi=4;
        +my @X=map("%xmm$_",(4..7,0..3));
        +my @Tx=map("%xmm$_",(8..10));
        +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
        +my @T=("%esi","%edi");
        +
        +my $_rol=sub { &shld(@_[0],@_) };
        +my $_ror=sub { &shrd(@_[0],@_) };
        +
        +$code.=<<___;
        +.type	aesni_cbc_sha1_enc_avx,\@function,6
        +.align	16
        +aesni_cbc_sha1_enc_avx:
        +	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
        +	#shr	\$6,$len			# debugging artefact
        +	#jz	.Lepilogue_avx			# debugging artefact
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	`-104-($win64?10*16:0)`(%rsp),%rsp
        +	#mov	$in0,$inp			# debugging artefact
        +	#lea	64(%rsp),$ctx			# debugging artefact
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,96+0(%rsp)
        +	movaps	%xmm7,96+16(%rsp)
        +	movaps	%xmm8,96+32(%rsp)
        +	movaps	%xmm9,96+48(%rsp)
        +	movaps	%xmm10,96+64(%rsp)
        +	movaps	%xmm11,96+80(%rsp)
        +	movaps	%xmm12,96+96(%rsp)
        +	movaps	%xmm13,96+112(%rsp)
        +	movaps	%xmm14,96+128(%rsp)
        +	movaps	%xmm15,96+144(%rsp)
        +.Lprologue_avx:
        +___
        +$code.=<<___;
        +	vzeroall
        +	mov	$in0,%r12			# reassign arguments
        +	mov	$out,%r13
        +	mov	$len,%r14
        +	mov	$key,%r15
        +	vmovdqu	($ivp),$iv			# load IV
        +	mov	$ivp,88(%rsp)			# save $ivp
        +___
        +my ($in0,$out,$len,$key)=map("%r$_",(12..15));	# reassign arguments
        +my $rounds="${ivp}d";
        +$code.=<<___;
        +	shl	\$6,$len
        +	sub	$in0,$out
        +	mov	240($key),$rounds
        +	add	\$112,$key		# size optimization
        +	add	$inp,$len		# end of input
        +
        +	lea	K_XX_XX(%rip),$K_XX_XX
        +	mov	0($ctx),$A		# load context
        +	mov	4($ctx),$B
        +	mov	8($ctx),$C
        +	mov	12($ctx),$D
        +	mov	$B,@T[0]		# magic seed
        +	mov	16($ctx),$E
        +
        +	vmovdqa	64($K_XX_XX),@X[2]	# pbswap mask
        +	vmovdqa	0($K_XX_XX),@Tx[1]	# K_00_19
        +	vmovdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
        +	vmovdqu	16($inp),@X[-3&7]
        +	vmovdqu	32($inp),@X[-2&7]
        +	vmovdqu	48($inp),@X[-1&7]
        +	vpshufb	@X[2],@X[-4&7],@X[-4&7]	# byte swap
        +	add	\$64,$inp
        +	vpshufb	@X[2],@X[-3&7],@X[-3&7]
        +	vpshufb	@X[2],@X[-2&7],@X[-2&7]
        +	vpshufb	@X[2],@X[-1&7],@X[-1&7]
        +	vpaddd	@Tx[1],@X[-4&7],@X[0]	# add K_00_19
        +	vpaddd	@Tx[1],@X[-3&7],@X[1]
        +	vpaddd	@Tx[1],@X[-2&7],@X[2]
        +	vmovdqa	@X[0],0(%rsp)		# X[]+K xfer to IALU
        +	vmovdqa	@X[1],16(%rsp)
        +	vmovdqa	@X[2],32(%rsp)
        +	vmovups	-112($key),$rndkey0	# $key[0]
        +	vmovups	16-112($key),$rndkey[0]	# forward reference
        +	jmp	.Loop_avx
        +___
        +
        +my $aesenc=sub {
        +  use integer;
        +  my ($n,$k)=($r/10,$r%10);
        +    if ($k==0) {
        +      $code.=<<___;
        +	vmovups		`16*$n`($in0),$in		# load input
        +	vxorps		$rndkey0,$in,$in
        +___
        +      $code.=<<___ if ($n);
        +	vmovups		$iv,`16*($n-1)`($out,$in0)	# write output
        +___
        +      $code.=<<___;
        +	vxorps		$in,$iv,$iv
        +	vaesenc		$rndkey[0],$iv,$iv
        +	vmovups		`32+16*$k-112`($key),$rndkey[1]
        +___
        +    } elsif ($k==9) {
        +      $sn++;
        +      $code.=<<___;
        +	cmp		\$11,$rounds
        +	jb		.Lvaesenclast$sn
        +	vaesenc		$rndkey[0],$iv,$iv
        +	vmovups		`32+16*($k+0)-112`($key),$rndkey[1]
        +	vaesenc		$rndkey[1],$iv,$iv
        +	vmovups		`32+16*($k+1)-112`($key),$rndkey[0]
        +	je		.Lvaesenclast$sn
        +	vaesenc		$rndkey[0],$iv,$iv
        +	vmovups		`32+16*($k+2)-112`($key),$rndkey[1]
        +	vaesenc		$rndkey[1],$iv,$iv
        +	vmovups		`32+16*($k+3)-112`($key),$rndkey[0]
        +.Lvaesenclast$sn:
        +	vaesenclast	$rndkey[0],$iv,$iv
        +	vmovups		16-112($key),$rndkey[1]		# forward reference
        +___
        +    } else {
        +      $code.=<<___;
        +	vaesenc		$rndkey[0],$iv,$iv
        +	vmovups		`32+16*$k-112`($key),$rndkey[1]
        +___
        +    }
        +    $r++;	unshift(@rndkey,pop(@rndkey));
        +};
        +
        +sub Xupdate_avx_16_31()		# recall that $Xi starts wtih 4
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &vpaddd	(@Tx[1],@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpsrldq(@Tx[0],@X[-1&7],4);	# "X[-3]", 3 dwords
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpsrld	(@Tx[0],@X[0],31);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpslldq(@Tx[2],@X[0],12);		# "X[0]"<<96, extract one dword
        +	&vpaddd	(@X[0],@X[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpsrld	(@Tx[1],@Tx[2],30);
        +	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=1
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpslld	(@Tx[2],@Tx[2],2);
        +	&vpxor	(@X[0],@X[0],@Tx[1]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@Tx[2]);		# "X[0]"^=("X[0]">>96)<<<2
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &vmovdqa	(@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)");	# K_XX_XX
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +
        +	 foreach (@insns) { eval; }	# remaining instructions [if any]
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xupdate_avx_32_79()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
        +	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"="X[-32]"^"X[-16]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&vpxor	(@X[0],@X[0],@X[-7&7]);		# "X[0]"^="X[-28]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns))	if (@insns[0] !~ /&ro[rl]/);
        +	if ($Xi%5) {
        +	  &vmovdqa	(@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
        +	} else {			# ... or load next one
        +	  &vmovdqa	(@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
        +	}
        +	  &vpaddd	(@Tx[1],@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&vpsrld	(@Tx[0],@X[0],30);
        +	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpslld	(@X[0],@X[0],2);
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=2
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	  &vmovdqa	(@Tx[1],@X[0])	if ($Xi<19);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xuplast_avx_80()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	  &vpaddd	(@Tx[1],@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
        +
        +	 foreach (@insns) { eval; }		# remaining instructions
        +
        +	&cmp	($inp,$len);
        +	&je	(".Ldone_avx");
        +
        +	unshift(@Tx,pop(@Tx));
        +
        +	&vmovdqa(@X[2],"64($K_XX_XX)");		# pbswap mask
        +	&vmovdqa(@Tx[1],"0($K_XX_XX)");		# K_00_19
        +	&vmovdqu(@X[-4&7],"0($inp)");		# load input
        +	&vmovdqu(@X[-3&7],"16($inp)");
        +	&vmovdqu(@X[-2&7],"32($inp)");
        +	&vmovdqu(@X[-1&7],"48($inp)");
        +	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);	# byte swap
        +	&add	($inp,64);
        +
        +  $Xi=0;
        +}
        +
        +sub Xloop_avx()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpaddd	(@X[$Xi&7],@X[($Xi-4)&7],@Tx[1]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	foreach (@insns) { eval; }
        +  $Xi++;
        +}
        +
        +sub Xtail_avx()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	foreach (@insns) { eval; }
        +}
        +
        +$code.=<<___;
        +.align	16
        +.Loop_avx:
        +___
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_32_79(\&body_00_19);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xuplast_avx_80(\&body_20_39);	# can jump to "done"
        +
        +				$saved_j=$j; @saved_V=@V;
        +				$saved_r=$r; @saved_rndkey=@rndkey;
        +
        +	&Xloop_avx(\&body_20_39);
        +	&Xloop_avx(\&body_20_39);
        +	&Xloop_avx(\&body_20_39);
        +
        +$code.=<<___;
        +	vmovups	$iv,48($out,$in0)		# write output
        +	lea	64($in0),$in0
        +
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	add	12($ctx),$D
        +	mov	$A,0($ctx)
        +	add	16($ctx),$E
        +	mov	@T[0],4($ctx)
        +	mov	@T[0],$B			# magic seed
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +	jmp	.Loop_avx
        +
        +.align	16
        +.Ldone_avx:
        +___
        +				$jj=$j=$saved_j; @V=@saved_V;
        +				$r=$saved_r;     @rndkey=@saved_rndkey;
        +
        +	&Xtail_avx(\&body_20_39);
        +	&Xtail_avx(\&body_20_39);
        +	&Xtail_avx(\&body_20_39);
        +
        +$code.=<<___;
        +	vmovups	$iv,48($out,$in0)		# write output
        +	mov	88(%rsp),$ivp			# restore $ivp
        +
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	mov	$A,0($ctx)
        +	add	12($ctx),$D
        +	mov	@T[0],4($ctx)
        +	add	16($ctx),$E
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +	vmovups	$iv,($ivp)			# write IV
        +	vzeroall
        +___
        +$code.=<<___ if ($win64);
        +	movaps	96+0(%rsp),%xmm6
        +	movaps	96+16(%rsp),%xmm7
        +	movaps	96+32(%rsp),%xmm8
        +	movaps	96+48(%rsp),%xmm9
        +	movaps	96+64(%rsp),%xmm10
        +	movaps	96+80(%rsp),%xmm11
        +	movaps	96+96(%rsp),%xmm12
        +	movaps	96+112(%rsp),%xmm13
        +	movaps	96+128(%rsp),%xmm14
        +	movaps	96+144(%rsp),%xmm15
        +___
        +$code.=<<___;
        +	lea	`104+($win64?10*16:0)`(%rsp),%rsi
        +	mov	0(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lepilogue_avx:
        +	ret
        +.size	aesni_cbc_sha1_enc_avx,.-aesni_cbc_sha1_enc_avx
        +___
        +}
        +$code.=<<___;
        +.align	64
        +K_XX_XX:
        +.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
        +.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
        +.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
        +.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
        +.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap mask
        +
        +.asciz	"AESNI-CBC+SHA1 stitch for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	64
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	ssse3_handler,\@abi-omnipotent
        +.align	16
        +ssse3_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lcommon_seh_tail
        +
        +	lea	96(%rax),%rsi
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$20,%ecx
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	`104+10*16`(%rax),%rax	# adjust stack pointer
        +
        +	mov	0(%rax),%r15
        +	mov	8(%rax),%r14
        +	mov	16(%rax),%r13
        +	mov	24(%rax),%r12
        +	mov	32(%rax),%rbp
        +	mov	40(%rax),%rbx
        +	lea	48(%rax),%rax
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lcommon_seh_tail:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	ssse3_handler,.-ssse3_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_aesni_cbc_sha1_enc_ssse3
        +	.rva	.LSEH_end_aesni_cbc_sha1_enc_ssse3
        +	.rva	.LSEH_info_aesni_cbc_sha1_enc_ssse3
        +___
        +$code.=<<___ if ($avx);
        +	.rva	.LSEH_begin_aesni_cbc_sha1_enc_avx
        +	.rva	.LSEH_end_aesni_cbc_sha1_enc_avx
        +	.rva	.LSEH_info_aesni_cbc_sha1_enc_avx
        +___
        +$code.=<<___;
        +.section	.xdata
        +.align	8
        +.LSEH_info_aesni_cbc_sha1_enc_ssse3:
        +	.byte	9,0,0,0
        +	.rva	ssse3_handler
        +	.rva	.Lprologue_ssse3,.Lepilogue_ssse3	# HandlerData[]
        +___
        +$code.=<<___ if ($avx);
        +.LSEH_info_aesni_cbc_sha1_enc_avx:
        +	.byte	9,0,0,0
        +	.rva	ssse3_handler
        +	.rva	.Lprologue_avx,.Lepilogue_avx		# HandlerData[]
        +___
        +}
        +
        +####################################################################
        +sub rex {
        +  local *opcode=shift;
        +  my ($dst,$src)=@_;
        +  my $rex=0;
        +
        +    $rex|=0x04			if($dst>=8);
        +    $rex|=0x01			if($src>=8);
        +    push @opcode,$rex|0x40	if($rex);
        +}
        +
        +sub aesni {
        +  my $line=shift;
        +  my @opcode=(0x66);
        +
        +    if ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
        +	my %opcodelet = (
        +		"aesenc" => 0xdc,	"aesenclast" => 0xdd
        +	);
        +	return undef if (!defined($opcodelet{$1}));
        +	rex(\@opcode,$3,$2);
        +	push @opcode,0x0f,0x38,$opcodelet{$1};
        +	push @opcode,0xc0|($2&7)|(($3&7)<<3);	# ModR/M
        +	return ".byte\t".join(',',@opcode);
        +    }
        +    return $line;
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aesni-x86.pl b/vendor/openssl/openssl/crypto/aes/asm/aesni-x86.pl
        new file mode 100644
        index 000000000..3dc345b58
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aesni-x86.pl
        @@ -0,0 +1,2189 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# This module implements support for Intel AES-NI extension. In
        +# OpenSSL context it's used with Intel engine, but can also be used as
        +# drop-in replacement for crypto/aes/asm/aes-586.pl [see below for
        +# details].
        +#
        +# Performance.
        +#
        +# To start with see corresponding paragraph in aesni-x86_64.pl...
        +# Instead of filling table similar to one found there I've chosen to
        +# summarize *comparison* results for raw ECB, CTR and CBC benchmarks.
        +# The simplified table below represents 32-bit performance relative
        +# to 64-bit one in every given point. Ratios vary for different
        +# encryption modes, therefore interval values.
        +#
        +#	16-byte     64-byte     256-byte    1-KB        8-KB
        +#	53-67%      67-84%      91-94%      95-98%      97-99.5%
        +#
        +# Lower ratios for smaller block sizes are perfectly understandable,
        +# because function call overhead is higher in 32-bit mode. Largest
        +# 8-KB block performance is virtually same: 32-bit code is less than
        +# 1% slower for ECB, CBC and CCM, and ~3% slower otherwise.
        +
        +# January 2011
        +#
        +# See aesni-x86_64.pl for details. Unlike x86_64 version this module
        +# interleaves at most 6 aes[enc|dec] instructions, because there are
        +# not enough registers for 8x interleave [which should be optimal for
        +# Sandy Bridge]. Actually, performance results for 6x interleave
        +# factor presented in aesni-x86_64.pl (except for CTR) are for this
        +# module.
        +
        +# April 2011
        +#
        +# Add aesni_xts_[en|de]crypt. Westmere spends 1.50 cycles processing
        +# one byte out of 8KB with 128-bit key, Sandy Bridge - 1.09.
        +
        +$PREFIX="aesni";	# if $PREFIX is set to "AES", the script
        +			# generates drop-in replacement for
        +			# crypto/aes/asm/aes-586.pl:-)
        +$inline=1;		# inline _aesni_[en|de]crypt
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0);
        +
        +if ($PREFIX eq "aesni")	{ $movekey=*movups; }
        +else			{ $movekey=*movups; }
        +
        +$len="eax";
        +$rounds="ecx";
        +$key="edx";
        +$inp="esi";
        +$out="edi";
        +$rounds_="ebx";	# backup copy for $rounds
        +$key_="ebp";	# backup copy for $key
        +
        +$rndkey0="xmm0";
        +$rndkey1="xmm1";
        +$inout0="xmm2";
        +$inout1="xmm3";
        +$inout2="xmm4";
        +$inout3="xmm5";	$in1="xmm5";
        +$inout4="xmm6";	$in0="xmm6";
        +$inout5="xmm7";	$ivec="xmm7";
        +
        +# AESNI extenstion
        +sub aeskeygenassist
        +{ my($dst,$src,$imm)=@_;
        +    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
        +    {	&data_byte(0x66,0x0f,0x3a,0xdf,0xc0|($1<<3)|$2,$imm);	}
        +}
        +sub aescommon
        +{ my($opcodelet,$dst,$src)=@_;
        +    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
        +    {	&data_byte(0x66,0x0f,0x38,$opcodelet,0xc0|($1<<3)|$2);}
        +}
        +sub aesimc	{ aescommon(0xdb,@_); }
        +sub aesenc	{ aescommon(0xdc,@_); }
        +sub aesenclast	{ aescommon(0xdd,@_); }
        +sub aesdec	{ aescommon(0xde,@_); }
        +sub aesdeclast	{ aescommon(0xdf,@_); }
        +
        +# Inline version of internal aesni_[en|de]crypt1
        +{ my $sn;
        +sub aesni_inline_generate1
        +{ my ($p,$inout,$ivec)=@_; $inout=$inout0 if (!defined($inout));
        +  $sn++;
        +
        +    &$movekey		($rndkey0,&QWP(0,$key));
        +    &$movekey		($rndkey1,&QWP(16,$key));
        +    &xorps		($ivec,$rndkey0)	if (defined($ivec));
        +    &lea		($key,&DWP(32,$key));
        +    &xorps		($inout,$ivec)		if (defined($ivec));
        +    &xorps		($inout,$rndkey0)	if (!defined($ivec));
        +    &set_label("${p}1_loop_$sn");
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&dec		($rounds);
        +	&$movekey	($rndkey1,&QWP(0,$key));
        +	&lea		($key,&DWP(16,$key));
        +    &jnz		(&label("${p}1_loop_$sn"));
        +    eval"&aes${p}last	($inout,$rndkey1)";
        +}}
        +
        +sub aesni_generate1	# fully unrolled loop
        +{ my ($p,$inout)=@_; $inout=$inout0 if (!defined($inout));
        +
        +    &function_begin_B("_aesni_${p}rypt1");
        +	&movups		($rndkey0,&QWP(0,$key));
        +	&$movekey	($rndkey1,&QWP(0x10,$key));
        +	&xorps		($inout,$rndkey0);
        +	&$movekey	($rndkey0,&QWP(0x20,$key));
        +	&lea		($key,&DWP(0x30,$key));
        +	&cmp		($rounds,11);
        +	&jb		(&label("${p}128"));
        +	&lea		($key,&DWP(0x20,$key));
        +	&je		(&label("${p}192"));
        +	&lea		($key,&DWP(0x20,$key));
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(-0x40,$key));
        +	eval"&aes${p}	($inout,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(-0x30,$key));
        +    &set_label("${p}192");
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(-0x20,$key));
        +	eval"&aes${p}	($inout,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(-0x10,$key));
        +    &set_label("${p}128");
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(0,$key));
        +	eval"&aes${p}	($inout,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0x10,$key));
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(0x20,$key));
        +	eval"&aes${p}	($inout,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0x30,$key));
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(0x40,$key));
        +	eval"&aes${p}	($inout,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0x50,$key));
        +	eval"&aes${p}	($inout,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(0x60,$key));
        +	eval"&aes${p}	($inout,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0x70,$key));
        +	eval"&aes${p}	($inout,$rndkey1)";
        +    eval"&aes${p}last	($inout,$rndkey0)";
        +    &ret();
        +    &function_end_B("_aesni_${p}rypt1");
        +}
        +
        +# void $PREFIX_encrypt (const void *inp,void *out,const AES_KEY *key);
        +&aesni_generate1("enc") if (!$inline);
        +&function_begin_B("${PREFIX}_encrypt");
        +	&mov	("eax",&wparam(0));
        +	&mov	($key,&wparam(2));
        +	&movups	($inout0,&QWP(0,"eax"));
        +	&mov	($rounds,&DWP(240,$key));
        +	&mov	("eax",&wparam(1));
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +	&movups	(&QWP(0,"eax"),$inout0);
        +	&ret	();
        +&function_end_B("${PREFIX}_encrypt");
        +
        +# void $PREFIX_decrypt (const void *inp,void *out,const AES_KEY *key);
        +&aesni_generate1("dec") if(!$inline);
        +&function_begin_B("${PREFIX}_decrypt");
        +	&mov	("eax",&wparam(0));
        +	&mov	($key,&wparam(2));
        +	&movups	($inout0,&QWP(0,"eax"));
        +	&mov	($rounds,&DWP(240,$key));
        +	&mov	("eax",&wparam(1));
        +	if ($inline)
        +	{   &aesni_inline_generate1("dec");	}
        +	else
        +	{   &call	("_aesni_decrypt1");	}
        +	&movups	(&QWP(0,"eax"),$inout0);
        +	&ret	();
        +&function_end_B("${PREFIX}_decrypt");
        +
        +# _aesni_[en|de]cryptN are private interfaces, N denotes interleave
        +# factor. Why 3x subroutine were originally used in loops? Even though
        +# aes[enc|dec] latency was originally 6, it could be scheduled only
        +# every *2nd* cycle. Thus 3x interleave was the one providing optimal
        +# utilization, i.e. when subroutine's throughput is virtually same as
        +# of non-interleaved subroutine [for number of input blocks up to 3].
        +# This is why it makes no sense to implement 2x subroutine.
        +# aes[enc|dec] latency in next processor generation is 8, but the
        +# instructions can be scheduled every cycle. Optimal interleave for
        +# new processor is therefore 8x, but it's unfeasible to accommodate it
        +# in XMM registers addreassable in 32-bit mode and therefore 6x is
        +# used instead...
        +
        +sub aesni_generate3
        +{ my $p=shift;
        +
        +    &function_begin_B("_aesni_${p}rypt3");
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&shr		($rounds,1);
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	&lea		($key,&DWP(32,$key));
        +	&xorps		($inout0,$rndkey0);
        +	&pxor		($inout1,$rndkey0);
        +	&pxor		($inout2,$rndkey0);
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +
        +    &set_label("${p}3_loop");
        +	eval"&aes${p}	($inout0,$rndkey1)";
        +	eval"&aes${p}	($inout1,$rndkey1)";
        +	&dec		($rounds);
        +	eval"&aes${p}	($inout2,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	eval"&aes${p}	($inout0,$rndkey0)";
        +	eval"&aes${p}	($inout1,$rndkey0)";
        +	&lea		($key,&DWP(32,$key));
        +	eval"&aes${p}	($inout2,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&jnz		(&label("${p}3_loop"));
        +    eval"&aes${p}	($inout0,$rndkey1)";
        +    eval"&aes${p}	($inout1,$rndkey1)";
        +    eval"&aes${p}	($inout2,$rndkey1)";
        +    eval"&aes${p}last	($inout0,$rndkey0)";
        +    eval"&aes${p}last	($inout1,$rndkey0)";
        +    eval"&aes${p}last	($inout2,$rndkey0)";
        +    &ret();
        +    &function_end_B("_aesni_${p}rypt3");
        +}
        +
        +# 4x interleave is implemented to improve small block performance,
        +# most notably [and naturally] 4 block by ~30%. One can argue that one
        +# should have implemented 5x as well, but improvement  would be <20%,
        +# so it's not worth it...
        +sub aesni_generate4
        +{ my $p=shift;
        +
        +    &function_begin_B("_aesni_${p}rypt4");
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	&shr		($rounds,1);
        +	&lea		($key,&DWP(32,$key));
        +	&xorps		($inout0,$rndkey0);
        +	&pxor		($inout1,$rndkey0);
        +	&pxor		($inout2,$rndkey0);
        +	&pxor		($inout3,$rndkey0);
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +
        +    &set_label("${p}4_loop");
        +	eval"&aes${p}	($inout0,$rndkey1)";
        +	eval"&aes${p}	($inout1,$rndkey1)";
        +	&dec		($rounds);
        +	eval"&aes${p}	($inout2,$rndkey1)";
        +	eval"&aes${p}	($inout3,$rndkey1)";
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	eval"&aes${p}	($inout0,$rndkey0)";
        +	eval"&aes${p}	($inout1,$rndkey0)";
        +	&lea		($key,&DWP(32,$key));
        +	eval"&aes${p}	($inout2,$rndkey0)";
        +	eval"&aes${p}	($inout3,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +    &jnz		(&label("${p}4_loop"));
        +
        +    eval"&aes${p}	($inout0,$rndkey1)";
        +    eval"&aes${p}	($inout1,$rndkey1)";
        +    eval"&aes${p}	($inout2,$rndkey1)";
        +    eval"&aes${p}	($inout3,$rndkey1)";
        +    eval"&aes${p}last	($inout0,$rndkey0)";
        +    eval"&aes${p}last	($inout1,$rndkey0)";
        +    eval"&aes${p}last	($inout2,$rndkey0)";
        +    eval"&aes${p}last	($inout3,$rndkey0)";
        +    &ret();
        +    &function_end_B("_aesni_${p}rypt4");
        +}
        +
        +sub aesni_generate6
        +{ my $p=shift;
        +
        +    &function_begin_B("_aesni_${p}rypt6");
        +    &static_label("_aesni_${p}rypt6_enter");
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&shr		($rounds,1);
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	&lea		($key,&DWP(32,$key));
        +	&xorps		($inout0,$rndkey0);
        +	&pxor		($inout1,$rndkey0);	# pxor does better here
        +	eval"&aes${p}	($inout0,$rndkey1)";
        +	&pxor		($inout2,$rndkey0);
        +	eval"&aes${p}	($inout1,$rndkey1)";
        +	&pxor		($inout3,$rndkey0);
        +	&dec		($rounds);
        +	eval"&aes${p}	($inout2,$rndkey1)";
        +	&pxor		($inout4,$rndkey0);
        +	eval"&aes${p}	($inout3,$rndkey1)";
        +	&pxor		($inout5,$rndkey0);
        +	eval"&aes${p}	($inout4,$rndkey1)";
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	eval"&aes${p}	($inout5,$rndkey1)";
        +	&jmp		(&label("_aesni_${p}rypt6_enter"));
        +
        +    &set_label("${p}6_loop",16);
        +	eval"&aes${p}	($inout0,$rndkey1)";
        +	eval"&aes${p}	($inout1,$rndkey1)";
        +	&dec		($rounds);
        +	eval"&aes${p}	($inout2,$rndkey1)";
        +	eval"&aes${p}	($inout3,$rndkey1)";
        +	eval"&aes${p}	($inout4,$rndkey1)";
        +	eval"&aes${p}	($inout5,$rndkey1)";
        +    &set_label("_aesni_${p}rypt6_enter",16);
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	eval"&aes${p}	($inout0,$rndkey0)";
        +	eval"&aes${p}	($inout1,$rndkey0)";
        +	&lea		($key,&DWP(32,$key));
        +	eval"&aes${p}	($inout2,$rndkey0)";
        +	eval"&aes${p}	($inout3,$rndkey0)";
        +	eval"&aes${p}	($inout4,$rndkey0)";
        +	eval"&aes${p}	($inout5,$rndkey0)";
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +    &jnz		(&label("${p}6_loop"));
        +
        +    eval"&aes${p}	($inout0,$rndkey1)";
        +    eval"&aes${p}	($inout1,$rndkey1)";
        +    eval"&aes${p}	($inout2,$rndkey1)";
        +    eval"&aes${p}	($inout3,$rndkey1)";
        +    eval"&aes${p}	($inout4,$rndkey1)";
        +    eval"&aes${p}	($inout5,$rndkey1)";
        +    eval"&aes${p}last	($inout0,$rndkey0)";
        +    eval"&aes${p}last	($inout1,$rndkey0)";
        +    eval"&aes${p}last	($inout2,$rndkey0)";
        +    eval"&aes${p}last	($inout3,$rndkey0)";
        +    eval"&aes${p}last	($inout4,$rndkey0)";
        +    eval"&aes${p}last	($inout5,$rndkey0)";
        +    &ret();
        +    &function_end_B("_aesni_${p}rypt6");
        +}
        +&aesni_generate3("enc") if ($PREFIX eq "aesni");
        +&aesni_generate3("dec");
        +&aesni_generate4("enc") if ($PREFIX eq "aesni");
        +&aesni_generate4("dec");
        +&aesni_generate6("enc") if ($PREFIX eq "aesni");
        +&aesni_generate6("dec");
        +
        +if ($PREFIX eq "aesni") {
        +######################################################################
        +# void aesni_ecb_encrypt (const void *in, void *out,
        +#                         size_t length, const AES_KEY *key,
        +#                         int enc);
        +&function_begin("aesni_ecb_encrypt");
        +	&mov	($inp,&wparam(0));
        +	&mov	($out,&wparam(1));
        +	&mov	($len,&wparam(2));
        +	&mov	($key,&wparam(3));
        +	&mov	($rounds_,&wparam(4));
        +	&and	($len,-16);
        +	&jz	(&label("ecb_ret"));
        +	&mov	($rounds,&DWP(240,$key));
        +	&test	($rounds_,$rounds_);
        +	&jz	(&label("ecb_decrypt"));
        +
        +	&mov	($key_,$key);		# backup $key
        +	&mov	($rounds_,$rounds);	# backup $rounds
        +	&cmp	($len,0x60);
        +	&jb	(&label("ecb_enc_tail"));
        +
        +	&movdqu	($inout0,&QWP(0,$inp));
        +	&movdqu	($inout1,&QWP(0x10,$inp));
        +	&movdqu	($inout2,&QWP(0x20,$inp));
        +	&movdqu	($inout3,&QWP(0x30,$inp));
        +	&movdqu	($inout4,&QWP(0x40,$inp));
        +	&movdqu	($inout5,&QWP(0x50,$inp));
        +	&lea	($inp,&DWP(0x60,$inp));
        +	&sub	($len,0x60);
        +	&jmp	(&label("ecb_enc_loop6_enter"));
        +
        +&set_label("ecb_enc_loop6",16);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movdqu	($inout0,&QWP(0,$inp));
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movdqu	($inout1,&QWP(0x10,$inp));
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movdqu	($inout2,&QWP(0x20,$inp));
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movdqu	($inout3,&QWP(0x30,$inp));
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&movdqu	($inout4,&QWP(0x40,$inp));
        +	&movups	(&QWP(0x50,$out),$inout5);
        +	&lea	($out,&DWP(0x60,$out));
        +	&movdqu	($inout5,&QWP(0x50,$inp));
        +	&lea	($inp,&DWP(0x60,$inp));
        +&set_label("ecb_enc_loop6_enter");
        +
        +	&call	("_aesni_encrypt6");
        +
        +	&mov	($key,$key_);		# restore $key
        +	&mov	($rounds,$rounds_);	# restore $rounds
        +	&sub	($len,0x60);
        +	&jnc	(&label("ecb_enc_loop6"));
        +
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&movups	(&QWP(0x50,$out),$inout5);
        +	&lea	($out,&DWP(0x60,$out));
        +	&add	($len,0x60);
        +	&jz	(&label("ecb_ret"));
        +
        +&set_label("ecb_enc_tail");
        +	&movups	($inout0,&QWP(0,$inp));
        +	&cmp	($len,0x20);
        +	&jb	(&label("ecb_enc_one"));
        +	&movups	($inout1,&QWP(0x10,$inp));
        +	&je	(&label("ecb_enc_two"));
        +	&movups	($inout2,&QWP(0x20,$inp));
        +	&cmp	($len,0x40);
        +	&jb	(&label("ecb_enc_three"));
        +	&movups	($inout3,&QWP(0x30,$inp));
        +	&je	(&label("ecb_enc_four"));
        +	&movups	($inout4,&QWP(0x40,$inp));
        +	&xorps	($inout5,$inout5);
        +	&call	("_aesni_encrypt6");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_enc_one",16);
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +	&movups	(&QWP(0,$out),$inout0);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_enc_two",16);
        +	&xorps	($inout2,$inout2);
        +	&call	("_aesni_encrypt3");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_enc_three",16);
        +	&call	("_aesni_encrypt3");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_enc_four",16);
        +	&call	("_aesni_encrypt4");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&jmp	(&label("ecb_ret"));
        +######################################################################
        +&set_label("ecb_decrypt",16);
        +	&mov	($key_,$key);		# backup $key
        +	&mov	($rounds_,$rounds);	# backup $rounds
        +	&cmp	($len,0x60);
        +	&jb	(&label("ecb_dec_tail"));
        +
        +	&movdqu	($inout0,&QWP(0,$inp));
        +	&movdqu	($inout1,&QWP(0x10,$inp));
        +	&movdqu	($inout2,&QWP(0x20,$inp));
        +	&movdqu	($inout3,&QWP(0x30,$inp));
        +	&movdqu	($inout4,&QWP(0x40,$inp));
        +	&movdqu	($inout5,&QWP(0x50,$inp));
        +	&lea	($inp,&DWP(0x60,$inp));
        +	&sub	($len,0x60);
        +	&jmp	(&label("ecb_dec_loop6_enter"));
        +
        +&set_label("ecb_dec_loop6",16);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movdqu	($inout0,&QWP(0,$inp));
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movdqu	($inout1,&QWP(0x10,$inp));
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movdqu	($inout2,&QWP(0x20,$inp));
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movdqu	($inout3,&QWP(0x30,$inp));
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&movdqu	($inout4,&QWP(0x40,$inp));
        +	&movups	(&QWP(0x50,$out),$inout5);
        +	&lea	($out,&DWP(0x60,$out));
        +	&movdqu	($inout5,&QWP(0x50,$inp));
        +	&lea	($inp,&DWP(0x60,$inp));
        +&set_label("ecb_dec_loop6_enter");
        +
        +	&call	("_aesni_decrypt6");
        +
        +	&mov	($key,$key_);		# restore $key
        +	&mov	($rounds,$rounds_);	# restore $rounds
        +	&sub	($len,0x60);
        +	&jnc	(&label("ecb_dec_loop6"));
        +
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&movups	(&QWP(0x50,$out),$inout5);
        +	&lea	($out,&DWP(0x60,$out));
        +	&add	($len,0x60);
        +	&jz	(&label("ecb_ret"));
        +
        +&set_label("ecb_dec_tail");
        +	&movups	($inout0,&QWP(0,$inp));
        +	&cmp	($len,0x20);
        +	&jb	(&label("ecb_dec_one"));
        +	&movups	($inout1,&QWP(0x10,$inp));
        +	&je	(&label("ecb_dec_two"));
        +	&movups	($inout2,&QWP(0x20,$inp));
        +	&cmp	($len,0x40);
        +	&jb	(&label("ecb_dec_three"));
        +	&movups	($inout3,&QWP(0x30,$inp));
        +	&je	(&label("ecb_dec_four"));
        +	&movups	($inout4,&QWP(0x40,$inp));
        +	&xorps	($inout5,$inout5);
        +	&call	("_aesni_decrypt6");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_dec_one",16);
        +	if ($inline)
        +	{   &aesni_inline_generate1("dec");	}
        +	else
        +	{   &call	("_aesni_decrypt1");	}
        +	&movups	(&QWP(0,$out),$inout0);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_dec_two",16);
        +	&xorps	($inout2,$inout2);
        +	&call	("_aesni_decrypt3");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_dec_three",16);
        +	&call	("_aesni_decrypt3");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&jmp	(&label("ecb_ret"));
        +
        +&set_label("ecb_dec_four",16);
        +	&call	("_aesni_decrypt4");
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +
        +&set_label("ecb_ret");
        +&function_end("aesni_ecb_encrypt");
        +
        +######################################################################
        +# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out,
        +#                         size_t blocks, const AES_KEY *key,
        +#                         const char *ivec,char *cmac);
        +#
        +# Handles only complete blocks, operates on 64-bit counter and
        +# does not update *ivec! Nor does it finalize CMAC value
        +# (see engine/eng_aesni.c for details)
        +#
        +{ my $cmac=$inout1;
        +&function_begin("aesni_ccm64_encrypt_blocks");
        +	&mov	($inp,&wparam(0));
        +	&mov	($out,&wparam(1));
        +	&mov	($len,&wparam(2));
        +	&mov	($key,&wparam(3));
        +	&mov	($rounds_,&wparam(4));
        +	&mov	($rounds,&wparam(5));
        +	&mov	($key_,"esp");
        +	&sub	("esp",60);
        +	&and	("esp",-16);			# align stack
        +	&mov	(&DWP(48,"esp"),$key_);
        +
        +	&movdqu	($ivec,&QWP(0,$rounds_));	# load ivec
        +	&movdqu	($cmac,&QWP(0,$rounds));	# load cmac
        +	&mov	($rounds,&DWP(240,$key));
        +
        +	# compose byte-swap control mask for pshufb on stack
        +	&mov	(&DWP(0,"esp"),0x0c0d0e0f);
        +	&mov	(&DWP(4,"esp"),0x08090a0b);
        +	&mov	(&DWP(8,"esp"),0x04050607);
        +	&mov	(&DWP(12,"esp"),0x00010203);
        +
        +	# compose counter increment vector on stack
        +	&mov	($rounds_,1);
        +	&xor	($key_,$key_);
        +	&mov	(&DWP(16,"esp"),$rounds_);
        +	&mov	(&DWP(20,"esp"),$key_);
        +	&mov	(&DWP(24,"esp"),$key_);
        +	&mov	(&DWP(28,"esp"),$key_);
        +
        +	&shr	($rounds,1);
        +	&lea	($key_,&DWP(0,$key));
        +	&movdqa	($inout3,&QWP(0,"esp"));
        +	&movdqa	($inout0,$ivec);
        +	&mov	($rounds_,$rounds);
        +	&pshufb	($ivec,$inout3);
        +
        +&set_label("ccm64_enc_outer");
        +	&$movekey	($rndkey0,&QWP(0,$key_));
        +	&mov		($rounds,$rounds_);
        +	&movups		($in0,&QWP(0,$inp));
        +
        +	&xorps		($inout0,$rndkey0);
        +	&$movekey	($rndkey1,&QWP(16,$key_));
        +	&xorps		($rndkey0,$in0);
        +	&lea		($key,&DWP(32,$key_));
        +	&xorps		($cmac,$rndkey0);		# cmac^=inp
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +
        +&set_label("ccm64_enc2_loop");
        +	&aesenc		($inout0,$rndkey1);
        +	&dec		($rounds);
        +	&aesenc		($cmac,$rndkey1);
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	&aesenc		($inout0,$rndkey0);
        +	&lea		($key,&DWP(32,$key));
        +	&aesenc		($cmac,$rndkey0);
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&jnz		(&label("ccm64_enc2_loop"));
        +	&aesenc		($inout0,$rndkey1);
        +	&aesenc		($cmac,$rndkey1);
        +	&paddq		($ivec,&QWP(16,"esp"));
        +	&aesenclast	($inout0,$rndkey0);
        +	&aesenclast	($cmac,$rndkey0);
        +
        +	&dec	($len);
        +	&lea	($inp,&DWP(16,$inp));
        +	&xorps	($in0,$inout0);			# inp^=E(ivec)
        +	&movdqa	($inout0,$ivec);
        +	&movups	(&QWP(0,$out),$in0);		# save output
        +	&lea	($out,&DWP(16,$out));
        +	&pshufb	($inout0,$inout3);
        +	&jnz	(&label("ccm64_enc_outer"));
        +
        +	&mov	("esp",&DWP(48,"esp"));
        +	&mov	($out,&wparam(5));
        +	&movups	(&QWP(0,$out),$cmac);
        +&function_end("aesni_ccm64_encrypt_blocks");
        +
        +&function_begin("aesni_ccm64_decrypt_blocks");
        +	&mov	($inp,&wparam(0));
        +	&mov	($out,&wparam(1));
        +	&mov	($len,&wparam(2));
        +	&mov	($key,&wparam(3));
        +	&mov	($rounds_,&wparam(4));
        +	&mov	($rounds,&wparam(5));
        +	&mov	($key_,"esp");
        +	&sub	("esp",60);
        +	&and	("esp",-16);			# align stack
        +	&mov	(&DWP(48,"esp"),$key_);
        +
        +	&movdqu	($ivec,&QWP(0,$rounds_));	# load ivec
        +	&movdqu	($cmac,&QWP(0,$rounds));	# load cmac
        +	&mov	($rounds,&DWP(240,$key));
        +
        +	# compose byte-swap control mask for pshufb on stack
        +	&mov	(&DWP(0,"esp"),0x0c0d0e0f);
        +	&mov	(&DWP(4,"esp"),0x08090a0b);
        +	&mov	(&DWP(8,"esp"),0x04050607);
        +	&mov	(&DWP(12,"esp"),0x00010203);
        +
        +	# compose counter increment vector on stack
        +	&mov	($rounds_,1);
        +	&xor	($key_,$key_);
        +	&mov	(&DWP(16,"esp"),$rounds_);
        +	&mov	(&DWP(20,"esp"),$key_);
        +	&mov	(&DWP(24,"esp"),$key_);
        +	&mov	(&DWP(28,"esp"),$key_);
        +
        +	&movdqa	($inout3,&QWP(0,"esp"));	# bswap mask
        +	&movdqa	($inout0,$ivec);
        +
        +	&mov	($key_,$key);
        +	&mov	($rounds_,$rounds);
        +
        +	&pshufb	($ivec,$inout3);
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +	&movups	($in0,&QWP(0,$inp));		# load inp
        +	&paddq	($ivec,&QWP(16,"esp"));
        +	&lea	($inp,&QWP(16,$inp));
        +	&jmp	(&label("ccm64_dec_outer"));
        +
        +&set_label("ccm64_dec_outer",16);
        +	&xorps	($in0,$inout0);			# inp ^= E(ivec)
        +	&movdqa	($inout0,$ivec);
        +	&mov	($rounds,$rounds_);
        +	&movups	(&QWP(0,$out),$in0);		# save output
        +	&lea	($out,&DWP(16,$out));
        +	&pshufb	($inout0,$inout3);
        +
        +	&sub	($len,1);
        +	&jz	(&label("ccm64_dec_break"));
        +
        +	&$movekey	($rndkey0,&QWP(0,$key_));
        +	&shr		($rounds,1);
        +	&$movekey	($rndkey1,&QWP(16,$key_));
        +	&xorps		($in0,$rndkey0);
        +	&lea		($key,&DWP(32,$key_));
        +	&xorps		($inout0,$rndkey0);
        +	&xorps		($cmac,$in0);		# cmac^=out
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +
        +&set_label("ccm64_dec2_loop");
        +	&aesenc		($inout0,$rndkey1);
        +	&dec		($rounds);
        +	&aesenc		($cmac,$rndkey1);
        +	&$movekey	($rndkey1,&QWP(16,$key));
        +	&aesenc		($inout0,$rndkey0);
        +	&lea		($key,&DWP(32,$key));
        +	&aesenc		($cmac,$rndkey0);
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&jnz		(&label("ccm64_dec2_loop"));
        +	&movups		($in0,&QWP(0,$inp));	# load inp
        +	&paddq		($ivec,&QWP(16,"esp"));
        +	&aesenc		($inout0,$rndkey1);
        +	&aesenc		($cmac,$rndkey1);
        +	&lea		($inp,&QWP(16,$inp));
        +	&aesenclast	($inout0,$rndkey0);
        +	&aesenclast	($cmac,$rndkey0);
        +	&jmp	(&label("ccm64_dec_outer"));
        +
        +&set_label("ccm64_dec_break",16);
        +	&mov	($key,$key_);
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc",$cmac,$in0);	}
        +	else
        +	{   &call	("_aesni_encrypt1",$cmac);	}
        +
        +	&mov	("esp",&DWP(48,"esp"));
        +	&mov	($out,&wparam(5));
        +	&movups	(&QWP(0,$out),$cmac);
        +&function_end("aesni_ccm64_decrypt_blocks");
        +}
        +
        +######################################################################
        +# void aesni_ctr32_encrypt_blocks (const void *in, void *out,
        +#                         size_t blocks, const AES_KEY *key,
        +#                         const char *ivec);
        +#
        +# Handles only complete blocks, operates on 32-bit counter and
        +# does not update *ivec! (see engine/eng_aesni.c for details)
        +#
        +# stack layout:
        +#	0	pshufb mask
        +#	16	vector addend: 0,6,6,6
        +# 	32	counter-less ivec
        +#	48	1st triplet of counter vector
        +#	64	2nd triplet of counter vector
        +#	80	saved %esp
        +
        +&function_begin("aesni_ctr32_encrypt_blocks");
        +	&mov	($inp,&wparam(0));
        +	&mov	($out,&wparam(1));
        +	&mov	($len,&wparam(2));
        +	&mov	($key,&wparam(3));
        +	&mov	($rounds_,&wparam(4));
        +	&mov	($key_,"esp");
        +	&sub	("esp",88);
        +	&and	("esp",-16);			# align stack
        +	&mov	(&DWP(80,"esp"),$key_);
        +
        +	&cmp	($len,1);
        +	&je	(&label("ctr32_one_shortcut"));
        +
        +	&movdqu	($inout5,&QWP(0,$rounds_));	# load ivec
        +
        +	# compose byte-swap control mask for pshufb on stack
        +	&mov	(&DWP(0,"esp"),0x0c0d0e0f);
        +	&mov	(&DWP(4,"esp"),0x08090a0b);
        +	&mov	(&DWP(8,"esp"),0x04050607);
        +	&mov	(&DWP(12,"esp"),0x00010203);
        +
        +	# compose counter increment vector on stack
        +	&mov	($rounds,6);
        +	&xor	($key_,$key_);
        +	&mov	(&DWP(16,"esp"),$rounds);
        +	&mov	(&DWP(20,"esp"),$rounds);
        +	&mov	(&DWP(24,"esp"),$rounds);
        +	&mov	(&DWP(28,"esp"),$key_);
        +
        +	&pextrd	($rounds_,$inout5,3);		# pull 32-bit counter
        +	&pinsrd	($inout5,$key_,3);		# wipe 32-bit counter
        +
        +	&mov	($rounds,&DWP(240,$key));	# key->rounds
        +
        +	# compose 2 vectors of 3x32-bit counters
        +	&bswap	($rounds_);
        +	&pxor	($rndkey1,$rndkey1);
        +	&pxor	($rndkey0,$rndkey0);
        +	&movdqa	($inout0,&QWP(0,"esp"));	# load byte-swap mask
        +	&pinsrd	($rndkey1,$rounds_,0);
        +	&lea	($key_,&DWP(3,$rounds_));
        +	&pinsrd	($rndkey0,$key_,0);
        +	&inc	($rounds_);
        +	&pinsrd	($rndkey1,$rounds_,1);
        +	&inc	($key_);
        +	&pinsrd	($rndkey0,$key_,1);
        +	&inc	($rounds_);
        +	&pinsrd	($rndkey1,$rounds_,2);
        +	&inc	($key_);
        +	&pinsrd	($rndkey0,$key_,2);
        +	&movdqa	(&QWP(48,"esp"),$rndkey1);	# save 1st triplet
        +	&pshufb	($rndkey1,$inout0);		# byte swap
        +	&movdqa	(&QWP(64,"esp"),$rndkey0);	# save 2nd triplet
        +	&pshufb	($rndkey0,$inout0);		# byte swap
        +
        +	&pshufd	($inout0,$rndkey1,3<<6);	# place counter to upper dword
        +	&pshufd	($inout1,$rndkey1,2<<6);
        +	&cmp	($len,6);
        +	&jb	(&label("ctr32_tail"));
        +	&movdqa	(&QWP(32,"esp"),$inout5);	# save counter-less ivec
        +	&shr	($rounds,1);
        +	&mov	($key_,$key);			# backup $key
        +	&mov	($rounds_,$rounds);		# backup $rounds
        +	&sub	($len,6);
        +	&jmp	(&label("ctr32_loop6"));
        +
        +&set_label("ctr32_loop6",16);
        +	&pshufd	($inout2,$rndkey1,1<<6);
        +	&movdqa	($rndkey1,&QWP(32,"esp"));	# pull counter-less ivec
        +	&pshufd	($inout3,$rndkey0,3<<6);
        +	&por	($inout0,$rndkey1);		# merge counter-less ivec
        +	&pshufd	($inout4,$rndkey0,2<<6);
        +	&por	($inout1,$rndkey1);
        +	&pshufd	($inout5,$rndkey0,1<<6);
        +	&por	($inout2,$rndkey1);
        +	&por	($inout3,$rndkey1);
        +	&por	($inout4,$rndkey1);
        +	&por	($inout5,$rndkey1);
        +
        +	# inlining _aesni_encrypt6's prologue gives ~4% improvement...
        +	&$movekey	($rndkey0,&QWP(0,$key_));
        +	&$movekey	($rndkey1,&QWP(16,$key_));
        +	&lea		($key,&DWP(32,$key_));
        +	&dec		($rounds);
        +	&pxor		($inout0,$rndkey0);
        +	&pxor		($inout1,$rndkey0);
        +	&aesenc		($inout0,$rndkey1);
        +	&pxor		($inout2,$rndkey0);
        +	&aesenc		($inout1,$rndkey1);
        +	&pxor		($inout3,$rndkey0);
        +	&aesenc		($inout2,$rndkey1);
        +	&pxor		($inout4,$rndkey0);
        +	&aesenc		($inout3,$rndkey1);
        +	&pxor		($inout5,$rndkey0);
        +	&aesenc		($inout4,$rndkey1);
        +	&$movekey	($rndkey0,&QWP(0,$key));
        +	&aesenc		($inout5,$rndkey1);
        +
        +	&call		(&label("_aesni_encrypt6_enter"));
        +
        +	&movups	($rndkey1,&QWP(0,$inp));
        +	&movups	($rndkey0,&QWP(0x10,$inp));
        +	&xorps	($inout0,$rndkey1);
        +	&movups	($rndkey1,&QWP(0x20,$inp));
        +	&xorps	($inout1,$rndkey0);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movdqa	($rndkey0,&QWP(16,"esp"));	# load increment
        +	&xorps	($inout2,$rndkey1);
        +	&movdqa	($rndkey1,&QWP(48,"esp"));	# load 1st triplet
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +
        +	&paddd	($rndkey1,$rndkey0);		# 1st triplet increment
        +	&paddd	($rndkey0,&QWP(64,"esp"));	# 2nd triplet increment
        +	&movdqa	($inout0,&QWP(0,"esp"));	# load byte swap mask
        +
        +	&movups	($inout1,&QWP(0x30,$inp));
        +	&movups	($inout2,&QWP(0x40,$inp));
        +	&xorps	($inout3,$inout1);
        +	&movups	($inout1,&QWP(0x50,$inp));
        +	&lea	($inp,&DWP(0x60,$inp));
        +	&movdqa	(&QWP(48,"esp"),$rndkey1);	# save 1st triplet
        +	&pshufb	($rndkey1,$inout0);		# byte swap
        +	&xorps	($inout4,$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&xorps	($inout5,$inout1);
        +	&movdqa	(&QWP(64,"esp"),$rndkey0);	# save 2nd triplet
        +	&pshufb	($rndkey0,$inout0);		# byte swap
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&pshufd	($inout0,$rndkey1,3<<6);
        +	&movups	(&QWP(0x50,$out),$inout5);
        +	&lea	($out,&DWP(0x60,$out));
        +
        +	&mov	($rounds,$rounds_);
        +	&pshufd	($inout1,$rndkey1,2<<6);
        +	&sub	($len,6);
        +	&jnc	(&label("ctr32_loop6"));
        +
        +	&add	($len,6);
        +	&jz	(&label("ctr32_ret"));
        +	&mov	($key,$key_);
        +	&lea	($rounds,&DWP(1,"",$rounds,2));	# restore $rounds
        +	&movdqa	($inout5,&QWP(32,"esp"));	# pull count-less ivec
        +
        +&set_label("ctr32_tail");
        +	&por	($inout0,$inout5);
        +	&cmp	($len,2);
        +	&jb	(&label("ctr32_one"));
        +
        +	&pshufd	($inout2,$rndkey1,1<<6);
        +	&por	($inout1,$inout5);
        +	&je	(&label("ctr32_two"));
        +
        +	&pshufd	($inout3,$rndkey0,3<<6);
        +	&por	($inout2,$inout5);
        +	&cmp	($len,4);
        +	&jb	(&label("ctr32_three"));
        +
        +	&pshufd	($inout4,$rndkey0,2<<6);
        +	&por	($inout3,$inout5);
        +	&je	(&label("ctr32_four"));
        +
        +	&por	($inout4,$inout5);
        +	&call	("_aesni_encrypt6");
        +	&movups	($rndkey1,&QWP(0,$inp));
        +	&movups	($rndkey0,&QWP(0x10,$inp));
        +	&xorps	($inout0,$rndkey1);
        +	&movups	($rndkey1,&QWP(0x20,$inp));
        +	&xorps	($inout1,$rndkey0);
        +	&movups	($rndkey0,&QWP(0x30,$inp));
        +	&xorps	($inout2,$rndkey1);
        +	&movups	($rndkey1,&QWP(0x40,$inp));
        +	&xorps	($inout3,$rndkey0);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&xorps	($inout4,$rndkey1);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&jmp	(&label("ctr32_ret"));
        +
        +&set_label("ctr32_one_shortcut",16);
        +	&movups	($inout0,&QWP(0,$rounds_));	# load ivec
        +	&mov	($rounds,&DWP(240,$key));
        +	
        +&set_label("ctr32_one");
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +	&movups	($in0,&QWP(0,$inp));
        +	&xorps	($in0,$inout0);
        +	&movups	(&QWP(0,$out),$in0);
        +	&jmp	(&label("ctr32_ret"));
        +
        +&set_label("ctr32_two",16);
        +	&call	("_aesni_encrypt3");
        +	&movups	($inout3,&QWP(0,$inp));
        +	&movups	($inout4,&QWP(0x10,$inp));
        +	&xorps	($inout0,$inout3);
        +	&xorps	($inout1,$inout4);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&jmp	(&label("ctr32_ret"));
        +
        +&set_label("ctr32_three",16);
        +	&call	("_aesni_encrypt3");
        +	&movups	($inout3,&QWP(0,$inp));
        +	&movups	($inout4,&QWP(0x10,$inp));
        +	&xorps	($inout0,$inout3);
        +	&movups	($inout5,&QWP(0x20,$inp));
        +	&xorps	($inout1,$inout4);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&xorps	($inout2,$inout5);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&jmp	(&label("ctr32_ret"));
        +
        +&set_label("ctr32_four",16);
        +	&call	("_aesni_encrypt4");
        +	&movups	($inout4,&QWP(0,$inp));
        +	&movups	($inout5,&QWP(0x10,$inp));
        +	&movups	($rndkey1,&QWP(0x20,$inp));
        +	&xorps	($inout0,$inout4);
        +	&movups	($rndkey0,&QWP(0x30,$inp));
        +	&xorps	($inout1,$inout5);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&xorps	($inout2,$rndkey1);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&xorps	($inout3,$rndkey0);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +
        +&set_label("ctr32_ret");
        +	&mov	("esp",&DWP(80,"esp"));
        +&function_end("aesni_ctr32_encrypt_blocks");
        +
        +######################################################################
        +# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len,
        +#	const AES_KEY *key1, const AES_KEY *key2
        +#	const unsigned char iv[16]);
        +#
        +{ my ($tweak,$twtmp,$twres,$twmask)=($rndkey1,$rndkey0,$inout0,$inout1);
        +
        +&function_begin("aesni_xts_encrypt");
        +	&mov	($key,&wparam(4));		# key2
        +	&mov	($inp,&wparam(5));		# clear-text tweak
        +
        +	&mov	($rounds,&DWP(240,$key));	# key2->rounds
        +	&movups	($inout0,&QWP(0,$inp));
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +
        +	&mov	($inp,&wparam(0));
        +	&mov	($out,&wparam(1));
        +	&mov	($len,&wparam(2));
        +	&mov	($key,&wparam(3));		# key1
        +
        +	&mov	($key_,"esp");
        +	&sub	("esp",16*7+8);
        +	&mov	($rounds,&DWP(240,$key));	# key1->rounds
        +	&and	("esp",-16);			# align stack
        +
        +	&mov	(&DWP(16*6+0,"esp"),0x87);	# compose the magic constant
        +	&mov	(&DWP(16*6+4,"esp"),0);
        +	&mov	(&DWP(16*6+8,"esp"),1);
        +	&mov	(&DWP(16*6+12,"esp"),0);
        +	&mov	(&DWP(16*7+0,"esp"),$len);	# save original $len
        +	&mov	(&DWP(16*7+4,"esp"),$key_);	# save original %esp
        +
        +	&movdqa	($tweak,$inout0);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($twmask,&QWP(6*16,"esp"));	# 0x0...010...87
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +
        +	&and	($len,-16);
        +	&mov	($key_,$key);			# backup $key
        +	&mov	($rounds_,$rounds);		# backup $rounds
        +	&sub	($len,16*6);
        +	&jc	(&label("xts_enc_short"));
        +
        +	&shr	($rounds,1);
        +	&mov	($rounds_,$rounds);
        +	&jmp	(&label("xts_enc_loop6"));
        +
        +&set_label("xts_enc_loop6",16);
        +	for ($i=0;$i<4;$i++) {
        +	    &pshufd	($twres,$twtmp,0x13);
        +	    &pxor	($twtmp,$twtmp);
        +	    &movdqa	(&QWP(16*$i,"esp"),$tweak);
        +	    &paddq	($tweak,$tweak);	# &psllq($tweak,1);
        +	    &pand	($twres,$twmask);	# isolate carry and residue
        +	    &pcmpgtd	($twtmp,$tweak);	# broadcast upper bits
        +	    &pxor	($tweak,$twres);
        +	}
        +	&pshufd	($inout5,$twtmp,0x13);
        +	&movdqa	(&QWP(16*$i++,"esp"),$tweak);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	 &$movekey	($rndkey0,&QWP(0,$key_));
        +	&pand	($inout5,$twmask);		# isolate carry and residue
        +	 &movups	($inout0,&QWP(0,$inp));	# load input
        +	&pxor	($inout5,$tweak);
        +
        +	# inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
        +	&movdqu	($inout1,&QWP(16*1,$inp));
        +	 &xorps		($inout0,$rndkey0);	# input^=rndkey[0]
        +	&movdqu	($inout2,&QWP(16*2,$inp));
        +	 &pxor		($inout1,$rndkey0);
        +	&movdqu	($inout3,&QWP(16*3,$inp));
        +	 &pxor		($inout2,$rndkey0);
        +	&movdqu	($inout4,&QWP(16*4,$inp));
        +	 &pxor		($inout3,$rndkey0);
        +	&movdqu	($rndkey1,&QWP(16*5,$inp));
        +	 &pxor		($inout4,$rndkey0);
        +	&lea	($inp,&DWP(16*6,$inp));
        +	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
        +	&movdqa	(&QWP(16*$i,"esp"),$inout5);	# save last tweak
        +	&pxor	($inout5,$rndkey1);
        +
        +	 &$movekey	($rndkey1,&QWP(16,$key_));
        +	 &lea		($key,&DWP(32,$key_));
        +	&pxor	($inout1,&QWP(16*1,"esp"));
        +	 &aesenc	($inout0,$rndkey1);
        +	&pxor	($inout2,&QWP(16*2,"esp"));
        +	 &aesenc	($inout1,$rndkey1);
        +	&pxor	($inout3,&QWP(16*3,"esp"));
        +	 &dec		($rounds);
        +	 &aesenc	($inout2,$rndkey1);
        +	&pxor	($inout4,&QWP(16*4,"esp"));
        +	 &aesenc	($inout3,$rndkey1);
        +	&pxor		($inout5,$rndkey0);
        +	 &aesenc	($inout4,$rndkey1);
        +	 &$movekey	($rndkey0,&QWP(0,$key));
        +	 &aesenc	($inout5,$rndkey1);
        +	&call		(&label("_aesni_encrypt6_enter"));
        +
        +	&movdqa	($tweak,&QWP(16*5,"esp"));	# last tweak
        +       &pxor	($twtmp,$twtmp);
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
        +       &pcmpgtd	($twtmp,$tweak);		# broadcast upper bits
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&xorps	($inout2,&QWP(16*2,"esp"));
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&xorps	($inout3,&QWP(16*3,"esp"));
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&xorps	($inout4,&QWP(16*4,"esp"));
        +	&movups	(&QWP(16*3,$out),$inout3);
        +	&xorps	($inout5,$tweak);
        +	&movups	(&QWP(16*4,$out),$inout4);
        +       &pshufd	($twres,$twtmp,0x13);
        +	&movups	(&QWP(16*5,$out),$inout5);
        +	&lea	($out,&DWP(16*6,$out));
        +       &movdqa	($twmask,&QWP(16*6,"esp"));	# 0x0...010...87
        +
        +	&pxor	($twtmp,$twtmp);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&mov	($rounds,$rounds_);		# restore $rounds
        +	&pxor	($tweak,$twres);
        +
        +	&sub	($len,16*6);
        +	&jnc	(&label("xts_enc_loop6"));
        +
        +	&lea	($rounds,&DWP(1,"",$rounds,2));	# restore $rounds
        +	&mov	($key,$key_);			# restore $key
        +	&mov	($rounds_,$rounds);
        +
        +&set_label("xts_enc_short");
        +	&add	($len,16*6);
        +	&jz	(&label("xts_enc_done6x"));
        +
        +	&movdqa	($inout3,$tweak);		# put aside previous tweak
        +	&cmp	($len,0x20);
        +	&jb	(&label("xts_enc_one"));
        +
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +	&je	(&label("xts_enc_two"));
        +
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($inout4,$tweak);		# put aside previous tweak
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +	&cmp	($len,0x40);
        +	&jb	(&label("xts_enc_three"));
        +
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($inout5,$tweak);		# put aside previous tweak
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +	&movdqa	(&QWP(16*0,"esp"),$inout3);
        +	&movdqa	(&QWP(16*1,"esp"),$inout4);
        +	&je	(&label("xts_enc_four"));
        +
        +	&movdqa	(&QWP(16*2,"esp"),$inout5);
        +	&pshufd	($inout5,$twtmp,0x13);
        +	&movdqa	(&QWP(16*3,"esp"),$tweak);
        +	&paddq	($tweak,$tweak);		# &psllq($inout0,1);
        +	&pand	($inout5,$twmask);		# isolate carry and residue
        +	&pxor	($inout5,$tweak);
        +
        +	&movdqu	($inout0,&QWP(16*0,$inp));	# load input
        +	&movdqu	($inout1,&QWP(16*1,$inp));
        +	&movdqu	($inout2,&QWP(16*2,$inp));
        +	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
        +	&movdqu	($inout3,&QWP(16*3,$inp));
        +	&pxor	($inout1,&QWP(16*1,"esp"));
        +	&movdqu	($inout4,&QWP(16*4,$inp));
        +	&pxor	($inout2,&QWP(16*2,"esp"));
        +	&lea	($inp,&DWP(16*5,$inp));
        +	&pxor	($inout3,&QWP(16*3,"esp"));
        +	&movdqa	(&QWP(16*4,"esp"),$inout5);	# save last tweak
        +	&pxor	($inout4,$inout5);
        +
        +	&call	("_aesni_encrypt6");
        +
        +	&movaps	($tweak,&QWP(16*4,"esp"));	# last tweak
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&xorps	($inout2,&QWP(16*2,"esp"));
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&xorps	($inout3,&QWP(16*3,"esp"));
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&xorps	($inout4,$tweak);
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&movups	(&QWP(16*3,$out),$inout3);
        +	&movups	(&QWP(16*4,$out),$inout4);
        +	&lea	($out,&DWP(16*5,$out));
        +	&jmp	(&label("xts_enc_done"));
        +
        +&set_label("xts_enc_one",16);
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&lea	($inp,&DWP(16*1,$inp));
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&lea	($out,&DWP(16*1,$out));
        +
        +	&movdqa	($tweak,$inout3);		# last tweak
        +	&jmp	(&label("xts_enc_done"));
        +
        +&set_label("xts_enc_two",16);
        +	&movaps	($inout4,$tweak);		# put aside last tweak
        +
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&movups	($inout1,&QWP(16*1,$inp));
        +	&lea	($inp,&DWP(16*2,$inp));
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	&xorps	($inout1,$inout4);
        +	&xorps	($inout2,$inout2);
        +
        +	&call	("_aesni_encrypt3");
        +
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&xorps	($inout1,$inout4);
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&lea	($out,&DWP(16*2,$out));
        +
        +	&movdqa	($tweak,$inout4);		# last tweak
        +	&jmp	(&label("xts_enc_done"));
        +
        +&set_label("xts_enc_three",16);
        +	&movaps	($inout5,$tweak);		# put aside last tweak
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&movups	($inout1,&QWP(16*1,$inp));
        +	&movups	($inout2,&QWP(16*2,$inp));
        +	&lea	($inp,&DWP(16*3,$inp));
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	&xorps	($inout1,$inout4);
        +	&xorps	($inout2,$inout5);
        +
        +	&call	("_aesni_encrypt3");
        +
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&xorps	($inout1,$inout4);
        +	&xorps	($inout2,$inout5);
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&lea	($out,&DWP(16*3,$out));
        +
        +	&movdqa	($tweak,$inout5);		# last tweak
        +	&jmp	(&label("xts_enc_done"));
        +
        +&set_label("xts_enc_four",16);
        +	&movaps	($inout4,$tweak);		# put aside last tweak
        +
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&movups	($inout1,&QWP(16*1,$inp));
        +	&movups	($inout2,&QWP(16*2,$inp));
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# input^=tweak
        +	&movups	($inout3,&QWP(16*3,$inp));
        +	&lea	($inp,&DWP(16*4,$inp));
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&xorps	($inout2,$inout5);
        +	&xorps	($inout3,$inout4);
        +
        +	&call	("_aesni_encrypt4");
        +
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&xorps	($inout2,$inout5);
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&xorps	($inout3,$inout4);
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&movups	(&QWP(16*3,$out),$inout3);
        +	&lea	($out,&DWP(16*4,$out));
        +
        +	&movdqa	($tweak,$inout4);		# last tweak
        +	&jmp	(&label("xts_enc_done"));
        +
        +&set_label("xts_enc_done6x",16);		# $tweak is pre-calculated
        +	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
        +	&and	($len,15);
        +	&jz	(&label("xts_enc_ret"));
        +	&movdqa	($inout3,$tweak);
        +	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
        +	&jmp	(&label("xts_enc_steal"));
        +
        +&set_label("xts_enc_done",16);
        +	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
        +	&pxor	($twtmp,$twtmp);
        +	&and	($len,15);
        +	&jz	(&label("xts_enc_ret"));
        +
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
        +	&pshufd	($inout3,$twtmp,0x13);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($inout3,&QWP(16*6,"esp"));	# isolate carry and residue
        +	&pxor	($inout3,$tweak);
        +
        +&set_label("xts_enc_steal");
        +	&movz	($rounds,&BP(0,$inp));
        +	&movz	($key,&BP(-16,$out));
        +	&lea	($inp,&DWP(1,$inp));
        +	&mov	(&BP(-16,$out),&LB($rounds));
        +	&mov	(&BP(0,$out),&LB($key));
        +	&lea	($out,&DWP(1,$out));
        +	&sub	($len,1);
        +	&jnz	(&label("xts_enc_steal"));
        +
        +	&sub	($out,&DWP(16*7+0,"esp"));	# rewind $out
        +	&mov	($key,$key_);			# restore $key
        +	&mov	($rounds,$rounds_);		# restore $rounds
        +
        +	&movups	($inout0,&QWP(-16,$out));	# load input
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&movups	(&QWP(-16,$out),$inout0);	# write output
        +
        +&set_label("xts_enc_ret");
        +	&mov	("esp",&DWP(16*7+4,"esp"));	# restore %esp
        +&function_end("aesni_xts_encrypt");
        +
        +&function_begin("aesni_xts_decrypt");
        +	&mov	($key,&wparam(4));		# key2
        +	&mov	($inp,&wparam(5));		# clear-text tweak
        +
        +	&mov	($rounds,&DWP(240,$key));	# key2->rounds
        +	&movups	($inout0,&QWP(0,$inp));
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc");	}
        +	else
        +	{   &call	("_aesni_encrypt1");	}
        +
        +	&mov	($inp,&wparam(0));
        +	&mov	($out,&wparam(1));
        +	&mov	($len,&wparam(2));
        +	&mov	($key,&wparam(3));		# key1
        +
        +	&mov	($key_,"esp");
        +	&sub	("esp",16*7+8);
        +	&and	("esp",-16);			# align stack
        +
        +	&xor	($rounds_,$rounds_);		# if(len%16) len-=16;
        +	&test	($len,15);
        +	&setnz	(&LB($rounds_));
        +	&shl	($rounds_,4);
        +	&sub	($len,$rounds_);
        +
        +	&mov	(&DWP(16*6+0,"esp"),0x87);	# compose the magic constant
        +	&mov	(&DWP(16*6+4,"esp"),0);
        +	&mov	(&DWP(16*6+8,"esp"),1);
        +	&mov	(&DWP(16*6+12,"esp"),0);
        +	&mov	(&DWP(16*7+0,"esp"),$len);	# save original $len
        +	&mov	(&DWP(16*7+4,"esp"),$key_);	# save original %esp
        +
        +	&mov	($rounds,&DWP(240,$key));	# key1->rounds
        +	&mov	($key_,$key);			# backup $key
        +	&mov	($rounds_,$rounds);		# backup $rounds
        +
        +	&movdqa	($tweak,$inout0);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($twmask,&QWP(6*16,"esp"));	# 0x0...010...87
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +
        +	&and	($len,-16);
        +	&sub	($len,16*6);
        +	&jc	(&label("xts_dec_short"));
        +
        +	&shr	($rounds,1);
        +	&mov	($rounds_,$rounds);
        +	&jmp	(&label("xts_dec_loop6"));
        +
        +&set_label("xts_dec_loop6",16);
        +	for ($i=0;$i<4;$i++) {
        +	    &pshufd	($twres,$twtmp,0x13);
        +	    &pxor	($twtmp,$twtmp);
        +	    &movdqa	(&QWP(16*$i,"esp"),$tweak);
        +	    &paddq	($tweak,$tweak);	# &psllq($tweak,1);
        +	    &pand	($twres,$twmask);	# isolate carry and residue
        +	    &pcmpgtd	($twtmp,$tweak);	# broadcast upper bits
        +	    &pxor	($tweak,$twres);
        +	}
        +	&pshufd	($inout5,$twtmp,0x13);
        +	&movdqa	(&QWP(16*$i++,"esp"),$tweak);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	 &$movekey	($rndkey0,&QWP(0,$key_));
        +	&pand	($inout5,$twmask);		# isolate carry and residue
        +	 &movups	($inout0,&QWP(0,$inp));	# load input
        +	&pxor	($inout5,$tweak);
        +
        +	# inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
        +	&movdqu	($inout1,&QWP(16*1,$inp));
        +	 &xorps		($inout0,$rndkey0);	# input^=rndkey[0]
        +	&movdqu	($inout2,&QWP(16*2,$inp));
        +	 &pxor		($inout1,$rndkey0);
        +	&movdqu	($inout3,&QWP(16*3,$inp));
        +	 &pxor		($inout2,$rndkey0);
        +	&movdqu	($inout4,&QWP(16*4,$inp));
        +	 &pxor		($inout3,$rndkey0);
        +	&movdqu	($rndkey1,&QWP(16*5,$inp));
        +	 &pxor		($inout4,$rndkey0);
        +	&lea	($inp,&DWP(16*6,$inp));
        +	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
        +	&movdqa	(&QWP(16*$i,"esp"),$inout5);	# save last tweak
        +	&pxor	($inout5,$rndkey1);
        +
        +	 &$movekey	($rndkey1,&QWP(16,$key_));
        +	 &lea		($key,&DWP(32,$key_));
        +	&pxor	($inout1,&QWP(16*1,"esp"));
        +	 &aesdec	($inout0,$rndkey1);
        +	&pxor	($inout2,&QWP(16*2,"esp"));
        +	 &aesdec	($inout1,$rndkey1);
        +	&pxor	($inout3,&QWP(16*3,"esp"));
        +	 &dec		($rounds);
        +	 &aesdec	($inout2,$rndkey1);
        +	&pxor	($inout4,&QWP(16*4,"esp"));
        +	 &aesdec	($inout3,$rndkey1);
        +	&pxor		($inout5,$rndkey0);
        +	 &aesdec	($inout4,$rndkey1);
        +	 &$movekey	($rndkey0,&QWP(0,$key));
        +	 &aesdec	($inout5,$rndkey1);
        +	&call		(&label("_aesni_decrypt6_enter"));
        +
        +	&movdqa	($tweak,&QWP(16*5,"esp"));	# last tweak
        +       &pxor	($twtmp,$twtmp);
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
        +       &pcmpgtd	($twtmp,$tweak);		# broadcast upper bits
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&xorps	($inout2,&QWP(16*2,"esp"));
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&xorps	($inout3,&QWP(16*3,"esp"));
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&xorps	($inout4,&QWP(16*4,"esp"));
        +	&movups	(&QWP(16*3,$out),$inout3);
        +	&xorps	($inout5,$tweak);
        +	&movups	(&QWP(16*4,$out),$inout4);
        +       &pshufd	($twres,$twtmp,0x13);
        +	&movups	(&QWP(16*5,$out),$inout5);
        +	&lea	($out,&DWP(16*6,$out));
        +       &movdqa	($twmask,&QWP(16*6,"esp"));	# 0x0...010...87
        +
        +	&pxor	($twtmp,$twtmp);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&mov	($rounds,$rounds_);		# restore $rounds
        +	&pxor	($tweak,$twres);
        +
        +	&sub	($len,16*6);
        +	&jnc	(&label("xts_dec_loop6"));
        +
        +	&lea	($rounds,&DWP(1,"",$rounds,2));	# restore $rounds
        +	&mov	($key,$key_);			# restore $key
        +	&mov	($rounds_,$rounds);
        +
        +&set_label("xts_dec_short");
        +	&add	($len,16*6);
        +	&jz	(&label("xts_dec_done6x"));
        +
        +	&movdqa	($inout3,$tweak);		# put aside previous tweak
        +	&cmp	($len,0x20);
        +	&jb	(&label("xts_dec_one"));
        +
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +	&je	(&label("xts_dec_two"));
        +
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($inout4,$tweak);		# put aside previous tweak
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +	&cmp	($len,0x40);
        +	&jb	(&label("xts_dec_three"));
        +
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($inout5,$tweak);		# put aside previous tweak
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +	&movdqa	(&QWP(16*0,"esp"),$inout3);
        +	&movdqa	(&QWP(16*1,"esp"),$inout4);
        +	&je	(&label("xts_dec_four"));
        +
        +	&movdqa	(&QWP(16*2,"esp"),$inout5);
        +	&pshufd	($inout5,$twtmp,0x13);
        +	&movdqa	(&QWP(16*3,"esp"),$tweak);
        +	&paddq	($tweak,$tweak);		# &psllq($inout0,1);
        +	&pand	($inout5,$twmask);		# isolate carry and residue
        +	&pxor	($inout5,$tweak);
        +
        +	&movdqu	($inout0,&QWP(16*0,$inp));	# load input
        +	&movdqu	($inout1,&QWP(16*1,$inp));
        +	&movdqu	($inout2,&QWP(16*2,$inp));
        +	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
        +	&movdqu	($inout3,&QWP(16*3,$inp));
        +	&pxor	($inout1,&QWP(16*1,"esp"));
        +	&movdqu	($inout4,&QWP(16*4,$inp));
        +	&pxor	($inout2,&QWP(16*2,"esp"));
        +	&lea	($inp,&DWP(16*5,$inp));
        +	&pxor	($inout3,&QWP(16*3,"esp"));
        +	&movdqa	(&QWP(16*4,"esp"),$inout5);	# save last tweak
        +	&pxor	($inout4,$inout5);
        +
        +	&call	("_aesni_decrypt6");
        +
        +	&movaps	($tweak,&QWP(16*4,"esp"));	# last tweak
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&xorps	($inout2,&QWP(16*2,"esp"));
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&xorps	($inout3,&QWP(16*3,"esp"));
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&xorps	($inout4,$tweak);
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&movups	(&QWP(16*3,$out),$inout3);
        +	&movups	(&QWP(16*4,$out),$inout4);
        +	&lea	($out,&DWP(16*5,$out));
        +	&jmp	(&label("xts_dec_done"));
        +
        +&set_label("xts_dec_one",16);
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&lea	($inp,&DWP(16*1,$inp));
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	if ($inline)
        +	{   &aesni_inline_generate1("dec");	}
        +	else
        +	{   &call	("_aesni_decrypt1");	}
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&lea	($out,&DWP(16*1,$out));
        +
        +	&movdqa	($tweak,$inout3);		# last tweak
        +	&jmp	(&label("xts_dec_done"));
        +
        +&set_label("xts_dec_two",16);
        +	&movaps	($inout4,$tweak);		# put aside last tweak
        +
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&movups	($inout1,&QWP(16*1,$inp));
        +	&lea	($inp,&DWP(16*2,$inp));
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	&xorps	($inout1,$inout4);
        +
        +	&call	("_aesni_decrypt3");
        +
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&xorps	($inout1,$inout4);
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&lea	($out,&DWP(16*2,$out));
        +
        +	&movdqa	($tweak,$inout4);		# last tweak
        +	&jmp	(&label("xts_dec_done"));
        +
        +&set_label("xts_dec_three",16);
        +	&movaps	($inout5,$tweak);		# put aside last tweak
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&movups	($inout1,&QWP(16*1,$inp));
        +	&movups	($inout2,&QWP(16*2,$inp));
        +	&lea	($inp,&DWP(16*3,$inp));
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	&xorps	($inout1,$inout4);
        +	&xorps	($inout2,$inout5);
        +
        +	&call	("_aesni_decrypt3");
        +
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&xorps	($inout1,$inout4);
        +	&xorps	($inout2,$inout5);
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&lea	($out,&DWP(16*3,$out));
        +
        +	&movdqa	($tweak,$inout5);		# last tweak
        +	&jmp	(&label("xts_dec_done"));
        +
        +&set_label("xts_dec_four",16);
        +	&movaps	($inout4,$tweak);		# put aside last tweak
        +
        +	&movups	($inout0,&QWP(16*0,$inp));	# load input
        +	&movups	($inout1,&QWP(16*1,$inp));
        +	&movups	($inout2,&QWP(16*2,$inp));
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# input^=tweak
        +	&movups	($inout3,&QWP(16*3,$inp));
        +	&lea	($inp,&DWP(16*4,$inp));
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&xorps	($inout2,$inout5);
        +	&xorps	($inout3,$inout4);
        +
        +	&call	("_aesni_decrypt4");
        +
        +	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
        +	&xorps	($inout1,&QWP(16*1,"esp"));
        +	&xorps	($inout2,$inout5);
        +	&movups	(&QWP(16*0,$out),$inout0);	# write output
        +	&xorps	($inout3,$inout4);
        +	&movups	(&QWP(16*1,$out),$inout1);
        +	&movups	(&QWP(16*2,$out),$inout2);
        +	&movups	(&QWP(16*3,$out),$inout3);
        +	&lea	($out,&DWP(16*4,$out));
        +
        +	&movdqa	($tweak,$inout4);		# last tweak
        +	&jmp	(&label("xts_dec_done"));
        +
        +&set_label("xts_dec_done6x",16);		# $tweak is pre-calculated
        +	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
        +	&and	($len,15);
        +	&jz	(&label("xts_dec_ret"));
        +	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
        +	&jmp	(&label("xts_dec_only_one_more"));
        +
        +&set_label("xts_dec_done",16);
        +	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
        +	&pxor	($twtmp,$twtmp);
        +	&and	($len,15);
        +	&jz	(&label("xts_dec_ret"));
        +
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
        +	&pshufd	($twres,$twtmp,0x13);
        +	&pxor	($twtmp,$twtmp);
        +	&movdqa	($twmask,&QWP(16*6,"esp"));
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($twres,$twmask);		# isolate carry and residue
        +	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
        +	&pxor	($tweak,$twres);
        +
        +&set_label("xts_dec_only_one_more");
        +	&pshufd	($inout3,$twtmp,0x13);
        +	&movdqa	($inout4,$tweak);		# put aside previous tweak
        +	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
        +	&pand	($inout3,$twmask);		# isolate carry and residue
        +	&pxor	($inout3,$tweak);
        +
        +	&mov	($key,$key_);			# restore $key
        +	&mov	($rounds,$rounds_);		# restore $rounds
        +
        +	&movups	($inout0,&QWP(0,$inp));		# load input
        +	&xorps	($inout0,$inout3);		# input^=tweak
        +	if ($inline)
        +	{   &aesni_inline_generate1("dec");	}
        +	else
        +	{   &call	("_aesni_decrypt1");	}
        +	&xorps	($inout0,$inout3);		# output^=tweak
        +	&movups	(&QWP(0,$out),$inout0);		# write output
        +
        +&set_label("xts_dec_steal");
        +	&movz	($rounds,&BP(16,$inp));
        +	&movz	($key,&BP(0,$out));
        +	&lea	($inp,&DWP(1,$inp));
        +	&mov	(&BP(0,$out),&LB($rounds));
        +	&mov	(&BP(16,$out),&LB($key));
        +	&lea	($out,&DWP(1,$out));
        +	&sub	($len,1);
        +	&jnz	(&label("xts_dec_steal"));
        +
        +	&sub	($out,&DWP(16*7+0,"esp"));	# rewind $out
        +	&mov	($key,$key_);			# restore $key
        +	&mov	($rounds,$rounds_);		# restore $rounds
        +
        +	&movups	($inout0,&QWP(0,$out));		# load input
        +	&xorps	($inout0,$inout4);		# input^=tweak
        +	if ($inline)
        +	{   &aesni_inline_generate1("dec");	}
        +	else
        +	{   &call	("_aesni_decrypt1");	}
        +	&xorps	($inout0,$inout4);		# output^=tweak
        +	&movups	(&QWP(0,$out),$inout0);		# write output
        +
        +&set_label("xts_dec_ret");
        +	&mov	("esp",&DWP(16*7+4,"esp"));	# restore %esp
        +&function_end("aesni_xts_decrypt");
        +}
        +}
        +
        +######################################################################
        +# void $PREFIX_cbc_encrypt (const void *inp, void *out,
        +#                           size_t length, const AES_KEY *key,
        +#                           unsigned char *ivp,const int enc);
        +&function_begin("${PREFIX}_cbc_encrypt");
        +	&mov	($inp,&wparam(0));
        +	&mov	($rounds_,"esp");
        +	&mov	($out,&wparam(1));
        +	&sub	($rounds_,24);
        +	&mov	($len,&wparam(2));
        +	&and	($rounds_,-16);
        +	&mov	($key,&wparam(3));
        +	&mov	($key_,&wparam(4));
        +	&test	($len,$len);
        +	&jz	(&label("cbc_abort"));
        +
        +	&cmp	(&wparam(5),0);
        +	&xchg	($rounds_,"esp");		# alloca
        +	&movups	($ivec,&QWP(0,$key_));		# load IV
        +	&mov	($rounds,&DWP(240,$key));
        +	&mov	($key_,$key);			# backup $key
        +	&mov	(&DWP(16,"esp"),$rounds_);	# save original %esp
        +	&mov	($rounds_,$rounds);		# backup $rounds
        +	&je	(&label("cbc_decrypt"));
        +
        +	&movaps	($inout0,$ivec);
        +	&cmp	($len,16);
        +	&jb	(&label("cbc_enc_tail"));
        +	&sub	($len,16);
        +	&jmp	(&label("cbc_enc_loop"));
        +
        +&set_label("cbc_enc_loop",16);
        +	&movups	($ivec,&QWP(0,$inp));		# input actually
        +	&lea	($inp,&DWP(16,$inp));
        +	if ($inline)
        +	{   &aesni_inline_generate1("enc",$inout0,$ivec);	}
        +	else
        +	{   &xorps($inout0,$ivec); &call("_aesni_encrypt1");	}
        +	&mov	($rounds,$rounds_);	# restore $rounds
        +	&mov	($key,$key_);		# restore $key
        +	&movups	(&QWP(0,$out),$inout0);	# store output
        +	&lea	($out,&DWP(16,$out));
        +	&sub	($len,16);
        +	&jnc	(&label("cbc_enc_loop"));
        +	&add	($len,16);
        +	&jnz	(&label("cbc_enc_tail"));
        +	&movaps	($ivec,$inout0);
        +	&jmp	(&label("cbc_ret"));
        +
        +&set_label("cbc_enc_tail");
        +	&mov	("ecx",$len);		# zaps $rounds
        +	&data_word(0xA4F3F689);		# rep movsb
        +	&mov	("ecx",16);		# zero tail
        +	&sub	("ecx",$len);
        +	&xor	("eax","eax");		# zaps $len
        +	&data_word(0xAAF3F689);		# rep stosb
        +	&lea	($out,&DWP(-16,$out));	# rewind $out by 1 block
        +	&mov	($rounds,$rounds_);	# restore $rounds
        +	&mov	($inp,$out);		# $inp and $out are the same
        +	&mov	($key,$key_);		# restore $key
        +	&jmp	(&label("cbc_enc_loop"));
        +######################################################################
        +&set_label("cbc_decrypt",16);
        +	&cmp	($len,0x50);
        +	&jbe	(&label("cbc_dec_tail"));
        +	&movaps	(&QWP(0,"esp"),$ivec);		# save IV
        +	&sub	($len,0x50);
        +	&jmp	(&label("cbc_dec_loop6_enter"));
        +
        +&set_label("cbc_dec_loop6",16);
        +	&movaps	(&QWP(0,"esp"),$rndkey0);	# save IV
        +	&movups	(&QWP(0,$out),$inout5);
        +	&lea	($out,&DWP(0x10,$out));
        +&set_label("cbc_dec_loop6_enter");
        +	&movdqu	($inout0,&QWP(0,$inp));
        +	&movdqu	($inout1,&QWP(0x10,$inp));
        +	&movdqu	($inout2,&QWP(0x20,$inp));
        +	&movdqu	($inout3,&QWP(0x30,$inp));
        +	&movdqu	($inout4,&QWP(0x40,$inp));
        +	&movdqu	($inout5,&QWP(0x50,$inp));
        +
        +	&call	("_aesni_decrypt6");
        +
        +	&movups	($rndkey1,&QWP(0,$inp));
        +	&movups	($rndkey0,&QWP(0x10,$inp));
        +	&xorps	($inout0,&QWP(0,"esp"));	# ^=IV
        +	&xorps	($inout1,$rndkey1);
        +	&movups	($rndkey1,&QWP(0x20,$inp));
        +	&xorps	($inout2,$rndkey0);
        +	&movups	($rndkey0,&QWP(0x30,$inp));
        +	&xorps	($inout3,$rndkey1);
        +	&movups	($rndkey1,&QWP(0x40,$inp));
        +	&xorps	($inout4,$rndkey0);
        +	&movups	($rndkey0,&QWP(0x50,$inp));	# IV
        +	&xorps	($inout5,$rndkey1);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&lea	($inp,&DWP(0x60,$inp));
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&mov	($rounds,$rounds_)		# restore $rounds
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&mov	($key,$key_);			# restore $key
        +	&movups	(&QWP(0x40,$out),$inout4);
        +	&lea	($out,&DWP(0x50,$out));
        +	&sub	($len,0x60);
        +	&ja	(&label("cbc_dec_loop6"));
        +
        +	&movaps	($inout0,$inout5);
        +	&movaps	($ivec,$rndkey0);
        +	&add	($len,0x50);
        +	&jle	(&label("cbc_dec_tail_collected"));
        +	&movups	(&QWP(0,$out),$inout0);
        +	&lea	($out,&DWP(0x10,$out));
        +&set_label("cbc_dec_tail");
        +	&movups	($inout0,&QWP(0,$inp));
        +	&movaps	($in0,$inout0);
        +	&cmp	($len,0x10);
        +	&jbe	(&label("cbc_dec_one"));
        +
        +	&movups	($inout1,&QWP(0x10,$inp));
        +	&movaps	($in1,$inout1);
        +	&cmp	($len,0x20);
        +	&jbe	(&label("cbc_dec_two"));
        +
        +	&movups	($inout2,&QWP(0x20,$inp));
        +	&cmp	($len,0x30);
        +	&jbe	(&label("cbc_dec_three"));
        +
        +	&movups	($inout3,&QWP(0x30,$inp));
        +	&cmp	($len,0x40);
        +	&jbe	(&label("cbc_dec_four"));
        +
        +	&movups	($inout4,&QWP(0x40,$inp));
        +	&movaps	(&QWP(0,"esp"),$ivec);		# save IV
        +	&movups	($inout0,&QWP(0,$inp));
        +	&xorps	($inout5,$inout5);
        +	&call	("_aesni_decrypt6");
        +	&movups	($rndkey1,&QWP(0,$inp));
        +	&movups	($rndkey0,&QWP(0x10,$inp));
        +	&xorps	($inout0,&QWP(0,"esp"));	# ^= IV
        +	&xorps	($inout1,$rndkey1);
        +	&movups	($rndkey1,&QWP(0x20,$inp));
        +	&xorps	($inout2,$rndkey0);
        +	&movups	($rndkey0,&QWP(0x30,$inp));
        +	&xorps	($inout3,$rndkey1);
        +	&movups	($ivec,&QWP(0x40,$inp));	# IV
        +	&xorps	($inout4,$rndkey0);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&movups	(&QWP(0x30,$out),$inout3);
        +	&lea	($out,&DWP(0x40,$out));
        +	&movaps	($inout0,$inout4);
        +	&sub	($len,0x50);
        +	&jmp	(&label("cbc_dec_tail_collected"));
        +
        +&set_label("cbc_dec_one",16);
        +	if ($inline)
        +	{   &aesni_inline_generate1("dec");	}
        +	else
        +	{   &call	("_aesni_decrypt1");	}
        +	&xorps	($inout0,$ivec);
        +	&movaps	($ivec,$in0);
        +	&sub	($len,0x10);
        +	&jmp	(&label("cbc_dec_tail_collected"));
        +
        +&set_label("cbc_dec_two",16);
        +	&xorps	($inout2,$inout2);
        +	&call	("_aesni_decrypt3");
        +	&xorps	($inout0,$ivec);
        +	&xorps	($inout1,$in0);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movaps	($inout0,$inout1);
        +	&lea	($out,&DWP(0x10,$out));
        +	&movaps	($ivec,$in1);
        +	&sub	($len,0x20);
        +	&jmp	(&label("cbc_dec_tail_collected"));
        +
        +&set_label("cbc_dec_three",16);
        +	&call	("_aesni_decrypt3");
        +	&xorps	($inout0,$ivec);
        +	&xorps	($inout1,$in0);
        +	&xorps	($inout2,$in1);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&movaps	($inout0,$inout2);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&lea	($out,&DWP(0x20,$out));
        +	&movups	($ivec,&QWP(0x20,$inp));
        +	&sub	($len,0x30);
        +	&jmp	(&label("cbc_dec_tail_collected"));
        +
        +&set_label("cbc_dec_four",16);
        +	&call	("_aesni_decrypt4");
        +	&movups	($rndkey1,&QWP(0x10,$inp));
        +	&movups	($rndkey0,&QWP(0x20,$inp));
        +	&xorps	($inout0,$ivec);
        +	&movups	($ivec,&QWP(0x30,$inp));
        +	&xorps	($inout1,$in0);
        +	&movups	(&QWP(0,$out),$inout0);
        +	&xorps	($inout2,$rndkey1);
        +	&movups	(&QWP(0x10,$out),$inout1);
        +	&xorps	($inout3,$rndkey0);
        +	&movups	(&QWP(0x20,$out),$inout2);
        +	&lea	($out,&DWP(0x30,$out));
        +	&movaps	($inout0,$inout3);
        +	&sub	($len,0x40);
        +
        +&set_label("cbc_dec_tail_collected");
        +	&and	($len,15);
        +	&jnz	(&label("cbc_dec_tail_partial"));
        +	&movups	(&QWP(0,$out),$inout0);
        +	&jmp	(&label("cbc_ret"));
        +
        +&set_label("cbc_dec_tail_partial",16);
        +	&movaps	(&QWP(0,"esp"),$inout0);
        +	&mov	("ecx",16);
        +	&mov	($inp,"esp");
        +	&sub	("ecx",$len);
        +	&data_word(0xA4F3F689);		# rep movsb
        +
        +&set_label("cbc_ret");
        +	&mov	("esp",&DWP(16,"esp"));	# pull original %esp
        +	&mov	($key_,&wparam(4));
        +	&movups	(&QWP(0,$key_),$ivec);	# output IV
        +&set_label("cbc_abort");
        +&function_end("${PREFIX}_cbc_encrypt");
        +
        +######################################################################
        +# Mechanical port from aesni-x86_64.pl.
        +#
        +# _aesni_set_encrypt_key is private interface,
        +# input:
        +#	"eax"	const unsigned char *userKey
        +#	$rounds	int bits
        +#	$key	AES_KEY *key
        +# output:
        +#	"eax"	return code
        +#	$round	rounds
        +
        +&function_begin_B("_aesni_set_encrypt_key");
        +	&test	("eax","eax");
        +	&jz	(&label("bad_pointer"));
        +	&test	($key,$key);
        +	&jz	(&label("bad_pointer"));
        +
        +	&movups	("xmm0",&QWP(0,"eax"));	# pull first 128 bits of *userKey
        +	&xorps	("xmm4","xmm4");	# low dword of xmm4 is assumed 0
        +	&lea	($key,&DWP(16,$key));
        +	&cmp	($rounds,256);
        +	&je	(&label("14rounds"));
        +	&cmp	($rounds,192);
        +	&je	(&label("12rounds"));
        +	&cmp	($rounds,128);
        +	&jne	(&label("bad_keybits"));
        +
        +&set_label("10rounds",16);
        +	&mov		($rounds,9);
        +	&$movekey	(&QWP(-16,$key),"xmm0");	# round 0
        +	&aeskeygenassist("xmm1","xmm0",0x01);		# round 1
        +	&call		(&label("key_128_cold"));
        +	&aeskeygenassist("xmm1","xmm0",0x2);		# round 2
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x04);		# round 3
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x08);		# round 4
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x10);		# round 5
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x20);		# round 6
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x40);		# round 7
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x80);		# round 8
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x1b);		# round 9
        +	&call		(&label("key_128"));
        +	&aeskeygenassist("xmm1","xmm0",0x36);		# round 10
        +	&call		(&label("key_128"));
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +	&mov		(&DWP(80,$key),$rounds);
        +	&xor		("eax","eax");
        +	&ret();
        +
        +&set_label("key_128",16);
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +	&lea		($key,&DWP(16,$key));
        +&set_label("key_128_cold");
        +	&shufps		("xmm4","xmm0",0b00010000);
        +	&xorps		("xmm0","xmm4");
        +	&shufps		("xmm4","xmm0",0b10001100);
        +	&xorps		("xmm0","xmm4");
        +	&shufps		("xmm1","xmm1",0b11111111);	# critical path
        +	&xorps		("xmm0","xmm1");
        +	&ret();
        +
        +&set_label("12rounds",16);
        +	&movq		("xmm2",&QWP(16,"eax"));	# remaining 1/3 of *userKey
        +	&mov		($rounds,11);
        +	&$movekey	(&QWP(-16,$key),"xmm0")		# round 0
        +	&aeskeygenassist("xmm1","xmm2",0x01);		# round 1,2
        +	&call		(&label("key_192a_cold"));
        +	&aeskeygenassist("xmm1","xmm2",0x02);		# round 2,3
        +	&call		(&label("key_192b"));
        +	&aeskeygenassist("xmm1","xmm2",0x04);		# round 4,5
        +	&call		(&label("key_192a"));
        +	&aeskeygenassist("xmm1","xmm2",0x08);		# round 5,6
        +	&call		(&label("key_192b"));
        +	&aeskeygenassist("xmm1","xmm2",0x10);		# round 7,8
        +	&call		(&label("key_192a"));
        +	&aeskeygenassist("xmm1","xmm2",0x20);		# round 8,9
        +	&call		(&label("key_192b"));
        +	&aeskeygenassist("xmm1","xmm2",0x40);		# round 10,11
        +	&call		(&label("key_192a"));
        +	&aeskeygenassist("xmm1","xmm2",0x80);		# round 11,12
        +	&call		(&label("key_192b"));
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +	&mov		(&DWP(48,$key),$rounds);
        +	&xor		("eax","eax");
        +	&ret();
        +
        +&set_label("key_192a",16);
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +	&lea		($key,&DWP(16,$key));
        +&set_label("key_192a_cold",16);
        +	&movaps		("xmm5","xmm2");
        +&set_label("key_192b_warm");
        +	&shufps		("xmm4","xmm0",0b00010000);
        +	&movdqa		("xmm3","xmm2");
        +	&xorps		("xmm0","xmm4");
        +	&shufps		("xmm4","xmm0",0b10001100);
        +	&pslldq		("xmm3",4);
        +	&xorps		("xmm0","xmm4");
        +	&pshufd		("xmm1","xmm1",0b01010101);	# critical path
        +	&pxor		("xmm2","xmm3");
        +	&pxor		("xmm0","xmm1");
        +	&pshufd		("xmm3","xmm0",0b11111111);
        +	&pxor		("xmm2","xmm3");
        +	&ret();
        +
        +&set_label("key_192b",16);
        +	&movaps		("xmm3","xmm0");
        +	&shufps		("xmm5","xmm0",0b01000100);
        +	&$movekey	(&QWP(0,$key),"xmm5");
        +	&shufps		("xmm3","xmm2",0b01001110);
        +	&$movekey	(&QWP(16,$key),"xmm3");
        +	&lea		($key,&DWP(32,$key));
        +	&jmp		(&label("key_192b_warm"));
        +
        +&set_label("14rounds",16);
        +	&movups		("xmm2",&QWP(16,"eax"));	# remaining half of *userKey
        +	&mov		($rounds,13);
        +	&lea		($key,&DWP(16,$key));
        +	&$movekey	(&QWP(-32,$key),"xmm0");	# round 0
        +	&$movekey	(&QWP(-16,$key),"xmm2");	# round 1
        +	&aeskeygenassist("xmm1","xmm2",0x01);		# round 2
        +	&call		(&label("key_256a_cold"));
        +	&aeskeygenassist("xmm1","xmm0",0x01);		# round 3
        +	&call		(&label("key_256b"));
        +	&aeskeygenassist("xmm1","xmm2",0x02);		# round 4
        +	&call		(&label("key_256a"));
        +	&aeskeygenassist("xmm1","xmm0",0x02);		# round 5
        +	&call		(&label("key_256b"));
        +	&aeskeygenassist("xmm1","xmm2",0x04);		# round 6
        +	&call		(&label("key_256a"));
        +	&aeskeygenassist("xmm1","xmm0",0x04);		# round 7
        +	&call		(&label("key_256b"));
        +	&aeskeygenassist("xmm1","xmm2",0x08);		# round 8
        +	&call		(&label("key_256a"));
        +	&aeskeygenassist("xmm1","xmm0",0x08);		# round 9
        +	&call		(&label("key_256b"));
        +	&aeskeygenassist("xmm1","xmm2",0x10);		# round 10
        +	&call		(&label("key_256a"));
        +	&aeskeygenassist("xmm1","xmm0",0x10);		# round 11
        +	&call		(&label("key_256b"));
        +	&aeskeygenassist("xmm1","xmm2",0x20);		# round 12
        +	&call		(&label("key_256a"));
        +	&aeskeygenassist("xmm1","xmm0",0x20);		# round 13
        +	&call		(&label("key_256b"));
        +	&aeskeygenassist("xmm1","xmm2",0x40);		# round 14
        +	&call		(&label("key_256a"));
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +	&mov		(&DWP(16,$key),$rounds);
        +	&xor		("eax","eax");
        +	&ret();
        +
        +&set_label("key_256a",16);
        +	&$movekey	(&QWP(0,$key),"xmm2");
        +	&lea		($key,&DWP(16,$key));
        +&set_label("key_256a_cold");
        +	&shufps		("xmm4","xmm0",0b00010000);
        +	&xorps		("xmm0","xmm4");
        +	&shufps		("xmm4","xmm0",0b10001100);
        +	&xorps		("xmm0","xmm4");
        +	&shufps		("xmm1","xmm1",0b11111111);	# critical path
        +	&xorps		("xmm0","xmm1");
        +	&ret();
        +
        +&set_label("key_256b",16);
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +	&lea		($key,&DWP(16,$key));
        +
        +	&shufps		("xmm4","xmm2",0b00010000);
        +	&xorps		("xmm2","xmm4");
        +	&shufps		("xmm4","xmm2",0b10001100);
        +	&xorps		("xmm2","xmm4");
        +	&shufps		("xmm1","xmm1",0b10101010);	# critical path
        +	&xorps		("xmm2","xmm1");
        +	&ret();
        +
        +&set_label("bad_pointer",4);
        +	&mov	("eax",-1);
        +	&ret	();
        +&set_label("bad_keybits",4);
        +	&mov	("eax",-2);
        +	&ret	();
        +&function_end_B("_aesni_set_encrypt_key");
        +
        +# int $PREFIX_set_encrypt_key (const unsigned char *userKey, int bits,
        +#                              AES_KEY *key)
        +&function_begin_B("${PREFIX}_set_encrypt_key");
        +	&mov	("eax",&wparam(0));
        +	&mov	($rounds,&wparam(1));
        +	&mov	($key,&wparam(2));
        +	&call	("_aesni_set_encrypt_key");
        +	&ret	();
        +&function_end_B("${PREFIX}_set_encrypt_key");
        +
        +# int $PREFIX_set_decrypt_key (const unsigned char *userKey, int bits,
        +#                              AES_KEY *key)
        +&function_begin_B("${PREFIX}_set_decrypt_key");
        +	&mov	("eax",&wparam(0));
        +	&mov	($rounds,&wparam(1));
        +	&mov	($key,&wparam(2));
        +	&call	("_aesni_set_encrypt_key");
        +	&mov	($key,&wparam(2));
        +	&shl	($rounds,4)	# rounds-1 after _aesni_set_encrypt_key
        +	&test	("eax","eax");
        +	&jnz	(&label("dec_key_ret"));
        +	&lea	("eax",&DWP(16,$key,$rounds));	# end of key schedule
        +
        +	&$movekey	("xmm0",&QWP(0,$key));	# just swap
        +	&$movekey	("xmm1",&QWP(0,"eax"));
        +	&$movekey	(&QWP(0,"eax"),"xmm0");
        +	&$movekey	(&QWP(0,$key),"xmm1");
        +	&lea		($key,&DWP(16,$key));
        +	&lea		("eax",&DWP(-16,"eax"));
        +
        +&set_label("dec_key_inverse");
        +	&$movekey	("xmm0",&QWP(0,$key));	# swap and inverse
        +	&$movekey	("xmm1",&QWP(0,"eax"));
        +	&aesimc		("xmm0","xmm0");
        +	&aesimc		("xmm1","xmm1");
        +	&lea		($key,&DWP(16,$key));
        +	&lea		("eax",&DWP(-16,"eax"));
        +	&$movekey	(&QWP(16,"eax"),"xmm0");
        +	&$movekey	(&QWP(-16,$key),"xmm1");
        +	&cmp		("eax",$key);
        +	&ja		(&label("dec_key_inverse"));
        +
        +	&$movekey	("xmm0",&QWP(0,$key));	# inverse middle
        +	&aesimc		("xmm0","xmm0");
        +	&$movekey	(&QWP(0,$key),"xmm0");
        +
        +	&xor		("eax","eax");		# return success
        +&set_label("dec_key_ret");
        +	&ret	();
        +&function_end_B("${PREFIX}_set_decrypt_key");
        +&asciz("AES for Intel AES-NI, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl b/vendor/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl
        new file mode 100644
        index 000000000..0dbb194b8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/aesni-x86_64.pl
        @@ -0,0 +1,3069 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# This module implements support for Intel AES-NI extension. In
        +# OpenSSL context it's used with Intel engine, but can also be used as
        +# drop-in replacement for crypto/aes/asm/aes-x86_64.pl [see below for
        +# details].
        +#
        +# Performance.
        +#
        +# Given aes(enc|dec) instructions' latency asymptotic performance for
        +# non-parallelizable modes such as CBC encrypt is 3.75 cycles per byte
        +# processed with 128-bit key. And given their throughput asymptotic
        +# performance for parallelizable modes is 1.25 cycles per byte. Being
        +# asymptotic limit it's not something you commonly achieve in reality,
        +# but how close does one get? Below are results collected for
        +# different modes and block sized. Pairs of numbers are for en-/
        +# decryption.
        +#
        +#	16-byte     64-byte     256-byte    1-KB        8-KB
        +# ECB	4.25/4.25   1.38/1.38   1.28/1.28   1.26/1.26	1.26/1.26
        +# CTR	5.42/5.42   1.92/1.92   1.44/1.44   1.28/1.28   1.26/1.26
        +# CBC	4.38/4.43   4.15/1.43   4.07/1.32   4.07/1.29   4.06/1.28
        +# CCM	5.66/9.42   4.42/5.41   4.16/4.40   4.09/4.15   4.06/4.07   
        +# OFB	5.42/5.42   4.64/4.64   4.44/4.44   4.39/4.39   4.38/4.38
        +# CFB	5.73/5.85   5.56/5.62   5.48/5.56   5.47/5.55   5.47/5.55
        +#
        +# ECB, CTR, CBC and CCM results are free from EVP overhead. This means
        +# that otherwise used 'openssl speed -evp aes-128-??? -engine aesni
        +# [-decrypt]' will exhibit 10-15% worse results for smaller blocks.
        +# The results were collected with specially crafted speed.c benchmark
        +# in order to compare them with results reported in "Intel Advanced
        +# Encryption Standard (AES) New Instruction Set" White Paper Revision
        +# 3.0 dated May 2010. All above results are consistently better. This
        +# module also provides better performance for block sizes smaller than
        +# 128 bytes in points *not* represented in the above table.
        +#
        +# Looking at the results for 8-KB buffer.
        +#
        +# CFB and OFB results are far from the limit, because implementation
        +# uses "generic" CRYPTO_[c|o]fb128_encrypt interfaces relying on
        +# single-block aesni_encrypt, which is not the most optimal way to go.
        +# CBC encrypt result is unexpectedly high and there is no documented
        +# explanation for it. Seemingly there is a small penalty for feeding
        +# the result back to AES unit the way it's done in CBC mode. There is
        +# nothing one can do and the result appears optimal. CCM result is
        +# identical to CBC, because CBC-MAC is essentially CBC encrypt without
        +# saving output. CCM CTR "stays invisible," because it's neatly
        +# interleaved wih CBC-MAC. This provides ~30% improvement over
        +# "straghtforward" CCM implementation with CTR and CBC-MAC performed
        +# disjointly. Parallelizable modes practically achieve the theoretical
        +# limit.
        +#
        +# Looking at how results vary with buffer size.
        +#
        +# Curves are practically saturated at 1-KB buffer size. In most cases
        +# "256-byte" performance is >95%, and "64-byte" is ~90% of "8-KB" one.
        +# CTR curve doesn't follow this pattern and is "slowest" changing one
        +# with "256-byte" result being 87% of "8-KB." This is because overhead
        +# in CTR mode is most computationally intensive. Small-block CCM
        +# decrypt is slower than encrypt, because first CTR and last CBC-MAC
        +# iterations can't be interleaved.
        +#
        +# Results for 192- and 256-bit keys.
        +#
        +# EVP-free results were observed to scale perfectly with number of
        +# rounds for larger block sizes, i.e. 192-bit result being 10/12 times
        +# lower and 256-bit one - 10/14. Well, in CBC encrypt case differences
        +# are a tad smaller, because the above mentioned penalty biases all
        +# results by same constant value. In similar way function call
        +# overhead affects small-block performance, as well as OFB and CFB
        +# results. Differences are not large, most common coefficients are
        +# 10/11.7 and 10/13.4 (as opposite to 10/12.0 and 10/14.0), but one
        +# observe even 10/11.2 and 10/12.4 (CTR, OFB, CFB)...
        +
        +# January 2011
        +#
        +# While Westmere processor features 6 cycles latency for aes[enc|dec]
        +# instructions, which can be scheduled every second cycle, Sandy
        +# Bridge spends 8 cycles per instruction, but it can schedule them
        +# every cycle. This means that code targeting Westmere would perform
        +# suboptimally on Sandy Bridge. Therefore this update.
        +#
        +# In addition, non-parallelizable CBC encrypt (as well as CCM) is
        +# optimized. Relative improvement might appear modest, 8% on Westmere,
        +# but in absolute terms it's 3.77 cycles per byte encrypted with
        +# 128-bit key on Westmere, and 5.07 - on Sandy Bridge. These numbers
        +# should be compared to asymptotic limits of 3.75 for Westmere and
        +# 5.00 for Sandy Bridge. Actually, the fact that they get this close
        +# to asymptotic limits is quite amazing. Indeed, the limit is
        +# calculated as latency times number of rounds, 10 for 128-bit key,
        +# and divided by 16, the number of bytes in block, or in other words
        +# it accounts *solely* for aesenc instructions. But there are extra
        +# instructions, and numbers so close to the asymptotic limits mean
        +# that it's as if it takes as little as *one* additional cycle to
        +# execute all of them. How is it possible? It is possible thanks to
        +# out-of-order execution logic, which manages to overlap post-
        +# processing of previous block, things like saving the output, with
        +# actual encryption of current block, as well as pre-processing of
        +# current block, things like fetching input and xor-ing it with
        +# 0-round element of the key schedule, with actual encryption of
        +# previous block. Keep this in mind...
        +#
        +# For parallelizable modes, such as ECB, CBC decrypt, CTR, higher
        +# performance is achieved by interleaving instructions working on
        +# independent blocks. In which case asymptotic limit for such modes
        +# can be obtained by dividing above mentioned numbers by AES
        +# instructions' interleave factor. Westmere can execute at most 3 
        +# instructions at a time, meaning that optimal interleave factor is 3,
        +# and that's where the "magic" number of 1.25 come from. "Optimal
        +# interleave factor" means that increase of interleave factor does
        +# not improve performance. The formula has proven to reflect reality
        +# pretty well on Westmere... Sandy Bridge on the other hand can
        +# execute up to 8 AES instructions at a time, so how does varying
        +# interleave factor affect the performance? Here is table for ECB
        +# (numbers are cycles per byte processed with 128-bit key):
        +#
        +# instruction interleave factor		3x	6x	8x
        +# theoretical asymptotic limit		1.67	0.83	0.625
        +# measured performance for 8KB block	1.05	0.86	0.84
        +#
        +# "as if" interleave factor		4.7x	5.8x	6.0x
        +#
        +# Further data for other parallelizable modes:
        +#
        +# CBC decrypt				1.16	0.93	0.93
        +# CTR					1.14	0.91	n/a
        +#
        +# Well, given 3x column it's probably inappropriate to call the limit
        +# asymptotic, if it can be surpassed, isn't it? What happens there?
        +# Rewind to CBC paragraph for the answer. Yes, out-of-order execution
        +# magic is responsible for this. Processor overlaps not only the
        +# additional instructions with AES ones, but even AES instuctions
        +# processing adjacent triplets of independent blocks. In the 6x case
        +# additional instructions  still claim disproportionally small amount
        +# of additional cycles, but in 8x case number of instructions must be
        +# a tad too high for out-of-order logic to cope with, and AES unit
        +# remains underutilized... As you can see 8x interleave is hardly
        +# justifiable, so there no need to feel bad that 32-bit aesni-x86.pl
        +# utilizies 6x interleave because of limited register bank capacity.
        +#
        +# Higher interleave factors do have negative impact on Westmere
        +# performance. While for ECB mode it's negligible ~1.5%, other
        +# parallelizables perform ~5% worse, which is outweighed by ~25%
        +# improvement on Sandy Bridge. To balance regression on Westmere
        +# CTR mode was implemented with 6x aesenc interleave factor.
        +
        +# April 2011
        +#
        +# Add aesni_xts_[en|de]crypt. Westmere spends 1.33 cycles processing
        +# one byte out of 8KB with 128-bit key, Sandy Bridge - 0.97. Just like
        +# in CTR mode AES instruction interleave factor was chosen to be 6x.
        +
        +$PREFIX="aesni";	# if $PREFIX is set to "AES", the script
        +			# generates drop-in replacement for
        +			# crypto/aes/asm/aes-x86_64.pl:-)
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +$movkey = $PREFIX eq "aesni" ? "movups" : "movups";
        +@_4args=$win64?	("%rcx","%rdx","%r8", "%r9") :	# Win64 order
        +		("%rdi","%rsi","%rdx","%rcx");	# Unix order
        +
        +$code=".text\n";
        +
        +$rounds="%eax";	# input to and changed by aesni_[en|de]cryptN !!!
        +# this is natural Unix argument order for public $PREFIX_[ecb|cbc]_encrypt ...
        +$inp="%rdi";
        +$out="%rsi";
        +$len="%rdx";
        +$key="%rcx";	# input to and changed by aesni_[en|de]cryptN !!!
        +$ivp="%r8";	# cbc, ctr, ...
        +
        +$rnds_="%r10d";	# backup copy for $rounds
        +$key_="%r11";	# backup copy for $key
        +
        +# %xmm register layout
        +$rndkey0="%xmm0";	$rndkey1="%xmm1";
        +$inout0="%xmm2";	$inout1="%xmm3";
        +$inout2="%xmm4";	$inout3="%xmm5";
        +$inout4="%xmm6";	$inout5="%xmm7";
        +$inout6="%xmm8";	$inout7="%xmm9";
        +
        +$in2="%xmm6";		$in1="%xmm7";	# used in CBC decrypt, CTR, ...
        +$in0="%xmm8";		$iv="%xmm9";
        +
        +# Inline version of internal aesni_[en|de]crypt1.
        +#
        +# Why folded loop? Because aes[enc|dec] is slow enough to accommodate
        +# cycles which take care of loop variables...
        +{ my $sn;
        +sub aesni_generate1 {
        +my ($p,$key,$rounds,$inout,$ivec)=@_;	$inout=$inout0 if (!defined($inout));
        +++$sn;
        +$code.=<<___;
        +	$movkey	($key),$rndkey0
        +	$movkey	16($key),$rndkey1
        +___
        +$code.=<<___ if (defined($ivec));
        +	xorps	$rndkey0,$ivec
        +	lea	32($key),$key
        +	xorps	$ivec,$inout
        +___
        +$code.=<<___ if (!defined($ivec));
        +	lea	32($key),$key
        +	xorps	$rndkey0,$inout
        +___
        +$code.=<<___;
        +.Loop_${p}1_$sn:
        +	aes${p}	$rndkey1,$inout
        +	dec	$rounds
        +	$movkey	($key),$rndkey1
        +	lea	16($key),$key
        +	jnz	.Loop_${p}1_$sn	# loop body is 16 bytes
        +	aes${p}last	$rndkey1,$inout
        +___
        +}}
        +# void $PREFIX_[en|de]crypt (const void *inp,void *out,const AES_KEY *key);
        +#
        +{ my ($inp,$out,$key) = @_4args;
        +
        +$code.=<<___;
        +.globl	${PREFIX}_encrypt
        +.type	${PREFIX}_encrypt,\@abi-omnipotent
        +.align	16
        +${PREFIX}_encrypt:
        +	movups	($inp),$inout0		# load input
        +	mov	240($key),$rounds	# key->rounds
        +___
        +	&aesni_generate1("enc",$key,$rounds);
        +$code.=<<___;
        +	movups	$inout0,($out)		# output
        +	ret
        +.size	${PREFIX}_encrypt,.-${PREFIX}_encrypt
        +
        +.globl	${PREFIX}_decrypt
        +.type	${PREFIX}_decrypt,\@abi-omnipotent
        +.align	16
        +${PREFIX}_decrypt:
        +	movups	($inp),$inout0		# load input
        +	mov	240($key),$rounds	# key->rounds
        +___
        +	&aesni_generate1("dec",$key,$rounds);
        +$code.=<<___;
        +	movups	$inout0,($out)		# output
        +	ret
        +.size	${PREFIX}_decrypt, .-${PREFIX}_decrypt
        +___
        +}
        +
        +# _aesni_[en|de]cryptN are private interfaces, N denotes interleave
        +# factor. Why 3x subroutine were originally used in loops? Even though
        +# aes[enc|dec] latency was originally 6, it could be scheduled only
        +# every *2nd* cycle. Thus 3x interleave was the one providing optimal
        +# utilization, i.e. when subroutine's throughput is virtually same as
        +# of non-interleaved subroutine [for number of input blocks up to 3].
        +# This is why it makes no sense to implement 2x subroutine.
        +# aes[enc|dec] latency in next processor generation is 8, but the
        +# instructions can be scheduled every cycle. Optimal interleave for
        +# new processor is therefore 8x...
        +sub aesni_generate3 {
        +my $dir=shift;
        +# As already mentioned it takes in $key and $rounds, which are *not*
        +# preserved. $inout[0-2] is cipher/clear text...
        +$code.=<<___;
        +.type	_aesni_${dir}rypt3,\@abi-omnipotent
        +.align	16
        +_aesni_${dir}rypt3:
        +	$movkey	($key),$rndkey0
        +	shr	\$1,$rounds
        +	$movkey	16($key),$rndkey1
        +	lea	32($key),$key
        +	xorps	$rndkey0,$inout0
        +	xorps	$rndkey0,$inout1
        +	xorps	$rndkey0,$inout2
        +	$movkey		($key),$rndkey0
        +
        +.L${dir}_loop3:
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	dec		$rounds
        +	aes${dir}	$rndkey1,$inout2
        +	$movkey		16($key),$rndkey1
        +	aes${dir}	$rndkey0,$inout0
        +	aes${dir}	$rndkey0,$inout1
        +	lea		32($key),$key
        +	aes${dir}	$rndkey0,$inout2
        +	$movkey		($key),$rndkey0
        +	jnz		.L${dir}_loop3
        +
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}last	$rndkey0,$inout0
        +	aes${dir}last	$rndkey0,$inout1
        +	aes${dir}last	$rndkey0,$inout2
        +	ret
        +.size	_aesni_${dir}rypt3,.-_aesni_${dir}rypt3
        +___
        +}
        +# 4x interleave is implemented to improve small block performance,
        +# most notably [and naturally] 4 block by ~30%. One can argue that one
        +# should have implemented 5x as well, but improvement would be <20%,
        +# so it's not worth it...
        +sub aesni_generate4 {
        +my $dir=shift;
        +# As already mentioned it takes in $key and $rounds, which are *not*
        +# preserved. $inout[0-3] is cipher/clear text...
        +$code.=<<___;
        +.type	_aesni_${dir}rypt4,\@abi-omnipotent
        +.align	16
        +_aesni_${dir}rypt4:
        +	$movkey	($key),$rndkey0
        +	shr	\$1,$rounds
        +	$movkey	16($key),$rndkey1
        +	lea	32($key),$key
        +	xorps	$rndkey0,$inout0
        +	xorps	$rndkey0,$inout1
        +	xorps	$rndkey0,$inout2
        +	xorps	$rndkey0,$inout3
        +	$movkey	($key),$rndkey0
        +
        +.L${dir}_loop4:
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	dec		$rounds
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}	$rndkey1,$inout3
        +	$movkey		16($key),$rndkey1
        +	aes${dir}	$rndkey0,$inout0
        +	aes${dir}	$rndkey0,$inout1
        +	lea		32($key),$key
        +	aes${dir}	$rndkey0,$inout2
        +	aes${dir}	$rndkey0,$inout3
        +	$movkey		($key),$rndkey0
        +	jnz		.L${dir}_loop4
        +
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}	$rndkey1,$inout3
        +	aes${dir}last	$rndkey0,$inout0
        +	aes${dir}last	$rndkey0,$inout1
        +	aes${dir}last	$rndkey0,$inout2
        +	aes${dir}last	$rndkey0,$inout3
        +	ret
        +.size	_aesni_${dir}rypt4,.-_aesni_${dir}rypt4
        +___
        +}
        +sub aesni_generate6 {
        +my $dir=shift;
        +# As already mentioned it takes in $key and $rounds, which are *not*
        +# preserved. $inout[0-5] is cipher/clear text...
        +$code.=<<___;
        +.type	_aesni_${dir}rypt6,\@abi-omnipotent
        +.align	16
        +_aesni_${dir}rypt6:
        +	$movkey		($key),$rndkey0
        +	shr		\$1,$rounds
        +	$movkey		16($key),$rndkey1
        +	lea		32($key),$key
        +	xorps		$rndkey0,$inout0
        +	pxor		$rndkey0,$inout1
        +	aes${dir}	$rndkey1,$inout0
        +	pxor		$rndkey0,$inout2
        +	aes${dir}	$rndkey1,$inout1
        +	pxor		$rndkey0,$inout3
        +	aes${dir}	$rndkey1,$inout2
        +	pxor		$rndkey0,$inout4
        +	aes${dir}	$rndkey1,$inout3
        +	pxor		$rndkey0,$inout5
        +	dec		$rounds
        +	aes${dir}	$rndkey1,$inout4
        +	$movkey		($key),$rndkey0
        +	aes${dir}	$rndkey1,$inout5
        +	jmp		.L${dir}_loop6_enter
        +.align	16
        +.L${dir}_loop6:
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	dec		$rounds
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}	$rndkey1,$inout3
        +	aes${dir}	$rndkey1,$inout4
        +	aes${dir}	$rndkey1,$inout5
        +.L${dir}_loop6_enter:				# happens to be 16-byte aligned
        +	$movkey		16($key),$rndkey1
        +	aes${dir}	$rndkey0,$inout0
        +	aes${dir}	$rndkey0,$inout1
        +	lea		32($key),$key
        +	aes${dir}	$rndkey0,$inout2
        +	aes${dir}	$rndkey0,$inout3
        +	aes${dir}	$rndkey0,$inout4
        +	aes${dir}	$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	jnz		.L${dir}_loop6
        +
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}	$rndkey1,$inout3
        +	aes${dir}	$rndkey1,$inout4
        +	aes${dir}	$rndkey1,$inout5
        +	aes${dir}last	$rndkey0,$inout0
        +	aes${dir}last	$rndkey0,$inout1
        +	aes${dir}last	$rndkey0,$inout2
        +	aes${dir}last	$rndkey0,$inout3
        +	aes${dir}last	$rndkey0,$inout4
        +	aes${dir}last	$rndkey0,$inout5
        +	ret
        +.size	_aesni_${dir}rypt6,.-_aesni_${dir}rypt6
        +___
        +}
        +sub aesni_generate8 {
        +my $dir=shift;
        +# As already mentioned it takes in $key and $rounds, which are *not*
        +# preserved. $inout[0-7] is cipher/clear text...
        +$code.=<<___;
        +.type	_aesni_${dir}rypt8,\@abi-omnipotent
        +.align	16
        +_aesni_${dir}rypt8:
        +	$movkey		($key),$rndkey0
        +	shr		\$1,$rounds
        +	$movkey		16($key),$rndkey1
        +	lea		32($key),$key
        +	xorps		$rndkey0,$inout0
        +	xorps		$rndkey0,$inout1
        +	aes${dir}	$rndkey1,$inout0
        +	pxor		$rndkey0,$inout2
        +	aes${dir}	$rndkey1,$inout1
        +	pxor		$rndkey0,$inout3
        +	aes${dir}	$rndkey1,$inout2
        +	pxor		$rndkey0,$inout4
        +	aes${dir}	$rndkey1,$inout3
        +	pxor		$rndkey0,$inout5
        +	dec		$rounds
        +	aes${dir}	$rndkey1,$inout4
        +	pxor		$rndkey0,$inout6
        +	aes${dir}	$rndkey1,$inout5
        +	pxor		$rndkey0,$inout7
        +	$movkey		($key),$rndkey0
        +	aes${dir}	$rndkey1,$inout6
        +	aes${dir}	$rndkey1,$inout7
        +	$movkey		16($key),$rndkey1
        +	jmp		.L${dir}_loop8_enter
        +.align	16
        +.L${dir}_loop8:
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	dec		$rounds
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}	$rndkey1,$inout3
        +	aes${dir}	$rndkey1,$inout4
        +	aes${dir}	$rndkey1,$inout5
        +	aes${dir}	$rndkey1,$inout6
        +	aes${dir}	$rndkey1,$inout7
        +	$movkey		16($key),$rndkey1
        +.L${dir}_loop8_enter:				# happens to be 16-byte aligned
        +	aes${dir}	$rndkey0,$inout0
        +	aes${dir}	$rndkey0,$inout1
        +	lea		32($key),$key
        +	aes${dir}	$rndkey0,$inout2
        +	aes${dir}	$rndkey0,$inout3
        +	aes${dir}	$rndkey0,$inout4
        +	aes${dir}	$rndkey0,$inout5
        +	aes${dir}	$rndkey0,$inout6
        +	aes${dir}	$rndkey0,$inout7
        +	$movkey		($key),$rndkey0
        +	jnz		.L${dir}_loop8
        +
        +	aes${dir}	$rndkey1,$inout0
        +	aes${dir}	$rndkey1,$inout1
        +	aes${dir}	$rndkey1,$inout2
        +	aes${dir}	$rndkey1,$inout3
        +	aes${dir}	$rndkey1,$inout4
        +	aes${dir}	$rndkey1,$inout5
        +	aes${dir}	$rndkey1,$inout6
        +	aes${dir}	$rndkey1,$inout7
        +	aes${dir}last	$rndkey0,$inout0
        +	aes${dir}last	$rndkey0,$inout1
        +	aes${dir}last	$rndkey0,$inout2
        +	aes${dir}last	$rndkey0,$inout3
        +	aes${dir}last	$rndkey0,$inout4
        +	aes${dir}last	$rndkey0,$inout5
        +	aes${dir}last	$rndkey0,$inout6
        +	aes${dir}last	$rndkey0,$inout7
        +	ret
        +.size	_aesni_${dir}rypt8,.-_aesni_${dir}rypt8
        +___
        +}
        +&aesni_generate3("enc") if ($PREFIX eq "aesni");
        +&aesni_generate3("dec");
        +&aesni_generate4("enc") if ($PREFIX eq "aesni");
        +&aesni_generate4("dec");
        +&aesni_generate6("enc") if ($PREFIX eq "aesni");
        +&aesni_generate6("dec");
        +&aesni_generate8("enc") if ($PREFIX eq "aesni");
        +&aesni_generate8("dec");
        +
        +if ($PREFIX eq "aesni") {
        +########################################################################
        +# void aesni_ecb_encrypt (const void *in, void *out,
        +#			  size_t length, const AES_KEY *key,
        +#			  int enc);
        +$code.=<<___;
        +.globl	aesni_ecb_encrypt
        +.type	aesni_ecb_encrypt,\@function,5
        +.align	16
        +aesni_ecb_encrypt:
        +	and	\$-16,$len
        +	jz	.Lecb_ret
        +
        +	mov	240($key),$rounds	# key->rounds
        +	$movkey	($key),$rndkey0
        +	mov	$key,$key_		# backup $key
        +	mov	$rounds,$rnds_		# backup $rounds
        +	test	%r8d,%r8d		# 5th argument
        +	jz	.Lecb_decrypt
        +#--------------------------- ECB ENCRYPT ------------------------------#
        +	cmp	\$0x80,$len
        +	jb	.Lecb_enc_tail
        +
        +	movdqu	($inp),$inout0
        +	movdqu	0x10($inp),$inout1
        +	movdqu	0x20($inp),$inout2
        +	movdqu	0x30($inp),$inout3
        +	movdqu	0x40($inp),$inout4
        +	movdqu	0x50($inp),$inout5
        +	movdqu	0x60($inp),$inout6
        +	movdqu	0x70($inp),$inout7
        +	lea	0x80($inp),$inp
        +	sub	\$0x80,$len
        +	jmp	.Lecb_enc_loop8_enter
        +.align 16
        +.Lecb_enc_loop8:
        +	movups	$inout0,($out)
        +	mov	$key_,$key		# restore $key
        +	movdqu	($inp),$inout0
        +	mov	$rnds_,$rounds		# restore $rounds
        +	movups	$inout1,0x10($out)
        +	movdqu	0x10($inp),$inout1
        +	movups	$inout2,0x20($out)
        +	movdqu	0x20($inp),$inout2
        +	movups	$inout3,0x30($out)
        +	movdqu	0x30($inp),$inout3
        +	movups	$inout4,0x40($out)
        +	movdqu	0x40($inp),$inout4
        +	movups	$inout5,0x50($out)
        +	movdqu	0x50($inp),$inout5
        +	movups	$inout6,0x60($out)
        +	movdqu	0x60($inp),$inout6
        +	movups	$inout7,0x70($out)
        +	lea	0x80($out),$out
        +	movdqu	0x70($inp),$inout7
        +	lea	0x80($inp),$inp
        +.Lecb_enc_loop8_enter:
        +
        +	call	_aesni_encrypt8
        +
        +	sub	\$0x80,$len
        +	jnc	.Lecb_enc_loop8
        +
        +	movups	$inout0,($out)
        +	mov	$key_,$key		# restore $key
        +	movups	$inout1,0x10($out)
        +	mov	$rnds_,$rounds		# restore $rounds
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +	movups	$inout6,0x60($out)
        +	movups	$inout7,0x70($out)
        +	lea	0x80($out),$out
        +	add	\$0x80,$len
        +	jz	.Lecb_ret
        +
        +.Lecb_enc_tail:
        +	movups	($inp),$inout0
        +	cmp	\$0x20,$len
        +	jb	.Lecb_enc_one
        +	movups	0x10($inp),$inout1
        +	je	.Lecb_enc_two
        +	movups	0x20($inp),$inout2
        +	cmp	\$0x40,$len
        +	jb	.Lecb_enc_three
        +	movups	0x30($inp),$inout3
        +	je	.Lecb_enc_four
        +	movups	0x40($inp),$inout4
        +	cmp	\$0x60,$len
        +	jb	.Lecb_enc_five
        +	movups	0x50($inp),$inout5
        +	je	.Lecb_enc_six
        +	movdqu	0x60($inp),$inout6
        +	call	_aesni_encrypt8
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +	movups	$inout6,0x60($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_one:
        +___
        +	&aesni_generate1("enc",$key,$rounds);
        +$code.=<<___;
        +	movups	$inout0,($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_two:
        +	xorps	$inout2,$inout2
        +	call	_aesni_encrypt3
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_three:
        +	call	_aesni_encrypt3
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_four:
        +	call	_aesni_encrypt4
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_five:
        +	xorps	$inout5,$inout5
        +	call	_aesni_encrypt6
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_enc_six:
        +	call	_aesni_encrypt6
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +	jmp	.Lecb_ret
        +#--------------------------- ECB DECRYPT ------------------------------#
        +.align	16
        +.Lecb_decrypt:
        +	cmp	\$0x80,$len
        +	jb	.Lecb_dec_tail
        +
        +	movdqu	($inp),$inout0
        +	movdqu	0x10($inp),$inout1
        +	movdqu	0x20($inp),$inout2
        +	movdqu	0x30($inp),$inout3
        +	movdqu	0x40($inp),$inout4
        +	movdqu	0x50($inp),$inout5
        +	movdqu	0x60($inp),$inout6
        +	movdqu	0x70($inp),$inout7
        +	lea	0x80($inp),$inp
        +	sub	\$0x80,$len
        +	jmp	.Lecb_dec_loop8_enter
        +.align 16
        +.Lecb_dec_loop8:
        +	movups	$inout0,($out)
        +	mov	$key_,$key		# restore $key
        +	movdqu	($inp),$inout0
        +	mov	$rnds_,$rounds		# restore $rounds
        +	movups	$inout1,0x10($out)
        +	movdqu	0x10($inp),$inout1
        +	movups	$inout2,0x20($out)
        +	movdqu	0x20($inp),$inout2
        +	movups	$inout3,0x30($out)
        +	movdqu	0x30($inp),$inout3
        +	movups	$inout4,0x40($out)
        +	movdqu	0x40($inp),$inout4
        +	movups	$inout5,0x50($out)
        +	movdqu	0x50($inp),$inout5
        +	movups	$inout6,0x60($out)
        +	movdqu	0x60($inp),$inout6
        +	movups	$inout7,0x70($out)
        +	lea	0x80($out),$out
        +	movdqu	0x70($inp),$inout7
        +	lea	0x80($inp),$inp
        +.Lecb_dec_loop8_enter:
        +
        +	call	_aesni_decrypt8
        +
        +	$movkey	($key_),$rndkey0
        +	sub	\$0x80,$len
        +	jnc	.Lecb_dec_loop8
        +
        +	movups	$inout0,($out)
        +	mov	$key_,$key		# restore $key
        +	movups	$inout1,0x10($out)
        +	mov	$rnds_,$rounds		# restore $rounds
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +	movups	$inout6,0x60($out)
        +	movups	$inout7,0x70($out)
        +	lea	0x80($out),$out
        +	add	\$0x80,$len
        +	jz	.Lecb_ret
        +
        +.Lecb_dec_tail:
        +	movups	($inp),$inout0
        +	cmp	\$0x20,$len
        +	jb	.Lecb_dec_one
        +	movups	0x10($inp),$inout1
        +	je	.Lecb_dec_two
        +	movups	0x20($inp),$inout2
        +	cmp	\$0x40,$len
        +	jb	.Lecb_dec_three
        +	movups	0x30($inp),$inout3
        +	je	.Lecb_dec_four
        +	movups	0x40($inp),$inout4
        +	cmp	\$0x60,$len
        +	jb	.Lecb_dec_five
        +	movups	0x50($inp),$inout5
        +	je	.Lecb_dec_six
        +	movups	0x60($inp),$inout6
        +	$movkey	($key),$rndkey0
        +	call	_aesni_decrypt8
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +	movups	$inout6,0x60($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_one:
        +___
        +	&aesni_generate1("dec",$key,$rounds);
        +$code.=<<___;
        +	movups	$inout0,($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_two:
        +	xorps	$inout2,$inout2
        +	call	_aesni_decrypt3
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_three:
        +	call	_aesni_decrypt3
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_four:
        +	call	_aesni_decrypt4
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_five:
        +	xorps	$inout5,$inout5
        +	call	_aesni_decrypt6
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	jmp	.Lecb_ret
        +.align	16
        +.Lecb_dec_six:
        +	call	_aesni_decrypt6
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +
        +.Lecb_ret:
        +	ret
        +.size	aesni_ecb_encrypt,.-aesni_ecb_encrypt
        +___
        +
        +{
        +######################################################################
        +# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out,
        +#                         size_t blocks, const AES_KEY *key,
        +#                         const char *ivec,char *cmac);
        +#
        +# Handles only complete blocks, operates on 64-bit counter and
        +# does not update *ivec! Nor does it finalize CMAC value
        +# (see engine/eng_aesni.c for details)
        +#
        +{
        +my $cmac="%r9";	# 6th argument
        +
        +my $increment="%xmm6";
        +my $bswap_mask="%xmm7";
        +
        +$code.=<<___;
        +.globl	aesni_ccm64_encrypt_blocks
        +.type	aesni_ccm64_encrypt_blocks,\@function,6
        +.align	16
        +aesni_ccm64_encrypt_blocks:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0x58(%rsp),%rsp
        +	movaps	%xmm6,(%rsp)
        +	movaps	%xmm7,0x10(%rsp)
        +	movaps	%xmm8,0x20(%rsp)
        +	movaps	%xmm9,0x30(%rsp)
        +.Lccm64_enc_body:
        +___
        +$code.=<<___;
        +	mov	240($key),$rounds		# key->rounds
        +	movdqu	($ivp),$iv
        +	movdqa	.Lincrement64(%rip),$increment
        +	movdqa	.Lbswap_mask(%rip),$bswap_mask
        +
        +	shr	\$1,$rounds
        +	lea	0($key),$key_
        +	movdqu	($cmac),$inout1
        +	movdqa	$iv,$inout0
        +	mov	$rounds,$rnds_
        +	pshufb	$bswap_mask,$iv
        +	jmp	.Lccm64_enc_outer
        +.align	16
        +.Lccm64_enc_outer:
        +	$movkey	($key_),$rndkey0
        +	mov	$rnds_,$rounds
        +	movups	($inp),$in0			# load inp
        +
        +	xorps	$rndkey0,$inout0		# counter
        +	$movkey	16($key_),$rndkey1
        +	xorps	$in0,$rndkey0
        +	lea	32($key_),$key
        +	xorps	$rndkey0,$inout1		# cmac^=inp
        +	$movkey	($key),$rndkey0
        +
        +.Lccm64_enc2_loop:
        +	aesenc	$rndkey1,$inout0
        +	dec	$rounds
        +	aesenc	$rndkey1,$inout1
        +	$movkey	16($key),$rndkey1
        +	aesenc	$rndkey0,$inout0
        +	lea	32($key),$key
        +	aesenc	$rndkey0,$inout1
        +	$movkey	0($key),$rndkey0
        +	jnz	.Lccm64_enc2_loop
        +	aesenc	$rndkey1,$inout0
        +	aesenc	$rndkey1,$inout1
        +	paddq	$increment,$iv
        +	aesenclast	$rndkey0,$inout0
        +	aesenclast	$rndkey0,$inout1
        +
        +	dec	$len
        +	lea	16($inp),$inp
        +	xorps	$inout0,$in0			# inp ^= E(iv)
        +	movdqa	$iv,$inout0
        +	movups	$in0,($out)			# save output
        +	lea	16($out),$out
        +	pshufb	$bswap_mask,$inout0
        +	jnz	.Lccm64_enc_outer
        +
        +	movups	$inout1,($cmac)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	(%rsp),%xmm6
        +	movaps	0x10(%rsp),%xmm7
        +	movaps	0x20(%rsp),%xmm8
        +	movaps	0x30(%rsp),%xmm9
        +	lea	0x58(%rsp),%rsp
        +.Lccm64_enc_ret:
        +___
        +$code.=<<___;
        +	ret
        +.size	aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks
        +___
        +######################################################################
        +$code.=<<___;
        +.globl	aesni_ccm64_decrypt_blocks
        +.type	aesni_ccm64_decrypt_blocks,\@function,6
        +.align	16
        +aesni_ccm64_decrypt_blocks:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0x58(%rsp),%rsp
        +	movaps	%xmm6,(%rsp)
        +	movaps	%xmm7,0x10(%rsp)
        +	movaps	%xmm8,0x20(%rsp)
        +	movaps	%xmm9,0x30(%rsp)
        +.Lccm64_dec_body:
        +___
        +$code.=<<___;
        +	mov	240($key),$rounds		# key->rounds
        +	movups	($ivp),$iv
        +	movdqu	($cmac),$inout1
        +	movdqa	.Lincrement64(%rip),$increment
        +	movdqa	.Lbswap_mask(%rip),$bswap_mask
        +
        +	movaps	$iv,$inout0
        +	mov	$rounds,$rnds_
        +	mov	$key,$key_
        +	pshufb	$bswap_mask,$iv
        +___
        +	&aesni_generate1("enc",$key,$rounds);
        +$code.=<<___;
        +	movups	($inp),$in0			# load inp
        +	paddq	$increment,$iv
        +	lea	16($inp),$inp
        +	jmp	.Lccm64_dec_outer
        +.align	16
        +.Lccm64_dec_outer:
        +	xorps	$inout0,$in0			# inp ^= E(iv)
        +	movdqa	$iv,$inout0
        +	mov	$rnds_,$rounds
        +	movups	$in0,($out)			# save output
        +	lea	16($out),$out
        +	pshufb	$bswap_mask,$inout0
        +
        +	sub	\$1,$len
        +	jz	.Lccm64_dec_break
        +
        +	$movkey	($key_),$rndkey0
        +	shr	\$1,$rounds
        +	$movkey	16($key_),$rndkey1
        +	xorps	$rndkey0,$in0
        +	lea	32($key_),$key
        +	xorps	$rndkey0,$inout0
        +	xorps	$in0,$inout1			# cmac^=out
        +	$movkey	($key),$rndkey0
        +
        +.Lccm64_dec2_loop:
        +	aesenc	$rndkey1,$inout0
        +	dec	$rounds
        +	aesenc	$rndkey1,$inout1
        +	$movkey	16($key),$rndkey1
        +	aesenc	$rndkey0,$inout0
        +	lea	32($key),$key
        +	aesenc	$rndkey0,$inout1
        +	$movkey	0($key),$rndkey0
        +	jnz	.Lccm64_dec2_loop
        +	movups	($inp),$in0			# load inp
        +	paddq	$increment,$iv
        +	aesenc	$rndkey1,$inout0
        +	aesenc	$rndkey1,$inout1
        +	lea	16($inp),$inp
        +	aesenclast	$rndkey0,$inout0
        +	aesenclast	$rndkey0,$inout1
        +	jmp	.Lccm64_dec_outer
        +
        +.align	16
        +.Lccm64_dec_break:
        +	#xorps	$in0,$inout1			# cmac^=out
        +___
        +	&aesni_generate1("enc",$key_,$rounds,$inout1,$in0);
        +$code.=<<___;
        +	movups	$inout1,($cmac)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	(%rsp),%xmm6
        +	movaps	0x10(%rsp),%xmm7
        +	movaps	0x20(%rsp),%xmm8
        +	movaps	0x30(%rsp),%xmm9
        +	lea	0x58(%rsp),%rsp
        +.Lccm64_dec_ret:
        +___
        +$code.=<<___;
        +	ret
        +.size	aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks
        +___
        +}
        +######################################################################
        +# void aesni_ctr32_encrypt_blocks (const void *in, void *out,
        +#                         size_t blocks, const AES_KEY *key,
        +#                         const char *ivec);
        +#
        +# Handles only complete blocks, operates on 32-bit counter and
        +# does not update *ivec! (see engine/eng_aesni.c for details)
        +#
        +{
        +my $reserved = $win64?0:-0x28;
        +my ($in0,$in1,$in2,$in3)=map("%xmm$_",(8..11));
        +my ($iv0,$iv1,$ivec)=("%xmm12","%xmm13","%xmm14");
        +my $bswap_mask="%xmm15";
        +
        +$code.=<<___;
        +.globl	aesni_ctr32_encrypt_blocks
        +.type	aesni_ctr32_encrypt_blocks,\@function,5
        +.align	16
        +aesni_ctr32_encrypt_blocks:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xc8(%rsp),%rsp
        +	movaps	%xmm6,0x20(%rsp)
        +	movaps	%xmm7,0x30(%rsp)
        +	movaps	%xmm8,0x40(%rsp)
        +	movaps	%xmm9,0x50(%rsp)
        +	movaps	%xmm10,0x60(%rsp)
        +	movaps	%xmm11,0x70(%rsp)
        +	movaps	%xmm12,0x80(%rsp)
        +	movaps	%xmm13,0x90(%rsp)
        +	movaps	%xmm14,0xa0(%rsp)
        +	movaps	%xmm15,0xb0(%rsp)
        +.Lctr32_body:
        +___
        +$code.=<<___;
        +	cmp	\$1,$len
        +	je	.Lctr32_one_shortcut
        +
        +	movdqu	($ivp),$ivec
        +	movdqa	.Lbswap_mask(%rip),$bswap_mask
        +	xor	$rounds,$rounds
        +	pextrd	\$3,$ivec,$rnds_		# pull 32-bit counter
        +	pinsrd	\$3,$rounds,$ivec		# wipe 32-bit counter
        +
        +	mov	240($key),$rounds		# key->rounds
        +	bswap	$rnds_
        +	pxor	$iv0,$iv0			# vector of 3 32-bit counters
        +	pxor	$iv1,$iv1			# vector of 3 32-bit counters
        +	pinsrd	\$0,$rnds_,$iv0
        +	lea	3($rnds_),$key_
        +	pinsrd	\$0,$key_,$iv1
        +	inc	$rnds_
        +	pinsrd	\$1,$rnds_,$iv0
        +	inc	$key_
        +	pinsrd	\$1,$key_,$iv1
        +	inc	$rnds_
        +	pinsrd	\$2,$rnds_,$iv0
        +	inc	$key_
        +	pinsrd	\$2,$key_,$iv1
        +	movdqa	$iv0,$reserved(%rsp)
        +	pshufb	$bswap_mask,$iv0
        +	movdqa	$iv1,`$reserved+0x10`(%rsp)
        +	pshufb	$bswap_mask,$iv1
        +
        +	pshufd	\$`3<<6`,$iv0,$inout0		# place counter to upper dword
        +	pshufd	\$`2<<6`,$iv0,$inout1
        +	pshufd	\$`1<<6`,$iv0,$inout2
        +	cmp	\$6,$len
        +	jb	.Lctr32_tail
        +	shr	\$1,$rounds
        +	mov	$key,$key_			# backup $key
        +	mov	$rounds,$rnds_			# backup $rounds
        +	sub	\$6,$len
        +	jmp	.Lctr32_loop6
        +
        +.align	16
        +.Lctr32_loop6:
        +	pshufd	\$`3<<6`,$iv1,$inout3
        +	por	$ivec,$inout0			# merge counter-less ivec
        +	 $movkey	($key_),$rndkey0
        +	pshufd	\$`2<<6`,$iv1,$inout4
        +	por	$ivec,$inout1
        +	 $movkey	16($key_),$rndkey1
        +	pshufd	\$`1<<6`,$iv1,$inout5
        +	por	$ivec,$inout2
        +	por	$ivec,$inout3
        +	 xorps		$rndkey0,$inout0
        +	por	$ivec,$inout4
        +	por	$ivec,$inout5
        +
        +	# inline _aesni_encrypt6 and interleave last rounds
        +	# with own code...
        +
        +	pxor		$rndkey0,$inout1
        +	aesenc		$rndkey1,$inout0
        +	lea		32($key_),$key
        +	pxor		$rndkey0,$inout2
        +	aesenc		$rndkey1,$inout1
        +	 movdqa		.Lincrement32(%rip),$iv1
        +	pxor		$rndkey0,$inout3
        +	aesenc		$rndkey1,$inout2
        +	 movdqa		$reserved(%rsp),$iv0
        +	pxor		$rndkey0,$inout4
        +	aesenc		$rndkey1,$inout3
        +	pxor		$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	dec		$rounds
        +	aesenc		$rndkey1,$inout4
        +	aesenc		$rndkey1,$inout5
        +	jmp		.Lctr32_enc_loop6_enter
        +.align	16
        +.Lctr32_enc_loop6:
        +	aesenc		$rndkey1,$inout0
        +	aesenc		$rndkey1,$inout1
        +	dec		$rounds
        +	aesenc		$rndkey1,$inout2
        +	aesenc		$rndkey1,$inout3
        +	aesenc		$rndkey1,$inout4
        +	aesenc		$rndkey1,$inout5
        +.Lctr32_enc_loop6_enter:
        +	$movkey		16($key),$rndkey1
        +	aesenc		$rndkey0,$inout0
        +	aesenc		$rndkey0,$inout1
        +	lea		32($key),$key
        +	aesenc		$rndkey0,$inout2
        +	aesenc		$rndkey0,$inout3
        +	aesenc		$rndkey0,$inout4
        +	aesenc		$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	jnz		.Lctr32_enc_loop6
        +
        +	aesenc		$rndkey1,$inout0
        +	 paddd		$iv1,$iv0		# increment counter vector
        +	aesenc		$rndkey1,$inout1
        +	 paddd		`$reserved+0x10`(%rsp),$iv1
        +	aesenc		$rndkey1,$inout2
        +	 movdqa		$iv0,$reserved(%rsp)	# save counter vector
        +	aesenc		$rndkey1,$inout3
        +	 movdqa		$iv1,`$reserved+0x10`(%rsp)
        +	aesenc		$rndkey1,$inout4
        +	 pshufb		$bswap_mask,$iv0	# byte swap
        +	aesenc		$rndkey1,$inout5
        +	 pshufb		$bswap_mask,$iv1
        +
        +	aesenclast	$rndkey0,$inout0
        +	 movups		($inp),$in0		# load input
        +	aesenclast	$rndkey0,$inout1
        +	 movups		0x10($inp),$in1
        +	aesenclast	$rndkey0,$inout2
        +	 movups		0x20($inp),$in2
        +	aesenclast	$rndkey0,$inout3
        +	 movups		0x30($inp),$in3
        +	aesenclast	$rndkey0,$inout4
        +	 movups		0x40($inp),$rndkey1
        +	aesenclast	$rndkey0,$inout5
        +	 movups		0x50($inp),$rndkey0
        +	 lea	0x60($inp),$inp
        +
        +	xorps	$inout0,$in0			# xor
        +	 pshufd	\$`3<<6`,$iv0,$inout0
        +	xorps	$inout1,$in1
        +	 pshufd	\$`2<<6`,$iv0,$inout1
        +	movups	$in0,($out)			# store output
        +	xorps	$inout2,$in2
        +	 pshufd	\$`1<<6`,$iv0,$inout2
        +	movups	$in1,0x10($out)
        +	xorps	$inout3,$in3
        +	movups	$in2,0x20($out)
        +	xorps	$inout4,$rndkey1
        +	movups	$in3,0x30($out)
        +	xorps	$inout5,$rndkey0
        +	movups	$rndkey1,0x40($out)
        +	movups	$rndkey0,0x50($out)
        +	lea	0x60($out),$out
        +	mov	$rnds_,$rounds
        +	sub	\$6,$len
        +	jnc	.Lctr32_loop6
        +
        +	add	\$6,$len
        +	jz	.Lctr32_done
        +	mov	$key_,$key			# restore $key
        +	lea	1($rounds,$rounds),$rounds	# restore original value
        +
        +.Lctr32_tail:
        +	por	$ivec,$inout0
        +	movups	($inp),$in0
        +	cmp	\$2,$len
        +	jb	.Lctr32_one
        +
        +	por	$ivec,$inout1
        +	movups	0x10($inp),$in1
        +	je	.Lctr32_two
        +
        +	pshufd	\$`3<<6`,$iv1,$inout3
        +	por	$ivec,$inout2
        +	movups	0x20($inp),$in2
        +	cmp	\$4,$len
        +	jb	.Lctr32_three
        +
        +	pshufd	\$`2<<6`,$iv1,$inout4
        +	por	$ivec,$inout3
        +	movups	0x30($inp),$in3
        +	je	.Lctr32_four
        +
        +	por	$ivec,$inout4
        +	xorps	$inout5,$inout5
        +
        +	call	_aesni_encrypt6
        +
        +	movups	0x40($inp),$rndkey1
        +	xorps	$inout0,$in0
        +	xorps	$inout1,$in1
        +	movups	$in0,($out)
        +	xorps	$inout2,$in2
        +	movups	$in1,0x10($out)
        +	xorps	$inout3,$in3
        +	movups	$in2,0x20($out)
        +	xorps	$inout4,$rndkey1
        +	movups	$in3,0x30($out)
        +	movups	$rndkey1,0x40($out)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_one_shortcut:
        +	movups	($ivp),$inout0
        +	movups	($inp),$in0
        +	mov	240($key),$rounds		# key->rounds
        +.Lctr32_one:
        +___
        +	&aesni_generate1("enc",$key,$rounds);
        +$code.=<<___;
        +	xorps	$inout0,$in0
        +	movups	$in0,($out)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_two:
        +	xorps	$inout2,$inout2
        +	call	_aesni_encrypt3
        +	xorps	$inout0,$in0
        +	xorps	$inout1,$in1
        +	movups	$in0,($out)
        +	movups	$in1,0x10($out)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_three:
        +	call	_aesni_encrypt3
        +	xorps	$inout0,$in0
        +	xorps	$inout1,$in1
        +	movups	$in0,($out)
        +	xorps	$inout2,$in2
        +	movups	$in1,0x10($out)
        +	movups	$in2,0x20($out)
        +	jmp	.Lctr32_done
        +
        +.align	16
        +.Lctr32_four:
        +	call	_aesni_encrypt4
        +	xorps	$inout0,$in0
        +	xorps	$inout1,$in1
        +	movups	$in0,($out)
        +	xorps	$inout2,$in2
        +	movups	$in1,0x10($out)
        +	xorps	$inout3,$in3
        +	movups	$in2,0x20($out)
        +	movups	$in3,0x30($out)
        +
        +.Lctr32_done:
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x20(%rsp),%xmm6
        +	movaps	0x30(%rsp),%xmm7
        +	movaps	0x40(%rsp),%xmm8
        +	movaps	0x50(%rsp),%xmm9
        +	movaps	0x60(%rsp),%xmm10
        +	movaps	0x70(%rsp),%xmm11
        +	movaps	0x80(%rsp),%xmm12
        +	movaps	0x90(%rsp),%xmm13
        +	movaps	0xa0(%rsp),%xmm14
        +	movaps	0xb0(%rsp),%xmm15
        +	lea	0xc8(%rsp),%rsp
        +.Lctr32_ret:
        +___
        +$code.=<<___;
        +	ret
        +.size	aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
        +___
        +}
        +
        +######################################################################
        +# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len,
        +#	const AES_KEY *key1, const AES_KEY *key2
        +#	const unsigned char iv[16]);
        +#
        +{
        +my @tweak=map("%xmm$_",(10..15));
        +my ($twmask,$twres,$twtmp)=("%xmm8","%xmm9",@tweak[4]);
        +my ($key2,$ivp,$len_)=("%r8","%r9","%r9");
        +my $frame_size = 0x68 + ($win64?160:0);
        +
        +$code.=<<___;
        +.globl	aesni_xts_encrypt
        +.type	aesni_xts_encrypt,\@function,6
        +.align	16
        +aesni_xts_encrypt:
        +	lea	-$frame_size(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,0x60(%rsp)
        +	movaps	%xmm7,0x70(%rsp)
        +	movaps	%xmm8,0x80(%rsp)
        +	movaps	%xmm9,0x90(%rsp)
        +	movaps	%xmm10,0xa0(%rsp)
        +	movaps	%xmm11,0xb0(%rsp)
        +	movaps	%xmm12,0xc0(%rsp)
        +	movaps	%xmm13,0xd0(%rsp)
        +	movaps	%xmm14,0xe0(%rsp)
        +	movaps	%xmm15,0xf0(%rsp)
        +.Lxts_enc_body:
        +___
        +$code.=<<___;
        +	movups	($ivp),@tweak[5]		# load clear-text tweak
        +	mov	240(%r8),$rounds		# key2->rounds
        +	mov	240($key),$rnds_		# key1->rounds
        +___
        +	# generate the tweak
        +	&aesni_generate1("enc",$key2,$rounds,@tweak[5]);
        +$code.=<<___;
        +	mov	$key,$key_			# backup $key
        +	mov	$rnds_,$rounds			# backup $rounds
        +	mov	$len,$len_			# backup $len
        +	and	\$-16,$len
        +
        +	movdqa	.Lxts_magic(%rip),$twmask
        +	pxor	$twtmp,$twtmp
        +	pcmpgtd	@tweak[5],$twtmp		# broadcast upper bits
        +___
        +    for ($i=0;$i<4;$i++) {
        +    $code.=<<___;
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[$i]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	pand	$twmask,$twres			# isolate carry and residue
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	pxor	$twres,@tweak[5]
        +___
        +    }
        +$code.=<<___;
        +	sub	\$16*6,$len
        +	jc	.Lxts_enc_short
        +
        +	shr	\$1,$rounds
        +	sub	\$1,$rounds
        +	mov	$rounds,$rnds_
        +	jmp	.Lxts_enc_grandloop
        +
        +.align	16
        +.Lxts_enc_grandloop:
        +	pshufd	\$0x13,$twtmp,$twres
        +	movdqa	@tweak[5],@tweak[4]
        +	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
        +	movdqu	`16*0`($inp),$inout0		# load input
        +	pand	$twmask,$twres			# isolate carry and residue
        +	movdqu	`16*1`($inp),$inout1
        +	pxor	$twres,@tweak[5]
        +
        +	movdqu	`16*2`($inp),$inout2
        +	pxor	@tweak[0],$inout0		# input^=tweak
        +	movdqu	`16*3`($inp),$inout3
        +	pxor	@tweak[1],$inout1
        +	movdqu	`16*4`($inp),$inout4
        +	pxor	@tweak[2],$inout2
        +	movdqu	`16*5`($inp),$inout5
        +	lea	`16*6`($inp),$inp
        +	pxor	@tweak[3],$inout3
        +	$movkey		($key_),$rndkey0
        +	pxor	@tweak[4],$inout4
        +	pxor	@tweak[5],$inout5
        +
        +	# inline _aesni_encrypt6 and interleave first and last rounds
        +	# with own code...
        +	$movkey		16($key_),$rndkey1
        +	pxor		$rndkey0,$inout0
        +	pxor		$rndkey0,$inout1
        +	 movdqa	@tweak[0],`16*0`(%rsp)		# put aside tweaks
        +	aesenc		$rndkey1,$inout0
        +	lea		32($key_),$key
        +	pxor		$rndkey0,$inout2
        +	 movdqa	@tweak[1],`16*1`(%rsp)
        +	aesenc		$rndkey1,$inout1
        +	pxor		$rndkey0,$inout3
        +	 movdqa	@tweak[2],`16*2`(%rsp)
        +	aesenc		$rndkey1,$inout2
        +	pxor		$rndkey0,$inout4
        +	 movdqa	@tweak[3],`16*3`(%rsp)
        +	aesenc		$rndkey1,$inout3
        +	pxor		$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	dec		$rounds
        +	 movdqa	@tweak[4],`16*4`(%rsp)
        +	aesenc		$rndkey1,$inout4
        +	 movdqa	@tweak[5],`16*5`(%rsp)
        +	aesenc		$rndkey1,$inout5
        +	pxor	$twtmp,$twtmp
        +	pcmpgtd	@tweak[5],$twtmp
        +	jmp		.Lxts_enc_loop6_enter
        +
        +.align	16
        +.Lxts_enc_loop6:
        +	aesenc		$rndkey1,$inout0
        +	aesenc		$rndkey1,$inout1
        +	dec		$rounds
        +	aesenc		$rndkey1,$inout2
        +	aesenc		$rndkey1,$inout3
        +	aesenc		$rndkey1,$inout4
        +	aesenc		$rndkey1,$inout5
        +.Lxts_enc_loop6_enter:
        +	$movkey		16($key),$rndkey1
        +	aesenc		$rndkey0,$inout0
        +	aesenc		$rndkey0,$inout1
        +	lea		32($key),$key
        +	aesenc		$rndkey0,$inout2
        +	aesenc		$rndkey0,$inout3
        +	aesenc		$rndkey0,$inout4
        +	aesenc		$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	jnz		.Lxts_enc_loop6
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesenc		$rndkey1,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesenc		$rndkey1,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcast upper bits
        +	 aesenc		$rndkey1,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesenc		$rndkey1,$inout3
        +	 aesenc		$rndkey1,$inout4
        +	 aesenc		$rndkey1,$inout5
        +	 $movkey	16($key),$rndkey1
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[0]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesenc		$rndkey0,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesenc		$rndkey0,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	 aesenc		$rndkey0,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesenc		$rndkey0,$inout3
        +	 aesenc		$rndkey0,$inout4
        +	 aesenc		$rndkey0,$inout5
        +	 $movkey	32($key),$rndkey0
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[1]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesenc		$rndkey1,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesenc		$rndkey1,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	 aesenc		$rndkey1,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesenc		$rndkey1,$inout3
        +	 aesenc		$rndkey1,$inout4
        +	 aesenc		$rndkey1,$inout5
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[2]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesenclast	$rndkey0,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesenclast	$rndkey0,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	 aesenclast	$rndkey0,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesenclast	$rndkey0,$inout3
        +	 aesenclast	$rndkey0,$inout4
        +	 aesenclast	$rndkey0,$inout5
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[3]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 xorps	`16*0`(%rsp),$inout0		# output^=tweak
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 xorps	`16*1`(%rsp),$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	pxor	$twres,@tweak[5]
        +
        +	xorps	`16*2`(%rsp),$inout2
        +	movups	$inout0,`16*0`($out)		# write output
        +	xorps	`16*3`(%rsp),$inout3
        +	movups	$inout1,`16*1`($out)
        +	xorps	`16*4`(%rsp),$inout4
        +	movups	$inout2,`16*2`($out)
        +	xorps	`16*5`(%rsp),$inout5
        +	movups	$inout3,`16*3`($out)
        +	mov	$rnds_,$rounds			# restore $rounds
        +	movups	$inout4,`16*4`($out)
        +	movups	$inout5,`16*5`($out)
        +	lea	`16*6`($out),$out
        +	sub	\$16*6,$len
        +	jnc	.Lxts_enc_grandloop
        +
        +	lea	3($rounds,$rounds),$rounds	# restore original value
        +	mov	$key_,$key			# restore $key
        +	mov	$rounds,$rnds_			# backup $rounds
        +
        +.Lxts_enc_short:
        +	add	\$16*6,$len
        +	jz	.Lxts_enc_done
        +
        +	cmp	\$0x20,$len
        +	jb	.Lxts_enc_one
        +	je	.Lxts_enc_two
        +
        +	cmp	\$0x40,$len
        +	jb	.Lxts_enc_three
        +	je	.Lxts_enc_four
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	movdqa	@tweak[5],@tweak[4]
        +	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
        +	 movdqu	($inp),$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 movdqu	16*1($inp),$inout1
        +	pxor	$twres,@tweak[5]
        +
        +	movdqu	16*2($inp),$inout2
        +	pxor	@tweak[0],$inout0
        +	movdqu	16*3($inp),$inout3
        +	pxor	@tweak[1],$inout1
        +	movdqu	16*4($inp),$inout4
        +	lea	16*5($inp),$inp
        +	pxor	@tweak[2],$inout2
        +	pxor	@tweak[3],$inout3
        +	pxor	@tweak[4],$inout4
        +
        +	call	_aesni_encrypt6
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[5],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +	movdqu	$inout0,($out)
        +	xorps	@tweak[3],$inout3
        +	movdqu	$inout1,16*1($out)
        +	xorps	@tweak[4],$inout4
        +	movdqu	$inout2,16*2($out)
        +	movdqu	$inout3,16*3($out)
        +	movdqu	$inout4,16*4($out)
        +	lea	16*5($out),$out
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_one:
        +	movups	($inp),$inout0
        +	lea	16*1($inp),$inp
        +	xorps	@tweak[0],$inout0
        +___
        +	&aesni_generate1("enc",$key,$rounds);
        +$code.=<<___;
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[1],@tweak[0]
        +	movups	$inout0,($out)
        +	lea	16*1($out),$out
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_two:
        +	movups	($inp),$inout0
        +	movups	16($inp),$inout1
        +	lea	32($inp),$inp
        +	xorps	@tweak[0],$inout0
        +	xorps	@tweak[1],$inout1
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[2],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	movups	$inout0,($out)
        +	movups	$inout1,16*1($out)
        +	lea	16*2($out),$out
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_three:
        +	movups	($inp),$inout0
        +	movups	16*1($inp),$inout1
        +	movups	16*2($inp),$inout2
        +	lea	16*3($inp),$inp
        +	xorps	@tweak[0],$inout0
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +
        +	call	_aesni_encrypt3
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[3],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +	movups	$inout0,($out)
        +	movups	$inout1,16*1($out)
        +	movups	$inout2,16*2($out)
        +	lea	16*3($out),$out
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_four:
        +	movups	($inp),$inout0
        +	movups	16*1($inp),$inout1
        +	movups	16*2($inp),$inout2
        +	xorps	@tweak[0],$inout0
        +	movups	16*3($inp),$inout3
        +	lea	16*4($inp),$inp
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +	xorps	@tweak[3],$inout3
        +
        +	call	_aesni_encrypt4
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[5],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +	movups	$inout0,($out)
        +	xorps	@tweak[3],$inout3
        +	movups	$inout1,16*1($out)
        +	movups	$inout2,16*2($out)
        +	movups	$inout3,16*3($out)
        +	lea	16*4($out),$out
        +	jmp	.Lxts_enc_done
        +
        +.align	16
        +.Lxts_enc_done:
        +	and	\$15,$len_
        +	jz	.Lxts_enc_ret
        +	mov	$len_,$len
        +
        +.Lxts_enc_steal:
        +	movzb	($inp),%eax			# borrow $rounds ...
        +	movzb	-16($out),%ecx			# ... and $key
        +	lea	1($inp),$inp
        +	mov	%al,-16($out)
        +	mov	%cl,0($out)
        +	lea	1($out),$out
        +	sub	\$1,$len
        +	jnz	.Lxts_enc_steal
        +
        +	sub	$len_,$out			# rewind $out
        +	mov	$key_,$key			# restore $key
        +	mov	$rnds_,$rounds			# restore $rounds
        +
        +	movups	-16($out),$inout0
        +	xorps	@tweak[0],$inout0
        +___
        +	&aesni_generate1("enc",$key,$rounds);
        +$code.=<<___;
        +	xorps	@tweak[0],$inout0
        +	movups	$inout0,-16($out)
        +
        +.Lxts_enc_ret:
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x60(%rsp),%xmm6
        +	movaps	0x70(%rsp),%xmm7
        +	movaps	0x80(%rsp),%xmm8
        +	movaps	0x90(%rsp),%xmm9
        +	movaps	0xa0(%rsp),%xmm10
        +	movaps	0xb0(%rsp),%xmm11
        +	movaps	0xc0(%rsp),%xmm12
        +	movaps	0xd0(%rsp),%xmm13
        +	movaps	0xe0(%rsp),%xmm14
        +	movaps	0xf0(%rsp),%xmm15
        +___
        +$code.=<<___;
        +	lea	$frame_size(%rsp),%rsp
        +.Lxts_enc_epilogue:
        +	ret
        +.size	aesni_xts_encrypt,.-aesni_xts_encrypt
        +___
        +
        +$code.=<<___;
        +.globl	aesni_xts_decrypt
        +.type	aesni_xts_decrypt,\@function,6
        +.align	16
        +aesni_xts_decrypt:
        +	lea	-$frame_size(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,0x60(%rsp)
        +	movaps	%xmm7,0x70(%rsp)
        +	movaps	%xmm8,0x80(%rsp)
        +	movaps	%xmm9,0x90(%rsp)
        +	movaps	%xmm10,0xa0(%rsp)
        +	movaps	%xmm11,0xb0(%rsp)
        +	movaps	%xmm12,0xc0(%rsp)
        +	movaps	%xmm13,0xd0(%rsp)
        +	movaps	%xmm14,0xe0(%rsp)
        +	movaps	%xmm15,0xf0(%rsp)
        +.Lxts_dec_body:
        +___
        +$code.=<<___;
        +	movups	($ivp),@tweak[5]		# load clear-text tweak
        +	mov	240($key2),$rounds		# key2->rounds
        +	mov	240($key),$rnds_		# key1->rounds
        +___
        +	# generate the tweak
        +	&aesni_generate1("enc",$key2,$rounds,@tweak[5]);
        +$code.=<<___;
        +	xor	%eax,%eax			# if ($len%16) len-=16;
        +	test	\$15,$len
        +	setnz	%al
        +	shl	\$4,%rax
        +	sub	%rax,$len
        +
        +	mov	$key,$key_			# backup $key
        +	mov	$rnds_,$rounds			# backup $rounds
        +	mov	$len,$len_			# backup $len
        +	and	\$-16,$len
        +
        +	movdqa	.Lxts_magic(%rip),$twmask
        +	pxor	$twtmp,$twtmp
        +	pcmpgtd	@tweak[5],$twtmp		# broadcast upper bits
        +___
        +    for ($i=0;$i<4;$i++) {
        +    $code.=<<___;
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[$i]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	pand	$twmask,$twres			# isolate carry and residue
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	pxor	$twres,@tweak[5]
        +___
        +    }
        +$code.=<<___;
        +	sub	\$16*6,$len
        +	jc	.Lxts_dec_short
        +
        +	shr	\$1,$rounds
        +	sub	\$1,$rounds
        +	mov	$rounds,$rnds_
        +	jmp	.Lxts_dec_grandloop
        +
        +.align	16
        +.Lxts_dec_grandloop:
        +	pshufd	\$0x13,$twtmp,$twres
        +	movdqa	@tweak[5],@tweak[4]
        +	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
        +	movdqu	`16*0`($inp),$inout0		# load input
        +	pand	$twmask,$twres			# isolate carry and residue
        +	movdqu	`16*1`($inp),$inout1
        +	pxor	$twres,@tweak[5]
        +
        +	movdqu	`16*2`($inp),$inout2
        +	pxor	@tweak[0],$inout0		# input^=tweak
        +	movdqu	`16*3`($inp),$inout3
        +	pxor	@tweak[1],$inout1
        +	movdqu	`16*4`($inp),$inout4
        +	pxor	@tweak[2],$inout2
        +	movdqu	`16*5`($inp),$inout5
        +	lea	`16*6`($inp),$inp
        +	pxor	@tweak[3],$inout3
        +	$movkey		($key_),$rndkey0
        +	pxor	@tweak[4],$inout4
        +	pxor	@tweak[5],$inout5
        +
        +	# inline _aesni_decrypt6 and interleave first and last rounds
        +	# with own code...
        +	$movkey		16($key_),$rndkey1
        +	pxor		$rndkey0,$inout0
        +	pxor		$rndkey0,$inout1
        +	 movdqa	@tweak[0],`16*0`(%rsp)		# put aside tweaks
        +	aesdec		$rndkey1,$inout0
        +	lea		32($key_),$key
        +	pxor		$rndkey0,$inout2
        +	 movdqa	@tweak[1],`16*1`(%rsp)
        +	aesdec		$rndkey1,$inout1
        +	pxor		$rndkey0,$inout3
        +	 movdqa	@tweak[2],`16*2`(%rsp)
        +	aesdec		$rndkey1,$inout2
        +	pxor		$rndkey0,$inout4
        +	 movdqa	@tweak[3],`16*3`(%rsp)
        +	aesdec		$rndkey1,$inout3
        +	pxor		$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	dec		$rounds
        +	 movdqa	@tweak[4],`16*4`(%rsp)
        +	aesdec		$rndkey1,$inout4
        +	 movdqa	@tweak[5],`16*5`(%rsp)
        +	aesdec		$rndkey1,$inout5
        +	pxor	$twtmp,$twtmp
        +	pcmpgtd	@tweak[5],$twtmp
        +	jmp		.Lxts_dec_loop6_enter
        +
        +.align	16
        +.Lxts_dec_loop6:
        +	aesdec		$rndkey1,$inout0
        +	aesdec		$rndkey1,$inout1
        +	dec		$rounds
        +	aesdec		$rndkey1,$inout2
        +	aesdec		$rndkey1,$inout3
        +	aesdec		$rndkey1,$inout4
        +	aesdec		$rndkey1,$inout5
        +.Lxts_dec_loop6_enter:
        +	$movkey		16($key),$rndkey1
        +	aesdec		$rndkey0,$inout0
        +	aesdec		$rndkey0,$inout1
        +	lea		32($key),$key
        +	aesdec		$rndkey0,$inout2
        +	aesdec		$rndkey0,$inout3
        +	aesdec		$rndkey0,$inout4
        +	aesdec		$rndkey0,$inout5
        +	$movkey		($key),$rndkey0
        +	jnz		.Lxts_dec_loop6
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesdec		$rndkey1,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesdec		$rndkey1,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcast upper bits
        +	 aesdec		$rndkey1,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesdec		$rndkey1,$inout3
        +	 aesdec		$rndkey1,$inout4
        +	 aesdec		$rndkey1,$inout5
        +	 $movkey	16($key),$rndkey1
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[0]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesdec		$rndkey0,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesdec		$rndkey0,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	 aesdec		$rndkey0,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesdec		$rndkey0,$inout3
        +	 aesdec		$rndkey0,$inout4
        +	 aesdec		$rndkey0,$inout5
        +	 $movkey	32($key),$rndkey0
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[1]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesdec		$rndkey1,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesdec		$rndkey1,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	 aesdec		$rndkey1,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesdec		$rndkey1,$inout3
        +	 aesdec		$rndkey1,$inout4
        +	 aesdec		$rndkey1,$inout5
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[2]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 aesdeclast	$rndkey0,$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 aesdeclast	$rndkey0,$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	 aesdeclast	$rndkey0,$inout2
        +	pxor	$twres,@tweak[5]
        +	 aesdeclast	$rndkey0,$inout3
        +	 aesdeclast	$rndkey0,$inout4
        +	 aesdeclast	$rndkey0,$inout5
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	pxor	$twtmp,$twtmp
        +	movdqa	@tweak[5],@tweak[3]
        +	paddq	@tweak[5],@tweak[5]		# psllq	1,$tweak
        +	 xorps	`16*0`(%rsp),$inout0		# output^=tweak
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 xorps	`16*1`(%rsp),$inout1
        +	pcmpgtd	@tweak[5],$twtmp		# broadcat upper bits
        +	pxor	$twres,@tweak[5]
        +
        +	xorps	`16*2`(%rsp),$inout2
        +	movups	$inout0,`16*0`($out)		# write output
        +	xorps	`16*3`(%rsp),$inout3
        +	movups	$inout1,`16*1`($out)
        +	xorps	`16*4`(%rsp),$inout4
        +	movups	$inout2,`16*2`($out)
        +	xorps	`16*5`(%rsp),$inout5
        +	movups	$inout3,`16*3`($out)
        +	mov	$rnds_,$rounds			# restore $rounds
        +	movups	$inout4,`16*4`($out)
        +	movups	$inout5,`16*5`($out)
        +	lea	`16*6`($out),$out
        +	sub	\$16*6,$len
        +	jnc	.Lxts_dec_grandloop
        +
        +	lea	3($rounds,$rounds),$rounds	# restore original value
        +	mov	$key_,$key			# restore $key
        +	mov	$rounds,$rnds_			# backup $rounds
        +
        +.Lxts_dec_short:
        +	add	\$16*6,$len
        +	jz	.Lxts_dec_done
        +
        +	cmp	\$0x20,$len
        +	jb	.Lxts_dec_one
        +	je	.Lxts_dec_two
        +
        +	cmp	\$0x40,$len
        +	jb	.Lxts_dec_three
        +	je	.Lxts_dec_four
        +
        +	pshufd	\$0x13,$twtmp,$twres
        +	movdqa	@tweak[5],@tweak[4]
        +	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
        +	 movdqu	($inp),$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 movdqu	16*1($inp),$inout1
        +	pxor	$twres,@tweak[5]
        +
        +	movdqu	16*2($inp),$inout2
        +	pxor	@tweak[0],$inout0
        +	movdqu	16*3($inp),$inout3
        +	pxor	@tweak[1],$inout1
        +	movdqu	16*4($inp),$inout4
        +	lea	16*5($inp),$inp
        +	pxor	@tweak[2],$inout2
        +	pxor	@tweak[3],$inout3
        +	pxor	@tweak[4],$inout4
        +
        +	call	_aesni_decrypt6
        +
        +	xorps	@tweak[0],$inout0
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +	movdqu	$inout0,($out)
        +	xorps	@tweak[3],$inout3
        +	movdqu	$inout1,16*1($out)
        +	xorps	@tweak[4],$inout4
        +	movdqu	$inout2,16*2($out)
        +	 pxor		$twtmp,$twtmp
        +	movdqu	$inout3,16*3($out)
        +	 pcmpgtd	@tweak[5],$twtmp
        +	movdqu	$inout4,16*4($out)
        +	lea	16*5($out),$out
        +	 pshufd		\$0x13,$twtmp,@tweak[1]	# $twres
        +	and	\$15,$len_
        +	jz	.Lxts_dec_ret
        +
        +	movdqa	@tweak[5],@tweak[0]
        +	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
        +	pand	$twmask,@tweak[1]		# isolate carry and residue
        +	pxor	@tweak[5],@tweak[1]
        +	jmp	.Lxts_dec_done2
        +
        +.align	16
        +.Lxts_dec_one:
        +	movups	($inp),$inout0
        +	lea	16*1($inp),$inp
        +	xorps	@tweak[0],$inout0
        +___
        +	&aesni_generate1("dec",$key,$rounds);
        +$code.=<<___;
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[1],@tweak[0]
        +	movups	$inout0,($out)
        +	movdqa	@tweak[2],@tweak[1]
        +	lea	16*1($out),$out
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_two:
        +	movups	($inp),$inout0
        +	movups	16($inp),$inout1
        +	lea	32($inp),$inp
        +	xorps	@tweak[0],$inout0
        +	xorps	@tweak[1],$inout1
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[2],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	movdqa	@tweak[3],@tweak[1]
        +	movups	$inout0,($out)
        +	movups	$inout1,16*1($out)
        +	lea	16*2($out),$out
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_three:
        +	movups	($inp),$inout0
        +	movups	16*1($inp),$inout1
        +	movups	16*2($inp),$inout2
        +	lea	16*3($inp),$inp
        +	xorps	@tweak[0],$inout0
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +
        +	call	_aesni_decrypt3
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[3],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	movdqa	@tweak[5],@tweak[1]
        +	xorps	@tweak[2],$inout2
        +	movups	$inout0,($out)
        +	movups	$inout1,16*1($out)
        +	movups	$inout2,16*2($out)
        +	lea	16*3($out),$out
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_four:
        +	pshufd	\$0x13,$twtmp,$twres
        +	movdqa	@tweak[5],@tweak[4]
        +	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
        +	 movups	($inp),$inout0
        +	pand	$twmask,$twres			# isolate carry and residue
        +	 movups	16*1($inp),$inout1
        +	pxor	$twres,@tweak[5]
        +
        +	movups	16*2($inp),$inout2
        +	xorps	@tweak[0],$inout0
        +	movups	16*3($inp),$inout3
        +	lea	16*4($inp),$inp
        +	xorps	@tweak[1],$inout1
        +	xorps	@tweak[2],$inout2
        +	xorps	@tweak[3],$inout3
        +
        +	call	_aesni_decrypt4
        +
        +	xorps	@tweak[0],$inout0
        +	movdqa	@tweak[4],@tweak[0]
        +	xorps	@tweak[1],$inout1
        +	movdqa	@tweak[5],@tweak[1]
        +	xorps	@tweak[2],$inout2
        +	movups	$inout0,($out)
        +	xorps	@tweak[3],$inout3
        +	movups	$inout1,16*1($out)
        +	movups	$inout2,16*2($out)
        +	movups	$inout3,16*3($out)
        +	lea	16*4($out),$out
        +	jmp	.Lxts_dec_done
        +
        +.align	16
        +.Lxts_dec_done:
        +	and	\$15,$len_
        +	jz	.Lxts_dec_ret
        +.Lxts_dec_done2:
        +	mov	$len_,$len
        +	mov	$key_,$key			# restore $key
        +	mov	$rnds_,$rounds			# restore $rounds
        +
        +	movups	($inp),$inout0
        +	xorps	@tweak[1],$inout0
        +___
        +	&aesni_generate1("dec",$key,$rounds);
        +$code.=<<___;
        +	xorps	@tweak[1],$inout0
        +	movups	$inout0,($out)
        +
        +.Lxts_dec_steal:
        +	movzb	16($inp),%eax			# borrow $rounds ...
        +	movzb	($out),%ecx			# ... and $key
        +	lea	1($inp),$inp
        +	mov	%al,($out)
        +	mov	%cl,16($out)
        +	lea	1($out),$out
        +	sub	\$1,$len
        +	jnz	.Lxts_dec_steal
        +
        +	sub	$len_,$out			# rewind $out
        +	mov	$key_,$key			# restore $key
        +	mov	$rnds_,$rounds			# restore $rounds
        +
        +	movups	($out),$inout0
        +	xorps	@tweak[0],$inout0
        +___
        +	&aesni_generate1("dec",$key,$rounds);
        +$code.=<<___;
        +	xorps	@tweak[0],$inout0
        +	movups	$inout0,($out)
        +
        +.Lxts_dec_ret:
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x60(%rsp),%xmm6
        +	movaps	0x70(%rsp),%xmm7
        +	movaps	0x80(%rsp),%xmm8
        +	movaps	0x90(%rsp),%xmm9
        +	movaps	0xa0(%rsp),%xmm10
        +	movaps	0xb0(%rsp),%xmm11
        +	movaps	0xc0(%rsp),%xmm12
        +	movaps	0xd0(%rsp),%xmm13
        +	movaps	0xe0(%rsp),%xmm14
        +	movaps	0xf0(%rsp),%xmm15
        +___
        +$code.=<<___;
        +	lea	$frame_size(%rsp),%rsp
        +.Lxts_dec_epilogue:
        +	ret
        +.size	aesni_xts_decrypt,.-aesni_xts_decrypt
        +___
        +} }}
        +
        +########################################################################
        +# void $PREFIX_cbc_encrypt (const void *inp, void *out,
        +#			    size_t length, const AES_KEY *key,
        +#			    unsigned char *ivp,const int enc);
        +{
        +my $reserved = $win64?0x40:-0x18;	# used in decrypt
        +$code.=<<___;
        +.globl	${PREFIX}_cbc_encrypt
        +.type	${PREFIX}_cbc_encrypt,\@function,6
        +.align	16
        +${PREFIX}_cbc_encrypt:
        +	test	$len,$len		# check length
        +	jz	.Lcbc_ret
        +
        +	mov	240($key),$rnds_	# key->rounds
        +	mov	$key,$key_		# backup $key
        +	test	%r9d,%r9d		# 6th argument
        +	jz	.Lcbc_decrypt
        +#--------------------------- CBC ENCRYPT ------------------------------#
        +	movups	($ivp),$inout0		# load iv as initial state
        +	mov	$rnds_,$rounds
        +	cmp	\$16,$len
        +	jb	.Lcbc_enc_tail
        +	sub	\$16,$len
        +	jmp	.Lcbc_enc_loop
        +.align	16
        +.Lcbc_enc_loop:
        +	movups	($inp),$inout1		# load input
        +	lea	16($inp),$inp
        +	#xorps	$inout1,$inout0
        +___
        +	&aesni_generate1("enc",$key,$rounds,$inout0,$inout1);
        +$code.=<<___;
        +	mov	$rnds_,$rounds		# restore $rounds
        +	mov	$key_,$key		# restore $key
        +	movups	$inout0,0($out)		# store output
        +	lea	16($out),$out
        +	sub	\$16,$len
        +	jnc	.Lcbc_enc_loop
        +	add	\$16,$len
        +	jnz	.Lcbc_enc_tail
        +	movups	$inout0,($ivp)
        +	jmp	.Lcbc_ret
        +
        +.Lcbc_enc_tail:
        +	mov	$len,%rcx	# zaps $key
        +	xchg	$inp,$out	# $inp is %rsi and $out is %rdi now
        +	.long	0x9066A4F3	# rep movsb
        +	mov	\$16,%ecx	# zero tail
        +	sub	$len,%rcx
        +	xor	%eax,%eax
        +	.long	0x9066AAF3	# rep stosb
        +	lea	-16(%rdi),%rdi	# rewind $out by 1 block
        +	mov	$rnds_,$rounds	# restore $rounds
        +	mov	%rdi,%rsi	# $inp and $out are the same
        +	mov	$key_,$key	# restore $key
        +	xor	$len,$len	# len=16
        +	jmp	.Lcbc_enc_loop	# one more spin
        +#--------------------------- CBC DECRYPT ------------------------------#
        +.align	16
        +.Lcbc_decrypt:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0x58(%rsp),%rsp
        +	movaps	%xmm6,(%rsp)
        +	movaps	%xmm7,0x10(%rsp)
        +	movaps	%xmm8,0x20(%rsp)
        +	movaps	%xmm9,0x30(%rsp)
        +.Lcbc_decrypt_body:
        +___
        +$code.=<<___;
        +	movups	($ivp),$iv
        +	mov	$rnds_,$rounds
        +	cmp	\$0x70,$len
        +	jbe	.Lcbc_dec_tail
        +	shr	\$1,$rnds_
        +	sub	\$0x70,$len
        +	mov	$rnds_,$rounds
        +	movaps	$iv,$reserved(%rsp)
        +	jmp	.Lcbc_dec_loop8_enter
        +.align	16
        +.Lcbc_dec_loop8:
        +	movaps	$rndkey0,$reserved(%rsp)	# save IV
        +	movups	$inout7,($out)
        +	lea	0x10($out),$out
        +.Lcbc_dec_loop8_enter:
        +	$movkey		($key),$rndkey0
        +	movups	($inp),$inout0			# load input
        +	movups	0x10($inp),$inout1
        +	$movkey		16($key),$rndkey1
        +
        +	lea		32($key),$key
        +	movdqu	0x20($inp),$inout2
        +	xorps		$rndkey0,$inout0
        +	movdqu	0x30($inp),$inout3
        +	xorps		$rndkey0,$inout1
        +	movdqu	0x40($inp),$inout4
        +	aesdec		$rndkey1,$inout0
        +	pxor		$rndkey0,$inout2
        +	movdqu	0x50($inp),$inout5
        +	aesdec		$rndkey1,$inout1
        +	pxor		$rndkey0,$inout3
        +	movdqu	0x60($inp),$inout6
        +	aesdec		$rndkey1,$inout2
        +	pxor		$rndkey0,$inout4
        +	movdqu	0x70($inp),$inout7
        +	aesdec		$rndkey1,$inout3
        +	pxor		$rndkey0,$inout5
        +	dec		$rounds
        +	aesdec		$rndkey1,$inout4
        +	pxor		$rndkey0,$inout6
        +	aesdec		$rndkey1,$inout5
        +	pxor		$rndkey0,$inout7
        +	$movkey		($key),$rndkey0
        +	aesdec		$rndkey1,$inout6
        +	aesdec		$rndkey1,$inout7
        +	$movkey		16($key),$rndkey1
        +
        +	call		.Ldec_loop8_enter
        +
        +	movups	($inp),$rndkey1		# re-load input
        +	movups	0x10($inp),$rndkey0
        +	xorps	$reserved(%rsp),$inout0	# ^= IV
        +	xorps	$rndkey1,$inout1
        +	movups	0x20($inp),$rndkey1
        +	xorps	$rndkey0,$inout2
        +	movups	0x30($inp),$rndkey0
        +	xorps	$rndkey1,$inout3
        +	movups	0x40($inp),$rndkey1
        +	xorps	$rndkey0,$inout4
        +	movups	0x50($inp),$rndkey0
        +	xorps	$rndkey1,$inout5
        +	movups	0x60($inp),$rndkey1
        +	xorps	$rndkey0,$inout6
        +	movups	0x70($inp),$rndkey0	# IV
        +	xorps	$rndkey1,$inout7
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	mov	$rnds_,$rounds		# restore $rounds
        +	movups	$inout4,0x40($out)
        +	mov	$key_,$key		# restore $key
        +	movups	$inout5,0x50($out)
        +	lea	0x80($inp),$inp
        +	movups	$inout6,0x60($out)
        +	lea	0x70($out),$out
        +	sub	\$0x80,$len
        +	ja	.Lcbc_dec_loop8
        +
        +	movaps	$inout7,$inout0
        +	movaps	$rndkey0,$iv
        +	add	\$0x70,$len
        +	jle	.Lcbc_dec_tail_collected
        +	movups	$inout0,($out)
        +	lea	1($rnds_,$rnds_),$rounds
        +	lea	0x10($out),$out
        +.Lcbc_dec_tail:
        +	movups	($inp),$inout0
        +	movaps	$inout0,$in0
        +	cmp	\$0x10,$len
        +	jbe	.Lcbc_dec_one
        +
        +	movups	0x10($inp),$inout1
        +	movaps	$inout1,$in1
        +	cmp	\$0x20,$len
        +	jbe	.Lcbc_dec_two
        +
        +	movups	0x20($inp),$inout2
        +	movaps	$inout2,$in2
        +	cmp	\$0x30,$len
        +	jbe	.Lcbc_dec_three
        +
        +	movups	0x30($inp),$inout3
        +	cmp	\$0x40,$len
        +	jbe	.Lcbc_dec_four
        +
        +	movups	0x40($inp),$inout4
        +	cmp	\$0x50,$len
        +	jbe	.Lcbc_dec_five
        +
        +	movups	0x50($inp),$inout5
        +	cmp	\$0x60,$len
        +	jbe	.Lcbc_dec_six
        +
        +	movups	0x60($inp),$inout6
        +	movaps	$iv,$reserved(%rsp)	# save IV
        +	call	_aesni_decrypt8
        +	movups	($inp),$rndkey1
        +	movups	0x10($inp),$rndkey0
        +	xorps	$reserved(%rsp),$inout0	# ^= IV
        +	xorps	$rndkey1,$inout1
        +	movups	0x20($inp),$rndkey1
        +	xorps	$rndkey0,$inout2
        +	movups	0x30($inp),$rndkey0
        +	xorps	$rndkey1,$inout3
        +	movups	0x40($inp),$rndkey1
        +	xorps	$rndkey0,$inout4
        +	movups	0x50($inp),$rndkey0
        +	xorps	$rndkey1,$inout5
        +	movups	0x60($inp),$iv		# IV
        +	xorps	$rndkey0,$inout6
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	movups	$inout5,0x50($out)
        +	lea	0x60($out),$out
        +	movaps	$inout6,$inout0
        +	sub	\$0x70,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_one:
        +___
        +	&aesni_generate1("dec",$key,$rounds);
        +$code.=<<___;
        +	xorps	$iv,$inout0
        +	movaps	$in0,$iv
        +	sub	\$0x10,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_two:
        +	xorps	$inout2,$inout2
        +	call	_aesni_decrypt3
        +	xorps	$iv,$inout0
        +	xorps	$in0,$inout1
        +	movups	$inout0,($out)
        +	movaps	$in1,$iv
        +	movaps	$inout1,$inout0
        +	lea	0x10($out),$out
        +	sub	\$0x20,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_three:
        +	call	_aesni_decrypt3
        +	xorps	$iv,$inout0
        +	xorps	$in0,$inout1
        +	movups	$inout0,($out)
        +	xorps	$in1,$inout2
        +	movups	$inout1,0x10($out)
        +	movaps	$in2,$iv
        +	movaps	$inout2,$inout0
        +	lea	0x20($out),$out
        +	sub	\$0x30,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_four:
        +	call	_aesni_decrypt4
        +	xorps	$iv,$inout0
        +	movups	0x30($inp),$iv
        +	xorps	$in0,$inout1
        +	movups	$inout0,($out)
        +	xorps	$in1,$inout2
        +	movups	$inout1,0x10($out)
        +	xorps	$in2,$inout3
        +	movups	$inout2,0x20($out)
        +	movaps	$inout3,$inout0
        +	lea	0x30($out),$out
        +	sub	\$0x40,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_five:
        +	xorps	$inout5,$inout5
        +	call	_aesni_decrypt6
        +	movups	0x10($inp),$rndkey1
        +	movups	0x20($inp),$rndkey0
        +	xorps	$iv,$inout0
        +	xorps	$in0,$inout1
        +	xorps	$rndkey1,$inout2
        +	movups	0x30($inp),$rndkey1
        +	xorps	$rndkey0,$inout3
        +	movups	0x40($inp),$iv
        +	xorps	$rndkey1,$inout4
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	lea	0x40($out),$out
        +	movaps	$inout4,$inout0
        +	sub	\$0x50,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_six:
        +	call	_aesni_decrypt6
        +	movups	0x10($inp),$rndkey1
        +	movups	0x20($inp),$rndkey0
        +	xorps	$iv,$inout0
        +	xorps	$in0,$inout1
        +	xorps	$rndkey1,$inout2
        +	movups	0x30($inp),$rndkey1
        +	xorps	$rndkey0,$inout3
        +	movups	0x40($inp),$rndkey0
        +	xorps	$rndkey1,$inout4
        +	movups	0x50($inp),$iv
        +	xorps	$rndkey0,$inout5
        +	movups	$inout0,($out)
        +	movups	$inout1,0x10($out)
        +	movups	$inout2,0x20($out)
        +	movups	$inout3,0x30($out)
        +	movups	$inout4,0x40($out)
        +	lea	0x50($out),$out
        +	movaps	$inout5,$inout0
        +	sub	\$0x60,$len
        +	jmp	.Lcbc_dec_tail_collected
        +.align	16
        +.Lcbc_dec_tail_collected:
        +	and	\$15,$len
        +	movups	$iv,($ivp)
        +	jnz	.Lcbc_dec_tail_partial
        +	movups	$inout0,($out)
        +	jmp	.Lcbc_dec_ret
        +.align	16
        +.Lcbc_dec_tail_partial:
        +	movaps	$inout0,$reserved(%rsp)
        +	mov	\$16,%rcx
        +	mov	$out,%rdi
        +	sub	$len,%rcx
        +	lea	$reserved(%rsp),%rsi
        +	.long	0x9066A4F3	# rep movsb
        +
        +.Lcbc_dec_ret:
        +___
        +$code.=<<___ if ($win64);
        +	movaps	(%rsp),%xmm6
        +	movaps	0x10(%rsp),%xmm7
        +	movaps	0x20(%rsp),%xmm8
        +	movaps	0x30(%rsp),%xmm9
        +	lea	0x58(%rsp),%rsp
        +___
        +$code.=<<___;
        +.Lcbc_ret:
        +	ret
        +.size	${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
        +___
        +} 
        +# int $PREFIX_set_[en|de]crypt_key (const unsigned char *userKey,
        +#				int bits, AES_KEY *key)
        +{ my ($inp,$bits,$key) = @_4args;
        +  $bits =~ s/%r/%e/;
        +
        +$code.=<<___;
        +.globl	${PREFIX}_set_decrypt_key
        +.type	${PREFIX}_set_decrypt_key,\@abi-omnipotent
        +.align	16
        +${PREFIX}_set_decrypt_key:
        +	.byte	0x48,0x83,0xEC,0x08	# sub rsp,8
        +	call	__aesni_set_encrypt_key
        +	shl	\$4,$bits		# rounds-1 after _aesni_set_encrypt_key
        +	test	%eax,%eax
        +	jnz	.Ldec_key_ret
        +	lea	16($key,$bits),$inp	# points at the end of key schedule
        +
        +	$movkey	($key),%xmm0		# just swap
        +	$movkey	($inp),%xmm1
        +	$movkey	%xmm0,($inp)
        +	$movkey	%xmm1,($key)
        +	lea	16($key),$key
        +	lea	-16($inp),$inp
        +
        +.Ldec_key_inverse:
        +	$movkey	($key),%xmm0		# swap and inverse
        +	$movkey	($inp),%xmm1
        +	aesimc	%xmm0,%xmm0
        +	aesimc	%xmm1,%xmm1
        +	lea	16($key),$key
        +	lea	-16($inp),$inp
        +	$movkey	%xmm0,16($inp)
        +	$movkey	%xmm1,-16($key)
        +	cmp	$key,$inp
        +	ja	.Ldec_key_inverse
        +
        +	$movkey	($key),%xmm0		# inverse middle
        +	aesimc	%xmm0,%xmm0
        +	$movkey	%xmm0,($inp)
        +.Ldec_key_ret:
        +	add	\$8,%rsp
        +	ret
        +.LSEH_end_set_decrypt_key:
        +.size	${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
        +___
        +
        +# This is based on submission by
        +#
        +#	Huang Ying <ying.huang@intel.com>
        +#	Vinodh Gopal <vinodh.gopal@intel.com>
        +#	Kahraman Akdemir
        +#
        +# Agressively optimized in respect to aeskeygenassist's critical path
        +# and is contained in %xmm0-5 to meet Win64 ABI requirement.
        +#
        +$code.=<<___;
        +.globl	${PREFIX}_set_encrypt_key
        +.type	${PREFIX}_set_encrypt_key,\@abi-omnipotent
        +.align	16
        +${PREFIX}_set_encrypt_key:
        +__aesni_set_encrypt_key:
        +	.byte	0x48,0x83,0xEC,0x08	# sub rsp,8
        +	mov	\$-1,%rax
        +	test	$inp,$inp
        +	jz	.Lenc_key_ret
        +	test	$key,$key
        +	jz	.Lenc_key_ret
        +
        +	movups	($inp),%xmm0		# pull first 128 bits of *userKey
        +	xorps	%xmm4,%xmm4		# low dword of xmm4 is assumed 0
        +	lea	16($key),%rax
        +	cmp	\$256,$bits
        +	je	.L14rounds
        +	cmp	\$192,$bits
        +	je	.L12rounds
        +	cmp	\$128,$bits
        +	jne	.Lbad_keybits
        +
        +.L10rounds:
        +	mov	\$9,$bits			# 10 rounds for 128-bit key
        +	$movkey	%xmm0,($key)			# round 0
        +	aeskeygenassist	\$0x1,%xmm0,%xmm1	# round 1
        +	call		.Lkey_expansion_128_cold
        +	aeskeygenassist	\$0x2,%xmm0,%xmm1	# round 2
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x4,%xmm0,%xmm1	# round 3
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x8,%xmm0,%xmm1	# round 4
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x10,%xmm0,%xmm1	# round 5
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x20,%xmm0,%xmm1	# round 6
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x40,%xmm0,%xmm1	# round 7
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x80,%xmm0,%xmm1	# round 8
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x1b,%xmm0,%xmm1	# round 9
        +	call		.Lkey_expansion_128
        +	aeskeygenassist	\$0x36,%xmm0,%xmm1	# round 10
        +	call		.Lkey_expansion_128
        +	$movkey	%xmm0,(%rax)
        +	mov	$bits,80(%rax)	# 240(%rdx)
        +	xor	%eax,%eax
        +	jmp	.Lenc_key_ret
        +
        +.align	16
        +.L12rounds:
        +	movq	16($inp),%xmm2			# remaining 1/3 of *userKey
        +	mov	\$11,$bits			# 12 rounds for 192
        +	$movkey	%xmm0,($key)			# round 0
        +	aeskeygenassist	\$0x1,%xmm2,%xmm1	# round 1,2
        +	call		.Lkey_expansion_192a_cold
        +	aeskeygenassist	\$0x2,%xmm2,%xmm1	# round 2,3
        +	call		.Lkey_expansion_192b
        +	aeskeygenassist	\$0x4,%xmm2,%xmm1	# round 4,5
        +	call		.Lkey_expansion_192a
        +	aeskeygenassist	\$0x8,%xmm2,%xmm1	# round 5,6
        +	call		.Lkey_expansion_192b
        +	aeskeygenassist	\$0x10,%xmm2,%xmm1	# round 7,8
        +	call		.Lkey_expansion_192a
        +	aeskeygenassist	\$0x20,%xmm2,%xmm1	# round 8,9
        +	call		.Lkey_expansion_192b
        +	aeskeygenassist	\$0x40,%xmm2,%xmm1	# round 10,11
        +	call		.Lkey_expansion_192a
        +	aeskeygenassist	\$0x80,%xmm2,%xmm1	# round 11,12
        +	call		.Lkey_expansion_192b
        +	$movkey	%xmm0,(%rax)
        +	mov	$bits,48(%rax)	# 240(%rdx)
        +	xor	%rax, %rax
        +	jmp	.Lenc_key_ret
        +
        +.align	16
        +.L14rounds:
        +	movups	16($inp),%xmm2			# remaning half of *userKey
        +	mov	\$13,$bits			# 14 rounds for 256
        +	lea	16(%rax),%rax
        +	$movkey	%xmm0,($key)			# round 0
        +	$movkey	%xmm2,16($key)			# round 1
        +	aeskeygenassist	\$0x1,%xmm2,%xmm1	# round 2
        +	call		.Lkey_expansion_256a_cold
        +	aeskeygenassist	\$0x1,%xmm0,%xmm1	# round 3
        +	call		.Lkey_expansion_256b
        +	aeskeygenassist	\$0x2,%xmm2,%xmm1	# round 4
        +	call		.Lkey_expansion_256a
        +	aeskeygenassist	\$0x2,%xmm0,%xmm1	# round 5
        +	call		.Lkey_expansion_256b
        +	aeskeygenassist	\$0x4,%xmm2,%xmm1	# round 6
        +	call		.Lkey_expansion_256a
        +	aeskeygenassist	\$0x4,%xmm0,%xmm1	# round 7
        +	call		.Lkey_expansion_256b
        +	aeskeygenassist	\$0x8,%xmm2,%xmm1	# round 8
        +	call		.Lkey_expansion_256a
        +	aeskeygenassist	\$0x8,%xmm0,%xmm1	# round 9
        +	call		.Lkey_expansion_256b
        +	aeskeygenassist	\$0x10,%xmm2,%xmm1	# round 10
        +	call		.Lkey_expansion_256a
        +	aeskeygenassist	\$0x10,%xmm0,%xmm1	# round 11
        +	call		.Lkey_expansion_256b
        +	aeskeygenassist	\$0x20,%xmm2,%xmm1	# round 12
        +	call		.Lkey_expansion_256a
        +	aeskeygenassist	\$0x20,%xmm0,%xmm1	# round 13
        +	call		.Lkey_expansion_256b
        +	aeskeygenassist	\$0x40,%xmm2,%xmm1	# round 14
        +	call		.Lkey_expansion_256a
        +	$movkey	%xmm0,(%rax)
        +	mov	$bits,16(%rax)	# 240(%rdx)
        +	xor	%rax,%rax
        +	jmp	.Lenc_key_ret
        +
        +.align	16
        +.Lbad_keybits:
        +	mov	\$-2,%rax
        +.Lenc_key_ret:
        +	add	\$8,%rsp
        +	ret
        +.LSEH_end_set_encrypt_key:
        +
        +.align	16
        +.Lkey_expansion_128:
        +	$movkey	%xmm0,(%rax)
        +	lea	16(%rax),%rax
        +.Lkey_expansion_128_cold:
        +	shufps	\$0b00010000,%xmm0,%xmm4
        +	xorps	%xmm4, %xmm0
        +	shufps	\$0b10001100,%xmm0,%xmm4
        +	xorps	%xmm4, %xmm0
        +	shufps	\$0b11111111,%xmm1,%xmm1	# critical path
        +	xorps	%xmm1,%xmm0
        +	ret
        +
        +.align 16
        +.Lkey_expansion_192a:
        +	$movkey	%xmm0,(%rax)
        +	lea	16(%rax),%rax
        +.Lkey_expansion_192a_cold:
        +	movaps	%xmm2, %xmm5
        +.Lkey_expansion_192b_warm:
        +	shufps	\$0b00010000,%xmm0,%xmm4
        +	movdqa	%xmm2,%xmm3
        +	xorps	%xmm4,%xmm0
        +	shufps	\$0b10001100,%xmm0,%xmm4
        +	pslldq	\$4,%xmm3
        +	xorps	%xmm4,%xmm0
        +	pshufd	\$0b01010101,%xmm1,%xmm1	# critical path
        +	pxor	%xmm3,%xmm2
        +	pxor	%xmm1,%xmm0
        +	pshufd	\$0b11111111,%xmm0,%xmm3
        +	pxor	%xmm3,%xmm2
        +	ret
        +
        +.align 16
        +.Lkey_expansion_192b:
        +	movaps	%xmm0,%xmm3
        +	shufps	\$0b01000100,%xmm0,%xmm5
        +	$movkey	%xmm5,(%rax)
        +	shufps	\$0b01001110,%xmm2,%xmm3
        +	$movkey	%xmm3,16(%rax)
        +	lea	32(%rax),%rax
        +	jmp	.Lkey_expansion_192b_warm
        +
        +.align	16
        +.Lkey_expansion_256a:
        +	$movkey	%xmm2,(%rax)
        +	lea	16(%rax),%rax
        +.Lkey_expansion_256a_cold:
        +	shufps	\$0b00010000,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	\$0b10001100,%xmm0,%xmm4
        +	xorps	%xmm4,%xmm0
        +	shufps	\$0b11111111,%xmm1,%xmm1	# critical path
        +	xorps	%xmm1,%xmm0
        +	ret
        +
        +.align 16
        +.Lkey_expansion_256b:
        +	$movkey	%xmm0,(%rax)
        +	lea	16(%rax),%rax
        +
        +	shufps	\$0b00010000,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	\$0b10001100,%xmm2,%xmm4
        +	xorps	%xmm4,%xmm2
        +	shufps	\$0b10101010,%xmm1,%xmm1	# critical path
        +	xorps	%xmm1,%xmm2
        +	ret
        +.size	${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
        +.size	__aesni_set_encrypt_key,.-__aesni_set_encrypt_key
        +___
        +}
        +
        +$code.=<<___;
        +.align	64
        +.Lbswap_mask:
        +	.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
        +.Lincrement32:
        +	.long	6,6,6,0
        +.Lincrement64:
        +	.long	1,0,0,0
        +.Lxts_magic:
        +	.long	0x87,0,1,0
        +
        +.asciz  "AES for Intel AES-NI, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	64
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +___
        +$code.=<<___ if ($PREFIX eq "aesni");
        +.type	ecb_se_handler,\@abi-omnipotent
        +.align	16
        +ecb_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	jmp	.Lcommon_seh_tail
        +.size	ecb_se_handler,.-ecb_se_handler
        +
        +.type	ccm64_se_handler,\@abi-omnipotent
        +.align	16
        +ccm64_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lcommon_seh_tail
        +
        +	lea	0(%rax),%rsi		# %xmm save area
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$8,%ecx		# 4*sizeof(%xmm0)/sizeof(%rax)
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	0x58(%rax),%rax		# adjust stack pointer
        +
        +	jmp	.Lcommon_seh_tail
        +.size	ccm64_se_handler,.-ccm64_se_handler
        +
        +.type	ctr32_se_handler,\@abi-omnipotent
        +.align	16
        +ctr32_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lctr32_body(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<"prologue" label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lctr32_ret(%rip),%r10
        +	cmp	%r10,%rbx
        +	jae	.Lcommon_seh_tail
        +
        +	lea	0x20(%rax),%rsi		# %xmm save area
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	0xc8(%rax),%rax		# adjust stack pointer
        +
        +	jmp	.Lcommon_seh_tail
        +.size	ctr32_se_handler,.-ctr32_se_handler
        +
        +.type	xts_se_handler,\@abi-omnipotent
        +.align	16
        +xts_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue lable
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lcommon_seh_tail
        +
        +	lea	0x60(%rax),%rsi		# %xmm save area
        +	lea	512($context),%rdi	# & context.Xmm6
        +	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	0x68+160(%rax),%rax	# adjust stack pointer
        +
        +	jmp	.Lcommon_seh_tail
        +.size	xts_se_handler,.-xts_se_handler
        +___
        +$code.=<<___;
        +.type	cbc_se_handler,\@abi-omnipotent
        +.align	16
        +cbc_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lcbc_decrypt(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<"prologue" label
        +	jb	.Lcommon_seh_tail
        +
        +	lea	.Lcbc_decrypt_body(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<cbc_decrypt_body
        +	jb	.Lrestore_cbc_rax
        +
        +	lea	.Lcbc_ret(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>="epilogue" label
        +	jae	.Lcommon_seh_tail
        +
        +	lea	0(%rax),%rsi		# top of stack
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$8,%ecx		# 4*sizeof(%xmm0)/sizeof(%rax)
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	0x58(%rax),%rax		# adjust stack pointer
        +	jmp	.Lcommon_seh_tail
        +
        +.Lrestore_cbc_rax:
        +	mov	120($context),%rax
        +
        +.Lcommon_seh_tail:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	cbc_se_handler,.-cbc_se_handler
        +
        +.section	.pdata
        +.align	4
        +___
        +$code.=<<___ if ($PREFIX eq "aesni");
        +	.rva	.LSEH_begin_aesni_ecb_encrypt
        +	.rva	.LSEH_end_aesni_ecb_encrypt
        +	.rva	.LSEH_info_ecb
        +
        +	.rva	.LSEH_begin_aesni_ccm64_encrypt_blocks
        +	.rva	.LSEH_end_aesni_ccm64_encrypt_blocks
        +	.rva	.LSEH_info_ccm64_enc
        +
        +	.rva	.LSEH_begin_aesni_ccm64_decrypt_blocks
        +	.rva	.LSEH_end_aesni_ccm64_decrypt_blocks
        +	.rva	.LSEH_info_ccm64_dec
        +
        +	.rva	.LSEH_begin_aesni_ctr32_encrypt_blocks
        +	.rva	.LSEH_end_aesni_ctr32_encrypt_blocks
        +	.rva	.LSEH_info_ctr32
        +
        +	.rva	.LSEH_begin_aesni_xts_encrypt
        +	.rva	.LSEH_end_aesni_xts_encrypt
        +	.rva	.LSEH_info_xts_enc
        +
        +	.rva	.LSEH_begin_aesni_xts_decrypt
        +	.rva	.LSEH_end_aesni_xts_decrypt
        +	.rva	.LSEH_info_xts_dec
        +___
        +$code.=<<___;
        +	.rva	.LSEH_begin_${PREFIX}_cbc_encrypt
        +	.rva	.LSEH_end_${PREFIX}_cbc_encrypt
        +	.rva	.LSEH_info_cbc
        +
        +	.rva	${PREFIX}_set_decrypt_key
        +	.rva	.LSEH_end_set_decrypt_key
        +	.rva	.LSEH_info_key
        +
        +	.rva	${PREFIX}_set_encrypt_key
        +	.rva	.LSEH_end_set_encrypt_key
        +	.rva	.LSEH_info_key
        +.section	.xdata
        +.align	8
        +___
        +$code.=<<___ if ($PREFIX eq "aesni");
        +.LSEH_info_ecb:
        +	.byte	9,0,0,0
        +	.rva	ecb_se_handler
        +.LSEH_info_ccm64_enc:
        +	.byte	9,0,0,0
        +	.rva	ccm64_se_handler
        +	.rva	.Lccm64_enc_body,.Lccm64_enc_ret	# HandlerData[]
        +.LSEH_info_ccm64_dec:
        +	.byte	9,0,0,0
        +	.rva	ccm64_se_handler
        +	.rva	.Lccm64_dec_body,.Lccm64_dec_ret	# HandlerData[]
        +.LSEH_info_ctr32:
        +	.byte	9,0,0,0
        +	.rva	ctr32_se_handler
        +.LSEH_info_xts_enc:
        +	.byte	9,0,0,0
        +	.rva	xts_se_handler
        +	.rva	.Lxts_enc_body,.Lxts_enc_epilogue	# HandlerData[]
        +.LSEH_info_xts_dec:
        +	.byte	9,0,0,0
        +	.rva	xts_se_handler
        +	.rva	.Lxts_dec_body,.Lxts_dec_epilogue	# HandlerData[]
        +___
        +$code.=<<___;
        +.LSEH_info_cbc:
        +	.byte	9,0,0,0
        +	.rva	cbc_se_handler
        +.LSEH_info_key:
        +	.byte	0x01,0x04,0x01,0x00
        +	.byte	0x04,0x02,0x00,0x00	# sub rsp,8
        +___
        +}
        +
        +sub rex {
        +  local *opcode=shift;
        +  my ($dst,$src)=@_;
        +  my $rex=0;
        +
        +    $rex|=0x04			if($dst>=8);
        +    $rex|=0x01			if($src>=8);
        +    push @opcode,$rex|0x40	if($rex);
        +}
        +
        +sub aesni {
        +  my $line=shift;
        +  my @opcode=(0x66);
        +
        +    if ($line=~/(aeskeygenassist)\s+\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
        +	rex(\@opcode,$4,$3);
        +	push @opcode,0x0f,0x3a,0xdf;
        +	push @opcode,0xc0|($3&7)|(($4&7)<<3);	# ModR/M
        +	my $c=$2;
        +	push @opcode,$c=~/^0/?oct($c):$c;
        +	return ".byte\t".join(',',@opcode);
        +    }
        +    elsif ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
        +	my %opcodelet = (
        +		"aesimc" => 0xdb,
        +		"aesenc" => 0xdc,	"aesenclast" => 0xdd,
        +		"aesdec" => 0xde,	"aesdeclast" => 0xdf
        +	);
        +	return undef if (!defined($opcodelet{$1}));
        +	rex(\@opcode,$3,$2);
        +	push @opcode,0x0f,0x38,$opcodelet{$1};
        +	push @opcode,0xc0|($2&7)|(($3&7)<<3);	# ModR/M
        +	return ".byte\t".join(',',@opcode);
        +    }
        +    return $line;
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl b/vendor/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl
        new file mode 100644
        index 000000000..ceb02b50d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/bsaes-x86_64.pl
        @@ -0,0 +1,3045 @@
        +#!/usr/bin/env perl
        +
        +###################################################################
        +### AES-128 [originally in CTR mode]				###
        +### bitsliced implementation for Intel Core 2 processors	###
        +### requires support of SSE extensions up to SSSE3		###
        +### Author: Emilia Käsper and Peter Schwabe			###
        +### Date: 2009-03-19						###
        +### Public domain						###
        +###								###
        +### See http://homes.esat.kuleuven.be/~ekasper/#software for	###
        +### further information.					###
        +###################################################################
        +#
        +# September 2011.
        +#
        +# Started as transliteration to "perlasm" the original code has
        +# undergone following changes:
        +#
        +# - code was made position-independent;
        +# - rounds were folded into a loop resulting in >5x size reduction
        +#   from 12.5KB to 2.2KB;
        +# - above was possibile thanks to mixcolumns() modification that
        +#   allowed to feed its output back to aesenc[last], this was
        +#   achieved at cost of two additional inter-registers moves;
        +# - some instruction reordering and interleaving;
        +# - this module doesn't implement key setup subroutine, instead it
        +#   relies on conversion of "conventional" key schedule as returned
        +#   by AES_set_encrypt_key (see discussion below);
        +# - first and last round keys are treated differently, which allowed
        +#   to skip one shiftrows(), reduce bit-sliced key schedule and
        +#   speed-up conversion by 22%;
        +# - support for 192- and 256-bit keys was added;
        +#
        +# Resulting performance in CPU cycles spent to encrypt one byte out
        +# of 4096-byte buffer with 128-bit key is:
        +#
        +#		Emilia's	this(*)		difference
        +#
        +# Core 2    	9.30		8.69		+7%
        +# Nehalem(**) 	7.63		6.98		+9%
        +# Atom	    	17.1		17.4		-2%(***)
        +#
        +# (*)	Comparison is not completely fair, because "this" is ECB,
        +#	i.e. no extra processing such as counter values calculation
        +#	and xor-ing input as in Emilia's CTR implementation is
        +#	performed. However, the CTR calculations stand for not more
        +#	than 1% of total time, so comparison is *rather* fair.
        +#
        +# (**)	Results were collected on Westmere, which is considered to
        +#	be equivalent to Nehalem for this code.
        +#
        +# (***)	Slowdown on Atom is rather strange per se, because original
        +#	implementation has a number of 9+-bytes instructions, which
        +#	are bad for Atom front-end, and which I eliminated completely.
        +#	In attempt to address deterioration sbox() was tested in FP
        +#	SIMD "domain" (movaps instead of movdqa, xorps instead of
        +#	pxor, etc.). While it resulted in nominal 4% improvement on
        +#	Atom, it hurted Westmere by more than 2x factor.
        +#
        +# As for key schedule conversion subroutine. Interface to OpenSSL
        +# relies on per-invocation on-the-fly conversion. This naturally
        +# has impact on performance, especially for short inputs. Conversion
        +# time in CPU cycles and its ratio to CPU cycles spent in 8x block
        +# function is:
        +#
        +# 		conversion	conversion/8x block
        +# Core 2	240		0.22
        +# Nehalem	180		0.20
        +# Atom		430		0.19
        +#
        +# The ratio values mean that 128-byte blocks will be processed
        +# 16-18% slower, 256-byte blocks - 9-10%, 384-byte blocks - 6-7%,
        +# etc. Then keep in mind that input sizes not divisible by 128 are
        +# *effectively* slower, especially shortest ones, e.g. consecutive
        +# 144-byte blocks are processed 44% slower than one would expect,
        +# 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings"
        +# it's still faster than ["hyper-threading-safe" code path in]
        +# aes-x86_64.pl on all lengths above 64 bytes...
        +#
        +# October 2011.
        +#
        +# Add decryption procedure. Performance in CPU cycles spent to decrypt
        +# one byte out of 4096-byte buffer with 128-bit key is:
        +#
        +# Core 2	11.0
        +# Nehalem	9.16
        +# Atom		20.9
        +#
        +# November 2011.
        +#
        +# Add bsaes_xts_[en|de]crypt. Less-than-80-bytes-block performance is
        +# suboptimal, but XTS is meant to be used with larger blocks...
        +#
        +#						<appro@openssl.org>
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
        +my @XMM=map("%xmm$_",(15,0..14));	# best on Atom, +10% over (0..15)
        +my $ecb=0;	# suppress unreferenced ECB subroutines, spare some space...
        +
        +{
        +my ($key,$rounds,$const)=("%rax","%r10d","%r11");
        +
        +sub Sbox {
        +# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
        +# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
        +my @b=@_[0..7];
        +my @t=@_[8..11];
        +my @s=@_[12..15];
        +	&InBasisChange	(@b);
        +	&Inv_GF256	(@b[6,5,0,3,7,1,4,2],@t,@s);
        +	&OutBasisChange	(@b[7,1,4,2,6,5,0,3]);
        +}
        +
        +sub InBasisChange {
        +# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
        +# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 
        +my @b=@_[0..7];
        +$code.=<<___;
        +	pxor	@b[6], @b[5]
        +	pxor	@b[1], @b[2]
        +	pxor	@b[0], @b[3]
        +	pxor	@b[2], @b[6]
        +	pxor 	@b[0], @b[5]
        +
        +	pxor	@b[3], @b[6]
        +	pxor	@b[7], @b[3]
        +	pxor	@b[5], @b[7]
        +	pxor	@b[4], @b[3]
        +	pxor	@b[5], @b[4]
        +	pxor	@b[1], @b[3]
        +
        +	pxor	@b[7], @b[2]
        +	pxor	@b[5], @b[1]
        +___
        +}
        +
        +sub OutBasisChange {
        +# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
        +# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
        +my @b=@_[0..7];
        +$code.=<<___;
        +	pxor	@b[6], @b[0]
        +	pxor	@b[4], @b[1]
        +	pxor	@b[0], @b[2]
        +	pxor	@b[6], @b[4]
        +	pxor	@b[1], @b[6]
        +
        +	pxor	@b[5], @b[1]
        +	pxor	@b[3], @b[5]
        +	pxor	@b[7], @b[3]
        +	pxor	@b[5], @b[7]
        +	pxor	@b[5], @b[2]
        +
        +	pxor	@b[7], @b[4]
        +___
        +}
        +
        +sub InvSbox {
        +# input in lsb 	> [b0, b1, b2, b3, b4, b5, b6, b7] < msb
        +# output in lsb	> [b0, b1, b6, b4, b2, b7, b3, b5] < msb
        +my @b=@_[0..7];
        +my @t=@_[8..11];
        +my @s=@_[12..15];
        +	&InvInBasisChange	(@b);
        +	&Inv_GF256		(@b[5,1,2,6,3,7,0,4],@t,@s);
        +	&InvOutBasisChange	(@b[3,7,0,4,5,1,2,6]);
        +}
        +
        +sub InvInBasisChange {		# OutBasisChange in reverse
        +my @b=@_[5,1,2,6,3,7,0,4];
        +$code.=<<___
        +	pxor	@b[7], @b[4]
        +
        +	pxor	@b[5], @b[7]
        +	pxor	@b[5], @b[2]
        +	pxor	@b[7], @b[3]
        +	pxor	@b[3], @b[5]
        +	pxor	@b[5], @b[1]
        +
        +	pxor	@b[1], @b[6]
        +	pxor	@b[0], @b[2]
        +	pxor	@b[6], @b[4]
        +	pxor	@b[6], @b[0]
        +	pxor	@b[4], @b[1]
        +___
        +}
        +
        +sub InvOutBasisChange {		# InBasisChange in reverse
        +my @b=@_[2,5,7,3,6,1,0,4];
        +$code.=<<___;
        +	pxor	@b[5], @b[1]
        +	pxor	@b[7], @b[2]
        +
        +	pxor	@b[1], @b[3]
        +	pxor	@b[5], @b[4]
        +	pxor	@b[5], @b[7]
        +	pxor	@b[4], @b[3]
        +	 pxor 	@b[0], @b[5]
        +	pxor	@b[7], @b[3]
        +	 pxor	@b[2], @b[6]
        +	 pxor	@b[1], @b[2]
        +	pxor	@b[3], @b[6]
        +
        +	pxor	@b[0], @b[3]
        +	pxor	@b[6], @b[5]
        +___
        +}
        +
        +sub Mul_GF4 {
        +#;*************************************************************
        +#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
        +#;*************************************************************
        +my ($x0,$x1,$y0,$y1,$t0)=@_;
        +$code.=<<___;
        +	movdqa	$y0, $t0
        +	pxor 	$y1, $t0
        +	pand	$x0, $t0
        +	pxor	$x1, $x0
        +	pand	$y0, $x1
        +	pand	$y1, $x0
        +	pxor	$x1, $x0
        +	pxor	$t0, $x1
        +___
        +}
        +
        +sub Mul_GF4_N {				# not used, see next subroutine
        +# multiply and scale by N
        +my ($x0,$x1,$y0,$y1,$t0)=@_;
        +$code.=<<___;
        +	movdqa	$y0, $t0
        +	pxor	$y1, $t0
        +	pand	$x0, $t0
        +	pxor	$x1, $x0
        +	pand	$y0, $x1
        +	pand	$y1, $x0
        +	pxor	$x0, $x1
        +	pxor	$t0, $x0
        +___
        +}
        +
        +sub Mul_GF4_N_GF4 {
        +# interleaved Mul_GF4_N and Mul_GF4
        +my ($x0,$x1,$y0,$y1,$t0,
        +    $x2,$x3,$y2,$y3,$t1)=@_;
        +$code.=<<___;
        +	movdqa	$y0, $t0
        +	 movdqa	$y2, $t1
        +	pxor	$y1, $t0
        +	 pxor 	$y3, $t1
        +	pand	$x0, $t0
        +	 pand	$x2, $t1
        +	pxor	$x1, $x0
        +	 pxor	$x3, $x2
        +	pand	$y0, $x1
        +	 pand	$y2, $x3
        +	pand	$y1, $x0
        +	 pand	$y3, $x2
        +	pxor	$x0, $x1
        +	 pxor	$x3, $x2
        +	pxor	$t0, $x0
        +	 pxor	$t1, $x3
        +___
        +}
        +sub Mul_GF16_2 {
        +my @x=@_[0..7];
        +my @y=@_[8..11];
        +my @t=@_[12..15];
        +$code.=<<___;
        +	movdqa	@x[0], @t[0]
        +	movdqa	@x[1], @t[1]
        +___
        +	&Mul_GF4  	(@x[0], @x[1], @y[0], @y[1], @t[2]);
        +$code.=<<___;
        +	pxor	@x[2], @t[0]
        +	pxor	@x[3], @t[1]
        +	pxor	@y[2], @y[0]
        +	pxor	@y[3], @y[1]
        +___
        +	Mul_GF4_N_GF4	(@t[0], @t[1], @y[0], @y[1], @t[3],
        +			 @x[2], @x[3], @y[2], @y[3], @t[2]);
        +$code.=<<___;
        +	pxor	@t[0], @x[0]
        +	pxor	@t[0], @x[2]
        +	pxor	@t[1], @x[1]
        +	pxor	@t[1], @x[3]
        +
        +	movdqa	@x[4], @t[0]
        +	movdqa	@x[5], @t[1]
        +	pxor	@x[6], @t[0]
        +	pxor	@x[7], @t[1]
        +___
        +	&Mul_GF4_N_GF4	(@t[0], @t[1], @y[0], @y[1], @t[3],
        +			 @x[6], @x[7], @y[2], @y[3], @t[2]);
        +$code.=<<___;
        +	pxor	@y[2], @y[0]
        +	pxor	@y[3], @y[1]
        +___
        +	&Mul_GF4  	(@x[4], @x[5], @y[0], @y[1], @t[3]);
        +$code.=<<___;
        +	pxor	@t[0], @x[4]
        +	pxor	@t[0], @x[6]
        +	pxor	@t[1], @x[5]
        +	pxor	@t[1], @x[7]
        +___
        +}
        +sub Inv_GF256 {
        +#;********************************************************************
        +#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
        +#;********************************************************************
        +my @x=@_[0..7];
        +my @t=@_[8..11];
        +my @s=@_[12..15];
        +# direct optimizations from hardware
        +$code.=<<___;
        +	movdqa	@x[4], @t[3]
        +	movdqa	@x[5], @t[2]
        +	movdqa	@x[1], @t[1]
        +	movdqa	@x[7], @s[1]
        +	movdqa	@x[0], @s[0]
        +
        +	pxor	@x[6], @t[3]
        +	pxor	@x[7], @t[2]
        +	pxor	@x[3], @t[1]
        +	 movdqa	@t[3], @s[2]
        +	pxor	@x[6], @s[1]
        +	 movdqa	@t[2], @t[0]
        +	pxor	@x[2], @s[0]
        +	 movdqa	@t[3], @s[3]
        +
        +	por	@t[1], @t[2]
        +	por	@s[0], @t[3]
        +	pxor	@t[0], @s[3]
        +	pand	@s[0], @s[2]
        +	pxor	@t[1], @s[0]
        +	pand	@t[1], @t[0]
        +	pand	@s[0], @s[3]
        +	movdqa	@x[3], @s[0]
        +	pxor	@x[2], @s[0]
        +	pand	@s[0], @s[1]
        +	pxor	@s[1], @t[3]
        +	pxor	@s[1], @t[2]
        +	movdqa	@x[4], @s[1]
        +	movdqa	@x[1], @s[0]
        +	pxor	@x[5], @s[1]
        +	pxor	@x[0], @s[0]
        +	movdqa	@s[1], @t[1]
        +	pand	@s[0], @s[1]
        +	por	@s[0], @t[1]
        +	pxor	@s[1], @t[0]
        +	pxor	@s[3], @t[3]
        +	pxor	@s[2], @t[2]
        +	pxor	@s[3], @t[1]
        +	movdqa	@x[7], @s[0]
        +	pxor	@s[2], @t[0]
        +	movdqa	@x[6], @s[1]
        +	pxor	@s[2], @t[1]
        +	movdqa	@x[5], @s[2]
        +	pand	@x[3], @s[0]
        +	movdqa	@x[4], @s[3]
        +	pand	@x[2], @s[1]
        +	pand	@x[1], @s[2]
        +	por	@x[0], @s[3]
        +	pxor	@s[0], @t[3]
        +	pxor	@s[1], @t[2]
        +	pxor	@s[2], @t[1]
        +	pxor	@s[3], @t[0] 
        +
        +	#Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
        +
        +	# new smaller inversion
        +
        +	movdqa	@t[3], @s[0]
        +	pand	@t[1], @t[3]
        +	pxor	@t[2], @s[0]
        +
        +	movdqa	@t[0], @s[2]
        +	movdqa	@s[0], @s[3]
        +	pxor	@t[3], @s[2]
        +	pand	@s[2], @s[3]
        +
        +	movdqa	@t[1], @s[1]
        +	pxor	@t[2], @s[3]
        +	pxor	@t[0], @s[1]
        +
        +	pxor	@t[2], @t[3]
        +
        +	pand	@t[3], @s[1]
        +
        +	movdqa	@s[2], @t[2]
        +	pxor	@t[0], @s[1]
        +
        +	pxor	@s[1], @t[2]
        +	pxor	@s[1], @t[1]
        +
        +	pand	@t[0], @t[2]
        +
        +	pxor	@t[2], @s[2]
        +	pxor	@t[2], @t[1]
        +
        +	pand	@s[3], @s[2]
        +
        +	pxor	@s[0], @s[2]
        +___
        +# output in s3, s2, s1, t1
        +
        +# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
        +
        +# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
        +	&Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
        +
        +### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
        +}
        +
        +# AES linear components
        +
        +sub ShiftRows {
        +my @x=@_[0..7];
        +my $mask=pop;
        +$code.=<<___;
        +	pxor	0x00($key),@x[0]
        +	pxor	0x10($key),@x[1]
        +	pshufb	$mask,@x[0]
        +	pxor	0x20($key),@x[2]
        +	pshufb	$mask,@x[1]
        +	pxor	0x30($key),@x[3]
        +	pshufb	$mask,@x[2]
        +	pxor	0x40($key),@x[4]
        +	pshufb	$mask,@x[3]
        +	pxor	0x50($key),@x[5]
        +	pshufb	$mask,@x[4]
        +	pxor	0x60($key),@x[6]
        +	pshufb	$mask,@x[5]
        +	pxor	0x70($key),@x[7]
        +	pshufb	$mask,@x[6]
        +	lea	0x80($key),$key
        +	pshufb	$mask,@x[7]
        +___
        +}
        +
        +sub MixColumns {
        +# modified to emit output in order suitable for feeding back to aesenc[last]
        +my @x=@_[0..7];
        +my @t=@_[8..15];
        +$code.=<<___;
        +	pshufd	\$0x93, @x[0], @t[0]	# x0 <<< 32
        +	pshufd	\$0x93, @x[1], @t[1]
        +	 pxor	@t[0], @x[0]		# x0 ^ (x0 <<< 32)
        +	pshufd	\$0x93, @x[2], @t[2]
        +	 pxor	@t[1], @x[1]
        +	pshufd	\$0x93, @x[3], @t[3]
        +	 pxor	@t[2], @x[2]
        +	pshufd	\$0x93, @x[4], @t[4]
        +	 pxor	@t[3], @x[3]
        +	pshufd	\$0x93, @x[5], @t[5]
        +	 pxor	@t[4], @x[4]
        +	pshufd	\$0x93, @x[6], @t[6]
        +	 pxor	@t[5], @x[5]
        +	pshufd	\$0x93, @x[7], @t[7]
        +	 pxor	@t[6], @x[6]
        +	 pxor	@t[7], @x[7]
        +
        +	pxor	@x[0], @t[1]
        +	pxor	@x[7], @t[0]
        +	pxor	@x[7], @t[1]
        +	 pshufd	\$0x4E, @x[0], @x[0] 	# (x0 ^ (x0 <<< 32)) <<< 64)
        +	pxor	@x[1], @t[2]
        +	 pshufd	\$0x4E, @x[1], @x[1]
        +	pxor	@x[4], @t[5]
        +	 pxor	@t[0], @x[0]
        +	pxor	@x[5], @t[6]
        +	 pxor	@t[1], @x[1]
        +	pxor	@x[3], @t[4]
        +	 pshufd	\$0x4E, @x[4], @t[0]
        +	pxor	@x[6], @t[7]
        +	 pshufd	\$0x4E, @x[5], @t[1]
        +	pxor	@x[2], @t[3]
        +	 pshufd	\$0x4E, @x[3], @x[4]
        +	pxor	@x[7], @t[3]
        +	 pshufd	\$0x4E, @x[7], @x[5]
        +	pxor	@x[7], @t[4]
        +	 pshufd	\$0x4E, @x[6], @x[3]
        +	pxor	@t[4], @t[0]
        +	 pshufd	\$0x4E, @x[2], @x[6]
        +	pxor	@t[5], @t[1]
        +
        +	pxor	@t[3], @x[4]
        +	pxor	@t[7], @x[5]
        +	pxor	@t[6], @x[3]
        +	 movdqa	@t[0], @x[2]
        +	pxor	@t[2], @x[6]
        +	 movdqa	@t[1], @x[7]
        +___
        +}
        +
        +sub InvMixColumns {
        +my @x=@_[0..7];
        +my @t=@_[8..15];
        +
        +$code.=<<___;
        +	# multiplication by 0x0e
        +	pshufd	\$0x93, @x[7], @t[7]
        +	movdqa	@x[2], @t[2]
        +	pxor	@x[5], @x[7]		# 7 5
        +	pxor	@x[5], @x[2]		# 2 5
        +	pshufd	\$0x93, @x[0], @t[0]
        +	movdqa	@x[5], @t[5]
        +	pxor	@x[0], @x[5]		# 5 0		[1]
        +	pxor	@x[1], @x[0]		# 0 1
        +	pshufd	\$0x93, @x[1], @t[1]
        +	pxor	@x[2], @x[1]		# 1 25
        +	pxor	@x[6], @x[0]		# 01 6		[2]
        +	pxor	@x[3], @x[1]		# 125 3		[4]
        +	pshufd	\$0x93, @x[3], @t[3]
        +	pxor	@x[0], @x[2]		# 25 016	[3]
        +	pxor	@x[7], @x[3]		# 3 75
        +	pxor	@x[6], @x[7]		# 75 6		[0]
        +	pshufd	\$0x93, @x[6], @t[6]
        +	movdqa	@x[4], @t[4]
        +	pxor	@x[4], @x[6]		# 6 4
        +	pxor	@x[3], @x[4]		# 4 375		[6]
        +	pxor	@x[7], @x[3]		# 375 756=36
        +	pxor	@t[5], @x[6]		# 64 5		[7]
        +	pxor	@t[2], @x[3]		# 36 2
        +	pxor	@t[4], @x[3]		# 362 4		[5]
        +	pshufd	\$0x93, @t[5], @t[5]
        +___
        +					my @y = @x[7,5,0,2,1,3,4,6];
        +$code.=<<___;
        +	# multiplication by 0x0b
        +	pxor	@y[0], @y[1]
        +	pxor	@t[0], @y[0]
        +	pxor	@t[1], @y[1]
        +	pshufd	\$0x93, @t[2], @t[2]
        +	pxor	@t[5], @y[0]
        +	pxor	@t[6], @y[1]
        +	pxor	@t[7], @y[0]
        +	pshufd	\$0x93, @t[4], @t[4]
        +	pxor	@t[6], @t[7]		# clobber t[7]
        +	pxor	@y[0], @y[1]
        +
        +	pxor	@t[0], @y[3]
        +	pshufd	\$0x93, @t[0], @t[0]
        +	pxor	@t[1], @y[2]
        +	pxor	@t[1], @y[4]
        +	pxor	@t[2], @y[2]
        +	pshufd	\$0x93, @t[1], @t[1]
        +	pxor	@t[2], @y[3]
        +	pxor	@t[2], @y[5]
        +	pxor	@t[7], @y[2]
        +	pshufd	\$0x93, @t[2], @t[2]
        +	pxor	@t[3], @y[3]
        +	pxor	@t[3], @y[6]
        +	pxor	@t[3], @y[4]
        +	pshufd	\$0x93, @t[3], @t[3]
        +	pxor	@t[4], @y[7]
        +	pxor	@t[4], @y[5]
        +	pxor	@t[7], @y[7]
        +	pxor	@t[5], @y[3]
        +	pxor	@t[4], @y[4]
        +	pxor	@t[5], @t[7]		# clobber t[7] even more
        +
        +	pxor	@t[7], @y[5]
        +	pshufd	\$0x93, @t[4], @t[4]
        +	pxor	@t[7], @y[6]
        +	pxor	@t[7], @y[4]
        +
        +	pxor	@t[5], @t[7]
        +	pshufd	\$0x93, @t[5], @t[5]
        +	pxor	@t[6], @t[7]		# restore t[7]
        +
        +	# multiplication by 0x0d
        +	pxor	@y[7], @y[4]
        +	pxor	@t[4], @y[7]
        +	pshufd	\$0x93, @t[6], @t[6]
        +	pxor	@t[0], @y[2]
        +	pxor	@t[5], @y[7]
        +	pxor	@t[2], @y[2]
        +	pshufd	\$0x93, @t[7], @t[7]
        +
        +	pxor	@y[1], @y[3]
        +	pxor	@t[1], @y[1]
        +	pxor	@t[0], @y[0]
        +	pxor	@t[0], @y[3]
        +	pxor	@t[5], @y[1]
        +	pxor	@t[5], @y[0]
        +	pxor	@t[7], @y[1]
        +	pshufd	\$0x93, @t[0], @t[0]
        +	pxor	@t[6], @y[0]
        +	pxor	@y[1], @y[3]
        +	pxor	@t[1], @y[4]
        +	pshufd	\$0x93, @t[1], @t[1]
        +
        +	pxor	@t[7], @y[7]
        +	pxor	@t[2], @y[4]
        +	pxor	@t[2], @y[5]
        +	pshufd	\$0x93, @t[2], @t[2]
        +	pxor	@t[6], @y[2]
        +	pxor	@t[3], @t[6]		# clobber t[6]
        +	pxor	@y[7], @y[4]
        +	pxor	@t[6], @y[3]
        +
        +	pxor	@t[6], @y[6]
        +	pxor	@t[5], @y[5]
        +	pxor	@t[4], @y[6]
        +	pshufd	\$0x93, @t[4], @t[4]
        +	pxor	@t[6], @y[5]
        +	pxor	@t[7], @y[6]
        +	pxor	@t[3], @t[6]		# restore t[6]
        +
        +	pshufd	\$0x93, @t[5], @t[5]
        +	pshufd	\$0x93, @t[6], @t[6]
        +	pshufd	\$0x93, @t[7], @t[7]
        +	pshufd	\$0x93, @t[3], @t[3]
        +
        +	# multiplication by 0x09
        +	pxor	@y[1], @y[4]
        +	pxor	@y[1], @t[1]		# t[1]=y[1]
        +	pxor	@t[5], @t[0]		# clobber t[0]
        +	pxor	@t[5], @t[1]
        +	pxor	@t[0], @y[3]
        +	pxor	@y[0], @t[0]		# t[0]=y[0]
        +	pxor	@t[6], @t[1]
        +	pxor	@t[7], @t[6]		# clobber t[6]
        +	pxor	@t[1], @y[4]
        +	pxor	@t[4], @y[7]
        +	pxor	@y[4], @t[4]		# t[4]=y[4]
        +	pxor	@t[3], @y[6]
        +	pxor	@y[3], @t[3]		# t[3]=y[3]
        +	pxor	@t[2], @y[5]
        +	pxor	@y[2], @t[2]		# t[2]=y[2]
        +	pxor	@t[7], @t[3]
        +	pxor	@y[5], @t[5]		# t[5]=y[5]
        +	pxor	@t[6], @t[2]
        +	pxor	@t[6], @t[5]
        +	pxor	@y[6], @t[6]		# t[6]=y[6]
        +	pxor	@y[7], @t[7]		# t[7]=y[7]
        +
        +	movdqa	@t[0],@XMM[0]
        +	movdqa	@t[1],@XMM[1]
        +	movdqa	@t[2],@XMM[2]
        +	movdqa	@t[3],@XMM[3]
        +	movdqa	@t[4],@XMM[4]
        +	movdqa	@t[5],@XMM[5]
        +	movdqa	@t[6],@XMM[6]
        +	movdqa	@t[7],@XMM[7]
        +___
        +}
        +
        +sub aesenc {				# not used
        +my @b=@_[0..7];
        +my @t=@_[8..15];
        +$code.=<<___;
        +	movdqa	0x30($const),@t[0]	# .LSR
        +___
        +	&ShiftRows	(@b,@t[0]);
        +	&Sbox		(@b,@t);
        +	&MixColumns	(@b[0,1,4,6,3,7,2,5],@t);
        +}
        +
        +sub aesenclast {			# not used
        +my @b=@_[0..7];
        +my @t=@_[8..15];
        +$code.=<<___;
        +	movdqa	0x40($const),@t[0]	# .LSRM0
        +___
        +	&ShiftRows	(@b,@t[0]);
        +	&Sbox		(@b,@t);
        +$code.=<<___
        +	pxor	0x00($key),@b[0]
        +	pxor	0x10($key),@b[1]
        +	pxor	0x20($key),@b[4]
        +	pxor	0x30($key),@b[6]
        +	pxor	0x40($key),@b[3]
        +	pxor	0x50($key),@b[7]
        +	pxor	0x60($key),@b[2]
        +	pxor	0x70($key),@b[5]
        +___
        +}
        +
        +sub swapmove {
        +my ($a,$b,$n,$mask,$t)=@_;
        +$code.=<<___;
        +	movdqa	$b,$t
        +	psrlq	\$$n,$b
        +	pxor  	$a,$b
        +	pand	$mask,$b
        +	pxor	$b,$a
        +	psllq	\$$n,$b
        +	pxor	$t,$b
        +___
        +}
        +sub swapmove2x {
        +my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
        +$code.=<<___;
        +	movdqa	$b0,$t0
        +	psrlq	\$$n,$b0
        +	 movdqa	$b1,$t1
        +	 psrlq	\$$n,$b1
        +	pxor  	$a0,$b0
        +	 pxor  	$a1,$b1
        +	pand	$mask,$b0
        +	 pand	$mask,$b1
        +	pxor	$b0,$a0
        +	psllq	\$$n,$b0
        +	 pxor	$b1,$a1
        +	 psllq	\$$n,$b1
        +	pxor	$t0,$b0
        +	 pxor	$t1,$b1
        +___
        +}
        +
        +sub bitslice {
        +my @x=reverse(@_[0..7]);
        +my ($t0,$t1,$t2,$t3)=@_[8..11];
        +$code.=<<___;
        +	movdqa	0x00($const),$t0	# .LBS0
        +	movdqa	0x10($const),$t1	# .LBS1
        +___
        +	&swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
        +	&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
        +$code.=<<___;
        +	movdqa	0x20($const),$t0	# .LBS2
        +___
        +	&swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
        +	&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
        +
        +	&swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
        +	&swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
        +}
        +
        +$code.=<<___;
        +.text
        +
        +.extern	asm_AES_encrypt
        +.extern	asm_AES_decrypt
        +
        +.type	_bsaes_encrypt8,\@abi-omnipotent
        +.align	64
        +_bsaes_encrypt8:
        +	lea	.LBS0(%rip), $const	# constants table
        +
        +	movdqa	($key), @XMM[9]		# round 0 key
        +	lea	0x10($key), $key
        +	movdqa	0x50($const), @XMM[8]	# .LM0SR
        +	pxor	@XMM[9], @XMM[0]	# xor with round0 key
        +	pxor	@XMM[9], @XMM[1]
        +	 pshufb	@XMM[8], @XMM[0]
        +	pxor	@XMM[9], @XMM[2]
        +	 pshufb	@XMM[8], @XMM[1]
        +	pxor	@XMM[9], @XMM[3]
        +	 pshufb	@XMM[8], @XMM[2]
        +	pxor	@XMM[9], @XMM[4]
        +	 pshufb	@XMM[8], @XMM[3]
        +	pxor	@XMM[9], @XMM[5]
        +	 pshufb	@XMM[8], @XMM[4]
        +	pxor	@XMM[9], @XMM[6]
        +	 pshufb	@XMM[8], @XMM[5]
        +	pxor	@XMM[9], @XMM[7]
        +	 pshufb	@XMM[8], @XMM[6]
        +	 pshufb	@XMM[8], @XMM[7]
        +_bsaes_encrypt8_bitslice:
        +___
        +	&bitslice	(@XMM[0..7, 8..11]);
        +$code.=<<___;
        +	dec	$rounds
        +	jmp	.Lenc_sbox
        +.align	16
        +.Lenc_loop:
        +___
        +	&ShiftRows	(@XMM[0..7, 8]);
        +$code.=".Lenc_sbox:\n";
        +	&Sbox		(@XMM[0..7, 8..15]);
        +$code.=<<___;
        +	dec	$rounds
        +	jl	.Lenc_done
        +___
        +	&MixColumns	(@XMM[0,1,4,6,3,7,2,5, 8..15]);
        +$code.=<<___;
        +	movdqa	0x30($const), @XMM[8]	# .LSR
        +	jnz	.Lenc_loop
        +	movdqa	0x40($const), @XMM[8]	# .LSRM0
        +	jmp	.Lenc_loop
        +.align	16
        +.Lenc_done:
        +___
        +	# output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
        +	&bitslice	(@XMM[0,1,4,6,3,7,2,5, 8..11]);
        +$code.=<<___;
        +	movdqa	($key), @XMM[8]		# last round key
        +	pxor	@XMM[8], @XMM[4]
        +	pxor	@XMM[8], @XMM[6]
        +	pxor	@XMM[8], @XMM[3]
        +	pxor	@XMM[8], @XMM[7]
        +	pxor	@XMM[8], @XMM[2]
        +	pxor	@XMM[8], @XMM[5]
        +	pxor	@XMM[8], @XMM[0]
        +	pxor	@XMM[8], @XMM[1]
        +	ret
        +.size	_bsaes_encrypt8,.-_bsaes_encrypt8
        +
        +.type	_bsaes_decrypt8,\@abi-omnipotent
        +.align	64
        +_bsaes_decrypt8:
        +	lea	.LBS0(%rip), $const	# constants table
        +
        +	movdqa	($key), @XMM[9]		# round 0 key
        +	lea	0x10($key), $key
        +	movdqa	-0x30($const), @XMM[8]	# .LM0ISR
        +	pxor	@XMM[9], @XMM[0]	# xor with round0 key
        +	pxor	@XMM[9], @XMM[1]
        +	 pshufb	@XMM[8], @XMM[0]
        +	pxor	@XMM[9], @XMM[2]
        +	 pshufb	@XMM[8], @XMM[1]
        +	pxor	@XMM[9], @XMM[3]
        +	 pshufb	@XMM[8], @XMM[2]
        +	pxor	@XMM[9], @XMM[4]
        +	 pshufb	@XMM[8], @XMM[3]
        +	pxor	@XMM[9], @XMM[5]
        +	 pshufb	@XMM[8], @XMM[4]
        +	pxor	@XMM[9], @XMM[6]
        +	 pshufb	@XMM[8], @XMM[5]
        +	pxor	@XMM[9], @XMM[7]
        +	 pshufb	@XMM[8], @XMM[6]
        +	 pshufb	@XMM[8], @XMM[7]
        +___
        +	&bitslice	(@XMM[0..7, 8..11]);
        +$code.=<<___;
        +	dec	$rounds
        +	jmp	.Ldec_sbox
        +.align	16
        +.Ldec_loop:
        +___
        +	&ShiftRows	(@XMM[0..7, 8]);
        +$code.=".Ldec_sbox:\n";
        +	&InvSbox	(@XMM[0..7, 8..15]);
        +$code.=<<___;
        +	dec	$rounds
        +	jl	.Ldec_done
        +___
        +	&InvMixColumns	(@XMM[0,1,6,4,2,7,3,5, 8..15]);
        +$code.=<<___;
        +	movdqa	-0x10($const), @XMM[8]	# .LISR
        +	jnz	.Ldec_loop
        +	movdqa	-0x20($const), @XMM[8]	# .LISRM0
        +	jmp	.Ldec_loop
        +.align	16
        +.Ldec_done:
        +___
        +	&bitslice	(@XMM[0,1,6,4,2,7,3,5, 8..11]);
        +$code.=<<___;
        +	movdqa	($key), @XMM[8]		# last round key
        +	pxor	@XMM[8], @XMM[6]
        +	pxor	@XMM[8], @XMM[4]
        +	pxor	@XMM[8], @XMM[2]
        +	pxor	@XMM[8], @XMM[7]
        +	pxor	@XMM[8], @XMM[3]
        +	pxor	@XMM[8], @XMM[5]
        +	pxor	@XMM[8], @XMM[0]
        +	pxor	@XMM[8], @XMM[1]
        +	ret
        +.size	_bsaes_decrypt8,.-_bsaes_decrypt8
        +___
        +}
        +{
        +my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11");
        +
        +sub bitslice_key {
        +my @x=reverse(@_[0..7]);
        +my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
        +
        +	&swapmove	(@x[0,1],1,$bs0,$t2,$t3);
        +$code.=<<___;
        +	#&swapmove(@x[2,3],1,$t0,$t2,$t3);
        +	movdqa	@x[0], @x[2]
        +	movdqa	@x[1], @x[3]
        +___
        +	#&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
        +
        +	&swapmove2x	(@x[0,2,1,3],2,$bs1,$t2,$t3);
        +$code.=<<___;
        +	#&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
        +	movdqa	@x[0], @x[4]
        +	movdqa	@x[2], @x[6]
        +	movdqa	@x[1], @x[5]
        +	movdqa	@x[3], @x[7]
        +___
        +	&swapmove2x	(@x[0,4,1,5],4,$bs2,$t2,$t3);
        +	&swapmove2x	(@x[2,6,3,7],4,$bs2,$t2,$t3);
        +}
        +
        +$code.=<<___;
        +.type	_bsaes_key_convert,\@abi-omnipotent
        +.align	16
        +_bsaes_key_convert:
        +	lea	.Lmasks(%rip), $const
        +	movdqu	($inp), %xmm7		# load round 0 key
        +	lea	0x10($inp), $inp
        +	movdqa	0x00($const), %xmm0	# 0x01...
        +	movdqa	0x10($const), %xmm1	# 0x02...
        +	movdqa	0x20($const), %xmm2	# 0x04...
        +	movdqa	0x30($const), %xmm3	# 0x08...
        +	movdqa	0x40($const), %xmm4	# .LM0
        +	pcmpeqd	%xmm5, %xmm5		# .LNOT
        +
        +	movdqu	($inp), %xmm6		# load round 1 key
        +	movdqa	%xmm7, ($out)		# save round 0 key
        +	lea	0x10($out), $out
        +	dec	$rounds
        +	jmp	.Lkey_loop
        +.align	16
        +.Lkey_loop:
        +	pshufb	%xmm4, %xmm6		# .LM0
        +
        +	movdqa	%xmm0,	%xmm8
        +	movdqa	%xmm1,	%xmm9
        +
        +	pand	%xmm6,	%xmm8
        +	pand	%xmm6,	%xmm9
        +	movdqa	%xmm2,	%xmm10
        +	pcmpeqb	%xmm0,	%xmm8
        +	psllq	\$4,	%xmm0		# 0x10...
        +	movdqa	%xmm3,	%xmm11
        +	pcmpeqb	%xmm1,	%xmm9
        +	psllq	\$4,	%xmm1		# 0x20...
        +
        +	pand	%xmm6,	%xmm10
        +	pand	%xmm6,	%xmm11
        +	movdqa	%xmm0,	%xmm12
        +	pcmpeqb	%xmm2,	%xmm10
        +	psllq	\$4,	%xmm2		# 0x40...
        +	movdqa	%xmm1,	%xmm13
        +	pcmpeqb	%xmm3,	%xmm11
        +	psllq	\$4,	%xmm3		# 0x80...
        +
        +	movdqa	%xmm2,	%xmm14
        +	movdqa	%xmm3,	%xmm15
        +	 pxor	%xmm5,	%xmm8		# "pnot"
        +	 pxor	%xmm5,	%xmm9
        +
        +	pand	%xmm6,	%xmm12
        +	pand	%xmm6,	%xmm13
        +	 movdqa	%xmm8, 0x00($out)	# write bit-sliced round key
        +	pcmpeqb	%xmm0,	%xmm12
        +	psrlq	\$4,	%xmm0		# 0x01...
        +	 movdqa	%xmm9, 0x10($out)
        +	pcmpeqb	%xmm1,	%xmm13
        +	psrlq	\$4,	%xmm1		# 0x02...
        +	 lea	0x10($inp), $inp
        +
        +	pand	%xmm6,	%xmm14
        +	pand	%xmm6,	%xmm15
        +	 movdqa	%xmm10, 0x20($out)
        +	pcmpeqb	%xmm2,	%xmm14
        +	psrlq	\$4,	%xmm2		# 0x04...
        +	 movdqa	%xmm11, 0x30($out)
        +	pcmpeqb	%xmm3,	%xmm15
        +	psrlq	\$4,	%xmm3		# 0x08...
        +	 movdqu	($inp), %xmm6		# load next round key
        +
        +	pxor	%xmm5, %xmm13		# "pnot"
        +	pxor	%xmm5, %xmm14
        +	movdqa	%xmm12, 0x40($out)
        +	movdqa	%xmm13, 0x50($out)
        +	movdqa	%xmm14, 0x60($out)
        +	movdqa	%xmm15, 0x70($out)
        +	lea	0x80($out),$out
        +	dec	$rounds
        +	jnz	.Lkey_loop
        +
        +	movdqa	0x50($const), %xmm7	# .L63
        +	#movdqa	%xmm6, ($out)		# don't save last round key
        +	ret
        +.size	_bsaes_key_convert,.-_bsaes_key_convert
        +___
        +}
        +
        +if (0 && !$win64) {	# following four functions are unsupported interface
        +			# used for benchmarking...
        +$code.=<<___;
        +.globl	bsaes_enc_key_convert
        +.type	bsaes_enc_key_convert,\@function,2
        +.align	16
        +bsaes_enc_key_convert:
        +	mov	240($inp),%r10d		# pass rounds
        +	mov	$inp,%rcx		# pass key
        +	mov	$out,%rax		# pass key schedule
        +	call	_bsaes_key_convert
        +	pxor	%xmm6,%xmm7		# fix up last round key
        +	movdqa	%xmm7,(%rax)		# save last round key
        +	ret
        +.size	bsaes_enc_key_convert,.-bsaes_enc_key_convert
        +
        +.globl	bsaes_encrypt_128
        +.type	bsaes_encrypt_128,\@function,4
        +.align	16
        +bsaes_encrypt_128:
        +.Lenc128_loop:
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	movdqu	0x10($inp), @XMM[1]
        +	movdqu	0x20($inp), @XMM[2]
        +	movdqu	0x30($inp), @XMM[3]
        +	movdqu	0x40($inp), @XMM[4]
        +	movdqu	0x50($inp), @XMM[5]
        +	movdqu	0x60($inp), @XMM[6]
        +	movdqu	0x70($inp), @XMM[7]
        +	mov	$key, %rax		# pass the $key
        +	lea	0x80($inp), $inp
        +	mov	\$10,%r10d
        +
        +	call	_bsaes_encrypt8
        +
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	movdqu	@XMM[3], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[2], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +	sub	\$0x80,$len
        +	ja	.Lenc128_loop
        +	ret
        +.size	bsaes_encrypt_128,.-bsaes_encrypt_128
        +
        +.globl	bsaes_dec_key_convert
        +.type	bsaes_dec_key_convert,\@function,2
        +.align	16
        +bsaes_dec_key_convert:
        +	mov	240($inp),%r10d		# pass rounds
        +	mov	$inp,%rcx		# pass key
        +	mov	$out,%rax		# pass key schedule
        +	call	_bsaes_key_convert
        +	pxor	($out),%xmm7		# fix up round 0 key
        +	movdqa	%xmm6,(%rax)		# save last round key
        +	movdqa	%xmm7,($out)
        +	ret
        +.size	bsaes_dec_key_convert,.-bsaes_dec_key_convert
        +
        +.globl	bsaes_decrypt_128
        +.type	bsaes_decrypt_128,\@function,4
        +.align	16
        +bsaes_decrypt_128:
        +.Ldec128_loop:
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	movdqu	0x10($inp), @XMM[1]
        +	movdqu	0x20($inp), @XMM[2]
        +	movdqu	0x30($inp), @XMM[3]
        +	movdqu	0x40($inp), @XMM[4]
        +	movdqu	0x50($inp), @XMM[5]
        +	movdqu	0x60($inp), @XMM[6]
        +	movdqu	0x70($inp), @XMM[7]
        +	mov	$key, %rax		# pass the $key
        +	lea	0x80($inp), $inp
        +	mov	\$10,%r10d
        +
        +	call	_bsaes_decrypt8
        +
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[3], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +	sub	\$0x80,$len
        +	ja	.Ldec128_loop
        +	ret
        +.size	bsaes_decrypt_128,.-bsaes_decrypt_128
        +___
        +}
        +{
        +######################################################################
        +#
        +# OpenSSL interface
        +#
        +my ($arg1,$arg2,$arg3,$arg4,$arg5,$arg6)=$win64	? ("%rcx","%rdx","%r8","%r9","%r10","%r11d")
        +						: ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
        +my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15");
        +
        +if ($ecb) {
        +$code.=<<___;
        +.globl	bsaes_ecb_encrypt_blocks
        +.type	bsaes_ecb_encrypt_blocks,\@abi-omnipotent
        +.align	16
        +bsaes_ecb_encrypt_blocks:
        +	mov	%rsp, %rax
        +.Lecb_enc_prologue:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	-0x48(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xa0(%rsp), %rsp
        +	movaps	%xmm6, 0x40(%rsp)
        +	movaps	%xmm7, 0x50(%rsp)
        +	movaps	%xmm8, 0x60(%rsp)
        +	movaps	%xmm9, 0x70(%rsp)
        +	movaps	%xmm10, 0x80(%rsp)
        +	movaps	%xmm11, 0x90(%rsp)
        +	movaps	%xmm12, 0xa0(%rsp)
        +	movaps	%xmm13, 0xb0(%rsp)
        +	movaps	%xmm14, 0xc0(%rsp)
        +	movaps	%xmm15, 0xd0(%rsp)
        +.Lecb_enc_body:
        +___
        +$code.=<<___;
        +	mov	%rsp,%rbp		# backup %rsp
        +	mov	240($arg4),%eax		# rounds
        +	mov	$arg1,$inp		# backup arguments
        +	mov	$arg2,$out
        +	mov	$arg3,$len
        +	mov	$arg4,$key
        +	cmp	\$8,$arg3
        +	jb	.Lecb_enc_short
        +
        +	mov	%eax,%ebx		# backup rounds
        +	shl	\$7,%rax		# 128 bytes per inner round key
        +	sub	\$`128-32`,%rax		# size of bit-sliced key schedule
        +	sub	%rax,%rsp
        +	mov	%rsp,%rax		# pass key schedule
        +	mov	$key,%rcx		# pass key
        +	mov	%ebx,%r10d		# pass rounds
        +	call	_bsaes_key_convert
        +	pxor	%xmm6,%xmm7		# fix up last round key
        +	movdqa	%xmm7,(%rax)		# save last round key
        +
        +	sub	\$8,$len
        +.Lecb_enc_loop:
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	movdqu	0x10($inp), @XMM[1]
        +	movdqu	0x20($inp), @XMM[2]
        +	movdqu	0x30($inp), @XMM[3]
        +	movdqu	0x40($inp), @XMM[4]
        +	movdqu	0x50($inp), @XMM[5]
        +	mov	%rsp, %rax		# pass key schedule
        +	movdqu	0x60($inp), @XMM[6]
        +	mov	%ebx,%r10d		# pass rounds
        +	movdqu	0x70($inp), @XMM[7]
        +	lea	0x80($inp), $inp
        +
        +	call	_bsaes_encrypt8
        +
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	movdqu	@XMM[3], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[2], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +	sub	\$8,$len
        +	jnc	.Lecb_enc_loop
        +
        +	add	\$8,$len
        +	jz	.Lecb_enc_done
        +
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	%ebx,%r10d		# pass rounds
        +	cmp	\$2,$len
        +	jb	.Lecb_enc_one
        +	movdqu	0x10($inp), @XMM[1]
        +	je	.Lecb_enc_two
        +	movdqu	0x20($inp), @XMM[2]
        +	cmp	\$4,$len
        +	jb	.Lecb_enc_three
        +	movdqu	0x30($inp), @XMM[3]
        +	je	.Lecb_enc_four
        +	movdqu	0x40($inp), @XMM[4]
        +	cmp	\$6,$len
        +	jb	.Lecb_enc_five
        +	movdqu	0x50($inp), @XMM[5]
        +	je	.Lecb_enc_six
        +	movdqu	0x60($inp), @XMM[6]
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	movdqu	@XMM[3], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[2], 0x60($out)
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_six:
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	movdqu	@XMM[3], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_five:
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	movdqu	@XMM[3], 0x40($out)
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_four:
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_three:
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_two:
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_one:
        +	call	_bsaes_encrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	jmp	.Lecb_enc_done
        +.align	16
        +.Lecb_enc_short:
        +	lea	($inp), $arg1
        +	lea	($out), $arg2
        +	lea	($key), $arg3
        +	call	asm_AES_encrypt
        +	lea	16($inp), $inp
        +	lea	16($out), $out
        +	dec	$len
        +	jnz	.Lecb_enc_short
        +
        +.Lecb_enc_done:
        +	lea	(%rsp),%rax
        +	pxor	%xmm0, %xmm0
        +.Lecb_enc_bzero:			# wipe key schedule [if any]
        +	movdqa	%xmm0, 0x00(%rax)
        +	movdqa	%xmm0, 0x10(%rax)
        +	lea	0x20(%rax), %rax
        +	cmp	%rax, %rbp
        +	jb	.Lecb_enc_bzero
        +
        +	lea	(%rbp),%rsp		# restore %rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x40(%rbp), %xmm6
        +	movaps	0x50(%rbp), %xmm7
        +	movaps	0x60(%rbp), %xmm8
        +	movaps	0x70(%rbp), %xmm9
        +	movaps	0x80(%rbp), %xmm10
        +	movaps	0x90(%rbp), %xmm11
        +	movaps	0xa0(%rbp), %xmm12
        +	movaps	0xb0(%rbp), %xmm13
        +	movaps	0xc0(%rbp), %xmm14
        +	movaps	0xd0(%rbp), %xmm15
        +	lea	0xa0(%rbp), %rsp
        +___
        +$code.=<<___;
        +	mov	0x48(%rsp), %r15
        +	mov	0x50(%rsp), %r14
        +	mov	0x58(%rsp), %r13
        +	mov	0x60(%rsp), %r12
        +	mov	0x68(%rsp), %rbx
        +	mov	0x70(%rsp), %rax
        +	lea	0x78(%rsp), %rsp
        +	mov	%rax, %rbp
        +.Lecb_enc_epilogue:
        +	ret
        +.size	bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
        +
        +.globl	bsaes_ecb_decrypt_blocks
        +.type	bsaes_ecb_decrypt_blocks,\@abi-omnipotent
        +.align	16
        +bsaes_ecb_decrypt_blocks:
        +	mov	%rsp, %rax
        +.Lecb_dec_prologue:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	-0x48(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xa0(%rsp), %rsp
        +	movaps	%xmm6, 0x40(%rsp)
        +	movaps	%xmm7, 0x50(%rsp)
        +	movaps	%xmm8, 0x60(%rsp)
        +	movaps	%xmm9, 0x70(%rsp)
        +	movaps	%xmm10, 0x80(%rsp)
        +	movaps	%xmm11, 0x90(%rsp)
        +	movaps	%xmm12, 0xa0(%rsp)
        +	movaps	%xmm13, 0xb0(%rsp)
        +	movaps	%xmm14, 0xc0(%rsp)
        +	movaps	%xmm15, 0xd0(%rsp)
        +.Lecb_dec_body:
        +___
        +$code.=<<___;
        +	mov	%rsp,%rbp		# backup %rsp
        +	mov	240($arg4),%eax		# rounds
        +	mov	$arg1,$inp		# backup arguments
        +	mov	$arg2,$out
        +	mov	$arg3,$len
        +	mov	$arg4,$key
        +	cmp	\$8,$arg3
        +	jb	.Lecb_dec_short
        +
        +	mov	%eax,%ebx		# backup rounds
        +	shl	\$7,%rax		# 128 bytes per inner round key
        +	sub	\$`128-32`,%rax		# size of bit-sliced key schedule
        +	sub	%rax,%rsp
        +	mov	%rsp,%rax		# pass key schedule
        +	mov	$key,%rcx		# pass key
        +	mov	%ebx,%r10d		# pass rounds
        +	call	_bsaes_key_convert
        +	pxor	(%rsp),%xmm7		# fix up 0 round key
        +	movdqa	%xmm6,(%rax)		# save last round key
        +	movdqa	%xmm7,(%rsp)
        +
        +	sub	\$8,$len
        +.Lecb_dec_loop:
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	movdqu	0x10($inp), @XMM[1]
        +	movdqu	0x20($inp), @XMM[2]
        +	movdqu	0x30($inp), @XMM[3]
        +	movdqu	0x40($inp), @XMM[4]
        +	movdqu	0x50($inp), @XMM[5]
        +	mov	%rsp, %rax		# pass key schedule
        +	movdqu	0x60($inp), @XMM[6]
        +	mov	%ebx,%r10d		# pass rounds
        +	movdqu	0x70($inp), @XMM[7]
        +	lea	0x80($inp), $inp
        +
        +	call	_bsaes_decrypt8
        +
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[3], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +	sub	\$8,$len
        +	jnc	.Lecb_dec_loop
        +
        +	add	\$8,$len
        +	jz	.Lecb_dec_done
        +
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	%ebx,%r10d		# pass rounds
        +	cmp	\$2,$len
        +	jb	.Lecb_dec_one
        +	movdqu	0x10($inp), @XMM[1]
        +	je	.Lecb_dec_two
        +	movdqu	0x20($inp), @XMM[2]
        +	cmp	\$4,$len
        +	jb	.Lecb_dec_three
        +	movdqu	0x30($inp), @XMM[3]
        +	je	.Lecb_dec_four
        +	movdqu	0x40($inp), @XMM[4]
        +	cmp	\$6,$len
        +	jb	.Lecb_dec_five
        +	movdqu	0x50($inp), @XMM[5]
        +	je	.Lecb_dec_six
        +	movdqu	0x60($inp), @XMM[6]
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[3], 0x60($out)
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_six:
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_five:
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_four:
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_three:
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_two:
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_one:
        +	call	_bsaes_decrypt8
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	jmp	.Lecb_dec_done
        +.align	16
        +.Lecb_dec_short:
        +	lea	($inp), $arg1
        +	lea	($out), $arg2
        +	lea	($key), $arg3
        +	call	asm_AES_decrypt
        +	lea	16($inp), $inp
        +	lea	16($out), $out
        +	dec	$len
        +	jnz	.Lecb_dec_short
        +
        +.Lecb_dec_done:
        +	lea	(%rsp),%rax
        +	pxor	%xmm0, %xmm0
        +.Lecb_dec_bzero:			# wipe key schedule [if any]
        +	movdqa	%xmm0, 0x00(%rax)
        +	movdqa	%xmm0, 0x10(%rax)
        +	lea	0x20(%rax), %rax
        +	cmp	%rax, %rbp
        +	jb	.Lecb_dec_bzero
        +
        +	lea	(%rbp),%rsp		# restore %rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x40(%rbp), %xmm6
        +	movaps	0x50(%rbp), %xmm7
        +	movaps	0x60(%rbp), %xmm8
        +	movaps	0x70(%rbp), %xmm9
        +	movaps	0x80(%rbp), %xmm10
        +	movaps	0x90(%rbp), %xmm11
        +	movaps	0xa0(%rbp), %xmm12
        +	movaps	0xb0(%rbp), %xmm13
        +	movaps	0xc0(%rbp), %xmm14
        +	movaps	0xd0(%rbp), %xmm15
        +	lea	0xa0(%rbp), %rsp
        +___
        +$code.=<<___;
        +	mov	0x48(%rsp), %r15
        +	mov	0x50(%rsp), %r14
        +	mov	0x58(%rsp), %r13
        +	mov	0x60(%rsp), %r12
        +	mov	0x68(%rsp), %rbx
        +	mov	0x70(%rsp), %rax
        +	lea	0x78(%rsp), %rsp
        +	mov	%rax, %rbp
        +.Lecb_dec_epilogue:
        +	ret
        +.size	bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
        +___
        +}
        +$code.=<<___;
        +.extern	asm_AES_cbc_encrypt
        +.globl	bsaes_cbc_encrypt
        +.type	bsaes_cbc_encrypt,\@abi-omnipotent
        +.align	16
        +bsaes_cbc_encrypt:
        +___
        +$code.=<<___ if ($win64);
        +	mov	48(%rsp),$arg6		# pull direction flag
        +___
        +$code.=<<___;
        +	cmp	\$0,$arg6
        +	jne	asm_AES_cbc_encrypt
        +	cmp	\$128,$arg3
        +	jb	asm_AES_cbc_encrypt
        +
        +	mov	%rsp, %rax
        +.Lcbc_dec_prologue:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	-0x48(%rsp), %rsp
        +___
        +$code.=<<___ if ($win64);
        +	mov	0xa0(%rsp),$arg5	# pull ivp
        +	lea	-0xa0(%rsp), %rsp
        +	movaps	%xmm6, 0x40(%rsp)
        +	movaps	%xmm7, 0x50(%rsp)
        +	movaps	%xmm8, 0x60(%rsp)
        +	movaps	%xmm9, 0x70(%rsp)
        +	movaps	%xmm10, 0x80(%rsp)
        +	movaps	%xmm11, 0x90(%rsp)
        +	movaps	%xmm12, 0xa0(%rsp)
        +	movaps	%xmm13, 0xb0(%rsp)
        +	movaps	%xmm14, 0xc0(%rsp)
        +	movaps	%xmm15, 0xd0(%rsp)
        +.Lcbc_dec_body:
        +___
        +$code.=<<___;
        +	mov	%rsp, %rbp		# backup %rsp
        +	mov	240($arg4), %eax	# rounds
        +	mov	$arg1, $inp		# backup arguments
        +	mov	$arg2, $out
        +	mov	$arg3, $len
        +	mov	$arg4, $key
        +	mov	$arg5, %rbx
        +	shr	\$4, $len		# bytes to blocks
        +
        +	mov	%eax, %edx		# rounds
        +	shl	\$7, %rax		# 128 bytes per inner round key
        +	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
        +	sub	%rax, %rsp
        +
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	$key, %rcx		# pass key
        +	mov	%edx, %r10d		# pass rounds
        +	call	_bsaes_key_convert
        +	pxor	(%rsp),%xmm7		# fix up 0 round key
        +	movdqa	%xmm6,(%rax)		# save last round key
        +	movdqa	%xmm7,(%rsp)
        +
        +	movdqu	(%rbx), @XMM[15]	# load IV
        +	sub	\$8,$len
        +.Lcbc_dec_loop:
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	movdqu	0x10($inp), @XMM[1]
        +	movdqu	0x20($inp), @XMM[2]
        +	movdqu	0x30($inp), @XMM[3]
        +	movdqu	0x40($inp), @XMM[4]
        +	movdqu	0x50($inp), @XMM[5]
        +	mov	%rsp, %rax		# pass key schedule
        +	movdqu	0x60($inp), @XMM[6]
        +	mov	%edx,%r10d		# pass rounds
        +	movdqu	0x70($inp), @XMM[7]
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	0x20($inp), @XMM[10]
        +	pxor	@XMM[9], @XMM[6]
        +	movdqu	0x30($inp), @XMM[11]
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	0x40($inp), @XMM[12]
        +	pxor	@XMM[11], @XMM[2]
        +	movdqu	0x50($inp), @XMM[13]
        +	pxor	@XMM[12], @XMM[7]
        +	movdqu	0x60($inp), @XMM[14]
        +	pxor	@XMM[13], @XMM[3]
        +	movdqu	0x70($inp), @XMM[15]	# IV
        +	pxor	@XMM[14], @XMM[5]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	lea	0x80($inp), $inp
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[3], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +	sub	\$8,$len
        +	jnc	.Lcbc_dec_loop
        +
        +	add	\$8,$len
        +	jz	.Lcbc_dec_done
        +
        +	movdqu	0x00($inp), @XMM[0]	# load input
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +	cmp	\$2,$len
        +	jb	.Lcbc_dec_one
        +	movdqu	0x10($inp), @XMM[1]
        +	je	.Lcbc_dec_two
        +	movdqu	0x20($inp), @XMM[2]
        +	cmp	\$4,$len
        +	jb	.Lcbc_dec_three
        +	movdqu	0x30($inp), @XMM[3]
        +	je	.Lcbc_dec_four
        +	movdqu	0x40($inp), @XMM[4]
        +	cmp	\$6,$len
        +	jb	.Lcbc_dec_five
        +	movdqu	0x50($inp), @XMM[5]
        +	je	.Lcbc_dec_six
        +	movdqu	0x60($inp), @XMM[6]
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +	call	_bsaes_decrypt8
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	0x20($inp), @XMM[10]
        +	pxor	@XMM[9], @XMM[6]
        +	movdqu	0x30($inp), @XMM[11]
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	0x40($inp), @XMM[12]
        +	pxor	@XMM[11], @XMM[2]
        +	movdqu	0x50($inp), @XMM[13]
        +	pxor	@XMM[12], @XMM[7]
        +	movdqu	0x60($inp), @XMM[15]	# IV
        +	pxor	@XMM[13], @XMM[3]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[3], 0x60($out)
        +	jmp	.Lcbc_dec_done
        +.align	16
        +.Lcbc_dec_six:
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +	call	_bsaes_decrypt8
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	0x20($inp), @XMM[10]
        +	pxor	@XMM[9], @XMM[6]
        +	movdqu	0x30($inp), @XMM[11]
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	0x40($inp), @XMM[12]
        +	pxor	@XMM[11], @XMM[2]
        +	movdqu	0x50($inp), @XMM[15]	# IV
        +	pxor	@XMM[12], @XMM[7]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	jmp	.Lcbc_dec_done
        +.align	16
        +.Lcbc_dec_five:
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +	call	_bsaes_decrypt8
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	0x20($inp), @XMM[10]
        +	pxor	@XMM[9], @XMM[6]
        +	movdqu	0x30($inp), @XMM[11]
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	0x40($inp), @XMM[15]	# IV
        +	pxor	@XMM[11], @XMM[2]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	jmp	.Lcbc_dec_done
        +.align	16
        +.Lcbc_dec_four:
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +	call	_bsaes_decrypt8
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	0x20($inp), @XMM[10]
        +	pxor	@XMM[9], @XMM[6]
        +	movdqu	0x30($inp), @XMM[15]	# IV
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	jmp	.Lcbc_dec_done
        +.align	16
        +.Lcbc_dec_three:
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +	call	_bsaes_decrypt8
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	0x20($inp), @XMM[15]	# IV
        +	pxor	@XMM[9], @XMM[6]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	jmp	.Lcbc_dec_done
        +.align	16
        +.Lcbc_dec_two:
        +	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
        +	call	_bsaes_decrypt8
        +	pxor	0x20(%rbp), @XMM[0]	# ^= IV
        +	movdqu	0x00($inp), @XMM[8]	# re-load input
        +	movdqu	0x10($inp), @XMM[15]	# IV
        +	pxor	@XMM[8], @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	jmp	.Lcbc_dec_done
        +.align	16
        +.Lcbc_dec_one:
        +	lea	($inp), $arg1
        +	lea	0x20(%rbp), $arg2	# buffer output
        +	lea	($key), $arg3
        +	call	asm_AES_decrypt		# doesn't touch %xmm
        +	pxor	0x20(%rbp), @XMM[15]	# ^= IV
        +	movdqu	@XMM[15], ($out)	# write output
        +	movdqa	@XMM[0], @XMM[15]	# IV
        +
        +.Lcbc_dec_done:
        +	movdqu	@XMM[15], (%rbx)	# return IV
        +	lea	(%rsp), %rax
        +	pxor	%xmm0, %xmm0
        +.Lcbc_dec_bzero:			# wipe key schedule [if any]
        +	movdqa	%xmm0, 0x00(%rax)
        +	movdqa	%xmm0, 0x10(%rax)
        +	lea	0x20(%rax), %rax
        +	cmp	%rax, %rbp
        +	ja	.Lcbc_dec_bzero
        +
        +	lea	(%rbp),%rsp		# restore %rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x40(%rbp), %xmm6
        +	movaps	0x50(%rbp), %xmm7
        +	movaps	0x60(%rbp), %xmm8
        +	movaps	0x70(%rbp), %xmm9
        +	movaps	0x80(%rbp), %xmm10
        +	movaps	0x90(%rbp), %xmm11
        +	movaps	0xa0(%rbp), %xmm12
        +	movaps	0xb0(%rbp), %xmm13
        +	movaps	0xc0(%rbp), %xmm14
        +	movaps	0xd0(%rbp), %xmm15
        +	lea	0xa0(%rbp), %rsp
        +___
        +$code.=<<___;
        +	mov	0x48(%rsp), %r15
        +	mov	0x50(%rsp), %r14
        +	mov	0x58(%rsp), %r13
        +	mov	0x60(%rsp), %r12
        +	mov	0x68(%rsp), %rbx
        +	mov	0x70(%rsp), %rax
        +	lea	0x78(%rsp), %rsp
        +	mov	%rax, %rbp
        +.Lcbc_dec_epilogue:
        +	ret
        +.size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
        +
        +.globl	bsaes_ctr32_encrypt_blocks
        +.type	bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
        +.align	16
        +bsaes_ctr32_encrypt_blocks:
        +	mov	%rsp, %rax
        +.Lctr_enc_prologue:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	-0x48(%rsp), %rsp
        +___
        +$code.=<<___ if ($win64);
        +	mov	0xa0(%rsp),$arg5	# pull ivp
        +	lea	-0xa0(%rsp), %rsp
        +	movaps	%xmm6, 0x40(%rsp)
        +	movaps	%xmm7, 0x50(%rsp)
        +	movaps	%xmm8, 0x60(%rsp)
        +	movaps	%xmm9, 0x70(%rsp)
        +	movaps	%xmm10, 0x80(%rsp)
        +	movaps	%xmm11, 0x90(%rsp)
        +	movaps	%xmm12, 0xa0(%rsp)
        +	movaps	%xmm13, 0xb0(%rsp)
        +	movaps	%xmm14, 0xc0(%rsp)
        +	movaps	%xmm15, 0xd0(%rsp)
        +.Lctr_enc_body:
        +___
        +$code.=<<___;
        +	mov	%rsp, %rbp		# backup %rsp
        +	movdqu	($arg5), %xmm0		# load counter
        +	mov	240($arg4), %eax	# rounds
        +	mov	$arg1, $inp		# backup arguments
        +	mov	$arg2, $out
        +	mov	$arg3, $len
        +	mov	$arg4, $key
        +	movdqa	%xmm0, 0x20(%rbp)	# copy counter
        +	cmp	\$8, $arg3
        +	jb	.Lctr_enc_short
        +
        +	mov	%eax, %ebx		# rounds
        +	shl	\$7, %rax		# 128 bytes per inner round key
        +	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
        +	sub	%rax, %rsp
        +
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	$key, %rcx		# pass key
        +	mov	%ebx, %r10d		# pass rounds
        +	call	_bsaes_key_convert
        +	pxor	%xmm6,%xmm7		# fix up last round key
        +	movdqa	%xmm7,(%rax)		# save last round key
        +
        +	movdqa	(%rsp), @XMM[9]		# load round0 key
        +	lea	.LADD1(%rip), %r11
        +	movdqa	0x20(%rbp), @XMM[0]	# counter copy
        +	movdqa	-0x20(%r11), @XMM[8]	# .LSWPUP
        +	pshufb	@XMM[8], @XMM[9]	# byte swap upper part
        +	pshufb	@XMM[8], @XMM[0]
        +	movdqa	@XMM[9], (%rsp)		# save adjusted round0 key
        +	jmp	.Lctr_enc_loop
        +.align	16
        +.Lctr_enc_loop:
        +	movdqa	@XMM[0], 0x20(%rbp)	# save counter
        +	movdqa	@XMM[0], @XMM[1]	# prepare 8 counter values
        +	movdqa	@XMM[0], @XMM[2]
        +	paddd	0x00(%r11), @XMM[1]	# .LADD1
        +	movdqa	@XMM[0], @XMM[3]
        +	paddd	0x10(%r11), @XMM[2]	# .LADD2
        +	movdqa	@XMM[0], @XMM[4]
        +	paddd	0x20(%r11), @XMM[3]	# .LADD3
        +	movdqa	@XMM[0], @XMM[5]
        +	paddd	0x30(%r11), @XMM[4]	# .LADD4
        +	movdqa	@XMM[0], @XMM[6]
        +	paddd	0x40(%r11), @XMM[5]	# .LADD5
        +	movdqa	@XMM[0], @XMM[7]
        +	paddd	0x50(%r11), @XMM[6]	# .LADD6
        +	paddd	0x60(%r11), @XMM[7]	# .LADD7
        +
        +	# Borrow prologue from _bsaes_encrypt8 to use the opportunity
        +	# to flip byte order in 32-bit counter
        +	movdqa	(%rsp), @XMM[9]		# round 0 key
        +	lea	0x10(%rsp), %rax	# pass key schedule
        +	movdqa	-0x10(%r11), @XMM[8]	# .LSWPUPM0SR
        +	pxor	@XMM[9], @XMM[0]	# xor with round0 key
        +	pxor	@XMM[9], @XMM[1]
        +	 pshufb	@XMM[8], @XMM[0]
        +	pxor	@XMM[9], @XMM[2]
        +	 pshufb	@XMM[8], @XMM[1]
        +	pxor	@XMM[9], @XMM[3]
        +	 pshufb	@XMM[8], @XMM[2]
        +	pxor	@XMM[9], @XMM[4]
        +	 pshufb	@XMM[8], @XMM[3]
        +	pxor	@XMM[9], @XMM[5]
        +	 pshufb	@XMM[8], @XMM[4]
        +	pxor	@XMM[9], @XMM[6]
        +	 pshufb	@XMM[8], @XMM[5]
        +	pxor	@XMM[9], @XMM[7]
        +	 pshufb	@XMM[8], @XMM[6]
        +	lea	.LBS0(%rip), %r11	# constants table
        +	 pshufb	@XMM[8], @XMM[7]
        +	mov	%ebx,%r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8_bitslice
        +
        +	sub	\$8,$len
        +	jc	.Lctr_enc_loop_done
        +
        +	movdqu	0x00($inp), @XMM[8]	# load input
        +	movdqu	0x10($inp), @XMM[9]
        +	movdqu	0x20($inp), @XMM[10]
        +	movdqu	0x30($inp), @XMM[11]
        +	movdqu	0x40($inp), @XMM[12]
        +	movdqu	0x50($inp), @XMM[13]
        +	movdqu	0x60($inp), @XMM[14]
        +	movdqu	0x70($inp), @XMM[15]
        +	lea	0x80($inp),$inp
        +	pxor	@XMM[0], @XMM[8]
        +	movdqa	0x20(%rbp), @XMM[0]	# load counter
        +	pxor	@XMM[9], @XMM[1]
        +	movdqu	@XMM[8], 0x00($out)	# write output
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	@XMM[11], @XMM[6]
        +	movdqu	@XMM[4], 0x20($out)
        +	pxor	@XMM[12], @XMM[3]
        +	movdqu	@XMM[6], 0x30($out)
        +	pxor	@XMM[13], @XMM[7]
        +	movdqu	@XMM[3], 0x40($out)
        +	pxor	@XMM[14], @XMM[2]
        +	movdqu	@XMM[7], 0x50($out)
        +	pxor	@XMM[15], @XMM[5]
        +	movdqu	@XMM[2], 0x60($out)
        +	lea	.LADD1(%rip), %r11
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +	paddd	0x70(%r11), @XMM[0]	# .LADD8
        +	jnz	.Lctr_enc_loop
        +
        +	jmp	.Lctr_enc_done
        +.align	16
        +.Lctr_enc_loop_done:
        +	add	\$8, $len
        +	movdqu	0x00($inp), @XMM[8]	# load input
        +	pxor	@XMM[8], @XMM[0]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	cmp	\$2,$len
        +	jb	.Lctr_enc_done
        +	movdqu	0x10($inp), @XMM[9]
        +	pxor	@XMM[9], @XMM[1]
        +	movdqu	@XMM[1], 0x10($out)
        +	je	.Lctr_enc_done
        +	movdqu	0x20($inp), @XMM[10]
        +	pxor	@XMM[10], @XMM[4]
        +	movdqu	@XMM[4], 0x20($out)
        +	cmp	\$4,$len
        +	jb	.Lctr_enc_done
        +	movdqu	0x30($inp), @XMM[11]
        +	pxor	@XMM[11], @XMM[6]
        +	movdqu	@XMM[6], 0x30($out)
        +	je	.Lctr_enc_done
        +	movdqu	0x40($inp), @XMM[12]
        +	pxor	@XMM[12], @XMM[3]
        +	movdqu	@XMM[3], 0x40($out)
        +	cmp	\$6,$len
        +	jb	.Lctr_enc_done
        +	movdqu	0x50($inp), @XMM[13]
        +	pxor	@XMM[13], @XMM[7]
        +	movdqu	@XMM[7], 0x50($out)
        +	je	.Lctr_enc_done
        +	movdqu	0x60($inp), @XMM[14]
        +	pxor	@XMM[14], @XMM[2]
        +	movdqu	@XMM[2], 0x60($out)
        +	jmp	.Lctr_enc_done
        +
        +.align	16
        +.Lctr_enc_short:
        +	lea	0x20(%rbp), $arg1
        +	lea	0x30(%rbp), $arg2
        +	lea	($key), $arg3
        +	call	asm_AES_encrypt
        +	movdqu	($inp), @XMM[1]
        +	lea	16($inp), $inp
        +	mov	0x2c(%rbp), %eax	# load 32-bit counter
        +	bswap	%eax
        +	pxor	0x30(%rbp), @XMM[1]
        +	inc	%eax			# increment
        +	movdqu	@XMM[1], ($out)
        +	bswap	%eax
        +	lea	16($out), $out
        +	mov	%eax, 0x2c(%rsp)	# save 32-bit counter
        +	dec	$len
        +	jnz	.Lctr_enc_short
        +
        +.Lctr_enc_done:
        +	lea	(%rsp), %rax
        +	pxor	%xmm0, %xmm0
        +.Lctr_enc_bzero:			# wipe key schedule [if any]
        +	movdqa	%xmm0, 0x00(%rax)
        +	movdqa	%xmm0, 0x10(%rax)
        +	lea	0x20(%rax), %rax
        +	cmp	%rax, %rbp
        +	ja	.Lctr_enc_bzero
        +
        +	lea	(%rbp),%rsp		# restore %rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x40(%rbp), %xmm6
        +	movaps	0x50(%rbp), %xmm7
        +	movaps	0x60(%rbp), %xmm8
        +	movaps	0x70(%rbp), %xmm9
        +	movaps	0x80(%rbp), %xmm10
        +	movaps	0x90(%rbp), %xmm11
        +	movaps	0xa0(%rbp), %xmm12
        +	movaps	0xb0(%rbp), %xmm13
        +	movaps	0xc0(%rbp), %xmm14
        +	movaps	0xd0(%rbp), %xmm15
        +	lea	0xa0(%rbp), %rsp
        +___
        +$code.=<<___;
        +	mov	0x48(%rsp), %r15
        +	mov	0x50(%rsp), %r14
        +	mov	0x58(%rsp), %r13
        +	mov	0x60(%rsp), %r12
        +	mov	0x68(%rsp), %rbx
        +	mov	0x70(%rsp), %rax
        +	lea	0x78(%rsp), %rsp
        +	mov	%rax, %rbp
        +.Lctr_enc_epilogue:
        +	ret
        +.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
        +___
        +######################################################################
        +# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
        +#	const AES_KEY *key1, const AES_KEY *key2,
        +#	const unsigned char iv[16]);
        +#
        +my ($twmask,$twres,$twtmp)=@XMM[13..15];
        +$code.=<<___;
        +.globl	bsaes_xts_encrypt
        +.type	bsaes_xts_encrypt,\@abi-omnipotent
        +.align	16
        +bsaes_xts_encrypt:
        +	mov	%rsp, %rax
        +.Lxts_enc_prologue:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	-0x48(%rsp), %rsp
        +___
        +$code.=<<___ if ($win64);
        +	mov	0xa0(%rsp),$arg5	# pull key2
        +	mov	0xa8(%rsp),$arg6	# pull ivp
        +	lea	-0xa0(%rsp), %rsp
        +	movaps	%xmm6, 0x40(%rsp)
        +	movaps	%xmm7, 0x50(%rsp)
        +	movaps	%xmm8, 0x60(%rsp)
        +	movaps	%xmm9, 0x70(%rsp)
        +	movaps	%xmm10, 0x80(%rsp)
        +	movaps	%xmm11, 0x90(%rsp)
        +	movaps	%xmm12, 0xa0(%rsp)
        +	movaps	%xmm13, 0xb0(%rsp)
        +	movaps	%xmm14, 0xc0(%rsp)
        +	movaps	%xmm15, 0xd0(%rsp)
        +.Lxts_enc_body:
        +___
        +$code.=<<___;
        +	mov	%rsp, %rbp		# backup %rsp
        +	mov	$arg1, $inp		# backup arguments
        +	mov	$arg2, $out
        +	mov	$arg3, $len
        +	mov	$arg4, $key
        +
        +	lea	($arg6), $arg1
        +	lea	0x20(%rbp), $arg2
        +	lea	($arg5), $arg3
        +	call	asm_AES_encrypt		# generate initial tweak
        +
        +	mov	240($key), %eax		# rounds
        +	mov	$len, %rbx		# backup $len
        +
        +	mov	%eax, %edx		# rounds
        +	shl	\$7, %rax		# 128 bytes per inner round key
        +	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
        +	sub	%rax, %rsp
        +
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	$key, %rcx		# pass key
        +	mov	%edx, %r10d		# pass rounds
        +	call	_bsaes_key_convert
        +	pxor	%xmm6, %xmm7		# fix up last round key
        +	movdqa	%xmm7, (%rax)		# save last round key
        +
        +	and	\$-16, $len
        +	sub	\$0x80, %rsp		# place for tweak[8]
        +	movdqa	0x20(%rbp), @XMM[7]	# initial tweak
        +
        +	pxor	$twtmp, $twtmp
        +	movdqa	.Lxts_magic(%rip), $twmask
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +
        +	sub	\$0x80, $len
        +	jc	.Lxts_enc_short
        +	jmp	.Lxts_enc_loop
        +
        +.align	16
        +.Lxts_enc_loop:
        +___
        +    for ($i=0;$i<7;$i++) {
        +    $code.=<<___;
        +	pshufd	\$0x13, $twtmp, $twres
        +	pxor	$twtmp, $twtmp
        +	movdqa	@XMM[7], @XMM[$i]
        +	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
        +	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +	pxor	$twres, @XMM[7]
        +___
        +    $code.=<<___ if ($i>=1);
        +	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
        +___
        +    $code.=<<___ if ($i>=2);
        +	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
        +___
        +    }
        +$code.=<<___;
        +	movdqu	0x60($inp), @XMM[8+6]
        +	pxor	@XMM[8+5], @XMM[5]
        +	movdqu	0x70($inp), @XMM[8+7]
        +	lea	0x80($inp), $inp
        +	movdqa	@XMM[7], 0x70(%rsp)
        +	pxor	@XMM[8+6], @XMM[6]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	pxor	@XMM[8+7], @XMM[7]
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[6]
        +	movdqu	@XMM[4], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[3]
        +	movdqu	@XMM[6], 0x30($out)
        +	pxor	0x50(%rsp), @XMM[7]
        +	movdqu	@XMM[3], 0x40($out)
        +	pxor	0x60(%rsp), @XMM[2]
        +	movdqu	@XMM[7], 0x50($out)
        +	pxor	0x70(%rsp), @XMM[5]
        +	movdqu	@XMM[2], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +
        +	movdqa	0x70(%rsp), @XMM[7]	# prepare next iteration tweak
        +	pxor	$twtmp, $twtmp
        +	movdqa	.Lxts_magic(%rip), $twmask
        +	pcmpgtd	@XMM[7], $twtmp
        +	pshufd	\$0x13, $twtmp, $twres
        +	pxor	$twtmp, $twtmp
        +	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +	pxor	$twres, @XMM[7]
        +
        +	sub	\$0x80,$len
        +	jnc	.Lxts_enc_loop
        +
        +.Lxts_enc_short:
        +	add	\$0x80, $len
        +	jz	.Lxts_enc_done
        +___
        +    for ($i=0;$i<7;$i++) {
        +    $code.=<<___;
        +	pshufd	\$0x13, $twtmp, $twres
        +	pxor	$twtmp, $twtmp
        +	movdqa	@XMM[7], @XMM[$i]
        +	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
        +	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +	pxor	$twres, @XMM[7]
        +___
        +    $code.=<<___ if ($i>=1);
        +	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
        +	cmp	\$`0x10*$i`,$len
        +	je	.Lxts_enc_$i
        +___
        +    $code.=<<___ if ($i>=2);
        +	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
        +___
        +    }
        +$code.=<<___;
        +	movdqu	0x60($inp), @XMM[8+6]
        +	pxor	@XMM[8+5], @XMM[5]
        +	movdqa	@XMM[7], 0x70(%rsp)
        +	lea	0x70($inp), $inp
        +	pxor	@XMM[8+6], @XMM[6]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[6]
        +	movdqu	@XMM[4], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[3]
        +	movdqu	@XMM[6], 0x30($out)
        +	pxor	0x50(%rsp), @XMM[7]
        +	movdqu	@XMM[3], 0x40($out)
        +	pxor	0x60(%rsp), @XMM[2]
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[2], 0x60($out)
        +	lea	0x70($out), $out
        +
        +	movdqa	0x70(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_enc_done
        +.align	16
        +.Lxts_enc_6:
        +	pxor	@XMM[8+4], @XMM[4]
        +	lea	0x60($inp), $inp
        +	pxor	@XMM[8+5], @XMM[5]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[6]
        +	movdqu	@XMM[4], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[3]
        +	movdqu	@XMM[6], 0x30($out)
        +	pxor	0x50(%rsp), @XMM[7]
        +	movdqu	@XMM[3], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	lea	0x60($out), $out
        +
        +	movdqa	0x60(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_enc_done
        +.align	16
        +.Lxts_enc_5:
        +	pxor	@XMM[8+3], @XMM[3]
        +	lea	0x50($inp), $inp
        +	pxor	@XMM[8+4], @XMM[4]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[6]
        +	movdqu	@XMM[4], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[3]
        +	movdqu	@XMM[6], 0x30($out)
        +	movdqu	@XMM[3], 0x40($out)
        +	lea	0x50($out), $out
        +
        +	movdqa	0x50(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_enc_done
        +.align	16
        +.Lxts_enc_4:
        +	pxor	@XMM[8+2], @XMM[2]
        +	lea	0x40($inp), $inp
        +	pxor	@XMM[8+3], @XMM[3]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[6]
        +	movdqu	@XMM[4], 0x20($out)
        +	movdqu	@XMM[6], 0x30($out)
        +	lea	0x40($out), $out
        +
        +	movdqa	0x40(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_enc_done
        +.align	16
        +.Lxts_enc_3:
        +	pxor	@XMM[8+1], @XMM[1]
        +	lea	0x30($inp), $inp
        +	pxor	@XMM[8+2], @XMM[2]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[4]
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[4], 0x20($out)
        +	lea	0x30($out), $out
        +
        +	movdqa	0x30(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_enc_done
        +.align	16
        +.Lxts_enc_2:
        +	pxor	@XMM[8+0], @XMM[0]
        +	lea	0x20($inp), $inp
        +	pxor	@XMM[8+1], @XMM[1]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_encrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	lea	0x20($out), $out
        +
        +	movdqa	0x20(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_enc_done
        +.align	16
        +.Lxts_enc_1:
        +	pxor	@XMM[0], @XMM[8]
        +	lea	0x10($inp), $inp
        +	movdqa	@XMM[8], 0x20(%rbp)
        +	lea	0x20(%rbp), $arg1
        +	lea	0x20(%rbp), $arg2
        +	lea	($key), $arg3
        +	call	asm_AES_encrypt		# doesn't touch %xmm
        +	pxor	0x20(%rbp), @XMM[0]	# ^= tweak[]
        +	#pxor	@XMM[8], @XMM[0]
        +	#lea	0x80(%rsp), %rax	# pass key schedule
        +	#mov	%edx, %r10d		# pass rounds
        +	#call	_bsaes_encrypt8
        +	#pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	lea	0x10($out), $out
        +
        +	movdqa	0x10(%rsp), @XMM[7]	# next iteration tweak
        +
        +.Lxts_enc_done:
        +	and	\$15, %ebx
        +	jz	.Lxts_enc_ret
        +	mov	$out, %rdx
        +
        +.Lxts_enc_steal:
        +	movzb	($inp), %eax
        +	movzb	-16(%rdx), %ecx
        +	lea	1($inp), $inp
        +	mov	%al, -16(%rdx)
        +	mov	%cl, 0(%rdx)
        +	lea	1(%rdx), %rdx
        +	sub	\$1,%ebx
        +	jnz	.Lxts_enc_steal
        +
        +	movdqu	-16($out), @XMM[0]
        +	lea	0x20(%rbp), $arg1
        +	pxor	@XMM[7], @XMM[0]
        +	lea	0x20(%rbp), $arg2
        +	movdqa	@XMM[0], 0x20(%rbp)
        +	lea	($key), $arg3
        +	call	asm_AES_encrypt		# doesn't touch %xmm
        +	pxor	0x20(%rbp), @XMM[7]
        +	movdqu	@XMM[7], -16($out)
        +
        +.Lxts_enc_ret:
        +	lea	(%rsp), %rax
        +	pxor	%xmm0, %xmm0
        +.Lxts_enc_bzero:			# wipe key schedule [if any]
        +	movdqa	%xmm0, 0x00(%rax)
        +	movdqa	%xmm0, 0x10(%rax)
        +	lea	0x20(%rax), %rax
        +	cmp	%rax, %rbp
        +	ja	.Lxts_enc_bzero
        +
        +	lea	(%rbp),%rsp		# restore %rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x40(%rbp), %xmm6
        +	movaps	0x50(%rbp), %xmm7
        +	movaps	0x60(%rbp), %xmm8
        +	movaps	0x70(%rbp), %xmm9
        +	movaps	0x80(%rbp), %xmm10
        +	movaps	0x90(%rbp), %xmm11
        +	movaps	0xa0(%rbp), %xmm12
        +	movaps	0xb0(%rbp), %xmm13
        +	movaps	0xc0(%rbp), %xmm14
        +	movaps	0xd0(%rbp), %xmm15
        +	lea	0xa0(%rbp), %rsp
        +___
        +$code.=<<___;
        +	mov	0x48(%rsp), %r15
        +	mov	0x50(%rsp), %r14
        +	mov	0x58(%rsp), %r13
        +	mov	0x60(%rsp), %r12
        +	mov	0x68(%rsp), %rbx
        +	mov	0x70(%rsp), %rax
        +	lea	0x78(%rsp), %rsp
        +	mov	%rax, %rbp
        +.Lxts_enc_epilogue:
        +	ret
        +.size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
        +
        +.globl	bsaes_xts_decrypt
        +.type	bsaes_xts_decrypt,\@abi-omnipotent
        +.align	16
        +bsaes_xts_decrypt:
        +	mov	%rsp, %rax
        +.Lxts_dec_prologue:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	lea	-0x48(%rsp), %rsp
        +___
        +$code.=<<___ if ($win64);
        +	mov	0xa0(%rsp),$arg5	# pull key2
        +	mov	0xa8(%rsp),$arg6	# pull ivp
        +	lea	-0xa0(%rsp), %rsp
        +	movaps	%xmm6, 0x40(%rsp)
        +	movaps	%xmm7, 0x50(%rsp)
        +	movaps	%xmm8, 0x60(%rsp)
        +	movaps	%xmm9, 0x70(%rsp)
        +	movaps	%xmm10, 0x80(%rsp)
        +	movaps	%xmm11, 0x90(%rsp)
        +	movaps	%xmm12, 0xa0(%rsp)
        +	movaps	%xmm13, 0xb0(%rsp)
        +	movaps	%xmm14, 0xc0(%rsp)
        +	movaps	%xmm15, 0xd0(%rsp)
        +.Lxts_dec_body:
        +___
        +$code.=<<___;
        +	mov	%rsp, %rbp		# backup %rsp
        +	mov	$arg1, $inp		# backup arguments
        +	mov	$arg2, $out
        +	mov	$arg3, $len
        +	mov	$arg4, $key
        +
        +	lea	($arg6), $arg1
        +	lea	0x20(%rbp), $arg2
        +	lea	($arg5), $arg3
        +	call	asm_AES_encrypt		# generate initial tweak
        +
        +	mov	240($key), %eax		# rounds
        +	mov	$len, %rbx		# backup $len
        +
        +	mov	%eax, %edx		# rounds
        +	shl	\$7, %rax		# 128 bytes per inner round key
        +	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
        +	sub	%rax, %rsp
        +
        +	mov	%rsp, %rax		# pass key schedule
        +	mov	$key, %rcx		# pass key
        +	mov	%edx, %r10d		# pass rounds
        +	call	_bsaes_key_convert
        +	pxor	(%rsp), %xmm7		# fix up round 0 key
        +	movdqa	%xmm6, (%rax)		# save last round key
        +	movdqa	%xmm7, (%rsp)
        +
        +	xor	%eax, %eax		# if ($len%16) len-=16;
        +	and	\$-16, $len
        +	test	\$15, %ebx
        +	setnz	%al
        +	shl	\$4, %rax
        +	sub	%rax, $len
        +
        +	sub	\$0x80, %rsp		# place for tweak[8]
        +	movdqa	0x20(%rbp), @XMM[7]	# initial tweak
        +
        +	pxor	$twtmp, $twtmp
        +	movdqa	.Lxts_magic(%rip), $twmask
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +
        +	sub	\$0x80, $len
        +	jc	.Lxts_dec_short
        +	jmp	.Lxts_dec_loop
        +
        +.align	16
        +.Lxts_dec_loop:
        +___
        +    for ($i=0;$i<7;$i++) {
        +    $code.=<<___;
        +	pshufd	\$0x13, $twtmp, $twres
        +	pxor	$twtmp, $twtmp
        +	movdqa	@XMM[7], @XMM[$i]
        +	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
        +	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +	pxor	$twres, @XMM[7]
        +___
        +    $code.=<<___ if ($i>=1);
        +	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
        +___
        +    $code.=<<___ if ($i>=2);
        +	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
        +___
        +    }
        +$code.=<<___;
        +	movdqu	0x60($inp), @XMM[8+6]
        +	pxor	@XMM[8+5], @XMM[5]
        +	movdqu	0x70($inp), @XMM[8+7]
        +	lea	0x80($inp), $inp
        +	movdqa	@XMM[7], 0x70(%rsp)
        +	pxor	@XMM[8+6], @XMM[6]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	pxor	@XMM[8+7], @XMM[7]
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[6]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[4]
        +	movdqu	@XMM[6], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[2]
        +	movdqu	@XMM[4], 0x30($out)
        +	pxor	0x50(%rsp), @XMM[7]
        +	movdqu	@XMM[2], 0x40($out)
        +	pxor	0x60(%rsp), @XMM[3]
        +	movdqu	@XMM[7], 0x50($out)
        +	pxor	0x70(%rsp), @XMM[5]
        +	movdqu	@XMM[3], 0x60($out)
        +	movdqu	@XMM[5], 0x70($out)
        +	lea	0x80($out), $out
        +
        +	movdqa	0x70(%rsp), @XMM[7]	# prepare next iteration tweak
        +	pxor	$twtmp, $twtmp
        +	movdqa	.Lxts_magic(%rip), $twmask
        +	pcmpgtd	@XMM[7], $twtmp
        +	pshufd	\$0x13, $twtmp, $twres
        +	pxor	$twtmp, $twtmp
        +	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +	pxor	$twres, @XMM[7]
        +
        +	sub	\$0x80,$len
        +	jnc	.Lxts_dec_loop
        +
        +.Lxts_dec_short:
        +	add	\$0x80, $len
        +	jz	.Lxts_dec_done
        +___
        +    for ($i=0;$i<7;$i++) {
        +    $code.=<<___;
        +	pshufd	\$0x13, $twtmp, $twres
        +	pxor	$twtmp, $twtmp
        +	movdqa	@XMM[7], @XMM[$i]
        +	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
        +	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
        +	pxor	$twres, @XMM[7]
        +___
        +    $code.=<<___ if ($i>=1);
        +	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
        +	cmp	\$`0x10*$i`,$len
        +	je	.Lxts_dec_$i
        +___
        +    $code.=<<___ if ($i>=2);
        +	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
        +___
        +    }
        +$code.=<<___;
        +	movdqu	0x60($inp), @XMM[8+6]
        +	pxor	@XMM[8+5], @XMM[5]
        +	movdqa	@XMM[7], 0x70(%rsp)
        +	lea	0x70($inp), $inp
        +	pxor	@XMM[8+6], @XMM[6]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[6]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[4]
        +	movdqu	@XMM[6], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[2]
        +	movdqu	@XMM[4], 0x30($out)
        +	pxor	0x50(%rsp), @XMM[7]
        +	movdqu	@XMM[2], 0x40($out)
        +	pxor	0x60(%rsp), @XMM[3]
        +	movdqu	@XMM[7], 0x50($out)
        +	movdqu	@XMM[3], 0x60($out)
        +	lea	0x70($out), $out
        +
        +	movdqa	0x70(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_dec_done
        +.align	16
        +.Lxts_dec_6:
        +	pxor	@XMM[8+4], @XMM[4]
        +	lea	0x60($inp), $inp
        +	pxor	@XMM[8+5], @XMM[5]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[6]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[4]
        +	movdqu	@XMM[6], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[2]
        +	movdqu	@XMM[4], 0x30($out)
        +	pxor	0x50(%rsp), @XMM[7]
        +	movdqu	@XMM[2], 0x40($out)
        +	movdqu	@XMM[7], 0x50($out)
        +	lea	0x60($out), $out
        +
        +	movdqa	0x60(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_dec_done
        +.align	16
        +.Lxts_dec_5:
        +	pxor	@XMM[8+3], @XMM[3]
        +	lea	0x50($inp), $inp
        +	pxor	@XMM[8+4], @XMM[4]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[6]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[4]
        +	movdqu	@XMM[6], 0x20($out)
        +	pxor	0x40(%rsp), @XMM[2]
        +	movdqu	@XMM[4], 0x30($out)
        +	movdqu	@XMM[2], 0x40($out)
        +	lea	0x50($out), $out
        +
        +	movdqa	0x50(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_dec_done
        +.align	16
        +.Lxts_dec_4:
        +	pxor	@XMM[8+2], @XMM[2]
        +	lea	0x40($inp), $inp
        +	pxor	@XMM[8+3], @XMM[3]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[6]
        +	movdqu	@XMM[1], 0x10($out)
        +	pxor	0x30(%rsp), @XMM[4]
        +	movdqu	@XMM[6], 0x20($out)
        +	movdqu	@XMM[4], 0x30($out)
        +	lea	0x40($out), $out
        +
        +	movdqa	0x40(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_dec_done
        +.align	16
        +.Lxts_dec_3:
        +	pxor	@XMM[8+1], @XMM[1]
        +	lea	0x30($inp), $inp
        +	pxor	@XMM[8+2], @XMM[2]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	pxor	0x20(%rsp), @XMM[6]
        +	movdqu	@XMM[1], 0x10($out)
        +	movdqu	@XMM[6], 0x20($out)
        +	lea	0x30($out), $out
        +
        +	movdqa	0x30(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_dec_done
        +.align	16
        +.Lxts_dec_2:
        +	pxor	@XMM[8+0], @XMM[0]
        +	lea	0x20($inp), $inp
        +	pxor	@XMM[8+1], @XMM[1]
        +	lea	0x80(%rsp), %rax	# pass key schedule
        +	mov	%edx, %r10d		# pass rounds
        +
        +	call	_bsaes_decrypt8
        +
        +	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	pxor	0x10(%rsp), @XMM[1]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	movdqu	@XMM[1], 0x10($out)
        +	lea	0x20($out), $out
        +
        +	movdqa	0x20(%rsp), @XMM[7]	# next iteration tweak
        +	jmp	.Lxts_dec_done
        +.align	16
        +.Lxts_dec_1:
        +	pxor	@XMM[0], @XMM[8]
        +	lea	0x10($inp), $inp
        +	movdqa	@XMM[8], 0x20(%rbp)
        +	lea	0x20(%rbp), $arg1
        +	lea	0x20(%rbp), $arg2
        +	lea	($key), $arg3
        +	call	asm_AES_decrypt		# doesn't touch %xmm
        +	pxor	0x20(%rbp), @XMM[0]	# ^= tweak[]
        +	#pxor	@XMM[8], @XMM[0]
        +	#lea	0x80(%rsp), %rax	# pass key schedule
        +	#mov	%edx, %r10d		# pass rounds
        +	#call	_bsaes_decrypt8
        +	#pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
        +	movdqu	@XMM[0], 0x00($out)	# write output
        +	lea	0x10($out), $out
        +
        +	movdqa	0x10(%rsp), @XMM[7]	# next iteration tweak
        +
        +.Lxts_dec_done:
        +	and	\$15, %ebx
        +	jz	.Lxts_dec_ret
        +
        +	pxor	$twtmp, $twtmp
        +	movdqa	.Lxts_magic(%rip), $twmask
        +	pcmpgtd	@XMM[7], $twtmp
        +	pshufd	\$0x13, $twtmp, $twres
        +	movdqa	@XMM[7], @XMM[6]
        +	paddq	@XMM[7], @XMM[7]	# psllq 1,$tweak
        +	pand	$twmask, $twres		# isolate carry and residue
        +	movdqu	($inp), @XMM[0]
        +	pxor	$twres, @XMM[7]
        +
        +	lea	0x20(%rbp), $arg1
        +	pxor	@XMM[7], @XMM[0]
        +	lea	0x20(%rbp), $arg2
        +	movdqa	@XMM[0], 0x20(%rbp)
        +	lea	($key), $arg3
        +	call	asm_AES_decrypt		# doesn't touch %xmm
        +	pxor	0x20(%rbp), @XMM[7]
        +	mov	$out, %rdx
        +	movdqu	@XMM[7], ($out)
        +
        +.Lxts_dec_steal:
        +	movzb	16($inp), %eax
        +	movzb	(%rdx), %ecx
        +	lea	1($inp), $inp
        +	mov	%al, (%rdx)
        +	mov	%cl, 16(%rdx)
        +	lea	1(%rdx), %rdx
        +	sub	\$1,%ebx
        +	jnz	.Lxts_dec_steal
        +
        +	movdqu	($out), @XMM[0]
        +	lea	0x20(%rbp), $arg1
        +	pxor	@XMM[6], @XMM[0]
        +	lea	0x20(%rbp), $arg2
        +	movdqa	@XMM[0], 0x20(%rbp)
        +	lea	($key), $arg3
        +	call	asm_AES_decrypt		# doesn't touch %xmm
        +	pxor	0x20(%rbp), @XMM[6]
        +	movdqu	@XMM[6], ($out)
        +
        +.Lxts_dec_ret:
        +	lea	(%rsp), %rax
        +	pxor	%xmm0, %xmm0
        +.Lxts_dec_bzero:			# wipe key schedule [if any]
        +	movdqa	%xmm0, 0x00(%rax)
        +	movdqa	%xmm0, 0x10(%rax)
        +	lea	0x20(%rax), %rax
        +	cmp	%rax, %rbp
        +	ja	.Lxts_dec_bzero
        +
        +	lea	(%rbp),%rsp		# restore %rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x40(%rbp), %xmm6
        +	movaps	0x50(%rbp), %xmm7
        +	movaps	0x60(%rbp), %xmm8
        +	movaps	0x70(%rbp), %xmm9
        +	movaps	0x80(%rbp), %xmm10
        +	movaps	0x90(%rbp), %xmm11
        +	movaps	0xa0(%rbp), %xmm12
        +	movaps	0xb0(%rbp), %xmm13
        +	movaps	0xc0(%rbp), %xmm14
        +	movaps	0xd0(%rbp), %xmm15
        +	lea	0xa0(%rbp), %rsp
        +___
        +$code.=<<___;
        +	mov	0x48(%rsp), %r15
        +	mov	0x50(%rsp), %r14
        +	mov	0x58(%rsp), %r13
        +	mov	0x60(%rsp), %r12
        +	mov	0x68(%rsp), %rbx
        +	mov	0x70(%rsp), %rax
        +	lea	0x78(%rsp), %rsp
        +	mov	%rax, %rbp
        +.Lxts_dec_epilogue:
        +	ret
        +.size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
        +___
        +}
        +$code.=<<___;
        +.type	_bsaes_const,\@object
        +.align	64
        +_bsaes_const:
        +.LM0ISR:	# InvShiftRows constants
        +	.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
        +.LISRM0:
        +	.quad	0x01040b0e0205080f, 0x0306090c00070a0d
        +.LISR:
        +	.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
        +.LBS0:		# bit-slice constants
        +	.quad	0x5555555555555555, 0x5555555555555555
        +.LBS1:
        +	.quad	0x3333333333333333, 0x3333333333333333
        +.LBS2:
        +	.quad	0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
        +.LSR:		# shiftrows constants
        +	.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
        +.LSRM0:
        +	.quad	0x0304090e00050a0f, 0x01060b0c0207080d
        +.LM0SR:
        +	.quad	0x0a0e02060f03070b, 0x0004080c05090d01
        +.LSWPUP:	# byte-swap upper dword
        +	.quad	0x0706050403020100, 0x0c0d0e0f0b0a0908
        +.LSWPUPM0SR:
        +	.quad	0x0a0d02060c03070b, 0x0004080f05090e01
        +.LADD1:		# counter increment constants
        +	.quad	0x0000000000000000, 0x0000000100000000
        +.LADD2:
        +	.quad	0x0000000000000000, 0x0000000200000000
        +.LADD3:
        +	.quad	0x0000000000000000, 0x0000000300000000
        +.LADD4:
        +	.quad	0x0000000000000000, 0x0000000400000000
        +.LADD5:
        +	.quad	0x0000000000000000, 0x0000000500000000
        +.LADD6:
        +	.quad	0x0000000000000000, 0x0000000600000000
        +.LADD7:
        +	.quad	0x0000000000000000, 0x0000000700000000
        +.LADD8:
        +	.quad	0x0000000000000000, 0x0000000800000000
        +.Lxts_magic:
        +	.long	0x87,0,1,0
        +.Lmasks:
        +	.quad	0x0101010101010101, 0x0101010101010101
        +	.quad	0x0202020202020202, 0x0202020202020202
        +	.quad	0x0404040404040404, 0x0404040404040404
        +	.quad	0x0808080808080808, 0x0808080808080808
        +.LM0:
        +	.quad	0x02060a0e03070b0f, 0x0004080c0105090d
        +.L63:
        +	.quad	0x6363636363636363, 0x6363636363636363
        +.asciz	"Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov"
        +.align	64
        +.size	_bsaes_const,.-_bsaes_const
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_prologue
        +
        +	mov	160($context),%rax	# pull context->Rbp
        +
        +	lea	0x40(%rax),%rsi		# %xmm save area
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	0xa0(%rax),%rax		# adjust stack pointer
        +
        +	mov	0x70(%rax),%rbp
        +	mov	0x68(%rax),%rbx
        +	mov	0x60(%rax),%r12
        +	mov	0x58(%rax),%r13
        +	mov	0x50(%rax),%r14
        +	mov	0x48(%rax),%r15
        +	lea	0x78(%rax),%rax		# adjust stack pointer
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	%rax,152($context)	# restore context->Rsp
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +___
        +$code.=<<___ if ($ecb);
        +	.rva	.Lecb_enc_prologue
        +	.rva	.Lecb_enc_epilogue
        +	.rva	.Lecb_enc_info
        +
        +	.rva	.Lecb_dec_prologue
        +	.rva	.Lecb_dec_epilogue
        +	.rva	.Lecb_dec_info
        +___
        +$code.=<<___;
        +	.rva	.Lcbc_dec_prologue
        +	.rva	.Lcbc_dec_epilogue
        +	.rva	.Lcbc_dec_info
        +
        +	.rva	.Lctr_enc_prologue
        +	.rva	.Lctr_enc_epilogue
        +	.rva	.Lctr_enc_info
        +
        +	.rva	.Lxts_enc_prologue
        +	.rva	.Lxts_enc_epilogue
        +	.rva	.Lxts_enc_info
        +
        +	.rva	.Lxts_dec_prologue
        +	.rva	.Lxts_dec_epilogue
        +	.rva	.Lxts_dec_info
        +
        +.section	.xdata
        +.align	8
        +___
        +$code.=<<___ if ($ecb);
        +.Lecb_enc_info:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lecb_enc_body,.Lecb_enc_epilogue	# HandlerData[]
        +.Lecb_dec_info:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lecb_dec_body,.Lecb_dec_epilogue	# HandlerData[]
        +___
        +$code.=<<___;
        +.Lcbc_dec_info:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lcbc_dec_body,.Lcbc_dec_epilogue	# HandlerData[]
        +.Lctr_enc_info:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lctr_enc_body,.Lctr_enc_epilogue	# HandlerData[]
        +.Lxts_enc_info:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lxts_enc_body,.Lxts_enc_epilogue	# HandlerData[]
        +.Lxts_dec_info:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lxts_dec_body,.Lxts_dec_epilogue	# HandlerData[]
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/vpaes-x86.pl b/vendor/openssl/openssl/crypto/aes/asm/vpaes-x86.pl
        new file mode 100644
        index 000000000..1533e2c30
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/vpaes-x86.pl
        @@ -0,0 +1,903 @@
        +#!/usr/bin/env perl
        +
        +######################################################################
        +## Constant-time SSSE3 AES core implementation.
        +## version 0.1
        +##
        +## By Mike Hamburg (Stanford University), 2009
        +## Public domain.
        +##
        +## For details see http://shiftleft.org/papers/vector_aes/ and
        +## http://crypto.stanford.edu/vpaes/.
        +
        +######################################################################
        +# September 2011.
        +#
        +# Port vpaes-x86_64.pl as 32-bit "almost" drop-in replacement for
        +# aes-586.pl. "Almost" refers to the fact that AES_cbc_encrypt
        +# doesn't handle partial vectors (doesn't have to if called from
        +# EVP only). "Drop-in" implies that this module doesn't share key
        +# schedule structure with the original nor does it make assumption
        +# about its alignment...
        +#
        +# Performance summary. aes-586.pl column lists large-block CBC
        +# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per
        +# byte processed with 128-bit key, and vpaes-x86.pl column - [also
        +# large-block CBC] encrypt/decrypt.
        +#
        +#		aes-586.pl		vpaes-x86.pl
        +#
        +# Core 2(**)	29.1/42.3/18.3		22.0/25.6(***)
        +# Nehalem	27.9/40.4/18.1		10.3/12.0
        +# Atom		102./119./60.1		64.5/85.3(***)
        +#
        +# (*)	"Hyper-threading" in the context refers rather to cache shared
        +#	among multiple cores, than to specifically Intel HTT. As vast
        +#	majority of contemporary cores share cache, slower code path
        +#	is common place. In other words "with-hyper-threading-off"
        +#	results are presented mostly for reference purposes.
        +#
        +# (**)	"Core 2" refers to initial 65nm design, a.k.a. Conroe.
        +#
        +# (***)	Less impressive improvement on Core 2 and Atom is due to slow
        +#	pshufb,	yet it's respectable +32%/65%  improvement on Core 2
        +#	and +58%/40% on Atom (as implied, over "hyper-threading-safe"
        +#	code path).
        +#
        +#						<appro@openssl.org>
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"vpaes-x86.pl",$x86only = $ARGV[$#ARGV] eq "386");
        +
        +$PREFIX="vpaes";
        +
        +my  ($round, $base, $magic, $key, $const, $inp, $out)=
        +    ("eax",  "ebx", "ecx",  "edx","ebp",  "esi","edi");
        +
        +&static_label("_vpaes_consts");
        +&static_label("_vpaes_schedule_low_round");
        +
        +&set_label("_vpaes_consts",64);
        +$k_inv=-0x30;		# inv, inva
        +	&data_word(0x0D080180,0x0E05060F,0x0A0B0C02,0x04070309);
        +	&data_word(0x0F0B0780,0x01040A06,0x02050809,0x030D0E0C);
        +
        +$k_s0F=-0x10;		# s0F
        +	&data_word(0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F);
        +
        +$k_ipt=0x00;		# input transform (lo, hi)
        +	&data_word(0x5A2A7000,0xC2B2E898,0x52227808,0xCABAE090);
        +	&data_word(0x317C4D00,0x4C01307D,0xB0FDCC81,0xCD80B1FC);
        +
        +$k_sb1=0x20;		# sb1u, sb1t
        +	&data_word(0xCB503E00,0xB19BE18F,0x142AF544,0xA5DF7A6E);
        +	&data_word(0xFAE22300,0x3618D415,0x0D2ED9EF,0x3BF7CCC1);
        +$k_sb2=0x40;		# sb2u, sb2t
        +	&data_word(0x0B712400,0xE27A93C6,0xBC982FCD,0x5EB7E955);
        +	&data_word(0x0AE12900,0x69EB8840,0xAB82234A,0xC2A163C8);
        +$k_sbo=0x60;		# sbou, sbot
        +	&data_word(0x6FBDC700,0xD0D26D17,0xC502A878,0x15AABF7A);
        +	&data_word(0x5FBB6A00,0xCFE474A5,0x412B35FA,0x8E1E90D1);
        +
        +$k_mc_forward=0x80;	# mc_forward
        +	&data_word(0x00030201,0x04070605,0x080B0A09,0x0C0F0E0D);
        +	&data_word(0x04070605,0x080B0A09,0x0C0F0E0D,0x00030201);
        +	&data_word(0x080B0A09,0x0C0F0E0D,0x00030201,0x04070605);
        +	&data_word(0x0C0F0E0D,0x00030201,0x04070605,0x080B0A09);
        +
        +$k_mc_backward=0xc0;	# mc_backward
        +	&data_word(0x02010003,0x06050407,0x0A09080B,0x0E0D0C0F);
        +	&data_word(0x0E0D0C0F,0x02010003,0x06050407,0x0A09080B);
        +	&data_word(0x0A09080B,0x0E0D0C0F,0x02010003,0x06050407);
        +	&data_word(0x06050407,0x0A09080B,0x0E0D0C0F,0x02010003);
        +
        +$k_sr=0x100;		# sr
        +	&data_word(0x03020100,0x07060504,0x0B0A0908,0x0F0E0D0C);
        +	&data_word(0x0F0A0500,0x030E0904,0x07020D08,0x0B06010C);
        +	&data_word(0x0B020900,0x0F060D04,0x030A0108,0x070E050C);
        +	&data_word(0x070A0D00,0x0B0E0104,0x0F020508,0x0306090C);
        +
        +$k_rcon=0x140;		# rcon
        +	&data_word(0xAF9DEEB6,0x1F8391B9,0x4D7C7D81,0x702A9808);
        +
        +$k_s63=0x150;		# s63: all equal to 0x63 transformed
        +	&data_word(0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B);
        +
        +$k_opt=0x160;		# output transform
        +	&data_word(0xD6B66000,0xFF9F4929,0xDEBE6808,0xF7974121);
        +	&data_word(0x50BCEC00,0x01EDBD51,0xB05C0CE0,0xE10D5DB1);
        +
        +$k_deskew=0x180;	# deskew tables: inverts the sbox's "skew"
        +	&data_word(0x47A4E300,0x07E4A340,0x5DBEF91A,0x1DFEB95A);
        +	&data_word(0x83EA6900,0x5F36B5DC,0xF49D1E77,0x2841C2AB);
        +##
        +##  Decryption stuff
        +##  Key schedule constants
        +##
        +$k_dksd=0x1a0;		# decryption key schedule: invskew x*D
        +	&data_word(0xA3E44700,0xFEB91A5D,0x5A1DBEF9,0x0740E3A4);
        +	&data_word(0xB5368300,0x41C277F4,0xAB289D1E,0x5FDC69EA);
        +$k_dksb=0x1c0;		# decryption key schedule: invskew x*B
        +	&data_word(0x8550D500,0x9A4FCA1F,0x1CC94C99,0x03D65386);
        +	&data_word(0xB6FC4A00,0x115BEDA7,0x7E3482C8,0xD993256F);
        +$k_dkse=0x1e0;		# decryption key schedule: invskew x*E + 0x63
        +	&data_word(0x1FC9D600,0xD5031CCA,0x994F5086,0x53859A4C);
        +	&data_word(0x4FDC7BE8,0xA2319605,0x20B31487,0xCD5EF96A);
        +$k_dks9=0x200;		# decryption key schedule: invskew x*9
        +	&data_word(0x7ED9A700,0xB6116FC8,0x82255BFC,0x4AED9334);
        +	&data_word(0x27143300,0x45765162,0xE9DAFDCE,0x8BB89FAC);
        +
        +##
        +##  Decryption stuff
        +##  Round function constants
        +##
        +$k_dipt=0x220;		# decryption input transform
        +	&data_word(0x0B545F00,0x0F505B04,0x114E451A,0x154A411E);
        +	&data_word(0x60056500,0x86E383E6,0xF491F194,0x12771772);
        +
        +$k_dsb9=0x240;		# decryption sbox output *9*u, *9*t
        +	&data_word(0x9A86D600,0x851C0353,0x4F994CC9,0xCAD51F50);
        +	&data_word(0xECD74900,0xC03B1789,0xB2FBA565,0x725E2C9E);
        +$k_dsbd=0x260;		# decryption sbox output *D*u, *D*t
        +	&data_word(0xE6B1A200,0x7D57CCDF,0x882A4439,0xF56E9B13);
        +	&data_word(0x24C6CB00,0x3CE2FAF7,0x15DEEFD3,0x2931180D);
        +$k_dsbb=0x280;		# decryption sbox output *B*u, *B*t
        +	&data_word(0x96B44200,0xD0226492,0xB0F2D404,0x602646F6);
        +	&data_word(0xCD596700,0xC19498A6,0x3255AA6B,0xF3FF0C3E);
        +$k_dsbe=0x2a0;		# decryption sbox output *E*u, *E*t
        +	&data_word(0x26D4D000,0x46F29296,0x64B4F6B0,0x22426004);
        +	&data_word(0xFFAAC100,0x0C55A6CD,0x98593E32,0x9467F36B);
        +$k_dsbo=0x2c0;		# decryption sbox final output
        +	&data_word(0x7EF94000,0x1387EA53,0xD4943E2D,0xC7AA6DB9);
        +	&data_word(0x93441D00,0x12D7560F,0xD8C58E9C,0xCA4B8159);
        +&asciz	("Vector Permutation AES for x86/SSSE3, Mike Hamburg (Stanford University)");
        +&align	(64);
        +
        +&function_begin_B("_vpaes_preheat");
        +	&add	($const,&DWP(0,"esp"));
        +	&movdqa	("xmm7",&QWP($k_inv,$const));
        +	&movdqa	("xmm6",&QWP($k_s0F,$const));
        +	&ret	();
        +&function_end_B("_vpaes_preheat");
        +
        +##
        +##  _aes_encrypt_core
        +##
        +##  AES-encrypt %xmm0.
        +##
        +##  Inputs:
        +##     %xmm0 = input
        +##     %xmm6-%xmm7 as in _vpaes_preheat
        +##    (%edx) = scheduled keys
        +##
        +##  Output in %xmm0
        +##  Clobbers  %xmm1-%xmm5, %eax, %ebx, %ecx, %edx
        +##
        +##
        +&function_begin_B("_vpaes_encrypt_core");
        +	&mov	($magic,16);
        +	&mov	($round,&DWP(240,$key));
        +	&movdqa	("xmm1","xmm6")
        +	&movdqa	("xmm2",&QWP($k_ipt,$const));
        +	&pandn	("xmm1","xmm0");
        +	&movdqu	("xmm5",&QWP(0,$key));
        +	&psrld	("xmm1",4);
        +	&pand	("xmm0","xmm6");
        +	&pshufb	("xmm2","xmm0");
        +	&movdqa	("xmm0",&QWP($k_ipt+16,$const));
        +	&pshufb	("xmm0","xmm1");
        +	&pxor	("xmm2","xmm5");
        +	&pxor	("xmm0","xmm2");
        +	&add	($key,16);
        +	&lea	($base,&DWP($k_mc_backward,$const));
        +	&jmp	(&label("enc_entry"));
        +
        +
        +&set_label("enc_loop",16);
        +	# middle of middle round
        +	&movdqa	("xmm4",&QWP($k_sb1,$const));	# 4 : sb1u
        +	&pshufb	("xmm4","xmm2");		# 4 = sb1u
        +	&pxor	("xmm4","xmm5");		# 4 = sb1u + k
        +	&movdqa	("xmm0",&QWP($k_sb1+16,$const));# 0 : sb1t
        +	&pshufb	("xmm0","xmm3");		# 0 = sb1t
        +	&pxor	("xmm0","xmm4");		# 0 = A
        +	&movdqa	("xmm5",&QWP($k_sb2,$const));	# 4 : sb2u
        +	&pshufb	("xmm5","xmm2");		# 4 = sb2u
        +	&movdqa	("xmm1",&QWP(-0x40,$base,$magic));# .Lk_mc_forward[]
        +	&movdqa	("xmm2",&QWP($k_sb2+16,$const));# 2 : sb2t
        +	&pshufb	("xmm2","xmm3");		# 2 = sb2t
        +	&pxor	("xmm2","xmm5");		# 2 = 2A
        +	&movdqa	("xmm4",&QWP(0,$base,$magic));	# .Lk_mc_backward[]
        +	&movdqa	("xmm3","xmm0");		# 3 = A
        +	&pshufb	("xmm0","xmm1");		# 0 = B
        +	&add	($key,16);			# next key
        +	&pxor	("xmm0","xmm2");		# 0 = 2A+B
        +	&pshufb	("xmm3","xmm4");		# 3 = D
        +	&add	($magic,16);			# next mc
        +	&pxor	("xmm3","xmm0");		# 3 = 2A+B+D
        +	&pshufb	("xmm0","xmm1");		# 0 = 2B+C
        +	&and	($magic,0x30);			# ... mod 4
        +	&pxor	("xmm0","xmm3");		# 0 = 2A+3B+C+D
        +	&sub	($round,1);			# nr--
        +
        +&set_label("enc_entry");
        +	# top of round
        +	&movdqa	("xmm1","xmm6");		# 1 : i
        +	&pandn	("xmm1","xmm0");		# 1 = i<<4
        +	&psrld	("xmm1",4);			# 1 = i
        +	&pand	("xmm0","xmm6");		# 0 = k
        +	&movdqa	("xmm5",&QWP($k_inv+16,$const));# 2 : a/k
        +	&pshufb	("xmm5","xmm0");		# 2 = a/k
        +	&pxor	("xmm0","xmm1");		# 0 = j
        +	&movdqa	("xmm3","xmm7");		# 3 : 1/i
        +	&pshufb	("xmm3","xmm1");		# 3 = 1/i
        +	&pxor	("xmm3","xmm5");		# 3 = iak = 1/i + a/k
        +	&movdqa	("xmm4","xmm7");		# 4 : 1/j
        +	&pshufb	("xmm4","xmm0");		# 4 = 1/j
        +	&pxor	("xmm4","xmm5");		# 4 = jak = 1/j + a/k
        +	&movdqa	("xmm2","xmm7");		# 2 : 1/iak
        +	&pshufb	("xmm2","xmm3");		# 2 = 1/iak
        +	&pxor	("xmm2","xmm0");		# 2 = io
        +	&movdqa	("xmm3","xmm7");		# 3 : 1/jak
        +	&movdqu	("xmm5",&QWP(0,$key));
        +	&pshufb	("xmm3","xmm4");		# 3 = 1/jak
        +	&pxor	("xmm3","xmm1");		# 3 = jo
        +	&jnz	(&label("enc_loop"));
        +
        +	# middle of last round
        +	&movdqa	("xmm4",&QWP($k_sbo,$const));	# 3 : sbou      .Lk_sbo
        +	&movdqa	("xmm0",&QWP($k_sbo+16,$const));# 3 : sbot      .Lk_sbo+16
        +	&pshufb	("xmm4","xmm2");		# 4 = sbou
        +	&pxor	("xmm4","xmm5");		# 4 = sb1u + k
        +	&pshufb	("xmm0","xmm3");		# 0 = sb1t
        +	&movdqa	("xmm1",&QWP(0x40,$base,$magic));# .Lk_sr[]
        +	&pxor	("xmm0","xmm4");		# 0 = A
        +	&pshufb	("xmm0","xmm1");
        +	&ret	();
        +&function_end_B("_vpaes_encrypt_core");
        +
        +##
        +##  Decryption core
        +##
        +##  Same API as encryption core.
        +##
        +&function_begin_B("_vpaes_decrypt_core");
        +	&mov	($round,&DWP(240,$key));
        +	&lea	($base,&DWP($k_dsbd,$const));
        +	&movdqa	("xmm1","xmm6");
        +	&movdqa	("xmm2",&QWP($k_dipt-$k_dsbd,$base));
        +	&pandn	("xmm1","xmm0");
        +	&mov	($magic,$round);
        +	&psrld	("xmm1",4)
        +	&movdqu	("xmm5",&QWP(0,$key));
        +	&shl	($magic,4);
        +	&pand	("xmm0","xmm6");
        +	&pshufb	("xmm2","xmm0");
        +	&movdqa	("xmm0",&QWP($k_dipt-$k_dsbd+16,$base));
        +	&xor	($magic,0x30);
        +	&pshufb	("xmm0","xmm1");
        +	&and	($magic,0x30);
        +	&pxor	("xmm2","xmm5");
        +	&movdqa	("xmm5",&QWP($k_mc_forward+48,$const));
        +	&pxor	("xmm0","xmm2");
        +	&add	($key,16);
        +	&lea	($magic,&DWP($k_sr-$k_dsbd,$base,$magic));
        +	&jmp	(&label("dec_entry"));
        +
        +&set_label("dec_loop",16);
        +##
        +##  Inverse mix columns
        +##
        +	&movdqa	("xmm4",&QWP(-0x20,$base));	# 4 : sb9u
        +	&pshufb	("xmm4","xmm2");		# 4 = sb9u
        +	&pxor	("xmm4","xmm0");
        +	&movdqa	("xmm0",&QWP(-0x10,$base));	# 0 : sb9t
        +	&pshufb	("xmm0","xmm3");		# 0 = sb9t
        +	&pxor	("xmm0","xmm4");		# 0 = ch
        +	&add	($key,16);			# next round key
        +
        +	&pshufb	("xmm0","xmm5");		# MC ch
        +	&movdqa	("xmm4",&QWP(0,$base));		# 4 : sbdu
        +	&pshufb	("xmm4","xmm2");		# 4 = sbdu
        +	&pxor	("xmm4","xmm0");		# 4 = ch
        +	&movdqa	("xmm0",&QWP(0x10,$base));	# 0 : sbdt
        +	&pshufb	("xmm0","xmm3");		# 0 = sbdt
        +	&pxor	("xmm0","xmm4");		# 0 = ch
        +	&sub	($round,1);			# nr--
        +
        +	&pshufb	("xmm0","xmm5");		# MC ch
        +	&movdqa	("xmm4",&QWP(0x20,$base));	# 4 : sbbu
        +	&pshufb	("xmm4","xmm2");		# 4 = sbbu
        +	&pxor	("xmm4","xmm0");		# 4 = ch
        +	&movdqa	("xmm0",&QWP(0x30,$base));	# 0 : sbbt
        +	&pshufb	("xmm0","xmm3");		# 0 = sbbt
        +	&pxor	("xmm0","xmm4");		# 0 = ch
        +
        +	&pshufb	("xmm0","xmm5");		# MC ch
        +	&movdqa	("xmm4",&QWP(0x40,$base));	# 4 : sbeu
        +	&pshufb	("xmm4","xmm2");		# 4 = sbeu
        +	&pxor	("xmm4","xmm0");		# 4 = ch
        +	&movdqa	("xmm0",&QWP(0x50,$base));	# 0 : sbet
        +	&pshufb	("xmm0","xmm3");		# 0 = sbet
        +	&pxor	("xmm0","xmm4");		# 0 = ch
        +
        +	&palignr("xmm5","xmm5",12);
        +
        +&set_label("dec_entry");
        +	# top of round
        +	&movdqa	("xmm1","xmm6");		# 1 : i
        +	&pandn	("xmm1","xmm0");		# 1 = i<<4
        +	&psrld	("xmm1",4);			# 1 = i
        +	&pand	("xmm0","xmm6");		# 0 = k
        +	&movdqa	("xmm2",&QWP($k_inv+16,$const));# 2 : a/k
        +	&pshufb	("xmm2","xmm0");		# 2 = a/k
        +	&pxor	("xmm0","xmm1");		# 0 = j
        +	&movdqa	("xmm3","xmm7");		# 3 : 1/i
        +	&pshufb	("xmm3","xmm1");		# 3 = 1/i
        +	&pxor	("xmm3","xmm2");		# 3 = iak = 1/i + a/k
        +	&movdqa	("xmm4","xmm7");		# 4 : 1/j
        +	&pshufb	("xmm4","xmm0");		# 4 = 1/j
        +	&pxor	("xmm4","xmm2");		# 4 = jak = 1/j + a/k
        +	&movdqa	("xmm2","xmm7");		# 2 : 1/iak
        +	&pshufb	("xmm2","xmm3");		# 2 = 1/iak
        +	&pxor	("xmm2","xmm0");		# 2 = io
        +	&movdqa	("xmm3","xmm7");		# 3 : 1/jak
        +	&pshufb	("xmm3","xmm4");		# 3 = 1/jak
        +	&pxor	("xmm3","xmm1");		# 3 = jo
        +	&movdqu	("xmm0",&QWP(0,$key));
        +	&jnz	(&label("dec_loop"));
        +
        +	# middle of last round
        +	&movdqa	("xmm4",&QWP(0x60,$base));	# 3 : sbou
        +	&pshufb	("xmm4","xmm2");		# 4 = sbou
        +	&pxor	("xmm4","xmm0");		# 4 = sb1u + k
        +	&movdqa	("xmm0",&QWP(0x70,$base));	# 0 : sbot
        +	&movdqa	("xmm2",&QWP(0,$magic));
        +	&pshufb	("xmm0","xmm3");		# 0 = sb1t
        +	&pxor	("xmm0","xmm4");		# 0 = A
        +	&pshufb	("xmm0","xmm2");
        +	&ret	();
        +&function_end_B("_vpaes_decrypt_core");
        +
        +########################################################
        +##                                                    ##
        +##                  AES key schedule                  ##
        +##                                                    ##
        +########################################################
        +&function_begin_B("_vpaes_schedule_core");
        +	&add	($const,&DWP(0,"esp"));
        +	&movdqu	("xmm0",&QWP(0,$inp));		# load key (unaligned)
        +	&movdqa	("xmm2",&QWP($k_rcon,$const));	# load rcon
        +
        +	# input transform
        +	&movdqa	("xmm3","xmm0");
        +	&lea	($base,&DWP($k_ipt,$const));
        +	&movdqa	(&QWP(4,"esp"),"xmm2");		# xmm8
        +	&call	("_vpaes_schedule_transform");
        +	&movdqa	("xmm7","xmm0");
        +
        +	&test	($out,$out);
        +	&jnz	(&label("schedule_am_decrypting"));
        +
        +	# encrypting, output zeroth round key after transform
        +	&movdqu	(&QWP(0,$key),"xmm0");
        +	&jmp	(&label("schedule_go"));
        +
        +&set_label("schedule_am_decrypting");
        +	# decrypting, output zeroth round key after shiftrows
        +	&movdqa	("xmm1",&QWP($k_sr,$const,$magic));
        +	&pshufb	("xmm3","xmm1");
        +	&movdqu	(&QWP(0,$key),"xmm3");
        +	&xor	($magic,0x30);
        +
        +&set_label("schedule_go");
        +	&cmp	($round,192);
        +	&ja	(&label("schedule_256"));
        +	&je	(&label("schedule_192"));
        +	# 128: fall though
        +
        +##
        +##  .schedule_128
        +##
        +##  128-bit specific part of key schedule.
        +##
        +##  This schedule is really simple, because all its parts
        +##  are accomplished by the subroutines.
        +##
        +&set_label("schedule_128");
        +	&mov	($round,10);
        +
        +&set_label("loop_schedule_128");
        +	&call	("_vpaes_schedule_round");
        +	&dec	($round);
        +	&jz	(&label("schedule_mangle_last"));
        +	&call	("_vpaes_schedule_mangle");	# write output
        +	&jmp	(&label("loop_schedule_128"));
        +
        +##
        +##  .aes_schedule_192
        +##
        +##  192-bit specific part of key schedule.
        +##
        +##  The main body of this schedule is the same as the 128-bit
        +##  schedule, but with more smearing.  The long, high side is
        +##  stored in %xmm7 as before, and the short, low side is in
        +##  the high bits of %xmm6.
        +##
        +##  This schedule is somewhat nastier, however, because each
        +##  round produces 192 bits of key material, or 1.5 round keys.
        +##  Therefore, on each cycle we do 2 rounds and produce 3 round
        +##  keys.
        +##
        +&set_label("schedule_192",16);
        +	&movdqu	("xmm0",&QWP(8,$inp));		# load key part 2 (very unaligned)
        +	&call	("_vpaes_schedule_transform");	# input transform	
        +	&movdqa	("xmm6","xmm0");		# save short part
        +	&pxor	("xmm4","xmm4");		# clear 4
        +	&movhlps("xmm6","xmm4");		# clobber low side with zeros
        +	&mov	($round,4);
        +
        +&set_label("loop_schedule_192");
        +	&call	("_vpaes_schedule_round");
        +	&palignr("xmm0","xmm6",8);
        +	&call	("_vpaes_schedule_mangle");	# save key n
        +	&call	("_vpaes_schedule_192_smear");
        +	&call	("_vpaes_schedule_mangle");	# save key n+1
        +	&call	("_vpaes_schedule_round");
        +	&dec	($round);
        +	&jz	(&label("schedule_mangle_last"));
        +	&call	("_vpaes_schedule_mangle");	# save key n+2
        +	&call	("_vpaes_schedule_192_smear");
        +	&jmp	(&label("loop_schedule_192"));
        +
        +##
        +##  .aes_schedule_256
        +##
        +##  256-bit specific part of key schedule.
        +##
        +##  The structure here is very similar to the 128-bit
        +##  schedule, but with an additional "low side" in
        +##  %xmm6.  The low side's rounds are the same as the
        +##  high side's, except no rcon and no rotation.
        +##
        +&set_label("schedule_256",16);
        +	&movdqu	("xmm0",&QWP(16,$inp));		# load key part 2 (unaligned)
        +	&call	("_vpaes_schedule_transform");	# input transform	
        +	&mov	($round,7);
        +
        +&set_label("loop_schedule_256");
        +	&call	("_vpaes_schedule_mangle");	# output low result
        +	&movdqa	("xmm6","xmm0");		# save cur_lo in xmm6
        +
        +	# high round
        +	&call	("_vpaes_schedule_round");
        +	&dec	($round);
        +	&jz	(&label("schedule_mangle_last"));
        +	&call	("_vpaes_schedule_mangle");	
        +
        +	# low round. swap xmm7 and xmm6
        +	&pshufd	("xmm0","xmm0",0xFF);
        +	&movdqa	(&QWP(20,"esp"),"xmm7");
        +	&movdqa	("xmm7","xmm6");
        +	&call	("_vpaes_schedule_low_round");
        +	&movdqa	("xmm7",&QWP(20,"esp"));
        +
        +	&jmp	(&label("loop_schedule_256"));
        +
        +##
        +##  .aes_schedule_mangle_last
        +##
        +##  Mangler for last round of key schedule
        +##  Mangles %xmm0
        +##    when encrypting, outputs out(%xmm0) ^ 63
        +##    when decrypting, outputs unskew(%xmm0)
        +##
        +##  Always called right before return... jumps to cleanup and exits
        +##
        +&set_label("schedule_mangle_last",16);
        +	# schedule last round key from xmm0
        +	&lea	($base,&DWP($k_deskew,$const));
        +	&test	($out,$out);
        +	&jnz	(&label("schedule_mangle_last_dec"));
        +
        +	# encrypting
        +	&movdqa	("xmm1",&QWP($k_sr,$const,$magic));
        +	&pshufb	("xmm0","xmm1");		# output permute
        +	&lea	($base,&DWP($k_opt,$const));	# prepare to output transform
        +	&add	($key,32);
        +
        +&set_label("schedule_mangle_last_dec");
        +	&add	($key,-16);
        +	&pxor	("xmm0",&QWP($k_s63,$const));
        +	&call	("_vpaes_schedule_transform");	# output transform
        +	&movdqu	(&QWP(0,$key),"xmm0");		# save last key
        +
        +	# cleanup
        +	&pxor	("xmm0","xmm0");
        +	&pxor	("xmm1","xmm1");
        +	&pxor	("xmm2","xmm2");
        +	&pxor	("xmm3","xmm3");
        +	&pxor	("xmm4","xmm4");
        +	&pxor	("xmm5","xmm5");
        +	&pxor	("xmm6","xmm6");
        +	&pxor	("xmm7","xmm7");
        +	&ret	();
        +&function_end_B("_vpaes_schedule_core");
        +
        +##
        +##  .aes_schedule_192_smear
        +##
        +##  Smear the short, low side in the 192-bit key schedule.
        +##
        +##  Inputs:
        +##    %xmm7: high side, b  a  x  y
        +##    %xmm6:  low side, d  c  0  0
        +##    %xmm13: 0
        +##
        +##  Outputs:
        +##    %xmm6: b+c+d  b+c  0  0
        +##    %xmm0: b+c+d  b+c  b  a
        +##
        +&function_begin_B("_vpaes_schedule_192_smear");
        +	&pshufd	("xmm0","xmm6",0x80);		# d c 0 0 -> c 0 0 0
        +	&pxor	("xmm6","xmm0");		# -> c+d c 0 0
        +	&pshufd	("xmm0","xmm7",0xFE);		# b a _ _ -> b b b a
        +	&pxor	("xmm6","xmm0");		# -> b+c+d b+c b a
        +	&movdqa	("xmm0","xmm6");
        +	&pxor	("xmm1","xmm1");
        +	&movhlps("xmm6","xmm1");		# clobber low side with zeros
        +	&ret	();
        +&function_end_B("_vpaes_schedule_192_smear");
        +
        +##
        +##  .aes_schedule_round
        +##
        +##  Runs one main round of the key schedule on %xmm0, %xmm7
        +##
        +##  Specifically, runs subbytes on the high dword of %xmm0
        +##  then rotates it by one byte and xors into the low dword of
        +##  %xmm7.
        +##
        +##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
        +##  next rcon.
        +##
        +##  Smears the dwords of %xmm7 by xoring the low into the
        +##  second low, result into third, result into highest.
        +##
        +##  Returns results in %xmm7 = %xmm0.
        +##  Clobbers %xmm1-%xmm5.
        +##
        +&function_begin_B("_vpaes_schedule_round");
        +	# extract rcon from xmm8
        +	&movdqa	("xmm2",&QWP(8,"esp"));		# xmm8
        +	&pxor	("xmm1","xmm1");
        +	&palignr("xmm1","xmm2",15);
        +	&palignr("xmm2","xmm2",15);
        +	&pxor	("xmm7","xmm1");
        +
        +	# rotate
        +	&pshufd	("xmm0","xmm0",0xFF);
        +	&palignr("xmm0","xmm0",1);
        +
        +	# fall through...
        +	&movdqa	(&QWP(8,"esp"),"xmm2");		# xmm8
        +
        +	# low round: same as high round, but no rotation and no rcon.
        +&set_label("_vpaes_schedule_low_round");
        +	# smear xmm7
        +	&movdqa	("xmm1","xmm7");
        +	&pslldq	("xmm7",4);
        +	&pxor	("xmm7","xmm1");
        +	&movdqa	("xmm1","xmm7");
        +	&pslldq	("xmm7",8);
        +	&pxor	("xmm7","xmm1");
        +	&pxor	("xmm7",&QWP($k_s63,$const));
        +
        +	# subbyte
        +	&movdqa	("xmm4",&QWP($k_s0F,$const));
        +	&movdqa	("xmm5",&QWP($k_inv,$const));	# 4 : 1/j
        +	&movdqa	("xmm1","xmm4");	
        +	&pandn	("xmm1","xmm0");
        +	&psrld	("xmm1",4);			# 1 = i
        +	&pand	("xmm0","xmm4");		# 0 = k
        +	&movdqa	("xmm2",&QWP($k_inv+16,$const));# 2 : a/k
        +	&pshufb	("xmm2","xmm0");		# 2 = a/k
        +	&pxor	("xmm0","xmm1");		# 0 = j
        +	&movdqa	("xmm3","xmm5");		# 3 : 1/i
        +	&pshufb	("xmm3","xmm1");		# 3 = 1/i
        +	&pxor	("xmm3","xmm2");		# 3 = iak = 1/i + a/k
        +	&movdqa	("xmm4","xmm5");		# 4 : 1/j
        +	&pshufb	("xmm4","xmm0");		# 4 = 1/j
        +	&pxor	("xmm4","xmm2");		# 4 = jak = 1/j + a/k
        +	&movdqa	("xmm2","xmm5");		# 2 : 1/iak
        +	&pshufb	("xmm2","xmm3");		# 2 = 1/iak
        +	&pxor	("xmm2","xmm0");		# 2 = io
        +	&movdqa	("xmm3","xmm5");		# 3 : 1/jak
        +	&pshufb	("xmm3","xmm4");		# 3 = 1/jak
        +	&pxor	("xmm3","xmm1");		# 3 = jo
        +	&movdqa	("xmm4",&QWP($k_sb1,$const));	# 4 : sbou
        +	&pshufb	("xmm4","xmm2");		# 4 = sbou
        +	&movdqa	("xmm0",&QWP($k_sb1+16,$const));# 0 : sbot
        +	&pshufb	("xmm0","xmm3");		# 0 = sb1t
        +	&pxor	("xmm0","xmm4");		# 0 = sbox output
        +
        +	# add in smeared stuff
        +	&pxor	("xmm0","xmm7");
        +	&movdqa	("xmm7","xmm0");
        +	&ret	();
        +&function_end_B("_vpaes_schedule_round");
        +
        +##
        +##  .aes_schedule_transform
        +##
        +##  Linear-transform %xmm0 according to tables at (%ebx)
        +##
        +##  Output in %xmm0
        +##  Clobbers %xmm1, %xmm2
        +##
        +&function_begin_B("_vpaes_schedule_transform");
        +	&movdqa	("xmm2",&QWP($k_s0F,$const));
        +	&movdqa	("xmm1","xmm2");
        +	&pandn	("xmm1","xmm0");
        +	&psrld	("xmm1",4);
        +	&pand	("xmm0","xmm2");
        +	&movdqa	("xmm2",&QWP(0,$base));
        +	&pshufb	("xmm2","xmm0");
        +	&movdqa	("xmm0",&QWP(16,$base));
        +	&pshufb	("xmm0","xmm1");
        +	&pxor	("xmm0","xmm2");
        +	&ret	();
        +&function_end_B("_vpaes_schedule_transform");
        +
        +##
        +##  .aes_schedule_mangle
        +##
        +##  Mangle xmm0 from (basis-transformed) standard version
        +##  to our version.
        +##
        +##  On encrypt,
        +##    xor with 0x63
        +##    multiply by circulant 0,1,1,1
        +##    apply shiftrows transform
        +##
        +##  On decrypt,
        +##    xor with 0x63
        +##    multiply by "inverse mixcolumns" circulant E,B,D,9
        +##    deskew
        +##    apply shiftrows transform
        +##
        +##
        +##  Writes out to (%edx), and increments or decrements it
        +##  Keeps track of round number mod 4 in %ecx
        +##  Preserves xmm0
        +##  Clobbers xmm1-xmm5
        +##
        +&function_begin_B("_vpaes_schedule_mangle");
        +	&movdqa	("xmm4","xmm0");	# save xmm0 for later
        +	&movdqa	("xmm5",&QWP($k_mc_forward,$const));
        +	&test	($out,$out);
        +	&jnz	(&label("schedule_mangle_dec"));
        +
        +	# encrypting
        +	&add	($key,16);
        +	&pxor	("xmm4",&QWP($k_s63,$const));
        +	&pshufb	("xmm4","xmm5");
        +	&movdqa	("xmm3","xmm4");
        +	&pshufb	("xmm4","xmm5");
        +	&pxor	("xmm3","xmm4");
        +	&pshufb	("xmm4","xmm5");
        +	&pxor	("xmm3","xmm4");
        +
        +	&jmp	(&label("schedule_mangle_both"));
        +
        +&set_label("schedule_mangle_dec",16);
        +	# inverse mix columns
        +	&movdqa	("xmm2",&QWP($k_s0F,$const));
        +	&lea	($inp,&DWP($k_dksd,$const));
        +	&movdqa	("xmm1","xmm2");
        +	&pandn	("xmm1","xmm4");
        +	&psrld	("xmm1",4);			# 1 = hi
        +	&pand	("xmm4","xmm2");		# 4 = lo
        +
        +	&movdqa	("xmm2",&QWP(0,$inp));
        +	&pshufb	("xmm2","xmm4");
        +	&movdqa	("xmm3",&QWP(0x10,$inp));
        +	&pshufb	("xmm3","xmm1");
        +	&pxor	("xmm3","xmm2");
        +	&pshufb	("xmm3","xmm5");
        +
        +	&movdqa	("xmm2",&QWP(0x20,$inp));
        +	&pshufb	("xmm2","xmm4");
        +	&pxor	("xmm2","xmm3");
        +	&movdqa	("xmm3",&QWP(0x30,$inp));
        +	&pshufb	("xmm3","xmm1");
        +	&pxor	("xmm3","xmm2");
        +	&pshufb	("xmm3","xmm5");
        +
        +	&movdqa	("xmm2",&QWP(0x40,$inp));
        +	&pshufb	("xmm2","xmm4");
        +	&pxor	("xmm2","xmm3");
        +	&movdqa	("xmm3",&QWP(0x50,$inp));
        +	&pshufb	("xmm3","xmm1");
        +	&pxor	("xmm3","xmm2");
        +	&pshufb	("xmm3","xmm5");
        +
        +	&movdqa	("xmm2",&QWP(0x60,$inp));
        +	&pshufb	("xmm2","xmm4");
        +	&pxor	("xmm2","xmm3");
        +	&movdqa	("xmm3",&QWP(0x70,$inp));
        +	&pshufb	("xmm3","xmm1");
        +	&pxor	("xmm3","xmm2");
        +
        +	&add	($key,-16);
        +
        +&set_label("schedule_mangle_both");
        +	&movdqa	("xmm1",&QWP($k_sr,$const,$magic));
        +	&pshufb	("xmm3","xmm1");
        +	&add	($magic,-16);
        +	&and	($magic,0x30);
        +	&movdqu	(&QWP(0,$key),"xmm3");
        +	&ret	();
        +&function_end_B("_vpaes_schedule_mangle");
        +
        +#
        +# Interface to OpenSSL
        +#
        +&function_begin("${PREFIX}_set_encrypt_key");
        +	&mov	($inp,&wparam(0));		# inp
        +	&lea	($base,&DWP(-56,"esp"));
        +	&mov	($round,&wparam(1));		# bits
        +	&and	($base,-16);
        +	&mov	($key,&wparam(2));		# key
        +	&xchg	($base,"esp");			# alloca
        +	&mov	(&DWP(48,"esp"),$base);
        +
        +	&mov	($base,$round);
        +	&shr	($base,5);
        +	&add	($base,5);
        +	&mov	(&DWP(240,$key),$base);		# AES_KEY->rounds = nbits/32+5;
        +	&mov	($magic,0x30);
        +	&mov	($out,0);
        +
        +	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
        +	&call	("_vpaes_schedule_core");
        +&set_label("pic_point");
        +
        +	&mov	("esp",&DWP(48,"esp"));
        +	&xor	("eax","eax");
        +&function_end("${PREFIX}_set_encrypt_key");
        +
        +&function_begin("${PREFIX}_set_decrypt_key");
        +	&mov	($inp,&wparam(0));		# inp
        +	&lea	($base,&DWP(-56,"esp"));
        +	&mov	($round,&wparam(1));		# bits
        +	&and	($base,-16);
        +	&mov	($key,&wparam(2));		# key
        +	&xchg	($base,"esp");			# alloca
        +	&mov	(&DWP(48,"esp"),$base);
        +
        +	&mov	($base,$round);
        +	&shr	($base,5);
        +	&add	($base,5);
        +	&mov	(&DWP(240,$key),$base);	# AES_KEY->rounds = nbits/32+5;
        +	&shl	($base,4);
        +	&lea	($key,&DWP(16,$key,$base));
        +
        +	&mov	($out,1);
        +	&mov	($magic,$round);
        +	&shr	($magic,1);
        +	&and	($magic,32);
        +	&xor	($magic,32);			# nbist==192?0:32;
        +
        +	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
        +	&call	("_vpaes_schedule_core");
        +&set_label("pic_point");
        +
        +	&mov	("esp",&DWP(48,"esp"));
        +	&xor	("eax","eax");
        +&function_end("${PREFIX}_set_decrypt_key");
        +
        +&function_begin("${PREFIX}_encrypt");
        +	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
        +	&call	("_vpaes_preheat");
        +&set_label("pic_point");
        +	&mov	($inp,&wparam(0));		# inp
        +	&lea	($base,&DWP(-56,"esp"));
        +	&mov	($out,&wparam(1));		# out
        +	&and	($base,-16);
        +	&mov	($key,&wparam(2));		# key
        +	&xchg	($base,"esp");			# alloca
        +	&mov	(&DWP(48,"esp"),$base);
        +
        +	&movdqu	("xmm0",&QWP(0,$inp));
        +	&call	("_vpaes_encrypt_core");
        +	&movdqu	(&QWP(0,$out),"xmm0");
        +
        +	&mov	("esp",&DWP(48,"esp"));
        +&function_end("${PREFIX}_encrypt");
        +
        +&function_begin("${PREFIX}_decrypt");
        +	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
        +	&call	("_vpaes_preheat");
        +&set_label("pic_point");
        +	&mov	($inp,&wparam(0));		# inp
        +	&lea	($base,&DWP(-56,"esp"));
        +	&mov	($out,&wparam(1));		# out
        +	&and	($base,-16);
        +	&mov	($key,&wparam(2));		# key
        +	&xchg	($base,"esp");			# alloca
        +	&mov	(&DWP(48,"esp"),$base);
        +
        +	&movdqu	("xmm0",&QWP(0,$inp));
        +	&call	("_vpaes_decrypt_core");
        +	&movdqu	(&QWP(0,$out),"xmm0");
        +
        +	&mov	("esp",&DWP(48,"esp"));
        +&function_end("${PREFIX}_decrypt");
        +
        +&function_begin("${PREFIX}_cbc_encrypt");
        +	&mov	($inp,&wparam(0));		# inp
        +	&mov	($out,&wparam(1));		# out
        +	&mov	($round,&wparam(2));		# len
        +	&mov	($key,&wparam(3));		# key
        +	&sub	($round,16);
        +	&jc	(&label("cbc_abort"));
        +	&lea	($base,&DWP(-56,"esp"));
        +	&mov	($const,&wparam(4));		# ivp
        +	&and	($base,-16);
        +	&mov	($magic,&wparam(5));		# enc
        +	&xchg	($base,"esp");			# alloca
        +	&movdqu	("xmm1",&QWP(0,$const));	# load IV
        +	&sub	($out,$inp);
        +	&mov	(&DWP(48,"esp"),$base);
        +
        +	&mov	(&DWP(0,"esp"),$out);		# save out
        +	&mov	(&DWP(4,"esp"),$key)		# save key
        +	&mov	(&DWP(8,"esp"),$const);		# save ivp
        +	&mov	($out,$round);			# $out works as $len
        +
        +	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
        +	&call	("_vpaes_preheat");
        +&set_label("pic_point");
        +	&cmp	($magic,0);
        +	&je	(&label("cbc_dec_loop"));
        +	&jmp	(&label("cbc_enc_loop"));
        +
        +&set_label("cbc_enc_loop",16);
        +	&movdqu	("xmm0",&QWP(0,$inp));		# load input
        +	&pxor	("xmm0","xmm1");		# inp^=iv
        +	&call	("_vpaes_encrypt_core");
        +	&mov	($base,&DWP(0,"esp"));		# restore out
        +	&mov	($key,&DWP(4,"esp"));		# restore key
        +	&movdqa	("xmm1","xmm0");
        +	&movdqu	(&QWP(0,$base,$inp),"xmm0");	# write output
        +	&lea	($inp,&DWP(16,$inp));
        +	&sub	($out,16);
        +	&jnc	(&label("cbc_enc_loop"));
        +	&jmp	(&label("cbc_done"));
        +
        +&set_label("cbc_dec_loop",16);
        +	&movdqu	("xmm0",&QWP(0,$inp));		# load input
        +	&movdqa	(&QWP(16,"esp"),"xmm1");	# save IV
        +	&movdqa	(&QWP(32,"esp"),"xmm0");	# save future IV
        +	&call	("_vpaes_decrypt_core");
        +	&mov	($base,&DWP(0,"esp"));		# restore out
        +	&mov	($key,&DWP(4,"esp"));		# restore key
        +	&pxor	("xmm0",&QWP(16,"esp"));	# out^=iv
        +	&movdqa	("xmm1",&QWP(32,"esp"));	# load next IV
        +	&movdqu	(&QWP(0,$base,$inp),"xmm0");	# write output
        +	&lea	($inp,&DWP(16,$inp));
        +	&sub	($out,16);
        +	&jnc	(&label("cbc_dec_loop"));
        +
        +&set_label("cbc_done");
        +	&mov	($base,&DWP(8,"esp"));		# restore ivp
        +	&mov	("esp",&DWP(48,"esp"));
        +	&movdqu	(&QWP(0,$base),"xmm1");		# write IV
        +&set_label("cbc_abort");
        +&function_end("${PREFIX}_cbc_encrypt");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl b/vendor/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl
        new file mode 100644
        index 000000000..41f2e46f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/aes/asm/vpaes-x86_64.pl
        @@ -0,0 +1,1207 @@
        +#!/usr/bin/env perl
        +
        +######################################################################
        +## Constant-time SSSE3 AES core implementation.
        +## version 0.1
        +##
        +## By Mike Hamburg (Stanford University), 2009
        +## Public domain.
        +##
        +## For details see http://shiftleft.org/papers/vector_aes/ and
        +## http://crypto.stanford.edu/vpaes/.
        +
        +######################################################################
        +# September 2011.
        +#
        +# Interface to OpenSSL as "almost" drop-in replacement for
        +# aes-x86_64.pl. "Almost" refers to the fact that AES_cbc_encrypt
        +# doesn't handle partial vectors (doesn't have to if called from
        +# EVP only). "Drop-in" implies that this module doesn't share key
        +# schedule structure with the original nor does it make assumption
        +# about its alignment...
        +#
        +# Performance summary. aes-x86_64.pl column lists large-block CBC
        +# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per
        +# byte processed with 128-bit key, and vpaes-x86_64.pl column -
        +# [also large-block CBC] encrypt/decrypt.
        +#
        +#		aes-x86_64.pl		vpaes-x86_64.pl
        +#
        +# Core 2(**)	30.5/43.7/14.3		21.8/25.7(***)
        +# Nehalem	30.5/42.2/14.6		 9.8/11.8
        +# Atom		63.9/79.0/32.1		64.0/84.8(***)
        +#
        +# (*)	"Hyper-threading" in the context refers rather to cache shared
        +#	among multiple cores, than to specifically Intel HTT. As vast
        +#	majority of contemporary cores share cache, slower code path
        +#	is common place. In other words "with-hyper-threading-off"
        +#	results are presented mostly for reference purposes.
        +#
        +# (**)	"Core 2" refers to initial 65nm design, a.k.a. Conroe.
        +#
        +# (***)	Less impressive improvement on Core 2 and Atom is due to slow
        +#	pshufb,	yet it's respectable +40%/78% improvement on Core 2
        +#	(as implied, over "hyper-threading-safe" code path).
        +#
        +#						<appro@openssl.org>
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +$PREFIX="vpaes";
        +
        +$code.=<<___;
        +.text
        +
        +##
        +##  _aes_encrypt_core
        +##
        +##  AES-encrypt %xmm0.
        +##
        +##  Inputs:
        +##     %xmm0 = input
        +##     %xmm9-%xmm15 as in _vpaes_preheat
        +##    (%rdx) = scheduled keys
        +##
        +##  Output in %xmm0
        +##  Clobbers  %xmm1-%xmm5, %r9, %r10, %r11, %rax
        +##  Preserves %xmm6 - %xmm8 so you get some local vectors
        +##
        +##
        +.type	_vpaes_encrypt_core,\@abi-omnipotent
        +.align 16
        +_vpaes_encrypt_core:
        +	mov	%rdx,	%r9
        +	mov	\$16,	%r11
        +	mov	240(%rdx),%eax
        +	movdqa	%xmm9,	%xmm1
        +	movdqa	.Lk_ipt(%rip), %xmm2	# iptlo
        +	pandn	%xmm0,	%xmm1
        +	movdqu	(%r9),	%xmm5		# round0 key
        +	psrld	\$4,	%xmm1
        +	pand	%xmm9,	%xmm0
        +	pshufb	%xmm0,	%xmm2
        +	movdqa	.Lk_ipt+16(%rip), %xmm0	# ipthi
        +	pshufb	%xmm1,	%xmm0
        +	pxor	%xmm5,	%xmm2
        +	pxor	%xmm2,	%xmm0
        +	add	\$16,	%r9
        +	lea	.Lk_mc_backward(%rip),%r10
        +	jmp	.Lenc_entry
        +
        +.align 16
        +.Lenc_loop:
        +	# middle of middle round
        +	movdqa  %xmm13,	%xmm4	# 4 : sb1u
        +	pshufb  %xmm2,	%xmm4	# 4 = sb1u
        +	pxor	%xmm5,	%xmm4	# 4 = sb1u + k
        +	movdqa  %xmm12,	%xmm0	# 0 : sb1t
        +	pshufb  %xmm3,	%xmm0	# 0 = sb1t
        +	pxor	%xmm4,	%xmm0	# 0 = A
        +	movdqa  %xmm15,	%xmm5	# 4 : sb2u
        +	pshufb	%xmm2,	%xmm5	# 4 = sb2u
        +	movdqa	-0x40(%r11,%r10), %xmm1		# .Lk_mc_forward[]
        +	movdqa	%xmm14, %xmm2	# 2 : sb2t
        +	pshufb	%xmm3,  %xmm2	# 2 = sb2t
        +	pxor	%xmm5,	%xmm2	# 2 = 2A
        +	movdqa	(%r11,%r10), %xmm4		# .Lk_mc_backward[]
        +	movdqa	%xmm0,  %xmm3	# 3 = A
        +	pshufb  %xmm1,  %xmm0	# 0 = B
        +	add	\$16,	%r9	# next key
        +	pxor	%xmm2,  %xmm0	# 0 = 2A+B
        +	pshufb	%xmm4,	%xmm3	# 3 = D
        +	add	\$16,	%r11	# next mc
        +	pxor	%xmm0,	%xmm3	# 3 = 2A+B+D
        +	pshufb  %xmm1,	%xmm0	# 0 = 2B+C
        +	and	\$0x30,	%r11	# ... mod 4
        +	pxor	%xmm3,	%xmm0	# 0 = 2A+3B+C+D
        +	sub	\$1,%rax	# nr--
        +
        +.Lenc_entry:
        +	# top of round
        +	movdqa  %xmm9, 	%xmm1	# 1 : i
        +	pandn	%xmm0, 	%xmm1	# 1 = i<<4
        +	psrld	\$4,   	%xmm1   # 1 = i
        +	pand	%xmm9, 	%xmm0   # 0 = k
        +	movdqa	%xmm11, %xmm5	# 2 : a/k
        +	pshufb  %xmm0,  %xmm5	# 2 = a/k
        +	pxor	%xmm1,	%xmm0	# 0 = j
        +	movdqa	%xmm10,	%xmm3  	# 3 : 1/i
        +	pshufb  %xmm1, 	%xmm3  	# 3 = 1/i
        +	pxor	%xmm5, 	%xmm3  	# 3 = iak = 1/i + a/k
        +	movdqa	%xmm10,	%xmm4  	# 4 : 1/j
        +	pshufb	%xmm0, 	%xmm4  	# 4 = 1/j
        +	pxor	%xmm5, 	%xmm4  	# 4 = jak = 1/j + a/k
        +	movdqa	%xmm10,	%xmm2  	# 2 : 1/iak
        +	pshufb  %xmm3,	%xmm2  	# 2 = 1/iak
        +	pxor	%xmm0, 	%xmm2  	# 2 = io
        +	movdqa	%xmm10, %xmm3   # 3 : 1/jak
        +	movdqu	(%r9),	%xmm5
        +	pshufb  %xmm4,  %xmm3   # 3 = 1/jak
        +	pxor	%xmm1,  %xmm3   # 3 = jo
        +	jnz	.Lenc_loop
        +
        +	# middle of last round
        +	movdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
        +	movdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
        +	pshufb  %xmm2,  %xmm4	# 4 = sbou
        +	pxor	%xmm5,  %xmm4	# 4 = sb1u + k
        +	pshufb  %xmm3,	%xmm0	# 0 = sb1t
        +	movdqa	0x40(%r11,%r10), %xmm1		# .Lk_sr[]
        +	pxor	%xmm4,	%xmm0	# 0 = A
        +	pshufb	%xmm1,	%xmm0
        +	ret
        +.size	_vpaes_encrypt_core,.-_vpaes_encrypt_core
        +	
        +##
        +##  Decryption core
        +##
        +##  Same API as encryption core.
        +##
        +.type	_vpaes_decrypt_core,\@abi-omnipotent
        +.align	16
        +_vpaes_decrypt_core:
        +	mov	%rdx,	%r9		# load key
        +	mov	240(%rdx),%eax
        +	movdqa	%xmm9,	%xmm1
        +	movdqa	.Lk_dipt(%rip), %xmm2	# iptlo
        +	pandn	%xmm0,	%xmm1
        +	mov	%rax,	%r11
        +	psrld	\$4,	%xmm1
        +	movdqu	(%r9),	%xmm5		# round0 key
        +	shl	\$4,	%r11
        +	pand	%xmm9,	%xmm0
        +	pshufb	%xmm0,	%xmm2
        +	movdqa	.Lk_dipt+16(%rip), %xmm0 # ipthi
        +	xor	\$0x30,	%r11
        +	lea	.Lk_dsbd(%rip),%r10
        +	pshufb	%xmm1,	%xmm0
        +	and	\$0x30,	%r11
        +	pxor	%xmm5,	%xmm2
        +	movdqa	.Lk_mc_forward+48(%rip), %xmm5
        +	pxor	%xmm2,	%xmm0
        +	add	\$16,	%r9
        +	add	%r10,	%r11
        +	jmp	.Ldec_entry
        +
        +.align 16
        +.Ldec_loop:
        +##
        +##  Inverse mix columns
        +##
        +	movdqa  -0x20(%r10),%xmm4	# 4 : sb9u
        +	pshufb	%xmm2,	%xmm4		# 4 = sb9u
        +	pxor	%xmm0,	%xmm4
        +	movdqa  -0x10(%r10),%xmm0	# 0 : sb9t
        +	pshufb	%xmm3,	%xmm0		# 0 = sb9t
        +	pxor	%xmm4,	%xmm0		# 0 = ch
        +	add	\$16, %r9		# next round key
        +
        +	pshufb	%xmm5,	%xmm0		# MC ch
        +	movdqa  0x00(%r10),%xmm4	# 4 : sbdu
        +	pshufb	%xmm2,	%xmm4		# 4 = sbdu
        +	pxor	%xmm0,	%xmm4		# 4 = ch
        +	movdqa  0x10(%r10),%xmm0	# 0 : sbdt
        +	pshufb	%xmm3,	%xmm0		# 0 = sbdt
        +	pxor	%xmm4,	%xmm0		# 0 = ch
        +	sub	\$1,%rax		# nr--
        +	
        +	pshufb	%xmm5,	%xmm0		# MC ch
        +	movdqa  0x20(%r10),%xmm4	# 4 : sbbu
        +	pshufb	%xmm2,	%xmm4		# 4 = sbbu
        +	pxor	%xmm0,	%xmm4		# 4 = ch
        +	movdqa  0x30(%r10),%xmm0	# 0 : sbbt
        +	pshufb	%xmm3,	%xmm0		# 0 = sbbt
        +	pxor	%xmm4,	%xmm0		# 0 = ch
        +	
        +	pshufb	%xmm5,	%xmm0		# MC ch
        +	movdqa  0x40(%r10),%xmm4	# 4 : sbeu
        +	pshufb	%xmm2,	%xmm4		# 4 = sbeu
        +	pxor	%xmm0,	%xmm4		# 4 = ch
        +	movdqa  0x50(%r10),%xmm0	# 0 : sbet
        +	pshufb	%xmm3,	%xmm0		# 0 = sbet
        +	pxor	%xmm4,	%xmm0		# 0 = ch
        +
        +	palignr	\$12,	%xmm5,	%xmm5
        +	
        +.Ldec_entry:
        +	# top of round
        +	movdqa  %xmm9, 	%xmm1	# 1 : i
        +	pandn	%xmm0, 	%xmm1	# 1 = i<<4
        +	psrld	\$4,    %xmm1	# 1 = i
        +	pand	%xmm9, 	%xmm0	# 0 = k
        +	movdqa	%xmm11, %xmm2	# 2 : a/k
        +	pshufb  %xmm0,  %xmm2	# 2 = a/k
        +	pxor	%xmm1,	%xmm0	# 0 = j
        +	movdqa	%xmm10,	%xmm3	# 3 : 1/i
        +	pshufb  %xmm1, 	%xmm3	# 3 = 1/i
        +	pxor	%xmm2, 	%xmm3	# 3 = iak = 1/i + a/k
        +	movdqa	%xmm10,	%xmm4	# 4 : 1/j
        +	pshufb	%xmm0, 	%xmm4	# 4 = 1/j
        +	pxor	%xmm2, 	%xmm4	# 4 = jak = 1/j + a/k
        +	movdqa	%xmm10,	%xmm2	# 2 : 1/iak
        +	pshufb  %xmm3,	%xmm2	# 2 = 1/iak
        +	pxor	%xmm0, 	%xmm2	# 2 = io
        +	movdqa	%xmm10, %xmm3	# 3 : 1/jak
        +	pshufb  %xmm4,  %xmm3	# 3 = 1/jak
        +	pxor	%xmm1,  %xmm3	# 3 = jo
        +	movdqu	(%r9),	%xmm0
        +	jnz	.Ldec_loop
        +
        +	# middle of last round
        +	movdqa	0x60(%r10), %xmm4	# 3 : sbou
        +	pshufb  %xmm2,  %xmm4	# 4 = sbou
        +	pxor	%xmm0,  %xmm4	# 4 = sb1u + k
        +	movdqa	0x70(%r10), %xmm0	# 0 : sbot
        +	movdqa	-0x160(%r11), %xmm2	# .Lk_sr-.Lk_dsbd=-0x160
        +	pshufb  %xmm3,	%xmm0	# 0 = sb1t
        +	pxor	%xmm4,	%xmm0	# 0 = A
        +	pshufb	%xmm2,	%xmm0
        +	ret
        +.size	_vpaes_decrypt_core,.-_vpaes_decrypt_core
        +
        +########################################################
        +##                                                    ##
        +##                  AES key schedule                  ##
        +##                                                    ##
        +########################################################
        +.type	_vpaes_schedule_core,\@abi-omnipotent
        +.align	16
        +_vpaes_schedule_core:
        +	# rdi = key
        +	# rsi = size in bits
        +	# rdx = buffer
        +	# rcx = direction.  0=encrypt, 1=decrypt
        +
        +	call	_vpaes_preheat		# load the tables
        +	movdqa	.Lk_rcon(%rip), %xmm8	# load rcon
        +	movdqu	(%rdi),	%xmm0		# load key (unaligned)
        +
        +	# input transform
        +	movdqa	%xmm0,	%xmm3
        +	lea	.Lk_ipt(%rip), %r11
        +	call	_vpaes_schedule_transform
        +	movdqa	%xmm0,	%xmm7
        +
        +	lea	.Lk_sr(%rip),%r10
        +	test	%rcx,	%rcx
        +	jnz	.Lschedule_am_decrypting
        +
        +	# encrypting, output zeroth round key after transform
        +	movdqu	%xmm0,	(%rdx)
        +	jmp	.Lschedule_go
        +
        +.Lschedule_am_decrypting:
        +	# decrypting, output zeroth round key after shiftrows
        +	movdqa	(%r8,%r10),%xmm1
        +	pshufb  %xmm1,	%xmm3
        +	movdqu	%xmm3,	(%rdx)
        +	xor	\$0x30, %r8
        +
        +.Lschedule_go:
        +	cmp	\$192,	%esi
        +	ja	.Lschedule_256
        +	je	.Lschedule_192
        +	# 128: fall though
        +
        +##
        +##  .schedule_128
        +##
        +##  128-bit specific part of key schedule.
        +##
        +##  This schedule is really simple, because all its parts
        +##  are accomplished by the subroutines.
        +##
        +.Lschedule_128:
        +	mov	\$10, %esi
        +	
        +.Loop_schedule_128:
        +	call 	_vpaes_schedule_round
        +	dec	%rsi
        +	jz 	.Lschedule_mangle_last
        +	call	_vpaes_schedule_mangle	# write output
        +	jmp 	.Loop_schedule_128
        +
        +##
        +##  .aes_schedule_192
        +##
        +##  192-bit specific part of key schedule.
        +##
        +##  The main body of this schedule is the same as the 128-bit
        +##  schedule, but with more smearing.  The long, high side is
        +##  stored in %xmm7 as before, and the short, low side is in
        +##  the high bits of %xmm6.
        +##
        +##  This schedule is somewhat nastier, however, because each
        +##  round produces 192 bits of key material, or 1.5 round keys.
        +##  Therefore, on each cycle we do 2 rounds and produce 3 round
        +##  keys.
        +##
        +.align	16
        +.Lschedule_192:
        +	movdqu	8(%rdi),%xmm0		# load key part 2 (very unaligned)
        +	call	_vpaes_schedule_transform	# input transform
        +	movdqa	%xmm0,	%xmm6		# save short part
        +	pxor	%xmm4,	%xmm4		# clear 4
        +	movhlps	%xmm4,	%xmm6		# clobber low side with zeros
        +	mov	\$4,	%esi
        +
        +.Loop_schedule_192:
        +	call	_vpaes_schedule_round
        +	palignr	\$8,%xmm6,%xmm0	
        +	call	_vpaes_schedule_mangle	# save key n
        +	call	_vpaes_schedule_192_smear
        +	call	_vpaes_schedule_mangle	# save key n+1
        +	call	_vpaes_schedule_round
        +	dec	%rsi
        +	jz 	.Lschedule_mangle_last
        +	call	_vpaes_schedule_mangle	# save key n+2
        +	call	_vpaes_schedule_192_smear
        +	jmp	.Loop_schedule_192
        +
        +##
        +##  .aes_schedule_256
        +##
        +##  256-bit specific part of key schedule.
        +##
        +##  The structure here is very similar to the 128-bit
        +##  schedule, but with an additional "low side" in
        +##  %xmm6.  The low side's rounds are the same as the
        +##  high side's, except no rcon and no rotation.
        +##
        +.align	16
        +.Lschedule_256:
        +	movdqu	16(%rdi),%xmm0		# load key part 2 (unaligned)
        +	call	_vpaes_schedule_transform	# input transform
        +	mov	\$7, %esi
        +	
        +.Loop_schedule_256:
        +	call	_vpaes_schedule_mangle	# output low result
        +	movdqa	%xmm0,	%xmm6		# save cur_lo in xmm6
        +
        +	# high round
        +	call	_vpaes_schedule_round
        +	dec	%rsi
        +	jz 	.Lschedule_mangle_last
        +	call	_vpaes_schedule_mangle	
        +
        +	# low round. swap xmm7 and xmm6
        +	pshufd	\$0xFF,	%xmm0,	%xmm0
        +	movdqa	%xmm7,	%xmm5
        +	movdqa	%xmm6,	%xmm7
        +	call	_vpaes_schedule_low_round
        +	movdqa	%xmm5,	%xmm7
        +	
        +	jmp	.Loop_schedule_256
        +
        +	
        +##
        +##  .aes_schedule_mangle_last
        +##
        +##  Mangler for last round of key schedule
        +##  Mangles %xmm0
        +##    when encrypting, outputs out(%xmm0) ^ 63
        +##    when decrypting, outputs unskew(%xmm0)
        +##
        +##  Always called right before return... jumps to cleanup and exits
        +##
        +.align	16
        +.Lschedule_mangle_last:
        +	# schedule last round key from xmm0
        +	lea	.Lk_deskew(%rip),%r11	# prepare to deskew
        +	test	%rcx, 	%rcx
        +	jnz	.Lschedule_mangle_last_dec
        +
        +	# encrypting
        +	movdqa	(%r8,%r10),%xmm1
        +	pshufb	%xmm1,	%xmm0		# output permute
        +	lea	.Lk_opt(%rip),	%r11	# prepare to output transform
        +	add	\$32,	%rdx
        +
        +.Lschedule_mangle_last_dec:
        +	add	\$-16,	%rdx
        +	pxor	.Lk_s63(%rip),	%xmm0
        +	call	_vpaes_schedule_transform # output transform
        +	movdqu	%xmm0,	(%rdx)		# save last key
        +
        +	# cleanup
        +	pxor	%xmm0,  %xmm0
        +	pxor	%xmm1,  %xmm1
        +	pxor	%xmm2,  %xmm2
        +	pxor	%xmm3,  %xmm3
        +	pxor	%xmm4,  %xmm4
        +	pxor	%xmm5,  %xmm5
        +	pxor	%xmm6,  %xmm6
        +	pxor	%xmm7,  %xmm7
        +	ret
        +.size	_vpaes_schedule_core,.-_vpaes_schedule_core
        +
        +##
        +##  .aes_schedule_192_smear
        +##
        +##  Smear the short, low side in the 192-bit key schedule.
        +##
        +##  Inputs:
        +##    %xmm7: high side, b  a  x  y
        +##    %xmm6:  low side, d  c  0  0
        +##    %xmm13: 0
        +##
        +##  Outputs:
        +##    %xmm6: b+c+d  b+c  0  0
        +##    %xmm0: b+c+d  b+c  b  a
        +##
        +.type	_vpaes_schedule_192_smear,\@abi-omnipotent
        +.align	16
        +_vpaes_schedule_192_smear:
        +	pshufd	\$0x80,	%xmm6,	%xmm0	# d c 0 0 -> c 0 0 0
        +	pxor	%xmm0,	%xmm6		# -> c+d c 0 0
        +	pshufd	\$0xFE,	%xmm7,	%xmm0	# b a _ _ -> b b b a
        +	pxor	%xmm0,	%xmm6		# -> b+c+d b+c b a
        +	movdqa	%xmm6,	%xmm0
        +	pxor	%xmm1,	%xmm1
        +	movhlps	%xmm1,	%xmm6		# clobber low side with zeros
        +	ret
        +.size	_vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
        +
        +##
        +##  .aes_schedule_round
        +##
        +##  Runs one main round of the key schedule on %xmm0, %xmm7
        +##
        +##  Specifically, runs subbytes on the high dword of %xmm0
        +##  then rotates it by one byte and xors into the low dword of
        +##  %xmm7.
        +##
        +##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
        +##  next rcon.
        +##
        +##  Smears the dwords of %xmm7 by xoring the low into the
        +##  second low, result into third, result into highest.
        +##
        +##  Returns results in %xmm7 = %xmm0.
        +##  Clobbers %xmm1-%xmm4, %r11.
        +##
        +.type	_vpaes_schedule_round,\@abi-omnipotent
        +.align	16
        +_vpaes_schedule_round:
        +	# extract rcon from xmm8
        +	pxor	%xmm1,	%xmm1
        +	palignr	\$15,	%xmm8,	%xmm1
        +	palignr	\$15,	%xmm8,	%xmm8
        +	pxor	%xmm1,	%xmm7
        +
        +	# rotate
        +	pshufd	\$0xFF,	%xmm0,	%xmm0
        +	palignr	\$1,	%xmm0,	%xmm0
        +	
        +	# fall through...
        +	
        +	# low round: same as high round, but no rotation and no rcon.
        +_vpaes_schedule_low_round:
        +	# smear xmm7
        +	movdqa	%xmm7,	%xmm1
        +	pslldq	\$4,	%xmm7
        +	pxor	%xmm1,	%xmm7
        +	movdqa	%xmm7,	%xmm1
        +	pslldq	\$8,	%xmm7
        +	pxor	%xmm1,	%xmm7
        +	pxor	.Lk_s63(%rip), %xmm7
        +
        +	# subbytes
        +	movdqa  %xmm9, 	%xmm1
        +	pandn	%xmm0, 	%xmm1
        +	psrld	\$4,    %xmm1		# 1 = i
        +	pand	%xmm9, 	%xmm0		# 0 = k
        +	movdqa	%xmm11, %xmm2		# 2 : a/k
        +	pshufb  %xmm0,  %xmm2		# 2 = a/k
        +	pxor	%xmm1,	%xmm0		# 0 = j
        +	movdqa	%xmm10,	%xmm3		# 3 : 1/i
        +	pshufb  %xmm1, 	%xmm3		# 3 = 1/i
        +	pxor	%xmm2, 	%xmm3		# 3 = iak = 1/i + a/k
        +	movdqa	%xmm10,	%xmm4		# 4 : 1/j
        +	pshufb	%xmm0, 	%xmm4		# 4 = 1/j
        +	pxor	%xmm2, 	%xmm4		# 4 = jak = 1/j + a/k
        +	movdqa	%xmm10,	%xmm2		# 2 : 1/iak
        +	pshufb  %xmm3,	%xmm2		# 2 = 1/iak
        +	pxor	%xmm0, 	%xmm2		# 2 = io
        +	movdqa	%xmm10, %xmm3		# 3 : 1/jak
        +	pshufb  %xmm4,  %xmm3		# 3 = 1/jak
        +	pxor	%xmm1,  %xmm3		# 3 = jo
        +	movdqa	%xmm13, %xmm4		# 4 : sbou
        +	pshufb  %xmm2,  %xmm4		# 4 = sbou
        +	movdqa	%xmm12, %xmm0		# 0 : sbot
        +	pshufb  %xmm3,	%xmm0		# 0 = sb1t
        +	pxor	%xmm4, 	%xmm0		# 0 = sbox output
        +
        +	# add in smeared stuff
        +	pxor	%xmm7,	%xmm0	
        +	movdqa	%xmm0,	%xmm7
        +	ret
        +.size	_vpaes_schedule_round,.-_vpaes_schedule_round
        +
        +##
        +##  .aes_schedule_transform
        +##
        +##  Linear-transform %xmm0 according to tables at (%r11)
        +##
        +##  Requires that %xmm9 = 0x0F0F... as in preheat
        +##  Output in %xmm0
        +##  Clobbers %xmm1, %xmm2
        +##
        +.type	_vpaes_schedule_transform,\@abi-omnipotent
        +.align	16
        +_vpaes_schedule_transform:
        +	movdqa	%xmm9,	%xmm1
        +	pandn	%xmm0,	%xmm1
        +	psrld	\$4,	%xmm1
        +	pand	%xmm9,	%xmm0
        +	movdqa	(%r11), %xmm2 	# lo
        +	pshufb	%xmm0,	%xmm2
        +	movdqa	16(%r11), %xmm0 # hi
        +	pshufb	%xmm1,	%xmm0
        +	pxor	%xmm2,	%xmm0
        +	ret
        +.size	_vpaes_schedule_transform,.-_vpaes_schedule_transform
        +
        +##
        +##  .aes_schedule_mangle
        +##
        +##  Mangle xmm0 from (basis-transformed) standard version
        +##  to our version.
        +##
        +##  On encrypt,
        +##    xor with 0x63
        +##    multiply by circulant 0,1,1,1
        +##    apply shiftrows transform
        +##
        +##  On decrypt,
        +##    xor with 0x63
        +##    multiply by "inverse mixcolumns" circulant E,B,D,9
        +##    deskew
        +##    apply shiftrows transform
        +##
        +##
        +##  Writes out to (%rdx), and increments or decrements it
        +##  Keeps track of round number mod 4 in %r8
        +##  Preserves xmm0
        +##  Clobbers xmm1-xmm5
        +##
        +.type	_vpaes_schedule_mangle,\@abi-omnipotent
        +.align	16
        +_vpaes_schedule_mangle:
        +	movdqa	%xmm0,	%xmm4	# save xmm0 for later
        +	movdqa	.Lk_mc_forward(%rip),%xmm5
        +	test	%rcx, 	%rcx
        +	jnz	.Lschedule_mangle_dec
        +
        +	# encrypting
        +	add	\$16,	%rdx
        +	pxor	.Lk_s63(%rip),%xmm4
        +	pshufb	%xmm5,	%xmm4
        +	movdqa	%xmm4,	%xmm3
        +	pshufb	%xmm5,	%xmm4
        +	pxor	%xmm4,	%xmm3
        +	pshufb	%xmm5,	%xmm4
        +	pxor	%xmm4,	%xmm3
        +
        +	jmp	.Lschedule_mangle_both
        +.align	16
        +.Lschedule_mangle_dec:
        +	# inverse mix columns
        +	lea	.Lk_dksd(%rip),%r11
        +	movdqa	%xmm9,	%xmm1
        +	pandn	%xmm4,	%xmm1
        +	psrld	\$4,	%xmm1	# 1 = hi
        +	pand	%xmm9,	%xmm4	# 4 = lo
        +
        +	movdqa	0x00(%r11), %xmm2
        +	pshufb	%xmm4,	%xmm2
        +	movdqa	0x10(%r11), %xmm3
        +	pshufb	%xmm1,	%xmm3
        +	pxor	%xmm2,	%xmm3
        +	pshufb	%xmm5,	%xmm3
        +
        +	movdqa	0x20(%r11), %xmm2
        +	pshufb	%xmm4,	%xmm2
        +	pxor	%xmm3,	%xmm2
        +	movdqa	0x30(%r11), %xmm3
        +	pshufb	%xmm1,	%xmm3
        +	pxor	%xmm2,	%xmm3
        +	pshufb	%xmm5,	%xmm3
        +
        +	movdqa	0x40(%r11), %xmm2
        +	pshufb	%xmm4,	%xmm2
        +	pxor	%xmm3,	%xmm2
        +	movdqa	0x50(%r11), %xmm3
        +	pshufb	%xmm1,	%xmm3
        +	pxor	%xmm2,	%xmm3
        +	pshufb	%xmm5,	%xmm3
        +
        +	movdqa	0x60(%r11), %xmm2
        +	pshufb	%xmm4,	%xmm2
        +	pxor	%xmm3,	%xmm2
        +	movdqa	0x70(%r11), %xmm3
        +	pshufb	%xmm1,	%xmm3
        +	pxor	%xmm2,	%xmm3
        +
        +	add	\$-16,	%rdx
        +
        +.Lschedule_mangle_both:
        +	movdqa	(%r8,%r10),%xmm1
        +	pshufb	%xmm1,%xmm3
        +	add	\$-16,	%r8
        +	and	\$0x30,	%r8
        +	movdqu	%xmm3,	(%rdx)
        +	ret
        +.size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
        +
        +#
        +# Interface to OpenSSL
        +#
        +.globl	${PREFIX}_set_encrypt_key
        +.type	${PREFIX}_set_encrypt_key,\@function,3
        +.align	16
        +${PREFIX}_set_encrypt_key:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xb8(%rsp),%rsp
        +	movaps	%xmm6,0x10(%rsp)
        +	movaps	%xmm7,0x20(%rsp)
        +	movaps	%xmm8,0x30(%rsp)
        +	movaps	%xmm9,0x40(%rsp)
        +	movaps	%xmm10,0x50(%rsp)
        +	movaps	%xmm11,0x60(%rsp)
        +	movaps	%xmm12,0x70(%rsp)
        +	movaps	%xmm13,0x80(%rsp)
        +	movaps	%xmm14,0x90(%rsp)
        +	movaps	%xmm15,0xa0(%rsp)
        +.Lenc_key_body:
        +___
        +$code.=<<___;
        +	mov	%esi,%eax
        +	shr	\$5,%eax
        +	add	\$5,%eax
        +	mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
        +
        +	mov	\$0,%ecx
        +	mov	\$0x30,%r8d
        +	call	_vpaes_schedule_core
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x10(%rsp),%xmm6
        +	movaps	0x20(%rsp),%xmm7
        +	movaps	0x30(%rsp),%xmm8
        +	movaps	0x40(%rsp),%xmm9
        +	movaps	0x50(%rsp),%xmm10
        +	movaps	0x60(%rsp),%xmm11
        +	movaps	0x70(%rsp),%xmm12
        +	movaps	0x80(%rsp),%xmm13
        +	movaps	0x90(%rsp),%xmm14
        +	movaps	0xa0(%rsp),%xmm15
        +	lea	0xb8(%rsp),%rsp
        +.Lenc_key_epilogue:
        +___
        +$code.=<<___;
        +	xor	%eax,%eax
        +	ret
        +.size	${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
        +
        +.globl	${PREFIX}_set_decrypt_key
        +.type	${PREFIX}_set_decrypt_key,\@function,3
        +.align	16
        +${PREFIX}_set_decrypt_key:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xb8(%rsp),%rsp
        +	movaps	%xmm6,0x10(%rsp)
        +	movaps	%xmm7,0x20(%rsp)
        +	movaps	%xmm8,0x30(%rsp)
        +	movaps	%xmm9,0x40(%rsp)
        +	movaps	%xmm10,0x50(%rsp)
        +	movaps	%xmm11,0x60(%rsp)
        +	movaps	%xmm12,0x70(%rsp)
        +	movaps	%xmm13,0x80(%rsp)
        +	movaps	%xmm14,0x90(%rsp)
        +	movaps	%xmm15,0xa0(%rsp)
        +.Ldec_key_body:
        +___
        +$code.=<<___;
        +	mov	%esi,%eax
        +	shr	\$5,%eax
        +	add	\$5,%eax
        +	mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
        +	shl	\$4,%eax
        +	lea	16(%rdx,%rax),%rdx
        +
        +	mov	\$1,%ecx
        +	mov	%esi,%r8d
        +	shr	\$1,%r8d
        +	and	\$32,%r8d
        +	xor	\$32,%r8d	# nbits==192?0:32
        +	call	_vpaes_schedule_core
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x10(%rsp),%xmm6
        +	movaps	0x20(%rsp),%xmm7
        +	movaps	0x30(%rsp),%xmm8
        +	movaps	0x40(%rsp),%xmm9
        +	movaps	0x50(%rsp),%xmm10
        +	movaps	0x60(%rsp),%xmm11
        +	movaps	0x70(%rsp),%xmm12
        +	movaps	0x80(%rsp),%xmm13
        +	movaps	0x90(%rsp),%xmm14
        +	movaps	0xa0(%rsp),%xmm15
        +	lea	0xb8(%rsp),%rsp
        +.Ldec_key_epilogue:
        +___
        +$code.=<<___;
        +	xor	%eax,%eax
        +	ret
        +.size	${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
        +
        +.globl	${PREFIX}_encrypt
        +.type	${PREFIX}_encrypt,\@function,3
        +.align	16
        +${PREFIX}_encrypt:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xb8(%rsp),%rsp
        +	movaps	%xmm6,0x10(%rsp)
        +	movaps	%xmm7,0x20(%rsp)
        +	movaps	%xmm8,0x30(%rsp)
        +	movaps	%xmm9,0x40(%rsp)
        +	movaps	%xmm10,0x50(%rsp)
        +	movaps	%xmm11,0x60(%rsp)
        +	movaps	%xmm12,0x70(%rsp)
        +	movaps	%xmm13,0x80(%rsp)
        +	movaps	%xmm14,0x90(%rsp)
        +	movaps	%xmm15,0xa0(%rsp)
        +.Lenc_body:
        +___
        +$code.=<<___;
        +	movdqu	(%rdi),%xmm0
        +	call	_vpaes_preheat
        +	call	_vpaes_encrypt_core
        +	movdqu	%xmm0,(%rsi)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x10(%rsp),%xmm6
        +	movaps	0x20(%rsp),%xmm7
        +	movaps	0x30(%rsp),%xmm8
        +	movaps	0x40(%rsp),%xmm9
        +	movaps	0x50(%rsp),%xmm10
        +	movaps	0x60(%rsp),%xmm11
        +	movaps	0x70(%rsp),%xmm12
        +	movaps	0x80(%rsp),%xmm13
        +	movaps	0x90(%rsp),%xmm14
        +	movaps	0xa0(%rsp),%xmm15
        +	lea	0xb8(%rsp),%rsp
        +.Lenc_epilogue:
        +___
        +$code.=<<___;
        +	ret
        +.size	${PREFIX}_encrypt,.-${PREFIX}_encrypt
        +
        +.globl	${PREFIX}_decrypt
        +.type	${PREFIX}_decrypt,\@function,3
        +.align	16
        +${PREFIX}_decrypt:
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xb8(%rsp),%rsp
        +	movaps	%xmm6,0x10(%rsp)
        +	movaps	%xmm7,0x20(%rsp)
        +	movaps	%xmm8,0x30(%rsp)
        +	movaps	%xmm9,0x40(%rsp)
        +	movaps	%xmm10,0x50(%rsp)
        +	movaps	%xmm11,0x60(%rsp)
        +	movaps	%xmm12,0x70(%rsp)
        +	movaps	%xmm13,0x80(%rsp)
        +	movaps	%xmm14,0x90(%rsp)
        +	movaps	%xmm15,0xa0(%rsp)
        +.Ldec_body:
        +___
        +$code.=<<___;
        +	movdqu	(%rdi),%xmm0
        +	call	_vpaes_preheat
        +	call	_vpaes_decrypt_core
        +	movdqu	%xmm0,(%rsi)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x10(%rsp),%xmm6
        +	movaps	0x20(%rsp),%xmm7
        +	movaps	0x30(%rsp),%xmm8
        +	movaps	0x40(%rsp),%xmm9
        +	movaps	0x50(%rsp),%xmm10
        +	movaps	0x60(%rsp),%xmm11
        +	movaps	0x70(%rsp),%xmm12
        +	movaps	0x80(%rsp),%xmm13
        +	movaps	0x90(%rsp),%xmm14
        +	movaps	0xa0(%rsp),%xmm15
        +	lea	0xb8(%rsp),%rsp
        +.Ldec_epilogue:
        +___
        +$code.=<<___;
        +	ret
        +.size	${PREFIX}_decrypt,.-${PREFIX}_decrypt
        +___
        +{
        +my ($inp,$out,$len,$key,$ivp,$enc)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
        +# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
        +#                       size_t length, const AES_KEY *key,
        +#                       unsigned char *ivp,const int enc);
        +$code.=<<___;
        +.globl	${PREFIX}_cbc_encrypt
        +.type	${PREFIX}_cbc_encrypt,\@function,6
        +.align	16
        +${PREFIX}_cbc_encrypt:
        +	xchg	$key,$len
        +___
        +($len,$key)=($key,$len);
        +$code.=<<___;
        +	sub	\$16,$len
        +	jc	.Lcbc_abort
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0xb8(%rsp),%rsp
        +	movaps	%xmm6,0x10(%rsp)
        +	movaps	%xmm7,0x20(%rsp)
        +	movaps	%xmm8,0x30(%rsp)
        +	movaps	%xmm9,0x40(%rsp)
        +	movaps	%xmm10,0x50(%rsp)
        +	movaps	%xmm11,0x60(%rsp)
        +	movaps	%xmm12,0x70(%rsp)
        +	movaps	%xmm13,0x80(%rsp)
        +	movaps	%xmm14,0x90(%rsp)
        +	movaps	%xmm15,0xa0(%rsp)
        +.Lcbc_body:
        +___
        +$code.=<<___;
        +	movdqu	($ivp),%xmm6		# load IV
        +	sub	$inp,$out
        +	call	_vpaes_preheat
        +	cmp	\$0,${enc}d
        +	je	.Lcbc_dec_loop
        +	jmp	.Lcbc_enc_loop
        +.align	16
        +.Lcbc_enc_loop:
        +	movdqu	($inp),%xmm0
        +	pxor	%xmm6,%xmm0
        +	call	_vpaes_encrypt_core
        +	movdqa	%xmm0,%xmm6
        +	movdqu	%xmm0,($out,$inp)
        +	lea	16($inp),$inp
        +	sub	\$16,$len
        +	jnc	.Lcbc_enc_loop
        +	jmp	.Lcbc_done
        +.align	16
        +.Lcbc_dec_loop:
        +	movdqu	($inp),%xmm0
        +	movdqa	%xmm0,%xmm7
        +	call	_vpaes_decrypt_core
        +	pxor	%xmm6,%xmm0
        +	movdqa	%xmm7,%xmm6
        +	movdqu	%xmm0,($out,$inp)
        +	lea	16($inp),$inp
        +	sub	\$16,$len
        +	jnc	.Lcbc_dec_loop
        +.Lcbc_done:
        +	movdqu	%xmm6,($ivp)		# save IV
        +___
        +$code.=<<___ if ($win64);
        +	movaps	0x10(%rsp),%xmm6
        +	movaps	0x20(%rsp),%xmm7
        +	movaps	0x30(%rsp),%xmm8
        +	movaps	0x40(%rsp),%xmm9
        +	movaps	0x50(%rsp),%xmm10
        +	movaps	0x60(%rsp),%xmm11
        +	movaps	0x70(%rsp),%xmm12
        +	movaps	0x80(%rsp),%xmm13
        +	movaps	0x90(%rsp),%xmm14
        +	movaps	0xa0(%rsp),%xmm15
        +	lea	0xb8(%rsp),%rsp
        +.Lcbc_epilogue:
        +___
        +$code.=<<___;
        +.Lcbc_abort:
        +	ret
        +.size	${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
        +___
        +}
        +$code.=<<___;
        +##
        +##  _aes_preheat
        +##
        +##  Fills register %r10 -> .aes_consts (so you can -fPIC)
        +##  and %xmm9-%xmm15 as specified below.
        +##
        +.type	_vpaes_preheat,\@abi-omnipotent
        +.align	16
        +_vpaes_preheat:
        +	lea	.Lk_s0F(%rip), %r10
        +	movdqa	-0x20(%r10), %xmm10	# .Lk_inv
        +	movdqa	-0x10(%r10), %xmm11	# .Lk_inv+16
        +	movdqa	0x00(%r10), %xmm9	# .Lk_s0F
        +	movdqa	0x30(%r10), %xmm13	# .Lk_sb1
        +	movdqa	0x40(%r10), %xmm12	# .Lk_sb1+16
        +	movdqa	0x50(%r10), %xmm15	# .Lk_sb2
        +	movdqa	0x60(%r10), %xmm14	# .Lk_sb2+16
        +	ret
        +.size	_vpaes_preheat,.-_vpaes_preheat
        +########################################################
        +##                                                    ##
        +##                     Constants                      ##
        +##                                                    ##
        +########################################################
        +.type	_vpaes_consts,\@object
        +.align	64
        +_vpaes_consts:
        +.Lk_inv:	# inv, inva
        +	.quad	0x0E05060F0D080180, 0x040703090A0B0C02
        +	.quad	0x01040A060F0B0780, 0x030D0E0C02050809
        +
        +.Lk_s0F:	# s0F
        +	.quad	0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
        +
        +.Lk_ipt:	# input transform (lo, hi)
        +	.quad	0xC2B2E8985A2A7000, 0xCABAE09052227808
        +	.quad	0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
        +
        +.Lk_sb1:	# sb1u, sb1t
        +	.quad	0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
        +	.quad	0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
        +.Lk_sb2:	# sb2u, sb2t
        +	.quad	0xE27A93C60B712400, 0x5EB7E955BC982FCD
        +	.quad	0x69EB88400AE12900, 0xC2A163C8AB82234A
        +.Lk_sbo:	# sbou, sbot
        +	.quad	0xD0D26D176FBDC700, 0x15AABF7AC502A878
        +	.quad	0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
        +
        +.Lk_mc_forward:	# mc_forward
        +	.quad	0x0407060500030201, 0x0C0F0E0D080B0A09
        +	.quad	0x080B0A0904070605, 0x000302010C0F0E0D
        +	.quad	0x0C0F0E0D080B0A09, 0x0407060500030201
        +	.quad	0x000302010C0F0E0D, 0x080B0A0904070605
        +
        +.Lk_mc_backward:# mc_backward
        +	.quad	0x0605040702010003, 0x0E0D0C0F0A09080B
        +	.quad	0x020100030E0D0C0F, 0x0A09080B06050407
        +	.quad	0x0E0D0C0F0A09080B, 0x0605040702010003
        +	.quad	0x0A09080B06050407, 0x020100030E0D0C0F
        +
        +.Lk_sr:		# sr
        +	.quad	0x0706050403020100, 0x0F0E0D0C0B0A0908
        +	.quad	0x030E09040F0A0500, 0x0B06010C07020D08
        +	.quad	0x0F060D040B020900, 0x070E050C030A0108
        +	.quad	0x0B0E0104070A0D00, 0x0306090C0F020508
        +
        +.Lk_rcon:	# rcon
        +	.quad	0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
        +
        +.Lk_s63:	# s63: all equal to 0x63 transformed
        +	.quad	0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
        +
        +.Lk_opt:	# output transform
        +	.quad	0xFF9F4929D6B66000, 0xF7974121DEBE6808
        +	.quad	0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
        +
        +.Lk_deskew:	# deskew tables: inverts the sbox's "skew"
        +	.quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
        +	.quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
        +
        +##
        +##  Decryption stuff
        +##  Key schedule constants
        +##
        +.Lk_dksd:	# decryption key schedule: invskew x*D
        +	.quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
        +	.quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
        +.Lk_dksb:	# decryption key schedule: invskew x*B
        +	.quad	0x9A4FCA1F8550D500, 0x03D653861CC94C99
        +	.quad	0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
        +.Lk_dkse:	# decryption key schedule: invskew x*E + 0x63
        +	.quad	0xD5031CCA1FC9D600, 0x53859A4C994F5086
        +	.quad	0xA23196054FDC7BE8, 0xCD5EF96A20B31487
        +.Lk_dks9:	# decryption key schedule: invskew x*9
        +	.quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
        +	.quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
        +
        +##
        +##  Decryption stuff
        +##  Round function constants
        +##
        +.Lk_dipt:	# decryption input transform
        +	.quad	0x0F505B040B545F00, 0x154A411E114E451A
        +	.quad	0x86E383E660056500, 0x12771772F491F194
        +
        +.Lk_dsb9:	# decryption sbox output *9*u, *9*t
        +	.quad	0x851C03539A86D600, 0xCAD51F504F994CC9
        +	.quad	0xC03B1789ECD74900, 0x725E2C9EB2FBA565
        +.Lk_dsbd:	# decryption sbox output *D*u, *D*t
        +	.quad	0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
        +	.quad	0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
        +.Lk_dsbb:	# decryption sbox output *B*u, *B*t
        +	.quad	0xD022649296B44200, 0x602646F6B0F2D404
        +	.quad	0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
        +.Lk_dsbe:	# decryption sbox output *E*u, *E*t
        +	.quad	0x46F2929626D4D000, 0x2242600464B4F6B0
        +	.quad	0x0C55A6CDFFAAC100, 0x9467F36B98593E32
        +.Lk_dsbo:	# decryption sbox final output
        +	.quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
        +	.quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
        +.asciz	"Vector Permutaion AES for x86_64/SSSE3, Mike Hamburg (Stanford University)"
        +.align	64
        +.size	_vpaes_consts,.-_vpaes_consts
        +___
        +
        +if ($win64) {
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_prologue
        +
        +	lea	16(%rax),%rsi		# %xmm save area
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	0xb8(%rax),%rax		# adjust stack pointer
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_${PREFIX}_set_encrypt_key
        +	.rva	.LSEH_end_${PREFIX}_set_encrypt_key
        +	.rva	.LSEH_info_${PREFIX}_set_encrypt_key
        +
        +	.rva	.LSEH_begin_${PREFIX}_set_decrypt_key
        +	.rva	.LSEH_end_${PREFIX}_set_decrypt_key
        +	.rva	.LSEH_info_${PREFIX}_set_decrypt_key
        +
        +	.rva	.LSEH_begin_${PREFIX}_encrypt
        +	.rva	.LSEH_end_${PREFIX}_encrypt
        +	.rva	.LSEH_info_${PREFIX}_encrypt
        +
        +	.rva	.LSEH_begin_${PREFIX}_decrypt
        +	.rva	.LSEH_end_${PREFIX}_decrypt
        +	.rva	.LSEH_info_${PREFIX}_decrypt
        +
        +	.rva	.LSEH_begin_${PREFIX}_cbc_encrypt
        +	.rva	.LSEH_end_${PREFIX}_cbc_encrypt
        +	.rva	.LSEH_info_${PREFIX}_cbc_encrypt
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_${PREFIX}_set_encrypt_key:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lenc_key_body,.Lenc_key_epilogue	# HandlerData[]
        +.LSEH_info_${PREFIX}_set_decrypt_key:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Ldec_key_body,.Ldec_key_epilogue	# HandlerData[]
        +.LSEH_info_${PREFIX}_encrypt:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lenc_body,.Lenc_epilogue		# HandlerData[]
        +.LSEH_info_${PREFIX}_decrypt:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Ldec_body,.Ldec_epilogue		# HandlerData[]
        +.LSEH_info_${PREFIX}_cbc_encrypt:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lcbc_body,.Lcbc_epilogue		# HandlerData[]
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/alphacpuid.pl b/vendor/openssl/openssl/crypto/alphacpuid.pl
        new file mode 100644
        index 000000000..4b3cbb982
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/alphacpuid.pl
        @@ -0,0 +1,126 @@
        +#!/usr/bin/env perl
        +print <<'___';
        +.text
        +
        +.set	noat
        +
        +.globl	OPENSSL_cpuid_setup
        +.ent	OPENSSL_cpuid_setup
        +OPENSSL_cpuid_setup:
        +	.frame	$30,0,$26
        +	.prologue 0
        +	ret	($26)
        +.end	OPENSSL_cpuid_setup
        +
        +.globl	OPENSSL_wipe_cpu
        +.ent	OPENSSL_wipe_cpu
        +OPENSSL_wipe_cpu:
        +	.frame	$30,0,$26
        +	.prologue 0
        +	clr	$1
        +	clr	$2
        +	clr	$3
        +	clr	$4
        +	clr	$5
        +	clr	$6
        +	clr	$7
        +	clr	$8
        +	clr	$16
        +	clr	$17
        +	clr	$18
        +	clr	$19
        +	clr	$20
        +	clr	$21
        +	clr	$22
        +	clr	$23
        +	clr	$24
        +	clr	$25
        +	clr	$27
        +	clr	$at
        +	clr	$29
        +	fclr	$f0
        +	fclr	$f1
        +	fclr	$f10
        +	fclr	$f11
        +	fclr	$f12
        +	fclr	$f13
        +	fclr	$f14
        +	fclr	$f15
        +	fclr	$f16
        +	fclr	$f17
        +	fclr	$f18
        +	fclr	$f19
        +	fclr	$f20
        +	fclr	$f21
        +	fclr	$f22
        +	fclr	$f23
        +	fclr	$f24
        +	fclr	$f25
        +	fclr	$f26
        +	fclr	$f27
        +	fclr	$f28
        +	fclr	$f29
        +	fclr	$f30
        +	mov	$sp,$0
        +	ret	($26)
        +.end	OPENSSL_wipe_cpu
        +
        +.globl	OPENSSL_atomic_add
        +.ent	OPENSSL_atomic_add
        +OPENSSL_atomic_add:
        +	.frame	$30,0,$26
        +	.prologue 0
        +1:	ldl_l	$0,0($16)
        +	addl	$0,$17,$1
        +	stl_c	$1,0($16)
        +	beq	$1,1b
        +	addl	$0,$17,$0
        +	ret	($26)
        +.end	OPENSSL_atomic_add
        +
        +.globl	OPENSSL_rdtsc
        +.ent	OPENSSL_rdtsc
        +OPENSSL_rdtsc:
        +	.frame	$30,0,$26
        +	.prologue 0
        +	rpcc	$0
        +	ret	($26)
        +.end	OPENSSL_rdtsc
        +
        +.globl	OPENSSL_cleanse
        +.ent	OPENSSL_cleanse
        +OPENSSL_cleanse:
        +	.frame	$30,0,$26
        +	.prologue 0
        +	beq	$17,.Ldone
        +	and	$16,7,$0
        +	bic	$17,7,$at
        +	beq	$at,.Little
        +	beq	$0,.Laligned
        +
        +.Little:
        +	subq	$0,8,$0
        +	ldq_u	$1,0($16)
        +	mov	$16,$2
        +.Lalign:
        +	mskbl	$1,$16,$1
        +	lda	$16,1($16)
        +	subq	$17,1,$17
        +	addq	$0,1,$0
        +	beq	$17,.Lout
        +	bne	$0,.Lalign
        +.Lout:	stq_u	$1,0($2)
        +	beq	$17,.Ldone
        +	bic	$17,7,$at
        +	beq	$at,.Little
        +
        +.Laligned:
        +	stq	$31,0($16)
        +	subq	$17,8,$17
        +	lda	$16,8($16)
        +	bic	$17,7,$at
        +	bne	$at,.Laligned
        +	bne	$17,.Little
        +.Ldone: ret	($26)
        +.end	OPENSSL_cleanse
        +___
        diff --git a/vendor/openssl/openssl/crypto/arm_arch.h b/vendor/openssl/openssl/crypto/arm_arch.h
        new file mode 100644
        index 000000000..5a8310768
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/arm_arch.h
        @@ -0,0 +1,51 @@
        +#ifndef __ARM_ARCH_H__
        +#define __ARM_ARCH_H__
        +
        +#if !defined(__ARM_ARCH__)
        +# if defined(__CC_ARM)
        +#  define __ARM_ARCH__ __TARGET_ARCH_ARM
        +#  if defined(__BIG_ENDIAN)
        +#   define __ARMEB__
        +#  else
        +#   define __ARMEL__
        +#  endif
        +# elif defined(__GNUC__)
        +  /*
        +   * Why doesn't gcc define __ARM_ARCH__? Instead it defines
        +   * bunch of below macros. See all_architectires[] table in
        +   * gcc/config/arm/arm.c. On a side note it defines
        +   * __ARMEL__/__ARMEB__ for little-/big-endian.
        +   */
        +#  if	defined(__ARM_ARCH_7__)	|| defined(__ARM_ARCH_7A__)	|| \
        +	defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__)	|| \
        +	defined(__ARM_ARCH_7EM__)
        +#   define __ARM_ARCH__ 7
        +#  elif	defined(__ARM_ARCH_6__)	|| defined(__ARM_ARCH_6J__)	|| \
        +	defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__)	|| \
        +	defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__)	|| \
        +	defined(__ARM_ARCH_6T2__)
        +#   define __ARM_ARCH__ 6
        +#  elif	defined(__ARM_ARCH_5__)	|| defined(__ARM_ARCH_5T__)	|| \
        +	defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__)	|| \
        +	defined(__ARM_ARCH_5TEJ__)
        +#   define __ARM_ARCH__ 5
        +#  elif	defined(__ARM_ARCH_4__)	|| defined(__ARM_ARCH_4T__)
        +#   define __ARM_ARCH__ 4
        +#  else
        +#   error "unsupported ARM architecture"
        +#  endif
        +# endif
        +#endif
        +
        +#ifdef OPENSSL_FIPSCANISTER
        +#include <openssl/fipssyms.h>
        +#endif
        +
        +#if !__ASSEMBLER__
        +extern unsigned int OPENSSL_armcap_P;
        +                                     
        +#define ARMV7_NEON      (1<<0)
        +#define ARMV7_TICK      (1<<1)
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/armcap.c b/vendor/openssl/openssl/crypto/armcap.c
        new file mode 100644
        index 000000000..5258d2fbd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/armcap.c
        @@ -0,0 +1,80 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <setjmp.h>
        +#include <signal.h>
        +#include <crypto.h>
        +
        +#include "arm_arch.h"
        +
        +unsigned int OPENSSL_armcap_P;
        +
        +static sigset_t all_masked;
        +
        +static sigjmp_buf ill_jmp;
        +static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
        +
        +/*
        + * Following subroutines could have been inlined, but it's not all
        + * ARM compilers support inline assembler...
        + */
        +void _armv7_neon_probe(void);
        +unsigned int _armv7_tick(void);
        +
        +unsigned int OPENSSL_rdtsc(void)
        +	{
        +	if (OPENSSL_armcap_P|ARMV7_TICK)
        +		return _armv7_tick();
        +	else
        +		return 0;
        +	}
        +
        +#if defined(__GNUC__) && __GNUC__>=2
        +void OPENSSL_cpuid_setup(void) __attribute__((constructor));
        +#endif
        +void OPENSSL_cpuid_setup(void)
        +	{
        +	char *e;
        +	struct sigaction	ill_oact,ill_act;
        +	sigset_t		oset;
        +	static int trigger=0;
        +
        +	if (trigger) return;
        +	trigger=1;
        + 
        +	if ((e=getenv("OPENSSL_armcap")))
        +		{
        +		OPENSSL_armcap_P=strtoul(e,NULL,0);
        +		return;
        +		}
        +
        +	sigfillset(&all_masked);
        +	sigdelset(&all_masked,SIGILL);
        +	sigdelset(&all_masked,SIGTRAP);
        +	sigdelset(&all_masked,SIGFPE);
        +	sigdelset(&all_masked,SIGBUS);
        +	sigdelset(&all_masked,SIGSEGV);
        +
        +	OPENSSL_armcap_P = 0;
        +
        +	memset(&ill_act,0,sizeof(ill_act));
        +	ill_act.sa_handler = ill_handler;
        +	ill_act.sa_mask    = all_masked;
        +
        +	sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
        +	sigaction(SIGILL,&ill_act,&ill_oact);
        +
        +	if (sigsetjmp(ill_jmp,1) == 0)
        +		{
        +		_armv7_neon_probe();
        +		OPENSSL_armcap_P |= ARMV7_NEON;
        +		}
        +	if (sigsetjmp(ill_jmp,1) == 0)
        +		{
        +		_armv7_tick();
        +		OPENSSL_armcap_P |= ARMV7_TICK;
        +		}
        +
        +	sigaction (SIGILL,&ill_oact,NULL);
        +	sigprocmask(SIG_SETMASK,&oset,NULL);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/armv4cpuid.S b/vendor/openssl/openssl/crypto/armv4cpuid.S
        new file mode 100644
        index 000000000..2d618deaa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/armv4cpuid.S
        @@ -0,0 +1,154 @@
        +#include "arm_arch.h"
        +
        +.text
        +.code	32
        +
        +.align	5
        +.global	_armv7_neon_probe
        +.type	_armv7_neon_probe,%function
        +_armv7_neon_probe:
        +	.word	0xf26ee1fe	@ vorr	q15,q15,q15
        +	.word	0xe12fff1e	@ bx	lr
        +.size	_armv7_neon_probe,.-_armv7_neon_probe
        +
        +.global	_armv7_tick
        +.type	_armv7_tick,%function
        +_armv7_tick:
        +	mrc	p15,0,r0,c9,c13,0
        +	.word	0xe12fff1e	@ bx	lr
        +.size	_armv7_tick,.-_armv7_tick
        +
        +.global	OPENSSL_atomic_add
        +.type	OPENSSL_atomic_add,%function
        +OPENSSL_atomic_add:
        +#if __ARM_ARCH__>=6
        +.Ladd:	ldrex	r2,[r0]
        +	add	r3,r2,r1
        +	strex	r2,r3,[r0]
        +	cmp	r2,#0
        +	bne	.Ladd
        +	mov	r0,r3
        +	.word	0xe12fff1e	@ bx	lr
        +#else
        +	stmdb	sp!,{r4-r6,lr}
        +	ldr	r2,.Lspinlock
        +	adr	r3,.Lspinlock
        +	mov	r4,r0
        +	mov	r5,r1
        +	add	r6,r3,r2	@ &spinlock
        +	b	.+8
        +.Lspin:	bl	sched_yield
        +	mov	r0,#-1
        +	swp	r0,r0,[r6]
        +	cmp	r0,#0
        +	bne	.Lspin
        +
        +	ldr	r2,[r4]
        +	add	r2,r2,r5
        +	str	r2,[r4]
        +	str	r0,[r6]		@ release spinlock
        +	ldmia	sp!,{r4-r6,lr}
        +	tst	lr,#1
        +	moveq	pc,lr
        +	.word	0xe12fff1e	@ bx	lr
        +#endif
        +.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
        +
        +.global	OPENSSL_cleanse
        +.type	OPENSSL_cleanse,%function
        +OPENSSL_cleanse:
        +	eor	ip,ip,ip
        +	cmp	r1,#7
        +	subhs	r1,r1,#4
        +	bhs	.Lot
        +	cmp	r1,#0
        +	beq	.Lcleanse_done
        +.Little:
        +	strb	ip,[r0],#1
        +	subs	r1,r1,#1
        +	bhi	.Little
        +	b	.Lcleanse_done
        +
        +.Lot:	tst	r0,#3
        +	beq	.Laligned
        +	strb	ip,[r0],#1
        +	sub	r1,r1,#1
        +	b	.Lot
        +.Laligned:
        +	str	ip,[r0],#4
        +	subs	r1,r1,#4
        +	bhs	.Laligned
        +	adds	r1,r1,#4
        +	bne	.Little
        +.Lcleanse_done:
        +	tst	lr,#1
        +	moveq	pc,lr
        +	.word	0xe12fff1e	@ bx	lr
        +.size	OPENSSL_cleanse,.-OPENSSL_cleanse
        +
        +.global	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,%function
        +OPENSSL_wipe_cpu:
        +	ldr	r0,.LOPENSSL_armcap
        +	adr	r1,.LOPENSSL_armcap
        +	ldr	r0,[r1,r0]
        +	eor	r2,r2,r2
        +	eor	r3,r3,r3
        +	eor	ip,ip,ip
        +	tst	r0,#1
        +	beq	.Lwipe_done
        +	.word	0xf3000150	@ veor    q0, q0, q0
        +	.word	0xf3022152	@ veor    q1, q1, q1
        +	.word	0xf3044154	@ veor    q2, q2, q2
        +	.word	0xf3066156	@ veor    q3, q3, q3
        +	.word	0xf34001f0	@ veor    q8, q8, q8
        +	.word	0xf34221f2	@ veor    q9, q9, q9
        +	.word	0xf34441f4	@ veor    q10, q10, q10
        +	.word	0xf34661f6	@ veor    q11, q11, q11
        +	.word	0xf34881f8	@ veor    q12, q12, q12
        +	.word	0xf34aa1fa	@ veor    q13, q13, q13
        +	.word	0xf34cc1fc	@ veor    q14, q14, q14
        +	.word	0xf34ee1fe	@ veor    q15, q15, q15
        +.Lwipe_done:
        +	mov	r0,sp
        +	tst	lr,#1
        +	moveq	pc,lr
        +	.word	0xe12fff1e	@ bx	lr
        +.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
        +
        +.global	OPENSSL_instrument_bus
        +.type	OPENSSL_instrument_bus,%function
        +OPENSSL_instrument_bus:
        +	eor	r0,r0,r0
        +	tst	lr,#1
        +	moveq	pc,lr
        +	.word	0xe12fff1e	@ bx	lr
        +.size	OPENSSL_instrument_bus,.-OPENSSL_instrument_bus
        +
        +.global	OPENSSL_instrument_bus2
        +.type	OPENSSL_instrument_bus2,%function
        +OPENSSL_instrument_bus2:
        +	eor	r0,r0,r0
        +	tst	lr,#1
        +	moveq	pc,lr
        +	.word	0xe12fff1e	@ bx	lr
        +.size	OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2
        +
        +.align	5
        +.LOPENSSL_armcap:
        +.word	OPENSSL_armcap_P-.LOPENSSL_armcap
        +#if __ARM_ARCH__>=6
        +.align	5
        +#else
        +.Lspinlock:
        +.word	atomic_add_spinlock-.Lspinlock
        +.align	5
        +
        +.data
        +.align	2
        +atomic_add_spinlock:
        +.word	0
        +#endif
        +
        +.comm	OPENSSL_armcap_P,4,4
        +.hidden	OPENSSL_armcap_P
        diff --git a/vendor/openssl/openssl/crypto/asn1/Makefile b/vendor/openssl/openssl/crypto/asn1/Makefile
        new file mode 100644
        index 000000000..f7787005d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/Makefile
        @@ -0,0 +1,930 @@
        +#
        +# OpenSSL/crypto/asn1/Makefile
        +#
        +
        +DIR=	asn1
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
        +	a_print.c a_type.c a_set.c a_dup.c a_d2i_fp.c a_i2d_fp.c \
        +	a_enum.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c \
        +	x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c x_bignum.c \
        +	x_long.c x_name.c x_x509.c x_x509a.c x_crl.c x_info.c x_spki.c nsseq.c \
        +	x_nx509.c d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
        +	t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.c \
        +	tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
        +	tasn_prn.c ameth_lib.c \
        +	f_int.c f_string.c n_pkey.c \
        +	f_enum.c x_pkey.c a_bool.c x_exten.c bio_asn1.c bio_ndef.c asn_mime.c \
        +	asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_bytes.c a_strnid.c \
        +	evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c
        +LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
        +	a_print.o a_type.o a_set.o a_dup.o a_d2i_fp.o a_i2d_fp.o \
        +	a_enum.o a_utf8.o a_sign.o a_digest.o a_verify.o a_mbstr.o a_strex.o \
        +	x_algor.o x_val.o x_pubkey.o x_sig.o x_req.o x_attrib.o x_bignum.o \
        +	x_long.o x_name.o x_x509.o x_x509a.o x_crl.o x_info.o x_spki.o nsseq.o \
        +	x_nx509.o d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
        +	t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.o \
        +	tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o tasn_typ.o \
        +	tasn_prn.o ameth_lib.o \
        +	f_int.o f_string.o n_pkey.o \
        +	f_enum.o x_pkey.o a_bool.o x_exten.o bio_asn1.o bio_ndef.o asn_mime.o \
        +	asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_bytes.o a_strnid.o \
        +	evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o asn_moid.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER=  asn1.h asn1_mac.h asn1t.h
        +HEADER=	$(EXHEADER) asn1_locl.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +test:	test.c
        +	cc -g -I../../include -c test.c
        +	cc -g -I../../include -o test test.o -L../.. -lcrypto
        +
        +pk:	pk.c
        +	cc -g -I../../include -c pk.c
        +	cc -g -I../../include -o pk pk.o -L../.. -lcrypto
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by top Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +a_bitstr.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_bitstr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_bitstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_bitstr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_bitstr.o: ../../include/openssl/opensslconf.h
        +a_bitstr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_bitstr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_bitstr.o: ../../include/openssl/symhacks.h ../cryptlib.h a_bitstr.c
        +a_bool.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_bool.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +a_bool.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_bool.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_bool.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +a_bool.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_bool.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_bool.o: ../../include/openssl/symhacks.h ../cryptlib.h a_bool.c
        +a_bytes.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_bytes.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_bytes.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_bytes.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_bytes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_bytes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_bytes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_bytes.o: ../cryptlib.h a_bytes.c
        +a_d2i_fp.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_d2i_fp.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
        +a_d2i_fp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_d2i_fp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_d2i_fp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +a_d2i_fp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_d2i_fp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_d2i_fp.o: ../../include/openssl/symhacks.h ../cryptlib.h a_d2i_fp.c
        +a_digest.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +a_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +a_digest.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +a_digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +a_digest.o: ../../include/openssl/opensslconf.h
        +a_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +a_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +a_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +a_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_digest.c
        +a_dup.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +a_dup.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_dup.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_dup.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +a_dup.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_dup.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_dup.o: ../../include/openssl/symhacks.h ../cryptlib.h a_dup.c
        +a_enum.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +a_enum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +a_enum.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_enum.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_enum.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_enum.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_enum.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_enum.o: ../cryptlib.h a_enum.c
        +a_gentm.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_gentm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_gentm.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_gentm.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_gentm.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_gentm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_gentm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_gentm.o: ../cryptlib.h ../o_time.h a_gentm.c
        +a_i2d_fp.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_i2d_fp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_i2d_fp.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_i2d_fp.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_i2d_fp.o: ../../include/openssl/opensslconf.h
        +a_i2d_fp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_i2d_fp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_i2d_fp.o: ../../include/openssl/symhacks.h ../cryptlib.h a_i2d_fp.c
        +a_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +a_int.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +a_int.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_int.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_int.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_int.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_int.o: ../cryptlib.h a_int.c
        +a_mbstr.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_mbstr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_mbstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_mbstr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_mbstr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_mbstr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_mbstr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_mbstr.o: ../cryptlib.h a_mbstr.c
        +a_object.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_object.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +a_object.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_object.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_object.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +a_object.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +a_object.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_object.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_object.o: ../../include/openssl/symhacks.h ../cryptlib.h a_object.c
        +a_octet.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_octet.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_octet.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_octet.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_octet.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_octet.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_octet.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_octet.o: ../cryptlib.h a_octet.c
        +a_print.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_print.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_print.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_print.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_print.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_print.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_print.o: ../cryptlib.h a_print.c
        +a_set.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_set.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
        +a_set.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_set.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_set.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +a_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_set.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_set.o: ../../include/openssl/symhacks.h ../cryptlib.h a_set.c
        +a_sign.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +a_sign.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +a_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +a_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +a_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +a_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +a_sign.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +a_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +a_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +a_sign.o: ../cryptlib.h a_sign.c asn1_locl.h
        +a_strex.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_strex.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_strex.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_strex.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +a_strex.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +a_strex.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +a_strex.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +a_strex.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_strex.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +a_strex.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +a_strex.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_strex.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +a_strex.o: ../cryptlib.h a_strex.c charmap.h
        +a_strnid.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_strnid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_strnid.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_strnid.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_strnid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +a_strnid.o: ../../include/openssl/opensslconf.h
        +a_strnid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_strnid.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_strnid.o: ../../include/openssl/symhacks.h ../cryptlib.h a_strnid.c
        +a_time.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_time.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +a_time.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_time.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_time.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +a_time.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_time.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_time.o: ../../include/openssl/symhacks.h ../cryptlib.h ../o_time.h a_time.c
        +a_type.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_type.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +a_type.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_type.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_type.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +a_type.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +a_type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_type.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_type.o: ../../include/openssl/symhacks.h ../cryptlib.h a_type.c
        +a_utctm.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_utctm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +a_utctm.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +a_utctm.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +a_utctm.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +a_utctm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +a_utctm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +a_utctm.o: ../cryptlib.h ../o_time.h a_utctm.c
        +a_utf8.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +a_utf8.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_utf8.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +a_utf8.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +a_utf8.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_utf8.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +a_utf8.o: ../../include/openssl/symhacks.h ../cryptlib.h a_utf8.c
        +a_verify.o: ../../e_os.h ../../include/openssl/asn1.h
        +a_verify.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +a_verify.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +a_verify.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +a_verify.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +a_verify.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +a_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +a_verify.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +a_verify.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +a_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +a_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +a_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +a_verify.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_verify.c
        +a_verify.o: asn1_locl.h
        +ameth_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +ameth_lib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +ameth_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ameth_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ameth_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ameth_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +ameth_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ameth_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ameth_lib.o: ../../include/openssl/opensslconf.h
        +ameth_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ameth_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ameth_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ameth_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ameth_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ameth_lib.c
        +ameth_lib.o: asn1_locl.h
        +asn1_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +asn1_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +asn1_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +asn1_err.o: ../../include/openssl/opensslconf.h
        +asn1_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn1_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +asn1_err.o: ../../include/openssl/symhacks.h asn1_err.c
        +asn1_gen.o: ../../e_os.h ../../include/openssl/asn1.h
        +asn1_gen.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +asn1_gen.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +asn1_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +asn1_gen.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +asn1_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +asn1_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +asn1_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +asn1_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn1_gen.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +asn1_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +asn1_gen.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +asn1_gen.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +asn1_gen.o: ../cryptlib.h asn1_gen.c
        +asn1_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +asn1_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
        +asn1_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +asn1_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +asn1_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +asn1_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn1_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +asn1_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_lib.c
        +asn1_par.o: ../../e_os.h ../../include/openssl/asn1.h
        +asn1_par.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +asn1_par.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +asn1_par.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +asn1_par.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +asn1_par.o: ../../include/openssl/opensslconf.h
        +asn1_par.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn1_par.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +asn1_par.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_par.c
        +asn_mime.o: ../../e_os.h ../../include/openssl/asn1.h
        +asn_mime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +asn_mime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +asn_mime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +asn_mime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +asn_mime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +asn_mime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +asn_mime.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +asn_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +asn_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +asn_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +asn_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +asn_mime.o: ../cryptlib.h asn1_locl.h asn_mime.c
        +asn_moid.o: ../../e_os.h ../../include/openssl/asn1.h
        +asn_moid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +asn_moid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +asn_moid.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +asn_moid.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +asn_moid.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +asn_moid.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +asn_moid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +asn_moid.o: ../../include/openssl/opensslconf.h
        +asn_moid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn_moid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +asn_moid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +asn_moid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +asn_moid.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn_moid.c
        +asn_pack.o: ../../e_os.h ../../include/openssl/asn1.h
        +asn_pack.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +asn_pack.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +asn_pack.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +asn_pack.o: ../../include/openssl/opensslconf.h
        +asn_pack.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +asn_pack.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +asn_pack.o: ../../include/openssl/symhacks.h ../cryptlib.h asn_pack.c
        +bio_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +bio_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bio_asn1.o: ../../include/openssl/opensslconf.h
        +bio_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_asn1.o: ../../include/openssl/symhacks.h bio_asn1.c
        +bio_ndef.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +bio_ndef.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +bio_ndef.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bio_ndef.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bio_ndef.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_ndef.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_ndef.o: ../../include/openssl/symhacks.h bio_ndef.c
        +d2i_pr.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +d2i_pr.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +d2i_pr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +d2i_pr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +d2i_pr.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +d2i_pr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +d2i_pr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +d2i_pr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +d2i_pr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +d2i_pr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +d2i_pr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +d2i_pr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +d2i_pr.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn1_locl.h d2i_pr.c
        +d2i_pu.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +d2i_pu.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +d2i_pu.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +d2i_pu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +d2i_pu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +d2i_pu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +d2i_pu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +d2i_pu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +d2i_pu.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +d2i_pu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +d2i_pu.o: ../cryptlib.h d2i_pu.c
        +evp_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_asn1.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
        +evp_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +evp_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +evp_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +evp_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +evp_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_asn1.c
        +f_enum.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +f_enum.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +f_enum.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +f_enum.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +f_enum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +f_enum.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +f_enum.o: ../../include/openssl/symhacks.h ../cryptlib.h f_enum.c
        +f_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +f_int.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +f_int.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +f_int.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +f_int.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +f_int.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +f_int.o: ../../include/openssl/symhacks.h ../cryptlib.h f_int.c
        +f_string.o: ../../e_os.h ../../include/openssl/asn1.h
        +f_string.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +f_string.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +f_string.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +f_string.o: ../../include/openssl/opensslconf.h
        +f_string.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +f_string.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +f_string.o: ../../include/openssl/symhacks.h ../cryptlib.h f_string.c
        +i2d_pr.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +i2d_pr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +i2d_pr.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +i2d_pr.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +i2d_pr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +i2d_pr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +i2d_pr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +i2d_pr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +i2d_pr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +i2d_pr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +i2d_pr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +i2d_pr.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn1_locl.h i2d_pr.c
        +i2d_pu.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +i2d_pu.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +i2d_pu.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +i2d_pu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +i2d_pu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +i2d_pu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +i2d_pu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +i2d_pu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +i2d_pu.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +i2d_pu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +i2d_pu.o: ../cryptlib.h i2d_pu.c
        +n_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +n_pkey.o: ../../include/openssl/asn1_mac.h ../../include/openssl/asn1t.h
        +n_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +n_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +n_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +n_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +n_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +n_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +n_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +n_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +n_pkey.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +n_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +n_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +n_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h n_pkey.c
        +nsseq.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +nsseq.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +nsseq.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +nsseq.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +nsseq.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
        +nsseq.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +nsseq.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +nsseq.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +nsseq.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +nsseq.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +nsseq.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +nsseq.o: ../../include/openssl/x509_vfy.h nsseq.c
        +p5_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
        +p5_pbe.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +p5_pbe.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p5_pbe.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p5_pbe.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p5_pbe.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p5_pbe.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p5_pbe.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p5_pbe.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p5_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +p5_pbe.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p5_pbe.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p5_pbe.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p5_pbe.o: ../cryptlib.h p5_pbe.c
        +p5_pbev2.o: ../../e_os.h ../../include/openssl/asn1.h
        +p5_pbev2.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +p5_pbev2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p5_pbev2.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p5_pbev2.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p5_pbev2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p5_pbev2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p5_pbev2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p5_pbev2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p5_pbev2.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +p5_pbev2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p5_pbev2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p5_pbev2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p5_pbev2.o: ../cryptlib.h p5_pbev2.c
        +p8_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +p8_pkey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +p8_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p8_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p8_pkey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p8_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p8_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p8_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p8_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p8_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p8_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p8_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p8_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p8_pkey.c
        +t_bitst.o: ../../e_os.h ../../include/openssl/asn1.h
        +t_bitst.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +t_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +t_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +t_bitst.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +t_bitst.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +t_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +t_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +t_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +t_bitst.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +t_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +t_bitst.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +t_bitst.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +t_bitst.o: ../cryptlib.h t_bitst.c
        +t_crl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +t_crl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +t_crl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +t_crl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +t_crl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +t_crl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +t_crl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +t_crl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +t_crl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +t_crl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +t_crl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +t_crl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +t_crl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +t_crl.o: ../cryptlib.h t_crl.c
        +t_pkey.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +t_pkey.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +t_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +t_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +t_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +t_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +t_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +t_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +t_pkey.o: ../cryptlib.h t_pkey.c
        +t_req.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +t_req.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +t_req.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +t_req.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +t_req.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +t_req.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +t_req.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +t_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +t_req.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +t_req.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +t_req.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +t_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +t_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +t_req.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +t_req.o: ../cryptlib.h t_req.c
        +t_spki.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +t_spki.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +t_spki.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +t_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +t_spki.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +t_spki.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +t_spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +t_spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +t_spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +t_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +t_spki.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +t_spki.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +t_spki.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +t_spki.o: ../cryptlib.h t_spki.c
        +t_x509.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +t_x509.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +t_x509.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +t_x509.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +t_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +t_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +t_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +t_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +t_x509.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +t_x509.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +t_x509.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +t_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +t_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +t_x509.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +t_x509.o: ../cryptlib.h asn1_locl.h t_x509.c
        +t_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
        +t_x509a.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +t_x509a.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +t_x509a.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +t_x509a.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +t_x509a.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +t_x509a.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +t_x509a.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +t_x509a.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +t_x509a.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +t_x509a.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +t_x509a.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +t_x509a.o: ../cryptlib.h t_x509a.c
        +tasn_dec.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +tasn_dec.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tasn_dec.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tasn_dec.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +tasn_dec.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +tasn_dec.o: ../../include/openssl/opensslconf.h
        +tasn_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_dec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +tasn_dec.o: ../../include/openssl/symhacks.h tasn_dec.c
        +tasn_enc.o: ../../e_os.h ../../include/openssl/asn1.h
        +tasn_enc.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +tasn_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +tasn_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +tasn_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tasn_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tasn_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +tasn_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h tasn_enc.c
        +tasn_fre.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +tasn_fre.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +tasn_fre.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
        +tasn_fre.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tasn_fre.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_fre.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +tasn_fre.o: ../../include/openssl/symhacks.h tasn_fre.c
        +tasn_new.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +tasn_new.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +tasn_new.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +tasn_new.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tasn_new.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tasn_new.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_new.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +tasn_new.o: ../../include/openssl/symhacks.h tasn_new.c
        +tasn_prn.o: ../../e_os.h ../../include/openssl/asn1.h
        +tasn_prn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +tasn_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +tasn_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tasn_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tasn_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +tasn_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +tasn_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +tasn_prn.o: ../../include/openssl/opensslconf.h
        +tasn_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_prn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tasn_prn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tasn_prn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tasn_prn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +tasn_prn.o: ../cryptlib.h asn1_locl.h tasn_prn.c
        +tasn_typ.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +tasn_typ.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +tasn_typ.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +tasn_typ.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_typ.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +tasn_typ.o: ../../include/openssl/symhacks.h tasn_typ.c
        +tasn_utl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +tasn_utl.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +tasn_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +tasn_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tasn_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tasn_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tasn_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +tasn_utl.o: ../../include/openssl/symhacks.h tasn_utl.c
        +x_algor.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +x_algor.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x_algor.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_algor.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_algor.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
        +x_algor.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_algor.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_algor.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_algor.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_algor.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_algor.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_algor.o: ../../include/openssl/x509_vfy.h x_algor.c
        +x_attrib.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_attrib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_attrib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_attrib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_attrib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_attrib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_attrib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_attrib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_attrib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_attrib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_attrib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_attrib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_attrib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_attrib.c
        +x_bignum.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_bignum.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_bignum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +x_bignum.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_bignum.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +x_bignum.o: ../../include/openssl/opensslconf.h
        +x_bignum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_bignum.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +x_bignum.o: ../../include/openssl/symhacks.h ../cryptlib.h x_bignum.c
        +x_crl.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_crl.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_crl.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +x_crl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_crl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_crl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x_crl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x_crl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x_crl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +x_crl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +x_crl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +x_crl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +x_crl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +x_crl.o: ../../include/openssl/x509v3.h ../cryptlib.h asn1_locl.h x_crl.c
        +x_exten.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +x_exten.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x_exten.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_exten.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_exten.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
        +x_exten.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_exten.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_exten.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_exten.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_exten.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_exten.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_exten.o: ../../include/openssl/x509_vfy.h x_exten.c
        +x_info.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +x_info.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_info.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_info.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_info.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_info.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_info.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_info.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_info.c
        +x_long.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_long.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_long.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +x_long.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_long.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +x_long.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +x_long.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +x_long.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +x_long.o: ../cryptlib.h x_long.c
        +x_name.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_name.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_name.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_name.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_name.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_name.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_name.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_name.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn1_locl.h x_name.c
        +x_nx509.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +x_nx509.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x_nx509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_nx509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_nx509.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
        +x_nx509.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_nx509.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_nx509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_nx509.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_nx509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_nx509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_nx509.o: ../../include/openssl/x509_vfy.h x_nx509.c
        +x_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_pkey.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
        +x_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_pkey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_pkey.c
        +x_pubkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_pubkey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_pubkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_pubkey.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +x_pubkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_pubkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x_pubkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x_pubkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x_pubkey.o: ../../include/openssl/opensslconf.h
        +x_pubkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_pubkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +x_pubkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +x_pubkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +x_pubkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +x_pubkey.o: ../cryptlib.h asn1_locl.h x_pubkey.c
        +x_req.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_req.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_req.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_req.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_req.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_req.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_req.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_req.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_req.c
        +x_sig.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_sig.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_sig.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_sig.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_sig.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_sig.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_sig.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_sig.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_sig.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_sig.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_sig.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_sig.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_sig.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_sig.c
        +x_spki.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_spki.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_spki.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_spki.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_spki.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_spki.c
        +x_val.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_val.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_val.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_val.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_val.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_val.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_val.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_val.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_val.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_val.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_val.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_val.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_val.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_val.c
        +x_x509.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_x509.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_x509.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +x_x509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x_x509.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +x_x509.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +x_x509.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +x_x509.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +x_x509.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +x_x509.o: ../../include/openssl/x509v3.h ../cryptlib.h x_x509.c
        +x_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
        +x_x509a.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x_x509a.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_x509a.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x_x509a.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x_x509a.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x_x509a.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x_x509a.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x_x509a.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x_x509a.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x_x509a.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_x509a.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_x509a.c
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_bitstr.c b/vendor/openssl/openssl/crypto/asn1/a_bitstr.c
        new file mode 100644
        index 000000000..34179960b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_bitstr.c
        @@ -0,0 +1,248 @@
        +/* crypto/asn1/a_bitstr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
        +{ return M_ASN1_BIT_STRING_set(x, d, len); }
        +
        +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
        +	{
        +	int ret,j,bits,len;
        +	unsigned char *p,*d;
        +
        +	if (a == NULL) return(0);
        +
        +	len=a->length;
        +
        +	if (len > 0)
        +		{
        +		if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
        +			{
        +			bits=(int)a->flags&0x07;
        +			}
        +		else
        +			{
        +			for ( ; len > 0; len--)
        +				{
        +				if (a->data[len-1]) break;
        +				}
        +			j=a->data[len-1];
        +			if      (j & 0x01) bits=0;
        +			else if (j & 0x02) bits=1;
        +			else if (j & 0x04) bits=2;
        +			else if (j & 0x08) bits=3;
        +			else if (j & 0x10) bits=4;
        +			else if (j & 0x20) bits=5;
        +			else if (j & 0x40) bits=6;
        +			else if (j & 0x80) bits=7;
        +			else bits=0; /* should not happen */
        +			}
        +		}
        +	else
        +		bits=0;
        +
        +	ret=1+len;
        +	if (pp == NULL) return(ret);
        +
        +	p= *pp;
        +
        +	*(p++)=(unsigned char)bits;
        +	d=a->data;
        +	memcpy(p,d,len);
        +	p+=len;
        +	if (len > 0) p[-1]&=(0xff<<bits);
        +	*pp=p;
        +	return(ret);
        +	}
        +
        +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
        +	const unsigned char **pp, long len)
        +	{
        +	ASN1_BIT_STRING *ret=NULL;
        +	const unsigned char *p;
        +	unsigned char *s;
        +	int i;
        +
        +	if (len < 1)
        +		{
        +		i=ASN1_R_STRING_TOO_SHORT;
        +		goto err;
        +		}
        +
        +	if ((a == NULL) || ((*a) == NULL))
        +		{
        +		if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
        +		}
        +	else
        +		ret=(*a);
        +
        +	p= *pp;
        +	i= *(p++);
        +	/* We do this to preserve the settings.  If we modify
        +	 * the settings, via the _set_bit function, we will recalculate
        +	 * on output */
        +	ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
        +	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
        +
        +	if (len-- > 1) /* using one because of the bits left byte */
        +		{
        +		s=(unsigned char *)OPENSSL_malloc((int)len);
        +		if (s == NULL)
        +			{
        +			i=ERR_R_MALLOC_FAILURE;
        +			goto err;
        +			}
        +		memcpy(s,p,(int)len);
        +		s[len-1]&=(0xff<<i);
        +		p+=len;
        +		}
        +	else
        +		s=NULL;
        +
        +	ret->length=(int)len;
        +	if (ret->data != NULL) OPENSSL_free(ret->data);
        +	ret->data=s;
        +	ret->type=V_ASN1_BIT_STRING;
        +	if (a != NULL) (*a)=ret;
        +	*pp=p;
        +	return(ret);
        +err:
        +	ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i);
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		M_ASN1_BIT_STRING_free(ret);
        +	return(NULL);
        +	}
        +
        +/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
        + */
        +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
        +	{
        +	int w,v,iv;
        +	unsigned char *c;
        +
        +	w=n/8;
        +	v=1<<(7-(n&0x07));
        +	iv= ~v;
        +	if (!value) v=0;
        +
        +	if (a == NULL)
        +		return 0;
        +
        +	a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
        +
        +	if ((a->length < (w+1)) || (a->data == NULL))
        +		{
        +		if (!value) return(1); /* Don't need to set */
        +		if (a->data == NULL)
        +			c=(unsigned char *)OPENSSL_malloc(w+1);
        +		else
        +			c=(unsigned char *)OPENSSL_realloc_clean(a->data,
        +								 a->length,
        +								 w+1);
        +		if (c == NULL)
        +			{
        +			ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +  		if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
        +		a->data=c;
        +		a->length=w+1;
        +	}
        +	a->data[w]=((a->data[w])&iv)|v;
        +	while ((a->length > 0) && (a->data[a->length-1] == 0))
        +		a->length--;
        +	return(1);
        +	}
        +
        +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
        +	{
        +	int w,v;
        +
        +	w=n/8;
        +	v=1<<(7-(n&0x07));
        +	if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
        +		return(0);
        +	return((a->data[w]&v) != 0);
        +	}
        +
        +/*
        + * Checks if the given bit string contains only bits specified by 
        + * the flags vector. Returns 0 if there is at least one bit set in 'a'
        + * which is not specified in 'flags', 1 otherwise.
        + * 'len' is the length of 'flags'.
        + */
        +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
        +			  unsigned char *flags, int flags_len)
        +	{
        +	int i, ok;
        +	/* Check if there is one bit set at all. */
        +	if (!a || !a->data) return 1;
        +
        +	/* Check each byte of the internal representation of the bit string. */
        +	ok = 1;
        +	for (i = 0; i < a->length && ok; ++i)
        +		{
        +		unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
        +		/* We are done if there is an unneeded bit set. */
        +		ok = (a->data[i] & mask) == 0;
        +		}
        +	return ok;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_bool.c b/vendor/openssl/openssl/crypto/asn1/a_bool.c
        new file mode 100644
        index 000000000..331acdf05
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_bool.c
        @@ -0,0 +1,114 @@
        +/* crypto/asn1/a_bool.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +
        +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
        +	{
        +	int r;
        +	unsigned char *p;
        +
        +	r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
        +	if (pp == NULL) return(r);
        +	p= *pp;
        +
        +	ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
        +	*(p++)= (unsigned char)a;
        +	*pp=p;
        +	return(r);
        +	}
        +
        +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
        +	{
        +	int ret= -1;
        +	const unsigned char *p;
        +	long len;
        +	int inf,tag,xclass;
        +	int i=0;
        +
        +	p= *pp;
        +	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
        +	if (inf & 0x80)
        +		{
        +		i=ASN1_R_BAD_OBJECT_HEADER;
        +		goto err;
        +		}
        +
        +	if (tag != V_ASN1_BOOLEAN)
        +		{
        +		i=ASN1_R_EXPECTING_A_BOOLEAN;
        +		goto err;
        +		}
        +
        +	if (len != 1)
        +		{
        +		i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
        +		goto err;
        +		}
        +	ret= (int)*(p++);
        +	if (a != NULL) (*a)=ret;
        +	*pp=p;
        +	return(ret);
        +err:
        +	ASN1err(ASN1_F_D2I_ASN1_BOOLEAN,i);
        +	return(ret);
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_bytes.c b/vendor/openssl/openssl/crypto/asn1/a_bytes.c
        new file mode 100644
        index 000000000..92d630cdb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_bytes.c
        @@ -0,0 +1,314 @@
        +/* crypto/asn1/a_bytes.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
        +/* type is a 'bitmap' of acceptable string types.
        + */
        +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
        +	     long length, int type)
        +	{
        +	ASN1_STRING *ret=NULL;
        +	const unsigned char *p;
        +	unsigned char *s;
        +	long len;
        +	int inf,tag,xclass;
        +	int i=0;
        +
        +	p= *pp;
        +	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
        +	if (inf & 0x80) goto err;
        +
        +	if (tag >= 32)
        +		{
        +		i=ASN1_R_TAG_VALUE_TOO_HIGH;
        +		goto err;
        +		}
        +	if (!(ASN1_tag2bit(tag) & type))
        +		{
        +		i=ASN1_R_WRONG_TYPE;
        +		goto err;
        +		}
        +
        +	/* If a bit-string, exit early */
        +	if (tag == V_ASN1_BIT_STRING)
        +		return(d2i_ASN1_BIT_STRING(a,pp,length));
        +
        +	if ((a == NULL) || ((*a) == NULL))
        +		{
        +		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
        +		}
        +	else
        +		ret=(*a);
        +
        +	if (len != 0)
        +		{
        +		s=(unsigned char *)OPENSSL_malloc((int)len+1);
        +		if (s == NULL)
        +			{
        +			i=ERR_R_MALLOC_FAILURE;
        +			goto err;
        +			}
        +		memcpy(s,p,(int)len);
        +		s[len]='\0';
        +		p+=len;
        +		}
        +	else
        +		s=NULL;
        +
        +	if (ret->data != NULL) OPENSSL_free(ret->data);
        +	ret->length=(int)len;
        +	ret->data=s;
        +	ret->type=tag;
        +	if (a != NULL) (*a)=ret;
        +	*pp=p;
        +	return(ret);
        +err:
        +	ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,i);
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		ASN1_STRING_free(ret);
        +	return(NULL);
        +	}
        +
        +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
        +	{
        +	int ret,r,constructed;
        +	unsigned char *p;
        +
        +	if (a == NULL)  return(0);
        +
        +	if (tag == V_ASN1_BIT_STRING)
        +		return(i2d_ASN1_BIT_STRING(a,pp));
        +		
        +	ret=a->length;
        +	r=ASN1_object_size(0,ret,tag);
        +	if (pp == NULL) return(r);
        +	p= *pp;
        +
        +	if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
        +		constructed=1;
        +	else
        +		constructed=0;
        +	ASN1_put_object(&p,constructed,ret,tag,xclass);
        +	memcpy(p,a->data,a->length);
        +	p+=a->length;
        +	*pp= p;
        +	return(r);
        +	}
        +
        +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
        +	     long length, int Ptag, int Pclass)
        +	{
        +	ASN1_STRING *ret=NULL;
        +	const unsigned char *p;
        +	unsigned char *s;
        +	long len;
        +	int inf,tag,xclass;
        +	int i=0;
        +
        +	if ((a == NULL) || ((*a) == NULL))
        +		{
        +		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
        +		}
        +	else
        +		ret=(*a);
        +
        +	p= *pp;
        +	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
        +	if (inf & 0x80)
        +		{
        +		i=ASN1_R_BAD_OBJECT_HEADER;
        +		goto err;
        +		}
        +
        +	if (tag != Ptag)
        +		{
        +		i=ASN1_R_WRONG_TAG;
        +		goto err;
        +		}
        +
        +	if (inf & V_ASN1_CONSTRUCTED)
        +		{
        +		ASN1_const_CTX c;
        +
        +		c.pp=pp;
        +		c.p=p;
        +		c.inf=inf;
        +		c.slen=len;
        +		c.tag=Ptag;
        +		c.xclass=Pclass;
        +		c.max=(length == 0)?0:(p+length);
        +		if (!asn1_collate_primitive(ret,&c)) 
        +			goto err; 
        +		else
        +			{
        +			p=c.p;
        +			}
        +		}
        +	else
        +		{
        +		if (len != 0)
        +			{
        +			if ((ret->length < len) || (ret->data == NULL))
        +				{
        +				if (ret->data != NULL) OPENSSL_free(ret->data);
        +				s=(unsigned char *)OPENSSL_malloc((int)len + 1);
        +				if (s == NULL)
        +					{
        +					i=ERR_R_MALLOC_FAILURE;
        +					goto err;
        +					}
        +				}
        +			else
        +				s=ret->data;
        +			memcpy(s,p,(int)len);
        +			s[len] = '\0';
        +			p+=len;
        +			}
        +		else
        +			{
        +			s=NULL;
        +			if (ret->data != NULL) OPENSSL_free(ret->data);
        +			}
        +
        +		ret->length=(int)len;
        +		ret->data=s;
        +		ret->type=Ptag;
        +		}
        +
        +	if (a != NULL) (*a)=ret;
        +	*pp=p;
        +	return(ret);
        +err:
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		ASN1_STRING_free(ret);
        +	ASN1err(ASN1_F_D2I_ASN1_BYTES,i);
        +	return(NULL);
        +	}
        +
        +
        +/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
        + * them into the one structure that is then returned */
        +/* There have been a few bug fixes for this function from
        + * Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
        +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
        +	{
        +	ASN1_STRING *os=NULL;
        +	BUF_MEM b;
        +	int num;
        +
        +	b.length=0;
        +	b.max=0;
        +	b.data=NULL;
        +
        +	if (a == NULL)
        +		{
        +		c->error=ERR_R_PASSED_NULL_PARAMETER;
        +		goto err;
        +		}
        +
        +	num=0;
        +	for (;;)
        +		{
        +		if (c->inf & 1)
        +			{
        +			c->eos=ASN1_const_check_infinite_end(&c->p,
        +				(long)(c->max-c->p));
        +			if (c->eos) break;
        +			}
        +		else
        +			{
        +			if (c->slen <= 0) break;
        +			}
        +
        +		c->q=c->p;
        +		if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
        +			== NULL)
        +			{
        +			c->error=ERR_R_ASN1_LIB;
        +			goto err;
        +			}
        +
        +		if (!BUF_MEM_grow_clean(&b,num+os->length))
        +			{
        +			c->error=ERR_R_BUF_LIB;
        +			goto err;
        +			}
        +		memcpy(&(b.data[num]),os->data,os->length);
        +		if (!(c->inf & 1))
        +			c->slen-=(c->p-c->q);
        +		num+=os->length;
        +		}
        +
        +	if (!asn1_const_Finish(c)) goto err;
        +
        +	a->length=num;
        +	if (a->data != NULL) OPENSSL_free(a->data);
        +	a->data=(unsigned char *)b.data;
        +	if (os != NULL) ASN1_STRING_free(os);
        +	return(1);
        +err:
        +	ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE,c->error);
        +	if (os != NULL) ASN1_STRING_free(os);
        +	if (b.data != NULL) OPENSSL_free(b.data);
        +	return(0);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_d2i_fp.c b/vendor/openssl/openssl/crypto/asn1/a_d2i_fp.c
        new file mode 100644
        index 000000000..52b2ebdb6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_d2i_fp.c
        @@ -0,0 +1,286 @@
        +/* crypto/asn1/a_d2i_fp.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <limits.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1_mac.h>
        +
        +static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
        +
        +#ifndef NO_OLD_ASN1
        +#ifndef OPENSSL_NO_FP_API
        +
        +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
        +        {
        +        BIO *b;
        +        void *ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_D2I_FP,ERR_R_BUF_LIB);
        +                return(NULL);
        +		}
        +        BIO_set_fp(b,in,BIO_NOCLOSE);
        +        ret=ASN1_d2i_bio(xnew,d2i,b,x);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
        +	{
        +	BUF_MEM *b = NULL;
        +	const unsigned char *p;
        +	void *ret=NULL;
        +	int len;
        +
        +	len = asn1_d2i_read_bio(in, &b);
        +	if(len < 0) goto err;
        +
        +	p=(unsigned char *)b->data;
        +	ret=d2i(x,&p,len);
        +err:
        +	if (b != NULL) BUF_MEM_free(b);
        +	return(ret);
        +	}
        +
        +#endif
        +
        +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
        +	{
        +	BUF_MEM *b = NULL;
        +	const unsigned char *p;
        +	void *ret=NULL;
        +	int len;
        +
        +	len = asn1_d2i_read_bio(in, &b);
        +	if(len < 0) goto err;
        +
        +	p=(const unsigned char *)b->data;
        +	ret=ASN1_item_d2i(x,&p,len, it);
        +err:
        +	if (b != NULL) BUF_MEM_free(b);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
        +        {
        +        BIO *b;
        +        char *ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_D2I_FP,ERR_R_BUF_LIB);
        +                return(NULL);
        +		}
        +        BIO_set_fp(b,in,BIO_NOCLOSE);
        +        ret=ASN1_item_d2i_bio(it,b,x);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +#define HEADER_SIZE   8
        +static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
        +	{
        +	BUF_MEM *b;
        +	unsigned char *p;
        +	int i;
        +	ASN1_const_CTX c;
        +	size_t want=HEADER_SIZE;
        +	int eos=0;
        +	size_t off=0;
        +	size_t len=0;
        +
        +	b=BUF_MEM_new();
        +	if (b == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
        +		return -1;
        +		}
        +
        +	ERR_clear_error();
        +	for (;;)
        +		{
        +		if (want >= (len-off))
        +			{
        +			want-=(len-off);
        +
        +			if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
        +				{
        +				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			i=BIO_read(in,&(b->data[len]),want);
        +			if ((i < 0) && ((len-off) == 0))
        +				{
        +				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA);
        +				goto err;
        +				}
        +			if (i > 0)
        +				{
        +				if (len+i < len)
        +					{
        +					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
        +					goto err;
        +					}
        +				len+=i;
        +				}
        +			}
        +		/* else data already loaded */
        +
        +		p=(unsigned char *)&(b->data[off]);
        +		c.p=p;
        +		c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
        +			len-off);
        +		if (c.inf & 0x80)
        +			{
        +			unsigned long e;
        +
        +			e=ERR_GET_REASON(ERR_peek_error());
        +			if (e != ASN1_R_TOO_LONG)
        +				goto err;
        +			else
        +				ERR_clear_error(); /* clear error */
        +			}
        +		i=c.p-p;/* header length */
        +		off+=i;	/* end of data */
        +
        +		if (c.inf & 1)
        +			{
        +			/* no data body so go round again */
        +			eos++;
        +			if (eos < 0)
        +				{
        +				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
        +				goto err;
        +				}
        +			want=HEADER_SIZE;
        +			}
        +		else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
        +			{
        +			/* eos value, so go back and read another header */
        +			eos--;
        +			if (eos <= 0)
        +				break;
        +			else
        +				want=HEADER_SIZE;
        +			}
        +		else 
        +			{
        +			/* suck in c.slen bytes of data */
        +			want=c.slen;
        +			if (want > (len-off))
        +				{
        +				want-=(len-off);
        +				if (want > INT_MAX /* BIO_read takes an int length */ ||
        +					len+want < len)
        +						{
        +						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
        +						goto err;
        +						}
        +				if (!BUF_MEM_grow_clean(b,len+want))
        +					{
        +					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				while (want > 0)
        +					{
        +					i=BIO_read(in,&(b->data[len]),want);
        +					if (i <= 0)
        +						{
        +						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
        +						    ASN1_R_NOT_ENOUGH_DATA);
        +						goto err;
        +						}
        +					/* This can't overflow because
        +					 * |len+want| didn't overflow. */
        +					len+=i;
        +					want-=i;
        +					}
        +				}
        +			if (off + c.slen < off)
        +				{
        +				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
        +				goto err;
        +				}
        +			off+=c.slen;
        +			if (eos <= 0)
        +				{
        +				break;
        +				}
        +			else
        +				want=HEADER_SIZE;
        +			}
        +		}
        +
        +	if (off > INT_MAX)
        +		{
        +		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
        +		goto err;
        +		}
        +
        +	*pb = b;
        +	return off;
        +err:
        +	if (b != NULL) BUF_MEM_free(b);
        +	return -1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_digest.c b/vendor/openssl/openssl/crypto/asn1/a_digest.c
        new file mode 100644
        index 000000000..cbdeea6ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_digest.c
        @@ -0,0 +1,113 @@
        +/* crypto/asn1/a_digest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +
        +#include "cryptlib.h"
        +
        +#ifndef NO_SYS_TYPES_H
        +# include <sys/types.h>
        +#endif
        +
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/buffer.h>
        +#include <openssl/x509.h>
        +
        +#ifndef NO_ASN1_OLD
        +
        +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
        +		unsigned char *md, unsigned int *len)
        +	{
        +	int i;
        +	unsigned char *str,*p;
        +
        +	i=i2d(data,NULL);
        +	if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_DIGEST,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	p=str;
        +	i2d(data,&p);
        +
        +	if (!EVP_Digest(str, i, md, len, type, NULL))
        +		return 0;
        +	OPENSSL_free(str);
        +	return(1);
        +	}
        +
        +#endif
        +
        +
        +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
        +		unsigned char *md, unsigned int *len)
        +	{
        +	int i;
        +	unsigned char *str = NULL;
        +
        +	i=ASN1_item_i2d(asn,&str, it);
        +	if (!str) return(0);
        +
        +	if (!EVP_Digest(str, i, md, len, type, NULL))
        +		return 0;
        +	OPENSSL_free(str);
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_dup.c b/vendor/openssl/openssl/crypto/asn1/a_dup.c
        new file mode 100644
        index 000000000..d98992548
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_dup.c
        @@ -0,0 +1,109 @@
        +/* crypto/asn1/a_dup.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +#ifndef NO_OLD_ASN1
        +
        +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
        +	{
        +	unsigned char *b,*p;
        +	const unsigned char *p2;
        +	int i;
        +	char *ret;
        +
        +	if (x == NULL) return(NULL);
        +
        +	i=i2d(x,NULL);
        +	b=OPENSSL_malloc(i+10);
        +	if (b == NULL)
        +		{ ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
        +	p= b;
        +	i=i2d(x,&p);
        +	p2= b;
        +	ret=d2i(NULL,&p2,i);
        +	OPENSSL_free(b);
        +	return(ret);
        +	}
        +
        +#endif
        +
        +/* ASN1_ITEM version of dup: this follows the model above except we don't need
        + * to allocate the buffer. At some point this could be rewritten to directly dup
        + * the underlying structure instead of doing and encode and decode.
        + */
        +
        +void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
        +	{
        +	unsigned char *b = NULL;
        +	const unsigned char *p;
        +	long i;
        +	void *ret;
        +
        +	if (x == NULL) return(NULL);
        +
        +	i=ASN1_item_i2d(x,&b,it);
        +	if (b == NULL)
        +		{ ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
        +	p= b;
        +	ret=ASN1_item_d2i(NULL,&p,i, it);
        +	OPENSSL_free(b);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_enum.c b/vendor/openssl/openssl/crypto/asn1/a_enum.c
        new file mode 100644
        index 000000000..fe9aa13b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_enum.c
        @@ -0,0 +1,182 @@
        +/* crypto/asn1/a_enum.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/bn.h>
        +
        +/* 
        + * Code for ENUMERATED type: identical to INTEGER apart from a different tag.
        + * for comments on encoding see a_int.c
        + */
        +
        +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
        +	{
        +	int j,k;
        +	unsigned int i;
        +	unsigned char buf[sizeof(long)+1];
        +	long d;
        +
        +	a->type=V_ASN1_ENUMERATED;
        +	if (a->length < (int)(sizeof(long)+1))
        +		{
        +		if (a->data != NULL)
        +			OPENSSL_free(a->data);
        +		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
        +			memset((char *)a->data,0,sizeof(long)+1);
        +		}
        +	if (a->data == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_ENUMERATED_SET,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	d=v;
        +	if (d < 0)
        +		{
        +		d= -d;
        +		a->type=V_ASN1_NEG_ENUMERATED;
        +		}
        +
        +	for (i=0; i<sizeof(long); i++)
        +		{
        +		if (d == 0) break;
        +		buf[i]=(int)d&0xff;
        +		d>>=8;
        +		}
        +	j=0;
        +	for (k=i-1; k >=0; k--)
        +		a->data[j++]=buf[k];
        +	a->length=j;
        +	return(1);
        +	}
        +
        +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
        +	{
        +	int neg=0,i;
        +	long r=0;
        +
        +	if (a == NULL) return(0L);
        +	i=a->type;
        +	if (i == V_ASN1_NEG_ENUMERATED)
        +		neg=1;
        +	else if (i != V_ASN1_ENUMERATED)
        +		return -1;
        +	
        +	if (a->length > (int)sizeof(long))
        +		{
        +		/* hmm... a bit ugly */
        +		return(0xffffffffL);
        +		}
        +	if (a->data == NULL)
        +		return 0;
        +
        +	for (i=0; i<a->length; i++)
        +		{
        +		r<<=8;
        +		r|=(unsigned char)a->data[i];
        +		}
        +	if (neg) r= -r;
        +	return(r);
        +	}
        +
        +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
        +	{
        +	ASN1_ENUMERATED *ret;
        +	int len,j;
        +
        +	if (ai == NULL)
        +		ret=M_ASN1_ENUMERATED_new();
        +	else
        +		ret=ai;
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
        +		goto err;
        +		}
        +	if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
        +	else ret->type=V_ASN1_ENUMERATED;
        +	j=BN_num_bits(bn);
        +	len=((j == 0)?0:((j/8)+1));
        +	if (ret->length < len+4)
        +		{
        +		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
        +		if (!new_data)
        +			{
        +			ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		ret->data=new_data;
        +		}
        +
        +	ret->length=BN_bn2bin(bn,ret->data);
        +	return(ret);
        +err:
        +	if (ret != ai) M_ASN1_ENUMERATED_free(ret);
        +	return(NULL);
        +	}
        +
        +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
        +	{
        +	BIGNUM *ret;
        +
        +	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
        +		ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
        +	else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_gentm.c b/vendor/openssl/openssl/crypto/asn1/a_gentm.c
        new file mode 100644
        index 000000000..c79c6f538
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_gentm.c
        @@ -0,0 +1,263 @@
        +/* crypto/asn1/a_gentm.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.]
        + */
        +
        +/* GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include "o_time.h"
        +#include <openssl/asn1.h>
        +
        +#if 0
        +
        +int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
        +	{
        +#ifdef CHARSET_EBCDIC
        +	/* KLUDGE! We convert to ascii before writing DER */
        +	int len;
        +	char tmp[24];
        +	ASN1_STRING tmpstr = *(ASN1_STRING *)a;
        +
        +	len = tmpstr.length;
        +	ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
        +	tmpstr.data = tmp;
        +
        +	a = (ASN1_GENERALIZEDTIME *) &tmpstr;
        +#endif
        +	return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
        +		V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL));
        +	}
        +
        +
        +ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
        +	     unsigned char **pp, long length)
        +	{
        +	ASN1_GENERALIZEDTIME *ret=NULL;
        +
        +	ret=(ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
        +		V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL);
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ERR_R_NESTED_ASN1_ERROR);
        +		return(NULL);
        +		}
        +#ifdef CHARSET_EBCDIC
        +	ascii2ebcdic(ret->data, ret->data, ret->length);
        +#endif
        +	if (!ASN1_GENERALIZEDTIME_check(ret))
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ASN1_R_INVALID_TIME_FORMAT);
        +		goto err;
        +		}
        +
        +	return(ret);
        +err:
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		M_ASN1_GENERALIZEDTIME_free(ret);
        +	return(NULL);
        +	}
        +
        +#endif
        +
        +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
        +	{
        +	static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
        +	static const int max[9]={99, 99,12,31,23,59,59,12,59};
        +	char *a;
        +	int n,i,l,o;
        +
        +	if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
        +	l=d->length;
        +	a=(char *)d->data;
        +	o=0;
        +	/* GENERALIZEDTIME is similar to UTCTIME except the year is
        +         * represented as YYYY. This stuff treats everything as a two digit
        +         * field so make first two fields 00 to 99
        +         */
        +	if (l < 13) goto err;
        +	for (i=0; i<7; i++)
        +		{
        +		if ((i == 6) && ((a[o] == 'Z') ||
        +			(a[o] == '+') || (a[o] == '-')))
        +			{ i++; break; }
        +		if ((a[o] < '0') || (a[o] > '9')) goto err;
        +		n= a[o]-'0';
        +		if (++o > l) goto err;
        +
        +		if ((a[o] < '0') || (a[o] > '9')) goto err;
        +		n=(n*10)+ a[o]-'0';
        +		if (++o > l) goto err;
        +
        +		if ((n < min[i]) || (n > max[i])) goto err;
        +		}
        +	/* Optional fractional seconds: decimal point followed by one
        +	 * or more digits.
        +	 */
        +	if (a[o] == '.')
        +		{
        +		if (++o > l) goto err;
        +		i = o;
        +		while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
        +			o++;
        +		/* Must have at least one digit after decimal point */
        +		if (i == o) goto err;
        +		}
        +
        +	if (a[o] == 'Z')
        +		o++;
        +	else if ((a[o] == '+') || (a[o] == '-'))
        +		{
        +		o++;
        +		if (o+4 > l) goto err;
        +		for (i=7; i<9; i++)
        +			{
        +			if ((a[o] < '0') || (a[o] > '9')) goto err;
        +			n= a[o]-'0';
        +			o++;
        +			if ((a[o] < '0') || (a[o] > '9')) goto err;
        +			n=(n*10)+ a[o]-'0';
        +			if ((n < min[i]) || (n > max[i])) goto err;
        +			o++;
        +			}
        +		}
        +	else
        +		{
        +		/* Missing time zone information. */
        +		goto err;
        +		}
        +	return(o == l);
        +err:
        +	return(0);
        +	}
        +
        +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
        +	{
        +	ASN1_GENERALIZEDTIME t;
        +
        +	t.type=V_ASN1_GENERALIZEDTIME;
        +	t.length=strlen(str);
        +	t.data=(unsigned char *)str;
        +	if (ASN1_GENERALIZEDTIME_check(&t))
        +		{
        +		if (s != NULL)
        +			{
        +			if (!ASN1_STRING_set((ASN1_STRING *)s,
        +				(unsigned char *)str,t.length))
        +				return 0;
        +			s->type=V_ASN1_GENERALIZEDTIME;
        +			}
        +		return(1);
        +		}
        +	else
        +		return(0);
        +	}
        +
        +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
        +	     time_t t)
        +	{
        +		return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
        +	}
        +
        +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
        +	     time_t t, int offset_day, long offset_sec)
        +	{
        +	char *p;
        +	struct tm *ts;
        +	struct tm data;
        +	size_t len = 20; 
        +
        +	if (s == NULL)
        +		s=M_ASN1_GENERALIZEDTIME_new();
        +	if (s == NULL)
        +		return(NULL);
        +
        +	ts=OPENSSL_gmtime(&t, &data);
        +	if (ts == NULL)
        +		return(NULL);
        +
        +	if (offset_day || offset_sec)
        +		{ 
        +		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
        +			return NULL;
        +		}
        +
        +	p=(char *)s->data;
        +	if ((p == NULL) || ((size_t)s->length < len))
        +		{
        +		p=OPENSSL_malloc(len);
        +		if (p == NULL)
        +			{
        +			ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		if (s->data != NULL)
        +			OPENSSL_free(s->data);
        +		s->data=(unsigned char *)p;
        +		}
        +
        +	BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
        +		     ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
        +	s->length=strlen(p);
        +	s->type=V_ASN1_GENERALIZEDTIME;
        +#ifdef CHARSET_EBCDIC_not
        +	ebcdic2ascii(s->data, s->data, s->length);
        +#endif
        +	return(s);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_i2d_fp.c b/vendor/openssl/openssl/crypto/asn1/a_i2d_fp.c
        new file mode 100644
        index 000000000..a3ad76d35
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_i2d_fp.c
        @@ -0,0 +1,163 @@
        +/* crypto/asn1/a_i2d_fp.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1.h>
        +
        +#ifndef NO_OLD_ASN1
        +
        +#ifndef OPENSSL_NO_FP_API
        +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_I2D_FP,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,out,BIO_NOCLOSE);
        +        ret=ASN1_i2d_bio(i2d,b,x);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
        +	{
        +	char *b;
        +	unsigned char *p;
        +	int i,j=0,n,ret=1;
        +
        +	n=i2d(x,NULL);
        +	b=(char *)OPENSSL_malloc(n);
        +	if (b == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_I2D_BIO,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +
        +	p=(unsigned char *)b;
        +	i2d(x,&p);
        +	
        +	for (;;)
        +		{
        +		i=BIO_write(out,&(b[j]),n);
        +		if (i == n) break;
        +		if (i <= 0)
        +			{
        +			ret=0;
        +			break;
        +			}
        +		j+=i;
        +		n-=i;
        +		}
        +	OPENSSL_free(b);
        +	return(ret);
        +	}
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_FP_API
        +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_I2D_FP,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,out,BIO_NOCLOSE);
        +        ret=ASN1_item_i2d_bio(it,b,x);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
        +	{
        +	unsigned char *b = NULL;
        +	int i,j=0,n,ret=1;
        +
        +	n = ASN1_item_i2d(x, &b, it);
        +	if (b == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +
        +	for (;;)
        +		{
        +		i=BIO_write(out,&(b[j]),n);
        +		if (i == n) break;
        +		if (i <= 0)
        +			{
        +			ret=0;
        +			break;
        +			}
        +		j+=i;
        +		n-=i;
        +		}
        +	OPENSSL_free(b);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_int.c b/vendor/openssl/openssl/crypto/asn1/a_int.c
        new file mode 100644
        index 000000000..ad0d2506f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_int.c
        @@ -0,0 +1,458 @@
        +/* crypto/asn1/a_int.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/bn.h>
        +
        +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
        +{ return M_ASN1_INTEGER_dup(x);}
        +
        +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
        +	{ 
        +	int neg, ret;
        +	/* Compare signs */
        +	neg = x->type & V_ASN1_NEG;
        +	if (neg != (y->type & V_ASN1_NEG))
        +		{
        +		if (neg)
        +			return -1;
        +		else
        +			return 1;
        +		}
        +
        +	ret = ASN1_STRING_cmp(x, y);
        +
        +	if (neg)
        +		return -ret;
        +	else
        +		return ret;
        +	}
        +	
        +
        +/* 
        + * This converts an ASN1 INTEGER into its content encoding.
        + * The internal representation is an ASN1_STRING whose data is a big endian
        + * representation of the value, ignoring the sign. The sign is determined by
        + * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. 
        + *
        + * Positive integers are no problem: they are almost the same as the DER
        + * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
        + *
        + * Negative integers are a bit trickier...
        + * The DER representation of negative integers is in 2s complement form.
        + * The internal form is converted by complementing each octet and finally 
        + * adding one to the result. This can be done less messily with a little trick.
        + * If the internal form has trailing zeroes then they will become FF by the
        + * complement and 0 by the add one (due to carry) so just copy as many trailing 
        + * zeros to the destination as there are in the source. The carry will add one
        + * to the last none zero octet: so complement this octet and add one and finally
        + * complement any left over until you get to the start of the string.
        + *
        + * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
        + * with 0xff. However if the first byte is 0x80 and one of the following bytes
        + * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
        + * followed by optional zeros isn't padded.
        + */
        +
        +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
        +	{
        +	int pad=0,ret,i,neg;
        +	unsigned char *p,*n,pb=0;
        +
        +	if ((a == NULL) || (a->data == NULL)) return(0);
        +	neg=a->type & V_ASN1_NEG;
        +	if (a->length == 0)
        +		ret=1;
        +	else
        +		{
        +		ret=a->length;
        +		i=a->data[0];
        +		if (!neg && (i > 127)) {
        +			pad=1;
        +			pb=0;
        +		} else if(neg) {
        +			if(i>128) {
        +				pad=1;
        +				pb=0xFF;
        +			} else if(i == 128) {
        +			/*
        +			 * Special case: if any other bytes non zero we pad:
        +			 * otherwise we don't.
        +			 */
        +				for(i = 1; i < a->length; i++) if(a->data[i]) {
        +						pad=1;
        +						pb=0xFF;
        +						break;
        +				}
        +			}
        +		}
        +		ret+=pad;
        +		}
        +	if (pp == NULL) return(ret);
        +	p= *pp;
        +
        +	if (pad) *(p++)=pb;
        +	if (a->length == 0) *(p++)=0;
        +	else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
        +	else {
        +		/* Begin at the end of the encoding */
        +		n=a->data + a->length - 1;
        +		p += a->length - 1;
        +		i = a->length;
        +		/* Copy zeros to destination as long as source is zero */
        +		while(!*n) {
        +			*(p--) = 0;
        +			n--;
        +			i--;
        +		}
        +		/* Complement and increment next octet */
        +		*(p--) = ((*(n--)) ^ 0xff) + 1;
        +		i--;
        +		/* Complement any octets left */
        +		for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
        +	}
        +
        +	*pp+=ret;
        +	return(ret);
        +	}
        +
        +/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
        +
        +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
        +	     long len)
        +	{
        +	ASN1_INTEGER *ret=NULL;
        +	const unsigned char *p, *pend;
        +	unsigned char *to,*s;
        +	int i;
        +
        +	if ((a == NULL) || ((*a) == NULL))
        +		{
        +		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
        +		ret->type=V_ASN1_INTEGER;
        +		}
        +	else
        +		ret=(*a);
        +
        +	p= *pp;
        +	pend = p + len;
        +
        +	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
        +	 * signifies a missing NULL parameter. */
        +	s=(unsigned char *)OPENSSL_malloc((int)len+1);
        +	if (s == NULL)
        +		{
        +		i=ERR_R_MALLOC_FAILURE;
        +		goto err;
        +		}
        +	to=s;
        +	if(!len) {
        +		/* Strictly speaking this is an illegal INTEGER but we
        +		 * tolerate it.
        +		 */
        +		ret->type=V_ASN1_INTEGER;
        +	} else if (*p & 0x80) /* a negative number */
        +		{
        +		ret->type=V_ASN1_NEG_INTEGER;
        +		if ((*p == 0xff) && (len != 1)) {
        +			p++;
        +			len--;
        +		}
        +		i = len;
        +		p += i - 1;
        +		to += i - 1;
        +		while((!*p) && i) {
        +			*(to--) = 0;
        +			i--;
        +			p--;
        +		}
        +		/* Special case: if all zeros then the number will be of
        +		 * the form FF followed by n zero bytes: this corresponds to
        +		 * 1 followed by n zero bytes. We've already written n zeros
        +		 * so we just append an extra one and set the first byte to
        +		 * a 1. This is treated separately because it is the only case
        +		 * where the number of bytes is larger than len.
        +		 */
        +		if(!i) {
        +			*s = 1;
        +			s[len] = 0;
        +			len++;
        +		} else {
        +			*(to--) = (*(p--) ^ 0xff) + 1;
        +			i--;
        +			for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
        +		}
        +	} else {
        +		ret->type=V_ASN1_INTEGER;
        +		if ((*p == 0) && (len != 1))
        +			{
        +			p++;
        +			len--;
        +			}
        +		memcpy(s,p,(int)len);
        +	}
        +
        +	if (ret->data != NULL) OPENSSL_free(ret->data);
        +	ret->data=s;
        +	ret->length=(int)len;
        +	if (a != NULL) (*a)=ret;
        +	*pp=pend;
        +	return(ret);
        +err:
        +	ASN1err(ASN1_F_C2I_ASN1_INTEGER,i);
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		M_ASN1_INTEGER_free(ret);
        +	return(NULL);
        +	}
        +
        +
        +/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
        + * ASN1 integers: some broken software can encode a positive INTEGER
        + * with its MSB set as negative (it doesn't add a padding zero).
        + */
        +
        +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
        +	     long length)
        +	{
        +	ASN1_INTEGER *ret=NULL;
        +	const unsigned char *p;
        +	unsigned char *s;
        +	long len;
        +	int inf,tag,xclass;
        +	int i;
        +
        +	if ((a == NULL) || ((*a) == NULL))
        +		{
        +		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
        +		ret->type=V_ASN1_INTEGER;
        +		}
        +	else
        +		ret=(*a);
        +
        +	p= *pp;
        +	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
        +	if (inf & 0x80)
        +		{
        +		i=ASN1_R_BAD_OBJECT_HEADER;
        +		goto err;
        +		}
        +
        +	if (tag != V_ASN1_INTEGER)
        +		{
        +		i=ASN1_R_EXPECTING_AN_INTEGER;
        +		goto err;
        +		}
        +
        +	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
        +	 * signifies a missing NULL parameter. */
        +	s=(unsigned char *)OPENSSL_malloc((int)len+1);
        +	if (s == NULL)
        +		{
        +		i=ERR_R_MALLOC_FAILURE;
        +		goto err;
        +		}
        +	ret->type=V_ASN1_INTEGER;
        +	if(len) {
        +		if ((*p == 0) && (len != 1))
        +			{
        +			p++;
        +			len--;
        +			}
        +		memcpy(s,p,(int)len);
        +		p+=len;
        +	}
        +
        +	if (ret->data != NULL) OPENSSL_free(ret->data);
        +	ret->data=s;
        +	ret->length=(int)len;
        +	if (a != NULL) (*a)=ret;
        +	*pp=p;
        +	return(ret);
        +err:
        +	ASN1err(ASN1_F_D2I_ASN1_UINTEGER,i);
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		M_ASN1_INTEGER_free(ret);
        +	return(NULL);
        +	}
        +
        +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
        +	{
        +	int j,k;
        +	unsigned int i;
        +	unsigned char buf[sizeof(long)+1];
        +	long d;
        +
        +	a->type=V_ASN1_INTEGER;
        +	if (a->length < (int)(sizeof(long)+1))
        +		{
        +		if (a->data != NULL)
        +			OPENSSL_free(a->data);
        +		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
        +			memset((char *)a->data,0,sizeof(long)+1);
        +		}
        +	if (a->data == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_INTEGER_SET,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	d=v;
        +	if (d < 0)
        +		{
        +		d= -d;
        +		a->type=V_ASN1_NEG_INTEGER;
        +		}
        +
        +	for (i=0; i<sizeof(long); i++)
        +		{
        +		if (d == 0) break;
        +		buf[i]=(int)d&0xff;
        +		d>>=8;
        +		}
        +	j=0;
        +	for (k=i-1; k >=0; k--)
        +		a->data[j++]=buf[k];
        +	a->length=j;
        +	return(1);
        +	}
        +
        +long ASN1_INTEGER_get(const ASN1_INTEGER *a)
        +	{
        +	int neg=0,i;
        +	long r=0;
        +
        +	if (a == NULL) return(0L);
        +	i=a->type;
        +	if (i == V_ASN1_NEG_INTEGER)
        +		neg=1;
        +	else if (i != V_ASN1_INTEGER)
        +		return -1;
        +	
        +	if (a->length > (int)sizeof(long))
        +		{
        +		/* hmm... a bit ugly, return all ones */
        +		return -1;
        +		}
        +	if (a->data == NULL)
        +		return 0;
        +
        +	for (i=0; i<a->length; i++)
        +		{
        +		r<<=8;
        +		r|=(unsigned char)a->data[i];
        +		}
        +	if (neg) r= -r;
        +	return(r);
        +	}
        +
        +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
        +	{
        +	ASN1_INTEGER *ret;
        +	int len,j;
        +
        +	if (ai == NULL)
        +		ret=M_ASN1_INTEGER_new();
        +	else
        +		ret=ai;
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
        +		goto err;
        +		}
        +	if (BN_is_negative(bn))
        +		ret->type = V_ASN1_NEG_INTEGER;
        +	else ret->type=V_ASN1_INTEGER;
        +	j=BN_num_bits(bn);
        +	len=((j == 0)?0:((j/8)+1));
        +	if (ret->length < len+4)
        +		{
        +		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
        +		if (!new_data)
        +			{
        +			ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		ret->data=new_data;
        +		}
        +	ret->length=BN_bn2bin(bn,ret->data);
        +	/* Correct zero case */
        +	if(!ret->length)
        +		{
        +		ret->data[0] = 0;
        +		ret->length = 1;
        +		}
        +	return(ret);
        +err:
        +	if (ret != ai) M_ASN1_INTEGER_free(ret);
        +	return(NULL);
        +	}
        +
        +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
        +	{
        +	BIGNUM *ret;
        +
        +	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
        +		ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
        +	else if(ai->type == V_ASN1_NEG_INTEGER)
        +		BN_set_negative(ret, 1);
        +	return(ret);
        +	}
        +
        +IMPLEMENT_STACK_OF(ASN1_INTEGER)
        +IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_mbstr.c b/vendor/openssl/openssl/crypto/asn1/a_mbstr.c
        new file mode 100644
        index 000000000..1538e0a4f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_mbstr.c
        @@ -0,0 +1,400 @@
        +/* a_mbstr.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +static int traverse_string(const unsigned char *p, int len, int inform,
        +		 int (*rfunc)(unsigned long value, void *in), void *arg);
        +static int in_utf8(unsigned long value, void *arg);
        +static int out_utf8(unsigned long value, void *arg);
        +static int type_str(unsigned long value, void *arg);
        +static int cpy_asc(unsigned long value, void *arg);
        +static int cpy_bmp(unsigned long value, void *arg);
        +static int cpy_univ(unsigned long value, void *arg);
        +static int cpy_utf8(unsigned long value, void *arg);
        +static int is_printable(unsigned long value);
        +
        +/* These functions take a string in UTF8, ASCII or multibyte form and
        + * a mask of permissible ASN1 string types. It then works out the minimal
        + * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
        + * and creates a string of the correct type with the supplied data.
        + * Yes this is horrible: it has to be :-(
        + * The 'ncopy' form checks minimum and maximum size limits too.
        + */
        +
        +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
        +					int inform, unsigned long mask)
        +{
        +	return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
        +}
        +
        +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
        +					int inform, unsigned long mask, 
        +					long minsize, long maxsize)
        +{
        +	int str_type;
        +	int ret;
        +	char free_out;
        +	int outform, outlen = 0;
        +	ASN1_STRING *dest;
        +	unsigned char *p;
        +	int nchar;
        +	char strbuf[32];
        +	int (*cpyfunc)(unsigned long,void *) = NULL;
        +	if(len == -1) len = strlen((const char *)in);
        +	if(!mask) mask = DIRSTRING_TYPE;
        +
        +	/* First do a string check and work out the number of characters */
        +	switch(inform) {
        +
        +		case MBSTRING_BMP:
        +		if(len & 1) {
        +			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
        +					 ASN1_R_INVALID_BMPSTRING_LENGTH);
        +			return -1;
        +		}
        +		nchar = len >> 1;
        +		break;
        +
        +		case MBSTRING_UNIV:
        +		if(len & 3) {
        +			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
        +					 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
        +			return -1;
        +		}
        +		nchar = len >> 2;
        +		break;
        +
        +		case MBSTRING_UTF8:
        +		nchar = 0;
        +		/* This counts the characters and does utf8 syntax checking */
        +		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
        +		if(ret < 0) {
        +			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
        +						 ASN1_R_INVALID_UTF8STRING);
        +			return -1;
        +		}
        +		break;
        +
        +		case MBSTRING_ASC:
        +		nchar = len;
        +		break;
        +
        +		default:
        +		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
        +		return -1;
        +	}
        +
        +	if((minsize > 0) && (nchar < minsize)) {
        +		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
        +		BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
        +		ERR_add_error_data(2, "minsize=", strbuf);
        +		return -1;
        +	}
        +
        +	if((maxsize > 0) && (nchar > maxsize)) {
        +		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
        +		BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
        +		ERR_add_error_data(2, "maxsize=", strbuf);
        +		return -1;
        +	}
        +
        +	/* Now work out minimal type (if any) */
        +	if(traverse_string(in, len, inform, type_str, &mask) < 0) {
        +		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
        +		return -1;
        +	}
        +
        +
        +	/* Now work out output format and string type */
        +	outform = MBSTRING_ASC;
        +	if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
        +	else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
        +	else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
        +	else if(mask & B_ASN1_BMPSTRING) {
        +		str_type = V_ASN1_BMPSTRING;
        +		outform = MBSTRING_BMP;
        +	} else if(mask & B_ASN1_UNIVERSALSTRING) {
        +		str_type = V_ASN1_UNIVERSALSTRING;
        +		outform = MBSTRING_UNIV;
        +	} else {
        +		str_type = V_ASN1_UTF8STRING;
        +		outform = MBSTRING_UTF8;
        +	}
        +	if(!out) return str_type;
        +	if(*out) {
        +		free_out = 0;
        +		dest = *out;
        +		if(dest->data) {
        +			dest->length = 0;
        +			OPENSSL_free(dest->data);
        +			dest->data = NULL;
        +		}
        +		dest->type = str_type;
        +	} else {
        +		free_out = 1;
        +		dest = ASN1_STRING_type_new(str_type);
        +		if(!dest) {
        +			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
        +							ERR_R_MALLOC_FAILURE);
        +			return -1;
        +		}
        +		*out = dest;
        +	}
        +	/* If both the same type just copy across */
        +	if(inform == outform) {
        +		if(!ASN1_STRING_set(dest, in, len)) {
        +			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +		}
        +		return str_type;
        +	} 
        +
        +	/* Work out how much space the destination will need */
        +	switch(outform) {
        +		case MBSTRING_ASC:
        +		outlen = nchar;
        +		cpyfunc = cpy_asc;
        +		break;
        +
        +		case MBSTRING_BMP:
        +		outlen = nchar << 1;
        +		cpyfunc = cpy_bmp;
        +		break;
        +
        +		case MBSTRING_UNIV:
        +		outlen = nchar << 2;
        +		cpyfunc = cpy_univ;
        +		break;
        +
        +		case MBSTRING_UTF8:
        +		outlen = 0;
        +		traverse_string(in, len, inform, out_utf8, &outlen);
        +		cpyfunc = cpy_utf8;
        +		break;
        +	}
        +	if(!(p = OPENSSL_malloc(outlen + 1))) {
        +		if(free_out) ASN1_STRING_free(dest);
        +		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
        +		return -1;
        +	}
        +	dest->length = outlen;
        +	dest->data = p;
        +	p[outlen] = 0;
        +	traverse_string(in, len, inform, cpyfunc, &p);
        +	return str_type;	
        +}
        +
        +/* This function traverses a string and passes the value of each character
        + * to an optional function along with a void * argument.
        + */
        +
        +static int traverse_string(const unsigned char *p, int len, int inform,
        +		 int (*rfunc)(unsigned long value, void *in), void *arg)
        +{
        +	unsigned long value;
        +	int ret;
        +	while(len) {
        +		if(inform == MBSTRING_ASC) {
        +			value = *p++;
        +			len--;
        +		} else if(inform == MBSTRING_BMP) {
        +			value = *p++ << 8;
        +			value |= *p++;
        +			len -= 2;
        +		} else if(inform == MBSTRING_UNIV) {
        +			value = ((unsigned long)*p++) << 24;
        +			value |= ((unsigned long)*p++) << 16;
        +			value |= *p++ << 8;
        +			value |= *p++;
        +			len -= 4;
        +		} else {
        +			ret = UTF8_getc(p, len, &value);
        +			if(ret < 0) return -1;
        +			len -= ret;
        +			p += ret;
        +		}
        +		if(rfunc) {
        +			ret = rfunc(value, arg);
        +			if(ret <= 0) return ret;
        +		}
        +	}
        +	return 1;
        +}
        +
        +/* Various utility functions for traverse_string */
        +
        +/* Just count number of characters */
        +
        +static int in_utf8(unsigned long value, void *arg)
        +{
        +	int *nchar;
        +	nchar = arg;
        +	(*nchar)++;
        +	return 1;
        +}
        +
        +/* Determine size of output as a UTF8 String */
        +
        +static int out_utf8(unsigned long value, void *arg)
        +{
        +	int *outlen;
        +	outlen = arg;
        +	*outlen += UTF8_putc(NULL, -1, value);
        +	return 1;
        +}
        +
        +/* Determine the "type" of a string: check each character against a
        + * supplied "mask".
        + */
        +
        +static int type_str(unsigned long value, void *arg)
        +{
        +	unsigned long types;
        +	types = *((unsigned long *)arg);
        +	if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
        +					types &= ~B_ASN1_PRINTABLESTRING;
        +	if((types & B_ASN1_IA5STRING) && (value > 127))
        +					types &= ~B_ASN1_IA5STRING;
        +	if((types & B_ASN1_T61STRING) && (value > 0xff))
        +					types &= ~B_ASN1_T61STRING;
        +	if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
        +					types &= ~B_ASN1_BMPSTRING;
        +	if(!types) return -1;
        +	*((unsigned long *)arg) = types;
        +	return 1;
        +}
        +
        +/* Copy one byte per character ASCII like strings */
        +
        +static int cpy_asc(unsigned long value, void *arg)
        +{
        +	unsigned char **p, *q;
        +	p = arg;
        +	q = *p;
        +	*q = (unsigned char) value;
        +	(*p)++;
        +	return 1;
        +}
        +
        +/* Copy two byte per character BMPStrings */
        +
        +static int cpy_bmp(unsigned long value, void *arg)
        +{
        +	unsigned char **p, *q;
        +	p = arg;
        +	q = *p;
        +	*q++ = (unsigned char) ((value >> 8) & 0xff);
        +	*q = (unsigned char) (value & 0xff);
        +	*p += 2;
        +	return 1;
        +}
        +
        +/* Copy four byte per character UniversalStrings */
        +
        +static int cpy_univ(unsigned long value, void *arg)
        +{
        +	unsigned char **p, *q;
        +	p = arg;
        +	q = *p;
        +	*q++ = (unsigned char) ((value >> 24) & 0xff);
        +	*q++ = (unsigned char) ((value >> 16) & 0xff);
        +	*q++ = (unsigned char) ((value >> 8) & 0xff);
        +	*q = (unsigned char) (value & 0xff);
        +	*p += 4;
        +	return 1;
        +}
        +
        +/* Copy to a UTF8String */
        +
        +static int cpy_utf8(unsigned long value, void *arg)
        +{
        +	unsigned char **p;
        +	int ret;
        +	p = arg;
        +	/* We already know there is enough room so pass 0xff as the length */
        +	ret = UTF8_putc(*p, 0xff, value);
        +	*p += ret;
        +	return 1;
        +}
        +
        +/* Return 1 if the character is permitted in a PrintableString */
        +static int is_printable(unsigned long value)
        +{
        +	int ch;
        +	if(value > 0x7f) return 0;
        +	ch = (int) value;
        +	/* Note: we can't use 'isalnum' because certain accented 
        +	 * characters may count as alphanumeric in some environments.
        +	 */
        +#ifndef CHARSET_EBCDIC
        +	if((ch >= 'a') && (ch <= 'z')) return 1;
        +	if((ch >= 'A') && (ch <= 'Z')) return 1;
        +	if((ch >= '0') && (ch <= '9')) return 1;
        +	if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
        +#else /*CHARSET_EBCDIC*/
        +	if((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) return 1;
        +	if((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) return 1;
        +	if((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) return 1;
        +	if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) return 1;
        +#endif /*CHARSET_EBCDIC*/
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_object.c b/vendor/openssl/openssl/crypto/asn1/a_object.c
        new file mode 100644
        index 000000000..3978c9150
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_object.c
        @@ -0,0 +1,403 @@
        +/* crypto/asn1/a_object.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <limits.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/bn.h>
        +
        +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
        +	{
        +	unsigned char *p;
        +	int objsize;
        +
        +	if ((a == NULL) || (a->data == NULL)) return(0);
        +
        +	objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
        +	if (pp == NULL) return objsize;
        +
        +	p= *pp;
        +	ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
        +	memcpy(p,a->data,a->length);
        +	p+=a->length;
        +
        +	*pp=p;
        +	return(objsize);
        +	}
        +
        +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
        +	{
        +	int i,first,len=0,c, use_bn;
        +	char ftmp[24], *tmp = ftmp;
        +	int tmpsize = sizeof ftmp;
        +	const char *p;
        +	unsigned long l;
        +	BIGNUM *bl = NULL;
        +
        +	if (num == 0)
        +		return(0);
        +	else if (num == -1)
        +		num=strlen(buf);
        +
        +	p=buf;
        +	c= *(p++);
        +	num--;
        +	if ((c >= '0') && (c <= '2'))
        +		{
        +		first= c-'0';
        +		}
        +	else
        +		{
        +		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
        +		goto err;
        +		}
        +
        +	if (num <= 0)
        +		{
        +		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
        +		goto err;
        +		}
        +	c= *(p++);
        +	num--;
        +	for (;;)
        +		{
        +		if (num <= 0) break;
        +		if ((c != '.') && (c != ' '))
        +			{
        +			ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
        +			goto err;
        +			}
        +		l=0;
        +		use_bn = 0;
        +		for (;;)
        +			{
        +			if (num <= 0) break;
        +			num--;
        +			c= *(p++);
        +			if ((c == ' ') || (c == '.'))
        +				break;
        +			if ((c < '0') || (c > '9'))
        +				{
        +				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
        +				goto err;
        +				}
        +			if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
        +				{
        +				use_bn = 1;
        +				if (!bl)
        +					bl = BN_new();
        +				if (!bl || !BN_set_word(bl, l))
        +					goto err;
        +				}
        +			if (use_bn)
        +				{
        +				if (!BN_mul_word(bl, 10L)
        +					|| !BN_add_word(bl, c-'0'))
        +					goto err;
        +				}
        +			else
        +				l=l*10L+(long)(c-'0');
        +			}
        +		if (len == 0)
        +			{
        +			if ((first < 2) && (l >= 40))
        +				{
        +				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
        +				goto err;
        +				}
        +			if (use_bn)
        +				{
        +				if (!BN_add_word(bl, first * 40))
        +					goto err;
        +				}
        +			else
        +				l+=(long)first*40;
        +			}
        +		i=0;
        +		if (use_bn)
        +			{
        +			int blsize;
        +			blsize = BN_num_bits(bl);
        +			blsize = (blsize + 6)/7;
        +			if (blsize > tmpsize)
        +				{
        +				if (tmp != ftmp)
        +					OPENSSL_free(tmp);
        +				tmpsize = blsize + 32;
        +				tmp = OPENSSL_malloc(tmpsize);
        +				if (!tmp)
        +					goto err;
        +				}
        +			while(blsize--)
        +				tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
        +			}
        +		else
        +			{
        +					
        +			for (;;)
        +				{
        +				tmp[i++]=(unsigned char)l&0x7f;
        +				l>>=7L;
        +				if (l == 0L) break;
        +				}
        +
        +			}
        +		if (out != NULL)
        +			{
        +			if (len+i > olen)
        +				{
        +				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
        +				goto err;
        +				}
        +			while (--i > 0)
        +				out[len++]=tmp[i]|0x80;
        +			out[len++]=tmp[0];
        +			}
        +		else
        +			len+=i;
        +		}
        +	if (tmp != ftmp)
        +		OPENSSL_free(tmp);
        +	if (bl)
        +		BN_free(bl);
        +	return(len);
        +err:
        +	if (tmp != ftmp)
        +		OPENSSL_free(tmp);
        +	if (bl)
        +		BN_free(bl);
        +	return(0);
        +	}
        +
        +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
        +{
        +	return OBJ_obj2txt(buf, buf_len, a, 0);
        +}
        +
        +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
        +	{
        +	char buf[80], *p = buf;
        +	int i;
        +
        +	if ((a == NULL) || (a->data == NULL))
        +		return(BIO_write(bp,"NULL",4));
        +	i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
        +	if (i > (int)(sizeof(buf) - 1))
        +		{
        +		p = OPENSSL_malloc(i + 1);
        +		if (!p)
        +			return -1;
        +		i2t_ASN1_OBJECT(p,i + 1,a);
        +		}
        +	if (i <= 0)
        +		return BIO_write(bp, "<INVALID>", 9);
        +	BIO_write(bp,p,i);
        +	if (p != buf)
        +		OPENSSL_free(p);
        +	return(i);
        +	}
        +
        +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
        +	     long length)
        +{
        +	const unsigned char *p;
        +	long len;
        +	int tag,xclass;
        +	int inf,i;
        +	ASN1_OBJECT *ret = NULL;
        +	p= *pp;
        +	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
        +	if (inf & 0x80)
        +		{
        +		i=ASN1_R_BAD_OBJECT_HEADER;
        +		goto err;
        +		}
        +
        +	if (tag != V_ASN1_OBJECT)
        +		{
        +		i=ASN1_R_EXPECTING_AN_OBJECT;
        +		goto err;
        +		}
        +	ret = c2i_ASN1_OBJECT(a, &p, len);
        +	if(ret) *pp = p;
        +	return ret;
        +err:
        +	ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
        +	return(NULL);
        +}
        +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
        +	     long len)
        +	{
        +	ASN1_OBJECT *ret=NULL;
        +	const unsigned char *p;
        +	unsigned char *data;
        +	int i;
        +	/* Sanity check OID encoding: can't have leading 0x80 in
        +	 * subidentifiers, see: X.690 8.19.2
        +	 */
        +	for (i = 0, p = *pp; i < len; i++, p++)
        +		{
        +		if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
        +			{
        +			ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
        +			return NULL;
        +			}
        +		}
        +
        +	/* only the ASN1_OBJECTs from the 'table' will have values
        +	 * for ->sn or ->ln */
        +	if ((a == NULL) || ((*a) == NULL) ||
        +		!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
        +		{
        +		if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
        +		}
        +	else	ret=(*a);
        +
        +	p= *pp;
        +	/* detach data from object */
        +	data = (unsigned char *)ret->data;
        +	ret->data = NULL;
        +	/* once detached we can change it */
        +	if ((data == NULL) || (ret->length < len))
        +		{
        +		ret->length=0;
        +		if (data != NULL) OPENSSL_free(data);
        +		data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
        +		if (data == NULL)
        +			{ i=ERR_R_MALLOC_FAILURE; goto err; }
        +		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
        +		}
        +	memcpy(data,p,(int)len);
        +	/* reattach data to object, after which it remains const */
        +	ret->data  =data;
        +	ret->length=(int)len;
        +	ret->sn=NULL;
        +	ret->ln=NULL;
        +	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
        +	p+=len;
        +
        +	if (a != NULL) (*a)=ret;
        +	*pp=p;
        +	return(ret);
        +err:
        +	ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		ASN1_OBJECT_free(ret);
        +	return(NULL);
        +	}
        +
        +ASN1_OBJECT *ASN1_OBJECT_new(void)
        +	{
        +	ASN1_OBJECT *ret;
        +
        +	ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	ret->length=0;
        +	ret->data=NULL;
        +	ret->nid=0;
        +	ret->sn=NULL;
        +	ret->ln=NULL;
        +	ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
        +	return(ret);
        +	}
        +
        +void ASN1_OBJECT_free(ASN1_OBJECT *a)
        +	{
        +	if (a == NULL) return;
        +	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
        +		{
        +#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
        +		if (a->sn != NULL) OPENSSL_free((void *)a->sn);
        +		if (a->ln != NULL) OPENSSL_free((void *)a->ln);
        +#endif
        +		a->sn=a->ln=NULL;
        +		}
        +	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
        +		{
        +		if (a->data != NULL) OPENSSL_free((void *)a->data);
        +		a->data=NULL;
        +		a->length=0;
        +		}
        +	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
        +		OPENSSL_free(a);
        +	}
        +
        +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
        +	     const char *sn, const char *ln)
        +	{
        +	ASN1_OBJECT o;
        +
        +	o.sn=sn;
        +	o.ln=ln;
        +	o.data=data;
        +	o.nid=nid;
        +	o.length=len;
        +	o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
        +		ASN1_OBJECT_FLAG_DYNAMIC_DATA;
        +	return(OBJ_dup(&o));
        +	}
        +
        +IMPLEMENT_STACK_OF(ASN1_OBJECT)
        +IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_octet.c b/vendor/openssl/openssl/crypto/asn1/a_octet.c
        new file mode 100644
        index 000000000..e8725e44f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_octet.c
        @@ -0,0 +1,71 @@
        +/* crypto/asn1/a_octet.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
        +{ return M_ASN1_OCTET_STRING_dup(x); }
        +
        +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
        +{ return M_ASN1_OCTET_STRING_cmp(a, b); }
        +
        +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
        +{ return M_ASN1_OCTET_STRING_set(x, d, len); }
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_print.c b/vendor/openssl/openssl/crypto/asn1/a_print.c
        new file mode 100644
        index 000000000..d18e77232
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_print.c
        @@ -0,0 +1,127 @@
        +/* crypto/asn1/a_print.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +int ASN1_PRINTABLE_type(const unsigned char *s, int len)
        +	{
        +	int c;
        +	int ia5=0;
        +	int t61=0;
        +
        +	if (len <= 0) len= -1;
        +	if (s == NULL) return(V_ASN1_PRINTABLESTRING);
        +
        +	while ((*s) && (len-- != 0))
        +		{
        +		c= *(s++);
        +#ifndef CHARSET_EBCDIC
        +		if (!(	((c >= 'a') && (c <= 'z')) ||
        +			((c >= 'A') && (c <= 'Z')) ||
        +			(c == ' ') ||
        +			((c >= '0') && (c <= '9')) ||
        +			(c == ' ') || (c == '\'') ||
        +			(c == '(') || (c == ')') ||
        +			(c == '+') || (c == ',') ||
        +			(c == '-') || (c == '.') ||
        +			(c == '/') || (c == ':') ||
        +			(c == '=') || (c == '?')))
        +			ia5=1;
        +		if (c&0x80)
        +			t61=1;
        +#else
        +		if (!isalnum(c) && (c != ' ') &&
        +		    strchr("'()+,-./:=?", c) == NULL)
        +			ia5=1;
        +		if (os_toascii[c] & 0x80)
        +			t61=1;
        +#endif
        +		}
        +	if (t61) return(V_ASN1_T61STRING);
        +	if (ia5) return(V_ASN1_IA5STRING);
        +	return(V_ASN1_PRINTABLESTRING);
        +	}
        +
        +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
        +	{
        +	int i;
        +	unsigned char *p;
        +
        +	if (s->type != V_ASN1_UNIVERSALSTRING) return(0);
        +	if ((s->length%4) != 0) return(0);
        +	p=s->data;
        +	for (i=0; i<s->length; i+=4)
        +		{
        +		if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
        +			break;
        +		else
        +			p+=4;
        +		}
        +	if (i < s->length) return(0);
        +	p=s->data;
        +	for (i=3; i<s->length; i+=4)
        +		{
        +		*(p++)=s->data[i];
        +		}
        +	*(p)='\0';
        +	s->length/=4;
        +	s->type=ASN1_PRINTABLE_type(s->data,s->length);
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_set.c b/vendor/openssl/openssl/crypto/asn1/a_set.c
        new file mode 100644
        index 000000000..d726c8d3a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_set.c
        @@ -0,0 +1,241 @@
        +/* crypto/asn1/a_set.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1_mac.h>
        +
        +#ifndef NO_ASN1_OLD
        +
        +typedef struct
        +    {
        +    unsigned char *pbData;
        +    int cbData;
        +    } MYBLOB;
        +
        +/* SetBlobCmp
        + * This function compares two elements of SET_OF block
        + */
        +static int SetBlobCmp(const void *elem1, const void *elem2 )
        +    {
        +    const MYBLOB *b1 = (const MYBLOB *)elem1;
        +    const MYBLOB *b2 = (const MYBLOB *)elem2;
        +    int r;
        +
        +    r = memcmp(b1->pbData, b2->pbData,
        +	       b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
        +    if(r != 0)
        +	return r;
        +    return b1->cbData-b2->cbData;
        +    }
        +
        +/* int is_set:  if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)    */
        +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
        +		 i2d_of_void *i2d, int ex_tag, int ex_class,
        +		 int is_set)
        +	{
        +	int ret=0,r;
        +	int i;
        +	unsigned char *p;
        +        unsigned char *pStart, *pTempMem;
        +        MYBLOB *rgSetBlob;
        +        int totSize;
        +
        +	if (a == NULL) return(0);
        +	for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--)
        +		ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL);
        +	r=ASN1_object_size(1,ret,ex_tag);
        +	if (pp == NULL) return(r);
        +
        +	p= *pp;
        +	ASN1_put_object(&p,1,ret,ex_tag,ex_class);
        +
        +/* Modified by gp@nsj.co.jp */
        +	/* And then again by Ben */
        +	/* And again by Steve */
        +
        +	if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2))
        +		{
        +		for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
        +                	i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
        +
        +		*pp=p;
        +		return(r);
        +		}
        +
        +        pStart  = p; /* Catch the beg of Setblobs*/
        +		/* In this array we will store the SET blobs */
        +		rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
        +		if (rgSetBlob == NULL)
        +			{
        +			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +
        +        for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
        +	        {
        +                rgSetBlob[i].pbData = p;  /* catch each set encode blob */
        +                i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
        +                rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
        +SetBlob
        +*/
        +		}
        +        *pp=p;
        +        totSize = p - pStart; /* This is the total size of all set blobs */
        +
        + /* Now we have to sort the blobs. I am using a simple algo.
        +    *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
        +        qsort( rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
        +		if (!(pTempMem = OPENSSL_malloc(totSize)))
        +			{
        +			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +
        +/* Copy to temp mem */
        +        p = pTempMem;
        +        for(i=0; i<sk_OPENSSL_BLOCK_num(a); ++i)
        +		{
        +                memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
        +                p += rgSetBlob[i].cbData;
        +		}
        +
        +/* Copy back to user mem*/
        +        memcpy(pStart, pTempMem, totSize);
        +        OPENSSL_free(pTempMem);
        +        OPENSSL_free(rgSetBlob);
        +
        +        return(r);
        +        }
        +
        +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
        +			      const unsigned char **pp,
        +			      long length, d2i_of_void *d2i,
        +			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
        +			      int ex_class)
        +	{
        +	ASN1_const_CTX c;
        +	STACK_OF(OPENSSL_BLOCK) *ret=NULL;
        +
        +	if ((a == NULL) || ((*a) == NULL))
        +		{
        +		if ((ret=sk_OPENSSL_BLOCK_new_null()) == NULL)
        +			{
        +			ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	else
        +		ret=(*a);
        +
        +	c.p= *pp;
        +	c.max=(length == 0)?0:(c.p+length);
        +
        +	c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,c.max-c.p);
        +	if (c.inf & 0x80) goto err;
        +	if (ex_class != c.xclass)
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS);
        +		goto err;
        +		}
        +	if (ex_tag != c.tag)
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG);
        +		goto err;
        +		}
        +	if ((c.slen+c.p) > c.max)
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR);
        +		goto err;
        +		}
        +	/* check for infinite constructed - it can be as long
        +	 * as the amount of data passed to us */
        +	if (c.inf == (V_ASN1_CONSTRUCTED+1))
        +		c.slen=length+ *pp-c.p;
        +	c.max=c.p+c.slen;
        +
        +	while (c.p < c.max)
        +		{
        +		char *s;
        +
        +		if (M_ASN1_D2I_end_sequence()) break;
        +		/* XXX: This was called with 4 arguments, incorrectly, it seems
        +		   if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) */
        +		if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
        +			{
        +			ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
        +			asn1_add_error(*pp,(int)(c.p- *pp));
        +			goto err;
        +			}
        +		if (!sk_OPENSSL_BLOCK_push(ret,s)) goto err;
        +		}
        +	if (a != NULL) (*a)=ret;
        +	*pp=c.p;
        +	return(ret);
        +err:
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		{
        +		if (free_func != NULL)
        +			sk_OPENSSL_BLOCK_pop_free(ret,free_func);
        +		else
        +			sk_OPENSSL_BLOCK_free(ret);
        +		}
        +	return(NULL);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_sign.c b/vendor/openssl/openssl/crypto/asn1/a_sign.c
        new file mode 100644
        index 000000000..7b4a193d6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_sign.c
        @@ -0,0 +1,333 @@
        +/* crypto/asn1/a_sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <time.h>
        +
        +#include "cryptlib.h"
        +
        +#ifndef NO_SYS_TYPES_H
        +# include <sys/types.h>
        +#endif
        +
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +#include "asn1_locl.h"
        +
        +#ifndef NO_ASN1_OLD
        +
        +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
        +	      ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
        +	      const EVP_MD *type)
        +	{
        +	EVP_MD_CTX ctx;
        +	unsigned char *p,*buf_in=NULL,*buf_out=NULL;
        +	int i,inl=0,outl=0,outll=0;
        +	X509_ALGOR *a;
        +
        +	EVP_MD_CTX_init(&ctx);
        +	for (i=0; i<2; i++)
        +		{
        +		if (i == 0)
        +			a=algor1;
        +		else
        +			a=algor2;
        +		if (a == NULL) continue;
        +                if (type->pkey_type == NID_dsaWithSHA1)
        +			{
        +			/* special case: RFC 2459 tells us to omit 'parameters'
        +			 * with id-dsa-with-sha1 */
        +			ASN1_TYPE_free(a->parameter);
        +			a->parameter = NULL;
        +			}
        +		else if ((a->parameter == NULL) || 
        +			(a->parameter->type != V_ASN1_NULL))
        +			{
        +			ASN1_TYPE_free(a->parameter);
        +			if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
        +			a->parameter->type=V_ASN1_NULL;
        +			}
        +		ASN1_OBJECT_free(a->algorithm);
        +		a->algorithm=OBJ_nid2obj(type->pkey_type);
        +		if (a->algorithm == NULL)
        +			{
        +			ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
        +			goto err;
        +			}
        +		if (a->algorithm->length == 0)
        +			{
        +			ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
        +			goto err;
        +			}
        +		}
        +	inl=i2d(data,NULL);
        +	buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
        +	outll=outl=EVP_PKEY_size(pkey);
        +	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
        +	if ((buf_in == NULL) || (buf_out == NULL))
        +		{
        +		outl=0;
        +		ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	p=buf_in;
        +
        +	i2d(data,&p);
        +	if (!EVP_SignInit_ex(&ctx,type, NULL)
        +		|| !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
        +		|| !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
        +			(unsigned int *)&outl,pkey))
        +		{
        +		outl=0;
        +		ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +	if (signature->data != NULL) OPENSSL_free(signature->data);
        +	signature->data=buf_out;
        +	buf_out=NULL;
        +	signature->length=outl;
        +	/* In the interests of compatibility, I'll make sure that
        +	 * the bit string has a 'not-used bits' value of 0
        +	 */
        +	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        +	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
        +err:
        +	EVP_MD_CTX_cleanup(&ctx);
        +	if (buf_in != NULL)
        +		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
        +	if (buf_out != NULL)
        +		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
        +	return(outl);
        +	}
        +
        +#endif
        +
        +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        +	     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
        +	     const EVP_MD *type)
        +	{
        +	EVP_MD_CTX ctx;
        +	EVP_MD_CTX_init(&ctx);
        +	if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
        +		{
        +		EVP_MD_CTX_cleanup(&ctx);
        +		return 0;
        +		}
        +	return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
        +	}
        +		
        +
        +int ASN1_item_sign_ctx(const ASN1_ITEM *it,
        +		X509_ALGOR *algor1, X509_ALGOR *algor2,
        +	     	ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
        +	{
        +	const EVP_MD *type;
        +	EVP_PKEY *pkey;
        +	unsigned char *buf_in=NULL,*buf_out=NULL;
        +	size_t inl=0,outl=0,outll=0;
        +	int signid, paramtype;
        +	int rv;
        +
        +	type = EVP_MD_CTX_md(ctx);
        +	pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
        +
        +	if (!type || !pkey)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
        +		return 0;
        +		}
        +
        +	if (pkey->ameth->item_sign)
        +		{
        +		rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
        +						signature);
        +		if (rv == 1)
        +			outl = signature->length;
        +		/* Return value meanings:
        +		 * <=0: error.
        +		 *   1: method does everything.
        +		 *   2: carry on as normal.
        +		 *   3: ASN1 method sets algorithm identifiers: just sign.
        +		 */
        +		if (rv <= 0)
        +			ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
        +		if (rv <= 1)
        +			goto err;
        +		}
        +	else
        +		rv = 2;
        +
        +	if (rv == 2)
        +		{
        +		if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
        +			{
        +			if (!pkey->ameth ||
        +				!OBJ_find_sigid_by_algs(&signid,
        +							EVP_MD_nid(type),
        +							pkey->ameth->pkey_id))
        +				{
        +				ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
        +					ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
        +				return 0;
        +				}
        +			}
        +		else
        +			signid = type->pkey_type;
        +
        +		if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
        +			paramtype = V_ASN1_NULL;
        +		else
        +			paramtype = V_ASN1_UNDEF;
        +
        +		if (algor1)
        +			X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
        +		if (algor2)
        +			X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
        +
        +		}
        +
        +	inl=ASN1_item_i2d(asn,&buf_in, it);
        +	outll=outl=EVP_PKEY_size(pkey);
        +	buf_out=OPENSSL_malloc((unsigned int)outl);
        +	if ((buf_in == NULL) || (buf_out == NULL))
        +		{
        +		outl=0;
        +		ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
        +		|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
        +		{
        +		outl=0;
        +		ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +	if (signature->data != NULL) OPENSSL_free(signature->data);
        +	signature->data=buf_out;
        +	buf_out=NULL;
        +	signature->length=outl;
        +	/* In the interests of compatibility, I'll make sure that
        +	 * the bit string has a 'not-used bits' value of 0
        +	 */
        +	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        +	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
        +err:
        +	EVP_MD_CTX_cleanup(ctx);
        +	if (buf_in != NULL)
        +		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
        +	if (buf_out != NULL)
        +		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
        +	return(outl);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_strex.c b/vendor/openssl/openssl/crypto/asn1/a_strex.c
        new file mode 100644
        index 000000000..bf63330f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_strex.c
        @@ -0,0 +1,576 @@
        +/* a_strex.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stdio.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/crypto.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +
        +#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)
        +
        +#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
        +		  ASN1_STRFLGS_ESC_QUOTE | \
        +		  ASN1_STRFLGS_ESC_CTRL | \
        +		  ASN1_STRFLGS_ESC_MSB)
        +
        +
        +/* Three IO functions for sending data to memory, a BIO and
        + * and a FILE pointer.
        + */
        +#if 0				/* never used */
        +static 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;
        +}
        +#endif
        +
        +static 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;
        +}
        +
        +static 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[HEX_SIZE(long)+3];
        +
        +	if(c > 0xffffffffL)
        +		return -1;
        +	if(c > 0xffff) {
        +		BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
        +		if(!io_ch(arg, tmphex, 10)) return -1;
        +		return 10;
        +	}
        +	if(c > 0xff) {
        +		BIO_snprintf(tmphex, sizeof tmphex, "\\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 we get this far and do any escaping at all must escape 
        +	 * the escape character itself: backslash.
        +	 */
        +	if (chtmp == '\\' && flags & ESC_FLAGS) {
        +		if(!io_ch(arg, "\\\\", 2)) return -1;
        +		return 2;
        +	}
        +	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 && flags & ASN1_STRFLGS_ESC_2253) 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;
        +			default:
        +			return -1;	/* invalid width */
        +		}
        +		if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
        +		if(type & BUF_TYPE_CONVUTF8) {
        +			unsigned char utfbuf[6];
        +			int utflen;
        +			utflen = UTF8_putc(utfbuf, sizeof utfbuf, 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)
        +{
        +	static const 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.
        + */
        +
        +static 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
        + */
        +
        +static const signed 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 */
        +};
        +
        +/* 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, &quotes, io_ch, NULL);
        +	if(len < 0) return -1;
        +	outlen += len;
        +	if(quotes) outlen += 2;
        +	if(!arg) return outlen;
        +	if(quotes && !io_ch(arg, "\"", 1)) return -1;
        +	if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
        +		return -1;
        +	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;
        +}
        +
        +#define FN_WIDTH_LN	25
        +#define FN_WIDTH_SN	10
        +
        +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, fld_len;
        +			if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
        +				OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
        +				fld_len = 0; /* XXX: what should this be? */
        +				objbuf = objtmp;
        +			} else {
        +				if(fn_opt == XN_FLAG_FN_SN) {
        +					fld_len = FN_WIDTH_SN;
        +					objbuf = OBJ_nid2sn(fn_nid);
        +				} else if(fn_opt == XN_FLAG_FN_LN) {
        +					fld_len = FN_WIDTH_LN;
        +					objbuf = OBJ_nid2ln(fn_nid);
        +				} else {
        +					fld_len = 0; /* XXX: what should this be? */
        +					objbuf = "";
        +				}
        +			}
        +			objlen = strlen(objbuf);
        +			if(!io_ch(arg, objbuf, objlen)) return -1;
        +			if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
        +				if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
        +				outlen += fld_len - objlen;
        +			}
        +			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)
        +{
        +	if(flags == XN_FLAG_COMPAT)
        +		return X509_NAME_print(out, nm, indent);
        +	return do_name_ex(send_bio_chars, out, nm, indent, flags);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
        +{
        +	if(flags == XN_FLAG_COMPAT)
        +		{
        +		BIO *btmp;
        +		int ret;
        +		btmp = BIO_new_fp(fp, BIO_NOCLOSE);
        +		if(!btmp) return -1;
        +		ret = X509_NAME_print(btmp, nm, indent);
        +		BIO_free(btmp);
        +		return ret;
        +		}
        +	return do_name_ex(send_fp_chars, fp, nm, indent, flags);
        +}
        +#endif
        +
        +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
        +{
        +	return do_print_ex(send_bio_chars, out, flags, str);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
        +{
        +	return do_print_ex(send_fp_chars, fp, flags, str);
        +}
        +#endif
        +
        +/* 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(!in) return -1;
        +	type = in->type;
        +	if((type < 0) || (type > 30)) return -1;
        +	mbflag = tag2nbyte[type];
        +	if(mbflag == -1) return -1;
        +	mbflag |= MBSTRING_FLAG;
        +	memset(&stmp, 0, sizeof(stmp));
        +	stmp.data = NULL;
        +	stmp.length = 0;
        +	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
        +	if(ret < 0) return ret;
        +	*out = stmp.data;
        +	return stmp.length;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_strnid.c b/vendor/openssl/openssl/crypto/asn1/a_strnid.c
        new file mode 100644
        index 000000000..2fc48c155
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_strnid.c
        @@ -0,0 +1,290 @@
        +/* a_strnid.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +
        +
        +static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
        +static void st_free(ASN1_STRING_TABLE *tbl);
        +static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
        +			const ASN1_STRING_TABLE * const *b);
        +
        +
        +/* This is the global mask for the mbstring functions: this is use to
        + * mask out certain types (such as BMPString and UTF8String) because
        + * certain software (e.g. Netscape) has problems with them.
        + */
        +
        +static unsigned long global_mask = 0xFFFFFFFFL;
        +
        +void ASN1_STRING_set_default_mask(unsigned long mask)
        +{
        +	global_mask = mask;
        +}
        +
        +unsigned long ASN1_STRING_get_default_mask(void)
        +{
        +	return global_mask;
        +}
        +
        +/* This function sets the default to various "flavours" of configuration.
        + * based on an ASCII string. Currently this is:
        + * MASK:XXXX : a numerical mask value.
        + * nobmp : Don't use BMPStrings (just Printable, T61).
        + * pkix : PKIX recommendation in RFC2459.
        + * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
        + * default:   the default value, Printable, T61, BMP.
        + */
        +
        +int ASN1_STRING_set_default_mask_asc(const char *p)
        +{
        +	unsigned long mask;
        +	char *end;
        +	if(!strncmp(p, "MASK:", 5)) {
        +		if(!p[5]) return 0;
        +		mask = strtoul(p + 5, &end, 0);
        +		if(*end) return 0;
        +	} else if(!strcmp(p, "nombstr"))
        +			 mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
        +	else if(!strcmp(p, "pkix"))
        +			mask = ~((unsigned long)B_ASN1_T61STRING);
        +	else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
        +	else if(!strcmp(p, "default"))
        +	    mask = 0xFFFFFFFFL;
        +	else return 0;
        +	ASN1_STRING_set_default_mask(mask);
        +	return 1;
        +}
        +
        +/* The following function generates an ASN1_STRING based on limits in a table.
        + * Frequently the types and length of an ASN1_STRING are restricted by a 
        + * corresponding OID. For example certificates and certificate requests.
        + */
        +
        +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
        +					int inlen, int inform, int nid)
        +{
        +	ASN1_STRING_TABLE *tbl;
        +	ASN1_STRING *str = NULL;
        +	unsigned long mask;
        +	int ret;
        +	if(!out) out = &str;
        +	tbl = ASN1_STRING_TABLE_get(nid);
        +	if(tbl) {
        +		mask = tbl->mask;
        +		if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
        +		ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
        +					tbl->minsize, tbl->maxsize);
        +	} else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
        +	if(ret <= 0) return NULL;
        +	return *out;
        +}
        +
        +/* Now the tables and helper functions for the string table:
        + */
        +
        +/* size limits: this stuff is taken straight from RFC3280 */
        +
        +#define ub_name				32768
        +#define ub_common_name			64
        +#define ub_locality_name		128
        +#define ub_state_name			128
        +#define ub_organization_name		64
        +#define ub_organization_unit_name	64
        +#define ub_title			64
        +#define ub_email_address		128
        +#define ub_serial_number		64
        +
        +
        +/* This table must be kept in NID order */
        +
        +static const ASN1_STRING_TABLE tbl_standard[] = {
        +{NID_commonName,		1, ub_common_name, DIRSTRING_TYPE, 0},
        +{NID_countryName,		2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        +{NID_localityName,		1, ub_locality_name, DIRSTRING_TYPE, 0},
        +{NID_stateOrProvinceName,	1, ub_state_name, DIRSTRING_TYPE, 0},
        +{NID_organizationName,		1, ub_organization_name, DIRSTRING_TYPE, 0},
        +{NID_organizationalUnitName,	1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
        +{NID_pkcs9_emailAddress,	1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
        +{NID_pkcs9_unstructuredName,	1, -1, PKCS9STRING_TYPE, 0},
        +{NID_pkcs9_challengePassword,	1, -1, PKCS9STRING_TYPE, 0},
        +{NID_pkcs9_unstructuredAddress,	1, -1, DIRSTRING_TYPE, 0},
        +{NID_givenName,			1, ub_name, DIRSTRING_TYPE, 0},
        +{NID_surname,			1, ub_name, DIRSTRING_TYPE, 0},
        +{NID_initials,			1, ub_name, DIRSTRING_TYPE, 0},
        +{NID_serialNumber,		1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        +{NID_friendlyName,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
        +{NID_name,			1, ub_name, DIRSTRING_TYPE, 0},
        +{NID_dnQualifier,		-1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        +{NID_domainComponent,		1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
        +{NID_ms_csp_name,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
        +};
        +
        +static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
        +			const ASN1_STRING_TABLE * const *b)
        +{
        +	return (*a)->nid - (*b)->nid;
        +}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
        +
        +static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
        +{
        +	return a->nid - b->nid;
        +}
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
        +
        +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
        +{
        +	int idx;
        +	ASN1_STRING_TABLE *ttmp;
        +	ASN1_STRING_TABLE fnd;
        +	fnd.nid = nid;
        +	ttmp = OBJ_bsearch_table(&fnd, tbl_standard, 
        +			   sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
        +	if(ttmp) return ttmp;
        +	if(!stable) return NULL;
        +	idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
        +	if(idx < 0) return NULL;
        +	return sk_ASN1_STRING_TABLE_value(stable, idx);
        +}
        +	
        +int ASN1_STRING_TABLE_add(int nid,
        +		 long minsize, long maxsize, unsigned long mask,
        +				unsigned long flags)
        +{
        +	ASN1_STRING_TABLE *tmp;
        +	char new_nid = 0;
        +	flags &= ~STABLE_FLAGS_MALLOC;
        +	if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
        +	if(!stable) {
        +		ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
        +		tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
        +		if(!tmp) {
        +			ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
        +							ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		tmp->flags = flags | STABLE_FLAGS_MALLOC;
        +		tmp->nid = nid;
        +		new_nid = 1;
        +	} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
        +	if(minsize != -1) tmp->minsize = minsize;
        +	if(maxsize != -1) tmp->maxsize = maxsize;
        +	tmp->mask = mask;
        +	if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
        +	return 1;
        +}
        +
        +void ASN1_STRING_TABLE_cleanup(void)
        +{
        +	STACK_OF(ASN1_STRING_TABLE) *tmp;
        +	tmp = stable;
        +	if(!tmp) return;
        +	stable = NULL;
        +	sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
        +}
        +
        +static void st_free(ASN1_STRING_TABLE *tbl)
        +{
        +	if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
        +}
        +
        +
        +IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
        +
        +#ifdef STRING_TABLE_TEST
        +
        +main()
        +{
        +	ASN1_STRING_TABLE *tmp;
        +	int i, last_nid = -1;
        +
        +	for (tmp = tbl_standard, i = 0;
        +		i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
        +		{
        +			if (tmp->nid < last_nid)
        +				{
        +				last_nid = 0;
        +				break;
        +				}
        +			last_nid = tmp->nid;
        +		}
        +
        +	if (last_nid != 0)
        +		{
        +		printf("Table order OK\n");
        +		exit(0);
        +		}
        +
        +	for (tmp = tbl_standard, i = 0;
        +		i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
        +			printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
        +							OBJ_nid2ln(tmp->nid));
        +
        +}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_time.c b/vendor/openssl/openssl/crypto/asn1/a_time.c
        new file mode 100644
        index 000000000..e2eb9b243
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_time.c
        @@ -0,0 +1,198 @@
        +/* crypto/asn1/a_time.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
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +
        +/* This is an implementation of the ASN1 Time structure which is:
        + *    Time ::= CHOICE {
        + *      utcTime        UTCTime,
        + *      generalTime    GeneralizedTime }
        + * written by Steve Henson.
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include "o_time.h"
        +#include <openssl/asn1t.h>
        +
        +IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
        +
        +#if 0
        +int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
        +	{
        +#ifdef CHARSET_EBCDIC
        +	/* KLUDGE! We convert to ascii before writing DER */
        +	char tmp[24];
        +	ASN1_STRING tmpstr;
        +
        +	if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
        +	    int len;
        +
        +	    tmpstr = *(ASN1_STRING *)a;
        +	    len = tmpstr.length;
        +	    ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
        +	    tmpstr.data = tmp;
        +	    a = (ASN1_GENERALIZEDTIME *) &tmpstr;
        +	}
        +#endif
        +	if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
        +				return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
        +				     a->type ,V_ASN1_UNIVERSAL));
        +	ASN1err(ASN1_F_I2D_ASN1_TIME,ASN1_R_EXPECTING_A_TIME);
        +	return -1;
        +	}
        +#endif
        +
        +
        +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
        +	{
        +	return ASN1_TIME_adj(s, t, 0, 0);
        +	}
        +
        +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
        +				int offset_day, long offset_sec)
        +	{
        +	struct tm *ts;
        +	struct tm data;
        +
        +	ts=OPENSSL_gmtime(&t,&data);
        +	if (ts == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
        +		return NULL;
        +		}
        +	if (offset_day || offset_sec)
        +		{ 
        +		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
        +			return NULL;
        +		}
        +	if((ts->tm_year >= 50) && (ts->tm_year < 150))
        +			return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
        +	return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
        +	}
        +
        +int ASN1_TIME_check(ASN1_TIME *t)
        +	{
        +	if (t->type == V_ASN1_GENERALIZEDTIME)
        +		return ASN1_GENERALIZEDTIME_check(t);
        +	else if (t->type == V_ASN1_UTCTIME)
        +		return ASN1_UTCTIME_check(t);
        +	return 0;
        +	}
        +
        +/* Convert an ASN1_TIME structure to GeneralizedTime */
        +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
        +	{
        +	ASN1_GENERALIZEDTIME *ret;
        +	char *str;
        +	int newlen;
        +
        +	if (!ASN1_TIME_check(t)) return NULL;
        +
        +	if (!out || !*out)
        +		{
        +		if (!(ret = ASN1_GENERALIZEDTIME_new ()))
        +			return NULL;
        +		if (out) *out = ret;
        +		}
        +	else ret = *out;
        +
        +	/* If already GeneralizedTime just copy across */
        +	if (t->type == V_ASN1_GENERALIZEDTIME)
        +		{
        +		if(!ASN1_STRING_set(ret, t->data, t->length))
        +			return NULL;
        +		return ret;
        +		}
        +
        +	/* grow the string */
        +	if (!ASN1_STRING_set(ret, NULL, t->length + 2))
        +		return NULL;
        +	/* ASN1_STRING_set() allocated 'len + 1' bytes. */
        +	newlen = t->length + 2 + 1;
        +	str = (char *)ret->data;
        +	/* Work out the century and prepend */
        +	if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
        +	else BUF_strlcpy(str, "20", newlen);
        +
        +	BUF_strlcat(str, (char *)t->data, newlen);
        +
        +	return ret;
        +	}
        +
        +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
        +	{
        +	ASN1_TIME t;
        +
        +	t.length = strlen(str);
        +	t.data = (unsigned char *)str;
        +	t.flags = 0;
        +	
        +	t.type = V_ASN1_UTCTIME;
        +
        +	if (!ASN1_TIME_check(&t))
        +		{
        +		t.type = V_ASN1_GENERALIZEDTIME;
        +		if (!ASN1_TIME_check(&t))
        +			return 0;
        +		}
        +	
        +	if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
        +			return 0;
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_type.c b/vendor/openssl/openssl/crypto/asn1/a_type.c
        new file mode 100644
        index 000000000..a45d2f9d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_type.c
        @@ -0,0 +1,159 @@
        +/* crypto/asn1/a_type.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +
        +int ASN1_TYPE_get(ASN1_TYPE *a)
        +	{
        +	if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
        +		return(a->type);
        +	else
        +		return(0);
        +	}
        +
        +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
        +	{
        +	if (a->value.ptr != NULL)
        +		{
        +		ASN1_TYPE **tmp_a = &a;
        +		ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
        +		}
        +	a->type=type;
        +	if (type == V_ASN1_BOOLEAN)
        +		a->value.boolean = value ? 0xff : 0;
        +	else
        +		a->value.ptr=value;
        +	}
        +
        +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
        +	{
        +	if (!value || (type == V_ASN1_BOOLEAN))
        +		{
        +		void *p = (void *)value;
        +		ASN1_TYPE_set(a, type, p);
        +		}
        +	else if (type == V_ASN1_OBJECT)
        +		{
        +		ASN1_OBJECT *odup;
        +		odup = OBJ_dup(value);
        +		if (!odup)
        +			return 0;
        +		ASN1_TYPE_set(a, type, odup);
        +		}
        +	else
        +		{
        +		ASN1_STRING *sdup;
        +		sdup = ASN1_STRING_dup(value);
        +		if (!sdup)
        +			return 0;
        +		ASN1_TYPE_set(a, type, sdup);
        +		}
        +	return 1;
        +	}
        +
        +IMPLEMENT_STACK_OF(ASN1_TYPE)
        +IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
        +
        +/* Returns 0 if they are equal, != 0 otherwise. */
        +int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
        +	{
        +	int result = -1;
        +
        +	if (!a || !b || a->type != b->type) return -1;
        +
        +	switch (a->type)
        +		{
        +	case V_ASN1_OBJECT:
        +		result = OBJ_cmp(a->value.object, b->value.object);
        +		break;
        +	case V_ASN1_NULL:
        +		result = 0;	/* They do not have content. */
        +		break;
        +	case V_ASN1_INTEGER:
        +	case V_ASN1_NEG_INTEGER:
        +	case V_ASN1_ENUMERATED:
        +	case V_ASN1_NEG_ENUMERATED:
        +	case V_ASN1_BIT_STRING:
        +	case V_ASN1_OCTET_STRING:
        +	case V_ASN1_SEQUENCE:
        +	case V_ASN1_SET:
        +	case V_ASN1_NUMERICSTRING:
        +	case V_ASN1_PRINTABLESTRING:
        +	case V_ASN1_T61STRING:
        +	case V_ASN1_VIDEOTEXSTRING:
        +	case V_ASN1_IA5STRING:
        +	case V_ASN1_UTCTIME:
        +	case V_ASN1_GENERALIZEDTIME:
        +	case V_ASN1_GRAPHICSTRING:
        +	case V_ASN1_VISIBLESTRING:
        +	case V_ASN1_GENERALSTRING:
        +	case V_ASN1_UNIVERSALSTRING:
        +	case V_ASN1_BMPSTRING:
        +	case V_ASN1_UTF8STRING:
        +	case V_ASN1_OTHER:
        +	default:
        +		result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
        +					 (ASN1_STRING *) b->value.ptr);
        +		break;
        +		}
        +
        +	return result;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_utctm.c b/vendor/openssl/openssl/crypto/asn1/a_utctm.c
        new file mode 100644
        index 000000000..072e23659
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_utctm.c
        @@ -0,0 +1,318 @@
        +/* crypto/asn1/a_utctm.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include "o_time.h"
        +#include <openssl/asn1.h>
        +
        +#if 0
        +int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
        +	{
        +#ifndef CHARSET_EBCDIC
        +	return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
        +		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
        +#else
        +	/* KLUDGE! We convert to ascii before writing DER */
        +	int len;
        +	char tmp[24];
        +	ASN1_STRING x = *(ASN1_STRING *)a;
        +
        +	len = x.length;
        +	ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
        +	x.data = tmp;
        +	return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
        +#endif
        +	}
        +
        +
        +ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
        +	     long length)
        +	{
        +	ASN1_UTCTIME *ret=NULL;
        +
        +	ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
        +		V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ERR_R_NESTED_ASN1_ERROR);
        +		return(NULL);
        +		}
        +#ifdef CHARSET_EBCDIC
        +	ascii2ebcdic(ret->data, ret->data, ret->length);
        +#endif
        +	if (!ASN1_UTCTIME_check(ret))
        +		{
        +		ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ASN1_R_INVALID_TIME_FORMAT);
        +		goto err;
        +		}
        +
        +	return(ret);
        +err:
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        +		M_ASN1_UTCTIME_free(ret);
        +	return(NULL);
        +	}
        +
        +#endif
        +
        +int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
        +	{
        +	static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
        +	static const int max[8]={99,12,31,23,59,59,12,59};
        +	char *a;
        +	int n,i,l,o;
        +
        +	if (d->type != V_ASN1_UTCTIME) return(0);
        +	l=d->length;
        +	a=(char *)d->data;
        +	o=0;
        +
        +	if (l < 11) goto err;
        +	for (i=0; i<6; i++)
        +		{
        +		if ((i == 5) && ((a[o] == 'Z') ||
        +			(a[o] == '+') || (a[o] == '-')))
        +			{ i++; break; }
        +		if ((a[o] < '0') || (a[o] > '9')) goto err;
        +		n= a[o]-'0';
        +		if (++o > l) goto err;
        +
        +		if ((a[o] < '0') || (a[o] > '9')) goto err;
        +		n=(n*10)+ a[o]-'0';
        +		if (++o > l) goto err;
        +
        +		if ((n < min[i]) || (n > max[i])) goto err;
        +		}
        +	if (a[o] == 'Z')
        +		o++;
        +	else if ((a[o] == '+') || (a[o] == '-'))
        +		{
        +		o++;
        +		if (o+4 > l) goto err;
        +		for (i=6; i<8; i++)
        +			{
        +			if ((a[o] < '0') || (a[o] > '9')) goto err;
        +			n= a[o]-'0';
        +			o++;
        +			if ((a[o] < '0') || (a[o] > '9')) goto err;
        +			n=(n*10)+ a[o]-'0';
        +			if ((n < min[i]) || (n > max[i])) goto err;
        +			o++;
        +			}
        +		}
        +	return(o == l);
        +err:
        +	return(0);
        +	}
        +
        +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
        +	{
        +	ASN1_UTCTIME t;
        +
        +	t.type=V_ASN1_UTCTIME;
        +	t.length=strlen(str);
        +	t.data=(unsigned char *)str;
        +	if (ASN1_UTCTIME_check(&t))
        +		{
        +		if (s != NULL)
        +			{
        +			if (!ASN1_STRING_set((ASN1_STRING *)s,
        +				(unsigned char *)str,t.length))
        +				return 0;
        +			s->type = V_ASN1_UTCTIME;
        +			}
        +		return(1);
        +		}
        +	else
        +		return(0);
        +	}
        +
        +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
        +	{
        +	return ASN1_UTCTIME_adj(s, t, 0, 0);
        +	}
        +
        +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
        +				int offset_day, long offset_sec)
        +	{
        +	char *p;
        +	struct tm *ts;
        +	struct tm data;
        +	size_t len = 20;
        +
        +	if (s == NULL)
        +		s=M_ASN1_UTCTIME_new();
        +	if (s == NULL)
        +		return(NULL);
        +
        +	ts=OPENSSL_gmtime(&t, &data);
        +	if (ts == NULL)
        +		return(NULL);
        +
        +	if (offset_day || offset_sec)
        +		{ 
        +		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
        +			return NULL;
        +		}
        +
        +	if((ts->tm_year < 50) || (ts->tm_year >= 150))
        +		return NULL;
        +
        +	p=(char *)s->data;
        +	if ((p == NULL) || ((size_t)s->length < len))
        +		{
        +		p=OPENSSL_malloc(len);
        +		if (p == NULL)
        +			{
        +			ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		if (s->data != NULL)
        +			OPENSSL_free(s->data);
        +		s->data=(unsigned char *)p;
        +		}
        +
        +	BIO_snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
        +		     ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
        +	s->length=strlen(p);
        +	s->type=V_ASN1_UTCTIME;
        +#ifdef CHARSET_EBCDIC_not
        +	ebcdic2ascii(s->data, s->data, s->length);
        +#endif
        +	return(s);
        +	}
        +
        +
        +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
        +	{
        +	struct tm *tm;
        +	struct tm data;
        +	int offset;
        +	int year;
        +
        +#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
        +
        +	if (s->data[12] == 'Z')
        +		offset=0;
        +	else
        +		{
        +		offset = g2(s->data+13)*60+g2(s->data+15);
        +		if (s->data[12] == '-')
        +			offset = -offset;
        +		}
        +
        +	t -= offset*60; /* FIXME: may overflow in extreme cases */
        +
        +	tm = OPENSSL_gmtime(&t, &data);
        +	
        +#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1
        +	year = g2(s->data);
        +	if (year < 50)
        +		year += 100;
        +	return_cmp(year,              tm->tm_year);
        +	return_cmp(g2(s->data+2) - 1, tm->tm_mon);
        +	return_cmp(g2(s->data+4),     tm->tm_mday);
        +	return_cmp(g2(s->data+6),     tm->tm_hour);
        +	return_cmp(g2(s->data+8),     tm->tm_min);
        +	return_cmp(g2(s->data+10),    tm->tm_sec);
        +#undef g2
        +#undef return_cmp
        +
        +	return 0;
        +	}
        +
        +
        +#if 0
        +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
        +	{
        +	struct tm tm;
        +	int offset;
        +
        +	memset(&tm,'\0',sizeof tm);
        +
        +#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
        +	tm.tm_year=g2(s->data);
        +	if(tm.tm_year < 50)
        +		tm.tm_year+=100;
        +	tm.tm_mon=g2(s->data+2)-1;
        +	tm.tm_mday=g2(s->data+4);
        +	tm.tm_hour=g2(s->data+6);
        +	tm.tm_min=g2(s->data+8);
        +	tm.tm_sec=g2(s->data+10);
        +	if(s->data[12] == 'Z')
        +		offset=0;
        +	else
        +		{
        +		offset=g2(s->data+13)*60+g2(s->data+15);
        +		if(s->data[12] == '-')
        +			offset= -offset;
        +		}
        +#undef g2
        +
        +	return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
        +	                               * instead of UTC, and unless we rewrite OpenSSL
        +				       * in Lisp we cannot locally change the timezone
        +				       * without possibly interfering with other parts
        +	                               * of the program. timegm, which uses UTC, is
        +				       * non-standard.
        +	                               * Also time_t is inappropriate for general
        +	                               * UTC times because it may a 32 bit type. */
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_utf8.c b/vendor/openssl/openssl/crypto/asn1/a_utf8.c
        new file mode 100644
        index 000000000..508e11e52
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_utf8.c
        @@ -0,0 +1,211 @@
        +/* crypto/asn1/a_utf8.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +
        +/* UTF8 utilities */
        +
        +/* This parses a UTF8 string one character at a time. It is passed a pointer
        + * to the string and the length of the string. It sets 'value' to the value of
        + * the current character. It returns the number of characters read or a
        + * negative error code:
        + * -1 = string too short
        + * -2 = illegal character
        + * -3 = subsequent characters not of the form 10xxxxxx
        + * -4 = character encoded incorrectly (not minimal length).
        + */
        +
        +int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
        +{
        +	const unsigned char *p;
        +	unsigned long value;
        +	int ret;
        +	if(len <= 0) return 0;
        +	p = str;
        +
        +	/* Check syntax and work out the encoded value (if correct) */
        +	if((*p & 0x80) == 0) {
        +		value = *p++ & 0x7f;
        +		ret = 1;
        +	} else if((*p & 0xe0) == 0xc0) {
        +		if(len < 2) return -1;
        +		if((p[1] & 0xc0) != 0x80) return -3;
        +		value = (*p++ & 0x1f) << 6;
        +		value |= *p++ & 0x3f;
        +		if(value < 0x80) return -4;
        +		ret = 2;
        +	} else if((*p & 0xf0) == 0xe0) {
        +		if(len < 3) return -1;
        +		if( ((p[1] & 0xc0) != 0x80)
        +		   || ((p[2] & 0xc0) != 0x80) ) return -3;
        +		value = (*p++ & 0xf) << 12;
        +		value |= (*p++ & 0x3f) << 6;
        +		value |= *p++ & 0x3f;
        +		if(value < 0x800) return -4;
        +		ret = 3;
        +	} else if((*p & 0xf8) == 0xf0) {
        +		if(len < 4) return -1;
        +		if( ((p[1] & 0xc0) != 0x80)
        +		   || ((p[2] & 0xc0) != 0x80) 
        +		   || ((p[3] & 0xc0) != 0x80) ) return -3;
        +		value = ((unsigned long)(*p++ & 0x7)) << 18;
        +		value |= (*p++ & 0x3f) << 12;
        +		value |= (*p++ & 0x3f) << 6;
        +		value |= *p++ & 0x3f;
        +		if(value < 0x10000) return -4;
        +		ret = 4;
        +	} else if((*p & 0xfc) == 0xf8) {
        +		if(len < 5) return -1;
        +		if( ((p[1] & 0xc0) != 0x80)
        +		   || ((p[2] & 0xc0) != 0x80) 
        +		   || ((p[3] & 0xc0) != 0x80) 
        +		   || ((p[4] & 0xc0) != 0x80) ) return -3;
        +		value = ((unsigned long)(*p++ & 0x3)) << 24;
        +		value |= ((unsigned long)(*p++ & 0x3f)) << 18;
        +		value |= ((unsigned long)(*p++ & 0x3f)) << 12;
        +		value |= (*p++ & 0x3f) << 6;
        +		value |= *p++ & 0x3f;
        +		if(value < 0x200000) return -4;
        +		ret = 5;
        +	} else if((*p & 0xfe) == 0xfc) {
        +		if(len < 6) return -1;
        +		if( ((p[1] & 0xc0) != 0x80)
        +		   || ((p[2] & 0xc0) != 0x80) 
        +		   || ((p[3] & 0xc0) != 0x80) 
        +		   || ((p[4] & 0xc0) != 0x80) 
        +		   || ((p[5] & 0xc0) != 0x80) ) return -3;
        +		value = ((unsigned long)(*p++ & 0x1)) << 30;
        +		value |= ((unsigned long)(*p++ & 0x3f)) << 24;
        +		value |= ((unsigned long)(*p++ & 0x3f)) << 18;
        +		value |= ((unsigned long)(*p++ & 0x3f)) << 12;
        +		value |= (*p++ & 0x3f) << 6;
        +		value |= *p++ & 0x3f;
        +		if(value < 0x4000000) return -4;
        +		ret = 6;
        +	} else return -2;
        +	*val = value;
        +	return ret;
        +}
        +
        +/* This takes a character 'value' and writes the UTF8 encoded value in
        + * 'str' where 'str' is a buffer containing 'len' characters. Returns
        + * the number of characters written or -1 if 'len' is too small. 'str' can
        + * be set to NULL in which case it just returns the number of characters.
        + * It will need at most 6 characters.
        + */
        +
        +int UTF8_putc(unsigned char *str, int len, unsigned long value)
        +{
        +	if(!str) len = 6;	/* Maximum we will need */
        +	else if(len <= 0) return -1;
        +	if(value < 0x80) {
        +		if(str) *str = (unsigned char)value;
        +		return 1;
        +	}
        +	if(value < 0x800) {
        +		if(len < 2) return -1;
        +		if(str) {
        +			*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
        +			*str = (unsigned char)((value & 0x3f) | 0x80);
        +		}
        +		return 2;
        +	}
        +	if(value < 0x10000) {
        +		if(len < 3) return -1;
        +		if(str) {
        +			*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
        +			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
        +			*str = (unsigned char)((value & 0x3f) | 0x80);
        +		}
        +		return 3;
        +	}
        +	if(value < 0x200000) {
        +		if(len < 4) return -1;
        +		if(str) {
        +			*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
        +			*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
        +			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
        +			*str = (unsigned char)((value & 0x3f) | 0x80);
        +		}
        +		return 4;
        +	}
        +	if(value < 0x4000000) {
        +		if(len < 5) return -1;
        +		if(str) {
        +			*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
        +			*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
        +			*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
        +			*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
        +			*str = (unsigned char)((value & 0x3f) | 0x80);
        +		}
        +		return 5;
        +	}
        +	if(len < 6) return -1;
        +	if(str) {
        +		*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
        +		*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
        +		*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
        +		*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
        +		*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
        +		*str = (unsigned char)((value & 0x3f) | 0x80);
        +	}
        +	return 6;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/a_verify.c b/vendor/openssl/openssl/crypto/asn1/a_verify.c
        new file mode 100644
        index 000000000..fc84cd3d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/a_verify.c
        @@ -0,0 +1,234 @@
        +/* crypto/asn1/a_verify.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +
        +#include "cryptlib.h"
        +#include "asn1_locl.h"
        +
        +#ifndef NO_SYS_TYPES_H
        +# include <sys/types.h>
        +#endif
        +
        +#include <openssl/bn.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +
        +#ifndef NO_ASN1_OLD
        +
        +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
        +		char *data, EVP_PKEY *pkey)
        +	{
        +	EVP_MD_CTX ctx;
        +	const EVP_MD *type;
        +	unsigned char *p,*buf_in=NULL;
        +	int ret= -1,i,inl;
        +
        +	EVP_MD_CTX_init(&ctx);
        +	i=OBJ_obj2nid(a->algorithm);
        +	type=EVP_get_digestbyname(OBJ_nid2sn(i));
        +	if (type == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
        +		goto err;
        +		}
        +	
        +	inl=i2d(data,NULL);
        +	buf_in=OPENSSL_malloc((unsigned int)inl);
        +	if (buf_in == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	p=buf_in;
        +
        +	i2d(data,&p);
        +	if (!EVP_VerifyInit_ex(&ctx,type, NULL)
        +		|| !EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl))
        +		{
        +		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
        +		ret=0;
        +		goto err;
        +		}
        +
        +	OPENSSL_cleanse(buf_in,(unsigned int)inl);
        +	OPENSSL_free(buf_in);
        +
        +	if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
        +			(unsigned int)signature->length,pkey) <= 0)
        +		{
        +		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
        +		ret=0;
        +		goto err;
        +		}
        +	/* we don't need to zero the 'ctx' because we just checked
        +	 * public information */
        +	/* memset(&ctx,0,sizeof(ctx)); */
        +	ret=1;
        +err:
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return(ret);
        +	}
        +
        +#endif
        +
        +
        +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
        +		ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
        +	{
        +	EVP_MD_CTX ctx;
        +	unsigned char *buf_in=NULL;
        +	int ret= -1,inl;
        +
        +	int mdnid, pknid;
        +
        +	if (!pkey)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
        +		return -1;
        +		}
        +
        +	EVP_MD_CTX_init(&ctx);
        +
        +	/* Convert signature OID into digest and public key OIDs */
        +	if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
        +		goto err;
        +		}
        +	if (mdnid == NID_undef)
        +		{
        +		if (!pkey->ameth || !pkey->ameth->item_verify)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
        +			goto err;
        +			}
        +		ret = pkey->ameth->item_verify(&ctx, it, asn, a,
        +							signature, pkey);
        +		/* Return value of 2 means carry on, anything else means we
        +		 * exit straight away: either a fatal error of the underlying
        +		 * verification routine handles all verification.
        +		 */
        +		if (ret != 2)
        +			goto err;
        +		ret = -1;
        +		}
        +	else
        +		{
        +		const EVP_MD *type;
        +		type=EVP_get_digestbynid(mdnid);
        +		if (type == NULL)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
        +			goto err;
        +			}
        +
        +		/* Check public key OID matches public key type */
        +		if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
        +			goto err;
        +			}
        +
        +		if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey))
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
        +			ret=0;
        +			goto err;
        +			}
        +
        +		}
        +
        +	inl = ASN1_item_i2d(asn, &buf_in, it);
        +	
        +	if (buf_in == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
        +		ret=0;
        +		goto err;
        +		}
        +
        +	OPENSSL_cleanse(buf_in,(unsigned int)inl);
        +	OPENSSL_free(buf_in);
        +
        +	if (EVP_DigestVerifyFinal(&ctx,signature->data,
        +			(size_t)signature->length) <= 0)
        +		{
        +		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
        +		ret=0;
        +		goto err;
        +		}
        +	/* we don't need to zero the 'ctx' because we just checked
        +	 * public information */
        +	/* memset(&ctx,0,sizeof(ctx)); */
        +	ret=1;
        +err:
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return(ret);
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/ameth_lib.c b/vendor/openssl/openssl/crypto/asn1/ameth_lib.c
        new file mode 100644
        index 000000000..a19e058fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/ameth_lib.c
        @@ -0,0 +1,460 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include "asn1_locl.h"
        +
        +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
        +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
        +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
        +extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
        +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
        +extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
        +
        +/* Keep this sorted in type order !! */
        +static const EVP_PKEY_ASN1_METHOD *standard_methods[] = 
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	&rsa_asn1_meths[0],
        +	&rsa_asn1_meths[1],
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	&dh_asn1_meth,
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	&dsa_asn1_meths[0],
        +	&dsa_asn1_meths[1],
        +	&dsa_asn1_meths[2],
        +	&dsa_asn1_meths[3],
        +	&dsa_asn1_meths[4],
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	&eckey_asn1_meth,
        +#endif
        +	&hmac_asn1_meth,
        +	&cmac_asn1_meth
        +	};
        +
        +typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
        +DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
        +static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
        +
        +
        +
        +#ifdef TEST
        +void main()
        +	{
        +	int i;
        +	for (i = 0;
        +		i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
        +		i++)
        +		fprintf(stderr, "Number %d id=%d (%s)\n", i,
        +			standard_methods[i]->pkey_id,
        +			OBJ_nid2sn(standard_methods[i]->pkey_id));
        +	}
        +#endif
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
        +			   const EVP_PKEY_ASN1_METHOD *, ameth);
        +
        +static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
        +		     const EVP_PKEY_ASN1_METHOD * const *b)
        +	{
        +        return ((*a)->pkey_id - (*b)->pkey_id);
        +	}
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
        +			     const EVP_PKEY_ASN1_METHOD *, ameth);
        +
        +int EVP_PKEY_asn1_get_count(void)
        +	{
        +	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
        +	if (app_methods)
        +		num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
        +	return num;
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
        +	{
        +	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
        +	if (idx < 0)
        +		return NULL; 
        +	if (idx < num)
        +		return standard_methods[idx];
        +	idx -= num;
        +	return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
        +	}
        +
        +static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
        +	{
        +	EVP_PKEY_ASN1_METHOD tmp;
        +	const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
        +	tmp.pkey_id = type;
        +	if (app_methods)
        +		{
        +		int idx;
        +		idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
        +		if (idx >= 0)
        +			return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
        +		}
        +	ret = OBJ_bsearch_ameth(&t, standard_methods,
        +			  sizeof(standard_methods)
        +			  /sizeof(EVP_PKEY_ASN1_METHOD *));
        +	if (!ret || !*ret)
        +		return NULL;
        +	return *ret;
        +	}
        +
        +/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
        + * also search through engines and set *pe to a functional reference
        + * to the engine implementing 'type' or NULL if no engine implements 
        + * it.
        + */
        +
        +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
        +	{
        +	const EVP_PKEY_ASN1_METHOD *t;
        +
        +	for (;;)
        +		{
        +		t = pkey_asn1_find(type);
        +		if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
        +			break;
        +		type = t->pkey_base_id;
        +		}
        +	if (pe)
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		ENGINE *e;
        +		/* type will contain the final unaliased type */
        +		e = ENGINE_get_pkey_asn1_meth_engine(type);
        +		if (e)
        +			{
        +			*pe = e;
        +			return ENGINE_get_pkey_asn1_meth(e, type);
        +			}
        +#endif
        +		*pe = NULL;
        +		}
        +	return t;
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
        +					const char *str, int len)
        +	{
        +	int i;
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	if (len == -1)
        +		len = strlen(str);
        +	if (pe)
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		ENGINE *e;
        +		ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
        +		if (ameth)
        +			{
        +			/* Convert structural into
        +			 * functional reference
        +			 */
        +			if (!ENGINE_init(e))
        +				ameth = NULL;
        +			ENGINE_free(e);
        +			*pe = e;
        +			return ameth;
        +			}
        +#endif
        +		*pe = NULL;
        +		}
        +	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
        +		{
        +		ameth = EVP_PKEY_asn1_get0(i);
        +		if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
        +			continue;
        +		if (((int)strlen(ameth->pem_str) == len) && 
        +			!strncasecmp(ameth->pem_str, str, len))
        +			return ameth;
        +		}
        +	return NULL;
        +	}
        +
        +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
        +	{
        +	if (app_methods == NULL)
        +		{
        +		app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
        +		if (!app_methods)
        +			return 0;
        +		}
        +	if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
        +		return 0;
        +	sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
        +	return 1;
        +	}
        +
        +int EVP_PKEY_asn1_add_alias(int to, int from)
        +	{
        +	EVP_PKEY_ASN1_METHOD *ameth;
        +	ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
        +	if (!ameth)
        +		return 0;
        +	ameth->pkey_base_id = to;
        +	return EVP_PKEY_asn1_add0(ameth);
        +	}
        +
        +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
        +				const char **pinfo, const char **ppem_str,
        +					const EVP_PKEY_ASN1_METHOD *ameth)
        +	{
        +	if (!ameth)
        +		return 0;
        +	if (ppkey_id)
        +		*ppkey_id = ameth->pkey_id;
        +	if (ppkey_base_id)
        +		*ppkey_base_id = ameth->pkey_base_id;
        +	if (ppkey_flags)
        +		*ppkey_flags = ameth->pkey_flags;
        +	if (pinfo)
        +		*pinfo = ameth->info;
        +	if (ppem_str)
        +		*ppem_str = ameth->pem_str;
        +	return 1;
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
        +	{
        +	return pkey->ameth;
        +	}
        +
        +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
        +					const char *pem_str, const char *info)
        +	{
        +	EVP_PKEY_ASN1_METHOD *ameth;
        +	ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
        +	if (!ameth)
        +		return NULL;
        +
        +	memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
        +
        +	ameth->pkey_id = id;
        +	ameth->pkey_base_id = id;
        +	ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
        +
        +	if (info)
        +		{
        +		ameth->info = BUF_strdup(info);
        +		if (!ameth->info)
        +			goto err;
        +		}
        +	else
        +		ameth->info = NULL;
        +
        +	if (pem_str)
        +		{
        +		ameth->pem_str = BUF_strdup(pem_str);
        +		if (!ameth->pem_str)
        +			goto err;
        +		}
        +	else
        +		ameth->pem_str = NULL;
        +
        +	ameth->pub_decode = 0;
        +	ameth->pub_encode = 0;
        +	ameth->pub_cmp = 0;
        +	ameth->pub_print = 0;
        +
        +	ameth->priv_decode = 0;
        +	ameth->priv_encode = 0;
        +	ameth->priv_print = 0;
        +
        +	ameth->old_priv_encode = 0;
        +	ameth->old_priv_decode = 0;
        +
        +	ameth->item_verify = 0;
        +	ameth->item_sign = 0;
        +
        +	ameth->pkey_size = 0;
        +	ameth->pkey_bits = 0;
        +
        +	ameth->param_decode = 0;
        +	ameth->param_encode = 0;
        +	ameth->param_missing = 0;
        +	ameth->param_copy = 0;
        +	ameth->param_cmp = 0;
        +	ameth->param_print = 0;
        +
        +	ameth->pkey_free = 0;
        +	ameth->pkey_ctrl = 0;
        +
        +	return ameth;
        +
        +	err:
        +
        +	EVP_PKEY_asn1_free(ameth);
        +	return NULL;
        +
        +	}
        +
        +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
        +			const EVP_PKEY_ASN1_METHOD *src)
        +	{
        +
        +	dst->pub_decode = src->pub_decode;
        +	dst->pub_encode = src->pub_encode;
        +	dst->pub_cmp = src->pub_cmp;
        +	dst->pub_print = src->pub_print;
        +
        +	dst->priv_decode = src->priv_decode;
        +	dst->priv_encode = src->priv_encode;
        +	dst->priv_print = src->priv_print;
        +
        +	dst->old_priv_encode = src->old_priv_encode;
        +	dst->old_priv_decode = src->old_priv_decode;
        +
        +	dst->pkey_size = src->pkey_size;
        +	dst->pkey_bits = src->pkey_bits;
        +
        +	dst->param_decode = src->param_decode;
        +	dst->param_encode = src->param_encode;
        +	dst->param_missing = src->param_missing;
        +	dst->param_copy = src->param_copy;
        +	dst->param_cmp = src->param_cmp;
        +	dst->param_print = src->param_print;
        +
        +	dst->pkey_free = src->pkey_free;
        +	dst->pkey_ctrl = src->pkey_ctrl;
        +
        +	dst->item_sign = src->item_sign;
        +	dst->item_verify = src->item_verify;
        +
        +	}
        +
        +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
        +	{
        +	if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
        +		{
        +		if (ameth->pem_str)
        +			OPENSSL_free(ameth->pem_str);
        +		if (ameth->info)
        +			OPENSSL_free(ameth->info);
        +		OPENSSL_free(ameth);
        +		}
        +	}
        +
        +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
        +		int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
        +		int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
        +		int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx),
        +		int (*pkey_size)(const EVP_PKEY *pk),
        +		int (*pkey_bits)(const EVP_PKEY *pk))
        +	{
        +	ameth->pub_decode = pub_decode;
        +	ameth->pub_encode = pub_encode;
        +	ameth->pub_cmp = pub_cmp;
        +	ameth->pub_print = pub_print;
        +	ameth->pkey_size = pkey_size;
        +	ameth->pkey_bits = pkey_bits;
        +	}
        +
        +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
        +		int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
        +		int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx))
        +	{
        +	ameth->priv_decode = priv_decode;
        +	ameth->priv_encode = priv_encode;
        +	ameth->priv_print = priv_print;
        +	}
        +
        +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*param_decode)(EVP_PKEY *pkey,
        +				const unsigned char **pder, int derlen),
        +		int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
        +		int (*param_missing)(const EVP_PKEY *pk),
        +		int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
        +		int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
        +		int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx))
        +	{
        +	ameth->param_decode = param_decode;
        +	ameth->param_encode = param_encode;
        +	ameth->param_missing = param_missing;
        +	ameth->param_copy = param_copy;
        +	ameth->param_cmp = param_cmp;
        +	ameth->param_print = param_print;
        +	}
        +
        +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
        +		void (*pkey_free)(EVP_PKEY *pkey))
        +	{
        +	ameth->pkey_free = pkey_free;
        +	}
        +
        +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
        +							long arg1, void *arg2))
        +	{
        +	ameth->pkey_ctrl = pkey_ctrl;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1.h b/vendor/openssl/openssl/crypto/asn1/asn1.h
        new file mode 100644
        index 000000000..220a0c8c6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1.h
        @@ -0,0 +1,1404 @@
        +/* crypto/asn1/asn1.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_ASN1_H
        +#define HEADER_ASN1_H
        +
        +#include <time.h>
        +#include <openssl/e_os2.h>
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/stack.h>
        +#include <openssl/safestack.h>
        +
        +#include <openssl/symhacks.h>
        +
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#endif
        +
        +#ifdef OPENSSL_BUILD_SHLIBCRYPTO
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#define V_ASN1_UNIVERSAL		0x00
        +#define	V_ASN1_APPLICATION		0x40
        +#define V_ASN1_CONTEXT_SPECIFIC		0x80
        +#define V_ASN1_PRIVATE			0xc0
        +
        +#define V_ASN1_CONSTRUCTED		0x20
        +#define V_ASN1_PRIMITIVE_TAG		0x1f
        +#define V_ASN1_PRIMATIVE_TAG		0x1f
        +
        +#define V_ASN1_APP_CHOOSE		-2	/* let the recipient choose */
        +#define V_ASN1_OTHER			-3	/* used in ASN1_TYPE */
        +#define V_ASN1_ANY			-4	/* used in ASN1 template code */
        +
        +#define V_ASN1_NEG			0x100	/* negative flag */
        +
        +#define V_ASN1_UNDEF			-1
        +#define V_ASN1_EOC			0
        +#define V_ASN1_BOOLEAN			1	/**/
        +#define V_ASN1_INTEGER			2
        +#define V_ASN1_NEG_INTEGER		(2 | V_ASN1_NEG)
        +#define V_ASN1_BIT_STRING		3
        +#define V_ASN1_OCTET_STRING		4
        +#define V_ASN1_NULL			5
        +#define V_ASN1_OBJECT			6
        +#define V_ASN1_OBJECT_DESCRIPTOR	7
        +#define V_ASN1_EXTERNAL			8
        +#define V_ASN1_REAL			9
        +#define V_ASN1_ENUMERATED		10
        +#define V_ASN1_NEG_ENUMERATED		(10 | V_ASN1_NEG)
        +#define V_ASN1_UTF8STRING		12
        +#define V_ASN1_SEQUENCE			16
        +#define V_ASN1_SET			17
        +#define V_ASN1_NUMERICSTRING		18	/**/
        +#define V_ASN1_PRINTABLESTRING		19
        +#define V_ASN1_T61STRING		20
        +#define V_ASN1_TELETEXSTRING		20	/* alias */
        +#define V_ASN1_VIDEOTEXSTRING		21	/**/
        +#define V_ASN1_IA5STRING		22
        +#define V_ASN1_UTCTIME			23
        +#define V_ASN1_GENERALIZEDTIME		24	/**/
        +#define V_ASN1_GRAPHICSTRING		25	/**/
        +#define V_ASN1_ISO64STRING		26	/**/
        +#define V_ASN1_VISIBLESTRING		26	/* alias */
        +#define V_ASN1_GENERALSTRING		27	/**/
        +#define V_ASN1_UNIVERSALSTRING		28	/**/
        +#define V_ASN1_BMPSTRING		30
        +
        +/* For use with d2i_ASN1_type_bytes() */
        +#define B_ASN1_NUMERICSTRING	0x0001
        +#define B_ASN1_PRINTABLESTRING	0x0002
        +#define B_ASN1_T61STRING	0x0004
        +#define B_ASN1_TELETEXSTRING	0x0004
        +#define B_ASN1_VIDEOTEXSTRING	0x0008
        +#define B_ASN1_IA5STRING	0x0010
        +#define B_ASN1_GRAPHICSTRING	0x0020
        +#define B_ASN1_ISO64STRING	0x0040
        +#define B_ASN1_VISIBLESTRING	0x0040
        +#define B_ASN1_GENERALSTRING	0x0080
        +#define B_ASN1_UNIVERSALSTRING	0x0100
        +#define B_ASN1_OCTET_STRING	0x0200
        +#define B_ASN1_BIT_STRING	0x0400
        +#define B_ASN1_BMPSTRING	0x0800
        +#define B_ASN1_UNKNOWN		0x1000
        +#define B_ASN1_UTF8STRING	0x2000
        +#define B_ASN1_UTCTIME		0x4000
        +#define B_ASN1_GENERALIZEDTIME	0x8000
        +#define B_ASN1_SEQUENCE		0x10000
        +
        +/* For use with ASN1_mbstring_copy() */
        +#define MBSTRING_FLAG		0x1000
        +#define MBSTRING_UTF8		(MBSTRING_FLAG)
        +#define MBSTRING_ASC		(MBSTRING_FLAG|1)
        +#define MBSTRING_BMP		(MBSTRING_FLAG|2)
        +#define MBSTRING_UNIV		(MBSTRING_FLAG|4)
        +
        +#define SMIME_OLDMIME		0x400
        +#define SMIME_CRLFEOL		0x800
        +#define SMIME_STREAM		0x1000
        +
        +struct X509_algor_st;
        +DECLARE_STACK_OF(X509_ALGOR)
        +
        +#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */
        +#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */
        +
        +/* We MUST make sure that, except for constness, asn1_ctx_st and
        +   asn1_const_ctx are exactly the same.  Fortunately, as soon as
        +   the old ASN1 parsing macros are gone, we can throw this away
        +   as well... */
        +typedef struct asn1_ctx_st
        +	{
        +	unsigned char *p;/* work char pointer */
        +	int eos;	/* end of sequence read for indefinite encoding */
        +	int error;	/* error code to use when returning an error */
        +	int inf;	/* constructed if 0x20, indefinite is 0x21 */
        +	int tag;	/* tag from last 'get object' */
        +	int xclass;	/* class from last 'get object' */
        +	long slen;	/* length of last 'get object' */
        +	unsigned char *max; /* largest value of p allowed */
        +	unsigned char *q;/* temporary variable */
        +	unsigned char **pp;/* variable */
        +	int line;	/* used in error processing */
        +	} ASN1_CTX;
        +
        +typedef struct asn1_const_ctx_st
        +	{
        +	const unsigned char *p;/* work char pointer */
        +	int eos;	/* end of sequence read for indefinite encoding */
        +	int error;	/* error code to use when returning an error */
        +	int inf;	/* constructed if 0x20, indefinite is 0x21 */
        +	int tag;	/* tag from last 'get object' */
        +	int xclass;	/* class from last 'get object' */
        +	long slen;	/* length of last 'get object' */
        +	const unsigned char *max; /* largest value of p allowed */
        +	const unsigned char *q;/* temporary variable */
        +	const unsigned char **pp;/* variable */
        +	int line;	/* used in error processing */
        +	} ASN1_const_CTX;
        +
        +/* These are used internally in the ASN1_OBJECT to keep track of
        + * whether the names and data need to be free()ed */
        +#define ASN1_OBJECT_FLAG_DYNAMIC	 0x01	/* internal use */
        +#define ASN1_OBJECT_FLAG_CRITICAL	 0x02	/* critical x509v3 object id */
        +#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04	/* internal use */
        +#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 	 0x08	/* internal use */
        +typedef struct asn1_object_st
        +	{
        +	const char *sn,*ln;
        +	int nid;
        +	int length;
        +	const unsigned char *data;	/* data remains const after init */
        +	int flags;	/* Should we free this one */
        +	} ASN1_OBJECT;
        +
        +#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
        +/* This indicates that the ASN1_STRING is not a real value but just a place
        + * holder for the location where indefinite length constructed data should
        + * be inserted in the memory buffer 
        + */
        +#define ASN1_STRING_FLAG_NDEF 0x010 
        +
        +/* This flag is used by the CMS code to indicate that a string is not
        + * complete and is a place holder for content when it had all been 
        + * accessed. The flag will be reset when content has been written to it.
        + */
        +
        +#define ASN1_STRING_FLAG_CONT 0x020 
        +/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
        + * type.
        + */
        +#define ASN1_STRING_FLAG_MSTRING 0x040 
        +/* This is the base type that holds just about everything :-) */
        +struct asn1_string_st
        +	{
        +	int length;
        +	int type;
        +	unsigned char *data;
        +	/* The value of the following field depends on the type being
        +	 * held.  It is mostly being used for BIT_STRING so if the
        +	 * input data has a non-zero 'unused bits' value, it will be
        +	 * handled correctly */
        +	long flags;
        +	};
        +
        +/* ASN1_ENCODING structure: this is used to save the received
        + * encoding of an ASN1 type. This is useful to get round
        + * problems with invalid encodings which can break signatures.
        + */
        +
        +typedef struct ASN1_ENCODING_st
        +	{
        +	unsigned char *enc;	/* DER encoding */
        +	long len;		/* Length of encoding */
        +	int modified;		 /* set to 1 if 'enc' is invalid */
        +	} ASN1_ENCODING;
        +
        +/* Used with ASN1 LONG type: if a long is set to this it is omitted */
        +#define ASN1_LONG_UNDEF	0x7fffffffL
        +
        +#define STABLE_FLAGS_MALLOC	0x01
        +#define STABLE_NO_MASK		0x02
        +#define DIRSTRING_TYPE	\
        + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
        +#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
        +
        +typedef struct asn1_string_table_st {
        +	int nid;
        +	long minsize;
        +	long maxsize;
        +	unsigned long mask;
        +	unsigned long flags;
        +} ASN1_STRING_TABLE;
        +
        +DECLARE_STACK_OF(ASN1_STRING_TABLE)
        +
        +/* size limits: this stuff is taken straight from RFC2459 */
        +
        +#define ub_name				32768
        +#define ub_common_name			64
        +#define ub_locality_name		128
        +#define ub_state_name			128
        +#define ub_organization_name		64
        +#define ub_organization_unit_name	64
        +#define ub_title			64
        +#define ub_email_address		128
        +
        +/* Declarations for template structures: for full definitions
        + * see asn1t.h
        + */
        +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
        +typedef struct ASN1_TLC_st ASN1_TLC;
        +/* This is just an opaque pointer */
        +typedef struct ASN1_VALUE_st ASN1_VALUE;
        +
        +/* Declare ASN1 functions: the implement macro in in asn1t.h */
        +
        +#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
        +
        +#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
        +	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
        +
        +#define DECLARE_ASN1_FUNCTIONS_name(type, name) \
        +	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
        +	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
        +
        +#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
        +	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
        +	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
        +
        +#define	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
        +	type *d2i_##name(type **a, const unsigned char **in, long len); \
        +	int i2d_##name(type *a, unsigned char **out); \
        +	DECLARE_ASN1_ITEM(itname)
        +
        +#define	DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
        +	type *d2i_##name(type **a, const unsigned char **in, long len); \
        +	int i2d_##name(const type *a, unsigned char **out); \
        +	DECLARE_ASN1_ITEM(name)
        +
        +#define	DECLARE_ASN1_NDEF_FUNCTION(name) \
        +	int i2d_##name##_NDEF(name *a, unsigned char **out);
        +
        +#define DECLARE_ASN1_FUNCTIONS_const(name) \
        +	DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
        +	DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
        +
        +#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
        +	type *name##_new(void); \
        +	void name##_free(type *a);
        +
        +#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
        +	DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
        +
        +#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
        +	int fname##_print_ctx(BIO *out, stname *x, int indent, \
        +					 const ASN1_PCTX *pctx);
        +
        +#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
        +#define I2D_OF(type) int (*)(type *,unsigned char **)
        +#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
        +
        +#define CHECKED_D2I_OF(type, d2i) \
        +    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
        +#define CHECKED_I2D_OF(type, i2d) \
        +    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
        +#define CHECKED_NEW_OF(type, xnew) \
        +    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
        +#define CHECKED_PTR_OF(type, p) \
        +    ((void*) (1 ? p : (type*)0))
        +#define CHECKED_PPTR_OF(type, p) \
        +    ((void**) (1 ? p : (type**)0))
        +
        +#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
        +#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
        +#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
        +
        +TYPEDEF_D2I2D_OF(void);
        +
        +/* The following macros and typedefs allow an ASN1_ITEM
        + * to be embedded in a structure and referenced. Since
        + * the ASN1_ITEM pointers need to be globally accessible
        + * (possibly from shared libraries) they may exist in
        + * different forms. On platforms that support it the
        + * ASN1_ITEM structure itself will be globally exported.
        + * Other platforms will export a function that returns
        + * an ASN1_ITEM pointer.
        + *
        + * To handle both cases transparently the macros below
        + * should be used instead of hard coding an ASN1_ITEM
        + * pointer in a structure.
        + *
        + * The structure will look like this:
        + *
        + * typedef struct SOMETHING_st {
        + *      ...
        + *      ASN1_ITEM_EXP *iptr;
        + *      ...
        + * } SOMETHING; 
        + *
        + * It would be initialised as e.g.:
        + *
        + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
        + *
        + * and the actual pointer extracted with:
        + *
        + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
        + *
        + * Finally an ASN1_ITEM pointer can be extracted from an
        + * appropriate reference with: ASN1_ITEM_rptr(X509). This
        + * would be used when a function takes an ASN1_ITEM * argument.
        + *
        + */
        +
        +#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +
        +/* ASN1_ITEM pointer exported type */
        +typedef const ASN1_ITEM ASN1_ITEM_EXP;
        +
        +/* Macro to obtain ASN1_ITEM pointer from exported type */
        +#define ASN1_ITEM_ptr(iptr) (iptr)
        +
        +/* Macro to include ASN1_ITEM pointer from base type */
        +#define ASN1_ITEM_ref(iptr) (&(iptr##_it))
        +
        +#define ASN1_ITEM_rptr(ref) (&(ref##_it))
        +
        +#define DECLARE_ASN1_ITEM(name) \
        +	OPENSSL_EXTERN const ASN1_ITEM name##_it;
        +
        +#else
        +
        +/* Platforms that can't easily handle shared global variables are declared
        + * as functions returning ASN1_ITEM pointers.
        + */
        +
        +/* ASN1_ITEM pointer exported type */
        +typedef const ASN1_ITEM * ASN1_ITEM_EXP(void);
        +
        +/* Macro to obtain ASN1_ITEM pointer from exported type */
        +#define ASN1_ITEM_ptr(iptr) (iptr())
        +
        +/* Macro to include ASN1_ITEM pointer from base type */
        +#define ASN1_ITEM_ref(iptr) (iptr##_it)
        +
        +#define ASN1_ITEM_rptr(ref) (ref##_it())
        +
        +#define DECLARE_ASN1_ITEM(name) \
        +	const ASN1_ITEM * name##_it(void);
        +
        +#endif
        +
        +/* Parameters used by ASN1_STRING_print_ex() */
        +
        +/* These determine which characters to escape:
        + * RFC2253 special characters, control characters and
        + * MSB set characters
        + */
        +
        +#define ASN1_STRFLGS_ESC_2253		1
        +#define ASN1_STRFLGS_ESC_CTRL		2
        +#define ASN1_STRFLGS_ESC_MSB		4
        +
        +
        +/* This flag determines how we do escaping: normally
        + * RC2253 backslash only, set this to use backslash and
        + * quote.
        + */
        +
        +#define ASN1_STRFLGS_ESC_QUOTE		8
        +
        +
        +/* These three flags are internal use only. */
        +
        +/* Character is a valid PrintableString character */
        +#define CHARTYPE_PRINTABLESTRING	0x10
        +/* Character needs escaping if it is the first character */
        +#define CHARTYPE_FIRST_ESC_2253		0x20
        +/* Character needs escaping if it is the last character */
        +#define CHARTYPE_LAST_ESC_2253		0x40
        +
        +/* NB the internal flags are safely reused below by flags
        + * handled at the top level.
        + */
        +
        +/* If this is set we convert all character strings
        + * to UTF8 first 
        + */
        +
        +#define ASN1_STRFLGS_UTF8_CONVERT	0x10
        +
        +/* If this is set we don't attempt to interpret content:
        + * just assume all strings are 1 byte per character. This
        + * will produce some pretty odd looking output!
        + */
        +
        +#define ASN1_STRFLGS_IGNORE_TYPE	0x20
        +
        +/* If this is set we include the string type in the output */
        +#define ASN1_STRFLGS_SHOW_TYPE		0x40
        +
        +/* This determines which strings to display and which to
        + * 'dump' (hex dump of content octets or DER encoding). We can
        + * only dump non character strings or everything. If we
        + * don't dump 'unknown' they are interpreted as character
        + * strings with 1 octet per character and are subject to
        + * the usual escaping options.
        + */
        +
        +#define ASN1_STRFLGS_DUMP_ALL		0x80
        +#define ASN1_STRFLGS_DUMP_UNKNOWN	0x100
        +
        +/* These determine what 'dumping' does, we can dump the
        + * content octets or the DER encoding: both use the
        + * RFC2253 #XXXXX notation.
        + */
        +
        +#define ASN1_STRFLGS_DUMP_DER		0x200
        +
        +/* All the string flags consistent with RFC2253,
        + * escaping control characters isn't essential in
        + * RFC2253 but it is advisable anyway.
        + */
        +
        +#define ASN1_STRFLGS_RFC2253	(ASN1_STRFLGS_ESC_2253 | \
        +				ASN1_STRFLGS_ESC_CTRL | \
        +				ASN1_STRFLGS_ESC_MSB | \
        +				ASN1_STRFLGS_UTF8_CONVERT | \
        +				ASN1_STRFLGS_DUMP_UNKNOWN | \
        +				ASN1_STRFLGS_DUMP_DER)
        +
        +DECLARE_STACK_OF(ASN1_INTEGER)
        +DECLARE_ASN1_SET_OF(ASN1_INTEGER)
        +
        +DECLARE_STACK_OF(ASN1_GENERALSTRING)
        +
        +typedef struct asn1_type_st
        +	{
        +	int type;
        +	union	{
        +		char *ptr;
        +		ASN1_BOOLEAN		boolean;
        +		ASN1_STRING *		asn1_string;
        +		ASN1_OBJECT *		object;
        +		ASN1_INTEGER *		integer;
        +		ASN1_ENUMERATED *	enumerated;
        +		ASN1_BIT_STRING *	bit_string;
        +		ASN1_OCTET_STRING *	octet_string;
        +		ASN1_PRINTABLESTRING *	printablestring;
        +		ASN1_T61STRING *	t61string;
        +		ASN1_IA5STRING *	ia5string;
        +		ASN1_GENERALSTRING *	generalstring;
        +		ASN1_BMPSTRING *	bmpstring;
        +		ASN1_UNIVERSALSTRING *	universalstring;
        +		ASN1_UTCTIME *		utctime;
        +		ASN1_GENERALIZEDTIME *	generalizedtime;
        +		ASN1_VISIBLESTRING *	visiblestring;
        +		ASN1_UTF8STRING *	utf8string;
        +		/* set and sequence are left complete and still
        +		 * contain the set or sequence bytes */
        +		ASN1_STRING *		set;
        +		ASN1_STRING *		sequence;
        +		ASN1_VALUE *		asn1_value;
        +		} value;
        +	} ASN1_TYPE;
        +
        +DECLARE_STACK_OF(ASN1_TYPE)
        +DECLARE_ASN1_SET_OF(ASN1_TYPE)
        +
        +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
        +
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
        +
        +typedef struct NETSCAPE_X509_st
        +	{
        +	ASN1_OCTET_STRING *header;
        +	X509 *cert;
        +	} NETSCAPE_X509;
        +
        +/* This is used to contain a list of bit names */
        +typedef struct BIT_STRING_BITNAME_st {
        +	int bitnum;
        +	const char *lname;
        +	const char *sname;
        +} BIT_STRING_BITNAME;
        +
        +
        +#define M_ASN1_STRING_length(x)	((x)->length)
        +#define M_ASN1_STRING_length_set(x, n)	((x)->length = (n))
        +#define M_ASN1_STRING_type(x)	((x)->type)
        +#define M_ASN1_STRING_data(x)	((x)->data)
        +
        +/* Macros for string operations */
        +#define M_ASN1_BIT_STRING_new()	(ASN1_BIT_STRING *)\
        +		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
        +#define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
        +		ASN1_STRING_dup((const ASN1_STRING *)a)
        +#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
        +		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
        +#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
        +
        +#define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
        +		ASN1_STRING_type_new(V_ASN1_INTEGER)
        +#define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
        +		ASN1_STRING_dup((const ASN1_STRING *)a)
        +#define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
        +		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
        +
        +#define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
        +		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
        +#define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
        +		ASN1_STRING_dup((const ASN1_STRING *)a)
        +#define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
        +		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
        +
        +#define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
        +		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
        +#define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
        +		ASN1_STRING_dup((const ASN1_STRING *)a)
        +#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
        +		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
        +#define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
        +#define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
        +#define M_i2d_ASN1_OCTET_STRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
        +		V_ASN1_UNIVERSAL)
        +
        +#define B_ASN1_TIME \
        +			B_ASN1_UTCTIME | \
        +			B_ASN1_GENERALIZEDTIME
        +
        +#define B_ASN1_PRINTABLE \
        +			B_ASN1_NUMERICSTRING| \
        +			B_ASN1_PRINTABLESTRING| \
        +			B_ASN1_T61STRING| \
        +			B_ASN1_IA5STRING| \
        +			B_ASN1_BIT_STRING| \
        +			B_ASN1_UNIVERSALSTRING|\
        +			B_ASN1_BMPSTRING|\
        +			B_ASN1_UTF8STRING|\
        +			B_ASN1_SEQUENCE|\
        +			B_ASN1_UNKNOWN
        +
        +#define B_ASN1_DIRECTORYSTRING \
        +			B_ASN1_PRINTABLESTRING| \
        +			B_ASN1_TELETEXSTRING|\
        +			B_ASN1_BMPSTRING|\
        +			B_ASN1_UNIVERSALSTRING|\
        +			B_ASN1_UTF8STRING
        +
        +#define B_ASN1_DISPLAYTEXT \
        +			B_ASN1_IA5STRING| \
        +			B_ASN1_VISIBLESTRING| \
        +			B_ASN1_BMPSTRING|\
        +			B_ASN1_UTF8STRING
        +
        +#define M_ASN1_PRINTABLE_new()	ASN1_STRING_type_new(V_ASN1_T61STRING)
        +#define M_ASN1_PRINTABLE_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
        +		pp,a->type,V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
        +		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
        +			B_ASN1_PRINTABLE)
        +
        +#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
        +#define M_DIRECTORYSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
        +						pp,a->type,V_ASN1_UNIVERSAL)
        +#define M_d2i_DIRECTORYSTRING(a,pp,l) \
        +		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
        +			B_ASN1_DIRECTORYSTRING)
        +
        +#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
        +#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
        +						pp,a->type,V_ASN1_UNIVERSAL)
        +#define M_d2i_DISPLAYTEXT(a,pp,l) \
        +		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
        +			B_ASN1_DISPLAYTEXT)
        +
        +#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
        +		ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
        +#define M_ASN1_PRINTABLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
        +		V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
        +		(ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
        +
        +#define M_ASN1_T61STRING_new()	(ASN1_T61STRING *)\
        +		ASN1_STRING_type_new(V_ASN1_T61STRING)
        +#define M_ASN1_T61STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_T61STRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
        +		V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_T61STRING(a,pp,l) \
        +		(ASN1_T61STRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
        +
        +#define M_ASN1_IA5STRING_new()	(ASN1_IA5STRING *)\
        +		ASN1_STRING_type_new(V_ASN1_IA5STRING)
        +#define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_IA5STRING_dup(a)	\
        +		(ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
        +#define M_i2d_ASN1_IA5STRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
        +			V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_IA5STRING(a,pp,l) \
        +		(ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
        +			B_ASN1_IA5STRING)
        +
        +#define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
        +		ASN1_STRING_type_new(V_ASN1_UTCTIME)
        +#define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
        +		ASN1_STRING_dup((const ASN1_STRING *)a)
        +
        +#define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
        +		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
        +#define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
        +	(const ASN1_STRING *)a)
        +
        +#define M_ASN1_TIME_new()	(ASN1_TIME *)\
        +		ASN1_STRING_type_new(V_ASN1_UTCTIME)
        +#define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
        +	ASN1_STRING_dup((const ASN1_STRING *)a)
        +
        +#define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
        +		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
        +#define M_ASN1_GENERALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_GENERALSTRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
        +			V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
        +		(ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
        +
        +#define M_ASN1_UNIVERSALSTRING_new()	(ASN1_UNIVERSALSTRING *)\
        +		ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
        +#define M_ASN1_UNIVERSALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
        +			V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
        +		(ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
        +
        +#define M_ASN1_BMPSTRING_new()	(ASN1_BMPSTRING *)\
        +		ASN1_STRING_type_new(V_ASN1_BMPSTRING)
        +#define M_ASN1_BMPSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_BMPSTRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
        +			V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
        +		(ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
        +
        +#define M_ASN1_VISIBLESTRING_new()	(ASN1_VISIBLESTRING *)\
        +		ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
        +#define M_ASN1_VISIBLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
        +			V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
        +		(ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
        +
        +#define M_ASN1_UTF8STRING_new()	(ASN1_UTF8STRING *)\
        +		ASN1_STRING_type_new(V_ASN1_UTF8STRING)
        +#define M_ASN1_UTF8STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
        +#define M_i2d_ASN1_UTF8STRING(a,pp) \
        +		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
        +			V_ASN1_UNIVERSAL)
        +#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
        +		(ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
        +		((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
        +
        +  /* for the is_set parameter to i2d_ASN1_SET */
        +#define IS_SEQUENCE	0
        +#define IS_SET		1
        +
        +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
        +
        +int ASN1_TYPE_get(ASN1_TYPE *a);
        +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
        +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
        +int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
        +
        +ASN1_OBJECT *	ASN1_OBJECT_new(void );
        +void		ASN1_OBJECT_free(ASN1_OBJECT *a);
        +int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
        +ASN1_OBJECT *	c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
        +			long length);
        +ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
        +			long length);
        +
        +DECLARE_ASN1_ITEM(ASN1_OBJECT)
        +
        +DECLARE_STACK_OF(ASN1_OBJECT)
        +DECLARE_ASN1_SET_OF(ASN1_OBJECT)
        +
        +ASN1_STRING *	ASN1_STRING_new(void);
        +void		ASN1_STRING_free(ASN1_STRING *a);
        +int		ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
        +ASN1_STRING *	ASN1_STRING_dup(const ASN1_STRING *a);
        +ASN1_STRING *	ASN1_STRING_type_new(int type );
        +int 		ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
        +  /* Since this is used to store all sorts of things, via macros, for now, make
        +     its data void * */
        +int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
        +void		ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
        +int ASN1_STRING_length(const ASN1_STRING *x);
        +void ASN1_STRING_length_set(ASN1_STRING *x, int n);
        +int ASN1_STRING_type(ASN1_STRING *x);
        +unsigned char * ASN1_STRING_data(ASN1_STRING *x);
        +
        +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
        +int		i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
        +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
        +			long length);
        +int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
        +			int length );
        +int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
        +int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
        +int            ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
        +                                     unsigned char *flags, int flags_len);
        +
        +#ifndef OPENSSL_NO_BIO
        +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
        +				BIT_STRING_BITNAME *tbl, int indent);
        +#endif
        +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
        +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
        +				BIT_STRING_BITNAME *tbl);
        +
        +int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
        +int 		d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
        +
        +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
        +int		i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
        +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
        +			long length);
        +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
        +			long length);
        +ASN1_INTEGER *	ASN1_INTEGER_dup(const ASN1_INTEGER *x);
        +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
        +
        +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
        +
        +int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
        +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
        +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
        +				int offset_day, long offset_sec);
        +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
        +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
        +#if 0
        +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
        +#endif
        +
        +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
        +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
        +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
        +	     time_t t, int offset_day, long offset_sec);
        +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
        +
        +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
        +ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
        +int 	ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
        +int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
        +
        +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
        +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
        +
        +int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
        +int UTF8_putc(unsigned char *str, int len, unsigned long value);
        +
        +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
        +
        +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
        +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
        +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
        +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
        +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
        +DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
        +
        +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
        +
        +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
        +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
        +				int offset_day, long offset_sec);
        +int ASN1_TIME_check(ASN1_TIME *t);
        +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
        +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
        +
        +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
        +		 i2d_of_void *i2d, int ex_tag, int ex_class,
        +		 int is_set);
        +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
        +			      const unsigned char **pp,
        +			      long length, d2i_of_void *d2i,
        +			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
        +			      int ex_class);
        +
        +#ifndef OPENSSL_NO_BIO
        +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
        +int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
        +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
        +int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
        +int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
        +int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
        +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
        +#endif
        +int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
        +
        +int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
        +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
        +	const char *sn, const char *ln);
        +
        +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
        +long ASN1_INTEGER_get(const ASN1_INTEGER *a);
        +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
        +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
        +
        +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
        +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
        +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
        +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
        +
        +/* General */
        +/* given a string, return the correct type, max is the maximum length */
        +int ASN1_PRINTABLE_type(const unsigned char *s, int max);
        +
        +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
        +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
        +	long length, int Ptag, int Pclass);
        +unsigned long ASN1_tag2bit(int tag);
        +/* type is one or more of the B_ASN1_ values. */
        +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
        +		long length,int type);
        +
        +/* PARSING */
        +int asn1_Finish(ASN1_CTX *c);
        +int asn1_const_Finish(ASN1_const_CTX *c);
        +
        +/* SPECIALS */
        +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
        +	int *pclass, long omax);
        +int ASN1_check_infinite_end(unsigned char **p,long len);
        +int ASN1_const_check_infinite_end(const unsigned char **p,long len);
        +void ASN1_put_object(unsigned char **pp, int constructed, int length,
        +	int tag, int xclass);
        +int ASN1_put_eoc(unsigned char **pp);
        +int ASN1_object_size(int constructed, int length, int tag);
        +
        +/* Used to implement other functions */
        +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
        +
        +#define ASN1_dup_of(type,i2d,d2i,x) \
        +    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
        +		     CHECKED_D2I_OF(type, d2i), \
        +		     CHECKED_PTR_OF(type, x)))
        +
        +#define ASN1_dup_of_const(type,i2d,d2i,x) \
        +    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
        +		     CHECKED_D2I_OF(type, d2i), \
        +		     CHECKED_PTR_OF(const type, x)))
        +
        +void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
        +
        +/* ASN1 alloc/free macros for when a type is only used internally */
        +
        +#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
        +#define M_ASN1_free_of(x, type) \
        +		ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
        +
        +#ifndef OPENSSL_NO_FP_API
        +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
        +
        +#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
        +    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
        +			CHECKED_D2I_OF(type, d2i), \
        +			in, \
        +			CHECKED_PPTR_OF(type, x)))
        +
        +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
        +int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
        +
        +#define ASN1_i2d_fp_of(type,i2d,out,x) \
        +    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
        +		 out, \
        +		 CHECKED_PTR_OF(type, x)))
        +
        +#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
        +    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
        +		 out, \
        +		 CHECKED_PTR_OF(const type, x)))
        +
        +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
        +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
        +#endif
        +
        +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
        +
        +#ifndef OPENSSL_NO_BIO
        +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
        +
        +#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
        +    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
        +			  CHECKED_D2I_OF(type, d2i), \
        +			  in, \
        +			  CHECKED_PPTR_OF(type, x)))
        +
        +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
        +int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
        +
        +#define ASN1_i2d_bio_of(type,i2d,out,x) \
        +    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
        +		  out, \
        +		  CHECKED_PTR_OF(type, x)))
        +
        +#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
        +    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
        +		  out, \
        +		  CHECKED_PTR_OF(const type, x)))
        +
        +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
        +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
        +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
        +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
        +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
        +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
        +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
        +				unsigned char *buf, int off);
        +int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
        +int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
        +#endif
        +const char *ASN1_tag2str(int tag);
        +
        +/* Used to load and write netscape format cert */
        +
        +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
        +
        +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
        +
        +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
        +	unsigned char *data, int len);
        +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
        +	unsigned char *data, int max_len);
        +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
        +	unsigned char *data, int len);
        +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
        +	unsigned char *data, int max_len);
        +
        +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
        +				 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
        +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
        +			     unsigned char **buf, int *len );
        +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
        +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
        +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
        +			      ASN1_OCTET_STRING **oct);
        +
        +#define ASN1_pack_string_of(type,obj,i2d,oct) \
        +    (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
        +		      CHECKED_I2D_OF(type, i2d), \
        +		      oct))
        +
        +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
        +
        +void ASN1_STRING_set_default_mask(unsigned long mask);
        +int ASN1_STRING_set_default_mask_asc(const char *p);
        +unsigned long ASN1_STRING_get_default_mask(void);
        +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
        +					int inform, unsigned long mask);
        +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
        +					int inform, unsigned long mask, 
        +					long minsize, long maxsize);
        +
        +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
        +		const unsigned char *in, int inlen, int inform, int nid);
        +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
        +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
        +void ASN1_STRING_TABLE_cleanup(void);
        +
        +/* ASN1 template functions */
        +
        +/* Old API compatible functions */
        +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
        +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
        +ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
        +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
        +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
        +
        +void ASN1_add_oid_module(void);
        +
        +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
        +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
        +
        +/* ASN1 Print flags */
        +
        +/* Indicate missing OPTIONAL fields */
        +#define ASN1_PCTX_FLAGS_SHOW_ABSENT		0x001	
        +/* Mark start and end of SEQUENCE */
        +#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE		0x002
        +/* Mark start and end of SEQUENCE/SET OF */
        +#define ASN1_PCTX_FLAGS_SHOW_SSOF		0x004
        +/* Show the ASN1 type of primitives */
        +#define ASN1_PCTX_FLAGS_SHOW_TYPE		0x008
        +/* Don't show ASN1 type of ANY */
        +#define ASN1_PCTX_FLAGS_NO_ANY_TYPE		0x010
        +/* Don't show ASN1 type of MSTRINGs */
        +#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE		0x020
        +/* Don't show field names in SEQUENCE */
        +#define ASN1_PCTX_FLAGS_NO_FIELD_NAME		0x040
        +/* Show structure names of each SEQUENCE field */
        +#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME	0x080
        +/* Don't show structure name even at top level */
        +#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME		0x100
        +
        +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
        +				const ASN1_ITEM *it, const ASN1_PCTX *pctx);
        +ASN1_PCTX *ASN1_PCTX_new(void);
        +void ASN1_PCTX_free(ASN1_PCTX *p);
        +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
        +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
        +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
        +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
        +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
        +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
        +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
        +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
        +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
        +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
        +
        +BIO_METHOD *BIO_f_asn1(void);
        +
        +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
        +
        +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
        +				const ASN1_ITEM *it);
        +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
        +				const char *hdr,
        +				const ASN1_ITEM *it);
        +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
        +				int ctype_nid, int econt_nid,
        +				STACK_OF(X509_ALGOR) *mdalgs,
        +				const ASN1_ITEM *it);
        +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
        +int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
        +int SMIME_text(BIO *in, BIO *out);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_ASN1_strings(void);
        +
        +/* Error codes for the ASN1 functions. */
        +
        +/* Function codes. */
        +#define ASN1_F_A2D_ASN1_OBJECT				 100
        +#define ASN1_F_A2I_ASN1_ENUMERATED			 101
        +#define ASN1_F_A2I_ASN1_INTEGER				 102
        +#define ASN1_F_A2I_ASN1_STRING				 103
        +#define ASN1_F_APPEND_EXP				 176
        +#define ASN1_F_ASN1_BIT_STRING_SET_BIT			 183
        +#define ASN1_F_ASN1_CB					 177
        +#define ASN1_F_ASN1_CHECK_TLEN				 104
        +#define ASN1_F_ASN1_COLLATE_PRIMITIVE			 105
        +#define ASN1_F_ASN1_COLLECT				 106
        +#define ASN1_F_ASN1_D2I_EX_PRIMITIVE			 108
        +#define ASN1_F_ASN1_D2I_FP				 109
        +#define ASN1_F_ASN1_D2I_READ_BIO			 107
        +#define ASN1_F_ASN1_DIGEST				 184
        +#define ASN1_F_ASN1_DO_ADB				 110
        +#define ASN1_F_ASN1_DUP					 111
        +#define ASN1_F_ASN1_ENUMERATED_SET			 112
        +#define ASN1_F_ASN1_ENUMERATED_TO_BN			 113
        +#define ASN1_F_ASN1_EX_C2I				 204
        +#define ASN1_F_ASN1_FIND_END				 190
        +#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ			 216
        +#define ASN1_F_ASN1_GENERALIZEDTIME_SET			 185
        +#define ASN1_F_ASN1_GENERATE_V3				 178
        +#define ASN1_F_ASN1_GET_OBJECT				 114
        +#define ASN1_F_ASN1_HEADER_NEW				 115
        +#define ASN1_F_ASN1_I2D_BIO				 116
        +#define ASN1_F_ASN1_I2D_FP				 117
        +#define ASN1_F_ASN1_INTEGER_SET				 118
        +#define ASN1_F_ASN1_INTEGER_TO_BN			 119
        +#define ASN1_F_ASN1_ITEM_D2I_FP				 206
        +#define ASN1_F_ASN1_ITEM_DUP				 191
        +#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW			 121
        +#define ASN1_F_ASN1_ITEM_EX_D2I				 120
        +#define ASN1_F_ASN1_ITEM_I2D_BIO			 192
        +#define ASN1_F_ASN1_ITEM_I2D_FP				 193
        +#define ASN1_F_ASN1_ITEM_PACK				 198
        +#define ASN1_F_ASN1_ITEM_SIGN				 195
        +#define ASN1_F_ASN1_ITEM_SIGN_CTX			 220
        +#define ASN1_F_ASN1_ITEM_UNPACK				 199
        +#define ASN1_F_ASN1_ITEM_VERIFY				 197
        +#define ASN1_F_ASN1_MBSTRING_NCOPY			 122
        +#define ASN1_F_ASN1_OBJECT_NEW				 123
        +#define ASN1_F_ASN1_OUTPUT_DATA				 214
        +#define ASN1_F_ASN1_PACK_STRING				 124
        +#define ASN1_F_ASN1_PCTX_NEW				 205
        +#define ASN1_F_ASN1_PKCS5_PBE_SET			 125
        +#define ASN1_F_ASN1_SEQ_PACK				 126
        +#define ASN1_F_ASN1_SEQ_UNPACK				 127
        +#define ASN1_F_ASN1_SIGN				 128
        +#define ASN1_F_ASN1_STR2TYPE				 179
        +#define ASN1_F_ASN1_STRING_SET				 186
        +#define ASN1_F_ASN1_STRING_TABLE_ADD			 129
        +#define ASN1_F_ASN1_STRING_TYPE_NEW			 130
        +#define ASN1_F_ASN1_TEMPLATE_EX_D2I			 132
        +#define ASN1_F_ASN1_TEMPLATE_NEW			 133
        +#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I			 131
        +#define ASN1_F_ASN1_TIME_ADJ				 217
        +#define ASN1_F_ASN1_TIME_SET				 175
        +#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 134
        +#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 135
        +#define ASN1_F_ASN1_UNPACK_STRING			 136
        +#define ASN1_F_ASN1_UTCTIME_ADJ				 218
        +#define ASN1_F_ASN1_UTCTIME_SET				 187
        +#define ASN1_F_ASN1_VERIFY				 137
        +#define ASN1_F_B64_READ_ASN1				 209
        +#define ASN1_F_B64_WRITE_ASN1				 210
        +#define ASN1_F_BIO_NEW_NDEF				 208
        +#define ASN1_F_BITSTR_CB				 180
        +#define ASN1_F_BN_TO_ASN1_ENUMERATED			 138
        +#define ASN1_F_BN_TO_ASN1_INTEGER			 139
        +#define ASN1_F_C2I_ASN1_BIT_STRING			 189
        +#define ASN1_F_C2I_ASN1_INTEGER				 194
        +#define ASN1_F_C2I_ASN1_OBJECT				 196
        +#define ASN1_F_COLLECT_DATA				 140
        +#define ASN1_F_D2I_ASN1_BIT_STRING			 141
        +#define ASN1_F_D2I_ASN1_BOOLEAN				 142
        +#define ASN1_F_D2I_ASN1_BYTES				 143
        +#define ASN1_F_D2I_ASN1_GENERALIZEDTIME			 144
        +#define ASN1_F_D2I_ASN1_HEADER				 145
        +#define ASN1_F_D2I_ASN1_INTEGER				 146
        +#define ASN1_F_D2I_ASN1_OBJECT				 147
        +#define ASN1_F_D2I_ASN1_SET				 148
        +#define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
        +#define ASN1_F_D2I_ASN1_UINTEGER			 150
        +#define ASN1_F_D2I_ASN1_UTCTIME				 151
        +#define ASN1_F_D2I_AUTOPRIVATEKEY			 207
        +#define ASN1_F_D2I_NETSCAPE_RSA				 152
        +#define ASN1_F_D2I_NETSCAPE_RSA_2			 153
        +#define ASN1_F_D2I_PRIVATEKEY				 154
        +#define ASN1_F_D2I_PUBLICKEY				 155
        +#define ASN1_F_D2I_RSA_NET				 200
        +#define ASN1_F_D2I_RSA_NET_2				 201
        +#define ASN1_F_D2I_X509					 156
        +#define ASN1_F_D2I_X509_CINF				 157
        +#define ASN1_F_D2I_X509_PKEY				 159
        +#define ASN1_F_I2D_ASN1_BIO_STREAM			 211
        +#define ASN1_F_I2D_ASN1_SET				 188
        +#define ASN1_F_I2D_ASN1_TIME				 160
        +#define ASN1_F_I2D_DSA_PUBKEY				 161
        +#define ASN1_F_I2D_EC_PUBKEY				 181
        +#define ASN1_F_I2D_PRIVATEKEY				 163
        +#define ASN1_F_I2D_PUBLICKEY				 164
        +#define ASN1_F_I2D_RSA_NET				 162
        +#define ASN1_F_I2D_RSA_PUBKEY				 165
        +#define ASN1_F_LONG_C2I					 166
        +#define ASN1_F_OID_MODULE_INIT				 174
        +#define ASN1_F_PARSE_TAGGING				 182
        +#define ASN1_F_PKCS5_PBE2_SET_IV			 167
        +#define ASN1_F_PKCS5_PBE_SET				 202
        +#define ASN1_F_PKCS5_PBE_SET0_ALGOR			 215
        +#define ASN1_F_PKCS5_PBKDF2_SET				 219
        +#define ASN1_F_SMIME_READ_ASN1				 212
        +#define ASN1_F_SMIME_TEXT				 213
        +#define ASN1_F_X509_CINF_NEW				 168
        +#define ASN1_F_X509_CRL_ADD0_REVOKED			 169
        +#define ASN1_F_X509_INFO_NEW				 170
        +#define ASN1_F_X509_NAME_ENCODE				 203
        +#define ASN1_F_X509_NAME_EX_D2I				 158
        +#define ASN1_F_X509_NAME_EX_NEW				 171
        +#define ASN1_F_X509_NEW					 172
        +#define ASN1_F_X509_PKEY_NEW				 173
        +
        +/* Reason codes. */
        +#define ASN1_R_ADDING_OBJECT				 171
        +#define ASN1_R_ASN1_PARSE_ERROR				 203
        +#define ASN1_R_ASN1_SIG_PARSE_ERROR			 204
        +#define ASN1_R_AUX_ERROR				 100
        +#define ASN1_R_BAD_CLASS				 101
        +#define ASN1_R_BAD_OBJECT_HEADER			 102
        +#define ASN1_R_BAD_PASSWORD_READ			 103
        +#define ASN1_R_BAD_TAG					 104
        +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH		 214
        +#define ASN1_R_BN_LIB					 105
        +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
        +#define ASN1_R_BUFFER_TOO_SMALL				 107
        +#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 108
        +#define ASN1_R_CONTEXT_NOT_INITIALISED			 217
        +#define ASN1_R_DATA_IS_WRONG				 109
        +#define ASN1_R_DECODE_ERROR				 110
        +#define ASN1_R_DECODING_ERROR				 111
        +#define ASN1_R_DEPTH_EXCEEDED				 174
        +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED	 198
        +#define ASN1_R_ENCODE_ERROR				 112
        +#define ASN1_R_ERROR_GETTING_TIME			 173
        +#define ASN1_R_ERROR_LOADING_SECTION			 172
        +#define ASN1_R_ERROR_PARSING_SET_ELEMENT		 113
        +#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS		 114
        +#define ASN1_R_EXPECTING_AN_INTEGER			 115
        +#define ASN1_R_EXPECTING_AN_OBJECT			 116
        +#define ASN1_R_EXPECTING_A_BOOLEAN			 117
        +#define ASN1_R_EXPECTING_A_TIME				 118
        +#define ASN1_R_EXPLICIT_LENGTH_MISMATCH			 119
        +#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED		 120
        +#define ASN1_R_FIELD_MISSING				 121
        +#define ASN1_R_FIRST_NUM_TOO_LARGE			 122
        +#define ASN1_R_HEADER_TOO_LONG				 123
        +#define ASN1_R_ILLEGAL_BITSTRING_FORMAT			 175
        +#define ASN1_R_ILLEGAL_BOOLEAN				 176
        +#define ASN1_R_ILLEGAL_CHARACTERS			 124
        +#define ASN1_R_ILLEGAL_FORMAT				 177
        +#define ASN1_R_ILLEGAL_HEX				 178
        +#define ASN1_R_ILLEGAL_IMPLICIT_TAG			 179
        +#define ASN1_R_ILLEGAL_INTEGER				 180
        +#define ASN1_R_ILLEGAL_NESTED_TAGGING			 181
        +#define ASN1_R_ILLEGAL_NULL				 125
        +#define ASN1_R_ILLEGAL_NULL_VALUE			 182
        +#define ASN1_R_ILLEGAL_OBJECT				 183
        +#define ASN1_R_ILLEGAL_OPTIONAL_ANY			 126
        +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE		 170
        +#define ASN1_R_ILLEGAL_TAGGED_ANY			 127
        +#define ASN1_R_ILLEGAL_TIME_VALUE			 184
        +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT			 185
        +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
        +#define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
        +#define ASN1_R_INVALID_DIGIT				 130
        +#define ASN1_R_INVALID_MIME_TYPE			 205
        +#define ASN1_R_INVALID_MODIFIER				 186
        +#define ASN1_R_INVALID_NUMBER				 187
        +#define ASN1_R_INVALID_OBJECT_ENCODING			 216
        +#define ASN1_R_INVALID_SEPARATOR			 131
        +#define ASN1_R_INVALID_TIME_FORMAT			 132
        +#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 133
        +#define ASN1_R_INVALID_UTF8STRING			 134
        +#define ASN1_R_IV_TOO_LARGE				 135
        +#define ASN1_R_LENGTH_ERROR				 136
        +#define ASN1_R_LIST_ERROR				 188
        +#define ASN1_R_MIME_NO_CONTENT_TYPE			 206
        +#define ASN1_R_MIME_PARSE_ERROR				 207
        +#define ASN1_R_MIME_SIG_PARSE_ERROR			 208
        +#define ASN1_R_MISSING_EOC				 137
        +#define ASN1_R_MISSING_SECOND_NUMBER			 138
        +#define ASN1_R_MISSING_VALUE				 189
        +#define ASN1_R_MSTRING_NOT_UNIVERSAL			 139
        +#define ASN1_R_MSTRING_WRONG_TAG			 140
        +#define ASN1_R_NESTED_ASN1_STRING			 197
        +#define ASN1_R_NON_HEX_CHARACTERS			 141
        +#define ASN1_R_NOT_ASCII_FORMAT				 190
        +#define ASN1_R_NOT_ENOUGH_DATA				 142
        +#define ASN1_R_NO_CONTENT_TYPE				 209
        +#define ASN1_R_NO_DEFAULT_DIGEST			 201
        +#define ASN1_R_NO_MATCHING_CHOICE_TYPE			 143
        +#define ASN1_R_NO_MULTIPART_BODY_FAILURE		 210
        +#define ASN1_R_NO_MULTIPART_BOUNDARY			 211
        +#define ASN1_R_NO_SIG_CONTENT_TYPE			 212
        +#define ASN1_R_NULL_IS_WRONG_LENGTH			 144
        +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT			 191
        +#define ASN1_R_ODD_NUMBER_OF_CHARS			 145
        +#define ASN1_R_PRIVATE_KEY_HEADER_MISSING		 146
        +#define ASN1_R_SECOND_NUMBER_TOO_LARGE			 147
        +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH			 148
        +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED			 149
        +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG		 192
        +#define ASN1_R_SHORT_LINE				 150
        +#define ASN1_R_SIG_INVALID_MIME_TYPE			 213
        +#define ASN1_R_STREAMING_NOT_SUPPORTED			 202
        +#define ASN1_R_STRING_TOO_LONG				 151
        +#define ASN1_R_STRING_TOO_SHORT				 152
        +#define ASN1_R_TAG_VALUE_TOO_HIGH			 153
        +#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
        +#define ASN1_R_TIME_NOT_ASCII_FORMAT			 193
        +#define ASN1_R_TOO_LONG					 155
        +#define ASN1_R_TYPE_NOT_CONSTRUCTED			 156
        +#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
        +#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
        +#define ASN1_R_UNEXPECTED_EOC				 159
        +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH		 215
        +#define ASN1_R_UNKNOWN_FORMAT				 160
        +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
        +#define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
        +#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 163
        +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM		 199
        +#define ASN1_R_UNKNOWN_TAG				 194
        +#define ASN1_R_UNKOWN_FORMAT				 195
        +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE		 164
        +#define ASN1_R_UNSUPPORTED_CIPHER			 165
        +#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 166
        +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 167
        +#define ASN1_R_UNSUPPORTED_TYPE				 196
        +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE			 200
        +#define ASN1_R_WRONG_TAG				 168
        +#define ASN1_R_WRONG_TYPE				 169
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1_err.c b/vendor/openssl/openssl/crypto/asn1/asn1_err.c
        new file mode 100644
        index 000000000..1a30bf119
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1_err.c
        @@ -0,0 +1,332 @@
        +/* crypto/asn1/asn1_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/asn1.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
        +
        +static ERR_STRING_DATA ASN1_str_functs[]=
        +	{
        +{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT),	"a2d_ASN1_OBJECT"},
        +{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED),	"a2i_ASN1_ENUMERATED"},
        +{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER),	"a2i_ASN1_INTEGER"},
        +{ERR_FUNC(ASN1_F_A2I_ASN1_STRING),	"a2i_ASN1_STRING"},
        +{ERR_FUNC(ASN1_F_APPEND_EXP),	"APPEND_EXP"},
        +{ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT),	"ASN1_BIT_STRING_set_bit"},
        +{ERR_FUNC(ASN1_F_ASN1_CB),	"ASN1_CB"},
        +{ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN),	"ASN1_CHECK_TLEN"},
        +{ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE),	"ASN1_COLLATE_PRIMITIVE"},
        +{ERR_FUNC(ASN1_F_ASN1_COLLECT),	"ASN1_COLLECT"},
        +{ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE),	"ASN1_D2I_EX_PRIMITIVE"},
        +{ERR_FUNC(ASN1_F_ASN1_D2I_FP),	"ASN1_d2i_fp"},
        +{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO),	"ASN1_D2I_READ_BIO"},
        +{ERR_FUNC(ASN1_F_ASN1_DIGEST),	"ASN1_digest"},
        +{ERR_FUNC(ASN1_F_ASN1_DO_ADB),	"ASN1_DO_ADB"},
        +{ERR_FUNC(ASN1_F_ASN1_DUP),	"ASN1_dup"},
        +{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET),	"ASN1_ENUMERATED_set"},
        +{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN),	"ASN1_ENUMERATED_to_BN"},
        +{ERR_FUNC(ASN1_F_ASN1_EX_C2I),	"ASN1_EX_C2I"},
        +{ERR_FUNC(ASN1_F_ASN1_FIND_END),	"ASN1_FIND_END"},
        +{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ),	"ASN1_GENERALIZEDTIME_adj"},
        +{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET),	"ASN1_GENERALIZEDTIME_set"},
        +{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3),	"ASN1_generate_v3"},
        +{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT),	"ASN1_get_object"},
        +{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW),	"ASN1_HEADER_NEW"},
        +{ERR_FUNC(ASN1_F_ASN1_I2D_BIO),	"ASN1_i2d_bio"},
        +{ERR_FUNC(ASN1_F_ASN1_I2D_FP),	"ASN1_i2d_fp"},
        +{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET),	"ASN1_INTEGER_set"},
        +{ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN),	"ASN1_INTEGER_to_BN"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP),	"ASN1_item_d2i_fp"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP),	"ASN1_item_dup"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW),	"ASN1_ITEM_EX_COMBINE_NEW"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I),	"ASN1_ITEM_EX_D2I"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO),	"ASN1_item_i2d_bio"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP),	"ASN1_item_i2d_fp"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK),	"ASN1_item_pack"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN),	"ASN1_item_sign"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX),	"ASN1_item_sign_ctx"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK),	"ASN1_item_unpack"},
        +{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY),	"ASN1_item_verify"},
        +{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY),	"ASN1_mbstring_ncopy"},
        +{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW),	"ASN1_OBJECT_new"},
        +{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA),	"ASN1_OUTPUT_DATA"},
        +{ERR_FUNC(ASN1_F_ASN1_PACK_STRING),	"ASN1_pack_string"},
        +{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW),	"ASN1_PCTX_new"},
        +{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET),	"ASN1_PKCS5_PBE_SET"},
        +{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK),	"ASN1_seq_pack"},
        +{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK),	"ASN1_seq_unpack"},
        +{ERR_FUNC(ASN1_F_ASN1_SIGN),	"ASN1_sign"},
        +{ERR_FUNC(ASN1_F_ASN1_STR2TYPE),	"ASN1_STR2TYPE"},
        +{ERR_FUNC(ASN1_F_ASN1_STRING_SET),	"ASN1_STRING_set"},
        +{ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD),	"ASN1_STRING_TABLE_add"},
        +{ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW),	"ASN1_STRING_type_new"},
        +{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I),	"ASN1_TEMPLATE_EX_D2I"},
        +{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW),	"ASN1_TEMPLATE_NEW"},
        +{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I),	"ASN1_TEMPLATE_NOEXP_D2I"},
        +{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ),	"ASN1_TIME_adj"},
        +{ERR_FUNC(ASN1_F_ASN1_TIME_SET),	"ASN1_TIME_set"},
        +{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),	"ASN1_TYPE_get_int_octetstring"},
        +{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING),	"ASN1_TYPE_get_octetstring"},
        +{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING),	"ASN1_unpack_string"},
        +{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ),	"ASN1_UTCTIME_adj"},
        +{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET),	"ASN1_UTCTIME_set"},
        +{ERR_FUNC(ASN1_F_ASN1_VERIFY),	"ASN1_verify"},
        +{ERR_FUNC(ASN1_F_B64_READ_ASN1),	"B64_READ_ASN1"},
        +{ERR_FUNC(ASN1_F_B64_WRITE_ASN1),	"B64_WRITE_ASN1"},
        +{ERR_FUNC(ASN1_F_BIO_NEW_NDEF),	"BIO_new_NDEF"},
        +{ERR_FUNC(ASN1_F_BITSTR_CB),	"BITSTR_CB"},
        +{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED),	"BN_to_ASN1_ENUMERATED"},
        +{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER),	"BN_to_ASN1_INTEGER"},
        +{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING),	"c2i_ASN1_BIT_STRING"},
        +{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER),	"c2i_ASN1_INTEGER"},
        +{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT),	"c2i_ASN1_OBJECT"},
        +{ERR_FUNC(ASN1_F_COLLECT_DATA),	"COLLECT_DATA"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING),	"D2I_ASN1_BIT_STRING"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN),	"d2i_ASN1_BOOLEAN"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES),	"d2i_ASN1_bytes"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME),	"D2I_ASN1_GENERALIZEDTIME"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER),	"D2I_ASN1_HEADER"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER),	"D2I_ASN1_INTEGER"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT),	"d2i_ASN1_OBJECT"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_SET),	"d2i_ASN1_SET"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES),	"d2i_ASN1_type_bytes"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER),	"d2i_ASN1_UINTEGER"},
        +{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME),	"D2I_ASN1_UTCTIME"},
        +{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY),	"d2i_AutoPrivateKey"},
        +{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA),	"d2i_Netscape_RSA"},
        +{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2),	"D2I_NETSCAPE_RSA_2"},
        +{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY),	"d2i_PrivateKey"},
        +{ERR_FUNC(ASN1_F_D2I_PUBLICKEY),	"d2i_PublicKey"},
        +{ERR_FUNC(ASN1_F_D2I_RSA_NET),	"d2i_RSA_NET"},
        +{ERR_FUNC(ASN1_F_D2I_RSA_NET_2),	"D2I_RSA_NET_2"},
        +{ERR_FUNC(ASN1_F_D2I_X509),	"D2I_X509"},
        +{ERR_FUNC(ASN1_F_D2I_X509_CINF),	"D2I_X509_CINF"},
        +{ERR_FUNC(ASN1_F_D2I_X509_PKEY),	"d2i_X509_PKEY"},
        +{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM),	"i2d_ASN1_bio_stream"},
        +{ERR_FUNC(ASN1_F_I2D_ASN1_SET),	"i2d_ASN1_SET"},
        +{ERR_FUNC(ASN1_F_I2D_ASN1_TIME),	"I2D_ASN1_TIME"},
        +{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY),	"i2d_DSA_PUBKEY"},
        +{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY),	"i2d_EC_PUBKEY"},
        +{ERR_FUNC(ASN1_F_I2D_PRIVATEKEY),	"i2d_PrivateKey"},
        +{ERR_FUNC(ASN1_F_I2D_PUBLICKEY),	"i2d_PublicKey"},
        +{ERR_FUNC(ASN1_F_I2D_RSA_NET),	"i2d_RSA_NET"},
        +{ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY),	"i2d_RSA_PUBKEY"},
        +{ERR_FUNC(ASN1_F_LONG_C2I),	"LONG_C2I"},
        +{ERR_FUNC(ASN1_F_OID_MODULE_INIT),	"OID_MODULE_INIT"},
        +{ERR_FUNC(ASN1_F_PARSE_TAGGING),	"PARSE_TAGGING"},
        +{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV),	"PKCS5_pbe2_set_iv"},
        +{ERR_FUNC(ASN1_F_PKCS5_PBE_SET),	"PKCS5_pbe_set"},
        +{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR),	"PKCS5_pbe_set0_algor"},
        +{ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET),	"PKCS5_pbkdf2_set"},
        +{ERR_FUNC(ASN1_F_SMIME_READ_ASN1),	"SMIME_read_ASN1"},
        +{ERR_FUNC(ASN1_F_SMIME_TEXT),	"SMIME_text"},
        +{ERR_FUNC(ASN1_F_X509_CINF_NEW),	"X509_CINF_NEW"},
        +{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED),	"X509_CRL_add0_revoked"},
        +{ERR_FUNC(ASN1_F_X509_INFO_NEW),	"X509_INFO_new"},
        +{ERR_FUNC(ASN1_F_X509_NAME_ENCODE),	"X509_NAME_ENCODE"},
        +{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I),	"X509_NAME_EX_D2I"},
        +{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW),	"X509_NAME_EX_NEW"},
        +{ERR_FUNC(ASN1_F_X509_NEW),	"X509_NEW"},
        +{ERR_FUNC(ASN1_F_X509_PKEY_NEW),	"X509_PKEY_new"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ASN1_str_reasons[]=
        +	{
        +{ERR_REASON(ASN1_R_ADDING_OBJECT)        ,"adding object"},
        +{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR)     ,"asn1 parse error"},
        +{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"},
        +{ERR_REASON(ASN1_R_AUX_ERROR)            ,"aux error"},
        +{ERR_REASON(ASN1_R_BAD_CLASS)            ,"bad class"},
        +{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER)    ,"bad object header"},
        +{ERR_REASON(ASN1_R_BAD_PASSWORD_READ)    ,"bad password read"},
        +{ERR_REASON(ASN1_R_BAD_TAG)              ,"bad tag"},
        +{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),"bmpstring is wrong length"},
        +{ERR_REASON(ASN1_R_BN_LIB)               ,"bn lib"},
        +{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
        +{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL)     ,"buffer too small"},
        +{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
        +{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED),"context not initialised"},
        +{ERR_REASON(ASN1_R_DATA_IS_WRONG)        ,"data is wrong"},
        +{ERR_REASON(ASN1_R_DECODE_ERROR)         ,"decode error"},
        +{ERR_REASON(ASN1_R_DECODING_ERROR)       ,"decoding error"},
        +{ERR_REASON(ASN1_R_DEPTH_EXCEEDED)       ,"depth exceeded"},
        +{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
        +{ERR_REASON(ASN1_R_ENCODE_ERROR)         ,"encode error"},
        +{ERR_REASON(ASN1_R_ERROR_GETTING_TIME)   ,"error getting time"},
        +{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
        +{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT),"error parsing set element"},
        +{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),"error setting cipher params"},
        +{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER) ,"expecting an integer"},
        +{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT)  ,"expecting an object"},
        +{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN)  ,"expecting a boolean"},
        +{ERR_REASON(ASN1_R_EXPECTING_A_TIME)     ,"expecting a time"},
        +{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH),"explicit length mismatch"},
        +{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),"explicit tag not constructed"},
        +{ERR_REASON(ASN1_R_FIELD_MISSING)        ,"field missing"},
        +{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE)  ,"first num too large"},
        +{ERR_REASON(ASN1_R_HEADER_TOO_LONG)      ,"header too long"},
        +{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT),"illegal bitstring format"},
        +{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN)      ,"illegal boolean"},
        +{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS)   ,"illegal characters"},
        +{ERR_REASON(ASN1_R_ILLEGAL_FORMAT)       ,"illegal format"},
        +{ERR_REASON(ASN1_R_ILLEGAL_HEX)          ,"illegal hex"},
        +{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) ,"illegal implicit tag"},
        +{ERR_REASON(ASN1_R_ILLEGAL_INTEGER)      ,"illegal integer"},
        +{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING),"illegal nested tagging"},
        +{ERR_REASON(ASN1_R_ILLEGAL_NULL)         ,"illegal null"},
        +{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE)   ,"illegal null value"},
        +{ERR_REASON(ASN1_R_ILLEGAL_OBJECT)       ,"illegal object"},
        +{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) ,"illegal optional any"},
        +{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),"illegal options on item template"},
        +{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY)   ,"illegal tagged any"},
        +{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE)   ,"illegal time value"},
        +{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
        +{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
        +{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
        +{ERR_REASON(ASN1_R_INVALID_DIGIT)        ,"invalid digit"},
        +{ERR_REASON(ASN1_R_INVALID_MIME_TYPE)    ,"invalid mime type"},
        +{ERR_REASON(ASN1_R_INVALID_MODIFIER)     ,"invalid modifier"},
        +{ERR_REASON(ASN1_R_INVALID_NUMBER)       ,"invalid number"},
        +{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
        +{ERR_REASON(ASN1_R_INVALID_SEPARATOR)    ,"invalid separator"},
        +{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT)  ,"invalid time format"},
        +{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
        +{ERR_REASON(ASN1_R_INVALID_UTF8STRING)   ,"invalid utf8string"},
        +{ERR_REASON(ASN1_R_IV_TOO_LARGE)         ,"iv too large"},
        +{ERR_REASON(ASN1_R_LENGTH_ERROR)         ,"length error"},
        +{ERR_REASON(ASN1_R_LIST_ERROR)           ,"list error"},
        +{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) ,"mime no content type"},
        +{ERR_REASON(ASN1_R_MIME_PARSE_ERROR)     ,"mime parse error"},
        +{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) ,"mime sig parse error"},
        +{ERR_REASON(ASN1_R_MISSING_EOC)          ,"missing eoc"},
        +{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"},
        +{ERR_REASON(ASN1_R_MISSING_VALUE)        ,"missing value"},
        +{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL),"mstring not universal"},
        +{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG)    ,"mstring wrong tag"},
        +{ERR_REASON(ASN1_R_NESTED_ASN1_STRING)   ,"nested asn1 string"},
        +{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS)   ,"non hex characters"},
        +{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT)     ,"not ascii format"},
        +{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA)      ,"not enough data"},
        +{ERR_REASON(ASN1_R_NO_CONTENT_TYPE)      ,"no content type"},
        +{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST)    ,"no default digest"},
        +{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
        +{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
        +{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
        +{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE)  ,"no sig content type"},
        +{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
        +{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
        +{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS)  ,"odd number of chars"},
        +{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),"private key header missing"},
        +{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE),"second number too large"},
        +{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH),"sequence length mismatch"},
        +{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"},
        +{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"},
        +{ERR_REASON(ASN1_R_SHORT_LINE)           ,"short line"},
        +{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
        +{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED),"streaming not supported"},
        +{ERR_REASON(ASN1_R_STRING_TOO_LONG)      ,"string too long"},
        +{ERR_REASON(ASN1_R_STRING_TOO_SHORT)     ,"string too short"},
        +{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH)   ,"tag value too high"},
        +{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
        +{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
        +{ERR_REASON(ASN1_R_TOO_LONG)             ,"too long"},
        +{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
        +{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
        +{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
        +{ERR_REASON(ASN1_R_UNEXPECTED_EOC)       ,"unexpected eoc"},
        +{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),"universalstring is wrong length"},
        +{ERR_REASON(ASN1_R_UNKNOWN_FORMAT)       ,"unknown format"},
        +{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
        +{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE)  ,"unknown object type"},
        +{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
        +{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
        +{ERR_REASON(ASN1_R_UNKNOWN_TAG)          ,"unknown tag"},
        +{ERR_REASON(ASN1_R_UNKOWN_FORMAT)        ,"unkown format"},
        +{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
        +{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER)   ,"unsupported cipher"},
        +{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
        +{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
        +{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE)     ,"unsupported type"},
        +{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
        +{ERR_REASON(ASN1_R_WRONG_TAG)            ,"wrong tag"},
        +{ERR_REASON(ASN1_R_WRONG_TYPE)           ,"wrong type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_ASN1_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,ASN1_str_functs);
        +		ERR_load_strings(0,ASN1_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1_gen.c b/vendor/openssl/openssl/crypto/asn1/asn1_gen.c
        new file mode 100644
        index 000000000..4fc241908
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1_gen.c
        @@ -0,0 +1,854 @@
        +/* asn1_gen.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/x509v3.h>
        +
        +#define ASN1_GEN_FLAG		0x10000
        +#define ASN1_GEN_FLAG_IMP	(ASN1_GEN_FLAG|1)
        +#define ASN1_GEN_FLAG_EXP	(ASN1_GEN_FLAG|2)
        +#define ASN1_GEN_FLAG_TAG	(ASN1_GEN_FLAG|3)
        +#define ASN1_GEN_FLAG_BITWRAP	(ASN1_GEN_FLAG|4)
        +#define ASN1_GEN_FLAG_OCTWRAP	(ASN1_GEN_FLAG|5)
        +#define ASN1_GEN_FLAG_SEQWRAP	(ASN1_GEN_FLAG|6)
        +#define ASN1_GEN_FLAG_SETWRAP	(ASN1_GEN_FLAG|7)
        +#define ASN1_GEN_FLAG_FORMAT	(ASN1_GEN_FLAG|8)
        +
        +#define ASN1_GEN_STR(str,val)	{str, sizeof(str) - 1, val}
        +
        +#define ASN1_FLAG_EXP_MAX	20
        +
        +/* Input formats */
        +
        +/* ASCII: default */
        +#define ASN1_GEN_FORMAT_ASCII	1
        +/* UTF8 */
        +#define ASN1_GEN_FORMAT_UTF8	2
        +/* Hex */
        +#define ASN1_GEN_FORMAT_HEX	3
        +/* List of bits */
        +#define ASN1_GEN_FORMAT_BITLIST	4
        +
        +
        +struct tag_name_st
        +	{
        +	const char *strnam;
        +	int len;
        +	int tag;
        +	};
        +
        +typedef struct
        +	{
        +	int exp_tag;
        +	int exp_class;
        +	int exp_constructed;
        +	int exp_pad;
        +	long exp_len;
        +	} tag_exp_type;
        +
        +typedef struct
        +	{
        +	int imp_tag;
        +	int imp_class;
        +	int utype;
        +	int format;
        +	const char *str;
        +	tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
        +	int exp_count;
        +	} tag_exp_arg;
        +
        +static int bitstr_cb(const char *elem, int len, void *bitstr);
        +static int asn1_cb(const char *elem, int len, void *bitstr);
        +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
        +static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
        +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
        +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
        +static int asn1_str2tag(const char *tagstr, int len);
        +
        +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
        +	{
        +	X509V3_CTX cnf;
        +
        +	if (!nconf)
        +		return ASN1_generate_v3(str, NULL);
        +
        +	X509V3_set_nconf(&cnf, nconf);
        +	return ASN1_generate_v3(str, &cnf);
        +	}
        +
        +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
        +	{
        +	ASN1_TYPE *ret;
        +	tag_exp_arg asn1_tags;
        +	tag_exp_type *etmp;
        +
        +	int i, len;
        +
        +	unsigned char *orig_der = NULL, *new_der = NULL;
        +	const unsigned char *cpy_start;
        +	unsigned char *p;
        +	const unsigned char *cp;
        +	int cpy_len;
        +	long hdr_len;
        +	int hdr_constructed = 0, hdr_tag, hdr_class;
        +	int r;
        +
        +	asn1_tags.imp_tag = -1;
        +	asn1_tags.imp_class = -1;
        +	asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
        +	asn1_tags.exp_count = 0;
        +	if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
        +		return NULL;
        +
        +	if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
        +		{
        +		if (!cnf)
        +			{
        +			ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
        +			return NULL;
        +			}
        +		ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
        +		}
        +	else
        +		ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
        +
        +	if (!ret)
        +		return NULL;
        +
        +	/* If no tagging return base type */
        +	if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
        +		return ret;
        +
        +	/* Generate the encoding */
        +	cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
        +	ASN1_TYPE_free(ret);
        +	ret = NULL;
        +	/* Set point to start copying for modified encoding */
        +	cpy_start = orig_der;
        +
        +	/* Do we need IMPLICIT tagging? */
        +	if (asn1_tags.imp_tag != -1)
        +		{
        +		/* If IMPLICIT we will replace the underlying tag */
        +		/* Skip existing tag+len */
        +		r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
        +		if (r & 0x80)
        +			goto err;
        +		/* Update copy length */
        +		cpy_len -= cpy_start - orig_der;
        +		/* For IMPLICIT tagging the length should match the
        +		 * original length and constructed flag should be
        +		 * consistent.
        +		 */
        +		if (r & 0x1)
        +			{
        +			/* Indefinite length constructed */
        +			hdr_constructed = 2;
        +			hdr_len = 0;
        +			}
        +		else
        +			/* Just retain constructed flag */
        +			hdr_constructed = r & V_ASN1_CONSTRUCTED;
        +		/* Work out new length with IMPLICIT tag: ignore constructed
        +		 * because it will mess up if indefinite length
        +		 */
        +		len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
        +		}
        +	else
        +		len = cpy_len;
        +
        +	/* Work out length in any EXPLICIT, starting from end */
        +
        +	for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
        +		{
        +		/* Content length: number of content octets + any padding */
        +		len += etmp->exp_pad;
        +		etmp->exp_len = len;
        +		/* Total object length: length including new header */
        +		len = ASN1_object_size(0, len, etmp->exp_tag);
        +		}
        +
        +	/* Allocate buffer for new encoding */
        +
        +	new_der = OPENSSL_malloc(len);
        +	if (!new_der)
        +		goto err;
        +
        +	/* Generate tagged encoding */
        +
        +	p = new_der;
        +
        +	/* Output explicit tags first */
        +
        +	for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
        +		{
        +		ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
        +					etmp->exp_tag, etmp->exp_class);
        +		if (etmp->exp_pad)
        +			*p++ = 0;
        +		}
        +
        +	/* If IMPLICIT, output tag */
        +
        +	if (asn1_tags.imp_tag != -1)
        +		{
        +		if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 
        +		    && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
        +		     || asn1_tags.imp_tag == V_ASN1_SET) )
        +			hdr_constructed = V_ASN1_CONSTRUCTED;
        +		ASN1_put_object(&p, hdr_constructed, hdr_len,
        +					asn1_tags.imp_tag, asn1_tags.imp_class);
        +		}
        +
        +	/* Copy across original encoding */
        +	memcpy(p, cpy_start, cpy_len);
        +
        +	cp = new_der;
        +
        +	/* Obtain new ASN1_TYPE structure */
        +	ret = d2i_ASN1_TYPE(NULL, &cp, len);
        +
        +	err:
        +	if (orig_der)
        +		OPENSSL_free(orig_der);
        +	if (new_der)
        +		OPENSSL_free(new_der);
        +
        +	return ret;
        +
        +	}
        +
        +static int asn1_cb(const char *elem, int len, void *bitstr)
        +	{
        +	tag_exp_arg *arg = bitstr;
        +	int i;
        +	int utype;
        +	int vlen = 0;
        +	const char *p, *vstart = NULL;
        +
        +	int tmp_tag, tmp_class;
        +
        +	for(i = 0, p = elem; i < len; p++, i++)
        +		{
        +		/* Look for the ':' in name value pairs */
        +		if (*p == ':')
        +			{
        +			vstart = p + 1;
        +			vlen = len - (vstart - elem);
        +			len = p - elem;
        +			break;
        +			}
        +		}
        +
        +	utype = asn1_str2tag(elem, len);
        +
        +	if (utype == -1)
        +		{
        +		ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
        +		ERR_add_error_data(2, "tag=", elem);
        +		return -1;
        +		}
        +
        +	/* If this is not a modifier mark end of string and exit */
        +	if (!(utype & ASN1_GEN_FLAG))
        +		{
        +		arg->utype = utype;
        +		arg->str = vstart;
        +		/* If no value and not end of string, error */
        +		if (!vstart && elem[len])
        +			{
        +			ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
        +			return -1;
        +			}
        +		return 0;
        +		}
        +
        +	switch(utype)
        +		{
        +
        +		case ASN1_GEN_FLAG_IMP:
        +		/* Check for illegal multiple IMPLICIT tagging */
        +		if (arg->imp_tag != -1)
        +			{
        +			ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
        +			return -1;
        +			}
        +		if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
        +			return -1;
        +		break;
        +
        +		case ASN1_GEN_FLAG_EXP:
        +
        +		if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
        +			return -1;
        +		if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
        +			return -1;
        +		break;
        +
        +		case ASN1_GEN_FLAG_SEQWRAP:
        +		if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
        +			return -1;
        +		break;
        +
        +		case ASN1_GEN_FLAG_SETWRAP:
        +		if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
        +			return -1;
        +		break;
        +
        +		case ASN1_GEN_FLAG_BITWRAP:
        +		if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
        +			return -1;
        +		break;
        +
        +		case ASN1_GEN_FLAG_OCTWRAP:
        +		if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
        +			return -1;
        +		break;
        +
        +		case ASN1_GEN_FLAG_FORMAT:
        +		if (!strncmp(vstart, "ASCII", 5))
        +			arg->format = ASN1_GEN_FORMAT_ASCII;
        +		else if (!strncmp(vstart, "UTF8", 4))
        +			arg->format = ASN1_GEN_FORMAT_UTF8;
        +		else if (!strncmp(vstart, "HEX", 3))
        +			arg->format = ASN1_GEN_FORMAT_HEX;
        +		else if (!strncmp(vstart, "BITLIST", 3))
        +			arg->format = ASN1_GEN_FORMAT_BITLIST;
        +		else
        +			{
        +			ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
        +			return -1;
        +			}
        +		break;
        +
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
        +	{
        +	char erch[2];
        +	long tag_num;
        +	char *eptr;
        +	if (!vstart)
        +		return 0;
        +	tag_num = strtoul(vstart, &eptr, 10);
        +	/* Check we haven't gone past max length: should be impossible */
        +	if (eptr && *eptr && (eptr > vstart + vlen))
        +		return 0;
        +	if (tag_num < 0)
        +		{
        +		ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
        +		return 0;
        +		}
        +	*ptag = tag_num;
        +	/* If we have non numeric characters, parse them */
        +	if (eptr)
        +		vlen -= eptr - vstart;
        +	else 
        +		vlen = 0;
        +	if (vlen)
        +		{
        +		switch (*eptr)
        +			{
        +
        +			case 'U':
        +			*pclass = V_ASN1_UNIVERSAL;
        +			break;
        +
        +			case 'A':
        +			*pclass = V_ASN1_APPLICATION;
        +			break;
        +
        +			case 'P':
        +			*pclass = V_ASN1_PRIVATE;
        +			break;
        +
        +			case 'C':
        +			*pclass = V_ASN1_CONTEXT_SPECIFIC;
        +			break;
        +
        +			default:
        +			erch[0] = *eptr;
        +			erch[1] = 0;
        +			ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
        +			ERR_add_error_data(2, "Char=", erch);
        +			return 0;
        +			break;
        +
        +			}
        +		}
        +	else
        +		*pclass = V_ASN1_CONTEXT_SPECIFIC;
        +
        +	return 1;
        +
        +	}
        +
        +/* Handle multiple types: SET and SEQUENCE */
        +
        +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
        +	{
        +	ASN1_TYPE *ret = NULL;
        +	STACK_OF(ASN1_TYPE) *sk = NULL;
        +	STACK_OF(CONF_VALUE) *sect = NULL;
        +	unsigned char *der = NULL;
        +	int derlen;
        +	int i;
        +	sk = sk_ASN1_TYPE_new_null();
        +	if (!sk)
        +		goto bad;
        +	if (section)
        +		{
        +		if (!cnf)
        +			goto bad;
        +		sect = X509V3_get_section(cnf, (char *)section);
        +		if (!sect)
        +			goto bad;
        +		for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
        +			{
        +			ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
        +			if (!typ)
        +				goto bad;
        +			if (!sk_ASN1_TYPE_push(sk, typ))
        +				goto bad;
        +			}
        +		}
        +
        +	/* Now we has a STACK of the components, convert to the correct form */
        +
        +	if (utype == V_ASN1_SET)
        +		derlen = i2d_ASN1_SET_ANY(sk, &der);
        +	else
        +		derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
        +
        +	if (derlen < 0)
        +		goto bad;
        +
        +	if (!(ret = ASN1_TYPE_new()))
        +		goto bad;
        +
        +	if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
        +		goto bad;
        +
        +	ret->type = utype;
        +
        +	ret->value.asn1_string->data = der;
        +	ret->value.asn1_string->length = derlen;
        +
        +	der = NULL;
        +
        +	bad:
        +
        +	if (der)
        +		OPENSSL_free(der);
        +
        +	if (sk)
        +		sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
        +	if (sect)
        +		X509V3_section_free(cnf, sect);
        +
        +	return ret;
        +	}
        +
        +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
        +	{
        +	tag_exp_type *exp_tmp;
        +	/* Can only have IMPLICIT if permitted */
        +	if ((arg->imp_tag != -1) && !imp_ok)
        +		{
        +		ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
        +		return 0;
        +		}
        +
        +	if (arg->exp_count == ASN1_FLAG_EXP_MAX)
        +		{
        +		ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
        +		return 0;
        +		}
        +
        +	exp_tmp = &arg->exp_list[arg->exp_count++];
        +
        +	/* If IMPLICIT set tag to implicit value then
        +	 * reset implicit tag since it has been used.
        +	 */
        +	if (arg->imp_tag != -1)
        +		{
        +		exp_tmp->exp_tag = arg->imp_tag;
        +		exp_tmp->exp_class = arg->imp_class;
        +		arg->imp_tag = -1;
        +		arg->imp_class = -1;
        +		}
        +	else
        +		{
        +		exp_tmp->exp_tag = exp_tag;
        +		exp_tmp->exp_class = exp_class;
        +		}
        +	exp_tmp->exp_constructed = exp_constructed;
        +	exp_tmp->exp_pad = exp_pad;
        +
        +	return 1;
        +	}
        +
        +
        +static int asn1_str2tag(const char *tagstr, int len)
        +	{
        +	unsigned int i;
        +	static const struct tag_name_st *tntmp, tnst [] = {
        +		ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
        +		ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
        +		ASN1_GEN_STR("NULL", V_ASN1_NULL),
        +		ASN1_GEN_STR("INT", V_ASN1_INTEGER),
        +		ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
        +		ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
        +		ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
        +		ASN1_GEN_STR("OID", V_ASN1_OBJECT),
        +		ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
        +		ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
        +		ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
        +		ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
        +		ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
        +		ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
        +		ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
        +		ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
        +		ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
        +		ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
        +		ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
        +		ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
        +		ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
        +		ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
        +		ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
        +		ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
        +		ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
        +		ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
        +		ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
        +		ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
        +		ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
        +		ASN1_GEN_STR("T61", V_ASN1_T61STRING),
        +		ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
        +		ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
        +		ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
        +		ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
        +		ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
        +		ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
        +
        +		/* Special cases */
        +		ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
        +		ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
        +		ASN1_GEN_STR("SET", V_ASN1_SET),
        +		/* type modifiers */
        +		/* Explicit tag */
        +		ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
        +		ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
        +		/* Implicit tag */
        +		ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
        +		ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
        +		/* OCTET STRING wrapper */
        +		ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
        +		/* SEQUENCE wrapper */
        +		ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
        +		/* SET wrapper */
        +		ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
        +		/* BIT STRING wrapper */
        +		ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
        +		ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
        +		ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
        +	};
        +
        +	if (len == -1)
        +		len = strlen(tagstr);
        +	
        +	tntmp = tnst;	
        +	for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
        +		{
        +		if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
        +			return tntmp->tag;
        +		}
        +	
        +	return -1;
        +	}
        +
        +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
        +	{
        +	ASN1_TYPE *atmp = NULL;
        +
        +	CONF_VALUE vtmp;
        +
        +	unsigned char *rdata;
        +	long rdlen;
        +
        +	int no_unused = 1;
        +
        +	if (!(atmp = ASN1_TYPE_new()))
        +		{
        +		ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	if (!str)
        +		str = "";
        +
        +	switch(utype)
        +		{
        +
        +		case V_ASN1_NULL:
        +		if (str && *str)
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
        +			goto bad_form;
        +			}
        +		break;
        +		
        +		case V_ASN1_BOOLEAN:
        +		if (format != ASN1_GEN_FORMAT_ASCII)
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
        +			goto bad_form;
        +			}
        +		vtmp.name = NULL;
        +		vtmp.section = NULL;
        +		vtmp.value = (char *)str;
        +		if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
        +			goto bad_str;
        +			}
        +		break;
        +
        +		case V_ASN1_INTEGER:
        +		case V_ASN1_ENUMERATED:
        +		if (format != ASN1_GEN_FORMAT_ASCII)
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
        +			goto bad_form;
        +			}
        +		if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
        +			goto bad_str;
        +			}
        +		break;
        +
        +		case V_ASN1_OBJECT:
        +		if (format != ASN1_GEN_FORMAT_ASCII)
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
        +			goto bad_form;
        +			}
        +		if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
        +			goto bad_str;
        +			}
        +		break;
        +
        +		case V_ASN1_UTCTIME:
        +		case V_ASN1_GENERALIZEDTIME:
        +		if (format != ASN1_GEN_FORMAT_ASCII)
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
        +			goto bad_form;
        +			}
        +		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        +			goto bad_str;
        +			}
        +		if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        +			goto bad_str;
        +			}
        +		atmp->value.asn1_string->type = utype;
        +		if (!ASN1_TIME_check(atmp->value.asn1_string))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
        +			goto bad_str;
        +			}
        +
        +		break;
        +
        +		case V_ASN1_BMPSTRING:
        +		case V_ASN1_PRINTABLESTRING:
        +		case V_ASN1_IA5STRING:
        +		case V_ASN1_T61STRING:
        +		case V_ASN1_UTF8STRING:
        +		case V_ASN1_VISIBLESTRING:
        +		case V_ASN1_UNIVERSALSTRING:
        +		case V_ASN1_GENERALSTRING:
        +		case V_ASN1_NUMERICSTRING:
        +
        +		if (format == ASN1_GEN_FORMAT_ASCII)
        +			format = MBSTRING_ASC;
        +		else if (format == ASN1_GEN_FORMAT_UTF8)
        +			format = MBSTRING_UTF8;
        +		else
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
        +			goto bad_form;
        +			}
        +
        +
        +		if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
        +						-1, format, ASN1_tag2bit(utype)) <= 0)
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        +			goto bad_str;
        +			}
        +		
        +
        +		break;
        +
        +		case V_ASN1_BIT_STRING:
        +
        +		case V_ASN1_OCTET_STRING:
        +
        +		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        +			goto bad_form;
        +			}
        +
        +		if (format == ASN1_GEN_FORMAT_HEX)
        +			{
        +
        +			if (!(rdata = string_to_hex((char *)str, &rdlen)))
        +				{
        +				ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
        +				goto bad_str;
        +				}
        +
        +			atmp->value.asn1_string->data = rdata;
        +			atmp->value.asn1_string->length = rdlen;
        +			atmp->value.asn1_string->type = utype;
        +
        +			}
        +		else if (format == ASN1_GEN_FORMAT_ASCII)
        +			ASN1_STRING_set(atmp->value.asn1_string, str, -1);
        +		else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
        +			{
        +			if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
        +				{
        +				ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
        +				goto bad_str;
        +				}
        +			no_unused = 0;
        +			
        +			}
        +		else 
        +			{
        +			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
        +			goto bad_form;
        +			}
        +
        +		if ((utype == V_ASN1_BIT_STRING) && no_unused)
        +			{
        +			atmp->value.asn1_string->flags
        +				&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        +        		atmp->value.asn1_string->flags
        +				|= ASN1_STRING_FLAG_BITS_LEFT;
        +			}
        +
        +
        +		break;
        +
        +		default:
        +		ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
        +		goto bad_str;
        +		break;
        +		}
        +
        +
        +	atmp->type = utype;
        +	return atmp;
        +
        +
        +	bad_str:
        +	ERR_add_error_data(2, "string=", str);
        +	bad_form:
        +
        +	ASN1_TYPE_free(atmp);
        +	return NULL;
        +
        +	}
        +
        +static int bitstr_cb(const char *elem, int len, void *bitstr)
        +	{
        +	long bitnum;
        +	char *eptr;
        +	if (!elem)
        +		return 0;
        +	bitnum = strtoul(elem, &eptr, 10);
        +	if (eptr && *eptr && (eptr != elem + len))
        +		return 0;
        +	if (bitnum < 0)
        +		{
        +		ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
        +		return 0;
        +		}
        +	if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
        +		{
        +		ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1_lib.c b/vendor/openssl/openssl/crypto/asn1/asn1_lib.c
        new file mode 100644
        index 000000000..1bcb44aee
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1_lib.c
        @@ -0,0 +1,482 @@
        +/* crypto/asn1/asn1_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <limits.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1_mac.h>
        +
        +static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
        +static void asn1_put_length(unsigned char **pp, int length);
        +const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
        +
        +static int _asn1_check_infinite_end(const unsigned char **p, long len)
        +	{
        +	/* If there is 0 or 1 byte left, the length check should pick
        +	 * things up */
        +	if (len <= 0)
        +		return(1);
        +	else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
        +		{
        +		(*p)+=2;
        +		return(1);
        +		}
        +	return(0);
        +	}
        +
        +int ASN1_check_infinite_end(unsigned char **p, long len)
        +	{
        +	return _asn1_check_infinite_end((const unsigned char **)p, len);
        +	}
        +
        +int ASN1_const_check_infinite_end(const unsigned char **p, long len)
        +	{
        +	return _asn1_check_infinite_end(p, len);
        +	}
        +
        +
        +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
        +	int *pclass, long omax)
        +	{
        +	int i,ret;
        +	long l;
        +	const unsigned char *p= *pp;
        +	int tag,xclass,inf;
        +	long max=omax;
        +
        +	if (!max) goto err;
        +	ret=(*p&V_ASN1_CONSTRUCTED);
        +	xclass=(*p&V_ASN1_PRIVATE);
        +	i= *p&V_ASN1_PRIMITIVE_TAG;
        +	if (i == V_ASN1_PRIMITIVE_TAG)
        +		{		/* high-tag */
        +		p++;
        +		if (--max == 0) goto err;
        +		l=0;
        +		while (*p&0x80)
        +			{
        +			l<<=7L;
        +			l|= *(p++)&0x7f;
        +			if (--max == 0) goto err;
        +			if (l > (INT_MAX >> 7L)) goto err;
        +			}
        +		l<<=7L;
        +		l|= *(p++)&0x7f;
        +		tag=(int)l;
        +		if (--max == 0) goto err;
        +		}
        +	else
        +		{ 
        +		tag=i;
        +		p++;
        +		if (--max == 0) goto err;
        +		}
        +	*ptag=tag;
        +	*pclass=xclass;
        +	if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
        +
        +#if 0
        +	fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n", 
        +		(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
        +		(int)(omax+ *pp));
        +
        +#endif
        +	if (*plength > (omax - (p - *pp)))
        +		{
        +		ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG);
        +		/* Set this so that even if things are not long enough
        +		 * the values are set correctly */
        +		ret|=0x80;
        +		}
        +	*pp=p;
        +	return(ret|inf);
        +err:
        +	ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_HEADER_TOO_LONG);
        +	return(0x80);
        +	}
        +
        +static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
        +	{
        +	const unsigned char *p= *pp;
        +	unsigned long ret=0;
        +	unsigned int i;
        +
        +	if (max-- < 1) return(0);
        +	if (*p == 0x80)
        +		{
        +		*inf=1;
        +		ret=0;
        +		p++;
        +		}
        +	else
        +		{
        +		*inf=0;
        +		i= *p&0x7f;
        +		if (*(p++) & 0x80)
        +			{
        +			if (i > sizeof(long))
        +				return 0;
        +			if (max-- == 0) return(0);
        +			while (i-- > 0)
        +				{
        +				ret<<=8L;
        +				ret|= *(p++);
        +				if (max-- == 0) return(0);
        +				}
        +			}
        +		else
        +			ret=i;
        +		}
        +	if (ret > LONG_MAX)
        +		return 0;
        +	*pp=p;
        +	*rl=(long)ret;
        +	return(1);
        +	}
        +
        +/* class 0 is constructed
        + * constructed == 2 for indefinite length constructed */
        +void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
        +	     int xclass)
        +	{
        +	unsigned char *p= *pp;
        +	int i, ttag;
        +
        +	i=(constructed)?V_ASN1_CONSTRUCTED:0;
        +	i|=(xclass&V_ASN1_PRIVATE);
        +	if (tag < 31)
        +		*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
        +	else
        +		{
        +		*(p++)=i|V_ASN1_PRIMITIVE_TAG;
        +		for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
        +		ttag = i;
        +		while(i-- > 0)
        +			{
        +			p[i] = tag & 0x7f;
        +			if(i != (ttag - 1)) p[i] |= 0x80;
        +			tag >>= 7;
        +			}
        +		p += ttag;
        +		}
        +	if (constructed == 2)
        +		*(p++)=0x80;
        +	else
        +		asn1_put_length(&p,length);
        +	*pp=p;
        +	}
        +
        +int ASN1_put_eoc(unsigned char **pp)
        +	{
        +	unsigned char *p = *pp;
        +	*p++ = 0;
        +	*p++ = 0;
        +	*pp = p;
        +	return 2;
        +	}
        +
        +static void asn1_put_length(unsigned char **pp, int length)
        +	{
        +	unsigned char *p= *pp;
        +	int i,l;
        +	if (length <= 127)
        +		*(p++)=(unsigned char)length;
        +	else
        +		{
        +		l=length;
        +		for (i=0; l > 0; i++)
        +			l>>=8;
        +		*(p++)=i|0x80;
        +		l=i;
        +		while (i-- > 0)
        +			{
        +			p[i]=length&0xff;
        +			length>>=8;
        +			}
        +		p+=l;
        +		}
        +	*pp=p;
        +	}
        +
        +int ASN1_object_size(int constructed, int length, int tag)
        +	{
        +	int ret;
        +
        +	ret=length;
        +	ret++;
        +	if (tag >= 31)
        +		{
        +		while (tag > 0)
        +			{
        +			tag>>=7;
        +			ret++;
        +			}
        +		}
        +	if (constructed == 2)
        +		return ret + 3;
        +	ret++;
        +	if (length > 127)
        +		{
        +		while (length > 0)
        +			{
        +			length>>=8;
        +			ret++;
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static int _asn1_Finish(ASN1_const_CTX *c)
        +	{
        +	if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
        +		{
        +		if (!ASN1_const_check_infinite_end(&c->p,c->slen))
        +			{
        +			c->error=ERR_R_MISSING_ASN1_EOS;
        +			return(0);
        +			}
        +		}
        +	if (	((c->slen != 0) && !(c->inf & 1)) ||
        +		((c->slen < 0) && (c->inf & 1)))
        +		{
        +		c->error=ERR_R_ASN1_LENGTH_MISMATCH;
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +int asn1_Finish(ASN1_CTX *c)
        +	{
        +	return _asn1_Finish((ASN1_const_CTX *)c);
        +	}
        +
        +int asn1_const_Finish(ASN1_const_CTX *c)
        +	{
        +	return _asn1_Finish(c);
        +	}
        +
        +int asn1_GetSequence(ASN1_const_CTX *c, long *length)
        +	{
        +	const unsigned char *q;
        +
        +	q=c->p;
        +	c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
        +		*length);
        +	if (c->inf & 0x80)
        +		{
        +		c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL;
        +		return(0);
        +		}
        +	if (c->tag != V_ASN1_SEQUENCE)
        +		{
        +		c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
        +		return(0);
        +		}
        +	(*length)-=(c->p-q);
        +	if (c->max && (*length < 0))
        +		{
        +		c->error=ERR_R_ASN1_LENGTH_MISMATCH;
        +		return(0);
        +		}
        +	if (c->inf == (1|V_ASN1_CONSTRUCTED))
        +		c->slen= *length+ *(c->pp)-c->p;
        +	c->eos=0;
        +	return(1);
        +	}
        +
        +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
        +	{
        +	if (str == NULL)
        +		return 0;
        +	dst->type = str->type;
        +	if (!ASN1_STRING_set(dst,str->data,str->length))
        +		return 0;
        +	dst->flags = str->flags;
        +	return 1;
        +	}
        +
        +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
        +	{
        +	ASN1_STRING *ret;
        +	if (!str)
        +		 return NULL;
        +	ret=ASN1_STRING_new();
        +	if (!ret)
        +		return NULL;
        +	if (!ASN1_STRING_copy(ret,str))
        +		{
        +		ASN1_STRING_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
        +	{
        +	unsigned char *c;
        +	const char *data=_data;
        +
        +	if (len < 0)
        +		{
        +		if (data == NULL)
        +			return(0);
        +		else
        +			len=strlen(data);
        +		}
        +	if ((str->length < len) || (str->data == NULL))
        +		{
        +		c=str->data;
        +		if (c == NULL)
        +			str->data=OPENSSL_malloc(len+1);
        +		else
        +			str->data=OPENSSL_realloc(c,len+1);
        +
        +		if (str->data == NULL)
        +			{
        +			ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE);
        +			str->data=c;
        +			return(0);
        +			}
        +		}
        +	str->length=len;
        +	if (data != NULL)
        +		{
        +		memcpy(str->data,data,len);
        +		/* an allowance for strings :-) */
        +		str->data[len]='\0';
        +		}
        +	return(1);
        +	}
        +
        +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
        +	{
        +	if (str->data)
        +		OPENSSL_free(str->data);
        +	str->data = data;
        +	str->length = len;
        +	}
        +
        +ASN1_STRING *ASN1_STRING_new(void)
        +	{
        +	return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
        +	}
        +
        +
        +ASN1_STRING *ASN1_STRING_type_new(int type)
        +	{
        +	ASN1_STRING *ret;
        +
        +	ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	ret->length=0;
        +	ret->type=type;
        +	ret->data=NULL;
        +	ret->flags=0;
        +	return(ret);
        +	}
        +
        +void ASN1_STRING_free(ASN1_STRING *a)
        +	{
        +	if (a == NULL) return;
        +	if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
        +		OPENSSL_free(a->data);
        +	OPENSSL_free(a);
        +	}
        +
        +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
        +	{
        +	int i;
        +
        +	i=(a->length-b->length);
        +	if (i == 0)
        +		{
        +		i=memcmp(a->data,b->data,a->length);
        +		if (i == 0)
        +			return(a->type-b->type);
        +		else
        +			return(i);
        +		}
        +	else
        +		return(i);
        +	}
        +
        +void asn1_add_error(const unsigned char *address, int offset)
        +	{
        +	char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
        +
        +	BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
        +	BIO_snprintf(buf2,sizeof buf2,"%d",offset);
        +	ERR_add_error_data(4,"address=",buf1," offset=",buf2);
        +	}
        +
        +int ASN1_STRING_length(const ASN1_STRING *x)
        +{ return M_ASN1_STRING_length(x); }
        +
        +void ASN1_STRING_length_set(ASN1_STRING *x, int len)
        +{ M_ASN1_STRING_length_set(x, len); return; }
        +
        +int ASN1_STRING_type(ASN1_STRING *x)
        +{ return M_ASN1_STRING_type(x); }
        +
        +unsigned char * ASN1_STRING_data(ASN1_STRING *x)
        +{ return M_ASN1_STRING_data(x); }
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1_locl.h b/vendor/openssl/openssl/crypto/asn1/asn1_locl.h
        new file mode 100644
        index 000000000..9fcf0d953
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1_locl.h
        @@ -0,0 +1,145 @@
        +/* asn1t.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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).
        + *
        + */
        +
        +/* Internal ASN1 structures and functions: not for application use */
        +
        +/* ASN1 print context structure */
        +
        +struct asn1_pctx_st
        +	{
        +	unsigned long flags;
        +	unsigned long nm_flags;
        +	unsigned long cert_flags;
        +	unsigned long oid_flags;
        +	unsigned long str_flags;
        +	} /* ASN1_PCTX */;
        +
        +/* ASN1 public key method structure */
        +
        +struct evp_pkey_asn1_method_st
        +	{
        +	int pkey_id;
        +	int pkey_base_id;
        +	unsigned long pkey_flags;
        +
        +	char *pem_str;
        +	char *info;
        +
        +	int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
        +	int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
        +	int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
        +	int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx);
        +
        +	int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
        +	int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
        +	int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx);
        +
        +	int (*pkey_size)(const EVP_PKEY *pk);
        +	int (*pkey_bits)(const EVP_PKEY *pk);
        +
        +	int (*param_decode)(EVP_PKEY *pkey,
        +				const unsigned char **pder, int derlen);
        +	int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
        +	int (*param_missing)(const EVP_PKEY *pk);
        +	int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
        +	int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
        +	int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx);
        +	int (*sig_print)(BIO *out,
        +			 const X509_ALGOR *sigalg, const ASN1_STRING *sig,
        +					 int indent, ASN1_PCTX *pctx);
        +
        +
        +	void (*pkey_free)(EVP_PKEY *pkey);
        +	int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
        +
        +	/* Legacy functions for old PEM */
        +
        +	int (*old_priv_decode)(EVP_PKEY *pkey,
        +				const unsigned char **pder, int derlen);
        +	int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
        +	/* Custom ASN1 signature verification */
        +	int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
        +				X509_ALGOR *a, ASN1_BIT_STRING *sig,
        +				EVP_PKEY *pkey);
        +	int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
        +				X509_ALGOR *alg1, X509_ALGOR *alg2, 
        +				ASN1_BIT_STRING *sig);
        +
        +	} /* EVP_PKEY_ASN1_METHOD */;
        +
        +/* Method to handle CRL access.
        + * In general a CRL could be very large (several Mb) and can consume large
        + * amounts of resources if stored in memory by multiple processes.
        + * This method allows general CRL operations to be redirected to more
        + * efficient callbacks: for example a CRL entry database.
        + */
        +
        +#define X509_CRL_METHOD_DYNAMIC		1
        +
        +struct x509_crl_method_st
        +	{
        +	int flags;
        +	int (*crl_init)(X509_CRL *crl);
        +	int (*crl_free)(X509_CRL *crl);
        +	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
        +				ASN1_INTEGER *ser, X509_NAME *issuer);
        +	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
        +	};
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1_mac.h b/vendor/openssl/openssl/crypto/asn1/asn1_mac.h
        new file mode 100644
        index 000000000..87bd0e9e1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1_mac.h
        @@ -0,0 +1,578 @@
        +/* crypto/asn1/asn1_mac.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_ASN1_MAC_H
        +#define HEADER_ASN1_MAC_H
        +
        +#include <openssl/asn1.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifndef ASN1_MAC_ERR_LIB
        +#define ASN1_MAC_ERR_LIB	ERR_LIB_ASN1
        +#endif 
        +
        +#define ASN1_MAC_H_err(f,r,line) \
        +	ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))
        +
        +#define M_ASN1_D2I_vars(a,type,func) \
        +	ASN1_const_CTX c; \
        +	type ret=NULL; \
        +	\
        +	c.pp=(const unsigned char **)pp; \
        +	c.q= *(const unsigned char **)pp; \
        +	c.error=ERR_R_NESTED_ASN1_ERROR; \
        +	if ((a == NULL) || ((*a) == NULL)) \
        +		{ if ((ret=(type)func()) == NULL) \
        +			{ c.line=__LINE__; goto err; } } \
        +	else	ret=(*a);
        +
        +#define M_ASN1_D2I_Init() \
        +	c.p= *(const unsigned char **)pp; \
        +	c.max=(length == 0)?0:(c.p+length);
        +
        +#define M_ASN1_D2I_Finish_2(a) \
        +	if (!asn1_const_Finish(&c)) \
        +		{ c.line=__LINE__; goto err; } \
        +	*(const unsigned char **)pp=c.p; \
        +	if (a != NULL) (*a)=ret; \
        +	return(ret);
        +
        +#define M_ASN1_D2I_Finish(a,func,e) \
        +	M_ASN1_D2I_Finish_2(a); \
        +err:\
        +	ASN1_MAC_H_err((e),c.error,c.line); \
        +	asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
        +	return(NULL)
        +
        +#define M_ASN1_D2I_start_sequence() \
        +	if (!asn1_GetSequence(&c,&length)) \
        +		{ c.line=__LINE__; goto err; }
        +/* Begin reading ASN1 without a surrounding sequence */
        +#define M_ASN1_D2I_begin() \
        +	c.slen = length;
        +
        +/* End reading ASN1 with no check on length */
        +#define M_ASN1_D2I_Finish_nolen(a, func, e) \
        +	*pp=c.p; \
        +	if (a != NULL) (*a)=ret; \
        +	return(ret); \
        +err:\
        +	ASN1_MAC_H_err((e),c.error,c.line); \
        +	asn1_add_error(*pp,(int)(c.q- *pp)); \
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
        +	return(NULL)
        +
        +#define M_ASN1_D2I_end_sequence() \
        +	(((c.inf&1) == 0)?(c.slen <= 0): \
        +		(c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
        +
        +/* Don't use this with d2i_ASN1_BOOLEAN() */
        +#define M_ASN1_D2I_get(b, func) \
        +	c.q=c.p; \
        +	if (func(&(b),&c.p,c.slen) == NULL) \
        +		{c.line=__LINE__; goto err; } \
        +	c.slen-=(c.p-c.q);
        +
        +/* Don't use this with d2i_ASN1_BOOLEAN() */
        +#define M_ASN1_D2I_get_x(type,b,func) \
        +	c.q=c.p; \
        +	if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
        +		{c.line=__LINE__; goto err; } \
        +	c.slen-=(c.p-c.q);
        +
        +/* use this instead () */
        +#define M_ASN1_D2I_get_int(b,func) \
        +	c.q=c.p; \
        +	if (func(&(b),&c.p,c.slen) < 0) \
        +		{c.line=__LINE__; goto err; } \
        +	c.slen-=(c.p-c.q);
        +
        +#define M_ASN1_D2I_get_opt(b,func,type) \
        +	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
        +		== (V_ASN1_UNIVERSAL|(type)))) \
        +		{ \
        +		M_ASN1_D2I_get(b,func); \
        +		}
        +
        +#define M_ASN1_D2I_get_int_opt(b,func,type) \
        +	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
        +		== (V_ASN1_UNIVERSAL|(type)))) \
        +		{ \
        +		M_ASN1_D2I_get_int(b,func); \
        +		}
        +
        +#define M_ASN1_D2I_get_imp(b,func, type) \
        +	M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
        +	c.q=c.p; \
        +	if (func(&(b),&c.p,c.slen) == NULL) \
        +		{c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
        +	c.slen-=(c.p-c.q);\
        +	M_ASN1_next_prev=_tmp;
        +
        +#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
        +	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
        +		(V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
        +		{ \
        +		unsigned char _tmp = M_ASN1_next; \
        +		M_ASN1_D2I_get_imp(b,func, type);\
        +		}
        +
        +#define M_ASN1_D2I_get_set(r,func,free_func) \
        +		M_ASN1_D2I_get_imp_set(r,func,free_func, \
        +			V_ASN1_SET,V_ASN1_UNIVERSAL);
        +
        +#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
        +		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
        +			V_ASN1_SET,V_ASN1_UNIVERSAL);
        +
        +#define M_ASN1_D2I_get_set_opt(r,func,free_func) \
        +	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
        +		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
        +		{ M_ASN1_D2I_get_set(r,func,free_func); }
        +
        +#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
        +	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
        +		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
        +		{ M_ASN1_D2I_get_set_type(type,r,func,free_func); }
        +
        +#define M_ASN1_I2D_len_SET_opt(a,f) \
        +	if ((a != NULL) && (sk_num(a) != 0)) \
        +		M_ASN1_I2D_len_SET(a,f);
        +
        +#define M_ASN1_I2D_put_SET_opt(a,f) \
        +	if ((a != NULL) && (sk_num(a) != 0)) \
        +		M_ASN1_I2D_put_SET(a,f);
        +
        +#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
        +	if ((a != NULL) && (sk_num(a) != 0)) \
        +		M_ASN1_I2D_put_SEQUENCE(a,f);
        +
        +#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
        +	if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +		M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
        +
        +#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
        +	if ((c.slen != 0) && \
        +		(M_ASN1_next == \
        +		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
        +		{ \
        +		M_ASN1_D2I_get_imp_set(b,func,free_func,\
        +			tag,V_ASN1_CONTEXT_SPECIFIC); \
        +		}
        +
        +#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
        +	if ((c.slen != 0) && \
        +		(M_ASN1_next == \
        +		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
        +		{ \
        +		M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
        +			tag,V_ASN1_CONTEXT_SPECIFIC); \
        +		}
        +
        +#define M_ASN1_D2I_get_seq(r,func,free_func) \
        +		M_ASN1_D2I_get_imp_set(r,func,free_func,\
        +			V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
        +
        +#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
        +		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
        +					    V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
        +
        +#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
        +	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
        +		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
        +		{ M_ASN1_D2I_get_seq(r,func,free_func); }
        +
        +#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
        +	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
        +		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
        +		{ M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
        +
        +#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
        +		M_ASN1_D2I_get_imp_set(r,func,free_func,\
        +			x,V_ASN1_CONTEXT_SPECIFIC);
        +
        +#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
        +		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
        +			x,V_ASN1_CONTEXT_SPECIFIC);
        +
        +#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
        +	c.q=c.p; \
        +	if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
        +		(void (*)())free_func,a,b) == NULL) \
        +		{ c.line=__LINE__; goto err; } \
        +	c.slen-=(c.p-c.q);
        +
        +#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
        +	c.q=c.p; \
        +	if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
        +				   free_func,a,b) == NULL) \
        +		{ c.line=__LINE__; goto err; } \
        +	c.slen-=(c.p-c.q);
        +
        +#define M_ASN1_D2I_get_set_strings(r,func,a,b) \
        +	c.q=c.p; \
        +	if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
        +		{ c.line=__LINE__; goto err; } \
        +	c.slen-=(c.p-c.q);
        +
        +#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
        +	if ((c.slen != 0L) && (M_ASN1_next == \
        +		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
        +		{ \
        +		int Tinf,Ttag,Tclass; \
        +		long Tlen; \
        +		\
        +		c.q=c.p; \
        +		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
        +		if (Tinf & 0x80) \
        +			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
        +			c.line=__LINE__; goto err; } \
        +		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
        +					Tlen = c.slen - (c.p - c.q) - 2; \
        +		if (func(&(r),&c.p,Tlen) == NULL) \
        +			{ c.line=__LINE__; goto err; } \
        +		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
        +			Tlen = c.slen - (c.p - c.q); \
        +			if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
        +				{ c.error=ERR_R_MISSING_ASN1_EOS; \
        +				c.line=__LINE__; goto err; } \
        +		}\
        +		c.slen-=(c.p-c.q); \
        +		}
        +
        +#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
        +	if ((c.slen != 0) && (M_ASN1_next == \
        +		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
        +		{ \
        +		int Tinf,Ttag,Tclass; \
        +		long Tlen; \
        +		\
        +		c.q=c.p; \
        +		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
        +		if (Tinf & 0x80) \
        +			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
        +			c.line=__LINE__; goto err; } \
        +		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
        +					Tlen = c.slen - (c.p - c.q) - 2; \
        +		if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
        +			(void (*)())free_func, \
        +			b,V_ASN1_UNIVERSAL) == NULL) \
        +			{ c.line=__LINE__; goto err; } \
        +		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
        +			Tlen = c.slen - (c.p - c.q); \
        +			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
        +				{ c.error=ERR_R_MISSING_ASN1_EOS; \
        +				c.line=__LINE__; goto err; } \
        +		}\
        +		c.slen-=(c.p-c.q); \
        +		}
        +
        +#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
        +	if ((c.slen != 0) && (M_ASN1_next == \
        +		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
        +		{ \
        +		int Tinf,Ttag,Tclass; \
        +		long Tlen; \
        +		\
        +		c.q=c.p; \
        +		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
        +		if (Tinf & 0x80) \
        +			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
        +			c.line=__LINE__; goto err; } \
        +		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
        +					Tlen = c.slen - (c.p - c.q) - 2; \
        +		if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
        +			free_func,b,V_ASN1_UNIVERSAL) == NULL) \
        +			{ c.line=__LINE__; goto err; } \
        +		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
        +			Tlen = c.slen - (c.p - c.q); \
        +			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
        +				{ c.error=ERR_R_MISSING_ASN1_EOS; \
        +				c.line=__LINE__; goto err; } \
        +		}\
        +		c.slen-=(c.p-c.q); \
        +		}
        +
        +/* New macros */
        +#define M_ASN1_New_Malloc(ret,type) \
        +	if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
        +		{ c.line=__LINE__; goto err2; }
        +
        +#define M_ASN1_New(arg,func) \
        +	if (((arg)=func()) == NULL) return(NULL)
        +
        +#define M_ASN1_New_Error(a) \
        +/*	err:	ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
        +		return(NULL);*/ \
        +	err2:	ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
        +		return(NULL)
        +
        +
        +/* BIG UGLY WARNING!  This is so damn ugly I wanna puke.  Unfortunately,
        +   some macros that use ASN1_const_CTX still insist on writing in the input
        +   stream.  ARGH!  ARGH!  ARGH!  Let's get rid of this macro package.
        +   Please?						-- Richard Levitte */
        +#define M_ASN1_next		(*((unsigned char *)(c.p)))
        +#define M_ASN1_next_prev	(*((unsigned char *)(c.q)))
        +
        +/*************************************************/
        +
        +#define M_ASN1_I2D_vars(a)	int r=0,ret=0; \
        +				unsigned char *p; \
        +				if (a == NULL) return(0)
        +
        +/* Length Macros */
        +#define M_ASN1_I2D_len(a,f)	ret+=f(a,NULL)
        +#define M_ASN1_I2D_len_IMP_opt(a,f)	if (a != NULL) M_ASN1_I2D_len(a,f)
        +
        +#define M_ASN1_I2D_len_SET(a,f) \
        +		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
        +
        +#define M_ASN1_I2D_len_SET_type(type,a,f) \
        +		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
        +					    V_ASN1_UNIVERSAL,IS_SET);
        +
        +#define M_ASN1_I2D_len_SEQUENCE(a,f) \
        +		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
        +				  IS_SEQUENCE);
        +
        +#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
        +		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
        +					    V_ASN1_UNIVERSAL,IS_SEQUENCE)
        +
        +#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			M_ASN1_I2D_len_SEQUENCE(a,f);
        +
        +#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +			M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
        +
        +#define M_ASN1_I2D_len_IMP_SET(a,f,x) \
        +		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
        +
        +#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
        +		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
        +					    V_ASN1_CONTEXT_SPECIFIC,IS_SET);
        +
        +#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
        +					  IS_SET);
        +
        +#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
        +					       V_ASN1_CONTEXT_SPECIFIC,IS_SET);
        +
        +#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
        +		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
        +				  IS_SEQUENCE);
        +
        +#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
        +					  IS_SEQUENCE);
        +
        +#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
        +						    V_ASN1_CONTEXT_SPECIFIC, \
        +						    IS_SEQUENCE);
        +
        +#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
        +		if (a != NULL)\
        +			{ \
        +			v=f(a,NULL); \
        +			ret+=ASN1_object_size(1,v,mtag); \
        +			}
        +
        +#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
        +		if ((a != NULL) && (sk_num(a) != 0))\
        +			{ \
        +			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
        +			ret+=ASN1_object_size(1,v,mtag); \
        +			}
        +
        +#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
        +		if ((a != NULL) && (sk_num(a) != 0))\
        +			{ \
        +			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
        +				       IS_SEQUENCE); \
        +			ret+=ASN1_object_size(1,v,mtag); \
        +			}
        +
        +#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0))\
        +			{ \
        +			v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
        +						 V_ASN1_UNIVERSAL, \
        +						 IS_SEQUENCE); \
        +			ret+=ASN1_object_size(1,v,mtag); \
        +			}
        +
        +/* Put Macros */
        +#define M_ASN1_I2D_put(a,f)	f(a,&p)
        +
        +#define M_ASN1_I2D_put_IMP_opt(a,f,t)	\
        +		if (a != NULL) \
        +			{ \
        +			unsigned char *q=p; \
        +			f(a,&p); \
        +			*q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
        +			}
        +
        +#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
        +			V_ASN1_UNIVERSAL,IS_SET)
        +#define M_ASN1_I2D_put_SET_type(type,a,f) \
        +     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
        +#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
        +			V_ASN1_CONTEXT_SPECIFIC,IS_SET)
        +#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
        +     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
        +#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
        +			V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
        +
        +#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
        +					     V_ASN1_UNIVERSAL,IS_SEQUENCE)
        +
        +#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
        +     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
        +			    IS_SEQUENCE)
        +
        +#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			M_ASN1_I2D_put_SEQUENCE(a,f);
        +
        +#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
        +				       IS_SET); }
        +
        +#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
        +						 V_ASN1_CONTEXT_SPECIFIC, \
        +						 IS_SET); }
        +
        +#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
        +				       IS_SEQUENCE); }
        +
        +#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
        +						 V_ASN1_CONTEXT_SPECIFIC, \
        +						 IS_SEQUENCE); }
        +
        +#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
        +		if (a != NULL) \
        +			{ \
        +			ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
        +			f(a,&p); \
        +			}
        +
        +#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			{ \
        +			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
        +			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
        +			}
        +
        +#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
        +		if ((a != NULL) && (sk_num(a) != 0)) \
        +			{ \
        +			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
        +			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
        +			}
        +
        +#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
        +		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
        +			{ \
        +			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
        +			i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
        +					       IS_SEQUENCE); \
        +			}
        +
        +#define M_ASN1_I2D_seq_total() \
        +		r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
        +		if (pp == NULL) return(r); \
        +		p= *pp; \
        +		ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
        +
        +#define M_ASN1_I2D_INF_seq_start(tag,ctx) \
        +		*(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
        +		*(p++)=0x80
        +
        +#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
        +
        +#define M_ASN1_I2D_finish()	*pp=p; \
        +				return(r);
        +
        +int asn1_GetSequence(ASN1_const_CTX *c, long *length);
        +void asn1_add_error(const unsigned char *address,int offset);
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1_par.c b/vendor/openssl/openssl/crypto/asn1/asn1_par.c
        new file mode 100644
        index 000000000..aaca69aeb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1_par.c
        @@ -0,0 +1,437 @@
        +/* crypto/asn1/asn1_par.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/asn1.h>
        +
        +static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
        +	int indent);
        +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
        +	int offset, int depth, int indent, int dump);
        +static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
        +	     int indent)
        +	{
        +	static const char fmt[]="%-18s";
        +	char str[128];
        +	const char *p;
        +
        +	if (constructed & V_ASN1_CONSTRUCTED)
        +		p="cons: ";
        +	else
        +		p="prim: ";
        +	if (BIO_write(bp,p,6) < 6) goto err;
        +	BIO_indent(bp,indent,128);
        +
        +	p=str;
        +	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
        +		BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
        +	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
        +		BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
        +	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
        +		BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
        +	else if (tag > 30)
        +		BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
        +	else
        +		p = ASN1_tag2str(tag);
        +
        +	if (BIO_printf(bp,fmt,p) <= 0)
        +		goto err;
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
        +	{
        +	return(asn1_parse2(bp,&pp,len,0,0,indent,0));
        +	}
        +
        +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
        +	{
        +	return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
        +	}
        +
        +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
        +	     int depth, int indent, int dump)
        +	{
        +	const unsigned char *p,*ep,*tot,*op,*opp;
        +	long len;
        +	int tag,xclass,ret=0;
        +	int nl,hl,j,r;
        +	ASN1_OBJECT *o=NULL;
        +	ASN1_OCTET_STRING *os=NULL;
        +	/* ASN1_BMPSTRING *bmp=NULL;*/
        +	int dump_indent;
        +
        +#if 0
        +	dump_indent = indent;
        +#else
        +	dump_indent = 6;	/* Because we know BIO_dump_indent() */
        +#endif
        +	p= *pp;
        +	tot=p+length;
        +	op=p-1;
        +	while ((p < tot) && (op < p))
        +		{
        +		op=p;
        +		j=ASN1_get_object(&p,&len,&tag,&xclass,length);
        +#ifdef LINT
        +		j=j;
        +#endif
        +		if (j & 0x80)
        +			{
        +			if (BIO_write(bp,"Error in encoding\n",18) <= 0)
        +				goto end;
        +			ret=0;
        +			goto end;
        +			}
        +		hl=(p-op);
        +		length-=hl;
        +		/* if j == 0x21 it is a constructed indefinite length object */
        +		if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
        +			<= 0) goto end;
        +
        +		if (j != (V_ASN1_CONSTRUCTED | 1))
        +			{
        +			if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
        +				depth,(long)hl,len) <= 0)
        +				goto end;
        +			}
        +		else
        +			{
        +			if (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
        +				depth,(long)hl) <= 0)
        +				goto end;
        +			}
        +		if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
        +			goto end;
        +		if (j & V_ASN1_CONSTRUCTED)
        +			{
        +			ep=p+len;
        +			if (BIO_write(bp,"\n",1) <= 0) goto end;
        +			if (len > length)
        +				{
        +				BIO_printf(bp,
        +					"length is greater than %ld\n",length);
        +				ret=0;
        +				goto end;
        +				}
        +			if ((j == 0x21) && (len == 0))
        +				{
        +				for (;;)
        +					{
        +					r=asn1_parse2(bp,&p,(long)(tot-p),
        +						offset+(p - *pp),depth+1,
        +						indent,dump);
        +					if (r == 0) { ret=0; goto end; }
        +					if ((r == 2) || (p >= tot)) break;
        +					}
        +				}
        +			else
        +				while (p < ep)
        +					{
        +					r=asn1_parse2(bp,&p,(long)len,
        +						offset+(p - *pp),depth+1,
        +						indent,dump);
        +					if (r == 0) { ret=0; goto end; }
        +					}
        +			}
        +		else if (xclass != 0)
        +			{
        +			p+=len;
        +			if (BIO_write(bp,"\n",1) <= 0) goto end;
        +			}
        +		else
        +			{
        +			nl=0;
        +			if (	(tag == V_ASN1_PRINTABLESTRING) ||
        +				(tag == V_ASN1_T61STRING) ||
        +				(tag == V_ASN1_IA5STRING) ||
        +				(tag == V_ASN1_VISIBLESTRING) ||
        +				(tag == V_ASN1_NUMERICSTRING) ||
        +				(tag == V_ASN1_UTF8STRING) ||
        +				(tag == V_ASN1_UTCTIME) ||
        +				(tag == V_ASN1_GENERALIZEDTIME))
        +				{
        +				if (BIO_write(bp,":",1) <= 0) goto end;
        +				if ((len > 0) &&
        +					BIO_write(bp,(const char *)p,(int)len)
        +					!= (int)len)
        +					goto end;
        +				}
        +			else if (tag == V_ASN1_OBJECT)
        +				{
        +				opp=op;
        +				if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
        +					{
        +					if (BIO_write(bp,":",1) <= 0) goto end;
        +					i2a_ASN1_OBJECT(bp,o);
        +					}
        +				else
        +					{
        +					if (BIO_write(bp,":BAD OBJECT",11) <= 0)
        +						goto end;
        +					}
        +				}
        +			else if (tag == V_ASN1_BOOLEAN)
        +				{
        +				int ii;
        +
        +				opp=op;
        +				ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
        +				if (ii < 0)
        +					{
        +					if (BIO_write(bp,"Bad boolean\n",12) <= 0)
        +						goto end;
        +					}
        +				BIO_printf(bp,":%d",ii);
        +				}
        +			else if (tag == V_ASN1_BMPSTRING)
        +				{
        +				/* do the BMP thang */
        +				}
        +			else if (tag == V_ASN1_OCTET_STRING)
        +				{
        +				int i,printable=1;
        +
        +				opp=op;
        +				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
        +				if (os != NULL && os->length > 0)
        +					{
        +					opp = os->data;
        +					/* testing whether the octet string is
        +					 * printable */
        +					for (i=0; i<os->length; i++)
        +						{
        +						if ((	(opp[i] < ' ') &&
        +							(opp[i] != '\n') &&
        +							(opp[i] != '\r') &&
        +							(opp[i] != '\t')) ||
        +							(opp[i] > '~'))
        +							{
        +							printable=0;
        +							break;
        +							}
        +						}
        +					if (printable)
        +					/* printable string */
        +						{
        +						if (BIO_write(bp,":",1) <= 0)
        +							goto end;
        +						if (BIO_write(bp,(const char *)opp,
        +							os->length) <= 0)
        +							goto end;
        +						}
        +					else if (!dump)
        +					/* not printable => print octet string
        +					 * as hex dump */
        +						{
        +						if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
        +							goto end;
        +						for (i=0; i<os->length; i++)
        +							{
        +							if (BIO_printf(bp,"%02X"
        +								, opp[i]) <= 0)
        +								goto end;
        +							}
        +						}
        +					else
        +					/* print the normal dump */
        +						{
        +						if (!nl) 
        +							{
        +							if (BIO_write(bp,"\n",1) <= 0)
        +								goto end;
        +							}
        +						if (BIO_dump_indent(bp,
        +							(const char *)opp,
        +							((dump == -1 || dump > 
        +							os->length)?os->length:dump),
        +							dump_indent) <= 0)
        +							goto end;
        +						nl=1;
        +						}
        +					}
        +				if (os != NULL)
        +					{
        +					M_ASN1_OCTET_STRING_free(os);
        +					os=NULL;
        +					}
        +				}
        +			else if (tag == V_ASN1_INTEGER)
        +				{
        +				ASN1_INTEGER *bs;
        +				int i;
        +
        +				opp=op;
        +				bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
        +				if (bs != NULL)
        +					{
        +					if (BIO_write(bp,":",1) <= 0) goto end;
        +					if (bs->type == V_ASN1_NEG_INTEGER)
        +						if (BIO_write(bp,"-",1) <= 0)
        +							goto end;
        +					for (i=0; i<bs->length; i++)
        +						{
        +						if (BIO_printf(bp,"%02X",
        +							bs->data[i]) <= 0)
        +							goto end;
        +						}
        +					if (bs->length == 0)
        +						{
        +						if (BIO_write(bp,"00",2) <= 0)
        +							goto end;
        +						}
        +					}
        +				else
        +					{
        +					if (BIO_write(bp,"BAD INTEGER",11) <= 0)
        +						goto end;
        +					}
        +				M_ASN1_INTEGER_free(bs);
        +				}
        +			else if (tag == V_ASN1_ENUMERATED)
        +				{
        +				ASN1_ENUMERATED *bs;
        +				int i;
        +
        +				opp=op;
        +				bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
        +				if (bs != NULL)
        +					{
        +					if (BIO_write(bp,":",1) <= 0) goto end;
        +					if (bs->type == V_ASN1_NEG_ENUMERATED)
        +						if (BIO_write(bp,"-",1) <= 0)
        +							goto end;
        +					for (i=0; i<bs->length; i++)
        +						{
        +						if (BIO_printf(bp,"%02X",
        +							bs->data[i]) <= 0)
        +							goto end;
        +						}
        +					if (bs->length == 0)
        +						{
        +						if (BIO_write(bp,"00",2) <= 0)
        +							goto end;
        +						}
        +					}
        +				else
        +					{
        +					if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
        +						goto end;
        +					}
        +				M_ASN1_ENUMERATED_free(bs);
        +				}
        +			else if (len > 0 && dump)
        +				{
        +				if (!nl) 
        +					{
        +					if (BIO_write(bp,"\n",1) <= 0)
        +						goto end;
        +					}
        +				if (BIO_dump_indent(bp,(const char *)p,
        +					((dump == -1 || dump > len)?len:dump),
        +					dump_indent) <= 0)
        +					goto end;
        +				nl=1;
        +				}
        +
        +			if (!nl) 
        +				{
        +				if (BIO_write(bp,"\n",1) <= 0) goto end;
        +				}
        +			p+=len;
        +			if ((tag == V_ASN1_EOC) && (xclass == 0))
        +				{
        +				ret=2; /* End of sequence */
        +				goto end;
        +				}
        +			}
        +		length-=len;
        +		}
        +	ret=1;
        +end:
        +	if (o != NULL) ASN1_OBJECT_free(o);
        +	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
        +	*pp=p;
        +	return(ret);
        +	}
        +
        +const char *ASN1_tag2str(int tag)
        +{
        +	static const char * const tag2str[] = {
        +	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
        +	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
        +	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
        +	"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", 		    /* 15-17 */
        +	"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
        +	"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
        +	"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
        +	"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"		    /* 28-30 */
        +	};
        +
        +	if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
        +							tag &= ~0x100;
        +
        +	if(tag < 0 || tag > 30) return "(unknown)";
        +	return tag2str[tag];
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn1t.h b/vendor/openssl/openssl/crypto/asn1/asn1t.h
        new file mode 100644
        index 000000000..d230e4bf7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn1t.h
        @@ -0,0 +1,960 @@
        +/* asn1t.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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_ASN1T_H
        +#define HEADER_ASN1T_H
        +
        +#include <stddef.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/asn1.h>
        +
        +#ifdef OPENSSL_BUILD_SHLIBCRYPTO
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +/* ASN1 template defines, structures and functions */
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +
        +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
        +#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
        +
        +
        +/* Macros for start and end of ASN1_ITEM definition */
        +
        +#define ASN1_ITEM_start(itname) \
        +	OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
        +
        +#define ASN1_ITEM_end(itname) \
        +		};
        +
        +#else
        +
        +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
        +#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
        +
        +
        +/* Macros for start and end of ASN1_ITEM definition */
        +
        +#define ASN1_ITEM_start(itname) \
        +	const ASN1_ITEM * itname##_it(void) \
        +	{ \
        +		static const ASN1_ITEM local_it = { 
        +
        +#define ASN1_ITEM_end(itname) \
        +		}; \
        +	return &local_it; \
        +	}
        +
        +#endif
        +
        +
        +/* Macros to aid ASN1 template writing */
        +
        +#define ASN1_ITEM_TEMPLATE(tname) \
        +	static const ASN1_TEMPLATE tname##_item_tt 
        +
        +#define ASN1_ITEM_TEMPLATE_END(tname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_PRIMITIVE,\
        +		-1,\
        +		&tname##_item_tt,\
        +		0,\
        +		NULL,\
        +		0,\
        +		#tname \
        +	ASN1_ITEM_end(tname)
        +
        +
        +/* This is a ASN1 type which just embeds a template */
        + 
        +/* This pair helps declare a SEQUENCE. We can do:
        + *
        + * 	ASN1_SEQUENCE(stname) = {
        + * 		... SEQUENCE components ...
        + * 	} ASN1_SEQUENCE_END(stname)
        + *
        + * 	This will produce an ASN1_ITEM called stname_it
        + *	for a structure called stname.
        + *
        + * 	If you want the same structure but a different
        + *	name then use:
        + *
        + * 	ASN1_SEQUENCE(itname) = {
        + * 		... SEQUENCE components ...
        + * 	} ASN1_SEQUENCE_END_name(stname, itname)
        + *
        + *	This will create an item called itname_it using
        + *	a structure called stname.
        + */
        +
        +#define ASN1_SEQUENCE(tname) \
        +	static const ASN1_TEMPLATE tname##_seq_tt[] 
        +
        +#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
        +
        +#define ASN1_SEQUENCE_END_name(stname, tname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_SEQUENCE,\
        +		V_ASN1_SEQUENCE,\
        +		tname##_seq_tt,\
        +		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
        +		NULL,\
        +		sizeof(stname),\
        +		#stname \
        +	ASN1_ITEM_end(tname)
        +
        +#define ASN1_NDEF_SEQUENCE(tname) \
        +	ASN1_SEQUENCE(tname)
        +
        +#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
        +	ASN1_SEQUENCE_cb(tname, cb)
        +
        +#define ASN1_SEQUENCE_cb(tname, cb) \
        +	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
        +	ASN1_SEQUENCE(tname)
        +
        +#define ASN1_BROKEN_SEQUENCE(tname) \
        +	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
        +	ASN1_SEQUENCE(tname)
        +
        +#define ASN1_SEQUENCE_ref(tname, cb, lck) \
        +	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
        +	ASN1_SEQUENCE(tname)
        +
        +#define ASN1_SEQUENCE_enc(tname, enc, cb) \
        +	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
        +	ASN1_SEQUENCE(tname)
        +
        +#define ASN1_NDEF_SEQUENCE_END(tname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_NDEF_SEQUENCE,\
        +		V_ASN1_SEQUENCE,\
        +		tname##_seq_tt,\
        +		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
        +		NULL,\
        +		sizeof(tname),\
        +		#tname \
        +	ASN1_ITEM_end(tname)
        +
        +#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
        +
        +#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
        +
        +#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
        +
        +#define ASN1_SEQUENCE_END_ref(stname, tname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_SEQUENCE,\
        +		V_ASN1_SEQUENCE,\
        +		tname##_seq_tt,\
        +		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
        +		&tname##_aux,\
        +		sizeof(stname),\
        +		#stname \
        +	ASN1_ITEM_end(tname)
        +
        +#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_NDEF_SEQUENCE,\
        +		V_ASN1_SEQUENCE,\
        +		tname##_seq_tt,\
        +		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
        +		&tname##_aux,\
        +		sizeof(stname),\
        +		#stname \
        +	ASN1_ITEM_end(tname)
        +
        +
        +/* This pair helps declare a CHOICE type. We can do:
        + *
        + * 	ASN1_CHOICE(chname) = {
        + * 		... CHOICE options ...
        + * 	ASN1_CHOICE_END(chname)
        + *
        + * 	This will produce an ASN1_ITEM called chname_it
        + *	for a structure called chname. The structure
        + *	definition must look like this:
        + *	typedef struct {
        + *		int type;
        + *		union {
        + *			ASN1_SOMETHING *opt1;
        + *			ASN1_SOMEOTHER *opt2;
        + *		} value;
        + *	} chname;
        + *	
        + *	the name of the selector must be 'type'.
        + * 	to use an alternative selector name use the
        + *      ASN1_CHOICE_END_selector() version.
        + */
        +
        +#define ASN1_CHOICE(tname) \
        +	static const ASN1_TEMPLATE tname##_ch_tt[] 
        +
        +#define ASN1_CHOICE_cb(tname, cb) \
        +	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
        +	ASN1_CHOICE(tname)
        +
        +#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
        +
        +#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
        +
        +#define ASN1_CHOICE_END_selector(stname, tname, selname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_CHOICE,\
        +		offsetof(stname,selname) ,\
        +		tname##_ch_tt,\
        +		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
        +		NULL,\
        +		sizeof(stname),\
        +		#stname \
        +	ASN1_ITEM_end(tname)
        +
        +#define ASN1_CHOICE_END_cb(stname, tname, selname) \
        +	;\
        +	ASN1_ITEM_start(tname) \
        +		ASN1_ITYPE_CHOICE,\
        +		offsetof(stname,selname) ,\
        +		tname##_ch_tt,\
        +		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
        +		&tname##_aux,\
        +		sizeof(stname),\
        +		#stname \
        +	ASN1_ITEM_end(tname)
        +
        +/* This helps with the template wrapper form of ASN1_ITEM */
        +
        +#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
        +	(flags), (tag), 0,\
        +	#name, ASN1_ITEM_ref(type) }
        +
        +/* These help with SEQUENCE or CHOICE components */
        +
        +/* used to declare other types */
        +
        +#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
        +	(flags), (tag), offsetof(stname, field),\
        +	#field, ASN1_ITEM_ref(type) }
        +
        +/* used when the structure is combined with the parent */
        +
        +#define ASN1_EX_COMBINE(flags, tag, type) { \
        +	(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
        +
        +/* implicit and explicit helper macros */
        +
        +#define ASN1_IMP_EX(stname, field, type, tag, ex) \
        +		ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
        +
        +#define ASN1_EXP_EX(stname, field, type, tag, ex) \
        +		ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
        +
        +/* Any defined by macros: the field used is in the table itself */
        +
        +#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
        +#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
        +#else
        +#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
        +#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
        +#endif
        +/* Plain simple type */
        +#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
        +
        +/* OPTIONAL simple type */
        +#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
        +
        +/* IMPLICIT tagged simple type */
        +#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
        +
        +/* IMPLICIT tagged OPTIONAL simple type */
        +#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
        +
        +/* Same as above but EXPLICIT */
        +
        +#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
        +#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
        +
        +/* SEQUENCE OF type */
        +#define ASN1_SEQUENCE_OF(stname, field, type) \
        +		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
        +
        +/* OPTIONAL SEQUENCE OF */
        +#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
        +		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
        +
        +/* Same as above but for SET OF */
        +
        +#define ASN1_SET_OF(stname, field, type) \
        +		ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
        +
        +#define ASN1_SET_OF_OPT(stname, field, type) \
        +		ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
        +
        +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
        +
        +#define ASN1_IMP_SET_OF(stname, field, type, tag) \
        +			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
        +
        +#define ASN1_EXP_SET_OF(stname, field, type, tag) \
        +			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
        +
        +#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
        +			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
        +
        +#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
        +			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
        +
        +#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
        +			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
        +
        +#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
        +			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
        +
        +#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
        +			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
        +
        +#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
        +			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
        +
        +/* EXPLICIT using indefinite length constructed form */
        +#define ASN1_NDEF_EXP(stname, field, type, tag) \
        +			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
        +
        +/* EXPLICIT OPTIONAL using indefinite length constructed form */
        +#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
        +			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
        +
        +/* Macros for the ASN1_ADB structure */
        +
        +#define ASN1_ADB(name) \
        +	static const ASN1_ADB_TABLE name##_adbtbl[] 
        +
        +#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +
        +#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
        +	;\
        +	static const ASN1_ADB name##_adb = {\
        +		flags,\
        +		offsetof(name, field),\
        +		app_table,\
        +		name##_adbtbl,\
        +		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
        +		def,\
        +		none\
        +	}
        +
        +#else
        +
        +#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
        +	;\
        +	static const ASN1_ITEM *name##_adb(void) \
        +	{ \
        +	static const ASN1_ADB internal_adb = \
        +		{\
        +		flags,\
        +		offsetof(name, field),\
        +		app_table,\
        +		name##_adbtbl,\
        +		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
        +		def,\
        +		none\
        +		}; \
        +		return (const ASN1_ITEM *) &internal_adb; \
        +	} \
        +	void dummy_function(void)
        +
        +#endif
        +
        +#define ADB_ENTRY(val, template) {val, template}
        +
        +#define ASN1_ADB_TEMPLATE(name) \
        +	static const ASN1_TEMPLATE name##_tt 
        +
        +/* This is the ASN1 template structure that defines
        + * a wrapper round the actual type. It determines the
        + * actual position of the field in the value structure,
        + * various flags such as OPTIONAL and the field name.
        + */
        +
        +struct ASN1_TEMPLATE_st {
        +unsigned long flags;		/* Various flags */
        +long tag;			/* tag, not used if no tagging */
        +unsigned long offset;		/* Offset of this field in structure */
        +#ifndef NO_ASN1_FIELD_NAMES
        +const char *field_name;		/* Field name */
        +#endif
        +ASN1_ITEM_EXP *item;		/* Relevant ASN1_ITEM or ASN1_ADB */
        +};
        +
        +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
        +
        +#define ASN1_TEMPLATE_item(t) (t->item_ptr)
        +#define ASN1_TEMPLATE_adb(t) (t->item_ptr)
        +
        +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
        +typedef struct ASN1_ADB_st ASN1_ADB;
        +
        +struct ASN1_ADB_st {
        +	unsigned long flags;	/* Various flags */
        +	unsigned long offset;	/* Offset of selector field */
        +	STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
        +	const ASN1_ADB_TABLE *tbl;	/* Table of possible types */
        +	long tblcount;		/* Number of entries in tbl */
        +	const ASN1_TEMPLATE *default_tt;  /* Type to use if no match */
        +	const ASN1_TEMPLATE *null_tt;  /* Type to use if selector is NULL */
        +};
        +
        +struct ASN1_ADB_TABLE_st {
        +	long value;		/* NID for an object or value for an int */
        +	const ASN1_TEMPLATE tt;		/* item for this value */
        +};
        +
        +/* template flags */
        +
        +/* Field is optional */
        +#define ASN1_TFLG_OPTIONAL	(0x1)
        +
        +/* Field is a SET OF */
        +#define ASN1_TFLG_SET_OF	(0x1 << 1)
        +
        +/* Field is a SEQUENCE OF */
        +#define ASN1_TFLG_SEQUENCE_OF	(0x2 << 1)
        +
        +/* Special case: this refers to a SET OF that
        + * will be sorted into DER order when encoded *and*
        + * the corresponding STACK will be modified to match
        + * the new order.
        + */
        +#define ASN1_TFLG_SET_ORDER	(0x3 << 1)
        +
        +/* Mask for SET OF or SEQUENCE OF */
        +#define ASN1_TFLG_SK_MASK	(0x3 << 1)
        +
        +/* These flags mean the tag should be taken from the
        + * tag field. If EXPLICIT then the underlying type
        + * is used for the inner tag.
        + */
        +
        +/* IMPLICIT tagging */
        +#define ASN1_TFLG_IMPTAG	(0x1 << 3)
        +
        +
        +/* EXPLICIT tagging, inner tag from underlying type */
        +#define ASN1_TFLG_EXPTAG	(0x2 << 3)
        +
        +#define ASN1_TFLG_TAG_MASK	(0x3 << 3)
        +
        +/* context specific IMPLICIT */
        +#define ASN1_TFLG_IMPLICIT	ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
        +
        +/* context specific EXPLICIT */
        +#define ASN1_TFLG_EXPLICIT	ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
        +
        +/* If tagging is in force these determine the
        + * type of tag to use. Otherwise the tag is
        + * determined by the underlying type. These 
        + * values reflect the actual octet format.
        + */
        +
        +/* Universal tag */ 
        +#define ASN1_TFLG_UNIVERSAL	(0x0<<6)
        +/* Application tag */ 
        +#define ASN1_TFLG_APPLICATION	(0x1<<6)
        +/* Context specific tag */ 
        +#define ASN1_TFLG_CONTEXT	(0x2<<6)
        +/* Private tag */ 
        +#define ASN1_TFLG_PRIVATE	(0x3<<6)
        +
        +#define ASN1_TFLG_TAG_CLASS	(0x3<<6)
        +
        +/* These are for ANY DEFINED BY type. In this case
        + * the 'item' field points to an ASN1_ADB structure
        + * which contains a table of values to decode the
        + * relevant type
        + */
        +
        +#define ASN1_TFLG_ADB_MASK	(0x3<<8)
        +
        +#define ASN1_TFLG_ADB_OID	(0x1<<8)
        +
        +#define ASN1_TFLG_ADB_INT	(0x1<<9)
        +
        +/* This flag means a parent structure is passed
        + * instead of the field: this is useful is a
        + * SEQUENCE is being combined with a CHOICE for
        + * example. Since this means the structure and
        + * item name will differ we need to use the
        + * ASN1_CHOICE_END_name() macro for example.
        + */
        +
        +#define ASN1_TFLG_COMBINE	(0x1<<10)
        +
        +/* This flag when present in a SEQUENCE OF, SET OF
        + * or EXPLICIT causes indefinite length constructed
        + * encoding to be used if required.
        + */
        +
        +#define ASN1_TFLG_NDEF		(0x1<<11)
        +
        +/* This is the actual ASN1 item itself */
        +
        +struct ASN1_ITEM_st {
        +char itype;			/* The item type, primitive, SEQUENCE, CHOICE or extern */
        +long utype;			/* underlying type */
        +const ASN1_TEMPLATE *templates;	/* If SEQUENCE or CHOICE this contains the contents */
        +long tcount;			/* Number of templates if SEQUENCE or CHOICE */
        +const void *funcs;		/* functions that handle this type */
        +long size;			/* Structure size (usually)*/
        +#ifndef NO_ASN1_FIELD_NAMES
        +const char *sname;		/* Structure name */
        +#endif
        +};
        +
        +/* These are values for the itype field and
        + * determine how the type is interpreted.
        + *
        + * For PRIMITIVE types the underlying type
        + * determines the behaviour if items is NULL.
        + *
        + * Otherwise templates must contain a single 
        + * template and the type is treated in the
        + * same way as the type specified in the template.
        + *
        + * For SEQUENCE types the templates field points
        + * to the members, the size field is the
        + * structure size.
        + *
        + * For CHOICE types the templates field points
        + * to each possible member (typically a union)
        + * and the 'size' field is the offset of the
        + * selector.
        + *
        + * The 'funcs' field is used for application
        + * specific functions. 
        + *
        + * For COMPAT types the funcs field gives a
        + * set of functions that handle this type, this
        + * supports the old d2i, i2d convention.
        + *
        + * The EXTERN type uses a new style d2i/i2d.
        + * The new style should be used where possible
        + * because it avoids things like the d2i IMPLICIT
        + * hack.
        + *
        + * MSTRING is a multiple string type, it is used
        + * for a CHOICE of character strings where the
        + * actual strings all occupy an ASN1_STRING
        + * structure. In this case the 'utype' field
        + * has a special meaning, it is used as a mask
        + * of acceptable types using the B_ASN1 constants.
        + *
        + * NDEF_SEQUENCE is the same as SEQUENCE except
        + * that it will use indefinite length constructed
        + * encoding if requested.
        + *
        + */
        +
        +#define ASN1_ITYPE_PRIMITIVE		0x0
        +
        +#define ASN1_ITYPE_SEQUENCE		0x1
        +
        +#define ASN1_ITYPE_CHOICE		0x2
        +
        +#define ASN1_ITYPE_COMPAT		0x3
        +
        +#define ASN1_ITYPE_EXTERN		0x4
        +
        +#define ASN1_ITYPE_MSTRING		0x5
        +
        +#define ASN1_ITYPE_NDEF_SEQUENCE	0x6
        +
        +/* Cache for ASN1 tag and length, so we
        + * don't keep re-reading it for things
        + * like CHOICE
        + */
        +
        +struct ASN1_TLC_st{
        +	char valid;	/* Values below are valid */
        +	int ret;	/* return value */
        +	long plen;	/* length */
        +	int ptag;	/* class value */
        +	int pclass;	/* class value */
        +	int hdrlen;	/* header length */
        +};
        +
        +/* Typedefs for ASN1 function pointers */
        +
        +typedef ASN1_VALUE * ASN1_new_func(void);
        +typedef void ASN1_free_func(ASN1_VALUE *a);
        +typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
        +typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
        +
        +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
        +					int tag, int aclass, char opt, ASN1_TLC *ctx);
        +
        +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
        +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +
        +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, 
        +						int indent, const char *fname, 
        +						const ASN1_PCTX *pctx);
        +
        +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
        +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
        +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
        +
        +typedef struct ASN1_COMPAT_FUNCS_st {
        +	ASN1_new_func *asn1_new;
        +	ASN1_free_func *asn1_free;
        +	ASN1_d2i_func *asn1_d2i;
        +	ASN1_i2d_func *asn1_i2d;
        +} ASN1_COMPAT_FUNCS;
        +
        +typedef struct ASN1_EXTERN_FUNCS_st {
        +	void *app_data;
        +	ASN1_ex_new_func *asn1_ex_new;
        +	ASN1_ex_free_func *asn1_ex_free;
        +	ASN1_ex_free_func *asn1_ex_clear;
        +	ASN1_ex_d2i *asn1_ex_d2i;
        +	ASN1_ex_i2d *asn1_ex_i2d;
        +	ASN1_ex_print_func *asn1_ex_print;
        +} ASN1_EXTERN_FUNCS;
        +
        +typedef struct ASN1_PRIMITIVE_FUNCS_st {
        +	void *app_data;
        +	unsigned long flags;
        +	ASN1_ex_new_func *prim_new;
        +	ASN1_ex_free_func *prim_free;
        +	ASN1_ex_free_func *prim_clear;
        +	ASN1_primitive_c2i *prim_c2i;
        +	ASN1_primitive_i2c *prim_i2c;
        +	ASN1_primitive_print *prim_print;
        +} ASN1_PRIMITIVE_FUNCS;
        +
        +/* This is the ASN1_AUX structure: it handles various
        + * miscellaneous requirements. For example the use of
        + * reference counts and an informational callback.
        + *
        + * The "informational callback" is called at various
        + * points during the ASN1 encoding and decoding. It can
        + * be used to provide minor customisation of the structures
        + * used. This is most useful where the supplied routines
        + * *almost* do the right thing but need some extra help
        + * at a few points. If the callback returns zero then
        + * it is assumed a fatal error has occurred and the 
        + * main operation should be abandoned.
        + *
        + * If major changes in the default behaviour are required
        + * then an external type is more appropriate.
        + */
        +
        +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
        +				void *exarg);
        +
        +typedef struct ASN1_AUX_st {
        +	void *app_data;
        +	int flags;
        +	int ref_offset;		/* Offset of reference value */
        +	int ref_lock;		/* Lock type to use */
        +	ASN1_aux_cb *asn1_cb;
        +	int enc_offset;		/* Offset of ASN1_ENCODING structure */
        +} ASN1_AUX;
        +
        +/* For print related callbacks exarg points to this structure */
        +typedef struct ASN1_PRINT_ARG_st {
        +	BIO *out;
        +	int indent;
        +	const ASN1_PCTX *pctx;
        +} ASN1_PRINT_ARG;
        +
        +/* For streaming related callbacks exarg points to this structure */
        +typedef struct ASN1_STREAM_ARG_st {
        +	/* BIO to stream through */
        +	BIO *out;
        +	/* BIO with filters appended */
        +	BIO *ndef_bio;
        +	/* Streaming I/O boundary */
        +	unsigned char **boundary;
        +} ASN1_STREAM_ARG;
        +
        +/* Flags in ASN1_AUX */
        +
        +/* Use a reference count */
        +#define ASN1_AFLG_REFCOUNT	1
        +/* Save the encoding of structure (useful for signatures) */
        +#define ASN1_AFLG_ENCODING	2
        +/* The Sequence length is invalid */
        +#define ASN1_AFLG_BROKEN	4
        +
        +/* operation values for asn1_cb */
        +
        +#define ASN1_OP_NEW_PRE		0
        +#define ASN1_OP_NEW_POST	1
        +#define ASN1_OP_FREE_PRE	2
        +#define ASN1_OP_FREE_POST	3
        +#define ASN1_OP_D2I_PRE		4
        +#define ASN1_OP_D2I_POST	5
        +#define ASN1_OP_I2D_PRE		6
        +#define ASN1_OP_I2D_POST	7
        +#define ASN1_OP_PRINT_PRE	8
        +#define ASN1_OP_PRINT_POST	9
        +#define ASN1_OP_STREAM_PRE	10
        +#define ASN1_OP_STREAM_POST	11
        +#define ASN1_OP_DETACHED_PRE	12
        +#define ASN1_OP_DETACHED_POST	13
        +
        +/* Macro to implement a primitive type */
        +#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
        +#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
        +				ASN1_ITEM_start(itname) \
        +					ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
        +				ASN1_ITEM_end(itname)
        +
        +/* Macro to implement a multi string type */
        +#define IMPLEMENT_ASN1_MSTRING(itname, mask) \
        +				ASN1_ITEM_start(itname) \
        +					ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
        +				ASN1_ITEM_end(itname)
        +
        +/* Macro to implement an ASN1_ITEM in terms of old style funcs */
        +
        +#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
        +
        +#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
        +	static const ASN1_COMPAT_FUNCS sname##_ff = { \
        +		(ASN1_new_func *)sname##_new, \
        +		(ASN1_free_func *)sname##_free, \
        +		(ASN1_d2i_func *)d2i_##sname, \
        +		(ASN1_i2d_func *)i2d_##sname, \
        +	}; \
        +	ASN1_ITEM_start(sname) \
        +		ASN1_ITYPE_COMPAT, \
        +		tag, \
        +		NULL, \
        +		0, \
        +		&sname##_ff, \
        +		0, \
        +		#sname \
        +	ASN1_ITEM_end(sname)
        +
        +#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
        +	ASN1_ITEM_start(sname) \
        +		ASN1_ITYPE_EXTERN, \
        +		tag, \
        +		NULL, \
        +		0, \
        +		&fptrs, \
        +		0, \
        +		#sname \
        +	ASN1_ITEM_end(sname)
        +
        +/* Macro to implement standard functions in terms of ASN1_ITEM structures */
        +
        +#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
        +
        +#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
        +
        +#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
        +			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
        +
        +#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
        +		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
        +
        +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
        +		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
        +
        +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
        +	pre stname *fname##_new(void) \
        +	{ \
        +		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
        +	} \
        +	pre void fname##_free(stname *a) \
        +	{ \
        +		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
        +	}
        +
        +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
        +	stname *fname##_new(void) \
        +	{ \
        +		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
        +	} \
        +	void fname##_free(stname *a) \
        +	{ \
        +		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
        +	}
        +
        +#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
        +	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
        +	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
        +
        +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
        +	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
        +	{ \
        +		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
        +	} \
        +	int i2d_##fname(stname *a, unsigned char **out) \
        +	{ \
        +		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
        +	} 
        +
        +#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
        +	int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
        +	{ \
        +		return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
        +	} 
        +
        +/* This includes evil casts to remove const: they will go away when full
        + * ASN1 constification is done.
        + */
        +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
        +	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
        +	{ \
        +		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
        +	} \
        +	int i2d_##fname(const stname *a, unsigned char **out) \
        +	{ \
        +		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
        +	} 
        +
        +#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
        +	stname * stname##_dup(stname *x) \
        +        { \
        +        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
        +        }
        +
        +#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
        +	IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
        +
        +#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
        +	int fname##_print_ctx(BIO *out, stname *x, int indent, \
        +						const ASN1_PCTX *pctx) \
        +	{ \
        +		return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
        +			ASN1_ITEM_rptr(itname), pctx); \
        +	} 
        +
        +#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
        +		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
        +
        +#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
        +	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
        +	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
        +
        +/* external definitions for primitive types */
        +
        +DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
        +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
        +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
        +DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
        +DECLARE_ASN1_ITEM(CBIGNUM)
        +DECLARE_ASN1_ITEM(BIGNUM)
        +DECLARE_ASN1_ITEM(LONG)
        +DECLARE_ASN1_ITEM(ZLONG)
        +
        +DECLARE_STACK_OF(ASN1_VALUE)
        +
        +/* Functions used internally by the ASN1 code */
        +
        +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
        +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +
        +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
        +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
        +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
        +				int tag, int aclass, char opt, ASN1_TLC *ctx);
        +
        +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
        +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
        +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +
        +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
        +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
        +
        +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
        +
        +ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
        +
        +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
        +
        +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
        +
        +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
        +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn_mime.c b/vendor/openssl/openssl/crypto/asn1/asn_mime.c
        new file mode 100644
        index 000000000..54a704a96
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn_mime.c
        @@ -0,0 +1,951 @@
        +/* asn_mime.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include "asn1_locl.h"
        +
        +/* Generalised MIME like utilities for streaming ASN1. Although many
        + * have a PKCS7/CMS like flavour others are more general purpose.
        + */
        +
        +/* MIME format structures
        + * Note that all are translated to lower case apart from
        + * parameter values. Quotes are stripped off
        + */
        +
        +typedef struct {
        +char *param_name;			/* Param name e.g. "micalg" */
        +char *param_value;			/* Param value e.g. "sha1" */
        +} MIME_PARAM;
        +
        +DECLARE_STACK_OF(MIME_PARAM)
        +IMPLEMENT_STACK_OF(MIME_PARAM)
        +
        +typedef struct {
        +char *name;				/* Name of line e.g. "content-type" */
        +char *value;				/* Value of line e.g. "text/plain" */
        +STACK_OF(MIME_PARAM) *params;		/* Zero or more parameters */
        +} MIME_HEADER;
        +
        +DECLARE_STACK_OF(MIME_HEADER)
        +IMPLEMENT_STACK_OF(MIME_HEADER)
        +
        +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
        +					const ASN1_ITEM *it);
        +static char * strip_ends(char *name);
        +static char * strip_start(char *name);
        +static char * strip_end(char *name);
        +static MIME_HEADER *mime_hdr_new(char *name, char *value);
        +static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
        +static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
        +static int mime_hdr_cmp(const MIME_HEADER * const *a,
        +			const MIME_HEADER * const *b);
        +static int mime_param_cmp(const MIME_PARAM * const *a,
        +			const MIME_PARAM * const *b);
        +static void mime_param_free(MIME_PARAM *param);
        +static int mime_bound_check(char *line, int linelen, char *bound, int blen);
        +static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
        +static int strip_eol(char *linebuf, int *plen);
        +static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
        +static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
        +static void mime_hdr_free(MIME_HEADER *hdr);
        +
        +#define MAX_SMLEN 1024
        +#define mime_debug(x) /* x */
        +
        +/* Output an ASN1 structure in BER format streaming if necessary */
        +
        +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
        +				const ASN1_ITEM *it)
        +	{
        +	/* If streaming create stream BIO and copy all content through it */
        +	if (flags & SMIME_STREAM)
        +		{
        +		BIO *bio, *tbio;
        +		bio = BIO_new_NDEF(out, val, it);
        +		if (!bio)
        +			{
        +			ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		SMIME_crlf_copy(in, bio, flags);
        +		(void)BIO_flush(bio);
        +		/* Free up successive BIOs until we hit the old output BIO */
        +		do
        +			{
        +			tbio = BIO_pop(bio);
        +			BIO_free(bio);
        +			bio = tbio;
        +			} while (bio != out);
        +		}
        +	/* else just write out ASN1 structure which will have all content
        +	 * stored internally
        +	 */
        +	else
        +		ASN1_item_i2d_bio(it, out, val);
        +	return 1;
        +	}
        +
        +/* Base 64 read and write of ASN1 structure */
        +
        +static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
        +				const ASN1_ITEM *it)
        +	{
        +	BIO *b64;
        +	int r;
        +	b64 = BIO_new(BIO_f_base64());
        +	if(!b64)
        +		{
        +		ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	/* prepend the b64 BIO so all data is base64 encoded.
        +	 */
        +	out = BIO_push(b64, out);
        +	r = i2d_ASN1_bio_stream(out, val, in, flags, it);
        +	(void)BIO_flush(out);
        +	BIO_pop(out);
        +	BIO_free(b64);
        +	return r;
        +	}
        +
        +/* Streaming ASN1 PEM write */
        +
        +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
        +				const char *hdr,
        +				const ASN1_ITEM *it)
        +	{
        +	int r;
        +	BIO_printf(out, "-----BEGIN %s-----\n", hdr);
        +	r = B64_write_ASN1(out, val, in, flags, it);
        +	BIO_printf(out, "-----END %s-----\n", hdr);
        +	return r;
        +	}
        +
        +static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
        +{
        +	BIO *b64;
        +	ASN1_VALUE *val;
        +	if(!(b64 = BIO_new(BIO_f_base64()))) {
        +		ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	bio = BIO_push(b64, bio);
        +	val = ASN1_item_d2i_bio(it, bio, NULL);
        +	if(!val)
        +		ASN1err(ASN1_F_B64_READ_ASN1,ASN1_R_DECODE_ERROR);
        +	(void)BIO_flush(bio);
        +	bio = BIO_pop(bio);
        +	BIO_free(b64);
        +	return val;
        +}
        +
        +/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
        +
        +static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
        +	{
        +	const EVP_MD *md;
        +	int i, have_unknown = 0, write_comma, ret = 0, md_nid;
        +	have_unknown = 0;
        +	write_comma = 0;
        +	for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
        +		{
        +		if (write_comma)
        +			BIO_write(out, ",", 1);
        +		write_comma = 1;
        +		md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
        +		md = EVP_get_digestbynid(md_nid);
        +		if (md && md->md_ctrl)
        +			{
        +			int rv;
        +			char *micstr;
        +			rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
        +			if (rv > 0)
        +				{
        +				BIO_puts(out, micstr);
        +				OPENSSL_free(micstr);
        +				continue;
        +				}
        +			if (rv != -2)
        +				goto err;
        +			}
        +		switch(md_nid)
        +			{
        +			case NID_sha1:
        +			BIO_puts(out, "sha1");
        +			break;
        +
        +			case NID_md5:
        +			BIO_puts(out, "md5");
        +			break;
        +
        +			case NID_sha256:
        +			BIO_puts(out, "sha-256");
        +			break;
        +
        +			case NID_sha384:
        +			BIO_puts(out, "sha-384");
        +			break;
        +
        +			case NID_sha512:
        +			BIO_puts(out, "sha-512");
        +			break;
        +
        +			case NID_id_GostR3411_94:
        +			BIO_puts(out, "gostr3411-94");
        +				goto err;
        +			break;
        +
        +			default:
        +			if (have_unknown)
        +				write_comma = 0;
        +			else
        +				{
        +				BIO_puts(out, "unknown");
        +				have_unknown = 1;
        +				}
        +			break;
        +
        +			}
        +		}
        +
        +	ret = 1;
        +	err:
        +
        +	return ret;
        +
        +	}
        +
        +/* SMIME sender */
        +
        +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
        +				int ctype_nid, int econt_nid,
        +				STACK_OF(X509_ALGOR) *mdalgs,
        +				const ASN1_ITEM *it)
        +{
        +	char bound[33], c;
        +	int i;
        +	const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
        +	const char *msg_type=NULL;
        +	if (flags & SMIME_OLDMIME)
        +		mime_prefix = "application/x-pkcs7-";
        +	else
        +		mime_prefix = "application/pkcs7-";
        +
        +	if (flags & SMIME_CRLFEOL)
        +		mime_eol = "\r\n";
        +	else
        +		mime_eol = "\n";
        +	if((flags & SMIME_DETACHED) && data) {
        +	/* We want multipart/signed */
        +		/* Generate a random boundary */
        +		RAND_pseudo_bytes((unsigned char *)bound, 32);
        +		for(i = 0; i < 32; i++) {
        +			c = bound[i] & 0xf;
        +			if(c < 10) c += '0';
        +			else c += 'A' - 10;
        +			bound[i] = c;
        +		}
        +		bound[32] = 0;
        +		BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
        +		BIO_printf(bio, "Content-Type: multipart/signed;");
        +		BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
        +		BIO_puts(bio, " micalg=\"");
        +		asn1_write_micalg(bio, mdalgs);
        +		BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
        +						bound, mime_eol, mime_eol);
        +		BIO_printf(bio, "This is an S/MIME signed message%s%s",
        +						mime_eol, mime_eol);
        +		/* Now write out the first part */
        +		BIO_printf(bio, "------%s%s", bound, mime_eol);
        +		if (!asn1_output_data(bio, data, val, flags, it))
        +			return 0;
        +		BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
        +
        +		/* Headers for signature */
        +
        +		BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); 
        +		BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
        +		BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
        +								mime_eol);
        +		BIO_printf(bio, "Content-Disposition: attachment;");
        +		BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
        +							mime_eol, mime_eol);
        +		B64_write_ASN1(bio, val, NULL, 0, it);
        +		BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
        +							mime_eol, mime_eol);
        +		return 1;
        +	}
        +
        +	/* Determine smime-type header */
        +
        +	if (ctype_nid == NID_pkcs7_enveloped)
        +		msg_type = "enveloped-data";
        +	else if (ctype_nid == NID_pkcs7_signed)
        +		{
        +		if (econt_nid == NID_id_smime_ct_receipt)
        +			msg_type = "signed-receipt";
        +		else if (sk_X509_ALGOR_num(mdalgs) >= 0)
        +			msg_type = "signed-data";
        +		else
        +			msg_type = "certs-only";
        +		}
        +	else if (ctype_nid == NID_id_smime_ct_compressedData)
        +		{
        +		msg_type = "compressed-data";
        +		cname = "smime.p7z";
        +		}
        +	/* MIME headers */
        +	BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
        +	BIO_printf(bio, "Content-Disposition: attachment;");
        +	BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
        +	BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
        +	if (msg_type)
        +		BIO_printf(bio, " smime-type=%s;", msg_type);
        +	BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
        +	BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
        +						mime_eol, mime_eol);
        +	if (!B64_write_ASN1(bio, val, data, flags, it))
        +		return 0;
        +	BIO_printf(bio, "%s", mime_eol);
        +	return 1;
        +}
        +
        +/* Handle output of ASN1 data */
        +
        +
        +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
        +					const ASN1_ITEM *it)
        +	{
        +	BIO *tmpbio;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_STREAM_ARG sarg;
        +	int rv = 1;
        +
        +	/* If data is not deteched or resigning then the output BIO is
        +	 * already set up to finalise when it is written through.
        +	 */
        +	if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST))
        +		{
        +		SMIME_crlf_copy(data, out, flags);
        +		return 1;
        +		}
        +
        +	if (!aux || !aux->asn1_cb)
        +		{
        +		ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
        +					ASN1_R_STREAMING_NOT_SUPPORTED);
        +		return 0;
        +		}
        +
        +	sarg.out = out;
        +	sarg.ndef_bio = NULL;
        +	sarg.boundary = NULL;
        +
        +	/* Let ASN1 code prepend any needed BIOs */
        +
        +	if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
        +		return 0;
        +
        +	/* Copy data across, passing through filter BIOs for processing */
        +	SMIME_crlf_copy(data, sarg.ndef_bio, flags);
        +
        +	/* Finalize structure */
        +	if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
        +		rv = 0;
        +
        +	/* Now remove any digests prepended to the BIO */
        +
        +	while (sarg.ndef_bio != out)
        +		{
        +		tmpbio = BIO_pop(sarg.ndef_bio);
        +		BIO_free(sarg.ndef_bio);
        +		sarg.ndef_bio = tmpbio;
        +		}
        +
        +	return rv;
        +
        +	}
        +
        +/* SMIME reader: handle multipart/signed and opaque signing.
        + * in multipart case the content is placed in a memory BIO
        + * pointed to by "bcont". In opaque this is set to NULL
        + */
        +
        +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
        +{
        +	BIO *asnin;
        +	STACK_OF(MIME_HEADER) *headers = NULL;
        +	STACK_OF(BIO) *parts = NULL;
        +	MIME_HEADER *hdr;
        +	MIME_PARAM *prm;
        +	ASN1_VALUE *val;
        +	int ret;
        +
        +	if(bcont) *bcont = NULL;
        +
        +	if (!(headers = mime_parse_hdr(bio))) {
        +		ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR);
        +		return NULL;
        +	}
        +
        +	if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
        +		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
        +		return NULL;
        +	}
        +
        +	/* Handle multipart/signed */
        +
        +	if(!strcmp(hdr->value, "multipart/signed")) {
        +		/* Split into two parts */
        +		prm = mime_param_find(hdr, "boundary");
        +		if(!prm || !prm->param_value) {
        +			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +			ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
        +			return NULL;
        +		}
        +		ret = multi_split(bio, prm->param_value, &parts);
        +		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +		if(!ret || (sk_BIO_num(parts) != 2) ) {
        +			ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
        +			sk_BIO_pop_free(parts, BIO_vfree);
        +			return NULL;
        +		}
        +
        +		/* Parse the signature piece */
        +		asnin = sk_BIO_value(parts, 1);
        +
        +		if (!(headers = mime_parse_hdr(asnin))) {
        +			ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
        +			sk_BIO_pop_free(parts, BIO_vfree);
        +			return NULL;
        +		}
        +
        +		/* Get content type */
        +
        +		if(!(hdr = mime_hdr_find(headers, "content-type")) ||
        +								 !hdr->value) {
        +			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +			ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
        +			return NULL;
        +		}
        +
        +		if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
        +			strcmp(hdr->value, "application/pkcs7-signature")) {
        +			ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
        +			ERR_add_error_data(2, "type: ", hdr->value);
        +			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +			sk_BIO_pop_free(parts, BIO_vfree);
        +			return NULL;
        +		}
        +		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +		/* Read in ASN1 */
        +		if(!(val = b64_read_asn1(asnin, it))) {
        +			ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR);
        +			sk_BIO_pop_free(parts, BIO_vfree);
        +			return NULL;
        +		}
        +
        +		if(bcont) {
        +			*bcont = sk_BIO_value(parts, 0);
        +			BIO_free(asnin);
        +			sk_BIO_free(parts);
        +		} else sk_BIO_pop_free(parts, BIO_vfree);
        +		return val;
        +	}
        +		
        +	/* OK, if not multipart/signed try opaque signature */
        +
        +	if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
        +	    strcmp (hdr->value, "application/pkcs7-mime")) {
        +		ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_INVALID_MIME_TYPE);
        +		ERR_add_error_data(2, "type: ", hdr->value);
        +		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +		return NULL;
        +	}
        +
        +	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +	
        +	if(!(val = b64_read_asn1(bio, it))) {
        +		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
        +		return NULL;
        +	}
        +	return val;
        +
        +}
        +
        +/* Copy text from one BIO to another making the output CRLF at EOL */
        +int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
        +{
        +	BIO *bf;
        +	char eol;
        +	int len;
        +	char linebuf[MAX_SMLEN];
        +	/* Buffer output so we don't write one line at a time. This is
        +	 * useful when streaming as we don't end up with one OCTET STRING
        +	 * per line.
        +	 */
        +	bf = BIO_new(BIO_f_buffer());
        +	if (!bf)
        +		return 0;
        +	out = BIO_push(bf, out);
        +	if(flags & SMIME_BINARY)
        +		{
        +		while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
        +						BIO_write(out, linebuf, len);
        +		}
        +	else
        +		{
        +		if(flags & SMIME_TEXT)
        +			BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
        +		while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
        +			{
        +			eol = strip_eol(linebuf, &len);
        +			if (len)
        +				BIO_write(out, linebuf, len);
        +			if(eol) BIO_write(out, "\r\n", 2);
        +			}
        +		}
        +	(void)BIO_flush(out);
        +	BIO_pop(out);
        +	BIO_free(bf);
        +	return 1;
        +}
        +
        +/* Strip off headers if they are text/plain */
        +int SMIME_text(BIO *in, BIO *out)
        +{
        +	char iobuf[4096];
        +	int len;
        +	STACK_OF(MIME_HEADER) *headers;
        +	MIME_HEADER *hdr;
        +
        +	if (!(headers = mime_parse_hdr(in))) {
        +		ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR);
        +		return 0;
        +	}
        +	if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
        +		ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE);
        +		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +		return 0;
        +	}
        +	if (strcmp (hdr->value, "text/plain")) {
        +		ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE);
        +		ERR_add_error_data(2, "type: ", hdr->value);
        +		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +		return 0;
        +	}
        +	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
        +	while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
        +						BIO_write(out, iobuf, len);
        +	if (len < 0)
        +		return 0;
        +	return 1;
        +}
        +
        +/* Split a multipart/XXX message body into component parts: result is
        + * canonical parts in a STACK of bios
        + */
        +
        +static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
        +{
        +	char linebuf[MAX_SMLEN];
        +	int len, blen;
        +	int eol = 0, next_eol = 0;
        +	BIO *bpart = NULL;
        +	STACK_OF(BIO) *parts;
        +	char state, part, first;
        +
        +	blen = strlen(bound);
        +	part = 0;
        +	state = 0;
        +	first = 1;
        +	parts = sk_BIO_new_null();
        +	*ret = parts;
        +	while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
        +		state = mime_bound_check(linebuf, len, bound, blen);
        +		if(state == 1) {
        +			first = 1;
        +			part++;
        +		} else if(state == 2) {
        +			sk_BIO_push(parts, bpart);
        +			return 1;
        +		} else if(part) {
        +			/* Strip CR+LF from linebuf */
        +			next_eol = strip_eol(linebuf, &len);
        +			if(first) {
        +				first = 0;
        +				if(bpart) sk_BIO_push(parts, bpart);
        +				bpart = BIO_new(BIO_s_mem());
        +				BIO_set_mem_eof_return(bpart, 0);
        +			} else if (eol)
        +				BIO_write(bpart, "\r\n", 2);
        +			eol = next_eol;
        +			if (len)
        +				BIO_write(bpart, linebuf, len);
        +		}
        +	}
        +	return 0;
        +}
        +
        +/* This is the big one: parse MIME header lines up to message body */
        +
        +#define MIME_INVALID	0
        +#define MIME_START	1
        +#define MIME_TYPE	2
        +#define MIME_NAME	3
        +#define MIME_VALUE	4
        +#define MIME_QUOTE	5
        +#define MIME_COMMENT	6
        +
        +
        +static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
        +{
        +	char *p, *q, c;
        +	char *ntmp;
        +	char linebuf[MAX_SMLEN];
        +	MIME_HEADER *mhdr = NULL;
        +	STACK_OF(MIME_HEADER) *headers;
        +	int len, state, save_state = 0;
        +
        +	headers = sk_MIME_HEADER_new(mime_hdr_cmp);
        +	while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
        +	/* If whitespace at line start then continuation line */
        +	if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
        +	else state = MIME_START;
        +	ntmp = NULL;
        +	/* Go through all characters */
        +	for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
        +
        +	/* State machine to handle MIME headers
        +	 * if this looks horrible that's because it *is*
        +         */
        +
        +		switch(state) {
        +			case MIME_START:
        +			if(c == ':') {
        +				state = MIME_TYPE;
        +				*p = 0;
        +				ntmp = strip_ends(q);
        +				q = p + 1;
        +			}
        +			break;
        +
        +			case MIME_TYPE:
        +			if(c == ';') {
        +				mime_debug("Found End Value\n");
        +				*p = 0;
        +				mhdr = mime_hdr_new(ntmp, strip_ends(q));
        +				sk_MIME_HEADER_push(headers, mhdr);
        +				ntmp = NULL;
        +				q = p + 1;
        +				state = MIME_NAME;
        +			} else if(c == '(') {
        +				save_state = state;
        +				state = MIME_COMMENT;
        +			}
        +			break;
        +
        +			case MIME_COMMENT:
        +			if(c == ')') {
        +				state = save_state;
        +			}
        +			break;
        +
        +			case MIME_NAME:
        +			if(c == '=') {
        +				state = MIME_VALUE;
        +				*p = 0;
        +				ntmp = strip_ends(q);
        +				q = p + 1;
        +			}
        +			break ;
        +
        +			case MIME_VALUE:
        +			if(c == ';') {
        +				state = MIME_NAME;
        +				*p = 0;
        +				mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
        +				ntmp = NULL;
        +				q = p + 1;
        +			} else if (c == '"') {
        +				mime_debug("Found Quote\n");
        +				state = MIME_QUOTE;
        +			} else if(c == '(') {
        +				save_state = state;
        +				state = MIME_COMMENT;
        +			}
        +			break;
        +
        +			case MIME_QUOTE:
        +			if(c == '"') {
        +				mime_debug("Found Match Quote\n");
        +				state = MIME_VALUE;
        +			}
        +			break;
        +		}
        +	}
        +
        +	if(state == MIME_TYPE) {
        +		mhdr = mime_hdr_new(ntmp, strip_ends(q));
        +		sk_MIME_HEADER_push(headers, mhdr);
        +	} else if(state == MIME_VALUE)
        +			 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
        +	if(p == linebuf) break;	/* Blank line means end of headers */
        +}
        +
        +return headers;
        +
        +}
        +
        +static char *strip_ends(char *name)
        +{
        +	return strip_end(strip_start(name));
        +}
        +
        +/* Strip a parameter of whitespace from start of param */
        +static char *strip_start(char *name)
        +{
        +	char *p, c;
        +	/* Look for first non white space or quote */
        +	for(p = name; (c = *p) ;p++) {
        +		if(c == '"') {
        +			/* Next char is start of string if non null */
        +			if(p[1]) return p + 1;
        +			/* Else null string */
        +			return NULL;
        +		}
        +		if(!isspace((unsigned char)c)) return p;
        +	}
        +	return NULL;
        +}
        +
        +/* As above but strip from end of string : maybe should handle brackets? */
        +static char *strip_end(char *name)
        +{
        +	char *p, c;
        +	if(!name) return NULL;
        +	/* Look for first non white space or quote */
        +	for(p = name + strlen(name) - 1; p >= name ;p--) {
        +		c = *p;
        +		if(c == '"') {
        +			if(p - 1 == name) return NULL;
        +			*p = 0;
        +			return name;
        +		}
        +		if(isspace((unsigned char)c)) *p = 0;	
        +		else return name;
        +	}
        +	return NULL;
        +}
        +
        +static MIME_HEADER *mime_hdr_new(char *name, char *value)
        +{
        +	MIME_HEADER *mhdr;
        +	char *tmpname, *tmpval, *p;
        +	int c;
        +	if(name) {
        +		if(!(tmpname = BUF_strdup(name))) return NULL;
        +		for(p = tmpname ; *p; p++) {
        +			c = (unsigned char)*p;
        +			if(isupper(c)) {
        +				c = tolower(c);
        +				*p = c;
        +			}
        +		}
        +	} else tmpname = NULL;
        +	if(value) {
        +		if(!(tmpval = BUF_strdup(value))) return NULL;
        +		for(p = tmpval ; *p; p++) {
        +			c = (unsigned char)*p;
        +			if(isupper(c)) {
        +				c = tolower(c);
        +				*p = c;
        +			}
        +		}
        +	} else tmpval = NULL;
        +	mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
        +	if(!mhdr) return NULL;
        +	mhdr->name = tmpname;
        +	mhdr->value = tmpval;
        +	if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
        +	return mhdr;
        +}
        +		
        +static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
        +{
        +	char *tmpname, *tmpval, *p;
        +	int c;
        +	MIME_PARAM *mparam;
        +	if(name) {
        +		tmpname = BUF_strdup(name);
        +		if(!tmpname) return 0;
        +		for(p = tmpname ; *p; p++) {
        +			c = (unsigned char)*p;
        +			if(isupper(c)) {
        +				c = tolower(c);
        +				*p = c;
        +			}
        +		}
        +	} else tmpname = NULL;
        +	if(value) {
        +		tmpval = BUF_strdup(value);
        +		if(!tmpval) return 0;
        +	} else tmpval = NULL;
        +	/* Parameter values are case sensitive so leave as is */
        +	mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
        +	if(!mparam) return 0;
        +	mparam->param_name = tmpname;
        +	mparam->param_value = tmpval;
        +	sk_MIME_PARAM_push(mhdr->params, mparam);
        +	return 1;
        +}
        +
        +static int mime_hdr_cmp(const MIME_HEADER * const *a,
        +			const MIME_HEADER * const *b)
        +{
        +	if (!(*a)->name || !(*b)->name)
        +		return !!(*a)->name - !!(*b)->name;
        +
        +	return(strcmp((*a)->name, (*b)->name));
        +}
        +
        +static int mime_param_cmp(const MIME_PARAM * const *a,
        +			const MIME_PARAM * const *b)
        +{
        +	if (!(*a)->param_name || !(*b)->param_name)
        +		return !!(*a)->param_name - !!(*b)->param_name;
        +	return(strcmp((*a)->param_name, (*b)->param_name));
        +}
        +
        +/* Find a header with a given name (if possible) */
        +
        +static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
        +{
        +	MIME_HEADER htmp;
        +	int idx;
        +	htmp.name = name;
        +	idx = sk_MIME_HEADER_find(hdrs, &htmp);
        +	if(idx < 0) return NULL;
        +	return sk_MIME_HEADER_value(hdrs, idx);
        +}
        +
        +static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
        +{
        +	MIME_PARAM param;
        +	int idx;
        +	param.param_name = name;
        +	idx = sk_MIME_PARAM_find(hdr->params, &param);
        +	if(idx < 0) return NULL;
        +	return sk_MIME_PARAM_value(hdr->params, idx);
        +}
        +
        +static void mime_hdr_free(MIME_HEADER *hdr)
        +{
        +	if(hdr->name) OPENSSL_free(hdr->name);
        +	if(hdr->value) OPENSSL_free(hdr->value);
        +	if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
        +	OPENSSL_free(hdr);
        +}
        +
        +static void mime_param_free(MIME_PARAM *param)
        +{
        +	if(param->param_name) OPENSSL_free(param->param_name);
        +	if(param->param_value) OPENSSL_free(param->param_value);
        +	OPENSSL_free(param);
        +}
        +
        +/* Check for a multipart boundary. Returns:
        + * 0 : no boundary
        + * 1 : part boundary
        + * 2 : final boundary
        + */
        +static int mime_bound_check(char *line, int linelen, char *bound, int blen)
        +{
        +	if(linelen == -1) linelen = strlen(line);
        +	if(blen == -1) blen = strlen(bound);
        +	/* Quickly eliminate if line length too short */
        +	if(blen + 2 > linelen) return 0;
        +	/* Check for part boundary */
        +	if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
        +		if(!strncmp(line + blen + 2, "--", 2)) return 2;
        +		else return 1;
        +	}
        +	return 0;
        +}
        +
        +static int strip_eol(char *linebuf, int *plen)
        +	{
        +	int len = *plen;
        +	char *p, c;
        +	int is_eol = 0;
        +	p = linebuf + len - 1;
        +	for (p = linebuf + len - 1; len > 0; len--, p--)
        +		{
        +		c = *p;
        +		if (c == '\n')
        +			is_eol = 1;
        +		else if (c != '\r')
        +			break;
        +		}
        +	*plen = len;
        +	return is_eol;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn_moid.c b/vendor/openssl/openssl/crypto/asn1/asn_moid.c
        new file mode 100644
        index 000000000..1ea6a5924
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn_moid.c
        @@ -0,0 +1,160 @@
        +/* asn_moid.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001-2004 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 <stdio.h>
        +#include <ctype.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/dso.h>
        +#include <openssl/x509.h>
        +
        +/* Simple ASN1 OID module: add all objects in a given section */
        +
        +static int do_create(char *value, char *name);
        +
        +static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
        +	{
        +	int i;
        +	const char *oid_section;
        +	STACK_OF(CONF_VALUE) *sktmp;
        +	CONF_VALUE *oval;
        +	oid_section = CONF_imodule_get_value(md);
        +	if(!(sktmp = NCONF_get_section(cnf, oid_section)))
        +		{
        +		ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
        +		return 0;
        +		}
        +	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
        +		{
        +		oval = sk_CONF_VALUE_value(sktmp, i);
        +		if(!do_create(oval->value, oval->name))
        +			{
        +			ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
        +			return 0;
        +			}
        +		}
        +	return 1;
        +	}
        +
        +static void oid_module_finish(CONF_IMODULE *md)
        +	{
        +	OBJ_cleanup();
        +	}
        +
        +void ASN1_add_oid_module(void)
        +	{
        +	CONF_module_add("oid_section", oid_module_init, oid_module_finish);
        +	}
        +
        +/* Create an OID based on a name value pair. Accept two formats.
        + * shortname = 1.2.3.4
        + * shortname = some long name, 1.2.3.4
        + */
        +
        +
        +static int do_create(char *value, char *name)
        +	{
        +	int nid;
        +	ASN1_OBJECT *oid;
        +	char *ln, *ostr, *p, *lntmp;
        +	p = strrchr(value, ',');
        +	if (!p)
        +		{
        +		ln = name;
        +		ostr = value;
        +		}
        +	else
        +		{
        +		ln = NULL;
        +		ostr = p + 1;
        +		if (!*ostr)
        +			return 0;
        +		while(isspace((unsigned char)*ostr)) ostr++;
        +		}
        +
        +	nid = OBJ_create(ostr, name, ln);
        +
        +	if (nid == NID_undef)
        +		return 0;
        +
        +	if (p)
        +		{
        +		ln = value;
        +		while(isspace((unsigned char)*ln)) ln++;
        +		p--;
        +		while(isspace((unsigned char)*p))
        +			{
        +			if (p == ln)
        +				return 0;
        +			p--;
        +			}
        +		p++;
        +		lntmp = OPENSSL_malloc((p - ln) + 1);
        +		if (lntmp == NULL)
        +			return 0;
        +		memcpy(lntmp, ln, p - ln);
        +		lntmp[p - ln] = 0;
        +		oid = OBJ_nid2obj(nid);
        +		oid->ln = lntmp;
        +		}
        +
        +	return 1;
        +	}
        +		
        +		
        diff --git a/vendor/openssl/openssl/crypto/asn1/asn_pack.c b/vendor/openssl/openssl/crypto/asn1/asn_pack.c
        new file mode 100644
        index 000000000..ad738217d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/asn_pack.c
        @@ -0,0 +1,191 @@
        +/* asn_pack.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +
        +#ifndef NO_ASN1_OLD
        +
        +/* ASN1 packing and unpacking functions */
        +
        +/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
        +
        +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
        +			 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK))
        +{
        +    STACK_OF(OPENSSL_BLOCK) *sk;
        +    const unsigned char *pbuf;
        +    pbuf =  buf;
        +    if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
        +					V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
        +		 ASN1err(ASN1_F_ASN1_SEQ_UNPACK,ASN1_R_DECODE_ERROR);
        +    return sk;
        +}
        +
        +/* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
        + * OPENSSL_malloc'ed buffer
        + */
        +
        +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
        +			     unsigned char **buf, int *len)
        +{
        +	int safelen;
        +	unsigned char *safe, *p;
        +	if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
        +					      V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
        +		ASN1err(ASN1_F_ASN1_SEQ_PACK,ASN1_R_ENCODE_ERROR);
        +		return NULL;
        +	}
        +	if (!(safe = OPENSSL_malloc (safelen))) {
        +		ASN1err(ASN1_F_ASN1_SEQ_PACK,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	p = safe;
        +	i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
        +								 IS_SEQUENCE);
        +	if (len) *len = safelen;
        +	if (buf) *buf = safe;
        +	return safe;
        +}
        +
        +/* Extract an ASN1 object from an ASN1_STRING */
        +
        +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
        +{
        +	const unsigned char *p;
        +	char *ret;
        +
        +	p = oct->data;
        +	if(!(ret = d2i(NULL, &p, oct->length)))
        +		ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR);
        +	return ret;
        +}
        +
        +/* Pack an ASN1 object into an ASN1_STRING */
        +
        +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
        +{
        +	unsigned char *p;
        +	ASN1_STRING *octmp;
        +
        +	if (!oct || !*oct) {
        +		if (!(octmp = ASN1_STRING_new ())) {
        +			ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +		}
        +		if (oct) *oct = octmp;
        +	} else octmp = *oct;
        +		
        +	if (!(octmp->length = i2d(obj, NULL))) {
        +		ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR);
        +		return NULL;
        +	}
        +	if (!(p = OPENSSL_malloc (octmp->length))) {
        +		ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	octmp->data = p;
        +	i2d (obj, &p);
        +	return octmp;
        +}
        +
        +#endif
        +
        +/* ASN1_ITEM versions of the above */
        +
        +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
        +{
        +	ASN1_STRING *octmp;
        +
        +	if (!oct || !*oct) {
        +		if (!(octmp = ASN1_STRING_new ())) {
        +			ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +		}
        +		if (oct) *oct = octmp;
        +	} else octmp = *oct;
        +
        +	if(octmp->data) {
        +		OPENSSL_free(octmp->data);
        +		octmp->data = NULL;
        +	}
        +		
        +	if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
        +		ASN1err(ASN1_F_ASN1_ITEM_PACK,ASN1_R_ENCODE_ERROR);
        +		return NULL;
        +	}
        +	if (!octmp->data) {
        +		ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	return octmp;
        +}
        +
        +/* Extract an ASN1 object from an ASN1_STRING */
        +
        +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
        +{
        +	const unsigned char *p;
        +	void *ret;
        +
        +	p = oct->data;
        +	if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
        +		ASN1err(ASN1_F_ASN1_ITEM_UNPACK,ASN1_R_DECODE_ERROR);
        +	return ret;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/bio_asn1.c b/vendor/openssl/openssl/crypto/asn1/bio_asn1.c
        new file mode 100644
        index 000000000..dc7efd551
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/bio_asn1.c
        @@ -0,0 +1,495 @@
        +/* bio_asn1.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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).
        + *
        + */
        +
        +/* Experimental ASN1 BIO. When written through the data is converted
        + * to an ASN1 string type: default is OCTET STRING. Additional functions
        + * can be provided to add prefix and suffix data.
        + */
        +
        +#include <string.h>
        +#include <openssl/bio.h>
        +#include <openssl/asn1.h>
        +
        +/* Must be large enough for biggest tag+length */
        +#define DEFAULT_ASN1_BUF_SIZE 20
        +
        +typedef enum 
        +	{
        +	ASN1_STATE_START,
        +	ASN1_STATE_PRE_COPY,
        +	ASN1_STATE_HEADER,
        +	ASN1_STATE_HEADER_COPY,
        +	ASN1_STATE_DATA_COPY,
        +	ASN1_STATE_POST_COPY,
        +	ASN1_STATE_DONE
        +	} asn1_bio_state_t;
        +
        +typedef struct BIO_ASN1_EX_FUNCS_st
        +	{
        +	asn1_ps_func	*ex_func;
        +	asn1_ps_func	*ex_free_func;
        +	} BIO_ASN1_EX_FUNCS;
        +
        +typedef struct BIO_ASN1_BUF_CTX_t
        +	{
        +	/* Internal state */
        +	asn1_bio_state_t state;
        +	/* Internal buffer */
        +	unsigned char *buf;
        +	/* Size of buffer */
        +	int bufsize;
        +	/* Current position in buffer */
        +	int bufpos;
        +	/* Current buffer length */
        +	int buflen;
        +	/* Amount of data to copy */
        +	int copylen;
        +	/* Class and tag to use */
        +	int asn1_class, asn1_tag;
        +	asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
        +	/* Extra buffer for prefix and suffix data */
        +	unsigned char *ex_buf;
        +	int ex_len;
        +	int ex_pos;
        +	void *ex_arg;
        +	} BIO_ASN1_BUF_CTX;
        +
        +
        +static int asn1_bio_write(BIO *h, const char *buf,int num);
        +static int asn1_bio_read(BIO *h, char *buf, int size);
        +static int asn1_bio_puts(BIO *h, const char *str);
        +static int asn1_bio_gets(BIO *h, char *str, int size);
        +static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int asn1_bio_new(BIO *h);
        +static int asn1_bio_free(BIO *data);
        +static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
        +
        +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
        +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
        +				asn1_ps_func *cleanup, asn1_bio_state_t next);
        +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
        +				asn1_ps_func *setup, 
        +				asn1_bio_state_t ex_state,
        +				asn1_bio_state_t other_state);
        +
        +static BIO_METHOD methods_asn1=
        +	{
        +	BIO_TYPE_ASN1,
        +	"asn1",
        +	asn1_bio_write,
        +	asn1_bio_read,
        +	asn1_bio_puts,
        +	asn1_bio_gets,
        +	asn1_bio_ctrl,
        +	asn1_bio_new,
        +	asn1_bio_free,
        +	asn1_bio_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_asn1(void)
        +	{
        +	return(&methods_asn1);
        +	}
        +
        +
        +static int asn1_bio_new(BIO *b)
        +	{
        +	BIO_ASN1_BUF_CTX *ctx;
        +	ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
        +	if (!ctx)
        +		return 0;
        +	if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
        +		return 0;
        +	b->init = 1;
        +	b->ptr = (char *)ctx;
        +	b->flags = 0;
        +	return 1;
        +	}
        +
        +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
        +	{
        +	ctx->buf = OPENSSL_malloc(size);
        +	if (!ctx->buf)
        +		return 0;
        +	ctx->bufsize = size;
        +	ctx->bufpos = 0;
        +	ctx->buflen = 0;
        +	ctx->copylen = 0;
        +	ctx->asn1_class = V_ASN1_UNIVERSAL;
        +	ctx->asn1_tag = V_ASN1_OCTET_STRING;
        +	ctx->ex_buf = 0;
        +	ctx->ex_pos = 0;
        +	ctx->ex_len = 0;
        +	ctx->state = ASN1_STATE_START;
        +	return 1;
        +	}
        +
        +static int asn1_bio_free(BIO *b)
        +	{
        +	BIO_ASN1_BUF_CTX *ctx;
        +	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
        +	if (ctx == NULL)
        +		return 0;
        +	if (ctx->buf)
        +		OPENSSL_free(ctx->buf);
        +	OPENSSL_free(ctx);
        +	b->init = 0;
        +	b->ptr = NULL;
        +	b->flags = 0;
        +	return 1;
        +	}
        +
        +static int asn1_bio_write(BIO *b, const char *in , int inl)
        +	{
        +	BIO_ASN1_BUF_CTX *ctx;
        +	int wrmax, wrlen, ret;
        +	unsigned char *p;
        +	if (!in || (inl < 0) || (b->next_bio == NULL))
        +		return 0;
        +	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
        +	if (ctx == NULL)
        +		return 0;
        +
        +	wrlen = 0;
        +	ret = -1;
        +
        +	for(;;)
        +		{
        +		switch (ctx->state)
        +			{
        +
        +			/* Setup prefix data, call it */
        +			case ASN1_STATE_START:
        +			if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
        +				ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
        +				return 0;
        +			break;
        +
        +			/* Copy any pre data first */
        +			case ASN1_STATE_PRE_COPY:
        +
        +			ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
        +							ASN1_STATE_HEADER);
        +
        +			if (ret <= 0)
        +				goto done;
        +
        +			break;
        +
        +			case ASN1_STATE_HEADER:
        +			ctx->buflen =
        +				ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
        +			OPENSSL_assert(ctx->buflen <= ctx->bufsize);
        +			p = ctx->buf;
        +			ASN1_put_object(&p, 0, inl,
        +					ctx->asn1_tag, ctx->asn1_class);
        +			ctx->copylen = inl;
        +			ctx->state = ASN1_STATE_HEADER_COPY;
        +
        +			break;
        +
        +			case ASN1_STATE_HEADER_COPY:	
        +			ret = BIO_write(b->next_bio,
        +					ctx->buf + ctx->bufpos, ctx->buflen);
        +			if (ret <= 0)
        +				goto done;
        +
        +			ctx->buflen -= ret;
        +			if (ctx->buflen)
        +				ctx->bufpos += ret;
        +			else
        +				{
        +				ctx->bufpos = 0;
        +				ctx->state = ASN1_STATE_DATA_COPY;
        +				}
        +
        +			break;
        +
        +			case ASN1_STATE_DATA_COPY:
        +
        +			if (inl > ctx->copylen)
        +				wrmax = ctx->copylen;
        +			else
        +				wrmax = inl;
        +			ret = BIO_write(b->next_bio, in, wrmax);
        +			if (ret <= 0)
        +				break;
        +			wrlen += ret;
        +			ctx->copylen -= ret;
        +			in += ret;
        +			inl -= ret;
        +
        +			if (ctx->copylen == 0)
        +				ctx->state = ASN1_STATE_HEADER;
        +
        +			if (inl == 0)
        +				goto done;
        +
        +			break;
        +
        +			default:
        +			BIO_clear_retry_flags(b);
        +			return 0;
        +
        +			}
        +
        +		}
        +
        +	done:
        +	BIO_clear_retry_flags(b);
        +	BIO_copy_next_retry(b);
        +
        +	return (wrlen > 0) ? wrlen : ret;
        +
        +	}
        +
        +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
        +				asn1_ps_func *cleanup, asn1_bio_state_t next)
        +	{
        +	int ret;
        +	if (ctx->ex_len <= 0)
        +		return 1;
        +	for(;;)
        +		{
        +		ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
        +								ctx->ex_len);
        +		if (ret <= 0)
        +			break;
        +		ctx->ex_len -= ret;
        +		if (ctx->ex_len > 0)
        +			ctx->ex_pos += ret;
        +		else
        +			{
        +			if(cleanup)
        +				cleanup(b, &ctx->ex_buf, &ctx->ex_len,
        +								&ctx->ex_arg);
        +			ctx->state = next;
        +			ctx->ex_pos = 0;
        +			break;
        +			}
        +		}
        +	return ret;
        +	}
        +
        +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
        +				asn1_ps_func *setup, 
        +				asn1_bio_state_t ex_state,
        +				asn1_bio_state_t other_state)
        +	{
        +	if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
        +		{
        +		BIO_clear_retry_flags(b);
        +		return 0;
        +		}
        +	if (ctx->ex_len > 0)
        +		ctx->state = ex_state;
        +	else
        +		ctx->state = other_state;
        +	return 1;
        +	}
        +
        +static int asn1_bio_read(BIO *b, char *in , int inl)
        +	{
        +	if (!b->next_bio)
        +		return 0;
        +	return BIO_read(b->next_bio, in , inl);
        +	}
        +
        +static int asn1_bio_puts(BIO *b, const char *str)
        +	{
        +	return asn1_bio_write(b, str, strlen(str));
        +	}
        +
        +static int asn1_bio_gets(BIO *b, char *str, int size)
        +	{
        +	if (!b->next_bio)
        +		return 0;
        +	return BIO_gets(b->next_bio, str , size);
        +	}
        +
        +static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
        +	{
        +	if (b->next_bio == NULL) return(0);
        +	return BIO_callback_ctrl(b->next_bio,cmd,fp);
        +	}
        +
        +static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
        +	{
        +	BIO_ASN1_BUF_CTX *ctx;
        +	BIO_ASN1_EX_FUNCS *ex_func;
        +	long ret = 1;
        +	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
        +	if (ctx == NULL)
        +		return 0;
        +	switch(cmd)
        +		{
        +
        +		case BIO_C_SET_PREFIX:
        +		ex_func = arg2;
        +		ctx->prefix  = ex_func->ex_func;
        +		ctx->prefix_free  = ex_func->ex_free_func;
        +		break;
        +
        +		case BIO_C_GET_PREFIX:
        +		ex_func = arg2;
        +		ex_func->ex_func = ctx->prefix;
        +		ex_func->ex_free_func = ctx->prefix_free;
        +		break;
        +
        +		case BIO_C_SET_SUFFIX:
        +		ex_func = arg2;
        +		ctx->suffix  = ex_func->ex_func;
        +		ctx->suffix_free  = ex_func->ex_free_func;
        +		break;
        +
        +		case BIO_C_GET_SUFFIX:
        +		ex_func = arg2;
        +		ex_func->ex_func = ctx->suffix;
        +		ex_func->ex_free_func = ctx->suffix_free;
        +		break;
        +
        +		case BIO_C_SET_EX_ARG:
        +		ctx->ex_arg = arg2;
        +		break;
        +
        +		case BIO_C_GET_EX_ARG:
        +		*(void **)arg2 = ctx->ex_arg;
        +		break;
        +
        +		case BIO_CTRL_FLUSH:
        +		if (!b->next_bio)
        +			return 0;
        +
        +		/* Call post function if possible */
        +		if (ctx->state == ASN1_STATE_HEADER)
        +			{
        +			if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
        +				ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
        +				return 0;
        +			}
        +
        +		if (ctx->state == ASN1_STATE_POST_COPY)
        +			{
        +			ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
        +							ASN1_STATE_DONE);
        +			if (ret <= 0)
        +				return ret;
        +			}
        +
        +		if (ctx->state == ASN1_STATE_DONE)
        +			return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
        +		else
        +			{
        +			BIO_clear_retry_flags(b);
        +			return 0;
        +			}
        +		break;
        +
        +
        +		default:
        +		if (!b->next_bio)
        +			return 0;
        +		return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
        +
        +		}
        +
        +	return ret;
        +	}
        +
        +static int asn1_bio_set_ex(BIO *b, int cmd,
        +		asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
        +	{
        +	BIO_ASN1_EX_FUNCS extmp;
        +	extmp.ex_func = ex_func;
        +	extmp.ex_free_func = ex_free_func;
        +	return BIO_ctrl(b, cmd, 0, &extmp);
        +	}
        +
        +static int asn1_bio_get_ex(BIO *b, int cmd,
        +		asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
        +	{
        +	BIO_ASN1_EX_FUNCS extmp;
        +	int ret;
        +	ret = BIO_ctrl(b, cmd, 0, &extmp);
        +	if (ret > 0)
        +		{
        +		*ex_func = extmp.ex_func;
        +		*ex_free_func = extmp.ex_free_func;
        +		}
        +	return ret;
        +	}
        +
        +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
        +	{
        +	return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
        +	}
        +
        +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
        +	{
        +	return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
        +	}
        +
        +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
        +	{
        +	return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
        +	}
        +
        +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
        +	{
        +	return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/bio_ndef.c b/vendor/openssl/openssl/crypto/asn1/bio_ndef.c
        new file mode 100644
        index 000000000..b91f97a1b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/bio_ndef.c
        @@ -0,0 +1,243 @@
        +/* bio_ndef.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +
        +#include <stdio.h>
        +
        +/* Experimental NDEF ASN1 BIO support routines */
        +
        +/* The usage is quite simple, initialize an ASN1 structure,
        + * get a BIO from it then any data written through the BIO
        + * will end up translated to approptiate format on the fly.
        + * The data is streamed out and does *not* need to be
        + * all held in memory at once.
        + *
        + * When the BIO is flushed the output is finalized and any
        + * signatures etc written out.
        + *
        + * The BIO is a 'proper' BIO and can handle non blocking I/O
        + * correctly.
        + *
        + * The usage is simple. The implementation is *not*...
        + */
        +
        +/* BIO support data stored in the ASN1 BIO ex_arg */
        +
        +typedef struct ndef_aux_st
        +	{
        +	/* ASN1 structure this BIO refers to */
        +	ASN1_VALUE *val;
        +	const ASN1_ITEM *it;
        +	/* Top of the BIO chain */
        +	BIO *ndef_bio;
        +	/* Output BIO */
        +	BIO *out;
        +	/* Boundary where content is inserted */
        +	unsigned char **boundary;
        +	/* DER buffer start */
        +	unsigned char *derbuf;
        +	} NDEF_SUPPORT;
        +
        +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
        +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
        +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
        +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
        +
        +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
        +	{
        +	NDEF_SUPPORT *ndef_aux = NULL;
        +	BIO *asn_bio = NULL;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_STREAM_ARG sarg;
        +
        +	if (!aux || !aux->asn1_cb)
        +		{
        +		ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
        +		return NULL;
        +		}
        +	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
        +	asn_bio = BIO_new(BIO_f_asn1());
        +
        +	/* ASN1 bio needs to be next to output BIO */
        +
        +	out = BIO_push(asn_bio, out);
        +
        +	if (!ndef_aux || !asn_bio || !out)
        +		goto err;
        +
        +	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
        +	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
        +
        +	/* Now let callback prepend any digest, cipher etc BIOs
        +	 * ASN1 structure needs.
        +	 */
        +
        +	sarg.out = out;
        +	sarg.ndef_bio = NULL;
        +	sarg.boundary = NULL;
        +
        +	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
        +		goto err;
        +
        +	ndef_aux->val = val;
        +	ndef_aux->it = it;
        +	ndef_aux->ndef_bio = sarg.ndef_bio;
        +	ndef_aux->boundary = sarg.boundary;
        +	ndef_aux->out = out;
        +
        +	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
        +
        +	return sarg.ndef_bio;
        +
        +	err:
        +	if (asn_bio)
        +		BIO_free(asn_bio);
        +	if (ndef_aux)
        +		OPENSSL_free(ndef_aux);
        +	return NULL;
        +	}
        +
        +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
        +	{
        +	NDEF_SUPPORT *ndef_aux;
        +	unsigned char *p;
        +	int derlen;
        +
        +	if (!parg)
        +		return 0;
        +
        +	ndef_aux = *(NDEF_SUPPORT **)parg;
        +
        +	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
        +	p = OPENSSL_malloc(derlen);
        +	ndef_aux->derbuf = p;
        +	*pbuf = p;
        +	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
        +
        +	if (!*ndef_aux->boundary)
        +		return 0;
        +
        +	*plen = *ndef_aux->boundary - *pbuf;
        +
        +	return 1;
        +	}
        +
        +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
        +	{
        +	NDEF_SUPPORT *ndef_aux;
        +
        +	if (!parg)
        +		return 0;
        +
        +	ndef_aux = *(NDEF_SUPPORT **)parg;
        +
        +	if (ndef_aux->derbuf)
        +		OPENSSL_free(ndef_aux->derbuf);
        +
        +	ndef_aux->derbuf = NULL;
        +	*pbuf = NULL;
        +	*plen = 0;
        +	return 1;
        +	}
        +
        +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
        +	{
        +	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
        +	if (!ndef_prefix_free(b, pbuf, plen, parg))
        +		return 0;
        +	OPENSSL_free(*pndef_aux);
        +	*pndef_aux = NULL;
        +	return 1;
        +	}
        +
        +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
        +	{
        +	NDEF_SUPPORT *ndef_aux;
        +	unsigned char *p;
        +	int derlen;
        +	const ASN1_AUX *aux;
        +	ASN1_STREAM_ARG sarg;
        +
        +	if (!parg)
        +		return 0;
        +
        +	ndef_aux = *(NDEF_SUPPORT **)parg;
        +
        +	aux = ndef_aux->it->funcs;
        +
        +	/* Finalize structures */
        +	sarg.ndef_bio = ndef_aux->ndef_bio;
        +	sarg.out = ndef_aux->out;
        +	sarg.boundary = ndef_aux->boundary;
        +	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
        +				&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
        +		return 0;
        +
        +	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
        +	p = OPENSSL_malloc(derlen);
        +	ndef_aux->derbuf = p;
        +	*pbuf = p;
        +	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
        +
        +	if (!*ndef_aux->boundary)
        +		return 0;
        +	*pbuf = *ndef_aux->boundary;
        +	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/charmap.h b/vendor/openssl/openssl/crypto/asn1/charmap.h
        new file mode 100644
        index 000000000..b55e63872
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/charmap.h
        @@ -0,0 +1,15 @@
        +/* Auto generated with chartype.pl script.
        + * Mask of various character properties
        + */
        +
        +static const 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/vendor/openssl/openssl/crypto/asn1/charmap.pl b/vendor/openssl/openssl/crypto/asn1/charmap.pl
        new file mode 100644
        index 000000000..2875c5986
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <<EOF;
        +/* Auto generated with chartype.pl script.
        + * Mask of various character properties
        + */
        +
        +static unsigned char char_type[] = {
        +EOF
        +
        +for($i = 0; $i < 128; $i++) {
        +	print("\n") if($i && (($i % 16) == 0));
        +	printf("%2d", $arr[$i]);
        +	print(",") if ($i != 127);
        +}
        +print("\n};\n\n");
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/d2i_pr.c b/vendor/openssl/openssl/crypto/asn1/d2i_pr.c
        new file mode 100644
        index 000000000..282894477
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/d2i_pr.c
        @@ -0,0 +1,170 @@
        +/* crypto/asn1/d2i_pr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include "asn1_locl.h"
        +
        +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
        +	     long length)
        +	{
        +	EVP_PKEY *ret;
        +
        +	if ((a == NULL) || (*a == NULL))
        +		{
        +		if ((ret=EVP_PKEY_new()) == NULL)
        +			{
        +			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_EVP_LIB);
        +			return(NULL);
        +			}
        +		}
        +	else
        +		{
        +		ret= *a;
        +#ifndef OPENSSL_NO_ENGINE
        +		if (ret->engine)
        +			{
        +			ENGINE_finish(ret->engine);
        +			ret->engine = NULL;
        +			}
        +#endif
        +		}
        +
        +	if (!EVP_PKEY_set_type(ret, type))
        +		{
        +		ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
        +		goto err;
        +		}
        +
        +	if (!ret->ameth->old_priv_decode ||
        +			!ret->ameth->old_priv_decode(ret, pp, length))
        +		{
        +		if (ret->ameth->priv_decode) 
        +			{
        +			PKCS8_PRIV_KEY_INFO *p8=NULL;
        +			p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
        +			if (!p8) goto err;
        +			EVP_PKEY_free(ret);
        +			ret = EVP_PKCS82PKEY(p8);
        +			PKCS8_PRIV_KEY_INFO_free(p8);
        +
        +			} 
        +		else 
        +			{
        +			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		}	
        +	if (a != NULL) (*a)=ret;
        +	return(ret);
        +err:
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
        +	return(NULL);
        +	}
        +
        +/* This works like d2i_PrivateKey() except it automatically works out the type */
        +
        +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
        +	     long length)
        +{
        +	STACK_OF(ASN1_TYPE) *inkey;
        +	const unsigned char *p;
        +	int keytype;
        +	p = *pp;
        +	/* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE):
        +	 * by analyzing it we can determine the passed structure: this
        +	 * assumes the input is surrounded by an ASN1 SEQUENCE.
        +	 */
        +	inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
        +	/* Since we only need to discern "traditional format" RSA and DSA
        +	 * keys we can just count the elements.
        +         */
        +	if(sk_ASN1_TYPE_num(inkey) == 6) 
        +		keytype = EVP_PKEY_DSA;
        +	else if (sk_ASN1_TYPE_num(inkey) == 4)
        +		keytype = EVP_PKEY_EC;
        +	else if (sk_ASN1_TYPE_num(inkey) == 3)  
        +		{ /* This seems to be PKCS8, not traditional format */
        +			PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
        +			EVP_PKEY *ret;
        +
        +			sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
        +			if (!p8) 
        +				{
        +				ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
        +				return NULL;
        +				}
        +			ret = EVP_PKCS82PKEY(p8);
        +			PKCS8_PRIV_KEY_INFO_free(p8);
        +			if (a) {
        +				*a = ret;
        +			}	
        +			return ret;
        +		}
        +	else keytype = EVP_PKEY_RSA;
        +	sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
        +	return d2i_PrivateKey(keytype, a, pp, length);
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/d2i_pu.c b/vendor/openssl/openssl/crypto/asn1/d2i_pu.c
        new file mode 100644
        index 000000000..c8f39ceb0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/d2i_pu.c
        @@ -0,0 +1,139 @@
        +/* crypto/asn1/d2i_pu.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/asn1.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_EC
        +#include <openssl/ec.h>
        +#endif
        +
        +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
        +	     long length)
        +	{
        +	EVP_PKEY *ret;
        +
        +	if ((a == NULL) || (*a == NULL))
        +		{
        +		if ((ret=EVP_PKEY_new()) == NULL)
        +			{
        +			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
        +			return(NULL);
        +			}
        +		}
        +	else	ret= *a;
        +
        +	if (!EVP_PKEY_set_type(ret, type))
        +		{
        +		ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +
        +	switch (EVP_PKEY_id(ret))
        +		{
        +#ifndef OPENSSL_NO_RSA
        +	case EVP_PKEY_RSA:
        +		if ((ret->pkey.rsa=d2i_RSAPublicKey(NULL,
        +			(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
        +			{
        +			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	case EVP_PKEY_DSA:
        +		if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
        +			(const unsigned char **)pp,length)) /* TMP UGLY CAST */
        +			{
        +			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	case EVP_PKEY_EC:
        +		if (!o2i_ECPublicKey(&(ret->pkey.ec),
        +				     (const unsigned char **)pp, length))
        +			{
        +			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +	break;
        +#endif
        +	default:
        +		ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
        +		goto err;
        +		/* break; */
        +		}
        +	if (a != NULL) (*a)=ret;
        +	return(ret);
        +err:
        +	if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
        +	return(NULL);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/evp_asn1.c b/vendor/openssl/openssl/crypto/asn1/evp_asn1.c
        new file mode 100644
        index 000000000..f3d980486
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/evp_asn1.c
        @@ -0,0 +1,189 @@
        +/* crypto/asn1/evp_asn1.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1_mac.h>
        +
        +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
        +	{
        +	ASN1_STRING *os;
        +
        +	if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0);
        +	if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0);
        +	ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os);
        +	return(1);
        +	}
        +
        +/* int max_len:  for returned value    */
        +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data,
        +	     int max_len)
        +	{
        +	int ret,num;
        +	unsigned char *p;
        +
        +	if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL))
        +		{
        +		ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
        +		return(-1);
        +		}
        +	p=M_ASN1_STRING_data(a->value.octet_string);
        +	ret=M_ASN1_STRING_length(a->value.octet_string);
        +	if (ret < max_len)
        +		num=ret;
        +	else
        +		num=max_len;
        +	memcpy(data,p,num);
        +	return(ret);
        +	}
        +
        +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
        +	     int len)
        +	{
        +	int n,size;
        +	ASN1_OCTET_STRING os,*osp;
        +	ASN1_INTEGER in;
        +	unsigned char *p;
        +	unsigned char buf[32]; /* when they have 256bit longs, 
        +				* I'll be in trouble */
        +	in.data=buf;
        +	in.length=32;
        +	os.data=data;
        +	os.type=V_ASN1_OCTET_STRING;
        +	os.length=len;
        +	ASN1_INTEGER_set(&in,num);
        +	n =  i2d_ASN1_INTEGER(&in,NULL);
        +	n+=M_i2d_ASN1_OCTET_STRING(&os,NULL);
        +
        +	size=ASN1_object_size(1,n,V_ASN1_SEQUENCE);
        +
        +	if ((osp=ASN1_STRING_new()) == NULL) return(0);
        +	/* Grow the 'string' */
        +	if (!ASN1_STRING_set(osp,NULL,size))
        +		{
        +		ASN1_STRING_free(osp);
        +		return(0);
        +		}
        +
        +	M_ASN1_STRING_length_set(osp, size);
        +	p=M_ASN1_STRING_data(osp);
        +
        +	ASN1_put_object(&p,1,n,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
        +	  i2d_ASN1_INTEGER(&in,&p);
        +	M_i2d_ASN1_OCTET_STRING(&os,&p);
        +
        +	ASN1_TYPE_set(a,V_ASN1_SEQUENCE,osp);
        +	return(1);
        +	}
        +
        +/* we return the actual length..., num may be missing, in which
        + * case, set it to zero */
        +/* int max_len:  for returned value    */
        +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
        +	     int max_len)
        +	{
        +	int ret= -1,n;
        +	ASN1_INTEGER *ai=NULL;
        +	ASN1_OCTET_STRING *os=NULL;
        +	const unsigned char *p;
        +	long length;
        +	ASN1_const_CTX c;
        +
        +	if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL))
        +		{
        +		goto err;
        +		}
        +	p=M_ASN1_STRING_data(a->value.sequence);
        +	length=M_ASN1_STRING_length(a->value.sequence);
        +
        +	c.pp= &p;
        +	c.p=p;
        +	c.max=p+length;
        +	c.error=ASN1_R_DATA_IS_WRONG;
        +
        +	M_ASN1_D2I_start_sequence();
        +	c.q=c.p;
        +	if ((ai=d2i_ASN1_INTEGER(NULL,&c.p,c.slen)) == NULL) goto err;
        +        c.slen-=(c.p-c.q);
        +	c.q=c.p;
        +	if ((os=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) goto err;
        +        c.slen-=(c.p-c.q);
        +	if (!M_ASN1_D2I_end_sequence()) goto err;
        +
        +	if (num != NULL)
        +		*num=ASN1_INTEGER_get(ai);
        +
        +	ret=M_ASN1_STRING_length(os);
        +	if (max_len > ret)
        +		n=ret;
        +	else
        +		n=max_len;
        +
        +	if (data != NULL)
        +		memcpy(data,M_ASN1_STRING_data(os),n);
        +	if (0)
        +		{
        +err:
        +		ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
        +		}
        +	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
        +	if (ai != NULL) M_ASN1_INTEGER_free(ai);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/f_enum.c b/vendor/openssl/openssl/crypto/asn1/f_enum.c
        new file mode 100644
        index 000000000..56e3cc8df
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/f_enum.c
        @@ -0,0 +1,207 @@
        +/* crypto/asn1/f_enum.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1.h>
        +
        +/* Based on a_int.c: equivalent ENUMERATED functions */
        +
        +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
        +	{
        +	int i,n=0;
        +	static const char *h="0123456789ABCDEF";
        +	char buf[2];
        +
        +	if (a == NULL) return(0);
        +
        +	if (a->length == 0)
        +		{
        +		if (BIO_write(bp,"00",2) != 2) goto err;
        +		n=2;
        +		}
        +	else
        +		{
        +		for (i=0; i<a->length; i++)
        +			{
        +			if ((i != 0) && (i%35 == 0))
        +				{
        +				if (BIO_write(bp,"\\\n",2) != 2) goto err;
        +				n+=2;
        +				}
        +			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
        +			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
        +			if (BIO_write(bp,buf,2) != 2) goto err;
        +			n+=2;
        +			}
        +		}
        +	return(n);
        +err:
        +	return(-1);
        +	}
        +
        +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
        +	{
        +	int ret=0;
        +	int i,j,k,m,n,again,bufsize;
        +	unsigned char *s=NULL,*sp;
        +	unsigned char *bufp;
        +	int num=0,slen=0,first=1;
        +
        +	bs->type=V_ASN1_ENUMERATED;
        +
        +	bufsize=BIO_gets(bp,buf,size);
        +	for (;;)
        +		{
        +		if (bufsize < 1) goto err_sl;
        +		i=bufsize;
        +		if (buf[i-1] == '\n') buf[--i]='\0';
        +		if (i == 0) goto err_sl;
        +		if (buf[i-1] == '\r') buf[--i]='\0';
        +		if (i == 0) goto err_sl;
        +		again=(buf[i-1] == '\\');
        +
        +		for (j=0; j<i; j++)
        +			{
        +			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
        +				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
        +				((buf[j] >= 'A') && (buf[j] <= 'F'))))
        +				{
        +				i=j;
        +				break;
        +				}
        +			}
        +		buf[i]='\0';
        +		/* We have now cleared all the crap off the end of the
        +		 * line */
        +		if (i < 2) goto err_sl;
        +
        +		bufp=(unsigned char *)buf;
        +		if (first)
        +			{
        +			first=0;
        +			if ((bufp[0] == '0') && (buf[1] == '0'))
        +				{
        +				bufp+=2;
        +				i-=2;
        +				}
        +			}
        +		k=0;
        +		i-=again;
        +		if (i%2 != 0)
        +			{
        +			ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
        +			goto err;
        +			}
        +		i/=2;
        +		if (num+i > slen)
        +			{
        +			if (s == NULL)
        +				sp=(unsigned char *)OPENSSL_malloc(
        +					(unsigned int)num+i*2);
        +			else
        +				sp=(unsigned char *)OPENSSL_realloc(s,
        +					(unsigned int)num+i*2);
        +			if (sp == NULL)
        +				{
        +				ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
        +				if (s != NULL) OPENSSL_free(s);
        +				goto err;
        +				}
        +			s=sp;
        +			slen=num+i*2;
        +			}
        +		for (j=0; j<i; j++,k+=2)
        +			{
        +			for (n=0; n<2; n++)
        +				{
        +				m=bufp[k+n];
        +				if ((m >= '0') && (m <= '9'))
        +					m-='0';
        +				else if ((m >= 'a') && (m <= 'f'))
        +					m=m-'a'+10;
        +				else if ((m >= 'A') && (m <= 'F'))
        +					m=m-'A'+10;
        +				else
        +					{
        +					ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_NON_HEX_CHARACTERS);
        +					goto err;
        +					}
        +				s[num+j]<<=4;
        +				s[num+j]|=m;
        +				}
        +			}
        +		num+=i;
        +		if (again)
        +			bufsize=BIO_gets(bp,buf,size);
        +		else
        +			break;
        +		}
        +	bs->length=num;
        +	bs->data=s;
        +	ret=1;
        +err:
        +	if (0)
        +		{
        +err_sl:
        +		ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
        +		}
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/f_int.c b/vendor/openssl/openssl/crypto/asn1/f_int.c
        new file mode 100644
        index 000000000..9494e597a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/f_int.c
        @@ -0,0 +1,219 @@
        +/* crypto/asn1/f_int.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1.h>
        +
        +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
        +	{
        +	int i,n=0;
        +	static const char *h="0123456789ABCDEF";
        +	char buf[2];
        +
        +	if (a == NULL) return(0);
        +
        +	if (a->type & V_ASN1_NEG)
        +		{
        +		if (BIO_write(bp, "-", 1) != 1) goto err;
        +		n = 1;
        +		}
        +
        +	if (a->length == 0)
        +		{
        +		if (BIO_write(bp,"00",2) != 2) goto err;
        +		n += 2;
        +		}
        +	else
        +		{
        +		for (i=0; i<a->length; i++)
        +			{
        +			if ((i != 0) && (i%35 == 0))
        +				{
        +				if (BIO_write(bp,"\\\n",2) != 2) goto err;
        +				n+=2;
        +				}
        +			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
        +			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
        +			if (BIO_write(bp,buf,2) != 2) goto err;
        +			n+=2;
        +			}
        +		}
        +	return(n);
        +err:
        +	return(-1);
        +	}
        +
        +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
        +	{
        +	int ret=0;
        +	int i,j,k,m,n,again,bufsize;
        +	unsigned char *s=NULL,*sp;
        +	unsigned char *bufp;
        +	int num=0,slen=0,first=1;
        +
        +	bs->type=V_ASN1_INTEGER;
        +
        +	bufsize=BIO_gets(bp,buf,size);
        +	for (;;)
        +		{
        +		if (bufsize < 1) goto err_sl;
        +		i=bufsize;
        +		if (buf[i-1] == '\n') buf[--i]='\0';
        +		if (i == 0) goto err_sl;
        +		if (buf[i-1] == '\r') buf[--i]='\0';
        +		if (i == 0) goto err_sl;
        +		again=(buf[i-1] == '\\');
        +
        +		for (j=0; j<i; j++)
        +			{
        +#ifndef CHARSET_EBCDIC
        +			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
        +				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
        +				((buf[j] >= 'A') && (buf[j] <= 'F'))))
        +#else
        +			/* This #ifdef is not strictly necessary, since
        +			 * the characters A...F a...f 0...9 are contiguous
        +			 * (yes, even in EBCDIC - but not the whole alphabet).
        +			 * Nevertheless, isxdigit() is faster.
        +			 */
        +			if (!isxdigit(buf[j]))
        +#endif
        +				{
        +				i=j;
        +				break;
        +				}
        +			}
        +		buf[i]='\0';
        +		/* We have now cleared all the crap off the end of the
        +		 * line */
        +		if (i < 2) goto err_sl;
        +
        +		bufp=(unsigned char *)buf;
        +		if (first)
        +			{
        +			first=0;
        +			if ((bufp[0] == '0') && (buf[1] == '0'))
        +				{
        +				bufp+=2;
        +				i-=2;
        +				}
        +			}
        +		k=0;
        +		i-=again;
        +		if (i%2 != 0)
        +			{
        +			ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_ODD_NUMBER_OF_CHARS);
        +			goto err;
        +			}
        +		i/=2;
        +		if (num+i > slen)
        +			{
        +			if (s == NULL)
        +				sp=(unsigned char *)OPENSSL_malloc(
        +					(unsigned int)num+i*2);
        +			else
        +				sp=OPENSSL_realloc_clean(s,slen,num+i*2);
        +			if (sp == NULL)
        +				{
        +				ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
        +				if (s != NULL) OPENSSL_free(s);
        +				goto err;
        +				}
        +			s=sp;
        +			slen=num+i*2;
        +			}
        +		for (j=0; j<i; j++,k+=2)
        +			{
        +			for (n=0; n<2; n++)
        +				{
        +				m=bufp[k+n];
        +				if ((m >= '0') && (m <= '9'))
        +					m-='0';
        +				else if ((m >= 'a') && (m <= 'f'))
        +					m=m-'a'+10;
        +				else if ((m >= 'A') && (m <= 'F'))
        +					m=m-'A'+10;
        +				else
        +					{
        +					ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_NON_HEX_CHARACTERS);
        +					goto err;
        +					}
        +				s[num+j]<<=4;
        +				s[num+j]|=m;
        +				}
        +			}
        +		num+=i;
        +		if (again)
        +			bufsize=BIO_gets(bp,buf,size);
        +		else
        +			break;
        +		}
        +	bs->length=num;
        +	bs->data=s;
        +	ret=1;
        +err:
        +	if (0)
        +		{
        +err_sl:
        +		ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_SHORT_LINE);
        +		}
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/f_string.c b/vendor/openssl/openssl/crypto/asn1/f_string.c
        new file mode 100644
        index 000000000..968698a79
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/f_string.c
        @@ -0,0 +1,212 @@
        +/* crypto/asn1/f_string.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1.h>
        +
        +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
        +	{
        +	int i,n=0;
        +	static const char *h="0123456789ABCDEF";
        +	char buf[2];
        +
        +	if (a == NULL) return(0);
        +
        +	if (a->length == 0)
        +		{
        +		if (BIO_write(bp,"0",1) != 1) goto err;
        +		n=1;
        +		}
        +	else
        +		{
        +		for (i=0; i<a->length; i++)
        +			{
        +			if ((i != 0) && (i%35 == 0))
        +				{
        +				if (BIO_write(bp,"\\\n",2) != 2) goto err;
        +				n+=2;
        +				}
        +			buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
        +			buf[1]=h[((unsigned char)a->data[i]   )&0x0f];
        +			if (BIO_write(bp,buf,2) != 2) goto err;
        +			n+=2;
        +			}
        +		}
        +	return(n);
        +err:
        +	return(-1);
        +	}
        +
        +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
        +	{
        +	int ret=0;
        +	int i,j,k,m,n,again,bufsize;
        +	unsigned char *s=NULL,*sp;
        +	unsigned char *bufp;
        +	int num=0,slen=0,first=1;
        +
        +	bufsize=BIO_gets(bp,buf,size);
        +	for (;;)
        +		{
        +		if (bufsize < 1)
        +			{
        +			if (first)
        +				break;
        +			else
        +				goto err_sl;
        +			}
        +		first=0;
        +
        +		i=bufsize;
        +		if (buf[i-1] == '\n') buf[--i]='\0';
        +		if (i == 0) goto err_sl;
        +		if (buf[i-1] == '\r') buf[--i]='\0';
        +		if (i == 0) goto err_sl;
        +		again=(buf[i-1] == '\\');
        +
        +		for (j=i-1; j>0; j--)
        +			{
        +#ifndef CHARSET_EBCDIC
        +			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
        +				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
        +				((buf[j] >= 'A') && (buf[j] <= 'F'))))
        +#else
        +			/* This #ifdef is not strictly necessary, since
        +			 * the characters A...F a...f 0...9 are contiguous
        +			 * (yes, even in EBCDIC - but not the whole alphabet).
        +			 * Nevertheless, isxdigit() is faster.
        +			 */
        +			if (!isxdigit(buf[j]))
        +#endif
        +				{
        +				i=j;
        +				break;
        +				}
        +			}
        +		buf[i]='\0';
        +		/* We have now cleared all the crap off the end of the
        +		 * line */
        +		if (i < 2) goto err_sl;
        +
        +		bufp=(unsigned char *)buf;
        +
        +		k=0;
        +		i-=again;
        +		if (i%2 != 0)
        +			{
        +			ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_ODD_NUMBER_OF_CHARS);
        +			goto err;
        +			}
        +		i/=2;
        +		if (num+i > slen)
        +			{
        +			if (s == NULL)
        +				sp=(unsigned char *)OPENSSL_malloc(
        +					(unsigned int)num+i*2);
        +			else
        +				sp=(unsigned char *)OPENSSL_realloc(s,
        +					(unsigned int)num+i*2);
        +			if (sp == NULL)
        +				{
        +				ASN1err(ASN1_F_A2I_ASN1_STRING,ERR_R_MALLOC_FAILURE);
        +				if (s != NULL) OPENSSL_free(s);
        +				goto err;
        +				}
        +			s=sp;
        +			slen=num+i*2;
        +			}
        +		for (j=0; j<i; j++,k+=2)
        +			{
        +			for (n=0; n<2; n++)
        +				{
        +				m=bufp[k+n];
        +				if ((m >= '0') && (m <= '9'))
        +					m-='0';
        +				else if ((m >= 'a') && (m <= 'f'))
        +					m=m-'a'+10;
        +				else if ((m >= 'A') && (m <= 'F'))
        +					m=m-'A'+10;
        +				else
        +					{
        +					ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_NON_HEX_CHARACTERS);
        +					goto err;
        +					}
        +				s[num+j]<<=4;
        +				s[num+j]|=m;
        +				}
        +			}
        +		num+=i;
        +		if (again)
        +			bufsize=BIO_gets(bp,buf,size);
        +		else
        +			break;
        +		}
        +	bs->length=num;
        +	bs->data=s;
        +	ret=1;
        +err:
        +	if (0)
        +		{
        +err_sl:
        +		ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_SHORT_LINE);
        +		}
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/i2d_pr.c b/vendor/openssl/openssl/crypto/asn1/i2d_pr.c
        new file mode 100644
        index 000000000..e398b6266
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/i2d_pr.c
        @@ -0,0 +1,80 @@
        +/* crypto/asn1/i2d_pr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include "asn1_locl.h"
        +
        +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
        +	{
        +	if (a->ameth && a->ameth->old_priv_encode)
        +		{
        +		return a->ameth->old_priv_encode(a, pp);
        +		}
        +	if (a->ameth && a->ameth->priv_encode) {
        +		PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
        +		int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
        +		PKCS8_PRIV_KEY_INFO_free(p8);
        +		return ret;
        +	}	
        +	ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
        +	return(-1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/i2d_pu.c b/vendor/openssl/openssl/crypto/asn1/i2d_pu.c
        new file mode 100644
        index 000000000..34286dbd3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/i2d_pu.c
        @@ -0,0 +1,95 @@
        +/* crypto/asn1/i2d_pu.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_EC
        +#include <openssl/ec.h>
        +#endif
        +
        +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
        +	{
        +	switch (a->type)
        +		{
        +#ifndef OPENSSL_NO_RSA
        +	case EVP_PKEY_RSA:
        +		return(i2d_RSAPublicKey(a->pkey.rsa,pp));
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	case EVP_PKEY_DSA:
        +		return(i2d_DSAPublicKey(a->pkey.dsa,pp));
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	case EVP_PKEY_EC:
        +		return(i2o_ECPublicKey(a->pkey.ec, pp));
        +#endif
        +	default:
        +		ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
        +		return(-1);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/n_pkey.c b/vendor/openssl/openssl/crypto/asn1/n_pkey.c
        new file mode 100644
        index 000000000..e25173993
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/n_pkey.c
        @@ -0,0 +1,353 @@
        +/* crypto/asn1/n_pkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#include <openssl/objects.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/asn1_mac.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +
        +#ifndef OPENSSL_NO_RC4
        +
        +typedef struct netscape_pkey_st
        +	{
        +	long version;
        +	X509_ALGOR *algor;
        +	ASN1_OCTET_STRING *private_key;
        +	} NETSCAPE_PKEY;
        +
        +typedef struct netscape_encrypted_pkey_st
        +	{
        +	ASN1_OCTET_STRING *os;
        +	/* This is the same structure as DigestInfo so use it:
        +	 * although this isn't really anything to do with
        +	 * digests.
        +	 */
        +	X509_SIG *enckey;
        +	} NETSCAPE_ENCRYPTED_PKEY;
        +
        +
        +ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
        +	ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
        +} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
        +
        +DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
        +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
        +
        +ASN1_SEQUENCE(NETSCAPE_PKEY) = {
        +	ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
        +	ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
        +	ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(NETSCAPE_PKEY)
        +
        +DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
        +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
        +
        +static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
        +			  int (*cb)(char *buf, int len, const char *prompt,
        +				    int verify),
        +			  int sgckey);
        +
        +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
        +		     int (*cb)(char *buf, int len, const char *prompt,
        +			       int verify))
        +{
        +	return i2d_RSA_NET(a, pp, cb, 0);
        +}
        +
        +int i2d_RSA_NET(const RSA *a, unsigned char **pp,
        +		int (*cb)(char *buf, int len, const char *prompt, int verify),
        +		int sgckey)
        +	{
        +	int i, j, ret = 0;
        +	int rsalen, pkeylen, olen;
        +	NETSCAPE_PKEY *pkey = NULL;
        +	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
        +	unsigned char buf[256],*zz;
        +	unsigned char key[EVP_MAX_KEY_LENGTH];
        +	EVP_CIPHER_CTX ctx;
        +	EVP_CIPHER_CTX_init(&ctx);
        +
        +	if (a == NULL) return(0);
        +
        +	if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
        +	if ((enckey=NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) goto err;
        +	pkey->version = 0;
        +
        +	pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
        +	if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
        +	pkey->algor->parameter->type=V_ASN1_NULL;
        +
        +	rsalen = i2d_RSAPrivateKey(a, NULL);
        +
        +	/* Fake some octet strings just for the initial length
        +	 * calculation.
        + 	 */
        +
        +	pkey->private_key->length=rsalen;
        +
        +	pkeylen=i2d_NETSCAPE_PKEY(pkey,NULL);
        +
        +	enckey->enckey->digest->length = pkeylen;
        +
        +	enckey->os->length = 11;	/* "private-key" */
        +
        +	enckey->enckey->algor->algorithm=OBJ_nid2obj(NID_rc4);
        +	if ((enckey->enckey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
        +	enckey->enckey->algor->parameter->type=V_ASN1_NULL;
        +
        +	if (pp == NULL)
        +		{
        +		olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
        +		NETSCAPE_PKEY_free(pkey);
        +		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
        +		return olen;
        +		}
        +
        +
        +	/* Since its RC4 encrypted length is actual length */
        +	if ((zz=(unsigned char *)OPENSSL_malloc(rsalen)) == NULL)
        +		{
        +		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	pkey->private_key->data = zz;
        +	/* Write out private key encoding */
        +	i2d_RSAPrivateKey(a,&zz);
        +
        +	if ((zz=OPENSSL_malloc(pkeylen)) == NULL)
        +		{
        +		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!ASN1_STRING_set(enckey->os, "private-key", -1)) 
        +		{
        +		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	enckey->enckey->digest->data = zz;
        +	i2d_NETSCAPE_PKEY(pkey,&zz);
        +
        +	/* Wipe the private key encoding */
        +	OPENSSL_cleanse(pkey->private_key->data, rsalen);
        +		
        +	if (cb == NULL)
        +		cb=EVP_read_pw_string;
        +	i=cb((char *)buf,256,"Enter Private Key password:",1);
        +	if (i != 0)
        +		{
        +		ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ);
        +		goto err;
        +		}
        +	i = strlen((char *)buf);
        +	/* If the key is used for SGC the algorithm is modified a little. */
        +	if(sgckey) {
        +		if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
        +			goto err;
        +		memcpy(buf + 16, "SGCKEYSALT", 10);
        +		i = 26;
        +	}
        +
        +	if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
        +		goto err;
        +	OPENSSL_cleanse(buf,256);
        +
        +	/* Encrypt private key in place */
        +	zz = enckey->enckey->digest->data;
        +	if (!EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL))
        +		goto err;
        +	if (!EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen))
        +		goto err;
        +	if (!EVP_EncryptFinal_ex(&ctx,zz + i,&j))
        +		goto err;
        +
        +	ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
        +err:
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
        +	NETSCAPE_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +
        +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
        +		      int (*cb)(char *buf, int len, const char *prompt,
        +				int verify))
        +{
        +	return d2i_RSA_NET(a, pp, length, cb, 0);
        +}
        +
        +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
        +		 int (*cb)(char *buf, int len, const char *prompt, int verify),
        +		 int sgckey)
        +	{
        +	RSA *ret=NULL;
        +	const unsigned char *p;
        +	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
        +
        +	p = *pp;
        +
        +	enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
        +	if(!enckey) {
        +		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR);
        +		return NULL;
        +	}
        +
        +	if ((enckey->os->length != 11) || (strncmp("private-key",
        +		(char *)enckey->os->data,11) != 0))
        +		{
        +		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING);
        +		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
        +		return NULL;
        +		}
        +	if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4)
        +		{
        +		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
        +		goto err;
        +	}
        +	if (cb == NULL)
        +		cb=EVP_read_pw_string;
        +	if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;
        +
        +	*pp = p;
        +
        +	err:
        +	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
        +	return ret;
        +
        +	}
        +
        +static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
        +			  int (*cb)(char *buf, int len, const char *prompt,
        +				    int verify), int sgckey)
        +	{
        +	NETSCAPE_PKEY *pkey=NULL;
        +	RSA *ret=NULL;
        +	int i,j;
        +	unsigned char buf[256];
        +	const unsigned char *zz;
        +	unsigned char key[EVP_MAX_KEY_LENGTH];
        +	EVP_CIPHER_CTX ctx;
        +	EVP_CIPHER_CTX_init(&ctx);
        +
        +	i=cb((char *)buf,256,"Enter Private Key password:",0);
        +	if (i != 0)
        +		{
        +		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ);
        +		goto err;
        +		}
        +
        +	i = strlen((char *)buf);
        +	if(sgckey){
        +		if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
        +			goto err;
        +		memcpy(buf + 16, "SGCKEYSALT", 10);
        +		i = 26;
        +	}
        +		
        +	if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
        +		goto err;
        +	OPENSSL_cleanse(buf,256);
        +
        +	if (!EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL))
        +		goto err;
        +	if (!EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length))
        +		goto err;
        +	if (!EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j))
        +		goto err;
        +	os->length=i+j;
        +
        +	zz=os->data;
        +
        +	if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL)
        +		{
        +		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
        +		goto err;
        +		}
        +		
        +	zz=pkey->private_key->data;
        +	if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL)
        +		{
        +		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
        +		goto err;
        +		}
        +err:
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	NETSCAPE_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +#endif /* OPENSSL_NO_RC4 */
        +
        +#else /* !OPENSSL_NO_RSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/asn1/nsseq.c b/vendor/openssl/openssl/crypto/asn1/nsseq.c
        new file mode 100644
        index 000000000..b8c420223
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/nsseq.c
        @@ -0,0 +1,83 @@
        +/* nsseq.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +
        +static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +{
        +	if(operation == ASN1_OP_NEW_POST) {
        +		NETSCAPE_CERT_SEQUENCE *nsseq;
        +		nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
        +		nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
        +	}
        +	return 1;
        +}
        +
        +/* Netscape certificate sequence structure */
        +
        +ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
        +	ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
        +	ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
        +} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
        diff --git a/vendor/openssl/openssl/crypto/asn1/p5_pbe.c b/vendor/openssl/openssl/crypto/asn1/p5_pbe.c
        new file mode 100644
        index 000000000..94bc38b99
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/p5_pbe.c
        @@ -0,0 +1,148 @@
        +/* p5_pbe.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/rand.h>
        +
        +/* PKCS#5 password based encryption structure */
        +
        +ASN1_SEQUENCE(PBEPARAM) = {
        +	ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(PBEPARAM)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
        +
        +
        +/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
        +
        +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
        +				const unsigned char *salt, int saltlen)
        +	{
        +	PBEPARAM *pbe=NULL;
        +	ASN1_STRING *pbe_str=NULL;
        +	unsigned char *sstr;
        +
        +	pbe = PBEPARAM_new();
        +	if (!pbe)
        +		{
        +		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if(iter <= 0)
        +		iter = PKCS5_DEFAULT_ITER;
        +	if (!ASN1_INTEGER_set(pbe->iter, iter))
        +		{
        +		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if (!saltlen)
        +		saltlen = PKCS5_SALT_LEN;
        +	if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
        +		{
        +		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	sstr = ASN1_STRING_data(pbe->salt);
        +	if (salt)
        +		memcpy(sstr, salt, saltlen);
        +	else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
        +		goto err;
        +
        +	if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
        +		{
        +		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	PBEPARAM_free(pbe);
        +	pbe = NULL;
        +
        +	if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
        +		return 1;
        +
        +err:
        +	if (pbe != NULL)
        +		PBEPARAM_free(pbe);
        +	if (pbe_str != NULL)
        +		ASN1_STRING_free(pbe_str);
        +	return 0;
        +	}
        +
        +/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
        +
        +X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
        +				const unsigned char *salt, int saltlen)
        +	{
        +	X509_ALGOR *ret;
        +	ret = X509_ALGOR_new();
        +	if (!ret)
        +		{
        +		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) 
        +		return ret;
        +
        +	X509_ALGOR_free(ret);
        +	return NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/p5_pbev2.c b/vendor/openssl/openssl/crypto/asn1/p5_pbev2.c
        new file mode 100644
        index 000000000..4ea683036
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/p5_pbev2.c
        @@ -0,0 +1,280 @@
        +/* p5_pbev2.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999-2004.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/rand.h>
        +
        +/* PKCS#5 v2.0 password based encryption structures */
        +
        +ASN1_SEQUENCE(PBE2PARAM) = {
        +	ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
        +	ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
        +} ASN1_SEQUENCE_END(PBE2PARAM)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
        +
        +ASN1_SEQUENCE(PBKDF2PARAM) = {
        +	ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
        +	ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
        +	ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
        +	ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
        +} ASN1_SEQUENCE_END(PBKDF2PARAM)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
        +
        +/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
        + * yes I know this is horrible!
        + *
        + * Extended version to allow application supplied PRF NID and IV.
        + */
        +
        +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
        +				 unsigned char *salt, int saltlen,
        +				 unsigned char *aiv, int prf_nid)
        +{
        +	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
        +	int alg_nid, keylen;
        +	EVP_CIPHER_CTX ctx;
        +	unsigned char iv[EVP_MAX_IV_LENGTH];
        +	PBE2PARAM *pbe2 = NULL;
        +	ASN1_OBJECT *obj;
        +
        +	alg_nid = EVP_CIPHER_type(cipher);
        +	if(alg_nid == NID_undef) {
        +		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
        +				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        +		goto err;
        +	}
        +	obj = OBJ_nid2obj(alg_nid);
        +
        +	if(!(pbe2 = PBE2PARAM_new())) goto merr;
        +
        +	/* Setup the AlgorithmIdentifier for the encryption scheme */
        +	scheme = pbe2->encryption;
        +
        +	scheme->algorithm = obj;
        +	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
        +
        +	/* Create random IV */
        +	if (EVP_CIPHER_iv_length(cipher))
        +		{
        +		if (aiv)
        +			memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
        +		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
        +  			goto err;
        +		}
        +
        +	EVP_CIPHER_CTX_init(&ctx);
        +
        +	/* Dummy cipherinit to just setup the IV, and PRF */
        +	if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
        +		goto err;
        +	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
        +		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
        +					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +		goto err;
        +	}
        +	/* If prf NID unspecified see if cipher has a preference.
        +	 * An error is OK here: just means use default PRF.
        +	 */
        +	if ((prf_nid == -1) && 
        +	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
        +		{
        +		ERR_clear_error();
        +		prf_nid = NID_hmacWithSHA1;
        +		}
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +
        +	/* If its RC2 then we'd better setup the key length */
        +
        +	if(alg_nid == NID_rc2_cbc)
        +		keylen = EVP_CIPHER_key_length(cipher);
        +	else
        +		keylen = -1;
        +
        +	/* Setup keyfunc */
        +
        +	X509_ALGOR_free(pbe2->keyfunc);
        +
        +	pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
        +
        +	if (!pbe2->keyfunc)
        +		goto merr;
        +
        +	/* Now set up top level AlgorithmIdentifier */
        +
        +	if(!(ret = X509_ALGOR_new())) goto merr;
        +	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;
        +
        +	ret->algorithm = OBJ_nid2obj(NID_pbes2);
        +
        +	/* Encode PBE2PARAM into parameter */
        +
        +	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
        +				 &ret->parameter->value.sequence)) goto merr;
        +	ret->parameter->type = V_ASN1_SEQUENCE;
        +
        +	PBE2PARAM_free(pbe2);
        +	pbe2 = NULL;
        +
        +	return ret;
        +
        +	merr:
        +	ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);
        +
        +	err:
        +	PBE2PARAM_free(pbe2);
        +	/* Note 'scheme' is freed as part of pbe2 */
        +	X509_ALGOR_free(kalg);
        +	X509_ALGOR_free(ret);
        +
        +	return NULL;
        +
        +}
        +
        +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
        +				 unsigned char *salt, int saltlen)
        +	{
        +	return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
        +	}
        +
        +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
        +				int prf_nid, int keylen)
        +	{
        +	X509_ALGOR *keyfunc = NULL;
        +	PBKDF2PARAM *kdf = NULL;
        +	ASN1_OCTET_STRING *osalt = NULL;
        +
        +	if(!(kdf = PBKDF2PARAM_new()))
        +		goto merr;
        +	if(!(osalt = M_ASN1_OCTET_STRING_new()))
        +		goto merr;
        +
        +	kdf->salt->value.octet_string = osalt;
        +	kdf->salt->type = V_ASN1_OCTET_STRING;
        +
        +	if (!saltlen)
        +		saltlen = PKCS5_SALT_LEN;
        +	if (!(osalt->data = OPENSSL_malloc (saltlen)))
        +		goto merr;
        +
        +	osalt->length = saltlen;
        +
        +	if (salt)
        +		memcpy (osalt->data, salt, saltlen);
        +	else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0)
        +		goto merr;
        +
        +	if(iter <= 0)
        +		iter = PKCS5_DEFAULT_ITER;
        +
        +	if(!ASN1_INTEGER_set(kdf->iter, iter))
        +		goto merr;
        +
        +	/* If have a key len set it up */
        +
        +	if(keylen > 0) 
        +		{
        +		if(!(kdf->keylength = M_ASN1_INTEGER_new()))
        +			goto merr;
        +		if(!ASN1_INTEGER_set (kdf->keylength, keylen))
        +			goto merr;
        +		}
        +
        +	/* prf can stay NULL if we are using hmacWithSHA1 */
        +	if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1)
        +		{
        +		kdf->prf = X509_ALGOR_new();
        +		if (!kdf->prf)
        +			goto merr;
        +		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
        +					V_ASN1_NULL, NULL);
        +		}
        +
        +	/* Finally setup the keyfunc structure */
        +
        +	keyfunc = X509_ALGOR_new();
        +	if (!keyfunc)
        +		goto merr;
        +
        +	keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
        +
        +	/* Encode PBKDF2PARAM into parameter of pbe2 */
        +
        +	if(!(keyfunc->parameter = ASN1_TYPE_new()))
        +		goto merr;
        +
        +	if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
        +			 &keyfunc->parameter->value.sequence))
        +		goto merr;
        +	keyfunc->parameter->type = V_ASN1_SEQUENCE;
        +
        +	PBKDF2PARAM_free(kdf);
        +	return keyfunc;
        +
        +	merr:
        +	ASN1err(ASN1_F_PKCS5_PBKDF2_SET,ERR_R_MALLOC_FAILURE);
        +	PBKDF2PARAM_free(kdf);
        +	X509_ALGOR_free(keyfunc);
        +	return NULL;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/p8_pkey.c b/vendor/openssl/openssl/crypto/asn1/p8_pkey.c
        new file mode 100644
        index 000000000..17b68d386
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/p8_pkey.c
        @@ -0,0 +1,155 @@
        +/* p8_pkey.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +
        +/* Minor tweak to operation: zero private key data */
        +static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +{
        +	/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
        +	if(operation == ASN1_OP_FREE_PRE) {
        +		PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
        +		if (key->pkey->value.octet_string)
        +		OPENSSL_cleanse(key->pkey->value.octet_string->data,
        +			key->pkey->value.octet_string->length);
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
        +	ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
        +	ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
        +	ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
        +} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
        +
        +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
        +					int version,
        +					int ptype, void *pval,
        +					unsigned char *penc, int penclen)
        +	{
        +	unsigned char **ppenc = NULL;
        +	if (version >= 0)
        +		{
        +		if (!ASN1_INTEGER_set(priv->version, version))
        +			return 0;
        +		}
        +	if (penc)
        +		{
        +		int pmtype;
        +		ASN1_OCTET_STRING *oct;
        +		oct = ASN1_OCTET_STRING_new();
        +		if (!oct)
        +			return 0;
        +		oct->data = penc;
        +		ppenc = &oct->data;
        +		oct->length = penclen;
        +		if (priv->broken == PKCS8_NO_OCTET)
        +			pmtype = V_ASN1_SEQUENCE;
        +		else
        +			pmtype = V_ASN1_OCTET_STRING;
        +		ASN1_TYPE_set(priv->pkey, pmtype, oct);
        +		}
        +	if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
        +		{
        +		/* If call fails do not swallow 'enc' */
        +		if (ppenc)
        +			*ppenc = NULL;
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
        +		const unsigned char **pk, int *ppklen,
        +		X509_ALGOR **pa,
        +		PKCS8_PRIV_KEY_INFO *p8)
        +	{
        +	if (ppkalg)
        +		*ppkalg = p8->pkeyalg->algorithm;
        +	if(p8->pkey->type == V_ASN1_OCTET_STRING)
        +		{
        +		p8->broken = PKCS8_OK;
        +		if (pk)
        +			{
        +			*pk = p8->pkey->value.octet_string->data;
        +			*ppklen = p8->pkey->value.octet_string->length;
        +			}
        +		}
        +	else if (p8->pkey->type == V_ASN1_SEQUENCE)
        +		{
        +		p8->broken = PKCS8_NO_OCTET;
        +		if (pk)
        +			{
        +			*pk = p8->pkey->value.sequence->data;
        +			*ppklen = p8->pkey->value.sequence->length;
        +			}
        +		}
        +	else
        +		return 0;
        +	if (pa)
        +		*pa = p8->pkeyalg;
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_bitst.c b/vendor/openssl/openssl/crypto/asn1/t_bitst.c
        new file mode 100644
        index 000000000..2e59a25fa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_bitst.c
        @@ -0,0 +1,102 @@
        +/* t_bitst.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
        +				BIT_STRING_BITNAME *tbl, int indent)
        +{
        +	BIT_STRING_BITNAME *bnam;
        +	char first = 1;
        +	BIO_printf(out, "%*s", indent, "");
        +	for(bnam = tbl; bnam->lname; bnam++) {
        +		if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
        +			if(!first) BIO_puts(out, ", ");
        +			BIO_puts(out, bnam->lname);
        +			first = 0;
        +		}
        +	}
        +	BIO_puts(out, "\n");
        +	return 1;
        +}
        +
        +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
        +				BIT_STRING_BITNAME *tbl)
        +{
        +	int bitnum;
        +	bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
        +	if(bitnum < 0) return 0;
        +	if(bs) {
        +		if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
        +			return 0;
        +	}
        +	return 1;
        +}
        +
        +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
        +{
        +	BIT_STRING_BITNAME *bnam;
        +	for(bnam = tbl; bnam->lname; bnam++) {
        +		if(!strcmp(bnam->sname, name) ||
        +			!strcmp(bnam->lname, name) ) return bnam->bitnum;
        +	}
        +	return -1;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_crl.c b/vendor/openssl/openssl/crypto/asn1/t_crl.c
        new file mode 100644
        index 000000000..c61169208
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_crl.c
        @@ -0,0 +1,132 @@
        +/* t_crl.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/bn.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		X509err(X509_F_X509_CRL_PRINT_FP,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=X509_CRL_print(b, x);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int X509_CRL_print(BIO *out, X509_CRL *x)
        +{
        +	STACK_OF(X509_REVOKED) *rev;
        +	X509_REVOKED *r;
        +	long l;
        +	int i;
        +	char *p;
        +
        +	BIO_printf(out, "Certificate Revocation List (CRL):\n");
        +	l = X509_CRL_get_version(x);
        +	BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
        +	i = OBJ_obj2nid(x->sig_alg->algorithm);
        +	X509_signature_print(out, x->sig_alg, NULL);
        +	p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
        +	BIO_printf(out,"%8sIssuer: %s\n","",p);
        +	OPENSSL_free(p);
        +	BIO_printf(out,"%8sLast Update: ","");
        +	ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x));
        +	BIO_printf(out,"\n%8sNext Update: ","");
        +	if (X509_CRL_get_nextUpdate(x))
        +		 ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x));
        +	else BIO_printf(out,"NONE");
        +	BIO_printf(out,"\n");
        +
        +	X509V3_extensions_print(out, "CRL extensions",
        +						x->crl->extensions, 0, 8);
        +
        +	rev = X509_CRL_get_REVOKED(x);
        +
        +	if(sk_X509_REVOKED_num(rev) > 0)
        +	    BIO_printf(out, "Revoked Certificates:\n");
        +	else BIO_printf(out, "No Revoked Certificates.\n");
        +
        +	for(i = 0; i < sk_X509_REVOKED_num(rev); i++) {
        +		r = sk_X509_REVOKED_value(rev, i);
        +		BIO_printf(out,"    Serial Number: ");
        +		i2a_ASN1_INTEGER(out,r->serialNumber);
        +		BIO_printf(out,"\n        Revocation Date: ");
        +		ASN1_TIME_print(out,r->revocationDate);
        +		BIO_printf(out,"\n");
        +		X509V3_extensions_print(out, "CRL entry extensions",
        +						r->extensions, 0, 8);
        +	}
        +	X509_signature_print(out, x->sig_alg, x->signature);
        +
        +	return 1;
        +
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_pkey.c b/vendor/openssl/openssl/crypto/asn1/t_pkey.c
        new file mode 100644
        index 000000000..9dd18f657
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_pkey.c
        @@ -0,0 +1,114 @@
        +/* crypto/asn1/t_pkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +#include <openssl/bn.h>
        +
        +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
        +			unsigned char *buf, int off)
        +	{
        +	int n,i;
        +	const char *neg;
        +
        +	if (num == NULL) return(1);
        +	neg = (BN_is_negative(num))?"-":"";
        +	if(!BIO_indent(bp,off,128))
        +		return 0;
        +	if (BN_is_zero(num))
        +		{
        +		if (BIO_printf(bp, "%s 0\n", number) <= 0)
        +			return 0;
        +		return 1;
        +		}
        +
        +	if (BN_num_bytes(num) <= BN_BYTES)
        +		{
        +		if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
        +			(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
        +			<= 0) return(0);
        +		}
        +	else
        +		{
        +		buf[0]=0;
        +		if (BIO_printf(bp,"%s%s",number,
        +			(neg[0] == '-')?" (Negative)":"") <= 0)
        +			return(0);
        +		n=BN_bn2bin(num,&buf[1]);
        +	
        +		if (buf[1] & 0x80)
        +			n++;
        +		else	buf++;
        +
        +		for (i=0; i<n; i++)
        +			{
        +			if ((i%15) == 0)
        +				{
        +				if(BIO_puts(bp,"\n") <= 0
        +				   || !BIO_indent(bp,off+4,128))
        +				    return 0;
        +				}
        +			if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
        +				<= 0) return(0);
        +			}
        +		if (BIO_write(bp,"\n",1) <= 0) return(0);
        +		}
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_req.c b/vendor/openssl/openssl/crypto/asn1/t_req.c
        new file mode 100644
        index 000000000..ea1794e3e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_req.c
        @@ -0,0 +1,266 @@
        +/* crypto/asn1/t_req.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/bn.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_FP_API
        +int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		X509err(X509_F_X509_REQ_PRINT_FP,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=X509_REQ_print(b, x);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag)
        +	{
        +	unsigned long l;
        +	int i;
        +	const char *neg;
        +	X509_REQ_INFO *ri;
        +	EVP_PKEY *pkey;
        +	STACK_OF(X509_ATTRIBUTE) *sk;
        +	STACK_OF(X509_EXTENSION) *exts;
        +	char mlch = ' ';
        +	int nmindent = 0;
        +
        +	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        +		mlch = '\n';
        +		nmindent = 12;
        +	}
        +
        +	if(nmflags == X509_FLAG_COMPAT)
        +		nmindent = 16;
        +
        +
        +	ri=x->req_info;
        +	if(!(cflag & X509_FLAG_NO_HEADER))
        +		{
        +		if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err;
        +		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_VERSION))
        +		{
        +		neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":"";
        +		l=0;
        +		for (i=0; i<ri->version->length; i++)
        +			{ l<<=8; l+=ri->version->data[i]; }
        +		if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,
        +			      l) <= 0)
        +		    goto err;
        +		}
        +        if(!(cflag & X509_FLAG_NO_SUBJECT))
        +                {
        +                if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
        +                if (X509_NAME_print_ex(bp,ri->subject,nmindent, nmflags) < 0) goto err;
        +                if (BIO_write(bp,"\n",1) <= 0) goto err;
        +                }
        +	if(!(cflag & X509_FLAG_NO_PUBKEY))
        +		{
        +		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
        +			goto err;
        +		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
        +			goto err;
        +		if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
        +			goto err;
        +		if (BIO_puts(bp, "\n") <= 0)
        +			goto err;
        +
        +		pkey=X509_REQ_get_pubkey(x);
        +		if (pkey == NULL)
        +			{
        +			BIO_printf(bp,"%12sUnable to load Public Key\n","");
        +			ERR_print_errors(bp);
        +			}
        +		else
        +			{
        +			EVP_PKEY_print_public(bp, pkey, 16, NULL);
        +			EVP_PKEY_free(pkey);
        +			}
        +		}
        +
        +	if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
        +		{
        +		/* may not be */
        +		if(BIO_printf(bp,"%8sAttributes:\n","") <= 0)
        +		    goto err;
        +
        +		sk=x->req_info->attributes;
        +		if (sk_X509_ATTRIBUTE_num(sk) == 0)
        +			{
        +			if(BIO_printf(bp,"%12sa0:00\n","") <= 0)
        +			    goto err;
        +			}
        +		else
        +			{
        +			for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
        +				{
        +				ASN1_TYPE *at;
        +				X509_ATTRIBUTE *a;
        +				ASN1_BIT_STRING *bs=NULL;
        +				ASN1_TYPE *t;
        +				int j,type=0,count=1,ii=0;
        +
        +				a=sk_X509_ATTRIBUTE_value(sk,i);
        +				if(X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
        +									continue;
        +				if(BIO_printf(bp,"%12s","") <= 0)
        +				    goto err;
        +				if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
        +				{
        +				if (a->single)
        +					{
        +					t=a->value.single;
        +					type=t->type;
        +					bs=t->value.bit_string;
        +					}
        +				else
        +					{
        +					ii=0;
        +					count=sk_ASN1_TYPE_num(a->value.set);
        +get_next:
        +					at=sk_ASN1_TYPE_value(a->value.set,ii);
        +					type=at->type;
        +					bs=at->value.asn1_string;
        +					}
        +				}
        +				for (j=25-j; j>0; j--)
        +					if (BIO_write(bp," ",1) != 1) goto err;
        +				if (BIO_puts(bp,":") <= 0) goto err;
        +				if (	(type == V_ASN1_PRINTABLESTRING) ||
        +					(type == V_ASN1_T61STRING) ||
        +					(type == V_ASN1_IA5STRING))
        +					{
        +					if (BIO_write(bp,(char *)bs->data,bs->length)
        +						!= bs->length)
        +						goto err;
        +					BIO_puts(bp,"\n");
        +					}
        +				else
        +					{
        +					BIO_puts(bp,"unable to print attribute\n");
        +					}
        +				if (++ii < count) goto get_next;
        +				}
        +			}
        +		}
        +	if(!(cflag & X509_FLAG_NO_EXTENSIONS))
        +		{
        +		exts = X509_REQ_get_extensions(x);
        +		if(exts)
        +			{
        +			BIO_printf(bp,"%8sRequested Extensions:\n","");
        +			for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
        +				{
        +				ASN1_OBJECT *obj;
        +				X509_EXTENSION *ex;
        +				int j;
        +				ex=sk_X509_EXTENSION_value(exts, i);
        +				if (BIO_printf(bp,"%12s","") <= 0) goto err;
        +				obj=X509_EXTENSION_get_object(ex);
        +				i2a_ASN1_OBJECT(bp,obj);
        +				j=X509_EXTENSION_get_critical(ex);
        +				if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
        +					goto err;
        +				if(!X509V3_EXT_print(bp, ex, cflag, 16))
        +					{
        +					BIO_printf(bp, "%16s", "");
        +					M_ASN1_OCTET_STRING_print(bp,ex->value);
        +					}
        +				if (BIO_write(bp,"\n",1) <= 0) goto err;
        +				}
        +			sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        +			}
        +		}
        +
        +	if(!(cflag & X509_FLAG_NO_SIGDUMP))
        +		{
        +		if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err;
        +		}
        +
        +	return(1);
        +err:
        +	X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB);
        +	return(0);
        +	}
        +
        +int X509_REQ_print(BIO *bp, X509_REQ *x)
        +	{
        +	return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_spki.c b/vendor/openssl/openssl/crypto/asn1/t_spki.c
        new file mode 100644
        index 000000000..079c081a8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_spki.c
        @@ -0,0 +1,107 @@
        +/* t_spki.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +/* Print out an SPKI */
        +
        +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
        +{
        +	EVP_PKEY *pkey;
        +	ASN1_IA5STRING *chal;
        +	int i, n;
        +	char *s;
        +	BIO_printf(out, "Netscape SPKI:\n");
        +	i=OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
        +	BIO_printf(out,"  Public Key Algorithm: %s\n",
        +				(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
        +	pkey = X509_PUBKEY_get(spki->spkac->pubkey);
        +	if(!pkey) BIO_printf(out, "  Unable to load public key\n");
        +	else
        +		{
        +		EVP_PKEY_print_public(out, pkey, 4, NULL);
        +		EVP_PKEY_free(pkey);
        +		}
        +	chal = spki->spkac->challenge;
        +	if(chal->length)
        +		BIO_printf(out, "  Challenge String: %s\n", chal->data);
        +	i=OBJ_obj2nid(spki->sig_algor->algorithm);
        +	BIO_printf(out,"  Signature Algorithm: %s",
        +				(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
        +
        +	n=spki->signature->length;
        +	s=(char *)spki->signature->data;
        +	for (i=0; i<n; i++)
        +		{
        +		if ((i%18) == 0) BIO_write(out,"\n      ",7);
        +		BIO_printf(out,"%02x%s",(unsigned char)s[i],
        +						((i+1) == n)?"":":");
        +		}
        +	BIO_write(out,"\n",1);
        +	return 1;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_x509.c b/vendor/openssl/openssl/crypto/asn1/t_x509.c
        new file mode 100644
        index 000000000..edbb39a02
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_x509.c
        @@ -0,0 +1,528 @@
        +/* crypto/asn1/t_x509.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_EC
        +#include <openssl/ec.h>
        +#endif
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include "asn1_locl.h"
        +
        +#ifndef OPENSSL_NO_FP_API
        +int X509_print_fp(FILE *fp, X509 *x)
        +	{
        +	return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
        +	}
        +
        +int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=X509_print_ex(b, x, nmflag, cflag);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int X509_print(BIO *bp, X509 *x)
        +{
        +	return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
        +}
        +
        +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
        +	{
        +	long l;
        +	int ret=0,i;
        +	char *m=NULL,mlch = ' ';
        +	int nmindent = 0;
        +	X509_CINF *ci;
        +	ASN1_INTEGER *bs;
        +	EVP_PKEY *pkey=NULL;
        +	const char *neg;
        +
        +	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        +			mlch = '\n';
        +			nmindent = 12;
        +	}
        +
        +	if(nmflags == X509_FLAG_COMPAT)
        +		nmindent = 16;
        +
        +	ci=x->cert_info;
        +	if(!(cflag & X509_FLAG_NO_HEADER))
        +		{
        +		if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
        +		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_VERSION))
        +		{
        +		l=X509_get_version(x);
        +		if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_SERIAL))
        +		{
        +
        +		if (BIO_write(bp,"        Serial Number:",22) <= 0) goto err;
        +
        +		bs=X509_get_serialNumber(x);
        +		if (bs->length <= (int)sizeof(long))
        +			{
        +			l=ASN1_INTEGER_get(bs);
        +			if (bs->type == V_ASN1_NEG_INTEGER)
        +				{
        +				l= -l;
        +				neg="-";
        +				}
        +			else
        +				neg="";
        +			if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
        +				goto err;
        +			}
        +		else
        +			{
        +			neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
        +			if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
        +
        +			for (i=0; i<bs->length; i++)
        +				{
        +				if (BIO_printf(bp,"%02x%c",bs->data[i],
        +					((i+1 == bs->length)?'\n':':')) <= 0)
        +					goto err;
        +				}
        +			}
        +
        +		}
        +
        +	if(!(cflag & X509_FLAG_NO_SIGNAME))
        +		{
        +		if(X509_signature_print(bp, x->sig_alg, NULL) <= 0)
        +			goto err;
        +#if 0
        +		if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0) 
        +			goto err;
        +		if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
        +			goto err;
        +		if (BIO_puts(bp, "\n") <= 0)
        +			goto err;
        +#endif
        +		}
        +
        +	if(!(cflag & X509_FLAG_NO_ISSUER))
        +		{
        +		if (BIO_printf(bp,"        Issuer:%c",mlch) <= 0) goto err;
        +		if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
        +		if (BIO_write(bp,"\n",1) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_VALIDITY))
        +		{
        +		if (BIO_write(bp,"        Validity\n",17) <= 0) goto err;
        +		if (BIO_write(bp,"            Not Before: ",24) <= 0) goto err;
        +		if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
        +		if (BIO_write(bp,"\n            Not After : ",25) <= 0) goto err;
        +		if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
        +		if (BIO_write(bp,"\n",1) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_SUBJECT))
        +		{
        +		if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
        +		if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
        +		if (BIO_write(bp,"\n",1) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_PUBKEY))
        +		{
        +		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
        +			goto err;
        +		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
        +			goto err;
        +		if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
        +			goto err;
        +		if (BIO_puts(bp, "\n") <= 0)
        +			goto err;
        +
        +		pkey=X509_get_pubkey(x);
        +		if (pkey == NULL)
        +			{
        +			BIO_printf(bp,"%12sUnable to load Public Key\n","");
        +			ERR_print_errors(bp);
        +			}
        +		else
        +			{
        +			EVP_PKEY_print_public(bp, pkey, 16, NULL);
        +			EVP_PKEY_free(pkey);
        +			}
        +		}
        +
        +	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
        +		X509V3_extensions_print(bp, "X509v3 extensions",
        +					ci->extensions, cflag, 8);
        +
        +	if(!(cflag & X509_FLAG_NO_SIGDUMP))
        +		{
        +		if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
        +		}
        +	if(!(cflag & X509_FLAG_NO_AUX))
        +		{
        +		if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
        +		}
        +	ret=1;
        +err:
        +	if (m != NULL) OPENSSL_free(m);
        +	return(ret);
        +	}
        +
        +int X509_ocspid_print (BIO *bp, X509 *x)
        +	{
        +	unsigned char *der=NULL ;
        +	unsigned char *dertmp;
        +	int derlen;
        +	int i;
        +	unsigned char SHA1md[SHA_DIGEST_LENGTH];
        +
        +	/* display the hash of the subject as it would appear
        +	   in OCSP requests */
        +	if (BIO_printf(bp,"        Subject OCSP hash: ") <= 0)
        +		goto err;
        +	derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
        +	if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
        +		goto err;
        +	i2d_X509_NAME(x->cert_info->subject, &dertmp);
        +
        +	if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
        +		goto err;
        +	for (i=0; i < SHA_DIGEST_LENGTH; i++)
        +		{
        +		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
        +		}
        +	OPENSSL_free (der);
        +	der=NULL;
        +
        +	/* display the hash of the public key as it would appear
        +	   in OCSP requests */
        +	if (BIO_printf(bp,"\n        Public key OCSP hash: ") <= 0)
        +		goto err;
        +
        +	if (!EVP_Digest(x->cert_info->key->public_key->data,
        +			x->cert_info->key->public_key->length,
        +			SHA1md, NULL, EVP_sha1(), NULL))
        +		goto err;
        +	for (i=0; i < SHA_DIGEST_LENGTH; i++)
        +		{
        +		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
        +			goto err;
        +		}
        +	BIO_printf(bp,"\n");
        +
        +	return (1);
        +err:
        +	if (der != NULL) OPENSSL_free(der);
        +	return(0);
        +	}
        +
        +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
        +{
        +	const unsigned char *s;
        +	int i, n;
        +
        +	n=sig->length;
        +	s=sig->data;
        +	for (i=0; i<n; i++)
        +		{
        +		if ((i%18) == 0)
        +			{
        +			if (BIO_write(bp,"\n",1) <= 0) return 0;
        +			if (BIO_indent(bp, indent, indent) <= 0) return 0;
        +			}
        +			if (BIO_printf(bp,"%02x%s",s[i],
        +				((i+1) == n)?"":":") <= 0) return 0;
        +		}
        +	if (BIO_write(bp,"\n",1) != 1) return 0;
        +
        +	return 1;
        +}
        +
        +int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
        +{
        +	int sig_nid;
        +	if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
        +	if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
        +
        +	sig_nid = OBJ_obj2nid(sigalg->algorithm);
        +	if (sig_nid != NID_undef)
        +		{
        +		int pkey_nid, dig_nid;
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +		if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
        +			{
        +			ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
        +			if (ameth && ameth->sig_print)
        +				return ameth->sig_print(bp, sigalg, sig, 9, 0);
        +			}
        +		}
        +	if (sig)
        +		return X509_signature_dump(bp, sig, 9);
        +	else if (BIO_puts(bp, "\n") <= 0)
        +		return 0;
        +	return 1;
        +}
        +
        +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
        +	{
        +	int i,n;
        +	char buf[80];
        +	const char *p;
        +
        +	if (v == NULL) return(0);
        +	n=0;
        +	p=(const char *)v->data;
        +	for (i=0; i<v->length; i++)
        +		{
        +		if ((p[i] > '~') || ((p[i] < ' ') &&
        +			(p[i] != '\n') && (p[i] != '\r')))
        +			buf[n]='.';
        +		else
        +			buf[n]=p[i];
        +		n++;
        +		if (n >= 80)
        +			{
        +			if (BIO_write(bp,buf,n) <= 0)
        +				return(0);
        +			n=0;
        +			}
        +		}
        +	if (n > 0)
        +		if (BIO_write(bp,buf,n) <= 0)
        +			return(0);
        +	return(1);
        +	}
        +
        +int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
        +{
        +	if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
        +	if(tm->type == V_ASN1_GENERALIZEDTIME)
        +				return ASN1_GENERALIZEDTIME_print(bp, tm);
        +	BIO_write(bp,"Bad time value",14);
        +	return(0);
        +}
        +
        +static const char *mon[12]=
        +    {
        +    "Jan","Feb","Mar","Apr","May","Jun",
        +    "Jul","Aug","Sep","Oct","Nov","Dec"
        +    };
        +
        +int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
        +	{
        +	char *v;
        +	int gmt=0;
        +	int i;
        +	int y=0,M=0,d=0,h=0,m=0,s=0;
        +	char *f = NULL;
        +	int f_len = 0;
        +
        +	i=tm->length;
        +	v=(char *)tm->data;
        +
        +	if (i < 12) goto err;
        +	if (v[i-1] == 'Z') gmt=1;
        +	for (i=0; i<12; i++)
        +		if ((v[i] > '9') || (v[i] < '0')) goto err;
        +	y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
        +	M= (v[4]-'0')*10+(v[5]-'0');
        +	if ((M > 12) || (M < 1)) goto err;
        +	d= (v[6]-'0')*10+(v[7]-'0');
        +	h= (v[8]-'0')*10+(v[9]-'0');
        +	m=  (v[10]-'0')*10+(v[11]-'0');
        +	if (tm->length >= 14 &&
        +	    (v[12] >= '0') && (v[12] <= '9') &&
        +	    (v[13] >= '0') && (v[13] <= '9'))
        +		{
        +		s=  (v[12]-'0')*10+(v[13]-'0');
        +		/* Check for fractions of seconds. */
        +		if (tm->length >= 15 && v[14] == '.')
        +			{
        +			int l = tm->length;
        +			f = &v[14];	/* The decimal point. */
        +			f_len = 1;
        +			while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
        +				++f_len;
        +			}
        +		}
        +
        +	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
        +		mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
        +		return(0);
        +	else
        +		return(1);
        +err:
        +	BIO_write(bp,"Bad time value",14);
        +	return(0);
        +	}
        +
        +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
        +	{
        +	const char *v;
        +	int gmt=0;
        +	int i;
        +	int y=0,M=0,d=0,h=0,m=0,s=0;
        +
        +	i=tm->length;
        +	v=(const char *)tm->data;
        +
        +	if (i < 10) goto err;
        +	if (v[i-1] == 'Z') gmt=1;
        +	for (i=0; i<10; i++)
        +		if ((v[i] > '9') || (v[i] < '0')) goto err;
        +	y= (v[0]-'0')*10+(v[1]-'0');
        +	if (y < 50) y+=100;
        +	M= (v[2]-'0')*10+(v[3]-'0');
        +	if ((M > 12) || (M < 1)) goto err;
        +	d= (v[4]-'0')*10+(v[5]-'0');
        +	h= (v[6]-'0')*10+(v[7]-'0');
        +	m=  (v[8]-'0')*10+(v[9]-'0');
        +	if (tm->length >=12 &&
        +	    (v[10] >= '0') && (v[10] <= '9') &&
        +	    (v[11] >= '0') && (v[11] <= '9'))
        +		s=  (v[10]-'0')*10+(v[11]-'0');
        +
        +	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
        +		mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
        +		return(0);
        +	else
        +		return(1);
        +err:
        +	BIO_write(bp,"Bad time value",14);
        +	return(0);
        +	}
        +
        +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
        +	{
        +	char *s,*c,*b;
        +	int ret=0,l,i;
        +
        +	l=80-2-obase;
        +
        +	b=X509_NAME_oneline(name,NULL,0);
        +	if (!*b)
        +		{
        +		OPENSSL_free(b);
        +		return 1;
        +		}
        +	s=b+1; /* skip the first slash */
        +
        +	c=s;
        +	for (;;)
        +		{
        +#ifndef CHARSET_EBCDIC
        +		if (	((*s == '/') &&
        +				((s[1] >= 'A') && (s[1] <= 'Z') && (
        +					(s[2] == '=') ||
        +					((s[2] >= 'A') && (s[2] <= 'Z') &&
        +					(s[3] == '='))
        +				 ))) ||
        +			(*s == '\0'))
        +#else
        +		if (	((*s == '/') &&
        +				(isupper(s[1]) && (
        +					(s[2] == '=') ||
        +					(isupper(s[2]) &&
        +					(s[3] == '='))
        +				 ))) ||
        +			(*s == '\0'))
        +#endif
        +			{
        +			i=s-c;
        +			if (BIO_write(bp,c,i) != i) goto err;
        +			c=s+1;	/* skip following slash */
        +			if (*s != '\0')
        +				{
        +				if (BIO_write(bp,", ",2) != 2) goto err;
        +				}
        +			l--;
        +			}
        +		if (*s == '\0') break;
        +		s++;
        +		l--;
        +		}
        +	
        +	ret=1;
        +	if (0)
        +		{
        +err:
        +		X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
        +		}
        +	OPENSSL_free(b);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/t_x509a.c b/vendor/openssl/openssl/crypto/asn1/t_x509a.c
        new file mode 100644
        index 000000000..8b18801a1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/t_x509a.c
        @@ -0,0 +1,110 @@
        +/* t_x509a.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +
        +/* X509_CERT_AUX and string set routines
        + */
        +
        +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
        +{
        +	char oidstr[80], first;
        +	int i;
        +	if(!aux) return 1;
        +	if(aux->trust) {
        +		first = 1;
        +		BIO_printf(out, "%*sTrusted Uses:\n%*s",
        +						indent, "", indent + 2, "");
        +		for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
        +			if(!first) BIO_puts(out, ", ");
        +			else first = 0;
        +			OBJ_obj2txt(oidstr, sizeof oidstr,
        +				sk_ASN1_OBJECT_value(aux->trust, i), 0);
        +			BIO_puts(out, oidstr);
        +		}
        +		BIO_puts(out, "\n");
        +	} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
        +	if(aux->reject) {
        +		first = 1;
        +		BIO_printf(out, "%*sRejected Uses:\n%*s",
        +						indent, "", indent + 2, "");
        +		for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
        +			if(!first) BIO_puts(out, ", ");
        +			else first = 0;
        +			OBJ_obj2txt(oidstr, sizeof oidstr,
        +				sk_ASN1_OBJECT_value(aux->reject, i), 0);
        +			BIO_puts(out, oidstr);
        +		}
        +		BIO_puts(out, "\n");
        +	} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
        +	if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
        +							aux->alias->data);
        +	if(aux->keyid) {
        +		BIO_printf(out, "%*sKey Id: ", indent, "");
        +		for(i = 0; i < aux->keyid->length; i++) 
        +			BIO_printf(out, "%s%02X", 
        +				i ? ":" : "",
        +				aux->keyid->data[i]);
        +		BIO_write(out,"\n",1);
        +	}
        +	return 1;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_dec.c b/vendor/openssl/openssl/crypto/asn1/tasn_dec.c
        new file mode 100644
        index 000000000..87d7dfdf5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_dec.c
        @@ -0,0 +1,1347 @@
        +/* tasn_dec.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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 <stddef.h>
        +#include <string.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +#include <openssl/err.h>
        +
        +static int asn1_check_eoc(const unsigned char **in, long len);
        +static int asn1_find_end(const unsigned char **in, long len, char inf);
        +
        +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
        +			char inf, int tag, int aclass, int depth);
        +
        +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
        +
        +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
        +				char *inf, char *cst,
        +				const unsigned char **in, long len,
        +				int exptag, int expclass, char opt,
        +				ASN1_TLC *ctx);
        +
        +static int asn1_template_ex_d2i(ASN1_VALUE **pval,
        +				const unsigned char **in, long len,
        +				const ASN1_TEMPLATE *tt, char opt,
        +				ASN1_TLC *ctx);
        +static int asn1_template_noexp_d2i(ASN1_VALUE **val,
        +				const unsigned char **in, long len,
        +				const ASN1_TEMPLATE *tt, char opt,
        +				ASN1_TLC *ctx);
        +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
        +				const unsigned char **in, long len,
        +				const ASN1_ITEM *it,
        +				int tag, int aclass, char opt, ASN1_TLC *ctx);
        +
        +/* Table to convert tags to bit values, used for MSTRING type */
        +static const unsigned long tag2bit[32] = {
        +0,	0,	0,	B_ASN1_BIT_STRING,	/* tags  0 -  3 */
        +B_ASN1_OCTET_STRING,	0,	0,		B_ASN1_UNKNOWN,/* tags  4- 7 */
        +B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,/* tags  8-11 */
        +B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
        +B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
        +B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,       /* tags 20-22 */
        +B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,			       /* tags 23-24 */	
        +B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING,  /* tags 25-27 */
        +B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
        +	};
        +
        +unsigned long ASN1_tag2bit(int tag)
        +	{
        +	if ((tag < 0) || (tag > 30)) return 0;
        +	return tag2bit[tag];
        +	}
        +
        +/* Macro to initialize and invalidate the cache */
        +
        +#define asn1_tlc_clear(c)	if (c) (c)->valid = 0
        +/* Version to avoid compiler warning about 'c' always non-NULL */
        +#define asn1_tlc_clear_nc(c)	(c)->valid = 0
        +
        +/* Decode an ASN1 item, this currently behaves just 
        + * like a standard 'd2i' function. 'in' points to 
        + * a buffer to read the data from, in future we will
        + * have more advanced versions that can input data
        + * a piece at a time and this will simply be a special
        + * case.
        + */
        +
        +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
        +		const unsigned char **in, long len, const ASN1_ITEM *it)
        +	{
        +	ASN1_TLC c;
        +	ASN1_VALUE *ptmpval = NULL;
        +	if (!pval)
        +		pval = &ptmpval;
        +	asn1_tlc_clear_nc(&c);
        +	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
        +		return *pval;
        +	return NULL;
        +	}
        +
        +int ASN1_template_d2i(ASN1_VALUE **pval,
        +		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
        +	{
        +	ASN1_TLC c;
        +	asn1_tlc_clear_nc(&c);
        +	return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
        +	}
        +
        +
        +/* Decode an item, taking care of IMPLICIT tagging, if any.
        + * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
        + */
        +
        +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
        +			const ASN1_ITEM *it,
        +			int tag, int aclass, char opt, ASN1_TLC *ctx)
        +	{
        +	const ASN1_TEMPLATE *tt, *errtt = NULL;
        +	const ASN1_COMPAT_FUNCS *cf;
        +	const ASN1_EXTERN_FUNCS *ef;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_aux_cb *asn1_cb;
        +	const unsigned char *p = NULL, *q;
        +	unsigned char *wp=NULL;	/* BIG FAT WARNING!  BREAKS CONST WHERE USED */
        +	unsigned char imphack = 0, oclass;
        +	char seq_eoc, seq_nolen, cst, isopt;
        +	long tmplen;
        +	int i;
        +	int otag;
        +	int ret = 0;
        +	ASN1_VALUE **pchptr, *ptmpval;
        +	if (!pval)
        +		return 0;
        +	if (aux && aux->asn1_cb)
        +		asn1_cb = aux->asn1_cb;
        +	else asn1_cb = 0;
        +
        +	switch(it->itype)
        +		{
        +		case ASN1_ITYPE_PRIMITIVE:
        +		if (it->templates)
        +			{
        +			/* tagging or OPTIONAL is currently illegal on an item
        +			 * template because the flags can't get passed down.
        +			 * In practice this isn't a problem: we include the
        +			 * relevant flags from the item template in the
        +			 * template itself.
        +			 */
        +			if ((tag != -1) || opt)
        +				{
        +				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +				ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
        +				goto err;
        +				}
        +			return asn1_template_ex_d2i(pval, in, len,
        +					it->templates, opt, ctx);
        +		}
        +		return asn1_d2i_ex_primitive(pval, in, len, it,
        +						tag, aclass, opt, ctx);
        +		break;
        +
        +		case ASN1_ITYPE_MSTRING:
        +		p = *in;
        +		/* Just read in tag and class */
        +		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
        +						&p, len, -1, 0, 1, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +
        +		/* Must be UNIVERSAL class */
        +		if (oclass != V_ASN1_UNIVERSAL)
        +			{
        +			/* If OPTIONAL, assume this is OK */
        +			if (opt) return -1;
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ASN1_R_MSTRING_NOT_UNIVERSAL);
        +			goto err;
        +			}
        +		/* Check tag matches bit map */
        +		if (!(ASN1_tag2bit(otag) & it->utype))
        +			{
        +			/* If OPTIONAL, assume this is OK */
        +			if (opt)
        +				return -1;
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ASN1_R_MSTRING_WRONG_TAG);
        +			goto err;
        +			}
        +		return asn1_d2i_ex_primitive(pval, in, len,
        +						it, otag, 0, 0, ctx);
        +
        +		case ASN1_ITYPE_EXTERN:
        +		/* Use new style d2i */
        +		ef = it->funcs;
        +		return ef->asn1_ex_d2i(pval, in, len,
        +						it, tag, aclass, opt, ctx);
        +
        +		case ASN1_ITYPE_COMPAT:
        +		/* we must resort to old style evil hackery */
        +		cf = it->funcs;
        +
        +		/* If OPTIONAL see if it is there */
        +		if (opt)
        +			{
        +			int exptag;
        +			p = *in;
        +			if (tag == -1)
        +				exptag = it->utype;
        +			else exptag = tag;
        +			/* Don't care about anything other than presence
        +			 * of expected tag */
        +
        +			ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
        +					&p, len, exptag, aclass, 1, ctx);
        +			if (!ret)
        +				{
        +				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +				goto err;
        +				}
        +			if (ret == -1)
        +				return -1;
        +			}
        +
        +		/* This is the old style evil hack IMPLICIT handling:
        +		 * since the underlying code is expecting a tag and
        +		 * class other than the one present we change the
        +		 * buffer temporarily then change it back afterwards.
        +		 * This doesn't and never did work for tags > 30.
        +		 *
        +		 * Yes this is *horrible* but it is only needed for
        +		 * old style d2i which will hopefully not be around
        +		 * for much longer.
        +		 * FIXME: should copy the buffer then modify it so
        +		 * the input buffer can be const: we should *always*
        +		 * copy because the old style d2i might modify the
        +		 * buffer.
        +		 */
        +
        +		if (tag != -1)
        +			{
        +			wp = *(unsigned char **)in;
        +			imphack = *wp;
        +			if (p == NULL)
        +				{
        +				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +				goto err;
        +				}
        +			*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
        +								| it->utype);
        +			}
        +
        +		ptmpval = cf->asn1_d2i(pval, in, len);
        +
        +		if (tag != -1)
        +			*wp = imphack;
        +
        +		if (ptmpval)
        +			return 1;
        +
        +		ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
        +		goto err;
        +
        +
        +		case ASN1_ITYPE_CHOICE:
        +		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
        +				goto auxerr;
        +
        +		/* Allocate structure */
        +		if (!*pval && !ASN1_item_ex_new(pval, it))
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +						ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +		/* CHOICE type, try each possibility in turn */
        +		p = *in;
        +		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
        +			{
        +			pchptr = asn1_get_field_ptr(pval, tt);
        +			/* We mark field as OPTIONAL so its absence
        +			 * can be recognised.
        +			 */
        +			ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
        +			/* If field not present, try the next one */
        +			if (ret == -1)
        +				continue;
        +			/* If positive return, read OK, break loop */
        +			if (ret > 0)
        +				break;
        +			/* Otherwise must be an ASN1 parsing error */
        +			errtt = tt;
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +						ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +
        +		/* Did we fall off the end without reading anything? */
        +		if (i == it->tcount)
        +			{
        +			/* If OPTIONAL, this is OK */
        +			if (opt)
        +				{
        +				/* Free and zero it */
        +				ASN1_item_ex_free(pval, it);
        +				return -1;
        +				}
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ASN1_R_NO_MATCHING_CHOICE_TYPE);
        +			goto err;
        +			}
        +
        +		asn1_set_choice_selector(pval, i, it);
        +		*in = p;
        +		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
        +				goto auxerr;
        +		return 1;
        +
        +		case ASN1_ITYPE_NDEF_SEQUENCE:
        +		case ASN1_ITYPE_SEQUENCE:
        +		p = *in;
        +		tmplen = len;
        +
        +		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
        +		if (tag == -1)
        +			{
        +			tag = V_ASN1_SEQUENCE;
        +			aclass = V_ASN1_UNIVERSAL;
        +			}
        +		/* Get SEQUENCE length and update len, p */
        +		ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
        +					&p, len, tag, aclass, opt, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +		else if (ret == -1)
        +			return -1;
        +		if (aux && (aux->flags & ASN1_AFLG_BROKEN))
        +			{
        +			len = tmplen - (p - *in);
        +			seq_nolen = 1;
        +			}
        +		/* If indefinite we don't do a length check */
        +		else seq_nolen = seq_eoc;
        +		if (!cst)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +				ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
        +			goto err;
        +			}
        +
        +		if (!*pval && !ASN1_item_ex_new(pval, it))
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +				ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +
        +		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
        +				goto auxerr;
        +
        +		/* Get each field entry */
        +		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
        +			{
        +			const ASN1_TEMPLATE *seqtt;
        +			ASN1_VALUE **pseqval;
        +			seqtt = asn1_do_adb(pval, tt, 1);
        +			if (!seqtt)
        +				goto err;
        +			pseqval = asn1_get_field_ptr(pval, seqtt);
        +			/* Have we ran out of data? */
        +			if (!len)
        +				break;
        +			q = p;
        +			if (asn1_check_eoc(&p, len))
        +				{
        +				if (!seq_eoc)
        +					{
        +					ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +							ASN1_R_UNEXPECTED_EOC);
        +					goto err;
        +					}
        +				len -= p - q;
        +				seq_eoc = 0;
        +				q = p;
        +				break;
        +				}
        +			/* This determines the OPTIONAL flag value. The field
        +			 * cannot be omitted if it is the last of a SEQUENCE
        +			 * and there is still data to be read. This isn't
        +			 * strictly necessary but it increases efficiency in
        +			 * some cases.
        +			 */
        +			if (i == (it->tcount - 1))
        +				isopt = 0;
        +			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
        +			/* attempt to read in field, allowing each to be
        +			 * OPTIONAL */
        +
        +			ret = asn1_template_ex_d2i(pseqval, &p, len,
        +							seqtt, isopt, ctx);
        +			if (!ret)
        +				{
        +				errtt = seqtt;
        +				goto err;
        +				}
        +			else if (ret == -1)
        +				{
        +				/* OPTIONAL component absent.
        +				 * Free and zero the field.
        +				 */
        +				ASN1_template_free(pseqval, seqtt);
        +				continue;
        +				}
        +			/* Update length */
        +			len -= p - q;
        +			}
        +
        +		/* Check for EOC if expecting one */
        +		if (seq_eoc && !asn1_check_eoc(&p, len))
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
        +			goto err;
        +			}
        +		/* Check all data read */
        +		if (!seq_nolen && len)
        +			{
        +			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +					ASN1_R_SEQUENCE_LENGTH_MISMATCH);
        +			goto err;
        +			}
        +
        +		/* If we get here we've got no more data in the SEQUENCE,
        +		 * however we may not have read all fields so check all
        +		 * remaining are OPTIONAL and clear any that are.
        +		 */
        +		for (; i < it->tcount; tt++, i++)
        +			{
        +			const ASN1_TEMPLATE *seqtt;
        +			seqtt = asn1_do_adb(pval, tt, 1);
        +			if (!seqtt)
        +				goto err;
        +			if (seqtt->flags & ASN1_TFLG_OPTIONAL)
        +				{
        +				ASN1_VALUE **pseqval;
        +				pseqval = asn1_get_field_ptr(pval, seqtt);
        +				ASN1_template_free(pseqval, seqtt);
        +				}
        +			else
        +				{
        +				errtt = seqtt;
        +				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
        +							ASN1_R_FIELD_MISSING);
        +				goto err;
        +				}
        +			}
        +		/* Save encoding */
        +		if (!asn1_enc_save(pval, *in, p - *in, it))
        +			goto auxerr;
        +		*in = p;
        +		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
        +				goto auxerr;
        +		return 1;
        +
        +		default:
        +		return 0;
        +		}
        +	auxerr:
        +	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
        +	err:
        +	ASN1_item_ex_free(pval, it);
        +	if (errtt)
        +		ERR_add_error_data(4, "Field=", errtt->field_name,
        +					", Type=", it->sname);
        +	else
        +		ERR_add_error_data(2, "Type=", it->sname);
        +	return 0;
        +	}
        +
        +/* Templates are handled with two separate functions.
        + * One handles any EXPLICIT tag and the other handles the rest.
        + */
        +
        +static int asn1_template_ex_d2i(ASN1_VALUE **val,
        +				const unsigned char **in, long inlen,
        +				const ASN1_TEMPLATE *tt, char opt,
        +							ASN1_TLC *ctx)
        +	{
        +	int flags, aclass;
        +	int ret;
        +	long len;
        +	const unsigned char *p, *q;
        +	char exp_eoc;
        +	if (!val)
        +		return 0;
        +	flags = tt->flags;
        +	aclass = flags & ASN1_TFLG_TAG_CLASS;
        +
        +	p = *in;
        +
        +	/* Check if EXPLICIT tag expected */
        +	if (flags & ASN1_TFLG_EXPTAG)
        +		{
        +		char cst;
        +		/* Need to work out amount of data available to the inner
        +		 * content and where it starts: so read in EXPLICIT header to
        +		 * get the info.
        +		 */
        +		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
        +					&p, inlen, tt->tag, aclass, opt, ctx);
        +		q = p;
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +			return 0;
        +			}
        +		else if (ret == -1)
        +			return -1;
        +		if (!cst)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
        +					ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
        +			return 0;
        +			}
        +		/* We've found the field so it can't be OPTIONAL now */
        +		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +			return 0;
        +			}
        +		/* We read the field in OK so update length */
        +		len -= p - q;
        +		if (exp_eoc)
        +			{
        +			/* If NDEF we must have an EOC here */
        +			if (!asn1_check_eoc(&p, len))
        +				{
        +				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
        +						ASN1_R_MISSING_EOC);
        +				goto err;
        +				}
        +			}
        +		else
        +			{
        +			/* Otherwise we must hit the EXPLICIT tag end or its
        +			 * an error */
        +			if (len)
        +				{
        +				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
        +					ASN1_R_EXPLICIT_LENGTH_MISMATCH);
        +				goto err;
        +				}
        +			}
        +		}
        +		else 
        +			return asn1_template_noexp_d2i(val, in, inlen,
        +								tt, opt, ctx);
        +
        +	*in = p;
        +	return 1;
        +
        +	err:
        +	ASN1_template_free(val, tt);
        +	return 0;
        +	}
        +
        +static int asn1_template_noexp_d2i(ASN1_VALUE **val,
        +				const unsigned char **in, long len,
        +				const ASN1_TEMPLATE *tt, char opt,
        +				ASN1_TLC *ctx)
        +	{
        +	int flags, aclass;
        +	int ret;
        +	const unsigned char *p, *q;
        +	if (!val)
        +		return 0;
        +	flags = tt->flags;
        +	aclass = flags & ASN1_TFLG_TAG_CLASS;
        +
        +	p = *in;
        +	q = p;
        +
        +	if (flags & ASN1_TFLG_SK_MASK)
        +		{
        +		/* SET OF, SEQUENCE OF */
        +		int sktag, skaclass;
        +		char sk_eoc;
        +		/* First work out expected inner tag value */
        +		if (flags & ASN1_TFLG_IMPTAG)
        +			{
        +			sktag = tt->tag;
        +			skaclass = aclass;
        +			}
        +		else
        +			{
        +			skaclass = V_ASN1_UNIVERSAL;
        +			if (flags & ASN1_TFLG_SET_OF)
        +				sktag = V_ASN1_SET;
        +			else
        +				sktag = V_ASN1_SEQUENCE;
        +			}
        +		/* Get the tag */
        +		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
        +					&p, len, sktag, skaclass, opt, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +						ERR_R_NESTED_ASN1_ERROR);
        +			return 0;
        +			}
        +		else if (ret == -1)
        +			return -1;
        +		if (!*val)
        +			*val = (ASN1_VALUE *)sk_new_null();
        +		else
        +			{
        +			/* We've got a valid STACK: free up any items present */
        +			STACK_OF(ASN1_VALUE) *sktmp
        +			    = (STACK_OF(ASN1_VALUE) *)*val;
        +			ASN1_VALUE *vtmp;
        +			while(sk_ASN1_VALUE_num(sktmp) > 0)
        +				{
        +				vtmp = sk_ASN1_VALUE_pop(sktmp);
        +				ASN1_item_ex_free(&vtmp,
        +						ASN1_ITEM_ptr(tt->item));
        +				}
        +			}
        +				
        +		if (!*val)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +						ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* Read as many items as we can */
        +		while(len > 0)
        +			{
        +			ASN1_VALUE *skfield;
        +			q = p;
        +			/* See if EOC found */
        +			if (asn1_check_eoc(&p, len))
        +				{
        +				if (!sk_eoc)
        +					{
        +					ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +							ASN1_R_UNEXPECTED_EOC);
        +					goto err;
        +					}
        +				len -= p - q;
        +				sk_eoc = 0;
        +				break;
        +				}
        +			skfield = NULL;
        +			if (!ASN1_item_ex_d2i(&skfield, &p, len,
        +						ASN1_ITEM_ptr(tt->item),
        +						-1, 0, 0, ctx))
        +				{
        +				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +				goto err;
        +				}
        +			len -= p - q;
        +			if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
        +						skfield))
        +				{
        +				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +						ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			}
        +		if (sk_eoc)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
        +			goto err;
        +			}
        +		}
        +	else if (flags & ASN1_TFLG_IMPTAG)
        +		{
        +		/* IMPLICIT tagging */
        +		ret = ASN1_item_ex_d2i(val, &p, len,
        +			ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +						ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +		else if (ret == -1)
        +			return -1;
        +		}
        +	else
        +		{
        +		/* Nothing special */
        +		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
        +							-1, 0, opt, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
        +					ERR_R_NESTED_ASN1_ERROR);
        +			goto err;
        +			}
        +		else if (ret == -1)
        +			return -1;
        +		}
        +
        +	*in = p;
        +	return 1;
        +
        +	err:
        +	ASN1_template_free(val, tt);
        +	return 0;
        +	}
        +
        +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
        +				const unsigned char **in, long inlen, 
        +				const ASN1_ITEM *it,
        +				int tag, int aclass, char opt, ASN1_TLC *ctx)
        +	{
        +	int ret = 0, utype;
        +	long plen;
        +	char cst, inf, free_cont = 0;
        +	const unsigned char *p;
        +	BUF_MEM buf;
        +	const unsigned char *cont = NULL;
        +	long len; 
        +	if (!pval)
        +		{
        +		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
        +		return 0; /* Should never happen */
        +		}
        +
        +	if (it->itype == ASN1_ITYPE_MSTRING)
        +		{
        +		utype = tag;
        +		tag = -1;
        +		}
        +	else
        +		utype = it->utype;
        +
        +	if (utype == V_ASN1_ANY)
        +		{
        +		/* If type is ANY need to figure out type from tag */
        +		unsigned char oclass;
        +		if (tag >= 0)
        +			{
        +			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
        +					ASN1_R_ILLEGAL_TAGGED_ANY);
        +			return 0;
        +			}
        +		if (opt)
        +			{
        +			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
        +					ASN1_R_ILLEGAL_OPTIONAL_ANY);
        +			return 0;
        +			}
        +		p = *in;
        +		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
        +					&p, inlen, -1, 0, 0, ctx);
        +		if (!ret)
        +			{
        +			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
        +					ERR_R_NESTED_ASN1_ERROR);
        +			return 0;
        +			}
        +		if (oclass != V_ASN1_UNIVERSAL)
        +			utype = V_ASN1_OTHER;
        +		}
        +	if (tag == -1)
        +		{
        +		tag = utype;
        +		aclass = V_ASN1_UNIVERSAL;
        +		}
        +	p = *in;
        +	/* Check header */
        +	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
        +				&p, inlen, tag, aclass, opt, ctx);
        +	if (!ret)
        +		{
        +		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
        +		return 0;
        +		}
        +	else if (ret == -1)
        +		return -1;
        +        ret = 0;
        +	/* SEQUENCE, SET and "OTHER" are left in encoded form */
        +	if ((utype == V_ASN1_SEQUENCE)
        +		|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
        +		{
        +		/* Clear context cache for type OTHER because the auto clear
        +		 * when we have a exact match wont work
        +		 */
        +		if (utype == V_ASN1_OTHER)
        +			{
        +			asn1_tlc_clear(ctx);
        +			}
        +		/* SEQUENCE and SET must be constructed */
        +		else if (!cst)
        +			{
        +			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
        +				ASN1_R_TYPE_NOT_CONSTRUCTED);
        +			return 0;
        +			}
        +
        +		cont = *in;
        +		/* If indefinite length constructed find the real end */
        +		if (inf)
        +			{
        +			if (!asn1_find_end(&p, plen, inf))
        +				 goto err;
        +			len = p - cont;
        +			}
        +		else
        +			{
        +			len = p - cont + plen;
        +			p += plen;
        +			buf.data = NULL;
        +			}
        +		}
        +	else if (cst)
        +		{
        +		buf.length = 0;
        +		buf.max = 0;
        +		buf.data = NULL;
        +		/* Should really check the internal tags are correct but
        +		 * some things may get this wrong. The relevant specs
        +		 * say that constructed string types should be OCTET STRINGs
        +		 * internally irrespective of the type. So instead just check
        +		 * for UNIVERSAL class and ignore the tag.
        +		 */
        +		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
        +			{
        +			free_cont = 1;
        +			goto err;
        +			}
        +		len = buf.length;
        +		/* Append a final null to string */
        +		if (!BUF_MEM_grow_clean(&buf, len + 1))
        +			{
        +			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
        +						ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		buf.data[len] = 0;
        +		cont = (const unsigned char *)buf.data;
        +		free_cont = 1;
        +		}
        +	else
        +		{
        +		cont = p;
        +		len = plen;
        +		p += plen;
        +		}
        +
        +	/* We now have content length and type: translate into a structure */
        +	if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
        +		goto err;
        +
        +	*in = p;
        +	ret = 1;
        +	err:
        +	if (free_cont && buf.data) OPENSSL_free(buf.data);
        +	return ret;
        +	}
        +
        +/* Translate ASN1 content octets into a structure */
        +
        +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
        +			int utype, char *free_cont, const ASN1_ITEM *it)
        +	{
        +	ASN1_VALUE **opval = NULL;
        +	ASN1_STRING *stmp;
        +	ASN1_TYPE *typ = NULL;
        +	int ret = 0;
        +	const ASN1_PRIMITIVE_FUNCS *pf;
        +	ASN1_INTEGER **tint;
        +	pf = it->funcs;
        +
        +	if (pf && pf->prim_c2i)
        +		return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
        +	/* If ANY type clear type and set pointer to internal value */
        +	if (it->utype == V_ASN1_ANY)
        +		{
        +		if (!*pval)
        +			{
        +			typ = ASN1_TYPE_new();
        +			if (typ == NULL)
        +				goto err;
        +			*pval = (ASN1_VALUE *)typ;
        +			}
        +		else
        +			typ = (ASN1_TYPE *)*pval;
        +
        +		if (utype != typ->type)
        +			ASN1_TYPE_set(typ, utype, NULL);
        +		opval = pval;
        +		pval = &typ->value.asn1_value;
        +		}
        +	switch(utype)
        +		{
        +		case V_ASN1_OBJECT:
        +		if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
        +			goto err;
        +		break;
        +
        +		case V_ASN1_NULL:
        +		if (len)
        +			{
        +			ASN1err(ASN1_F_ASN1_EX_C2I,
        +						ASN1_R_NULL_IS_WRONG_LENGTH);
        +			goto err;
        +			}
        +		*pval = (ASN1_VALUE *)1;
        +		break;
        +
        +		case V_ASN1_BOOLEAN:
        +		if (len != 1)
        +			{
        +			ASN1err(ASN1_F_ASN1_EX_C2I,
        +						ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
        +			goto err;
        +			}
        +		else
        +			{
        +			ASN1_BOOLEAN *tbool;
        +			tbool = (ASN1_BOOLEAN *)pval;
        +			*tbool = *cont;
        +			}
        +		break;
        +
        +		case V_ASN1_BIT_STRING:
        +		if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
        +			goto err;
        +		break;
        +
        +		case V_ASN1_INTEGER:
        +		case V_ASN1_NEG_INTEGER:
        +		case V_ASN1_ENUMERATED:
        +		case V_ASN1_NEG_ENUMERATED:
        +		tint = (ASN1_INTEGER **)pval;
        +		if (!c2i_ASN1_INTEGER(tint, &cont, len))
        +			goto err;
        +		/* Fixup type to match the expected form */
        +		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
        +		break;
        +
        +		case V_ASN1_OCTET_STRING:
        +		case V_ASN1_NUMERICSTRING:
        +		case V_ASN1_PRINTABLESTRING:
        +		case V_ASN1_T61STRING:
        +		case V_ASN1_VIDEOTEXSTRING:
        +		case V_ASN1_IA5STRING:
        +		case V_ASN1_UTCTIME:
        +		case V_ASN1_GENERALIZEDTIME:
        +		case V_ASN1_GRAPHICSTRING:
        +		case V_ASN1_VISIBLESTRING:
        +		case V_ASN1_GENERALSTRING:
        +		case V_ASN1_UNIVERSALSTRING:
        +		case V_ASN1_BMPSTRING:
        +		case V_ASN1_UTF8STRING:
        +		case V_ASN1_OTHER:
        +		case V_ASN1_SET:
        +		case V_ASN1_SEQUENCE:
        +		default:
        +		if (utype == V_ASN1_BMPSTRING && (len & 1))
        +			{
        +			ASN1err(ASN1_F_ASN1_EX_C2I,
        +					ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
        +			goto err;
        +			}
        +		if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
        +			{
        +			ASN1err(ASN1_F_ASN1_EX_C2I,
        +					ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
        +			goto err;
        +			}
        +		/* All based on ASN1_STRING and handled the same */
        +		if (!*pval)
        +			{
        +			stmp = ASN1_STRING_type_new(utype);
        +			if (!stmp)
        +				{
        +				ASN1err(ASN1_F_ASN1_EX_C2I,
        +							ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			*pval = (ASN1_VALUE *)stmp;
        +			}
        +		else
        +			{
        +			stmp = (ASN1_STRING *)*pval;
        +			stmp->type = utype;
        +			}
        +		/* If we've already allocated a buffer use it */
        +		if (*free_cont)
        +			{
        +			if (stmp->data)
        +				OPENSSL_free(stmp->data);
        +			stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
        +			stmp->length = len;
        +			*free_cont = 0;
        +			}
        +		else
        +			{
        +			if (!ASN1_STRING_set(stmp, cont, len))
        +				{
        +				ASN1err(ASN1_F_ASN1_EX_C2I,
        +							ERR_R_MALLOC_FAILURE);
        +				ASN1_STRING_free(stmp);	
        +				*pval = NULL;
        +				goto err;
        +				}
        +			}
        +		break;
        +		}
        +	/* If ASN1_ANY and NULL type fix up value */
        +	if (typ && (utype == V_ASN1_NULL))
        +		 typ->value.ptr = NULL;
        +
        +	ret = 1;
        +	err:
        +	if (!ret)
        +		{
        +		ASN1_TYPE_free(typ);
        +		if (opval)
        +			*opval = NULL;
        +		}
        +	return ret;
        +	}
        +
        +
        +/* This function finds the end of an ASN1 structure when passed its maximum
        + * length, whether it is indefinite length and a pointer to the content.
        + * This is more efficient than calling asn1_collect because it does not
        + * recurse on each indefinite length header.
        + */
        +
        +static int asn1_find_end(const unsigned char **in, long len, char inf)
        +	{
        +	int expected_eoc;
        +	long plen;
        +	const unsigned char *p = *in, *q;
        +	/* If not indefinite length constructed just add length */
        +	if (inf == 0)
        +		{
        +		*in += len;
        +		return 1;
        +		}
        +	expected_eoc = 1;
        +	/* Indefinite length constructed form. Find the end when enough EOCs
        +	 * are found. If more indefinite length constructed headers
        +	 * are encountered increment the expected eoc count otherwise just
        +	 * skip to the end of the data.
        +	 */
        +	while (len > 0)
        +		{
        +		if(asn1_check_eoc(&p, len))
        +			{
        +			expected_eoc--;
        +			if (expected_eoc == 0)
        +				break;
        +			len -= 2;
        +			continue;
        +			}
        +		q = p;
        +		/* Just read in a header: only care about the length */
        +		if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
        +				-1, 0, 0, NULL))
        +			{
        +			ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
        +			return 0;
        +			}
        +		if (inf)
        +			expected_eoc++;
        +		else
        +			p += plen;
        +		len -= p - q;
        +		}
        +	if (expected_eoc)
        +		{
        +		ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
        +		return 0;
        +		}
        +	*in = p;
        +	return 1;
        +	}
        +/* This function collects the asn1 data from a constructred string
        + * type into a buffer. The values of 'in' and 'len' should refer
        + * to the contents of the constructed type and 'inf' should be set
        + * if it is indefinite length.
        + */
        +
        +#ifndef ASN1_MAX_STRING_NEST
        +/* This determines how many levels of recursion are permitted in ASN1
        + * string types. If it is not limited stack overflows can occur. If set
        + * to zero no recursion is allowed at all. Although zero should be adequate
        + * examples exist that require a value of 1. So 5 should be more than enough.
        + */
        +#define ASN1_MAX_STRING_NEST 5
        +#endif
        +
        +
        +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
        +			char inf, int tag, int aclass, int depth)
        +	{
        +	const unsigned char *p, *q;
        +	long plen;
        +	char cst, ininf;
        +	p = *in;
        +	inf &= 1;
        +	/* If no buffer and not indefinite length constructed just pass over
        +	 * the encoded data */
        +	if (!buf && !inf)
        +		{
        +		*in += len;
        +		return 1;
        +		}
        +	while(len > 0)
        +		{
        +		q = p;
        +		/* Check for EOC */
        +		if (asn1_check_eoc(&p, len))
        +			{
        +			/* EOC is illegal outside indefinite length
        +			 * constructed form */
        +			if (!inf)
        +				{
        +				ASN1err(ASN1_F_ASN1_COLLECT,
        +					ASN1_R_UNEXPECTED_EOC);
        +				return 0;
        +				}
        +			inf = 0;
        +			break;
        +			}
        +
        +		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
        +					len, tag, aclass, 0, NULL))
        +			{
        +			ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
        +			return 0;
        +			}
        +
        +		/* If indefinite length constructed update max length */
        +		if (cst)
        +			{
        +			if (depth >= ASN1_MAX_STRING_NEST)
        +				{
        +				ASN1err(ASN1_F_ASN1_COLLECT,
        +					ASN1_R_NESTED_ASN1_STRING);
        +				return 0;
        +				}
        +			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
        +						depth + 1))
        +				return 0;
        +			}
        +		else if (plen && !collect_data(buf, &p, plen))
        +			return 0;
        +		len -= p - q;
        +		}
        +	if (inf)
        +		{
        +		ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
        +		return 0;
        +		}
        +	*in = p;
        +	return 1;
        +	}
        +
        +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
        +	{
        +	int len;
        +	if (buf)
        +		{
        +		len = buf->length;
        +		if (!BUF_MEM_grow_clean(buf, len + plen))
        +			{
        +			ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		memcpy(buf->data + len, *p, plen);
        +		}
        +	*p += plen;
        +	return 1;
        +	}
        +
        +/* Check for ASN1 EOC and swallow it if found */
        +
        +static int asn1_check_eoc(const unsigned char **in, long len)
        +	{
        +	const unsigned char *p;
        +	if (len < 2) return 0;
        +	p = *in;
        +	if (!p[0] && !p[1])
        +		{
        +		*in += 2;
        +		return 1;
        +		}
        +	return 0;
        +	}
        +
        +/* Check an ASN1 tag and length: a bit like ASN1_get_object
        + * but it sets the length for indefinite length constructed
        + * form, we don't know the exact length but we can set an
        + * upper bound to the amount of data available minus the
        + * header length just read.
        + */
        +
        +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
        +				char *inf, char *cst,
        +				const unsigned char **in, long len,
        +				int exptag, int expclass, char opt,
        +				ASN1_TLC *ctx)
        +	{
        +	int i;
        +	int ptag, pclass;
        +	long plen;
        +	const unsigned char *p, *q;
        +	p = *in;
        +	q = p;
        +
        +	if (ctx && ctx->valid)
        +		{
        +		i = ctx->ret;
        +		plen = ctx->plen;
        +		pclass = ctx->pclass;
        +		ptag = ctx->ptag;
        +		p += ctx->hdrlen;
        +		}
        +	else
        +		{
        +		i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
        +		if (ctx)
        +			{
        +			ctx->ret = i;
        +			ctx->plen = plen;
        +			ctx->pclass = pclass;
        +			ctx->ptag = ptag;
        +			ctx->hdrlen = p - q;
        +			ctx->valid = 1;
        +			/* If definite length, and no error, length +
        +			 * header can't exceed total amount of data available. 
        +			 */
        +			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
        +				{
        +				ASN1err(ASN1_F_ASN1_CHECK_TLEN,
        +							ASN1_R_TOO_LONG);
        +				asn1_tlc_clear(ctx);
        +				return 0;
        +				}
        +			}
        +		}
        +
        +	if (i & 0x80)
        +		{
        +		ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
        +		asn1_tlc_clear(ctx);
        +		return 0;
        +		}
        +	if (exptag >= 0)
        +		{
        +		if ((exptag != ptag) || (expclass != pclass))
        +			{
        +			/* If type is OPTIONAL, not an error:
        +			 * indicate missing type.
        +			 */
        +			if (opt) return -1;
        +			asn1_tlc_clear(ctx);
        +			ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
        +			return 0;
        +			}
        +		/* We have a tag and class match:
        +		 * assume we are going to do something with it */
        +		asn1_tlc_clear(ctx);
        +		}
        +
        +	if (i & 1)
        +		plen = len - (p - q);
        +
        +	if (inf)
        +		*inf = i & 1;
        +
        +	if (cst)
        +		*cst = i & V_ASN1_CONSTRUCTED;
        +
        +	if (olen)
        +		*olen = plen;
        +
        +	if (oclass)
        +		*oclass = pclass;
        +
        +	if (otag)
        +		*otag = ptag;
        +
        +	*in = p;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_enc.c b/vendor/openssl/openssl/crypto/asn1/tasn_enc.c
        new file mode 100644
        index 000000000..936ad1f76
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_enc.c
        @@ -0,0 +1,691 @@
        +/* tasn_enc.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2004 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 <stddef.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +
        +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
        +					const ASN1_ITEM *it,
        +					int tag, int aclass);
        +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
        +					int skcontlen, const ASN1_ITEM *item,
        +					int do_sort, int iclass);
        +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
        +					const ASN1_TEMPLATE *tt,
        +					int tag, int aclass);
        +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
        +					const ASN1_ITEM *it, int flags);
        +
        +/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
        + * to use indefinite length constructed encoding, where appropriate
        + */
        +
        +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
        +						const ASN1_ITEM *it)
        +	{
        +	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
        +	}
        +
        +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
        +	{
        +	return asn1_item_flags_i2d(val, out, it, 0);
        +	}
        +
        +/* Encode an ASN1 item, this is use by the
        + * standard 'i2d' function. 'out' points to 
        + * a buffer to output the data to.
        + *
        + * The new i2d has one additional feature. If the output
        + * buffer is NULL (i.e. *out == NULL) then a buffer is
        + * allocated and populated with the encoding.
        + */
        +
        +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
        +					const ASN1_ITEM *it, int flags)
        +	{
        +	if (out && !*out)
        +		{
        +		unsigned char *p, *buf;
        +		int len;
        +		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
        +		if (len <= 0)
        +			return len;
        +		buf = OPENSSL_malloc(len);
        +		if (!buf)
        +			return -1;
        +		p = buf;
        +		ASN1_item_ex_i2d(&val, &p, it, -1, flags);
        +		*out = buf;
        +		return len;
        +		}
        +
        +	return ASN1_item_ex_i2d(&val, out, it, -1, flags);
        +	}
        +
        +/* Encode an item, taking care of IMPLICIT tagging (if any).
        + * This function performs the normal item handling: it can be
        + * used in external types.
        + */
        +
        +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
        +			const ASN1_ITEM *it, int tag, int aclass)
        +	{
        +	const ASN1_TEMPLATE *tt = NULL;
        +	unsigned char *p = NULL;
        +	int i, seqcontlen, seqlen, ndef = 1;
        +	const ASN1_COMPAT_FUNCS *cf;
        +	const ASN1_EXTERN_FUNCS *ef;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_aux_cb *asn1_cb = 0;
        +
        +	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
        +		return 0;
        +
        +	if (aux && aux->asn1_cb)
        +		 asn1_cb = aux->asn1_cb;
        +
        +	switch(it->itype)
        +		{
        +
        +		case ASN1_ITYPE_PRIMITIVE:
        +		if (it->templates)
        +			return asn1_template_ex_i2d(pval, out, it->templates,
        +								tag, aclass);
        +		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
        +		break;
        +
        +		case ASN1_ITYPE_MSTRING:
        +		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
        +
        +		case ASN1_ITYPE_CHOICE:
        +		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
        +				return 0;
        +		i = asn1_get_choice_selector(pval, it);
        +		if ((i >= 0) && (i < it->tcount))
        +			{
        +			ASN1_VALUE **pchval;
        +			const ASN1_TEMPLATE *chtt;
        +			chtt = it->templates + i;
        +			pchval = asn1_get_field_ptr(pval, chtt);
        +			return asn1_template_ex_i2d(pchval, out, chtt,
        +								-1, aclass);
        +			}
        +		/* Fixme: error condition if selector out of range */
        +		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
        +				return 0;
        +		break;
        +
        +		case ASN1_ITYPE_EXTERN:
        +		/* If new style i2d it does all the work */
        +		ef = it->funcs;
        +		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
        +
        +		case ASN1_ITYPE_COMPAT:
        +		/* old style hackery... */
        +		cf = it->funcs;
        +		if (out)
        +			p = *out;
        +		i = cf->asn1_i2d(*pval, out);
        +		/* Fixup for IMPLICIT tag: note this messes up for tags > 30,
        +		 * but so did the old code. Tags > 30 are very rare anyway.
        +		 */
        +		if (out && (tag != -1))
        +			*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
        +		return i;
        +		
        +		case ASN1_ITYPE_NDEF_SEQUENCE:
        +		/* Use indefinite length constructed if requested */
        +		if (aclass & ASN1_TFLG_NDEF) ndef = 2;
        +		/* fall through */
        +
        +		case ASN1_ITYPE_SEQUENCE:
        +		i = asn1_enc_restore(&seqcontlen, out, pval, it);
        +		/* An error occurred */
        +		if (i < 0)
        +			return 0;
        +		/* We have a valid cached encoding... */
        +		if (i > 0)
        +			return seqcontlen;
        +		/* Otherwise carry on */
        +		seqcontlen = 0;
        +		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
        +		if (tag == -1)
        +			{
        +			tag = V_ASN1_SEQUENCE;
        +			/* Retain any other flags in aclass */
        +			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
        +					| V_ASN1_UNIVERSAL;
        +			}
        +		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
        +				return 0;
        +		/* First work out sequence content length */
        +		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
        +			{
        +			const ASN1_TEMPLATE *seqtt;
        +			ASN1_VALUE **pseqval;
        +			seqtt = asn1_do_adb(pval, tt, 1);
        +			if (!seqtt)
        +				return 0;
        +			pseqval = asn1_get_field_ptr(pval, seqtt);
        +			/* FIXME: check for errors in enhanced version */
        +			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
        +								-1, aclass);
        +			}
        +
        +		seqlen = ASN1_object_size(ndef, seqcontlen, tag);
        +		if (!out)
        +			return seqlen;
        +		/* Output SEQUENCE header */
        +		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
        +		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
        +			{
        +			const ASN1_TEMPLATE *seqtt;
        +			ASN1_VALUE **pseqval;
        +			seqtt = asn1_do_adb(pval, tt, 1);
        +			if (!seqtt)
        +				return 0;
        +			pseqval = asn1_get_field_ptr(pval, seqtt);
        +			/* FIXME: check for errors in enhanced version */
        +			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
        +			}
        +		if (ndef == 2)
        +			ASN1_put_eoc(out);
        +		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
        +				return 0;
        +		return seqlen;
        +
        +		default:
        +		return 0;
        +
        +		}
        +	return 0;
        +	}
        +
        +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
        +							const ASN1_TEMPLATE *tt)
        +	{
        +	return asn1_template_ex_i2d(pval, out, tt, -1, 0);
        +	}
        +
        +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
        +				const ASN1_TEMPLATE *tt, int tag, int iclass)
        +	{
        +	int i, ret, flags, ttag, tclass, ndef;
        +	flags = tt->flags;
        +	/* Work out tag and class to use: tagging may come
        +	 * either from the template or the arguments, not both
        +	 * because this would create ambiguity. Additionally
        +	 * the iclass argument may contain some additional flags
        +	 * which should be noted and passed down to other levels.
        +	 */
        +	if (flags & ASN1_TFLG_TAG_MASK)
        +		{
        +		/* Error if argument and template tagging */
        +		if (tag != -1)
        +			/* FIXME: error code here */
        +			return -1;
        +		/* Get tagging from template */
        +		ttag = tt->tag;
        +		tclass = flags & ASN1_TFLG_TAG_CLASS;
        +		}
        +	else if (tag != -1)
        +		{
        +		/* No template tagging, get from arguments */
        +		ttag = tag;
        +		tclass = iclass & ASN1_TFLG_TAG_CLASS;
        +		}
        +	else
        +		{
        +		ttag = -1;
        +		tclass = 0;
        +		}
        +	/* 
        +	 * Remove any class mask from iflag.
        +	 */
        +	iclass &= ~ASN1_TFLG_TAG_CLASS;
        +
        +	/* At this point 'ttag' contains the outer tag to use,
        +	 * 'tclass' is the class and iclass is any flags passed
        +	 * to this function.
        +	 */
        +
        +	/* if template and arguments require ndef, use it */
        +	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
        +		ndef = 2;
        +	else ndef = 1;
        +
        +	if (flags & ASN1_TFLG_SK_MASK)
        +		{
        +		/* SET OF, SEQUENCE OF */
        +		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
        +		int isset, sktag, skaclass;
        +		int skcontlen, sklen;
        +		ASN1_VALUE *skitem;
        +
        +		if (!*pval)
        +			return 0;
        +
        +		if (flags & ASN1_TFLG_SET_OF)
        +			{
        +			isset = 1;
        +			/* 2 means we reorder */
        +			if (flags & ASN1_TFLG_SEQUENCE_OF)
        +				isset = 2;
        +			}
        +		else isset = 0;
        +
        +		/* Work out inner tag value: if EXPLICIT
        +		 * or no tagging use underlying type.
        +		 */
        +		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
        +			{
        +			sktag = ttag;
        +			skaclass = tclass;
        +			}
        +		else
        +			{
        +			skaclass = V_ASN1_UNIVERSAL;
        +			if (isset)
        +				sktag = V_ASN1_SET;
        +			else sktag = V_ASN1_SEQUENCE;
        +			}
        +
        +		/* Determine total length of items */
        +		skcontlen = 0;
        +		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
        +			{
        +			skitem = sk_ASN1_VALUE_value(sk, i);
        +			skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
        +						ASN1_ITEM_ptr(tt->item),
        +							-1, iclass);
        +			}
        +		sklen = ASN1_object_size(ndef, skcontlen, sktag);
        +		/* If EXPLICIT need length of surrounding tag */
        +		if (flags & ASN1_TFLG_EXPTAG)
        +			ret = ASN1_object_size(ndef, sklen, ttag);
        +		else ret = sklen;
        +
        +		if (!out)
        +			return ret;
        +
        +		/* Now encode this lot... */
        +		/* EXPLICIT tag */
        +		if (flags & ASN1_TFLG_EXPTAG)
        +			ASN1_put_object(out, ndef, sklen, ttag, tclass);
        +		/* SET or SEQUENCE and IMPLICIT tag */
        +		ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
        +		/* And the stuff itself */
        +		asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
        +								isset, iclass);
        +		if (ndef == 2)
        +			{
        +			ASN1_put_eoc(out);
        +			if (flags & ASN1_TFLG_EXPTAG)
        +				ASN1_put_eoc(out);
        +			}
        +
        +		return ret;
        +		}
        +
        +	if (flags & ASN1_TFLG_EXPTAG)
        +		{
        +		/* EXPLICIT tagging */
        +		/* Find length of tagged item */
        +		i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
        +								-1, iclass);
        +		if (!i)
        +			return 0;
        +		/* Find length of EXPLICIT tag */
        +		ret = ASN1_object_size(ndef, i, ttag);
        +		if (out)
        +			{
        +			/* Output tag and item */
        +			ASN1_put_object(out, ndef, i, ttag, tclass);
        +			ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
        +								-1, iclass);
        +			if (ndef == 2)
        +				ASN1_put_eoc(out);
        +			}
        +		return ret;
        +		}
        +
        +	/* Either normal or IMPLICIT tagging: combine class and flags */
        +	return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
        +						ttag, tclass | iclass);
        +
        +}
        +
        +/* Temporary structure used to hold DER encoding of items for SET OF */
        +
        +typedef	struct {
        +	unsigned char *data;
        +	int length;
        +	ASN1_VALUE *field;
        +} DER_ENC;
        +
        +static int der_cmp(const void *a, const void *b)
        +	{
        +	const DER_ENC *d1 = a, *d2 = b;
        +	int cmplen, i;
        +	cmplen = (d1->length < d2->length) ? d1->length : d2->length;
        +	i = memcmp(d1->data, d2->data, cmplen);
        +	if (i)
        +		return i;
        +	return d1->length - d2->length;
        +	}
        +
        +/* Output the content octets of SET OF or SEQUENCE OF */
        +
        +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
        +					int skcontlen, const ASN1_ITEM *item,
        +					int do_sort, int iclass)
        +	{
        +	int i;
        +	ASN1_VALUE *skitem;
        +	unsigned char *tmpdat = NULL, *p = NULL;
        +	DER_ENC *derlst = NULL, *tder;
        +	if (do_sort)
        +		 {
        +		/* Don't need to sort less than 2 items */
        +		if (sk_ASN1_VALUE_num(sk) < 2)
        +			do_sort = 0;
        +		else
        +			{
        +			derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
        +						* sizeof(*derlst));
        +			tmpdat = OPENSSL_malloc(skcontlen);
        +			if (!derlst || !tmpdat)
        +				return 0;
        +			}
        +		}
        +	/* If not sorting just output each item */
        +	if (!do_sort)
        +		{
        +		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
        +			{
        +			skitem = sk_ASN1_VALUE_value(sk, i);
        +			ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
        +			}
        +		return 1;
        +		}
        +	p = tmpdat;
        +
        +	/* Doing sort: build up a list of each member's DER encoding */
        +	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
        +		{
        +		skitem = sk_ASN1_VALUE_value(sk, i);
        +		tder->data = p;
        +		tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
        +		tder->field = skitem;
        +		}
        +
        +	/* Now sort them */
        +	qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
        +	/* Output sorted DER encoding */	
        +	p = *out;
        +	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
        +		{
        +		memcpy(p, tder->data, tder->length);
        +		p += tder->length;
        +		}
        +	*out = p;
        +	/* If do_sort is 2 then reorder the STACK */
        +	if (do_sort == 2)
        +		{
        +		for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
        +							i++, tder++)
        +			(void)sk_ASN1_VALUE_set(sk, i, tder->field);
        +		}
        +	OPENSSL_free(derlst);
        +	OPENSSL_free(tmpdat);
        +	return 1;
        +	}
        +
        +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
        +				const ASN1_ITEM *it, int tag, int aclass)
        +	{
        +	int len;
        +	int utype;
        +	int usetag;
        +	int ndef = 0;
        +
        +	utype = it->utype;
        +
        +	/* Get length of content octets and maybe find
        +	 * out the underlying type.
        +	 */
        +
        +	len = asn1_ex_i2c(pval, NULL, &utype, it);
        +
        +	/* If SEQUENCE, SET or OTHER then header is
        +	 * included in pseudo content octets so don't
        +	 * include tag+length. We need to check here
        +	 * because the call to asn1_ex_i2c() could change
        +	 * utype.
        +	 */
        +	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
        +	   (utype == V_ASN1_OTHER))
        +		usetag = 0;
        +	else usetag = 1;
        +
        +	/* -1 means omit type */
        +
        +	if (len == -1)
        +		return 0;
        +
        +	/* -2 return is special meaning use ndef */
        +	if (len == -2)
        +		{
        +		ndef = 2;
        +		len = 0;
        +		}
        +
        +	/* If not implicitly tagged get tag from underlying type */
        +	if (tag == -1) tag = utype;
        +
        +	/* Output tag+length followed by content octets */
        +	if (out)
        +		{
        +		if (usetag)
        +			ASN1_put_object(out, ndef, len, tag, aclass);
        +		asn1_ex_i2c(pval, *out, &utype, it);
        +		if (ndef)
        +			ASN1_put_eoc(out);
        +		else
        +			*out += len;
        +		}
        +
        +	if (usetag)
        +		return ASN1_object_size(ndef, len, tag);
        +	return len;
        +	}
        +
        +/* Produce content octets from a structure */
        +
        +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
        +				const ASN1_ITEM *it)
        +	{
        +	ASN1_BOOLEAN *tbool = NULL;
        +	ASN1_STRING *strtmp;
        +	ASN1_OBJECT *otmp;
        +	int utype;
        +	const unsigned char *cont;
        +	unsigned char c;
        +	int len;
        +	const ASN1_PRIMITIVE_FUNCS *pf;
        +	pf = it->funcs;
        +	if (pf && pf->prim_i2c)
        +		return pf->prim_i2c(pval, cout, putype, it);
        +
        +	/* Should type be omitted? */
        +	if ((it->itype != ASN1_ITYPE_PRIMITIVE)
        +		|| (it->utype != V_ASN1_BOOLEAN))
        +		{
        +		if (!*pval) return -1;
        +		}
        +
        +	if (it->itype == ASN1_ITYPE_MSTRING)
        +		{
        +		/* If MSTRING type set the underlying type */
        +		strtmp = (ASN1_STRING *)*pval;
        +		utype = strtmp->type;
        +		*putype = utype;
        +		}
        +	else if (it->utype == V_ASN1_ANY)
        +		{
        +		/* If ANY set type and pointer to value */
        +		ASN1_TYPE *typ;
        +		typ = (ASN1_TYPE *)*pval;
        +		utype = typ->type;
        +		*putype = utype;
        +		pval = &typ->value.asn1_value;
        +		}
        +	else utype = *putype;
        +
        +	switch(utype)
        +		{
        +		case V_ASN1_OBJECT:
        +		otmp = (ASN1_OBJECT *)*pval;
        +		cont = otmp->data;
        +		len = otmp->length;
        +		break;
        +
        +		case V_ASN1_NULL:
        +		cont = NULL;
        +		len = 0;
        +		break;
        +
        +		case V_ASN1_BOOLEAN:
        +		tbool = (ASN1_BOOLEAN *)pval;
        +		if (*tbool == -1)
        +			return -1;
        +		if (it->utype != V_ASN1_ANY)
        +			{
        +			/* Default handling if value == size field then omit */
        +			if (*tbool && (it->size > 0))
        +				return -1;
        +			if (!*tbool && !it->size)
        +				return -1;
        +			}
        +		c = (unsigned char)*tbool;
        +		cont = &c;
        +		len = 1;
        +		break;
        +
        +		case V_ASN1_BIT_STRING:
        +		return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
        +							cout ? &cout : NULL);
        +		break;
        +
        +		case V_ASN1_INTEGER:
        +		case V_ASN1_NEG_INTEGER:
        +		case V_ASN1_ENUMERATED:
        +		case V_ASN1_NEG_ENUMERATED:
        +		/* These are all have the same content format
        +		 * as ASN1_INTEGER
        +		 */
        +		return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
        +							cout ? &cout : NULL);
        +		break;
        +
        +		case V_ASN1_OCTET_STRING:
        +		case V_ASN1_NUMERICSTRING:
        +		case V_ASN1_PRINTABLESTRING:
        +		case V_ASN1_T61STRING:
        +		case V_ASN1_VIDEOTEXSTRING:
        +		case V_ASN1_IA5STRING:
        +		case V_ASN1_UTCTIME:
        +		case V_ASN1_GENERALIZEDTIME:
        +		case V_ASN1_GRAPHICSTRING:
        +		case V_ASN1_VISIBLESTRING:
        +		case V_ASN1_GENERALSTRING:
        +		case V_ASN1_UNIVERSALSTRING:
        +		case V_ASN1_BMPSTRING:
        +		case V_ASN1_UTF8STRING:
        +		case V_ASN1_SEQUENCE:
        +		case V_ASN1_SET:
        +		default:
        +		/* All based on ASN1_STRING and handled the same */
        +		strtmp = (ASN1_STRING *)*pval;
        +		/* Special handling for NDEF */
        +		if ((it->size == ASN1_TFLG_NDEF)
        +			&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
        +			{
        +			if (cout)
        +				{
        +				strtmp->data = cout;
        +				strtmp->length = 0;
        +				}
        +			/* Special return code */
        +			return -2;
        +			}
        +		cont = strtmp->data;
        +		len = strtmp->length;
        +
        +		break;
        +
        +		}
        +	if (cout && len)
        +		memcpy(cout, cont, len);
        +	return len;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_fre.c b/vendor/openssl/openssl/crypto/asn1/tasn_fre.c
        new file mode 100644
        index 000000000..77d3092d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_fre.c
        @@ -0,0 +1,266 @@
        +/* tasn_fre.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stddef.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +
        +static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
        +
        +/* Free up an ASN1 structure */
        +
        +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
        +	{
        +	asn1_item_combine_free(&val, it, 0);
        +	}
        +
        +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	asn1_item_combine_free(pval, it, 0);
        +	}
        +
        +static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
        +	{
        +	const ASN1_TEMPLATE *tt = NULL, *seqtt;
        +	const ASN1_EXTERN_FUNCS *ef;
        +	const ASN1_COMPAT_FUNCS *cf;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_aux_cb *asn1_cb;
        +	int i;
        +	if (!pval)
        +		return;
        +	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
        +		return;
        +	if (aux && aux->asn1_cb)
        +		asn1_cb = aux->asn1_cb;
        +	else
        +		asn1_cb = 0;
        +
        +	switch(it->itype)
        +		{
        +
        +		case ASN1_ITYPE_PRIMITIVE:
        +		if (it->templates)
        +			ASN1_template_free(pval, it->templates);
        +		else
        +			ASN1_primitive_free(pval, it);
        +		break;
        +
        +		case ASN1_ITYPE_MSTRING:
        +		ASN1_primitive_free(pval, it);
        +		break;
        +
        +		case ASN1_ITYPE_CHOICE:
        +		if (asn1_cb)
        +			{
        +			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
        +			if (i == 2)
        +				return;
        +			}
        +		i = asn1_get_choice_selector(pval, it);
        +		if ((i >= 0) && (i < it->tcount))
        +			{
        +			ASN1_VALUE **pchval;
        +			tt = it->templates + i;
        +			pchval = asn1_get_field_ptr(pval, tt);
        +			ASN1_template_free(pchval, tt);
        +			}
        +		if (asn1_cb)
        +			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
        +		if (!combine)
        +			{
        +			OPENSSL_free(*pval);
        +			*pval = NULL;
        +			}
        +		break;
        +
        +		case ASN1_ITYPE_COMPAT:
        +		cf = it->funcs;
        +		if (cf && cf->asn1_free)
        +			cf->asn1_free(*pval);
        +		break;
        +
        +		case ASN1_ITYPE_EXTERN:
        +		ef = it->funcs;
        +		if (ef && ef->asn1_ex_free)
        +			ef->asn1_ex_free(pval, it);
        +		break;
        +
        +		case ASN1_ITYPE_NDEF_SEQUENCE:
        +		case ASN1_ITYPE_SEQUENCE:
        +		if (asn1_do_lock(pval, -1, it) > 0)
        +			return;
        +		if (asn1_cb)
        +			{
        +			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
        +			if (i == 2)
        +				return;
        +			}		
        +		asn1_enc_free(pval, it);
        +		/* If we free up as normal we will invalidate any
        +		 * ANY DEFINED BY field and we wont be able to 
        +		 * determine the type of the field it defines. So
        +		 * free up in reverse order.
        +		 */
        +		tt = it->templates + it->tcount - 1;
        +		for (i = 0; i < it->tcount; tt--, i++)
        +			{
        +			ASN1_VALUE **pseqval;
        +			seqtt = asn1_do_adb(pval, tt, 0);
        +			if (!seqtt)
        +				continue;
        +			pseqval = asn1_get_field_ptr(pval, seqtt);
        +			ASN1_template_free(pseqval, seqtt);
        +			}
        +		if (asn1_cb)
        +			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
        +		if (!combine)
        +			{
        +			OPENSSL_free(*pval);
        +			*pval = NULL;
        +			}
        +		break;
        +		}
        +	}
        +
        +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
        +	{
        +	int i;
        +	if (tt->flags & ASN1_TFLG_SK_MASK)
        +		{
        +		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
        +		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
        +			{
        +			ASN1_VALUE *vtmp;
        +			vtmp = sk_ASN1_VALUE_value(sk, i);
        +			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
        +									0);
        +			}
        +		sk_ASN1_VALUE_free(sk);
        +		*pval = NULL;
        +		}
        +	else
        +		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
        +						tt->flags & ASN1_TFLG_COMBINE);
        +	}
        +
        +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	int utype;
        +	if (it)
        +		{
        +		const ASN1_PRIMITIVE_FUNCS *pf;
        +		pf = it->funcs;
        +		if (pf && pf->prim_free)
        +			{
        +			pf->prim_free(pval, it);
        +			return;
        +			}
        +		}
        +	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
        +	if (!it)
        +		{
        +		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
        +		utype = typ->type;
        +		pval = &typ->value.asn1_value;
        +		if (!*pval)
        +			return;
        +		}
        +	else if (it->itype == ASN1_ITYPE_MSTRING)
        +		{
        +		utype = -1;
        +		if (!*pval)
        +			return;
        +		}
        +	else
        +		{
        +		utype = it->utype;
        +		if ((utype != V_ASN1_BOOLEAN) && !*pval)
        +			return;
        +		}
        +
        +	switch(utype)
        +		{
        +		case V_ASN1_OBJECT:
        +		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
        +		break;
        +
        +		case V_ASN1_BOOLEAN:
        +		if (it)
        +			*(ASN1_BOOLEAN *)pval = it->size;
        +		else
        +			*(ASN1_BOOLEAN *)pval = -1;
        +		return;
        +
        +		case V_ASN1_NULL:
        +		break;
        +
        +		case V_ASN1_ANY:
        +		ASN1_primitive_free(pval, NULL);
        +		OPENSSL_free(*pval);
        +		break;
        +
        +		default:
        +		ASN1_STRING_free((ASN1_STRING *)*pval);
        +		*pval = NULL;
        +		break;
        +		}
        +	*pval = NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_new.c b/vendor/openssl/openssl/crypto/asn1/tasn_new.c
        new file mode 100644
        index 000000000..0d9e78cc7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_new.c
        @@ -0,0 +1,396 @@
        +/* tasn_new.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2004 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 <stddef.h>
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/err.h>
        +#include <openssl/asn1t.h>
        +#include <string.h>
        +
        +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								int combine);
        +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
        +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +
        +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
        +	{
        +	ASN1_VALUE *ret = NULL;
        +	if (ASN1_item_ex_new(&ret, it) > 0)
        +		return ret;
        +	return NULL;
        +	}
        +
        +/* Allocate an ASN1 structure */
        +
        +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	return asn1_item_ex_combine_new(pval, it, 0);
        +	}
        +
        +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								int combine)
        +	{
        +	const ASN1_TEMPLATE *tt = NULL;
        +	const ASN1_COMPAT_FUNCS *cf;
        +	const ASN1_EXTERN_FUNCS *ef;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_aux_cb *asn1_cb;
        +	ASN1_VALUE **pseqval;
        +	int i;
        +	if (aux && aux->asn1_cb)
        +		asn1_cb = aux->asn1_cb;
        +	else
        +		asn1_cb = 0;
        +
        +	if (!combine) *pval = NULL;
        +
        +#ifdef CRYPTO_MDEBUG
        +	if (it->sname)
        +		CRYPTO_push_info(it->sname);
        +#endif
        +
        +	switch(it->itype)
        +		{
        +
        +		case ASN1_ITYPE_EXTERN:
        +		ef = it->funcs;
        +		if (ef && ef->asn1_ex_new)
        +			{
        +			if (!ef->asn1_ex_new(pval, it))
        +				goto memerr;
        +			}
        +		break;
        +
        +		case ASN1_ITYPE_COMPAT:
        +		cf = it->funcs;
        +		if (cf && cf->asn1_new) {
        +			*pval = cf->asn1_new();
        +			if (!*pval)
        +				goto memerr;
        +		}
        +		break;
        +
        +		case ASN1_ITYPE_PRIMITIVE:
        +		if (it->templates)
        +			{
        +			if (!ASN1_template_new(pval, it->templates))
        +				goto memerr;
        +			}
        +		else if (!ASN1_primitive_new(pval, it))
        +				goto memerr;
        +		break;
        +
        +		case ASN1_ITYPE_MSTRING:
        +		if (!ASN1_primitive_new(pval, it))
        +				goto memerr;
        +		break;
        +
        +		case ASN1_ITYPE_CHOICE:
        +		if (asn1_cb)
        +			{
        +			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
        +			if (!i)
        +				goto auxerr;
        +			if (i==2)
        +				{
        +#ifdef CRYPTO_MDEBUG
        +				if (it->sname)
        +					CRYPTO_pop_info();
        +#endif
        +				return 1;
        +				}
        +			}
        +		if (!combine)
        +			{
        +			*pval = OPENSSL_malloc(it->size);
        +			if (!*pval)
        +				goto memerr;
        +			memset(*pval, 0, it->size);
        +			}
        +		asn1_set_choice_selector(pval, -1, it);
        +		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
        +				goto auxerr;
        +		break;
        +
        +		case ASN1_ITYPE_NDEF_SEQUENCE:
        +		case ASN1_ITYPE_SEQUENCE:
        +		if (asn1_cb)
        +			{
        +			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
        +			if (!i)
        +				goto auxerr;
        +			if (i==2)
        +				{
        +#ifdef CRYPTO_MDEBUG
        +				if (it->sname)
        +					CRYPTO_pop_info();
        +#endif
        +				return 1;
        +				}
        +			}
        +		if (!combine)
        +			{
        +			*pval = OPENSSL_malloc(it->size);
        +			if (!*pval)
        +				goto memerr;
        +			memset(*pval, 0, it->size);
        +			asn1_do_lock(pval, 0, it);
        +			asn1_enc_init(pval, it);
        +			}
        +		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
        +			{
        +			pseqval = asn1_get_field_ptr(pval, tt);
        +			if (!ASN1_template_new(pseqval, tt))
        +				goto memerr;
        +			}
        +		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
        +				goto auxerr;
        +		break;
        +	}
        +#ifdef CRYPTO_MDEBUG
        +	if (it->sname) CRYPTO_pop_info();
        +#endif
        +	return 1;
        +
        +	memerr:
        +	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
        +#ifdef CRYPTO_MDEBUG
        +	if (it->sname) CRYPTO_pop_info();
        +#endif
        +	return 0;
        +
        +	auxerr:
        +	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
        +	ASN1_item_ex_free(pval, it);
        +#ifdef CRYPTO_MDEBUG
        +	if (it->sname) CRYPTO_pop_info();
        +#endif
        +	return 0;
        +
        +	}
        +
        +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	const ASN1_EXTERN_FUNCS *ef;
        +
        +	switch(it->itype)
        +		{
        +
        +		case ASN1_ITYPE_EXTERN:
        +		ef = it->funcs;
        +		if (ef && ef->asn1_ex_clear) 
        +			ef->asn1_ex_clear(pval, it);
        +		else *pval = NULL;
        +		break;
        +
        +
        +		case ASN1_ITYPE_PRIMITIVE:
        +		if (it->templates) 
        +			asn1_template_clear(pval, it->templates);
        +		else
        +			asn1_primitive_clear(pval, it);
        +		break;
        +
        +		case ASN1_ITYPE_MSTRING:
        +		asn1_primitive_clear(pval, it);
        +		break;
        +
        +		case ASN1_ITYPE_COMPAT:
        +		case ASN1_ITYPE_CHOICE:
        +		case ASN1_ITYPE_SEQUENCE:
        +		case ASN1_ITYPE_NDEF_SEQUENCE:
        +		*pval = NULL;
        +		break;
        +		}
        +	}
        +
        +
        +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
        +	{
        +	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
        +	int ret;
        +	if (tt->flags & ASN1_TFLG_OPTIONAL)
        +		{
        +		asn1_template_clear(pval, tt);
        +		return 1;
        +		}
        +	/* If ANY DEFINED BY nothing to do */
        +
        +	if (tt->flags & ASN1_TFLG_ADB_MASK)
        +		{
        +		*pval = NULL;
        +		return 1;
        +		}
        +#ifdef CRYPTO_MDEBUG
        +	if (tt->field_name)
        +		CRYPTO_push_info(tt->field_name);
        +#endif
        +	/* If SET OF or SEQUENCE OF, its a STACK */
        +	if (tt->flags & ASN1_TFLG_SK_MASK)
        +		{
        +		STACK_OF(ASN1_VALUE) *skval;
        +		skval = sk_ASN1_VALUE_new_null();
        +		if (!skval)
        +			{
        +			ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
        +			ret = 0;
        +			goto done;
        +			}
        +		*pval = (ASN1_VALUE *)skval;
        +		ret = 1;
        +		goto done;
        +		}
        +	/* Otherwise pass it back to the item routine */
        +	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
        +	done:
        +#ifdef CRYPTO_MDEBUG
        +	if (it->sname)
        +		CRYPTO_pop_info();
        +#endif
        +	return ret;
        +	}
        +
        +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
        +	{
        +	/* If ADB or STACK just NULL the field */
        +	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 
        +		*pval = NULL;
        +	else
        +		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
        +	}
        +
        +
        +/* NB: could probably combine most of the real XXX_new() behaviour and junk
        + * all the old functions.
        + */
        +
        +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	ASN1_TYPE *typ;
        +	ASN1_STRING *str;
        +	int utype;
        +
        +	if (it && it->funcs)
        +		{
        +		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
        +		if (pf->prim_new)
        +			return pf->prim_new(pval, it);
        +		}
        +
        +	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
        +		utype = -1;
        +	else
        +		utype = it->utype;
        +	switch(utype)
        +		{
        +		case V_ASN1_OBJECT:
        +		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
        +		return 1;
        +
        +		case V_ASN1_BOOLEAN:
        +		*(ASN1_BOOLEAN *)pval = it->size;
        +		return 1;
        +
        +		case V_ASN1_NULL:
        +		*pval = (ASN1_VALUE *)1;
        +		return 1;
        +
        +		case V_ASN1_ANY:
        +		typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
        +		if (!typ)
        +			return 0;
        +		typ->value.ptr = NULL;
        +		typ->type = -1;
        +		*pval = (ASN1_VALUE *)typ;
        +		break;
        +
        +		default:
        +		str = ASN1_STRING_type_new(utype);
        +		if (it->itype == ASN1_ITYPE_MSTRING && str)
        +			str->flags |= ASN1_STRING_FLAG_MSTRING;
        +		*pval = (ASN1_VALUE *)str;
        +		break;
        +		}
        +	if (*pval)
        +		return 1;
        +	return 0;
        +	}
        +
        +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	int utype;
        +	if (it && it->funcs)
        +		{
        +		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
        +		if (pf->prim_clear)
        +			pf->prim_clear(pval, it);
        +		else 
        +			*pval = NULL;
        +		return;
        +		}
        +	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
        +		utype = -1;
        +	else
        +		utype = it->utype;
        +	if (utype == V_ASN1_BOOLEAN)
        +		*(ASN1_BOOLEAN *)pval = it->size;
        +	else *pval = NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_prn.c b/vendor/openssl/openssl/crypto/asn1/tasn_prn.c
        new file mode 100644
        index 000000000..542a091a6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_prn.c
        @@ -0,0 +1,627 @@
        +/* tasn_prn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000,2005 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 <stddef.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +#include <openssl/err.h>
        +#include <openssl/x509v3.h>
        +#include "asn1_locl.h"
        +
        +/* Print routines.
        + */
        +
        +/* ASN1_PCTX routines */
        +
        +ASN1_PCTX default_pctx = 
        +	{
        +	ASN1_PCTX_FLAGS_SHOW_ABSENT,	/* flags */
        +	0,	/* nm_flags */
        +	0,	/* cert_flags */
        +	0,	/* oid_flags */
        +	0	/* str_flags */
        +	};
        +	
        +
        +ASN1_PCTX *ASN1_PCTX_new(void)
        +	{
        +	ASN1_PCTX *ret;
        +	ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	ret->flags = 0;
        +	ret->nm_flags = 0;
        +	ret->cert_flags = 0;
        +	ret->oid_flags = 0;
        +	ret->str_flags = 0;
        +	return ret;
        +	}
        +
        +void ASN1_PCTX_free(ASN1_PCTX *p)
        +	{
        +	OPENSSL_free(p);
        +	}
        +
        +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
        +	{
        +	return p->flags;
        +	}
        +
        +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
        +	{
        +	p->flags = flags;
        +	}
        +
        +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
        +	{
        +	return p->nm_flags;
        +	}
        +
        +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
        +	{
        +	p->nm_flags = flags;
        +	}
        +
        +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
        +	{
        +	return p->cert_flags;
        +	}
        +
        +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
        +	{
        +	p->cert_flags = flags;
        +	}
        +
        +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
        +	{
        +	return p->oid_flags;
        +	}
        +
        +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
        +	{
        +	p->oid_flags = flags;
        +	}
        +
        +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
        +	{
        +	return p->str_flags;
        +	}
        +
        +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
        +	{
        +	p->str_flags = flags;
        +	}
        +
        +/* Main print routines */
        +
        +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
        +				const ASN1_ITEM *it,
        +				const char *fname, const char *sname,
        +				int nohdr, const ASN1_PCTX *pctx);
        +
        +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
        +				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
        +
        +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
        +				const ASN1_ITEM *it, int indent,
        +				const char *fname, const char *sname,
        +				const ASN1_PCTX *pctx);
        +
        +static int asn1_print_fsname(BIO *out, int indent,
        +			const char *fname, const char *sname,
        +			const ASN1_PCTX *pctx);
        +
        +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
        +				const ASN1_ITEM *it, const ASN1_PCTX *pctx)
        +	{
        +	const char *sname;
        +	if (pctx == NULL)
        +		pctx = &default_pctx;
        +	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
        +		sname = NULL;
        +	else
        +		sname = it->sname;
        +	return asn1_item_print_ctx(out, &ifld, indent, it,
        +							NULL, sname, 0, pctx);
        +	}
        +
        +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
        +				const ASN1_ITEM *it,
        +				const char *fname, const char *sname,
        +				int nohdr, const ASN1_PCTX *pctx)
        +	{
        +	const ASN1_TEMPLATE *tt;
        +	const ASN1_EXTERN_FUNCS *ef;
        +	ASN1_VALUE **tmpfld;
        +	const ASN1_AUX *aux = it->funcs;
        +	ASN1_aux_cb *asn1_cb;
        +	ASN1_PRINT_ARG parg;
        +	int i;
        +	if (aux && aux->asn1_cb)
        +		{
        +		parg.out = out;
        +		parg.indent = indent;
        +		parg.pctx = pctx;
        +		asn1_cb = aux->asn1_cb;
        +		}
        +	else asn1_cb = 0;
        +
        +	if(*fld == NULL)
        +		{
        +		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
        +			{
        +			if (!nohdr && !asn1_print_fsname(out, indent,
        +							fname, sname, pctx))
        +				return 0;
        +			if (BIO_puts(out, "<ABSENT>\n") <= 0)
        +				return 0;
        +			}
        +		return 1;
        +		}
        +
        +	switch(it->itype)
        +		{
        +		case ASN1_ITYPE_PRIMITIVE:
        +		if(it->templates)
        +			{
        +			if (!asn1_template_print_ctx(out, fld, indent,
        +							it->templates, pctx))
        +				return 0;
        +			}
        +		/* fall thru */
        +		case ASN1_ITYPE_MSTRING:
        +		if (!asn1_primitive_print(out, fld, it,
        +				indent, fname, sname,pctx))
        +			return 0;
        +		break;
        +
        +		case ASN1_ITYPE_EXTERN:
        +		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
        +			return 0;
        +		/* Use new style print routine if possible */
        +		ef = it->funcs;
        +		if (ef && ef->asn1_ex_print)
        +			{
        +			i = ef->asn1_ex_print(out, fld, indent, "", pctx);
        +			if (!i)
        +				return 0;
        +			if ((i == 2) && (BIO_puts(out, "\n") <= 0))
        +				return 0;
        +			return 1;
        +			}
        +		else if (sname && 
        +			BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
        +			return 0;
        +		break;
        +
        +		case ASN1_ITYPE_CHOICE:
        +#if 0
        +		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
        +			return 0;
        +#endif
        +		/* CHOICE type, get selector */
        +		i = asn1_get_choice_selector(fld, it);
        +		/* This should never happen... */
        +		if((i < 0) || (i >= it->tcount))
        +			{
        +			if (BIO_printf(out,
        +				"ERROR: selector [%d] invalid\n", i) <= 0)
        +				return 0;
        +			return 1;
        +			}
        +		tt = it->templates + i;
        +		tmpfld = asn1_get_field_ptr(fld, tt);
        +		if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
        +			return 0;
        +		break;
        +
        +		case ASN1_ITYPE_SEQUENCE:
        +		case ASN1_ITYPE_NDEF_SEQUENCE:
        +		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
        +			return 0;
        +		if (fname || sname)
        +			{
        +			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
        +				{
        +				if (BIO_puts(out, " {\n") <= 0)
        +					return 0;
        +				}
        +			else
        +				{
        +				if (BIO_puts(out, "\n") <= 0)
        +					return 0;
        +				}
        +			}
        +
        +		if (asn1_cb)
        +			{
        +			i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
        +			if (i == 0)
        +				return 0;
        +			if (i == 2)
        +				return 1;
        +			}
        +
        +		/* Print each field entry */
        +		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
        +			{
        +			const ASN1_TEMPLATE *seqtt;
        +			seqtt = asn1_do_adb(fld, tt, 1);
        +			tmpfld = asn1_get_field_ptr(fld, seqtt);
        +			if (!asn1_template_print_ctx(out, tmpfld,
        +						indent + 2, seqtt, pctx))
        +				return 0;
        +			}
        +		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
        +			{
        +			if (BIO_printf(out, "%*s}\n", indent, "") < 0)
        +				return 0;
        +			}
        +
        +		if (asn1_cb)
        +			{
        +			i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
        +			if (i == 0)
        +				return 0;
        +			}
        +		break;
        +
        +		default:
        +		BIO_printf(out, "Unprocessed type %d\n", it->itype);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
        +				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
        +	{
        +	int i, flags;
        +	const char *sname, *fname;
        +	flags = tt->flags;
        +	if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
        +		sname = ASN1_ITEM_ptr(tt->item)->sname;
        +	else
        +		sname = NULL;
        +	if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
        +		fname = NULL;
        +	else
        +		fname = tt->field_name;
        +	if(flags & ASN1_TFLG_SK_MASK)
        +		{
        +		char *tname;
        +		ASN1_VALUE *skitem;
        +		STACK_OF(ASN1_VALUE) *stack;
        +
        +		/* SET OF, SEQUENCE OF */
        +		if (fname)
        +			{
        +			if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
        +				{
        +				if(flags & ASN1_TFLG_SET_OF)
        +					tname = "SET";
        +				else
        +					tname = "SEQUENCE";
        +				if (BIO_printf(out, "%*s%s OF %s {\n",
        +					indent, "", tname, tt->field_name) <= 0)
        +					return 0;
        +				}
        +			else if (BIO_printf(out, "%*s%s:\n", indent, "",
        +					fname) <= 0)
        +				return 0;
        +			}
        +		stack = (STACK_OF(ASN1_VALUE) *)*fld;
        +		for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
        +			{
        +			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
        +				return 0;
        +
        +			skitem = sk_ASN1_VALUE_value(stack, i);
        +			if (!asn1_item_print_ctx(out, &skitem, indent + 2,
        +				ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
        +				return 0;
        +			}
        +		if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
        +				return 0;
        +		if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
        +			{
        +			if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
        +				return 0;
        +			}
        +		return 1;
        +		}
        +	return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
        +							fname, sname, 0, pctx);
        +	}
        +
        +static int asn1_print_fsname(BIO *out, int indent,
        +			const char *fname, const char *sname,
        +			const ASN1_PCTX *pctx)
        +	{
        +	static char spaces[] = "                    ";
        +	const int nspaces = sizeof(spaces) - 1;
        +
        +#if 0
        +	if (!sname && !fname)
        +		return 1;
        +#endif
        +
        +	while (indent > nspaces)
        +		{
        +		if (BIO_write(out, spaces, nspaces) != nspaces)
        +			return 0;
        +		indent -= nspaces;
        +		}
        +	if (BIO_write(out, spaces, indent) != indent)
        +		return 0;
        +	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
        +		sname = NULL;
        +	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
        +		fname = NULL;
        +	if (!sname && !fname)
        +		return 1;
        +	if (fname)
        +		{
        +		if (BIO_puts(out, fname) <= 0)
        +			return 0;
        +		}
        +	if (sname)
        +		{
        +		if (fname)
        +			{
        +			if (BIO_printf(out, " (%s)", sname) <= 0)
        +				return 0;
        +			}
        +		else
        +			{
        +			if (BIO_puts(out, sname) <= 0)
        +				return 0;
        +			}
        +		}
        +	if (BIO_write(out, ": ", 2) != 2)
        +		return 0;
        +	return 1;
        +	}
        +
        +static int asn1_print_boolean_ctx(BIO *out, int boolval,
        +							const ASN1_PCTX *pctx)
        +	{
        +	const char *str;
        +	switch (boolval)
        +		{
        +		case -1:
        +		str = "BOOL ABSENT";
        +		break;
        +
        +		case 0:
        +		str = "FALSE";
        +		break;
        +
        +		default:
        +		str = "TRUE";
        +		break;
        +
        +		}
        +
        +	if (BIO_puts(out, str) <= 0)
        +		return 0;
        +	return 1;
        +
        +	}
        +
        +static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
        +						const ASN1_PCTX *pctx)
        +	{
        +	char *s;
        +	int ret = 1;
        +	s = i2s_ASN1_INTEGER(NULL, str);
        +	if (BIO_puts(out, s) <= 0)
        +		ret = 0;
        +	OPENSSL_free(s);
        +	return ret;
        +	}
        +
        +static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
        +						const ASN1_PCTX *pctx)
        +	{
        +	char objbuf[80];
        +	const char *ln;
        +	ln = OBJ_nid2ln(OBJ_obj2nid(oid));
        +	if(!ln)
        +		ln = "";
        +	OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
        +	if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
        +		return 0;
        +	return 1;
        +	}
        +
        +static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
        +						const ASN1_PCTX *pctx)
        +	{
        +	if (str->type == V_ASN1_BIT_STRING)
        +		{
        +		if (BIO_printf(out, " (%ld unused bits)\n",
        +					str->flags & 0x7) <= 0)
        +				return 0;
        +		}
        +	else if (BIO_puts(out, "\n") <= 0)
        +		return 0;
        +	if ((str->length > 0)
        +		&& BIO_dump_indent(out, (char *)str->data, str->length,
        +				indent + 2) <= 0)
        +		return 0;
        +	return 1;
        +	}
        +
        +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
        +				const ASN1_ITEM *it, int indent,
        +				const char *fname, const char *sname,
        +				const ASN1_PCTX *pctx)
        +	{
        +	long utype;
        +	ASN1_STRING *str;
        +	int ret = 1, needlf = 1;
        +	const char *pname;
        +	const ASN1_PRIMITIVE_FUNCS *pf;
        +	pf = it->funcs;
        +	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
        +			return 0;
        +	if (pf && pf->prim_print)
        +		return pf->prim_print(out, fld, it, indent, pctx);
        +	str = (ASN1_STRING *)*fld;
        +	if (it->itype == ASN1_ITYPE_MSTRING)
        +		utype = str->type & ~V_ASN1_NEG;
        +	else
        +		utype = it->utype;
        +	if (utype == V_ASN1_ANY)
        +		{
        +		ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
        +		utype = atype->type;
        +		fld = &atype->value.asn1_value;
        +		str = (ASN1_STRING *)*fld;
        +		if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
        +			pname = NULL;
        +		else 
        +			pname = ASN1_tag2str(utype);
        +		}
        +	else
        +		{
        +		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
        +			pname = ASN1_tag2str(utype);
        +		else 
        +			pname = NULL;
        +		}
        +
        +	if (utype == V_ASN1_NULL)
        +		{
        +		if (BIO_puts(out, "NULL\n") <= 0)
        +			return 0;
        +		return 1;
        +		}
        +
        +	if (pname)
        +		{
        +		if (BIO_puts(out, pname) <= 0)
        +			return 0;
        +		if (BIO_puts(out, ":") <= 0)
        +			return 0;
        +		}
        +
        +	switch (utype)
        +		{
        +		case V_ASN1_BOOLEAN:
        +			{
        +			int boolval = *(int *)fld;
        +			if (boolval == -1)
        +				boolval = it->size;
        +			ret = asn1_print_boolean_ctx(out, boolval, pctx);
        +			}
        +		break;
        +
        +		case V_ASN1_INTEGER:
        +		case V_ASN1_ENUMERATED:
        +		ret = asn1_print_integer_ctx(out, str, pctx);
        +		break;
        +
        +		case V_ASN1_UTCTIME:
        +		ret = ASN1_UTCTIME_print(out, str);
        +		break;
        +
        +		case V_ASN1_GENERALIZEDTIME:
        +		ret = ASN1_GENERALIZEDTIME_print(out, str);
        +		break;
        +
        +		case V_ASN1_OBJECT:
        +		ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
        +		break;
        +
        +		case V_ASN1_OCTET_STRING:
        +		case V_ASN1_BIT_STRING:
        +		ret = asn1_print_obstring_ctx(out, str, indent, pctx);
        +		needlf = 0;
        +		break;
        +
        +		case V_ASN1_SEQUENCE:
        +		case V_ASN1_SET:
        +		case V_ASN1_OTHER:
        +		if (BIO_puts(out, "\n") <= 0)
        +			return 0;
        +		if (ASN1_parse_dump(out, str->data, str->length,
        +						indent, 0) <= 0)
        +			ret = 0;
        +		needlf = 0;
        +		break;
        +
        +		default:
        +		ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
        +
        +		}
        +	if (!ret)
        +		return 0;
        +	if (needlf && BIO_puts(out, "\n") <= 0)
        +		return 0;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_typ.c b/vendor/openssl/openssl/crypto/asn1/tasn_typ.c
        new file mode 100644
        index 000000000..6fb1c372d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_typ.c
        @@ -0,0 +1,148 @@
        +/* tasn_typ.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stdio.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +
        +/* Declarations for string types */
        +
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_INTEGER)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_NULL)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_T61STRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING)
        +IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING)
        +
        +IMPLEMENT_ASN1_TYPE(ASN1_ANY)
        +
        +/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
        +IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
        +
        +/* Multistring types */
        +
        +IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
        +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
        +
        +IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
        +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
        +
        +IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
        +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
        +
        +/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
        +IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
        +IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
        +IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
        +
        +/* Special, OCTET STRING with indefinite length constructed support */
        +
        +IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
        +
        +ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
        +ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
        +
        +ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
        +ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
        diff --git a/vendor/openssl/openssl/crypto/asn1/tasn_utl.c b/vendor/openssl/openssl/crypto/asn1/tasn_utl.c
        new file mode 100644
        index 000000000..ca9ec7a32
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/tasn_utl.c
        @@ -0,0 +1,279 @@
        +/* tasn_utl.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2004 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 <stddef.h>
        +#include <string.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +#include <openssl/err.h>
        +
        +/* Utility functions for manipulating fields and offsets */
        +
        +/* Add 'offset' to 'addr' */
        +#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
        +
        +/* Given an ASN1_ITEM CHOICE type return
        + * the selector value
        + */
        +
        +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	int *sel = offset2ptr(*pval, it->utype);
        +	return *sel;
        +	}
        +
        +/* Given an ASN1_ITEM CHOICE type set
        + * the selector value, return old value.
        + */
        +
        +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
        +	{	
        +	int *sel, ret;
        +	sel = offset2ptr(*pval, it->utype);
        +	ret = *sel;
        +	*sel = value;
        +	return ret;
        +	}
        +
        +/* Do reference counting. The value 'op' decides what to do. 
        + * if it is +1 then the count is incremented. If op is 0 count is
        + * set to 1. If op is -1 count is decremented and the return value
        + * is the current refrence count or 0 if no reference count exists.
        + */
        +
        +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
        +	{
        +	const ASN1_AUX *aux;
        +	int *lck, ret;
        +	if ((it->itype != ASN1_ITYPE_SEQUENCE)
        +	   && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
        +		return 0;
        +	aux = it->funcs;
        +	if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
        +		return 0;
        +	lck = offset2ptr(*pval, aux->ref_offset);
        +	if (op == 0)
        +		{
        +		*lck = 1;
        +		return 1;
        +		}
        +	ret = CRYPTO_add(lck, op, aux->ref_lock);
        +#ifdef REF_PRINT
        +	fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
        +#endif
        +#ifdef REF_CHECK
        +	if (ret < 0) 
        +		fprintf(stderr, "%s, bad reference count\n", it->sname);
        +#endif
        +	return ret;
        +	}
        +
        +static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	const ASN1_AUX *aux;
        +	if (!pval || !*pval)
        +		return NULL;
        +	aux = it->funcs;
        +	if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
        +		return NULL;
        +	return offset2ptr(*pval, aux->enc_offset);
        +	}
        +
        +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	ASN1_ENCODING *enc;
        +	enc = asn1_get_enc_ptr(pval, it);
        +	if (enc)
        +		{
        +		enc->enc = NULL;
        +		enc->len = 0;
        +		enc->modified = 1;
        +		}
        +	}
        +
        +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +	{
        +	ASN1_ENCODING *enc;
        +	enc = asn1_get_enc_ptr(pval, it);
        +	if (enc)
        +		{
        +		if (enc->enc)
        +			OPENSSL_free(enc->enc);
        +		enc->enc = NULL;
        +		enc->len = 0;
        +		enc->modified = 1;
        +		}
        +	}
        +
        +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
        +							 const ASN1_ITEM *it)
        +	{
        +	ASN1_ENCODING *enc;
        +	enc = asn1_get_enc_ptr(pval, it);
        +	if (!enc)
        +		return 1;
        +
        +	if (enc->enc)
        +		OPENSSL_free(enc->enc);
        +	enc->enc = OPENSSL_malloc(inlen);
        +	if (!enc->enc)
        +		return 0;
        +	memcpy(enc->enc, in, inlen);
        +	enc->len = inlen;
        +	enc->modified = 0;
        +
        +	return 1;
        +	}
        +		
        +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
        +							const ASN1_ITEM *it)
        +	{
        +	ASN1_ENCODING *enc;
        +	enc = asn1_get_enc_ptr(pval, it);
        +	if (!enc || enc->modified)
        +		return 0;
        +	if (out)
        +		{
        +		memcpy(*out, enc->enc, enc->len);
        +		*out += enc->len;
        +		}
        +	if (len)
        +		*len = enc->len;
        +	return 1;
        +	}
        +
        +/* Given an ASN1_TEMPLATE get a pointer to a field */
        +ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
        +	{
        +	ASN1_VALUE **pvaltmp;
        +	if (tt->flags & ASN1_TFLG_COMBINE)
        +		return pval;
        +	pvaltmp = offset2ptr(*pval, tt->offset);
        +	/* NOTE for BOOLEAN types the field is just a plain
        + 	 * int so we can't return int **, so settle for
        +	 * (int *).
        +	 */
        +	return pvaltmp;
        +	}
        +
        +/* Handle ANY DEFINED BY template, find the selector, look up
        + * the relevant ASN1_TEMPLATE in the table and return it.
        + */
        +
        +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
        +								int nullerr)
        +	{
        +	const ASN1_ADB *adb;
        +	const ASN1_ADB_TABLE *atbl;
        +	long selector;
        +	ASN1_VALUE **sfld;
        +	int i;
        +	if (!(tt->flags & ASN1_TFLG_ADB_MASK))
        +		return tt;
        +
        +	/* Else ANY DEFINED BY ... get the table */
        +	adb = ASN1_ADB_ptr(tt->item);
        +
        +	/* Get the selector field */
        +	sfld = offset2ptr(*pval, adb->offset);
        +
        +	/* Check if NULL */
        +	if (!sfld)
        +		{
        +		if (!adb->null_tt)
        +			goto err;
        +		return adb->null_tt;
        +		}
        +
        +	/* Convert type to a long:
        +	 * NB: don't check for NID_undef here because it
        +	 * might be a legitimate value in the table
        +	 */
        +	if (tt->flags & ASN1_TFLG_ADB_OID) 
        +		selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
        +	else 
        +		selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
        +
        +	/* Try to find matching entry in table
        +	 * Maybe should check application types first to
        +	 * allow application override? Might also be useful
        +	 * to have a flag which indicates table is sorted and
        +	 * we can do a binary search. For now stick to a
        +	 * linear search.
        +	 */
        +
        +	for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
        +		if (atbl->value == selector)
        +			return &atbl->tt;
        +
        +	/* FIXME: need to search application table too */
        +
        +	/* No match, return default type */
        +	if (!adb->default_tt)
        +		goto err;		
        +	return adb->default_tt;
        +	
        +	err:
        +	/* FIXME: should log the value or OID of unsupported type */
        +	if (nullerr)
        +		ASN1err(ASN1_F_ASN1_DO_ADB,
        +			ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
        +	return NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_algor.c b/vendor/openssl/openssl/crypto/asn1/x_algor.c
        new file mode 100644
        index 000000000..274e456c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_algor.c
        @@ -0,0 +1,144 @@
        +/* x_algor.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stddef.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +
        +ASN1_SEQUENCE(X509_ALGOR) = {
        +	ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
        +	ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
        +} ASN1_SEQUENCE_END(X509_ALGOR)
        +
        +ASN1_ITEM_TEMPLATE(X509_ALGORS) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
        +ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
        +
        +IMPLEMENT_STACK_OF(X509_ALGOR)
        +IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
        +
        +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
        +	{
        +	if (!alg)
        +		return 0;
        +	if (ptype != V_ASN1_UNDEF)
        +		{
        +		if (alg->parameter == NULL)
        +			alg->parameter = ASN1_TYPE_new();
        +		if (alg->parameter == NULL)
        +			return 0;
        +		}
        +	if (alg)
        +		{
        +		if (alg->algorithm)
        +			ASN1_OBJECT_free(alg->algorithm);
        +		alg->algorithm = aobj;
        +		}
        +	if (ptype == 0)
        +		return 1;	
        +	if (ptype == V_ASN1_UNDEF)
        +		{
        +		if (alg->parameter)
        +			{
        +			ASN1_TYPE_free(alg->parameter);
        +			alg->parameter = NULL;
        +			}
        +		}
        +	else
        +		ASN1_TYPE_set(alg->parameter, ptype, pval);
        +	return 1;
        +	}
        +
        +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
        +						X509_ALGOR *algor)
        +	{
        +	if (paobj)
        +		*paobj = algor->algorithm;
        +	if (pptype)
        +		{
        +		if (algor->parameter == NULL)
        +			{
        +			*pptype = V_ASN1_UNDEF;
        +			return;
        +			}
        +		else
        +			*pptype = algor->parameter->type;
        +		if (ppval)
        +			*ppval = algor->parameter->value.ptr;
        +		}
        +	}
        +
        +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
        +
        +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
        +	{
        +	int param_type;
        +
        +	if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
        +		param_type = V_ASN1_UNDEF;
        +	else
        +		param_type = V_ASN1_NULL;
        +
        +	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_attrib.c b/vendor/openssl/openssl/crypto/asn1/x_attrib.c
        new file mode 100644
        index 000000000..1e3713f18
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_attrib.c
        @@ -0,0 +1,118 @@
        +/* crypto/asn1/x_attrib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +
        +/* X509_ATTRIBUTE: this has the following form:
        + *
        + * typedef struct x509_attributes_st
        + *	{
        + *	ASN1_OBJECT *object;
        + *	int single;
        + *	union	{
        + *		char		*ptr;
        + * 		STACK_OF(ASN1_TYPE) *set;
        + * 		ASN1_TYPE	*single;
        + *		} value;
        + *	} X509_ATTRIBUTE;
        + *
        + * this needs some extra thought because the CHOICE type is
        + * merged with the main structure and because the value can
        + * be anything at all we *must* try the SET OF first because
        + * the ASN1_ANY type will swallow anything including the whole
        + * SET OF structure.
        + */
        +
        +ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
        +	ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
        +	ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
        +} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
        +
        +ASN1_SEQUENCE(X509_ATTRIBUTE) = {
        +	ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
        +	/* CHOICE type merged with parent */
        +	ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
        +} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
        +	{
        +	X509_ATTRIBUTE *ret=NULL;
        +	ASN1_TYPE *val=NULL;
        +
        +	if ((ret=X509_ATTRIBUTE_new()) == NULL)
        +		return(NULL);
        +	ret->object=OBJ_nid2obj(nid);
        +	ret->single=0;
        +	if ((ret->value.set=sk_ASN1_TYPE_new_null()) == NULL) goto err;
        +	if ((val=ASN1_TYPE_new()) == NULL) goto err;
        +	if (!sk_ASN1_TYPE_push(ret->value.set,val)) goto err;
        +
        +	ASN1_TYPE_set(val,atrtype,value);
        +	return(ret);
        +err:
        +	if (ret != NULL) X509_ATTRIBUTE_free(ret);
        +	if (val != NULL) ASN1_TYPE_free(val);
        +	return(NULL);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_bignum.c b/vendor/openssl/openssl/crypto/asn1/x_bignum.c
        new file mode 100644
        index 000000000..9cf3204a1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_bignum.c
        @@ -0,0 +1,139 @@
        +/* x_bignum.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/bn.h>
        +
        +/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
        + * BIGNUM directly. Currently it ignores the sign which isn't a problem since all
        + * BIGNUMs used are non negative and anything that looks negative is normally due
        + * to an encoding error.
        + */
        +
        +#define BN_SENSITIVE	1
        +
        +static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +
        +static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
        +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
        +
        +static ASN1_PRIMITIVE_FUNCS bignum_pf = {
        +	NULL, 0,
        +	bn_new,
        +	bn_free,
        +	0,
        +	bn_c2i,
        +	bn_i2c
        +};
        +
        +ASN1_ITEM_start(BIGNUM)
        +	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
        +ASN1_ITEM_end(BIGNUM)
        +
        +ASN1_ITEM_start(CBIGNUM)
        +	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
        +ASN1_ITEM_end(CBIGNUM)
        +
        +static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +{
        +	*pval = (ASN1_VALUE *)BN_new();
        +	if(*pval) return 1;
        +	else return 0;
        +}
        +
        +static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +{
        +	if(!*pval) return;
        +	if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
        +	else BN_free((BIGNUM *)*pval);
        +	*pval = NULL;
        +}
        +
        +static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
        +{
        +	BIGNUM *bn;
        +	int pad;
        +	if(!*pval) return -1;
        +	bn = (BIGNUM *)*pval;
        +	/* If MSB set in an octet we need a padding byte */
        +	if(BN_num_bits(bn) & 0x7) pad = 0;
        +	else pad = 1;
        +	if(cont) {
        +		if(pad) *cont++ = 0;
        +		BN_bn2bin(bn, cont);
        +	}
        +	return pad + BN_num_bytes(bn);
        +}
        +
        +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
        +		  int utype, char *free_cont, const ASN1_ITEM *it)
        +{
        +	BIGNUM *bn;
        +	if(!*pval) bn_new(pval, it);
        +	bn  = (BIGNUM *)*pval;
        +	if(!BN_bin2bn(cont, len, bn)) {
        +		bn_free(pval, it);
        +		return 0;
        +	}
        +	return 1;
        +}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_crl.c b/vendor/openssl/openssl/crypto/asn1/x_crl.c
        new file mode 100644
        index 000000000..c51c690ba
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_crl.c
        @@ -0,0 +1,527 @@
        +/* crypto/asn1/x_crl.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "asn1_locl.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
        +				const X509_REVOKED * const *b);
        +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
        +
        +ASN1_SEQUENCE(X509_REVOKED) = {
        +	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
        +	ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
        +	ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
        +} ASN1_SEQUENCE_END(X509_REVOKED)
        +
        +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
        +static int def_crl_lookup(X509_CRL *crl,
        +		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
        +
        +static X509_CRL_METHOD int_crl_meth =
        +	{
        +	0,
        +	0,0,
        +	def_crl_lookup,
        +	def_crl_verify
        +	};
        +
        +static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
        +
        +/* The X509_CRL_INFO structure needs a bit of customisation.
        + * Since we cache the original encoding the signature wont be affected by
        + * reordering of the revoked field.
        + */
        +static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +{
        +	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
        +
        +	if(!a || !a->revoked) return 1;
        +	switch(operation) {
        +		/* Just set cmp function here. We don't sort because that
        +		 * would affect the output of X509_CRL_print().
        +		 */
        +		case ASN1_OP_D2I_POST:
        +		(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
        +		break;
        +	}
        +	return 1;
        +}
        +
        +
        +ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
        +	ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
        +	ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
        +	ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
        +	ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
        +	ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
        +	ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
        +} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
        +
        +/* Set CRL entry issuer according to CRL certificate issuer extension.
        + * Check for unhandled critical CRL entry extensions.
        + */
        +
        +static int crl_set_issuers(X509_CRL *crl)
        +	{
        +
        +	int i, j;
        +	GENERAL_NAMES *gens, *gtmp;
        +	STACK_OF(X509_REVOKED) *revoked;
        +
        +	revoked = X509_CRL_get_REVOKED(crl);
        +
        +	gens = NULL;
        +	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
        +		{
        +		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
        +		STACK_OF(X509_EXTENSION) *exts;
        +		ASN1_ENUMERATED *reason;
        +		X509_EXTENSION *ext;
        +		gtmp = X509_REVOKED_get_ext_d2i(rev, 
        +						NID_certificate_issuer,
        +						&j, NULL);
        +		if (!gtmp && (j != -1))
        +			{
        +			crl->flags |= EXFLAG_INVALID;
        +			return 1;
        +			}
        +
        +		if (gtmp)
        +			{
        +			gens = gtmp;
        +			if (!crl->issuers)
        +				{
        +				crl->issuers = sk_GENERAL_NAMES_new_null();
        +				if (!crl->issuers)
        +					return 0;
        +				}
        +			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
        +				return 0;
        +			}
        +		rev->issuer = gens;
        +
        +		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
        +								&j, NULL);
        +		if (!reason && (j != -1))
        +			{
        +			crl->flags |= EXFLAG_INVALID;
        +			return 1;
        +			}
        +
        +		if (reason)
        +			{
        +			rev->reason = ASN1_ENUMERATED_get(reason);
        +			ASN1_ENUMERATED_free(reason);
        +			}
        +		else
        +			rev->reason = CRL_REASON_NONE;	
        +
        +		/* Check for critical CRL entry extensions */
        +
        +		exts = rev->extensions;
        +
        +		for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
        +			{
        +			ext = sk_X509_EXTENSION_value(exts, j);
        +			if (ext->critical > 0)
        +				{
        +				if (OBJ_obj2nid(ext->object) ==
        +					NID_certificate_issuer)
        +					continue;
        +				crl->flags |= EXFLAG_CRITICAL;
        +				break;
        +				}
        +			}
        +
        +
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +/* The X509_CRL structure needs a bit of customisation. Cache some extensions
        + * and hash of the whole CRL.
        + */
        +static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +	{
        +	X509_CRL *crl = (X509_CRL *)*pval;
        +	STACK_OF(X509_EXTENSION) *exts;
        +	X509_EXTENSION *ext;
        +	int idx;
        +
        +	switch(operation)
        +		{
        +		case ASN1_OP_NEW_POST:
        +		crl->idp = NULL;
        +		crl->akid = NULL;
        +		crl->flags = 0;
        +		crl->idp_flags = 0;
        +		crl->idp_reasons = CRLDP_ALL_REASONS;
        +		crl->meth = default_crl_method;
        +		crl->meth_data = NULL;
        +		crl->issuers = NULL;
        +		crl->crl_number = NULL;
        +		crl->base_crl_number = NULL;
        +		break;
        +
        +		case ASN1_OP_D2I_POST:
        +#ifndef OPENSSL_NO_SHA
        +		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
        +#endif
        +		crl->idp = X509_CRL_get_ext_d2i(crl,
        +				NID_issuing_distribution_point, NULL, NULL);
        +		if (crl->idp)
        +			setup_idp(crl, crl->idp);
        +
        +		crl->akid = X509_CRL_get_ext_d2i(crl,
        +				NID_authority_key_identifier, NULL, NULL);	
        +
        +		crl->crl_number = X509_CRL_get_ext_d2i(crl,
        +				NID_crl_number, NULL, NULL);	
        +
        +		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
        +				NID_delta_crl, NULL, NULL);	
        +		/* Delta CRLs must have CRL number */
        +		if (crl->base_crl_number && !crl->crl_number)
        +			crl->flags |= EXFLAG_INVALID;
        +
        +		/* See if we have any unhandled critical CRL extensions and 
        +		 * indicate this in a flag. We only currently handle IDP so
        +		 * anything else critical sets the flag.
        +		 *
        +		 * This code accesses the X509_CRL structure directly:
        +		 * applications shouldn't do this.
        +		 */
        +
        +		exts = crl->crl->extensions;
        +
        +		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
        +			{
        +			int nid;
        +			ext = sk_X509_EXTENSION_value(exts, idx);
        +			nid = OBJ_obj2nid(ext->object);
        +			if (nid == NID_freshest_crl)
        +				crl->flags |= EXFLAG_FRESHEST;
        +			if (ext->critical > 0)
        +				{
        +				/* We handle IDP and deltas */
        +				if ((nid == NID_issuing_distribution_point)
        +					|| (nid == NID_delta_crl))
        +					break;;
        +				crl->flags |= EXFLAG_CRITICAL;
        +				break;
        +				}
        +			}
        +
        +
        +		if (!crl_set_issuers(crl))
        +			return 0;
        +
        +		if (crl->meth->crl_init)
        +			{
        +			if (crl->meth->crl_init(crl) == 0)
        +				return 0;
        +			}
        +		break;
        +
        +		case ASN1_OP_FREE_POST:
        +		if (crl->meth->crl_free)
        +			{
        +			if (!crl->meth->crl_free(crl))
        +				return 0;
        +			}
        +		if (crl->akid)
        +			AUTHORITY_KEYID_free(crl->akid);
        +		if (crl->idp)
        +			ISSUING_DIST_POINT_free(crl->idp);
        +		ASN1_INTEGER_free(crl->crl_number);
        +		ASN1_INTEGER_free(crl->base_crl_number);
        +		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
        +		break;
        +		}
        +	return 1;
        +	}
        +
        +/* Convert IDP into a more convenient form */
        +
        +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
        +	{
        +	int idp_only = 0;
        +	/* Set various flags according to IDP */
        +	crl->idp_flags |= IDP_PRESENT;
        +	if (idp->onlyuser > 0)
        +		{
        +		idp_only++;
        +		crl->idp_flags |= IDP_ONLYUSER;
        +		}
        +	if (idp->onlyCA > 0)
        +		{
        +		idp_only++;
        +		crl->idp_flags |= IDP_ONLYCA;
        +		}
        +	if (idp->onlyattr > 0)
        +		{
        +		idp_only++;
        +		crl->idp_flags |= IDP_ONLYATTR;
        +		}
        +
        +	if (idp_only > 1)
        +		crl->idp_flags |= IDP_INVALID;
        +
        +	if (idp->indirectCRL > 0)
        +		crl->idp_flags |= IDP_INDIRECT;
        +
        +	if (idp->onlysomereasons)
        +		{
        +		crl->idp_flags |= IDP_REASONS;
        +		if (idp->onlysomereasons->length > 0)
        +			crl->idp_reasons = idp->onlysomereasons->data[0];
        +		if (idp->onlysomereasons->length > 1)
        +			crl->idp_reasons |=
        +				(idp->onlysomereasons->data[1] << 8);
        +		crl->idp_reasons &= CRLDP_ALL_REASONS;
        +		}
        +
        +	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
        +	}
        +
        +ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
        +	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
        +	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
        +	ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
        +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
        +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
        +
        +static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
        +			const X509_REVOKED * const *b)
        +	{
        +	return(ASN1_STRING_cmp(
        +		(ASN1_STRING *)(*a)->serialNumber,
        +		(ASN1_STRING *)(*b)->serialNumber));
        +	}
        +
        +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
        +{
        +	X509_CRL_INFO *inf;
        +	inf = crl->crl;
        +	if(!inf->revoked)
        +		inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
        +	if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
        +		ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	inf->enc.modified = 1;
        +	return 1;
        +}
        +
        +int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
        +	{
        +	if (crl->meth->crl_verify)
        +		return crl->meth->crl_verify(crl, r);
        +	return 0;
        +	}
        +
        +int X509_CRL_get0_by_serial(X509_CRL *crl,
        +		X509_REVOKED **ret, ASN1_INTEGER *serial)
        +	{
        +	if (crl->meth->crl_lookup)
        +		return crl->meth->crl_lookup(crl, ret, serial, NULL);
        +	return 0;
        +	}
        +
        +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
        +	{
        +	if (crl->meth->crl_lookup)
        +		return crl->meth->crl_lookup(crl, ret,
        +						X509_get_serialNumber(x),
        +						X509_get_issuer_name(x));
        +	return 0;
        +	}
        +
        +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
        +	{
        +	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
        +		crl->sig_alg, crl->signature,crl->crl,r));
        +	}
        +
        +static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
        +						X509_REVOKED *rev)
        +	{
        +	int i;
        +
        +	if (!rev->issuer)
        +		{
        +		if (!nm)
        +			return 1;
        +		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
        +			return 1;
        +		return 0;
        +		}
        +
        +	if (!nm)
        +		nm = X509_CRL_get_issuer(crl);
        +
        +	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
        +		{
        +		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
        +		if (gen->type != GEN_DIRNAME)
        +			continue;
        +		if (!X509_NAME_cmp(nm, gen->d.directoryName))
        +			return 1;
        +		}
        +	return 0;
        +
        +	}
        +
        +static int def_crl_lookup(X509_CRL *crl,
        +		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
        +	{
        +	X509_REVOKED rtmp, *rev;
        +	int idx;
        +	rtmp.serialNumber = serial;
        +	/* Sort revoked into serial number order if not already sorted.
        +	 * Do this under a lock to avoid race condition.
        + 	 */
        +	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
        +		{
        +		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
        +		sk_X509_REVOKED_sort(crl->crl->revoked);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
        +		}
        +	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
        +	if(idx < 0)
        +		return 0;
        +	/* Need to look for matching name */
        +	for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
        +		{
        +		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
        +		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
        +			return 0;
        +		if (crl_revoked_issuer_match(crl, issuer, rev))
        +			{
        +			if (ret)
        +				*ret = rev;
        +			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
        +				return 2;
        +			return 1;
        +			}
        +		}
        +	return 0;
        +	}
        +
        +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
        +	{
        +	if (meth == NULL)
        +		default_crl_method = &int_crl_meth;
        +	else 
        +		default_crl_method = meth;
        +	}
        +
        +X509_CRL_METHOD *X509_CRL_METHOD_new(
        +	int (*crl_init)(X509_CRL *crl),
        +	int (*crl_free)(X509_CRL *crl),
        +	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
        +				ASN1_INTEGER *ser, X509_NAME *issuer),
        +	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
        +	{
        +	X509_CRL_METHOD *m;
        +	m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
        +	if (!m)
        +		return NULL;
        +	m->crl_init = crl_init;
        +	m->crl_free = crl_free;
        +	m->crl_lookup = crl_lookup;
        +	m->crl_verify = crl_verify;
        +	m->flags = X509_CRL_METHOD_DYNAMIC;
        +	return m;
        +	}
        +
        +void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
        +	{
        +	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
        +		return;
        +	OPENSSL_free(m);
        +	}
        +
        +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
        +	{
        +	crl->meth_data = dat;
        +	}
        +
        +void *X509_CRL_get_meth_data(X509_CRL *crl)
        +	{
        +	return crl->meth_data;
        +	}
        +
        +IMPLEMENT_STACK_OF(X509_REVOKED)
        +IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
        +IMPLEMENT_STACK_OF(X509_CRL)
        +IMPLEMENT_ASN1_SET_OF(X509_CRL)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_exten.c b/vendor/openssl/openssl/crypto/asn1/x_exten.c
        new file mode 100644
        index 000000000..3a2123992
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_exten.c
        @@ -0,0 +1,76 @@
        +/* x_exten.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stddef.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +
        +ASN1_SEQUENCE(X509_EXTENSION) = {
        +	ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
        +	ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
        +	ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(X509_EXTENSION)
        +
        +ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
        +ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_info.c b/vendor/openssl/openssl/crypto/asn1/x_info.c
        new file mode 100644
        index 000000000..d44f6cdb0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_info.c
        @@ -0,0 +1,114 @@
        +/* crypto/asn1/x_info.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +
        +X509_INFO *X509_INFO_new(void)
        +	{
        +	X509_INFO *ret=NULL;
        +
        +	ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
        +	if (ret == NULL)
        +		{
        +		ASN1err(ASN1_F_X509_INFO_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        + 
        +        ret->enc_cipher.cipher=NULL;
        +        ret->enc_len=0;
        +        ret->enc_data=NULL;
        + 
        +	ret->references=1;
        +	ret->x509=NULL;
        +	ret->crl=NULL;
        +	ret->x_pkey=NULL;
        +	return(ret);
        +	}
        +
        +void X509_INFO_free(X509_INFO *x)
        +	{
        +	int i;
        +
        +	if (x == NULL) return;
        +
        +	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_INFO);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509_INFO",x);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"X509_INFO_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +
        +	if (x->x509 != NULL) X509_free(x->x509);
        +	if (x->crl != NULL) X509_CRL_free(x->crl);
        +	if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
        +	if (x->enc_data != NULL) OPENSSL_free(x->enc_data);
        +	OPENSSL_free(x);
        +	}
        +
        +IMPLEMENT_STACK_OF(X509_INFO)
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_long.c b/vendor/openssl/openssl/crypto/asn1/x_long.c
        new file mode 100644
        index 000000000..75317418e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_long.c
        @@ -0,0 +1,179 @@
        +/* x_long.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/bn.h>
        +
        +/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
        + * and a long directly.
        + */
        +
        +
        +static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
        +
        +static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
        +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
        +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
        +
        +static ASN1_PRIMITIVE_FUNCS long_pf = {
        +	NULL, 0,
        +	long_new,
        +	long_free,
        +	long_free,	/* Clear should set to initial value */
        +	long_c2i,
        +	long_i2c,
        +	long_print
        +};
        +
        +ASN1_ITEM_start(LONG)
        +	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
        +ASN1_ITEM_end(LONG)
        +
        +ASN1_ITEM_start(ZLONG)
        +	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
        +ASN1_ITEM_end(ZLONG)
        +
        +static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +{
        +	*(long *)pval = it->size;
        +	return 1;
        +}
        +
        +static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +{
        +	*(long *)pval = it->size;
        +}
        +
        +static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
        +{
        +	long ltmp;
        +	unsigned long utmp;
        +	int clen, pad, i;
        +	/* this exists to bypass broken gcc optimization */
        +	char *cp = (char *)pval;
        +
        +	/* use memcpy, because we may not be long aligned */
        +	memcpy(&ltmp, cp, sizeof(long));
        +
        +	if(ltmp == it->size) return -1;
        +	/* Convert the long to positive: we subtract one if negative so
        +	 * we can cleanly handle the padding if only the MSB of the leading
        +	 * octet is set. 
        +	 */
        +	if(ltmp < 0) utmp = -ltmp - 1;
        +	else utmp = ltmp;
        +	clen = BN_num_bits_word(utmp);
        +	/* If MSB of leading octet set we need to pad */
        +	if(!(clen & 0x7)) pad = 1;
        +	else pad = 0;
        +
        +	/* Convert number of bits to number of octets */
        +	clen = (clen + 7) >> 3;
        +
        +	if(cont) {
        +		if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
        +		for(i = clen - 1; i >= 0; i--) {
        +			cont[i] = (unsigned char)(utmp & 0xff);
        +			if(ltmp < 0) cont[i] ^= 0xff;
        +			utmp >>= 8;
        +		}
        +	}
        +	return clen + pad;
        +}
        +
        +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
        +		    int utype, char *free_cont, const ASN1_ITEM *it)
        +{
        +	int neg, i;
        +	long ltmp;
        +	unsigned long utmp = 0;
        +	char *cp = (char *)pval;
        +	if(len > (int)sizeof(long)) {
        +		ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
        +		return 0;
        +	}
        +	/* Is it negative? */
        +	if(len && (cont[0] & 0x80)) neg = 1;
        +	else neg = 0;
        +	utmp = 0;
        +	for(i = 0; i < len; i++) {
        +		utmp <<= 8;
        +		if(neg) utmp |= cont[i] ^ 0xff;
        +		else utmp |= cont[i];
        +	}
        +	ltmp = (long)utmp;
        +	if(neg) {
        +		ltmp++;
        +		ltmp = -ltmp;
        +	}
        +	if(ltmp == it->size) {
        +		ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
        +		return 0;
        +	}
        +	memcpy(cp, &ltmp, sizeof(long));
        +	return 1;
        +}
        +
        +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +			int indent, const ASN1_PCTX *pctx)
        +	{
        +	return BIO_printf(out, "%ld\n", *(long *)pval);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_name.c b/vendor/openssl/openssl/crypto/asn1/x_name.c
        new file mode 100644
        index 000000000..d7c231869
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_name.c
        @@ -0,0 +1,519 @@
        +/* crypto/asn1/x_name.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include "asn1_locl.h"
        +
        +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
        +DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
        +
        +static int x509_name_ex_d2i(ASN1_VALUE **val,
        +				const unsigned char **in, long len,
        +				const ASN1_ITEM *it,
        +				int tag, int aclass, char opt, ASN1_TLC *ctx);
        +
        +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
        +				const ASN1_ITEM *it, int tag, int aclass);
        +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
        +static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
        +
        +static int x509_name_encode(X509_NAME *a);
        +static int x509_name_canon(X509_NAME *a);
        +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
        +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
        +			  unsigned char **in);
        +
        +
        +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
        +						int indent,
        +						const char *fname, 
        +						const ASN1_PCTX *pctx);
        +
        +ASN1_SEQUENCE(X509_NAME_ENTRY) = {
        +	ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
        +	ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
        +} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
        +
        +/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
        + * so declare two template wrappers for this
        + */
        +
        +ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
        +ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
        +
        +ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
        +ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
        +
        +/* Normally that's where it would end: we'd have two nested STACK structures
        + * representing the ASN1. Unfortunately X509_NAME uses a completely different
        + * form and caches encodings so we have to process the internal form and convert
        + * to the external form.
        + */
        +
        +const ASN1_EXTERN_FUNCS x509_name_ff = {
        +	NULL,
        +	x509_name_ex_new,
        +	x509_name_ex_free,
        +	0,	/* Default clear behaviour is OK */
        +	x509_name_ex_d2i,
        +	x509_name_ex_i2d,
        +	x509_name_ex_print
        +};
        +
        +IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
        +
        +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
        +{
        +	X509_NAME *ret = NULL;
        +	ret = OPENSSL_malloc(sizeof(X509_NAME));
        +	if(!ret) goto memerr;
        +	if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
        +		goto memerr;
        +	if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
        +	ret->canon_enc = NULL;
        +	ret->canon_enclen = 0;
        +	ret->modified=1;
        +	*val = (ASN1_VALUE *)ret;
        +	return 1;
        +
        + memerr:
        +	ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
        +	if (ret)
        +		{
        +		if (ret->entries)
        +			sk_X509_NAME_ENTRY_free(ret->entries);
        +		OPENSSL_free(ret);
        +		}
        +	return 0;
        +}
        +
        +static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
        +{
        +	X509_NAME *a;
        +	if(!pval || !*pval)
        +	    return;
        +	a = (X509_NAME *)*pval;
        +
        +	BUF_MEM_free(a->bytes);
        +	sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
        +	if (a->canon_enc)
        +		OPENSSL_free(a->canon_enc);
        +	OPENSSL_free(a);
        +	*pval = NULL;
        +}
        +
        +static int x509_name_ex_d2i(ASN1_VALUE **val,
        +			const unsigned char **in, long len, const ASN1_ITEM *it,
        +				int tag, int aclass, char opt, ASN1_TLC *ctx)
        +{
        +	const unsigned char *p = *in, *q;
        +	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
        +		ASN1_VALUE *a; } intname = {NULL};
        +	union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
        +	int i, j, ret;
        +	STACK_OF(X509_NAME_ENTRY) *entries;
        +	X509_NAME_ENTRY *entry;
        +	q = p;
        +
        +	/* Get internal representation of Name */
        +	ret = ASN1_item_ex_d2i(&intname.a,
        +			       &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
        +			       tag, aclass, opt, ctx);
        +	
        +	if(ret <= 0) return ret;
        +
        +	if(*val) x509_name_ex_free(val, NULL);
        +	if(!x509_name_ex_new(&nm.a, NULL)) goto err;
        +	/* We've decoded it: now cache encoding */
        +	if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
        +	memcpy(nm.x->bytes->data, q, p - q);
        +
        +	/* Convert internal representation to X509_NAME structure */
        +	for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
        +		entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
        +		for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
        +			entry = sk_X509_NAME_ENTRY_value(entries, j);
        +			entry->set = i;
        +			if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
        +				goto err;
        +		}
        +		sk_X509_NAME_ENTRY_free(entries);
        +	}
        +	sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
        +	ret = x509_name_canon(nm.x);
        +	if (!ret)
        +		goto err;
        +	nm.x->modified = 0;
        +	*val = nm.a;
        +	*in = p;
        +	return ret;
        +err:
        +        if (nm.x != NULL)
        +		X509_NAME_free(nm.x);
        +	ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
        +	return 0;
        +}
        +
        +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
        +{
        +	int ret;
        +	X509_NAME *a = (X509_NAME *)*val;
        +	if(a->modified) {
        +		ret = x509_name_encode(a);
        +		if(ret < 0)
        +			return ret;
        +		ret = x509_name_canon(a);
        +		if(ret < 0)
        +			return ret;
        +	}
        +	ret = a->bytes->length;
        +	if(out != NULL) {
        +		memcpy(*out,a->bytes->data,ret);
        +		*out+=ret;
        +	}
        +	return ret;
        +}
        +
        +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
        +	{
        +	sk_X509_NAME_ENTRY_free(ne);
        +	}
        +
        +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
        +	{
        +	sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
        +	}
        +
        +static int x509_name_encode(X509_NAME *a)
        +{
        +	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
        +		ASN1_VALUE *a; } intname = {NULL};
        +	int len;
        +	unsigned char *p;
        +	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
        +	X509_NAME_ENTRY *entry;
        +	int i, set = -1;
        +	intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
        +	if(!intname.s) goto memerr;
        +	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
        +		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
        +		if(entry->set != set) {
        +			entries = sk_X509_NAME_ENTRY_new_null();
        +			if(!entries) goto memerr;
        +			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
        +							     entries))
        +				goto memerr;
        +			set = entry->set;
        +		}
        +		if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
        +	}
        +	len = ASN1_item_ex_i2d(&intname.a, NULL,
        +			       ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
        +	if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
        +	p=(unsigned char *)a->bytes->data;
        +	ASN1_item_ex_i2d(&intname.a,
        +			 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
        +	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
        +					     local_sk_X509_NAME_ENTRY_free);
        +	a->modified = 0;
        +	return len;
        +memerr:
        +	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
        +					     local_sk_X509_NAME_ENTRY_free);
        +	ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
        +	return -1;
        +}
        +
        +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
        +						int indent,
        +						const char *fname, 
        +						const ASN1_PCTX *pctx)
        +	{
        +	if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
        +					indent, pctx->nm_flags) <= 0)
        +		return 0;
        +	return 2;
        +	}
        +
        +/* This function generates the canonical encoding of the Name structure.
        + * In it all strings are converted to UTF8, leading, trailing and
        + * multiple spaces collapsed, converted to lower case and the leading
        + * SEQUENCE header removed.
        + *
        + * In future we could also normalize the UTF8 too.
        + *
        + * By doing this comparison of Name structures can be rapidly
        + * perfomed by just using memcmp() of the canonical encoding.
        + * By omitting the leading SEQUENCE name constraints of type
        + * dirName can also be checked with a simple memcmp().
        + */
        +
        +static int x509_name_canon(X509_NAME *a)
        +	{
        +	unsigned char *p;
        +	STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
        +	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
        +	X509_NAME_ENTRY *entry, *tmpentry = NULL;
        +	int i, set = -1, ret = 0;
        +
        +	if (a->canon_enc)
        +		{
        +		OPENSSL_free(a->canon_enc);
        +		a->canon_enc = NULL;
        +		}
        +	/* Special case: empty X509_NAME => null encoding */
        +	if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
        +		{
        +		a->canon_enclen = 0;
        +		return 1;
        +		}
        +	intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
        +	if(!intname)
        +		goto err;
        +	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
        +		{
        +		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
        +		if(entry->set != set)
        +			{
        +			entries = sk_X509_NAME_ENTRY_new_null();
        +			if(!entries)
        +				goto err;
        +			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
        +				goto err;
        +			set = entry->set;
        +			}
        +		tmpentry = X509_NAME_ENTRY_new();
        +		tmpentry->object = OBJ_dup(entry->object);
        +		if (!asn1_string_canon(tmpentry->value, entry->value))
        +			goto err;
        +		if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
        +			goto err;
        +		tmpentry = NULL;
        +		}
        +
        +	/* Finally generate encoding */
        +
        +	a->canon_enclen = i2d_name_canon(intname, NULL);
        +
        +	p = OPENSSL_malloc(a->canon_enclen);
        +
        +	if (!p)
        +		goto err;
        +
        +	a->canon_enc = p;
        +
        +	i2d_name_canon(intname, &p);
        +
        +	ret = 1;
        +
        +	err:
        +
        +	if (tmpentry)
        +		X509_NAME_ENTRY_free(tmpentry);
        +	if (intname)
        +		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
        +					local_sk_X509_NAME_ENTRY_pop_free);
        +	return ret;
        +	}
        +
        +/* Bitmap of all the types of string that will be canonicalized. */
        +
        +#define ASN1_MASK_CANON	\
        +	(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
        +	| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
        +	| B_ASN1_VISIBLESTRING)
        +	
        +
        +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
        +	{
        +	unsigned char *to, *from;
        +	int len, i;
        +
        +	/* If type not in bitmask just copy string across */
        +	if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
        +		{
        +		if (!ASN1_STRING_copy(out, in))
        +			return 0;
        +		return 1;
        +		}
        +
        +	out->type = V_ASN1_UTF8STRING;
        +	out->length = ASN1_STRING_to_UTF8(&out->data, in);
        +	if (out->length == -1)
        +		return 0;
        +
        +	to = out->data;
        +	from = to;
        +
        +	len = out->length;
        +
        +	/* Convert string in place to canonical form.
        +	 * Ultimately we may need to handle a wider range of characters
        +	 * but for now ignore anything with MSB set and rely on the
        +	 * isspace() and tolower() functions.
        +	 */
        +
        +	/* Ignore leading spaces */
        +	while((len > 0) && !(*from & 0x80) && isspace(*from))
        +		{
        +		from++;
        +		len--;
        +		}
        +
        +	to = from + len - 1;
        +
        +	/* Ignore trailing spaces */
        +	while ((len > 0) && !(*to & 0x80) && isspace(*to))
        +		{
        +		to--;
        +		len--;
        +		}
        +
        +	to = out->data;
        +
        +	i = 0;
        +	while(i < len)
        +		{
        +		/* If MSB set just copy across */
        +		if (*from & 0x80)
        +			{
        +			*to++ = *from++;
        +			i++;
        +			}
        +		/* Collapse multiple spaces */
        +		else if (isspace(*from))
        +			{
        +			/* Copy one space across */
        +			*to++ = ' ';
        +			/* Ignore subsequent spaces. Note: don't need to
        +			 * check len here because we know the last 
        +			 * character is a non-space so we can't overflow.
        +			 */
        +			do
        +				{
        +				from++;
        +				i++;
        +				}
        +			while(!(*from & 0x80) && isspace(*from));
        +			}
        +		else
        +			{
        +			*to++ = tolower(*from);
        +			from++;
        +			i++;
        +			}
        +		}
        +
        +	out->length = to - out->data;
        +
        +	return 1;
        +
        +	}
        +
        +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
        +			  unsigned char **in)
        +	{
        +	int i, len, ltmp;
        +	ASN1_VALUE *v;
        +	STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
        +
        +	len = 0;
        +	for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
        +		{
        +		v = sk_ASN1_VALUE_value(intname, i);
        +		ltmp = ASN1_item_ex_i2d(&v, in,
        +			ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
        +		if (ltmp < 0)
        +			return ltmp;
        +		len += ltmp;
        +		}
        +	return len;
        +	}
        +
        +int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
        +	{
        +	X509_NAME *in;
        +
        +	if (!xn || !name) return(0);
        +
        +	if (*xn != name)
        +		{
        +		in=X509_NAME_dup(name);
        +		if (in != NULL)
        +			{
        +			X509_NAME_free(*xn);
        +			*xn=in;
        +			}
        +		}
        +	return(*xn != NULL);
        +	}
        +	
        +IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
        +IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_nx509.c b/vendor/openssl/openssl/crypto/asn1/x_nx509.c
        new file mode 100644
        index 000000000..fbd9a22db
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_nx509.c
        @@ -0,0 +1,72 @@
        +/* x_nx509.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2005.
        + */
        +/* ====================================================================
        + * Copyright (c) 2005 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 <stddef.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +
        +/* Old netscape certificate wrapper format */
        +
        +ASN1_SEQUENCE(NETSCAPE_X509) = {
        +	ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
        +	ASN1_OPT(NETSCAPE_X509, cert, X509)
        +} ASN1_SEQUENCE_END(NETSCAPE_X509)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
        +
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_pkey.c b/vendor/openssl/openssl/crypto/asn1/x_pkey.c
        new file mode 100644
        index 000000000..845361842
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_pkey.c
        @@ -0,0 +1,151 @@
        +/* crypto/asn1/x_pkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/asn1_mac.h>
        +#include <openssl/x509.h>
        +
        +/* need to implement */
        +int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp)
        +	{
        +	return(0);
        +	}
        +
        +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length)
        +	{
        +	int i;
        +	M_ASN1_D2I_vars(a,X509_PKEY *,X509_PKEY_new);
        +
        +	M_ASN1_D2I_Init();
        +	M_ASN1_D2I_start_sequence();
        +	M_ASN1_D2I_get_x(X509_ALGOR,ret->enc_algor,d2i_X509_ALGOR);
        +	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->enc_pkey,d2i_ASN1_OCTET_STRING);
        +
        +	ret->cipher.cipher=EVP_get_cipherbyname(
        +		OBJ_nid2ln(OBJ_obj2nid(ret->enc_algor->algorithm)));
        +	if (ret->cipher.cipher == NULL)
        +		{
        +		c.error=ASN1_R_UNSUPPORTED_CIPHER;
        +		c.line=__LINE__;
        +		goto err;
        +		}
        +	if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) 
        +		{
        +		i=ret->enc_algor->parameter->value.octet_string->length;
        +		if (i > EVP_MAX_IV_LENGTH)
        +			{
        +			c.error=ASN1_R_IV_TOO_LARGE;
        +			c.line=__LINE__;
        +			goto err;
        +			}
        +		memcpy(ret->cipher.iv,
        +			ret->enc_algor->parameter->value.octet_string->data,i);
        +		}
        +	else
        +		memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
        +	M_ASN1_D2I_Finish(a,X509_PKEY_free,ASN1_F_D2I_X509_PKEY);
        +	}
        +
        +X509_PKEY *X509_PKEY_new(void)
        +	{
        +	X509_PKEY *ret=NULL;
        +	ASN1_CTX c;
        +
        +	M_ASN1_New_Malloc(ret,X509_PKEY);
        +	ret->version=0;
        +	M_ASN1_New(ret->enc_algor,X509_ALGOR_new);
        +	M_ASN1_New(ret->enc_pkey,M_ASN1_OCTET_STRING_new);
        +	ret->dec_pkey=NULL;
        +	ret->key_length=0;
        +	ret->key_data=NULL;
        +	ret->key_free=0;
        +	ret->cipher.cipher=NULL;
        +	memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
        +	ret->references=1;
        +	return(ret);
        +	M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
        +	}
        +
        +void X509_PKEY_free(X509_PKEY *x)
        +	{
        +	int i;
        +
        +	if (x == NULL) return;
        +
        +	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509_PKEY",x);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"X509_PKEY_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +
        +	if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
        +	if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
        +	if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
        +	if ((x->key_data != NULL) && (x->key_free)) OPENSSL_free(x->key_data);
        +	OPENSSL_free(x);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_pubkey.c b/vendor/openssl/openssl/crypto/asn1/x_pubkey.c
        new file mode 100644
        index 000000000..b649e1fcf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_pubkey.c
        @@ -0,0 +1,385 @@
        +/* crypto/asn1/x_pubkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include "asn1_locl.h"
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +/* Minor tweak to operation: free up EVP_PKEY */
        +static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +			void *exarg)
        +	{
        +	if (operation == ASN1_OP_FREE_POST)
        +		{
        +		X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
        +		EVP_PKEY_free(pubkey->pkey);
        +		}
        +	return 1;
        +	}
        +
        +ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
        +	ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
        +	ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
        +
        +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
        +	{
        +	X509_PUBKEY *pk=NULL;
        +
        +	if (x == NULL) return(0);
        +
        +	if ((pk=X509_PUBKEY_new()) == NULL) goto error;
        +
        +	if (pkey->ameth)
        +		{
        +		if (pkey->ameth->pub_encode)
        +			{
        +			if (!pkey->ameth->pub_encode(pk, pkey))
        +				{
        +				X509err(X509_F_X509_PUBKEY_SET,
        +					X509_R_PUBLIC_KEY_ENCODE_ERROR);
        +				goto error;
        +				}
        +			}
        +		else
        +			{
        +			X509err(X509_F_X509_PUBKEY_SET,
        +				X509_R_METHOD_NOT_SUPPORTED);
        +			goto error;
        +			}
        +		}
        +	else
        +		{
        +		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
        +		goto error;
        +		}
        +
        +	if (*x != NULL)
        +		X509_PUBKEY_free(*x);
        +
        +	*x=pk;
        +
        +	return 1;
        +error:
        +	if (pk != NULL) X509_PUBKEY_free(pk);
        +	return 0;
        +	}
        +
        +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
        +	{
        +	EVP_PKEY *ret=NULL;
        +
        +	if (key == NULL) goto error;
        +
        +	if (key->pkey != NULL)
        +		{
        +		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
        +		return key->pkey;
        +		}
        +
        +	if (key->public_key == NULL) goto error;
        +
        +	if ((ret = EVP_PKEY_new()) == NULL)
        +		{
        +		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
        +		goto error;
        +		}
        +
        +	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
        +		{
        +		X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
        +		goto error;
        +		}
        +
        +	if (ret->ameth->pub_decode)
        +		{
        +		if (!ret->ameth->pub_decode(ret, key))
        +			{
        +			X509err(X509_F_X509_PUBKEY_GET,
        +						X509_R_PUBLIC_KEY_DECODE_ERROR);
        +			goto error;
        +			}
        +		}
        +	else
        +		{
        +		X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
        +		goto error;
        +		}
        +
        +	/* Check to see if another thread set key->pkey first */
        +	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
        +	if (key->pkey)
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
        +		EVP_PKEY_free(ret);
        +		ret = key->pkey;
        +		}
        +	else
        +		{
        +		key->pkey = ret;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
        +		}
        +	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
        +
        +	return ret;
        +
        +	error:
        +	if (ret != NULL)
        +		EVP_PKEY_free(ret);
        +	return(NULL);
        +	}
        +
        +/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
        + * and encode or decode as X509_PUBKEY
        + */
        +
        +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
        +	     long length)
        +	{
        +	X509_PUBKEY *xpk;
        +	EVP_PKEY *pktmp;
        +	xpk = d2i_X509_PUBKEY(NULL, pp, length);
        +	if(!xpk) return NULL;
        +	pktmp = X509_PUBKEY_get(xpk);
        +	X509_PUBKEY_free(xpk);
        +	if(!pktmp) return NULL;
        +	if(a)
        +		{
        +		EVP_PKEY_free(*a);
        +		*a = pktmp;
        +		}
        +	return pktmp;
        +	}
        +
        +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
        +	{
        +	X509_PUBKEY *xpk=NULL;
        +	int ret;
        +	if(!a) return 0;
        +	if(!X509_PUBKEY_set(&xpk, a)) return 0;
        +	ret = i2d_X509_PUBKEY(xpk, pp);
        +	X509_PUBKEY_free(xpk);
        +	return ret;
        +	}
        +
        +/* The following are equivalents but which return RSA and DSA
        + * keys
        + */
        +#ifndef OPENSSL_NO_RSA
        +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
        +	     long length)
        +	{
        +	EVP_PKEY *pkey;
        +	RSA *key;
        +	const unsigned char *q;
        +	q = *pp;
        +	pkey = d2i_PUBKEY(NULL, &q, length);
        +	if (!pkey) return NULL;
        +	key = EVP_PKEY_get1_RSA(pkey);
        +	EVP_PKEY_free(pkey);
        +	if (!key) return NULL;
        +	*pp = q;
        +	if (a)
        +		{
        +		RSA_free(*a);
        +		*a = key;
        +		}
        +	return key;
        +	}
        +
        +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
        +	{
        +	EVP_PKEY *pktmp;
        +	int ret;
        +	if (!a) return 0;
        +	pktmp = EVP_PKEY_new();
        +	if (!pktmp)
        +		{
        +		ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	EVP_PKEY_set1_RSA(pktmp, a);
        +	ret = i2d_PUBKEY(pktmp, pp);
        +	EVP_PKEY_free(pktmp);
        +	return ret;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
        +	     long length)
        +	{
        +	EVP_PKEY *pkey;
        +	DSA *key;
        +	const unsigned char *q;
        +	q = *pp;
        +	pkey = d2i_PUBKEY(NULL, &q, length);
        +	if (!pkey) return NULL;
        +	key = EVP_PKEY_get1_DSA(pkey);
        +	EVP_PKEY_free(pkey);
        +	if (!key) return NULL;
        +	*pp = q;
        +	if (a)
        +		{
        +		DSA_free(*a);
        +		*a = key;
        +		}
        +	return key;
        +	}
        +
        +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
        +	{
        +	EVP_PKEY *pktmp;
        +	int ret;
        +	if(!a) return 0;
        +	pktmp = EVP_PKEY_new();
        +	if(!pktmp)
        +		{
        +		ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	EVP_PKEY_set1_DSA(pktmp, a);
        +	ret = i2d_PUBKEY(pktmp, pp);
        +	EVP_PKEY_free(pktmp);
        +	return ret;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
        +	{
        +	EVP_PKEY *pkey;
        +	EC_KEY *key;
        +	const unsigned char *q;
        +	q = *pp;
        +	pkey = d2i_PUBKEY(NULL, &q, length);
        +	if (!pkey) return(NULL);
        +	key = EVP_PKEY_get1_EC_KEY(pkey);
        +	EVP_PKEY_free(pkey);
        +	if (!key)  return(NULL);
        +	*pp = q;
        +	if (a)
        +		{
        +		EC_KEY_free(*a);
        +		*a = key;
        +		}
        +	return(key);
        +	}
        +
        +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
        +	{
        +	EVP_PKEY *pktmp;
        +	int ret;
        +	if (!a)	return(0);
        +	if ((pktmp = EVP_PKEY_new()) == NULL)
        +		{
        +		ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	EVP_PKEY_set1_EC_KEY(pktmp, a);
        +	ret = i2d_PUBKEY(pktmp, pp);
        +	EVP_PKEY_free(pktmp);
        +	return(ret);
        +	}
        +#endif
        +
        +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
        +					int ptype, void *pval,
        +					unsigned char *penc, int penclen)
        +	{
        +	if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
        +		return 0;
        +	if (penc)
        +		{
        +		if (pub->public_key->data)
        +			OPENSSL_free(pub->public_key->data);
        +		pub->public_key->data = penc;
        +		pub->public_key->length = penclen;
        +  		/* Set number of unused bits to zero */
        +		pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        +		pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
        +		}
        +	return 1;
        +	}
        +
        +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
        +		const unsigned char **pk, int *ppklen,
        +		X509_ALGOR **pa,
        +		X509_PUBKEY *pub)
        +	{
        +	if (ppkalg)
        +		*ppkalg = pub->algor->algorithm;
        +	if (pk)
        +		{
        +		*pk = pub->public_key->data;
        +		*ppklen = pub->public_key->length;
        +		}
        +	if (pa)
        +		*pa = pub->algor;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_req.c b/vendor/openssl/openssl/crypto/asn1/x_req.c
        new file mode 100644
        index 000000000..d57555827
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_req.c
        @@ -0,0 +1,113 @@
        +/* crypto/asn1/x_req.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +
        +/* X509_REQ_INFO is handled in an unusual way to get round
        + * invalid encodings. Some broken certificate requests don't
        + * encode the attributes field if it is empty. This is in
        + * violation of PKCS#10 but we need to tolerate it. We do
        + * this by making the attributes field OPTIONAL then using
        + * the callback to initialise it to an empty STACK. 
        + *
        + * This means that the field will be correctly encoded unless
        + * we NULL out the field.
        + *
        + * As a result we no longer need the req_kludge field because
        + * the information is now contained in the attributes field:
        + * 1. If it is NULL then it's the invalid omission.
        + * 2. If it is empty it is the correct encoding.
        + * 3. If it is not empty then some attributes are present.
        + *
        + */
        +
        +static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +{
        +	X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
        +
        +	if(operation == ASN1_OP_NEW_POST) {
        +		rinf->attributes = sk_X509_ATTRIBUTE_new_null();
        +		if(!rinf->attributes) return 0;
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
        +	ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
        +	ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
        +	/* This isn't really OPTIONAL but it gets round invalid
        +	 * encodings
        +	 */
        +	ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
        +} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
        +
        +ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
        +	ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
        +	ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
        +	ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_sig.c b/vendor/openssl/openssl/crypto/asn1/x_sig.c
        new file mode 100644
        index 000000000..42efa86c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_sig.c
        @@ -0,0 +1,69 @@
        +/* crypto/asn1/x_sig.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +
        +ASN1_SEQUENCE(X509_SIG) = {
        +	ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
        +	ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(X509_SIG)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_spki.c b/vendor/openssl/openssl/crypto/asn1/x_spki.c
        new file mode 100644
        index 000000000..2aece077c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_spki.c
        @@ -0,0 +1,81 @@
        +/* crypto/asn1/x_spki.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.]
        + */
        +
        + /* This module was send to me my Pat Richards <patr@x509.com> who
        +  * wrote it.  It is under my Copyright with his permission
        +  */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/asn1t.h>
        +
        +ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
        +	ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
        +	ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
        +} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
        +
        +ASN1_SEQUENCE(NETSCAPE_SPKI) = {
        +	ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
        +	ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
        +	ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_val.c b/vendor/openssl/openssl/crypto/asn1/x_val.c
        new file mode 100644
        index 000000000..dc17c6775
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_val.c
        @@ -0,0 +1,69 @@
        +/* crypto/asn1/x_val.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +
        +ASN1_SEQUENCE(X509_VAL) = {
        +	ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
        +	ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
        +} ASN1_SEQUENCE_END(X509_VAL)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_x509.c b/vendor/openssl/openssl/crypto/asn1/x_x509.c
        new file mode 100644
        index 000000000..de3df9eb5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_x509.c
        @@ -0,0 +1,194 @@
        +/* crypto/asn1/x_x509.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
        +	ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
        +	ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
        +	ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
        +	ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
        +	ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
        +	ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
        +	ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
        +	ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
        +	ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
        +	ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
        +} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
        +/* X509 top level structure needs a bit of customisation */
        +
        +extern void policy_cache_free(X509_POLICY_CACHE *cache);
        +
        +static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +{
        +	X509 *ret = (X509 *)*pval;
        +
        +	switch(operation) {
        +
        +		case ASN1_OP_NEW_POST:
        +		ret->valid=0;
        +		ret->name = NULL;
        +		ret->ex_flags = 0;
        +		ret->ex_pathlen = -1;
        +		ret->skid = NULL;
        +		ret->akid = NULL;
        +#ifndef OPENSSL_NO_RFC3779
        +		ret->rfc3779_addr = NULL;
        +		ret->rfc3779_asid = NULL;
        +#endif
        +		ret->aux = NULL;
        +		ret->crldp = NULL;
        +		CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
        +		break;
        +
        +		case ASN1_OP_D2I_POST:
        +		if (ret->name != NULL) OPENSSL_free(ret->name);
        +		ret->name=X509_NAME_oneline(ret->cert_info->subject,NULL,0);
        +		break;
        +
        +		case ASN1_OP_FREE_POST:
        +		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
        +		X509_CERT_AUX_free(ret->aux);
        +		ASN1_OCTET_STRING_free(ret->skid);
        +		AUTHORITY_KEYID_free(ret->akid);
        +		CRL_DIST_POINTS_free(ret->crldp);
        +		policy_cache_free(ret->policy_cache);
        +		GENERAL_NAMES_free(ret->altname);
        +		NAME_CONSTRAINTS_free(ret->nc);
        +#ifndef OPENSSL_NO_RFC3779
        +		sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
        +		ASIdentifiers_free(ret->rfc3779_asid);
        +#endif
        +
        +		if (ret->name != NULL) OPENSSL_free(ret->name);
        +		break;
        +
        +	}
        +
        +	return 1;
        +
        +}
        +
        +ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
        +	ASN1_SIMPLE(X509, cert_info, X509_CINF),
        +	ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
        +	ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END_ref(X509, X509)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509)
        +IMPLEMENT_ASN1_DUP_FUNCTION(X509)
        +
        +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +        {
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
        +				new_func, dup_func, free_func);
        +        }
        +
        +int X509_set_ex_data(X509 *r, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
        +	}
        +
        +void *X509_get_ex_data(X509 *r, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&r->ex_data,idx));
        +	}
        +
        +/* X509_AUX ASN1 routines. X509_AUX is the name given to
        + * a certificate with extra info tagged on the end. Since these
        + * functions set how a certificate is trusted they should only
        + * be used when the certificate comes from a reliable source
        + * such as local storage.
        + *
        + */
        +
        +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
        +{
        +	const unsigned char *q;
        +	X509 *ret;
        +	/* Save start position */
        +	q = *pp;
        +	ret = d2i_X509(a, pp, length);
        +	/* If certificate unreadable then forget it */
        +	if(!ret) return NULL;
        +	/* update length */
        +	length -= *pp - q;
        +	if(!length) return ret;
        +	if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
        +	return ret;
        +	err:
        +	X509_free(ret);
        +	return NULL;
        +}
        +
        +int i2d_X509_AUX(X509 *a, unsigned char **pp)
        +{
        +	int length;
        +	length = i2d_X509(a, pp);
        +	if(a) length += i2d_X509_CERT_AUX(a->aux, pp);
        +	return length;
        +}
        diff --git a/vendor/openssl/openssl/crypto/asn1/x_x509a.c b/vendor/openssl/openssl/crypto/asn1/x_x509a.c
        new file mode 100644
        index 000000000..b603f82de
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/asn1/x_x509a.c
        @@ -0,0 +1,180 @@
        +/* a_x509a.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +
        +/* X509_CERT_AUX routines. These are used to encode additional
        + * user modifiable data about a certificate. This data is
        + * appended to the X509 encoding when the *_X509_AUX routines
        + * are used. This means that the "traditional" X509 routines
        + * will simply ignore the extra data. 
        + */
        +
        +static X509_CERT_AUX *aux_get(X509 *x);
        +
        +ASN1_SEQUENCE(X509_CERT_AUX) = {
        +	ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
        +	ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
        +	ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
        +	ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
        +	ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
        +} ASN1_SEQUENCE_END(X509_CERT_AUX)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
        +
        +static X509_CERT_AUX *aux_get(X509 *x)
        +{
        +	if(!x) return NULL;
        +	if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL;
        +	return x->aux;
        +}
        +
        +int X509_alias_set1(X509 *x, unsigned char *name, int len)
        +{
        +	X509_CERT_AUX *aux;
        +	if (!name)
        +		{
        +		if (!x || !x->aux || !x->aux->alias)
        +			return 1;
        +		ASN1_UTF8STRING_free(x->aux->alias);
        +		x->aux->alias = NULL;
        +		return 1;
        +		}
        +	if(!(aux = aux_get(x))) return 0;
        +	if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
        +	return ASN1_STRING_set(aux->alias, name, len);
        +}
        +
        +int X509_keyid_set1(X509 *x, unsigned char *id, int len)
        +{
        +	X509_CERT_AUX *aux;
        +	if (!id)
        +		{
        +		if (!x || !x->aux || !x->aux->keyid)
        +			return 1;
        +		ASN1_OCTET_STRING_free(x->aux->keyid);
        +		x->aux->keyid = NULL;
        +		return 1;
        +		}
        +	if(!(aux = aux_get(x))) return 0;
        +	if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
        +	return ASN1_STRING_set(aux->keyid, id, len);
        +}
        +
        +unsigned char *X509_alias_get0(X509 *x, int *len)
        +{
        +	if(!x->aux || !x->aux->alias) return NULL;
        +	if(len) *len = x->aux->alias->length;
        +	return x->aux->alias->data;
        +}
        +
        +unsigned char *X509_keyid_get0(X509 *x, int *len)
        +{
        +	if(!x->aux || !x->aux->keyid) return NULL;
        +	if(len) *len = x->aux->keyid->length;
        +	return x->aux->keyid->data;
        +}
        +
        +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
        +{
        +	X509_CERT_AUX *aux;
        +	ASN1_OBJECT *objtmp;
        +	if(!(objtmp = OBJ_dup(obj))) return 0;
        +	if(!(aux = aux_get(x))) return 0;
        +	if(!aux->trust
        +		&& !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0;
        +	return sk_ASN1_OBJECT_push(aux->trust, objtmp);
        +}
        +
        +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
        +{
        +	X509_CERT_AUX *aux;
        +	ASN1_OBJECT *objtmp;
        +	if(!(objtmp = OBJ_dup(obj))) return 0;
        +	if(!(aux = aux_get(x))) return 0;
        +	if(!aux->reject
        +		&& !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0;
        +	return sk_ASN1_OBJECT_push(aux->reject, objtmp);
        +}
        +
        +void X509_trust_clear(X509 *x)
        +{
        +	if(x->aux && x->aux->trust) {
        +		sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
        +		x->aux->trust = NULL;
        +	}
        +}
        +
        +void X509_reject_clear(X509 *x)
        +{
        +	if(x->aux && x->aux->reject) {
        +		sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
        +		x->aux->reject = NULL;
        +	}
        +}
        +
        +ASN1_SEQUENCE(X509_CERT_PAIR) = {
        +	ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
        +	ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
        +} ASN1_SEQUENCE_END(X509_CERT_PAIR)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)
        diff --git a/vendor/openssl/openssl/crypto/bf/COPYRIGHT b/vendor/openssl/openssl/crypto/bf/COPYRIGHT
        new file mode 100644
        index 000000000..685722350
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/COPYRIGHT
        @@ -0,0 +1,46 @@
        +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        +All rights reserved.
        +
        +This package is an Blowfish implementation written
        +by Eric Young (eay@cryptsoft.com).
        +
        +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.
        +
        +Copyright remains Eric Young's, and as such any Copyright notices in
        +the code are not to be removed.
        +
        +Redistribution and use in source 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 software developed by Eric Young (eay@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 license 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 distrubution license
        +[including the GNU Public License.]
        +
        +The reason behind this being stated in this direct manner is past
        +experience in code simply being copied and the attribution removed
        +from it and then being distributed as part of other packages. This
        +implementation was a non-trivial and unpaid effort.
        diff --git a/vendor/openssl/openssl/crypto/bf/INSTALL b/vendor/openssl/openssl/crypto/bf/INSTALL
        new file mode 100644
        index 000000000..3b2592353
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/INSTALL
        @@ -0,0 +1,14 @@
        +This Eric Young's blowfish implementation, taken from his SSLeay library
        +and made available as a separate library.
        + 
        +The version number (0.7.2m) is the SSLeay version that this library was
        +taken from.
        + 
        +To build, just unpack and type make.
        +If you are not using gcc, edit the Makefile.
        +If you are compiling for an x86 box, try the assembler (it needs improving).
        +There are also some compile time options that can improve performance,
        +these are documented in the Makefile.
        + 
        +eric 15-Apr-1997
        + 
        diff --git a/vendor/openssl/openssl/crypto/bf/Makefile b/vendor/openssl/openssl/crypto/bf/Makefile
        new file mode 100644
        index 000000000..d01bfaa31
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/Makefile
        @@ -0,0 +1,101 @@
        +#
        +# OpenSSL/crypto/blowfish/Makefile
        +#
        +
        +DIR=	bf
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +BF_ENC=		bf_enc.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=bftest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=bf_skey.c bf_ecb.c bf_enc.c bf_cfb64.c bf_ofb64.c 
        +LIBOBJ=bf_skey.o bf_ecb.o $(BF_ENC) bf_cfb64.o bf_ofb64.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= blowfish.h
        +HEADER=	bf_pi.h bf_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) || echo Never mind.
        +	@touch lib
        +
        +bf-586.s:	asm/bf-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
        +	$(PERL) asm/bf-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +# We need to use force because 'install' matches 'INSTALL' on case
        +# insensitive systems
        +FRC.install:
        +install: FRC.install
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +bf_cfb64.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
        +bf_cfb64.o: ../../include/openssl/opensslconf.h bf_cfb64.c bf_locl.h
        +bf_ecb.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
        +bf_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +bf_ecb.o: bf_ecb.c bf_locl.h
        +bf_enc.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
        +bf_enc.o: ../../include/openssl/opensslconf.h bf_enc.c bf_locl.h
        +bf_ofb64.o: ../../include/openssl/blowfish.h ../../include/openssl/e_os2.h
        +bf_ofb64.o: ../../include/openssl/opensslconf.h bf_locl.h bf_ofb64.c
        +bf_skey.o: ../../include/openssl/blowfish.h ../../include/openssl/crypto.h
        +bf_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +bf_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bf_skey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bf_skey.o: ../../include/openssl/symhacks.h bf_locl.h bf_pi.h bf_skey.c
        diff --git a/vendor/openssl/openssl/crypto/bf/README b/vendor/openssl/openssl/crypto/bf/README
        new file mode 100644
        index 000000000..f2712fd0e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/README
        @@ -0,0 +1,8 @@
        +This is a quick packaging up of my blowfish code into a library.
        +It has been lifted from SSLeay.
        +The copyright notices seem a little harsh because I have not spent the
        +time to rewrite the conditions from the normal SSLeay ones.
        +
        +Basically if you just want to play with the library, not a problem.
        +
        +eric 15-Apr-1997
        diff --git a/vendor/openssl/openssl/crypto/bf/VERSION b/vendor/openssl/openssl/crypto/bf/VERSION
        new file mode 100644
        index 000000000..be995855e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/VERSION
        @@ -0,0 +1,6 @@
        +The version numbers will follow my SSL implementation
        +
        +0.7.2r - Some reasonable default compiler options from 
        +	Peter Gutman <pgut001@cs.auckland.ac.nz>
        +
        +0.7.2m - the first release
        diff --git a/vendor/openssl/openssl/crypto/bf/asm/bf-586.pl b/vendor/openssl/openssl/crypto/bf/asm/bf-586.pl
        new file mode 100644
        index 000000000..b74cfbafd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/asm/bf-586.pl
        @@ -0,0 +1,137 @@
        +#!/usr/local/bin/perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +require "cbc.pl";
        +
        +&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386");
        +
        +$BF_ROUNDS=16;
        +$BF_OFF=($BF_ROUNDS+2)*4;
        +$L="edi";
        +$R="esi";
        +$P="ebp";
        +$tmp1="eax";
        +$tmp2="ebx";
        +$tmp3="ecx";
        +$tmp4="edx";
        +
        +&BF_encrypt("BF_encrypt",1);
        +&BF_encrypt("BF_decrypt",0);
        +&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
        +&asm_finish();
        +
        +sub BF_encrypt
        +	{
        +	local($name,$enc)=@_;
        +
        +	&function_begin_B($name,"");
        +
        +	&comment("");
        +
        +	&push("ebp");
        +	&push("ebx");
        +	&mov($tmp2,&wparam(0));
        +	&mov($P,&wparam(1));
        +	&push("esi");
        +	&push("edi");
        +
        +	&comment("Load the 2 words");
        +	&mov($L,&DWP(0,$tmp2,"",0));
        +	&mov($R,&DWP(4,$tmp2,"",0));
        +
        +	&xor(	$tmp1,	$tmp1);
        +
        +	# encrypting part
        +
        +	if ($enc)
        +		{
        +		 &mov($tmp2,&DWP(0,$P,"",0));
        +		&xor(	$tmp3,	$tmp3);
        +
        +		&xor($L,$tmp2);
        +		for ($i=0; $i<$BF_ROUNDS; $i+=2)
        +			{
        +			&comment("");
        +			&comment("Round $i");
        +			&BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
        +
        +			&comment("");
        +			&comment("Round ".sprintf("%d",$i+1));
        +			&BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
        +			}
        +		# &mov($tmp1,&wparam(0)); In last loop
        +		&mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
        +		}
        +	else
        +		{
        +		 &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
        +		&xor(	$tmp3,	$tmp3);
        +
        +		&xor($L,$tmp2);
        +		for ($i=$BF_ROUNDS; $i>0; $i-=2)
        +			{
        +			&comment("");
        +			&comment("Round $i");
        +			&BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
        +			&comment("");
        +			&comment("Round ".sprintf("%d",$i-1));
        +			&BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
        +			}
        +		# &mov($tmp1,&wparam(0)); In last loop
        +		&mov($tmp4,&DWP(0,$P,"",0));
        +		}
        +
        +	&xor($R,$tmp4);
        +	&mov(&DWP(4,$tmp1,"",0),$L);
        +
        +	&mov(&DWP(0,$tmp1,"",0),$R);
        +	&function_end($name);
        +	}
        +
        +sub BF_ENCRYPT
        +	{
        +	local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
        +
        +	&mov(	$tmp4,		&DWP(&n2a($i*4),$P,"",0)); # for next round
        +
        +	&mov(	$tmp2,		$R);
        +	&xor(	$L,		$tmp4);
        +
        +	&shr(	$tmp2,		16);
        +	&mov(	$tmp4,		$R);
        +
        +	&movb(	&LB($tmp1),	&HB($tmp2));	# A
        +	&and(	$tmp2,		0xff);		# B
        +
        +	&movb(	&LB($tmp3),	&HB($tmp4));	# C
        +	&and(	$tmp4,		0xff);		# D
        +
        +	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
        +	&mov(	$tmp2,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
        +
        +	&add(	$tmp2,		$tmp1);
        +	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
        +
        +	&xor(	$tmp2,		$tmp1);
        +	&mov(	$tmp4,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
        +
        +	&add(	$tmp2,		$tmp4);
        +	if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
        +		{ &xor(	$tmp1,		$tmp1); }
        +	else
        +		{
        +		&comment("Load parameter 0 ($i) enc=$enc");
        +		&mov($tmp1,&wparam(0));
        +		} # In last loop
        +
        +	&xor(	$L,		$tmp2);
        +	# delay
        +	}
        +
        +sub n2a
        +	{
        +	sprintf("%d",$_[0]);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/asm/bf-686.pl b/vendor/openssl/openssl/crypto/bf/asm/bf-686.pl
        new file mode 100644
        index 000000000..8e4c25f59
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/asm/bf-686.pl
        @@ -0,0 +1,127 @@
        +#!/usr/local/bin/perl
        +
        +push(@INC,"perlasm","../../perlasm");
        +require "x86asm.pl";
        +require "cbc.pl";
        +
        +&asm_init($ARGV[0],"bf-686.pl");
        +
        +$BF_ROUNDS=16;
        +$BF_OFF=($BF_ROUNDS+2)*4;
        +$L="ecx";
        +$R="edx";
        +$P="edi";
        +$tot="esi";
        +$tmp1="eax";
        +$tmp2="ebx";
        +$tmp3="ebp";
        +
        +&des_encrypt("BF_encrypt",1);
        +&des_encrypt("BF_decrypt",0);
        +&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
        +
        +&asm_finish();
        +
        +&file_end();
        +
        +sub des_encrypt
        +	{
        +	local($name,$enc)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	&comment("Load the 2 words");
        +	&mov("eax",&wparam(0));
        +	&mov($L,&DWP(0,"eax","",0));
        +	&mov($R,&DWP(4,"eax","",0));
        +
        +	&comment("");
        +	&comment("P pointer, s and enc flag");
        +	&mov($P,&wparam(1));
        +
        +	&xor(	$tmp1,	$tmp1);
        +	&xor(	$tmp2,	$tmp2);
        +
        +	# encrypting part
        +
        +	if ($enc)
        +		{
        +		&xor($L,&DWP(0,$P,"",0));
        +		for ($i=0; $i<$BF_ROUNDS; $i+=2)
        +			{
        +			&comment("");
        +			&comment("Round $i");
        +			&BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3);
        +
        +			&comment("");
        +			&comment("Round ".sprintf("%d",$i+1));
        +			&BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3);
        +			}
        +		&xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
        +
        +		&mov("eax",&wparam(0));
        +		&mov(&DWP(0,"eax","",0),$R);
        +		&mov(&DWP(4,"eax","",0),$L);
        +		&function_end_A($name);
        +		}
        +	else
        +		{
        +		&xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
        +		for ($i=$BF_ROUNDS; $i>0; $i-=2)
        +			{
        +			&comment("");
        +			&comment("Round $i");
        +			&BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3);
        +			&comment("");
        +			&comment("Round ".sprintf("%d",$i-1));
        +			&BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3);
        +			}
        +		&xor($R,&DWP(0,$P,"",0));
        +
        +		&mov("eax",&wparam(0));
        +		&mov(&DWP(0,"eax","",0),$R);
        +		&mov(&DWP(4,"eax","",0),$L);
        +		&function_end_A($name);
        +		}
        +
        +	&function_end_B($name);
        +	}
        +
        +sub BF_ENCRYPT
        +	{
        +	local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_;
        +
        +	&rotr(	$R,		16);
        +	&mov(	$tot,		&DWP(&n2a($i*4),$P,"",0));
        +
        +	&movb(	&LB($tmp1),	&HB($R));
        +	&movb(	&LB($tmp2),	&LB($R));
        +
        +	&rotr(	$R,		16);
        +	&xor(	$L,		$tot);
        +
        +	&mov(	$tot,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
        +	&mov(	$tmp3,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
        +
        +	&movb(	&LB($tmp1),	&HB($R));
        +	&movb(	&LB($tmp2),	&LB($R));
        +
        +	&add(	$tot,		$tmp3);
        +	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay
        +
        +	&xor(	$tot,		$tmp1);
        +	&mov(	$tmp3,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4));
        +
        +	&add(	$tot,		$tmp3);
        +	&xor(	$tmp1,		$tmp1);
        +
        +	&xor(	$L,		$tot);					
        +	# delay
        +	}
        +
        +sub n2a
        +	{
        +	sprintf("%d",$_[0]);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/asm/readme b/vendor/openssl/openssl/crypto/bf/asm/readme
        new file mode 100644
        index 000000000..2385fa381
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/asm/readme
        @@ -0,0 +1,10 @@
        +There are blowfish assembler generation scripts.
        +bf-586.pl version is for the pentium and
        +bf-686.pl is my original version, which is faster on the pentium pro.
        +
        +When using a bf-586.pl, the pentium pro/II is %8 slower than using
        +bf-686.pl.  When using a bf-686.pl, the pentium is %16 slower
        +than bf-586.pl
        +
        +So the default is bf-586.pl
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_cbc.c b/vendor/openssl/openssl/crypto/bf/bf_cbc.c
        new file mode 100644
        index 000000000..f949629dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_cbc.c
        @@ -0,0 +1,143 @@
        +/* crypto/bf/bf_cbc.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 <openssl/blowfish.h>
        +#include "bf_locl.h"
        +
        +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
        +	{
        +	register BF_LONG tin0,tin1;
        +	register BF_LONG tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	BF_LONG tin[2];
        +
        +	if (encrypt)
        +		{
        +		n2l(ivec,tout0);
        +		n2l(ivec,tout1);
        +		ivec-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_encrypt(tin,schedule);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			n2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_encrypt(tin,schedule);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			}
        +		l2n(tout0,ivec);
        +		l2n(tout1,ivec);
        +		}
        +	else
        +		{
        +		n2l(ivec,xor0);
        +		n2l(ivec,xor1);
        +		ivec-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_decrypt(tin,schedule);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_decrypt(tin,schedule);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2nn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		l2n(xor0,ivec);
        +		l2n(xor1,ivec);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_cfb64.c b/vendor/openssl/openssl/crypto/bf/bf_cfb64.c
        new file mode 100644
        index 000000000..6451c8d40
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_cfb64.c
        @@ -0,0 +1,121 @@
        +/* crypto/bf/bf_cfb64.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 <openssl/blowfish.h>
        +#include "bf_locl.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     const BF_KEY *schedule, unsigned char *ivec, int *num, int encrypt)
        +	{
        +	register BF_LONG v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	BF_LONG ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv=(unsigned char *)ivec;
        +	if (encrypt)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				n2l(iv,v0); ti[0]=v0;
        +				n2l(iv,v1); ti[1]=v1;
        +				BF_encrypt((BF_LONG *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2n(t,iv);
        +				t=ti[1]; l2n(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				n2l(iv,v0); ti[0]=v0;
        +				n2l(iv,v1); ti[1]=v1;
        +				BF_encrypt((BF_LONG *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2n(t,iv);
        +				t=ti[1]; l2n(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=t=c=cc=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_ecb.c b/vendor/openssl/openssl/crypto/bf/bf_ecb.c
        new file mode 100644
        index 000000000..1607cefa3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_ecb.c
        @@ -0,0 +1,96 @@
        +/* crypto/bf/bf_ecb.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 <openssl/blowfish.h>
        +#include "bf_locl.h"
        +#include <openssl/opensslv.h>
        +
        +/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
        + * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
        + * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
        + */
        +
        +const char BF_version[]="Blowfish" OPENSSL_VERSION_PTEXT;
        +
        +const char *BF_options(void)
        +	{
        +#ifdef BF_PTR
        +	return("blowfish(ptr)");
        +#elif defined(BF_PTR2)
        +	return("blowfish(ptr2)");
        +#else
        +	return("blowfish(idx)");
        +#endif
        +	}
        +
        +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	     const BF_KEY *key, int encrypt)
        +	{
        +	BF_LONG l,d[2];
        +
        +	n2l(in,l); d[0]=l;
        +	n2l(in,l); d[1]=l;
        +	if (encrypt)
        +		BF_encrypt(d,key);
        +	else
        +		BF_decrypt(d,key);
        +	l=d[0]; l2n(l,out);
        +	l=d[1]; l2n(l,out);
        +	l=d[0]=d[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_enc.c b/vendor/openssl/openssl/crypto/bf/bf_enc.c
        new file mode 100644
        index 000000000..2d21d09f4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_enc.c
        @@ -0,0 +1,306 @@
        +/* crypto/bf/bf_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <openssl/blowfish.h>
        +#include "bf_locl.h"
        +
        +/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
        + * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
        + * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
        + */
        +
        +#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
        +#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
        +to modify the code.
        +#endif
        +
        +void BF_encrypt(BF_LONG *data, const BF_KEY *key)
        +	{
        +#ifndef BF_PTR2
        +	register BF_LONG l,r;
        +	register const BF_LONG *p,*s;
        +
        +	p=key->P;
        +	s= &(key->S[0]);
        +	l=data[0];
        +	r=data[1];
        +
        +	l^=p[0];
        +	BF_ENC(r,l,s,p[ 1]);
        +	BF_ENC(l,r,s,p[ 2]);
        +	BF_ENC(r,l,s,p[ 3]);
        +	BF_ENC(l,r,s,p[ 4]);
        +	BF_ENC(r,l,s,p[ 5]);
        +	BF_ENC(l,r,s,p[ 6]);
        +	BF_ENC(r,l,s,p[ 7]);
        +	BF_ENC(l,r,s,p[ 8]);
        +	BF_ENC(r,l,s,p[ 9]);
        +	BF_ENC(l,r,s,p[10]);
        +	BF_ENC(r,l,s,p[11]);
        +	BF_ENC(l,r,s,p[12]);
        +	BF_ENC(r,l,s,p[13]);
        +	BF_ENC(l,r,s,p[14]);
        +	BF_ENC(r,l,s,p[15]);
        +	BF_ENC(l,r,s,p[16]);
        +#if BF_ROUNDS == 20
        +	BF_ENC(r,l,s,p[17]);
        +	BF_ENC(l,r,s,p[18]);
        +	BF_ENC(r,l,s,p[19]);
        +	BF_ENC(l,r,s,p[20]);
        +#endif
        +	r^=p[BF_ROUNDS+1];
        +
        +	data[1]=l&0xffffffffL;
        +	data[0]=r&0xffffffffL;
        +#else
        +	register BF_LONG l,r,t,*k;
        +
        +	l=data[0];
        +	r=data[1];
        +	k=(BF_LONG*)key;
        +
        +	l^=k[0];
        +	BF_ENC(r,l,k, 1);
        +	BF_ENC(l,r,k, 2);
        +	BF_ENC(r,l,k, 3);
        +	BF_ENC(l,r,k, 4);
        +	BF_ENC(r,l,k, 5);
        +	BF_ENC(l,r,k, 6);
        +	BF_ENC(r,l,k, 7);
        +	BF_ENC(l,r,k, 8);
        +	BF_ENC(r,l,k, 9);
        +	BF_ENC(l,r,k,10);
        +	BF_ENC(r,l,k,11);
        +	BF_ENC(l,r,k,12);
        +	BF_ENC(r,l,k,13);
        +	BF_ENC(l,r,k,14);
        +	BF_ENC(r,l,k,15);
        +	BF_ENC(l,r,k,16);
        +#if BF_ROUNDS == 20
        +	BF_ENC(r,l,k,17);
        +	BF_ENC(l,r,k,18);
        +	BF_ENC(r,l,k,19);
        +	BF_ENC(l,r,k,20);
        +#endif
        +	r^=k[BF_ROUNDS+1];
        +
        +	data[1]=l&0xffffffffL;
        +	data[0]=r&0xffffffffL;
        +#endif
        +	}
        +
        +#ifndef BF_DEFAULT_OPTIONS
        +
        +void BF_decrypt(BF_LONG *data, const BF_KEY *key)
        +	{
        +#ifndef BF_PTR2
        +	register BF_LONG l,r;
        +	register const BF_LONG *p,*s;
        +
        +	p=key->P;
        +	s= &(key->S[0]);
        +	l=data[0];
        +	r=data[1];
        +
        +	l^=p[BF_ROUNDS+1];
        +#if BF_ROUNDS == 20
        +	BF_ENC(r,l,s,p[20]);
        +	BF_ENC(l,r,s,p[19]);
        +	BF_ENC(r,l,s,p[18]);
        +	BF_ENC(l,r,s,p[17]);
        +#endif
        +	BF_ENC(r,l,s,p[16]);
        +	BF_ENC(l,r,s,p[15]);
        +	BF_ENC(r,l,s,p[14]);
        +	BF_ENC(l,r,s,p[13]);
        +	BF_ENC(r,l,s,p[12]);
        +	BF_ENC(l,r,s,p[11]);
        +	BF_ENC(r,l,s,p[10]);
        +	BF_ENC(l,r,s,p[ 9]);
        +	BF_ENC(r,l,s,p[ 8]);
        +	BF_ENC(l,r,s,p[ 7]);
        +	BF_ENC(r,l,s,p[ 6]);
        +	BF_ENC(l,r,s,p[ 5]);
        +	BF_ENC(r,l,s,p[ 4]);
        +	BF_ENC(l,r,s,p[ 3]);
        +	BF_ENC(r,l,s,p[ 2]);
        +	BF_ENC(l,r,s,p[ 1]);
        +	r^=p[0];
        +
        +	data[1]=l&0xffffffffL;
        +	data[0]=r&0xffffffffL;
        +#else
        +	register BF_LONG l,r,t,*k;
        +
        +	l=data[0];
        +	r=data[1];
        +	k=(BF_LONG *)key;
        +
        +	l^=k[BF_ROUNDS+1];
        +#if BF_ROUNDS == 20
        +	BF_ENC(r,l,k,20);
        +	BF_ENC(l,r,k,19);
        +	BF_ENC(r,l,k,18);
        +	BF_ENC(l,r,k,17);
        +#endif
        +	BF_ENC(r,l,k,16);
        +	BF_ENC(l,r,k,15);
        +	BF_ENC(r,l,k,14);
        +	BF_ENC(l,r,k,13);
        +	BF_ENC(r,l,k,12);
        +	BF_ENC(l,r,k,11);
        +	BF_ENC(r,l,k,10);
        +	BF_ENC(l,r,k, 9);
        +	BF_ENC(r,l,k, 8);
        +	BF_ENC(l,r,k, 7);
        +	BF_ENC(r,l,k, 6);
        +	BF_ENC(l,r,k, 5);
        +	BF_ENC(r,l,k, 4);
        +	BF_ENC(l,r,k, 3);
        +	BF_ENC(r,l,k, 2);
        +	BF_ENC(l,r,k, 1);
        +	r^=k[0];
        +
        +	data[1]=l&0xffffffffL;
        +	data[0]=r&0xffffffffL;
        +#endif
        +	}
        +
        +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
        +	{
        +	register BF_LONG tin0,tin1;
        +	register BF_LONG tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	BF_LONG tin[2];
        +
        +	if (encrypt)
        +		{
        +		n2l(ivec,tout0);
        +		n2l(ivec,tout1);
        +		ivec-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_encrypt(tin,schedule);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			n2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_encrypt(tin,schedule);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			}
        +		l2n(tout0,ivec);
        +		l2n(tout1,ivec);
        +		}
        +	else
        +		{
        +		n2l(ivec,xor0);
        +		n2l(ivec,xor1);
        +		ivec-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_decrypt(tin,schedule);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			BF_decrypt(tin,schedule);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2nn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		l2n(xor0,ivec);
        +		l2n(xor1,ivec);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_locl.h b/vendor/openssl/openssl/crypto/bf/bf_locl.h
        new file mode 100644
        index 000000000..cc7c3ec99
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_locl.h
        @@ -0,0 +1,219 @@
        +/* crypto/bf/bf_locl.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_BF_LOCL_H
        +#define HEADER_BF_LOCL_H
        +#include <openssl/opensslconf.h> /* BF_PTR, BF_PTR2 */
        +
        +#undef c2l
        +#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
        +			 l|=((unsigned long)(*((c)++)))<< 8L, \
        +			 l|=((unsigned long)(*((c)++)))<<16L, \
        +			 l|=((unsigned long)(*((c)++)))<<24L)
        +
        +/* NOTE - c is not incremented as per c2l */
        +#undef c2ln
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 5: l2|=((unsigned long)(*(--(c))));     \
        +			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 1: l1|=((unsigned long)(*(--(c))));     \
        +				} \
        +			}
        +
        +#undef l2c
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +
        +/* NOTE - c is not incremented as per l2c */
        +#undef l2cn
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per n2l */
        +#define n2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))    ; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
        +			case 4: l1 =((unsigned long)(*(--(c))))    ; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per l2n */
        +#define l2nn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +				} \
        +			}
        +
        +#undef n2l
        +#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
        +                         l|=((unsigned long)(*((c)++)))<<16L, \
        +                         l|=((unsigned long)(*((c)++)))<< 8L, \
        +                         l|=((unsigned long)(*((c)++))))
        +
        +#undef l2n
        +#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)     )&0xff))
        +
        +/* This is actually a big endian algorithm, the most significant byte
        + * is used to lookup array 0 */
        +
        +#if defined(BF_PTR2)
        +
        +/*
        + * This is basically a special Intel version. Point is that Intel
        + * doesn't have many registers, but offers a reach choice of addressing
        + * modes. So we spare some registers by directly traversing BF_KEY
        + * structure and hiring the most decorated addressing mode. The code
        + * generated by EGCS is *perfectly* competitive with assembler
        + * implementation!
        + */
        +#define BF_ENC(LL,R,KEY,Pi) (\
        +	LL^=KEY[Pi], \
        +	t=  KEY[BF_ROUNDS+2 +   0 + ((R>>24)&0xFF)], \
        +	t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
        +	t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
        +	t+= KEY[BF_ROUNDS+2 + 768 + ((R    )&0xFF)], \
        +	LL^=t \
        +	)
        +
        +#elif defined(BF_PTR)
        +
        +#ifndef BF_LONG_LOG2
        +#define BF_LONG_LOG2  2       /* default to BF_LONG being 32 bits */
        +#endif
        +#define BF_M  (0xFF<<BF_LONG_LOG2)
        +#define BF_0  (24-BF_LONG_LOG2)
        +#define BF_1  (16-BF_LONG_LOG2)
        +#define BF_2  ( 8-BF_LONG_LOG2)
        +#define BF_3  BF_LONG_LOG2 /* left shift */
        +
        +/*
        + * This is normally very good on RISC platforms where normally you
        + * have to explicitly "multiply" array index by sizeof(BF_LONG)
        + * in order to calculate the effective address. This implementation
        + * excuses CPU from this extra work. Power[PC] uses should have most
        + * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely
        + * rlwinm. So let'em double-check if their compiler does it.
        + */
        +
        +#define BF_ENC(LL,R,S,P) ( \
        +	LL^=P, \
        +	LL^= (((*(BF_LONG *)((unsigned char *)&(S[  0])+((R>>BF_0)&BF_M))+ \
        +		*(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
        +		*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
        +		*(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \
        +	)
        +#else
        +
        +/*
        + * This is a *generic* version. Seem to perform best on platforms that
        + * offer explicit support for extraction of 8-bit nibbles preferably
        + * complemented with "multiplying" of array index by sizeof(BF_LONG).
        + * For the moment of this writing the list comprises Alpha CPU featuring
        + * extbl and s[48]addq instructions.
        + */
        +
        +#define BF_ENC(LL,R,S,P) ( \
        +	LL^=P, \
        +	LL^=(((	S[       ((int)(R>>24)&0xff)] + \
        +		S[0x0100+((int)(R>>16)&0xff)])^ \
        +		S[0x0200+((int)(R>> 8)&0xff)])+ \
        +		S[0x0300+((int)(R    )&0xff)])&0xffffffffL \
        +	)
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_ofb64.c b/vendor/openssl/openssl/crypto/bf/bf_ofb64.c
        new file mode 100644
        index 000000000..f2a9ff6e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_ofb64.c
        @@ -0,0 +1,110 @@
        +/* crypto/bf/bf_ofb64.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 <openssl/blowfish.h>
        +#include "bf_locl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     const BF_KEY *schedule, unsigned char *ivec, int *num)
        +	{
        +	register BF_LONG v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned char d[8];
        +	register char *dp;
        +	BF_LONG ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv=(unsigned char *)ivec;
        +	n2l(iv,v0);
        +	n2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=(char *)d;
        +	l2n(v0,dp);
        +	l2n(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			BF_encrypt((BF_LONG *)ti,schedule);
        +			dp=(char *)d;
        +			t=ti[0]; l2n(t,dp);
        +			t=ti[1]; l2n(t,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +		v0=ti[0];
        +		v1=ti[1];
        +		iv=(unsigned char *)ivec;
        +		l2n(v0,iv);
        +		l2n(v1,iv);
        +		}
        +	t=v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_opts.c b/vendor/openssl/openssl/crypto/bf/bf_opts.c
        new file mode 100644
        index 000000000..1721bb99b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_opts.c
        @@ -0,0 +1,331 @@
        +/* crypto/bf/bf_opts.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.]
        + */
        +
        +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
        + * This is for machines with 64k code segment size restrictions. */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/blowfish.h>
        +
        +#define BF_DEFAULT_OPTIONS
        +
        +#undef BF_ENC
        +#define BF_encrypt  BF_encrypt_normal
        +#undef HEADER_BF_LOCL_H
        +#include "bf_enc.c"
        +
        +#define BF_PTR
        +#undef BF_PTR2
        +#undef BF_ENC
        +#undef BF_encrypt
        +#define BF_encrypt  BF_encrypt_ptr
        +#undef HEADER_BF_LOCL_H
        +#include "bf_enc.c"
        +
        +#undef BF_PTR
        +#define BF_PTR2
        +#undef BF_ENC
        +#undef BF_encrypt
        +#define BF_encrypt  BF_encrypt_ptr2
        +#undef HEADER_BF_LOCL_H
        +#include "bf_enc.c"
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +# ifndef CLK_TCK
        +#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
        +#   define HZ	100.0
        +#  else /* _BSD_CLK_TCK_ */
        +#   define HZ ((double)_BSD_CLK_TCK_)
        +#  endif
        +# else /* CLK_TCK */
        +#  define HZ ((double)CLK_TCK)
        +# endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +#ifdef SIGALRM
        +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
        +#else
        +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
        +#endif
        +	
        +#define time_it(func,name,index) \
        +	print_name(name); \
        +	Time_F(START); \
        +	for (count=0,run=1; COND(cb); count+=4) \
        +		{ \
        +		unsigned long d[2]; \
        +		func(d,&sch); \
        +		func(d,&sch); \
        +		func(d,&sch); \
        +		func(d,&sch); \
        +		} \
        +	tm[index]=Time_F(STOP); \
        +	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
        +	tm[index]=((double)COUNT(cb))/tm[index];
        +
        +#define print_it(name,index) \
        +	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
        +		tm[index]*8,1.0e6/tm[index]);
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static char key[16]={	0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +				0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
        +	BF_KEY sch;
        +	double d,tm[16],max=0;
        +	int rank[16];
        +	char *str[16];
        +	int max_idx=0,i,num=0,j;
        +#ifndef SIGALARM
        +	long ca,cb,cc,cd,ce;
        +#endif
        +
        +	for (i=0; i<12; i++)
        +		{
        +		tm[i]=0.0;
        +		rank[i]=0;
        +		}
        +
        +#ifndef TIMES
        +	fprintf(stderr,"To get the most accurate results, try to run this\n");
        +	fprintf(stderr,"program when this computer is idle.\n");
        +#endif
        +
        +	BF_set_key(&sch,16,key);
        +
        +#ifndef SIGALRM
        +	fprintf(stderr,"First we calculate the approximate speed ...\n");
        +	count=10;
        +	do	{
        +		long i;
        +		unsigned long data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			BF_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count;
        +	cb=count*3;
        +	cc=count*3*8/BUFSIZE+1;
        +	cd=count*8/BUFSIZE+1;
        +
        +	ce=count/20+1;
        +#define COND(d) (count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c) (run)
        +#define COUNT(d) (count)
        +        signal(SIGALRM,sig_done);
        +        alarm(10);
        +#endif
        +
        +	time_it(BF_encrypt_normal,	"BF_encrypt_normal ", 0);
        +	time_it(BF_encrypt_ptr,		"BF_encrypt_ptr    ", 1);
        +	time_it(BF_encrypt_ptr2,	"BF_encrypt_ptr2   ", 2);
        +	num+=3;
        +
        +	str[0]="<nothing>";
        +	print_it("BF_encrypt_normal ",0);
        +	max=tm[0];
        +	max_idx=0;
        +	str[1]="ptr      ";
        +	print_it("BF_encrypt_ptr ",1);
        +	if (max < tm[1]) { max=tm[1]; max_idx=1; }
        +	str[2]="ptr2     ";
        +	print_it("BF_encrypt_ptr2 ",2);
        +	if (max < tm[2]) { max=tm[2]; max_idx=2; }
        +
        +	printf("options    BF ecb/s\n");
        +	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
        +	d=tm[max_idx];
        +	tm[max_idx]= -2.0;
        +	max= -1.0;
        +	for (;;)
        +		{
        +		for (i=0; i<3; i++)
        +			{
        +			if (max < tm[i]) { max=tm[i]; j=i; }
        +			}
        +		if (max < 0.0) break;
        +		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
        +		tm[j]= -2.0;
        +		max= -1.0;
        +		}
        +
        +	switch (max_idx)
        +		{
        +	case 0:
        +		printf("-DBF_DEFAULT_OPTIONS\n");
        +		break;
        +	case 1:
        +		printf("-DBF_PTR\n");
        +		break;
        +	case 2:
        +		printf("-DBF_PTR2\n");
        +		break;
        +		}
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_pi.h b/vendor/openssl/openssl/crypto/bf/bf_pi.h
        new file mode 100644
        index 000000000..9949513c6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_pi.h
        @@ -0,0 +1,325 @@
        +/* crypto/bf/bf_pi.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.]
        + */
        +
        +static const BF_KEY bf_init= {
        +	{
        +	0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
        +	0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
        +	0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
        +	0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
        +	0x9216d5d9L, 0x8979fb1b
        +	},{
        +	0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L, 
        +	0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L, 
        +	0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L, 
        +	0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL, 
        +	0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL, 
        +	0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L, 
        +	0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL, 
        +	0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL, 
        +	0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L, 
        +	0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L, 
        +	0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL, 
        +	0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL, 
        +	0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL, 
        +	0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L, 
        +	0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L, 
        +	0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L, 
        +	0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L, 
        +	0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L, 
        +	0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL, 
        +	0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L, 
        +	0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L, 
        +	0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L, 
        +	0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L, 
        +	0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL, 
        +	0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L, 
        +	0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL, 
        +	0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL, 
        +	0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L, 
        +	0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL, 
        +	0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L, 
        +	0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL, 
        +	0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L, 
        +	0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L, 
        +	0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL, 
        +	0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L, 
        +	0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L, 
        +	0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL, 
        +	0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L, 
        +	0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL, 
        +	0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L, 
        +	0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L, 
        +	0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL, 
        +	0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L, 
        +	0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L, 
        +	0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L, 
        +	0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L, 
        +	0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L, 
        +	0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL, 
        +	0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL, 
        +	0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L, 
        +	0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L, 
        +	0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L, 
        +	0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L, 
        +	0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL, 
        +	0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L, 
        +	0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL, 
        +	0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL, 
        +	0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L, 
        +	0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L, 
        +	0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L, 
        +	0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L, 
        +	0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L, 
        +	0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L, 
        +	0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL, 
        +	0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L, 
        +	0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L, 
        +	0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L, 
        +	0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL, 
        +	0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L, 
        +	0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L, 
        +	0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL, 
        +	0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L, 
        +	0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L, 
        +	0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L, 
        +	0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL, 
        +	0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL, 
        +	0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L, 
        +	0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L, 
        +	0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L, 
        +	0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L, 
        +	0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL, 
        +	0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL, 
        +	0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL, 
        +	0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L, 
        +	0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL, 
        +	0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L, 
        +	0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L, 
        +	0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL, 
        +	0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL, 
        +	0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L, 
        +	0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL, 
        +	0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L, 
        +	0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL, 
        +	0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL, 
        +	0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L, 
        +	0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L, 
        +	0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L, 
        +	0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L, 
        +	0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L, 
        +	0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L, 
        +	0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L, 
        +	0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL, 
        +	0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L, 
        +	0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL, 
        +	0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L, 
        +	0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L, 
        +	0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L, 
        +	0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L, 
        +	0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L, 
        +	0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L, 
        +	0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L, 
        +	0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L, 
        +	0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L, 
        +	0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L, 
        +	0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L, 
        +	0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L, 
        +	0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L, 
        +	0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L, 
        +	0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L, 
        +	0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L, 
        +	0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL, 
        +	0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL, 
        +	0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L, 
        +	0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL, 
        +	0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L, 
        +	0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L, 
        +	0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L, 
        +	0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L, 
        +	0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L, 
        +	0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L, 
        +	0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL, 
        +	0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L, 
        +	0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L, 
        +	0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L, 
        +	0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL, 
        +	0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL, 
        +	0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL, 
        +	0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L, 
        +	0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L, 
        +	0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL, 
        +	0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L, 
        +	0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL, 
        +	0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L, 
        +	0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL, 
        +	0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L, 
        +	0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL, 
        +	0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L, 
        +	0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL, 
        +	0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L, 
        +	0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L, 
        +	0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL, 
        +	0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L, 
        +	0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L, 
        +	0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L, 
        +	0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L, 
        +	0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL, 
        +	0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L, 
        +	0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL, 
        +	0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L, 
        +	0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL, 
        +	0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L, 
        +	0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL, 
        +	0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL, 
        +	0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL, 
        +	0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L, 
        +	0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L, 
        +	0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL, 
        +	0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL, 
        +	0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL, 
        +	0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL, 
        +	0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL, 
        +	0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L, 
        +	0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L, 
        +	0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L, 
        +	0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L, 
        +	0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL, 
        +	0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL, 
        +	0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L, 
        +	0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L, 
        +	0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L, 
        +	0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L, 
        +	0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L, 
        +	0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L, 
        +	0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L, 
        +	0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L, 
        +	0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L, 
        +	0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L, 
        +	0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL, 
        +	0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L, 
        +	0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL, 
        +	0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L, 
        +	0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L, 
        +	0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL, 
        +	0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL, 
        +	0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL, 
        +	0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L, 
        +	0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L, 
        +	0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L, 
        +	0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L, 
        +	0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L, 
        +	0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L, 
        +	0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L, 
        +	0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L, 
        +	0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L, 
        +	0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L, 
        +	0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L, 
        +	0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L, 
        +	0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL, 
        +	0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL, 
        +	0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L, 
        +	0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL, 
        +	0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL, 
        +	0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL, 
        +	0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L, 
        +	0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL, 
        +	0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL, 
        +	0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L, 
        +	0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L, 
        +	0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L, 
        +	0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L, 
        +	0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL, 
        +	0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL, 
        +	0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L, 
        +	0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L, 
        +	0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L, 
        +	0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL, 
        +	0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L, 
        +	0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L, 
        +	0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L, 
        +	0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL, 
        +	0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L, 
        +	0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L, 
        +	0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L, 
        +	0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL, 
        +	0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL, 
        +	0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L, 
        +	0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L, 
        +	0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L, 
        +	0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L, 
        +	0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL, 
        +	0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L, 
        +	0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL, 
        +	0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL, 
        +	0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L, 
        +	0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L, 
        +	0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL, 
        +	0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L, 
        +	0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL, 
        +	0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L, 
        +	0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL, 
        +	0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L, 
        +	0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L, 
        +	0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL, 
        +	0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L, 
        +	0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL, 
        +	0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L, 
        +	}
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bf_skey.c b/vendor/openssl/openssl/crypto/bf/bf_skey.c
        new file mode 100644
        index 000000000..3b0bca41a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bf_skey.c
        @@ -0,0 +1,124 @@
        +/* crypto/bf/bf_skey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/blowfish.h>
        +#include "bf_locl.h"
        +#include "bf_pi.h"
        +
        +void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
        +#ifdef OPENSSL_FIPS
        +	{
        +	fips_cipher_abort(BLOWFISH);
        +	private_BF_set_key(key, len, data);
        +	}
        +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data)
        +#endif
        +	{
        +	int i;
        +	BF_LONG *p,ri,in[2];
        +	const unsigned char *d,*end;
        +
        +
        +	memcpy(key,&bf_init,sizeof(BF_KEY));
        +	p=key->P;
        +
        +	if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
        +
        +	d=data;
        +	end= &(data[len]);
        +	for (i=0; i<(BF_ROUNDS+2); i++)
        +		{
        +		ri= *(d++);
        +		if (d >= end) d=data;
        +
        +		ri<<=8;
        +		ri|= *(d++);
        +		if (d >= end) d=data;
        +
        +		ri<<=8;
        +		ri|= *(d++);
        +		if (d >= end) d=data;
        +
        +		ri<<=8;
        +		ri|= *(d++);
        +		if (d >= end) d=data;
        +
        +		p[i]^=ri;
        +		}
        +
        +	in[0]=0L;
        +	in[1]=0L;
        +	for (i=0; i<(BF_ROUNDS+2); i+=2)
        +		{
        +		BF_encrypt(in,key);
        +		p[i  ]=in[0];
        +		p[i+1]=in[1];
        +		}
        +
        +	p=key->S;
        +	for (i=0; i<4*256; i+=2)
        +		{
        +		BF_encrypt(in,key);
        +		p[i  ]=in[0];
        +		p[i+1]=in[1];
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bfs.cpp b/vendor/openssl/openssl/crypto/bf/bfs.cpp
        new file mode 100644
        index 000000000..d74c45776
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bfs.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/blowfish.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	BF_KEY key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			BF_encrypt(&data[0],&key);
        +			GetTSC(s1);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			GetTSC(e2);
        +			BF_encrypt(&data[0],&key);
        +			}
        +
        +		printf("blowfish %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bf/bfspeed.c b/vendor/openssl/openssl/crypto/bf/bfspeed.c
        new file mode 100644
        index 000000000..c41ef3b40
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bfspeed.c
        @@ -0,0 +1,277 @@
        +/* crypto/bf/bfspeed.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/blowfish.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +#ifndef CLK_TCK
        +#define HZ	100.0
        +#else /* CLK_TCK */
        +#define HZ ((double)CLK_TCK)
        +#endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static unsigned char key[] ={
        +			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
        +			};
        +	BF_KEY sch;
        +	double a,b,c,d;
        +#ifndef SIGALRM
        +	long ca,cb,cc;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	BF_set_key(&sch,16,key);
        +	count=10;
        +	do	{
        +		long i;
        +		BF_LONG data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			BF_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count/512;
        +	cb=count;
        +	cc=count*8/BUFSIZE+1;
        +	printf("Doing BF_set_key %ld times\n",ca);
        +#define COND(d)	(count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing BF_set_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count+=4)
        +		{
        +		BF_set_key(&sch,16,key);
        +		BF_set_key(&sch,16,key);
        +		BF_set_key(&sch,16,key);
        +		BF_set_key(&sch,16,key);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld BF_set_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing BF_encrypt's for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing BF_encrypt %ld times\n",cb);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cb); count+=4)
        +		{
        +		BF_LONG data[2];
        +
        +		BF_encrypt(data,&sch);
        +		BF_encrypt(data,&sch);
        +		BF_encrypt(data,&sch);
        +		BF_encrypt(data,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld BF_encrypt's in %.2f second\n",count,d);
        +	b=((double)COUNT(cb)*8)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing BF_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing BF_cbc_encrypt %ld times on %ld byte blocks\n",cc,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		BF_cbc_encrypt(buf,buf,BUFSIZE,&sch,
        +			&(key[0]),BF_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld BF_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +	printf("Blowfish set_key       per sec = %12.3f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("Blowfish raw ecb bytes per sec = %12.3f (%9.3fuS)\n",b,8.0e6/b);
        +	printf("Blowfish cbc     bytes per sec = %12.3f (%9.3fuS)\n",c,8.0e6/c);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bf/bftest.c b/vendor/openssl/openssl/crypto/bf/bftest.c
        new file mode 100644
        index 000000000..97e6634d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/bftest.c
        @@ -0,0 +1,540 @@
        +/* crypto/bf/bftest.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.]
        + */
        +
        +/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
        + * RC2 modes, more of the code will be uncommented. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_BF is defined */
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_BF
        +int main(int argc, char *argv[])
        +{
        +    printf("No BF support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/blowfish.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static char *bf_key[2]={
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"Who is John Galt?"
        +	};
        +
        +/* big endian */
        +static BF_LONG bf_plain[2][2]={
        +	{0x424c4f57L,0x46495348L},
        +	{0xfedcba98L,0x76543210L}
        +	};
        +
        +static BF_LONG bf_cipher[2][2]={
        +	{0x324ed0feL,0xf413a203L},
        +	{0xcc91732bL,0x8022f684L}
        +	};
        +/************/
        +
        +/* Lets use the DES test vectors :-) */
        +#define NUM_TESTS 34
        +static unsigned char ecb_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
        +	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
        +	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
        +	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
        +	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
        +	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
        +	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
        +	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
        +	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
        +	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
        +	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
        +	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
        +	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
        +	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
        +	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
        +	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
        +	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
        +	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
        +	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
        +	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
        +	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
        +	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
        +	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
        +
        +static unsigned char plain_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
        +	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
        +	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
        +	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
        +	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
        +	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
        +	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
        +	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
        +	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
        +	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
        +	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
        +	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
        +	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
        +	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
        +	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
        +	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
        +	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
        +	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
        +	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
        +
        +static unsigned char cipher_data[NUM_TESTS][8]={
        +	{0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
        +	{0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A},
        +	{0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2},
        +	{0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D},
        +	{0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96},
        +	{0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7},
        +	{0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
        +	{0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D},
        +	{0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B},
        +	{0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0},
        +	{0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4},
        +	{0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB},
        +	{0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A},
        +	{0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18},
        +	{0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98},
        +	{0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5},
        +	{0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79},
        +	{0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3},
        +	{0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69},
        +	{0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B},
        +	{0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E},
        +	{0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD},
        +	{0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19},
        +	{0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3},
        +	{0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5},
        +	{0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78},
        +	{0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01},
        +	{0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2},
        +	{0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE},
        +	{0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D},
        +	{0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4},
        +	{0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC},
        +	{0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A},
        +	{0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A},
        +	};
        +
        +static unsigned char cbc_key [16]={
        +	0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        +	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
        +static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
        +static char cbc_data[40]="7654321 Now is the time for ";
        +static unsigned char cbc_ok[32]={
        +	0x6B,0x77,0xB4,0xD6,0x30,0x06,0xDE,0xE6,
        +	0x05,0xB1,0x56,0xE2,0x74,0x03,0x97,0x93,
        +	0x58,0xDE,0xB9,0xE7,0x15,0x46,0x16,0xD9,
        +	0x59,0xF1,0x65,0x2B,0xD5,0xFF,0x92,0xCC};
        +
        +static unsigned char cfb64_ok[]={
        +	0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
        +	0xF2,0x6E,0xCF,0x6D,0x2E,0xB9,0xE7,0x6E,
        +	0x3D,0xA3,0xDE,0x04,0xD1,0x51,0x72,0x00,
        +	0x51,0x9D,0x57,0xA6,0xC3};
        +
        +static unsigned char ofb64_ok[]={
        +	0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
        +	0x62,0xB3,0x43,0xCC,0x5B,0x65,0x58,0x73,
        +	0x10,0xDD,0x90,0x8D,0x0C,0x24,0x1B,0x22,
        +	0x63,0xC2,0xCF,0x80,0xDA};
        +
        +#define KEY_TEST_NUM	25
        +static unsigned char key_test[KEY_TEST_NUM]={
        +	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87,
        +	0x78,0x69,0x5a,0x4b,0x3c,0x2d,0x1e,0x0f,
        +	0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
        +	0x88};
        +
        +static unsigned char key_data[8]=
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10};
        +
        +static unsigned char key_out[KEY_TEST_NUM][8]={
        +	{0xF9,0xAD,0x59,0x7C,0x49,0xDB,0x00,0x5E},
        +	{0xE9,0x1D,0x21,0xC1,0xD9,0x61,0xA6,0xD6},
        +	{0xE9,0xC2,0xB7,0x0A,0x1B,0xC6,0x5C,0xF3},
        +	{0xBE,0x1E,0x63,0x94,0x08,0x64,0x0F,0x05},
        +	{0xB3,0x9E,0x44,0x48,0x1B,0xDB,0x1E,0x6E},
        +	{0x94,0x57,0xAA,0x83,0xB1,0x92,0x8C,0x0D},
        +	{0x8B,0xB7,0x70,0x32,0xF9,0x60,0x62,0x9D},
        +	{0xE8,0x7A,0x24,0x4E,0x2C,0xC8,0x5E,0x82},
        +	{0x15,0x75,0x0E,0x7A,0x4F,0x4E,0xC5,0x77},
        +	{0x12,0x2B,0xA7,0x0B,0x3A,0xB6,0x4A,0xE0},
        +	{0x3A,0x83,0x3C,0x9A,0xFF,0xC5,0x37,0xF6},
        +	{0x94,0x09,0xDA,0x87,0xA9,0x0F,0x6B,0xF2},
        +	{0x88,0x4F,0x80,0x62,0x50,0x60,0xB8,0xB4},
        +	{0x1F,0x85,0x03,0x1C,0x19,0xE1,0x19,0x68},
        +	{0x79,0xD9,0x37,0x3A,0x71,0x4C,0xA3,0x4F},
        +	{0x93,0x14,0x28,0x87,0xEE,0x3B,0xE1,0x5C},
        +	{0x03,0x42,0x9E,0x83,0x8C,0xE2,0xD1,0x4B},
        +	{0xA4,0x29,0x9E,0x27,0x46,0x9F,0xF6,0x7B},
        +	{0xAF,0xD5,0xAE,0xD1,0xC1,0xBC,0x96,0xA8},
        +	{0x10,0x85,0x1C,0x0E,0x38,0x58,0xDA,0x9F},
        +	{0xE6,0xF5,0x1E,0xD7,0x9B,0x9D,0xB2,0x1F},
        +	{0x64,0xA6,0xE1,0x4A,0xFD,0x36,0xB4,0x6F},
        +	{0x80,0xC7,0xD7,0xD4,0x5A,0x54,0x79,0xAD},
        +	{0x05,0x04,0x4B,0x62,0xFA,0x52,0xD0,0x80},
        +	};
        +
        +static int test(void );
        +static int print_test_data(void );
        +int main(int argc, char *argv[])
        +	{
        +	int ret;
        +
        +	if (argc > 1)
        +		ret=print_test_data();
        +	else
        +		ret=test();
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (ret) printf("ERROR: %d\n", ret);
        +#endif
        +	EXIT(ret);
        +	return(0);
        +	}
        +
        +static int print_test_data(void)
        +	{
        +	unsigned int i,j;
        +
        +	printf("ecb test data\n");
        +	printf("key bytes\t\tclear bytes\t\tcipher bytes\n");
        +	for (i=0; i<NUM_TESTS; i++)
        +		{
        +		for (j=0; j<8; j++)
        +			printf("%02X",ecb_data[i][j]);
        +		printf("\t");
        +		for (j=0; j<8; j++)
        +			printf("%02X",plain_data[i][j]);
        +		printf("\t");
        +		for (j=0; j<8; j++)
        +			printf("%02X",cipher_data[i][j]);
        +		printf("\n");
        +		}
        +
        +	printf("set_key test data\n");
        +	printf("data[8]= ");
        +	for (j=0; j<8; j++)
        +		printf("%02X",key_data[j]);
        +	printf("\n");
        +	for (i=0; i<KEY_TEST_NUM-1; i++)
        +		{
        +		printf("c=");
        +		for (j=0; j<8; j++)
        +			printf("%02X",key_out[i][j]);
        +		printf(" k[%2u]=",i+1);
        +		for (j=0; j<i+1; j++)
        +			printf("%02X",key_test[j]);
        +		printf("\n");
        +		}
        +
        +	printf("\nchaining mode test data\n");
        +	printf("key[16]   = ");
        +	for (j=0; j<16; j++)
        +		printf("%02X",cbc_key[j]);
        +	printf("\niv[8]     = ");
        +	for (j=0; j<8; j++)
        +		printf("%02X",cbc_iv[j]);
        +	printf("\ndata[%d]  = '%s'",(int)strlen(cbc_data)+1,cbc_data);
        +	printf("\ndata[%d]  = ",(int)strlen(cbc_data)+1);
        +	for (j=0; j<strlen(cbc_data)+1; j++)
        +		printf("%02X",cbc_data[j]);
        +	printf("\n");
        +	printf("cbc cipher text\n");
        +	printf("cipher[%d]= ",32);
        +	for (j=0; j<32; j++)
        +		printf("%02X",cbc_ok[j]);
        +	printf("\n");
        +
        +	printf("cfb64 cipher text\n");
        +	printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
        +	for (j=0; j<strlen(cbc_data)+1; j++)
        +		printf("%02X",cfb64_ok[j]);
        +	printf("\n");
        +
        +	printf("ofb64 cipher text\n");
        +	printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
        +	for (j=0; j<strlen(cbc_data)+1; j++)
        +		printf("%02X",ofb64_ok[j]);
        +	printf("\n");
        +	return(0);
        +	}
        +
        +static int test(void)
        +	{
        +	unsigned char cbc_in[40],cbc_out[40],iv[8];
        +	int i,n,err=0;
        +	BF_KEY key;
        +	BF_LONG data[2]; 
        +	unsigned char out[8]; 
        +	BF_LONG len;
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(cbc_data, cbc_data, strlen(cbc_data));
        +#endif
        +
        +	printf("testing blowfish in raw ecb mode\n");
        +	for (n=0; n<2; n++)
        +		{
        +#ifdef CHARSET_EBCDIC
        +		ebcdic2ascii(bf_key[n], bf_key[n], strlen(bf_key[n]));
        +#endif
        +		BF_set_key(&key,strlen(bf_key[n]),(unsigned char *)bf_key[n]);
        +
        +		data[0]=bf_plain[n][0];
        +		data[1]=bf_plain[n][1];
        +		BF_encrypt(data,&key);
        +		if (memcmp(&(bf_cipher[n][0]),&(data[0]),8) != 0)
        +			{
        +			printf("BF_encrypt error encrypting\n");
        +			printf("got     :");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)data[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)bf_cipher[n][i]);
        +			err=1;
        +			printf("\n");
        +			}
        +
        +		BF_decrypt(&(data[0]),&key);
        +		if (memcmp(&(bf_plain[n][0]),&(data[0]),8) != 0)
        +			{
        +			printf("BF_encrypt error decrypting\n");
        +			printf("got     :");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)data[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)bf_plain[n][i]);
        +			printf("\n");
        +			err=1;
        +			}
        +		}
        +
        +	printf("testing blowfish in ecb mode\n");
        +
        +	for (n=0; n<NUM_TESTS; n++)
        +		{
        +		BF_set_key(&key,8,ecb_data[n]);
        +
        +		BF_ecb_encrypt(&(plain_data[n][0]),out,&key,BF_ENCRYPT);
        +		if (memcmp(&(cipher_data[n][0]),out,8) != 0)
        +			{
        +			printf("BF_ecb_encrypt blowfish error encrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",out[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",cipher_data[n][i]);
        +			err=1;
        +			printf("\n");
        +			}
        +
        +		BF_ecb_encrypt(out,out,&key,BF_DECRYPT);
        +		if (memcmp(&(plain_data[n][0]),out,8) != 0)
        +			{
        +			printf("BF_ecb_encrypt error decrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",out[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",plain_data[n][i]);
        +			printf("\n");
        +			err=1;
        +			}
        +		}
        +
        +	printf("testing blowfish set_key\n");
        +	for (n=1; n<KEY_TEST_NUM; n++)
        +		{
        +		BF_set_key(&key,n,key_test);
        +		BF_ecb_encrypt(key_data,out,&key,BF_ENCRYPT);
        +		/* mips-sgi-irix6.5-gcc  vv  -mabi=64 bug workaround */
        +		if (memcmp(out,&(key_out[i=n-1][0]),8) != 0)
        +			{
        +			printf("blowfish setkey error\n");
        +			err=1;
        +			}
        +		}
        +
        +	printf("testing blowfish in cbc mode\n");
        +	len=strlen(cbc_data)+1;
        +
        +	BF_set_key(&key,16,cbc_key);
        +	memset(cbc_in,0,sizeof cbc_in);
        +	memset(cbc_out,0,sizeof cbc_out);
        +	memcpy(iv,cbc_iv,sizeof iv);
        +	BF_cbc_encrypt((unsigned char *)cbc_data,cbc_out,len,
        +		&key,iv,BF_ENCRYPT);
        +	if (memcmp(cbc_out,cbc_ok,32) != 0)
        +		{
        +		err=1;
        +		printf("BF_cbc_encrypt encrypt error\n");
        +		for (i=0; i<32; i++) printf("0x%02X,",cbc_out[i]);
        +		}
        +	memcpy(iv,cbc_iv,8);
        +	BF_cbc_encrypt(cbc_out,cbc_in,len,
        +		&key,iv,BF_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
        +		{
        +		printf("BF_cbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("testing blowfish in cfb64 mode\n");
        +
        +	BF_set_key(&key,16,cbc_key);
        +	memset(cbc_in,0,40);
        +	memset(cbc_out,0,40);
        +	memcpy(iv,cbc_iv,8);
        +	n=0;
        +	BF_cfb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,
        +		&key,iv,&n,BF_ENCRYPT);
        +	BF_cfb64_encrypt((unsigned char *)&(cbc_data[13]),&(cbc_out[13]),len-13,
        +		&key,iv,&n,BF_ENCRYPT);
        +	if (memcmp(cbc_out,cfb64_ok,(int)len) != 0)
        +		{
        +		err=1;
        +		printf("BF_cfb64_encrypt encrypt error\n");
        +		for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
        +		}
        +	n=0;
        +	memcpy(iv,cbc_iv,8);
        +	BF_cfb64_encrypt(cbc_out,cbc_in,17,
        +		&key,iv,&n,BF_DECRYPT);
        +	BF_cfb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,
        +		&key,iv,&n,BF_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,(int)len) != 0)
        +		{
        +		printf("BF_cfb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("testing blowfish in ofb64\n");
        +
        +	BF_set_key(&key,16,cbc_key);
        +	memset(cbc_in,0,40);
        +	memset(cbc_out,0,40);
        +	memcpy(iv,cbc_iv,8);
        +	n=0;
        +	BF_ofb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,&key,iv,&n);
        +	BF_ofb64_encrypt((unsigned char *)&(cbc_data[13]),
        +		&(cbc_out[13]),len-13,&key,iv,&n);
        +	if (memcmp(cbc_out,ofb64_ok,(int)len) != 0)
        +		{
        +		err=1;
        +		printf("BF_ofb64_encrypt encrypt error\n");
        +		for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
        +		}
        +	n=0;
        +	memcpy(iv,cbc_iv,8);
        +	BF_ofb64_encrypt(cbc_out,cbc_in,17,&key,iv,&n);
        +	BF_ofb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,&key,iv,&n);
        +	if (memcmp(cbc_in,cbc_data,(int)len) != 0)
        +		{
        +		printf("BF_ofb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	return(err);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bf/blowfish.h b/vendor/openssl/openssl/crypto/bf/blowfish.h
        new file mode 100644
        index 000000000..4b6c8920a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bf/blowfish.h
        @@ -0,0 +1,129 @@
        +/* crypto/bf/blowfish.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_BLOWFISH_H
        +#define HEADER_BLOWFISH_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_NO_BF
        +#error BF is disabled.
        +#endif
        +
        +#define BF_ENCRYPT	1
        +#define BF_DECRYPT	0
        +
        +/*
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
        + * ! BF_LONG_LOG2 has to be defined along.                        !
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + */
        +
        +#if defined(__LP32__)
        +#define BF_LONG unsigned long
        +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
        +#define BF_LONG unsigned long
        +#define BF_LONG_LOG2 3
        +/*
        + * _CRAY note. I could declare short, but I have no idea what impact
        + * does it have on performance on none-T3E machines. I could declare
        + * int, but at least on C90 sizeof(int) can be chosen at compile time.
        + * So I've chosen long...
        + *					<appro@fy.chalmers.se>
        + */
        +#else
        +#define BF_LONG unsigned int
        +#endif
        +
        +#define BF_ROUNDS	16
        +#define BF_BLOCK	8
        +
        +typedef struct bf_key_st
        +	{
        +	BF_LONG P[BF_ROUNDS+2];
        +	BF_LONG S[4*256];
        +	} BF_KEY;
        +
        +#ifdef OPENSSL_FIPS 
        +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data);
        +#endif
        +void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
        +
        +void BF_encrypt(BF_LONG *data,const BF_KEY *key);
        +void BF_decrypt(BF_LONG *data,const BF_KEY *key);
        +
        +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	const BF_KEY *key, int enc);
        +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	const BF_KEY *schedule, unsigned char *ivec, int enc);
        +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	const BF_KEY *schedule, unsigned char *ivec, int *num, int enc);
        +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	const BF_KEY *schedule, unsigned char *ivec, int *num);
        +const char *BF_options(void);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/Makefile b/vendor/openssl/openssl/crypto/bio/Makefile
        new file mode 100644
        index 000000000..c395d8049
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/Makefile
        @@ -0,0 +1,222 @@
        +#
        +# OpenSSL/crypto/bio/Makefile
        +#
        +
        +DIR=	bio
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= bio_lib.c bio_cb.c bio_err.c \
        +	bss_mem.c bss_null.c bss_fd.c \
        +	bss_file.c bss_sock.c bss_conn.c \
        +	bf_null.c bf_buff.c b_print.c b_dump.c \
        +	b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
        +	bss_dgram.c
        +#	bf_lbuf.c
        +LIBOBJ= bio_lib.o bio_cb.o bio_err.o \
        +	bss_mem.o bss_null.o bss_fd.o \
        +	bss_file.o bss_sock.o bss_conn.o \
        +	bf_null.o bf_buff.o b_print.o b_dump.o \
        +	b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o \
        +	bss_dgram.o
        +#	bf_lbuf.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= bio.h
        +HEADER=	bio_lcl.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +b_dump.o: ../../e_os.h ../../include/openssl/bio.h
        +b_dump.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +b_dump.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +b_dump.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +b_dump.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +b_dump.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +b_dump.o: ../../include/openssl/symhacks.h ../cryptlib.h b_dump.c bio_lcl.h
        +b_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +b_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +b_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +b_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +b_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +b_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +b_print.o: ../../include/openssl/symhacks.h ../cryptlib.h b_print.c
        +b_sock.o: ../../e_os.h ../../include/openssl/bio.h
        +b_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +b_sock.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +b_sock.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +b_sock.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +b_sock.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +b_sock.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +b_sock.o: ../cryptlib.h b_sock.c
        +bf_buff.o: ../../e_os.h ../../include/openssl/bio.h
        +bf_buff.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bf_buff.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bf_buff.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bf_buff.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bf_buff.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bf_buff.o: ../../include/openssl/symhacks.h ../cryptlib.h bf_buff.c
        +bf_nbio.o: ../../e_os.h ../../include/openssl/bio.h
        +bf_nbio.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bf_nbio.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bf_nbio.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bf_nbio.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bf_nbio.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +bf_nbio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bf_nbio.o: ../cryptlib.h bf_nbio.c
        +bf_null.o: ../../e_os.h ../../include/openssl/bio.h
        +bf_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bf_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bf_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bf_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bf_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bf_null.o: ../../include/openssl/symhacks.h ../cryptlib.h bf_null.c
        +bio_cb.o: ../../e_os.h ../../include/openssl/bio.h
        +bio_cb.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bio_cb.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bio_cb.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bio_cb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_cb.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_cb.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_cb.c
        +bio_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +bio_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bio_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bio_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_err.o: ../../include/openssl/symhacks.h bio_err.c
        +bio_lib.o: ../../e_os.h ../../include/openssl/bio.h
        +bio_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bio_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bio_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bio_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lib.c
        +bss_acpt.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_acpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_acpt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_acpt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_acpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_acpt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_acpt.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_acpt.c
        +bss_bio.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_bio.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bss_bio.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +bss_bio.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +bss_bio.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +bss_bio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bss_bio.o: bss_bio.c
        +bss_conn.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_conn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_conn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_conn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_conn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_conn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_conn.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_conn.c
        +bss_dgram.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_dgram.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_dgram.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_dgram.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_dgram.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_dgram.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_dgram.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_dgram.c
        +bss_fd.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_fd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_fd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_fd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_fd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_fd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_fd.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lcl.h bss_fd.c
        +bss_file.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_file.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_file.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_file.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_file.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_file.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_file.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lcl.h bss_file.c
        +bss_log.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_log.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_log.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_log.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_log.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_log.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_log.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_log.c
        +bss_mem.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_mem.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_mem.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_mem.c
        +bss_null.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_null.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_null.c
        +bss_sock.o: ../../e_os.h ../../include/openssl/bio.h
        +bss_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bss_sock.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bss_sock.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bss_sock.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bss_sock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bss_sock.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_sock.c
        diff --git a/vendor/openssl/openssl/crypto/bio/b_dump.c b/vendor/openssl/openssl/crypto/bio/b_dump.c
        new file mode 100644
        index 000000000..c80ecc429
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/b_dump.c
        @@ -0,0 +1,187 @@
        +/* crypto/bio/b_dump.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.]
        + */
        +
        +/* 
        + * Stolen from tjh's ssl/ssl_trc.c stuff.
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bio_lcl.h"
        +
        +#define TRUNCATE
        +#define DUMP_WIDTH	16
        +#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
        +
        +int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
        +	void *u, const char *s, int len)
        +	{
        +	return BIO_dump_indent_cb(cb, u, s, len, 0);
        +	}
        +
        +int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
        +	void *u, const char *s, int len, int indent)
        +	{
        +	int ret=0;
        +	char buf[288+1],tmp[20],str[128+1];
        +	int i,j,rows,trc;
        +	unsigned char ch;
        +	int dump_width;
        +
        +	trc=0;
        +
        +#ifdef TRUNCATE
        +	for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
        +		trc++;
        +#endif
        +
        +	if (indent < 0)
        +		indent = 0;
        +	if (indent)
        +		{
        +		if (indent > 128) indent=128;
        +		memset(str,' ',indent);
        +		}
        +	str[indent]='\0';
        +
        +	dump_width=DUMP_WIDTH_LESS_INDENT(indent);
        +	rows=(len/dump_width);
        +	if ((rows*dump_width)<len)
        +		rows++;
        +	for(i=0;i<rows;i++)
        +		{
        +		buf[0]='\0';	/* start with empty string */
        +		BUF_strlcpy(buf,str,sizeof buf);
        +		BIO_snprintf(tmp,sizeof tmp,"%04x - ",i*dump_width);
        +		BUF_strlcat(buf,tmp,sizeof buf);
        +		for(j=0;j<dump_width;j++)
        +			{
        +			if (((i*dump_width)+j)>=len)
        +				{
        +				BUF_strlcat(buf,"   ",sizeof buf);
        +				}
        +			else
        +				{
        +				ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
        +				BIO_snprintf(tmp,sizeof tmp,"%02x%c",ch,
        +					j==7?'-':' ');
        +				BUF_strlcat(buf,tmp,sizeof buf);
        +				}
        +			}
        +		BUF_strlcat(buf,"  ",sizeof buf);
        +		for(j=0;j<dump_width;j++)
        +			{
        +			if (((i*dump_width)+j)>=len)
        +				break;
        +			ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
        +#ifndef CHARSET_EBCDIC
        +			BIO_snprintf(tmp,sizeof tmp,"%c",
        +				((ch>=' ')&&(ch<='~'))?ch:'.');
        +#else
        +			BIO_snprintf(tmp,sizeof tmp,"%c",
        +				((ch>=os_toascii[' '])&&(ch<=os_toascii['~']))
        +				? os_toebcdic[ch]
        +				: '.');
        +#endif
        +			BUF_strlcat(buf,tmp,sizeof buf);
        +			}
        +		BUF_strlcat(buf,"\n",sizeof buf);
        +		/* if this is the last call then update the ddt_dump thing so
        +		 * that we will move the selection point in the debug window
        +		 */
        +		ret+=cb((void *)buf,strlen(buf),u);
        +		}
        +#ifdef TRUNCATE
        +	if (trc > 0)
        +		{
        +		BIO_snprintf(buf,sizeof buf,"%s%04x - <SPACES/NULS>\n",str,
        +			len+trc);
        +		ret+=cb((void *)buf,strlen(buf),u);
        +		}
        +#endif
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +static int write_fp(const void *data, size_t len, void *fp)
        +	{
        +	return UP_fwrite(data, len, 1, fp);
        +	}
        +int BIO_dump_fp(FILE *fp, const char *s, int len)
        +	{
        +	return BIO_dump_cb(write_fp, fp, s, len);
        +	}
        +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
        +	{
        +	return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
        +	}
        +#endif
        +
        +static int write_bio(const void *data, size_t len, void *bp)
        +	{
        +	return BIO_write((BIO *)bp, (const char *)data, len);
        +	}
        +int BIO_dump(BIO *bp, const char *s, int len)
        +	{
        +	return BIO_dump_cb(write_bio, bp, s, len);
        +	}
        +int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
        +	{
        +	return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/b_print.c b/vendor/openssl/openssl/crypto/bio/b_print.c
        new file mode 100644
        index 000000000..143a7cfef
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/b_print.c
        @@ -0,0 +1,842 @@
        +/* crypto/bio/b_print.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* disable assert() unless BIO_DEBUG has been defined */
        +#ifndef BIO_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +
        +/* 
        + * Stolen from tjh's ssl/ssl_trc.c stuff.
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include <assert.h>
        +#include <limits.h>
        +#include "cryptlib.h"
        +#ifndef NO_SYS_TYPES_H
        +#include <sys/types.h>
        +#endif
        +#include <openssl/bn.h>         /* To get BN_LLONG properly defined */
        +#include <openssl/bio.h>
        +
        +#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
        +# ifndef HAVE_LONG_LONG
        +#  define HAVE_LONG_LONG 1
        +# endif
        +#endif
        +
        +/***************************************************************************/
        +
        +/*
        + * Copyright Patrick Powell 1995
        + * This code is based on code written by Patrick Powell <papowell@astart.com>
        + * It may be used for any purpose as long as this notice remains intact
        + * on all source code distributions.
        + */
        +
        +/*
        + * This code contains numerious changes and enhancements which were
        + * made by lots of contributors over the last years to Patrick Powell's
        + * original code:
        + *
        + * o Patrick Powell <papowell@astart.com>      (1995)
        + * o Brandon Long <blong@fiction.net>          (1996, for Mutt)
        + * o Thomas Roessler <roessler@guug.de>        (1998, for Mutt)
        + * o Michael Elkins <me@cs.hmc.edu>            (1998, for Mutt)
        + * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
        + * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
        + * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
        + * o ...                                       (for OpenSSL)
        + */
        +
        +#ifdef HAVE_LONG_DOUBLE
        +#define LDOUBLE long double
        +#else
        +#define LDOUBLE double
        +#endif
        +
        +#ifdef HAVE_LONG_LONG
        +# if defined(_WIN32) && !defined(__GNUC__)
        +# define LLONG __int64
        +# else
        +# define LLONG long long
        +# endif
        +#else
        +#define LLONG long
        +#endif
        +
        +static void fmtstr     (char **, char **, size_t *, size_t *,
        +			const char *, int, int, int);
        +static void fmtint     (char **, char **, size_t *, size_t *,
        +			LLONG, int, int, int, int);
        +static void fmtfp      (char **, char **, size_t *, size_t *,
        +			LDOUBLE, int, int, int);
        +static void doapr_outch (char **, char **, size_t *, size_t *, int);
        +static void _dopr(char **sbuffer, char **buffer,
        +		  size_t *maxlen, size_t *retlen, int *truncated,
        +		  const char *format, va_list args);
        +
        +/* format read states */
        +#define DP_S_DEFAULT    0
        +#define DP_S_FLAGS      1
        +#define DP_S_MIN        2
        +#define DP_S_DOT        3
        +#define DP_S_MAX        4
        +#define DP_S_MOD        5
        +#define DP_S_CONV       6
        +#define DP_S_DONE       7
        +
        +/* format flags - Bits */
        +#define DP_F_MINUS      (1 << 0)
        +#define DP_F_PLUS       (1 << 1)
        +#define DP_F_SPACE      (1 << 2)
        +#define DP_F_NUM        (1 << 3)
        +#define DP_F_ZERO       (1 << 4)
        +#define DP_F_UP         (1 << 5)
        +#define DP_F_UNSIGNED   (1 << 6)
        +
        +/* conversion flags */
        +#define DP_C_SHORT      1
        +#define DP_C_LONG       2
        +#define DP_C_LDOUBLE    3
        +#define DP_C_LLONG      4
        +
        +/* some handy macros */
        +#define char_to_int(p) (p - '0')
        +#define OSSL_MAX(p,q) ((p >= q) ? p : q)
        +
        +static void
        +_dopr(
        +    char **sbuffer,
        +    char **buffer,
        +    size_t *maxlen,
        +    size_t *retlen,
        +    int *truncated,
        +    const char *format,
        +    va_list args)
        +{
        +    char ch;
        +    LLONG value;
        +    LDOUBLE fvalue;
        +    char *strvalue;
        +    int min;
        +    int max;
        +    int state;
        +    int flags;
        +    int cflags;
        +    size_t currlen;
        +
        +    state = DP_S_DEFAULT;
        +    flags = currlen = cflags = min = 0;
        +    max = -1;
        +    ch = *format++;
        +
        +    while (state != DP_S_DONE) {
        +        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
        +            state = DP_S_DONE;
        +
        +        switch (state) {
        +        case DP_S_DEFAULT:
        +            if (ch == '%')
        +                state = DP_S_FLAGS;
        +            else
        +                doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
        +            ch = *format++;
        +            break;
        +        case DP_S_FLAGS:
        +            switch (ch) {
        +            case '-':
        +                flags |= DP_F_MINUS;
        +                ch = *format++;
        +                break;
        +            case '+':
        +                flags |= DP_F_PLUS;
        +                ch = *format++;
        +                break;
        +            case ' ':
        +                flags |= DP_F_SPACE;
        +                ch = *format++;
        +                break;
        +            case '#':
        +                flags |= DP_F_NUM;
        +                ch = *format++;
        +                break;
        +            case '0':
        +                flags |= DP_F_ZERO;
        +                ch = *format++;
        +                break;
        +            default:
        +                state = DP_S_MIN;
        +                break;
        +            }
        +            break;
        +        case DP_S_MIN:
        +            if (isdigit((unsigned char)ch)) {
        +                min = 10 * min + char_to_int(ch);
        +                ch = *format++;
        +            } else if (ch == '*') {
        +                min = va_arg(args, int);
        +                ch = *format++;
        +                state = DP_S_DOT;
        +            } else
        +                state = DP_S_DOT;
        +            break;
        +        case DP_S_DOT:
        +            if (ch == '.') {
        +                state = DP_S_MAX;
        +                ch = *format++;
        +            } else
        +                state = DP_S_MOD;
        +            break;
        +        case DP_S_MAX:
        +            if (isdigit((unsigned char)ch)) {
        +                if (max < 0)
        +                    max = 0;
        +                max = 10 * max + char_to_int(ch);
        +                ch = *format++;
        +            } else if (ch == '*') {
        +                max = va_arg(args, int);
        +                ch = *format++;
        +                state = DP_S_MOD;
        +            } else
        +                state = DP_S_MOD;
        +            break;
        +        case DP_S_MOD:
        +            switch (ch) {
        +            case 'h':
        +                cflags = DP_C_SHORT;
        +                ch = *format++;
        +                break;
        +            case 'l':
        +                if (*format == 'l') {
        +                    cflags = DP_C_LLONG;
        +                    format++;
        +                } else
        +                    cflags = DP_C_LONG;
        +                ch = *format++;
        +                break;
        +            case 'q':
        +                cflags = DP_C_LLONG;
        +                ch = *format++;
        +                break;
        +            case 'L':
        +                cflags = DP_C_LDOUBLE;
        +                ch = *format++;
        +                break;
        +            default:
        +                break;
        +            }
        +            state = DP_S_CONV;
        +            break;
        +        case DP_S_CONV:
        +            switch (ch) {
        +            case 'd':
        +            case 'i':
        +                switch (cflags) {
        +                case DP_C_SHORT:
        +                    value = (short int)va_arg(args, int);
        +                    break;
        +                case DP_C_LONG:
        +                    value = va_arg(args, long int);
        +                    break;
        +                case DP_C_LLONG:
        +                    value = va_arg(args, LLONG);
        +                    break;
        +                default:
        +                    value = va_arg(args, int);
        +                    break;
        +                }
        +                fmtint(sbuffer, buffer, &currlen, maxlen,
        +                       value, 10, min, max, flags);
        +                break;
        +            case 'X':
        +                flags |= DP_F_UP;
        +                /* FALLTHROUGH */
        +            case 'x':
        +            case 'o':
        +            case 'u':
        +                flags |= DP_F_UNSIGNED;
        +                switch (cflags) {
        +                case DP_C_SHORT:
        +                    value = (unsigned short int)va_arg(args, unsigned int);
        +                    break;
        +                case DP_C_LONG:
        +                    value = (LLONG) va_arg(args,
        +                        unsigned long int);
        +                    break;
        +                case DP_C_LLONG:
        +                    value = va_arg(args, unsigned LLONG);
        +                    break;
        +                default:
        +                    value = (LLONG) va_arg(args,
        +                        unsigned int);
        +                    break;
        +                }
        +                fmtint(sbuffer, buffer, &currlen, maxlen, value,
        +                       ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
        +                       min, max, flags);
        +                break;
        +            case 'f':
        +                if (cflags == DP_C_LDOUBLE)
        +                    fvalue = va_arg(args, LDOUBLE);
        +                else
        +                    fvalue = va_arg(args, double);
        +                fmtfp(sbuffer, buffer, &currlen, maxlen,
        +                      fvalue, min, max, flags);
        +                break;
        +            case 'E':
        +                flags |= DP_F_UP;
        +            case 'e':
        +                if (cflags == DP_C_LDOUBLE)
        +                    fvalue = va_arg(args, LDOUBLE);
        +                else
        +                    fvalue = va_arg(args, double);
        +                break;
        +            case 'G':
        +                flags |= DP_F_UP;
        +            case 'g':
        +                if (cflags == DP_C_LDOUBLE)
        +                    fvalue = va_arg(args, LDOUBLE);
        +                else
        +                    fvalue = va_arg(args, double);
        +                break;
        +            case 'c':
        +                doapr_outch(sbuffer, buffer, &currlen, maxlen,
        +                    va_arg(args, int));
        +                break;
        +            case 's':
        +                strvalue = va_arg(args, char *);
        +                if (max < 0) {
        +		    if (buffer)
        +			max = INT_MAX;
        +		    else
        +			max = *maxlen;
        +		}
        +                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
        +                       flags, min, max);
        +                break;
        +            case 'p':
        +                value = (long)va_arg(args, void *);
        +                fmtint(sbuffer, buffer, &currlen, maxlen,
        +                    value, 16, min, max, flags|DP_F_NUM);
        +                break;
        +            case 'n': /* XXX */
        +                if (cflags == DP_C_SHORT) {
        +                    short int *num;
        +                    num = va_arg(args, short int *);
        +                    *num = currlen;
        +                } else if (cflags == DP_C_LONG) { /* XXX */
        +                    long int *num;
        +                    num = va_arg(args, long int *);
        +                    *num = (long int) currlen;
        +                } else if (cflags == DP_C_LLONG) { /* XXX */
        +                    LLONG *num;
        +                    num = va_arg(args, LLONG *);
        +                    *num = (LLONG) currlen;
        +                } else {
        +                    int    *num;
        +                    num = va_arg(args, int *);
        +                    *num = currlen;
        +                }
        +                break;
        +            case '%':
        +                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
        +                break;
        +            case 'w':
        +                /* not supported yet, treat as next char */
        +                ch = *format++;
        +                break;
        +            default:
        +                /* unknown, skip */
        +                break;
        +            }
        +            ch = *format++;
        +            state = DP_S_DEFAULT;
        +            flags = cflags = min = 0;
        +            max = -1;
        +            break;
        +        case DP_S_DONE:
        +            break;
        +        default:
        +            break;
        +        }
        +    }
        +    *truncated = (currlen > *maxlen - 1);
        +    if (*truncated)
        +        currlen = *maxlen - 1;
        +    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
        +    *retlen = currlen - 1;
        +    return;
        +}
        +
        +static void
        +fmtstr(
        +    char **sbuffer,
        +    char **buffer,
        +    size_t *currlen,
        +    size_t *maxlen,
        +    const char *value,
        +    int flags,
        +    int min,
        +    int max)
        +{
        +    int padlen, strln;
        +    int cnt = 0;
        +
        +    if (value == 0)
        +        value = "<NULL>";
        +    for (strln = 0; value[strln]; ++strln)
        +        ;
        +    padlen = min - strln;
        +    if (padlen < 0)
        +        padlen = 0;
        +    if (flags & DP_F_MINUS)
        +        padlen = -padlen;
        +
        +    while ((padlen > 0) && (cnt < max)) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        +        --padlen;
        +        ++cnt;
        +    }
        +    while (*value && (cnt < max)) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
        +        ++cnt;
        +    }
        +    while ((padlen < 0) && (cnt < max)) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        +        ++padlen;
        +        ++cnt;
        +    }
        +}
        +
        +static void
        +fmtint(
        +    char **sbuffer,
        +    char **buffer,
        +    size_t *currlen,
        +    size_t *maxlen,
        +    LLONG value,
        +    int base,
        +    int min,
        +    int max,
        +    int flags)
        +{
        +    int signvalue = 0;
        +    const char *prefix = "";
        +    unsigned LLONG uvalue;
        +    char convert[DECIMAL_SIZE(value)+3];
        +    int place = 0;
        +    int spadlen = 0;
        +    int zpadlen = 0;
        +    int caps = 0;
        +
        +    if (max < 0)
        +        max = 0;
        +    uvalue = value;
        +    if (!(flags & DP_F_UNSIGNED)) {
        +        if (value < 0) {
        +            signvalue = '-';
        +            uvalue = -value;
        +        } else if (flags & DP_F_PLUS)
        +            signvalue = '+';
        +        else if (flags & DP_F_SPACE)
        +            signvalue = ' ';
        +    }
        +    if (flags & DP_F_NUM) {
        +	if (base == 8) prefix = "0";
        +	if (base == 16) prefix = "0x";
        +    }
        +    if (flags & DP_F_UP)
        +        caps = 1;
        +    do {
        +        convert[place++] =
        +            (caps ? "0123456789ABCDEF" : "0123456789abcdef")
        +            [uvalue % (unsigned) base];
        +        uvalue = (uvalue / (unsigned) base);
        +    } while (uvalue && (place < (int)sizeof(convert)));
        +    if (place == sizeof(convert))
        +        place--;
        +    convert[place] = 0;
        +
        +    zpadlen = max - place;
        +    spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
        +    if (zpadlen < 0)
        +        zpadlen = 0;
        +    if (spadlen < 0)
        +        spadlen = 0;
        +    if (flags & DP_F_ZERO) {
        +        zpadlen = OSSL_MAX(zpadlen, spadlen);
        +        spadlen = 0;
        +    }
        +    if (flags & DP_F_MINUS)
        +        spadlen = -spadlen;
        +
        +    /* spaces */
        +    while (spadlen > 0) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        +        --spadlen;
        +    }
        +
        +    /* sign */
        +    if (signvalue)
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
        +
        +    /* prefix */
        +    while (*prefix) {
        +	doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
        +	prefix++;
        +    }
        +
        +    /* zeros */
        +    if (zpadlen > 0) {
        +        while (zpadlen > 0) {
        +            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
        +            --zpadlen;
        +        }
        +    }
        +    /* digits */
        +    while (place > 0)
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
        +
        +    /* left justified spaces */
        +    while (spadlen < 0) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        +        ++spadlen;
        +    }
        +    return;
        +}
        +
        +static LDOUBLE
        +abs_val(LDOUBLE value)
        +{
        +    LDOUBLE result = value;
        +    if (value < 0)
        +        result = -value;
        +    return result;
        +}
        +
        +static LDOUBLE
        +pow_10(int in_exp)
        +{
        +    LDOUBLE result = 1;
        +    while (in_exp) {
        +        result *= 10;
        +        in_exp--;
        +    }
        +    return result;
        +}
        +
        +static long
        +roundv(LDOUBLE value)
        +{
        +    long intpart;
        +    intpart = (long) value;
        +    value = value - intpart;
        +    if (value >= 0.5)
        +        intpart++;
        +    return intpart;
        +}
        +
        +static void
        +fmtfp(
        +    char **sbuffer,
        +    char **buffer,
        +    size_t *currlen,
        +    size_t *maxlen,
        +    LDOUBLE fvalue,
        +    int min,
        +    int max,
        +    int flags)
        +{
        +    int signvalue = 0;
        +    LDOUBLE ufvalue;
        +    char iconvert[20];
        +    char fconvert[20];
        +    int iplace = 0;
        +    int fplace = 0;
        +    int padlen = 0;
        +    int zpadlen = 0;
        +    int caps = 0;
        +    long intpart;
        +    long fracpart;
        +    long max10;
        +
        +    if (max < 0)
        +        max = 6;
        +    ufvalue = abs_val(fvalue);
        +    if (fvalue < 0)
        +        signvalue = '-';
        +    else if (flags & DP_F_PLUS)
        +        signvalue = '+';
        +    else if (flags & DP_F_SPACE)
        +        signvalue = ' ';
        +
        +    intpart = (long)ufvalue;
        +
        +    /* sorry, we only support 9 digits past the decimal because of our
        +       conversion method */
        +    if (max > 9)
        +        max = 9;
        +
        +    /* we "cheat" by converting the fractional part to integer by
        +       multiplying by a factor of 10 */
        +    max10 = roundv(pow_10(max));
        +    fracpart = roundv(pow_10(max) * (ufvalue - intpart));
        +
        +    if (fracpart >= max10) {
        +        intpart++;
        +        fracpart -= max10;
        +    }
        +
        +    /* convert integer part */
        +    do {
        +        iconvert[iplace++] =
        +            (caps ? "0123456789ABCDEF"
        +              : "0123456789abcdef")[intpart % 10];
        +        intpart = (intpart / 10);
        +    } while (intpart && (iplace < (int)sizeof(iconvert)));
        +    if (iplace == sizeof iconvert)
        +        iplace--;
        +    iconvert[iplace] = 0;
        +
        +    /* convert fractional part */
        +    do {
        +        fconvert[fplace++] =
        +            (caps ? "0123456789ABCDEF"
        +              : "0123456789abcdef")[fracpart % 10];
        +        fracpart = (fracpart / 10);
        +    } while (fplace < max);
        +    if (fplace == sizeof fconvert)
        +        fplace--;
        +    fconvert[fplace] = 0;
        +
        +    /* -1 for decimal point, another -1 if we are printing a sign */
        +    padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
        +    zpadlen = max - fplace;
        +    if (zpadlen < 0)
        +        zpadlen = 0;
        +    if (padlen < 0)
        +        padlen = 0;
        +    if (flags & DP_F_MINUS)
        +        padlen = -padlen;
        +
        +    if ((flags & DP_F_ZERO) && (padlen > 0)) {
        +        if (signvalue) {
        +            doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
        +            --padlen;
        +            signvalue = 0;
        +        }
        +        while (padlen > 0) {
        +            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
        +            --padlen;
        +        }
        +    }
        +    while (padlen > 0) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        +        --padlen;
        +    }
        +    if (signvalue)
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
        +
        +    while (iplace > 0)
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
        +
        +    /*
        +     * Decimal point. This should probably use locale to find the correct
        +     * char to print out.
        +     */
        +    if (max > 0 || (flags & DP_F_NUM)) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
        +
        +        while (fplace > 0)
        +            doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
        +    }
        +    while (zpadlen > 0) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
        +        --zpadlen;
        +    }
        +
        +    while (padlen < 0) {
        +        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
        +        ++padlen;
        +    }
        +}
        +
        +static void
        +doapr_outch(
        +    char **sbuffer,
        +    char **buffer,
        +    size_t *currlen,
        +    size_t *maxlen,
        +    int c)
        +{
        +    /* If we haven't at least one buffer, someone has doe a big booboo */
        +    assert(*sbuffer != NULL || buffer != NULL);
        +
        +    if (buffer) {
        +	while (*currlen >= *maxlen) {
        +	    if (*buffer == NULL) {
        +		if (*maxlen == 0)
        +		    *maxlen = 1024;
        +		*buffer = OPENSSL_malloc(*maxlen);
        +		if (*currlen > 0) {
        +		    assert(*sbuffer != NULL);
        +		    memcpy(*buffer, *sbuffer, *currlen);
        +		}
        +		*sbuffer = NULL;
        +	    } else {
        +		*maxlen += 1024;
        +		*buffer = OPENSSL_realloc(*buffer, *maxlen);
        +	    }
        +	}
        +	/* What to do if *buffer is NULL? */
        +	assert(*sbuffer != NULL || *buffer != NULL);
        +    }
        +
        +    if (*currlen < *maxlen) {
        +	if (*sbuffer)
        +	    (*sbuffer)[(*currlen)++] = (char)c;
        +	else
        +	    (*buffer)[(*currlen)++] = (char)c;
        +    }
        +
        +    return;
        +}
        +
        +/***************************************************************************/
        +
        +int BIO_printf (BIO *bio, const char *format, ...)
        +	{
        +	va_list args;
        +	int ret;
        +
        +	va_start(args, format);
        +
        +	ret = BIO_vprintf(bio, format, args);
        +
        +	va_end(args);
        +	return(ret);
        +	}
        +
        +int BIO_vprintf (BIO *bio, const char *format, va_list args)
        +	{
        +	int ret;
        +	size_t retlen;
        +	char hugebuf[1024*2];	/* Was previously 10k, which is unreasonable
        +				   in small-stack environments, like threads
        +				   or DOS programs. */
        +	char *hugebufp = hugebuf;
        +	size_t hugebufsize = sizeof(hugebuf);
        +	char *dynbuf = NULL;
        +	int ignored;
        +
        +	dynbuf = NULL;
        +	CRYPTO_push_info("doapr()");
        +	_dopr(&hugebufp, &dynbuf, &hugebufsize,
        +		&retlen, &ignored, format, args);
        +	if (dynbuf)
        +		{
        +		ret=BIO_write(bio, dynbuf, (int)retlen);
        +		OPENSSL_free(dynbuf);
        +		}
        +	else
        +		{
        +		ret=BIO_write(bio, hugebuf, (int)retlen);
        +		}
        +	CRYPTO_pop_info();
        +	return(ret);
        +	}
        +
        +/* As snprintf is not available everywhere, we provide our own implementation.
        + * This function has nothing to do with BIOs, but it's closely related
        + * to BIO_printf, and we need *some* name prefix ...
        + * (XXX  the function should be renamed, but to what?) */
        +int BIO_snprintf(char *buf, size_t n, const char *format, ...)
        +	{
        +	va_list args;
        +	int ret;
        +
        +	va_start(args, format);
        +
        +	ret = BIO_vsnprintf(buf, n, format, args);
        +
        +	va_end(args);
        +	return(ret);
        +	}
        +
        +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
        +	{
        +	size_t retlen;
        +	int truncated;
        +
        +	_dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
        +
        +	if (truncated)
        +		/* In case of truncation, return -1 like traditional snprintf.
        +		 * (Current drafts for ISO/IEC 9899 say snprintf should return
        +		 * the number of characters that would have been written,
        +		 * had the buffer been large enough.) */
        +		return -1;
        +	else
        +		return (retlen <= INT_MAX) ? (int)retlen : -1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bio/b_sock.c b/vendor/openssl/openssl/crypto/bio/b_sock.c
        new file mode 100644
        index 000000000..41f958be7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/b_sock.c
        @@ -0,0 +1,975 @@
        +/* crypto/bio/b_sock.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK)
        +#include <netdb.h>
        +#if defined(NETWARE_CLIB)
        +#include <sys/ioctl.h>
        +NETDB_DEFINE_CONTEXT
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_SOCK
        +
        +#include <openssl/dso.h>
        +
        +#define SOCKET_PROTOCOL IPPROTO_TCP
        +
        +#ifdef SO_MAXCONN
        +#define MAX_LISTEN  SO_MAXCONN
        +#elif defined(SOMAXCONN)
        +#define MAX_LISTEN  SOMAXCONN
        +#else
        +#define MAX_LISTEN  32
        +#endif
        +
        +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK))
        +static int wsa_init_done=0;
        +#endif
        +
        +/*
        + * WSAAPI specifier is required to make indirect calls to run-time
        + * linked WinSock 2 functions used in this module, to be specific
        + * [get|free]addrinfo and getnameinfo. This is because WinSock uses
        + * uses non-C calling convention, __stdcall vs. __cdecl, on x86
        + * Windows. On non-WinSock platforms WSAAPI needs to be void.
        + */
        +#ifndef WSAAPI
        +#define WSAAPI
        +#endif
        +
        +#if 0
        +static unsigned long BIO_ghbn_hits=0L;
        +static unsigned long BIO_ghbn_miss=0L;
        +
        +#define GHBN_NUM	4
        +static struct ghbn_cache_st
        +	{
        +	char name[129];
        +	struct hostent *ent;
        +	unsigned long order;
        +	} ghbn_cache[GHBN_NUM];
        +#endif
        +
        +static int get_ip(const char *str,unsigned char *ip);
        +#if 0
        +static void ghbn_free(struct hostent *a);
        +static struct hostent *ghbn_dup(struct hostent *a);
        +#endif
        +int BIO_get_host_ip(const char *str, unsigned char *ip)
        +	{
        +	int i;
        +	int err = 1;
        +	int locked = 0;
        +	struct hostent *he;
        +
        +	i=get_ip(str,ip);
        +	if (i < 0)
        +		{
        +		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS);
        +		goto err;
        +		}
        +
        +	/* At this point, we have something that is most probably correct
        +	   in some way, so let's init the socket. */
        +	if (BIO_sock_init() != 1)
        +		return 0; /* don't generate another error code here */
        +
        +	/* If the string actually contained an IP address, we need not do
        +	   anything more */
        +	if (i > 0) return(1);
        +
        +	/* do a gethostbyname */
        +	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
        +	locked = 1;
        +	he=BIO_gethostbyname(str);
        +	if (he == NULL)
        +		{
        +		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP);
        +		goto err;
        +		}
        +
        +	/* cast to short because of win16 winsock definition */
        +	if ((short)he->h_addrtype != AF_INET)
        +		{
        +		BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
        +		goto err;
        +		}
        +	for (i=0; i<4; i++)
        +		ip[i]=he->h_addr_list[0][i];
        +	err = 0;
        +
        + err:
        +	if (locked)
        +		CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
        +	if (err)
        +		{
        +		ERR_add_error_data(2,"host=",str);
        +		return 0;
        +		}
        +	else
        +		return 1;
        +	}
        +
        +int BIO_get_port(const char *str, unsigned short *port_ptr)
        +	{
        +	int i;
        +	struct servent *s;
        +
        +	if (str == NULL)
        +		{
        +		BIOerr(BIO_F_BIO_GET_PORT,BIO_R_NO_PORT_DEFINED);
        +		return(0);
        +		}
        +	i=atoi(str);
        +	if (i != 0)
        +		*port_ptr=(unsigned short)i;
        +	else
        +		{
        +		CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME);
        +		/* Note: under VMS with SOCKETSHR, it seems like the first
        +		 * parameter is 'char *', instead of 'const char *'
        +		 */
        +#ifndef CONST_STRICT
        +		s=getservbyname((char *)str,"tcp");
        +#else
        +		s=getservbyname(str,"tcp");
        +#endif
        +		if(s != NULL)
        +			*port_ptr=ntohs((unsigned short)s->s_port);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME);
        +		if(s == NULL)
        +			{
        +			if (strcmp(str,"http") == 0)
        +				*port_ptr=80;
        +			else if (strcmp(str,"telnet") == 0)
        +				*port_ptr=23;
        +			else if (strcmp(str,"socks") == 0)
        +				*port_ptr=1080;
        +			else if (strcmp(str,"https") == 0)
        +				*port_ptr=443;
        +			else if (strcmp(str,"ssl") == 0)
        +				*port_ptr=443;
        +			else if (strcmp(str,"ftp") == 0)
        +				*port_ptr=21;
        +			else if (strcmp(str,"gopher") == 0)
        +				*port_ptr=70;
        +#if 0
        +			else if (strcmp(str,"wais") == 0)
        +				*port_ptr=21;
        +#endif
        +			else
        +				{
        +				SYSerr(SYS_F_GETSERVBYNAME,get_last_socket_error());
        +				ERR_add_error_data(3,"service='",str,"'");
        +				return(0);
        +				}
        +			}
        +		}
        +	return(1);
        +	}
        +
        +int BIO_sock_error(int sock)
        +	{
        +	int j,i;
        +	int size;
        +		 
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +	return 0;
        +#endif
        +		 
        +	size=sizeof(int);
        +	/* Note: under Windows the third parameter is of type (char *)
        +	 * whereas under other systems it is (void *) if you don't have
        +	 * a cast it will choke the compiler: if you do have a cast then
        +	 * you can either go for (char *) or (void *).
        +	 */
        +	i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size);
        +	if (i < 0)
        +		return(1);
        +	else
        +		return(j);
        +	}
        +
        +#if 0
        +long BIO_ghbn_ctrl(int cmd, int iarg, char *parg)
        +	{
        +	int i;
        +	char **p;
        +
        +	switch (cmd)
        +		{
        +	case BIO_GHBN_CTRL_HITS:
        +		return(BIO_ghbn_hits);
        +		/* break; */
        +	case BIO_GHBN_CTRL_MISSES:
        +		return(BIO_ghbn_miss);
        +		/* break; */
        +	case BIO_GHBN_CTRL_CACHE_SIZE:
        +		return(GHBN_NUM);
        +		/* break; */
        +	case BIO_GHBN_CTRL_GET_ENTRY:
        +		if ((iarg >= 0) && (iarg <GHBN_NUM) &&
        +			(ghbn_cache[iarg].order > 0))
        +			{
        +			p=(char **)parg;
        +			if (p == NULL) return(0);
        +			*p=ghbn_cache[iarg].name;
        +			ghbn_cache[iarg].name[128]='\0';
        +			return(1);
        +			}
        +		return(0);
        +		/* break; */
        +	case BIO_GHBN_CTRL_FLUSH:
        +		for (i=0; i<GHBN_NUM; i++)
        +			ghbn_cache[i].order=0;
        +		break;
        +	default:
        +		return(0);
        +		}
        +	return(1);
        +	}
        +#endif
        +
        +#if 0
        +static struct hostent *ghbn_dup(struct hostent *a)
        +	{
        +	struct hostent *ret;
        +	int i,j;
        +
        +	MemCheck_off();
        +	ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent));
        +	if (ret == NULL) return(NULL);
        +	memset(ret,0,sizeof(struct hostent));
        +
        +	for (i=0; a->h_aliases[i] != NULL; i++)
        +		;
        +	i++;
        +	ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *));
        +	if (ret->h_aliases == NULL)
        +		goto err;
        +	memset(ret->h_aliases, 0, i*sizeof(char *));
        +
        +	for (i=0; a->h_addr_list[i] != NULL; i++)
        +		;
        +	i++;
        +	ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *));
        +	if (ret->h_addr_list == NULL)
        +		goto err;
        +	memset(ret->h_addr_list, 0, i*sizeof(char *));
        +
        +	j=strlen(a->h_name)+1;
        +	if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err;
        +	memcpy((char *)ret->h_name,a->h_name,j);
        +	for (i=0; a->h_aliases[i] != NULL; i++)
        +		{
        +		j=strlen(a->h_aliases[i])+1;
        +		if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err;
        +		memcpy(ret->h_aliases[i],a->h_aliases[i],j);
        +		}
        +	ret->h_length=a->h_length;
        +	ret->h_addrtype=a->h_addrtype;
        +	for (i=0; a->h_addr_list[i] != NULL; i++)
        +		{
        +		if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL)
        +			goto err;
        +		memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length);
        +		}
        +	if (0)
        +		{
        +err:	
        +		if (ret != NULL)
        +			ghbn_free(ret);
        +		ret=NULL;
        +		}
        +	MemCheck_on();
        +	return(ret);
        +	}
        +
        +static void ghbn_free(struct hostent *a)
        +	{
        +	int i;
        +
        +	if(a == NULL)
        +	    return;
        +
        +	if (a->h_aliases != NULL)
        +		{
        +		for (i=0; a->h_aliases[i] != NULL; i++)
        +			OPENSSL_free(a->h_aliases[i]);
        +		OPENSSL_free(a->h_aliases);
        +		}
        +	if (a->h_addr_list != NULL)
        +		{
        +		for (i=0; a->h_addr_list[i] != NULL; i++)
        +			OPENSSL_free(a->h_addr_list[i]);
        +		OPENSSL_free(a->h_addr_list);
        +		}
        +	if (a->h_name != NULL) OPENSSL_free(a->h_name);
        +	OPENSSL_free(a);
        +	}
        +
        +#endif
        +
        +struct hostent *BIO_gethostbyname(const char *name)
        +	{
        +#if 1
        +	/* Caching gethostbyname() results forever is wrong,
        +	 * so we have to let the true gethostbyname() worry about this */
        +#if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
        +	return gethostbyname((char*)name);
        +#else
        +	return gethostbyname(name);
        +#endif
        +#else
        +	struct hostent *ret;
        +	int i,lowi=0,j;
        +	unsigned long low= (unsigned long)-1;
        +
        +
        +#  if 0
        +	/* It doesn't make sense to use locking here: The function interface
        +	 * is not thread-safe, because threads can never be sure when
        +	 * some other thread destroys the data they were given a pointer to.
        +	 */
        +	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
        +#  endif
        +	j=strlen(name);
        +	if (j < 128)
        +		{
        +		for (i=0; i<GHBN_NUM; i++)
        +			{
        +			if (low > ghbn_cache[i].order)
        +				{
        +				low=ghbn_cache[i].order;
        +				lowi=i;
        +				}
        +			if (ghbn_cache[i].order > 0)
        +				{
        +				if (strncmp(name,ghbn_cache[i].name,128) == 0)
        +					break;
        +				}
        +			}
        +		}
        +	else
        +		i=GHBN_NUM;
        +
        +	if (i == GHBN_NUM) /* no hit*/
        +		{
        +		BIO_ghbn_miss++;
        +		/* Note: under VMS with SOCKETSHR, it seems like the first
        +		 * parameter is 'char *', instead of 'const char *'
        +		 */
        +#  ifndef CONST_STRICT
        +		ret=gethostbyname((char *)name);
        +#  else
        +		ret=gethostbyname(name);
        +#  endif
        +
        +		if (ret == NULL)
        +			goto end;
        +		if (j > 128) /* too big to cache */
        +			{
        +#  if 0
        +			/* If we were trying to make this function thread-safe (which
        +			 * is bound to fail), we'd have to give up in this case
        +			 * (or allocate more memory). */
        +			ret = NULL;
        +#  endif
        +			goto end;
        +			}
        +
        +		/* else add to cache */
        +		if (ghbn_cache[lowi].ent != NULL)
        +			ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
        +		ghbn_cache[lowi].name[0] = '\0';
        +
        +		if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
        +			{
        +			BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
        +			goto end;
        +			}
        +		strncpy(ghbn_cache[lowi].name,name,128);
        +		ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
        +		}
        +	else
        +		{
        +		BIO_ghbn_hits++;
        +		ret= ghbn_cache[i].ent;
        +		ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
        +		}
        +end:
        +#  if 0
        +	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
        +#  endif
        +	return(ret);
        +#endif
        +	}
        +
        +
        +int BIO_sock_init(void)
        +	{
        +#ifdef OPENSSL_SYS_WINDOWS
        +	static struct WSAData wsa_state;
        +
        +	if (!wsa_init_done)
        +		{
        +		int err;
        +	  
        +		wsa_init_done=1;
        +		memset(&wsa_state,0,sizeof(wsa_state));
        +		/* Not making wsa_state available to the rest of the
        +		 * code is formally wrong. But the structures we use
        +		 * are [beleived to be] invariable among Winsock DLLs,
        +		 * while API availability is [expected to be] probed
        +		 * at run-time with DSO_global_lookup. */
        +		if (WSAStartup(0x0202,&wsa_state)!=0)
        +			{
        +			err=WSAGetLastError();
        +			SYSerr(SYS_F_WSASTARTUP,err);
        +			BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
        +			return(-1);
        +			}
        +		}
        +#endif /* OPENSSL_SYS_WINDOWS */
        +#ifdef WATT32
        +	extern int _watt_do_exit;
        +	_watt_do_exit = 0;    /* don't make sock_init() call exit() */
        +	if (sock_init())
        +		return (-1);
        +#endif
        +
        +#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
        +    WORD wVerReq;
        +    WSADATA wsaData;
        +    int err;
        +
        +    if (!wsa_init_done)
        +    {
        +        wsa_init_done=1;
        +        wVerReq = MAKEWORD( 2, 0 );
        +        err = WSAStartup(wVerReq,&wsaData);
        +        if (err != 0)
        +        {
        +            SYSerr(SYS_F_WSASTARTUP,err);
        +            BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
        +            return(-1);
        +			}
        +		}
        +#endif
        +
        +	return(1);
        +	}
        +
        +void BIO_sock_cleanup(void)
        +	{
        +#ifdef OPENSSL_SYS_WINDOWS
        +	if (wsa_init_done)
        +		{
        +		wsa_init_done=0;
        +#if 0		/* this call is claimed to be non-present in Winsock2 */
        +		WSACancelBlockingCall();
        +#endif
        +		WSACleanup();
        +		}
        +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)
        +   if (wsa_init_done)
        +        {
        +        wsa_init_done=0;
        +        WSACleanup();
        +		}
        +#endif
        +	}
        +
        +#if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
        +
        +int BIO_socket_ioctl(int fd, long type, void *arg)
        +	{
        +	int i;
        +
        +#ifdef __DJGPP__
        +	i=ioctlsocket(fd,type,(char *)arg);
        +#else
        +# if defined(OPENSSL_SYS_VMS)
        +	/* 2011-02-18 SMS.
        +	 * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
        +	 * observe that all the consumers pass in an "unsigned long *",
        +	 * so we arrange a local copy with a short pointer, and use
        +	 * that, instead.
        +	 */
        +#  if __INITIAL_POINTER_SIZE == 64
        +#   define ARG arg_32p
        +#   pragma pointer_size save
        +#   pragma pointer_size 32
        +	unsigned long arg_32;
        +	unsigned long *arg_32p;
        +#   pragma pointer_size restore
        +	arg_32p = &arg_32;
        +	arg_32 = *((unsigned long *) arg);
        +#  else /* __INITIAL_POINTER_SIZE == 64 */
        +#   define ARG arg
        +#  endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +# else /* defined(OPENSSL_SYS_VMS) */
        +#  define ARG arg
        +# endif /* defined(OPENSSL_SYS_VMS) [else] */
        +
        +	i=ioctlsocket(fd,type,ARG);
        +#endif /* __DJGPP__ */
        +	if (i < 0)
        +		SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error());
        +	return(i);
        +	}
        +#endif /* __VMS_VER */
        +
        +/* The reason I have implemented this instead of using sscanf is because
        + * Visual C 1.52c gives an unresolved external when linking a DLL :-( */
        +static int get_ip(const char *str, unsigned char ip[4])
        +	{
        +	unsigned int tmp[4];
        +	int num=0,c,ok=0;
        +
        +	tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
        +
        +	for (;;)
        +		{
        +		c= *(str++);
        +		if ((c >= '0') && (c <= '9'))
        +			{
        +			ok=1;
        +			tmp[num]=tmp[num]*10+c-'0';
        +			if (tmp[num] > 255) return(0);
        +			}
        +		else if (c == '.')
        +			{
        +			if (!ok) return(-1);
        +			if (num == 3) return(0);
        +			num++;
        +			ok=0;
        +			}
        +		else if (c == '\0' && (num == 3) && ok)
        +			break;
        +		else
        +			return(0);
        +		}
        +	ip[0]=tmp[0];
        +	ip[1]=tmp[1];
        +	ip[2]=tmp[2];
        +	ip[3]=tmp[3];
        +	return(1);
        +	}
        +
        +int BIO_get_accept_socket(char *host, int bind_mode)
        +	{
        +	int ret=0;
        +	union {
        +		struct sockaddr sa;
        +		struct sockaddr_in sa_in;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 sa_in6;
        +#endif
        +	} server,client;
        +	int s=INVALID_SOCKET,cs,addrlen;
        +	unsigned char ip[4];
        +	unsigned short port;
        +	char *str=NULL,*e;
        +	char *h,*p;
        +	unsigned long l;
        +	int err_num;
        +
        +	if (BIO_sock_init() != 1) return(INVALID_SOCKET);
        +
        +	if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET);
        +
        +	h=p=NULL;
        +	h=str;
        +	for (e=str; *e; e++)
        +		{
        +		if (*e == ':')
        +			{
        +			p=e;
        +			}
        +		else if (*e == '/')
        +			{
        +			*e='\0';
        +			break;
        +			}
        +		}
        +	if (p)	*p++='\0';	/* points at last ':', '::port' is special [see below] */
        +	else	p=h,h=NULL;
        +
        +#ifdef EAI_FAMILY
        +	do {
        +	static union {	void *p;
        +			int (WSAAPI *f)(const char *,const char *,
        +				 const struct addrinfo *,
        +				 struct addrinfo **);
        +			} p_getaddrinfo = {NULL};
        +	static union {	void *p;
        +			void (WSAAPI *f)(struct addrinfo *);
        +			} p_freeaddrinfo = {NULL};
        +	struct addrinfo *res,hint;
        +
        +	if (p_getaddrinfo.p==NULL)
        +		{
        +		if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL ||
        +		    (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL)
        +			p_getaddrinfo.p=(void*)-1;
        +		}
        +	if (p_getaddrinfo.p==(void *)-1) break;
        +
        +	/* '::port' enforces IPv6 wildcard listener. Some OSes,
        +	 * e.g. Solaris, default to IPv6 without any hint. Also
        +	 * note that commonly IPv6 wildchard socket can service
        +	 * IPv4 connections just as well...  */
        +	memset(&hint,0,sizeof(hint));
        +	hint.ai_flags = AI_PASSIVE;
        +	if (h)
        +		{
        +		if (strchr(h,':'))
        +			{
        +			if (h[1]=='\0') h=NULL;
        +#if OPENSSL_USE_IPV6
        +			hint.ai_family = AF_INET6;
        +#else
        +			h=NULL;
        +#endif
        +			}
        +	    	else if (h[0]=='*' && h[1]=='\0')
        +			{
        +			hint.ai_family = AF_INET;
        +			h=NULL;
        +			}
        +		}
        +
        +	if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
        +
        +	addrlen = res->ai_addrlen<=sizeof(server) ?
        +			res->ai_addrlen :
        +			sizeof(server);
        +	memcpy(&server, res->ai_addr, addrlen);
        +
        +	(*p_freeaddrinfo.f)(res);
        +	goto again;
        +	} while (0);
        +#endif
        +
        +	if (!BIO_get_port(p,&port)) goto err;
        +
        +	memset((char *)&server,0,sizeof(server));
        +	server.sa_in.sin_family=AF_INET;
        +	server.sa_in.sin_port=htons(port);
        +	addrlen = sizeof(server.sa_in);
        +
        +	if (h == NULL || strcmp(h,"*") == 0)
        +		server.sa_in.sin_addr.s_addr=INADDR_ANY;
        +	else
        +		{
        +                if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
        +		l=(unsigned long)
        +			((unsigned long)ip[0]<<24L)|
        +			((unsigned long)ip[1]<<16L)|
        +			((unsigned long)ip[2]<< 8L)|
        +			((unsigned long)ip[3]);
        +		server.sa_in.sin_addr.s_addr=htonl(l);
        +		}
        +
        +again:
        +	s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
        +	if (s == INVALID_SOCKET)
        +		{
        +		SYSerr(SYS_F_SOCKET,get_last_socket_error());
        +		ERR_add_error_data(3,"port='",host,"'");
        +		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET);
        +		goto err;
        +		}
        +
        +#ifdef SO_REUSEADDR
        +	if (bind_mode == BIO_BIND_REUSEADDR)
        +		{
        +		int i=1;
        +
        +		ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i));
        +		bind_mode=BIO_BIND_NORMAL;
        +		}
        +#endif
        +	if (bind(s,&server.sa,addrlen) == -1)
        +		{
        +#ifdef SO_REUSEADDR
        +		err_num=get_last_socket_error();
        +		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
        +#ifdef OPENSSL_SYS_WINDOWS
        +			/* Some versions of Windows define EADDRINUSE to
        +			 * a dummy value.
        +			 */
        +			(err_num == WSAEADDRINUSE))
        +#else
        +			(err_num == EADDRINUSE))
        +#endif
        +			{
        +			client = server;
        +			if (h == NULL || strcmp(h,"*") == 0)
        +				{
        +#if OPENSSL_USE_IPV6
        +				if (client.sa.sa_family == AF_INET6)
        +					{
        +					memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr));
        +					client.sa_in6.sin6_addr.s6_addr[15]=1;
        +					}
        +				else
        +#endif
        +				if (client.sa.sa_family == AF_INET)
        +					{
        +					client.sa_in.sin_addr.s_addr=htonl(0x7F000001);
        +					}
        +				else	goto err;
        +				}
        +			cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
        +			if (cs != INVALID_SOCKET)
        +				{
        +				int ii;
        +				ii=connect(cs,&client.sa,addrlen);
        +				closesocket(cs);
        +				if (ii == INVALID_SOCKET)
        +					{
        +					bind_mode=BIO_BIND_REUSEADDR;
        +					closesocket(s);
        +					goto again;
        +					}
        +				/* else error */
        +				}
        +			/* else error */
        +			}
        +#endif
        +		SYSerr(SYS_F_BIND,err_num);
        +		ERR_add_error_data(3,"port='",host,"'");
        +		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET);
        +		goto err;
        +		}
        +	if (listen(s,MAX_LISTEN) == -1)
        +		{
        +		SYSerr(SYS_F_BIND,get_last_socket_error());
        +		ERR_add_error_data(3,"port='",host,"'");
        +		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_LISTEN_SOCKET);
        +		goto err;
        +		}
        +	ret=1;
        +err:
        +	if (str != NULL) OPENSSL_free(str);
        +	if ((ret == 0) && (s != INVALID_SOCKET))
        +		{
        +		closesocket(s);
        +		s= INVALID_SOCKET;
        +		}
        +	return(s);
        +	}
        +
        +int BIO_accept(int sock, char **addr)
        +	{
        +	int ret=INVALID_SOCKET;
        +	unsigned long l;
        +	unsigned short port;
        +	char *p;
        +
        +	struct {
        +	/*
        +	 * As for following union. Trouble is that there are platforms
        +	 * that have socklen_t and there are platforms that don't, on
        +	 * some platforms socklen_t is int and on some size_t. So what
        +	 * one can do? One can cook #ifdef spaghetti, which is nothing
        +	 * but masochistic. Or one can do union between int and size_t.
        +	 * One naturally does it primarily for 64-bit platforms where
        +	 * sizeof(int) != sizeof(size_t). But would it work? Note that
        +	 * if size_t member is initialized to 0, then later int member
        +	 * assignment naturally does the job on little-endian platforms
        +	 * regardless accept's expectations! What about big-endians?
        +	 * If accept expects int*, then it works, and if size_t*, then
        +	 * length value would appear as unreasonably large. But this
        +	 * won't prevent it from filling in the address structure. The
        +	 * trouble of course would be if accept returns more data than
        +	 * actual buffer can accomodate and overwrite stack... That's
        +	 * where early OPENSSL_assert comes into picture. Besides, the
        +	 * only 64-bit big-endian platform found so far that expects
        +	 * size_t* is HP-UX, where stack grows towards higher address.
        +	 * <appro>
        +	 */
        +	union { size_t s; int i; } len;
        +	union {
        +		struct sockaddr sa;
        +		struct sockaddr_in sa_in;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 sa_in6;
        +#endif
        +		} from;
        +	} sa;
        +
        +	sa.len.s=0;
        +	sa.len.i=sizeof(sa.from);
        +	memset(&sa.from,0,sizeof(sa.from));
        +	ret=accept(sock,&sa.from.sa,(void *)&sa.len);
        +	if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
        +		{
        +		OPENSSL_assert(sa.len.s<=sizeof(sa.from));
        +		sa.len.i = (int)sa.len.s;
        +		/* use sa.len.i from this point */
        +		}
        +	if (ret == INVALID_SOCKET)
        +		{
        +		if(BIO_sock_should_retry(ret)) return -2;
        +		SYSerr(SYS_F_ACCEPT,get_last_socket_error());
        +		BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR);
        +		goto end;
        +		}
        +
        +	if (addr == NULL) goto end;
        +
        +#ifdef EAI_FAMILY
        +	do {
        +	char   h[NI_MAXHOST],s[NI_MAXSERV];
        +	size_t nl;
        +	static union {	void *p;
        +			int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/,
        +				 char *,size_t,char *,size_t,int);
        +			} p_getnameinfo = {NULL};
        +			/* 2nd argument to getnameinfo is specified to
        +			 * be socklen_t. Unfortunately there is a number
        +			 * of environments where socklen_t is not defined.
        +			 * As it's passed by value, it's safe to pass it
        +			 * as size_t... <appro> */
        +
        +	if (p_getnameinfo.p==NULL)
        +		{
        +		if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL)
        +			p_getnameinfo.p=(void*)-1;
        +		}
        +	if (p_getnameinfo.p==(void *)-1) break;
        +
        +	if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s),
        +	    NI_NUMERICHOST|NI_NUMERICSERV)) break;
        +	nl = strlen(h)+strlen(s)+2;
        +	p = *addr;
        +	if (p)	{ *p = '\0'; p = OPENSSL_realloc(p,nl);	}
        +	else	{ p = OPENSSL_malloc(nl);		}
        +	if (p==NULL)
        +		{
        +		BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
        +		goto end;
        +		}
        +	*addr = p;
        +	BIO_snprintf(*addr,nl,"%s:%s",h,s);
        +	goto end;
        +	} while(0);
        +#endif
        +	if (sa.from.sa.sa_family != AF_INET) goto end;
        +	l=ntohl(sa.from.sa_in.sin_addr.s_addr);
        +	port=ntohs(sa.from.sa_in.sin_port);
        +	if (*addr == NULL)
        +		{
        +		if ((p=OPENSSL_malloc(24)) == NULL)
        +			{
        +			BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
        +			goto end;
        +			}
        +		*addr=p;
        +		}
        +	BIO_snprintf(*addr,24,"%d.%d.%d.%d:%d",
        +		     (unsigned char)(l>>24L)&0xff,
        +		     (unsigned char)(l>>16L)&0xff,
        +		     (unsigned char)(l>> 8L)&0xff,
        +		     (unsigned char)(l     )&0xff,
        +		     port);
        +end:
        +	return(ret);
        +	}
        +
        +int BIO_set_tcp_ndelay(int s, int on)
        +	{
        +	int ret=0;
        +#if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
        +	int opt;
        +
        +#ifdef SOL_TCP
        +	opt=SOL_TCP;
        +#else
        +#ifdef IPPROTO_TCP
        +	opt=IPPROTO_TCP;
        +#endif
        +#endif
        +	
        +	ret=setsockopt(s,opt,TCP_NODELAY,(char *)&on,sizeof(on));
        +#endif
        +	return(ret == 0);
        +	}
        +
        +int BIO_socket_nbio(int s, int mode)
        +	{
        +	int ret= -1;
        +	int l;
        +
        +	l=mode;
        +#ifdef FIONBIO
        +	ret=BIO_socket_ioctl(s,FIONBIO,&l);
        +#endif
        +	return(ret == 0);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/bf_buff.c b/vendor/openssl/openssl/crypto/bio/bf_buff.c
        new file mode 100644
        index 000000000..4b5a132d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bf_buff.c
        @@ -0,0 +1,512 @@
        +/* crypto/bio/bf_buff.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +static int buffer_write(BIO *h, const char *buf,int num);
        +static int buffer_read(BIO *h, char *buf, int size);
        +static int buffer_puts(BIO *h, const char *str);
        +static int buffer_gets(BIO *h, char *str, int size);
        +static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int buffer_new(BIO *h);
        +static int buffer_free(BIO *data);
        +static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
        +#define DEFAULT_BUFFER_SIZE	4096
        +
        +static BIO_METHOD methods_buffer=
        +	{
        +	BIO_TYPE_BUFFER,
        +	"buffer",
        +	buffer_write,
        +	buffer_read,
        +	buffer_puts,
        +	buffer_gets,
        +	buffer_ctrl,
        +	buffer_new,
        +	buffer_free,
        +	buffer_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_buffer(void)
        +	{
        +	return(&methods_buffer);
        +	}
        +
        +static int buffer_new(BIO *bi)
        +	{
        +	BIO_F_BUFFER_CTX *ctx;
        +
        +	ctx=(BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
        +	if (ctx == NULL) return(0);
        +	ctx->ibuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
        +	if (ctx->ibuf == NULL) { OPENSSL_free(ctx); return(0); }
        +	ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
        +	if (ctx->obuf == NULL) { OPENSSL_free(ctx->ibuf); OPENSSL_free(ctx); return(0); }
        +	ctx->ibuf_size=DEFAULT_BUFFER_SIZE;
        +	ctx->obuf_size=DEFAULT_BUFFER_SIZE;
        +	ctx->ibuf_len=0;
        +	ctx->ibuf_off=0;
        +	ctx->obuf_len=0;
        +	ctx->obuf_off=0;
        +
        +	bi->init=1;
        +	bi->ptr=(char *)ctx;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int buffer_free(BIO *a)
        +	{
        +	BIO_F_BUFFER_CTX *b;
        +
        +	if (a == NULL) return(0);
        +	b=(BIO_F_BUFFER_CTX *)a->ptr;
        +	if (b->ibuf != NULL) OPENSSL_free(b->ibuf);
        +	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 buffer_read(BIO *b, char *out, int outl)
        +	{
        +	int i,num=0;
        +	BIO_F_BUFFER_CTX *ctx;
        +
        +	if (out == NULL) return(0);
        +	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
        +	num=0;
        +	BIO_clear_retry_flags(b);
        +
        +start:
        +	i=ctx->ibuf_len;
        +	/* If there is stuff left over, grab it */
        +	if (i != 0)
        +		{
        +		if (i > outl) i=outl;
        +		memcpy(out,&(ctx->ibuf[ctx->ibuf_off]),i);
        +		ctx->ibuf_off+=i;
        +		ctx->ibuf_len-=i;
        +		num+=i;
        +		if (outl == i)  return(num);
        +		outl-=i;
        +		out+=i;
        +		}
        +
        +	/* We may have done a partial read. try to do more.
        +	 * We have nothing in the buffer.
        +	 * If we get an error and have read some data, just return it
        +	 * and let them retry to get the error again.
        +	 * copy direct to parent address space */
        +	if (outl > ctx->ibuf_size)
        +		{
        +		for (;;)
        +			{
        +			i=BIO_read(b->next_bio,out,outl);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				if (i < 0) return((num > 0)?num:i);
        +				if (i == 0) return(num);
        +				}
        +			num+=i;
        +			if (outl == i) return(num);
        +			out+=i;
        +			outl-=i;
        +			}
        +		}
        +	/* else */
        +
        +	/* we are going to be doing some buffering */
        +	i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
        +	if (i <= 0)
        +		{
        +		BIO_copy_next_retry(b);
        +		if (i < 0) return((num > 0)?num:i);
        +		if (i == 0) return(num);
        +		}
        +	ctx->ibuf_off=0;
        +	ctx->ibuf_len=i;
        +
        +	/* Lets re-read using ourselves :-) */
        +	goto start;
        +	}
        +
        +static int buffer_write(BIO *b, const char *in, int inl)
        +	{
        +	int i,num=0;
        +	BIO_F_BUFFER_CTX *ctx;
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
        +	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
        +
        +	BIO_clear_retry_flags(b);
        +start:
        +	i=ctx->obuf_size-(ctx->obuf_len+ctx->obuf_off);
        +	/* add to buffer and return */
        +	if (i >= inl)
        +		{
        +		memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl);
        +		ctx->obuf_len+=inl;
        +		return(num+inl);
        +		}
        +	/* else */
        +	/* stuff already in buffer, so add to it first, then flush */
        +	if (ctx->obuf_len != 0)
        +		{
        +		if (i > 0) /* lets fill it up if we can */
        +			{
        +			memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i);
        +			in+=i;
        +			inl-=i;
        +			num+=i;
        +			ctx->obuf_len+=i;
        +			}
        +		/* we now have a full buffer needing flushing */
        +		for (;;)
        +			{
        +			i=BIO_write(b->next_bio,&(ctx->obuf[ctx->obuf_off]),
        +				ctx->obuf_len);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +
        +				if (i < 0) return((num > 0)?num:i);
        +				if (i == 0) return(num);
        +				}
        +			ctx->obuf_off+=i;
        +			ctx->obuf_len-=i;
        +			if (ctx->obuf_len == 0) break;
        +			}
        +		}
        +	/* we only get here if the buffer has been flushed and we
        +	 * still have stuff to write */
        +	ctx->obuf_off=0;
        +
        +	/* we now have inl bytes to write */
        +	while (inl >= ctx->obuf_size)
        +		{
        +		i=BIO_write(b->next_bio,in,inl);
        +		if (i <= 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			if (i < 0) return((num > 0)?num:i);
        +			if (i == 0) return(num);
        +			}
        +		num+=i;
        +		in+=i;
        +		inl-=i;
        +		if (inl == 0) return(num);
        +		}
        +
        +	/* copy the rest into the buffer since we have only a small 
        +	 * amount left */
        +	goto start;
        +	}
        +
        +static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	BIO *dbio;
        +	BIO_F_BUFFER_CTX *ctx;
        +	long ret=1;
        +	char *p1,*p2;
        +	int r,i,*ip;
        +	int ibs,obs;
        +
        +	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ctx->ibuf_off=0;
        +		ctx->ibuf_len=0;
        +		ctx->obuf_off=0;
        +		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_C_GET_BUFF_NUM_LINES:
        +		ret=0;
        +		p1=ctx->ibuf;
        +		for (i=0; i<ctx->ibuf_len; i++)
        +			{
        +			if (p1[ctx->ibuf_off + i] == '\n') ret++;
        +			}
        +		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_CTRL_PENDING:
        +		ret=(long)ctx->ibuf_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_READ_DATA:
        +		if (num > ctx->ibuf_size)
        +			{
        +			p1=OPENSSL_malloc((int)num);
        +			if (p1 == NULL) goto malloc_error;
        +			if (ctx->ibuf != NULL) OPENSSL_free(ctx->ibuf);
        +			ctx->ibuf=p1;
        +			}
        +		ctx->ibuf_off=0;
        +		ctx->ibuf_len=(int)num;
        +		memcpy(ctx->ibuf,ptr,(int)num);
        +		ret=1;
        +		break;
        +	case BIO_C_SET_BUFF_SIZE:
        +		if (ptr != NULL)
        +			{
        +			ip=(int *)ptr;
        +			if (*ip == 0)
        +				{
        +				ibs=(int)num;
        +				obs=ctx->obuf_size;
        +				}
        +			else /* if (*ip == 1) */
        +				{
        +				ibs=ctx->ibuf_size;
        +				obs=(int)num;
        +				}
        +			}
        +		else
        +			{
        +			ibs=(int)num;
        +			obs=(int)num;
        +			}
        +		p1=ctx->ibuf;
        +		p2=ctx->obuf;
        +		if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size))
        +			{
        +			p1=(char *)OPENSSL_malloc((int)num);
        +			if (p1 == NULL) goto malloc_error;
        +			}
        +		if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size))
        +			{
        +			p2=(char *)OPENSSL_malloc((int)num);
        +			if (p2 == NULL)
        +				{
        +				if (p1 != ctx->ibuf) OPENSSL_free(p1);
        +				goto malloc_error;
        +				}
        +			}
        +		if (ctx->ibuf != p1)
        +			{
        +			OPENSSL_free(ctx->ibuf);
        +			ctx->ibuf=p1;
        +			ctx->ibuf_off=0;
        +			ctx->ibuf_len=0;
        +			ctx->ibuf_size=ibs;
        +			}
        +		if (ctx->obuf != p2)
        +			{
        +			OPENSSL_free(ctx->obuf);
        +			ctx->obuf=p2;
        +			ctx->obuf_off=0;
        +			ctx->obuf_len=0;
        +			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_off]),
        +					ctx->obuf_len);
        +#if 0
        +fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r);
        +#endif
        +				BIO_copy_next_retry(b);
        +				if (r <= 0) return((long)r);
        +				ctx->obuf_off+=r;
        +				ctx->obuf_len-=r;
        +				}
        +			else
        +				{
        +				ctx->obuf_len=0;
        +				ctx->obuf_off=0;
        +				ret=1;
        +				break;
        +				}
        +			}
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_DUP:
        +		dbio=(BIO *)ptr;
        +		if (	!BIO_set_read_buffer_size(dbio,ctx->ibuf_size) ||
        +			!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_BUFFER_CTRL,ERR_R_MALLOC_FAILURE);
        +	return(0);
        +	}
        +
        +static long buffer_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 buffer_gets(BIO *b, char *buf, int size)
        +	{
        +	BIO_F_BUFFER_CTX *ctx;
        +	int num=0,i,flag;
        +	char *p;
        +
        +	ctx=(BIO_F_BUFFER_CTX *)b->ptr;
        +	size--; /* reserve space for a '\0' */
        +	BIO_clear_retry_flags(b);
        +
        +	for (;;)
        +		{
        +		if (ctx->ibuf_len > 0)
        +			{
        +			p= &(ctx->ibuf[ctx->ibuf_off]);
        +			flag=0;
        +			for (i=0; (i<ctx->ibuf_len) && (i<size); i++)
        +				{
        +				*(buf++)=p[i];
        +				if (p[i] == '\n')
        +					{
        +					flag=1;
        +					i++;
        +					break;
        +					}
        +				}
        +			num+=i;
        +			size-=i;
        +			ctx->ibuf_len-=i;
        +			ctx->ibuf_off+=i;
        +			if (flag || size == 0)
        +				{
        +				*buf='\0';
        +				return(num);
        +				}
        +			}
        +		else	/* read another chunk */
        +			{
        +			i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				*buf='\0';
        +				if (i < 0) return((num > 0)?num:i);
        +				if (i == 0) return(num);
        +				}
        +			ctx->ibuf_len=i;
        +			ctx->ibuf_off=0;
        +			}
        +		}
        +	}
        +
        +static int buffer_puts(BIO *b, const char *str)
        +	{
        +	return(buffer_write(b,str,strlen(str)));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bf_lbuf.c b/vendor/openssl/openssl/crypto/bio/bf_lbuf.c
        new file mode 100644
        index 000000000..ec0f7eb0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bf_lbuf.c
        @@ -0,0 +1,397 @@
        +/* crypto/bio/bf_buff.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +
        +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;
        +					}
        +				}
        +
        +#if 0
        +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);
        +
        +#if 0
        +BIO_write(b->next_bio, ">*>", 3);
        +#endif
        +				if (i < 0) return((num > 0)?num:i);
        +				if (i == 0) return(num);
        +				}
        +#if 0
        +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)
        +			{
        +#if 0
        +BIO_write(b->next_bio, "<*<", 3);
        +#endif
        +			i=BIO_write(b->next_bio,in,p - in);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +#if 0
        +BIO_write(b->next_bio, ">*>", 3);
        +#endif
        +				if (i < 0) return((num > 0)?num:i);
        +				if (i == 0) return(num);
        +				}
        +#if 0
        +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/vendor/openssl/openssl/crypto/bio/bf_nbio.c b/vendor/openssl/openssl/crypto/bio/bf_nbio.c
        new file mode 100644
        index 000000000..028616c06
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bf_nbio.c
        @@ -0,0 +1,253 @@
        +/* crypto/bio/bf_nbio.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#include <openssl/bio.h>
        +
        +/* BIO_put and BIO_get both add to the digest,
        + * BIO_gets returns the digest */
        +
        +static int nbiof_write(BIO *h,const char *buf,int num);
        +static int nbiof_read(BIO *h,char *buf,int size);
        +static int nbiof_puts(BIO *h,const char *str);
        +static int nbiof_gets(BIO *h,char *str,int size);
        +static long nbiof_ctrl(BIO *h,int cmd,long arg1,void *arg2);
        +static int nbiof_new(BIO *h);
        +static int nbiof_free(BIO *data);
        +static long nbiof_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
        +typedef struct nbio_test_st
        +	{
        +	/* only set if we sent a 'should retry' error */
        +	int lrn;
        +	int lwn;
        +	} NBIO_TEST;
        +
        +static BIO_METHOD methods_nbiof=
        +	{
        +	BIO_TYPE_NBIO_TEST,
        +	"non-blocking IO test filter",
        +	nbiof_write,
        +	nbiof_read,
        +	nbiof_puts,
        +	nbiof_gets,
        +	nbiof_ctrl,
        +	nbiof_new,
        +	nbiof_free,
        +	nbiof_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_nbio_test(void)
        +	{
        +	return(&methods_nbiof);
        +	}
        +
        +static int nbiof_new(BIO *bi)
        +	{
        +	NBIO_TEST *nt;
        +
        +	if (!(nt=(NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) return(0);
        +	nt->lrn= -1;
        +	nt->lwn= -1;
        +	bi->ptr=(char *)nt;
        +	bi->init=1;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int nbiof_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	if (a->ptr != NULL)
        +		OPENSSL_free(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +	}
        +	
        +static int nbiof_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +#if 1
        +	int num;
        +	unsigned char n;
        +#endif
        +
        +	if (out == NULL) return(0);
        +	if (b->next_bio == NULL) return(0);
        +
        +	BIO_clear_retry_flags(b);
        +#if 1
        +	RAND_pseudo_bytes(&n,1);
        +	num=(n&0x07);
        +
        +	if (outl > num) outl=num;
        +
        +	if (num == 0)
        +		{
        +		ret= -1;
        +		BIO_set_retry_read(b);
        +		}
        +	else
        +#endif
        +		{
        +		ret=BIO_read(b->next_bio,out,outl);
        +		if (ret < 0)
        +			BIO_copy_next_retry(b);
        +		}
        +	return(ret);
        +	}
        +
        +static int nbiof_write(BIO *b, const char *in, int inl)
        +	{
        +	NBIO_TEST *nt;
        +	int ret=0;
        +	int num;
        +	unsigned char n;
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +	if (b->next_bio == NULL) return(0);
        +	nt=(NBIO_TEST *)b->ptr;
        +
        +	BIO_clear_retry_flags(b);
        +
        +#if 1
        +	if (nt->lwn > 0)
        +		{
        +		num=nt->lwn;
        +		nt->lwn=0;
        +		}
        +	else
        +		{
        +		RAND_pseudo_bytes(&n,1);
        +		num=(n&7);
        +		}
        +
        +	if (inl > num) inl=num;
        +
        +	if (num == 0)
        +		{
        +		ret= -1;
        +		BIO_set_retry_write(b);
        +		}
        +	else
        +#endif
        +		{
        +		ret=BIO_write(b->next_bio,in,inl);
        +		if (ret < 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			nt->lwn=inl;
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret;
        +
        +	if (b->next_bio == NULL) return(0);
        +	switch (cmd)
        +		{
        +        case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +	case BIO_CTRL_DUP:
        +		ret=0L;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long nbiof_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 nbiof_gets(BIO *bp, char *buf, int size)
        +	{
        +	if (bp->next_bio == NULL) return(0);
        +	return(BIO_gets(bp->next_bio,buf,size));
        +	}
        +
        +
        +static int nbiof_puts(BIO *bp, const char *str)
        +	{
        +	if (bp->next_bio == NULL) return(0);
        +	return(BIO_puts(bp->next_bio,str));
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bf_null.c b/vendor/openssl/openssl/crypto/bio/bf_null.c
        new file mode 100644
        index 000000000..c1bf39a90
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bf_null.c
        @@ -0,0 +1,183 @@
        +/* crypto/bio/bf_null.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +/* BIO_put and BIO_get both add to the digest,
        + * BIO_gets returns the digest */
        +
        +static int nullf_write(BIO *h, const char *buf, int num);
        +static int nullf_read(BIO *h, char *buf, int size);
        +static int nullf_puts(BIO *h, const char *str);
        +static int nullf_gets(BIO *h, char *str, int size);
        +static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int nullf_new(BIO *h);
        +static int nullf_free(BIO *data);
        +static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
        +static BIO_METHOD methods_nullf=
        +	{
        +	BIO_TYPE_NULL_FILTER,
        +	"NULL filter",
        +	nullf_write,
        +	nullf_read,
        +	nullf_puts,
        +	nullf_gets,
        +	nullf_ctrl,
        +	nullf_new,
        +	nullf_free,
        +	nullf_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_null(void)
        +	{
        +	return(&methods_nullf);
        +	}
        +
        +static int nullf_new(BIO *bi)
        +	{
        +	bi->init=1;
        +	bi->ptr=NULL;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int nullf_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +/*	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;*/
        +	return(1);
        +	}
        +	
        +static int nullf_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 nullf_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret=0;
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +	if (b->next_bio == NULL) return(0);
        +	ret=BIO_write(b->next_bio,in,inl);
        +	BIO_clear_retry_flags(b);
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret;
        +
        +	if (b->next_bio == NULL) return(0);
        +	switch(cmd)
        +		{
        +        case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +	case BIO_CTRL_DUP:
        +		ret=0L;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		}
        +	return(ret);
        +	}
        +
        +static long nullf_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 nullf_gets(BIO *bp, char *buf, int size)
        +	{
        +	if (bp->next_bio == NULL) return(0);
        +	return(BIO_gets(bp->next_bio,buf,size));
        +	}
        +
        +
        +static int nullf_puts(BIO *bp, const char *str)
        +	{
        +	if (bp->next_bio == NULL) return(0);
        +	return(BIO_puts(bp->next_bio,str));
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bio.h b/vendor/openssl/openssl/crypto/bio/bio.h
        new file mode 100644
        index 000000000..05699ab21
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bio.h
        @@ -0,0 +1,847 @@
        +/* crypto/bio/bio.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_BIO_H
        +#define HEADER_BIO_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +# include <stdio.h>
        +#endif
        +#include <stdarg.h>
        +
        +#include <openssl/crypto.h>
        +
        +#ifndef OPENSSL_NO_SCTP
        +# ifndef OPENSSL_SYS_VMS
        +# include <stdint.h>
        +# else
        +# include <inttypes.h>
        +# endif
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* These are the 'types' of BIOs */
        +#define BIO_TYPE_NONE		0
        +#define BIO_TYPE_MEM		(1|0x0400)
        +#define BIO_TYPE_FILE		(2|0x0400)
        +
        +#define BIO_TYPE_FD		(4|0x0400|0x0100)
        +#define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
        +#define BIO_TYPE_NULL		(6|0x0400)
        +#define BIO_TYPE_SSL		(7|0x0200)
        +#define BIO_TYPE_MD		(8|0x0200)		/* passive filter */
        +#define BIO_TYPE_BUFFER		(9|0x0200)		/* filter */
        +#define BIO_TYPE_CIPHER		(10|0x0200)		/* filter */
        +#define BIO_TYPE_BASE64		(11|0x0200)		/* filter */
        +#define BIO_TYPE_CONNECT	(12|0x0400|0x0100)	/* socket - connect */
        +#define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)	/* socket for accept */
        +#define BIO_TYPE_PROXY_CLIENT	(14|0x0200)		/* client proxy BIO */
        +#define BIO_TYPE_PROXY_SERVER	(15|0x0200)		/* server proxy BIO */
        +#define BIO_TYPE_NBIO_TEST	(16|0x0200)		/* server proxy BIO */
        +#define BIO_TYPE_NULL_FILTER	(17|0x0200)
        +#define BIO_TYPE_BER		(18|0x0200)		/* BER -> bin filter */
        +#define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
        +#define BIO_TYPE_LINEBUFFER	(20|0x0200)		/* filter */
        +#define BIO_TYPE_DGRAM		(21|0x0400|0x0100)
        +#ifndef OPENSSL_NO_SCTP
        +#define BIO_TYPE_DGRAM_SCTP	(24|0x0400|0x0100)
        +#endif
        +#define BIO_TYPE_ASN1 		(22|0x0200)		/* filter */
        +#define BIO_TYPE_COMP 		(23|0x0200)		/* filter */
        +
        +#define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
        +#define BIO_TYPE_FILTER		0x0200
        +#define BIO_TYPE_SOURCE_SINK	0x0400
        +
        +/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
        + * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
        +#define BIO_NOCLOSE		0x00
        +#define BIO_CLOSE		0x01
        +
        +/* These are used in the following macros and are passed to
        + * BIO_ctrl() */
        +#define BIO_CTRL_RESET		1  /* opt - rewind/zero etc */
        +#define BIO_CTRL_EOF		2  /* opt - are we at the eof */
        +#define BIO_CTRL_INFO		3  /* opt - extra tit-bits */
        +#define BIO_CTRL_SET		4  /* man - set the 'IO' type */
        +#define BIO_CTRL_GET		5  /* man - get the 'IO' type */
        +#define BIO_CTRL_PUSH		6  /* opt - internal, used to signify change */
        +#define BIO_CTRL_POP		7  /* opt - internal, used to signify change */
        +#define BIO_CTRL_GET_CLOSE	8  /* man - set the 'close' on free */
        +#define BIO_CTRL_SET_CLOSE	9  /* man - set the 'close' on free */
        +#define BIO_CTRL_PENDING	10  /* opt - is their more data buffered */
        +#define BIO_CTRL_FLUSH		11  /* opt - 'flush' buffered output */
        +#define BIO_CTRL_DUP		12  /* man - extra stuff for 'duped' BIO */
        +#define BIO_CTRL_WPENDING	13  /* opt - number of bytes still to write */
        +/* callback is int cb(BIO *bio,state,ret); */
        +#define BIO_CTRL_SET_CALLBACK	14  /* opt - set callback function */
        +#define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */
        +
        +#define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */
        +
        +/* dgram BIO stuff */
        +#define BIO_CTRL_DGRAM_CONNECT       31  /* BIO dgram special */
        +#define BIO_CTRL_DGRAM_SET_CONNECTED 32  /* allow for an externally
        +					  * connected socket to be
        +					  * passed in */ 
        +#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */
        +#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */
        +#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */
        +#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */
        +
        +#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */
        +#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */
        +					
        +/* #ifdef IP_MTU_DISCOVER */
        +#define BIO_CTRL_DGRAM_MTU_DISCOVER       39 /* set DF bit on egress packets */
        +/* #endif */
        +
        +#define BIO_CTRL_DGRAM_QUERY_MTU          40 /* as kernel for current MTU */
        +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU   47
        +#define BIO_CTRL_DGRAM_GET_MTU            41 /* get cached value for MTU */
        +#define BIO_CTRL_DGRAM_SET_MTU            42 /* set cached value for
        +					      * MTU. want to use this
        +					      * if asking the kernel
        +					      * fails */
        +
        +#define BIO_CTRL_DGRAM_MTU_EXCEEDED       43 /* check whether the MTU
        +					      * was exceed in the
        +					      * previous write
        +					      * operation */
        +
        +#define BIO_CTRL_DGRAM_GET_PEER           46
        +#define BIO_CTRL_DGRAM_SET_PEER           44 /* Destination for the data */
        +
        +#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45 /* Next DTLS handshake timeout to
        +                                              * adjust socket timeouts */
        +
        +#ifndef OPENSSL_NO_SCTP
        +/* SCTP stuff */
        +#define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE	50
        +#define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY		51
        +#define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY		52
        +#define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD		53
        +#define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO		60
        +#define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO		61
        +#define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO		62
        +#define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO		63
        +#define BIO_CTRL_DGRAM_SCTP_GET_PRINFO			64
        +#define BIO_CTRL_DGRAM_SCTP_SET_PRINFO			65
        +#define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN		70
        +#endif
        +
        +/* modifiers */
        +#define BIO_FP_READ		0x02
        +#define BIO_FP_WRITE		0x04
        +#define BIO_FP_APPEND		0x08
        +#define BIO_FP_TEXT		0x10
        +
        +#define BIO_FLAGS_READ		0x01
        +#define BIO_FLAGS_WRITE		0x02
        +#define BIO_FLAGS_IO_SPECIAL	0x04
        +#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
        +#define BIO_FLAGS_SHOULD_RETRY	0x08
        +#ifndef	BIO_FLAGS_UPLINK
        +/* "UPLINK" flag denotes file descriptors provided by application.
        +   It defaults to 0, as most platforms don't require UPLINK interface. */
        +#define	BIO_FLAGS_UPLINK	0
        +#endif
        +
        +/* Used in BIO_gethostbyname() */
        +#define BIO_GHBN_CTRL_HITS		1
        +#define BIO_GHBN_CTRL_MISSES		2
        +#define BIO_GHBN_CTRL_CACHE_SIZE	3
        +#define BIO_GHBN_CTRL_GET_ENTRY		4
        +#define BIO_GHBN_CTRL_FLUSH		5
        +
        +/* Mostly used in the SSL BIO */
        +/* Not used anymore
        + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
        + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
        + * #define BIO_FLAGS_PROTOCOL_STARTUP	0x40
        + */
        +
        +#define BIO_FLAGS_BASE64_NO_NL	0x100
        +
        +/* This is used with memory BIOs: it means we shouldn't free up or change the
        + * data in any way.
        + */
        +#define BIO_FLAGS_MEM_RDONLY	0x200
        +
        +typedef struct bio_st BIO;
        +
        +void BIO_set_flags(BIO *b, int flags);
        +int  BIO_test_flags(const BIO *b, int flags);
        +void BIO_clear_flags(BIO *b, int flags);
        +
        +#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
        +#define BIO_set_retry_special(b) \
        +		BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
        +#define BIO_set_retry_read(b) \
        +		BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
        +#define BIO_set_retry_write(b) \
        +		BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
        +
        +/* These are normally used internally in BIOs */
        +#define BIO_clear_retry_flags(b) \
        +		BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
        +#define BIO_get_retry_flags(b) \
        +		BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
        +
        +/* These should be used by the application to tell why we should retry */
        +#define BIO_should_read(a)		BIO_test_flags(a, BIO_FLAGS_READ)
        +#define BIO_should_write(a)		BIO_test_flags(a, BIO_FLAGS_WRITE)
        +#define BIO_should_io_special(a)	BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
        +#define BIO_retry_type(a)		BIO_test_flags(a, BIO_FLAGS_RWS)
        +#define BIO_should_retry(a)		BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
        +
        +/* The next three are used in conjunction with the
        + * BIO_should_io_special() condition.  After this returns true,
        + * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 
        + * stack and return the 'reason' for the special and the offending BIO.
        + * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
        +/* Returned from the SSL bio when the certificate retrieval code had an error */
        +#define BIO_RR_SSL_X509_LOOKUP		0x01
        +/* Returned from the connect BIO when a connect would have blocked */
        +#define BIO_RR_CONNECT			0x02
        +/* Returned from the accept BIO when an accept would have blocked */
        +#define BIO_RR_ACCEPT			0x03
        +
        +/* These are passed by the BIO callback */
        +#define BIO_CB_FREE	0x01
        +#define BIO_CB_READ	0x02
        +#define BIO_CB_WRITE	0x03
        +#define BIO_CB_PUTS	0x04
        +#define BIO_CB_GETS	0x05
        +#define BIO_CB_CTRL	0x06
        +
        +/* The callback is called before and after the underling operation,
        + * The BIO_CB_RETURN flag indicates if it is after the call */
        +#define BIO_CB_RETURN	0x80
        +#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
        +#define BIO_cb_pre(a)	(!((a)&BIO_CB_RETURN))
        +#define BIO_cb_post(a)	((a)&BIO_CB_RETURN)
        +
        +long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long);
        +void BIO_set_callback(BIO *b, 
        +	long (*callback)(struct bio_st *,int,const char *,int, long,long));
        +char *BIO_get_callback_arg(const BIO *b);
        +void BIO_set_callback_arg(BIO *b, char *arg);
        +
        +const char * BIO_method_name(const BIO *b);
        +int BIO_method_type(const BIO *b);
        +
        +typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
        +
        +typedef struct bio_method_st
        +	{
        +	int type;
        +	const char *name;
        +	int (*bwrite)(BIO *, const char *, int);
        +	int (*bread)(BIO *, char *, int);
        +	int (*bputs)(BIO *, const char *);
        +	int (*bgets)(BIO *, char *, int);
        +	long (*ctrl)(BIO *, int, long, void *);
        +	int (*create)(BIO *);
        +	int (*destroy)(BIO *);
        +        long (*callback_ctrl)(BIO *, int, bio_info_cb *);
        +	} BIO_METHOD;
        +
        +struct bio_st
        +	{
        +	BIO_METHOD *method;
        +	/* bio, mode, argp, argi, argl, ret */
        +	long (*callback)(struct bio_st *,int,const char *,int, long,long);
        +	char *cb_arg; /* first argument for the callback */
        +
        +	int init;
        +	int shutdown;
        +	int flags;	/* extra storage */
        +	int retry_reason;
        +	int num;
        +	void *ptr;
        +	struct bio_st *next_bio;	/* used by filter BIOs */
        +	struct bio_st *prev_bio;	/* used by filter BIOs */
        +	int references;
        +	unsigned long num_read;
        +	unsigned long num_write;
        +
        +	CRYPTO_EX_DATA ex_data;
        +	};
        +
        +DECLARE_STACK_OF(BIO)
        +
        +typedef struct bio_f_buffer_ctx_struct
        +	{
        +	/* Buffers are setup like this:
        +	 *
        +	 * <---------------------- size ----------------------->
        +	 * +---------------------------------------------------+
        +	 * | consumed | remaining          | free space        |
        +	 * +---------------------------------------------------+
        +	 * <-- off --><------- len ------->
        +	 */
        +
        +	/* BIO *bio; */ /* this is now in the BIO struct */
        +	int ibuf_size;	/* how big is the input buffer */
        +	int obuf_size;	/* how big is the output buffer */
        +
        +	char *ibuf;		/* the char array */
        +	int ibuf_len;		/* how many bytes are in it */
        +	int ibuf_off;		/* write/read offset */
        +
        +	char *obuf;		/* the char array */
        +	int obuf_len;		/* how many bytes are in it */
        +	int obuf_off;		/* write/read offset */
        +	} BIO_F_BUFFER_CTX;
        +
        +/* Prefix and suffix callback in ASN1 BIO */
        +typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
        +
        +#ifndef OPENSSL_NO_SCTP
        +/* SCTP parameter structs */
        +struct bio_dgram_sctp_sndinfo
        +	{
        +	uint16_t snd_sid;
        +	uint16_t snd_flags;
        +	uint32_t snd_ppid;
        +	uint32_t snd_context;
        +	};
        +
        +struct bio_dgram_sctp_rcvinfo
        +	{
        +	uint16_t rcv_sid;
        +	uint16_t rcv_ssn;
        +	uint16_t rcv_flags;
        +	uint32_t rcv_ppid;
        +	uint32_t rcv_tsn;
        +	uint32_t rcv_cumtsn;
        +	uint32_t rcv_context;
        +	};
        +
        +struct bio_dgram_sctp_prinfo
        +	{
        +	uint16_t pr_policy;
        +	uint32_t pr_value;
        +	};
        +#endif
        +
        +/* connect BIO stuff */
        +#define BIO_CONN_S_BEFORE		1
        +#define BIO_CONN_S_GET_IP		2
        +#define BIO_CONN_S_GET_PORT		3
        +#define BIO_CONN_S_CREATE_SOCKET	4
        +#define BIO_CONN_S_CONNECT		5
        +#define BIO_CONN_S_OK			6
        +#define BIO_CONN_S_BLOCKED_CONNECT	7
        +#define BIO_CONN_S_NBIO			8
        +/*#define BIO_CONN_get_param_hostname	BIO_ctrl */
        +
        +#define BIO_C_SET_CONNECT			100
        +#define BIO_C_DO_STATE_MACHINE			101
        +#define BIO_C_SET_NBIO				102
        +#define BIO_C_SET_PROXY_PARAM			103
        +#define BIO_C_SET_FD				104
        +#define BIO_C_GET_FD				105
        +#define BIO_C_SET_FILE_PTR			106
        +#define BIO_C_GET_FILE_PTR			107
        +#define BIO_C_SET_FILENAME			108
        +#define BIO_C_SET_SSL				109
        +#define BIO_C_GET_SSL				110
        +#define BIO_C_SET_MD				111
        +#define BIO_C_GET_MD				112
        +#define BIO_C_GET_CIPHER_STATUS			113
        +#define BIO_C_SET_BUF_MEM			114
        +#define BIO_C_GET_BUF_MEM_PTR			115
        +#define BIO_C_GET_BUFF_NUM_LINES		116
        +#define BIO_C_SET_BUFF_SIZE			117
        +#define BIO_C_SET_ACCEPT			118
        +#define BIO_C_SSL_MODE				119
        +#define BIO_C_GET_MD_CTX			120
        +#define BIO_C_GET_PROXY_PARAM			121
        +#define BIO_C_SET_BUFF_READ_DATA		122 /* data to read first */
        +#define BIO_C_GET_CONNECT			123
        +#define BIO_C_GET_ACCEPT			124
        +#define BIO_C_SET_SSL_RENEGOTIATE_BYTES		125
        +#define BIO_C_GET_SSL_NUM_RENEGOTIATES		126
        +#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT	127
        +#define BIO_C_FILE_SEEK				128
        +#define BIO_C_GET_CIPHER_CTX			129
        +#define BIO_C_SET_BUF_MEM_EOF_RETURN		130/*return end of input value*/
        +#define BIO_C_SET_BIND_MODE			131
        +#define BIO_C_GET_BIND_MODE			132
        +#define BIO_C_FILE_TELL				133
        +#define BIO_C_GET_SOCKS				134
        +#define BIO_C_SET_SOCKS				135
        +
        +#define BIO_C_SET_WRITE_BUF_SIZE		136/* for BIO_s_bio */
        +#define BIO_C_GET_WRITE_BUF_SIZE		137
        +#define BIO_C_MAKE_BIO_PAIR			138
        +#define BIO_C_DESTROY_BIO_PAIR			139
        +#define BIO_C_GET_WRITE_GUARANTEE		140
        +#define BIO_C_GET_READ_REQUEST			141
        +#define BIO_C_SHUTDOWN_WR			142
        +#define BIO_C_NREAD0				143
        +#define BIO_C_NREAD				144
        +#define BIO_C_NWRITE0				145
        +#define BIO_C_NWRITE				146
        +#define BIO_C_RESET_READ_REQUEST		147
        +#define BIO_C_SET_MD_CTX			148
        +
        +#define BIO_C_SET_PREFIX			149
        +#define BIO_C_GET_PREFIX			150
        +#define BIO_C_SET_SUFFIX			151
        +#define BIO_C_GET_SUFFIX			152
        +
        +#define BIO_C_SET_EX_ARG			153
        +#define BIO_C_GET_EX_ARG			154
        +
        +#define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
        +#define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
        +
        +/* BIO_s_connect() and BIO_s_socks4a_connect() */
        +#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
        +#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
        +#define BIO_set_conn_ip(b,ip)	  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
        +#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
        +#define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
        +#define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
        +#define BIO_get_conn_ip(b) 		 BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
        +#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0)
        +
        +
        +#define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
        +
        +/* BIO_s_accept_socket() */
        +#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
        +#define BIO_get_accept_port(b)	BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
        +/* #define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
        +#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
        +#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
        +
        +#define BIO_BIND_NORMAL			0
        +#define BIO_BIND_REUSEADDR_IF_UNUSED	1
        +#define BIO_BIND_REUSEADDR		2
        +#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
        +#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
        +
        +#define BIO_do_connect(b)	BIO_do_handshake(b)
        +#define BIO_do_accept(b)	BIO_do_handshake(b)
        +#define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
        +
        +/* BIO_s_proxy_client() */
        +#define BIO_set_url(b,url)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
        +#define BIO_set_proxies(b,p)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
        +/* BIO_set_nbio(b,n) */
        +#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
        +/* BIO *BIO_get_filter_bio(BIO *bio); */
        +#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
        +#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
        +#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
        +
        +#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
        +#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
        +#define BIO_get_url(b,url)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
        +#define BIO_get_no_connect_return(b)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
        +
        +#define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
        +#define BIO_get_fd(b,c)		BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
        +
        +#define BIO_set_fp(b,fp,c)	BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
        +#define BIO_get_fp(b,fpp)	BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
        +
        +#define BIO_seek(b,ofs)	(int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
        +#define BIO_tell(b)	(int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
        +
        +/* name is cast to lose const, but might be better to route through a function
        +   so we can do it safely */
        +#ifdef CONST_STRICT
        +/* If you are wondering why this isn't defined, its because CONST_STRICT is
        + * purely a compile-time kludge to allow const to be checked.
        + */
        +int BIO_read_filename(BIO *b,const char *name);
        +#else
        +#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
        +		BIO_CLOSE|BIO_FP_READ,(char *)name)
        +#endif
        +#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
        +		BIO_CLOSE|BIO_FP_WRITE,name)
        +#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
        +		BIO_CLOSE|BIO_FP_APPEND,name)
        +#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
        +		BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
        +
        +/* WARNING WARNING, this ups the reference count on the read bio of the
        + * SSL structure.  This is because the ssl read BIO is now pointed to by
        + * the next_bio field in the bio.  So when you free the BIO, make sure
        + * you are doing a BIO_free_all() to catch the underlying BIO. */
        +#define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
        +#define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
        +#define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
        +#define BIO_set_ssl_renegotiate_bytes(b,num) \
        +	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
        +#define BIO_get_num_renegotiates(b) \
        +	BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
        +#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
        +	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
        +
        +/* defined in evp.h */
        +/* #define BIO_set_md(b,md)	BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
        +
        +#define BIO_get_mem_data(b,pp)	BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
        +#define BIO_set_mem_buf(b,bm,c)	BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
        +#define BIO_get_mem_ptr(b,pp)	BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
        +#define BIO_set_mem_eof_return(b,v) \
        +				BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
        +
        +/* For the BIO_f_buffer() type */
        +#define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
        +#define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
        +#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
        +#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
        +#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
        +
        +/* Don't use the next one unless you know what you are doing :-) */
        +#define BIO_dup_state(b,ret)	BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
        +
        +#define BIO_reset(b)		(int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
        +#define BIO_eof(b)		(int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
        +#define BIO_set_close(b,c)	(int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
        +#define BIO_get_close(b)	(int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
        +#define BIO_pending(b)		(int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
        +#define BIO_wpending(b)		(int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
        +/* ...pending macros have inappropriate return type */
        +size_t BIO_ctrl_pending(BIO *b);
        +size_t BIO_ctrl_wpending(BIO *b);
        +#define BIO_flush(b)		(int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
        +#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
        +						   cbp)
        +#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
        +
        +/* For the BIO_f_buffer() type */
        +#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
        +
        +/* For BIO_s_bio() */
        +#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)
        +#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)
        +/* macros with inappropriate type -- but ...pending macros use int too: */
        +#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
        +#define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
        +size_t BIO_ctrl_get_write_guarantee(BIO *b);
        +size_t BIO_ctrl_get_read_request(BIO *b);
        +int BIO_ctrl_reset_read_request(BIO *b);
        +
        +/* ctrl macros for dgram */
        +#define BIO_ctrl_dgram_connect(b,peer)  \
        +                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
        +#define BIO_ctrl_set_connected(b, state, peer) \
        +         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
        +#define BIO_dgram_recv_timedout(b) \
        +         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
        +#define BIO_dgram_send_timedout(b) \
        +         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
        +#define BIO_dgram_get_peer(b,peer) \
        +         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
        +#define BIO_dgram_set_peer(b,peer) \
        +         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
        +
        +/* These two aren't currently implemented */
        +/* int BIO_get_ex_num(BIO *bio); */
        +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
        +int BIO_set_ex_data(BIO *bio,int idx,void *data);
        +void *BIO_get_ex_data(BIO *bio,int idx);
        +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +unsigned long BIO_number_read(BIO *bio);
        +unsigned long BIO_number_written(BIO *bio);
        +
        +/* For BIO_f_asn1() */
        +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
        +					asn1_ps_func *prefix_free);
        +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
        +					asn1_ps_func **pprefix_free);
        +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
        +					asn1_ps_func *suffix_free);
        +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
        +					asn1_ps_func **psuffix_free);
        +
        +# ifndef OPENSSL_NO_FP_API
        +BIO_METHOD *BIO_s_file(void );
        +BIO *BIO_new_file(const char *filename, const char *mode);
        +BIO *BIO_new_fp(FILE *stream, int close_flag);
        +# define BIO_s_file_internal	BIO_s_file
        +# endif
        +BIO *	BIO_new(BIO_METHOD *type);
        +int	BIO_set(BIO *a,BIO_METHOD *type);
        +int	BIO_free(BIO *a);
        +void	BIO_vfree(BIO *a);
        +int	BIO_read(BIO *b, void *data, int len);
        +int	BIO_gets(BIO *bp,char *buf, int size);
        +int	BIO_write(BIO *b, const void *data, int len);
        +int	BIO_puts(BIO *bp,const char *buf);
        +int	BIO_indent(BIO *b,int indent,int max);
        +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);
        +BIO *	BIO_push(BIO *b,BIO *append);
        +BIO *	BIO_pop(BIO *b);
        +void	BIO_free_all(BIO *a);
        +BIO *	BIO_find_type(BIO *b,int bio_type);
        +BIO *	BIO_next(BIO *b);
        +BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
        +int	BIO_get_retry_reason(BIO *bio);
        +BIO *	BIO_dup_chain(BIO *in);
        +
        +int BIO_nread0(BIO *bio, char **buf);
        +int BIO_nread(BIO *bio, char **buf, int num);
        +int BIO_nwrite0(BIO *bio, char **buf);
        +int BIO_nwrite(BIO *bio, char **buf, int num);
        +
        +long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
        +	long argl,long ret);
        +
        +BIO_METHOD *BIO_s_mem(void);
        +BIO *BIO_new_mem_buf(void *buf, int len);
        +BIO_METHOD *BIO_s_socket(void);
        +BIO_METHOD *BIO_s_connect(void);
        +BIO_METHOD *BIO_s_accept(void);
        +BIO_METHOD *BIO_s_fd(void);
        +#ifndef OPENSSL_SYS_OS2
        +BIO_METHOD *BIO_s_log(void);
        +#endif
        +BIO_METHOD *BIO_s_bio(void);
        +BIO_METHOD *BIO_s_null(void);
        +BIO_METHOD *BIO_f_null(void);
        +BIO_METHOD *BIO_f_buffer(void);
        +#ifdef OPENSSL_SYS_VMS
        +BIO_METHOD *BIO_f_linebuffer(void);
        +#endif
        +BIO_METHOD *BIO_f_nbio_test(void);
        +#ifndef OPENSSL_NO_DGRAM
        +BIO_METHOD *BIO_s_datagram(void);
        +#ifndef OPENSSL_NO_SCTP
        +BIO_METHOD *BIO_s_datagram_sctp(void);
        +#endif
        +#endif
        +
        +/* BIO_METHOD *BIO_f_ber(void); */
        +
        +int BIO_sock_should_retry(int i);
        +int BIO_sock_non_fatal_error(int error);
        +int BIO_dgram_non_fatal_error(int error);
        +
        +int BIO_fd_should_retry(int i);
        +int BIO_fd_non_fatal_error(int error);
        +int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
        +		void *u, const char *s, int len);
        +int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
        +		       void *u, const char *s, int len, int indent);
        +int BIO_dump(BIO *b,const char *bytes,int len);
        +int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent);
        +#ifndef OPENSSL_NO_FP_API
        +int BIO_dump_fp(FILE *fp, const char *s, int len);
        +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
        +#endif
        +struct hostent *BIO_gethostbyname(const char *name);
        +/* We might want a thread-safe interface too:
        + * struct hostent *BIO_gethostbyname_r(const char *name,
        + *     struct hostent *result, void *buffer, size_t buflen);
        + * or something similar (caller allocates a struct hostent,
        + * pointed to by "result", and additional buffer space for the various
        + * substructures; if the buffer does not suffice, NULL is returned
        + * and an appropriate error code is set).
        + */
        +int BIO_sock_error(int sock);
        +int BIO_socket_ioctl(int fd, long type, void *arg);
        +int BIO_socket_nbio(int fd,int mode);
        +int BIO_get_port(const char *str, unsigned short *port_ptr);
        +int BIO_get_host_ip(const char *str, unsigned char *ip);
        +int BIO_get_accept_socket(char *host_port,int mode);
        +int BIO_accept(int sock,char **ip_port);
        +int BIO_sock_init(void );
        +void BIO_sock_cleanup(void);
        +int BIO_set_tcp_ndelay(int sock,int turn_on);
        +
        +BIO *BIO_new_socket(int sock, int close_flag);
        +BIO *BIO_new_dgram(int fd, int close_flag);
        +#ifndef OPENSSL_NO_SCTP
        +BIO *BIO_new_dgram_sctp(int fd, int close_flag);
        +int BIO_dgram_is_sctp(BIO *bio);
        +int BIO_dgram_sctp_notification_cb(BIO *b,
        +                                   void (*handle_notifications)(BIO *bio, void *context, void *buf),
        +                                   void *context);
        +int BIO_dgram_sctp_wait_for_dry(BIO *b);
        +int BIO_dgram_sctp_msg_waiting(BIO *b);
        +#endif
        +BIO *BIO_new_fd(int fd, int close_flag);
        +BIO *BIO_new_connect(char *host_port);
        +BIO *BIO_new_accept(char *host_port);
        +
        +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
        +	BIO **bio2, size_t writebuf2);
        +/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
        + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
        + * Size 0 uses default value.
        + */
        +
        +void BIO_copy_next_retry(BIO *b);
        +
        +/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/
        +
        +#ifdef __GNUC__
        +#  define __bio_h__attr__ __attribute__
        +#else
        +#  define __bio_h__attr__(x)
        +#endif
        +int BIO_printf(BIO *bio, const char *format, ...)
        +	__bio_h__attr__((__format__(__printf__,2,3)));
        +int BIO_vprintf(BIO *bio, const char *format, va_list args)
        +	__bio_h__attr__((__format__(__printf__,2,0)));
        +int BIO_snprintf(char *buf, size_t n, const char *format, ...)
        +	__bio_h__attr__((__format__(__printf__,3,4)));
        +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
        +	__bio_h__attr__((__format__(__printf__,3,0)));
        +#undef __bio_h__attr__
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_BIO_strings(void);
        +
        +/* Error codes for the BIO functions. */
        +
        +/* Function codes. */
        +#define BIO_F_ACPT_STATE				 100
        +#define BIO_F_BIO_ACCEPT				 101
        +#define BIO_F_BIO_BER_GET_HEADER			 102
        +#define BIO_F_BIO_CALLBACK_CTRL				 131
        +#define BIO_F_BIO_CTRL					 103
        +#define BIO_F_BIO_GETHOSTBYNAME				 120
        +#define BIO_F_BIO_GETS					 104
        +#define BIO_F_BIO_GET_ACCEPT_SOCKET			 105
        +#define BIO_F_BIO_GET_HOST_IP				 106
        +#define BIO_F_BIO_GET_PORT				 107
        +#define BIO_F_BIO_MAKE_PAIR				 121
        +#define BIO_F_BIO_NEW					 108
        +#define BIO_F_BIO_NEW_FILE				 109
        +#define BIO_F_BIO_NEW_MEM_BUF				 126
        +#define BIO_F_BIO_NREAD					 123
        +#define BIO_F_BIO_NREAD0				 124
        +#define BIO_F_BIO_NWRITE				 125
        +#define BIO_F_BIO_NWRITE0				 122
        +#define BIO_F_BIO_PUTS					 110
        +#define BIO_F_BIO_READ					 111
        +#define BIO_F_BIO_SOCK_INIT				 112
        +#define BIO_F_BIO_WRITE					 113
        +#define BIO_F_BUFFER_CTRL				 114
        +#define BIO_F_CONN_CTRL					 127
        +#define BIO_F_CONN_STATE				 115
        +#define BIO_F_DGRAM_SCTP_READ				 132
        +#define BIO_F_FILE_CTRL					 116
        +#define BIO_F_FILE_READ					 130
        +#define BIO_F_LINEBUFFER_CTRL				 129
        +#define BIO_F_MEM_READ					 128
        +#define BIO_F_MEM_WRITE					 117
        +#define BIO_F_SSL_NEW					 118
        +#define BIO_F_WSASTARTUP				 119
        +
        +/* Reason codes. */
        +#define BIO_R_ACCEPT_ERROR				 100
        +#define BIO_R_BAD_FOPEN_MODE				 101
        +#define BIO_R_BAD_HOSTNAME_LOOKUP			 102
        +#define BIO_R_BROKEN_PIPE				 124
        +#define BIO_R_CONNECT_ERROR				 103
        +#define BIO_R_EOF_ON_MEMORY_BIO				 127
        +#define BIO_R_ERROR_SETTING_NBIO			 104
        +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET	 105
        +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET	 106
        +#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET		 107
        +#define BIO_R_INVALID_ARGUMENT				 125
        +#define BIO_R_INVALID_IP_ADDRESS			 108
        +#define BIO_R_IN_USE					 123
        +#define BIO_R_KEEPALIVE					 109
        +#define BIO_R_NBIO_CONNECT_ERROR			 110
        +#define BIO_R_NO_ACCEPT_PORT_SPECIFIED			 111
        +#define BIO_R_NO_HOSTNAME_SPECIFIED			 112
        +#define BIO_R_NO_PORT_DEFINED				 113
        +#define BIO_R_NO_PORT_SPECIFIED				 114
        +#define BIO_R_NO_SUCH_FILE				 128
        +#define BIO_R_NULL_PARAMETER				 115
        +#define BIO_R_TAG_MISMATCH				 116
        +#define BIO_R_UNABLE_TO_BIND_SOCKET			 117
        +#define BIO_R_UNABLE_TO_CREATE_SOCKET			 118
        +#define BIO_R_UNABLE_TO_LISTEN_SOCKET			 119
        +#define BIO_R_UNINITIALIZED				 120
        +#define BIO_R_UNSUPPORTED_METHOD			 121
        +#define BIO_R_WRITE_TO_READ_ONLY_BIO			 126
        +#define BIO_R_WSASTARTUP				 122
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/bio_cb.c b/vendor/openssl/openssl/crypto/bio/bio_cb.c
        new file mode 100644
        index 000000000..9bcbc321d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bio_cb.c
        @@ -0,0 +1,143 @@
        +/* crypto/bio/bio_cb.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +
        +long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp,
        +	     int argi, long argl, long ret)
        +	{
        +	BIO *b;
        +	MS_STATIC char buf[256];
        +	char *p;
        +	long r=1;
        +	size_t p_maxlen;
        +
        +	if (BIO_CB_RETURN & cmd)
        +		r=ret;
        +
        +	BIO_snprintf(buf,sizeof buf,"BIO[%08lX]:",(unsigned long)bio);
        +	p= &(buf[14]);
        +	p_maxlen = sizeof buf - 14;
        +	switch (cmd)
        +		{
        +	case BIO_CB_FREE:
        +		BIO_snprintf(p,p_maxlen,"Free - %s\n",bio->method->name);
        +		break;
        +	case BIO_CB_READ:
        +		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
        +			BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s fd=%d\n",
        +				 bio->num,(unsigned long)argi,
        +				 bio->method->name,bio->num);
        +		else
        +			BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s\n",
        +				 bio->num,(unsigned long)argi,
        +				 bio->method->name);
        +		break;
        +	case BIO_CB_WRITE:
        +		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
        +			BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s fd=%d\n",
        +				 bio->num,(unsigned long)argi,
        +				 bio->method->name,bio->num);
        +		else
        +			BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s\n",
        +				 bio->num,(unsigned long)argi,
        +				 bio->method->name);
        +		break;
        +	case BIO_CB_PUTS:
        +		BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name);
        +		break;
        +	case BIO_CB_GETS:
        +		BIO_snprintf(p,p_maxlen,"gets(%lu) - %s\n",(unsigned long)argi,bio->method->name);
        +		break;
        +	case BIO_CB_CTRL:
        +		BIO_snprintf(p,p_maxlen,"ctrl(%lu) - %s\n",(unsigned long)argi,bio->method->name);
        +		break;
        +	case BIO_CB_RETURN|BIO_CB_READ:
        +		BIO_snprintf(p,p_maxlen,"read return %ld\n",ret);
        +		break;
        +	case BIO_CB_RETURN|BIO_CB_WRITE:
        +		BIO_snprintf(p,p_maxlen,"write return %ld\n",ret);
        +		break;
        +	case BIO_CB_RETURN|BIO_CB_GETS:
        +		BIO_snprintf(p,p_maxlen,"gets return %ld\n",ret);
        +		break;
        +	case BIO_CB_RETURN|BIO_CB_PUTS:
        +		BIO_snprintf(p,p_maxlen,"puts return %ld\n",ret);
        +		break;
        +	case BIO_CB_RETURN|BIO_CB_CTRL:
        +		BIO_snprintf(p,p_maxlen,"ctrl return %ld\n",ret);
        +		break;
        +	default:
        +		BIO_snprintf(p,p_maxlen,"bio callback - unknown type (%d)\n",cmd);
        +		break;
        +		}
        +
        +	b=(BIO *)bio->cb_arg;
        +	if (b != NULL)
        +		BIO_write(b,buf,strlen(buf));
        +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
        +	else
        +		fputs(buf,stderr);
        +#endif
        +	return(r);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bio/bio_err.c b/vendor/openssl/openssl/crypto/bio/bio_err.c
        new file mode 100644
        index 000000000..0dbfbd80d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bio_err.c
        @@ -0,0 +1,155 @@
        +/* crypto/bio/bio_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/bio.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
        +
        +static ERR_STRING_DATA BIO_str_functs[]=
        +	{
        +{ERR_FUNC(BIO_F_ACPT_STATE),	"ACPT_STATE"},
        +{ERR_FUNC(BIO_F_BIO_ACCEPT),	"BIO_accept"},
        +{ERR_FUNC(BIO_F_BIO_BER_GET_HEADER),	"BIO_BER_GET_HEADER"},
        +{ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL),	"BIO_callback_ctrl"},
        +{ERR_FUNC(BIO_F_BIO_CTRL),	"BIO_ctrl"},
        +{ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME),	"BIO_gethostbyname"},
        +{ERR_FUNC(BIO_F_BIO_GETS),	"BIO_gets"},
        +{ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET),	"BIO_get_accept_socket"},
        +{ERR_FUNC(BIO_F_BIO_GET_HOST_IP),	"BIO_get_host_ip"},
        +{ERR_FUNC(BIO_F_BIO_GET_PORT),	"BIO_get_port"},
        +{ERR_FUNC(BIO_F_BIO_MAKE_PAIR),	"BIO_MAKE_PAIR"},
        +{ERR_FUNC(BIO_F_BIO_NEW),	"BIO_new"},
        +{ERR_FUNC(BIO_F_BIO_NEW_FILE),	"BIO_new_file"},
        +{ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF),	"BIO_new_mem_buf"},
        +{ERR_FUNC(BIO_F_BIO_NREAD),	"BIO_nread"},
        +{ERR_FUNC(BIO_F_BIO_NREAD0),	"BIO_nread0"},
        +{ERR_FUNC(BIO_F_BIO_NWRITE),	"BIO_nwrite"},
        +{ERR_FUNC(BIO_F_BIO_NWRITE0),	"BIO_nwrite0"},
        +{ERR_FUNC(BIO_F_BIO_PUTS),	"BIO_puts"},
        +{ERR_FUNC(BIO_F_BIO_READ),	"BIO_read"},
        +{ERR_FUNC(BIO_F_BIO_SOCK_INIT),	"BIO_sock_init"},
        +{ERR_FUNC(BIO_F_BIO_WRITE),	"BIO_write"},
        +{ERR_FUNC(BIO_F_BUFFER_CTRL),	"BUFFER_CTRL"},
        +{ERR_FUNC(BIO_F_CONN_CTRL),	"CONN_CTRL"},
        +{ERR_FUNC(BIO_F_CONN_STATE),	"CONN_STATE"},
        +{ERR_FUNC(BIO_F_DGRAM_SCTP_READ),	"DGRAM_SCTP_READ"},
        +{ERR_FUNC(BIO_F_FILE_CTRL),	"FILE_CTRL"},
        +{ERR_FUNC(BIO_F_FILE_READ),	"FILE_READ"},
        +{ERR_FUNC(BIO_F_LINEBUFFER_CTRL),	"LINEBUFFER_CTRL"},
        +{ERR_FUNC(BIO_F_MEM_READ),	"MEM_READ"},
        +{ERR_FUNC(BIO_F_MEM_WRITE),	"MEM_WRITE"},
        +{ERR_FUNC(BIO_F_SSL_NEW),	"SSL_new"},
        +{ERR_FUNC(BIO_F_WSASTARTUP),	"WSASTARTUP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA BIO_str_reasons[]=
        +	{
        +{ERR_REASON(BIO_R_ACCEPT_ERROR)          ,"accept error"},
        +{ERR_REASON(BIO_R_BAD_FOPEN_MODE)        ,"bad fopen mode"},
        +{ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP)   ,"bad hostname lookup"},
        +{ERR_REASON(BIO_R_BROKEN_PIPE)           ,"broken pipe"},
        +{ERR_REASON(BIO_R_CONNECT_ERROR)         ,"connect error"},
        +{ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO)     ,"EOF on memory BIO"},
        +{ERR_REASON(BIO_R_ERROR_SETTING_NBIO)    ,"error setting nbio"},
        +{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET),"error setting nbio on accepted socket"},
        +{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET),"error setting nbio on accept socket"},
        +{ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),"gethostbyname addr is not af inet"},
        +{ERR_REASON(BIO_R_INVALID_ARGUMENT)      ,"invalid argument"},
        +{ERR_REASON(BIO_R_INVALID_IP_ADDRESS)    ,"invalid ip address"},
        +{ERR_REASON(BIO_R_IN_USE)                ,"in use"},
        +{ERR_REASON(BIO_R_KEEPALIVE)             ,"keepalive"},
        +{ERR_REASON(BIO_R_NBIO_CONNECT_ERROR)    ,"nbio connect error"},
        +{ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED),"no accept port specified"},
        +{ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED) ,"no hostname specified"},
        +{ERR_REASON(BIO_R_NO_PORT_DEFINED)       ,"no port defined"},
        +{ERR_REASON(BIO_R_NO_PORT_SPECIFIED)     ,"no port specified"},
        +{ERR_REASON(BIO_R_NO_SUCH_FILE)          ,"no such file"},
        +{ERR_REASON(BIO_R_NULL_PARAMETER)        ,"null parameter"},
        +{ERR_REASON(BIO_R_TAG_MISMATCH)          ,"tag mismatch"},
        +{ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET) ,"unable to bind socket"},
        +{ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET),"unable to create socket"},
        +{ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET),"unable to listen socket"},
        +{ERR_REASON(BIO_R_UNINITIALIZED)         ,"uninitialized"},
        +{ERR_REASON(BIO_R_UNSUPPORTED_METHOD)    ,"unsupported method"},
        +{ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO),"write to read only BIO"},
        +{ERR_REASON(BIO_R_WSASTARTUP)            ,"WSAStartup"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_BIO_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(BIO_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,BIO_str_functs);
        +		ERR_load_strings(0,BIO_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bio/bio_lcl.h b/vendor/openssl/openssl/crypto/bio/bio_lcl.h
        new file mode 100644
        index 000000000..e7f7ec8d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bio_lcl.h
        @@ -0,0 +1,36 @@
        +#include <openssl/bio.h>
        +
        +#if BIO_FLAGS_UPLINK==0
        +/* Shortcut UPLINK calls on most platforms... */
        +#define	UP_stdin	stdin
        +#define	UP_stdout	stdout
        +#define	UP_stderr	stderr
        +#define	UP_fprintf	fprintf
        +#define	UP_fgets	fgets
        +#define	UP_fread	fread
        +#define	UP_fwrite	fwrite
        +#undef	UP_fsetmod
        +#define	UP_feof		feof
        +#define	UP_fclose	fclose
        +
        +#define	UP_fopen	fopen
        +#define	UP_fseek	fseek
        +#define	UP_ftell	ftell
        +#define	UP_fflush	fflush
        +#define	UP_ferror	ferror
        +#ifdef _WIN32
        +#define	UP_fileno	_fileno
        +#define	UP_open		_open
        +#define	UP_read		_read
        +#define	UP_write	_write
        +#define	UP_lseek	_lseek
        +#define	UP_close	_close
        +#else
        +#define	UP_fileno	fileno
        +#define	UP_open		open
        +#define	UP_read		read
        +#define	UP_write	write
        +#define	UP_lseek	lseek
        +#define	UP_close	close
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/bio_lib.c b/vendor/openssl/openssl/crypto/bio/bio_lib.c
        new file mode 100644
        index 000000000..9c9646afa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bio_lib.c
        @@ -0,0 +1,602 @@
        +/* crypto/bio/bio_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#include <openssl/stack.h>
        +
        +BIO *BIO_new(BIO_METHOD *method)
        +	{
        +	BIO *ret=NULL;
        +
        +	ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
        +	if (ret == NULL)
        +		{
        +		BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	if (!BIO_set(ret,method))
        +		{
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +		}
        +	return(ret);
        +	}
        +
        +int BIO_set(BIO *bio, BIO_METHOD *method)
        +	{
        +	bio->method=method;
        +	bio->callback=NULL;
        +	bio->cb_arg=NULL;
        +	bio->init=0;
        +	bio->shutdown=1;
        +	bio->flags=0;
        +	bio->retry_reason=0;
        +	bio->num=0;
        +	bio->ptr=NULL;
        +	bio->prev_bio=NULL;
        +	bio->next_bio=NULL;
        +	bio->references=1;
        +	bio->num_read=0L;
        +	bio->num_write=0L;
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
        +	if (method->create != NULL)
        +		if (!method->create(bio))
        +			{
        +			CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
        +					&bio->ex_data);
        +			return(0);
        +			}
        +	return(1);
        +	}
        +
        +int BIO_free(BIO *a)
        +	{
        +	int i;
        +
        +	if (a == NULL) return(0);
        +
        +	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
        +#ifdef REF_PRINT
        +	REF_PRINT("BIO",a);
        +#endif
        +	if (i > 0) return(1);
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"BIO_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +	if ((a->callback != NULL) &&
        +		((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
        +			return(i);
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
        +
        +	if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
        +	a->method->destroy(a);
        +	OPENSSL_free(a);
        +	return(1);
        +	}
        +
        +void BIO_vfree(BIO *a)
        +    { BIO_free(a); }
        +
        +void BIO_clear_flags(BIO *b, int flags)
        +	{
        +	b->flags &= ~flags;
        +	}
        +
        +int	BIO_test_flags(const BIO *b, int flags)
        +	{
        +	return (b->flags & flags);
        +	}
        +
        +void	BIO_set_flags(BIO *b, int flags)
        +	{
        +	b->flags |= flags;
        +	}
        +
        +long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long)
        +	{
        +	return b->callback;
        +	}
        +
        +void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long))
        +	{
        +	b->callback = cb;
        +	}
        +
        +void BIO_set_callback_arg(BIO *b, char *arg)
        +	{
        +	b->cb_arg = arg;
        +	}
        +
        +char * BIO_get_callback_arg(const BIO *b)
        +	{
        +	return b->cb_arg;
        +	}
        +
        +const char * BIO_method_name(const BIO *b)
        +	{
        +	return b->method->name;
        +	}
        +
        +int BIO_method_type(const BIO *b)
        +	{
        +	return b->method->type;
        +	}
        +
        +
        +int BIO_read(BIO *b, void *out, int outl)
        +	{
        +	int i;
        +	long (*cb)(BIO *,int,const char *,int,long,long);
        +
        +	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
        +		{
        +		BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
        +		return(-2);
        +		}
        +
        +	cb=b->callback;
        +	if ((cb != NULL) &&
        +		((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
        +			return(i);
        +
        +	if (!b->init)
        +		{
        +		BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
        +		return(-2);
        +		}
        +
        +	i=b->method->bread(b,out,outl);
        +
        +	if (i > 0) b->num_read+=(unsigned long)i;
        +
        +	if (cb != NULL)
        +		i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
        +			0L,(long)i);
        +	return(i);
        +	}
        +
        +int BIO_write(BIO *b, const void *in, int inl)
        +	{
        +	int i;
        +	long (*cb)(BIO *,int,const char *,int,long,long);
        +
        +	if (b == NULL)
        +		return(0);
        +
        +	cb=b->callback;
        +	if ((b->method == NULL) || (b->method->bwrite == NULL))
        +		{
        +		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
        +		return(-2);
        +		}
        +
        +	if ((cb != NULL) &&
        +		((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
        +			return(i);
        +
        +	if (!b->init)
        +		{
        +		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
        +		return(-2);
        +		}
        +
        +	i=b->method->bwrite(b,in,inl);
        +
        +	if (i > 0) b->num_write+=(unsigned long)i;
        +
        +	if (cb != NULL)
        +		i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
        +			0L,(long)i);
        +	return(i);
        +	}
        +
        +int BIO_puts(BIO *b, const char *in)
        +	{
        +	int i;
        +	long (*cb)(BIO *,int,const char *,int,long,long);
        +
        +	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
        +		{
        +		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
        +		return(-2);
        +		}
        +
        +	cb=b->callback;
        +
        +	if ((cb != NULL) &&
        +		((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
        +			return(i);
        +
        +	if (!b->init)
        +		{
        +		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
        +		return(-2);
        +		}
        +
        +	i=b->method->bputs(b,in);
        +
        +	if (i > 0) b->num_write+=(unsigned long)i;
        +
        +	if (cb != NULL)
        +		i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
        +			0L,(long)i);
        +	return(i);
        +	}
        +
        +int BIO_gets(BIO *b, char *in, int inl)
        +	{
        +	int i;
        +	long (*cb)(BIO *,int,const char *,int,long,long);
        +
        +	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
        +		{
        +		BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
        +		return(-2);
        +		}
        +
        +	cb=b->callback;
        +
        +	if ((cb != NULL) &&
        +		((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
        +			return(i);
        +
        +	if (!b->init)
        +		{
        +		BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
        +		return(-2);
        +		}
        +
        +	i=b->method->bgets(b,in,inl);
        +
        +	if (cb != NULL)
        +		i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
        +			0L,(long)i);
        +	return(i);
        +	}
        +
        +int BIO_indent(BIO *b,int indent,int max)
        +	{
        +	if(indent < 0)
        +		indent=0;
        +	if(indent > max)
        +		indent=max;
        +	while(indent--)
        +		if(BIO_puts(b," ") != 1)
        +			return 0;
        +	return 1;
        +	}
        +
        +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
        +	{
        +	int i;
        +
        +	i=iarg;
        +	return(BIO_ctrl(b,cmd,larg,(char *)&i));
        +	}
        +
        +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
        +	{
        +	char *p=NULL;
        +
        +	if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
        +		return(NULL);
        +	else
        +		return(p);
        +	}
        +
        +long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
        +	{
        +	long ret;
        +	long (*cb)(BIO *,int,const char *,int,long,long);
        +
        +	if (b == NULL) return(0);
        +
        +	if ((b->method == NULL) || (b->method->ctrl == NULL))
        +		{
        +		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
        +		return(-2);
        +		}
        +
        +	cb=b->callback;
        +
        +	if ((cb != NULL) &&
        +		((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
        +		return(ret);
        +
        +	ret=b->method->ctrl(b,cmd,larg,parg);
        +
        +	if (cb != NULL)
        +		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
        +			larg,ret);
        +	return(ret);
        +	}
        +
        +long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
        +	{
        +	long ret;
        +	long (*cb)(BIO *,int,const char *,int,long,long);
        +
        +	if (b == NULL) return(0);
        +
        +	if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
        +		{
        +		BIOerr(BIO_F_BIO_CALLBACK_CTRL,BIO_R_UNSUPPORTED_METHOD);
        +		return(-2);
        +		}
        +
        +	cb=b->callback;
        +
        +	if ((cb != NULL) &&
        +		((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
        +		return(ret);
        +
        +	ret=b->method->callback_ctrl(b,cmd,fp);
        +
        +	if (cb != NULL)
        +		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
        +			0,ret);
        +	return(ret);
        +	}
        +
        +/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
        + * do; but those macros have inappropriate return type, and for interfacing
        + * from other programming languages, C macros aren't much of a help anyway. */
        +size_t BIO_ctrl_pending(BIO *bio)
        +	{
        +	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
        +	}
        +
        +size_t BIO_ctrl_wpending(BIO *bio)
        +	{
        +	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
        +	}
        +
        +
        +/* put the 'bio' on the end of b's list of operators */
        +BIO *BIO_push(BIO *b, BIO *bio)
        +	{
        +	BIO *lb;
        +
        +	if (b == NULL) return(bio);
        +	lb=b;
        +	while (lb->next_bio != NULL)
        +		lb=lb->next_bio;
        +	lb->next_bio=bio;
        +	if (bio != NULL)
        +		bio->prev_bio=lb;
        +	/* called to do internal processing */
        +	BIO_ctrl(b,BIO_CTRL_PUSH,0,lb);
        +	return(b);
        +	}
        +
        +/* Remove the first and return the rest */
        +BIO *BIO_pop(BIO *b)
        +	{
        +	BIO *ret;
        +
        +	if (b == NULL) return(NULL);
        +	ret=b->next_bio;
        +
        +	BIO_ctrl(b,BIO_CTRL_POP,0,b);
        +
        +	if (b->prev_bio != NULL)
        +		b->prev_bio->next_bio=b->next_bio;
        +	if (b->next_bio != NULL)
        +		b->next_bio->prev_bio=b->prev_bio;
        +
        +	b->next_bio=NULL;
        +	b->prev_bio=NULL;
        +	return(ret);
        +	}
        +
        +BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
        +	{
        +	BIO *b,*last;
        +
        +	b=last=bio;
        +	for (;;)
        +		{
        +		if (!BIO_should_retry(b)) break;
        +		last=b;
        +		b=b->next_bio;
        +		if (b == NULL) break;
        +		}
        +	if (reason != NULL) *reason=last->retry_reason;
        +	return(last);
        +	}
        +
        +int BIO_get_retry_reason(BIO *bio)
        +	{
        +	return(bio->retry_reason);
        +	}
        +
        +BIO *BIO_find_type(BIO *bio, int type)
        +	{
        +	int mt,mask;
        +
        +	if(!bio) return NULL;
        +	mask=type&0xff;
        +	do	{
        +		if (bio->method != NULL)
        +			{
        +			mt=bio->method->type;
        +
        +			if (!mask)
        +				{
        +				if (mt & type) return(bio);
        +				}
        +			else if (mt == type)
        +				return(bio);
        +			}
        +		bio=bio->next_bio;
        +		} while (bio != NULL);
        +	return(NULL);
        +	}
        +
        +BIO *BIO_next(BIO *b)
        +	{
        +	if(!b) return NULL;
        +	return b->next_bio;
        +	}
        +
        +void BIO_free_all(BIO *bio)
        +	{
        +	BIO *b;
        +	int ref;
        +
        +	while (bio != NULL)
        +		{
        +		b=bio;
        +		ref=b->references;
        +		bio=bio->next_bio;
        +		BIO_free(b);
        +		/* Since ref count > 1, don't free anyone else. */
        +		if (ref > 1) break;
        +		}
        +	}
        +
        +BIO *BIO_dup_chain(BIO *in)
        +	{
        +	BIO *ret=NULL,*eoc=NULL,*bio,*new_bio;
        +
        +	for (bio=in; bio != NULL; bio=bio->next_bio)
        +		{
        +		if ((new_bio=BIO_new(bio->method)) == NULL) goto err;
        +		new_bio->callback=bio->callback;
        +		new_bio->cb_arg=bio->cb_arg;
        +		new_bio->init=bio->init;
        +		new_bio->shutdown=bio->shutdown;
        +		new_bio->flags=bio->flags;
        +
        +		/* This will let SSL_s_sock() work with stdin/stdout */
        +		new_bio->num=bio->num;
        +
        +		if (!BIO_dup_state(bio,(char *)new_bio))
        +			{
        +			BIO_free(new_bio);
        +			goto err;
        +			}
        +
        +		/* copy app data */
        +		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
        +					&bio->ex_data))
        +			goto err;
        +
        +		if (ret == NULL)
        +			{
        +			eoc=new_bio;
        +			ret=eoc;
        +			}
        +		else
        +			{
        +			BIO_push(eoc,new_bio);
        +			eoc=new_bio;
        +			}
        +		}
        +	return(ret);
        +err:
        +	if (ret != NULL)
        +		BIO_free(ret);
        +	return(NULL);	
        +	}
        +
        +void BIO_copy_next_retry(BIO *b)
        +	{
        +	BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
        +	b->retry_reason=b->next_bio->retry_reason;
        +	}
        +
        +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +	{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
        +				new_func, dup_func, free_func);
        +	}
        +
        +int BIO_set_ex_data(BIO *bio, int idx, void *data)
        +	{
        +	return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
        +	}
        +
        +void *BIO_get_ex_data(BIO *bio, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
        +	}
        +
        +unsigned long BIO_number_read(BIO *bio)
        +{
        +	if(bio) return bio->num_read;
        +	return 0;
        +}
        +
        +unsigned long BIO_number_written(BIO *bio)
        +{
        +	if(bio) return bio->num_write;
        +	return 0;
        +}
        +
        +IMPLEMENT_STACK_OF(BIO)
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_acpt.c b/vendor/openssl/openssl/crypto/bio/bss_acpt.c
        new file mode 100644
        index 000000000..5d49e1a72
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_acpt.c
        @@ -0,0 +1,478 @@
        +/* crypto/bio/bss_acpt.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +#ifndef OPENSSL_NO_SOCK
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
        +#else
        +#define SOCKET_PROTOCOL IPPROTO_TCP
        +#endif
        +
        +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
        +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
        +#undef FIONBIO
        +#endif
        +
        +typedef struct bio_accept_st
        +	{
        +	int state;
        +	char *param_addr;
        +
        +	int accept_sock;
        +	int accept_nbio;
        +
        +	char *addr;
        +	int nbio;
        +	/* If 0, it means normal, if 1, do a connect on bind failure,
        +	 * and if there is no-one listening, bind with SO_REUSEADDR.
        +	 * If 2, always use SO_REUSEADDR. */
        +	int bind_mode;
        +	BIO *bio_chain;
        +	} BIO_ACCEPT;
        +
        +static int acpt_write(BIO *h, const char *buf, int num);
        +static int acpt_read(BIO *h, char *buf, int size);
        +static int acpt_puts(BIO *h, const char *str);
        +static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int acpt_new(BIO *h);
        +static int acpt_free(BIO *data);
        +static int acpt_state(BIO *b, BIO_ACCEPT *c);
        +static void acpt_close_socket(BIO *data);
        +static BIO_ACCEPT *BIO_ACCEPT_new(void );
        +static void BIO_ACCEPT_free(BIO_ACCEPT *a);
        +
        +#define ACPT_S_BEFORE			1
        +#define ACPT_S_GET_ACCEPT_SOCKET	2
        +#define ACPT_S_OK			3
        +
        +static BIO_METHOD methods_acceptp=
        +	{
        +	BIO_TYPE_ACCEPT,
        +	"socket accept",
        +	acpt_write,
        +	acpt_read,
        +	acpt_puts,
        +	NULL, /* connect_gets, */
        +	acpt_ctrl,
        +	acpt_new,
        +	acpt_free,
        +	NULL,
        +	};
        +
        +BIO_METHOD *BIO_s_accept(void)
        +	{
        +	return(&methods_acceptp);
        +	}
        +
        +static int acpt_new(BIO *bi)
        +	{
        +	BIO_ACCEPT *ba;
        +
        +	bi->init=0;
        +	bi->num=INVALID_SOCKET;
        +	bi->flags=0;
        +	if ((ba=BIO_ACCEPT_new()) == NULL)
        +		return(0);
        +	bi->ptr=(char *)ba;
        +	ba->state=ACPT_S_BEFORE;
        +	bi->shutdown=1;
        +	return(1);
        +	}
        +
        +static BIO_ACCEPT *BIO_ACCEPT_new(void)
        +	{
        +	BIO_ACCEPT *ret;
        +
        +	if ((ret=(BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL)
        +		return(NULL);
        +
        +	memset(ret,0,sizeof(BIO_ACCEPT));
        +	ret->accept_sock=INVALID_SOCKET;
        +	ret->bind_mode=BIO_BIND_NORMAL;
        +	return(ret);
        +	}
        +
        +static void BIO_ACCEPT_free(BIO_ACCEPT *a)
        +	{
        +	if(a == NULL)
        +	    return;
        +
        +	if (a->param_addr != NULL) OPENSSL_free(a->param_addr);
        +	if (a->addr != NULL) OPENSSL_free(a->addr);
        +	if (a->bio_chain != NULL) BIO_free(a->bio_chain);
        +	OPENSSL_free(a);
        +	}
        +
        +static void acpt_close_socket(BIO *bio)
        +	{
        +	BIO_ACCEPT *c;
        +
        +	c=(BIO_ACCEPT *)bio->ptr;
        +	if (c->accept_sock != INVALID_SOCKET)
        +		{
        +		shutdown(c->accept_sock,2);
        +		closesocket(c->accept_sock);
        +		c->accept_sock=INVALID_SOCKET;
        +		bio->num=INVALID_SOCKET;
        +		}
        +	}
        +
        +static int acpt_free(BIO *a)
        +	{
        +	BIO_ACCEPT *data;
        +
        +	if (a == NULL) return(0);
        +	data=(BIO_ACCEPT *)a->ptr;
        +	 
        +	if (a->shutdown)
        +		{
        +		acpt_close_socket(a);
        +		BIO_ACCEPT_free(data);
        +		a->ptr=NULL;
        +		a->flags=0;
        +		a->init=0;
        +		}
        +	return(1);
        +	}
        +	
        +static int acpt_state(BIO *b, BIO_ACCEPT *c)
        +	{
        +	BIO *bio=NULL,*dbio;
        +	int s= -1;
        +	int i;
        +
        +again:
        +	switch (c->state)
        +		{
        +	case ACPT_S_BEFORE:
        +		if (c->param_addr == NULL)
        +			{
        +			BIOerr(BIO_F_ACPT_STATE,BIO_R_NO_ACCEPT_PORT_SPECIFIED);
        +			return(-1);
        +			}
        +		s=BIO_get_accept_socket(c->param_addr,c->bind_mode);
        +		if (s == INVALID_SOCKET)
        +			return(-1);
        +
        +		if (c->accept_nbio)
        +			{
        +			if (!BIO_socket_nbio(s,1))
        +				{
        +				closesocket(s);
        +				BIOerr(BIO_F_ACPT_STATE,BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
        +				return(-1);
        +				}
        +			}
        +		c->accept_sock=s;
        +		b->num=s;
        +		c->state=ACPT_S_GET_ACCEPT_SOCKET;
        +		return(1);
        +		/* break; */
        +	case ACPT_S_GET_ACCEPT_SOCKET:
        +		if (b->next_bio != NULL)
        +			{
        +			c->state=ACPT_S_OK;
        +			goto again;
        +			}
        +		BIO_clear_retry_flags(b);
        +		b->retry_reason=0;
        +		i=BIO_accept(c->accept_sock,&(c->addr));
        +
        +		/* -2 return means we should retry */
        +		if(i == -2)
        +			{
        +			BIO_set_retry_special(b);
        +			b->retry_reason=BIO_RR_ACCEPT;
        +			return -1;
        +			}
        +
        +		if (i < 0) return(i);
        +
        +		bio=BIO_new_socket(i,BIO_CLOSE);
        +		if (bio == NULL) goto err;
        +
        +		BIO_set_callback(bio,BIO_get_callback(b));
        +		BIO_set_callback_arg(bio,BIO_get_callback_arg(b));
        +
        +		if (c->nbio)
        +			{
        +			if (!BIO_socket_nbio(i,1))
        +				{
        +				BIOerr(BIO_F_ACPT_STATE,BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
        +				goto err;
        +				}
        +			}
        +
        +		/* If the accept BIO has an bio_chain, we dup it and
        +		 * put the new socket at the end. */
        +		if (c->bio_chain != NULL)
        +			{
        +			if ((dbio=BIO_dup_chain(c->bio_chain)) == NULL)
        +				goto err;
        +			if (!BIO_push(dbio,bio)) goto err;
        +			bio=dbio;
        +			}
        +		if (BIO_push(b,bio) == NULL) goto err;
        +
        +		c->state=ACPT_S_OK;
        +		return(1);
        +err:
        +		if (bio != NULL)
        +			BIO_free(bio);
        +		else if (s >= 0)
        +			closesocket(s);
        +		return(0);
        +		/* break; */
        +	case ACPT_S_OK:
        +		if (b->next_bio == NULL)
        +			{
        +			c->state=ACPT_S_GET_ACCEPT_SOCKET;
        +			goto again;
        +			}
        +		return(1);
        +		/* break; */
        +	default:	
        +		return(0);
        +		/* break; */
        +		}
        +
        +	}
        +
        +static int acpt_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +	BIO_ACCEPT *data;
        +
        +	BIO_clear_retry_flags(b);
        +	data=(BIO_ACCEPT *)b->ptr;
        +
        +	while (b->next_bio == NULL)
        +		{
        +		ret=acpt_state(b,data);
        +		if (ret <= 0) return(ret);
        +		}
        +
        +	ret=BIO_read(b->next_bio,out,outl);
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static int acpt_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret;
        +	BIO_ACCEPT *data;
        +
        +	BIO_clear_retry_flags(b);
        +	data=(BIO_ACCEPT *)b->ptr;
        +
        +	while (b->next_bio == NULL)
        +		{
        +		ret=acpt_state(b,data);
        +		if (ret <= 0) return(ret);
        +		}
        +
        +	ret=BIO_write(b->next_bio,in,inl);
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	int *ip;
        +	long ret=1;
        +	BIO_ACCEPT *data;
        +	char **pp;
        +
        +	data=(BIO_ACCEPT *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ret=0;
        +		data->state=ACPT_S_BEFORE;
        +		acpt_close_socket(b);
        +		b->flags=0;
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		/* use this one to start the connection */
        +		ret=(long)acpt_state(b,data);
        +		break;
        +	case BIO_C_SET_ACCEPT:
        +		if (ptr != NULL)
        +			{
        +			if (num == 0)
        +				{
        +				b->init=1;
        +				if (data->param_addr != NULL)
        +					OPENSSL_free(data->param_addr);
        +				data->param_addr=BUF_strdup(ptr);
        +				}
        +			else if (num == 1)
        +				{
        +				data->accept_nbio=(ptr != NULL);
        +				}
        +			else if (num == 2)
        +				{
        +				if (data->bio_chain != NULL)
        +					BIO_free(data->bio_chain);
        +				data->bio_chain=(BIO *)ptr;
        +				}
        +			}
        +		break;
        +	case BIO_C_SET_NBIO:
        +		data->nbio=(int)num;
        +		break;
        +	case BIO_C_SET_FD:
        +		b->init=1;
        +		b->num= *((int *)ptr);
        +		data->accept_sock=b->num;
        +		data->state=ACPT_S_GET_ACCEPT_SOCKET;
        +		b->shutdown=(int)num;
        +		b->init=1;
        +		break;
        +	case BIO_C_GET_FD:
        +		if (b->init)
        +			{
        +			ip=(int *)ptr;
        +			if (ip != NULL)
        +				*ip=data->accept_sock;
        +			ret=data->accept_sock;
        +			}
        +		else
        +			ret= -1;
        +		break;
        +	case BIO_C_GET_ACCEPT:
        +		if (b->init)
        +			{
        +			if (ptr != NULL)
        +				{
        +				pp=(char **)ptr;
        +				*pp=data->param_addr;
        +				}
        +			else
        +				ret= -1;
        +			}
        +		else
        +			ret= -1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_WPENDING:
        +		ret=0;
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		break;
        +	case BIO_C_SET_BIND_MODE:
        +		data->bind_mode=(int)num;
        +		break;
        +	case BIO_C_GET_BIND_MODE:
        +		ret=(long)data->bind_mode;
        +		break;
        +	case BIO_CTRL_DUP:
        +/*		dbio=(BIO *)ptr;
        +		if (data->param_port) EAY EAY
        +			BIO_set_port(dbio,data->param_port);
        +		if (data->param_hostname)
        +			BIO_set_hostname(dbio,data->param_hostname);
        +		BIO_set_nbio(dbio,data->nbio); */
        +		break;
        +
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int acpt_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=acpt_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +BIO *BIO_new_accept(char *str)
        +	{
        +	BIO *ret;
        +
        +	ret=BIO_new(BIO_s_accept());
        +	if (ret == NULL) return(NULL);
        +	if (BIO_set_accept_port(ret,str))
        +		return(ret);
        +	else
        +		{
        +		BIO_free(ret);
        +		return(NULL);
        +		}
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_bio.c b/vendor/openssl/openssl/crypto/bio/bss_bio.c
        new file mode 100644
        index 000000000..52ef0ebcb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_bio.c
        @@ -0,0 +1,924 @@
        +/* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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).
        + *
        + */
        +
        +/* Special method for a BIO where the other endpoint is also a BIO
        + * of this kind, handled by the same thread (i.e. the "peer" is actually
        + * ourselves, wearing a different hat).
        + * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
        + * for which no specific BIO method is available.
        + * See ssl/ssltest.c for some hints on how this can be used. */
        +
        +/* BIO_DEBUG implies BIO_PAIR_DEBUG */
        +#ifdef BIO_DEBUG
        +# ifndef BIO_PAIR_DEBUG
        +#  define BIO_PAIR_DEBUG
        +# endif
        +#endif
        +
        +/* disable assert() unless BIO_PAIR_DEBUG has been defined */
        +#ifndef BIO_PAIR_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +
        +#include <assert.h>
        +#include <limits.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/crypto.h>
        +
        +#include "e_os.h"
        +
        +/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
        +#if defined(OPENSSL_SYS_VXWORKS)
        +# undef SSIZE_MAX
        +#endif
        +#ifndef SSIZE_MAX
        +# define SSIZE_MAX INT_MAX
        +#endif
        +
        +static int bio_new(BIO *bio);
        +static int bio_free(BIO *bio);
        +static int bio_read(BIO *bio, char *buf, int size);
        +static int bio_write(BIO *bio, const char *buf, int num);
        +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
        +static int bio_puts(BIO *bio, const char *str);
        +
        +static int bio_make_pair(BIO *bio1, BIO *bio2);
        +static void bio_destroy_pair(BIO *bio);
        +
        +static BIO_METHOD methods_biop =
        +{
        +	BIO_TYPE_BIO,
        +	"BIO pair",
        +	bio_write,
        +	bio_read,
        +	bio_puts,
        +	NULL /* no bio_gets */,
        +	bio_ctrl,
        +	bio_new,
        +	bio_free,
        +	NULL /* no bio_callback_ctrl */
        +};
        +
        +BIO_METHOD *BIO_s_bio(void)
        +	{
        +	return &methods_biop;
        +	}
        +
        +struct bio_bio_st
        +{
        +	BIO *peer;     /* NULL if buf == NULL.
        +	                * If peer != NULL, then peer->ptr is also a bio_bio_st,
        +	                * and its "peer" member points back to us.
        +	                * peer != NULL iff init != 0 in the BIO. */
        +	
        +	/* This is for what we write (i.e. reading uses peer's struct): */
        +	int closed;     /* valid iff peer != NULL */
        +	size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
        +	size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
        +	size_t size;
        +	char *buf;      /* "size" elements (if != NULL) */
        +
        +	size_t request; /* valid iff peer != NULL; 0 if len != 0,
        +	                 * otherwise set by peer to number of bytes
        +	                 * it (unsuccessfully) tried to read,
        +	                 * never more than buffer space (size-len) warrants. */
        +};
        +
        +static int bio_new(BIO *bio)
        +	{
        +	struct bio_bio_st *b;
        +	
        +	b = OPENSSL_malloc(sizeof *b);
        +	if (b == NULL)
        +		return 0;
        +
        +	b->peer = NULL;
        +	b->size = 17*1024; /* enough for one TLS record (just a default) */
        +	b->buf = NULL;
        +
        +	bio->ptr = b;
        +	return 1;
        +	}
        +
        +
        +static int bio_free(BIO *bio)
        +	{
        +	struct bio_bio_st *b;
        +
        +	if (bio == NULL)
        +		return 0;
        +	b = bio->ptr;
        +
        +	assert(b != NULL);
        +
        +	if (b->peer)
        +		bio_destroy_pair(bio);
        +	
        +	if (b->buf != NULL)
        +		{
        +		OPENSSL_free(b->buf);
        +		}
        +
        +	OPENSSL_free(b);
        +
        +	return 1;
        +	}
        +
        +
        +
        +static int bio_read(BIO *bio, char *buf, int size_)
        +	{
        +	size_t size = size_;
        +	size_t rest;
        +	struct bio_bio_st *b, *peer_b;
        +
        +	BIO_clear_retry_flags(bio);
        +
        +	if (!bio->init)
        +		return 0;
        +
        +	b = bio->ptr;
        +	assert(b != NULL);
        +	assert(b->peer != NULL);
        +	peer_b = b->peer->ptr;
        +	assert(peer_b != NULL);
        +	assert(peer_b->buf != NULL);
        +
        +	peer_b->request = 0; /* will be set in "retry_read" situation */
        +
        +	if (buf == NULL || size == 0)
        +		return 0;
        +
        +	if (peer_b->len == 0)
        +		{
        +		if (peer_b->closed)
        +			return 0; /* writer has closed, and no data is left */
        +		else
        +			{
        +			BIO_set_retry_read(bio); /* buffer is empty */
        +			if (size <= peer_b->size)
        +				peer_b->request = size;
        +			else
        +				/* don't ask for more than the peer can
        +				 * deliver in one write */
        +				peer_b->request = peer_b->size;
        +			return -1;
        +			}
        +		}
        +
        +	/* we can read */
        +	if (peer_b->len < size)
        +		size = peer_b->len;
        +
        +	/* now read "size" bytes */
        +	
        +	rest = size;
        +	
        +	assert(rest > 0);
        +	do /* one or two iterations */
        +		{
        +		size_t chunk;
        +		
        +		assert(rest <= peer_b->len);
        +		if (peer_b->offset + rest <= peer_b->size)
        +			chunk = rest;
        +		else
        +			/* wrap around ring buffer */
        +			chunk = peer_b->size - peer_b->offset;
        +		assert(peer_b->offset + chunk <= peer_b->size);
        +		
        +		memcpy(buf, peer_b->buf + peer_b->offset, chunk);
        +		
        +		peer_b->len -= chunk;
        +		if (peer_b->len)
        +			{
        +			peer_b->offset += chunk;
        +			assert(peer_b->offset <= peer_b->size);
        +			if (peer_b->offset == peer_b->size)
        +				peer_b->offset = 0;
        +			buf += chunk;
        +			}
        +		else
        +			{
        +			/* buffer now empty, no need to advance "buf" */
        +			assert(chunk == rest);
        +			peer_b->offset = 0;
        +			}
        +		rest -= chunk;
        +		}
        +	while (rest);
        +	
        +	return size;
        +	}
        +
        +/* non-copying interface: provide pointer to available data in buffer
        + *    bio_nread0:  return number of available bytes
        + *    bio_nread:   also advance index
        + * (example usage:  bio_nread0(), read from buffer, bio_nread()
        + *  or just         bio_nread(), read from buffer)
        + */
        +/* WARNING: The non-copying interface is largely untested as of yet
        + * and may contain bugs. */
        +static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
        +	{
        +	struct bio_bio_st *b, *peer_b;
        +	ossl_ssize_t num;
        +	
        +	BIO_clear_retry_flags(bio);
        +
        +	if (!bio->init)
        +		return 0;
        +	
        +	b = bio->ptr;
        +	assert(b != NULL);
        +	assert(b->peer != NULL);
        +	peer_b = b->peer->ptr;
        +	assert(peer_b != NULL);
        +	assert(peer_b->buf != NULL);
        +	
        +	peer_b->request = 0;
        +	
        +	if (peer_b->len == 0)
        +		{
        +		char dummy;
        +		
        +		/* avoid code duplication -- nothing available for reading */
        +		return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
        +		}
        +
        +	num = peer_b->len;
        +	if (peer_b->size < peer_b->offset + num)
        +		/* no ring buffer wrap-around for non-copying interface */
        +		num = peer_b->size - peer_b->offset;
        +	assert(num > 0);
        +
        +	if (buf != NULL)
        +		*buf = peer_b->buf + peer_b->offset;
        +	return num;
        +	}
        +
        +static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
        +	{
        +	struct bio_bio_st *b, *peer_b;
        +	ossl_ssize_t num, available;
        +
        +	if (num_ > SSIZE_MAX)
        +		num = SSIZE_MAX;
        +	else
        +		num = (ossl_ssize_t)num_;
        +
        +	available = bio_nread0(bio, buf);
        +	if (num > available)
        +		num = available;
        +	if (num <= 0)
        +		return num;
        +
        +	b = bio->ptr;
        +	peer_b = b->peer->ptr;
        +
        +	peer_b->len -= num;
        +	if (peer_b->len) 
        +		{
        +		peer_b->offset += num;
        +		assert(peer_b->offset <= peer_b->size);
        +		if (peer_b->offset == peer_b->size)
        +			peer_b->offset = 0;
        +		}
        +	else
        +		peer_b->offset = 0;
        +
        +	return num;
        +	}
        +
        +
        +static int bio_write(BIO *bio, const char *buf, int num_)
        +	{
        +	size_t num = num_;
        +	size_t rest;
        +	struct bio_bio_st *b;
        +
        +	BIO_clear_retry_flags(bio);
        +
        +	if (!bio->init || buf == NULL || num == 0)
        +		return 0;
        +
        +	b = bio->ptr;		
        +	assert(b != NULL);
        +	assert(b->peer != NULL);
        +	assert(b->buf != NULL);
        +
        +	b->request = 0;
        +	if (b->closed)
        +		{
        +		/* we already closed */
        +		BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
        +		return -1;
        +		}
        +
        +	assert(b->len <= b->size);
        +
        +	if (b->len == b->size)
        +		{
        +		BIO_set_retry_write(bio); /* buffer is full */
        +		return -1;
        +		}
        +
        +	/* we can write */
        +	if (num > b->size - b->len)
        +		num = b->size - b->len;
        +	
        +	/* now write "num" bytes */
        +
        +	rest = num;
        +	
        +	assert(rest > 0);
        +	do /* one or two iterations */
        +		{
        +		size_t write_offset;
        +		size_t chunk;
        +
        +		assert(b->len + rest <= b->size);
        +
        +		write_offset = b->offset + b->len;
        +		if (write_offset >= b->size)
        +			write_offset -= b->size;
        +		/* b->buf[write_offset] is the first byte we can write to. */
        +
        +		if (write_offset + rest <= b->size)
        +			chunk = rest;
        +		else
        +			/* wrap around ring buffer */
        +			chunk = b->size - write_offset;
        +		
        +		memcpy(b->buf + write_offset, buf, chunk);
        +		
        +		b->len += chunk;
        +
        +		assert(b->len <= b->size);
        +		
        +		rest -= chunk;
        +		buf += chunk;
        +		}
        +	while (rest);
        +
        +	return num;
        +	}
        +
        +/* non-copying interface: provide pointer to region to write to
        + *   bio_nwrite0:  check how much space is available
        + *   bio_nwrite:   also increase length
        + * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
        + *  or just         bio_nwrite(), write to buffer)
        + */
        +static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
        +	{
        +	struct bio_bio_st *b;
        +	size_t num;
        +	size_t write_offset;
        +
        +	BIO_clear_retry_flags(bio);
        +
        +	if (!bio->init)
        +		return 0;
        +
        +	b = bio->ptr;		
        +	assert(b != NULL);
        +	assert(b->peer != NULL);
        +	assert(b->buf != NULL);
        +
        +	b->request = 0;
        +	if (b->closed)
        +		{
        +		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
        +		return -1;
        +		}
        +
        +	assert(b->len <= b->size);
        +
        +	if (b->len == b->size)
        +		{
        +		BIO_set_retry_write(bio);
        +		return -1;
        +		}
        +
        +	num = b->size - b->len;
        +	write_offset = b->offset + b->len;
        +	if (write_offset >= b->size)
        +		write_offset -= b->size;
        +	if (write_offset + num > b->size)
        +		/* no ring buffer wrap-around for non-copying interface
        +		 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
        +		 * BIO_nwrite may have to be called twice) */
        +		num = b->size - write_offset;
        +
        +	if (buf != NULL)
        +		*buf = b->buf + write_offset;
        +	assert(write_offset + num <= b->size);
        +
        +	return num;
        +	}
        +
        +static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
        +	{
        +	struct bio_bio_st *b;
        +	ossl_ssize_t num, space;
        +
        +	if (num_ > SSIZE_MAX)
        +		num = SSIZE_MAX;
        +	else
        +		num = (ossl_ssize_t)num_;
        +
        +	space = bio_nwrite0(bio, buf);
        +	if (num > space)
        +		num = space;
        +	if (num <= 0)
        +		return num;
        +	b = bio->ptr;
        +	assert(b != NULL);
        +	b->len += num;
        +	assert(b->len <= b->size);
        +
        +	return num;
        +	}
        +
        +
        +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
        +	{
        +	long ret;
        +	struct bio_bio_st *b = bio->ptr;
        +	
        +	assert(b != NULL);
        +
        +	switch (cmd)
        +		{
        +	/* specific CTRL codes */
        +
        +	case BIO_C_SET_WRITE_BUF_SIZE:
        +		if (b->peer)
        +			{
        +			BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
        +			ret = 0;
        +			}
        +		else if (num == 0)
        +			{
        +			BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
        +			ret = 0;
        +			}
        +		else
        +			{
        +			size_t new_size = num;
        +
        +			if (b->size != new_size)
        +				{
        +				if (b->buf) 
        +					{
        +					OPENSSL_free(b->buf);
        +					b->buf = NULL;
        +					}
        +				b->size = new_size;
        +				}
        +			ret = 1;
        +			}
        +		break;
        +
        +	case BIO_C_GET_WRITE_BUF_SIZE:
        +		ret = (long) b->size;
        +		break;
        +
        +	case BIO_C_MAKE_BIO_PAIR:
        +		{
        +		BIO *other_bio = ptr;
        +		
        +		if (bio_make_pair(bio, other_bio))
        +			ret = 1;
        +		else
        +			ret = 0;
        +		}
        +		break;
        +		
        +	case BIO_C_DESTROY_BIO_PAIR:
        +		/* Affects both BIOs in the pair -- call just once!
        +		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
        +		bio_destroy_pair(bio);
        +		ret = 1;
        +		break;
        +
        +	case BIO_C_GET_WRITE_GUARANTEE:
        +		/* How many bytes can the caller feed to the next write
        +		 * without having to keep any? */
        +		if (b->peer == NULL || b->closed)
        +			ret = 0;
        +		else
        +			ret = (long) b->size - b->len;
        +		break;
        +
        +	case BIO_C_GET_READ_REQUEST:
        +		/* If the peer unsuccessfully tried to read, how many bytes
        +		 * were requested?  (As with BIO_CTRL_PENDING, that number
        +		 * can usually be treated as boolean.) */
        +		ret = (long) b->request;
        +		break;
        +
        +	case BIO_C_RESET_READ_REQUEST:
        +		/* Reset request.  (Can be useful after read attempts
        +		 * at the other side that are meant to be non-blocking,
        +		 * e.g. when probing SSL_read to see if any data is
        +		 * available.) */
        +		b->request = 0;
        +		ret = 1;
        +		break;
        +
        +	case BIO_C_SHUTDOWN_WR:
        +		/* similar to shutdown(..., SHUT_WR) */
        +		b->closed = 1;
        +		ret = 1;
        +		break;
        +
        +	case BIO_C_NREAD0:
        +		/* prepare for non-copying read */
        +		ret = (long) bio_nread0(bio, ptr);
        +		break;
        +		
        +	case BIO_C_NREAD:
        +		/* non-copying read */
        +		ret = (long) bio_nread(bio, ptr, (size_t) num);
        +		break;
        +		
        +	case BIO_C_NWRITE0:
        +		/* prepare for non-copying write */
        +		ret = (long) bio_nwrite0(bio, ptr);
        +		break;
        +
        +	case BIO_C_NWRITE:
        +		/* non-copying write */
        +		ret = (long) bio_nwrite(bio, ptr, (size_t) num);
        +		break;
        +		
        +
        +	/* standard CTRL codes follow */
        +
        +	case BIO_CTRL_RESET:
        +		if (b->buf != NULL)
        +			{
        +			b->len = 0;
        +			b->offset = 0;
        +			}
        +		ret = 0;
        +		break;		
        +
        +	case BIO_CTRL_GET_CLOSE:
        +		ret = bio->shutdown;
        +		break;
        +
        +	case BIO_CTRL_SET_CLOSE:
        +		bio->shutdown = (int) num;
        +		ret = 1;
        +		break;
        +
        +	case BIO_CTRL_PENDING:
        +		if (b->peer != NULL)
        +			{
        +			struct bio_bio_st *peer_b = b->peer->ptr;
        +			
        +			ret = (long) peer_b->len;
        +			}
        +		else
        +			ret = 0;
        +		break;
        +
        +	case BIO_CTRL_WPENDING:
        +		if (b->buf != NULL)
        +			ret = (long) b->len;
        +		else
        +			ret = 0;
        +		break;
        +
        +	case BIO_CTRL_DUP:
        +		/* See BIO_dup_chain for circumstances we have to expect. */
        +		{
        +		BIO *other_bio = ptr;
        +		struct bio_bio_st *other_b;
        +		
        +		assert(other_bio != NULL);
        +		other_b = other_bio->ptr;
        +		assert(other_b != NULL);
        +		
        +		assert(other_b->buf == NULL); /* other_bio is always fresh */
        +
        +		other_b->size = b->size;
        +		}
        +
        +		ret = 1;
        +		break;
        +
        +	case BIO_CTRL_FLUSH:
        +		ret = 1;
        +		break;
        +
        +	case BIO_CTRL_EOF:
        +		{
        +		BIO *other_bio = ptr;
        +		
        +		if (other_bio)
        +			{
        +			struct bio_bio_st *other_b = other_bio->ptr;
        +			
        +			assert(other_b != NULL);
        +			ret = other_b->len == 0 && other_b->closed;
        +			}
        +		else
        +			ret = 1;
        +		}
        +		break;
        +
        +	default:
        +		ret = 0;
        +		}
        +	return ret;
        +	}
        +
        +static int bio_puts(BIO *bio, const char *str)
        +	{
        +	return bio_write(bio, str, strlen(str));
        +	}
        +
        +
        +static int bio_make_pair(BIO *bio1, BIO *bio2)
        +	{
        +	struct bio_bio_st *b1, *b2;
        +
        +	assert(bio1 != NULL);
        +	assert(bio2 != NULL);
        +
        +	b1 = bio1->ptr;
        +	b2 = bio2->ptr;
        +	
        +	if (b1->peer != NULL || b2->peer != NULL)
        +		{
        +		BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
        +		return 0;
        +		}
        +	
        +	if (b1->buf == NULL)
        +		{
        +		b1->buf = OPENSSL_malloc(b1->size);
        +		if (b1->buf == NULL)
        +			{
        +			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		b1->len = 0;
        +		b1->offset = 0;
        +		}
        +	
        +	if (b2->buf == NULL)
        +		{
        +		b2->buf = OPENSSL_malloc(b2->size);
        +		if (b2->buf == NULL)
        +			{
        +			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		b2->len = 0;
        +		b2->offset = 0;
        +		}
        +	
        +	b1->peer = bio2;
        +	b1->closed = 0;
        +	b1->request = 0;
        +	b2->peer = bio1;
        +	b2->closed = 0;
        +	b2->request = 0;
        +
        +	bio1->init = 1;
        +	bio2->init = 1;
        +
        +	return 1;
        +	}
        +
        +static void bio_destroy_pair(BIO *bio)
        +	{
        +	struct bio_bio_st *b = bio->ptr;
        +
        +	if (b != NULL)
        +		{
        +		BIO *peer_bio = b->peer;
        +
        +		if (peer_bio != NULL)
        +			{
        +			struct bio_bio_st *peer_b = peer_bio->ptr;
        +
        +			assert(peer_b != NULL);
        +			assert(peer_b->peer == bio);
        +
        +			peer_b->peer = NULL;
        +			peer_bio->init = 0;
        +			assert(peer_b->buf != NULL);
        +			peer_b->len = 0;
        +			peer_b->offset = 0;
        +			
        +			b->peer = NULL;
        +			bio->init = 0;
        +			assert(b->buf != NULL);
        +			b->len = 0;
        +			b->offset = 0;
        +			}
        +		}
        +	}
        + 
        +
        +/* Exported convenience functions */
        +int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
        +	BIO **bio2_p, size_t writebuf2)
        +	 {
        +	 BIO *bio1 = NULL, *bio2 = NULL;
        +	 long r;
        +	 int ret = 0;
        +
        +	 bio1 = BIO_new(BIO_s_bio());
        +	 if (bio1 == NULL)
        +		 goto err;
        +	 bio2 = BIO_new(BIO_s_bio());
        +	 if (bio2 == NULL)
        +		 goto err;
        +
        +	 if (writebuf1)
        +		 {
        +		 r = BIO_set_write_buf_size(bio1, writebuf1);
        +		 if (!r)
        +			 goto err;
        +		 }
        +	 if (writebuf2)
        +		 {
        +		 r = BIO_set_write_buf_size(bio2, writebuf2);
        +		 if (!r)
        +			 goto err;
        +		 }
        +
        +	 r = BIO_make_bio_pair(bio1, bio2);
        +	 if (!r)
        +		 goto err;
        +	 ret = 1;
        +
        + err:
        +	 if (ret == 0)
        +		 {
        +		 if (bio1)
        +			 {
        +			 BIO_free(bio1);
        +			 bio1 = NULL;
        +			 }
        +		 if (bio2)
        +			 {
        +			 BIO_free(bio2);
        +			 bio2 = NULL;
        +			 }
        +		 }
        +
        +	 *bio1_p = bio1;
        +	 *bio2_p = bio2;
        +	 return ret;
        +	 }
        +
        +size_t BIO_ctrl_get_write_guarantee(BIO *bio)
        +	{
        +	return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
        +	}
        +
        +size_t BIO_ctrl_get_read_request(BIO *bio)
        +	{
        +	return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
        +	}
        +
        +int BIO_ctrl_reset_read_request(BIO *bio)
        +	{
        +	return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
        +	}
        +
        +
        +/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
        + * (conceivably some other BIOs could allow non-copying reads and writes too.)
        + */
        +int BIO_nread0(BIO *bio, char **buf)
        +	{
        +	long ret;
        +
        +	if (!bio->init)
        +		{
        +		BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
        +		return -2;
        +		}
        +
        +	ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
        +	if (ret > INT_MAX)
        +		return INT_MAX;
        +	else
        +		return (int) ret;
        +	}
        +
        +int BIO_nread(BIO *bio, char **buf, int num)
        +	{
        +	int ret;
        +
        +	if (!bio->init)
        +		{
        +		BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
        +		return -2;
        +		}
        +
        +	ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
        +	if (ret > 0)
        +		bio->num_read += ret;
        +	return ret;
        +	}
        +
        +int BIO_nwrite0(BIO *bio, char **buf)
        +	{
        +	long ret;
        +
        +	if (!bio->init)
        +		{
        +		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
        +		return -2;
        +		}
        +
        +	ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
        +	if (ret > INT_MAX)
        +		return INT_MAX;
        +	else
        +		return (int) ret;
        +	}
        +
        +int BIO_nwrite(BIO *bio, char **buf, int num)
        +	{
        +	int ret;
        +
        +	if (!bio->init)
        +		{
        +		BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
        +		return -2;
        +		}
        +
        +	ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
        +	if (ret > 0)
        +		bio->num_write += ret;
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_conn.c b/vendor/openssl/openssl/crypto/bio/bss_conn.c
        new file mode 100644
        index 000000000..c14727855
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_conn.c
        @@ -0,0 +1,652 @@
        +/* crypto/bio/bss_conn.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +#ifndef OPENSSL_NO_SOCK
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
        +#else
        +#define SOCKET_PROTOCOL IPPROTO_TCP
        +#endif
        +
        +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
        +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
        +#undef FIONBIO
        +#endif
        +
        +
        +typedef struct bio_connect_st
        +	{
        +	int state;
        +
        +	char *param_hostname;
        +	char *param_port;
        +	int nbio;
        +
        +	unsigned char ip[4];
        +	unsigned short port;
        +
        +	struct sockaddr_in them;
        +
        +	/* int socket; this will be kept in bio->num so that it is
        +	 * compatible with the bss_sock bio */ 
        +
        +	/* called when the connection is initially made
        +	 *  callback(BIO,state,ret);  The callback should return
        +	 * 'ret'.  state is for compatibility with the ssl info_callback */
        +	int (*info_callback)(const BIO *bio,int state,int ret);
        +	} BIO_CONNECT;
        +
        +static int conn_write(BIO *h, const char *buf, int num);
        +static int conn_read(BIO *h, char *buf, int size);
        +static int conn_puts(BIO *h, const char *str);
        +static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int conn_new(BIO *h);
        +static int conn_free(BIO *data);
        +static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
        +
        +static int conn_state(BIO *b, BIO_CONNECT *c);
        +static void conn_close_socket(BIO *data);
        +BIO_CONNECT *BIO_CONNECT_new(void );
        +void BIO_CONNECT_free(BIO_CONNECT *a);
        +
        +static BIO_METHOD methods_connectp=
        +	{
        +	BIO_TYPE_CONNECT,
        +	"socket connect",
        +	conn_write,
        +	conn_read,
        +	conn_puts,
        +	NULL, /* connect_gets, */
        +	conn_ctrl,
        +	conn_new,
        +	conn_free,
        +	conn_callback_ctrl,
        +	};
        +
        +static int conn_state(BIO *b, BIO_CONNECT *c)
        +	{
        +	int ret= -1,i;
        +	unsigned long l;
        +	char *p,*q;
        +	int (*cb)(const BIO *,int,int)=NULL;
        +
        +	if (c->info_callback != NULL)
        +		cb=c->info_callback;
        +
        +	for (;;)
        +		{
        +		switch (c->state)
        +			{
        +		case BIO_CONN_S_BEFORE:
        +			p=c->param_hostname;
        +			if (p == NULL)
        +				{
        +				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED);
        +				goto exit_loop;
        +				}
        +			for ( ; *p != '\0'; p++)
        +				{
        +				if ((*p == ':') || (*p == '/')) break;
        +				}
        +
        +			i= *p;
        +			if ((i == ':') || (i == '/'))
        +				{
        +
        +				*(p++)='\0';
        +				if (i == ':')
        +					{
        +					for (q=p; *q; q++)
        +						if (*q == '/')
        +							{
        +							*q='\0';
        +							break;
        +							}
        +					if (c->param_port != NULL)
        +						OPENSSL_free(c->param_port);
        +					c->param_port=BUF_strdup(p);
        +					}
        +				}
        +
        +			if (c->param_port == NULL)
        +				{
        +				BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED);
        +				ERR_add_error_data(2,"host=",c->param_hostname);
        +				goto exit_loop;
        +				}
        +			c->state=BIO_CONN_S_GET_IP;
        +			break;
        +
        +		case BIO_CONN_S_GET_IP:
        +			if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0)
        +				goto exit_loop;
        +			c->state=BIO_CONN_S_GET_PORT;
        +			break;
        +
        +		case BIO_CONN_S_GET_PORT:
        +			if (c->param_port == NULL)
        +				{
        +				/* abort(); */
        +				goto exit_loop;
        +				}
        +			else if (BIO_get_port(c->param_port,&c->port) <= 0)
        +				goto exit_loop;
        +			c->state=BIO_CONN_S_CREATE_SOCKET;
        +			break;
        +
        +		case BIO_CONN_S_CREATE_SOCKET:
        +			/* now setup address */
        +			memset((char *)&c->them,0,sizeof(c->them));
        +			c->them.sin_family=AF_INET;
        +			c->them.sin_port=htons((unsigned short)c->port);
        +			l=(unsigned long)
        +				((unsigned long)c->ip[0]<<24L)|
        +				((unsigned long)c->ip[1]<<16L)|
        +				((unsigned long)c->ip[2]<< 8L)|
        +				((unsigned long)c->ip[3]);
        +			c->them.sin_addr.s_addr=htonl(l);
        +			c->state=BIO_CONN_S_CREATE_SOCKET;
        +
        +			ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
        +			if (ret == INVALID_SOCKET)
        +				{
        +				SYSerr(SYS_F_SOCKET,get_last_socket_error());
        +				ERR_add_error_data(4,"host=",c->param_hostname,
        +					":",c->param_port);
        +				BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET);
        +				goto exit_loop;
        +				}
        +			b->num=ret;
        +			c->state=BIO_CONN_S_NBIO;
        +			break;
        +
        +		case BIO_CONN_S_NBIO:
        +			if (c->nbio)
        +				{
        +				if (!BIO_socket_nbio(b->num,1))
        +					{
        +					BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO);
        +					ERR_add_error_data(4,"host=",
        +						c->param_hostname,
        +						":",c->param_port);
        +					goto exit_loop;
        +					}
        +				}
        +			c->state=BIO_CONN_S_CONNECT;
        +
        +#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
        +			i=1;
        +			i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
        +			if (i < 0)
        +				{
        +				SYSerr(SYS_F_SOCKET,get_last_socket_error());
        +				ERR_add_error_data(4,"host=",c->param_hostname,
        +					":",c->param_port);
        +				BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE);
        +				goto exit_loop;
        +				}
        +#endif
        +			break;
        +
        +		case BIO_CONN_S_CONNECT:
        +			BIO_clear_retry_flags(b);
        +			ret=connect(b->num,
        +				(struct sockaddr *)&c->them,
        +				sizeof(c->them));
        +			b->retry_reason=0;
        +			if (ret < 0)
        +				{
        +				if (BIO_sock_should_retry(ret))
        +					{
        +					BIO_set_retry_special(b);
        +					c->state=BIO_CONN_S_BLOCKED_CONNECT;
        +					b->retry_reason=BIO_RR_CONNECT;
        +					}
        +				else
        +					{
        +					SYSerr(SYS_F_CONNECT,get_last_socket_error());
        +					ERR_add_error_data(4,"host=",
        +						c->param_hostname,
        +						":",c->param_port);
        +					BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR);
        +					}
        +				goto exit_loop;
        +				}
        +			else
        +				c->state=BIO_CONN_S_OK;
        +			break;
        +
        +		case BIO_CONN_S_BLOCKED_CONNECT:
        +			i=BIO_sock_error(b->num);
        +			if (i)
        +				{
        +				BIO_clear_retry_flags(b);
        +				SYSerr(SYS_F_CONNECT,i);
        +				ERR_add_error_data(4,"host=",
        +					c->param_hostname,
        +					":",c->param_port);
        +				BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR);
        +				ret=0;
        +				goto exit_loop;
        +				}
        +			else
        +				c->state=BIO_CONN_S_OK;
        +			break;
        +
        +		case BIO_CONN_S_OK:
        +			ret=1;
        +			goto exit_loop;
        +		default:
        +			/* abort(); */
        +			goto exit_loop;
        +			}
        +
        +		if (cb != NULL)
        +			{
        +			if (!(ret=cb((BIO *)b,c->state,ret)))
        +				goto end;
        +			}
        +		}
        +
        +	/* Loop does not exit */
        +exit_loop:
        +	if (cb != NULL)
        +		ret=cb((BIO *)b,c->state,ret);
        +end:
        +	return(ret);
        +	}
        +
        +BIO_CONNECT *BIO_CONNECT_new(void)
        +	{
        +	BIO_CONNECT *ret;
        +
        +	if ((ret=(BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL)
        +		return(NULL);
        +	ret->state=BIO_CONN_S_BEFORE;
        +	ret->param_hostname=NULL;
        +	ret->param_port=NULL;
        +	ret->info_callback=NULL;
        +	ret->nbio=0;
        +	ret->ip[0]=0;
        +	ret->ip[1]=0;
        +	ret->ip[2]=0;
        +	ret->ip[3]=0;
        +	ret->port=0;
        +	memset((char *)&ret->them,0,sizeof(ret->them));
        +	return(ret);
        +	}
        +
        +void BIO_CONNECT_free(BIO_CONNECT *a)
        +	{
        +	if(a == NULL)
        +	    return;
        +
        +	if (a->param_hostname != NULL)
        +		OPENSSL_free(a->param_hostname);
        +	if (a->param_port != NULL)
        +		OPENSSL_free(a->param_port);
        +	OPENSSL_free(a);
        +	}
        +
        +BIO_METHOD *BIO_s_connect(void)
        +	{
        +	return(&methods_connectp);
        +	}
        +
        +static int conn_new(BIO *bi)
        +	{
        +	bi->init=0;
        +	bi->num=INVALID_SOCKET;
        +	bi->flags=0;
        +	if ((bi->ptr=(char *)BIO_CONNECT_new()) == NULL)
        +		return(0);
        +	else
        +		return(1);
        +	}
        +
        +static void conn_close_socket(BIO *bio)
        +	{
        +	BIO_CONNECT *c;
        +
        +	c=(BIO_CONNECT *)bio->ptr;
        +	if (bio->num != INVALID_SOCKET)
        +		{
        +		/* Only do a shutdown if things were established */
        +		if (c->state == BIO_CONN_S_OK)
        +			shutdown(bio->num,2);
        +		closesocket(bio->num);
        +		bio->num=INVALID_SOCKET;
        +		}
        +	}
        +
        +static int conn_free(BIO *a)
        +	{
        +	BIO_CONNECT *data;
        +
        +	if (a == NULL) return(0);
        +	data=(BIO_CONNECT *)a->ptr;
        +	 
        +	if (a->shutdown)
        +		{
        +		conn_close_socket(a);
        +		BIO_CONNECT_free(data);
        +		a->ptr=NULL;
        +		a->flags=0;
        +		a->init=0;
        +		}
        +	return(1);
        +	}
        +	
        +static int conn_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +	BIO_CONNECT *data;
        +
        +	data=(BIO_CONNECT *)b->ptr;
        +	if (data->state != BIO_CONN_S_OK)
        +		{
        +		ret=conn_state(b,data);
        +		if (ret <= 0)
        +				return(ret);
        +		}
        +
        +	if (out != NULL)
        +		{
        +		clear_socket_error();
        +		ret=readsocket(b->num,out,outl);
        +		BIO_clear_retry_flags(b);
        +		if (ret <= 0)
        +			{
        +			if (BIO_sock_should_retry(ret))
        +				BIO_set_retry_read(b);
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static int conn_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret;
        +	BIO_CONNECT *data;
        +
        +	data=(BIO_CONNECT *)b->ptr;
        +	if (data->state != BIO_CONN_S_OK)
        +		{
        +		ret=conn_state(b,data);
        +		if (ret <= 0) return(ret);
        +		}
        +
        +	clear_socket_error();
        +	ret=writesocket(b->num,in,inl);
        +	BIO_clear_retry_flags(b);
        +	if (ret <= 0)
        +		{
        +		if (BIO_sock_should_retry(ret))
        +			BIO_set_retry_write(b);
        +		}
        +	return(ret);
        +	}
        +
        +static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	BIO *dbio;
        +	int *ip;
        +	const char **pptr;
        +	long ret=1;
        +	BIO_CONNECT *data;
        +
        +	data=(BIO_CONNECT *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ret=0;
        +		data->state=BIO_CONN_S_BEFORE;
        +		conn_close_socket(b);
        +		b->flags=0;
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		/* use this one to start the connection */
        +		if (data->state != BIO_CONN_S_OK)
        +			ret=(long)conn_state(b,data);
        +		else
        +			ret=1;
        +		break;
        +	case BIO_C_GET_CONNECT:
        +		if (ptr != NULL)
        +			{
        +			pptr=(const char **)ptr;
        +			if (num == 0)
        +				{
        +				*pptr=data->param_hostname;
        +
        +				}
        +			else if (num == 1)
        +				{
        +				*pptr=data->param_port;
        +				}
        +			else if (num == 2)
        +				{
        +				*pptr= (char *)&(data->ip[0]);
        +				}
        +			else if (num == 3)
        +				{
        +				*((int *)ptr)=data->port;
        +				}
        +			if ((!b->init) || (ptr == NULL))
        +				*pptr="not initialized";
        +			ret=1;
        +			}
        +		break;
        +	case BIO_C_SET_CONNECT:
        +		if (ptr != NULL)
        +			{
        +			b->init=1;
        +			if (num == 0)
        +				{
        +				if (data->param_hostname != NULL)
        +					OPENSSL_free(data->param_hostname);
        +				data->param_hostname=BUF_strdup(ptr);
        +				}
        +			else if (num == 1)
        +				{
        +				if (data->param_port != NULL)
        +					OPENSSL_free(data->param_port);
        +				data->param_port=BUF_strdup(ptr);
        +				}
        +			else if (num == 2)
        +				{
        +				char buf[16];
        +				unsigned char *p = ptr;
        +
        +				BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d",
        +					     p[0],p[1],p[2],p[3]);
        +				if (data->param_hostname != NULL)
        +					OPENSSL_free(data->param_hostname);
        +				data->param_hostname=BUF_strdup(buf);
        +				memcpy(&(data->ip[0]),ptr,4);
        +				}
        +			else if (num == 3)
        +				{
        +				char buf[DECIMAL_SIZE(int)+1];
        +
        +				BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr);
        +				if (data->param_port != NULL)
        +					OPENSSL_free(data->param_port);
        +				data->param_port=BUF_strdup(buf);
        +				data->port= *(int *)ptr;
        +				}
        +			}
        +		break;
        +	case BIO_C_SET_NBIO:
        +		data->nbio=(int)num;
        +		break;
        +	case BIO_C_GET_FD:
        +		if (b->init)
        +			{
        +			ip=(int *)ptr;
        +			if (ip != NULL)
        +				*ip=b->num;
        +			ret=b->num;
        +			}
        +		else
        +			ret= -1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_WPENDING:
        +		ret=0;
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		break;
        +	case BIO_CTRL_DUP:
        +		{
        +		dbio=(BIO *)ptr;
        +		if (data->param_port)
        +			BIO_set_conn_port(dbio,data->param_port);
        +		if (data->param_hostname)
        +			BIO_set_conn_hostname(dbio,data->param_hostname);
        +		BIO_set_nbio(dbio,data->nbio);
        +		/* FIXME: the cast of the function seems unlikely to be a good idea */
        +                (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback);
        +		}
        +		break;
        +	case BIO_CTRL_SET_CALLBACK:
        +		{
        +#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
        +		BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		ret = -1;
        +#else
        +		ret=0;
        +#endif
        +		}
        +		break;
        +	case BIO_CTRL_GET_CALLBACK:
        +		{
        +		int (**fptr)(const BIO *bio,int state,int xret);
        +
        +		fptr=(int (**)(const BIO *bio,int state,int xret))ptr;
        +		*fptr=data->info_callback;
        +		}
        +		break;
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
        +	{
        +	long ret=1;
        +	BIO_CONNECT *data;
        +
        +	data=(BIO_CONNECT *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_SET_CALLBACK:
        +		{
        +		data->info_callback=(int (*)(const struct bio_st *, int, int))fp;
        +		}
        +		break;
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int conn_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=conn_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +BIO *BIO_new_connect(char *str)
        +	{
        +	BIO *ret;
        +
        +	ret=BIO_new(BIO_s_connect());
        +	if (ret == NULL) return(NULL);
        +	if (BIO_set_conn_hostname(ret,str))
        +		return(ret);
        +	else
        +		{
        +		BIO_free(ret);
        +		return(NULL);
        +		}
        +	}
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_dgram.c b/vendor/openssl/openssl/crypto/bio/bss_dgram.c
        new file mode 100644
        index 000000000..899090997
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_dgram.c
        @@ -0,0 +1,1865 @@
        +/* crypto/bio/bio_dgram.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "cryptlib.h"
        +
        +#include <openssl/bio.h>
        +#ifndef OPENSSL_NO_DGRAM
        +
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
        +#include <sys/timeb.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_SCTP
        +#include <netinet/sctp.h>
        +#include <fcntl.h>
        +#define OPENSSL_SCTP_DATA_CHUNK_TYPE            0x00
        +#define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
        +#endif
        +
        +#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
        +#define IP_MTU      14 /* linux is lame */
        +#endif
        +
        +#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
        +/* Standard definition causes type-punning problems. */
        +#undef IN6_IS_ADDR_V4MAPPED
        +#define s6_addr32 __u6_addr.__u6_addr32
        +#define IN6_IS_ADDR_V4MAPPED(a)               \
        +        (((a)->s6_addr32[0] == 0) &&          \
        +         ((a)->s6_addr32[1] == 0) &&          \
        +         ((a)->s6_addr32[2] == htonl(0x0000ffff)))
        +#endif
        +
        +#ifdef WATT32
        +#define sock_write SockWrite  /* Watt-32 uses same names */
        +#define sock_read  SockRead
        +#define sock_puts  SockPuts
        +#endif
        +
        +static int dgram_write(BIO *h, const char *buf, int num);
        +static int dgram_read(BIO *h, char *buf, int size);
        +static int dgram_puts(BIO *h, const char *str);
        +static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int dgram_new(BIO *h);
        +static int dgram_free(BIO *data);
        +static int dgram_clear(BIO *bio);
        +
        +#ifndef OPENSSL_NO_SCTP
        +static int dgram_sctp_write(BIO *h, const char *buf, int num);
        +static int dgram_sctp_read(BIO *h, char *buf, int size);
        +static int dgram_sctp_puts(BIO *h, const char *str);
        +static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int dgram_sctp_new(BIO *h);
        +static int dgram_sctp_free(BIO *data);
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp);
        +#endif
        +#endif
        +
        +static int BIO_dgram_should_retry(int s);
        +
        +static void get_current_time(struct timeval *t);
        +
        +static BIO_METHOD methods_dgramp=
        +	{
        +	BIO_TYPE_DGRAM,
        +	"datagram socket",
        +	dgram_write,
        +	dgram_read,
        +	dgram_puts,
        +	NULL, /* dgram_gets, */
        +	dgram_ctrl,
        +	dgram_new,
        +	dgram_free,
        +	NULL,
        +	};
        +
        +#ifndef OPENSSL_NO_SCTP
        +static BIO_METHOD methods_dgramp_sctp=
        +	{
        +	BIO_TYPE_DGRAM_SCTP,
        +	"datagram sctp socket",
        +	dgram_sctp_write,
        +	dgram_sctp_read,
        +	dgram_sctp_puts,
        +	NULL, /* dgram_gets, */
        +	dgram_sctp_ctrl,
        +	dgram_sctp_new,
        +	dgram_sctp_free,
        +	NULL,
        +	};
        +#endif
        +
        +typedef struct bio_dgram_data_st
        +	{
        +	union {
        +		struct sockaddr sa;
        +		struct sockaddr_in sa_in;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 sa_in6;
        +#endif
        +	} peer;
        +	unsigned int connected;
        +	unsigned int _errno;
        +	unsigned int mtu;
        +	struct timeval next_timeout;
        +	struct timeval socket_timeout;
        +	} bio_dgram_data;
        +
        +#ifndef OPENSSL_NO_SCTP
        +typedef struct bio_dgram_sctp_save_message_st
        +	{
        +        BIO *bio;
        +        char *data;
        +        int length;
        +	} bio_dgram_sctp_save_message;
        +
        +typedef struct bio_dgram_sctp_data_st
        +	{
        +	union {
        +		struct sockaddr sa;
        +		struct sockaddr_in sa_in;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 sa_in6;
        +#endif
        +	} peer;
        +	unsigned int connected;
        +	unsigned int _errno;
        +	unsigned int mtu;
        +	struct bio_dgram_sctp_sndinfo sndinfo;
        +	struct bio_dgram_sctp_rcvinfo rcvinfo;
        +	struct bio_dgram_sctp_prinfo prinfo;
        +	void (*handle_notifications)(BIO *bio, void *context, void *buf);
        +	void* notification_context;
        +	int in_handshake;
        +	int ccs_rcvd;
        +	int ccs_sent;
        +	int save_shutdown;
        +	int peer_auth_tested;
        +	bio_dgram_sctp_save_message saved_message;
        +	} bio_dgram_sctp_data;
        +#endif
        +
        +BIO_METHOD *BIO_s_datagram(void)
        +	{
        +	return(&methods_dgramp);
        +	}
        +
        +BIO *BIO_new_dgram(int fd, int close_flag)
        +	{
        +	BIO *ret;
        +
        +	ret=BIO_new(BIO_s_datagram());
        +	if (ret == NULL) return(NULL);
        +	BIO_set_fd(ret,fd,close_flag);
        +	return(ret);
        +	}
        +
        +static int dgram_new(BIO *bi)
        +	{
        +	bio_dgram_data *data = NULL;
        +
        +	bi->init=0;
        +	bi->num=0;
        +	data = OPENSSL_malloc(sizeof(bio_dgram_data));
        +	if (data == NULL)
        +		return 0;
        +	memset(data, 0x00, sizeof(bio_dgram_data));
        +    bi->ptr = data;
        +
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int dgram_free(BIO *a)
        +	{
        +	bio_dgram_data *data;
        +
        +	if (a == NULL) return(0);
        +	if ( ! dgram_clear(a))
        +		return 0;
        +
        +	data = (bio_dgram_data *)a->ptr;
        +	if(data != NULL) OPENSSL_free(data);
        +
        +	return(1);
        +	}
        +
        +static int dgram_clear(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	if (a->shutdown)
        +		{
        +		if (a->init)
        +			{
        +			SHUTDOWN2(a->num);
        +			}
        +		a->init=0;
        +		a->flags=0;
        +		}
        +	return(1);
        +	}
        +
        +static void dgram_adjust_rcv_timeout(BIO *b)
        +	{
        +#if defined(SO_RCVTIMEO)
        +	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
        +	union { size_t s; int i; } sz = {0};
        +
        +	/* Is a timer active? */
        +	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
        +		{
        +		struct timeval timenow, timeleft;
        +
        +		/* Read current socket timeout */
        +#ifdef OPENSSL_SYS_WINDOWS
        +		int timeout;
        +
        +		sz.i = sizeof(timeout);
        +		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
        +					   (void*)&timeout, &sz.i) < 0)
        +			{ perror("getsockopt"); }
        +		else
        +			{
        +			data->socket_timeout.tv_sec = timeout / 1000;
        +			data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
        +			}
        +#else
        +		sz.i = sizeof(data->socket_timeout);
        +		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
        +						&(data->socket_timeout), (void *)&sz) < 0)
        +			{ perror("getsockopt"); }
        +		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
        +			OPENSSL_assert(sz.s<=sizeof(data->socket_timeout));
        +#endif
        +
        +		/* Get current time */
        +		get_current_time(&timenow);
        +
        +		/* Calculate time left until timer expires */
        +		memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
        +		timeleft.tv_sec -= timenow.tv_sec;
        +		timeleft.tv_usec -= timenow.tv_usec;
        +		if (timeleft.tv_usec < 0)
        +			{
        +			timeleft.tv_sec--;
        +			timeleft.tv_usec += 1000000;
        +			}
        +
        +		if (timeleft.tv_sec < 0)
        +			{
        +			timeleft.tv_sec = 0;
        +			timeleft.tv_usec = 1;
        +			}
        +
        +		/* Adjust socket timeout if next handhake message timer
        +		 * will expire earlier.
        +		 */
        +		if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) ||
        +			(data->socket_timeout.tv_sec > timeleft.tv_sec) ||
        +			(data->socket_timeout.tv_sec == timeleft.tv_sec &&
        +			 data->socket_timeout.tv_usec >= timeleft.tv_usec))
        +			{
        +#ifdef OPENSSL_SYS_WINDOWS
        +			timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
        +			if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
        +						   (void*)&timeout, sizeof(timeout)) < 0)
        +				{ perror("setsockopt"); }
        +#else
        +			if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
        +							sizeof(struct timeval)) < 0)
        +				{ perror("setsockopt"); }
        +#endif
        +			}
        +		}
        +#endif
        +	}
        +
        +static void dgram_reset_rcv_timeout(BIO *b)
        +	{
        +#if defined(SO_RCVTIMEO)
        +	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
        +
        +	/* Is a timer active? */
        +	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
        +		{
        +#ifdef OPENSSL_SYS_WINDOWS
        +		int timeout = data->socket_timeout.tv_sec * 1000 +
        +					  data->socket_timeout.tv_usec / 1000;
        +		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
        +					   (void*)&timeout, sizeof(timeout)) < 0)
        +			{ perror("setsockopt"); }
        +#else
        +		if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
        +						sizeof(struct timeval)) < 0)
        +			{ perror("setsockopt"); }
        +#endif
        +		}
        +#endif
        +	}
        +
        +static int dgram_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
        +
        +	struct	{
        +	/*
        +	 * See commentary in b_sock.c. <appro>
        +	 */
        +	union	{ size_t s; int i; } len;
        +	union	{
        +		struct sockaddr sa;
        +		struct sockaddr_in sa_in;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 sa_in6;
        +#endif
        +		} peer;
        +	} sa;
        +
        +	sa.len.s=0;
        +	sa.len.i=sizeof(sa.peer);
        +
        +	if (out != NULL)
        +		{
        +		clear_socket_error();
        +		memset(&sa.peer, 0x00, sizeof(sa.peer));
        +		dgram_adjust_rcv_timeout(b);
        +		ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len);
        +		if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
        +			{
        +			OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
        +			sa.len.i = (int)sa.len.s;
        +			}
        +
        +		if ( ! data->connected  && ret >= 0)
        +			BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
        +
        +		BIO_clear_retry_flags(b);
        +		if (ret < 0)
        +			{
        +			if (BIO_dgram_should_retry(ret))
        +				{
        +				BIO_set_retry_read(b);
        +				data->_errno = get_last_socket_error();
        +				}
        +			}
        +
        +		dgram_reset_rcv_timeout(b);
        +		}
        +	return(ret);
        +	}
        +
        +static int dgram_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret;
        +	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
        +	clear_socket_error();
        +
        +	if ( data->connected )
        +		ret=writesocket(b->num,in,inl);
        +	else
        +		{
        +		int peerlen = sizeof(data->peer);
        +
        +		if (data->peer.sa.sa_family == AF_INET)
        +			peerlen = sizeof(data->peer.sa_in);
        +#if OPENSSL_USE_IPV6
        +		else if (data->peer.sa.sa_family == AF_INET6)
        +			peerlen = sizeof(data->peer.sa_in6);
        +#endif
        +#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
        +		ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
        +#else
        +		ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
        +#endif
        +		}
        +
        +	BIO_clear_retry_flags(b);
        +	if (ret <= 0)
        +		{
        +		if (BIO_dgram_should_retry(ret))
        +			{
        +			BIO_set_retry_write(b);  
        +			data->_errno = get_last_socket_error();
        +
        +#if 0 /* higher layers are responsible for querying MTU, if necessary */
        +			if ( data->_errno == EMSGSIZE)
        +				/* retrieve the new MTU */
        +				BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
        +#endif
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +	int *ip;
        +	struct sockaddr *to = NULL;
        +	bio_dgram_data *data = NULL;
        +#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
        +	int sockopt_val = 0;
        +	socklen_t sockopt_len;	/* assume that system supporting IP_MTU is
        +				 * modern enough to define socklen_t */
        +	socklen_t addr_len;
        +	union	{
        +		struct sockaddr	sa;
        +		struct sockaddr_in s4;
        +#if OPENSSL_USE_IPV6
        +		struct sockaddr_in6 s6;
        +#endif
        +		} addr;
        +#endif
        +
        +	data = (bio_dgram_data *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		num=0;
        +	case BIO_C_FILE_SEEK:
        +		ret=0;
        +		break;
        +	case BIO_C_FILE_TELL:
        +	case BIO_CTRL_INFO:
        +		ret=0;
        +		break;
        +	case BIO_C_SET_FD:
        +		dgram_clear(b);
        +		b->num= *((int *)ptr);
        +		b->shutdown=(int)num;
        +		b->init=1;
        +		break;
        +	case BIO_C_GET_FD:
        +		if (b->init)
        +			{
        +			ip=(int *)ptr;
        +			if (ip != NULL) *ip=b->num;
        +			ret=b->num;
        +			}
        +		else
        +			ret= -1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_WPENDING:
        +		ret=0;
        +		break;
        +	case BIO_CTRL_DUP:
        +	case BIO_CTRL_FLUSH:
        +		ret=1;
        +		break;
        +	case BIO_CTRL_DGRAM_CONNECT:
        +		to = (struct sockaddr *)ptr;
        +#if 0
        +		if (connect(b->num, to, sizeof(struct sockaddr)) < 0)
        +			{ perror("connect"); ret = 0; }
        +		else
        +			{
        +#endif
        +			switch (to->sa_family)
        +				{
        +				case AF_INET:
        +					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
        +					break;
        +#if OPENSSL_USE_IPV6
        +				case AF_INET6:
        +					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
        +					break;
        +#endif
        +				default:
        +					memcpy(&data->peer,to,sizeof(data->peer.sa));
        +					break;
        +				}
        +#if 0
        +			}
        +#endif
        +		break;
        +		/* (Linux)kernel sets DF bit on outgoing IP packets */
        +	case BIO_CTRL_DGRAM_MTU_DISCOVER:
        +#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
        +		addr_len = (socklen_t)sizeof(addr);
        +		memset((void *)&addr, 0, sizeof(addr));
        +		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
        +			{
        +			ret = 0;
        +			break;
        +			}
        +		switch (addr.sa.sa_family)
        +			{
        +		case AF_INET:
        +			sockopt_val = IP_PMTUDISC_DO;
        +			if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
        +				&sockopt_val, sizeof(sockopt_val))) < 0)
        +				perror("setsockopt");
        +			break;
        +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
        +		case AF_INET6:
        +			sockopt_val = IPV6_PMTUDISC_DO;
        +			if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
        +				&sockopt_val, sizeof(sockopt_val))) < 0)
        +				perror("setsockopt");
        +			break;
        +#endif
        +		default:
        +			ret = -1;
        +			break;
        +			}
        +		ret = -1;
        +#else
        +		break;
        +#endif
        +	case BIO_CTRL_DGRAM_QUERY_MTU:
        +#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
        +		addr_len = (socklen_t)sizeof(addr);
        +		memset((void *)&addr, 0, sizeof(addr));
        +		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
        +			{
        +			ret = 0;
        +			break;
        +			}
        +		sockopt_len = sizeof(sockopt_val);
        +		switch (addr.sa.sa_family)
        +			{
        +		case AF_INET:
        +			if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
        +				&sockopt_len)) < 0 || sockopt_val < 0)
        +				{
        +				ret = 0;
        +				}
        +			else
        +				{
        +				/* we assume that the transport protocol is UDP and no
        +				 * IP options are used.
        +				 */
        +				data->mtu = sockopt_val - 8 - 20;
        +				ret = data->mtu;
        +				}
        +			break;
        +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
        +		case AF_INET6:
        +			if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
        +				&sockopt_len)) < 0 || sockopt_val < 0)
        +				{
        +				ret = 0;
        +				}
        +			else
        +				{
        +				/* we assume that the transport protocol is UDP and no
        +				 * IPV6 options are used.
        +				 */
        +				data->mtu = sockopt_val - 8 - 40;
        +				ret = data->mtu;
        +				}
        +			break;
        +#endif
        +		default:
        +			ret = 0;
        +			break;
        +			}
        +#else
        +		ret = 0;
        +#endif
        +		break;
        +	case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
        +		switch (data->peer.sa.sa_family)
        +			{
        +			case AF_INET:
        +				ret = 576 - 20 - 8;
        +				break;
        +#if OPENSSL_USE_IPV6
        +			case AF_INET6:
        +#ifdef IN6_IS_ADDR_V4MAPPED
        +				if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
        +					ret = 576 - 20 - 8;
        +				else
        +#endif
        +					ret = 1280 - 40 - 8;
        +				break;
        +#endif
        +			default:
        +				ret = 576 - 20 - 8;
        +				break;
        +			}
        +		break;
        +	case BIO_CTRL_DGRAM_GET_MTU:
        +		return data->mtu;
        +		break;
        +	case BIO_CTRL_DGRAM_SET_MTU:
        +		data->mtu = num;
        +		ret = num;
        +		break;
        +	case BIO_CTRL_DGRAM_SET_CONNECTED:
        +		to = (struct sockaddr *)ptr;
        +
        +		if ( to != NULL)
        +			{
        +			data->connected = 1;
        +			switch (to->sa_family)
        +				{
        +				case AF_INET:
        +					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
        +					break;
        +#if OPENSSL_USE_IPV6
        +				case AF_INET6:
        +					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
        +					break;
        +#endif
        +				default:
        +					memcpy(&data->peer,to,sizeof(data->peer.sa));
        +					break;
        +				}
        +			}
        +		else
        +			{
        +			data->connected = 0;
        +			memset(&(data->peer), 0x00, sizeof(data->peer));
        +			}
        +		break;
        +	case BIO_CTRL_DGRAM_GET_PEER:
        +		switch (data->peer.sa.sa_family)
        +			{
        +			case AF_INET:
        +				ret=sizeof(data->peer.sa_in);
        +				break;
        +#if OPENSSL_USE_IPV6
        +			case AF_INET6:
        +				ret=sizeof(data->peer.sa_in6);
        +				break;
        +#endif
        +			default:
        +				ret=sizeof(data->peer.sa);
        +				break;
        +			}
        +		if (num==0 || num>ret)
        +			num=ret;
        +		memcpy(ptr,&data->peer,(ret=num));
        +		break;
        +	case BIO_CTRL_DGRAM_SET_PEER:
        +		to = (struct sockaddr *) ptr;
        +		switch (to->sa_family)
        +			{
        +			case AF_INET:
        +				memcpy(&data->peer,to,sizeof(data->peer.sa_in));
        +				break;
        +#if OPENSSL_USE_IPV6
        +			case AF_INET6:
        +				memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
        +				break;
        +#endif
        +			default:
        +				memcpy(&data->peer,to,sizeof(data->peer.sa));
        +				break;
        +			}
        +		break;
        +	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
        +		memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
        +		break;
        +#if defined(SO_RCVTIMEO)
        +	case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
        +#ifdef OPENSSL_SYS_WINDOWS
        +		{
        +		struct timeval *tv = (struct timeval *)ptr;
        +		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
        +		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
        +			(void*)&timeout, sizeof(timeout)) < 0)
        +			{ perror("setsockopt"); ret = -1; }
        +		}
        +#else
        +		if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
        +			sizeof(struct timeval)) < 0)
        +			{ perror("setsockopt");	ret = -1; }
        +#endif
        +		break;
        +	case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
        +		{
        +		union { size_t s; int i; } sz = {0};
        +#ifdef OPENSSL_SYS_WINDOWS
        +		int timeout;
        +		struct timeval *tv = (struct timeval *)ptr;
        +
        +		sz.i = sizeof(timeout);
        +		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
        +			(void*)&timeout, &sz.i) < 0)
        +			{ perror("getsockopt"); ret = -1; }
        +		else
        +			{
        +			tv->tv_sec = timeout / 1000;
        +			tv->tv_usec = (timeout % 1000) * 1000;
        +			ret = sizeof(*tv);
        +			}
        +#else
        +		sz.i = sizeof(struct timeval);
        +		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
        +			ptr, (void *)&sz) < 0)
        +			{ perror("getsockopt"); ret = -1; }
        +		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
        +			{
        +			OPENSSL_assert(sz.s<=sizeof(struct timeval));
        +			ret = (int)sz.s;
        +			}
        +		else
        +			ret = sz.i;
        +#endif
        +		}
        +		break;
        +#endif
        +#if defined(SO_SNDTIMEO)
        +	case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
        +#ifdef OPENSSL_SYS_WINDOWS
        +		{
        +		struct timeval *tv = (struct timeval *)ptr;
        +		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
        +		if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
        +			(void*)&timeout, sizeof(timeout)) < 0)
        +			{ perror("setsockopt"); ret = -1; }
        +		}
        +#else
        +		if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
        +			sizeof(struct timeval)) < 0)
        +			{ perror("setsockopt");	ret = -1; }
        +#endif
        +		break;
        +	case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
        +		{
        +		union { size_t s; int i; } sz = {0};
        +#ifdef OPENSSL_SYS_WINDOWS
        +		int timeout;
        +		struct timeval *tv = (struct timeval *)ptr;
        +
        +		sz.i = sizeof(timeout);
        +		if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
        +			(void*)&timeout, &sz.i) < 0)
        +			{ perror("getsockopt"); ret = -1; }
        +		else
        +			{
        +			tv->tv_sec = timeout / 1000;
        +			tv->tv_usec = (timeout % 1000) * 1000;
        +			ret = sizeof(*tv);
        +			}
        +#else
        +		sz.i = sizeof(struct timeval);
        +		if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 
        +			ptr, (void *)&sz) < 0)
        +			{ perror("getsockopt"); ret = -1; }
        +		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
        +			{
        +			OPENSSL_assert(sz.s<=sizeof(struct timeval));
        +			ret = (int)sz.s;
        +			}
        +		else
        +			ret = sz.i;
        +#endif
        +		}
        +		break;
        +#endif
        +	case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
        +		/* fall-through */
        +	case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
        +#ifdef OPENSSL_SYS_WINDOWS
        +		if ( data->_errno == WSAETIMEDOUT)
        +#else
        +		if ( data->_errno == EAGAIN)
        +#endif
        +			{
        +			ret = 1;
        +			data->_errno = 0;
        +			}
        +		else
        +			ret = 0;
        +		break;
        +#ifdef EMSGSIZE
        +	case BIO_CTRL_DGRAM_MTU_EXCEEDED:
        +		if ( data->_errno == EMSGSIZE)
        +			{
        +			ret = 1;
        +			data->_errno = 0;
        +			}
        +		else
        +			ret = 0;
        +		break;
        +#endif
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int dgram_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=dgram_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_SCTP
        +BIO_METHOD *BIO_s_datagram_sctp(void)
        +	{
        +	return(&methods_dgramp_sctp);
        +	}
        +
        +BIO *BIO_new_dgram_sctp(int fd, int close_flag)
        +	{
        +	BIO *bio;
        +	int ret, optval = 20000;
        +	int auth_data = 0, auth_forward = 0;
        +	unsigned char *p;
        +	struct sctp_authchunk auth;
        +	struct sctp_authchunks *authchunks;
        +	socklen_t sockopt_len;
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +#ifdef SCTP_EVENT
        +	struct sctp_event event;
        +#else
        +	struct sctp_event_subscribe event;
        +#endif
        +#endif
        +
        +	bio=BIO_new(BIO_s_datagram_sctp());
        +	if (bio == NULL) return(NULL);
        +	BIO_set_fd(bio,fd,close_flag);
        +
        +	/* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
        +	auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
        +	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
        +	OPENSSL_assert(ret >= 0);
        +	auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
        +	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
        +	OPENSSL_assert(ret >= 0);
        +
        +	/* Test if activation was successful. When using accept(),
        +	 * SCTP-AUTH has to be activated for the listening socket
        +	 * already, otherwise the connected socket won't use it. */
        +	sockopt_len = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
        +	authchunks = OPENSSL_malloc(sockopt_len);
        +	memset(authchunks, 0, sizeof(sockopt_len));
        +	ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len);
        +	OPENSSL_assert(ret >= 0);
        +	
        +	for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
        +	     p < (unsigned char*) authchunks + sockopt_len;
        +	     p += sizeof(uint8_t))
        +		{
        +		if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
        +		if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
        +		}
        +		
        +	OPENSSL_free(authchunks);
        +
        +	OPENSSL_assert(auth_data);
        +	OPENSSL_assert(auth_forward);
        +
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +#ifdef SCTP_EVENT
        +	memset(&event, 0, sizeof(struct sctp_event));
        +	event.se_assoc_id = 0;
        +	event.se_type = SCTP_AUTHENTICATION_EVENT;
        +	event.se_on = 1;
        +	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
        +	OPENSSL_assert(ret >= 0);
        +#else
        +	sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
        +	ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
        +	OPENSSL_assert(ret >= 0);
        +
        +	event.sctp_authentication_event = 1;
        +
        +	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
        +	OPENSSL_assert(ret >= 0);
        +#endif
        +#endif
        +
        +	/* Disable partial delivery by setting the min size
        +	 * larger than the max record size of 2^14 + 2048 + 13
        +	 */
        +	ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval));
        +	OPENSSL_assert(ret >= 0);
        +
        +	return(bio);
        +	}
        +
        +int BIO_dgram_is_sctp(BIO *bio)
        +	{
        +	return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
        +	}
        +
        +static int dgram_sctp_new(BIO *bi)
        +	{
        +	bio_dgram_sctp_data *data = NULL;
        +
        +	bi->init=0;
        +	bi->num=0;
        +	data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data));
        +	if (data == NULL)
        +		return 0;
        +	memset(data, 0x00, sizeof(bio_dgram_sctp_data));
        +#ifdef SCTP_PR_SCTP_NONE
        +	data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
        +#endif
        +    bi->ptr = data;
        +
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int dgram_sctp_free(BIO *a)
        +	{
        +	bio_dgram_sctp_data *data;
        +
        +	if (a == NULL) return(0);
        +	if ( ! dgram_clear(a))
        +		return 0;
        +
        +	data = (bio_dgram_sctp_data *)a->ptr;
        +	if(data != NULL) OPENSSL_free(data);
        +
        +	return(1);
        +	}
        +
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
        +	{
        +	int ret;
        +	struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
        +
        +	if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY)
        +		{
        +		struct sctp_authkeyid authkeyid;
        +
        +		/* delete key */
        +		authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
        +		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
        +		      &authkeyid, sizeof(struct sctp_authkeyid));
        +		}
        +	}
        +#endif
        +
        +static int dgram_sctp_read(BIO *b, char *out, int outl)
        +	{
        +	int ret = 0, n = 0, i, optval;
        +	socklen_t optlen;
        +	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
        +	union sctp_notification *snp;
        +	struct msghdr msg;
        +	struct iovec iov;
        +	struct cmsghdr *cmsg;
        +	char cmsgbuf[512];
        +
        +	if (out != NULL)
        +		{
        +		clear_socket_error();
        +
        +		do
        +			{
        +			memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
        +			iov.iov_base = out;
        +			iov.iov_len = outl;
        +			msg.msg_name = NULL;
        +			msg.msg_namelen = 0;
        +			msg.msg_iov = &iov;
        +			msg.msg_iovlen = 1;
        +			msg.msg_control = cmsgbuf;
        +			msg.msg_controllen = 512;
        +			msg.msg_flags = 0;
        +			n = recvmsg(b->num, &msg, 0);
        +
        +			if (msg.msg_controllen > 0)
        +				{
        +				for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
        +					{
        +					if (cmsg->cmsg_level != IPPROTO_SCTP)
        +						continue;
        +#ifdef SCTP_RCVINFO
        +					if (cmsg->cmsg_type == SCTP_RCVINFO)
        +						{
        +						struct sctp_rcvinfo *rcvinfo;
        +
        +						rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
        +						data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
        +						data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
        +						data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
        +						data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
        +						data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
        +						data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
        +						data->rcvinfo.rcv_context = rcvinfo->rcv_context;
        +						}
        +#endif
        +#ifdef SCTP_SNDRCV
        +					if (cmsg->cmsg_type == SCTP_SNDRCV)
        +						{
        +						struct sctp_sndrcvinfo *sndrcvinfo;
        +
        +						sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
        +						data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
        +						data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
        +						data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
        +						data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
        +						data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
        +						data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
        +						data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
        +						}
        +#endif
        +					}
        +				}
        +
        +			if (n <= 0)
        +				{
        +				if (n < 0)
        +					ret = n;
        +				break;
        +				}
        +
        +			if (msg.msg_flags & MSG_NOTIFICATION)
        +				{
        +				snp = (union sctp_notification*) out;
        +				if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
        +					{
        +#ifdef SCTP_EVENT
        +					struct sctp_event event;
        +#else
        +					struct sctp_event_subscribe event;
        +					socklen_t eventsize;
        +#endif
        +					/* If a message has been delayed until the socket
        +					 * is dry, it can be sent now.
        +					 */
        +					if (data->saved_message.length > 0)
        +						{
        +						dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
        +						                 data->saved_message.length);
        +						OPENSSL_free(data->saved_message.data);
        +						data->saved_message.length = 0;
        +						}
        +
        +					/* disable sender dry event */
        +#ifdef SCTP_EVENT
        +					memset(&event, 0, sizeof(struct sctp_event));
        +					event.se_assoc_id = 0;
        +					event.se_type = SCTP_SENDER_DRY_EVENT;
        +					event.se_on = 0;
        +					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
        +					OPENSSL_assert(i >= 0);
        +#else
        +					eventsize = sizeof(struct sctp_event_subscribe);
        +					i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
        +					OPENSSL_assert(i >= 0);
        +
        +					event.sctp_sender_dry_event = 0;
        +
        +					i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
        +					OPENSSL_assert(i >= 0);
        +#endif
        +					}
        +
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +				if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
        +					dgram_sctp_handle_auth_free_key_event(b, snp);
        +#endif
        +
        +				if (data->handle_notifications != NULL)
        +					data->handle_notifications(b, data->notification_context, (void*) out);
        +
        +				memset(out, 0, outl);
        +				}
        +			else
        +				ret += n;
        +			}
        +		while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
        +
        +		if (ret > 0 && !(msg.msg_flags & MSG_EOR))
        +			{
        +			/* Partial message read, this should never happen! */
        +
        +			/* The buffer was too small, this means the peer sent
        +			 * a message that was larger than allowed. */
        +			if (ret == outl)
        +				return -1;
        +
        +			/* Test if socket buffer can handle max record
        +			 * size (2^14 + 2048 + 13)
        +			 */
        +			optlen = (socklen_t) sizeof(int);
        +			ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
        +			OPENSSL_assert(ret >= 0);
        +			OPENSSL_assert(optval >= 18445);
        +
        +			/* Test if SCTP doesn't partially deliver below
        +			 * max record size (2^14 + 2048 + 13)
        +			 */
        +			optlen = (socklen_t) sizeof(int);
        +			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
        +			                 &optval, &optlen);
        +			OPENSSL_assert(ret >= 0);
        +			OPENSSL_assert(optval >= 18445);
        +
        +			/* Partially delivered notification??? Probably a bug.... */
        +			OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
        +
        +			/* Everything seems ok till now, so it's most likely
        +			 * a message dropped by PR-SCTP.
        +			 */
        +			memset(out, 0, outl);
        +			BIO_set_retry_read(b);
        +			return -1;
        +			}
        +
        +		BIO_clear_retry_flags(b);
        +		if (ret < 0)
        +			{
        +			if (BIO_dgram_should_retry(ret))
        +				{
        +				BIO_set_retry_read(b);
        +				data->_errno = get_last_socket_error();
        +				}
        +			}
        +
        +		/* Test if peer uses SCTP-AUTH before continuing */
        +		if (!data->peer_auth_tested)
        +			{
        +			int ii, auth_data = 0, auth_forward = 0;
        +			unsigned char *p;
        +			struct sctp_authchunks *authchunks;
        +
        +			optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
        +			authchunks = OPENSSL_malloc(optlen);
        +			memset(authchunks, 0, sizeof(optlen));
        +			ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
        +			OPENSSL_assert(ii >= 0);
        +
        +			for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
        +				 p < (unsigned char*) authchunks + optlen;
        +				 p += sizeof(uint8_t))
        +				{
        +				if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
        +				if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
        +				}
        +
        +			OPENSSL_free(authchunks);
        +
        +			if (!auth_data || !auth_forward)
        +				{
        +				BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR);
        +				return -1;
        +				}
        +
        +			data->peer_auth_tested = 1;
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static int dgram_sctp_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret;
        +	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
        +	struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
        +	struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
        +	struct bio_dgram_sctp_sndinfo handshake_sinfo;
        +	struct iovec iov[1];
        +	struct msghdr msg;
        +	struct cmsghdr *cmsg;
        +#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
        +	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
        +	struct sctp_sndinfo *sndinfo;
        +	struct sctp_prinfo *prinfo;
        +#else
        +	char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
        +	struct sctp_sndrcvinfo *sndrcvinfo;
        +#endif
        +
        +	clear_socket_error();
        +
        +	/* If we're send anything else than application data,
        +	 * disable all user parameters and flags.
        +	 */
        +	if (in[0] != 23) {
        +		memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
        +#ifdef SCTP_SACK_IMMEDIATELY
        +		handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
        +#endif
        +		sinfo = &handshake_sinfo;
        +	}
        +
        +	/* If we have to send a shutdown alert message and the
        +	 * socket is not dry yet, we have to save it and send it
        +	 * as soon as the socket gets dry.
        +	 */
        +	if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
        +	{
        +		data->saved_message.bio = b;
        +		data->saved_message.length = inl;
        +		data->saved_message.data = OPENSSL_malloc(inl);
        +		memcpy(data->saved_message.data, in, inl);
        +		return inl;
        +	}
        +
        +	iov[0].iov_base = (char *)in;
        +	iov[0].iov_len = inl;
        +	msg.msg_name = NULL;
        +	msg.msg_namelen = 0;
        +	msg.msg_iov = iov;
        +	msg.msg_iovlen = 1;
        +	msg.msg_control = (caddr_t)cmsgbuf;
        +	msg.msg_controllen = 0;
        +	msg.msg_flags = 0;
        +#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
        +	cmsg = (struct cmsghdr *)cmsgbuf;
        +	cmsg->cmsg_level = IPPROTO_SCTP;
        +	cmsg->cmsg_type = SCTP_SNDINFO;
        +	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
        +	sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
        +	memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
        +	sndinfo->snd_sid = sinfo->snd_sid;
        +	sndinfo->snd_flags = sinfo->snd_flags;
        +	sndinfo->snd_ppid = sinfo->snd_ppid;
        +	sndinfo->snd_context = sinfo->snd_context;
        +	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
        +
        +	cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
        +	cmsg->cmsg_level = IPPROTO_SCTP;
        +	cmsg->cmsg_type = SCTP_PRINFO;
        +	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
        +	prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
        +	memset(prinfo, 0, sizeof(struct sctp_prinfo));
        +	prinfo->pr_policy = pinfo->pr_policy;
        +	prinfo->pr_value = pinfo->pr_value;
        +	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
        +#else
        +	cmsg = (struct cmsghdr *)cmsgbuf;
        +	cmsg->cmsg_level = IPPROTO_SCTP;
        +	cmsg->cmsg_type = SCTP_SNDRCV;
        +	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
        +	sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
        +	memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
        +	sndrcvinfo->sinfo_stream = sinfo->snd_sid;
        +	sndrcvinfo->sinfo_flags = sinfo->snd_flags;
        +#ifdef __FreeBSD__
        +	sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
        +#endif
        +	sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
        +	sndrcvinfo->sinfo_context = sinfo->snd_context;
        +	sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
        +	msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
        +#endif
        +
        +	ret = sendmsg(b->num, &msg, 0);
        +
        +	BIO_clear_retry_flags(b);
        +	if (ret <= 0)
        +		{
        +		if (BIO_dgram_should_retry(ret))
        +			{
        +			BIO_set_retry_write(b);  
        +			data->_errno = get_last_socket_error();
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +	bio_dgram_sctp_data *data = NULL;
        +	socklen_t sockopt_len = 0;
        +	struct sctp_authkeyid authkeyid;
        +	struct sctp_authkey *authkey;
        +
        +	data = (bio_dgram_sctp_data *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_DGRAM_QUERY_MTU:
        +		/* Set to maximum (2^14)
        +		 * and ignore user input to enable transport
        +		 * protocol fragmentation.
        +		 * Returns always 2^14.
        +		 */
        +		data->mtu = 16384;
        +		ret = data->mtu;
        +		break;
        +	case BIO_CTRL_DGRAM_SET_MTU:
        +		/* Set to maximum (2^14)
        +		 * and ignore input to enable transport
        +		 * protocol fragmentation.
        +		 * Returns always 2^14.
        +		 */
        +		data->mtu = 16384;
        +		ret = data->mtu;
        +		break;
        +	case BIO_CTRL_DGRAM_SET_CONNECTED:
        +	case BIO_CTRL_DGRAM_CONNECT:
        +		/* Returns always -1. */
        +		ret = -1;
        +		break;
        +	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
        +		/* SCTP doesn't need the DTLS timer
        +		 * Returns always 1.
        +		 */
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
        +		if (num > 0)
        +			data->in_handshake = 1;
        +		else
        +			data->in_handshake = 0;
        +
        +		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int));
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
        +		/* New shared key for SCTP AUTH.
        +		 * Returns 0 on success, -1 otherwise.
        +		 */
        +
        +		/* Get active key */
        +		sockopt_len = sizeof(struct sctp_authkeyid);
        +		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
        +		if (ret < 0) break;
        +
        +		/* Add new key */
        +		sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
        +		authkey = OPENSSL_malloc(sockopt_len);
        +		memset(authkey, 0x00, sockopt_len);
        +		authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
        +#ifndef __FreeBSD__
        +		/* This field is missing in FreeBSD 8.2 and earlier,
        +		 * and FreeBSD 8.3 and higher work without it.
        +		 */
        +		authkey->sca_keylength = 64;
        +#endif
        +		memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
        +
        +		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
        +		if (ret < 0) break;
        +
        +		/* Reset active key */
        +		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
        +		      &authkeyid, sizeof(struct sctp_authkeyid));
        +		if (ret < 0) break;
        +
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
        +		/* Returns 0 on success, -1 otherwise. */
        +
        +		/* Get active key */
        +		sockopt_len = sizeof(struct sctp_authkeyid);
        +		ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
        +		if (ret < 0) break;
        +
        +		/* Set active key */
        +		authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
        +		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
        +		      &authkeyid, sizeof(struct sctp_authkeyid));
        +		if (ret < 0) break;
        +
        +		/* CCS has been sent, so remember that and fall through
        +		 * to check if we need to deactivate an old key
        +		 */
        +		data->ccs_sent = 1;
        +
        +	case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
        +		/* Returns 0 on success, -1 otherwise. */
        +
        +		/* Has this command really been called or is this just a fall-through? */
        +		if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
        +			data->ccs_rcvd = 1;
        +
        +		/* CSS has been both, received and sent, so deactivate an old key */
        +		if (data->ccs_rcvd == 1 && data->ccs_sent == 1)
        +			{
        +			/* Get active key */
        +			sockopt_len = sizeof(struct sctp_authkeyid);
        +			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
        +			if (ret < 0) break;
        +
        +			/* Deactivate key or delete second last key if
        +			 * SCTP_AUTHENTICATION_EVENT is not available.
        +			 */
        +			authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
        +#ifdef SCTP_AUTH_DEACTIVATE_KEY
        +			sockopt_len = sizeof(struct sctp_authkeyid);
        +			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
        +			      &authkeyid, sockopt_len);
        +			if (ret < 0) break;
        +#endif
        +#ifndef SCTP_AUTHENTICATION_EVENT
        +			if (authkeyid.scact_keynumber > 0)
        +				{
        +				authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
        +				ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
        +					  &authkeyid, sizeof(struct sctp_authkeyid));
        +				if (ret < 0) break;
        +				}
        +#endif
        +
        +			data->ccs_rcvd = 0;
        +			data->ccs_sent = 0;
        +			}
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
        +		/* Returns the size of the copied struct. */
        +		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
        +			num = sizeof(struct bio_dgram_sctp_sndinfo);
        +
        +		memcpy(ptr, &(data->sndinfo), num);
        +		ret = num;
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
        +		/* Returns the size of the copied struct. */
        +		if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
        +			num = sizeof(struct bio_dgram_sctp_sndinfo);
        +
        +		memcpy(&(data->sndinfo), ptr, num);
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
        +		/* Returns the size of the copied struct. */
        +		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
        +			num = sizeof(struct bio_dgram_sctp_rcvinfo);
        +
        +		memcpy(ptr, &data->rcvinfo, num);
        +
        +		ret = num;
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
        +		/* Returns the size of the copied struct. */
        +		if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
        +			num = sizeof(struct bio_dgram_sctp_rcvinfo);
        +
        +		memcpy(&(data->rcvinfo), ptr, num);
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
        +		/* Returns the size of the copied struct. */
        +		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
        +			num = sizeof(struct bio_dgram_sctp_prinfo);
        +
        +		memcpy(ptr, &(data->prinfo), num);
        +		ret = num;
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
        +		/* Returns the size of the copied struct. */
        +		if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
        +			num = sizeof(struct bio_dgram_sctp_prinfo);
        +
        +		memcpy(&(data->prinfo), ptr, num);
        +		break;
        +	case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
        +		/* Returns always 1. */
        +		if (num > 0)
        +			data->save_shutdown = 1;
        +		else
        +			data->save_shutdown = 0;
        +		break;
        +
        +	default:
        +		/* Pass to default ctrl function to
        +		 * process SCTP unspecific commands
        +		 */
        +		ret=dgram_ctrl(b, cmd, num, ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +int BIO_dgram_sctp_notification_cb(BIO *b,
        +                                   void (*handle_notifications)(BIO *bio, void *context, void *buf),
        +                                   void *context)
        +	{
        +	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
        +
        +	if (handle_notifications != NULL)
        +		{
        +		data->handle_notifications = handle_notifications;
        +		data->notification_context = context;
        +		}
        +	else
        +		return -1;
        +
        +	return 0;
        +	}
        +
        +int BIO_dgram_sctp_wait_for_dry(BIO *b)
        +{
        +	int is_dry = 0;
        +	int n, sockflags, ret;
        +	union sctp_notification snp;
        +	struct msghdr msg;
        +	struct iovec iov;
        +#ifdef SCTP_EVENT
        +	struct sctp_event event;
        +#else
        +	struct sctp_event_subscribe event;
        +	socklen_t eventsize;
        +#endif
        +	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
        +
        +	/* set sender dry event */
        +#ifdef SCTP_EVENT
        +	memset(&event, 0, sizeof(struct sctp_event));
        +	event.se_assoc_id = 0;
        +	event.se_type = SCTP_SENDER_DRY_EVENT;
        +	event.se_on = 1;
        +	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
        +#else
        +	eventsize = sizeof(struct sctp_event_subscribe);
        +	ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
        +	if (ret < 0)
        +		return -1;
        +	
        +	event.sctp_sender_dry_event = 1;
        +	
        +	ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
        +#endif
        +	if (ret < 0)
        +		return -1;
        +
        +	/* peek for notification */
        +	memset(&snp, 0x00, sizeof(union sctp_notification));
        +	iov.iov_base = (char *)&snp;
        +	iov.iov_len = sizeof(union sctp_notification);
        +	msg.msg_name = NULL;
        +	msg.msg_namelen = 0;
        +	msg.msg_iov = &iov;
        +	msg.msg_iovlen = 1;
        +	msg.msg_control = NULL;
        +	msg.msg_controllen = 0;
        +	msg.msg_flags = 0;
        +
        +	n = recvmsg(b->num, &msg, MSG_PEEK);
        +	if (n <= 0)
        +		{
        +		if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
        +			return -1;
        +		else
        +			return 0;
        +		}
        +
        +	/* if we find a notification, process it and try again if necessary */
        +	while (msg.msg_flags & MSG_NOTIFICATION)
        +		{
        +		memset(&snp, 0x00, sizeof(union sctp_notification));
        +		iov.iov_base = (char *)&snp;
        +		iov.iov_len = sizeof(union sctp_notification);
        +		msg.msg_name = NULL;
        +		msg.msg_namelen = 0;
        +		msg.msg_iov = &iov;
        +		msg.msg_iovlen = 1;
        +		msg.msg_control = NULL;
        +		msg.msg_controllen = 0;
        +		msg.msg_flags = 0;
        +
        +		n = recvmsg(b->num, &msg, 0);
        +		if (n <= 0)
        +			{
        +			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
        +				return -1;
        +			else
        +				return is_dry;
        +			}
        +		
        +		if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
        +			{
        +			is_dry = 1;
        +
        +			/* disable sender dry event */
        +#ifdef SCTP_EVENT
        +			memset(&event, 0, sizeof(struct sctp_event));
        +			event.se_assoc_id = 0;
        +			event.se_type = SCTP_SENDER_DRY_EVENT;
        +			event.se_on = 0;
        +			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
        +#else
        +			eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
        +			ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
        +			if (ret < 0)
        +				return -1;
        +
        +			event.sctp_sender_dry_event = 0;
        +
        +			ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
        +#endif
        +			if (ret < 0)
        +				return -1;
        +			}
        +
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +		if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
        +			dgram_sctp_handle_auth_free_key_event(b, &snp);
        +#endif
        +
        +		if (data->handle_notifications != NULL)
        +			data->handle_notifications(b, data->notification_context, (void*) &snp);
        +
        +		/* found notification, peek again */
        +		memset(&snp, 0x00, sizeof(union sctp_notification));
        +		iov.iov_base = (char *)&snp;
        +		iov.iov_len = sizeof(union sctp_notification);
        +		msg.msg_name = NULL;
        +		msg.msg_namelen = 0;
        +		msg.msg_iov = &iov;
        +		msg.msg_iovlen = 1;
        +		msg.msg_control = NULL;
        +		msg.msg_controllen = 0;
        +		msg.msg_flags = 0;
        +
        +		/* if we have seen the dry already, don't wait */
        +		if (is_dry)
        +			{
        +			sockflags = fcntl(b->num, F_GETFL, 0);
        +			fcntl(b->num, F_SETFL, O_NONBLOCK);
        +			}
        +
        +		n = recvmsg(b->num, &msg, MSG_PEEK);
        +
        +		if (is_dry)
        +			{
        +			fcntl(b->num, F_SETFL, sockflags);
        +			}
        +
        +		if (n <= 0)
        +			{
        +			if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
        +				return -1;
        +			else
        +				return is_dry;
        +			}
        +		}
        +
        +	/* read anything else */
        +	return is_dry;
        +}
        +
        +int BIO_dgram_sctp_msg_waiting(BIO *b)
        +	{
        +	int n, sockflags;
        +	union sctp_notification snp;
        +	struct msghdr msg;
        +	struct iovec iov;
        +	bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
        +
        +	/* Check if there are any messages waiting to be read */
        +	do
        +		{
        +		memset(&snp, 0x00, sizeof(union sctp_notification));
        +		iov.iov_base = (char *)&snp;
        +		iov.iov_len = sizeof(union sctp_notification);
        +		msg.msg_name = NULL;
        +		msg.msg_namelen = 0;
        +		msg.msg_iov = &iov;
        +		msg.msg_iovlen = 1;
        +		msg.msg_control = NULL;
        +		msg.msg_controllen = 0;
        +		msg.msg_flags = 0;
        +
        +		sockflags = fcntl(b->num, F_GETFL, 0);
        +		fcntl(b->num, F_SETFL, O_NONBLOCK);
        +		n = recvmsg(b->num, &msg, MSG_PEEK);
        +		fcntl(b->num, F_SETFL, sockflags);
        +
        +		/* if notification, process and try again */
        +		if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION))
        +			{
        +#ifdef SCTP_AUTHENTICATION_EVENT
        +			if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
        +				dgram_sctp_handle_auth_free_key_event(b, &snp);
        +#endif
        +
        +			memset(&snp, 0x00, sizeof(union sctp_notification));
        +			iov.iov_base = (char *)&snp;
        +			iov.iov_len = sizeof(union sctp_notification);
        +			msg.msg_name = NULL;
        +			msg.msg_namelen = 0;
        +			msg.msg_iov = &iov;
        +			msg.msg_iovlen = 1;
        +			msg.msg_control = NULL;
        +			msg.msg_controllen = 0;
        +			msg.msg_flags = 0;
        +			n = recvmsg(b->num, &msg, 0);
        +
        +			if (data->handle_notifications != NULL)
        +				data->handle_notifications(b, data->notification_context, (void*) &snp);
        +			}
        +
        +		} while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
        +
        +	/* Return 1 if there is a message to be read, return 0 otherwise. */
        +	if (n > 0)
        +		return 1;
        +	else
        +		return 0;
        +	}
        +
        +static int dgram_sctp_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=dgram_sctp_write(bp,str,n);
        +	return(ret);
        +	}
        +#endif
        +
        +static int BIO_dgram_should_retry(int i)
        +	{
        +	int err;
        +
        +	if ((i == 0) || (i == -1))
        +		{
        +		err=get_last_socket_error();
        +
        +#if defined(OPENSSL_SYS_WINDOWS)
        +	/* If the socket return value (i) is -1
        +	 * and err is unexpectedly 0 at this point,
        +	 * the error code was overwritten by
        +	 * another system call before this error
        +	 * handling is called.
        +	 */
        +#endif
        +
        +		return(BIO_dgram_non_fatal_error(err));
        +		}
        +	return(0);
        +	}
        +
        +int BIO_dgram_non_fatal_error(int err)
        +	{
        +	switch (err)
        +		{
        +#if defined(OPENSSL_SYS_WINDOWS)
        +# if defined(WSAEWOULDBLOCK)
        +	case WSAEWOULDBLOCK:
        +# endif
        +
        +# if 0 /* This appears to always be an error */
        +#  if defined(WSAENOTCONN)
        +	case WSAENOTCONN:
        +#  endif
        +# endif
        +#endif
        +
        +#ifdef EWOULDBLOCK
        +# ifdef WSAEWOULDBLOCK
        +#  if WSAEWOULDBLOCK != EWOULDBLOCK
        +	case EWOULDBLOCK:
        +#  endif
        +# else
        +	case EWOULDBLOCK:
        +# endif
        +#endif
        +
        +#ifdef EINTR
        +	case EINTR:
        +#endif
        +
        +#ifdef EAGAIN
        +#if EWOULDBLOCK != EAGAIN
        +	case EAGAIN:
        +# endif
        +#endif
        +
        +#ifdef EPROTO
        +	case EPROTO:
        +#endif
        +
        +#ifdef EINPROGRESS
        +	case EINPROGRESS:
        +#endif
        +
        +#ifdef EALREADY
        +	case EALREADY:
        +#endif
        +
        +		return(1);
        +		/* break; */
        +	default:
        +		break;
        +		}
        +	return(0);
        +	}
        +
        +static void get_current_time(struct timeval *t)
        +	{
        +#ifdef OPENSSL_SYS_WIN32
        +	struct _timeb tb;
        +	_ftime(&tb);
        +	t->tv_sec = (long)tb.time;
        +	t->tv_usec = (long)tb.millitm * 1000;
        +#elif defined(OPENSSL_SYS_VMS)
        +	struct timeb tb;
        +	ftime(&tb);
        +	t->tv_sec = (long)tb.time;
        +	t->tv_usec = (long)tb.millitm * 1000;
        +#else
        +	gettimeofday(t, NULL);
        +#endif
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_fd.c b/vendor/openssl/openssl/crypto/bio/bss_fd.c
        new file mode 100644
        index 000000000..d1bf85aae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_fd.c
        @@ -0,0 +1,319 @@
        +/* crypto/bio/bss_fd.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "cryptlib.h"
        +
        +#if defined(OPENSSL_NO_POSIX_IO)
        +/*
        + * One can argue that one should implement dummy placeholder for
        + * BIO_s_fd here...
        + */
        +#else
        +/*
        + * As for unconditional usage of "UPLINK" interface in this module.
        + * Trouble is that unlike Unix file descriptors [which are indexes
        + * in kernel-side per-process table], corresponding descriptors on
        + * platforms which require "UPLINK" interface seem to be indexes
        + * in a user-land, non-global table. Well, in fact they are indexes
        + * in stdio _iob[], and recall that _iob[] was the very reason why
        + * "UPLINK" interface was introduced in first place. But one way on
        + * another. Neither libcrypto or libssl use this BIO meaning that
        + * file descriptors can only be provided by application. Therefore
        + * "UPLINK" calls are due...
        + */
        +#include "bio_lcl.h"
        +
        +static int fd_write(BIO *h, const char *buf, int num);
        +static int fd_read(BIO *h, char *buf, int size);
        +static int fd_puts(BIO *h, const char *str);
        +static int fd_gets(BIO *h, char *buf, int size);
        +static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int fd_new(BIO *h);
        +static int fd_free(BIO *data);
        +int BIO_fd_should_retry(int s);
        +
        +static BIO_METHOD methods_fdp=
        +	{
        +	BIO_TYPE_FD,"file descriptor",
        +	fd_write,
        +	fd_read,
        +	fd_puts,
        +	fd_gets,
        +	fd_ctrl,
        +	fd_new,
        +	fd_free,
        +	NULL,
        +	};
        +
        +BIO_METHOD *BIO_s_fd(void)
        +	{
        +	return(&methods_fdp);
        +	}
        +
        +BIO *BIO_new_fd(int fd,int close_flag)
        +	{
        +	BIO *ret;
        +	ret=BIO_new(BIO_s_fd());
        +	if (ret == NULL) return(NULL);
        +	BIO_set_fd(ret,fd,close_flag);
        +	return(ret);
        +	}
        +
        +static int fd_new(BIO *bi)
        +	{
        +	bi->init=0;
        +	bi->num=-1;
        +	bi->ptr=NULL;
        +	bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */
        +	return(1);
        +	}
        +
        +static int fd_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	if (a->shutdown)
        +		{
        +		if (a->init)
        +			{
        +			UP_close(a->num);
        +			}
        +		a->init=0;
        +		a->flags=BIO_FLAGS_UPLINK;
        +		}
        +	return(1);
        +	}
        +	
        +static int fd_read(BIO *b, char *out,int outl)
        +	{
        +	int ret=0;
        +
        +	if (out != NULL)
        +		{
        +		clear_sys_error();
        +		ret=UP_read(b->num,out,outl);
        +		BIO_clear_retry_flags(b);
        +		if (ret <= 0)
        +			{
        +			if (BIO_fd_should_retry(ret))
        +				BIO_set_retry_read(b);
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static int fd_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret;
        +	clear_sys_error();
        +	ret=UP_write(b->num,in,inl);
        +	BIO_clear_retry_flags(b);
        +	if (ret <= 0)
        +		{
        +		if (BIO_fd_should_retry(ret))
        +			BIO_set_retry_write(b);
        +		}
        +	return(ret);
        +	}
        +
        +static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +	int *ip;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		num=0;
        +	case BIO_C_FILE_SEEK:
        +		ret=(long)UP_lseek(b->num,num,0);
        +		break;
        +	case BIO_C_FILE_TELL:
        +	case BIO_CTRL_INFO:
        +		ret=(long)UP_lseek(b->num,0,1);
        +		break;
        +	case BIO_C_SET_FD:
        +		fd_free(b);
        +		b->num= *((int *)ptr);
        +		b->shutdown=(int)num;
        +		b->init=1;
        +		break;
        +	case BIO_C_GET_FD:
        +		if (b->init)
        +			{
        +			ip=(int *)ptr;
        +			if (ip != NULL) *ip=b->num;
        +			ret=b->num;
        +			}
        +		else
        +			ret= -1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_WPENDING:
        +		ret=0;
        +		break;
        +	case BIO_CTRL_DUP:
        +	case BIO_CTRL_FLUSH:
        +		ret=1;
        +		break;
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int fd_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=fd_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +static int fd_gets(BIO *bp, char *buf, int size)
        +        {
        +	int ret=0;
        +	char *ptr=buf;
        +	char *end=buf+size-1;
        +
        +	while ( (ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n') )
        +		ptr++;
        +
        +	ptr[0]='\0';
        +
        +	if (buf[0] != '\0')
        +		ret=strlen(buf);
        +	return(ret);
        +        }
        +
        +int BIO_fd_should_retry(int i)
        +	{
        +	int err;
        +
        +	if ((i == 0) || (i == -1))
        +		{
        +		err=get_last_sys_error();
        +
        +#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
        +		if ((i == -1) && (err == 0))
        +			return(1);
        +#endif
        +
        +		return(BIO_fd_non_fatal_error(err));
        +		}
        +	return(0);
        +	}
        +
        +int BIO_fd_non_fatal_error(int err)
        +	{
        +	switch (err)
        +		{
        +
        +#ifdef EWOULDBLOCK
        +# ifdef WSAEWOULDBLOCK
        +#  if WSAEWOULDBLOCK != EWOULDBLOCK
        +	case EWOULDBLOCK:
        +#  endif
        +# else
        +	case EWOULDBLOCK:
        +# endif
        +#endif
        +
        +#if defined(ENOTCONN)
        +	case ENOTCONN:
        +#endif
        +
        +#ifdef EINTR
        +	case EINTR:
        +#endif
        +
        +#ifdef EAGAIN
        +#if EWOULDBLOCK != EAGAIN
        +	case EAGAIN:
        +# endif
        +#endif
        +
        +#ifdef EPROTO
        +	case EPROTO:
        +#endif
        +
        +#ifdef EINPROGRESS
        +	case EINPROGRESS:
        +#endif
        +
        +#ifdef EALREADY
        +	case EALREADY:
        +#endif
        +		return(1);
        +		/* break; */
        +	default:
        +		break;
        +		}
        +	return(0);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_file.c b/vendor/openssl/openssl/crypto/bio/bss_file.c
        new file mode 100644
        index 000000000..b954fe7eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_file.c
        @@ -0,0 +1,477 @@
        +/* crypto/bio/bss_file.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.]
        + */
        +
        +/*
        + * 03-Dec-1997	rdenny@dc3.com  Fix bug preventing use of stdin/stdout
        + *		with binary data (e.g. asn1parse -inform DER < xxx) under
        + *		Windows
        + */
        +
        +#ifndef HEADER_BSS_FILE_C
        +#define HEADER_BSS_FILE_C
        +
        +#if defined(__linux) || defined(__sun) || defined(__hpux)
        +/* Following definition aliases fopen to fopen64 on above mentioned
        + * platforms. This makes it possible to open and sequentially access
        + * files larger than 2GB from 32-bit application. It does not allow to
        + * traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
        + * 32-bit platform permits that, not with fseek/ftell. Not to mention
        + * that breaking 2GB limit for seeking would require surgery to *our*
        + * API. But sequential access suffices for practical cases when you
        + * can run into large files, such as fingerprinting, so we can let API
        + * alone. For reference, the list of 32-bit platforms which allow for
        + * sequential access of large files without extra "magic" comprise *BSD,
        + * Darwin, IRIX...
        + */
        +#ifndef _FILE_OFFSET_BITS
        +#define _FILE_OFFSET_BITS 64
        +#endif
        +#endif
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include "bio_lcl.h"
        +#include <openssl/err.h>
        +
        +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
        +#include <nwfileio.h>
        +#endif
        +
        +#if !defined(OPENSSL_NO_STDIO)
        +
        +static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
        +static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
        +static int MS_CALLBACK file_puts(BIO *h, const char *str);
        +static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
        +static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int MS_CALLBACK file_new(BIO *h);
        +static int MS_CALLBACK file_free(BIO *data);
        +static BIO_METHOD methods_filep=
        +	{
        +	BIO_TYPE_FILE,
        +	"FILE pointer",
        +	file_write,
        +	file_read,
        +	file_puts,
        +	file_gets,
        +	file_ctrl,
        +	file_new,
        +	file_free,
        +	NULL,
        +	};
        +
        +BIO *BIO_new_file(const char *filename, const char *mode)
        +	{
        +	BIO  *ret;
        +	FILE *file=NULL;
        +
        +#if defined(_WIN32) && defined(CP_UTF8)
        +	int sz, len_0 = (int)strlen(filename)+1;
        +	DWORD flags;
        +
        +	/*
        +	 * Basically there are three cases to cover: a) filename is
        +	 * pure ASCII string; b) actual UTF-8 encoded string and
        +	 * c) locale-ized string, i.e. one containing 8-bit
        +	 * characters that are meaningful in current system locale.
        +	 * If filename is pure ASCII or real UTF-8 encoded string,
        +	 * MultiByteToWideChar succeeds and _wfopen works. If
        +	 * filename is locale-ized string, chances are that
        +	 * MultiByteToWideChar fails reporting
        +	 * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
        +	 * back to fopen...
        +	 */
        +	if ((sz=MultiByteToWideChar(CP_UTF8,(flags=MB_ERR_INVALID_CHARS),
        +					filename,len_0,NULL,0))>0 ||
        +	    (GetLastError()==ERROR_INVALID_FLAGS &&
        +	     (sz=MultiByteToWideChar(CP_UTF8,(flags=0),
        +					filename,len_0,NULL,0))>0)
        +	   )
        +		{
        +		WCHAR  wmode[8];
        +		WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
        +
        +		if (MultiByteToWideChar(CP_UTF8,flags,
        +					filename,len_0,wfilename,sz) &&
        +		    MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1,
        +			    		wmode,sizeof(wmode)/sizeof(wmode[0])) &&
        +		    (file=_wfopen(wfilename,wmode))==NULL &&
        +		    (errno==ENOENT || errno==EBADF)
        +		   )	/* UTF-8 decode succeeded, but no file, filename
        +			 * could still have been locale-ized... */
        +			file = fopen(filename,mode);
        +		}
        +	else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION)
        +		{
        +		file = fopen(filename,mode);
        +		}
        +#else
        +	file=fopen(filename,mode);	
        +#endif
        +	if (file == NULL)
        +		{
        +		SYSerr(SYS_F_FOPEN,get_last_sys_error());
        +		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
        +		if (errno == ENOENT)
        +			BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
        +		else
        +			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
        +		return(NULL);
        +		}
        +	if ((ret=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		fclose(file);
        +		return(NULL);
        +		}
        +
        +	BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
        +	BIO_set_fp(ret,file,BIO_CLOSE);
        +	return(ret);
        +	}
        +
        +BIO *BIO_new_fp(FILE *stream, int close_flag)
        +	{
        +	BIO *ret;
        +
        +	if ((ret=BIO_new(BIO_s_file())) == NULL)
        +		return(NULL);
        +
        +	BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */
        +	BIO_set_fp(ret,stream,close_flag);
        +	return(ret);
        +	}
        +
        +BIO_METHOD *BIO_s_file(void)
        +	{
        +	return(&methods_filep);
        +	}
        +
        +static int MS_CALLBACK file_new(BIO *bi)
        +	{
        +	bi->init=0;
        +	bi->num=0;
        +	bi->ptr=NULL;
        +	bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */
        +	return(1);
        +	}
        +
        +static int MS_CALLBACK file_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	if (a->shutdown)
        +		{
        +		if ((a->init) && (a->ptr != NULL))
        +			{
        +			if (a->flags&BIO_FLAGS_UPLINK)
        +				UP_fclose (a->ptr);
        +			else
        +				fclose (a->ptr);
        +			a->ptr=NULL;
        +			a->flags=BIO_FLAGS_UPLINK;
        +			}
        +		a->init=0;
        +		}
        +	return(1);
        +	}
        +	
        +static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +
        +	if (b->init && (out != NULL))
        +		{
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			ret=UP_fread(out,1,(int)outl,b->ptr);
        +		else
        +			ret=fread(out,1,(int)outl,(FILE *)b->ptr);
        +		if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr))
        +			{
        +			SYSerr(SYS_F_FREAD,get_last_sys_error());
        +			BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
        +			ret=-1;
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret=0;
        +
        +	if (b->init && (in != NULL))
        +		{
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			ret=UP_fwrite(in,(int)inl,1,b->ptr);
        +		else
        +			ret=fwrite(in,(int)inl,1,(FILE *)b->ptr);
        +		if (ret)
        +			ret=inl;
        +		/* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
        +		/* according to Tim Hudson <tjh@cryptsoft.com>, the commented
        +		 * out version above can cause 'inl' write calls under
        +		 * some stupid stdio implementations (VMS) */
        +		}
        +	return(ret);
        +	}
        +
        +static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +	FILE *fp=(FILE *)b->ptr;
        +	FILE **fpp;
        +	char p[4];
        +
        +	switch (cmd)
        +		{
        +	case BIO_C_FILE_SEEK:
        +	case BIO_CTRL_RESET:
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			ret=(long)UP_fseek(b->ptr,num,0);
        +		else
        +			ret=(long)fseek(fp,num,0);
        +		break;
        +	case BIO_CTRL_EOF:
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			ret=(long)UP_feof(fp);
        +		else
        +			ret=(long)feof(fp);
        +		break;
        +	case BIO_C_FILE_TELL:
        +	case BIO_CTRL_INFO:
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			ret=UP_ftell(b->ptr);
        +		else
        +			ret=ftell(fp);
        +		break;
        +	case BIO_C_SET_FILE_PTR:
        +		file_free(b);
        +		b->shutdown=(int)num&BIO_CLOSE;
        +		b->ptr=ptr;
        +		b->init=1;
        +#if BIO_FLAGS_UPLINK!=0
        +#if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
        +#define _IOB_ENTRIES 20
        +#endif
        +#if defined(_IOB_ENTRIES)
        +		/* Safety net to catch purely internal BIO_set_fp calls */
        +		if ((size_t)ptr >= (size_t)stdin &&
        +		    (size_t)ptr <  (size_t)(stdin+_IOB_ENTRIES))
        +			BIO_clear_flags(b,BIO_FLAGS_UPLINK);
        +#endif
        +#endif
        +#ifdef UP_fsetmod
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
        +		else
        +#endif
        +		{
        +#if defined(OPENSSL_SYS_WINDOWS)
        +		int fd = _fileno((FILE*)ptr);
        +		if (num & BIO_FP_TEXT)
        +			_setmode(fd,_O_TEXT);
        +		else
        +			_setmode(fd,_O_BINARY);
        +#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
        +		int fd = fileno((FILE*)ptr);
        +		/* Under CLib there are differences in file modes */
        +		if (num & BIO_FP_TEXT)
        +			setmode(fd,O_TEXT);
        +		else
        +			setmode(fd,O_BINARY);
        +#elif defined(OPENSSL_SYS_MSDOS)
        +		int fd = fileno((FILE*)ptr);
        +		/* Set correct text/binary mode */
        +		if (num & BIO_FP_TEXT)
        +			_setmode(fd,_O_TEXT);
        +		/* Dangerous to set stdin/stdout to raw (unless redirected) */
        +		else
        +			{
        +			if (fd == STDIN_FILENO || fd == STDOUT_FILENO)
        +				{
        +				if (isatty(fd) <= 0)
        +					_setmode(fd,_O_BINARY);
        +				}
        +			else
        +				_setmode(fd,_O_BINARY);
        +			}
        +#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
        +		int fd = fileno((FILE*)ptr);
        +		if (num & BIO_FP_TEXT)
        +			setmode(fd, O_TEXT);
        +		else
        +			setmode(fd, O_BINARY);
        +#endif
        +		}
        +		break;
        +	case BIO_C_SET_FILENAME:
        +		file_free(b);
        +		b->shutdown=(int)num&BIO_CLOSE;
        +		if (num & BIO_FP_APPEND)
        +			{
        +			if (num & BIO_FP_READ)
        +				BUF_strlcpy(p,"a+",sizeof p);
        +			else	BUF_strlcpy(p,"a",sizeof p);
        +			}
        +		else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
        +			BUF_strlcpy(p,"r+",sizeof p);
        +		else if (num & BIO_FP_WRITE)
        +			BUF_strlcpy(p,"w",sizeof p);
        +		else if (num & BIO_FP_READ)
        +			BUF_strlcpy(p,"r",sizeof p);
        +		else
        +			{
        +			BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
        +			ret=0;
        +			break;
        +			}
        +#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
        +		if (!(num & BIO_FP_TEXT))
        +			strcat(p,"b");
        +		else
        +			strcat(p,"t");
        +#endif
        +#if defined(OPENSSL_SYS_NETWARE)
        +		if (!(num & BIO_FP_TEXT))
        +			strcat(p,"b");
        +		else
        +			strcat(p,"t");
        +#endif
        +		fp=fopen(ptr,p);
        +		if (fp == NULL)
        +			{
        +			SYSerr(SYS_F_FOPEN,get_last_sys_error());
        +			ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
        +			BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
        +			ret=0;
        +			break;
        +			}
        +		b->ptr=fp;
        +		b->init=1;
        +		BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
        +		break;
        +	case BIO_C_GET_FILE_PTR:
        +		/* the ptr parameter is actually a FILE ** in this case. */
        +		if (ptr != NULL)
        +			{
        +			fpp=(FILE **)ptr;
        +			*fpp=(FILE *)b->ptr;
        +			}
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=(long)b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		if (b->flags&BIO_FLAGS_UPLINK)
        +			UP_fflush(b->ptr);
        +		else
        +			fflush((FILE *)b->ptr);
        +		break;
        +	case BIO_CTRL_DUP:
        +		ret=1;
        +		break;
        +
        +	case BIO_CTRL_WPENDING:
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_PUSH:
        +	case BIO_CTRL_POP:
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
        +	{
        +	int ret=0;
        +
        +	buf[0]='\0';
        +	if (bp->flags&BIO_FLAGS_UPLINK)
        +		{
        +		if (!UP_fgets(buf,size,bp->ptr))
        +			goto err;
        +		}
        +	else
        +		{
        +		if (!fgets(buf,size,(FILE *)bp->ptr))
        +			goto err;
        +		}
        +	if (buf[0] != '\0')
        +		ret=strlen(buf);
        +	err:
        +	return(ret);
        +	}
        +
        +static int MS_CALLBACK file_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=file_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +#endif /* OPENSSL_NO_STDIO */
        +
        +#endif /* HEADER_BSS_FILE_C */
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_log.c b/vendor/openssl/openssl/crypto/bio/bss_log.c
        new file mode 100644
        index 000000000..b7dce5c1a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_log.c
        @@ -0,0 +1,399 @@
        +/* crypto/bio/bss_log.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
        + *    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).
        + *
        + */
        +
        +/*
        +	Why BIO_s_log?
        +
        +	BIO_s_log is useful for system daemons (or services under NT).
        +	It is one-way BIO, it sends all stuff to syslogd (on system that
        +	commonly use that), or event log (on NT), or OPCOM (on OpenVMS).
        +
        +*/
        +
        +
        +#include <stdio.h>
        +#include <errno.h>
        +
        +#include "cryptlib.h"
        +
        +#if defined(OPENSSL_SYS_WINCE)
        +#elif defined(OPENSSL_SYS_WIN32)
        +#elif defined(OPENSSL_SYS_VMS)
        +#  include <opcdef.h>
        +#  include <descrip.h>
        +#  include <lib$routines.h>
        +#  include <starlet.h>
        +/* Some compiler options may mask the declaration of "_malloc32". */
        +#  if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
        +#    if __INITIAL_POINTER_SIZE == 64
        +#      pragma pointer_size save
        +#      pragma pointer_size 32
        +    void * _malloc32  (__size_t);
        +#      pragma pointer_size restore
        +#    endif /* __INITIAL_POINTER_SIZE == 64 */
        +#  endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */
        +#elif defined(__ultrix)
        +#  include <sys/syslog.h>
        +#elif defined(OPENSSL_SYS_NETWARE)
        +#  define NO_SYSLOG
        +#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
        +#  include <syslog.h>
        +#endif
        +
        +#include <openssl/buffer.h>
        +#include <openssl/err.h>
        +
        +#ifndef NO_SYSLOG
        +
        +#if defined(OPENSSL_SYS_WIN32)
        +#define LOG_EMERG	0
        +#define LOG_ALERT	1
        +#define LOG_CRIT	2
        +#define LOG_ERR		3
        +#define LOG_WARNING	4
        +#define LOG_NOTICE	5
        +#define LOG_INFO	6
        +#define LOG_DEBUG	7
        +
        +#define LOG_DAEMON	(3<<3)
        +#elif defined(OPENSSL_SYS_VMS)
        +/* On VMS, we don't really care about these, but we need them to compile */
        +#define LOG_EMERG	0
        +#define LOG_ALERT	1
        +#define LOG_CRIT	2
        +#define LOG_ERR		3
        +#define LOG_WARNING	4
        +#define LOG_NOTICE	5
        +#define LOG_INFO	6
        +#define LOG_DEBUG	7
        +
        +#define LOG_DAEMON	OPC$M_NM_NTWORK
        +#endif
        +
        +static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num);
        +static int MS_CALLBACK slg_puts(BIO *h, const char *str);
        +static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int MS_CALLBACK slg_new(BIO *h);
        +static int MS_CALLBACK slg_free(BIO *data);
        +static void xopenlog(BIO* bp, char* name, int level);
        +static void xsyslog(BIO* bp, int priority, const char* string);
        +static void xcloselog(BIO* bp);
        +
        +static BIO_METHOD methods_slg=
        +	{
        +	BIO_TYPE_MEM,"syslog",
        +	slg_write,
        +	NULL,
        +	slg_puts,
        +	NULL,
        +	slg_ctrl,
        +	slg_new,
        +	slg_free,
        +	NULL,
        +	};
        +
        +BIO_METHOD *BIO_s_log(void)
        +	{
        +	return(&methods_slg);
        +	}
        +
        +static int MS_CALLBACK slg_new(BIO *bi)
        +	{
        +	bi->init=1;
        +	bi->num=0;
        +	bi->ptr=NULL;
        +	xopenlog(bi, "application", LOG_DAEMON);
        +	return(1);
        +	}
        +
        +static int MS_CALLBACK slg_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	xcloselog(a);
        +	return(1);
        +	}
        +	
        +static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret= inl;
        +	char* buf;
        +	char* pp;
        +	int priority, i;
        +	static const struct
        +		{
        +		int strl;
        +		char str[10];
        +		int log_level;
        +		}
        +	mapping[] =
        +		{
        +		{ 6, "PANIC ", LOG_EMERG },
        +		{ 6, "EMERG ", LOG_EMERG },
        +		{ 4, "EMR ", LOG_EMERG },
        +		{ 6, "ALERT ", LOG_ALERT },
        +		{ 4, "ALR ", LOG_ALERT },
        +		{ 5, "CRIT ", LOG_CRIT },
        +		{ 4, "CRI ", LOG_CRIT },
        +		{ 6, "ERROR ", LOG_ERR },
        +		{ 4, "ERR ", LOG_ERR },
        +		{ 8, "WARNING ", LOG_WARNING },
        +		{ 5, "WARN ", LOG_WARNING },
        +		{ 4, "WAR ", LOG_WARNING },
        +		{ 7, "NOTICE ", LOG_NOTICE },
        +		{ 5, "NOTE ", LOG_NOTICE },
        +		{ 4, "NOT ", LOG_NOTICE },
        +		{ 5, "INFO ", LOG_INFO },
        +		{ 4, "INF ", LOG_INFO },
        +		{ 6, "DEBUG ", LOG_DEBUG },
        +		{ 4, "DBG ", LOG_DEBUG },
        +		{ 0, "", LOG_ERR } /* The default */
        +		};
        +
        +	if((buf= (char *)OPENSSL_malloc(inl+ 1)) == NULL){
        +		return(0);
        +	}
        +	strncpy(buf, in, inl);
        +	buf[inl]= '\0';
        +
        +	i = 0;
        +	while(strncmp(buf, mapping[i].str, mapping[i].strl) != 0) i++;
        +	priority = mapping[i].log_level;
        +	pp = buf + mapping[i].strl;
        +
        +	xsyslog(b, priority, pp);
        +
        +	OPENSSL_free(buf);
        +	return(ret);
        +	}
        +
        +static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_SET:
        +		xcloselog(b);
        +		xopenlog(b, ptr, num);
        +		break;
        +	default:
        +		break;
        +		}
        +	return(0);
        +	}
        +
        +static int MS_CALLBACK slg_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=slg_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +#if defined(OPENSSL_SYS_WIN32)
        +
        +static void xopenlog(BIO* bp, char* name, int level)
        +{
        +	if (GetVersion() < 0x80000000)
        +		bp->ptr = RegisterEventSourceA(NULL,name);
        +	else
        +		bp->ptr = NULL;
        +}
        +
        +static void xsyslog(BIO *bp, int priority, const char *string)
        +{
        +	LPCSTR lpszStrings[2];
        +	WORD evtype= EVENTLOG_ERROR_TYPE;
        +	char pidbuf[DECIMAL_SIZE(DWORD)+4];
        +
        +	if (bp->ptr == NULL)
        +		return;
        +
        +	switch (priority)
        +		{
        +	case LOG_EMERG:
        +	case LOG_ALERT:
        +	case LOG_CRIT:
        +	case LOG_ERR:
        +		evtype = EVENTLOG_ERROR_TYPE;
        +		break;
        +	case LOG_WARNING:
        +		evtype = EVENTLOG_WARNING_TYPE;
        +		break;
        +	case LOG_NOTICE:
        +	case LOG_INFO:
        +	case LOG_DEBUG:
        +		evtype = EVENTLOG_INFORMATION_TYPE;
        +		break;
        +	default:		/* Should never happen, but set it
        +				   as error anyway. */
        +		evtype = EVENTLOG_ERROR_TYPE;
        +		break;
        +		}
        +
        +	sprintf(pidbuf, "[%u] ", GetCurrentProcessId());
        +	lpszStrings[0] = pidbuf;
        +	lpszStrings[1] = string;
        +
        +	ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
        +				lpszStrings, NULL);
        +}
        +	
        +static void xcloselog(BIO* bp)
        +{
        +	if(bp->ptr)
        +		DeregisterEventSource((HANDLE)(bp->ptr));
        +	bp->ptr= NULL;
        +}
        +
        +#elif defined(OPENSSL_SYS_VMS)
        +
        +static int VMS_OPC_target = LOG_DAEMON;
        +
        +static void xopenlog(BIO* bp, char* name, int level)
        +{
        +	VMS_OPC_target = level; 
        +}
        +
        +static void xsyslog(BIO *bp, int priority, const char *string)
        +{
        +	struct dsc$descriptor_s opc_dsc;
        +
        +/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
        +#if __INITIAL_POINTER_SIZE == 64
        +# pragma pointer_size save
        +# pragma pointer_size 32
        +# define OPCDEF_TYPE __char_ptr32
        +# define OPCDEF_MALLOC _malloc32
        +#else /* __INITIAL_POINTER_SIZE == 64 */
        +# define OPCDEF_TYPE char *
        +# define OPCDEF_MALLOC OPENSSL_malloc
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +	struct opcdef *opcdef_p;
        +
        +#if __INITIAL_POINTER_SIZE == 64
        +# pragma pointer_size restore
        +#endif /* __INITIAL_POINTER_SIZE == 64 */
        +
        +	char buf[10240];
        +	unsigned int len;
        +        struct dsc$descriptor_s buf_dsc;
        +	$DESCRIPTOR(fao_cmd, "!AZ: !AZ");
        +	char *priority_tag;
        +
        +	switch (priority)
        +	  {
        +	  case LOG_EMERG: priority_tag = "Emergency"; break;
        +	  case LOG_ALERT: priority_tag = "Alert"; break;
        +	  case LOG_CRIT: priority_tag = "Critical"; break;
        +	  case LOG_ERR: priority_tag = "Error"; break;
        +	  case LOG_WARNING: priority_tag = "Warning"; break;
        +	  case LOG_NOTICE: priority_tag = "Notice"; break;
        +	  case LOG_INFO: priority_tag = "Info"; break;
        +	  case LOG_DEBUG: priority_tag = "DEBUG"; break;
        +	  }
        +
        +	buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
        +	buf_dsc.dsc$b_class = DSC$K_CLASS_S;
        +	buf_dsc.dsc$a_pointer = buf;
        +	buf_dsc.dsc$w_length = sizeof(buf) - 1;
        +
        +	lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
        +
        +	/* We know there's an 8-byte header.  That's documented. */
        +	opcdef_p = OPCDEF_MALLOC( 8+ len);
        +	opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
        +	memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
        +	opcdef_p->opc$l_ms_rqstid = 0;
        +	memcpy(&opcdef_p->opc$l_ms_text, buf, len);
        +
        +	opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
        +	opc_dsc.dsc$b_class = DSC$K_CLASS_S;
        +	opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
        +	opc_dsc.dsc$w_length = len + 8;
        +
        +	sys$sndopr(opc_dsc, 0);
        +
        +	OPENSSL_free(opcdef_p);
        +}
        +
        +static void xcloselog(BIO* bp)
        +{
        +}
        +
        +#else /* Unix/Watt32 */
        +
        +static void xopenlog(BIO* bp, char* name, int level)
        +{
        +#ifdef WATT32   /* djgpp/DOS */
        +	openlog(name, LOG_PID|LOG_CONS|LOG_NDELAY, level);
        +#else
        +	openlog(name, LOG_PID|LOG_CONS, level);
        +#endif
        +}
        +
        +static void xsyslog(BIO *bp, int priority, const char *string)
        +{
        +	syslog(priority, "%s", string);
        +}
        +
        +static void xcloselog(BIO* bp)
        +{
        +	closelog();
        +}
        +
        +#endif /* Unix */
        +
        +#endif /* NO_SYSLOG */
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_mem.c b/vendor/openssl/openssl/crypto/bio/bss_mem.c
        new file mode 100644
        index 000000000..37d4194e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_mem.c
        @@ -0,0 +1,319 @@
        +/* crypto/bio/bss_mem.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +static int mem_write(BIO *h, const char *buf, int num);
        +static int mem_read(BIO *h, char *buf, int size);
        +static int mem_puts(BIO *h, const char *str);
        +static int mem_gets(BIO *h, char *str, int size);
        +static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int mem_new(BIO *h);
        +static int mem_free(BIO *data);
        +static BIO_METHOD mem_method=
        +	{
        +	BIO_TYPE_MEM,
        +	"memory buffer",
        +	mem_write,
        +	mem_read,
        +	mem_puts,
        +	mem_gets,
        +	mem_ctrl,
        +	mem_new,
        +	mem_free,
        +	NULL,
        +	};
        +
        +/* bio->num is used to hold the value to return on 'empty', if it is
        + * 0, should_retry is not set */
        +
        +BIO_METHOD *BIO_s_mem(void)
        +	{
        +	return(&mem_method);
        +	}
        +
        +BIO *BIO_new_mem_buf(void *buf, int len)
        +{
        +	BIO *ret;
        +	BUF_MEM *b;
        +	size_t sz;
        +
        +	if (!buf) {
        +		BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER);
        +		return NULL;
        +	}
        +	sz = (len<0) ? strlen(buf) : (size_t)len;
        +	if(!(ret = BIO_new(BIO_s_mem())) ) return NULL;
        +	b = (BUF_MEM *)ret->ptr;
        +	b->data = buf;
        +	b->length = sz;
        +	b->max = sz;
        +	ret->flags |= BIO_FLAGS_MEM_RDONLY;
        +	/* Since this is static data retrying wont help */
        +	ret->num = 0;
        +	return ret;
        +}
        +
        +static int mem_new(BIO *bi)
        +	{
        +	BUF_MEM *b;
        +
        +	if ((b=BUF_MEM_new()) == NULL)
        +		return(0);
        +	bi->shutdown=1;
        +	bi->init=1;
        +	bi->num= -1;
        +	bi->ptr=(char *)b;
        +	return(1);
        +	}
        +
        +static int mem_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	if (a->shutdown)
        +		{
        +		if ((a->init) && (a->ptr != NULL))
        +			{
        +			BUF_MEM *b;
        +			b = (BUF_MEM *)a->ptr;
        +			if(a->flags & BIO_FLAGS_MEM_RDONLY) b->data = NULL;
        +			BUF_MEM_free(b);
        +			a->ptr=NULL;
        +			}
        +		}
        +	return(1);
        +	}
        +	
        +static int mem_read(BIO *b, char *out, int outl)
        +	{
        +	int ret= -1;
        +	BUF_MEM *bm;
        +
        +	bm=(BUF_MEM *)b->ptr;
        +	BIO_clear_retry_flags(b);
        +	ret=(outl >=0 && (size_t)outl > bm->length)?(int)bm->length:outl;
        +	if ((out != NULL) && (ret > 0)) {
        +		memcpy(out,bm->data,ret);
        +		bm->length-=ret;
        +		if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret;
        +		else {
        +			memmove(&(bm->data[0]),&(bm->data[ret]),bm->length);
        +		}
        +	} else if (bm->length == 0)
        +		{
        +		ret = b->num;
        +		if (ret != 0)
        +			BIO_set_retry_read(b);
        +		}
        +	return(ret);
        +	}
        +
        +static int mem_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret= -1;
        +	int blen;
        +	BUF_MEM *bm;
        +
        +	bm=(BUF_MEM *)b->ptr;
        +	if (in == NULL)
        +		{
        +		BIOerr(BIO_F_MEM_WRITE,BIO_R_NULL_PARAMETER);
        +		goto end;
        +		}
        +
        +	if(b->flags & BIO_FLAGS_MEM_RDONLY) {
        +		BIOerr(BIO_F_MEM_WRITE,BIO_R_WRITE_TO_READ_ONLY_BIO);
        +		goto end;
        +	}
        +
        +	BIO_clear_retry_flags(b);
        +	blen=bm->length;
        +	if (BUF_MEM_grow_clean(bm,blen+inl) != (blen+inl))
        +		goto end;
        +	memcpy(&(bm->data[blen]),in,inl);
        +	ret=inl;
        +end:
        +	return(ret);
        +	}
        +
        +static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +	char **pptr;
        +
        +	BUF_MEM *bm=(BUF_MEM *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		if (bm->data != NULL)
        +			{
        +			/* For read only case reset to the start again */
        +			if(b->flags & BIO_FLAGS_MEM_RDONLY) 
        +				{
        +				bm->data -= bm->max - bm->length;
        +				bm->length = bm->max;
        +				}
        +			else
        +				{
        +				memset(bm->data,0,bm->max);
        +				bm->length=0;
        +				}
        +			}
        +		break;
        +	case BIO_CTRL_EOF:
        +		ret=(long)(bm->length == 0);
        +		break;
        +	case BIO_C_SET_BUF_MEM_EOF_RETURN:
        +		b->num=(int)num;
        +		break;
        +	case BIO_CTRL_INFO:
        +		ret=(long)bm->length;
        +		if (ptr != NULL)
        +			{
        +			pptr=(char **)ptr;
        +			*pptr=(char *)&(bm->data[0]);
        +			}
        +		break;
        +	case BIO_C_SET_BUF_MEM:
        +		mem_free(b);
        +		b->shutdown=(int)num;
        +		b->ptr=ptr;
        +		break;
        +	case BIO_C_GET_BUF_MEM_PTR:
        +		if (ptr != NULL)
        +			{
        +			pptr=(char **)ptr;
        +			*pptr=(char *)bm;
        +			}
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=(long)b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +
        +	case BIO_CTRL_WPENDING:
        +		ret=0L;
        +		break;
        +	case BIO_CTRL_PENDING:
        +		ret=(long)bm->length;
        +		break;
        +	case BIO_CTRL_DUP:
        +	case BIO_CTRL_FLUSH:
        +		ret=1;
        +		break;
        +	case BIO_CTRL_PUSH:
        +	case BIO_CTRL_POP:
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int mem_gets(BIO *bp, char *buf, int size)
        +	{
        +	int i,j;
        +	int ret= -1;
        +	char *p;
        +	BUF_MEM *bm=(BUF_MEM *)bp->ptr;
        +
        +	BIO_clear_retry_flags(bp);
        +	j=bm->length;
        +	if ((size-1) < j) j=size-1;
        +	if (j <= 0)
        +		{
        +		*buf='\0';
        +		return 0;
        +		}
        +	p=bm->data;
        +	for (i=0; i<j; i++)
        +		{
        +		if (p[i] == '\n')
        +			{
        +			i++;
        +			break;
        +			}
        +		}
        +
        +	/*
        +	 * i is now the max num of bytes to copy, either j or up to
        +	 * and including the first newline
        +	 */ 
        +
        +	i=mem_read(bp,buf,i);
        +	if (i > 0) buf[i]='\0';
        +	ret=i;
        +	return(ret);
        +	}
        +
        +static int mem_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=mem_write(bp,str,n);
        +	/* memory semantics is that it will always work */
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_null.c b/vendor/openssl/openssl/crypto/bio/bss_null.c
        new file mode 100644
        index 000000000..46b73339d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_null.c
        @@ -0,0 +1,150 @@
        +/* crypto/bio/bss_null.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +static int null_write(BIO *h, const char *buf, int num);
        +static int null_read(BIO *h, char *buf, int size);
        +static int null_puts(BIO *h, const char *str);
        +static int null_gets(BIO *h, char *str, int size);
        +static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int null_new(BIO *h);
        +static int null_free(BIO *data);
        +static BIO_METHOD null_method=
        +	{
        +	BIO_TYPE_NULL,
        +	"NULL",
        +	null_write,
        +	null_read,
        +	null_puts,
        +	null_gets,
        +	null_ctrl,
        +	null_new,
        +	null_free,
        +	NULL,
        +	};
        +
        +BIO_METHOD *BIO_s_null(void)
        +	{
        +	return(&null_method);
        +	}
        +
        +static int null_new(BIO *bi)
        +	{
        +	bi->init=1;
        +	bi->num=0;
        +	bi->ptr=(NULL);
        +	return(1);
        +	}
        +
        +static int null_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	return(1);
        +	}
        +	
        +static int null_read(BIO *b, char *out, int outl)
        +	{
        +	return(0);
        +	}
        +
        +static int null_write(BIO *b, const char *in, int inl)
        +	{
        +	return(inl);
        +	}
        +
        +static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +	case BIO_CTRL_EOF:
        +	case BIO_CTRL_SET:
        +	case BIO_CTRL_SET_CLOSE:
        +	case BIO_CTRL_FLUSH:
        +	case BIO_CTRL_DUP:
        +		ret=1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +	case BIO_CTRL_INFO:
        +	case BIO_CTRL_GET:
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_WPENDING:
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int null_gets(BIO *bp, char *buf, int size)
        +	{
        +	return(0);
        +	}
        +
        +static int null_puts(BIO *bp, const char *str)
        +	{
        +	if (str == NULL) return(0);
        +	return(strlen(str));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_rtcp.c b/vendor/openssl/openssl/crypto/bio/bss_rtcp.c
        new file mode 100644
        index 000000000..7dae48556
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_rtcp.c
        @@ -0,0 +1,294 @@
        +/* crypto/bio/bss_rtcp.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.]
        + */
        +
        +/* Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu>
        + * Date:   22-JUL-1996
        + * Revised: 25-SEP-1997		Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD
        + */
        +/* VMS */
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +
        +#include <iodef.h>		/* VMS IO$_ definitions */
        +#include <starlet.h>
        +
        +typedef unsigned short io_channel;
        +/*************************************************************************/
        +struct io_status { short status, count; long flags; };
        +
        +struct rpc_msg {		/* Should have member alignment inhibited */
        +   char channel;		/* 'A'-app data. 'R'-remote client 'G'-global */
        +   char function;		/* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */
        +   unsigned short int length;	/* Amount of data returned or max to return */
        +   char data[4092];		/* variable data */
        +};
        +#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092)
        +
        +struct rpc_ctx {
        +    int filled, pos;
        +    struct rpc_msg msg;
        +};
        +
        +static int rtcp_write(BIO *h,const char *buf,int num);
        +static int rtcp_read(BIO *h,char *buf,int size);
        +static int rtcp_puts(BIO *h,const char *str);
        +static int rtcp_gets(BIO *h,char *str,int size);
        +static long rtcp_ctrl(BIO *h,int cmd,long arg1,void *arg2);
        +static int rtcp_new(BIO *h);
        +static int rtcp_free(BIO *data);
        +
        +static BIO_METHOD rtcp_method=
        +	{
        +	BIO_TYPE_FD,
        +	"RTCP",
        +	rtcp_write,
        +	rtcp_read,
        +	rtcp_puts,
        +	rtcp_gets,
        +	rtcp_ctrl,
        +	rtcp_new,
        +	rtcp_free,
        +	NULL,
        +	};
        +
        +BIO_METHOD *BIO_s_rtcp(void)
        +	{
        +	return(&rtcp_method);
        +	}
        +/*****************************************************************************/
        +/* Decnet I/O routines.
        + */
        +
        +#ifdef __DECC
        +#pragma message save
        +#pragma message disable DOLLARID
        +#endif
        +
        +static int get ( io_channel chan, char *buffer, int maxlen, int *length )
        +{
        +    int status;
        +    struct io_status iosb;
        +    status = sys$qiow ( 0, chan, IO$_READVBLK, &iosb, 0, 0,
        +	buffer, maxlen, 0, 0, 0, 0 );
        +    if ( (status&1) == 1 ) status = iosb.status;
        +    if ( (status&1) == 1 ) *length = iosb.count;
        +    return status;
        +}
        +
        +static int put ( io_channel chan, char *buffer, int length )
        +{
        +    int status;
        +    struct io_status iosb;
        +    status = sys$qiow ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0,
        +	buffer, length, 0, 0, 0, 0 );
        +    if ( (status&1) == 1 ) status = iosb.status;
        +    return status;
        +}
        +
        +#ifdef __DECC
        +#pragma message restore
        +#endif
        +
        +/***************************************************************************/
        +
        +static int rtcp_new(BIO *bi)
        +{
        +    struct rpc_ctx *ctx;
        +	bi->init=1;
        +	bi->num=0;
        +	bi->flags = 0;
        +	bi->ptr=OPENSSL_malloc(sizeof(struct rpc_ctx));
        +	ctx = (struct rpc_ctx *) bi->ptr;
        +	ctx->filled = 0;
        +	ctx->pos = 0;
        +	return(1);
        +}
        +
        +static int rtcp_free(BIO *a)
        +{
        +	if (a == NULL) return(0);
        +	if ( a->ptr ) OPENSSL_free ( a->ptr );
        +	a->ptr = NULL;
        +	return(1);
        +}
        +	
        +static int rtcp_read(BIO *b, char *out, int outl)
        +{
        +    int status, length;
        +    struct rpc_ctx *ctx;
        +    /*
        +     * read data, return existing.
        +     */
        +    ctx = (struct rpc_ctx *) b->ptr;
        +    if ( ctx->pos < ctx->filled ) {
        +	length = ctx->filled - ctx->pos;
        +	if ( length > outl ) length = outl;
        +	memmove ( out, &ctx->msg.data[ctx->pos], length );
        +	ctx->pos += length;
        +	return length;
        +    }
        +    /*
        +     * Requst more data from R channel.
        +     */
        +    ctx->msg.channel = 'R';
        +    ctx->msg.function = 'G';
        +    ctx->msg.length = sizeof(ctx->msg.data);
        +    status = put ( b->num, (char *) &ctx->msg, RPC_HDR_SIZE );
        +    if ( (status&1) == 0 ) {
        +	return -1;
        +    }
        +    /*
        +     * Read.
        +     */
        +    ctx->pos = ctx->filled = 0;
        +    status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length );
        +    if ( (status&1) == 0 ) length = -1;
        +    if ( ctx->msg.channel != 'R' || ctx->msg.function != 'C' ) {
        +	length = -1;
        +    }
        +    ctx->filled = length - RPC_HDR_SIZE;
        +    
        +    if ( ctx->pos < ctx->filled ) {
        +	length = ctx->filled - ctx->pos;
        +	if ( length > outl ) length = outl;
        +	memmove ( out, ctx->msg.data, length );
        +	ctx->pos += length;
        +	return length;
        +    }
        +
        +    return length;
        +}
        +
        +static int rtcp_write(BIO *b, const char *in, int inl)
        +{
        +    int status, i, segment, length;
        +    struct rpc_ctx *ctx;
        +    /*
        +     * Output data, send in chunks no larger that sizeof(ctx->msg.data).
        +     */
        +    ctx = (struct rpc_ctx *) b->ptr;
        +    for ( i = 0; i < inl; i += segment ) {
        +	segment = inl - i;
        +	if ( segment > sizeof(ctx->msg.data) ) segment = sizeof(ctx->msg.data);
        +	ctx->msg.channel = 'R';
        +	ctx->msg.function = 'P';
        +	ctx->msg.length = segment;
        +	memmove ( ctx->msg.data, &in[i], segment );
        +	status = put ( b->num, (char *) &ctx->msg, segment + RPC_HDR_SIZE );
        +	if ((status&1) == 0 ) { i = -1; break; }
        +
        +	status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length );
        +	if ( ((status&1) == 0) || (length < RPC_HDR_SIZE) ) { i = -1; break; }
        +	if ( (ctx->msg.channel != 'R') || (ctx->msg.function != 'C') ) {
        +	   printf("unexpected response when confirming put %c %c\n",
        +		ctx->msg.channel, ctx->msg.function );
        +
        +	}
        +    }
        +    return(i);
        +}
        +
        +static long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +	case BIO_CTRL_EOF:
        +		ret = 1;
        +		break;
        +	case BIO_C_SET_FD:
        +		b->num = num;
        +		ret = 1;
        +	 	break;
        +	case BIO_CTRL_SET_CLOSE:
        +	case BIO_CTRL_FLUSH:
        +	case BIO_CTRL_DUP:
        +		ret=1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +	case BIO_CTRL_INFO:
        +	case BIO_CTRL_GET:
        +	case BIO_CTRL_PENDING:
        +	case BIO_CTRL_WPENDING:
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int rtcp_gets(BIO *bp, char *buf, int size)
        +	{
        +	return(0);
        +	}
        +
        +static int rtcp_puts(BIO *bp, const char *str)
        +{
        +    int length;
        +    if (str == NULL) return(0);
        +    length = strlen ( str );
        +    if ( length == 0 ) return (0);
        +    return rtcp_write ( bp,str, length );
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/bio/bss_sock.c b/vendor/openssl/openssl/crypto/bio/bss_sock.c
        new file mode 100644
        index 000000000..3df31938c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bio/bss_sock.c
        @@ -0,0 +1,294 @@
        +/* crypto/bio/bss_sock.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_SOCK
        +
        +#include <openssl/bio.h>
        +
        +#ifdef WATT32
        +#define sock_write SockWrite  /* Watt-32 uses same names */
        +#define sock_read  SockRead
        +#define sock_puts  SockPuts
        +#endif
        +
        +static int sock_write(BIO *h, const char *buf, int num);
        +static int sock_read(BIO *h, char *buf, int size);
        +static int sock_puts(BIO *h, const char *str);
        +static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int sock_new(BIO *h);
        +static int sock_free(BIO *data);
        +int BIO_sock_should_retry(int s);
        +
        +static BIO_METHOD methods_sockp=
        +	{
        +	BIO_TYPE_SOCKET,
        +	"socket",
        +	sock_write,
        +	sock_read,
        +	sock_puts,
        +	NULL, /* sock_gets, */
        +	sock_ctrl,
        +	sock_new,
        +	sock_free,
        +	NULL,
        +	};
        +
        +BIO_METHOD *BIO_s_socket(void)
        +	{
        +	return(&methods_sockp);
        +	}
        +
        +BIO *BIO_new_socket(int fd, int close_flag)
        +	{
        +	BIO *ret;
        +
        +	ret=BIO_new(BIO_s_socket());
        +	if (ret == NULL) return(NULL);
        +	BIO_set_fd(ret,fd,close_flag);
        +	return(ret);
        +	}
        +
        +static int sock_new(BIO *bi)
        +	{
        +	bi->init=0;
        +	bi->num=0;
        +	bi->ptr=NULL;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int sock_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	if (a->shutdown)
        +		{
        +		if (a->init)
        +			{
        +			SHUTDOWN2(a->num);
        +			}
        +		a->init=0;
        +		a->flags=0;
        +		}
        +	return(1);
        +	}
        +	
        +static int sock_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +
        +	if (out != NULL)
        +		{
        +		clear_socket_error();
        +		ret=readsocket(b->num,out,outl);
        +		BIO_clear_retry_flags(b);
        +		if (ret <= 0)
        +			{
        +			if (BIO_sock_should_retry(ret))
        +				BIO_set_retry_read(b);
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +static int sock_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret;
        +	
        +	clear_socket_error();
        +	ret=writesocket(b->num,in,inl);
        +	BIO_clear_retry_flags(b);
        +	if (ret <= 0)
        +		{
        +		if (BIO_sock_should_retry(ret))
        +			BIO_set_retry_write(b);
        +		}
        +	return(ret);
        +	}
        +
        +static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	long ret=1;
        +	int *ip;
        +
        +	switch (cmd)
        +		{
        +	case BIO_C_SET_FD:
        +		sock_free(b);
        +		b->num= *((int *)ptr);
        +		b->shutdown=(int)num;
        +		b->init=1;
        +		break;
        +	case BIO_C_GET_FD:
        +		if (b->init)
        +			{
        +			ip=(int *)ptr;
        +			if (ip != NULL) *ip=b->num;
        +			ret=b->num;
        +			}
        +		else
        +			ret= -1;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_DUP:
        +	case BIO_CTRL_FLUSH:
        +		ret=1;
        +		break;
        +	default:
        +		ret=0;
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int sock_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=sock_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +int BIO_sock_should_retry(int i)
        +	{
        +	int err;
        +
        +	if ((i == 0) || (i == -1))
        +		{
        +		err=get_last_socket_error();
        +
        +#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
        +		if ((i == -1) && (err == 0))
        +			return(1);
        +#endif
        +
        +		return(BIO_sock_non_fatal_error(err));
        +		}
        +	return(0);
        +	}
        +
        +int BIO_sock_non_fatal_error(int err)
        +	{
        +	switch (err)
        +		{
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
        +# if defined(WSAEWOULDBLOCK)
        +	case WSAEWOULDBLOCK:
        +# endif
        +
        +# if 0 /* This appears to always be an error */
        +#  if defined(WSAENOTCONN)
        +	case WSAENOTCONN:
        +#  endif
        +# endif
        +#endif
        +
        +#ifdef EWOULDBLOCK
        +# ifdef WSAEWOULDBLOCK
        +#  if WSAEWOULDBLOCK != EWOULDBLOCK
        +	case EWOULDBLOCK:
        +#  endif
        +# else
        +	case EWOULDBLOCK:
        +# endif
        +#endif
        +
        +#if defined(ENOTCONN)
        +	case ENOTCONN:
        +#endif
        +
        +#ifdef EINTR
        +	case EINTR:
        +#endif
        +
        +#ifdef EAGAIN
        +# if EWOULDBLOCK != EAGAIN
        +	case EAGAIN:
        +# endif
        +#endif
        +
        +#ifdef EPROTO
        +	case EPROTO:
        +#endif
        +
        +#ifdef EINPROGRESS
        +	case EINPROGRESS:
        +#endif
        +
        +#ifdef EALREADY
        +	case EALREADY:
        +#endif
        +		return(1);
        +		/* break; */
        +	default:
        +		break;
        +		}
        +	return(0);
        +	}
        +
        +#endif  /* #ifndef OPENSSL_NO_SOCK */
        diff --git a/vendor/openssl/openssl/crypto/bn/Makefile b/vendor/openssl/openssl/crypto/bn/Makefile
        new file mode 100644
        index 000000000..672773454
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/Makefile
        @@ -0,0 +1,375 @@
        +#
        +# OpenSSL/crypto/bn/Makefile
        +#
        +
        +DIR=	bn
        +TOP=	../..
        +CC=	cc
        +CPP=    $(CC) -E
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +BN_ASM=		bn_asm.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=bntest.c exptest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
        +	bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
        +	bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
        +	bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
        +	bn_depr.c bn_const.c bn_x931p.c
        +
        +LIBOBJ=	bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
        +	bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
        +	bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
        +	bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o \
        +	bn_depr.o bn_const.o bn_x931p.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= bn.h
        +HEADER=	bn_lcl.h bn_prime.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +bn_prime.h: bn_prime.pl
        +	$(PERL) bn_prime.pl >bn_prime.h
        +
        +divtest: divtest.c ../../libcrypto.a
        +	cc -I../../include divtest.c -o divtest ../../libcrypto.a
        +
        +bnbug: bnbug.c ../../libcrypto.a top
        +	cc -g -I../../include bnbug.c -o bnbug ../../libcrypto.a
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +bn-586.s:	asm/bn-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/bn-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +co-586.s:	asm/co-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/co-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +x86-mont.s:	asm/x86-mont.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/x86-mont.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +x86-gf2m.s:	asm/x86-gf2m.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/x86-gf2m.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +
        +sparcv8.o:	asm/sparcv8.S
        +	$(CC) $(CFLAGS) -c asm/sparcv8.S
        +bn-sparcv9.o:	asm/sparcv8plus.S
        +	$(CC) $(CFLAGS) -c -o $@ asm/sparcv8plus.S
        +sparcv9a-mont.s:	asm/sparcv9a-mont.pl
        +	$(PERL) asm/sparcv9a-mont.pl $(CFLAGS) > $@
        +sparcv9-mont.s:		asm/sparcv9-mont.pl
        +	$(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@
        +
        +bn-mips3.o:	asm/mips3.s
        +	@if [ "$(CC)" = "gcc" ]; then \
        +		ABI=`expr "$(CFLAGS)" : ".*-mabi=\([n3264]*\)"` && \
        +		as -$$ABI -O -o $@ asm/mips3.s; \
        +	else	$(CC) -c $(CFLAGS) -o $@ asm/mips3.s; fi
        +
        +bn-mips.s:	asm/mips.pl
        +	$(PERL) asm/mips.pl $(PERLASM_SCHEME) $@
        +mips-mont.s:	asm/mips-mont.pl
        +	$(PERL)	asm/mips-mont.pl $(PERLASM_SCHEME) $@
        +
        +bn-s390x.o:	asm/s390x.S
        +	$(CC) $(CFLAGS) -c -o $@ asm/s390x.S
        +s390x-gf2m.s:	asm/s390x-gf2m.pl
        +	$(PERL) asm/s390x-gf2m.pl $(PERLASM_SCHEME) $@
        +
        +x86_64-gcc.o:	asm/x86_64-gcc.c
        +	$(CC) $(CFLAGS) -c -o $@ asm/x86_64-gcc.c
        +x86_64-mont.s:	asm/x86_64-mont.pl
        +	$(PERL) asm/x86_64-mont.pl $(PERLASM_SCHEME) > $@
        +x86_64-mont5.s:	asm/x86_64-mont5.pl
        +	$(PERL) asm/x86_64-mont5.pl $(PERLASM_SCHEME) > $@
        +x86_64-gf2m.s:	asm/x86_64-gf2m.pl
        +	$(PERL) asm/x86_64-gf2m.pl $(PERLASM_SCHEME) > $@
        +modexp512-x86_64.s:	asm/modexp512-x86_64.pl
        +	$(PERL) asm/modexp512-x86_64.pl $(PERLASM_SCHEME) > $@
        +
        +bn-ia64.s:	asm/ia64.S
        +	$(CC) $(CFLAGS) -E asm/ia64.S > $@
        +ia64-mont.s:	asm/ia64-mont.pl
        +	$(PERL) asm/ia64-mont.pl $@ $(CFLAGS)
        +
        +# GNU assembler fails to compile PA-RISC2 modules, insist on calling
        +# vendor assembler...
        +pa-risc2W.o: asm/pa-risc2W.s
        +	/usr/ccs/bin/as -o pa-risc2W.o asm/pa-risc2W.s
        +pa-risc2.o: asm/pa-risc2.s
        +	/usr/ccs/bin/as -o pa-risc2.o asm/pa-risc2.s
        +parisc-mont.s:	asm/parisc-mont.pl
        +	$(PERL) asm/parisc-mont.pl $(PERLASM_SCHEME) $@
        +
        +# ppc - AIX, Linux, MacOS X...
        +bn-ppc.s:	asm/ppc.pl;	$(PERL) asm/ppc.pl $(PERLASM_SCHEME) $@
        +ppc-mont.s:	asm/ppc-mont.pl;$(PERL) asm/ppc-mont.pl $(PERLASM_SCHEME) $@
        +ppc64-mont.s:	asm/ppc64-mont.pl;$(PERL) asm/ppc64-mont.pl $(PERLASM_SCHEME) $@
        +
        +alpha-mont.s:	asm/alpha-mont.pl
        +	$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
        +
        +# GNU make "catch all"
        +%-mont.s:	asm/%-mont.pl;	$(PERL) $< $(PERLASM_SCHEME) $@
        +%-gf2m.S:	asm/%-gf2m.pl;	$(PERL) $< $(PERLASM_SCHEME) $@
        +
        +armv4-gf2m.o:	armv4-gf2m.S
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	do  \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +
        +exptest:
        +	rm -f exptest
        +	gcc -I../../include -g2 -ggdb -o exptest exptest.c ../../libcrypto.a
        +
        +div:
        +	rm -f a.out
        +	gcc -I.. -g div.c ../../libcrypto.a
        +
        +tags:
        +	ctags $(SRC)
        +
        +tests:
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +
        +depend:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +bn_add.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_add.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_add.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_add.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_add.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_add.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_add.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_add.c bn_lcl.h
        +bn_asm.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_asm.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_asm.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_asm.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_asm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_asm.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_asm.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_asm.c bn_lcl.h
        +bn_blind.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_blind.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_blind.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_blind.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_blind.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_blind.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_blind.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_blind.c bn_lcl.h
        +bn_const.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bn_const.o: ../../include/openssl/opensslconf.h
        +bn_const.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_const.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_const.o: ../../include/openssl/symhacks.h bn.h bn_const.c
        +bn_ctx.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_ctx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_ctx.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_ctx.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_ctx.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_ctx.c bn_lcl.h
        +bn_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_depr.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +bn_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bn_depr.o: ../cryptlib.h bn_depr.c bn_lcl.h
        +bn_div.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_div.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_div.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_div.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_div.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_div.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_div.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_div.c bn_lcl.h
        +bn_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bn_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +bn_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +bn_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +bn_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bn_err.o: bn_err.c
        +bn_exp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_exp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_exp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_exp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_exp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_exp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_exp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp.c bn_lcl.h
        +bn_exp2.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_exp2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_exp2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_exp2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_exp2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_exp2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_exp2.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp2.c bn_lcl.h
        +bn_gcd.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_gcd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_gcd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_gcd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_gcd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_gcd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_gcd.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gcd.c bn_lcl.h
        +bn_gf2m.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_gf2m.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_gf2m.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_gf2m.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_gf2m.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_gf2m.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_gf2m.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gf2m.c bn_lcl.h
        +bn_kron.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_kron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_kron.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_kron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_kron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_kron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_kron.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_kron.c bn_lcl.h
        +bn_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_lib.c
        +bn_mod.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_mod.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_mod.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_mod.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_mod.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_mod.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mod.c
        +bn_mont.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_mont.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_mont.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_mont.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mont.c
        +bn_mpi.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_mpi.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_mpi.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_mpi.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_mpi.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_mpi.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_mpi.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mpi.c
        +bn_mul.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_mul.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_mul.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_mul.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_mul.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_mul.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_mul.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mul.c
        +bn_nist.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_nist.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_nist.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_nist.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_nist.c
        +bn_prime.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_prime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_prime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_prime.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_prime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_prime.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +bn_prime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bn_prime.o: ../cryptlib.h bn_lcl.h bn_prime.c bn_prime.h
        +bn_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_print.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_print.c
        +bn_rand.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_rand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +bn_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bn_rand.o: ../cryptlib.h bn_lcl.h bn_rand.c
        +bn_recp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_recp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_recp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_recp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_recp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_recp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_recp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_recp.c
        +bn_shift.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_shift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_shift.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_shift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_shift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_shift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_shift.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_shift.c
        +bn_sqr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_sqr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_sqr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_sqr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_sqr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_sqr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_sqr.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_sqr.c
        +bn_sqrt.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_sqrt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_sqrt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_sqrt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_sqrt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_sqrt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_sqrt.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_sqrt.c
        +bn_word.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +bn_word.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bn_word.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bn_word.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +bn_word.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_word.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_word.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_word.c
        +bn_x931p.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +bn_x931p.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +bn_x931p.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bn_x931p.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bn_x931p.o: ../../include/openssl/symhacks.h bn_x931p.c
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/README b/vendor/openssl/openssl/crypto/bn/asm/README
        new file mode 100644
        index 000000000..b0f3a68a0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/README
        @@ -0,0 +1,27 @@
        +<OBSOLETE>
        +
        +All assember in this directory are just version of the file
        +crypto/bn/bn_asm.c.
        +
        +Quite a few of these files are just the assember output from gcc since on 
        +quite a few machines they are 2 times faster than the system compiler.
        +
        +For the x86, I have hand written assember because of the bad job all
        +compilers seem to do on it.  This normally gives a 2 time speed up in the RSA
        +routines.
        +
        +For the DEC alpha, I also hand wrote the assember (except the division which
        +is just the output from the C compiler pasted on the end of the file).
        +On the 2 alpha C compilers I had access to, it was not possible to do
        +64b x 64b -> 128b calculations (both long and the long long data types
        +were 64 bits).  So the hand assember gives access to the 128 bit result and
        +a 2 times speedup :-).
        +
        +There are 3 versions of assember for the HP PA-RISC.
        +
        +pa-risc.s is the origional one which works fine and generated using gcc :-)
        +
        +pa-risc2W.s and pa-risc2.s are 64 and 32-bit PA-RISC 2.0 implementations
        +by Chris Ruemmler from HP (with some help from the HP C compiler).
        +
        +</OBSOLETE>
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/alpha-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/alpha-mont.pl
        new file mode 100644
        index 000000000..03596e201
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/alpha-mont.pl
        @@ -0,0 +1,321 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# On 21264 RSA sign performance improves by 70/35/20/15 percent for
        +# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
        +# instructed to '-tune host' code with in-line assembler. Other
        +# benchmarks improve by 15-20%. To anchor it to something else, the
        +# code provides approximately the same performance per GHz as AMD64.
        +# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
        +# difference.
        +
        +# int bn_mul_mont(
        +$rp="a0";	# BN_ULONG *rp,
        +$ap="a1";	# const BN_ULONG *ap,
        +$bp="a2";	# const BN_ULONG *bp,
        +$np="a3";	# const BN_ULONG *np,
        +$n0="a4";	# const BN_ULONG *n0,
        +$num="a5";	# int num);
        +
        +$lo0="t0";
        +$hi0="t1";
        +$lo1="t2";
        +$hi1="t3";
        +$aj="t4";
        +$bi="t5";
        +$nj="t6";
        +$tp="t7";
        +$alo="t8";
        +$ahi="t9";
        +$nlo="t10";
        +$nhi="t11";
        +$tj="t12";
        +$i="s3";
        +$j="s4";
        +$m1="s5";
        +
        +$code=<<___;
        +#ifdef __linux__
        +#include <asm/regdef.h>
        +#else
        +#include <asm.h>
        +#include <regdef.h>
        +#endif
        +
        +.text
        +
        +.set	noat
        +.set	noreorder
        +
        +.globl	bn_mul_mont
        +.align	5
        +.ent	bn_mul_mont
        +bn_mul_mont:
        +	lda	sp,-48(sp)
        +	stq	ra,0(sp)
        +	stq	s3,8(sp)
        +	stq	s4,16(sp)
        +	stq	s5,24(sp)
        +	stq	fp,32(sp)
        +	mov	sp,fp
        +	.mask	0x0400f000,-48
        +	.frame	fp,48,ra
        +	.prologue 0
        +
        +	.align	4
        +	.set	reorder
        +	sextl	$num,$num
        +	mov	0,v0
        +	cmplt	$num,4,AT
        +	bne	AT,.Lexit
        +
        +	ldq	$hi0,0($ap)	# ap[0]
        +	s8addq	$num,16,AT
        +	ldq	$aj,8($ap)
        +	subq	sp,AT,sp
        +	ldq	$bi,0($bp)	# bp[0]
        +	lda	AT,-4096(zero)	# mov	-4096,AT
        +	ldq	$n0,0($n0)
        +	and	sp,AT,sp
        +
        +	mulq	$hi0,$bi,$lo0
        +	ldq	$hi1,0($np)	# np[0]
        +	umulh	$hi0,$bi,$hi0
        +	ldq	$nj,8($np)
        +
        +	mulq	$lo0,$n0,$m1
        +
        +	mulq	$hi1,$m1,$lo1
        +	umulh	$hi1,$m1,$hi1
        +
        +	addq	$lo1,$lo0,$lo1
        +	cmpult	$lo1,$lo0,AT
        +	addq	$hi1,AT,$hi1
        +
        +	mulq	$aj,$bi,$alo
        +	mov	2,$j
        +	umulh	$aj,$bi,$ahi
        +	mov	sp,$tp
        +
        +	mulq	$nj,$m1,$nlo
        +	s8addq	$j,$ap,$aj
        +	umulh	$nj,$m1,$nhi
        +	s8addq	$j,$np,$nj
        +.align	4
        +.L1st:
        +	.set	noreorder
        +	ldq	$aj,0($aj)
        +	addl	$j,1,$j
        +	ldq	$nj,0($nj)
        +	lda	$tp,8($tp)
        +
        +	addq	$alo,$hi0,$lo0
        +	mulq	$aj,$bi,$alo
        +	cmpult	$lo0,$hi0,AT
        +	addq	$nlo,$hi1,$lo1
        +
        +	mulq	$nj,$m1,$nlo
        +	addq	$ahi,AT,$hi0
        +	cmpult	$lo1,$hi1,v0
        +	cmplt	$j,$num,$tj
        +
        +	umulh	$aj,$bi,$ahi
        +	addq	$nhi,v0,$hi1
        +	addq	$lo1,$lo0,$lo1
        +	s8addq	$j,$ap,$aj
        +
        +	umulh	$nj,$m1,$nhi
        +	cmpult	$lo1,$lo0,v0
        +	addq	$hi1,v0,$hi1
        +	s8addq	$j,$np,$nj
        +
        +	stq	$lo1,-8($tp)
        +	nop
        +	unop
        +	bne	$tj,.L1st
        +	.set	reorder
        +
        +	addq	$alo,$hi0,$lo0
        +	addq	$nlo,$hi1,$lo1
        +	cmpult	$lo0,$hi0,AT
        +	cmpult	$lo1,$hi1,v0
        +	addq	$ahi,AT,$hi0
        +	addq	$nhi,v0,$hi1
        +
        +	addq	$lo1,$lo0,$lo1
        +	cmpult	$lo1,$lo0,v0
        +	addq	$hi1,v0,$hi1
        +
        +	stq	$lo1,0($tp)
        +
        +	addq	$hi1,$hi0,$hi1
        +	cmpult	$hi1,$hi0,AT
        +	stq	$hi1,8($tp)
        +	stq	AT,16($tp)
        +
        +	mov	1,$i
        +.align	4
        +.Louter:
        +	s8addq	$i,$bp,$bi
        +	ldq	$hi0,0($ap)
        +	ldq	$aj,8($ap)
        +	ldq	$bi,0($bi)
        +	ldq	$hi1,0($np)
        +	ldq	$nj,8($np)
        +	ldq	$tj,0(sp)
        +
        +	mulq	$hi0,$bi,$lo0
        +	umulh	$hi0,$bi,$hi0
        +
        +	addq	$lo0,$tj,$lo0
        +	cmpult	$lo0,$tj,AT
        +	addq	$hi0,AT,$hi0
        +
        +	mulq	$lo0,$n0,$m1
        +
        +	mulq	$hi1,$m1,$lo1
        +	umulh	$hi1,$m1,$hi1
        +
        +	addq	$lo1,$lo0,$lo1
        +	cmpult	$lo1,$lo0,AT
        +	mov	2,$j
        +	addq	$hi1,AT,$hi1
        +
        +	mulq	$aj,$bi,$alo
        +	mov	sp,$tp
        +	umulh	$aj,$bi,$ahi
        +
        +	mulq	$nj,$m1,$nlo
        +	s8addq	$j,$ap,$aj
        +	umulh	$nj,$m1,$nhi
        +.align	4
        +.Linner:
        +	.set	noreorder
        +	ldq	$tj,8($tp)	#L0
        +	nop			#U1
        +	ldq	$aj,0($aj)	#L1
        +	s8addq	$j,$np,$nj	#U0
        +
        +	ldq	$nj,0($nj)	#L0
        +	nop			#U1
        +	addq	$alo,$hi0,$lo0	#L1
        +	lda	$tp,8($tp)
        +
        +	mulq	$aj,$bi,$alo	#U1
        +	cmpult	$lo0,$hi0,AT	#L0
        +	addq	$nlo,$hi1,$lo1	#L1
        +	addl	$j,1,$j
        +
        +	mulq	$nj,$m1,$nlo	#U1
        +	addq	$ahi,AT,$hi0	#L0
        +	addq	$lo0,$tj,$lo0	#L1
        +	cmpult	$lo1,$hi1,v0	#U0
        +
        +	umulh	$aj,$bi,$ahi	#U1
        +	cmpult	$lo0,$tj,AT	#L0
        +	addq	$lo1,$lo0,$lo1	#L1
        +	addq	$nhi,v0,$hi1	#U0
        +
        +	umulh	$nj,$m1,$nhi	#U1
        +	s8addq	$j,$ap,$aj	#L0
        +	cmpult	$lo1,$lo0,v0	#L1
        +	cmplt	$j,$num,$tj	#U0	# borrow $tj
        +
        +	addq	$hi0,AT,$hi0	#L0
        +	addq	$hi1,v0,$hi1	#U1
        +	stq	$lo1,-8($tp)	#L1
        +	bne	$tj,.Linner	#U0
        +	.set	reorder
        +
        +	ldq	$tj,8($tp)
        +	addq	$alo,$hi0,$lo0
        +	addq	$nlo,$hi1,$lo1
        +	cmpult	$lo0,$hi0,AT
        +	cmpult	$lo1,$hi1,v0
        +	addq	$ahi,AT,$hi0
        +	addq	$nhi,v0,$hi1
        +
        +	addq	$lo0,$tj,$lo0
        +	cmpult	$lo0,$tj,AT
        +	addq	$hi0,AT,$hi0
        +
        +	ldq	$tj,16($tp)
        +	addq	$lo1,$lo0,$j
        +	cmpult	$j,$lo0,v0
        +	addq	$hi1,v0,$hi1
        +
        +	addq	$hi1,$hi0,$lo1
        +	stq	$j,0($tp)
        +	cmpult	$lo1,$hi0,$hi1
        +	addq	$lo1,$tj,$lo1
        +	cmpult	$lo1,$tj,AT
        +	addl	$i,1,$i
        +	addq	$hi1,AT,$hi1
        +	stq	$lo1,8($tp)
        +	cmplt	$i,$num,$tj	# borrow $tj
        +	stq	$hi1,16($tp)
        +	bne	$tj,.Louter
        +
        +	s8addq	$num,sp,$tj	# &tp[num]
        +	mov	$rp,$bp		# put rp aside
        +	mov	sp,$tp
        +	mov	sp,$ap
        +	mov	0,$hi0		# clear borrow bit
        +
        +.align	4
        +.Lsub:	ldq	$lo0,0($tp)
        +	ldq	$lo1,0($np)
        +	lda	$tp,8($tp)
        +	lda	$np,8($np)
        +	subq	$lo0,$lo1,$lo1	# tp[i]-np[i]
        +	cmpult	$lo0,$lo1,AT
        +	subq	$lo1,$hi0,$lo0
        +	cmpult	$lo1,$lo0,$hi0
        +	or	$hi0,AT,$hi0
        +	stq	$lo0,0($rp)
        +	cmpult	$tp,$tj,v0
        +	lda	$rp,8($rp)
        +	bne	v0,.Lsub
        +
        +	subq	$hi1,$hi0,$hi0	# handle upmost overflow bit
        +	mov	sp,$tp
        +	mov	$bp,$rp		# restore rp
        +
        +	and	sp,$hi0,$ap
        +	bic	$bp,$hi0,$bp
        +	bis	$bp,$ap,$ap	# ap=borrow?tp:rp
        +
        +.align	4
        +.Lcopy:	ldq	$aj,0($ap)	# copy or in-place refresh
        +	lda	$tp,8($tp)
        +	lda	$rp,8($rp)
        +	lda	$ap,8($ap)
        +	stq	zero,-8($tp)	# zap tp
        +	cmpult	$tp,$tj,AT
        +	stq	$aj,-8($rp)
        +	bne	AT,.Lcopy
        +	mov	1,v0
        +
        +.Lexit:
        +	.set	noreorder
        +	mov	fp,sp
        +	/*ldq	ra,0(sp)*/
        +	ldq	s3,8(sp)
        +	ldq	s4,16(sp)
        +	ldq	s5,24(sp)
        +	ldq	fp,32(sp)
        +	lda	sp,48(sp)
        +	ret	(ra)
        +.end	bn_mul_mont
        +.ascii	"Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +___
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl b/vendor/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl
        new file mode 100644
        index 000000000..c52e0b75b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/armv4-gf2m.pl
        @@ -0,0 +1,278 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# May 2011
        +#
        +# The module implements bn_GF2m_mul_2x2 polynomial multiplication
        +# used in bn_gf2m.c. It's kind of low-hanging mechanical port from
        +# C for the time being... Except that it has two code paths: pure
        +# integer code suitable for any ARMv4 and later CPU and NEON code
        +# suitable for ARMv7. Pure integer 1x1 multiplication subroutine runs
        +# in ~45 cycles on dual-issue core such as Cortex A8, which is ~50%
        +# faster than compiler-generated code. For ECDH and ECDSA verify (but
        +# not for ECDSA sign) it means 25%-45% improvement depending on key
        +# length, more for longer keys. Even though NEON 1x1 multiplication
        +# runs in even less cycles, ~30, improvement is measurable only on
        +# longer keys. One has to optimize code elsewhere to get NEON glow...
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
        +sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
        +sub Q()     { shift=~m|d([1-3]?[02468])|?"q".($1/2):""; }
        +
        +$code=<<___;
        +#include "arm_arch.h"
        +
        +.text
        +.code	32
        +
        +#if __ARM_ARCH__>=7
        +.fpu	neon
        +
        +.type	mul_1x1_neon,%function
        +.align	5
        +mul_1x1_neon:
        +	vshl.u64	`&Dlo("q1")`,d16,#8	@ q1-q3 are slided $a
        +	vmull.p8	`&Q("d0")`,d16,d17	@ a·bb
        +	vshl.u64	`&Dlo("q2")`,d16,#16
        +	vmull.p8	q1,`&Dlo("q1")`,d17	@ a<<8·bb
        +	vshl.u64	`&Dlo("q3")`,d16,#24
        +	vmull.p8	q2,`&Dlo("q2")`,d17	@ a<<16·bb
        +	vshr.u64	`&Dlo("q1")`,#8
        +	vmull.p8	q3,`&Dlo("q3")`,d17	@ a<<24·bb
        +	vshl.u64	`&Dhi("q1")`,#24
        +	veor		d0,`&Dlo("q1")`
        +	vshr.u64	`&Dlo("q2")`,#16
        +	veor		d0,`&Dhi("q1")`
        +	vshl.u64	`&Dhi("q2")`,#16
        +	veor		d0,`&Dlo("q2")`
        +	vshr.u64	`&Dlo("q3")`,#24
        +	veor		d0,`&Dhi("q2")`
        +	vshl.u64	`&Dhi("q3")`,#8
        +	veor		d0,`&Dlo("q3")`
        +	veor		d0,`&Dhi("q3")`
        +	bx	lr
        +.size	mul_1x1_neon,.-mul_1x1_neon
        +#endif
        +___
        +################
        +# private interface to mul_1x1_ialu
        +#
        +$a="r1";
        +$b="r0";
        +
        +($a0,$a1,$a2,$a12,$a4,$a14)=
        +($hi,$lo,$t0,$t1, $i0,$i1 )=map("r$_",(4..9),12);
        +
        +$mask="r12";
        +
        +$code.=<<___;
        +.type	mul_1x1_ialu,%function
        +.align	5
        +mul_1x1_ialu:
        +	mov	$a0,#0
        +	bic	$a1,$a,#3<<30		@ a1=a&0x3fffffff
        +	str	$a0,[sp,#0]		@ tab[0]=0
        +	add	$a2,$a1,$a1		@ a2=a1<<1
        +	str	$a1,[sp,#4]		@ tab[1]=a1
        +	eor	$a12,$a1,$a2		@ a1^a2
        +	str	$a2,[sp,#8]		@ tab[2]=a2
        +	mov	$a4,$a1,lsl#2		@ a4=a1<<2
        +	str	$a12,[sp,#12]		@ tab[3]=a1^a2
        +	eor	$a14,$a1,$a4		@ a1^a4
        +	str	$a4,[sp,#16]		@ tab[4]=a4
        +	eor	$a0,$a2,$a4		@ a2^a4
        +	str	$a14,[sp,#20]		@ tab[5]=a1^a4
        +	eor	$a12,$a12,$a4		@ a1^a2^a4
        +	str	$a0,[sp,#24]		@ tab[6]=a2^a4
        +	and	$i0,$mask,$b,lsl#2
        +	str	$a12,[sp,#28]		@ tab[7]=a1^a2^a4
        +
        +	and	$i1,$mask,$b,lsr#1
        +	ldr	$lo,[sp,$i0]		@ tab[b       & 0x7]
        +	and	$i0,$mask,$b,lsr#4
        +	ldr	$t1,[sp,$i1]		@ tab[b >>  3 & 0x7]
        +	and	$i1,$mask,$b,lsr#7
        +	ldr	$t0,[sp,$i0]		@ tab[b >>  6 & 0x7]
        +	eor	$lo,$lo,$t1,lsl#3	@ stall
        +	mov	$hi,$t1,lsr#29
        +	ldr	$t1,[sp,$i1]		@ tab[b >>  9 & 0x7]
        +
        +	and	$i0,$mask,$b,lsr#10
        +	eor	$lo,$lo,$t0,lsl#6
        +	eor	$hi,$hi,$t0,lsr#26
        +	ldr	$t0,[sp,$i0]		@ tab[b >> 12 & 0x7]
        +
        +	and	$i1,$mask,$b,lsr#13
        +	eor	$lo,$lo,$t1,lsl#9
        +	eor	$hi,$hi,$t1,lsr#23
        +	ldr	$t1,[sp,$i1]		@ tab[b >> 15 & 0x7]
        +
        +	and	$i0,$mask,$b,lsr#16
        +	eor	$lo,$lo,$t0,lsl#12
        +	eor	$hi,$hi,$t0,lsr#20
        +	ldr	$t0,[sp,$i0]		@ tab[b >> 18 & 0x7]
        +
        +	and	$i1,$mask,$b,lsr#19
        +	eor	$lo,$lo,$t1,lsl#15
        +	eor	$hi,$hi,$t1,lsr#17
        +	ldr	$t1,[sp,$i1]		@ tab[b >> 21 & 0x7]
        +
        +	and	$i0,$mask,$b,lsr#22
        +	eor	$lo,$lo,$t0,lsl#18
        +	eor	$hi,$hi,$t0,lsr#14
        +	ldr	$t0,[sp,$i0]		@ tab[b >> 24 & 0x7]
        +
        +	and	$i1,$mask,$b,lsr#25
        +	eor	$lo,$lo,$t1,lsl#21
        +	eor	$hi,$hi,$t1,lsr#11
        +	ldr	$t1,[sp,$i1]		@ tab[b >> 27 & 0x7]
        +
        +	tst	$a,#1<<30
        +	and	$i0,$mask,$b,lsr#28
        +	eor	$lo,$lo,$t0,lsl#24
        +	eor	$hi,$hi,$t0,lsr#8
        +	ldr	$t0,[sp,$i0]		@ tab[b >> 30      ]
        +
        +	eorne	$lo,$lo,$b,lsl#30
        +	eorne	$hi,$hi,$b,lsr#2
        +	tst	$a,#1<<31
        +	eor	$lo,$lo,$t1,lsl#27
        +	eor	$hi,$hi,$t1,lsr#5
        +	eorne	$lo,$lo,$b,lsl#31
        +	eorne	$hi,$hi,$b,lsr#1
        +	eor	$lo,$lo,$t0,lsl#30
        +	eor	$hi,$hi,$t0,lsr#2
        +
        +	mov	pc,lr
        +.size	mul_1x1_ialu,.-mul_1x1_ialu
        +___
        +################
        +# void	bn_GF2m_mul_2x2(BN_ULONG *r,
        +#	BN_ULONG a1,BN_ULONG a0,
        +#	BN_ULONG b1,BN_ULONG b0);	# r[3..0]=a1a0·b1b0
        +
        +($A1,$B1,$A0,$B0,$A1B1,$A0B0)=map("d$_",(18..23));
        +
        +$code.=<<___;
        +.global	bn_GF2m_mul_2x2
        +.type	bn_GF2m_mul_2x2,%function
        +.align	5
        +bn_GF2m_mul_2x2:
        +#if __ARM_ARCH__>=7
        +	ldr	r12,.LOPENSSL_armcap
        +.Lpic:	ldr	r12,[pc,r12]
        +	tst	r12,#1
        +	beq	.Lialu
        +
        +	veor	$A1,$A1
        +	vmov.32	$B1,r3,r3		@ two copies of b1
        +	vmov.32	${A1}[0],r1		@ a1
        +
        +	veor	$A0,$A0
        +	vld1.32	${B0}[],[sp,:32]	@ two copies of b0
        +	vmov.32	${A0}[0],r2		@ a0
        +	mov	r12,lr
        +
        +	vmov	d16,$A1
        +	vmov	d17,$B1
        +	bl	mul_1x1_neon		@ a1·b1
        +	vmov	$A1B1,d0
        +
        +	vmov	d16,$A0
        +	vmov	d17,$B0
        +	bl	mul_1x1_neon		@ a0·b0
        +	vmov	$A0B0,d0
        +
        +	veor	d16,$A0,$A1
        +	veor	d17,$B0,$B1
        +	veor	$A0,$A0B0,$A1B1
        +	bl	mul_1x1_neon		@ (a0+a1)·(b0+b1)
        +
        +	veor	d0,$A0			@ (a0+a1)·(b0+b1)-a0·b0-a1·b1
        +	vshl.u64 d1,d0,#32
        +	vshr.u64 d0,d0,#32
        +	veor	$A0B0,d1
        +	veor	$A1B1,d0
        +	vst1.32	{${A0B0}[0]},[r0,:32]!
        +	vst1.32	{${A0B0}[1]},[r0,:32]!
        +	vst1.32	{${A1B1}[0]},[r0,:32]!
        +	vst1.32	{${A1B1}[1]},[r0,:32]
        +	bx	r12
        +.align	4
        +.Lialu:
        +#endif
        +___
        +$ret="r10";	# reassigned 1st argument
        +$code.=<<___;
        +	stmdb	sp!,{r4-r10,lr}
        +	mov	$ret,r0			@ reassign 1st argument
        +	mov	$b,r3			@ $b=b1
        +	ldr	r3,[sp,#32]		@ load b0
        +	mov	$mask,#7<<2
        +	sub	sp,sp,#32		@ allocate tab[8]
        +
        +	bl	mul_1x1_ialu		@ a1·b1
        +	str	$lo,[$ret,#8]
        +	str	$hi,[$ret,#12]
        +
        +	eor	$b,$b,r3		@ flip b0 and b1
        +	 eor	$a,$a,r2		@ flip a0 and a1
        +	eor	r3,r3,$b
        +	 eor	r2,r2,$a
        +	eor	$b,$b,r3
        +	 eor	$a,$a,r2
        +	bl	mul_1x1_ialu		@ a0·b0
        +	str	$lo,[$ret]
        +	str	$hi,[$ret,#4]
        +
        +	eor	$a,$a,r2
        +	eor	$b,$b,r3
        +	bl	mul_1x1_ialu		@ (a1+a0)·(b1+b0)
        +___
        +@r=map("r$_",(6..9));
        +$code.=<<___;
        +	ldmia	$ret,{@r[0]-@r[3]}
        +	eor	$lo,$lo,$hi
        +	eor	$hi,$hi,@r[1]
        +	eor	$lo,$lo,@r[0]
        +	eor	$hi,$hi,@r[2]
        +	eor	$lo,$lo,@r[3]
        +	eor	$hi,$hi,@r[3]
        +	str	$hi,[$ret,#8]
        +	eor	$lo,$lo,$hi
        +	add	sp,sp,#32		@ destroy tab[8]
        +	str	$lo,[$ret,#4]
        +
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r10,pc}
        +#else
        +	ldmia	sp!,{r4-r10,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
        +#if __ARM_ARCH__>=7
        +.align	5
        +.LOPENSSL_armcap:
        +.word	OPENSSL_armcap_P-(.Lpic+8)
        +#endif
        +.asciz	"GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	5
        +
        +.comm	OPENSSL_armcap_P,4,4
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;    # make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT;   # enforce flush
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/armv4-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/armv4-mont.pl
        new file mode 100644
        index 000000000..f78a8b5f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/armv4-mont.pl
        @@ -0,0 +1,204 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# January 2007.
        +
        +# Montgomery multiplication for ARMv4.
        +#
        +# Performance improvement naturally varies among CPU implementations
        +# and compilers. The code was observed to provide +65-35% improvement
        +# [depending on key length, less for longer keys] on ARM920T, and
        +# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
        +# base and compiler generated code with in-lined umull and even umlal
        +# instructions. The latter means that this code didn't really have an 
        +# "advantage" of utilizing some "secret" instruction.
        +#
        +# The code is interoperable with Thumb ISA and is rather compact, less
        +# than 1/2KB. Windows CE port would be trivial, as it's exclusively
        +# about decorations, ABI and instruction syntax are identical.
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$num="r0";	# starts as num argument, but holds &tp[num-1]
        +$ap="r1";
        +$bp="r2"; $bi="r2"; $rp="r2";
        +$np="r3";
        +$tp="r4";
        +$aj="r5";
        +$nj="r6";
        +$tj="r7";
        +$n0="r8";
        +###########	# r9 is reserved by ELF as platform specific, e.g. TLS pointer
        +$alo="r10";	# sl, gcc uses it to keep @GOT
        +$ahi="r11";	# fp
        +$nlo="r12";	# ip
        +###########	# r13 is stack pointer
        +$nhi="r14";	# lr
        +###########	# r15 is program counter
        +
        +#### argument block layout relative to &tp[num-1], a.k.a. $num
        +$_rp="$num,#12*4";
        +# ap permanently resides in r1
        +$_bp="$num,#13*4";
        +# np permanently resides in r3
        +$_n0="$num,#14*4";
        +$_num="$num,#15*4";	$_bpend=$_num;
        +
        +$code=<<___;
        +.text
        +
        +.global	bn_mul_mont
        +.type	bn_mul_mont,%function
        +
        +.align	2
        +bn_mul_mont:
        +	stmdb	sp!,{r0,r2}		@ sp points at argument block
        +	ldr	$num,[sp,#3*4]		@ load num
        +	cmp	$num,#2
        +	movlt	r0,#0
        +	addlt	sp,sp,#2*4
        +	blt	.Labrt
        +
        +	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
        +
        +	mov	$num,$num,lsl#2		@ rescale $num for byte count
        +	sub	sp,sp,$num		@ alloca(4*num)
        +	sub	sp,sp,#4		@ +extra dword
        +	sub	$num,$num,#4		@ "num=num-1"
        +	add	$tp,$bp,$num		@ &bp[num-1]
        +
        +	add	$num,sp,$num		@ $num to point at &tp[num-1]
        +	ldr	$n0,[$_n0]		@ &n0
        +	ldr	$bi,[$bp]		@ bp[0]
        +	ldr	$aj,[$ap],#4		@ ap[0],ap++
        +	ldr	$nj,[$np],#4		@ np[0],np++
        +	ldr	$n0,[$n0]		@ *n0
        +	str	$tp,[$_bpend]		@ save &bp[num]
        +
        +	umull	$alo,$ahi,$aj,$bi	@ ap[0]*bp[0]
        +	str	$n0,[$_n0]		@ save n0 value
        +	mul	$n0,$alo,$n0		@ "tp[0]"*n0
        +	mov	$nlo,#0
        +	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"t[0]"
        +	mov	$tp,sp
        +
        +.L1st:
        +	ldr	$aj,[$ap],#4		@ ap[j],ap++
        +	mov	$alo,$ahi
        +	ldr	$nj,[$np],#4		@ np[j],np++
        +	mov	$ahi,#0
        +	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[0]
        +	mov	$nhi,#0
        +	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
        +	adds	$nlo,$nlo,$alo
        +	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
        +	adc	$nlo,$nhi,#0
        +	cmp	$tp,$num
        +	bne	.L1st
        +
        +	adds	$nlo,$nlo,$ahi
        +	ldr	$tp,[$_bp]		@ restore bp
        +	mov	$nhi,#0
        +	ldr	$n0,[$_n0]		@ restore n0
        +	adc	$nhi,$nhi,#0
        +	str	$nlo,[$num]		@ tp[num-1]=
        +	str	$nhi,[$num,#4]		@ tp[num]=
        +
        +.Louter:
        +	sub	$tj,$num,sp		@ "original" $num-1 value
        +	sub	$ap,$ap,$tj		@ "rewind" ap to &ap[1]
        +	ldr	$bi,[$tp,#4]!		@ *(++bp)
        +	sub	$np,$np,$tj		@ "rewind" np to &np[1]
        +	ldr	$aj,[$ap,#-4]		@ ap[0]
        +	ldr	$alo,[sp]		@ tp[0]
        +	ldr	$nj,[$np,#-4]		@ np[0]
        +	ldr	$tj,[sp,#4]		@ tp[1]
        +
        +	mov	$ahi,#0
        +	umlal	$alo,$ahi,$aj,$bi	@ ap[0]*bp[i]+tp[0]
        +	str	$tp,[$_bp]		@ save bp
        +	mul	$n0,$alo,$n0
        +	mov	$nlo,#0
        +	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"tp[0]"
        +	mov	$tp,sp
        +
        +.Linner:
        +	ldr	$aj,[$ap],#4		@ ap[j],ap++
        +	adds	$alo,$ahi,$tj		@ +=tp[j]
        +	ldr	$nj,[$np],#4		@ np[j],np++
        +	mov	$ahi,#0
        +	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[i]
        +	mov	$nhi,#0
        +	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
        +	adc	$ahi,$ahi,#0
        +	ldr	$tj,[$tp,#8]		@ tp[j+1]
        +	adds	$nlo,$nlo,$alo
        +	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
        +	adc	$nlo,$nhi,#0
        +	cmp	$tp,$num
        +	bne	.Linner
        +
        +	adds	$nlo,$nlo,$ahi
        +	mov	$nhi,#0
        +	ldr	$tp,[$_bp]		@ restore bp
        +	adc	$nhi,$nhi,#0
        +	ldr	$n0,[$_n0]		@ restore n0
        +	adds	$nlo,$nlo,$tj
        +	ldr	$tj,[$_bpend]		@ restore &bp[num]
        +	adc	$nhi,$nhi,#0
        +	str	$nlo,[$num]		@ tp[num-1]=
        +	str	$nhi,[$num,#4]		@ tp[num]=
        +
        +	cmp	$tp,$tj
        +	bne	.Louter
        +
        +	ldr	$rp,[$_rp]		@ pull rp
        +	add	$num,$num,#4		@ $num to point at &tp[num]
        +	sub	$aj,$num,sp		@ "original" num value
        +	mov	$tp,sp			@ "rewind" $tp
        +	mov	$ap,$tp			@ "borrow" $ap
        +	sub	$np,$np,$aj		@ "rewind" $np to &np[0]
        +
        +	subs	$tj,$tj,$tj		@ "clear" carry flag
        +.Lsub:	ldr	$tj,[$tp],#4
        +	ldr	$nj,[$np],#4
        +	sbcs	$tj,$tj,$nj		@ tp[j]-np[j]
        +	str	$tj,[$rp],#4		@ rp[j]=
        +	teq	$tp,$num		@ preserve carry
        +	bne	.Lsub
        +	sbcs	$nhi,$nhi,#0		@ upmost carry
        +	mov	$tp,sp			@ "rewind" $tp
        +	sub	$rp,$rp,$aj		@ "rewind" $rp
        +
        +	and	$ap,$tp,$nhi
        +	bic	$np,$rp,$nhi
        +	orr	$ap,$ap,$np		@ ap=borrow?tp:rp
        +
        +.Lcopy:	ldr	$tj,[$ap],#4		@ copy or in-place refresh
        +	str	sp,[$tp],#4		@ zap tp
        +	str	$tj,[$rp],#4
        +	cmp	$tp,$num
        +	bne	.Lcopy
        +
        +	add	sp,$num,#4		@ skip over tp[num+1]
        +	ldmia	sp!,{r4-r12,lr}		@ restore registers
        +	add	sp,sp,#2*4		@ skip over {r0,r2}
        +	mov	r0,#1
        +.Labrt:	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +.size	bn_mul_mont,.-bn_mul_mont
        +.asciz	"Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +___
        +
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/bn-586.pl b/vendor/openssl/openssl/crypto/bn/asm/bn-586.pl
        new file mode 100644
        index 000000000..332ef3e91
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/bn-586.pl
        @@ -0,0 +1,774 @@
        +#!/usr/local/bin/perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0);
        +
        +$sse2=0;
        +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +&external_label("OPENSSL_ia32cap_P") if ($sse2);
        +
        +&bn_mul_add_words("bn_mul_add_words");
        +&bn_mul_words("bn_mul_words");
        +&bn_sqr_words("bn_sqr_words");
        +&bn_div_words("bn_div_words");
        +&bn_add_words("bn_add_words");
        +&bn_sub_words("bn_sub_words");
        +&bn_sub_part_words("bn_sub_part_words");
        +
        +&asm_finish();
        +
        +sub bn_mul_add_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
        +
        +	$r="eax";
        +	$a="edx";
        +	$c="ecx";
        +
        +	if ($sse2) {
        +		&picmeup("eax","OPENSSL_ia32cap_P");
        +		&bt(&DWP(0,"eax"),26);
        +		&jnc(&label("maw_non_sse2"));
        +
        +		&mov($r,&wparam(0));
        +		&mov($a,&wparam(1));
        +		&mov($c,&wparam(2));
        +		&movd("mm0",&wparam(3));	# mm0 = w
        +		&pxor("mm1","mm1");		# mm1 = carry_in
        +		&jmp(&label("maw_sse2_entry"));
        +		
        +	&set_label("maw_sse2_unrolled",16);
        +		&movd("mm3",&DWP(0,$r,"",0));	# mm3 = r[0]
        +		&paddq("mm1","mm3");		# mm1 = carry_in + r[0]
        +		&movd("mm2",&DWP(0,$a,"",0));	# mm2 = a[0]
        +		&pmuludq("mm2","mm0");		# mm2 = w*a[0]
        +		&movd("mm4",&DWP(4,$a,"",0));	# mm4 = a[1]
        +		&pmuludq("mm4","mm0");		# mm4 = w*a[1]
        +		&movd("mm6",&DWP(8,$a,"",0));	# mm6 = a[2]
        +		&pmuludq("mm6","mm0");		# mm6 = w*a[2]
        +		&movd("mm7",&DWP(12,$a,"",0));	# mm7 = a[3]
        +		&pmuludq("mm7","mm0");		# mm7 = w*a[3]
        +		&paddq("mm1","mm2");		# mm1 = carry_in + r[0] + w*a[0]
        +		&movd("mm3",&DWP(4,$r,"",0));	# mm3 = r[1]
        +		&paddq("mm3","mm4");		# mm3 = r[1] + w*a[1]
        +		&movd("mm5",&DWP(8,$r,"",0));	# mm5 = r[2]
        +		&paddq("mm5","mm6");		# mm5 = r[2] + w*a[2]
        +		&movd("mm4",&DWP(12,$r,"",0));	# mm4 = r[3]
        +		&paddq("mm7","mm4");		# mm7 = r[3] + w*a[3]
        +		&movd(&DWP(0,$r,"",0),"mm1");
        +		&movd("mm2",&DWP(16,$a,"",0));	# mm2 = a[4]
        +		&pmuludq("mm2","mm0");		# mm2 = w*a[4]
        +		&psrlq("mm1",32);		# mm1 = carry0
        +		&movd("mm4",&DWP(20,$a,"",0));	# mm4 = a[5]
        +		&pmuludq("mm4","mm0");		# mm4 = w*a[5]
        +		&paddq("mm1","mm3");		# mm1 = carry0 + r[1] + w*a[1]
        +		&movd("mm6",&DWP(24,$a,"",0));	# mm6 = a[6]
        +		&pmuludq("mm6","mm0");		# mm6 = w*a[6]
        +		&movd(&DWP(4,$r,"",0),"mm1");
        +		&psrlq("mm1",32);		# mm1 = carry1
        +		&movd("mm3",&DWP(28,$a,"",0));	# mm3 = a[7]
        +		&add($a,32);
        +		&pmuludq("mm3","mm0");		# mm3 = w*a[7]
        +		&paddq("mm1","mm5");		# mm1 = carry1 + r[2] + w*a[2]
        +		&movd("mm5",&DWP(16,$r,"",0));	# mm5 = r[4]
        +		&paddq("mm2","mm5");		# mm2 = r[4] + w*a[4]
        +		&movd(&DWP(8,$r,"",0),"mm1");
        +		&psrlq("mm1",32);		# mm1 = carry2
        +		&paddq("mm1","mm7");		# mm1 = carry2 + r[3] + w*a[3]
        +		&movd("mm5",&DWP(20,$r,"",0));	# mm5 = r[5]
        +		&paddq("mm4","mm5");		# mm4 = r[5] + w*a[5]
        +		&movd(&DWP(12,$r,"",0),"mm1");
        +		&psrlq("mm1",32);		# mm1 = carry3
        +		&paddq("mm1","mm2");		# mm1 = carry3 + r[4] + w*a[4]
        +		&movd("mm5",&DWP(24,$r,"",0));	# mm5 = r[6]
        +		&paddq("mm6","mm5");		# mm6 = r[6] + w*a[6]
        +		&movd(&DWP(16,$r,"",0),"mm1");
        +		&psrlq("mm1",32);		# mm1 = carry4
        +		&paddq("mm1","mm4");		# mm1 = carry4 + r[5] + w*a[5]
        +		&movd("mm5",&DWP(28,$r,"",0));	# mm5 = r[7]
        +		&paddq("mm3","mm5");		# mm3 = r[7] + w*a[7]
        +		&movd(&DWP(20,$r,"",0),"mm1");
        +		&psrlq("mm1",32);		# mm1 = carry5
        +		&paddq("mm1","mm6");		# mm1 = carry5 + r[6] + w*a[6]
        +		&movd(&DWP(24,$r,"",0),"mm1");
        +		&psrlq("mm1",32);		# mm1 = carry6
        +		&paddq("mm1","mm3");		# mm1 = carry6 + r[7] + w*a[7]
        +		&movd(&DWP(28,$r,"",0),"mm1");
        +		&lea($r,&DWP(32,$r));
        +		&psrlq("mm1",32);		# mm1 = carry_out
        +
        +		&sub($c,8);
        +		&jz(&label("maw_sse2_exit"));
        +	&set_label("maw_sse2_entry");
        +		&test($c,0xfffffff8);
        +		&jnz(&label("maw_sse2_unrolled"));
        +
        +	&set_label("maw_sse2_loop",4);
        +		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
        +		&movd("mm3",&DWP(0,$r));	# mm3 = r[i]
        +		&pmuludq("mm2","mm0");		# a[i] *= w
        +		&lea($a,&DWP(4,$a));
        +		&paddq("mm1","mm3");		# carry += r[i]
        +		&paddq("mm1","mm2");		# carry += a[i]*w
        +		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
        +		&sub($c,1);
        +		&psrlq("mm1",32);		# carry = carry_high
        +		&lea($r,&DWP(4,$r));
        +		&jnz(&label("maw_sse2_loop"));
        +	&set_label("maw_sse2_exit");
        +		&movd("eax","mm1");		# c = carry_out
        +		&emms();
        +		&ret();
        +
        +	&set_label("maw_non_sse2",16);
        +	}
        +
        +	# function_begin prologue
        +	&push("ebp");
        +	&push("ebx");
        +	&push("esi");
        +	&push("edi");
        +
        +	&comment("");
        +	$Low="eax";
        +	$High="edx";
        +	$a="ebx";
        +	$w="ebp";
        +	$r="edi";
        +	$c="esi";
        +
        +	&xor($c,$c);		# clear carry
        +	&mov($r,&wparam(0));	#
        +
        +	&mov("ecx",&wparam(2));	#
        +	&mov($a,&wparam(1));	#
        +
        +	&and("ecx",0xfffffff8);	# num / 8
        +	&mov($w,&wparam(3));	#
        +
        +	&push("ecx");		# Up the stack for a tmp variable
        +
        +	&jz(&label("maw_finish"));
        +
        +	&set_label("maw_loop",16);
        +
        +	for ($i=0; $i<32; $i+=4)
        +		{
        +		&comment("Round $i");
        +
        +		 &mov("eax",&DWP($i,$a)); 	# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+= c
        +		&adc("edx",0);			# H(t)+=carry
        +		 &add("eax",&DWP($i,$r));	# L(t)+= *r
        +		&adc("edx",0);			# H(t)+=carry
        +		 &mov(&DWP($i,$r),"eax");	# *r= L(t);
        +		&mov($c,"edx");			# c=  H(t);
        +		}
        +
        +	&comment("");
        +	&sub("ecx",8);
        +	&lea($a,&DWP(32,$a));
        +	&lea($r,&DWP(32,$r));
        +	&jnz(&label("maw_loop"));
        +
        +	&set_label("maw_finish",0);
        +	&mov("ecx",&wparam(2));	# get num
        +	&and("ecx",7);
        +	&jnz(&label("maw_finish2"));	# helps branch prediction
        +	&jmp(&label("maw_end"));
        +
        +	&set_label("maw_finish2",1);
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		 &mov("eax",&DWP($i*4,$a));	# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+=c
        +		&adc("edx",0);			# H(t)+=carry
        +		 &add("eax",&DWP($i*4,$r));	# L(t)+= *r
        +		&adc("edx",0);			# H(t)+=carry
        +		 &dec("ecx") if ($i != 7-1);
        +		&mov(&DWP($i*4,$r),"eax");	# *r= L(t);
        +		 &mov($c,"edx");		# c=  H(t);
        +		&jz(&label("maw_end")) if ($i != 7-1);
        +		}
        +	&set_label("maw_end",0);
        +	&mov("eax",$c);
        +
        +	&pop("ecx");	# clear variable from
        +
        +	&function_end($name);
        +	}
        +
        +sub bn_mul_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
        +
        +	$r="eax";
        +	$a="edx";
        +	$c="ecx";
        +
        +	if ($sse2) {
        +		&picmeup("eax","OPENSSL_ia32cap_P");
        +		&bt(&DWP(0,"eax"),26);
        +		&jnc(&label("mw_non_sse2"));
        +
        +		&mov($r,&wparam(0));
        +		&mov($a,&wparam(1));
        +		&mov($c,&wparam(2));
        +		&movd("mm0",&wparam(3));	# mm0 = w
        +		&pxor("mm1","mm1");		# mm1 = carry = 0
        +
        +	&set_label("mw_sse2_loop",16);
        +		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
        +		&pmuludq("mm2","mm0");		# a[i] *= w
        +		&lea($a,&DWP(4,$a));
        +		&paddq("mm1","mm2");		# carry += a[i]*w
        +		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
        +		&sub($c,1);
        +		&psrlq("mm1",32);		# carry = carry_high
        +		&lea($r,&DWP(4,$r));
        +		&jnz(&label("mw_sse2_loop"));
        +
        +		&movd("eax","mm1");		# return carry
        +		&emms();
        +		&ret();
        +	&set_label("mw_non_sse2",16);
        +	}
        +
        +	# function_begin prologue
        +	&push("ebp");
        +	&push("ebx");
        +	&push("esi");
        +	&push("edi");
        +
        +	&comment("");
        +	$Low="eax";
        +	$High="edx";
        +	$a="ebx";
        +	$w="ecx";
        +	$r="edi";
        +	$c="esi";
        +	$num="ebp";
        +
        +	&xor($c,$c);		# clear carry
        +	&mov($r,&wparam(0));	#
        +	&mov($a,&wparam(1));	#
        +	&mov($num,&wparam(2));	#
        +	&mov($w,&wparam(3));	#
        +
        +	&and($num,0xfffffff8);	# num / 8
        +	&jz(&label("mw_finish"));
        +
        +	&set_label("mw_loop",0);
        +	for ($i=0; $i<32; $i+=4)
        +		{
        +		&comment("Round $i");
        +
        +		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+=c
        +		 # XXX
        +
        +		&adc("edx",0);			# H(t)+=carry
        +		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
        +
        +		&mov($c,"edx");			# c=  H(t);
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	&add($r,32);
        +	&sub($num,8);
        +	&jz(&label("mw_finish"));
        +	&jmp(&label("mw_loop"));
        +
        +	&set_label("mw_finish",0);
        +	&mov($num,&wparam(2));	# get num
        +	&and($num,7);
        +	&jnz(&label("mw_finish2"));
        +	&jmp(&label("mw_end"));
        +
        +	&set_label("mw_finish2",1);
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		 &mov("eax",&DWP($i*4,$a,"",0));# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+=c
        +		 # XXX
        +		&adc("edx",0);			# H(t)+=carry
        +		 &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
        +		&mov($c,"edx");			# c=  H(t);
        +		 &dec($num) if ($i != 7-1);
        +		&jz(&label("mw_end")) if ($i != 7-1);
        +		}
        +	&set_label("mw_end",0);
        +	&mov("eax",$c);
        +
        +	&function_end($name);
        +	}
        +
        +sub bn_sqr_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
        +
        +	$r="eax";
        +	$a="edx";
        +	$c="ecx";
        +
        +	if ($sse2) {
        +		&picmeup("eax","OPENSSL_ia32cap_P");
        +		&bt(&DWP(0,"eax"),26);
        +		&jnc(&label("sqr_non_sse2"));
        +
        +		&mov($r,&wparam(0));
        +		&mov($a,&wparam(1));
        +		&mov($c,&wparam(2));
        +
        +	&set_label("sqr_sse2_loop",16);
        +		&movd("mm0",&DWP(0,$a));	# mm0 = a[i]
        +		&pmuludq("mm0","mm0");		# a[i] *= a[i]
        +		&lea($a,&DWP(4,$a));		# a++
        +		&movq(&QWP(0,$r),"mm0");	# r[i] = a[i]*a[i]
        +		&sub($c,1);
        +		&lea($r,&DWP(8,$r));		# r += 2
        +		&jnz(&label("sqr_sse2_loop"));
        +
        +		&emms();
        +		&ret();
        +	&set_label("sqr_non_sse2",16);
        +	}
        +
        +	# function_begin prologue
        +	&push("ebp");
        +	&push("ebx");
        +	&push("esi");
        +	&push("edi");
        +
        +	&comment("");
        +	$r="esi";
        +	$a="edi";
        +	$num="ebx";
        +
        +	&mov($r,&wparam(0));	#
        +	&mov($a,&wparam(1));	#
        +	&mov($num,&wparam(2));	#
        +
        +	&and($num,0xfffffff8);	# num / 8
        +	&jz(&label("sw_finish"));
        +
        +	&set_label("sw_loop",0);
        +	for ($i=0; $i<32; $i+=4)
        +		{
        +		&comment("Round $i");
        +		&mov("eax",&DWP($i,$a,"",0)); 	# *a
        +		 # XXX
        +		&mul("eax");			# *a * *a
        +		&mov(&DWP($i*2,$r,"",0),"eax");	#
        +		 &mov(&DWP($i*2+4,$r,"",0),"edx");#
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	&add($r,64);
        +	&sub($num,8);
        +	&jnz(&label("sw_loop"));
        +
        +	&set_label("sw_finish",0);
        +	&mov($num,&wparam(2));	# get num
        +	&and($num,7);
        +	&jz(&label("sw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov("eax",&DWP($i*4,$a,"",0));	# *a
        +		 # XXX
        +		&mul("eax");			# *a * *a
        +		&mov(&DWP($i*8,$r,"",0),"eax");	#
        +		 &dec($num) if ($i != 7-1);
        +		&mov(&DWP($i*8+4,$r,"",0),"edx");
        +		 &jz(&label("sw_end")) if ($i != 7-1);
        +		}
        +	&set_label("sw_end",0);
        +
        +	&function_end($name);
        +	}
        +
        +sub bn_div_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin_B($name,"");
        +	&mov("edx",&wparam(0));	#
        +	&mov("eax",&wparam(1));	#
        +	&mov("ecx",&wparam(2));	#
        +	&div("ecx");
        +	&ret();
        +	&function_end_B($name);
        +	}
        +
        +sub bn_add_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$a="esi";
        +	$b="edi";
        +	$c="eax";
        +	$r="ebx";
        +	$tmp1="ecx";
        +	$tmp2="edx";
        +	$num="ebp";
        +
        +	&mov($r,&wparam(0));	# get r
        +	 &mov($a,&wparam(1));	# get a
        +	&mov($b,&wparam(2));	# get b
        +	 &mov($num,&wparam(3));	# get num
        +	&xor($c,$c);		# clear carry
        +	 &and($num,0xfffffff8);	# num / 8
        +
        +	&jz(&label("aw_finish"));
        +
        +	&set_label("aw_loop",0);
        +	for ($i=0; $i<8; $i++)
        +		{
        +		&comment("Round $i");
        +
        +		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
        +		&add($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &add($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	 &add($b,32);
        +	&add($r,32);
        +	 &sub($num,8);
        +	&jnz(&label("aw_loop"));
        +
        +	&set_label("aw_finish",0);
        +	&mov($num,&wparam(3));	# get num
        +	&and($num,7);
        +	 &jz(&label("aw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
        +		&add($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &add($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &dec($num) if ($i != 6);
        +		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +		 &jz(&label("aw_end")) if ($i != 6);
        +		}
        +	&set_label("aw_end",0);
        +
        +#	&mov("eax",$c);		# $c is "eax"
        +
        +	&function_end($name);
        +	}
        +
        +sub bn_sub_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$a="esi";
        +	$b="edi";
        +	$c="eax";
        +	$r="ebx";
        +	$tmp1="ecx";
        +	$tmp2="edx";
        +	$num="ebp";
        +
        +	&mov($r,&wparam(0));	# get r
        +	 &mov($a,&wparam(1));	# get a
        +	&mov($b,&wparam(2));	# get b
        +	 &mov($num,&wparam(3));	# get num
        +	&xor($c,$c);		# clear carry
        +	 &and($num,0xfffffff8);	# num / 8
        +
        +	&jz(&label("aw_finish"));
        +
        +	&set_label("aw_loop",0);
        +	for ($i=0; $i<8; $i++)
        +		{
        +		&comment("Round $i");
        +
        +		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
        +		&sub($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &sub($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	 &add($b,32);
        +	&add($r,32);
        +	 &sub($num,8);
        +	&jnz(&label("aw_loop"));
        +
        +	&set_label("aw_finish",0);
        +	&mov($num,&wparam(3));	# get num
        +	&and($num,7);
        +	 &jz(&label("aw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
        +		&sub($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &sub($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &dec($num) if ($i != 6);
        +		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +		 &jz(&label("aw_end")) if ($i != 6);
        +		}
        +	&set_label("aw_end",0);
        +
        +#	&mov("eax",$c);		# $c is "eax"
        +
        +	&function_end($name);
        +	}
        +
        +sub bn_sub_part_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$a="esi";
        +	$b="edi";
        +	$c="eax";
        +	$r="ebx";
        +	$tmp1="ecx";
        +	$tmp2="edx";
        +	$num="ebp";
        +
        +	&mov($r,&wparam(0));	# get r
        +	 &mov($a,&wparam(1));	# get a
        +	&mov($b,&wparam(2));	# get b
        +	 &mov($num,&wparam(3));	# get num
        +	&xor($c,$c);		# clear carry
        +	 &and($num,0xfffffff8);	# num / 8
        +
        +	&jz(&label("aw_finish"));
        +
        +	&set_label("aw_loop",0);
        +	for ($i=0; $i<8; $i++)
        +		{
        +		&comment("Round $i");
        +
        +		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
        +		&sub($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &sub($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	 &add($b,32);
        +	&add($r,32);
        +	 &sub($num,8);
        +	&jnz(&label("aw_loop"));
        +
        +	&set_label("aw_finish",0);
        +	&mov($num,&wparam(3));	# get num
        +	&and($num,7);
        +	 &jz(&label("aw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov($tmp1,&DWP(0,$a,"",0));	# *a
        +		 &mov($tmp2,&DWP(0,$b,"",0));# *b
        +		&sub($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &sub($tmp1,$tmp2);
        +		&adc($c,0);
        +		&mov(&DWP(0,$r,"",0),$tmp1);	# *r
        +		&add($a, 4);
        +		&add($b, 4);
        +		&add($r, 4);
        +		 &dec($num) if ($i != 6);
        +		 &jz(&label("aw_end")) if ($i != 6);
        +		}
        +	&set_label("aw_end",0);
        +
        +	&cmp(&wparam(4),0);
        +	&je(&label("pw_end"));
        +
        +	&mov($num,&wparam(4));	# get dl
        +	&cmp($num,0);
        +	&je(&label("pw_end"));
        +	&jge(&label("pw_pos"));
        +
        +	&comment("pw_neg");
        +	&mov($tmp2,0);
        +	&sub($tmp2,$num);
        +	&mov($num,$tmp2);
        +	&and($num,0xfffffff8);	# num / 8
        +	&jz(&label("pw_neg_finish"));
        +
        +	&set_label("pw_neg_loop",0);
        +	for ($i=0; $i<8; $i++)
        +	{
        +	    &comment("dl<0 Round $i");
        +
        +	    &mov($tmp1,0);
        +	    &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
        +	    &sub($tmp1,$c);
        +	    &mov($c,0);
        +	    &adc($c,$c);
        +	    &sub($tmp1,$tmp2);
        +	    &adc($c,0);
        +	    &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
        +	}
        +	    
        +	&comment("");
        +	&add($b,32);
        +	&add($r,32);
        +	&sub($num,8);
        +	&jnz(&label("pw_neg_loop"));
        +	    
        +	&set_label("pw_neg_finish",0);
        +	&mov($tmp2,&wparam(4));	# get dl
        +	&mov($num,0);
        +	&sub($num,$tmp2);
        +	&and($num,7);
        +	&jz(&label("pw_end"));
        +	    
        +	for ($i=0; $i<7; $i++)
        +	{
        +	    &comment("dl<0 Tail Round $i");
        +	    &mov($tmp1,0);
        +	    &mov($tmp2,&DWP($i*4,$b,"",0));# *b
        +	    &sub($tmp1,$c);
        +	    &mov($c,0);
        +	    &adc($c,$c);
        +	    &sub($tmp1,$tmp2);
        +	    &adc($c,0);
        +	    &dec($num) if ($i != 6);
        +	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +	    &jz(&label("pw_end")) if ($i != 6);
        +	}
        +
        +	&jmp(&label("pw_end"));
        +	
        +	&set_label("pw_pos",0);
        +	
        +	&and($num,0xfffffff8);	# num / 8
        +	&jz(&label("pw_pos_finish"));
        +
        +	&set_label("pw_pos_loop",0);
        +
        +	for ($i=0; $i<8; $i++)
        +	{
        +	    &comment("dl>0 Round $i");
        +
        +	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +	    &sub($tmp1,$c);
        +	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +	    &jnc(&label("pw_nc".$i));
        +	}
        +	    
        +	&comment("");
        +	&add($a,32);
        +	&add($r,32);
        +	&sub($num,8);
        +	&jnz(&label("pw_pos_loop"));
        +	    
        +	&set_label("pw_pos_finish",0);
        +	&mov($num,&wparam(4));	# get dl
        +	&and($num,7);
        +	&jz(&label("pw_end"));
        +	    
        +	for ($i=0; $i<7; $i++)
        +	{
        +	    &comment("dl>0 Tail Round $i");
        +	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +	    &sub($tmp1,$c);
        +	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +	    &jnc(&label("pw_tail_nc".$i));
        +	    &dec($num) if ($i != 6);
        +	    &jz(&label("pw_end")) if ($i != 6);
        +	}
        +	&mov($c,1);
        +	&jmp(&label("pw_end"));
        +
        +	&set_label("pw_nc_loop",0);
        +	for ($i=0; $i<8; $i++)
        +	{
        +	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +	    &set_label("pw_nc".$i,0);
        +	}
        +	    
        +	&comment("");
        +	&add($a,32);
        +	&add($r,32);
        +	&sub($num,8);
        +	&jnz(&label("pw_nc_loop"));
        +	    
        +	&mov($num,&wparam(4));	# get dl
        +	&and($num,7);
        +	&jz(&label("pw_nc_end"));
        +	    
        +	for ($i=0; $i<7; $i++)
        +	{
        +	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
        +	    &set_label("pw_tail_nc".$i,0);
        +	    &dec($num) if ($i != 6);
        +	    &jz(&label("pw_nc_end")) if ($i != 6);
        +	}
        +
        +	&set_label("pw_nc_end",0);
        +	&mov($c,0);
        +
        +	&set_label("pw_end",0);
        +
        +#	&mov("eax",$c);		# $c is "eax"
        +
        +	&function_end($name);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/co-586.pl b/vendor/openssl/openssl/crypto/bn/asm/co-586.pl
        new file mode 100644
        index 000000000..57101a6bd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/co-586.pl
        @@ -0,0 +1,287 @@
        +#!/usr/local/bin/perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0);
        +
        +&bn_mul_comba("bn_mul_comba8",8);
        +&bn_mul_comba("bn_mul_comba4",4);
        +&bn_sqr_comba("bn_sqr_comba8",8);
        +&bn_sqr_comba("bn_sqr_comba4",4);
        +
        +&asm_finish();
        +
        +sub mul_add_c
        +	{
        +	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
        +
        +	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
        +	# words, and 1 if load return value
        +
        +	&comment("mul a[$ai]*b[$bi]");
        +
        +	# "eax" and "edx" will always be pre-loaded.
        +	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
        +	# &mov("edx",&DWP($bi*4,$b,"",0));
        +
        +	&mul("edx");
        +	&add($c0,"eax");
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
        +	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
        +	 ###
        +	&adc($c1,"edx");
        +	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
        +	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
        +	 ###
        +	&adc($c2,0);
        +	 # is pos > 1, it means it is the last loop 
        +	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
        +	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
        +	}
        +
        +sub sqr_add_c
        +	{
        +	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
        +
        +	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
        +	# words, and 1 if load return value
        +
        +	&comment("sqr a[$ai]*a[$bi]");
        +
        +	# "eax" and "edx" will always be pre-loaded.
        +	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
        +	# &mov("edx",&DWP($bi*4,$b,"",0));
        +
        +	if ($ai == $bi)
        +		{ &mul("eax");}
        +	else
        +		{ &mul("edx");}
        +	&add($c0,"eax");
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
        +	 ###
        +	&adc($c1,"edx");
        +	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
        +	 ###
        +	&adc($c2,0);
        +	 # is pos > 1, it means it is the last loop 
        +	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
        +	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
        +	}
        +
        +sub sqr_add_c2
        +	{
        +	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
        +
        +	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
        +	# words, and 1 if load return value
        +
        +	&comment("sqr a[$ai]*a[$bi]");
        +
        +	# "eax" and "edx" will always be pre-loaded.
        +	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
        +	# &mov("edx",&DWP($bi*4,$a,"",0));
        +
        +	if ($ai == $bi)
        +		{ &mul("eax");}
        +	else
        +		{ &mul("edx");}
        +	&add("eax","eax");
        +	 ###
        +	&adc("edx","edx");
        +	 ###
        +	&adc($c2,0);
        +	 &add($c0,"eax");
        +	&adc($c1,"edx");
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
        +	&adc($c2,0);
        +	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
        +	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
        +	 ###
        +	}
        +
        +sub bn_mul_comba
        +	{
        +	local($name,$num)=@_;
        +	local($a,$b,$c0,$c1,$c2);
        +	local($i,$as,$ae,$bs,$be,$ai,$bi);
        +	local($tot,$end);
        +
        +	&function_begin_B($name,"");
        +
        +	$c0="ebx";
        +	$c1="ecx";
        +	$c2="ebp";
        +	$a="esi";
        +	$b="edi";
        +	
        +	$as=0;
        +	$ae=0;
        +	$bs=0;
        +	$be=0;
        +	$tot=$num+$num-1;
        +
        +	&push("esi");
        +	 &mov($a,&wparam(1));
        +	&push("edi");
        +	 &mov($b,&wparam(2));
        +	&push("ebp");
        +	 &push("ebx");
        +
        +	&xor($c0,$c0);
        +	 &mov("eax",&DWP(0,$a,"",0));	# load the first word 
        +	&xor($c1,$c1);
        +	 &mov("edx",&DWP(0,$b,"",0));	# load the first second 
        +
        +	for ($i=0; $i<$tot; $i++)
        +		{
        +		$ai=$as;
        +		$bi=$bs;
        +		$end=$be+1;
        +
        +		&comment("################## Calculate word $i"); 
        +
        +		for ($j=$bs; $j<$end; $j++)
        +			{
        +			&xor($c2,$c2) if ($j == $bs);
        +			if (($j+1) == $end)
        +				{
        +				$v=1;
        +				$v=2 if (($i+1) == $tot);
        +				}
        +			else
        +				{ $v=0; }
        +			if (($j+1) != $end)
        +				{
        +				$na=($ai-1);
        +				$nb=($bi+1);
        +				}
        +			else
        +				{
        +				$na=$as+($i < ($num-1));
        +				$nb=$bs+($i >= ($num-1));
        +				}
        +#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
        +			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
        +			if ($v)
        +				{
        +				&comment("saved r[$i]");
        +				# &mov("eax",&wparam(0));
        +				# &mov(&DWP($i*4,"eax","",0),$c0);
        +				($c0,$c1,$c2)=($c1,$c2,$c0);
        +				}
        +			$ai--;
        +			$bi++;
        +			}
        +		$as++ if ($i < ($num-1));
        +		$ae++ if ($i >= ($num-1));
        +
        +		$bs++ if ($i >= ($num-1));
        +		$be++ if ($i < ($num-1));
        +		}
        +	&comment("save r[$i]");
        +	# &mov("eax",&wparam(0));
        +	&mov(&DWP($i*4,"eax","",0),$c0);
        +
        +	&pop("ebx");
        +	&pop("ebp");
        +	&pop("edi");
        +	&pop("esi");
        +	&ret();
        +	&function_end_B($name);
        +	}
        +
        +sub bn_sqr_comba
        +	{
        +	local($name,$num)=@_;
        +	local($r,$a,$c0,$c1,$c2)=@_;
        +	local($i,$as,$ae,$bs,$be,$ai,$bi);
        +	local($b,$tot,$end,$half);
        +
        +	&function_begin_B($name,"");
        +
        +	$c0="ebx";
        +	$c1="ecx";
        +	$c2="ebp";
        +	$a="esi";
        +	$r="edi";
        +
        +	&push("esi");
        +	 &push("edi");
        +	&push("ebp");
        +	 &push("ebx");
        +	&mov($r,&wparam(0));
        +	 &mov($a,&wparam(1));
        +	&xor($c0,$c0);
        +	 &xor($c1,$c1);
        +	&mov("eax",&DWP(0,$a,"",0)); # load the first word
        +
        +	$as=0;
        +	$ae=0;
        +	$bs=0;
        +	$be=0;
        +	$tot=$num+$num-1;
        +
        +	for ($i=0; $i<$tot; $i++)
        +		{
        +		$ai=$as;
        +		$bi=$bs;
        +		$end=$be+1;
        +
        +		&comment("############### Calculate word $i");
        +		for ($j=$bs; $j<$end; $j++)
        +			{
        +			&xor($c2,$c2) if ($j == $bs);
        +			if (($ai-1) < ($bi+1))
        +				{
        +				$v=1;
        +				$v=2 if ($i+1) == $tot;
        +				}
        +			else
        +				{ $v=0; }
        +			if (!$v)
        +				{
        +				$na=$ai-1;
        +				$nb=$bi+1;
        +				}
        +			else
        +				{
        +				$na=$as+($i < ($num-1));
        +				$nb=$bs+($i >= ($num-1));
        +				}
        +			if ($ai == $bi)
        +				{
        +				&sqr_add_c($r,$a,$ai,$bi,
        +					$c0,$c1,$c2,$v,$i,$na,$nb);
        +				}
        +			else
        +				{
        +				&sqr_add_c2($r,$a,$ai,$bi,
        +					$c0,$c1,$c2,$v,$i,$na,$nb);
        +				}
        +			if ($v)
        +				{
        +				&comment("saved r[$i]");
        +				#&mov(&DWP($i*4,$r,"",0),$c0);
        +				($c0,$c1,$c2)=($c1,$c2,$c0);
        +				last;
        +				}
        +			$ai--;
        +			$bi++;
        +			}
        +		$as++ if ($i < ($num-1));
        +		$ae++ if ($i >= ($num-1));
        +
        +		$bs++ if ($i >= ($num-1));
        +		$be++ if ($i < ($num-1));
        +		}
        +	&mov(&DWP($i*4,$r,"",0),$c0);
        +	&pop("ebx");
        +	&pop("ebp");
        +	&pop("edi");
        +	&pop("esi");
        +	&ret();
        +	&function_end_B($name);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/ia64-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/ia64-mont.pl
        new file mode 100644
        index 000000000..e25865842
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/ia64-mont.pl
        @@ -0,0 +1,851 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# January 2010
        +#
        +# "Teaser" Montgomery multiplication module for IA-64. There are
        +# several possibilities for improvement:
        +#
        +# - modulo-scheduling outer loop would eliminate quite a number of
        +#   stalls after ldf8, xma and getf.sig outside inner loop and
        +#   improve shorter key performance;
        +# - shorter vector support [with input vectors being fetched only
        +#   once] should be added;
        +# - 2x unroll with help of n0[1] would make the code scalable on
        +#   "wider" IA-64, "wider" than Itanium 2 that is, which is not of
        +#   acute interest, because upcoming Tukwila's individual cores are
        +#   reportedly based on Itanium 2 design;
        +# - dedicated squaring procedure(?);
        +#
        +# January 2010
        +#
        +# Shorter vector support is implemented by zero-padding ap and np
        +# vectors up to 8 elements, or 512 bits. This means that 256-bit
        +# inputs will be processed only 2 times faster than 512-bit inputs,
        +# not 4 [as one would expect, because algorithm complexity is n^2].
        +# The reason for padding is that inputs shorter than 512 bits won't
        +# be processed faster anyway, because minimal critical path of the
        +# core loop happens to match 512-bit timing. Either way, it resulted
        +# in >100% improvement of 512-bit RSA sign benchmark and 50% - of
        +# 1024-bit one [in comparison to original version of *this* module].
        +#
        +# So far 'openssl speed rsa dsa' output on 900MHz Itanium 2 *with*
        +# this module is:
        +#                   sign    verify    sign/s verify/s
        +# rsa  512 bits 0.000290s 0.000024s   3452.8  42031.4
        +# rsa 1024 bits 0.000793s 0.000058s   1261.7  17172.0
        +# rsa 2048 bits 0.005908s 0.000148s    169.3   6754.0
        +# rsa 4096 bits 0.033456s 0.000469s     29.9   2133.6
        +# dsa  512 bits 0.000253s 0.000198s   3949.9   5057.0
        +# dsa 1024 bits 0.000585s 0.000607s   1708.4   1647.4
        +# dsa 2048 bits 0.001453s 0.001703s    688.1    587.4
        +#
        +# ... and *without* (but still with ia64.S):
        +#
        +# rsa  512 bits 0.000670s 0.000041s   1491.8  24145.5
        +# rsa 1024 bits 0.001988s 0.000080s    502.9  12499.3
        +# rsa 2048 bits 0.008702s 0.000189s    114.9   5293.9
        +# rsa 4096 bits 0.043860s 0.000533s     22.8   1875.9
        +# dsa  512 bits 0.000441s 0.000427s   2265.3   2340.6
        +# dsa 1024 bits 0.000823s 0.000867s   1215.6   1153.2
        +# dsa 2048 bits 0.001894s 0.002179s    528.1    458.9
        +#
        +# As it can be seen, RSA sign performance improves by 130-30%,
        +# hereafter less for longer keys, while verify - by 74-13%.
        +# DSA performance improves by 115-30%.
        +
        +if ($^O eq "hpux") {
        +    $ADDP="addp4";
        +    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
        +} else { $ADDP="add"; }
        +
        +$code=<<___;
        +.explicit
        +.text
        +
        +// int bn_mul_mont (BN_ULONG *rp,const BN_ULONG *ap,
        +//		    const BN_ULONG *bp,const BN_ULONG *np,
        +//		    const BN_ULONG *n0p,int num);			
        +.align	64
        +.global	bn_mul_mont#
        +.proc	bn_mul_mont#
        +bn_mul_mont:
        +	.prologue
        +	.body
        +{ .mmi;	cmp4.le		p6,p7=2,r37;;
        +(p6)	cmp4.lt.unc	p8,p9=8,r37
        +	mov		ret0=r0		};;
        +{ .bbb;
        +(p9)	br.cond.dptk.many	bn_mul_mont_8
        +(p8)	br.cond.dpnt.many	bn_mul_mont_general
        +(p7)	br.ret.spnt.many	b0	};;
        +.endp	bn_mul_mont#
        +
        +prevfs=r2;	prevpr=r3;	prevlc=r10;	prevsp=r11;
        +
        +rptr=r8;	aptr=r9;	bptr=r14;	nptr=r15;
        +tptr=r16;	// &tp[0]
        +tp_1=r17;	// &tp[-1]
        +num=r18;	len=r19;	lc=r20;
        +topbit=r21;	// carry bit from tmp[num]
        +
        +n0=f6;
        +m0=f7;
        +bi=f8;
        +
        +.align	64
        +.local	bn_mul_mont_general#
        +.proc	bn_mul_mont_general#
        +bn_mul_mont_general:
        +	.prologue
        +{ .mmi;	.save	ar.pfs,prevfs
        +	alloc	prevfs=ar.pfs,6,2,0,8
        +	$ADDP	aptr=0,in1
        +	.save	ar.lc,prevlc
        +	mov	prevlc=ar.lc		}
        +{ .mmi;	.vframe	prevsp
        +	mov	prevsp=sp
        +	$ADDP	bptr=0,in2
        +	.save	pr,prevpr
        +	mov	prevpr=pr		};;
        +
        +	.body
        +	.rotf		alo[6],nlo[4],ahi[8],nhi[6]
        +	.rotr		a[3],n[3],t[2]
        +
        +{ .mmi;	ldf8		bi=[bptr],8		// (*bp++)
        +	ldf8		alo[4]=[aptr],16	// ap[0]
        +	$ADDP		r30=8,in1	};;
        +{ .mmi;	ldf8		alo[3]=[r30],16		// ap[1]
        +	ldf8		alo[2]=[aptr],16	// ap[2]
        +	$ADDP		in4=0,in4	};;
        +{ .mmi;	ldf8		alo[1]=[r30]		// ap[3]
        +	ldf8		n0=[in4]		// n0
        +	$ADDP		rptr=0,in0		}
        +{ .mmi;	$ADDP		nptr=0,in3
        +	mov		r31=16
        +	zxt4		num=in5		};;
        +{ .mmi;	ldf8		nlo[2]=[nptr],8		// np[0]
        +	shladd		len=num,3,r0
        +	shladd		r31=num,3,r31	};;
        +{ .mmi;	ldf8		nlo[1]=[nptr],8		// np[1]
        +	add		lc=-5,num
        +	sub		r31=sp,r31	};;
        +{ .mfb;	and		sp=-16,r31		// alloca
        +	xmpy.hu		ahi[2]=alo[4],bi	// ap[0]*bp[0]
        +	nop.b		0		}
        +{ .mfb;	nop.m		0
        +	xmpy.lu		alo[4]=alo[4],bi
        +	brp.loop.imp	.L1st_ctop,.L1st_cend-16
        +					};;
        +{ .mfi;	nop.m		0
        +	xma.hu		ahi[1]=alo[3],bi,ahi[2]	// ap[1]*bp[0]
        +	add		tp_1=8,sp	}
        +{ .mfi;	nop.m		0
        +	xma.lu		alo[3]=alo[3],bi,ahi[2]
        +	mov		pr.rot=0x20001f<<16
        +			// ------^----- (p40) at first (p23)
        +			// ----------^^ p[16:20]=1
        +					};;
        +{ .mfi;	nop.m		0
        +	xmpy.lu		m0=alo[4],n0		// (ap[0]*bp[0])*n0
        +	mov		ar.lc=lc	}
        +{ .mfi;	nop.m		0
        +	fcvt.fxu.s1	nhi[1]=f0
        +	mov		ar.ec=8		};;
        +
        +.align	32
        +.L1st_ctop:
        +.pred.rel	"mutex",p40,p42
        +{ .mfi;	(p16)	ldf8		alo[0]=[aptr],8		    // *(aptr++)
        +	(p18)	xma.hu		ahi[0]=alo[2],bi,ahi[1]
        +	(p40)	add		n[2]=n[2],a[2]		}   // (p23)					}
        +{ .mfi;	(p18)	ldf8		nlo[0]=[nptr],8		    // *(nptr++)(p16)
        +	(p18)	xma.lu		alo[2]=alo[2],bi,ahi[1]
        +	(p42)	add		n[2]=n[2],a[2],1	};; // (p23)
        +{ .mfi;	(p21)	getf.sig	a[0]=alo[5]
        +	(p20)	xma.hu		nhi[0]=nlo[2],m0,nhi[1]
        +	(p42)	cmp.leu		p41,p39=n[2],a[2]   	}   // (p23)
        +{ .mfi;	(p23)	st8		[tp_1]=n[2],8
        +	(p20)	xma.lu		nlo[2]=nlo[2],m0,nhi[1]
        +	(p40)	cmp.ltu		p41,p39=n[2],a[2]	}   // (p23)
        +{ .mmb;	(p21)	getf.sig	n[0]=nlo[3]
        +	(p16)	nop.m		0
        +	br.ctop.sptk	.L1st_ctop			};;
        +.L1st_cend:
        +
        +{ .mmi;	getf.sig	a[0]=ahi[6]		// (p24)
        +	getf.sig	n[0]=nhi[4]
        +	add		num=-1,num	};;	// num--
        +{ .mmi;	.pred.rel	"mutex",p40,p42
        +(p40)	add		n[0]=n[0],a[0]
        +(p42)	add		n[0]=n[0],a[0],1
        +	sub		aptr=aptr,len	};;	// rewind
        +{ .mmi;	.pred.rel	"mutex",p40,p42
        +(p40)	cmp.ltu		p41,p39=n[0],a[0]
        +(p42)	cmp.leu		p41,p39=n[0],a[0]
        +	sub		nptr=nptr,len	};;
        +{ .mmi;	.pred.rel	"mutex",p39,p41
        +(p39)	add		topbit=r0,r0
        +(p41)	add		topbit=r0,r0,1
        +	nop.i		0		}	
        +{ .mmi;	st8		[tp_1]=n[0]
        +	add		tptr=16,sp
        +	add		tp_1=8,sp	};;
        +
        +.Louter:
        +{ .mmi;	ldf8		bi=[bptr],8		// (*bp++)
        +	ldf8		ahi[3]=[tptr]		// tp[0]
        +	add		r30=8,aptr	};;
        +{ .mmi;	ldf8		alo[4]=[aptr],16	// ap[0]
        +	ldf8		alo[3]=[r30],16		// ap[1]
        +	add		r31=8,nptr	};;
        +{ .mfb;	ldf8		alo[2]=[aptr],16	// ap[2]
        +	xma.hu		ahi[2]=alo[4],bi,ahi[3]	// ap[0]*bp[i]+tp[0]
        +	brp.loop.imp	.Linner_ctop,.Linner_cend-16
        +					}
        +{ .mfb;	ldf8		alo[1]=[r30]		// ap[3]
        +	xma.lu		alo[4]=alo[4],bi,ahi[3]
        +	clrrrb.pr			};;
        +{ .mfi;	ldf8		nlo[2]=[nptr],16	// np[0]
        +	xma.hu		ahi[1]=alo[3],bi,ahi[2]	// ap[1]*bp[i]
        +	nop.i		0		}
        +{ .mfi;	ldf8		nlo[1]=[r31]		// np[1]
        +	xma.lu		alo[3]=alo[3],bi,ahi[2]
        +	mov		pr.rot=0x20101f<<16
        +			// ------^----- (p40) at first (p23)
        +			// --------^--- (p30) at first (p22)
        +			// ----------^^ p[16:20]=1
        +					};;
        +{ .mfi;	st8		[tptr]=r0		// tp[0] is already accounted
        +	xmpy.lu		m0=alo[4],n0		// (ap[0]*bp[i]+tp[0])*n0
        +	mov		ar.lc=lc	}
        +{ .mfi;
        +	fcvt.fxu.s1	nhi[1]=f0
        +	mov		ar.ec=8		};;
        +
        +// This loop spins in 4*(n+7) ticks on Itanium 2 and should spin in
        +// 7*(n+7) ticks on Itanium (the one codenamed Merced). Factor of 7
        +// in latter case accounts for two-tick pipeline stall, which means
        +// that its performance would be ~20% lower than optimal one. No
        +// attempt was made to address this, because original Itanium is
        +// hardly represented out in the wild...
        +.align	32
        +.Linner_ctop:
        +.pred.rel	"mutex",p40,p42
        +.pred.rel	"mutex",p30,p32
        +{ .mfi;	(p16)	ldf8		alo[0]=[aptr],8		    // *(aptr++)
        +	(p18)	xma.hu		ahi[0]=alo[2],bi,ahi[1]
        +	(p40)	add		n[2]=n[2],a[2]		}   // (p23)
        +{ .mfi;	(p16)	nop.m		0
        +	(p18)	xma.lu		alo[2]=alo[2],bi,ahi[1]
        +	(p42)	add		n[2]=n[2],a[2],1	};; // (p23)
        +{ .mfi;	(p21)	getf.sig	a[0]=alo[5]
        +	(p16)	nop.f		0
        +	(p40)	cmp.ltu		p41,p39=n[2],a[2]	}   // (p23)
        +{ .mfi;	(p21)	ld8		t[0]=[tptr],8
        +	(p16)	nop.f		0
        +	(p42)	cmp.leu		p41,p39=n[2],a[2]	};; // (p23)
        +{ .mfi;	(p18)	ldf8		nlo[0]=[nptr],8		    // *(nptr++)
        +	(p20)	xma.hu		nhi[0]=nlo[2],m0,nhi[1]
        +	(p30)	add		a[1]=a[1],t[1]		}   // (p22)
        +{ .mfi;	(p16)	nop.m		0
        +	(p20)	xma.lu		nlo[2]=nlo[2],m0,nhi[1]
        +	(p32)	add		a[1]=a[1],t[1],1	};; // (p22)
        +{ .mmi;	(p21)	getf.sig	n[0]=nlo[3]
        +	(p16)	nop.m		0
        +	(p30)	cmp.ltu		p31,p29=a[1],t[1]	}   // (p22)
        +{ .mmb;	(p23)	st8		[tp_1]=n[2],8
        +	(p32)	cmp.leu		p31,p29=a[1],t[1]	    // (p22)
        +	br.ctop.sptk	.Linner_ctop			};;
        +.Linner_cend:
        +
        +{ .mmi;	getf.sig	a[0]=ahi[6]		// (p24)
        +	getf.sig	n[0]=nhi[4]
        +	nop.i		0		};;
        +
        +{ .mmi;	.pred.rel	"mutex",p31,p33
        +(p31)	add		a[0]=a[0],topbit
        +(p33)	add		a[0]=a[0],topbit,1
        +	mov		topbit=r0	};;
        +{ .mfi; .pred.rel	"mutex",p31,p33
        +(p31)	cmp.ltu		p32,p30=a[0],topbit
        +(p33)	cmp.leu		p32,p30=a[0],topbit
        +					}
        +{ .mfi;	.pred.rel	"mutex",p40,p42
        +(p40)	add		n[0]=n[0],a[0]
        +(p42)	add		n[0]=n[0],a[0],1
        +					};;
        +{ .mmi;	.pred.rel	"mutex",p44,p46
        +(p40)	cmp.ltu		p41,p39=n[0],a[0]
        +(p42)	cmp.leu		p41,p39=n[0],a[0]
        +(p32)	add		topbit=r0,r0,1	}
        +
        +{ .mmi;	st8		[tp_1]=n[0],8
        +	cmp4.ne		p6,p0=1,num
        +	sub		aptr=aptr,len	};;	// rewind
        +{ .mmi;	sub		nptr=nptr,len
        +(p41)	add		topbit=r0,r0,1
        +	add		tptr=16,sp	}
        +{ .mmb;	add		tp_1=8,sp
        +	add		num=-1,num		// num--
        +(p6)	br.cond.sptk.many	.Louter	};;
        +
        +{ .mbb;	add		lc=4,lc
        +	brp.loop.imp	.Lsub_ctop,.Lsub_cend-16
        +	clrrrb.pr			};;
        +{ .mii;	nop.m		0
        +	mov		pr.rot=0x10001<<16
        +			// ------^---- (p33) at first (p17)
        +	mov		ar.lc=lc	}
        +{ .mii;	nop.m		0
        +	mov		ar.ec=3
        +	nop.i		0		};;
        +
        +.Lsub_ctop:
        +.pred.rel	"mutex",p33,p35
        +{ .mfi;	(p16)	ld8		t[0]=[tptr],8		    // t=*(tp++)
        +	(p16)	nop.f		0
        +	(p33)	sub		n[1]=t[1],n[1]		}   // (p17)
        +{ .mfi;	(p16)	ld8		n[0]=[nptr],8		    // n=*(np++)
        +	(p16)	nop.f		0
        +	(p35)	sub		n[1]=t[1],n[1],1	};; // (p17)
        +{ .mib;	(p18)	st8		[rptr]=n[2],8		    // *(rp++)=r
        +	(p33)	cmp.gtu		p34,p32=n[1],t[1]	    // (p17)
        +	(p18)	nop.b		0			}
        +{ .mib;	(p18)	nop.m		0
        +	(p35)	cmp.geu		p34,p32=n[1],t[1]	    // (p17)
        +	br.ctop.sptk	.Lsub_ctop			};;
        +.Lsub_cend:
        +
        +{ .mmb;	.pred.rel	"mutex",p34,p36
        +(p34)	sub	topbit=topbit,r0	// (p19)
        +(p36)	sub	topbit=topbit,r0,1
        +	brp.loop.imp	.Lcopy_ctop,.Lcopy_cend-16
        +					}
        +{ .mmb;	sub	rptr=rptr,len		// rewind
        +	sub	tptr=tptr,len
        +	clrrrb.pr			};;
        +{ .mmi;	and	aptr=tptr,topbit
        +	andcm	bptr=rptr,topbit
        +	mov	pr.rot=1<<16		};;
        +{ .mii;	or	nptr=aptr,bptr
        +	mov	ar.lc=lc
        +	mov	ar.ec=3			};;
        +
        +.Lcopy_ctop:
        +{ .mmb;	(p16)	ld8	n[0]=[nptr],8
        +	(p18)	st8	[tptr]=r0,8
        +	(p16)	nop.b	0		}
        +{ .mmb;	(p16)	nop.m	0
        +	(p18)	st8	[rptr]=n[2],8
        +	br.ctop.sptk	.Lcopy_ctop	};;
        +.Lcopy_cend:
        +
        +{ .mmi;	mov		ret0=1			// signal "handled"
        +	rum		1<<5			// clear um.mfh
        +	mov		ar.lc=prevlc	}
        +{ .mib;	.restore	sp
        +	mov		sp=prevsp
        +	mov		pr=prevpr,0x1ffff
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_mul_mont_general#
        +
        +a1=r16;  a2=r17;  a3=r18;  a4=r19;  a5=r20;  a6=r21;  a7=r22;  a8=r23;
        +n1=r24;  n2=r25;  n3=r26;  n4=r27;  n5=r28;  n6=r29;  n7=r30;  n8=r31;
        +t0=r15;
        +
        +ai0=f8;  ai1=f9;  ai2=f10; ai3=f11; ai4=f12; ai5=f13; ai6=f14; ai7=f15;
        +ni0=f16; ni1=f17; ni2=f18; ni3=f19; ni4=f20; ni5=f21; ni6=f22; ni7=f23;
        +
        +.align	64
        +.skip	48		// aligns loop body
        +.local	bn_mul_mont_8#
        +.proc	bn_mul_mont_8#
        +bn_mul_mont_8:
        +	.prologue
        +{ .mmi;	.save		ar.pfs,prevfs
        +	alloc		prevfs=ar.pfs,6,2,0,8
        +	.vframe		prevsp
        +	mov		prevsp=sp
        +	.save		ar.lc,prevlc
        +	mov		prevlc=ar.lc	}
        +{ .mmi;	add		r17=-6*16,sp
        +	add		sp=-7*16,sp
        +	.save		pr,prevpr
        +	mov		prevpr=pr	};;
        +
        +{ .mmi;	.save.gf	0,0x10
        +	stf.spill	[sp]=f16,-16
        +	.save.gf	0,0x20
        +	stf.spill	[r17]=f17,32
        +	add		r16=-5*16,prevsp};;
        +{ .mmi;	.save.gf	0,0x40
        +	stf.spill	[r16]=f18,32
        +	.save.gf	0,0x80
        +	stf.spill	[r17]=f19,32
        +	$ADDP		aptr=0,in1	};;
        +{ .mmi;	.save.gf	0,0x100
        +	stf.spill	[r16]=f20,32
        +	.save.gf	0,0x200
        +	stf.spill	[r17]=f21,32
        +	$ADDP		r29=8,in1	};;
        +{ .mmi;	.save.gf	0,0x400
        +	stf.spill	[r16]=f22
        +	.save.gf	0,0x800
        +	stf.spill	[r17]=f23
        +	$ADDP		rptr=0,in0	};;
        +
        +	.body
        +	.rotf		bj[8],mj[2],tf[2],alo[10],ahi[10],nlo[10],nhi[10]
        +	.rotr		t[8]
        +
        +// load input vectors padding them to 8 elements
        +{ .mmi;	ldf8		ai0=[aptr],16		// ap[0]
        +	ldf8		ai1=[r29],16		// ap[1]
        +	$ADDP		bptr=0,in2	}
        +{ .mmi;	$ADDP		r30=8,in2
        +	$ADDP		nptr=0,in3
        +	$ADDP		r31=8,in3	};;
        +{ .mmi;	ldf8		bj[7]=[bptr],16		// bp[0]
        +	ldf8		bj[6]=[r30],16		// bp[1]
        +	cmp4.le		p4,p5=3,in5	}
        +{ .mmi;	ldf8		ni0=[nptr],16		// np[0]
        +	ldf8		ni1=[r31],16		// np[1]
        +	cmp4.le		p6,p7=4,in5	};;
        +
        +{ .mfi;	(p4)ldf8	ai2=[aptr],16		// ap[2]
        +	(p5)fcvt.fxu	ai2=f0
        +	cmp4.le		p8,p9=5,in5	}
        +{ .mfi;	(p6)ldf8	ai3=[r29],16		// ap[3]
        +	(p7)fcvt.fxu	ai3=f0
        +	cmp4.le		p10,p11=6,in5	}
        +{ .mfi;	(p4)ldf8	bj[5]=[bptr],16		// bp[2]
        +	(p5)fcvt.fxu	bj[5]=f0
        +	cmp4.le		p12,p13=7,in5	}
        +{ .mfi;	(p6)ldf8	bj[4]=[r30],16		// bp[3]
        +	(p7)fcvt.fxu	bj[4]=f0
        +	cmp4.le		p14,p15=8,in5	}
        +{ .mfi;	(p4)ldf8	ni2=[nptr],16		// np[2]
        +	(p5)fcvt.fxu	ni2=f0
        +	addp4		r28=-1,in5	}
        +{ .mfi;	(p6)ldf8	ni3=[r31],16		// np[3]
        +	(p7)fcvt.fxu	ni3=f0
        +	$ADDP		in4=0,in4	};;
        +
        +{ .mfi;	ldf8		n0=[in4]
        +	fcvt.fxu	tf[1]=f0
        +	nop.i		0		}
        +
        +{ .mfi;	(p8)ldf8	ai4=[aptr],16		// ap[4]
        +	(p9)fcvt.fxu	ai4=f0
        +	mov		t[0]=r0		}
        +{ .mfi;	(p10)ldf8	ai5=[r29],16		// ap[5]
        +	(p11)fcvt.fxu	ai5=f0
        +	mov		t[1]=r0		}
        +{ .mfi;	(p8)ldf8	bj[3]=[bptr],16		// bp[4]
        +	(p9)fcvt.fxu	bj[3]=f0
        +	mov		t[2]=r0		}
        +{ .mfi;	(p10)ldf8	bj[2]=[r30],16		// bp[5]
        +	(p11)fcvt.fxu	bj[2]=f0
        +	mov		t[3]=r0		}
        +{ .mfi;	(p8)ldf8	ni4=[nptr],16		// np[4]
        +	(p9)fcvt.fxu	ni4=f0
        +	mov		t[4]=r0		}
        +{ .mfi;	(p10)ldf8	ni5=[r31],16		// np[5]
        +	(p11)fcvt.fxu	ni5=f0
        +	mov		t[5]=r0		};;
        +
        +{ .mfi;	(p12)ldf8	ai6=[aptr],16		// ap[6]
        +	(p13)fcvt.fxu	ai6=f0
        +	mov		t[6]=r0		}
        +{ .mfi;	(p14)ldf8	ai7=[r29],16		// ap[7]
        +	(p15)fcvt.fxu	ai7=f0
        +	mov		t[7]=r0		}
        +{ .mfi;	(p12)ldf8	bj[1]=[bptr],16		// bp[6]
        +	(p13)fcvt.fxu	bj[1]=f0
        +	mov		ar.lc=r28	}
        +{ .mfi;	(p14)ldf8	bj[0]=[r30],16		// bp[7]
        +	(p15)fcvt.fxu	bj[0]=f0
        +	mov		ar.ec=1		}
        +{ .mfi;	(p12)ldf8	ni6=[nptr],16		// np[6]
        +	(p13)fcvt.fxu	ni6=f0
        +	mov		pr.rot=1<<16	}
        +{ .mfb;	(p14)ldf8	ni7=[r31],16		// np[7]
        +	(p15)fcvt.fxu	ni7=f0
        +	brp.loop.imp	.Louter_8_ctop,.Louter_8_cend-16
        +					};;
        +
        +// The loop is scheduled for 32*n ticks on Itanium 2. Actual attempt
        +// to measure with help of Interval Time Counter indicated that the
        +// factor is a tad higher: 33 or 34, if not 35. Exact measurement and
        +// addressing the issue is problematic, because I don't have access
        +// to platform-specific instruction-level profiler. On Itanium it
        +// should run in 56*n ticks, because of higher xma latency...
        +.Louter_8_ctop:
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mfi;	(p16)	nop.m		0			// 0:
        +	(p16)	xma.hu		ahi[0]=ai0,bj[7],tf[1]	//	ap[0]*b[i]+t[0]
        +	(p40)	add		a3=a3,n3	}	//	(p17) a3+=n3
        +{ .mfi;	(p42)	add		a3=a3,n3,1
        +	(p16)	xma.lu		alo[0]=ai0,bj[7],tf[1]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p17)	getf.sig	a7=alo[8]		// 1:
        +	(p48)	add		t[6]=t[6],a3		//	(p17) t[6]+=a3
        +	(p50)	add		t[6]=t[6],a3,1	};;
        +{ .mfi;	(p17)	getf.sig	a8=ahi[8]		// 2:
        +	(p17)	xma.hu		nhi[7]=ni6,mj[1],nhi[6]	//	np[6]*m0
        +	(p40)	cmp.ltu		p43,p41=a3,n3	}
        +{ .mfi;	(p42)	cmp.leu		p43,p41=a3,n3
        +	(p17)	xma.lu		nlo[7]=ni6,mj[1],nhi[6]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p17)	getf.sig	n5=nlo[6]		// 3:
        +	(p48)	cmp.ltu		p51,p49=t[6],a3
        +	(p50)	cmp.leu		p51,p49=t[6],a3	};;
        +	.pred.rel		"mutex",p41,p43
        +	.pred.rel		"mutex",p49,p51
        +{ .mfi;	(p16)	nop.m		0			// 4:
        +	(p16)	xma.hu		ahi[1]=ai1,bj[7],ahi[0]	//	ap[1]*b[i]
        +	(p41)	add		a4=a4,n4	}	//	(p17) a4+=n4
        +{ .mfi;	(p43)	add		a4=a4,n4,1
        +	(p16)	xma.lu		alo[1]=ai1,bj[7],ahi[0]
        +	(p16)	nop.i		0		};;
        +{ .mfi;	(p49)	add		t[5]=t[5],a4		// 5:	(p17) t[5]+=a4
        +	(p16)	xmpy.lu		mj[0]=alo[0],n0		//	(ap[0]*b[i]+t[0])*n0
        +	(p51)	add		t[5]=t[5],a4,1	};;
        +{ .mfi;	(p16)	nop.m		0			// 6:
        +	(p17)	xma.hu		nhi[8]=ni7,mj[1],nhi[7]	//	np[7]*m0
        +	(p41)	cmp.ltu		p42,p40=a4,n4	}
        +{ .mfi;	(p43)	cmp.leu		p42,p40=a4,n4
        +	(p17)	xma.lu		nlo[8]=ni7,mj[1],nhi[7]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p17)	getf.sig	n6=nlo[7]		// 7:
        +	(p49)	cmp.ltu		p50,p48=t[5],a4
        +	(p51)	cmp.leu		p50,p48=t[5],a4	};;
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mfi;	(p16)	nop.m		0			// 8:
        +	(p16)	xma.hu		ahi[2]=ai2,bj[7],ahi[1]	//	ap[2]*b[i]
        +	(p40)	add		a5=a5,n5	}	//	(p17) a5+=n5
        +{ .mfi;	(p42)	add		a5=a5,n5,1
        +	(p16)	xma.lu		alo[2]=ai2,bj[7],ahi[1]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	a1=alo[1]		// 9:
        +	(p48)	add		t[4]=t[4],a5		//	p(17) t[4]+=a5
        +	(p50)	add		t[4]=t[4],a5,1	};;
        +{ .mfi;	(p16)	nop.m		0			// 10:
        +	(p16)	xma.hu		nhi[0]=ni0,mj[0],alo[0]	//	np[0]*m0
        +	(p40)	cmp.ltu		p43,p41=a5,n5	}
        +{ .mfi;	(p42)	cmp.leu		p43,p41=a5,n5
        +	(p16)	xma.lu		nlo[0]=ni0,mj[0],alo[0]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p17)	getf.sig	n7=nlo[8]		// 11:
        +	(p48)	cmp.ltu		p51,p49=t[4],a5
        +	(p50)	cmp.leu		p51,p49=t[4],a5	};;
        +	.pred.rel		"mutex",p41,p43
        +	.pred.rel		"mutex",p49,p51
        +{ .mfi;	(p17)	getf.sig	n8=nhi[8]		// 12:
        +	(p16)	xma.hu		ahi[3]=ai3,bj[7],ahi[2]	//	ap[3]*b[i]
        +	(p41)	add		a6=a6,n6	}	//	(p17) a6+=n6
        +{ .mfi;	(p43)	add		a6=a6,n6,1
        +	(p16)	xma.lu		alo[3]=ai3,bj[7],ahi[2]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	a2=alo[2]		// 13:
        +	(p49)	add		t[3]=t[3],a6		//	(p17) t[3]+=a6
        +	(p51)	add		t[3]=t[3],a6,1	};;
        +{ .mfi;	(p16)	nop.m		0			// 14:
        +	(p16)	xma.hu		nhi[1]=ni1,mj[0],nhi[0]	//	np[1]*m0
        +	(p41)	cmp.ltu		p42,p40=a6,n6	}
        +{ .mfi;	(p43)	cmp.leu		p42,p40=a6,n6
        +	(p16)	xma.lu		nlo[1]=ni1,mj[0],nhi[0]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	nop.m		0			// 15:
        +	(p49)	cmp.ltu		p50,p48=t[3],a6
        +	(p51)	cmp.leu		p50,p48=t[3],a6	};;
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mfi;	(p16)	nop.m		0			// 16:
        +	(p16)	xma.hu		ahi[4]=ai4,bj[7],ahi[3]	//	ap[4]*b[i]
        +	(p40)	add		a7=a7,n7	}	//	(p17) a7+=n7
        +{ .mfi;	(p42)	add		a7=a7,n7,1
        +	(p16)	xma.lu		alo[4]=ai4,bj[7],ahi[3]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	a3=alo[3]		// 17:
        +	(p48)	add		t[2]=t[2],a7		//	(p17) t[2]+=a7
        +	(p50)	add		t[2]=t[2],a7,1	};;
        +{ .mfi;	(p16)	nop.m		0			// 18:
        +	(p16)	xma.hu		nhi[2]=ni2,mj[0],nhi[1]	//	np[2]*m0
        +	(p40)	cmp.ltu		p43,p41=a7,n7	}
        +{ .mfi;	(p42)	cmp.leu		p43,p41=a7,n7
        +	(p16)	xma.lu		nlo[2]=ni2,mj[0],nhi[1]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	n1=nlo[1]		// 19:
        +	(p48)	cmp.ltu		p51,p49=t[2],a7
        +	(p50)	cmp.leu		p51,p49=t[2],a7	};;
        +	.pred.rel		"mutex",p41,p43
        +	.pred.rel		"mutex",p49,p51
        +{ .mfi;	(p16)	nop.m		0			// 20:
        +	(p16)	xma.hu		ahi[5]=ai5,bj[7],ahi[4]	//	ap[5]*b[i]
        +	(p41)	add		a8=a8,n8	}	//	(p17) a8+=n8
        +{ .mfi;	(p43)	add		a8=a8,n8,1
        +	(p16)	xma.lu		alo[5]=ai5,bj[7],ahi[4]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	a4=alo[4]		// 21:
        +	(p49)	add		t[1]=t[1],a8		//	(p17) t[1]+=a8
        +	(p51)	add		t[1]=t[1],a8,1	};;
        +{ .mfi;	(p16)	nop.m		0			// 22:
        +	(p16)	xma.hu		nhi[3]=ni3,mj[0],nhi[2]	//	np[3]*m0
        +	(p41)	cmp.ltu		p42,p40=a8,n8	}
        +{ .mfi;	(p43)	cmp.leu		p42,p40=a8,n8
        +	(p16)	xma.lu		nlo[3]=ni3,mj[0],nhi[2]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	n2=nlo[2]		// 23:
        +	(p49)	cmp.ltu		p50,p48=t[1],a8
        +	(p51)	cmp.leu		p50,p48=t[1],a8	};;
        +{ .mfi;	(p16)	nop.m		0			// 24:
        +	(p16)	xma.hu		ahi[6]=ai6,bj[7],ahi[5]	//	ap[6]*b[i]
        +	(p16)	add		a1=a1,n1	}	//	(p16) a1+=n1
        +{ .mfi;	(p16)	nop.m		0
        +	(p16)	xma.lu		alo[6]=ai6,bj[7],ahi[5]
        +	(p17)	mov		t[0]=r0		};;
        +{ .mii;	(p16)	getf.sig	a5=alo[5]		// 25:
        +	(p16)	add		t0=t[7],a1		//	(p16) t[7]+=a1
        +	(p42)	add		t[0]=t[0],r0,1	};;
        +{ .mfi;	(p16)	setf.sig	tf[0]=t0		// 26:
        +	(p16)	xma.hu		nhi[4]=ni4,mj[0],nhi[3]	//	np[4]*m0
        +	(p50)	add		t[0]=t[0],r0,1	}
        +{ .mfi;	(p16)	cmp.ltu.unc	p42,p40=a1,n1
        +	(p16)	xma.lu		nlo[4]=ni4,mj[0],nhi[3]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	n3=nlo[3]		// 27:
        +	(p16)	cmp.ltu.unc	p50,p48=t0,a1
        +	(p16)	nop.i		0		};;
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mfi;	(p16)	nop.m		0			// 28:
        +	(p16)	xma.hu		ahi[7]=ai7,bj[7],ahi[6]	//	ap[7]*b[i]
        +	(p40)	add		a2=a2,n2	}	//	(p16) a2+=n2
        +{ .mfi;	(p42)	add		a2=a2,n2,1
        +	(p16)	xma.lu		alo[7]=ai7,bj[7],ahi[6]
        +	(p16)	nop.i		0		};;
        +{ .mii;	(p16)	getf.sig	a6=alo[6]		// 29:
        +	(p48)	add		t[6]=t[6],a2		//	(p16) t[6]+=a2
        +	(p50)	add		t[6]=t[6],a2,1	};;
        +{ .mfi;	(p16)	nop.m		0			// 30:
        +	(p16)	xma.hu		nhi[5]=ni5,mj[0],nhi[4]	//	np[5]*m0
        +	(p40)	cmp.ltu		p41,p39=a2,n2	}
        +{ .mfi;	(p42)	cmp.leu		p41,p39=a2,n2
        +	(p16)	xma.lu		nlo[5]=ni5,mj[0],nhi[4]
        +	(p16)	nop.i		0		};;
        +{ .mfi;	(p16)	getf.sig	n4=nlo[4]		// 31:
        +	(p16)	nop.f		0
        +	(p48)	cmp.ltu		p49,p47=t[6],a2	}
        +{ .mfb;	(p50)	cmp.leu		p49,p47=t[6],a2
        +	(p16)	nop.f		0
        +	br.ctop.sptk.many	.Louter_8_ctop	};;
        +.Louter_8_cend:
        +
        +// above loop has to execute one more time, without (p16), which is
        +// replaced with merged move of np[8] to GPR bank
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mmi;	(p0)	getf.sig	n1=ni0			// 0:
        +	(p40)	add		a3=a3,n3		//	(p17) a3+=n3
        +	(p42)	add		a3=a3,n3,1	};;
        +{ .mii;	(p17)	getf.sig	a7=alo[8]		// 1:
        +	(p48)	add		t[6]=t[6],a3		//	(p17) t[6]+=a3
        +	(p50)	add		t[6]=t[6],a3,1	};;
        +{ .mfi;	(p17)	getf.sig	a8=ahi[8]		// 2:
        +	(p17)	xma.hu		nhi[7]=ni6,mj[1],nhi[6]	//	np[6]*m0
        +	(p40)	cmp.ltu		p43,p41=a3,n3	}
        +{ .mfi;	(p42)	cmp.leu		p43,p41=a3,n3
        +	(p17)	xma.lu		nlo[7]=ni6,mj[1],nhi[6]
        +	(p0)	nop.i		0		};;
        +{ .mii;	(p17)	getf.sig	n5=nlo[6]		// 3:
        +	(p48)	cmp.ltu		p51,p49=t[6],a3
        +	(p50)	cmp.leu		p51,p49=t[6],a3	};;
        +	.pred.rel		"mutex",p41,p43
        +	.pred.rel		"mutex",p49,p51
        +{ .mmi;	(p0)	getf.sig	n2=ni1			// 4:
        +	(p41)	add		a4=a4,n4		//	(p17) a4+=n4
        +	(p43)	add		a4=a4,n4,1	};;
        +{ .mfi;	(p49)	add		t[5]=t[5],a4		// 5:	(p17) t[5]+=a4
        +	(p0)	nop.f		0
        +	(p51)	add		t[5]=t[5],a4,1	};;
        +{ .mfi;	(p0)	getf.sig	n3=ni2			// 6:
        +	(p17)	xma.hu		nhi[8]=ni7,mj[1],nhi[7]	//	np[7]*m0
        +	(p41)	cmp.ltu		p42,p40=a4,n4	}
        +{ .mfi;	(p43)	cmp.leu		p42,p40=a4,n4
        +	(p17)	xma.lu		nlo[8]=ni7,mj[1],nhi[7]
        +	(p0)	nop.i		0		};;
        +{ .mii;	(p17)	getf.sig	n6=nlo[7]		// 7:
        +	(p49)	cmp.ltu		p50,p48=t[5],a4
        +	(p51)	cmp.leu		p50,p48=t[5],a4	};;
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mii;	(p0)	getf.sig	n4=ni3			// 8:
        +	(p40)	add		a5=a5,n5		//	(p17) a5+=n5
        +	(p42)	add		a5=a5,n5,1	};;
        +{ .mii;	(p0)	nop.m		0			// 9:
        +	(p48)	add		t[4]=t[4],a5		//	p(17) t[4]+=a5
        +	(p50)	add		t[4]=t[4],a5,1	};;
        +{ .mii;	(p0)	nop.m		0			// 10:
        +	(p40)	cmp.ltu		p43,p41=a5,n5
        +	(p42)	cmp.leu		p43,p41=a5,n5	};;
        +{ .mii;	(p17)	getf.sig	n7=nlo[8]		// 11:
        +	(p48)	cmp.ltu		p51,p49=t[4],a5
        +	(p50)	cmp.leu		p51,p49=t[4],a5	};;
        +	.pred.rel		"mutex",p41,p43
        +	.pred.rel		"mutex",p49,p51
        +{ .mii;	(p17)	getf.sig	n8=nhi[8]		// 12:
        +	(p41)	add		a6=a6,n6		//	(p17) a6+=n6
        +	(p43)	add		a6=a6,n6,1	};;
        +{ .mii;	(p0)	getf.sig	n5=ni4			// 13:
        +	(p49)	add		t[3]=t[3],a6		//	(p17) t[3]+=a6
        +	(p51)	add		t[3]=t[3],a6,1	};;
        +{ .mii;	(p0)	nop.m		0			// 14:
        +	(p41)	cmp.ltu		p42,p40=a6,n6
        +	(p43)	cmp.leu		p42,p40=a6,n6	};;
        +{ .mii;	(p0)	getf.sig	n6=ni5			// 15:
        +	(p49)	cmp.ltu		p50,p48=t[3],a6
        +	(p51)	cmp.leu		p50,p48=t[3],a6	};;
        +	.pred.rel		"mutex",p40,p42
        +	.pred.rel		"mutex",p48,p50
        +{ .mii;	(p0)	nop.m		0			// 16:
        +	(p40)	add		a7=a7,n7		//	(p17) a7+=n7
        +	(p42)	add		a7=a7,n7,1	};;
        +{ .mii;	(p0)	nop.m		0			// 17:
        +	(p48)	add		t[2]=t[2],a7		//	(p17) t[2]+=a7
        +	(p50)	add		t[2]=t[2],a7,1	};;
        +{ .mii;	(p0)	nop.m		0			// 18:
        +	(p40)	cmp.ltu		p43,p41=a7,n7
        +	(p42)	cmp.leu		p43,p41=a7,n7	};;
        +{ .mii;	(p0)	getf.sig	n7=ni6			// 19:
        +	(p48)	cmp.ltu		p51,p49=t[2],a7
        +	(p50)	cmp.leu		p51,p49=t[2],a7	};;
        +	.pred.rel		"mutex",p41,p43
        +	.pred.rel		"mutex",p49,p51
        +{ .mii;	(p0)	nop.m		0			// 20:
        +	(p41)	add		a8=a8,n8		//	(p17) a8+=n8
        +	(p43)	add		a8=a8,n8,1	};;
        +{ .mmi;	(p0)	nop.m		0			// 21:
        +	(p49)	add		t[1]=t[1],a8		//	(p17) t[1]+=a8
        +	(p51)	add		t[1]=t[1],a8,1	}
        +{ .mmi;	(p17)	mov		t[0]=r0
        +	(p41)	cmp.ltu		p42,p40=a8,n8
        +	(p43)	cmp.leu		p42,p40=a8,n8	};;
        +{ .mmi;	(p0)	getf.sig	n8=ni7			// 22:
        +	(p49)	cmp.ltu		p50,p48=t[1],a8
        +	(p51)	cmp.leu		p50,p48=t[1],a8	}
        +{ .mmi;	(p42)	add		t[0]=t[0],r0,1
        +	(p0)	add		r16=-7*16,prevsp
        +	(p0)	add		r17=-6*16,prevsp	};;
        +
        +// subtract np[8] from carrybit|tmp[8]
        +// carrybit|tmp[8] layout upon exit from above loop is:
        +//	t[0]|t[1]|t[2]|t[3]|t[4]|t[5]|t[6]|t[7]|t0 (least significant)
        +{ .mmi;	(p50)add	t[0]=t[0],r0,1
        +	add		r18=-5*16,prevsp
        +	sub		n1=t0,n1	};;
        +{ .mmi;	cmp.gtu		p34,p32=n1,t0;;
        +	.pred.rel	"mutex",p32,p34
        +	(p32)sub	n2=t[7],n2
        +	(p34)sub	n2=t[7],n2,1	};;
        +{ .mii;	(p32)cmp.gtu	p35,p33=n2,t[7]
        +	(p34)cmp.geu	p35,p33=n2,t[7];;
        +	.pred.rel	"mutex",p33,p35
        +	(p33)sub	n3=t[6],n3	}
        +{ .mmi;	(p35)sub	n3=t[6],n3,1;;
        +	(p33)cmp.gtu	p34,p32=n3,t[6]
        +	(p35)cmp.geu	p34,p32=n3,t[6]	};;
        +	.pred.rel	"mutex",p32,p34
        +{ .mii;	(p32)sub	n4=t[5],n4
        +	(p34)sub	n4=t[5],n4,1;;
        +	(p32)cmp.gtu	p35,p33=n4,t[5]	}
        +{ .mmi;	(p34)cmp.geu	p35,p33=n4,t[5];;
        +	.pred.rel	"mutex",p33,p35
        +	(p33)sub	n5=t[4],n5
        +	(p35)sub	n5=t[4],n5,1	};;
        +{ .mii;	(p33)cmp.gtu	p34,p32=n5,t[4]
        +	(p35)cmp.geu	p34,p32=n5,t[4];;
        +	.pred.rel	"mutex",p32,p34
        +	(p32)sub	n6=t[3],n6	}
        +{ .mmi;	(p34)sub	n6=t[3],n6,1;;
        +	(p32)cmp.gtu	p35,p33=n6,t[3]
        +	(p34)cmp.geu	p35,p33=n6,t[3]	};;
        +	.pred.rel	"mutex",p33,p35
        +{ .mii;	(p33)sub	n7=t[2],n7
        +	(p35)sub	n7=t[2],n7,1;;
        +	(p33)cmp.gtu	p34,p32=n7,t[2]	}
        +{ .mmi;	(p35)cmp.geu	p34,p32=n7,t[2];;
        +	.pred.rel	"mutex",p32,p34
        +	(p32)sub	n8=t[1],n8
        +	(p34)sub	n8=t[1],n8,1	};;
        +{ .mii;	(p32)cmp.gtu	p35,p33=n8,t[1]
        +	(p34)cmp.geu	p35,p33=n8,t[1];;
        +	.pred.rel	"mutex",p33,p35
        +	(p33)sub	a8=t[0],r0	}
        +{ .mmi;	(p35)sub	a8=t[0],r0,1;;
        +	(p33)cmp.gtu	p34,p32=a8,t[0]
        +	(p35)cmp.geu	p34,p32=a8,t[0]	};;
        +
        +// save the result, either tmp[num] or tmp[num]-np[num]
        +	.pred.rel	"mutex",p32,p34
        +{ .mmi;	(p32)st8	[rptr]=n1,8
        +	(p34)st8	[rptr]=t0,8
        +	add		r19=-4*16,prevsp};;
        +{ .mmb;	(p32)st8	[rptr]=n2,8
        +	(p34)st8	[rptr]=t[7],8
        +	(p5)br.cond.dpnt.few	.Ldone	};;
        +{ .mmb;	(p32)st8	[rptr]=n3,8
        +	(p34)st8	[rptr]=t[6],8
        +	(p7)br.cond.dpnt.few	.Ldone	};;
        +{ .mmb;	(p32)st8	[rptr]=n4,8
        +	(p34)st8	[rptr]=t[5],8
        +	(p9)br.cond.dpnt.few	.Ldone	};;
        +{ .mmb;	(p32)st8	[rptr]=n5,8
        +	(p34)st8	[rptr]=t[4],8
        +	(p11)br.cond.dpnt.few	.Ldone	};;
        +{ .mmb;	(p32)st8	[rptr]=n6,8
        +	(p34)st8	[rptr]=t[3],8
        +	(p13)br.cond.dpnt.few	.Ldone	};;
        +{ .mmb;	(p32)st8	[rptr]=n7,8
        +	(p34)st8	[rptr]=t[2],8
        +	(p15)br.cond.dpnt.few	.Ldone	};;
        +{ .mmb;	(p32)st8	[rptr]=n8,8
        +	(p34)st8	[rptr]=t[1],8
        +	nop.b		0		};;
        +.Ldone:						// epilogue
        +{ .mmi;	ldf.fill	f16=[r16],64
        +	ldf.fill	f17=[r17],64
        +	nop.i		0		}
        +{ .mmi;	ldf.fill	f18=[r18],64
        +	ldf.fill	f19=[r19],64
        +	mov		pr=prevpr,0x1ffff	};;
        +{ .mmi;	ldf.fill	f20=[r16]
        +	ldf.fill	f21=[r17]
        +	mov		ar.lc=prevlc	}
        +{ .mmi;	ldf.fill	f22=[r18]
        +	ldf.fill	f23=[r19]
        +	mov		ret0=1		}	// signal "handled"
        +{ .mib;	rum		1<<5
        +	.restore	sp
        +	mov		sp=prevsp
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_mul_mont_8#
        +
        +.type	copyright#,\@object
        +copyright:
        +stringz	"Montgomery multiplication for IA-64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$output=shift and open STDOUT,">$output";
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/ia64.S b/vendor/openssl/openssl/crypto/bn/asm/ia64.S
        new file mode 100644
        index 000000000..951abc53e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/ia64.S
        @@ -0,0 +1,1555 @@
        +.explicit
        +.text
        +.ident	"ia64.S, Version 2.1"
        +.ident	"IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
        +
        +//
        +// ====================================================================
        +// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +// project.
        +//
        +// Rights for redistribution and usage in source and binary forms are
        +// granted according to the OpenSSL license. Warranty of any kind is
        +// disclaimed.
        +// ====================================================================
        +//
        +// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is
        +// different from Itanium to this module viewpoint. Most notably, is it
        +// "wider" than Itanium? Can you experience loop scalability as
        +// discussed in commentary sections? Not really:-( Itanium2 has 6
        +// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to
        +// spin twice as fast, as I need 8 IALU ports. Amount of floating point
        +// ports is the same, i.e. 2, while I need 4. In other words, to this
        +// module Itanium2 remains effectively as "wide" as Itanium. Yet it's
        +// essentially different in respect to this module, and a re-tune was
        +// required. Well, because some intruction latencies has changed. Most
        +// noticeably those intensively used:
        +//
        +//			Itanium	Itanium2
        +//	ldf8		9	6		L2 hit
        +//	ld8		2	1		L1 hit
        +//	getf		2	5
        +//	xma[->getf]	7[+1]	4[+0]
        +//	add[->st8]	1[+1]	1[+0]
        +//
        +// What does it mean? You might ratiocinate that the original code
        +// should run just faster... Because sum of latencies is smaller...
        +// Wrong! Note that getf latency increased. This means that if a loop is
        +// scheduled for lower latency (as they were), then it will suffer from
        +// stall condition and the code will therefore turn anti-scalable, e.g.
        +// original bn_mul_words spun at 5*n or 2.5 times slower than expected
        +// on Itanium2! What to do? Reschedule loops for Itanium2? But then
        +// Itanium would exhibit anti-scalability. So I've chosen to reschedule
        +// for worst latency for every instruction aiming for best *all-round*
        +// performance.  
        +
        +// Q.	How much faster does it get?
        +// A.	Here is the output from 'openssl speed rsa dsa' for vanilla
        +//	0.9.6a compiled with gcc version 2.96 20000731 (Red Hat
        +//	Linux 7.1 2.96-81):
        +//
        +//	                  sign    verify    sign/s verify/s
        +//	rsa  512 bits   0.0036s   0.0003s    275.3   2999.2
        +//	rsa 1024 bits   0.0203s   0.0011s     49.3    894.1
        +//	rsa 2048 bits   0.1331s   0.0040s      7.5    250.9
        +//	rsa 4096 bits   0.9270s   0.0147s      1.1     68.1
        +//	                  sign    verify    sign/s verify/s
        +//	dsa  512 bits   0.0035s   0.0043s    288.3    234.8
        +//	dsa 1024 bits   0.0111s   0.0135s     90.0     74.2
        +//
        +//	And here is similar output but for this assembler
        +//	implementation:-)
        +//
        +//	                  sign    verify    sign/s verify/s
        +//	rsa  512 bits   0.0021s   0.0001s    549.4   9638.5
        +//	rsa 1024 bits   0.0055s   0.0002s    183.8   4481.1
        +//	rsa 2048 bits   0.0244s   0.0006s     41.4   1726.3
        +//	rsa 4096 bits   0.1295s   0.0018s      7.7    561.5
        +//	                  sign    verify    sign/s verify/s
        +//	dsa  512 bits   0.0012s   0.0013s    891.9    756.6
        +//	dsa 1024 bits   0.0023s   0.0028s    440.4    376.2
        +//	
        +//	Yes, you may argue that it's not fair comparison as it's
        +//	possible to craft the C implementation with BN_UMULT_HIGH
        +//	inline assembler macro. But of course! Here is the output
        +//	with the macro:
        +//
        +//	                  sign    verify    sign/s verify/s
        +//	rsa  512 bits   0.0020s   0.0002s    495.0   6561.0
        +//	rsa 1024 bits   0.0086s   0.0004s    116.2   2235.7
        +//	rsa 2048 bits   0.0519s   0.0015s     19.3    667.3
        +//	rsa 4096 bits   0.3464s   0.0053s      2.9    187.7
        +//	                  sign    verify    sign/s verify/s
        +//	dsa  512 bits   0.0016s   0.0020s    613.1    510.5
        +//	dsa 1024 bits   0.0045s   0.0054s    221.0    183.9
        +//
        +//	My code is still way faster, huh:-) And I believe that even
        +//	higher performance can be achieved. Note that as keys get
        +//	longer, performance gain is larger. Why? According to the
        +//	profiler there is another player in the field, namely
        +//	BN_from_montgomery consuming larger and larger portion of CPU
        +//	time as keysize decreases. I therefore consider putting effort
        +//	to assembler implementation of the following routine:
        +//
        +//	void bn_mul_add_mont (BN_ULONG *rp,BN_ULONG *np,int nl,BN_ULONG n0)
        +//	{
        +//	int      i,j;
        +//	BN_ULONG v;
        +//
        +//	for (i=0; i<nl; i++)
        +//		{
        +//		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
        +//		nrp++;
        +//		rp++;
        +//		if (((nrp[-1]+=v)&BN_MASK2) < v)
        +//			for (j=0; ((++nrp[j])&BN_MASK2) == 0; j++) ;
        +//		}
        +//	}
        +//
        +//	It might as well be beneficial to implement even combaX
        +//	variants, as it appears as it can literally unleash the
        +//	performance (see comment section to bn_mul_comba8 below).
        +//
        +//	And finally for your reference the output for 0.9.6a compiled
        +//	with SGIcc version 0.01.0-12 (keep in mind that for the moment
        +//	of this writing it's not possible to convince SGIcc to use
        +//	BN_UMULT_HIGH inline assembler macro, yet the code is fast,
        +//	i.e. for a compiler generated one:-):
        +//
        +//	                  sign    verify    sign/s verify/s
        +//	rsa  512 bits   0.0022s   0.0002s    452.7   5894.3
        +//	rsa 1024 bits   0.0097s   0.0005s    102.7   2002.9
        +//	rsa 2048 bits   0.0578s   0.0017s     17.3    600.2
        +//	rsa 4096 bits   0.3838s   0.0061s      2.6    164.5
        +//	                  sign    verify    sign/s verify/s
        +//	dsa  512 bits   0.0018s   0.0022s    547.3    459.6
        +//	dsa 1024 bits   0.0051s   0.0062s    196.6    161.3
        +//
        +//	Oh! Benchmarks were performed on 733MHz Lion-class Itanium
        +//	system running Redhat Linux 7.1 (very special thanks to Ray
        +//	McCaffity of Williams Communications for providing an account).
        +//
        +// Q.	What's the heck with 'rum 1<<5' at the end of every function?
        +// A.	Well, by clearing the "upper FP registers written" bit of the
        +//	User Mask I want to excuse the kernel from preserving upper
        +//	(f32-f128) FP register bank over process context switch, thus
        +//	minimizing bus bandwidth consumption during the switch (i.e.
        +//	after PKI opration completes and the program is off doing
        +//	something else like bulk symmetric encryption). Having said
        +//	this, I also want to point out that it might be good idea
        +//	to compile the whole toolkit (as well as majority of the
        +//	programs for that matter) with -mfixed-range=f32-f127 command
        +//	line option. No, it doesn't prevent the compiler from writing
        +//	to upper bank, but at least discourages to do so. If you don't
        +//	like the idea you have the option to compile the module with
        +//	-Drum=nop.m in command line.
        +//
        +
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +#define	ADDP	addp4
        +#else
        +#define	ADDP	add
        +#endif
        +
        +#if 1
        +//
        +// bn_[add|sub]_words routines.
        +//
        +// Loops are spinning in 2*(n+5) ticks on Itanuim (provided that the
        +// data reside in L1 cache, i.e. 2 ticks away). It's possible to
        +// compress the epilogue and get down to 2*n+6, but at the cost of
        +// scalability (the neat feature of this implementation is that it
        +// shall automagically spin in n+5 on "wider" IA-64 implementations:-)
        +// I consider that the epilogue is short enough as it is to trade tiny
        +// performance loss on Itanium for scalability.
        +//
        +// BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num)
        +//
        +.global	bn_add_words#
        +.proc	bn_add_words#
        +.align	64
        +.skip	32	// makes the loop body aligned at 64-byte boundary
        +bn_add_words:
        +	.prologue
        +	.save	ar.pfs,r2
        +{ .mii;	alloc		r2=ar.pfs,4,12,0,16
        +	cmp4.le		p6,p0=r35,r0	};;
        +{ .mfb;	mov		r8=r0			// return value
        +(p6)	br.ret.spnt.many	b0	};;
        +
        +{ .mib;	sub		r10=r35,r0,1
        +	.save	ar.lc,r3
        +	mov		r3=ar.lc
        +	brp.loop.imp	.L_bn_add_words_ctop,.L_bn_add_words_cend-16
        +					}
        +{ .mib;	ADDP		r14=0,r32		// rp
        +	.save	pr,r9
        +	mov		r9=pr		};;
        +	.body
        +{ .mii;	ADDP		r15=0,r33		// ap
        +	mov		ar.lc=r10
        +	mov		ar.ec=6		}
        +{ .mib;	ADDP		r16=0,r34		// bp
        +	mov		pr.rot=1<<16	};;
        +
        +.L_bn_add_words_ctop:
        +{ .mii;	(p16)	ld8		r32=[r16],8	  // b=*(bp++)
        +	(p18)	add		r39=r37,r34
        +	(p19)	cmp.ltu.unc	p56,p0=r40,r38	}
        +{ .mfb;	(p0)	nop.m		0x0
        +	(p0)	nop.f		0x0
        +	(p0)	nop.b		0x0		}
        +{ .mii;	(p16)	ld8		r35=[r15],8	  // a=*(ap++)
        +	(p58)	cmp.eq.or	p57,p0=-1,r41	  // (p20)
        +	(p58)	add		r41=1,r41	} // (p20)
        +{ .mfb;	(p21)	st8		[r14]=r42,8	  // *(rp++)=r
        +	(p0)	nop.f		0x0
        +	br.ctop.sptk	.L_bn_add_words_ctop	};;
        +.L_bn_add_words_cend:
        +
        +{ .mii;
        +(p59)	add		r8=1,r8		// return value
        +	mov		pr=r9,0x1ffff
        +	mov		ar.lc=r3	}
        +{ .mbb;	nop.b		0x0
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_add_words#
        +
        +//
        +// BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num)
        +//
        +.global	bn_sub_words#
        +.proc	bn_sub_words#
        +.align	64
        +.skip	32	// makes the loop body aligned at 64-byte boundary
        +bn_sub_words:
        +	.prologue
        +	.save	ar.pfs,r2
        +{ .mii;	alloc		r2=ar.pfs,4,12,0,16
        +	cmp4.le		p6,p0=r35,r0	};;
        +{ .mfb;	mov		r8=r0			// return value
        +(p6)	br.ret.spnt.many	b0	};;
        +
        +{ .mib;	sub		r10=r35,r0,1
        +	.save	ar.lc,r3
        +	mov		r3=ar.lc
        +	brp.loop.imp	.L_bn_sub_words_ctop,.L_bn_sub_words_cend-16
        +					}
        +{ .mib;	ADDP		r14=0,r32		// rp
        +	.save	pr,r9
        +	mov		r9=pr		};;
        +	.body
        +{ .mii;	ADDP		r15=0,r33		// ap
        +	mov		ar.lc=r10
        +	mov		ar.ec=6		}
        +{ .mib;	ADDP		r16=0,r34		// bp
        +	mov		pr.rot=1<<16	};;
        +
        +.L_bn_sub_words_ctop:
        +{ .mii;	(p16)	ld8		r32=[r16],8	  // b=*(bp++)
        +	(p18)	sub		r39=r37,r34
        +	(p19)	cmp.gtu.unc	p56,p0=r40,r38	}
        +{ .mfb;	(p0)	nop.m		0x0
        +	(p0)	nop.f		0x0
        +	(p0)	nop.b		0x0		}
        +{ .mii;	(p16)	ld8		r35=[r15],8	  // a=*(ap++)
        +	(p58)	cmp.eq.or	p57,p0=0,r41	  // (p20)
        +	(p58)	add		r41=-1,r41	} // (p20)
        +{ .mbb;	(p21)	st8		[r14]=r42,8	  // *(rp++)=r
        +	(p0)	nop.b		0x0
        +	br.ctop.sptk	.L_bn_sub_words_ctop	};;
        +.L_bn_sub_words_cend:
        +
        +{ .mii;
        +(p59)	add		r8=1,r8		// return value
        +	mov		pr=r9,0x1ffff
        +	mov		ar.lc=r3	}
        +{ .mbb;	nop.b		0x0
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_sub_words#
        +#endif
        +
        +#if 0
        +#define XMA_TEMPTATION
        +#endif
        +
        +#if 1
        +//
        +// BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
        +//
        +.global	bn_mul_words#
        +.proc	bn_mul_words#
        +.align	64
        +.skip	32	// makes the loop body aligned at 64-byte boundary
        +bn_mul_words:
        +	.prologue
        +	.save	ar.pfs,r2
        +#ifdef XMA_TEMPTATION
        +{ .mfi;	alloc		r2=ar.pfs,4,0,0,0	};;
        +#else
        +{ .mfi;	alloc		r2=ar.pfs,4,12,0,16	};;
        +#endif
        +{ .mib;	mov		r8=r0			// return value
        +	cmp4.le		p6,p0=r34,r0
        +(p6)	br.ret.spnt.many	b0		};;
        +
        +{ .mii;	sub	r10=r34,r0,1
        +	.save	ar.lc,r3
        +	mov	r3=ar.lc
        +	.save	pr,r9
        +	mov	r9=pr			};;
        +
        +	.body
        +{ .mib;	setf.sig	f8=r35	// w
        +	mov		pr.rot=0x800001<<16
        +			// ------^----- serves as (p50) at first (p27)
        +	brp.loop.imp	.L_bn_mul_words_ctop,.L_bn_mul_words_cend-16
        +					}
        +
        +#ifndef XMA_TEMPTATION
        +
        +{ .mmi;	ADDP		r14=0,r32	// rp
        +	ADDP		r15=0,r33	// ap
        +	mov		ar.lc=r10	}
        +{ .mmi;	mov		r40=0		// serves as r35 at first (p27)
        +	mov		ar.ec=13	};;
        +
        +// This loop spins in 2*(n+12) ticks. It's scheduled for data in Itanium
        +// L2 cache (i.e. 9 ticks away) as floating point load/store instructions
        +// bypass L1 cache and L2 latency is actually best-case scenario for
        +// ldf8. The loop is not scalable and shall run in 2*(n+12) even on
        +// "wider" IA-64 implementations. It's a trade-off here. n+24 loop
        +// would give us ~5% in *overall* performance improvement on "wider"
        +// IA-64, but would hurt Itanium for about same because of longer
        +// epilogue. As it's a matter of few percents in either case I've
        +// chosen to trade the scalability for development time (you can see
        +// this very instruction sequence in bn_mul_add_words loop which in
        +// turn is scalable).
        +.L_bn_mul_words_ctop:
        +{ .mfi;	(p25)	getf.sig	r36=f52			// low
        +	(p21)	xmpy.lu		f48=f37,f8
        +	(p28)	cmp.ltu		p54,p50=r41,r39	}
        +{ .mfi;	(p16)	ldf8		f32=[r15],8
        +	(p21)	xmpy.hu		f40=f37,f8
        +	(p0)	nop.i		0x0		};;
        +{ .mii;	(p25)	getf.sig	r32=f44			// high
        +	.pred.rel	"mutex",p50,p54
        +	(p50)	add		r40=r38,r35		// (p27)
        +	(p54)	add		r40=r38,r35,1	}	// (p27)
        +{ .mfb;	(p28)	st8		[r14]=r41,8
        +	(p0)	nop.f		0x0
        +	br.ctop.sptk	.L_bn_mul_words_ctop	};;
        +.L_bn_mul_words_cend:
        +
        +{ .mii;	nop.m		0x0
        +.pred.rel	"mutex",p51,p55
        +(p51)	add		r8=r36,r0
        +(p55)	add		r8=r36,r0,1	}
        +{ .mfb;	nop.m	0x0
        +	nop.f	0x0
        +	nop.b	0x0			}
        +
        +#else	// XMA_TEMPTATION
        +
        +	setf.sig	f37=r0	// serves as carry at (p18) tick
        +	mov		ar.lc=r10
        +	mov		ar.ec=5;;
        +
        +// Most of you examining this code very likely wonder why in the name
        +// of Intel the following loop is commented out? Indeed, it looks so
        +// neat that you find it hard to believe that it's something wrong
        +// with it, right? The catch is that every iteration depends on the
        +// result from previous one and the latter isn't available instantly.
        +// The loop therefore spins at the latency of xma minus 1, or in other
        +// words at 6*(n+4) ticks:-( Compare to the "production" loop above
        +// that runs in 2*(n+11) where the low latency problem is worked around
        +// by moving the dependency to one-tick latent interger ALU. Note that
        +// "distance" between ldf8 and xma is not latency of ldf8, but the
        +// *difference* between xma and ldf8 latencies.
        +.L_bn_mul_words_ctop:
        +{ .mfi;	(p16)	ldf8		f32=[r33],8
        +	(p18)	xma.hu		f38=f34,f8,f39	}
        +{ .mfb;	(p20)	stf8		[r32]=f37,8
        +	(p18)	xma.lu		f35=f34,f8,f39
        +	br.ctop.sptk	.L_bn_mul_words_ctop	};;
        +.L_bn_mul_words_cend:
        +
        +	getf.sig	r8=f41		// the return value
        +
        +#endif	// XMA_TEMPTATION
        +
        +{ .mii;	nop.m		0x0
        +	mov		pr=r9,0x1ffff
        +	mov		ar.lc=r3	}
        +{ .mfb;	rum		1<<5		// clear um.mfh
        +	nop.f		0x0
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_mul_words#
        +#endif
        +
        +#if 1
        +//
        +// BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
        +//
        +.global	bn_mul_add_words#
        +.proc	bn_mul_add_words#
        +.align	64
        +.skip	48	// makes the loop body aligned at 64-byte boundary
        +bn_mul_add_words:
        +	.prologue
        +	.save	ar.pfs,r2
        +{ .mmi;	alloc		r2=ar.pfs,4,4,0,8
        +	cmp4.le		p6,p0=r34,r0
        +	.save	ar.lc,r3
        +	mov		r3=ar.lc	};;
        +{ .mib;	mov		r8=r0		// return value
        +	sub		r10=r34,r0,1
        +(p6)	br.ret.spnt.many	b0	};;
        +
        +{ .mib;	setf.sig	f8=r35		// w
        +	.save	pr,r9
        +	mov		r9=pr
        +	brp.loop.imp	.L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16
        +					}
        +	.body
        +{ .mmi;	ADDP		r14=0,r32	// rp
        +	ADDP		r15=0,r33	// ap
        +	mov		ar.lc=r10	}
        +{ .mii;	ADDP		r16=0,r32	// rp copy
        +	mov		pr.rot=0x2001<<16
        +			// ------^----- serves as (p40) at first (p27)
        +	mov		ar.ec=11	};;
        +
        +// This loop spins in 3*(n+10) ticks on Itanium and in 2*(n+10) on
        +// Itanium 2. Yes, unlike previous versions it scales:-) Previous
        +// version was peforming *all* additions in IALU and was starving
        +// for those even on Itanium 2. In this version one addition is
        +// moved to FPU and is folded with multiplication. This is at cost
        +// of propogating the result from previous call to this subroutine
        +// to L2 cache... In other words negligible even for shorter keys.
        +// *Overall* performance improvement [over previous version] varies
        +// from 11 to 22 percent depending on key length.
        +.L_bn_mul_add_words_ctop:
        +.pred.rel	"mutex",p40,p42
        +{ .mfi;	(p23)	getf.sig	r36=f45			// low
        +	(p20)	xma.lu		f42=f36,f8,f50		// low
        +	(p40)	add		r39=r39,r35	}	// (p27)
        +{ .mfi;	(p16)	ldf8		f32=[r15],8		// *(ap++)
        +	(p20)	xma.hu		f36=f36,f8,f50		// high
        +	(p42)	add		r39=r39,r35,1	};;	// (p27)
        +{ .mmi;	(p24)	getf.sig	r32=f40			// high
        +	(p16)	ldf8		f46=[r16],8		// *(rp1++)
        +	(p40)	cmp.ltu		p41,p39=r39,r35	}	// (p27)
        +{ .mib;	(p26)	st8		[r14]=r39,8		// *(rp2++)
        +	(p42)	cmp.leu		p41,p39=r39,r35		// (p27)
        +	br.ctop.sptk	.L_bn_mul_add_words_ctop};;
        +.L_bn_mul_add_words_cend:
        +
        +{ .mmi;	.pred.rel	"mutex",p40,p42
        +(p40)	add		r8=r35,r0
        +(p42)	add		r8=r35,r0,1
        +	mov		pr=r9,0x1ffff	}
        +{ .mib;	rum		1<<5		// clear um.mfh
        +	mov		ar.lc=r3
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_mul_add_words#
        +#endif
        +
        +#if 1
        +//
        +// void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
        +//
        +.global	bn_sqr_words#
        +.proc	bn_sqr_words#
        +.align	64
        +.skip	32	// makes the loop body aligned at 64-byte boundary 
        +bn_sqr_words:
        +	.prologue
        +	.save	ar.pfs,r2
        +{ .mii;	alloc		r2=ar.pfs,3,0,0,0
        +	sxt4		r34=r34		};;
        +{ .mii;	cmp.le		p6,p0=r34,r0
        +	mov		r8=r0		}	// return value
        +{ .mfb;	ADDP		r32=0,r32
        +	nop.f		0x0
        +(p6)	br.ret.spnt.many	b0	};;
        +
        +{ .mii;	sub	r10=r34,r0,1
        +	.save	ar.lc,r3
        +	mov	r3=ar.lc
        +	.save	pr,r9
        +	mov	r9=pr			};;
        +
        +	.body
        +{ .mib;	ADDP		r33=0,r33
        +	mov		pr.rot=1<<16
        +	brp.loop.imp	.L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16
        +					}
        +{ .mii;	add		r34=8,r32
        +	mov		ar.lc=r10
        +	mov		ar.ec=18	};;
        +
        +// 2*(n+17) on Itanium, (n+17) on "wider" IA-64 implementations. It's
        +// possible to compress the epilogue (I'm getting tired to write this
        +// comment over and over) and get down to 2*n+16 at the cost of
        +// scalability. The decision will very likely be reconsidered after the
        +// benchmark program is profiled. I.e. if perfomance gain on Itanium
        +// will appear larger than loss on "wider" IA-64, then the loop should
        +// be explicitely split and the epilogue compressed.
        +.L_bn_sqr_words_ctop:
        +{ .mfi;	(p16)	ldf8		f32=[r33],8
        +	(p25)	xmpy.lu		f42=f41,f41
        +	(p0)	nop.i		0x0		}
        +{ .mib;	(p33)	stf8		[r32]=f50,16
        +	(p0)	nop.i		0x0
        +	(p0)	nop.b		0x0		}
        +{ .mfi;	(p0)	nop.m		0x0
        +	(p25)	xmpy.hu		f52=f41,f41
        +	(p0)	nop.i		0x0		}
        +{ .mib;	(p33)	stf8		[r34]=f60,16
        +	(p0)	nop.i		0x0
        +	br.ctop.sptk	.L_bn_sqr_words_ctop	};;
        +.L_bn_sqr_words_cend:
        +
        +{ .mii;	nop.m		0x0
        +	mov		pr=r9,0x1ffff
        +	mov		ar.lc=r3	}
        +{ .mfb;	rum		1<<5		// clear um.mfh
        +	nop.f		0x0
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_sqr_words#
        +#endif
        +
        +#if 1
        +// Apparently we win nothing by implementing special bn_sqr_comba8.
        +// Yes, it is possible to reduce the number of multiplications by
        +// almost factor of two, but then the amount of additions would
        +// increase by factor of two (as we would have to perform those
        +// otherwise performed by xma ourselves). Normally we would trade
        +// anyway as multiplications are way more expensive, but not this
        +// time... Multiplication kernel is fully pipelined and as we drain
        +// one 128-bit multiplication result per clock cycle multiplications
        +// are effectively as inexpensive as additions. Special implementation
        +// might become of interest for "wider" IA-64 implementation as you'll
        +// be able to get through the multiplication phase faster (there won't
        +// be any stall issues as discussed in the commentary section below and
        +// you therefore will be able to employ all 4 FP units)... But these
        +// Itanium days it's simply too hard to justify the effort so I just
        +// drop down to bn_mul_comba8 code:-)
        +//
        +// void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
        +//
        +.global	bn_sqr_comba8#
        +.proc	bn_sqr_comba8#
        +.align	64
        +bn_sqr_comba8:
        +	.prologue
        +	.save	ar.pfs,r2
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +{ .mii;	alloc	r2=ar.pfs,2,1,0,0
        +	addp4	r33=0,r33
        +	addp4	r32=0,r32		};;
        +{ .mii;
        +#else
        +{ .mii;	alloc	r2=ar.pfs,2,1,0,0
        +#endif
        +	mov	r34=r33
        +	add	r14=8,r33		};;
        +	.body
        +{ .mii;	add	r17=8,r34
        +	add	r15=16,r33
        +	add	r18=16,r34		}
        +{ .mfb;	add	r16=24,r33
        +	br	.L_cheat_entry_point8	};;
        +.endp	bn_sqr_comba8#
        +#endif
        +
        +#if 1
        +// I've estimated this routine to run in ~120 ticks, but in reality
        +// (i.e. according to ar.itc) it takes ~160 ticks. Are those extra
        +// cycles consumed for instructions fetch? Or did I misinterpret some
        +// clause in Itanium µ-architecture manual? Comments are welcomed and
        +// highly appreciated.
        +//
        +// On Itanium 2 it takes ~190 ticks. This is because of stalls on
        +// result from getf.sig. I do nothing about it at this point for
        +// reasons depicted below.
        +//
        +// However! It should be noted that even 160 ticks is darn good result
        +// as it's over 10 (yes, ten, spelled as t-e-n) times faster than the
        +// C version (compiled with gcc with inline assembler). I really
        +// kicked compiler's butt here, didn't I? Yeah! This brings us to the
        +// following statement. It's damn shame that this routine isn't called
        +// very often nowadays! According to the profiler most CPU time is
        +// consumed by bn_mul_add_words called from BN_from_montgomery. In
        +// order to estimate what we're missing, I've compared the performance
        +// of this routine against "traditional" implementation, i.e. against
        +// following routine:
        +//
        +// void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +// {	r[ 8]=bn_mul_words(    &(r[0]),a,8,b[0]);
        +//	r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
        +//	r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
        +//	r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
        +//	r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
        +//	r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
        +//	r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
        +//	r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
        +// }
        +//
        +// The one below is over 8 times faster than the one above:-( Even
        +// more reasons to "combafy" bn_mul_add_mont...
        +//
        +// And yes, this routine really made me wish there were an optimizing
        +// assembler! It also feels like it deserves a dedication.
        +//
        +//	To my wife for being there and to my kids...
        +//
        +// void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +//
        +#define	carry1	r14
        +#define	carry2	r15
        +#define	carry3	r34
        +.global	bn_mul_comba8#
        +.proc	bn_mul_comba8#
        +.align	64
        +bn_mul_comba8:
        +	.prologue
        +	.save	ar.pfs,r2
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +{ .mii;	alloc	r2=ar.pfs,3,0,0,0
        +	addp4	r33=0,r33
        +	addp4	r34=0,r34		};;
        +{ .mii;	addp4	r32=0,r32
        +#else
        +{ .mii;	alloc   r2=ar.pfs,3,0,0,0
        +#endif
        +	add	r14=8,r33
        +	add	r17=8,r34		}
        +	.body
        +{ .mii;	add	r15=16,r33
        +	add	r18=16,r34
        +	add	r16=24,r33		}
        +.L_cheat_entry_point8:
        +{ .mmi;	add	r19=24,r34
        +
        +	ldf8	f32=[r33],32		};;
        +
        +{ .mmi;	ldf8	f120=[r34],32
        +	ldf8	f121=[r17],32		}
        +{ .mmi;	ldf8	f122=[r18],32
        +	ldf8	f123=[r19],32		};;
        +{ .mmi;	ldf8	f124=[r34]
        +	ldf8	f125=[r17]		}
        +{ .mmi;	ldf8	f126=[r18]
        +	ldf8	f127=[r19]		}
        +
        +{ .mmi;	ldf8	f33=[r14],32
        +	ldf8	f34=[r15],32		}
        +{ .mmi;	ldf8	f35=[r16],32;;
        +	ldf8	f36=[r33]		}
        +{ .mmi;	ldf8	f37=[r14]
        +	ldf8	f38=[r15]		}
        +{ .mfi;	ldf8	f39=[r16]
        +// -------\ Entering multiplier's heaven /-------
        +// ------------\                    /------------
        +// -----------------\          /-----------------
        +// ----------------------\/----------------------
        +		xma.hu	f41=f32,f120,f0		}
        +{ .mfi;		xma.lu	f40=f32,f120,f0		};; // (*)
        +{ .mfi;		xma.hu	f51=f32,f121,f0		}
        +{ .mfi;		xma.lu	f50=f32,f121,f0		};;
        +{ .mfi;		xma.hu	f61=f32,f122,f0		}
        +{ .mfi;		xma.lu	f60=f32,f122,f0		};;
        +{ .mfi;		xma.hu	f71=f32,f123,f0		}
        +{ .mfi;		xma.lu	f70=f32,f123,f0		};;
        +{ .mfi;		xma.hu	f81=f32,f124,f0		}
        +{ .mfi;		xma.lu	f80=f32,f124,f0		};;
        +{ .mfi;		xma.hu	f91=f32,f125,f0		}
        +{ .mfi;		xma.lu	f90=f32,f125,f0		};;
        +{ .mfi;		xma.hu	f101=f32,f126,f0	}
        +{ .mfi;		xma.lu	f100=f32,f126,f0	};;
        +{ .mfi;		xma.hu	f111=f32,f127,f0	}
        +{ .mfi;		xma.lu	f110=f32,f127,f0	};;//
        +// (*)	You can argue that splitting at every second bundle would
        +//	prevent "wider" IA-64 implementations from achieving the peak
        +//	performance. Well, not really... The catch is that if you
        +//	intend to keep 4 FP units busy by splitting at every fourth
        +//	bundle and thus perform these 16 multiplications in 4 ticks,
        +//	the first bundle *below* would stall because the result from
        +//	the first xma bundle *above* won't be available for another 3
        +//	ticks (if not more, being an optimist, I assume that "wider"
        +//	implementation will have same latency:-). This stall will hold
        +//	you back and the performance would be as if every second bundle
        +//	were split *anyway*...
        +{ .mfi;	getf.sig	r16=f40
        +		xma.hu	f42=f33,f120,f41
        +	add		r33=8,r32		}
        +{ .mfi;		xma.lu	f41=f33,f120,f41	};;
        +{ .mfi;	getf.sig	r24=f50
        +		xma.hu	f52=f33,f121,f51	}
        +{ .mfi;		xma.lu	f51=f33,f121,f51	};;
        +{ .mfi;	st8		[r32]=r16,16
        +		xma.hu	f62=f33,f122,f61	}
        +{ .mfi;		xma.lu	f61=f33,f122,f61	};;
        +{ .mfi;		xma.hu	f72=f33,f123,f71	}
        +{ .mfi;		xma.lu	f71=f33,f123,f71	};;
        +{ .mfi;		xma.hu	f82=f33,f124,f81	}
        +{ .mfi;		xma.lu	f81=f33,f124,f81	};;
        +{ .mfi;		xma.hu	f92=f33,f125,f91	}
        +{ .mfi;		xma.lu	f91=f33,f125,f91	};;
        +{ .mfi;		xma.hu	f102=f33,f126,f101	}
        +{ .mfi;		xma.lu	f101=f33,f126,f101	};;
        +{ .mfi;		xma.hu	f112=f33,f127,f111	}
        +{ .mfi;		xma.lu	f111=f33,f127,f111	};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r25=f41
        +		xma.hu	f43=f34,f120,f42	}
        +{ .mfi;		xma.lu	f42=f34,f120,f42	};;
        +{ .mfi;	getf.sig	r16=f60
        +		xma.hu	f53=f34,f121,f52	}
        +{ .mfi;		xma.lu	f52=f34,f121,f52	};;
        +{ .mfi;	getf.sig	r17=f51
        +		xma.hu	f63=f34,f122,f62
        +	add		r25=r25,r24		}
        +{ .mfi;		xma.lu	f62=f34,f122,f62
        +	mov		carry1=0		};;
        +{ .mfi;	cmp.ltu		p6,p0=r25,r24
        +		xma.hu	f73=f34,f123,f72	}
        +{ .mfi;		xma.lu	f72=f34,f123,f72	};;
        +{ .mfi;	st8		[r33]=r25,16
        +		xma.hu	f83=f34,f124,f82
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;		xma.lu	f82=f34,f124,f82	};;
        +{ .mfi;		xma.hu	f93=f34,f125,f92	}
        +{ .mfi;		xma.lu	f92=f34,f125,f92	};;
        +{ .mfi;		xma.hu	f103=f34,f126,f102	}
        +{ .mfi;		xma.lu	f102=f34,f126,f102	};;
        +{ .mfi;		xma.hu	f113=f34,f127,f112	}
        +{ .mfi;		xma.lu	f112=f34,f127,f112	};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r18=f42
        +		xma.hu	f44=f35,f120,f43
        +	add		r17=r17,r16		}
        +{ .mfi;		xma.lu	f43=f35,f120,f43	};;
        +{ .mfi;	getf.sig	r24=f70
        +		xma.hu	f54=f35,f121,f53	}
        +{ .mfi;	mov		carry2=0
        +		xma.lu	f53=f35,f121,f53	};;
        +{ .mfi;	getf.sig	r25=f61
        +		xma.hu	f64=f35,f122,f63
        +	cmp.ltu		p7,p0=r17,r16		}
        +{ .mfi;	add		r18=r18,r17
        +		xma.lu	f63=f35,f122,f63	};;
        +{ .mfi;	getf.sig	r26=f52
        +		xma.hu	f74=f35,f123,f73
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r18,r17
        +		xma.lu	f73=f35,f123,f73
        +	add		r18=r18,carry1		};;
        +{ .mfi;
        +		xma.hu	f84=f35,f124,f83
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r18,carry1
        +		xma.lu	f83=f35,f124,f83	};;
        +{ .mfi;	st8		[r32]=r18,16
        +		xma.hu	f94=f35,f125,f93
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;		xma.lu	f93=f35,f125,f93	};;
        +{ .mfi;		xma.hu	f104=f35,f126,f103	}
        +{ .mfi;		xma.lu	f103=f35,f126,f103	};;
        +{ .mfi;		xma.hu	f114=f35,f127,f113	}
        +{ .mfi;	mov		carry1=0
        +		xma.lu	f113=f35,f127,f113
        +	add		r25=r25,r24		};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r27=f43
        +		xma.hu	f45=f36,f120,f44
        +	cmp.ltu		p6,p0=r25,r24		}
        +{ .mfi;		xma.lu	f44=f36,f120,f44	
        +	add		r26=r26,r25		};;
        +{ .mfi;	getf.sig	r16=f80
        +		xma.hu	f55=f36,f121,f54
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;		xma.lu	f54=f36,f121,f54	};;
        +{ .mfi;	getf.sig	r17=f71
        +		xma.hu	f65=f36,f122,f64
        +	cmp.ltu		p6,p0=r26,r25		}
        +{ .mfi;		xma.lu	f64=f36,f122,f64
        +	add		r27=r27,r26		};;
        +{ .mfi;	getf.sig	r18=f62
        +		xma.hu	f75=f36,f123,f74
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	cmp.ltu		p6,p0=r27,r26
        +		xma.lu	f74=f36,f123,f74
        +	add		r27=r27,carry2		};;
        +{ .mfi;	getf.sig	r19=f53
        +		xma.hu	f85=f36,f124,f84
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;		xma.lu	f84=f36,f124,f84
        +	cmp.ltu		p6,p0=r27,carry2	};;
        +{ .mfi;	st8		[r33]=r27,16
        +		xma.hu	f95=f36,f125,f94
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;		xma.lu	f94=f36,f125,f94	};;
        +{ .mfi;		xma.hu	f105=f36,f126,f104	}
        +{ .mfi;	mov		carry2=0
        +		xma.lu	f104=f36,f126,f104
        +	add		r17=r17,r16		};;
        +{ .mfi;		xma.hu	f115=f36,f127,f114
        +	cmp.ltu		p7,p0=r17,r16		}
        +{ .mfi;		xma.lu	f114=f36,f127,f114
        +	add		r18=r18,r17		};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r20=f44
        +		xma.hu	f46=f37,f120,f45
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r18,r17
        +		xma.lu	f45=f37,f120,f45
        +	add		r19=r19,r18		};;
        +{ .mfi;	getf.sig	r24=f90
        +		xma.hu	f56=f37,f121,f55	}
        +{ .mfi;		xma.lu	f55=f37,f121,f55	};;
        +{ .mfi;	getf.sig	r25=f81
        +		xma.hu	f66=f37,f122,f65
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r19,r18
        +		xma.lu	f65=f37,f122,f65
        +	add		r20=r20,r19		};;
        +{ .mfi;	getf.sig	r26=f72
        +		xma.hu	f76=f37,f123,f75
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r20,r19
        +		xma.lu	f75=f37,f123,f75
        +	add		r20=r20,carry1		};;
        +{ .mfi;	getf.sig	r27=f63
        +		xma.hu	f86=f37,f124,f85
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;		xma.lu	f85=f37,f124,f85
        +	cmp.ltu		p7,p0=r20,carry1	};;
        +{ .mfi;	getf.sig	r28=f54
        +		xma.hu	f96=f37,f125,f95
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	st8		[r32]=r20,16
        +		xma.lu	f95=f37,f125,f95	};;
        +{ .mfi;		xma.hu	f106=f37,f126,f105	}
        +{ .mfi;	mov		carry1=0
        +		xma.lu	f105=f37,f126,f105
        +	add		r25=r25,r24		};;
        +{ .mfi;		xma.hu	f116=f37,f127,f115
        +	cmp.ltu		p6,p0=r25,r24		}
        +{ .mfi;		xma.lu	f115=f37,f127,f115
        +	add		r26=r26,r25		};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r29=f45
        +		xma.hu	f47=f38,f120,f46
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	cmp.ltu		p6,p0=r26,r25
        +		xma.lu	f46=f38,f120,f46
        +	add		r27=r27,r26		};;
        +{ .mfi;	getf.sig	r16=f100
        +		xma.hu	f57=f38,f121,f56
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	cmp.ltu		p6,p0=r27,r26
        +		xma.lu	f56=f38,f121,f56
        +	add		r28=r28,r27		};;
        +{ .mfi;	getf.sig	r17=f91
        +		xma.hu	f67=f38,f122,f66
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	cmp.ltu		p6,p0=r28,r27
        +		xma.lu	f66=f38,f122,f66
        +	add		r29=r29,r28		};;
        +{ .mfi;	getf.sig	r18=f82
        +		xma.hu	f77=f38,f123,f76
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	cmp.ltu		p6,p0=r29,r28
        +		xma.lu	f76=f38,f123,f76
        +	add		r29=r29,carry2		};;
        +{ .mfi;	getf.sig	r19=f73
        +		xma.hu	f87=f38,f124,f86
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;		xma.lu	f86=f38,f124,f86
        +	cmp.ltu		p6,p0=r29,carry2	};;
        +{ .mfi;	getf.sig	r20=f64
        +		xma.hu	f97=f38,f125,f96
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	st8		[r33]=r29,16
        +		xma.lu	f96=f38,f125,f96	};;
        +{ .mfi;	getf.sig	r21=f55
        +		xma.hu	f107=f38,f126,f106	}
        +{ .mfi;	mov		carry2=0
        +		xma.lu	f106=f38,f126,f106
        +	add		r17=r17,r16		};;
        +{ .mfi;		xma.hu	f117=f38,f127,f116
        +	cmp.ltu		p7,p0=r17,r16		}
        +{ .mfi;		xma.lu	f116=f38,f127,f116
        +	add		r18=r18,r17		};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r22=f46
        +		xma.hu	f48=f39,f120,f47
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r18,r17
        +		xma.lu	f47=f39,f120,f47
        +	add		r19=r19,r18		};;
        +{ .mfi;	getf.sig	r24=f110
        +		xma.hu	f58=f39,f121,f57
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r19,r18
        +		xma.lu	f57=f39,f121,f57
        +	add		r20=r20,r19		};;
        +{ .mfi;	getf.sig	r25=f101
        +		xma.hu	f68=f39,f122,f67
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r20,r19
        +		xma.lu	f67=f39,f122,f67
        +	add		r21=r21,r20		};;
        +{ .mfi;	getf.sig	r26=f92
        +		xma.hu	f78=f39,f123,f77
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r21,r20
        +		xma.lu	f77=f39,f123,f77
        +	add		r22=r22,r21		};;
        +{ .mfi;	getf.sig	r27=f83
        +		xma.hu	f88=f39,f124,f87
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	cmp.ltu		p7,p0=r22,r21
        +		xma.lu	f87=f39,f124,f87
        +	add		r22=r22,carry1		};;
        +{ .mfi;	getf.sig	r28=f74
        +		xma.hu	f98=f39,f125,f97
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;		xma.lu	f97=f39,f125,f97
        +	cmp.ltu		p7,p0=r22,carry1	};;
        +{ .mfi;	getf.sig	r29=f65
        +		xma.hu	f108=f39,f126,f107
        +(p7)	add		carry2=1,carry2		}
        +{ .mfi;	st8		[r32]=r22,16
        +		xma.lu	f107=f39,f126,f107	};;
        +{ .mfi;	getf.sig	r30=f56
        +		xma.hu	f118=f39,f127,f117	}
        +{ .mfi;		xma.lu	f117=f39,f127,f117	};;//
        +//-------------------------------------------------//
        +// Leaving muliplier's heaven... Quite a ride, huh?
        +
        +{ .mii;	getf.sig	r31=f47
        +	add		r25=r25,r24
        +	mov		carry1=0		};;
        +{ .mii;		getf.sig	r16=f111
        +	cmp.ltu		p6,p0=r25,r24
        +	add		r26=r26,r25		};;
        +{ .mfb;		getf.sig	r17=f102	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,r25
        +	add		r27=r27,r26		};;
        +{ .mfb;	nop.m	0x0				}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r27,r26
        +	add		r28=r28,r27		};;
        +{ .mii;		getf.sig	r18=f93
        +		add		r17=r17,r16
        +		mov		carry3=0	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r28,r27
        +	add		r29=r29,r28		};;
        +{ .mii;		getf.sig	r19=f84
        +		cmp.ltu		p7,p0=r17,r16	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r29,r28
        +	add		r30=r30,r29		};;
        +{ .mii;		getf.sig	r20=f75
        +		add		r18=r18,r17	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r30,r29
        +	add		r31=r31,r30		};;
        +{ .mfb;		getf.sig	r21=f66		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r18,r17
        +		add		r19=r19,r18	}
        +{ .mfb;	nop.m	0x0				}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r31,r30
        +	add		r31=r31,carry2		};;
        +{ .mfb;		getf.sig	r22=f57		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r19,r18
        +		add		r20=r20,r19	}
        +{ .mfb;	nop.m	0x0				}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r31,carry2	};;
        +{ .mfb;		getf.sig	r23=f48		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r20,r19
        +		add		r21=r21,r20	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1		}
        +{ .mfb;	st8		[r33]=r31,16		};;
        +
        +{ .mfb;	getf.sig	r24=f112		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r21,r20
        +		add		r22=r22,r21	};;
        +{ .mfb;	getf.sig	r25=f103		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r22,r21
        +		add		r23=r23,r22	};;
        +{ .mfb;	getf.sig	r26=f94			}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r23,r22
        +		add		r23=r23,carry1	};;
        +{ .mfb;	getf.sig	r27=f85			}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p8=r23,carry1};;
        +{ .mii;	getf.sig	r28=f76
        +	add		r25=r25,r24
        +	mov		carry1=0		}
        +{ .mii;		st8		[r32]=r23,16
        +	(p7)	add		carry2=1,carry3
        +	(p8)	add		carry2=0,carry3	};;
        +
        +{ .mfb;	nop.m	0x0				}
        +{ .mii;	getf.sig	r29=f67
        +	cmp.ltu		p6,p0=r25,r24
        +	add		r26=r26,r25		};;
        +{ .mfb;	getf.sig	r30=f58			}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,r25
        +	add		r27=r27,r26		};;
        +{ .mfb;		getf.sig	r16=f113	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r27,r26
        +	add		r28=r28,r27		};;
        +{ .mfb;		getf.sig	r17=f104	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r28,r27
        +	add		r29=r29,r28		};;
        +{ .mfb;		getf.sig	r18=f95		}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r29,r28
        +	add		r30=r30,r29		};;
        +{ .mii;		getf.sig	r19=f86
        +		add		r17=r17,r16
        +		mov		carry3=0	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r30,r29
        +	add		r30=r30,carry2		};;
        +{ .mii;		getf.sig	r20=f77
        +		cmp.ltu		p7,p0=r17,r16
        +		add		r18=r18,r17	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r30,carry2	};;
        +{ .mfb;		getf.sig	r21=f68		}
        +{ .mii;	st8		[r33]=r30,16
        +(p6)	add		carry1=1,carry1		};;
        +
        +{ .mfb;	getf.sig	r24=f114		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r18,r17
        +		add		r19=r19,r18	};;
        +{ .mfb;	getf.sig	r25=f105		}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r19,r18
        +		add		r20=r20,r19	};;
        +{ .mfb;	getf.sig	r26=f96			}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r20,r19
        +		add		r21=r21,r20	};;
        +{ .mfb;	getf.sig	r27=f87			}
        +{ .mii;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p0=r21,r20
        +		add		r21=r21,carry1	};;
        +{ .mib;	getf.sig	r28=f78			
        +	add		r25=r25,r24		}
        +{ .mib;	(p7)	add		carry3=1,carry3
        +		cmp.ltu		p7,p8=r21,carry1};;
        +{ .mii;		st8		[r32]=r21,16
        +	(p7)	add		carry2=1,carry3
        +	(p8)	add		carry2=0,carry3	}
        +
        +{ .mii;	mov		carry1=0
        +	cmp.ltu		p6,p0=r25,r24
        +	add		r26=r26,r25		};;
        +{ .mfb;		getf.sig	r16=f115	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,r25
        +	add		r27=r27,r26		};;
        +{ .mfb;		getf.sig	r17=f106	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r27,r26
        +	add		r28=r28,r27		};;
        +{ .mfb;		getf.sig	r18=f97		}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r28,r27
        +	add		r28=r28,carry2		};;
        +{ .mib;		getf.sig	r19=f88
        +		add		r17=r17,r16	}
        +{ .mib;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r28,carry2	};;
        +{ .mii;	st8		[r33]=r28,16
        +(p6)	add		carry1=1,carry1		}
        +
        +{ .mii;		mov		carry2=0
        +		cmp.ltu		p7,p0=r17,r16
        +		add		r18=r18,r17	};;
        +{ .mfb;	getf.sig	r24=f116		}
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r18,r17
        +		add		r19=r19,r18	};;
        +{ .mfb;	getf.sig	r25=f107		}
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r19,r18
        +		add		r19=r19,carry1	};;
        +{ .mfb;	getf.sig	r26=f98			}
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r19,carry1};;
        +{ .mii;		st8		[r32]=r19,16
        +	(p7)	add		carry2=1,carry2	}
        +
        +{ .mfb;	add		r25=r25,r24		};;
        +
        +{ .mfb;		getf.sig	r16=f117	}
        +{ .mii;	mov		carry1=0
        +	cmp.ltu		p6,p0=r25,r24
        +	add		r26=r26,r25		};;
        +{ .mfb;		getf.sig	r17=f108	}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,r25
        +	add		r26=r26,carry2		};;
        +{ .mfb;	nop.m	0x0				}
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,carry2	};;
        +{ .mii;	st8		[r33]=r26,16
        +(p6)	add		carry1=1,carry1		}
        +
        +{ .mfb;		add		r17=r17,r16	};;
        +{ .mfb;	getf.sig	r24=f118		}
        +{ .mii;		mov		carry2=0
        +		cmp.ltu		p7,p0=r17,r16
        +		add		r17=r17,carry1	};;
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r17,carry1};;
        +{ .mii;		st8		[r32]=r17
        +	(p7)	add		carry2=1,carry2	};;
        +{ .mfb;	add		r24=r24,carry2		};;
        +{ .mib;	st8		[r33]=r24		}
        +
        +{ .mib;	rum		1<<5		// clear um.mfh
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_mul_comba8#
        +#undef	carry3
        +#undef	carry2
        +#undef	carry1
        +#endif
        +
        +#if 1
        +// It's possible to make it faster (see comment to bn_sqr_comba8), but
        +// I reckon it doesn't worth the effort. Basically because the routine
        +// (actually both of them) practically never called... So I just play
        +// same trick as with bn_sqr_comba8.
        +//
        +// void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
        +//
        +.global	bn_sqr_comba4#
        +.proc	bn_sqr_comba4#
        +.align	64
        +bn_sqr_comba4:
        +	.prologue
        +	.save	ar.pfs,r2
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +{ .mii;	alloc   r2=ar.pfs,2,1,0,0
        +	addp4	r32=0,r32
        +	addp4	r33=0,r33		};;
        +{ .mii;
        +#else
        +{ .mii;	alloc	r2=ar.pfs,2,1,0,0
        +#endif
        +	mov	r34=r33
        +	add	r14=8,r33		};;
        +	.body
        +{ .mii;	add	r17=8,r34
        +	add	r15=16,r33
        +	add	r18=16,r34		}
        +{ .mfb;	add	r16=24,r33
        +	br	.L_cheat_entry_point4	};;
        +.endp	bn_sqr_comba4#
        +#endif
        +
        +#if 1
        +// Runs in ~115 cycles and ~4.5 times faster than C. Well, whatever...
        +//
        +// void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +//
        +#define	carry1	r14
        +#define	carry2	r15
        +.global	bn_mul_comba4#
        +.proc	bn_mul_comba4#
        +.align	64
        +bn_mul_comba4:
        +	.prologue
        +	.save	ar.pfs,r2
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +{ .mii;	alloc   r2=ar.pfs,3,0,0,0
        +	addp4	r33=0,r33
        +	addp4	r34=0,r34		};;
        +{ .mii;	addp4	r32=0,r32
        +#else
        +{ .mii;	alloc	r2=ar.pfs,3,0,0,0
        +#endif
        +	add	r14=8,r33
        +	add	r17=8,r34		}
        +	.body
        +{ .mii;	add	r15=16,r33
        +	add	r18=16,r34
        +	add	r16=24,r33		};;
        +.L_cheat_entry_point4:
        +{ .mmi;	add	r19=24,r34
        +
        +	ldf8	f32=[r33]		}
        +
        +{ .mmi;	ldf8	f120=[r34]
        +	ldf8	f121=[r17]		};;
        +{ .mmi;	ldf8	f122=[r18]
        +	ldf8	f123=[r19]		}
        +
        +{ .mmi;	ldf8	f33=[r14]
        +	ldf8	f34=[r15]		}
        +{ .mfi;	ldf8	f35=[r16]
        +
        +		xma.hu	f41=f32,f120,f0		}
        +{ .mfi;		xma.lu	f40=f32,f120,f0		};;
        +{ .mfi;		xma.hu	f51=f32,f121,f0		}
        +{ .mfi;		xma.lu	f50=f32,f121,f0		};;
        +{ .mfi;		xma.hu	f61=f32,f122,f0		}
        +{ .mfi;		xma.lu	f60=f32,f122,f0		};;
        +{ .mfi;		xma.hu	f71=f32,f123,f0		}
        +{ .mfi;		xma.lu	f70=f32,f123,f0		};;//
        +// Major stall takes place here, and 3 more places below. Result from
        +// first xma is not available for another 3 ticks.
        +{ .mfi;	getf.sig	r16=f40
        +		xma.hu	f42=f33,f120,f41
        +	add		r33=8,r32		}
        +{ .mfi;		xma.lu	f41=f33,f120,f41	};;
        +{ .mfi;	getf.sig	r24=f50
        +		xma.hu	f52=f33,f121,f51	}
        +{ .mfi;		xma.lu	f51=f33,f121,f51	};;
        +{ .mfi;	st8		[r32]=r16,16
        +		xma.hu	f62=f33,f122,f61	}
        +{ .mfi;		xma.lu	f61=f33,f122,f61	};;
        +{ .mfi;		xma.hu	f72=f33,f123,f71	}
        +{ .mfi;		xma.lu	f71=f33,f123,f71	};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r25=f41
        +		xma.hu	f43=f34,f120,f42	}
        +{ .mfi;		xma.lu	f42=f34,f120,f42	};;
        +{ .mfi;	getf.sig	r16=f60
        +		xma.hu	f53=f34,f121,f52	}
        +{ .mfi;		xma.lu	f52=f34,f121,f52	};;
        +{ .mfi;	getf.sig	r17=f51
        +		xma.hu	f63=f34,f122,f62
        +	add		r25=r25,r24		}
        +{ .mfi;	mov		carry1=0
        +		xma.lu	f62=f34,f122,f62	};;
        +{ .mfi;	st8		[r33]=r25,16
        +		xma.hu	f73=f34,f123,f72
        +	cmp.ltu		p6,p0=r25,r24		}
        +{ .mfi;		xma.lu	f72=f34,f123,f72	};;//
        +//-------------------------------------------------//
        +{ .mfi;	getf.sig	r18=f42
        +		xma.hu	f44=f35,f120,f43
        +(p6)	add		carry1=1,carry1		}
        +{ .mfi;	add		r17=r17,r16
        +		xma.lu	f43=f35,f120,f43
        +	mov		carry2=0		};;
        +{ .mfi;	getf.sig	r24=f70
        +		xma.hu	f54=f35,f121,f53
        +	cmp.ltu		p7,p0=r17,r16		}
        +{ .mfi;		xma.lu	f53=f35,f121,f53	};;
        +{ .mfi;	getf.sig	r25=f61
        +		xma.hu	f64=f35,f122,f63
        +	add		r18=r18,r17		}
        +{ .mfi;		xma.lu	f63=f35,f122,f63
        +(p7)	add		carry2=1,carry2		};;
        +{ .mfi;	getf.sig	r26=f52
        +		xma.hu	f74=f35,f123,f73
        +	cmp.ltu		p7,p0=r18,r17		}
        +{ .mfi;		xma.lu	f73=f35,f123,f73
        +	add		r18=r18,carry1		};;
        +//-------------------------------------------------//
        +{ .mii;	st8		[r32]=r18,16
        +(p7)	add		carry2=1,carry2
        +	cmp.ltu		p7,p0=r18,carry1	};;
        +
        +{ .mfi;	getf.sig	r27=f43	// last major stall
        +(p7)	add		carry2=1,carry2		};;
        +{ .mii;		getf.sig	r16=f71
        +	add		r25=r25,r24
        +	mov		carry1=0		};;
        +{ .mii;		getf.sig	r17=f62	
        +	cmp.ltu		p6,p0=r25,r24
        +	add		r26=r26,r25		};;
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,r25
        +	add		r27=r27,r26		};;
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r27,r26
        +	add		r27=r27,carry2		};;
        +{ .mii;		getf.sig	r18=f53
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r27,carry2	};;
        +{ .mfi;	st8		[r33]=r27,16
        +(p6)	add		carry1=1,carry1		}
        +
        +{ .mii;		getf.sig	r19=f44
        +		add		r17=r17,r16
        +		mov		carry2=0	};;
        +{ .mii;	getf.sig	r24=f72
        +		cmp.ltu		p7,p0=r17,r16
        +		add		r18=r18,r17	};;
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r18,r17
        +		add		r19=r19,r18	};;
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r19,r18
        +		add		r19=r19,carry1	};;
        +{ .mii;	getf.sig	r25=f63
        +	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r19,carry1};;
        +{ .mii;		st8		[r32]=r19,16
        +	(p7)	add		carry2=1,carry2	}
        +
        +{ .mii;	getf.sig	r26=f54
        +	add		r25=r25,r24
        +	mov		carry1=0		};;
        +{ .mii;		getf.sig	r16=f73
        +	cmp.ltu		p6,p0=r25,r24
        +	add		r26=r26,r25		};;
        +{ .mii;
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,r25
        +	add		r26=r26,carry2		};;
        +{ .mii;		getf.sig	r17=f64
        +(p6)	add		carry1=1,carry1
        +	cmp.ltu		p6,p0=r26,carry2	};;
        +{ .mii;	st8		[r33]=r26,16
        +(p6)	add		carry1=1,carry1		}
        +
        +{ .mii;	getf.sig	r24=f74
        +		add		r17=r17,r16	
        +		mov		carry2=0	};;
        +{ .mii;		cmp.ltu		p7,p0=r17,r16
        +		add		r17=r17,carry1	};;
        +
        +{ .mii;	(p7)	add		carry2=1,carry2
        +		cmp.ltu		p7,p0=r17,carry1};;
        +{ .mii;		st8		[r32]=r17,16
        +	(p7)	add		carry2=1,carry2	};;
        +
        +{ .mii;	add		r24=r24,carry2		};;
        +{ .mii;	st8		[r33]=r24		}
        +
        +{ .mib;	rum		1<<5		// clear um.mfh
        +	br.ret.sptk.many	b0	};;
        +.endp	bn_mul_comba4#
        +#undef	carry2
        +#undef	carry1
        +#endif
        +
        +#if 1
        +//
        +// BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
        +//
        +// In the nutshell it's a port of my MIPS III/IV implementation.
        +//
        +#define	AT	r14
        +#define	H	r16
        +#define	HH	r20
        +#define	L	r17
        +#define	D	r18
        +#define	DH	r22
        +#define	I	r21
        +
        +#if 0
        +// Some preprocessors (most notably HP-UX) appear to be allergic to
        +// macros enclosed to parenthesis [as these three were].
        +#define	cont	p16
        +#define	break	p0	// p20
        +#define	equ	p24
        +#else
        +cont=p16
        +break=p0
        +equ=p24
        +#endif
        +
        +.global	abort#
        +.global	bn_div_words#
        +.proc	bn_div_words#
        +.align	64
        +bn_div_words:
        +	.prologue
        +	.save	ar.pfs,r2
        +{ .mii;	alloc		r2=ar.pfs,3,5,0,8
        +	.save	b0,r3
        +	mov		r3=b0
        +	.save	pr,r10
        +	mov		r10=pr		};;
        +{ .mmb;	cmp.eq		p6,p0=r34,r0
        +	mov		r8=-1
        +(p6)	br.ret.spnt.many	b0	};;
        +
        +	.body
        +{ .mii;	mov		H=r32		// save h
        +	mov		ar.ec=0		// don't rotate at exit
        +	mov		pr.rot=0	}
        +{ .mii;	mov		L=r33		// save l
        +	mov		r36=r0		};;
        +
        +.L_divw_shift:	// -vv- note signed comparison
        +{ .mfi;	(p0)	cmp.lt		p16,p0=r0,r34	// d
        +	(p0)	shladd		r33=r34,1,r0	}
        +{ .mfb;	(p0)	add		r35=1,r36
        +	(p0)	nop.f		0x0
        +(p16)	br.wtop.dpnt		.L_divw_shift	};;
        +
        +{ .mii;	mov		D=r34
        +	shr.u		DH=r34,32
        +	sub		r35=64,r36		};;
        +{ .mii;	setf.sig	f7=DH
        +	shr.u		AT=H,r35
        +	mov		I=r36			};;
        +{ .mib;	cmp.ne		p6,p0=r0,AT
        +	shl		H=H,r36
        +(p6)	br.call.spnt.clr	b0=abort	};;	// overflow, die...
        +
        +{ .mfi;	fcvt.xuf.s1	f7=f7
        +	shr.u		AT=L,r35		};;
        +{ .mii;	shl		L=L,r36
        +	or		H=H,AT			};;
        +
        +{ .mii;	nop.m		0x0
        +	cmp.leu		p6,p0=D,H;;
        +(p6)	sub		H=H,D			}
        +
        +{ .mlx;	setf.sig	f14=D
        +	movl		AT=0xffffffff		};;
        +///////////////////////////////////////////////////////////
        +{ .mii;	setf.sig	f6=H
        +	shr.u		HH=H,32;;
        +	cmp.eq		p6,p7=HH,DH		};;
        +{ .mfb;
        +(p6)	setf.sig	f8=AT
        +(p7)	fcvt.xuf.s1	f6=f6
        +(p7)	br.call.sptk	b6=.L_udiv64_32_b6	};;
        +
        +{ .mfi;	getf.sig	r33=f8				// q
        +	xmpy.lu		f9=f8,f14		}
        +{ .mfi;	xmpy.hu		f10=f8,f14
        +	shrp		H=H,L,32		};;
        +
        +{ .mmi;	getf.sig	r35=f9				// tl
        +	getf.sig	r31=f10			};;	// th
        +
        +.L_divw_1st_iter:
        +{ .mii;	(p0)	add		r32=-1,r33
        +	(p0)	cmp.eq		equ,cont=HH,r31		};;
        +{ .mii;	(p0)	cmp.ltu		p8,p0=r35,D
        +	(p0)	sub		r34=r35,D
        +	(equ)	cmp.leu		break,cont=r35,H	};;
        +{ .mib;	(cont)	cmp.leu		cont,break=HH,r31
        +	(p8)	add		r31=-1,r31
        +(cont)	br.wtop.spnt		.L_divw_1st_iter	};;
        +///////////////////////////////////////////////////////////
        +{ .mii;	sub		H=H,r35
        +	shl		r8=r33,32
        +	shl		L=L,32			};;
        +///////////////////////////////////////////////////////////
        +{ .mii;	setf.sig	f6=H
        +	shr.u		HH=H,32;;
        +	cmp.eq		p6,p7=HH,DH		};;
        +{ .mfb;
        +(p6)	setf.sig	f8=AT
        +(p7)	fcvt.xuf.s1	f6=f6
        +(p7)	br.call.sptk	b6=.L_udiv64_32_b6	};;
        +
        +{ .mfi;	getf.sig	r33=f8				// q
        +	xmpy.lu		f9=f8,f14		}
        +{ .mfi;	xmpy.hu		f10=f8,f14
        +	shrp		H=H,L,32		};;
        +
        +{ .mmi;	getf.sig	r35=f9				// tl
        +	getf.sig	r31=f10			};;	// th
        +
        +.L_divw_2nd_iter:
        +{ .mii;	(p0)	add		r32=-1,r33
        +	(p0)	cmp.eq		equ,cont=HH,r31		};;
        +{ .mii;	(p0)	cmp.ltu		p8,p0=r35,D
        +	(p0)	sub		r34=r35,D
        +	(equ)	cmp.leu		break,cont=r35,H	};;
        +{ .mib;	(cont)	cmp.leu		cont,break=HH,r31
        +	(p8)	add		r31=-1,r31
        +(cont)	br.wtop.spnt		.L_divw_2nd_iter	};;
        +///////////////////////////////////////////////////////////
        +{ .mii;	sub	H=H,r35
        +	or	r8=r8,r33
        +	mov	ar.pfs=r2		};;
        +{ .mii;	shr.u	r9=H,I			// remainder if anybody wants it
        +	mov	pr=r10,0x1ffff		}
        +{ .mfb;	br.ret.sptk.many	b0	};;
        +
        +// Unsigned 64 by 32 (well, by 64 for the moment) bit integer division
        +// procedure.
        +//
        +// inputs:	f6 = (double)a, f7 = (double)b
        +// output:	f8 = (int)(a/b)
        +// clobbered:	f8,f9,f10,f11,pred
        +pred=p15
        +// One can argue that this snippet is copyrighted to Intel
        +// Corporation, as it's essentially identical to one of those
        +// found in "Divide, Square Root and Remainder" section at
        +// http://www.intel.com/software/products/opensource/libraries/num.htm.
        +// Yes, I admit that the referred code was used as template,
        +// but after I realized that there hardly is any other instruction
        +// sequence which would perform this operation. I mean I figure that
        +// any independent attempt to implement high-performance division
        +// will result in code virtually identical to the Intel code. It
        +// should be noted though that below division kernel is 1 cycle
        +// faster than Intel one (note commented splits:-), not to mention
        +// original prologue (rather lack of one) and epilogue.
        +.align	32
        +.skip	16
        +.L_udiv64_32_b6:
        +	frcpa.s1	f8,pred=f6,f7;;		// [0]  y0 = 1 / b
        +
        +(pred)	fnma.s1		f9=f7,f8,f1		// [5]  e0 = 1 - b * y0
        +(pred)	fmpy.s1		f10=f6,f8;;		// [5]  q0 = a * y0
        +(pred)	fmpy.s1		f11=f9,f9		// [10] e1 = e0 * e0
        +(pred)	fma.s1		f10=f9,f10,f10;;	// [10] q1 = q0 + e0 * q0
        +(pred)	fma.s1		f8=f9,f8,f8	//;;	// [15] y1 = y0 + e0 * y0
        +(pred)	fma.s1		f9=f11,f10,f10;;	// [15] q2 = q1 + e1 * q1
        +(pred)	fma.s1		f8=f11,f8,f8	//;;	// [20] y2 = y1 + e1 * y1
        +(pred)	fnma.s1		f10=f7,f9,f6;;		// [20] r2 = a - b * q2
        +(pred)	fma.s1		f8=f10,f8,f9;;		// [25] q3 = q2 + r2 * y2
        +
        +	fcvt.fxu.trunc.s1	f8=f8		// [30] q = trunc(q3)
        +	br.ret.sptk.many	b6;;
        +.endp	bn_div_words#
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/mips-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/mips-mont.pl
        new file mode 100644
        index 000000000..b944a12b8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/mips-mont.pl
        @@ -0,0 +1,426 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# This module doesn't present direct interest for OpenSSL, because it
        +# doesn't provide better performance for longer keys, at least not on
        +# in-order-execution cores. While 512-bit RSA sign operations can be
        +# 65% faster in 64-bit mode, 1024-bit ones are only 15% faster, and
        +# 4096-bit ones are up to 15% slower. In 32-bit mode it varies from
        +# 16% improvement for 512-bit RSA sign to -33% for 4096-bit RSA
        +# verify:-( All comparisons are against bn_mul_mont-free assembler.
        +# The module might be of interest to embedded system developers, as
        +# the code is smaller than 1KB, yet offers >3x improvement on MIPS64
        +# and 75-30% [less for longer keys] on MIPS32 over compiler-generated
        +# code.
        +
        +######################################################################
        +# There is a number of MIPS ABI in use, O32 and N32/64 are most
        +# widely used. Then there is a new contender: NUBI. It appears that if
        +# one picks the latter, it's possible to arrange code in ABI neutral
        +# manner. Therefore let's stick to NUBI register layout:
        +#
        +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
        +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
        +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
        +#
        +# The return value is placed in $a0. Following coding rules facilitate
        +# interoperability:
        +#
        +# - never ever touch $tp, "thread pointer", former $gp;
        +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
        +#   old code];
        +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
        +#
        +# For reference here is register layout for N32/64 MIPS ABIs:
        +#
        +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
        +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
        +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
        +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
        +#
        +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
        +
        +if ($flavour =~ /64|n32/i) {
        +	$PTR_ADD="dadd";	# incidentally works even on n32
        +	$PTR_SUB="dsub";	# incidentally works even on n32
        +	$REG_S="sd";
        +	$REG_L="ld";
        +	$SZREG=8;
        +} else {
        +	$PTR_ADD="add";
        +	$PTR_SUB="sub";
        +	$REG_S="sw";
        +	$REG_L="lw";
        +	$SZREG=4;
        +}
        +$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0x00fff000 : 0x00ff0000;
        +#
        +# <appro@openssl.org>
        +#
        +######################################################################
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64|n32/i) {
        +	$LD="ld";
        +	$ST="sd";
        +	$MULTU="dmultu";
        +	$ADDU="daddu";
        +	$SUBU="dsubu";
        +	$BNSZ=8;
        +} else {
        +	$LD="lw";
        +	$ST="sw";
        +	$MULTU="multu";
        +	$ADDU="addu";
        +	$SUBU="subu";
        +	$BNSZ=4;
        +}
        +
        +# int bn_mul_mont(
        +$rp=$a0;	# BN_ULONG *rp,
        +$ap=$a1;	# const BN_ULONG *ap,
        +$bp=$a2;	# const BN_ULONG *bp,
        +$np=$a3;	# const BN_ULONG *np,
        +$n0=$a4;	# const BN_ULONG *n0,
        +$num=$a5;	# int num);
        +
        +$lo0=$a6;
        +$hi0=$a7;
        +$lo1=$t1;
        +$hi1=$t2;
        +$aj=$s0;
        +$bi=$s1;
        +$nj=$s2;
        +$tp=$s3;
        +$alo=$s4;
        +$ahi=$s5;
        +$nlo=$s6;
        +$nhi=$s7;
        +$tj=$s8;
        +$i=$s9;
        +$j=$s10;
        +$m1=$s11;
        +
        +$FRAMESIZE=14;
        +
        +$code=<<___;
        +.text
        +
        +.set	noat
        +.set	noreorder
        +
        +.align	5
        +.globl	bn_mul_mont
        +.ent	bn_mul_mont
        +bn_mul_mont:
        +___
        +$code.=<<___ if ($flavour =~ /o32/i);
        +	lw	$n0,16($sp)
        +	lw	$num,20($sp)
        +___
        +$code.=<<___;
        +	slt	$at,$num,4
        +	bnez	$at,1f
        +	li	$t0,0
        +	slt	$at,$num,17	# on in-order CPU
        +	bnezl	$at,bn_mul_mont_internal
        +	nop
        +1:	jr	$ra
        +	li	$a0,0
        +.end	bn_mul_mont
        +
        +.align	5
        +.ent	bn_mul_mont_internal
        +bn_mul_mont_internal:
        +	.frame	$fp,$FRAMESIZE*$SZREG,$ra
        +	.mask	0x40000000|$SAVED_REGS_MASK,-$SZREG
        +	$PTR_SUB $sp,$FRAMESIZE*$SZREG
        +	$REG_S	$fp,($FRAMESIZE-1)*$SZREG($sp)
        +	$REG_S	$s11,($FRAMESIZE-2)*$SZREG($sp)
        +	$REG_S	$s10,($FRAMESIZE-3)*$SZREG($sp)
        +	$REG_S	$s9,($FRAMESIZE-4)*$SZREG($sp)
        +	$REG_S	$s8,($FRAMESIZE-5)*$SZREG($sp)
        +	$REG_S	$s7,($FRAMESIZE-6)*$SZREG($sp)
        +	$REG_S	$s6,($FRAMESIZE-7)*$SZREG($sp)
        +	$REG_S	$s5,($FRAMESIZE-8)*$SZREG($sp)
        +	$REG_S	$s4,($FRAMESIZE-9)*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_S	$s3,($FRAMESIZE-10)*$SZREG($sp)
        +	$REG_S	$s2,($FRAMESIZE-11)*$SZREG($sp)
        +	$REG_S	$s1,($FRAMESIZE-12)*$SZREG($sp)
        +	$REG_S	$s0,($FRAMESIZE-13)*$SZREG($sp)
        +___
        +$code.=<<___;
        +	move	$fp,$sp
        +
        +	.set	reorder
        +	$LD	$n0,0($n0)
        +	$LD	$bi,0($bp)	# bp[0]
        +	$LD	$aj,0($ap)	# ap[0]
        +	$LD	$nj,0($np)	# np[0]
        +
        +	$PTR_SUB $sp,2*$BNSZ	# place for two extra words
        +	sll	$num,`log($BNSZ)/log(2)`
        +	li	$at,-4096
        +	$PTR_SUB $sp,$num
        +	and	$sp,$at
        +
        +	$MULTU	$aj,$bi
        +	$LD	$alo,$BNSZ($ap)
        +	$LD	$nlo,$BNSZ($np)
        +	mflo	$lo0
        +	mfhi	$hi0
        +	$MULTU	$lo0,$n0
        +	mflo	$m1
        +
        +	$MULTU	$alo,$bi
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	$MULTU	$nj,$m1
        +	mflo	$lo1
        +	mfhi	$hi1
        +	$MULTU	$nlo,$m1
        +	$ADDU	$lo1,$lo0
        +	sltu	$at,$lo1,$lo0
        +	$ADDU	$hi1,$at
        +	mflo	$nlo
        +	mfhi	$nhi
        +
        +	move	$tp,$sp
        +	li	$j,2*$BNSZ
        +.align	4
        +.L1st:
        +	.set	noreorder
        +	$PTR_ADD $aj,$ap,$j
        +	$PTR_ADD $nj,$np,$j
        +	$LD	$aj,($aj)
        +	$LD	$nj,($nj)
        +
        +	$MULTU	$aj,$bi
        +	$ADDU	$lo0,$alo,$hi0
        +	$ADDU	$lo1,$nlo,$hi1
        +	sltu	$at,$lo0,$hi0
        +	sltu	$t0,$lo1,$hi1
        +	$ADDU	$hi0,$ahi,$at
        +	$ADDU	$hi1,$nhi,$t0
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	$ADDU	$lo1,$lo0
        +	sltu	$at,$lo1,$lo0
        +	$MULTU	$nj,$m1
        +	$ADDU	$hi1,$at
        +	addu	$j,$BNSZ
        +	$ST	$lo1,($tp)
        +	sltu	$t0,$j,$num
        +	mflo	$nlo
        +	mfhi	$nhi
        +
        +	bnez	$t0,.L1st
        +	$PTR_ADD $tp,$BNSZ
        +	.set	reorder
        +
        +	$ADDU	$lo0,$alo,$hi0
        +	sltu	$at,$lo0,$hi0
        +	$ADDU	$hi0,$ahi,$at
        +
        +	$ADDU	$lo1,$nlo,$hi1
        +	sltu	$t0,$lo1,$hi1
        +	$ADDU	$hi1,$nhi,$t0
        +	$ADDU	$lo1,$lo0
        +	sltu	$at,$lo1,$lo0
        +	$ADDU	$hi1,$at
        +
        +	$ST	$lo1,($tp)
        +
        +	$ADDU	$hi1,$hi0
        +	sltu	$at,$hi1,$hi0
        +	$ST	$hi1,$BNSZ($tp)
        +	$ST	$at,2*$BNSZ($tp)
        +
        +	li	$i,$BNSZ
        +.align	4
        +.Louter:
        +	$PTR_ADD $bi,$bp,$i
        +	$LD	$bi,($bi)
        +	$LD	$aj,($ap)
        +	$LD	$alo,$BNSZ($ap)
        +	$LD	$tj,($sp)
        +
        +	$MULTU	$aj,$bi
        +	$LD	$nj,($np)
        +	$LD	$nlo,$BNSZ($np)
        +	mflo	$lo0
        +	mfhi	$hi0
        +	$ADDU	$lo0,$tj
        +	$MULTU	$lo0,$n0
        +	sltu	$at,$lo0,$tj
        +	$ADDU	$hi0,$at
        +	mflo	$m1
        +
        +	$MULTU	$alo,$bi
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	$MULTU	$nj,$m1
        +	mflo	$lo1
        +	mfhi	$hi1
        +
        +	$MULTU	$nlo,$m1
        +	$ADDU	$lo1,$lo0
        +	sltu	$at,$lo1,$lo0
        +	$ADDU	$hi1,$at
        +	mflo	$nlo
        +	mfhi	$nhi
        +
        +	move	$tp,$sp
        +	li	$j,2*$BNSZ
        +	$LD	$tj,$BNSZ($tp)
        +.align	4
        +.Linner:
        +	.set	noreorder
        +	$PTR_ADD $aj,$ap,$j
        +	$PTR_ADD $nj,$np,$j
        +	$LD	$aj,($aj)
        +	$LD	$nj,($nj)
        +
        +	$MULTU	$aj,$bi
        +	$ADDU	$lo0,$alo,$hi0
        +	$ADDU	$lo1,$nlo,$hi1
        +	sltu	$at,$lo0,$hi0
        +	sltu	$t0,$lo1,$hi1
        +	$ADDU	$hi0,$ahi,$at
        +	$ADDU	$hi1,$nhi,$t0
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	$ADDU	$lo0,$tj
        +	addu	$j,$BNSZ
        +	$MULTU	$nj,$m1
        +	sltu	$at,$lo0,$tj
        +	$ADDU	$lo1,$lo0
        +	$ADDU	$hi0,$at
        +	sltu	$t0,$lo1,$lo0
        +	$LD	$tj,2*$BNSZ($tp)
        +	$ADDU	$hi1,$t0
        +	sltu	$at,$j,$num
        +	mflo	$nlo
        +	mfhi	$nhi
        +	$ST	$lo1,($tp)
        +	bnez	$at,.Linner
        +	$PTR_ADD $tp,$BNSZ
        +	.set	reorder
        +
        +	$ADDU	$lo0,$alo,$hi0
        +	sltu	$at,$lo0,$hi0
        +	$ADDU	$hi0,$ahi,$at
        +	$ADDU	$lo0,$tj
        +	sltu	$t0,$lo0,$tj
        +	$ADDU	$hi0,$t0
        +
        +	$LD	$tj,2*$BNSZ($tp)
        +	$ADDU	$lo1,$nlo,$hi1
        +	sltu	$at,$lo1,$hi1
        +	$ADDU	$hi1,$nhi,$at
        +	$ADDU	$lo1,$lo0
        +	sltu	$t0,$lo1,$lo0
        +	$ADDU	$hi1,$t0
        +	$ST	$lo1,($tp)
        +
        +	$ADDU	$lo1,$hi1,$hi0
        +	sltu	$hi1,$lo1,$hi0
        +	$ADDU	$lo1,$tj
        +	sltu	$at,$lo1,$tj
        +	$ADDU	$hi1,$at
        +	$ST	$lo1,$BNSZ($tp)
        +	$ST	$hi1,2*$BNSZ($tp)
        +
        +	addu	$i,$BNSZ
        +	sltu	$t0,$i,$num
        +	bnez	$t0,.Louter
        +
        +	.set	noreorder
        +	$PTR_ADD $tj,$sp,$num	# &tp[num]
        +	move	$tp,$sp
        +	move	$ap,$sp
        +	li	$hi0,0		# clear borrow bit
        +
        +.align	4
        +.Lsub:	$LD	$lo0,($tp)
        +	$LD	$lo1,($np)
        +	$PTR_ADD $tp,$BNSZ
        +	$PTR_ADD $np,$BNSZ
        +	$SUBU	$lo1,$lo0,$lo1	# tp[i]-np[i]
        +	sgtu	$at,$lo1,$lo0
        +	$SUBU	$lo0,$lo1,$hi0
        +	sgtu	$hi0,$lo0,$lo1
        +	$ST	$lo0,($rp)
        +	or	$hi0,$at
        +	sltu	$at,$tp,$tj
        +	bnez	$at,.Lsub
        +	$PTR_ADD $rp,$BNSZ
        +
        +	$SUBU	$hi0,$hi1,$hi0	# handle upmost overflow bit
        +	move	$tp,$sp
        +	$PTR_SUB $rp,$num	# restore rp
        +	not	$hi1,$hi0
        +
        +	and	$ap,$hi0,$sp
        +	and	$bp,$hi1,$rp
        +	or	$ap,$ap,$bp	# ap=borrow?tp:rp
        +
        +.align	4
        +.Lcopy:	$LD	$aj,($ap)
        +	$PTR_ADD $ap,$BNSZ
        +	$ST	$zero,($tp)
        +	$PTR_ADD $tp,$BNSZ
        +	sltu	$at,$tp,$tj
        +	$ST	$aj,($rp)
        +	bnez	$at,.Lcopy
        +	$PTR_ADD $rp,$BNSZ
        +
        +	li	$a0,1
        +	li	$t0,1
        +
        +	.set	noreorder
        +	move	$sp,$fp
        +	$REG_L	$fp,($FRAMESIZE-1)*$SZREG($sp)
        +	$REG_L	$s11,($FRAMESIZE-2)*$SZREG($sp)
        +	$REG_L	$s10,($FRAMESIZE-3)*$SZREG($sp)
        +	$REG_L	$s9,($FRAMESIZE-4)*$SZREG($sp)
        +	$REG_L	$s8,($FRAMESIZE-5)*$SZREG($sp)
        +	$REG_L	$s7,($FRAMESIZE-6)*$SZREG($sp)
        +	$REG_L	$s6,($FRAMESIZE-7)*$SZREG($sp)
        +	$REG_L	$s5,($FRAMESIZE-8)*$SZREG($sp)
        +	$REG_L	$s4,($FRAMESIZE-9)*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$s3,($FRAMESIZE-10)*$SZREG($sp)
        +	$REG_L	$s2,($FRAMESIZE-11)*$SZREG($sp)
        +	$REG_L	$s1,($FRAMESIZE-12)*$SZREG($sp)
        +	$REG_L	$s0,($FRAMESIZE-13)*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE*$SZREG
        +.end	bn_mul_mont_internal
        +.rdata
        +.asciiz	"Montgomery Multiplication for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/mips.pl b/vendor/openssl/openssl/crypto/bn/asm/mips.pl
        new file mode 100644
        index 000000000..38b51645f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/mips.pl
        @@ -0,0 +1,2585 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project.
        +#
        +# Rights for redistribution and usage in source and binary forms are
        +# granted according to the OpenSSL license. Warranty of any kind is
        +# disclaimed.
        +# ====================================================================
        +
        +
        +# July 1999
        +#
        +# This is drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c.
        +#
        +# The module is designed to work with either of the "new" MIPS ABI(5),
        +# namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
        +# IRIX 5.x not only because it doesn't support new ABIs but also
        +# because 5.x kernels put R4x00 CPU into 32-bit mode and all those
        +# 64-bit instructions (daddu, dmultu, etc.) found below gonna only
        +# cause illegal instruction exception:-(
        +#
        +# In addition the code depends on preprocessor flags set up by MIPSpro
        +# compiler driver (either as or cc) and therefore (probably?) can't be
        +# compiled by the GNU assembler. GNU C driver manages fine though...
        +# I mean as long as -mmips-as is specified or is the default option,
        +# because then it simply invokes /usr/bin/as which in turn takes
        +# perfect care of the preprocessor definitions. Another neat feature
        +# offered by the MIPSpro assembler is an optimization pass. This gave
        +# me the opportunity to have the code looking more regular as all those
        +# architecture dependent instruction rescheduling details were left to
        +# the assembler. Cool, huh?
        +#
        +# Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
        +# goes way over 3 times faster!
        +#
        +#					<appro@fy.chalmers.se>
        +
        +# October 2010
        +#
        +# Adapt the module even for 32-bit ABIs and other OSes. The former was
        +# achieved by mechanical replacement of 64-bit arithmetic instructions
        +# such as dmultu, daddu, etc. with their 32-bit counterparts and
        +# adjusting offsets denoting multiples of BN_ULONG. Above mentioned
        +# >3x performance improvement naturally does not apply to 32-bit code
        +# [because there is no instruction 32-bit compiler can't use], one
        +# has to content with 40-85% improvement depending on benchmark and
        +# key length, more for longer keys.
        +
        +$flavour = shift;
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64|n32/i) {
        +	$LD="ld";
        +	$ST="sd";
        +	$MULTU="dmultu";
        +	$DIVU="ddivu";
        +	$ADDU="daddu";
        +	$SUBU="dsubu";
        +	$SRL="dsrl";
        +	$SLL="dsll";
        +	$BNSZ=8;
        +	$PTR_ADD="daddu";
        +	$PTR_SUB="dsubu";
        +	$SZREG=8;
        +	$REG_S="sd";
        +	$REG_L="ld";
        +} else {
        +	$LD="lw";
        +	$ST="sw";
        +	$MULTU="multu";
        +	$DIVU="divu";
        +	$ADDU="addu";
        +	$SUBU="subu";
        +	$SRL="srl";
        +	$SLL="sll";
        +	$BNSZ=4;
        +	$PTR_ADD="addu";
        +	$PTR_SUB="subu";
        +	$SZREG=4;
        +	$REG_S="sw";
        +	$REG_L="lw";
        +	$code=".set	mips2\n";
        +}
        +
        +# Below is N32/64 register layout used in the original module.
        +#
        +($zero,$at,$v0,$v1)=map("\$$_",(0..3));
        +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
        +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
        +($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
        +($ta0,$ta1,$ta2,$ta3)=($a4,$a5,$a6,$a7);
        +#
        +# No special adaptation is required for O32. NUBI on the other hand
        +# is treated by saving/restoring ($v1,$t0..$t3).
        +
        +$gp=$v1 if ($flavour =~ /nubi/i);
        +
        +$minus4=$v1;
        +
        +$code.=<<___;
        +.rdata
        +.asciiz	"mips3.s, Version 1.2"
        +.asciiz	"MIPS II/III/IV ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>"
        +
        +.text
        +.set	noat
        +
        +.align	5
        +.globl	bn_mul_add_words
        +.ent	bn_mul_add_words
        +bn_mul_add_words:
        +	.set	noreorder
        +	bgtz	$a2,bn_mul_add_words_internal
        +	move	$v0,$zero
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_mul_add_words
        +
        +.align	5
        +.ent	bn_mul_add_words_internal
        +bn_mul_add_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	li	$minus4,-4
        +	and	$ta0,$a2,$minus4
        +	$LD	$t0,0($a1)
        +	beqz	$ta0,.L_bn_mul_add_words_tail
        +
        +.L_bn_mul_add_words_loop:
        +	$MULTU	$t0,$a3
        +	$LD	$t1,0($a0)
        +	$LD	$t2,$BNSZ($a1)
        +	$LD	$t3,$BNSZ($a0)
        +	$LD	$ta0,2*$BNSZ($a1)
        +	$LD	$ta1,2*$BNSZ($a0)
        +	$ADDU	$t1,$v0
        +	sltu	$v0,$t1,$v0	# All manuals say it "compares 32-bit
        +				# values", but it seems to work fine
        +				# even on 64-bit registers.
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$t1,$at
        +	$ADDU	$v0,$t0
        +	 $MULTU	$t2,$a3
        +	sltu	$at,$t1,$at
        +	$ST	$t1,0($a0)
        +	$ADDU	$v0,$at
        +
        +	$LD	$ta2,3*$BNSZ($a1)
        +	$LD	$ta3,3*$BNSZ($a0)
        +	$ADDU	$t3,$v0
        +	sltu	$v0,$t3,$v0
        +	mflo	$at
        +	mfhi	$t2
        +	$ADDU	$t3,$at
        +	$ADDU	$v0,$t2
        +	 $MULTU	$ta0,$a3
        +	sltu	$at,$t3,$at
        +	$ST	$t3,$BNSZ($a0)
        +	$ADDU	$v0,$at
        +
        +	subu	$a2,4
        +	$PTR_ADD $a0,4*$BNSZ
        +	$PTR_ADD $a1,4*$BNSZ
        +	$ADDU	$ta1,$v0
        +	sltu	$v0,$ta1,$v0
        +	mflo	$at
        +	mfhi	$ta0
        +	$ADDU	$ta1,$at
        +	$ADDU	$v0,$ta0
        +	 $MULTU	$ta2,$a3
        +	sltu	$at,$ta1,$at
        +	$ST	$ta1,-2*$BNSZ($a0)
        +	$ADDU	$v0,$at
        +
        +
        +	and	$ta0,$a2,$minus4
        +	$ADDU	$ta3,$v0
        +	sltu	$v0,$ta3,$v0
        +	mflo	$at
        +	mfhi	$ta2
        +	$ADDU	$ta3,$at
        +	$ADDU	$v0,$ta2
        +	sltu	$at,$ta3,$at
        +	$ST	$ta3,-$BNSZ($a0)
        +	$ADDU	$v0,$at
        +	.set	noreorder
        +	bgtzl	$ta0,.L_bn_mul_add_words_loop
        +	$LD	$t0,0($a1)
        +
        +	beqz	$a2,.L_bn_mul_add_words_return
        +	nop
        +
        +.L_bn_mul_add_words_tail:
        +	.set	reorder
        +	$LD	$t0,0($a1)
        +	$MULTU	$t0,$a3
        +	$LD	$t1,0($a0)
        +	subu	$a2,1
        +	$ADDU	$t1,$v0
        +	sltu	$v0,$t1,$v0
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$t1,$at
        +	$ADDU	$v0,$t0
        +	sltu	$at,$t1,$at
        +	$ST	$t1,0($a0)
        +	$ADDU	$v0,$at
        +	beqz	$a2,.L_bn_mul_add_words_return
        +
        +	$LD	$t0,$BNSZ($a1)
        +	$MULTU	$t0,$a3
        +	$LD	$t1,$BNSZ($a0)
        +	subu	$a2,1
        +	$ADDU	$t1,$v0
        +	sltu	$v0,$t1,$v0
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$t1,$at
        +	$ADDU	$v0,$t0
        +	sltu	$at,$t1,$at
        +	$ST	$t1,$BNSZ($a0)
        +	$ADDU	$v0,$at
        +	beqz	$a2,.L_bn_mul_add_words_return
        +
        +	$LD	$t0,2*$BNSZ($a1)
        +	$MULTU	$t0,$a3
        +	$LD	$t1,2*$BNSZ($a0)
        +	$ADDU	$t1,$v0
        +	sltu	$v0,$t1,$v0
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$t1,$at
        +	$ADDU	$v0,$t0
        +	sltu	$at,$t1,$at
        +	$ST	$t1,2*$BNSZ($a0)
        +	$ADDU	$v0,$at
        +
        +.L_bn_mul_add_words_return:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_mul_add_words_internal
        +
        +.align	5
        +.globl	bn_mul_words
        +.ent	bn_mul_words
        +bn_mul_words:
        +	.set	noreorder
        +	bgtz	$a2,bn_mul_words_internal
        +	move	$v0,$zero
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_mul_words
        +
        +.align	5
        +.ent	bn_mul_words_internal
        +bn_mul_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	li	$minus4,-4
        +	and	$ta0,$a2,$minus4
        +	$LD	$t0,0($a1)
        +	beqz	$ta0,.L_bn_mul_words_tail
        +
        +.L_bn_mul_words_loop:
        +	$MULTU	$t0,$a3
        +	$LD	$t2,$BNSZ($a1)
        +	$LD	$ta0,2*$BNSZ($a1)
        +	$LD	$ta2,3*$BNSZ($a1)
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$v0,$at
        +	sltu	$t1,$v0,$at
        +	 $MULTU	$t2,$a3
        +	$ST	$v0,0($a0)
        +	$ADDU	$v0,$t1,$t0
        +
        +	subu	$a2,4
        +	$PTR_ADD $a0,4*$BNSZ
        +	$PTR_ADD $a1,4*$BNSZ
        +	mflo	$at
        +	mfhi	$t2
        +	$ADDU	$v0,$at
        +	sltu	$t3,$v0,$at
        +	 $MULTU	$ta0,$a3
        +	$ST	$v0,-3*$BNSZ($a0)
        +	$ADDU	$v0,$t3,$t2
        +
        +	mflo	$at
        +	mfhi	$ta0
        +	$ADDU	$v0,$at
        +	sltu	$ta1,$v0,$at
        +	 $MULTU	$ta2,$a3
        +	$ST	$v0,-2*$BNSZ($a0)
        +	$ADDU	$v0,$ta1,$ta0
        +
        +	and	$ta0,$a2,$minus4
        +	mflo	$at
        +	mfhi	$ta2
        +	$ADDU	$v0,$at
        +	sltu	$ta3,$v0,$at
        +	$ST	$v0,-$BNSZ($a0)
        +	$ADDU	$v0,$ta3,$ta2
        +	.set	noreorder
        +	bgtzl	$ta0,.L_bn_mul_words_loop
        +	$LD	$t0,0($a1)
        +
        +	beqz	$a2,.L_bn_mul_words_return
        +	nop
        +
        +.L_bn_mul_words_tail:
        +	.set	reorder
        +	$LD	$t0,0($a1)
        +	$MULTU	$t0,$a3
        +	subu	$a2,1
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$v0,$at
        +	sltu	$t1,$v0,$at
        +	$ST	$v0,0($a0)
        +	$ADDU	$v0,$t1,$t0
        +	beqz	$a2,.L_bn_mul_words_return
        +
        +	$LD	$t0,$BNSZ($a1)
        +	$MULTU	$t0,$a3
        +	subu	$a2,1
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$v0,$at
        +	sltu	$t1,$v0,$at
        +	$ST	$v0,$BNSZ($a0)
        +	$ADDU	$v0,$t1,$t0
        +	beqz	$a2,.L_bn_mul_words_return
        +
        +	$LD	$t0,2*$BNSZ($a1)
        +	$MULTU	$t0,$a3
        +	mflo	$at
        +	mfhi	$t0
        +	$ADDU	$v0,$at
        +	sltu	$t1,$v0,$at
        +	$ST	$v0,2*$BNSZ($a0)
        +	$ADDU	$v0,$t1,$t0
        +
        +.L_bn_mul_words_return:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_mul_words_internal
        +
        +.align	5
        +.globl	bn_sqr_words
        +.ent	bn_sqr_words
        +bn_sqr_words:
        +	.set	noreorder
        +	bgtz	$a2,bn_sqr_words_internal
        +	move	$v0,$zero
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_sqr_words
        +
        +.align	5
        +.ent	bn_sqr_words_internal
        +bn_sqr_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	li	$minus4,-4
        +	and	$ta0,$a2,$minus4
        +	$LD	$t0,0($a1)
        +	beqz	$ta0,.L_bn_sqr_words_tail
        +
        +.L_bn_sqr_words_loop:
        +	$MULTU	$t0,$t0
        +	$LD	$t2,$BNSZ($a1)
        +	$LD	$ta0,2*$BNSZ($a1)
        +	$LD	$ta2,3*$BNSZ($a1)
        +	mflo	$t1
        +	mfhi	$t0
        +	$ST	$t1,0($a0)
        +	$ST	$t0,$BNSZ($a0)
        +
        +	$MULTU	$t2,$t2
        +	subu	$a2,4
        +	$PTR_ADD $a0,8*$BNSZ
        +	$PTR_ADD $a1,4*$BNSZ
        +	mflo	$t3
        +	mfhi	$t2
        +	$ST	$t3,-6*$BNSZ($a0)
        +	$ST	$t2,-5*$BNSZ($a0)
        +
        +	$MULTU	$ta0,$ta0
        +	mflo	$ta1
        +	mfhi	$ta0
        +	$ST	$ta1,-4*$BNSZ($a0)
        +	$ST	$ta0,-3*$BNSZ($a0)
        +
        +
        +	$MULTU	$ta2,$ta2
        +	and	$ta0,$a2,$minus4
        +	mflo	$ta3
        +	mfhi	$ta2
        +	$ST	$ta3,-2*$BNSZ($a0)
        +	$ST	$ta2,-$BNSZ($a0)
        +
        +	.set	noreorder
        +	bgtzl	$ta0,.L_bn_sqr_words_loop
        +	$LD	$t0,0($a1)
        +
        +	beqz	$a2,.L_bn_sqr_words_return
        +	nop
        +
        +.L_bn_sqr_words_tail:
        +	.set	reorder
        +	$LD	$t0,0($a1)
        +	$MULTU	$t0,$t0
        +	subu	$a2,1
        +	mflo	$t1
        +	mfhi	$t0
        +	$ST	$t1,0($a0)
        +	$ST	$t0,$BNSZ($a0)
        +	beqz	$a2,.L_bn_sqr_words_return
        +
        +	$LD	$t0,$BNSZ($a1)
        +	$MULTU	$t0,$t0
        +	subu	$a2,1
        +	mflo	$t1
        +	mfhi	$t0
        +	$ST	$t1,2*$BNSZ($a0)
        +	$ST	$t0,3*$BNSZ($a0)
        +	beqz	$a2,.L_bn_sqr_words_return
        +
        +	$LD	$t0,2*$BNSZ($a1)
        +	$MULTU	$t0,$t0
        +	mflo	$t1
        +	mfhi	$t0
        +	$ST	$t1,4*$BNSZ($a0)
        +	$ST	$t0,5*$BNSZ($a0)
        +
        +.L_bn_sqr_words_return:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +
        +.end	bn_sqr_words_internal
        +
        +.align	5
        +.globl	bn_add_words
        +.ent	bn_add_words
        +bn_add_words:
        +	.set	noreorder
        +	bgtz	$a3,bn_add_words_internal
        +	move	$v0,$zero
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_add_words
        +
        +.align	5
        +.ent	bn_add_words_internal
        +bn_add_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	li	$minus4,-4
        +	and	$at,$a3,$minus4
        +	$LD	$t0,0($a1)
        +	beqz	$at,.L_bn_add_words_tail
        +
        +.L_bn_add_words_loop:
        +	$LD	$ta0,0($a2)
        +	subu	$a3,4
        +	$LD	$t1,$BNSZ($a1)
        +	and	$at,$a3,$minus4
        +	$LD	$t2,2*$BNSZ($a1)
        +	$PTR_ADD $a2,4*$BNSZ
        +	$LD	$t3,3*$BNSZ($a1)
        +	$PTR_ADD $a0,4*$BNSZ
        +	$LD	$ta1,-3*$BNSZ($a2)
        +	$PTR_ADD $a1,4*$BNSZ
        +	$LD	$ta2,-2*$BNSZ($a2)
        +	$LD	$ta3,-$BNSZ($a2)
        +	$ADDU	$ta0,$t0
        +	sltu	$t8,$ta0,$t0
        +	$ADDU	$t0,$ta0,$v0
        +	sltu	$v0,$t0,$ta0
        +	$ST	$t0,-4*$BNSZ($a0)
        +	$ADDU	$v0,$t8
        +
        +	$ADDU	$ta1,$t1
        +	sltu	$t9,$ta1,$t1
        +	$ADDU	$t1,$ta1,$v0
        +	sltu	$v0,$t1,$ta1
        +	$ST	$t1,-3*$BNSZ($a0)
        +	$ADDU	$v0,$t9
        +
        +	$ADDU	$ta2,$t2
        +	sltu	$t8,$ta2,$t2
        +	$ADDU	$t2,$ta2,$v0
        +	sltu	$v0,$t2,$ta2
        +	$ST	$t2,-2*$BNSZ($a0)
        +	$ADDU	$v0,$t8
        +	
        +	$ADDU	$ta3,$t3
        +	sltu	$t9,$ta3,$t3
        +	$ADDU	$t3,$ta3,$v0
        +	sltu	$v0,$t3,$ta3
        +	$ST	$t3,-$BNSZ($a0)
        +	$ADDU	$v0,$t9
        +	
        +	.set	noreorder
        +	bgtzl	$at,.L_bn_add_words_loop
        +	$LD	$t0,0($a1)
        +
        +	beqz	$a3,.L_bn_add_words_return
        +	nop
        +
        +.L_bn_add_words_tail:
        +	.set	reorder
        +	$LD	$t0,0($a1)
        +	$LD	$ta0,0($a2)
        +	$ADDU	$ta0,$t0
        +	subu	$a3,1
        +	sltu	$t8,$ta0,$t0
        +	$ADDU	$t0,$ta0,$v0
        +	sltu	$v0,$t0,$ta0
        +	$ST	$t0,0($a0)
        +	$ADDU	$v0,$t8
        +	beqz	$a3,.L_bn_add_words_return
        +
        +	$LD	$t1,$BNSZ($a1)
        +	$LD	$ta1,$BNSZ($a2)
        +	$ADDU	$ta1,$t1
        +	subu	$a3,1
        +	sltu	$t9,$ta1,$t1
        +	$ADDU	$t1,$ta1,$v0
        +	sltu	$v0,$t1,$ta1
        +	$ST	$t1,$BNSZ($a0)
        +	$ADDU	$v0,$t9
        +	beqz	$a3,.L_bn_add_words_return
        +
        +	$LD	$t2,2*$BNSZ($a1)
        +	$LD	$ta2,2*$BNSZ($a2)
        +	$ADDU	$ta2,$t2
        +	sltu	$t8,$ta2,$t2
        +	$ADDU	$t2,$ta2,$v0
        +	sltu	$v0,$t2,$ta2
        +	$ST	$t2,2*$BNSZ($a0)
        +	$ADDU	$v0,$t8
        +
        +.L_bn_add_words_return:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +
        +.end	bn_add_words_internal
        +
        +.align	5
        +.globl	bn_sub_words
        +.ent	bn_sub_words
        +bn_sub_words:
        +	.set	noreorder
        +	bgtz	$a3,bn_sub_words_internal
        +	move	$v0,$zero
        +	jr	$ra
        +	move	$a0,$zero
        +.end	bn_sub_words
        +
        +.align	5
        +.ent	bn_sub_words_internal
        +bn_sub_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	li	$minus4,-4
        +	and	$at,$a3,$minus4
        +	$LD	$t0,0($a1)
        +	beqz	$at,.L_bn_sub_words_tail
        +
        +.L_bn_sub_words_loop:
        +	$LD	$ta0,0($a2)
        +	subu	$a3,4
        +	$LD	$t1,$BNSZ($a1)
        +	and	$at,$a3,$minus4
        +	$LD	$t2,2*$BNSZ($a1)
        +	$PTR_ADD $a2,4*$BNSZ
        +	$LD	$t3,3*$BNSZ($a1)
        +	$PTR_ADD $a0,4*$BNSZ
        +	$LD	$ta1,-3*$BNSZ($a2)
        +	$PTR_ADD $a1,4*$BNSZ
        +	$LD	$ta2,-2*$BNSZ($a2)
        +	$LD	$ta3,-$BNSZ($a2)
        +	sltu	$t8,$t0,$ta0
        +	$SUBU	$ta0,$t0,$ta0
        +	$SUBU	$t0,$ta0,$v0
        +	sgtu	$v0,$t0,$ta0
        +	$ST	$t0,-4*$BNSZ($a0)
        +	$ADDU	$v0,$t8
        +
        +	sltu	$t9,$t1,$ta1
        +	$SUBU	$ta1,$t1,$ta1
        +	$SUBU	$t1,$ta1,$v0
        +	sgtu	$v0,$t1,$ta1
        +	$ST	$t1,-3*$BNSZ($a0)
        +	$ADDU	$v0,$t9
        +
        +
        +	sltu	$t8,$t2,$ta2
        +	$SUBU	$ta2,$t2,$ta2
        +	$SUBU	$t2,$ta2,$v0
        +	sgtu	$v0,$t2,$ta2
        +	$ST	$t2,-2*$BNSZ($a0)
        +	$ADDU	$v0,$t8
        +
        +	sltu	$t9,$t3,$ta3
        +	$SUBU	$ta3,$t3,$ta3
        +	$SUBU	$t3,$ta3,$v0
        +	sgtu	$v0,$t3,$ta3
        +	$ST	$t3,-$BNSZ($a0)
        +	$ADDU	$v0,$t9
        +
        +	.set	noreorder
        +	bgtzl	$at,.L_bn_sub_words_loop
        +	$LD	$t0,0($a1)
        +
        +	beqz	$a3,.L_bn_sub_words_return
        +	nop
        +
        +.L_bn_sub_words_tail:
        +	.set	reorder
        +	$LD	$t0,0($a1)
        +	$LD	$ta0,0($a2)
        +	subu	$a3,1
        +	sltu	$t8,$t0,$ta0
        +	$SUBU	$ta0,$t0,$ta0
        +	$SUBU	$t0,$ta0,$v0
        +	sgtu	$v0,$t0,$ta0
        +	$ST	$t0,0($a0)
        +	$ADDU	$v0,$t8
        +	beqz	$a3,.L_bn_sub_words_return
        +
        +	$LD	$t1,$BNSZ($a1)
        +	subu	$a3,1
        +	$LD	$ta1,$BNSZ($a2)
        +	sltu	$t9,$t1,$ta1
        +	$SUBU	$ta1,$t1,$ta1
        +	$SUBU	$t1,$ta1,$v0
        +	sgtu	$v0,$t1,$ta1
        +	$ST	$t1,$BNSZ($a0)
        +	$ADDU	$v0,$t9
        +	beqz	$a3,.L_bn_sub_words_return
        +
        +	$LD	$t2,2*$BNSZ($a1)
        +	$LD	$ta2,2*$BNSZ($a2)
        +	sltu	$t8,$t2,$ta2
        +	$SUBU	$ta2,$t2,$ta2
        +	$SUBU	$t2,$ta2,$v0
        +	sgtu	$v0,$t2,$ta2
        +	$ST	$t2,2*$BNSZ($a0)
        +	$ADDU	$v0,$t8
        +
        +.L_bn_sub_words_return:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_sub_words_internal
        +
        +.align 5
        +.globl	bn_div_3_words
        +.ent	bn_div_3_words
        +bn_div_3_words:
        +	.set	noreorder
        +	move	$a3,$a0		# we know that bn_div_words does not
        +				# touch $a3, $ta2, $ta3 and preserves $a2
        +				# so that we can save two arguments
        +				# and return address in registers
        +				# instead of stack:-)
        +				
        +	$LD	$a0,($a3)
        +	move	$ta2,$a1
        +	bne	$a0,$a2,bn_div_3_words_internal
        +	$LD	$a1,-$BNSZ($a3)
        +	li	$v0,-1
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_div_3_words
        +
        +.align	5
        +.ent	bn_div_3_words_internal
        +bn_div_3_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	move	$ta3,$ra
        +	bal	bn_div_words_internal
        +	move	$ra,$ta3
        +	$MULTU	$ta2,$v0
        +	$LD	$t2,-2*$BNSZ($a3)
        +	move	$ta0,$zero
        +	mfhi	$t1
        +	mflo	$t0
        +	sltu	$t8,$t1,$a1
        +.L_bn_div_3_words_inner_loop:
        +	bnez	$t8,.L_bn_div_3_words_inner_loop_done
        +	sgeu	$at,$t2,$t0
        +	seq	$t9,$t1,$a1
        +	and	$at,$t9
        +	sltu	$t3,$t0,$ta2
        +	$ADDU	$a1,$a2
        +	$SUBU	$t1,$t3
        +	$SUBU	$t0,$ta2
        +	sltu	$t8,$t1,$a1
        +	sltu	$ta0,$a1,$a2
        +	or	$t8,$ta0
        +	.set	noreorder
        +	beqzl	$at,.L_bn_div_3_words_inner_loop
        +	$SUBU	$v0,1
        +	.set	reorder
        +.L_bn_div_3_words_inner_loop_done:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_div_3_words_internal
        +
        +.align	5
        +.globl	bn_div_words
        +.ent	bn_div_words
        +bn_div_words:
        +	.set	noreorder
        +	bnez	$a2,bn_div_words_internal
        +	li	$v0,-1		# I would rather signal div-by-zero
        +				# which can be done with 'break 7'
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_div_words
        +
        +.align	5
        +.ent	bn_div_words_internal
        +bn_div_words_internal:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	move	$v1,$zero
        +	bltz	$a2,.L_bn_div_words_body
        +	move	$t9,$v1
        +	$SLL	$a2,1
        +	bgtz	$a2,.-4
        +	addu	$t9,1
        +
        +	.set	reorder
        +	negu	$t1,$t9
        +	li	$t2,-1
        +	$SLL	$t2,$t1
        +	and	$t2,$a0
        +	$SRL	$at,$a1,$t1
        +	.set	noreorder
        +	bnezl	$t2,.+8
        +	break	6		# signal overflow
        +	.set	reorder
        +	$SLL	$a0,$t9
        +	$SLL	$a1,$t9
        +	or	$a0,$at
        +___
        +$QT=$ta0;
        +$HH=$ta1;
        +$DH=$v1;
        +$code.=<<___;
        +.L_bn_div_words_body:
        +	$SRL	$DH,$a2,4*$BNSZ	# bits
        +	sgeu	$at,$a0,$a2
        +	.set	noreorder
        +	bnezl	$at,.+8
        +	$SUBU	$a0,$a2
        +	.set	reorder
        +
        +	li	$QT,-1
        +	$SRL	$HH,$a0,4*$BNSZ	# bits
        +	$SRL	$QT,4*$BNSZ	# q=0xffffffff
        +	beq	$DH,$HH,.L_bn_div_words_skip_div1
        +	$DIVU	$zero,$a0,$DH
        +	mflo	$QT
        +.L_bn_div_words_skip_div1:
        +	$MULTU	$a2,$QT
        +	$SLL	$t3,$a0,4*$BNSZ	# bits
        +	$SRL	$at,$a1,4*$BNSZ	# bits
        +	or	$t3,$at
        +	mflo	$t0
        +	mfhi	$t1
        +.L_bn_div_words_inner_loop1:
        +	sltu	$t2,$t3,$t0
        +	seq	$t8,$HH,$t1
        +	sltu	$at,$HH,$t1
        +	and	$t2,$t8
        +	sltu	$v0,$t0,$a2
        +	or	$at,$t2
        +	.set	noreorder
        +	beqz	$at,.L_bn_div_words_inner_loop1_done
        +	$SUBU	$t1,$v0
        +	$SUBU	$t0,$a2
        +	b	.L_bn_div_words_inner_loop1
        +	$SUBU	$QT,1
        +	.set	reorder
        +.L_bn_div_words_inner_loop1_done:
        +
        +	$SLL	$a1,4*$BNSZ	# bits
        +	$SUBU	$a0,$t3,$t0
        +	$SLL	$v0,$QT,4*$BNSZ	# bits
        +
        +	li	$QT,-1
        +	$SRL	$HH,$a0,4*$BNSZ	# bits
        +	$SRL	$QT,4*$BNSZ	# q=0xffffffff
        +	beq	$DH,$HH,.L_bn_div_words_skip_div2
        +	$DIVU	$zero,$a0,$DH
        +	mflo	$QT
        +.L_bn_div_words_skip_div2:
        +	$MULTU	$a2,$QT
        +	$SLL	$t3,$a0,4*$BNSZ	# bits
        +	$SRL	$at,$a1,4*$BNSZ	# bits
        +	or	$t3,$at
        +	mflo	$t0
        +	mfhi	$t1
        +.L_bn_div_words_inner_loop2:
        +	sltu	$t2,$t3,$t0
        +	seq	$t8,$HH,$t1
        +	sltu	$at,$HH,$t1
        +	and	$t2,$t8
        +	sltu	$v1,$t0,$a2
        +	or	$at,$t2
        +	.set	noreorder
        +	beqz	$at,.L_bn_div_words_inner_loop2_done
        +	$SUBU	$t1,$v1
        +	$SUBU	$t0,$a2
        +	b	.L_bn_div_words_inner_loop2
        +	$SUBU	$QT,1
        +	.set	reorder
        +.L_bn_div_words_inner_loop2_done:
        +
        +	$SUBU	$a0,$t3,$t0
        +	or	$v0,$QT
        +	$SRL	$v1,$a0,$t9	# $v1 contains remainder if anybody wants it
        +	$SRL	$a2,$t9		# restore $a2
        +
        +	.set	noreorder
        +	move	$a1,$v1
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	move	$a0,$v0
        +.end	bn_div_words_internal
        +___
        +undef $HH; undef $QT; undef $DH;
        +
        +($a_0,$a_1,$a_2,$a_3)=($t0,$t1,$t2,$t3);
        +($b_0,$b_1,$b_2,$b_3)=($ta0,$ta1,$ta2,$ta3);
        +
        +($a_4,$a_5,$a_6,$a_7)=($s0,$s2,$s4,$a1); # once we load a[7], no use for $a1
        +($b_4,$b_5,$b_6,$b_7)=($s1,$s3,$s5,$a2); # once we load b[7], no use for $a2
        +
        +($t_1,$t_2,$c_1,$c_2,$c_3)=($t8,$t9,$v0,$v1,$a3);
        +
        +$code.=<<___;
        +
        +.align	5
        +.globl	bn_mul_comba8
        +.ent	bn_mul_comba8
        +bn_mul_comba8:
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,12*$SZREG,$ra
        +	.mask	0x803ff008,-$SZREG
        +	$PTR_SUB $sp,12*$SZREG
        +	$REG_S	$ra,11*$SZREG($sp)
        +	$REG_S	$s5,10*$SZREG($sp)
        +	$REG_S	$s4,9*$SZREG($sp)
        +	$REG_S	$s3,8*$SZREG($sp)
        +	$REG_S	$s2,7*$SZREG($sp)
        +	$REG_S	$s1,6*$SZREG($sp)
        +	$REG_S	$s0,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour !~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x003f0000,-$SZREG
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$s5,5*$SZREG($sp)
        +	$REG_S	$s4,4*$SZREG($sp)
        +	$REG_S	$s3,3*$SZREG($sp)
        +	$REG_S	$s2,2*$SZREG($sp)
        +	$REG_S	$s1,1*$SZREG($sp)
        +	$REG_S	$s0,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +
        +	.set	reorder
        +	$LD	$a_0,0($a1)	# If compiled with -mips3 option on
        +				# R5000 box assembler barks on this
        +				# 1ine with "should not have mult/div
        +				# as last instruction in bb (R10K
        +				# bug)" warning. If anybody out there
        +				# has a clue about how to circumvent
        +				# this do send me a note.
        +				#		<appro\@fy.chalmers.se>
        +
        +	$LD	$b_0,0($a2)
        +	$LD	$a_1,$BNSZ($a1)
        +	$LD	$a_2,2*$BNSZ($a1)
        +	$MULTU	$a_0,$b_0		# mul_add_c(a[0],b[0],c1,c2,c3);
        +	$LD	$a_3,3*$BNSZ($a1)
        +	$LD	$b_1,$BNSZ($a2)
        +	$LD	$b_2,2*$BNSZ($a2)
        +	$LD	$b_3,3*$BNSZ($a2)
        +	mflo	$c_1
        +	mfhi	$c_2
        +
        +	$LD	$a_4,4*$BNSZ($a1)
        +	$LD	$a_5,5*$BNSZ($a1)
        +	$MULTU	$a_0,$b_1		# mul_add_c(a[0],b[1],c2,c3,c1);
        +	$LD	$a_6,6*$BNSZ($a1)
        +	$LD	$a_7,7*$BNSZ($a1)
        +	$LD	$b_4,4*$BNSZ($a2)
        +	$LD	$b_5,5*$BNSZ($a2)
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_1,$b_0		# mul_add_c(a[1],b[0],c2,c3,c1);
        +	$ADDU	$c_3,$t_2,$at
        +	$LD	$b_6,6*$BNSZ($a2)
        +	$LD	$b_7,7*$BNSZ($a2)
        +	$ST	$c_1,0($a0)	# r[0]=c1;
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_2,$b_0		# mul_add_c(a[2],b[0],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	$ST	$c_2,$BNSZ($a0)	# r[1]=c2;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_1,$b_1		# mul_add_c(a[1],b[1],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_0,$b_2		# mul_add_c(a[0],b[2],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$c_2,$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_0,$b_3		# mul_add_c(a[0],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,2*$BNSZ($a0)	# r[2]=c3;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_1,$b_2		# mul_add_c(a[1],b[2],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$c_3,$c_2,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_2,$b_1		# mul_add_c(a[2],b[1],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_3,$b_0		# mul_add_c(a[3],b[0],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_4,$b_0		# mul_add_c(a[4],b[0],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,3*$BNSZ($a0)	# r[3]=c1;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_3,$b_1		# mul_add_c(a[3],b[1],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_2,$b_2		# mul_add_c(a[2],b[2],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_1,$b_3		# mul_add_c(a[1],b[3],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_0,$b_4		# mul_add_c(a[0],b[4],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_0,$b_5		# mul_add_c(a[0],b[5],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,4*$BNSZ($a0)	# r[4]=c2;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_1,$b_4		# mul_add_c(a[1],b[4],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$c_2,$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_2,$b_3		# mul_add_c(a[2],b[3],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_3,$b_2		# mul_add_c(a[3],b[2],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_4,$b_1		# mul_add_c(a[4],b[1],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_5,$b_0		# mul_add_c(a[5],b[0],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_6,$b_0		# mul_add_c(a[6],b[0],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,5*$BNSZ($a0)	# r[5]=c3;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_5,$b_1		# mul_add_c(a[5],b[1],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$c_3,$c_2,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_4,$b_2		# mul_add_c(a[4],b[2],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_3,$b_3		# mul_add_c(a[3],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_2,$b_4		# mul_add_c(a[2],b[4],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_1,$b_5		# mul_add_c(a[1],b[5],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_0,$b_6		# mul_add_c(a[0],b[6],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_0,$b_7		# mul_add_c(a[0],b[7],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,6*$BNSZ($a0)	# r[6]=c1;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_1,$b_6		# mul_add_c(a[1],b[6],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_2,$b_5		# mul_add_c(a[2],b[5],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_3,$b_4		# mul_add_c(a[3],b[4],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_4,$b_3		# mul_add_c(a[4],b[3],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_5,$b_2		# mul_add_c(a[5],b[2],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_6,$b_1		# mul_add_c(a[6],b[1],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_7,$b_0		# mul_add_c(a[7],b[0],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_7,$b_1		# mul_add_c(a[7],b[1],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,7*$BNSZ($a0)	# r[7]=c2;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_6,$b_2		# mul_add_c(a[6],b[2],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$c_2,$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_5,$b_3		# mul_add_c(a[5],b[3],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_4,$b_4		# mul_add_c(a[4],b[4],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_3,$b_5		# mul_add_c(a[3],b[5],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_2,$b_6		# mul_add_c(a[2],b[6],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_1,$b_7		# mul_add_c(a[1],b[7],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_2,$b_7		# mul_add_c(a[2],b[7],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,8*$BNSZ($a0)	# r[8]=c3;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_3,$b_6		# mul_add_c(a[3],b[6],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$c_3,$c_2,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_4,$b_5		# mul_add_c(a[4],b[5],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_5,$b_4		# mul_add_c(a[5],b[4],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_6,$b_3		# mul_add_c(a[6],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_7,$b_2		# mul_add_c(a[7],b[2],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_7,$b_3		# mul_add_c(a[7],b[3],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,9*$BNSZ($a0)	# r[9]=c1;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_6,$b_4		# mul_add_c(a[6],b[4],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_5,$b_5		# mul_add_c(a[5],b[5],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_4,$b_6		# mul_add_c(a[4],b[6],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_3,$b_7		# mul_add_c(a[3],b[7],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_4,$b_7		# mul_add_c(a[4],b[7],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,10*$BNSZ($a0)	# r[10]=c2;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_5,$b_6		# mul_add_c(a[5],b[6],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$c_2,$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_6,$b_5		# mul_add_c(a[6],b[5],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_7,$b_4		# mul_add_c(a[7],b[4],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_7,$b_5		# mul_add_c(a[7],b[5],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,11*$BNSZ($a0)	# r[11]=c3;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_6,$b_6		# mul_add_c(a[6],b[6],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$c_3,$c_2,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_5,$b_7		# mul_add_c(a[5],b[7],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_6,$b_7		# mul_add_c(a[6],b[7],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,12*$BNSZ($a0)	# r[12]=c1;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_7,$b_6		# mul_add_c(a[7],b[6],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_7,$b_7		# mul_add_c(a[7],b[7],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,13*$BNSZ($a0)	# r[13]=c2;
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	$ST	$c_3,14*$BNSZ($a0)	# r[14]=c3;
        +	$ST	$c_1,15*$BNSZ($a0)	# r[15]=c1;
        +
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$s5,10*$SZREG($sp)
        +	$REG_L	$s4,9*$SZREG($sp)
        +	$REG_L	$s3,8*$SZREG($sp)
        +	$REG_L	$s2,7*$SZREG($sp)
        +	$REG_L	$s1,6*$SZREG($sp)
        +	$REG_L	$s0,5*$SZREG($sp)
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	jr	$ra
        +	$PTR_ADD $sp,12*$SZREG
        +___
        +$code.=<<___ if ($flavour !~ /nubi/i);
        +	$REG_L	$s5,5*$SZREG($sp)
        +	$REG_L	$s4,4*$SZREG($sp)
        +	$REG_L	$s3,3*$SZREG($sp)
        +	$REG_L	$s2,2*$SZREG($sp)
        +	$REG_L	$s1,1*$SZREG($sp)
        +	$REG_L	$s0,0*$SZREG($sp)
        +	jr	$ra
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +.end	bn_mul_comba8
        +
        +.align	5
        +.globl	bn_mul_comba4
        +.ent	bn_mul_comba4
        +bn_mul_comba4:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	$LD	$a_0,0($a1)
        +	$LD	$b_0,0($a2)
        +	$LD	$a_1,$BNSZ($a1)
        +	$LD	$a_2,2*$BNSZ($a1)
        +	$MULTU	$a_0,$b_0		# mul_add_c(a[0],b[0],c1,c2,c3);
        +	$LD	$a_3,3*$BNSZ($a1)
        +	$LD	$b_1,$BNSZ($a2)
        +	$LD	$b_2,2*$BNSZ($a2)
        +	$LD	$b_3,3*$BNSZ($a2)
        +	mflo	$c_1
        +	mfhi	$c_2
        +	$ST	$c_1,0($a0)
        +
        +	$MULTU	$a_0,$b_1		# mul_add_c(a[0],b[1],c2,c3,c1);
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_1,$b_0		# mul_add_c(a[1],b[0],c2,c3,c1);
        +	$ADDU	$c_3,$t_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_2,$b_0		# mul_add_c(a[2],b[0],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	$ST	$c_2,$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_1,$b_1		# mul_add_c(a[1],b[1],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_0,$b_2		# mul_add_c(a[0],b[2],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$c_2,$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_0,$b_3		# mul_add_c(a[0],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,2*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_1,$b_2		# mul_add_c(a[1],b[2],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$c_3,$c_2,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_2,$b_1		# mul_add_c(a[2],b[1],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$MULTU	$a_3,$b_0		# mul_add_c(a[3],b[0],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_3,$b_1		# mul_add_c(a[3],b[1],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,3*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_2,$b_2		# mul_add_c(a[2],b[2],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$c_1,$c_3,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$MULTU	$a_1,$b_3		# mul_add_c(a[1],b[3],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_2,$b_3		# mul_add_c(a[2],b[3],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,4*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$MULTU	$a_3,$b_2		# mul_add_c(a[3],b[2],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$c_2,$c_1,$t_2
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_3,$b_3		# mul_add_c(a[3],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,5*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	$ST	$c_1,6*$BNSZ($a0)
        +	$ST	$c_2,7*$BNSZ($a0)
        +
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	nop
        +.end	bn_mul_comba4
        +___
        +
        +($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
        +
        +$code.=<<___;
        +
        +.align	5
        +.globl	bn_sqr_comba8
        +.ent	bn_sqr_comba8
        +bn_sqr_comba8:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	$LD	$a_0,0($a1)
        +	$LD	$a_1,$BNSZ($a1)
        +	$LD	$a_2,2*$BNSZ($a1)
        +	$LD	$a_3,3*$BNSZ($a1)
        +
        +	$MULTU	$a_0,$a_0		# mul_add_c(a[0],b[0],c1,c2,c3);
        +	$LD	$a_4,4*$BNSZ($a1)
        +	$LD	$a_5,5*$BNSZ($a1)
        +	$LD	$a_6,6*$BNSZ($a1)
        +	$LD	$a_7,7*$BNSZ($a1)
        +	mflo	$c_1
        +	mfhi	$c_2
        +	$ST	$c_1,0($a0)
        +
        +	$MULTU	$a_0,$a_1		# mul_add_c2(a[0],b[1],c2,c3,c1);
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	 $MULTU	$a_2,$a_0		# mul_add_c2(a[2],b[0],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$c_3,$t_2,$at
        +	$ST	$c_2,$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_2,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_1,$a_1		# mul_add_c(a[1],b[1],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_0,$a_3		# mul_add_c2(a[0],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,2*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_3,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_1,$a_2		# mul_add_c2(a[1],b[2],c1,c2,c3);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_3,$at
        +	 $MULTU	$a_4,$a_0		# mul_add_c2(a[4],b[0],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,3*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_3,$a_1		# mul_add_c2(a[3],b[1],c2,c3,c1);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_1,$at
        +	$MULTU	$a_2,$a_2		# mul_add_c(a[2],b[2],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_0,$a_5		# mul_add_c2(a[0],b[5],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,4*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_2,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_1,$a_4		# mul_add_c2(a[1],b[4],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_2,$at
        +	$MULTU	$a_2,$a_3		# mul_add_c2(a[2],b[3],c3,c1,c2);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	 $MULTU	$a_6,$a_0		# mul_add_c2(a[6],b[0],c1,c2,c3);
        +	$ADDU	$c_2,$at
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,5*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_3,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_5,$a_1		# mul_add_c2(a[5],b[1],c1,c2,c3);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_3,$at
        +	$MULTU	$a_4,$a_2		# mul_add_c2(a[4],b[2],c1,c2,c3);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_3,$at
        +	$MULTU	$a_3,$a_3		# mul_add_c(a[3],b[3],c1,c2,c3);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_0,$a_7		# mul_add_c2(a[0],b[7],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,6*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_1,$a_6		# mul_add_c2(a[1],b[6],c2,c3,c1);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_1,$at
        +	$MULTU	$a_2,$a_5		# mul_add_c2(a[2],b[5],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_1,$at
        +	$MULTU	$a_3,$a_4		# mul_add_c2(a[3],b[4],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_1,$at
        +	 $MULTU	$a_7,$a_1		# mul_add_c2(a[7],b[1],c3,c1,c2);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,7*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_2,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_6,$a_2		# mul_add_c2(a[6],b[2],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_2,$at
        +	$MULTU	$a_5,$a_3		# mul_add_c2(a[5],b[3],c3,c1,c2);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_2,$at
        +	$MULTU	$a_4,$a_4		# mul_add_c(a[4],b[4],c3,c1,c2);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_2,$a_7		# mul_add_c2(a[2],b[7],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,8*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_3,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_3,$a_6		# mul_add_c2(a[3],b[6],c1,c2,c3);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_3,$at
        +	$MULTU	$a_4,$a_5		# mul_add_c2(a[4],b[5],c1,c2,c3);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_3,$at
        +	 $MULTU	$a_7,$a_3		# mul_add_c2(a[7],b[3],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,9*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_6,$a_4		# mul_add_c2(a[6],b[4],c2,c3,c1);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_1,$at
        +	$MULTU	$a_5,$a_5		# mul_add_c(a[5],b[5],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_4,$a_7		# mul_add_c2(a[4],b[7],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,10*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_2,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_5,$a_6		# mul_add_c2(a[5],b[6],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_2,$at
        +	 $MULTU	$a_7,$a_5		# mul_add_c2(a[7],b[5],c1,c2,c3);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,11*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_3,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_6,$a_6		# mul_add_c(a[6],b[6],c1,c2,c3);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	 $MULTU	$a_6,$a_7		# mul_add_c2(a[6],b[7],c2,c3,c1);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,12*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	 $MULTU	$a_7,$a_7		# mul_add_c(a[7],b[7],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,13*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	$ST	$c_3,14*$BNSZ($a0)
        +	$ST	$c_1,15*$BNSZ($a0)
        +
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	nop
        +.end	bn_sqr_comba8
        +
        +.align	5
        +.globl	bn_sqr_comba4
        +.ent	bn_sqr_comba4
        +bn_sqr_comba4:
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	.frame	$sp,6*$SZREG,$ra
        +	.mask	0x8000f008,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,6*$SZREG
        +	$REG_S	$ra,5*$SZREG($sp)
        +	$REG_S	$t3,4*$SZREG($sp)
        +	$REG_S	$t2,3*$SZREG($sp)
        +	$REG_S	$t1,2*$SZREG($sp)
        +	$REG_S	$t0,1*$SZREG($sp)
        +	$REG_S	$gp,0*$SZREG($sp)
        +___
        +$code.=<<___;
        +	.set	reorder
        +	$LD	$a_0,0($a1)
        +	$LD	$a_1,$BNSZ($a1)
        +	$MULTU	$a_0,$a_0		# mul_add_c(a[0],b[0],c1,c2,c3);
        +	$LD	$a_2,2*$BNSZ($a1)
        +	$LD	$a_3,3*$BNSZ($a1)
        +	mflo	$c_1
        +	mfhi	$c_2
        +	$ST	$c_1,0($a0)
        +
        +	$MULTU	$a_0,$a_1		# mul_add_c2(a[0],b[1],c2,c3,c1);
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	 $MULTU	$a_2,$a_0		# mul_add_c2(a[2],b[0],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$c_3,$t_2,$at
        +	$ST	$c_2,$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_2,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_1,$a_1		# mul_add_c(a[1],b[1],c3,c1,c2);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	 $MULTU	$a_0,$a_3		# mul_add_c2(a[0],b[3],c1,c2,c3);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,2*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_3,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_1,$a_2		# mul_add_c(a2[1],b[2],c1,c2,c3);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$at,$t_2,$zero
        +	$ADDU	$c_3,$at
        +	 $MULTU	$a_3,$a_1		# mul_add_c2(a[3],b[1],c2,c3,c1);
        +	$SLL	$t_2,1
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	sltu	$at,$c_2,$t_2
        +	$ADDU	$c_3,$at
        +	$ST	$c_1,3*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_1,$t_2,$zero
        +	$SLL	$t_2,1
        +	$MULTU	$a_2,$a_2		# mul_add_c(a[2],b[2],c2,c3,c1);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_2,$t_1
        +	sltu	$at,$c_2,$t_1
        +	 $MULTU	$a_2,$a_3		# mul_add_c2(a[2],b[3],c3,c1,c2);
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_3,$t_2
        +	sltu	$at,$c_3,$t_2
        +	$ADDU	$c_1,$at
        +	$ST	$c_2,4*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	slt	$c_2,$t_2,$zero
        +	$SLL	$t_2,1
        +	 $MULTU	$a_3,$a_3		# mul_add_c(a[3],b[3],c1,c2,c3);
        +	slt	$a2,$t_1,$zero
        +	$ADDU	$t_2,$a2
        +	$SLL	$t_1,1
        +	$ADDU	$c_3,$t_1
        +	sltu	$at,$c_3,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_1,$t_2
        +	sltu	$at,$c_1,$t_2
        +	$ADDU	$c_2,$at
        +	$ST	$c_3,5*$BNSZ($a0)
        +
        +	mflo	$t_1
        +	mfhi	$t_2
        +	$ADDU	$c_1,$t_1
        +	sltu	$at,$c_1,$t_1
        +	$ADDU	$t_2,$at
        +	$ADDU	$c_2,$t_2
        +	$ST	$c_1,6*$BNSZ($a0)
        +	$ST	$c_2,7*$BNSZ($a0)
        +
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$t3,4*$SZREG($sp)
        +	$REG_L	$t2,3*$SZREG($sp)
        +	$REG_L	$t1,2*$SZREG($sp)
        +	$REG_L	$t0,1*$SZREG($sp)
        +	$REG_L	$gp,0*$SZREG($sp)
        +	$PTR_ADD $sp,6*$SZREG
        +___
        +$code.=<<___;
        +	jr	$ra
        +	nop
        +.end	bn_sqr_comba4
        +___
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/mips3-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/mips3-mont.pl
        new file mode 100644
        index 000000000..8f9156e02
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/mips3-mont.pl
        @@ -0,0 +1,327 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# This module doesn't present direct interest for OpenSSL, because it
        +# doesn't provide better performance for longer keys. While 512-bit
        +# RSA private key operations are 40% faster, 1024-bit ones are hardly
        +# faster at all, while longer key operations are slower by up to 20%.
        +# It might be of interest to embedded system developers though, as
        +# it's smaller than 1KB, yet offers ~3x improvement over compiler
        +# generated code.
        +#
        +# The module targets N32 and N64 MIPS ABIs and currently is a bit
        +# IRIX-centric, i.e. is likely to require adaptation for other OSes.
        +
        +# int bn_mul_mont(
        +$rp="a0";	# BN_ULONG *rp,
        +$ap="a1";	# const BN_ULONG *ap,
        +$bp="a2";	# const BN_ULONG *bp,
        +$np="a3";	# const BN_ULONG *np,
        +$n0="a4";	# const BN_ULONG *n0,
        +$num="a5";	# int num);
        +
        +$lo0="a6";
        +$hi0="a7";
        +$lo1="v0";
        +$hi1="v1";
        +$aj="t0";
        +$bi="t1";
        +$nj="t2";
        +$tp="t3";
        +$alo="s0";
        +$ahi="s1";
        +$nlo="s2";
        +$nhi="s3";
        +$tj="s4";
        +$i="s5";
        +$j="s6";
        +$fp="t8";
        +$m1="t9";
        +
        +$FRAME=8*(2+8);
        +
        +$code=<<___;
        +#include <asm.h>
        +#include <regdef.h>
        +
        +.text
        +
        +.set	noat
        +.set	reorder
        +
        +.align	5
        +.globl	bn_mul_mont
        +.ent	bn_mul_mont
        +bn_mul_mont:
        +	.set	noreorder
        +	PTR_SUB	sp,64
        +	move	$fp,sp
        +	.frame	$fp,64,ra
        +	slt	AT,$num,4
        +	li	v0,0
        +	beqzl	AT,.Lproceed
        +	nop
        +	jr	ra
        +	PTR_ADD	sp,$fp,64
        +	.set	reorder
        +.align	5
        +.Lproceed:
        +	ld	$n0,0($n0)
        +	ld	$bi,0($bp)	# bp[0]
        +	ld	$aj,0($ap)	# ap[0]
        +	ld	$nj,0($np)	# np[0]
        +	PTR_SUB	sp,16		# place for two extra words
        +	sll	$num,3
        +	li	AT,-4096
        +	PTR_SUB	sp,$num
        +	and	sp,AT
        +
        +	sd	s0,0($fp)
        +	sd	s1,8($fp)
        +	sd	s2,16($fp)
        +	sd	s3,24($fp)
        +	sd	s4,32($fp)
        +	sd	s5,40($fp)
        +	sd	s6,48($fp)
        +	sd	s7,56($fp)
        +
        +	dmultu	$aj,$bi
        +	ld	$alo,8($ap)
        +	ld	$nlo,8($np)
        +	mflo	$lo0
        +	mfhi	$hi0
        +	dmultu	$lo0,$n0
        +	mflo	$m1
        +
        +	dmultu	$alo,$bi
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	dmultu	$nj,$m1
        +	mflo	$lo1
        +	mfhi	$hi1
        +	dmultu	$nlo,$m1
        +	daddu	$lo1,$lo0
        +	sltu	AT,$lo1,$lo0
        +	daddu	$hi1,AT
        +	mflo	$nlo
        +	mfhi	$nhi
        +
        +	move	$tp,sp
        +	li	$j,16
        +.align	4
        +.L1st:
        +	.set	noreorder
        +	PTR_ADD	$aj,$ap,$j
        +	ld	$aj,($aj)
        +	PTR_ADD	$nj,$np,$j
        +	ld	$nj,($nj)
        +
        +	dmultu	$aj,$bi
        +	daddu	$lo0,$alo,$hi0
        +	daddu	$lo1,$nlo,$hi1
        +	sltu	AT,$lo0,$hi0
        +	sltu	s7,$lo1,$hi1
        +	daddu	$hi0,$ahi,AT
        +	daddu	$hi1,$nhi,s7
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	daddu	$lo1,$lo0
        +	sltu	AT,$lo1,$lo0
        +	dmultu	$nj,$m1
        +	daddu	$hi1,AT
        +	addu	$j,8
        +	sd	$lo1,($tp)
        +	sltu	s7,$j,$num
        +	mflo	$nlo
        +	mfhi	$nhi
        +
        +	bnez	s7,.L1st
        +	PTR_ADD	$tp,8
        +	.set	reorder
        +
        +	daddu	$lo0,$alo,$hi0
        +	sltu	AT,$lo0,$hi0
        +	daddu	$hi0,$ahi,AT
        +
        +	daddu	$lo1,$nlo,$hi1
        +	sltu	s7,$lo1,$hi1
        +	daddu	$hi1,$nhi,s7
        +	daddu	$lo1,$lo0
        +	sltu	AT,$lo1,$lo0
        +	daddu	$hi1,AT
        +
        +	sd	$lo1,($tp)
        +
        +	daddu	$hi1,$hi0
        +	sltu	AT,$hi1,$hi0
        +	sd	$hi1,8($tp)
        +	sd	AT,16($tp)
        +
        +	li	$i,8
        +.align	4
        +.Louter:
        +	PTR_ADD	$bi,$bp,$i
        +	ld	$bi,($bi)
        +	ld	$aj,($ap)
        +	ld	$alo,8($ap)
        +	ld	$tj,(sp)
        +
        +	dmultu	$aj,$bi
        +	ld	$nj,($np)
        +	ld	$nlo,8($np)
        +	mflo	$lo0
        +	mfhi	$hi0
        +	daddu	$lo0,$tj
        +	dmultu	$lo0,$n0
        +	sltu	AT,$lo0,$tj
        +	daddu	$hi0,AT
        +	mflo	$m1
        +
        +	dmultu	$alo,$bi
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	dmultu	$nj,$m1
        +	mflo	$lo1
        +	mfhi	$hi1
        +
        +	dmultu	$nlo,$m1
        +	daddu	$lo1,$lo0
        +	sltu	AT,$lo1,$lo0
        +	daddu	$hi1,AT
        +	mflo	$nlo
        +	mfhi	$nhi
        +
        +	move	$tp,sp
        +	li	$j,16
        +	ld	$tj,8($tp)
        +.align	4
        +.Linner:
        +	.set	noreorder
        +	PTR_ADD	$aj,$ap,$j
        +	ld	$aj,($aj)
        +	PTR_ADD	$nj,$np,$j
        +	ld	$nj,($nj)
        +
        +	dmultu	$aj,$bi
        +	daddu	$lo0,$alo,$hi0
        +	daddu	$lo1,$nlo,$hi1
        +	sltu	AT,$lo0,$hi0
        +	sltu	s7,$lo1,$hi1
        +	daddu	$hi0,$ahi,AT
        +	daddu	$hi1,$nhi,s7
        +	mflo	$alo
        +	mfhi	$ahi
        +
        +	daddu	$lo0,$tj
        +	addu	$j,8
        +	dmultu	$nj,$m1
        +	sltu	AT,$lo0,$tj
        +	daddu	$lo1,$lo0
        +	daddu	$hi0,AT
        +	sltu	s7,$lo1,$lo0
        +	ld	$tj,16($tp)
        +	daddu	$hi1,s7
        +	sltu	AT,$j,$num
        +	mflo	$nlo
        +	mfhi	$nhi
        +	sd	$lo1,($tp)
        +	bnez	AT,.Linner
        +	PTR_ADD	$tp,8
        +	.set	reorder
        +
        +	daddu	$lo0,$alo,$hi0
        +	sltu	AT,$lo0,$hi0
        +	daddu	$hi0,$ahi,AT
        +	daddu	$lo0,$tj
        +	sltu	s7,$lo0,$tj
        +	daddu	$hi0,s7
        +
        +	ld	$tj,16($tp)
        +	daddu	$lo1,$nlo,$hi1
        +	sltu	AT,$lo1,$hi1
        +	daddu	$hi1,$nhi,AT
        +	daddu	$lo1,$lo0
        +	sltu	s7,$lo1,$lo0
        +	daddu	$hi1,s7
        +	sd	$lo1,($tp)
        +
        +	daddu	$lo1,$hi1,$hi0
        +	sltu	$hi1,$lo1,$hi0
        +	daddu	$lo1,$tj
        +	sltu	AT,$lo1,$tj
        +	daddu	$hi1,AT
        +	sd	$lo1,8($tp)
        +	sd	$hi1,16($tp)
        +
        +	addu	$i,8
        +	sltu	s7,$i,$num
        +	bnez	s7,.Louter
        +
        +	.set	noreorder
        +	PTR_ADD	$tj,sp,$num	# &tp[num]
        +	move	$tp,sp
        +	move	$ap,sp
        +	li	$hi0,0		# clear borrow bit
        +
        +.align	4
        +.Lsub:	ld	$lo0,($tp)
        +	ld	$lo1,($np)
        +	PTR_ADD	$tp,8
        +	PTR_ADD	$np,8
        +	dsubu	$lo1,$lo0,$lo1	# tp[i]-np[i]
        +	sgtu	AT,$lo1,$lo0
        +	dsubu	$lo0,$lo1,$hi0
        +	sgtu	$hi0,$lo0,$lo1
        +	sd	$lo0,($rp)
        +	or	$hi0,AT
        +	sltu	AT,$tp,$tj
        +	bnez	AT,.Lsub
        +	PTR_ADD	$rp,8
        +
        +	dsubu	$hi0,$hi1,$hi0	# handle upmost overflow bit
        +	move	$tp,sp
        +	PTR_SUB	$rp,$num	# restore rp
        +	not	$hi1,$hi0
        +
        +	and	$ap,$hi0,sp
        +	and	$bp,$hi1,$rp
        +	or	$ap,$ap,$bp	# ap=borrow?tp:rp
        +
        +.align	4
        +.Lcopy:	ld	$aj,($ap)
        +	PTR_ADD	$ap,8
        +	PTR_ADD	$tp,8
        +	sd	zero,-8($tp)
        +	sltu	AT,$tp,$tj
        +	sd	$aj,($rp)
        +	bnez	AT,.Lcopy
        +	PTR_ADD	$rp,8
        +
        +	ld	s0,0($fp)
        +	ld	s1,8($fp)
        +	ld	s2,16($fp)
        +	ld	s3,24($fp)
        +	ld	s4,32($fp)
        +	ld	s5,40($fp)
        +	ld	s6,48($fp)
        +	ld	s7,56($fp)
        +	li	v0,1
        +	jr	ra
        +	PTR_ADD	sp,$fp,64
        +	.set	reorder
        +END(bn_mul_mont)
        +.rdata
        +.asciiz	"Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/mips3.s b/vendor/openssl/openssl/crypto/bn/asm/mips3.s
        new file mode 100644
        index 000000000..dca4105c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/mips3.s
        @@ -0,0 +1,2201 @@
        +.rdata
        +.asciiz	"mips3.s, Version 1.1"
        +.asciiz	"MIPS III/IV ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
        +
        +/*
        + * ====================================================================
        + * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        + * project.
        + *
        + * Rights for redistribution and usage in source and binary forms are
        + * granted according to the OpenSSL license. Warranty of any kind is
        + * disclaimed.
        + * ====================================================================
        + */
        +
        +/*
        + * This is my modest contributon to the OpenSSL project (see
        + * http://www.openssl.org/ for more information about it) and is
        + * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c
        + * module. For updates see http://fy.chalmers.se/~appro/hpe/.
        + *
        + * The module is designed to work with either of the "new" MIPS ABI(5),
        + * namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
        + * IRIX 5.x not only because it doesn't support new ABIs but also
        + * because 5.x kernels put R4x00 CPU into 32-bit mode and all those
        + * 64-bit instructions (daddu, dmultu, etc.) found below gonna only
        + * cause illegal instruction exception:-(
        + *
        + * In addition the code depends on preprocessor flags set up by MIPSpro
        + * compiler driver (either as or cc) and therefore (probably?) can't be
        + * compiled by the GNU assembler. GNU C driver manages fine though...
        + * I mean as long as -mmips-as is specified or is the default option,
        + * because then it simply invokes /usr/bin/as which in turn takes
        + * perfect care of the preprocessor definitions. Another neat feature
        + * offered by the MIPSpro assembler is an optimization pass. This gave
        + * me the opportunity to have the code looking more regular as all those
        + * architecture dependent instruction rescheduling details were left to
        + * the assembler. Cool, huh?
        + *
        + * Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
        + * goes way over 3 times faster!
        + *
        + *					<appro@fy.chalmers.se>
        + */
        +#include <asm.h>
        +#include <regdef.h>
        +
        +#if _MIPS_ISA>=4
        +#define	MOVNZ(cond,dst,src)	\
        +	movn	dst,src,cond
        +#else
        +#define	MOVNZ(cond,dst,src)	\
        +	.set	noreorder;	\
        +	bnezl	cond,.+8;	\
        +	move	dst,src;	\
        +	.set	reorder
        +#endif
        +
        +.text
        +
        +.set	noat
        +.set	reorder
        +
        +#define	MINUS4	v1
        +
        +.align	5
        +LEAF(bn_mul_add_words)
        +	.set	noreorder
        +	bgtzl	a2,.L_bn_mul_add_words_proceed
        +	ld	t0,0(a1)
        +	jr	ra
        +	move	v0,zero
        +	.set	reorder
        +
        +.L_bn_mul_add_words_proceed:
        +	li	MINUS4,-4
        +	and	ta0,a2,MINUS4
        +	move	v0,zero
        +	beqz	ta0,.L_bn_mul_add_words_tail
        +
        +.L_bn_mul_add_words_loop:
        +	dmultu	t0,a3
        +	ld	t1,0(a0)
        +	ld	t2,8(a1)
        +	ld	t3,8(a0)
        +	ld	ta0,16(a1)
        +	ld	ta1,16(a0)
        +	daddu	t1,v0
        +	sltu	v0,t1,v0	/* All manuals say it "compares 32-bit
        +				 * values", but it seems to work fine
        +				 * even on 64-bit registers. */
        +	mflo	AT
        +	mfhi	t0
        +	daddu	t1,AT
        +	daddu	v0,t0
        +	sltu	AT,t1,AT
        +	sd	t1,0(a0)
        +	daddu	v0,AT
        +
        +	dmultu	t2,a3
        +	ld	ta2,24(a1)
        +	ld	ta3,24(a0)
        +	daddu	t3,v0
        +	sltu	v0,t3,v0
        +	mflo	AT
        +	mfhi	t2
        +	daddu	t3,AT
        +	daddu	v0,t2
        +	sltu	AT,t3,AT
        +	sd	t3,8(a0)
        +	daddu	v0,AT
        +
        +	dmultu	ta0,a3
        +	subu	a2,4
        +	PTR_ADD	a0,32
        +	PTR_ADD	a1,32
        +	daddu	ta1,v0
        +	sltu	v0,ta1,v0
        +	mflo	AT
        +	mfhi	ta0
        +	daddu	ta1,AT
        +	daddu	v0,ta0
        +	sltu	AT,ta1,AT
        +	sd	ta1,-16(a0)
        +	daddu	v0,AT
        +
        +
        +	dmultu	ta2,a3
        +	and	ta0,a2,MINUS4
        +	daddu	ta3,v0
        +	sltu	v0,ta3,v0
        +	mflo	AT
        +	mfhi	ta2
        +	daddu	ta3,AT
        +	daddu	v0,ta2
        +	sltu	AT,ta3,AT
        +	sd	ta3,-8(a0)
        +	daddu	v0,AT
        +	.set	noreorder
        +	bgtzl	ta0,.L_bn_mul_add_words_loop
        +	ld	t0,0(a1)
        +
        +	bnezl	a2,.L_bn_mul_add_words_tail
        +	ld	t0,0(a1)
        +	.set	reorder
        +
        +.L_bn_mul_add_words_return:
        +	jr	ra
        +
        +.L_bn_mul_add_words_tail:
        +	dmultu	t0,a3
        +	ld	t1,0(a0)
        +	subu	a2,1
        +	daddu	t1,v0
        +	sltu	v0,t1,v0
        +	mflo	AT
        +	mfhi	t0
        +	daddu	t1,AT
        +	daddu	v0,t0
        +	sltu	AT,t1,AT
        +	sd	t1,0(a0)
        +	daddu	v0,AT
        +	beqz	a2,.L_bn_mul_add_words_return
        +
        +	ld	t0,8(a1)
        +	dmultu	t0,a3
        +	ld	t1,8(a0)
        +	subu	a2,1
        +	daddu	t1,v0
        +	sltu	v0,t1,v0
        +	mflo	AT
        +	mfhi	t0
        +	daddu	t1,AT
        +	daddu	v0,t0
        +	sltu	AT,t1,AT
        +	sd	t1,8(a0)
        +	daddu	v0,AT
        +	beqz	a2,.L_bn_mul_add_words_return
        +
        +	ld	t0,16(a1)
        +	dmultu	t0,a3
        +	ld	t1,16(a0)
        +	daddu	t1,v0
        +	sltu	v0,t1,v0
        +	mflo	AT
        +	mfhi	t0
        +	daddu	t1,AT
        +	daddu	v0,t0
        +	sltu	AT,t1,AT
        +	sd	t1,16(a0)
        +	daddu	v0,AT
        +	jr	ra
        +END(bn_mul_add_words)
        +
        +.align	5
        +LEAF(bn_mul_words)
        +	.set	noreorder
        +	bgtzl	a2,.L_bn_mul_words_proceed
        +	ld	t0,0(a1)
        +	jr	ra
        +	move	v0,zero
        +	.set	reorder
        +
        +.L_bn_mul_words_proceed:
        +	li	MINUS4,-4
        +	and	ta0,a2,MINUS4
        +	move	v0,zero
        +	beqz	ta0,.L_bn_mul_words_tail
        +
        +.L_bn_mul_words_loop:
        +	dmultu	t0,a3
        +	ld	t2,8(a1)
        +	ld	ta0,16(a1)
        +	ld	ta2,24(a1)
        +	mflo	AT
        +	mfhi	t0
        +	daddu	v0,AT
        +	sltu	t1,v0,AT
        +	sd	v0,0(a0)
        +	daddu	v0,t1,t0
        +
        +	dmultu	t2,a3
        +	subu	a2,4
        +	PTR_ADD	a0,32
        +	PTR_ADD	a1,32
        +	mflo	AT
        +	mfhi	t2
        +	daddu	v0,AT
        +	sltu	t3,v0,AT
        +	sd	v0,-24(a0)
        +	daddu	v0,t3,t2
        +
        +	dmultu	ta0,a3
        +	mflo	AT
        +	mfhi	ta0
        +	daddu	v0,AT
        +	sltu	ta1,v0,AT
        +	sd	v0,-16(a0)
        +	daddu	v0,ta1,ta0
        +
        +
        +	dmultu	ta2,a3
        +	and	ta0,a2,MINUS4
        +	mflo	AT
        +	mfhi	ta2
        +	daddu	v0,AT
        +	sltu	ta3,v0,AT
        +	sd	v0,-8(a0)
        +	daddu	v0,ta3,ta2
        +	.set	noreorder
        +	bgtzl	ta0,.L_bn_mul_words_loop
        +	ld	t0,0(a1)
        +
        +	bnezl	a2,.L_bn_mul_words_tail
        +	ld	t0,0(a1)
        +	.set	reorder
        +
        +.L_bn_mul_words_return:
        +	jr	ra
        +
        +.L_bn_mul_words_tail:
        +	dmultu	t0,a3
        +	subu	a2,1
        +	mflo	AT
        +	mfhi	t0
        +	daddu	v0,AT
        +	sltu	t1,v0,AT
        +	sd	v0,0(a0)
        +	daddu	v0,t1,t0
        +	beqz	a2,.L_bn_mul_words_return
        +
        +	ld	t0,8(a1)
        +	dmultu	t0,a3
        +	subu	a2,1
        +	mflo	AT
        +	mfhi	t0
        +	daddu	v0,AT
        +	sltu	t1,v0,AT
        +	sd	v0,8(a0)
        +	daddu	v0,t1,t0
        +	beqz	a2,.L_bn_mul_words_return
        +
        +	ld	t0,16(a1)
        +	dmultu	t0,a3
        +	mflo	AT
        +	mfhi	t0
        +	daddu	v0,AT
        +	sltu	t1,v0,AT
        +	sd	v0,16(a0)
        +	daddu	v0,t1,t0
        +	jr	ra
        +END(bn_mul_words)
        +
        +.align	5
        +LEAF(bn_sqr_words)
        +	.set	noreorder
        +	bgtzl	a2,.L_bn_sqr_words_proceed
        +	ld	t0,0(a1)
        +	jr	ra
        +	move	v0,zero
        +	.set	reorder
        +
        +.L_bn_sqr_words_proceed:
        +	li	MINUS4,-4
        +	and	ta0,a2,MINUS4
        +	move	v0,zero
        +	beqz	ta0,.L_bn_sqr_words_tail
        +
        +.L_bn_sqr_words_loop:
        +	dmultu	t0,t0
        +	ld	t2,8(a1)
        +	ld	ta0,16(a1)
        +	ld	ta2,24(a1)
        +	mflo	t1
        +	mfhi	t0
        +	sd	t1,0(a0)
        +	sd	t0,8(a0)
        +
        +	dmultu	t2,t2
        +	subu	a2,4
        +	PTR_ADD	a0,64
        +	PTR_ADD	a1,32
        +	mflo	t3
        +	mfhi	t2
        +	sd	t3,-48(a0)
        +	sd	t2,-40(a0)
        +
        +	dmultu	ta0,ta0
        +	mflo	ta1
        +	mfhi	ta0
        +	sd	ta1,-32(a0)
        +	sd	ta0,-24(a0)
        +
        +
        +	dmultu	ta2,ta2
        +	and	ta0,a2,MINUS4
        +	mflo	ta3
        +	mfhi	ta2
        +	sd	ta3,-16(a0)
        +	sd	ta2,-8(a0)
        +
        +	.set	noreorder
        +	bgtzl	ta0,.L_bn_sqr_words_loop
        +	ld	t0,0(a1)
        +
        +	bnezl	a2,.L_bn_sqr_words_tail
        +	ld	t0,0(a1)
        +	.set	reorder
        +
        +.L_bn_sqr_words_return:
        +	move	v0,zero
        +	jr	ra
        +
        +.L_bn_sqr_words_tail:
        +	dmultu	t0,t0
        +	subu	a2,1
        +	mflo	t1
        +	mfhi	t0
        +	sd	t1,0(a0)
        +	sd	t0,8(a0)
        +	beqz	a2,.L_bn_sqr_words_return
        +
        +	ld	t0,8(a1)
        +	dmultu	t0,t0
        +	subu	a2,1
        +	mflo	t1
        +	mfhi	t0
        +	sd	t1,16(a0)
        +	sd	t0,24(a0)
        +	beqz	a2,.L_bn_sqr_words_return
        +
        +	ld	t0,16(a1)
        +	dmultu	t0,t0
        +	mflo	t1
        +	mfhi	t0
        +	sd	t1,32(a0)
        +	sd	t0,40(a0)
        +	jr	ra
        +END(bn_sqr_words)
        +
        +.align	5
        +LEAF(bn_add_words)
        +	.set	noreorder
        +	bgtzl	a3,.L_bn_add_words_proceed
        +	ld	t0,0(a1)
        +	jr	ra
        +	move	v0,zero
        +	.set	reorder
        +
        +.L_bn_add_words_proceed:
        +	li	MINUS4,-4
        +	and	AT,a3,MINUS4
        +	move	v0,zero
        +	beqz	AT,.L_bn_add_words_tail
        +
        +.L_bn_add_words_loop:
        +	ld	ta0,0(a2)
        +	subu	a3,4
        +	ld	t1,8(a1)
        +	and	AT,a3,MINUS4
        +	ld	t2,16(a1)
        +	PTR_ADD	a2,32
        +	ld	t3,24(a1)
        +	PTR_ADD	a0,32
        +	ld	ta1,-24(a2)
        +	PTR_ADD	a1,32
        +	ld	ta2,-16(a2)
        +	ld	ta3,-8(a2)
        +	daddu	ta0,t0
        +	sltu	t8,ta0,t0
        +	daddu	t0,ta0,v0
        +	sltu	v0,t0,ta0
        +	sd	t0,-32(a0)
        +	daddu	v0,t8
        +
        +	daddu	ta1,t1
        +	sltu	t9,ta1,t1
        +	daddu	t1,ta1,v0
        +	sltu	v0,t1,ta1
        +	sd	t1,-24(a0)
        +	daddu	v0,t9
        +
        +	daddu	ta2,t2
        +	sltu	t8,ta2,t2
        +	daddu	t2,ta2,v0
        +	sltu	v0,t2,ta2
        +	sd	t2,-16(a0)
        +	daddu	v0,t8
        +	
        +	daddu	ta3,t3
        +	sltu	t9,ta3,t3
        +	daddu	t3,ta3,v0
        +	sltu	v0,t3,ta3
        +	sd	t3,-8(a0)
        +	daddu	v0,t9
        +	
        +	.set	noreorder
        +	bgtzl	AT,.L_bn_add_words_loop
        +	ld	t0,0(a1)
        +
        +	bnezl	a3,.L_bn_add_words_tail
        +	ld	t0,0(a1)
        +	.set	reorder
        +
        +.L_bn_add_words_return:
        +	jr	ra
        +
        +.L_bn_add_words_tail:
        +	ld	ta0,0(a2)
        +	daddu	ta0,t0
        +	subu	a3,1
        +	sltu	t8,ta0,t0
        +	daddu	t0,ta0,v0
        +	sltu	v0,t0,ta0
        +	sd	t0,0(a0)
        +	daddu	v0,t8
        +	beqz	a3,.L_bn_add_words_return
        +
        +	ld	t1,8(a1)
        +	ld	ta1,8(a2)
        +	daddu	ta1,t1
        +	subu	a3,1
        +	sltu	t9,ta1,t1
        +	daddu	t1,ta1,v0
        +	sltu	v0,t1,ta1
        +	sd	t1,8(a0)
        +	daddu	v0,t9
        +	beqz	a3,.L_bn_add_words_return
        +
        +	ld	t2,16(a1)
        +	ld	ta2,16(a2)
        +	daddu	ta2,t2
        +	sltu	t8,ta2,t2
        +	daddu	t2,ta2,v0
        +	sltu	v0,t2,ta2
        +	sd	t2,16(a0)
        +	daddu	v0,t8
        +	jr	ra
        +END(bn_add_words)
        +
        +.align	5
        +LEAF(bn_sub_words)
        +	.set	noreorder
        +	bgtzl	a3,.L_bn_sub_words_proceed
        +	ld	t0,0(a1)
        +	jr	ra
        +	move	v0,zero
        +	.set	reorder
        +
        +.L_bn_sub_words_proceed:
        +	li	MINUS4,-4
        +	and	AT,a3,MINUS4
        +	move	v0,zero
        +	beqz	AT,.L_bn_sub_words_tail
        +
        +.L_bn_sub_words_loop:
        +	ld	ta0,0(a2)
        +	subu	a3,4
        +	ld	t1,8(a1)
        +	and	AT,a3,MINUS4
        +	ld	t2,16(a1)
        +	PTR_ADD	a2,32
        +	ld	t3,24(a1)
        +	PTR_ADD	a0,32
        +	ld	ta1,-24(a2)
        +	PTR_ADD	a1,32
        +	ld	ta2,-16(a2)
        +	ld	ta3,-8(a2)
        +	sltu	t8,t0,ta0
        +	dsubu	t0,ta0
        +	dsubu	ta0,t0,v0
        +	sd	ta0,-32(a0)
        +	MOVNZ	(t0,v0,t8)
        +
        +	sltu	t9,t1,ta1
        +	dsubu	t1,ta1
        +	dsubu	ta1,t1,v0
        +	sd	ta1,-24(a0)
        +	MOVNZ	(t1,v0,t9)
        +
        +
        +	sltu	t8,t2,ta2
        +	dsubu	t2,ta2
        +	dsubu	ta2,t2,v0
        +	sd	ta2,-16(a0)
        +	MOVNZ	(t2,v0,t8)
        +
        +	sltu	t9,t3,ta3
        +	dsubu	t3,ta3
        +	dsubu	ta3,t3,v0
        +	sd	ta3,-8(a0)
        +	MOVNZ	(t3,v0,t9)
        +
        +	.set	noreorder
        +	bgtzl	AT,.L_bn_sub_words_loop
        +	ld	t0,0(a1)
        +
        +	bnezl	a3,.L_bn_sub_words_tail
        +	ld	t0,0(a1)
        +	.set	reorder
        +
        +.L_bn_sub_words_return:
        +	jr	ra
        +
        +.L_bn_sub_words_tail:
        +	ld	ta0,0(a2)
        +	subu	a3,1
        +	sltu	t8,t0,ta0
        +	dsubu	t0,ta0
        +	dsubu	ta0,t0,v0
        +	MOVNZ	(t0,v0,t8)
        +	sd	ta0,0(a0)
        +	beqz	a3,.L_bn_sub_words_return
        +
        +	ld	t1,8(a1)
        +	subu	a3,1
        +	ld	ta1,8(a2)
        +	sltu	t9,t1,ta1
        +	dsubu	t1,ta1
        +	dsubu	ta1,t1,v0
        +	MOVNZ	(t1,v0,t9)
        +	sd	ta1,8(a0)
        +	beqz	a3,.L_bn_sub_words_return
        +
        +	ld	t2,16(a1)
        +	ld	ta2,16(a2)
        +	sltu	t8,t2,ta2
        +	dsubu	t2,ta2
        +	dsubu	ta2,t2,v0
        +	MOVNZ	(t2,v0,t8)
        +	sd	ta2,16(a0)
        +	jr	ra
        +END(bn_sub_words)
        +
        +#undef	MINUS4
        +
        +.align 5
        +LEAF(bn_div_3_words)
        +	.set	reorder
        +	move	a3,a0		/* we know that bn_div_words doesn't
        +				 * touch a3, ta2, ta3 and preserves a2
        +				 * so that we can save two arguments
        +				 * and return address in registers
        +				 * instead of stack:-)
        +				 */
        +	ld	a0,(a3)
        +	move	ta2,a1
        +	ld	a1,-8(a3)
        +	bne	a0,a2,.L_bn_div_3_words_proceed
        +	li	v0,-1
        +	jr	ra
        +.L_bn_div_3_words_proceed:
        +	move	ta3,ra
        +	bal	bn_div_words
        +	move	ra,ta3
        +	dmultu	ta2,v0
        +	ld	t2,-16(a3)
        +	move	ta0,zero
        +	mfhi	t1
        +	mflo	t0
        +	sltu	t8,t1,v1
        +.L_bn_div_3_words_inner_loop:
        +	bnez	t8,.L_bn_div_3_words_inner_loop_done
        +	sgeu	AT,t2,t0
        +	seq	t9,t1,v1
        +	and	AT,t9
        +	sltu	t3,t0,ta2
        +	daddu	v1,a2
        +	dsubu	t1,t3
        +	dsubu	t0,ta2
        +	sltu	t8,t1,v1
        +	sltu	ta0,v1,a2
        +	or	t8,ta0
        +	.set	noreorder
        +	beqzl	AT,.L_bn_div_3_words_inner_loop
        +	dsubu	v0,1
        +	.set	reorder
        +.L_bn_div_3_words_inner_loop_done:
        +	jr	ra
        +END(bn_div_3_words)
        +
        +.align	5
        +LEAF(bn_div_words)
        +	.set	noreorder
        +	bnezl	a2,.L_bn_div_words_proceed
        +	move	v1,zero
        +	jr	ra
        +	li	v0,-1		/* I'd rather signal div-by-zero
        +				 * which can be done with 'break 7' */
        +
        +.L_bn_div_words_proceed:
        +	bltz	a2,.L_bn_div_words_body
        +	move	t9,v1
        +	dsll	a2,1
        +	bgtz	a2,.-4
        +	addu	t9,1
        +
        +	.set	reorder
        +	negu	t1,t9
        +	li	t2,-1
        +	dsll	t2,t1
        +	and	t2,a0
        +	dsrl	AT,a1,t1
        +	.set	noreorder
        +	bnezl	t2,.+8
        +	break	6		/* signal overflow */
        +	.set	reorder
        +	dsll	a0,t9
        +	dsll	a1,t9
        +	or	a0,AT
        +
        +#define	QT	ta0
        +#define	HH	ta1
        +#define	DH	v1
        +.L_bn_div_words_body:
        +	dsrl	DH,a2,32
        +	sgeu	AT,a0,a2
        +	.set	noreorder
        +	bnezl	AT,.+8
        +	dsubu	a0,a2
        +	.set	reorder
        +
        +	li	QT,-1
        +	dsrl	HH,a0,32
        +	dsrl	QT,32	/* q=0xffffffff */
        +	beq	DH,HH,.L_bn_div_words_skip_div1
        +	ddivu	zero,a0,DH
        +	mflo	QT
        +.L_bn_div_words_skip_div1:
        +	dmultu	a2,QT
        +	dsll	t3,a0,32
        +	dsrl	AT,a1,32
        +	or	t3,AT
        +	mflo	t0
        +	mfhi	t1
        +.L_bn_div_words_inner_loop1:
        +	sltu	t2,t3,t0
        +	seq	t8,HH,t1
        +	sltu	AT,HH,t1
        +	and	t2,t8
        +	sltu	v0,t0,a2
        +	or	AT,t2
        +	.set	noreorder
        +	beqz	AT,.L_bn_div_words_inner_loop1_done
        +	dsubu	t1,v0
        +	dsubu	t0,a2
        +	b	.L_bn_div_words_inner_loop1
        +	dsubu	QT,1
        +	.set	reorder
        +.L_bn_div_words_inner_loop1_done:
        +
        +	dsll	a1,32
        +	dsubu	a0,t3,t0
        +	dsll	v0,QT,32
        +
        +	li	QT,-1
        +	dsrl	HH,a0,32
        +	dsrl	QT,32	/* q=0xffffffff */
        +	beq	DH,HH,.L_bn_div_words_skip_div2
        +	ddivu	zero,a0,DH
        +	mflo	QT
        +.L_bn_div_words_skip_div2:
        +#undef	DH
        +	dmultu	a2,QT
        +	dsll	t3,a0,32
        +	dsrl	AT,a1,32
        +	or	t3,AT
        +	mflo	t0
        +	mfhi	t1
        +.L_bn_div_words_inner_loop2:
        +	sltu	t2,t3,t0
        +	seq	t8,HH,t1
        +	sltu	AT,HH,t1
        +	and	t2,t8
        +	sltu	v1,t0,a2
        +	or	AT,t2
        +	.set	noreorder
        +	beqz	AT,.L_bn_div_words_inner_loop2_done
        +	dsubu	t1,v1
        +	dsubu	t0,a2
        +	b	.L_bn_div_words_inner_loop2
        +	dsubu	QT,1
        +	.set	reorder
        +.L_bn_div_words_inner_loop2_done:	
        +#undef	HH
        +
        +	dsubu	a0,t3,t0
        +	or	v0,QT
        +	dsrl	v1,a0,t9	/* v1 contains remainder if anybody wants it */
        +	dsrl	a2,t9		/* restore a2 */
        +	jr	ra
        +#undef	QT
        +END(bn_div_words)
        +
        +#define	a_0	t0
        +#define	a_1	t1
        +#define	a_2	t2
        +#define	a_3	t3
        +#define	b_0	ta0
        +#define	b_1	ta1
        +#define	b_2	ta2
        +#define	b_3	ta3
        +
        +#define	a_4	s0
        +#define	a_5	s2
        +#define	a_6	s4
        +#define	a_7	a1	/* once we load a[7] we don't need a anymore */
        +#define	b_4	s1
        +#define	b_5	s3
        +#define	b_6	s5
        +#define	b_7	a2	/* once we load b[7] we don't need b anymore */
        +
        +#define	t_1	t8
        +#define	t_2	t9
        +
        +#define	c_1	v0
        +#define	c_2	v1
        +#define	c_3	a3
        +
        +#define	FRAME_SIZE	48
        +
        +.align	5
        +LEAF(bn_mul_comba8)
        +	.set	noreorder
        +	PTR_SUB	sp,FRAME_SIZE
        +	.frame	sp,64,ra
        +	.set	reorder
        +	ld	a_0,0(a1)	/* If compiled with -mips3 option on
        +				 * R5000 box assembler barks on this
        +				 * line with "shouldn't have mult/div
        +				 * as last instruction in bb (R10K
        +				 * bug)" warning. If anybody out there
        +				 * has a clue about how to circumvent
        +				 * this do send me a note.
        +				 *		<appro@fy.chalmers.se>
        +				 */
        +	ld	b_0,0(a2)
        +	ld	a_1,8(a1)
        +	ld	a_2,16(a1)
        +	ld	a_3,24(a1)
        +	ld	b_1,8(a2)
        +	ld	b_2,16(a2)
        +	ld	b_3,24(a2)
        +	dmultu	a_0,b_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
        +	sd	s0,0(sp)
        +	sd	s1,8(sp)
        +	sd	s2,16(sp)
        +	sd	s3,24(sp)
        +	sd	s4,32(sp)
        +	sd	s5,40(sp)
        +	mflo	c_1
        +	mfhi	c_2
        +
        +	dmultu	a_0,b_1		/* mul_add_c(a[0],b[1],c2,c3,c1); */
        +	ld	a_4,32(a1)
        +	ld	a_5,40(a1)
        +	ld	a_6,48(a1)
        +	ld	a_7,56(a1)
        +	ld	b_4,32(a2)
        +	ld	b_5,40(a2)
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	c_3,t_2,AT
        +	dmultu	a_1,b_0		/* mul_add_c(a[1],b[0],c2,c3,c1); */
        +	ld	b_6,48(a2)
        +	ld	b_7,56(a2)
        +	sd	c_1,0(a0)	/* r[0]=c1; */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	sd	c_2,8(a0)	/* r[1]=c2; */
        +
        +	dmultu	a_2,b_0		/* mul_add_c(a[2],b[0],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	dmultu	a_1,b_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	c_2,c_1,t_2
        +	dmultu	a_0,b_2		/* mul_add_c(a[0],b[2],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,16(a0)	/* r[2]=c3; */
        +
        +	dmultu	a_0,b_3		/* mul_add_c(a[0],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	c_3,c_2,t_2
        +	dmultu	a_1,b_2		/* mul_add_c(a[1],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_2,b_1		/* mul_add_c(a[2],b[1],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_3,b_0		/* mul_add_c(a[3],b[0],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,24(a0)	/* r[3]=c1; */
        +
        +	dmultu	a_4,b_0		/* mul_add_c(a[4],b[0],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	dmultu	a_3,b_1		/* mul_add_c(a[3],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_2,b_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_1,b_3		/* mul_add_c(a[1],b[3],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_0,b_4		/* mul_add_c(a[0],b[4],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,32(a0)	/* r[4]=c2; */
        +
        +	dmultu	a_0,b_5		/* mul_add_c(a[0],b[5],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	c_2,c_1,t_2
        +	dmultu	a_1,b_4		/* mul_add_c(a[1],b[4],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_2,b_3		/* mul_add_c(a[2],b[3],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_3,b_2		/* mul_add_c(a[3],b[2],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_4,b_1		/* mul_add_c(a[4],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_5,b_0		/* mul_add_c(a[5],b[0],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,40(a0)	/* r[5]=c3; */
        +
        +	dmultu	a_6,b_0		/* mul_add_c(a[6],b[0],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	c_3,c_2,t_2
        +	dmultu	a_5,b_1		/* mul_add_c(a[5],b[1],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_4,b_2		/* mul_add_c(a[4],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_3,b_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_2,b_4		/* mul_add_c(a[2],b[4],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_1,b_5		/* mul_add_c(a[1],b[5],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_0,b_6		/* mul_add_c(a[0],b[6],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,48(a0)	/* r[6]=c1; */
        +
        +	dmultu	a_0,b_7		/* mul_add_c(a[0],b[7],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	dmultu	a_1,b_6		/* mul_add_c(a[1],b[6],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_2,b_5		/* mul_add_c(a[2],b[5],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_3,b_4		/* mul_add_c(a[3],b[4],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_4,b_3		/* mul_add_c(a[4],b[3],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_5,b_2		/* mul_add_c(a[5],b[2],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_6,b_1		/* mul_add_c(a[6],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_7,b_0		/* mul_add_c(a[7],b[0],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,56(a0)	/* r[7]=c2; */
        +
        +	dmultu	a_7,b_1		/* mul_add_c(a[7],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	c_2,c_1,t_2
        +	dmultu	a_6,b_2		/* mul_add_c(a[6],b[2],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_5,b_3		/* mul_add_c(a[5],b[3],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_4,b_4		/* mul_add_c(a[4],b[4],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_3,b_5		/* mul_add_c(a[3],b[5],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_2,b_6		/* mul_add_c(a[2],b[6],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_1,b_7		/* mul_add_c(a[1],b[7],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,64(a0)	/* r[8]=c3; */
        +
        +	dmultu	a_2,b_7		/* mul_add_c(a[2],b[7],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	c_3,c_2,t_2
        +	dmultu	a_3,b_6		/* mul_add_c(a[3],b[6],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_4,b_5		/* mul_add_c(a[4],b[5],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_5,b_4		/* mul_add_c(a[5],b[4],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_6,b_3		/* mul_add_c(a[6],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_7,b_2		/* mul_add_c(a[7],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,72(a0)	/* r[9]=c1; */
        +
        +	dmultu	a_7,b_3		/* mul_add_c(a[7],b[3],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	dmultu	a_6,b_4		/* mul_add_c(a[6],b[4],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_5,b_5		/* mul_add_c(a[5],b[5],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_4,b_6		/* mul_add_c(a[4],b[6],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_3,b_7		/* mul_add_c(a[3],b[7],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,80(a0)	/* r[10]=c2; */
        +
        +	dmultu	a_4,b_7		/* mul_add_c(a[4],b[7],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	c_2,c_1,t_2
        +	dmultu	a_5,b_6		/* mul_add_c(a[5],b[6],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_6,b_5		/* mul_add_c(a[6],b[5],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_7,b_4		/* mul_add_c(a[7],b[4],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,88(a0)	/* r[11]=c3; */
        +
        +	dmultu	a_7,b_5		/* mul_add_c(a[7],b[5],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	c_3,c_2,t_2
        +	dmultu	a_6,b_6		/* mul_add_c(a[6],b[6],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_5,b_7		/* mul_add_c(a[5],b[7],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,96(a0)	/* r[12]=c1; */
        +
        +	dmultu	a_6,b_7		/* mul_add_c(a[6],b[7],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	dmultu	a_7,b_6		/* mul_add_c(a[7],b[6],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,104(a0)	/* r[13]=c2; */
        +
        +	dmultu	a_7,b_7		/* mul_add_c(a[7],b[7],c3,c1,c2); */
        +	ld	s0,0(sp)
        +	ld	s1,8(sp)
        +	ld	s2,16(sp)
        +	ld	s3,24(sp)
        +	ld	s4,32(sp)
        +	ld	s5,40(sp)
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sd	c_3,112(a0)	/* r[14]=c3; */
        +	sd	c_1,120(a0)	/* r[15]=c1; */
        +
        +	PTR_ADD	sp,FRAME_SIZE
        +
        +	jr	ra
        +END(bn_mul_comba8)
        +
        +.align	5
        +LEAF(bn_mul_comba4)
        +	.set	reorder
        +	ld	a_0,0(a1)
        +	ld	b_0,0(a2)
        +	ld	a_1,8(a1)
        +	ld	a_2,16(a1)
        +	dmultu	a_0,b_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
        +	ld	a_3,24(a1)
        +	ld	b_1,8(a2)
        +	ld	b_2,16(a2)
        +	ld	b_3,24(a2)
        +	mflo	c_1
        +	mfhi	c_2
        +	sd	c_1,0(a0)
        +
        +	dmultu	a_0,b_1		/* mul_add_c(a[0],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	c_3,t_2,AT
        +	dmultu	a_1,b_0		/* mul_add_c(a[1],b[0],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	sd	c_2,8(a0)
        +
        +	dmultu	a_2,b_0		/* mul_add_c(a[2],b[0],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	dmultu	a_1,b_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	c_2,c_1,t_2
        +	dmultu	a_0,b_2		/* mul_add_c(a[0],b[2],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,16(a0)
        +
        +	dmultu	a_0,b_3		/* mul_add_c(a[0],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	c_3,c_2,t_2
        +	dmultu	a_1,b_2		/* mul_add_c(a[1],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_2,b_1		/* mul_add_c(a[2],b[1],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_3,b_0		/* mul_add_c(a[3],b[0],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,24(a0)
        +
        +	dmultu	a_3,b_1		/* mul_add_c(a[3],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	c_1,c_3,t_2
        +	dmultu	a_2,b_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_1,b_3		/* mul_add_c(a[1],b[3],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,32(a0)
        +
        +	dmultu	a_2,b_3		/* mul_add_c(a[2],b[3],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	c_2,c_1,t_2
        +	dmultu	a_3,b_2		/* mul_add_c(a[3],b[2],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,40(a0)
        +
        +	dmultu	a_3,b_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sd	c_1,48(a0)
        +	sd	c_2,56(a0)
        +
        +	jr	ra
        +END(bn_mul_comba4)
        +
        +#undef	a_4
        +#undef	a_5
        +#undef	a_6
        +#undef	a_7
        +#define	a_4	b_0
        +#define	a_5	b_1
        +#define	a_6	b_2
        +#define	a_7	b_3
        +
        +.align	5
        +LEAF(bn_sqr_comba8)
        +	.set	reorder
        +	ld	a_0,0(a1)
        +	ld	a_1,8(a1)
        +	ld	a_2,16(a1)
        +	ld	a_3,24(a1)
        +
        +	dmultu	a_0,a_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
        +	ld	a_4,32(a1)
        +	ld	a_5,40(a1)
        +	ld	a_6,48(a1)
        +	ld	a_7,56(a1)
        +	mflo	c_1
        +	mfhi	c_2
        +	sd	c_1,0(a0)
        +
        +	dmultu	a_0,a_1		/* mul_add_c2(a[0],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	c_3,t_2,AT
        +	sd	c_2,8(a0)
        +
        +	dmultu	a_2,a_0		/* mul_add_c2(a[2],b[0],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_2,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_1,a_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,16(a0)
        +
        +	dmultu	a_0,a_3		/* mul_add_c2(a[0],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_3,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_1,a_2		/* mul_add_c2(a[1],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_3,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,24(a0)
        +
        +	dmultu	a_4,a_0		/* mul_add_c2(a[4],b[0],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_3,a_1		/* mul_add_c2(a[3],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_1,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_2,a_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,32(a0)
        +
        +	dmultu	a_0,a_5		/* mul_add_c2(a[0],b[5],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_2,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_1,a_4		/* mul_add_c2(a[1],b[4],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_2,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_2,a_3		/* mul_add_c2(a[2],b[3],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_2,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,40(a0)
        +
        +	dmultu	a_6,a_0		/* mul_add_c2(a[6],b[0],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_3,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_5,a_1		/* mul_add_c2(a[5],b[1],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_3,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_4,a_2		/* mul_add_c2(a[4],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_3,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_3,a_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,48(a0)
        +
        +	dmultu	a_0,a_7		/* mul_add_c2(a[0],b[7],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_1,a_6		/* mul_add_c2(a[1],b[6],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_1,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_2,a_5		/* mul_add_c2(a[2],b[5],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_1,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_3,a_4		/* mul_add_c2(a[3],b[4],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_1,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,56(a0)
        +
        +	dmultu	a_7,a_1		/* mul_add_c2(a[7],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_2,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_6,a_2		/* mul_add_c2(a[6],b[2],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_2,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_5,a_3		/* mul_add_c2(a[5],b[3],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_2,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_4,a_4		/* mul_add_c(a[4],b[4],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,64(a0)
        +
        +	dmultu	a_2,a_7		/* mul_add_c2(a[2],b[7],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_3,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_3,a_6		/* mul_add_c2(a[3],b[6],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_3,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_4,a_5		/* mul_add_c2(a[4],b[5],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_3,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,72(a0)
        +
        +	dmultu	a_7,a_3		/* mul_add_c2(a[7],b[3],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_6,a_4		/* mul_add_c2(a[6],b[4],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_1,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_5,a_5		/* mul_add_c(a[5],b[5],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,80(a0)
        +
        +	dmultu	a_4,a_7		/* mul_add_c2(a[4],b[7],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_2,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_5,a_6		/* mul_add_c2(a[5],b[6],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_2,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,88(a0)
        +
        +	dmultu	a_7,a_5		/* mul_add_c2(a[7],b[5],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_3,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_6,a_6		/* mul_add_c(a[6],b[6],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,96(a0)
        +
        +	dmultu	a_6,a_7		/* mul_add_c2(a[6],b[7],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,104(a0)
        +
        +	dmultu	a_7,a_7		/* mul_add_c(a[7],b[7],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sd	c_3,112(a0)
        +	sd	c_1,120(a0)
        +
        +	jr	ra
        +END(bn_sqr_comba8)
        +
        +.align	5
        +LEAF(bn_sqr_comba4)
        +	.set	reorder
        +	ld	a_0,0(a1)
        +	ld	a_1,8(a1)
        +	ld	a_2,16(a1)
        +	ld	a_3,24(a1)
        +	dmultu	a_0,a_0		/* mul_add_c(a[0],b[0],c1,c2,c3); */
        +	mflo	c_1
        +	mfhi	c_2
        +	sd	c_1,0(a0)
        +
        +	dmultu	a_0,a_1		/* mul_add_c2(a[0],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	c_3,t_2,AT
        +	sd	c_2,8(a0)
        +
        +	dmultu	a_2,a_0		/* mul_add_c2(a[2],b[0],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_2,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	dmultu	a_1,a_1		/* mul_add_c(a[1],b[1],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,16(a0)
        +
        +	dmultu	a_0,a_3		/* mul_add_c2(a[0],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_3,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	dmultu	a_1,a_2		/* mul_add_c(a2[1],b[2],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	AT,t_2,zero
        +	daddu	c_3,AT
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sltu	AT,c_2,t_2
        +	daddu	c_3,AT
        +	sd	c_1,24(a0)
        +
        +	dmultu	a_3,a_1		/* mul_add_c2(a[3],b[1],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_1,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	dmultu	a_2,a_2		/* mul_add_c(a[2],b[2],c2,c3,c1); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_2,t_1
        +	sltu	AT,c_2,t_1
        +	daddu	t_2,AT
        +	daddu	c_3,t_2
        +	sltu	AT,c_3,t_2
        +	daddu	c_1,AT
        +	sd	c_2,32(a0)
        +
        +	dmultu	a_2,a_3		/* mul_add_c2(a[2],b[3],c3,c1,c2); */
        +	mflo	t_1
        +	mfhi	t_2
        +	slt	c_2,t_2,zero
        +	dsll	t_2,1
        +	slt	a2,t_1,zero
        +	daddu	t_2,a2
        +	dsll	t_1,1
        +	daddu	c_3,t_1
        +	sltu	AT,c_3,t_1
        +	daddu	t_2,AT
        +	daddu	c_1,t_2
        +	sltu	AT,c_1,t_2
        +	daddu	c_2,AT
        +	sd	c_3,40(a0)
        +
        +	dmultu	a_3,a_3		/* mul_add_c(a[3],b[3],c1,c2,c3); */
        +	mflo	t_1
        +	mfhi	t_2
        +	daddu	c_1,t_1
        +	sltu	AT,c_1,t_1
        +	daddu	t_2,AT
        +	daddu	c_2,t_2
        +	sd	c_1,48(a0)
        +	sd	c_2,56(a0)
        +
        +	jr	ra
        +END(bn_sqr_comba4)
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl b/vendor/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl
        new file mode 100644
        index 000000000..bfd6e9754
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/modexp512-x86_64.pl
        @@ -0,0 +1,1497 @@
        +#!/usr/bin/env perl
        +#
        +# Copyright (c) 2010-2011 Intel Corp.
        +#   Author: Vinodh.Gopal@intel.com
        +#           Jim Guilford
        +#           Erdinc.Ozturk@intel.com
        +#           Maxim.Perminov@intel.com
        +#
        +# More information about algorithm used can be found at:
        +#   http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf
        +#
        +# ====================================================================
        +# Copyright (c) 2011 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.
        +# ====================================================================
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +use strict;
        +my $code=".text\n\n";
        +my $m=0;
        +
        +#
        +# Define x512 macros
        +#
        +
        +#MULSTEP_512_ADD	MACRO	x7, x6, x5, x4, x3, x2, x1, x0, dst, src1, src2, add_src, tmp1, tmp2
        +#
        +# uses rax, rdx, and args
        +sub MULSTEP_512_ADD
        +{
        + my ($x, $DST, $SRC2, $ASRC, $OP, $TMP)=@_;
        + my @X=@$x;	# make a copy
        +$code.=<<___;
        +	 mov	(+8*0)($SRC2), %rax
        +	 mul	$OP			# rdx:rax = %OP * [0]
        +	 mov	($ASRC), $X[0]
        +	 add	%rax, $X[0]
        +	 adc	\$0, %rdx
        +	 mov	$X[0], $DST
        +___
        +for(my $i=1;$i<8;$i++) {
        +$code.=<<___;
        +	 mov	%rdx, $TMP
        +
        +	 mov	(+8*$i)($SRC2), %rax
        +	 mul	$OP			# rdx:rax = %OP * [$i]
        +	 mov	(+8*$i)($ASRC), $X[$i]
        +	 add	%rax, $X[$i]
        +	 adc	\$0, %rdx
        +	 add	$TMP, $X[$i]
        +	 adc	\$0, %rdx
        +___
        +}
        +$code.=<<___;
        +	 mov	%rdx, $X[0]
        +___
        +}
        +
        +#MULSTEP_512	MACRO	x7, x6, x5, x4, x3, x2, x1, x0, dst, src2, src1_val, tmp
        +#
        +# uses rax, rdx, and args
        +sub MULSTEP_512
        +{
        + my ($x, $DST, $SRC2, $OP, $TMP)=@_;
        + my @X=@$x;	# make a copy
        +$code.=<<___;
        +	 mov	(+8*0)($SRC2), %rax
        +	 mul	$OP			# rdx:rax = %OP * [0]
        +	 add	%rax, $X[0]
        +	 adc	\$0, %rdx
        +	 mov	$X[0], $DST
        +___
        +for(my $i=1;$i<8;$i++) {
        +$code.=<<___;
        +	 mov	%rdx, $TMP
        +
        +	 mov	(+8*$i)($SRC2), %rax
        +	 mul	$OP			# rdx:rax = %OP * [$i]
        +	 add	%rax, $X[$i]
        +	 adc	\$0, %rdx
        +	 add	$TMP, $X[$i]
        +	 adc	\$0, %rdx
        +___
        +}
        +$code.=<<___;
        +	 mov	%rdx, $X[0]
        +___
        +}
        +
        +#
        +# Swizzle Macros
        +#
        +
        +# macro to copy data from flat space to swizzled table
        +#MACRO swizzle	pDst, pSrc, tmp1, tmp2
        +# pDst and pSrc are modified
        +sub swizzle
        +{
        + my ($pDst, $pSrc, $cnt, $d0)=@_;
        +$code.=<<___;
        +	 mov	\$8, $cnt
        +loop_$m:
        +	 mov	($pSrc), $d0
        +	 mov	$d0#w, ($pDst)
        +	 shr	\$16, $d0
        +	 mov	$d0#w, (+64*1)($pDst)
        +	 shr	\$16, $d0
        +	 mov	$d0#w, (+64*2)($pDst)
        +	 shr	\$16, $d0
        +	 mov	$d0#w, (+64*3)($pDst)
        +	 lea	8($pSrc), $pSrc
        +	 lea	64*4($pDst), $pDst
        +	 dec	$cnt
        +	 jnz	loop_$m
        +___
        +
        + $m++;
        +}
        +
        +# macro to copy data from swizzled table to  flat space
        +#MACRO unswizzle	pDst, pSrc, tmp*3
        +sub unswizzle
        +{
        + my ($pDst, $pSrc, $cnt, $d0, $d1)=@_;
        +$code.=<<___;
        +	 mov	\$4, $cnt
        +loop_$m:
        +	 movzxw	(+64*3+256*0)($pSrc), $d0
        +	 movzxw	(+64*3+256*1)($pSrc), $d1
        +	 shl	\$16, $d0
        +	 shl	\$16, $d1
        +	 mov	(+64*2+256*0)($pSrc), $d0#w
        +	 mov	(+64*2+256*1)($pSrc), $d1#w
        +	 shl	\$16, $d0
        +	 shl	\$16, $d1
        +	 mov	(+64*1+256*0)($pSrc), $d0#w
        +	 mov	(+64*1+256*1)($pSrc), $d1#w
        +	 shl	\$16, $d0
        +	 shl	\$16, $d1
        +	 mov	(+64*0+256*0)($pSrc), $d0#w
        +	 mov	(+64*0+256*1)($pSrc), $d1#w
        +	 mov	$d0, (+8*0)($pDst)
        +	 mov	$d1, (+8*1)($pDst)
        +	 lea	256*2($pSrc), $pSrc
        +	 lea	8*2($pDst), $pDst
        +	 sub	\$1, $cnt
        +	 jnz	loop_$m
        +___
        +
        + $m++;
        +}
        +
        +#
        +# Data Structures
        +#
        +
        +# Reduce Data
        +#
        +#
        +# Offset  Value
        +# 0C0     Carries
        +# 0B8     X2[10]
        +# 0B0     X2[9]
        +# 0A8     X2[8]
        +# 0A0     X2[7]
        +# 098     X2[6]
        +# 090     X2[5]
        +# 088     X2[4]
        +# 080     X2[3]
        +# 078     X2[2]
        +# 070     X2[1]
        +# 068     X2[0]
        +# 060     X1[12]  P[10]
        +# 058     X1[11]  P[9]  Z[8]
        +# 050     X1[10]  P[8]  Z[7]
        +# 048     X1[9]   P[7]  Z[6]
        +# 040     X1[8]   P[6]  Z[5]
        +# 038     X1[7]   P[5]  Z[4]
        +# 030     X1[6]   P[4]  Z[3]
        +# 028     X1[5]   P[3]  Z[2]
        +# 020     X1[4]   P[2]  Z[1]
        +# 018     X1[3]   P[1]  Z[0]
        +# 010     X1[2]   P[0]  Y[2]
        +# 008     X1[1]   Q[1]  Y[1]
        +# 000     X1[0]   Q[0]  Y[0]
        +
        +my $X1_offset           =  0;			# 13 qwords
        +my $X2_offset           =  $X1_offset + 13*8;			# 11 qwords
        +my $Carries_offset      =  $X2_offset + 11*8;			# 1 qword
        +my $Q_offset            =  0;			# 2 qwords
        +my $P_offset            =  $Q_offset + 2*8;			# 11 qwords
        +my $Y_offset            =  0;			# 3 qwords
        +my $Z_offset            =  $Y_offset + 3*8;			# 9 qwords
        +
        +my $Red_Data_Size       =  $Carries_offset + 1*8;			# (25 qwords)
        +
        +#
        +# Stack Frame
        +#
        +#
        +# offset	value
        +# ...		<old stack contents>
        +# ...
        +# 280		Garray
        +
        +# 278		tmp16[15]
        +# ...		...
        +# 200		tmp16[0]
        +
        +# 1F8		tmp[7]
        +# ...		...
        +# 1C0		tmp[0]
        +
        +# 1B8		GT[7]
        +# ...		...
        +# 180		GT[0]
        +
        +# 178		Reduce Data
        +# ...		...
        +# 0B8		Reduce Data
        +# 0B0		reserved
        +# 0A8		reserved
        +# 0A0		reserved
        +# 098		reserved
        +# 090		reserved
        +# 088		reduce result addr
        +# 080		exp[8]
        +
        +# ...
        +# 048		exp[1]
        +# 040		exp[0]
        +
        +# 038		reserved
        +# 030		loop_idx
        +# 028		pg
        +# 020		i
        +# 018		pData	; arg 4
        +# 010		pG	; arg 2
        +# 008		pResult	; arg 1
        +# 000		rsp	; stack pointer before subtract
        +
        +my $rsp_offset          =  0;
        +my $pResult_offset      =  8*1 + $rsp_offset;
        +my $pG_offset           =  8*1 + $pResult_offset;
        +my $pData_offset        =  8*1 + $pG_offset;
        +my $i_offset            =  8*1 + $pData_offset;
        +my $pg_offset           =  8*1 + $i_offset;
        +my $loop_idx_offset     =  8*1 + $pg_offset;
        +my $reserved1_offset    =  8*1 + $loop_idx_offset;
        +my $exp_offset          =  8*1 + $reserved1_offset;
        +my $red_result_addr_offset=  8*9 + $exp_offset;
        +my $reserved2_offset    =  8*1 + $red_result_addr_offset;
        +my $Reduce_Data_offset  =  8*5 + $reserved2_offset;
        +my $GT_offset           =  $Red_Data_Size + $Reduce_Data_offset;
        +my $tmp_offset          =  8*8 + $GT_offset;
        +my $tmp16_offset        =  8*8 + $tmp_offset;
        +my $garray_offset       =  8*16 + $tmp16_offset;
        +my $mem_size            =  8*8*32 + $garray_offset;
        +
        +#
        +# Offsets within Reduce Data
        +#
        +#
        +#	struct MODF_2FOLD_MONT_512_C1_DATA {
        +#	UINT64 t[8][8];
        +#	UINT64 m[8];
        +#	UINT64 m1[8]; /* 2^768 % m */
        +#	UINT64 m2[8]; /* 2^640 % m */
        +#	UINT64 k1[2]; /* (- 1/m) % 2^128 */
        +#	};
        +
        +my $T                   =  0;
        +my $M                   =  512;			# = 8 * 8 * 8
        +my $M1                  =  576;			# = 8 * 8 * 9 /* += 8 * 8 */
        +my $M2                  =  640;			# = 8 * 8 * 10 /* += 8 * 8 */
        +my $K1                  =  704;			# = 8 * 8 * 11 /* += 8 * 8 */
        +
        +#
        +#   FUNCTIONS
        +#
        +
        +{{{
        +#
        +# MULADD_128x512 : Function to multiply 128-bits (2 qwords) by 512-bits (8 qwords)
        +#                       and add 512-bits (8 qwords)
        +#                       to get 640 bits (10 qwords)
        +# Input: 128-bit mul source: [rdi+8*1], rbp
        +#        512-bit mul source: [rsi+8*n]
        +#        512-bit add source: r15, r14, ..., r9, r8
        +# Output: r9, r8, r15, r14, r13, r12, r11, r10, [rcx+8*1], [rcx+8*0]
        +# Clobbers all regs except: rcx, rsi, rdi
        +$code.=<<___;
        +.type	MULADD_128x512,\@abi-omnipotent
        +.align	16
        +MULADD_128x512:
        +___
        +	&MULSTEP_512([map("%r$_",(8..15))], "(+8*0)(%rcx)", "%rsi", "%rbp", "%rbx");
        +$code.=<<___;
        +	 mov	(+8*1)(%rdi), %rbp
        +___
        +	&MULSTEP_512([map("%r$_",(9..15,8))], "(+8*1)(%rcx)", "%rsi", "%rbp", "%rbx");
        +$code.=<<___;
        +	 ret
        +.size	MULADD_128x512,.-MULADD_128x512
        +___
        +}}}
        +
        +{{{
        +#MULADD_256x512	MACRO	pDst, pA, pB, OP, TMP, X7, X6, X5, X4, X3, X2, X1, X0
        +#
        +# Inputs: pDst: Destination  (768 bits, 12 qwords)
        +#         pA:   Multiplicand (1024 bits, 16 qwords)
        +#         pB:   Multiplicand (512 bits, 8 qwords)
        +# Dst = Ah * B + Al
        +# where Ah is (in qwords) A[15:12] (256 bits) and Al is A[7:0] (512 bits)
        +# Results in X3 X2 X1 X0 X7 X6 X5 X4 Dst[3:0]
        +# Uses registers: arguments, RAX, RDX
        +sub MULADD_256x512
        +{
        + my ($pDst, $pA, $pB, $OP, $TMP, $X)=@_;
        +$code.=<<___;
        +	mov	(+8*12)($pA), $OP
        +___
        +	&MULSTEP_512_ADD($X, "(+8*0)($pDst)", $pB, $pA, $OP, $TMP);
        +	push(@$X,shift(@$X));
        +
        +$code.=<<___;
        +	 mov	(+8*13)($pA), $OP
        +___
        +	&MULSTEP_512($X, "(+8*1)($pDst)", $pB, $OP, $TMP);
        +	push(@$X,shift(@$X));
        +
        +$code.=<<___;
        +	 mov	(+8*14)($pA), $OP
        +___
        +	&MULSTEP_512($X, "(+8*2)($pDst)", $pB, $OP, $TMP);
        +	push(@$X,shift(@$X));
        +
        +$code.=<<___;
        +	 mov	(+8*15)($pA), $OP
        +___
        +	&MULSTEP_512($X, "(+8*3)($pDst)", $pB, $OP, $TMP);
        +	push(@$X,shift(@$X));
        +}
        +
        +#
        +# mont_reduce(UINT64 *x,  /* 1024 bits, 16 qwords */
        +#	       UINT64 *m,  /*  512 bits,  8 qwords */
        +#	       MODF_2FOLD_MONT_512_C1_DATA *data,
        +#             UINT64 *r)  /*  512 bits,  8 qwords */
        +# Input:  x (number to be reduced): tmp16 (Implicit)
        +#         m (modulus):              [pM]  (Implicit)
        +#         data (reduce data):       [pData] (Implicit)
        +# Output: r (result):		     Address in [red_res_addr]
        +#         result also in: r9, r8, r15, r14, r13, r12, r11, r10
        +
        +my @X=map("%r$_",(8..15));
        +
        +$code.=<<___;
        +.type	mont_reduce,\@abi-omnipotent
        +.align	16
        +mont_reduce:
        +___
        +
        +my $STACK_DEPTH         =  8;
        +	#
        +	# X1 = Xh * M1 + Xl
        +$code.=<<___;
        +	 lea	(+$Reduce_Data_offset+$X1_offset+$STACK_DEPTH)(%rsp), %rdi			# pX1 (Dst) 769 bits, 13 qwords
        +	 mov	(+$pData_offset+$STACK_DEPTH)(%rsp), %rsi			# pM1 (Bsrc) 512 bits, 8 qwords
        +	 add	\$$M1, %rsi
        +	 lea	(+$tmp16_offset+$STACK_DEPTH)(%rsp), %rcx			# X (Asrc) 1024 bits, 16 qwords
        +
        +___
        +
        +	&MULADD_256x512("%rdi", "%rcx", "%rsi", "%rbp", "%rbx", \@X);	# rotates @X 4 times
        +	# results in r11, r10, r9, r8, r15, r14, r13, r12, X1[3:0]
        +
        +$code.=<<___;
        +	 xor	%rax, %rax
        +	# X1 += xl
        +	 add	(+8*8)(%rcx), $X[4]
        +	 adc	(+8*9)(%rcx), $X[5]
        +	 adc	(+8*10)(%rcx), $X[6]
        +	 adc	(+8*11)(%rcx), $X[7]
        +	 adc	\$0, %rax
        +	# X1 is now rax, r11-r8, r15-r12, tmp16[3:0]
        +
        +	#
        +	# check for carry ;; carry stored in rax
        +	 mov	$X[4], (+8*8)(%rdi)			# rdi points to X1
        +	 mov	$X[5], (+8*9)(%rdi)
        +	 mov	$X[6], %rbp
        +	 mov	$X[7], (+8*11)(%rdi)
        +
        +	 mov	%rax, (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp)
        +
        +	 mov	(+8*0)(%rdi), $X[4]
        +	 mov	(+8*1)(%rdi), $X[5]
        +	 mov	(+8*2)(%rdi), $X[6]
        +	 mov	(+8*3)(%rdi), $X[7]
        +
        +	# X1 is now stored in: X1[11], rbp, X1[9:8], r15-r8
        +	# rdi -> X1
        +	# rsi -> M1
        +
        +	#
        +	# X2 = Xh * M2 + Xl
        +	# do first part (X2 = Xh * M2)
        +	 add	\$8*10, %rdi			# rdi -> pXh ; 128 bits, 2 qwords
        +				#        Xh is actually { [rdi+8*1], rbp }
        +	 add	\$`$M2-$M1`, %rsi			# rsi -> M2
        +	 lea	(+$Reduce_Data_offset+$X2_offset+$STACK_DEPTH)(%rsp), %rcx			# rcx -> pX2 ; 641 bits, 11 qwords
        +___
        +	unshift(@X,pop(@X));	unshift(@X,pop(@X));
        +$code.=<<___;
        +
        +	 call	MULADD_128x512			# args in rcx, rdi / rbp, rsi, r15-r8
        +	# result in r9, r8, r15, r14, r13, r12, r11, r10, X2[1:0]
        +	 mov	(+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp), %rax
        +
        +	# X2 += Xl
        +	 add	(+8*8-8*10)(%rdi), $X[6]		# (-8*10) is to adjust rdi -> Xh to Xl
        +	 adc	(+8*9-8*10)(%rdi), $X[7]
        +	 mov	$X[6], (+8*8)(%rcx)
        +	 mov	$X[7], (+8*9)(%rcx)
        +
        +	 adc	%rax, %rax
        +	 mov	%rax, (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp)
        +
        +	 lea	(+$Reduce_Data_offset+$Q_offset+$STACK_DEPTH)(%rsp), %rdi			# rdi -> pQ ; 128 bits, 2 qwords
        +	 add	\$`$K1-$M2`, %rsi			# rsi -> pK1 ; 128 bits, 2 qwords
        +
        +	# MUL_128x128t128	rdi, rcx, rsi	; Q = X2 * K1 (bottom half)
        +	# B1:B0 = rsi[1:0] = K1[1:0]
        +	# A1:A0 = rcx[1:0] = X2[1:0]
        +	# Result = rdi[1],rbp = Q[1],rbp
        +	 mov	(%rsi), %r8			# B0
        +	 mov	(+8*1)(%rsi), %rbx			# B1
        +
        +	 mov	(%rcx), %rax			# A0
        +	 mul	%r8			# B0
        +	 mov	%rax, %rbp
        +	 mov	%rdx, %r9
        +
        +	 mov	(+8*1)(%rcx), %rax			# A1
        +	 mul	%r8			# B0
        +	 add	%rax, %r9
        +
        +	 mov	(%rcx), %rax			# A0
        +	 mul	%rbx			# B1
        +	 add	%rax, %r9
        +
        +	 mov	%r9, (+8*1)(%rdi)
        +	# end MUL_128x128t128
        +
        +	 sub	\$`$K1-$M`, %rsi
        +
        +	 mov	(%rcx), $X[6]
        +	 mov	(+8*1)(%rcx), $X[7]			# r9:r8 = X2[1:0]
        +
        +	 call	MULADD_128x512			# args in rcx, rdi / rbp, rsi, r15-r8
        +	# result in r9, r8, r15, r14, r13, r12, r11, r10, X2[1:0]
        +
        +	# load first half of m to rdx, rdi, rbx, rax
        +	# moved this here for efficiency
        +	 mov	(+8*0)(%rsi), %rax
        +	 mov	(+8*1)(%rsi), %rbx
        +	 mov	(+8*2)(%rsi), %rdi
        +	 mov	(+8*3)(%rsi), %rdx
        +
        +	# continue with reduction
        +	 mov	(+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp), %rbp
        +
        +	 add	(+8*8)(%rcx), $X[6]
        +	 adc	(+8*9)(%rcx), $X[7]
        +
        +	#accumulate the final carry to rbp
        +	 adc	%rbp, %rbp
        +
        +	# Add in overflow corrections: R = (X2>>128) += T[overflow]
        +	# R = {r9, r8, r15, r14, ..., r10}
        +	 shl	\$3, %rbp
        +	 mov	(+$pData_offset+$STACK_DEPTH)(%rsp), %rcx			# rsi -> Data (and points to T)
        +	 add	%rcx, %rbp			# pT ; 512 bits, 8 qwords, spread out
        +
        +	# rsi will be used to generate a mask after the addition
        +	 xor	%rsi, %rsi
        +
        +	 add	(+8*8*0)(%rbp), $X[0]
        +	 adc	(+8*8*1)(%rbp), $X[1]
        +	 adc	(+8*8*2)(%rbp), $X[2]
        +	 adc	(+8*8*3)(%rbp), $X[3]
        +	 adc	(+8*8*4)(%rbp), $X[4]
        +	 adc	(+8*8*5)(%rbp), $X[5]
        +	 adc	(+8*8*6)(%rbp), $X[6]
        +	 adc	(+8*8*7)(%rbp), $X[7]
        +
        +	# if there is a carry:	rsi = 0xFFFFFFFFFFFFFFFF
        +	# if carry is clear:	rsi = 0x0000000000000000
        +	 sbb	\$0, %rsi
        +
        +	# if carry is clear, subtract 0. Otherwise, subtract 256 bits of m
        +	 and	%rsi, %rax
        +	 and	%rsi, %rbx
        +	 and	%rsi, %rdi
        +	 and	%rsi, %rdx
        +
        +	 mov	\$1, %rbp
        +	 sub	%rax, $X[0]
        +	 sbb	%rbx, $X[1]
        +	 sbb	%rdi, $X[2]
        +	 sbb	%rdx, $X[3]
        +
        +	# if there is a borrow:		rbp = 0
        +	# if there is no borrow:	rbp = 1
        +	# this is used to save the borrows in between the first half and the 2nd half of the subtraction of m
        +	 sbb	\$0, %rbp
        +
        +	#load second half of m to rdx, rdi, rbx, rax
        +
        +	 add	\$$M, %rcx
        +	 mov	(+8*4)(%rcx), %rax
        +	 mov	(+8*5)(%rcx), %rbx
        +	 mov	(+8*6)(%rcx), %rdi
        +	 mov	(+8*7)(%rcx), %rdx
        +
        +	# use the rsi mask as before
        +	# if carry is clear, subtract 0. Otherwise, subtract 256 bits of m
        +	 and	%rsi, %rax
        +	 and	%rsi, %rbx
        +	 and	%rsi, %rdi
        +	 and	%rsi, %rdx
        +
        +	# if rbp = 0, there was a borrow before, it is moved to the carry flag
        +	# if rbp = 1, there was not a borrow before, carry flag is cleared
        +	 sub	\$1, %rbp
        +
        +	 sbb	%rax, $X[4]
        +	 sbb	%rbx, $X[5]
        +	 sbb	%rdi, $X[6]
        +	 sbb	%rdx, $X[7]
        +
        +	# write R back to memory
        +
        +	 mov	(+$red_result_addr_offset+$STACK_DEPTH)(%rsp), %rsi
        +	 mov	$X[0], (+8*0)(%rsi)
        +	 mov	$X[1], (+8*1)(%rsi)
        +	 mov	$X[2], (+8*2)(%rsi)
        +	 mov	$X[3], (+8*3)(%rsi)
        +	 mov	$X[4], (+8*4)(%rsi)
        +	 mov	$X[5], (+8*5)(%rsi)
        +	 mov	$X[6], (+8*6)(%rsi)
        +	 mov	$X[7], (+8*7)(%rsi)
        +
        +	 ret
        +.size	mont_reduce,.-mont_reduce
        +___
        +}}}
        +
        +{{{
        +#MUL_512x512	MACRO	pDst, pA, pB, x7, x6, x5, x4, x3, x2, x1, x0, tmp*2
        +#
        +# Inputs: pDst: Destination  (1024 bits, 16 qwords)
        +#         pA:   Multiplicand (512 bits, 8 qwords)
        +#         pB:   Multiplicand (512 bits, 8 qwords)
        +# Uses registers rax, rdx, args
        +#   B operand in [pB] and also in x7...x0
        +sub MUL_512x512
        +{
        + my ($pDst, $pA, $pB, $x, $OP, $TMP, $pDst_o)=@_;
        + my ($pDst,  $pDst_o) = ($pDst =~ m/([^+]*)\+?(.*)?/);
        + my @X=@$x;	# make a copy
        +
        +$code.=<<___;
        +	 mov	(+8*0)($pA), $OP
        +
        +	 mov	$X[0], %rax
        +	 mul	$OP			# rdx:rax = %OP * [0]
        +	 mov	%rax, (+$pDst_o+8*0)($pDst)
        +	 mov	%rdx, $X[0]
        +___
        +for(my $i=1;$i<8;$i++) {
        +$code.=<<___;
        +	 mov	$X[$i], %rax
        +	 mul	$OP			# rdx:rax = %OP * [$i]
        +	 add	%rax, $X[$i-1]
        +	 adc	\$0, %rdx
        +	 mov	%rdx, $X[$i]
        +___
        +}
        +
        +for(my $i=1;$i<8;$i++) {
        +$code.=<<___;
        +	 mov	(+8*$i)($pA), $OP
        +___
        +
        +	&MULSTEP_512(\@X, "(+$pDst_o+8*$i)($pDst)", $pB, $OP, $TMP);
        +	push(@X,shift(@X));
        +}
        +
        +$code.=<<___;
        +	 mov	$X[0], (+$pDst_o+8*8)($pDst)
        +	 mov	$X[1], (+$pDst_o+8*9)($pDst)
        +	 mov	$X[2], (+$pDst_o+8*10)($pDst)
        +	 mov	$X[3], (+$pDst_o+8*11)($pDst)
        +	 mov	$X[4], (+$pDst_o+8*12)($pDst)
        +	 mov	$X[5], (+$pDst_o+8*13)($pDst)
        +	 mov	$X[6], (+$pDst_o+8*14)($pDst)
        +	 mov	$X[7], (+$pDst_o+8*15)($pDst)
        +___
        +}
        +
        +#
        +# mont_mul_a3b : subroutine to compute (Src1 * Src2) % M (all 512-bits)
        +# Input:  src1: Address of source 1: rdi
        +#         src2: Address of source 2: rsi
        +# Output: dst:  Address of destination: [red_res_addr]
        +#    src2 and result also in: r9, r8, r15, r14, r13, r12, r11, r10
        +# Temp:   Clobbers [tmp16], all registers
        +$code.=<<___;
        +.type	mont_mul_a3b,\@abi-omnipotent
        +.align	16
        +mont_mul_a3b:
        +	#
        +	# multiply tmp = src1 * src2
        +	# For multiply: dst = rcx, src1 = rdi, src2 = rsi
        +	# stack depth is extra 8 from call
        +___
        +	&MUL_512x512("%rsp+$tmp16_offset+8", "%rdi", "%rsi", [map("%r$_",(10..15,8..9))], "%rbp", "%rbx");
        +$code.=<<___;
        +	#
        +	# Dst = tmp % m
        +	# Call reduce(tmp, m, data, dst)
        +
        +	# tail recursion optimization: jmp to mont_reduce and return from there
        +	 jmp	mont_reduce
        +	# call	mont_reduce
        +	# ret
        +.size	mont_mul_a3b,.-mont_mul_a3b
        +___
        +}}}
        +
        +{{{
        +#SQR_512 MACRO pDest, pA, x7, x6, x5, x4, x3, x2, x1, x0, tmp*4
        +#
        +# Input in memory [pA] and also in x7...x0
        +# Uses all argument registers plus rax and rdx
        +#
        +# This version computes all of the off-diagonal terms into memory,
        +# and then it adds in the diagonal terms
        +
        +sub SQR_512
        +{
        + my ($pDst, $pA, $x, $A, $tmp, $x7, $x6, $pDst_o)=@_;
        + my ($pDst,  $pDst_o) = ($pDst =~ m/([^+]*)\+?(.*)?/);
        + my @X=@$x;	# make a copy
        +$code.=<<___;
        +	# ------------------
        +	# first pass 01...07
        +	# ------------------
        +	 mov	$X[0], $A
        +
        +	 mov	$X[1],%rax
        +	 mul	$A
        +	 mov	%rax, (+$pDst_o+8*1)($pDst)
        +___
        +for(my $i=2;$i<8;$i++) {
        +$code.=<<___;
        +	 mov	%rdx, $X[$i-2]
        +	 mov	$X[$i],%rax
        +	 mul	$A
        +	 add	%rax, $X[$i-2]
        +	 adc	\$0, %rdx
        +___
        +}
        +$code.=<<___;
        +	 mov	%rdx, $x7
        +
        +	 mov	$X[0], (+$pDst_o+8*2)($pDst)
        +
        +	# ------------------
        +	# second pass 12...17
        +	# ------------------
        +
        +	 mov	(+8*1)($pA), $A
        +
        +	 mov	(+8*2)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[1]
        +	 adc	\$0, %rdx
        +	 mov	$X[1], (+$pDst_o+8*3)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	(+8*3)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[2]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[2]
        +	 adc	\$0, %rdx
        +	 mov	$X[2], (+$pDst_o+8*4)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	(+8*4)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[3]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[3]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[0]
        +	 mov	(+8*5)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[4]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[4]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[6],%rax
        +	 mul	$A
        +	 add	%rax, $X[5]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[5]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[7],%rax
        +	 mul	$A
        +	 add	%rax, $x7
        +	 adc	\$0, %rdx
        +	 add	$X[0], $x7
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[1]
        +
        +	# ------------------
        +	# third pass 23...27
        +	# ------------------
        +	 mov	(+8*2)($pA), $A
        +
        +	 mov	(+8*3)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[3]
        +	 adc	\$0, %rdx
        +	 mov	$X[3], (+$pDst_o+8*5)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	(+8*4)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[4]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[4]
        +	 adc	\$0, %rdx
        +	 mov	$X[4], (+$pDst_o+8*6)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	(+8*5)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[5]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[5]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[6],%rax
        +	 mul	$A
        +	 add	%rax, $x7
        +	 adc	\$0, %rdx
        +	 add	$X[0], $x7
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[7],%rax
        +	 mul	$A
        +	 add	%rax, $X[1]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[1]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[2]
        +
        +	# ------------------
        +	# fourth pass 34...37
        +	# ------------------
        +
        +	 mov	(+8*3)($pA), $A
        +
        +	 mov	(+8*4)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[5]
        +	 adc	\$0, %rdx
        +	 mov	$X[5], (+$pDst_o+8*7)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	(+8*5)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $x7
        +	 adc	\$0, %rdx
        +	 add	$X[0], $x7
        +	 adc	\$0, %rdx
        +	 mov	$x7, (+$pDst_o+8*8)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[6],%rax
        +	 mul	$A
        +	 add	%rax, $X[1]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[1]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[7],%rax
        +	 mul	$A
        +	 add	%rax, $X[2]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[2]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[5]
        +
        +	# ------------------
        +	# fifth pass 45...47
        +	# ------------------
        +	 mov	(+8*4)($pA), $A
        +
        +	 mov	(+8*5)($pA),%rax
        +	 mul	$A
        +	 add	%rax, $X[1]
        +	 adc	\$0, %rdx
        +	 mov	$X[1], (+$pDst_o+8*9)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[6],%rax
        +	 mul	$A
        +	 add	%rax, $X[2]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[2]
        +	 adc	\$0, %rdx
        +	 mov	$X[2], (+$pDst_o+8*10)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[7],%rax
        +	 mul	$A
        +	 add	%rax, $X[5]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[5]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $X[1]
        +
        +	# ------------------
        +	# sixth pass 56...57
        +	# ------------------
        +	 mov	(+8*5)($pA), $A
        +
        +	 mov	$X[6],%rax
        +	 mul	$A
        +	 add	%rax, $X[5]
        +	 adc	\$0, %rdx
        +	 mov	$X[5], (+$pDst_o+8*11)($pDst)
        +
        +	 mov	%rdx, $X[0]
        +	 mov	$X[7],%rax
        +	 mul	$A
        +	 add	%rax, $X[1]
        +	 adc	\$0, %rdx
        +	 add	$X[0], $X[1]
        +	 adc	\$0, %rdx
        +	 mov	$X[1], (+$pDst_o+8*12)($pDst)
        +
        +	 mov	%rdx, $X[2]
        +
        +	# ------------------
        +	# seventh pass 67
        +	# ------------------
        +	 mov	$X[6], $A
        +
        +	 mov	$X[7],%rax
        +	 mul	$A
        +	 add	%rax, $X[2]
        +	 adc	\$0, %rdx
        +	 mov	$X[2], (+$pDst_o+8*13)($pDst)
        +
        +	 mov	%rdx, (+$pDst_o+8*14)($pDst)
        +
        +	# start finalize (add	in squares, and double off-terms)
        +	 mov	(+$pDst_o+8*1)($pDst), $X[0]
        +	 mov	(+$pDst_o+8*2)($pDst), $X[1]
        +	 mov	(+$pDst_o+8*3)($pDst), $X[2]
        +	 mov	(+$pDst_o+8*4)($pDst), $X[3]
        +	 mov	(+$pDst_o+8*5)($pDst), $X[4]
        +	 mov	(+$pDst_o+8*6)($pDst), $X[5]
        +
        +	 mov	(+8*3)($pA), %rax
        +	 mul	%rax
        +	 mov	%rax, $x6
        +	 mov	%rdx, $X[6]
        +
        +	 add	$X[0], $X[0]
        +	 adc	$X[1], $X[1]
        +	 adc	$X[2], $X[2]
        +	 adc	$X[3], $X[3]
        +	 adc	$X[4], $X[4]
        +	 adc	$X[5], $X[5]
        +	 adc	\$0, $X[6]
        +
        +	 mov	(+8*0)($pA), %rax
        +	 mul	%rax
        +	 mov	%rax, (+$pDst_o+8*0)($pDst)
        +	 mov	%rdx, $A
        +
        +	 mov	(+8*1)($pA), %rax
        +	 mul	%rax
        +
        +	 add	$A, $X[0]
        +	 adc	%rax, $X[1]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $A
        +	 mov	$X[0], (+$pDst_o+8*1)($pDst)
        +	 mov	$X[1], (+$pDst_o+8*2)($pDst)
        +
        +	 mov	(+8*2)($pA), %rax
        +	 mul	%rax
        +
        +	 add	$A, $X[2]
        +	 adc	%rax, $X[3]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $A
        +
        +	 mov	$X[2], (+$pDst_o+8*3)($pDst)
        +	 mov	$X[3], (+$pDst_o+8*4)($pDst)
        +
        +	 xor	$tmp, $tmp
        +	 add	$A, $X[4]
        +	 adc	$x6, $X[5]
        +	 adc	\$0, $tmp
        +
        +	 mov	$X[4], (+$pDst_o+8*5)($pDst)
        +	 mov	$X[5], (+$pDst_o+8*6)($pDst)
        +
        +	# %%tmp has 0/1 in column 7
        +	# %%A6 has a full value in column 7
        +
        +	 mov	(+$pDst_o+8*7)($pDst), $X[0]
        +	 mov	(+$pDst_o+8*8)($pDst), $X[1]
        +	 mov	(+$pDst_o+8*9)($pDst), $X[2]
        +	 mov	(+$pDst_o+8*10)($pDst), $X[3]
        +	 mov	(+$pDst_o+8*11)($pDst), $X[4]
        +	 mov	(+$pDst_o+8*12)($pDst), $X[5]
        +	 mov	(+$pDst_o+8*13)($pDst), $x6
        +	 mov	(+$pDst_o+8*14)($pDst), $x7
        +
        +	 mov	$X[7], %rax
        +	 mul	%rax
        +	 mov	%rax, $X[7]
        +	 mov	%rdx, $A
        +
        +	 add	$X[0], $X[0]
        +	 adc	$X[1], $X[1]
        +	 adc	$X[2], $X[2]
        +	 adc	$X[3], $X[3]
        +	 adc	$X[4], $X[4]
        +	 adc	$X[5], $X[5]
        +	 adc	$x6, $x6
        +	 adc	$x7, $x7
        +	 adc	\$0, $A
        +
        +	 add	$tmp, $X[0]
        +
        +	 mov	(+8*4)($pA), %rax
        +	 mul	%rax
        +
        +	 add	$X[6], $X[0]
        +	 adc	%rax, $X[1]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $tmp
        +
        +	 mov	$X[0], (+$pDst_o+8*7)($pDst)
        +	 mov	$X[1], (+$pDst_o+8*8)($pDst)
        +
        +	 mov	(+8*5)($pA), %rax
        +	 mul	%rax
        +
        +	 add	$tmp, $X[2]
        +	 adc	%rax, $X[3]
        +	 adc	\$0, %rdx
        +
        +	 mov	%rdx, $tmp
        +
        +	 mov	$X[2], (+$pDst_o+8*9)($pDst)
        +	 mov	$X[3], (+$pDst_o+8*10)($pDst)
        +
        +	 mov	(+8*6)($pA), %rax
        +	 mul	%rax
        +
        +	 add	$tmp, $X[4]
        +	 adc	%rax, $X[5]
        +	 adc	\$0, %rdx
        +
        +	 mov	$X[4], (+$pDst_o+8*11)($pDst)
        +	 mov	$X[5], (+$pDst_o+8*12)($pDst)
        +
        +	 add	%rdx, $x6
        +	 adc	$X[7], $x7
        +	 adc	\$0, $A
        +
        +	 mov	$x6, (+$pDst_o+8*13)($pDst)
        +	 mov	$x7, (+$pDst_o+8*14)($pDst)
        +	 mov	$A, (+$pDst_o+8*15)($pDst)
        +___
        +}
        +
        +#
        +# sqr_reduce: subroutine to compute Result = reduce(Result * Result)
        +#
        +# input and result also in: r9, r8, r15, r14, r13, r12, r11, r10
        +#
        +$code.=<<___;
        +.type	sqr_reduce,\@abi-omnipotent
        +.align	16
        +sqr_reduce:
        +	 mov	(+$pResult_offset+8)(%rsp), %rcx
        +___
        +	&SQR_512("%rsp+$tmp16_offset+8", "%rcx", [map("%r$_",(10..15,8..9))], "%rbx", "%rbp", "%rsi", "%rdi");
        +$code.=<<___;
        +	# tail recursion optimization: jmp to mont_reduce and return from there
        +	 jmp	mont_reduce
        +	# call	mont_reduce
        +	# ret
        +.size	sqr_reduce,.-sqr_reduce
        +___
        +}}}
        +
        +#
        +# MAIN FUNCTION
        +#
        +
        +#mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */
        +#           UINT64 *g,   /* 512 bits, 8 qwords */
        +#           UINT64 *exp, /* 512 bits, 8 qwords */
        +#           struct mod_ctx_512 *data)
        +
        +# window size = 5
        +# table size = 2^5 = 32
        +#table_entries	equ	32
        +#table_size	equ	table_entries * 8
        +$code.=<<___;
        +.globl	mod_exp_512
        +.type	mod_exp_512,\@function,4
        +mod_exp_512:
        +	 push	%rbp
        +	 push	%rbx
        +	 push	%r12
        +	 push	%r13
        +	 push	%r14
        +	 push	%r15
        +
        +	# adjust stack down and then align it with cache boundary
        +	 mov	%rsp, %r8
        +	 sub	\$$mem_size, %rsp
        +	 and	\$-64, %rsp
        +
        +	# store previous stack pointer and arguments
        +	 mov	%r8, (+$rsp_offset)(%rsp)
        +	 mov	%rdi, (+$pResult_offset)(%rsp)
        +	 mov	%rsi, (+$pG_offset)(%rsp)
        +	 mov	%rcx, (+$pData_offset)(%rsp)
        +.Lbody:
        +	# transform g into montgomery space
        +	# GT = reduce(g * C2) = reduce(g * (2^256))
        +	# reduce expects to have the input in [tmp16]
        +	 pxor	%xmm4, %xmm4
        +	 movdqu	(+16*0)(%rsi), %xmm0
        +	 movdqu	(+16*1)(%rsi), %xmm1
        +	 movdqu	(+16*2)(%rsi), %xmm2
        +	 movdqu	(+16*3)(%rsi), %xmm3
        +	 movdqa	%xmm4, (+$tmp16_offset+16*0)(%rsp)
        +	 movdqa	%xmm4, (+$tmp16_offset+16*1)(%rsp)
        +	 movdqa	%xmm4, (+$tmp16_offset+16*6)(%rsp)
        +	 movdqa	%xmm4, (+$tmp16_offset+16*7)(%rsp)
        +	 movdqa	%xmm0, (+$tmp16_offset+16*2)(%rsp)
        +	 movdqa	%xmm1, (+$tmp16_offset+16*3)(%rsp)
        +	 movdqa	%xmm2, (+$tmp16_offset+16*4)(%rsp)
        +	 movdqa	%xmm3, (+$tmp16_offset+16*5)(%rsp)
        +
        +	# load pExp before rdx gets blown away
        +	 movdqu	(+16*0)(%rdx), %xmm0
        +	 movdqu	(+16*1)(%rdx), %xmm1
        +	 movdqu	(+16*2)(%rdx), %xmm2
        +	 movdqu	(+16*3)(%rdx), %xmm3
        +
        +	 lea	(+$GT_offset)(%rsp), %rbx
        +	 mov	%rbx, (+$red_result_addr_offset)(%rsp)
        +	 call	mont_reduce
        +
        +	# Initialize tmp = C
        +	 lea	(+$tmp_offset)(%rsp), %rcx
        +	 xor	%rax, %rax
        +	 mov	%rax, (+8*0)(%rcx)
        +	 mov	%rax, (+8*1)(%rcx)
        +	 mov	%rax, (+8*3)(%rcx)
        +	 mov	%rax, (+8*4)(%rcx)
        +	 mov	%rax, (+8*5)(%rcx)
        +	 mov	%rax, (+8*6)(%rcx)
        +	 mov	%rax, (+8*7)(%rcx)
        +	 mov	%rax, (+$exp_offset+8*8)(%rsp)
        +	 movq	\$1, (+8*2)(%rcx)
        +
        +	 lea	(+$garray_offset)(%rsp), %rbp
        +	 mov	%rcx, %rsi			# pTmp
        +	 mov	%rbp, %rdi			# Garray[][0]
        +___
        +
        +	&swizzle("%rdi", "%rcx", "%rax", "%rbx");
        +
        +	# for (rax = 31; rax != 0; rax--) {
        +	#     tmp = reduce(tmp * G)
        +	#     swizzle(pg, tmp);
        +	#     pg += 2; }
        +$code.=<<___;
        +	 mov	\$31, %rax
        +	 mov	%rax, (+$i_offset)(%rsp)
        +	 mov	%rbp, (+$pg_offset)(%rsp)
        +	# rsi -> pTmp
        +	 mov	%rsi, (+$red_result_addr_offset)(%rsp)
        +	 mov	(+8*0)(%rsi), %r10
        +	 mov	(+8*1)(%rsi), %r11
        +	 mov	(+8*2)(%rsi), %r12
        +	 mov	(+8*3)(%rsi), %r13
        +	 mov	(+8*4)(%rsi), %r14
        +	 mov	(+8*5)(%rsi), %r15
        +	 mov	(+8*6)(%rsi), %r8
        +	 mov	(+8*7)(%rsi), %r9
        +init_loop:
        +	 lea	(+$GT_offset)(%rsp), %rdi
        +	 call	mont_mul_a3b
        +	 lea	(+$tmp_offset)(%rsp), %rsi
        +	 mov	(+$pg_offset)(%rsp), %rbp
        +	 add	\$2, %rbp
        +	 mov	%rbp, (+$pg_offset)(%rsp)
        +	 mov	%rsi, %rcx			# rcx = rsi = addr of tmp
        +___
        +
        +	&swizzle("%rbp", "%rcx", "%rax", "%rbx");
        +$code.=<<___;
        +	 mov	(+$i_offset)(%rsp), %rax
        +	 sub	\$1, %rax
        +	 mov	%rax, (+$i_offset)(%rsp)
        +	 jne	init_loop
        +
        +	#
        +	# Copy exponent onto stack
        +	 movdqa	%xmm0, (+$exp_offset+16*0)(%rsp)
        +	 movdqa	%xmm1, (+$exp_offset+16*1)(%rsp)
        +	 movdqa	%xmm2, (+$exp_offset+16*2)(%rsp)
        +	 movdqa	%xmm3, (+$exp_offset+16*3)(%rsp)
        +
        +
        +	#
        +	# Do exponentiation
        +	# Initialize result to G[exp{511:507}]
        +	 mov	(+$exp_offset+62)(%rsp), %eax
        +	 mov	%rax, %rdx
        +	 shr	\$11, %rax
        +	 and	\$0x07FF, %edx
        +	 mov	%edx, (+$exp_offset+62)(%rsp)
        +	 lea	(+$garray_offset)(%rsp,%rax,2), %rsi
        +	 mov	(+$pResult_offset)(%rsp), %rdx
        +___
        +
        +	&unswizzle("%rdx", "%rsi", "%rbp", "%rbx", "%rax");
        +
        +	#
        +	# Loop variables
        +	# rcx = [loop_idx] = index: 510-5 to 0 by 5
        +$code.=<<___;
        +	 movq	\$505, (+$loop_idx_offset)(%rsp)
        +
        +	 mov	(+$pResult_offset)(%rsp), %rcx
        +	 mov	%rcx, (+$red_result_addr_offset)(%rsp)
        +	 mov	(+8*0)(%rcx), %r10
        +	 mov	(+8*1)(%rcx), %r11
        +	 mov	(+8*2)(%rcx), %r12
        +	 mov	(+8*3)(%rcx), %r13
        +	 mov	(+8*4)(%rcx), %r14
        +	 mov	(+8*5)(%rcx), %r15
        +	 mov	(+8*6)(%rcx), %r8
        +	 mov	(+8*7)(%rcx), %r9
        +	 jmp	sqr_2
        +
        +main_loop_a3b:
        +	 call	sqr_reduce
        +	 call	sqr_reduce
        +	 call	sqr_reduce
        +sqr_2:
        +	 call	sqr_reduce
        +	 call	sqr_reduce
        +
        +	#
        +	# Do multiply, first look up proper value in Garray
        +	 mov	(+$loop_idx_offset)(%rsp), %rcx			# bit index
        +	 mov	%rcx, %rax
        +	 shr	\$4, %rax			# rax is word pointer
        +	 mov	(+$exp_offset)(%rsp,%rax,2), %edx
        +	 and	\$15, %rcx
        +	 shrq	%cl, %rdx
        +	 and	\$0x1F, %rdx
        +
        +	 lea	(+$garray_offset)(%rsp,%rdx,2), %rsi
        +	 lea	(+$tmp_offset)(%rsp), %rdx
        +	 mov	%rdx, %rdi
        +___
        +
        +	&unswizzle("%rdx", "%rsi", "%rbp", "%rbx", "%rax");
        +	# rdi = tmp = pG
        +
        +	#
        +	# Call mod_mul_a1(pDst,  pSrc1, pSrc2, pM, pData)
        +	#                 result result pG     M   Data
        +$code.=<<___;
        +	 mov	(+$pResult_offset)(%rsp), %rsi
        +	 call	mont_mul_a3b
        +
        +	#
        +	# finish loop
        +	 mov	(+$loop_idx_offset)(%rsp), %rcx
        +	 sub	\$5, %rcx
        +	 mov	%rcx, (+$loop_idx_offset)(%rsp)
        +	 jge	main_loop_a3b
        +
        +	#
        +
        +end_main_loop_a3b:
        +	# transform result out of Montgomery space
        +	# result = reduce(result)
        +	 mov	(+$pResult_offset)(%rsp), %rdx
        +	 pxor	%xmm4, %xmm4
        +	 movdqu	(+16*0)(%rdx), %xmm0
        +	 movdqu	(+16*1)(%rdx), %xmm1
        +	 movdqu	(+16*2)(%rdx), %xmm2
        +	 movdqu	(+16*3)(%rdx), %xmm3
        +	 movdqa	%xmm4, (+$tmp16_offset+16*4)(%rsp)
        +	 movdqa	%xmm4, (+$tmp16_offset+16*5)(%rsp)
        +	 movdqa	%xmm4, (+$tmp16_offset+16*6)(%rsp)
        +	 movdqa	%xmm4, (+$tmp16_offset+16*7)(%rsp)
        +	 movdqa	%xmm0, (+$tmp16_offset+16*0)(%rsp)
        +	 movdqa	%xmm1, (+$tmp16_offset+16*1)(%rsp)
        +	 movdqa	%xmm2, (+$tmp16_offset+16*2)(%rsp)
        +	 movdqa	%xmm3, (+$tmp16_offset+16*3)(%rsp)
        +	 call	mont_reduce
        +
        +	# If result > m, subract m
        +	# load result into r15:r8
        +	 mov	(+$pResult_offset)(%rsp), %rax
        +	 mov	(+8*0)(%rax), %r8
        +	 mov	(+8*1)(%rax), %r9
        +	 mov	(+8*2)(%rax), %r10
        +	 mov	(+8*3)(%rax), %r11
        +	 mov	(+8*4)(%rax), %r12
        +	 mov	(+8*5)(%rax), %r13
        +	 mov	(+8*6)(%rax), %r14
        +	 mov	(+8*7)(%rax), %r15
        +
        +	# subtract m
        +	 mov	(+$pData_offset)(%rsp), %rbx
        +	 add	\$$M, %rbx
        +
        +	 sub	(+8*0)(%rbx), %r8
        +	 sbb	(+8*1)(%rbx), %r9
        +	 sbb	(+8*2)(%rbx), %r10
        +	 sbb	(+8*3)(%rbx), %r11
        +	 sbb	(+8*4)(%rbx), %r12
        +	 sbb	(+8*5)(%rbx), %r13
        +	 sbb	(+8*6)(%rbx), %r14
        +	 sbb	(+8*7)(%rbx), %r15
        +
        +	# if Carry is clear, replace result with difference
        +	 mov	(+8*0)(%rax), %rsi
        +	 mov	(+8*1)(%rax), %rdi
        +	 mov	(+8*2)(%rax), %rcx
        +	 mov	(+8*3)(%rax), %rdx
        +	 cmovnc	%r8, %rsi
        +	 cmovnc	%r9, %rdi
        +	 cmovnc	%r10, %rcx
        +	 cmovnc	%r11, %rdx
        +	 mov	%rsi, (+8*0)(%rax)
        +	 mov	%rdi, (+8*1)(%rax)
        +	 mov	%rcx, (+8*2)(%rax)
        +	 mov	%rdx, (+8*3)(%rax)
        +
        +	 mov	(+8*4)(%rax), %rsi
        +	 mov	(+8*5)(%rax), %rdi
        +	 mov	(+8*6)(%rax), %rcx
        +	 mov	(+8*7)(%rax), %rdx
        +	 cmovnc	%r12, %rsi
        +	 cmovnc	%r13, %rdi
        +	 cmovnc	%r14, %rcx
        +	 cmovnc	%r15, %rdx
        +	 mov	%rsi, (+8*4)(%rax)
        +	 mov	%rdi, (+8*5)(%rax)
        +	 mov	%rcx, (+8*6)(%rax)
        +	 mov	%rdx, (+8*7)(%rax)
        +
        +	 mov	(+$rsp_offset)(%rsp), %rsi
        +	 mov	0(%rsi),%r15
        +	 mov	8(%rsi),%r14
        +	 mov	16(%rsi),%r13
        +	 mov	24(%rsi),%r12
        +	 mov	32(%rsi),%rbx
        +	 mov	40(%rsi),%rbp
        +	 lea	48(%rsi),%rsp
        +.Lepilogue:
        +	 ret
        +.size mod_exp_512, . - mod_exp_512
        +___
        +
        +if ($win64) {
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +my $rec="%rcx";
        +my $frame="%rdx";
        +my $context="%r8";
        +my $disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	mod_exp_512_se_handler,\@abi-omnipotent
        +.align	16
        +mod_exp_512_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lbody(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_prologue
        +
        +	mov	$rsp_offset(%rax),%rax	# pull saved Rsp
        +
        +	mov	32(%rax),%rbx
        +	mov	40(%rax),%rbp
        +	mov	24(%rax),%r12
        +	mov	16(%rax),%r13
        +	mov	8(%rax),%r14
        +	mov	0(%rax),%r15
        +	lea	48(%rax),%rax
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	mod_exp_512_se_handler,.-mod_exp_512_se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_mod_exp_512
        +	.rva	.LSEH_end_mod_exp_512
        +	.rva	.LSEH_info_mod_exp_512
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_mod_exp_512:
        +	.byte	9,0,0,0
        +	.rva	mod_exp_512_se_handler
        +___
        +}
        +
        +sub reg_part {
        +my ($reg,$conv)=@_;
        +    if ($reg =~ /%r[0-9]+/)	{ $reg .= $conv; }
        +    elsif ($conv eq "b")	{ $reg =~ s/%[er]([^x]+)x?/%$1l/;	}
        +    elsif ($conv eq "w")	{ $reg =~ s/%[er](.+)/%$1/;		}
        +    elsif ($conv eq "d")	{ $reg =~ s/%[er](.+)/%e$1/;		}
        +    return $reg;
        +}
        +
        +$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/(\(\+[^)]+\))/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/pa-risc2.s b/vendor/openssl/openssl/crypto/bn/asm/pa-risc2.s
        new file mode 100644
        index 000000000..f3b16290e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/pa-risc2.s
        @@ -0,0 +1,1618 @@
        +;
        +; PA-RISC 2.0 implementation of bn_asm code, based on the
        +; 64-bit version of the code.  This code is effectively the
        +; same as the 64-bit version except the register model is
        +; slightly different given all values must be 32-bit between
        +; function calls.  Thus the 64-bit return values are returned
        +; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit
        +;
        +;
        +; 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.0N
        +	.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 32-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,r29  (ret0,ret1)
        +;     Stack pointer          ; r30  (sp) 
        +;     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
        +n           .reg %r23
        +
        +;
        +; Note that the "w" argument for bn_mul_add_words and bn_mul_words
        +; is passed on the stack at a delta of -56 from the top of stack
        +; as the routine is entered.
        +;
        +
        +;
        +; Globals used in some routines
        +;
        +
        +top_overflow .reg %r23
        +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
        +; arg3 = num
        +; -56(sp) =  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  
        +	NOP
        +    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,%ret1           ; return 0 by default
        +    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
        +
        +    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    -184(%sp),fw        ; (-56-128) load up w into 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    %ret1,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,%ret1           ; 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     %ret1,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,%ret1            ; ht++
        +    STD     lt_0,0(r_ptr)             ; rp[0] = lt
        +
        +bn_mul_add_words_exit
        +    .EXIT
        +	
        +    EXTRD,U %ret1,31,32,%ret0         ; for 32-bit, return in ret0/ret1
        +    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
        +; arg3 = num
        +; w on stack at -56(sp)
        +
        +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  
        +	NOP
        +    STD     %r5,16(%sp)         ; save r5  
        +
        +    STD     %r6,24(%sp)         ; save r6  
        +    STD     %r7,32(%sp)         ; save r7  
        +    COPY    %r0,%ret1           ; return 0 by default
        +    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
        +
        +    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    -184(%sp),fw        ; (-56-128) load up w into 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    %ret1,lt_0,lt_0            ; lt = lt + c (ret1);
        +	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,%ret1                ; 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     %ret1,lt_0,lt_0           ; lt = lt + c;
        +    ADD,DC  ht_0,%r0,ht_0             ; ht++
        +
        +    COPY    ht_0,%ret1                ; copy carry
        +    STD     lt_0,0(r_ptr)             ; rp[0] = lt
        +
        +bn_mul_words_exit
        +    .EXIT
        +    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
        +    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	
        +
        +;----------------------------------------------------------------------------
        +;
        +;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,%ret1           ; 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,%ret1,t                    ; t = t+c;
        +	ADD,DC  %r0,%r0,%ret1                ; set c to carry
        +	ADD     t,b,l                        ; l = t + b[0]
        +	ADD,DC  %ret1,%r0,%ret1              ; c+= carry
        +	STD     l,0(r_ptr)
        +
        +	LDD     8(a_ptr),t
        +	LDD     8(b_ptr),b
        +	ADD     t,%ret1,t                     ; t = t+c;
        +	ADD,DC  %r0,%r0,%ret1                 ; set c to carry
        +	ADD     t,b,l                         ; l = t + b[0]
        +	ADD,DC  %ret1,%r0,%ret1               ; 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,%ret1,t                 ; t = t+c;
        +	ADD,DC  %r0,%r0,%ret1             ; set c to carry (could use CMPCLR??)
        +	ADD     t,b,l                     ; l = t + b[0]
        +	ADD,DC  %ret1,%r0,%ret1           ; c+= carry
        +	STD     l,0(r_ptr)
        +
        +bn_add_words_exit
        +    .EXIT
        +    BVE     (%rp)
        +    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
        +	.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,%ret1           ; 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,%ret1,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,%ret1
        +	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,%ret1,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,%ret1
        +	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,%ret1,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,%ret1
        +
        +	STD     sub_tmp1,0(r_ptr)
        +
        +bn_sub_words_exit
        +    .EXIT
        +    BVE     (%rp)
        +    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
        +	.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 output from the HP C compiler.  
        +;
        +;------------------------------------------------------------------------------
        +bn_div_words
        +	.PROC
        +	.EXPORT	bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN
        +	.IMPORT	BN_num_bits_word,CODE
        +	;--- not PIC	.IMPORT	__iob,DATA
        +	;--- not PIC	.IMPORT	fprintf,CODE
        +	.IMPORT	abort,CODE
        +	.IMPORT	$$div2U,MILLICODE
        +	.CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
        +        .ENTRY
        +        STW     %r2,-20(%r30)   ;offset 0x8ec
        +        STW,MA  %r3,192(%r30)   ;offset 0x8f0
        +        STW     %r4,-188(%r30)  ;offset 0x8f4
        +        DEPD    %r5,31,32,%r6   ;offset 0x8f8
        +        STD     %r6,-184(%r30)  ;offset 0x8fc
        +        DEPD    %r7,31,32,%r8   ;offset 0x900
        +        STD     %r8,-176(%r30)  ;offset 0x904
        +        STW     %r9,-168(%r30)  ;offset 0x908
        +        LDD     -248(%r30),%r3  ;offset 0x90c
        +        COPY    %r26,%r4        ;offset 0x910
        +        COPY    %r24,%r5        ;offset 0x914
        +        DEPD    %r25,31,32,%r4  ;offset 0x918
        +        CMPB,*<>        %r3,%r0,$0006000C       ;offset 0x91c
        +        DEPD    %r23,31,32,%r5  ;offset 0x920
        +        MOVIB,TR        -1,%r29,$00060002       ;offset 0x924
        +        EXTRD,U %r29,31,32,%r28 ;offset 0x928
        +$0006002A
        +        LDO     -1(%r29),%r29   ;offset 0x92c
        +        SUB     %r23,%r7,%r23   ;offset 0x930
        +$00060024
        +        SUB     %r4,%r31,%r25   ;offset 0x934
        +        AND     %r25,%r19,%r26  ;offset 0x938
        +        CMPB,*<>,N      %r0,%r26,$00060046      ;offset 0x93c
        +        DEPD,Z  %r25,31,32,%r20 ;offset 0x940
        +        OR      %r20,%r24,%r21  ;offset 0x944
        +        CMPB,*<<,N      %r21,%r23,$0006002A     ;offset 0x948
        +        SUB     %r31,%r2,%r31   ;offset 0x94c
        +$00060046
        +$0006002E
        +        DEPD,Z  %r23,31,32,%r25 ;offset 0x950
        +        EXTRD,U %r23,31,32,%r26 ;offset 0x954
        +        AND     %r25,%r19,%r24  ;offset 0x958
        +        ADD,L   %r31,%r26,%r31  ;offset 0x95c
        +        CMPCLR,*>>=     %r5,%r24,%r0    ;offset 0x960
        +        LDO     1(%r31),%r31    ;offset 0x964
        +$00060032
        +        CMPB,*<<=,N     %r31,%r4,$00060036      ;offset 0x968
        +        LDO     -1(%r29),%r29   ;offset 0x96c
        +        ADD,L   %r4,%r3,%r4     ;offset 0x970
        +$00060036
        +        ADDIB,=,N       -1,%r8,$D0      ;offset 0x974
        +        SUB     %r5,%r24,%r28   ;offset 0x978
        +$0006003A
        +        SUB     %r4,%r31,%r24   ;offset 0x97c
        +        SHRPD   %r24,%r28,32,%r4        ;offset 0x980
        +        DEPD,Z  %r29,31,32,%r9  ;offset 0x984
        +        DEPD,Z  %r28,31,32,%r5  ;offset 0x988
        +$0006001C
        +        EXTRD,U %r4,31,32,%r31  ;offset 0x98c
        +        CMPB,*<>,N      %r31,%r2,$00060020      ;offset 0x990
        +        MOVB,TR %r6,%r29,$D1    ;offset 0x994
        +        STD     %r29,-152(%r30) ;offset 0x998
        +$0006000C
        +        EXTRD,U %r3,31,32,%r25  ;offset 0x99c
        +        COPY    %r3,%r26        ;offset 0x9a0
        +        EXTRD,U %r3,31,32,%r9   ;offset 0x9a4
        +        EXTRD,U %r4,31,32,%r8   ;offset 0x9a8
        +        .CALL   ARGW0=GR,ARGW1=GR,RTNVAL=GR     ;in=25,26;out=28;
        +        B,L     BN_num_bits_word,%r2    ;offset 0x9ac
        +        EXTRD,U %r5,31,32,%r7   ;offset 0x9b0
        +        LDI     64,%r20 ;offset 0x9b4
        +        DEPD    %r7,31,32,%r5   ;offset 0x9b8
        +        DEPD    %r8,31,32,%r4   ;offset 0x9bc
        +        DEPD    %r9,31,32,%r3   ;offset 0x9c0
        +        CMPB,=  %r28,%r20,$00060012     ;offset 0x9c4
        +        COPY    %r28,%r24       ;offset 0x9c8
        +        MTSARCM %r24    ;offset 0x9cc
        +        DEPDI,Z -1,%sar,1,%r19  ;offset 0x9d0
        +        CMPB,*>>,N      %r4,%r19,$D2    ;offset 0x9d4
        +$00060012
        +        SUBI    64,%r24,%r31    ;offset 0x9d8
        +        CMPCLR,*<<      %r4,%r3,%r0     ;offset 0x9dc
        +        SUB     %r4,%r3,%r4     ;offset 0x9e0
        +$00060016
        +        CMPB,=  %r31,%r0,$0006001A      ;offset 0x9e4
        +        COPY    %r0,%r9 ;offset 0x9e8
        +        MTSARCM %r31    ;offset 0x9ec
        +        DEPD,Z  %r3,%sar,64,%r3 ;offset 0x9f0
        +        SUBI    64,%r31,%r26    ;offset 0x9f4
        +        MTSAR   %r26    ;offset 0x9f8
        +        SHRPD   %r4,%r5,%sar,%r4        ;offset 0x9fc
        +        MTSARCM %r31    ;offset 0xa00
        +        DEPD,Z  %r5,%sar,64,%r5 ;offset 0xa04
        +$0006001A
        +        DEPDI,Z -1,31,32,%r19   ;offset 0xa08
        +        AND     %r3,%r19,%r29   ;offset 0xa0c
        +        EXTRD,U %r29,31,32,%r2  ;offset 0xa10
        +        DEPDI,Z -1,63,32,%r6    ;offset 0xa14
        +        MOVIB,TR        2,%r8,$0006001C ;offset 0xa18
        +        EXTRD,U %r3,63,32,%r7   ;offset 0xa1c
        +$D2
        +        ;--- not PIC	ADDIL   LR'__iob-$global$,%r27,%r1      ;offset 0xa20
        +        ;--- not PIC	LDIL    LR'C$7,%r21     ;offset 0xa24
        +        ;--- not PIC	LDO     RR'__iob-$global$+32(%r1),%r26  ;offset 0xa28
        +        ;--- not PIC	.CALL   ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR    ;in=24,25,26;out=28;
        +        ;--- not PIC	B,L     fprintf,%r2     ;offset 0xa2c
        +        ;--- not PIC	LDO     RR'C$7(%r21),%r25       ;offset 0xa30
        +        .CALL           ;
        +        B,L     abort,%r2       ;offset 0xa34
        +        NOP             ;offset 0xa38
        +        B       $D3     ;offset 0xa3c
        +        LDW     -212(%r30),%r2  ;offset 0xa40
        +$00060020
        +        COPY    %r4,%r26        ;offset 0xa44
        +        EXTRD,U %r4,31,32,%r25  ;offset 0xa48
        +        COPY    %r2,%r24        ;offset 0xa4c
        +        .CALL   ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
        +        B,L     $$div2U,%r31    ;offset 0xa50
        +        EXTRD,U %r2,31,32,%r23  ;offset 0xa54
        +        DEPD    %r28,31,32,%r29 ;offset 0xa58
        +$00060022
        +        STD     %r29,-152(%r30) ;offset 0xa5c
        +$D1
        +        AND     %r5,%r19,%r24   ;offset 0xa60
        +        EXTRD,U %r24,31,32,%r24 ;offset 0xa64
        +        STW     %r2,-160(%r30)  ;offset 0xa68
        +        STW     %r7,-128(%r30)  ;offset 0xa6c
        +        FLDD    -152(%r30),%fr4 ;offset 0xa70
        +        FLDD    -152(%r30),%fr7 ;offset 0xa74
        +        FLDW    -160(%r30),%fr8L        ;offset 0xa78
        +        FLDW    -128(%r30),%fr5L        ;offset 0xa7c
        +        XMPYU   %fr8L,%fr7L,%fr10       ;offset 0xa80
        +        FSTD    %fr10,-136(%r30)        ;offset 0xa84
        +        XMPYU   %fr8L,%fr7R,%fr22       ;offset 0xa88
        +        FSTD    %fr22,-144(%r30)        ;offset 0xa8c
        +        XMPYU   %fr5L,%fr4L,%fr11       ;offset 0xa90
        +        XMPYU   %fr5L,%fr4R,%fr23       ;offset 0xa94
        +        FSTD    %fr11,-112(%r30)        ;offset 0xa98
        +        FSTD    %fr23,-120(%r30)        ;offset 0xa9c
        +        LDD     -136(%r30),%r28 ;offset 0xaa0
        +        DEPD,Z  %r28,31,32,%r31 ;offset 0xaa4
        +        LDD     -144(%r30),%r20 ;offset 0xaa8
        +        ADD,L   %r20,%r31,%r31  ;offset 0xaac
        +        LDD     -112(%r30),%r22 ;offset 0xab0
        +        DEPD,Z  %r22,31,32,%r22 ;offset 0xab4
        +        LDD     -120(%r30),%r21 ;offset 0xab8
        +        B       $00060024       ;offset 0xabc
        +        ADD,L   %r21,%r22,%r23  ;offset 0xac0
        +$D0
        +        OR      %r9,%r29,%r29   ;offset 0xac4
        +$00060040
        +        EXTRD,U %r29,31,32,%r28 ;offset 0xac8
        +$00060002
        +$L2
        +        LDW     -212(%r30),%r2  ;offset 0xacc
        +$D3
        +        LDW     -168(%r30),%r9  ;offset 0xad0
        +        LDD     -176(%r30),%r8  ;offset 0xad4
        +        EXTRD,U %r8,31,32,%r7   ;offset 0xad8
        +        LDD     -184(%r30),%r6  ;offset 0xadc
        +        EXTRD,U %r6,31,32,%r5   ;offset 0xae0
        +        LDW     -188(%r30),%r4  ;offset 0xae4
        +        BVE     (%r2)   ;offset 0xae8
        +        .EXIT
        +        LDW,MB  -192(%r30),%r3  ;offset 0xaec
        +	.PROCEND	;in=23,25;out=28,29;fpin=105,107;
        +
        +
        +
        +
        +;----------------------------------------------------------------------------
        +;
        +; 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	
        +
        +
        +;--- not PIC	.SPACE	$TEXT$
        +;--- not PIC	.SUBSPA	$CODE$
        +;--- not PIC	.SPACE	$PRIVATE$,SORT=16
        +;--- not PIC	.IMPORT	$global$,DATA
        +;--- not PIC	.SPACE	$TEXT$
        +;--- not PIC	.SUBSPA	$CODE$
        +;--- not PIC	.SUBSPA	$LIT$,ACCESS=0x2c
        +;--- not PIC	C$7
        +;--- not PIC	.ALIGN	8
        +;--- not PIC	.STRINGZ	"Division would overflow (%d)\n"
        +	.END
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/pa-risc2W.s b/vendor/openssl/openssl/crypto/bn/asm/pa-risc2W.s
        new file mode 100644
        index 000000000..a99545754
        --- /dev/null
        +++ b/vendor/openssl/openssl/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<<i) (forward) 
        +
        +$00000012
        +    SUBI    64,%r24,%r31                       ; i = 64 - i;
        +    CMPCLR,*<< %r4,%r3,%r0                     ; if (h >= 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<tl)
        +    LDO     1(%r31),%r31                 ; th++;
        +    CMPB,*<<=,N     %r31,%r4,$00000036   ;if (n < th) (forward)
        +    LDO     -1(%r29),%r29                ;q--; 
        +    ADD,L   %r4,%r3,%r4                  ;h += d;
        +$00000036
        +    ADDIB,=,N       -1,%r9,$D1 ;if (--count == 0) break (forward) 
        +    SUB     %r5,%r24,%r28                ; l -= tl;
        +    SUB     %r4,%r31,%r24                ; h -= th;
        +    SHRPD   %r24,%r28,32,%r4             ; h = ((h<<32)|(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$,ACCESS=0x2c
        +C$4
        +	.ALIGN	8
        +	.STRINGZ	"Division would overflow (%d)\n"
        +	.END
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/parisc-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/parisc-mont.pl
        new file mode 100644
        index 000000000..4a766a87f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/parisc-mont.pl
        @@ -0,0 +1,993 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# On PA-7100LC this module performs ~90-50% better, less for longer
        +# keys, than code generated by gcc 3.2 for PA-RISC 1.1. Latter means
        +# that compiler utilized xmpyu instruction to perform 32x32=64-bit
        +# multiplication, which in turn means that "baseline" performance was
        +# optimal in respect to instruction set capabilities. Fair comparison
        +# with vendor compiler is problematic, because OpenSSL doesn't define
        +# BN_LLONG [presumably] for historical reasons, which drives compiler
        +# toward 4 times 16x16=32-bit multiplicatons [plus complementary
        +# shifts and additions] instead. This means that you should observe
        +# several times improvement over code generated by vendor compiler
        +# for PA-RISC 1.1, but the "baseline" is far from optimal. The actual
        +# improvement coefficient was never collected on PA-7100LC, or any
        +# other 1.1 CPU, because I don't have access to such machine with
        +# vendor compiler. But to give you a taste, PA-RISC 1.1 code path
        +# reportedly outperformed code generated by cc +DA1.1 +O3 by factor
        +# of ~5x on PA-8600.
        +#
        +# On PA-RISC 2.0 it has to compete with pa-risc2[W].s, which is
        +# reportedly ~2x faster than vendor compiler generated code [according
        +# to comment in pa-risc2[W].s]. Here comes a catch. Execution core of
        +# this implementation is actually 32-bit one, in the sense that it
        +# operates on 32-bit values. But pa-risc2[W].s operates on arrays of
        +# 64-bit BN_LONGs... How do they interoperate then? No problem. This
        +# module picks halves of 64-bit values in reverse order and pretends
        +# they were 32-bit BN_LONGs. But can 32-bit core compete with "pure"
        +# 64-bit code such as pa-risc2[W].s then? Well, the thing is that
        +# 32x32=64-bit multiplication is the best even PA-RISC 2.0 can do,
        +# i.e. there is no "wider" multiplication like on most other 64-bit
        +# platforms. This means that even being effectively 32-bit, this
        +# implementation performs "64-bit" computational task in same amount
        +# of arithmetic operations, most notably multiplications. It requires
        +# more memory references, most notably to tp[num], but this doesn't
        +# seem to exhaust memory port capacity. And indeed, dedicated PA-RISC
        +# 2.0 code path, provides virtually same performance as pa-risc2[W].s:
        +# it's ~10% better for shortest key length and ~10% worse for longest
        +# one.
        +#
        +# In case it wasn't clear. The module has two distinct code paths:
        +# PA-RISC 1.1 and PA-RISC 2.0 ones. Latter features carry-free 64-bit
        +# additions and 64-bit integer loads, not to mention specific
        +# instruction scheduling. In 64-bit build naturally only 2.0 code path
        +# is assembled. In 32-bit application context both code paths are
        +# assembled, PA-RISC 2.0 CPU is detected at run-time and proper path
        +# is taken automatically. Also, in 32-bit build the module imposes
        +# couple of limitations: vector lengths has to be even and vector
        +# addresses has to be 64-bit aligned. Normally neither is a problem:
        +# most common key lengths are even and vectors are commonly malloc-ed,
        +# which ensures alignment.
        +#
        +# Special thanks to polarhome.com for providing HP-UX account on
        +# PA-RISC 1.1 machine, and to correspondent who chose to remain
        +# anonymous for testing the code on PA-RISC 2.0 machine.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +
        +$flavour = shift;
        +$output = shift;
        +
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$FRAME_MARKER	=80;
        +	$SAVED_RP	=16;
        +	$PUSH		="std";
        +	$PUSHMA		="std,ma";
        +	$POP		="ldd";
        +	$POPMB		="ldd,mb";
        +	$BN_SZ		=$SIZE_T;
        +} else {
        +	$LEVEL		="1.1";	#$LEVEL.="\n\t.ALLOW\t2.0";
        +	$SIZE_T		=4;
        +	$FRAME_MARKER	=48;
        +	$SAVED_RP	=20;
        +	$PUSH		="stw";
        +	$PUSHMA		="stwm";
        +	$POP		="ldw";
        +	$POPMB		="ldwm";
        +	$BN_SZ		=$SIZE_T;
        +	if (open CONF,"<${dir}../../opensslconf.h") {
        +	    while(<CONF>) {
        +		if (m/#\s*define\s+SIXTY_FOUR_BIT/) {
        +		    $BN_SZ=8;
        +		    $LEVEL="2.0";
        +		    last;
        +		}
        +	    }
        +	    close CONF;
        +	}
        +}
        +
        +$FRAME=8*$SIZE_T+$FRAME_MARKER;	# 8 saved regs + frame marker
        +				#                [+ argument transfer]
        +$LOCALS=$FRAME-$FRAME_MARKER;
        +$FRAME+=32;			# local variables
        +
        +$tp="%r31";
        +$ti1="%r29";
        +$ti0="%r28";
        +
        +$rp="%r26";
        +$ap="%r25";
        +$bp="%r24";
        +$np="%r23";
        +$n0="%r22";	# passed through stack in 32-bit
        +$num="%r21";	# passed through stack in 32-bit
        +$idx="%r20";
        +$arrsz="%r19";
        +
        +$nm1="%r7";
        +$nm0="%r6";
        +$ab1="%r5";
        +$ab0="%r4";
        +
        +$fp="%r3";
        +$hi1="%r2";
        +$hi0="%r1";
        +
        +$xfer=$n0;	# accomodates [-16..15] offset in fld[dw]s
        +
        +$fm0="%fr4";	$fti=$fm0;
        +$fbi="%fr5L";
        +$fn0="%fr5R";
        +$fai="%fr6";	$fab0="%fr7";	$fab1="%fr8";
        +$fni="%fr9";	$fnm0="%fr10";	$fnm1="%fr11";
        +
        +$code=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.EXPORT	bn_mul_mont,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
        +	.ALIGN	64
        +bn_mul_mont
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-8*$SIZE_T`,NO_CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=6
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)		; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	ldo	-$FRAME(%sp),$fp
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	ldw	`-$FRAME_MARKER-4`($fp),$n0
        +	ldw	`-$FRAME_MARKER-8`($fp),$num
        +	nop
        +	nop					; alignment
        +___
        +$code.=<<___ if ($BN_SZ==4);
        +	comiclr,<=	6,$num,%r0		; are vectors long enough?
        +	b		L\$abort
        +	ldi		0,%r28			; signal "unhandled"
        +	add,ev		%r0,$num,$num		; is $num even?
        +	b		L\$abort
        +	nop
        +	or		$ap,$np,$ti1
        +	extru,=		$ti1,31,3,%r0		; are ap and np 64-bit aligned?
        +	b		L\$abort
        +	nop
        +	nop					; alignment
        +	nop
        +
        +	fldws		0($n0),${fn0}
        +	fldws,ma	4($bp),${fbi}		; bp[0]
        +___
        +$code.=<<___ if ($BN_SZ==8);
        +	comib,>		3,$num,L\$abort		; are vectors long enough?
        +	ldi		0,%r28			; signal "unhandled"
        +	addl		$num,$num,$num		; I operate on 32-bit values
        +
        +	fldws		4($n0),${fn0}		; only low part of n0
        +	fldws		4($bp),${fbi}		; bp[0] in flipped word order
        +___
        +$code.=<<___;
        +	fldds		0($ap),${fai}		; ap[0,1]
        +	fldds		0($np),${fni}		; np[0,1]
        +
        +	sh2addl		$num,%r0,$arrsz
        +	ldi		31,$hi0
        +	ldo		36($arrsz),$hi1		; space for tp[num+1]
        +	andcm		$hi1,$hi0,$hi1		; align
        +	addl		$hi1,%sp,%sp
        +	$PUSH		$fp,-$SIZE_T(%sp)
        +
        +	ldo		`$LOCALS+16`($fp),$xfer
        +	ldo		`$LOCALS+32+4`($fp),$tp
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[0]
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[0]
        +	xmpyu		${fn0},${fab0}R,${fm0}
        +
        +	addl		$arrsz,$ap,$ap		; point at the end
        +	addl		$arrsz,$np,$np
        +	subi		0,$arrsz,$idx		; j=0
        +	ldo		8($idx),$idx		; j++++
        +
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[0]*m
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[1]*m
        +	fstds		${fab0},-16($xfer)
        +	fstds		${fnm0},-8($xfer)
        +	fstds		${fab1},0($xfer)
        +	fstds		${fnm1},8($xfer)
        +	 flddx		$idx($ap),${fai}	; ap[2,3]
        +	 flddx		$idx($np),${fni}	; np[2,3]
        +___
        +$code.=<<___ if ($BN_SZ==4);
        +	mtctl		$hi0,%cr11		; $hi0 still holds 31
        +	extrd,u,*=	$hi0,%sar,1,$hi0	; executes on PA-RISC 1.0
        +	b		L\$parisc11
        +	nop
        +___
        +$code.=<<___;					# PA-RISC 2.0 code-path
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	ldd		-16($xfer),$ab0
        +	fstds		${fab0},-16($xfer)
        +
        +	extrd,u		$ab0,31,32,$hi0
        +	extrd,u		$ab0,63,32,$ab0
        +	ldd		-8($xfer),$nm0
        +	fstds		${fnm0},-8($xfer)
        +	 ldo		8($idx),$idx		; j++++
        +	 addl		$ab0,$nm0,$nm0		; low part is discarded
        +	 extrd,u	$nm0,31,32,$hi1
        +
        +L\$1st
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[0]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
        +	ldd		0($xfer),$ab1
        +	fstds		${fab1},0($xfer)
        +	 addl		$hi0,$ab1,$ab1
        +	 extrd,u	$ab1,31,32,$hi0
        +	ldd		8($xfer),$nm1
        +	fstds		${fnm1},8($xfer)
        +	 extrd,u	$ab1,63,32,$ab1
        +	 addl		$hi1,$nm1,$nm1
        +	flddx		$idx($ap),${fai}	; ap[j,j+1]
        +	flddx		$idx($np),${fni}	; np[j,j+1]
        +	 addl		$ab1,$nm1,$nm1
        +	 extrd,u	$nm1,31,32,$hi1
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	ldd		-16($xfer),$ab0
        +	fstds		${fab0},-16($xfer)
        +	 addl		$hi0,$ab0,$ab0
        +	 extrd,u	$ab0,31,32,$hi0
        +	ldd		-8($xfer),$nm0
        +	fstds		${fnm0},-8($xfer)
        +	 extrd,u	$ab0,63,32,$ab0
        +	 addl		$hi1,$nm0,$nm0
        +	stw		$nm1,-4($tp)		; tp[j-1]
        +	 addl		$ab0,$nm0,$nm0
        +	 stw,ma		$nm0,8($tp)		; tp[j-1]
        +	addib,<>	8,$idx,L\$1st		; j++++
        +	 extrd,u	$nm0,31,32,$hi1
        +
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[0]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
        +	ldd		0($xfer),$ab1
        +	fstds		${fab1},0($xfer)
        +	 addl		$hi0,$ab1,$ab1
        +	 extrd,u	$ab1,31,32,$hi0
        +	ldd		8($xfer),$nm1
        +	fstds		${fnm1},8($xfer)
        +	 extrd,u	$ab1,63,32,$ab1
        +	 addl		$hi1,$nm1,$nm1
        +	ldd		-16($xfer),$ab0
        +	 addl		$ab1,$nm1,$nm1
        +	ldd		-8($xfer),$nm0
        +	 extrd,u	$nm1,31,32,$hi1
        +
        +	 addl		$hi0,$ab0,$ab0
        +	 extrd,u	$ab0,31,32,$hi0
        +	stw		$nm1,-4($tp)		; tp[j-1]
        +	 extrd,u	$ab0,63,32,$ab0
        +	 addl		$hi1,$nm0,$nm0
        +	ldd		0($xfer),$ab1
        +	 addl		$ab0,$nm0,$nm0
        +	ldd,mb		8($xfer),$nm1
        +	 extrd,u	$nm0,31,32,$hi1
        +	stw,ma		$nm0,8($tp)		; tp[j-1]
        +
        +	ldo		-1($num),$num		; i--
        +	subi		0,$arrsz,$idx		; j=0
        +___
        +$code.=<<___ if ($BN_SZ==4);
        +	fldws,ma	4($bp),${fbi}		; bp[1]
        +___
        +$code.=<<___ if ($BN_SZ==8);
        +	fldws		0($bp),${fbi}		; bp[1] in flipped word order
        +___
        +$code.=<<___;
        +	 flddx		$idx($ap),${fai}	; ap[0,1]
        +	 flddx		$idx($np),${fni}	; np[0,1]
        +	 fldws		8($xfer),${fti}R	; tp[0]
        +	addl		$hi0,$ab1,$ab1
        +	 extrd,u	$ab1,31,32,$hi0
        +	 extrd,u	$ab1,63,32,$ab1
        +	 ldo		8($idx),$idx		; j++++
        +	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[1]
        +	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[1]
        +	addl		$hi1,$nm1,$nm1
        +	addl		$ab1,$nm1,$nm1
        +	extrd,u		$nm1,31,32,$hi1
        +	 fstws,mb	${fab0}L,-8($xfer)	; save high part
        +	stw		$nm1,-4($tp)		; tp[j-1]
        +
        +	 fcpy,sgl	%fr0,${fti}L		; zero high part
        +	 fcpy,sgl	%fr0,${fab0}L
        +	addl		$hi1,$hi0,$hi0
        +	extrd,u		$hi0,31,32,$hi1
        +	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
        +	 fcnvxf,dbl,dbl	${fab0},${fab0}
        +	stw		$hi0,0($tp)
        +	stw		$hi1,4($tp)
        +
        +	fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
        +	fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
        +	xmpyu		${fn0},${fab0}R,${fm0}
        +	ldo		`$LOCALS+32+4`($fp),$tp
        +L\$outer
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[0]*m
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[1]*m
        +	fstds		${fab0},-16($xfer)	; 33-bit value
        +	fstds		${fnm0},-8($xfer)
        +	 flddx		$idx($ap),${fai}	; ap[2]
        +	 flddx		$idx($np),${fni}	; np[2]
        +	 ldo		8($idx),$idx		; j++++
        +	ldd		-16($xfer),$ab0		; 33-bit value
        +	ldd		-8($xfer),$nm0
        +	ldw		0($xfer),$hi0		; high part
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	 extrd,u	$ab0,31,32,$ti0		; carry bit
        +	 extrd,u	$ab0,63,32,$ab0
        +	fstds		${fab1},0($xfer)
        +	 addl		$ti0,$hi0,$hi0		; account carry bit
        +	fstds		${fnm1},8($xfer)
        +	 addl		$ab0,$nm0,$nm0		; low part is discarded
        +	ldw		0($tp),$ti1		; tp[1]
        +	 extrd,u	$nm0,31,32,$hi1
        +	fstds		${fab0},-16($xfer)
        +	fstds		${fnm0},-8($xfer)
        +
        +L\$inner
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[i]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
        +	ldd		0($xfer),$ab1
        +	fstds		${fab1},0($xfer)
        +	 addl		$hi0,$ti1,$ti1
        +	 addl		$ti1,$ab1,$ab1
        +	ldd		8($xfer),$nm1
        +	fstds		${fnm1},8($xfer)
        +	 extrd,u	$ab1,31,32,$hi0
        +	 extrd,u	$ab1,63,32,$ab1
        +	flddx		$idx($ap),${fai}	; ap[j,j+1]
        +	flddx		$idx($np),${fni}	; np[j,j+1]
        +	 addl		$hi1,$nm1,$nm1
        +	 addl		$ab1,$nm1,$nm1
        +	ldw		4($tp),$ti0		; tp[j]
        +	stw		$nm1,-4($tp)		; tp[j-1]
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	ldd		-16($xfer),$ab0
        +	fstds		${fab0},-16($xfer)
        +	 addl		$hi0,$ti0,$ti0
        +	 addl		$ti0,$ab0,$ab0
        +	ldd		-8($xfer),$nm0
        +	fstds		${fnm0},-8($xfer)
        +	 extrd,u	$ab0,31,32,$hi0
        +	 extrd,u	$nm1,31,32,$hi1
        +	ldw		8($tp),$ti1		; tp[j]
        +	 extrd,u	$ab0,63,32,$ab0
        +	 addl		$hi1,$nm0,$nm0
        +	 addl		$ab0,$nm0,$nm0
        +	 stw,ma		$nm0,8($tp)		; tp[j-1]
        +	addib,<>	8,$idx,L\$inner		; j++++
        +	 extrd,u	$nm0,31,32,$hi1
        +
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[i]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
        +	ldd		0($xfer),$ab1
        +	fstds		${fab1},0($xfer)
        +	 addl		$hi0,$ti1,$ti1
        +	 addl		$ti1,$ab1,$ab1
        +	ldd		8($xfer),$nm1
        +	fstds		${fnm1},8($xfer)
        +	 extrd,u	$ab1,31,32,$hi0
        +	 extrd,u	$ab1,63,32,$ab1
        +	ldw		4($tp),$ti0		; tp[j]
        +	 addl		$hi1,$nm1,$nm1
        +	 addl		$ab1,$nm1,$nm1
        +	ldd		-16($xfer),$ab0
        +	ldd		-8($xfer),$nm0
        +	 extrd,u	$nm1,31,32,$hi1
        +
        +	addl		$hi0,$ab0,$ab0
        +	 addl		$ti0,$ab0,$ab0
        +	 stw		$nm1,-4($tp)		; tp[j-1]
        +	 extrd,u	$ab0,31,32,$hi0
        +	ldw		8($tp),$ti1		; tp[j]
        +	 extrd,u	$ab0,63,32,$ab0
        +	 addl		$hi1,$nm0,$nm0
        +	ldd		0($xfer),$ab1
        +	 addl		$ab0,$nm0,$nm0
        +	ldd,mb		8($xfer),$nm1
        +	 extrd,u	$nm0,31,32,$hi1
        +	 stw,ma		$nm0,8($tp)		; tp[j-1]
        +
        +	addib,=		-1,$num,L\$outerdone	; i--
        +	subi		0,$arrsz,$idx		; j=0
        +___
        +$code.=<<___ if ($BN_SZ==4);
        +	fldws,ma	4($bp),${fbi}		; bp[i]
        +___
        +$code.=<<___ if ($BN_SZ==8);
        +	ldi		12,$ti0			; bp[i] in flipped word order
        +	addl,ev		%r0,$num,$num
        +	ldi		-4,$ti0
        +	addl		$ti0,$bp,$bp
        +	fldws		0($bp),${fbi}
        +___
        +$code.=<<___;
        +	 flddx		$idx($ap),${fai}	; ap[0]
        +	addl		$hi0,$ab1,$ab1
        +	 flddx		$idx($np),${fni}	; np[0]
        +	 fldws		8($xfer),${fti}R	; tp[0]
        +	addl		$ti1,$ab1,$ab1
        +	extrd,u		$ab1,31,32,$hi0
        +	extrd,u		$ab1,63,32,$ab1
        +
        +	 ldo		8($idx),$idx		; j++++
        +	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[i]
        +	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[i]
        +	ldw		4($tp),$ti0		; tp[j]
        +
        +	addl		$hi1,$nm1,$nm1
        +	 fstws,mb	${fab0}L,-8($xfer)	; save high part
        +	addl		$ab1,$nm1,$nm1
        +	extrd,u		$nm1,31,32,$hi1
        +	 fcpy,sgl	%fr0,${fti}L		; zero high part
        +	 fcpy,sgl	%fr0,${fab0}L
        +	stw		$nm1,-4($tp)		; tp[j-1]
        +
        +	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
        +	 fcnvxf,dbl,dbl	${fab0},${fab0}
        +	addl		$hi1,$hi0,$hi0
        +	 fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
        +	addl		$ti0,$hi0,$hi0
        +	extrd,u		$hi0,31,32,$hi1
        +	 fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
        +	stw		$hi0,0($tp)
        +	stw		$hi1,4($tp)
        +	 xmpyu		${fn0},${fab0}R,${fm0}
        +
        +	b		L\$outer
        +	ldo		`$LOCALS+32+4`($fp),$tp
        +
        +L\$outerdone
        +	addl		$hi0,$ab1,$ab1
        +	addl		$ti1,$ab1,$ab1
        +	extrd,u		$ab1,31,32,$hi0
        +	extrd,u		$ab1,63,32,$ab1
        +
        +	ldw		4($tp),$ti0		; tp[j]
        +
        +	addl		$hi1,$nm1,$nm1
        +	addl		$ab1,$nm1,$nm1
        +	extrd,u		$nm1,31,32,$hi1
        +	stw		$nm1,-4($tp)		; tp[j-1]
        +
        +	addl		$hi1,$hi0,$hi0
        +	addl		$ti0,$hi0,$hi0
        +	extrd,u		$hi0,31,32,$hi1
        +	stw		$hi0,0($tp)
        +	stw		$hi1,4($tp)
        +
        +	ldo		`$LOCALS+32`($fp),$tp
        +	sub		%r0,%r0,%r0		; clear borrow
        +___
        +$code.=<<___ if ($BN_SZ==4);
        +	ldws,ma		4($tp),$ti0
        +	extru,=		$rp,31,3,%r0		; is rp 64-bit aligned?
        +	b		L\$sub_pa11
        +	addl		$tp,$arrsz,$tp
        +L\$sub
        +	ldwx		$idx($np),$hi0
        +	subb		$ti0,$hi0,$hi1
        +	ldwx		$idx($tp),$ti0
        +	addib,<>	4,$idx,L\$sub
        +	stws,ma		$hi1,4($rp)
        +
        +	subb		$ti0,%r0,$hi1
        +	ldo		-4($tp),$tp
        +___
        +$code.=<<___ if ($BN_SZ==8);
        +	ldd,ma		8($tp),$ti0
        +L\$sub
        +	ldd		$idx($np),$hi0
        +	shrpd		$ti0,$ti0,32,$ti0	; flip word order
        +	std		$ti0,-8($tp)		; save flipped value
        +	sub,db		$ti0,$hi0,$hi1
        +	ldd,ma		8($tp),$ti0
        +	addib,<>	8,$idx,L\$sub
        +	std,ma		$hi1,8($rp)
        +
        +	extrd,u		$ti0,31,32,$ti0		; carry in flipped word order
        +	sub,db		$ti0,%r0,$hi1
        +	ldo		-8($tp),$tp
        +___
        +$code.=<<___;
        +	and		$tp,$hi1,$ap
        +	andcm		$rp,$hi1,$bp
        +	or		$ap,$bp,$np
        +
        +	sub		$rp,$arrsz,$rp		; rewind rp
        +	subi		0,$arrsz,$idx
        +	ldo		`$LOCALS+32`($fp),$tp
        +L\$copy
        +	ldd		$idx($np),$hi0
        +	std,ma		%r0,8($tp)
        +	addib,<>	8,$idx,.-8		; L\$copy
        +	std,ma		$hi0,8($rp)	
        +___
        +
        +if ($BN_SZ==4) {				# PA-RISC 1.1 code-path
        +$ablo=$ab0;
        +$abhi=$ab1;
        +$nmlo0=$nm0;
        +$nmhi0=$nm1;
        +$nmlo1="%r9";
        +$nmhi1="%r8";
        +
        +$code.=<<___;
        +	b		L\$done
        +	nop
        +
        +	.ALIGN		8
        +L\$parisc11
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	ldw		-12($xfer),$ablo
        +	ldw		-16($xfer),$hi0
        +	ldw		-4($xfer),$nmlo0
        +	ldw		-8($xfer),$nmhi0
        +	fstds		${fab0},-16($xfer)
        +	fstds		${fnm0},-8($xfer)
        +
        +	 ldo		8($idx),$idx		; j++++
        +	 add		$ablo,$nmlo0,$nmlo0	; discarded
        +	 addc		%r0,$nmhi0,$hi1
        +	ldw		4($xfer),$ablo
        +	ldw		0($xfer),$abhi
        +	nop
        +
        +L\$1st_pa11
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[0]
        +	flddx		$idx($ap),${fai}	; ap[j,j+1]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
        +	flddx		$idx($np),${fni}	; np[j,j+1]
        +	 add		$hi0,$ablo,$ablo
        +	ldw		12($xfer),$nmlo1
        +	 addc		%r0,$abhi,$hi0
        +	ldw		8($xfer),$nmhi1
        +	 add		$ablo,$nmlo1,$nmlo1
        +	fstds		${fab1},0($xfer)
        +	 addc		%r0,$nmhi1,$nmhi1
        +	fstds		${fnm1},8($xfer)
        +	 add		$hi1,$nmlo1,$nmlo1
        +	ldw		-12($xfer),$ablo
        +	 addc		%r0,$nmhi1,$hi1
        +	ldw		-16($xfer),$abhi
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
        +	ldw		-4($xfer),$nmlo0
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	ldw		-8($xfer),$nmhi0
        +	 add		$hi0,$ablo,$ablo
        +	stw		$nmlo1,-4($tp)		; tp[j-1]
        +	 addc		%r0,$abhi,$hi0
        +	fstds		${fab0},-16($xfer)
        +	 add		$ablo,$nmlo0,$nmlo0
        +	fstds		${fnm0},-8($xfer)
        +	 addc		%r0,$nmhi0,$nmhi0
        +	ldw		0($xfer),$abhi
        +	 add		$hi1,$nmlo0,$nmlo0
        +	ldw		4($xfer),$ablo
        +	 stws,ma	$nmlo0,8($tp)		; tp[j-1]
        +	addib,<>	8,$idx,L\$1st_pa11	; j++++
        +	 addc		%r0,$nmhi0,$hi1
        +
        +	 ldw		8($xfer),$nmhi1
        +	 ldw		12($xfer),$nmlo1
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[0]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
        +	 add		$hi0,$ablo,$ablo
        +	fstds		${fab1},0($xfer)
        +	 addc		%r0,$abhi,$hi0
        +	fstds		${fnm1},8($xfer)
        +	 add		$ablo,$nmlo1,$nmlo1
        +	ldw		-16($xfer),$abhi
        +	 addc		%r0,$nmhi1,$nmhi1
        +	ldw		-12($xfer),$ablo
        +	 add		$hi1,$nmlo1,$nmlo1
        +	ldw		-8($xfer),$nmhi0
        +	 addc		%r0,$nmhi1,$hi1
        +	ldw		-4($xfer),$nmlo0
        +
        +	 add		$hi0,$ablo,$ablo
        +	stw		$nmlo1,-4($tp)		; tp[j-1]
        +	 addc		%r0,$abhi,$hi0
        +	ldw		0($xfer),$abhi
        +	 add		$ablo,$nmlo0,$nmlo0
        +	ldw		4($xfer),$ablo
        +	 addc		%r0,$nmhi0,$nmhi0
        +	ldws,mb		8($xfer),$nmhi1
        +	 add		$hi1,$nmlo0,$nmlo0
        +	ldw		4($xfer),$nmlo1
        +	 addc		%r0,$nmhi0,$hi1
        +	stws,ma		$nmlo0,8($tp)		; tp[j-1]
        +
        +	ldo		-1($num),$num		; i--
        +	subi		0,$arrsz,$idx		; j=0
        +
        +	 fldws,ma	4($bp),${fbi}		; bp[1]
        +	 flddx		$idx($ap),${fai}	; ap[0,1]
        +	 flddx		$idx($np),${fni}	; np[0,1]
        +	 fldws		8($xfer),${fti}R	; tp[0]
        +	add		$hi0,$ablo,$ablo
        +	addc		%r0,$abhi,$hi0
        +	 ldo		8($idx),$idx		; j++++
        +	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[1]
        +	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[1]
        +	add		$hi1,$nmlo1,$nmlo1
        +	addc		%r0,$nmhi1,$nmhi1
        +	add		$ablo,$nmlo1,$nmlo1
        +	addc		%r0,$nmhi1,$hi1
        +	 fstws,mb	${fab0}L,-8($xfer)	; save high part
        +	stw		$nmlo1,-4($tp)		; tp[j-1]
        +
        +	 fcpy,sgl	%fr0,${fti}L		; zero high part
        +	 fcpy,sgl	%fr0,${fab0}L
        +	add		$hi1,$hi0,$hi0
        +	addc		%r0,%r0,$hi1
        +	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
        +	 fcnvxf,dbl,dbl	${fab0},${fab0}
        +	stw		$hi0,0($tp)
        +	stw		$hi1,4($tp)
        +
        +	fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
        +	fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
        +	xmpyu		${fn0},${fab0}R,${fm0}
        +	ldo		`$LOCALS+32+4`($fp),$tp
        +L\$outer_pa11
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[0]*m
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[1]*m
        +	fstds		${fab0},-16($xfer)	; 33-bit value
        +	fstds		${fnm0},-8($xfer)
        +	 flddx		$idx($ap),${fai}	; ap[2,3]
        +	 flddx		$idx($np),${fni}	; np[2,3]
        +	ldw		-16($xfer),$abhi	; carry bit actually
        +	 ldo		8($idx),$idx		; j++++
        +	ldw		-12($xfer),$ablo
        +	ldw		-8($xfer),$nmhi0
        +	ldw		-4($xfer),$nmlo0
        +	ldw		0($xfer),$hi0		; high part
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	fstds		${fab1},0($xfer)
        +	 addl		$abhi,$hi0,$hi0		; account carry bit
        +	fstds		${fnm1},8($xfer)
        +	 add		$ablo,$nmlo0,$nmlo0	; discarded
        +	ldw		0($tp),$ti1		; tp[1]
        +	 addc		%r0,$nmhi0,$hi1
        +	fstds		${fab0},-16($xfer)
        +	fstds		${fnm0},-8($xfer)
        +	ldw		4($xfer),$ablo
        +	ldw		0($xfer),$abhi
        +
        +L\$inner_pa11
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[i]
        +	flddx		$idx($ap),${fai}	; ap[j,j+1]
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
        +	flddx		$idx($np),${fni}	; np[j,j+1]
        +	 add		$hi0,$ablo,$ablo
        +	ldw		4($tp),$ti0		; tp[j]
        +	 addc		%r0,$abhi,$abhi
        +	ldw		12($xfer),$nmlo1
        +	 add		$ti1,$ablo,$ablo
        +	ldw		8($xfer),$nmhi1
        +	 addc		%r0,$abhi,$hi0
        +	fstds		${fab1},0($xfer)
        +	 add		$ablo,$nmlo1,$nmlo1
        +	fstds		${fnm1},8($xfer)
        +	 addc		%r0,$nmhi1,$nmhi1
        +	ldw		-12($xfer),$ablo
        +	 add		$hi1,$nmlo1,$nmlo1
        +	ldw		-16($xfer),$abhi
        +	 addc		%r0,$nmhi1,$hi1
        +
        +	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
        +	ldw		8($tp),$ti1		; tp[j]
        +	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
        +	ldw		-4($xfer),$nmlo0
        +	 add		$hi0,$ablo,$ablo
        +	ldw		-8($xfer),$nmhi0
        +	 addc		%r0,$abhi,$abhi
        +	stw		$nmlo1,-4($tp)		; tp[j-1]
        +	 add		$ti0,$ablo,$ablo
        +	fstds		${fab0},-16($xfer)
        +	 addc		%r0,$abhi,$hi0
        +	fstds		${fnm0},-8($xfer)
        +	 add		$ablo,$nmlo0,$nmlo0
        +	ldw		4($xfer),$ablo
        +	 addc		%r0,$nmhi0,$nmhi0
        +	ldw		0($xfer),$abhi
        +	 add		$hi1,$nmlo0,$nmlo0
        +	 stws,ma	$nmlo0,8($tp)		; tp[j-1]
        +	addib,<>	8,$idx,L\$inner_pa11	; j++++
        +	 addc		%r0,$nmhi0,$hi1
        +
        +	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[i]
        +	ldw		12($xfer),$nmlo1
        +	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
        +	ldw		8($xfer),$nmhi1
        +	 add		$hi0,$ablo,$ablo
        +	ldw		4($tp),$ti0		; tp[j]
        +	 addc		%r0,$abhi,$abhi
        +	fstds		${fab1},0($xfer)
        +	 add		$ti1,$ablo,$ablo
        +	fstds		${fnm1},8($xfer)
        +	 addc		%r0,$abhi,$hi0
        +	ldw		-16($xfer),$abhi
        +	 add		$ablo,$nmlo1,$nmlo1
        +	ldw		-12($xfer),$ablo
        +	 addc		%r0,$nmhi1,$nmhi1
        +	ldw		-8($xfer),$nmhi0
        +	 add		$hi1,$nmlo1,$nmlo1
        +	ldw		-4($xfer),$nmlo0
        +	 addc		%r0,$nmhi1,$hi1
        +
        +	add		$hi0,$ablo,$ablo
        +	 stw		$nmlo1,-4($tp)		; tp[j-1]
        +	addc		%r0,$abhi,$abhi
        +	 add		$ti0,$ablo,$ablo
        +	ldw		8($tp),$ti1		; tp[j]
        +	 addc		%r0,$abhi,$hi0
        +	ldw		0($xfer),$abhi
        +	 add		$ablo,$nmlo0,$nmlo0
        +	ldw		4($xfer),$ablo
        +	 addc		%r0,$nmhi0,$nmhi0
        +	ldws,mb		8($xfer),$nmhi1
        +	 add		$hi1,$nmlo0,$nmlo0
        +	ldw		4($xfer),$nmlo1
        +	 addc		%r0,$nmhi0,$hi1
        +	 stws,ma	$nmlo0,8($tp)		; tp[j-1]
        +
        +	addib,=		-1,$num,L\$outerdone_pa11; i--
        +	subi		0,$arrsz,$idx		; j=0
        +
        +	 fldws,ma	4($bp),${fbi}		; bp[i]
        +	 flddx		$idx($ap),${fai}	; ap[0]
        +	add		$hi0,$ablo,$ablo
        +	addc		%r0,$abhi,$abhi
        +	 flddx		$idx($np),${fni}	; np[0]
        +	 fldws		8($xfer),${fti}R	; tp[0]
        +	add		$ti1,$ablo,$ablo
        +	addc		%r0,$abhi,$hi0
        +
        +	 ldo		8($idx),$idx		; j++++
        +	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[i]
        +	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[i]
        +	ldw		4($tp),$ti0		; tp[j]
        +
        +	add		$hi1,$nmlo1,$nmlo1
        +	addc		%r0,$nmhi1,$nmhi1
        +	 fstws,mb	${fab0}L,-8($xfer)	; save high part
        +	add		$ablo,$nmlo1,$nmlo1
        +	addc		%r0,$nmhi1,$hi1
        +	 fcpy,sgl	%fr0,${fti}L		; zero high part
        +	 fcpy,sgl	%fr0,${fab0}L
        +	stw		$nmlo1,-4($tp)		; tp[j-1]
        +
        +	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
        +	 fcnvxf,dbl,dbl	${fab0},${fab0}
        +	add		$hi1,$hi0,$hi0
        +	addc		%r0,%r0,$hi1
        +	 fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
        +	add		$ti0,$hi0,$hi0
        +	addc		%r0,$hi1,$hi1
        +	 fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
        +	stw		$hi0,0($tp)
        +	stw		$hi1,4($tp)
        +	 xmpyu		${fn0},${fab0}R,${fm0}
        +
        +	b		L\$outer_pa11
        +	ldo		`$LOCALS+32+4`($fp),$tp
        +
        +L\$outerdone_pa11
        +	add		$hi0,$ablo,$ablo
        +	addc		%r0,$abhi,$abhi
        +	add		$ti1,$ablo,$ablo
        +	addc		%r0,$abhi,$hi0
        +
        +	ldw		4($tp),$ti0		; tp[j]
        +
        +	add		$hi1,$nmlo1,$nmlo1
        +	addc		%r0,$nmhi1,$nmhi1
        +	add		$ablo,$nmlo1,$nmlo1
        +	addc		%r0,$nmhi1,$hi1
        +	stw		$nmlo1,-4($tp)		; tp[j-1]
        +
        +	add		$hi1,$hi0,$hi0
        +	addc		%r0,%r0,$hi1
        +	add		$ti0,$hi0,$hi0
        +	addc		%r0,$hi1,$hi1
        +	stw		$hi0,0($tp)
        +	stw		$hi1,4($tp)
        +
        +	ldo		`$LOCALS+32+4`($fp),$tp
        +	sub		%r0,%r0,%r0		; clear borrow
        +	ldw		-4($tp),$ti0
        +	addl		$tp,$arrsz,$tp
        +L\$sub_pa11
        +	ldwx		$idx($np),$hi0
        +	subb		$ti0,$hi0,$hi1
        +	ldwx		$idx($tp),$ti0
        +	addib,<>	4,$idx,L\$sub_pa11
        +	stws,ma		$hi1,4($rp)
        +
        +	subb		$ti0,%r0,$hi1
        +	ldo		-4($tp),$tp
        +	and		$tp,$hi1,$ap
        +	andcm		$rp,$hi1,$bp
        +	or		$ap,$bp,$np
        +
        +	sub		$rp,$arrsz,$rp		; rewind rp
        +	subi		0,$arrsz,$idx
        +	ldo		`$LOCALS+32`($fp),$tp
        +L\$copy_pa11
        +	ldwx		$idx($np),$hi0
        +	stws,ma		%r0,4($tp)
        +	addib,<>	4,$idx,L\$copy_pa11
        +	stws,ma		$hi0,4($rp)	
        +
        +	nop					; alignment
        +L\$done
        +___
        +}
        +
        +$code.=<<___;
        +	ldi		1,%r28			; signal "handled"
        +	ldo		$FRAME($fp),%sp		; destroy tp[num+1]
        +
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +L\$abort
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +	.STRINGZ "Montgomery Multiplication for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +# Explicitly encode PA-RISC 2.0 instructions used in this module, so
        +# that it can be compiled with .LEVEL 1.0. It should be noted that I
        +# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
        +# directive...
        +
        +my $ldd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "ldd$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)		# format 4
        +    {	my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3;
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)	# format 5
        +    {	my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3;
        +	$opcode|=(($1&0xF)<<17)|(($1&0x10)<<12);		# encode offset
        +	$opcode|=(1<<5)  if ($mod =~ /^,m/);
        +	$opcode|=(1<<13) if ($mod =~ /^,mb/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $std = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "std$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/)	# format 6
        +    {	my $opcode=(0x03<<26)|($3<<21)|($1<<16)|(1<<12)|(0xB<<6);
        +	$opcode|=(($2&0xF)<<1)|(($2&0x10)>>4);			# encode offset
        +	$opcode|=(1<<5)  if ($mod =~ /^,m/);
        +	$opcode|=(1<<13) if ($mod =~ /^,mb/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $extrd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "extrd$mod\t$args";
        +
        +    # I only have ",u" completer, it's implicitly encoded...
        +    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 15
        +    {	my $opcode=(0x36<<26)|($1<<21)|($4<<16);
        +	my $len=32-$3;
        +	$opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5);		# encode pos
        +	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/)	# format 12
        +    {	my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
        +	my $len=32-$2;
        +	$opcode |= (($len&0x20)<<3)|($len&0x1f);		# encode len
        +	$opcode |= (1<<13) if ($mod =~ /,\**=/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $shrpd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "shrpd$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/)	# format 14
        +    {	my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
        +	my $cpos=63-$3;
        +	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode sa
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $sub = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "sub$mod\t$args";
        +
        +    if ($mod eq ",db" && $args =~ /%r([0-9]+),%r([0-9]+),%r([0-9]+)/) {
        +	my $opcode=(0x02<<26)|($2<<21)|($1<<16)|$3;
        +	$opcode|=(1<<10);	# e1
        +	$opcode|=(1<<8);	# e2
        +	$opcode|=(1<<5);	# d
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +sub assemble {
        +  my ($mnemonic,$mod,$args)=@_;
        +  my $opcode = eval("\$$mnemonic");
        +
        +    ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
        +}
        +
        +foreach (split("\n",$code)) {
        +	s/\`([^\`]*)\`/eval $1/ge;
        +	# flip word order in 64-bit mode...
        +	s/(xmpyu\s+)($fai|$fni)([LR])/$1.$2.($3 eq "L"?"R":"L")/e if ($BN_SZ==8);
        +	# assemble 2.0 instructions in 32-bit mode...
        +	s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($BN_SZ==4);
        +
        +	print $_,"\n";
        +}
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/ppc-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/ppc-mont.pl
        new file mode 100644
        index 000000000..f9b6992cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/ppc-mont.pl
        @@ -0,0 +1,334 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# April 2006
        +
        +# "Teaser" Montgomery multiplication module for PowerPC. It's possible
        +# to gain a bit more by modulo-scheduling outer loop, then dedicated
        +# squaring procedure should give further 20% and code can be adapted
        +# for 32-bit application running on 64-bit CPU. As for the latter.
        +# It won't be able to achieve "native" 64-bit performance, because in
        +# 32-bit application context every addc instruction will have to be
        +# expanded as addc, twice right shift by 32 and finally adde, etc.
        +# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
        +# for 64-bit application running on PPC970/G5 is:
        +#
        +# 512-bit	+65%	
        +# 1024-bit	+35%
        +# 2048-bit	+18%
        +# 4096-bit	+4%
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /32/) {
        +	$BITS=	32;
        +	$BNSZ=	$BITS/8;
        +	$SIZE_T=4;
        +	$RZONE=	224;
        +
        +	$LD=	"lwz";		# load
        +	$LDU=	"lwzu";		# load and update
        +	$LDX=	"lwzx";		# load indexed
        +	$ST=	"stw";		# store
        +	$STU=	"stwu";		# store and update
        +	$STX=	"stwx";		# store indexed
        +	$STUX=	"stwux";	# store indexed and update
        +	$UMULL=	"mullw";	# unsigned multiply low
        +	$UMULH=	"mulhwu";	# unsigned multiply high
        +	$UCMP=	"cmplw";	# unsigned compare
        +	$SHRI=	"srwi";		# unsigned shift right by immediate	
        +	$PUSH=	$ST;
        +	$POP=	$LD;
        +} elsif ($flavour =~ /64/) {
        +	$BITS=	64;
        +	$BNSZ=	$BITS/8;
        +	$SIZE_T=8;
        +	$RZONE=	288;
        +
        +	# same as above, but 64-bit mnemonics...
        +	$LD=	"ld";		# load
        +	$LDU=	"ldu";		# load and update
        +	$LDX=	"ldx";		# load indexed
        +	$ST=	"std";		# store
        +	$STU=	"stdu";		# store and update
        +	$STX=	"stdx";		# store indexed
        +	$STUX=	"stdux";	# store indexed and update
        +	$UMULL=	"mulld";	# unsigned multiply low
        +	$UMULH=	"mulhdu";	# unsigned multiply high
        +	$UCMP=	"cmpld";	# unsigned compare
        +	$SHRI=	"srdi";		# unsigned shift right by immediate	
        +	$PUSH=	$ST;
        +	$POP=	$LD;
        +} else { die "nonsense $flavour"; }
        +
        +$FRAME=8*$SIZE_T+$RZONE;
        +$LOCALS=8*$SIZE_T;
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
        +
        +$sp="r1";
        +$toc="r2";
        +$rp="r3";	$ovf="r3";
        +$ap="r4";
        +$bp="r5";
        +$np="r6";
        +$n0="r7";
        +$num="r8";
        +$rp="r9";	# $rp is reassigned
        +$aj="r10";
        +$nj="r11";
        +$tj="r12";
        +# non-volatile registers
        +$i="r20";
        +$j="r21";
        +$tp="r22";
        +$m0="r23";
        +$m1="r24";
        +$lo0="r25";
        +$hi0="r26";
        +$lo1="r27";
        +$hi1="r28";
        +$alo="r29";
        +$ahi="r30";
        +$nlo="r31";
        +#
        +$nhi="r0";
        +
        +$code=<<___;
        +.machine "any"
        +.text
        +
        +.globl	.bn_mul_mont_int
        +.align	4
        +.bn_mul_mont_int:
        +	cmpwi	$num,4
        +	mr	$rp,r3		; $rp is reassigned
        +	li	r3,0
        +	bltlr
        +___
        +$code.=<<___ if ($BNSZ==4);
        +	cmpwi	$num,32		; longer key performance is not better
        +	bgelr
        +___
        +$code.=<<___;
        +	slwi	$num,$num,`log($BNSZ)/log(2)`
        +	li	$tj,-4096
        +	addi	$ovf,$num,$FRAME
        +	subf	$ovf,$ovf,$sp	; $sp-$ovf
        +	and	$ovf,$ovf,$tj	; minimize TLB usage
        +	subf	$ovf,$sp,$ovf	; $ovf-$sp
        +	mr	$tj,$sp
        +	srwi	$num,$num,`log($BNSZ)/log(2)`
        +	$STUX	$sp,$sp,$ovf
        +
        +	$PUSH	r20,`-12*$SIZE_T`($tj)
        +	$PUSH	r21,`-11*$SIZE_T`($tj)
        +	$PUSH	r22,`-10*$SIZE_T`($tj)
        +	$PUSH	r23,`-9*$SIZE_T`($tj)
        +	$PUSH	r24,`-8*$SIZE_T`($tj)
        +	$PUSH	r25,`-7*$SIZE_T`($tj)
        +	$PUSH	r26,`-6*$SIZE_T`($tj)
        +	$PUSH	r27,`-5*$SIZE_T`($tj)
        +	$PUSH	r28,`-4*$SIZE_T`($tj)
        +	$PUSH	r29,`-3*$SIZE_T`($tj)
        +	$PUSH	r30,`-2*$SIZE_T`($tj)
        +	$PUSH	r31,`-1*$SIZE_T`($tj)
        +
        +	$LD	$n0,0($n0)	; pull n0[0] value
        +	addi	$num,$num,-2	; adjust $num for counter register
        +
        +	$LD	$m0,0($bp)	; m0=bp[0]
        +	$LD	$aj,0($ap)	; ap[0]
        +	addi	$tp,$sp,$LOCALS
        +	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[0]
        +	$UMULH	$hi0,$aj,$m0
        +
        +	$LD	$aj,$BNSZ($ap)	; ap[1]
        +	$LD	$nj,0($np)	; np[0]
        +
        +	$UMULL	$m1,$lo0,$n0	; "tp[0]"*n0
        +
        +	$UMULL	$alo,$aj,$m0	; ap[1]*bp[0]
        +	$UMULH	$ahi,$aj,$m0
        +
        +	$UMULL	$lo1,$nj,$m1	; np[0]*m1
        +	$UMULH	$hi1,$nj,$m1
        +	$LD	$nj,$BNSZ($np)	; np[1]
        +	addc	$lo1,$lo1,$lo0
        +	addze	$hi1,$hi1
        +
        +	$UMULL	$nlo,$nj,$m1	; np[1]*m1
        +	$UMULH	$nhi,$nj,$m1
        +
        +	mtctr	$num
        +	li	$j,`2*$BNSZ`
        +.align	4
        +L1st:
        +	$LDX	$aj,$ap,$j	; ap[j]
        +	addc	$lo0,$alo,$hi0
        +	$LDX	$nj,$np,$j	; np[j]
        +	addze	$hi0,$ahi
        +	$UMULL	$alo,$aj,$m0	; ap[j]*bp[0]
        +	addc	$lo1,$nlo,$hi1
        +	$UMULH	$ahi,$aj,$m0
        +	addze	$hi1,$nhi
        +	$UMULL	$nlo,$nj,$m1	; np[j]*m1
        +	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
        +	$UMULH	$nhi,$nj,$m1
        +	addze	$hi1,$hi1
        +	$ST	$lo1,0($tp)	; tp[j-1]
        +
        +	addi	$j,$j,$BNSZ	; j++
        +	addi	$tp,$tp,$BNSZ	; tp++
        +	bdnz-	L1st
        +;L1st
        +	addc	$lo0,$alo,$hi0
        +	addze	$hi0,$ahi
        +
        +	addc	$lo1,$nlo,$hi1
        +	addze	$hi1,$nhi
        +	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
        +	addze	$hi1,$hi1
        +	$ST	$lo1,0($tp)	; tp[j-1]
        +
        +	li	$ovf,0
        +	addc	$hi1,$hi1,$hi0
        +	addze	$ovf,$ovf	; upmost overflow bit
        +	$ST	$hi1,$BNSZ($tp)
        +
        +	li	$i,$BNSZ
        +.align	4
        +Louter:
        +	$LDX	$m0,$bp,$i	; m0=bp[i]
        +	$LD	$aj,0($ap)	; ap[0]
        +	addi	$tp,$sp,$LOCALS
        +	$LD	$tj,$LOCALS($sp); tp[0]
        +	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[i]
        +	$UMULH	$hi0,$aj,$m0
        +	$LD	$aj,$BNSZ($ap)	; ap[1]
        +	$LD	$nj,0($np)	; np[0]
        +	addc	$lo0,$lo0,$tj	; ap[0]*bp[i]+tp[0]
        +	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
        +	addze	$hi0,$hi0
        +	$UMULL	$m1,$lo0,$n0	; tp[0]*n0
        +	$UMULH	$ahi,$aj,$m0
        +	$UMULL	$lo1,$nj,$m1	; np[0]*m1
        +	$UMULH	$hi1,$nj,$m1
        +	$LD	$nj,$BNSZ($np)	; np[1]
        +	addc	$lo1,$lo1,$lo0
        +	$UMULL	$nlo,$nj,$m1	; np[1]*m1
        +	addze	$hi1,$hi1
        +	$UMULH	$nhi,$nj,$m1
        +
        +	mtctr	$num
        +	li	$j,`2*$BNSZ`
        +.align	4
        +Linner:
        +	$LDX	$aj,$ap,$j	; ap[j]
        +	addc	$lo0,$alo,$hi0
        +	$LD	$tj,$BNSZ($tp)	; tp[j]
        +	addze	$hi0,$ahi
        +	$LDX	$nj,$np,$j	; np[j]
        +	addc	$lo1,$nlo,$hi1
        +	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
        +	addze	$hi1,$nhi
        +	$UMULH	$ahi,$aj,$m0
        +	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
        +	$UMULL	$nlo,$nj,$m1	; np[j]*m1
        +	addze	$hi0,$hi0
        +	$UMULH	$nhi,$nj,$m1
        +	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
        +	addi	$j,$j,$BNSZ	; j++
        +	addze	$hi1,$hi1
        +	$ST	$lo1,0($tp)	; tp[j-1]
        +	addi	$tp,$tp,$BNSZ	; tp++
        +	bdnz-	Linner
        +;Linner
        +	$LD	$tj,$BNSZ($tp)	; tp[j]
        +	addc	$lo0,$alo,$hi0
        +	addze	$hi0,$ahi
        +	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
        +	addze	$hi0,$hi0
        +
        +	addc	$lo1,$nlo,$hi1
        +	addze	$hi1,$nhi
        +	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
        +	addze	$hi1,$hi1
        +	$ST	$lo1,0($tp)	; tp[j-1]
        +
        +	addic	$ovf,$ovf,-1	; move upmost overflow to XER[CA]
        +	li	$ovf,0
        +	adde	$hi1,$hi1,$hi0
        +	addze	$ovf,$ovf
        +	$ST	$hi1,$BNSZ($tp)
        +;
        +	slwi	$tj,$num,`log($BNSZ)/log(2)`
        +	$UCMP	$i,$tj
        +	addi	$i,$i,$BNSZ
        +	ble-	Louter
        +
        +	addi	$num,$num,2	; restore $num
        +	subfc	$j,$j,$j	; j=0 and "clear" XER[CA]
        +	addi	$tp,$sp,$LOCALS
        +	mtctr	$num
        +
        +.align	4
        +Lsub:	$LDX	$tj,$tp,$j
        +	$LDX	$nj,$np,$j
        +	subfe	$aj,$nj,$tj	; tp[j]-np[j]
        +	$STX	$aj,$rp,$j
        +	addi	$j,$j,$BNSZ
        +	bdnz-	Lsub
        +
        +	li	$j,0
        +	mtctr	$num
        +	subfe	$ovf,$j,$ovf	; handle upmost overflow bit
        +	and	$ap,$tp,$ovf
        +	andc	$np,$rp,$ovf
        +	or	$ap,$ap,$np	; ap=borrow?tp:rp
        +
        +.align	4
        +Lcopy:				; copy or in-place refresh
        +	$LDX	$tj,$ap,$j
        +	$STX	$tj,$rp,$j
        +	$STX	$j,$tp,$j	; zap at once
        +	addi	$j,$j,$BNSZ
        +	bdnz-	Lcopy
        +
        +	$POP	$tj,0($sp)
        +	li	r3,1
        +	$POP	r20,`-12*$SIZE_T`($tj)
        +	$POP	r21,`-11*$SIZE_T`($tj)
        +	$POP	r22,`-10*$SIZE_T`($tj)
        +	$POP	r23,`-9*$SIZE_T`($tj)
        +	$POP	r24,`-8*$SIZE_T`($tj)
        +	$POP	r25,`-7*$SIZE_T`($tj)
        +	$POP	r26,`-6*$SIZE_T`($tj)
        +	$POP	r27,`-5*$SIZE_T`($tj)
        +	$POP	r28,`-4*$SIZE_T`($tj)
        +	$POP	r29,`-3*$SIZE_T`($tj)
        +	$POP	r30,`-2*$SIZE_T`($tj)
        +	$POP	r31,`-1*$SIZE_T`($tj)
        +	mr	$sp,$tj
        +	blr
        +	.long	0
        +	.byte	0,12,4,0,0x80,12,6,0
        +	.long	0
        +
        +.asciz  "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/ppc.pl b/vendor/openssl/openssl/crypto/bn/asm/ppc.pl
        new file mode 100644
        index 000000000..1249ce229
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/ppc.pl
        @@ -0,0 +1,1998 @@
        +#!/usr/bin/env perl
        +#
        +# Implemented as a Perl wrapper as we want to support several different
        +# architectures with single file. We pick up the target based on the
        +# file name we are asked to generate.
        +#
        +# It should be noted though that this perl code is nothing like
        +# <openssl>/crypto/perlasm/x86*. In this case perl is used pretty much
        +# as pre-processor to cover for platform differences in name decoration,
        +# linker tables, 32-/64-bit instruction sets...
        +#
        +# As you might know there're several PowerPC ABI in use. Most notably
        +# Linux and AIX use different 32-bit ABIs. Good news are that these ABIs
        +# are similar enough to implement leaf(!) functions, which would be ABI
        +# neutral. And that's what you find here: ABI neutral leaf functions.
        +# In case you wonder what that is...
        +#
        +#       AIX performance
        +#
        +#	MEASUREMENTS WITH cc ON a 200 MhZ PowerPC 604e.
        +#
        +#	The following is the performance of 32-bit compiler
        +#	generated code:
        +#
        +#	OpenSSL 0.9.6c 21 dec 2001
        +#	built on: Tue Jun 11 11:06:51 EDT 2002
        +#	options:bn(64,32) ...
        +#compiler: cc -DTHREADS  -DAIX -DB_ENDIAN -DBN_LLONG -O3
        +#                  sign    verify    sign/s verify/s
        +#rsa  512 bits   0.0098s   0.0009s    102.0   1170.6
        +#rsa 1024 bits   0.0507s   0.0026s     19.7    387.5
        +#rsa 2048 bits   0.3036s   0.0085s      3.3    117.1
        +#rsa 4096 bits   2.0040s   0.0299s      0.5     33.4
        +#dsa  512 bits   0.0087s   0.0106s    114.3     94.5
        +#dsa 1024 bits   0.0256s   0.0313s     39.0     32.0	
        +#
        +#	Same bechmark with this assembler code:
        +#
        +#rsa  512 bits   0.0056s   0.0005s    178.6   2049.2
        +#rsa 1024 bits   0.0283s   0.0015s     35.3    674.1
        +#rsa 2048 bits   0.1744s   0.0050s      5.7    201.2
        +#rsa 4096 bits   1.1644s   0.0179s      0.9     55.7
        +#dsa  512 bits   0.0052s   0.0062s    191.6    162.0
        +#dsa 1024 bits   0.0149s   0.0180s     67.0     55.5
        +#
        +#	Number of operations increases by at almost 75%
        +#
        +#	Here are performance numbers for 64-bit compiler
        +#	generated code:
        +#
        +#	OpenSSL 0.9.6g [engine] 9 Aug 2002
        +#	built on: Fri Apr 18 16:59:20 EDT 2003
        +#	options:bn(64,64) ...
        +#	compiler: cc -DTHREADS -D_REENTRANT -q64 -DB_ENDIAN -O3
        +#                  sign    verify    sign/s verify/s
        +#rsa  512 bits   0.0028s   0.0003s    357.1   3844.4
        +#rsa 1024 bits   0.0148s   0.0008s     67.5   1239.7
        +#rsa 2048 bits   0.0963s   0.0028s     10.4    353.0
        +#rsa 4096 bits   0.6538s   0.0102s      1.5     98.1
        +#dsa  512 bits   0.0026s   0.0032s    382.5    313.7
        +#dsa 1024 bits   0.0081s   0.0099s    122.8    100.6
        +#
        +#	Same benchmark with this assembler code:
        +#
        +#rsa  512 bits   0.0020s   0.0002s    510.4   6273.7
        +#rsa 1024 bits   0.0088s   0.0005s    114.1   2128.3
        +#rsa 2048 bits   0.0540s   0.0016s     18.5    622.5
        +#rsa 4096 bits   0.3700s   0.0058s      2.7    171.0
        +#dsa  512 bits   0.0016s   0.0020s    610.7    507.1
        +#dsa 1024 bits   0.0047s   0.0058s    212.5    173.2
        +#	
        +#	Again, performance increases by at about 75%
        +#
        +#       Mac OS X, Apple G5 1.8GHz (Note this is 32 bit code)
        +#       OpenSSL 0.9.7c 30 Sep 2003
        +#
        +#       Original code.
        +#
        +#rsa  512 bits   0.0011s   0.0001s    906.1  11012.5
        +#rsa 1024 bits   0.0060s   0.0003s    166.6   3363.1
        +#rsa 2048 bits   0.0370s   0.0010s     27.1    982.4
        +#rsa 4096 bits   0.2426s   0.0036s      4.1    280.4
        +#dsa  512 bits   0.0010s   0.0012s   1038.1    841.5
        +#dsa 1024 bits   0.0030s   0.0037s    329.6    269.7
        +#dsa 2048 bits   0.0101s   0.0127s     98.9     78.6
        +#
        +#       Same benchmark with this assembler code:
        +#
        +#rsa  512 bits   0.0007s   0.0001s   1416.2  16645.9
        +#rsa 1024 bits   0.0036s   0.0002s    274.4   5380.6
        +#rsa 2048 bits   0.0222s   0.0006s     45.1   1589.5
        +#rsa 4096 bits   0.1469s   0.0022s      6.8    449.6
        +#dsa  512 bits   0.0006s   0.0007s   1664.2   1376.2
        +#dsa 1024 bits   0.0018s   0.0023s    545.0    442.2
        +#dsa 2048 bits   0.0061s   0.0075s    163.5    132.8
        +#
        +#        Performance increase of ~60%
        +#
        +#	If you have comments or suggestions to improve code send
        +#	me a note at schari@us.ibm.com
        +#
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /32/) {
        +	$BITS=	32;
        +	$BNSZ=	$BITS/8;
        +	$ISA=	"\"ppc\"";
        +
        +	$LD=	"lwz";		# load
        +	$LDU=	"lwzu";		# load and update
        +	$ST=	"stw";		# store
        +	$STU=	"stwu";		# store and update
        +	$UMULL=	"mullw";	# unsigned multiply low
        +	$UMULH=	"mulhwu";	# unsigned multiply high
        +	$UDIV=	"divwu";	# unsigned divide
        +	$UCMPI=	"cmplwi";	# unsigned compare with immediate
        +	$UCMP=	"cmplw";	# unsigned compare
        +	$CNTLZ=	"cntlzw";	# count leading zeros
        +	$SHL=	"slw";		# shift left
        +	$SHR=	"srw";		# unsigned shift right
        +	$SHRI=	"srwi";		# unsigned shift right by immediate	
        +	$SHLI=	"slwi";		# shift left by immediate
        +	$CLRU=	"clrlwi";	# clear upper bits
        +	$INSR=	"insrwi";	# insert right
        +	$ROTL=	"rotlwi";	# rotate left by immediate
        +	$TR=	"tw";		# conditional trap
        +} elsif ($flavour =~ /64/) {
        +	$BITS=	64;
        +	$BNSZ=	$BITS/8;
        +	$ISA=	"\"ppc64\"";
        +
        +	# same as above, but 64-bit mnemonics...
        +	$LD=	"ld";		# load
        +	$LDU=	"ldu";		# load and update
        +	$ST=	"std";		# store
        +	$STU=	"stdu";		# store and update
        +	$UMULL=	"mulld";	# unsigned multiply low
        +	$UMULH=	"mulhdu";	# unsigned multiply high
        +	$UDIV=	"divdu";	# unsigned divide
        +	$UCMPI=	"cmpldi";	# unsigned compare with immediate
        +	$UCMP=	"cmpld";	# unsigned compare
        +	$CNTLZ=	"cntlzd";	# count leading zeros
        +	$SHL=	"sld";		# shift left
        +	$SHR=	"srd";		# unsigned shift right
        +	$SHRI=	"srdi";		# unsigned shift right by immediate	
        +	$SHLI=	"sldi";		# shift left by immediate
        +	$CLRU=	"clrldi";	# clear upper bits
        +	$INSR=	"insrdi";	# insert right 
        +	$ROTL=	"rotldi";	# rotate left by immediate
        +	$TR=	"td";		# conditional trap
        +} else { die "nonsense $flavour"; }
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
        +
        +$data=<<EOF;
        +#--------------------------------------------------------------------
        +#
        +#
        +#
        +#
        +#	File:		ppc32.s
        +#
        +#	Created by:	Suresh Chari
        +#			IBM Thomas J. Watson Research Library
        +#			Hawthorne, NY
        +#
        +#
        +#	Description:	Optimized assembly routines for OpenSSL crypto
        +#			on the 32 bitPowerPC platform.
        +#
        +#
        +#	Version History
        +#
        +#	2. Fixed bn_add,bn_sub and bn_div_words, added comments,
        +#	   cleaned up code. Also made a single version which can
        +#	   be used for both the AIX and Linux compilers. See NOTE
        +#	   below.
        +#				12/05/03		Suresh Chari
        +#			(with lots of help from)        Andy Polyakov
        +##	
        +#	1. Initial version	10/20/02		Suresh Chari
        +#
        +#
        +#	The following file works for the xlc,cc
        +#	and gcc compilers.
        +#
        +#	NOTE:	To get the file to link correctly with the gcc compiler
        +#	        you have to change the names of the routines and remove
        +#		the first .(dot) character. This should automatically
        +#		be done in the build process.
        +#
        +#	Hand optimized assembly code for the following routines
        +#	
        +#	bn_sqr_comba4
        +#	bn_sqr_comba8
        +#	bn_mul_comba4
        +#	bn_mul_comba8
        +#	bn_sub_words
        +#	bn_add_words
        +#	bn_div_words
        +#	bn_sqr_words
        +#	bn_mul_words
        +#	bn_mul_add_words
        +#
        +#	NOTE:	It is possible to optimize this code more for
        +#	specific PowerPC or Power architectures. On the Northstar
        +#	architecture the optimizations in this file do
        +#	 NOT provide much improvement.
        +#
        +#	If you have comments or suggestions to improve code send
        +#	me a note at schari\@us.ibm.com
        +#
        +#--------------------------------------------------------------------------
        +#
        +#	Defines to be used in the assembly code.
        +#	
        +#.set r0,0	# we use it as storage for value of 0
        +#.set SP,1	# preserved
        +#.set RTOC,2	# preserved 
        +#.set r3,3	# 1st argument/return value
        +#.set r4,4	# 2nd argument/volatile register
        +#.set r5,5	# 3rd argument/volatile register
        +#.set r6,6	# ...
        +#.set r7,7
        +#.set r8,8
        +#.set r9,9
        +#.set r10,10
        +#.set r11,11
        +#.set r12,12
        +#.set r13,13	# not used, nor any other "below" it...
        +
        +#	Declare function names to be global
        +#	NOTE:	For gcc these names MUST be changed to remove
        +#	        the first . i.e. for example change ".bn_sqr_comba4"
        +#		to "bn_sqr_comba4". This should be automatically done
        +#		in the build.
        +	
        +	.globl	.bn_sqr_comba4
        +	.globl	.bn_sqr_comba8
        +	.globl	.bn_mul_comba4
        +	.globl	.bn_mul_comba8
        +	.globl	.bn_sub_words
        +	.globl	.bn_add_words
        +	.globl	.bn_div_words
        +	.globl	.bn_sqr_words
        +	.globl	.bn_mul_words
        +	.globl	.bn_mul_add_words
        +	
        +# .text section
        +	
        +	.machine	"any"
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_sqr_comba4" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +
        +.align	4
        +.bn_sqr_comba4:
        +#
        +# Optimized version of bn_sqr_comba4.
        +#
        +# void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
        +# r3 contains r
        +# r4 contains a
        +#
        +# Freely use registers r5,r6,r7,r8,r9,r10,r11 as follows:	
        +# 
        +# r5,r6 are the two BN_ULONGs being multiplied.
        +# r7,r8 are the results of the 32x32 giving 64 bit multiply.
        +# r9,r10, r11 are the equivalents of c1,c2, c3.
        +# Here's the assembly
        +#
        +#
        +	xor		r0,r0,r0		# set r0 = 0. Used in the addze
        +						# instructions below
        +	
        +						#sqr_add_c(a,0,c1,c2,c3)
        +	$LD		r5,`0*$BNSZ`(r4)		
        +	$UMULL		r9,r5,r5		
        +	$UMULH		r10,r5,r5		#in first iteration. No need
        +						#to add since c1=c2=c3=0.
        +						# Note c3(r11) is NOT set to 0
        +						# but will be.
        +
        +	$ST		r9,`0*$BNSZ`(r3)	# r[0]=c1;
        +						# sqr_add_c2(a,1,0,c2,c3,c1);
        +	$LD		r6,`1*$BNSZ`(r4)		
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +					
        +	addc		r7,r7,r7		# compute (r7,r8)=2*(r7,r8)
        +	adde		r8,r8,r8
        +	addze		r9,r0			# catch carry if any.
        +						# r9= r0(=0) and carry 
        +	
        +	addc		r10,r7,r10		# now add to temp result.
        +	addze		r11,r8                  # r8 added to r11 which is 0 
        +	addze		r9,r9
        +	
        +	$ST		r10,`1*$BNSZ`(r3)	#r[1]=c2; 
        +						#sqr_add_c(a,1,c3,c1,c2)
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r0
        +						#sqr_add_c2(a,2,0,c3,c1,c2)
        +	$LD		r6,`2*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r7,r7,r7
        +	adde		r8,r8,r8
        +	addze		r10,r10
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	$ST		r11,`2*$BNSZ`(r3)	#r[2]=c3 
        +						#sqr_add_c2(a,3,0,c1,c2,c3);
        +	$LD		r6,`3*$BNSZ`(r4)		
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r7,r7,r7
        +	adde		r8,r8,r8
        +	addze		r11,r0
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +						#sqr_add_c2(a,2,1,c1,c2,c3);
        +	$LD		r5,`1*$BNSZ`(r4)
        +	$LD		r6,`2*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r7,r7,r7
        +	adde		r8,r8,r8
        +	addze		r11,r11
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	$ST		r9,`3*$BNSZ`(r3)	#r[3]=c1
        +						#sqr_add_c(a,2,c2,c3,c1);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r0
        +						#sqr_add_c2(a,3,1,c2,c3,c1);
        +	$LD		r6,`3*$BNSZ`(r4)		
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r7,r7,r7
        +	adde		r8,r8,r8
        +	addze		r9,r9
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	$ST		r10,`4*$BNSZ`(r3)	#r[4]=c2
        +						#sqr_add_c2(a,3,2,c3,c1,c2);
        +	$LD		r5,`2*$BNSZ`(r4)		
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r7,r7,r7
        +	adde		r8,r8,r8
        +	addze		r10,r0
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	$ST		r11,`5*$BNSZ`(r3)	#r[5] = c3
        +						#sqr_add_c(a,3,c1,c2,c3);
        +	$UMULL		r7,r6,r6		
        +	$UMULH		r8,r6,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +
        +	$ST		r9,`6*$BNSZ`(r3)	#r[6]=c1
        +	$ST		r10,`7*$BNSZ`(r3)	#r[7]=c2
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,2,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_sqr_comba8" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +	
        +.align	4
        +.bn_sqr_comba8:
        +#
        +# This is an optimized version of the bn_sqr_comba8 routine.
        +# Tightly uses the adde instruction
        +#
        +#
        +# void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
        +# r3 contains r
        +# r4 contains a
        +#
        +# Freely use registers r5,r6,r7,r8,r9,r10,r11 as follows:	
        +# 
        +# r5,r6 are the two BN_ULONGs being multiplied.
        +# r7,r8 are the results of the 32x32 giving 64 bit multiply.
        +# r9,r10, r11 are the equivalents of c1,c2, c3.
        +#
        +# Possible optimization of loading all 8 longs of a into registers
        +# doesnt provide any speedup
        +# 
        +
        +	xor		r0,r0,r0		#set r0 = 0.Used in addze
        +						#instructions below.
        +
        +						#sqr_add_c(a,0,c1,c2,c3);
        +	$LD		r5,`0*$BNSZ`(r4)
        +	$UMULL		r9,r5,r5		#1st iteration:	no carries.
        +	$UMULH		r10,r5,r5
        +	$ST		r9,`0*$BNSZ`(r3)	# r[0]=c1;
        +						#sqr_add_c2(a,1,0,c2,c3,c1);
        +	$LD		r6,`1*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6	
        +	
        +	addc		r10,r7,r10		#add the two register number
        +	adde		r11,r8,r0 		# (r8,r7) to the three register
        +	addze		r9,r0			# number (r9,r11,r10).NOTE:r0=0
        +	
        +	addc		r10,r7,r10		#add the two register number
        +	adde		r11,r8,r11 		# (r8,r7) to the three register
        +	addze		r9,r9			# number (r9,r11,r10).
        +	
        +	$ST		r10,`1*$BNSZ`(r3)	# r[1]=c2
        +				
        +						#sqr_add_c(a,1,c3,c1,c2);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r0
        +						#sqr_add_c2(a,2,0,c3,c1,c2);
        +	$LD		r6,`2*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	
        +	$ST		r11,`2*$BNSZ`(r3)	#r[2]=c3
        +						#sqr_add_c2(a,3,0,c1,c2,c3);
        +	$LD		r6,`3*$BNSZ`(r4)	#r6 = a[3]. r5 is already a[0].
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r0
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +						#sqr_add_c2(a,2,1,c1,c2,c3);
        +	$LD		r5,`1*$BNSZ`(r4)
        +	$LD		r6,`2*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	
        +	$ST		r9,`3*$BNSZ`(r3)	#r[3]=c1;
        +						#sqr_add_c(a,2,c2,c3,c1);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r0
        +						#sqr_add_c2(a,3,1,c2,c3,c1);
        +	$LD		r6,`3*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +						#sqr_add_c2(a,4,0,c2,c3,c1);
        +	$LD		r5,`0*$BNSZ`(r4)
        +	$LD		r6,`4*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	$ST		r10,`4*$BNSZ`(r3)	#r[4]=c2;
        +						#sqr_add_c2(a,5,0,c3,c1,c2);
        +	$LD		r6,`5*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r0
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +						#sqr_add_c2(a,4,1,c3,c1,c2);
        +	$LD		r5,`1*$BNSZ`(r4)
        +	$LD		r6,`4*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +						#sqr_add_c2(a,3,2,c3,c1,c2);
        +	$LD		r5,`2*$BNSZ`(r4)
        +	$LD		r6,`3*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	$ST		r11,`5*$BNSZ`(r3)	#r[5]=c3;
        +						#sqr_add_c(a,3,c1,c2,c3);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r0
        +						#sqr_add_c2(a,4,2,c1,c2,c3);
        +	$LD		r6,`4*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +						#sqr_add_c2(a,5,1,c1,c2,c3);
        +	$LD		r5,`1*$BNSZ`(r4)
        +	$LD		r6,`5*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +						#sqr_add_c2(a,6,0,c1,c2,c3);
        +	$LD		r5,`0*$BNSZ`(r4)
        +	$LD		r6,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	$ST		r9,`6*$BNSZ`(r3)	#r[6]=c1;
        +						#sqr_add_c2(a,7,0,c2,c3,c1);
        +	$LD		r6,`7*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r0
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +						#sqr_add_c2(a,6,1,c2,c3,c1);
        +	$LD		r5,`1*$BNSZ`(r4)
        +	$LD		r6,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +						#sqr_add_c2(a,5,2,c2,c3,c1);
        +	$LD		r5,`2*$BNSZ`(r4)
        +	$LD		r6,`5*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +						#sqr_add_c2(a,4,3,c2,c3,c1);
        +	$LD		r5,`3*$BNSZ`(r4)
        +	$LD		r6,`4*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	$ST		r10,`7*$BNSZ`(r3)	#r[7]=c2;
        +						#sqr_add_c(a,4,c3,c1,c2);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r0
        +						#sqr_add_c2(a,5,3,c3,c1,c2);
        +	$LD		r6,`5*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +						#sqr_add_c2(a,6,2,c3,c1,c2);
        +	$LD		r5,`2*$BNSZ`(r4)
        +	$LD		r6,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +						#sqr_add_c2(a,7,1,c3,c1,c2);
        +	$LD		r5,`1*$BNSZ`(r4)
        +	$LD		r6,`7*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	$ST		r11,`8*$BNSZ`(r3)	#r[8]=c3;
        +						#sqr_add_c2(a,7,2,c1,c2,c3);
        +	$LD		r5,`2*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r0
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +						#sqr_add_c2(a,6,3,c1,c2,c3);
        +	$LD		r5,`3*$BNSZ`(r4)
        +	$LD		r6,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +						#sqr_add_c2(a,5,4,c1,c2,c3);
        +	$LD		r5,`4*$BNSZ`(r4)
        +	$LD		r6,`5*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	$ST		r9,`9*$BNSZ`(r3)	#r[9]=c1;
        +						#sqr_add_c(a,5,c2,c3,c1);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r0
        +						#sqr_add_c2(a,6,4,c2,c3,c1);
        +	$LD		r6,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +						#sqr_add_c2(a,7,3,c2,c3,c1);
        +	$LD		r5,`3*$BNSZ`(r4)
        +	$LD		r6,`7*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	$ST		r10,`10*$BNSZ`(r3)	#r[10]=c2;
        +						#sqr_add_c2(a,7,4,c3,c1,c2);
        +	$LD		r5,`4*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r0
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +						#sqr_add_c2(a,6,5,c3,c1,c2);
        +	$LD		r5,`5*$BNSZ`(r4)
        +	$LD		r6,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	addze		r10,r10
        +	$ST		r11,`11*$BNSZ`(r3)	#r[11]=c3;
        +						#sqr_add_c(a,6,c1,c2,c3);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r0
        +						#sqr_add_c2(a,7,5,c1,c2,c3)
        +	$LD		r6,`7*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	addc		r9,r7,r9
        +	adde		r10,r8,r10
        +	addze		r11,r11
        +	$ST		r9,`12*$BNSZ`(r3)	#r[12]=c1;
        +	
        +						#sqr_add_c2(a,7,6,c2,c3,c1)
        +	$LD		r5,`6*$BNSZ`(r4)
        +	$UMULL		r7,r5,r6
        +	$UMULH		r8,r5,r6
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r0
        +	addc		r10,r7,r10
        +	adde		r11,r8,r11
        +	addze		r9,r9
        +	$ST		r10,`13*$BNSZ`(r3)	#r[13]=c2;
        +						#sqr_add_c(a,7,c3,c1,c2);
        +	$UMULL		r7,r6,r6
        +	$UMULH		r8,r6,r6
        +	addc		r11,r7,r11
        +	adde		r9,r8,r9
        +	$ST		r11,`14*$BNSZ`(r3)	#r[14]=c3;
        +	$ST		r9, `15*$BNSZ`(r3)	#r[15]=c1;
        +
        +
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,2,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_mul_comba4" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +
        +.align	4
        +.bn_mul_comba4:
        +#
        +# This is an optimized version of the bn_mul_comba4 routine.
        +#
        +# void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +# r3 contains r
        +# r4 contains a
        +# r5 contains b
        +# r6, r7 are the 2 BN_ULONGs being multiplied.
        +# r8, r9 are the results of the 32x32 giving 64 multiply.
        +# r10, r11, r12 are the equivalents of c1, c2, and c3.
        +#
        +	xor	r0,r0,r0		#r0=0. Used in addze below.
        +					#mul_add_c(a[0],b[0],c1,c2,c3);
        +	$LD	r6,`0*$BNSZ`(r4)		
        +	$LD	r7,`0*$BNSZ`(r5)		
        +	$UMULL	r10,r6,r7		
        +	$UMULH	r11,r6,r7		
        +	$ST	r10,`0*$BNSZ`(r3)	#r[0]=c1
        +					#mul_add_c(a[0],b[1],c2,c3,c1);
        +	$LD	r7,`1*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r8,r11
        +	adde	r12,r9,r0
        +	addze	r10,r0
        +					#mul_add_c(a[1],b[0],c2,c3,c1);
        +	$LD	r6, `1*$BNSZ`(r4)		
        +	$LD	r7, `0*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r8,r11
        +	adde	r12,r9,r12
        +	addze	r10,r10
        +	$ST	r11,`1*$BNSZ`(r3)	#r[1]=c2
        +					#mul_add_c(a[2],b[0],c3,c1,c2);
        +	$LD	r6,`2*$BNSZ`(r4)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r8,r12
        +	adde	r10,r9,r10
        +	addze	r11,r0
        +					#mul_add_c(a[1],b[1],c3,c1,c2);
        +	$LD	r6,`1*$BNSZ`(r4)		
        +	$LD	r7,`1*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r8,r12
        +	adde	r10,r9,r10
        +	addze	r11,r11
        +					#mul_add_c(a[0],b[2],c3,c1,c2);
        +	$LD	r6,`0*$BNSZ`(r4)		
        +	$LD	r7,`2*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r8,r12
        +	adde	r10,r9,r10
        +	addze	r11,r11
        +	$ST	r12,`2*$BNSZ`(r3)	#r[2]=c3
        +					#mul_add_c(a[0],b[3],c1,c2,c3);
        +	$LD	r7,`3*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r8,r10
        +	adde	r11,r9,r11
        +	addze	r12,r0
        +					#mul_add_c(a[1],b[2],c1,c2,c3);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r8,r10
        +	adde	r11,r9,r11
        +	addze	r12,r12
        +					#mul_add_c(a[2],b[1],c1,c2,c3);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r8,r10
        +	adde	r11,r9,r11
        +	addze	r12,r12
        +					#mul_add_c(a[3],b[0],c1,c2,c3);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`0*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r8,r10
        +	adde	r11,r9,r11
        +	addze	r12,r12
        +	$ST	r10,`3*$BNSZ`(r3)	#r[3]=c1
        +					#mul_add_c(a[3],b[1],c2,c3,c1);
        +	$LD	r7,`1*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r8,r11
        +	adde	r12,r9,r12
        +	addze	r10,r0
        +					#mul_add_c(a[2],b[2],c2,c3,c1);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r8,r11
        +	adde	r12,r9,r12
        +	addze	r10,r10
        +					#mul_add_c(a[1],b[3],c2,c3,c1);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r8,r11
        +	adde	r12,r9,r12
        +	addze	r10,r10
        +	$ST	r11,`4*$BNSZ`(r3)	#r[4]=c2
        +					#mul_add_c(a[2],b[3],c3,c1,c2);
        +	$LD	r6,`2*$BNSZ`(r4)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r8,r12
        +	adde	r10,r9,r10
        +	addze	r11,r0
        +					#mul_add_c(a[3],b[2],c3,c1,c2);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r8,r12
        +	adde	r10,r9,r10
        +	addze	r11,r11
        +	$ST	r12,`5*$BNSZ`(r3)	#r[5]=c3
        +					#mul_add_c(a[3],b[3],c1,c2,c3);
        +	$LD	r7,`3*$BNSZ`(r5)		
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r8,r10
        +	adde	r11,r9,r11
        +
        +	$ST	r10,`6*$BNSZ`(r3)	#r[6]=c1
        +	$ST	r11,`7*$BNSZ`(r3)	#r[7]=c2
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,3,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_mul_comba8" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +	
        +.align	4
        +.bn_mul_comba8:
        +#
        +# Optimized version of the bn_mul_comba8 routine.
        +#
        +# void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +# r3 contains r
        +# r4 contains a
        +# r5 contains b
        +# r6, r7 are the 2 BN_ULONGs being multiplied.
        +# r8, r9 are the results of the 32x32 giving 64 multiply.
        +# r10, r11, r12 are the equivalents of c1, c2, and c3.
        +#
        +	xor	r0,r0,r0		#r0=0. Used in addze below.
        +	
        +					#mul_add_c(a[0],b[0],c1,c2,c3);
        +	$LD	r6,`0*$BNSZ`(r4)	#a[0]
        +	$LD	r7,`0*$BNSZ`(r5)	#b[0]
        +	$UMULL	r10,r6,r7
        +	$UMULH	r11,r6,r7
        +	$ST	r10,`0*$BNSZ`(r3)	#r[0]=c1;
        +					#mul_add_c(a[0],b[1],c2,c3,c1);
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	addze	r12,r9			# since we didnt set r12 to zero before.
        +	addze	r10,r0
        +					#mul_add_c(a[1],b[0],c2,c3,c1);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`0*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +	$ST	r11,`1*$BNSZ`(r3)	#r[1]=c2;
        +					#mul_add_c(a[2],b[0],c3,c1,c2);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r0
        +					#mul_add_c(a[1],b[1],c3,c1,c2);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[0],b[2],c3,c1,c2);
        +	$LD	r6,`0*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +	$ST	r12,`2*$BNSZ`(r3)	#r[2]=c3;
        +					#mul_add_c(a[0],b[3],c1,c2,c3);
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r0
        +					#mul_add_c(a[1],b[2],c1,c2,c3);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +		
        +					#mul_add_c(a[2],b[1],c1,c2,c3);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[3],b[0],c1,c2,c3);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`0*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +	$ST	r10,`3*$BNSZ`(r3)	#r[3]=c1;
        +					#mul_add_c(a[4],b[0],c2,c3,c1);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r0
        +					#mul_add_c(a[3],b[1],c2,c3,c1);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[2],b[2],c2,c3,c1);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[1],b[3],c2,c3,c1);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[0],b[4],c2,c3,c1);
        +	$LD	r6,`0*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +	$ST	r11,`4*$BNSZ`(r3)	#r[4]=c2;
        +					#mul_add_c(a[0],b[5],c3,c1,c2);
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r0
        +					#mul_add_c(a[1],b[4],c3,c1,c2);
        +	$LD	r6,`1*$BNSZ`(r4)		
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[2],b[3],c3,c1,c2);
        +	$LD	r6,`2*$BNSZ`(r4)		
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[3],b[2],c3,c1,c2);
        +	$LD	r6,`3*$BNSZ`(r4)		
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[4],b[1],c3,c1,c2);
        +	$LD	r6,`4*$BNSZ`(r4)		
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[5],b[0],c3,c1,c2);
        +	$LD	r6,`5*$BNSZ`(r4)		
        +	$LD	r7,`0*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +	$ST	r12,`5*$BNSZ`(r3)	#r[5]=c3;
        +					#mul_add_c(a[6],b[0],c1,c2,c3);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r0
        +					#mul_add_c(a[5],b[1],c1,c2,c3);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[4],b[2],c1,c2,c3);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[3],b[3],c1,c2,c3);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[2],b[4],c1,c2,c3);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[1],b[5],c1,c2,c3);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[0],b[6],c1,c2,c3);
        +	$LD	r6,`0*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +	$ST	r10,`6*$BNSZ`(r3)	#r[6]=c1;
        +					#mul_add_c(a[0],b[7],c2,c3,c1);
        +	$LD	r7,`7*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r0
        +					#mul_add_c(a[1],b[6],c2,c3,c1);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[2],b[5],c2,c3,c1);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[3],b[4],c2,c3,c1);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[4],b[3],c2,c3,c1);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[5],b[2],c2,c3,c1);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[6],b[1],c2,c3,c1);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[7],b[0],c2,c3,c1);
        +	$LD	r6,`7*$BNSZ`(r4)
        +	$LD	r7,`0*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +	$ST	r11,`7*$BNSZ`(r3)	#r[7]=c2;
        +					#mul_add_c(a[7],b[1],c3,c1,c2);
        +	$LD	r7,`1*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r0
        +					#mul_add_c(a[6],b[2],c3,c1,c2);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[5],b[3],c3,c1,c2);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[4],b[4],c3,c1,c2);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[3],b[5],c3,c1,c2);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[2],b[6],c3,c1,c2);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[1],b[7],c3,c1,c2);
        +	$LD	r6,`1*$BNSZ`(r4)
        +	$LD	r7,`7*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +	$ST	r12,`8*$BNSZ`(r3)	#r[8]=c3;
        +					#mul_add_c(a[2],b[7],c1,c2,c3);
        +	$LD	r6,`2*$BNSZ`(r4)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r0
        +					#mul_add_c(a[3],b[6],c1,c2,c3);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[4],b[5],c1,c2,c3);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[5],b[4],c1,c2,c3);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[6],b[3],c1,c2,c3);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[7],b[2],c1,c2,c3);
        +	$LD	r6,`7*$BNSZ`(r4)
        +	$LD	r7,`2*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +	$ST	r10,`9*$BNSZ`(r3)	#r[9]=c1;
        +					#mul_add_c(a[7],b[3],c2,c3,c1);
        +	$LD	r7,`3*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r0
        +					#mul_add_c(a[6],b[4],c2,c3,c1);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[5],b[5],c2,c3,c1);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[4],b[6],c2,c3,c1);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +					#mul_add_c(a[3],b[7],c2,c3,c1);
        +	$LD	r6,`3*$BNSZ`(r4)
        +	$LD	r7,`7*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +	$ST	r11,`10*$BNSZ`(r3)	#r[10]=c2;
        +					#mul_add_c(a[4],b[7],c3,c1,c2);
        +	$LD	r6,`4*$BNSZ`(r4)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r0
        +					#mul_add_c(a[5],b[6],c3,c1,c2);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[6],b[5],c3,c1,c2);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +					#mul_add_c(a[7],b[4],c3,c1,c2);
        +	$LD	r6,`7*$BNSZ`(r4)
        +	$LD	r7,`4*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	addze	r11,r11
        +	$ST	r12,`11*$BNSZ`(r3)	#r[11]=c3;
        +					#mul_add_c(a[7],b[5],c1,c2,c3);
        +	$LD	r7,`5*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r0
        +					#mul_add_c(a[6],b[6],c1,c2,c3);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +					#mul_add_c(a[5],b[7],c1,c2,c3);
        +	$LD	r6,`5*$BNSZ`(r4)
        +	$LD	r7,`7*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r10,r10,r8
        +	adde	r11,r11,r9
        +	addze	r12,r12
        +	$ST	r10,`12*$BNSZ`(r3)	#r[12]=c1;
        +					#mul_add_c(a[6],b[7],c2,c3,c1);
        +	$LD	r6,`6*$BNSZ`(r4)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r0
        +					#mul_add_c(a[7],b[6],c2,c3,c1);
        +	$LD	r6,`7*$BNSZ`(r4)
        +	$LD	r7,`6*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r11,r11,r8
        +	adde	r12,r12,r9
        +	addze	r10,r10
        +	$ST	r11,`13*$BNSZ`(r3)	#r[13]=c2;
        +					#mul_add_c(a[7],b[7],c3,c1,c2);
        +	$LD	r7,`7*$BNSZ`(r5)
        +	$UMULL	r8,r6,r7
        +	$UMULH	r9,r6,r7
        +	addc	r12,r12,r8
        +	adde	r10,r10,r9
        +	$ST	r12,`14*$BNSZ`(r3)	#r[14]=c3;
        +	$ST	r10,`15*$BNSZ`(r3)	#r[15]=c1;
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,3,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_sub_words" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +#
        +.align	4
        +.bn_sub_words:
        +#
        +#	Handcoded version of bn_sub_words
        +#
        +#BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
        +#
        +#	r3 = r
        +#	r4 = a
        +#	r5 = b
        +#	r6 = n
        +#
        +#       Note:	No loop unrolling done since this is not a performance
        +#               critical loop.
        +
        +	xor	r0,r0,r0	#set r0 = 0
        +#
        +#	check for r6 = 0 AND set carry bit.
        +#
        +	subfc.	r7,r0,r6        # If r6 is 0 then result is 0.
        +				# if r6 > 0 then result !=0
        +				# In either case carry bit is set.
        +	beq	Lppcasm_sub_adios
        +	addi	r4,r4,-$BNSZ
        +	addi	r3,r3,-$BNSZ
        +	addi	r5,r5,-$BNSZ
        +	mtctr	r6
        +Lppcasm_sub_mainloop:	
        +	$LDU	r7,$BNSZ(r4)
        +	$LDU	r8,$BNSZ(r5)
        +	subfe	r6,r8,r7	# r6 = r7+carry bit + onescomplement(r8)
        +				# if carry = 1 this is r7-r8. Else it
        +				# is r7-r8 -1 as we need.
        +	$STU	r6,$BNSZ(r3)
        +	bdnz-	Lppcasm_sub_mainloop
        +Lppcasm_sub_adios:	
        +	subfze	r3,r0		# if carry bit is set then r3 = 0 else -1
        +	andi.	r3,r3,1         # keep only last bit.
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,4,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_add_words" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +
        +.align	4
        +.bn_add_words:
        +#
        +#	Handcoded version of bn_add_words
        +#
        +#BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
        +#
        +#	r3 = r
        +#	r4 = a
        +#	r5 = b
        +#	r6 = n
        +#
        +#       Note:	No loop unrolling done since this is not a performance
        +#               critical loop.
        +
        +	xor	r0,r0,r0
        +#
        +#	check for r6 = 0. Is this needed?
        +#
        +	addic.	r6,r6,0		#test r6 and clear carry bit.
        +	beq	Lppcasm_add_adios
        +	addi	r4,r4,-$BNSZ
        +	addi	r3,r3,-$BNSZ
        +	addi	r5,r5,-$BNSZ
        +	mtctr	r6
        +Lppcasm_add_mainloop:	
        +	$LDU	r7,$BNSZ(r4)
        +	$LDU	r8,$BNSZ(r5)
        +	adde	r8,r7,r8
        +	$STU	r8,$BNSZ(r3)
        +	bdnz-	Lppcasm_add_mainloop
        +Lppcasm_add_adios:	
        +	addze	r3,r0			#return carry bit.
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,4,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_div_words" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +
        +.align	4
        +.bn_div_words:
        +#
        +#	This is a cleaned up version of code generated by
        +#	the AIX compiler. The only optimization is to use
        +#	the PPC instruction to count leading zeros instead
        +#	of call to num_bits_word. Since this was compiled
        +#	only at level -O2 we can possibly squeeze it more?
        +#	
        +#	r3 = h
        +#	r4 = l
        +#	r5 = d
        +	
        +	$UCMPI	0,r5,0			# compare r5 and 0
        +	bne	Lppcasm_div1		# proceed if d!=0
        +	li	r3,-1			# d=0 return -1
        +	blr
        +Lppcasm_div1:
        +	xor	r0,r0,r0		#r0=0
        +	li	r8,$BITS
        +	$CNTLZ.	r7,r5			#r7 = num leading 0s in d.
        +	beq	Lppcasm_div2		#proceed if no leading zeros
        +	subf	r8,r7,r8		#r8 = BN_num_bits_word(d)
        +	$SHR.	r9,r3,r8		#are there any bits above r8'th?
        +	$TR	16,r9,r0		#if there're, signal to dump core...
        +Lppcasm_div2:
        +	$UCMP	0,r3,r5			#h>=d?
        +	blt	Lppcasm_div3		#goto Lppcasm_div3 if not
        +	subf	r3,r5,r3		#h-=d ; 
        +Lppcasm_div3:				#r7 = BN_BITS2-i. so r7=i
        +	cmpi	0,0,r7,0		# is (i == 0)?
        +	beq	Lppcasm_div4
        +	$SHL	r3,r3,r7		# h = (h<< i)
        +	$SHR	r8,r4,r8		# r8 = (l >> BN_BITS2 -i)
        +	$SHL	r5,r5,r7		# d<<=i
        +	or	r3,r3,r8		# h = (h<<i)|(l>>(BN_BITS2-i))
        +	$SHL	r4,r4,r7		# l <<=i
        +Lppcasm_div4:
        +	$SHRI	r9,r5,`$BITS/2`		# r9 = dh
        +					# dl will be computed when needed
        +					# as it saves registers.
        +	li	r6,2			#r6=2
        +	mtctr	r6			#counter will be in count.
        +Lppcasm_divouterloop: 
        +	$SHRI	r8,r3,`$BITS/2`		#r8 = (h>>BN_BITS4)
        +	$SHRI	r11,r4,`$BITS/2`	#r11= (l&BN_MASK2h)>>BN_BITS4
        +					# compute here for innerloop.
        +	$UCMP	0,r8,r9			# is (h>>BN_BITS4)==dh
        +	bne	Lppcasm_div5		# goto Lppcasm_div5 if not
        +
        +	li	r8,-1
        +	$CLRU	r8,r8,`$BITS/2`		#q = BN_MASK2l 
        +	b	Lppcasm_div6
        +Lppcasm_div5:
        +	$UDIV	r8,r3,r9		#q = h/dh
        +Lppcasm_div6:
        +	$UMULL	r12,r9,r8		#th = q*dh
        +	$CLRU	r10,r5,`$BITS/2`	#r10=dl
        +	$UMULL	r6,r8,r10		#tl = q*dl
        +	
        +Lppcasm_divinnerloop:
        +	subf	r10,r12,r3		#t = h -th
        +	$SHRI	r7,r10,`$BITS/2`	#r7= (t &BN_MASK2H), sort of...
        +	addic.	r7,r7,0			#test if r7 == 0. used below.
        +					# now want to compute
        +					# r7 = (t<<BN_BITS4)|((l&BN_MASK2h)>>BN_BITS4)
        +					# the following 2 instructions do that
        +	$SHLI	r7,r10,`$BITS/2`	# r7 = (t<<BN_BITS4)
        +	or	r7,r7,r11		# r7|=((l&BN_MASK2h)>>BN_BITS4)
        +	$UCMP	cr1,r6,r7		# compare (tl <= r7)
        +	bne	Lppcasm_divinnerexit
        +	ble	cr1,Lppcasm_divinnerexit
        +	addi	r8,r8,-1		#q--
        +	subf	r12,r9,r12		#th -=dh
        +	$CLRU	r10,r5,`$BITS/2`	#r10=dl. t is no longer needed in loop.
        +	subf	r6,r10,r6		#tl -=dl
        +	b	Lppcasm_divinnerloop
        +Lppcasm_divinnerexit:
        +	$SHRI	r10,r6,`$BITS/2`	#t=(tl>>BN_BITS4)
        +	$SHLI	r11,r6,`$BITS/2`	#tl=(tl<<BN_BITS4)&BN_MASK2h;
        +	$UCMP	cr1,r4,r11		# compare l and tl
        +	add	r12,r12,r10		# th+=t
        +	bge	cr1,Lppcasm_div7	# if (l>=tl) goto Lppcasm_div7
        +	addi	r12,r12,1		# th++
        +Lppcasm_div7:
        +	subf	r11,r11,r4		#r11=l-tl
        +	$UCMP	cr1,r3,r12		#compare h and th
        +	bge	cr1,Lppcasm_div8	#if (h>=th) goto Lppcasm_div8
        +	addi	r8,r8,-1		# q--
        +	add	r3,r5,r3		# h+=d
        +Lppcasm_div8:
        +	subf	r12,r12,r3		#r12 = h-th
        +	$SHLI	r4,r11,`$BITS/2`	#l=(l&BN_MASK2l)<<BN_BITS4
        +					# want to compute
        +					# h = ((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2
        +					# the following 2 instructions will do this.
        +	$INSR	r11,r12,`$BITS/2`,`$BITS/2`	# r11 is the value we want rotated $BITS/2.
        +	$ROTL	r3,r11,`$BITS/2`	# rotate by $BITS/2 and store in r3
        +	bdz	Lppcasm_div9		#if (count==0) break ;
        +	$SHLI	r0,r8,`$BITS/2`		#ret =q<<BN_BITS4
        +	b	Lppcasm_divouterloop
        +Lppcasm_div9:
        +	or	r3,r8,r0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,3,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_sqr_words" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +.align	4
        +.bn_sqr_words:
        +#
        +#	Optimized version of bn_sqr_words
        +#
        +#	void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
        +#
        +#	r3 = r
        +#	r4 = a
        +#	r5 = n
        +#
        +#	r6 = a[i].
        +#	r7,r8 = product.
        +#
        +#	No unrolling done here. Not performance critical.
        +
        +	addic.	r5,r5,0			#test r5.
        +	beq	Lppcasm_sqr_adios
        +	addi	r4,r4,-$BNSZ
        +	addi	r3,r3,-$BNSZ
        +	mtctr	r5
        +Lppcasm_sqr_mainloop:	
        +					#sqr(r[0],r[1],a[0]);
        +	$LDU	r6,$BNSZ(r4)
        +	$UMULL	r7,r6,r6
        +	$UMULH  r8,r6,r6
        +	$STU	r7,$BNSZ(r3)
        +	$STU	r8,$BNSZ(r3)
        +	bdnz-	Lppcasm_sqr_mainloop
        +Lppcasm_sqr_adios:	
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,3,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_mul_words" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +
        +.align	4	
        +.bn_mul_words:
        +#
        +# BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
        +#
        +# r3 = rp
        +# r4 = ap
        +# r5 = num
        +# r6 = w
        +	xor	r0,r0,r0
        +	xor	r12,r12,r12		# used for carry
        +	rlwinm.	r7,r5,30,2,31		# num >> 2
        +	beq	Lppcasm_mw_REM
        +	mtctr	r7
        +Lppcasm_mw_LOOP:	
        +					#mul(rp[0],ap[0],w,c1);
        +	$LD	r8,`0*$BNSZ`(r4)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	addc	r9,r9,r12
        +	#addze	r10,r10			#carry is NOT ignored.
        +					#will be taken care of
        +					#in second spin below
        +					#using adde.
        +	$ST	r9,`0*$BNSZ`(r3)
        +					#mul(rp[1],ap[1],w,c1);
        +	$LD	r8,`1*$BNSZ`(r4)	
        +	$UMULL	r11,r6,r8
        +	$UMULH  r12,r6,r8
        +	adde	r11,r11,r10
        +	#addze	r12,r12
        +	$ST	r11,`1*$BNSZ`(r3)
        +					#mul(rp[2],ap[2],w,c1);
        +	$LD	r8,`2*$BNSZ`(r4)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	adde	r9,r9,r12
        +	#addze	r10,r10
        +	$ST	r9,`2*$BNSZ`(r3)
        +					#mul_add(rp[3],ap[3],w,c1);
        +	$LD	r8,`3*$BNSZ`(r4)
        +	$UMULL	r11,r6,r8
        +	$UMULH  r12,r6,r8
        +	adde	r11,r11,r10
        +	addze	r12,r12			#this spin we collect carry into
        +					#r12
        +	$ST	r11,`3*$BNSZ`(r3)
        +	
        +	addi	r3,r3,`4*$BNSZ`
        +	addi	r4,r4,`4*$BNSZ`
        +	bdnz-	Lppcasm_mw_LOOP
        +
        +Lppcasm_mw_REM:
        +	andi.	r5,r5,0x3
        +	beq	Lppcasm_mw_OVER
        +					#mul(rp[0],ap[0],w,c1);
        +	$LD	r8,`0*$BNSZ`(r4)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	addc	r9,r9,r12
        +	addze	r10,r10
        +	$ST	r9,`0*$BNSZ`(r3)
        +	addi	r12,r10,0
        +	
        +	addi	r5,r5,-1
        +	cmpli	0,0,r5,0
        +	beq	Lppcasm_mw_OVER
        +
        +	
        +					#mul(rp[1],ap[1],w,c1);
        +	$LD	r8,`1*$BNSZ`(r4)	
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	addc	r9,r9,r12
        +	addze	r10,r10
        +	$ST	r9,`1*$BNSZ`(r3)
        +	addi	r12,r10,0
        +	
        +	addi	r5,r5,-1
        +	cmpli	0,0,r5,0
        +	beq	Lppcasm_mw_OVER
        +	
        +					#mul_add(rp[2],ap[2],w,c1);
        +	$LD	r8,`2*$BNSZ`(r4)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	addc	r9,r9,r12
        +	addze	r10,r10
        +	$ST	r9,`2*$BNSZ`(r3)
        +	addi	r12,r10,0
        +		
        +Lppcasm_mw_OVER:	
        +	addi	r3,r12,0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,4,0
        +	.long	0
        +
        +#
        +#	NOTE:	The following label name should be changed to
        +#		"bn_mul_add_words" i.e. remove the first dot
        +#		for the gcc compiler. This should be automatically
        +#		done in the build
        +#
        +
        +.align	4
        +.bn_mul_add_words:
        +#
        +# BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
        +#
        +# r3 = rp
        +# r4 = ap
        +# r5 = num
        +# r6 = w
        +#
        +# empirical evidence suggests that unrolled version performs best!!
        +#
        +	xor	r0,r0,r0		#r0 = 0
        +	xor	r12,r12,r12  		#r12 = 0 . used for carry		
        +	rlwinm.	r7,r5,30,2,31		# num >> 2
        +	beq	Lppcasm_maw_leftover	# if (num < 4) go LPPCASM_maw_leftover
        +	mtctr	r7
        +Lppcasm_maw_mainloop:	
        +					#mul_add(rp[0],ap[0],w,c1);
        +	$LD	r8,`0*$BNSZ`(r4)
        +	$LD	r11,`0*$BNSZ`(r3)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	addc	r9,r9,r12		#r12 is carry.
        +	addze	r10,r10
        +	addc	r9,r9,r11
        +	#addze	r10,r10
        +					#the above instruction addze
        +					#is NOT needed. Carry will NOT
        +					#be ignored. It's not affected
        +					#by multiply and will be collected
        +					#in the next spin
        +	$ST	r9,`0*$BNSZ`(r3)
        +	
        +					#mul_add(rp[1],ap[1],w,c1);
        +	$LD	r8,`1*$BNSZ`(r4)	
        +	$LD	r9,`1*$BNSZ`(r3)
        +	$UMULL	r11,r6,r8
        +	$UMULH  r12,r6,r8
        +	adde	r11,r11,r10		#r10 is carry.
        +	addze	r12,r12
        +	addc	r11,r11,r9
        +	#addze	r12,r12
        +	$ST	r11,`1*$BNSZ`(r3)
        +	
        +					#mul_add(rp[2],ap[2],w,c1);
        +	$LD	r8,`2*$BNSZ`(r4)
        +	$UMULL	r9,r6,r8
        +	$LD	r11,`2*$BNSZ`(r3)
        +	$UMULH  r10,r6,r8
        +	adde	r9,r9,r12
        +	addze	r10,r10
        +	addc	r9,r9,r11
        +	#addze	r10,r10
        +	$ST	r9,`2*$BNSZ`(r3)
        +	
        +					#mul_add(rp[3],ap[3],w,c1);
        +	$LD	r8,`3*$BNSZ`(r4)
        +	$UMULL	r11,r6,r8
        +	$LD	r9,`3*$BNSZ`(r3)
        +	$UMULH  r12,r6,r8
        +	adde	r11,r11,r10
        +	addze	r12,r12
        +	addc	r11,r11,r9
        +	addze	r12,r12
        +	$ST	r11,`3*$BNSZ`(r3)
        +	addi	r3,r3,`4*$BNSZ`
        +	addi	r4,r4,`4*$BNSZ`
        +	bdnz-	Lppcasm_maw_mainloop
        +	
        +Lppcasm_maw_leftover:
        +	andi.	r5,r5,0x3
        +	beq	Lppcasm_maw_adios
        +	addi	r3,r3,-$BNSZ
        +	addi	r4,r4,-$BNSZ
        +					#mul_add(rp[0],ap[0],w,c1);
        +	mtctr	r5
        +	$LDU	r8,$BNSZ(r4)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	$LDU	r11,$BNSZ(r3)
        +	addc	r9,r9,r11
        +	addze	r10,r10
        +	addc	r9,r9,r12
        +	addze	r12,r10
        +	$ST	r9,0(r3)
        +	
        +	bdz	Lppcasm_maw_adios
        +					#mul_add(rp[1],ap[1],w,c1);
        +	$LDU	r8,$BNSZ(r4)	
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	$LDU	r11,$BNSZ(r3)
        +	addc	r9,r9,r11
        +	addze	r10,r10
        +	addc	r9,r9,r12
        +	addze	r12,r10
        +	$ST	r9,0(r3)
        +	
        +	bdz	Lppcasm_maw_adios
        +					#mul_add(rp[2],ap[2],w,c1);
        +	$LDU	r8,$BNSZ(r4)
        +	$UMULL	r9,r6,r8
        +	$UMULH  r10,r6,r8
        +	$LDU	r11,$BNSZ(r3)
        +	addc	r9,r9,r11
        +	addze	r10,r10
        +	addc	r9,r9,r12
        +	addze	r12,r10
        +	$ST	r9,0(r3)
        +		
        +Lppcasm_maw_adios:	
        +	addi	r3,r12,0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,4,0
        +	.long	0
        +	.align	4
        +EOF
        +$data =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $data;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/ppc64-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/ppc64-mont.pl
        new file mode 100644
        index 000000000..a14e769ad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/ppc64-mont.pl
        @@ -0,0 +1,1088 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# December 2007
        +
        +# The reason for undertaken effort is basically following. Even though
        +# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
        +# performance was observed to be less than impressive, essentially as
        +# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
        +# Well, it's not surprising that IBM had to make some sacrifices to
        +# boost the clock frequency that much, but no overall improvement?
        +# Having observed how much difference did switching to FPU make on
        +# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
        +# Unfortunately the resulting performance improvement is not as
        +# impressive, ~30%, and in absolute terms is still very far from what
        +# one would expect from 4.7GHz CPU. There is a chance that I'm doing
        +# something wrong, but in the lack of assembler level micro-profiling
        +# data or at least decent platform guide I can't tell... Or better
        +# results might be achieved with VMX... Anyway, this module provides
        +# *worse* performance on other PowerPC implementations, ~40-15% slower
        +# on PPC970 depending on key length and ~40% slower on Power 5 for all
        +# key lengths. As it's obviously inappropriate as "best all-round"
        +# alternative, it has to be complemented with run-time CPU family
        +# detection. Oh! It should also be noted that unlike other PowerPC
        +# implementation IALU ppc-mont.pl module performs *suboptimaly* on
        +# >=1024-bit key lengths on Power 6. It should also be noted that
        +# *everything* said so far applies to 64-bit builds! As far as 32-bit
        +# application executed on 64-bit CPU goes, this module is likely to
        +# become preferred choice, because it's easy to adapt it for such
        +# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
        +
        +# February 2008
        +
        +# Micro-profiling assisted optimization results in ~15% improvement
        +# over original ppc64-mont.pl version, or overall ~50% improvement
        +# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
        +# Power 6 CPU, this module is 5-150% faster depending on key length,
        +# [hereafter] more for longer keys. But if compared to ppc-mont.pl
        +# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
        +# in absolute terms, but it's apparently the way Power 6 is...
        +
        +# December 2009
        +
        +# Adapted for 32-bit build this module delivers 25-120%, yes, more
        +# than *twice* for longer keys, performance improvement over 32-bit
        +# ppc-mont.pl on 1.8GHz PPC970. However! This implementation utilizes
        +# even 64-bit integer operations and the trouble is that most PPC
        +# operating systems don't preserve upper halves of general purpose
        +# registers upon 32-bit signal delivery. They do preserve them upon
        +# context switch, but not signalling:-( This means that asynchronous
        +# signals have to be blocked upon entry to this subroutine. Signal
        +# masking (and of course complementary unmasking) has quite an impact
        +# on performance, naturally larger for shorter keys. It's so severe
        +# that 512-bit key performance can be as low as 1/3 of expected one.
        +# This is why this routine can be engaged for longer key operations
        +# only on these OSes, see crypto/ppccap.c for further details. MacOS X
        +# is an exception from this and doesn't require signal masking, and
        +# that's where above improvement coefficients were collected. For
        +# others alternative would be to break dependence on upper halves of
        +# GPRs by sticking to 32-bit integer operations...
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /32/) {
        +	$SIZE_T=4;
        +	$RZONE=	224;
        +	$fname=	"bn_mul_mont_fpu64";
        +
        +	$STUX=	"stwux";	# store indexed and update
        +	$PUSH=	"stw";
        +	$POP=	"lwz";
        +} elsif ($flavour =~ /64/) {
        +	$SIZE_T=8;
        +	$RZONE=	288;
        +	$fname=	"bn_mul_mont_fpu64";
        +
        +	# same as above, but 64-bit mnemonics...
        +	$STUX=	"stdux";	# store indexed and update
        +	$PUSH=	"std";
        +	$POP=	"ld";
        +} else { die "nonsense $flavour"; }
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
        +
        +$FRAME=64;	# padded frame header
        +$TRANSFER=16*8;
        +
        +$carry="r0";
        +$sp="r1";
        +$toc="r2";
        +$rp="r3";	$ovf="r3";
        +$ap="r4";
        +$bp="r5";
        +$np="r6";
        +$n0="r7";
        +$num="r8";
        +$rp="r9";	# $rp is reassigned
        +$tp="r10";
        +$j="r11";
        +$i="r12";
        +# non-volatile registers
        +$nap_d="r22";	# interleaved ap and np in double format
        +$a0="r23";	# ap[0]
        +$t0="r24";	# temporary registers
        +$t1="r25";
        +$t2="r26";
        +$t3="r27";
        +$t4="r28";
        +$t5="r29";
        +$t6="r30";
        +$t7="r31";
        +
        +# PPC offers enough register bank capacity to unroll inner loops twice
        +#
        +#     ..A3A2A1A0
        +#           dcba
        +#    -----------
        +#            A0a
        +#           A0b
        +#          A0c
        +#         A0d
        +#          A1a
        +#         A1b
        +#        A1c
        +#       A1d
        +#        A2a
        +#       A2b
        +#      A2c
        +#     A2d
        +#      A3a
        +#     A3b
        +#    A3c
        +#   A3d
        +#    ..a
        +#   ..b
        +#
        +$ba="f0";	$bb="f1";	$bc="f2";	$bd="f3";
        +$na="f4";	$nb="f5";	$nc="f6";	$nd="f7";
        +$dota="f8";	$dotb="f9";
        +$A0="f10";	$A1="f11";	$A2="f12";	$A3="f13";
        +$N0="f20";	$N1="f21";	$N2="f22";	$N3="f23";
        +$T0a="f24";	$T0b="f25";
        +$T1a="f26";	$T1b="f27";
        +$T2a="f28";	$T2b="f29";
        +$T3a="f30";	$T3b="f31";
        +
        +# sp----------->+-------------------------------+
        +#		| saved sp			|
        +#		+-------------------------------+
        +#		.				.
        +#   +64		+-------------------------------+
        +#		| 16 gpr<->fpr transfer zone	|
        +#		.				.
        +#		.				.
        +#   +16*8	+-------------------------------+
        +#		| __int64 tmp[-1]		|
        +#		+-------------------------------+
        +#		| __int64 tmp[num]		|
        +#		.				.
        +#		.				.
        +#		.				.
        +#   +(num+1)*8	+-------------------------------+
        +#		| padding to 64 byte boundary	|
        +#		.				.
        +#   +X		+-------------------------------+
        +#		| double nap_d[4*num]		|
        +#		.				.
        +#		.				.
        +#		.				.
        +#		+-------------------------------+
        +#		.				.
        +#   -12*size_t	+-------------------------------+
        +#		| 10 saved gpr, r22-r31		|
        +#		.				.
        +#		.				.
        +#   -12*8	+-------------------------------+
        +#		| 12 saved fpr, f20-f31		|
        +#		.				.
        +#		.				.
        +#		+-------------------------------+
        +
        +$code=<<___;
        +.machine "any"
        +.text
        +
        +.globl	.$fname
        +.align	5
        +.$fname:
        +	cmpwi	$num,`3*8/$SIZE_T`
        +	mr	$rp,r3		; $rp is reassigned
        +	li	r3,0		; possible "not handled" return code
        +	bltlr-
        +	andi.	r0,$num,`16/$SIZE_T-1`		; $num has to be "even"
        +	bnelr-
        +
        +	slwi	$num,$num,`log($SIZE_T)/log(2)`	; num*=sizeof(BN_LONG)
        +	li	$i,-4096
        +	slwi	$tp,$num,2	; place for {an}p_{lh}[num], i.e. 4*num
        +	add	$tp,$tp,$num	; place for tp[num+1]
        +	addi	$tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
        +	subf	$tp,$tp,$sp	; $sp-$tp
        +	and	$tp,$tp,$i	; minimize TLB usage
        +	subf	$tp,$sp,$tp	; $tp-$sp
        +	mr	$i,$sp
        +	$STUX	$sp,$sp,$tp	; alloca
        +
        +	$PUSH	r22,`-12*8-10*$SIZE_T`($i)
        +	$PUSH	r23,`-12*8-9*$SIZE_T`($i)
        +	$PUSH	r24,`-12*8-8*$SIZE_T`($i)
        +	$PUSH	r25,`-12*8-7*$SIZE_T`($i)
        +	$PUSH	r26,`-12*8-6*$SIZE_T`($i)
        +	$PUSH	r27,`-12*8-5*$SIZE_T`($i)
        +	$PUSH	r28,`-12*8-4*$SIZE_T`($i)
        +	$PUSH	r29,`-12*8-3*$SIZE_T`($i)
        +	$PUSH	r30,`-12*8-2*$SIZE_T`($i)
        +	$PUSH	r31,`-12*8-1*$SIZE_T`($i)
        +	stfd	f20,`-12*8`($i)
        +	stfd	f21,`-11*8`($i)
        +	stfd	f22,`-10*8`($i)
        +	stfd	f23,`-9*8`($i)
        +	stfd	f24,`-8*8`($i)
        +	stfd	f25,`-7*8`($i)
        +	stfd	f26,`-6*8`($i)
        +	stfd	f27,`-5*8`($i)
        +	stfd	f28,`-4*8`($i)
        +	stfd	f29,`-3*8`($i)
        +	stfd	f30,`-2*8`($i)
        +	stfd	f31,`-1*8`($i)
        +___
        +$code.=<<___ if ($SIZE_T==8);
        +	ld	$a0,0($ap)	; pull ap[0] value
        +	ld	$n0,0($n0)	; pull n0[0] value
        +	ld	$t3,0($bp)	; bp[0]
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	mr	$t1,$n0
        +	lwz	$a0,0($ap)	; pull ap[0,1] value
        +	lwz	$t0,4($ap)
        +	lwz	$n0,0($t1)	; pull n0[0,1] value
        +	lwz	$t1,4($t1)
        +	lwz	$t3,0($bp)	; bp[0,1]
        +	lwz	$t2,4($bp)
        +	insrdi	$a0,$t0,32,0
        +	insrdi	$n0,$t1,32,0
        +	insrdi	$t3,$t2,32,0
        +___
        +$code.=<<___;
        +	addi	$tp,$sp,`$FRAME+$TRANSFER+8+64`
        +	li	$i,-64
        +	add	$nap_d,$tp,$num
        +	and	$nap_d,$nap_d,$i	; align to 64 bytes
        +
        +	mulld	$t7,$a0,$t3	; ap[0]*bp[0]
        +	; nap_d is off by 1, because it's used with stfdu/lfdu
        +	addi	$nap_d,$nap_d,-8
        +	srwi	$j,$num,`3+1`	; counter register, num/2
        +	mulld	$t7,$t7,$n0	; tp[0]*n0
        +	addi	$j,$j,-1
        +	addi	$tp,$sp,`$FRAME+$TRANSFER-8`
        +	li	$carry,0
        +	mtctr	$j
        +
        +	; transfer bp[0] to FPU as 4x16-bit values
        +	extrdi	$t0,$t3,16,48
        +	extrdi	$t1,$t3,16,32
        +	extrdi	$t2,$t3,16,16
        +	extrdi	$t3,$t3,16,0
        +	std	$t0,`$FRAME+0`($sp)
        +	std	$t1,`$FRAME+8`($sp)
        +	std	$t2,`$FRAME+16`($sp)
        +	std	$t3,`$FRAME+24`($sp)
        +	; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
        +	extrdi	$t4,$t7,16,48
        +	extrdi	$t5,$t7,16,32
        +	extrdi	$t6,$t7,16,16
        +	extrdi	$t7,$t7,16,0
        +	std	$t4,`$FRAME+32`($sp)
        +	std	$t5,`$FRAME+40`($sp)
        +	std	$t6,`$FRAME+48`($sp)
        +	std	$t7,`$FRAME+56`($sp)
        +___
        +$code.=<<___ if ($SIZE_T==8);
        +	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
        +	lwz	$t1,0($ap)
        +	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
        +	lwz	$t3,8($ap)
        +	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
        +	lwz	$t5,0($np)
        +	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
        +	lwz	$t7,8($np)
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	lwz	$t0,0($ap)		; load a[j..j+3] as 32-bit word pairs
        +	lwz	$t1,4($ap)
        +	lwz	$t2,8($ap)
        +	lwz	$t3,12($ap)
        +	lwz	$t4,0($np)		; load n[j..j+3] as 32-bit word pairs
        +	lwz	$t5,4($np)
        +	lwz	$t6,8($np)
        +	lwz	$t7,12($np)
        +___
        +$code.=<<___;
        +	lfd	$ba,`$FRAME+0`($sp)
        +	lfd	$bb,`$FRAME+8`($sp)
        +	lfd	$bc,`$FRAME+16`($sp)
        +	lfd	$bd,`$FRAME+24`($sp)
        +	lfd	$na,`$FRAME+32`($sp)
        +	lfd	$nb,`$FRAME+40`($sp)
        +	lfd	$nc,`$FRAME+48`($sp)
        +	lfd	$nd,`$FRAME+56`($sp)
        +	std	$t0,`$FRAME+64`($sp)
        +	std	$t1,`$FRAME+72`($sp)
        +	std	$t2,`$FRAME+80`($sp)
        +	std	$t3,`$FRAME+88`($sp)
        +	std	$t4,`$FRAME+96`($sp)
        +	std	$t5,`$FRAME+104`($sp)
        +	std	$t6,`$FRAME+112`($sp)
        +	std	$t7,`$FRAME+120`($sp)
        +	fcfid	$ba,$ba
        +	fcfid	$bb,$bb
        +	fcfid	$bc,$bc
        +	fcfid	$bd,$bd
        +	fcfid	$na,$na
        +	fcfid	$nb,$nb
        +	fcfid	$nc,$nc
        +	fcfid	$nd,$nd
        +
        +	lfd	$A0,`$FRAME+64`($sp)
        +	lfd	$A1,`$FRAME+72`($sp)
        +	lfd	$A2,`$FRAME+80`($sp)
        +	lfd	$A3,`$FRAME+88`($sp)
        +	lfd	$N0,`$FRAME+96`($sp)
        +	lfd	$N1,`$FRAME+104`($sp)
        +	lfd	$N2,`$FRAME+112`($sp)
        +	lfd	$N3,`$FRAME+120`($sp)
        +	fcfid	$A0,$A0
        +	fcfid	$A1,$A1
        +	fcfid	$A2,$A2
        +	fcfid	$A3,$A3
        +	fcfid	$N0,$N0
        +	fcfid	$N1,$N1
        +	fcfid	$N2,$N2
        +	fcfid	$N3,$N3
        +	addi	$ap,$ap,16
        +	addi	$np,$np,16
        +
        +	fmul	$T1a,$A1,$ba
        +	fmul	$T1b,$A1,$bb
        +	stfd	$A0,8($nap_d)		; save a[j] in double format
        +	stfd	$A1,16($nap_d)
        +	fmul	$T2a,$A2,$ba
        +	fmul	$T2b,$A2,$bb
        +	stfd	$A2,24($nap_d)		; save a[j+1] in double format
        +	stfd	$A3,32($nap_d)
        +	fmul	$T3a,$A3,$ba
        +	fmul	$T3b,$A3,$bb
        +	stfd	$N0,40($nap_d)		; save n[j] in double format
        +	stfd	$N1,48($nap_d)
        +	fmul	$T0a,$A0,$ba
        +	fmul	$T0b,$A0,$bb
        +	stfd	$N2,56($nap_d)		; save n[j+1] in double format
        +	stfdu	$N3,64($nap_d)
        +
        +	fmadd	$T1a,$A0,$bc,$T1a
        +	fmadd	$T1b,$A0,$bd,$T1b
        +	fmadd	$T2a,$A1,$bc,$T2a
        +	fmadd	$T2b,$A1,$bd,$T2b
        +	fmadd	$T3a,$A2,$bc,$T3a
        +	fmadd	$T3b,$A2,$bd,$T3b
        +	fmul	$dota,$A3,$bc
        +	fmul	$dotb,$A3,$bd
        +
        +	fmadd	$T1a,$N1,$na,$T1a
        +	fmadd	$T1b,$N1,$nb,$T1b
        +	fmadd	$T2a,$N2,$na,$T2a
        +	fmadd	$T2b,$N2,$nb,$T2b
        +	fmadd	$T3a,$N3,$na,$T3a
        +	fmadd	$T3b,$N3,$nb,$T3b
        +	fmadd	$T0a,$N0,$na,$T0a
        +	fmadd	$T0b,$N0,$nb,$T0b
        +
        +	fmadd	$T1a,$N0,$nc,$T1a
        +	fmadd	$T1b,$N0,$nd,$T1b
        +	fmadd	$T2a,$N1,$nc,$T2a
        +	fmadd	$T2b,$N1,$nd,$T2b
        +	fmadd	$T3a,$N2,$nc,$T3a
        +	fmadd	$T3b,$N2,$nd,$T3b
        +	fmadd	$dota,$N3,$nc,$dota
        +	fmadd	$dotb,$N3,$nd,$dotb
        +
        +	fctid	$T0a,$T0a
        +	fctid	$T0b,$T0b
        +	fctid	$T1a,$T1a
        +	fctid	$T1b,$T1b
        +	fctid	$T2a,$T2a
        +	fctid	$T2b,$T2b
        +	fctid	$T3a,$T3a
        +	fctid	$T3b,$T3b
        +
        +	stfd	$T0a,`$FRAME+0`($sp)
        +	stfd	$T0b,`$FRAME+8`($sp)
        +	stfd	$T1a,`$FRAME+16`($sp)
        +	stfd	$T1b,`$FRAME+24`($sp)
        +	stfd	$T2a,`$FRAME+32`($sp)
        +	stfd	$T2b,`$FRAME+40`($sp)
        +	stfd	$T3a,`$FRAME+48`($sp)
        +	stfd	$T3b,`$FRAME+56`($sp)
        +
        +.align	5
        +L1st:
        +___
        +$code.=<<___ if ($SIZE_T==8);
        +	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
        +	lwz	$t1,0($ap)
        +	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
        +	lwz	$t3,8($ap)
        +	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
        +	lwz	$t5,0($np)
        +	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
        +	lwz	$t7,8($np)
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	lwz	$t0,0($ap)		; load a[j..j+3] as 32-bit word pairs
        +	lwz	$t1,4($ap)
        +	lwz	$t2,8($ap)
        +	lwz	$t3,12($ap)
        +	lwz	$t4,0($np)		; load n[j..j+3] as 32-bit word pairs
        +	lwz	$t5,4($np)
        +	lwz	$t6,8($np)
        +	lwz	$t7,12($np)
        +___
        +$code.=<<___;
        +	std	$t0,`$FRAME+64`($sp)
        +	std	$t1,`$FRAME+72`($sp)
        +	std	$t2,`$FRAME+80`($sp)
        +	std	$t3,`$FRAME+88`($sp)
        +	std	$t4,`$FRAME+96`($sp)
        +	std	$t5,`$FRAME+104`($sp)
        +	std	$t6,`$FRAME+112`($sp)
        +	std	$t7,`$FRAME+120`($sp)
        +	ld	$t0,`$FRAME+0`($sp)
        +	ld	$t1,`$FRAME+8`($sp)
        +	ld	$t2,`$FRAME+16`($sp)
        +	ld	$t3,`$FRAME+24`($sp)
        +	ld	$t4,`$FRAME+32`($sp)
        +	ld	$t5,`$FRAME+40`($sp)
        +	ld	$t6,`$FRAME+48`($sp)
        +	ld	$t7,`$FRAME+56`($sp)
        +	lfd	$A0,`$FRAME+64`($sp)
        +	lfd	$A1,`$FRAME+72`($sp)
        +	lfd	$A2,`$FRAME+80`($sp)
        +	lfd	$A3,`$FRAME+88`($sp)
        +	lfd	$N0,`$FRAME+96`($sp)
        +	lfd	$N1,`$FRAME+104`($sp)
        +	lfd	$N2,`$FRAME+112`($sp)
        +	lfd	$N3,`$FRAME+120`($sp)
        +	fcfid	$A0,$A0
        +	fcfid	$A1,$A1
        +	fcfid	$A2,$A2
        +	fcfid	$A3,$A3
        +	fcfid	$N0,$N0
        +	fcfid	$N1,$N1
        +	fcfid	$N2,$N2
        +	fcfid	$N3,$N3
        +	addi	$ap,$ap,16
        +	addi	$np,$np,16
        +
        +	fmul	$T1a,$A1,$ba
        +	fmul	$T1b,$A1,$bb
        +	fmul	$T2a,$A2,$ba
        +	fmul	$T2b,$A2,$bb
        +	stfd	$A0,8($nap_d)		; save a[j] in double format
        +	stfd	$A1,16($nap_d)
        +	fmul	$T3a,$A3,$ba
        +	fmul	$T3b,$A3,$bb
        +	fmadd	$T0a,$A0,$ba,$dota
        +	fmadd	$T0b,$A0,$bb,$dotb
        +	stfd	$A2,24($nap_d)		; save a[j+1] in double format
        +	stfd	$A3,32($nap_d)
        +
        +	fmadd	$T1a,$A0,$bc,$T1a
        +	fmadd	$T1b,$A0,$bd,$T1b
        +	fmadd	$T2a,$A1,$bc,$T2a
        +	fmadd	$T2b,$A1,$bd,$T2b
        +	stfd	$N0,40($nap_d)		; save n[j] in double format
        +	stfd	$N1,48($nap_d)
        +	fmadd	$T3a,$A2,$bc,$T3a
        +	fmadd	$T3b,$A2,$bd,$T3b
        +	 add	$t0,$t0,$carry		; can not overflow
        +	fmul	$dota,$A3,$bc
        +	fmul	$dotb,$A3,$bd
        +	stfd	$N2,56($nap_d)		; save n[j+1] in double format
        +	stfdu	$N3,64($nap_d)
        +	 srdi	$carry,$t0,16
        +	 add	$t1,$t1,$carry
        +	 srdi	$carry,$t1,16
        +
        +	fmadd	$T1a,$N1,$na,$T1a
        +	fmadd	$T1b,$N1,$nb,$T1b
        +	 insrdi	$t0,$t1,16,32
        +	fmadd	$T2a,$N2,$na,$T2a
        +	fmadd	$T2b,$N2,$nb,$T2b
        +	 add	$t2,$t2,$carry
        +	fmadd	$T3a,$N3,$na,$T3a
        +	fmadd	$T3b,$N3,$nb,$T3b
        +	 srdi	$carry,$t2,16
        +	fmadd	$T0a,$N0,$na,$T0a
        +	fmadd	$T0b,$N0,$nb,$T0b
        +	 insrdi	$t0,$t2,16,16
        +	 add	$t3,$t3,$carry
        +	 srdi	$carry,$t3,16
        +
        +	fmadd	$T1a,$N0,$nc,$T1a
        +	fmadd	$T1b,$N0,$nd,$T1b
        +	 insrdi	$t0,$t3,16,0		; 0..63 bits
        +	fmadd	$T2a,$N1,$nc,$T2a
        +	fmadd	$T2b,$N1,$nd,$T2b
        +	 add	$t4,$t4,$carry
        +	fmadd	$T3a,$N2,$nc,$T3a
        +	fmadd	$T3b,$N2,$nd,$T3b
        +	 srdi	$carry,$t4,16
        +	fmadd	$dota,$N3,$nc,$dota
        +	fmadd	$dotb,$N3,$nd,$dotb
        +	 add	$t5,$t5,$carry
        +	 srdi	$carry,$t5,16
        +	 insrdi	$t4,$t5,16,32
        +
        +	fctid	$T0a,$T0a
        +	fctid	$T0b,$T0b
        +	 add	$t6,$t6,$carry
        +	fctid	$T1a,$T1a
        +	fctid	$T1b,$T1b
        +	 srdi	$carry,$t6,16
        +	fctid	$T2a,$T2a
        +	fctid	$T2b,$T2b
        +	 insrdi	$t4,$t6,16,16
        +	fctid	$T3a,$T3a
        +	fctid	$T3b,$T3b
        +	 add	$t7,$t7,$carry
        +	 insrdi	$t4,$t7,16,0		; 64..127 bits
        +	 srdi	$carry,$t7,16		; upper 33 bits
        +
        +	stfd	$T0a,`$FRAME+0`($sp)
        +	stfd	$T0b,`$FRAME+8`($sp)
        +	stfd	$T1a,`$FRAME+16`($sp)
        +	stfd	$T1b,`$FRAME+24`($sp)
        +	stfd	$T2a,`$FRAME+32`($sp)
        +	stfd	$T2b,`$FRAME+40`($sp)
        +	stfd	$T3a,`$FRAME+48`($sp)
        +	stfd	$T3b,`$FRAME+56`($sp)
        +	 std	$t0,8($tp)		; tp[j-1]
        +	 stdu	$t4,16($tp)		; tp[j]
        +	bdnz-	L1st
        +
        +	fctid	$dota,$dota
        +	fctid	$dotb,$dotb
        +
        +	ld	$t0,`$FRAME+0`($sp)
        +	ld	$t1,`$FRAME+8`($sp)
        +	ld	$t2,`$FRAME+16`($sp)
        +	ld	$t3,`$FRAME+24`($sp)
        +	ld	$t4,`$FRAME+32`($sp)
        +	ld	$t5,`$FRAME+40`($sp)
        +	ld	$t6,`$FRAME+48`($sp)
        +	ld	$t7,`$FRAME+56`($sp)
        +	stfd	$dota,`$FRAME+64`($sp)
        +	stfd	$dotb,`$FRAME+72`($sp)
        +
        +	add	$t0,$t0,$carry		; can not overflow
        +	srdi	$carry,$t0,16
        +	add	$t1,$t1,$carry
        +	srdi	$carry,$t1,16
        +	insrdi	$t0,$t1,16,32
        +	add	$t2,$t2,$carry
        +	srdi	$carry,$t2,16
        +	insrdi	$t0,$t2,16,16
        +	add	$t3,$t3,$carry
        +	srdi	$carry,$t3,16
        +	insrdi	$t0,$t3,16,0		; 0..63 bits
        +	add	$t4,$t4,$carry
        +	srdi	$carry,$t4,16
        +	add	$t5,$t5,$carry
        +	srdi	$carry,$t5,16
        +	insrdi	$t4,$t5,16,32
        +	add	$t6,$t6,$carry
        +	srdi	$carry,$t6,16
        +	insrdi	$t4,$t6,16,16
        +	add	$t7,$t7,$carry
        +	insrdi	$t4,$t7,16,0		; 64..127 bits
        +	srdi	$carry,$t7,16		; upper 33 bits
        +	ld	$t6,`$FRAME+64`($sp)
        +	ld	$t7,`$FRAME+72`($sp)
        +
        +	std	$t0,8($tp)		; tp[j-1]
        +	stdu	$t4,16($tp)		; tp[j]
        +
        +	add	$t6,$t6,$carry		; can not overflow
        +	srdi	$carry,$t6,16
        +	add	$t7,$t7,$carry
        +	insrdi	$t6,$t7,48,0
        +	srdi	$ovf,$t7,48
        +	std	$t6,8($tp)		; tp[num-1]
        +
        +	slwi	$t7,$num,2
        +	subf	$nap_d,$t7,$nap_d	; rewind pointer
        +
        +	li	$i,8			; i=1
        +.align	5
        +Louter:
        +___
        +$code.=<<___ if ($SIZE_T==8);
        +	ldx	$t3,$bp,$i	; bp[i]
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	add	$t0,$bp,$i
        +	lwz	$t3,0($t0)		; bp[i,i+1]
        +	lwz	$t0,4($t0)
        +	insrdi	$t3,$t0,32,0
        +___
        +$code.=<<___;
        +	ld	$t6,`$FRAME+$TRANSFER+8`($sp)	; tp[0]
        +	mulld	$t7,$a0,$t3	; ap[0]*bp[i]
        +
        +	addi	$tp,$sp,`$FRAME+$TRANSFER`
        +	add	$t7,$t7,$t6	; ap[0]*bp[i]+tp[0]
        +	li	$carry,0
        +	mulld	$t7,$t7,$n0	; tp[0]*n0
        +	mtctr	$j
        +
        +	; transfer bp[i] to FPU as 4x16-bit values
        +	extrdi	$t0,$t3,16,48
        +	extrdi	$t1,$t3,16,32
        +	extrdi	$t2,$t3,16,16
        +	extrdi	$t3,$t3,16,0
        +	std	$t0,`$FRAME+0`($sp)
        +	std	$t1,`$FRAME+8`($sp)
        +	std	$t2,`$FRAME+16`($sp)
        +	std	$t3,`$FRAME+24`($sp)
        +	; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
        +	extrdi	$t4,$t7,16,48
        +	extrdi	$t5,$t7,16,32
        +	extrdi	$t6,$t7,16,16
        +	extrdi	$t7,$t7,16,0
        +	std	$t4,`$FRAME+32`($sp)
        +	std	$t5,`$FRAME+40`($sp)
        +	std	$t6,`$FRAME+48`($sp)
        +	std	$t7,`$FRAME+56`($sp)
        +
        +	lfd	$A0,8($nap_d)		; load a[j] in double format
        +	lfd	$A1,16($nap_d)
        +	lfd	$A2,24($nap_d)		; load a[j+1] in double format
        +	lfd	$A3,32($nap_d)
        +	lfd	$N0,40($nap_d)		; load n[j] in double format
        +	lfd	$N1,48($nap_d)
        +	lfd	$N2,56($nap_d)		; load n[j+1] in double format
        +	lfdu	$N3,64($nap_d)
        +
        +	lfd	$ba,`$FRAME+0`($sp)
        +	lfd	$bb,`$FRAME+8`($sp)
        +	lfd	$bc,`$FRAME+16`($sp)
        +	lfd	$bd,`$FRAME+24`($sp)
        +	lfd	$na,`$FRAME+32`($sp)
        +	lfd	$nb,`$FRAME+40`($sp)
        +	lfd	$nc,`$FRAME+48`($sp)
        +	lfd	$nd,`$FRAME+56`($sp)
        +
        +	fcfid	$ba,$ba
        +	fcfid	$bb,$bb
        +	fcfid	$bc,$bc
        +	fcfid	$bd,$bd
        +	fcfid	$na,$na
        +	fcfid	$nb,$nb
        +	fcfid	$nc,$nc
        +	fcfid	$nd,$nd
        +
        +	fmul	$T1a,$A1,$ba
        +	fmul	$T1b,$A1,$bb
        +	fmul	$T2a,$A2,$ba
        +	fmul	$T2b,$A2,$bb
        +	fmul	$T3a,$A3,$ba
        +	fmul	$T3b,$A3,$bb
        +	fmul	$T0a,$A0,$ba
        +	fmul	$T0b,$A0,$bb
        +
        +	fmadd	$T1a,$A0,$bc,$T1a
        +	fmadd	$T1b,$A0,$bd,$T1b
        +	fmadd	$T2a,$A1,$bc,$T2a
        +	fmadd	$T2b,$A1,$bd,$T2b
        +	fmadd	$T3a,$A2,$bc,$T3a
        +	fmadd	$T3b,$A2,$bd,$T3b
        +	fmul	$dota,$A3,$bc
        +	fmul	$dotb,$A3,$bd
        +
        +	fmadd	$T1a,$N1,$na,$T1a
        +	fmadd	$T1b,$N1,$nb,$T1b
        +	 lfd	$A0,8($nap_d)		; load a[j] in double format
        +	 lfd	$A1,16($nap_d)
        +	fmadd	$T2a,$N2,$na,$T2a
        +	fmadd	$T2b,$N2,$nb,$T2b
        +	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
        +	 lfd	$A3,32($nap_d)
        +	fmadd	$T3a,$N3,$na,$T3a
        +	fmadd	$T3b,$N3,$nb,$T3b
        +	fmadd	$T0a,$N0,$na,$T0a
        +	fmadd	$T0b,$N0,$nb,$T0b
        +
        +	fmadd	$T1a,$N0,$nc,$T1a
        +	fmadd	$T1b,$N0,$nd,$T1b
        +	fmadd	$T2a,$N1,$nc,$T2a
        +	fmadd	$T2b,$N1,$nd,$T2b
        +	fmadd	$T3a,$N2,$nc,$T3a
        +	fmadd	$T3b,$N2,$nd,$T3b
        +	fmadd	$dota,$N3,$nc,$dota
        +	fmadd	$dotb,$N3,$nd,$dotb
        +
        +	fctid	$T0a,$T0a
        +	fctid	$T0b,$T0b
        +	fctid	$T1a,$T1a
        +	fctid	$T1b,$T1b
        +	fctid	$T2a,$T2a
        +	fctid	$T2b,$T2b
        +	fctid	$T3a,$T3a
        +	fctid	$T3b,$T3b
        +
        +	stfd	$T0a,`$FRAME+0`($sp)
        +	stfd	$T0b,`$FRAME+8`($sp)
        +	stfd	$T1a,`$FRAME+16`($sp)
        +	stfd	$T1b,`$FRAME+24`($sp)
        +	stfd	$T2a,`$FRAME+32`($sp)
        +	stfd	$T2b,`$FRAME+40`($sp)
        +	stfd	$T3a,`$FRAME+48`($sp)
        +	stfd	$T3b,`$FRAME+56`($sp)
        +
        +.align	5
        +Linner:
        +	fmul	$T1a,$A1,$ba
        +	fmul	$T1b,$A1,$bb
        +	fmul	$T2a,$A2,$ba
        +	fmul	$T2b,$A2,$bb
        +	lfd	$N0,40($nap_d)		; load n[j] in double format
        +	lfd	$N1,48($nap_d)
        +	fmul	$T3a,$A3,$ba
        +	fmul	$T3b,$A3,$bb
        +	fmadd	$T0a,$A0,$ba,$dota
        +	fmadd	$T0b,$A0,$bb,$dotb
        +	lfd	$N2,56($nap_d)		; load n[j+1] in double format
        +	lfdu	$N3,64($nap_d)
        +
        +	fmadd	$T1a,$A0,$bc,$T1a
        +	fmadd	$T1b,$A0,$bd,$T1b
        +	fmadd	$T2a,$A1,$bc,$T2a
        +	fmadd	$T2b,$A1,$bd,$T2b
        +	 lfd	$A0,8($nap_d)		; load a[j] in double format
        +	 lfd	$A1,16($nap_d)
        +	fmadd	$T3a,$A2,$bc,$T3a
        +	fmadd	$T3b,$A2,$bd,$T3b
        +	fmul	$dota,$A3,$bc
        +	fmul	$dotb,$A3,$bd
        +	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
        +	 lfd	$A3,32($nap_d)
        +
        +	fmadd	$T1a,$N1,$na,$T1a
        +	fmadd	$T1b,$N1,$nb,$T1b
        +	 ld	$t0,`$FRAME+0`($sp)
        +	 ld	$t1,`$FRAME+8`($sp)
        +	fmadd	$T2a,$N2,$na,$T2a
        +	fmadd	$T2b,$N2,$nb,$T2b
        +	 ld	$t2,`$FRAME+16`($sp)
        +	 ld	$t3,`$FRAME+24`($sp)
        +	fmadd	$T3a,$N3,$na,$T3a
        +	fmadd	$T3b,$N3,$nb,$T3b
        +	 add	$t0,$t0,$carry		; can not overflow
        +	 ld	$t4,`$FRAME+32`($sp)
        +	 ld	$t5,`$FRAME+40`($sp)
        +	fmadd	$T0a,$N0,$na,$T0a
        +	fmadd	$T0b,$N0,$nb,$T0b
        +	 srdi	$carry,$t0,16
        +	 add	$t1,$t1,$carry
        +	 srdi	$carry,$t1,16
        +	 ld	$t6,`$FRAME+48`($sp)
        +	 ld	$t7,`$FRAME+56`($sp)
        +
        +	fmadd	$T1a,$N0,$nc,$T1a
        +	fmadd	$T1b,$N0,$nd,$T1b
        +	 insrdi	$t0,$t1,16,32
        +	 ld	$t1,8($tp)		; tp[j]
        +	fmadd	$T2a,$N1,$nc,$T2a
        +	fmadd	$T2b,$N1,$nd,$T2b
        +	 add	$t2,$t2,$carry
        +	fmadd	$T3a,$N2,$nc,$T3a
        +	fmadd	$T3b,$N2,$nd,$T3b
        +	 srdi	$carry,$t2,16
        +	 insrdi	$t0,$t2,16,16
        +	fmadd	$dota,$N3,$nc,$dota
        +	fmadd	$dotb,$N3,$nd,$dotb
        +	 add	$t3,$t3,$carry
        +	 ldu	$t2,16($tp)		; tp[j+1]
        +	 srdi	$carry,$t3,16
        +	 insrdi	$t0,$t3,16,0		; 0..63 bits
        +	 add	$t4,$t4,$carry
        +
        +	fctid	$T0a,$T0a
        +	fctid	$T0b,$T0b
        +	 srdi	$carry,$t4,16
        +	fctid	$T1a,$T1a
        +	fctid	$T1b,$T1b
        +	 add	$t5,$t5,$carry
        +	fctid	$T2a,$T2a
        +	fctid	$T2b,$T2b
        +	 srdi	$carry,$t5,16
        +	 insrdi	$t4,$t5,16,32
        +	fctid	$T3a,$T3a
        +	fctid	$T3b,$T3b
        +	 add	$t6,$t6,$carry
        +	 srdi	$carry,$t6,16
        +	 insrdi	$t4,$t6,16,16
        +
        +	stfd	$T0a,`$FRAME+0`($sp)
        +	stfd	$T0b,`$FRAME+8`($sp)
        +	 add	$t7,$t7,$carry
        +	 addc	$t3,$t0,$t1
        +___
        +$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
        +	extrdi	$t0,$t0,32,0
        +	extrdi	$t1,$t1,32,0
        +	adde	$t0,$t0,$t1
        +___
        +$code.=<<___;
        +	stfd	$T1a,`$FRAME+16`($sp)
        +	stfd	$T1b,`$FRAME+24`($sp)
        +	 insrdi	$t4,$t7,16,0		; 64..127 bits
        +	 srdi	$carry,$t7,16		; upper 33 bits
        +	stfd	$T2a,`$FRAME+32`($sp)
        +	stfd	$T2b,`$FRAME+40`($sp)
        +	 adde	$t5,$t4,$t2
        +___
        +$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
        +	extrdi	$t4,$t4,32,0
        +	extrdi	$t2,$t2,32,0
        +	adde	$t4,$t4,$t2
        +___
        +$code.=<<___;
        +	stfd	$T3a,`$FRAME+48`($sp)
        +	stfd	$T3b,`$FRAME+56`($sp)
        +	 addze	$carry,$carry
        +	 std	$t3,-16($tp)		; tp[j-1]
        +	 std	$t5,-8($tp)		; tp[j]
        +	bdnz-	Linner
        +
        +	fctid	$dota,$dota
        +	fctid	$dotb,$dotb
        +	ld	$t0,`$FRAME+0`($sp)
        +	ld	$t1,`$FRAME+8`($sp)
        +	ld	$t2,`$FRAME+16`($sp)
        +	ld	$t3,`$FRAME+24`($sp)
        +	ld	$t4,`$FRAME+32`($sp)
        +	ld	$t5,`$FRAME+40`($sp)
        +	ld	$t6,`$FRAME+48`($sp)
        +	ld	$t7,`$FRAME+56`($sp)
        +	stfd	$dota,`$FRAME+64`($sp)
        +	stfd	$dotb,`$FRAME+72`($sp)
        +
        +	add	$t0,$t0,$carry		; can not overflow
        +	srdi	$carry,$t0,16
        +	add	$t1,$t1,$carry
        +	srdi	$carry,$t1,16
        +	insrdi	$t0,$t1,16,32
        +	add	$t2,$t2,$carry
        +	ld	$t1,8($tp)		; tp[j]
        +	srdi	$carry,$t2,16
        +	insrdi	$t0,$t2,16,16
        +	add	$t3,$t3,$carry
        +	ldu	$t2,16($tp)		; tp[j+1]
        +	srdi	$carry,$t3,16
        +	insrdi	$t0,$t3,16,0		; 0..63 bits
        +	add	$t4,$t4,$carry
        +	srdi	$carry,$t4,16
        +	add	$t5,$t5,$carry
        +	srdi	$carry,$t5,16
        +	insrdi	$t4,$t5,16,32
        +	add	$t6,$t6,$carry
        +	srdi	$carry,$t6,16
        +	insrdi	$t4,$t6,16,16
        +	add	$t7,$t7,$carry
        +	insrdi	$t4,$t7,16,0		; 64..127 bits
        +	srdi	$carry,$t7,16		; upper 33 bits
        +	ld	$t6,`$FRAME+64`($sp)
        +	ld	$t7,`$FRAME+72`($sp)
        +
        +	addc	$t3,$t0,$t1
        +___
        +$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
        +	extrdi	$t0,$t0,32,0
        +	extrdi	$t1,$t1,32,0
        +	adde	$t0,$t0,$t1
        +___
        +$code.=<<___;
        +	adde	$t5,$t4,$t2
        +___
        +$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
        +	extrdi	$t4,$t4,32,0
        +	extrdi	$t2,$t2,32,0
        +	adde	$t4,$t4,$t2
        +___
        +$code.=<<___;
        +	addze	$carry,$carry
        +
        +	std	$t3,-16($tp)		; tp[j-1]
        +	std	$t5,-8($tp)		; tp[j]
        +
        +	add	$carry,$carry,$ovf	; comsume upmost overflow
        +	add	$t6,$t6,$carry		; can not overflow
        +	srdi	$carry,$t6,16
        +	add	$t7,$t7,$carry
        +	insrdi	$t6,$t7,48,0
        +	srdi	$ovf,$t7,48
        +	std	$t6,0($tp)		; tp[num-1]
        +
        +	slwi	$t7,$num,2
        +	addi	$i,$i,8
        +	subf	$nap_d,$t7,$nap_d	; rewind pointer
        +	cmpw	$i,$num
        +	blt-	Louter
        +___
        +
        +$code.=<<___ if ($SIZE_T==8);
        +	subf	$np,$num,$np	; rewind np
        +	addi	$j,$j,1		; restore counter
        +	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
        +	addi	$tp,$sp,`$FRAME+$TRANSFER+8`
        +	addi	$t4,$sp,`$FRAME+$TRANSFER+16`
        +	addi	$t5,$np,8
        +	addi	$t6,$rp,8
        +	mtctr	$j
        +
        +.align	4
        +Lsub:	ldx	$t0,$tp,$i
        +	ldx	$t1,$np,$i
        +	ldx	$t2,$t4,$i
        +	ldx	$t3,$t5,$i
        +	subfe	$t0,$t1,$t0	; tp[j]-np[j]
        +	subfe	$t2,$t3,$t2	; tp[j+1]-np[j+1]
        +	stdx	$t0,$rp,$i
        +	stdx	$t2,$t6,$i
        +	addi	$i,$i,16
        +	bdnz-	Lsub
        +
        +	li	$i,0
        +	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
        +	and	$ap,$tp,$ovf
        +	andc	$np,$rp,$ovf
        +	or	$ap,$ap,$np	; ap=borrow?tp:rp
        +	addi	$t7,$ap,8
        +	mtctr	$j
        +
        +.align	4
        +Lcopy:				; copy or in-place refresh
        +	ldx	$t0,$ap,$i
        +	ldx	$t1,$t7,$i
        +	std	$i,8($nap_d)	; zap nap_d
        +	std	$i,16($nap_d)
        +	std	$i,24($nap_d)
        +	std	$i,32($nap_d)
        +	std	$i,40($nap_d)
        +	std	$i,48($nap_d)
        +	std	$i,56($nap_d)
        +	stdu	$i,64($nap_d)
        +	stdx	$t0,$rp,$i
        +	stdx	$t1,$t6,$i
        +	stdx	$i,$tp,$i	; zap tp at once
        +	stdx	$i,$t4,$i
        +	addi	$i,$i,16
        +	bdnz-	Lcopy
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	subf	$np,$num,$np	; rewind np
        +	addi	$j,$j,1		; restore counter
        +	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
        +	addi	$tp,$sp,`$FRAME+$TRANSFER`
        +	addi	$np,$np,-4
        +	addi	$rp,$rp,-4
        +	addi	$ap,$sp,`$FRAME+$TRANSFER+4`
        +	mtctr	$j
        +
        +.align	4
        +Lsub:	ld	$t0,8($tp)	; load tp[j..j+3] in 64-bit word order
        +	ldu	$t2,16($tp)
        +	lwz	$t4,4($np)	; load np[j..j+3] in 32-bit word order
        +	lwz	$t5,8($np)
        +	lwz	$t6,12($np)
        +	lwzu	$t7,16($np)
        +	extrdi	$t1,$t0,32,0
        +	extrdi	$t3,$t2,32,0
        +	subfe	$t4,$t4,$t0	; tp[j]-np[j]
        +	 stw	$t0,4($ap)	; save tp[j..j+3] in 32-bit word order
        +	subfe	$t5,$t5,$t1	; tp[j+1]-np[j+1]
        +	 stw	$t1,8($ap)
        +	subfe	$t6,$t6,$t2	; tp[j+2]-np[j+2]
        +	 stw	$t2,12($ap)
        +	subfe	$t7,$t7,$t3	; tp[j+3]-np[j+3]
        +	 stwu	$t3,16($ap)
        +	stw	$t4,4($rp)
        +	stw	$t5,8($rp)
        +	stw	$t6,12($rp)
        +	stwu	$t7,16($rp)
        +	bdnz-	Lsub
        +
        +	li	$i,0
        +	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
        +	addi	$tp,$sp,`$FRAME+$TRANSFER+4`
        +	subf	$rp,$num,$rp	; rewind rp
        +	and	$ap,$tp,$ovf
        +	andc	$np,$rp,$ovf
        +	or	$ap,$ap,$np	; ap=borrow?tp:rp
        +	addi	$tp,$sp,`$FRAME+$TRANSFER`
        +	mtctr	$j
        +
        +.align	4
        +Lcopy:				; copy or in-place refresh
        +	lwz	$t0,4($ap)
        +	lwz	$t1,8($ap)
        +	lwz	$t2,12($ap)
        +	lwzu	$t3,16($ap)
        +	std	$i,8($nap_d)	; zap nap_d
        +	std	$i,16($nap_d)
        +	std	$i,24($nap_d)
        +	std	$i,32($nap_d)
        +	std	$i,40($nap_d)
        +	std	$i,48($nap_d)
        +	std	$i,56($nap_d)
        +	stdu	$i,64($nap_d)
        +	stw	$t0,4($rp)
        +	stw	$t1,8($rp)
        +	stw	$t2,12($rp)
        +	stwu	$t3,16($rp)
        +	std	$i,8($tp)	; zap tp at once
        +	stdu	$i,16($tp)
        +	bdnz-	Lcopy
        +___
        +
        +$code.=<<___;
        +	$POP	$i,0($sp)
        +	li	r3,1	; signal "handled"
        +	$POP	r22,`-12*8-10*$SIZE_T`($i)
        +	$POP	r23,`-12*8-9*$SIZE_T`($i)
        +	$POP	r24,`-12*8-8*$SIZE_T`($i)
        +	$POP	r25,`-12*8-7*$SIZE_T`($i)
        +	$POP	r26,`-12*8-6*$SIZE_T`($i)
        +	$POP	r27,`-12*8-5*$SIZE_T`($i)
        +	$POP	r28,`-12*8-4*$SIZE_T`($i)
        +	$POP	r29,`-12*8-3*$SIZE_T`($i)
        +	$POP	r30,`-12*8-2*$SIZE_T`($i)
        +	$POP	r31,`-12*8-1*$SIZE_T`($i)
        +	lfd	f20,`-12*8`($i)
        +	lfd	f21,`-11*8`($i)
        +	lfd	f22,`-10*8`($i)
        +	lfd	f23,`-9*8`($i)
        +	lfd	f24,`-8*8`($i)
        +	lfd	f25,`-7*8`($i)
        +	lfd	f26,`-6*8`($i)
        +	lfd	f27,`-5*8`($i)
        +	lfd	f28,`-4*8`($i)
        +	lfd	f29,`-3*8`($i)
        +	lfd	f30,`-2*8`($i)
        +	lfd	f31,`-1*8`($i)
        +	mr	$sp,$i
        +	blr
        +	.long	0
        +	.byte	0,12,4,0,0x8c,10,6,0
        +	.long	0
        +
        +.asciz  "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl b/vendor/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl
        new file mode 100644
        index 000000000..cd9f13eca
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/s390x-gf2m.pl
        @@ -0,0 +1,221 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# May 2011
        +#
        +# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
        +# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
        +# the time being... gcc 4.3 appeared to generate poor code, therefore
        +# the effort. And indeed, the module delivers 55%-90%(*) improvement
        +# on haviest ECDSA verify and ECDH benchmarks for 163- and 571-bit
        +# key lengths on z990, 30%-55%(*) - on z10, and 70%-110%(*) - on z196.
        +# This is for 64-bit build. In 32-bit "highgprs" case improvement is
        +# even higher, for example on z990 it was measured 80%-150%. ECDSA
        +# sign is modest 9%-12% faster. Keep in mind that these coefficients
        +# are not ones for bn_GF2m_mul_2x2 itself, as not all CPU time is
        +# burnt in it...
        +#
        +# (*)	gcc 4.1 was observed to deliver better results than gcc 4.3,
        +#	so that improvement coefficients can vary from one specific
        +#	setup to another.
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +        $SIZE_T=4;
        +        $g="";
        +} else {
        +        $SIZE_T=8;
        +        $g="g";
        +}
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$stdframe=16*$SIZE_T+4*8;
        +
        +$rp="%r2";
        +$a1="%r3";
        +$a0="%r4";
        +$b1="%r5";
        +$b0="%r6";
        +
        +$ra="%r14";
        +$sp="%r15";
        +
        +@T=("%r0","%r1");
        +@i=("%r12","%r13");
        +
        +($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(6..11));
        +($lo,$hi,$b)=map("%r$_",(3..5)); $a=$lo; $mask=$a8;
        +
        +$code.=<<___;
        +.text
        +
        +.type	_mul_1x1,\@function
        +.align	16
        +_mul_1x1:
        +	lgr	$a1,$a
        +	sllg	$a2,$a,1
        +	sllg	$a4,$a,2
        +	sllg	$a8,$a,3
        +
        +	srag	$lo,$a1,63			# broadcast 63rd bit
        +	nihh	$a1,0x1fff
        +	srag	@i[0],$a2,63			# broadcast 62nd bit
        +	nihh	$a2,0x3fff
        +	srag	@i[1],$a4,63			# broadcast 61st bit
        +	nihh	$a4,0x7fff
        +	ngr	$lo,$b
        +	ngr	@i[0],$b
        +	ngr	@i[1],$b
        +
        +	lghi	@T[0],0
        +	lgr	$a12,$a1
        +	stg	@T[0],`$stdframe+0*8`($sp)	# tab[0]=0
        +	xgr	$a12,$a2
        +	stg	$a1,`$stdframe+1*8`($sp)	# tab[1]=a1
        +	 lgr	$a48,$a4
        +	stg	$a2,`$stdframe+2*8`($sp)	# tab[2]=a2
        +	 xgr	$a48,$a8
        +	stg	$a12,`$stdframe+3*8`($sp)	# tab[3]=a1^a2
        +	 xgr	$a1,$a4
        +
        +	stg	$a4,`$stdframe+4*8`($sp)	# tab[4]=a4
        +	xgr	$a2,$a4
        +	stg	$a1,`$stdframe+5*8`($sp)	# tab[5]=a1^a4
        +	xgr	$a12,$a4
        +	stg	$a2,`$stdframe+6*8`($sp)	# tab[6]=a2^a4
        +	 xgr	$a1,$a48
        +	stg	$a12,`$stdframe+7*8`($sp)	# tab[7]=a1^a2^a4
        +	 xgr	$a2,$a48
        +
        +	stg	$a8,`$stdframe+8*8`($sp)	# tab[8]=a8
        +	xgr	$a12,$a48
        +	stg	$a1,`$stdframe+9*8`($sp)	# tab[9]=a1^a8
        +	 xgr	$a1,$a4
        +	stg	$a2,`$stdframe+10*8`($sp)	# tab[10]=a2^a8
        +	 xgr	$a2,$a4
        +	stg	$a12,`$stdframe+11*8`($sp)	# tab[11]=a1^a2^a8
        +
        +	xgr	$a12,$a4
        +	stg	$a48,`$stdframe+12*8`($sp)	# tab[12]=a4^a8
        +	 srlg	$hi,$lo,1
        +	stg	$a1,`$stdframe+13*8`($sp)	# tab[13]=a1^a4^a8
        +	 sllg	$lo,$lo,63
        +	stg	$a2,`$stdframe+14*8`($sp)	# tab[14]=a2^a4^a8
        +	 srlg	@T[0],@i[0],2
        +	stg	$a12,`$stdframe+15*8`($sp)	# tab[15]=a1^a2^a4^a8
        +
        +	lghi	$mask,`0xf<<3`
        +	sllg	$a1,@i[0],62
        +	 sllg	@i[0],$b,3
        +	srlg	@T[1],@i[1],3
        +	 ngr	@i[0],$mask
        +	sllg	$a2,@i[1],61
        +	 srlg	@i[1],$b,4-3
        +	xgr	$hi,@T[0]
        +	 ngr	@i[1],$mask
        +	xgr	$lo,$a1
        +	xgr	$hi,@T[1]
        +	xgr	$lo,$a2
        +
        +	xg	$lo,$stdframe(@i[0],$sp)
        +	srlg	@i[0],$b,8-3
        +	ngr	@i[0],$mask
        +___
        +for($n=1;$n<14;$n++) {
        +$code.=<<___;
        +	lg	@T[1],$stdframe(@i[1],$sp)
        +	srlg	@i[1],$b,`($n+2)*4`-3
        +	sllg	@T[0],@T[1],`$n*4`
        +	ngr	@i[1],$mask
        +	srlg	@T[1],@T[1],`64-$n*4`
        +	xgr	$lo,@T[0]
        +	xgr	$hi,@T[1]
        +___
        +	push(@i,shift(@i)); push(@T,shift(@T));
        +}
        +$code.=<<___;
        +	lg	@T[1],$stdframe(@i[1],$sp)
        +	sllg	@T[0],@T[1],`$n*4`
        +	srlg	@T[1],@T[1],`64-$n*4`
        +	xgr	$lo,@T[0]
        +	xgr	$hi,@T[1]
        +
        +	lg	@T[0],$stdframe(@i[0],$sp)
        +	sllg	@T[1],@T[0],`($n+1)*4`
        +	srlg	@T[0],@T[0],`64-($n+1)*4`
        +	xgr	$lo,@T[1]
        +	xgr	$hi,@T[0]
        +
        +	br	$ra
        +.size	_mul_1x1,.-_mul_1x1
        +
        +.globl	bn_GF2m_mul_2x2
        +.type	bn_GF2m_mul_2x2,\@function
        +.align	16
        +bn_GF2m_mul_2x2:
        +	stm${g}	%r3,%r15,3*$SIZE_T($sp)
        +
        +	lghi	%r1,-$stdframe-128
        +	la	%r0,0($sp)
        +	la	$sp,0(%r1,$sp)			# alloca
        +	st${g}	%r0,0($sp)			# back chain
        +___
        +if ($SIZE_T==8) {
        +my @r=map("%r$_",(6..9));
        +$code.=<<___;
        +	bras	$ra,_mul_1x1			# a1·b1
        +	stmg	$lo,$hi,16($rp)
        +
        +	lg	$a,`$stdframe+128+4*$SIZE_T`($sp)
        +	lg	$b,`$stdframe+128+6*$SIZE_T`($sp)
        +	bras	$ra,_mul_1x1			# a0·b0
        +	stmg	$lo,$hi,0($rp)
        +
        +	lg	$a,`$stdframe+128+3*$SIZE_T`($sp)
        +	lg	$b,`$stdframe+128+5*$SIZE_T`($sp)
        +	xg	$a,`$stdframe+128+4*$SIZE_T`($sp)
        +	xg	$b,`$stdframe+128+6*$SIZE_T`($sp)
        +	bras	$ra,_mul_1x1			# (a0+a1)·(b0+b1)
        +	lmg	@r[0],@r[3],0($rp)
        +
        +	xgr	$lo,$hi
        +	xgr	$hi,@r[1]
        +	xgr	$lo,@r[0]
        +	xgr	$hi,@r[2]
        +	xgr	$lo,@r[3]	
        +	xgr	$hi,@r[3]
        +	xgr	$lo,$hi
        +	stg	$hi,16($rp)
        +	stg	$lo,8($rp)
        +___
        +} else {
        +$code.=<<___;
        +	sllg	%r3,%r3,32
        +	sllg	%r5,%r5,32
        +	or	%r3,%r4
        +	or	%r5,%r6
        +	bras	$ra,_mul_1x1
        +	rllg	$lo,$lo,32
        +	rllg	$hi,$hi,32
        +	stmg	$lo,$hi,0($rp)
        +___
        +}
        +$code.=<<___;
        +	lm${g}	%r6,%r15,`$stdframe+128+6*$SIZE_T`($sp)
        +	br	$ra
        +.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
        +.string	"GF(2^m) Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/s390x-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/s390x-mont.pl
        new file mode 100644
        index 000000000..9fd64e81e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/s390x-mont.pl
        @@ -0,0 +1,277 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# April 2007.
        +#
        +# Performance improvement over vanilla C code varies from 85% to 45%
        +# depending on key length and benchmark. Unfortunately in this context
        +# these are not very impressive results [for code that utilizes "wide"
        +# 64x64=128-bit multiplication, which is not commonly available to C
        +# programmers], at least hand-coded bn_asm.c replacement is known to
        +# provide 30-40% better results for longest keys. Well, on a second
        +# thought it's not very surprising, because z-CPUs are single-issue
        +# and _strictly_ in-order execution, while bn_mul_mont is more or less
        +# dependent on CPU ability to pipe-line instructions and have several
        +# of them "in-flight" at the same time. I mean while other methods,
        +# for example Karatsuba, aim to minimize amount of multiplications at
        +# the cost of other operations increase, bn_mul_mont aim to neatly
        +# "overlap" multiplications and the other operations [and on most
        +# platforms even minimize the amount of the other operations, in
        +# particular references to memory]. But it's possible to improve this
        +# module performance by implementing dedicated squaring code-path and
        +# possibly by unrolling loops...
        +
        +# January 2009.
        +#
        +# Reschedule to minimize/avoid Address Generation Interlock hazard,
        +# make inner loops counter-based.
        +
        +# November 2010.
        +#
        +# Adapt for -m31 build. If kernel supports what's called "highgprs"
        +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
        +# instructions and achieve "64-bit" performance even in 31-bit legacy
        +# application context. The feature is not specific to any particular
        +# processor, as long as it's "z-CPU". Latter implies that the code
        +# remains z/Architecture specific. Compatibility with 32-bit BN_ULONG
        +# is achieved by swapping words after 64-bit loads, follow _dswap-s.
        +# On z990 it was measured to perform 2.6-2.2 times better than
        +# compiler-generated code, less for longer keys...
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +	$SIZE_T=4;
        +	$g="";
        +} else {
        +	$SIZE_T=8;
        +	$g="g";
        +}
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$stdframe=16*$SIZE_T+4*8;
        +
        +$mn0="%r0";
        +$num="%r1";
        +
        +# int bn_mul_mont(
        +$rp="%r2";		# BN_ULONG *rp,
        +$ap="%r3";		# const BN_ULONG *ap,
        +$bp="%r4";		# const BN_ULONG *bp,
        +$np="%r5";		# const BN_ULONG *np,
        +$n0="%r6";		# const BN_ULONG *n0,
        +#$num="160(%r15)"	# int num);
        +
        +$bi="%r2";	# zaps rp
        +$j="%r7";
        +
        +$ahi="%r8";
        +$alo="%r9";
        +$nhi="%r10";
        +$nlo="%r11";
        +$AHI="%r12";
        +$NHI="%r13";
        +$count="%r14";
        +$sp="%r15";
        +
        +$code.=<<___;
        +.text
        +.globl	bn_mul_mont
        +.type	bn_mul_mont,\@function
        +bn_mul_mont:
        +	lgf	$num,`$stdframe+$SIZE_T-4`($sp)	# pull $num
        +	sla	$num,`log($SIZE_T)/log(2)`	# $num to enumerate bytes
        +	la	$bp,0($num,$bp)
        +
        +	st${g}	%r2,2*$SIZE_T($sp)
        +
        +	cghi	$num,16		#
        +	lghi	%r2,0		#
        +	blr	%r14		# if($num<16) return 0;
        +___
        +$code.=<<___ if ($flavour =~ /3[12]/);
        +	tmll	$num,4
        +	bnzr	%r14		# if ($num&1) return 0;
        +___
        +$code.=<<___ if ($flavour !~ /3[12]/);
        +	cghi	$num,96		#
        +	bhr	%r14		# if($num>96) return 0;
        +___
        +$code.=<<___;
        +	stm${g}	%r3,%r15,3*$SIZE_T($sp)
        +
        +	lghi	$rp,-$stdframe-8	# leave room for carry bit
        +	lcgr	$j,$num		# -$num
        +	lgr	%r0,$sp
        +	la	$rp,0($rp,$sp)
        +	la	$sp,0($j,$rp)	# alloca
        +	st${g}	%r0,0($sp)	# back chain
        +
        +	sra	$num,3		# restore $num
        +	la	$bp,0($j,$bp)	# restore $bp
        +	ahi	$num,-1		# adjust $num for inner loop
        +	lg	$n0,0($n0)	# pull n0
        +	_dswap	$n0
        +
        +	lg	$bi,0($bp)
        +	_dswap	$bi
        +	lg	$alo,0($ap)
        +	_dswap	$alo
        +	mlgr	$ahi,$bi	# ap[0]*bp[0]
        +	lgr	$AHI,$ahi
        +
        +	lgr	$mn0,$alo	# "tp[0]"*n0
        +	msgr	$mn0,$n0
        +
        +	lg	$nlo,0($np)	#
        +	_dswap	$nlo
        +	mlgr	$nhi,$mn0	# np[0]*m1
        +	algr	$nlo,$alo	# +="tp[0]"
        +	lghi	$NHI,0
        +	alcgr	$NHI,$nhi
        +
        +	la	$j,8(%r0)	# j=1
        +	lr	$count,$num
        +
        +.align	16
        +.L1st:
        +	lg	$alo,0($j,$ap)
        +	_dswap	$alo
        +	mlgr	$ahi,$bi	# ap[j]*bp[0]
        +	algr	$alo,$AHI
        +	lghi	$AHI,0
        +	alcgr	$AHI,$ahi
        +
        +	lg	$nlo,0($j,$np)
        +	_dswap	$nlo
        +	mlgr	$nhi,$mn0	# np[j]*m1
        +	algr	$nlo,$NHI
        +	lghi	$NHI,0
        +	alcgr	$nhi,$NHI	# +="tp[j]"
        +	algr	$nlo,$alo
        +	alcgr	$NHI,$nhi
        +
        +	stg	$nlo,$stdframe-8($j,$sp)	# tp[j-1]=
        +	la	$j,8($j)	# j++
        +	brct	$count,.L1st
        +
        +	algr	$NHI,$AHI
        +	lghi	$AHI,0
        +	alcgr	$AHI,$AHI	# upmost overflow bit
        +	stg	$NHI,$stdframe-8($j,$sp)
        +	stg	$AHI,$stdframe($j,$sp)
        +	la	$bp,8($bp)	# bp++
        +
        +.Louter:
        +	lg	$bi,0($bp)	# bp[i]
        +	_dswap	$bi
        +	lg	$alo,0($ap)
        +	_dswap	$alo
        +	mlgr	$ahi,$bi	# ap[0]*bp[i]
        +	alg	$alo,$stdframe($sp)	# +=tp[0]
        +	lghi	$AHI,0
        +	alcgr	$AHI,$ahi
        +
        +	lgr	$mn0,$alo
        +	msgr	$mn0,$n0	# tp[0]*n0
        +
        +	lg	$nlo,0($np)	# np[0]
        +	_dswap	$nlo
        +	mlgr	$nhi,$mn0	# np[0]*m1
        +	algr	$nlo,$alo	# +="tp[0]"
        +	lghi	$NHI,0
        +	alcgr	$NHI,$nhi
        +
        +	la	$j,8(%r0)	# j=1
        +	lr	$count,$num
        +
        +.align	16
        +.Linner:
        +	lg	$alo,0($j,$ap)
        +	_dswap	$alo
        +	mlgr	$ahi,$bi	# ap[j]*bp[i]
        +	algr	$alo,$AHI
        +	lghi	$AHI,0
        +	alcgr	$ahi,$AHI
        +	alg	$alo,$stdframe($j,$sp)# +=tp[j]
        +	alcgr	$AHI,$ahi
        +
        +	lg	$nlo,0($j,$np)
        +	_dswap	$nlo
        +	mlgr	$nhi,$mn0	# np[j]*m1
        +	algr	$nlo,$NHI
        +	lghi	$NHI,0
        +	alcgr	$nhi,$NHI
        +	algr	$nlo,$alo	# +="tp[j]"
        +	alcgr	$NHI,$nhi
        +
        +	stg	$nlo,$stdframe-8($j,$sp)	# tp[j-1]=
        +	la	$j,8($j)	# j++
        +	brct	$count,.Linner
        +
        +	algr	$NHI,$AHI
        +	lghi	$AHI,0
        +	alcgr	$AHI,$AHI
        +	alg	$NHI,$stdframe($j,$sp)# accumulate previous upmost overflow bit
        +	lghi	$ahi,0
        +	alcgr	$AHI,$ahi	# new upmost overflow bit
        +	stg	$NHI,$stdframe-8($j,$sp)
        +	stg	$AHI,$stdframe($j,$sp)
        +
        +	la	$bp,8($bp)	# bp++
        +	cl${g}	$bp,`$stdframe+8+4*$SIZE_T`($j,$sp)	# compare to &bp[num]
        +	jne	.Louter
        +
        +	l${g}	$rp,`$stdframe+8+2*$SIZE_T`($j,$sp)	# reincarnate rp
        +	la	$ap,$stdframe($sp)
        +	ahi	$num,1		# restore $num, incidentally clears "borrow"
        +
        +	la	$j,0(%r0)
        +	lr	$count,$num
        +.Lsub:	lg	$alo,0($j,$ap)
        +	lg	$nlo,0($j,$np)
        +	_dswap	$nlo
        +	slbgr	$alo,$nlo
        +	stg	$alo,0($j,$rp)
        +	la	$j,8($j)
        +	brct	$count,.Lsub
        +	lghi	$ahi,0
        +	slbgr	$AHI,$ahi	# handle upmost carry
        +
        +	ngr	$ap,$AHI
        +	lghi	$np,-1
        +	xgr	$np,$AHI
        +	ngr	$np,$rp
        +	ogr	$ap,$np		# ap=borrow?tp:rp
        +
        +	la	$j,0(%r0)
        +	lgr	$count,$num
        +.Lcopy:	lg	$alo,0($j,$ap)		# copy or in-place refresh
        +	_dswap	$alo
        +	stg	$j,$stdframe($j,$sp)	# zap tp
        +	stg	$alo,0($j,$rp)
        +	la	$j,8($j)
        +	brct	$count,.Lcopy
        +
        +	la	%r1,`$stdframe+8+6*$SIZE_T`($j,$sp)
        +	lm${g}	%r6,%r15,0(%r1)
        +	lghi	%r2,1		# signal "processed"
        +	br	%r14
        +.size	bn_mul_mont,.-bn_mul_mont
        +.string	"Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +foreach (split("\n",$code)) {
        +	s/\`([^\`]*)\`/eval $1/ge;
        +	s/_dswap\s+(%r[0-9]+)/sprintf("rllg\t%s,%s,32",$1,$1) if($SIZE_T==4)/e;
        +	print $_,"\n";
        +}
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/s390x.S b/vendor/openssl/openssl/crypto/bn/asm/s390x.S
        new file mode 100644
        index 000000000..43fcb79bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/s390x.S
        @@ -0,0 +1,678 @@
        +.ident "s390x.S, version 1.1"
        +// ====================================================================
        +// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +// project.
        +//
        +// Rights for redistribution and usage in source and binary forms are
        +// granted according to the OpenSSL license. Warranty of any kind is
        +// disclaimed.
        +// ====================================================================
        +
        +.text
        +
        +#define zero	%r0
        +
        +// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
        +.globl	bn_mul_add_words
        +.type	bn_mul_add_words,@function
        +.align	4
        +bn_mul_add_words:
        +	lghi	zero,0		// zero = 0
        +	la	%r1,0(%r2)	// put rp aside
        +	lghi	%r2,0		// i=0;
        +	ltgfr	%r4,%r4
        +	bler	%r14		// if (len<=0) return 0;
        +
        +	stmg	%r6,%r10,48(%r15)
        +	lghi	%r10,3
        +	lghi	%r8,0		// carry = 0
        +	nr	%r10,%r4	// len%4
        +	sra	%r4,2		// cnt=len/4
        +	jz	.Loop1_madd	// carry is incidentally cleared if branch taken
        +	algr	zero,zero	// clear carry
        +
        +.Loop4_madd:
        +	lg	%r7,0(%r2,%r3)	// ap[i]
        +	mlgr	%r6,%r5		// *=w
        +	alcgr	%r7,%r8		// +=carry
        +	alcgr	%r6,zero
        +	alg	%r7,0(%r2,%r1)	// +=rp[i]
        +	stg	%r7,0(%r2,%r1)	// rp[i]=
        +
        +	lg	%r9,8(%r2,%r3)
        +	mlgr	%r8,%r5
        +	alcgr	%r9,%r6
        +	alcgr	%r8,zero
        +	alg	%r9,8(%r2,%r1)
        +	stg	%r9,8(%r2,%r1)
        +
        +	lg	%r7,16(%r2,%r3)
        +	mlgr	%r6,%r5
        +	alcgr	%r7,%r8
        +	alcgr	%r6,zero
        +	alg	%r7,16(%r2,%r1)
        +	stg	%r7,16(%r2,%r1)
        +
        +	lg	%r9,24(%r2,%r3)
        +	mlgr	%r8,%r5
        +	alcgr	%r9,%r6
        +	alcgr	%r8,zero
        +	alg	%r9,24(%r2,%r1)
        +	stg	%r9,24(%r2,%r1)
        +
        +	la	%r2,32(%r2)	// i+=4
        +	brct	%r4,.Loop4_madd
        +
        +	la	%r10,1(%r10)		// see if len%4 is zero ...
        +	brct	%r10,.Loop1_madd	// without touching condition code:-)
        +
        +.Lend_madd:
        +	alcgr	%r8,zero	// collect carry bit
        +	lgr	%r2,%r8
        +	lmg	%r6,%r10,48(%r15)
        +	br	%r14
        +
        +.Loop1_madd:
        +	lg	%r7,0(%r2,%r3)	// ap[i]
        +	mlgr	%r6,%r5		// *=w
        +	alcgr	%r7,%r8		// +=carry
        +	alcgr	%r6,zero
        +	alg	%r7,0(%r2,%r1)	// +=rp[i]
        +	stg	%r7,0(%r2,%r1)	// rp[i]=
        +
        +	lgr	%r8,%r6
        +	la	%r2,8(%r2)	// i++
        +	brct	%r10,.Loop1_madd
        +
        +	j	.Lend_madd
        +.size	bn_mul_add_words,.-bn_mul_add_words
        +
        +// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
        +.globl	bn_mul_words
        +.type	bn_mul_words,@function
        +.align	4
        +bn_mul_words:
        +	lghi	zero,0		// zero = 0
        +	la	%r1,0(%r2)	// put rp aside
        +	lghi	%r2,0		// i=0;
        +	ltgfr	%r4,%r4
        +	bler	%r14		// if (len<=0) return 0;
        +
        +	stmg	%r6,%r10,48(%r15)
        +	lghi	%r10,3
        +	lghi	%r8,0		// carry = 0
        +	nr	%r10,%r4	// len%4
        +	sra	%r4,2		// cnt=len/4
        +	jz	.Loop1_mul	// carry is incidentally cleared if branch taken
        +	algr	zero,zero	// clear carry
        +
        +.Loop4_mul:
        +	lg	%r7,0(%r2,%r3)	// ap[i]
        +	mlgr	%r6,%r5		// *=w
        +	alcgr	%r7,%r8		// +=carry
        +	stg	%r7,0(%r2,%r1)	// rp[i]=
        +
        +	lg	%r9,8(%r2,%r3)
        +	mlgr	%r8,%r5
        +	alcgr	%r9,%r6
        +	stg	%r9,8(%r2,%r1)
        +
        +	lg	%r7,16(%r2,%r3)
        +	mlgr	%r6,%r5
        +	alcgr	%r7,%r8
        +	stg	%r7,16(%r2,%r1)
        +
        +	lg	%r9,24(%r2,%r3)
        +	mlgr	%r8,%r5
        +	alcgr	%r9,%r6
        +	stg	%r9,24(%r2,%r1)
        +
        +	la	%r2,32(%r2)	// i+=4
        +	brct	%r4,.Loop4_mul
        +
        +	la	%r10,1(%r10)		// see if len%4 is zero ...
        +	brct	%r10,.Loop1_mul		// without touching condition code:-)
        +
        +.Lend_mul:
        +	alcgr	%r8,zero	// collect carry bit
        +	lgr	%r2,%r8
        +	lmg	%r6,%r10,48(%r15)
        +	br	%r14
        +
        +.Loop1_mul:
        +	lg	%r7,0(%r2,%r3)	// ap[i]
        +	mlgr	%r6,%r5		// *=w
        +	alcgr	%r7,%r8		// +=carry
        +	stg	%r7,0(%r2,%r1)	// rp[i]=
        +
        +	lgr	%r8,%r6
        +	la	%r2,8(%r2)	// i++
        +	brct	%r10,.Loop1_mul
        +
        +	j	.Lend_mul
        +.size	bn_mul_words,.-bn_mul_words
        +
        +// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
        +.globl	bn_sqr_words
        +.type	bn_sqr_words,@function
        +.align	4
        +bn_sqr_words:
        +	ltgfr	%r4,%r4
        +	bler	%r14
        +
        +	stmg	%r6,%r7,48(%r15)
        +	srag	%r1,%r4,2	// cnt=len/4
        +	jz	.Loop1_sqr
        +
        +.Loop4_sqr:
        +	lg	%r7,0(%r3)
        +	mlgr	%r6,%r7
        +	stg	%r7,0(%r2)
        +	stg	%r6,8(%r2)
        +
        +	lg	%r7,8(%r3)
        +	mlgr	%r6,%r7
        +	stg	%r7,16(%r2)
        +	stg	%r6,24(%r2)
        +
        +	lg	%r7,16(%r3)
        +	mlgr	%r6,%r7
        +	stg	%r7,32(%r2)
        +	stg	%r6,40(%r2)
        +
        +	lg	%r7,24(%r3)
        +	mlgr	%r6,%r7
        +	stg	%r7,48(%r2)
        +	stg	%r6,56(%r2)
        +
        +	la	%r3,32(%r3)
        +	la	%r2,64(%r2)
        +	brct	%r1,.Loop4_sqr
        +
        +	lghi	%r1,3
        +	nr	%r4,%r1		// cnt=len%4
        +	jz	.Lend_sqr
        +
        +.Loop1_sqr:
        +	lg	%r7,0(%r3)
        +	mlgr	%r6,%r7
        +	stg	%r7,0(%r2)
        +	stg	%r6,8(%r2)
        +
        +	la	%r3,8(%r3)
        +	la	%r2,16(%r2)
        +	brct	%r4,.Loop1_sqr
        +
        +.Lend_sqr:
        +	lmg	%r6,%r7,48(%r15)
        +	br	%r14
        +.size	bn_sqr_words,.-bn_sqr_words
        +
        +// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
        +.globl	bn_div_words
        +.type	bn_div_words,@function
        +.align	4
        +bn_div_words:
        +	dlgr	%r2,%r4
        +	lgr	%r2,%r3
        +	br	%r14
        +.size	bn_div_words,.-bn_div_words
        +
        +// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
        +.globl	bn_add_words
        +.type	bn_add_words,@function
        +.align	4
        +bn_add_words:
        +	la	%r1,0(%r2)	// put rp aside
        +	lghi	%r2,0		// i=0
        +	ltgfr	%r5,%r5
        +	bler	%r14		// if (len<=0) return 0;
        +
        +	stg	%r6,48(%r15)
        +	lghi	%r6,3
        +	nr	%r6,%r5		// len%4
        +	sra	%r5,2		// len/4, use sra because it sets condition code
        +	jz	.Loop1_add	// carry is incidentally cleared if branch taken
        +	algr	%r2,%r2		// clear carry
        +
        +.Loop4_add:
        +	lg	%r0,0(%r2,%r3)
        +	alcg	%r0,0(%r2,%r4)
        +	stg	%r0,0(%r2,%r1)
        +	lg	%r0,8(%r2,%r3)
        +	alcg	%r0,8(%r2,%r4)
        +	stg	%r0,8(%r2,%r1)
        +	lg	%r0,16(%r2,%r3)
        +	alcg	%r0,16(%r2,%r4)
        +	stg	%r0,16(%r2,%r1)
        +	lg	%r0,24(%r2,%r3)
        +	alcg	%r0,24(%r2,%r4)
        +	stg	%r0,24(%r2,%r1)
        +
        +	la	%r2,32(%r2)	// i+=4
        +	brct	%r5,.Loop4_add
        +
        +	la	%r6,1(%r6)	// see if len%4 is zero ...
        +	brct	%r6,.Loop1_add	// without touching condition code:-)
        +
        +.Lexit_add:
        +	lghi	%r2,0
        +	alcgr	%r2,%r2
        +	lg	%r6,48(%r15)
        +	br	%r14
        +
        +.Loop1_add:
        +	lg	%r0,0(%r2,%r3)
        +	alcg	%r0,0(%r2,%r4)
        +	stg	%r0,0(%r2,%r1)
        +
        +	la	%r2,8(%r2)	// i++
        +	brct	%r6,.Loop1_add
        +
        +	j	.Lexit_add
        +.size	bn_add_words,.-bn_add_words
        +
        +// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
        +.globl	bn_sub_words
        +.type	bn_sub_words,@function
        +.align	4
        +bn_sub_words:
        +	la	%r1,0(%r2)	// put rp aside
        +	lghi	%r2,0		// i=0
        +	ltgfr	%r5,%r5
        +	bler	%r14		// if (len<=0) return 0;
        +
        +	stg	%r6,48(%r15)
        +	lghi	%r6,3
        +	nr	%r6,%r5		// len%4
        +	sra	%r5,2		// len/4, use sra because it sets condition code
        +	jnz	.Loop4_sub	// borrow is incidentally cleared if branch taken
        +	slgr	%r2,%r2		// clear borrow
        +
        +.Loop1_sub:
        +	lg	%r0,0(%r2,%r3)
        +	slbg	%r0,0(%r2,%r4)
        +	stg	%r0,0(%r2,%r1)
        +
        +	la	%r2,8(%r2)	// i++
        +	brct	%r6,.Loop1_sub
        +	j	.Lexit_sub
        +
        +.Loop4_sub:
        +	lg	%r0,0(%r2,%r3)
        +	slbg	%r0,0(%r2,%r4)
        +	stg	%r0,0(%r2,%r1)
        +	lg	%r0,8(%r2,%r3)
        +	slbg	%r0,8(%r2,%r4)
        +	stg	%r0,8(%r2,%r1)
        +	lg	%r0,16(%r2,%r3)
        +	slbg	%r0,16(%r2,%r4)
        +	stg	%r0,16(%r2,%r1)
        +	lg	%r0,24(%r2,%r3)
        +	slbg	%r0,24(%r2,%r4)
        +	stg	%r0,24(%r2,%r1)
        +
        +	la	%r2,32(%r2)	// i+=4
        +	brct	%r5,.Loop4_sub
        +
        +	la	%r6,1(%r6)	// see if len%4 is zero ...
        +	brct	%r6,.Loop1_sub	// without touching condition code:-)
        +
        +.Lexit_sub:
        +	lghi	%r2,0
        +	slbgr	%r2,%r2
        +	lcgr	%r2,%r2
        +	lg	%r6,48(%r15)
        +	br	%r14
        +.size	bn_sub_words,.-bn_sub_words
        +
        +#define c1	%r1
        +#define c2	%r5
        +#define c3	%r8
        +
        +#define mul_add_c(ai,bi,c1,c2,c3)	\
        +	lg	%r7,ai*8(%r3);		\
        +	mlg	%r6,bi*8(%r4);		\
        +	algr	c1,%r7;			\
        +	alcgr	c2,%r6;			\
        +	alcgr	c3,zero
        +
        +// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
        +.globl	bn_mul_comba8
        +.type	bn_mul_comba8,@function
        +.align	4
        +bn_mul_comba8:
        +	stmg	%r6,%r8,48(%r15)
        +
        +	lghi	c1,0
        +	lghi	c2,0
        +	lghi	c3,0
        +	lghi	zero,0
        +
        +	mul_add_c(0,0,c1,c2,c3);
        +	stg	c1,0*8(%r2)
        +	lghi	c1,0
        +
        +	mul_add_c(0,1,c2,c3,c1);
        +	mul_add_c(1,0,c2,c3,c1);
        +	stg	c2,1*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(2,0,c3,c1,c2);
        +	mul_add_c(1,1,c3,c1,c2);
        +	mul_add_c(0,2,c3,c1,c2);
        +	stg	c3,2*8(%r2)
        +	lghi	c3,0
        +
        +	mul_add_c(0,3,c1,c2,c3);
        +	mul_add_c(1,2,c1,c2,c3);
        +	mul_add_c(2,1,c1,c2,c3);
        +	mul_add_c(3,0,c1,c2,c3);
        +	stg	c1,3*8(%r2)
        +	lghi	c1,0
        +
        +	mul_add_c(4,0,c2,c3,c1);
        +	mul_add_c(3,1,c2,c3,c1);
        +	mul_add_c(2,2,c2,c3,c1);
        +	mul_add_c(1,3,c2,c3,c1);
        +	mul_add_c(0,4,c2,c3,c1);
        +	stg	c2,4*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(0,5,c3,c1,c2);
        +	mul_add_c(1,4,c3,c1,c2);
        +	mul_add_c(2,3,c3,c1,c2);
        +	mul_add_c(3,2,c3,c1,c2);
        +	mul_add_c(4,1,c3,c1,c2);
        +	mul_add_c(5,0,c3,c1,c2);
        +	stg	c3,5*8(%r2)
        +	lghi	c3,0
        +
        +	mul_add_c(6,0,c1,c2,c3);
        +	mul_add_c(5,1,c1,c2,c3);
        +	mul_add_c(4,2,c1,c2,c3);
        +	mul_add_c(3,3,c1,c2,c3);
        +	mul_add_c(2,4,c1,c2,c3);
        +	mul_add_c(1,5,c1,c2,c3);
        +	mul_add_c(0,6,c1,c2,c3);
        +	stg	c1,6*8(%r2)
        +	lghi	c1,0
        +
        +	mul_add_c(0,7,c2,c3,c1);
        +	mul_add_c(1,6,c2,c3,c1);
        +	mul_add_c(2,5,c2,c3,c1);
        +	mul_add_c(3,4,c2,c3,c1);
        +	mul_add_c(4,3,c2,c3,c1);
        +	mul_add_c(5,2,c2,c3,c1);
        +	mul_add_c(6,1,c2,c3,c1);
        +	mul_add_c(7,0,c2,c3,c1);
        +	stg	c2,7*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(7,1,c3,c1,c2);
        +	mul_add_c(6,2,c3,c1,c2);
        +	mul_add_c(5,3,c3,c1,c2);
        +	mul_add_c(4,4,c3,c1,c2);
        +	mul_add_c(3,5,c3,c1,c2);
        +	mul_add_c(2,6,c3,c1,c2);
        +	mul_add_c(1,7,c3,c1,c2);
        +	stg	c3,8*8(%r2)
        +	lghi	c3,0
        +
        +	mul_add_c(2,7,c1,c2,c3);
        +	mul_add_c(3,6,c1,c2,c3);
        +	mul_add_c(4,5,c1,c2,c3);
        +	mul_add_c(5,4,c1,c2,c3);
        +	mul_add_c(6,3,c1,c2,c3);
        +	mul_add_c(7,2,c1,c2,c3);
        +	stg	c1,9*8(%r2)
        +	lghi	c1,0
        +
        +	mul_add_c(7,3,c2,c3,c1);
        +	mul_add_c(6,4,c2,c3,c1);
        +	mul_add_c(5,5,c2,c3,c1);
        +	mul_add_c(4,6,c2,c3,c1);
        +	mul_add_c(3,7,c2,c3,c1);
        +	stg	c2,10*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(4,7,c3,c1,c2);
        +	mul_add_c(5,6,c3,c1,c2);
        +	mul_add_c(6,5,c3,c1,c2);
        +	mul_add_c(7,4,c3,c1,c2);
        +	stg	c3,11*8(%r2)
        +	lghi	c3,0
        +
        +	mul_add_c(7,5,c1,c2,c3);
        +	mul_add_c(6,6,c1,c2,c3);
        +	mul_add_c(5,7,c1,c2,c3);
        +	stg	c1,12*8(%r2)
        +	lghi	c1,0
        +
        +
        +	mul_add_c(6,7,c2,c3,c1);
        +	mul_add_c(7,6,c2,c3,c1);
        +	stg	c2,13*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(7,7,c3,c1,c2);
        +	stg	c3,14*8(%r2)
        +	stg	c1,15*8(%r2)
        +
        +	lmg	%r6,%r8,48(%r15)
        +	br	%r14
        +.size	bn_mul_comba8,.-bn_mul_comba8
        +
        +// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
        +.globl	bn_mul_comba4
        +.type	bn_mul_comba4,@function
        +.align	4
        +bn_mul_comba4:
        +	stmg	%r6,%r8,48(%r15)
        +
        +	lghi	c1,0
        +	lghi	c2,0
        +	lghi	c3,0
        +	lghi	zero,0
        +
        +	mul_add_c(0,0,c1,c2,c3);
        +	stg	c1,0*8(%r3)
        +	lghi	c1,0
        +
        +	mul_add_c(0,1,c2,c3,c1);
        +	mul_add_c(1,0,c2,c3,c1);
        +	stg	c2,1*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(2,0,c3,c1,c2);
        +	mul_add_c(1,1,c3,c1,c2);
        +	mul_add_c(0,2,c3,c1,c2);
        +	stg	c3,2*8(%r2)
        +	lghi	c3,0
        +
        +	mul_add_c(0,3,c1,c2,c3);
        +	mul_add_c(1,2,c1,c2,c3);
        +	mul_add_c(2,1,c1,c2,c3);
        +	mul_add_c(3,0,c1,c2,c3);
        +	stg	c1,3*8(%r2)
        +	lghi	c1,0
        +
        +	mul_add_c(3,1,c2,c3,c1);
        +	mul_add_c(2,2,c2,c3,c1);
        +	mul_add_c(1,3,c2,c3,c1);
        +	stg	c2,4*8(%r2)
        +	lghi	c2,0
        +
        +	mul_add_c(2,3,c3,c1,c2);
        +	mul_add_c(3,2,c3,c1,c2);
        +	stg	c3,5*8(%r2)
        +	lghi	c3,0
        +
        +	mul_add_c(3,3,c1,c2,c3);
        +	stg	c1,6*8(%r2)
        +	stg	c2,7*8(%r2)
        +
        +	stmg	%r6,%r8,48(%r15)
        +	br	%r14
        +.size	bn_mul_comba4,.-bn_mul_comba4
        +
        +#define sqr_add_c(ai,c1,c2,c3)		\
        +	lg	%r7,ai*8(%r3);		\
        +	mlgr	%r6,%r7;		\
        +	algr	c1,%r7;			\
        +	alcgr	c2,%r6;			\
        +	alcgr	c3,zero
        +
        +#define sqr_add_c2(ai,aj,c1,c2,c3)	\
        +	lg	%r7,ai*8(%r3);		\
        +	mlg	%r6,aj*8(%r3);		\
        +	algr	c1,%r7;			\
        +	alcgr	c2,%r6;			\
        +	alcgr	c3,zero;		\
        +	algr	c1,%r7;			\
        +	alcgr	c2,%r6;			\
        +	alcgr	c3,zero
        +
        +// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
        +.globl	bn_sqr_comba8
        +.type	bn_sqr_comba8,@function
        +.align	4
        +bn_sqr_comba8:
        +	stmg	%r6,%r8,48(%r15)
        +
        +	lghi	c1,0
        +	lghi	c2,0
        +	lghi	c3,0
        +	lghi	zero,0
        +
        +	sqr_add_c(0,c1,c2,c3);
        +	stg	c1,0*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c2(1,0,c2,c3,c1);
        +	stg	c2,1*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c(1,c3,c1,c2);
        +	sqr_add_c2(2,0,c3,c1,c2);
        +	stg	c3,2*8(%r2)
        +	lghi	c3,0
        +
        +	sqr_add_c2(3,0,c1,c2,c3);
        +	sqr_add_c2(2,1,c1,c2,c3);
        +	stg	c1,3*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c(2,c2,c3,c1);
        +	sqr_add_c2(3,1,c2,c3,c1);
        +	sqr_add_c2(4,0,c2,c3,c1);
        +	stg	c2,4*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c2(5,0,c3,c1,c2);
        +	sqr_add_c2(4,1,c3,c1,c2);
        +	sqr_add_c2(3,2,c3,c1,c2);
        +	stg	c3,5*8(%r2)
        +	lghi	c3,0
        +
        +	sqr_add_c(3,c1,c2,c3);
        +	sqr_add_c2(4,2,c1,c2,c3);
        +	sqr_add_c2(5,1,c1,c2,c3);
        +	sqr_add_c2(6,0,c1,c2,c3);
        +	stg	c1,6*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c2(7,0,c2,c3,c1);
        +	sqr_add_c2(6,1,c2,c3,c1);
        +	sqr_add_c2(5,2,c2,c3,c1);
        +	sqr_add_c2(4,3,c2,c3,c1);
        +	stg	c2,7*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c(4,c3,c1,c2);
        +	sqr_add_c2(5,3,c3,c1,c2);
        +	sqr_add_c2(6,2,c3,c1,c2);
        +	sqr_add_c2(7,1,c3,c1,c2);
        +	stg	c3,8*8(%r2)
        +	lghi	c3,0
        +
        +	sqr_add_c2(7,2,c1,c2,c3);
        +	sqr_add_c2(6,3,c1,c2,c3);
        +	sqr_add_c2(5,4,c1,c2,c3);
        +	stg	c1,9*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c(5,c2,c3,c1);
        +	sqr_add_c2(6,4,c2,c3,c1);
        +	sqr_add_c2(7,3,c2,c3,c1);
        +	stg	c2,10*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c2(7,4,c3,c1,c2);
        +	sqr_add_c2(6,5,c3,c1,c2);
        +	stg	c3,11*8(%r2)
        +	lghi	c3,0
        +
        +	sqr_add_c(6,c1,c2,c3);
        +	sqr_add_c2(7,5,c1,c2,c3);
        +	stg	c1,12*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c2(7,6,c2,c3,c1);
        +	stg	c2,13*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c(7,c3,c1,c2);
        +	stg	c3,14*8(%r2)
        +	stg	c1,15*8(%r2)
        +
        +	lmg	%r6,%r8,48(%r15)
        +	br	%r14
        +.size	bn_sqr_comba8,.-bn_sqr_comba8
        +
        +// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
        +.globl bn_sqr_comba4
        +.type	bn_sqr_comba4,@function
        +.align	4
        +bn_sqr_comba4:
        +	stmg	%r6,%r8,48(%r15)
        +
        +	lghi	c1,0
        +	lghi	c2,0
        +	lghi	c3,0
        +	lghi	zero,0
        +
        +	sqr_add_c(0,c1,c2,c3);
        +	stg	c1,0*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c2(1,0,c2,c3,c1);
        +	stg	c2,1*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c(1,c3,c1,c2);
        +	sqr_add_c2(2,0,c3,c1,c2);
        +	stg	c3,2*8(%r2)
        +	lghi	c3,0
        +
        +	sqr_add_c2(3,0,c1,c2,c3);
        +	sqr_add_c2(2,1,c1,c2,c3);
        +	stg	c1,3*8(%r2)
        +	lghi	c1,0
        +
        +	sqr_add_c(2,c2,c3,c1);
        +	sqr_add_c2(3,1,c2,c3,c1);
        +	stg	c2,4*8(%r2)
        +	lghi	c2,0
        +
        +	sqr_add_c2(3,2,c3,c1,c2);
        +	stg	c3,5*8(%r2)
        +	lghi	c3,0
        +
        +	sqr_add_c(3,c1,c2,c3);
        +	stg	c1,6*8(%r2)
        +	stg	c2,7*8(%r2)
        +
        +	lmg	%r6,%r8,48(%r15)
        +	br	%r14
        +.size	bn_sqr_comba4,.-bn_sqr_comba4
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/sparcv8.S b/vendor/openssl/openssl/crypto/bn/asm/sparcv8.S
        new file mode 100644
        index 000000000..88c5dc480
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/sparcv8.S
        @@ -0,0 +1,1458 @@
        +.ident	"sparcv8.s, Version 1.4"
        +.ident	"SPARC v8 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
        +
        +/*
        + * ====================================================================
        + * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        + * project.
        + *
        + * Rights for redistribution and usage in source and binary forms are
        + * granted according to the OpenSSL license. Warranty of any kind is
        + * disclaimed.
        + * ====================================================================
        + */
        +
        +/*
        + * This is my modest contributon to OpenSSL project (see
        + * http://www.openssl.org/ for more information about it) and is
        + * a drop-in SuperSPARC ISA replacement for crypto/bn/bn_asm.c
        + * module. For updates see http://fy.chalmers.se/~appro/hpe/.
        + *
        + * See bn_asm.sparc.v8plus.S for more details.
        + */
        +
        +/*
        + * Revision history.
        + *
        + * 1.1	- new loop unrolling model(*);
        + * 1.2	- made gas friendly;
        + * 1.3	- fixed problem with /usr/ccs/lib/cpp;
        + * 1.4	- some retunes;
        + *
        + * (*)	see bn_asm.sparc.v8plus.S for details
        + */
        +
        +.section	".text",#alloc,#execinstr
        +.file		"bn_asm.sparc.v8.S"
        +
        +.align	32
        +
        +.global bn_mul_add_words
        +/*
        + * BN_ULONG bn_mul_add_words(rp,ap,num,w)
        + * BN_ULONG *rp,*ap;
        + * int num;
        + * BN_ULONG w;
        + */
        +bn_mul_add_words:
        +	cmp	%o2,0
        +	bg,a	.L_bn_mul_add_words_proceed
        +	ld	[%o1],%g2
        +	retl
        +	clr	%o0
        +
        +.L_bn_mul_add_words_proceed:
        +	andcc	%o2,-4,%g0
        +	bz	.L_bn_mul_add_words_tail
        +	clr	%o5
        +
        +.L_bn_mul_add_words_loop:
        +	ld	[%o0],%o4
        +	ld	[%o1+4],%g3
        +	umul	%o3,%g2,%g2
        +	rd	%y,%g1
        +	addcc	%o4,%o5,%o4
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g2,%o4
        +	st	%o4,[%o0]
        +	addx	%g1,0,%o5
        +
        +	ld	[%o0+4],%o4
        +	ld	[%o1+8],%g2
        +	umul	%o3,%g3,%g3
        +	dec	4,%o2
        +	rd	%y,%g1
        +	addcc	%o4,%o5,%o4
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g3,%o4
        +	st	%o4,[%o0+4]
        +	addx	%g1,0,%o5
        +
        +	ld	[%o0+8],%o4
        +	ld	[%o1+12],%g3
        +	umul	%o3,%g2,%g2
        +	inc	16,%o1
        +	rd	%y,%g1
        +	addcc	%o4,%o5,%o4
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g2,%o4
        +	st	%o4,[%o0+8]
        +	addx	%g1,0,%o5
        +
        +	ld	[%o0+12],%o4
        +	umul	%o3,%g3,%g3
        +	inc	16,%o0
        +	rd	%y,%g1
        +	addcc	%o4,%o5,%o4
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g3,%o4
        +	st	%o4,[%o0-4]
        +	addx	%g1,0,%o5
        +	andcc	%o2,-4,%g0
        +	bnz,a	.L_bn_mul_add_words_loop
        +	ld	[%o1],%g2
        +
        +	tst	%o2
        +	bnz,a	.L_bn_mul_add_words_tail
        +	ld	[%o1],%g2
        +.L_bn_mul_add_words_return:
        +	retl
        +	mov	%o5,%o0
        +	nop
        +
        +.L_bn_mul_add_words_tail:
        +	ld	[%o0],%o4
        +	umul	%o3,%g2,%g2
        +	addcc	%o4,%o5,%o4
        +	rd	%y,%g1
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g2,%o4
        +	addx	%g1,0,%o5
        +	deccc	%o2
        +	bz	.L_bn_mul_add_words_return
        +	st	%o4,[%o0]
        +
        +	ld	[%o1+4],%g2
        +	ld	[%o0+4],%o4
        +	umul	%o3,%g2,%g2
        +	rd	%y,%g1
        +	addcc	%o4,%o5,%o4
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g2,%o4
        +	addx	%g1,0,%o5
        +	deccc	%o2
        +	bz	.L_bn_mul_add_words_return
        +	st	%o4,[%o0+4]
        +
        +	ld	[%o1+8],%g2
        +	ld	[%o0+8],%o4
        +	umul	%o3,%g2,%g2
        +	rd	%y,%g1
        +	addcc	%o4,%o5,%o4
        +	addx	%g1,0,%g1
        +	addcc	%o4,%g2,%o4
        +	st	%o4,[%o0+8]
        +	retl
        +	addx	%g1,0,%o0
        +
        +.type	bn_mul_add_words,#function
        +.size	bn_mul_add_words,(.-bn_mul_add_words)
        +
        +.align	32
        +
        +.global bn_mul_words
        +/*
        + * BN_ULONG bn_mul_words(rp,ap,num,w)
        + * BN_ULONG *rp,*ap;
        + * int num;
        + * BN_ULONG w;
        + */
        +bn_mul_words:
        +	cmp	%o2,0
        +	bg,a	.L_bn_mul_words_proceeed
        +	ld	[%o1],%g2
        +	retl
        +	clr	%o0
        +
        +.L_bn_mul_words_proceeed:
        +	andcc	%o2,-4,%g0
        +	bz	.L_bn_mul_words_tail
        +	clr	%o5
        +
        +.L_bn_mul_words_loop:
        +	ld	[%o1+4],%g3
        +	umul	%o3,%g2,%g2
        +	addcc	%g2,%o5,%g2
        +	rd	%y,%g1
        +	addx	%g1,0,%o5
        +	st	%g2,[%o0]
        +
        +	ld	[%o1+8],%g2
        +	umul	%o3,%g3,%g3
        +	addcc	%g3,%o5,%g3
        +	rd	%y,%g1
        +	dec	4,%o2
        +	addx	%g1,0,%o5
        +	st	%g3,[%o0+4]
        +
        +	ld	[%o1+12],%g3
        +	umul	%o3,%g2,%g2
        +	addcc	%g2,%o5,%g2
        +	rd	%y,%g1
        +	inc	16,%o1
        +	st	%g2,[%o0+8]
        +	addx	%g1,0,%o5
        +
        +	umul	%o3,%g3,%g3
        +	addcc	%g3,%o5,%g3
        +	rd	%y,%g1
        +	inc	16,%o0
        +	addx	%g1,0,%o5
        +	st	%g3,[%o0-4]
        +	andcc	%o2,-4,%g0
        +	nop
        +	bnz,a	.L_bn_mul_words_loop
        +	ld	[%o1],%g2
        +
        +	tst	%o2
        +	bnz,a	.L_bn_mul_words_tail
        +	ld	[%o1],%g2
        +.L_bn_mul_words_return:
        +	retl
        +	mov	%o5,%o0
        +	nop
        +
        +.L_bn_mul_words_tail:
        +	umul	%o3,%g2,%g2
        +	addcc	%g2,%o5,%g2
        +	rd	%y,%g1
        +	addx	%g1,0,%o5
        +	deccc	%o2
        +	bz	.L_bn_mul_words_return
        +	st	%g2,[%o0]
        +	nop
        +
        +	ld	[%o1+4],%g2
        +	umul	%o3,%g2,%g2
        +	addcc	%g2,%o5,%g2
        +	rd	%y,%g1
        +	addx	%g1,0,%o5
        +	deccc	%o2
        +	bz	.L_bn_mul_words_return
        +	st	%g2,[%o0+4]
        +
        +	ld	[%o1+8],%g2
        +	umul	%o3,%g2,%g2
        +	addcc	%g2,%o5,%g2
        +	rd	%y,%g1
        +	st	%g2,[%o0+8]
        +	retl
        +	addx	%g1,0,%o0
        +
        +.type	bn_mul_words,#function
        +.size	bn_mul_words,(.-bn_mul_words)
        +
        +.align  32
        +.global	bn_sqr_words
        +/*
        + * void bn_sqr_words(r,a,n)
        + * BN_ULONG *r,*a;
        + * int n;
        + */
        +bn_sqr_words:
        +	cmp	%o2,0
        +	bg,a	.L_bn_sqr_words_proceeed
        +	ld	[%o1],%g2
        +	retl
        +	clr	%o0
        +
        +.L_bn_sqr_words_proceeed:
        +	andcc	%o2,-4,%g0
        +	bz	.L_bn_sqr_words_tail
        +	clr	%o5
        +
        +.L_bn_sqr_words_loop:
        +	ld	[%o1+4],%g3
        +	umul	%g2,%g2,%o4
        +	st	%o4,[%o0]
        +	rd	%y,%o5
        +	st	%o5,[%o0+4]
        +
        +	ld	[%o1+8],%g2
        +	umul	%g3,%g3,%o4
        +	dec	4,%o2
        +	st	%o4,[%o0+8]
        +	rd	%y,%o5
        +	st	%o5,[%o0+12]
        +	nop
        +
        +	ld	[%o1+12],%g3
        +	umul	%g2,%g2,%o4
        +	st	%o4,[%o0+16]
        +	rd	%y,%o5
        +	inc	16,%o1
        +	st	%o5,[%o0+20]
        +
        +	umul	%g3,%g3,%o4
        +	inc	32,%o0
        +	st	%o4,[%o0-8]
        +	rd	%y,%o5
        +	st	%o5,[%o0-4]
        +	andcc	%o2,-4,%g2
        +	bnz,a	.L_bn_sqr_words_loop
        +	ld	[%o1],%g2
        +
        +	tst	%o2
        +	nop
        +	bnz,a	.L_bn_sqr_words_tail
        +	ld	[%o1],%g2
        +.L_bn_sqr_words_return:
        +	retl
        +	clr	%o0
        +
        +.L_bn_sqr_words_tail:
        +	umul	%g2,%g2,%o4
        +	st	%o4,[%o0]
        +	deccc	%o2
        +	rd	%y,%o5
        +	bz	.L_bn_sqr_words_return
        +	st	%o5,[%o0+4]
        +
        +	ld	[%o1+4],%g2
        +	umul	%g2,%g2,%o4
        +	st	%o4,[%o0+8]
        +	deccc	%o2
        +	rd	%y,%o5
        +	nop
        +	bz	.L_bn_sqr_words_return
        +	st	%o5,[%o0+12]
        +
        +	ld	[%o1+8],%g2
        +	umul	%g2,%g2,%o4
        +	st	%o4,[%o0+16]
        +	rd	%y,%o5
        +	st	%o5,[%o0+20]
        +	retl
        +	clr	%o0
        +
        +.type	bn_sqr_words,#function
        +.size	bn_sqr_words,(.-bn_sqr_words)
        +
        +.align	32
        +
        +.global bn_div_words
        +/*
        + * BN_ULONG bn_div_words(h,l,d)
        + * BN_ULONG h,l,d;
        + */
        +bn_div_words:
        +	wr	%o0,%y
        +	udiv	%o1,%o2,%o0
        +	retl
        +	nop
        +
        +.type	bn_div_words,#function
        +.size	bn_div_words,(.-bn_div_words)
        +
        +.align	32
        +
        +.global bn_add_words
        +/*
        + * BN_ULONG bn_add_words(rp,ap,bp,n)
        + * BN_ULONG *rp,*ap,*bp;
        + * int n;
        + */
        +bn_add_words:
        +	cmp	%o3,0
        +	bg,a	.L_bn_add_words_proceed
        +	ld	[%o1],%o4
        +	retl
        +	clr	%o0
        +
        +.L_bn_add_words_proceed:
        +	andcc	%o3,-4,%g0
        +	bz	.L_bn_add_words_tail
        +	clr	%g1
        +	ba	.L_bn_add_words_warn_loop
        +	addcc	%g0,0,%g0	! clear carry flag
        +
        +.L_bn_add_words_loop:
        +	ld	[%o1],%o4
        +.L_bn_add_words_warn_loop:
        +	ld	[%o2],%o5
        +	ld	[%o1+4],%g3
        +	ld	[%o2+4],%g4
        +	dec	4,%o3
        +	addxcc	%o5,%o4,%o5
        +	st	%o5,[%o0]
        +
        +	ld	[%o1+8],%o4
        +	ld	[%o2+8],%o5
        +	inc	16,%o1
        +	addxcc	%g3,%g4,%g3
        +	st	%g3,[%o0+4]
        +	
        +	ld	[%o1-4],%g3
        +	ld	[%o2+12],%g4
        +	inc	16,%o2
        +	addxcc	%o5,%o4,%o5
        +	st	%o5,[%o0+8]
        +
        +	inc	16,%o0
        +	addxcc	%g3,%g4,%g3
        +	st	%g3,[%o0-4]
        +	addx	%g0,0,%g1
        +	andcc	%o3,-4,%g0
        +	bnz,a	.L_bn_add_words_loop
        +	addcc	%g1,-1,%g0
        +
        +	tst	%o3
        +	bnz,a	.L_bn_add_words_tail
        +	ld	[%o1],%o4
        +.L_bn_add_words_return:
        +	retl
        +	mov	%g1,%o0
        +
        +.L_bn_add_words_tail:
        +	addcc	%g1,-1,%g0
        +	ld	[%o2],%o5
        +	addxcc	%o5,%o4,%o5
        +	addx	%g0,0,%g1
        +	deccc	%o3
        +	bz	.L_bn_add_words_return
        +	st	%o5,[%o0]
        +
        +	ld	[%o1+4],%o4
        +	addcc	%g1,-1,%g0
        +	ld	[%o2+4],%o5
        +	addxcc	%o5,%o4,%o5
        +	addx	%g0,0,%g1
        +	deccc	%o3
        +	bz	.L_bn_add_words_return
        +	st	%o5,[%o0+4]
        +
        +	ld	[%o1+8],%o4
        +	addcc	%g1,-1,%g0
        +	ld	[%o2+8],%o5
        +	addxcc	%o5,%o4,%o5
        +	st	%o5,[%o0+8]
        +	retl
        +	addx	%g0,0,%o0
        +
        +.type	bn_add_words,#function
        +.size	bn_add_words,(.-bn_add_words)
        +
        +.align	32
        +
        +.global bn_sub_words
        +/*
        + * BN_ULONG bn_sub_words(rp,ap,bp,n)
        + * BN_ULONG *rp,*ap,*bp;
        + * int n;
        + */
        +bn_sub_words:
        +	cmp	%o3,0
        +	bg,a	.L_bn_sub_words_proceed
        +	ld	[%o1],%o4
        +	retl
        +	clr	%o0
        +
        +.L_bn_sub_words_proceed:
        +	andcc	%o3,-4,%g0
        +	bz	.L_bn_sub_words_tail
        +	clr	%g1
        +	ba	.L_bn_sub_words_warm_loop
        +	addcc	%g0,0,%g0	! clear carry flag
        +
        +.L_bn_sub_words_loop:
        +	ld	[%o1],%o4
        +.L_bn_sub_words_warm_loop:
        +	ld	[%o2],%o5
        +	ld	[%o1+4],%g3
        +	ld	[%o2+4],%g4
        +	dec	4,%o3
        +	subxcc	%o4,%o5,%o5
        +	st	%o5,[%o0]
        +
        +	ld	[%o1+8],%o4
        +	ld	[%o2+8],%o5
        +	inc	16,%o1
        +	subxcc	%g3,%g4,%g4
        +	st	%g4,[%o0+4]
        +	
        +	ld	[%o1-4],%g3
        +	ld	[%o2+12],%g4
        +	inc	16,%o2
        +	subxcc	%o4,%o5,%o5
        +	st	%o5,[%o0+8]
        +
        +	inc	16,%o0
        +	subxcc	%g3,%g4,%g4
        +	st	%g4,[%o0-4]
        +	addx	%g0,0,%g1
        +	andcc	%o3,-4,%g0
        +	bnz,a	.L_bn_sub_words_loop
        +	addcc	%g1,-1,%g0
        +
        +	tst	%o3
        +	nop
        +	bnz,a	.L_bn_sub_words_tail
        +	ld	[%o1],%o4
        +.L_bn_sub_words_return:
        +	retl
        +	mov	%g1,%o0
        +
        +.L_bn_sub_words_tail:
        +	addcc	%g1,-1,%g0
        +	ld	[%o2],%o5
        +	subxcc	%o4,%o5,%o5
        +	addx	%g0,0,%g1
        +	deccc	%o3
        +	bz	.L_bn_sub_words_return
        +	st	%o5,[%o0]
        +	nop
        +
        +	ld	[%o1+4],%o4
        +	addcc	%g1,-1,%g0
        +	ld	[%o2+4],%o5
        +	subxcc	%o4,%o5,%o5
        +	addx	%g0,0,%g1
        +	deccc	%o3
        +	bz	.L_bn_sub_words_return
        +	st	%o5,[%o0+4]
        +
        +	ld	[%o1+8],%o4
        +	addcc	%g1,-1,%g0
        +	ld	[%o2+8],%o5
        +	subxcc	%o4,%o5,%o5
        +	st	%o5,[%o0+8]
        +	retl
        +	addx	%g0,0,%o0
        +
        +.type	bn_sub_words,#function
        +.size	bn_sub_words,(.-bn_sub_words)
        +
        +#define FRAME_SIZE	-96
        +
        +/*
        + * Here is register usage map for *all* routines below.
        + */
        +#define t_1	%o0
        +#define	t_2	%o1
        +#define c_1	%o2
        +#define c_2	%o3
        +#define c_3	%o4
        +
        +#define ap(I)	[%i1+4*I]
        +#define bp(I)	[%i2+4*I]
        +#define rp(I)	[%i0+4*I]
        +
        +#define	a_0	%l0
        +#define	a_1	%l1
        +#define	a_2	%l2
        +#define	a_3	%l3
        +#define	a_4	%l4
        +#define	a_5	%l5
        +#define	a_6	%l6
        +#define	a_7	%l7
        +
        +#define	b_0	%i3
        +#define	b_1	%i4
        +#define	b_2	%i5
        +#define	b_3	%o5
        +#define	b_4	%g1
        +#define	b_5	%g2
        +#define	b_6	%g3
        +#define	b_7	%g4
        +
        +.align	32
        +.global bn_mul_comba8
        +/*
        + * void bn_mul_comba8(r,a,b)
        + * BN_ULONG *r,*a,*b;
        + */
        +bn_mul_comba8:
        +	save	%sp,FRAME_SIZE,%sp
        +	ld	ap(0),a_0
        +	ld	bp(0),b_0
        +	umul	a_0,b_0,c_1	!=!mul_add_c(a[0],b[0],c1,c2,c3);
        +	ld	bp(1),b_1
        +	rd	%y,c_2
        +	st	c_1,rp(0)	!r[0]=c1;
        +
        +	umul	a_0,b_1,t_1	!=!mul_add_c(a[0],b[1],c2,c3,c1);
        +	ld	ap(1),a_1
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	%g0,t_2,c_3	!=
        +	addx	%g0,%g0,c_1
        +	ld	ap(2),a_2
        +	umul	a_1,b_0,t_1	!mul_add_c(a[1],b[0],c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	st	c_2,rp(1)	!r[1]=c2;
        +	addx	c_1,%g0,c_1	!=
        +
        +	umul	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	%g0,%g0,c_2
        +	ld	bp(2),b_2
        +	umul	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	ld	bp(3),b_3
        +	addx	c_2,%g0,c_2	!=
        +	umul	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	st	c_3,rp(2)	!r[2]=c3;
        +
        +	umul	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	%g0,%g0,c_3
        +	umul	a_1,b_2,t_1	!=!mul_add_c(a[1],b[2],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	ld	ap(3),a_3
        +	umul	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2		!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	ld	ap(4),a_4
        +	umul	a_3,b_0,t_1	!mul_add_c(a[3],b[0],c1,c2,c3);!=
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(3)	!r[3]=c1;
        +
        +	umul	a_4,b_0,t_1	!mul_add_c(a[4],b[0],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	umul	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	umul	a_2,b_2,t_1	!=!mul_add_c(a[2],b[2],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	ld	bp(4),b_4
        +	umul	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	ld	bp(5),b_5
        +	umul	a_0,b_4,t_1	!=!mul_add_c(a[0],b[4],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	st	c_2,rp(4)	!r[4]=c2;
        +
        +	umul	a_0,b_5,t_1	!mul_add_c(a[0],b[5],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2
        +	umul	a_1,b_4,t_1	!mul_add_c(a[1],b[4],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_2,b_3,t_1	!=!mul_add_c(a[2],b[3],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	umul	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	ld	ap(5),a_5
        +	umul	a_4,b_1,t_1	!mul_add_c(a[4],b[1],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	ld	ap(6),a_6
        +	addx	c_2,%g0,c_2	!=
        +	umul	a_5,b_0,t_1	!mul_add_c(a[5],b[0],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	st	c_3,rp(5)	!r[5]=c3;
        +
        +	umul	a_6,b_0,t_1	!mul_add_c(a[6],b[0],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	%g0,%g0,c_3
        +	umul	a_5,b_1,t_1	!=!mul_add_c(a[5],b[1],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_4,b_2,t_1	!mul_add_c(a[4],b[2],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	umul	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2		!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_2,b_4,t_1	!mul_add_c(a[2],b[4],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	ld	bp(6),b_6
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_1,b_5,t_1	!mul_add_c(a[1],b[5],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	ld	bp(7),b_7
        +	umul	a_0,b_6,t_1	!mul_add_c(a[0],b[6],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	st	c_1,rp(6)	!r[6]=c1;
        +	addx	c_3,%g0,c_3	!=
        +
        +	umul	a_0,b_7,t_1	!mul_add_c(a[0],b[7],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	%g0,%g0,c_1
        +	umul	a_1,b_6,t_1	!mul_add_c(a[1],b[6],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	umul	a_2,b_5,t_1	!mul_add_c(a[2],b[5],c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	umul	a_3,b_4,t_1	!=!mul_add_c(a[3],b[4],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	umul	a_4,b_3,t_1	!mul_add_c(a[4],b[3],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_5,b_2,t_1	!mul_add_c(a[5],b[2],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	ld	ap(7),a_7
        +	umul	a_6,b_1,t_1	!=!mul_add_c(a[6],b[1],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	umul	a_7,b_0,t_1	!mul_add_c(a[7],b[0],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	st	c_2,rp(7)	!r[7]=c2;
        +
        +	umul	a_7,b_1,t_1	!mul_add_c(a[7],b[1],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2
        +	umul	a_6,b_2,t_1	!=!mul_add_c(a[6],b[2],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	umul	a_5,b_3,t_1	!mul_add_c(a[5],b[3],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	umul	a_4,b_4,t_1	!mul_add_c(a[4],b[4],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_3,b_5,t_1	!mul_add_c(a[3],b[5],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_2,b_6,t_1	!=!mul_add_c(a[2],b[6],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	umul	a_1,b_7,t_1	!mul_add_c(a[1],b[7],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!
        +	addx	c_2,%g0,c_2
        +	st	c_3,rp(8)	!r[8]=c3;
        +
        +	umul	a_2,b_7,t_1	!mul_add_c(a[2],b[7],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	%g0,%g0,c_3
        +	umul	a_3,b_6,t_1	!=!mul_add_c(a[3],b[6],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_4,b_5,t_1	!mul_add_c(a[4],b[5],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	umul	a_5,b_4,t_1	!mul_add_c(a[5],b[4],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2		!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_6,b_3,t_1	!mul_add_c(a[6],b[3],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_7,b_2,t_1	!=!mul_add_c(a[7],b[2],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(9)	!r[9]=c1;
        +
        +	umul	a_7,b_3,t_1	!mul_add_c(a[7],b[3],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	umul	a_6,b_4,t_1	!mul_add_c(a[6],b[4],c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	umul	a_5,b_5,t_1	!=!mul_add_c(a[5],b[5],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	umul	a_4,b_6,t_1	!mul_add_c(a[4],b[6],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_3,b_7,t_1	!mul_add_c(a[3],b[7],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	st	c_2,rp(10)	!r[10]=c2;
        +
        +	umul	a_4,b_7,t_1	!=!mul_add_c(a[4],b[7],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2	!=
        +	umul	a_5,b_6,t_1	!mul_add_c(a[5],b[6],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	umul	a_6,b_5,t_1	!mul_add_c(a[6],b[5],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_7,b_4,t_1	!mul_add_c(a[7],b[4],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	st	c_3,rp(11)	!r[11]=c3;
        +	addx	c_2,%g0,c_2	!=
        +
        +	umul	a_7,b_5,t_1	!mul_add_c(a[7],b[5],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	%g0,%g0,c_3
        +	umul	a_6,b_6,t_1	!mul_add_c(a[6],b[6],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2		!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_5,b_7,t_1	!mul_add_c(a[5],b[7],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	st	c_1,rp(12)	!r[12]=c1;
        +	addx	c_3,%g0,c_3	!=
        +
        +	umul	a_6,b_7,t_1	!mul_add_c(a[6],b[7],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	%g0,%g0,c_1
        +	umul	a_7,b_6,t_1	!mul_add_c(a[7],b[6],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	st	c_2,rp(13)	!r[13]=c2;
        +
        +	umul	a_7,b_7,t_1	!=!mul_add_c(a[7],b[7],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	nop			!=
        +	st	c_3,rp(14)	!r[14]=c3;
        +	st	c_1,rp(15)	!r[15]=c1;
        +
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_mul_comba8,#function
        +.size	bn_mul_comba8,(.-bn_mul_comba8)
        +
        +.align	32
        +
        +.global bn_mul_comba4
        +/*
        + * void bn_mul_comba4(r,a,b)
        + * BN_ULONG *r,*a,*b;
        + */
        +bn_mul_comba4:
        +	save	%sp,FRAME_SIZE,%sp
        +	ld	ap(0),a_0
        +	ld	bp(0),b_0
        +	umul	a_0,b_0,c_1	!=!mul_add_c(a[0],b[0],c1,c2,c3);
        +	ld	bp(1),b_1
        +	rd	%y,c_2
        +	st	c_1,rp(0)	!r[0]=c1;
        +
        +	umul	a_0,b_1,t_1	!=!mul_add_c(a[0],b[1],c2,c3,c1);
        +	ld	ap(1),a_1
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	%g0,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	ld	ap(2),a_2
        +	umul	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	st	c_2,rp(1)	!r[1]=c2;
        +
        +	umul	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2
        +	ld	bp(2),b_2
        +	umul	a_1,b_1,t_1	!=!mul_add_c(a[1],b[1],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	ld	bp(3),b_3
        +	umul	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	st	c_3,rp(2)	!r[2]=c3;
        +
        +	umul	a_0,b_3,t_1	!=!mul_add_c(a[0],b[3],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	%g0,%g0,c_3	!=
        +	umul	a_1,b_2,t_1	!mul_add_c(a[1],b[2],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	ld	ap(3),a_3
        +	umul	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_3,b_0,t_1	!=!mul_add_c(a[3],b[0],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(3)	!r[3]=c1;
        +
        +	umul	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	umul	a_2,b_2,t_1	!mul_add_c(a[2],b[2],c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	umul	a_1,b_3,t_1	!=!mul_add_c(a[1],b[3],c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	st	c_2,rp(4)	!r[4]=c2;
        +
        +	umul	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2
        +	umul	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	st	c_3,rp(5)	!r[5]=c3;
        +	addx	c_2,%g0,c_2	!=
        +
        +	umul	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	st	c_1,rp(6)	!r[6]=c1;
        +	st	c_2,rp(7)	!r[7]=c2;
        +	
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_mul_comba4,#function
        +.size	bn_mul_comba4,(.-bn_mul_comba4)
        +
        +.align	32
        +
        +.global bn_sqr_comba8
        +bn_sqr_comba8:
        +	save	%sp,FRAME_SIZE,%sp
        +	ld	ap(0),a_0
        +	ld	ap(1),a_1
        +	umul	a_0,a_0,c_1	!=!sqr_add_c(a,0,c1,c2,c3);
        +	rd	%y,c_2
        +	st	c_1,rp(0)	!r[0]=c1;
        +
        +	ld	ap(2),a_2
        +	umul	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	%g0,t_2,c_3
        +	addx	%g0,%g0,c_1	!=
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3
        +	st	c_2,rp(1)	!r[1]=c2;
        +	addx	c_1,%g0,c_1	!=
        +
        +	umul	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	%g0,%g0,c_2
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	ld	ap(3),a_3
        +	umul	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	st	c_3,rp(2)	!r[2]=c3;
        +
        +	umul	a_0,a_3,t_1	!=!sqr_add_c2(a,3,0,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	%g0,%g0,c_3	!=
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	ld	ap(4),a_4
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(3)	!r[3]=c1;
        +
        +	umul	a_4,a_0,t_1	!sqr_add_c2(a,4,0,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	ld	ap(5),a_5
        +	umul	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	st	c_2,rp(4)	!r[4]=c2;
        +	addx	c_1,%g0,c_1	!=
        +
        +	umul	a_0,a_5,t_1	!sqr_add_c2(a,5,0,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	%g0,%g0,c_2
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	umul	a_1,a_4,t_1	!sqr_add_c2(a,4,1,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	ld	ap(6),a_6
        +	umul	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	st	c_3,rp(5)	!r[5]=c3;
        +
        +	umul	a_6,a_0,t_1	!sqr_add_c2(a,6,0,c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	%g0,%g0,c_3
        +	addcc	c_1,t_1,c_1	!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_5,a_1,t_1	!sqr_add_c2(a,5,1,c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	addcc	c_1,t_1,c_1	!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	umul	a_4,a_2,t_1	!sqr_add_c2(a,4,2,c1,c2,c3);
        +	addcc	c_1,t_1,c_1	!=
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	addcc	c_1,t_1,c_1	!=
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3
        +	ld	ap(7),a_7
        +	umul	a_3,a_3,t_1	!=!sqr_add_c(a,3,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(6)	!r[6]=c1;
        +
        +	umul	a_0,a_7,t_1	!sqr_add_c2(a,7,0,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_1,a_6,t_1	!sqr_add_c2(a,6,1,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_2,a_5,t_1	!sqr_add_c2(a,5,2,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_3,a_4,t_1	!sqr_add_c2(a,4,3,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	st	c_2,rp(7)	!r[7]=c2;
        +
        +	umul	a_7,a_1,t_1	!sqr_add_c2(a,7,1,c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2
        +	addcc	c_3,t_1,c_3	!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_6,a_2,t_1	!sqr_add_c2(a,6,2,c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	addcc	c_3,t_1,c_3	!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_5,a_3,t_1	!sqr_add_c2(a,5,3,c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	addcc	c_3,t_1,c_3	!=
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_4,a_4,t_1	!sqr_add_c(a,4,c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	st	c_3,rp(8)	!r[8]=c3;
        +	addx	c_2,%g0,c_2	!=
        +
        +	umul	a_2,a_7,t_1	!sqr_add_c2(a,7,2,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	%g0,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_3,a_6,t_1	!sqr_add_c2(a,6,3,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_4,a_5,t_1	!sqr_add_c2(a,5,4,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(9)	!r[9]=c1;
        +
        +	umul	a_7,a_3,t_1	!sqr_add_c2(a,7,3,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_6,a_4,t_1	!sqr_add_c2(a,6,4,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_5,a_5,t_1	!sqr_add_c(a,5,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	st	c_2,rp(10)	!r[10]=c2;
        +
        +	umul	a_4,a_7,t_1	!=!sqr_add_c2(a,7,4,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2	!=
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2
        +	umul	a_5,a_6,t_1	!=!sqr_add_c2(a,6,5,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	c_2,%g0,c_2	!=
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1
        +	st	c_3,rp(11)	!r[11]=c3;
        +	addx	c_2,%g0,c_2	!=
        +
        +	umul	a_7,a_5,t_1	!sqr_add_c2(a,7,5,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	%g0,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_6,a_6,t_1	!sqr_add_c(a,6,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	st	c_1,rp(12)	!r[12]=c1;
        +
        +	umul	a_6,a_7,t_1	!sqr_add_c2(a,7,6,c2,c3,c1);
        +	addcc	c_2,t_1,c_2	!=
        +	rd	%y,t_2
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	addcc	c_2,t_1,c_2	!=
        +	addxcc	c_3,t_2,c_3
        +	st	c_2,rp(13)	!r[13]=c2;
        +	addx	c_1,%g0,c_1	!=
        +
        +	umul	a_7,a_7,t_1	!sqr_add_c(a,7,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1	!=
        +	st	c_3,rp(14)	!r[14]=c3;
        +	st	c_1,rp(15)	!r[15]=c1;
        +
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_sqr_comba8,#function
        +.size	bn_sqr_comba8,(.-bn_sqr_comba8)
        +
        +.align	32
        +
        +.global bn_sqr_comba4
        +/*
        + * void bn_sqr_comba4(r,a)
        + * BN_ULONG *r,*a;
        + */
        +bn_sqr_comba4:
        +	save	%sp,FRAME_SIZE,%sp
        +	ld	ap(0),a_0
        +	umul	a_0,a_0,c_1	!sqr_add_c(a,0,c1,c2,c3);
        +	ld	ap(1),a_1	!=
        +	rd	%y,c_2
        +	st	c_1,rp(0)	!r[0]=c1;
        +
        +	ld	ap(2),a_2
        +	umul	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2
        +	addxcc	%g0,t_2,c_3
        +	addx	%g0,%g0,c_1	!=
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1	!=
        +	st	c_2,rp(1)	!r[1]=c2;
        +
        +	umul	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2		!=
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1	!=
        +	addx	c_2,%g0,c_2
        +	ld	ap(3),a_3
        +	umul	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
        +	addcc	c_3,t_1,c_3	!=
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	st	c_3,rp(2)	!r[2]=c3;
        +	addx	c_2,%g0,c_2	!=
        +
        +	umul	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	%g0,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	umul	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	addx	c_3,%g0,c_3
        +	addcc	c_1,t_1,c_1
        +	addxcc	c_2,t_2,c_2
        +	addx	c_3,%g0,c_3	!=
        +	st	c_1,rp(3)	!r[3]=c1;
        +
        +	umul	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	%g0,%g0,c_1
        +	addcc	c_2,t_1,c_2
        +	addxcc	c_3,t_2,c_3	!=
        +	addx	c_1,%g0,c_1
        +	umul	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
        +	addcc	c_2,t_1,c_2
        +	rd	%y,t_2		!=
        +	addxcc	c_3,t_2,c_3
        +	addx	c_1,%g0,c_1
        +	st	c_2,rp(4)	!r[4]=c2;
        +
        +	umul	a_2,a_3,t_1	!=!sqr_add_c2(a,3,2,c3,c1,c2);
        +	addcc	c_3,t_1,c_3
        +	rd	%y,t_2
        +	addxcc	c_1,t_2,c_1
        +	addx	%g0,%g0,c_2	!=
        +	addcc	c_3,t_1,c_3
        +	addxcc	c_1,t_2,c_1
        +	st	c_3,rp(5)	!r[5]=c3;
        +	addx	c_2,%g0,c_2	!=
        +
        +	umul	a_3,a_3,t_1	!sqr_add_c(a,3,c1,c2,c3);
        +	addcc	c_1,t_1,c_1
        +	rd	%y,t_2
        +	addxcc	c_2,t_2,c_2	!=
        +	st	c_1,rp(6)	!r[6]=c1;
        +	st	c_2,rp(7)	!r[7]=c2;
        +	
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_sqr_comba4,#function
        +.size	bn_sqr_comba4,(.-bn_sqr_comba4)
        +
        +.align	32
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/sparcv8plus.S b/vendor/openssl/openssl/crypto/bn/asm/sparcv8plus.S
        new file mode 100644
        index 000000000..63de1860f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/sparcv8plus.S
        @@ -0,0 +1,1558 @@
        +.ident	"sparcv8plus.s, Version 1.4"
        +.ident	"SPARC v9 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
        +
        +/*
        + * ====================================================================
        + * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        + * project.
        + *
        + * Rights for redistribution and usage in source and binary forms are
        + * granted according to the OpenSSL license. Warranty of any kind is
        + * disclaimed.
        + * ====================================================================
        + */
        +
        +/*
        + * This is my modest contributon to OpenSSL project (see
        + * http://www.openssl.org/ for more information about it) and is
        + * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c
        + * module. For updates see http://fy.chalmers.se/~appro/hpe/.
        + *
        + * Questions-n-answers.
        + *
        + * Q. How to compile?
        + * A. With SC4.x/SC5.x:
        + *
        + *	cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
        + *
        + *    and with gcc:
        + *
        + *	gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o
        + *
        + *    or if above fails (it does if you have gas installed):
        + *
        + *	gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o
        + *
        + *    Quick-n-dirty way to fuse the module into the library.
        + *    Provided that the library is already configured and built
        + *    (in 0.9.2 case with no-asm option):
        + *
        + *	# cd crypto/bn
        + *	# cp /some/place/bn_asm.sparc.v8plus.S .
        + *	# cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
        + *	# make
        + *	# cd ../..
        + *	# make; make test
        + *
        + *    Quick-n-dirty way to get rid of it:
        + *
        + *	# cd crypto/bn
        + *	# touch bn_asm.c
        + *	# make
        + *	# cd ../..
        + *	# make; make test
        + *
        + * Q. V8plus achitecture? What kind of beast is that?
        + * A. Well, it's rather a programming model than an architecture...
        + *    It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under
        + *    special conditions, namely when kernel doesn't preserve upper
        + *    32 bits of otherwise 64-bit registers during a context switch.
        + *
        + * Q. Why just UltraSPARC? What about SuperSPARC?
        + * A. Original release did target UltraSPARC only. Now SuperSPARC
        + *    version is provided along. Both version share bn_*comba[48]
        + *    implementations (see comment later in code for explanation).
        + *    But what's so special about this UltraSPARC implementation?
        + *    Why didn't I let compiler do the job? Trouble is that most of
        + *    available compilers (well, SC5.0 is the only exception) don't
        + *    attempt to take advantage of UltraSPARC's 64-bitness under
        + *    32-bit kernels even though it's perfectly possible (see next
        + *    question).
        + *
        + * Q. 64-bit registers under 32-bit kernels? Didn't you just say it
        + *    doesn't work?
        + * A. You can't adress *all* registers as 64-bit wide:-( The catch is
        + *    that you actually may rely upon %o0-%o5 and %g1-%g4 being fully
        + *    preserved if you're in a leaf function, i.e. such never calling
        + *    any other functions. All functions in this module are leaf and
        + *    10 registers is a handful. And as a matter of fact none-"comba"
        + *    routines don't require even that much and I could even afford to
        + *    not allocate own stack frame for 'em:-)
        + *
        + * Q. What about 64-bit kernels?
        + * A. What about 'em? Just kidding:-) Pure 64-bit version is currently
        + *    under evaluation and development...
        + *
        + * Q. What about shared libraries?
        + * A. What about 'em? Kidding again:-) Code does *not* contain any
        + *    code position dependencies and it's safe to include it into
        + *    shared library as is.
        + *
        + * Q. How much faster does it go?
        + * A. Do you have a good benchmark? In either case below is what I
        + *    experience with crypto/bn/expspeed.c test program:
        + *
        + *	v8plus module on U10/300MHz against bn_asm.c compiled with:
        + *
        + *	cc-5.0 -xarch=v8plus -xO5 -xdepend	+7-12%
        + *	cc-4.2 -xarch=v8plus -xO5 -xdepend	+25-35%
        + *	egcs-1.1.2 -mcpu=ultrasparc -O3		+35-45%
        + *
        + *	v8 module on SS10/60MHz against bn_asm.c compiled with:
        + *
        + *	cc-5.0 -xarch=v8 -xO5 -xdepend		+7-10%
        + *	cc-4.2 -xarch=v8 -xO5 -xdepend		+10%
        + *	egcs-1.1.2 -mv8 -O3			+35-45%
        + *
        + *    As you can see it's damn hard to beat the new Sun C compiler
        + *    and it's in first place GNU C users who will appreciate this
        + *    assembler implementation:-)	
        + */
        +
        +/*
        + * Revision history.
        + *
        + * 1.0	- initial release;
        + * 1.1	- new loop unrolling model(*);
        + *	- some more fine tuning;
        + * 1.2	- made gas friendly;
        + *	- updates to documentation concerning v9;
        + *	- new performance comparison matrix;
        + * 1.3	- fixed problem with /usr/ccs/lib/cpp;
        + * 1.4	- native V9 bn_*_comba[48] implementation (15% more efficient)
        + *	  resulting in slight overall performance kick;
        + *	- some retunes;
        + *	- support for GNU as added;
        + *
        + * (*)	Originally unrolled loop looked like this:
        + *	    for (;;) {
        + *		op(p+0); if (--n==0) break;
        + *		op(p+1); if (--n==0) break;
        + *		op(p+2); if (--n==0) break;
        + *		op(p+3); if (--n==0) break;
        + *		p+=4;
        + *	    }
        + *	I unroll according to following:
        + *	    while (n&~3) {
        + *		op(p+0); op(p+1); op(p+2); op(p+3);
        + *		p+=4; n=-4;
        + *	    }
        + *	    if (n) {
        + *		op(p+0); if (--n==0) return;
        + *		op(p+2); if (--n==0) return;
        + *		op(p+3); return;
        + *	    }
        + */
        +
        +#if defined(__SUNPRO_C) && defined(__sparcv9)
        +  /* They've said -xarch=v9 at command line */
        +  .register	%g2,#scratch
        +  .register	%g3,#scratch
        +# define	FRAME_SIZE	-192
        +#elif defined(__GNUC__) && defined(__arch64__)
        +  /* They've said -m64 at command line */
        +  .register	%g2,#scratch
        +  .register	%g3,#scratch
        +# define	FRAME_SIZE	-192
        +#else 
        +# define	FRAME_SIZE	-96
        +#endif 
        +/*
        + * GNU assembler can't stand stuw:-(
        + */
        +#define stuw st
        +
        +.section	".text",#alloc,#execinstr
        +.file		"bn_asm.sparc.v8plus.S"
        +
        +.align	32
        +
        +.global bn_mul_add_words
        +/*
        + * BN_ULONG bn_mul_add_words(rp,ap,num,w)
        + * BN_ULONG *rp,*ap;
        + * int num;
        + * BN_ULONG w;
        + */
        +bn_mul_add_words:
        +	sra	%o2,%g0,%o2	! signx %o2
        +	brgz,a	%o2,.L_bn_mul_add_words_proceed
        +	lduw	[%o1],%g2
        +	retl
        +	clr	%o0
        +	nop
        +	nop
        +	nop
        +
        +.L_bn_mul_add_words_proceed:
        +	srl	%o3,%g0,%o3	! clruw	%o3
        +	andcc	%o2,-4,%g0
        +	bz,pn	%icc,.L_bn_mul_add_words_tail
        +	clr	%o5
        +
        +.L_bn_mul_add_words_loop:	! wow! 32 aligned!
        +	lduw	[%o0],%g1
        +	lduw	[%o1+4],%g3
        +	mulx	%o3,%g2,%g2
        +	add	%g1,%o5,%o4
        +	nop
        +	add	%o4,%g2,%o4
        +	stuw	%o4,[%o0]
        +	srlx	%o4,32,%o5
        +
        +	lduw	[%o0+4],%g1
        +	lduw	[%o1+8],%g2
        +	mulx	%o3,%g3,%g3
        +	add	%g1,%o5,%o4
        +	dec	4,%o2
        +	add	%o4,%g3,%o4
        +	stuw	%o4,[%o0+4]
        +	srlx	%o4,32,%o5
        +
        +	lduw	[%o0+8],%g1
        +	lduw	[%o1+12],%g3
        +	mulx	%o3,%g2,%g2
        +	add	%g1,%o5,%o4
        +	inc	16,%o1
        +	add	%o4,%g2,%o4
        +	stuw	%o4,[%o0+8]
        +	srlx	%o4,32,%o5
        +
        +	lduw	[%o0+12],%g1
        +	mulx	%o3,%g3,%g3
        +	add	%g1,%o5,%o4
        +	inc	16,%o0
        +	add	%o4,%g3,%o4
        +	andcc	%o2,-4,%g0
        +	stuw	%o4,[%o0-4]
        +	srlx	%o4,32,%o5
        +	bnz,a,pt	%icc,.L_bn_mul_add_words_loop
        +	lduw	[%o1],%g2
        +
        +	brnz,a,pn	%o2,.L_bn_mul_add_words_tail
        +	lduw	[%o1],%g2
        +.L_bn_mul_add_words_return:
        +	retl
        +	mov	%o5,%o0
        +
        +.L_bn_mul_add_words_tail:
        +	lduw	[%o0],%g1
        +	mulx	%o3,%g2,%g2
        +	add	%g1,%o5,%o4
        +	dec	%o2
        +	add	%o4,%g2,%o4
        +	srlx	%o4,32,%o5
        +	brz,pt	%o2,.L_bn_mul_add_words_return
        +	stuw	%o4,[%o0]
        +
        +	lduw	[%o1+4],%g2
        +	lduw	[%o0+4],%g1
        +	mulx	%o3,%g2,%g2
        +	add	%g1,%o5,%o4
        +	dec	%o2
        +	add	%o4,%g2,%o4
        +	srlx	%o4,32,%o5
        +	brz,pt	%o2,.L_bn_mul_add_words_return
        +	stuw	%o4,[%o0+4]
        +
        +	lduw	[%o1+8],%g2
        +	lduw	[%o0+8],%g1
        +	mulx	%o3,%g2,%g2
        +	add	%g1,%o5,%o4
        +	add	%o4,%g2,%o4
        +	stuw	%o4,[%o0+8]
        +	retl
        +	srlx	%o4,32,%o0
        +
        +.type	bn_mul_add_words,#function
        +.size	bn_mul_add_words,(.-bn_mul_add_words)
        +
        +.align	32
        +
        +.global bn_mul_words
        +/*
        + * BN_ULONG bn_mul_words(rp,ap,num,w)
        + * BN_ULONG *rp,*ap;
        + * int num;
        + * BN_ULONG w;
        + */
        +bn_mul_words:
        +	sra	%o2,%g0,%o2	! signx %o2
        +	brgz,a	%o2,.L_bn_mul_words_proceeed
        +	lduw	[%o1],%g2
        +	retl
        +	clr	%o0
        +	nop
        +	nop
        +	nop
        +
        +.L_bn_mul_words_proceeed:
        +	srl	%o3,%g0,%o3	! clruw	%o3
        +	andcc	%o2,-4,%g0
        +	bz,pn	%icc,.L_bn_mul_words_tail
        +	clr	%o5
        +
        +.L_bn_mul_words_loop:		! wow! 32 aligned!
        +	lduw	[%o1+4],%g3
        +	mulx	%o3,%g2,%g2
        +	add	%g2,%o5,%o4
        +	nop
        +	stuw	%o4,[%o0]
        +	srlx	%o4,32,%o5
        +
        +	lduw	[%o1+8],%g2
        +	mulx	%o3,%g3,%g3
        +	add	%g3,%o5,%o4
        +	dec	4,%o2
        +	stuw	%o4,[%o0+4]
        +	srlx	%o4,32,%o5
        +
        +	lduw	[%o1+12],%g3
        +	mulx	%o3,%g2,%g2
        +	add	%g2,%o5,%o4
        +	inc	16,%o1
        +	stuw	%o4,[%o0+8]
        +	srlx	%o4,32,%o5
        +
        +	mulx	%o3,%g3,%g3
        +	add	%g3,%o5,%o4
        +	inc	16,%o0
        +	stuw	%o4,[%o0-4]
        +	srlx	%o4,32,%o5
        +	andcc	%o2,-4,%g0
        +	bnz,a,pt	%icc,.L_bn_mul_words_loop
        +	lduw	[%o1],%g2
        +	nop
        +	nop
        +
        +	brnz,a,pn	%o2,.L_bn_mul_words_tail
        +	lduw	[%o1],%g2
        +.L_bn_mul_words_return:
        +	retl
        +	mov	%o5,%o0
        +
        +.L_bn_mul_words_tail:
        +	mulx	%o3,%g2,%g2
        +	add	%g2,%o5,%o4
        +	dec	%o2
        +	srlx	%o4,32,%o5
        +	brz,pt	%o2,.L_bn_mul_words_return
        +	stuw	%o4,[%o0]
        +
        +	lduw	[%o1+4],%g2
        +	mulx	%o3,%g2,%g2
        +	add	%g2,%o5,%o4
        +	dec	%o2
        +	srlx	%o4,32,%o5
        +	brz,pt	%o2,.L_bn_mul_words_return
        +	stuw	%o4,[%o0+4]
        +
        +	lduw	[%o1+8],%g2
        +	mulx	%o3,%g2,%g2
        +	add	%g2,%o5,%o4
        +	stuw	%o4,[%o0+8]
        +	retl
        +	srlx	%o4,32,%o0
        +
        +.type	bn_mul_words,#function
        +.size	bn_mul_words,(.-bn_mul_words)
        +
        +.align  32
        +.global	bn_sqr_words
        +/*
        + * void bn_sqr_words(r,a,n)
        + * BN_ULONG *r,*a;
        + * int n;
        + */
        +bn_sqr_words:
        +	sra	%o2,%g0,%o2	! signx %o2
        +	brgz,a	%o2,.L_bn_sqr_words_proceeed
        +	lduw	[%o1],%g2
        +	retl
        +	clr	%o0
        +	nop
        +	nop
        +	nop
        +
        +.L_bn_sqr_words_proceeed:
        +	andcc	%o2,-4,%g0
        +	nop
        +	bz,pn	%icc,.L_bn_sqr_words_tail
        +	nop
        +
        +.L_bn_sqr_words_loop:		! wow! 32 aligned!
        +	lduw	[%o1+4],%g3
        +	mulx	%g2,%g2,%o4
        +	stuw	%o4,[%o0]
        +	srlx	%o4,32,%o5
        +	stuw	%o5,[%o0+4]
        +	nop
        +
        +	lduw	[%o1+8],%g2
        +	mulx	%g3,%g3,%o4
        +	dec	4,%o2
        +	stuw	%o4,[%o0+8]
        +	srlx	%o4,32,%o5
        +	stuw	%o5,[%o0+12]
        +
        +	lduw	[%o1+12],%g3
        +	mulx	%g2,%g2,%o4
        +	srlx	%o4,32,%o5
        +	stuw	%o4,[%o0+16]
        +	inc	16,%o1
        +	stuw	%o5,[%o0+20]
        +
        +	mulx	%g3,%g3,%o4
        +	inc	32,%o0
        +	stuw	%o4,[%o0-8]
        +	srlx	%o4,32,%o5
        +	andcc	%o2,-4,%g2
        +	stuw	%o5,[%o0-4]
        +	bnz,a,pt	%icc,.L_bn_sqr_words_loop
        +	lduw	[%o1],%g2
        +	nop
        +
        +	brnz,a,pn	%o2,.L_bn_sqr_words_tail
        +	lduw	[%o1],%g2
        +.L_bn_sqr_words_return:
        +	retl
        +	clr	%o0
        +
        +.L_bn_sqr_words_tail:
        +	mulx	%g2,%g2,%o4
        +	dec	%o2
        +	stuw	%o4,[%o0]
        +	srlx	%o4,32,%o5
        +	brz,pt	%o2,.L_bn_sqr_words_return
        +	stuw	%o5,[%o0+4]
        +
        +	lduw	[%o1+4],%g2
        +	mulx	%g2,%g2,%o4
        +	dec	%o2
        +	stuw	%o4,[%o0+8]
        +	srlx	%o4,32,%o5
        +	brz,pt	%o2,.L_bn_sqr_words_return
        +	stuw	%o5,[%o0+12]
        +
        +	lduw	[%o1+8],%g2
        +	mulx	%g2,%g2,%o4
        +	srlx	%o4,32,%o5
        +	stuw	%o4,[%o0+16]
        +	stuw	%o5,[%o0+20]
        +	retl
        +	clr	%o0
        +
        +.type	bn_sqr_words,#function
        +.size	bn_sqr_words,(.-bn_sqr_words)
        +
        +.align	32
        +.global bn_div_words
        +/*
        + * BN_ULONG bn_div_words(h,l,d)
        + * BN_ULONG h,l,d;
        + */
        +bn_div_words:
        +	sllx	%o0,32,%o0
        +	or	%o0,%o1,%o0
        +	udivx	%o0,%o2,%o0
        +	retl
        +	srl	%o0,%g0,%o0	! clruw	%o0
        +
        +.type	bn_div_words,#function
        +.size	bn_div_words,(.-bn_div_words)
        +
        +.align	32
        +
        +.global bn_add_words
        +/*
        + * BN_ULONG bn_add_words(rp,ap,bp,n)
        + * BN_ULONG *rp,*ap,*bp;
        + * int n;
        + */
        +bn_add_words:
        +	sra	%o3,%g0,%o3	! signx %o3
        +	brgz,a	%o3,.L_bn_add_words_proceed
        +	lduw	[%o1],%o4
        +	retl
        +	clr	%o0
        +
        +.L_bn_add_words_proceed:
        +	andcc	%o3,-4,%g0
        +	bz,pn	%icc,.L_bn_add_words_tail
        +	addcc	%g0,0,%g0	! clear carry flag
        +
        +.L_bn_add_words_loop:		! wow! 32 aligned!
        +	dec	4,%o3
        +	lduw	[%o2],%o5
        +	lduw	[%o1+4],%g1
        +	lduw	[%o2+4],%g2
        +	lduw	[%o1+8],%g3
        +	lduw	[%o2+8],%g4
        +	addccc	%o5,%o4,%o5
        +	stuw	%o5,[%o0]
        +
        +	lduw	[%o1+12],%o4
        +	lduw	[%o2+12],%o5
        +	inc	16,%o1
        +	addccc	%g1,%g2,%g1
        +	stuw	%g1,[%o0+4]
        +	
        +	inc	16,%o2
        +	addccc	%g3,%g4,%g3
        +	stuw	%g3,[%o0+8]
        +
        +	inc	16,%o0
        +	addccc	%o5,%o4,%o5
        +	stuw	%o5,[%o0-4]
        +	and	%o3,-4,%g1
        +	brnz,a,pt	%g1,.L_bn_add_words_loop
        +	lduw	[%o1],%o4
        +
        +	brnz,a,pn	%o3,.L_bn_add_words_tail
        +	lduw	[%o1],%o4
        +.L_bn_add_words_return:
        +	clr	%o0
        +	retl
        +	movcs	%icc,1,%o0
        +	nop
        +
        +.L_bn_add_words_tail:
        +	lduw	[%o2],%o5
        +	dec	%o3
        +	addccc	%o5,%o4,%o5
        +	brz,pt	%o3,.L_bn_add_words_return
        +	stuw	%o5,[%o0]
        +
        +	lduw	[%o1+4],%o4
        +	lduw	[%o2+4],%o5
        +	dec	%o3
        +	addccc	%o5,%o4,%o5
        +	brz,pt	%o3,.L_bn_add_words_return
        +	stuw	%o5,[%o0+4]
        +
        +	lduw	[%o1+8],%o4
        +	lduw	[%o2+8],%o5
        +	addccc	%o5,%o4,%o5
        +	stuw	%o5,[%o0+8]
        +	clr	%o0
        +	retl
        +	movcs	%icc,1,%o0
        +
        +.type	bn_add_words,#function
        +.size	bn_add_words,(.-bn_add_words)
        +
        +.global bn_sub_words
        +/*
        + * BN_ULONG bn_sub_words(rp,ap,bp,n)
        + * BN_ULONG *rp,*ap,*bp;
        + * int n;
        + */
        +bn_sub_words:
        +	sra	%o3,%g0,%o3	! signx %o3
        +	brgz,a	%o3,.L_bn_sub_words_proceed
        +	lduw	[%o1],%o4
        +	retl
        +	clr	%o0
        +
        +.L_bn_sub_words_proceed:
        +	andcc	%o3,-4,%g0
        +	bz,pn	%icc,.L_bn_sub_words_tail
        +	addcc	%g0,0,%g0	! clear carry flag
        +
        +.L_bn_sub_words_loop:		! wow! 32 aligned!
        +	dec	4,%o3
        +	lduw	[%o2],%o5
        +	lduw	[%o1+4],%g1
        +	lduw	[%o2+4],%g2
        +	lduw	[%o1+8],%g3
        +	lduw	[%o2+8],%g4
        +	subccc	%o4,%o5,%o5
        +	stuw	%o5,[%o0]
        +
        +	lduw	[%o1+12],%o4
        +	lduw	[%o2+12],%o5
        +	inc	16,%o1
        +	subccc	%g1,%g2,%g2
        +	stuw	%g2,[%o0+4]
        +
        +	inc	16,%o2
        +	subccc	%g3,%g4,%g4
        +	stuw	%g4,[%o0+8]
        +
        +	inc	16,%o0
        +	subccc	%o4,%o5,%o5
        +	stuw	%o5,[%o0-4]
        +	and	%o3,-4,%g1
        +	brnz,a,pt	%g1,.L_bn_sub_words_loop
        +	lduw	[%o1],%o4
        +
        +	brnz,a,pn	%o3,.L_bn_sub_words_tail
        +	lduw	[%o1],%o4
        +.L_bn_sub_words_return:
        +	clr	%o0
        +	retl
        +	movcs	%icc,1,%o0
        +	nop
        +
        +.L_bn_sub_words_tail:		! wow! 32 aligned!
        +	lduw	[%o2],%o5
        +	dec	%o3
        +	subccc	%o4,%o5,%o5
        +	brz,pt	%o3,.L_bn_sub_words_return
        +	stuw	%o5,[%o0]
        +
        +	lduw	[%o1+4],%o4
        +	lduw	[%o2+4],%o5
        +	dec	%o3
        +	subccc	%o4,%o5,%o5
        +	brz,pt	%o3,.L_bn_sub_words_return
        +	stuw	%o5,[%o0+4]
        +
        +	lduw	[%o1+8],%o4
        +	lduw	[%o2+8],%o5
        +	subccc	%o4,%o5,%o5
        +	stuw	%o5,[%o0+8]
        +	clr	%o0
        +	retl
        +	movcs	%icc,1,%o0
        +
        +.type	bn_sub_words,#function
        +.size	bn_sub_words,(.-bn_sub_words)
        +
        +/*
        + * Code below depends on the fact that upper parts of the %l0-%l7
        + * and %i0-%i7 are zeroed by kernel after context switch. In
        + * previous versions this comment stated that "the trouble is that
        + * it's not feasible to implement the mumbo-jumbo in less V9
        + * instructions:-(" which apparently isn't true thanks to
        + * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement
        + * results not from the shorter code, but from elimination of
        + * multicycle none-pairable 'rd %y,%rd' instructions.
        + *
        + *							Andy.
        + */
        +
        +/*
        + * Here is register usage map for *all* routines below.
        + */
        +#define t_1	%o0
        +#define	t_2	%o1
        +#define c_12	%o2
        +#define c_3	%o3
        +
        +#define ap(I)	[%i1+4*I]
        +#define bp(I)	[%i2+4*I]
        +#define rp(I)	[%i0+4*I]
        +
        +#define	a_0	%l0
        +#define	a_1	%l1
        +#define	a_2	%l2
        +#define	a_3	%l3
        +#define	a_4	%l4
        +#define	a_5	%l5
        +#define	a_6	%l6
        +#define	a_7	%l7
        +
        +#define	b_0	%i3
        +#define	b_1	%i4
        +#define	b_2	%i5
        +#define	b_3	%o4
        +#define	b_4	%o5
        +#define	b_5	%o7
        +#define	b_6	%g1
        +#define	b_7	%g4
        +
        +.align	32
        +.global bn_mul_comba8
        +/*
        + * void bn_mul_comba8(r,a,b)
        + * BN_ULONG *r,*a,*b;
        + */
        +bn_mul_comba8:
        +	save	%sp,FRAME_SIZE,%sp
        +	mov	1,t_2
        +	lduw	ap(0),a_0
        +	sllx	t_2,32,t_2
        +	lduw	bp(0),b_0	!=
        +	lduw	bp(1),b_1
        +	mulx	a_0,b_0,t_1	!mul_add_c(a[0],b[0],c1,c2,c3);
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(0)	!=!r[0]=c1;
        +
        +	lduw	ap(1),a_1
        +	mulx	a_0,b_1,t_1	!mul_add_c(a[0],b[1],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3		!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(2),a_2
        +	mulx	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(1)	!r[1]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
        +	addcc	c_12,t_1,c_12	!=
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	bp(2),b_2	!=
        +	mulx	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	lduw	bp(3),b_3
        +	mulx	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(2)	!r[2]=c3;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_1,b_2,t_1	!=!mul_add_c(a[1],b[2],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	lduw	ap(3),a_3
        +	mulx	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
        +	addcc	c_12,t_1,c_12	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(4),a_4
        +	mulx	a_3,b_0,t_1	!=!mul_add_c(a[3],b[0],c1,c2,c3);!=
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(3)	!r[3]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_4,b_0,t_1	!mul_add_c(a[4],b[0],c2,c3,c1);
        +	addcc	c_12,t_1,c_12	!=
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_1,t_1	!=!mul_add_c(a[3],b[1],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_2,b_2,t_1	!=!mul_add_c(a[2],b[2],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	bp(4),b_4	!=
        +	mulx	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	lduw	bp(5),b_5
        +	mulx	a_0,b_4,t_1	!mul_add_c(a[0],b[4],c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(4)	!r[4]=c2;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_0,b_5,t_1	!mul_add_c(a[0],b[5],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_1,b_4,t_1	!mul_add_c(a[1],b[4],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	lduw	ap(5),a_5
        +	mulx	a_4,b_1,t_1	!mul_add_c(a[4],b[1],c3,c1,c2);
        +	addcc	c_12,t_1,c_12	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(6),a_6
        +	mulx	a_5,b_0,t_1	!=!mul_add_c(a[5],b[0],c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(5)	!r[5]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_6,b_0,t_1	!mul_add_c(a[6],b[0],c1,c2,c3);
        +	addcc	c_12,t_1,c_12	!=
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_5,b_1,t_1	!=!mul_add_c(a[5],b[1],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_4,b_2,t_1	!=!mul_add_c(a[4],b[2],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_3,t_1	!=!mul_add_c(a[3],b[3],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_2,b_4,t_1	!=!mul_add_c(a[2],b[4],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	bp(6),b_6	!=
        +	mulx	a_1,b_5,t_1	!mul_add_c(a[1],b[5],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	lduw	bp(7),b_7
        +	mulx	a_0,b_6,t_1	!mul_add_c(a[0],b[6],c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(6)	!r[6]=c1;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_0,b_7,t_1	!mul_add_c(a[0],b[7],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_1,b_6,t_1	!mul_add_c(a[1],b[6],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_2,b_5,t_1	!mul_add_c(a[2],b[5],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_4,t_1	!mul_add_c(a[3],b[4],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_4,b_3,t_1	!mul_add_c(a[4],b[3],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_5,b_2,t_1	!mul_add_c(a[5],b[2],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	lduw	ap(7),a_7
        +	mulx	a_6,b_1,t_1	!=!mul_add_c(a[6],b[1],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_7,b_0,t_1	!=!mul_add_c(a[7],b[0],c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(7)	!r[7]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_7,b_1,t_1	!=!mul_add_c(a[7],b[1],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_6,b_2,t_1	!mul_add_c(a[6],b[2],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_5,b_3,t_1	!mul_add_c(a[5],b[3],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_4,b_4,t_1	!mul_add_c(a[4],b[4],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_3,b_5,t_1	!mul_add_c(a[3],b[5],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_2,b_6,t_1	!mul_add_c(a[2],b[6],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_1,b_7,t_1	!mul_add_c(a[1],b[7],c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(8)	!r[8]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,b_7,t_1	!=!mul_add_c(a[2],b[7],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	mulx	a_3,b_6,t_1	!mul_add_c(a[3],b[6],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_4,b_5,t_1	!mul_add_c(a[4],b[5],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_5,b_4,t_1	!mul_add_c(a[5],b[4],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_6,b_3,t_1	!mul_add_c(a[6],b[3],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_7,b_2,t_1	!mul_add_c(a[7],b[2],c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(9)	!r[9]=c1;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_7,b_3,t_1	!mul_add_c(a[7],b[3],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_6,b_4,t_1	!mul_add_c(a[6],b[4],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_5,b_5,t_1	!mul_add_c(a[5],b[5],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_4,b_6,t_1	!mul_add_c(a[4],b[6],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_7,t_1	!mul_add_c(a[3],b[7],c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(10)	!r[10]=c2;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_4,b_7,t_1	!mul_add_c(a[4],b[7],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_5,b_6,t_1	!mul_add_c(a[5],b[6],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_6,b_5,t_1	!mul_add_c(a[6],b[5],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_7,b_4,t_1	!mul_add_c(a[7],b[4],c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(11)	!r[11]=c3;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_7,b_5,t_1	!mul_add_c(a[7],b[5],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_6,b_6,t_1	!mul_add_c(a[6],b[6],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_5,b_7,t_1	!mul_add_c(a[5],b[7],c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(12)	!r[12]=c1;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_6,b_7,t_1	!mul_add_c(a[6],b[7],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_7,b_6,t_1	!mul_add_c(a[7],b[6],c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	st	t_1,rp(13)	!r[13]=c2;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_7,b_7,t_1	!mul_add_c(a[7],b[7],c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(14)	!r[14]=c3;
        +	stuw	c_12,rp(15)	!r[15]=c1;
        +
        +	ret
        +	restore	%g0,%g0,%o0	!=
        +
        +.type	bn_mul_comba8,#function
        +.size	bn_mul_comba8,(.-bn_mul_comba8)
        +
        +.align	32
        +
        +.global bn_mul_comba4
        +/*
        + * void bn_mul_comba4(r,a,b)
        + * BN_ULONG *r,*a,*b;
        + */
        +bn_mul_comba4:
        +	save	%sp,FRAME_SIZE,%sp
        +	lduw	ap(0),a_0
        +	mov	1,t_2
        +	lduw	bp(0),b_0
        +	sllx	t_2,32,t_2	!=
        +	lduw	bp(1),b_1
        +	mulx	a_0,b_0,t_1	!mul_add_c(a[0],b[0],c1,c2,c3);
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(0)	!=!r[0]=c1;
        +
        +	lduw	ap(1),a_1
        +	mulx	a_0,b_1,t_1	!mul_add_c(a[0],b[1],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3		!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(2),a_2
        +	mulx	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(1)	!r[1]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
        +	addcc	c_12,t_1,c_12	!=
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	bp(2),b_2	!=
        +	mulx	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3	!=
        +	lduw	bp(3),b_3
        +	mulx	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(2)	!r[2]=c3;
        +	or	c_12,c_3,c_12	!=
        +
        +	mulx	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	mulx	a_1,b_2,t_1	!mul_add_c(a[1],b[2],c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8	!=
        +	add	c_3,t_2,c_3
        +	lduw	ap(3),a_3
        +	mulx	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
        +	addcc	c_12,t_1,c_12	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_0,t_1	!mul_add_c(a[3],b[0],c1,c2,c3);!=
        +	addcc	c_12,t_1,t_1	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(3)	!=!r[3]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3		!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_2,b_2,t_1	!mul_add_c(a[2],b[2],c2,c3,c1);
        +	addcc	c_12,t_1,c_12	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
        +	addcc	c_12,t_1,t_1	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(4)	!=!r[4]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3		!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
        +	addcc	c_12,t_1,t_1	!=
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(5)	!=!r[5]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	srlx	t_1,32,c_12	!=
        +	stuw	t_1,rp(6)	!r[6]=c1;
        +	stuw	c_12,rp(7)	!r[7]=c2;
        +	
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_mul_comba4,#function
        +.size	bn_mul_comba4,(.-bn_mul_comba4)
        +
        +.align	32
        +
        +.global bn_sqr_comba8
        +bn_sqr_comba8:
        +	save	%sp,FRAME_SIZE,%sp
        +	mov	1,t_2
        +	lduw	ap(0),a_0
        +	sllx	t_2,32,t_2
        +	lduw	ap(1),a_1
        +	mulx	a_0,a_0,t_1	!sqr_add_c(a,0,c1,c2,c3);
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(0)	!r[0]=c1;
        +
        +	lduw	ap(2),a_2
        +	mulx	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(1)	!r[1]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(3),a_3
        +	mulx	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(2)	!r[2]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(4),a_4
        +	mulx	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	st	t_1,rp(3)	!r[3]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_4,a_0,t_1	!sqr_add_c2(a,4,0,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(5),a_5
        +	mulx	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(4)	!r[4]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_0,a_5,t_1	!sqr_add_c2(a,5,0,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_1,a_4,t_1	!sqr_add_c2(a,4,1,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(6),a_6
        +	mulx	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(5)	!r[5]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_6,a_0,t_1	!sqr_add_c2(a,6,0,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_5,a_1,t_1	!sqr_add_c2(a,5,1,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_4,a_2,t_1	!sqr_add_c2(a,4,2,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(7),a_7
        +	mulx	a_3,a_3,t_1	!=!sqr_add_c(a,3,c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(6)	!r[6]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_0,a_7,t_1	!sqr_add_c2(a,7,0,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_1,a_6,t_1	!sqr_add_c2(a,6,1,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_2,a_5,t_1	!sqr_add_c2(a,5,2,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,a_4,t_1	!sqr_add_c2(a,4,3,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(7)	!r[7]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_7,a_1,t_1	!sqr_add_c2(a,7,1,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_6,a_2,t_1	!sqr_add_c2(a,6,2,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_5,a_3,t_1	!sqr_add_c2(a,5,3,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_4,a_4,t_1	!sqr_add_c(a,4,c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(8)	!r[8]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,a_7,t_1	!sqr_add_c2(a,7,2,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_3,a_6,t_1	!sqr_add_c2(a,6,3,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_4,a_5,t_1	!sqr_add_c2(a,5,4,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(9)	!r[9]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_7,a_3,t_1	!sqr_add_c2(a,7,3,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_6,a_4,t_1	!sqr_add_c2(a,6,4,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_5,a_5,t_1	!sqr_add_c(a,5,c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(10)	!r[10]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_4,a_7,t_1	!sqr_add_c2(a,7,4,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_5,a_6,t_1	!sqr_add_c2(a,6,5,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(11)	!r[11]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_7,a_5,t_1	!sqr_add_c2(a,7,5,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_6,a_6,t_1	!sqr_add_c(a,6,c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(12)	!r[12]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_6,a_7,t_1	!sqr_add_c2(a,7,6,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(13)	!r[13]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_7,a_7,t_1	!sqr_add_c(a,7,c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(14)	!r[14]=c3;
        +	stuw	c_12,rp(15)	!r[15]=c1;
        +
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_sqr_comba8,#function
        +.size	bn_sqr_comba8,(.-bn_sqr_comba8)
        +
        +.align	32
        +
        +.global bn_sqr_comba4
        +/*
        + * void bn_sqr_comba4(r,a)
        + * BN_ULONG *r,*a;
        + */
        +bn_sqr_comba4:
        +	save	%sp,FRAME_SIZE,%sp
        +	mov	1,t_2
        +	lduw	ap(0),a_0
        +	sllx	t_2,32,t_2
        +	lduw	ap(1),a_1
        +	mulx	a_0,a_0,t_1	!sqr_add_c(a,0,c1,c2,c3);
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(0)	!r[0]=c1;
        +
        +	lduw	ap(2),a_2
        +	mulx	a_0,a_1,t_1	!sqr_add_c2(a,1,0,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(1)	!r[1]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	lduw	ap(3),a_3
        +	mulx	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(2)	!r[2]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(3)	!r[3]=c1;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,c_12
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	mulx	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(4)	!r[4]=c2;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
        +	addcc	c_12,t_1,c_12
        +	clr	c_3
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	addcc	c_12,t_1,t_1
        +	bcs,a	%xcc,.+8
        +	add	c_3,t_2,c_3
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(5)	!r[5]=c3;
        +	or	c_12,c_3,c_12
        +
        +	mulx	a_3,a_3,t_1	!sqr_add_c(a,3,c1,c2,c3);
        +	addcc	c_12,t_1,t_1
        +	srlx	t_1,32,c_12
        +	stuw	t_1,rp(6)	!r[6]=c1;
        +	stuw	c_12,rp(7)	!r[7]=c2;
        +	
        +	ret
        +	restore	%g0,%g0,%o0
        +
        +.type	bn_sqr_comba4,#function
        +.size	bn_sqr_comba4,(.-bn_sqr_comba4)
        +
        +.align	32
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl
        new file mode 100644
        index 000000000..b8fb1e8a2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl
        @@ -0,0 +1,606 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# December 2005
        +#
        +# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
        +# for undertaken effort are multiple. First of all, UltraSPARC is not
        +# the whole SPARCv9 universe and other VIS-free implementations deserve
        +# optimized code as much. Secondly, newly introduced UltraSPARC T1,
        +# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes,
        +# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
        +# several integrated RSA/DSA accelerator circuits accessible through
        +# kernel driver [only(*)], but having decent user-land software
        +# implementation is important too. Finally, reasons like desire to
        +# experiment with dedicated squaring procedure. Yes, this module
        +# implements one, because it was easiest to draft it in SPARCv9
        +# instructions...
        +
        +# (*)	Engine accessing the driver in question is on my TODO list.
        +#	For reference, acceleator is estimated to give 6 to 10 times
        +#	improvement on single-threaded RSA sign. It should be noted
        +#	that 6-10x improvement coefficient does not actually mean
        +#	something extraordinary in terms of absolute [single-threaded]
        +#	performance, as SPARCv9 instruction set is by all means least
        +#	suitable for high performance crypto among other 64 bit
        +#	platforms. 6-10x factor simply places T1 in same performance
        +#	domain as say AMD64 and IA-64. Improvement of RSA verify don't
        +#	appear impressive at all, but it's the sign operation which is
        +#	far more critical/interesting.
        +
        +# You might notice that inner loops are modulo-scheduled:-) This has
        +# essentially negligible impact on UltraSPARC performance, it's
        +# Fujitsu SPARC64 V users who should notice and hopefully appreciate
        +# the advantage... Currently this module surpasses sparcv9a-mont.pl
        +# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
        +# module still have hidden potential [see TODO list there], which is
        +# estimated to be larger than 20%...
        +
        +# int bn_mul_mont(
        +$rp="%i0";	# BN_ULONG *rp,
        +$ap="%i1";	# const BN_ULONG *ap,
        +$bp="%i2";	# const BN_ULONG *bp,
        +$np="%i3";	# const BN_ULONG *np,
        +$n0="%i4";	# const BN_ULONG *n0,
        +$num="%i5";	# int num);
        +
        +$bits=32;
        +for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +if ($bits==64)	{ $bias=2047; $frame=192; }
        +else		{ $bias=0;    $frame=128; }
        +
        +$car0="%o0";
        +$car1="%o1";
        +$car2="%o2";	# 1 bit
        +$acc0="%o3";
        +$acc1="%o4";
        +$mask="%g1";	# 32 bits, what a waste...
        +$tmp0="%g4";
        +$tmp1="%g5";
        +
        +$i="%l0";
        +$j="%l1";
        +$mul0="%l2";
        +$mul1="%l3";
        +$tp="%l4";
        +$apj="%l5";
        +$npj="%l6";
        +$tpj="%l7";
        +
        +$fname="bn_mul_mont_int";
        +
        +$code=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.global	$fname
        +.align	32
        +$fname:
        +	cmp	%o5,4			! 128 bits minimum
        +	bge,pt	%icc,.Lenter
        +	sethi	%hi(0xffffffff),$mask
        +	retl
        +	clr	%o0
        +.align	32
        +.Lenter:
        +	save	%sp,-$frame,%sp
        +	sll	$num,2,$num		! num*=4
        +	or	$mask,%lo(0xffffffff),$mask
        +	ld	[$n0],$n0
        +	cmp	$ap,$bp
        +	and	$num,$mask,$num
        +	ld	[$bp],$mul0		! bp[0]
        +	nop
        +
        +	add	%sp,$bias,%o7		! real top of stack
        +	ld	[$ap],$car0		! ap[0] ! redundant in squaring context
        +	sub	%o7,$num,%o7
        +	ld	[$ap+4],$apj		! ap[1]
        +	and	%o7,-1024,%o7
        +	ld	[$np],$car1		! np[0]
        +	sub	%o7,$bias,%sp		! alloca
        +	ld	[$np+4],$npj		! np[1]
        +	be,pt	`$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont
        +	mov	12,$j
        +
        +	mulx	$car0,$mul0,$car0	! ap[0]*bp[0]
        +	mulx	$apj,$mul0,$tmp0	!prologue! ap[1]*bp[0]
        +	and	$car0,$mask,$acc0
        +	add	%sp,$bias+$frame,$tp
        +	ld	[$ap+8],$apj		!prologue!
        +
        +	mulx	$n0,$acc0,$mul1		! "t[0]"*n0
        +	and	$mul1,$mask,$mul1
        +
        +	mulx	$car1,$mul1,$car1	! np[0]*"t[0]"*n0
        +	mulx	$npj,$mul1,$acc1	!prologue! np[1]*"t[0]"*n0
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	ld	[$np+8],$npj		!prologue!
        +	srlx	$car1,32,$car1
        +	mov	$tmp0,$acc0		!prologue!
        +
        +.L1st:
        +	mulx	$apj,$mul0,$tmp0
        +	mulx	$npj,$mul1,$tmp1
        +	add	$acc0,$car0,$car0
        +	ld	[$ap+$j],$apj		! ap[j]
        +	and	$car0,$mask,$acc0
        +	add	$acc1,$car1,$car1
        +	ld	[$np+$j],$npj		! np[j]
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	add	$j,4,$j			! j++
        +	mov	$tmp0,$acc0
        +	st	$car1,[$tp]
        +	cmp	$j,$num
        +	mov	$tmp1,$acc1
        +	srlx	$car1,32,$car1
        +	bl	%icc,.L1st
        +	add	$tp,4,$tp		! tp++
        +!.L1st
        +
        +	mulx	$apj,$mul0,$tmp0	!epilogue!
        +	mulx	$npj,$mul1,$tmp1
        +	add	$acc0,$car0,$car0
        +	and	$car0,$mask,$acc0
        +	add	$acc1,$car1,$car1
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp]
        +	srlx	$car1,32,$car1
        +
        +	add	$tmp0,$car0,$car0
        +	and	$car0,$mask,$acc0
        +	add	$tmp1,$car1,$car1
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp+4]
        +	srlx	$car1,32,$car1
        +
        +	add	$car0,$car1,$car1
        +	st	$car1,[$tp+8]
        +	srlx	$car1,32,$car2
        +
        +	mov	4,$i			! i++
        +	ld	[$bp+4],$mul0		! bp[1]
        +.Louter:
        +	add	%sp,$bias+$frame,$tp
        +	ld	[$ap],$car0		! ap[0]
        +	ld	[$ap+4],$apj		! ap[1]
        +	ld	[$np],$car1		! np[0]
        +	ld	[$np+4],$npj		! np[1]
        +	ld	[$tp],$tmp1		! tp[0]
        +	ld	[$tp+4],$tpj		! tp[1]
        +	mov	12,$j
        +
        +	mulx	$car0,$mul0,$car0
        +	mulx	$apj,$mul0,$tmp0	!prologue!
        +	add	$tmp1,$car0,$car0
        +	ld	[$ap+8],$apj		!prologue!
        +	and	$car0,$mask,$acc0
        +
        +	mulx	$n0,$acc0,$mul1
        +	and	$mul1,$mask,$mul1
        +
        +	mulx	$car1,$mul1,$car1
        +	mulx	$npj,$mul1,$acc1	!prologue!
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	ld	[$np+8],$npj		!prologue!
        +	srlx	$car1,32,$car1
        +	mov	$tmp0,$acc0		!prologue!
        +
        +.Linner:
        +	mulx	$apj,$mul0,$tmp0
        +	mulx	$npj,$mul1,$tmp1
        +	add	$tpj,$car0,$car0
        +	ld	[$ap+$j],$apj		! ap[j]
        +	add	$acc0,$car0,$car0
        +	add	$acc1,$car1,$car1
        +	ld	[$np+$j],$npj		! np[j]
        +	and	$car0,$mask,$acc0
        +	ld	[$tp+8],$tpj		! tp[j]
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	add	$j,4,$j			! j++
        +	mov	$tmp0,$acc0
        +	st	$car1,[$tp]		! tp[j-1]
        +	srlx	$car1,32,$car1
        +	mov	$tmp1,$acc1
        +	cmp	$j,$num
        +	bl	%icc,.Linner
        +	add	$tp,4,$tp		! tp++
        +!.Linner
        +
        +	mulx	$apj,$mul0,$tmp0	!epilogue!
        +	mulx	$npj,$mul1,$tmp1
        +	add	$tpj,$car0,$car0
        +	add	$acc0,$car0,$car0
        +	ld	[$tp+8],$tpj		! tp[j]
        +	and	$car0,$mask,$acc0
        +	add	$acc1,$car1,$car1
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp]		! tp[j-1]
        +	srlx	$car1,32,$car1
        +
        +	add	$tpj,$car0,$car0
        +	add	$tmp0,$car0,$car0
        +	and	$car0,$mask,$acc0
        +	add	$tmp1,$car1,$car1
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp+4]		! tp[j-1]
        +	srlx	$car0,32,$car0
        +	add	$i,4,$i			! i++
        +	srlx	$car1,32,$car1
        +
        +	add	$car0,$car1,$car1
        +	cmp	$i,$num
        +	add	$car2,$car1,$car1
        +	st	$car1,[$tp+8]
        +
        +	srlx	$car1,32,$car2
        +	bl,a	%icc,.Louter
        +	ld	[$bp+$i],$mul0		! bp[i]
        +!.Louter
        +
        +	add	$tp,12,$tp
        +
        +.Ltail:
        +	add	$np,$num,$np
        +	add	$rp,$num,$rp
        +	mov	$tp,$ap
        +	sub	%g0,$num,%o7		! k=-num
        +	ba	.Lsub
        +	subcc	%g0,%g0,%g0		! clear %icc.c
        +.align	16
        +.Lsub:
        +	ld	[$tp+%o7],%o0
        +	ld	[$np+%o7],%o1
        +	subccc	%o0,%o1,%o1		! tp[j]-np[j]
        +	add	$rp,%o7,$i
        +	add	%o7,4,%o7
        +	brnz	%o7,.Lsub
        +	st	%o1,[$i]
        +	subc	$car2,0,$car2		! handle upmost overflow bit
        +	and	$tp,$car2,$ap
        +	andn	$rp,$car2,$np
        +	or	$ap,$np,$ap
        +	sub	%g0,$num,%o7
        +
        +.Lcopy:
        +	ld	[$ap+%o7],%o0		! copy or in-place refresh
        +	st	%g0,[$tp+%o7]		! zap tp
        +	st	%o0,[$rp+%o7]
        +	add	%o7,4,%o7
        +	brnz	%o7,.Lcopy
        +	nop
        +	mov	1,%i0
        +	ret
        +	restore
        +___
        +
        +########
        +######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
        +######## code without following dedicated squaring procedure.
        +########
        +$sbit="%i2";		# re-use $bp!
        +
        +$code.=<<___;
        +.align	32
        +.Lbn_sqr_mont:
        +	mulx	$mul0,$mul0,$car0		! ap[0]*ap[0]
        +	mulx	$apj,$mul0,$tmp0		!prologue!
        +	and	$car0,$mask,$acc0
        +	add	%sp,$bias+$frame,$tp
        +	ld	[$ap+8],$apj			!prologue!
        +
        +	mulx	$n0,$acc0,$mul1			! "t[0]"*n0
        +	srlx	$car0,32,$car0
        +	and	$mul1,$mask,$mul1
        +
        +	mulx	$car1,$mul1,$car1		! np[0]*"t[0]"*n0
        +	mulx	$npj,$mul1,$acc1		!prologue!
        +	and	$car0,1,$sbit
        +	ld	[$np+8],$npj			!prologue!
        +	srlx	$car0,1,$car0
        +	add	$acc0,$car1,$car1
        +	srlx	$car1,32,$car1
        +	mov	$tmp0,$acc0			!prologue!
        +
        +.Lsqr_1st:
        +	mulx	$apj,$mul0,$tmp0
        +	mulx	$npj,$mul1,$tmp1
        +	add	$acc0,$car0,$car0		! ap[j]*a0+c0
        +	add	$acc1,$car1,$car1
        +	ld	[$ap+$j],$apj			! ap[j]
        +	and	$car0,$mask,$acc0
        +	ld	[$np+$j],$npj			! np[j]
        +	srlx	$car0,32,$car0
        +	add	$acc0,$acc0,$acc0
        +	or	$sbit,$acc0,$acc0
        +	mov	$tmp1,$acc1
        +	srlx	$acc0,32,$sbit
        +	add	$j,4,$j				! j++
        +	and	$acc0,$mask,$acc0
        +	cmp	$j,$num
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp]
        +	mov	$tmp0,$acc0
        +	srlx	$car1,32,$car1
        +	bl	%icc,.Lsqr_1st
        +	add	$tp,4,$tp			! tp++
        +!.Lsqr_1st
        +
        +	mulx	$apj,$mul0,$tmp0		! epilogue
        +	mulx	$npj,$mul1,$tmp1
        +	add	$acc0,$car0,$car0		! ap[j]*a0+c0
        +	add	$acc1,$car1,$car1
        +	and	$car0,$mask,$acc0
        +	srlx	$car0,32,$car0
        +	add	$acc0,$acc0,$acc0
        +	or	$sbit,$acc0,$acc0
        +	srlx	$acc0,32,$sbit
        +	and	$acc0,$mask,$acc0
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp]
        +	srlx	$car1,32,$car1
        +
        +	add	$tmp0,$car0,$car0		! ap[j]*a0+c0
        +	add	$tmp1,$car1,$car1
        +	and	$car0,$mask,$acc0
        +	srlx	$car0,32,$car0
        +	add	$acc0,$acc0,$acc0
        +	or	$sbit,$acc0,$acc0
        +	srlx	$acc0,32,$sbit
        +	and	$acc0,$mask,$acc0
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp+4]
        +	srlx	$car1,32,$car1
        +
        +	add	$car0,$car0,$car0
        +	or	$sbit,$car0,$car0
        +	add	$car0,$car1,$car1
        +	st	$car1,[$tp+8]
        +	srlx	$car1,32,$car2
        +
        +	ld	[%sp+$bias+$frame],$tmp0	! tp[0]
        +	ld	[%sp+$bias+$frame+4],$tmp1	! tp[1]
        +	ld	[%sp+$bias+$frame+8],$tpj	! tp[2]
        +	ld	[$ap+4],$mul0			! ap[1]
        +	ld	[$ap+8],$apj			! ap[2]
        +	ld	[$np],$car1			! np[0]
        +	ld	[$np+4],$npj			! np[1]
        +	mulx	$n0,$tmp0,$mul1
        +
        +	mulx	$mul0,$mul0,$car0
        +	and	$mul1,$mask,$mul1
        +
        +	mulx	$car1,$mul1,$car1
        +	mulx	$npj,$mul1,$acc1
        +	add	$tmp0,$car1,$car1
        +	and	$car0,$mask,$acc0
        +	ld	[$np+8],$npj			! np[2]
        +	srlx	$car1,32,$car1
        +	add	$tmp1,$car1,$car1
        +	srlx	$car0,32,$car0
        +	add	$acc0,$car1,$car1
        +	and	$car0,1,$sbit
        +	add	$acc1,$car1,$car1
        +	srlx	$car0,1,$car0
        +	mov	12,$j
        +	st	$car1,[%sp+$bias+$frame]	! tp[0]=
        +	srlx	$car1,32,$car1
        +	add	%sp,$bias+$frame+4,$tp
        +
        +.Lsqr_2nd:
        +	mulx	$apj,$mul0,$acc0
        +	mulx	$npj,$mul1,$acc1
        +	add	$acc0,$car0,$car0
        +	add	$tpj,$car1,$car1
        +	ld	[$ap+$j],$apj			! ap[j]
        +	and	$car0,$mask,$acc0
        +	ld	[$np+$j],$npj			! np[j]
        +	srlx	$car0,32,$car0
        +	add	$acc1,$car1,$car1
        +	ld	[$tp+8],$tpj			! tp[j]
        +	add	$acc0,$acc0,$acc0
        +	add	$j,4,$j				! j++
        +	or	$sbit,$acc0,$acc0
        +	srlx	$acc0,32,$sbit
        +	and	$acc0,$mask,$acc0
        +	cmp	$j,$num
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp]			! tp[j-1]
        +	srlx	$car1,32,$car1
        +	bl	%icc,.Lsqr_2nd
        +	add	$tp,4,$tp			! tp++
        +!.Lsqr_2nd
        +
        +	mulx	$apj,$mul0,$acc0
        +	mulx	$npj,$mul1,$acc1
        +	add	$acc0,$car0,$car0
        +	add	$tpj,$car1,$car1
        +	and	$car0,$mask,$acc0
        +	srlx	$car0,32,$car0
        +	add	$acc1,$car1,$car1
        +	add	$acc0,$acc0,$acc0
        +	or	$sbit,$acc0,$acc0
        +	srlx	$acc0,32,$sbit
        +	and	$acc0,$mask,$acc0
        +	add	$acc0,$car1,$car1
        +	st	$car1,[$tp]			! tp[j-1]
        +	srlx	$car1,32,$car1
        +
        +	add	$car0,$car0,$car0
        +	or	$sbit,$car0,$car0
        +	add	$car0,$car1,$car1
        +	add	$car2,$car1,$car1
        +	st	$car1,[$tp+4]
        +	srlx	$car1,32,$car2
        +
        +	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
        +	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
        +	ld	[$ap+8],$mul0			! ap[2]
        +	ld	[$np],$car1			! np[0]
        +	ld	[$np+4],$npj			! np[1]
        +	mulx	$n0,$tmp1,$mul1
        +	and	$mul1,$mask,$mul1
        +	mov	8,$i
        +
        +	mulx	$mul0,$mul0,$car0
        +	mulx	$car1,$mul1,$car1
        +	and	$car0,$mask,$acc0
        +	add	$tmp1,$car1,$car1
        +	srlx	$car0,32,$car0
        +	add	%sp,$bias+$frame,$tp
        +	srlx	$car1,32,$car1
        +	and	$car0,1,$sbit
        +	srlx	$car0,1,$car0
        +	mov	4,$j
        +
        +.Lsqr_outer:
        +.Lsqr_inner1:
        +	mulx	$npj,$mul1,$acc1
        +	add	$tpj,$car1,$car1
        +	add	$j,4,$j
        +	ld	[$tp+8],$tpj
        +	cmp	$j,$i
        +	add	$acc1,$car1,$car1
        +	ld	[$np+$j],$npj
        +	st	$car1,[$tp]
        +	srlx	$car1,32,$car1
        +	bl	%icc,.Lsqr_inner1
        +	add	$tp,4,$tp
        +!.Lsqr_inner1
        +
        +	add	$j,4,$j
        +	ld	[$ap+$j],$apj			! ap[j]
        +	mulx	$npj,$mul1,$acc1
        +	add	$tpj,$car1,$car1
        +	ld	[$np+$j],$npj			! np[j]
        +	add	$acc0,$car1,$car1
        +	ld	[$tp+8],$tpj			! tp[j]
        +	add	$acc1,$car1,$car1
        +	st	$car1,[$tp]
        +	srlx	$car1,32,$car1
        +
        +	add	$j,4,$j
        +	cmp	$j,$num
        +	be,pn	%icc,.Lsqr_no_inner2
        +	add	$tp,4,$tp
        +
        +.Lsqr_inner2:
        +	mulx	$apj,$mul0,$acc0
        +	mulx	$npj,$mul1,$acc1
        +	add	$tpj,$car1,$car1
        +	add	$acc0,$car0,$car0
        +	ld	[$ap+$j],$apj			! ap[j]
        +	and	$car0,$mask,$acc0
        +	ld	[$np+$j],$npj			! np[j]
        +	srlx	$car0,32,$car0
        +	add	$acc0,$acc0,$acc0
        +	ld	[$tp+8],$tpj			! tp[j]
        +	or	$sbit,$acc0,$acc0
        +	add	$j,4,$j				! j++
        +	srlx	$acc0,32,$sbit
        +	and	$acc0,$mask,$acc0
        +	cmp	$j,$num
        +	add	$acc0,$car1,$car1
        +	add	$acc1,$car1,$car1
        +	st	$car1,[$tp]			! tp[j-1]
        +	srlx	$car1,32,$car1
        +	bl	%icc,.Lsqr_inner2
        +	add	$tp,4,$tp			! tp++
        +
        +.Lsqr_no_inner2:
        +	mulx	$apj,$mul0,$acc0
        +	mulx	$npj,$mul1,$acc1
        +	add	$tpj,$car1,$car1
        +	add	$acc0,$car0,$car0
        +	and	$car0,$mask,$acc0
        +	srlx	$car0,32,$car0
        +	add	$acc0,$acc0,$acc0
        +	or	$sbit,$acc0,$acc0
        +	srlx	$acc0,32,$sbit
        +	and	$acc0,$mask,$acc0
        +	add	$acc0,$car1,$car1
        +	add	$acc1,$car1,$car1
        +	st	$car1,[$tp]			! tp[j-1]
        +	srlx	$car1,32,$car1
        +
        +	add	$car0,$car0,$car0
        +	or	$sbit,$car0,$car0
        +	add	$car0,$car1,$car1
        +	add	$car2,$car1,$car1
        +	st	$car1,[$tp+4]
        +	srlx	$car1,32,$car2
        +
        +	add	$i,4,$i				! i++
        +	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
        +	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
        +	ld	[$ap+$i],$mul0			! ap[j]
        +	ld	[$np],$car1			! np[0]
        +	ld	[$np+4],$npj			! np[1]
        +	mulx	$n0,$tmp1,$mul1
        +	and	$mul1,$mask,$mul1
        +	add	$i,4,$tmp0
        +
        +	mulx	$mul0,$mul0,$car0
        +	mulx	$car1,$mul1,$car1
        +	and	$car0,$mask,$acc0
        +	add	$tmp1,$car1,$car1
        +	srlx	$car0,32,$car0
        +	add	%sp,$bias+$frame,$tp
        +	srlx	$car1,32,$car1
        +	and	$car0,1,$sbit
        +	srlx	$car0,1,$car0
        +
        +	cmp	$tmp0,$num			! i<num-1
        +	bl	%icc,.Lsqr_outer
        +	mov	4,$j
        +
        +.Lsqr_last:
        +	mulx	$npj,$mul1,$acc1
        +	add	$tpj,$car1,$car1
        +	add	$j,4,$j
        +	ld	[$tp+8],$tpj
        +	cmp	$j,$i
        +	add	$acc1,$car1,$car1
        +	ld	[$np+$j],$npj
        +	st	$car1,[$tp]
        +	srlx	$car1,32,$car1
        +	bl	%icc,.Lsqr_last
        +	add	$tp,4,$tp
        +!.Lsqr_last
        +
        +	mulx	$npj,$mul1,$acc1
        +	add	$tpj,$car1,$car1
        +	add	$acc0,$car1,$car1
        +	add	$acc1,$car1,$car1
        +	st	$car1,[$tp]
        +	srlx	$car1,32,$car1
        +
        +	add	$car0,$car0,$car0		! recover $car0
        +	or	$sbit,$car0,$car0
        +	add	$car0,$car1,$car1
        +	add	$car2,$car1,$car1
        +	st	$car1,[$tp+4]
        +	srlx	$car1,32,$car2
        +
        +	ba	.Ltail
        +	add	$tp,8,$tp
        +.type	$fname,#function
        +.size	$fname,(.-$fname)
        +.asciz	"Montgomery Multipltication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	32
        +___
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl
        new file mode 100644
        index 000000000..a14205f2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/sparcv9a-mont.pl
        @@ -0,0 +1,882 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# October 2005
        +#
        +# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
        +# Because unlike integer multiplier, which simply stalls whole CPU,
        +# FPU is fully pipelined and can effectively emit 48 bit partial
        +# product every cycle. Why not blended SPARC v9? One can argue that
        +# making this module dependent on UltraSPARC VIS extension limits its
        +# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
        +# implementations from compatibility matrix. But the rest, whole Sun
        +# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
        +# VIS extension instructions used in this module. This is considered
        +# good enough to not care about HAL SPARC64 users [if any] who have
        +# integer-only pure SPARCv9 module to "fall down" to.
        +
        +# USI&II cores currently exhibit uniform 2x improvement [over pre-
        +# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
        +# performance improves few percents for shorter keys and worsens few
        +# percents for longer keys. This is because USIII integer multiplier
        +# is >3x faster than USI&II one, which is harder to match [but see
        +# TODO list below]. It should also be noted that SPARC64 V features
        +# out-of-order execution, which *might* mean that integer multiplier
        +# is pipelined, which in turn *might* be impossible to match... On
        +# additional note, SPARC64 V implements FP Multiply-Add instruction,
        +# which is perfectly usable in this context... In other words, as far
        +# as Fujitsu SPARC64 V goes, talk to the author:-)
        +
        +# The implementation implies following "non-natural" limitations on
        +# input arguments:
        +# - num may not be less than 4;
        +# - num has to be even;
        +# Failure to meet either condition has no fatal effects, simply
        +# doesn't give any performance gain.
        +
        +# TODO:
        +# - modulo-schedule inner loop for better performance (on in-order
        +#   execution core such as UltraSPARC this shall result in further
        +#   noticeable(!) improvement);
        +# - dedicated squaring procedure[?];
        +
        +######################################################################
        +# November 2006
        +#
        +# Modulo-scheduled inner loops allow to interleave floating point and
        +# integer instructions and minimize Read-After-Write penalties. This
        +# results in *further* 20-50% perfromance improvement [depending on
        +# key length, more for longer keys] on USI&II cores and 30-80% - on
        +# USIII&IV.
        +
        +$fname="bn_mul_mont_fpu";
        +$bits=32;
        +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +
        +if ($bits==64) {
        +	$bias=2047;
        +	$frame=192;
        +} else {
        +	$bias=0;
        +	$frame=128;	# 96 rounded up to largest known cache-line
        +}
        +$locals=64;
        +
        +# In order to provide for 32-/64-bit ABI duality, I keep integers wider
        +# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
        +# exclusively for pointers, indexes and other small values...
        +# int bn_mul_mont(
        +$rp="%i0";	# BN_ULONG *rp,
        +$ap="%i1";	# const BN_ULONG *ap,
        +$bp="%i2";	# const BN_ULONG *bp,
        +$np="%i3";	# const BN_ULONG *np,
        +$n0="%i4";	# const BN_ULONG *n0,
        +$num="%i5";	# int num);
        +
        +$tp="%l0";	# t[num]
        +$ap_l="%l1";	# a[num],n[num] are smashed to 32-bit words and saved
        +$ap_h="%l2";	# to these four vectors as double-precision FP values.
        +$np_l="%l3";	# This way a bunch of fxtods are eliminated in second
        +$np_h="%l4";	# loop and L1-cache aliasing is minimized...
        +$i="%l5";
        +$j="%l6";
        +$mask="%l7";	# 16-bit mask, 0xffff
        +
        +$n0="%g4";	# reassigned(!) to "64-bit" register
        +$carry="%i4";	# %i4 reused(!) for a carry bit
        +
        +# FP register naming chart
        +#
        +#     ..HILO
        +#       dcba
        +#   --------
        +#        LOa
        +#       LOb
        +#      LOc
        +#     LOd
        +#      HIa
        +#     HIb
        +#    HIc
        +#   HId
        +#    ..a
        +#   ..b
        +$ba="%f0";    $bb="%f2";    $bc="%f4";    $bd="%f6";
        +$na="%f8";    $nb="%f10";   $nc="%f12";   $nd="%f14";
        +$alo="%f16";  $alo_="%f17"; $ahi="%f18";  $ahi_="%f19";
        +$nlo="%f20";  $nlo_="%f21"; $nhi="%f22";  $nhi_="%f23";
        +
        +$dota="%f24"; $dotb="%f26";
        +
        +$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
        +$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
        +$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
        +$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
        +
        +$ASI_FL16_P=0xD2;	# magic ASI value to engage 16-bit FP load
        +
        +$code=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.global $fname
        +.align  32
        +$fname:
        +	save	%sp,-$frame-$locals,%sp
        +
        +	cmp	$num,4
        +	bl,a,pn %icc,.Lret
        +	clr	%i0
        +	andcc	$num,1,%g0		! $num has to be even...
        +	bnz,a,pn %icc,.Lret
        +	clr	%i0			! signal "unsupported input value"
        +
        +	srl	$num,1,$num
        +	sethi	%hi(0xffff),$mask
        +	ld	[%i4+0],$n0		! $n0 reassigned, remember?
        +	or	$mask,%lo(0xffff),$mask
        +	ld	[%i4+4],%o0
        +	sllx	%o0,32,%o0
        +	or	%o0,$n0,$n0		! $n0=n0[1].n0[0]
        +
        +	sll	$num,3,$num		! num*=8
        +
        +	add	%sp,$bias,%o0		! real top of stack
        +	sll	$num,2,%o1
        +	add	%o1,$num,%o1		! %o1=num*5
        +	sub	%o0,%o1,%o0
        +	and	%o0,-2048,%o0		! optimize TLB utilization
        +	sub	%o0,$bias,%sp		! alloca(5*num*8)
        +
        +	rd	%asi,%o7		! save %asi
        +	add	%sp,$bias+$frame+$locals,$tp
        +	add	$tp,$num,$ap_l
        +	add	$ap_l,$num,$ap_l	! [an]p_[lh] point at the vectors' ends !
        +	add	$ap_l,$num,$ap_h
        +	add	$ap_h,$num,$np_l
        +	add	$np_l,$num,$np_h
        +
        +	wr	%g0,$ASI_FL16_P,%asi	! setup %asi for 16-bit FP loads
        +
        +	add	$rp,$num,$rp		! readjust input pointers to point
        +	add	$ap,$num,$ap		! at the ends too...
        +	add	$bp,$num,$bp
        +	add	$np,$num,$np
        +
        +	stx	%o7,[%sp+$bias+$frame+48]	! save %asi
        +
        +	sub	%g0,$num,$i		! i=-num
        +	sub	%g0,$num,$j		! j=-num
        +
        +	add	$ap,$j,%o3
        +	add	$bp,$i,%o4
        +
        +	ld	[%o3+4],%g1		! bp[0]
        +	ld	[%o3+0],%o0
        +	ld	[%o4+4],%g5		! ap[0]
        +	sllx	%g1,32,%g1
        +	ld	[%o4+0],%o1
        +	sllx	%g5,32,%g5
        +	or	%g1,%o0,%o0
        +	or	%g5,%o1,%o1
        +
        +	add	$np,$j,%o5
        +
        +	mulx	%o1,%o0,%o0		! ap[0]*bp[0]
        +	mulx	$n0,%o0,%o0		! ap[0]*bp[0]*n0
        +	stx	%o0,[%sp+$bias+$frame+0]
        +
        +	ld	[%o3+0],$alo_	! load a[j] as pair of 32-bit words
        +	fzeros	$alo
        +	ld	[%o3+4],$ahi_
        +	fzeros	$ahi
        +	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
        +	fzeros	$nlo
        +	ld	[%o5+4],$nhi_
        +	fzeros	$nhi
        +
        +	! transfer b[i] to FPU as 4x16-bit values
        +	ldda	[%o4+2]%asi,$ba
        +	fxtod	$alo,$alo
        +	ldda	[%o4+0]%asi,$bb
        +	fxtod	$ahi,$ahi
        +	ldda	[%o4+6]%asi,$bc
        +	fxtod	$nlo,$nlo
        +	ldda	[%o4+4]%asi,$bd
        +	fxtod	$nhi,$nhi
        +
        +	! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
        +	ldda	[%sp+$bias+$frame+6]%asi,$na
        +	fxtod	$ba,$ba
        +	ldda	[%sp+$bias+$frame+4]%asi,$nb
        +	fxtod	$bb,$bb
        +	ldda	[%sp+$bias+$frame+2]%asi,$nc
        +	fxtod	$bc,$bc
        +	ldda	[%sp+$bias+$frame+0]%asi,$nd
        +	fxtod	$bd,$bd
        +
        +	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
        +	fxtod	$na,$na
        +	std	$ahi,[$ap_h+$j]
        +	fxtod	$nb,$nb
        +	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
        +	fxtod	$nc,$nc
        +	std	$nhi,[$np_h+$j]
        +	fxtod	$nd,$nd
        +
        +		fmuld	$alo,$ba,$aloa
        +		fmuld	$nlo,$na,$nloa
        +		fmuld	$alo,$bb,$alob
        +		fmuld	$nlo,$nb,$nlob
        +		fmuld	$alo,$bc,$aloc
        +	faddd	$aloa,$nloa,$nloa
        +		fmuld	$nlo,$nc,$nloc
        +		fmuld	$alo,$bd,$alod
        +	faddd	$alob,$nlob,$nlob
        +		fmuld	$nlo,$nd,$nlod
        +		fmuld	$ahi,$ba,$ahia
        +	faddd	$aloc,$nloc,$nloc
        +		fmuld	$nhi,$na,$nhia
        +		fmuld	$ahi,$bb,$ahib
        +	faddd	$alod,$nlod,$nlod
        +		fmuld	$nhi,$nb,$nhib
        +		fmuld	$ahi,$bc,$ahic
        +	faddd	$ahia,$nhia,$nhia
        +		fmuld	$nhi,$nc,$nhic
        +		fmuld	$ahi,$bd,$ahid
        +	faddd	$ahib,$nhib,$nhib
        +		fmuld	$nhi,$nd,$nhid
        +
        +	faddd	$ahic,$nhic,$dota	! $nhic
        +	faddd	$ahid,$nhid,$dotb	! $nhid
        +
        +	faddd	$nloc,$nhia,$nloc
        +	faddd	$nlod,$nhib,$nlod
        +
        +	fdtox	$nloa,$nloa
        +	fdtox	$nlob,$nlob
        +	fdtox	$nloc,$nloc
        +	fdtox	$nlod,$nlod
        +
        +	std	$nloa,[%sp+$bias+$frame+0]
        +	add	$j,8,$j
        +	std	$nlob,[%sp+$bias+$frame+8]
        +	add	$ap,$j,%o4
        +	std	$nloc,[%sp+$bias+$frame+16]
        +	add	$np,$j,%o5
        +	std	$nlod,[%sp+$bias+$frame+24]
        +
        +	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
        +	fzeros	$alo
        +	ld	[%o4+4],$ahi_
        +	fzeros	$ahi
        +	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
        +	fzeros	$nlo
        +	ld	[%o5+4],$nhi_
        +	fzeros	$nhi
        +
        +	fxtod	$alo,$alo
        +	fxtod	$ahi,$ahi
        +	fxtod	$nlo,$nlo
        +	fxtod	$nhi,$nhi
        +
        +	ldx	[%sp+$bias+$frame+0],%o0
        +		fmuld	$alo,$ba,$aloa
        +	ldx	[%sp+$bias+$frame+8],%o1
        +		fmuld	$nlo,$na,$nloa
        +	ldx	[%sp+$bias+$frame+16],%o2
        +		fmuld	$alo,$bb,$alob
        +	ldx	[%sp+$bias+$frame+24],%o3
        +		fmuld	$nlo,$nb,$nlob
        +
        +	srlx	%o0,16,%o7
        +	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
        +		fmuld	$alo,$bc,$aloc
        +	add	%o7,%o1,%o1
        +	std	$ahi,[$ap_h+$j]
        +		faddd	$aloa,$nloa,$nloa
        +		fmuld	$nlo,$nc,$nloc
        +	srlx	%o1,16,%o7
        +	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
        +		fmuld	$alo,$bd,$alod
        +	add	%o7,%o2,%o2
        +	std	$nhi,[$np_h+$j]
        +		faddd	$alob,$nlob,$nlob
        +		fmuld	$nlo,$nd,$nlod
        +	srlx	%o2,16,%o7
        +		fmuld	$ahi,$ba,$ahia
        +	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
        +		faddd	$aloc,$nloc,$nloc
        +		fmuld	$nhi,$na,$nhia
        +	!and	%o0,$mask,%o0
        +	!and	%o1,$mask,%o1
        +	!and	%o2,$mask,%o2
        +	!sllx	%o1,16,%o1
        +	!sllx	%o2,32,%o2
        +	!sllx	%o3,48,%o7
        +	!or	%o1,%o0,%o0
        +	!or	%o2,%o0,%o0
        +	!or	%o7,%o0,%o0		! 64-bit result
        +	srlx	%o3,16,%g1		! 34-bit carry
        +		fmuld	$ahi,$bb,$ahib
        +
        +	faddd	$alod,$nlod,$nlod
        +		fmuld	$nhi,$nb,$nhib
        +		fmuld	$ahi,$bc,$ahic
        +	faddd	$ahia,$nhia,$nhia
        +		fmuld	$nhi,$nc,$nhic
        +		fmuld	$ahi,$bd,$ahid
        +	faddd	$ahib,$nhib,$nhib
        +		fmuld	$nhi,$nd,$nhid
        +
        +	faddd	$dota,$nloa,$nloa
        +	faddd	$dotb,$nlob,$nlob
        +	faddd	$ahic,$nhic,$dota	! $nhic
        +	faddd	$ahid,$nhid,$dotb	! $nhid
        +
        +	faddd	$nloc,$nhia,$nloc
        +	faddd	$nlod,$nhib,$nlod
        +
        +	fdtox	$nloa,$nloa
        +	fdtox	$nlob,$nlob
        +	fdtox	$nloc,$nloc
        +	fdtox	$nlod,$nlod
        +
        +	std	$nloa,[%sp+$bias+$frame+0]
        +	std	$nlob,[%sp+$bias+$frame+8]
        +	addcc	$j,8,$j
        +	std	$nloc,[%sp+$bias+$frame+16]
        +	bz,pn	%icc,.L1stskip
        +	std	$nlod,[%sp+$bias+$frame+24]
        +
        +.align	32			! incidentally already aligned !
        +.L1st:
        +	add	$ap,$j,%o4
        +	add	$np,$j,%o5
        +	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
        +	fzeros	$alo
        +	ld	[%o4+4],$ahi_
        +	fzeros	$ahi
        +	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
        +	fzeros	$nlo
        +	ld	[%o5+4],$nhi_
        +	fzeros	$nhi
        +
        +	fxtod	$alo,$alo
        +	fxtod	$ahi,$ahi
        +	fxtod	$nlo,$nlo
        +	fxtod	$nhi,$nhi
        +
        +	ldx	[%sp+$bias+$frame+0],%o0
        +		fmuld	$alo,$ba,$aloa
        +	ldx	[%sp+$bias+$frame+8],%o1
        +		fmuld	$nlo,$na,$nloa
        +	ldx	[%sp+$bias+$frame+16],%o2
        +		fmuld	$alo,$bb,$alob
        +	ldx	[%sp+$bias+$frame+24],%o3
        +		fmuld	$nlo,$nb,$nlob
        +
        +	srlx	%o0,16,%o7
        +	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
        +		fmuld	$alo,$bc,$aloc
        +	add	%o7,%o1,%o1
        +	std	$ahi,[$ap_h+$j]
        +		faddd	$aloa,$nloa,$nloa
        +		fmuld	$nlo,$nc,$nloc
        +	srlx	%o1,16,%o7
        +	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
        +		fmuld	$alo,$bd,$alod
        +	add	%o7,%o2,%o2
        +	std	$nhi,[$np_h+$j]
        +		faddd	$alob,$nlob,$nlob
        +		fmuld	$nlo,$nd,$nlod
        +	srlx	%o2,16,%o7
        +		fmuld	$ahi,$ba,$ahia
        +	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
        +	and	%o0,$mask,%o0
        +		faddd	$aloc,$nloc,$nloc
        +		fmuld	$nhi,$na,$nhia
        +	and	%o1,$mask,%o1
        +	and	%o2,$mask,%o2
        +		fmuld	$ahi,$bb,$ahib
        +	sllx	%o1,16,%o1
        +		faddd	$alod,$nlod,$nlod
        +		fmuld	$nhi,$nb,$nhib
        +	sllx	%o2,32,%o2
        +		fmuld	$ahi,$bc,$ahic
        +	sllx	%o3,48,%o7
        +	or	%o1,%o0,%o0
        +		faddd	$ahia,$nhia,$nhia
        +		fmuld	$nhi,$nc,$nhic
        +	or	%o2,%o0,%o0
        +		fmuld	$ahi,$bd,$ahid
        +	or	%o7,%o0,%o0		! 64-bit result
        +		faddd	$ahib,$nhib,$nhib
        +		fmuld	$nhi,$nd,$nhid
        +	addcc	%g1,%o0,%o0
        +		faddd	$dota,$nloa,$nloa
        +	srlx	%o3,16,%g1		! 34-bit carry
        +		faddd	$dotb,$nlob,$nlob
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	stx	%o0,[$tp]		! tp[j-1]=
        +
        +	faddd	$ahic,$nhic,$dota	! $nhic
        +	faddd	$ahid,$nhid,$dotb	! $nhid
        +
        +	faddd	$nloc,$nhia,$nloc
        +	faddd	$nlod,$nhib,$nlod
        +
        +	fdtox	$nloa,$nloa
        +	fdtox	$nlob,$nlob
        +	fdtox	$nloc,$nloc
        +	fdtox	$nlod,$nlod
        +
        +	std	$nloa,[%sp+$bias+$frame+0]
        +	std	$nlob,[%sp+$bias+$frame+8]
        +	std	$nloc,[%sp+$bias+$frame+16]
        +	std	$nlod,[%sp+$bias+$frame+24]
        +
        +	addcc	$j,8,$j
        +	bnz,pt	%icc,.L1st
        +	add	$tp,8,$tp
        +
        +.L1stskip:
        +	fdtox	$dota,$dota
        +	fdtox	$dotb,$dotb
        +
        +	ldx	[%sp+$bias+$frame+0],%o0
        +	ldx	[%sp+$bias+$frame+8],%o1
        +	ldx	[%sp+$bias+$frame+16],%o2
        +	ldx	[%sp+$bias+$frame+24],%o3
        +
        +	srlx	%o0,16,%o7
        +	std	$dota,[%sp+$bias+$frame+32]
        +	add	%o7,%o1,%o1
        +	std	$dotb,[%sp+$bias+$frame+40]
        +	srlx	%o1,16,%o7
        +	add	%o7,%o2,%o2
        +	srlx	%o2,16,%o7
        +	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
        +	and	%o0,$mask,%o0
        +	and	%o1,$mask,%o1
        +	and	%o2,$mask,%o2
        +	sllx	%o1,16,%o1
        +	sllx	%o2,32,%o2
        +	sllx	%o3,48,%o7
        +	or	%o1,%o0,%o0
        +	or	%o2,%o0,%o0
        +	or	%o7,%o0,%o0		! 64-bit result
        +	ldx	[%sp+$bias+$frame+32],%o4
        +	addcc	%g1,%o0,%o0
        +	ldx	[%sp+$bias+$frame+40],%o5
        +	srlx	%o3,16,%g1		! 34-bit carry
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	stx	%o0,[$tp]		! tp[j-1]=
        +	add	$tp,8,$tp
        +
        +	srlx	%o4,16,%o7
        +	add	%o7,%o5,%o5
        +	and	%o4,$mask,%o4
        +	sllx	%o5,16,%o7
        +	or	%o7,%o4,%o4
        +	addcc	%g1,%o4,%o4
        +	srlx	%o5,48,%g1
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	mov	%g1,$carry
        +	stx	%o4,[$tp]		! tp[num-1]=
        +
        +	ba	.Louter
        +	add	$i,8,$i
        +.align	32
        +.Louter:
        +	sub	%g0,$num,$j		! j=-num
        +	add	%sp,$bias+$frame+$locals,$tp
        +
        +	add	$ap,$j,%o3
        +	add	$bp,$i,%o4
        +
        +	ld	[%o3+4],%g1		! bp[i]
        +	ld	[%o3+0],%o0
        +	ld	[%o4+4],%g5		! ap[0]
        +	sllx	%g1,32,%g1
        +	ld	[%o4+0],%o1
        +	sllx	%g5,32,%g5
        +	or	%g1,%o0,%o0
        +	or	%g5,%o1,%o1
        +
        +	ldx	[$tp],%o2		! tp[0]
        +	mulx	%o1,%o0,%o0
        +	addcc	%o2,%o0,%o0
        +	mulx	$n0,%o0,%o0		! (ap[0]*bp[i]+t[0])*n0
        +	stx	%o0,[%sp+$bias+$frame+0]
        +
        +	! transfer b[i] to FPU as 4x16-bit values
        +	ldda	[%o4+2]%asi,$ba
        +	ldda	[%o4+0]%asi,$bb
        +	ldda	[%o4+6]%asi,$bc
        +	ldda	[%o4+4]%asi,$bd
        +
        +	! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
        +	ldda	[%sp+$bias+$frame+6]%asi,$na
        +	fxtod	$ba,$ba
        +	ldda	[%sp+$bias+$frame+4]%asi,$nb
        +	fxtod	$bb,$bb
        +	ldda	[%sp+$bias+$frame+2]%asi,$nc
        +	fxtod	$bc,$bc
        +	ldda	[%sp+$bias+$frame+0]%asi,$nd
        +	fxtod	$bd,$bd
        +	ldd	[$ap_l+$j],$alo		! load a[j] in double format
        +	fxtod	$na,$na
        +	ldd	[$ap_h+$j],$ahi
        +	fxtod	$nb,$nb
        +	ldd	[$np_l+$j],$nlo		! load n[j] in double format
        +	fxtod	$nc,$nc
        +	ldd	[$np_h+$j],$nhi
        +	fxtod	$nd,$nd
        +
        +		fmuld	$alo,$ba,$aloa
        +		fmuld	$nlo,$na,$nloa
        +		fmuld	$alo,$bb,$alob
        +		fmuld	$nlo,$nb,$nlob
        +		fmuld	$alo,$bc,$aloc
        +	faddd	$aloa,$nloa,$nloa
        +		fmuld	$nlo,$nc,$nloc
        +		fmuld	$alo,$bd,$alod
        +	faddd	$alob,$nlob,$nlob
        +		fmuld	$nlo,$nd,$nlod
        +		fmuld	$ahi,$ba,$ahia
        +	faddd	$aloc,$nloc,$nloc
        +		fmuld	$nhi,$na,$nhia
        +		fmuld	$ahi,$bb,$ahib
        +	faddd	$alod,$nlod,$nlod
        +		fmuld	$nhi,$nb,$nhib
        +		fmuld	$ahi,$bc,$ahic
        +	faddd	$ahia,$nhia,$nhia
        +		fmuld	$nhi,$nc,$nhic
        +		fmuld	$ahi,$bd,$ahid
        +	faddd	$ahib,$nhib,$nhib
        +		fmuld	$nhi,$nd,$nhid
        +
        +	faddd	$ahic,$nhic,$dota	! $nhic
        +	faddd	$ahid,$nhid,$dotb	! $nhid
        +
        +	faddd	$nloc,$nhia,$nloc
        +	faddd	$nlod,$nhib,$nlod
        +
        +	fdtox	$nloa,$nloa
        +	fdtox	$nlob,$nlob
        +	fdtox	$nloc,$nloc
        +	fdtox	$nlod,$nlod
        +
        +	std	$nloa,[%sp+$bias+$frame+0]
        +	std	$nlob,[%sp+$bias+$frame+8]
        +	std	$nloc,[%sp+$bias+$frame+16]
        +	add	$j,8,$j
        +	std	$nlod,[%sp+$bias+$frame+24]
        +
        +	ldd	[$ap_l+$j],$alo		! load a[j] in double format
        +	ldd	[$ap_h+$j],$ahi
        +	ldd	[$np_l+$j],$nlo		! load n[j] in double format
        +	ldd	[$np_h+$j],$nhi
        +
        +		fmuld	$alo,$ba,$aloa
        +		fmuld	$nlo,$na,$nloa
        +		fmuld	$alo,$bb,$alob
        +		fmuld	$nlo,$nb,$nlob
        +		fmuld	$alo,$bc,$aloc
        +	ldx	[%sp+$bias+$frame+0],%o0
        +		faddd	$aloa,$nloa,$nloa
        +		fmuld	$nlo,$nc,$nloc
        +	ldx	[%sp+$bias+$frame+8],%o1
        +		fmuld	$alo,$bd,$alod
        +	ldx	[%sp+$bias+$frame+16],%o2
        +		faddd	$alob,$nlob,$nlob
        +		fmuld	$nlo,$nd,$nlod
        +	ldx	[%sp+$bias+$frame+24],%o3
        +		fmuld	$ahi,$ba,$ahia
        +
        +	srlx	%o0,16,%o7
        +		faddd	$aloc,$nloc,$nloc
        +		fmuld	$nhi,$na,$nhia
        +	add	%o7,%o1,%o1
        +		fmuld	$ahi,$bb,$ahib
        +	srlx	%o1,16,%o7
        +		faddd	$alod,$nlod,$nlod
        +		fmuld	$nhi,$nb,$nhib
        +	add	%o7,%o2,%o2
        +		fmuld	$ahi,$bc,$ahic
        +	srlx	%o2,16,%o7
        +		faddd	$ahia,$nhia,$nhia
        +		fmuld	$nhi,$nc,$nhic
        +	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
        +	! why?
        +	and	%o0,$mask,%o0
        +		fmuld	$ahi,$bd,$ahid
        +	and	%o1,$mask,%o1
        +	and	%o2,$mask,%o2
        +		faddd	$ahib,$nhib,$nhib
        +		fmuld	$nhi,$nd,$nhid
        +	sllx	%o1,16,%o1
        +		faddd	$dota,$nloa,$nloa
        +	sllx	%o2,32,%o2
        +		faddd	$dotb,$nlob,$nlob
        +	sllx	%o3,48,%o7
        +	or	%o1,%o0,%o0
        +		faddd	$ahic,$nhic,$dota	! $nhic
        +	or	%o2,%o0,%o0
        +		faddd	$ahid,$nhid,$dotb	! $nhid
        +	or	%o7,%o0,%o0		! 64-bit result
        +	ldx	[$tp],%o7
        +		faddd	$nloc,$nhia,$nloc
        +	addcc	%o7,%o0,%o0
        +	! end-of-why?
        +		faddd	$nlod,$nhib,$nlod
        +	srlx	%o3,16,%g1		! 34-bit carry
        +		fdtox	$nloa,$nloa
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	fdtox	$nlob,$nlob
        +	fdtox	$nloc,$nloc
        +	fdtox	$nlod,$nlod
        +
        +	std	$nloa,[%sp+$bias+$frame+0]
        +	std	$nlob,[%sp+$bias+$frame+8]
        +	addcc	$j,8,$j
        +	std	$nloc,[%sp+$bias+$frame+16]
        +	bz,pn	%icc,.Linnerskip
        +	std	$nlod,[%sp+$bias+$frame+24]
        +
        +	ba	.Linner
        +	nop
        +.align	32
        +.Linner:
        +	ldd	[$ap_l+$j],$alo		! load a[j] in double format
        +	ldd	[$ap_h+$j],$ahi
        +	ldd	[$np_l+$j],$nlo		! load n[j] in double format
        +	ldd	[$np_h+$j],$nhi
        +
        +		fmuld	$alo,$ba,$aloa
        +		fmuld	$nlo,$na,$nloa
        +		fmuld	$alo,$bb,$alob
        +		fmuld	$nlo,$nb,$nlob
        +		fmuld	$alo,$bc,$aloc
        +	ldx	[%sp+$bias+$frame+0],%o0
        +		faddd	$aloa,$nloa,$nloa
        +		fmuld	$nlo,$nc,$nloc
        +	ldx	[%sp+$bias+$frame+8],%o1
        +		fmuld	$alo,$bd,$alod
        +	ldx	[%sp+$bias+$frame+16],%o2
        +		faddd	$alob,$nlob,$nlob
        +		fmuld	$nlo,$nd,$nlod
        +	ldx	[%sp+$bias+$frame+24],%o3
        +		fmuld	$ahi,$ba,$ahia
        +
        +	srlx	%o0,16,%o7
        +		faddd	$aloc,$nloc,$nloc
        +		fmuld	$nhi,$na,$nhia
        +	add	%o7,%o1,%o1
        +		fmuld	$ahi,$bb,$ahib
        +	srlx	%o1,16,%o7
        +		faddd	$alod,$nlod,$nlod
        +		fmuld	$nhi,$nb,$nhib
        +	add	%o7,%o2,%o2
        +		fmuld	$ahi,$bc,$ahic
        +	srlx	%o2,16,%o7
        +		faddd	$ahia,$nhia,$nhia
        +		fmuld	$nhi,$nc,$nhic
        +	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
        +	and	%o0,$mask,%o0
        +		fmuld	$ahi,$bd,$ahid
        +	and	%o1,$mask,%o1
        +	and	%o2,$mask,%o2
        +		faddd	$ahib,$nhib,$nhib
        +		fmuld	$nhi,$nd,$nhid
        +	sllx	%o1,16,%o1
        +		faddd	$dota,$nloa,$nloa
        +	sllx	%o2,32,%o2
        +		faddd	$dotb,$nlob,$nlob
        +	sllx	%o3,48,%o7
        +	or	%o1,%o0,%o0
        +		faddd	$ahic,$nhic,$dota	! $nhic
        +	or	%o2,%o0,%o0
        +		faddd	$ahid,$nhid,$dotb	! $nhid
        +	or	%o7,%o0,%o0		! 64-bit result
        +		faddd	$nloc,$nhia,$nloc
        +	addcc	%g1,%o0,%o0
        +	ldx	[$tp+8],%o7		! tp[j]
        +		faddd	$nlod,$nhib,$nlod
        +	srlx	%o3,16,%g1		! 34-bit carry
        +		fdtox	$nloa,$nloa
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +		fdtox	$nlob,$nlob
        +	addcc	%o7,%o0,%o0
        +		fdtox	$nloc,$nloc
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	stx	%o0,[$tp]		! tp[j-1]
        +		fdtox	$nlod,$nlod
        +
        +	std	$nloa,[%sp+$bias+$frame+0]
        +	std	$nlob,[%sp+$bias+$frame+8]
        +	std	$nloc,[%sp+$bias+$frame+16]
        +	addcc	$j,8,$j
        +	std	$nlod,[%sp+$bias+$frame+24]
        +	bnz,pt	%icc,.Linner
        +	add	$tp,8,$tp
        +
        +.Linnerskip:
        +	fdtox	$dota,$dota
        +	fdtox	$dotb,$dotb
        +
        +	ldx	[%sp+$bias+$frame+0],%o0
        +	ldx	[%sp+$bias+$frame+8],%o1
        +	ldx	[%sp+$bias+$frame+16],%o2
        +	ldx	[%sp+$bias+$frame+24],%o3
        +
        +	srlx	%o0,16,%o7
        +	std	$dota,[%sp+$bias+$frame+32]
        +	add	%o7,%o1,%o1
        +	std	$dotb,[%sp+$bias+$frame+40]
        +	srlx	%o1,16,%o7
        +	add	%o7,%o2,%o2
        +	srlx	%o2,16,%o7
        +	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
        +	and	%o0,$mask,%o0
        +	and	%o1,$mask,%o1
        +	and	%o2,$mask,%o2
        +	sllx	%o1,16,%o1
        +	sllx	%o2,32,%o2
        +	sllx	%o3,48,%o7
        +	or	%o1,%o0,%o0
        +	or	%o2,%o0,%o0
        +	ldx	[%sp+$bias+$frame+32],%o4
        +	or	%o7,%o0,%o0		! 64-bit result
        +	ldx	[%sp+$bias+$frame+40],%o5
        +	addcc	%g1,%o0,%o0
        +	ldx	[$tp+8],%o7		! tp[j]
        +	srlx	%o3,16,%g1		! 34-bit carry
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	addcc	%o7,%o0,%o0
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	stx	%o0,[$tp]		! tp[j-1]
        +	add	$tp,8,$tp
        +
        +	srlx	%o4,16,%o7
        +	add	%o7,%o5,%o5
        +	and	%o4,$mask,%o4
        +	sllx	%o5,16,%o7
        +	or	%o7,%o4,%o4
        +	addcc	%g1,%o4,%o4
        +	srlx	%o5,48,%g1
        +	bcs,a	%xcc,.+8
        +	add	%g1,1,%g1
        +
        +	addcc	$carry,%o4,%o4
        +	stx	%o4,[$tp]		! tp[num-1]
        +	mov	%g1,$carry
        +	bcs,a	%xcc,.+8
        +	add	$carry,1,$carry
        +
        +	addcc	$i,8,$i
        +	bnz	%icc,.Louter
        +	nop
        +
        +	add	$tp,8,$tp		! adjust tp to point at the end
        +	orn	%g0,%g0,%g4
        +	sub	%g0,$num,%o7		! n=-num
        +	ba	.Lsub
        +	subcc	%g0,%g0,%g0		! clear %icc.c
        +
        +.align	32
        +.Lsub:
        +	ldx	[$tp+%o7],%o0
        +	add	$np,%o7,%g1
        +	ld	[%g1+0],%o2
        +	ld	[%g1+4],%o3
        +	srlx	%o0,32,%o1
        +	subccc	%o0,%o2,%o2
        +	add	$rp,%o7,%g1
        +	subccc	%o1,%o3,%o3
        +	st	%o2,[%g1+0]
        +	add	%o7,8,%o7
        +	brnz,pt	%o7,.Lsub
        +	st	%o3,[%g1+4]
        +	subc	$carry,0,%g4
        +	sub	%g0,$num,%o7		! n=-num
        +	ba	.Lcopy
        +	nop
        +
        +.align	32
        +.Lcopy:
        +	ldx	[$tp+%o7],%o0
        +	add	$rp,%o7,%g1
        +	ld	[%g1+0],%o2
        +	ld	[%g1+4],%o3
        +	stx	%g0,[$tp+%o7]
        +	and	%o0,%g4,%o0
        +	srlx	%o0,32,%o1
        +	andn	%o2,%g4,%o2
        +	andn	%o3,%g4,%o3
        +	or	%o2,%o0,%o0
        +	or	%o3,%o1,%o1
        +	st	%o0,[%g1+0]
        +	add	%o7,8,%o7
        +	brnz,pt	%o7,.Lcopy
        +	st	%o1,[%g1+4]
        +	sub	%g0,$num,%o7		! n=-num
        +
        +.Lzap:
        +	stx	%g0,[$ap_l+%o7]
        +	stx	%g0,[$ap_h+%o7]
        +	stx	%g0,[$np_l+%o7]
        +	stx	%g0,[$np_h+%o7]
        +	add	%o7,8,%o7
        +	brnz,pt	%o7,.Lzap
        +	nop
        +
        +	ldx	[%sp+$bias+$frame+48],%o7
        +	wr	%g0,%o7,%asi		! restore %asi
        +
        +	mov	1,%i0
        +.Lret:
        +	ret
        +	restore
        +.type   $fname,#function
        +.size	$fname,(.-$fname)
        +.asciz	"Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	32
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +
        +# Below substitution makes it possible to compile without demanding
        +# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
        +# dare to do this, because VIS capability is detected at run-time now
        +# and this routine is not called on CPU not capable to execute it. Do
        +# note that fzeros is not the only VIS dependency! Another dependency
        +# is implicit and is just _a_ numerical value loaded to %asi register,
        +# which assembler can't recognize as VIS specific...
        +$code =~ s/fzeros\s+%f([0-9]+)/
        +	   sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
        +	  /gem;
        +
        +print $code;
        +# flush
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/via-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/via-mont.pl
        new file mode 100644
        index 000000000..c046a514c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/via-mont.pl
        @@ -0,0 +1,242 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# Wrapper around 'rep montmul', VIA-specific instruction accessing
        +# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
        +# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
        +#
        +# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
        +# different software configurations on 1.5GHz VIA Esther processor.
        +# Lines marked with "software integer" denote performance of hand-
        +# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
        +# refers to hand-coded SSE2 Montgomery multiplication procedure found
        +# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
        +# Padlock SDK 2.0.1 available for download from VIA, which naturally
        +# utilizes the magic 'repz montmul' instruction. And finally "hardware
        +# this" refers to *this* implementation which also uses 'repz montmul'
        +#
        +#                   sign    verify    sign/s verify/s
        +# rsa  512 bits 0.001720s 0.000140s    581.4   7149.7	software integer
        +# rsa  512 bits 0.000690s 0.000086s   1450.3  11606.0	software SSE2
        +# rsa  512 bits 0.006136s 0.000201s    163.0   4974.5	hardware VIA SDK
        +# rsa  512 bits 0.000712s 0.000050s   1404.9  19858.5	hardware this
        +#
        +# rsa 1024 bits 0.008518s 0.000413s    117.4   2420.8	software integer
        +# rsa 1024 bits 0.004275s 0.000277s    233.9   3609.7	software SSE2
        +# rsa 1024 bits 0.012136s 0.000260s     82.4   3844.5	hardware VIA SDK
        +# rsa 1024 bits 0.002522s 0.000116s    396.5   8650.9	hardware this
        +#
        +# rsa 2048 bits 0.050101s 0.001371s     20.0    729.6	software integer
        +# rsa 2048 bits 0.030273s 0.001008s     33.0    991.9	software SSE2
        +# rsa 2048 bits 0.030833s 0.000976s     32.4   1025.1	hardware VIA SDK
        +# rsa 2048 bits 0.011879s 0.000342s     84.2   2921.7	hardware this
        +#
        +# rsa 4096 bits 0.327097s 0.004859s      3.1    205.8	software integer
        +# rsa 4096 bits 0.229318s 0.003859s      4.4    259.2	software SSE2
        +# rsa 4096 bits 0.233953s 0.003274s      4.3    305.4	hardware VIA SDK
        +# rsa 4096 bits 0.070493s 0.001166s     14.2    857.6	hardware this
        +#
        +# dsa  512 bits 0.001342s 0.001651s    745.2    605.7	software integer
        +# dsa  512 bits 0.000844s 0.000987s   1185.3   1013.1	software SSE2
        +# dsa  512 bits 0.001902s 0.002247s    525.6    444.9	hardware VIA SDK
        +# dsa  512 bits 0.000458s 0.000524s   2182.2   1909.1	hardware this
        +#
        +# dsa 1024 bits 0.003964s 0.004926s    252.3    203.0	software integer
        +# dsa 1024 bits 0.002686s 0.003166s    372.3    315.8	software SSE2
        +# dsa 1024 bits 0.002397s 0.002823s    417.1    354.3	hardware VIA SDK
        +# dsa 1024 bits 0.000978s 0.001170s   1022.2    855.0	hardware this
        +#
        +# dsa 2048 bits 0.013280s 0.016518s     75.3     60.5	software integer
        +# dsa 2048 bits 0.009911s 0.011522s    100.9     86.8	software SSE2
        +# dsa 2048 bits 0.009542s 0.011763s    104.8     85.0	hardware VIA SDK
        +# dsa 2048 bits 0.002884s 0.003352s    346.8    298.3	hardware this
        +#
        +# To give you some other reference point here is output for 2.4GHz P4
        +# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
        +# SSE2" in above terms.
        +#
        +# rsa  512 bits 0.000407s 0.000047s   2454.2  21137.0
        +# rsa 1024 bits 0.002426s 0.000141s    412.1   7100.0
        +# rsa 2048 bits 0.015046s 0.000491s     66.5   2034.9
        +# rsa 4096 bits 0.109770s 0.002379s      9.1    420.3
        +# dsa  512 bits 0.000438s 0.000525s   2281.1   1904.1
        +# dsa 1024 bits 0.001346s 0.001595s    742.7    627.0
        +# dsa 2048 bits 0.004745s 0.005582s    210.7    179.1
        +#
        +# Conclusions: 
        +# - VIA SDK leaves a *lot* of room for improvement (which this
        +#   implementation successfully fills:-);
        +# - 'rep montmul' gives up to >3x performance improvement depending on
        +#   key length;
        +# - in terms of absolute performance it delivers approximately as much
        +#   as modern out-of-order 32-bit cores [again, for longer keys].
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"via-mont.pl");
        +
        +# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
        +$func="bn_mul_mont_padlock";
        +
        +$pad=16*1;	# amount of reserved bytes on top of every vector
        +
        +# stack layout
        +$mZeroPrime=&DWP(0,"esp");		# these are specified by VIA
        +$A=&DWP(4,"esp");
        +$B=&DWP(8,"esp");
        +$T=&DWP(12,"esp");
        +$M=&DWP(16,"esp");
        +$scratch=&DWP(20,"esp");
        +$rp=&DWP(24,"esp");			# these are mine
        +$sp=&DWP(28,"esp");
        +# &DWP(32,"esp")			# 32 byte scratch area
        +# &DWP(64+(4*$num+$pad)*0,"esp")	# padded tp[num]
        +# &DWP(64+(4*$num+$pad)*1,"esp")	# padded copy of ap[num]
        +# &DWP(64+(4*$num+$pad)*2,"esp")	# padded copy of bp[num]
        +# &DWP(64+(4*$num+$pad)*3,"esp")	# padded copy of np[num]
        +# Note that SDK suggests to unconditionally allocate 2K per vector. This
        +# has quite an impact on performance. It naturally depends on key length,
        +# but to give an example 1024 bit private RSA key operations suffer >30%
        +# penalty. I allocate only as much as actually required...
        +
        +&function_begin($func);
        +	&xor	("eax","eax");
        +	&mov	("ecx",&wparam(5));	# num
        +	# meet VIA's limitations for num [note that the specification
        +	# expresses them in bits, while we work with amount of 32-bit words]
        +	&test	("ecx",3);
        +	&jnz	(&label("leave"));	# num % 4 != 0
        +	&cmp	("ecx",8);
        +	&jb	(&label("leave"));	# num < 8
        +	&cmp	("ecx",1024);
        +	&ja	(&label("leave"));	# num > 1024
        +
        +	&pushf	();
        +	&cld	();
        +
        +	&mov	("edi",&wparam(0));	# rp
        +	&mov	("eax",&wparam(1));	# ap
        +	&mov	("ebx",&wparam(2));	# bp
        +	&mov	("edx",&wparam(3));	# np
        +	&mov	("esi",&wparam(4));	# n0
        +	&mov	("esi",&DWP(0,"esi"));	# *n0
        +
        +	&lea	("ecx",&DWP($pad,"","ecx",4));	# ecx becomes vector size in bytes
        +	&lea	("ebp",&DWP(64,"","ecx",4));	# allocate 4 vectors + 64 bytes
        +	&neg	("ebp");
        +	&add	("ebp","esp");
        +	&and	("ebp",-64);		# align to cache-line
        +	&xchg	("ebp","esp");		# alloca
        +
        +	&mov	($rp,"edi");		# save rp
        +	&mov	($sp,"ebp");		# save esp
        +
        +	&mov	($mZeroPrime,"esi");
        +	&lea	("esi",&DWP(64,"esp"));	# tp
        +	&mov	($T,"esi");
        +	&lea	("edi",&DWP(32,"esp"));	# scratch area
        +	&mov	($scratch,"edi");
        +	&mov	("esi","eax");
        +
        +	&lea	("ebp",&DWP(-$pad,"ecx"));
        +	&shr	("ebp",2);		# restore original num value in ebp
        +
        +	&xor	("eax","eax");
        +
        +	&mov	("ecx","ebp");
        +	&lea	("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
        +	&data_byte(0xf3,0xab);		# rep stosl, bzero
        +
        +	&mov	("ecx","ebp");
        +	&lea	("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
        +	&mov	($A,"edi");
        +	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
        +	&mov	("ecx",$pad/4);
        +	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
        +	# edi points at the end of padded ap copy...
        +
        +	&mov	("ecx","ebp");
        +	&mov	("esi","ebx");
        +	&mov	($B,"edi");
        +	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
        +	&mov	("ecx",$pad/4);
        +	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
        +	# edi points at the end of padded bp copy...
        +
        +	&mov	("ecx","ebp");
        +	&mov	("esi","edx");
        +	&mov	($M,"edi");
        +	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
        +	&mov	("ecx",$pad/4);
        +	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
        +	# edi points at the end of padded np copy...
        +
        +	# let magic happen...
        +	&mov	("ecx","ebp");
        +	&mov	("esi","esp");
        +	&shl	("ecx",5);		# convert word counter to bit counter
        +	&align	(4);
        +	&data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
        +
        +	&mov	("ecx","ebp");
        +	&lea	("esi",&DWP(64,"esp"));		# tp
        +	# edi still points at the end of padded np copy...
        +	&neg	("ebp");
        +	&lea	("ebp",&DWP(-$pad,"edi","ebp",4));	# so just "rewind"
        +	&mov	("edi",$rp);			# restore rp
        +	&xor	("edx","edx");			# i=0 and clear CF
        +
        +&set_label("sub",8);
        +	&mov	("eax",&DWP(0,"esi","edx",4));
        +	&sbb	("eax",&DWP(0,"ebp","edx",4));
        +	&mov	(&DWP(0,"edi","edx",4),"eax");	# rp[i]=tp[i]-np[i]
        +	&lea	("edx",&DWP(1,"edx"));		# i++
        +	&loop	(&label("sub"));		# doesn't affect CF!
        +
        +	&mov	("eax",&DWP(0,"esi","edx",4));	# upmost overflow bit
        +	&sbb	("eax",0);
        +	&and	("esi","eax");
        +	&not	("eax");
        +	&mov	("ebp","edi");
        +	&and	("ebp","eax");
        +	&or	("esi","ebp");			# tp=carry?tp:rp
        +
        +	&mov	("ecx","edx");			# num
        +	&xor	("edx","edx");			# i=0
        +
        +&set_label("copy",8);
        +	&mov	("eax",&DWP(0,"esi","edx",4));
        +	&mov	(&DWP(64,"esp","edx",4),"ecx");	# zap tp
        +	&mov	(&DWP(0,"edi","edx",4),"eax");
        +	&lea	("edx",&DWP(1,"edx"));		# i++
        +	&loop	(&label("copy"));
        +
        +	&mov	("ebp",$sp);
        +	&xor	("eax","eax");
        +
        +	&mov	("ecx",64/4);
        +	&mov	("edi","esp");		# zap frame including scratch area
        +	&data_byte(0xf3,0xab);		# rep stosl, bzero
        +
        +	# zap copies of ap, bp and np
        +	&lea	("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
        +	&lea	("ecx",&DWP(3*$pad/4,"edx","edx",2));
        +	&data_byte(0xf3,0xab);		# rep stosl, bzero
        +
        +	&mov	("esp","ebp");
        +	&inc	("eax");		# signal "done"
        +	&popf	();
        +&set_label("leave");
        +&function_end($func);
        +
        +&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/vms.mar b/vendor/openssl/openssl/crypto/bn/asm/vms.mar
        new file mode 100644
        index 000000000..aefab15cd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/vms.mar
        @@ -0,0 +1,6440 @@
        +	.title	vax_bn_mul_add_words  unsigned multiply & add, 32*32+32+32=>64
        +;
        +; w.j.m. 15-jan-1999
        +;
        +; it's magic ...
        +;
        +; ULONG bn_mul_add_words(ULONG r[],ULONG a[],int n,ULONG w) {
        +;	ULONG c = 0;
        +;	int i;
        +;	for(i = 0; i < n; i++) <c,r[i]> := r[i] + c + a[i] * w ;
        +;	return c;
        +; }
        +
        +r=4 ;(AP)
        +a=8 ;(AP)
        +n=12 ;(AP)	n	by value (input)
        +w=16 ;(AP)	w	by value (input)
        +
        +
        +	.psect	code,nowrt
        +
        +.entry	bn_mul_add_words,^m<r2,r3,r4,r5,r6>
        +
        +	moval	@r(ap),r2
        +	moval	@a(ap),r3
        +	movl	n(ap),r4	; assumed >0 by C code
        +	movl	w(ap),r5
        +	clrl	r6		; c
        +
        +0$:
        +	emul	r5,(r3),(r2),r0		; w, a[], r[] considered signed
        +
        +	; fixup for "negative" r[]
        +	tstl	(r2)
        +	bgeq	10$
        +	incl	r1
        +10$:
        +
        +	; add in c
        +	addl2	r6,r0
        +	adwc	#0,r1
        +
        +	; combined fixup for "negative" w, a[]
        +	tstl	r5
        +	bgeq	20$
        +	addl2	(r3),r1
        +20$:
        +	tstl	(r3)
        +	bgeq	30$
        +	addl2	r5,r1
        +30$:
        +
        +	movl	r0,(r2)+		; store lo result in r[] & advance
        +	addl	#4,r3			; advance a[]
        +	movl	r1,r6			; store hi result => c
        +
        +	sobgtr	r4,0$
        +
        +	movl	r6,r0			; return c
        +	ret
        +
        +	.title	vax_bn_mul_words  unsigned multiply & add, 32*32+32=>64
        +;
        +; w.j.m. 15-jan-1999
        +;
        +; it's magic ...
        +;
        +; ULONG bn_mul_words(ULONG r[],ULONG a[],int n,ULONG w) {
        +;	ULONG c = 0;
        +;	int i;
        +;	for(i = 0; i < num; i++) <c,r[i]> := a[i] * w + c ;
        +;	return(c);
        +; }
        +
        +r=4 ;(AP)
        +a=8 ;(AP)
        +n=12 ;(AP)	n	by value (input)
        +w=16 ;(AP)	w	by value (input)
        +
        +
        +	.psect	code,nowrt
        +
        +.entry	bn_mul_words,^m<r2,r3,r4,r5,r6>
        +
        +	moval	@r(ap),r2	; r2 -> r[]
        +	moval	@a(ap),r3	; r3 -> a[]
        +	movl	n(ap),r4	; r4 = loop count (assumed >0 by C code)
        +	movl	w(ap),r5	; r5 = w
        +	clrl	r6		; r6 = c
        +
        +0$:
        +	; <r1,r0> := w * a[] + c
        +	emul	r5,(r3),r6,r0		; w, a[], c considered signed
        +
        +	; fixup for "negative" c
        +	tstl	r6			; c
        +	bgeq	10$
        +	incl	r1
        +10$:
        +
        +	; combined fixup for "negative" w, a[]
        +	tstl	r5			; w
        +	bgeq	20$
        +	addl2	(r3),r1			; a[]
        +20$:
        +	tstl	(r3)			; a[]
        +	bgeq	30$
        +	addl2	r5,r1			; w
        +30$:
        +
        +	movl	r0,(r2)+		; store lo result in r[] & advance
        +	addl	#4,r3			; advance a[]
        +	movl	r1,r6			; store hi result => c
        +
        +	sobgtr	r4,0$
        +
        +	movl	r6,r0			; return c
        +	ret
        +
        +	.title	vax_bn_sqr_words  unsigned square, 32*32=>64
        +;
        +; w.j.m. 15-jan-1999
        +;
        +; it's magic ...
        +;
        +; void bn_sqr_words(ULONG r[],ULONG a[],int n) {
        +;	int i;
        +;	for(i = 0; i < n; i++) <r[2*i+1],r[2*i]> := a[i] * a[i] ;
        +; }
        +
        +r=4 ;(AP)
        +a=8 ;(AP)
        +n=12 ;(AP)	n	by value (input)
        +
        +
        +	.psect	code,nowrt
        +
        +.entry	bn_sqr_words,^m<r2,r3,r4,r5>
        +
        +	moval	@r(ap),r2	; r2 -> r[]
        +	moval	@a(ap),r3	; r3 -> a[]
        +	movl	n(ap),r4	; r4 = n (assumed >0 by C code)
        +
        +0$:
        +	movl	(r3)+,r5		; r5 = a[] & advance
        +
        +	; <r1,r0> := a[] * a[]
        +	emul	r5,r5,#0,r0		; a[] considered signed
        +
        +	; fixup for "negative" a[]
        +	tstl	r5			; a[]
        +	bgeq	30$
        +	addl2	r5,r1			; a[]
        +	addl2	r5,r1			; a[]
        +30$:
        +
        +	movl	r0,(r2)+		; store lo result in r[] & advance
        +	movl	r1,(r2)+		; store hi result in r[] & advance
        +
        +	sobgtr	r4,0$
        +
        +	movl	#1,r0			; return SS$_NORMAL
        +	ret
        +
        +	.title	vax_bn_div_words  unsigned divide
        +;
        +; Richard Levitte 20-Nov-2000
        +;
        +; ULONG bn_div_words(ULONG h, ULONG l, ULONG d)
        +; {
        +;	return ((ULONG)((((ULLONG)h)<<32)|l) / (ULLONG)d);
        +; }
        +;
        +; Using EDIV would be very easy, if it didn't do signed calculations.
        +; Any time any of the input numbers are signed, there are problems,
        +; usually with integer overflow, at which point it returns useless
        +; data (the quotient gets the value of l, and the remainder becomes 0).
        +;
        +; If it was just for the dividend, it would be very easy, just divide
        +; it by 2 (unsigned), do the division, multiply the resulting quotient
        +; and remainder by 2, add the bit that was dropped when dividing by 2
        +; to the remainder, and do some adjustment so the remainder doesn't
        +; end up larger than the divisor.  For some cases when the divisor is
        +; negative (from EDIV's point of view, i.e. when the highest bit is set),
        +; dividing the dividend by 2 isn't enough, and since some operations
        +; might generate integer overflows even when the dividend is divided by
        +; 4 (when the high part of the shifted down dividend ends up being exactly
        +; half of the divisor, the result is the quotient 0x80000000, which is
        +; negative...) it needs to be divided by 8.  Furthermore, the divisor needs
        +; to be divided by 2 (unsigned) as well, to avoid more problems with the sign.
        +; In this case, a little extra fiddling with the remainder is required.
        +;
        +; So, the simplest way to handle this is always to divide the dividend
        +; by 8, and to divide the divisor by 2 if it's highest bit is set.
        +; After EDIV has been used, the quotient gets multiplied by 8 if the
        +; original divisor was positive, otherwise 4.  The remainder, oddly
        +; enough, is *always* multiplied by 8.
        +; NOTE: in the case mentioned above, where the high part of the shifted
        +; down dividend ends up being exactly half the shifted down divisor, we
        +; end up with a 33 bit quotient.  That's no problem however, it usually
        +; means we have ended up with a too large remainder as well, and the
        +; problem is fixed by the last part of the algorithm (next paragraph).
        +;
        +; The routine ends with comparing the resulting remainder with the
        +; original divisor and if the remainder is larger, subtract the
        +; original divisor from it, and increase the quotient by 1.  This is
        +; done until the remainder is smaller than the divisor.
        +;
        +; The complete algorithm looks like this:
        +;
        +; d'    = d
        +; l'    = l & 7
        +; [h,l] = [h,l] >> 3
        +; [q,r] = floor([h,l] / d)	# This is the EDIV operation
        +; if (q < 0) q = -q		# I doubt this is necessary any more
        +;
        +; r'    = r >> 29
        +; if (d' >= 0)
        +;   q'  = q >> 29
        +;   q   = q << 3
        +; else
        +;   q'  = q >> 30
        +;   q   = q << 2
        +; r     = (r << 3) + l'
        +;
        +; if (d' < 0)
        +;   {
        +;     [r',r] = [r',r] - q
        +;     while ([r',r] < 0)
        +;       {
        +;         [r',r] = [r',r] + d
        +;         [q',q] = [q',q] - 1
        +;       }
        +;   }
        +;
        +; while ([r',r] >= d')
        +;   {
        +;     [r',r] = [r',r] - d'
        +;     [q',q] = [q',q] + 1
        +;   }
        +;
        +; return q
        +
        +h=4 ;(AP)	h	by value (input)
        +l=8 ;(AP)	l	by value (input)
        +d=12 ;(AP)	d	by value (input)
        +
        +;r2 = l, q
        +;r3 = h, r
        +;r4 = d
        +;r5 = l'
        +;r6 = r'
        +;r7 = d'
        +;r8 = q'
        +
        +	.psect	code,nowrt
        +
        +.entry	bn_div_words,^m<r2,r3,r4,r5,r6,r7,r8>
        +	movl	l(ap),r2
        +	movl	h(ap),r3
        +	movl	d(ap),r4
        +
        +	bicl3	#^XFFFFFFF8,r2,r5 ; l' = l & 7
        +	bicl3	#^X00000007,r2,r2
        +
        +	bicl3	#^XFFFFFFF8,r3,r6
        +	bicl3	#^X00000007,r3,r3
        +        
        +	addl	r6,r2
        +
        +	rotl	#-3,r2,r2	; l = l >> 3
        +	rotl	#-3,r3,r3	; h = h >> 3
        +                
        +	movl	r4,r7		; d' = d
        +
        +	movl	#0,r6		; r' = 0
        +	movl	#0,r8		; q' = 0
        +
        +	tstl	r4
        +	beql	666$		; Uh-oh, the divisor is 0...
        +	bgtr	1$
        +	rotl	#-1,r4,r4	; If d is negative, shift it right.
        +	bicl2	#^X80000000,r4	; Since d is then a large number, the
        +				; lowest bit is insignificant
        +				; (contradict that, and I'll fix the problem!)
        +1$:     
        +	ediv	r4,r2,r2,r3	; Do the actual division
        +
        +	tstl	r2
        +	bgeq	3$
        +	mnegl	r2,r2		; if q < 0, negate it
        +3$:     
        +	tstl	r7
        +	blss	4$
        +	rotl	#3,r2,r2	;   q = q << 3
        +	bicl3	#^XFFFFFFF8,r2,r8 ;    q' gets the high bits from q
        +	bicl3	#^X00000007,r2,r2
        +	bsb	41$
        +4$:				; else
        +	rotl	#2,r2,r2	;   q = q << 2
        +	bicl3	#^XFFFFFFFC,r2,r8 ;   q' gets the high bits from q
        +	bicl3	#^X00000003,r2,r2
        +41$:
        +	rotl	#3,r3,r3	; r = r << 3
        +	bicl3	#^XFFFFFFF8,r3,r6 ; r' gets the high bits from r
        +	bicl3	#^X00000007,r3,r3
        +	addl	r5,r3		; r = r + l'
        +
        +	tstl	r7
        +	bgeq	5$
        +	bitl	#1,r7
        +	beql	5$		; if d' < 0 && d' & 1
        +	subl	r2,r3		;   [r',r] = [r',r] - [q',q]
        +	sbwc	r8,r6
        +45$:
        +	bgeq	5$		;   while r < 0
        +	decl	r2		;     [q',q] = [q',q] - 1
        +	sbwc	#0,r8
        +	addl	r7,r3		;     [r',r] = [r',r] + d'
        +	adwc	#0,r6
        +	brb	45$
        +
        +; The return points are placed in the middle to keep a short distance from
        +; all the branch points
        +42$:
        +;	movl	r3,r1
        +	movl	r2,r0
        +	ret
        +666$:
        +	movl	#^XFFFFFFFF,r0
        +	ret
        +
        +5$:
        +	tstl	r6
        +	bneq	6$
        +	cmpl	r3,r7
        +	blssu	42$		; while [r',r] >= d'
        +6$:
        +	subl	r7,r3		;   [r',r] = [r',r] - d'
        +	sbwc	#0,r6
        +	incl	r2		;   [q',q] = [q',q] + 1
        +	adwc	#0,r8
        +	brb	5$	
        +
        +	.title	vax_bn_add_words  unsigned add of two arrays
        +;
        +; Richard Levitte 20-Nov-2000
        +;
        +; ULONG bn_add_words(ULONG r[], ULONG a[], ULONG b[], int n) {
        +;	ULONG c = 0;
        +;	int i;
        +;	for (i = 0; i < n; i++) <c,r[i]> = a[i] + b[i] + c;
        +;	return(c);
        +; }
        +
        +r=4 ;(AP)	r	by reference (output)
        +a=8 ;(AP)	a	by reference (input)
        +b=12 ;(AP)	b	by reference (input)
        +n=16 ;(AP)	n	by value (input)
        +
        +
        +	.psect	code,nowrt
        +
        +.entry	bn_add_words,^m<r2,r3,r4,r5,r6>
        +
        +	moval	@r(ap),r2
        +	moval	@a(ap),r3
        +	moval	@b(ap),r4
        +	movl	n(ap),r5	; assumed >0 by C code
        +	clrl	r0		; c
        +
        +	tstl	r5		; carry = 0
        +	bleq	666$
        +
        +0$:
        +	movl	(r3)+,r6	; carry untouched
        +	adwc	(r4)+,r6	; carry used and touched
        +	movl	r6,(r2)+	; carry untouched
        +	sobgtr	r5,0$		; carry untouched
        +
        +	adwc	#0,r0
        +666$:
        +	ret
        +
        +	.title	vax_bn_sub_words  unsigned add of two arrays
        +;
        +; Richard Levitte 20-Nov-2000
        +;
        +; ULONG bn_sub_words(ULONG r[], ULONG a[], ULONG b[], int n) {
        +;	ULONG c = 0;
        +;	int i;
        +;	for (i = 0; i < n; i++) <c,r[i]> = a[i] - b[i] - c;
        +;	return(c);
        +; }
        +
        +r=4 ;(AP)	r	by reference (output)
        +a=8 ;(AP)	a	by reference (input)
        +b=12 ;(AP)	b	by reference (input)
        +n=16 ;(AP)	n	by value (input)
        +
        +
        +	.psect	code,nowrt
        +
        +.entry	bn_sub_words,^m<r2,r3,r4,r5,r6>
        +
        +	moval	@r(ap),r2
        +	moval	@a(ap),r3
        +	moval	@b(ap),r4
        +	movl	n(ap),r5	; assumed >0 by C code
        +	clrl	r0		; c
        +
        +	tstl	r5		; carry = 0
        +	bleq	666$
        +
        +0$:
        +	movl	(r3)+,r6	; carry untouched
        +	sbwc	(r4)+,r6	; carry used and touched
        +	movl	r6,(r2)+	; carry untouched
        +	sobgtr	r5,0$		; carry untouched
        +
        +	adwc	#0,r0
        +666$:
        +	ret
        +
        +
        +;r=4 ;(AP)
        +;a=8 ;(AP)
        +;b=12 ;(AP)
        +;n=16 ;(AP)	n	by value (input)
        +
        +	.psect	code,nowrt
        +
        +.entry	BN_MUL_COMBA8,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
        +	movab	-924(sp),sp
        +	clrq	r8
        +
        +	clrl	r10
        +
        +	movl	8(ap),r6
        +	movzwl	2(r6),r3
        +	movl	12(ap),r7
        +	bicl3	#-65536,(r7),r2
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-12(fp)
        +	bicl3	#-65536,r3,-16(fp)
        +	mull3	r0,-12(fp),-4(fp)
        +	mull2	r2,-12(fp)
        +	mull3	r2,-16(fp),-8(fp)
        +	mull2	r0,-16(fp)
        +	addl3	-4(fp),-8(fp),r0
        +	bicl3	#0,r0,-4(fp)
        +	cmpl	-4(fp),-8(fp)
        +	bgequ	noname.45
        +	addl2	#65536,-16(fp)
        +noname.45:
        +	movzwl	-2(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-16(fp)
        +	bicl3	#-65536,-4(fp),r0
        +	ashl	#16,r0,-8(fp)
        +	addl3	-8(fp),-12(fp),r0
        +	bicl3	#0,r0,-12(fp)
        +	cmpl	-12(fp),-8(fp)
        +	bgequ	noname.46
        +	incl	-16(fp)
        +noname.46:
        +	movl	-12(fp),r1
        +	movl	-16(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.47
        +	incl	r2
        +noname.47:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.48
        +	incl	r10
        +noname.48:
        +
        +	movl	4(ap),r11
        +	movl	r9,(r11)
        +
        +	clrl	r9
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-28(fp)
        +	bicl3	#-65536,r2,-32(fp)
        +	mull3	r0,-28(fp),-20(fp)
        +	mull2	r3,-28(fp)
        +	mull3	r3,-32(fp),-24(fp)
        +	mull2	r0,-32(fp)
        +	addl3	-20(fp),-24(fp),r0
        +	bicl3	#0,r0,-20(fp)
        +	cmpl	-20(fp),-24(fp)
        +	bgequ	noname.49
        +	addl2	#65536,-32(fp)
        +noname.49:
        +	movzwl	-18(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-32(fp)
        +	bicl3	#-65536,-20(fp),r0
        +	ashl	#16,r0,-24(fp)
        +	addl3	-24(fp),-28(fp),r0
        +	bicl3	#0,r0,-28(fp)
        +	cmpl	-28(fp),-24(fp)
        +	bgequ	noname.50
        +	incl	-32(fp)
        +noname.50:
        +	movl	-28(fp),r1
        +	movl	-32(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.51
        +	incl	r2
        +noname.51:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.52
        +	incl	r9
        +noname.52:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-44(fp)
        +	bicl3	#-65536,r2,-48(fp)
        +	mull3	r0,-44(fp),-36(fp)
        +	mull2	r3,-44(fp)
        +	mull3	r3,-48(fp),-40(fp)
        +	mull2	r0,-48(fp)
        +	addl3	-36(fp),-40(fp),r0
        +	bicl3	#0,r0,-36(fp)
        +	cmpl	-36(fp),-40(fp)
        +	bgequ	noname.53
        +	addl2	#65536,-48(fp)
        +noname.53:
        +	movzwl	-34(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-48(fp)
        +	bicl3	#-65536,-36(fp),r0
        +	ashl	#16,r0,-40(fp)
        +	addl3	-40(fp),-44(fp),r0
        +	bicl3	#0,r0,-44(fp)
        +	cmpl	-44(fp),-40(fp)
        +	bgequ	noname.54
        +	incl	-48(fp)
        +noname.54:
        +	movl	-44(fp),r1
        +	movl	-48(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.55
        +	incl	r2
        +noname.55:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.56
        +	incl	r9
        +noname.56:
        +
        +	movl	r8,4(r11)
        +
        +	clrl	r8
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-60(fp)
        +	bicl3	#-65536,r2,-64(fp)
        +	mull3	r0,-60(fp),-52(fp)
        +	mull2	r3,-60(fp)
        +	mull3	r3,-64(fp),-56(fp)
        +	mull2	r0,-64(fp)
        +	addl3	-52(fp),-56(fp),r0
        +	bicl3	#0,r0,-52(fp)
        +	cmpl	-52(fp),-56(fp)
        +	bgequ	noname.57
        +	addl2	#65536,-64(fp)
        +noname.57:
        +	movzwl	-50(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-64(fp)
        +	bicl3	#-65536,-52(fp),r0
        +	ashl	#16,r0,-56(fp)
        +	addl3	-56(fp),-60(fp),r0
        +	bicl3	#0,r0,-60(fp)
        +	cmpl	-60(fp),-56(fp)
        +	bgequ	noname.58
        +	incl	-64(fp)
        +noname.58:
        +	movl	-60(fp),r1
        +	movl	-64(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.59
        +	incl	r2
        +noname.59:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.60
        +	incl	r8
        +noname.60:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-76(fp)
        +	bicl3	#-65536,r2,-80(fp)
        +	mull3	r0,-76(fp),-68(fp)
        +	mull2	r3,-76(fp)
        +	mull3	r3,-80(fp),-72(fp)
        +	mull2	r0,-80(fp)
        +	addl3	-68(fp),-72(fp),r0
        +	bicl3	#0,r0,-68(fp)
        +	cmpl	-68(fp),-72(fp)
        +	bgequ	noname.61
        +	addl2	#65536,-80(fp)
        +noname.61:
        +	movzwl	-66(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-80(fp)
        +	bicl3	#-65536,-68(fp),r0
        +	ashl	#16,r0,-72(fp)
        +	addl3	-72(fp),-76(fp),r0
        +	bicl3	#0,r0,-76(fp)
        +	cmpl	-76(fp),-72(fp)
        +	bgequ	noname.62
        +	incl	-80(fp)
        +noname.62:
        +	movl	-76(fp),r1
        +	movl	-80(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.63
        +	incl	r2
        +noname.63:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.64
        +	incl	r8
        +noname.64:
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-92(fp)
        +	bicl3	#-65536,r2,-96(fp)
        +	mull3	r0,-92(fp),-84(fp)
        +	mull2	r3,-92(fp)
        +	mull3	r3,-96(fp),-88(fp)
        +	mull2	r0,-96(fp)
        +	addl3	-84(fp),-88(fp),r0
        +	bicl3	#0,r0,-84(fp)
        +	cmpl	-84(fp),-88(fp)
        +	bgequ	noname.65
        +	addl2	#65536,-96(fp)
        +noname.65:
        +	movzwl	-82(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-96(fp)
        +	bicl3	#-65536,-84(fp),r0
        +	ashl	#16,r0,-88(fp)
        +	addl3	-88(fp),-92(fp),r0
        +	bicl3	#0,r0,-92(fp)
        +	cmpl	-92(fp),-88(fp)
        +	bgequ	noname.66
        +	incl	-96(fp)
        +noname.66:
        +	movl	-92(fp),r1
        +	movl	-96(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.67
        +	incl	r2
        +noname.67:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.68
        +	incl	r8
        +noname.68:
        +
        +	movl	r10,8(r11)
        +
        +	clrl	r10
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-108(fp)
        +	bicl3	#-65536,r2,-112(fp)
        +	mull3	r0,-108(fp),-100(fp)
        +	mull2	r3,-108(fp)
        +	mull3	r3,-112(fp),-104(fp)
        +	mull2	r0,-112(fp)
        +	addl3	-100(fp),-104(fp),r0
        +	bicl3	#0,r0,-100(fp)
        +	cmpl	-100(fp),-104(fp)
        +	bgequ	noname.69
        +	addl2	#65536,-112(fp)
        +noname.69:
        +	movzwl	-98(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-112(fp)
        +	bicl3	#-65536,-100(fp),r0
        +	ashl	#16,r0,-104(fp)
        +	addl3	-104(fp),-108(fp),r0
        +	bicl3	#0,r0,-108(fp)
        +	cmpl	-108(fp),-104(fp)
        +	bgequ	noname.70
        +	incl	-112(fp)
        +noname.70:
        +	movl	-108(fp),r1
        +	movl	-112(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.71
        +	incl	r2
        +noname.71:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.72
        +	incl	r10
        +noname.72:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-124(fp)
        +	bicl3	#-65536,r2,-128(fp)
        +	mull3	r0,-124(fp),-116(fp)
        +	mull2	r3,-124(fp)
        +	mull3	r3,-128(fp),-120(fp)
        +	mull2	r0,-128(fp)
        +	addl3	-116(fp),-120(fp),r0
        +	bicl3	#0,r0,-116(fp)
        +	cmpl	-116(fp),-120(fp)
        +	bgequ	noname.73
        +	addl2	#65536,-128(fp)
        +noname.73:
        +	movzwl	-114(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-128(fp)
        +	bicl3	#-65536,-116(fp),r0
        +	ashl	#16,r0,-120(fp)
        +	addl3	-120(fp),-124(fp),r0
        +	bicl3	#0,r0,-124(fp)
        +	cmpl	-124(fp),-120(fp)
        +	bgequ	noname.74
        +	incl	-128(fp)
        +noname.74:
        +	movl	-124(fp),r1
        +	movl	-128(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.75
        +	incl	r2
        +noname.75:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.76
        +	incl	r10
        +noname.76:
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-140(fp)
        +	bicl3	#-65536,r2,-144(fp)
        +	mull3	r0,-140(fp),-132(fp)
        +	mull2	r3,-140(fp)
        +	mull3	r3,-144(fp),-136(fp)
        +	mull2	r0,-144(fp)
        +	addl3	-132(fp),-136(fp),r0
        +	bicl3	#0,r0,-132(fp)
        +	cmpl	-132(fp),-136(fp)
        +	bgequ	noname.77
        +	addl2	#65536,-144(fp)
        +noname.77:
        +	movzwl	-130(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-144(fp)
        +	bicl3	#-65536,-132(fp),r0
        +	ashl	#16,r0,-136(fp)
        +	addl3	-136(fp),-140(fp),r0
        +	bicl3	#0,r0,-140(fp)
        +	cmpl	-140(fp),-136(fp)
        +	bgequ	noname.78
        +	incl	-144(fp)
        +noname.78:
        +	movl	-140(fp),r1
        +	movl	-144(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.79
        +	incl	r2
        +noname.79:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.80
        +	incl	r10
        +noname.80:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-156(fp)
        +	bicl3	#-65536,r2,-160(fp)
        +	mull3	r0,-156(fp),-148(fp)
        +	mull2	r3,-156(fp)
        +	mull3	r3,-160(fp),-152(fp)
        +	mull2	r0,-160(fp)
        +	addl3	-148(fp),-152(fp),r0
        +	bicl3	#0,r0,-148(fp)
        +	cmpl	-148(fp),-152(fp)
        +	bgequ	noname.81
        +	addl2	#65536,-160(fp)
        +noname.81:
        +	movzwl	-146(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-160(fp)
        +	bicl3	#-65536,-148(fp),r0
        +	ashl	#16,r0,-152(fp)
        +	addl3	-152(fp),-156(fp),r0
        +	bicl3	#0,r0,-156(fp)
        +	cmpl	-156(fp),-152(fp)
        +	bgequ	noname.82
        +	incl	-160(fp)
        +noname.82:
        +	movl	-156(fp),r1
        +	movl	-160(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.83
        +	incl	r2
        +noname.83:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.84
        +	incl	r10
        +noname.84:
        +
        +	movl	r9,12(r11)
        +
        +	clrl	r9
        +
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r6),-172(fp)
        +	bicl3	#-65536,r2,-176(fp)
        +	mull3	r0,-172(fp),-164(fp)
        +	mull2	r3,-172(fp)
        +	mull3	r3,-176(fp),-168(fp)
        +	mull2	r0,-176(fp)
        +	addl3	-164(fp),-168(fp),r0
        +	bicl3	#0,r0,-164(fp)
        +	cmpl	-164(fp),-168(fp)
        +	bgequ	noname.85
        +	addl2	#65536,-176(fp)
        +noname.85:
        +	movzwl	-162(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-176(fp)
        +	bicl3	#-65536,-164(fp),r0
        +	ashl	#16,r0,-168(fp)
        +	addl3	-168(fp),-172(fp),r0
        +	bicl3	#0,r0,-172(fp)
        +	cmpl	-172(fp),-168(fp)
        +	bgequ	noname.86
        +	incl	-176(fp)
        +noname.86:
        +	movl	-172(fp),r1
        +	movl	-176(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.87
        +	incl	r2
        +noname.87:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.88
        +	incl	r9
        +noname.88:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-188(fp)
        +	bicl3	#-65536,r2,-192(fp)
        +	mull3	r0,-188(fp),-180(fp)
        +	mull2	r3,-188(fp)
        +	mull3	r3,-192(fp),-184(fp)
        +	mull2	r0,-192(fp)
        +	addl3	-180(fp),-184(fp),r0
        +	bicl3	#0,r0,-180(fp)
        +	cmpl	-180(fp),-184(fp)
        +	bgequ	noname.89
        +	addl2	#65536,-192(fp)
        +noname.89:
        +	movzwl	-178(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-192(fp)
        +	bicl3	#-65536,-180(fp),r0
        +	ashl	#16,r0,-184(fp)
        +	addl3	-184(fp),-188(fp),r0
        +	bicl3	#0,r0,-188(fp)
        +	cmpl	-188(fp),-184(fp)
        +	bgequ	noname.90
        +	incl	-192(fp)
        +noname.90:
        +	movl	-188(fp),r1
        +	movl	-192(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.91
        +	incl	r2
        +noname.91:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.92
        +	incl	r9
        +noname.92:
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-204(fp)
        +	bicl3	#-65536,r2,-208(fp)
        +	mull3	r0,-204(fp),-196(fp)
        +	mull2	r3,-204(fp)
        +	mull3	r3,-208(fp),-200(fp)
        +	mull2	r0,-208(fp)
        +	addl3	-196(fp),-200(fp),r0
        +	bicl3	#0,r0,-196(fp)
        +	cmpl	-196(fp),-200(fp)
        +	bgequ	noname.93
        +	addl2	#65536,-208(fp)
        +noname.93:
        +	movzwl	-194(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-208(fp)
        +	bicl3	#-65536,-196(fp),r0
        +	ashl	#16,r0,-200(fp)
        +	addl3	-200(fp),-204(fp),r0
        +	bicl3	#0,r0,-204(fp)
        +	cmpl	-204(fp),-200(fp)
        +	bgequ	noname.94
        +	incl	-208(fp)
        +noname.94:
        +	movl	-204(fp),r1
        +	movl	-208(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.95
        +	incl	r2
        +noname.95:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.96
        +	incl	r9
        +noname.96:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-220(fp)
        +	bicl3	#-65536,r2,-224(fp)
        +	mull3	r0,-220(fp),-212(fp)
        +	mull2	r3,-220(fp)
        +	mull3	r3,-224(fp),-216(fp)
        +	mull2	r0,-224(fp)
        +	addl3	-212(fp),-216(fp),r0
        +	bicl3	#0,r0,-212(fp)
        +	cmpl	-212(fp),-216(fp)
        +	bgequ	noname.97
        +	addl2	#65536,-224(fp)
        +noname.97:
        +	movzwl	-210(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-224(fp)
        +	bicl3	#-65536,-212(fp),r0
        +	ashl	#16,r0,-216(fp)
        +	addl3	-216(fp),-220(fp),r0
        +	bicl3	#0,r0,-220(fp)
        +	cmpl	-220(fp),-216(fp)
        +	bgequ	noname.98
        +	incl	-224(fp)
        +noname.98:
        +	movl	-220(fp),r1
        +	movl	-224(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.99
        +	incl	r2
        +noname.99:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.100
        +	incl	r9
        +noname.100:
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,16(r7),r3
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-236(fp)
        +	bicl3	#-65536,r2,-240(fp)
        +	mull3	r0,-236(fp),-228(fp)
        +	mull2	r3,-236(fp)
        +	mull3	r3,-240(fp),-232(fp)
        +	mull2	r0,-240(fp)
        +	addl3	-228(fp),-232(fp),r0
        +	bicl3	#0,r0,-228(fp)
        +	cmpl	-228(fp),-232(fp)
        +	bgequ	noname.101
        +	addl2	#65536,-240(fp)
        +noname.101:
        +	movzwl	-226(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-240(fp)
        +	bicl3	#-65536,-228(fp),r0
        +	ashl	#16,r0,-232(fp)
        +	addl3	-232(fp),-236(fp),r0
        +	bicl3	#0,r0,-236(fp)
        +	cmpl	-236(fp),-232(fp)
        +	bgequ	noname.102
        +	incl	-240(fp)
        +noname.102:
        +	movl	-236(fp),r1
        +	movl	-240(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.103
        +	incl	r2
        +noname.103:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.104
        +	incl	r9
        +noname.104:
        +
        +	movl	r8,16(r11)
        +
        +	clrl	r8
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,20(r7),r3
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-252(fp)
        +	bicl3	#-65536,r2,-256(fp)
        +	mull3	r0,-252(fp),-244(fp)
        +	mull2	r3,-252(fp)
        +	mull3	r3,-256(fp),-248(fp)
        +	mull2	r0,-256(fp)
        +	addl3	-244(fp),-248(fp),r0
        +	bicl3	#0,r0,-244(fp)
        +	cmpl	-244(fp),-248(fp)
        +	bgequ	noname.105
        +	addl2	#65536,-256(fp)
        +noname.105:
        +	movzwl	-242(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-256(fp)
        +	bicl3	#-65536,-244(fp),r0
        +	ashl	#16,r0,-248(fp)
        +	addl3	-248(fp),-252(fp),r0
        +	bicl3	#0,r0,-252(fp)
        +	cmpl	-252(fp),-248(fp)
        +	bgequ	noname.106
        +	incl	-256(fp)
        +noname.106:
        +	movl	-252(fp),r1
        +	movl	-256(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.107
        +	incl	r2
        +noname.107:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.108
        +	incl	r8
        +noname.108:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,16(r7),r3
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-268(fp)
        +	bicl3	#-65536,r2,-272(fp)
        +	mull3	r0,-268(fp),-260(fp)
        +	mull2	r3,-268(fp)
        +	mull3	r3,-272(fp),-264(fp)
        +	mull2	r0,-272(fp)
        +	addl3	-260(fp),-264(fp),r0
        +	bicl3	#0,r0,-260(fp)
        +	cmpl	-260(fp),-264(fp)
        +	bgequ	noname.109
        +	addl2	#65536,-272(fp)
        +noname.109:
        +	movzwl	-258(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-272(fp)
        +	bicl3	#-65536,-260(fp),r0
        +	ashl	#16,r0,-264(fp)
        +	addl3	-264(fp),-268(fp),r0
        +	bicl3	#0,r0,-268(fp)
        +	cmpl	-268(fp),-264(fp)
        +	bgequ	noname.110
        +	incl	-272(fp)
        +noname.110:
        +	movl	-268(fp),r1
        +	movl	-272(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.111
        +	incl	r2
        +noname.111:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.112
        +	incl	r8
        +noname.112:
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-284(fp)
        +	bicl3	#-65536,r2,-288(fp)
        +	mull3	r0,-284(fp),-276(fp)
        +	mull2	r3,-284(fp)
        +	mull3	r3,-288(fp),-280(fp)
        +	mull2	r0,-288(fp)
        +	addl3	-276(fp),-280(fp),r0
        +	bicl3	#0,r0,-276(fp)
        +	cmpl	-276(fp),-280(fp)
        +	bgequ	noname.113
        +	addl2	#65536,-288(fp)
        +noname.113:
        +	movzwl	-274(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-288(fp)
        +	bicl3	#-65536,-276(fp),r0
        +	ashl	#16,r0,-280(fp)
        +	addl3	-280(fp),-284(fp),r0
        +	bicl3	#0,r0,-284(fp)
        +	cmpl	-284(fp),-280(fp)
        +	bgequ	noname.114
        +	incl	-288(fp)
        +noname.114:
        +	movl	-284(fp),r1
        +	movl	-288(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.115
        +	incl	r2
        +noname.115:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.116
        +	incl	r8
        +noname.116:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-300(fp)
        +	bicl3	#-65536,r2,-304(fp)
        +	mull3	r0,-300(fp),-292(fp)
        +	mull2	r3,-300(fp)
        +	mull3	r3,-304(fp),-296(fp)
        +	mull2	r0,-304(fp)
        +	addl3	-292(fp),-296(fp),r0
        +	bicl3	#0,r0,-292(fp)
        +	cmpl	-292(fp),-296(fp)
        +	bgequ	noname.117
        +	addl2	#65536,-304(fp)
        +noname.117:
        +	movzwl	-290(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-304(fp)
        +	bicl3	#-65536,-292(fp),r0
        +	ashl	#16,r0,-296(fp)
        +	addl3	-296(fp),-300(fp),r0
        +	bicl3	#0,r0,-300(fp)
        +	cmpl	-300(fp),-296(fp)
        +	bgequ	noname.118
        +	incl	-304(fp)
        +noname.118:
        +	movl	-300(fp),r1
        +	movl	-304(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.119
        +	incl	r2
        +noname.119:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.120
        +	incl	r8
        +noname.120:
        +
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r6),-316(fp)
        +	bicl3	#-65536,r2,-320(fp)
        +	mull3	r0,-316(fp),-308(fp)
        +	mull2	r3,-316(fp)
        +	mull3	r3,-320(fp),-312(fp)
        +	mull2	r0,-320(fp)
        +	addl3	-308(fp),-312(fp),r0
        +	bicl3	#0,r0,-308(fp)
        +	cmpl	-308(fp),-312(fp)
        +	bgequ	noname.121
        +	addl2	#65536,-320(fp)
        +noname.121:
        +	movzwl	-306(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-320(fp)
        +	bicl3	#-65536,-308(fp),r0
        +	ashl	#16,r0,-312(fp)
        +	addl3	-312(fp),-316(fp),r0
        +	bicl3	#0,r0,-316(fp)
        +	cmpl	-316(fp),-312(fp)
        +	bgequ	noname.122
        +	incl	-320(fp)
        +noname.122:
        +	movl	-316(fp),r1
        +	movl	-320(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.123
        +	incl	r2
        +
        +noname.123:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.124
        +	incl	r8
        +noname.124:
        +
        +	movzwl	22(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,20(r6),-332(fp)
        +	bicl3	#-65536,r2,-336(fp)
        +	mull3	r0,-332(fp),-324(fp)
        +	mull2	r3,-332(fp)
        +	mull3	r3,-336(fp),-328(fp)
        +	mull2	r0,-336(fp)
        +	addl3	-324(fp),-328(fp),r0
        +	bicl3	#0,r0,-324(fp)
        +	cmpl	-324(fp),-328(fp)
        +	bgequ	noname.125
        +	addl2	#65536,-336(fp)
        +noname.125:
        +	movzwl	-322(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-336(fp)
        +	bicl3	#-65536,-324(fp),r0
        +	ashl	#16,r0,-328(fp)
        +	addl3	-328(fp),-332(fp),r0
        +	bicl3	#0,r0,-332(fp)
        +	cmpl	-332(fp),-328(fp)
        +	bgequ	noname.126
        +	incl	-336(fp)
        +noname.126:
        +	movl	-332(fp),r1
        +	movl	-336(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.127
        +	incl	r2
        +noname.127:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.128
        +	incl	r8
        +noname.128:
        +
        +	movl	r10,20(r11)
        +
        +	clrl	r10
        +
        +	movzwl	26(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,24(r6),-348(fp)
        +	bicl3	#-65536,r2,-352(fp)
        +	mull3	r0,-348(fp),-340(fp)
        +	mull2	r3,-348(fp)
        +	mull3	r3,-352(fp),-344(fp)
        +	mull2	r0,-352(fp)
        +	addl3	-340(fp),-344(fp),r0
        +	bicl3	#0,r0,-340(fp)
        +	cmpl	-340(fp),-344(fp)
        +	bgequ	noname.129
        +	addl2	#65536,-352(fp)
        +noname.129:
        +	movzwl	-338(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-352(fp)
        +	bicl3	#-65536,-340(fp),r0
        +	ashl	#16,r0,-344(fp)
        +	addl3	-344(fp),-348(fp),r0
        +	bicl3	#0,r0,-348(fp)
        +	cmpl	-348(fp),-344(fp)
        +	bgequ	noname.130
        +	incl	-352(fp)
        +noname.130:
        +	movl	-348(fp),r1
        +	movl	-352(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.131
        +	incl	r2
        +noname.131:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.132
        +	incl	r10
        +noname.132:
        +
        +	movzwl	22(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,20(r6),-364(fp)
        +	bicl3	#-65536,r2,-368(fp)
        +	mull3	r0,-364(fp),-356(fp)
        +	mull2	r3,-364(fp)
        +	mull3	r3,-368(fp),-360(fp)
        +	mull2	r0,-368(fp)
        +	addl3	-356(fp),-360(fp),r0
        +	bicl3	#0,r0,-356(fp)
        +	cmpl	-356(fp),-360(fp)
        +	bgequ	noname.133
        +	addl2	#65536,-368(fp)
        +noname.133:
        +	movzwl	-354(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-368(fp)
        +	bicl3	#-65536,-356(fp),r0
        +	ashl	#16,r0,-360(fp)
        +	addl3	-360(fp),-364(fp),r0
        +	bicl3	#0,r0,-364(fp)
        +	cmpl	-364(fp),-360(fp)
        +	bgequ	noname.134
        +	incl	-368(fp)
        +noname.134:
        +	movl	-364(fp),r1
        +	movl	-368(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.135
        +	incl	r2
        +noname.135:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.136
        +	incl	r10
        +noname.136:
        +
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r6),-380(fp)
        +	bicl3	#-65536,r2,-384(fp)
        +	mull3	r0,-380(fp),-372(fp)
        +	mull2	r3,-380(fp)
        +	mull3	r3,-384(fp),-376(fp)
        +	mull2	r0,-384(fp)
        +	addl3	-372(fp),-376(fp),r0
        +	bicl3	#0,r0,-372(fp)
        +	cmpl	-372(fp),-376(fp)
        +	bgequ	noname.137
        +	addl2	#65536,-384(fp)
        +noname.137:
        +	movzwl	-370(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-384(fp)
        +	bicl3	#-65536,-372(fp),r0
        +	ashl	#16,r0,-376(fp)
        +	addl3	-376(fp),-380(fp),r0
        +	bicl3	#0,r0,-380(fp)
        +	cmpl	-380(fp),-376(fp)
        +	bgequ	noname.138
        +	incl	-384(fp)
        +noname.138:
        +	movl	-380(fp),r1
        +	movl	-384(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.139
        +	incl	r2
        +noname.139:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.140
        +	incl	r10
        +noname.140:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-396(fp)
        +	bicl3	#-65536,r2,-400(fp)
        +	mull3	r0,-396(fp),-388(fp)
        +	mull2	r3,-396(fp)
        +	mull3	r3,-400(fp),-392(fp)
        +	mull2	r0,-400(fp)
        +	addl3	-388(fp),-392(fp),r0
        +	bicl3	#0,r0,-388(fp)
        +	cmpl	-388(fp),-392(fp)
        +	bgequ	noname.141
        +	addl2	#65536,-400(fp)
        +noname.141:
        +	movzwl	-386(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-400(fp)
        +	bicl3	#-65536,-388(fp),r0
        +	ashl	#16,r0,-392(fp)
        +	addl3	-392(fp),-396(fp),r0
        +	bicl3	#0,r0,-396(fp)
        +	cmpl	-396(fp),-392(fp)
        +	bgequ	noname.142
        +	incl	-400(fp)
        +noname.142:
        +	movl	-396(fp),r1
        +	movl	-400(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.143
        +	incl	r2
        +noname.143:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.144
        +	incl	r10
        +noname.144:
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,16(r7),r3
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-412(fp)
        +	bicl3	#-65536,r2,-416(fp)
        +	mull3	r0,-412(fp),-404(fp)
        +	mull2	r3,-412(fp)
        +	mull3	r3,-416(fp),-408(fp)
        +	mull2	r0,-416(fp)
        +	addl3	-404(fp),-408(fp),r0
        +	bicl3	#0,r0,-404(fp)
        +	cmpl	-404(fp),-408(fp)
        +	bgequ	noname.145
        +	addl2	#65536,-416(fp)
        +noname.145:
        +	movzwl	-402(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-416(fp)
        +	bicl3	#-65536,-404(fp),r0
        +	ashl	#16,r0,-408(fp)
        +	addl3	-408(fp),-412(fp),r0
        +	bicl3	#0,r0,-412(fp)
        +	cmpl	-412(fp),-408(fp)
        +	bgequ	noname.146
        +	incl	-416(fp)
        +noname.146:
        +	movl	-412(fp),r1
        +	movl	-416(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.147
        +	incl	r2
        +noname.147:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.148
        +	incl	r10
        +noname.148:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,20(r7),r3
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-428(fp)
        +	bicl3	#-65536,r2,-432(fp)
        +	mull3	r0,-428(fp),-420(fp)
        +	mull2	r3,-428(fp)
        +	mull3	r3,-432(fp),-424(fp)
        +	mull2	r0,-432(fp)
        +	addl3	-420(fp),-424(fp),r0
        +	bicl3	#0,r0,-420(fp)
        +	cmpl	-420(fp),-424(fp)
        +	bgequ	noname.149
        +	addl2	#65536,-432(fp)
        +noname.149:
        +	movzwl	-418(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-432(fp)
        +	bicl3	#-65536,-420(fp),r0
        +	ashl	#16,r0,-424(fp)
        +	addl3	-424(fp),-428(fp),r0
        +	bicl3	#0,r0,-428(fp)
        +	cmpl	-428(fp),-424(fp)
        +	bgequ	noname.150
        +	incl	-432(fp)
        +noname.150:
        +	movl	-428(fp),r1
        +	movl	-432(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.151
        +	incl	r2
        +noname.151:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.152
        +	incl	r10
        +noname.152:
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,24(r7),r3
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-444(fp)
        +	bicl3	#-65536,r2,-448(fp)
        +	mull3	r0,-444(fp),-436(fp)
        +	mull2	r3,-444(fp)
        +	mull3	r3,-448(fp),-440(fp)
        +	mull2	r0,-448(fp)
        +	addl3	-436(fp),-440(fp),r0
        +	bicl3	#0,r0,-436(fp)
        +	cmpl	-436(fp),-440(fp)
        +	bgequ	noname.153
        +	addl2	#65536,-448(fp)
        +noname.153:
        +	movzwl	-434(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-448(fp)
        +	bicl3	#-65536,-436(fp),r0
        +	ashl	#16,r0,-440(fp)
        +	addl3	-440(fp),-444(fp),r0
        +	bicl3	#0,r0,-444(fp)
        +	cmpl	-444(fp),-440(fp)
        +	bgequ	noname.154
        +	incl	-448(fp)
        +noname.154:
        +	movl	-444(fp),r1
        +	movl	-448(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.155
        +	incl	r2
        +noname.155:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.156
        +	incl	r10
        +noname.156:
        +
        +	movl	r9,24(r11)
        +
        +	clrl	r9
        +
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,28(r7),r3
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,(r6),-460(fp)
        +	bicl3	#-65536,r2,-464(fp)
        +	mull3	r0,-460(fp),-452(fp)
        +	mull2	r3,-460(fp)
        +	mull3	r3,-464(fp),-456(fp)
        +	mull2	r0,-464(fp)
        +	addl3	-452(fp),-456(fp),r0
        +	bicl3	#0,r0,-452(fp)
        +	cmpl	-452(fp),-456(fp)
        +	bgequ	noname.157
        +	addl2	#65536,-464(fp)
        +noname.157:
        +	movzwl	-450(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-464(fp)
        +	bicl3	#-65536,-452(fp),r0
        +	ashl	#16,r0,-456(fp)
        +	addl3	-456(fp),-460(fp),r0
        +	bicl3	#0,r0,-460(fp)
        +	cmpl	-460(fp),-456(fp)
        +	bgequ	noname.158
        +	incl	-464(fp)
        +noname.158:
        +	movl	-460(fp),r1
        +	movl	-464(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.159
        +	incl	r2
        +noname.159:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.160
        +	incl	r9
        +noname.160:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,24(r7),r3
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-476(fp)
        +	bicl3	#-65536,r2,-480(fp)
        +	mull3	r0,-476(fp),-468(fp)
        +	mull2	r3,-476(fp)
        +	mull3	r3,-480(fp),-472(fp)
        +	mull2	r0,-480(fp)
        +	addl3	-468(fp),-472(fp),r0
        +	bicl3	#0,r0,-468(fp)
        +	cmpl	-468(fp),-472(fp)
        +	bgequ	noname.161
        +	addl2	#65536,-480(fp)
        +noname.161:
        +	movzwl	-466(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-480(fp)
        +	bicl3	#-65536,-468(fp),r0
        +	ashl	#16,r0,-472(fp)
        +	addl3	-472(fp),-476(fp),r0
        +	bicl3	#0,r0,-476(fp)
        +	cmpl	-476(fp),-472(fp)
        +	bgequ	noname.162
        +	incl	-480(fp)
        +noname.162:
        +	movl	-476(fp),r1
        +	movl	-480(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.163
        +	incl	r2
        +noname.163:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.164
        +	incl	r9
        +noname.164:
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,20(r7),r3
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-492(fp)
        +	bicl3	#-65536,r2,-496(fp)
        +	mull3	r0,-492(fp),-484(fp)
        +	mull2	r3,-492(fp)
        +	mull3	r3,-496(fp),-488(fp)
        +	mull2	r0,-496(fp)
        +	addl3	-484(fp),-488(fp),r0
        +	bicl3	#0,r0,-484(fp)
        +	cmpl	-484(fp),-488(fp)
        +	bgequ	noname.165
        +	addl2	#65536,-496(fp)
        +noname.165:
        +	movzwl	-482(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-496(fp)
        +	bicl3	#-65536,-484(fp),r0
        +	ashl	#16,r0,-488(fp)
        +	addl3	-488(fp),-492(fp),r0
        +	bicl3	#0,r0,-492(fp)
        +	cmpl	-492(fp),-488(fp)
        +	bgequ	noname.166
        +	incl	-496(fp)
        +noname.166:
        +	movl	-492(fp),r1
        +	movl	-496(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.167
        +	incl	r2
        +noname.167:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.168
        +	incl	r9
        +noname.168:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,16(r7),r3
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-508(fp)
        +	bicl3	#-65536,r2,-512(fp)
        +	mull3	r0,-508(fp),-500(fp)
        +	mull2	r3,-508(fp)
        +	mull3	r3,-512(fp),-504(fp)
        +	mull2	r0,-512(fp)
        +	addl3	-500(fp),-504(fp),r0
        +	bicl3	#0,r0,-500(fp)
        +	cmpl	-500(fp),-504(fp)
        +	bgequ	noname.169
        +	addl2	#65536,-512(fp)
        +noname.169:
        +	movzwl	-498(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-512(fp)
        +	bicl3	#-65536,-500(fp),r0
        +	ashl	#16,r0,-504(fp)
        +	addl3	-504(fp),-508(fp),r0
        +	bicl3	#0,r0,-508(fp)
        +	cmpl	-508(fp),-504(fp)
        +	bgequ	noname.170
        +	incl	-512(fp)
        +noname.170:
        +	movl	-508(fp),r1
        +	movl	-512(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.171
        +	incl	r2
        +noname.171:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.172
        +	incl	r9
        +noname.172:
        +
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r6),-524(fp)
        +	bicl3	#-65536,r2,-528(fp)
        +	mull3	r0,-524(fp),-516(fp)
        +	mull2	r3,-524(fp)
        +	mull3	r3,-528(fp),-520(fp)
        +	mull2	r0,-528(fp)
        +	addl3	-516(fp),-520(fp),r0
        +	bicl3	#0,r0,-516(fp)
        +	cmpl	-516(fp),-520(fp)
        +	bgequ	noname.173
        +	addl2	#65536,-528(fp)
        +noname.173:
        +	movzwl	-514(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-528(fp)
        +	bicl3	#-65536,-516(fp),r0
        +	ashl	#16,r0,-520(fp)
        +	addl3	-520(fp),-524(fp),r0
        +	bicl3	#0,r0,-524(fp)
        +	cmpl	-524(fp),-520(fp)
        +	bgequ	noname.174
        +	incl	-528(fp)
        +noname.174:
        +	movl	-524(fp),r1
        +	movl	-528(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.175
        +	incl	r2
        +noname.175:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.176
        +	incl	r9
        +noname.176:
        +
        +	movzwl	22(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,20(r6),-540(fp)
        +	bicl3	#-65536,r2,-544(fp)
        +	mull3	r0,-540(fp),-532(fp)
        +	mull2	r3,-540(fp)
        +	mull3	r3,-544(fp),-536(fp)
        +	mull2	r0,-544(fp)
        +	addl3	-532(fp),-536(fp),r0
        +	bicl3	#0,r0,-532(fp)
        +	cmpl	-532(fp),-536(fp)
        +	bgequ	noname.177
        +	addl2	#65536,-544(fp)
        +noname.177:
        +	movzwl	-530(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-544(fp)
        +	bicl3	#-65536,-532(fp),r0
        +	ashl	#16,r0,-536(fp)
        +	addl3	-536(fp),-540(fp),r0
        +	bicl3	#0,r0,-540(fp)
        +	cmpl	-540(fp),-536(fp)
        +	bgequ	noname.178
        +	incl	-544(fp)
        +noname.178:
        +	movl	-540(fp),r1
        +	movl	-544(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.179
        +	incl	r2
        +noname.179:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.180
        +	incl	r9
        +noname.180:
        +
        +	movzwl	26(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,24(r6),-556(fp)
        +	bicl3	#-65536,r2,-560(fp)
        +	mull3	r0,-556(fp),-548(fp)
        +	mull2	r3,-556(fp)
        +	mull3	r3,-560(fp),-552(fp)
        +	mull2	r0,-560(fp)
        +	addl3	-548(fp),-552(fp),r0
        +	bicl3	#0,r0,-548(fp)
        +	cmpl	-548(fp),-552(fp)
        +	bgequ	noname.181
        +	addl2	#65536,-560(fp)
        +noname.181:
        +	movzwl	-546(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-560(fp)
        +	bicl3	#-65536,-548(fp),r0
        +	ashl	#16,r0,-552(fp)
        +	addl3	-552(fp),-556(fp),r0
        +	bicl3	#0,r0,-556(fp)
        +	cmpl	-556(fp),-552(fp)
        +	bgequ	noname.182
        +	incl	-560(fp)
        +noname.182:
        +	movl	-556(fp),r1
        +	movl	-560(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.183
        +	incl	r2
        +noname.183:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.184
        +	incl	r9
        +noname.184:
        +
        +	movzwl	30(r6),r2
        +	bicl3	#-65536,(r7),r3
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,28(r6),-572(fp)
        +	bicl3	#-65536,r2,-576(fp)
        +	mull3	r0,-572(fp),-564(fp)
        +	mull2	r3,-572(fp)
        +	mull3	r3,-576(fp),-568(fp)
        +	mull2	r0,-576(fp)
        +	addl3	-564(fp),-568(fp),r0
        +	bicl3	#0,r0,-564(fp)
        +	cmpl	-564(fp),-568(fp)
        +	bgequ	noname.185
        +	addl2	#65536,-576(fp)
        +noname.185:
        +	movzwl	-562(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-576(fp)
        +	bicl3	#-65536,-564(fp),r0
        +	ashl	#16,r0,-568(fp)
        +	addl3	-568(fp),-572(fp),r0
        +	bicl3	#0,r0,-572(fp)
        +	cmpl	-572(fp),-568(fp)
        +	bgequ	noname.186
        +	incl	-576(fp)
        +noname.186:
        +	movl	-572(fp),r1
        +	movl	-576(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.187
        +	incl	r2
        +noname.187:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.188
        +	incl	r9
        +noname.188:
        +
        +	movl	r8,28(r11)
        +
        +	clrl	r8
        +
        +	movzwl	30(r6),r2
        +	bicl3	#-65536,4(r7),r3
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,28(r6),-588(fp)
        +	bicl3	#-65536,r2,-592(fp)
        +	mull3	r0,-588(fp),-580(fp)
        +	mull2	r3,-588(fp)
        +	mull3	r3,-592(fp),-584(fp)
        +	mull2	r0,-592(fp)
        +	addl3	-580(fp),-584(fp),r0
        +	bicl3	#0,r0,-580(fp)
        +	cmpl	-580(fp),-584(fp)
        +	bgequ	noname.189
        +	addl2	#65536,-592(fp)
        +noname.189:
        +	movzwl	-578(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-592(fp)
        +	bicl3	#-65536,-580(fp),r0
        +	ashl	#16,r0,-584(fp)
        +	addl3	-584(fp),-588(fp),r0
        +	bicl3	#0,r0,-588(fp)
        +	cmpl	-588(fp),-584(fp)
        +	bgequ	noname.190
        +	incl	-592(fp)
        +noname.190:
        +	movl	-588(fp),r1
        +	movl	-592(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.191
        +	incl	r2
        +noname.191:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.192
        +	incl	r8
        +noname.192:
        +
        +	movzwl	26(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,24(r6),-604(fp)
        +	bicl3	#-65536,r2,-608(fp)
        +	mull3	r0,-604(fp),-596(fp)
        +	mull2	r3,-604(fp)
        +	mull3	r3,-608(fp),-600(fp)
        +	mull2	r0,-608(fp)
        +	addl3	-596(fp),-600(fp),r0
        +	bicl3	#0,r0,-596(fp)
        +	cmpl	-596(fp),-600(fp)
        +	bgequ	noname.193
        +	addl2	#65536,-608(fp)
        +noname.193:
        +	movzwl	-594(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-608(fp)
        +	bicl3	#-65536,-596(fp),r0
        +	ashl	#16,r0,-600(fp)
        +	addl3	-600(fp),-604(fp),r0
        +	bicl3	#0,r0,-604(fp)
        +	cmpl	-604(fp),-600(fp)
        +	bgequ	noname.194
        +	incl	-608(fp)
        +noname.194:
        +	movl	-604(fp),r1
        +	movl	-608(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.195
        +	incl	r2
        +noname.195:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.196
        +	incl	r8
        +noname.196:
        +
        +	movzwl	22(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,20(r6),-620(fp)
        +	bicl3	#-65536,r2,-624(fp)
        +	mull3	r0,-620(fp),-612(fp)
        +	mull2	r3,-620(fp)
        +	mull3	r3,-624(fp),-616(fp)
        +	mull2	r0,-624(fp)
        +	addl3	-612(fp),-616(fp),r0
        +	bicl3	#0,r0,-612(fp)
        +	cmpl	-612(fp),-616(fp)
        +	bgequ	noname.197
        +	addl2	#65536,-624(fp)
        +noname.197:
        +	movzwl	-610(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-624(fp)
        +	bicl3	#-65536,-612(fp),r0
        +	ashl	#16,r0,-616(fp)
        +	addl3	-616(fp),-620(fp),r0
        +	bicl3	#0,r0,-620(fp)
        +	cmpl	-620(fp),-616(fp)
        +	bgequ	noname.198
        +	incl	-624(fp)
        +noname.198:
        +	movl	-620(fp),r1
        +	movl	-624(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.199
        +	incl	r2
        +noname.199:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.200
        +	incl	r8
        +noname.200:
        +
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,16(r7),r3
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r6),-636(fp)
        +	bicl3	#-65536,r2,-640(fp)
        +	mull3	r0,-636(fp),-628(fp)
        +	mull2	r3,-636(fp)
        +	mull3	r3,-640(fp),-632(fp)
        +	mull2	r0,-640(fp)
        +	addl3	-628(fp),-632(fp),r0
        +	bicl3	#0,r0,-628(fp)
        +	cmpl	-628(fp),-632(fp)
        +	bgequ	noname.201
        +	addl2	#65536,-640(fp)
        +noname.201:
        +	movzwl	-626(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-640(fp)
        +	bicl3	#-65536,-628(fp),r0
        +	ashl	#16,r0,-632(fp)
        +	addl3	-632(fp),-636(fp),r0
        +	bicl3	#0,r0,-636(fp)
        +	cmpl	-636(fp),-632(fp)
        +	bgequ	noname.202
        +	incl	-640(fp)
        +noname.202:
        +	movl	-636(fp),r1
        +	movl	-640(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.203
        +	incl	r2
        +noname.203:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.204
        +	incl	r8
        +noname.204:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,20(r7),r3
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-652(fp)
        +	bicl3	#-65536,r2,-656(fp)
        +	mull3	r0,-652(fp),-644(fp)
        +	mull2	r3,-652(fp)
        +	mull3	r3,-656(fp),-648(fp)
        +	mull2	r0,-656(fp)
        +	addl3	-644(fp),-648(fp),r0
        +	bicl3	#0,r0,-644(fp)
        +	cmpl	-644(fp),-648(fp)
        +	bgequ	noname.205
        +	addl2	#65536,-656(fp)
        +noname.205:
        +	movzwl	-642(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-656(fp)
        +	bicl3	#-65536,-644(fp),r0
        +	ashl	#16,r0,-648(fp)
        +	addl3	-648(fp),-652(fp),r0
        +	bicl3	#0,r0,-652(fp)
        +	cmpl	-652(fp),-648(fp)
        +	bgequ	noname.206
        +	incl	-656(fp)
        +noname.206:
        +	movl	-652(fp),r1
        +	movl	-656(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.207
        +	incl	r2
        +noname.207:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.208
        +	incl	r8
        +noname.208:
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,24(r7),r3
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-668(fp)
        +	bicl3	#-65536,r2,-672(fp)
        +	mull3	r0,-668(fp),-660(fp)
        +	mull2	r3,-668(fp)
        +	mull3	r3,-672(fp),-664(fp)
        +	mull2	r0,-672(fp)
        +	addl3	-660(fp),-664(fp),r0
        +	bicl3	#0,r0,-660(fp)
        +	cmpl	-660(fp),-664(fp)
        +	bgequ	noname.209
        +	addl2	#65536,-672(fp)
        +noname.209:
        +	movzwl	-658(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-672(fp)
        +	bicl3	#-65536,-660(fp),r0
        +	ashl	#16,r0,-664(fp)
        +	addl3	-664(fp),-668(fp),r0
        +	bicl3	#0,r0,-668(fp)
        +	cmpl	-668(fp),-664(fp)
        +	bgequ	noname.210
        +	incl	-672(fp)
        +noname.210:
        +	movl	-668(fp),r1
        +	movl	-672(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.211
        +	incl	r2
        +noname.211:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.212
        +	incl	r8
        +noname.212:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,28(r7),r3
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-684(fp)
        +	bicl3	#-65536,r2,-688(fp)
        +	mull3	r0,-684(fp),-676(fp)
        +	mull2	r3,-684(fp)
        +	mull3	r3,-688(fp),-680(fp)
        +	mull2	r0,-688(fp)
        +	addl3	-676(fp),-680(fp),r0
        +	bicl3	#0,r0,-676(fp)
        +	cmpl	-676(fp),-680(fp)
        +	bgequ	noname.213
        +	addl2	#65536,-688(fp)
        +noname.213:
        +	movzwl	-674(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-688(fp)
        +	bicl3	#-65536,-676(fp),r0
        +	ashl	#16,r0,-680(fp)
        +	addl3	-680(fp),-684(fp),r0
        +	bicl3	#0,r0,-684(fp)
        +	cmpl	-684(fp),-680(fp)
        +	bgequ	noname.214
        +	incl	-688(fp)
        +noname.214:
        +	movl	-684(fp),r1
        +	movl	-688(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.215
        +	incl	r2
        +noname.215:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.216
        +	incl	r8
        +noname.216:
        +
        +	movl	r10,32(r11)
        +
        +	clrl	r10
        +
        +	movzwl	10(r6),r2
        +	bicl3	#-65536,28(r7),r3
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r6),-700(fp)
        +	bicl3	#-65536,r2,-704(fp)
        +	mull3	r0,-700(fp),-692(fp)
        +	mull2	r3,-700(fp)
        +	mull3	r3,-704(fp),-696(fp)
        +	mull2	r0,-704(fp)
        +	addl3	-692(fp),-696(fp),r0
        +	bicl3	#0,r0,-692(fp)
        +	cmpl	-692(fp),-696(fp)
        +	bgequ	noname.217
        +	addl2	#65536,-704(fp)
        +noname.217:
        +	movzwl	-690(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-704(fp)
        +	bicl3	#-65536,-692(fp),r0
        +	ashl	#16,r0,-696(fp)
        +	addl3	-696(fp),-700(fp),r0
        +	bicl3	#0,r0,-700(fp)
        +	cmpl	-700(fp),-696(fp)
        +	bgequ	noname.218
        +	incl	-704(fp)
        +noname.218:
        +	movl	-700(fp),r1
        +	movl	-704(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.219
        +	incl	r2
        +noname.219:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.220
        +	incl	r10
        +noname.220:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,24(r7),r3
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-716(fp)
        +	bicl3	#-65536,r2,-720(fp)
        +	mull3	r0,-716(fp),-708(fp)
        +	mull2	r3,-716(fp)
        +	mull3	r3,-720(fp),-712(fp)
        +	mull2	r0,-720(fp)
        +	addl3	-708(fp),-712(fp),r0
        +	bicl3	#0,r0,-708(fp)
        +	cmpl	-708(fp),-712(fp)
        +	bgequ	noname.221
        +	addl2	#65536,-720(fp)
        +noname.221:
        +	movzwl	-706(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-720(fp)
        +	bicl3	#-65536,-708(fp),r0
        +	ashl	#16,r0,-712(fp)
        +	addl3	-712(fp),-716(fp),r0
        +	bicl3	#0,r0,-716(fp)
        +	cmpl	-716(fp),-712(fp)
        +	bgequ	noname.222
        +	incl	-720(fp)
        +noname.222:
        +	movl	-716(fp),r1
        +	movl	-720(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.223
        +	incl	r2
        +noname.223:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.224
        +	incl	r10
        +noname.224:
        +
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,20(r7),r3
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r6),-732(fp)
        +	bicl3	#-65536,r2,-736(fp)
        +	mull3	r0,-732(fp),-724(fp)
        +	mull2	r3,-732(fp)
        +	mull3	r3,-736(fp),-728(fp)
        +	mull2	r0,-736(fp)
        +	addl3	-724(fp),-728(fp),r0
        +	bicl3	#0,r0,-724(fp)
        +	cmpl	-724(fp),-728(fp)
        +	bgequ	noname.225
        +	addl2	#65536,-736(fp)
        +noname.225:
        +	movzwl	-722(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-736(fp)
        +	bicl3	#-65536,-724(fp),r0
        +	ashl	#16,r0,-728(fp)
        +	addl3	-728(fp),-732(fp),r0
        +	bicl3	#0,r0,-732(fp)
        +	cmpl	-732(fp),-728(fp)
        +	bgequ	noname.226
        +	incl	-736(fp)
        +noname.226:
        +	movl	-732(fp),r1
        +	movl	-736(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.227
        +	incl	r2
        +noname.227:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.228
        +	incl	r10
        +noname.228:
        +
        +	movzwl	22(r6),r2
        +	bicl3	#-65536,16(r7),r3
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,20(r6),-748(fp)
        +	bicl3	#-65536,r2,-752(fp)
        +	mull3	r0,-748(fp),-740(fp)
        +	mull2	r3,-748(fp)
        +	mull3	r3,-752(fp),-744(fp)
        +	mull2	r0,-752(fp)
        +	addl3	-740(fp),-744(fp),r0
        +	bicl3	#0,r0,-740(fp)
        +	cmpl	-740(fp),-744(fp)
        +	bgequ	noname.229
        +	addl2	#65536,-752(fp)
        +noname.229:
        +	movzwl	-738(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-752(fp)
        +	bicl3	#-65536,-740(fp),r0
        +	ashl	#16,r0,-744(fp)
        +	addl3	-744(fp),-748(fp),r0
        +	bicl3	#0,r0,-748(fp)
        +	cmpl	-748(fp),-744(fp)
        +	bgequ	noname.230
        +	incl	-752(fp)
        +noname.230:
        +	movl	-748(fp),r1
        +	movl	-752(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.231
        +	incl	r2
        +noname.231:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.232
        +	incl	r10
        +noname.232:
        +
        +	movzwl	26(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,24(r6),-764(fp)
        +	bicl3	#-65536,r2,-768(fp)
        +	mull3	r0,-764(fp),-756(fp)
        +	mull2	r3,-764(fp)
        +	mull3	r3,-768(fp),-760(fp)
        +	mull2	r0,-768(fp)
        +	addl3	-756(fp),-760(fp),r0
        +	bicl3	#0,r0,-756(fp)
        +	cmpl	-756(fp),-760(fp)
        +	bgequ	noname.233
        +	addl2	#65536,-768(fp)
        +noname.233:
        +	movzwl	-754(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-768(fp)
        +	bicl3	#-65536,-756(fp),r0
        +	ashl	#16,r0,-760(fp)
        +	addl3	-760(fp),-764(fp),r0
        +	bicl3	#0,r0,-764(fp)
        +	cmpl	-764(fp),-760(fp)
        +	bgequ	noname.234
        +	incl	-768(fp)
        +noname.234:
        +	movl	-764(fp),r1
        +	movl	-768(fp),r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.235
        +	incl	r2
        +noname.235:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.236
        +	incl	r10
        +noname.236:
        +
        +	bicl3	#-65536,28(r6),r3
        +	movzwl	30(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,8(r7),r2
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-772(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-776(fp)
        +	mull2	r0,r4
        +	addl3	-772(fp),-776(fp),r0
        +	bicl3	#0,r0,-772(fp)
        +	cmpl	-772(fp),-776(fp)
        +	bgequ	noname.237
        +	addl2	#65536,r4
        +noname.237:
        +	movzwl	-770(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-772(fp),r0
        +	ashl	#16,r0,-776(fp)
        +	addl2	-776(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-776(fp)
        +	bgequ	noname.238
        +	incl	r4
        +noname.238:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.239
        +	incl	r2
        +noname.239:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.240
        +	incl	r10
        +noname.240:
        +
        +	movl	r9,36(r11)
        +
        +	clrl	r9
        +
        +	bicl3	#-65536,28(r6),r3
        +	movzwl	30(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r7),r2
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-780(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-784(fp)
        +	mull2	r0,r4
        +	addl3	-780(fp),-784(fp),r0
        +	bicl3	#0,r0,-780(fp)
        +	cmpl	-780(fp),-784(fp)
        +	bgequ	noname.241
        +	addl2	#65536,r4
        +noname.241:
        +	movzwl	-778(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-780(fp),r0
        +	ashl	#16,r0,-784(fp)
        +	addl2	-784(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-784(fp)
        +	bgequ	noname.242
        +	incl	r4
        +noname.242:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.243
        +	incl	r2
        +noname.243:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.244
        +	incl	r9
        +noname.244:
        +
        +	bicl3	#-65536,24(r6),r3
        +	movzwl	26(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r7),r2
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-788(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-792(fp)
        +	mull2	r0,r4
        +	addl3	-788(fp),-792(fp),r0
        +	bicl3	#0,r0,-788(fp)
        +	cmpl	-788(fp),-792(fp)
        +	bgequ	noname.245
        +	addl2	#65536,r4
        +noname.245:
        +	movzwl	-786(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-788(fp),r0
        +	ashl	#16,r0,-792(fp)
        +	addl2	-792(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-792(fp)
        +	bgequ	noname.246
        +	incl	r4
        +noname.246:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.247
        +	incl	r2
        +noname.247:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.248
        +	incl	r9
        +noname.248:
        +
        +	bicl3	#-65536,20(r6),r3
        +	movzwl	22(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r7),r2
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-796(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-800(fp)
        +	mull2	r0,r4
        +	addl3	-796(fp),-800(fp),r0
        +	bicl3	#0,r0,-796(fp)
        +	cmpl	-796(fp),-800(fp)
        +	bgequ	noname.249
        +	addl2	#65536,r4
        +noname.249:
        +	movzwl	-794(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-796(fp),r0
        +	ashl	#16,r0,-800(fp)
        +	addl2	-800(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-800(fp)
        +	bgequ	noname.250
        +	incl	r4
        +noname.250:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.251
        +	incl	r2
        +noname.251:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.252
        +	incl	r9
        +noname.252:
        +
        +	bicl3	#-65536,16(r6),r3
        +	movzwl	18(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,24(r7),r2
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-804(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-808(fp)
        +	mull2	r0,r4
        +	addl3	-804(fp),-808(fp),r0
        +	bicl3	#0,r0,-804(fp)
        +	cmpl	-804(fp),-808(fp)
        +	bgequ	noname.253
        +	addl2	#65536,r4
        +noname.253:
        +	movzwl	-802(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-804(fp),r0
        +	ashl	#16,r0,-808(fp)
        +	addl2	-808(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-808(fp)
        +	bgequ	noname.254
        +	incl	r4
        +noname.254:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.255
        +	incl	r2
        +noname.255:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.256
        +	incl	r9
        +noname.256:
        +
        +	bicl3	#-65536,12(r6),r3
        +	movzwl	14(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,28(r7),r2
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-812(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-816(fp)
        +	mull2	r0,r4
        +	addl3	-812(fp),-816(fp),r0
        +	bicl3	#0,r0,-812(fp)
        +	cmpl	-812(fp),-816(fp)
        +	bgequ	noname.257
        +	addl2	#65536,r4
        +noname.257:
        +	movzwl	-810(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-812(fp),r0
        +	ashl	#16,r0,-816(fp)
        +	addl2	-816(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-816(fp)
        +	bgequ	noname.258
        +	incl	r4
        +noname.258:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.259
        +	incl	r2
        +noname.259:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.260
        +	incl	r9
        +noname.260:
        +
        +	movl	r8,40(r11)
        +
        +	clrl	r8
        +
        +	bicl3	#-65536,16(r6),r3
        +	movzwl	18(r6),r2
        +	bicl3	#-65536,28(r7),r1
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r4
        +	bicl3	#-65536,r2,-828(fp)
        +	mull3	r0,r4,-820(fp)
        +	mull2	r1,r4
        +	mull3	r1,-828(fp),-824(fp)
        +	mull2	r0,-828(fp)
        +	addl3	-820(fp),-824(fp),r0
        +	bicl3	#0,r0,-820(fp)
        +	cmpl	-820(fp),-824(fp)
        +	bgequ	noname.261
        +	addl2	#65536,-828(fp)
        +noname.261:
        +	movzwl	-818(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-828(fp)
        +	bicl3	#-65536,-820(fp),r0
        +	ashl	#16,r0,-824(fp)
        +	addl2	-824(fp),r4
        +	bicl2	#0,r4
        +	cmpl	r4,-824(fp)
        +	bgequ	noname.262
        +	incl	-828(fp)
        +noname.262:
        +	movl	r4,r1
        +	movl	-828(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.263
        +	incl	r2
        +noname.263:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.264
        +	incl	r8
        +noname.264:
        +
        +	movzwl	22(r6),r2
        +	bicl3	#-65536,24(r7),r3
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,20(r6),-840(fp)
        +	bicl3	#-65536,r2,-844(fp)
        +	mull3	r0,-840(fp),-832(fp)
        +	mull2	r3,-840(fp)
        +	mull3	r3,-844(fp),-836(fp)
        +	mull2	r0,-844(fp)
        +	addl3	-832(fp),-836(fp),r0
        +	bicl3	#0,r0,-832(fp)
        +	cmpl	-832(fp),-836(fp)
        +	bgequ	noname.265
        +	addl2	#65536,-844(fp)
        +noname.265:
        +	movzwl	-830(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-844(fp)
        +	bicl3	#-65536,-832(fp),r0
        +	ashl	#16,r0,-836(fp)
        +	addl3	-836(fp),-840(fp),r0
        +	bicl3	#0,r0,-840(fp)
        +	cmpl	-840(fp),-836(fp)
        +	bgequ	noname.266
        +	incl	-844(fp)
        +noname.266:
        +	movl	-840(fp),r1
        +	movl	-844(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.267
        +	incl	r2
        +noname.267:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.268
        +	incl	r8
        +noname.268:
        +
        +	bicl3	#-65536,24(r6),r3
        +	movzwl	26(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r7),r2
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-848(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-852(fp)
        +	mull2	r0,r4
        +	addl3	-848(fp),-852(fp),r0
        +	bicl3	#0,r0,-848(fp)
        +	cmpl	-848(fp),-852(fp)
        +	bgequ	noname.269
        +	addl2	#65536,r4
        +noname.269:
        +	movzwl	-846(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-848(fp),r0
        +	ashl	#16,r0,-852(fp)
        +	addl2	-852(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-852(fp)
        +	bgequ	noname.270
        +	incl	r4
        +noname.270:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.271
        +	incl	r2
        +noname.271:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.272
        +	incl	r8
        +noname.272:
        +
        +	bicl3	#-65536,28(r6),r3
        +	movzwl	30(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r7),r2
        +	movzwl	18(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-856(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-860(fp)
        +	mull2	r0,r4
        +	addl3	-856(fp),-860(fp),r0
        +	bicl3	#0,r0,-856(fp)
        +	cmpl	-856(fp),-860(fp)
        +	bgequ	noname.273
        +	addl2	#65536,r4
        +noname.273:
        +	movzwl	-854(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-856(fp),r0
        +	ashl	#16,r0,-860(fp)
        +	addl2	-860(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-860(fp)
        +	bgequ	noname.274
        +	incl	r4
        +noname.274:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.275
        +	incl	r2
        +noname.275:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.276
        +	incl	r8
        +noname.276:
        +
        +	movl	r10,44(r11)
        +
        +	clrl	r10
        +
        +	bicl3	#-65536,28(r6),r3
        +	movzwl	30(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r7),r2
        +	movzwl	22(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-864(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-868(fp)
        +	mull2	r0,r4
        +	addl3	-864(fp),-868(fp),r0
        +	bicl3	#0,r0,-864(fp)
        +	cmpl	-864(fp),-868(fp)
        +	bgequ	noname.277
        +	addl2	#65536,r4
        +noname.277:
        +	movzwl	-862(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-864(fp),r0
        +	ashl	#16,r0,-868(fp)
        +	addl2	-868(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-868(fp)
        +	bgequ	noname.278
        +	incl	r4
        +noname.278:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.279
        +	incl	r2
        +noname.279:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.280
        +	incl	r10
        +noname.280:
        +
        +	bicl3	#-65536,24(r6),r3
        +	movzwl	26(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,24(r7),r2
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-872(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-876(fp)
        +	mull2	r0,r4
        +	addl3	-872(fp),-876(fp),r0
        +	bicl3	#0,r0,-872(fp)
        +	cmpl	-872(fp),-876(fp)
        +	bgequ	noname.281
        +	addl2	#65536,r4
        +noname.281:
        +	movzwl	-870(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-872(fp),r0
        +	ashl	#16,r0,-876(fp)
        +	addl2	-876(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-876(fp)
        +	bgequ	noname.282
        +	incl	r4
        +noname.282:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.283
        +	incl	r2
        +noname.283:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.284
        +	incl	r10
        +noname.284:
        +
        +	bicl3	#-65536,20(r6),r3
        +	movzwl	22(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,28(r7),r2
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-880(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-884(fp)
        +	mull2	r0,r4
        +	addl3	-880(fp),-884(fp),r0
        +	bicl3	#0,r0,-880(fp)
        +	cmpl	-880(fp),-884(fp)
        +	bgequ	noname.285
        +	addl2	#65536,r4
        +noname.285:
        +	movzwl	-878(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-880(fp),r0
        +	ashl	#16,r0,-884(fp)
        +	addl2	-884(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-884(fp)
        +	bgequ	noname.286
        +	incl	r4
        +noname.286:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.287
        +	incl	r2
        +noname.287:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.288
        +	incl	r10
        +noname.288:
        +
        +	movl	r9,48(r11)
        +
        +	clrl	r9
        +
        +	bicl3	#-65536,24(r6),r3
        +	movzwl	26(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,28(r7),r2
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-888(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-892(fp)
        +	mull2	r0,r4
        +	addl3	-888(fp),-892(fp),r0
        +	bicl3	#0,r0,-888(fp)
        +	cmpl	-888(fp),-892(fp)
        +	bgequ	noname.289
        +	addl2	#65536,r4
        +noname.289:
        +	movzwl	-886(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-888(fp),r0
        +	ashl	#16,r0,-892(fp)
        +	addl2	-892(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-892(fp)
        +	bgequ	noname.290
        +	incl	r4
        +noname.290:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.291
        +	incl	r2
        +noname.291:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.292
        +	incl	r9
        +noname.292:
        +
        +	movzwl	30(r6),r2
        +	bicl3	#-65536,24(r7),r3
        +	movzwl	26(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,28(r6),-904(fp)
        +	bicl3	#-65536,r2,-908(fp)
        +	mull3	r0,-904(fp),-896(fp)
        +	mull2	r3,-904(fp)
        +	mull3	r3,-908(fp),-900(fp)
        +	mull2	r0,-908(fp)
        +	addl3	-896(fp),-900(fp),r0
        +	bicl3	#0,r0,-896(fp)
        +	cmpl	-896(fp),-900(fp)
        +	bgequ	noname.293
        +	addl2	#65536,-908(fp)
        +noname.293:
        +	movzwl	-894(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-908(fp)
        +	bicl3	#-65536,-896(fp),r0
        +	ashl	#16,r0,-900(fp)
        +	addl3	-900(fp),-904(fp),r0
        +	bicl3	#0,r0,-904(fp)
        +	cmpl	-904(fp),-900(fp)
        +	bgequ	noname.294
        +	incl	-908(fp)
        +noname.294:
        +	movl	-904(fp),r1
        +	movl	-908(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.295
        +	incl	r2
        +noname.295:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.296
        +	incl	r9
        +noname.296:
        +
        +	movl	r8,52(r11)
        +
        +	clrl	r8
        +
        +	movzwl	30(r6),r2
        +	bicl3	#-65536,28(r7),r3
        +	movzwl	30(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,28(r6),-920(fp)
        +	bicl3	#-65536,r2,-924(fp)
        +	mull3	r0,-920(fp),-912(fp)
        +	mull2	r3,-920(fp)
        +	mull3	r3,-924(fp),-916(fp)
        +	mull2	r0,-924(fp)
        +	addl3	-912(fp),-916(fp),r0
        +	bicl3	#0,r0,-912(fp)
        +	cmpl	-912(fp),-916(fp)
        +	bgequ	noname.297
        +	addl2	#65536,-924(fp)
        +noname.297:
        +	movzwl	-910(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-924(fp)
        +	bicl3	#-65536,-912(fp),r0
        +	ashl	#16,r0,-916(fp)
        +	addl3	-916(fp),-920(fp),r0
        +	bicl3	#0,r0,-920(fp)
        +	cmpl	-920(fp),-916(fp)
        +	bgequ	noname.298
        +	incl	-924(fp)
        +noname.298:
        +	movl	-920(fp),r1
        +	movl	-924(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.299
        +	incl	r2
        +noname.299:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.300
        +	incl	r8
        +noname.300:
        +
        +	movl	r10,56(r11)
        +
        +	movl	r9,60(r11)
        +
        +	ret	
        +
        +
        +
        +;r=4 ;(AP)
        +;a=8 ;(AP)
        +;b=12 ;(AP)
        +;n=16 ;(AP)	n	by value (input)
        +
        +	.psect	code,nowrt
        +
        +.entry	BN_MUL_COMBA4,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
        +	movab	-156(sp),sp
        +
        +	clrq	r9
        +
        +	clrl	r8
        +
        +	movl	8(ap),r6
        +	bicl3	#-65536,(r6),r3
        +	movzwl	2(r6),r2
        +	bicl2	#-65536,r2
        +	movl	12(ap),r7
        +	bicl3	#-65536,(r7),r1
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r2,r4
        +	mull3	r0,r5,-4(fp)
        +	mull2	r1,r5
        +	mull3	r1,r4,-8(fp)
        +	mull2	r0,r4
        +	addl3	-4(fp),-8(fp),r0
        +	bicl3	#0,r0,-4(fp)
        +	cmpl	-4(fp),-8(fp)
        +	bgequ	noname.303
        +	addl2	#65536,r4
        +noname.303:
        +	movzwl	-2(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-4(fp),r0
        +	ashl	#16,r0,-8(fp)
        +	addl2	-8(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-8(fp)
        +	bgequ	noname.304
        +	incl	r4
        +noname.304:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.305
        +	incl	r2
        +noname.305:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.306
        +	incl	r8
        +noname.306:
        +
        +	movl	4(ap),r11
        +	movl	r10,(r11)
        +
        +	clrl	r10
        +
        +	bicl3	#-65536,(r6),r3
        +	movzwl	2(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r7),r2
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-12(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-16(fp)
        +	mull2	r0,r4
        +	addl3	-12(fp),-16(fp),r0
        +	bicl3	#0,r0,-12(fp)
        +	cmpl	-12(fp),-16(fp)
        +	bgequ	noname.307
        +	addl2	#65536,r4
        +noname.307:
        +	movzwl	-10(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-12(fp),r0
        +	ashl	#16,r0,-16(fp)
        +	addl2	-16(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-16(fp)
        +	bgequ	noname.308
        +	incl	r4
        +noname.308:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.309
        +	incl	r2
        +noname.309:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.310
        +	incl	r10
        +noname.310:
        +
        +	bicl3	#-65536,4(r6),r3
        +	movzwl	6(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,(r7),r2
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-20(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-24(fp)
        +	mull2	r0,r4
        +	addl3	-20(fp),-24(fp),r0
        +	bicl3	#0,r0,-20(fp)
        +	cmpl	-20(fp),-24(fp)
        +	bgequ	noname.311
        +	addl2	#65536,r4
        +noname.311:
        +	movzwl	-18(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-20(fp),r0
        +	ashl	#16,r0,-24(fp)
        +	addl2	-24(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-24(fp)
        +	bgequ	noname.312
        +	incl	r4
        +noname.312:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.313
        +	incl	r2
        +noname.313:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.314
        +	incl	r10
        +noname.314:
        +
        +	movl	r9,4(r11)
        +
        +	clrl	r9
        +
        +	bicl3	#-65536,8(r6),r3
        +	movzwl	10(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,(r7),r2
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-28(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-32(fp)
        +	mull2	r0,r4
        +	addl3	-28(fp),-32(fp),r0
        +	bicl3	#0,r0,-28(fp)
        +	cmpl	-28(fp),-32(fp)
        +	bgequ	noname.315
        +	addl2	#65536,r4
        +noname.315:
        +	movzwl	-26(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-28(fp),r0
        +	ashl	#16,r0,-32(fp)
        +	addl2	-32(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-32(fp)
        +	bgequ	noname.316
        +	incl	r4
        +noname.316:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.317
        +	incl	r2
        +noname.317:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.318
        +	incl	r9
        +noname.318:
        +
        +	bicl3	#-65536,4(r6),r3
        +	movzwl	6(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r7),r2
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-36(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-40(fp)
        +	mull2	r0,r4
        +	addl3	-36(fp),-40(fp),r0
        +	bicl3	#0,r0,-36(fp)
        +	cmpl	-36(fp),-40(fp)
        +	bgequ	noname.319
        +	addl2	#65536,r4
        +noname.319:
        +	movzwl	-34(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-36(fp),r0
        +	ashl	#16,r0,-40(fp)
        +	addl2	-40(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-40(fp)
        +	bgequ	noname.320
        +	incl	r4
        +noname.320:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.321
        +	incl	r2
        +noname.321:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.322
        +	incl	r9
        +noname.322:
        +
        +	bicl3	#-65536,(r6),r3
        +	movzwl	2(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,8(r7),r2
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-44(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-48(fp)
        +	mull2	r0,r4
        +	addl3	-44(fp),-48(fp),r0
        +	bicl3	#0,r0,-44(fp)
        +	cmpl	-44(fp),-48(fp)
        +	bgequ	noname.323
        +	addl2	#65536,r4
        +noname.323:
        +	movzwl	-42(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-44(fp),r0
        +	ashl	#16,r0,-48(fp)
        +	addl2	-48(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-48(fp)
        +	bgequ	noname.324
        +	incl	r4
        +noname.324:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.325
        +	incl	r2
        +noname.325:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.326
        +	incl	r9
        +noname.326:
        +
        +	movl	r8,8(r11)
        +
        +	clrl	r8
        +
        +	bicl3	#-65536,(r6),r3
        +	movzwl	2(r6),r2
        +	bicl3	#-65536,12(r7),r1
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r4
        +	bicl3	#-65536,r2,-60(fp)
        +	mull3	r0,r4,-52(fp)
        +	mull2	r1,r4
        +	mull3	r1,-60(fp),-56(fp)
        +	mull2	r0,-60(fp)
        +	addl3	-52(fp),-56(fp),r0
        +	bicl3	#0,r0,-52(fp)
        +	cmpl	-52(fp),-56(fp)
        +	bgequ	noname.327
        +	addl2	#65536,-60(fp)
        +noname.327:
        +	movzwl	-50(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-60(fp)
        +	bicl3	#-65536,-52(fp),r0
        +	ashl	#16,r0,-56(fp)
        +	addl2	-56(fp),r4
        +	bicl2	#0,r4
        +	cmpl	r4,-56(fp)
        +	bgequ	noname.328
        +	incl	-60(fp)
        +noname.328:
        +	movl	r4,r1
        +	movl	-60(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.329
        +	incl	r2
        +noname.329:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.330
        +	incl	r8
        +noname.330:
        +
        +	movzwl	6(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r6),-72(fp)
        +	bicl3	#-65536,r2,-76(fp)
        +	mull3	r0,-72(fp),-64(fp)
        +	mull2	r3,-72(fp)
        +	mull3	r3,-76(fp),-68(fp)
        +	mull2	r0,-76(fp)
        +	addl3	-64(fp),-68(fp),r0
        +	bicl3	#0,r0,-64(fp)
        +	cmpl	-64(fp),-68(fp)
        +	bgequ	noname.331
        +	addl2	#65536,-76(fp)
        +noname.331:
        +	movzwl	-62(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-76(fp)
        +	bicl3	#-65536,-64(fp),r0
        +	ashl	#16,r0,-68(fp)
        +	addl3	-68(fp),-72(fp),r0
        +	bicl3	#0,r0,-72(fp)
        +	cmpl	-72(fp),-68(fp)
        +	bgequ	noname.332
        +	incl	-76(fp)
        +noname.332:
        +	movl	-72(fp),r1
        +	movl	-76(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.333
        +	incl	r2
        +noname.333:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.334
        +	incl	r8
        +noname.334:
        +
        +	bicl3	#-65536,8(r6),r3
        +	movzwl	10(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r7),r2
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-80(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-84(fp)
        +	mull2	r0,r4
        +	addl3	-80(fp),-84(fp),r0
        +	bicl3	#0,r0,-80(fp)
        +	cmpl	-80(fp),-84(fp)
        +	bgequ	noname.335
        +	addl2	#65536,r4
        +noname.335:
        +	movzwl	-78(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-80(fp),r0
        +	ashl	#16,r0,-84(fp)
        +	addl2	-84(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-84(fp)
        +	bgequ	noname.336
        +	incl	r4
        +noname.336:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.337
        +	incl	r2
        +noname.337:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.338
        +	incl	r8
        +noname.338:
        +
        +	bicl3	#-65536,12(r6),r3
        +	movzwl	14(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,(r7),r2
        +	movzwl	2(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-88(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-92(fp)
        +	mull2	r0,r4
        +	addl3	-88(fp),-92(fp),r0
        +	bicl3	#0,r0,-88(fp)
        +	cmpl	-88(fp),-92(fp)
        +	bgequ	noname.339
        +	addl2	#65536,r4
        +noname.339:
        +	movzwl	-86(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-88(fp),r0
        +	ashl	#16,r0,-92(fp)
        +	addl2	-92(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-92(fp)
        +	bgequ	noname.340
        +	incl	r4
        +noname.340:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.341
        +	incl	r2
        +noname.341:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.342
        +	incl	r8
        +noname.342:
        +
        +	movl	r10,12(r11)
        +
        +	clrl	r10
        +
        +	bicl3	#-65536,12(r6),r3
        +	movzwl	14(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r7),r2
        +	movzwl	6(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-96(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-100(fp)
        +	mull2	r0,r4
        +	addl3	-96(fp),-100(fp),r0
        +	bicl3	#0,r0,-96(fp)
        +	cmpl	-96(fp),-100(fp)
        +	bgequ	noname.343
        +	addl2	#65536,r4
        +noname.343:
        +	movzwl	-94(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-96(fp),r0
        +	ashl	#16,r0,-100(fp)
        +	addl2	-100(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-100(fp)
        +	bgequ	noname.344
        +	incl	r4
        +noname.344:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.345
        +	incl	r2
        +noname.345:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.346
        +	incl	r10
        +noname.346:
        +
        +	bicl3	#-65536,8(r6),r3
        +	movzwl	10(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,8(r7),r2
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-104(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-108(fp)
        +	mull2	r0,r4
        +	addl3	-104(fp),-108(fp),r0
        +	bicl3	#0,r0,-104(fp)
        +	cmpl	-104(fp),-108(fp)
        +	bgequ	noname.347
        +	addl2	#65536,r4
        +noname.347:
        +	movzwl	-102(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-104(fp),r0
        +	ashl	#16,r0,-108(fp)
        +	addl2	-108(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-108(fp)
        +	bgequ	noname.348
        +	incl	r4
        +noname.348:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.349
        +	incl	r2
        +noname.349:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.350
        +	incl	r10
        +noname.350:
        +
        +	bicl3	#-65536,4(r6),r3
        +	movzwl	6(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r7),r2
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-112(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-116(fp)
        +	mull2	r0,r4
        +	addl3	-112(fp),-116(fp),r0
        +	bicl3	#0,r0,-112(fp)
        +	cmpl	-112(fp),-116(fp)
        +	bgequ	noname.351
        +	addl2	#65536,r4
        +noname.351:
        +	movzwl	-110(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-112(fp),r0
        +	ashl	#16,r0,-116(fp)
        +	addl2	-116(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-116(fp)
        +	bgequ	noname.352
        +	incl	r4
        +noname.352:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.353
        +	incl	r2
        +noname.353:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.354
        +	incl	r10
        +noname.354:
        +
        +	movl	r9,16(r11)
        +
        +	clrl	r9
        +
        +	bicl3	#-65536,8(r6),r3
        +	movzwl	10(r6),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r7),r2
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-120(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-124(fp)
        +	mull2	r0,r4
        +	addl3	-120(fp),-124(fp),r0
        +	bicl3	#0,r0,-120(fp)
        +	cmpl	-120(fp),-124(fp)
        +	bgequ	noname.355
        +	addl2	#65536,r4
        +noname.355:
        +	movzwl	-118(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-120(fp),r0
        +	ashl	#16,r0,-124(fp)
        +	addl2	-124(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-124(fp)
        +	bgequ	noname.356
        +	incl	r4
        +noname.356:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.357
        +	incl	r2
        +noname.357:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.358
        +	incl	r9
        +noname.358:
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,8(r7),r3
        +	movzwl	10(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-136(fp)
        +	bicl3	#-65536,r2,-140(fp)
        +	mull3	r0,-136(fp),-128(fp)
        +	mull2	r3,-136(fp)
        +	mull3	r3,-140(fp),-132(fp)
        +	mull2	r0,-140(fp)
        +	addl3	-128(fp),-132(fp),r0
        +	bicl3	#0,r0,-128(fp)
        +	cmpl	-128(fp),-132(fp)
        +	bgequ	noname.359
        +	addl2	#65536,-140(fp)
        +noname.359:
        +	movzwl	-126(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-140(fp)
        +	bicl3	#-65536,-128(fp),r0
        +	ashl	#16,r0,-132(fp)
        +	addl3	-132(fp),-136(fp),r0
        +	bicl3	#0,r0,-136(fp)
        +	cmpl	-136(fp),-132(fp)
        +	bgequ	noname.360
        +	incl	-140(fp)
        +noname.360:
        +	movl	-136(fp),r1
        +	movl	-140(fp),r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.361
        +	incl	r2
        +noname.361:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.362
        +	incl	r9
        +noname.362:
        +
        +	movl	r8,20(r11)
        +
        +	clrl	r8
        +
        +	movzwl	14(r6),r2
        +	bicl3	#-65536,12(r7),r3
        +	movzwl	14(r7),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r6),-152(fp)
        +	bicl3	#-65536,r2,-156(fp)
        +	mull3	r0,-152(fp),-144(fp)
        +	mull2	r3,-152(fp)
        +	mull3	r3,-156(fp),-148(fp)
        +	mull2	r0,-156(fp)
        +	addl3	-144(fp),-148(fp),r0
        +	bicl3	#0,r0,-144(fp)
        +	cmpl	-144(fp),-148(fp)
        +	bgequ	noname.363
        +	addl2	#65536,-156(fp)
        +noname.363:
        +	movzwl	-142(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-156(fp)
        +	bicl3	#-65536,-144(fp),r0
        +	ashl	#16,r0,-148(fp)
        +	addl3	-148(fp),-152(fp),r0
        +	bicl3	#0,r0,-152(fp)
        +	cmpl	-152(fp),-148(fp)
        +	bgequ	noname.364
        +	incl	-156(fp)
        +noname.364:
        +	movl	-152(fp),r1
        +	movl	-156(fp),r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.365
        +	incl	r2
        +noname.365:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.366
        +	incl	r8
        +noname.366:
        +
        +	movl	r10,24(r11)
        +
        +	movl	r9,28(r11)
        +
        +	ret	
        +
        +
        +
        +;r=4 ;(AP)
        +;a=8 ;(AP)
        +;b=12 ;(AP)
        +;n=16 ;(AP)	n	by value (input)
        +
        +	.psect	code,nowrt
        +
        +.entry	BN_SQR_COMBA8,^m<r2,r3,r4,r5,r6,r7,r8,r9>
        +	movab	-444(sp),sp
        +
        +	clrq	r8
        +
        +	clrl	r7
        +
        +	movl	8(ap),r4
        +	movl	(r4),r3
        +	bicl3	#-65536,r3,-4(fp)
        +	extzv	#16,#16,r3,r0
        +	bicl3	#-65536,r0,r3
        +	movl	-4(fp),r0
        +	mull3	r0,r3,-8(fp)
        +	mull3	r0,r0,-4(fp)
        +	mull2	r3,r3
        +	bicl3	#32767,-8(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r3
        +	bicl3	#-65536,-8(fp),r0
        +	ashl	#17,r0,-8(fp)
        +	addl3	-4(fp),-8(fp),r0
        +	bicl3	#0,r0,-4(fp)
        +	cmpl	-4(fp),-8(fp)
        +	bgequ	noname.369
        +	incl	r3
        +noname.369:
        +	movl	-4(fp),r1
        +	movl	r3,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.370
        +	incl	r2
        +noname.370:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.371
        +	incl	r7
        +noname.371:
        +
        +	movl	r9,@4(ap)
        +
        +	clrl	r9
        +
        +	movzwl	6(r4),r2
        +	bicl3	#-65536,(r4),r3
        +	movzwl	2(r4),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,4(r4),-20(fp)
        +	bicl3	#-65536,r2,-24(fp)
        +	mull3	r0,-20(fp),-12(fp)
        +	mull2	r3,-20(fp)
        +	mull3	r3,-24(fp),-16(fp)
        +	mull2	r0,-24(fp)
        +	addl3	-12(fp),-16(fp),r0
        +	bicl3	#0,r0,-12(fp)
        +	cmpl	-12(fp),-16(fp)
        +	bgequ	noname.372
        +	addl2	#65536,-24(fp)
        +noname.372:
        +	movzwl	-10(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-24(fp)
        +	bicl3	#-65536,-12(fp),r0
        +	ashl	#16,r0,-16(fp)
        +	addl3	-16(fp),-20(fp),r0
        +	bicl3	#0,r0,-20(fp)
        +	cmpl	-20(fp),-16(fp)
        +	bgequ	noname.373
        +	incl	-24(fp)
        +noname.373:
        +	movl	-20(fp),r3
        +	movl	-24(fp),r2
        +	bbc	#31,r2,noname.374
        +	incl	r9
        +noname.374:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.375
        +	incl	r2
        +noname.375:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.376
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.376
        +	incl	r9
        +noname.376:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.377
        +	incl	r9
        +noname.377:
        +
        +	movl	4(ap),r0
        +	movl	r8,4(r0)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r4
        +	movl	4(r4),r3
        +	bicl3	#-65536,r3,-28(fp)
        +	extzv	#16,#16,r3,r0
        +	bicl3	#-65536,r0,r3
        +	movl	-28(fp),r0
        +	mull3	r0,r3,-32(fp)
        +	mull3	r0,r0,-28(fp)
        +	mull2	r3,r3
        +	bicl3	#32767,-32(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r3
        +	bicl3	#-65536,-32(fp),r0
        +	ashl	#17,r0,-32(fp)
        +	addl3	-28(fp),-32(fp),r0
        +	bicl3	#0,r0,-28(fp)
        +	cmpl	-28(fp),-32(fp)
        +	bgequ	noname.378
        +	incl	r3
        +noname.378:
        +	movl	-28(fp),r1
        +	movl	r3,r2
        +	addl2	r1,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r1
        +	bgequ	noname.379
        +	incl	r2
        +noname.379:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.380
        +	incl	r8
        +noname.380:
        +
        +	movzwl	10(r4),r2
        +	bicl3	#-65536,(r4),r3
        +	movzwl	2(r4),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,8(r4),-44(fp)
        +	bicl3	#-65536,r2,-48(fp)
        +	mull3	r0,-44(fp),-36(fp)
        +	mull2	r3,-44(fp)
        +	mull3	r3,-48(fp),-40(fp)
        +	mull2	r0,-48(fp)
        +	addl3	-36(fp),-40(fp),r0
        +	bicl3	#0,r0,-36(fp)
        +	cmpl	-36(fp),-40(fp)
        +	bgequ	noname.381
        +	addl2	#65536,-48(fp)
        +noname.381:
        +	movzwl	-34(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-48(fp)
        +	bicl3	#-65536,-36(fp),r0
        +	ashl	#16,r0,-40(fp)
        +	addl3	-40(fp),-44(fp),r0
        +	bicl3	#0,r0,-44(fp)
        +	cmpl	-44(fp),-40(fp)
        +	bgequ	noname.382
        +	incl	-48(fp)
        +noname.382:
        +	movl	-44(fp),r3
        +	movl	-48(fp),r2
        +	bbc	#31,r2,noname.383
        +	incl	r8
        +noname.383:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.384
        +	incl	r2
        +noname.384:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.385
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.385
        +	incl	r8
        +noname.385:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.386
        +	incl	r8
        +noname.386:
        +
        +	movl	4(ap),r0
        +	movl	r7,8(r0)
        +
        +	clrl	r7
        +
        +	movl	8(ap),r0
        +	movzwl	14(r0),r2
        +	bicl3	#-65536,(r0),r3
        +	movzwl	2(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r0),-60(fp)
        +	bicl3	#-65536,r2,-64(fp)
        +	mull3	r1,-60(fp),-52(fp)
        +	mull2	r3,-60(fp)
        +	mull3	r3,-64(fp),-56(fp)
        +	mull2	r1,-64(fp)
        +	addl3	-52(fp),-56(fp),r0
        +	bicl3	#0,r0,-52(fp)
        +	cmpl	-52(fp),-56(fp)
        +	bgequ	noname.387
        +	addl2	#65536,-64(fp)
        +noname.387:
        +	movzwl	-50(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-64(fp)
        +	bicl3	#-65536,-52(fp),r0
        +	ashl	#16,r0,-56(fp)
        +	addl3	-56(fp),-60(fp),r0
        +	bicl3	#0,r0,-60(fp)
        +	cmpl	-60(fp),-56(fp)
        +	bgequ	noname.388
        +	incl	-64(fp)
        +noname.388:
        +	movl	-60(fp),r3
        +	movl	-64(fp),r2
        +	bbc	#31,r2,noname.389
        +	incl	r7
        +noname.389:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.390
        +	incl	r2
        +noname.390:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.391
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.391
        +	incl	r7
        +noname.391:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.392
        +	incl	r7
        +noname.392:
        +
        +	movl	8(ap),r0
        +	movzwl	10(r0),r2
        +	bicl3	#-65536,4(r0),r3
        +	movzwl	6(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,8(r0),-76(fp)
        +	bicl3	#-65536,r2,-80(fp)
        +	mull3	r1,-76(fp),-68(fp)
        +	mull2	r3,-76(fp)
        +	mull3	r3,-80(fp),-72(fp)
        +	mull2	r1,-80(fp)
        +	addl3	-68(fp),-72(fp),r0
        +	bicl3	#0,r0,-68(fp)
        +	cmpl	-68(fp),-72(fp)
        +	bgequ	noname.393
        +	addl2	#65536,-80(fp)
        +noname.393:
        +	movzwl	-66(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-80(fp)
        +	bicl3	#-65536,-68(fp),r0
        +	ashl	#16,r0,-72(fp)
        +	addl3	-72(fp),-76(fp),r0
        +	bicl3	#0,r0,-76(fp)
        +	cmpl	-76(fp),-72(fp)
        +	bgequ	noname.394
        +	incl	-80(fp)
        +noname.394:
        +	movl	-76(fp),r3
        +	movl	-80(fp),r2
        +	bbc	#31,r2,noname.395
        +	incl	r7
        +noname.395:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.396
        +	incl	r2
        +noname.396:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.397
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.397
        +	incl	r7
        +noname.397:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.398
        +	incl	r7
        +noname.398:
        +
        +	movl	4(ap),r0
        +	movl	r9,12(r0)
        +
        +	clrl	r9
        +
        +	movl	8(ap),r2
        +	movl	8(r2),r4
        +	bicl3	#-65536,r4,-84(fp)
        +	extzv	#16,#16,r4,r0
        +	bicl3	#-65536,r0,r4
        +	movl	-84(fp),r0
        +	mull3	r0,r4,-88(fp)
        +	mull3	r0,r0,-84(fp)
        +	mull2	r4,r4
        +	bicl3	#32767,-88(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-88(fp),r0
        +	ashl	#17,r0,-88(fp)
        +	addl3	-84(fp),-88(fp),r0
        +	bicl3	#0,r0,-84(fp)
        +	cmpl	-84(fp),-88(fp)
        +	bgequ	noname.399
        +	incl	r4
        +noname.399:
        +	movl	-84(fp),r1
        +	movl	r4,r3
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.400
        +	incl	r3
        +noname.400:
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.401
        +	incl	r9
        +noname.401:
        +
        +	movzwl	14(r2),r3
        +	bicl3	#-65536,4(r2),r1
        +	movzwl	6(r2),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,12(r2),-100(fp)
        +	bicl3	#-65536,r3,-104(fp)
        +	mull3	r0,-100(fp),-92(fp)
        +	mull2	r1,-100(fp)
        +	mull3	r1,-104(fp),-96(fp)
        +	mull2	r0,-104(fp)
        +	addl3	-92(fp),-96(fp),r0
        +	bicl3	#0,r0,-92(fp)
        +	cmpl	-92(fp),-96(fp)
        +	bgequ	noname.402
        +	addl2	#65536,-104(fp)
        +noname.402:
        +	movzwl	-90(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-104(fp)
        +	bicl3	#-65536,-92(fp),r0
        +	ashl	#16,r0,-96(fp)
        +	addl3	-96(fp),-100(fp),r0
        +	bicl3	#0,r0,-100(fp)
        +	cmpl	-100(fp),-96(fp)
        +	bgequ	noname.403
        +	incl	-104(fp)
        +noname.403:
        +	movl	-100(fp),r3
        +	movl	-104(fp),r2
        +	bbc	#31,r2,noname.404
        +	incl	r9
        +noname.404:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.405
        +	incl	r2
        +noname.405:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.406
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.406
        +	incl	r9
        +noname.406:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.407
        +	incl	r9
        +noname.407:
        +
        +	movl	8(ap),r0
        +	movzwl	18(r0),r2
        +	bicl3	#-65536,(r0),r3
        +	movzwl	2(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r0),-116(fp)
        +	bicl3	#-65536,r2,-120(fp)
        +	mull3	r1,-116(fp),-108(fp)
        +	mull2	r3,-116(fp)
        +	mull3	r3,-120(fp),-112(fp)
        +	mull2	r1,-120(fp)
        +	addl3	-108(fp),-112(fp),r0
        +	bicl3	#0,r0,-108(fp)
        +	cmpl	-108(fp),-112(fp)
        +	bgequ	noname.408
        +	addl2	#65536,-120(fp)
        +noname.408:
        +	movzwl	-106(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-120(fp)
        +	bicl3	#-65536,-108(fp),r0
        +	ashl	#16,r0,-112(fp)
        +	addl3	-112(fp),-116(fp),r0
        +	bicl3	#0,r0,-116(fp)
        +	cmpl	-116(fp),-112(fp)
        +	bgequ	noname.409
        +	incl	-120(fp)
        +noname.409:
        +	movl	-116(fp),r3
        +	movl	-120(fp),r2
        +	bbc	#31,r2,noname.410
        +	incl	r9
        +noname.410:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.411
        +	incl	r2
        +noname.411:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.412
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.412
        +	incl	r9
        +noname.412:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.413
        +	incl	r9
        +noname.413:
        +
        +	movl	4(ap),r0
        +	movl	r8,16(r0)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r0
        +	movzwl	22(r0),r2
        +	bicl3	#-65536,(r0),r3
        +	movzwl	2(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r0),-132(fp)
        +	bicl3	#-65536,r2,-136(fp)
        +	mull3	r1,-132(fp),-124(fp)
        +	mull2	r3,-132(fp)
        +	mull3	r3,-136(fp),-128(fp)
        +	mull2	r1,-136(fp)
        +	addl3	-124(fp),-128(fp),r0
        +	bicl3	#0,r0,-124(fp)
        +	cmpl	-124(fp),-128(fp)
        +	bgequ	noname.414
        +	addl2	#65536,-136(fp)
        +noname.414:
        +	movzwl	-122(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-136(fp)
        +	bicl3	#-65536,-124(fp),r0
        +	ashl	#16,r0,-128(fp)
        +	addl3	-128(fp),-132(fp),r0
        +	bicl3	#0,r0,-132(fp)
        +	cmpl	-132(fp),-128(fp)
        +	bgequ	noname.415
        +	incl	-136(fp)
        +noname.415:
        +	movl	-132(fp),r3
        +	movl	-136(fp),r2
        +	bbc	#31,r2,noname.416
        +	incl	r8
        +noname.416:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.417
        +	incl	r2
        +noname.417:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.418
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.418
        +	incl	r8
        +noname.418:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.419
        +	incl	r8
        +noname.419:
        +
        +	movl	8(ap),r0
        +	movzwl	18(r0),r2
        +	bicl3	#-65536,4(r0),r3
        +	movzwl	6(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r0),-148(fp)
        +	bicl3	#-65536,r2,-152(fp)
        +	mull3	r1,-148(fp),-140(fp)
        +	mull2	r3,-148(fp)
        +	mull3	r3,-152(fp),-144(fp)
        +	mull2	r1,-152(fp)
        +	addl3	-140(fp),-144(fp),r0
        +	bicl3	#0,r0,-140(fp)
        +	cmpl	-140(fp),-144(fp)
        +	bgequ	noname.420
        +	addl2	#65536,-152(fp)
        +noname.420:
        +	movzwl	-138(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-152(fp)
        +	bicl3	#-65536,-140(fp),r0
        +	ashl	#16,r0,-144(fp)
        +	addl3	-144(fp),-148(fp),r0
        +	bicl3	#0,r0,-148(fp)
        +	cmpl	-148(fp),-144(fp)
        +	bgequ	noname.421
        +	incl	-152(fp)
        +noname.421:
        +	movl	-148(fp),r3
        +	movl	-152(fp),r2
        +	bbc	#31,r2,noname.422
        +	incl	r8
        +noname.422:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.423
        +	incl	r2
        +noname.423:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.424
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.424
        +	incl	r8
        +noname.424:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.425
        +	incl	r8
        +noname.425:
        +
        +	movl	8(ap),r0
        +	movzwl	14(r0),r2
        +	bicl3	#-65536,8(r0),r3
        +	movzwl	10(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r0),-164(fp)
        +	bicl3	#-65536,r2,-168(fp)
        +	mull3	r1,-164(fp),-156(fp)
        +	mull2	r3,-164(fp)
        +	mull3	r3,-168(fp),-160(fp)
        +	mull2	r1,-168(fp)
        +	addl3	-156(fp),-160(fp),r0
        +	bicl3	#0,r0,-156(fp)
        +	cmpl	-156(fp),-160(fp)
        +	bgequ	noname.426
        +	addl2	#65536,-168(fp)
        +noname.426:
        +	movzwl	-154(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-168(fp)
        +	bicl3	#-65536,-156(fp),r0
        +	ashl	#16,r0,-160(fp)
        +	addl3	-160(fp),-164(fp),r0
        +	bicl3	#0,r0,-164(fp)
        +	cmpl	-164(fp),-160(fp)
        +	bgequ	noname.427
        +	incl	-168(fp)
        +noname.427:
        +	movl	-164(fp),r3
        +	movl	-168(fp),r2
        +	bbc	#31,r2,noname.428
        +	incl	r8
        +noname.428:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.429
        +	incl	r2
        +noname.429:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.430
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.430
        +	incl	r8
        +noname.430:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.431
        +	incl	r8
        +noname.431:
        +
        +	movl	4(ap),r0
        +	movl	r7,20(r0)
        +
        +	clrl	r7
        +
        +	movl	8(ap),r2
        +	movl	12(r2),r4
        +	bicl3	#-65536,r4,-172(fp)
        +	extzv	#16,#16,r4,r0
        +	bicl3	#-65536,r0,r4
        +	movl	-172(fp),r0
        +	mull3	r0,r4,-176(fp)
        +	mull3	r0,r0,-172(fp)
        +	mull2	r4,r4
        +	bicl3	#32767,-176(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-176(fp),r0
        +	ashl	#17,r0,-176(fp)
        +	addl3	-172(fp),-176(fp),r0
        +	bicl3	#0,r0,-172(fp)
        +	cmpl	-172(fp),-176(fp)
        +	bgequ	noname.432
        +	incl	r4
        +noname.432:
        +	movl	-172(fp),r1
        +	movl	r4,r3
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.433
        +	incl	r3
        +noname.433:
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.434
        +	incl	r7
        +noname.434:
        +
        +	movzwl	18(r2),r3
        +	bicl3	#-65536,8(r2),r1
        +	movzwl	10(r2),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,16(r2),-188(fp)
        +	bicl3	#-65536,r3,-192(fp)
        +	mull3	r0,-188(fp),-180(fp)
        +	mull2	r1,-188(fp)
        +	mull3	r1,-192(fp),-184(fp)
        +	mull2	r0,-192(fp)
        +	addl3	-180(fp),-184(fp),r0
        +	bicl3	#0,r0,-180(fp)
        +	cmpl	-180(fp),-184(fp)
        +	bgequ	noname.435
        +	addl2	#65536,-192(fp)
        +noname.435:
        +	movzwl	-178(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-192(fp)
        +	bicl3	#-65536,-180(fp),r0
        +	ashl	#16,r0,-184(fp)
        +	addl3	-184(fp),-188(fp),r0
        +	bicl3	#0,r0,-188(fp)
        +	cmpl	-188(fp),-184(fp)
        +	bgequ	noname.436
        +	incl	-192(fp)
        +noname.436:
        +	movl	-188(fp),r3
        +	movl	-192(fp),r2
        +	bbc	#31,r2,noname.437
        +	incl	r7
        +noname.437:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.438
        +	incl	r2
        +noname.438:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.439
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.439
        +	incl	r7
        +noname.439:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.440
        +	incl	r7
        +noname.440:
        +
        +	movl	8(ap),r0
        +	movzwl	22(r0),r2
        +	bicl3	#-65536,4(r0),r3
        +	movzwl	6(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r0),-204(fp)
        +	bicl3	#-65536,r2,-208(fp)
        +	mull3	r1,-204(fp),-196(fp)
        +	mull2	r3,-204(fp)
        +	mull3	r3,-208(fp),-200(fp)
        +	mull2	r1,-208(fp)
        +	addl3	-196(fp),-200(fp),r0
        +	bicl3	#0,r0,-196(fp)
        +	cmpl	-196(fp),-200(fp)
        +	bgequ	noname.441
        +	addl2	#65536,-208(fp)
        +noname.441:
        +	movzwl	-194(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-208(fp)
        +	bicl3	#-65536,-196(fp),r0
        +	ashl	#16,r0,-200(fp)
        +	addl3	-200(fp),-204(fp),r0
        +	bicl3	#0,r0,-204(fp)
        +	cmpl	-204(fp),-200(fp)
        +	bgequ	noname.442
        +	incl	-208(fp)
        +noname.442:
        +	movl	-204(fp),r3
        +	movl	-208(fp),r2
        +	bbc	#31,r2,noname.443
        +	incl	r7
        +noname.443:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.444
        +	incl	r2
        +noname.444:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.445
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.445
        +	incl	r7
        +noname.445:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.446
        +	incl	r7
        +noname.446:
        +
        +	movl	8(ap),r0
        +	movzwl	26(r0),r2
        +	bicl3	#-65536,(r0),r3
        +	movzwl	2(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,24(r0),-220(fp)
        +	bicl3	#-65536,r2,-224(fp)
        +	mull3	r1,-220(fp),-212(fp)
        +	mull2	r3,-220(fp)
        +	mull3	r3,-224(fp),-216(fp)
        +	mull2	r1,-224(fp)
        +	addl3	-212(fp),-216(fp),r0
        +	bicl3	#0,r0,-212(fp)
        +	cmpl	-212(fp),-216(fp)
        +	bgequ	noname.447
        +	addl2	#65536,-224(fp)
        +noname.447:
        +	movzwl	-210(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-224(fp)
        +	bicl3	#-65536,-212(fp),r0
        +	ashl	#16,r0,-216(fp)
        +	addl3	-216(fp),-220(fp),r0
        +	bicl3	#0,r0,-220(fp)
        +	cmpl	-220(fp),-216(fp)
        +	bgequ	noname.448
        +	incl	-224(fp)
        +noname.448:
        +	movl	-220(fp),r3
        +	movl	-224(fp),r2
        +	bbc	#31,r2,noname.449
        +	incl	r7
        +noname.449:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.450
        +	incl	r2
        +noname.450:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.451
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.451
        +	incl	r7
        +noname.451:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.452
        +	incl	r7
        +noname.452:
        +
        +	movl	4(ap),r0
        +	movl	r9,24(r0)
        +
        +	clrl	r9
        +
        +	movl	8(ap),r0
        +	movzwl	30(r0),r2
        +	bicl3	#-65536,(r0),r3
        +	movzwl	2(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,28(r0),-236(fp)
        +	bicl3	#-65536,r2,-240(fp)
        +	mull3	r1,-236(fp),-228(fp)
        +	mull2	r3,-236(fp)
        +	mull3	r3,-240(fp),-232(fp)
        +	mull2	r1,-240(fp)
        +	addl3	-228(fp),-232(fp),r0
        +	bicl3	#0,r0,-228(fp)
        +	cmpl	-228(fp),-232(fp)
        +	bgequ	noname.453
        +	addl2	#65536,-240(fp)
        +noname.453:
        +	movzwl	-226(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-240(fp)
        +	bicl3	#-65536,-228(fp),r0
        +	ashl	#16,r0,-232(fp)
        +	addl3	-232(fp),-236(fp),r0
        +	bicl3	#0,r0,-236(fp)
        +	cmpl	-236(fp),-232(fp)
        +	bgequ	noname.454
        +	incl	-240(fp)
        +noname.454:
        +	movl	-236(fp),r3
        +	movl	-240(fp),r2
        +	bbc	#31,r2,noname.455
        +	incl	r9
        +noname.455:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.456
        +	incl	r2
        +noname.456:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.457
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.457
        +	incl	r9
        +noname.457:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.458
        +	incl	r9
        +noname.458:
        +
        +	movl	8(ap),r0
        +	movzwl	26(r0),r2
        +	bicl3	#-65536,4(r0),r3
        +	movzwl	6(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,24(r0),-252(fp)
        +	bicl3	#-65536,r2,-256(fp)
        +	mull3	r1,-252(fp),-244(fp)
        +	mull2	r3,-252(fp)
        +	mull3	r3,-256(fp),-248(fp)
        +	mull2	r1,-256(fp)
        +	addl3	-244(fp),-248(fp),r0
        +	bicl3	#0,r0,-244(fp)
        +	cmpl	-244(fp),-248(fp)
        +	bgequ	noname.459
        +	addl2	#65536,-256(fp)
        +noname.459:
        +	movzwl	-242(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-256(fp)
        +	bicl3	#-65536,-244(fp),r0
        +	ashl	#16,r0,-248(fp)
        +	addl3	-248(fp),-252(fp),r0
        +	bicl3	#0,r0,-252(fp)
        +	cmpl	-252(fp),-248(fp)
        +	bgequ	noname.460
        +	incl	-256(fp)
        +noname.460:
        +	movl	-252(fp),r3
        +	movl	-256(fp),r2
        +	bbc	#31,r2,noname.461
        +	incl	r9
        +noname.461:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.462
        +	incl	r2
        +noname.462:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.463
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.463
        +	incl	r9
        +noname.463:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.464
        +	incl	r9
        +noname.464:
        +
        +	movl	8(ap),r0
        +	movzwl	22(r0),r2
        +	bicl3	#-65536,8(r0),r3
        +	movzwl	10(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r0),-268(fp)
        +	bicl3	#-65536,r2,-272(fp)
        +	mull3	r1,-268(fp),-260(fp)
        +	mull2	r3,-268(fp)
        +	mull3	r3,-272(fp),-264(fp)
        +	mull2	r1,-272(fp)
        +	addl3	-260(fp),-264(fp),r0
        +	bicl3	#0,r0,-260(fp)
        +	cmpl	-260(fp),-264(fp)
        +	bgequ	noname.465
        +	addl2	#65536,-272(fp)
        +noname.465:
        +	movzwl	-258(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-272(fp)
        +	bicl3	#-65536,-260(fp),r0
        +	ashl	#16,r0,-264(fp)
        +	addl3	-264(fp),-268(fp),r0
        +	bicl3	#0,r0,-268(fp)
        +	cmpl	-268(fp),-264(fp)
        +	bgequ	noname.466
        +	incl	-272(fp)
        +noname.466:
        +	movl	-268(fp),r3
        +	movl	-272(fp),r2
        +	bbc	#31,r2,noname.467
        +	incl	r9
        +noname.467:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.468
        +	incl	r2
        +noname.468:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.469
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.469
        +	incl	r9
        +noname.469:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.470
        +	incl	r9
        +noname.470:
        +
        +	movl	8(ap),r0
        +	movzwl	18(r0),r2
        +	bicl3	#-65536,12(r0),r3
        +	movzwl	14(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r0),-284(fp)
        +	bicl3	#-65536,r2,-288(fp)
        +	mull3	r1,-284(fp),-276(fp)
        +	mull2	r3,-284(fp)
        +	mull3	r3,-288(fp),-280(fp)
        +	mull2	r1,-288(fp)
        +	addl3	-276(fp),-280(fp),r0
        +	bicl3	#0,r0,-276(fp)
        +	cmpl	-276(fp),-280(fp)
        +	bgequ	noname.471
        +	addl2	#65536,-288(fp)
        +noname.471:
        +	movzwl	-274(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-288(fp)
        +	bicl3	#-65536,-276(fp),r0
        +	ashl	#16,r0,-280(fp)
        +	addl3	-280(fp),-284(fp),r0
        +	bicl3	#0,r0,-284(fp)
        +	cmpl	-284(fp),-280(fp)
        +	bgequ	noname.472
        +	incl	-288(fp)
        +noname.472:
        +	movl	-284(fp),r3
        +	movl	-288(fp),r2
        +	bbc	#31,r2,noname.473
        +	incl	r9
        +noname.473:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.474
        +	incl	r2
        +noname.474:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.475
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.475
        +	incl	r9
        +noname.475:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.476
        +	incl	r9
        +noname.476:
        +
        +	movl	4(ap),r0
        +	movl	r8,28(r0)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r3
        +	movl	16(r3),r4
        +	bicl3	#-65536,r4,r5
        +	extzv	#16,#16,r4,r0
        +	bicl3	#-65536,r0,r4
        +	mull3	r5,r4,-292(fp)
        +	mull2	r5,r5
        +	mull2	r4,r4
        +	bicl3	#32767,-292(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-292(fp),r0
        +	ashl	#17,r0,-292(fp)
        +	addl2	-292(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-292(fp)
        +	bgequ	noname.477
        +	incl	r4
        +noname.477:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r1
        +	bgequ	noname.478
        +	incl	r2
        +noname.478:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.479
        +	incl	r8
        +noname.479:
        +
        +	bicl3	#-65536,20(r3),r4
        +	movzwl	22(r3),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r3),r2
        +	movzwl	14(r3),r0
        +	bicl2	#-65536,r0
        +	movl	r4,r6
        +	movl	r1,r5
        +	mull3	r0,r6,-296(fp)
        +	mull2	r2,r6
        +	mull3	r2,r5,-300(fp)
        +	mull2	r0,r5
        +	addl3	-296(fp),-300(fp),r0
        +	bicl3	#0,r0,-296(fp)
        +	cmpl	-296(fp),-300(fp)
        +	bgequ	noname.480
        +	addl2	#65536,r5
        +noname.480:
        +	movzwl	-294(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r5
        +	bicl3	#-65536,-296(fp),r0
        +	ashl	#16,r0,-300(fp)
        +	addl2	-300(fp),r6
        +	bicl2	#0,r6
        +	cmpl	r6,-300(fp)
        +	bgequ	noname.481
        +	incl	r5
        +noname.481:
        +	movl	r6,r3
        +	movl	r5,r2
        +	bbc	#31,r2,noname.482
        +	incl	r8
        +noname.482:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.483
        +	incl	r2
        +noname.483:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.484
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.484
        +	incl	r8
        +noname.484:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.485
        +	incl	r8
        +noname.485:
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,24(r0),r3
        +	movzwl	26(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,8(r0),r2
        +	movzwl	10(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-304(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-308(fp)
        +	mull2	r0,r4
        +	addl3	-304(fp),-308(fp),r0
        +	bicl3	#0,r0,-304(fp)
        +	cmpl	-304(fp),-308(fp)
        +	bgequ	noname.486
        +	addl2	#65536,r4
        +noname.486:
        +	movzwl	-302(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-304(fp),r0
        +	ashl	#16,r0,-308(fp)
        +	addl2	-308(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-308(fp)
        +	bgequ	noname.487
        +	incl	r4
        +noname.487:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.488
        +	incl	r8
        +noname.488:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.489
        +	incl	r2
        +noname.489:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.490
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.490
        +	incl	r8
        +noname.490:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.491
        +	incl	r8
        +noname.491:
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,28(r0),r3
        +	movzwl	30(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r0),r2
        +	movzwl	6(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-312(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-316(fp)
        +	mull2	r0,r4
        +	addl3	-312(fp),-316(fp),r0
        +	bicl3	#0,r0,-312(fp)
        +	cmpl	-312(fp),-316(fp)
        +	bgequ	noname.492
        +	addl2	#65536,r4
        +noname.492:
        +	movzwl	-310(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-312(fp),r0
        +	ashl	#16,r0,-316(fp)
        +	addl2	-316(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-316(fp)
        +	bgequ	noname.493
        +	incl	r4
        +noname.493:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.494
        +	incl	r8
        +noname.494:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.495
        +	incl	r2
        +noname.495:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.496
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.496
        +	incl	r8
        +noname.496:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.497
        +	incl	r8
        +noname.497:
        +
        +	movl	4(ap),r0
        +	movl	r7,32(r0)
        +
        +	clrl	r7
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,28(r0),r3
        +	movzwl	30(r0),r2
        +	bicl3	#-65536,8(r0),r1
        +	movzwl	10(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r4
        +	bicl3	#-65536,r2,-328(fp)
        +	mull3	r0,r4,-320(fp)
        +	mull2	r1,r4
        +	mull3	r1,-328(fp),-324(fp)
        +	mull2	r0,-328(fp)
        +	addl3	-320(fp),-324(fp),r0
        +	bicl3	#0,r0,-320(fp)
        +	cmpl	-320(fp),-324(fp)
        +	bgequ	noname.498
        +	addl2	#65536,-328(fp)
        +noname.498:
        +	movzwl	-318(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-328(fp)
        +	bicl3	#-65536,-320(fp),r0
        +	ashl	#16,r0,-324(fp)
        +	addl2	-324(fp),r4
        +	bicl2	#0,r4
        +	cmpl	r4,-324(fp)
        +	bgequ	noname.499
        +	incl	-328(fp)
        +noname.499:
        +	movl	r4,r3
        +	movl	-328(fp),r2
        +	bbc	#31,r2,noname.500
        +	incl	r7
        +noname.500:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.501
        +	incl	r2
        +noname.501:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.502
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.502
        +	incl	r7
        +noname.502:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.503
        +	incl	r7
        +noname.503:
        +
        +	movl	8(ap),r0
        +	movzwl	26(r0),r2
        +	bicl3	#-65536,12(r0),r3
        +	movzwl	14(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,24(r0),-340(fp)
        +	bicl3	#-65536,r2,-344(fp)
        +	mull3	r1,-340(fp),-332(fp)
        +	mull2	r3,-340(fp)
        +	mull3	r3,-344(fp),-336(fp)
        +	mull2	r1,-344(fp)
        +	addl3	-332(fp),-336(fp),r0
        +	bicl3	#0,r0,-332(fp)
        +	cmpl	-332(fp),-336(fp)
        +	bgequ	noname.504
        +	addl2	#65536,-344(fp)
        +noname.504:
        +	movzwl	-330(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-344(fp)
        +	bicl3	#-65536,-332(fp),r0
        +	ashl	#16,r0,-336(fp)
        +	addl3	-336(fp),-340(fp),r0
        +	bicl3	#0,r0,-340(fp)
        +	cmpl	-340(fp),-336(fp)
        +	bgequ	noname.505
        +	incl	-344(fp)
        +noname.505:
        +	movl	-340(fp),r3
        +	movl	-344(fp),r2
        +	bbc	#31,r2,noname.506
        +	incl	r7
        +noname.506:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.507
        +	incl	r2
        +noname.507:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.508
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.508
        +	incl	r7
        +noname.508:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.509
        +	incl	r7
        +noname.509:
        +
        +	movl	8(ap),r0
        +	movzwl	22(r0),r2
        +	bicl3	#-65536,16(r0),r3
        +	movzwl	18(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r0),-356(fp)
        +	bicl3	#-65536,r2,-360(fp)
        +	mull3	r1,-356(fp),-348(fp)
        +	mull2	r3,-356(fp)
        +	mull3	r3,-360(fp),-352(fp)
        +	mull2	r1,-360(fp)
        +	addl3	-348(fp),-352(fp),r0
        +	bicl3	#0,r0,-348(fp)
        +	cmpl	-348(fp),-352(fp)
        +	bgequ	noname.510
        +	addl2	#65536,-360(fp)
        +noname.510:
        +	movzwl	-346(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-360(fp)
        +	bicl3	#-65536,-348(fp),r0
        +	ashl	#16,r0,-352(fp)
        +	addl3	-352(fp),-356(fp),r0
        +	bicl3	#0,r0,-356(fp)
        +	cmpl	-356(fp),-352(fp)
        +	bgequ	noname.511
        +	incl	-360(fp)
        +noname.511:
        +	movl	-356(fp),r3
        +	movl	-360(fp),r2
        +	bbc	#31,r2,noname.512
        +	incl	r7
        +noname.512:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.513
        +	incl	r2
        +noname.513:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.514
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.514
        +	incl	r7
        +noname.514:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.515
        +	incl	r7
        +noname.515:
        +
        +	movl	4(ap),r0
        +	movl	r9,36(r0)
        +
        +	clrl	r9
        +
        +	movl	8(ap),r3
        +	movl	20(r3),r4
        +	bicl3	#-65536,r4,-364(fp)
        +	extzv	#16,#16,r4,r0
        +	bicl3	#-65536,r0,r4
        +	movl	-364(fp),r0
        +	mull3	r0,r4,-368(fp)
        +	mull3	r0,r0,-364(fp)
        +	mull2	r4,r4
        +	bicl3	#32767,-368(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-368(fp),r0
        +	ashl	#17,r0,-368(fp)
        +	addl3	-364(fp),-368(fp),r0
        +	bicl3	#0,r0,-364(fp)
        +	cmpl	-364(fp),-368(fp)
        +	bgequ	noname.516
        +	incl	r4
        +noname.516:
        +	movl	-364(fp),r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.517
        +	incl	r2
        +noname.517:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.518
        +	incl	r9
        +noname.518:
        +
        +	bicl3	#-65536,24(r3),r4
        +	movzwl	26(r3),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r3),r2
        +	movzwl	18(r3),r0
        +	bicl2	#-65536,r0
        +	movl	r4,r6
        +	movl	r1,r5
        +	mull3	r0,r6,-372(fp)
        +	mull2	r2,r6
        +	mull3	r2,r5,-376(fp)
        +	mull2	r0,r5
        +	addl3	-372(fp),-376(fp),r0
        +	bicl3	#0,r0,-372(fp)
        +	cmpl	-372(fp),-376(fp)
        +	bgequ	noname.519
        +	addl2	#65536,r5
        +noname.519:
        +	movzwl	-370(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r5
        +	bicl3	#-65536,-372(fp),r0
        +	ashl	#16,r0,-376(fp)
        +	addl2	-376(fp),r6
        +	bicl2	#0,r6
        +	cmpl	r6,-376(fp)
        +	bgequ	noname.520
        +	incl	r5
        +noname.520:
        +	movl	r6,r3
        +	movl	r5,r2
        +	bbc	#31,r2,noname.521
        +	incl	r9
        +noname.521:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.522
        +	incl	r2
        +noname.522:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.523
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.523
        +	incl	r9
        +noname.523:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.524
        +	incl	r9
        +noname.524:
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,28(r0),r3
        +	movzwl	30(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,12(r0),r2
        +	movzwl	14(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-380(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-384(fp)
        +	mull2	r0,r4
        +	addl3	-380(fp),-384(fp),r0
        +	bicl3	#0,r0,-380(fp)
        +	cmpl	-380(fp),-384(fp)
        +	bgequ	noname.525
        +	addl2	#65536,r4
        +noname.525:
        +	movzwl	-378(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-380(fp),r0
        +	ashl	#16,r0,-384(fp)
        +	addl2	-384(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-384(fp)
        +	bgequ	noname.526
        +	incl	r4
        +noname.526:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.527
        +	incl	r9
        +noname.527:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.528
        +	incl	r2
        +noname.528:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.529
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.529
        +	incl	r9
        +noname.529:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.530
        +	incl	r9
        +noname.530:
        +	movl	4(ap),r0
        +	movl	r8,40(r0)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,28(r0),r3
        +	movzwl	30(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,16(r0),r2
        +	movzwl	18(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-388(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-392(fp)
        +	mull2	r0,r4
        +	addl3	-388(fp),-392(fp),r0
        +	bicl3	#0,r0,-388(fp)
        +	cmpl	-388(fp),-392(fp)
        +	bgequ	noname.531
        +	addl2	#65536,r4
        +noname.531:
        +	movzwl	-386(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-388(fp),r0
        +	ashl	#16,r0,-392(fp)
        +	addl2	-392(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-392(fp)
        +	bgequ	noname.532
        +	incl	r4
        +noname.532:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.533
        +	incl	r8
        +noname.533:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.534
        +	incl	r2
        +noname.534:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.535
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.535
        +	incl	r8
        +noname.535:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.536
        +	incl	r8
        +noname.536:
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,24(r0),r3
        +	movzwl	26(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,20(r0),r2
        +	movzwl	22(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-396(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-400(fp)
        +	mull2	r0,r4
        +	addl3	-396(fp),-400(fp),r0
        +	bicl3	#0,r0,-396(fp)
        +	cmpl	-396(fp),-400(fp)
        +	bgequ	noname.537
        +	addl2	#65536,r4
        +noname.537:
        +	movzwl	-394(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-396(fp),r0
        +	ashl	#16,r0,-400(fp)
        +	addl2	-400(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-400(fp)
        +	bgequ	noname.538
        +	incl	r4
        +noname.538:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.539
        +	incl	r8
        +noname.539:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.540
        +	incl	r2
        +noname.540:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r3
        +	bgequ	noname.541
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.541
        +	incl	r8
        +noname.541:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.542
        +	incl	r8
        +noname.542:
        +
        +	movl	4(ap),r0
        +	movl	r7,44(r0)
        +
        +	clrl	r7
        +
        +	movl	8(ap),r3
        +	movl	24(r3),r4
        +	bicl3	#-65536,r4,r5
        +	extzv	#16,#16,r4,r0
        +	bicl3	#-65536,r0,r4
        +	mull3	r5,r4,-404(fp)
        +	mull2	r5,r5
        +	mull2	r4,r4
        +	bicl3	#32767,-404(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-404(fp),r0
        +	ashl	#17,r0,-404(fp)
        +	addl2	-404(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-404(fp)
        +	bgequ	noname.543
        +	incl	r4
        +noname.543:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.544
        +	incl	r2
        +noname.544:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.545
        +	incl	r7
        +noname.545:
        +
        +	movzwl	30(r3),r2
        +	bicl3	#-65536,20(r3),r1
        +	movzwl	22(r3),r0
        +	bicl2	#-65536,r0
        +	bicl3	#-65536,28(r3),-416(fp)
        +	bicl3	#-65536,r2,-420(fp)
        +	mull3	r0,-416(fp),-408(fp)
        +	mull2	r1,-416(fp)
        +	mull3	r1,-420(fp),-412(fp)
        +	mull2	r0,-420(fp)
        +	addl3	-408(fp),-412(fp),r0
        +	bicl3	#0,r0,-408(fp)
        +	cmpl	-408(fp),-412(fp)
        +	bgequ	noname.546
        +	addl2	#65536,-420(fp)
        +noname.546:
        +	movzwl	-406(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-420(fp)
        +	bicl3	#-65536,-408(fp),r0
        +	ashl	#16,r0,-412(fp)
        +	addl3	-412(fp),-416(fp),r0
        +	bicl3	#0,r0,-416(fp)
        +	cmpl	-416(fp),-412(fp)
        +	bgequ	noname.547
        +	incl	-420(fp)
        +noname.547:
        +	movl	-416(fp),r3
        +	movl	-420(fp),r2
        +	bbc	#31,r2,noname.548
        +	incl	r7
        +noname.548:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.549
        +	incl	r2
        +noname.549:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.550
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.550
        +	incl	r7
        +noname.550:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.551
        +	incl	r7
        +noname.551:
        +
        +	movl	4(ap),r0
        +	movl	r9,48(r0)
        +
        +	clrl	r9
        +
        +	movl	8(ap),r0
        +	movzwl	30(r0),r2
        +	bicl3	#-65536,24(r0),r3
        +	movzwl	26(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,28(r0),-432(fp)
        +	bicl3	#-65536,r2,-436(fp)
        +	mull3	r1,-432(fp),-424(fp)
        +	mull2	r3,-432(fp)
        +	mull3	r3,-436(fp),-428(fp)
        +	mull2	r1,-436(fp)
        +	addl3	-424(fp),-428(fp),r0
        +	bicl3	#0,r0,-424(fp)
        +	cmpl	-424(fp),-428(fp)
        +	bgequ	noname.552
        +	addl2	#65536,-436(fp)
        +noname.552:
        +	movzwl	-422(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,-436(fp)
        +	bicl3	#-65536,-424(fp),r0
        +	ashl	#16,r0,-428(fp)
        +	addl3	-428(fp),-432(fp),r0
        +	bicl3	#0,r0,-432(fp)
        +	cmpl	-432(fp),-428(fp)
        +	bgequ	noname.553
        +	incl	-436(fp)
        +noname.553:
        +	movl	-432(fp),r3
        +	movl	-436(fp),r2
        +	bbc	#31,r2,noname.554
        +	incl	r9
        +noname.554:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.555
        +	incl	r2
        +noname.555:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.556
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.556
        +	incl	r9
        +noname.556:
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.557
        +	incl	r9
        +noname.557:
        +
        +	movl	4(ap),r4
        +	movl	r8,52(r4)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r0
        +	movl	28(r0),r3
        +	bicl3	#-65536,r3,-440(fp)
        +	extzv	#16,#16,r3,r0
        +	bicl3	#-65536,r0,r3
        +	movl	-440(fp),r0
        +	mull3	r0,r3,-444(fp)
        +	mull3	r0,r0,-440(fp)
        +	mull2	r3,r3
        +	bicl3	#32767,-444(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r3
        +	bicl3	#-65536,-444(fp),r0
        +	ashl	#17,r0,-444(fp)
        +	addl3	-440(fp),-444(fp),r0
        +	bicl3	#0,r0,-440(fp)
        +	cmpl	-440(fp),-444(fp)
        +	bgequ	noname.558
        +	incl	r3
        +noname.558:
        +	movl	-440(fp),r1
        +	movl	r3,r2
        +	addl2	r1,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r1
        +	bgequ	noname.559
        +	incl	r2
        +noname.559:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.560
        +	incl	r8
        +noname.560:
        +
        +	movl	r7,56(r4)
        +
        +	movl	r9,60(r4)
        +
        +	ret	
        +
        +
        +
        +;r=4 ;(AP)
        +;a=8 ;(AP)
        +;b=12 ;(AP)
        +;n=16 ;(AP)	n	by value (input)
        +
        +	.psect	code,nowrt
        +
        +.entry	BN_SQR_COMBA4,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10>
        +	subl2	#44,sp
        +
        +	clrq	r8
        +
        +	clrl	r10
        +
        +	movl	8(ap),r5
        +	movl	(r5),r3
        +	bicl3	#-65536,r3,r4
        +	extzv	#16,#16,r3,r0
        +	bicl3	#-65536,r0,r3
        +	mull3	r4,r3,-4(fp)
        +	mull2	r4,r4
        +	mull2	r3,r3
        +	bicl3	#32767,-4(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r3
        +	bicl3	#-65536,-4(fp),r0
        +	ashl	#17,r0,-4(fp)
        +	addl2	-4(fp),r4
        +	bicl2	#0,r4
        +	cmpl	r4,-4(fp)
        +	bgequ	noname.563
        +	incl	r3
        +noname.563:
        +	movl	r4,r1
        +	movl	r3,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.564
        +	incl	r2
        +noname.564:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.565
        +	incl	r10
        +noname.565:
        +
        +	movl	r9,@4(ap)
        +
        +	clrl	r9
        +
        +	bicl3	#-65536,4(r5),r3
        +	movzwl	6(r5),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,(r5),r2
        +	movzwl	2(r5),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r6
        +	movl	r1,r4
        +	mull3	r0,r6,-8(fp)
        +	mull2	r2,r6
        +	mull2	r4,r2
        +	mull2	r0,r4
        +	addl3	-8(fp),r2,r0
        +	bicl3	#0,r0,-8(fp)
        +	cmpl	-8(fp),r2
        +	bgequ	noname.566
        +	addl2	#65536,r4
        +noname.566:
        +	movzwl	-6(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-8(fp),r0
        +	ashl	#16,r0,r1
        +	addl2	r1,r6
        +	bicl2	#0,r6
        +	cmpl	r6,r1
        +	bgequ	noname.567
        +	incl	r4
        +noname.567:
        +	movl	r6,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.568
        +	incl	r9
        +noname.568:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.569
        +	incl	r2
        +noname.569:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.570
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.570
        +	incl	r9
        +noname.570:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.571
        +	incl	r9
        +noname.571:
        +
        +	movl	4(ap),r0
        +	movl	r8,4(r0)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r4
        +	movl	4(r4),r3
        +	bicl3	#-65536,r3,r5
        +	extzv	#16,#16,r3,r0
        +	bicl3	#-65536,r0,r3
        +	mull3	r5,r3,r1
        +	mull2	r5,r5
        +	mull2	r3,r3
        +	bicl3	#32767,r1,r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r3
        +	bicl2	#-65536,r1
        +	ashl	#17,r1,r1
        +	addl2	r1,r5
        +	bicl2	#0,r5
        +	cmpl	r5,r1
        +	bgequ	noname.572
        +	incl	r3
        +noname.572:
        +	movl	r5,r1
        +	movl	r3,r2
        +	addl2	r1,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r1
        +	bgequ	noname.573
        +	incl	r2
        +noname.573:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.574
        +	incl	r8
        +noname.574:
        +
        +	bicl3	#-65536,8(r4),r3
        +	movzwl	10(r4),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,(r4),r2
        +	movzwl	2(r4),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r6
        +	movl	r1,r5
        +	mull3	r0,r6,r7
        +	mull2	r2,r6
        +	mull2	r5,r2
        +	mull2	r0,r5
        +	addl2	r2,r7
        +	bicl2	#0,r7
        +	cmpl	r7,r2
        +	bgequ	noname.575
        +	addl2	#65536,r5
        +noname.575:
        +	extzv	#16,#16,r7,r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r5
        +	bicl3	#-65536,r7,r0
        +	ashl	#16,r0,r1
        +	addl2	r1,r6
        +	bicl2	#0,r6
        +	cmpl	r6,r1
        +	bgequ	noname.576
        +	incl	r5
        +noname.576:
        +	movl	r6,r3
        +	movl	r5,r2
        +	bbc	#31,r2,noname.577
        +	incl	r8
        +noname.577:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.578
        +	incl	r2
        +noname.578:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r3
        +	bgequ	noname.579
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.579
        +	incl	r8
        +noname.579:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.580
        +	incl	r8
        +noname.580:
        +
        +	movl	4(ap),r0
        +	movl	r10,8(r0)
        +
        +	clrl	r10
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,12(r0),r3
        +	movzwl	14(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,(r0),r2
        +	movzwl	2(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,r6
        +	mull2	r2,r5
        +	mull3	r2,r4,-12(fp)
        +	mull2	r0,r4
        +	addl2	-12(fp),r6
        +	bicl2	#0,r6
        +	cmpl	r6,-12(fp)
        +	bgequ	noname.581
        +	addl2	#65536,r4
        +noname.581:
        +	extzv	#16,#16,r6,r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,r6,r0
        +	ashl	#16,r0,-12(fp)
        +	addl2	-12(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-12(fp)
        +	bgequ	noname.582
        +	incl	r4
        +noname.582:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.583
        +	incl	r10
        +noname.583:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.584
        +	incl	r2
        +noname.584:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.585
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.585
        +	incl	r10
        +noname.585:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.586
        +	incl	r10
        +noname.586:
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,8(r0),r3
        +	movzwl	10(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r0),r2
        +	movzwl	6(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-16(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-20(fp)
        +	mull2	r0,r4
        +	addl3	-16(fp),-20(fp),r0
        +	bicl3	#0,r0,-16(fp)
        +	cmpl	-16(fp),-20(fp)
        +	bgequ	noname.587
        +	addl2	#65536,r4
        +noname.587:
        +	movzwl	-14(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-16(fp),r0
        +	ashl	#16,r0,-20(fp)
        +	addl2	-20(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-20(fp)
        +	bgequ	noname.588
        +	incl	r4
        +noname.588:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.589
        +	incl	r10
        +noname.589:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.590
        +	incl	r2
        +noname.590:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r3
        +	bgequ	noname.591
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.591
        +	incl	r10
        +noname.591:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.592
        +	incl	r10
        +noname.592:
        +	movl	4(ap),r0
        +	movl	r9,12(r0)
        +
        +	clrl	r9
        +
        +	movl	8(ap),r3
        +	movl	8(r3),r4
        +	bicl3	#-65536,r4,r5
        +	extzv	#16,#16,r4,r0
        +	bicl3	#-65536,r0,r4
        +	mull3	r5,r4,-24(fp)
        +	mull2	r5,r5
        +	mull2	r4,r4
        +	bicl3	#32767,-24(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-24(fp),r0
        +	ashl	#17,r0,-24(fp)
        +	addl2	-24(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-24(fp)
        +	bgequ	noname.593
        +	incl	r4
        +noname.593:
        +	movl	r5,r1
        +	movl	r4,r2
        +	addl2	r1,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r1
        +	bgequ	noname.594
        +	incl	r2
        +noname.594:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.595
        +	incl	r9
        +noname.595:
        +
        +	bicl3	#-65536,12(r3),r4
        +	movzwl	14(r3),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,4(r3),r2
        +	movzwl	6(r3),r0
        +	bicl2	#-65536,r0
        +	movl	r4,r6
        +	movl	r1,r5
        +	mull3	r0,r6,-28(fp)
        +	mull2	r2,r6
        +	mull3	r2,r5,-32(fp)
        +	mull2	r0,r5
        +	addl3	-28(fp),-32(fp),r0
        +	bicl3	#0,r0,-28(fp)
        +	cmpl	-28(fp),-32(fp)
        +	bgequ	noname.596
        +	addl2	#65536,r5
        +noname.596:
        +	movzwl	-26(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r5
        +	bicl3	#-65536,-28(fp),r0
        +	ashl	#16,r0,-32(fp)
        +	addl2	-32(fp),r6
        +	bicl2	#0,r6
        +	cmpl	r6,-32(fp)
        +	bgequ	noname.597
        +	incl	r5
        +noname.597:
        +	movl	r6,r3
        +	movl	r5,r2
        +	bbc	#31,r2,noname.598
        +	incl	r9
        +noname.598:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.599
        +	incl	r2
        +noname.599:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r3
        +	bgequ	noname.600
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.600
        +	incl	r9
        +noname.600:
        +	addl2	r2,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r2
        +	bgequ	noname.601
        +	incl	r9
        +noname.601:
        +
        +	movl	4(ap),r0
        +	movl	r8,16(r0)
        +
        +	clrl	r8
        +
        +	movl	8(ap),r0
        +	bicl3	#-65536,12(r0),r3
        +	movzwl	14(r0),r1
        +	bicl2	#-65536,r1
        +	bicl3	#-65536,8(r0),r2
        +	movzwl	10(r0),r0
        +	bicl2	#-65536,r0
        +	movl	r3,r5
        +	movl	r1,r4
        +	mull3	r0,r5,-36(fp)
        +	mull2	r2,r5
        +	mull3	r2,r4,-40(fp)
        +	mull2	r0,r4
        +	addl3	-36(fp),-40(fp),r0
        +	bicl3	#0,r0,-36(fp)
        +	cmpl	-36(fp),-40(fp)
        +	bgequ	noname.602
        +	addl2	#65536,r4
        +noname.602:
        +	movzwl	-34(fp),r0
        +	bicl2	#-65536,r0
        +	addl2	r0,r4
        +	bicl3	#-65536,-36(fp),r0
        +	ashl	#16,r0,-40(fp)
        +	addl2	-40(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-40(fp)
        +	bgequ	noname.603
        +	incl	r4
        +noname.603:
        +	movl	r5,r3
        +	movl	r4,r2
        +	bbc	#31,r2,noname.604
        +	incl	r8
        +noname.604:
        +	addl2	r2,r2
        +	bicl2	#0,r2
        +	bbc	#31,r3,noname.605
        +	incl	r2
        +noname.605:
        +	addl2	r3,r3
        +	bicl2	#0,r3
        +	addl2	r3,r10
        +	bicl2	#0,r10
        +	cmpl	r10,r3
        +	bgequ	noname.606
        +	incl	r2
        +	bicl3	#0,r2,r0
        +	bneq	noname.606
        +	incl	r8
        +noname.606:
        +	addl2	r2,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r2
        +	bgequ	noname.607
        +	incl	r8
        +noname.607:
        +
        +	movl	4(ap),r4
        +	movl	r10,20(r4)
        +
        +	clrl	r10
        +
        +	movl	8(ap),r0
        +	movl	12(r0),r3
        +	bicl3	#-65536,r3,r5
        +	extzv	#16,#16,r3,r0
        +	bicl3	#-65536,r0,r3
        +	mull3	r5,r3,-44(fp)
        +	mull2	r5,r5
        +	mull2	r3,r3
        +	bicl3	#32767,-44(fp),r0
        +	extzv	#15,#17,r0,r0
        +	addl2	r0,r3
        +	bicl3	#-65536,-44(fp),r0
        +	ashl	#17,r0,-44(fp)
        +	addl2	-44(fp),r5
        +	bicl2	#0,r5
        +	cmpl	r5,-44(fp)
        +	bgequ	noname.608
        +	incl	r3
        +noname.608:
        +	movl	r5,r1
        +	movl	r3,r2
        +	addl2	r1,r9
        +	bicl2	#0,r9
        +	cmpl	r9,r1
        +	bgequ	noname.609
        +	incl	r2
        +noname.609:
        +	addl2	r2,r8
        +	bicl2	#0,r8
        +	cmpl	r8,r2
        +	bgequ	noname.610
        +	incl	r10
        +noname.610:
        +
        +	movl	r9,24(r4)
        +
        +	movl	r8,28(r4)
        +
        +	ret	
        +
        +; For now, the code below doesn't work, so I end this prematurely.
        +.end
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86-gf2m.pl b/vendor/openssl/openssl/crypto/bn/asm/x86-gf2m.pl
        new file mode 100644
        index 000000000..808a1e596
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86-gf2m.pl
        @@ -0,0 +1,313 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# May 2011
        +#
        +# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
        +# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
        +# the time being... Except that it has three code paths: pure integer
        +# code suitable for any x86 CPU, MMX code suitable for PIII and later
        +# and PCLMULQDQ suitable for Westmere and later. Improvement varies
        +# from one benchmark and µ-arch to another. Below are interval values
        +# for 163- and 571-bit ECDH benchmarks relative to compiler-generated
        +# code:
        +#
        +# PIII		16%-30%
        +# P4		12%-12%
        +# Opteron	18%-40%
        +# Core2		19%-44%
        +# Atom		38%-64%
        +# Westmere	53%-121%(PCLMULQDQ)/20%-32%(MMX)
        +# Sandy Bridge	72%-127%(PCLMULQDQ)/27%-23%(MMX)
        +#
        +# Note that above improvement coefficients are not coefficients for
        +# bn_GF2m_mul_2x2 itself. For example 120% ECDH improvement is result
        +# of bn_GF2m_mul_2x2 being >4x faster. As it gets faster, benchmark
        +# is more and more dominated by other subroutines, most notably by
        +# BN_GF2m_mod[_mul]_arr...
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0,$x86only = $ARGV[$#ARGV] eq "386");
        +
        +$sse2=0;
        +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +&external_label("OPENSSL_ia32cap_P") if ($sse2);
        +
        +$a="eax";
        +$b="ebx";
        +($a1,$a2,$a4)=("ecx","edx","ebp");
        +
        +$R="mm0";
        +@T=("mm1","mm2");
        +($A,$B,$B30,$B31)=("mm2","mm3","mm4","mm5");
        +@i=("esi","edi");
        +
        +					if (!$x86only) {
        +&function_begin_B("_mul_1x1_mmx");
        +	&sub	("esp",32+4);
        +	 &mov	($a1,$a);
        +	 &lea	($a2,&DWP(0,$a,$a));
        +	 &and	($a1,0x3fffffff);
        +	 &lea	($a4,&DWP(0,$a2,$a2));
        +	 &mov	(&DWP(0*4,"esp"),0);
        +	 &and	($a2,0x7fffffff);
        +	&movd	($A,$a);
        +	&movd	($B,$b);
        +	 &mov	(&DWP(1*4,"esp"),$a1);	# a1
        +	 &xor	($a1,$a2);		# a1^a2
        +	&pxor	($B31,$B31);
        +	&pxor	($B30,$B30);
        +	 &mov	(&DWP(2*4,"esp"),$a2);	# a2
        +	 &xor	($a2,$a4);		# a2^a4
        +	 &mov	(&DWP(3*4,"esp"),$a1);	# a1^a2
        +	&pcmpgtd($B31,$A);		# broadcast 31st bit
        +	&paddd	($A,$A);		# $A<<=1
        +	 &xor	($a1,$a2);		# a1^a4=a1^a2^a2^a4
        +	 &mov	(&DWP(4*4,"esp"),$a4);	# a4
        +	 &xor	($a4,$a2);		# a2=a4^a2^a4
        +	&pand	($B31,$B);
        +	&pcmpgtd($B30,$A);		# broadcast 30th bit
        +	 &mov	(&DWP(5*4,"esp"),$a1);	# a1^a4
        +	 &xor	($a4,$a1);		# a1^a2^a4
        +	&psllq	($B31,31);
        +	&pand	($B30,$B);
        +	 &mov	(&DWP(6*4,"esp"),$a2);	# a2^a4
        +	&mov	(@i[0],0x7);
        +	 &mov	(&DWP(7*4,"esp"),$a4);	# a1^a2^a4
        +	 &mov	($a4,@i[0]);
        +	&and	(@i[0],$b);
        +	&shr	($b,3);
        +	&mov	(@i[1],$a4);
        +	&psllq	($B30,30);
        +	&and	(@i[1],$b);
        +	&shr	($b,3);
        +	&movd	($R,&DWP(0,"esp",@i[0],4));
        +	&mov	(@i[0],$a4);
        +	&and	(@i[0],$b);
        +	&shr	($b,3);
        +	for($n=1;$n<9;$n++) {
        +		&movd	(@T[1],&DWP(0,"esp",@i[1],4));
        +		&mov	(@i[1],$a4);
        +		&psllq	(@T[1],3*$n);
        +		&and	(@i[1],$b);
        +		&shr	($b,3);
        +		&pxor	($R,@T[1]);
        +
        +		push(@i,shift(@i)); push(@T,shift(@T));
        +	}
        +	&movd	(@T[1],&DWP(0,"esp",@i[1],4));
        +	&pxor	($R,$B30);
        +	&psllq	(@T[1],3*$n++);
        +	&pxor	($R,@T[1]);
        +
        +	&movd	(@T[0],&DWP(0,"esp",@i[0],4));
        +	&pxor	($R,$B31);
        +	&psllq	(@T[0],3*$n);
        +	&add	("esp",32+4);
        +	&pxor	($R,@T[0]);
        +	&ret	();
        +&function_end_B("_mul_1x1_mmx");
        +					}
        +
        +($lo,$hi)=("eax","edx");
        +@T=("ecx","ebp");
        +
        +&function_begin_B("_mul_1x1_ialu");
        +	&sub	("esp",32+4);
        +	 &mov	($a1,$a);
        +	 &lea	($a2,&DWP(0,$a,$a));
        +	 &lea	($a4,&DWP(0,"",$a,4));
        +	 &and	($a1,0x3fffffff);
        +	&lea	(@i[1],&DWP(0,$lo,$lo));
        +	&sar	($lo,31);		# broadcast 31st bit
        +	 &mov	(&DWP(0*4,"esp"),0);
        +	 &and	($a2,0x7fffffff);
        +	 &mov	(&DWP(1*4,"esp"),$a1);	# a1
        +	 &xor	($a1,$a2);		# a1^a2
        +	 &mov	(&DWP(2*4,"esp"),$a2);	# a2
        +	 &xor	($a2,$a4);		# a2^a4
        +	 &mov	(&DWP(3*4,"esp"),$a1);	# a1^a2
        +	 &xor	($a1,$a2);		# a1^a4=a1^a2^a2^a4
        +	 &mov	(&DWP(4*4,"esp"),$a4);	# a4
        +	 &xor	($a4,$a2);		# a2=a4^a2^a4
        +	 &mov	(&DWP(5*4,"esp"),$a1);	# a1^a4
        +	 &xor	($a4,$a1);		# a1^a2^a4
        +	&sar	(@i[1],31);		# broardcast 30th bit
        +	&and	($lo,$b);
        +	 &mov	(&DWP(6*4,"esp"),$a2);	# a2^a4
        +	&and	(@i[1],$b);
        +	 &mov	(&DWP(7*4,"esp"),$a4);	# a1^a2^a4
        +	&mov	($hi,$lo);
        +	&shl	($lo,31);
        +	&mov	(@T[0],@i[1]);
        +	&shr	($hi,1);
        +
        +	 &mov	(@i[0],0x7);
        +	&shl	(@i[1],30);
        +	 &and	(@i[0],$b);
        +	&shr	(@T[0],2);
        +	&xor	($lo,@i[1]);
        +
        +	&shr	($b,3);
        +	&mov	(@i[1],0x7);		# 5-byte instruction!?
        +	&and	(@i[1],$b);
        +	&shr	($b,3);
        +	 &xor	($hi,@T[0]);
        +	&xor	($lo,&DWP(0,"esp",@i[0],4));
        +	&mov	(@i[0],0x7);
        +	&and	(@i[0],$b);
        +	&shr	($b,3);
        +	for($n=1;$n<9;$n++) {
        +		&mov	(@T[1],&DWP(0,"esp",@i[1],4));
        +		&mov	(@i[1],0x7);
        +		&mov	(@T[0],@T[1]);
        +		&shl	(@T[1],3*$n);
        +		&and	(@i[1],$b);
        +		&shr	(@T[0],32-3*$n);
        +		&xor	($lo,@T[1]);
        +		&shr	($b,3);
        +		&xor	($hi,@T[0]);
        +
        +		push(@i,shift(@i)); push(@T,shift(@T));
        +	}
        +	&mov	(@T[1],&DWP(0,"esp",@i[1],4));
        +	&mov	(@T[0],@T[1]);
        +	&shl	(@T[1],3*$n);
        +	&mov	(@i[1],&DWP(0,"esp",@i[0],4));
        +	&shr	(@T[0],32-3*$n);	$n++;
        +	&mov	(@i[0],@i[1]);
        +	&xor	($lo,@T[1]);
        +	&shl	(@i[1],3*$n);
        +	&xor	($hi,@T[0]);
        +	&shr	(@i[0],32-3*$n);
        +	&xor	($lo,@i[1]);
        +	&xor	($hi,@i[0]);
        +
        +	&add	("esp",32+4);
        +	&ret	();
        +&function_end_B("_mul_1x1_ialu");
        +
        +# void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0);
        +&function_begin_B("bn_GF2m_mul_2x2");
        +if (!$x86only) {
        +	&picmeup("edx","OPENSSL_ia32cap_P");
        +	&mov	("eax",&DWP(0,"edx"));
        +	&mov	("edx",&DWP(4,"edx"));
        +	&test	("eax",1<<23);		# check MMX bit
        +	&jz	(&label("ialu"));
        +if ($sse2) {
        +	&test	("eax",1<<24);		# check FXSR bit
        +	&jz	(&label("mmx"));
        +	&test	("edx",1<<1);		# check PCLMULQDQ bit
        +	&jz	(&label("mmx"));
        +
        +	&movups		("xmm0",&QWP(8,"esp"));
        +	&shufps		("xmm0","xmm0",0b10110001);
        +	&pclmulqdq	("xmm0","xmm0",1);
        +	&mov		("eax",&DWP(4,"esp"));
        +	&movups		(&QWP(0,"eax"),"xmm0");
        +	&ret	();
        +
        +&set_label("mmx",16);
        +}
        +	&push	("ebp");
        +	&push	("ebx");
        +	&push	("esi");
        +	&push	("edi");
        +	&mov	($a,&wparam(1));
        +	&mov	($b,&wparam(3));
        +	&call	("_mul_1x1_mmx");	# a1·b1
        +	&movq	("mm7",$R);
        +
        +	&mov	($a,&wparam(2));
        +	&mov	($b,&wparam(4));
        +	&call	("_mul_1x1_mmx");	# a0·b0
        +	&movq	("mm6",$R);
        +
        +	&mov	($a,&wparam(1));
        +	&mov	($b,&wparam(3));
        +	&xor	($a,&wparam(2));
        +	&xor	($b,&wparam(4));
        +	&call	("_mul_1x1_mmx");	# (a0+a1)·(b0+b1)
        +	&pxor	($R,"mm7");
        +	&mov	($a,&wparam(0));
        +	&pxor	($R,"mm6");		# (a0+a1)·(b0+b1)-a1·b1-a0·b0
        +
        +	&movq	($A,$R);
        +	&psllq	($R,32);
        +	&pop	("edi");
        +	&psrlq	($A,32);
        +	&pop	("esi");
        +	&pxor	($R,"mm6");
        +	&pop	("ebx");
        +	&pxor	($A,"mm7");
        +	&movq	(&QWP(0,$a),$R);
        +	&pop	("ebp");
        +	&movq	(&QWP(8,$a),$A);
        +	&emms	();
        +	&ret	();
        +&set_label("ialu",16);
        +}
        +	&push	("ebp");
        +	&push	("ebx");
        +	&push	("esi");
        +	&push	("edi");
        +	&stack_push(4+1);
        +
        +	&mov	($a,&wparam(1));
        +	&mov	($b,&wparam(3));
        +	&call	("_mul_1x1_ialu");	# a1·b1
        +	&mov	(&DWP(8,"esp"),$lo);
        +	&mov	(&DWP(12,"esp"),$hi);
        +
        +	&mov	($a,&wparam(2));
        +	&mov	($b,&wparam(4));
        +	&call	("_mul_1x1_ialu");	# a0·b0
        +	&mov	(&DWP(0,"esp"),$lo);
        +	&mov	(&DWP(4,"esp"),$hi);
        +
        +	&mov	($a,&wparam(1));
        +	&mov	($b,&wparam(3));
        +	&xor	($a,&wparam(2));
        +	&xor	($b,&wparam(4));
        +	&call	("_mul_1x1_ialu");	# (a0+a1)·(b0+b1)
        +
        +	&mov	("ebp",&wparam(0));
        +		 @r=("ebx","ecx","edi","esi");
        +	&mov	(@r[0],&DWP(0,"esp"));
        +	&mov	(@r[1],&DWP(4,"esp"));
        +	&mov	(@r[2],&DWP(8,"esp"));
        +	&mov	(@r[3],&DWP(12,"esp"));
        +
        +	&xor	($lo,$hi);
        +	&xor	($hi,@r[1]);
        +	&xor	($lo,@r[0]);
        +	&mov	(&DWP(0,"ebp"),@r[0]);
        +	&xor	($hi,@r[2]);
        +	&mov	(&DWP(12,"ebp"),@r[3]);
        +	&xor	($lo,@r[3]);
        +	&stack_pop(4+1);
        +	&xor	($hi,@r[3]);
        +	&pop	("edi");
        +	&xor	($lo,$hi);
        +	&pop	("esi");
        +	&mov	(&DWP(8,"ebp"),$hi);
        +	&pop	("ebx");
        +	&mov	(&DWP(4,"ebp"),$lo);
        +	&pop	("ebp");
        +	&ret	();
        +&function_end_B("bn_GF2m_mul_2x2");
        +
        +&asciz	("GF(2^m) Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/x86-mont.pl
        new file mode 100644
        index 000000000..e8f6b0508
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86-mont.pl
        @@ -0,0 +1,593 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# October 2005
        +#
        +# This is a "teaser" code, as it can be improved in several ways...
        +# First of all non-SSE2 path should be implemented (yes, for now it
        +# performs Montgomery multiplication/convolution only on SSE2-capable
        +# CPUs such as P4, others fall down to original code). Then inner loop
        +# can be unrolled and modulo-scheduled to improve ILP and possibly
        +# moved to 128-bit XMM register bank (though it would require input
        +# rearrangement and/or increase bus bandwidth utilization). Dedicated
        +# squaring procedure should give further performance improvement...
        +# Yet, for being draft, the code improves rsa512 *sign* benchmark by
        +# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-)
        +
        +# December 2006
        +#
        +# Modulo-scheduling SSE2 loops results in further 15-20% improvement.
        +# Integer-only code [being equipped with dedicated squaring procedure]
        +# gives ~40% on rsa512 sign benchmark...
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0);
        +
        +$sse2=0;
        +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +&external_label("OPENSSL_ia32cap_P") if ($sse2);
        +
        +&function_begin("bn_mul_mont");
        +
        +$i="edx";
        +$j="ecx";
        +$ap="esi";	$tp="esi";		# overlapping variables!!!
        +$rp="edi";	$bp="edi";		# overlapping variables!!!
        +$np="ebp";
        +$num="ebx";
        +
        +$_num=&DWP(4*0,"esp");			# stack top layout
        +$_rp=&DWP(4*1,"esp");
        +$_ap=&DWP(4*2,"esp");
        +$_bp=&DWP(4*3,"esp");
        +$_np=&DWP(4*4,"esp");
        +$_n0=&DWP(4*5,"esp");	$_n0q=&QWP(4*5,"esp");
        +$_sp=&DWP(4*6,"esp");
        +$_bpend=&DWP(4*7,"esp");
        +$frame=32;				# size of above frame rounded up to 16n
        +
        +	&xor	("eax","eax");
        +	&mov	("edi",&wparam(5));	# int num
        +	&cmp	("edi",4);
        +	&jl	(&label("just_leave"));
        +
        +	&lea	("esi",&wparam(0));	# put aside pointer to argument block
        +	&lea	("edx",&wparam(1));	# load ap
        +	&mov	("ebp","esp");		# saved stack pointer!
        +	&add	("edi",2);		# extra two words on top of tp
        +	&neg	("edi");
        +	&lea	("esp",&DWP(-$frame,"esp","edi",4));	# alloca($frame+4*(num+2))
        +	&neg	("edi");
        +
        +	# minimize cache contention by arraning 2K window between stack
        +	# pointer and ap argument [np is also position sensitive vector,
        +	# but it's assumed to be near ap, as it's allocated at ~same
        +	# time].
        +	&mov	("eax","esp");
        +	&sub	("eax","edx");
        +	&and	("eax",2047);
        +	&sub	("esp","eax");		# this aligns sp and ap modulo 2048
        +
        +	&xor	("edx","esp");
        +	&and	("edx",2048);
        +	&xor	("edx",2048);
        +	&sub	("esp","edx");		# this splits them apart modulo 4096
        +
        +	&and	("esp",-64);		# align to cache line
        +
        +	################################# load argument block...
        +	&mov	("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
        +	&mov	("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
        +	&mov	("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
        +	&mov	("edx",&DWP(3*4,"esi"));# const BN_ULONG *np
        +	&mov	("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
        +	#&mov	("edi",&DWP(5*4,"esi"));# int num
        +
        +	&mov	("esi",&DWP(0,"esi"));	# pull n0[0]
        +	&mov	($_rp,"eax");		# ... save a copy of argument block
        +	&mov	($_ap,"ebx");
        +	&mov	($_bp,"ecx");
        +	&mov	($_np,"edx");
        +	&mov	($_n0,"esi");
        +	&lea	($num,&DWP(-3,"edi"));	# num=num-1 to assist modulo-scheduling
        +	#&mov	($_num,$num);		# redundant as $num is not reused
        +	&mov	($_sp,"ebp");		# saved stack pointer!
        +
        +if($sse2) {
        +$acc0="mm0";	# mmx register bank layout
        +$acc1="mm1";
        +$car0="mm2";
        +$car1="mm3";
        +$mul0="mm4";
        +$mul1="mm5";
        +$temp="mm6";
        +$mask="mm7";
        +
        +	&picmeup("eax","OPENSSL_ia32cap_P");
        +	&bt	(&DWP(0,"eax"),26);
        +	&jnc	(&label("non_sse2"));
        +
        +	&mov	("eax",-1);
        +	&movd	($mask,"eax");		# mask 32 lower bits
        +
        +	&mov	($ap,$_ap);		# load input pointers
        +	&mov	($bp,$_bp);
        +	&mov	($np,$_np);
        +
        +	&xor	($i,$i);		# i=0
        +	&xor	($j,$j);		# j=0
        +
        +	&movd	($mul0,&DWP(0,$bp));		# bp[0]
        +	&movd	($mul1,&DWP(0,$ap));		# ap[0]
        +	&movd	($car1,&DWP(0,$np));		# np[0]
        +
        +	&pmuludq($mul1,$mul0);			# ap[0]*bp[0]
        +	&movq	($car0,$mul1);
        +	&movq	($acc0,$mul1);			# I wish movd worked for
        +	&pand	($acc0,$mask);			# inter-register transfers
        +
        +	&pmuludq($mul1,$_n0q);			# *=n0
        +
        +	&pmuludq($car1,$mul1);			# "t[0]"*np[0]*n0
        +	&paddq	($car1,$acc0);
        +
        +	&movd	($acc1,&DWP(4,$np));		# np[1]
        +	&movd	($acc0,&DWP(4,$ap));		# ap[1]
        +
        +	&psrlq	($car0,32);
        +	&psrlq	($car1,32);
        +
        +	&inc	($j);				# j++
        +&set_label("1st",16);
        +	&pmuludq($acc0,$mul0);			# ap[j]*bp[0]
        +	&pmuludq($acc1,$mul1);			# np[j]*m1
        +	&paddq	($car0,$acc0);			# +=c0
        +	&paddq	($car1,$acc1);			# +=c1
        +
        +	&movq	($acc0,$car0);
        +	&pand	($acc0,$mask);
        +	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
        +	&paddq	($car1,$acc0);			# +=ap[j]*bp[0];
        +	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
        +	&psrlq	($car0,32);
        +	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[j-1]=
        +	&psrlq	($car1,32);
        +
        +	&lea	($j,&DWP(1,$j));
        +	&cmp	($j,$num);
        +	&jl	(&label("1st"));
        +
        +	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[0]
        +	&pmuludq($acc1,$mul1);			# np[num-1]*m1
        +	&paddq	($car0,$acc0);			# +=c0
        +	&paddq	($car1,$acc1);			# +=c1
        +
        +	&movq	($acc0,$car0);
        +	&pand	($acc0,$mask);
        +	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[0];
        +	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
        +
        +	&psrlq	($car0,32);
        +	&psrlq	($car1,32);
        +
        +	&paddq	($car1,$car0);
        +	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
        +
        +	&inc	($i);				# i++
        +&set_label("outer");
        +	&xor	($j,$j);			# j=0
        +
        +	&movd	($mul0,&DWP(0,$bp,$i,4));	# bp[i]
        +	&movd	($mul1,&DWP(0,$ap));		# ap[0]
        +	&movd	($temp,&DWP($frame,"esp"));	# tp[0]
        +	&movd	($car1,&DWP(0,$np));		# np[0]
        +	&pmuludq($mul1,$mul0);			# ap[0]*bp[i]
        +
        +	&paddq	($mul1,$temp);			# +=tp[0]
        +	&movq	($acc0,$mul1);
        +	&movq	($car0,$mul1);
        +	&pand	($acc0,$mask);
        +
        +	&pmuludq($mul1,$_n0q);			# *=n0
        +
        +	&pmuludq($car1,$mul1);
        +	&paddq	($car1,$acc0);
        +
        +	&movd	($temp,&DWP($frame+4,"esp"));	# tp[1]
        +	&movd	($acc1,&DWP(4,$np));		# np[1]
        +	&movd	($acc0,&DWP(4,$ap));		# ap[1]
        +
        +	&psrlq	($car0,32);
        +	&psrlq	($car1,32);
        +	&paddq	($car0,$temp);			# +=tp[1]
        +
        +	&inc	($j);				# j++
        +	&dec	($num);
        +&set_label("inner");
        +	&pmuludq($acc0,$mul0);			# ap[j]*bp[i]
        +	&pmuludq($acc1,$mul1);			# np[j]*m1
        +	&paddq	($car0,$acc0);			# +=c0
        +	&paddq	($car1,$acc1);			# +=c1
        +
        +	&movq	($acc0,$car0);
        +	&movd	($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1]
        +	&pand	($acc0,$mask);
        +	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
        +	&paddq	($car1,$acc0);			# +=ap[j]*bp[i]+tp[j]
        +	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
        +	&psrlq	($car0,32);
        +	&movd	(&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]=
        +	&psrlq	($car1,32);
        +	&paddq	($car0,$temp);			# +=tp[j+1]
        +
        +	&dec	($num);
        +	&lea	($j,&DWP(1,$j));		# j++
        +	&jnz	(&label("inner"));
        +
        +	&mov	($num,$j);
        +	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[i]
        +	&pmuludq($acc1,$mul1);			# np[num-1]*m1
        +	&paddq	($car0,$acc0);			# +=c0
        +	&paddq	($car1,$acc1);			# +=c1
        +
        +	&movq	($acc0,$car0);
        +	&pand	($acc0,$mask);
        +	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[i]+tp[num-1]
        +	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
        +	&psrlq	($car0,32);
        +	&psrlq	($car1,32);
        +
        +	&movd	($temp,&DWP($frame+4,"esp",$num,4));	# += tp[num]
        +	&paddq	($car1,$car0);
        +	&paddq	($car1,$temp);
        +	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
        +
        +	&lea	($i,&DWP(1,$i));		# i++
        +	&cmp	($i,$num);
        +	&jle	(&label("outer"));
        +
        +	&emms	();				# done with mmx bank
        +	&jmp	(&label("common_tail"));
        +
        +&set_label("non_sse2",16);
        +}
        +
        +if (0) {
        +	&mov	("esp",$_sp);
        +	&xor	("eax","eax");	# signal "not fast enough [yet]"
        +	&jmp	(&label("just_leave"));
        +	# While the below code provides competitive performance for
        +	# all key lengthes on modern Intel cores, it's still more
        +	# than 10% slower for 4096-bit key elsewhere:-( "Competitive"
        +	# means compared to the original integer-only assembler.
        +	# 512-bit RSA sign is better by ~40%, but that's about all
        +	# one can say about all CPUs...
        +} else {
        +$inp="esi";	# integer path uses these registers differently
        +$word="edi";
        +$carry="ebp";
        +
        +	&mov	($inp,$_ap);
        +	&lea	($carry,&DWP(1,$num));
        +	&mov	($word,$_bp);
        +	&xor	($j,$j);				# j=0
        +	&mov	("edx",$inp);
        +	&and	($carry,1);				# see if num is even
        +	&sub	("edx",$word);				# see if ap==bp
        +	&lea	("eax",&DWP(4,$word,$num,4));		# &bp[num]
        +	&or	($carry,"edx");
        +	&mov	($word,&DWP(0,$word));			# bp[0]
        +	&jz	(&label("bn_sqr_mont"));
        +	&mov	($_bpend,"eax");
        +	&mov	("eax",&DWP(0,$inp));
        +	&xor	("edx","edx");
        +
        +&set_label("mull",16);
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[j]*bp[0]
        +	&add	($carry,"eax");
        +	&lea	($j,&DWP(1,$j));
        +	&adc	("edx",0);
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
        +	&cmp	($j,$num);
        +	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
        +	&jl	(&label("mull"));
        +
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[num-1]*bp[0]
        +	 &mov	($word,$_n0);
        +	&add	("eax",$carry);
        +	 &mov	($inp,$_np);
        +	&adc	("edx",0);
        +	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
        +
        +	&mov	(&DWP($frame,"esp",$num,4),"eax");	# tp[num-1]=
        +	&xor	($j,$j);
        +	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
        +	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
        +
        +	&mov	("eax",&DWP(0,$inp));			# np[0]
        +	&mul	($word);				# np[0]*m
        +	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
        +	&mov	("eax",&DWP(4,$inp));			# np[1]
        +	&adc	("edx",0);
        +	&inc	($j);
        +
        +	&jmp	(&label("2ndmadd"));
        +
        +&set_label("1stmadd",16);
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[j]*bp[i]
        +	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
        +	&lea	($j,&DWP(1,$j));
        +	&adc	("edx",0);
        +	&add	($carry,"eax");
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
        +	&adc	("edx",0);
        +	&cmp	($j,$num);
        +	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
        +	&jl	(&label("1stmadd"));
        +
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[num-1]*bp[i]
        +	&add	("eax",&DWP($frame,"esp",$num,4));	# +=tp[num-1]
        +	 &mov	($word,$_n0);
        +	&adc	("edx",0);
        +	 &mov	($inp,$_np);
        +	&add	($carry,"eax");
        +	&adc	("edx",0);
        +	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
        +
        +	&xor	($j,$j);
        +	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
        +	&mov	(&DWP($frame,"esp",$num,4),$carry);	# tp[num-1]=
        +	&adc	($j,0);
        +	 &mov	("eax",&DWP(0,$inp));			# np[0]
        +	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
        +	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
        +
        +	&mul	($word);				# np[0]*m
        +	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
        +	&mov	("eax",&DWP(4,$inp));			# np[1]
        +	&adc	("edx",0);
        +	&mov	($j,1);
        +
        +&set_label("2ndmadd",16);
        +	&mov	($carry,"edx");
        +	&mul	($word);				# np[j]*m
        +	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
        +	&lea	($j,&DWP(1,$j));
        +	&adc	("edx",0);
        +	&add	($carry,"eax");
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+1]
        +	&adc	("edx",0);
        +	&cmp	($j,$num);
        +	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j-1]=
        +	&jl	(&label("2ndmadd"));
        +
        +	&mov	($carry,"edx");
        +	&mul	($word);				# np[j]*m
        +	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
        +	&adc	("edx",0);
        +	&add	($carry,"eax");
        +	&adc	("edx",0);
        +	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
        +
        +	&xor	("eax","eax");
        +	 &mov	($j,$_bp);				# &bp[i]
        +	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
        +	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
        +	 &lea	($j,&DWP(4,$j));
        +	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
        +	 &cmp	($j,$_bpend);
        +	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
        +	&je	(&label("common_tail"));
        +
        +	&mov	($word,&DWP(0,$j));			# bp[i+1]
        +	&mov	($inp,$_ap);
        +	&mov	($_bp,$j);				# &bp[++i]
        +	&xor	($j,$j);
        +	&xor	("edx","edx");
        +	&mov	("eax",&DWP(0,$inp));
        +	&jmp	(&label("1stmadd"));
        +
        +&set_label("bn_sqr_mont",16);
        +$sbit=$num;
        +	&mov	($_num,$num);
        +	&mov	($_bp,$j);				# i=0
        +
        +	&mov	("eax",$word);				# ap[0]
        +	&mul	($word);				# ap[0]*ap[0]
        +	&mov	(&DWP($frame,"esp"),"eax");		# tp[0]=
        +	&mov	($sbit,"edx");
        +	&shr	("edx",1);
        +	&and	($sbit,1);
        +	&inc	($j);
        +&set_label("sqr",16);
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[j]*ap[0]
        +	&add	("eax",$carry);
        +	&lea	($j,&DWP(1,$j));
        +	&adc	("edx",0);
        +	&lea	($carry,&DWP(0,$sbit,"eax",2));
        +	&shr	("eax",31);
        +	&cmp	($j,$_num);
        +	&mov	($sbit,"eax");
        +	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
        +	&jl	(&label("sqr"));
        +
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[num-1]
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[num-1]*ap[0]
        +	&add	("eax",$carry);
        +	 &mov	($word,$_n0);
        +	&adc	("edx",0);
        +	 &mov	($inp,$_np);
        +	&lea	($carry,&DWP(0,$sbit,"eax",2));
        +	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
        +	&shr	("eax",31);
        +	&mov	(&DWP($frame,"esp",$j,4),$carry);	# tp[num-1]=
        +
        +	&lea	($carry,&DWP(0,"eax","edx",2));
        +	 &mov	("eax",&DWP(0,$inp));			# np[0]
        +	&shr	("edx",31);
        +	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num]=
        +	&mov	(&DWP($frame+8,"esp",$j,4),"edx");	# tp[num+1]=
        +
        +	&mul	($word);				# np[0]*m
        +	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
        +	&mov	($num,$j);
        +	&adc	("edx",0);
        +	&mov	("eax",&DWP(4,$inp));			# np[1]
        +	&mov	($j,1);
        +
        +&set_label("3rdmadd",16);
        +	&mov	($carry,"edx");
        +	&mul	($word);				# np[j]*m
        +	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
        +	&adc	("edx",0);
        +	&add	($carry,"eax");
        +	&mov	("eax",&DWP(4,$inp,$j,4));		# np[j+1]
        +	&adc	("edx",0);
        +	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j-1]=
        +
        +	&mov	($carry,"edx");
        +	&mul	($word);				# np[j+1]*m
        +	&add	($carry,&DWP($frame+4,"esp",$j,4));	# +=tp[j+1]
        +	&lea	($j,&DWP(2,$j));
        +	&adc	("edx",0);
        +	&add	($carry,"eax");
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+2]
        +	&adc	("edx",0);
        +	&cmp	($j,$num);
        +	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j]=
        +	&jl	(&label("3rdmadd"));
        +
        +	&mov	($carry,"edx");
        +	&mul	($word);				# np[j]*m
        +	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
        +	&adc	("edx",0);
        +	&add	($carry,"eax");
        +	&adc	("edx",0);
        +	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
        +
        +	&mov	($j,$_bp);				# i
        +	&xor	("eax","eax");
        +	&mov	($inp,$_ap);
        +	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
        +	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
        +	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
        +	&cmp	($j,$num);
        +	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
        +	&je	(&label("common_tail"));
        +
        +	&mov	($word,&DWP(4,$inp,$j,4));		# ap[i]
        +	&lea	($j,&DWP(1,$j));
        +	&mov	("eax",$word);
        +	&mov	($_bp,$j);				# ++i
        +	&mul	($word);				# ap[i]*ap[i]
        +	&add	("eax",&DWP($frame,"esp",$j,4));	# +=tp[i]
        +	&adc	("edx",0);
        +	&mov	(&DWP($frame,"esp",$j,4),"eax");	# tp[i]=
        +	&xor	($carry,$carry);
        +	&cmp	($j,$num);
        +	&lea	($j,&DWP(1,$j));
        +	&je	(&label("sqrlast"));
        +
        +	&mov	($sbit,"edx");				# zaps $num
        +	&shr	("edx",1);
        +	&and	($sbit,1);
        +&set_label("sqradd",16);
        +	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
        +	&mov	($carry,"edx");
        +	&mul	($word);				# ap[j]*ap[i]
        +	&add	("eax",$carry);
        +	&lea	($carry,&DWP(0,"eax","eax"));
        +	&adc	("edx",0);
        +	&shr	("eax",31);
        +	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
        +	&lea	($j,&DWP(1,$j));
        +	&adc	("eax",0);
        +	&add	($carry,$sbit);
        +	&adc	("eax",0);
        +	&cmp	($j,$_num);
        +	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
        +	&mov	($sbit,"eax");
        +	&jle	(&label("sqradd"));
        +
        +	&mov	($carry,"edx");
        +	&add	("edx","edx");
        +	&shr	($carry,31);
        +	&add	("edx",$sbit);
        +	&adc	($carry,0);
        +&set_label("sqrlast");
        +	&mov	($word,$_n0);
        +	&mov	($inp,$_np);
        +	&imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
        +
        +	&add	("edx",&DWP($frame,"esp",$j,4));	# +=tp[num]
        +	&mov	("eax",&DWP(0,$inp));			# np[0]
        +	&adc	($carry,0);
        +	&mov	(&DWP($frame,"esp",$j,4),"edx");	# tp[num]=
        +	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num+1]=
        +
        +	&mul	($word);				# np[0]*m
        +	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
        +	&lea	($num,&DWP(-1,$j));
        +	&adc	("edx",0);
        +	&mov	($j,1);
        +	&mov	("eax",&DWP(4,$inp));			# np[1]
        +
        +	&jmp	(&label("3rdmadd"));
        +}
        +
        +&set_label("common_tail",16);
        +	&mov	($np,$_np);			# load modulus pointer
        +	&mov	($rp,$_rp);			# load result pointer
        +	&lea	($tp,&DWP($frame,"esp"));	# [$ap and $bp are zapped]
        +
        +	&mov	("eax",&DWP(0,$tp));		# tp[0]
        +	&mov	($j,$num);			# j=num-1
        +	&xor	($i,$i);			# i=0 and clear CF!
        +
        +&set_label("sub",16);
        +	&sbb	("eax",&DWP(0,$np,$i,4));
        +	&mov	(&DWP(0,$rp,$i,4),"eax");	# rp[i]=tp[i]-np[i]
        +	&dec	($j);				# doesn't affect CF!
        +	&mov	("eax",&DWP(4,$tp,$i,4));	# tp[i+1]
        +	&lea	($i,&DWP(1,$i));		# i++
        +	&jge	(&label("sub"));
        +
        +	&sbb	("eax",0);			# handle upmost overflow bit
        +	&and	($tp,"eax");
        +	&not	("eax");
        +	&mov	($np,$rp);
        +	&and	($np,"eax");
        +	&or	($tp,$np);			# tp=carry?tp:rp
        +
        +&set_label("copy",16);				# copy or in-place refresh
        +	&mov	("eax",&DWP(0,$tp,$num,4));
        +	&mov	(&DWP(0,$rp,$num,4),"eax");	# rp[i]=tp[i]
        +	&mov	(&DWP($frame,"esp",$num,4),$j);	# zap temporary vector
        +	&dec	($num);
        +	&jge	(&label("copy"));
        +
        +	&mov	("esp",$_sp);		# pull saved stack pointer
        +	&mov	("eax",1);
        +&set_label("just_leave");
        +&function_end("bn_mul_mont");
        +
        +&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86.pl b/vendor/openssl/openssl/crypto/bn/asm/x86.pl
        new file mode 100644
        index 000000000..1bc4f1bb2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86.pl
        @@ -0,0 +1,28 @@
        +#!/usr/local/bin/perl
        +
        +push(@INC,"perlasm","../../perlasm");
        +require "x86asm.pl";
        +
        +require("x86/mul_add.pl");
        +require("x86/mul.pl");
        +require("x86/sqr.pl");
        +require("x86/div.pl");
        +require("x86/add.pl");
        +require("x86/sub.pl");
        +require("x86/comba.pl");
        +
        +&asm_init($ARGV[0],$0);
        +
        +&bn_mul_add_words("bn_mul_add_words");
        +&bn_mul_words("bn_mul_words");
        +&bn_sqr_words("bn_sqr_words");
        +&bn_div_words("bn_div_words");
        +&bn_add_words("bn_add_words");
        +&bn_sub_words("bn_sub_words");
        +&bn_mul_comba("bn_mul_comba8",8);
        +&bn_mul_comba("bn_mul_comba4",4);
        +&bn_sqr_comba("bn_sqr_comba8",8);
        +&bn_sqr_comba("bn_sqr_comba4",4);
        +
        +&asm_finish();
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/add.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/add.pl
        new file mode 100644
        index 000000000..0b5cf583e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/add.pl
        @@ -0,0 +1,76 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub bn_add_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$a="esi";
        +	$b="edi";
        +	$c="eax";
        +	$r="ebx";
        +	$tmp1="ecx";
        +	$tmp2="edx";
        +	$num="ebp";
        +
        +	&mov($r,&wparam(0));	# get r
        +	 &mov($a,&wparam(1));	# get a
        +	&mov($b,&wparam(2));	# get b
        +	 &mov($num,&wparam(3));	# get num
        +	&xor($c,$c);		# clear carry
        +	 &and($num,0xfffffff8);	# num / 8
        +
        +	&jz(&label("aw_finish"));
        +
        +	&set_label("aw_loop",0);
        +	for ($i=0; $i<8; $i++)
        +		{
        +		&comment("Round $i");
        +
        +		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
        +		&add($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &add($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	 &add($b,32);
        +	&add($r,32);
        +	 &sub($num,8);
        +	&jnz(&label("aw_loop"));
        +
        +	&set_label("aw_finish",0);
        +	&mov($num,&wparam(3));	# get num
        +	&and($num,7);
        +	 &jz(&label("aw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
        +		&add($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &add($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &dec($num) if ($i != 6);
        +		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *a
        +		 &jz(&label("aw_end")) if ($i != 6);
        +		}
        +	&set_label("aw_end",0);
        +
        +#	&mov("eax",$c);		# $c is "eax"
        +
        +	&function_end($name);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/comba.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/comba.pl
        new file mode 100644
        index 000000000..229125362
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/comba.pl
        @@ -0,0 +1,277 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub mul_add_c
        +	{
        +	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
        +
        +	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
        +	# words, and 1 if load return value
        +
        +	&comment("mul a[$ai]*b[$bi]");
        +
        +	# "eax" and "edx" will always be pre-loaded.
        +	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
        +	# &mov("edx",&DWP($bi*4,$b,"",0));
        +
        +	&mul("edx");
        +	&add($c0,"eax");
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
        +	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
        +	 ###
        +	&adc($c1,"edx");
        +	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
        +	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
        +	 ###
        +	&adc($c2,0);
        +	 # is pos > 1, it means it is the last loop 
        +	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
        +	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
        +	}
        +
        +sub sqr_add_c
        +	{
        +	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
        +
        +	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
        +	# words, and 1 if load return value
        +
        +	&comment("sqr a[$ai]*a[$bi]");
        +
        +	# "eax" and "edx" will always be pre-loaded.
        +	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
        +	# &mov("edx",&DWP($bi*4,$b,"",0));
        +
        +	if ($ai == $bi)
        +		{ &mul("eax");}
        +	else
        +		{ &mul("edx");}
        +	&add($c0,"eax");
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
        +	 ###
        +	&adc($c1,"edx");
        +	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
        +	 ###
        +	&adc($c2,0);
        +	 # is pos > 1, it means it is the last loop 
        +	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
        +	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
        +	}
        +
        +sub sqr_add_c2
        +	{
        +	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
        +
        +	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
        +	# words, and 1 if load return value
        +
        +	&comment("sqr a[$ai]*a[$bi]");
        +
        +	# "eax" and "edx" will always be pre-loaded.
        +	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
        +	# &mov("edx",&DWP($bi*4,$a,"",0));
        +
        +	if ($ai == $bi)
        +		{ &mul("eax");}
        +	else
        +		{ &mul("edx");}
        +	&add("eax","eax");
        +	 ###
        +	&adc("edx","edx");
        +	 ###
        +	&adc($c2,0);
        +	 &add($c0,"eax");
        +	&adc($c1,"edx");
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
        +	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
        +	&adc($c2,0);
        +	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
        +	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
        +	 ###
        +	}
        +
        +sub bn_mul_comba
        +	{
        +	local($name,$num)=@_;
        +	local($a,$b,$c0,$c1,$c2);
        +	local($i,$as,$ae,$bs,$be,$ai,$bi);
        +	local($tot,$end);
        +
        +	&function_begin_B($name,"");
        +
        +	$c0="ebx";
        +	$c1="ecx";
        +	$c2="ebp";
        +	$a="esi";
        +	$b="edi";
        +	
        +	$as=0;
        +	$ae=0;
        +	$bs=0;
        +	$be=0;
        +	$tot=$num+$num-1;
        +
        +	&push("esi");
        +	 &mov($a,&wparam(1));
        +	&push("edi");
        +	 &mov($b,&wparam(2));
        +	&push("ebp");
        +	 &push("ebx");
        +
        +	&xor($c0,$c0);
        +	 &mov("eax",&DWP(0,$a,"",0));	# load the first word 
        +	&xor($c1,$c1);
        +	 &mov("edx",&DWP(0,$b,"",0));	# load the first second 
        +
        +	for ($i=0; $i<$tot; $i++)
        +		{
        +		$ai=$as;
        +		$bi=$bs;
        +		$end=$be+1;
        +
        +		&comment("################## Calculate word $i"); 
        +
        +		for ($j=$bs; $j<$end; $j++)
        +			{
        +			&xor($c2,$c2) if ($j == $bs);
        +			if (($j+1) == $end)
        +				{
        +				$v=1;
        +				$v=2 if (($i+1) == $tot);
        +				}
        +			else
        +				{ $v=0; }
        +			if (($j+1) != $end)
        +				{
        +				$na=($ai-1);
        +				$nb=($bi+1);
        +				}
        +			else
        +				{
        +				$na=$as+($i < ($num-1));
        +				$nb=$bs+($i >= ($num-1));
        +				}
        +#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
        +			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
        +			if ($v)
        +				{
        +				&comment("saved r[$i]");
        +				# &mov("eax",&wparam(0));
        +				# &mov(&DWP($i*4,"eax","",0),$c0);
        +				($c0,$c1,$c2)=($c1,$c2,$c0);
        +				}
        +			$ai--;
        +			$bi++;
        +			}
        +		$as++ if ($i < ($num-1));
        +		$ae++ if ($i >= ($num-1));
        +
        +		$bs++ if ($i >= ($num-1));
        +		$be++ if ($i < ($num-1));
        +		}
        +	&comment("save r[$i]");
        +	# &mov("eax",&wparam(0));
        +	&mov(&DWP($i*4,"eax","",0),$c0);
        +
        +	&pop("ebx");
        +	&pop("ebp");
        +	&pop("edi");
        +	&pop("esi");
        +	&ret();
        +	&function_end_B($name);
        +	}
        +
        +sub bn_sqr_comba
        +	{
        +	local($name,$num)=@_;
        +	local($r,$a,$c0,$c1,$c2)=@_;
        +	local($i,$as,$ae,$bs,$be,$ai,$bi);
        +	local($b,$tot,$end,$half);
        +
        +	&function_begin_B($name,"");
        +
        +	$c0="ebx";
        +	$c1="ecx";
        +	$c2="ebp";
        +	$a="esi";
        +	$r="edi";
        +
        +	&push("esi");
        +	 &push("edi");
        +	&push("ebp");
        +	 &push("ebx");
        +	&mov($r,&wparam(0));
        +	 &mov($a,&wparam(1));
        +	&xor($c0,$c0);
        +	 &xor($c1,$c1);
        +	&mov("eax",&DWP(0,$a,"",0)); # load the first word
        +
        +	$as=0;
        +	$ae=0;
        +	$bs=0;
        +	$be=0;
        +	$tot=$num+$num-1;
        +
        +	for ($i=0; $i<$tot; $i++)
        +		{
        +		$ai=$as;
        +		$bi=$bs;
        +		$end=$be+1;
        +
        +		&comment("############### Calculate word $i");
        +		for ($j=$bs; $j<$end; $j++)
        +			{
        +			&xor($c2,$c2) if ($j == $bs);
        +			if (($ai-1) < ($bi+1))
        +				{
        +				$v=1;
        +				$v=2 if ($i+1) == $tot;
        +				}
        +			else
        +				{ $v=0; }
        +			if (!$v)
        +				{
        +				$na=$ai-1;
        +				$nb=$bi+1;
        +				}
        +			else
        +				{
        +				$na=$as+($i < ($num-1));
        +				$nb=$bs+($i >= ($num-1));
        +				}
        +			if ($ai == $bi)
        +				{
        +				&sqr_add_c($r,$a,$ai,$bi,
        +					$c0,$c1,$c2,$v,$i,$na,$nb);
        +				}
        +			else
        +				{
        +				&sqr_add_c2($r,$a,$ai,$bi,
        +					$c0,$c1,$c2,$v,$i,$na,$nb);
        +				}
        +			if ($v)
        +				{
        +				&comment("saved r[$i]");
        +				#&mov(&DWP($i*4,$r,"",0),$c0);
        +				($c0,$c1,$c2)=($c1,$c2,$c0);
        +				last;
        +				}
        +			$ai--;
        +			$bi++;
        +			}
        +		$as++ if ($i < ($num-1));
        +		$ae++ if ($i >= ($num-1));
        +
        +		$bs++ if ($i >= ($num-1));
        +		$be++ if ($i < ($num-1));
        +		}
        +	&mov(&DWP($i*4,$r,"",0),$c0);
        +	&pop("ebx");
        +	&pop("ebp");
        +	&pop("edi");
        +	&pop("esi");
        +	&ret();
        +	&function_end_B($name);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/div.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/div.pl
        new file mode 100644
        index 000000000..0e90152ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/div.pl
        @@ -0,0 +1,15 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub bn_div_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +	&mov("edx",&wparam(0));	#
        +	&mov("eax",&wparam(1));	#
        +	&mov("ebx",&wparam(2));	#
        +	&div("ebx");
        +	&function_end($name);
        +	}
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/f b/vendor/openssl/openssl/crypto/bn/asm/x86/f
        new file mode 100644
        index 000000000..22e411222
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/f
        @@ -0,0 +1,3 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/mul.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/mul.pl
        new file mode 100644
        index 000000000..674cb9b05
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/mul.pl
        @@ -0,0 +1,77 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub bn_mul_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$Low="eax";
        +	$High="edx";
        +	$a="ebx";
        +	$w="ecx";
        +	$r="edi";
        +	$c="esi";
        +	$num="ebp";
        +
        +	&xor($c,$c);		# clear carry
        +	&mov($r,&wparam(0));	#
        +	&mov($a,&wparam(1));	#
        +	&mov($num,&wparam(2));	#
        +	&mov($w,&wparam(3));	#
        +
        +	&and($num,0xfffffff8);	# num / 8
        +	&jz(&label("mw_finish"));
        +
        +	&set_label("mw_loop",0);
        +	for ($i=0; $i<32; $i+=4)
        +		{
        +		&comment("Round $i");
        +
        +		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+=c
        +		 # XXX
        +
        +		&adc("edx",0);			# H(t)+=carry
        +		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
        +
        +		&mov($c,"edx");			# c=  H(t);
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	&add($r,32);
        +	&sub($num,8);
        +	&jz(&label("mw_finish"));
        +	&jmp(&label("mw_loop"));
        +
        +	&set_label("mw_finish",0);
        +	&mov($num,&wparam(2));	# get num
        +	&and($num,7);
        +	&jnz(&label("mw_finish2"));
        +	&jmp(&label("mw_end"));
        +
        +	&set_label("mw_finish2",1);
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		 &mov("eax",&DWP($i*4,$a,"",0));# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+=c
        +		 # XXX
        +		&adc("edx",0);			# H(t)+=carry
        +		 &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
        +		&mov($c,"edx");			# c=  H(t);
        +		 &dec($num) if ($i != 7-1);
        +		&jz(&label("mw_end")) if ($i != 7-1);
        +		}
        +	&set_label("mw_end",0);
        +	&mov("eax",$c);
        +
        +	&function_end($name);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/mul_add.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/mul_add.pl
        new file mode 100644
        index 000000000..61830d3a9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/mul_add.pl
        @@ -0,0 +1,87 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub bn_mul_add_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$Low="eax";
        +	$High="edx";
        +	$a="ebx";
        +	$w="ebp";
        +	$r="edi";
        +	$c="esi";
        +
        +	&xor($c,$c);		# clear carry
        +	&mov($r,&wparam(0));	#
        +
        +	&mov("ecx",&wparam(2));	#
        +	&mov($a,&wparam(1));	#
        +
        +	&and("ecx",0xfffffff8);	# num / 8
        +	&mov($w,&wparam(3));	#
        +
        +	&push("ecx");		# Up the stack for a tmp variable
        +
        +	&jz(&label("maw_finish"));
        +
        +	&set_label("maw_loop",0);
        +
        +	&mov(&swtmp(0),"ecx");	#
        +
        +	for ($i=0; $i<32; $i+=4)
        +		{
        +		&comment("Round $i");
        +
        +		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);		# L(t)+= *r
        +		 &mov($c,&DWP($i,$r,"",0));	# L(t)+= *r
        +		&adc("edx",0);			# H(t)+=carry
        +		 &add("eax",$c);		# L(t)+=c
        +		&adc("edx",0);			# H(t)+=carry
        +		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
        +		&mov($c,"edx");			# c=  H(t);
        +		}
        +
        +	&comment("");
        +	&mov("ecx",&swtmp(0));	#
        +	&add($a,32);
        +	&add($r,32);
        +	&sub("ecx",8);
        +	&jnz(&label("maw_loop"));
        +
        +	&set_label("maw_finish",0);
        +	&mov("ecx",&wparam(2));	# get num
        +	&and("ecx",7);
        +	&jnz(&label("maw_finish2"));	# helps branch prediction
        +	&jmp(&label("maw_end"));
        +
        +	&set_label("maw_finish2",1);
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		 &mov("eax",&DWP($i*4,$a,"",0));# *a
        +		&mul($w);			# *a * w
        +		&add("eax",$c);			# L(t)+=c
        +		 &mov($c,&DWP($i*4,$r,"",0));	# L(t)+= *r
        +		&adc("edx",0);			# H(t)+=carry
        +		 &add("eax",$c);
        +		&adc("edx",0);			# H(t)+=carry
        +		 &dec("ecx") if ($i != 7-1);
        +		&mov(&DWP($i*4,$r,"",0),"eax");	# *r= L(t);
        +		 &mov($c,"edx");			# c=  H(t);
        +		&jz(&label("maw_end")) if ($i != 7-1);
        +		}
        +	&set_label("maw_end",0);
        +	&mov("eax",$c);
        +
        +	&pop("ecx");	# clear variable from
        +
        +	&function_end($name);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/sqr.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/sqr.pl
        new file mode 100644
        index 000000000..1f90993cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/sqr.pl
        @@ -0,0 +1,60 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub bn_sqr_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$r="esi";
        +	$a="edi";
        +	$num="ebx";
        +
        +	&mov($r,&wparam(0));	#
        +	&mov($a,&wparam(1));	#
        +	&mov($num,&wparam(2));	#
        +
        +	&and($num,0xfffffff8);	# num / 8
        +	&jz(&label("sw_finish"));
        +
        +	&set_label("sw_loop",0);
        +	for ($i=0; $i<32; $i+=4)
        +		{
        +		&comment("Round $i");
        +		&mov("eax",&DWP($i,$a,"",0)); 	# *a
        +		 # XXX
        +		&mul("eax");			# *a * *a
        +		&mov(&DWP($i*2,$r,"",0),"eax");	#
        +		 &mov(&DWP($i*2+4,$r,"",0),"edx");#
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	&add($r,64);
        +	&sub($num,8);
        +	&jnz(&label("sw_loop"));
        +
        +	&set_label("sw_finish",0);
        +	&mov($num,&wparam(2));	# get num
        +	&and($num,7);
        +	&jz(&label("sw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov("eax",&DWP($i*4,$a,"",0));	# *a
        +		 # XXX
        +		&mul("eax");			# *a * *a
        +		&mov(&DWP($i*8,$r,"",0),"eax");	#
        +		 &dec($num) if ($i != 7-1);
        +		&mov(&DWP($i*8+4,$r,"",0),"edx");
        +		 &jz(&label("sw_end")) if ($i != 7-1);
        +		}
        +	&set_label("sw_end",0);
        +
        +	&function_end($name);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86/sub.pl b/vendor/openssl/openssl/crypto/bn/asm/x86/sub.pl
        new file mode 100644
        index 000000000..837b0e1b0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86/sub.pl
        @@ -0,0 +1,76 @@
        +#!/usr/local/bin/perl
        +# x86 assember
        +
        +sub bn_sub_words
        +	{
        +	local($name)=@_;
        +
        +	&function_begin($name,"");
        +
        +	&comment("");
        +	$a="esi";
        +	$b="edi";
        +	$c="eax";
        +	$r="ebx";
        +	$tmp1="ecx";
        +	$tmp2="edx";
        +	$num="ebp";
        +
        +	&mov($r,&wparam(0));	# get r
        +	 &mov($a,&wparam(1));	# get a
        +	&mov($b,&wparam(2));	# get b
        +	 &mov($num,&wparam(3));	# get num
        +	&xor($c,$c);		# clear carry
        +	 &and($num,0xfffffff8);	# num / 8
        +
        +	&jz(&label("aw_finish"));
        +
        +	&set_label("aw_loop",0);
        +	for ($i=0; $i<8; $i++)
        +		{
        +		&comment("Round $i");
        +
        +		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
        +		&sub($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &sub($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
        +		}
        +
        +	&comment("");
        +	&add($a,32);
        +	 &add($b,32);
        +	&add($r,32);
        +	 &sub($num,8);
        +	&jnz(&label("aw_loop"));
        +
        +	&set_label("aw_finish",0);
        +	&mov($num,&wparam(3));	# get num
        +	&and($num,7);
        +	 &jz(&label("aw_end"));
        +
        +	for ($i=0; $i<7; $i++)
        +		{
        +		&comment("Tail Round $i");
        +		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
        +		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
        +		&sub($tmp1,$c);
        +		 &mov($c,0);
        +		&adc($c,$c);
        +		 &sub($tmp1,$tmp2);
        +		&adc($c,0);
        +		 &dec($num) if ($i != 6);
        +		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *a
        +		 &jz(&label("aw_end")) if ($i != 6);
        +		}
        +	&set_label("aw_end",0);
        +
        +#	&mov("eax",$c);		# $c is "eax"
        +
        +	&function_end($name);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86_64-gcc.c b/vendor/openssl/openssl/crypto/bn/asm/x86_64-gcc.c
        new file mode 100644
        index 000000000..acb0b4011
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86_64-gcc.c
        @@ -0,0 +1,606 @@
        +#include "../bn_lcl.h"
        +#if !(defined(__GNUC__) && __GNUC__>=2)
        +# include "../bn_asm.c"	/* kind of dirty hack for Sun Studio */
        +#else
        +/*
        + * x86_64 BIGNUM accelerator version 0.1, December 2002.
        + *
        + * Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        + * project.
        + *
        + * Rights for redistribution and usage in source and binary forms are
        + * granted according to the OpenSSL license. Warranty of any kind is
        + * disclaimed.
        + *
        + * Q. Version 0.1? It doesn't sound like Andy, he used to assign real
        + *    versions, like 1.0...
        + * A. Well, that's because this code is basically a quick-n-dirty
        + *    proof-of-concept hack. As you can see it's implemented with
        + *    inline assembler, which means that you're bound to GCC and that
        + *    there might be enough room for further improvement.
        + *
        + * Q. Why inline assembler?
        + * A. x86_64 features own ABI which I'm not familiar with. This is
        + *    why I decided to let the compiler take care of subroutine
        + *    prologue/epilogue as well as register allocation. For reference.
        + *    Win64 implements different ABI for AMD64, different from Linux.
        + *
        + * Q. How much faster does it get?
        + * A. 'apps/openssl speed rsa dsa' output with no-asm:
        + *
        + *	                  sign    verify    sign/s verify/s
        + *	rsa  512 bits   0.0006s   0.0001s   1683.8  18456.2
        + *	rsa 1024 bits   0.0028s   0.0002s    356.0   6407.0
        + *	rsa 2048 bits   0.0172s   0.0005s     58.0   1957.8
        + *	rsa 4096 bits   0.1155s   0.0018s      8.7    555.6
        + *	                  sign    verify    sign/s verify/s
        + *	dsa  512 bits   0.0005s   0.0006s   2100.8   1768.3
        + *	dsa 1024 bits   0.0014s   0.0018s    692.3    559.2
        + *	dsa 2048 bits   0.0049s   0.0061s    204.7    165.0
        + *
        + *    'apps/openssl speed rsa dsa' output with this module:
        + *
        + *	                  sign    verify    sign/s verify/s
        + *	rsa  512 bits   0.0004s   0.0000s   2767.1  33297.9
        + *	rsa 1024 bits   0.0012s   0.0001s    867.4  14674.7
        + *	rsa 2048 bits   0.0061s   0.0002s    164.0   5270.0
        + *	rsa 4096 bits   0.0384s   0.0006s     26.1   1650.8
        + *	                  sign    verify    sign/s verify/s
        + *	dsa  512 bits   0.0002s   0.0003s   4442.2   3786.3
        + *	dsa 1024 bits   0.0005s   0.0007s   1835.1   1497.4
        + *	dsa 2048 bits   0.0016s   0.0020s    620.4    504.6
        + *
        + *    For the reference. IA-32 assembler implementation performs
        + *    very much like 64-bit code compiled with no-asm on the same
        + *    machine.
        + */
        +
        +#ifdef _WIN64
        +#define BN_ULONG unsigned long long
        +#else
        +#define BN_ULONG unsigned long
        +#endif
        +
        +#undef mul
        +#undef mul_add
        +#undef sqr
        +
        +/*
        + * "m"(a), "+m"(r)	is the way to favor DirectPath µ-code;
        + * "g"(0)		let the compiler to decide where does it
        + *			want to keep the value of zero;
        + */
        +#define mul_add(r,a,word,carry) do {	\
        +	register BN_ULONG high,low;	\
        +	asm ("mulq %3"			\
        +		: "=a"(low),"=d"(high)	\
        +		: "a"(word),"m"(a)	\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(carry),"+d"(high)\
        +		: "a"(low),"g"(0)	\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+m"(r),"+d"(high)	\
        +		: "r"(carry),"g"(0)	\
        +		: "cc");		\
        +	carry=high;			\
        +	} while (0)
        +
        +#define mul(r,a,word,carry) do {	\
        +	register BN_ULONG high,low;	\
        +	asm ("mulq %3"			\
        +		: "=a"(low),"=d"(high)	\
        +		: "a"(word),"g"(a)	\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(carry),"+d"(high)\
        +		: "a"(low),"g"(0)	\
        +		: "cc");		\
        +	(r)=carry, carry=high;		\
        +	} while (0)
        +
        +#define sqr(r0,r1,a)			\
        +	asm ("mulq %2"			\
        +		: "=a"(r0),"=d"(r1)	\
        +		: "a"(a)		\
        +		: "cc");
        +
        +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
        +	{
        +	BN_ULONG c1=0;
        +
        +	if (num <= 0) return(c1);
        +
        +	while (num&~3)
        +		{
        +		mul_add(rp[0],ap[0],w,c1);
        +		mul_add(rp[1],ap[1],w,c1);
        +		mul_add(rp[2],ap[2],w,c1);
        +		mul_add(rp[3],ap[3],w,c1);
        +		ap+=4; rp+=4; num-=4;
        +		}
        +	if (num)
        +		{
        +		mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
        +		mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
        +		mul_add(rp[2],ap[2],w,c1); return c1;
        +		}
        +	
        +	return(c1);
        +	} 
        +
        +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
        +	{
        +	BN_ULONG c1=0;
        +
        +	if (num <= 0) return(c1);
        +
        +	while (num&~3)
        +		{
        +		mul(rp[0],ap[0],w,c1);
        +		mul(rp[1],ap[1],w,c1);
        +		mul(rp[2],ap[2],w,c1);
        +		mul(rp[3],ap[3],w,c1);
        +		ap+=4; rp+=4; num-=4;
        +		}
        +	if (num)
        +		{
        +		mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
        +		mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
        +		mul(rp[2],ap[2],w,c1);
        +		}
        +	return(c1);
        +	} 
        +
        +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
        +        {
        +	if (n <= 0) return;
        +
        +	while (n&~3)
        +		{
        +		sqr(r[0],r[1],a[0]);
        +		sqr(r[2],r[3],a[1]);
        +		sqr(r[4],r[5],a[2]);
        +		sqr(r[6],r[7],a[3]);
        +		a+=4; r+=8; n-=4;
        +		}
        +	if (n)
        +		{
        +		sqr(r[0],r[1],a[0]); if (--n == 0) return;
        +		sqr(r[2],r[3],a[1]); if (--n == 0) return;
        +		sqr(r[4],r[5],a[2]);
        +		}
        +	}
        +
        +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
        +{	BN_ULONG ret,waste;
        +
        +	asm ("divq	%4"
        +		: "=a"(ret),"=d"(waste)
        +		: "a"(l),"d"(h),"g"(d)
        +		: "cc");
        +
        +	return ret;
        +}
        +
        +BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
        +{ BN_ULONG ret=0,i=0;
        +
        +	if (n <= 0) return 0;
        +
        +	asm (
        +	"	subq	%2,%2		\n"
        +	".p2align 4			\n"
        +	"1:	movq	(%4,%2,8),%0	\n"
        +	"	adcq	(%5,%2,8),%0	\n"
        +	"	movq	%0,(%3,%2,8)	\n"
        +	"	leaq	1(%2),%2	\n"
        +	"	loop	1b		\n"
        +	"	sbbq	%0,%0		\n"
        +		: "=&a"(ret),"+c"(n),"=&r"(i)
        +		: "r"(rp),"r"(ap),"r"(bp)
        +		: "cc"
        +	);
        +
        +  return ret&1;
        +}
        +
        +#ifndef SIMICS
        +BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
        +{ BN_ULONG ret=0,i=0;
        +
        +	if (n <= 0) return 0;
        +
        +	asm (
        +	"	subq	%2,%2		\n"
        +	".p2align 4			\n"
        +	"1:	movq	(%4,%2,8),%0	\n"
        +	"	sbbq	(%5,%2,8),%0	\n"
        +	"	movq	%0,(%3,%2,8)	\n"
        +	"	leaq	1(%2),%2	\n"
        +	"	loop	1b		\n"
        +	"	sbbq	%0,%0		\n"
        +		: "=&a"(ret),"+c"(n),"=&r"(i)
        +		: "r"(rp),"r"(ap),"r"(bp)
        +		: "cc"
        +	);
        +
        +  return ret&1;
        +}
        +#else
        +/* Simics 1.4<7 has buggy sbbq:-( */
        +#define BN_MASK2 0xffffffffffffffffL
        +BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
        +        {
        +	BN_ULONG t1,t2;
        +	int c=0;
        +
        +	if (n <= 0) return((BN_ULONG)0);
        +
        +	for (;;)
        +		{
        +		t1=a[0]; t2=b[0];
        +		r[0]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		if (--n <= 0) break;
        +
        +		t1=a[1]; t2=b[1];
        +		r[1]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		if (--n <= 0) break;
        +
        +		t1=a[2]; t2=b[2];
        +		r[2]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		if (--n <= 0) break;
        +
        +		t1=a[3]; t2=b[3];
        +		r[3]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		if (--n <= 0) break;
        +
        +		a+=4;
        +		b+=4;
        +		r+=4;
        +		}
        +	return(c);
        +	}
        +#endif
        +
        +/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
        +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
        +/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
        +/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
        +
        +#if 0
        +/* original macros are kept for reference purposes */
        +#define mul_add_c(a,b,c0,c1,c2) {	\
        +	BN_ULONG ta=(a),tb=(b);		\
        +	t1 = ta * tb;			\
        +	t2 = BN_UMULT_HIGH(ta,tb);	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define mul_add_c2(a,b,c0,c1,c2) {	\
        +	BN_ULONG ta=(a),tb=(b),t0;	\
        +	t1 = BN_UMULT_HIGH(ta,tb);	\
        +	t0 = ta * tb;			\
        +	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
        +	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +#else
        +#define mul_add_c(a,b,c0,c1,c2)	do {	\
        +	asm ("mulq %3"			\
        +		: "=a"(t1),"=d"(t2)	\
        +		: "a"(a),"m"(b)		\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(c0),"+d"(t2)	\
        +		: "a"(t1),"g"(0)	\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(c1),"+r"(c2)	\
        +		: "d"(t2),"g"(0)	\
        +		: "cc");		\
        +	} while (0)
        +
        +#define sqr_add_c(a,i,c0,c1,c2)	do {	\
        +	asm ("mulq %2"			\
        +		: "=a"(t1),"=d"(t2)	\
        +		: "a"(a[i])		\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(c0),"+d"(t2)	\
        +		: "a"(t1),"g"(0)	\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(c1),"+r"(c2)	\
        +		: "d"(t2),"g"(0)	\
        +		: "cc");		\
        +	} while (0)
        +
        +#define mul_add_c2(a,b,c0,c1,c2) do {	\
        +	asm ("mulq %3"			\
        +		: "=a"(t1),"=d"(t2)	\
        +		: "a"(a),"m"(b)		\
        +		: "cc");		\
        +	asm ("addq %0,%0; adcq %2,%1"	\
        +		: "+d"(t2),"+r"(c2)	\
        +		: "g"(0)		\
        +		: "cc");		\
        +	asm ("addq %0,%0; adcq %2,%1"	\
        +		: "+a"(t1),"+d"(t2)	\
        +		: "g"(0)		\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(c0),"+d"(t2)	\
        +		: "a"(t1),"g"(0)	\
        +		: "cc");		\
        +	asm ("addq %2,%0; adcq %3,%1"	\
        +		: "+r"(c1),"+r"(c2)	\
        +		: "d"(t2),"g"(0)	\
        +		: "cc");		\
        +	} while (0)
        +#endif
        +
        +#define sqr_add_c2(a,i,j,c0,c1,c2)	\
        +	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
        +
        +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +	{
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	mul_add_c(a[0],b[0],c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	mul_add_c(a[0],b[1],c2,c3,c1);
        +	mul_add_c(a[1],b[0],c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	mul_add_c(a[2],b[0],c3,c1,c2);
        +	mul_add_c(a[1],b[1],c3,c1,c2);
        +	mul_add_c(a[0],b[2],c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	mul_add_c(a[0],b[3],c1,c2,c3);
        +	mul_add_c(a[1],b[2],c1,c2,c3);
        +	mul_add_c(a[2],b[1],c1,c2,c3);
        +	mul_add_c(a[3],b[0],c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	mul_add_c(a[4],b[0],c2,c3,c1);
        +	mul_add_c(a[3],b[1],c2,c3,c1);
        +	mul_add_c(a[2],b[2],c2,c3,c1);
        +	mul_add_c(a[1],b[3],c2,c3,c1);
        +	mul_add_c(a[0],b[4],c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	mul_add_c(a[0],b[5],c3,c1,c2);
        +	mul_add_c(a[1],b[4],c3,c1,c2);
        +	mul_add_c(a[2],b[3],c3,c1,c2);
        +	mul_add_c(a[3],b[2],c3,c1,c2);
        +	mul_add_c(a[4],b[1],c3,c1,c2);
        +	mul_add_c(a[5],b[0],c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	mul_add_c(a[6],b[0],c1,c2,c3);
        +	mul_add_c(a[5],b[1],c1,c2,c3);
        +	mul_add_c(a[4],b[2],c1,c2,c3);
        +	mul_add_c(a[3],b[3],c1,c2,c3);
        +	mul_add_c(a[2],b[4],c1,c2,c3);
        +	mul_add_c(a[1],b[5],c1,c2,c3);
        +	mul_add_c(a[0],b[6],c1,c2,c3);
        +	r[6]=c1;
        +	c1=0;
        +	mul_add_c(a[0],b[7],c2,c3,c1);
        +	mul_add_c(a[1],b[6],c2,c3,c1);
        +	mul_add_c(a[2],b[5],c2,c3,c1);
        +	mul_add_c(a[3],b[4],c2,c3,c1);
        +	mul_add_c(a[4],b[3],c2,c3,c1);
        +	mul_add_c(a[5],b[2],c2,c3,c1);
        +	mul_add_c(a[6],b[1],c2,c3,c1);
        +	mul_add_c(a[7],b[0],c2,c3,c1);
        +	r[7]=c2;
        +	c2=0;
        +	mul_add_c(a[7],b[1],c3,c1,c2);
        +	mul_add_c(a[6],b[2],c3,c1,c2);
        +	mul_add_c(a[5],b[3],c3,c1,c2);
        +	mul_add_c(a[4],b[4],c3,c1,c2);
        +	mul_add_c(a[3],b[5],c3,c1,c2);
        +	mul_add_c(a[2],b[6],c3,c1,c2);
        +	mul_add_c(a[1],b[7],c3,c1,c2);
        +	r[8]=c3;
        +	c3=0;
        +	mul_add_c(a[2],b[7],c1,c2,c3);
        +	mul_add_c(a[3],b[6],c1,c2,c3);
        +	mul_add_c(a[4],b[5],c1,c2,c3);
        +	mul_add_c(a[5],b[4],c1,c2,c3);
        +	mul_add_c(a[6],b[3],c1,c2,c3);
        +	mul_add_c(a[7],b[2],c1,c2,c3);
        +	r[9]=c1;
        +	c1=0;
        +	mul_add_c(a[7],b[3],c2,c3,c1);
        +	mul_add_c(a[6],b[4],c2,c3,c1);
        +	mul_add_c(a[5],b[5],c2,c3,c1);
        +	mul_add_c(a[4],b[6],c2,c3,c1);
        +	mul_add_c(a[3],b[7],c2,c3,c1);
        +	r[10]=c2;
        +	c2=0;
        +	mul_add_c(a[4],b[7],c3,c1,c2);
        +	mul_add_c(a[5],b[6],c3,c1,c2);
        +	mul_add_c(a[6],b[5],c3,c1,c2);
        +	mul_add_c(a[7],b[4],c3,c1,c2);
        +	r[11]=c3;
        +	c3=0;
        +	mul_add_c(a[7],b[5],c1,c2,c3);
        +	mul_add_c(a[6],b[6],c1,c2,c3);
        +	mul_add_c(a[5],b[7],c1,c2,c3);
        +	r[12]=c1;
        +	c1=0;
        +	mul_add_c(a[6],b[7],c2,c3,c1);
        +	mul_add_c(a[7],b[6],c2,c3,c1);
        +	r[13]=c2;
        +	c2=0;
        +	mul_add_c(a[7],b[7],c3,c1,c2);
        +	r[14]=c3;
        +	r[15]=c1;
        +	}
        +
        +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +	{
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	mul_add_c(a[0],b[0],c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	mul_add_c(a[0],b[1],c2,c3,c1);
        +	mul_add_c(a[1],b[0],c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	mul_add_c(a[2],b[0],c3,c1,c2);
        +	mul_add_c(a[1],b[1],c3,c1,c2);
        +	mul_add_c(a[0],b[2],c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	mul_add_c(a[0],b[3],c1,c2,c3);
        +	mul_add_c(a[1],b[2],c1,c2,c3);
        +	mul_add_c(a[2],b[1],c1,c2,c3);
        +	mul_add_c(a[3],b[0],c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	mul_add_c(a[3],b[1],c2,c3,c1);
        +	mul_add_c(a[2],b[2],c2,c3,c1);
        +	mul_add_c(a[1],b[3],c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	mul_add_c(a[2],b[3],c3,c1,c2);
        +	mul_add_c(a[3],b[2],c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	mul_add_c(a[3],b[3],c1,c2,c3);
        +	r[6]=c1;
        +	r[7]=c2;
        +	}
        +
        +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
        +	{
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	sqr_add_c(a,0,c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	sqr_add_c2(a,1,0,c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	sqr_add_c(a,1,c3,c1,c2);
        +	sqr_add_c2(a,2,0,c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	sqr_add_c2(a,3,0,c1,c2,c3);
        +	sqr_add_c2(a,2,1,c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	sqr_add_c(a,2,c2,c3,c1);
        +	sqr_add_c2(a,3,1,c2,c3,c1);
        +	sqr_add_c2(a,4,0,c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	sqr_add_c2(a,5,0,c3,c1,c2);
        +	sqr_add_c2(a,4,1,c3,c1,c2);
        +	sqr_add_c2(a,3,2,c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	sqr_add_c(a,3,c1,c2,c3);
        +	sqr_add_c2(a,4,2,c1,c2,c3);
        +	sqr_add_c2(a,5,1,c1,c2,c3);
        +	sqr_add_c2(a,6,0,c1,c2,c3);
        +	r[6]=c1;
        +	c1=0;
        +	sqr_add_c2(a,7,0,c2,c3,c1);
        +	sqr_add_c2(a,6,1,c2,c3,c1);
        +	sqr_add_c2(a,5,2,c2,c3,c1);
        +	sqr_add_c2(a,4,3,c2,c3,c1);
        +	r[7]=c2;
        +	c2=0;
        +	sqr_add_c(a,4,c3,c1,c2);
        +	sqr_add_c2(a,5,3,c3,c1,c2);
        +	sqr_add_c2(a,6,2,c3,c1,c2);
        +	sqr_add_c2(a,7,1,c3,c1,c2);
        +	r[8]=c3;
        +	c3=0;
        +	sqr_add_c2(a,7,2,c1,c2,c3);
        +	sqr_add_c2(a,6,3,c1,c2,c3);
        +	sqr_add_c2(a,5,4,c1,c2,c3);
        +	r[9]=c1;
        +	c1=0;
        +	sqr_add_c(a,5,c2,c3,c1);
        +	sqr_add_c2(a,6,4,c2,c3,c1);
        +	sqr_add_c2(a,7,3,c2,c3,c1);
        +	r[10]=c2;
        +	c2=0;
        +	sqr_add_c2(a,7,4,c3,c1,c2);
        +	sqr_add_c2(a,6,5,c3,c1,c2);
        +	r[11]=c3;
        +	c3=0;
        +	sqr_add_c(a,6,c1,c2,c3);
        +	sqr_add_c2(a,7,5,c1,c2,c3);
        +	r[12]=c1;
        +	c1=0;
        +	sqr_add_c2(a,7,6,c2,c3,c1);
        +	r[13]=c2;
        +	c2=0;
        +	sqr_add_c(a,7,c3,c1,c2);
        +	r[14]=c3;
        +	r[15]=c1;
        +	}
        +
        +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
        +	{
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	sqr_add_c(a,0,c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	sqr_add_c2(a,1,0,c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	sqr_add_c(a,1,c3,c1,c2);
        +	sqr_add_c2(a,2,0,c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	sqr_add_c2(a,3,0,c1,c2,c3);
        +	sqr_add_c2(a,2,1,c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	sqr_add_c(a,2,c2,c3,c1);
        +	sqr_add_c2(a,3,1,c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	sqr_add_c2(a,3,2,c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	sqr_add_c(a,3,c1,c2,c3);
        +	r[6]=c1;
        +	r[7]=c2;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl b/vendor/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl
        new file mode 100644
        index 000000000..a30d4ef02
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86_64-gf2m.pl
        @@ -0,0 +1,389 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# May 2011
        +#
        +# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
        +# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
        +# the time being... Except that it has two code paths: code suitable
        +# for any x86_64 CPU and PCLMULQDQ one suitable for Westmere and
        +# later. Improvement varies from one benchmark and µ-arch to another.
        +# Vanilla code path is at most 20% faster than compiler-generated code
        +# [not very impressive], while PCLMULQDQ - whole 85%-160% better on
        +# 163- and 571-bit ECDH benchmarks on Intel CPUs. Keep in mind that
        +# these coefficients are not ones for bn_GF2m_mul_2x2 itself, as not
        +# all CPU time is burnt in it...
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open STDOUT,"| \"$^X\" $xlate $flavour $output";
        +
        +($lo,$hi)=("%rax","%rdx");	$a=$lo;
        +($i0,$i1)=("%rsi","%rdi");
        +($t0,$t1)=("%rbx","%rcx");
        +($b,$mask)=("%rbp","%r8");
        +($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(9..15));
        +($R,$Tx)=("%xmm0","%xmm1");
        +
        +$code.=<<___;
        +.text
        +
        +.type	_mul_1x1,\@abi-omnipotent
        +.align	16
        +_mul_1x1:
        +	sub	\$128+8,%rsp
        +	mov	\$-1,$a1
        +	lea	($a,$a),$i0
        +	shr	\$3,$a1
        +	lea	(,$a,4),$i1
        +	and	$a,$a1			# a1=a&0x1fffffffffffffff
        +	lea	(,$a,8),$a8
        +	sar	\$63,$a			# broadcast 63rd bit
        +	lea	($a1,$a1),$a2
        +	sar	\$63,$i0		# broadcast 62nd bit
        +	lea	(,$a1,4),$a4
        +	and	$b,$a
        +	sar	\$63,$i1		# boardcast 61st bit
        +	mov	$a,$hi			# $a is $lo
        +	shl	\$63,$lo
        +	and	$b,$i0
        +	shr	\$1,$hi
        +	mov	$i0,$t1
        +	shl	\$62,$i0
        +	and	$b,$i1
        +	shr	\$2,$t1
        +	xor	$i0,$lo
        +	mov	$i1,$t0
        +	shl	\$61,$i1
        +	xor	$t1,$hi
        +	shr	\$3,$t0
        +	xor	$i1,$lo
        +	xor	$t0,$hi
        +
        +	mov	$a1,$a12
        +	movq	\$0,0(%rsp)		# tab[0]=0
        +	xor	$a2,$a12		# a1^a2
        +	mov	$a1,8(%rsp)		# tab[1]=a1
        +	 mov	$a4,$a48
        +	mov	$a2,16(%rsp)		# tab[2]=a2
        +	 xor	$a8,$a48		# a4^a8
        +	mov	$a12,24(%rsp)		# tab[3]=a1^a2
        +
        +	xor	$a4,$a1
        +	mov	$a4,32(%rsp)		# tab[4]=a4
        +	xor	$a4,$a2
        +	mov	$a1,40(%rsp)		# tab[5]=a1^a4
        +	xor	$a4,$a12
        +	mov	$a2,48(%rsp)		# tab[6]=a2^a4
        +	 xor	$a48,$a1		# a1^a4^a4^a8=a1^a8
        +	mov	$a12,56(%rsp)		# tab[7]=a1^a2^a4
        +	 xor	$a48,$a2		# a2^a4^a4^a8=a1^a8
        +
        +	mov	$a8,64(%rsp)		# tab[8]=a8
        +	xor	$a48,$a12		# a1^a2^a4^a4^a8=a1^a2^a8
        +	mov	$a1,72(%rsp)		# tab[9]=a1^a8
        +	 xor	$a4,$a1			# a1^a8^a4
        +	mov	$a2,80(%rsp)		# tab[10]=a2^a8
        +	 xor	$a4,$a2			# a2^a8^a4
        +	mov	$a12,88(%rsp)		# tab[11]=a1^a2^a8
        +
        +	xor	$a4,$a12		# a1^a2^a8^a4
        +	mov	$a48,96(%rsp)		# tab[12]=a4^a8
        +	 mov	$mask,$i0
        +	mov	$a1,104(%rsp)		# tab[13]=a1^a4^a8
        +	 and	$b,$i0
        +	mov	$a2,112(%rsp)		# tab[14]=a2^a4^a8
        +	 shr	\$4,$b
        +	mov	$a12,120(%rsp)		# tab[15]=a1^a2^a4^a8
        +	 mov	$mask,$i1
        +	 and	$b,$i1
        +	 shr	\$4,$b
        +
        +	movq	(%rsp,$i0,8),$R		# half of calculations is done in SSE2
        +	mov	$mask,$i0
        +	and	$b,$i0
        +	shr	\$4,$b
        +___
        +    for ($n=1;$n<8;$n++) {
        +	$code.=<<___;
        +	mov	(%rsp,$i1,8),$t1
        +	mov	$mask,$i1
        +	mov	$t1,$t0
        +	shl	\$`8*$n-4`,$t1
        +	and	$b,$i1
        +	 movq	(%rsp,$i0,8),$Tx
        +	shr	\$`64-(8*$n-4)`,$t0
        +	xor	$t1,$lo
        +	 pslldq	\$$n,$Tx
        +	 mov	$mask,$i0
        +	shr	\$4,$b
        +	xor	$t0,$hi
        +	 and	$b,$i0
        +	 shr	\$4,$b
        +	 pxor	$Tx,$R
        +___
        +    }
        +$code.=<<___;
        +	mov	(%rsp,$i1,8),$t1
        +	mov	$t1,$t0
        +	shl	\$`8*$n-4`,$t1
        +	movq	$R,$i0
        +	shr	\$`64-(8*$n-4)`,$t0
        +	xor	$t1,$lo
        +	psrldq	\$8,$R
        +	xor	$t0,$hi
        +	movq	$R,$i1
        +	xor	$i0,$lo
        +	xor	$i1,$hi
        +
        +	add	\$128+8,%rsp
        +	ret
        +.Lend_mul_1x1:
        +.size	_mul_1x1,.-_mul_1x1
        +___
        +
        +($rp,$a1,$a0,$b1,$b0) = $win64?	("%rcx","%rdx","%r8", "%r9","%r10") :	# Win64 order
        +				("%rdi","%rsi","%rdx","%rcx","%r8");	# Unix order
        +
        +$code.=<<___;
        +.extern	OPENSSL_ia32cap_P
        +.globl	bn_GF2m_mul_2x2
        +.type	bn_GF2m_mul_2x2,\@abi-omnipotent
        +.align	16
        +bn_GF2m_mul_2x2:
        +	mov	OPENSSL_ia32cap_P(%rip),%rax
        +	bt	\$33,%rax
        +	jnc	.Lvanilla_mul_2x2
        +
        +	movq		$a1,%xmm0
        +	movq		$b1,%xmm1
        +	movq		$a0,%xmm2
        +___
        +$code.=<<___ if ($win64);
        +	movq		40(%rsp),%xmm3
        +___
        +$code.=<<___ if (!$win64);
        +	movq		$b0,%xmm3
        +___
        +$code.=<<___;
        +	movdqa		%xmm0,%xmm4
        +	movdqa		%xmm1,%xmm5
        +	pclmulqdq	\$0,%xmm1,%xmm0	# a1·b1
        +	pxor		%xmm2,%xmm4
        +	pxor		%xmm3,%xmm5
        +	pclmulqdq	\$0,%xmm3,%xmm2	# a0·b0
        +	pclmulqdq	\$0,%xmm5,%xmm4	# (a0+a1)·(b0+b1)
        +	xorps		%xmm0,%xmm4
        +	xorps		%xmm2,%xmm4	# (a0+a1)·(b0+b1)-a0·b0-a1·b1
        +	movdqa		%xmm4,%xmm5
        +	pslldq		\$8,%xmm4
        +	psrldq		\$8,%xmm5
        +	pxor		%xmm4,%xmm2
        +	pxor		%xmm5,%xmm0
        +	movdqu		%xmm2,0($rp)
        +	movdqu		%xmm0,16($rp)
        +	ret
        +
        +.align	16
        +.Lvanilla_mul_2x2:
        +	lea	-8*17(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	mov	`8*17+40`(%rsp),$b0
        +	mov	%rdi,8*15(%rsp)
        +	mov	%rsi,8*16(%rsp)
        +___
        +$code.=<<___;
        +	mov	%r14,8*10(%rsp)
        +	mov	%r13,8*11(%rsp)
        +	mov	%r12,8*12(%rsp)
        +	mov	%rbp,8*13(%rsp)
        +	mov	%rbx,8*14(%rsp)
        +.Lbody_mul_2x2:
        +	mov	$rp,32(%rsp)		# save the arguments
        +	mov	$a1,40(%rsp)
        +	mov	$a0,48(%rsp)
        +	mov	$b1,56(%rsp)
        +	mov	$b0,64(%rsp)
        +
        +	mov	\$0xf,$mask
        +	mov	$a1,$a
        +	mov	$b1,$b
        +	call	_mul_1x1		# a1·b1
        +	mov	$lo,16(%rsp)
        +	mov	$hi,24(%rsp)
        +
        +	mov	48(%rsp),$a
        +	mov	64(%rsp),$b
        +	call	_mul_1x1		# a0·b0
        +	mov	$lo,0(%rsp)
        +	mov	$hi,8(%rsp)
        +
        +	mov	40(%rsp),$a
        +	mov	56(%rsp),$b
        +	xor	48(%rsp),$a
        +	xor	64(%rsp),$b
        +	call	_mul_1x1		# (a0+a1)·(b0+b1)
        +___
        +	@r=("%rbx","%rcx","%rdi","%rsi");
        +$code.=<<___;
        +	mov	0(%rsp),@r[0]
        +	mov	8(%rsp),@r[1]
        +	mov	16(%rsp),@r[2]
        +	mov	24(%rsp),@r[3]
        +	mov	32(%rsp),%rbp
        +
        +	xor	$hi,$lo
        +	xor	@r[1],$hi
        +	xor	@r[0],$lo
        +	mov	@r[0],0(%rbp)
        +	xor	@r[2],$hi
        +	mov	@r[3],24(%rbp)
        +	xor	@r[3],$lo
        +	xor	@r[3],$hi
        +	xor	$hi,$lo
        +	mov	$hi,16(%rbp)
        +	mov	$lo,8(%rbp)
        +
        +	mov	8*10(%rsp),%r14
        +	mov	8*11(%rsp),%r13
        +	mov	8*12(%rsp),%r12
        +	mov	8*13(%rsp),%rbp
        +	mov	8*14(%rsp),%rbx
        +___
        +$code.=<<___ if ($win64);
        +	mov	8*15(%rsp),%rdi
        +	mov	8*16(%rsp),%rsi
        +___
        +$code.=<<___;
        +	lea	8*17(%rsp),%rsp
        +	ret
        +.Lend_mul_2x2:
        +.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
        +.asciz	"GF(2^m) Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	16
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#               CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern __imp_RtlVirtualUnwind
        +
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lbody_mul_2x2(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<"prologue" label
        +	jb	.Lin_prologue
        +
        +	mov	8*10(%rax),%r14		# mimic epilogue
        +	mov	8*11(%rax),%r13
        +	mov	8*12(%rax),%r12
        +	mov	8*13(%rax),%rbp
        +	mov	8*14(%rax),%rbx
        +	mov	8*15(%rax),%rdi
        +	mov	8*16(%rax),%rsi
        +
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +
        +.Lin_prologue:
        +	lea	8*17(%rax),%rax
        +	mov	%rax,152($context)	# restore context->Rsp
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	_mul_1x1
        +	.rva	.Lend_mul_1x1
        +	.rva	.LSEH_info_1x1
        +
        +	.rva	.Lvanilla_mul_2x2
        +	.rva	.Lend_mul_2x2
        +	.rva	.LSEH_info_2x2
        +.section	.xdata
        +.align	8
        +.LSEH_info_1x1:
        +	.byte	0x01,0x07,0x02,0x00
        +	.byte	0x07,0x01,0x11,0x00	# sub rsp,128+8
        +.LSEH_info_2x2:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86_64-mont.pl b/vendor/openssl/openssl/crypto/bn/asm/x86_64-mont.pl
        new file mode 100644
        index 000000000..17fb94c84
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86_64-mont.pl
        @@ -0,0 +1,1681 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# October 2005.
        +#
        +# Montgomery multiplication routine for x86_64. While it gives modest
        +# 9% improvement of rsa4096 sign on Opteron, rsa512 sign runs more
        +# than twice, >2x, as fast. Most common rsa1024 sign is improved by
        +# respectful 50%. It remains to be seen if loop unrolling and
        +# dedicated squaring routine can provide further improvement...
        +
        +# July 2011.
        +#
        +# Add dedicated squaring procedure. Performance improvement varies
        +# from platform to platform, but in average it's ~5%/15%/25%/33%
        +# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively.
        +
        +# August 2011.
        +#
        +# Unroll and modulo-schedule inner loops in such manner that they
        +# are "fallen through" for input lengths of 8, which is critical for
        +# 1024-bit RSA *sign*. Average performance improvement in comparison
        +# to *initial* version of this module from 2005 is ~0%/30%/40%/45%
        +# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively.
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +# int bn_mul_mont(
        +$rp="%rdi";	# BN_ULONG *rp,
        +$ap="%rsi";	# const BN_ULONG *ap,
        +$bp="%rdx";	# const BN_ULONG *bp,
        +$np="%rcx";	# const BN_ULONG *np,
        +$n0="%r8";	# const BN_ULONG *n0,
        +$num="%r9";	# int num);
        +$lo0="%r10";
        +$hi0="%r11";
        +$hi1="%r13";
        +$i="%r14";
        +$j="%r15";
        +$m0="%rbx";
        +$m1="%rbp";
        +
        +$code=<<___;
        +.text
        +
        +.globl	bn_mul_mont
        +.type	bn_mul_mont,\@function,6
        +.align	16
        +bn_mul_mont:
        +	test	\$3,${num}d
        +	jnz	.Lmul_enter
        +	cmp	\$8,${num}d
        +	jb	.Lmul_enter
        +	cmp	$ap,$bp
        +	jne	.Lmul4x_enter
        +	jmp	.Lsqr4x_enter
        +
        +.align	16
        +.Lmul_enter:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +
        +	mov	${num}d,${num}d
        +	lea	2($num),%r10
        +	mov	%rsp,%r11
        +	neg	%r10
        +	lea	(%rsp,%r10,8),%rsp	# tp=alloca(8*(num+2))
        +	and	\$-1024,%rsp		# minimize TLB usage
        +
        +	mov	%r11,8(%rsp,$num,8)	# tp[num+1]=%rsp
        +.Lmul_body:
        +	mov	$bp,%r12		# reassign $bp
        +___
        +		$bp="%r12";
        +$code.=<<___;
        +	mov	($n0),$n0		# pull n0[0] value
        +	mov	($bp),$m0		# m0=bp[0]
        +	mov	($ap),%rax
        +
        +	xor	$i,$i			# i=0
        +	xor	$j,$j			# j=0
        +
        +	mov	$n0,$m1
        +	mulq	$m0			# ap[0]*bp[0]
        +	mov	%rax,$lo0
        +	mov	($np),%rax
        +
        +	imulq	$lo0,$m1		# "tp[0]"*n0
        +	mov	%rdx,$hi0
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$lo0		# discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$hi1
        +
        +	lea	1($j),$j		# j++
        +	jmp	.L1st_enter
        +
        +.align	16
        +.L1st:
        +	add	%rax,$hi1
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
        +	mov	$lo0,$hi0
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +
        +.L1st_enter:
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$hi0
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	lea	1($j),$j		# j++
        +	mov	%rdx,$lo0
        +
        +	mulq	$m1			# np[j]*m1
        +	cmp	$num,$j
        +	jne	.L1st
        +
        +	add	%rax,$hi1
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +	mov	$lo0,$hi0
        +
        +	xor	%rdx,%rdx
        +	add	$hi0,$hi1
        +	adc	\$0,%rdx
        +	mov	$hi1,-8(%rsp,$num,8)
        +	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
        +
        +	lea	1($i),$i		# i++
        +	jmp	.Louter
        +.align	16
        +.Louter:
        +	mov	($bp,$i,8),$m0		# m0=bp[i]
        +	xor	$j,$j			# j=0
        +	mov	$n0,$m1
        +	mov	(%rsp),$lo0
        +	mulq	$m0			# ap[0]*bp[i]
        +	add	%rax,$lo0		# ap[0]*bp[i]+tp[0]
        +	mov	($np),%rax
        +	adc	\$0,%rdx
        +
        +	imulq	$lo0,$m1		# tp[0]*n0
        +	mov	%rdx,$hi0
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$lo0		# discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	8(%rsp),$lo0		# tp[1]
        +	mov	%rdx,$hi1
        +
        +	lea	1($j),$j		# j++
        +	jmp	.Linner_enter
        +
        +.align	16
        +.Linner:
        +	add	%rax,$hi1
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
        +	mov	(%rsp,$j,8),$lo0
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +
        +.Linner_enter:
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$hi0
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$hi0,$lo0		# ap[j]*bp[i]+tp[j]
        +	mov	%rdx,$hi0
        +	adc	\$0,$hi0
        +	lea	1($j),$j		# j++
        +
        +	mulq	$m1			# np[j]*m1
        +	cmp	$num,$j
        +	jne	.Linner
        +
        +	add	%rax,$hi1
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
        +	mov	(%rsp,$j,8),$lo0
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +
        +	xor	%rdx,%rdx
        +	add	$hi0,$hi1
        +	adc	\$0,%rdx
        +	add	$lo0,$hi1		# pull upmost overflow bit
        +	adc	\$0,%rdx
        +	mov	$hi1,-8(%rsp,$num,8)
        +	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
        +
        +	lea	1($i),$i		# i++
        +	cmp	$num,$i
        +	jl	.Louter
        +
        +	xor	$i,$i			# i=0 and clear CF!
        +	mov	(%rsp),%rax		# tp[0]
        +	lea	(%rsp),$ap		# borrow ap for tp
        +	mov	$num,$j			# j=num
        +	jmp	.Lsub
        +.align	16
        +.Lsub:	sbb	($np,$i,8),%rax
        +	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]-np[i]
        +	mov	8($ap,$i,8),%rax	# tp[i+1]
        +	lea	1($i),$i		# i++
        +	dec	$j			# doesnn't affect CF!
        +	jnz	.Lsub
        +
        +	sbb	\$0,%rax		# handle upmost overflow bit
        +	xor	$i,$i
        +	and	%rax,$ap
        +	not	%rax
        +	mov	$rp,$np
        +	and	%rax,$np
        +	mov	$num,$j			# j=num
        +	or	$np,$ap			# ap=borrow?tp:rp
        +.align	16
        +.Lcopy:					# copy or in-place refresh
        +	mov	($ap,$i,8),%rax
        +	mov	$i,(%rsp,$i,8)		# zap temporary vector
        +	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]
        +	lea	1($i),$i
        +	sub	\$1,$j
        +	jnz	.Lcopy
        +
        +	mov	8(%rsp,$num,8),%rsi	# restore %rsp
        +	mov	\$1,%rax
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lmul_epilogue:
        +	ret
        +.size	bn_mul_mont,.-bn_mul_mont
        +___
        +{{{
        +my @A=("%r10","%r11");
        +my @N=("%r13","%rdi");
        +$code.=<<___;
        +.type	bn_mul4x_mont,\@function,6
        +.align	16
        +bn_mul4x_mont:
        +.Lmul4x_enter:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +
        +	mov	${num}d,${num}d
        +	lea	4($num),%r10
        +	mov	%rsp,%r11
        +	neg	%r10
        +	lea	(%rsp,%r10,8),%rsp	# tp=alloca(8*(num+4))
        +	and	\$-1024,%rsp		# minimize TLB usage
        +
        +	mov	%r11,8(%rsp,$num,8)	# tp[num+1]=%rsp
        +.Lmul4x_body:
        +	mov	$rp,16(%rsp,$num,8)	# tp[num+2]=$rp
        +	mov	%rdx,%r12		# reassign $bp
        +___
        +		$bp="%r12";
        +$code.=<<___;
        +	mov	($n0),$n0		# pull n0[0] value
        +	mov	($bp),$m0		# m0=bp[0]
        +	mov	($ap),%rax
        +
        +	xor	$i,$i			# i=0
        +	xor	$j,$j			# j=0
        +
        +	mov	$n0,$m1
        +	mulq	$m0			# ap[0]*bp[0]
        +	mov	%rax,$A[0]
        +	mov	($np),%rax
        +
        +	imulq	$A[0],$m1		# "tp[0]"*n0
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$A[0]		# discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0
        +	add	%rax,$A[1]
        +	mov	8($np),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1
        +	add	%rax,$N[1]
        +	mov	16($ap),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	lea	4($j),$j		# j++
        +	adc	\$0,%rdx
        +	mov	$N[1],(%rsp)
        +	mov	%rdx,$N[0]
        +	jmp	.L1st4x
        +.align	16
        +.L1st4x:
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[0]
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-8(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[1]
        +	mov	8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	lea	4($j),$j		# j++
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	-16($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +	cmp	$num,$j
        +	jl	.L1st4x
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	xor	$N[1],$N[1]
        +	add	$A[0],$N[0]
        +	adc	\$0,$N[1]
        +	mov	$N[0],-8(%rsp,$j,8)
        +	mov	$N[1],(%rsp,$j,8)	# store upmost overflow bit
        +
        +	lea	1($i),$i		# i++
        +.align	4
        +.Louter4x:
        +	mov	($bp,$i,8),$m0		# m0=bp[i]
        +	xor	$j,$j			# j=0
        +	mov	(%rsp),$A[0]
        +	mov	$n0,$m1
        +	mulq	$m0			# ap[0]*bp[i]
        +	add	%rax,$A[0]		# ap[0]*bp[i]+tp[0]
        +	mov	($np),%rax
        +	adc	\$0,%rdx
        +
        +	imulq	$A[0],$m1		# tp[0]*n0
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$A[0]		# "$N[0]", discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	8($np),%rax
        +	adc	\$0,%rdx
        +	add	8(%rsp),$A[1]		# +tp[1]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	16($ap),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[i]+tp[j]
        +	lea	4($j),$j		# j+=2
        +	adc	\$0,%rdx
        +	mov	$N[1],(%rsp)		# tp[j-1]
        +	mov	%rdx,$N[0]
        +	jmp	.Linner4x
        +.align	16
        +.Linner4x:
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-16(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-8(%rsp,$j,8),$A[1]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[0]
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-8(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	8(%rsp,$j,8),$A[1]
        +	adc	\$0,%rdx
        +	lea	4($j),$j		# j++
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	-16($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	adc	\$0,%rdx
        +	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +	cmp	$num,$j
        +	jl	.Linner4x
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-16(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-8(%rsp,$j,8),$A[1]
        +	adc	\$0,%rdx
        +	lea	1($i),$i		# i++
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	xor	$N[1],$N[1]
        +	add	$A[0],$N[0]
        +	adc	\$0,$N[1]
        +	add	(%rsp,$num,8),$N[0]	# pull upmost overflow bit
        +	adc	\$0,$N[1]
        +	mov	$N[0],-8(%rsp,$j,8)
        +	mov	$N[1],(%rsp,$j,8)	# store upmost overflow bit
        +
        +	cmp	$num,$i
        +	jl	.Louter4x
        +___
        +{
        +my @ri=("%rax","%rdx",$m0,$m1);
        +$code.=<<___;
        +	mov	16(%rsp,$num,8),$rp	# restore $rp
        +	mov	0(%rsp),@ri[0]		# tp[0]
        +	pxor	%xmm0,%xmm0
        +	mov	8(%rsp),@ri[1]		# tp[1]
        +	shr	\$2,$num		# num/=4
        +	lea	(%rsp),$ap		# borrow ap for tp
        +	xor	$i,$i			# i=0 and clear CF!
        +
        +	sub	0($np),@ri[0]
        +	mov	16($ap),@ri[2]		# tp[2]
        +	mov	24($ap),@ri[3]		# tp[3]
        +	sbb	8($np),@ri[1]
        +	lea	-1($num),$j		# j=num/4-1
        +	jmp	.Lsub4x
        +.align	16
        +.Lsub4x:
        +	mov	@ri[0],0($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	@ri[1],8($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	16($np,$i,8),@ri[2]
        +	mov	32($ap,$i,8),@ri[0]	# tp[i+1]
        +	mov	40($ap,$i,8),@ri[1]
        +	sbb	24($np,$i,8),@ri[3]
        +	mov	@ri[2],16($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	@ri[3],24($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	32($np,$i,8),@ri[0]
        +	mov	48($ap,$i,8),@ri[2]
        +	mov	56($ap,$i,8),@ri[3]
        +	sbb	40($np,$i,8),@ri[1]
        +	lea	4($i),$i		# i++
        +	dec	$j			# doesnn't affect CF!
        +	jnz	.Lsub4x
        +
        +	mov	@ri[0],0($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	32($ap,$i,8),@ri[0]	# load overflow bit
        +	sbb	16($np,$i,8),@ri[2]
        +	mov	@ri[1],8($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	24($np,$i,8),@ri[3]
        +	mov	@ri[2],16($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +
        +	sbb	\$0,@ri[0]		# handle upmost overflow bit
        +	mov	@ri[3],24($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	xor	$i,$i			# i=0
        +	and	@ri[0],$ap
        +	not	@ri[0]
        +	mov	$rp,$np
        +	and	@ri[0],$np
        +	lea	-1($num),$j
        +	or	$np,$ap			# ap=borrow?tp:rp
        +
        +	movdqu	($ap),%xmm1
        +	movdqa	%xmm0,(%rsp)
        +	movdqu	%xmm1,($rp)
        +	jmp	.Lcopy4x
        +.align	16
        +.Lcopy4x:					# copy or in-place refresh
        +	movdqu	16($ap,$i),%xmm2
        +	movdqu	32($ap,$i),%xmm1
        +	movdqa	%xmm0,16(%rsp,$i)
        +	movdqu	%xmm2,16($rp,$i)
        +	movdqa	%xmm0,32(%rsp,$i)
        +	movdqu	%xmm1,32($rp,$i)
        +	lea	32($i),$i
        +	dec	$j
        +	jnz	.Lcopy4x
        +
        +	shl	\$2,$num
        +	movdqu	16($ap,$i),%xmm2
        +	movdqa	%xmm0,16(%rsp,$i)
        +	movdqu	%xmm2,16($rp,$i)
        +___
        +}
        +$code.=<<___;
        +	mov	8(%rsp,$num,8),%rsi	# restore %rsp
        +	mov	\$1,%rax
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lmul4x_epilogue:
        +	ret
        +.size	bn_mul4x_mont,.-bn_mul4x_mont
        +___
        +}}}
        +{{{
        +######################################################################
        +# void bn_sqr4x_mont(
        +my $rptr="%rdi";	# const BN_ULONG *rptr,
        +my $aptr="%rsi";	# const BN_ULONG *aptr,
        +my $bptr="%rdx";	# not used
        +my $nptr="%rcx";	# const BN_ULONG *nptr,
        +my $n0  ="%r8";		# const BN_ULONG *n0);
        +my $num ="%r9";		# int num, has to be divisible by 4 and
        +			# not less than 8
        +
        +my ($i,$j,$tptr)=("%rbp","%rcx",$rptr);
        +my @A0=("%r10","%r11");
        +my @A1=("%r12","%r13");
        +my ($a0,$a1,$ai)=("%r14","%r15","%rbx");
        +
        +$code.=<<___;
        +.type	bn_sqr4x_mont,\@function,6
        +.align	16
        +bn_sqr4x_mont:
        +.Lsqr4x_enter:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +
        +	shl	\$3,${num}d		# convert $num to bytes
        +	xor	%r10,%r10
        +	mov	%rsp,%r11		# put aside %rsp
        +	sub	$num,%r10		# -$num
        +	mov	($n0),$n0		# *n0
        +	lea	-72(%rsp,%r10,2),%rsp	# alloca(frame+2*$num)
        +	and	\$-1024,%rsp		# minimize TLB usage
        +	##############################################################
        +	# Stack layout
        +	#
        +	# +0	saved $num, used in reduction section
        +	# +8	&t[2*$num], used in reduction section
        +	# +32	saved $rptr
        +	# +40	saved $nptr
        +	# +48	saved *n0
        +	# +56	saved %rsp
        +	# +64	t[2*$num]
        +	#
        +	mov	$rptr,32(%rsp)		# save $rptr
        +	mov	$nptr,40(%rsp)
        +	mov	$n0,  48(%rsp)
        +	mov	%r11, 56(%rsp)		# save original %rsp
        +.Lsqr4x_body:
        +	##############################################################
        +	# Squaring part:
        +	#
        +	# a) multiply-n-add everything but a[i]*a[i];
        +	# b) shift result of a) by 1 to the left and accumulate
        +	#    a[i]*a[i] products;
        +	#
        +	lea	32(%r10),$i		# $i=-($num-32)
        +	lea	($aptr,$num),$aptr	# end of a[] buffer, ($aptr,$i)=&ap[2]
        +
        +	mov	$num,$j			# $j=$num
        +
        +					# comments apply to $num==8 case
        +	mov	-32($aptr,$i),$a0	# a[0]
        +	lea	64(%rsp,$num,2),$tptr	# end of tp[] buffer, &tp[2*$num]
        +	mov	-24($aptr,$i),%rax	# a[1]
        +	lea	-32($tptr,$i),$tptr	# end of tp[] window, &tp[2*$num-"$i"]
        +	mov	-16($aptr,$i),$ai	# a[2]
        +	mov	%rax,$a1
        +
        +	mul	$a0			# a[1]*a[0]
        +	mov	%rax,$A0[0]		# a[1]*a[0]
        +	 mov	$ai,%rax		# a[2]
        +	mov	%rdx,$A0[1]
        +	mov	$A0[0],-24($tptr,$i)	# t[1]
        +
        +	xor	$A0[0],$A0[0]
        +	mul	$a0			# a[2]*a[0]
        +	add	%rax,$A0[1]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[0]
        +	mov	$A0[1],-16($tptr,$i)	# t[2]
        +
        +	lea	-16($i),$j		# j=-16
        +
        +
        +	 mov	8($aptr,$j),$ai		# a[3]
        +	mul	$a1			# a[2]*a[1]
        +	mov	%rax,$A1[0]		# a[2]*a[1]+t[3]
        +	 mov	$ai,%rax
        +	mov	%rdx,$A1[1]
        +
        +	xor	$A0[1],$A0[1]
        +	add	$A1[0],$A0[0]
        +	 lea	16($j),$j
        +	adc	\$0,$A0[1]
        +	mul	$a0			# a[3]*a[0]
        +	add	%rax,$A0[0]		# a[3]*a[0]+a[2]*a[1]+t[3]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],-8($tptr,$j)	# t[3]
        +	jmp	.Lsqr4x_1st
        +
        +.align	16
        +.Lsqr4x_1st:
        +	 mov	($aptr,$j),$ai		# a[4]
        +	xor	$A1[0],$A1[0]
        +	mul	$a1			# a[3]*a[1]
        +	add	%rax,$A1[1]		# a[3]*a[1]+t[4]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[0]
        +
        +	xor	$A0[0],$A0[0]
        +	add	$A1[1],$A0[1]
        +	adc	\$0,$A0[0]
        +	mul	$a0			# a[4]*a[0]
        +	add	%rax,$A0[1]		# a[4]*a[0]+a[3]*a[1]+t[4]
        +	 mov	$ai,%rax		# a[3]
        +	adc	%rdx,$A0[0]
        +	mov	$A0[1],($tptr,$j)	# t[4]
        +
        +
        +	 mov	8($aptr,$j),$ai		# a[5]
        +	xor	$A1[1],$A1[1]
        +	mul	$a1			# a[4]*a[3]
        +	add	%rax,$A1[0]		# a[4]*a[3]+t[5]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[1]
        +
        +	xor	$A0[1],$A0[1]
        +	add	$A1[0],$A0[0]
        +	adc	\$0,$A0[1]
        +	mul	$a0			# a[5]*a[2]
        +	add	%rax,$A0[0]		# a[5]*a[2]+a[4]*a[3]+t[5]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],8($tptr,$j)	# t[5]
        +
        +	 mov	16($aptr,$j),$ai	# a[6]
        +	xor	$A1[0],$A1[0]
        +	mul	$a1			# a[5]*a[3]
        +	add	%rax,$A1[1]		# a[5]*a[3]+t[6]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[0]
        +
        +	xor	$A0[0],$A0[0]
        +	add	$A1[1],$A0[1]
        +	adc	\$0,$A0[0]
        +	mul	$a0			# a[6]*a[2]
        +	add	%rax,$A0[1]		# a[6]*a[2]+a[5]*a[3]+t[6]
        +	 mov	$ai,%rax		# a[3]
        +	adc	%rdx,$A0[0]
        +	mov	$A0[1],16($tptr,$j)	# t[6]
        +
        +
        +	 mov	24($aptr,$j),$ai	# a[7]
        +	xor	$A1[1],$A1[1]
        +	mul	$a1			# a[6]*a[5]
        +	add	%rax,$A1[0]		# a[6]*a[5]+t[7]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[1]
        +
        +	xor	$A0[1],$A0[1]
        +	add	$A1[0],$A0[0]
        +	 lea	32($j),$j
        +	adc	\$0,$A0[1]
        +	mul	$a0			# a[7]*a[4]
        +	add	%rax,$A0[0]		# a[7]*a[4]+a[6]*a[5]+t[6]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],-8($tptr,$j)	# t[7]
        +
        +	cmp	\$0,$j
        +	jne	.Lsqr4x_1st
        +
        +	xor	$A1[0],$A1[0]
        +	add	$A0[1],$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$a1			# a[7]*a[5]
        +	add	%rax,$A1[1]
        +	adc	%rdx,$A1[0]
        +
        +	mov	$A1[1],($tptr)		# t[8]
        +	lea	16($i),$i
        +	mov	$A1[0],8($tptr)		# t[9]
        +	jmp	.Lsqr4x_outer
        +
        +.align	16
        +.Lsqr4x_outer:				# comments apply to $num==6 case
        +	mov	-32($aptr,$i),$a0	# a[0]
        +	lea	64(%rsp,$num,2),$tptr	# end of tp[] buffer, &tp[2*$num]
        +	mov	-24($aptr,$i),%rax	# a[1]
        +	lea	-32($tptr,$i),$tptr	# end of tp[] window, &tp[2*$num-"$i"]
        +	mov	-16($aptr,$i),$ai	# a[2]
        +	mov	%rax,$a1
        +
        +	mov	-24($tptr,$i),$A0[0]	# t[1]
        +	xor	$A0[1],$A0[1]
        +	mul	$a0			# a[1]*a[0]
        +	add	%rax,$A0[0]		# a[1]*a[0]+t[1]
        +	 mov	$ai,%rax		# a[2]
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],-24($tptr,$i)	# t[1]
        +
        +	xor	$A0[0],$A0[0]
        +	add	-16($tptr,$i),$A0[1]	# a[2]*a[0]+t[2]
        +	adc	\$0,$A0[0]
        +	mul	$a0			# a[2]*a[0]
        +	add	%rax,$A0[1]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[0]
        +	mov	$A0[1],-16($tptr,$i)	# t[2]
        +
        +	lea	-16($i),$j		# j=-16
        +	xor	$A1[0],$A1[0]
        +
        +
        +	 mov	8($aptr,$j),$ai		# a[3]
        +	xor	$A1[1],$A1[1]
        +	add	8($tptr,$j),$A1[0]
        +	adc	\$0,$A1[1]
        +	mul	$a1			# a[2]*a[1]
        +	add	%rax,$A1[0]		# a[2]*a[1]+t[3]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[1]
        +
        +	xor	$A0[1],$A0[1]
        +	add	$A1[0],$A0[0]
        +	adc	\$0,$A0[1]
        +	mul	$a0			# a[3]*a[0]
        +	add	%rax,$A0[0]		# a[3]*a[0]+a[2]*a[1]+t[3]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],8($tptr,$j)	# t[3]
        +
        +	lea	16($j),$j
        +	jmp	.Lsqr4x_inner
        +
        +.align	16
        +.Lsqr4x_inner:
        +	 mov	($aptr,$j),$ai		# a[4]
        +	xor	$A1[0],$A1[0]
        +	add	($tptr,$j),$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$a1			# a[3]*a[1]
        +	add	%rax,$A1[1]		# a[3]*a[1]+t[4]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[0]
        +
        +	xor	$A0[0],$A0[0]
        +	add	$A1[1],$A0[1]
        +	adc	\$0,$A0[0]
        +	mul	$a0			# a[4]*a[0]
        +	add	%rax,$A0[1]		# a[4]*a[0]+a[3]*a[1]+t[4]
        +	 mov	$ai,%rax		# a[3]
        +	adc	%rdx,$A0[0]
        +	mov	$A0[1],($tptr,$j)	# t[4]
        +
        +	 mov	8($aptr,$j),$ai		# a[5]
        +	xor	$A1[1],$A1[1]
        +	add	8($tptr,$j),$A1[0]
        +	adc	\$0,$A1[1]
        +	mul	$a1			# a[4]*a[3]
        +	add	%rax,$A1[0]		# a[4]*a[3]+t[5]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A1[1]
        +
        +	xor	$A0[1],$A0[1]
        +	add	$A1[0],$A0[0]
        +	lea	16($j),$j		# j++
        +	adc	\$0,$A0[1]
        +	mul	$a0			# a[5]*a[2]
        +	add	%rax,$A0[0]		# a[5]*a[2]+a[4]*a[3]+t[5]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],-8($tptr,$j)	# t[5], "preloaded t[1]" below
        +
        +	cmp	\$0,$j
        +	jne	.Lsqr4x_inner
        +
        +	xor	$A1[0],$A1[0]
        +	add	$A0[1],$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$a1			# a[5]*a[3]
        +	add	%rax,$A1[1]
        +	adc	%rdx,$A1[0]
        +
        +	mov	$A1[1],($tptr)		# t[6], "preloaded t[2]" below
        +	mov	$A1[0],8($tptr)		# t[7], "preloaded t[3]" below
        +
        +	add	\$16,$i
        +	jnz	.Lsqr4x_outer
        +
        +					# comments apply to $num==4 case
        +	mov	-32($aptr),$a0		# a[0]
        +	lea	64(%rsp,$num,2),$tptr	# end of tp[] buffer, &tp[2*$num]
        +	mov	-24($aptr),%rax		# a[1]
        +	lea	-32($tptr,$i),$tptr	# end of tp[] window, &tp[2*$num-"$i"]
        +	mov	-16($aptr),$ai		# a[2]
        +	mov	%rax,$a1
        +
        +	xor	$A0[1],$A0[1]
        +	mul	$a0			# a[1]*a[0]
        +	add	%rax,$A0[0]		# a[1]*a[0]+t[1], preloaded t[1]
        +	 mov	$ai,%rax		# a[2]
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],-24($tptr)	# t[1]
        +
        +	xor	$A0[0],$A0[0]
        +	add	$A1[1],$A0[1]		# a[2]*a[0]+t[2], preloaded t[2]
        +	adc	\$0,$A0[0]
        +	mul	$a0			# a[2]*a[0]
        +	add	%rax,$A0[1]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[0]
        +	mov	$A0[1],-16($tptr)	# t[2]
        +
        +	 mov	-8($aptr),$ai		# a[3]
        +	mul	$a1			# a[2]*a[1]
        +	add	%rax,$A1[0]		# a[2]*a[1]+t[3], preloaded t[3]
        +	 mov	$ai,%rax
        +	adc	\$0,%rdx
        +
        +	xor	$A0[1],$A0[1]
        +	add	$A1[0],$A0[0]
        +	 mov	%rdx,$A1[1]
        +	adc	\$0,$A0[1]
        +	mul	$a0			# a[3]*a[0]
        +	add	%rax,$A0[0]		# a[3]*a[0]+a[2]*a[1]+t[3]
        +	 mov	$ai,%rax
        +	adc	%rdx,$A0[1]
        +	mov	$A0[0],-8($tptr)	# t[3]
        +
        +	xor	$A1[0],$A1[0]
        +	add	$A0[1],$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$a1			# a[3]*a[1]
        +	add	%rax,$A1[1]
        +	 mov	-16($aptr),%rax		# a[2]
        +	adc	%rdx,$A1[0]
        +
        +	mov	$A1[1],($tptr)		# t[4]
        +	mov	$A1[0],8($tptr)		# t[5]
        +
        +	mul	$ai			# a[2]*a[3]
        +___
        +{
        +my ($shift,$carry)=($a0,$a1);
        +my @S=(@A1,$ai,$n0);
        +$code.=<<___;
        +	 add	\$16,$i
        +	 xor	$shift,$shift
        +	 sub	$num,$i			# $i=16-$num
        +	 xor	$carry,$carry
        +
        +	add	$A1[0],%rax		# t[5]
        +	adc	\$0,%rdx
        +	mov	%rax,8($tptr)		# t[5]
        +	mov	%rdx,16($tptr)		# t[6]
        +	mov	$carry,24($tptr)	# t[7]
        +
        +	 mov	-16($aptr,$i),%rax	# a[0]
        +	lea	64(%rsp,$num,2),$tptr
        +	 xor	$A0[0],$A0[0]		# t[0]
        +	 mov	-24($tptr,$i,2),$A0[1]	# t[1]
        +
        +	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[1]		# | t[2*i]>>63
        +	 mov	-16($tptr,$i,2),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	-8($tptr,$i,2),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[0]
        +	 mov	-8($aptr,$i),%rax	# a[i+1]	# prefetch
        +	mov	$S[0],-32($tptr,$i,2)
        +	adc	%rdx,$S[1]
        +
        +	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1 | shift
        +	 mov	$S[1],-24($tptr,$i,2)
        +	 sbb	$carry,$carry		# mov cf,$carry
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[3]		# | t[2*i]>>63
        +	 mov	0($tptr,$i,2),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	8($tptr,$i,2),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[2]
        +	 mov	0($aptr,$i),%rax	# a[i+1]	# prefetch
        +	mov	$S[2],-16($tptr,$i,2)
        +	adc	%rdx,$S[3]
        +	lea	16($i),$i
        +	mov	$S[3],-40($tptr,$i,2)
        +	sbb	$carry,$carry		# mov cf,$carry
        +	jmp	.Lsqr4x_shift_n_add
        +
        +.align	16
        +.Lsqr4x_shift_n_add:
        +	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[1]		# | t[2*i]>>63
        +	 mov	-16($tptr,$i,2),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	-8($tptr,$i,2),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[0]
        +	 mov	-8($aptr,$i),%rax	# a[i+1]	# prefetch
        +	mov	$S[0],-32($tptr,$i,2)
        +	adc	%rdx,$S[1]
        +
        +	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1 | shift
        +	 mov	$S[1],-24($tptr,$i,2)
        +	 sbb	$carry,$carry		# mov cf,$carry
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[3]		# | t[2*i]>>63
        +	 mov	0($tptr,$i,2),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	8($tptr,$i,2),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[2]
        +	 mov	0($aptr,$i),%rax	# a[i+1]	# prefetch
        +	mov	$S[2],-16($tptr,$i,2)
        +	adc	%rdx,$S[3]
        +
        +	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
        +	 mov	$S[3],-8($tptr,$i,2)
        +	 sbb	$carry,$carry		# mov cf,$carry
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[1]		# | t[2*i]>>63
        +	 mov	16($tptr,$i,2),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	24($tptr,$i,2),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[0]
        +	 mov	8($aptr,$i),%rax	# a[i+1]	# prefetch
        +	mov	$S[0],0($tptr,$i,2)
        +	adc	%rdx,$S[1]
        +
        +	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1 | shift
        +	 mov	$S[1],8($tptr,$i,2)
        +	 sbb	$carry,$carry		# mov cf,$carry
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[3]		# | t[2*i]>>63
        +	 mov	32($tptr,$i,2),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	40($tptr,$i,2),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[2]
        +	 mov	16($aptr,$i),%rax	# a[i+1]	# prefetch
        +	mov	$S[2],16($tptr,$i,2)
        +	adc	%rdx,$S[3]
        +	mov	$S[3],24($tptr,$i,2)
        +	sbb	$carry,$carry		# mov cf,$carry
        +	add	\$32,$i
        +	jnz	.Lsqr4x_shift_n_add
        +
        +	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[1]		# | t[2*i]>>63
        +	 mov	-16($tptr),$A0[0]	# t[2*i+2]	# prefetch
        +	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	 mov	-8($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
        +	adc	%rax,$S[0]
        +	 mov	-8($aptr),%rax		# a[i+1]	# prefetch
        +	mov	$S[0],-32($tptr)
        +	adc	%rdx,$S[1]
        +
        +	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1|shift
        +	 mov	$S[1],-24($tptr)
        +	 sbb	$carry,$carry		# mov cf,$carry
        +	shr	\$63,$A0[0]
        +	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
        +	shr	\$63,$A0[1]
        +	or	$A0[0],$S[3]		# | t[2*i]>>63
        +	mul	%rax			# a[i]*a[i]
        +	neg	$carry			# mov $carry,cf
        +	adc	%rax,$S[2]
        +	adc	%rdx,$S[3]
        +	mov	$S[2],-16($tptr)
        +	mov	$S[3],-8($tptr)
        +___
        +}
        +##############################################################
        +# Montgomery reduction part, "word-by-word" algorithm.
        +#
        +{
        +my ($topbit,$nptr)=("%rbp",$aptr);
        +my ($m0,$m1)=($a0,$a1);
        +my @Ni=("%rbx","%r9");
        +$code.=<<___;
        +	mov	40(%rsp),$nptr		# restore $nptr
        +	mov	48(%rsp),$n0		# restore *n0
        +	xor	$j,$j
        +	mov	$num,0(%rsp)		# save $num
        +	sub	$num,$j			# $j=-$num
        +	 mov	64(%rsp),$A0[0]		# t[0]		# modsched #
        +	 mov	$n0,$m0			#		# modsched #
        +	lea	64(%rsp,$num,2),%rax	# end of t[] buffer
        +	lea	64(%rsp,$num),$tptr	# end of t[] window
        +	mov	%rax,8(%rsp)		# save end of t[] buffer
        +	lea	($nptr,$num),$nptr	# end of n[] buffer
        +	xor	$topbit,$topbit		# $topbit=0
        +
        +	mov	0($nptr,$j),%rax	# n[0]		# modsched #
        +	mov	8($nptr,$j),$Ni[1]	# n[1]		# modsched #
        +	 imulq	$A0[0],$m0		# m0=t[0]*n0	# modsched #
        +	 mov	%rax,$Ni[0]		#		# modsched #
        +	jmp	.Lsqr4x_mont_outer
        +
        +.align	16
        +.Lsqr4x_mont_outer:
        +	xor	$A0[1],$A0[1]
        +	mul	$m0			# n[0]*m0
        +	add	%rax,$A0[0]		# n[0]*m0+t[0]
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A0[1]
        +	mov	$n0,$m1
        +
        +	xor	$A0[0],$A0[0]
        +	add	8($tptr,$j),$A0[1]
        +	adc	\$0,$A0[0]
        +	mul	$m0			# n[1]*m0
        +	add	%rax,$A0[1]		# n[1]*m0+t[1]
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A0[0]
        +
        +	imulq	$A0[1],$m1
        +
        +	mov	16($nptr,$j),$Ni[0]	# n[2]
        +	xor	$A1[1],$A1[1]
        +	add	$A0[1],$A1[0]
        +	adc	\$0,$A1[1]
        +	mul	$m1			# n[0]*m1
        +	add	%rax,$A1[0]		# n[0]*m1+"t[1]"
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A1[1]
        +	mov	$A1[0],8($tptr,$j)	# "t[1]"
        +
        +	xor	$A0[1],$A0[1]
        +	add	16($tptr,$j),$A0[0]
        +	adc	\$0,$A0[1]
        +	mul	$m0			# n[2]*m0
        +	add	%rax,$A0[0]		# n[2]*m0+t[2]
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A0[1]
        +
        +	mov	24($nptr,$j),$Ni[1]	# n[3]
        +	xor	$A1[0],$A1[0]
        +	add	$A0[0],$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$m1			# n[1]*m1
        +	add	%rax,$A1[1]		# n[1]*m1+"t[2]"
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A1[0]
        +	mov	$A1[1],16($tptr,$j)	# "t[2]"
        +
        +	xor	$A0[0],$A0[0]
        +	add	24($tptr,$j),$A0[1]
        +	lea	32($j),$j
        +	adc	\$0,$A0[0]
        +	mul	$m0			# n[3]*m0
        +	add	%rax,$A0[1]		# n[3]*m0+t[3]
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A0[0]
        +	jmp	.Lsqr4x_mont_inner
        +
        +.align	16
        +.Lsqr4x_mont_inner:
        +	mov	($nptr,$j),$Ni[0]	# n[4]
        +	xor	$A1[1],$A1[1]
        +	add	$A0[1],$A1[0]
        +	adc	\$0,$A1[1]
        +	mul	$m1			# n[2]*m1
        +	add	%rax,$A1[0]		# n[2]*m1+"t[3]"
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A1[1]
        +	mov	$A1[0],-8($tptr,$j)	# "t[3]"
        +
        +	xor	$A0[1],$A0[1]
        +	add	($tptr,$j),$A0[0]
        +	adc	\$0,$A0[1]
        +	mul	$m0			# n[4]*m0
        +	add	%rax,$A0[0]		# n[4]*m0+t[4]
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A0[1]
        +
        +	mov	8($nptr,$j),$Ni[1]	# n[5]
        +	xor	$A1[0],$A1[0]
        +	add	$A0[0],$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$m1			# n[3]*m1
        +	add	%rax,$A1[1]		# n[3]*m1+"t[4]"
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A1[0]
        +	mov	$A1[1],($tptr,$j)	# "t[4]"
        +
        +	xor	$A0[0],$A0[0]
        +	add	8($tptr,$j),$A0[1]
        +	adc	\$0,$A0[0]
        +	mul	$m0			# n[5]*m0
        +	add	%rax,$A0[1]		# n[5]*m0+t[5]
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A0[0]
        +
        +
        +	mov	16($nptr,$j),$Ni[0]	# n[6]
        +	xor	$A1[1],$A1[1]
        +	add	$A0[1],$A1[0]
        +	adc	\$0,$A1[1]
        +	mul	$m1			# n[4]*m1
        +	add	%rax,$A1[0]		# n[4]*m1+"t[5]"
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A1[1]
        +	mov	$A1[0],8($tptr,$j)	# "t[5]"
        +
        +	xor	$A0[1],$A0[1]
        +	add	16($tptr,$j),$A0[0]
        +	adc	\$0,$A0[1]
        +	mul	$m0			# n[6]*m0
        +	add	%rax,$A0[0]		# n[6]*m0+t[6]
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A0[1]
        +
        +	mov	24($nptr,$j),$Ni[1]	# n[7]
        +	xor	$A1[0],$A1[0]
        +	add	$A0[0],$A1[1]
        +	adc	\$0,$A1[0]
        +	mul	$m1			# n[5]*m1
        +	add	%rax,$A1[1]		# n[5]*m1+"t[6]"
        +	 mov	$Ni[1],%rax
        +	adc	%rdx,$A1[0]
        +	mov	$A1[1],16($tptr,$j)	# "t[6]"
        +
        +	xor	$A0[0],$A0[0]
        +	add	24($tptr,$j),$A0[1]
        +	lea	32($j),$j
        +	adc	\$0,$A0[0]
        +	mul	$m0			# n[7]*m0
        +	add	%rax,$A0[1]		# n[7]*m0+t[7]
        +	 mov	$Ni[0],%rax
        +	adc	%rdx,$A0[0]
        +	cmp	\$0,$j
        +	jne	.Lsqr4x_mont_inner
        +
        +	 sub	0(%rsp),$j		# $j=-$num	# modsched #
        +	 mov	$n0,$m0			#		# modsched #
        +
        +	xor	$A1[1],$A1[1]
        +	add	$A0[1],$A1[0]
        +	adc	\$0,$A1[1]
        +	mul	$m1			# n[6]*m1
        +	add	%rax,$A1[0]		# n[6]*m1+"t[7]"
        +	mov	$Ni[1],%rax
        +	adc	%rdx,$A1[1]
        +	mov	$A1[0],-8($tptr)	# "t[7]"
        +
        +	xor	$A0[1],$A0[1]
        +	add	($tptr),$A0[0]		# +t[8]
        +	adc	\$0,$A0[1]
        +	 mov	0($nptr,$j),$Ni[0]	# n[0]		# modsched #
        +	add	$topbit,$A0[0]
        +	adc	\$0,$A0[1]
        +
        +	 imulq	16($tptr,$j),$m0	# m0=t[0]*n0	# modsched #
        +	xor	$A1[0],$A1[0]
        +	 mov	8($nptr,$j),$Ni[1]	# n[1]		# modsched #
        +	add	$A0[0],$A1[1]
        +	 mov	16($tptr,$j),$A0[0]	# t[0]		# modsched #
        +	adc	\$0,$A1[0]
        +	mul	$m1			# n[7]*m1
        +	add	%rax,$A1[1]		# n[7]*m1+"t[8]"
        +	 mov	$Ni[0],%rax		#		# modsched #
        +	adc	%rdx,$A1[0]
        +	mov	$A1[1],($tptr)		# "t[8]"
        +
        +	xor	$topbit,$topbit
        +	add	8($tptr),$A1[0]		# +t[9]
        +	adc	$topbit,$topbit
        +	add	$A0[1],$A1[0]
        +	lea	16($tptr),$tptr		# "t[$num]>>128"
        +	adc	\$0,$topbit
        +	mov	$A1[0],-8($tptr)	# "t[9]"
        +	cmp	8(%rsp),$tptr		# are we done?
        +	jb	.Lsqr4x_mont_outer
        +
        +	mov	0(%rsp),$num		# restore $num
        +	mov	$topbit,($tptr)		# save $topbit
        +___
        +}
        +##############################################################
        +# Post-condition, 4x unrolled copy from bn_mul_mont
        +#
        +{
        +my ($tptr,$nptr)=("%rbx",$aptr);
        +my @ri=("%rax","%rdx","%r10","%r11");
        +$code.=<<___;
        +	mov	64(%rsp,$num),@ri[0]	# tp[0]
        +	lea	64(%rsp,$num),$tptr	# upper half of t[2*$num] holds result
        +	mov	40(%rsp),$nptr		# restore $nptr
        +	shr	\$5,$num		# num/4
        +	mov	8($tptr),@ri[1]		# t[1]
        +	xor	$i,$i			# i=0 and clear CF!
        +
        +	mov	32(%rsp),$rptr		# restore $rptr
        +	sub	0($nptr),@ri[0]
        +	mov	16($tptr),@ri[2]	# t[2]
        +	mov	24($tptr),@ri[3]	# t[3]
        +	sbb	8($nptr),@ri[1]
        +	lea	-1($num),$j		# j=num/4-1
        +	jmp	.Lsqr4x_sub
        +.align	16
        +.Lsqr4x_sub:
        +	mov	@ri[0],0($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	@ri[1],8($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	16($nptr,$i,8),@ri[2]
        +	mov	32($tptr,$i,8),@ri[0]	# tp[i+1]
        +	mov	40($tptr,$i,8),@ri[1]
        +	sbb	24($nptr,$i,8),@ri[3]
        +	mov	@ri[2],16($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	@ri[3],24($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	32($nptr,$i,8),@ri[0]
        +	mov	48($tptr,$i,8),@ri[2]
        +	mov	56($tptr,$i,8),@ri[3]
        +	sbb	40($nptr,$i,8),@ri[1]
        +	lea	4($i),$i		# i++
        +	dec	$j			# doesn't affect CF!
        +	jnz	.Lsqr4x_sub
        +
        +	mov	@ri[0],0($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	32($tptr,$i,8),@ri[0]	# load overflow bit
        +	sbb	16($nptr,$i,8),@ri[2]
        +	mov	@ri[1],8($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	24($nptr,$i,8),@ri[3]
        +	mov	@ri[2],16($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +
        +	sbb	\$0,@ri[0]		# handle upmost overflow bit
        +	mov	@ri[3],24($rptr,$i,8)	# rp[i]=tp[i]-np[i]
        +	xor	$i,$i			# i=0
        +	and	@ri[0],$tptr
        +	not	@ri[0]
        +	mov	$rptr,$nptr
        +	and	@ri[0],$nptr
        +	lea	-1($num),$j
        +	or	$nptr,$tptr		# tp=borrow?tp:rp
        +
        +	pxor	%xmm0,%xmm0
        +	lea	64(%rsp,$num,8),$nptr
        +	movdqu	($tptr),%xmm1
        +	lea	($nptr,$num,8),$nptr
        +	movdqa	%xmm0,64(%rsp)		# zap lower half of temporary vector
        +	movdqa	%xmm0,($nptr)		# zap upper half of temporary vector
        +	movdqu	%xmm1,($rptr)
        +	jmp	.Lsqr4x_copy
        +.align	16
        +.Lsqr4x_copy:				# copy or in-place refresh
        +	movdqu	16($tptr,$i),%xmm2
        +	movdqu	32($tptr,$i),%xmm1
        +	movdqa	%xmm0,80(%rsp,$i)	# zap lower half of temporary vector
        +	movdqa	%xmm0,96(%rsp,$i)	# zap lower half of temporary vector
        +	movdqa	%xmm0,16($nptr,$i)	# zap upper half of temporary vector
        +	movdqa	%xmm0,32($nptr,$i)	# zap upper half of temporary vector
        +	movdqu	%xmm2,16($rptr,$i)
        +	movdqu	%xmm1,32($rptr,$i)
        +	lea	32($i),$i
        +	dec	$j
        +	jnz	.Lsqr4x_copy
        +
        +	movdqu	16($tptr,$i),%xmm2
        +	movdqa	%xmm0,80(%rsp,$i)	# zap lower half of temporary vector
        +	movdqa	%xmm0,16($nptr,$i)	# zap upper half of temporary vector
        +	movdqu	%xmm2,16($rptr,$i)
        +___
        +}
        +$code.=<<___;
        +	mov	56(%rsp),%rsi		# restore %rsp
        +	mov	\$1,%rax
        +	mov	0(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lsqr4x_epilogue:
        +	ret
        +.size	bn_sqr4x_mont,.-bn_sqr4x_mont
        +___
        +}}}
        +$code.=<<___;
        +.asciz	"Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	16
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	mul_handler,\@abi-omnipotent
        +.align	16
        +mul_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# end of prologue label
        +	cmp	%r10,%rbx		# context->Rip<end of prologue label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lcommon_seh_tail
        +
        +	mov	192($context),%r10	# pull $num
        +	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
        +	lea	48(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +	jmp	.Lcommon_seh_tail
        +.size	mul_handler,.-mul_handler
        +
        +.type	sqr_handler,\@abi-omnipotent
        +.align	16
        +sqr_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lsqr4x_body(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lsqr_body
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lsqr4x_epilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lsqr_epilogue
        +	jae	.Lcommon_seh_tail
        +
        +	mov	56(%rax),%rax		# pull saved stack pointer
        +	lea	48(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lcommon_seh_tail:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	sqr_handler,.-sqr_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_bn_mul_mont
        +	.rva	.LSEH_end_bn_mul_mont
        +	.rva	.LSEH_info_bn_mul_mont
        +
        +	.rva	.LSEH_begin_bn_mul4x_mont
        +	.rva	.LSEH_end_bn_mul4x_mont
        +	.rva	.LSEH_info_bn_mul4x_mont
        +
        +	.rva	.LSEH_begin_bn_sqr4x_mont
        +	.rva	.LSEH_end_bn_sqr4x_mont
        +	.rva	.LSEH_info_bn_sqr4x_mont
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_bn_mul_mont:
        +	.byte	9,0,0,0
        +	.rva	mul_handler
        +	.rva	.Lmul_body,.Lmul_epilogue	# HandlerData[]
        +.LSEH_info_bn_mul4x_mont:
        +	.byte	9,0,0,0
        +	.rva	mul_handler
        +	.rva	.Lmul4x_body,.Lmul4x_epilogue	# HandlerData[]
        +.LSEH_info_bn_sqr4x_mont:
        +	.byte	9,0,0,0
        +	.rva	sqr_handler
        +___
        +}
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl b/vendor/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl
        new file mode 100644
        index 000000000..8f8dc5a59
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl
        @@ -0,0 +1,1071 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# August 2011.
        +#
        +# Companion to x86_64-mont.pl that optimizes cache-timing attack
        +# countermeasures. The subroutines are produced by replacing bp[i]
        +# references in their x86_64-mont.pl counterparts with cache-neutral
        +# references to powers table computed in BN_mod_exp_mont_consttime.
        +# In addition subroutine that scatters elements of the powers table
        +# is implemented, so that scatter-/gathering can be tuned without
        +# bn_exp.c modifications.
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +# int bn_mul_mont_gather5(
        +$rp="%rdi";	# BN_ULONG *rp,
        +$ap="%rsi";	# const BN_ULONG *ap,
        +$bp="%rdx";	# const BN_ULONG *bp,
        +$np="%rcx";	# const BN_ULONG *np,
        +$n0="%r8";	# const BN_ULONG *n0,
        +$num="%r9";	# int num,
        +		# int idx);	# 0 to 2^5-1, "index" in $bp holding
        +				# pre-computed powers of a', interlaced
        +				# in such manner that b[0] is $bp[idx],
        +				# b[1] is [2^5+idx], etc.
        +$lo0="%r10";
        +$hi0="%r11";
        +$hi1="%r13";
        +$i="%r14";
        +$j="%r15";
        +$m0="%rbx";
        +$m1="%rbp";
        +
        +$code=<<___;
        +.text
        +
        +.globl	bn_mul_mont_gather5
        +.type	bn_mul_mont_gather5,\@function,6
        +.align	64
        +bn_mul_mont_gather5:
        +	test	\$3,${num}d
        +	jnz	.Lmul_enter
        +	cmp	\$8,${num}d
        +	jb	.Lmul_enter
        +	jmp	.Lmul4x_enter
        +
        +.align	16
        +.Lmul_enter:
        +	mov	${num}d,${num}d
        +	mov	`($win64?56:8)`(%rsp),%r10d	# load 7th argument
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0x28(%rsp),%rsp
        +	movaps	%xmm6,(%rsp)
        +	movaps	%xmm7,0x10(%rsp)
        +.Lmul_alloca:
        +___
        +$code.=<<___;
        +	mov	%rsp,%rax
        +	lea	2($num),%r11
        +	neg	%r11
        +	lea	(%rsp,%r11,8),%rsp	# tp=alloca(8*(num+2))
        +	and	\$-1024,%rsp		# minimize TLB usage
        +
        +	mov	%rax,8(%rsp,$num,8)	# tp[num+1]=%rsp
        +.Lmul_body:
        +	mov	$bp,%r12		# reassign $bp
        +___
        +		$bp="%r12";
        +		$STRIDE=2**5*8;		# 5 is "window size"
        +		$N=$STRIDE/4;		# should match cache line size
        +$code.=<<___;
        +	mov	%r10,%r11
        +	shr	\$`log($N/8)/log(2)`,%r10
        +	and	\$`$N/8-1`,%r11
        +	not	%r10
        +	lea	.Lmagic_masks(%rip),%rax
        +	and	\$`2**5/($N/8)-1`,%r10	# 5 is "window size"
        +	lea	96($bp,%r11,8),$bp	# pointer within 1st cache line
        +	movq	0(%rax,%r10,8),%xmm4	# set of masks denoting which
        +	movq	8(%rax,%r10,8),%xmm5	# cache line contains element
        +	movq	16(%rax,%r10,8),%xmm6	# denoted by 7th argument
        +	movq	24(%rax,%r10,8),%xmm7
        +
        +	movq	`0*$STRIDE/4-96`($bp),%xmm0
        +	movq	`1*$STRIDE/4-96`($bp),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($bp),%xmm2
        +	pand	%xmm5,%xmm1
        +	movq	`3*$STRIDE/4-96`($bp),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($bp),$bp
        +	por	%xmm3,%xmm0
        +
        +	movq	%xmm0,$m0		# m0=bp[0]
        +
        +	mov	($n0),$n0		# pull n0[0] value
        +	mov	($ap),%rax
        +
        +	xor	$i,$i			# i=0
        +	xor	$j,$j			# j=0
        +
        +	movq	`0*$STRIDE/4-96`($bp),%xmm0
        +	movq	`1*$STRIDE/4-96`($bp),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($bp),%xmm2
        +	pand	%xmm5,%xmm1
        +
        +	mov	$n0,$m1
        +	mulq	$m0			# ap[0]*bp[0]
        +	mov	%rax,$lo0
        +	mov	($np),%rax
        +
        +	movq	`3*$STRIDE/4-96`($bp),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +
        +	imulq	$lo0,$m1		# "tp[0]"*n0
        +	mov	%rdx,$hi0
        +
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($bp),$bp
        +	por	%xmm3,%xmm0
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$lo0		# discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$hi1
        +
        +	lea	1($j),$j		# j++
        +	jmp	.L1st_enter
        +
        +.align	16
        +.L1st:
        +	add	%rax,$hi1
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
        +	mov	$lo0,$hi0
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +
        +.L1st_enter:
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$hi0
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	lea	1($j),$j		# j++
        +	mov	%rdx,$lo0
        +
        +	mulq	$m1			# np[j]*m1
        +	cmp	$num,$j
        +	jne	.L1st
        +
        +	movq	%xmm0,$m0		# bp[1]
        +
        +	add	%rax,$hi1
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +	mov	$lo0,$hi0
        +
        +	xor	%rdx,%rdx
        +	add	$hi0,$hi1
        +	adc	\$0,%rdx
        +	mov	$hi1,-8(%rsp,$num,8)
        +	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
        +
        +	lea	1($i),$i		# i++
        +	jmp	.Louter
        +.align	16
        +.Louter:
        +	xor	$j,$j			# j=0
        +	mov	$n0,$m1
        +	mov	(%rsp),$lo0
        +
        +	movq	`0*$STRIDE/4-96`($bp),%xmm0
        +	movq	`1*$STRIDE/4-96`($bp),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($bp),%xmm2
        +	pand	%xmm5,%xmm1
        +
        +	mulq	$m0			# ap[0]*bp[i]
        +	add	%rax,$lo0		# ap[0]*bp[i]+tp[0]
        +	mov	($np),%rax
        +	adc	\$0,%rdx
        +
        +	movq	`3*$STRIDE/4-96`($bp),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +
        +	imulq	$lo0,$m1		# tp[0]*n0
        +	mov	%rdx,$hi0
        +
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($bp),$bp
        +	por	%xmm3,%xmm0
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$lo0		# discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	8(%rsp),$lo0		# tp[1]
        +	mov	%rdx,$hi1
        +
        +	lea	1($j),$j		# j++
        +	jmp	.Linner_enter
        +
        +.align	16
        +.Linner:
        +	add	%rax,$hi1
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
        +	mov	(%rsp,$j,8),$lo0
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +
        +.Linner_enter:
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$hi0
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$hi0,$lo0		# ap[j]*bp[i]+tp[j]
        +	mov	%rdx,$hi0
        +	adc	\$0,$hi0
        +	lea	1($j),$j		# j++
        +
        +	mulq	$m1			# np[j]*m1
        +	cmp	$num,$j
        +	jne	.Linner
        +
        +	movq	%xmm0,$m0		# bp[i+1]
        +
        +	add	%rax,$hi1
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
        +	mov	(%rsp,$j,8),$lo0
        +	adc	\$0,%rdx
        +	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$hi1
        +
        +	xor	%rdx,%rdx
        +	add	$hi0,$hi1
        +	adc	\$0,%rdx
        +	add	$lo0,$hi1		# pull upmost overflow bit
        +	adc	\$0,%rdx
        +	mov	$hi1,-8(%rsp,$num,8)
        +	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
        +
        +	lea	1($i),$i		# i++
        +	cmp	$num,$i
        +	jl	.Louter
        +
        +	xor	$i,$i			# i=0 and clear CF!
        +	mov	(%rsp),%rax		# tp[0]
        +	lea	(%rsp),$ap		# borrow ap for tp
        +	mov	$num,$j			# j=num
        +	jmp	.Lsub
        +.align	16
        +.Lsub:	sbb	($np,$i,8),%rax
        +	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]-np[i]
        +	mov	8($ap,$i,8),%rax	# tp[i+1]
        +	lea	1($i),$i		# i++
        +	dec	$j			# doesnn't affect CF!
        +	jnz	.Lsub
        +
        +	sbb	\$0,%rax		# handle upmost overflow bit
        +	xor	$i,$i
        +	and	%rax,$ap
        +	not	%rax
        +	mov	$rp,$np
        +	and	%rax,$np
        +	mov	$num,$j			# j=num
        +	or	$np,$ap			# ap=borrow?tp:rp
        +.align	16
        +.Lcopy:					# copy or in-place refresh
        +	mov	($ap,$i,8),%rax
        +	mov	$i,(%rsp,$i,8)		# zap temporary vector
        +	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]
        +	lea	1($i),$i
        +	sub	\$1,$j
        +	jnz	.Lcopy
        +
        +	mov	8(%rsp,$num,8),%rsi	# restore %rsp
        +	mov	\$1,%rax
        +___
        +$code.=<<___ if ($win64);
        +	movaps	(%rsi),%xmm6
        +	movaps	0x10(%rsi),%xmm7
        +	lea	0x28(%rsi),%rsi
        +___
        +$code.=<<___;
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lmul_epilogue:
        +	ret
        +.size	bn_mul_mont_gather5,.-bn_mul_mont_gather5
        +___
        +{{{
        +my @A=("%r10","%r11");
        +my @N=("%r13","%rdi");
        +$code.=<<___;
        +.type	bn_mul4x_mont_gather5,\@function,6
        +.align	16
        +bn_mul4x_mont_gather5:
        +.Lmul4x_enter:
        +	mov	${num}d,${num}d
        +	mov	`($win64?56:8)`(%rsp),%r10d	# load 7th argument
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +___
        +$code.=<<___ if ($win64);
        +	lea	-0x28(%rsp),%rsp
        +	movaps	%xmm6,(%rsp)
        +	movaps	%xmm7,0x10(%rsp)
        +.Lmul4x_alloca:
        +___
        +$code.=<<___;
        +	mov	%rsp,%rax
        +	lea	4($num),%r11
        +	neg	%r11
        +	lea	(%rsp,%r11,8),%rsp	# tp=alloca(8*(num+4))
        +	and	\$-1024,%rsp		# minimize TLB usage
        +
        +	mov	%rax,8(%rsp,$num,8)	# tp[num+1]=%rsp
        +.Lmul4x_body:
        +	mov	$rp,16(%rsp,$num,8)	# tp[num+2]=$rp
        +	mov	%rdx,%r12		# reassign $bp
        +___
        +		$bp="%r12";
        +		$STRIDE=2**5*8;		# 5 is "window size"
        +		$N=$STRIDE/4;		# should match cache line size
        +$code.=<<___;
        +	mov	%r10,%r11
        +	shr	\$`log($N/8)/log(2)`,%r10
        +	and	\$`$N/8-1`,%r11
        +	not	%r10
        +	lea	.Lmagic_masks(%rip),%rax
        +	and	\$`2**5/($N/8)-1`,%r10	# 5 is "window size"
        +	lea	96($bp,%r11,8),$bp	# pointer within 1st cache line
        +	movq	0(%rax,%r10,8),%xmm4	# set of masks denoting which
        +	movq	8(%rax,%r10,8),%xmm5	# cache line contains element
        +	movq	16(%rax,%r10,8),%xmm6	# denoted by 7th argument
        +	movq	24(%rax,%r10,8),%xmm7
        +
        +	movq	`0*$STRIDE/4-96`($bp),%xmm0
        +	movq	`1*$STRIDE/4-96`($bp),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($bp),%xmm2
        +	pand	%xmm5,%xmm1
        +	movq	`3*$STRIDE/4-96`($bp),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($bp),$bp
        +	por	%xmm3,%xmm0
        +
        +	movq	%xmm0,$m0		# m0=bp[0]
        +	mov	($n0),$n0		# pull n0[0] value
        +	mov	($ap),%rax
        +
        +	xor	$i,$i			# i=0
        +	xor	$j,$j			# j=0
        +
        +	movq	`0*$STRIDE/4-96`($bp),%xmm0
        +	movq	`1*$STRIDE/4-96`($bp),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($bp),%xmm2
        +	pand	%xmm5,%xmm1
        +
        +	mov	$n0,$m1
        +	mulq	$m0			# ap[0]*bp[0]
        +	mov	%rax,$A[0]
        +	mov	($np),%rax
        +
        +	movq	`3*$STRIDE/4-96`($bp),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +
        +	imulq	$A[0],$m1		# "tp[0]"*n0
        +	mov	%rdx,$A[1]
        +
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($bp),$bp
        +	por	%xmm3,%xmm0
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$A[0]		# discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0
        +	add	%rax,$A[1]
        +	mov	8($np),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1
        +	add	%rax,$N[1]
        +	mov	16($ap),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	lea	4($j),$j		# j++
        +	adc	\$0,%rdx
        +	mov	$N[1],(%rsp)
        +	mov	%rdx,$N[0]
        +	jmp	.L1st4x
        +.align	16
        +.L1st4x:
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[0]
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-8(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[1]
        +	mov	8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	lea	4($j),$j		# j++
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	-16($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +	cmp	$num,$j
        +	jl	.L1st4x
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[0]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	movq	%xmm0,$m0		# bp[1]
        +
        +	xor	$N[1],$N[1]
        +	add	$A[0],$N[0]
        +	adc	\$0,$N[1]
        +	mov	$N[0],-8(%rsp,$j,8)
        +	mov	$N[1],(%rsp,$j,8)	# store upmost overflow bit
        +
        +	lea	1($i),$i		# i++
        +.align	4
        +.Louter4x:
        +	xor	$j,$j			# j=0
        +	movq	`0*$STRIDE/4-96`($bp),%xmm0
        +	movq	`1*$STRIDE/4-96`($bp),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($bp),%xmm2
        +	pand	%xmm5,%xmm1
        +
        +	mov	(%rsp),$A[0]
        +	mov	$n0,$m1
        +	mulq	$m0			# ap[0]*bp[i]
        +	add	%rax,$A[0]		# ap[0]*bp[i]+tp[0]
        +	mov	($np),%rax
        +	adc	\$0,%rdx
        +
        +	movq	`3*$STRIDE/4-96`($bp),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +
        +	imulq	$A[0],$m1		# tp[0]*n0
        +	mov	%rdx,$A[1]
        +
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($bp),$bp
        +	por	%xmm3,%xmm0
        +
        +	mulq	$m1			# np[0]*m1
        +	add	%rax,$A[0]		# "$N[0]", discarded
        +	mov	8($ap),%rax
        +	adc	\$0,%rdx
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	8($np),%rax
        +	adc	\$0,%rdx
        +	add	8(%rsp),$A[1]		# +tp[1]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	16($ap),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[i]+tp[j]
        +	lea	4($j),$j		# j+=2
        +	adc	\$0,%rdx
        +	mov	%rdx,$N[0]
        +	jmp	.Linner4x
        +.align	16
        +.Linner4x:
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-16(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-8(%rsp,$j,8),$A[1]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[0]
        +	mov	($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	8(%rsp,$j,8),$A[1]
        +	adc	\$0,%rdx
        +	lea	4($j),$j		# j++
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	-16($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	adc	\$0,%rdx
        +	mov	$N[0],-40(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +	cmp	$num,$j
        +	jl	.Linner4x
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[0]
        +	mov	-16($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-16(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
        +	adc	\$0,%rdx
        +	mov	%rdx,$A[1]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[0]
        +	mov	-8($ap,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	$A[0],$N[0]
        +	adc	\$0,%rdx
        +	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[1]
        +
        +	mulq	$m0			# ap[j]*bp[i]
        +	add	%rax,$A[1]
        +	mov	-8($np,$j,8),%rax
        +	adc	\$0,%rdx
        +	add	-8(%rsp,$j,8),$A[1]
        +	adc	\$0,%rdx
        +	lea	1($i),$i		# i++
        +	mov	%rdx,$A[0]
        +
        +	mulq	$m1			# np[j]*m1
        +	add	%rax,$N[1]
        +	mov	($ap),%rax		# ap[0]
        +	adc	\$0,%rdx
        +	add	$A[1],$N[1]
        +	adc	\$0,%rdx
        +	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
        +	mov	%rdx,$N[0]
        +
        +	movq	%xmm0,$m0		# bp[i+1]
        +	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
        +
        +	xor	$N[1],$N[1]
        +	add	$A[0],$N[0]
        +	adc	\$0,$N[1]
        +	add	(%rsp,$num,8),$N[0]	# pull upmost overflow bit
        +	adc	\$0,$N[1]
        +	mov	$N[0],-8(%rsp,$j,8)
        +	mov	$N[1],(%rsp,$j,8)	# store upmost overflow bit
        +
        +	cmp	$num,$i
        +	jl	.Louter4x
        +___
        +{
        +my @ri=("%rax","%rdx",$m0,$m1);
        +$code.=<<___;
        +	mov	16(%rsp,$num,8),$rp	# restore $rp
        +	mov	0(%rsp),@ri[0]		# tp[0]
        +	pxor	%xmm0,%xmm0
        +	mov	8(%rsp),@ri[1]		# tp[1]
        +	shr	\$2,$num		# num/=4
        +	lea	(%rsp),$ap		# borrow ap for tp
        +	xor	$i,$i			# i=0 and clear CF!
        +
        +	sub	0($np),@ri[0]
        +	mov	16($ap),@ri[2]		# tp[2]
        +	mov	24($ap),@ri[3]		# tp[3]
        +	sbb	8($np),@ri[1]
        +	lea	-1($num),$j		# j=num/4-1
        +	jmp	.Lsub4x
        +.align	16
        +.Lsub4x:
        +	mov	@ri[0],0($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	@ri[1],8($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	16($np,$i,8),@ri[2]
        +	mov	32($ap,$i,8),@ri[0]	# tp[i+1]
        +	mov	40($ap,$i,8),@ri[1]
        +	sbb	24($np,$i,8),@ri[3]
        +	mov	@ri[2],16($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	@ri[3],24($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	32($np,$i,8),@ri[0]
        +	mov	48($ap,$i,8),@ri[2]
        +	mov	56($ap,$i,8),@ri[3]
        +	sbb	40($np,$i,8),@ri[1]
        +	lea	4($i),$i		# i++
        +	dec	$j			# doesnn't affect CF!
        +	jnz	.Lsub4x
        +
        +	mov	@ri[0],0($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	mov	32($ap,$i,8),@ri[0]	# load overflow bit
        +	sbb	16($np,$i,8),@ri[2]
        +	mov	@ri[1],8($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	sbb	24($np,$i,8),@ri[3]
        +	mov	@ri[2],16($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +
        +	sbb	\$0,@ri[0]		# handle upmost overflow bit
        +	mov	@ri[3],24($rp,$i,8)	# rp[i]=tp[i]-np[i]
        +	xor	$i,$i			# i=0
        +	and	@ri[0],$ap
        +	not	@ri[0]
        +	mov	$rp,$np
        +	and	@ri[0],$np
        +	lea	-1($num),$j
        +	or	$np,$ap			# ap=borrow?tp:rp
        +
        +	movdqu	($ap),%xmm1
        +	movdqa	%xmm0,(%rsp)
        +	movdqu	%xmm1,($rp)
        +	jmp	.Lcopy4x
        +.align	16
        +.Lcopy4x:					# copy or in-place refresh
        +	movdqu	16($ap,$i),%xmm2
        +	movdqu	32($ap,$i),%xmm1
        +	movdqa	%xmm0,16(%rsp,$i)
        +	movdqu	%xmm2,16($rp,$i)
        +	movdqa	%xmm0,32(%rsp,$i)
        +	movdqu	%xmm1,32($rp,$i)
        +	lea	32($i),$i
        +	dec	$j
        +	jnz	.Lcopy4x
        +
        +	shl	\$2,$num
        +	movdqu	16($ap,$i),%xmm2
        +	movdqa	%xmm0,16(%rsp,$i)
        +	movdqu	%xmm2,16($rp,$i)
        +___
        +}
        +$code.=<<___;
        +	mov	8(%rsp,$num,8),%rsi	# restore %rsp
        +	mov	\$1,%rax
        +___
        +$code.=<<___ if ($win64);
        +	movaps	(%rsi),%xmm6
        +	movaps	0x10(%rsi),%xmm7
        +	lea	0x28(%rsi),%rsi
        +___
        +$code.=<<___;
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lmul4x_epilogue:
        +	ret
        +.size	bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5
        +___
        +}}}
        +
        +{
        +my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order
        +				("%rdi","%rsi","%rdx","%rcx"); # Unix order
        +my $out=$inp;
        +my $STRIDE=2**5*8;
        +my $N=$STRIDE/4;
        +
        +$code.=<<___;
        +.globl	bn_scatter5
        +.type	bn_scatter5,\@abi-omnipotent
        +.align	16
        +bn_scatter5:
        +	cmp	\$0, $num
        +	jz	.Lscatter_epilogue
        +	lea	($tbl,$idx,8),$tbl
        +.Lscatter:
        +	mov	($inp),%rax
        +	lea	8($inp),$inp
        +	mov	%rax,($tbl)
        +	lea	32*8($tbl),$tbl
        +	sub	\$1,$num
        +	jnz	.Lscatter
        +.Lscatter_epilogue:
        +	ret
        +.size	bn_scatter5,.-bn_scatter5
        +
        +.globl	bn_gather5
        +.type	bn_gather5,\@abi-omnipotent
        +.align	16
        +bn_gather5:
        +___
        +$code.=<<___ if ($win64);
        +.LSEH_begin_bn_gather5:
        +	# I can't trust assembler to use specific encoding:-(
        +	.byte	0x48,0x83,0xec,0x28		#sub	\$0x28,%rsp
        +	.byte	0x0f,0x29,0x34,0x24		#movaps	%xmm6,(%rsp)
        +	.byte	0x0f,0x29,0x7c,0x24,0x10	#movdqa	%xmm7,0x10(%rsp)
        +___
        +$code.=<<___;
        +	mov	$idx,%r11
        +	shr	\$`log($N/8)/log(2)`,$idx
        +	and	\$`$N/8-1`,%r11
        +	not	$idx
        +	lea	.Lmagic_masks(%rip),%rax
        +	and	\$`2**5/($N/8)-1`,$idx	# 5 is "window size"
        +	lea	96($tbl,%r11,8),$tbl	# pointer within 1st cache line
        +	movq	0(%rax,$idx,8),%xmm4	# set of masks denoting which
        +	movq	8(%rax,$idx,8),%xmm5	# cache line contains element
        +	movq	16(%rax,$idx,8),%xmm6	# denoted by 7th argument
        +	movq	24(%rax,$idx,8),%xmm7
        +	jmp	.Lgather
        +.align	16
        +.Lgather:
        +	movq	`0*$STRIDE/4-96`($tbl),%xmm0
        +	movq	`1*$STRIDE/4-96`($tbl),%xmm1
        +	pand	%xmm4,%xmm0
        +	movq	`2*$STRIDE/4-96`($tbl),%xmm2
        +	pand	%xmm5,%xmm1
        +	movq	`3*$STRIDE/4-96`($tbl),%xmm3
        +	pand	%xmm6,%xmm2
        +	por	%xmm1,%xmm0
        +	pand	%xmm7,%xmm3
        +	por	%xmm2,%xmm0
        +	lea	$STRIDE($tbl),$tbl
        +	por	%xmm3,%xmm0
        +
        +	movq	%xmm0,($out)		# m0=bp[0]
        +	lea	8($out),$out
        +	sub	\$1,$num
        +	jnz	.Lgather
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,(%rsp)
        +	movaps	%xmm7,0x10(%rsp)
        +	lea	0x28(%rsp),%rsp
        +___
        +$code.=<<___;
        +	ret
        +.LSEH_end_bn_gather5:
        +.size	bn_gather5,.-bn_gather5
        +___
        +}
        +$code.=<<___;
        +.align	64
        +.Lmagic_masks:
        +	.long	0,0, 0,0, 0,0, -1,-1
        +	.long	0,0, 0,0, 0,0,  0,0
        +.asciz	"Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	mul_handler,\@abi-omnipotent
        +.align	16
        +mul_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# end of prologue label
        +	cmp	%r10,%rbx		# context->Rip<end of prologue label
        +	jb	.Lcommon_seh_tail
        +
        +	lea	`40+48`(%rax),%rax
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# end of alloca label
        +	cmp	%r10,%rbx		# context->Rip<end of alloca label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	8(%r11),%r10d		# HandlerData[2]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lcommon_seh_tail
        +
        +	mov	192($context),%r10	# pull $num
        +	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
        +
        +	movaps	(%rax),%xmm0
        +	movaps	16(%rax),%xmm1
        +	lea	`40+48`(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +	movups	%xmm0,512($context)	# restore context->Xmm6
        +	movups	%xmm1,528($context)	# restore context->Xmm7
        +
        +.Lcommon_seh_tail:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	mul_handler,.-mul_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_bn_mul_mont_gather5
        +	.rva	.LSEH_end_bn_mul_mont_gather5
        +	.rva	.LSEH_info_bn_mul_mont_gather5
        +
        +	.rva	.LSEH_begin_bn_mul4x_mont_gather5
        +	.rva	.LSEH_end_bn_mul4x_mont_gather5
        +	.rva	.LSEH_info_bn_mul4x_mont_gather5
        +
        +	.rva	.LSEH_begin_bn_gather5
        +	.rva	.LSEH_end_bn_gather5
        +	.rva	.LSEH_info_bn_gather5
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_bn_mul_mont_gather5:
        +	.byte	9,0,0,0
        +	.rva	mul_handler
        +	.rva	.Lmul_alloca,.Lmul_body,.Lmul_epilogue		# HandlerData[]
        +.align	8
        +.LSEH_info_bn_mul4x_mont_gather5:
        +	.byte	9,0,0,0
        +	.rva	mul_handler
        +	.rva	.Lmul4x_alloca,.Lmul4x_body,.Lmul4x_epilogue	# HandlerData[]
        +.align	8
        +.LSEH_info_bn_gather5:
        +        .byte   0x01,0x0d,0x05,0x00
        +        .byte   0x0d,0x78,0x01,0x00	#movaps	0x10(rsp),xmm7
        +        .byte   0x08,0x68,0x00,0x00	#movaps	(rsp),xmm6
        +        .byte   0x04,0x42,0x00,0x00	#sub	rsp,0x28
        +.align	8
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/bn/asm/x86_64-win32-masm.asm b/vendor/openssl/openssl/crypto/bn/asm/x86_64-win32-masm.asm
        new file mode 100644
        index 000000000..2c9197ba3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/asm/x86_64-win32-masm.asm
        @@ -0,0 +1,1679 @@
        +
        +_TEXT SEGMENT
        +
        +
        +ALIGN 16
        +PUBLIC bn_mul_add_words
        +bn_mul_add_words PROC
        +  push rbp
        +  push rdi
        +  push rsi
        +  push rbx
        +  test r8d, r8d
        +  jle label0
        +  xor ebx, ebx
        +  test r8d, -4
        +  mov r10, rdx
        +  je label1
        +  lea rbp, qword ptr [rcx + 8]
        +  lea rdi, qword ptr [rcx + 16]
        +  lea rsi, qword ptr [rcx + 24]
        +  sub rbp, rdx
        +  sub rdi, rdx
        +  sub rsi, rdx
        +label2:
        +  sub r8d, 4
        +  mov rax, r9
        +
        +  mul qword ptr [r10]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, r9
        +
        +  add qword ptr [rcx], rbx
        +  adc rdx, 0
        +
        +  add rcx, 32
        +  mov r11, rdx
        +
        +  mul qword ptr [r10 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, r9
        +
        +  add qword ptr [r10 + rbp], r11
        +  adc rdx, 0
        +
        +  mov rbx, rdx
        +
        +  mul qword ptr [r10 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, r9
        +
        +  add qword ptr [r10 + rdi], rbx
        +  adc rdx, 0
        +
        +  mov r11, rdx
        +
        +  mul qword ptr [r10 + 24]
        +  add r11, rax
        +  adc rdx, 0
        +  add qword ptr [r10 + rsi], r11
        +  adc rdx, 0
        +
        +  add r10, 32
        +  test r8d, -4
        +  mov rbx, rdx
        +  jne label2
        +  test r8d, r8d
        +  mov r11, rdx
        +  je label3
        +label1:
        +  mov rax, r9
        +
        +  mul qword ptr [r10]
        +  add rbx, rax
        +  adc rdx, 0
        +  add qword ptr [rcx], rbx
        +  adc rdx, 0
        +
        +  sub r8d, 1
        +  mov r11, rdx
        +  je label3
        +  mov rax, r9
        +
        +  mul qword ptr [r10 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +  add qword ptr [rcx + 8], r11
        +  adc rdx, 0
        +
        +  cmp r8d, 1
        +  mov rbx, rdx
        +  je label4
        +  mov rax, r9
        +
        +  mul qword ptr [r10 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +  add qword ptr [rcx + 16], rbx
        +  adc rdx, 0
        +
        +  mov r11, rdx
        +label3:
        +  mov rax, r11
        +  pop rbx
        +  pop rsi
        +  pop rdi
        +  pop rbp
        +  ret
        +label0:
        +  xor r11d, r11d
        +  mov rax, r11
        +  pop rbx
        +  pop rsi
        +  pop rdi
        +  pop rbp
        +  ret
        +label4:
        +  mov r11, rdx
        +  jmp label3
        +bn_mul_add_words ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_mul_words
        +bn_mul_words PROC
        +  push rsi
        +  push rbx
        +  test r8d, r8d
        +  mov r10, rdx
        +  jle label5
        +  xor ebx, ebx
        +  test r8d, -4
        +  je label6
        +label7:
        +  sub r8d, 4
        +  mov rax, r9
        +
        +  mul qword ptr [r10]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, r9
        +  mov qword ptr [rcx], rbx
        +  mov r11, rdx
        +
        +  mul qword ptr [r10 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, r9
        +  mov qword ptr [rcx + 8], r11
        +  mov rbx, rdx
        +
        +  mul qword ptr [r10 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, r9
        +  mov qword ptr [rcx + 16], rbx
        +  mov r11, rdx
        +
        +  mul qword ptr [r10 + 24]
        +
        +  add r10, 32
        +
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 24], r11
        +  add rcx, 32
        +  test r8d, -4
        +  mov rbx, rdx
        +  jne label7
        +  test r8d, r8d
        +  mov r11, rdx
        +  jne label6
        +label8:
        +  mov rax, r11
        +  pop rbx
        +  pop rsi
        +  ret
        +label6:
        +  mov rax, r9
        +
        +  mul qword ptr [r10]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  sub r8d, 1
        +  mov qword ptr [rcx], rbx
        +  mov r11, rdx
        +  je label8
        +  mov rax, r9
        +
        +  mul qword ptr [r10 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  cmp r8d, 1
        +  mov rbx, rdx
        +  mov qword ptr [rcx + 8], r11
        +  je label9
        +  mov rax, r9
        +
        +  mul qword ptr [r10 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov r11, rdx
        +  mov qword ptr [rcx + 16], rbx
        +  mov rax, r11
        +  pop rbx
        +  pop rsi
        +  ret
        +label9:
        +  mov r11, rdx
        +  jmp label8
        +label5:
        +  xor r11d, r11d
        +  mov rax, r11
        +  pop rbx
        +  pop rsi
        +  ret
        +bn_mul_words ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_sqr_words
        +bn_sqr_words PROC
        +  test r8d, r8d
        +  mov r9, rdx
        +  jle label10
        +  test r8d, -4
        +  je label11
        +label12:
        +  sub r8d, 4
        +  mov rax, qword ptr [r9]
        +
        +  mul rax
        +
        +  mov qword ptr [rcx + 8], rdx
        +  mov qword ptr [rcx], rax
        +  mov rax, qword ptr [r9 + 8]
        +
        +  mul rax
        +
        +  mov qword ptr [rcx + 24], rdx
        +  mov qword ptr [rcx + 16], rax
        +  mov rax, qword ptr [r9 + 16]
        +
        +  mul rax
        +
        +  mov qword ptr [rcx + 40], rdx
        +  mov qword ptr [rcx + 32], rax
        +  mov rax, qword ptr [r9 + 24]
        +  add r9, 32
        +
        +  mul rax
        +
        +  mov qword ptr [rcx + 48], rax
        +  mov qword ptr [rcx + 56], rdx
        +  add rcx, 64
        +  test r8d, -4
        +  jne label12
        +  test r8d, r8d
        +  je label10
        +label11:
        +  mov rax, qword ptr [r9]
        +
        +  mul rax
        +
        +  sub r8d, 1
        +  mov qword ptr [rcx], rax
        +  mov qword ptr [rcx + 8], rdx
        +  je label10
        +  mov rax, qword ptr [r9 + 8]
        +
        +  mul rax
        +
        +  cmp r8d, 1
        +  mov qword ptr [rcx + 16], rax
        +  mov qword ptr [rcx + 24], rdx
        +  je label10
        +  mov rax, qword ptr [r9 + 16]
        +
        +  mul rax
        +
        +  mov qword ptr [rcx + 32], rax
        +  mov qword ptr [rcx + 40], rdx
        +label10:
        +  ret 0
        +bn_sqr_words ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_div_words
        +bn_div_words PROC
        +  mov rax, rdx
        +  mov rdx, rcx
        +
        +  div r8
        +
        +  ret
        +bn_div_words ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_add_words
        +bn_add_words PROC
        +  test r9d, r9d
        +  mov r10, rcx
        +  jle label13
        +  mov ecx, r9d
        +
        +  sub r11, r11
        +label14:
        +  mov rax, qword ptr [rdx + r11 * 8]
        +  adc rax, qword ptr [r8 + r11 * 8]
        +  mov qword ptr [r10 + r11 * 8], rax
        +  lea r11, qword ptr [r11 + 1]
        +  loop label14
        +  sbb rax, rax
        +
        +  and eax, 1
        +  ret
        +label13:
        +  xor eax, eax
        +  ret
        +bn_add_words ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_sub_words
        +bn_sub_words PROC
        +  test r9d, r9d
        +  mov r10, rcx
        +  jle label15
        +  mov ecx, r9d
        +
        +  sub r11, r11
        +label16:
        +  mov rax, qword ptr [rdx + r11 * 8]
        +  sbb rax, qword ptr [r8 + r11 * 8]
        +  mov qword ptr [r10 + r11 * 8], rax
        +  lea r11, qword ptr [r11 + 1]
        +  loop label16
        +  sbb rax, rax
        +
        +  and eax, 1
        +  ret
        +label15:
        +  xor eax, eax
        +  ret
        +bn_sub_words ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_mul_comba8
        +bn_mul_comba8 PROC
        +  push rsi
        +  push rbx
        +  xor r10d, r10d
        +  mov rax, qword ptr [rdx]
        +  mov r9, rdx
        +  mov rsi, r10
        +  mov r11, r10
        +
        +  mul qword ptr [r8]
        +
        +  mov rbx, r10
        +
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx], rsi
        +  mov rax, qword ptr [r9]
        +
        +  add r11, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 8]
        +
        +  mov rsi, r11
        +  mov r11, r10
        +
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 8], rsi
        +  mov rsi, r10
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 16], rbx
        +  mov rbx, r10
        +  mov rax, qword ptr [r9]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 24]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 24], r11
        +  mov rax, qword ptr [r9 + 32]
        +  mov r11, r10
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 16]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 24]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 32]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 32], rsi
        +  mov rsi, r10
        +  mov rax, qword ptr [r9]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 40]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 32]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 24]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 40], rbx
        +  mov rax, qword ptr [r9 + 48]
        +  mov rbx, r10
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 24]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 32]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 40]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 48]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 48], r11
        +  mov r11, r10
        +  mov rax, qword ptr [r9]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 56]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 48]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 40]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 32]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 24]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 16]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 48]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 56]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 56], rsi
        +  mov rax, qword ptr [r9 + 56]
        +  mov rsi, r10
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 48]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 24]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 32]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 40]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 48]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 56]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 64], rbx
        +  mov rbx, r10
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 56]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 48]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 40]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 32]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 48]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 24]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 56]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 72], r11
        +  mov rax, qword ptr [r9 + 56]
        +  mov r11, r10
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 24]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 48]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 32]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 40]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 48]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 56]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 80], rsi
        +  mov rsi, r10
        +  mov rax, qword ptr [r9 + 32]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 56]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 48]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 48]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 40]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 56]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 32]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 88], rbx
        +  mov rbx, r10
        +  mov rax, qword ptr [r9 + 56]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 40]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 48]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 48]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 40]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 56]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 96], r11
        +  mov rax, qword ptr [r9 + 48]
        +  mov r11, r10
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 56]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 56]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 48]
        +  add rsi, rax
        +  adc rdx, 0
        +  add rbx, rdx
        +  adc r11, 0
        +
        +  mov qword ptr [rcx + 104], rsi
        +  mov rax, qword ptr [r9 + 56]
        +
        +  mul qword ptr [r8 + 56]
        +
        +  mov r8, rbx
        +
        +  add r8, rax
        +  adc rdx, 0
        +  add r11, rdx
        +  adc r10, 0
        +
        +  mov qword ptr [rcx + 112], r8
        +  mov qword ptr [rcx + 120], r11
        +  pop rbx
        +  pop rsi
        +  ret
        +bn_mul_comba8 ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_mul_comba4
        +bn_mul_comba4 PROC
        +  push rsi
        +  push rbx
        +  xor r10d, r10d
        +  mov rax, qword ptr [rdx]
        +  mov r9, rdx
        +  mov rbx, r10
        +  mov r11, r10
        +
        +  mul qword ptr [r8]
        +
        +  mov rsi, r10
        +
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx], rbx
        +  mov rbx, r10
        +  mov rax, qword ptr [r9]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 8], r11
        +  mov r11, r10
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 16]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 16], rsi
        +  mov rsi, r10
        +  mov rax, qword ptr [r9]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 24]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 16]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8]
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 24], rbx
        +  mov rax, qword ptr [r9 + 24]
        +  mov rbx, r10
        +
        +  add r11, rdx
        +  adc rsi, 0
        +  mul qword ptr [r8 + 8]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 8]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 24]
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 32], r11
        +  mov r11, r10
        +  mov rax, qword ptr [r9 + 16]
        +
        +  add rsi, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 24]
        +  add rsi, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r9 + 24]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 16]
        +  add rsi, rax
        +  adc rdx, 0
        +  add rbx, rdx
        +  adc r11, 0
        +
        +  mov qword ptr [rcx + 40], rsi
        +  mov rax, qword ptr [r9 + 24]
        +
        +  mul qword ptr [r8 + 24]
        +
        +  mov r8, rbx
        +
        +  add r8, rax
        +  adc rdx, 0
        +  add r11, rdx
        +  adc r10, 0
        +
        +  mov qword ptr [rcx + 48], r8
        +  mov qword ptr [rcx + 56], r11
        +  pop rbx
        +  pop rsi
        +  ret
        +bn_mul_comba4 ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_sqr_comba8
        +bn_sqr_comba8 PROC
        +  push rsi
        +  push rbx
        +  xor r9d, r9d
        +  mov rax, qword ptr [rdx]
        +  mov r8, rdx
        +  mov rbx, r9
        +  mov r10, r9
        +
        +  mul rax
        +
        +  mov r11, r9
        +  mov rsi, r9
        +
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx], rbx
        +  mov rax, qword ptr [r8 + 8]
        +
        +  add r10, rdx
        +  adc r11, 0
        +  mul qword ptr [r8]
        +
        +  mov rbx, r10
        +
        +  add rdx, rdx
        +  adc rsi, 0
        +  add rax, rax
        +  adc rdx, 0
        +
        +  mov r10, rsi
        +
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 8], rbx
        +  mov rbx, r9
        +  mov rax, qword ptr [r8 + 8]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul rax
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 16]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 16], r11
        +  mov r11, r9
        +  mov rax, qword ptr [r8 + 24]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 16]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 24], r10
        +  mov r10, r9
        +  mov rax, qword ptr [r8 + 16]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul rax
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 24]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 32]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 32], rbx
        +  mov rbx, r9
        +  mov rax, qword ptr [r8 + 40]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 32]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 24]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 40], r11
        +  mov rax, qword ptr [r8 + 24]
        +  mov r11, r9
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul rax
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 32]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 16]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 40]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 48], r10
        +  mov r10, r9
        +  mov rax, qword ptr [r8 + 56]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 40]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 16]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 32]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 24]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 56], rbx
        +  mov rbx, r9
        +  mov rax, qword ptr [r8 + 32]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul rax
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 40]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 24]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 56]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 64], r11
        +  mov rax, qword ptr [r8 + 56]
        +  mov r11, r9
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 16]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 24]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 40]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 32]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 72], r10
        +  mov r10, r9
        +  mov rax, qword ptr [r8 + 40]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul rax
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 32]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 56]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 24]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 80], rbx
        +  mov rbx, r9
        +  mov rax, qword ptr [r8 + 56]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8 + 32]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 40]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 88], r11
        +  mov r11, r9
        +  mov rax, qword ptr [r8 + 48]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul rax
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 56]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 40]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 96], r10
        +  mov r10, r9
        +  mov rax, qword ptr [r8 + 56]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 48]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +  add r11, rdx
        +  adc r10, 0
        +
        +  mov qword ptr [rcx + 104], rbx
        +  mov rax, qword ptr [r8 + 56]
        +  mov r8, r11
        +
        +  mul rax
        +  add r8, rax
        +  adc rdx, 0
        +  add r10, rdx
        +  adc r9, 0
        +
        +  mov qword ptr [rcx + 112], r8
        +  mov qword ptr [rcx + 120], r10
        +  pop rbx
        +  pop rsi
        +  ret
        +bn_sqr_comba8 ENDP
        +
        +
        +ALIGN 16
        +PUBLIC bn_sqr_comba4
        +bn_sqr_comba4 PROC
        +  push rbx
        +  xor r9d, r9d
        +  mov rax, qword ptr [rdx]
        +  mov r8, rdx
        +  mov r11, r9
        +  mov r10, r9
        +
        +  mul rax
        +
        +  mov rbx, r9
        +
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx], r11
        +  mov r11, r9
        +  mov rax, qword ptr [r8 + 8]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 8], r10
        +  mov r10, r9
        +  mov rax, qword ptr [r8 + 8]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul rax
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 16]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 16], rbx
        +  mov rbx, r9
        +  mov rax, qword ptr [r8 + 24]
        +
        +  add r11, rdx
        +  adc r10, 0
        +  mul qword ptr [r8]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 16]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc rbx, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r11, rax
        +  adc rdx, 0
        +
        +  mov qword ptr [rcx + 24], r11
        +  mov r11, r9
        +  mov rax, qword ptr [r8 + 16]
        +
        +  add r10, rdx
        +  adc rbx, 0
        +  mul rax
        +  add r10, rax
        +  adc rdx, 0
        +
        +  mov rax, qword ptr [r8 + 24]
        +
        +  add rbx, rdx
        +  adc r11, 0
        +  mul qword ptr [r8 + 8]
        +  add rdx, rdx
        +  adc r11, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add r10, rax
        +  adc rdx, 0
        +  add rbx, rdx
        +  adc r11, 0
        +
        +  mov qword ptr [rcx + 32], r10
        +  mov r10, r9
        +  mov rax, qword ptr [r8 + 24]
        +
        +  mul qword ptr [r8 + 16]
        +  add rdx, rdx
        +  adc r10, 0
        +  add rax, rax
        +  adc rdx, 0
        +  add rbx, rax
        +  adc rdx, 0
        +  add r11, rdx
        +  adc r10, 0
        +
        +  mov qword ptr [rcx + 40], rbx
        +  mov rax, qword ptr [r8 + 24]
        +  mov r8, r11
        +
        +  mul rax
        +  add r8, rax
        +  adc rdx, 0
        +  add r10, rdx
        +  adc r9, 0
        +
        +  mov qword ptr [rcx + 48], r8
        +  mov qword ptr [rcx + 56], r10
        +  pop rbx
        +  ret
        +bn_sqr_comba4 ENDP
        +
        +
        +_TEXT ENDS
        +
        +END
        diff --git a/vendor/openssl/openssl/crypto/bn/bn.h b/vendor/openssl/openssl/crypto/bn/bn.h
        new file mode 100644
        index 000000000..f34248ec4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn.h
        @@ -0,0 +1,891 @@
        +/* crypto/bn/bn.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the Eric Young open source
        + * license provided above.
        + *
        + * The binary polynomial arithmetic software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#ifndef HEADER_BN_H
        +#define HEADER_BN_H
        +
        +#include <openssl/e_os2.h>
        +#ifndef OPENSSL_NO_FP_API
        +#include <stdio.h> /* FILE */
        +#endif
        +#include <openssl/ossl_typ.h>
        +#include <openssl/crypto.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* These preprocessor symbols control various aspects of the bignum headers and
        + * library code. They're not defined by any "normal" configuration, as they are
        + * intended for development and testing purposes. NB: defining all three can be
        + * useful for debugging application code as well as openssl itself.
        + *
        + * BN_DEBUG - turn on various debugging alterations to the bignum code
        + * BN_DEBUG_RAND - uses random poisoning of unused words to trip up
        + * mismanagement of bignum internals. You must also define BN_DEBUG.
        + */
        +/* #define BN_DEBUG */
        +/* #define BN_DEBUG_RAND */
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +#define BN_MUL_COMBA
        +#define BN_SQR_COMBA
        +#define BN_RECURSION
        +#endif
        +
        +/* This next option uses the C libraries (2 word)/(1 word) function.
        + * If it is not defined, I use my C version (which is slower).
        + * The reason for this flag is that when the particular C compiler
        + * library routine is used, and the library is linked with a different
        + * compiler, the library is missing.  This mostly happens when the
        + * library is built with gcc and then linked using normal cc.  This would
        + * be a common occurrence because gcc normally produces code that is
        + * 2 times faster than system compilers for the big number stuff.
        + * For machines with only one compiler (or shared libraries), this should
        + * be on.  Again this in only really a problem on machines
        + * using "long long's", are 32bit, and are not using my assembler code. */
        +#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
        +    defined(OPENSSL_SYS_WIN32) || defined(linux)
        +# ifndef BN_DIV2W
        +#  define BN_DIV2W
        +# endif
        +#endif
        +
        +/* assuming long is 64bit - this is the DEC Alpha
        + * unsigned long long is only 64 bits :-(, don't define
        + * BN_LLONG for the DEC Alpha */
        +#ifdef SIXTY_FOUR_BIT_LONG
        +#define BN_ULLONG	unsigned long long
        +#define BN_ULONG	unsigned long
        +#define BN_LONG		long
        +#define BN_BITS		128
        +#define BN_BYTES	8
        +#define BN_BITS2	64
        +#define BN_BITS4	32
        +#define BN_MASK		(0xffffffffffffffffffffffffffffffffLL)
        +#define BN_MASK2	(0xffffffffffffffffL)
        +#define BN_MASK2l	(0xffffffffL)
        +#define BN_MASK2h	(0xffffffff00000000L)
        +#define BN_MASK2h1	(0xffffffff80000000L)
        +#define BN_TBIT		(0x8000000000000000L)
        +#define BN_DEC_CONV	(10000000000000000000UL)
        +#define BN_DEC_FMT1	"%lu"
        +#define BN_DEC_FMT2	"%019lu"
        +#define BN_DEC_NUM	19
        +#define BN_HEX_FMT1	"%lX"
        +#define BN_HEX_FMT2	"%016lX"
        +#endif
        +
        +/* This is where the long long data type is 64 bits, but long is 32.
        + * For machines where there are 64bit registers, this is the mode to use.
        + * IRIX, on R4000 and above should use this mode, along with the relevant
        + * assembler code :-).  Do NOT define BN_LLONG.
        + */
        +#ifdef SIXTY_FOUR_BIT
        +#undef BN_LLONG
        +#undef BN_ULLONG
        +#define BN_ULONG	unsigned long long
        +#define BN_LONG		long long
        +#define BN_BITS		128
        +#define BN_BYTES	8
        +#define BN_BITS2	64
        +#define BN_BITS4	32
        +#define BN_MASK2	(0xffffffffffffffffLL)
        +#define BN_MASK2l	(0xffffffffL)
        +#define BN_MASK2h	(0xffffffff00000000LL)
        +#define BN_MASK2h1	(0xffffffff80000000LL)
        +#define BN_TBIT		(0x8000000000000000LL)
        +#define BN_DEC_CONV	(10000000000000000000ULL)
        +#define BN_DEC_FMT1	"%llu"
        +#define BN_DEC_FMT2	"%019llu"
        +#define BN_DEC_NUM	19
        +#define BN_HEX_FMT1	"%llX"
        +#define BN_HEX_FMT2	"%016llX"
        +#endif
        +
        +#ifdef THIRTY_TWO_BIT
        +#ifdef BN_LLONG
        +# if defined(_WIN32) && !defined(__GNUC__)
        +#  define BN_ULLONG	unsigned __int64
        +#  define BN_MASK	(0xffffffffffffffffI64)
        +# else
        +#  define BN_ULLONG	unsigned long long
        +#  define BN_MASK	(0xffffffffffffffffLL)
        +# endif
        +#endif
        +#define BN_ULONG	unsigned int
        +#define BN_LONG		int
        +#define BN_BITS		64
        +#define BN_BYTES	4
        +#define BN_BITS2	32
        +#define BN_BITS4	16
        +#define BN_MASK2	(0xffffffffL)
        +#define BN_MASK2l	(0xffff)
        +#define BN_MASK2h1	(0xffff8000L)
        +#define BN_MASK2h	(0xffff0000L)
        +#define BN_TBIT		(0x80000000L)
        +#define BN_DEC_CONV	(1000000000L)
        +#define BN_DEC_FMT1	"%u"
        +#define BN_DEC_FMT2	"%09u"
        +#define BN_DEC_NUM	9
        +#define BN_HEX_FMT1	"%X"
        +#define BN_HEX_FMT2	"%08X"
        +#endif
        +
        +/* 2011-02-22 SMS.
        + * In various places, a size_t variable or a type cast to size_t was
        + * used to perform integer-only operations on pointers.  This failed on
        + * VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t is
        + * still only 32 bits.  What's needed in these cases is an integer type
        + * with the same size as a pointer, which size_t is not certain to be. 
        + * The only fix here is VMS-specific.
        + */
        +#if defined(OPENSSL_SYS_VMS)
        +# if __INITIAL_POINTER_SIZE == 64
        +#  define PTR_SIZE_INT long long
        +# else /* __INITIAL_POINTER_SIZE == 64 */
        +#  define PTR_SIZE_INT int
        +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +#else /* defined(OPENSSL_SYS_VMS) */
        +# define PTR_SIZE_INT size_t
        +#endif /* defined(OPENSSL_SYS_VMS) [else] */
        +
        +#define BN_DEFAULT_BITS	1280
        +
        +#define BN_FLG_MALLOCED		0x01
        +#define BN_FLG_STATIC_DATA	0x02
        +#define BN_FLG_CONSTTIME	0x04 /* avoid leaking exponent information through timing,
        +                                      * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
        +                                      * BN_div() will call BN_div_no_branch,
        +                                      * BN_mod_inverse() will call BN_mod_inverse_no_branch.
        +                                      */
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */
        +                                      /* avoid leaking exponent information through timings
        +                                      * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
        +#endif
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +#define BN_FLG_FREE		0x8000	/* used for debuging */
        +#endif
        +#define BN_set_flags(b,n)	((b)->flags|=(n))
        +#define BN_get_flags(b,n)	((b)->flags&(n))
        +
        +/* get a clone of a BIGNUM with changed flags, for *temporary* use only
        + * (the two BIGNUMs cannot not be used in parallel!) */
        +#define BN_with_flags(dest,b,n)  ((dest)->d=(b)->d, \
        +                                  (dest)->top=(b)->top, \
        +                                  (dest)->dmax=(b)->dmax, \
        +                                  (dest)->neg=(b)->neg, \
        +                                  (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
        +                                                 |  ((b)->flags & ~BN_FLG_MALLOCED) \
        +                                                 |  BN_FLG_STATIC_DATA \
        +                                                 |  (n)))
        +
        +/* Already declared in ossl_typ.h */
        +#if 0
        +typedef struct bignum_st BIGNUM;
        +/* Used for temp variables (declaration hidden in bn_lcl.h) */
        +typedef struct bignum_ctx BN_CTX;
        +typedef struct bn_blinding_st BN_BLINDING;
        +typedef struct bn_mont_ctx_st BN_MONT_CTX;
        +typedef struct bn_recp_ctx_st BN_RECP_CTX;
        +typedef struct bn_gencb_st BN_GENCB;
        +#endif
        +
        +struct bignum_st
        +	{
        +	BN_ULONG *d;	/* Pointer to an array of 'BN_BITS2' bit chunks. */
        +	int top;	/* Index of last used d +1. */
        +	/* The next are internal book keeping for bn_expand. */
        +	int dmax;	/* Size of the d array. */
        +	int neg;	/* one if the number is negative */
        +	int flags;
        +	};
        +
        +/* Used for montgomery multiplication */
        +struct bn_mont_ctx_st
        +	{
        +	int ri;        /* number of bits in R */
        +	BIGNUM RR;     /* used to convert to montgomery form */
        +	BIGNUM N;      /* The modulus */
        +	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
        +	                * (Ni is only stored for bignum algorithm) */
        +	BN_ULONG n0[2];/* least significant word(s) of Ni;
        +	                  (type changed with 0.9.9, was "BN_ULONG n0;" before) */
        +	int flags;
        +	};
        +
        +/* Used for reciprocal division/mod functions
        + * It cannot be shared between threads
        + */
        +struct bn_recp_ctx_st
        +	{
        +	BIGNUM N;	/* the divisor */
        +	BIGNUM Nr;	/* the reciprocal */
        +	int num_bits;
        +	int shift;
        +	int flags;
        +	};
        +
        +/* Used for slow "generation" functions. */
        +struct bn_gencb_st
        +	{
        +	unsigned int ver;	/* To handle binary (in)compatibility */
        +	void *arg;		/* callback-specific data */
        +	union
        +		{
        +		/* if(ver==1) - handles old style callbacks */
        +		void (*cb_1)(int, int, void *);
        +		/* if(ver==2) - new callback style */
        +		int (*cb_2)(int, int, BN_GENCB *);
        +		} cb;
        +	};
        +/* Wrapper function to make using BN_GENCB easier,  */
        +int BN_GENCB_call(BN_GENCB *cb, int a, int b);
        +/* Macro to populate a BN_GENCB structure with an "old"-style callback */
        +#define BN_GENCB_set_old(gencb, callback, cb_arg) { \
        +		BN_GENCB *tmp_gencb = (gencb); \
        +		tmp_gencb->ver = 1; \
        +		tmp_gencb->arg = (cb_arg); \
        +		tmp_gencb->cb.cb_1 = (callback); }
        +/* Macro to populate a BN_GENCB structure with a "new"-style callback */
        +#define BN_GENCB_set(gencb, callback, cb_arg) { \
        +		BN_GENCB *tmp_gencb = (gencb); \
        +		tmp_gencb->ver = 2; \
        +		tmp_gencb->arg = (cb_arg); \
        +		tmp_gencb->cb.cb_2 = (callback); }
        +
        +#define BN_prime_checks 0 /* default: select number of iterations
        +			     based on the size of the number */
        +
        +/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
        + * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
        + * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
        + * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
        + * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
        +#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
        +                                (b) >=  850 ?  3 : \
        +                                (b) >=  650 ?  4 : \
        +                                (b) >=  550 ?  5 : \
        +                                (b) >=  450 ?  6 : \
        +                                (b) >=  400 ?  7 : \
        +                                (b) >=  350 ?  8 : \
        +                                (b) >=  300 ?  9 : \
        +                                (b) >=  250 ? 12 : \
        +                                (b) >=  200 ? 15 : \
        +                                (b) >=  150 ? 18 : \
        +                                /* b >= 100 */ 27)
        +
        +#define BN_num_bytes(a)	((BN_num_bits(a)+7)/8)
        +
        +/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
        +#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
        +				(((w) == 0) && ((a)->top == 0)))
        +#define BN_is_zero(a)       ((a)->top == 0)
        +#define BN_is_one(a)        (BN_abs_is_word((a),1) && !(a)->neg)
        +#define BN_is_word(a,w)     (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
        +#define BN_is_odd(a)	    (((a)->top > 0) && ((a)->d[0] & 1))
        +
        +#define BN_one(a)	(BN_set_word((a),1))
        +#define BN_zero_ex(a) \
        +	do { \
        +		BIGNUM *_tmp_bn = (a); \
        +		_tmp_bn->top = 0; \
        +		_tmp_bn->neg = 0; \
        +	} while(0)
        +#ifdef OPENSSL_NO_DEPRECATED
        +#define BN_zero(a)	BN_zero_ex(a)
        +#else
        +#define BN_zero(a)	(BN_set_word((a),0))
        +#endif
        +
        +const BIGNUM *BN_value_one(void);
        +char *	BN_options(void);
        +BN_CTX *BN_CTX_new(void);
        +#ifndef OPENSSL_NO_DEPRECATED
        +void	BN_CTX_init(BN_CTX *c);
        +#endif
        +void	BN_CTX_free(BN_CTX *c);
        +void	BN_CTX_start(BN_CTX *ctx);
        +BIGNUM *BN_CTX_get(BN_CTX *ctx);
        +void	BN_CTX_end(BN_CTX *ctx);
        +int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
        +int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
        +int	BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
        +int	BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
        +int	BN_num_bits(const BIGNUM *a);
        +int	BN_num_bits_word(BN_ULONG);
        +BIGNUM *BN_new(void);
        +void	BN_init(BIGNUM *);
        +void	BN_clear_free(BIGNUM *a);
        +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
        +void	BN_swap(BIGNUM *a, BIGNUM *b);
        +BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
        +int	BN_bn2bin(const BIGNUM *a, unsigned char *to);
        +BIGNUM *BN_mpi2bn(const unsigned char *s,int len,BIGNUM *ret);
        +int	BN_bn2mpi(const BIGNUM *a, unsigned char *to);
        +int	BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        +int	BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        +int	BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        +int	BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        +int	BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
        +int	BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
        +/** BN_set_negative sets sign of a BIGNUM
        + * \param  b  pointer to the BIGNUM object
        + * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise 
        + */
        +void	BN_set_negative(BIGNUM *b, int n);
        +/** BN_is_negative returns 1 if the BIGNUM is negative
        + * \param  a  pointer to the BIGNUM object
        + * \return 1 if a < 0 and 0 otherwise
        + */
        +#define BN_is_negative(a) ((a)->neg != 0)
        +
        +int	BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
        +	BN_CTX *ctx);
        +#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
        +int	BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
        +int	BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
        +int	BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
        +int	BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
        +int	BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
        +int	BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const BIGNUM *m, BN_CTX *ctx);
        +int	BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        +int	BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        +int	BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
        +int	BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx);
        +int	BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
        +
        +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
        +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
        +int	BN_mul_word(BIGNUM *a, BN_ULONG w);
        +int	BN_add_word(BIGNUM *a, BN_ULONG w);
        +int	BN_sub_word(BIGNUM *a, BN_ULONG w);
        +int	BN_set_word(BIGNUM *a, BN_ULONG w);
        +BN_ULONG BN_get_word(const BIGNUM *a);
        +
        +int	BN_cmp(const BIGNUM *a, const BIGNUM *b);
        +void	BN_free(BIGNUM *a);
        +int	BN_is_bit_set(const BIGNUM *a, int n);
        +int	BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
        +int	BN_lshift1(BIGNUM *r, const BIGNUM *a);
        +int	BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
        +
        +int	BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m,BN_CTX *ctx);
        +int	BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
        +int	BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +int	BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
        +	const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
        +	BN_CTX *ctx,BN_MONT_CTX *m_ctx);
        +int	BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m,BN_CTX *ctx);
        +
        +int	BN_mask_bits(BIGNUM *a,int n);
        +#ifndef OPENSSL_NO_FP_API
        +int	BN_print_fp(FILE *fp, const BIGNUM *a);
        +#endif
        +#ifdef HEADER_BIO_H
        +int	BN_print(BIO *fp, const BIGNUM *a);
        +#else
        +int	BN_print(void *fp, const BIGNUM *a);
        +#endif
        +int	BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
        +int	BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
        +int	BN_rshift1(BIGNUM *r, const BIGNUM *a);
        +void	BN_clear(BIGNUM *a);
        +BIGNUM *BN_dup(const BIGNUM *a);
        +int	BN_ucmp(const BIGNUM *a, const BIGNUM *b);
        +int	BN_set_bit(BIGNUM *a, int n);
        +int	BN_clear_bit(BIGNUM *a, int n);
        +char *	BN_bn2hex(const BIGNUM *a);
        +char *	BN_bn2dec(const BIGNUM *a);
        +int 	BN_hex2bn(BIGNUM **a, const char *str);
        +int 	BN_dec2bn(BIGNUM **a, const char *str);
        +int	BN_asc2bn(BIGNUM **a, const char *str);
        +int	BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
        +int	BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
        +BIGNUM *BN_mod_inverse(BIGNUM *ret,
        +	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
        +BIGNUM *BN_mod_sqrt(BIGNUM *ret,
        +	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
        +
        +/* Deprecated versions */
        +#ifndef OPENSSL_NO_DEPRECATED
        +BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
        +	const BIGNUM *add, const BIGNUM *rem,
        +	void (*callback)(int,int,void *),void *cb_arg);
        +int	BN_is_prime(const BIGNUM *p,int nchecks,
        +	void (*callback)(int,int,void *),
        +	BN_CTX *ctx,void *cb_arg);
        +int	BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
        +	void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
        +	int do_trial_division);
        +#endif /* !defined(OPENSSL_NO_DEPRECATED) */
        +
        +/* Newer versions */
        +int	BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add,
        +		const BIGNUM *rem, BN_GENCB *cb);
        +int	BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
        +int	BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
        +		int do_trial_division, BN_GENCB *cb);
        +
        +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
        +
        +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
        +			const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
        +			const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
        +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
        +			BIGNUM *Xp1, BIGNUM *Xp2,
        +			const BIGNUM *Xp,
        +			const BIGNUM *e, BN_CTX *ctx,
        +			BN_GENCB *cb);
        +
        +BN_MONT_CTX *BN_MONT_CTX_new(void );
        +void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
        +int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
        +	BN_MONT_CTX *mont, BN_CTX *ctx);
        +#define BN_to_montgomery(r,a,mont,ctx)	BN_mod_mul_montgomery(\
        +	(r),(a),&((mont)->RR),(mont),(ctx))
        +int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
        +	BN_MONT_CTX *mont, BN_CTX *ctx);
        +void BN_MONT_CTX_free(BN_MONT_CTX *mont);
        +int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
        +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
        +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
        +					const BIGNUM *mod, BN_CTX *ctx);
        +
        +/* BN_BLINDING flags */
        +#define	BN_BLINDING_NO_UPDATE	0x00000001
        +#define	BN_BLINDING_NO_RECREATE	0x00000002
        +
        +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
        +void BN_BLINDING_free(BN_BLINDING *b);
        +int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
        +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
        +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
        +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
        +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
        +#ifndef OPENSSL_NO_DEPRECATED
        +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
        +void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
        +#endif
        +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
        +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
        +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
        +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
        +	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
        +	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
        +	BN_MONT_CTX *m_ctx);
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +void BN_set_params(int mul,int high,int low,int mont);
        +int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
        +#endif
        +
        +void	BN_RECP_CTX_init(BN_RECP_CTX *recp);
        +BN_RECP_CTX *BN_RECP_CTX_new(void);
        +void	BN_RECP_CTX_free(BN_RECP_CTX *recp);
        +int	BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
        +int	BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
        +	BN_RECP_CTX *recp,BN_CTX *ctx);
        +int	BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx);
        +int	BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
        +	BN_RECP_CTX *recp, BN_CTX *ctx);
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +/* Functions for arithmetic over binary polynomials represented by BIGNUMs. 
        + *
        + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
        + * ignored.
        + *
        + * Note that input arguments are not const so that their bit arrays can
        + * be expanded to the appropriate size if needed.
        + */
        +
        +int	BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/
        +#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
        +int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/
        +int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
        +int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	BN_CTX *ctx); /* r = (a * a) mod p */
        +int	BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p,
        +	BN_CTX *ctx); /* r = (1 / b) mod p */
        +int	BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
        +int	BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
        +int	BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	BN_CTX *ctx); /* r = sqrt(a) mod p */
        +int	BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	BN_CTX *ctx); /* r^2 + r = a mod p */
        +#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
        +/* Some functions allow for representation of the irreducible polynomials
        + * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
        + *     t^p[0] + t^p[1] + ... + t^p[k]
        + * where m = p[0] > p[1] > ... > p[k] = 0.
        + */
        +int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
        +	/* r = a mod p */
        +int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const int p[], BN_CTX *ctx); /* r = (a * b) mod p */
        +int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
        +	BN_CTX *ctx); /* r = (a * a) mod p */
        +int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
        +	BN_CTX *ctx); /* r = (1 / b) mod p */
        +int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const int p[], BN_CTX *ctx); /* r = (a / b) mod p */
        +int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +	const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
        +int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
        +	const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
        +int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
        +	const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
        +int	BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
        +int	BN_GF2m_arr2poly(const int p[], BIGNUM *a);
        +
        +#endif
        +
        +/* faster mod functions for the 'NIST primes' 
        + * 0 <= a < p^2 */
        +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
        +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
        +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
        +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
        +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
        +
        +const BIGNUM *BN_get0_nist_prime_192(void);
        +const BIGNUM *BN_get0_nist_prime_224(void);
        +const BIGNUM *BN_get0_nist_prime_256(void);
        +const BIGNUM *BN_get0_nist_prime_384(void);
        +const BIGNUM *BN_get0_nist_prime_521(void);
        +
        +/* library internal functions */
        +
        +#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
        +	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
        +#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
        +BIGNUM *bn_expand2(BIGNUM *a, int words);
        +#ifndef OPENSSL_NO_DEPRECATED
        +BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
        +#endif
        +
        +/* Bignum consistency macros
        + * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
        + * bignum data after direct manipulations on the data. There is also an
        + * "internal" macro, bn_check_top(), for verifying that there are no leading
        + * zeroes. Unfortunately, some auditing is required due to the fact that
        + * bn_fix_top() has become an overabused duct-tape because bignum data is
        + * occasionally passed around in an inconsistent state. So the following
        + * changes have been made to sort this out;
        + * - bn_fix_top()s implementation has been moved to bn_correct_top()
        + * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
        + *   bn_check_top() is as before.
        + * - if BN_DEBUG *is* defined;
        + *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
        + *     consistent. (ed: only if BN_DEBUG_RAND is defined)
        + *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
        + * The idea is to have debug builds flag up inconsistent bignums when they
        + * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
        + * the use of bn_fix_top() was appropriate (ie. it follows directly after code
        + * that manipulates the bignum) it is converted to bn_correct_top(), and if it
        + * was not appropriate, we convert it permanently to bn_check_top() and track
        + * down the cause of the bug. Eventually, no internal code should be using the
        + * bn_fix_top() macro. External applications and libraries should try this with
        + * their own code too, both in terms of building against the openssl headers
        + * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
        + * defined. This not only improves external code, it provides more test
        + * coverage for openssl's own code.
        + */
        +
        +#ifdef BN_DEBUG
        +
        +/* We only need assert() when debugging */
        +#include <assert.h>
        +
        +#ifdef BN_DEBUG_RAND
        +/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
        +#ifndef RAND_pseudo_bytes
        +int RAND_pseudo_bytes(unsigned char *buf,int num);
        +#define BN_DEBUG_TRIX
        +#endif
        +#define bn_pollute(a) \
        +	do { \
        +		const BIGNUM *_bnum1 = (a); \
        +		if(_bnum1->top < _bnum1->dmax) { \
        +			unsigned char _tmp_char; \
        +			/* We cast away const without the compiler knowing, any \
        +			 * *genuinely* constant variables that aren't mutable \
        +			 * wouldn't be constructed with top!=dmax. */ \
        +			BN_ULONG *_not_const; \
        +			memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
        +			RAND_pseudo_bytes(&_tmp_char, 1); \
        +			memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
        +				(_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
        +		} \
        +	} while(0)
        +#ifdef BN_DEBUG_TRIX
        +#undef RAND_pseudo_bytes
        +#endif
        +#else
        +#define bn_pollute(a)
        +#endif
        +#define bn_check_top(a) \
        +	do { \
        +		const BIGNUM *_bnum2 = (a); \
        +		if (_bnum2 != NULL) { \
        +			assert((_bnum2->top == 0) || \
        +				(_bnum2->d[_bnum2->top - 1] != 0)); \
        +			bn_pollute(_bnum2); \
        +		} \
        +	} while(0)
        +
        +#define bn_fix_top(a)		bn_check_top(a)
        +
        +#else /* !BN_DEBUG */
        +
        +#define bn_pollute(a)
        +#define bn_check_top(a)
        +#define bn_fix_top(a)		bn_correct_top(a)
        +
        +#endif
        +
        +#define bn_correct_top(a) \
        +        { \
        +        BN_ULONG *ftl; \
        +	int tmp_top = (a)->top; \
        +	if (tmp_top > 0) \
        +		{ \
        +		for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
        +			if (*(ftl--)) break; \
        +		(a)->top = tmp_top; \
        +		} \
        +	bn_pollute(a); \
        +	}
        +
        +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
        +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
        +void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
        +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
        +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
        +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
        +
        +/* Primes from RFC 2409 */
        +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
        +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);
        +
        +/* Primes from RFC 3526 */
        +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
        +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
        +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
        +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
        +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
        +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);
        +
        +int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_BN_strings(void);
        +
        +/* Error codes for the BN functions. */
        +
        +/* Function codes. */
        +#define BN_F_BNRAND					 127
        +#define BN_F_BN_BLINDING_CONVERT_EX			 100
        +#define BN_F_BN_BLINDING_CREATE_PARAM			 128
        +#define BN_F_BN_BLINDING_INVERT_EX			 101
        +#define BN_F_BN_BLINDING_NEW				 102
        +#define BN_F_BN_BLINDING_UPDATE				 103
        +#define BN_F_BN_BN2DEC					 104
        +#define BN_F_BN_BN2HEX					 105
        +#define BN_F_BN_CTX_GET					 116
        +#define BN_F_BN_CTX_NEW					 106
        +#define BN_F_BN_CTX_START				 129
        +#define BN_F_BN_DIV					 107
        +#define BN_F_BN_DIV_NO_BRANCH				 138
        +#define BN_F_BN_DIV_RECP				 130
        +#define BN_F_BN_EXP					 123
        +#define BN_F_BN_EXPAND2					 108
        +#define BN_F_BN_EXPAND_INTERNAL				 120
        +#define BN_F_BN_GF2M_MOD				 131
        +#define BN_F_BN_GF2M_MOD_EXP				 132
        +#define BN_F_BN_GF2M_MOD_MUL				 133
        +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD			 134
        +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR			 135
        +#define BN_F_BN_GF2M_MOD_SQR				 136
        +#define BN_F_BN_GF2M_MOD_SQRT				 137
        +#define BN_F_BN_MOD_EXP2_MONT				 118
        +#define BN_F_BN_MOD_EXP_MONT				 109
        +#define BN_F_BN_MOD_EXP_MONT_CONSTTIME			 124
        +#define BN_F_BN_MOD_EXP_MONT_WORD			 117
        +#define BN_F_BN_MOD_EXP_RECP				 125
        +#define BN_F_BN_MOD_EXP_SIMPLE				 126
        +#define BN_F_BN_MOD_INVERSE				 110
        +#define BN_F_BN_MOD_INVERSE_NO_BRANCH			 139
        +#define BN_F_BN_MOD_LSHIFT_QUICK			 119
        +#define BN_F_BN_MOD_MUL_RECIPROCAL			 111
        +#define BN_F_BN_MOD_SQRT				 121
        +#define BN_F_BN_MPI2BN					 112
        +#define BN_F_BN_NEW					 113
        +#define BN_F_BN_RAND					 114
        +#define BN_F_BN_RAND_RANGE				 122
        +#define BN_F_BN_USUB					 115
        +
        +/* Reason codes. */
        +#define BN_R_ARG2_LT_ARG3				 100
        +#define BN_R_BAD_RECIPROCAL				 101
        +#define BN_R_BIGNUM_TOO_LONG				 114
        +#define BN_R_CALLED_WITH_EVEN_MODULUS			 102
        +#define BN_R_DIV_BY_ZERO				 103
        +#define BN_R_ENCODING_ERROR				 104
        +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA		 105
        +#define BN_R_INPUT_NOT_REDUCED				 110
        +#define BN_R_INVALID_LENGTH				 106
        +#define BN_R_INVALID_RANGE				 115
        +#define BN_R_NOT_A_SQUARE				 111
        +#define BN_R_NOT_INITIALIZED				 107
        +#define BN_R_NO_INVERSE					 108
        +#define BN_R_NO_SOLUTION				 116
        +#define BN_R_P_IS_NOT_PRIME				 112
        +#define BN_R_TOO_MANY_ITERATIONS			 113
        +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES		 109
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/bn.mul b/vendor/openssl/openssl/crypto/bn/bn.mul
        new file mode 100644
        index 000000000..9728870d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn.mul
        @@ -0,0 +1,19 @@
        +We need
        +
        +* bn_mul_comba8
        +* bn_mul_comba4
        +* bn_mul_normal
        +* bn_mul_recursive
        +
        +* bn_sqr_comba8
        +* bn_sqr_comba4
        +bn_sqr_normal -> BN_sqr
        +* bn_sqr_recursive
        +
        +* bn_mul_low_recursive
        +* bn_mul_low_normal
        +* bn_mul_high
        +
        +* bn_mul_part_recursive	# symetric but not power of 2
        +
        +bn_mul_asymetric_recursive # uneven, but do the chop up.
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_add.c b/vendor/openssl/openssl/crypto/bn/bn_add.c
        new file mode 100644
        index 000000000..940516370
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_add.c
        @@ -0,0 +1,313 @@
        +/* crypto/bn/bn_add.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +/* r can == a or b */
        +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
        +	{
        +	const BIGNUM *tmp;
        +	int a_neg = a->neg, ret;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	/*  a +  b	a+b
        +	 *  a + -b	a-b
        +	 * -a +  b	b-a
        +	 * -a + -b	-(a+b)
        +	 */
        +	if (a_neg ^ b->neg)
        +		{
        +		/* only one is negative */
        +		if (a_neg)
        +			{ tmp=a; a=b; b=tmp; }
        +
        +		/* we are now a - b */
        +
        +		if (BN_ucmp(a,b) < 0)
        +			{
        +			if (!BN_usub(r,b,a)) return(0);
        +			r->neg=1;
        +			}
        +		else
        +			{
        +			if (!BN_usub(r,a,b)) return(0);
        +			r->neg=0;
        +			}
        +		return(1);
        +		}
        +
        +	ret = BN_uadd(r,a,b);
        +	r->neg = a_neg;
        +	bn_check_top(r);
        +	return ret;
        +	}
        +
        +/* unsigned add of b to a */
        +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
        +	{
        +	int max,min,dif;
        +	BN_ULONG *ap,*bp,*rp,carry,t1,t2;
        +	const BIGNUM *tmp;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	if (a->top < b->top)
        +		{ tmp=a; a=b; b=tmp; }
        +	max = a->top;
        +	min = b->top;
        +	dif = max - min;
        +
        +	if (bn_wexpand(r,max+1) == NULL)
        +		return 0;
        +
        +	r->top=max;
        +
        +
        +	ap=a->d;
        +	bp=b->d;
        +	rp=r->d;
        +
        +	carry=bn_add_words(rp,ap,bp,min);
        +	rp+=min;
        +	ap+=min;
        +	bp+=min;
        +
        +	if (carry)
        +		{
        +		while (dif)
        +			{
        +			dif--;
        +			t1 = *(ap++);
        +			t2 = (t1+1) & BN_MASK2;
        +			*(rp++) = t2;
        +			if (t2)
        +				{
        +				carry=0;
        +				break;
        +				}
        +			}
        +		if (carry)
        +			{
        +			/* carry != 0 => dif == 0 */
        +			*rp = 1;
        +			r->top++;
        +			}
        +		}
        +	if (dif && rp != ap)
        +		while (dif--)
        +			/* copy remaining words if ap != rp */
        +			*(rp++) = *(ap++);
        +	r->neg = 0;
        +	bn_check_top(r);
        +	return 1;
        +	}
        +
        +/* unsigned subtraction of b from a, a must be larger than b. */
        +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
        +	{
        +	int max,min,dif;
        +	register BN_ULONG t1,t2,*ap,*bp,*rp;
        +	int i,carry;
        +#if defined(IRIX_CC_BUG) && !defined(LINT)
        +	int dummy;
        +#endif
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	max = a->top;
        +	min = b->top;
        +	dif = max - min;
        +
        +	if (dif < 0)	/* hmm... should not be happening */
        +		{
        +		BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
        +		return(0);
        +		}
        +
        +	if (bn_wexpand(r,max) == NULL) return(0);
        +
        +	ap=a->d;
        +	bp=b->d;
        +	rp=r->d;
        +
        +#if 1
        +	carry=0;
        +	for (i = min; i != 0; i--)
        +		{
        +		t1= *(ap++);
        +		t2= *(bp++);
        +		if (carry)
        +			{
        +			carry=(t1 <= t2);
        +			t1=(t1-t2-1)&BN_MASK2;
        +			}
        +		else
        +			{
        +			carry=(t1 < t2);
        +			t1=(t1-t2)&BN_MASK2;
        +			}
        +#if defined(IRIX_CC_BUG) && !defined(LINT)
        +		dummy=t1;
        +#endif
        +		*(rp++)=t1&BN_MASK2;
        +		}
        +#else
        +	carry=bn_sub_words(rp,ap,bp,min);
        +	ap+=min;
        +	bp+=min;
        +	rp+=min;
        +#endif
        +	if (carry) /* subtracted */
        +		{
        +		if (!dif)
        +			/* error: a < b */
        +			return 0;
        +		while (dif)
        +			{
        +			dif--;
        +			t1 = *(ap++);
        +			t2 = (t1-1)&BN_MASK2;
        +			*(rp++) = t2;
        +			if (t1)
        +				break;
        +			}
        +		}
        +#if 0
        +	memcpy(rp,ap,sizeof(*rp)*(max-i));
        +#else
        +	if (rp != ap)
        +		{
        +		for (;;)
        +			{
        +			if (!dif--) break;
        +			rp[0]=ap[0];
        +			if (!dif--) break;
        +			rp[1]=ap[1];
        +			if (!dif--) break;
        +			rp[2]=ap[2];
        +			if (!dif--) break;
        +			rp[3]=ap[3];
        +			rp+=4;
        +			ap+=4;
        +			}
        +		}
        +#endif
        +
        +	r->top=max;
        +	r->neg=0;
        +	bn_correct_top(r);
        +	return(1);
        +	}
        +
        +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
        +	{
        +	int max;
        +	int add=0,neg=0;
        +	const BIGNUM *tmp;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	/*  a -  b	a-b
        +	 *  a - -b	a+b
        +	 * -a -  b	-(a+b)
        +	 * -a - -b	b-a
        +	 */
        +	if (a->neg)
        +		{
        +		if (b->neg)
        +			{ tmp=a; a=b; b=tmp; }
        +		else
        +			{ add=1; neg=1; }
        +		}
        +	else
        +		{
        +		if (b->neg) { add=1; neg=0; }
        +		}
        +
        +	if (add)
        +		{
        +		if (!BN_uadd(r,a,b)) return(0);
        +		r->neg=neg;
        +		return(1);
        +		}
        +
        +	/* We are actually doing a - b :-) */
        +
        +	max=(a->top > b->top)?a->top:b->top;
        +	if (bn_wexpand(r,max) == NULL) return(0);
        +	if (BN_ucmp(a,b) < 0)
        +		{
        +		if (!BN_usub(r,b,a)) return(0);
        +		r->neg=1;
        +		}
        +	else
        +		{
        +		if (!BN_usub(r,a,b)) return(0);
        +		r->neg=0;
        +		}
        +	bn_check_top(r);
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_asm.c b/vendor/openssl/openssl/crypto/bn/bn_asm.c
        new file mode 100644
        index 000000000..c43c91cc0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_asm.c
        @@ -0,0 +1,1030 @@
        +/* crypto/bn/bn_asm.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef BN_DEBUG
        +# undef NDEBUG /* avoid conflicting definitions */
        +# define NDEBUG
        +#endif
        +
        +#include <stdio.h>
        +#include <assert.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
        +
        +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
        +	{
        +	BN_ULONG c1=0;
        +
        +	assert(num >= 0);
        +	if (num <= 0) return(c1);
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (num&~3)
        +		{
        +		mul_add(rp[0],ap[0],w,c1);
        +		mul_add(rp[1],ap[1],w,c1);
        +		mul_add(rp[2],ap[2],w,c1);
        +		mul_add(rp[3],ap[3],w,c1);
        +		ap+=4; rp+=4; num-=4;
        +		}
        +#endif
        +	while (num)
        +		{
        +		mul_add(rp[0],ap[0],w,c1);
        +		ap++; rp++; num--;
        +		}
        +	
        +	return(c1);
        +	} 
        +
        +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
        +	{
        +	BN_ULONG c1=0;
        +
        +	assert(num >= 0);
        +	if (num <= 0) return(c1);
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (num&~3)
        +		{
        +		mul(rp[0],ap[0],w,c1);
        +		mul(rp[1],ap[1],w,c1);
        +		mul(rp[2],ap[2],w,c1);
        +		mul(rp[3],ap[3],w,c1);
        +		ap+=4; rp+=4; num-=4;
        +		}
        +#endif
        +	while (num)
        +		{
        +		mul(rp[0],ap[0],w,c1);
        +		ap++; rp++; num--;
        +		}
        +	return(c1);
        +	} 
        +
        +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
        +        {
        +	assert(n >= 0);
        +	if (n <= 0) return;
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (n&~3)
        +		{
        +		sqr(r[0],r[1],a[0]);
        +		sqr(r[2],r[3],a[1]);
        +		sqr(r[4],r[5],a[2]);
        +		sqr(r[6],r[7],a[3]);
        +		a+=4; r+=8; n-=4;
        +		}
        +#endif
        +	while (n)
        +		{
        +		sqr(r[0],r[1],a[0]);
        +		a++; r+=2; n--;
        +		}
        +	}
        +
        +#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
        +
        +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
        +	{
        +	BN_ULONG c=0;
        +	BN_ULONG bl,bh;
        +
        +	assert(num >= 0);
        +	if (num <= 0) return((BN_ULONG)0);
        +
        +	bl=LBITS(w);
        +	bh=HBITS(w);
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (num&~3)
        +		{
        +		mul_add(rp[0],ap[0],bl,bh,c);
        +		mul_add(rp[1],ap[1],bl,bh,c);
        +		mul_add(rp[2],ap[2],bl,bh,c);
        +		mul_add(rp[3],ap[3],bl,bh,c);
        +		ap+=4; rp+=4; num-=4;
        +		}
        +#endif
        +	while (num)
        +		{
        +		mul_add(rp[0],ap[0],bl,bh,c);
        +		ap++; rp++; num--;
        +		}
        +	return(c);
        +	} 
        +
        +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
        +	{
        +	BN_ULONG carry=0;
        +	BN_ULONG bl,bh;
        +
        +	assert(num >= 0);
        +	if (num <= 0) return((BN_ULONG)0);
        +
        +	bl=LBITS(w);
        +	bh=HBITS(w);
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (num&~3)
        +		{
        +		mul(rp[0],ap[0],bl,bh,carry);
        +		mul(rp[1],ap[1],bl,bh,carry);
        +		mul(rp[2],ap[2],bl,bh,carry);
        +		mul(rp[3],ap[3],bl,bh,carry);
        +		ap+=4; rp+=4; num-=4;
        +		}
        +#endif
        +	while (num)
        +		{
        +		mul(rp[0],ap[0],bl,bh,carry);
        +		ap++; rp++; num--;
        +		}
        +	return(carry);
        +	} 
        +
        +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
        +        {
        +	assert(n >= 0);
        +	if (n <= 0) return;
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (n&~3)
        +		{
        +		sqr64(r[0],r[1],a[0]);
        +		sqr64(r[2],r[3],a[1]);
        +		sqr64(r[4],r[5],a[2]);
        +		sqr64(r[6],r[7],a[3]);
        +		a+=4; r+=8; n-=4;
        +		}
        +#endif
        +	while (n)
        +		{
        +		sqr64(r[0],r[1],a[0]);
        +		a++; r+=2; n--;
        +		}
        +	}
        +
        +#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
        +
        +#if defined(BN_LLONG) && defined(BN_DIV2W)
        +
        +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
        +	{
        +	return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
        +	}
        +
        +#else
        +
        +/* Divide h,l by d and return the result. */
        +/* I need to test this some more :-( */
        +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
        +	{
        +	BN_ULONG dh,dl,q,ret=0,th,tl,t;
        +	int i,count=2;
        +
        +	if (d == 0) return(BN_MASK2);
        +
        +	i=BN_num_bits_word(d);
        +	assert((i == BN_BITS2) || (h <= (BN_ULONG)1<<i));
        +
        +	i=BN_BITS2-i;
        +	if (h >= d) h-=d;
        +
        +	if (i)
        +		{
        +		d<<=i;
        +		h=(h<<i)|(l>>(BN_BITS2-i));
        +		l<<=i;
        +		}
        +	dh=(d&BN_MASK2h)>>BN_BITS4;
        +	dl=(d&BN_MASK2l);
        +	for (;;)
        +		{
        +		if ((h>>BN_BITS4) == dh)
        +			q=BN_MASK2l;
        +		else
        +			q=h/dh;
        +
        +		th=q*dh;
        +		tl=dl*q;
        +		for (;;)
        +			{
        +			t=h-th;
        +			if ((t&BN_MASK2h) ||
        +				((tl) <= (
        +					(t<<BN_BITS4)|
        +					((l&BN_MASK2h)>>BN_BITS4))))
        +				break;
        +			q--;
        +			th-=dh;
        +			tl-=dl;
        +			}
        +		t=(tl>>BN_BITS4);
        +		tl=(tl<<BN_BITS4)&BN_MASK2h;
        +		th+=t;
        +
        +		if (l < tl) th++;
        +		l-=tl;
        +		if (h < th)
        +			{
        +			h+=d;
        +			q--;
        +			}
        +		h-=th;
        +
        +		if (--count == 0) break;
        +
        +		ret=q<<BN_BITS4;
        +		h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
        +		l=(l&BN_MASK2l)<<BN_BITS4;
        +		}
        +	ret|=q;
        +	return(ret);
        +	}
        +#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
        +
        +#ifdef BN_LLONG
        +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
        +        {
        +	BN_ULLONG ll=0;
        +
        +	assert(n >= 0);
        +	if (n <= 0) return((BN_ULONG)0);
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (n&~3)
        +		{
        +		ll+=(BN_ULLONG)a[0]+b[0];
        +		r[0]=(BN_ULONG)ll&BN_MASK2;
        +		ll>>=BN_BITS2;
        +		ll+=(BN_ULLONG)a[1]+b[1];
        +		r[1]=(BN_ULONG)ll&BN_MASK2;
        +		ll>>=BN_BITS2;
        +		ll+=(BN_ULLONG)a[2]+b[2];
        +		r[2]=(BN_ULONG)ll&BN_MASK2;
        +		ll>>=BN_BITS2;
        +		ll+=(BN_ULLONG)a[3]+b[3];
        +		r[3]=(BN_ULONG)ll&BN_MASK2;
        +		ll>>=BN_BITS2;
        +		a+=4; b+=4; r+=4; n-=4;
        +		}
        +#endif
        +	while (n)
        +		{
        +		ll+=(BN_ULLONG)a[0]+b[0];
        +		r[0]=(BN_ULONG)ll&BN_MASK2;
        +		ll>>=BN_BITS2;
        +		a++; b++; r++; n--;
        +		}
        +	return((BN_ULONG)ll);
        +	}
        +#else /* !BN_LLONG */
        +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
        +        {
        +	BN_ULONG c,l,t;
        +
        +	assert(n >= 0);
        +	if (n <= 0) return((BN_ULONG)0);
        +
        +	c=0;
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (n&~3)
        +		{
        +		t=a[0];
        +		t=(t+c)&BN_MASK2;
        +		c=(t < c);
        +		l=(t+b[0])&BN_MASK2;
        +		c+=(l < t);
        +		r[0]=l;
        +		t=a[1];
        +		t=(t+c)&BN_MASK2;
        +		c=(t < c);
        +		l=(t+b[1])&BN_MASK2;
        +		c+=(l < t);
        +		r[1]=l;
        +		t=a[2];
        +		t=(t+c)&BN_MASK2;
        +		c=(t < c);
        +		l=(t+b[2])&BN_MASK2;
        +		c+=(l < t);
        +		r[2]=l;
        +		t=a[3];
        +		t=(t+c)&BN_MASK2;
        +		c=(t < c);
        +		l=(t+b[3])&BN_MASK2;
        +		c+=(l < t);
        +		r[3]=l;
        +		a+=4; b+=4; r+=4; n-=4;
        +		}
        +#endif
        +	while(n)
        +		{
        +		t=a[0];
        +		t=(t+c)&BN_MASK2;
        +		c=(t < c);
        +		l=(t+b[0])&BN_MASK2;
        +		c+=(l < t);
        +		r[0]=l;
        +		a++; b++; r++; n--;
        +		}
        +	return((BN_ULONG)c);
        +	}
        +#endif /* !BN_LLONG */
        +
        +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
        +        {
        +	BN_ULONG t1,t2;
        +	int c=0;
        +
        +	assert(n >= 0);
        +	if (n <= 0) return((BN_ULONG)0);
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	while (n&~3)
        +		{
        +		t1=a[0]; t2=b[0];
        +		r[0]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		t1=a[1]; t2=b[1];
        +		r[1]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		t1=a[2]; t2=b[2];
        +		r[2]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		t1=a[3]; t2=b[3];
        +		r[3]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		a+=4; b+=4; r+=4; n-=4;
        +		}
        +#endif
        +	while (n)
        +		{
        +		t1=a[0]; t2=b[0];
        +		r[0]=(t1-t2-c)&BN_MASK2;
        +		if (t1 != t2) c=(t1 < t2);
        +		a++; b++; r++; n--;
        +		}
        +	return(c);
        +	}
        +
        +#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
        +
        +#undef bn_mul_comba8
        +#undef bn_mul_comba4
        +#undef bn_sqr_comba8
        +#undef bn_sqr_comba4
        +
        +/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
        +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
        +/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
        +/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
        +
        +#ifdef BN_LLONG
        +#define mul_add_c(a,b,c0,c1,c2) \
        +	t=(BN_ULLONG)a*b; \
        +	t1=(BN_ULONG)Lw(t); \
        +	t2=(BN_ULONG)Hw(t); \
        +	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
        +	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
        +
        +#define mul_add_c2(a,b,c0,c1,c2) \
        +	t=(BN_ULLONG)a*b; \
        +	tt=(t+t)&BN_MASK; \
        +	if (tt < t) c2++; \
        +	t1=(BN_ULONG)Lw(tt); \
        +	t2=(BN_ULONG)Hw(tt); \
        +	c0=(c0+t1)&BN_MASK2;  \
        +	if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
        +	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
        +
        +#define sqr_add_c(a,i,c0,c1,c2) \
        +	t=(BN_ULLONG)a[i]*a[i]; \
        +	t1=(BN_ULONG)Lw(t); \
        +	t2=(BN_ULONG)Hw(t); \
        +	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
        +	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
        +
        +#define sqr_add_c2(a,i,j,c0,c1,c2) \
        +	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
        +
        +#elif defined(BN_UMULT_LOHI)
        +
        +#define mul_add_c(a,b,c0,c1,c2)	{	\
        +	BN_ULONG ta=(a),tb=(b);		\
        +	BN_UMULT_LOHI(t1,t2,ta,tb);	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define mul_add_c2(a,b,c0,c1,c2) {	\
        +	BN_ULONG ta=(a),tb=(b),t0;	\
        +	BN_UMULT_LOHI(t0,t1,ta,tb);	\
        +	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
        +	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define sqr_add_c(a,i,c0,c1,c2)	{	\
        +	BN_ULONG ta=(a)[i];		\
        +	BN_UMULT_LOHI(t1,t2,ta,ta);	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define sqr_add_c2(a,i,j,c0,c1,c2)	\
        +	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
        +
        +#elif defined(BN_UMULT_HIGH)
        +
        +#define mul_add_c(a,b,c0,c1,c2)	{	\
        +	BN_ULONG ta=(a),tb=(b);		\
        +	t1 = ta * tb;			\
        +	t2 = BN_UMULT_HIGH(ta,tb);	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define mul_add_c2(a,b,c0,c1,c2) {	\
        +	BN_ULONG ta=(a),tb=(b),t0;	\
        +	t1 = BN_UMULT_HIGH(ta,tb);	\
        +	t0 = ta * tb;			\
        +	t2 = t1+t1; c2 += (t2<t1)?1:0;	\
        +	t1 = t0+t0; t2 += (t1<t0)?1:0;	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define sqr_add_c(a,i,c0,c1,c2)	{	\
        +	BN_ULONG ta=(a)[i];		\
        +	t1 = ta * ta;			\
        +	t2 = BN_UMULT_HIGH(ta,ta);	\
        +	c0 += t1; t2 += (c0<t1)?1:0;	\
        +	c1 += t2; c2 += (c1<t2)?1:0;	\
        +	}
        +
        +#define sqr_add_c2(a,i,j,c0,c1,c2)	\
        +	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
        +
        +#else /* !BN_LLONG */
        +#define mul_add_c(a,b,c0,c1,c2) \
        +	t1=LBITS(a); t2=HBITS(a); \
        +	bl=LBITS(b); bh=HBITS(b); \
        +	mul64(t1,t2,bl,bh); \
        +	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
        +	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
        +
        +#define mul_add_c2(a,b,c0,c1,c2) \
        +	t1=LBITS(a); t2=HBITS(a); \
        +	bl=LBITS(b); bh=HBITS(b); \
        +	mul64(t1,t2,bl,bh); \
        +	if (t2 & BN_TBIT) c2++; \
        +	t2=(t2+t2)&BN_MASK2; \
        +	if (t1 & BN_TBIT) t2++; \
        +	t1=(t1+t1)&BN_MASK2; \
        +	c0=(c0+t1)&BN_MASK2;  \
        +	if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
        +	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
        +
        +#define sqr_add_c(a,i,c0,c1,c2) \
        +	sqr64(t1,t2,(a)[i]); \
        +	c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
        +	c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
        +
        +#define sqr_add_c2(a,i,j,c0,c1,c2) \
        +	mul_add_c2((a)[i],(a)[j],c0,c1,c2)
        +#endif /* !BN_LLONG */
        +
        +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +	{
        +#ifdef BN_LLONG
        +	BN_ULLONG t;
        +#else
        +	BN_ULONG bl,bh;
        +#endif
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	mul_add_c(a[0],b[0],c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	mul_add_c(a[0],b[1],c2,c3,c1);
        +	mul_add_c(a[1],b[0],c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	mul_add_c(a[2],b[0],c3,c1,c2);
        +	mul_add_c(a[1],b[1],c3,c1,c2);
        +	mul_add_c(a[0],b[2],c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	mul_add_c(a[0],b[3],c1,c2,c3);
        +	mul_add_c(a[1],b[2],c1,c2,c3);
        +	mul_add_c(a[2],b[1],c1,c2,c3);
        +	mul_add_c(a[3],b[0],c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	mul_add_c(a[4],b[0],c2,c3,c1);
        +	mul_add_c(a[3],b[1],c2,c3,c1);
        +	mul_add_c(a[2],b[2],c2,c3,c1);
        +	mul_add_c(a[1],b[3],c2,c3,c1);
        +	mul_add_c(a[0],b[4],c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	mul_add_c(a[0],b[5],c3,c1,c2);
        +	mul_add_c(a[1],b[4],c3,c1,c2);
        +	mul_add_c(a[2],b[3],c3,c1,c2);
        +	mul_add_c(a[3],b[2],c3,c1,c2);
        +	mul_add_c(a[4],b[1],c3,c1,c2);
        +	mul_add_c(a[5],b[0],c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	mul_add_c(a[6],b[0],c1,c2,c3);
        +	mul_add_c(a[5],b[1],c1,c2,c3);
        +	mul_add_c(a[4],b[2],c1,c2,c3);
        +	mul_add_c(a[3],b[3],c1,c2,c3);
        +	mul_add_c(a[2],b[4],c1,c2,c3);
        +	mul_add_c(a[1],b[5],c1,c2,c3);
        +	mul_add_c(a[0],b[6],c1,c2,c3);
        +	r[6]=c1;
        +	c1=0;
        +	mul_add_c(a[0],b[7],c2,c3,c1);
        +	mul_add_c(a[1],b[6],c2,c3,c1);
        +	mul_add_c(a[2],b[5],c2,c3,c1);
        +	mul_add_c(a[3],b[4],c2,c3,c1);
        +	mul_add_c(a[4],b[3],c2,c3,c1);
        +	mul_add_c(a[5],b[2],c2,c3,c1);
        +	mul_add_c(a[6],b[1],c2,c3,c1);
        +	mul_add_c(a[7],b[0],c2,c3,c1);
        +	r[7]=c2;
        +	c2=0;
        +	mul_add_c(a[7],b[1],c3,c1,c2);
        +	mul_add_c(a[6],b[2],c3,c1,c2);
        +	mul_add_c(a[5],b[3],c3,c1,c2);
        +	mul_add_c(a[4],b[4],c3,c1,c2);
        +	mul_add_c(a[3],b[5],c3,c1,c2);
        +	mul_add_c(a[2],b[6],c3,c1,c2);
        +	mul_add_c(a[1],b[7],c3,c1,c2);
        +	r[8]=c3;
        +	c3=0;
        +	mul_add_c(a[2],b[7],c1,c2,c3);
        +	mul_add_c(a[3],b[6],c1,c2,c3);
        +	mul_add_c(a[4],b[5],c1,c2,c3);
        +	mul_add_c(a[5],b[4],c1,c2,c3);
        +	mul_add_c(a[6],b[3],c1,c2,c3);
        +	mul_add_c(a[7],b[2],c1,c2,c3);
        +	r[9]=c1;
        +	c1=0;
        +	mul_add_c(a[7],b[3],c2,c3,c1);
        +	mul_add_c(a[6],b[4],c2,c3,c1);
        +	mul_add_c(a[5],b[5],c2,c3,c1);
        +	mul_add_c(a[4],b[6],c2,c3,c1);
        +	mul_add_c(a[3],b[7],c2,c3,c1);
        +	r[10]=c2;
        +	c2=0;
        +	mul_add_c(a[4],b[7],c3,c1,c2);
        +	mul_add_c(a[5],b[6],c3,c1,c2);
        +	mul_add_c(a[6],b[5],c3,c1,c2);
        +	mul_add_c(a[7],b[4],c3,c1,c2);
        +	r[11]=c3;
        +	c3=0;
        +	mul_add_c(a[7],b[5],c1,c2,c3);
        +	mul_add_c(a[6],b[6],c1,c2,c3);
        +	mul_add_c(a[5],b[7],c1,c2,c3);
        +	r[12]=c1;
        +	c1=0;
        +	mul_add_c(a[6],b[7],c2,c3,c1);
        +	mul_add_c(a[7],b[6],c2,c3,c1);
        +	r[13]=c2;
        +	c2=0;
        +	mul_add_c(a[7],b[7],c3,c1,c2);
        +	r[14]=c3;
        +	r[15]=c1;
        +	}
        +
        +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +	{
        +#ifdef BN_LLONG
        +	BN_ULLONG t;
        +#else
        +	BN_ULONG bl,bh;
        +#endif
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	mul_add_c(a[0],b[0],c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	mul_add_c(a[0],b[1],c2,c3,c1);
        +	mul_add_c(a[1],b[0],c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	mul_add_c(a[2],b[0],c3,c1,c2);
        +	mul_add_c(a[1],b[1],c3,c1,c2);
        +	mul_add_c(a[0],b[2],c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	mul_add_c(a[0],b[3],c1,c2,c3);
        +	mul_add_c(a[1],b[2],c1,c2,c3);
        +	mul_add_c(a[2],b[1],c1,c2,c3);
        +	mul_add_c(a[3],b[0],c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	mul_add_c(a[3],b[1],c2,c3,c1);
        +	mul_add_c(a[2],b[2],c2,c3,c1);
        +	mul_add_c(a[1],b[3],c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	mul_add_c(a[2],b[3],c3,c1,c2);
        +	mul_add_c(a[3],b[2],c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	mul_add_c(a[3],b[3],c1,c2,c3);
        +	r[6]=c1;
        +	r[7]=c2;
        +	}
        +
        +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
        +	{
        +#ifdef BN_LLONG
        +	BN_ULLONG t,tt;
        +#else
        +	BN_ULONG bl,bh;
        +#endif
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	sqr_add_c(a,0,c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	sqr_add_c2(a,1,0,c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	sqr_add_c(a,1,c3,c1,c2);
        +	sqr_add_c2(a,2,0,c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	sqr_add_c2(a,3,0,c1,c2,c3);
        +	sqr_add_c2(a,2,1,c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	sqr_add_c(a,2,c2,c3,c1);
        +	sqr_add_c2(a,3,1,c2,c3,c1);
        +	sqr_add_c2(a,4,0,c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	sqr_add_c2(a,5,0,c3,c1,c2);
        +	sqr_add_c2(a,4,1,c3,c1,c2);
        +	sqr_add_c2(a,3,2,c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	sqr_add_c(a,3,c1,c2,c3);
        +	sqr_add_c2(a,4,2,c1,c2,c3);
        +	sqr_add_c2(a,5,1,c1,c2,c3);
        +	sqr_add_c2(a,6,0,c1,c2,c3);
        +	r[6]=c1;
        +	c1=0;
        +	sqr_add_c2(a,7,0,c2,c3,c1);
        +	sqr_add_c2(a,6,1,c2,c3,c1);
        +	sqr_add_c2(a,5,2,c2,c3,c1);
        +	sqr_add_c2(a,4,3,c2,c3,c1);
        +	r[7]=c2;
        +	c2=0;
        +	sqr_add_c(a,4,c3,c1,c2);
        +	sqr_add_c2(a,5,3,c3,c1,c2);
        +	sqr_add_c2(a,6,2,c3,c1,c2);
        +	sqr_add_c2(a,7,1,c3,c1,c2);
        +	r[8]=c3;
        +	c3=0;
        +	sqr_add_c2(a,7,2,c1,c2,c3);
        +	sqr_add_c2(a,6,3,c1,c2,c3);
        +	sqr_add_c2(a,5,4,c1,c2,c3);
        +	r[9]=c1;
        +	c1=0;
        +	sqr_add_c(a,5,c2,c3,c1);
        +	sqr_add_c2(a,6,4,c2,c3,c1);
        +	sqr_add_c2(a,7,3,c2,c3,c1);
        +	r[10]=c2;
        +	c2=0;
        +	sqr_add_c2(a,7,4,c3,c1,c2);
        +	sqr_add_c2(a,6,5,c3,c1,c2);
        +	r[11]=c3;
        +	c3=0;
        +	sqr_add_c(a,6,c1,c2,c3);
        +	sqr_add_c2(a,7,5,c1,c2,c3);
        +	r[12]=c1;
        +	c1=0;
        +	sqr_add_c2(a,7,6,c2,c3,c1);
        +	r[13]=c2;
        +	c2=0;
        +	sqr_add_c(a,7,c3,c1,c2);
        +	r[14]=c3;
        +	r[15]=c1;
        +	}
        +
        +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
        +	{
        +#ifdef BN_LLONG
        +	BN_ULLONG t,tt;
        +#else
        +	BN_ULONG bl,bh;
        +#endif
        +	BN_ULONG t1,t2;
        +	BN_ULONG c1,c2,c3;
        +
        +	c1=0;
        +	c2=0;
        +	c3=0;
        +	sqr_add_c(a,0,c1,c2,c3);
        +	r[0]=c1;
        +	c1=0;
        +	sqr_add_c2(a,1,0,c2,c3,c1);
        +	r[1]=c2;
        +	c2=0;
        +	sqr_add_c(a,1,c3,c1,c2);
        +	sqr_add_c2(a,2,0,c3,c1,c2);
        +	r[2]=c3;
        +	c3=0;
        +	sqr_add_c2(a,3,0,c1,c2,c3);
        +	sqr_add_c2(a,2,1,c1,c2,c3);
        +	r[3]=c1;
        +	c1=0;
        +	sqr_add_c(a,2,c2,c3,c1);
        +	sqr_add_c2(a,3,1,c2,c3,c1);
        +	r[4]=c2;
        +	c2=0;
        +	sqr_add_c2(a,3,2,c3,c1,c2);
        +	r[5]=c3;
        +	c3=0;
        +	sqr_add_c(a,3,c1,c2,c3);
        +	r[6]=c1;
        +	r[7]=c2;
        +	}
        +
        +#ifdef OPENSSL_NO_ASM
        +#ifdef OPENSSL_BN_ASM_MONT
        +#include <alloca.h>
        +/*
        + * This is essentially reference implementation, which may or may not
        + * result in performance improvement. E.g. on IA-32 this routine was
        + * observed to give 40% faster rsa1024 private key operations and 10%
        + * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
        + * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
        + * reference implementation, one to be used as starting point for
        + * platform-specific assembler. Mentioned numbers apply to compiler
        + * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
        + * can vary not only from platform to platform, but even for compiler
        + * versions. Assembler vs. assembler improvement coefficients can
        + * [and are known to] differ and are to be documented elsewhere.
        + */
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
        +	{
        +	BN_ULONG c0,c1,ml,*tp,n0;
        +#ifdef mul64
        +	BN_ULONG mh;
        +#endif
        +	volatile BN_ULONG *vp;
        +	int i=0,j;
        +
        +#if 0	/* template for platform-specific implementation */
        +	if (ap==bp)	return bn_sqr_mont(rp,ap,np,n0p,num);
        +#endif
        +	vp = tp = alloca((num+2)*sizeof(BN_ULONG));
        +
        +	n0 = *n0p;
        +
        +	c0 = 0;
        +	ml = bp[0];
        +#ifdef mul64
        +	mh = HBITS(ml);
        +	ml = LBITS(ml);
        +	for (j=0;j<num;++j)
        +		mul(tp[j],ap[j],ml,mh,c0);
        +#else
        +	for (j=0;j<num;++j)
        +		mul(tp[j],ap[j],ml,c0);
        +#endif
        +
        +	tp[num]   = c0;
        +	tp[num+1] = 0;
        +	goto enter;
        +
        +	for(i=0;i<num;i++)
        +		{
        +		c0 = 0;
        +		ml = bp[i];
        +#ifdef mul64
        +		mh = HBITS(ml);
        +		ml = LBITS(ml);
        +		for (j=0;j<num;++j)
        +			mul_add(tp[j],ap[j],ml,mh,c0);
        +#else
        +		for (j=0;j<num;++j)
        +			mul_add(tp[j],ap[j],ml,c0);
        +#endif
        +		c1 = (tp[num] + c0)&BN_MASK2;
        +		tp[num]   = c1;
        +		tp[num+1] = (c1<c0?1:0);
        +	enter:
        +		c1  = tp[0];
        +		ml = (c1*n0)&BN_MASK2;
        +		c0 = 0;
        +#ifdef mul64
        +		mh = HBITS(ml);
        +		ml = LBITS(ml);
        +		mul_add(c1,np[0],ml,mh,c0);
        +#else
        +		mul_add(c1,ml,np[0],c0);
        +#endif
        +		for(j=1;j<num;j++)
        +			{
        +			c1 = tp[j];
        +#ifdef mul64
        +			mul_add(c1,np[j],ml,mh,c0);
        +#else
        +			mul_add(c1,ml,np[j],c0);
        +#endif
        +			tp[j-1] = c1&BN_MASK2;
        +			}
        +		c1        = (tp[num] + c0)&BN_MASK2;
        +		tp[num-1] = c1;
        +		tp[num]   = tp[num+1] + (c1<c0?1:0);
        +		}
        +
        +	if (tp[num]!=0 || tp[num-1]>=np[num-1])
        +		{
        +		c0 = bn_sub_words(rp,tp,np,num);
        +		if (tp[num]!=0 || c0==0)
        +			{
        +			for(i=0;i<num+2;i++)	vp[i] = 0;
        +			return 1;
        +			}
        +		}
        +	for(i=0;i<num;i++)	rp[i] = tp[i],	vp[i] = 0;
        +	vp[num]   = 0;
        +	vp[num+1] = 0;
        +	return 1;
        +	}
        +#else
        +/*
        + * Return value of 0 indicates that multiplication/convolution was not
        + * performed to signal the caller to fall down to alternative/original
        + * code-path.
        + */
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
        +{	return 0;	}
        +#endif /* OPENSSL_BN_ASM_MONT */
        +#endif
        +
        +#else /* !BN_MUL_COMBA */
        +
        +/* hmm... is it faster just to do a multiply? */
        +#undef bn_sqr_comba4
        +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
        +	{
        +	BN_ULONG t[8];
        +	bn_sqr_normal(r,a,4,t);
        +	}
        +
        +#undef bn_sqr_comba8
        +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
        +	{
        +	BN_ULONG t[16];
        +	bn_sqr_normal(r,a,8,t);
        +	}
        +
        +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +	{
        +	r[4]=bn_mul_words(    &(r[0]),a,4,b[0]);
        +	r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]);
        +	r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]);
        +	r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]);
        +	}
        +
        +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
        +	{
        +	r[ 8]=bn_mul_words(    &(r[0]),a,8,b[0]);
        +	r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
        +	r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
        +	r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
        +	r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
        +	r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
        +	r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
        +	r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
        +	}
        +
        +#ifdef OPENSSL_NO_ASM
        +#ifdef OPENSSL_BN_ASM_MONT
        +#include <alloca.h>
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
        +	{
        +	BN_ULONG c0,c1,*tp,n0=*n0p;
        +	volatile BN_ULONG *vp;
        +	int i=0,j;
        +
        +	vp = tp = alloca((num+2)*sizeof(BN_ULONG));
        +
        +	for(i=0;i<=num;i++)	tp[i]=0;
        +
        +	for(i=0;i<num;i++)
        +		{
        +		c0         = bn_mul_add_words(tp,ap,num,bp[i]);
        +		c1         = (tp[num] + c0)&BN_MASK2;
        +		tp[num]    = c1;
        +		tp[num+1]  = (c1<c0?1:0);
        +
        +		c0         = bn_mul_add_words(tp,np,num,tp[0]*n0);
        +		c1         = (tp[num] + c0)&BN_MASK2;
        +		tp[num]    = c1;
        +		tp[num+1] += (c1<c0?1:0);
        +		for(j=0;j<=num;j++)	tp[j]=tp[j+1];
        +		}
        +
        +	if (tp[num]!=0 || tp[num-1]>=np[num-1])
        +		{
        +		c0 = bn_sub_words(rp,tp,np,num);
        +		if (tp[num]!=0 || c0==0)
        +			{
        +			for(i=0;i<num+2;i++)	vp[i] = 0;
        +			return 1;
        +			}
        +		}
        +	for(i=0;i<num;i++)	rp[i] = tp[i],	vp[i] = 0;
        +	vp[num]   = 0;
        +	vp[num+1] = 0;
        +	return 1;
        +	}
        +#else
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
        +{	return 0;	}
        +#endif /* OPENSSL_BN_ASM_MONT */
        +#endif
        +
        +#endif /* !BN_MUL_COMBA */
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_blind.c b/vendor/openssl/openssl/crypto/bn/bn_blind.c
        new file mode 100644
        index 000000000..9ed8bc2b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_blind.c
        @@ -0,0 +1,385 @@
        +/* crypto/bn/bn_blind.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +#define BN_BLINDING_COUNTER	32
        +
        +struct bn_blinding_st
        +	{
        +	BIGNUM *A;
        +	BIGNUM *Ai;
        +	BIGNUM *e;
        +	BIGNUM *mod; /* just a reference */
        +#ifndef OPENSSL_NO_DEPRECATED
        +	unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
        +				  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
        +#endif
        +	CRYPTO_THREADID tid;
        +	int counter;
        +	unsigned long flags;
        +	BN_MONT_CTX *m_ctx;
        +	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx,
        +			  BN_MONT_CTX *m_ctx);
        +	};
        +
        +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
        +	{
        +	BN_BLINDING *ret=NULL;
        +
        +	bn_check_top(mod);
        +
        +	if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL)
        +		{
        +		BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	memset(ret,0,sizeof(BN_BLINDING));
        +	if (A != NULL)
        +		{
        +		if ((ret->A  = BN_dup(A))  == NULL) goto err;
        +		}
        +	if (Ai != NULL)
        +		{
        +		if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
        +		}
        +
        +	/* save a copy of mod in the BN_BLINDING structure */
        +	if ((ret->mod = BN_dup(mod)) == NULL) goto err;
        +	if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
        +		BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
        +
        +	/* Set the counter to the special value -1
        +	 * to indicate that this is never-used fresh blinding
        +	 * that does not need updating before first use. */
        +	ret->counter = -1;
        +	CRYPTO_THREADID_current(&ret->tid);
        +	return(ret);
        +err:
        +	if (ret != NULL) BN_BLINDING_free(ret);
        +	return(NULL);
        +	}
        +
        +void BN_BLINDING_free(BN_BLINDING *r)
        +	{
        +	if(r == NULL)
        +	    return;
        +
        +	if (r->A  != NULL) BN_free(r->A );
        +	if (r->Ai != NULL) BN_free(r->Ai);
        +	if (r->e  != NULL) BN_free(r->e );
        +	if (r->mod != NULL) BN_free(r->mod); 
        +	OPENSSL_free(r);
        +	}
        +
        +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
        +	{
        +	int ret=0;
        +
        +	if ((b->A == NULL) || (b->Ai == NULL))
        +		{
        +		BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED);
        +		goto err;
        +		}
        +
        +	if (b->counter == -1)
        +		b->counter = 0;
        +
        +	if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
        +		!(b->flags & BN_BLINDING_NO_RECREATE))
        +		{
        +		/* re-create blinding parameters */
        +		if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
        +			goto err;
        +		}
        +	else if (!(b->flags & BN_BLINDING_NO_UPDATE))
        +		{
        +		if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err;
        +		if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err;
        +		}
        +
        +	ret=1;
        +err:
        +	if (b->counter == BN_BLINDING_COUNTER)
        +		b->counter = 0;
        +	return(ret);
        +	}
        +
        +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
        +	{
        +	return BN_BLINDING_convert_ex(n, NULL, b, ctx);
        +	}
        +
        +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
        +	{
        +	int ret = 1;
        +
        +	bn_check_top(n);
        +
        +	if ((b->A == NULL) || (b->Ai == NULL))
        +		{
        +		BNerr(BN_F_BN_BLINDING_CONVERT_EX,BN_R_NOT_INITIALIZED);
        +		return(0);
        +		}
        +
        +	if (b->counter == -1)
        +		/* Fresh blinding, doesn't need updating. */
        +		b->counter = 0;
        +	else if (!BN_BLINDING_update(b,ctx))
        +		return(0);
        +
        +	if (r != NULL)
        +		{
        +		if (!BN_copy(r, b->Ai)) ret=0;
        +		}
        +
        +	if (!BN_mod_mul(n,n,b->A,b->mod,ctx)) ret=0;
        +	
        +	return ret;
        +	}
        +
        +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
        +	{
        +	return BN_BLINDING_invert_ex(n, NULL, b, ctx);
        +	}
        +
        +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
        +	{
        +	int ret;
        +
        +	bn_check_top(n);
        +
        +	if (r != NULL)
        +		ret = BN_mod_mul(n, n, r, b->mod, ctx);
        +	else
        +		{
        +		if (b->Ai == NULL)
        +			{
        +			BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED);
        +			return(0);
        +			}
        +		ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
        +		}
        +
        +	bn_check_top(n);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
        +	{
        +	return b->thread_id;
        +	}
        +
        +void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
        +	{
        +	b->thread_id = n;
        +	}
        +#endif
        +
        +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
        +	{
        +	return &b->tid;
        +	}
        +
        +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
        +	{
        +	return b->flags;
        +	}
        +
        +void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
        +	{
        +	b->flags = flags;
        +	}
        +
        +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
        +	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
        +	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
        +	BN_MONT_CTX *m_ctx)
        +{
        +	int    retry_counter = 32;
        +	BN_BLINDING *ret = NULL;
        +
        +	if (b == NULL)
        +		ret = BN_BLINDING_new(NULL, NULL, m);
        +	else
        +		ret = b;
        +
        +	if (ret == NULL)
        +		goto err;
        +
        +	if (ret->A  == NULL && (ret->A  = BN_new()) == NULL)
        +		goto err;
        +	if (ret->Ai == NULL && (ret->Ai	= BN_new()) == NULL)
        +		goto err;
        +
        +	if (e != NULL)
        +		{
        +		if (ret->e != NULL)
        +			BN_free(ret->e);
        +		ret->e = BN_dup(e);
        +		}
        +	if (ret->e == NULL)
        +		goto err;
        +
        +	if (bn_mod_exp != NULL)
        +		ret->bn_mod_exp = bn_mod_exp;
        +	if (m_ctx != NULL)
        +		ret->m_ctx = m_ctx;
        +
        +	do {
        +		if (!BN_rand_range(ret->A, ret->mod)) goto err;
        +		if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL)
        +			{
        +			/* this should almost never happen for good RSA keys */
        +			unsigned long error = ERR_peek_last_error();
        +			if (ERR_GET_REASON(error) == BN_R_NO_INVERSE)
        +				{
        +				if (retry_counter-- == 0)
        +				{
        +					BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
        +						BN_R_TOO_MANY_ITERATIONS);
        +					goto err;
        +				}
        +				ERR_clear_error();
        +				}
        +			else
        +				goto err;
        +			}
        +		else
        +			break;
        +	} while (1);
        +
        +	if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL)
        +		{
        +		if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
        +			goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
        +			goto err;
        +		}
        +
        +	return ret;
        +err:
        +	if (b == NULL && ret != NULL)
        +		{
        +		BN_BLINDING_free(ret);
        +		ret = NULL;
        +		}
        +
        +	return ret;
        +}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_const.c b/vendor/openssl/openssl/crypto/bn/bn_const.c
        new file mode 100644
        index 000000000..eb60a25b3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_const.c
        @@ -0,0 +1,402 @@
        +/* crypto/bn/knownprimes.c */
        +/* Insert boilerplate */
        +
        +#include "bn.h"
        +
        +/* "First Oakley Default Group" from RFC2409, section 6.1.
        + *
        + * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
        + *
        + * RFC2409 specifies a generator of 2.
        + * RFC2412 specifies a generator of of 22.
        + */
        +
        +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC2409_PRIME_768[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC2409_PRIME_768,sizeof(RFC2409_PRIME_768),bn);
        +	}
        +
        +/* "Second Oakley Default Group" from RFC2409, section 6.2.
        + *
        + * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
        + *
        + * RFC2409 specifies a generator of 2.
        + * RFC2412 specifies a generator of 22.
        + */
        +
        +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC2409_PRIME_1024[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC2409_PRIME_1024,sizeof(RFC2409_PRIME_1024),bn);
        +	}
        +
        +/* "1536-bit MODP Group" from RFC3526, Section 2.
        + *
        + * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
        + *
        + * RFC3526 specifies a generator of 2.
        + * RFC2312 specifies a generator of 22.
        + */
        +
        +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC3526_PRIME_1536[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        +		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
        +		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        +		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
        +		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        +		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
        +		0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC3526_PRIME_1536,sizeof(RFC3526_PRIME_1536),bn);
        +	}
        +
        +/* "2048-bit MODP Group" from RFC3526, Section 3.
        + *
        + * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
        + *
        + * RFC3526 specifies a generator of 2.
        + */
        +
        +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC3526_PRIME_2048[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        +		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
        +		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        +		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
        +		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        +		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
        +		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
        +		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
        +		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
        +		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
        +		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
        +		0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
        +		0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC3526_PRIME_2048,sizeof(RFC3526_PRIME_2048),bn);
        +	}
        +
        +/* "3072-bit MODP Group" from RFC3526, Section 4.
        + *
        + * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
        + *
        + * RFC3526 specifies a generator of 2.
        + */
        +
        +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC3526_PRIME_3072[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        +		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
        +		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        +		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
        +		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        +		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
        +		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
        +		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
        +		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
        +		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
        +		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
        +		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
        +		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
        +		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
        +		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
        +		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
        +		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
        +		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
        +		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
        +		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
        +		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
        +		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
        +		0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC3526_PRIME_3072,sizeof(RFC3526_PRIME_3072),bn);
        +	}
        +
        +/* "4096-bit MODP Group" from RFC3526, Section 5.
        + *
        + * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
        + *
        + * RFC3526 specifies a generator of 2.
        + */
        +
        +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC3526_PRIME_4096[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        +		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
        +		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        +		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
        +		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        +		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
        +		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
        +		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
        +		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
        +		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
        +		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
        +		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
        +		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
        +		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
        +		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
        +		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
        +		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
        +		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
        +		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
        +		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
        +		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
        +		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
        +		0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
        +		0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
        +		0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
        +		0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
        +		0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
        +		0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
        +		0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
        +		0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
        +		0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
        +		0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
        +		0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC3526_PRIME_4096,sizeof(RFC3526_PRIME_4096),bn);
        +	}
        +
        +/* "6144-bit MODP Group" from RFC3526, Section 6.
        + *
        + * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
        + *
        + * RFC3526 specifies a generator of 2.
        + */
        +
        +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC3526_PRIME_6144[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        +		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
        +		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        +		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
        +		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        +		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
        +		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
        +		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
        +		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
        +		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
        +		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
        +		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
        +		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
        +		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
        +		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
        +		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
        +		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
        +		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
        +		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
        +		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
        +		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
        +		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
        +		0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
        +		0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
        +		0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
        +		0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
        +		0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
        +		0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
        +		0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
        +		0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
        +		0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
        +		0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
        +		0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
        +		0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
        +		0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
        +		0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
        +		0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
        +		0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
        +		0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
        +		0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
        +		0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
        +		0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
        +		0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
        +		0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
        +		0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
        +		0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
        +		0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
        +		0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
        +		0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
        +		0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
        +		0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
        +		0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
        +		0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
        +		0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
        +		0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC3526_PRIME_6144,sizeof(RFC3526_PRIME_6144),bn);
        +	}
        +
        +/* "8192-bit MODP Group" from RFC3526, Section 7.
        + *
        + * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
        + *
        + * RFC3526 specifies a generator of 2.
        + */
        +
        +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn)
        +	{
        +	static const unsigned char RFC3526_PRIME_8192[]={
        +		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
        +		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
        +		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
        +		0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
        +		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
        +		0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
        +		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
        +		0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
        +		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
        +		0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
        +		0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
        +		0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
        +		0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
        +		0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
        +		0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
        +		0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
        +		0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
        +		0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
        +		0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
        +		0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
        +		0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
        +		0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
        +		0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
        +		0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
        +		0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
        +		0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
        +		0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
        +		0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
        +		0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
        +		0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
        +		0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
        +		0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
        +		0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
        +		0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
        +		0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
        +		0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
        +		0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
        +		0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
        +		0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
        +		0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
        +		0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
        +		0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
        +		0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
        +		0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
        +		0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
        +		0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
        +		0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
        +		0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
        +		0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
        +		0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
        +		0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
        +		0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
        +		0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
        +		0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
        +		0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
        +		0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
        +		0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
        +		0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
        +		0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
        +		0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
        +		0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
        +		0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
        +		0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
        +		0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
        +		0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
        +		0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
        +		0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
        +		0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
        +		0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
        +		0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
        +		0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
        +		0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
        +		0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
        +		0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
        +		0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
        +		0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
        +		0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
        +		0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
        +		0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
        +		0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
        +		0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
        +		0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
        +		0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
        +		0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
        +		0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
        +		0xFF,0xFF,0xFF,0xFF,
        +		};
        +	return BN_bin2bn(RFC3526_PRIME_8192,sizeof(RFC3526_PRIME_8192),bn);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_ctx.c b/vendor/openssl/openssl/crypto/bn/bn_ctx.c
        new file mode 100644
        index 000000000..3f2256f67
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_ctx.c
        @@ -0,0 +1,454 @@
        +/* crypto/bn/bn_ctx.c */
        +/* Written by Ulf Moeller for the OpenSSL project. */
        +/* ====================================================================
        + * Copyright (c) 1998-2004 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).
        + *
        + */
        +
        +#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
        +#ifndef NDEBUG
        +#define NDEBUG
        +#endif
        +#endif
        +
        +#include <stdio.h>
        +#include <assert.h>
        +
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +/* TODO list
        + *
        + * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
        + * check they can be safely removed.
        + *  - Check +1 and other ugliness in BN_from_montgomery()
        + *
        + * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
        + * appropriate 'block' size that will be honoured by bn_expand_internal() to
        + * prevent piddly little reallocations. OTOH, profiling bignum expansions in
        + * BN_CTX doesn't show this to be a big issue.
        + */
        +
        +/* How many bignums are in each "pool item"; */
        +#define BN_CTX_POOL_SIZE	16
        +/* The stack frame info is resizing, set a first-time expansion size; */
        +#define BN_CTX_START_FRAMES	32
        +
        +/***********/
        +/* BN_POOL */
        +/***********/
        +
        +/* A bundle of bignums that can be linked with other bundles */
        +typedef struct bignum_pool_item
        +	{
        +	/* The bignum values */
        +	BIGNUM vals[BN_CTX_POOL_SIZE];
        +	/* Linked-list admin */
        +	struct bignum_pool_item *prev, *next;
        +	} BN_POOL_ITEM;
        +/* A linked-list of bignums grouped in bundles */
        +typedef struct bignum_pool
        +	{
        +	/* Linked-list admin */
        +	BN_POOL_ITEM *head, *current, *tail;
        +	/* Stack depth and allocation size */
        +	unsigned used, size;
        +	} BN_POOL;
        +static void		BN_POOL_init(BN_POOL *);
        +static void		BN_POOL_finish(BN_POOL *);
        +#ifndef OPENSSL_NO_DEPRECATED
        +static void		BN_POOL_reset(BN_POOL *);
        +#endif
        +static BIGNUM *		BN_POOL_get(BN_POOL *);
        +static void		BN_POOL_release(BN_POOL *, unsigned int);
        +
        +/************/
        +/* BN_STACK */
        +/************/
        +
        +/* A wrapper to manage the "stack frames" */
        +typedef struct bignum_ctx_stack
        +	{
        +	/* Array of indexes into the bignum stack */
        +	unsigned int *indexes;
        +	/* Number of stack frames, and the size of the allocated array */
        +	unsigned int depth, size;
        +	} BN_STACK;
        +static void		BN_STACK_init(BN_STACK *);
        +static void		BN_STACK_finish(BN_STACK *);
        +#ifndef OPENSSL_NO_DEPRECATED
        +static void		BN_STACK_reset(BN_STACK *);
        +#endif
        +static int		BN_STACK_push(BN_STACK *, unsigned int);
        +static unsigned int	BN_STACK_pop(BN_STACK *);
        +
        +/**********/
        +/* BN_CTX */
        +/**********/
        +
        +/* The opaque BN_CTX type */
        +struct bignum_ctx
        +	{
        +	/* The bignum bundles */
        +	BN_POOL pool;
        +	/* The "stack frames", if you will */
        +	BN_STACK stack;
        +	/* The number of bignums currently assigned */
        +	unsigned int used;
        +	/* Depth of stack overflow */
        +	int err_stack;
        +	/* Block "gets" until an "end" (compatibility behaviour) */
        +	int too_many;
        +	};
        +
        +/* Enable this to find BN_CTX bugs */
        +#ifdef BN_CTX_DEBUG
        +static const char *ctxdbg_cur = NULL;
        +static void ctxdbg(BN_CTX *ctx)
        +	{
        +	unsigned int bnidx = 0, fpidx = 0;
        +	BN_POOL_ITEM *item = ctx->pool.head;
        +	BN_STACK *stack = &ctx->stack;
        +	fprintf(stderr,"(%08x): ", (unsigned int)ctx);
        +	while(bnidx < ctx->used)
        +		{
        +		fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
        +		if(!(bnidx % BN_CTX_POOL_SIZE))
        +			item = item->next;
        +		}
        +	fprintf(stderr,"\n");
        +	bnidx = 0;
        +	fprintf(stderr,"          : ");
        +	while(fpidx < stack->depth)
        +		{
        +		while(bnidx++ < stack->indexes[fpidx])
        +			fprintf(stderr,"    ");
        +		fprintf(stderr,"^^^ ");
        +		bnidx++;
        +		fpidx++;
        +		}
        +	fprintf(stderr,"\n");
        +	}
        +#define CTXDBG_ENTRY(str, ctx)	do { \
        +				ctxdbg_cur = (str); \
        +				fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
        +				ctxdbg(ctx); \
        +				} while(0)
        +#define CTXDBG_EXIT(ctx)	do { \
        +				fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
        +				ctxdbg(ctx); \
        +				} while(0)
        +#define CTXDBG_RET(ctx,ret)
        +#else
        +#define CTXDBG_ENTRY(str, ctx)
        +#define CTXDBG_EXIT(ctx)
        +#define CTXDBG_RET(ctx,ret)
        +#endif
        +
        +/* This function is an evil legacy and should not be used. This implementation
        + * is WYSIWYG, though I've done my best. */
        +#ifndef OPENSSL_NO_DEPRECATED
        +void BN_CTX_init(BN_CTX *ctx)
        +	{
        +	/* Assume the caller obtained the context via BN_CTX_new() and so is
        +	 * trying to reset it for use. Nothing else makes sense, least of all
        +	 * binary compatibility from a time when they could declare a static
        +	 * variable. */
        +	BN_POOL_reset(&ctx->pool);
        +	BN_STACK_reset(&ctx->stack);
        +	ctx->used = 0;
        +	ctx->err_stack = 0;
        +	ctx->too_many = 0;
        +	}
        +#endif
        +
        +BN_CTX *BN_CTX_new(void)
        +	{
        +	BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
        +	if(!ret)
        +		{
        +		BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	/* Initialise the structure */
        +	BN_POOL_init(&ret->pool);
        +	BN_STACK_init(&ret->stack);
        +	ret->used = 0;
        +	ret->err_stack = 0;
        +	ret->too_many = 0;
        +	return ret;
        +	}
        +
        +void BN_CTX_free(BN_CTX *ctx)
        +	{
        +	if (ctx == NULL)
        +		return;
        +#ifdef BN_CTX_DEBUG
        +	{
        +	BN_POOL_ITEM *pool = ctx->pool.head;
        +	fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
        +		ctx->stack.size, ctx->pool.size);
        +	fprintf(stderr,"dmaxs: ");
        +	while(pool) {
        +		unsigned loop = 0;
        +		while(loop < BN_CTX_POOL_SIZE)
        +			fprintf(stderr,"%02x ", pool->vals[loop++].dmax);
        +		pool = pool->next;
        +	}
        +	fprintf(stderr,"\n");
        +	}
        +#endif
        +	BN_STACK_finish(&ctx->stack);
        +	BN_POOL_finish(&ctx->pool);
        +	OPENSSL_free(ctx);
        +	}
        +
        +void BN_CTX_start(BN_CTX *ctx)
        +	{
        +	CTXDBG_ENTRY("BN_CTX_start", ctx);
        +	/* If we're already overflowing ... */
        +	if(ctx->err_stack || ctx->too_many)
        +		ctx->err_stack++;
        +	/* (Try to) get a new frame pointer */
        +	else if(!BN_STACK_push(&ctx->stack, ctx->used))
        +		{
        +		BNerr(BN_F_BN_CTX_START,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
        +		ctx->err_stack++;
        +		}
        +	CTXDBG_EXIT(ctx);
        +	}
        +
        +void BN_CTX_end(BN_CTX *ctx)
        +	{
        +	CTXDBG_ENTRY("BN_CTX_end", ctx);
        +	if(ctx->err_stack)
        +		ctx->err_stack--;
        +	else
        +		{
        +		unsigned int fp = BN_STACK_pop(&ctx->stack);
        +		/* Does this stack frame have anything to release? */
        +		if(fp < ctx->used)
        +			BN_POOL_release(&ctx->pool, ctx->used - fp);
        +		ctx->used = fp;
        +		/* Unjam "too_many" in case "get" had failed */
        +		ctx->too_many = 0;
        +		}
        +	CTXDBG_EXIT(ctx);
        +	}
        +
        +BIGNUM *BN_CTX_get(BN_CTX *ctx)
        +	{
        +	BIGNUM *ret;
        +	CTXDBG_ENTRY("BN_CTX_get", ctx);
        +	if(ctx->err_stack || ctx->too_many) return NULL;
        +	if((ret = BN_POOL_get(&ctx->pool)) == NULL)
        +		{
        +		/* Setting too_many prevents repeated "get" attempts from
        +		 * cluttering the error stack. */
        +		ctx->too_many = 1;
        +		BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
        +		return NULL;
        +		}
        +	/* OK, make sure the returned bignum is "zero" */
        +	BN_zero(ret);
        +	ctx->used++;
        +	CTXDBG_RET(ctx, ret);
        +	return ret;
        +	}
        +
        +/************/
        +/* BN_STACK */
        +/************/
        +
        +static void BN_STACK_init(BN_STACK *st)
        +	{
        +	st->indexes = NULL;
        +	st->depth = st->size = 0;
        +	}
        +
        +static void BN_STACK_finish(BN_STACK *st)
        +	{
        +	if(st->size) OPENSSL_free(st->indexes);
        +	}
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +static void BN_STACK_reset(BN_STACK *st)
        +	{
        +	st->depth = 0;
        +	}
        +#endif
        +
        +static int BN_STACK_push(BN_STACK *st, unsigned int idx)
        +	{
        +	if(st->depth == st->size)
        +		/* Need to expand */
        +		{
        +		unsigned int newsize = (st->size ?
        +				(st->size * 3 / 2) : BN_CTX_START_FRAMES);
        +		unsigned int *newitems = OPENSSL_malloc(newsize *
        +						sizeof(unsigned int));
        +		if(!newitems) return 0;
        +		if(st->depth)
        +			memcpy(newitems, st->indexes, st->depth *
        +						sizeof(unsigned int));
        +		if(st->size) OPENSSL_free(st->indexes);
        +		st->indexes = newitems;
        +		st->size = newsize;
        +		}
        +	st->indexes[(st->depth)++] = idx;
        +	return 1;
        +	}
        +
        +static unsigned int BN_STACK_pop(BN_STACK *st)
        +	{
        +	return st->indexes[--(st->depth)];
        +	}
        +
        +/***********/
        +/* BN_POOL */
        +/***********/
        +
        +static void BN_POOL_init(BN_POOL *p)
        +	{
        +	p->head = p->current = p->tail = NULL;
        +	p->used = p->size = 0;
        +	}
        +
        +static void BN_POOL_finish(BN_POOL *p)
        +	{
        +	while(p->head)
        +		{
        +		unsigned int loop = 0;
        +		BIGNUM *bn = p->head->vals;
        +		while(loop++ < BN_CTX_POOL_SIZE)
        +			{
        +			if(bn->d) BN_clear_free(bn);
        +			bn++;
        +			}
        +		p->current = p->head->next;
        +		OPENSSL_free(p->head);
        +		p->head = p->current;
        +		}
        +	}
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +static void BN_POOL_reset(BN_POOL *p)
        +	{
        +	BN_POOL_ITEM *item = p->head;
        +	while(item)
        +		{
        +		unsigned int loop = 0;
        +		BIGNUM *bn = item->vals;
        +		while(loop++ < BN_CTX_POOL_SIZE)
        +			{
        +			if(bn->d) BN_clear(bn);
        +			bn++;
        +			}
        +		item = item->next;
        +		}
        +	p->current = p->head;
        +	p->used = 0;
        +	}
        +#endif
        +
        +static BIGNUM *BN_POOL_get(BN_POOL *p)
        +	{
        +	if(p->used == p->size)
        +		{
        +		BIGNUM *bn;
        +		unsigned int loop = 0;
        +		BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
        +		if(!item) return NULL;
        +		/* Initialise the structure */
        +		bn = item->vals;
        +		while(loop++ < BN_CTX_POOL_SIZE)
        +			BN_init(bn++);
        +		item->prev = p->tail;
        +		item->next = NULL;
        +		/* Link it in */
        +		if(!p->head)
        +			p->head = p->current = p->tail = item;
        +		else
        +			{
        +			p->tail->next = item;
        +			p->tail = item;
        +			p->current = item;
        +			}
        +		p->size += BN_CTX_POOL_SIZE;
        +		p->used++;
        +		/* Return the first bignum from the new pool */
        +		return item->vals;
        +		}
        +	if(!p->used)
        +		p->current = p->head;
        +	else if((p->used % BN_CTX_POOL_SIZE) == 0)
        +		p->current = p->current->next;
        +	return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
        +	}
        +
        +static void BN_POOL_release(BN_POOL *p, unsigned int num)
        +	{
        +	unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
        +	p->used -= num;
        +	while(num--)
        +		{
        +		bn_check_top(p->current->vals + offset);
        +		if(!offset)
        +			{
        +			offset = BN_CTX_POOL_SIZE - 1;
        +			p->current = p->current->prev;
        +			}
        +		else
        +			offset--;
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_depr.c b/vendor/openssl/openssl/crypto/bn/bn_depr.c
        new file mode 100644
        index 000000000..27535e4fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_depr.c
        @@ -0,0 +1,112 @@
        +/* crypto/bn/bn_depr.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +/* Support for deprecated functions goes here - static linkage will only slurp
        + * this code if applications are using them directly. */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +#include <openssl/rand.h>
        +
        +static void *dummy=&dummy;
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
        +	const BIGNUM *add, const BIGNUM *rem,
        +	void (*callback)(int,int,void *), void *cb_arg)
        +	{
        +	BN_GENCB cb;
        +	BIGNUM *rnd=NULL;
        +	int found = 0;
        +
        +	BN_GENCB_set_old(&cb, callback, cb_arg);
        +
        +	if (ret == NULL)
        +		{
        +		if ((rnd=BN_new()) == NULL) goto err;
        +		}
        +	else
        +		rnd=ret;
        +	if(!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
        +		goto err;
        +
        +	/* we have a prime :-) */
        +	found = 1;
        +err:
        +	if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
        +	return(found ? rnd : NULL);
        +	}
        +
        +int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
        +	BN_CTX *ctx_passed, void *cb_arg)
        +	{
        +	BN_GENCB cb;
        +	BN_GENCB_set_old(&cb, callback, cb_arg);
        +	return BN_is_prime_ex(a, checks, ctx_passed, &cb);
        +	}
        +
        +int BN_is_prime_fasttest(const BIGNUM *a, int checks,
        +		void (*callback)(int,int,void *),
        +		BN_CTX *ctx_passed, void *cb_arg,
        +		int do_trial_division)
        +	{
        +	BN_GENCB cb;
        +	BN_GENCB_set_old(&cb, callback, cb_arg);
        +	return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
        +				do_trial_division, &cb);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_div.c b/vendor/openssl/openssl/crypto/bn/bn_div.c
        new file mode 100644
        index 000000000..7b2403185
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_div.c
        @@ -0,0 +1,448 @@
        +/* crypto/bn/bn_div.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/bn.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +
        +/* The old slow way */
        +#if 0
        +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
        +	   BN_CTX *ctx)
        +	{
        +	int i,nm,nd;
        +	int ret = 0;
        +	BIGNUM *D;
        +
        +	bn_check_top(m);
        +	bn_check_top(d);
        +	if (BN_is_zero(d))
        +		{
        +		BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
        +		return(0);
        +		}
        +
        +	if (BN_ucmp(m,d) < 0)
        +		{
        +		if (rem != NULL)
        +			{ if (BN_copy(rem,m) == NULL) return(0); }
        +		if (dv != NULL) BN_zero(dv);
        +		return(1);
        +		}
        +
        +	BN_CTX_start(ctx);
        +	D = BN_CTX_get(ctx);
        +	if (dv == NULL) dv = BN_CTX_get(ctx);
        +	if (rem == NULL) rem = BN_CTX_get(ctx);
        +	if (D == NULL || dv == NULL || rem == NULL)
        +		goto end;
        +
        +	nd=BN_num_bits(d);
        +	nm=BN_num_bits(m);
        +	if (BN_copy(D,d) == NULL) goto end;
        +	if (BN_copy(rem,m) == NULL) goto end;
        +
        +	/* The next 2 are needed so we can do a dv->d[0]|=1 later
        +	 * since BN_lshift1 will only work once there is a value :-) */
        +	BN_zero(dv);
        +	if(bn_wexpand(dv,1) == NULL) goto end;
        +	dv->top=1;
        +
        +	if (!BN_lshift(D,D,nm-nd)) goto end;
        +	for (i=nm-nd; i>=0; i--)
        +		{
        +		if (!BN_lshift1(dv,dv)) goto end;
        +		if (BN_ucmp(rem,D) >= 0)
        +			{
        +			dv->d[0]|=1;
        +			if (!BN_usub(rem,rem,D)) goto end;
        +			}
        +/* CAN IMPROVE (and have now :=) */
        +		if (!BN_rshift1(D,D)) goto end;
        +		}
        +	rem->neg=BN_is_zero(rem)?0:m->neg;
        +	dv->neg=m->neg^d->neg;
        +	ret = 1;
        + end:
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +#else
        +
        +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
        +    && !defined(PEDANTIC) && !defined(BN_DIV3W)
        +# if defined(__GNUC__) && __GNUC__>=2
        +#  if defined(__i386) || defined (__i386__)
        +   /*
        +    * There were two reasons for implementing this template:
        +    * - GNU C generates a call to a function (__udivdi3 to be exact)
        +    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
        +    *   understand why...);
        +    * - divl doesn't only calculate quotient, but also leaves
        +    *   remainder in %edx which we can definitely use here:-)
        +    *
        +    *					<appro@fy.chalmers.se>
        +    */
        +#undef bn_div_words
        +#  define bn_div_words(n0,n1,d0)		\
        +	({  asm volatile (			\
        +		"divl	%4"			\
        +		: "=a"(q), "=d"(rem)		\
        +		: "a"(n1), "d"(n0), "g"(d0)	\
        +		: "cc");			\
        +	    q;					\
        +	})
        +#  define REMAINDER_IS_ALREADY_CALCULATED
        +#  elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
        +   /*
        +    * Same story here, but it's 128-bit by 64-bit division. Wow!
        +    *					<appro@fy.chalmers.se>
        +    */
        +#  undef bn_div_words
        +#  define bn_div_words(n0,n1,d0)		\
        +	({  asm volatile (			\
        +		"divq	%4"			\
        +		: "=a"(q), "=d"(rem)		\
        +		: "a"(n1), "d"(n0), "g"(d0)	\
        +		: "cc");			\
        +	    q;					\
        +	})
        +#  define REMAINDER_IS_ALREADY_CALCULATED
        +#  endif /* __<cpu> */
        +# endif /* __GNUC__ */
        +#endif /* OPENSSL_NO_ASM */
        +
        +
        +/* BN_div computes  dv := num / divisor,  rounding towards
        + * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
        + * Thus:
        + *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
        + *     rm->neg == num->neg                 (unless the remainder is zero)
        + * If 'dv' or 'rm' is NULL, the respective value is not returned.
        + */
        +int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
        +	   BN_CTX *ctx)
        +	{
        +	int norm_shift,i,loop;
        +	BIGNUM *tmp,wnum,*snum,*sdiv,*res;
        +	BN_ULONG *resp,*wnump;
        +	BN_ULONG d0,d1;
        +	int num_n,div_n;
        +	int no_branch=0;
        +
        +	/* Invalid zero-padding would have particularly bad consequences
        +	 * in the case of 'num', so don't just rely on bn_check_top() for this one
        +	 * (bn_check_top() works only for BN_DEBUG builds) */
        +	if (num->top > 0 && num->d[num->top - 1] == 0)
        +		{
        +		BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED);
        +		return 0;
        +		}
        +
        +	bn_check_top(num);
        +
        +	if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
        +		{
        +		no_branch=1;
        +		}
        +
        +	bn_check_top(dv);
        +	bn_check_top(rm);
        +	/* bn_check_top(num); */ /* 'num' has been checked already */
        +	bn_check_top(divisor);
        +
        +	if (BN_is_zero(divisor))
        +		{
        +		BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
        +		return(0);
        +		}
        +
        +	if (!no_branch && BN_ucmp(num,divisor) < 0)
        +		{
        +		if (rm != NULL)
        +			{ if (BN_copy(rm,num) == NULL) return(0); }
        +		if (dv != NULL) BN_zero(dv);
        +		return(1);
        +		}
        +
        +	BN_CTX_start(ctx);
        +	tmp=BN_CTX_get(ctx);
        +	snum=BN_CTX_get(ctx);
        +	sdiv=BN_CTX_get(ctx);
        +	if (dv == NULL)
        +		res=BN_CTX_get(ctx);
        +	else	res=dv;
        +	if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
        +		goto err;
        +
        +	/* First we normalise the numbers */
        +	norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
        +	if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
        +	sdiv->neg=0;
        +	norm_shift+=BN_BITS2;
        +	if (!(BN_lshift(snum,num,norm_shift))) goto err;
        +	snum->neg=0;
        +
        +	if (no_branch)
        +		{
        +		/* Since we don't know whether snum is larger than sdiv,
        +		 * we pad snum with enough zeroes without changing its
        +		 * value. 
        +		 */
        +		if (snum->top <= sdiv->top+1) 
        +			{
        +			if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
        +			for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
        +			snum->top = sdiv->top + 2;
        +			}
        +		else
        +			{
        +			if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
        +			snum->d[snum->top] = 0;
        +			snum->top ++;
        +			}
        +		}
        +
        +	div_n=sdiv->top;
        +	num_n=snum->top;
        +	loop=num_n-div_n;
        +	/* Lets setup a 'window' into snum
        +	 * This is the part that corresponds to the current
        +	 * 'area' being divided */
        +	wnum.neg   = 0;
        +	wnum.d     = &(snum->d[loop]);
        +	wnum.top   = div_n;
        +	/* only needed when BN_ucmp messes up the values between top and max */
        +	wnum.dmax  = snum->dmax - loop; /* so we don't step out of bounds */
        +
        +	/* Get the top 2 words of sdiv */
        +	/* div_n=sdiv->top; */
        +	d0=sdiv->d[div_n-1];
        +	d1=(div_n == 1)?0:sdiv->d[div_n-2];
        +
        +	/* pointer to the 'top' of snum */
        +	wnump= &(snum->d[num_n-1]);
        +
        +	/* Setup to 'res' */
        +	res->neg= (num->neg^divisor->neg);
        +	if (!bn_wexpand(res,(loop+1))) goto err;
        +	res->top=loop-no_branch;
        +	resp= &(res->d[loop-1]);
        +
        +	/* space for temp */
        +	if (!bn_wexpand(tmp,(div_n+1))) goto err;
        +
        +	if (!no_branch)
        +		{
        +		if (BN_ucmp(&wnum,sdiv) >= 0)
        +			{
        +			/* If BN_DEBUG_RAND is defined BN_ucmp changes (via
        +			 * bn_pollute) the const bignum arguments =>
        +			 * clean the values between top and max again */
        +			bn_clear_top2max(&wnum);
        +			bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
        +			*resp=1;
        +			}
        +		else
        +			res->top--;
        +		}
        +
        +	/* if res->top == 0 then clear the neg value otherwise decrease
        +	 * the resp pointer */
        +	if (res->top == 0)
        +		res->neg = 0;
        +	else
        +		resp--;
        +
        +	for (i=0; i<loop-1; i++, wnump--, resp--)
        +		{
        +		BN_ULONG q,l0;
        +		/* the first part of the loop uses the top two words of
        +		 * snum and sdiv to calculate a BN_ULONG q such that
        +		 * | wnum - sdiv * q | < sdiv */
        +#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
        +		BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
        +		q=bn_div_3_words(wnump,d1,d0);
        +#else
        +		BN_ULONG n0,n1,rem=0;
        +
        +		n0=wnump[0];
        +		n1=wnump[-1];
        +		if (n0 == d0)
        +			q=BN_MASK2;
        +		else 			/* n0 < d0 */
        +			{
        +#ifdef BN_LLONG
        +			BN_ULLONG t2;
        +
        +#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
        +			q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
        +#else
        +			q=bn_div_words(n0,n1,d0);
        +#ifdef BN_DEBUG_LEVITTE
        +			fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
        +X) -> 0x%08X\n",
        +				n0, n1, d0, q);
        +#endif
        +#endif
        +
        +#ifndef REMAINDER_IS_ALREADY_CALCULATED
        +			/*
        +			 * rem doesn't have to be BN_ULLONG. The least we
        +			 * know it's less that d0, isn't it?
        +			 */
        +			rem=(n1-q*d0)&BN_MASK2;
        +#endif
        +			t2=(BN_ULLONG)d1*q;
        +
        +			for (;;)
        +				{
        +				if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
        +					break;
        +				q--;
        +				rem += d0;
        +				if (rem < d0) break; /* don't let rem overflow */
        +				t2 -= d1;
        +				}
        +#else /* !BN_LLONG */
        +			BN_ULONG t2l,t2h;
        +
        +			q=bn_div_words(n0,n1,d0);
        +#ifdef BN_DEBUG_LEVITTE
        +			fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
        +X) -> 0x%08X\n",
        +				n0, n1, d0, q);
        +#endif
        +#ifndef REMAINDER_IS_ALREADY_CALCULATED
        +			rem=(n1-q*d0)&BN_MASK2;
        +#endif
        +
        +#if defined(BN_UMULT_LOHI)
        +			BN_UMULT_LOHI(t2l,t2h,d1,q);
        +#elif defined(BN_UMULT_HIGH)
        +			t2l = d1 * q;
        +			t2h = BN_UMULT_HIGH(d1,q);
        +#else
        +			{
        +			BN_ULONG ql, qh;
        +			t2l=LBITS(d1); t2h=HBITS(d1);
        +			ql =LBITS(q);  qh =HBITS(q);
        +			mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
        +			}
        +#endif
        +
        +			for (;;)
        +				{
        +				if ((t2h < rem) ||
        +					((t2h == rem) && (t2l <= wnump[-2])))
        +					break;
        +				q--;
        +				rem += d0;
        +				if (rem < d0) break; /* don't let rem overflow */
        +				if (t2l < d1) t2h--; t2l -= d1;
        +				}
        +#endif /* !BN_LLONG */
        +			}
        +#endif /* !BN_DIV3W */
        +
        +		l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
        +		tmp->d[div_n]=l0;
        +		wnum.d--;
        +		/* ingore top values of the bignums just sub the two 
        +		 * BN_ULONG arrays with bn_sub_words */
        +		if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
        +			{
        +			/* Note: As we have considered only the leading
        +			 * two BN_ULONGs in the calculation of q, sdiv * q
        +			 * might be greater than wnum (but then (q-1) * sdiv
        +			 * is less or equal than wnum)
        +			 */
        +			q--;
        +			if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
        +				/* we can't have an overflow here (assuming
        +				 * that q != 0, but if q == 0 then tmp is
        +				 * zero anyway) */
        +				(*wnump)++;
        +			}
        +		/* store part of the result */
        +		*resp = q;
        +		}
        +	bn_correct_top(snum);
        +	if (rm != NULL)
        +		{
        +		/* Keep a copy of the neg flag in num because if rm==num
        +		 * BN_rshift() will overwrite it.
        +		 */
        +		int neg = num->neg;
        +		BN_rshift(rm,snum,norm_shift);
        +		if (!BN_is_zero(rm))
        +			rm->neg = neg;
        +		bn_check_top(rm);
        +		}
        +	if (no_branch)	bn_correct_top(res);
        +	BN_CTX_end(ctx);
        +	return(1);
        +err:
        +	bn_check_top(rm);
        +	BN_CTX_end(ctx);
        +	return(0);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_err.c b/vendor/openssl/openssl/crypto/bn/bn_err.c
        new file mode 100644
        index 000000000..cfe2eb94a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_err.c
        @@ -0,0 +1,150 @@
        +/* crypto/bn/bn_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
        +
        +static ERR_STRING_DATA BN_str_functs[]=
        +	{
        +{ERR_FUNC(BN_F_BNRAND),	"BNRAND"},
        +{ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX),	"BN_BLINDING_convert_ex"},
        +{ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM),	"BN_BLINDING_create_param"},
        +{ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX),	"BN_BLINDING_invert_ex"},
        +{ERR_FUNC(BN_F_BN_BLINDING_NEW),	"BN_BLINDING_new"},
        +{ERR_FUNC(BN_F_BN_BLINDING_UPDATE),	"BN_BLINDING_update"},
        +{ERR_FUNC(BN_F_BN_BN2DEC),	"BN_bn2dec"},
        +{ERR_FUNC(BN_F_BN_BN2HEX),	"BN_bn2hex"},
        +{ERR_FUNC(BN_F_BN_CTX_GET),	"BN_CTX_get"},
        +{ERR_FUNC(BN_F_BN_CTX_NEW),	"BN_CTX_new"},
        +{ERR_FUNC(BN_F_BN_CTX_START),	"BN_CTX_start"},
        +{ERR_FUNC(BN_F_BN_DIV),	"BN_div"},
        +{ERR_FUNC(BN_F_BN_DIV_NO_BRANCH),	"BN_div_no_branch"},
        +{ERR_FUNC(BN_F_BN_DIV_RECP),	"BN_div_recp"},
        +{ERR_FUNC(BN_F_BN_EXP),	"BN_exp"},
        +{ERR_FUNC(BN_F_BN_EXPAND2),	"bn_expand2"},
        +{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL),	"BN_EXPAND_INTERNAL"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD),	"BN_GF2m_mod"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD_EXP),	"BN_GF2m_mod_exp"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD_MUL),	"BN_GF2m_mod_mul"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD),	"BN_GF2m_mod_solve_quad"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR),	"BN_GF2m_mod_solve_quad_arr"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD_SQR),	"BN_GF2m_mod_sqr"},
        +{ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT),	"BN_GF2m_mod_sqrt"},
        +{ERR_FUNC(BN_F_BN_MOD_EXP2_MONT),	"BN_mod_exp2_mont"},
        +{ERR_FUNC(BN_F_BN_MOD_EXP_MONT),	"BN_mod_exp_mont"},
        +{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME),	"BN_mod_exp_mont_consttime"},
        +{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD),	"BN_mod_exp_mont_word"},
        +{ERR_FUNC(BN_F_BN_MOD_EXP_RECP),	"BN_mod_exp_recp"},
        +{ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE),	"BN_mod_exp_simple"},
        +{ERR_FUNC(BN_F_BN_MOD_INVERSE),	"BN_mod_inverse"},
        +{ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH),	"BN_mod_inverse_no_branch"},
        +{ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK),	"BN_mod_lshift_quick"},
        +{ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL),	"BN_mod_mul_reciprocal"},
        +{ERR_FUNC(BN_F_BN_MOD_SQRT),	"BN_mod_sqrt"},
        +{ERR_FUNC(BN_F_BN_MPI2BN),	"BN_mpi2bn"},
        +{ERR_FUNC(BN_F_BN_NEW),	"BN_new"},
        +{ERR_FUNC(BN_F_BN_RAND),	"BN_rand"},
        +{ERR_FUNC(BN_F_BN_RAND_RANGE),	"BN_rand_range"},
        +{ERR_FUNC(BN_F_BN_USUB),	"BN_usub"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA BN_str_reasons[]=
        +	{
        +{ERR_REASON(BN_R_ARG2_LT_ARG3)           ,"arg2 lt arg3"},
        +{ERR_REASON(BN_R_BAD_RECIPROCAL)         ,"bad reciprocal"},
        +{ERR_REASON(BN_R_BIGNUM_TOO_LONG)        ,"bignum too long"},
        +{ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS),"called with even modulus"},
        +{ERR_REASON(BN_R_DIV_BY_ZERO)            ,"div by zero"},
        +{ERR_REASON(BN_R_ENCODING_ERROR)         ,"encoding error"},
        +{ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA),"expand on static bignum data"},
        +{ERR_REASON(BN_R_INPUT_NOT_REDUCED)      ,"input not reduced"},
        +{ERR_REASON(BN_R_INVALID_LENGTH)         ,"invalid length"},
        +{ERR_REASON(BN_R_INVALID_RANGE)          ,"invalid range"},
        +{ERR_REASON(BN_R_NOT_A_SQUARE)           ,"not a square"},
        +{ERR_REASON(BN_R_NOT_INITIALIZED)        ,"not initialized"},
        +{ERR_REASON(BN_R_NO_INVERSE)             ,"no inverse"},
        +{ERR_REASON(BN_R_NO_SOLUTION)            ,"no solution"},
        +{ERR_REASON(BN_R_P_IS_NOT_PRIME)         ,"p is not prime"},
        +{ERR_REASON(BN_R_TOO_MANY_ITERATIONS)    ,"too many iterations"},
        +{ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),"too many temporary variables"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_BN_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(BN_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,BN_str_functs);
        +		ERR_load_strings(0,BN_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_exp.c b/vendor/openssl/openssl/crypto/bn/bn_exp.c
        new file mode 100644
        index 000000000..2abf6fd67
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_exp.c
        @@ -0,0 +1,1097 @@
        +/* crypto/bn/bn_exp.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 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 "bn_lcl.h"
        +
        +#include <stdlib.h>
        +#ifdef _WIN32
        +# include <malloc.h>
        +# ifndef alloca
        +#  define alloca _alloca
        +# endif
        +#elif defined(__GNUC__)
        +# ifndef alloca
        +#  define alloca(s) __builtin_alloca((s))
        +# endif
        +#endif
        +
        +/* maximum precomputation table size for *variable* sliding windows */
        +#define TABLE_SIZE	32
        +
        +/* this one works - simple but works */
        +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	int i,bits,ret=0;
        +	BIGNUM *v,*rr;
        +
        +	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
        +		{
        +		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
        +		BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return -1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	if ((r == a) || (r == p))
        +		rr = BN_CTX_get(ctx);
        +	else
        +		rr = r;
        +	v = BN_CTX_get(ctx);
        +	if (rr == NULL || v == NULL) goto err;
        +
        +	if (BN_copy(v,a) == NULL) goto err;
        +	bits=BN_num_bits(p);
        +
        +	if (BN_is_odd(p))
        +		{ if (BN_copy(rr,a) == NULL) goto err; }
        +	else	{ if (!BN_one(rr)) goto err; }
        +
        +	for (i=1; i<bits; i++)
        +		{
        +		if (!BN_sqr(v,v,ctx)) goto err;
        +		if (BN_is_bit_set(p,i))
        +			{
        +			if (!BN_mul(rr,rr,v,ctx)) goto err;
        +			}
        +		}
        +	ret=1;
        +err:
        +	if (r != rr) BN_copy(r,rr);
        +	BN_CTX_end(ctx);
        +	bn_check_top(r);
        +	return(ret);
        +	}
        +
        +
        +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
        +	       BN_CTX *ctx)
        +	{
        +	int ret;
        +
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	bn_check_top(m);
        +
        +	/* For even modulus  m = 2^k*m_odd,  it might make sense to compute
        +	 * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
        +	 * exponentiation for the odd part), using appropriate exponent
        +	 * reductions, and combine the results using the CRT.
        +	 *
        +	 * For now, we use Montgomery only if the modulus is odd; otherwise,
        +	 * exponentiation using the reciprocal-based quick remaindering
        +	 * algorithm is used.
        +	 *
        +	 * (Timing obtained with expspeed.c [computations  a^p mod m
        +	 * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
        +	 * 4096, 8192 bits], compared to the running time of the
        +	 * standard algorithm:
        +	 *
        +	 *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
        +         *                     55 .. 77 %  [UltraSparc processor, but
        +	 *                                  debug-solaris-sparcv8-gcc conf.]
        +	 * 
        +	 *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
        +	 *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
        +	 *
        +	 * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
        +	 * at 2048 and more bits, but at 512 and 1024 bits, it was
        +	 * slower even than the standard algorithm!
        +	 *
        +	 * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
        +	 * should be obtained when the new Montgomery reduction code
        +	 * has been integrated into OpenSSL.)
        +	 */
        +
        +#define MONT_MUL_MOD
        +#define MONT_EXP_WORD
        +#define RECP_MUL_MOD
        +
        +#ifdef MONT_MUL_MOD
        +	/* I have finally been able to take out this pre-condition of
        +	 * the top bit being set.  It was caused by an error in BN_div
        +	 * with negatives.  There was also another problem when for a^b%m
        +	 * a >= m.  eay 07-May-97 */
        +/*	if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
        +
        +	if (BN_is_odd(m))
        +		{
        +#  ifdef MONT_EXP_WORD
        +		if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0))
        +			{
        +			BN_ULONG A = a->d[0];
        +			ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
        +			}
        +		else
        +#  endif
        +			ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
        +		}
        +	else
        +#endif
        +#ifdef RECP_MUL_MOD
        +		{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }
        +#else
        +		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
        +#endif
        +
        +	bn_check_top(r);
        +	return(ret);
        +	}
        +
        +
        +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		    const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	int i,j,bits,ret=0,wstart,wend,window,wvalue;
        +	int start=1;
        +	BIGNUM *aa;
        +	/* Table of variables obtained from 'ctx' */
        +	BIGNUM *val[TABLE_SIZE];
        +	BN_RECP_CTX recp;
        +
        +	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
        +		{
        +		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
        +		BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return -1;
        +		}
        +
        +	bits=BN_num_bits(p);
        +
        +	if (bits == 0)
        +		{
        +		ret = BN_one(r);
        +		return ret;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	aa = BN_CTX_get(ctx);
        +	val[0] = BN_CTX_get(ctx);
        +	if(!aa || !val[0]) goto err;
        +
        +	BN_RECP_CTX_init(&recp);
        +	if (m->neg)
        +		{
        +		/* ignore sign of 'm' */
        +		if (!BN_copy(aa, m)) goto err;
        +		aa->neg = 0;
        +		if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err;
        +		}
        +	else
        +		{
        +		if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
        +		}
        +
        +	if (!BN_nnmod(val[0],a,m,ctx)) goto err;		/* 1 */
        +	if (BN_is_zero(val[0]))
        +		{
        +		BN_zero(r);
        +		ret = 1;
        +		goto err;
        +		}
        +
        +	window = BN_window_bits_for_exponent_size(bits);
        +	if (window > 1)
        +		{
        +		if (!BN_mod_mul_reciprocal(aa,val[0],val[0],&recp,ctx))
        +			goto err;				/* 2 */
        +		j=1<<(window-1);
        +		for (i=1; i<j; i++)
        +			{
        +			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
        +					!BN_mod_mul_reciprocal(val[i],val[i-1],
        +						aa,&recp,ctx))
        +				goto err;
        +			}
        +		}
        +		
        +	start=1;	/* This is used to avoid multiplication etc
        +			 * when there is only the value '1' in the
        +			 * buffer. */
        +	wvalue=0;	/* The 'value' of the window */
        +	wstart=bits-1;	/* The top bit of the window */
        +	wend=0;		/* The bottom bit of the window */
        +
        +	if (!BN_one(r)) goto err;
        +
        +	for (;;)
        +		{
        +		if (BN_is_bit_set(p,wstart) == 0)
        +			{
        +			if (!start)
        +				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
        +				goto err;
        +			if (wstart == 0) break;
        +			wstart--;
        +			continue;
        +			}
        +		/* We now have wstart on a 'set' bit, we now need to work out
        +		 * how bit a window to do.  To do this we need to scan
        +		 * forward until the last set bit before the end of the
        +		 * window */
        +		j=wstart;
        +		wvalue=1;
        +		wend=0;
        +		for (i=1; i<window; i++)
        +			{
        +			if (wstart-i < 0) break;
        +			if (BN_is_bit_set(p,wstart-i))
        +				{
        +				wvalue<<=(i-wend);
        +				wvalue|=1;
        +				wend=i;
        +				}
        +			}
        +
        +		/* wend is the size of the current window */
        +		j=wend+1;
        +		/* add the 'bytes above' */
        +		if (!start)
        +			for (i=0; i<j; i++)
        +				{
        +				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
        +					goto err;
        +				}
        +		
        +		/* wvalue will be an odd number < 2^window */
        +		if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],&recp,ctx))
        +			goto err;
        +
        +		/* move the 'window' down further */
        +		wstart-=wend+1;
        +		wvalue=0;
        +		start=0;
        +		if (wstart < 0) break;
        +		}
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	BN_RECP_CTX_free(&recp);
        +	bn_check_top(r);
        +	return(ret);
        +	}
        +
        +
        +int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
        +		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        +	{
        +	int i,j,bits,ret=0,wstart,wend,window,wvalue;
        +	int start=1;
        +	BIGNUM *d,*r;
        +	const BIGNUM *aa;
        +	/* Table of variables obtained from 'ctx' */
        +	BIGNUM *val[TABLE_SIZE];
        +	BN_MONT_CTX *mont=NULL;
        +
        +	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
        +		{
        +		return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
        +		}
        +
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	bn_check_top(m);
        +
        +	if (!BN_is_odd(m))
        +		{
        +		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
        +		return(0);
        +		}
        +	bits=BN_num_bits(p);
        +	if (bits == 0)
        +		{
        +		ret = BN_one(rr);
        +		return ret;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	d = BN_CTX_get(ctx);
        +	r = BN_CTX_get(ctx);
        +	val[0] = BN_CTX_get(ctx);
        +	if (!d || !r || !val[0]) goto err;
        +
        +	/* If this is not done, things will break in the montgomery
        +	 * part */
        +
        +	if (in_mont != NULL)
        +		mont=in_mont;
        +	else
        +		{
        +		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
        +		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
        +		}
        +
        +	if (a->neg || BN_ucmp(a,m) >= 0)
        +		{
        +		if (!BN_nnmod(val[0],a,m,ctx))
        +			goto err;
        +		aa= val[0];
        +		}
        +	else
        +		aa=a;
        +	if (BN_is_zero(aa))
        +		{
        +		BN_zero(rr);
        +		ret = 1;
        +		goto err;
        +		}
        +	if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */
        +
        +	window = BN_window_bits_for_exponent_size(bits);
        +	if (window > 1)
        +		{
        +		if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */
        +		j=1<<(window-1);
        +		for (i=1; i<j; i++)
        +			{
        +			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
        +					!BN_mod_mul_montgomery(val[i],val[i-1],
        +						d,mont,ctx))
        +				goto err;
        +			}
        +		}
        +
        +	start=1;	/* This is used to avoid multiplication etc
        +			 * when there is only the value '1' in the
        +			 * buffer. */
        +	wvalue=0;	/* The 'value' of the window */
        +	wstart=bits-1;	/* The top bit of the window */
        +	wend=0;		/* The bottom bit of the window */
        +
        +	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
        +	for (;;)
        +		{
        +		if (BN_is_bit_set(p,wstart) == 0)
        +			{
        +			if (!start)
        +				{
        +				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
        +				goto err;
        +				}
        +			if (wstart == 0) break;
        +			wstart--;
        +			continue;
        +			}
        +		/* We now have wstart on a 'set' bit, we now need to work out
        +		 * how bit a window to do.  To do this we need to scan
        +		 * forward until the last set bit before the end of the
        +		 * window */
        +		j=wstart;
        +		wvalue=1;
        +		wend=0;
        +		for (i=1; i<window; i++)
        +			{
        +			if (wstart-i < 0) break;
        +			if (BN_is_bit_set(p,wstart-i))
        +				{
        +				wvalue<<=(i-wend);
        +				wvalue|=1;
        +				wend=i;
        +				}
        +			}
        +
        +		/* wend is the size of the current window */
        +		j=wend+1;
        +		/* add the 'bytes above' */
        +		if (!start)
        +			for (i=0; i<j; i++)
        +				{
        +				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
        +					goto err;
        +				}
        +		
        +		/* wvalue will be an odd number < 2^window */
        +		if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx))
        +			goto err;
        +
        +		/* move the 'window' down further */
        +		wstart-=wend+1;
        +		wvalue=0;
        +		start=0;
        +		if (wstart < 0) break;
        +		}
        +	if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
        +	ret=1;
        +err:
        +	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
        +	BN_CTX_end(ctx);
        +	bn_check_top(rr);
        +	return(ret);
        +	}
        +
        +
        +/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
        + * so that accessing any of these table values shows the same access pattern as far
        + * as cache lines are concerned.  The following functions are used to transfer a BIGNUM
        + * from/to that table. */
        +
        +static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, int idx, int width)
        +	{
        +	size_t i, j;
        +
        +	if (top > b->top)
        +		top = b->top; /* this works because 'buf' is explicitly zeroed */
        +	for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
        +		{
        +		buf[j] = ((unsigned char*)b->d)[i];
        +		}
        +
        +	return 1;
        +	}
        +
        +static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
        +	{
        +	size_t i, j;
        +
        +	if (bn_wexpand(b, top) == NULL)
        +		return 0;
        +
        +	for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
        +		{
        +		((unsigned char*)b->d)[i] = buf[j];
        +		}
        +
        +	b->top = top;
        +	bn_correct_top(b);
        +	return 1;
        +	}	
        +
        +/* Given a pointer value, compute the next address that is a cache line multiple. */
        +#define MOD_EXP_CTIME_ALIGN(x_) \
        +	((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
        +
        +/* This variant of BN_mod_exp_mont() uses fixed windows and the special
        + * precomputation memory layout to limit data-dependency to a minimum
        + * to protect secret exponents (cf. the hyper-threading timing attacks
        + * pointed out by Colin Percival,
        + * http://www.daemonology.net/hyperthreading-considered-harmful/)
        + */
        +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
        +		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        +	{
        +	int i,bits,ret=0,window,wvalue;
        +	int top;
        +	BN_MONT_CTX *mont=NULL;
        +
        +	int numPowers;
        +	unsigned char *powerbufFree=NULL;
        +	int powerbufLen = 0;
        +	unsigned char *powerbuf=NULL;
        +	BIGNUM tmp, am;
        +
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	bn_check_top(m);
        +
        +	top = m->top;
        +
        +	if (!(m->d[0] & 1))
        +		{
        +		BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,BN_R_CALLED_WITH_EVEN_MODULUS);
        +		return(0);
        +		}
        +	bits=BN_num_bits(p);
        +	if (bits == 0)
        +		{
        +		ret = BN_one(rr);
        +		return ret;
        +		}
        +
        +	BN_CTX_start(ctx);
        +
        +	/* Allocate a montgomery context if it was not supplied by the caller.
        +	 * If this is not done, things will break in the montgomery part.
        + 	 */
        +	if (in_mont != NULL)
        +		mont=in_mont;
        +	else
        +		{
        +		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
        +		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
        +		}
        +
        +	/* Get the window size to use with size of p. */
        +	window = BN_window_bits_for_ctime_exponent_size(bits);
        +#if defined(OPENSSL_BN_ASM_MONT5)
        +	if (window==6 && bits<=1024) window=5;	/* ~5% improvement of 2048-bit RSA sign */
        +#endif
        +
        +	/* Allocate a buffer large enough to hold all of the pre-computed
        +	 * powers of am, am itself and tmp.
        +	 */
        +	numPowers = 1 << window;
        +	powerbufLen = sizeof(m->d[0])*(top*numPowers +
        +				((2*top)>numPowers?(2*top):numPowers));
        +#ifdef alloca
        +	if (powerbufLen < 3072)
        +		powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
        +	else
        +#endif
        +	if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
        +		goto err;
        +		
        +	powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
        +	memset(powerbuf, 0, powerbufLen);
        +
        +#ifdef alloca
        +	if (powerbufLen < 3072)
        +		powerbufFree = NULL;
        +#endif
        +
        +	/* lay down tmp and am right after powers table */
        +	tmp.d     = (BN_ULONG *)(powerbuf + sizeof(m->d[0])*top*numPowers);
        +	am.d      = tmp.d + top;
        +	tmp.top   = am.top  = 0;
        +	tmp.dmax  = am.dmax = top;
        +	tmp.neg   = am.neg  = 0;
        +	tmp.flags = am.flags = BN_FLG_STATIC_DATA;
        +
        +	/* prepare a^0 in Montgomery domain */
        +#if 1
        + 	if (!BN_to_montgomery(&tmp,BN_value_one(),mont,ctx))	goto err;
        +#else
        +	tmp.d[0] = (0-m->d[0])&BN_MASK2;	/* 2^(top*BN_BITS2) - m */
        +	for (i=1;i<top;i++)
        +		tmp.d[i] = (~m->d[i])&BN_MASK2;
        +	tmp.top = top;
        +#endif
        +
        +	/* prepare a^1 in Montgomery domain */
        +	if (a->neg || BN_ucmp(a,m) >= 0)
        +		{
        +		if (!BN_mod(&am,a,m,ctx))			goto err;
        +		if (!BN_to_montgomery(&am,&am,mont,ctx))	goto err;
        +		}
        +	else	if (!BN_to_montgomery(&am,a,mont,ctx))		goto err;
        +
        +#if defined(OPENSSL_BN_ASM_MONT5)
        +    /* This optimization uses ideas from http://eprint.iacr.org/2011/239,
        +     * specifically optimization of cache-timing attack countermeasures
        +     * and pre-computation optimization. */
        +
        +    /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
        +     * 512-bit RSA is hardly relevant, we omit it to spare size... */ 
        +    if (window==5)
        +	{
        +	void bn_mul_mont_gather5(BN_ULONG *rp,const BN_ULONG *ap,
        +			const void *table,const BN_ULONG *np,
        +			const BN_ULONG *n0,int num,int power);
        +	void bn_scatter5(const BN_ULONG *inp,size_t num,
        +			void *table,size_t power);
        +	void bn_gather5(BN_ULONG *out,size_t num,
        +			void *table,size_t power);
        +
        +	BN_ULONG *np=mont->N.d, *n0=mont->n0;
        +
        +	/* BN_to_montgomery can contaminate words above .top
        +	 * [in BN_DEBUG[_DEBUG] build]... */
        +	for (i=am.top; i<top; i++)	am.d[i]=0;
        +	for (i=tmp.top; i<top; i++)	tmp.d[i]=0;
        +
        +	bn_scatter5(tmp.d,top,powerbuf,0);
        +	bn_scatter5(am.d,am.top,powerbuf,1);
        +	bn_mul_mont(tmp.d,am.d,am.d,np,n0,top);
        +	bn_scatter5(tmp.d,top,powerbuf,2);
        +
        +#if 0
        +	for (i=3; i<32; i++)
        +		{
        +		/* Calculate a^i = a^(i-1) * a */
        +		bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
        +		bn_scatter5(tmp.d,top,powerbuf,i);
        +		}
        +#else
        +	/* same as above, but uses squaring for 1/2 of operations */
        +	for (i=4; i<32; i*=2)
        +		{
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_scatter5(tmp.d,top,powerbuf,i);
        +		}
        +	for (i=3; i<8; i+=2)
        +		{
        +		int j;
        +		bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
        +		bn_scatter5(tmp.d,top,powerbuf,i);
        +		for (j=2*i; j<32; j*=2)
        +			{
        +			bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +			bn_scatter5(tmp.d,top,powerbuf,j);
        +			}
        +		}
        +	for (; i<16; i+=2)
        +		{
        +		bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
        +		bn_scatter5(tmp.d,top,powerbuf,i);
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_scatter5(tmp.d,top,powerbuf,2*i);
        +		}
        +	for (; i<32; i+=2)
        +		{
        +		bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1);
        +		bn_scatter5(tmp.d,top,powerbuf,i);
        +		}
        +#endif
        +	bits--;
        +	for (wvalue=0, i=bits%5; i>=0; i--,bits--)
        +		wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
        +	bn_gather5(tmp.d,top,powerbuf,wvalue);
        +
        +	/* Scan the exponent one window at a time starting from the most
        +	 * significant bits.
        +	 */
        +	while (bits >= 0)
        +		{
        +		for (wvalue=0, i=0; i<5; i++,bits--)
        +			wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
        +
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top);
        +		bn_mul_mont_gather5(tmp.d,tmp.d,powerbuf,np,n0,top,wvalue);
        +		}
        +
        +	tmp.top=top;
        +	bn_correct_top(&tmp);
        +	}
        +    else
        +#endif
        +	{
        +	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, numPowers)) goto err;
        +	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am,  top, powerbuf, 1, numPowers)) goto err;
        +
        +	/* If the window size is greater than 1, then calculate
        +	 * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
        +	 * (even powers could instead be computed as (a^(i/2))^2
        +	 * to use the slight performance advantage of sqr over mul).
        +	 */
        +	if (window > 1)
        +		{
        +		if (!BN_mod_mul_montgomery(&tmp,&am,&am,mont,ctx))	goto err;
        +		if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, numPowers)) goto err;
        +		for (i=3; i<numPowers; i++)
        +			{
        +			/* Calculate a^i = a^(i-1) * a */
        +			if (!BN_mod_mul_montgomery(&tmp,&am,&tmp,mont,ctx))
        +				goto err;
        +			if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, numPowers)) goto err;
        +			}
        +		}
        +
        +	bits--;
        +	for (wvalue=0, i=bits%window; i>=0; i--,bits--)
        +		wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
        +	if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp,top,powerbuf,wvalue,numPowers)) goto err;
        + 
        +	/* Scan the exponent one window at a time starting from the most
        +	 * significant bits.
        +	 */
        + 	while (bits >= 0)
        +  		{
        + 		wvalue=0; /* The 'value' of the window */
        + 		
        + 		/* Scan the window, squaring the result as we go */
        + 		for (i=0; i<window; i++,bits--)
        + 			{
        +			if (!BN_mod_mul_montgomery(&tmp,&tmp,&tmp,mont,ctx))	goto err;
        +			wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
        +  			}
        + 		
        +		/* Fetch the appropriate pre-computed value from the pre-buf */
        +		if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, numPowers)) goto err;
        +
        + 		/* Multiply the result into the intermediate result */
        + 		if (!BN_mod_mul_montgomery(&tmp,&tmp,&am,mont,ctx)) goto err;
        +  		}
        +	}
        +
        + 	/* Convert the final result from montgomery to standard format */
        +	if (!BN_from_montgomery(rr,&tmp,mont,ctx)) goto err;
        +	ret=1;
        +err:
        +	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
        +	if (powerbuf!=NULL)
        +		{
        +		OPENSSL_cleanse(powerbuf,powerbufLen);
        +		if (powerbufFree) OPENSSL_free(powerbufFree);
        +		}
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
        +                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        +	{
        +	BN_MONT_CTX *mont = NULL;
        +	int b, bits, ret=0;
        +	int r_is_one;
        +	BN_ULONG w, next_w;
        +	BIGNUM *d, *r, *t;
        +	BIGNUM *swap_tmp;
        +#define BN_MOD_MUL_WORD(r, w, m) \
        +		(BN_mul_word(r, (w)) && \
        +		(/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
        +			(BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
        +		/* BN_MOD_MUL_WORD is only used with 'w' large,
        +		 * so the BN_ucmp test is probably more overhead
        +		 * than always using BN_mod (which uses BN_copy if
        +		 * a similar test returns true). */
        +		/* We can use BN_mod and do not need BN_nnmod because our
        +		 * accumulator is never negative (the result of BN_mod does
        +		 * not depend on the sign of the modulus).
        +		 */
        +#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
        +		(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
        +
        +	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
        +		{
        +		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
        +		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return -1;
        +		}
        +
        +	bn_check_top(p);
        +	bn_check_top(m);
        +
        +	if (!BN_is_odd(m))
        +		{
        +		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
        +		return(0);
        +		}
        +	if (m->top == 1)
        +		a %= m->d[0]; /* make sure that 'a' is reduced */
        +
        +	bits = BN_num_bits(p);
        +	if (bits == 0)
        +		{
        +		ret = BN_one(rr);
        +		return ret;
        +		}
        +	if (a == 0)
        +		{
        +		BN_zero(rr);
        +		ret = 1;
        +		return ret;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	d = BN_CTX_get(ctx);
        +	r = BN_CTX_get(ctx);
        +	t = BN_CTX_get(ctx);
        +	if (d == NULL || r == NULL || t == NULL) goto err;
        +
        +	if (in_mont != NULL)
        +		mont=in_mont;
        +	else
        +		{
        +		if ((mont = BN_MONT_CTX_new()) == NULL) goto err;
        +		if (!BN_MONT_CTX_set(mont, m, ctx)) goto err;
        +		}
        +
        +	r_is_one = 1; /* except for Montgomery factor */
        +
        +	/* bits-1 >= 0 */
        +
        +	/* The result is accumulated in the product r*w. */
        +	w = a; /* bit 'bits-1' of 'p' is always set */
        +	for (b = bits-2; b >= 0; b--)
        +		{
        +		/* First, square r*w. */
        +		next_w = w*w;
        +		if ((next_w/w) != w) /* overflow */
        +			{
        +			if (r_is_one)
        +				{
        +				if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
        +				r_is_one = 0;
        +				}
        +			else
        +				{
        +				if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
        +				}
        +			next_w = 1;
        +			}
        +		w = next_w;
        +		if (!r_is_one)
        +			{
        +			if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err;
        +			}
        +
        +		/* Second, multiply r*w by 'a' if exponent bit is set. */
        +		if (BN_is_bit_set(p, b))
        +			{
        +			next_w = w*a;
        +			if ((next_w/a) != w) /* overflow */
        +				{
        +				if (r_is_one)
        +					{
        +					if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
        +					r_is_one = 0;
        +					}
        +				else
        +					{
        +					if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
        +					}
        +				next_w = a;
        +				}
        +			w = next_w;
        +			}
        +		}
        +
        +	/* Finally, set r:=r*w. */
        +	if (w != 1)
        +		{
        +		if (r_is_one)
        +			{
        +			if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
        +			r_is_one = 0;
        +			}
        +		else
        +			{
        +			if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
        +			}
        +		}
        +
        +	if (r_is_one) /* can happen only if a == 1*/
        +		{
        +		if (!BN_one(rr)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_from_montgomery(rr, r, mont, ctx)) goto err;
        +		}
        +	ret = 1;
        +err:
        +	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
        +	BN_CTX_end(ctx);
        +	bn_check_top(rr);
        +	return(ret);
        +	}
        +
        +
        +/* The old fallback, simple version :-) */
        +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	int i,j,bits,ret=0,wstart,wend,window,wvalue;
        +	int start=1;
        +	BIGNUM *d;
        +	/* Table of variables obtained from 'ctx' */
        +	BIGNUM *val[TABLE_SIZE];
        +
        +	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
        +		{
        +		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
        +		BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return -1;
        +		}
        +
        +	bits=BN_num_bits(p);
        +
        +	if (bits == 0)
        +		{
        +		ret = BN_one(r);
        +		return ret;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	d = BN_CTX_get(ctx);
        +	val[0] = BN_CTX_get(ctx);
        +	if(!d || !val[0]) goto err;
        +
        +	if (!BN_nnmod(val[0],a,m,ctx)) goto err;		/* 1 */
        +	if (BN_is_zero(val[0]))
        +		{
        +		BN_zero(r);
        +		ret = 1;
        +		goto err;
        +		}
        +
        +	window = BN_window_bits_for_exponent_size(bits);
        +	if (window > 1)
        +		{
        +		if (!BN_mod_mul(d,val[0],val[0],m,ctx))
        +			goto err;				/* 2 */
        +		j=1<<(window-1);
        +		for (i=1; i<j; i++)
        +			{
        +			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
        +					!BN_mod_mul(val[i],val[i-1],d,m,ctx))
        +				goto err;
        +			}
        +		}
        +
        +	start=1;	/* This is used to avoid multiplication etc
        +			 * when there is only the value '1' in the
        +			 * buffer. */
        +	wvalue=0;	/* The 'value' of the window */
        +	wstart=bits-1;	/* The top bit of the window */
        +	wend=0;		/* The bottom bit of the window */
        +
        +	if (!BN_one(r)) goto err;
        +
        +	for (;;)
        +		{
        +		if (BN_is_bit_set(p,wstart) == 0)
        +			{
        +			if (!start)
        +				if (!BN_mod_mul(r,r,r,m,ctx))
        +				goto err;
        +			if (wstart == 0) break;
        +			wstart--;
        +			continue;
        +			}
        +		/* We now have wstart on a 'set' bit, we now need to work out
        +		 * how bit a window to do.  To do this we need to scan
        +		 * forward until the last set bit before the end of the
        +		 * window */
        +		j=wstart;
        +		wvalue=1;
        +		wend=0;
        +		for (i=1; i<window; i++)
        +			{
        +			if (wstart-i < 0) break;
        +			if (BN_is_bit_set(p,wstart-i))
        +				{
        +				wvalue<<=(i-wend);
        +				wvalue|=1;
        +				wend=i;
        +				}
        +			}
        +
        +		/* wend is the size of the current window */
        +		j=wend+1;
        +		/* add the 'bytes above' */
        +		if (!start)
        +			for (i=0; i<j; i++)
        +				{
        +				if (!BN_mod_mul(r,r,r,m,ctx))
        +					goto err;
        +				}
        +		
        +		/* wvalue will be an odd number < 2^window */
        +		if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx))
        +			goto err;
        +
        +		/* move the 'window' down further */
        +		wstart-=wend+1;
        +		wvalue=0;
        +		start=0;
        +		if (wstart < 0) break;
        +		}
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	bn_check_top(r);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_exp2.c b/vendor/openssl/openssl/crypto/bn/bn_exp2.c
        new file mode 100644
        index 000000000..bd0c34b91
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_exp2.c
        @@ -0,0 +1,312 @@
        +/* crypto/bn/bn_exp2.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 <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +#define TABLE_SIZE	32
        +
        +int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
        +	const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
        +	BN_CTX *ctx, BN_MONT_CTX *in_mont)
        +	{
        +	int i,j,bits,b,bits1,bits2,ret=0,wpos1,wpos2,window1,window2,wvalue1,wvalue2;
        +	int r_is_one=1;
        +	BIGNUM *d,*r;
        +	const BIGNUM *a_mod_m;
        +	/* Tables of variables obtained from 'ctx' */
        +	BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
        +	BN_MONT_CTX *mont=NULL;
        +
        +	bn_check_top(a1);
        +	bn_check_top(p1);
        +	bn_check_top(a2);
        +	bn_check_top(p2);
        +	bn_check_top(m);
        +
        +	if (!(m->d[0] & 1))
        +		{
        +		BNerr(BN_F_BN_MOD_EXP2_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
        +		return(0);
        +		}
        +	bits1=BN_num_bits(p1);
        +	bits2=BN_num_bits(p2);
        +	if ((bits1 == 0) && (bits2 == 0))
        +		{
        +		ret = BN_one(rr);
        +		return ret;
        +		}
        +	
        +	bits=(bits1 > bits2)?bits1:bits2;
        +
        +	BN_CTX_start(ctx);
        +	d = BN_CTX_get(ctx);
        +	r = BN_CTX_get(ctx);
        +	val1[0] = BN_CTX_get(ctx);
        +	val2[0] = BN_CTX_get(ctx);
        +	if(!d || !r || !val1[0] || !val2[0]) goto err;
        +
        +	if (in_mont != NULL)
        +		mont=in_mont;
        +	else
        +		{
        +		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
        +		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
        +		}
        +
        +	window1 = BN_window_bits_for_exponent_size(bits1);
        +	window2 = BN_window_bits_for_exponent_size(bits2);
        +
        +	/*
        +	 * Build table for a1:   val1[i] := a1^(2*i + 1) mod m  for i = 0 .. 2^(window1-1)
        +	 */
        +	if (a1->neg || BN_ucmp(a1,m) >= 0)
        +		{
        +		if (!BN_mod(val1[0],a1,m,ctx))
        +			goto err;
        +		a_mod_m = val1[0];
        +		}
        +	else
        +		a_mod_m = a1;
        +	if (BN_is_zero(a_mod_m))
        +		{
        +		BN_zero(rr);
        +		ret = 1;
        +		goto err;
        +		}
        +
        +	if (!BN_to_montgomery(val1[0],a_mod_m,mont,ctx)) goto err;
        +	if (window1 > 1)
        +		{
        +		if (!BN_mod_mul_montgomery(d,val1[0],val1[0],mont,ctx)) goto err;
        +
        +		j=1<<(window1-1);
        +		for (i=1; i<j; i++)
        +			{
        +			if(((val1[i] = BN_CTX_get(ctx)) == NULL) ||
        +					!BN_mod_mul_montgomery(val1[i],val1[i-1],
        +						d,mont,ctx))
        +				goto err;
        +			}
        +		}
        +
        +
        +	/*
        +	 * Build table for a2:   val2[i] := a2^(2*i + 1) mod m  for i = 0 .. 2^(window2-1)
        +	 */
        +	if (a2->neg || BN_ucmp(a2,m) >= 0)
        +		{
        +		if (!BN_mod(val2[0],a2,m,ctx))
        +			goto err;
        +		a_mod_m = val2[0];
        +		}
        +	else
        +		a_mod_m = a2;
        +	if (BN_is_zero(a_mod_m))
        +		{
        +		BN_zero(rr);
        +		ret = 1;
        +		goto err;
        +		}
        +	if (!BN_to_montgomery(val2[0],a_mod_m,mont,ctx)) goto err;
        +	if (window2 > 1)
        +		{
        +		if (!BN_mod_mul_montgomery(d,val2[0],val2[0],mont,ctx)) goto err;
        +
        +		j=1<<(window2-1);
        +		for (i=1; i<j; i++)
        +			{
        +			if(((val2[i] = BN_CTX_get(ctx)) == NULL) ||
        +					!BN_mod_mul_montgomery(val2[i],val2[i-1],
        +						d,mont,ctx))
        +				goto err;
        +			}
        +		}
        +
        +
        +	/* Now compute the power product, using independent windows. */
        +	r_is_one=1;
        +	wvalue1=0;  /* The 'value' of the first window */
        +	wvalue2=0;  /* The 'value' of the second window */
        +	wpos1=0;    /* If wvalue1 > 0, the bottom bit of the first window */
        +	wpos2=0;    /* If wvalue2 > 0, the bottom bit of the second window */
        +
        +	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
        +	for (b=bits-1; b>=0; b--)
        +		{
        +		if (!r_is_one)
        +			{
        +			if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
        +				goto err;
        +			}
        +		
        +		if (!wvalue1)
        +			if (BN_is_bit_set(p1, b))
        +				{
        +				/* consider bits b-window1+1 .. b for this window */
        +				i = b-window1+1;
        +				while (!BN_is_bit_set(p1, i)) /* works for i<0 */
        +					i++;
        +				wpos1 = i;
        +				wvalue1 = 1;
        +				for (i = b-1; i >= wpos1; i--)
        +					{
        +					wvalue1 <<= 1;
        +					if (BN_is_bit_set(p1, i))
        +						wvalue1++;
        +					}
        +				}
        +		
        +		if (!wvalue2)
        +			if (BN_is_bit_set(p2, b))
        +				{
        +				/* consider bits b-window2+1 .. b for this window */
        +				i = b-window2+1;
        +				while (!BN_is_bit_set(p2, i))
        +					i++;
        +				wpos2 = i;
        +				wvalue2 = 1;
        +				for (i = b-1; i >= wpos2; i--)
        +					{
        +					wvalue2 <<= 1;
        +					if (BN_is_bit_set(p2, i))
        +						wvalue2++;
        +					}
        +				}
        +
        +		if (wvalue1 && b == wpos1)
        +			{
        +			/* wvalue1 is odd and < 2^window1 */
        +			if (!BN_mod_mul_montgomery(r,r,val1[wvalue1>>1],mont,ctx))
        +				goto err;
        +			wvalue1 = 0;
        +			r_is_one = 0;
        +			}
        +		
        +		if (wvalue2 && b == wpos2)
        +			{
        +			/* wvalue2 is odd and < 2^window2 */
        +			if (!BN_mod_mul_montgomery(r,r,val2[wvalue2>>1],mont,ctx))
        +				goto err;
        +			wvalue2 = 0;
        +			r_is_one = 0;
        +			}
        +		}
        +	if (!BN_from_montgomery(rr,r,mont,ctx))
        +		goto err;
        +	ret=1;
        +err:
        +	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
        +	BN_CTX_end(ctx);
        +	bn_check_top(rr);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_gcd.c b/vendor/openssl/openssl/crypto/bn/bn_gcd.c
        new file mode 100644
        index 000000000..a808f5317
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_gcd.c
        @@ -0,0 +1,655 @@
        +/* crypto/bn/bn_gcd.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
        +
        +int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*t;
        +	int ret=0;
        +
        +	bn_check_top(in_a);
        +	bn_check_top(in_b);
        +
        +	BN_CTX_start(ctx);
        +	a = BN_CTX_get(ctx);
        +	b = BN_CTX_get(ctx);
        +	if (a == NULL || b == NULL) goto err;
        +
        +	if (BN_copy(a,in_a) == NULL) goto err;
        +	if (BN_copy(b,in_b) == NULL) goto err;
        +	a->neg = 0;
        +	b->neg = 0;
        +
        +	if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
        +	t=euclid(a,b);
        +	if (t == NULL) goto err;
        +
        +	if (BN_copy(r,t) == NULL) goto err;
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	bn_check_top(r);
        +	return(ret);
        +	}
        +
        +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
        +	{
        +	BIGNUM *t;
        +	int shifts=0;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	/* 0 <= b <= a */
        +	while (!BN_is_zero(b))
        +		{
        +		/* 0 < b <= a */
        +
        +		if (BN_is_odd(a))
        +			{
        +			if (BN_is_odd(b))
        +				{
        +				if (!BN_sub(a,a,b)) goto err;
        +				if (!BN_rshift1(a,a)) goto err;
        +				if (BN_cmp(a,b) < 0)
        +					{ t=a; a=b; b=t; }
        +				}
        +			else		/* a odd - b even */
        +				{
        +				if (!BN_rshift1(b,b)) goto err;
        +				if (BN_cmp(a,b) < 0)
        +					{ t=a; a=b; b=t; }
        +				}
        +			}
        +		else			/* a is even */
        +			{
        +			if (BN_is_odd(b))
        +				{
        +				if (!BN_rshift1(a,a)) goto err;
        +				if (BN_cmp(a,b) < 0)
        +					{ t=a; a=b; b=t; }
        +				}
        +			else		/* a even - b even */
        +				{
        +				if (!BN_rshift1(a,a)) goto err;
        +				if (!BN_rshift1(b,b)) goto err;
        +				shifts++;
        +				}
        +			}
        +		/* 0 <= b <= a */
        +		}
        +
        +	if (shifts)
        +		{
        +		if (!BN_lshift(a,a,shifts)) goto err;
        +		}
        +	bn_check_top(a);
        +	return(a);
        +err:
        +	return(NULL);
        +	}
        +
        +
        +/* solves ax == 1 (mod n) */
        +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
        +        const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
        +
        +BIGNUM *BN_mod_inverse(BIGNUM *in,
        +	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
        +	{
        +	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
        +	BIGNUM *ret=NULL;
        +	int sign;
        +
        +	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
        +		{
        +		return BN_mod_inverse_no_branch(in, a, n, ctx);
        +		}
        +
        +	bn_check_top(a);
        +	bn_check_top(n);
        +
        +	BN_CTX_start(ctx);
        +	A = BN_CTX_get(ctx);
        +	B = BN_CTX_get(ctx);
        +	X = BN_CTX_get(ctx);
        +	D = BN_CTX_get(ctx);
        +	M = BN_CTX_get(ctx);
        +	Y = BN_CTX_get(ctx);
        +	T = BN_CTX_get(ctx);
        +	if (T == NULL) goto err;
        +
        +	if (in == NULL)
        +		R=BN_new();
        +	else
        +		R=in;
        +	if (R == NULL) goto err;
        +
        +	BN_one(X);
        +	BN_zero(Y);
        +	if (BN_copy(B,a) == NULL) goto err;
        +	if (BN_copy(A,n) == NULL) goto err;
        +	A->neg = 0;
        +	if (B->neg || (BN_ucmp(B, A) >= 0))
        +		{
        +		if (!BN_nnmod(B, B, A, ctx)) goto err;
        +		}
        +	sign = -1;
        +	/* From  B = a mod |n|,  A = |n|  it follows that
        +	 *
        +	 *      0 <= B < A,
        +	 *     -sign*X*a  ==  B   (mod |n|),
        +	 *      sign*Y*a  ==  A   (mod |n|).
        +	 */
        +
        +	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
        +		{
        +		/* Binary inversion algorithm; requires odd modulus.
        +		 * This is faster than the general algorithm if the modulus
        +		 * is sufficiently small (about 400 .. 500 bits on 32-bit
        +		 * sytems, but much more on 64-bit systems) */
        +		int shift;
        +		
        +		while (!BN_is_zero(B))
        +			{
        +			/*
        +			 *      0 < B < |n|,
        +			 *      0 < A <= |n|,
        +			 * (1) -sign*X*a  ==  B   (mod |n|),
        +			 * (2)  sign*Y*a  ==  A   (mod |n|)
        +			 */
        +
        +			/* Now divide  B  by the maximum possible power of two in the integers,
        +			 * and divide  X  by the same value mod |n|.
        +			 * When we're done, (1) still holds. */
        +			shift = 0;
        +			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
        +				{
        +				shift++;
        +				
        +				if (BN_is_odd(X))
        +					{
        +					if (!BN_uadd(X, X, n)) goto err;
        +					}
        +				/* now X is even, so we can easily divide it by two */
        +				if (!BN_rshift1(X, X)) goto err;
        +				}
        +			if (shift > 0)
        +				{
        +				if (!BN_rshift(B, B, shift)) goto err;
        +				}
        +
        +
        +			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
        +			shift = 0;
        +			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
        +				{
        +				shift++;
        +				
        +				if (BN_is_odd(Y))
        +					{
        +					if (!BN_uadd(Y, Y, n)) goto err;
        +					}
        +				/* now Y is even */
        +				if (!BN_rshift1(Y, Y)) goto err;
        +				}
        +			if (shift > 0)
        +				{
        +				if (!BN_rshift(A, A, shift)) goto err;
        +				}
        +
        +			
        +			/* We still have (1) and (2).
        +			 * Both  A  and  B  are odd.
        +			 * The following computations ensure that
        +			 *
        +			 *     0 <= B < |n|,
        +			 *      0 < A < |n|,
        +			 * (1) -sign*X*a  ==  B   (mod |n|),
        +			 * (2)  sign*Y*a  ==  A   (mod |n|),
        +			 *
        +			 * and that either  A  or  B  is even in the next iteration.
        +			 */
        +			if (BN_ucmp(B, A) >= 0)
        +				{
        +				/* -sign*(X + Y)*a == B - A  (mod |n|) */
        +				if (!BN_uadd(X, X, Y)) goto err;
        +				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
        +				 * actually makes the algorithm slower */
        +				if (!BN_usub(B, B, A)) goto err;
        +				}
        +			else
        +				{
        +				/*  sign*(X + Y)*a == A - B  (mod |n|) */
        +				if (!BN_uadd(Y, Y, X)) goto err;
        +				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
        +				if (!BN_usub(A, A, B)) goto err;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		/* general inversion algorithm */
        +
        +		while (!BN_is_zero(B))
        +			{
        +			BIGNUM *tmp;
        +			
        +			/*
        +			 *      0 < B < A,
        +			 * (*) -sign*X*a  ==  B   (mod |n|),
        +			 *      sign*Y*a  ==  A   (mod |n|)
        +			 */
        +			
        +			/* (D, M) := (A/B, A%B) ... */
        +			if (BN_num_bits(A) == BN_num_bits(B))
        +				{
        +				if (!BN_one(D)) goto err;
        +				if (!BN_sub(M,A,B)) goto err;
        +				}
        +			else if (BN_num_bits(A) == BN_num_bits(B) + 1)
        +				{
        +				/* A/B is 1, 2, or 3 */
        +				if (!BN_lshift1(T,B)) goto err;
        +				if (BN_ucmp(A,T) < 0)
        +					{
        +					/* A < 2*B, so D=1 */
        +					if (!BN_one(D)) goto err;
        +					if (!BN_sub(M,A,B)) goto err;
        +					}
        +				else
        +					{
        +					/* A >= 2*B, so D=2 or D=3 */
        +					if (!BN_sub(M,A,T)) goto err;
        +					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
        +					if (BN_ucmp(A,D) < 0)
        +						{
        +						/* A < 3*B, so D=2 */
        +						if (!BN_set_word(D,2)) goto err;
        +						/* M (= A - 2*B) already has the correct value */
        +						}
        +					else
        +						{
        +						/* only D=3 remains */
        +						if (!BN_set_word(D,3)) goto err;
        +						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
        +						if (!BN_sub(M,M,B)) goto err;
        +						}
        +					}
        +				}
        +			else
        +				{
        +				if (!BN_div(D,M,A,B,ctx)) goto err;
        +				}
        +			
        +			/* Now
        +			 *      A = D*B + M;
        +			 * thus we have
        +			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
        +			 */
        +			
        +			tmp=A; /* keep the BIGNUM object, the value does not matter */
        +			
        +			/* (A, B) := (B, A mod B) ... */
        +			A=B;
        +			B=M;
        +			/* ... so we have  0 <= B < A  again */
        +			
        +			/* Since the former  M  is now  B  and the former  B  is now  A,
        +			 * (**) translates into
        +			 *       sign*Y*a  ==  D*A + B    (mod |n|),
        +			 * i.e.
        +			 *       sign*Y*a - D*A  ==  B    (mod |n|).
        +			 * Similarly, (*) translates into
        +			 *      -sign*X*a  ==  A          (mod |n|).
        +			 *
        +			 * Thus,
        +			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
        +			 * i.e.
        +			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
        +			 *
        +			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
        +			 *      -sign*X*a  ==  B   (mod |n|),
        +			 *       sign*Y*a  ==  A   (mod |n|).
        +			 * Note that  X  and  Y  stay non-negative all the time.
        +			 */
        +			
        +			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
        +			if (BN_is_one(D))
        +				{
        +				if (!BN_add(tmp,X,Y)) goto err;
        +				}
        +			else
        +				{
        +				if (BN_is_word(D,2))
        +					{
        +					if (!BN_lshift1(tmp,X)) goto err;
        +					}
        +				else if (BN_is_word(D,4))
        +					{
        +					if (!BN_lshift(tmp,X,2)) goto err;
        +					}
        +				else if (D->top == 1)
        +					{
        +					if (!BN_copy(tmp,X)) goto err;
        +					if (!BN_mul_word(tmp,D->d[0])) goto err;
        +					}
        +				else
        +					{
        +					if (!BN_mul(tmp,D,X,ctx)) goto err;
        +					}
        +				if (!BN_add(tmp,tmp,Y)) goto err;
        +				}
        +			
        +			M=Y; /* keep the BIGNUM object, the value does not matter */
        +			Y=X;
        +			X=tmp;
        +			sign = -sign;
        +			}
        +		}
        +		
        +	/*
        +	 * The while loop (Euclid's algorithm) ends when
        +	 *      A == gcd(a,n);
        +	 * we have
        +	 *       sign*Y*a  ==  A  (mod |n|),
        +	 * where  Y  is non-negative.
        +	 */
        +
        +	if (sign < 0)
        +		{
        +		if (!BN_sub(Y,n,Y)) goto err;
        +		}
        +	/* Now  Y*a  ==  A  (mod |n|).  */
        +	
        +
        +	if (BN_is_one(A))
        +		{
        +		/* Y*a == 1  (mod |n|) */
        +		if (!Y->neg && BN_ucmp(Y,n) < 0)
        +			{
        +			if (!BN_copy(R,Y)) goto err;
        +			}
        +		else
        +			{
        +			if (!BN_nnmod(R,Y,n,ctx)) goto err;
        +			}
        +		}
        +	else
        +		{
        +		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
        +		goto err;
        +		}
        +	ret=R;
        +err:
        +	if ((ret == NULL) && (in == NULL)) BN_free(R);
        +	BN_CTX_end(ctx);
        +	bn_check_top(ret);
        +	return(ret);
        +	}
        +
        +
        +/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. 
        + * It does not contain branches that may leak sensitive information.
        + */
        +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
        +	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
        +	{
        +	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
        +	BIGNUM local_A, local_B;
        +	BIGNUM *pA, *pB;
        +	BIGNUM *ret=NULL;
        +	int sign;
        +
        +	bn_check_top(a);
        +	bn_check_top(n);
        +
        +	BN_CTX_start(ctx);
        +	A = BN_CTX_get(ctx);
        +	B = BN_CTX_get(ctx);
        +	X = BN_CTX_get(ctx);
        +	D = BN_CTX_get(ctx);
        +	M = BN_CTX_get(ctx);
        +	Y = BN_CTX_get(ctx);
        +	T = BN_CTX_get(ctx);
        +	if (T == NULL) goto err;
        +
        +	if (in == NULL)
        +		R=BN_new();
        +	else
        +		R=in;
        +	if (R == NULL) goto err;
        +
        +	BN_one(X);
        +	BN_zero(Y);
        +	if (BN_copy(B,a) == NULL) goto err;
        +	if (BN_copy(A,n) == NULL) goto err;
        +	A->neg = 0;
        +
        +	if (B->neg || (BN_ucmp(B, A) >= 0))
        +		{
        +		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
        +	 	 * BN_div_no_branch will be called eventually.
        +	 	 */
        +		pB = &local_B;
        +		BN_with_flags(pB, B, BN_FLG_CONSTTIME);	
        +		if (!BN_nnmod(B, pB, A, ctx)) goto err;
        +		}
        +	sign = -1;
        +	/* From  B = a mod |n|,  A = |n|  it follows that
        +	 *
        +	 *      0 <= B < A,
        +	 *     -sign*X*a  ==  B   (mod |n|),
        +	 *      sign*Y*a  ==  A   (mod |n|).
        +	 */
        +
        +	while (!BN_is_zero(B))
        +		{
        +		BIGNUM *tmp;
        +		
        +		/*
        +		 *      0 < B < A,
        +		 * (*) -sign*X*a  ==  B   (mod |n|),
        +		 *      sign*Y*a  ==  A   (mod |n|)
        +		 */
        +
        +		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
        +	 	 * BN_div_no_branch will be called eventually.
        +	 	 */
        +		pA = &local_A;
        +		BN_with_flags(pA, A, BN_FLG_CONSTTIME);	
        +		
        +		/* (D, M) := (A/B, A%B) ... */		
        +		if (!BN_div(D,M,pA,B,ctx)) goto err;
        +		
        +		/* Now
        +		 *      A = D*B + M;
        +		 * thus we have
        +		 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
        +		 */
        +		
        +		tmp=A; /* keep the BIGNUM object, the value does not matter */
        +		
        +		/* (A, B) := (B, A mod B) ... */
        +		A=B;
        +		B=M;
        +		/* ... so we have  0 <= B < A  again */
        +		
        +		/* Since the former  M  is now  B  and the former  B  is now  A,
        +		 * (**) translates into
        +		 *       sign*Y*a  ==  D*A + B    (mod |n|),
        +		 * i.e.
        +		 *       sign*Y*a - D*A  ==  B    (mod |n|).
        +		 * Similarly, (*) translates into
        +		 *      -sign*X*a  ==  A          (mod |n|).
        +		 *
        +		 * Thus,
        +		 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
        +		 * i.e.
        +		 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
        +		 *
        +		 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
        +		 *      -sign*X*a  ==  B   (mod |n|),
        +		 *       sign*Y*a  ==  A   (mod |n|).
        +		 * Note that  X  and  Y  stay non-negative all the time.
        +		 */
        +			
        +		if (!BN_mul(tmp,D,X,ctx)) goto err;
        +		if (!BN_add(tmp,tmp,Y)) goto err;
        +
        +		M=Y; /* keep the BIGNUM object, the value does not matter */
        +		Y=X;
        +		X=tmp;
        +		sign = -sign;
        +		}
        +		
        +	/*
        +	 * The while loop (Euclid's algorithm) ends when
        +	 *      A == gcd(a,n);
        +	 * we have
        +	 *       sign*Y*a  ==  A  (mod |n|),
        +	 * where  Y  is non-negative.
        +	 */
        +
        +	if (sign < 0)
        +		{
        +		if (!BN_sub(Y,n,Y)) goto err;
        +		}
        +	/* Now  Y*a  ==  A  (mod |n|).  */
        +
        +	if (BN_is_one(A))
        +		{
        +		/* Y*a == 1  (mod |n|) */
        +		if (!Y->neg && BN_ucmp(Y,n) < 0)
        +			{
        +			if (!BN_copy(R,Y)) goto err;
        +			}
        +		else
        +			{
        +			if (!BN_nnmod(R,Y,n,ctx)) goto err;
        +			}
        +		}
        +	else
        +		{
        +		BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE);
        +		goto err;
        +		}
        +	ret=R;
        +err:
        +	if ((ret == NULL) && (in == NULL)) BN_free(R);
        +	BN_CTX_end(ctx);
        +	bn_check_top(ret);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_gf2m.c b/vendor/openssl/openssl/crypto/bn/bn_gf2m.c
        new file mode 100644
        index 000000000..8a4dc20ad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_gf2m.c
        @@ -0,0 +1,1113 @@
        +/* crypto/bn/bn_gf2m.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * In addition, Sun covenants to all licensees who provide a reciprocal
        + * covenant with respect to their own patents if any, not to sue under
        + * current and future patent claims necessarily infringed by the making,
        + * using, practicing, selling, offering for sale and/or otherwise
        + * disposing of the ECC Code as delivered hereunder (or portions thereof),
        + * provided that such covenant shall not apply:
        + *  1) for code that a licensee deletes from the ECC Code;
        + *  2) separates from the ECC Code; or
        + *  3) for infringements caused by:
        + *       i) the modification of the ECC Code or
        + *      ii) the combination of the ECC Code with other software or
        + *          devices where such combination causes the infringement.
        + *
        + * The software is originally written by Sheueling Chang Shantz and
        + * Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +/* NOTE: This file is licensed pursuant to the OpenSSL license below
        + * and may be modified; but after modifications, the above covenant
        + * may no longer apply!  In such cases, the corresponding paragraph
        + * ["In addition, Sun covenants ... causes the infringement."] and
        + * this note can be edited out; but please keep the Sun copyright
        + * notice and attribution. */
        +
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <assert.h>
        +#include <limits.h>
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
        +#define MAX_ITERATIONS 50
        +
        +static const BN_ULONG SQR_tb[16] =
        +  {     0,     1,     4,     5,    16,    17,    20,    21,
        +       64,    65,    68,    69,    80,    81,    84,    85 };
        +/* Platform-specific macros to accelerate squaring. */
        +#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
        +#define SQR1(w) \
        +    SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
        +    SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
        +    SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
        +    SQR_tb[(w) >> 36 & 0xF] <<  8 | SQR_tb[(w) >> 32 & 0xF]
        +#define SQR0(w) \
        +    SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
        +    SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
        +    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
        +    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
        +#endif
        +#ifdef THIRTY_TWO_BIT
        +#define SQR1(w) \
        +    SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
        +    SQR_tb[(w) >> 20 & 0xF] <<  8 | SQR_tb[(w) >> 16 & 0xF]
        +#define SQR0(w) \
        +    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
        +    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
        +#endif
        +
        +#if !defined(OPENSSL_BN_ASM_GF2m)
        +/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
        + * result is a polynomial r with degree < 2 * BN_BITS - 1
        + * The caller MUST ensure that the variables have the right amount
        + * of space allocated.
        + */
        +#ifdef THIRTY_TWO_BIT
        +static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
        +	{
        +	register BN_ULONG h, l, s;
        +	BN_ULONG tab[8], top2b = a >> 30; 
        +	register BN_ULONG a1, a2, a4;
        +
        +	a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
        +
        +	tab[0] =  0; tab[1] = a1;    tab[2] = a2;    tab[3] = a1^a2;
        +	tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
        +
        +	s = tab[b       & 0x7]; l  = s;
        +	s = tab[b >>  3 & 0x7]; l ^= s <<  3; h  = s >> 29;
        +	s = tab[b >>  6 & 0x7]; l ^= s <<  6; h ^= s >> 26;
        +	s = tab[b >>  9 & 0x7]; l ^= s <<  9; h ^= s >> 23;
        +	s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
        +	s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
        +	s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
        +	s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
        +	s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >>  8;
        +	s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >>  5;
        +	s = tab[b >> 30      ]; l ^= s << 30; h ^= s >>  2;
        +
        +	/* compensate for the top two bits of a */
        +
        +	if (top2b & 01) { l ^= b << 30; h ^= b >> 2; } 
        +	if (top2b & 02) { l ^= b << 31; h ^= b >> 1; } 
        +
        +	*r1 = h; *r0 = l;
        +	} 
        +#endif
        +#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
        +static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
        +	{
        +	register BN_ULONG h, l, s;
        +	BN_ULONG tab[16], top3b = a >> 61;
        +	register BN_ULONG a1, a2, a4, a8;
        +
        +	a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1;
        +
        +	tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
        +	tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
        +	tab[ 8] = a8;    tab[ 9] = a1^a8;    tab[10] = a2^a8;    tab[11] = a1^a2^a8;
        +	tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
        +
        +	s = tab[b       & 0xF]; l  = s;
        +	s = tab[b >>  4 & 0xF]; l ^= s <<  4; h  = s >> 60;
        +	s = tab[b >>  8 & 0xF]; l ^= s <<  8; h ^= s >> 56;
        +	s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
        +	s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
        +	s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
        +	s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
        +	s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
        +	s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
        +	s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
        +	s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
        +	s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
        +	s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
        +	s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
        +	s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >>  8;
        +	s = tab[b >> 60      ]; l ^= s << 60; h ^= s >>  4;
        +
        +	/* compensate for the top three bits of a */
        +
        +	if (top3b & 01) { l ^= b << 61; h ^= b >> 3; } 
        +	if (top3b & 02) { l ^= b << 62; h ^= b >> 2; } 
        +	if (top3b & 04) { l ^= b << 63; h ^= b >> 1; } 
        +
        +	*r1 = h; *r0 = l;
        +	} 
        +#endif
        +
        +/* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
        + * result is a polynomial r with degree < 4 * BN_BITS2 - 1
        + * The caller MUST ensure that the variables have the right amount
        + * of space allocated.
        + */
        +static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, const BN_ULONG b1, const BN_ULONG b0)
        +	{
        +	BN_ULONG m1, m0;
        +	/* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
        +	bn_GF2m_mul_1x1(r+3, r+2, a1, b1);
        +	bn_GF2m_mul_1x1(r+1, r, a0, b0);
        +	bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
        +	/* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
        +	r[2] ^= m1 ^ r[1] ^ r[3];  /* h0 ^= m1 ^ l1 ^ h1; */
        +	r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0;  /* l1 ^= l0 ^ h0 ^ m0; */
        +	}
        +#else
        +void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0);
        +#endif 
        +
        +/* Add polynomials a and b and store result in r; r could be a or b, a and b 
        + * could be equal; r is the bitwise XOR of a and b.
        + */
        +int	BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
        +	{
        +	int i;
        +	const BIGNUM *at, *bt;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	if (a->top < b->top) { at = b; bt = a; }
        +	else { at = a; bt = b; }
        +
        +	if(bn_wexpand(r, at->top) == NULL)
        +		return 0;
        +
        +	for (i = 0; i < bt->top; i++)
        +		{
        +		r->d[i] = at->d[i] ^ bt->d[i];
        +		}
        +	for (; i < at->top; i++)
        +		{
        +		r->d[i] = at->d[i];
        +		}
        +	
        +	r->top = at->top;
        +	bn_correct_top(r);
        +	
        +	return 1;
        +	}
        +
        +
        +/* Some functions allow for representation of the irreducible polynomials
        + * as an int[], say p.  The irreducible f(t) is then of the form:
        + *     t^p[0] + t^p[1] + ... + t^p[k]
        + * where m = p[0] > p[1] > ... > p[k] = 0.
        + */
        +
        +
        +/* Performs modular reduction of a and store result in r.  r could be a. */
        +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
        +	{
        +	int j, k;
        +	int n, dN, d0, d1;
        +	BN_ULONG zz, *z;
        +
        +	bn_check_top(a);
        +
        +	if (!p[0])
        +		{
        +		/* reduction mod 1 => return 0 */
        +		BN_zero(r);
        +		return 1;
        +		}
        +
        +	/* Since the algorithm does reduction in the r value, if a != r, copy
        +	 * the contents of a into r so we can do reduction in r. 
        +	 */
        +	if (a != r)
        +		{
        +		if (!bn_wexpand(r, a->top)) return 0;
        +		for (j = 0; j < a->top; j++)
        +			{
        +			r->d[j] = a->d[j];
        +			}
        +		r->top = a->top;
        +		}
        +	z = r->d;
        +
        +	/* start reduction */
        +	dN = p[0] / BN_BITS2;  
        +	for (j = r->top - 1; j > dN;)
        +		{
        +		zz = z[j];
        +		if (z[j] == 0) { j--; continue; }
        +		z[j] = 0;
        +
        +		for (k = 1; p[k] != 0; k++)
        +			{
        +			/* reducing component t^p[k] */
        +			n = p[0] - p[k];
        +			d0 = n % BN_BITS2;  d1 = BN_BITS2 - d0;
        +			n /= BN_BITS2; 
        +			z[j-n] ^= (zz>>d0);
        +			if (d0) z[j-n-1] ^= (zz<<d1);
        +			}
        +
        +		/* reducing component t^0 */
        +		n = dN;  
        +		d0 = p[0] % BN_BITS2;
        +		d1 = BN_BITS2 - d0;
        +		z[j-n] ^= (zz >> d0);
        +		if (d0) z[j-n-1] ^= (zz << d1);
        +		}
        +
        +	/* final round of reduction */
        +	while (j == dN)
        +		{
        +
        +		d0 = p[0] % BN_BITS2;
        +		zz = z[dN] >> d0;
        +		if (zz == 0) break;
        +		d1 = BN_BITS2 - d0;
        +		
        +		/* clear up the top d1 bits */
        +		if (d0)
        +			z[dN] = (z[dN] << d1) >> d1;
        +		else
        +			z[dN] = 0;
        +		z[0] ^= zz; /* reduction t^0 component */
        +
        +		for (k = 1; p[k] != 0; k++)
        +			{
        +			BN_ULONG tmp_ulong;
        +
        +			/* reducing component t^p[k]*/
        +			n = p[k] / BN_BITS2;   
        +			d0 = p[k] % BN_BITS2;
        +			d1 = BN_BITS2 - d0;
        +			z[n] ^= (zz << d0);
        +			tmp_ulong = zz >> d1;
        +                        if (d0 && tmp_ulong)
        +                                z[n+1] ^= tmp_ulong;
        +			}
        +
        +		
        +		}
        +
        +	bn_correct_top(r);
        +	return 1;
        +	}
        +
        +/* Performs modular reduction of a by p and store result in r.  r could be a.
        + *
        + * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_arr function.
        + */
        +int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
        +	{
        +	int ret = 0;
        +	int arr[6];
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	ret = BN_GF2m_poly2arr(p, arr, sizeof(arr)/sizeof(arr[0]));
        +	if (!ret || ret > (int)(sizeof(arr)/sizeof(arr[0])))
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH);
        +		return 0;
        +		}
        +	ret = BN_GF2m_mod_arr(r, a, arr);
        +	bn_check_top(r);
        +	return ret;
        +	}
        +
        +
        +/* Compute the product of two polynomials a and b, reduce modulo p, and store
        + * the result in r.  r could be a or b; a could be b.
        + */
        +int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
        +	{
        +	int zlen, i, j, k, ret = 0;
        +	BIGNUM *s;
        +	BN_ULONG x1, x0, y1, y0, zz[4];
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	if (a == b)
        +		{
        +		return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
        +		}
        +
        +	BN_CTX_start(ctx);
        +	if ((s = BN_CTX_get(ctx)) == NULL) goto err;
        +	
        +	zlen = a->top + b->top + 4;
        +	if (!bn_wexpand(s, zlen)) goto err;
        +	s->top = zlen;
        +
        +	for (i = 0; i < zlen; i++) s->d[i] = 0;
        +
        +	for (j = 0; j < b->top; j += 2)
        +		{
        +		y0 = b->d[j];
        +		y1 = ((j+1) == b->top) ? 0 : b->d[j+1];
        +		for (i = 0; i < a->top; i += 2)
        +			{
        +			x0 = a->d[i];
        +			x1 = ((i+1) == a->top) ? 0 : a->d[i+1];
        +			bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
        +			for (k = 0; k < 4; k++) s->d[i+j+k] ^= zz[k];
        +			}
        +		}
        +
        +	bn_correct_top(s);
        +	if (BN_GF2m_mod_arr(r, s, p))
        +		ret = 1;
        +	bn_check_top(r);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Compute the product of two polynomials a and b, reduce modulo p, and store
        + * the result in r.  r could be a or b; a could equal b.
        + *
        + * This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_mul_arr function.
        + */
        +int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	const int max = BN_num_bits(p) + 1;
        +	int *arr=NULL;
        +	bn_check_top(a);
        +	bn_check_top(b);
        +	bn_check_top(p);
        +	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
        +	ret = BN_GF2m_poly2arr(p, arr, max);
        +	if (!ret || ret > max)
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD_MUL,BN_R_INVALID_LENGTH);
        +		goto err;
        +		}
        +	ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
        +	bn_check_top(r);
        +err:
        +	if (arr) OPENSSL_free(arr);
        +	return ret;
        +	}
        +
        +
        +/* Square a, reduce the result mod p, and store it in a.  r could be a. */
        +int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
        +	{
        +	int i, ret = 0;
        +	BIGNUM *s;
        +
        +	bn_check_top(a);
        +	BN_CTX_start(ctx);
        +	if ((s = BN_CTX_get(ctx)) == NULL) return 0;
        +	if (!bn_wexpand(s, 2 * a->top)) goto err;
        +
        +	for (i = a->top - 1; i >= 0; i--)
        +		{
        +		s->d[2*i+1] = SQR1(a->d[i]);
        +		s->d[2*i  ] = SQR0(a->d[i]);
        +		}
        +
        +	s->top = 2 * a->top;
        +	bn_correct_top(s);
        +	if (!BN_GF2m_mod_arr(r, s, p)) goto err;
        +	bn_check_top(r);
        +	ret = 1;
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Square a, reduce the result mod p, and store it in a.  r could be a.
        + *
        + * This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_sqr_arr function.
        + */
        +int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	const int max = BN_num_bits(p) + 1;
        +	int *arr=NULL;
        +
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
        +	ret = BN_GF2m_poly2arr(p, arr, max);
        +	if (!ret || ret > max)
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD_SQR,BN_R_INVALID_LENGTH);
        +		goto err;
        +		}
        +	ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
        +	bn_check_top(r);
        +err:
        +	if (arr) OPENSSL_free(arr);
        +	return ret;
        +	}
        +
        +
        +/* Invert a, reduce modulo p, and store the result in r. r could be a. 
        + * Uses Modified Almost Inverse Algorithm (Algorithm 10) from
        + *     Hankerson, D., Hernandez, J.L., and Menezes, A.  "Software Implementation
        + *     of Elliptic Curve Cryptography Over Binary Fields".
        + */
        +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
        +	int ret = 0;
        +
        +	bn_check_top(a);
        +	bn_check_top(p);
        +
        +	BN_CTX_start(ctx);
        +	
        +	if ((b = BN_CTX_get(ctx))==NULL) goto err;
        +	if ((c = BN_CTX_get(ctx))==NULL) goto err;
        +	if ((u = BN_CTX_get(ctx))==NULL) goto err;
        +	if ((v = BN_CTX_get(ctx))==NULL) goto err;
        +
        +	if (!BN_GF2m_mod(u, a, p)) goto err;
        +	if (BN_is_zero(u)) goto err;
        +
        +	if (!BN_copy(v, p)) goto err;
        +#if 0
        +	if (!BN_one(b)) goto err;
        +
        +	while (1)
        +		{
        +		while (!BN_is_odd(u))
        +			{
        +			if (BN_is_zero(u)) goto err;
        +			if (!BN_rshift1(u, u)) goto err;
        +			if (BN_is_odd(b))
        +				{
        +				if (!BN_GF2m_add(b, b, p)) goto err;
        +				}
        +			if (!BN_rshift1(b, b)) goto err;
        +			}
        +
        +		if (BN_abs_is_word(u, 1)) break;
        +
        +		if (BN_num_bits(u) < BN_num_bits(v))
        +			{
        +			tmp = u; u = v; v = tmp;
        +			tmp = b; b = c; c = tmp;
        +			}
        +		
        +		if (!BN_GF2m_add(u, u, v)) goto err;
        +		if (!BN_GF2m_add(b, b, c)) goto err;
        +		}
        +#else
        +	{
        +	int i,	ubits = BN_num_bits(u),
        +		vbits = BN_num_bits(v),	/* v is copy of p */
        +		top = p->top;
        +	BN_ULONG *udp,*bdp,*vdp,*cdp;
        +
        +	bn_wexpand(u,top);	udp = u->d;
        +				for (i=u->top;i<top;i++) udp[i] = 0;
        +				u->top = top;
        +	bn_wexpand(b,top);	bdp = b->d;
        +				bdp[0] = 1;
        +				for (i=1;i<top;i++) bdp[i] = 0;
        +				b->top = top;
        +	bn_wexpand(c,top);	cdp = c->d;
        +				for (i=0;i<top;i++) cdp[i] = 0;
        +				c->top = top;
        +	vdp = v->d;	/* It pays off to "cache" *->d pointers, because
        +			 * it allows optimizer to be more aggressive.
        +			 * But we don't have to "cache" p->d, because *p
        +			 * is declared 'const'... */
        +	while (1)
        +		{
        +		while (ubits && !(udp[0]&1))
        +			{
        +			BN_ULONG u0,u1,b0,b1,mask;
        +
        +			u0   = udp[0];
        +			b0   = bdp[0];
        +			mask = (BN_ULONG)0-(b0&1);
        +			b0  ^= p->d[0]&mask;
        +			for (i=0;i<top-1;i++)
        +				{
        +				u1 = udp[i+1];
        +				udp[i] = ((u0>>1)|(u1<<(BN_BITS2-1)))&BN_MASK2;
        +				u0 = u1;
        +				b1 = bdp[i+1]^(p->d[i+1]&mask);
        +				bdp[i] = ((b0>>1)|(b1<<(BN_BITS2-1)))&BN_MASK2;
        +				b0 = b1;
        +				}
        +			udp[i] = u0>>1;
        +			bdp[i] = b0>>1;
        +			ubits--;
        +			}
        +
        +		if (ubits<=BN_BITS2 && udp[0]==1) break;
        +
        +		if (ubits<vbits)
        +			{
        +			i = ubits; ubits = vbits; vbits = i;
        +			tmp = u; u = v; v = tmp;
        +			tmp = b; b = c; c = tmp;
        +			udp = vdp; vdp = v->d;
        +			bdp = cdp; cdp = c->d;
        +			}
        +		for(i=0;i<top;i++)
        +			{
        +			udp[i] ^= vdp[i];
        +			bdp[i] ^= cdp[i];
        +			}
        +		if (ubits==vbits)
        +			{
        +			BN_ULONG ul;
        +			int utop = (ubits-1)/BN_BITS2;
        +
        +			while ((ul=udp[utop])==0 && utop) utop--;
        +			ubits = utop*BN_BITS2 + BN_num_bits_word(ul);
        +			}
        +		}
        +	bn_correct_top(b);
        +	}
        +#endif
        +
        +	if (!BN_copy(r, b)) goto err;
        +	bn_check_top(r);
        +	ret = 1;
        +
        +err:
        +#ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */
        +        bn_correct_top(c);
        +        bn_correct_top(u);
        +        bn_correct_top(v);
        +#endif
        +  	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Invert xx, reduce modulo p, and store the result in r. r could be xx. 
        + *
        + * This function calls down to the BN_GF2m_mod_inv implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_inv function.
        + */
        +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx)
        +	{
        +	BIGNUM *field;
        +	int ret = 0;
        +
        +	bn_check_top(xx);
        +	BN_CTX_start(ctx);
        +	if ((field = BN_CTX_get(ctx)) == NULL) goto err;
        +	if (!BN_GF2m_arr2poly(p, field)) goto err;
        +	
        +	ret = BN_GF2m_mod_inv(r, xx, field, ctx);
        +	bn_check_top(r);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +
        +#ifndef OPENSSL_SUN_GF2M_DIV
        +/* Divide y by x, reduce modulo p, and store the result in r. r could be x 
        + * or y, x could equal y.
        + */
        +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	BIGNUM *xinv = NULL;
        +	int ret = 0;
        +
        +	bn_check_top(y);
        +	bn_check_top(x);
        +	bn_check_top(p);
        +
        +	BN_CTX_start(ctx);
        +	xinv = BN_CTX_get(ctx);
        +	if (xinv == NULL) goto err;
        +	
        +	if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) goto err;
        +	if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) goto err;
        +	bn_check_top(r);
        +	ret = 1;
        +
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +#else
        +/* Divide y by x, reduce modulo p, and store the result in r. r could be x 
        + * or y, x could equal y.
        + * Uses algorithm Modular_Division_GF(2^m) from 
        + *     Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to 
        + *     the Great Divide".
        + */
        +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	BIGNUM *a, *b, *u, *v;
        +	int ret = 0;
        +
        +	bn_check_top(y);
        +	bn_check_top(x);
        +	bn_check_top(p);
        +
        +	BN_CTX_start(ctx);
        +	
        +	a = BN_CTX_get(ctx);
        +	b = BN_CTX_get(ctx);
        +	u = BN_CTX_get(ctx);
        +	v = BN_CTX_get(ctx);
        +	if (v == NULL) goto err;
        +
        +	/* reduce x and y mod p */
        +	if (!BN_GF2m_mod(u, y, p)) goto err;
        +	if (!BN_GF2m_mod(a, x, p)) goto err;
        +	if (!BN_copy(b, p)) goto err;
        +	
        +	while (!BN_is_odd(a))
        +		{
        +		if (!BN_rshift1(a, a)) goto err;
        +		if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
        +		if (!BN_rshift1(u, u)) goto err;
        +		}
        +
        +	do
        +		{
        +		if (BN_GF2m_cmp(b, a) > 0)
        +			{
        +			if (!BN_GF2m_add(b, b, a)) goto err;
        +			if (!BN_GF2m_add(v, v, u)) goto err;
        +			do
        +				{
        +				if (!BN_rshift1(b, b)) goto err;
        +				if (BN_is_odd(v)) if (!BN_GF2m_add(v, v, p)) goto err;
        +				if (!BN_rshift1(v, v)) goto err;
        +				} while (!BN_is_odd(b));
        +			}
        +		else if (BN_abs_is_word(a, 1))
        +			break;
        +		else
        +			{
        +			if (!BN_GF2m_add(a, a, b)) goto err;
        +			if (!BN_GF2m_add(u, u, v)) goto err;
        +			do
        +				{
        +				if (!BN_rshift1(a, a)) goto err;
        +				if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
        +				if (!BN_rshift1(u, u)) goto err;
        +				} while (!BN_is_odd(a));
        +			}
        +		} while (1);
        +
        +	if (!BN_copy(r, u)) goto err;
        +	bn_check_top(r);
        +	ret = 1;
        +
        +err:
        +  	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +#endif
        +
        +/* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx 
        + * or yy, xx could equal yy.
        + *
        + * This function calls down to the BN_GF2m_mod_div implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_div function.
        + */
        +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int p[], BN_CTX *ctx)
        +	{
        +	BIGNUM *field;
        +	int ret = 0;
        +
        +	bn_check_top(yy);
        +	bn_check_top(xx);
        +
        +	BN_CTX_start(ctx);
        +	if ((field = BN_CTX_get(ctx)) == NULL) goto err;
        +	if (!BN_GF2m_arr2poly(p, field)) goto err;
        +	
        +	ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
        +	bn_check_top(r);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +
        +/* Compute the bth power of a, reduce modulo p, and store
        + * the result in r.  r could be a.
        + * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
        + */
        +int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
        +	{
        +	int ret = 0, i, n;
        +	BIGNUM *u;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	if (BN_is_zero(b))
        +		return(BN_one(r));
        +
        +	if (BN_abs_is_word(b, 1))
        +		return (BN_copy(r, a) != NULL);
        +
        +	BN_CTX_start(ctx);
        +	if ((u = BN_CTX_get(ctx)) == NULL) goto err;
        +	
        +	if (!BN_GF2m_mod_arr(u, a, p)) goto err;
        +	
        +	n = BN_num_bits(b) - 1;
        +	for (i = n - 1; i >= 0; i--)
        +		{
        +		if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) goto err;
        +		if (BN_is_bit_set(b, i))
        +			{
        +			if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) goto err;
        +			}
        +		}
        +	if (!BN_copy(r, u)) goto err;
        +	bn_check_top(r);
        +	ret = 1;
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Compute the bth power of a, reduce modulo p, and store
        + * the result in r.  r could be a.
        + *
        + * This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_exp_arr function.
        + */
        +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	const int max = BN_num_bits(p) + 1;
        +	int *arr=NULL;
        +	bn_check_top(a);
        +	bn_check_top(b);
        +	bn_check_top(p);
        +	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
        +	ret = BN_GF2m_poly2arr(p, arr, max);
        +	if (!ret || ret > max)
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD_EXP,BN_R_INVALID_LENGTH);
        +		goto err;
        +		}
        +	ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
        +	bn_check_top(r);
        +err:
        +	if (arr) OPENSSL_free(arr);
        +	return ret;
        +	}
        +
        +/* Compute the square root of a, reduce modulo p, and store
        + * the result in r.  r could be a.
        + * Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
        + */
        +int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BIGNUM *u;
        +
        +	bn_check_top(a);
        +
        +	if (!p[0])
        +		{
        +		/* reduction mod 1 => return 0 */
        +		BN_zero(r);
        +		return 1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	if ((u = BN_CTX_get(ctx)) == NULL) goto err;
        +	
        +	if (!BN_set_bit(u, p[0] - 1)) goto err;
        +	ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
        +	bn_check_top(r);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Compute the square root of a, reduce modulo p, and store
        + * the result in r.  r could be a.
        + *
        + * This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_sqrt_arr function.
        + */
        +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	const int max = BN_num_bits(p) + 1;
        +	int *arr=NULL;
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
        +	ret = BN_GF2m_poly2arr(p, arr, max);
        +	if (!ret || ret > max)
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD_SQRT,BN_R_INVALID_LENGTH);
        +		goto err;
        +		}
        +	ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
        +	bn_check_top(r);
        +err:
        +	if (arr) OPENSSL_free(arr);
        +	return ret;
        +	}
        +
        +/* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
        + * Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
        + */
        +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CTX *ctx)
        +	{
        +	int ret = 0, count = 0, j;
        +	BIGNUM *a, *z, *rho, *w, *w2, *tmp;
        +
        +	bn_check_top(a_);
        +
        +	if (!p[0])
        +		{
        +		/* reduction mod 1 => return 0 */
        +		BN_zero(r);
        +		return 1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	a = BN_CTX_get(ctx);
        +	z = BN_CTX_get(ctx);
        +	w = BN_CTX_get(ctx);
        +	if (w == NULL) goto err;
        +
        +	if (!BN_GF2m_mod_arr(a, a_, p)) goto err;
        +	
        +	if (BN_is_zero(a))
        +		{
        +		BN_zero(r);
        +		ret = 1;
        +		goto err;
        +		}
        +
        +	if (p[0] & 0x1) /* m is odd */
        +		{
        +		/* compute half-trace of a */
        +		if (!BN_copy(z, a)) goto err;
        +		for (j = 1; j <= (p[0] - 1) / 2; j++)
        +			{
        +			if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
        +			if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
        +			if (!BN_GF2m_add(z, z, a)) goto err;
        +			}
        +		
        +		}
        +	else /* m is even */
        +		{
        +		rho = BN_CTX_get(ctx);
        +		w2 = BN_CTX_get(ctx);
        +		tmp = BN_CTX_get(ctx);
        +		if (tmp == NULL) goto err;
        +		do
        +			{
        +			if (!BN_rand(rho, p[0], 0, 0)) goto err;
        +			if (!BN_GF2m_mod_arr(rho, rho, p)) goto err;
        +			BN_zero(z);
        +			if (!BN_copy(w, rho)) goto err;
        +			for (j = 1; j <= p[0] - 1; j++)
        +				{
        +				if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
        +				if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) goto err;
        +				if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) goto err;
        +				if (!BN_GF2m_add(z, z, tmp)) goto err;
        +				if (!BN_GF2m_add(w, w2, rho)) goto err;
        +				}
        +			count++;
        +			} while (BN_is_zero(w) && (count < MAX_ITERATIONS));
        +		if (BN_is_zero(w))
        +			{
        +			BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,BN_R_TOO_MANY_ITERATIONS);
        +			goto err;
        +			}
        +		}
        +	
        +	if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err;
        +	if (!BN_GF2m_add(w, z, w)) goto err;
        +	if (BN_GF2m_cmp(w, a))
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
        +		goto err;
        +		}
        +
        +	if (!BN_copy(r, z)) goto err;
        +	bn_check_top(r);
        +
        +	ret = 1;
        +
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
        + *
        + * This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper
        + * function is only provided for convenience; for best performance, use the 
        + * BN_GF2m_mod_solve_quad_arr function.
        + */
        +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	const int max = BN_num_bits(p) + 1;
        +	int *arr=NULL;
        +	bn_check_top(a);
        +	bn_check_top(p);
        +	if ((arr = (int *)OPENSSL_malloc(sizeof(int) *
        +						max)) == NULL) goto err;
        +	ret = BN_GF2m_poly2arr(p, arr, max);
        +	if (!ret || ret > max)
        +		{
        +		BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD,BN_R_INVALID_LENGTH);
        +		goto err;
        +		}
        +	ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
        +	bn_check_top(r);
        +err:
        +	if (arr) OPENSSL_free(arr);
        +	return ret;
        +	}
        +
        +/* Convert the bit-string representation of a polynomial
        + * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding 
        + * to the bits with non-zero coefficient.  Array is terminated with -1.
        + * Up to max elements of the array will be filled.  Return value is total
        + * number of array elements that would be filled if array was large enough.
        + */
        +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
        +	{
        +	int i, j, k = 0;
        +	BN_ULONG mask;
        +
        +	if (BN_is_zero(a))
        +		return 0;
        +
        +	for (i = a->top - 1; i >= 0; i--)
        +		{
        +		if (!a->d[i])
        +			/* skip word if a->d[i] == 0 */
        +			continue;
        +		mask = BN_TBIT;
        +		for (j = BN_BITS2 - 1; j >= 0; j--)
        +			{
        +			if (a->d[i] & mask) 
        +				{
        +				if (k < max) p[k] = BN_BITS2 * i + j;
        +				k++;
        +				}
        +			mask >>= 1;
        +			}
        +		}
        +
        +	if (k < max) {
        +		p[k] = -1;
        +		k++;
        +	}
        +
        +	return k;
        +	}
        +
        +/* Convert the coefficient array representation of a polynomial to a 
        + * bit-string.  The array must be terminated by -1.
        + */
        +int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
        +	{
        +	int i;
        +
        +	bn_check_top(a);
        +	BN_zero(a);
        +	for (i = 0; p[i] != -1; i++)
        +		{
        +		if (BN_set_bit(a, p[i]) == 0)
        +			return 0;
        +		}
        +	bn_check_top(a);
        +
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_kron.c b/vendor/openssl/openssl/crypto/bn/bn_kron.c
        new file mode 100644
        index 000000000..740359b75
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_kron.c
        @@ -0,0 +1,184 @@
        +/* crypto/bn/bn_kron.c */
        +/* ====================================================================
        + * 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 "bn_lcl.h"
        +
        +/* least significant word */
        +#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
        +
        +/* Returns -2 for errors because both -1 and 0 are valid results. */
        +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int i;
        +	int ret = -2; /* avoid 'uninitialized' warning */
        +	int err = 0;
        +	BIGNUM *A, *B, *tmp;
        +	/* In 'tab', only odd-indexed entries are relevant:
        +	 * For any odd BIGNUM n,
        +	 *     tab[BN_lsw(n) & 7]
        +	 * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
        +	 * Note that the sign of n does not matter.
        +	 */
        +	static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1};
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	BN_CTX_start(ctx);
        +	A = BN_CTX_get(ctx);
        +	B = BN_CTX_get(ctx);
        +	if (B == NULL) goto end;
        +	
        +	err = !BN_copy(A, a);
        +	if (err) goto end;
        +	err = !BN_copy(B, b);
        +	if (err) goto end;
        +
        +	/*
        +	 * Kronecker symbol, imlemented according to Henri Cohen,
        +	 * "A Course in Computational Algebraic Number Theory"
        +	 * (algorithm 1.4.10).
        +	 */
        +
        +	/* Cohen's step 1: */
        +
        +	if (BN_is_zero(B))
        +		{
        +		ret = BN_abs_is_word(A, 1);
        +		goto end;
        + 		}
        +	
        +	/* Cohen's step 2: */
        +
        +	if (!BN_is_odd(A) && !BN_is_odd(B))
        +		{
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	/* now  B  is non-zero */
        +	i = 0;
        +	while (!BN_is_bit_set(B, i))
        +		i++;
        +	err = !BN_rshift(B, B, i);
        +	if (err) goto end;
        +	if (i & 1)
        +		{
        +		/* i is odd */
        +		/* (thus  B  was even, thus  A  must be odd!)  */
        +
        +		/* set 'ret' to $(-1)^{(A^2-1)/8}$ */
        +		ret = tab[BN_lsw(A) & 7];
        +		}
        +	else
        +		{
        +		/* i is even */
        +		ret = 1;
        +		}
        +	
        +	if (B->neg)
        +		{
        +		B->neg = 0;
        +		if (A->neg)
        +			ret = -ret;
        +		}
        +
        +	/* now  B  is positive and odd, so what remains to be done is
        +	 * to compute the Jacobi symbol  (A/B)  and multiply it by 'ret' */
        +
        +	while (1)
        +		{
        +		/* Cohen's step 3: */
        +
        +		/*  B  is positive and odd */
        +
        +		if (BN_is_zero(A))
        +			{
        +			ret = BN_is_one(B) ? ret : 0;
        +			goto end;
        +			}
        +
        +		/* now  A  is non-zero */
        +		i = 0;
        +		while (!BN_is_bit_set(A, i))
        +			i++;
        +		err = !BN_rshift(A, A, i);
        +		if (err) goto end;
        +		if (i & 1)
        +			{
        +			/* i is odd */
        +			/* multiply 'ret' by  $(-1)^{(B^2-1)/8}$ */
        +			ret = ret * tab[BN_lsw(B) & 7];
        +			}
        +	
        +		/* Cohen's step 4: */
        +		/* multiply 'ret' by  $(-1)^{(A-1)(B-1)/4}$ */
        +		if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
        +			ret = -ret;
        +		
        +		/* (A, B) := (B mod |A|, |A|) */
        +		err = !BN_nnmod(B, B, A, ctx);
        +		if (err) goto end;
        +		tmp = A; A = B; B = tmp;
        +		tmp->neg = 0;
        +		}
        +end:
        +	BN_CTX_end(ctx);
        +	if (err)
        +		return -2;
        +	else
        +		return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_lcl.h b/vendor/openssl/openssl/crypto/bn/bn_lcl.h
        new file mode 100644
        index 000000000..817c773b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_lcl.h
        @@ -0,0 +1,515 @@
        +/* crypto/bn/bn_lcl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_BN_LCL_H
        +#define HEADER_BN_LCL_H
        +
        +#include <openssl/bn.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +/*
        + * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
        + *
        + *
        + * For window size 'w' (w >= 2) and a random 'b' bits exponent,
        + * the number of multiplications is a constant plus on average
        + *
        + *    2^(w-1) + (b-w)/(w+1);
        + *
        + * here  2^(w-1)  is for precomputing the table (we actually need
        + * entries only for windows that have the lowest bit set), and
        + * (b-w)/(w+1)  is an approximation for the expected number of
        + * w-bit windows, not counting the first one.
        + *
        + * Thus we should use
        + *
        + *    w >= 6  if        b > 671
        + *     w = 5  if  671 > b > 239
        + *     w = 4  if  239 > b >  79
        + *     w = 3  if   79 > b >  23
        + *    w <= 2  if   23 > b
        + *
        + * (with draws in between).  Very small exponents are often selected
        + * with low Hamming weight, so we use  w = 1  for b <= 23.
        + */
        +#if 1
        +#define BN_window_bits_for_exponent_size(b) \
        +		((b) > 671 ? 6 : \
        +		 (b) > 239 ? 5 : \
        +		 (b) >  79 ? 4 : \
        +		 (b) >  23 ? 3 : 1)
        +#else
        +/* Old SSLeay/OpenSSL table.
        + * Maximum window size was 5, so this table differs for b==1024;
        + * but it coincides for other interesting values (b==160, b==512).
        + */
        +#define BN_window_bits_for_exponent_size(b) \
        +		((b) > 255 ? 5 : \
        +		 (b) > 127 ? 4 : \
        +		 (b) >  17 ? 3 : 1)
        +#endif	 
        +
        +
        +
        +/* BN_mod_exp_mont_conttime is based on the assumption that the
        + * L1 data cache line width of the target processor is at least
        + * the following value.
        + */
        +#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH	( 64 )
        +#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK	(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
        +
        +/* Window sizes optimized for fixed window size modular exponentiation
        + * algorithm (BN_mod_exp_mont_consttime).
        + *
        + * To achieve the security goals of BN_mode_exp_mont_consttime, the
        + * maximum size of the window must not exceed
        + * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). 
        + *
        + * Window size thresholds are defined for cache line sizes of 32 and 64,
        + * cache line sizes where log_2(32)=5 and log_2(64)=6 respectively. A
        + * window size of 7 should only be used on processors that have a 128
        + * byte or greater cache line size.
        + */
        +#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
        +
        +#  define BN_window_bits_for_ctime_exponent_size(b) \
        +		((b) > 937 ? 6 : \
        +		 (b) > 306 ? 5 : \
        +		 (b) >  89 ? 4 : \
        +		 (b) >  22 ? 3 : 1)
        +#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE	(6)
        +
        +#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
        +
        +#  define BN_window_bits_for_ctime_exponent_size(b) \
        +		((b) > 306 ? 5 : \
        +		 (b) >  89 ? 4 : \
        +		 (b) >  22 ? 3 : 1)
        +#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE	(5)
        +
        +#endif
        +
        +
        +/* Pentium pro 16,16,16,32,64 */
        +/* Alpha       16,16,16,16.64 */
        +#define BN_MULL_SIZE_NORMAL			(16) /* 32 */
        +#define BN_MUL_RECURSIVE_SIZE_NORMAL		(16) /* 32 less than */
        +#define BN_SQR_RECURSIVE_SIZE_NORMAL		(16) /* 32 */
        +#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL	(32) /* 32 */
        +#define BN_MONT_CTX_SET_SIZE_WORD		(64) /* 32 */
        +
        +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
        +/*
        + * BN_UMULT_HIGH section.
        + *
        + * No, I'm not trying to overwhelm you when stating that the
        + * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
        + * you to be impressed when I say that if the compiler doesn't
        + * support 2*N integer type, then you have to replace every N*N
        + * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
        + * and additions which unavoidably results in severe performance
        + * penalties. Of course provided that the hardware is capable of
        + * producing 2*N result... That's when you normally start
        + * considering assembler implementation. However! It should be
        + * pointed out that some CPUs (most notably Alpha, PowerPC and
        + * upcoming IA-64 family:-) provide *separate* instruction
        + * calculating the upper half of the product placing the result
        + * into a general purpose register. Now *if* the compiler supports
        + * inline assembler, then it's not impossible to implement the
        + * "bignum" routines (and have the compiler optimize 'em)
        + * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
        + * macro is about:-)
        + *
        + *					<appro@fy.chalmers.se>
        + */
        +# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
        +#  if defined(__DECC)
        +#   include <c_asm.h>
        +#   define BN_UMULT_HIGH(a,b)	(BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
        +#  elif defined(__GNUC__) && __GNUC__>=2
        +#   define BN_UMULT_HIGH(a,b)	({	\
        +	register BN_ULONG ret;		\
        +	asm ("umulh	%1,%2,%0"	\
        +	     : "=r"(ret)		\
        +	     : "r"(a), "r"(b));		\
        +	ret;			})
        +#  endif	/* compiler */
        +# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
        +#  if defined(__GNUC__) && __GNUC__>=2
        +#   define BN_UMULT_HIGH(a,b)	({	\
        +	register BN_ULONG ret;		\
        +	asm ("mulhdu	%0,%1,%2"	\
        +	     : "=r"(ret)		\
        +	     : "r"(a), "r"(b));		\
        +	ret;			})
        +#  endif	/* compiler */
        +# elif (defined(__x86_64) || defined(__x86_64__)) && \
        +       (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
        +#  if defined(__GNUC__) && __GNUC__>=2
        +#   define BN_UMULT_HIGH(a,b)	({	\
        +	register BN_ULONG ret,discard;	\
        +	asm ("mulq	%3"		\
        +	     : "=a"(discard),"=d"(ret)	\
        +	     : "a"(a), "g"(b)		\
        +	     : "cc");			\
        +	ret;			})
        +#   define BN_UMULT_LOHI(low,high,a,b)	\
        +	asm ("mulq	%3"		\
        +		: "=a"(low),"=d"(high)	\
        +		: "a"(a),"g"(b)		\
        +		: "cc");
        +#  endif
        +# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
        +#  if defined(_MSC_VER) && _MSC_VER>=1400
        +    unsigned __int64 __umulh	(unsigned __int64 a,unsigned __int64 b);
        +    unsigned __int64 _umul128	(unsigned __int64 a,unsigned __int64 b,
        +				 unsigned __int64 *h);
        +#   pragma intrinsic(__umulh,_umul128)
        +#   define BN_UMULT_HIGH(a,b)		__umulh((a),(b))
        +#   define BN_UMULT_LOHI(low,high,a,b)	((low)=_umul128((a),(b),&(high)))
        +#  endif
        +# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
        +#  if defined(__GNUC__) && __GNUC__>=2
        +#   if __GNUC__>=4 && __GNUC_MINOR__>=4 /* "h" constraint is no more since 4.4 */
        +#     define BN_UMULT_HIGH(a,b)		 (((__uint128_t)(a)*(b))>>64)
        +#     define BN_UMULT_LOHI(low,high,a,b) ({	\
        +	__uint128_t ret=(__uint128_t)(a)*(b);	\
        +	(high)=ret>>64; (low)=ret;	 })
        +#   else
        +#     define BN_UMULT_HIGH(a,b)	({	\
        +	register BN_ULONG ret;		\
        +	asm ("dmultu	%1,%2"		\
        +	     : "=h"(ret)		\
        +	     : "r"(a), "r"(b) : "l");	\
        +	ret;			})
        +#     define BN_UMULT_LOHI(low,high,a,b)\
        +	asm ("dmultu	%2,%3"		\
        +	     : "=l"(low),"=h"(high)	\
        +	     : "r"(a), "r"(b));
        +#    endif
        +#  endif
        +# endif		/* cpu */
        +#endif		/* OPENSSL_NO_ASM */
        +
        +/*************************************************************
        + * Using the long long type
        + */
        +#define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
        +#define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
        +
        +#ifdef BN_DEBUG_RAND
        +#define bn_clear_top2max(a) \
        +	{ \
        +	int      ind = (a)->dmax - (a)->top; \
        +	BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
        +	for (; ind != 0; ind--) \
        +		*(++ftl) = 0x0; \
        +	}
        +#else
        +#define bn_clear_top2max(a)
        +#endif
        +
        +#ifdef BN_LLONG
        +#define mul_add(r,a,w,c) { \
        +	BN_ULLONG t; \
        +	t=(BN_ULLONG)w * (a) + (r) + (c); \
        +	(r)= Lw(t); \
        +	(c)= Hw(t); \
        +	}
        +
        +#define mul(r,a,w,c) { \
        +	BN_ULLONG t; \
        +	t=(BN_ULLONG)w * (a) + (c); \
        +	(r)= Lw(t); \
        +	(c)= Hw(t); \
        +	}
        +
        +#define sqr(r0,r1,a) { \
        +	BN_ULLONG t; \
        +	t=(BN_ULLONG)(a)*(a); \
        +	(r0)=Lw(t); \
        +	(r1)=Hw(t); \
        +	}
        +
        +#elif defined(BN_UMULT_LOHI)
        +#define mul_add(r,a,w,c) {		\
        +	BN_ULONG high,low,ret,tmp=(a);	\
        +	ret =  (r);			\
        +	BN_UMULT_LOHI(low,high,w,tmp);	\
        +	ret += (c);			\
        +	(c) =  (ret<(c))?1:0;		\
        +	(c) += high;			\
        +	ret += low;			\
        +	(c) += (ret<low)?1:0;		\
        +	(r) =  ret;			\
        +	}
        +
        +#define mul(r,a,w,c)	{		\
        +	BN_ULONG high,low,ret,ta=(a);	\
        +	BN_UMULT_LOHI(low,high,w,ta);	\
        +	ret =  low + (c);		\
        +	(c) =  high;			\
        +	(c) += (ret<low)?1:0;		\
        +	(r) =  ret;			\
        +	}
        +
        +#define sqr(r0,r1,a)	{		\
        +	BN_ULONG tmp=(a);		\
        +	BN_UMULT_LOHI(r0,r1,tmp,tmp);	\
        +	}
        +
        +#elif defined(BN_UMULT_HIGH)
        +#define mul_add(r,a,w,c) {		\
        +	BN_ULONG high,low,ret,tmp=(a);	\
        +	ret =  (r);			\
        +	high=  BN_UMULT_HIGH(w,tmp);	\
        +	ret += (c);			\
        +	low =  (w) * tmp;		\
        +	(c) =  (ret<(c))?1:0;		\
        +	(c) += high;			\
        +	ret += low;			\
        +	(c) += (ret<low)?1:0;		\
        +	(r) =  ret;			\
        +	}
        +
        +#define mul(r,a,w,c)	{		\
        +	BN_ULONG high,low,ret,ta=(a);	\
        +	low =  (w) * ta;		\
        +	high=  BN_UMULT_HIGH(w,ta);	\
        +	ret =  low + (c);		\
        +	(c) =  high;			\
        +	(c) += (ret<low)?1:0;		\
        +	(r) =  ret;			\
        +	}
        +
        +#define sqr(r0,r1,a)	{		\
        +	BN_ULONG tmp=(a);		\
        +	(r0) = tmp * tmp;		\
        +	(r1) = BN_UMULT_HIGH(tmp,tmp);	\
        +	}
        +
        +#else
        +/*************************************************************
        + * No long long type
        + */
        +
        +#define LBITS(a)	((a)&BN_MASK2l)
        +#define HBITS(a)	(((a)>>BN_BITS4)&BN_MASK2l)
        +#define	L2HBITS(a)	(((a)<<BN_BITS4)&BN_MASK2)
        +
        +#define LLBITS(a)	((a)&BN_MASKl)
        +#define LHBITS(a)	(((a)>>BN_BITS2)&BN_MASKl)
        +#define	LL2HBITS(a)	((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
        +
        +#define mul64(l,h,bl,bh) \
        +	{ \
        +	BN_ULONG m,m1,lt,ht; \
        + \
        +	lt=l; \
        +	ht=h; \
        +	m =(bh)*(lt); \
        +	lt=(bl)*(lt); \
        +	m1=(bl)*(ht); \
        +	ht =(bh)*(ht); \
        +	m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \
        +	ht+=HBITS(m); \
        +	m1=L2HBITS(m); \
        +	lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
        +	(l)=lt; \
        +	(h)=ht; \
        +	}
        +
        +#define sqr64(lo,ho,in) \
        +	{ \
        +	BN_ULONG l,h,m; \
        + \
        +	h=(in); \
        +	l=LBITS(h); \
        +	h=HBITS(h); \
        +	m =(l)*(h); \
        +	l*=l; \
        +	h*=h; \
        +	h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
        +	m =(m&BN_MASK2l)<<(BN_BITS4+1); \
        +	l=(l+m)&BN_MASK2; if (l < m) h++; \
        +	(lo)=l; \
        +	(ho)=h; \
        +	}
        +
        +#define mul_add(r,a,bl,bh,c) { \
        +	BN_ULONG l,h; \
        + \
        +	h= (a); \
        +	l=LBITS(h); \
        +	h=HBITS(h); \
        +	mul64(l,h,(bl),(bh)); \
        + \
        +	/* non-multiply part */ \
        +	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
        +	(c)=(r); \
        +	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
        +	(c)=h&BN_MASK2; \
        +	(r)=l; \
        +	}
        +
        +#define mul(r,a,bl,bh,c) { \
        +	BN_ULONG l,h; \
        + \
        +	h= (a); \
        +	l=LBITS(h); \
        +	h=HBITS(h); \
        +	mul64(l,h,(bl),(bh)); \
        + \
        +	/* non-multiply part */ \
        +	l+=(c); if ((l&BN_MASK2) < (c)) h++; \
        +	(c)=h&BN_MASK2; \
        +	(r)=l&BN_MASK2; \
        +	}
        +#endif /* !BN_LLONG */
        +
        +#if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS)
        +#undef bn_div_words
        +#endif
        +
        +void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
        +void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
        +void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
        +void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
        +void bn_sqr_comba8(BN_ULONG *r,const BN_ULONG *a);
        +void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a);
        +int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n);
        +int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
        +	int cl, int dl);
        +void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
        +	int dna,int dnb,BN_ULONG *t);
        +void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
        +	int n,int tna,int tnb,BN_ULONG *t);
        +void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t);
        +void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
        +void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
        +	BN_ULONG *t);
        +void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
        +	BN_ULONG *t);
        +BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
        +	int cl, int dl);
        +BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
        +	int cl, int dl);
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_lib.c b/vendor/openssl/openssl/crypto/bn/bn_lib.c
        new file mode 100644
        index 000000000..7a5676de6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_lib.c
        @@ -0,0 +1,826 @@
        +/* crypto/bn/bn_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef BN_DEBUG
        +# undef NDEBUG /* avoid conflicting definitions */
        +# define NDEBUG
        +#endif
        +
        +#include <assert.h>
        +#include <limits.h>
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
        +
        +/* This stuff appears to be completely unused, so is deprecated */
        +#ifndef OPENSSL_NO_DEPRECATED
        +/* For a 32 bit machine
        + * 2 -   4 ==  128
        + * 3 -   8 ==  256
        + * 4 -  16 ==  512
        + * 5 -  32 == 1024
        + * 6 -  64 == 2048
        + * 7 - 128 == 4096
        + * 8 - 256 == 8192
        + */
        +static int bn_limit_bits=0;
        +static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
        +static int bn_limit_bits_low=0;
        +static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
        +static int bn_limit_bits_high=0;
        +static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
        +static int bn_limit_bits_mont=0;
        +static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
        +
        +void BN_set_params(int mult, int high, int low, int mont)
        +	{
        +	if (mult >= 0)
        +		{
        +		if (mult > (int)(sizeof(int)*8)-1)
        +			mult=sizeof(int)*8-1;
        +		bn_limit_bits=mult;
        +		bn_limit_num=1<<mult;
        +		}
        +	if (high >= 0)
        +		{
        +		if (high > (int)(sizeof(int)*8)-1)
        +			high=sizeof(int)*8-1;
        +		bn_limit_bits_high=high;
        +		bn_limit_num_high=1<<high;
        +		}
        +	if (low >= 0)
        +		{
        +		if (low > (int)(sizeof(int)*8)-1)
        +			low=sizeof(int)*8-1;
        +		bn_limit_bits_low=low;
        +		bn_limit_num_low=1<<low;
        +		}
        +	if (mont >= 0)
        +		{
        +		if (mont > (int)(sizeof(int)*8)-1)
        +			mont=sizeof(int)*8-1;
        +		bn_limit_bits_mont=mont;
        +		bn_limit_num_mont=1<<mont;
        +		}
        +	}
        +
        +int BN_get_params(int which)
        +	{
        +	if      (which == 0) return(bn_limit_bits);
        +	else if (which == 1) return(bn_limit_bits_high);
        +	else if (which == 2) return(bn_limit_bits_low);
        +	else if (which == 3) return(bn_limit_bits_mont);
        +	else return(0);
        +	}
        +#endif
        +
        +const BIGNUM *BN_value_one(void)
        +	{
        +	static const BN_ULONG data_one=1L;
        +	static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
        +
        +	return(&const_one);
        +	}
        +
        +int BN_num_bits_word(BN_ULONG l)
        +	{
        +	static const unsigned char bits[256]={
        +		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
        +		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
        +		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        +		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        +		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        +		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        +		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        +		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        +		};
        +
        +#if defined(SIXTY_FOUR_BIT_LONG)
        +	if (l & 0xffffffff00000000L)
        +		{
        +		if (l & 0xffff000000000000L)
        +			{
        +			if (l & 0xff00000000000000L)
        +				{
        +				return(bits[(int)(l>>56)]+56);
        +				}
        +			else	return(bits[(int)(l>>48)]+48);
        +			}
        +		else
        +			{
        +			if (l & 0x0000ff0000000000L)
        +				{
        +				return(bits[(int)(l>>40)]+40);
        +				}
        +			else	return(bits[(int)(l>>32)]+32);
        +			}
        +		}
        +	else
        +#else
        +#ifdef SIXTY_FOUR_BIT
        +	if (l & 0xffffffff00000000LL)
        +		{
        +		if (l & 0xffff000000000000LL)
        +			{
        +			if (l & 0xff00000000000000LL)
        +				{
        +				return(bits[(int)(l>>56)]+56);
        +				}
        +			else	return(bits[(int)(l>>48)]+48);
        +			}
        +		else
        +			{
        +			if (l & 0x0000ff0000000000LL)
        +				{
        +				return(bits[(int)(l>>40)]+40);
        +				}
        +			else	return(bits[(int)(l>>32)]+32);
        +			}
        +		}
        +	else
        +#endif
        +#endif
        +		{
        +#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
        +		if (l & 0xffff0000L)
        +			{
        +			if (l & 0xff000000L)
        +				return(bits[(int)(l>>24L)]+24);
        +			else	return(bits[(int)(l>>16L)]+16);
        +			}
        +		else
        +#endif
        +			{
        +#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
        +			if (l & 0xff00L)
        +				return(bits[(int)(l>>8)]+8);
        +			else	
        +#endif
        +				return(bits[(int)(l   )]  );
        +			}
        +		}
        +	}
        +
        +int BN_num_bits(const BIGNUM *a)
        +	{
        +	int i = a->top - 1;
        +	bn_check_top(a);
        +
        +	if (BN_is_zero(a)) return 0;
        +	return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
        +	}
        +
        +void BN_clear_free(BIGNUM *a)
        +	{
        +	int i;
        +
        +	if (a == NULL) return;
        +	bn_check_top(a);
        +	if (a->d != NULL)
        +		{
        +		OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
        +		if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
        +			OPENSSL_free(a->d);
        +		}
        +	i=BN_get_flags(a,BN_FLG_MALLOCED);
        +	OPENSSL_cleanse(a,sizeof(BIGNUM));
        +	if (i)
        +		OPENSSL_free(a);
        +	}
        +
        +void BN_free(BIGNUM *a)
        +	{
        +	if (a == NULL) return;
        +	bn_check_top(a);
        +	if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
        +		OPENSSL_free(a->d);
        +	if (a->flags & BN_FLG_MALLOCED)
        +		OPENSSL_free(a);
        +	else
        +		{
        +#ifndef OPENSSL_NO_DEPRECATED
        +		a->flags|=BN_FLG_FREE;
        +#endif
        +		a->d = NULL;
        +		}
        +	}
        +
        +void BN_init(BIGNUM *a)
        +	{
        +	memset(a,0,sizeof(BIGNUM));
        +	bn_check_top(a);
        +	}
        +
        +BIGNUM *BN_new(void)
        +	{
        +	BIGNUM *ret;
        +
        +	if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
        +		{
        +		BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	ret->flags=BN_FLG_MALLOCED;
        +	ret->top=0;
        +	ret->neg=0;
        +	ret->dmax=0;
        +	ret->d=NULL;
        +	bn_check_top(ret);
        +	return(ret);
        +	}
        +
        +/* This is used both by bn_expand2() and bn_dup_expand() */
        +/* The caller MUST check that words > b->dmax before calling this */
        +static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
        +	{
        +	BN_ULONG *A,*a = NULL;
        +	const BN_ULONG *B;
        +	int i;
        +
        +	bn_check_top(b);
        +
        +	if (words > (INT_MAX/(4*BN_BITS2)))
        +		{
        +		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
        +		return NULL;
        +		}
        +	if (BN_get_flags(b,BN_FLG_STATIC_DATA))
        +		{
        +		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
        +		return(NULL);
        +		}
        +	a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
        +	if (A == NULL)
        +		{
        +		BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +#if 1
        +	B=b->d;
        +	/* Check if the previous number needs to be copied */
        +	if (B != NULL)
        +		{
        +		for (i=b->top>>2; i>0; i--,A+=4,B+=4)
        +			{
        +			/*
        +			 * The fact that the loop is unrolled
        +			 * 4-wise is a tribute to Intel. It's
        +			 * the one that doesn't have enough
        +			 * registers to accomodate more data.
        +			 * I'd unroll it 8-wise otherwise:-)
        +			 *
        +			 *		<appro@fy.chalmers.se>
        +			 */
        +			BN_ULONG a0,a1,a2,a3;
        +			a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
        +			A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
        +			}
        +		switch (b->top&3)
        +			{
        +		case 3:	A[2]=B[2];
        +		case 2:	A[1]=B[1];
        +		case 1:	A[0]=B[0];
        +		case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
        +		         * the switch table by doing a=top&3; a--; goto jump_table[a];
        +		         * which fails for top== 0 */
        +			;
        +			}
        +		}
        +
        +#else
        +	memset(A,0,sizeof(BN_ULONG)*words);
        +	memcpy(A,b->d,sizeof(b->d[0])*b->top);
        +#endif
        +		
        +	return(a);
        +	}
        +
        +/* This is an internal function that can be used instead of bn_expand2()
        + * when there is a need to copy BIGNUMs instead of only expanding the
        + * data part, while still expanding them.
        + * Especially useful when needing to expand BIGNUMs that are declared
        + * 'const' and should therefore not be changed.
        + * The reason to use this instead of a BN_dup() followed by a bn_expand2()
        + * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
        + * will allocate new memory for the BIGNUM data twice, and free it once,
        + * while bn_dup_expand() makes sure allocation is made only once.
        + */
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
        +	{
        +	BIGNUM *r = NULL;
        +
        +	bn_check_top(b);
        +
        +	/* This function does not work if
        +	 *      words <= b->dmax && top < words
        +	 * because BN_dup() does not preserve 'dmax'!
        +	 * (But bn_dup_expand() is not used anywhere yet.)
        +	 */
        +
        +	if (words > b->dmax)
        +		{
        +		BN_ULONG *a = bn_expand_internal(b, words);
        +
        +		if (a)
        +			{
        +			r = BN_new();
        +			if (r)
        +				{
        +				r->top = b->top;
        +				r->dmax = words;
        +				r->neg = b->neg;
        +				r->d = a;
        +				}
        +			else
        +				{
        +				/* r == NULL, BN_new failure */
        +				OPENSSL_free(a);
        +				}
        +			}
        +		/* If a == NULL, there was an error in allocation in
        +		   bn_expand_internal(), and NULL should be returned */
        +		}
        +	else
        +		{
        +		r = BN_dup(b);
        +		}
        +
        +	bn_check_top(r);
        +	return r;
        +	}
        +#endif
        +
        +/* This is an internal function that should not be used in applications.
        + * It ensures that 'b' has enough room for a 'words' word number
        + * and initialises any unused part of b->d with leading zeros.
        + * It is mostly used by the various BIGNUM routines. If there is an error,
        + * NULL is returned. If not, 'b' is returned. */
        +
        +BIGNUM *bn_expand2(BIGNUM *b, int words)
        +	{
        +	bn_check_top(b);
        +
        +	if (words > b->dmax)
        +		{
        +		BN_ULONG *a = bn_expand_internal(b, words);
        +		if(!a) return NULL;
        +		if(b->d) OPENSSL_free(b->d);
        +		b->d=a;
        +		b->dmax=words;
        +		}
        +
        +/* None of this should be necessary because of what b->top means! */
        +#if 0
        +	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
        +	if (b->top < b->dmax)
        +		{
        +		int i;
        +		BN_ULONG *A = &(b->d[b->top]);
        +		for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
        +			{
        +			A[0]=0; A[1]=0; A[2]=0; A[3]=0;
        +			A[4]=0; A[5]=0; A[6]=0; A[7]=0;
        +			}
        +		for (i=(b->dmax - b->top)&7; i>0; i--,A++)
        +			A[0]=0;
        +		assert(A == &(b->d[b->dmax]));
        +		}
        +#endif
        +	bn_check_top(b);
        +	return b;
        +	}
        +
        +BIGNUM *BN_dup(const BIGNUM *a)
        +	{
        +	BIGNUM *t;
        +
        +	if (a == NULL) return NULL;
        +	bn_check_top(a);
        +
        +	t = BN_new();
        +	if (t == NULL) return NULL;
        +	if(!BN_copy(t, a))
        +		{
        +		BN_free(t);
        +		return NULL;
        +		}
        +	bn_check_top(t);
        +	return t;
        +	}
        +
        +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
        +	{
        +	int i;
        +	BN_ULONG *A;
        +	const BN_ULONG *B;
        +
        +	bn_check_top(b);
        +
        +	if (a == b) return(a);
        +	if (bn_wexpand(a,b->top) == NULL) return(NULL);
        +
        +#if 1
        +	A=a->d;
        +	B=b->d;
        +	for (i=b->top>>2; i>0; i--,A+=4,B+=4)
        +		{
        +		BN_ULONG a0,a1,a2,a3;
        +		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
        +		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
        +		}
        +	switch (b->top&3)
        +		{
        +		case 3: A[2]=B[2];
        +		case 2: A[1]=B[1];
        +		case 1: A[0]=B[0];
        +		case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
        +		}
        +#else
        +	memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
        +#endif
        +
        +	a->top=b->top;
        +	a->neg=b->neg;
        +	bn_check_top(a);
        +	return(a);
        +	}
        +
        +void BN_swap(BIGNUM *a, BIGNUM *b)
        +	{
        +	int flags_old_a, flags_old_b;
        +	BN_ULONG *tmp_d;
        +	int tmp_top, tmp_dmax, tmp_neg;
        +	
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	flags_old_a = a->flags;
        +	flags_old_b = b->flags;
        +
        +	tmp_d = a->d;
        +	tmp_top = a->top;
        +	tmp_dmax = a->dmax;
        +	tmp_neg = a->neg;
        +	
        +	a->d = b->d;
        +	a->top = b->top;
        +	a->dmax = b->dmax;
        +	a->neg = b->neg;
        +	
        +	b->d = tmp_d;
        +	b->top = tmp_top;
        +	b->dmax = tmp_dmax;
        +	b->neg = tmp_neg;
        +	
        +	a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
        +	b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
        +	bn_check_top(a);
        +	bn_check_top(b);
        +	}
        +
        +void BN_clear(BIGNUM *a)
        +	{
        +	bn_check_top(a);
        +	if (a->d != NULL)
        +		memset(a->d,0,a->dmax*sizeof(a->d[0]));
        +	a->top=0;
        +	a->neg=0;
        +	}
        +
        +BN_ULONG BN_get_word(const BIGNUM *a)
        +	{
        +	if (a->top > 1)
        +		return BN_MASK2;
        +	else if (a->top == 1)
        +		return a->d[0];
        +	/* a->top == 0 */
        +	return 0;
        +	}
        +
        +int BN_set_word(BIGNUM *a, BN_ULONG w)
        +	{
        +	bn_check_top(a);
        +	if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
        +	a->neg = 0;
        +	a->d[0] = w;
        +	a->top = (w ? 1 : 0);
        +	bn_check_top(a);
        +	return(1);
        +	}
        +
        +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
        +	{
        +	unsigned int i,m;
        +	unsigned int n;
        +	BN_ULONG l;
        +	BIGNUM  *bn = NULL;
        +
        +	if (ret == NULL)
        +		ret = bn = BN_new();
        +	if (ret == NULL) return(NULL);
        +	bn_check_top(ret);
        +	l=0;
        +	n=len;
        +	if (n == 0)
        +		{
        +		ret->top=0;
        +		return(ret);
        +		}
        +	i=((n-1)/BN_BYTES)+1;
        +	m=((n-1)%(BN_BYTES));
        +	if (bn_wexpand(ret, (int)i) == NULL)
        +		{
        +		if (bn) BN_free(bn);
        +		return NULL;
        +		}
        +	ret->top=i;
        +	ret->neg=0;
        +	while (n--)
        +		{
        +		l=(l<<8L)| *(s++);
        +		if (m-- == 0)
        +			{
        +			ret->d[--i]=l;
        +			l=0;
        +			m=BN_BYTES-1;
        +			}
        +		}
        +	/* need to call this due to clear byte at top if avoiding
        +	 * having the top bit set (-ve number) */
        +	bn_correct_top(ret);
        +	return(ret);
        +	}
        +
        +/* ignore negative */
        +int BN_bn2bin(const BIGNUM *a, unsigned char *to)
        +	{
        +	int n,i;
        +	BN_ULONG l;
        +
        +	bn_check_top(a);
        +	n=i=BN_num_bytes(a);
        +	while (i--)
        +		{
        +		l=a->d[i/BN_BYTES];
        +		*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
        +		}
        +	return(n);
        +	}
        +
        +int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
        +	{
        +	int i;
        +	BN_ULONG t1,t2,*ap,*bp;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	i=a->top-b->top;
        +	if (i != 0) return(i);
        +	ap=a->d;
        +	bp=b->d;
        +	for (i=a->top-1; i>=0; i--)
        +		{
        +		t1= ap[i];
        +		t2= bp[i];
        +		if (t1 != t2)
        +			return((t1 > t2) ? 1 : -1);
        +		}
        +	return(0);
        +	}
        +
        +int BN_cmp(const BIGNUM *a, const BIGNUM *b)
        +	{
        +	int i;
        +	int gt,lt;
        +	BN_ULONG t1,t2;
        +
        +	if ((a == NULL) || (b == NULL))
        +		{
        +		if (a != NULL)
        +			return(-1);
        +		else if (b != NULL)
        +			return(1);
        +		else
        +			return(0);
        +		}
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +
        +	if (a->neg != b->neg)
        +		{
        +		if (a->neg)
        +			return(-1);
        +		else	return(1);
        +		}
        +	if (a->neg == 0)
        +		{ gt=1; lt= -1; }
        +	else	{ gt= -1; lt=1; }
        +
        +	if (a->top > b->top) return(gt);
        +	if (a->top < b->top) return(lt);
        +	for (i=a->top-1; i>=0; i--)
        +		{
        +		t1=a->d[i];
        +		t2=b->d[i];
        +		if (t1 > t2) return(gt);
        +		if (t1 < t2) return(lt);
        +		}
        +	return(0);
        +	}
        +
        +int BN_set_bit(BIGNUM *a, int n)
        +	{
        +	int i,j,k;
        +
        +	if (n < 0)
        +		return 0;
        +
        +	i=n/BN_BITS2;
        +	j=n%BN_BITS2;
        +	if (a->top <= i)
        +		{
        +		if (bn_wexpand(a,i+1) == NULL) return(0);
        +		for(k=a->top; k<i+1; k++)
        +			a->d[k]=0;
        +		a->top=i+1;
        +		}
        +
        +	a->d[i]|=(((BN_ULONG)1)<<j);
        +	bn_check_top(a);
        +	return(1);
        +	}
        +
        +int BN_clear_bit(BIGNUM *a, int n)
        +	{
        +	int i,j;
        +
        +	bn_check_top(a);
        +	if (n < 0) return 0;
        +
        +	i=n/BN_BITS2;
        +	j=n%BN_BITS2;
        +	if (a->top <= i) return(0);
        +
        +	a->d[i]&=(~(((BN_ULONG)1)<<j));
        +	bn_correct_top(a);
        +	return(1);
        +	}
        +
        +int BN_is_bit_set(const BIGNUM *a, int n)
        +	{
        +	int i,j;
        +
        +	bn_check_top(a);
        +	if (n < 0) return 0;
        +	i=n/BN_BITS2;
        +	j=n%BN_BITS2;
        +	if (a->top <= i) return 0;
        +	return (int)(((a->d[i])>>j)&((BN_ULONG)1));
        +	}
        +
        +int BN_mask_bits(BIGNUM *a, int n)
        +	{
        +	int b,w;
        +
        +	bn_check_top(a);
        +	if (n < 0) return 0;
        +
        +	w=n/BN_BITS2;
        +	b=n%BN_BITS2;
        +	if (w >= a->top) return 0;
        +	if (b == 0)
        +		a->top=w;
        +	else
        +		{
        +		a->top=w+1;
        +		a->d[w]&= ~(BN_MASK2<<b);
        +		}
        +	bn_correct_top(a);
        +	return(1);
        +	}
        +
        +void BN_set_negative(BIGNUM *a, int b)
        +	{
        +	if (b && !BN_is_zero(a))
        +		a->neg = 1;
        +	else
        +		a->neg = 0;
        +	}
        +
        +int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
        +	{
        +	int i;
        +	BN_ULONG aa,bb;
        +
        +	aa=a[n-1];
        +	bb=b[n-1];
        +	if (aa != bb) return((aa > bb)?1:-1);
        +	for (i=n-2; i>=0; i--)
        +		{
        +		aa=a[i];
        +		bb=b[i];
        +		if (aa != bb) return((aa > bb)?1:-1);
        +		}
        +	return(0);
        +	}
        +
        +/* Here follows a specialised variants of bn_cmp_words().  It has the
        +   property of performing the operation on arrays of different sizes.
        +   The sizes of those arrays is expressed through cl, which is the
        +   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
        +   delta between the two lengths, calculated as len(a)-len(b).
        +   All lengths are the number of BN_ULONGs...  */
        +
        +int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
        +	int cl, int dl)
        +	{
        +	int n,i;
        +	n = cl-1;
        +
        +	if (dl < 0)
        +		{
        +		for (i=dl; i<0; i++)
        +			{
        +			if (b[n-i] != 0)
        +				return -1; /* a < b */
        +			}
        +		}
        +	if (dl > 0)
        +		{
        +		for (i=dl; i>0; i--)
        +			{
        +			if (a[n+i] != 0)
        +				return 1; /* a > b */
        +			}
        +		}
        +	return bn_cmp_words(a,b,cl);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_mod.c b/vendor/openssl/openssl/crypto/bn/bn_mod.c
        new file mode 100644
        index 000000000..77d6ddb91
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_mod.c
        @@ -0,0 +1,301 @@
        +/* crypto/bn/bn_mod.c */
        +/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
        + * for the OpenSSL project. */
        +/* ====================================================================
        + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +
        +#if 0 /* now just a #define */
        +int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
        +	{
        +	return(BN_div(NULL,rem,m,d,ctx));
        +	/* note that  rem->neg == m->neg  (unless the remainder is zero) */
        +	}
        +#endif
        +
        +
        +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
        +	{
        +	/* like BN_mod, but returns non-negative remainder
        +	 * (i.e.,  0 <= r < |d|  always holds) */
        +
        +	if (!(BN_mod(r,m,d,ctx)))
        +		return 0;
        +	if (!r->neg)
        +		return 1;
        +	/* now   -|d| < r < 0,  so we have to set  r := r + |d| */
        +	return (d->neg ? BN_sub : BN_add)(r, r, d);
        +}
        +
        +
        +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	if (!BN_add(r, a, b)) return 0;
        +	return BN_nnmod(r, r, m, ctx);
        +	}
        +
        +
        +/* BN_mod_add variant that may be used if both  a  and  b  are non-negative
        + * and less than  m */
        +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
        +	{
        +	if (!BN_uadd(r, a, b)) return 0;
        +	if (BN_ucmp(r, m) >= 0)
        +		return BN_usub(r, r, m);
        +	return 1;
        +	}
        +
        +
        +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	if (!BN_sub(r, a, b)) return 0;
        +	return BN_nnmod(r, r, m, ctx);
        +	}
        +
        +
        +/* BN_mod_sub variant that may be used if both  a  and  b  are non-negative
        + * and less than  m */
        +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
        +	{
        +	if (!BN_sub(r, a, b)) return 0;
        +	if (r->neg)
        +		return BN_add(r, r, m);
        +	return 1;
        +	}
        +
        +
        +/* slow but works */
        +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
        +	BN_CTX *ctx)
        +	{
        +	BIGNUM *t;
        +	int ret=0;
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +	bn_check_top(m);
        +
        +	BN_CTX_start(ctx);
        +	if ((t = BN_CTX_get(ctx)) == NULL) goto err;
        +	if (a == b)
        +		{ if (!BN_sqr(t,a,ctx)) goto err; }
        +	else
        +		{ if (!BN_mul(t,a,b,ctx)) goto err; }
        +	if (!BN_nnmod(r,t,m,ctx)) goto err;
        +	bn_check_top(r);
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +
        +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	if (!BN_sqr(r, a, ctx)) return 0;
        +	/* r->neg == 0,  thus we don't need BN_nnmod */
        +	return BN_mod(r, r, m, ctx);
        +	}
        +
        +
        +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	if (!BN_lshift1(r, a)) return 0;
        +	bn_check_top(r);
        +	return BN_nnmod(r, r, m, ctx);
        +	}
        +
        +
        +/* BN_mod_lshift1 variant that may be used if  a  is non-negative
        + * and less than  m */
        +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
        +	{
        +	if (!BN_lshift1(r, a)) return 0;
        +	bn_check_top(r);
        +	if (BN_cmp(r, m) >= 0)
        +		return BN_sub(r, r, m);
        +	return 1;
        +	}
        +
        +
        +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	BIGNUM *abs_m = NULL;
        +	int ret;
        +
        +	if (!BN_nnmod(r, a, m, ctx)) return 0;
        +
        +	if (m->neg)
        +		{
        +		abs_m = BN_dup(m);
        +		if (abs_m == NULL) return 0;
        +		abs_m->neg = 0;
        +		}
        +	
        +	ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
        +	bn_check_top(r);
        +
        +	if (abs_m)
        +		BN_free(abs_m);
        +	return ret;
        +	}
        +
        +
        +/* BN_mod_lshift variant that may be used if  a  is non-negative
        + * and less than  m */
        +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
        +	{
        +	if (r != a)
        +		{
        +		if (BN_copy(r, a) == NULL) return 0;
        +		}
        +
        +	while (n > 0)
        +		{
        +		int max_shift;
        +		
        +		/* 0 < r < m */
        +		max_shift = BN_num_bits(m) - BN_num_bits(r);
        +		/* max_shift >= 0 */
        +
        +		if (max_shift < 0)
        +			{
        +			BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
        +			return 0;
        +			}
        +
        +		if (max_shift > n)
        +			max_shift = n;
        +
        +		if (max_shift)
        +			{
        +			if (!BN_lshift(r, r, max_shift)) return 0;
        +			n -= max_shift;
        +			}
        +		else
        +			{
        +			if (!BN_lshift1(r, r)) return 0;
        +			--n;
        +			}
        +
        +		/* BN_num_bits(r) <= BN_num_bits(m) */
        +
        +		if (BN_cmp(r, m) >= 0) 
        +			{
        +			if (!BN_sub(r, r, m)) return 0;
        +			}
        +		}
        +	bn_check_top(r);
        +	
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_mont.c b/vendor/openssl/openssl/crypto/bn/bn_mont.c
        new file mode 100644
        index 000000000..427b5cf4d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_mont.c
        @@ -0,0 +1,509 @@
        +/* crypto/bn/bn_mont.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 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).
        + *
        + */
        +
        +/*
        + * Details about Montgomery multiplication algorithms can be found at
        + * http://security.ece.orst.edu/publications.html, e.g.
        + * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
        + * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +#define MONT_WORD /* use the faster word-based algorithm */
        +
        +#ifdef MONT_WORD
        +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
        +#endif
        +
        +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        +			  BN_MONT_CTX *mont, BN_CTX *ctx)
        +	{
        +	BIGNUM *tmp;
        +	int ret=0;
        +#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
        +	int num = mont->N.top;
        +
        +	if (num>1 && a->top==num && b->top==num)
        +		{
        +		if (bn_wexpand(r,num) == NULL) return(0);
        +		if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
        +			{
        +			r->neg = a->neg^b->neg;
        +			r->top = num;
        +			bn_correct_top(r);
        +			return(1);
        +			}
        +		}
        +#endif
        +
        +	BN_CTX_start(ctx);
        +	tmp = BN_CTX_get(ctx);
        +	if (tmp == NULL) goto err;
        +
        +	bn_check_top(tmp);
        +	if (a == b)
        +		{
        +		if (!BN_sqr(tmp,a,ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mul(tmp,a,b,ctx)) goto err;
        +		}
        +	/* reduce from aRR to aR */
        +#ifdef MONT_WORD
        +	if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
        +#else
        +	if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
        +#endif
        +	bn_check_top(r);
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +#ifdef MONT_WORD
        +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
        +	{
        +	BIGNUM *n;
        +	BN_ULONG *ap,*np,*rp,n0,v,carry;
        +	int nl,max,i;
        +
        +	n= &(mont->N);
        +	nl=n->top;
        +	if (nl == 0) { ret->top=0; return(1); }
        +
        +	max=(2*nl); /* carry is stored separately */
        +	if (bn_wexpand(r,max) == NULL) return(0);
        +
        +	r->neg^=n->neg;
        +	np=n->d;
        +	rp=r->d;
        +
        +	/* clear the top words of T */
        +#if 1
        +	for (i=r->top; i<max; i++) /* memset? XXX */
        +		rp[i]=0;
        +#else
        +	memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
        +#endif
        +
        +	r->top=max;
        +	n0=mont->n0[0];
        +
        +#ifdef BN_COUNT
        +	fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
        +#endif
        +	for (carry=0, i=0; i<nl; i++, rp++)
        +		{
        +#ifdef __TANDEM
        +                {
        +                   long long t1;
        +                   long long t2;
        +                   long long t3;
        +                   t1 = rp[0] * (n0 & 0177777);
        +                   t2 = 037777600000l;
        +                   t2 = n0 & t2;
        +                   t3 = rp[0] & 0177777;
        +                   t2 = (t3 * t2) & BN_MASK2;
        +                   t1 = t1 + t2;
        +                   v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
        +                }
        +#else
        +		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
        +#endif
        +		v = (v+carry+rp[nl])&BN_MASK2;
        +		carry |= (v != rp[nl]);
        +		carry &= (v <= rp[nl]);
        +		rp[nl]=v;
        +		}
        +
        +	if (bn_wexpand(ret,nl) == NULL) return(0);
        +	ret->top=nl;
        +	ret->neg=r->neg;
        +
        +	rp=ret->d;
        +	ap=&(r->d[nl]);
        +
        +#define BRANCH_FREE 1
        +#if BRANCH_FREE
        +	{
        +	BN_ULONG *nrp;
        +	size_t m;
        +
        +	v=bn_sub_words(rp,ap,np,nl)-carry;
        +	/* if subtraction result is real, then
        +	 * trick unconditional memcpy below to perform in-place
        +	 * "refresh" instead of actual copy. */
        +	m=(0-(size_t)v);
        +	nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m)|((PTR_SIZE_INT)ap&m));
        +
        +	for (i=0,nl-=4; i<nl; i+=4)
        +		{
        +		BN_ULONG t1,t2,t3,t4;
        +		
        +		t1=nrp[i+0];
        +		t2=nrp[i+1];
        +		t3=nrp[i+2];	ap[i+0]=0;
        +		t4=nrp[i+3];	ap[i+1]=0;
        +		rp[i+0]=t1;	ap[i+2]=0;
        +		rp[i+1]=t2;	ap[i+3]=0;
        +		rp[i+2]=t3;
        +		rp[i+3]=t4;
        +		}
        +	for (nl+=4; i<nl; i++)
        +		rp[i]=nrp[i], ap[i]=0;
        +	}
        +#else
        +	if (bn_sub_words (rp,ap,np,nl)-carry)
        +		memcpy(rp,ap,nl*sizeof(BN_ULONG));
        +#endif
        +	bn_correct_top(r);
        +	bn_correct_top(ret);
        +	bn_check_top(ret);
        +
        +	return(1);
        +	}
        +#endif	/* MONT_WORD */
        +
        +int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
        +	     BN_CTX *ctx)
        +	{
        +	int retn=0;
        +#ifdef MONT_WORD
        +	BIGNUM *t;
        +
        +	BN_CTX_start(ctx);
        +	if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
        +		retn = BN_from_montgomery_word(ret,t,mont);
        +	BN_CTX_end(ctx);
        +#else /* !MONT_WORD */
        +	BIGNUM *t1,*t2;
        +
        +	BN_CTX_start(ctx);
        +	t1 = BN_CTX_get(ctx);
        +	t2 = BN_CTX_get(ctx);
        +	if (t1 == NULL || t2 == NULL) goto err;
        +	
        +	if (!BN_copy(t1,a)) goto err;
        +	BN_mask_bits(t1,mont->ri);
        +
        +	if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
        +	BN_mask_bits(t2,mont->ri);
        +
        +	if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
        +	if (!BN_add(t2,a,t1)) goto err;
        +	if (!BN_rshift(ret,t2,mont->ri)) goto err;
        +
        +	if (BN_ucmp(ret, &(mont->N)) >= 0)
        +		{
        +		if (!BN_usub(ret,ret,&(mont->N))) goto err;
        +		}
        +	retn=1;
        +	bn_check_top(ret);
        + err:
        +	BN_CTX_end(ctx);
        +#endif /* MONT_WORD */
        +	return(retn);
        +	}
        +
        +BN_MONT_CTX *BN_MONT_CTX_new(void)
        +	{
        +	BN_MONT_CTX *ret;
        +
        +	if ((ret=(BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
        +		return(NULL);
        +
        +	BN_MONT_CTX_init(ret);
        +	ret->flags=BN_FLG_MALLOCED;
        +	return(ret);
        +	}
        +
        +void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
        +	{
        +	ctx->ri=0;
        +	BN_init(&(ctx->RR));
        +	BN_init(&(ctx->N));
        +	BN_init(&(ctx->Ni));
        +	ctx->n0[0] = ctx->n0[1] = 0;
        +	ctx->flags=0;
        +	}
        +
        +void BN_MONT_CTX_free(BN_MONT_CTX *mont)
        +	{
        +	if(mont == NULL)
        +	    return;
        +
        +	BN_free(&(mont->RR));
        +	BN_free(&(mont->N));
        +	BN_free(&(mont->Ni));
        +	if (mont->flags & BN_FLG_MALLOCED)
        +		OPENSSL_free(mont);
        +	}
        +
        +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BIGNUM *Ri,*R;
        +
        +	BN_CTX_start(ctx);
        +	if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
        +	R= &(mont->RR);					/* grab RR as a temp */
        +	if (!BN_copy(&(mont->N),mod)) goto err;		/* Set N */
        +	mont->N.neg = 0;
        +
        +#ifdef MONT_WORD
        +		{
        +		BIGNUM tmod;
        +		BN_ULONG buf[2];
        +
        +		BN_init(&tmod);
        +		tmod.d=buf;
        +		tmod.dmax=2;
        +		tmod.neg=0;
        +
        +		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
        +
        +#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
        +		/* Only certain BN_BITS2<=32 platforms actually make use of
        +		 * n0[1], and we could use the #else case (with a shorter R
        +		 * value) for the others.  However, currently only the assembler
        +		 * files do know which is which. */
        +
        +		BN_zero(R);
        +		if (!(BN_set_bit(R,2*BN_BITS2))) goto err;
        +
        +								tmod.top=0;
        +		if ((buf[0] = mod->d[0]))			tmod.top=1;
        +		if ((buf[1] = mod->top>1 ? mod->d[1] : 0))	tmod.top=2;
        +
        +		if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
        +			goto err;
        +		if (!BN_lshift(Ri,Ri,2*BN_BITS2)) goto err; /* R*Ri */
        +		if (!BN_is_zero(Ri))
        +			{
        +			if (!BN_sub_word(Ri,1)) goto err;
        +			}
        +		else /* if N mod word size == 1 */
        +			{
        +			if (bn_expand(Ri,(int)sizeof(BN_ULONG)*2) == NULL)
        +				goto err;
        +			/* Ri-- (mod double word size) */
        +			Ri->neg=0;
        +			Ri->d[0]=BN_MASK2;
        +			Ri->d[1]=BN_MASK2;
        +			Ri->top=2;
        +			}
        +		if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
        +		/* Ni = (R*Ri-1)/N,
        +		 * keep only couple of least significant words: */
        +		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
        +		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
        +#else
        +		BN_zero(R);
        +		if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */
        +
        +		buf[0]=mod->d[0]; /* tmod = N mod word size */
        +		buf[1]=0;
        +		tmod.top = buf[0] != 0 ? 1 : 0;
        +							/* Ri = R^-1 mod N*/
        +		if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
        +			goto err;
        +		if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
        +		if (!BN_is_zero(Ri))
        +			{
        +			if (!BN_sub_word(Ri,1)) goto err;
        +			}
        +		else /* if N mod word size == 1 */
        +			{
        +			if (!BN_set_word(Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
        +			}
        +		if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
        +		/* Ni = (R*Ri-1)/N,
        +		 * keep only least significant word: */
        +		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
        +		mont->n0[1] = 0;
        +#endif
        +		}
        +#else /* !MONT_WORD */
        +		{ /* bignum version */
        +		mont->ri=BN_num_bits(&mont->N);
        +		BN_zero(R);
        +		if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
        +		                                        /* Ri = R^-1 mod N*/
        +		if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
        +			goto err;
        +		if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
        +		if (!BN_sub_word(Ri,1)) goto err;
        +							/* Ni = (R*Ri-1) / N */
        +		if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
        +		}
        +#endif
        +
        +	/* setup RR for conversions */
        +	BN_zero(&(mont->RR));
        +	if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
        +	if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
        +
        +	ret = 1;
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
        +	{
        +	if (to == from) return(to);
        +
        +	if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
        +	if (!BN_copy(&(to->N),&(from->N))) return NULL;
        +	if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
        +	to->ri=from->ri;
        +	to->n0[0]=from->n0[0];
        +	to->n0[1]=from->n0[1];
        +	return(to);
        +	}
        +
        +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
        +					const BIGNUM *mod, BN_CTX *ctx)
        +	{
        +	int got_write_lock = 0;
        +	BN_MONT_CTX *ret;
        +
        +	CRYPTO_r_lock(lock);
        +	if (!*pmont)
        +		{
        +		CRYPTO_r_unlock(lock);
        +		CRYPTO_w_lock(lock);
        +		got_write_lock = 1;
        +
        +		if (!*pmont)
        +			{
        +			ret = BN_MONT_CTX_new();
        +			if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
        +				BN_MONT_CTX_free(ret);
        +			else
        +				*pmont = ret;
        +			}
        +		}
        +	
        +	ret = *pmont;
        +	
        +	if (got_write_lock)
        +		CRYPTO_w_unlock(lock);
        +	else
        +		CRYPTO_r_unlock(lock);
        +		
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_mpi.c b/vendor/openssl/openssl/crypto/bn/bn_mpi.c
        new file mode 100644
        index 000000000..a054d21ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_mpi.c
        @@ -0,0 +1,130 @@
        +/* crypto/bn/bn_mpi.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
        +	{
        +	int bits;
        +	int num=0;
        +	int ext=0;
        +	long l;
        +
        +	bits=BN_num_bits(a);
        +	num=(bits+7)/8;
        +	if (bits > 0)
        +		{
        +		ext=((bits & 0x07) == 0);
        +		}
        +	if (d == NULL)
        +		return(num+4+ext);
        +
        +	l=num+ext;
        +	d[0]=(unsigned char)(l>>24)&0xff;
        +	d[1]=(unsigned char)(l>>16)&0xff;
        +	d[2]=(unsigned char)(l>> 8)&0xff;
        +	d[3]=(unsigned char)(l    )&0xff;
        +	if (ext) d[4]=0;
        +	num=BN_bn2bin(a,&(d[4+ext]));
        +	if (a->neg)
        +		d[4]|=0x80;
        +	return(num+4+ext);
        +	}
        +
        +BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
        +	{
        +	long len;
        +	int neg=0;
        +
        +	if (n < 4)
        +		{
        +		BNerr(BN_F_BN_MPI2BN,BN_R_INVALID_LENGTH);
        +		return(NULL);
        +		}
        +	len=((long)d[0]<<24)|((long)d[1]<<16)|((int)d[2]<<8)|(int)d[3];
        +	if ((len+4) != n)
        +		{
        +		BNerr(BN_F_BN_MPI2BN,BN_R_ENCODING_ERROR);
        +		return(NULL);
        +		}
        +
        +	if (a == NULL) a=BN_new();
        +	if (a == NULL) return(NULL);
        +
        +	if (len == 0)
        +		{
        +		a->neg=0;
        +		a->top=0;
        +		return(a);
        +		}
        +	d+=4;
        +	if ((*d) & 0x80)
        +		neg=1;
        +	if (BN_bin2bn(d,(int)len,a) == NULL)
        +		return(NULL);
        +	a->neg=neg;
        +	if (neg)
        +		{
        +		BN_clear_bit(a,BN_num_bits(a)-1);
        +		}
        +	bn_check_top(a);
        +	return(a);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_mul.c b/vendor/openssl/openssl/crypto/bn/bn_mul.c
        new file mode 100644
        index 000000000..12e5be80e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_mul.c
        @@ -0,0 +1,1166 @@
        +/* crypto/bn/bn_mul.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef BN_DEBUG
        +# undef NDEBUG /* avoid conflicting definitions */
        +# define NDEBUG
        +#endif
        +
        +#include <stdio.h>
        +#include <assert.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
        +/* Here follows specialised variants of bn_add_words() and
        +   bn_sub_words().  They have the property performing operations on
        +   arrays of different sizes.  The sizes of those arrays is expressed through
        +   cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
        +   which is the delta between the two lengths, calculated as len(a)-len(b).
        +   All lengths are the number of BN_ULONGs...  For the operations that require
        +   a result array as parameter, it must have the length cl+abs(dl).
        +   These functions should probably end up in bn_asm.c as soon as there are
        +   assembler counterparts for the systems that use assembler files.  */
        +
        +BN_ULONG bn_sub_part_words(BN_ULONG *r,
        +	const BN_ULONG *a, const BN_ULONG *b,
        +	int cl, int dl)
        +	{
        +	BN_ULONG c, t;
        +
        +	assert(cl >= 0);
        +	c = bn_sub_words(r, a, b, cl);
        +
        +	if (dl == 0)
        +		return c;
        +
        +	r += cl;
        +	a += cl;
        +	b += cl;
        +
        +	if (dl < 0)
        +		{
        +#ifdef BN_COUNT
        +		fprintf(stderr, "  bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
        +#endif
        +		for (;;)
        +			{
        +			t = b[0];
        +			r[0] = (0-t-c)&BN_MASK2;
        +			if (t != 0) c=1;
        +			if (++dl >= 0) break;
        +
        +			t = b[1];
        +			r[1] = (0-t-c)&BN_MASK2;
        +			if (t != 0) c=1;
        +			if (++dl >= 0) break;
        +
        +			t = b[2];
        +			r[2] = (0-t-c)&BN_MASK2;
        +			if (t != 0) c=1;
        +			if (++dl >= 0) break;
        +
        +			t = b[3];
        +			r[3] = (0-t-c)&BN_MASK2;
        +			if (t != 0) c=1;
        +			if (++dl >= 0) break;
        +
        +			b += 4;
        +			r += 4;
        +			}
        +		}
        +	else
        +		{
        +		int save_dl = dl;
        +#ifdef BN_COUNT
        +		fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c);
        +#endif
        +		while(c)
        +			{
        +			t = a[0];
        +			r[0] = (t-c)&BN_MASK2;
        +			if (t != 0) c=0;
        +			if (--dl <= 0) break;
        +
        +			t = a[1];
        +			r[1] = (t-c)&BN_MASK2;
        +			if (t != 0) c=0;
        +			if (--dl <= 0) break;
        +
        +			t = a[2];
        +			r[2] = (t-c)&BN_MASK2;
        +			if (t != 0) c=0;
        +			if (--dl <= 0) break;
        +
        +			t = a[3];
        +			r[3] = (t-c)&BN_MASK2;
        +			if (t != 0) c=0;
        +			if (--dl <= 0) break;
        +
        +			save_dl = dl;
        +			a += 4;
        +			r += 4;
        +			}
        +		if (dl > 0)
        +			{
        +#ifdef BN_COUNT
        +			fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
        +#endif
        +			if (save_dl > dl)
        +				{
        +				switch (save_dl - dl)
        +					{
        +				case 1:
        +					r[1] = a[1];
        +					if (--dl <= 0) break;
        +				case 2:
        +					r[2] = a[2];
        +					if (--dl <= 0) break;
        +				case 3:
        +					r[3] = a[3];
        +					if (--dl <= 0) break;
        +					}
        +				a += 4;
        +				r += 4;
        +				}
        +			}
        +		if (dl > 0)
        +			{
        +#ifdef BN_COUNT
        +			fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl);
        +#endif
        +			for(;;)
        +				{
        +				r[0] = a[0];
        +				if (--dl <= 0) break;
        +				r[1] = a[1];
        +				if (--dl <= 0) break;
        +				r[2] = a[2];
        +				if (--dl <= 0) break;
        +				r[3] = a[3];
        +				if (--dl <= 0) break;
        +
        +				a += 4;
        +				r += 4;
        +				}
        +			}
        +		}
        +	return c;
        +	}
        +#endif
        +
        +BN_ULONG bn_add_part_words(BN_ULONG *r,
        +	const BN_ULONG *a, const BN_ULONG *b,
        +	int cl, int dl)
        +	{
        +	BN_ULONG c, l, t;
        +
        +	assert(cl >= 0);
        +	c = bn_add_words(r, a, b, cl);
        +
        +	if (dl == 0)
        +		return c;
        +
        +	r += cl;
        +	a += cl;
        +	b += cl;
        +
        +	if (dl < 0)
        +		{
        +		int save_dl = dl;
        +#ifdef BN_COUNT
        +		fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
        +#endif
        +		while (c)
        +			{
        +			l=(c+b[0])&BN_MASK2;
        +			c=(l < c);
        +			r[0]=l;
        +			if (++dl >= 0) break;
        +
        +			l=(c+b[1])&BN_MASK2;
        +			c=(l < c);
        +			r[1]=l;
        +			if (++dl >= 0) break;
        +
        +			l=(c+b[2])&BN_MASK2;
        +			c=(l < c);
        +			r[2]=l;
        +			if (++dl >= 0) break;
        +
        +			l=(c+b[3])&BN_MASK2;
        +			c=(l < c);
        +			r[3]=l;
        +			if (++dl >= 0) break;
        +
        +			save_dl = dl;
        +			b+=4;
        +			r+=4;
        +			}
        +		if (dl < 0)
        +			{
        +#ifdef BN_COUNT
        +			fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl);
        +#endif
        +			if (save_dl < dl)
        +				{
        +				switch (dl - save_dl)
        +					{
        +				case 1:
        +					r[1] = b[1];
        +					if (++dl >= 0) break;
        +				case 2:
        +					r[2] = b[2];
        +					if (++dl >= 0) break;
        +				case 3:
        +					r[3] = b[3];
        +					if (++dl >= 0) break;
        +					}
        +				b += 4;
        +				r += 4;
        +				}
        +			}
        +		if (dl < 0)
        +			{
        +#ifdef BN_COUNT
        +			fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl);
        +#endif
        +			for(;;)
        +				{
        +				r[0] = b[0];
        +				if (++dl >= 0) break;
        +				r[1] = b[1];
        +				if (++dl >= 0) break;
        +				r[2] = b[2];
        +				if (++dl >= 0) break;
        +				r[3] = b[3];
        +				if (++dl >= 0) break;
        +
        +				b += 4;
        +				r += 4;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		int save_dl = dl;
        +#ifdef BN_COUNT
        +		fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
        +#endif
        +		while (c)
        +			{
        +			t=(a[0]+c)&BN_MASK2;
        +			c=(t < c);
        +			r[0]=t;
        +			if (--dl <= 0) break;
        +
        +			t=(a[1]+c)&BN_MASK2;
        +			c=(t < c);
        +			r[1]=t;
        +			if (--dl <= 0) break;
        +
        +			t=(a[2]+c)&BN_MASK2;
        +			c=(t < c);
        +			r[2]=t;
        +			if (--dl <= 0) break;
        +
        +			t=(a[3]+c)&BN_MASK2;
        +			c=(t < c);
        +			r[3]=t;
        +			if (--dl <= 0) break;
        +
        +			save_dl = dl;
        +			a+=4;
        +			r+=4;
        +			}
        +#ifdef BN_COUNT
        +		fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
        +#endif
        +		if (dl > 0)
        +			{
        +			if (save_dl > dl)
        +				{
        +				switch (save_dl - dl)
        +					{
        +				case 1:
        +					r[1] = a[1];
        +					if (--dl <= 0) break;
        +				case 2:
        +					r[2] = a[2];
        +					if (--dl <= 0) break;
        +				case 3:
        +					r[3] = a[3];
        +					if (--dl <= 0) break;
        +					}
        +				a += 4;
        +				r += 4;
        +				}
        +			}
        +		if (dl > 0)
        +			{
        +#ifdef BN_COUNT
        +			fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl);
        +#endif
        +			for(;;)
        +				{
        +				r[0] = a[0];
        +				if (--dl <= 0) break;
        +				r[1] = a[1];
        +				if (--dl <= 0) break;
        +				r[2] = a[2];
        +				if (--dl <= 0) break;
        +				r[3] = a[3];
        +				if (--dl <= 0) break;
        +
        +				a += 4;
        +				r += 4;
        +				}
        +			}
        +		}
        +	return c;
        +	}
        +
        +#ifdef BN_RECURSION
        +/* Karatsuba recursive multiplication algorithm
        + * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
        +
        +/* r is 2*n2 words in size,
        + * a and b are both n2 words in size.
        + * n2 must be a power of 2.
        + * We multiply and return the result.
        + * t must be 2*n2 words in size
        + * We calculate
        + * a[0]*b[0]
        + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
        + * a[1]*b[1]
        + */
        +/* dnX may not be positive, but n2/2+dnX has to be */
        +void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
        +	int dna, int dnb, BN_ULONG *t)
        +	{
        +	int n=n2/2,c1,c2;
        +	int tna=n+dna, tnb=n+dnb;
        +	unsigned int neg,zero;
        +	BN_ULONG ln,lo,*p;
        +
        +# ifdef BN_COUNT
        +	fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
        +# endif
        +# ifdef BN_MUL_COMBA
        +#  if 0
        +	if (n2 == 4)
        +		{
        +		bn_mul_comba4(r,a,b);
        +		return;
        +		}
        +#  endif
        +	/* Only call bn_mul_comba 8 if n2 == 8 and the
        +	 * two arrays are complete [steve]
        +	 */
        +	if (n2 == 8 && dna == 0 && dnb == 0)
        +		{
        +		bn_mul_comba8(r,a,b);
        +		return; 
        +		}
        +# endif /* BN_MUL_COMBA */
        +	/* Else do normal multiply */
        +	if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
        +		{
        +		bn_mul_normal(r,a,n2+dna,b,n2+dnb);
        +		if ((dna + dnb) < 0)
        +			memset(&r[2*n2 + dna + dnb], 0,
        +				sizeof(BN_ULONG) * -(dna + dnb));
        +		return;
        +		}
        +	/* r=(a[0]-a[1])*(b[1]-b[0]) */
        +	c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
        +	c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
        +	zero=neg=0;
        +	switch (c1*3+c2)
        +		{
        +	case -4:
        +		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
        +		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
        +		break;
        +	case -3:
        +		zero=1;
        +		break;
        +	case -2:
        +		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
        +		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
        +		neg=1;
        +		break;
        +	case -1:
        +	case 0:
        +	case 1:
        +		zero=1;
        +		break;
        +	case 2:
        +		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
        +		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
        +		neg=1;
        +		break;
        +	case 3:
        +		zero=1;
        +		break;
        +	case 4:
        +		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
        +		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
        +		break;
        +		}
        +
        +# ifdef BN_MUL_COMBA
        +	if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
        +					       extra args to do this well */
        +		{
        +		if (!zero)
        +			bn_mul_comba4(&(t[n2]),t,&(t[n]));
        +		else
        +			memset(&(t[n2]),0,8*sizeof(BN_ULONG));
        +		
        +		bn_mul_comba4(r,a,b);
        +		bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
        +		}
        +	else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
        +						    take extra args to do this
        +						    well */
        +		{
        +		if (!zero)
        +			bn_mul_comba8(&(t[n2]),t,&(t[n]));
        +		else
        +			memset(&(t[n2]),0,16*sizeof(BN_ULONG));
        +		
        +		bn_mul_comba8(r,a,b);
        +		bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
        +		}
        +	else
        +# endif /* BN_MUL_COMBA */
        +		{
        +		p= &(t[n2*2]);
        +		if (!zero)
        +			bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
        +		else
        +			memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
        +		bn_mul_recursive(r,a,b,n,0,0,p);
        +		bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
        +		}
        +
        +	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
        +	 * r[10] holds (a[0]*b[0])
        +	 * r[32] holds (b[1]*b[1])
        +	 */
        +
        +	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
        +
        +	if (neg) /* if t[32] is negative */
        +		{
        +		c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
        +		}
        +	else
        +		{
        +		/* Might have a carry */
        +		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
        +		}
        +
        +	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
        +	 * r[10] holds (a[0]*b[0])
        +	 * r[32] holds (b[1]*b[1])
        +	 * c1 holds the carry bits
        +	 */
        +	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
        +	if (c1)
        +		{
        +		p= &(r[n+n2]);
        +		lo= *p;
        +		ln=(lo+c1)&BN_MASK2;
        +		*p=ln;
        +
        +		/* The overflow will stop before we over write
        +		 * words we should not overwrite */
        +		if (ln < (BN_ULONG)c1)
        +			{
        +			do	{
        +				p++;
        +				lo= *p;
        +				ln=(lo+1)&BN_MASK2;
        +				*p=ln;
        +				} while (ln == 0);
        +			}
        +		}
        +	}
        +
        +/* n+tn is the word length
        + * t needs to be n*4 is size, as does r */
        +/* tnX may not be negative but less than n */
        +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
        +	     int tna, int tnb, BN_ULONG *t)
        +	{
        +	int i,j,n2=n*2;
        +	int c1,c2,neg;
        +	BN_ULONG ln,lo,*p;
        +
        +# ifdef BN_COUNT
        +	fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
        +		n, tna, n, tnb);
        +# endif
        +	if (n < 8)
        +		{
        +		bn_mul_normal(r,a,n+tna,b,n+tnb);
        +		return;
        +		}
        +
        +	/* r=(a[0]-a[1])*(b[1]-b[0]) */
        +	c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
        +	c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
        +	neg=0;
        +	switch (c1*3+c2)
        +		{
        +	case -4:
        +		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
        +		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
        +		break;
        +	case -3:
        +		/* break; */
        +	case -2:
        +		bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
        +		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
        +		neg=1;
        +		break;
        +	case -1:
        +	case 0:
        +	case 1:
        +		/* break; */
        +	case 2:
        +		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
        +		bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
        +		neg=1;
        +		break;
        +	case 3:
        +		/* break; */
        +	case 4:
        +		bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
        +		bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
        +		break;
        +		}
        +		/* The zero case isn't yet implemented here. The speedup
        +		   would probably be negligible. */
        +# if 0
        +	if (n == 4)
        +		{
        +		bn_mul_comba4(&(t[n2]),t,&(t[n]));
        +		bn_mul_comba4(r,a,b);
        +		bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
        +		memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
        +		}
        +	else
        +# endif
        +	if (n == 8)
        +		{
        +		bn_mul_comba8(&(t[n2]),t,&(t[n]));
        +		bn_mul_comba8(r,a,b);
        +		bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
        +		memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
        +		}
        +	else
        +		{
        +		p= &(t[n2*2]);
        +		bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
        +		bn_mul_recursive(r,a,b,n,0,0,p);
        +		i=n/2;
        +		/* If there is only a bottom half to the number,
        +		 * just do it */
        +		if (tna > tnb)
        +			j = tna - i;
        +		else
        +			j = tnb - i;
        +		if (j == 0)
        +			{
        +			bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
        +				i,tna-i,tnb-i,p);
        +			memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
        +			}
        +		else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
        +				{
        +				bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
        +					i,tna-i,tnb-i,p);
        +				memset(&(r[n2+tna+tnb]),0,
        +					sizeof(BN_ULONG)*(n2-tna-tnb));
        +				}
        +		else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
        +			{
        +			memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
        +			if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
        +				&& tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
        +				{
        +				bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
        +				}
        +			else
        +				{
        +				for (;;)
        +					{
        +					i/=2;
        +					/* these simplified conditions work
        +					 * exclusively because difference
        +					 * between tna and tnb is 1 or 0 */
        +					if (i < tna || i < tnb)
        +						{
        +						bn_mul_part_recursive(&(r[n2]),
        +							&(a[n]),&(b[n]),
        +							i,tna-i,tnb-i,p);
        +						break;
        +						}
        +					else if (i == tna || i == tnb)
        +						{
        +						bn_mul_recursive(&(r[n2]),
        +							&(a[n]),&(b[n]),
        +							i,tna-i,tnb-i,p);
        +						break;
        +						}
        +					}
        +				}
        +			}
        +		}
        +
        +	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
        +	 * r[10] holds (a[0]*b[0])
        +	 * r[32] holds (b[1]*b[1])
        +	 */
        +
        +	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
        +
        +	if (neg) /* if t[32] is negative */
        +		{
        +		c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
        +		}
        +	else
        +		{
        +		/* Might have a carry */
        +		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
        +		}
        +
        +	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
        +	 * r[10] holds (a[0]*b[0])
        +	 * r[32] holds (b[1]*b[1])
        +	 * c1 holds the carry bits
        +	 */
        +	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
        +	if (c1)
        +		{
        +		p= &(r[n+n2]);
        +		lo= *p;
        +		ln=(lo+c1)&BN_MASK2;
        +		*p=ln;
        +
        +		/* The overflow will stop before we over write
        +		 * words we should not overwrite */
        +		if (ln < (BN_ULONG)c1)
        +			{
        +			do	{
        +				p++;
        +				lo= *p;
        +				ln=(lo+1)&BN_MASK2;
        +				*p=ln;
        +				} while (ln == 0);
        +			}
        +		}
        +	}
        +
        +/* a and b must be the same size, which is n2.
        + * r needs to be n2 words and t needs to be n2*2
        + */
        +void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
        +	     BN_ULONG *t)
        +	{
        +	int n=n2/2;
        +
        +# ifdef BN_COUNT
        +	fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
        +# endif
        +
        +	bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
        +	if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
        +		{
        +		bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
        +		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
        +		bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
        +		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
        +		}
        +	else
        +		{
        +		bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
        +		bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
        +		bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
        +		bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
        +		}
        +	}
        +
        +/* a and b must be the same size, which is n2.
        + * r needs to be n2 words and t needs to be n2*2
        + * l is the low words of the output.
        + * t needs to be n2*3
        + */
        +void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
        +	     BN_ULONG *t)
        +	{
        +	int i,n;
        +	int c1,c2;
        +	int neg,oneg,zero;
        +	BN_ULONG ll,lc,*lp,*mp;
        +
        +# ifdef BN_COUNT
        +	fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
        +# endif
        +	n=n2/2;
        +
        +	/* Calculate (al-ah)*(bh-bl) */
        +	neg=zero=0;
        +	c1=bn_cmp_words(&(a[0]),&(a[n]),n);
        +	c2=bn_cmp_words(&(b[n]),&(b[0]),n);
        +	switch (c1*3+c2)
        +		{
        +	case -4:
        +		bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
        +		bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
        +		break;
        +	case -3:
        +		zero=1;
        +		break;
        +	case -2:
        +		bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
        +		bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
        +		neg=1;
        +		break;
        +	case -1:
        +	case 0:
        +	case 1:
        +		zero=1;
        +		break;
        +	case 2:
        +		bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
        +		bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
        +		neg=1;
        +		break;
        +	case 3:
        +		zero=1;
        +		break;
        +	case 4:
        +		bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
        +		bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
        +		break;
        +		}
        +		
        +	oneg=neg;
        +	/* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
        +	/* r[10] = (a[1]*b[1]) */
        +# ifdef BN_MUL_COMBA
        +	if (n == 8)
        +		{
        +		bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
        +		bn_mul_comba8(r,&(a[n]),&(b[n]));
        +		}
        +	else
        +# endif
        +		{
        +		bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
        +		bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
        +		}
        +
        +	/* s0 == low(al*bl)
        +	 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
        +	 * We know s0 and s1 so the only unknown is high(al*bl)
        +	 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
        +	 * high(al*bl) == s1 - (r[0]+l[0]+t[0])
        +	 */
        +	if (l != NULL)
        +		{
        +		lp= &(t[n2+n]);
        +		c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
        +		}
        +	else
        +		{
        +		c1=0;
        +		lp= &(r[0]);
        +		}
        +
        +	if (neg)
        +		neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
        +	else
        +		{
        +		bn_add_words(&(t[n2]),lp,&(t[0]),n);
        +		neg=0;
        +		}
        +
        +	if (l != NULL)
        +		{
        +		bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
        +		}
        +	else
        +		{
        +		lp= &(t[n2+n]);
        +		mp= &(t[n2]);
        +		for (i=0; i<n; i++)
        +			lp[i]=((~mp[i])+1)&BN_MASK2;
        +		}
        +
        +	/* s[0] = low(al*bl)
        +	 * t[3] = high(al*bl)
        +	 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
        +	 * r[10] = (a[1]*b[1])
        +	 */
        +	/* R[10] = al*bl
        +	 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
        +	 * R[32] = ah*bh
        +	 */
        +	/* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
        +	 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
        +	 * R[3]=r[1]+(carry/borrow)
        +	 */
        +	if (l != NULL)
        +		{
        +		lp= &(t[n2]);
        +		c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
        +		}
        +	else
        +		{
        +		lp= &(t[n2+n]);
        +		c1=0;
        +		}
        +	c1+=(int)(bn_add_words(&(t[n2]),lp,  &(r[0]),n));
        +	if (oneg)
        +		c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
        +	else
        +		c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
        +
        +	c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
        +	c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
        +	if (oneg)
        +		c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
        +	else
        +		c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
        +	
        +	if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
        +		{
        +		i=0;
        +		if (c1 > 0)
        +			{
        +			lc=c1;
        +			do	{
        +				ll=(r[i]+lc)&BN_MASK2;
        +				r[i++]=ll;
        +				lc=(lc > ll);
        +				} while (lc);
        +			}
        +		else
        +			{
        +			lc= -c1;
        +			do	{
        +				ll=r[i];
        +				r[i++]=(ll-lc)&BN_MASK2;
        +				lc=(lc > ll);
        +				} while (lc);
        +			}
        +		}
        +	if (c2 != 0) /* Add starting at r[1] */
        +		{
        +		i=n;
        +		if (c2 > 0)
        +			{
        +			lc=c2;
        +			do	{
        +				ll=(r[i]+lc)&BN_MASK2;
        +				r[i++]=ll;
        +				lc=(lc > ll);
        +				} while (lc);
        +			}
        +		else
        +			{
        +			lc= -c2;
        +			do	{
        +				ll=r[i];
        +				r[i++]=(ll-lc)&BN_MASK2;
        +				lc=(lc > ll);
        +				} while (lc);
        +			}
        +		}
        +	}
        +#endif /* BN_RECURSION */
        +
        +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret=0;
        +	int top,al,bl;
        +	BIGNUM *rr;
        +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
        +	int i;
        +#endif
        +#ifdef BN_RECURSION
        +	BIGNUM *t=NULL;
        +	int j=0,k;
        +#endif
        +
        +#ifdef BN_COUNT
        +	fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
        +#endif
        +
        +	bn_check_top(a);
        +	bn_check_top(b);
        +	bn_check_top(r);
        +
        +	al=a->top;
        +	bl=b->top;
        +
        +	if ((al == 0) || (bl == 0))
        +		{
        +		BN_zero(r);
        +		return(1);
        +		}
        +	top=al+bl;
        +
        +	BN_CTX_start(ctx);
        +	if ((r == a) || (r == b))
        +		{
        +		if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
        +		}
        +	else
        +		rr = r;
        +	rr->neg=a->neg^b->neg;
        +
        +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
        +	i = al-bl;
        +#endif
        +#ifdef BN_MUL_COMBA
        +	if (i == 0)
        +		{
        +# if 0
        +		if (al == 4)
        +			{
        +			if (bn_wexpand(rr,8) == NULL) goto err;
        +			rr->top=8;
        +			bn_mul_comba4(rr->d,a->d,b->d);
        +			goto end;
        +			}
        +# endif
        +		if (al == 8)
        +			{
        +			if (bn_wexpand(rr,16) == NULL) goto err;
        +			rr->top=16;
        +			bn_mul_comba8(rr->d,a->d,b->d);
        +			goto end;
        +			}
        +		}
        +#endif /* BN_MUL_COMBA */
        +#ifdef BN_RECURSION
        +	if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
        +		{
        +		if (i >= -1 && i <= 1)
        +			{
        +			/* Find out the power of two lower or equal
        +			   to the longest of the two numbers */
        +			if (i >= 0)
        +				{
        +				j = BN_num_bits_word((BN_ULONG)al);
        +				}
        +			if (i == -1)
        +				{
        +				j = BN_num_bits_word((BN_ULONG)bl);
        +				}
        +			j = 1<<(j-1);
        +			assert(j <= al || j <= bl);
        +			k = j+j;
        +			t = BN_CTX_get(ctx);
        +			if (t == NULL)
        +				goto err;
        +			if (al > j || bl > j)
        +				{
        +				if (bn_wexpand(t,k*4) == NULL) goto err;
        +				if (bn_wexpand(rr,k*4) == NULL) goto err;
        +				bn_mul_part_recursive(rr->d,a->d,b->d,
        +					j,al-j,bl-j,t->d);
        +				}
        +			else	/* al <= j || bl <= j */
        +				{
        +				if (bn_wexpand(t,k*2) == NULL) goto err;
        +				if (bn_wexpand(rr,k*2) == NULL) goto err;
        +				bn_mul_recursive(rr->d,a->d,b->d,
        +					j,al-j,bl-j,t->d);
        +				}
        +			rr->top=top;
        +			goto end;
        +			}
        +#if 0
        +		if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
        +			{
        +			BIGNUM *tmp_bn = (BIGNUM *)b;
        +			if (bn_wexpand(tmp_bn,al) == NULL) goto err;
        +			tmp_bn->d[bl]=0;
        +			bl++;
        +			i--;
        +			}
        +		else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
        +			{
        +			BIGNUM *tmp_bn = (BIGNUM *)a;
        +			if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
        +			tmp_bn->d[al]=0;
        +			al++;
        +			i++;
        +			}
        +		if (i == 0)
        +			{
        +			/* symmetric and > 4 */
        +			/* 16 or larger */
        +			j=BN_num_bits_word((BN_ULONG)al);
        +			j=1<<(j-1);
        +			k=j+j;
        +			t = BN_CTX_get(ctx);
        +			if (al == j) /* exact multiple */
        +				{
        +				if (bn_wexpand(t,k*2) == NULL) goto err;
        +				if (bn_wexpand(rr,k*2) == NULL) goto err;
        +				bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
        +				}
        +			else
        +				{
        +				if (bn_wexpand(t,k*4) == NULL) goto err;
        +				if (bn_wexpand(rr,k*4) == NULL) goto err;
        +				bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
        +				}
        +			rr->top=top;
        +			goto end;
        +			}
        +#endif
        +		}
        +#endif /* BN_RECURSION */
        +	if (bn_wexpand(rr,top) == NULL) goto err;
        +	rr->top=top;
        +	bn_mul_normal(rr->d,a->d,al,b->d,bl);
        +
        +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
        +end:
        +#endif
        +	bn_correct_top(rr);
        +	if (r != rr) BN_copy(r,rr);
        +	ret=1;
        +err:
        +	bn_check_top(r);
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
        +	{
        +	BN_ULONG *rr;
        +
        +#ifdef BN_COUNT
        +	fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
        +#endif
        +
        +	if (na < nb)
        +		{
        +		int itmp;
        +		BN_ULONG *ltmp;
        +
        +		itmp=na; na=nb; nb=itmp;
        +		ltmp=a;   a=b;   b=ltmp;
        +
        +		}
        +	rr= &(r[na]);
        +	if (nb <= 0)
        +		{
        +		(void)bn_mul_words(r,a,na,0);
        +		return;
        +		}
        +	else
        +		rr[0]=bn_mul_words(r,a,na,b[0]);
        +
        +	for (;;)
        +		{
        +		if (--nb <= 0) return;
        +		rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
        +		if (--nb <= 0) return;
        +		rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
        +		if (--nb <= 0) return;
        +		rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
        +		if (--nb <= 0) return;
        +		rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
        +		rr+=4;
        +		r+=4;
        +		b+=4;
        +		}
        +	}
        +
        +void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
        +	{
        +#ifdef BN_COUNT
        +	fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
        +#endif
        +	bn_mul_words(r,a,n,b[0]);
        +
        +	for (;;)
        +		{
        +		if (--n <= 0) return;
        +		bn_mul_add_words(&(r[1]),a,n,b[1]);
        +		if (--n <= 0) return;
        +		bn_mul_add_words(&(r[2]),a,n,b[2]);
        +		if (--n <= 0) return;
        +		bn_mul_add_words(&(r[3]),a,n,b[3]);
        +		if (--n <= 0) return;
        +		bn_mul_add_words(&(r[4]),a,n,b[4]);
        +		r+=4;
        +		b+=4;
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_nist.c b/vendor/openssl/openssl/crypto/bn/bn_nist.c
        new file mode 100644
        index 000000000..43caee477
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_nist.c
        @@ -0,0 +1,1102 @@
        +/* crypto/bn/bn_nist.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 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 "bn_lcl.h"
        +#include "cryptlib.h"
        +
        +
        +#define BN_NIST_192_TOP	(192+BN_BITS2-1)/BN_BITS2
        +#define BN_NIST_224_TOP	(224+BN_BITS2-1)/BN_BITS2
        +#define BN_NIST_256_TOP	(256+BN_BITS2-1)/BN_BITS2
        +#define BN_NIST_384_TOP	(384+BN_BITS2-1)/BN_BITS2
        +#define BN_NIST_521_TOP	(521+BN_BITS2-1)/BN_BITS2
        +
        +/* pre-computed tables are "carry-less" values of modulus*(i+1) */
        +#if BN_BITS2 == 64
        +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
        +	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL},
        +	{0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL},
        +	{0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFCULL,0xFFFFFFFFFFFFFFFFULL}
        +	};
        +static const BN_ULONG _nist_p_192_sqr[] = {
        +	0x0000000000000001ULL,0x0000000000000002ULL,0x0000000000000001ULL,
        +	0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL
        +	};
        +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
        +	{0x0000000000000001ULL,0xFFFFFFFF00000000ULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL},
        +	{0x0000000000000002ULL,0xFFFFFFFE00000000ULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFFULL} /* this one is "carry-full" */
        +	};
        +static const BN_ULONG _nist_p_224_sqr[] = {
        +	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
        +	0xFFFFFFFFFFFFFFFFULL,0x0000000200000000ULL,
        +	0x0000000000000000ULL,0xFFFFFFFFFFFFFFFEULL,
        +	0xFFFFFFFFFFFFFFFFULL
        +	};
        +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
        +	{0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL,
        +	 0x0000000000000000ULL,0xFFFFFFFF00000001ULL},
        +	{0xFFFFFFFFFFFFFFFEULL,0x00000001FFFFFFFFULL,
        +	 0x0000000000000000ULL,0xFFFFFFFE00000002ULL},
        +	{0xFFFFFFFFFFFFFFFDULL,0x00000002FFFFFFFFULL,
        +	 0x0000000000000000ULL,0xFFFFFFFD00000003ULL},
        +	{0xFFFFFFFFFFFFFFFCULL,0x00000003FFFFFFFFULL,
        +	 0x0000000000000000ULL,0xFFFFFFFC00000004ULL},
        +	{0xFFFFFFFFFFFFFFFBULL,0x00000004FFFFFFFFULL,
        +	 0x0000000000000000ULL,0xFFFFFFFB00000005ULL},
        +	};
        +static const BN_ULONG _nist_p_256_sqr[] = {
        +	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
        +	0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFEULL,
        +	0x00000001FFFFFFFEULL,0x00000001FFFFFFFEULL,
        +	0xFFFFFFFE00000001ULL,0xFFFFFFFE00000002ULL
        +	};
        +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
        +	{0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,0xFFFFFFFFFFFFFFFEULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
        +	{0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
        +	{0x00000002FFFFFFFDULL,0xFFFFFFFD00000000ULL,0xFFFFFFFFFFFFFFFCULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
        +	{0x00000003FFFFFFFCULL,0xFFFFFFFC00000000ULL,0xFFFFFFFFFFFFFFFBULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
        +	{0x00000004FFFFFFFBULL,0xFFFFFFFB00000000ULL,0xFFFFFFFFFFFFFFFAULL,
        +	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
        +	};
        +static const BN_ULONG _nist_p_384_sqr[] = {
        +	0xFFFFFFFE00000001ULL,0x0000000200000000ULL,0xFFFFFFFE00000000ULL,
        +	0x0000000200000000ULL,0x0000000000000001ULL,0x0000000000000000ULL,
        +	0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
        +	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL
        +	};
        +static const BN_ULONG _nist_p_521[] =
        +	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
        +	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
        +	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
        +	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
        +	0x00000000000001FFULL};
        +static const BN_ULONG _nist_p_521_sqr[] = {
        +	0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL,
        +	0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL,
        +	0x0000000000000000ULL,0x0000000000000000ULL,0xFFFFFFFFFFFFFC00ULL,
        +	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
        +	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
        +	0xFFFFFFFFFFFFFFFFULL,0x000000000003FFFFULL
        +	};
        +#elif BN_BITS2 == 32
        +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
        +	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
        +	};
        +static const BN_ULONG _nist_p_192_sqr[] = {
        +	0x00000001,0x00000000,0x00000002,0x00000000,0x00000001,0x00000000,
        +	0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
        +	};
        +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
        +	{0x00000001,0x00000000,0x00000000,0xFFFFFFFF,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0x00000002,0x00000000,0x00000000,0xFFFFFFFE,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
        +	};
        +static const BN_ULONG _nist_p_224_sqr[] = {
        +	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
        +	0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000002,
        +	0x00000000,0x00000000,0xFFFFFFFE,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF
        +	};
        +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
        +	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
        +	 0x00000000,0x00000000,0x00000001,0xFFFFFFFF},
        +	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000001,
        +	 0x00000000,0x00000000,0x00000002,0xFFFFFFFE},
        +	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0x00000002,
        +	 0x00000000,0x00000000,0x00000003,0xFFFFFFFD},
        +	{0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000003,
        +	 0x00000000,0x00000000,0x00000004,0xFFFFFFFC},
        +	{0xFFFFFFFB,0xFFFFFFFF,0xFFFFFFFF,0x00000004,
        +	 0x00000000,0x00000000,0x00000005,0xFFFFFFFB},
        +	};
        +static const BN_ULONG _nist_p_256_sqr[] = {
        +	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
        +	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000001,
        +	0xFFFFFFFE,0x00000001,0xFFFFFFFE,0x00000001,
        +	0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE
        +	};
        +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
        +	{0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0xFFFFFFFD,0x00000002,0x00000000,0xFFFFFFFD,0xFFFFFFFC,0xFFFFFFFF,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0xFFFFFFFC,0x00000003,0x00000000,0xFFFFFFFC,0xFFFFFFFB,0xFFFFFFFF,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	{0xFFFFFFFB,0x00000004,0x00000000,0xFFFFFFFB,0xFFFFFFFA,0xFFFFFFFF,
        +	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
        +	};
        +static const BN_ULONG _nist_p_384_sqr[] = {
        +	0x00000001,0xFFFFFFFE,0x00000000,0x00000002,0x00000000,0xFFFFFFFE,
        +	0x00000000,0x00000002,0x00000001,0x00000000,0x00000000,0x00000000,
        +	0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
        +	};
        +static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
        +	0xFFFFFFFF,0x000001FF};
        +static const BN_ULONG _nist_p_521_sqr[] = {
        +	0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
        +	0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
        +	0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFC00,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
        +	0xFFFFFFFF,0xFFFFFFFF,0x0003FFFF
        +	};
        +#else
        +#error "unsupported BN_BITS2"
        +#endif
        +
        +
        +static const BIGNUM _bignum_nist_p_192 =
        +	{
        +	(BN_ULONG *)_nist_p_192[0],
        +	BN_NIST_192_TOP,
        +	BN_NIST_192_TOP,
        +	0,
        +	BN_FLG_STATIC_DATA
        +	};
        +
        +static const BIGNUM _bignum_nist_p_224 =
        +	{
        +	(BN_ULONG *)_nist_p_224[0],
        +	BN_NIST_224_TOP,
        +	BN_NIST_224_TOP,
        +	0,
        +	BN_FLG_STATIC_DATA
        +	};
        +
        +static const BIGNUM _bignum_nist_p_256 =
        +	{
        +	(BN_ULONG *)_nist_p_256[0],
        +	BN_NIST_256_TOP,
        +	BN_NIST_256_TOP,
        +	0,
        +	BN_FLG_STATIC_DATA
        +	};
        +
        +static const BIGNUM _bignum_nist_p_384 =
        +	{
        +	(BN_ULONG *)_nist_p_384[0],
        +	BN_NIST_384_TOP,
        +	BN_NIST_384_TOP,
        +	0,
        +	BN_FLG_STATIC_DATA
        +	};
        +
        +static const BIGNUM _bignum_nist_p_521 =
        +	{
        +	(BN_ULONG *)_nist_p_521,
        +	BN_NIST_521_TOP,
        +	BN_NIST_521_TOP,
        +	0,
        +	BN_FLG_STATIC_DATA
        +	};
        +
        +
        +const BIGNUM *BN_get0_nist_prime_192(void)
        +	{
        +	return &_bignum_nist_p_192;
        +	}
        +
        +const BIGNUM *BN_get0_nist_prime_224(void)
        +	{
        +	return &_bignum_nist_p_224;
        +	}
        +
        +const BIGNUM *BN_get0_nist_prime_256(void)
        +	{
        +	return &_bignum_nist_p_256;
        +	}
        +
        +const BIGNUM *BN_get0_nist_prime_384(void)
        +	{
        +	return &_bignum_nist_p_384;
        +	}
        +
        +const BIGNUM *BN_get0_nist_prime_521(void)
        +	{
        +	return &_bignum_nist_p_521;
        +	}
        +
        +
        +static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max)
        +	{
        +	int i;
        +	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
        +
        +#ifdef BN_DEBUG
        +	OPENSSL_assert(top <= max);
        +#endif
        +	for (i = (top); i != 0; i--)
        +		*_tmp1++ = *_tmp2++;
        +	for (i = (max) - (top); i != 0; i--)
        +		*_tmp1++ = (BN_ULONG) 0;
        +	}
        +
        +static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
        +	{ 
        +	int i;
        +	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
        +	for (i = (top); i != 0; i--)
        +		*_tmp1++ = *_tmp2++;
        +	}
        +
        +#if BN_BITS2 == 64
        +#define bn_cp_64(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
        +#define bn_64_set_0(to, n)		(to)[n] = (BN_ULONG)0;
        +/*
        + * two following macros are implemented under assumption that they
        + * are called in a sequence with *ascending* n, i.e. as they are...
        + */
        +#define bn_cp_32_naked(to, n, from, m)	(((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
        +						:(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
        +#define bn_32_set_0(to, n)		(((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
        +#define bn_cp_32(to,n,from,m)		((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
        +# if defined(L_ENDIAN)
        +#  if defined(__arch64__)
        +#   define NIST_INT64 long
        +#  else
        +#   define NIST_INT64 long long
        +#  endif
        +# endif
        +#else
        +#define bn_cp_64(to, n, from, m) \
        +	{ \
        +	bn_cp_32(to, (n)*2, from, (m)*2); \
        +	bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
        +	}
        +#define bn_64_set_0(to, n) \
        +	{ \
        +	bn_32_set_0(to, (n)*2); \
        +	bn_32_set_0(to, (n)*2+1); \
        +	}
        +#define bn_cp_32(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
        +#define bn_32_set_0(to, n)		(to)[n] = (BN_ULONG)0;
        +# if defined(_WIN32) && !defined(__GNUC__)
        +#  define NIST_INT64 __int64
        +# elif defined(BN_LLONG)
        +#  define NIST_INT64 long long
        +# endif
        +#endif /* BN_BITS2 != 64 */
        +
        +#define nist_set_192(to, from, a1, a2, a3) \
        +	{ \
        +	bn_cp_64(to, 0, from, (a3) - 3) \
        +	bn_cp_64(to, 1, from, (a2) - 3) \
        +	bn_cp_64(to, 2, from, (a1) - 3) \
        +	}
        +
        +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        +	BN_CTX *ctx)
        +	{
        +	int      top = a->top, i;
        +	int      carry;
        +	register BN_ULONG *r_d, *a_d = a->d;
        +	union	{
        +		BN_ULONG	bn[BN_NIST_192_TOP];
        +		unsigned int	ui[BN_NIST_192_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
        +		} buf;
        +	BN_ULONG c_d[BN_NIST_192_TOP],
        +		*res;
        +	PTR_SIZE_INT mask;
        +	static const BIGNUM _bignum_nist_p_192_sqr = {
        +		(BN_ULONG *)_nist_p_192_sqr,
        +		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
        +		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
        +		0,BN_FLG_STATIC_DATA };
        +
        +	field = &_bignum_nist_p_192; /* just to make sure */
        +
        + 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_192_sqr)>=0)
        +		return BN_nnmod(r, a, field, ctx);
        +
        +	i = BN_ucmp(field, a);
        +	if (i == 0)
        +		{
        +		BN_zero(r);
        +		return 1;
        +		}
        +	else if (i > 0)
        +		return (r == a) ? 1 : (BN_copy(r ,a) != NULL);
        +
        +	if (r != a)
        +		{
        +		if (!bn_wexpand(r, BN_NIST_192_TOP))
        +			return 0;
        +		r_d = r->d;
        +		nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
        +		}
        +	else
        +		r_d = a_d;
        +
        +	nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
        +
        +#if defined(NIST_INT64)
        +	{
        +	NIST_INT64		acc;	/* accumulator */
        +	unsigned int		*rp=(unsigned int *)r_d;
        +	const unsigned int	*bp=(const unsigned int *)buf.ui;
        +
        +	acc  = rp[0];	acc += bp[3*2-6];
        +			acc += bp[5*2-6]; rp[0] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[1];	acc += bp[3*2-5];
        +			acc += bp[5*2-5]; rp[1] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[2];	acc += bp[3*2-6];
        +			acc += bp[4*2-6];
        +			acc += bp[5*2-6]; rp[2] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[3];	acc += bp[3*2-5];
        +			acc += bp[4*2-5];
        +			acc += bp[5*2-5]; rp[3] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[4];	acc += bp[4*2-6];
        +			acc += bp[5*2-6]; rp[4] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[5];	acc += bp[4*2-5];
        +			acc += bp[5*2-5]; rp[5] = (unsigned int)acc;
        +
        +	carry = (int)(acc>>32);
        +	}
        +#else
        +	{
        +	BN_ULONG t_d[BN_NIST_192_TOP];
        +
        +	nist_set_192(t_d, buf.bn, 0, 3, 3);
        +	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
        +	nist_set_192(t_d, buf.bn, 4, 4, 0);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
        +	nist_set_192(t_d, buf.bn, 5, 5, 5)
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
        +	}
        +#endif
        +	if (carry > 0)
        +		carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP);
        +	else
        +		carry = 1;
        +
        +	/*
        +	 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
        +	 * as comparison implies subtraction, we can write
        +	 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
        +	 * this is what happens below, but without explicit if:-) a.
        +	 */
        +	mask  = 0-(PTR_SIZE_INT)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP);
        +	mask &= 0-(PTR_SIZE_INT)carry;
        +	res   = (BN_ULONG *)
        +	 (((PTR_SIZE_INT)c_d&~mask) | ((PTR_SIZE_INT)r_d&mask));
        +	nist_cp_bn(r_d, res, BN_NIST_192_TOP);
        +	r->top = BN_NIST_192_TOP;
        +	bn_correct_top(r);
        +
        +	return 1;
        +	}
        +
        +typedef BN_ULONG (*bn_addsub_f)(BN_ULONG *,const BN_ULONG *,const BN_ULONG *,int);
        +
        +#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
        +	{ \
        +	bn_cp_32(to, 0, from, (a7) - 7) \
        +	bn_cp_32(to, 1, from, (a6) - 7) \
        +	bn_cp_32(to, 2, from, (a5) - 7) \
        +	bn_cp_32(to, 3, from, (a4) - 7) \
        +	bn_cp_32(to, 4, from, (a3) - 7) \
        +	bn_cp_32(to, 5, from, (a2) - 7) \
        +	bn_cp_32(to, 6, from, (a1) - 7) \
        +	}
        +
        +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        +	BN_CTX *ctx)
        +	{
        +	int	top = a->top, i;
        +	int	carry;
        +	BN_ULONG *r_d, *a_d = a->d;
        +	BN_ULONG buf[BN_NIST_224_TOP],
        +		 c_d[BN_NIST_224_TOP],
        +		*res;
        +	PTR_SIZE_INT mask;
        +	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
        +	static const BIGNUM _bignum_nist_p_224_sqr = {
        +		(BN_ULONG *)_nist_p_224_sqr,
        +		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
        +		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
        +		0,BN_FLG_STATIC_DATA };
        +
        +
        +	field = &_bignum_nist_p_224; /* just to make sure */
        +
        + 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_224_sqr)>=0)
        +		return BN_nnmod(r, a, field, ctx);
        +
        +	i = BN_ucmp(field, a);
        +	if (i == 0)
        +		{
        +		BN_zero(r);
        +		return 1;
        +		}
        +	else if (i > 0)
        +		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
        +
        +	if (r != a)
        +		{
        +		if (!bn_wexpand(r, BN_NIST_224_TOP))
        +			return 0;
        +		r_d = r->d;
        +		nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
        +		}
        +	else
        +		r_d = a_d;
        +
        +#if BN_BITS2==64
        +	/* copy upper 256 bits of 448 bit number ... */
        +	nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP);
        +	/* ... and right shift by 32 to obtain upper 224 bits */
        +	nist_set_224(buf, c_d, 14, 13, 12, 11, 10, 9, 8);
        +	/* truncate lower part to 224 bits too */
        +	r_d[BN_NIST_224_TOP-1] &= BN_MASK2l;
        +#else
        +	nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
        +#endif
        +
        +#if defined(NIST_INT64) && BN_BITS2!=64
        +	{
        +	NIST_INT64		acc;	/* accumulator */
        +	unsigned int		*rp=(unsigned int *)r_d;
        +	const unsigned int	*bp=(const unsigned int *)buf;
        +
        +	acc  = rp[0];	acc -= bp[7-7];
        +			acc -= bp[11-7]; rp[0] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[1];	acc -= bp[8-7];
        +			acc -= bp[12-7]; rp[1] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[2];	acc -= bp[9-7];
        +			acc -= bp[13-7]; rp[2] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[3];	acc += bp[7-7];
        +			acc += bp[11-7];
        +			acc -= bp[10-7]; rp[3] = (unsigned int)acc; acc>>= 32;
        +
        +	acc += rp[4];	acc += bp[8-7];
        +			acc += bp[12-7];
        +			acc -= bp[11-7]; rp[4] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[5];	acc += bp[9-7];
        +			acc += bp[13-7];
        +			acc -= bp[12-7]; rp[5] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[6];	acc += bp[10-7];
        +			acc -= bp[13-7]; rp[6] = (unsigned int)acc;
        +
        +	carry = (int)(acc>>32);
        +# if BN_BITS2==64
        +	rp[7] = carry;
        +# endif
        +	}	
        +#else
        +	{
        +	BN_ULONG t_d[BN_NIST_224_TOP];
        +
        +	nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
        +	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
        +	nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
        +	nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
        +	nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
        +
        +#if BN_BITS2==64
        +	carry = (int)(r_d[BN_NIST_224_TOP-1]>>32);
        +#endif
        +	}
        +#endif
        +	u.f = bn_sub_words;
        +	if (carry > 0)
        +		{
        +		carry = (int)bn_sub_words(r_d,r_d,_nist_p_224[carry-1],BN_NIST_224_TOP);
        +#if BN_BITS2==64
        +		carry=(int)(~(r_d[BN_NIST_224_TOP-1]>>32))&1;
        +#endif
        +		}
        +	else if (carry < 0)
        +		{
        +		/* it's a bit more comlicated logic in this case.
        +		 * if bn_add_words yields no carry, then result
        +		 * has to be adjusted by unconditionally *adding*
        +		 * the modulus. but if it does, then result has
        +		 * to be compared to the modulus and conditionally
        +		 * adjusted by *subtracting* the latter. */
        +		carry = (int)bn_add_words(r_d,r_d,_nist_p_224[-carry-1],BN_NIST_224_TOP);
        +		mask = 0-(PTR_SIZE_INT)carry;
        +		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
        +		 ((PTR_SIZE_INT)bn_add_words&~mask);
        +		}
        +	else
        +		carry = 1;
        +
        +	/* otherwise it's effectively same as in BN_nist_mod_192... */
        +	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP);
        +	mask &= 0-(PTR_SIZE_INT)carry;
        +	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
        +	 ((PTR_SIZE_INT)r_d&mask));
        +	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
        +	r->top = BN_NIST_224_TOP;
        +	bn_correct_top(r);
        +
        +	return 1;
        +	}
        +
        +#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
        +	{ \
        +	bn_cp_32(to, 0, from, (a8) - 8) \
        +	bn_cp_32(to, 1, from, (a7) - 8) \
        +	bn_cp_32(to, 2, from, (a6) - 8) \
        +	bn_cp_32(to, 3, from, (a5) - 8) \
        +	bn_cp_32(to, 4, from, (a4) - 8) \
        +	bn_cp_32(to, 5, from, (a3) - 8) \
        +	bn_cp_32(to, 6, from, (a2) - 8) \
        +	bn_cp_32(to, 7, from, (a1) - 8) \
        +	}
        +
        +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        +	BN_CTX *ctx)
        +	{
        +	int	i, top = a->top;
        +	int	carry = 0;
        +	register BN_ULONG *a_d = a->d, *r_d;
        +	union	{
        +		BN_ULONG bn[BN_NIST_256_TOP];
        +		unsigned int ui[BN_NIST_256_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
        +		} buf;
        +	BN_ULONG c_d[BN_NIST_256_TOP],
        +		*res;
        +	PTR_SIZE_INT mask;
        +	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
        +	static const BIGNUM _bignum_nist_p_256_sqr = {
        +		(BN_ULONG *)_nist_p_256_sqr,
        +		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
        +		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
        +		0,BN_FLG_STATIC_DATA };
        +
        +	field = &_bignum_nist_p_256; /* just to make sure */
        +
        + 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_256_sqr)>=0)
        +		return BN_nnmod(r, a, field, ctx);
        +
        +	i = BN_ucmp(field, a);
        +	if (i == 0)
        +		{
        +		BN_zero(r);
        +		return 1;
        +		}
        +	else if (i > 0)
        +		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
        +
        +	if (r != a)
        +		{
        +		if (!bn_wexpand(r, BN_NIST_256_TOP))
        +			return 0;
        +		r_d = r->d;
        +		nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
        +		}
        +	else
        +		r_d = a_d;
        +
        +	nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP);
        +
        +#if defined(NIST_INT64)
        +	{
        +	NIST_INT64		acc;	/* accumulator */
        +	unsigned int		*rp=(unsigned int *)r_d;
        +	const unsigned int	*bp=(const unsigned int *)buf.ui;
        +
        +	acc = rp[0];	acc += bp[8-8];
        +			acc += bp[9-8];
        +			acc -= bp[11-8];
        +			acc -= bp[12-8];
        +			acc -= bp[13-8];
        +			acc -= bp[14-8]; rp[0] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[1];	acc += bp[9-8];
        +			acc += bp[10-8];
        +			acc -= bp[12-8];
        +			acc -= bp[13-8];
        +			acc -= bp[14-8];
        +			acc -= bp[15-8]; rp[1] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[2];	acc += bp[10-8];
        +			acc += bp[11-8];
        +			acc -= bp[13-8];
        +			acc -= bp[14-8];
        +			acc -= bp[15-8]; rp[2] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[3];	acc += bp[11-8];
        +			acc += bp[11-8];
        +			acc += bp[12-8];
        +			acc += bp[12-8];
        +			acc += bp[13-8];
        +			acc -= bp[15-8];
        +			acc -= bp[8-8];
        +			acc -= bp[9-8];  rp[3] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[4];	acc += bp[12-8];
        +			acc += bp[12-8];
        +			acc += bp[13-8];
        +			acc += bp[13-8];
        +			acc += bp[14-8];
        +			acc -= bp[9-8];
        +			acc -= bp[10-8]; rp[4] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[5];	acc += bp[13-8];
        +			acc += bp[13-8];
        +			acc += bp[14-8];
        +			acc += bp[14-8];
        +			acc += bp[15-8];
        +			acc -= bp[10-8];
        +			acc -= bp[11-8]; rp[5] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[6];	acc += bp[14-8];
        +			acc += bp[14-8];
        +			acc += bp[15-8];
        +			acc += bp[15-8];
        +			acc += bp[14-8];
        +			acc += bp[13-8];
        +			acc -= bp[8-8];
        +			acc -= bp[9-8];  rp[6] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[7];	acc += bp[15-8];
        +			acc += bp[15-8];
        +			acc += bp[15-8];
        +			acc += bp[8 -8];
        +			acc -= bp[10-8];
        +			acc -= bp[11-8];
        +			acc -= bp[12-8];
        +			acc -= bp[13-8]; rp[7] = (unsigned int)acc;
        +
        +	carry = (int)(acc>>32);
        +	}
        +#else
        +	{
        +	BN_ULONG t_d[BN_NIST_256_TOP];
        +
        +	/*S1*/
        +	nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
        +	/*S2*/
        +	nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
        +	carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
        +	/* left shift */
        +		{
        +		register BN_ULONG *ap,t,c;
        +		ap = t_d;
        +		c=0;
        +		for (i = BN_NIST_256_TOP; i != 0; --i)
        +			{
        +			t= *ap;
        +			*(ap++)=((t<<1)|c)&BN_MASK2;
        +			c=(t & BN_TBIT)?1:0;
        +			}
        +		carry <<= 1;
        +		carry  |= c;
        +		}
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +	/*S3*/
        +	nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +	/*S4*/
        +	nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +	/*D1*/
        +	nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +	/*D2*/
        +	nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +	/*D3*/
        +	nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +	/*D4*/
        +	nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
        +
        +	}
        +#endif
        +	/* see BN_nist_mod_224 for explanation */
        +	u.f = bn_sub_words;
        +	if (carry > 0)
        +		carry = (int)bn_sub_words(r_d,r_d,_nist_p_256[carry-1],BN_NIST_256_TOP);
        +	else if (carry < 0)
        +		{
        +		carry = (int)bn_add_words(r_d,r_d,_nist_p_256[-carry-1],BN_NIST_256_TOP);
        +		mask = 0-(PTR_SIZE_INT)carry;
        +		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
        +		 ((PTR_SIZE_INT)bn_add_words&~mask);
        +		}
        +	else
        +		carry = 1;
        +
        +	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP);
        +	mask &= 0-(PTR_SIZE_INT)carry;
        +	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
        +	 ((PTR_SIZE_INT)r_d&mask));
        +	nist_cp_bn(r_d, res, BN_NIST_256_TOP);
        +	r->top = BN_NIST_256_TOP;
        +	bn_correct_top(r);
        +
        +	return 1;
        +	}
        +
        +#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
        +	{ \
        +	bn_cp_32(to, 0, from,  (a12) - 12) \
        +	bn_cp_32(to, 1, from,  (a11) - 12) \
        +	bn_cp_32(to, 2, from,  (a10) - 12) \
        +	bn_cp_32(to, 3, from,  (a9) - 12)  \
        +	bn_cp_32(to, 4, from,  (a8) - 12)  \
        +	bn_cp_32(to, 5, from,  (a7) - 12)  \
        +	bn_cp_32(to, 6, from,  (a6) - 12)  \
        +	bn_cp_32(to, 7, from,  (a5) - 12)  \
        +	bn_cp_32(to, 8, from,  (a4) - 12)  \
        +	bn_cp_32(to, 9, from,  (a3) - 12)  \
        +	bn_cp_32(to, 10, from, (a2) - 12)  \
        +	bn_cp_32(to, 11, from, (a1) - 12)  \
        +	}
        +
        +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        +	BN_CTX *ctx)
        +	{
        +	int	i, top = a->top;
        +	int	carry = 0;
        +	register BN_ULONG *r_d, *a_d = a->d;
        +	union	{
        +		BN_ULONG bn[BN_NIST_384_TOP];
        +		unsigned int ui[BN_NIST_384_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
        +		} buf;
        +	BN_ULONG c_d[BN_NIST_384_TOP],
        +		*res;
        +	PTR_SIZE_INT mask;
        +	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
        +	static const BIGNUM _bignum_nist_p_384_sqr = {
        +		(BN_ULONG *)_nist_p_384_sqr,
        +		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
        +		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
        +		0,BN_FLG_STATIC_DATA };
        +
        +
        +	field = &_bignum_nist_p_384; /* just to make sure */
        +
        + 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_384_sqr)>=0)
        +		return BN_nnmod(r, a, field, ctx);
        +
        +	i = BN_ucmp(field, a);
        +	if (i == 0)
        +		{
        +		BN_zero(r);
        +		return 1;
        +		}
        +	else if (i > 0)
        +		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
        +
        +	if (r != a)
        +		{
        +		if (!bn_wexpand(r, BN_NIST_384_TOP))
        +			return 0;
        +		r_d = r->d;
        +		nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
        +		}
        +	else
        +		r_d = a_d;
        +
        +	nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP);
        +
        +#if defined(NIST_INT64)
        +	{
        +	NIST_INT64		acc;	/* accumulator */
        +	unsigned int		*rp=(unsigned int *)r_d;
        +	const unsigned int	*bp=(const unsigned int *)buf.ui;
        +
        +	acc = rp[0];	acc += bp[12-12];
        +			acc += bp[21-12];
        +			acc += bp[20-12];
        +			acc -= bp[23-12]; rp[0] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[1];	acc += bp[13-12];
        +			acc += bp[22-12];
        +			acc += bp[23-12];
        +			acc -= bp[12-12];
        +			acc -= bp[20-12]; rp[1] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[2];	acc += bp[14-12];
        +			acc += bp[23-12];
        +			acc -= bp[13-12];
        +			acc -= bp[21-12]; rp[2] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[3];	acc += bp[15-12];
        +			acc += bp[12-12];
        +			acc += bp[20-12];
        +			acc += bp[21-12];
        +			acc -= bp[14-12];
        +			acc -= bp[22-12];
        +			acc -= bp[23-12]; rp[3] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[4];	acc += bp[21-12];
        +			acc += bp[21-12];
        +			acc += bp[16-12];
        +			acc += bp[13-12];
        +			acc += bp[12-12];
        +			acc += bp[20-12];
        +			acc += bp[22-12];
        +			acc -= bp[15-12];
        +			acc -= bp[23-12];
        +			acc -= bp[23-12]; rp[4] = (unsigned int)acc; acc >>= 32;
        +
        +	acc += rp[5];	acc += bp[22-12];
        +			acc += bp[22-12];
        +			acc += bp[17-12];
        +			acc += bp[14-12];
        +			acc += bp[13-12];
        +			acc += bp[21-12];
        +			acc += bp[23-12];
        +			acc -= bp[16-12]; rp[5] = (unsigned int)acc; acc >>= 32;
        +			
        +	acc += rp[6];	acc += bp[23-12];
        +			acc += bp[23-12];
        +			acc += bp[18-12];
        +			acc += bp[15-12];
        +			acc += bp[14-12];
        +			acc += bp[22-12];
        +			acc -= bp[17-12]; rp[6] = (unsigned int)acc; acc >>= 32;
        +			
        +	acc += rp[7];	acc += bp[19-12];
        +			acc += bp[16-12];
        +			acc += bp[15-12];
        +			acc += bp[23-12];
        +			acc -= bp[18-12]; rp[7] = (unsigned int)acc; acc >>= 32;
        +			
        +	acc += rp[8];	acc += bp[20-12];
        +			acc += bp[17-12];
        +			acc += bp[16-12];
        +			acc -= bp[19-12]; rp[8] = (unsigned int)acc; acc >>= 32;
        +			
        +	acc += rp[9];	acc += bp[21-12];
        +			acc += bp[18-12];
        +			acc += bp[17-12];
        +			acc -= bp[20-12]; rp[9] = (unsigned int)acc; acc >>= 32;
        +			
        +	acc += rp[10];	acc += bp[22-12];
        +			acc += bp[19-12];
        +			acc += bp[18-12];
        +			acc -= bp[21-12]; rp[10] = (unsigned int)acc; acc >>= 32;
        +			
        +	acc += rp[11];	acc += bp[23-12];
        +			acc += bp[20-12];
        +			acc += bp[19-12];
        +			acc -= bp[22-12]; rp[11] = (unsigned int)acc;
        +
        +	carry = (int)(acc>>32);
        +	}
        +#else
        +	{
        +	BN_ULONG t_d[BN_NIST_384_TOP];
        +
        +	/*S1*/
        +	nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4);
        +		/* left shift */
        +		{
        +		register BN_ULONG *ap,t,c;
        +		ap = t_d;
        +		c=0;
        +		for (i = 3; i != 0; --i)
        +			{
        +			t= *ap;
        +			*(ap++)=((t<<1)|c)&BN_MASK2;
        +			c=(t & BN_TBIT)?1:0;
        +			}
        +		*ap=c;
        +		}
        +	carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), 
        +		t_d, BN_NIST_256_TOP);
        +	/*S2 */
        +	carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
        +	/*S3*/
        +	nist_set_384(t_d,buf.bn,20,19,18,17,16,15,14,13,12,23,22,21);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +	/*S4*/
        +	nist_set_384(t_d,buf.bn,19,18,17,16,15,14,13,12,20,0,23,0);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +	/*S5*/
        +	nist_set_384(t_d, buf.bn,0,0,0,0,23,22,21,20,0,0,0,0);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +	/*S6*/
        +	nist_set_384(t_d,buf.bn,0,0,0,0,0,0,23,22,21,0,0,20);
        +	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +	/*D1*/
        +	nist_set_384(t_d,buf.bn,22,21,20,19,18,17,16,15,14,13,12,23);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +	/*D2*/
        +	nist_set_384(t_d,buf.bn,0,0,0,0,0,0,0,23,22,21,20,0);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +	/*D3*/
        +	nist_set_384(t_d,buf.bn,0,0,0,0,0,0,0,23,23,0,0,0);
        +	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
        +
        +	}
        +#endif
        +	/* see BN_nist_mod_224 for explanation */
        +	u.f = bn_sub_words;
        +	if (carry > 0)
        +		carry = (int)bn_sub_words(r_d,r_d,_nist_p_384[carry-1],BN_NIST_384_TOP);
        +	else if (carry < 0)
        +		{
        +		carry = (int)bn_add_words(r_d,r_d,_nist_p_384[-carry-1],BN_NIST_384_TOP);
        +		mask = 0-(PTR_SIZE_INT)carry;
        +		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
        +		 ((PTR_SIZE_INT)bn_add_words&~mask);
        +		}
        +	else
        +		carry = 1;
        +
        +	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP);
        +	mask &= 0-(PTR_SIZE_INT)carry;
        +	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
        +	 ((PTR_SIZE_INT)r_d&mask));
        +	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
        +	r->top = BN_NIST_384_TOP;
        +	bn_correct_top(r);
        +
        +	return 1;
        +	}
        +
        +#define BN_NIST_521_RSHIFT	(521%BN_BITS2)
        +#define BN_NIST_521_LSHIFT	(BN_BITS2-BN_NIST_521_RSHIFT)
        +#define BN_NIST_521_TOP_MASK	((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
        +
        +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        +	BN_CTX *ctx)
        +	{
        +	int	top = a->top, i;
        +	BN_ULONG *r_d, *a_d = a->d,
        +		 t_d[BN_NIST_521_TOP],
        +		 val,tmp,*res;
        +	PTR_SIZE_INT mask;
        +	static const BIGNUM _bignum_nist_p_521_sqr = {
        +		(BN_ULONG *)_nist_p_521_sqr,
        +		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
        +		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
        +		0,BN_FLG_STATIC_DATA };
        +
        +	field = &_bignum_nist_p_521; /* just to make sure */
        +
        + 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_521_sqr)>=0)
        +		return BN_nnmod(r, a, field, ctx);
        +
        +	i = BN_ucmp(field, a);
        +	if (i == 0)
        +		{
        +		BN_zero(r);
        +		return 1;
        +		}
        +	else if (i > 0)
        +		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
        +
        +	if (r != a)
        +		{
        +		if (!bn_wexpand(r,BN_NIST_521_TOP))
        +			return 0;
        +		r_d = r->d;
        +		nist_cp_bn(r_d,a_d, BN_NIST_521_TOP);
        +		}
        +	else
        +		r_d = a_d;
        +
        +	/* upper 521 bits, copy ... */
        +	nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP);
        +	/* ... and right shift */
        +	for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
        +		{
        +		tmp = val>>BN_NIST_521_RSHIFT;
        +		val = t_d[i+1];
        +		t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
        +		}
        +	t_d[i] = val>>BN_NIST_521_RSHIFT;
        +	/* lower 521 bits */
        +	r_d[i] &= BN_NIST_521_TOP_MASK;
        +
        +	bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP);
        +	mask = 0-(PTR_SIZE_INT)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP);
        +	res  = (BN_ULONG *)(((PTR_SIZE_INT)t_d&~mask) |
        +	 ((PTR_SIZE_INT)r_d&mask));
        +	nist_cp_bn(r_d,res,BN_NIST_521_TOP);
        +	r->top = BN_NIST_521_TOP;
        +	bn_correct_top(r);
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_prime.c b/vendor/openssl/openssl/crypto/bn/bn_prime.c
        new file mode 100644
        index 000000000..7b25979dd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_prime.c
        @@ -0,0 +1,494 @@
        +/* crypto/bn/bn_prime.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +#include <openssl/rand.h>
        +
        +/* NB: these functions have been "upgraded", the deprecated versions (which are
        + * compatibility wrappers using these functions) are in bn_depr.c.
        + * - Geoff
        + */
        +
        +/* The quick sieve algorithm approach to weeding out primes is
        + * Philip Zimmermann's, as implemented in PGP.  I have had a read of
        + * his comments and implemented my own version.
        + */
        +#include "bn_prime.h"
        +
        +static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
        +	const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
        +static int probable_prime(BIGNUM *rnd, int bits);
        +static int probable_prime_dh(BIGNUM *rnd, int bits,
        +	const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
        +static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
        +	const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
        +
        +int BN_GENCB_call(BN_GENCB *cb, int a, int b)
        +	{
        +	/* No callback means continue */
        +	if(!cb) return 1;
        +	switch(cb->ver)
        +		{
        +	case 1:
        +		/* Deprecated-style callbacks */
        +		if(!cb->cb.cb_1)
        +			return 1;
        +		cb->cb.cb_1(a, b, cb->arg);
        +		return 1;
        +	case 2:
        +		/* New-style callbacks */
        +		return cb->cb.cb_2(a, b, cb);
        +	default:
        +		break;
        +		}
        +	/* Unrecognised callback type */
        +	return 0;
        +	}
        +
        +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
        +	const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
        +	{
        +	BIGNUM *t;
        +	int found=0;
        +	int i,j,c1=0;
        +	BN_CTX *ctx;
        +	int checks = BN_prime_checks_for_size(bits);
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	t = BN_CTX_get(ctx);
        +	if(!t) goto err;
        +loop: 
        +	/* make a random number and set the top and bottom bits */
        +	if (add == NULL)
        +		{
        +		if (!probable_prime(ret,bits)) goto err;
        +		}
        +	else
        +		{
        +		if (safe)
        +			{
        +			if (!probable_prime_dh_safe(ret,bits,add,rem,ctx))
        +				 goto err;
        +			}
        +		else
        +			{
        +			if (!probable_prime_dh(ret,bits,add,rem,ctx))
        +				goto err;
        +			}
        +		}
        +	/* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
        +	if(!BN_GENCB_call(cb, 0, c1++))
        +		/* aborted */
        +		goto err;
        +
        +	if (!safe)
        +		{
        +		i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb);
        +		if (i == -1) goto err;
        +		if (i == 0) goto loop;
        +		}
        +	else
        +		{
        +		/* for "safe prime" generation,
        +		 * check that (p-1)/2 is prime.
        +		 * Since a prime is odd, We just
        +		 * need to divide by 2 */
        +		if (!BN_rshift1(t,ret)) goto err;
        +
        +		for (i=0; i<checks; i++)
        +			{
        +			j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb);
        +			if (j == -1) goto err;
        +			if (j == 0) goto loop;
        +
        +			j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb);
        +			if (j == -1) goto err;
        +			if (j == 0) goto loop;
        +
        +			if(!BN_GENCB_call(cb, 2, c1-1))
        +				goto err;
        +			/* We have a safe prime test pass */
        +			}
        +		}
        +	/* we have a prime :-) */
        +	found = 1;
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	bn_check_top(ret);
        +	return found;
        +	}
        +
        +int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
        +	{
        +	return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
        +	}
        +
        +int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
        +		int do_trial_division, BN_GENCB *cb)
        +	{
        +	int i, j, ret = -1;
        +	int k;
        +	BN_CTX *ctx = NULL;
        +	BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
        +	BN_MONT_CTX *mont = NULL;
        +	const BIGNUM *A = NULL;
        +
        +	if (BN_cmp(a, BN_value_one()) <= 0)
        +		return 0;
        +	
        +	if (checks == BN_prime_checks)
        +		checks = BN_prime_checks_for_size(BN_num_bits(a));
        +
        +	/* first look for small factors */
        +	if (!BN_is_odd(a))
        +		/* a is even => a is prime if and only if a == 2 */
        +		return BN_is_word(a, 2);
        +	if (do_trial_division)
        +		{
        +		for (i = 1; i < NUMPRIMES; i++)
        +			if (BN_mod_word(a, primes[i]) == 0) 
        +				return 0;
        +		if(!BN_GENCB_call(cb, 1, -1))
        +			goto err;
        +		}
        +
        +	if (ctx_passed != NULL)
        +		ctx = ctx_passed;
        +	else
        +		if ((ctx=BN_CTX_new()) == NULL)
        +			goto err;
        +	BN_CTX_start(ctx);
        +
        +	/* A := abs(a) */
        +	if (a->neg)
        +		{
        +		BIGNUM *t;
        +		if ((t = BN_CTX_get(ctx)) == NULL) goto err;
        +		BN_copy(t, a);
        +		t->neg = 0;
        +		A = t;
        +		}
        +	else
        +		A = a;
        +	A1 = BN_CTX_get(ctx);
        +	A1_odd = BN_CTX_get(ctx);
        +	check = BN_CTX_get(ctx);
        +	if (check == NULL) goto err;
        +
        +	/* compute A1 := A - 1 */
        +	if (!BN_copy(A1, A))
        +		goto err;
        +	if (!BN_sub_word(A1, 1))
        +		goto err;
        +	if (BN_is_zero(A1))
        +		{
        +		ret = 0;
        +		goto err;
        +		}
        +
        +	/* write  A1  as  A1_odd * 2^k */
        +	k = 1;
        +	while (!BN_is_bit_set(A1, k))
        +		k++;
        +	if (!BN_rshift(A1_odd, A1, k))
        +		goto err;
        +
        +	/* Montgomery setup for computations mod A */
        +	mont = BN_MONT_CTX_new();
        +	if (mont == NULL)
        +		goto err;
        +	if (!BN_MONT_CTX_set(mont, A, ctx))
        +		goto err;
        +	
        +	for (i = 0; i < checks; i++)
        +		{
        +		if (!BN_pseudo_rand_range(check, A1))
        +			goto err;
        +		if (!BN_add_word(check, 1))
        +			goto err;
        +		/* now 1 <= check < A */
        +
        +		j = witness(check, A, A1, A1_odd, k, ctx, mont);
        +		if (j == -1) goto err;
        +		if (j)
        +			{
        +			ret=0;
        +			goto err;
        +			}
        +		if(!BN_GENCB_call(cb, 1, i))
        +			goto err;
        +		}
        +	ret=1;
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		if (ctx_passed == NULL)
        +			BN_CTX_free(ctx);
        +		}
        +	if (mont != NULL)
        +		BN_MONT_CTX_free(mont);
        +
        +	return(ret);
        +	}
        +
        +static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
        +	const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
        +	{
        +	if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
        +		return -1;
        +	if (BN_is_one(w))
        +		return 0; /* probably prime */
        +	if (BN_cmp(w, a1) == 0)
        +		return 0; /* w == -1 (mod a),  'a' is probably prime */
        +	while (--k)
        +		{
        +		if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
        +			return -1;
        +		if (BN_is_one(w))
        +			return 1; /* 'a' is composite, otherwise a previous 'w' would
        +			           * have been == -1 (mod 'a') */
        +		if (BN_cmp(w, a1) == 0)
        +			return 0; /* w == -1 (mod a), 'a' is probably prime */
        +		}
        +	/* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
        +	 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
        +	bn_check_top(w);
        +	return 1;
        +	}
        +
        +static int probable_prime(BIGNUM *rnd, int bits)
        +	{
        +	int i;
        +	prime_t mods[NUMPRIMES];
        +	BN_ULONG delta,maxdelta;
        +
        +again:
        +	if (!BN_rand(rnd,bits,1,1)) return(0);
        +	/* we now have a random number 'rand' to test. */
        +	for (i=1; i<NUMPRIMES; i++)
        +		mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
        +	maxdelta=BN_MASK2 - primes[NUMPRIMES-1];
        +	delta=0;
        +	loop: for (i=1; i<NUMPRIMES; i++)
        +		{
        +		/* check that rnd is not a prime and also
        +		 * that gcd(rnd-1,primes) == 1 (except for 2) */
        +		if (((mods[i]+delta)%primes[i]) <= 1)
        +			{
        +			delta+=2;
        +			if (delta > maxdelta) goto again;
        +			goto loop;
        +			}
        +		}
        +	if (!BN_add_word(rnd,delta)) return(0);
        +	bn_check_top(rnd);
        +	return(1);
        +	}
        +
        +static int probable_prime_dh(BIGNUM *rnd, int bits,
        +	const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
        +	{
        +	int i,ret=0;
        +	BIGNUM *t1;
        +
        +	BN_CTX_start(ctx);
        +	if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
        +
        +	if (!BN_rand(rnd,bits,0,1)) goto err;
        +
        +	/* we need ((rnd-rem) % add) == 0 */
        +
        +	if (!BN_mod(t1,rnd,add,ctx)) goto err;
        +	if (!BN_sub(rnd,rnd,t1)) goto err;
        +	if (rem == NULL)
        +		{ if (!BN_add_word(rnd,1)) goto err; }
        +	else
        +		{ if (!BN_add(rnd,rnd,rem)) goto err; }
        +
        +	/* we now have a random number 'rand' to test. */
        +
        +	loop: for (i=1; i<NUMPRIMES; i++)
        +		{
        +		/* check that rnd is a prime */
        +		if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
        +			{
        +			if (!BN_add(rnd,rnd,add)) goto err;
        +			goto loop;
        +			}
        +		}
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	bn_check_top(rnd);
        +	return(ret);
        +	}
        +
        +static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
        +	const BIGNUM *rem, BN_CTX *ctx)
        +	{
        +	int i,ret=0;
        +	BIGNUM *t1,*qadd,*q;
        +
        +	bits--;
        +	BN_CTX_start(ctx);
        +	t1 = BN_CTX_get(ctx);
        +	q = BN_CTX_get(ctx);
        +	qadd = BN_CTX_get(ctx);
        +	if (qadd == NULL) goto err;
        +
        +	if (!BN_rshift1(qadd,padd)) goto err;
        +		
        +	if (!BN_rand(q,bits,0,1)) goto err;
        +
        +	/* we need ((rnd-rem) % add) == 0 */
        +	if (!BN_mod(t1,q,qadd,ctx)) goto err;
        +	if (!BN_sub(q,q,t1)) goto err;
        +	if (rem == NULL)
        +		{ if (!BN_add_word(q,1)) goto err; }
        +	else
        +		{
        +		if (!BN_rshift1(t1,rem)) goto err;
        +		if (!BN_add(q,q,t1)) goto err;
        +		}
        +
        +	/* we now have a random number 'rand' to test. */
        +	if (!BN_lshift1(p,q)) goto err;
        +	if (!BN_add_word(p,1)) goto err;
        +
        +	loop: for (i=1; i<NUMPRIMES; i++)
        +		{
        +		/* check that p and q are prime */
        +		/* check that for p and q
        +		 * gcd(p-1,primes) == 1 (except for 2) */
        +		if (	(BN_mod_word(p,(BN_ULONG)primes[i]) == 0) ||
        +			(BN_mod_word(q,(BN_ULONG)primes[i]) == 0))
        +			{
        +			if (!BN_add(p,p,padd)) goto err;
        +			if (!BN_add(q,q,qadd)) goto err;
        +			goto loop;
        +			}
        +		}
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	bn_check_top(p);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_prime.h b/vendor/openssl/openssl/crypto/bn/bn_prime.h
        new file mode 100644
        index 000000000..51d2194fe
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_prime.h
        @@ -0,0 +1,327 @@
        +/* Auto generated by bn_prime.pl */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef EIGHT_BIT
        +#define NUMPRIMES 2048
        +typedef unsigned short prime_t;
        +#else
        +#define NUMPRIMES 54
        +typedef unsigned char prime_t;
        +#endif
        +static const prime_t primes[NUMPRIMES]=
        +	{
        +	   2,   3,   5,   7,  11,  13,  17,  19,
        +	  23,  29,  31,  37,  41,  43,  47,  53,
        +	  59,  61,  67,  71,  73,  79,  83,  89,
        +	  97, 101, 103, 107, 109, 113, 127, 131,
        +	 137, 139, 149, 151, 157, 163, 167, 173,
        +	 179, 181, 191, 193, 197, 199, 211, 223,
        +	 227, 229, 233, 239, 241, 251,
        +#ifndef EIGHT_BIT
        +	 257, 263,
        +	 269, 271, 277, 281, 283, 293, 307, 311,
        +	 313, 317, 331, 337, 347, 349, 353, 359,
        +	 367, 373, 379, 383, 389, 397, 401, 409,
        +	 419, 421, 431, 433, 439, 443, 449, 457,
        +	 461, 463, 467, 479, 487, 491, 499, 503,
        +	 509, 521, 523, 541, 547, 557, 563, 569,
        +	 571, 577, 587, 593, 599, 601, 607, 613,
        +	 617, 619, 631, 641, 643, 647, 653, 659,
        +	 661, 673, 677, 683, 691, 701, 709, 719,
        +	 727, 733, 739, 743, 751, 757, 761, 769,
        +	 773, 787, 797, 809, 811, 821, 823, 827,
        +	 829, 839, 853, 857, 859, 863, 877, 881,
        +	 883, 887, 907, 911, 919, 929, 937, 941,
        +	 947, 953, 967, 971, 977, 983, 991, 997,
        +	1009,1013,1019,1021,1031,1033,1039,1049,
        +	1051,1061,1063,1069,1087,1091,1093,1097,
        +	1103,1109,1117,1123,1129,1151,1153,1163,
        +	1171,1181,1187,1193,1201,1213,1217,1223,
        +	1229,1231,1237,1249,1259,1277,1279,1283,
        +	1289,1291,1297,1301,1303,1307,1319,1321,
        +	1327,1361,1367,1373,1381,1399,1409,1423,
        +	1427,1429,1433,1439,1447,1451,1453,1459,
        +	1471,1481,1483,1487,1489,1493,1499,1511,
        +	1523,1531,1543,1549,1553,1559,1567,1571,
        +	1579,1583,1597,1601,1607,1609,1613,1619,
        +	1621,1627,1637,1657,1663,1667,1669,1693,
        +	1697,1699,1709,1721,1723,1733,1741,1747,
        +	1753,1759,1777,1783,1787,1789,1801,1811,
        +	1823,1831,1847,1861,1867,1871,1873,1877,
        +	1879,1889,1901,1907,1913,1931,1933,1949,
        +	1951,1973,1979,1987,1993,1997,1999,2003,
        +	2011,2017,2027,2029,2039,2053,2063,2069,
        +	2081,2083,2087,2089,2099,2111,2113,2129,
        +	2131,2137,2141,2143,2153,2161,2179,2203,
        +	2207,2213,2221,2237,2239,2243,2251,2267,
        +	2269,2273,2281,2287,2293,2297,2309,2311,
        +	2333,2339,2341,2347,2351,2357,2371,2377,
        +	2381,2383,2389,2393,2399,2411,2417,2423,
        +	2437,2441,2447,2459,2467,2473,2477,2503,
        +	2521,2531,2539,2543,2549,2551,2557,2579,
        +	2591,2593,2609,2617,2621,2633,2647,2657,
        +	2659,2663,2671,2677,2683,2687,2689,2693,
        +	2699,2707,2711,2713,2719,2729,2731,2741,
        +	2749,2753,2767,2777,2789,2791,2797,2801,
        +	2803,2819,2833,2837,2843,2851,2857,2861,
        +	2879,2887,2897,2903,2909,2917,2927,2939,
        +	2953,2957,2963,2969,2971,2999,3001,3011,
        +	3019,3023,3037,3041,3049,3061,3067,3079,
        +	3083,3089,3109,3119,3121,3137,3163,3167,
        +	3169,3181,3187,3191,3203,3209,3217,3221,
        +	3229,3251,3253,3257,3259,3271,3299,3301,
        +	3307,3313,3319,3323,3329,3331,3343,3347,
        +	3359,3361,3371,3373,3389,3391,3407,3413,
        +	3433,3449,3457,3461,3463,3467,3469,3491,
        +	3499,3511,3517,3527,3529,3533,3539,3541,
        +	3547,3557,3559,3571,3581,3583,3593,3607,
        +	3613,3617,3623,3631,3637,3643,3659,3671,
        +	3673,3677,3691,3697,3701,3709,3719,3727,
        +	3733,3739,3761,3767,3769,3779,3793,3797,
        +	3803,3821,3823,3833,3847,3851,3853,3863,
        +	3877,3881,3889,3907,3911,3917,3919,3923,
        +	3929,3931,3943,3947,3967,3989,4001,4003,
        +	4007,4013,4019,4021,4027,4049,4051,4057,
        +	4073,4079,4091,4093,4099,4111,4127,4129,
        +	4133,4139,4153,4157,4159,4177,4201,4211,
        +	4217,4219,4229,4231,4241,4243,4253,4259,
        +	4261,4271,4273,4283,4289,4297,4327,4337,
        +	4339,4349,4357,4363,4373,4391,4397,4409,
        +	4421,4423,4441,4447,4451,4457,4463,4481,
        +	4483,4493,4507,4513,4517,4519,4523,4547,
        +	4549,4561,4567,4583,4591,4597,4603,4621,
        +	4637,4639,4643,4649,4651,4657,4663,4673,
        +	4679,4691,4703,4721,4723,4729,4733,4751,
        +	4759,4783,4787,4789,4793,4799,4801,4813,
        +	4817,4831,4861,4871,4877,4889,4903,4909,
        +	4919,4931,4933,4937,4943,4951,4957,4967,
        +	4969,4973,4987,4993,4999,5003,5009,5011,
        +	5021,5023,5039,5051,5059,5077,5081,5087,
        +	5099,5101,5107,5113,5119,5147,5153,5167,
        +	5171,5179,5189,5197,5209,5227,5231,5233,
        +	5237,5261,5273,5279,5281,5297,5303,5309,
        +	5323,5333,5347,5351,5381,5387,5393,5399,
        +	5407,5413,5417,5419,5431,5437,5441,5443,
        +	5449,5471,5477,5479,5483,5501,5503,5507,
        +	5519,5521,5527,5531,5557,5563,5569,5573,
        +	5581,5591,5623,5639,5641,5647,5651,5653,
        +	5657,5659,5669,5683,5689,5693,5701,5711,
        +	5717,5737,5741,5743,5749,5779,5783,5791,
        +	5801,5807,5813,5821,5827,5839,5843,5849,
        +	5851,5857,5861,5867,5869,5879,5881,5897,
        +	5903,5923,5927,5939,5953,5981,5987,6007,
        +	6011,6029,6037,6043,6047,6053,6067,6073,
        +	6079,6089,6091,6101,6113,6121,6131,6133,
        +	6143,6151,6163,6173,6197,6199,6203,6211,
        +	6217,6221,6229,6247,6257,6263,6269,6271,
        +	6277,6287,6299,6301,6311,6317,6323,6329,
        +	6337,6343,6353,6359,6361,6367,6373,6379,
        +	6389,6397,6421,6427,6449,6451,6469,6473,
        +	6481,6491,6521,6529,6547,6551,6553,6563,
        +	6569,6571,6577,6581,6599,6607,6619,6637,
        +	6653,6659,6661,6673,6679,6689,6691,6701,
        +	6703,6709,6719,6733,6737,6761,6763,6779,
        +	6781,6791,6793,6803,6823,6827,6829,6833,
        +	6841,6857,6863,6869,6871,6883,6899,6907,
        +	6911,6917,6947,6949,6959,6961,6967,6971,
        +	6977,6983,6991,6997,7001,7013,7019,7027,
        +	7039,7043,7057,7069,7079,7103,7109,7121,
        +	7127,7129,7151,7159,7177,7187,7193,7207,
        +	7211,7213,7219,7229,7237,7243,7247,7253,
        +	7283,7297,7307,7309,7321,7331,7333,7349,
        +	7351,7369,7393,7411,7417,7433,7451,7457,
        +	7459,7477,7481,7487,7489,7499,7507,7517,
        +	7523,7529,7537,7541,7547,7549,7559,7561,
        +	7573,7577,7583,7589,7591,7603,7607,7621,
        +	7639,7643,7649,7669,7673,7681,7687,7691,
        +	7699,7703,7717,7723,7727,7741,7753,7757,
        +	7759,7789,7793,7817,7823,7829,7841,7853,
        +	7867,7873,7877,7879,7883,7901,7907,7919,
        +	7927,7933,7937,7949,7951,7963,7993,8009,
        +	8011,8017,8039,8053,8059,8069,8081,8087,
        +	8089,8093,8101,8111,8117,8123,8147,8161,
        +	8167,8171,8179,8191,8209,8219,8221,8231,
        +	8233,8237,8243,8263,8269,8273,8287,8291,
        +	8293,8297,8311,8317,8329,8353,8363,8369,
        +	8377,8387,8389,8419,8423,8429,8431,8443,
        +	8447,8461,8467,8501,8513,8521,8527,8537,
        +	8539,8543,8563,8573,8581,8597,8599,8609,
        +	8623,8627,8629,8641,8647,8663,8669,8677,
        +	8681,8689,8693,8699,8707,8713,8719,8731,
        +	8737,8741,8747,8753,8761,8779,8783,8803,
        +	8807,8819,8821,8831,8837,8839,8849,8861,
        +	8863,8867,8887,8893,8923,8929,8933,8941,
        +	8951,8963,8969,8971,8999,9001,9007,9011,
        +	9013,9029,9041,9043,9049,9059,9067,9091,
        +	9103,9109,9127,9133,9137,9151,9157,9161,
        +	9173,9181,9187,9199,9203,9209,9221,9227,
        +	9239,9241,9257,9277,9281,9283,9293,9311,
        +	9319,9323,9337,9341,9343,9349,9371,9377,
        +	9391,9397,9403,9413,9419,9421,9431,9433,
        +	9437,9439,9461,9463,9467,9473,9479,9491,
        +	9497,9511,9521,9533,9539,9547,9551,9587,
        +	9601,9613,9619,9623,9629,9631,9643,9649,
        +	9661,9677,9679,9689,9697,9719,9721,9733,
        +	9739,9743,9749,9767,9769,9781,9787,9791,
        +	9803,9811,9817,9829,9833,9839,9851,9857,
        +	9859,9871,9883,9887,9901,9907,9923,9929,
        +	9931,9941,9949,9967,9973,10007,10009,10037,
        +	10039,10061,10067,10069,10079,10091,10093,10099,
        +	10103,10111,10133,10139,10141,10151,10159,10163,
        +	10169,10177,10181,10193,10211,10223,10243,10247,
        +	10253,10259,10267,10271,10273,10289,10301,10303,
        +	10313,10321,10331,10333,10337,10343,10357,10369,
        +	10391,10399,10427,10429,10433,10453,10457,10459,
        +	10463,10477,10487,10499,10501,10513,10529,10531,
        +	10559,10567,10589,10597,10601,10607,10613,10627,
        +	10631,10639,10651,10657,10663,10667,10687,10691,
        +	10709,10711,10723,10729,10733,10739,10753,10771,
        +	10781,10789,10799,10831,10837,10847,10853,10859,
        +	10861,10867,10883,10889,10891,10903,10909,10937,
        +	10939,10949,10957,10973,10979,10987,10993,11003,
        +	11027,11047,11057,11059,11069,11071,11083,11087,
        +	11093,11113,11117,11119,11131,11149,11159,11161,
        +	11171,11173,11177,11197,11213,11239,11243,11251,
        +	11257,11261,11273,11279,11287,11299,11311,11317,
        +	11321,11329,11351,11353,11369,11383,11393,11399,
        +	11411,11423,11437,11443,11447,11467,11471,11483,
        +	11489,11491,11497,11503,11519,11527,11549,11551,
        +	11579,11587,11593,11597,11617,11621,11633,11657,
        +	11677,11681,11689,11699,11701,11717,11719,11731,
        +	11743,11777,11779,11783,11789,11801,11807,11813,
        +	11821,11827,11831,11833,11839,11863,11867,11887,
        +	11897,11903,11909,11923,11927,11933,11939,11941,
        +	11953,11959,11969,11971,11981,11987,12007,12011,
        +	12037,12041,12043,12049,12071,12073,12097,12101,
        +	12107,12109,12113,12119,12143,12149,12157,12161,
        +	12163,12197,12203,12211,12227,12239,12241,12251,
        +	12253,12263,12269,12277,12281,12289,12301,12323,
        +	12329,12343,12347,12373,12377,12379,12391,12401,
        +	12409,12413,12421,12433,12437,12451,12457,12473,
        +	12479,12487,12491,12497,12503,12511,12517,12527,
        +	12539,12541,12547,12553,12569,12577,12583,12589,
        +	12601,12611,12613,12619,12637,12641,12647,12653,
        +	12659,12671,12689,12697,12703,12713,12721,12739,
        +	12743,12757,12763,12781,12791,12799,12809,12821,
        +	12823,12829,12841,12853,12889,12893,12899,12907,
        +	12911,12917,12919,12923,12941,12953,12959,12967,
        +	12973,12979,12983,13001,13003,13007,13009,13033,
        +	13037,13043,13049,13063,13093,13099,13103,13109,
        +	13121,13127,13147,13151,13159,13163,13171,13177,
        +	13183,13187,13217,13219,13229,13241,13249,13259,
        +	13267,13291,13297,13309,13313,13327,13331,13337,
        +	13339,13367,13381,13397,13399,13411,13417,13421,
        +	13441,13451,13457,13463,13469,13477,13487,13499,
        +	13513,13523,13537,13553,13567,13577,13591,13597,
        +	13613,13619,13627,13633,13649,13669,13679,13681,
        +	13687,13691,13693,13697,13709,13711,13721,13723,
        +	13729,13751,13757,13759,13763,13781,13789,13799,
        +	13807,13829,13831,13841,13859,13873,13877,13879,
        +	13883,13901,13903,13907,13913,13921,13931,13933,
        +	13963,13967,13997,13999,14009,14011,14029,14033,
        +	14051,14057,14071,14081,14083,14087,14107,14143,
        +	14149,14153,14159,14173,14177,14197,14207,14221,
        +	14243,14249,14251,14281,14293,14303,14321,14323,
        +	14327,14341,14347,14369,14387,14389,14401,14407,
        +	14411,14419,14423,14431,14437,14447,14449,14461,
        +	14479,14489,14503,14519,14533,14537,14543,14549,
        +	14551,14557,14561,14563,14591,14593,14621,14627,
        +	14629,14633,14639,14653,14657,14669,14683,14699,
        +	14713,14717,14723,14731,14737,14741,14747,14753,
        +	14759,14767,14771,14779,14783,14797,14813,14821,
        +	14827,14831,14843,14851,14867,14869,14879,14887,
        +	14891,14897,14923,14929,14939,14947,14951,14957,
        +	14969,14983,15013,15017,15031,15053,15061,15073,
        +	15077,15083,15091,15101,15107,15121,15131,15137,
        +	15139,15149,15161,15173,15187,15193,15199,15217,
        +	15227,15233,15241,15259,15263,15269,15271,15277,
        +	15287,15289,15299,15307,15313,15319,15329,15331,
        +	15349,15359,15361,15373,15377,15383,15391,15401,
        +	15413,15427,15439,15443,15451,15461,15467,15473,
        +	15493,15497,15511,15527,15541,15551,15559,15569,
        +	15581,15583,15601,15607,15619,15629,15641,15643,
        +	15647,15649,15661,15667,15671,15679,15683,15727,
        +	15731,15733,15737,15739,15749,15761,15767,15773,
        +	15787,15791,15797,15803,15809,15817,15823,15859,
        +	15877,15881,15887,15889,15901,15907,15913,15919,
        +	15923,15937,15959,15971,15973,15991,16001,16007,
        +	16033,16057,16061,16063,16067,16069,16073,16087,
        +	16091,16097,16103,16111,16127,16139,16141,16183,
        +	16187,16189,16193,16217,16223,16229,16231,16249,
        +	16253,16267,16273,16301,16319,16333,16339,16349,
        +	16361,16363,16369,16381,16411,16417,16421,16427,
        +	16433,16447,16451,16453,16477,16481,16487,16493,
        +	16519,16529,16547,16553,16561,16567,16573,16603,
        +	16607,16619,16631,16633,16649,16651,16657,16661,
        +	16673,16691,16693,16699,16703,16729,16741,16747,
        +	16759,16763,16787,16811,16823,16829,16831,16843,
        +	16871,16879,16883,16889,16901,16903,16921,16927,
        +	16931,16937,16943,16963,16979,16981,16987,16993,
        +	17011,17021,17027,17029,17033,17041,17047,17053,
        +	17077,17093,17099,17107,17117,17123,17137,17159,
        +	17167,17183,17189,17191,17203,17207,17209,17231,
        +	17239,17257,17291,17293,17299,17317,17321,17327,
        +	17333,17341,17351,17359,17377,17383,17387,17389,
        +	17393,17401,17417,17419,17431,17443,17449,17467,
        +	17471,17477,17483,17489,17491,17497,17509,17519,
        +	17539,17551,17569,17573,17579,17581,17597,17599,
        +	17609,17623,17627,17657,17659,17669,17681,17683,
        +	17707,17713,17729,17737,17747,17749,17761,17783,
        +	17789,17791,17807,17827,17837,17839,17851,17863,
        +#endif
        +	};
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_prime.pl b/vendor/openssl/openssl/crypto/bn/bn_prime.pl
        new file mode 100644
        index 000000000..3fafb6f3e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_prime.pl
        @@ -0,0 +1,119 @@
        +#!/usr/local/bin/perl
        +# bn_prime.pl
        +
        +$num=2048;
        +$num=$ARGV[0] if ($#ARGV >= 0);
        +
        +push(@primes,2);
        +$p=1;
        +loop: while ($#primes < $num-1)
        +	{
        +	$p+=2;
        +	$s=int(sqrt($p));
        +
        +	for ($i=0; defined($primes[$i]) && $primes[$i]<=$s; $i++)
        +		{
        +		next loop if (($p%$primes[$i]) == 0);
        +		}
        +	push(@primes,$p);
        +	}
        +
        +# print <<"EOF";
        +# /* Auto generated by bn_prime.pl */
        +# /* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au).
        +#  * All rights reserved.
        +#  * Copyright remains Eric Young's, and as such any Copyright notices in
        +#  * the code are not to be removed.
        +#  * See the COPYRIGHT file in the SSLeay distribution for more details.
        +#  */
        +# 
        +# EOF
        +
        +print <<\EOF;
        +/* Auto generated by bn_prime.pl */
        +/* 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.]
        + */
        +
        +EOF
        +
        +for ($i=0; $i <= $#primes; $i++)
        +	{
        +	if ($primes[$i] > 256)
        +		{
        +		$eight=$i;
        +		last;
        +		}
        +	}
        +
        +printf "#ifndef EIGHT_BIT\n";
        +printf "#define NUMPRIMES %d\n",$num;
        +printf "typedef unsigned short prime_t;\n";
        +printf "#else\n";
        +printf "#define NUMPRIMES %d\n",$eight;
        +printf "typedef unsigned char prime_t;\n";
        +printf "#endif\n";
        +print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t";
        +$init=0;
        +for ($i=0; $i <= $#primes; $i++)
        +	{
        +	printf "\n#ifndef EIGHT_BIT\n\t" if ($primes[$i] > 256) && !($init++);
        +	printf("\n\t") if (($i%8) == 0) && ($i != 0);
        +	printf("%4d,",$primes[$i]);
        +	}
        +print "\n#endif\n\t};\n";
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_print.c b/vendor/openssl/openssl/crypto/bn/bn_print.c
        new file mode 100644
        index 000000000..1743b6a7e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_print.c
        @@ -0,0 +1,378 @@
        +/* crypto/bn/bn_print.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include "bn_lcl.h"
        +
        +static const char Hex[]="0123456789ABCDEF";
        +
        +/* Must 'OPENSSL_free' the returned data */
        +char *BN_bn2hex(const BIGNUM *a)
        +	{
        +	int i,j,v,z=0;
        +	char *buf;
        +	char *p;
        +
        +	buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
        +	if (buf == NULL)
        +		{
        +		BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	p=buf;
        +	if (a->neg) *(p++)='-';
        +	if (BN_is_zero(a)) *(p++)='0';
        +	for (i=a->top-1; i >=0; i--)
        +		{
        +		for (j=BN_BITS2-8; j >= 0; j-=8)
        +			{
        +			/* strip leading zeros */
        +			v=((int)(a->d[i]>>(long)j))&0xff;
        +			if (z || (v != 0))
        +				{
        +				*(p++)=Hex[v>>4];
        +				*(p++)=Hex[v&0x0f];
        +				z=1;
        +				}
        +			}
        +		}
        +	*p='\0';
        +err:
        +	return(buf);
        +	}
        +
        +/* Must 'OPENSSL_free' the returned data */
        +char *BN_bn2dec(const BIGNUM *a)
        +	{
        +	int i=0,num, ok = 0;
        +	char *buf=NULL;
        +	char *p;
        +	BIGNUM *t=NULL;
        +	BN_ULONG *bn_data=NULL,*lp;
        +
        +	/* get an upper bound for the length of the decimal integer
        +	 * num <= (BN_num_bits(a) + 1) * log(2)
        +	 *     <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1     (rounding error)
        +	 *     <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1 
        +	 */
        +	i=BN_num_bits(a)*3;
        +	num=(i/10+i/1000+1)+1;
        +	bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
        +	buf=(char *)OPENSSL_malloc(num+3);
        +	if ((buf == NULL) || (bn_data == NULL))
        +		{
        +		BNerr(BN_F_BN_BN2DEC,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if ((t=BN_dup(a)) == NULL) goto err;
        +
        +#define BUF_REMAIN (num+3 - (size_t)(p - buf))
        +	p=buf;
        +	lp=bn_data;
        +	if (BN_is_zero(t))
        +		{
        +		*(p++)='0';
        +		*(p++)='\0';
        +		}
        +	else
        +		{
        +		if (BN_is_negative(t))
        +			*p++ = '-';
        +
        +		i=0;
        +		while (!BN_is_zero(t))
        +			{
        +			*lp=BN_div_word(t,BN_DEC_CONV);
        +			lp++;
        +			}
        +		lp--;
        +		/* We now have a series of blocks, BN_DEC_NUM chars
        +		 * in length, where the last one needs truncation.
        +		 * The blocks need to be reversed in order. */
        +		BIO_snprintf(p,BUF_REMAIN,BN_DEC_FMT1,*lp);
        +		while (*p) p++;
        +		while (lp != bn_data)
        +			{
        +			lp--;
        +			BIO_snprintf(p,BUF_REMAIN,BN_DEC_FMT2,*lp);
        +			while (*p) p++;
        +			}
        +		}
        +	ok = 1;
        +err:
        +	if (bn_data != NULL) OPENSSL_free(bn_data);
        +	if (t != NULL) BN_free(t);
        +	if (!ok && buf)
        +		{
        +		OPENSSL_free(buf);
        +		buf = NULL;
        +		}
        +
        +	return(buf);
        +	}
        +
        +int BN_hex2bn(BIGNUM **bn, const char *a)
        +	{
        +	BIGNUM *ret=NULL;
        +	BN_ULONG l=0;
        +	int neg=0,h,m,i,j,k,c;
        +	int num;
        +
        +	if ((a == NULL) || (*a == '\0')) return(0);
        +
        +	if (*a == '-') { neg=1; a++; }
        +
        +	for (i=0; isxdigit((unsigned char) a[i]); i++)
        +		;
        +
        +	num=i+neg;
        +	if (bn == NULL) return(num);
        +
        +	/* a is the start of the hex digits, and it is 'i' long */
        +	if (*bn == NULL)
        +		{
        +		if ((ret=BN_new()) == NULL) return(0);
        +		}
        +	else
        +		{
        +		ret= *bn;
        +		BN_zero(ret);
        +		}
        +
        +	/* i is the number of hex digests; */
        +	if (bn_expand(ret,i*4) == NULL) goto err;
        +
        +	j=i; /* least significant 'hex' */
        +	m=0;
        +	h=0;
        +	while (j > 0)
        +		{
        +		m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
        +		l=0;
        +		for (;;)
        +			{
        +			c=a[j-m];
        +			if ((c >= '0') && (c <= '9')) k=c-'0';
        +			else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
        +			else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
        +			else k=0; /* paranoia */
        +			l=(l<<4)|k;
        +
        +			if (--m <= 0)
        +				{
        +				ret->d[h++]=l;
        +				break;
        +				}
        +			}
        +		j-=(BN_BYTES*2);
        +		}
        +	ret->top=h;
        +	bn_correct_top(ret);
        +	ret->neg=neg;
        +
        +	*bn=ret;
        +	bn_check_top(ret);
        +	return(num);
        +err:
        +	if (*bn == NULL) BN_free(ret);
        +	return(0);
        +	}
        +
        +int BN_dec2bn(BIGNUM **bn, const char *a)
        +	{
        +	BIGNUM *ret=NULL;
        +	BN_ULONG l=0;
        +	int neg=0,i,j;
        +	int num;
        +
        +	if ((a == NULL) || (*a == '\0')) return(0);
        +	if (*a == '-') { neg=1; a++; }
        +
        +	for (i=0; isdigit((unsigned char) a[i]); i++)
        +		;
        +
        +	num=i+neg;
        +	if (bn == NULL) return(num);
        +
        +	/* a is the start of the digits, and it is 'i' long.
        +	 * We chop it into BN_DEC_NUM digits at a time */
        +	if (*bn == NULL)
        +		{
        +		if ((ret=BN_new()) == NULL) return(0);
        +		}
        +	else
        +		{
        +		ret= *bn;
        +		BN_zero(ret);
        +		}
        +
        +	/* i is the number of digests, a bit of an over expand; */
        +	if (bn_expand(ret,i*4) == NULL) goto err;
        +
        +	j=BN_DEC_NUM-(i%BN_DEC_NUM);
        +	if (j == BN_DEC_NUM) j=0;
        +	l=0;
        +	while (*a)
        +		{
        +		l*=10;
        +		l+= *a-'0';
        +		a++;
        +		if (++j == BN_DEC_NUM)
        +			{
        +			BN_mul_word(ret,BN_DEC_CONV);
        +			BN_add_word(ret,l);
        +			l=0;
        +			j=0;
        +			}
        +		}
        +	ret->neg=neg;
        +
        +	bn_correct_top(ret);
        +	*bn=ret;
        +	bn_check_top(ret);
        +	return(num);
        +err:
        +	if (*bn == NULL) BN_free(ret);
        +	return(0);
        +	}
        +
        +int BN_asc2bn(BIGNUM **bn, const char *a)
        +	{
        +	const char *p = a;
        +	if (*p == '-')
        +		p++;
        +
        +	if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x'))
        +		{		
        +		if (!BN_hex2bn(bn, p + 2))
        +			return 0;
        +		}
        +	else
        +		{
        +		if (!BN_dec2bn(bn, p))
        +			return 0;
        +		}
        +	if (*a == '-')
        +		(*bn)->neg = 1;
        +	return 1;
        +	}
        +
        +#ifndef OPENSSL_NO_BIO
        +#ifndef OPENSSL_NO_FP_API
        +int BN_print_fp(FILE *fp, const BIGNUM *a)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		return(0);
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	ret=BN_print(b,a);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +#endif
        +
        +int BN_print(BIO *bp, const BIGNUM *a)
        +	{
        +	int i,j,v,z=0;
        +	int ret=0;
        +
        +	if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
        +	if (BN_is_zero(a) && (BIO_write(bp,"0",1) != 1)) goto end;
        +	for (i=a->top-1; i >=0; i--)
        +		{
        +		for (j=BN_BITS2-4; j >= 0; j-=4)
        +			{
        +			/* strip leading zeros */
        +			v=((int)(a->d[i]>>(long)j))&0x0f;
        +			if (z || (v != 0))
        +				{
        +				if (BIO_write(bp,&(Hex[v]),1) != 1)
        +					goto end;
        +				z=1;
        +				}
        +			}
        +		}
        +	ret=1;
        +end:
        +	return(ret);
        +	}
        +#endif
        +
        +char *BN_options(void)
        +	{
        +	static int init=0;
        +	static char data[16];
        +
        +	if (!init)
        +		{
        +		init++;
        +#ifdef BN_LLONG
        +		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
        +			     (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
        +#else
        +		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
        +			     (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
        +#endif
        +		}
        +	return(data);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_rand.c b/vendor/openssl/openssl/crypto/bn/bn_rand.c
        new file mode 100644
        index 000000000..b376c28ff
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_rand.c
        @@ -0,0 +1,305 @@
        +/* crypto/bn/bn_rand.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +#include <openssl/rand.h>
        +
        +static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
        +	{
        +	unsigned char *buf=NULL;
        +	int ret=0,bit,bytes,mask;
        +	time_t tim;
        +
        +	if (bits == 0)
        +		{
        +		BN_zero(rnd);
        +		return 1;
        +		}
        +
        +	bytes=(bits+7)/8;
        +	bit=(bits-1)%8;
        +	mask=0xff<<(bit+1);
        +
        +	buf=(unsigned char *)OPENSSL_malloc(bytes);
        +	if (buf == NULL)
        +		{
        +		BNerr(BN_F_BNRAND,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	/* make a random number and set the top and bottom bits */
        +	time(&tim);
        +	RAND_add(&tim,sizeof(tim),0.0);
        +
        +	if (pseudorand)
        +		{
        +		if (RAND_pseudo_bytes(buf, bytes) == -1)
        +			goto err;
        +		}
        +	else
        +		{
        +		if (RAND_bytes(buf, bytes) <= 0)
        +			goto err;
        +		}
        +
        +#if 1
        +	if (pseudorand == 2)
        +		{
        +		/* generate patterns that are more likely to trigger BN
        +		   library bugs */
        +		int i;
        +		unsigned char c;
        +
        +		for (i = 0; i < bytes; i++)
        +			{
        +			RAND_pseudo_bytes(&c, 1);
        +			if (c >= 128 && i > 0)
        +				buf[i] = buf[i-1];
        +			else if (c < 42)
        +				buf[i] = 0;
        +			else if (c < 84)
        +				buf[i] = 255;
        +			}
        +		}
        +#endif
        +
        +	if (top != -1)
        +		{
        +		if (top)
        +			{
        +			if (bit == 0)
        +				{
        +				buf[0]=1;
        +				buf[1]|=0x80;
        +				}
        +			else
        +				{
        +				buf[0]|=(3<<(bit-1));
        +				}
        +			}
        +		else
        +			{
        +			buf[0]|=(1<<bit);
        +			}
        +		}
        +	buf[0] &= ~mask;
        +	if (bottom) /* set bottom bit if requested */
        +		buf[bytes-1]|=1;
        +	if (!BN_bin2bn(buf,bytes,rnd)) goto err;
        +	ret=1;
        +err:
        +	if (buf != NULL)
        +		{
        +		OPENSSL_cleanse(buf,bytes);
        +		OPENSSL_free(buf);
        +		}
        +	bn_check_top(rnd);
        +	return(ret);
        +	}
        +
        +int     BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
        +	{
        +	return bnrand(0, rnd, bits, top, bottom);
        +	}
        +
        +int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
        +	{
        +	return bnrand(1, rnd, bits, top, bottom);
        +	}
        +
        +#if 1
        +int     BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
        +	{
        +	return bnrand(2, rnd, bits, top, bottom);
        +	}
        +#endif
        +
        +
        +/* random number r:  0 <= r < range */
        +static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
        +	{
        +	int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
        +	int n;
        +	int count = 100;
        +
        +	if (range->neg || BN_is_zero(range))
        +		{
        +		BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
        +		return 0;
        +		}
        +
        +	n = BN_num_bits(range); /* n > 0 */
        +
        +	/* BN_is_bit_set(range, n - 1) always holds */
        +
        +	if (n == 1)
        +		BN_zero(r);
        +	else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
        +		{
        +		/* range = 100..._2,
        +		 * so  3*range (= 11..._2)  is exactly one bit longer than  range */
        +		do
        +			{
        +			if (!bn_rand(r, n + 1, -1, 0)) return 0;
        +			/* If  r < 3*range,  use  r := r MOD range
        +			 * (which is either  r, r - range,  or  r - 2*range).
        +			 * Otherwise, iterate once more.
        +			 * Since  3*range = 11..._2, each iteration succeeds with
        +			 * probability >= .75. */
        +			if (BN_cmp(r ,range) >= 0)
        +				{
        +				if (!BN_sub(r, r, range)) return 0;
        +				if (BN_cmp(r, range) >= 0)
        +					if (!BN_sub(r, r, range)) return 0;
        +				}
        +
        +			if (!--count)
        +				{
        +				BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
        +				return 0;
        +				}
        +			
        +			}
        +		while (BN_cmp(r, range) >= 0);
        +		}
        +	else
        +		{
        +		do
        +			{
        +			/* range = 11..._2  or  range = 101..._2 */
        +			if (!bn_rand(r, n, -1, 0)) return 0;
        +
        +			if (!--count)
        +				{
        +				BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
        +				return 0;
        +				}
        +			}
        +		while (BN_cmp(r, range) >= 0);
        +		}
        +
        +	bn_check_top(r);
        +	return 1;
        +	}
        +
        +
        +int	BN_rand_range(BIGNUM *r, const BIGNUM *range)
        +	{
        +	return bn_rand_range(0, r, range);
        +	}
        +
        +int	BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
        +	{
        +	return bn_rand_range(1, r, range);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_recp.c b/vendor/openssl/openssl/crypto/bn/bn_recp.c
        new file mode 100644
        index 000000000..2e8efb8da
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_recp.c
        @@ -0,0 +1,234 @@
        +/* crypto/bn/bn_recp.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +void BN_RECP_CTX_init(BN_RECP_CTX *recp)
        +	{
        +	BN_init(&(recp->N));
        +	BN_init(&(recp->Nr));
        +	recp->num_bits=0;
        +	recp->flags=0;
        +	}
        +
        +BN_RECP_CTX *BN_RECP_CTX_new(void)
        +	{
        +	BN_RECP_CTX *ret;
        +
        +	if ((ret=(BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL)
        +		return(NULL);
        +
        +	BN_RECP_CTX_init(ret);
        +	ret->flags=BN_FLG_MALLOCED;
        +	return(ret);
        +	}
        +
        +void BN_RECP_CTX_free(BN_RECP_CTX *recp)
        +	{
        +	if(recp == NULL)
        +	    return;
        +
        +	BN_free(&(recp->N));
        +	BN_free(&(recp->Nr));
        +	if (recp->flags & BN_FLG_MALLOCED)
        +		OPENSSL_free(recp);
        +	}
        +
        +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
        +	{
        +	if (!BN_copy(&(recp->N),d)) return 0;
        +	BN_zero(&(recp->Nr));
        +	recp->num_bits=BN_num_bits(d);
        +	recp->shift=0;
        +	return(1);
        +	}
        +
        +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
        +	BN_RECP_CTX *recp, BN_CTX *ctx)
        +	{
        +	int ret=0;
        +	BIGNUM *a;
        +	const BIGNUM *ca;
        +
        +	BN_CTX_start(ctx);
        +	if ((a = BN_CTX_get(ctx)) == NULL) goto err;
        +	if (y != NULL)
        +		{
        +		if (x == y)
        +			{ if (!BN_sqr(a,x,ctx)) goto err; }
        +		else
        +			{ if (!BN_mul(a,x,y,ctx)) goto err; }
        +		ca = a;
        +		}
        +	else
        +		ca=x; /* Just do the mod */
        +
        +	ret = BN_div_recp(NULL,r,ca,recp,ctx);
        +err:
        +	BN_CTX_end(ctx);
        +	bn_check_top(r);
        +	return(ret);
        +	}
        +
        +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
        +	BN_RECP_CTX *recp, BN_CTX *ctx)
        +	{
        +	int i,j,ret=0;
        +	BIGNUM *a,*b,*d,*r;
        +
        +	BN_CTX_start(ctx);
        +	a=BN_CTX_get(ctx);
        +	b=BN_CTX_get(ctx);
        +	if (dv != NULL)
        +		d=dv;
        +	else
        +		d=BN_CTX_get(ctx);
        +	if (rem != NULL)
        +		r=rem;
        +	else
        +		r=BN_CTX_get(ctx);
        +	if (a == NULL || b == NULL || d == NULL || r == NULL) goto err;
        +
        +	if (BN_ucmp(m,&(recp->N)) < 0)
        +		{
        +		BN_zero(d);
        +		if (!BN_copy(r,m)) return 0;
        +		BN_CTX_end(ctx);
        +		return(1);
        +		}
        +
        +	/* We want the remainder
        +	 * Given input of ABCDEF / ab
        +	 * we need multiply ABCDEF by 3 digests of the reciprocal of ab
        +	 *
        +	 */
        +
        +	/* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
        +	i=BN_num_bits(m);
        +	j=recp->num_bits<<1;
        +	if (j>i) i=j;
        +
        +	/* Nr := round(2^i / N) */
        +	if (i != recp->shift)
        +		recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
        +			i,ctx); /* BN_reciprocal returns i, or -1 for an error */
        +	if (recp->shift == -1) goto err;
        +
        +	/* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
        +	 *    = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
        +	 *   <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
        +	 *    = |m/N|
        +	 */
        +	if (!BN_rshift(a,m,recp->num_bits)) goto err;
        +	if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
        +	if (!BN_rshift(d,b,i-recp->num_bits)) goto err;
        +	d->neg=0;
        +
        +	if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
        +	if (!BN_usub(r,m,b)) goto err;
        +	r->neg=0;
        +
        +#if 1
        +	j=0;
        +	while (BN_ucmp(r,&(recp->N)) >= 0)
        +		{
        +		if (j++ > 2)
        +			{
        +			BNerr(BN_F_BN_DIV_RECP,BN_R_BAD_RECIPROCAL);
        +			goto err;
        +			}
        +		if (!BN_usub(r,r,&(recp->N))) goto err;
        +		if (!BN_add_word(d,1)) goto err;
        +		}
        +#endif
        +
        +	r->neg=BN_is_zero(r)?0:m->neg;
        +	d->neg=m->neg^recp->N.neg;
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	bn_check_top(dv);
        +	bn_check_top(rem);
        +	return(ret);
        +	} 
        +
        +/* len is the expected size of the result
        + * We actually calculate with an extra word of precision, so
        + * we can do faster division if the remainder is not required.
        + */
        +/* r := 2^len / m */
        +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
        +	{
        +	int ret= -1;
        +	BIGNUM *t;
        +
        +	BN_CTX_start(ctx);
        +	if((t = BN_CTX_get(ctx)) == NULL) goto err;
        +
        +	if (!BN_set_bit(t,len)) goto err;
        +
        +	if (!BN_div(r,NULL,t,m,ctx)) goto err;
        +
        +	ret=len;
        +err:
        +	bn_check_top(r);
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_shift.c b/vendor/openssl/openssl/crypto/bn/bn_shift.c
        new file mode 100644
        index 000000000..a6fca2c42
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_shift.c
        @@ -0,0 +1,223 @@
        +/* crypto/bn/bn_shift.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +int BN_lshift1(BIGNUM *r, const BIGNUM *a)
        +	{
        +	register BN_ULONG *ap,*rp,t,c;
        +	int i;
        +
        +	bn_check_top(r);
        +	bn_check_top(a);
        +
        +	if (r != a)
        +		{
        +		r->neg=a->neg;
        +		if (bn_wexpand(r,a->top+1) == NULL) return(0);
        +		r->top=a->top;
        +		}
        +	else
        +		{
        +		if (bn_wexpand(r,a->top+1) == NULL) return(0);
        +		}
        +	ap=a->d;
        +	rp=r->d;
        +	c=0;
        +	for (i=0; i<a->top; i++)
        +		{
        +		t= *(ap++);
        +		*(rp++)=((t<<1)|c)&BN_MASK2;
        +		c=(t & BN_TBIT)?1:0;
        +		}
        +	if (c)
        +		{
        +		*rp=1;
        +		r->top++;
        +		}
        +	bn_check_top(r);
        +	return(1);
        +	}
        +
        +int BN_rshift1(BIGNUM *r, const BIGNUM *a)
        +	{
        +	BN_ULONG *ap,*rp,t,c;
        +	int i,j;
        +
        +	bn_check_top(r);
        +	bn_check_top(a);
        +
        +	if (BN_is_zero(a))
        +		{
        +		BN_zero(r);
        +		return(1);
        +		}
        +	i = a->top;
        +	ap= a->d;
        +	j = i-(ap[i-1]==1);
        +	if (a != r)
        +		{
        +		if (bn_wexpand(r,j) == NULL) return(0);
        +		r->neg=a->neg;
        +		}
        +	rp=r->d;
        +	t=ap[--i];
        +	c=(t&1)?BN_TBIT:0;
        +	if (t>>=1) rp[i]=t;
        +	while (i>0)
        +		{
        +		t=ap[--i];
        +		rp[i]=((t>>1)&BN_MASK2)|c;
        +		c=(t&1)?BN_TBIT:0;
        +		}
        +	r->top=j;
        +	bn_check_top(r);
        +	return(1);
        +	}
        +
        +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
        +	{
        +	int i,nw,lb,rb;
        +	BN_ULONG *t,*f;
        +	BN_ULONG l;
        +
        +	bn_check_top(r);
        +	bn_check_top(a);
        +
        +	r->neg=a->neg;
        +	nw=n/BN_BITS2;
        +	if (bn_wexpand(r,a->top+nw+1) == NULL) return(0);
        +	lb=n%BN_BITS2;
        +	rb=BN_BITS2-lb;
        +	f=a->d;
        +	t=r->d;
        +	t[a->top+nw]=0;
        +	if (lb == 0)
        +		for (i=a->top-1; i>=0; i--)
        +			t[nw+i]=f[i];
        +	else
        +		for (i=a->top-1; i>=0; i--)
        +			{
        +			l=f[i];
        +			t[nw+i+1]|=(l>>rb)&BN_MASK2;
        +			t[nw+i]=(l<<lb)&BN_MASK2;
        +			}
        +	memset(t,0,nw*sizeof(t[0]));
        +/*	for (i=0; i<nw; i++)
        +		t[i]=0;*/
        +	r->top=a->top+nw+1;
        +	bn_correct_top(r);
        +	bn_check_top(r);
        +	return(1);
        +	}
        +
        +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
        +	{
        +	int i,j,nw,lb,rb;
        +	BN_ULONG *t,*f;
        +	BN_ULONG l,tmp;
        +
        +	bn_check_top(r);
        +	bn_check_top(a);
        +
        +	nw=n/BN_BITS2;
        +	rb=n%BN_BITS2;
        +	lb=BN_BITS2-rb;
        +	if (nw >= a->top || a->top == 0)
        +		{
        +		BN_zero(r);
        +		return(1);
        +		}
        +	i = (BN_num_bits(a)-n+(BN_BITS2-1))/BN_BITS2;
        +	if (r != a)
        +		{
        +		r->neg=a->neg;
        +		if (bn_wexpand(r,i) == NULL) return(0);
        +		}
        +	else
        +		{
        +		if (n == 0)
        +			return 1; /* or the copying loop will go berserk */
        +		}
        +
        +	f= &(a->d[nw]);
        +	t=r->d;
        +	j=a->top-nw;
        +	r->top=i;
        +
        +	if (rb == 0)
        +		{
        +		for (i=j; i != 0; i--)
        +			*(t++)= *(f++);
        +		}
        +	else
        +		{
        +		l= *(f++);
        +		for (i=j-1; i != 0; i--)
        +			{
        +			tmp =(l>>rb)&BN_MASK2;
        +			l= *(f++);
        +			*(t++) =(tmp|(l<<lb))&BN_MASK2;
        +			}
        +		if ((l = (l>>rb)&BN_MASK2)) *(t) = l;
        +		}
        +	bn_check_top(r);
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_sqr.c b/vendor/openssl/openssl/crypto/bn/bn_sqr.c
        new file mode 100644
        index 000000000..270d0cd34
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_sqr.c
        @@ -0,0 +1,294 @@
        +/* crypto/bn/bn_sqr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +/* r must not be a */
        +/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
        +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        +	{
        +	int max,al;
        +	int ret = 0;
        +	BIGNUM *tmp,*rr;
        +
        +#ifdef BN_COUNT
        +	fprintf(stderr,"BN_sqr %d * %d\n",a->top,a->top);
        +#endif
        +	bn_check_top(a);
        +
        +	al=a->top;
        +	if (al <= 0)
        +		{
        +		r->top=0;
        +		return 1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	rr=(a != r) ? r : BN_CTX_get(ctx);
        +	tmp=BN_CTX_get(ctx);
        +	if (!rr || !tmp) goto err;
        +
        +	max = 2 * al; /* Non-zero (from above) */
        +	if (bn_wexpand(rr,max) == NULL) goto err;
        +
        +	if (al == 4)
        +		{
        +#ifndef BN_SQR_COMBA
        +		BN_ULONG t[8];
        +		bn_sqr_normal(rr->d,a->d,4,t);
        +#else
        +		bn_sqr_comba4(rr->d,a->d);
        +#endif
        +		}
        +	else if (al == 8)
        +		{
        +#ifndef BN_SQR_COMBA
        +		BN_ULONG t[16];
        +		bn_sqr_normal(rr->d,a->d,8,t);
        +#else
        +		bn_sqr_comba8(rr->d,a->d);
        +#endif
        +		}
        +	else 
        +		{
        +#if defined(BN_RECURSION)
        +		if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
        +			{
        +			BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
        +			bn_sqr_normal(rr->d,a->d,al,t);
        +			}
        +		else
        +			{
        +			int j,k;
        +
        +			j=BN_num_bits_word((BN_ULONG)al);
        +			j=1<<(j-1);
        +			k=j+j;
        +			if (al == j)
        +				{
        +				if (bn_wexpand(tmp,k*2) == NULL) goto err;
        +				bn_sqr_recursive(rr->d,a->d,al,tmp->d);
        +				}
        +			else
        +				{
        +				if (bn_wexpand(tmp,max) == NULL) goto err;
        +				bn_sqr_normal(rr->d,a->d,al,tmp->d);
        +				}
        +			}
        +#else
        +		if (bn_wexpand(tmp,max) == NULL) goto err;
        +		bn_sqr_normal(rr->d,a->d,al,tmp->d);
        +#endif
        +		}
        +
        +	rr->neg=0;
        +	/* If the most-significant half of the top word of 'a' is zero, then
        +	 * the square of 'a' will max-1 words. */
        +	if(a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
        +		rr->top = max - 1;
        +	else
        +		rr->top = max;
        +	if (rr != r) BN_copy(r,rr);
        +	ret = 1;
        + err:
        +	bn_check_top(rr);
        +	bn_check_top(tmp);
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +/* tmp must have 2*n words */
        +void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
        +	{
        +	int i,j,max;
        +	const BN_ULONG *ap;
        +	BN_ULONG *rp;
        +
        +	max=n*2;
        +	ap=a;
        +	rp=r;
        +	rp[0]=rp[max-1]=0;
        +	rp++;
        +	j=n;
        +
        +	if (--j > 0)
        +		{
        +		ap++;
        +		rp[j]=bn_mul_words(rp,ap,j,ap[-1]);
        +		rp+=2;
        +		}
        +
        +	for (i=n-2; i>0; i--)
        +		{
        +		j--;
        +		ap++;
        +		rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]);
        +		rp+=2;
        +		}
        +
        +	bn_add_words(r,r,r,max);
        +
        +	/* There will not be a carry */
        +
        +	bn_sqr_words(tmp,a,n);
        +
        +	bn_add_words(r,r,tmp,max);
        +	}
        +
        +#ifdef BN_RECURSION
        +/* r is 2*n words in size,
        + * a and b are both n words in size.    (There's not actually a 'b' here ...)
        + * n must be a power of 2.
        + * We multiply and return the result.
        + * t must be 2*n words in size
        + * We calculate
        + * a[0]*b[0]
        + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
        + * a[1]*b[1]
        + */
        +void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
        +	{
        +	int n=n2/2;
        +	int zero,c1;
        +	BN_ULONG ln,lo,*p;
        +
        +#ifdef BN_COUNT
        +	fprintf(stderr," bn_sqr_recursive %d * %d\n",n2,n2);
        +#endif
        +	if (n2 == 4)
        +		{
        +#ifndef BN_SQR_COMBA
        +		bn_sqr_normal(r,a,4,t);
        +#else
        +		bn_sqr_comba4(r,a);
        +#endif
        +		return;
        +		}
        +	else if (n2 == 8)
        +		{
        +#ifndef BN_SQR_COMBA
        +		bn_sqr_normal(r,a,8,t);
        +#else
        +		bn_sqr_comba8(r,a);
        +#endif
        +		return;
        +		}
        +	if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
        +		{
        +		bn_sqr_normal(r,a,n2,t);
        +		return;
        +		}
        +	/* r=(a[0]-a[1])*(a[1]-a[0]) */
        +	c1=bn_cmp_words(a,&(a[n]),n);
        +	zero=0;
        +	if (c1 > 0)
        +		bn_sub_words(t,a,&(a[n]),n);
        +	else if (c1 < 0)
        +		bn_sub_words(t,&(a[n]),a,n);
        +	else
        +		zero=1;
        +
        +	/* The result will always be negative unless it is zero */
        +	p= &(t[n2*2]);
        +
        +	if (!zero)
        +		bn_sqr_recursive(&(t[n2]),t,n,p);
        +	else
        +		memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
        +	bn_sqr_recursive(r,a,n,p);
        +	bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
        +
        +	/* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
        +	 * r[10] holds (a[0]*b[0])
        +	 * r[32] holds (b[1]*b[1])
        +	 */
        +
        +	c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
        +
        +	/* t[32] is negative */
        +	c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
        +
        +	/* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
        +	 * r[10] holds (a[0]*a[0])
        +	 * r[32] holds (a[1]*a[1])
        +	 * c1 holds the carry bits
        +	 */
        +	c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
        +	if (c1)
        +		{
        +		p= &(r[n+n2]);
        +		lo= *p;
        +		ln=(lo+c1)&BN_MASK2;
        +		*p=ln;
        +
        +		/* The overflow will stop before we over write
        +		 * words we should not overwrite */
        +		if (ln < (BN_ULONG)c1)
        +			{
        +			do	{
        +				p++;
        +				lo= *p;
        +				ln=(lo+1)&BN_MASK2;
        +				*p=ln;
        +				} while (ln == 0);
        +			}
        +		}
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_sqrt.c b/vendor/openssl/openssl/crypto/bn/bn_sqrt.c
        new file mode 100644
        index 000000000..6beaf9e5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_sqrt.c
        @@ -0,0 +1,393 @@
        +/* crypto/bn/bn_sqrt.c */
        +/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
        + * and Bodo Moeller for the OpenSSL project. */
        +/* ====================================================================
        + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +
        +BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 
        +/* Returns 'ret' such that
        + *      ret^2 == a (mod p),
        + * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
        + * in Algebraic Computational Number Theory", algorithm 1.5.1).
        + * 'p' must be prime!
        + */
        +	{
        +	BIGNUM *ret = in;
        +	int err = 1;
        +	int r;
        +	BIGNUM *A, *b, *q, *t, *x, *y;
        +	int e, i, j;
        +	
        +	if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
        +		{
        +		if (BN_abs_is_word(p, 2))
        +			{
        +			if (ret == NULL)
        +				ret = BN_new();
        +			if (ret == NULL)
        +				goto end;
        +			if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
        +				{
        +				if (ret != in)
        +					BN_free(ret);
        +				return NULL;
        +				}
        +			bn_check_top(ret);
        +			return ret;
        +			}
        +
        +		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
        +		return(NULL);
        +		}
        +
        +	if (BN_is_zero(a) || BN_is_one(a))
        +		{
        +		if (ret == NULL)
        +			ret = BN_new();
        +		if (ret == NULL)
        +			goto end;
        +		if (!BN_set_word(ret, BN_is_one(a)))
        +			{
        +			if (ret != in)
        +				BN_free(ret);
        +			return NULL;
        +			}
        +		bn_check_top(ret);
        +		return ret;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	A = BN_CTX_get(ctx);
        +	b = BN_CTX_get(ctx);
        +	q = BN_CTX_get(ctx);
        +	t = BN_CTX_get(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	if (y == NULL) goto end;
        +	
        +	if (ret == NULL)
        +		ret = BN_new();
        +	if (ret == NULL) goto end;
        +
        +	/* A = a mod p */
        +	if (!BN_nnmod(A, a, p, ctx)) goto end;
        +
        +	/* now write  |p| - 1  as  2^e*q  where  q  is odd */
        +	e = 1;
        +	while (!BN_is_bit_set(p, e))
        +		e++;
        +	/* we'll set  q  later (if needed) */
        +
        +	if (e == 1)
        +		{
        +		/* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
        +		 * modulo  (|p|-1)/2,  and square roots can be computed
        +		 * directly by modular exponentiation.
        +		 * We have
        +		 *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
        +		 * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
        +		 */
        +		if (!BN_rshift(q, p, 2)) goto end;
        +		q->neg = 0;
        +		if (!BN_add_word(q, 1)) goto end;
        +		if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
        +		err = 0;
        +		goto vrfy;
        +		}
        +	
        +	if (e == 2)
        +		{
        +		/* |p| == 5  (mod 8)
        +		 *
        +		 * In this case  2  is always a non-square since
        +		 * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
        +		 * So if  a  really is a square, then  2*a  is a non-square.
        +		 * Thus for
        +		 *      b := (2*a)^((|p|-5)/8),
        +		 *      i := (2*a)*b^2
        +		 * we have
        +		 *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
        +		 *         = (2*a)^((p-1)/2)
        +		 *         = -1;
        +		 * so if we set
        +		 *      x := a*b*(i-1),
        +		 * then
        +		 *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
        +		 *         = a^2 * b^2 * (-2*i)
        +		 *         = a*(-i)*(2*a*b^2)
        +		 *         = a*(-i)*i
        +		 *         = a.
        +		 *
        +		 * (This is due to A.O.L. Atkin, 
        +		 * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
        +		 * November 1992.)
        +		 */
        +
        +		/* t := 2*a */
        +		if (!BN_mod_lshift1_quick(t, A, p)) goto end;
        +
        +		/* b := (2*a)^((|p|-5)/8) */
        +		if (!BN_rshift(q, p, 3)) goto end;
        +		q->neg = 0;
        +		if (!BN_mod_exp(b, t, q, p, ctx)) goto end;
        +
        +		/* y := b^2 */
        +		if (!BN_mod_sqr(y, b, p, ctx)) goto end;
        +
        +		/* t := (2*a)*b^2 - 1*/
        +		if (!BN_mod_mul(t, t, y, p, ctx)) goto end;
        +		if (!BN_sub_word(t, 1)) goto end;
        +
        +		/* x = a*b*t */
        +		if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
        +		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
        +
        +		if (!BN_copy(ret, x)) goto end;
        +		err = 0;
        +		goto vrfy;
        +		}
        +	
        +	/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
        +	 * First, find some  y  that is not a square. */
        +	if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
        +	q->neg = 0;
        +	i = 2;
        +	do
        +		{
        +		/* For efficiency, try small numbers first;
        +		 * if this fails, try random numbers.
        +		 */
        +		if (i < 22)
        +			{
        +			if (!BN_set_word(y, i)) goto end;
        +			}
        +		else
        +			{
        +			if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end;
        +			if (BN_ucmp(y, p) >= 0)
        +				{
        +				if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end;
        +				}
        +			/* now 0 <= y < |p| */
        +			if (BN_is_zero(y))
        +				if (!BN_set_word(y, i)) goto end;
        +			}
        +		
        +		r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
        +		if (r < -1) goto end;
        +		if (r == 0)
        +			{
        +			/* m divides p */
        +			BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
        +			goto end;
        +			}
        +		}
        +	while (r == 1 && ++i < 82);
        +	
        +	if (r != -1)
        +		{
        +		/* Many rounds and still no non-square -- this is more likely
        +		 * a bug than just bad luck.
        +		 * Even if  p  is not prime, we should have found some  y
        +		 * such that r == -1.
        +		 */
        +		BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
        +		goto end;
        +		}
        +
        +	/* Here's our actual 'q': */
        +	if (!BN_rshift(q, q, e)) goto end;
        +
        +	/* Now that we have some non-square, we can find an element
        +	 * of order  2^e  by computing its q'th power. */
        +	if (!BN_mod_exp(y, y, q, p, ctx)) goto end;
        +	if (BN_is_one(y))
        +		{
        +		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
        +		goto end;
        +		}
        +
        +	/* Now we know that (if  p  is indeed prime) there is an integer
        +	 * k,  0 <= k < 2^e,  such that
        +	 *
        +	 *      a^q * y^k == 1   (mod p).
        +	 *
        +	 * As  a^q  is a square and  y  is not,  k  must be even.
        +	 * q+1  is even, too, so there is an element
        +	 *
        +	 *     X := a^((q+1)/2) * y^(k/2),
        +	 *
        +	 * and it satisfies
        +	 *
        +	 *     X^2 = a^q * a     * y^k
        +	 *         = a,
        +	 *
        +	 * so it is the square root that we are looking for.
        +	 */
        +	
        +	/* t := (q-1)/2  (note that  q  is odd) */
        +	if (!BN_rshift1(t, q)) goto end;
        +	
        +	/* x := a^((q-1)/2) */
        +	if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
        +		{
        +		if (!BN_nnmod(t, A, p, ctx)) goto end;
        +		if (BN_is_zero(t))
        +			{
        +			/* special case: a == 0  (mod p) */
        +			BN_zero(ret);
        +			err = 0;
        +			goto end;
        +			}
        +		else
        +			if (!BN_one(x)) goto end;
        +		}
        +	else
        +		{
        +		if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
        +		if (BN_is_zero(x))
        +			{
        +			/* special case: a == 0  (mod p) */
        +			BN_zero(ret);
        +			err = 0;
        +			goto end;
        +			}
        +		}
        +
        +	/* b := a*x^2  (= a^q) */
        +	if (!BN_mod_sqr(b, x, p, ctx)) goto end;
        +	if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
        +	
        +	/* x := a*x    (= a^((q+1)/2)) */
        +	if (!BN_mod_mul(x, x, A, p, ctx)) goto end;
        +
        +	while (1)
        +		{
        +		/* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
        +		 * where  E  refers to the original value of  e,  which we
        +		 * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
        +		 *
        +		 * We have  a*b = x^2,
        +		 *    y^2^(e-1) = -1,
        +		 *    b^2^(e-1) = 1.
        +		 */
        +
        +		if (BN_is_one(b))
        +			{
        +			if (!BN_copy(ret, x)) goto end;
        +			err = 0;
        +			goto vrfy;
        +			}
        +
        +
        +		/* find smallest  i  such that  b^(2^i) = 1 */
        +		i = 1;
        +		if (!BN_mod_sqr(t, b, p, ctx)) goto end;
        +		while (!BN_is_one(t))
        +			{
        +			i++;
        +			if (i == e)
        +				{
        +				BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
        +				goto end;
        +				}
        +			if (!BN_mod_mul(t, t, t, p, ctx)) goto end;
        +			}
        +		
        +
        +		/* t := y^2^(e - i - 1) */
        +		if (!BN_copy(t, y)) goto end;
        +		for (j = e - i - 1; j > 0; j--)
        +			{
        +			if (!BN_mod_sqr(t, t, p, ctx)) goto end;
        +			}
        +		if (!BN_mod_mul(y, t, t, p, ctx)) goto end;
        +		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
        +		if (!BN_mod_mul(b, b, y, p, ctx)) goto end;
        +		e = i;
        +		}
        +
        + vrfy:
        +	if (!err)
        +		{
        +		/* verify the result -- the input might have been not a square
        +		 * (test added in 0.9.8) */
        +		
        +		if (!BN_mod_sqr(x, ret, p, ctx))
        +			err = 1;
        +		
        +		if (!err && 0 != BN_cmp(x, A))
        +			{
        +			BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
        +			err = 1;
        +			}
        +		}
        +
        + end:
        +	if (err)
        +		{
        +		if (ret != NULL && ret != in)
        +			{
        +			BN_clear_free(ret);
        +			}
        +		ret = NULL;
        +		}
        +	BN_CTX_end(ctx);
        +	bn_check_top(ret);
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_word.c b/vendor/openssl/openssl/crypto/bn/bn_word.c
        new file mode 100644
        index 000000000..de83a15b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_word.c
        @@ -0,0 +1,238 @@
        +/* crypto/bn/bn_word.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
        +	{
        +#ifndef BN_LLONG
        +	BN_ULONG ret=0;
        +#else
        +	BN_ULLONG ret=0;
        +#endif
        +	int i;
        +
        +	if (w == 0)
        +		return (BN_ULONG)-1;
        +
        +	bn_check_top(a);
        +	w&=BN_MASK2;
        +	for (i=a->top-1; i>=0; i--)
        +		{
        +#ifndef BN_LLONG
        +		ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
        +		ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
        +#else
        +		ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
        +			(BN_ULLONG)w);
        +#endif
        +		}
        +	return((BN_ULONG)ret);
        +	}
        +
        +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
        +	{
        +	BN_ULONG ret = 0;
        +	int i, j;
        +
        +	bn_check_top(a);
        +	w &= BN_MASK2;
        +
        +	if (!w)
        +		/* actually this an error (division by zero) */
        +		return (BN_ULONG)-1;
        +	if (a->top == 0)
        +		return 0;
        +
        +	/* normalize input (so bn_div_words doesn't complain) */
        +	j = BN_BITS2 - BN_num_bits_word(w);
        +	w <<= j;
        +	if (!BN_lshift(a, a, j))
        +		return (BN_ULONG)-1;
        +
        +	for (i=a->top-1; i>=0; i--)
        +		{
        +		BN_ULONG l,d;
        +		
        +		l=a->d[i];
        +		d=bn_div_words(ret,l,w);
        +		ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
        +		a->d[i]=d;
        +		}
        +	if ((a->top > 0) && (a->d[a->top-1] == 0))
        +		a->top--;
        +	ret >>= j;
        +	bn_check_top(a);
        +	return(ret);
        +	}
        +
        +int BN_add_word(BIGNUM *a, BN_ULONG w)
        +	{
        +	BN_ULONG l;
        +	int i;
        +
        +	bn_check_top(a);
        +	w &= BN_MASK2;
        +
        +	/* degenerate case: w is zero */
        +	if (!w) return 1;
        +	/* degenerate case: a is zero */
        +	if(BN_is_zero(a)) return BN_set_word(a, w);
        +	/* handle 'a' when negative */
        +	if (a->neg)
        +		{
        +		a->neg=0;
        +		i=BN_sub_word(a,w);
        +		if (!BN_is_zero(a))
        +			a->neg=!(a->neg);
        +		return(i);
        +		}
        +	for (i=0;w!=0 && i<a->top;i++)
        +		{
        +		a->d[i] = l = (a->d[i]+w)&BN_MASK2;
        +		w = (w>l)?1:0;
        +		}
        +	if (w && i==a->top)
        +		{
        +		if (bn_wexpand(a,a->top+1) == NULL) return 0;
        +		a->top++;
        +		a->d[i]=w;
        +		}
        +	bn_check_top(a);
        +	return(1);
        +	}
        +
        +int BN_sub_word(BIGNUM *a, BN_ULONG w)
        +	{
        +	int i;
        +
        +	bn_check_top(a);
        +	w &= BN_MASK2;
        +
        +	/* degenerate case: w is zero */
        +	if (!w) return 1;
        +	/* degenerate case: a is zero */
        +	if(BN_is_zero(a))
        +		{
        +		i = BN_set_word(a,w);
        +		if (i != 0)
        +			BN_set_negative(a, 1);
        +		return i;
        +		}
        +	/* handle 'a' when negative */
        +	if (a->neg)
        +		{
        +		a->neg=0;
        +		i=BN_add_word(a,w);
        +		a->neg=1;
        +		return(i);
        +		}
        +
        +	if ((a->top == 1) && (a->d[0] < w))
        +		{
        +		a->d[0]=w-a->d[0];
        +		a->neg=1;
        +		return(1);
        +		}
        +	i=0;
        +	for (;;)
        +		{
        +		if (a->d[i] >= w)
        +			{
        +			a->d[i]-=w;
        +			break;
        +			}
        +		else
        +			{
        +			a->d[i]=(a->d[i]-w)&BN_MASK2;
        +			i++;
        +			w=1;
        +			}
        +		}
        +	if ((a->d[i] == 0) && (i == (a->top-1)))
        +		a->top--;
        +	bn_check_top(a);
        +	return(1);
        +	}
        +
        +int BN_mul_word(BIGNUM *a, BN_ULONG w)
        +	{
        +	BN_ULONG ll;
        +
        +	bn_check_top(a);
        +	w&=BN_MASK2;
        +	if (a->top)
        +		{
        +		if (w == 0)
        +			BN_zero(a);
        +		else
        +			{
        +			ll=bn_mul_words(a->d,a->d,a->top,w);
        +			if (ll)
        +				{
        +				if (bn_wexpand(a,a->top+1) == NULL) return(0);
        +				a->d[a->top++]=ll;
        +				}
        +			}
        +		}
        +	bn_check_top(a);
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bn_x931p.c b/vendor/openssl/openssl/crypto/bn/bn_x931p.c
        new file mode 100644
        index 000000000..04c5c874e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bn_x931p.c
        @@ -0,0 +1,272 @@
        +/* bn_x931p.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2005.
        + */
        +/* ====================================================================
        + * Copyright (c) 2005 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 <stdio.h>
        +#include <openssl/bn.h>
        +
        +/* X9.31 routines for prime derivation */
        +
        +/* X9.31 prime derivation. This is used to generate the primes pi
        + * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd
        + * integers.
        + */
        +
        +static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
        +			BN_GENCB *cb)
        +	{
        +	int i = 0;
        +	if (!BN_copy(pi, Xpi))
        +		return 0;
        +	if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
        +		return 0;
        +	for(;;)
        +		{
        +		i++;
        +		BN_GENCB_call(cb, 0, i);
        +		/* NB 27 MR is specificed in X9.31 */
        +		if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
        +			break;
        +		if (!BN_add_word(pi, 2))
        +			return 0;
        +		}
        +	BN_GENCB_call(cb, 2, i);
        +	return 1;
        +	}
        +
        +/* This is the main X9.31 prime derivation function. From parameters
        + * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are
        + * not NULL they will be returned too: this is needed for testing.
        + */
        +
        +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
        +			const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
        +			const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
        +	{
        +	int ret = 0;
        +
        +	BIGNUM *t, *p1p2, *pm1;
        +
        +	/* Only even e supported */
        +	if (!BN_is_odd(e))
        +		return 0;
        +
        +	BN_CTX_start(ctx);
        +	if (!p1)
        +		p1 = BN_CTX_get(ctx);
        +
        +	if (!p2)
        +		p2 = BN_CTX_get(ctx);
        +
        +	t = BN_CTX_get(ctx);
        +
        +	p1p2 = BN_CTX_get(ctx);
        +
        +	pm1 = BN_CTX_get(ctx);
        +
        +	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
        +		goto err;
        +
        +	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
        +		goto err;
        +
        +	if (!BN_mul(p1p2, p1, p2, ctx))
        +		goto err;
        +
        +	/* First set p to value of Rp */
        +
        +	if (!BN_mod_inverse(p, p2, p1, ctx))
        +		goto err;
        +
        +	if (!BN_mul(p, p, p2, ctx))
        +		goto err;
        +
        +	if (!BN_mod_inverse(t, p1, p2, ctx))
        +		goto err;
        +
        +	if (!BN_mul(t, t, p1, ctx))
        +		goto err;
        +
        +	if (!BN_sub(p, p, t))
        +		goto err;
        +
        +	if (p->neg && !BN_add(p, p, p1p2))
        +		goto err;
        +
        +	/* p now equals Rp */
        +
        +	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
        +		goto err;
        +
        +	if (!BN_add(p, p, Xp))
        +		goto err;
        +
        +	/* p now equals Yp0 */
        +
        +	for (;;)
        +		{
        +		int i = 1;
        +		BN_GENCB_call(cb, 0, i++);
        +		if (!BN_copy(pm1, p))
        +			goto err;
        +		if (!BN_sub_word(pm1, 1))
        +			goto err;
        +		if (!BN_gcd(t, pm1, e, ctx))
        +			goto err;
        +		if (BN_is_one(t)
        +		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
        +		 * offering similar or better guarantees 50 MR is considerably 
        +		 * better.
        +		 */
        +			&& BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
        +			break;
        +		if (!BN_add(p, p, p1p2))
        +			goto err;
        +		}
        +
        +	BN_GENCB_call(cb, 3, 0);
        +
        +	ret = 1;
        +
        +	err:
        +
        +	BN_CTX_end(ctx);
        +
        +	return ret;
        +	}
        +
        +/* Generate pair of paramters Xp, Xq for X9.31 prime generation.
        + * Note: nbits paramter is sum of number of bits in both.
        + */
        +
        +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
        +	{
        +	BIGNUM *t;
        +	int i;
        +	/* Number of bits for each prime is of the form
        +	 * 512+128s for s = 0, 1, ...
        +	 */
        +	if ((nbits < 1024) || (nbits & 0xff))
        +		return 0;
        +	nbits >>= 1;
        +	/* The random value Xp must be between sqrt(2) * 2^(nbits-1) and
        +	 * 2^nbits - 1. By setting the top two bits we ensure that the lower
        +	 * bound is exceeded.
        +	 */
        +	if (!BN_rand(Xp, nbits, 1, 0))
        +		return 0;
        +
        +	BN_CTX_start(ctx);
        +	t = BN_CTX_get(ctx);
        +
        +	for (i = 0; i < 1000; i++)
        +		{
        +		if (!BN_rand(Xq, nbits, 1, 0))
        +			return 0;
        +		/* Check that |Xp - Xq| > 2^(nbits - 100) */
        +		BN_sub(t, Xp, Xq);
        +		if (BN_num_bits(t) > (nbits - 100))
        +			break;
        +		}
        +
        +	BN_CTX_end(ctx);
        +
        +	if (i < 1000)
        +		return 1;
        +
        +	return 0;
        +
        +	}
        +
        +/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1
        + * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL
        + * the relevant parameter will be stored in it.
        + *
        + * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq
        + * are generated using the previous function and supplied as input.
        + */
        +
        +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
        +			BIGNUM *Xp1, BIGNUM *Xp2,
        +			const BIGNUM *Xp,
        +			const BIGNUM *e, BN_CTX *ctx,
        +			BN_GENCB *cb)
        +	{
        +	int ret = 0;
        +
        +	BN_CTX_start(ctx);
        +	if (!Xp1)
        +		Xp1 = BN_CTX_get(ctx);
        +	if (!Xp2)
        +		Xp2 = BN_CTX_get(ctx);
        +
        +	if (!BN_rand(Xp1, 101, 0, 0))
        +		goto error;
        +	if (!BN_rand(Xp2, 101, 0, 0))
        +		goto error;
        +	if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
        +		goto error;
        +
        +	ret = 1;
        +
        +	error:
        +	BN_CTX_end(ctx);
        +
        +	return ret;
        +
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bnspeed.c b/vendor/openssl/openssl/crypto/bn/bnspeed.c
        new file mode 100644
        index 000000000..b554ac8cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bnspeed.c
        @@ -0,0 +1,233 @@
        +/* unused */
        +
        +/* crypto/bn/bnspeed.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.]
        + */
        +
        +/* most of this code has been pilfered from my libdes speed.c program */
        +
        +#define BASENUM	1000000
        +#undef PROG
        +#define PROG bnspeed_main
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <signal.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/bn.h>
        +#include <openssl/x509.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +# ifndef CLK_TCK
        +#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
        +#   define HZ	100.0
        +#  else /* _BSD_CLK_TCK_ */
        +#   define HZ ((double)_BSD_CLK_TCK_)
        +#  endif
        +# else /* CLK_TCK */
        +#  define HZ ((double)CLK_TCK)
        +# endif
        +#endif
        +
        +#undef BUFSIZE
        +#define BUFSIZE	((long)1024*8)
        +int run=0;
        +
        +static double Time_F(int s);
        +#define START	0
        +#define STOP	1
        +
        +static double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret < 1e-3)?1e-3:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
        +		return((ret < 0.001)?0.001:ret);
        +		}
        +#endif
        +	}
        +
        +#define NUM_SIZES	5
        +static int sizes[NUM_SIZES]={128,256,512,1024,2048};
        +/*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
        +
        +void do_mul(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx); 
        +
        +int main(int argc, char **argv)
        +	{
        +	BN_CTX *ctx;
        +	BIGNUM a,b,c;
        +
        +	ctx=BN_CTX_new();
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	do_mul(&a,&b,&c,ctx);
        +	}
        +
        +void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int i,j,k;
        +	double tm;
        +	long num;
        +
        +	for (i=0; i<NUM_SIZES; i++)
        +		{
        +		num=BASENUM;
        +		if (i) num/=(i*3);
        +		BN_rand(a,sizes[i],1,0);
        +		for (j=i; j<NUM_SIZES; j++)
        +			{
        +			BN_rand(b,sizes[j],1,0);
        +			Time_F(START);
        +			for (k=0; k<num; k++)
        +				BN_mul(r,b,a,ctx);
        +			tm=Time_F(STOP);
        +			printf("mul %4d x %4d -> %8.3fms\n",sizes[i],sizes[j],tm*1000.0/num);
        +			}
        +		}
        +
        +	for (i=0; i<NUM_SIZES; i++)
        +		{
        +		num=BASENUM;
        +		if (i) num/=(i*3);
        +		BN_rand(a,sizes[i],1,0);
        +		Time_F(START);
        +		for (k=0; k<num; k++)
        +			BN_sqr(r,a,ctx);
        +		tm=Time_F(STOP);
        +		printf("sqr %4d x %4d -> %8.3fms\n",sizes[i],sizes[i],tm*1000.0/num);
        +		}
        +
        +	for (i=0; i<NUM_SIZES; i++)
        +		{
        +		num=BASENUM/10;
        +		if (i) num/=(i*3);
        +		BN_rand(a,sizes[i]-1,1,0);
        +		for (j=i; j<NUM_SIZES; j++)
        +			{
        +			BN_rand(b,sizes[j],1,0);
        +			Time_F(START);
        +			for (k=0; k<100000; k++)
        +				BN_div(r, NULL, b, a,ctx);
        +			tm=Time_F(STOP);
        +			printf("div %4d / %4d -> %8.3fms\n",sizes[j],sizes[i]-1,tm*1000.0/num);
        +			}
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/bntest.c b/vendor/openssl/openssl/crypto/bn/bntest.c
        new file mode 100644
        index 000000000..06f5954ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/bntest.c
        @@ -0,0 +1,2013 @@
        +/* crypto/bn/bntest.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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the Eric Young open source
        + * license provided above.
        + *
        + * The binary polynomial arithmetic software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +
        +const int num0 = 100; /* number of tests */
        +const int num1 = 50;  /* additional tests for some functions */
        +const int num2 = 5;   /* number of tests for slow functions */
        +
        +int test_add(BIO *bp);
        +int test_sub(BIO *bp);
        +int test_lshift1(BIO *bp);
        +int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
        +int test_rshift1(BIO *bp);
        +int test_rshift(BIO *bp,BN_CTX *ctx);
        +int test_div(BIO *bp,BN_CTX *ctx);
        +int test_div_word(BIO *bp);
        +int test_div_recp(BIO *bp,BN_CTX *ctx);
        +int test_mul(BIO *bp);
        +int test_sqr(BIO *bp,BN_CTX *ctx);
        +int test_mont(BIO *bp,BN_CTX *ctx);
        +int test_mod(BIO *bp,BN_CTX *ctx);
        +int test_mod_mul(BIO *bp,BN_CTX *ctx);
        +int test_mod_exp(BIO *bp,BN_CTX *ctx);
        +int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
        +int test_exp(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_add(BIO *bp);
        +int test_gf2m_mod(BIO *bp);
        +int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
        +int test_kron(BIO *bp,BN_CTX *ctx);
        +int test_sqrt(BIO *bp,BN_CTX *ctx);
        +int rand_neg(void);
        +static int results=0;
        +
        +static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
        +"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +static void message(BIO *out, char *m)
        +	{
        +	fprintf(stderr, "test %s\n", m);
        +	BIO_puts(out, "print \"test ");
        +	BIO_puts(out, m);
        +	BIO_puts(out, "\\n\"\n");
        +	}
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_CTX *ctx;
        +	BIO *out;
        +	char *outfile=NULL;
        +
        +	results = 0;
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if (strcmp(*argv,"-results") == 0)
        +			results=1;
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) break;
        +			outfile= *(++argv);
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) EXIT(1);
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) EXIT(1);
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +		}
        +	else
        +		{
        +		if (!BIO_write_filename(out,outfile))
        +			{
        +			perror(outfile);
        +			EXIT(1);
        +			}
        +		}
        +
        +	if (!results)
        +		BIO_puts(out,"obase=16\nibase=16\n");
        +
        +	message(out,"BN_add");
        +	if (!test_add(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_sub");
        +	if (!test_sub(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_lshift1");
        +	if (!test_lshift1(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_lshift (fixed)");
        +	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
        +	    goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_lshift");
        +	if (!test_lshift(out,ctx,NULL)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_rshift1");
        +	if (!test_rshift1(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_rshift");
        +	if (!test_rshift(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_sqr");
        +	if (!test_sqr(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mul");
        +	if (!test_mul(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_div");
        +	if (!test_div(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_div_word");
        +	if (!test_div_word(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_div_recp");
        +	if (!test_div_recp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod");
        +	if (!test_mod(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_mul");
        +	if (!test_mod_mul(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mont");
        +	if (!test_mont(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_exp");
        +	if (!test_mod_exp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_exp_mont_consttime");
        +	if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_exp");
        +	if (!test_exp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_kronecker");
        +	if (!test_kron(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_sqrt");
        +	if (!test_sqrt(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +#ifndef OPENSSL_NO_EC2M
        +	message(out,"BN_GF2m_add");
        +	if (!test_gf2m_add(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod");
        +	if (!test_gf2m_mod(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_mul");
        +	if (!test_gf2m_mod_mul(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_sqr");
        +	if (!test_gf2m_mod_sqr(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_inv");
        +	if (!test_gf2m_mod_inv(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_div");
        +	if (!test_gf2m_mod_div(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_exp");
        +	if (!test_gf2m_mod_exp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_sqrt");
        +	if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_solve_quad");
        +	if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +#endif
        +	BN_CTX_free(ctx);
        +	BIO_free(out);
        +
        +/**/
        +	EXIT(0);
        +err:
        +	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
        +	                      * the failure, see test_bn in test/Makefile.ssl*/
        +	(void)BIO_flush(out);
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	EXIT(1);
        +	return(1);
        +	}
        +
        +int test_add(BIO *bp)
        +	{
        +	BIGNUM a,b,c;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	BN_bntest_rand(&a,512,0,0);
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(&b,450+i,0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_add(&c,&a,&b);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," + ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		a.neg=!a.neg;
        +		b.neg=!b.neg;
        +		BN_add(&c,&c,&b);
        +		BN_add(&c,&c,&a);
        +		if(!BN_is_zero(&c))
        +		    {
        +		    fprintf(stderr,"Add test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	return(1);
        +	}
        +
        +int test_sub(BIO *bp)
        +	{
        +	BIGNUM a,b,c;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i < num1)
        +			{
        +			BN_bntest_rand(&a,512,0,0);
        +			BN_copy(&b,&a);
        +			if (BN_set_bit(&a,i)==0) return(0);
        +			BN_add_word(&b,i);
        +			}
        +		else
        +			{
        +			BN_bntest_rand(&b,400+i-num1,0,0);
        +			a.neg=rand_neg();
        +			b.neg=rand_neg();
        +			}
        +		BN_sub(&c,&a,&b);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," - ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_add(&c,&c,&b);
        +		BN_sub(&c,&c,&a);
        +		if(!BN_is_zero(&c))
        +		    {
        +		    fprintf(stderr,"Subtract test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	return(1);
        +	}
        +
        +int test_div(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,b,c,d,e;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i < num1)
        +			{
        +			BN_bntest_rand(&a,400,0,0);
        +			BN_copy(&b,&a);
        +			BN_lshift(&a,&a,i);
        +			BN_add_word(&a,i);
        +			}
        +		else
        +			BN_bntest_rand(&b,50+3*(i-num1),0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_div(&d,&c,&a,&b,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," / ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&d);
        +			BIO_puts(bp,"\n");
        +
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(&e,&d,&b,ctx);
        +		BN_add(&d,&e,&c);
        +		BN_sub(&d,&d,&a);
        +		if(!BN_is_zero(&d))
        +		    {
        +		    fprintf(stderr,"Division test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	return(1);
        +	}
        +
        +static void print_word(BIO *bp,BN_ULONG w)
        +	{
        +#ifdef SIXTY_FOUR_BIT
        +	if (sizeof(w) > sizeof(unsigned long))
        +		{
        +		unsigned long	h=(unsigned long)(w>>32),
        +				l=(unsigned long)(w);
        +
        +		if (h)	BIO_printf(bp,"%lX%08lX",h,l);
        +		else	BIO_printf(bp,"%lX",l);
        +		return;
        +		}
        +#endif
        +	BIO_printf(bp,BN_HEX_FMT1,w);
        +	}
        +
        +int test_div_word(BIO *bp)
        +	{
        +	BIGNUM   a,b;
        +	BN_ULONG r,s;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		do {
        +			BN_bntest_rand(&a,512,-1,0);
        +			BN_bntest_rand(&b,BN_BITS2,-1,0);
        +			s = b.d[0];
        +		} while (!s);
        +
        +		BN_copy(&b, &a);
        +		r = BN_div_word(&b, s);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," / ");
        +				print_word(bp,s);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&b);
        +			BIO_puts(bp,"\n");
        +
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," % ");
        +				print_word(bp,s);
        +				BIO_puts(bp," - ");
        +				}
        +			print_word(bp,r);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul_word(&b,s);
        +		BN_add_word(&b,r);
        +		BN_sub(&b,&a,&b);
        +		if(!BN_is_zero(&b))
        +		    {
        +		    fprintf(stderr,"Division (word) test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	return(1);
        +	}
        +
        +int test_div_recp(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,b,c,d,e;
        +	BN_RECP_CTX recp;
        +	int i;
        +
        +	BN_RECP_CTX_init(&recp);
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i < num1)
        +			{
        +			BN_bntest_rand(&a,400,0,0);
        +			BN_copy(&b,&a);
        +			BN_lshift(&a,&a,i);
        +			BN_add_word(&a,i);
        +			}
        +		else
        +			BN_bntest_rand(&b,50+3*(i-num1),0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_RECP_CTX_set(&recp,&b,ctx);
        +		BN_div_recp(&d,&c,&a,&recp,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," / ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&d);
        +			BIO_puts(bp,"\n");
        +
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(&e,&d,&b,ctx);
        +		BN_add(&d,&e,&c);
        +		BN_sub(&d,&d,&a);
        +		if(!BN_is_zero(&d))
        +		    {
        +		    fprintf(stderr,"Reciprocal division test failed!\n");
        +		    fprintf(stderr,"a=");
        +		    BN_print_fp(stderr,&a);
        +		    fprintf(stderr,"\nb=");
        +		    BN_print_fp(stderr,&b);
        +		    fprintf(stderr,"\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	BN_RECP_CTX_free(&recp);
        +	return(1);
        +	}
        +
        +int test_mul(BIO *bp)
        +	{
        +	BIGNUM a,b,c,d,e;
        +	int i;
        +	BN_CTX *ctx;
        +
        +	ctx = BN_CTX_new();
        +	if (ctx == NULL) EXIT(1);
        +	
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i <= num1)
        +			{
        +			BN_bntest_rand(&a,100,0,0);
        +			BN_bntest_rand(&b,100,0,0);
        +			}
        +		else
        +			BN_bntest_rand(&b,i-num1,0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_mul(&c,&a,&b,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(&d,&e,&c,&a,ctx);
        +		BN_sub(&d,&d,&b);
        +		if(!BN_is_zero(&d) || !BN_is_zero(&e))
        +		    {
        +		    fprintf(stderr,"Multiplication test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	BN_CTX_free(ctx);
        +	return(1);
        +	}
        +
        +int test_sqr(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,c,d,e;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(&a,40+i*10,0,0);
        +		a.neg=rand_neg();
        +		BN_sqr(&c,&a,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,&a);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(&d,&e,&c,&a,ctx);
        +		BN_sub(&d,&d,&a);
        +		if(!BN_is_zero(&d) || !BN_is_zero(&e))
        +		    {
        +		    fprintf(stderr,"Square test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	return(1);
        +	}
        +
        +int test_mont(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,b,c,d,A,B;
        +	BIGNUM n;
        +	int i;
        +	BN_MONT_CTX *mont;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&A);
        +	BN_init(&B);
        +	BN_init(&n);
        +
        +	mont=BN_MONT_CTX_new();
        +	if (mont == NULL)
        +		return 0;
        +
        +	BN_bntest_rand(&a,100,0,0); /**/
        +	BN_bntest_rand(&b,100,0,0); /**/
        +	for (i=0; i<num2; i++)
        +		{
        +		int bits = (200*(i+1))/num2;
        +
        +		if (bits == 0)
        +			continue;
        +		BN_bntest_rand(&n,bits,0,1);
        +		BN_MONT_CTX_set(mont,&n,ctx);
        +
        +		BN_nnmod(&a,&a,&n,ctx);
        +		BN_nnmod(&b,&b,&n,ctx);
        +
        +		BN_to_montgomery(&A,&a,mont,ctx);
        +		BN_to_montgomery(&B,&b,mont,ctx);
        +
        +		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
        +		BN_from_montgomery(&A,&c,mont,ctx);/**/
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +#ifdef undef
        +fprintf(stderr,"%d * %d %% %d\n",
        +BN_num_bits(&a),
        +BN_num_bits(&b),
        +BN_num_bits(mont->N));
        +#endif
        +				BN_print(bp,&a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,&(mont->N));
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&A);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mod_mul(&d,&a,&b,&n,ctx);
        +		BN_sub(&d,&d,&A);
        +		if(!BN_is_zero(&d))
        +		    {
        +		    fprintf(stderr,"Montgomery multiplication test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_MONT_CTX_free(mont);
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&A);
        +	BN_free(&B);
        +	BN_free(&n);
        +	return(1);
        +	}
        +
        +int test_mod(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_bntest_rand(a,1024,0,0); /**/
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(b,450+i*10,0,0); /**/
        +		a->neg=rand_neg();
        +		b->neg=rand_neg();
        +		BN_mod(c,a,b,ctx);/**/
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(d,e,a,b,ctx);
        +		BN_sub(e,e,c);
        +		if(!BN_is_zero(e))
        +		    {
        +		    fprintf(stderr,"Modulo test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_mod_mul(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i,j;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	for (j=0; j<3; j++) {
        +	BN_bntest_rand(c,1024,0,0); /**/
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a,475+i*10,0,0); /**/
        +		BN_bntest_rand(b,425+i*11,0,0); /**/
        +		a->neg=rand_neg();
        +		b->neg=rand_neg();
        +		if (!BN_mod_mul(e,a,b,c,ctx))
        +			{
        +			unsigned long l;
        +
        +			while ((l=ERR_get_error()))
        +				fprintf(stderr,"ERROR:%s\n",
        +					ERR_error_string(l,NULL));
        +			EXIT(1);
        +			}
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,c);
        +				if ((a->neg ^ b->neg) && !BN_is_zero(e))
        +					{
        +					/* If  (a*b) % c  is negative,  c  must be added
        +					 * in order to obtain the normalized remainder
        +					 * (new with OpenSSL 0.9.7, previous versions of
        +					 * BN_mod_mul could generate negative results)
        +					 */
        +					BIO_puts(bp," + ");
        +					BN_print(bp,c);
        +					}
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,e);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(d,a,b,ctx);
        +		BN_sub(d,d,e);
        +		BN_div(a,b,d,c,ctx);
        +		if(!BN_is_zero(b))
        +		    {
        +		    fprintf(stderr,"Modulo multiply test failed!\n");
        +		    ERR_print_errors_fp(stderr);
        +		    return 0;
        +		    }
        +		}
        +	}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_mod_exp(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
        +	for (i=0; i<num2; i++)
        +		{
        +		BN_bntest_rand(a,20+i*5,0,0); /**/
        +		BN_bntest_rand(b,2+i,0,0); /**/
        +
        +		if (!BN_mod_exp(d,a,b,c,ctx))
        +			return(0);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,d);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_exp(e,a,b,ctx);
        +		BN_sub(e,e,d);
        +		BN_div(a,b,e,c,ctx);
        +		if(!BN_is_zero(b))
        +		    {
        +		    fprintf(stderr,"Modulo exponentiation test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
        +	for (i=0; i<num2; i++)
        +		{
        +		BN_bntest_rand(a,20+i*5,0,0); /**/
        +		BN_bntest_rand(b,2+i,0,0); /**/
        +
        +		if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
        +			return(00);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,d);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_exp(e,a,b,ctx);
        +		BN_sub(e,e,d);
        +		BN_div(a,b,e,c,ctx);
        +		if(!BN_is_zero(b))
        +		    {
        +		    fprintf(stderr,"Modulo exponentiation test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_exp(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*d,*e,*one;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	one=BN_new();
        +	BN_one(one);
        +
        +	for (i=0; i<num2; i++)
        +		{
        +		BN_bntest_rand(a,20+i*5,0,0); /**/
        +		BN_bntest_rand(b,2+i,0,0); /**/
        +
        +		if (BN_exp(d,a,b,ctx) <= 0)
        +			return(0);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,d);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_one(e);
        +		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
        +		    BN_mul(e,e,a,ctx);
        +		BN_sub(e,e,d);
        +		if(!BN_is_zero(e))
        +		    {
        +		    fprintf(stderr,"Exponentiation test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(one);
        +	return(1);
        +	}
        +#ifndef OPENSSL_NO_EC2M
        +int test_gf2m_add(BIO *bp)
        +	{
        +	BIGNUM a,b,c;
        +	int i, ret = 0;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_rand(&a,512,0,0);
        +		BN_copy(&b, BN_value_one());
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_GF2m_add(&c,&a,&b);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," = ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +#endif
        +		/* Test that two added values have the correct parity. */
        +		if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
        +			{
        +		    fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
        +			goto err;
        +			}
        +		BN_GF2m_add(&c,&c,&c);
        +		/* Test that c + c = 0. */
        +		if(!BN_is_zero(&c))
        +		    {
        +		    fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
        +			goto err;
        +		    }
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod(BIO *bp)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 1024, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod(c, a, b[j]);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp," % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp," - ");
        +					BN_print(bp,c);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(d, a, c);
        +			BN_GF2m_mod(e, d, b[j]);
        +			/* Test that a + (a mod p) mod p == 0. */
        +			if(!BN_is_zero(e))
        +				{
        +				fprintf(stderr,"GF(2^m) modulo test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +	g=BN_new();
        +	h=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 1024, 0, 0);
        +		BN_bntest_rand(c, 1024, 0, 0);
        +		BN_bntest_rand(d, 1024, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_mul(e, a, c, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp," * ");
        +					BN_print(bp,c);
        +					BIO_puts(bp," % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp," - ");
        +					BN_print(bp,e);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(f, a, d);
        +			BN_GF2m_mod_mul(g, f, c, b[j], ctx);
        +			BN_GF2m_mod_mul(h, d, c, b[j], ctx);
        +			BN_GF2m_add(f, e, g);
        +			BN_GF2m_add(f, f, h);
        +			/* Test that (a+d)*c = a*c + d*c. */
        +			if(!BN_is_zero(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	BN_free(g);
        +	BN_free(h);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 1024, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_sqr(c, a, b[j], ctx);
        +			BN_copy(d, a);
        +			BN_GF2m_mod_mul(d, a, d, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp," ^ 2 % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp, " = ");
        +					BN_print(bp,c);
        +					BIO_puts(bp,"; a * a = ");
        +					BN_print(bp,d);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(d, c, d);
        +			/* Test that a*a = a^2. */
        +			if(!BN_is_zero(d))
        +				{
        +				fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0); 
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_inv(c, a, b[j], ctx);
        +			BN_GF2m_mod_mul(d, a, c, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp, " * ");
        +					BN_print(bp,c);
        +					BIO_puts(bp," - 1 % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			/* Test that ((1/a)*a) = 1. */
        +			if(!BN_is_one(d))
        +				{
        +				fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0); 
        +		BN_bntest_rand(c, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_div(d, a, c, b[j], ctx);
        +			BN_GF2m_mod_mul(e, d, c, b[j], ctx);
        +			BN_GF2m_mod_div(f, a, e, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp, " = ");
        +					BN_print(bp,c);
        +					BIO_puts(bp," * ");
        +					BN_print(bp,d);
        +					BIO_puts(bp, " % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			/* Test that ((a/c)*c)/a = 1. */
        +			if(!BN_is_one(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular division test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0);
        +		BN_bntest_rand(c, 512, 0, 0);
        +		BN_bntest_rand(d, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_exp(e, a, c, b[j], ctx);
        +			BN_GF2m_mod_exp(f, a, d, b[j], ctx);
        +			BN_GF2m_mod_mul(e, e, f, b[j], ctx);
        +			BN_add(f, c, d);
        +			BN_GF2m_mod_exp(f, a, f, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp, " ^ (");
        +					BN_print(bp,c);
        +					BIO_puts(bp," + ");
        +					BN_print(bp,d);
        +					BIO_puts(bp, ") = ");
        +					BN_print(bp,e);
        +					BIO_puts(bp, "; - ");
        +					BN_print(bp,f);
        +					BIO_puts(bp, " % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(f, e, f);
        +			/* Test that a^(c+d)=a^c*a^d. */
        +			if(!BN_is_zero(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod(c, a, b[j]);
        +			BN_GF2m_mod_sqrt(d, a, b[j], ctx);
        +			BN_GF2m_mod_sqr(e, d, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,d);
        +					BIO_puts(bp, " ^ 2 - ");
        +					BN_print(bp,a);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(f, c, e);
        +			/* Test that d^2 = a, where d = sqrt(a). */
        +			if(!BN_is_zero(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular square root test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e;
        +	int i, j, s = 0, t, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
        +			if (t)
        +				{
        +				s++;
        +				BN_GF2m_mod_sqr(d, c, b[j], ctx);
        +				BN_GF2m_add(d, c, d);
        +				BN_GF2m_mod(e, a, b[j]);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +				if (bp != NULL)
        +					{
        +					if (!results)
        +						{
        +						BN_print(bp,c);
        +						BIO_puts(bp, " is root of z^2 + z = ");
        +						BN_print(bp,a);
        +						BIO_puts(bp, " % ");
        +						BN_print(bp,b[j]);
        +						BIO_puts(bp, "\n");
        +						}
        +					}
        +#endif
        +				BN_GF2m_add(e, e, d);
        +				/* Test that solution of quadratic c satisfies c^2 + c = a. */
        +				if(!BN_is_zero(e))
        +					{
        +					fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
        +					goto err;
        +					}
        +
        +				}
        +			else 
        +				{
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +				if (bp != NULL)
        +					{
        +					if (!results)
        +						{
        +						BIO_puts(bp, "There are no roots of z^2 + z = ");
        +						BN_print(bp,a);
        +						BIO_puts(bp, " % ");
        +						BN_print(bp,b[j]);
        +						BIO_puts(bp, "\n");
        +						}
        +					}
        +#endif
        +				}
        +			}
        +		}
        +	if (s == 0)
        +		{	
        +		fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
        +		fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
        +		goto err;
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return ret;
        +	}
        +#endif
        +static int genprime_cb(int p, int n, BN_GENCB *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	putc(c, stderr);
        +	fflush(stderr);
        +	return 1;
        +	}
        +
        +int test_kron(BIO *bp, BN_CTX *ctx)
        +	{
        +	BN_GENCB cb;
        +	BIGNUM *a,*b,*r,*t;
        +	int i;
        +	int legendre, kronecker;
        +	int ret = 0;
        +
        +	a = BN_new();
        +	b = BN_new();
        +	r = BN_new();
        +	t = BN_new();
        +	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
        +
        +	BN_GENCB_set(&cb, genprime_cb, NULL);
        +	
        +	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
        +	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
        +	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
        +	 * So we generate a random prime  b  and compare these values
        +	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
        +	 * primality test to confirm that  b  is prime, except that we
        +	 * don't want to test whether  b  is prime but whether BN_kronecker
        +	 * works.) */
        +
        +	if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
        +	b->neg = rand_neg();
        +	putc('\n', stderr);
        +
        +	for (i = 0; i < num0; i++)
        +		{
        +		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
        +		a->neg = rand_neg();
        +
        +		/* t := (|b|-1)/2  (note that b is odd) */
        +		if (!BN_copy(t, b)) goto err;
        +		t->neg = 0;
        +		if (!BN_sub_word(t, 1)) goto err;
        +		if (!BN_rshift1(t, t)) goto err;
        +		/* r := a^t mod b */
        +		b->neg=0;
        +		
        +		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
        +		b->neg=1;
        +
        +		if (BN_is_word(r, 1))
        +			legendre = 1;
        +		else if (BN_is_zero(r))
        +			legendre = 0;
        +		else
        +			{
        +			if (!BN_add_word(r, 1)) goto err;
        +			if (0 != BN_ucmp(r, b))
        +				{
        +				fprintf(stderr, "Legendre symbol computation failed\n");
        +				goto err;
        +				}
        +			legendre = -1;
        +			}
        +		
        +		kronecker = BN_kronecker(a, b, ctx);
        +		if (kronecker < -1) goto err;
        +		/* we actually need BN_kronecker(a, |b|) */
        +		if (a->neg && b->neg)
        +			kronecker = -kronecker;
        +		
        +		if (legendre != kronecker)
        +			{
        +			fprintf(stderr, "legendre != kronecker; a = ");
        +			BN_print_fp(stderr, a);
        +			fprintf(stderr, ", b = ");
        +			BN_print_fp(stderr, b);
        +			fprintf(stderr, "\n");
        +			goto err;
        +			}
        +
        +		putc('.', stderr);
        +		fflush(stderr);
        +		}
        +
        +	putc('\n', stderr);
        +	fflush(stderr);
        +	ret = 1;
        + err:
        +	if (a != NULL) BN_free(a);
        +	if (b != NULL) BN_free(b);
        +	if (r != NULL) BN_free(r);
        +	if (t != NULL) BN_free(t);
        +	return ret;
        +	}
        +
        +int test_sqrt(BIO *bp, BN_CTX *ctx)
        +	{
        +	BN_GENCB cb;
        +	BIGNUM *a,*p,*r;
        +	int i, j;
        +	int ret = 0;
        +
        +	a = BN_new();
        +	p = BN_new();
        +	r = BN_new();
        +	if (a == NULL || p == NULL || r == NULL) goto err;
        +
        +	BN_GENCB_set(&cb, genprime_cb, NULL);
        +
        +	for (i = 0; i < 16; i++)
        +		{
        +		if (i < 8)
        +			{
        +			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
        +			
        +			if (!BN_set_word(p, primes[i])) goto err;
        +			}
        +		else
        +			{
        +			if (!BN_set_word(a, 32)) goto err;
        +			if (!BN_set_word(r, 2*i + 1)) goto err;
        +		
        +			if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
        +			putc('\n', stderr);
        +			}
        +		p->neg = rand_neg();
        +
        +		for (j = 0; j < num2; j++)
        +			{
        +			/* construct 'a' such that it is a square modulo p,
        +			 * but in general not a proper square and not reduced modulo p */
        +			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
        +			if (!BN_nnmod(r, r, p, ctx)) goto err;
        +			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
        +			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
        +			if (!BN_nnmod(a, a, p, ctx)) goto err;
        +			if (!BN_mod_sqr(a, a, p, ctx)) goto err;
        +			if (!BN_mul(a, a, r, ctx)) goto err;
        +			if (rand_neg())
        +				if (!BN_sub(a, a, p)) goto err;
        +
        +			if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
        +			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
        +
        +			if (!BN_nnmod(a, a, p, ctx)) goto err;
        +
        +			if (BN_cmp(a, r) != 0)
        +				{
        +				fprintf(stderr, "BN_mod_sqrt failed: a = ");
        +				BN_print_fp(stderr, a);
        +				fprintf(stderr, ", r = ");
        +				BN_print_fp(stderr, r);
        +				fprintf(stderr, ", p = ");
        +				BN_print_fp(stderr, p);
        +				fprintf(stderr, "\n");
        +				goto err;
        +				}
        +
        +			putc('.', stderr);
        +			fflush(stderr);
        +			}
        +		
        +		putc('\n', stderr);
        +		fflush(stderr);
        +		}
        +	ret = 1;
        + err:
        +	if (a != NULL) BN_free(a);
        +	if (p != NULL) BN_free(p);
        +	if (r != NULL) BN_free(r);
        +	return ret;
        +	}
        +
        +int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
        +	{
        +	BIGNUM *a,*b,*c,*d;
        +	int i;
        +
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	BN_one(c);
        +
        +	if(a_)
        +	    a=a_;
        +	else
        +	    {
        +	    a=BN_new();
        +	    BN_bntest_rand(a,200,0,0); /**/
        +	    a->neg=rand_neg();
        +	    }
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_lshift(b,a,i+1);
        +		BN_add(c,c,c);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(d,a,c,ctx);
        +		BN_sub(d,d,b);
        +		if(!BN_is_zero(d))
        +		    {
        +		    fprintf(stderr,"Left shift test failed!\n");
        +		    fprintf(stderr,"a=");
        +		    BN_print_fp(stderr,a);
        +		    fprintf(stderr,"\nb=");
        +		    BN_print_fp(stderr,b);
        +		    fprintf(stderr,"\nc=");
        +		    BN_print_fp(stderr,c);
        +		    fprintf(stderr,"\nd=");
        +		    BN_print_fp(stderr,d);
        +		    fprintf(stderr,"\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	return(1);
        +	}
        +
        +int test_lshift1(BIO *bp)
        +	{
        +	BIGNUM *a,*b,*c;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +
        +	BN_bntest_rand(a,200,0,0); /**/
        +	a->neg=rand_neg();
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_lshift1(b,a);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," * 2");
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_add(c,a,a);
        +		BN_sub(a,b,c);
        +		if(!BN_is_zero(a))
        +		    {
        +		    fprintf(stderr,"Left shift one test failed!\n");
        +		    return 0;
        +		    }
        +		
        +		BN_copy(a,b);
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	return(1);
        +	}
        +
        +int test_rshift(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	BN_one(c);
        +
        +	BN_bntest_rand(a,200,0,0); /**/
        +	a->neg=rand_neg();
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_rshift(b,a,i+1);
        +		BN_add(c,c,c);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," / ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(d,e,a,c,ctx);
        +		BN_sub(d,d,b);
        +		if(!BN_is_zero(d))
        +		    {
        +		    fprintf(stderr,"Right shift test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_rshift1(BIO *bp)
        +	{
        +	BIGNUM *a,*b,*c;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +
        +	BN_bntest_rand(a,200,0,0); /**/
        +	a->neg=rand_neg();
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_rshift1(b,a);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," / 2");
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_sub(c,a,b);
        +		BN_sub(c,c,b);
        +		if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
        +		    {
        +		    fprintf(stderr,"Right shift one test failed!\n");
        +		    return 0;
        +		    }
        +		BN_copy(a,b);
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	return(1);
        +	}
        +
        +int rand_neg(void)
        +	{
        +	static unsigned int neg=0;
        +	static int sign[8]={0,0,0,1,1,0,1,1};
        +
        +	return(sign[(neg++)%8]);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/divtest.c b/vendor/openssl/openssl/crypto/bn/divtest.c
        new file mode 100644
        index 000000000..d3fc688f3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/divtest.c
        @@ -0,0 +1,41 @@
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +
        +static int Rand(n)
        +{
        +    unsigned char x[2];
        +    RAND_pseudo_bytes(x,2);
        +    return (x[0] + 2*x[1]);
        +}
        +
        +static void bug(char *m, BIGNUM *a, BIGNUM *b)
        +{
        +    printf("%s!\na=",m);
        +    BN_print_fp(stdout, a);
        +    printf("\nb=");
        +    BN_print_fp(stdout, b);
        +    printf("\n");
        +    fflush(stdout);
        +}
        +
        +main()
        +{
        +    BIGNUM *a=BN_new(), *b=BN_new(), *c=BN_new(), *d=BN_new(),
        +	*C=BN_new(), *D=BN_new();
        +    BN_RECP_CTX *recp=BN_RECP_CTX_new();
        +    BN_CTX *ctx=BN_CTX_new();
        +
        +    for(;;) {
        +	BN_pseudo_rand(a,Rand(),0,0);
        +	BN_pseudo_rand(b,Rand(),0,0);
        +	if (BN_is_zero(b)) continue;
        +
        +	BN_RECP_CTX_set(recp,b,ctx);
        +	if (BN_div(C,D,a,b,ctx) != 1)
        +	    bug("BN_div failed",a,b);
        +	if (BN_div_recp(c,d,a,recp,ctx) != 1)
        +	    bug("BN_div_recp failed",a,b);
        +	else if (BN_cmp(c,C) != 0 || BN_cmp(c,C) != 0)
        +	    bug("mismatch",a,b);
        +    }
        +}
        diff --git a/vendor/openssl/openssl/crypto/bn/exp.c b/vendor/openssl/openssl/crypto/bn/exp.c
        new file mode 100644
        index 000000000..4865b0ef7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/exp.c
        @@ -0,0 +1,62 @@
        +/* unused */
        +
        +#include <stdio.h>
        +#include <openssl/tmdiff.h>
        +#include "bn_lcl.h"
        +
        +#define SIZE	256
        +#define NUM	(8*8*8)
        +#define MOD	(8*8*8*8*8)
        +
        +main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	BN_CTX ctx;
        +	BIGNUM a,b,c,r,rr,t,l;
        +	int j,i,size=SIZE,num=NUM,mod=MOD;
        +	char *start,*end;
        +	BN_MONT_CTX mont;
        +	double d,md;
        +
        +	BN_MONT_CTX_init(&mont);
        +	BN_CTX_init(&ctx);
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&r);
        +
        +	start=ms_time_new();
        +	end=ms_time_new();
        +	while (size <= 1024*8)
        +		{
        +		BN_rand(&a,size,0,0);
        +		BN_rand(&b,size,1,0);
        +		BN_rand(&c,size,0,1);
        +
        +		BN_mod(&a,&a,&c,&ctx);
        +
        +		ms_time_get(start);
        +		for (i=0; i<10; i++)
        +			BN_MONT_CTX_set(&mont,&c,&ctx);
        +		ms_time_get(end);
        +		md=ms_time_diff(start,end);
        +
        +		ms_time_get(start);
        +		for (i=0; i<num; i++)
        +			{
        +			/* bn_mull(&r,&a,&b,&ctx); */
        +			/* BN_sqr(&r,&a,&ctx); */
        +			BN_mod_exp_mont(&r,&a,&b,&c,&ctx,&mont);
        +			}
        +		ms_time_get(end);
        +		d=ms_time_diff(start,end)/* *50/33 */;
        +		printf("%5d bit:%6.2f %6d %6.4f %4d m_set(%5.4f)\n",size,
        +			d,num,d/num,(int)((d/num)*mod),md/10.0);
        +		num/=8;
        +		mod/=8;
        +		if (num <= 0) num=1;
        +		size*=2;
        +		}
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/bn/expspeed.c b/vendor/openssl/openssl/crypto/bn/expspeed.c
        new file mode 100644
        index 000000000..4d5f221f3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/expspeed.c
        @@ -0,0 +1,353 @@
        +/* unused */
        +
        +/* crypto/bn/expspeed.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.]
        + */
        +
        +/* most of this code has been pilfered from my libdes speed.c program */
        +
        +#define BASENUM	5000
        +#define NUM_START 0
        +
        +
        +/* determine timings for modexp, modmul, modsqr, gcd, Kronecker symbol,
        + * modular inverse, or modular square roots */
        +#define TEST_EXP
        +#undef TEST_MUL
        +#undef TEST_SQR
        +#undef TEST_GCD
        +#undef TEST_KRON
        +#undef TEST_INV
        +#undef TEST_SQRT
        +#define P_MOD_64 9 /* least significant 6 bits for prime to be used for BN_sqrt timings */
        +
        +#if defined(TEST_EXP) + defined(TEST_MUL) + defined(TEST_SQR) + defined(TEST_GCD) + defined(TEST_KRON) + defined(TEST_INV) +defined(TEST_SQRT) != 1
        +#  error "choose one test"
        +#endif
        +
        +#if defined(TEST_INV) || defined(TEST_SQRT)
        +#  define C_PRIME
        +static void genprime_cb(int p, int n, void *arg);
        +#endif
        +
        +
        +
        +#undef PROG
        +#define PROG bnspeed_main
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <signal.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/bn.h>
        +#include <openssl/x509.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +# ifndef CLK_TCK
        +#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
        +#   define HZ	100.0
        +#  else /* _BSD_CLK_TCK_ */
        +#   define HZ ((double)_BSD_CLK_TCK_)
        +#  endif
        +# else /* CLK_TCK */
        +#  define HZ ((double)CLK_TCK)
        +# endif
        +#endif
        +
        +#undef BUFSIZE
        +#define BUFSIZE	((long)1024*8)
        +int run=0;
        +
        +static double Time_F(int s);
        +#define START	0
        +#define STOP	1
        +
        +static double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret < 1e-3)?1e-3:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
        +		return((ret < 0.001)?0.001:ret);
        +		}
        +#endif
        +	}
        +
        +#define NUM_SIZES	7
        +#if NUM_START > NUM_SIZES
        +#   error "NUM_START > NUM_SIZES"
        +#endif
        +static int sizes[NUM_SIZES]={128,256,512,1024,2048,4096,8192};
        +static int mul_c[NUM_SIZES]={8*8*8*8*8*8,8*8*8*8*8,8*8*8*8,8*8*8,8*8,8,1};
        +/*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
        +
        +#define RAND_SEED(string) { const char str[] = string; RAND_seed(string, sizeof str); }
        +
        +void do_mul_exp(BIGNUM *r,BIGNUM *a,BIGNUM *b,BIGNUM *c,BN_CTX *ctx); 
        +
        +int main(int argc, char **argv)
        +	{
        +	BN_CTX *ctx;
        +	BIGNUM *a,*b,*c,*r;
        +
        +#if 1
        +	if (!CRYPTO_set_mem_debug_functions(0,0,0,0,0))
        +		abort();
        +#endif
        +
        +	ctx=BN_CTX_new();
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	r=BN_new();
        +
        +	while (!RAND_status())
        +		/* not enough bits */
        +		RAND_SEED("I demand a manual recount!");
        +
        +	do_mul_exp(r,a,b,c,ctx);
        +	return 0;
        +	}
        +
        +void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
        +	{
        +	int i,k;
        +	double tm;
        +	long num;
        +
        +	num=BASENUM;
        +	for (i=NUM_START; i<NUM_SIZES; i++)
        +		{
        +#ifdef C_PRIME
        +#  ifdef TEST_SQRT
        +		if (!BN_set_word(a, 64)) goto err;
        +		if (!BN_set_word(b, P_MOD_64)) goto err;
        +#    define ADD a
        +#    define REM b
        +#  else
        +#    define ADD NULL
        +#    define REM NULL
        +#  endif
        +		if (!BN_generate_prime(c,sizes[i],0,ADD,REM,genprime_cb,NULL)) goto err;
        +		putc('\n', stderr);
        +		fflush(stderr);
        +#endif
        +
        +		for (k=0; k<num; k++)
        +			{
        +			if (k%50 == 0) /* Average over num/50 different choices of random numbers. */
        +				{
        +				if (!BN_pseudo_rand(a,sizes[i],1,0)) goto err;
        +
        +				if (!BN_pseudo_rand(b,sizes[i],1,0)) goto err;
        +
        +#ifndef C_PRIME
        +				if (!BN_pseudo_rand(c,sizes[i],1,1)) goto err;
        +#endif
        +
        +#ifdef TEST_SQRT				
        +				if (!BN_mod_sqr(a,a,c,ctx)) goto err;
        +				if (!BN_mod_sqr(b,b,c,ctx)) goto err;
        +#else
        +				if (!BN_nnmod(a,a,c,ctx)) goto err;
        +				if (!BN_nnmod(b,b,c,ctx)) goto err;
        +#endif
        +
        +				if (k == 0)
        +					Time_F(START);
        +				}
        +
        +#if defined(TEST_EXP)
        +			if (!BN_mod_exp(r,a,b,c,ctx)) goto err;
        +#elif defined(TEST_MUL)
        +			{
        +			int i = 0;
        +			for (i = 0; i < 50; i++)
        +				if (!BN_mod_mul(r,a,b,c,ctx)) goto err;
        +			}
        +#elif defined(TEST_SQR)
        +			{
        +			int i = 0;
        +			for (i = 0; i < 50; i++)
        +				{
        +				if (!BN_mod_sqr(r,a,c,ctx)) goto err;
        +				if (!BN_mod_sqr(r,b,c,ctx)) goto err;
        +				}
        +			}
        +#elif defined(TEST_GCD)
        +			if (!BN_gcd(r,a,b,ctx)) goto err;
        +			if (!BN_gcd(r,b,c,ctx)) goto err;
        +			if (!BN_gcd(r,c,a,ctx)) goto err;
        +#elif defined(TEST_KRON)
        +			if (-2 == BN_kronecker(a,b,ctx)) goto err;
        +			if (-2 == BN_kronecker(b,c,ctx)) goto err;
        +			if (-2 == BN_kronecker(c,a,ctx)) goto err;
        +#elif defined(TEST_INV)
        +			if (!BN_mod_inverse(r,a,c,ctx)) goto err;
        +			if (!BN_mod_inverse(r,b,c,ctx)) goto err;
        +#else /* TEST_SQRT */
        +			if (!BN_mod_sqrt(r,a,c,ctx)) goto err;
        +			if (!BN_mod_sqrt(r,b,c,ctx)) goto err;
        +#endif
        +			}
        +		tm=Time_F(STOP);
        +		printf(
        +#if defined(TEST_EXP)
        +			"modexp %4d ^ %4d %% %4d"
        +#elif defined(TEST_MUL)
        +			"50*modmul %4d %4d %4d"
        +#elif defined(TEST_SQR)
        +			"100*modsqr %4d %4d %4d"
        +#elif defined(TEST_GCD)
        +			"3*gcd %4d %4d %4d"
        +#elif defined(TEST_KRON)
        +			"3*kronecker %4d %4d %4d"
        +#elif defined(TEST_INV)
        +			"2*inv %4d %4d mod %4d"
        +#else /* TEST_SQRT */
        +			"2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d"
        +#endif
        +			" -> %8.6fms %5.1f (%ld)\n",
        +#ifdef TEST_SQRT
        +			P_MOD_64,
        +#endif
        +			sizes[i],sizes[i],sizes[i],tm*1000.0/num,tm*mul_c[i]/num, num);
        +		num/=7;
        +		if (num <= 0) num=1;
        +		}
        +	return;
        +
        + err:
        +	ERR_print_errors_fp(stderr);
        +	}
        +
        +
        +#ifdef C_PRIME
        +static void genprime_cb(int p, int n, void *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	putc(c, stderr);
        +	fflush(stderr);
        +	(void)n;
        +	(void)arg;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/bn/exptest.c b/vendor/openssl/openssl/crypto/bn/exptest.c
        new file mode 100644
        index 000000000..074a8e882
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/exptest.c
        @@ -0,0 +1,204 @@
        +/* crypto/bn/exptest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +#define NUM_BITS	(BN_BITS*2)
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_CTX *ctx;
        +	BIO *out=NULL;
        +	int i,ret;
        +	unsigned char c;
        +	BIGNUM *r_mont,*r_mont_const,*r_recp,*r_simple,*a,*b,*m;
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
        +	                                       * even check its return value
        +	                                       * (which we should) */
        +
        +	ERR_load_BN_strings();
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) EXIT(1);
        +	r_mont=BN_new();
        +	r_mont_const=BN_new();
        +	r_recp=BN_new();
        +	r_simple=BN_new();
        +	a=BN_new();
        +	b=BN_new();
        +	m=BN_new();
        +	if (	(r_mont == NULL) || (r_recp == NULL) ||
        +		(a == NULL) || (b == NULL))
        +		goto err;
        +
        +	out=BIO_new(BIO_s_file());
        +
        +	if (out == NULL) EXIT(1);
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +
        +	for (i=0; i<200; i++)
        +		{
        +		RAND_bytes(&c,1);
        +		c=(c%BN_BITS)-BN_BITS2;
        +		BN_rand(a,NUM_BITS+c,0,0);
        +
        +		RAND_bytes(&c,1);
        +		c=(c%BN_BITS)-BN_BITS2;
        +		BN_rand(b,NUM_BITS+c,0,0);
        +
        +		RAND_bytes(&c,1);
        +		c=(c%BN_BITS)-BN_BITS2;
        +		BN_rand(m,NUM_BITS+c,0,1);
        +
        +		BN_mod(a,a,m,ctx);
        +		BN_mod(b,b,m,ctx);
        +
        +		ret=BN_mod_exp_mont(r_mont,a,b,m,ctx,NULL);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_mont() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		ret=BN_mod_exp_recp(r_recp,a,b,m,ctx);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_recp() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		ret=BN_mod_exp_simple(r_simple,a,b,m,ctx);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_simple() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		ret=BN_mod_exp_mont_consttime(r_mont_const,a,b,m,ctx,NULL);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_mont_consttime() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		if (BN_cmp(r_simple, r_mont) == 0
        +		    && BN_cmp(r_simple,r_recp) == 0
        +			&& BN_cmp(r_simple,r_mont_const) == 0)
        +			{
        +			printf(".");
        +			fflush(stdout);
        +			}
        +		else
        +		  	{
        +			if (BN_cmp(r_simple,r_mont) != 0)
        +				printf("\nsimple and mont results differ\n");
        +			if (BN_cmp(r_simple,r_mont_const) != 0)
        +				printf("\nsimple and mont const time results differ\n");
        +			if (BN_cmp(r_simple,r_recp) != 0)
        +				printf("\nsimple and recp results differ\n");
        +
        +			printf("a (%3d) = ",BN_num_bits(a));   BN_print(out,a);
        +			printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b);
        +			printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m);
        +			printf("\nsimple   =");	BN_print(out,r_simple);
        +			printf("\nrecp     =");	BN_print(out,r_recp);
        +			printf("\nmont     ="); BN_print(out,r_mont);
        +			printf("\nmont_ct  ="); BN_print(out,r_mont_const);
        +			printf("\n");
        +			EXIT(1);
        +			}
        +		}
        +	BN_free(r_mont);
        +	BN_free(r_mont_const);
        +	BN_free(r_recp);
        +	BN_free(r_simple);
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(m);
        +	BN_CTX_free(ctx);
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks(out);
        +	BIO_free(out);
        +	printf(" done\n");
        +	EXIT(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors(out);
        +#ifdef OPENSSL_SYS_NETWARE
        +    printf("ERROR\n");
        +#endif
        +	EXIT(1);
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/bn/todo b/vendor/openssl/openssl/crypto/bn/todo
        new file mode 100644
        index 000000000..e47e381ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/todo
        @@ -0,0 +1,3 @@
        +Cache RECP_CTX values
        +make the result argument independant of the inputs.
        +split up the _exp_ functions
        diff --git a/vendor/openssl/openssl/crypto/bn/vms-helper.c b/vendor/openssl/openssl/crypto/bn/vms-helper.c
        new file mode 100644
        index 000000000..4b63149bf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/bn/vms-helper.c
        @@ -0,0 +1,68 @@
        +/* vms-helper.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).
        + *
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "bn_lcl.h"
        +
        +bn_div_words_abort(int i)
        +{
        +#ifdef BN_DEBUG
        +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
        +	fprintf(stderr,"Division would overflow (%d)\n",i);
        +#endif
        +	abort();
        +#endif
        +}
        diff --git a/vendor/openssl/openssl/crypto/buffer/Makefile b/vendor/openssl/openssl/crypto/buffer/Makefile
        new file mode 100644
        index 000000000..2efba47f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/buffer/Makefile
        @@ -0,0 +1,97 @@
        +#
        +# OpenSSL/crypto/buffer/Makefile
        +#
        +
        +DIR=	buffer
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= buffer.c buf_str.c buf_err.c
        +LIBOBJ= buffer.o buf_str.o buf_err.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= buffer.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +buf_err.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +buf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +buf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +buf_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +buf_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +buf_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +buf_err.o: buf_err.c
        +buf_str.o: ../../e_os.h ../../include/openssl/bio.h
        +buf_str.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +buf_str.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +buf_str.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +buf_str.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +buf_str.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +buf_str.o: ../../include/openssl/symhacks.h ../cryptlib.h buf_str.c
        +buffer.o: ../../e_os.h ../../include/openssl/bio.h
        +buffer.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +buffer.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +buffer.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +buffer.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +buffer.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +buffer.o: ../../include/openssl/symhacks.h ../cryptlib.h buffer.c
        diff --git a/vendor/openssl/openssl/crypto/buffer/buf_err.c b/vendor/openssl/openssl/crypto/buffer/buf_err.c
        new file mode 100644
        index 000000000..8f1de6192
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/buffer/buf_err.c
        @@ -0,0 +1,99 @@
        +/* crypto/buffer/buf_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/buffer.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason)
        +
        +static ERR_STRING_DATA BUF_str_functs[]=
        +	{
        +{ERR_FUNC(BUF_F_BUF_MEMDUP),	"BUF_memdup"},
        +{ERR_FUNC(BUF_F_BUF_MEM_GROW),	"BUF_MEM_grow"},
        +{ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN),	"BUF_MEM_grow_clean"},
        +{ERR_FUNC(BUF_F_BUF_MEM_NEW),	"BUF_MEM_new"},
        +{ERR_FUNC(BUF_F_BUF_STRDUP),	"BUF_strdup"},
        +{ERR_FUNC(BUF_F_BUF_STRNDUP),	"BUF_strndup"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA BUF_str_reasons[]=
        +	{
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_BUF_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(BUF_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,BUF_str_functs);
        +		ERR_load_strings(0,BUF_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/buffer/buf_str.c b/vendor/openssl/openssl/crypto/buffer/buf_str.c
        new file mode 100644
        index 000000000..151f5ea97
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/buffer/buf_str.c
        @@ -0,0 +1,119 @@
        +/* crypto/buffer/buffer.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +
        +char *BUF_strdup(const char *str)
        +	{
        +	if (str == NULL) return(NULL);
        +	return BUF_strndup(str, strlen(str));
        +	}
        +
        +char *BUF_strndup(const char *str, size_t siz)
        +	{
        +	char *ret;
        +
        +	if (str == NULL) return(NULL);
        +
        +	ret=OPENSSL_malloc(siz+1);
        +	if (ret == NULL) 
        +		{
        +		BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	BUF_strlcpy(ret,str,siz+1);
        +	return(ret);
        +	}
        +
        +void *BUF_memdup(const void *data, size_t siz)
        +	{
        +	void *ret;
        +
        +	if (data == NULL) return(NULL);
        +
        +	ret=OPENSSL_malloc(siz);
        +	if (ret == NULL) 
        +		{
        +		BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	return memcpy(ret, data, siz);
        +	}	
        +
        +size_t BUF_strlcpy(char *dst, const char *src, size_t size)
        +	{
        +	size_t l = 0;
        +	for(; size > 1 && *src; size--)
        +		{
        +		*dst++ = *src++;
        +		l++;
        +		}
        +	if (size)
        +		*dst = '\0';
        +	return l + strlen(src);
        +	}
        +
        +size_t BUF_strlcat(char *dst, const char *src, size_t size)
        +	{
        +	size_t l = 0;
        +	for(; size > 0 && *dst; size--, dst++)
        +		l++;
        +	return l + BUF_strlcpy(dst, src, size);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/buffer/buffer.c b/vendor/openssl/openssl/crypto/buffer/buffer.c
        new file mode 100644
        index 000000000..d7aa79ad7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/buffer/buffer.c
        @@ -0,0 +1,203 @@
        +/* crypto/buffer/buffer.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +
        +/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
        + * function is applied in several functions in this file and this limit ensures
        + * that the result fits in an int. */
        +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
        +
        +BUF_MEM *BUF_MEM_new(void)
        +	{
        +	BUF_MEM *ret;
        +
        +	ret=OPENSSL_malloc(sizeof(BUF_MEM));
        +	if (ret == NULL)
        +		{
        +		BUFerr(BUF_F_BUF_MEM_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	ret->length=0;
        +	ret->max=0;
        +	ret->data=NULL;
        +	return(ret);
        +	}
        +
        +void BUF_MEM_free(BUF_MEM *a)
        +	{
        +	if(a == NULL)
        +	    return;
        +
        +	if (a->data != NULL)
        +		{
        +		memset(a->data,0,(unsigned int)a->max);
        +		OPENSSL_free(a->data);
        +		}
        +	OPENSSL_free(a);
        +	}
        +
        +int BUF_MEM_grow(BUF_MEM *str, size_t len)
        +	{
        +	char *ret;
        +	size_t n;
        +
        +	if (str->length >= len)
        +		{
        +		str->length=len;
        +		return(len);
        +		}
        +	if (str->max >= len)
        +		{
        +		memset(&str->data[str->length],0,len-str->length);
        +		str->length=len;
        +		return(len);
        +		}
        +	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
        +	if (len > LIMIT_BEFORE_EXPANSION)
        +		{
        +		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	n=(len+3)/3*4;
        +	if (str->data == NULL)
        +		ret=OPENSSL_malloc(n);
        +	else
        +		ret=OPENSSL_realloc(str->data,n);
        +	if (ret == NULL)
        +		{
        +		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
        +		len=0;
        +		}
        +	else
        +		{
        +		str->data=ret;
        +		str->max=n;
        +		memset(&str->data[str->length],0,len-str->length);
        +		str->length=len;
        +		}
        +	return(len);
        +	}
        +
        +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
        +	{
        +	char *ret;
        +	size_t n;
        +
        +	if (str->length >= len)
        +		{
        +		memset(&str->data[len],0,str->length-len);
        +		str->length=len;
        +		return(len);
        +		}
        +	if (str->max >= len)
        +		{
        +		memset(&str->data[str->length],0,len-str->length);
        +		str->length=len;
        +		return(len);
        +		}
        +	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
        +	if (len > LIMIT_BEFORE_EXPANSION)
        +		{
        +		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	n=(len+3)/3*4;
        +	if (str->data == NULL)
        +		ret=OPENSSL_malloc(n);
        +	else
        +		ret=OPENSSL_realloc_clean(str->data,str->max,n);
        +	if (ret == NULL)
        +		{
        +		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
        +		len=0;
        +		}
        +	else
        +		{
        +		str->data=ret;
        +		str->max=n;
        +		memset(&str->data[str->length],0,len-str->length);
        +		str->length=len;
        +		}
        +	return(len);
        +	}
        +
        +void BUF_reverse(unsigned char *out, unsigned char *in, size_t size)
        +	{
        +	size_t i;
        +	if (in)
        +		{
        +		out += size - 1;
        +		for (i = 0; i < size; i++)
        +			*in++ = *out--;
        +		}
        +	else
        +		{
        +		unsigned char *q;
        +		char c;
        +		q = out + size - 1;
        +		for (i = 0; i < size/2; i++)
        +			{
        +			c = *q;
        +			*q-- = *out;
        +			*out++ = c;
        +			}
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/crypto/buffer/buffer.h b/vendor/openssl/openssl/crypto/buffer/buffer.h
        new file mode 100644
        index 000000000..178e41828
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/buffer/buffer.h
        @@ -0,0 +1,119 @@
        +/* crypto/buffer/buffer.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_BUFFER_H
        +#define HEADER_BUFFER_H
        +
        +#include <openssl/ossl_typ.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#include <stddef.h>
        +
        +#if !defined(NO_SYS_TYPES_H)
        +#include <sys/types.h>
        +#endif
        +
        +/* Already declared in ossl_typ.h */
        +/* typedef struct buf_mem_st BUF_MEM; */
        +
        +struct buf_mem_st
        +	{
        +	size_t length;	/* current number of bytes */
        +	char *data;
        +	size_t max;	/* size of buffer */
        +	};
        +
        +BUF_MEM *BUF_MEM_new(void);
        +void	BUF_MEM_free(BUF_MEM *a);
        +int	BUF_MEM_grow(BUF_MEM *str, size_t len);
        +int	BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
        +char *	BUF_strdup(const char *str);
        +char *	BUF_strndup(const char *str, size_t siz);
        +void *	BUF_memdup(const void *data, size_t siz);
        +void	BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);
        +
        +/* safe string functions */
        +size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
        +size_t BUF_strlcat(char *dst,const char *src,size_t siz);
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_BUF_strings(void);
        +
        +/* Error codes for the BUF functions. */
        +
        +/* Function codes. */
        +#define BUF_F_BUF_MEMDUP				 103
        +#define BUF_F_BUF_MEM_GROW				 100
        +#define BUF_F_BUF_MEM_GROW_CLEAN			 105
        +#define BUF_F_BUF_MEM_NEW				 101
        +#define BUF_F_BUF_STRDUP				 102
        +#define BUF_F_BUF_STRNDUP				 104
        +
        +/* Reason codes. */
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/camellia/Makefile b/vendor/openssl/openssl/crypto/camellia/Makefile
        new file mode 100644
        index 000000000..6ce6fc99c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/Makefile
        @@ -0,0 +1,110 @@
        +#
        +# crypto/camellia/Makefile
        +#
        +
        +DIR= camellia
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +#TEST=camelliatest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=camellia.c cmll_misc.c cmll_ecb.c cmll_cbc.c cmll_ofb.c \
        +	   cmll_cfb.c cmll_ctr.c cmll_utl.c
        +
        +LIBOBJ= cmll_ecb.o cmll_ofb.o cmll_cfb.o cmll_ctr.o cmll_utl.o $(CMLL_ENC)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= camellia.h
        +HEADER= cmll_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) || echo Never mind.
        +	@touch lib
        +
        +cmll-x86.s:	asm/cmll-x86.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/cmll-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +cmll-x86_64.s:  asm/cmll-x86_64.pl
        +	$(PERL) asm/cmll-x86_64.pl $(PERLASM_SCHEME) > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +camellia.o: ../../include/openssl/opensslconf.h camellia.c camellia.h
        +camellia.o: cmll_locl.h
        +cmll_cbc.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
        +cmll_cbc.o: ../../include/openssl/opensslconf.h cmll_cbc.c
        +cmll_cfb.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
        +cmll_cfb.o: ../../include/openssl/opensslconf.h cmll_cfb.c
        +cmll_ctr.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
        +cmll_ctr.o: ../../include/openssl/opensslconf.h cmll_ctr.c
        +cmll_ecb.o: ../../include/openssl/camellia.h
        +cmll_ecb.o: ../../include/openssl/opensslconf.h cmll_ecb.c cmll_locl.h
        +cmll_misc.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
        +cmll_misc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +cmll_misc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cmll_misc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cmll_misc.o: ../../include/openssl/symhacks.h cmll_locl.h cmll_misc.c
        +cmll_ofb.o: ../../include/openssl/camellia.h ../../include/openssl/modes.h
        +cmll_ofb.o: ../../include/openssl/opensslconf.h cmll_ofb.c
        +cmll_utl.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
        +cmll_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +cmll_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cmll_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cmll_utl.o: ../../include/openssl/symhacks.h cmll_locl.h cmll_utl.c
        diff --git a/vendor/openssl/openssl/crypto/camellia/asm/cmll-x86.pl b/vendor/openssl/openssl/crypto/camellia/asm/cmll-x86.pl
        new file mode 100644
        index 000000000..c314d6231
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/asm/cmll-x86.pl
        @@ -0,0 +1,1138 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
        +#
        +# This module may be used under the terms of either the GNU General
        +# Public License version 2 or later, the GNU Lesser General Public
        +# License version 2.1 or later, the Mozilla Public License version
        +# 1.1 or the BSD License. The exact terms of either license are
        +# distributed along with this module. For further details see
        +# http://www.openssl.org/~appro/camellia/.
        +# ====================================================================
        +
        +# Performance in cycles per processed byte (less is better) in
        +# 'openssl speed ...' benchmark:
        +#
        +#			AMD K8	Core2	PIII	P4
        +# -evp camellia-128-ecb	21.5	22.8	27.0	28.9
        +# + over gcc 3.4.6	+90/11% +70/10%	+53/4%	+160/64%
        +# + over icc 8.0	+48/19% +21/15%	+21/17%	+55/37%
        +#
        +# camellia-128-cbc	17.3	21.1	23.9	25.9
        +#
        +# 128-bit key setup	196	280	256	240	cycles/key
        +# + over gcc 3.4.6	+30/0%	+17/11%	+11/0%	+63/40%
        +# + over icc 8.0	+18/3%	+10/0%	+10/3%	+21/10%
        +#
        +# Pairs of numbers in "+" rows represent performance improvement over
        +# compiler generated position-independent code, PIC, and non-PIC
        +# respectively. PIC results are of greater relevance, as this module
        +# is position-independent, i.e. suitable for a shared library or PIE.
        +# Position independence "costs" one register, which is why compilers
        +# are so close with non-PIC results, they have an extra register to
        +# spare. CBC results are better than ECB ones thanks to "zero-copy"
        +# private _x86_* interface, and are ~30-40% better than with compiler
        +# generated cmll_cbc.o, and reach ~80-90% of x86_64 performance on
        +# same CPU (where applicable).
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +$OPENSSL=1;
        +
        +&asm_init($ARGV[0],"cmll-586.pl",$ARGV[$#ARGV] eq "386");
        +
        +@T=("eax","ebx","ecx","edx");
        +$idx="esi";
        +$key="edi";
        +$Tbl="ebp";
        +
        +# stack frame layout in _x86_Camellia_* routines, frame is allocated
        +# by caller
        +$__ra=&DWP(0,"esp");	# return address
        +$__s0=&DWP(4,"esp");	# s0 backing store
        +$__s1=&DWP(8,"esp");	# s1 backing store
        +$__s2=&DWP(12,"esp");	# s2 backing store
        +$__s3=&DWP(16,"esp");	# s3 backing store
        +$__end=&DWP(20,"esp");	# pointer to end/start of key schedule
        +
        +# stack frame layout in Camellia_[en|crypt] routines, which differs from
        +# above by 4 and overlaps by pointer to end/start of key schedule
        +$_end=&DWP(16,"esp");
        +$_esp=&DWP(20,"esp");
        +
        +# const unsigned int Camellia_SBOX[4][256];
        +# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
        +# and [2][] - with [3][]. This is done to optimize code size.
        +$SBOX1_1110=0;		# Camellia_SBOX[0]
        +$SBOX4_4404=4;		# Camellia_SBOX[1]
        +$SBOX2_0222=2048;	# Camellia_SBOX[2]
        +$SBOX3_3033=2052;	# Camellia_SBOX[3]
        +&static_label("Camellia_SIGMA");
        +&static_label("Camellia_SBOX");
        +
        +sub Camellia_Feistel {
        +my $i=@_[0];
        +my $seed=defined(@_[1])?@_[1]:0;
        +my $scale=$seed<0?-8:8;
        +my $frame=defined(@_[2])?@_[2]:0;
        +my $j=($i&1)*2;
        +my $t0=@T[($j)%4],$t1=@T[($j+1)%4],$t2=@T[($j+2)%4],$t3=@T[($j+3)%4];
        +
        +	&xor	($t0,$idx);				# t0^=key[0]
        +	&xor	($t1,&DWP($seed+$i*$scale+4,$key));	# t1^=key[1]
        +	&movz	($idx,&HB($t0));			# (t0>>8)&0xff
        +	&mov	($t3,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t3=SBOX3_3033[0]
        +	&movz	($idx,&LB($t0));			# (t0>>0)&0xff
        +	&xor	($t3,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t3^=SBOX4_4404[0]
        +	&shr	($t0,16);
        +	&movz	($idx,&LB($t1));			# (t1>>0)&0xff
        +	&mov	($t2,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t2=SBOX1_1110[1]
        +	&movz	($idx,&HB($t0));			# (t0>>24)&0xff
        +	&xor	($t3,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t3^=SBOX1_1110[0]
        +	&movz	($idx,&HB($t1));			# (t1>>8)&0xff
        +	&xor	($t2,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t2^=SBOX4_4404[1]
        +	&shr	($t1,16);
        +	&movz	($t0,&LB($t0));				# (t0>>16)&0xff
        +	&xor	($t3,&DWP($SBOX2_0222,$Tbl,$t0,8));	# t3^=SBOX2_0222[0]
        +	&movz	($idx,&HB($t1));			# (t1>>24)&0xff
        +	&mov	($t0,&DWP($frame+4*(($j+3)%4),"esp"));	# prefetch "s3"
        +	&xor	($t2,$t3);				# t2^=t3
        +	&rotr	($t3,8);				# t3=RightRotate(t3,8)
        +	&xor	($t2,&DWP($SBOX2_0222,$Tbl,$idx,8));	# t2^=SBOX2_0222[1]
        +	&movz	($idx,&LB($t1));			# (t1>>16)&0xff
        +	&mov	($t1,&DWP($frame+4*(($j+2)%4),"esp"));	# prefetch "s2"
        +	&xor	($t3,$t0);				# t3^=s3
        +	&xor	($t2,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t2^=SBOX3_3033[1]
        +	&mov	($idx,&DWP($seed+($i+1)*$scale,$key));	# prefetch key[i+1]
        +	&xor	($t3,$t2);				# t3^=t2
        +	&mov	(&DWP($frame+4*(($j+3)%4),"esp"),$t3);	# s3=t3
        +	&xor	($t2,$t1);				# t2^=s2
        +	&mov	(&DWP($frame+4*(($j+2)%4),"esp"),$t2);	# s2=t2
        +}
        +
        +# void Camellia_EncryptBlock_Rounds(
        +#		int grandRounds,
        +#		const Byte plaintext[],
        +#		const KEY_TABLE_TYPE keyTable,
        +#		Byte ciphertext[])
        +&function_begin("Camellia_EncryptBlock_Rounds");
        +	&mov	("eax",&wparam(0));	# load grandRounds
        +	&mov	($idx,&wparam(1));	# load plaintext pointer
        +	&mov	($key,&wparam(2));	# load key schedule pointer
        +
        +	&mov	("ebx","esp");
        +	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
        +	&and	("esp",-64);
        +
        +	# place stack frame just "above mod 1024" the key schedule
        +	# this ensures that cache associativity of 2 suffices
        +	&lea	("ecx",&DWP(-64-63,$key));
        +	&sub	("ecx","esp");
        +	&neg	("ecx");
        +	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	("esp","ecx");
        +	&add	("esp",4);	# 4 is reserved for callee's return address
        +
        +	&shl	("eax",6);
        +	&lea	("eax",&DWP(0,$key,"eax"));
        +	&mov	($_esp,"ebx");	# save %esp
        +	&mov	($_end,"eax");	# save keyEnd
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($Tbl);
        +	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
        +
        +	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
        +	&mov	(@T[1],&DWP(4,$idx));
        +	&mov	(@T[2],&DWP(8,$idx));
        +	&bswap	(@T[0]);
        +	&mov	(@T[3],&DWP(12,$idx));
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +
        +	&call	("_x86_Camellia_encrypt");
        +
        +	&mov	("esp",$_esp);
        +	&bswap	(@T[0]);
        +	&mov	($idx,&wparam(3));	# load ciphertext pointer
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
        +	&mov	(&DWP(4,$idx),@T[1]);
        +	&mov	(&DWP(8,$idx),@T[2]);
        +	&mov	(&DWP(12,$idx),@T[3]);
        +&function_end("Camellia_EncryptBlock_Rounds");
        +# V1.x API
        +&function_begin_B("Camellia_EncryptBlock");
        +	&mov	("eax",128);
        +	&sub	("eax",&wparam(0));	# load keyBitLength
        +	&mov	("eax",3);
        +	&adc	("eax",0);		# keyBitLength==128?3:4
        +	&mov	(&wparam(0),"eax");
        +	&jmp	(&label("Camellia_EncryptBlock_Rounds"));
        +&function_end_B("Camellia_EncryptBlock");
        +
        +if ($OPENSSL) {
        +# void Camellia_encrypt(
        +#		const unsigned char *in,
        +#		unsigned char *out,
        +#		const CAMELLIA_KEY *key)
        +&function_begin("Camellia_encrypt");
        +	&mov	($idx,&wparam(0));	# load plaintext pointer
        +	&mov	($key,&wparam(2));	# load key schedule pointer
        +
        +	&mov	("ebx","esp");
        +	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
        +	&and	("esp",-64);
        +	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
        +
        +	# place stack frame just "above mod 1024" the key schedule
        +	# this ensures that cache associativity of 2 suffices
        +	&lea	("ecx",&DWP(-64-63,$key));
        +	&sub	("ecx","esp");
        +	&neg	("ecx");
        +	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	("esp","ecx");
        +	&add	("esp",4);	# 4 is reserved for callee's return address
        +
        +	&shl	("eax",6);
        +	&lea	("eax",&DWP(0,$key,"eax"));
        +	&mov	($_esp,"ebx");	# save %esp
        +	&mov	($_end,"eax");	# save keyEnd
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($Tbl);
        +	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
        +
        +	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
        +	&mov	(@T[1],&DWP(4,$idx));
        +	&mov	(@T[2],&DWP(8,$idx));
        +	&bswap	(@T[0]);
        +	&mov	(@T[3],&DWP(12,$idx));
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +
        +	&call	("_x86_Camellia_encrypt");
        +
        +	&mov	("esp",$_esp);
        +	&bswap	(@T[0]);
        +	&mov	($idx,&wparam(1));	# load ciphertext pointer
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
        +	&mov	(&DWP(4,$idx),@T[1]);
        +	&mov	(&DWP(8,$idx),@T[2]);
        +	&mov	(&DWP(12,$idx),@T[3]);
        +&function_end("Camellia_encrypt");
        +}
        +
        +&function_begin_B("_x86_Camellia_encrypt");
        +	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
        +	&xor	(@T[1],&DWP(4,$key));
        +	&xor	(@T[2],&DWP(8,$key));
        +	&xor	(@T[3],&DWP(12,$key));
        +	&mov	($idx,&DWP(16,$key));	# prefetch key[4]
        +
        +	&mov	($__s0,@T[0]);		# save s[0-3]
        +	&mov	($__s1,@T[1]);
        +	&mov	($__s2,@T[2]);
        +	&mov	($__s3,@T[3]);
        +
        +&set_label("loop",16);
        +	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16,4); }
        +
        +	&add	($key,16*4);
        +	&cmp	($key,$__end);
        +	&je	(&label("done"));
        +
        +	# @T[0-1] are preloaded, $idx is preloaded with key[0]
        +	&and	($idx,@T[0]);
        +	 &mov	 (@T[3],$__s3);
        +	&rotl	($idx,1);
        +	 &mov	 (@T[2],@T[3]);
        +	&xor	(@T[1],$idx);
        +	 &or	 (@T[2],&DWP(12,$key));
        +	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
        +	 &xor	 (@T[2],$__s2);
        +
        +	&mov	($idx,&DWP(4,$key));
        +	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
        +	&or	($idx,@T[1]);
        +	 &and	 (@T[2],&DWP(8,$key));
        +	&xor	(@T[0],$idx);
        +	 &rotl	 (@T[2],1);
        +	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
        +	 &xor	 (@T[3],@T[2]);
        +	&mov	($idx,&DWP(16,$key));		# prefetch key[4]
        +	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
        +	&jmp	(&label("loop"));
        +
        +&set_label("done",8);
        +	&mov	(@T[2],@T[0]);		# SwapHalf
        +	&mov	(@T[3],@T[1]);
        +	&mov	(@T[0],$__s2);
        +	&mov	(@T[1],$__s3);
        +	&xor	(@T[0],$idx);		# $idx is preloaded with key[0]
        +	&xor	(@T[1],&DWP(4,$key));
        +	&xor	(@T[2],&DWP(8,$key));
        +	&xor	(@T[3],&DWP(12,$key));
        +	&ret	();
        +&function_end_B("_x86_Camellia_encrypt");
        +
        +# void Camellia_DecryptBlock_Rounds(
        +#		int grandRounds,
        +#		const Byte ciphertext[],
        +#		const KEY_TABLE_TYPE keyTable,
        +#		Byte plaintext[])
        +&function_begin("Camellia_DecryptBlock_Rounds");
        +	&mov	("eax",&wparam(0));	# load grandRounds
        +	&mov	($idx,&wparam(1));	# load ciphertext pointer
        +	&mov	($key,&wparam(2));	# load key schedule pointer
        +
        +	&mov	("ebx","esp");
        +	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
        +	&and	("esp",-64);
        +
        +	# place stack frame just "above mod 1024" the key schedule
        +	# this ensures that cache associativity of 2 suffices
        +	&lea	("ecx",&DWP(-64-63,$key));
        +	&sub	("ecx","esp");
        +	&neg	("ecx");
        +	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	("esp","ecx");
        +	&add	("esp",4);	# 4 is reserved for callee's return address
        +
        +	&shl	("eax",6);
        +	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
        +	&lea	($key,&DWP(0,$key,"eax"));
        +	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($Tbl);
        +	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
        +
        +	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
        +	&mov	(@T[1],&DWP(4,$idx));
        +	&mov	(@T[2],&DWP(8,$idx));
        +	&bswap	(@T[0]);
        +	&mov	(@T[3],&DWP(12,$idx));
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +
        +	&call	("_x86_Camellia_decrypt");
        +
        +	&mov	("esp",&DWP(5*4,"esp"));
        +	&bswap	(@T[0]);
        +	&mov	($idx,&wparam(3));	# load plaintext pointer
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
        +	&mov	(&DWP(4,$idx),@T[1]);
        +	&mov	(&DWP(8,$idx),@T[2]);
        +	&mov	(&DWP(12,$idx),@T[3]);
        +&function_end("Camellia_DecryptBlock_Rounds");
        +# V1.x API
        +&function_begin_B("Camellia_DecryptBlock");
        +	&mov	("eax",128);
        +	&sub	("eax",&wparam(0));	# load keyBitLength
        +	&mov	("eax",3);
        +	&adc	("eax",0);		# keyBitLength==128?3:4
        +	&mov	(&wparam(0),"eax");
        +	&jmp	(&label("Camellia_DecryptBlock_Rounds"));
        +&function_end_B("Camellia_DecryptBlock");
        +
        +if ($OPENSSL) {
        +# void Camellia_decrypt(
        +#		const unsigned char *in,
        +#		unsigned char *out,
        +#		const CAMELLIA_KEY *key)
        +&function_begin("Camellia_decrypt");
        +	&mov	($idx,&wparam(0));	# load ciphertext pointer
        +	&mov	($key,&wparam(2));	# load key schedule pointer
        +
        +	&mov	("ebx","esp");
        +	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
        +	&and	("esp",-64);
        +	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
        +
        +	# place stack frame just "above mod 1024" the key schedule
        +	# this ensures that cache associativity of 2 suffices
        +	&lea	("ecx",&DWP(-64-63,$key));
        +	&sub	("ecx","esp");
        +	&neg	("ecx");
        +	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	("esp","ecx");
        +	&add	("esp",4);	# 4 is reserved for callee's return address
        +
        +	&shl	("eax",6);
        +	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
        +	&lea	($key,&DWP(0,$key,"eax"));
        +	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($Tbl);
        +	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
        +
        +	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
        +	&mov	(@T[1],&DWP(4,$idx));
        +	&mov	(@T[2],&DWP(8,$idx));
        +	&bswap	(@T[0]);
        +	&mov	(@T[3],&DWP(12,$idx));
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +
        +	&call	("_x86_Camellia_decrypt");
        +
        +	&mov	("esp",&DWP(5*4,"esp"));
        +	&bswap	(@T[0]);
        +	&mov	($idx,&wparam(1));	# load plaintext pointer
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
        +	&mov	(&DWP(4,$idx),@T[1]);
        +	&mov	(&DWP(8,$idx),@T[2]);
        +	&mov	(&DWP(12,$idx),@T[3]);
        +&function_end("Camellia_decrypt");
        +}
        +
        +&function_begin_B("_x86_Camellia_decrypt");
        +	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
        +	&xor	(@T[1],&DWP(4,$key));
        +	&xor	(@T[2],&DWP(8,$key));
        +	&xor	(@T[3],&DWP(12,$key));
        +	&mov	($idx,&DWP(-8,$key));	# prefetch key[-2]
        +
        +	&mov	($__s0,@T[0]);		# save s[0-3]
        +	&mov	($__s1,@T[1]);
        +	&mov	($__s2,@T[2]);
        +	&mov	($__s3,@T[3]);
        +
        +&set_label("loop",16);
        +	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8,4); }
        +
        +	&sub	($key,16*4);
        +	&cmp	($key,$__end);
        +	&je	(&label("done"));
        +
        +	# @T[0-1] are preloaded, $idx is preloaded with key[2]
        +	&and	($idx,@T[0]);
        +	 &mov	 (@T[3],$__s3);
        +	&rotl	($idx,1);
        +	 &mov	 (@T[2],@T[3]);
        +	&xor	(@T[1],$idx);
        +	 &or	 (@T[2],&DWP(4,$key));
        +	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
        +	 &xor	 (@T[2],$__s2);
        +
        +	&mov	($idx,&DWP(12,$key));
        +	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
        +	&or	($idx,@T[1]);
        +	 &and	 (@T[2],&DWP(0,$key));
        +	&xor	(@T[0],$idx);
        +	 &rotl	 (@T[2],1);
        +	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
        +	 &xor	 (@T[3],@T[2]);
        +	&mov	($idx,&DWP(-8,$key));	# prefetch key[4]
        +	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
        +	&jmp	(&label("loop"));
        +
        +&set_label("done",8);
        +	&mov	(@T[2],@T[0]);		# SwapHalf
        +	&mov	(@T[3],@T[1]);
        +	&mov	(@T[0],$__s2);
        +	&mov	(@T[1],$__s3);
        +	&xor	(@T[2],$idx);		# $idx is preloaded with key[2]
        +	&xor	(@T[3],&DWP(12,$key));
        +	&xor	(@T[0],&DWP(0,$key));
        +	&xor	(@T[1],&DWP(4,$key));
        +	&ret	();
        +&function_end_B("_x86_Camellia_decrypt");
        +
        +# shld is very slow on Intel P4 family. Even on AMD it limits
        +# instruction decode rate [because it's VectorPath] and consequently
        +# performance. PIII, PM and Core[2] seem to be the only ones which
        +# execute this code ~7% faster...
        +sub __rotl128 {
        +  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
        +
        +    $rnd *= 2;
        +    if ($rot) {
        +	&mov	($idx,$i0);
        +	&shld	($i0,$i1,$rot);
        +	&shld	($i1,$i2,$rot);
        +	&shld	($i2,$i3,$rot);
        +	&shld	($i3,$idx,$rot);
        +    }
        +    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
        +    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
        +    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
        +    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
        +}
        +
        +# ... Implementing 128-bit rotate without shld gives >3x performance
        +# improvement on P4, only ~7% degradation on other Intel CPUs and
        +# not worse performance on AMD. This is therefore preferred.
        +sub _rotl128 {
        +  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
        +
        +    $rnd *= 2;
        +    if ($rot) {
        +	&mov	($Tbl,$i0);
        +	&shl	($i0,$rot);
        +	&mov	($idx,$i1);
        +	&shr	($idx,32-$rot);
        +	&shl	($i1,$rot);
        +	&or	($i0,$idx);
        +	&mov	($idx,$i2);
        +	&shl	($i2,$rot);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
        +	&shr	($idx,32-$rot);
        +	&or	($i1,$idx);
        +	&shr	($Tbl,32-$rot);
        +	&mov	($idx,$i3);
        +	&shr	($idx,32-$rot);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
        +	&shl	($i3,$rot);
        +	&or	($i2,$idx);
        +	&or	($i3,$Tbl);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
        +    } else {
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
        +	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
        +    }
        +}
        +
        +sub _saveround {
        +my ($rnd,$key,@T)=@_;
        +my $bias=int(@T[0])?shift(@T):0;
        +
        +	&mov	(&DWP($bias+$rnd*8+0,$key),@T[0]);
        +	&mov	(&DWP($bias+$rnd*8+4,$key),@T[1])	if ($#T>=1);
        +	&mov	(&DWP($bias+$rnd*8+8,$key),@T[2])	if ($#T>=2);
        +	&mov	(&DWP($bias+$rnd*8+12,$key),@T[3])	if ($#T>=3);
        +}
        +
        +sub _loadround {
        +my ($rnd,$key,@T)=@_;
        +my $bias=int(@T[0])?shift(@T):0;
        +
        +	&mov	(@T[0],&DWP($bias+$rnd*8+0,$key));
        +	&mov	(@T[1],&DWP($bias+$rnd*8+4,$key))	if ($#T>=1);
        +	&mov	(@T[2],&DWP($bias+$rnd*8+8,$key))	if ($#T>=2);
        +	&mov	(@T[3],&DWP($bias+$rnd*8+12,$key))	if ($#T>=3);
        +}
        +
        +# void Camellia_Ekeygen(
        +#		const int keyBitLength,
        +#		const Byte *rawKey,
        +#		KEY_TABLE_TYPE keyTable)
        +&function_begin("Camellia_Ekeygen");
        +{ my $step=0;
        +
        +	&stack_push(4);				# place for s[0-3]
        +
        +	&mov	($Tbl,&wparam(0));		# load arguments
        +	&mov	($idx,&wparam(1));
        +	&mov	($key,&wparam(2));
        +
        +	&mov	(@T[0],&DWP(0,$idx));		# load 0-127 bits
        +	&mov	(@T[1],&DWP(4,$idx));
        +	&mov	(@T[2],&DWP(8,$idx));
        +	&mov	(@T[3],&DWP(12,$idx));
        +
        +	&bswap	(@T[0]);
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +
        +	&_saveround	(0,$key,@T);		# KL<<<0
        +
        +	&cmp	($Tbl,128);
        +	&je	(&label("1st128"));
        +
        +	&mov	(@T[0],&DWP(16,$idx));		# load 128-191 bits
        +	&mov	(@T[1],&DWP(20,$idx));
        +	&cmp	($Tbl,192);
        +	&je	(&label("1st192"));
        +	&mov	(@T[2],&DWP(24,$idx));		# load 192-255 bits
        +	&mov	(@T[3],&DWP(28,$idx));
        +	&jmp	(&label("1st256"));
        +&set_label("1st192",4);
        +	&mov	(@T[2],@T[0]);
        +	&mov	(@T[3],@T[1]);
        +	&not	(@T[2]);
        +	&not	(@T[3]);
        +&set_label("1st256",4);
        +	&bswap	(@T[0]);
        +	&bswap	(@T[1]);
        +	&bswap	(@T[2]);
        +	&bswap	(@T[3]);
        +
        +	&_saveround	(4,$key,@T);		# temporary storage for KR!
        +
        +	&xor	(@T[0],&DWP(0*8+0,$key));	# KR^KL
        +	&xor	(@T[1],&DWP(0*8+4,$key));
        +	&xor	(@T[2],&DWP(1*8+0,$key));
        +	&xor	(@T[3],&DWP(1*8+4,$key));
        +
        +&set_label("1st128",4);
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($Tbl);
        +	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
        +	&lea	($key,&DWP(&label("Camellia_SIGMA")."-".&label("Camellia_SBOX"),$Tbl));
        +
        +	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[0]
        +	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
        +	&mov	(&swtmp(1),@T[1]);
        +	&mov	(&swtmp(2),@T[2]);
        +	&mov	(&swtmp(3),@T[3]);
        +	&Camellia_Feistel($step++);
        +	&Camellia_Feistel($step++);
        +	&mov	(@T[2],&swtmp(2));
        +	&mov	(@T[3],&swtmp(3));
        +
        +	&mov	($idx,&wparam(2));
        +	&xor	(@T[0],&DWP(0*8+0,$idx));	# ^KL
        +	&xor	(@T[1],&DWP(0*8+4,$idx));
        +	&xor	(@T[2],&DWP(1*8+0,$idx));
        +	&xor	(@T[3],&DWP(1*8+4,$idx));
        +
        +	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[4]
        +	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
        +	&mov	(&swtmp(1),@T[1]);
        +	&mov	(&swtmp(2),@T[2]);
        +	&mov	(&swtmp(3),@T[3]);
        +	&Camellia_Feistel($step++);
        +	&Camellia_Feistel($step++);
        +	&mov	(@T[2],&swtmp(2));
        +	&mov	(@T[3],&swtmp(3));
        +
        +	&mov	($idx,&wparam(0));
        +	&cmp	($idx,128);
        +	&jne	(&label("2nd256"));
        +
        +	&mov	($key,&wparam(2));
        +	&lea	($key,&DWP(128,$key));		# size optimization
        +
        +	####### process KA
        +	&_saveround	(2,$key,-128,@T);	# KA<<<0
        +	&_rotl128	(@T,15,6,@T);		# KA<<<15
        +	&_rotl128	(@T,15,8,@T);		# KA<<<(15+15=30)
        +	&_rotl128	(@T,15,12,@T[0],@T[1]);	# KA<<<(30+15=45)
        +	&_rotl128	(@T,15,14,@T);		# KA<<<(45+15=60)
        +	push		(@T,shift(@T));		# rotl128(@T,32);
        +	&_rotl128	(@T,2,20,@T);		# KA<<<(60+32+2=94)
        +	&_rotl128	(@T,17,24,@T);		# KA<<<(94+17=111)
        +
        +	####### process KL
        +	&_loadround	(0,$key,-128,@T);	# load KL
        +	&_rotl128	(@T,15,4,@T);		# KL<<<15
        +	&_rotl128	(@T,30,10,@T);		# KL<<<(15+30=45)
        +	&_rotl128	(@T,15,13,@T[2],@T[3]);	# KL<<<(45+15=60)
        +	&_rotl128	(@T,17,16,@T);		# KL<<<(60+17=77)
        +	&_rotl128	(@T,17,18,@T);		# KL<<<(77+17=94)
        +	&_rotl128	(@T,17,22,@T);		# KL<<<(94+17=111)
        +
        +	while (@T[0] ne "eax")			# restore order
        +	{   unshift	(@T,pop(@T));   }
        +
        +	&mov	("eax",3);			# 3 grandRounds
        +	&jmp	(&label("done"));
        +
        +&set_label("2nd256",16);
        +	&mov	($idx,&wparam(2));
        +	&_saveround	(6,$idx,@T);		# temporary storage for KA!
        +
        +	&xor	(@T[0],&DWP(4*8+0,$idx));	# KA^KR
        +	&xor	(@T[1],&DWP(4*8+4,$idx));
        +	&xor	(@T[2],&DWP(5*8+0,$idx));
        +	&xor	(@T[3],&DWP(5*8+4,$idx));
        +
        +	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[8]
        +	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
        +	&mov	(&swtmp(1),@T[1]);
        +	&mov	(&swtmp(2),@T[2]);
        +	&mov	(&swtmp(3),@T[3]);
        +	&Camellia_Feistel($step++);
        +	&Camellia_Feistel($step++);
        +	&mov	(@T[2],&swtmp(2));
        +	&mov	(@T[3],&swtmp(3));
        +
        +	&mov	($key,&wparam(2));
        +	&lea	($key,&DWP(128,$key));		# size optimization
        +
        +	####### process KB
        +	&_saveround	(2,$key,-128,@T);	# KB<<<0
        +	&_rotl128	(@T,30,10,@T);		# KB<<<30
        +	&_rotl128	(@T,30,20,@T);		# KB<<<(30+30=60)
        +	push		(@T,shift(@T));		# rotl128(@T,32);
        +	&_rotl128	(@T,19,32,@T);		# KB<<<(60+32+19=111)
        +
        +	####### process KR
        +	&_loadround	(4,$key,-128,@T);	# load KR
        +	&_rotl128	(@T,15,4,@T);		# KR<<<15
        +	&_rotl128	(@T,15,8,@T);		# KR<<<(15+15=30)
        +	&_rotl128	(@T,30,18,@T);		# KR<<<(30+30=60)
        +	push		(@T,shift(@T));		# rotl128(@T,32);
        +	&_rotl128	(@T,2,26,@T);		# KR<<<(60+32+2=94)
        +
        +	####### process KA
        +	&_loadround	(6,$key,-128,@T);	# load KA
        +	&_rotl128	(@T,15,6,@T);		# KA<<<15
        +	&_rotl128	(@T,30,14,@T);		# KA<<<(15+30=45)
        +	push		(@T,shift(@T));		# rotl128(@T,32);
        +	&_rotl128	(@T,0,24,@T);		# KA<<<(45+32+0=77)
        +	&_rotl128	(@T,17,28,@T);		# KA<<<(77+17=94)
        +
        +	####### process KL
        +	&_loadround	(0,$key,-128,@T);	# load KL
        +	push		(@T,shift(@T));		# rotl128(@T,32);
        +	&_rotl128	(@T,13,12,@T);		# KL<<<(32+13=45)
        +	&_rotl128	(@T,15,16,@T);		# KL<<<(45+15=60)
        +	&_rotl128	(@T,17,22,@T);		# KL<<<(60+17=77)
        +	push		(@T,shift(@T));		# rotl128(@T,32);
        +	&_rotl128	(@T,2,30,@T);		# KL<<<(77+32+2=111)
        +
        +	while (@T[0] ne "eax")			# restore order
        +	{   unshift	(@T,pop(@T));   }
        +
        +	&mov	("eax",4);			# 4 grandRounds
        +&set_label("done");
        +	&lea	("edx",&DWP(272-128,$key));	# end of key schedule
        +	&stack_pop(4);
        +}
        +&function_end("Camellia_Ekeygen");
        +
        +if ($OPENSSL) {
        +# int private_Camellia_set_key (
        +#		const unsigned char *userKey,
        +#		int bits,
        +#		CAMELLIA_KEY *key)
        +&function_begin_B("private_Camellia_set_key");
        +	&push	("ebx");
        +	&mov	("ecx",&wparam(0));	# pull arguments
        +	&mov	("ebx",&wparam(1));
        +	&mov	("edx",&wparam(2));
        +
        +	&mov	("eax",-1);
        +	&test	("ecx","ecx");
        +	&jz	(&label("done"));	# userKey==NULL?
        +	&test	("edx","edx");
        +	&jz	(&label("done"));	# key==NULL?
        +
        +	&mov	("eax",-2);
        +	&cmp	("ebx",256);
        +	&je	(&label("arg_ok"));	# bits==256?
        +	&cmp	("ebx",192);
        +	&je	(&label("arg_ok"));	# bits==192?
        +	&cmp	("ebx",128);
        +	&jne	(&label("done"));	# bits!=128?
        +&set_label("arg_ok",4);
        +
        +	&push	("edx");		# push arguments
        +	&push	("ecx");
        +	&push	("ebx");
        +	&call	("Camellia_Ekeygen");
        +	&stack_pop(3);
        +
        +	# eax holds grandRounds and edx points at where to put it
        +	&mov	(&DWP(0,"edx"),"eax");
        +	&xor	("eax","eax");
        +&set_label("done",4);
        +	&pop	("ebx");
        +	&ret	();
        +&function_end_B("private_Camellia_set_key");
        +}
        +
        +@SBOX=(
        +112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
        + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
        +134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
        +166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
        +139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
        +223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
        + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
        +254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
        +170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
        + 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
        +135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
        + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
        +233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
        +120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
        +114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
        + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
        +
        +sub S1110 { my $i=shift; $i=@SBOX[$i]; return $i<<24|$i<<16|$i<<8; }
        +sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; return $i<<24|$i<<16|$i; }	
        +sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; return $i<<16|$i<<8|$i; }	
        +sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; return $i<<24|$i<<8|$i; }	
        +
        +&set_label("Camellia_SIGMA",64);
        +&data_word(
        +    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2,
        +    0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c,
        +    0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd,
        +    0,          0,          0,          0);
        +&set_label("Camellia_SBOX",64);
        +# tables are interleaved, remember?
        +for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
        +for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
        +
        +# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
        +#			size_t length, const CAMELLIA_KEY *key,
        +#			unsigned char *ivp,const int enc);
        +{
        +# stack frame layout
        +#             -4(%esp)		# return address	 0(%esp)
        +#              0(%esp)		# s0			 4(%esp)
        +#              4(%esp)		# s1			 8(%esp)
        +#              8(%esp)		# s2			12(%esp)
        +#             12(%esp)		# s3			16(%esp)
        +#             16(%esp)		# end of key schedule	20(%esp)
        +#             20(%esp)		# %esp backup
        +my $_inp=&DWP(24,"esp");	#copy of wparam(0)
        +my $_out=&DWP(28,"esp");	#copy of wparam(1)
        +my $_len=&DWP(32,"esp");	#copy of wparam(2)
        +my $_key=&DWP(36,"esp");	#copy of wparam(3)
        +my $_ivp=&DWP(40,"esp");	#copy of wparam(4)
        +my $ivec=&DWP(44,"esp");	#ivec[16]
        +my $_tmp=&DWP(44,"esp");	#volatile variable [yes, aliases with ivec]
        +my ($s0,$s1,$s2,$s3) = @T;
        +
        +&function_begin("Camellia_cbc_encrypt");
        +	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
        +	&cmp	($s2,0);
        +	&je	(&label("enc_out"));
        +
        +	&pushf	();
        +	&cld	();
        +
        +	&mov	($s0,&wparam(0));	# load inp
        +	&mov	($s1,&wparam(1));	# load out
        +	#&mov	($s2,&wparam(2));	# load len
        +	&mov	($s3,&wparam(3));	# load key
        +	&mov	($Tbl,&wparam(4));	# load ivp
        +
        +	# allocate aligned stack frame...
        +	&lea	($idx,&DWP(-64,"esp"));
        +	&and	($idx,-64);
        +
        +	# place stack frame just "above mod 1024" the key schedule
        +	# this ensures that cache associativity of 2 suffices
        +	&lea	($key,&DWP(-64-63,$s3));
        +	&sub	($key,$idx);
        +	&neg	($key);
        +	&and	($key,0x3C0);	# modulo 1024, but aligned to cache-line
        +	&sub	($idx,$key);
        +
        +	&mov	($key,&wparam(5));	# load enc
        +
        +	&exch	("esp",$idx);
        +	&add	("esp",4);		# reserve for return address!
        +	&mov	($_esp,$idx);		# save %esp
        +
        +	&mov	($_inp,$s0);		# save copy of inp
        +	&mov	($_out,$s1);		# save copy of out
        +	&mov	($_len,$s2);		# save copy of len
        +	&mov	($_key,$s3);		# save copy of key
        +	&mov	($_ivp,$Tbl);		# save copy of ivp
        +
        +	&call   (&label("pic_point"));	# make it PIC!
        +	&set_label("pic_point");
        +	&blindpop($Tbl);
        +	&lea    ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
        +
        +	&mov	($idx,32);
        +	&set_label("prefetch_sbox",4);
        +		&mov	($s0,&DWP(0,$Tbl));
        +		&mov	($s1,&DWP(32,$Tbl));
        +		&mov	($s2,&DWP(64,$Tbl));
        +		&mov	($s3,&DWP(96,$Tbl));
        +		&lea	($Tbl,&DWP(128,$Tbl));
        +		&dec	($idx);
        +	&jnz	(&label("prefetch_sbox"));
        +	&mov	($s0,$_key);
        +	&sub	($Tbl,4096);
        +	&mov	($idx,$_inp);
        +	&mov	($s3,&DWP(272,$s0));		# load grandRounds
        +
        +	&cmp	($key,0);
        +	&je	(&label("DECRYPT"));
        +
        +	&mov	($s2,$_len);
        +	&mov	($key,$_ivp);
        +	&shl	($s3,6);
        +	&lea	($s3,&DWP(0,$s0,$s3));
        +	&mov	($_end,$s3);
        +
        +	&test	($s2,0xFFFFFFF0);
        +	&jz	(&label("enc_tail"));		# short input...
        +
        +	&mov	($s0,&DWP(0,$key));		# load iv
        +	&mov	($s1,&DWP(4,$key));
        +
        +	&set_label("enc_loop",4);
        +		&mov	($s2,&DWP(8,$key));
        +		&mov	($s3,&DWP(12,$key));
        +
        +		&xor	($s0,&DWP(0,$idx));	# xor input data
        +		&xor	($s1,&DWP(4,$idx));
        +		&xor	($s2,&DWP(8,$idx));
        +		&bswap	($s0);
        +		&xor	($s3,&DWP(12,$idx));
        +		&bswap	($s1);
        +		&mov	($key,$_key);		# load key
        +		&bswap	($s2);
        +		&bswap	($s3);
        +
        +		&call	("_x86_Camellia_encrypt");
        +
        +		&mov	($idx,$_inp);		# load inp
        +		&mov	($key,$_out);		# load out
        +
        +		&bswap	($s0);
        +		&bswap	($s1);
        +		&bswap	($s2);
        +		&mov	(&DWP(0,$key),$s0);	# save output data
        +		&bswap	($s3);
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($s2,$_len);		# load len
        +
        +		&lea	($idx,&DWP(16,$idx));
        +		&mov	($_inp,$idx);		# save inp
        +
        +		&lea	($s3,&DWP(16,$key));
        +		&mov	($_out,$s3);		# save out
        +
        +		&sub	($s2,16);
        +		&test	($s2,0xFFFFFFF0);
        +		&mov	($_len,$s2);		# save len
        +	&jnz	(&label("enc_loop"));
        +	&test	($s2,15);
        +	&jnz	(&label("enc_tail"));
        +	&mov	($idx,$_ivp);		# load ivp
        +	&mov	($s2,&DWP(8,$key));	# restore last dwords
        +	&mov	($s3,&DWP(12,$key));
        +	&mov	(&DWP(0,$idx),$s0);	# save ivec
        +	&mov	(&DWP(4,$idx),$s1);
        +	&mov	(&DWP(8,$idx),$s2);
        +	&mov	(&DWP(12,$idx),$s3);
        +
        +	&mov	("esp",$_esp);
        +	&popf	();
        +    &set_label("enc_out");
        +	&function_end_A();
        +	&pushf	();			# kludge, never executed
        +
        +    &set_label("enc_tail",4);
        +	&mov	($s0,$key eq "edi" ? $key : "");
        +	&mov	($key,$_out);			# load out
        +	&push	($s0);				# push ivp
        +	&mov	($s1,16);
        +	&sub	($s1,$s2);
        +	&cmp	($key,$idx);			# compare with inp
        +	&je	(&label("enc_in_place"));
        +	&align	(4);
        +	&data_word(0xA4F3F689);	# rep movsb	# copy input
        +	&jmp	(&label("enc_skip_in_place"));
        +    &set_label("enc_in_place");
        +	&lea	($key,&DWP(0,$key,$s2));
        +    &set_label("enc_skip_in_place");
        +	&mov	($s2,$s1);
        +	&xor	($s0,$s0);
        +	&align	(4);
        +	&data_word(0xAAF3F689);	# rep stosb	# zero tail
        +	&pop	($key);				# pop ivp
        +
        +	&mov	($idx,$_out);			# output as input
        +	&mov	($s0,&DWP(0,$key));
        +	&mov	($s1,&DWP(4,$key));
        +	&mov	($_len,16);			# len=16
        +	&jmp	(&label("enc_loop"));		# one more spin...
        +
        +#----------------------------- DECRYPT -----------------------------#
        +&set_label("DECRYPT",16);
        +	&shl	($s3,6);
        +	&lea	($s3,&DWP(0,$s0,$s3));
        +	&mov	($_end,$s0);
        +	&mov	($_key,$s3);
        +
        +	&cmp	($idx,$_out);
        +	&je	(&label("dec_in_place"));	# in-place processing...
        +
        +	&mov	($key,$_ivp);			# load ivp
        +	&mov	($_tmp,$key);
        +
        +	&set_label("dec_loop",4);
        +		&mov	($s0,&DWP(0,$idx));	# read input
        +		&mov	($s1,&DWP(4,$idx));
        +		&mov	($s2,&DWP(8,$idx));
        +		&bswap	($s0);
        +		&mov	($s3,&DWP(12,$idx));
        +		&bswap	($s1);
        +		&mov	($key,$_key);		# load key
        +		&bswap	($s2);
        +		&bswap	($s3);
        +
        +		&call	("_x86_Camellia_decrypt");
        +
        +		&mov	($key,$_tmp);		# load ivp
        +		&mov	($idx,$_len);		# load len
        +
        +		&bswap	($s0);
        +		&bswap	($s1);
        +		&bswap	($s2);
        +		&xor	($s0,&DWP(0,$key));	# xor iv
        +		&bswap	($s3);
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +		&sub	($idx,16);
        +		&jc	(&label("dec_partial"));
        +		&mov	($_len,$idx);		# save len
        +		&mov	($idx,$_inp);		# load inp
        +		&mov	($key,$_out);		# load out
        +
        +		&mov	(&DWP(0,$key),$s0);	# write output
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($_tmp,$idx);		# save ivp
        +		&lea	($idx,&DWP(16,$idx));
        +		&mov	($_inp,$idx);		# save inp
        +
        +		&lea	($key,&DWP(16,$key));
        +		&mov	($_out,$key);		# save out
        +
        +	&jnz	(&label("dec_loop"));
        +	&mov	($key,$_tmp);		# load temp ivp
        +    &set_label("dec_end");
        +	&mov	($idx,$_ivp);		# load user ivp
        +	&mov	($s0,&DWP(0,$key));	# load iv
        +	&mov	($s1,&DWP(4,$key));
        +	&mov	($s2,&DWP(8,$key));
        +	&mov	($s3,&DWP(12,$key));
        +	&mov	(&DWP(0,$idx),$s0);	# copy back to user
        +	&mov	(&DWP(4,$idx),$s1);
        +	&mov	(&DWP(8,$idx),$s2);
        +	&mov	(&DWP(12,$idx),$s3);
        +	&jmp	(&label("dec_out"));
        +
        +    &set_label("dec_partial",4);
        +	&lea	($key,$ivec);
        +	&mov	(&DWP(0,$key),$s0);	# dump output to stack
        +	&mov	(&DWP(4,$key),$s1);
        +	&mov	(&DWP(8,$key),$s2);
        +	&mov	(&DWP(12,$key),$s3);
        +	&lea	($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx));
        +	&mov	($idx eq "esi" ? $idx : "",$key);
        +	&mov	($key eq "edi" ? $key : "",$_out);	# load out
        +	&data_word(0xA4F3F689);	# rep movsb		# copy output
        +	&mov	($key,$_inp);				# use inp as temp ivp
        +	&jmp	(&label("dec_end"));
        +
        +    &set_label("dec_in_place",4);
        +	&set_label("dec_in_place_loop");
        +		&lea	($key,$ivec);
        +		&mov	($s0,&DWP(0,$idx));	# read input
        +		&mov	($s1,&DWP(4,$idx));
        +		&mov	($s2,&DWP(8,$idx));
        +		&mov	($s3,&DWP(12,$idx));
        +
        +		&mov	(&DWP(0,$key),$s0);	# copy to temp
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&bswap	($s0);
        +		&mov	(&DWP(12,$key),$s3);
        +		&bswap	($s1);
        +		&mov	($key,$_key);		# load key
        +		&bswap	($s2);
        +		&bswap	($s3);
        +
        +		&call	("_x86_Camellia_decrypt");
        +
        +		&mov	($key,$_ivp);		# load ivp
        +		&mov	($idx,$_out);		# load out
        +
        +		&bswap	($s0);
        +		&bswap	($s1);
        +		&bswap	($s2);
        +		&xor	($s0,&DWP(0,$key));	# xor iv
        +		&bswap	($s3);
        +		&xor	($s1,&DWP(4,$key));
        +		&xor	($s2,&DWP(8,$key));
        +		&xor	($s3,&DWP(12,$key));
        +
        +		&mov	(&DWP(0,$idx),$s0);	# write output
        +		&mov	(&DWP(4,$idx),$s1);
        +		&mov	(&DWP(8,$idx),$s2);
        +		&mov	(&DWP(12,$idx),$s3);
        +
        +		&lea	($idx,&DWP(16,$idx));
        +		&mov	($_out,$idx);		# save out
        +
        +		&lea	($idx,$ivec);
        +		&mov	($s0,&DWP(0,$idx));	# read temp
        +		&mov	($s1,&DWP(4,$idx));
        +		&mov	($s2,&DWP(8,$idx));
        +		&mov	($s3,&DWP(12,$idx));
        +
        +		&mov	(&DWP(0,$key),$s0);	# copy iv
        +		&mov	(&DWP(4,$key),$s1);
        +		&mov	(&DWP(8,$key),$s2);
        +		&mov	(&DWP(12,$key),$s3);
        +
        +		&mov	($idx,$_inp);		# load inp
        +
        +		&lea	($idx,&DWP(16,$idx));
        +		&mov	($_inp,$idx);		# save inp
        +
        +		&mov	($s2,$_len);		# load len
        +		&sub	($s2,16);
        +		&jc	(&label("dec_in_place_partial"));
        +		&mov	($_len,$s2);		# save len
        +	&jnz	(&label("dec_in_place_loop"));
        +	&jmp	(&label("dec_out"));
        +
        +    &set_label("dec_in_place_partial",4);
        +	# one can argue if this is actually required...
        +	&mov	($key eq "edi" ? $key : "",$_out);
        +	&lea	($idx eq "esi" ? $idx : "",$ivec);
        +	&lea	($key,&DWP(0,$key,$s2));
        +	&lea	($idx,&DWP(16,$idx,$s2));
        +	&neg	($s2 eq "ecx" ? $s2 : "");
        +	&data_word(0xA4F3F689);	# rep movsb	# restore tail
        +
        +    &set_label("dec_out",4);
        +    &mov	("esp",$_esp);
        +    &popf	();
        +&function_end("Camellia_cbc_encrypt");
        +}
        +
        +&asciz("Camellia for x86 by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl b/vendor/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl
        new file mode 100644
        index 000000000..9f4b82fa4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/asm/cmll-x86_64.pl
        @@ -0,0 +1,1081 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
        +#
        +# This module may be used under the terms of either the GNU General
        +# Public License version 2 or later, the GNU Lesser General Public
        +# License version 2.1 or later, the Mozilla Public License version
        +# 1.1 or the BSD License. The exact terms of either license are
        +# distributed along with this module. For further details see
        +# http://www.openssl.org/~appro/camellia/.
        +# ====================================================================
        +
        +# Performance in cycles per processed byte (less is better) in
        +# 'openssl speed ...' benchmark:
        +#
        +#			AMD64	Core2	EM64T
        +# -evp camellia-128-ecb	16.7	21.0	22.7
        +# + over gcc 3.4.6	+25%	+5%	0%
        +#
        +# camellia-128-cbc	15.7	20.4	21.1
        +#
        +# 128-bit key setup	128	216	205	cycles/key
        +# + over gcc 3.4.6	+54%	+39%	+15%
        +#
        +# Numbers in "+" rows represent performance improvement over compiler
        +# generated code. Key setup timings are impressive on AMD and Core2
        +# thanks to 64-bit operations being covertly deployed. Improvement on
        +# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
        +# apparently emulates some of 64-bit operations in [32-bit] microcode.
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
        +sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
        +                        $r =~ s/%[er]([sd]i)/%\1l/;
        +                        $r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
        +
        +$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
        +@S=("%r8d","%r9d","%r10d","%r11d");
        +$i0="%esi";
        +$i1="%edi";
        +$Tbl="%rbp";	# size optimization
        +$inp="%r12";
        +$out="%r13";
        +$key="%r14";
        +$keyend="%r15";
        +$arg0d=$win64?"%ecx":"%edi";
        +
        +# const unsigned int Camellia_SBOX[4][256];
        +# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
        +# and [2][] - with [3][]. This is done to minimize code size.
        +$SBOX1_1110=0;		# Camellia_SBOX[0]
        +$SBOX4_4404=4;		# Camellia_SBOX[1]
        +$SBOX2_0222=2048;	# Camellia_SBOX[2]
        +$SBOX3_3033=2052;	# Camellia_SBOX[3]
        +
        +sub Camellia_Feistel {
        +my $i=@_[0];
        +my $seed=defined(@_[1])?@_[1]:0;
        +my $scale=$seed<0?-8:8;
        +my $j=($i&1)*2;
        +my $s0=@S[($j)%4],$s1=@S[($j+1)%4],$s2=@S[($j+2)%4],$s3=@S[($j+3)%4];
        +
        +$code.=<<___;
        +	xor	$s0,$t0				# t0^=key[0]
        +	xor	$s1,$t1				# t1^=key[1]
        +	movz	`&hi("$t0")`,$i0		# (t0>>8)&0xff
        +	movz	`&lo("$t1")`,$i1		# (t1>>0)&0xff
        +	mov	$SBOX3_3033($Tbl,$i0,8),$t3	# t3=SBOX3_3033[0]
        +	mov	$SBOX1_1110($Tbl,$i1,8),$t2	# t2=SBOX1_1110[1]
        +	movz	`&lo("$t0")`,$i0		# (t0>>0)&0xff
        +	shr	\$16,$t0
        +	movz	`&hi("$t1")`,$i1		# (t1>>8)&0xff
        +	xor	$SBOX4_4404($Tbl,$i0,8),$t3	# t3^=SBOX4_4404[0]
        +	shr	\$16,$t1
        +	xor	$SBOX4_4404($Tbl,$i1,8),$t2	# t2^=SBOX4_4404[1]
        +	movz	`&hi("$t0")`,$i0		# (t0>>24)&0xff
        +	movz	`&lo("$t1")`,$i1		# (t1>>16)&0xff
        +	xor	$SBOX1_1110($Tbl,$i0,8),$t3	# t3^=SBOX1_1110[0]
        +	xor	$SBOX3_3033($Tbl,$i1,8),$t2	# t2^=SBOX3_3033[1]
        +	movz	`&lo("$t0")`,$i0		# (t0>>16)&0xff
        +	movz	`&hi("$t1")`,$i1		# (t1>>24)&0xff
        +	xor	$SBOX2_0222($Tbl,$i0,8),$t3	# t3^=SBOX2_0222[0]
        +	xor	$SBOX2_0222($Tbl,$i1,8),$t2	# t2^=SBOX2_0222[1]
        +	mov	`$seed+($i+1)*$scale`($key),$t1	# prefetch key[i+1]
        +	mov	`$seed+($i+1)*$scale+4`($key),$t0
        +	xor	$t3,$t2				# t2^=t3
        +	ror	\$8,$t3				# t3=RightRotate(t3,8)
        +	xor	$t2,$s2
        +	xor	$t2,$s3
        +	xor	$t3,$s3
        +___
        +}
        +
        +# void Camellia_EncryptBlock_Rounds(
        +#		int grandRounds,
        +#		const Byte plaintext[],
        +#		const KEY_TABLE_TYPE keyTable,
        +#		Byte ciphertext[])
        +$code=<<___;
        +.text
        +
        +# V1.x API
        +.globl	Camellia_EncryptBlock
        +.type	Camellia_EncryptBlock,\@abi-omnipotent
        +.align	16
        +Camellia_EncryptBlock:
        +	movl	\$128,%eax
        +	subl	$arg0d,%eax
        +	movl	\$3,$arg0d
        +	adcl	\$0,$arg0d	# keyBitLength==128?3:4
        +	jmp	.Lenc_rounds
        +.size	Camellia_EncryptBlock,.-Camellia_EncryptBlock
        +# V2
        +.globl	Camellia_EncryptBlock_Rounds
        +.type	Camellia_EncryptBlock_Rounds,\@function,4
        +.align	16
        +.Lenc_rounds:
        +Camellia_EncryptBlock_Rounds:
        +	push	%rbx
        +	push	%rbp
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +.Lenc_prologue:
        +
        +	#mov	%rsi,$inp		# put away arguments
        +	mov	%rcx,$out
        +	mov	%rdx,$key
        +
        +	shl	\$6,%edi		# process grandRounds
        +	lea	.LCamellia_SBOX(%rip),$Tbl
        +	lea	($key,%rdi),$keyend
        +
        +	mov	0(%rsi),@S[0]		# load plaintext
        +	mov	4(%rsi),@S[1]
        +	mov	8(%rsi),@S[2]
        +	bswap	@S[0]
        +	mov	12(%rsi),@S[3]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	bswap	@S[3]
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	bswap	@S[0]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	mov	@S[0],0($out)
        +	bswap	@S[3]
        +	mov	@S[1],4($out)
        +	mov	@S[2],8($out)
        +	mov	@S[3],12($out)
        +
        +	mov	0(%rsp),%r15
        +	mov	8(%rsp),%r14
        +	mov	16(%rsp),%r13
        +	mov	24(%rsp),%rbp
        +	mov	32(%rsp),%rbx
        +	lea	40(%rsp),%rsp
        +.Lenc_epilogue:
        +	ret
        +.size	Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
        +
        +.type	_x86_64_Camellia_encrypt,\@abi-omnipotent
        +.align	16
        +_x86_64_Camellia_encrypt:
        +	xor	0($key),@S[1]
        +	xor	4($key),@S[0]		# ^=key[0-3]
        +	xor	8($key),@S[3]
        +	xor	12($key),@S[2]
        +.align	16
        +.Leloop:
        +	mov	16($key),$t1		# prefetch key[4-5]
        +	mov	20($key),$t0
        +
        +___
        +	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); }
        +$code.=<<___;
        +	lea	16*4($key),$key
        +	cmp	$keyend,$key
        +	mov	8($key),$t3		# prefetch key[2-3]
        +	mov	12($key),$t2
        +	je	.Ledone
        +
        +	and	@S[0],$t0
        +	or	@S[3],$t3
        +	rol	\$1,$t0
        +	xor	$t3,@S[2]		# s2^=s3|key[3];
        +	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
        +	and	@S[2],$t2
        +	or	@S[1],$t1
        +	rol	\$1,$t2
        +	xor	$t1,@S[0]		# s0^=s1|key[1];
        +	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
        +	jmp	.Leloop
        +
        +.align	16
        +.Ledone:
        +	xor	@S[2],$t0		# SwapHalf
        +	xor	@S[3],$t1
        +	xor	@S[0],$t2
        +	xor	@S[1],$t3
        +
        +	mov	$t0,@S[0]
        +	mov	$t1,@S[1]
        +	mov	$t2,@S[2]
        +	mov	$t3,@S[3]
        +
        +	.byte	0xf3,0xc3		# rep ret
        +.size	_x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
        +
        +# V1.x API
        +.globl	Camellia_DecryptBlock
        +.type	Camellia_DecryptBlock,\@abi-omnipotent
        +.align	16
        +Camellia_DecryptBlock:
        +	movl	\$128,%eax
        +	subl	$arg0d,%eax
        +	movl	\$3,$arg0d
        +	adcl	\$0,$arg0d	# keyBitLength==128?3:4
        +	jmp	.Ldec_rounds
        +.size	Camellia_DecryptBlock,.-Camellia_DecryptBlock
        +# V2
        +.globl	Camellia_DecryptBlock_Rounds
        +.type	Camellia_DecryptBlock_Rounds,\@function,4
        +.align	16
        +.Ldec_rounds:
        +Camellia_DecryptBlock_Rounds:
        +	push	%rbx
        +	push	%rbp
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +.Ldec_prologue:
        +
        +	#mov	%rsi,$inp		# put away arguments
        +	mov	%rcx,$out
        +	mov	%rdx,$keyend
        +
        +	shl	\$6,%edi		# process grandRounds
        +	lea	.LCamellia_SBOX(%rip),$Tbl
        +	lea	($keyend,%rdi),$key
        +
        +	mov	0(%rsi),@S[0]		# load plaintext
        +	mov	4(%rsi),@S[1]
        +	mov	8(%rsi),@S[2]
        +	bswap	@S[0]
        +	mov	12(%rsi),@S[3]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	bswap	@S[3]
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	bswap	@S[0]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	mov	@S[0],0($out)
        +	bswap	@S[3]
        +	mov	@S[1],4($out)
        +	mov	@S[2],8($out)
        +	mov	@S[3],12($out)
        +
        +	mov	0(%rsp),%r15
        +	mov	8(%rsp),%r14
        +	mov	16(%rsp),%r13
        +	mov	24(%rsp),%rbp
        +	mov	32(%rsp),%rbx
        +	lea	40(%rsp),%rsp
        +.Ldec_epilogue:
        +	ret
        +.size	Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
        +
        +.type	_x86_64_Camellia_decrypt,\@abi-omnipotent
        +.align	16
        +_x86_64_Camellia_decrypt:
        +	xor	0($key),@S[1]
        +	xor	4($key),@S[0]		# ^=key[0-3]
        +	xor	8($key),@S[3]
        +	xor	12($key),@S[2]
        +.align	16
        +.Ldloop:
        +	mov	-8($key),$t1		# prefetch key[4-5]
        +	mov	-4($key),$t0
        +
        +___
        +	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); }
        +$code.=<<___;
        +	lea	-16*4($key),$key
        +	cmp	$keyend,$key
        +	mov	0($key),$t3		# prefetch key[2-3]
        +	mov	4($key),$t2
        +	je	.Lddone
        +
        +	and	@S[0],$t0
        +	or	@S[3],$t3
        +	rol	\$1,$t0
        +	xor	$t3,@S[2]		# s2^=s3|key[3];
        +	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
        +	and	@S[2],$t2
        +	or	@S[1],$t1
        +	rol	\$1,$t2
        +	xor	$t1,@S[0]		# s0^=s1|key[1];
        +	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
        +
        +	jmp	.Ldloop
        +
        +.align	16
        +.Lddone:
        +	xor	@S[2],$t2
        +	xor	@S[3],$t3
        +	xor	@S[0],$t0
        +	xor	@S[1],$t1
        +
        +	mov	$t2,@S[0]		# SwapHalf
        +	mov	$t3,@S[1]
        +	mov	$t0,@S[2]
        +	mov	$t1,@S[3]
        +
        +	.byte	0xf3,0xc3		# rep ret
        +.size	_x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
        +___
        +
        +sub _saveround {
        +my ($rnd,$key,@T)=@_;
        +my $bias=int(@T[0])?shift(@T):0;
        +
        +    if ($#T==3) {
        +	$code.=<<___;
        +	mov	@T[1],`$bias+$rnd*8+0`($key)
        +	mov	@T[0],`$bias+$rnd*8+4`($key)
        +	mov	@T[3],`$bias+$rnd*8+8`($key)
        +	mov	@T[2],`$bias+$rnd*8+12`($key)
        +___
        +    } else {
        +	$code.="	mov	@T[0],`$bias+$rnd*8+0`($key)\n";
        +	$code.="	mov	@T[1],`$bias+$rnd*8+8`($key)\n"	if ($#T>=1);
        +    }
        +}
        +
        +sub _loadround {
        +my ($rnd,$key,@T)=@_;
        +my $bias=int(@T[0])?shift(@T):0;
        +
        +$code.="	mov	`$bias+$rnd*8+0`($key),@T[0]\n";
        +$code.="	mov	`$bias+$rnd*8+8`($key),@T[1]\n"	if ($#T>=1);
        +}
        +
        +# shld is very slow on Intel EM64T family. Even on AMD it limits
        +# instruction decode rate [because it's VectorPath] and consequently
        +# performance...
        +sub __rotl128 {
        +my ($i0,$i1,$rot)=@_;
        +
        +    if ($rot) {
        +	$code.=<<___;
        +	mov	$i0,%r11
        +	shld	\$$rot,$i1,$i0
        +	shld	\$$rot,%r11,$i1
        +___
        +    }
        +}
        +
        +# ... Implementing 128-bit rotate without shld gives 80% better
        +# performance EM64T, +15% on AMD64 and only ~7% degradation on
        +# Core2. This is therefore preferred.
        +sub _rotl128 {
        +my ($i0,$i1,$rot)=@_;
        +
        +    if ($rot) {
        +	$code.=<<___;
        +	mov	$i0,%r11
        +	shl	\$$rot,$i0
        +	mov	$i1,%r9
        +	shr	\$`64-$rot`,%r9
        +	shr	\$`64-$rot`,%r11
        +	or	%r9,$i0
        +	shl	\$$rot,$i1
        +	or	%r11,$i1
        +___
        +    }
        +}
        +
        +{ my $step=0;
        +
        +$code.=<<___;
        +.globl	Camellia_Ekeygen
        +.type	Camellia_Ekeygen,\@function,3
        +.align	16
        +Camellia_Ekeygen:
        +	push	%rbx
        +	push	%rbp
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +.Lkey_prologue:
        +
        +	mov	%rdi,$keyend		# put away arguments, keyBitLength
        +	mov	%rdx,$out		# keyTable
        +
        +	mov	0(%rsi),@S[0]		# load 0-127 bits
        +	mov	4(%rsi),@S[1]
        +	mov	8(%rsi),@S[2]
        +	mov	12(%rsi),@S[3]
        +
        +	bswap	@S[0]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	bswap	@S[3]
        +___
        +	&_saveround	(0,$out,@S);	# KL<<<0
        +$code.=<<___;
        +	cmp	\$128,$keyend		# check keyBitLength
        +	je	.L1st128
        +
        +	mov	16(%rsi),@S[0]		# load 128-191 bits
        +	mov	20(%rsi),@S[1]
        +	cmp	\$192,$keyend
        +	je	.L1st192
        +	mov	24(%rsi),@S[2]		# load 192-255 bits
        +	mov	28(%rsi),@S[3]
        +	jmp	.L1st256
        +.L1st192:
        +	mov	@S[0],@S[2]
        +	mov	@S[1],@S[3]
        +	not	@S[2]
        +	not	@S[3]
        +.L1st256:
        +	bswap	@S[0]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	bswap	@S[3]
        +___
        +	&_saveround	(4,$out,@S);	# temp storage for KR!
        +$code.=<<___;
        +	xor	0($out),@S[1]		# KR^KL
        +	xor	4($out),@S[0]
        +	xor	8($out),@S[3]
        +	xor	12($out),@S[2]
        +
        +.L1st128:
        +	lea	.LCamellia_SIGMA(%rip),$key
        +	lea	.LCamellia_SBOX(%rip),$Tbl
        +
        +	mov	0($key),$t1
        +	mov	4($key),$t0
        +___
        +	&Camellia_Feistel($step++);
        +	&Camellia_Feistel($step++);
        +$code.=<<___;
        +	xor	0($out),@S[1]		# ^KL
        +	xor	4($out),@S[0]
        +	xor	8($out),@S[3]
        +	xor	12($out),@S[2]
        +___
        +	&Camellia_Feistel($step++);
        +	&Camellia_Feistel($step++);
        +$code.=<<___;
        +	cmp	\$128,$keyend
        +	jne	.L2nd256
        +
        +	lea	128($out),$out		# size optimization
        +	shl	\$32,%r8		# @S[0]||
        +	shl	\$32,%r10		# @S[2]||
        +	or	%r9,%r8			# ||@S[1]
        +	or	%r11,%r10		# ||@S[3]
        +___
        +	&_loadround	(0,$out,-128,"%rax","%rbx");	# KL
        +	&_saveround	(2,$out,-128,"%r8","%r10");	# KA<<<0
        +	&_rotl128	("%rax","%rbx",15);
        +	&_saveround	(4,$out,-128,"%rax","%rbx");	# KL<<<15
        +	&_rotl128	("%r8","%r10",15);
        +	&_saveround	(6,$out,-128,"%r8","%r10");	# KA<<<15
        +	&_rotl128	("%r8","%r10",15);		# 15+15=30
        +	&_saveround	(8,$out,-128,"%r8","%r10");	# KA<<<30
        +	&_rotl128	("%rax","%rbx",30);		# 15+30=45
        +	&_saveround	(10,$out,-128,"%rax","%rbx");	# KL<<<45
        +	&_rotl128	("%r8","%r10",15);		# 30+15=45
        +	&_saveround	(12,$out,-128,"%r8");		# KA<<<45
        +	&_rotl128	("%rax","%rbx",15);		# 45+15=60
        +	&_saveround	(13,$out,-128,"%rbx");		# KL<<<60
        +	&_rotl128	("%r8","%r10",15);		# 45+15=60
        +	&_saveround	(14,$out,-128,"%r8","%r10");	# KA<<<60
        +	&_rotl128	("%rax","%rbx",17);		# 60+17=77
        +	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<77
        +	&_rotl128	("%rax","%rbx",17);		# 77+17=94
        +	&_saveround	(18,$out,-128,"%rax","%rbx");	# KL<<<94
        +	&_rotl128	("%r8","%r10",34);		# 60+34=94
        +	&_saveround	(20,$out,-128,"%r8","%r10");	# KA<<<94
        +	&_rotl128	("%rax","%rbx",17);		# 94+17=111
        +	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<111
        +	&_rotl128	("%r8","%r10",17);		# 94+17=111
        +	&_saveround	(24,$out,-128,"%r8","%r10");	# KA<<<111
        +$code.=<<___;
        +	mov	\$3,%eax
        +	jmp	.Ldone
        +.align	16
        +.L2nd256:
        +___
        +	&_saveround	(6,$out,@S);	# temp storage for KA!
        +$code.=<<___;
        +	xor	`4*8+0`($out),@S[1]	# KA^KR
        +	xor	`4*8+4`($out),@S[0]
        +	xor	`5*8+0`($out),@S[3]
        +	xor	`5*8+4`($out),@S[2]
        +___
        +	&Camellia_Feistel($step++);
        +	&Camellia_Feistel($step++);
        +
        +	&_loadround	(0,$out,"%rax","%rbx");	# KL
        +	&_loadround	(4,$out,"%rcx","%rdx");	# KR
        +	&_loadround	(6,$out,"%r14","%r15");	# KA
        +$code.=<<___;
        +	lea	128($out),$out		# size optimization
        +	shl	\$32,%r8		# @S[0]||
        +	shl	\$32,%r10		# @S[2]||
        +	or	%r9,%r8			# ||@S[1]
        +	or	%r11,%r10		# ||@S[3]
        +___
        +	&_saveround	(2,$out,-128,"%r8","%r10");	# KB<<<0
        +	&_rotl128	("%rcx","%rdx",15);
        +	&_saveround	(4,$out,-128,"%rcx","%rdx");	# KR<<<15
        +	&_rotl128	("%r14","%r15",15);
        +	&_saveround	(6,$out,-128,"%r14","%r15");	# KA<<<15
        +	&_rotl128	("%rcx","%rdx",15);		# 15+15=30
        +	&_saveround	(8,$out,-128,"%rcx","%rdx");	# KR<<<30
        +	&_rotl128	("%r8","%r10",30);
        +	&_saveround	(10,$out,-128,"%r8","%r10");	# KB<<<30
        +	&_rotl128	("%rax","%rbx",45);
        +	&_saveround	(12,$out,-128,"%rax","%rbx");	# KL<<<45
        +	&_rotl128	("%r14","%r15",30);		# 15+30=45
        +	&_saveround	(14,$out,-128,"%r14","%r15");	# KA<<<45
        +	&_rotl128	("%rax","%rbx",15);		# 45+15=60
        +	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<60
        +	&_rotl128	("%rcx","%rdx",30);		# 30+30=60
        +	&_saveround	(18,$out,-128,"%rcx","%rdx");	# KR<<<60
        +	&_rotl128	("%r8","%r10",30);		# 30+30=60
        +	&_saveround	(20,$out,-128,"%r8","%r10");	# KB<<<60
        +	&_rotl128	("%rax","%rbx",17);		# 60+17=77
        +	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<77
        +	&_rotl128	("%r14","%r15",32);		# 45+32=77
        +	&_saveround	(24,$out,-128,"%r14","%r15");	# KA<<<77
        +	&_rotl128	("%rcx","%rdx",34);		# 60+34=94
        +	&_saveround	(26,$out,-128,"%rcx","%rdx");	# KR<<<94
        +	&_rotl128	("%r14","%r15",17);		# 77+17=94
        +	&_saveround	(28,$out,-128,"%r14","%r15");	# KA<<<77
        +	&_rotl128	("%rax","%rbx",34);		# 77+34=111
        +	&_saveround	(30,$out,-128,"%rax","%rbx");	# KL<<<111
        +	&_rotl128	("%r8","%r10",51);		# 60+51=111
        +	&_saveround	(32,$out,-128,"%r8","%r10");	# KB<<<111
        +$code.=<<___;
        +	mov	\$4,%eax
        +.Ldone:
        +	mov	0(%rsp),%r15
        +	mov	8(%rsp),%r14
        +	mov	16(%rsp),%r13
        +	mov	24(%rsp),%rbp
        +	mov	32(%rsp),%rbx
        +	lea	40(%rsp),%rsp
        +.Lkey_epilogue:
        +	ret
        +.size	Camellia_Ekeygen,.-Camellia_Ekeygen
        +___
        +}
        +
        +@SBOX=(
        +112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
        + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
        +134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
        +166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
        +139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
        +223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
        + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
        +254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
        +170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
        + 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
        +135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
        + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
        +233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
        +120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
        +114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
        + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
        +
        +sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); }
        +sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); }
        +sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); }
        +sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); }
        +
        +$code.=<<___;
        +.align	64
        +.LCamellia_SIGMA:
        +.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
        +.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
        +.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
        +.long	0,          0,          0,          0
        +.LCamellia_SBOX:
        +___
        +# tables are interleaved, remember?
        +sub data_word { $code.=".long\t".join(',',@_)."\n"; }
        +for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
        +for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
        +
        +# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
        +#			size_t length, const CAMELLIA_KEY *key,
        +#			unsigned char *ivp,const int enc);
        +{
        +$_key="0(%rsp)";
        +$_end="8(%rsp)";	# inp+len&~15
        +$_res="16(%rsp)";	# len&15
        +$ivec="24(%rsp)";
        +$_ivp="40(%rsp)";
        +$_rsp="48(%rsp)";
        +
        +$code.=<<___;
        +.globl	Camellia_cbc_encrypt
        +.type	Camellia_cbc_encrypt,\@function,6
        +.align	16
        +Camellia_cbc_encrypt:
        +	cmp	\$0,%rdx
        +	je	.Lcbc_abort
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +.Lcbc_prologue:
        +
        +	mov	%rsp,%rbp
        +	sub	\$64,%rsp
        +	and	\$-64,%rsp
        +
        +	# place stack frame just "above mod 1024" the key schedule,
        +	# this ensures that cache associativity suffices
        +	lea	-64-63(%rcx),%r10
        +	sub	%rsp,%r10
        +	neg	%r10
        +	and	\$0x3C0,%r10
        +	sub	%r10,%rsp
        +	#add	\$8,%rsp		# 8 is reserved for callee's ra
        +
        +	mov	%rdi,$inp		# inp argument
        +	mov	%rsi,$out		# out argument
        +	mov	%r8,%rbx		# ivp argument
        +	mov	%rcx,$key		# key argument
        +	mov	272(%rcx),${keyend}d	# grandRounds
        +
        +	mov	%r8,$_ivp
        +	mov	%rbp,$_rsp
        +
        +.Lcbc_body:
        +	lea	.LCamellia_SBOX(%rip),$Tbl
        +
        +	mov	\$32,%ecx
        +.align	4
        +.Lcbc_prefetch_sbox:
        +	mov	0($Tbl),%rax
        +	mov	32($Tbl),%rsi
        +	mov	64($Tbl),%rdi
        +	mov	96($Tbl),%r11
        +	lea	128($Tbl),$Tbl
        +	loop	.Lcbc_prefetch_sbox
        +	sub	\$4096,$Tbl
        +	shl	\$6,$keyend
        +	mov	%rdx,%rcx		# len argument
        +	lea	($key,$keyend),$keyend
        +
        +	cmp	\$0,%r9d		# enc argument
        +	je	.LCBC_DECRYPT
        +
        +	and	\$-16,%rdx
        +	and	\$15,%rcx		# length residue
        +	lea	($inp,%rdx),%rdx
        +	mov	$key,$_key
        +	mov	%rdx,$_end
        +	mov	%rcx,$_res
        +
        +	cmp	$inp,%rdx
        +	mov	0(%rbx),@S[0]		# load IV
        +	mov	4(%rbx),@S[1]
        +	mov	8(%rbx),@S[2]
        +	mov	12(%rbx),@S[3]
        +	je	.Lcbc_enc_tail
        +	jmp	.Lcbc_eloop
        +
        +.align	16
        +.Lcbc_eloop:
        +	xor	0($inp),@S[0]
        +	xor	4($inp),@S[1]
        +	xor	8($inp),@S[2]
        +	bswap	@S[0]
        +	xor	12($inp),@S[3]
        +	bswap	@S[1]
        +	bswap	@S[2]
        +	bswap	@S[3]
        +
        +	call	_x86_64_Camellia_encrypt
        +
        +	mov	$_key,$key		# "rewind" the key
        +	bswap	@S[0]
        +	mov	$_end,%rdx
        +	bswap	@S[1]
        +	mov	$_res,%rcx
        +	bswap	@S[2]
        +	mov	@S[0],0($out)
        +	bswap	@S[3]
        +	mov	@S[1],4($out)
        +	mov	@S[2],8($out)
        +	lea	16($inp),$inp
        +	mov	@S[3],12($out)
        +	cmp	%rdx,$inp
        +	lea	16($out),$out
        +	jne	.Lcbc_eloop
        +
        +	cmp	\$0,%rcx
        +	jne	.Lcbc_enc_tail
        +
        +	mov	$_ivp,$out
        +	mov	@S[0],0($out)		# write out IV residue
        +	mov	@S[1],4($out)
        +	mov	@S[2],8($out)
        +	mov	@S[3],12($out)
        +	jmp	.Lcbc_done
        +
        +.align	16
        +.Lcbc_enc_tail:
        +	xor	%rax,%rax
        +	mov	%rax,0+$ivec
        +	mov	%rax,8+$ivec
        +	mov	%rax,$_res
        +
        +.Lcbc_enc_pushf:
        +	pushfq
        +	cld
        +	mov	$inp,%rsi
        +	lea	8+$ivec,%rdi
        +	.long	0x9066A4F3		# rep movsb
        +	popfq
        +.Lcbc_enc_popf:
        +
        +	lea	$ivec,$inp
        +	lea	16+$ivec,%rax
        +	mov	%rax,$_end
        +	jmp	.Lcbc_eloop		# one more time
        +
        +.align	16
        +.LCBC_DECRYPT:
        +	xchg	$key,$keyend
        +	add	\$15,%rdx
        +	and	\$15,%rcx		# length residue
        +	and	\$-16,%rdx
        +	mov	$key,$_key
        +	lea	($inp,%rdx),%rdx
        +	mov	%rdx,$_end
        +	mov	%rcx,$_res
        +
        +	mov	(%rbx),%rax		# load IV
        +	mov	8(%rbx),%rbx
        +	jmp	.Lcbc_dloop
        +.align	16
        +.Lcbc_dloop:
        +	mov	0($inp),@S[0]
        +	mov	4($inp),@S[1]
        +	mov	8($inp),@S[2]
        +	bswap	@S[0]
        +	mov	12($inp),@S[3]
        +	bswap	@S[1]
        +	mov	%rax,0+$ivec		# save IV to temporary storage
        +	bswap	@S[2]
        +	mov	%rbx,8+$ivec
        +	bswap	@S[3]
        +
        +	call	_x86_64_Camellia_decrypt
        +
        +	mov	$_key,$key		# "rewind" the key
        +	mov	$_end,%rdx
        +	mov	$_res,%rcx
        +
        +	bswap	@S[0]
        +	mov	($inp),%rax		# load IV for next iteration
        +	bswap	@S[1]
        +	mov	8($inp),%rbx
        +	bswap	@S[2]
        +	xor	0+$ivec,@S[0]
        +	bswap	@S[3]
        +	xor	4+$ivec,@S[1]
        +	xor	8+$ivec,@S[2]
        +	lea	16($inp),$inp
        +	xor	12+$ivec,@S[3]
        +	cmp	%rdx,$inp
        +	je	.Lcbc_ddone
        +
        +	mov	@S[0],0($out)
        +	mov	@S[1],4($out)
        +	mov	@S[2],8($out)
        +	mov	@S[3],12($out)
        +
        +	lea	16($out),$out
        +	jmp	.Lcbc_dloop
        +
        +.align	16
        +.Lcbc_ddone:
        +	mov	$_ivp,%rdx
        +	cmp	\$0,%rcx
        +	jne	.Lcbc_dec_tail
        +
        +	mov	@S[0],0($out)
        +	mov	@S[1],4($out)
        +	mov	@S[2],8($out)
        +	mov	@S[3],12($out)
        +
        +	mov	%rax,(%rdx)		# write out IV residue
        +	mov	%rbx,8(%rdx)
        +	jmp	.Lcbc_done
        +.align	16
        +.Lcbc_dec_tail:
        +	mov	@S[0],0+$ivec
        +	mov	@S[1],4+$ivec
        +	mov	@S[2],8+$ivec
        +	mov	@S[3],12+$ivec
        +
        +.Lcbc_dec_pushf:
        +	pushfq
        +	cld
        +	lea	8+$ivec,%rsi
        +	lea	($out),%rdi
        +	.long	0x9066A4F3		# rep movsb
        +	popfq
        +.Lcbc_dec_popf:
        +
        +	mov	%rax,(%rdx)		# write out IV residue
        +	mov	%rbx,8(%rdx)
        +	jmp	.Lcbc_done
        +
        +.align	16
        +.Lcbc_done:
        +	mov	$_rsp,%rcx
        +	mov	0(%rcx),%r15
        +	mov	8(%rcx),%r14
        +	mov	16(%rcx),%r13
        +	mov	24(%rcx),%r12
        +	mov	32(%rcx),%rbp
        +	mov	40(%rcx),%rbx
        +	lea	48(%rcx),%rsp
        +.Lcbc_abort:
        +	ret
        +.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
        +
        +.asciz	"Camellia for x86_64 by <appro\@openssl.org>"
        +___
        +}
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	common_se_handler,\@abi-omnipotent
        +.align	16
        +common_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	lea	-64(%rsp),%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_prologue
        +
        +	lea	40(%rax),%rax
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r13
        +	mov	-32(%rax),%r14
        +	mov	-40(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	jmp	.Lcommon_seh_exit
        +.size	common_se_handler,.-common_se_handler
        +
        +.type	cbc_se_handler,\@abi-omnipotent
        +.align	16
        +cbc_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	lea	-64(%rsp),%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lcbc_prologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
        +	jb	.Lin_cbc_prologue
        +
        +	lea	.Lcbc_body(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_body
        +	jb	.Lin_cbc_frame_setup
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lcbc_abort(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lcbc_abort
        +	jae	.Lin_cbc_prologue
        +
        +	# handle pushf/popf in Camellia_cbc_encrypt
        +	lea	.Lcbc_enc_pushf(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<=.Lcbc_enc_pushf
        +	jbe	.Lin_cbc_no_flag
        +	lea	8(%rax),%rax
        +	lea	.Lcbc_enc_popf(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_enc_popf
        +	jb	.Lin_cbc_no_flag
        +	lea	-8(%rax),%rax
        +	lea	.Lcbc_dec_pushf(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<=.Lcbc_dec_pushf
        +	jbe	.Lin_cbc_no_flag
        +	lea	8(%rax),%rax
        +	lea	.Lcbc_dec_popf(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lcbc_dec_popf
        +	jb	.Lin_cbc_no_flag
        +	lea	-8(%rax),%rax
        +
        +.Lin_cbc_no_flag:
        +	mov	48(%rax),%rax		# $_rsp
        +	lea	48(%rax),%rax
        +
        +.Lin_cbc_frame_setup:
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_cbc_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +.align	4
        +.Lcommon_seh_exit:
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	lea	64(%rsp),%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	cbc_se_handler,.-cbc_se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_Camellia_EncryptBlock_Rounds
        +	.rva	.LSEH_end_Camellia_EncryptBlock_Rounds
        +	.rva	.LSEH_info_Camellia_EncryptBlock_Rounds
        +
        +	.rva	.LSEH_begin_Camellia_DecryptBlock_Rounds
        +	.rva	.LSEH_end_Camellia_DecryptBlock_Rounds
        +	.rva	.LSEH_info_Camellia_DecryptBlock_Rounds
        +
        +	.rva	.LSEH_begin_Camellia_Ekeygen
        +	.rva	.LSEH_end_Camellia_Ekeygen
        +	.rva	.LSEH_info_Camellia_Ekeygen
        +
        +	.rva	.LSEH_begin_Camellia_cbc_encrypt
        +	.rva	.LSEH_end_Camellia_cbc_encrypt
        +	.rva	.LSEH_info_Camellia_cbc_encrypt
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_Camellia_EncryptBlock_Rounds:
        +	.byte	9,0,0,0
        +	.rva	common_se_handler
        +	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
        +.LSEH_info_Camellia_DecryptBlock_Rounds:
        +	.byte	9,0,0,0
        +	.rva	common_se_handler
        +	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
        +.LSEH_info_Camellia_Ekeygen:
        +	.byte	9,0,0,0
        +	.rva	common_se_handler
        +	.rva	.Lkey_prologue,.Lkey_epilogue	# HandlerData[]
        +.LSEH_info_Camellia_cbc_encrypt:
        +	.byte	9,0,0,0
        +	.rva	cbc_se_handler
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/camellia/camellia.c b/vendor/openssl/openssl/crypto/camellia/camellia.c
        new file mode 100644
        index 000000000..75fc8991c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/camellia.c
        @@ -0,0 +1,582 @@
        +/* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
        + * ALL RIGHTS RESERVED.
        + *
        + * Intellectual Property information for Camellia:
        + *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
        + *
        + * News Release for Announcement of Camellia open source:
        + *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
        + *
        + * The Camellia Code included herein is developed by
        + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
        + * to the OpenSSL project.
        + *
        + * The Camellia Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + */
        +
        +/* Algorithm Specification 
        +   http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
        +*/
        + 
        +/*
        + * This release balances code size and performance. In particular key
        + * schedule setup is fully unrolled, because doing so *significantly*
        + * reduces amount of instructions per setup round and code increase is
        + * justifiable. In block functions on the other hand only inner loops
        + * are unrolled, as full unroll gives only nominal performance boost,
        + * while code size grows 4 or 7 times. Also, unlike previous versions
        + * this one "encourages" compiler to keep intermediate variables in
        + * registers, which should give better "all round" results, in other
        + * words reasonable performance even with not so modern compilers.
        + */
        +
        +#include "camellia.h"
        +#include "cmll_locl.h"
        +#include <string.h>
        +#include <stdlib.h>
        +
        +/* 32-bit rotations */
        +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
        +#  define RightRotate(x, s) _lrotr(x, s)
        +#  define LeftRotate(x, s)  _lrotl(x, s)
        +#  if _MSC_VER >= 1400
        +#   define SWAP(x) _byteswap_ulong(x)
        +#  else
        +#   define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
        +#  endif
        +#  define GETU32(p)   SWAP(*((u32 *)(p)))
        +#  define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v)))
        +# elif defined(__GNUC__) && __GNUC__>=2
        +#  if defined(__i386) || defined(__x86_64)
        +#   define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
        +#   define LeftRotate(x,s)  ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
        +#   if defined(B_ENDIAN) /* stratus.com does it */
        +#    define GETU32(p)   (*(u32 *)(p))
        +#    define PUTU32(p,v) (*(u32 *)(p)=(v))
        +#   else
        +#    define GETU32(p)   ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
        +#    define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
        +#   endif
        +#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
        +        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
        +#   define LeftRotate(x,s)  ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
        +#   define RightRotate(x,s) LeftRotate(x,(32-s))
        +#  elif defined(__s390x__)
        +#   define LeftRotate(x,s)  ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
        +#   define RightRotate(x,s) LeftRotate(x,(32-s))
        +#   define GETU32(p)   (*(u32 *)(p))
        +#   define PUTU32(p,v) (*(u32 *)(p)=(v))
        +#  endif
        +# endif
        +#endif
        +
        +#if !defined(RightRotate) && !defined(LeftRotate)
        +# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
        +# define LeftRotate(x, s)  ( ((x) << (s)) + ((x) >> (32 - s)) )
        +#endif
        +
        +#if !defined(GETU32) && !defined(PUTU32)
        +# define GETU32(p)   (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] <<  8) ^ ((u32)(p)[3]))
        +# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >>  8), (p)[3] = (u8)(v))
        +#endif
        +
        +/* S-box data */
        +#define SBOX1_1110 Camellia_SBOX[0]
        +#define SBOX4_4404 Camellia_SBOX[1]
        +#define SBOX2_0222 Camellia_SBOX[2]
        +#define SBOX3_3033 Camellia_SBOX[3]
        +static const u32 Camellia_SBOX[][256] = {
        +{   0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 
        +    0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 
        +    0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, 
        +    0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, 
        +    0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 
        +    0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 
        +    0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, 
        +    0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, 
        +    0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 
        +    0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 
        +    0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, 
        +    0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, 
        +    0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 
        +    0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 
        +    0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, 
        +    0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, 
        +    0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 
        +    0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 
        +    0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, 
        +    0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, 
        +    0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 
        +    0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 
        +    0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, 
        +    0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, 
        +    0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 
        +    0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 
        +    0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, 
        +    0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, 
        +    0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 
        +    0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 
        +    0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, 
        +    0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, 
        +    0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 
        +    0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 
        +    0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, 
        +    0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, 
        +    0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 
        +    0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 
        +    0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, 
        +    0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, 
        +    0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 
        +    0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 
        +    0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 },
        +{   0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 
        +    0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 
        +    0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, 
        +    0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, 
        +    0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 
        +    0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 
        +    0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, 
        +    0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, 
        +    0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 
        +    0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 
        +    0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, 
        +    0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, 
        +    0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 
        +    0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 
        +    0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, 
        +    0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, 
        +    0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 
        +    0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 
        +    0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, 
        +    0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, 
        +    0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 
        +    0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 
        +    0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, 
        +    0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, 
        +    0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 
        +    0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 
        +    0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, 
        +    0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, 
        +    0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 
        +    0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 
        +    0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, 
        +    0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, 
        +    0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 
        +    0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 
        +    0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, 
        +    0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, 
        +    0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 
        +    0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 
        +    0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, 
        +    0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, 
        +    0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 
        +    0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 
        +    0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e },
        +{   0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 
        +    0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 
        +    0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, 
        +    0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, 
        +    0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 
        +    0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 
        +    0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, 
        +    0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, 
        +    0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 
        +    0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 
        +    0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, 
        +    0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, 
        +    0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 
        +    0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 
        +    0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, 
        +    0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, 
        +    0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 
        +    0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 
        +    0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, 
        +    0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, 
        +    0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 
        +    0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 
        +    0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, 
        +    0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, 
        +    0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 
        +    0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 
        +    0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, 
        +    0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, 
        +    0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 
        +    0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 
        +    0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, 
        +    0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, 
        +    0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 
        +    0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 
        +    0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, 
        +    0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, 
        +    0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 
        +    0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 
        +    0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, 
        +    0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, 
        +    0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 
        +    0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 
        +    0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d },
        +{   0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 
        +    0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 
        +    0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, 
        +    0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, 
        +    0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 
        +    0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 
        +    0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, 
        +    0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, 
        +    0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 
        +    0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 
        +    0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, 
        +    0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, 
        +    0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 
        +    0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 
        +    0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, 
        +    0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, 
        +    0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 
        +    0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 
        +    0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, 
        +    0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, 
        +    0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 
        +    0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 
        +    0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, 
        +    0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, 
        +    0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 
        +    0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 
        +    0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, 
        +    0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, 
        +    0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 
        +    0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 
        +    0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, 
        +    0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, 
        +    0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 
        +    0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 
        +    0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, 
        +    0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, 
        +    0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 
        +    0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 
        +    0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, 
        +    0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, 
        +    0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 
        +    0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 
        +    0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f }
        +};
        +
        +/* Key generation constants */
        +static const u32 SIGMA[] = {
        +    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
        +    0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
        +};
        +
        +/* The phi algorithm given in C.2.7 of the Camellia spec document. */
        +/*
        + * This version does not attempt to minimize amount of temporary
        + * variables, but instead explicitly exposes algorithm's parallelism.
        + * It is therefore most appropriate for platforms with not less than
        + * ~16 registers. For platforms with less registers [well, x86 to be
        + * specific] assembler version should be/is provided anyway...
        + */
        +#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\
        +	register u32 _t0,_t1,_t2,_t3;\
        +\
        +	_t0  = _s0 ^ (_key)[0];\
        +	_t3  = SBOX4_4404[_t0&0xff];\
        +	_t1  = _s1 ^ (_key)[1];\
        +	_t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\
        +	_t2  = SBOX1_1110[_t1&0xff];\
        +	_t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\
        +	_t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\
        +	_t3 ^= SBOX1_1110[(_t0 >> 24)];\
        +	_t2 ^= _t3;\
        +	_t3  = RightRotate(_t3,8);\
        +	_t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\
        +	_s3 ^= _t3;\
        +	_t2 ^= SBOX2_0222[(_t1 >> 24)];\
        +	_s2 ^= _t2; \
        +	_s3 ^= _t2;\
        +} while(0)
        +
        +/*
        + * Note that n has to be less than 32. Rotations for larger amount
        + * of bits are achieved by "rotating" order of s-elements and
        + * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32).
        + */
        +#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\
        +	u32 _t0=_s0>>(32-_n);\
        +	_s0 = (_s0<<_n) | (_s1>>(32-_n));\
        +	_s1 = (_s1<<_n) | (_s2>>(32-_n));\
        +	_s2 = (_s2<<_n) | (_s3>>(32-_n));\
        +	_s3 = (_s3<<_n) | _t0;\
        +} while (0)
        +
        +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
        +	{
        +	register u32 s0,s1,s2,s3;
        +
        +	k[0] = s0 = GETU32(rawKey);
        +	k[1] = s1 = GETU32(rawKey+4);
        +	k[2] = s2 = GETU32(rawKey+8);
        +	k[3] = s3 = GETU32(rawKey+12);
        +
        +	if (keyBitLength != 128)
        +		{
        +		k[8] = s0 = GETU32(rawKey+16);
        +		k[9] = s1 = GETU32(rawKey+20);
        +		if (keyBitLength == 192)
        +			{
        +			k[10] = s2 = ~s0;
        +			k[11] = s3 = ~s1;
        +			}
        +		else
        +			{
        +			k[10] = s2 = GETU32(rawKey+24);
        +			k[11] = s3 = GETU32(rawKey+28);
        +			}
        +		s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
        +		}
        +
        +	/* Use the Feistel routine to scramble the key material */
        +	Camellia_Feistel(s0,s1,s2,s3,SIGMA+0);
        +	Camellia_Feistel(s2,s3,s0,s1,SIGMA+2);
        +
        +	s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
        +	Camellia_Feistel(s0,s1,s2,s3,SIGMA+4);
        +	Camellia_Feistel(s2,s3,s0,s1,SIGMA+6);
        +
        +	/* Fill the keyTable. Requires many block rotations. */
        +	if (keyBitLength == 128)
        +		{
        +		k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
        +		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 15 */
        +		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
        +		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 30 */
        +		k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
        +		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 45 */
        +		k[24] = s0, k[25] = s1;
        +		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 60 */
        +		k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
        +		RotLeft128(s1,s2,s3,s0,2);	/* KA <<< 94 */
        +		k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
        +		RotLeft128(s1,s2,s3,s0,17);	/* KA <<<111 */
        +		k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
        +
        +		s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
        +		RotLeft128(s0,s1,s2,s3,15);	/* KL <<< 15 */
        +		k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
        +		RotLeft128(s0,s1,s2,s3,30);	/* KL <<< 45 */
        +		k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
        +		RotLeft128(s0,s1,s2,s3,15);	/* KL <<< 60 */
        +		k[26] = s2, k[27] = s3;
        +		RotLeft128(s0,s1,s2,s3,17);	/* KL <<< 77 */
        +		k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
        +		RotLeft128(s0,s1,s2,s3,17);	/* KL <<< 94 */
        +		k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
        +		RotLeft128(s0,s1,s2,s3,17);	/* KL <<<111 */
        +		k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
        +
        +		return 3;	/* grand rounds */
        +		}
        +	else
        +		{
        +		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
        +		s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11];
        +		Camellia_Feistel(s0,s1,s2,s3,(SIGMA+8));
        +		Camellia_Feistel(s2,s3,s0,s1,(SIGMA+10));
        +
        +		k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
        +		RotLeft128(s0,s1,s2,s3,30);	/* KB <<< 30 */
        +		k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
        +		RotLeft128(s0,s1,s2,s3,30);	/* KB <<< 60 */
        +		k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
        +		RotLeft128(s1,s2,s3,s0,19);	/* KB <<<111 */
        +		k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
        +
        +		s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11];
        +		RotLeft128(s0,s1,s2,s3,15);	/* KR <<< 15 */
        +		k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
        +		RotLeft128(s0,s1,s2,s3,15);	/* KR <<< 30 */
        +		k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
        +		RotLeft128(s0,s1,s2,s3,30);	/* KR <<< 60 */
        +		k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
        +		RotLeft128(s1,s2,s3,s0,2);	/* KR <<< 94 */
        +		k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
        +
        +		s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
        +		RotLeft128(s0,s1,s2,s3,15);	/* KA <<< 15 */
        +		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
        +		RotLeft128(s0,s1,s2,s3,30);	/* KA <<< 45 */
        +		k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
        +						/* KA <<< 77 */
        +		k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
        +		RotLeft128(s1,s2,s3,s0,17);	/* KA <<< 94 */
        +		k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
        +
        +		s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
        +		RotLeft128(s1,s2,s3,s0,13);	/* KL <<< 45 */
        +		k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
        +		RotLeft128(s1,s2,s3,s0,15);	/* KL <<< 60 */
        +		k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
        +		RotLeft128(s1,s2,s3,s0,17);	/* KL <<< 77 */
        +		k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
        +		RotLeft128(s2,s3,s0,s1,2);	/* KL <<<111 */
        +		k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
        +
        +		return 4;	/* grand rounds */
        +		}
        +	/*
        +	 * It is possible to perform certain precalculations, which
        +	 * would spare few cycles in block procedure. It's not done,
        +	 * because it upsets the performance balance between key
        +	 * setup and block procedures, negatively affecting overall
        +	 * throughput in applications operating on short messages
        +	 * and volatile keys.
        +	 */ 
        +	}
        +
        +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
        +	{
        +	register u32 s0,s1,s2,s3; 
        +	const u32 *k = keyTable,*kend = keyTable+grandRounds*16; 
        +
        +	s0 = GETU32(plaintext)    ^ k[0];
        +	s1 = GETU32(plaintext+4)  ^ k[1];
        +	s2 = GETU32(plaintext+8)  ^ k[2];
        +	s3 = GETU32(plaintext+12) ^ k[3];
        +	k += 4;
        +
        +	while (1)
        +		{
        +		/* Camellia makes 6 Feistel rounds */
        +		Camellia_Feistel(s0,s1,s2,s3,k+0);
        +		Camellia_Feistel(s2,s3,s0,s1,k+2);
        +		Camellia_Feistel(s0,s1,s2,s3,k+4);
        +		Camellia_Feistel(s2,s3,s0,s1,k+6);
        +		Camellia_Feistel(s0,s1,s2,s3,k+8);
        +		Camellia_Feistel(s2,s3,s0,s1,k+10);
        +		k += 12;
        +
        +		if (k == kend) break;
        +
        +		/* This is the same function as the diffusion function D
        +		 * of the accompanying documentation. See section 3.2
        +		 * for properties of the FLlayer function. */
        +		s1 ^= LeftRotate(s0 & k[0], 1);
        +		s2 ^= s3 | k[3];
        +		s0 ^= s1 | k[1];
        +		s3 ^= LeftRotate(s2 & k[2], 1);
        +		k += 4;
        +		}
        +
        +	s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
        +
        +	PUTU32(ciphertext,   s2);
        +	PUTU32(ciphertext+4, s3);
        +	PUTU32(ciphertext+8, s0);
        +	PUTU32(ciphertext+12,s1);
        +	}
        +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
        +	{
        +	Camellia_EncryptBlock_Rounds(keyBitLength==128?3:4,
        +			plaintext,keyTable,ciphertext);
        +	}
        +
        +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 plaintext[])
        +	{
        +	u32 s0,s1,s2,s3; 
        +	const u32 *k = keyTable+grandRounds*16,*kend = keyTable+4; 
        +
        +	s0 = GETU32(ciphertext)    ^ k[0];
        +	s1 = GETU32(ciphertext+4)  ^ k[1];
        +	s2 = GETU32(ciphertext+8)  ^ k[2];
        +	s3 = GETU32(ciphertext+12) ^ k[3];
        +
        +	while (1)
        +		{
        +		/* Camellia makes 6 Feistel rounds */
        +		k -= 12;
        +		Camellia_Feistel(s0,s1,s2,s3,k+10);
        +		Camellia_Feistel(s2,s3,s0,s1,k+8);
        +		Camellia_Feistel(s0,s1,s2,s3,k+6);
        +		Camellia_Feistel(s2,s3,s0,s1,k+4);
        +		Camellia_Feistel(s0,s1,s2,s3,k+2);
        +		Camellia_Feistel(s2,s3,s0,s1,k+0);
        +
        +		if (k == kend) break;
        +
        +		/* This is the same function as the diffusion function D
        +		 * of the accompanying documentation. See section 3.2
        +		 * for properties of the FLlayer function. */
        +		k -= 4;
        +		s1 ^= LeftRotate(s0 & k[2], 1);
        +		s2 ^= s3 | k[1];
        +		s0 ^= s1 | k[3];
        +		s3 ^= LeftRotate(s2 & k[0], 1);
        +		}
        +
        +	k -= 4;
        +	s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
        +
        +	PUTU32(plaintext,   s2);
        +	PUTU32(plaintext+4, s3);
        +	PUTU32(plaintext+8, s0);
        +	PUTU32(plaintext+12,s1);
        +	}
        +void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
        +	{
        +	Camellia_DecryptBlock_Rounds(keyBitLength==128?3:4,
        +			plaintext,keyTable,ciphertext);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/camellia/camellia.h b/vendor/openssl/openssl/crypto/camellia/camellia.h
        new file mode 100644
        index 000000000..67911e0ad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/camellia.h
        @@ -0,0 +1,130 @@
        +/* crypto/camellia/camellia.h -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#ifndef HEADER_CAMELLIA_H
        +#define HEADER_CAMELLIA_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_CAMELLIA
        +#error CAMELLIA is disabled.
        +#endif
        +
        +#include <stddef.h>
        +
        +#define CAMELLIA_ENCRYPT	1
        +#define CAMELLIA_DECRYPT	0
        +
        +/* Because array size can't be a const in C, the following two are macros.
        +   Both sizes are in bytes. */
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* This should be a hidden type, but EVP requires that the size be known */
        +
        +#define CAMELLIA_BLOCK_SIZE 16
        +#define CAMELLIA_TABLE_BYTE_LEN 272
        +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
        +
        +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */
        +
        +struct camellia_key_st 
        +	{
        +	union	{
        +		double d;	/* ensures 64-bit align */
        +		KEY_TABLE_TYPE rd_key;
        +		} u;
        +	int grand_rounds;
        +	};
        +typedef struct camellia_key_st CAMELLIA_KEY;
        +
        +#ifdef OPENSSL_FIPS
        +int private_Camellia_set_key(const unsigned char *userKey, const int bits,
        +	CAMELLIA_KEY *key);
        +#endif
        +int Camellia_set_key(const unsigned char *userKey, const int bits,
        +	CAMELLIA_KEY *key);
        +
        +void Camellia_encrypt(const unsigned char *in, unsigned char *out,
        +	const CAMELLIA_KEY *key);
        +void Camellia_decrypt(const unsigned char *in, unsigned char *out,
        +	const CAMELLIA_KEY *key);
        +
        +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	const CAMELLIA_KEY *key, const int enc);
        +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, const int enc);
        +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num, const int enc);
        +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num, const int enc);
        +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num, const int enc);
        +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num);
        +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
        +	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
        +	unsigned int *num);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* !HEADER_Camellia_H */
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_cbc.c b/vendor/openssl/openssl/crypto/camellia/cmll_cbc.c
        new file mode 100644
        index 000000000..4c8d455ad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_cbc.c
        @@ -0,0 +1,64 @@
        +/* crypto/camellia/camellia_cbc.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/camellia.h>
        +#include <openssl/modes.h>
        +
        +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t len, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, const int enc) 
        +	{
        +
        +	if (enc)
        +		CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)Camellia_encrypt);
        +	else
        +		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)Camellia_decrypt);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_cfb.c b/vendor/openssl/openssl/crypto/camellia/cmll_cfb.c
        new file mode 100644
        index 000000000..3d81b51d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_cfb.c
        @@ -0,0 +1,139 @@
        +/* crypto/camellia/camellia_cfb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +/* 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 <openssl/camellia.h>
        +#include <openssl/modes.h>
        +
        +
        +/* The input and output encrypted as though 128bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 128bit block we have used is contained in *num;
        + */
        +
        +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num, const int enc)
        +	{
        +
        +	CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
        +	}
        +
        +/* N.B. This expects the input to be packed, MS bit first */
        +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num, const int enc)
        +	{
        +	CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
        +	}
        +
        +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num, const int enc)
        +	{
        +	CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_ctr.c b/vendor/openssl/openssl/crypto/camellia/cmll_ctr.c
        new file mode 100644
        index 000000000..014e621a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_ctr.c
        @@ -0,0 +1,64 @@
        +/* crypto/camellia/camellia_ctr.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/camellia.h>
        +#include <openssl/modes.h>
        +
        +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
        +	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
        +	unsigned int *num) 
        +	{
        +
        +	CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)Camellia_encrypt);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_ecb.c b/vendor/openssl/openssl/crypto/camellia/cmll_ecb.c
        new file mode 100644
        index 000000000..70dc0e563
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_ecb.c
        @@ -0,0 +1,74 @@
        +/* crypto/camellia/camellia_ecb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#ifndef CAMELLIA_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +#include <openssl/camellia.h>
        +#include "cmll_locl.h"
        +
        +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	const CAMELLIA_KEY *key, const int enc) 
        +	{
        +
        +	assert(in && out && key);
        +	assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
        +
        +	if (CAMELLIA_ENCRYPT == enc)
        +		Camellia_encrypt(in, out, key);
        +	else
        +		Camellia_decrypt(in, out, key);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_locl.h b/vendor/openssl/openssl/crypto/camellia/cmll_locl.h
        new file mode 100644
        index 000000000..246b6ce1d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_locl.h
        @@ -0,0 +1,86 @@
        +/* crypto/camellia/camellia_locl.h -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
        + * ALL RIGHTS RESERVED.
        + *
        + * Intellectual Property information for Camellia:
        + *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
        + *
        + * News Release for Announcement of Camellia open source:
        + *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
        + *
        + * The Camellia Code included herein is developed by
        + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
        + * to the OpenSSL project.
        + *
        + * The Camellia Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + */
        +
        +#ifndef HEADER_CAMELLIA_LOCL_H
        +#define HEADER_CAMELLIA_LOCL_H
        +
        +typedef unsigned int  u32;
        +typedef unsigned char u8;
        +
        +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey,
        +		     KEY_TABLE_TYPE keyTable);
        +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
        +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
        +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
        +void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], 
        +		const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
        +int private_Camellia_set_key(const unsigned char *userKey, const int bits,
        +			     CAMELLIA_KEY *key);
        +#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_misc.c b/vendor/openssl/openssl/crypto/camellia/cmll_misc.c
        new file mode 100644
        index 000000000..f44d48564
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_misc.c
        @@ -0,0 +1,80 @@
        +/* crypto/camellia/camellia_misc.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        + 
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +#include <openssl/camellia.h>
        +#include "cmll_locl.h"
        +
        +const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
        +
        +int private_Camellia_set_key(const unsigned char *userKey, const int bits,
        +	CAMELLIA_KEY *key)
        +	{
        +	if(!userKey || !key)
        +		return -1;
        +	if(bits != 128 && bits != 192 && bits != 256)
        +		return -2;
        +	key->grand_rounds = Camellia_Ekeygen(bits , userKey, key->u.rd_key);
        +	return 0;
        +	}
        +
        +void Camellia_encrypt(const unsigned char *in, unsigned char *out,
        +	const CAMELLIA_KEY *key)
        +	{
        +	Camellia_EncryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out);
        +	}
        +
        +void Camellia_decrypt(const unsigned char *in, unsigned char *out,
        +	const CAMELLIA_KEY *key)
        +	{
        +	Camellia_DecryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_ofb.c b/vendor/openssl/openssl/crypto/camellia/cmll_ofb.c
        new file mode 100644
        index 000000000..a482befc7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_ofb.c
        @@ -0,0 +1,119 @@
        +/* crypto/camellia/camellia_ofb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +/* 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 <openssl/camellia.h>
        +#include <openssl/modes.h>
        +
        +/* The input and output encrypted as though 128bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 128bit block we have used is contained in *num;
        + */
        +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +	size_t length, const CAMELLIA_KEY *key,
        +	unsigned char *ivec, int *num) {
        +	CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)Camellia_encrypt);
        +}
        diff --git a/vendor/openssl/openssl/crypto/camellia/cmll_utl.c b/vendor/openssl/openssl/crypto/camellia/cmll_utl.c
        new file mode 100644
        index 000000000..7a35711ec
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/camellia/cmll_utl.c
        @@ -0,0 +1,64 @@
        +/* crypto/camellia/cmll_utl.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + *
        + */
        + 
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +#include <openssl/camellia.h>
        +#include "cmll_locl.h"
        +
        +int Camellia_set_key(const unsigned char *userKey, const int bits,
        +	CAMELLIA_KEY *key)
        +	{
        +#ifdef OPENSSL_FIPS
        +	fips_cipher_abort(Camellia);
        +#endif
        +	return private_Camellia_set_key(userKey, bits, key);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cast/Makefile b/vendor/openssl/openssl/crypto/cast/Makefile
        new file mode 100644
        index 000000000..f3f485988
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/Makefile
        @@ -0,0 +1,102 @@
        +#
        +# OpenSSL/crypto/cast/Makefile
        +#
        +
        +DIR=	cast
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CAST_ENC=c_enc.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=casttest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c 
        +LIBOBJ=c_skey.o c_ecb.o $(CAST_ENC) c_cfb64.o c_ofb64.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= cast.h
        +HEADER=	cast_s.h cast_lcl.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +cast-586.s:	asm/cast-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
        +	$(PERL)	asm/cast-586.pl $(PERLASM_SCHEME) $(CLAGS) $(PROCESSOR) > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +c_cfb64.o: ../../e_os.h ../../include/openssl/cast.h
        +c_cfb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +c_cfb64.o: c_cfb64.c cast_lcl.h
        +c_ecb.o: ../../e_os.h ../../include/openssl/cast.h
        +c_ecb.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +c_ecb.o: ../../include/openssl/opensslv.h c_ecb.c cast_lcl.h
        +c_enc.o: ../../e_os.h ../../include/openssl/cast.h
        +c_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +c_enc.o: c_enc.c cast_lcl.h
        +c_ofb64.o: ../../e_os.h ../../include/openssl/cast.h
        +c_ofb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +c_ofb64.o: c_ofb64.c cast_lcl.h
        +c_skey.o: ../../e_os.h ../../include/openssl/cast.h
        +c_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +c_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +c_skey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +c_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +c_skey.o: c_skey.c cast_lcl.h cast_s.h
        diff --git a/vendor/openssl/openssl/crypto/cast/asm/cast-586.pl b/vendor/openssl/openssl/crypto/cast/asm/cast-586.pl
        new file mode 100644
        index 000000000..bf6810d33
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/asm/cast-586.pl
        @@ -0,0 +1,177 @@
        +#!/usr/local/bin/perl
        +
        +# define for pentium pro friendly version
        +$ppro=1;
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +require "cbc.pl";
        +
        +&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386");
        +
        +$CAST_ROUNDS=16;
        +$L="edi";
        +$R="esi";
        +$K="ebp";
        +$tmp1="ecx";
        +$tmp2="ebx";
        +$tmp3="eax";
        +$tmp4="edx";
        +$S1="CAST_S_table0";
        +$S2="CAST_S_table1";
        +$S3="CAST_S_table2";
        +$S4="CAST_S_table3";
        +
        +@F1=("add","xor","sub");
        +@F2=("xor","sub","add");
        +@F3=("sub","add","xor");
        +
        +&CAST_encrypt("CAST_encrypt",1);
        +&CAST_encrypt("CAST_decrypt",0);
        +&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1);
        +
        +&asm_finish();
        +
        +sub CAST_encrypt {
        +    local($name,$enc)=@_;
        +
        +    local($win_ex)=<<"EOF";
        +EXTERN	_CAST_S_table0:DWORD
        +EXTERN	_CAST_S_table1:DWORD
        +EXTERN	_CAST_S_table2:DWORD
        +EXTERN	_CAST_S_table3:DWORD
        +EOF
        +    &main::external_label(
        +			  "CAST_S_table0",
        +			  "CAST_S_table1",
        +			  "CAST_S_table2",
        +			  "CAST_S_table3",
        +			  );
        +
        +    &function_begin_B($name,$win_ex);
        +
        +    &comment("");
        +
        +    &push("ebp");
        +    &push("ebx");
        +    &mov($tmp2,&wparam(0));
        +    &mov($K,&wparam(1));
        +    &push("esi");
        +    &push("edi");
        +
        +    &comment("Load the 2 words");
        +    &mov($L,&DWP(0,$tmp2,"",0));
        +    &mov($R,&DWP(4,$tmp2,"",0));
        +
        +    &comment('Get short key flag');
        +    &mov($tmp3,&DWP(128,$K,"",0));
        +    if($enc) {
        +	&push($tmp3);
        +    } else {
        +	&or($tmp3,$tmp3);
        +	&jnz(&label('cast_dec_skip'));
        +    }
        +
        +    &xor($tmp3,	$tmp3);
        +
        +    # encrypting part
        +
        +    if ($enc) {
        +	&E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&comment('test short key flag');
        +	&pop($tmp4);
        +	&or($tmp4,$tmp4);
        +	&jnz(&label('cast_enc_done'));
        +	&E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +    } else {
        +	&E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&set_label('cast_dec_skip');
        +	&E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
        +	&E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
        +    }
        +
        +    &set_label('cast_enc_done') if $enc;
        +# Why the nop? - Ben 17/1/99
        +    &nop();
        +    &mov($tmp3,&wparam(0));
        +    &mov(&DWP(4,$tmp3,"",0),$L);
        +    &mov(&DWP(0,$tmp3,"",0),$R);
        +    &function_end($name);
        +}
        +
        +sub E_CAST {
        +    local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_;
        +    # Ri needs to have 16 pre added.
        +
        +    &comment("round $i");
        +    &mov(	$tmp4,		&DWP($i*8,$K,"",1));
        +
        +    &mov(	$tmp1,		&DWP($i*8+4,$K,"",1));
        +    &$OP1(	$tmp4,		$R);
        +
        +    &rotl(	$tmp4,		&LB($tmp1));
        +
        +    if ($ppro) {
        +	&mov(	$tmp2,		$tmp4);		# B
        +	&xor(	$tmp1,		$tmp1);
        +	
        +	&movb(	&LB($tmp1),	&HB($tmp4));	# A
        +	&and(	$tmp2,		0xff);
        +
        +	&shr(	$tmp4,		16); 		#
        +	&xor(	$tmp3,		$tmp3);
        +    } else {
        +	&mov(	$tmp2,		$tmp4);		# B
        +	&movb(	&LB($tmp1),	&HB($tmp4));	# A	# BAD BAD BAD
        +	
        +	&shr(	$tmp4,		16); 		#
        +	&and(	$tmp2,		0xff);
        +    }
        +
        +    &movb(	&LB($tmp3),	&HB($tmp4));	# C	# BAD BAD BAD
        +    &and(	$tmp4,		0xff);		# D
        +
        +    &mov(	$tmp1,		&DWP($S1,"",$tmp1,4));
        +    &mov(	$tmp2,		&DWP($S2,"",$tmp2,4));
        +
        +    &$OP2(	$tmp1,		$tmp2);
        +    &mov(	$tmp2,		&DWP($S3,"",$tmp3,4));
        +
        +    &$OP3(	$tmp1,		$tmp2);
        +    &mov(	$tmp2,		&DWP($S4,"",$tmp4,4));
        +
        +    &$OP1(	$tmp1,		$tmp2);
        +    # XXX
        +
        +    &xor(	$L,		$tmp1);
        +    # XXX
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/cast/asm/readme b/vendor/openssl/openssl/crypto/cast/asm/readme
        new file mode 100644
        index 000000000..fbcd76289
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/asm/readme
        @@ -0,0 +1,7 @@
        +There is a ppro flag in cast-586 which turns on/off
        +generation of pentium pro/II friendly code
        +
        +This flag makes the inner loop one cycle longer, but generates 
        +code that runs %30 faster on the pentium pro/II, while only %7 slower
        +on the pentium.  By default, this flag is on.
        +
        diff --git a/vendor/openssl/openssl/crypto/cast/c_cfb64.c b/vendor/openssl/openssl/crypto/cast/c_cfb64.c
        new file mode 100644
        index 000000000..dcec13a20
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/c_cfb64.c
        @@ -0,0 +1,121 @@
        +/* crypto/cast/c_cfb64.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 <openssl/cast.h>
        +#include "cast_lcl.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, const CAST_KEY *schedule, unsigned char *ivec,
        +			int *num, int enc)
        +	{
        +	register CAST_LONG v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	CAST_LONG ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv=ivec;
        +	if (enc)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				n2l(iv,v0); ti[0]=v0;
        +				n2l(iv,v1); ti[1]=v1;
        +				CAST_encrypt((CAST_LONG *)ti,schedule);
        +				iv=ivec;
        +				t=ti[0]; l2n(t,iv);
        +				t=ti[1]; l2n(t,iv);
        +				iv=ivec;
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				n2l(iv,v0); ti[0]=v0;
        +				n2l(iv,v1); ti[1]=v1;
        +				CAST_encrypt((CAST_LONG *)ti,schedule);
        +				iv=ivec;
        +				t=ti[0]; l2n(t,iv);
        +				t=ti[1]; l2n(t,iv);
        +				iv=ivec;
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=t=c=cc=0;
        +	*num=n;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cast/c_ecb.c b/vendor/openssl/openssl/crypto/cast/c_ecb.c
        new file mode 100644
        index 000000000..b6a3b1fff
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/c_ecb.c
        @@ -0,0 +1,79 @@
        +/* crypto/cast/c_ecb.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 <openssl/cast.h>
        +#include "cast_lcl.h"
        +#include <openssl/opensslv.h>
        +
        +const char CAST_version[]="CAST" OPENSSL_VERSION_PTEXT;
        +
        +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +		      const CAST_KEY *ks, int enc)
        +	{
        +	CAST_LONG l,d[2];
        +
        +	n2l(in,l); d[0]=l;
        +	n2l(in,l); d[1]=l;
        +	if (enc)
        +		CAST_encrypt(d,ks);
        +	else
        +		CAST_decrypt(d,ks);
        +	l=d[0]; l2n(l,out);
        +	l=d[1]; l2n(l,out);
        +	l=d[0]=d[1]=0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cast/c_enc.c b/vendor/openssl/openssl/crypto/cast/c_enc.c
        new file mode 100644
        index 000000000..357c41ebf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/c_enc.c
        @@ -0,0 +1,208 @@
        +/* crypto/cast/c_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <openssl/cast.h>
        +#include "cast_lcl.h"
        +
        +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
        +	{
        +	register CAST_LONG l,r,t;
        +	const register CAST_LONG *k;
        +
        +	k= &(key->data[0]);
        +	l=data[0];
        +	r=data[1];
        +
        +	E_CAST( 0,k,l,r,+,^,-);
        +	E_CAST( 1,k,r,l,^,-,+);
        +	E_CAST( 2,k,l,r,-,+,^);
        +	E_CAST( 3,k,r,l,+,^,-);
        +	E_CAST( 4,k,l,r,^,-,+);
        +	E_CAST( 5,k,r,l,-,+,^);
        +	E_CAST( 6,k,l,r,+,^,-);
        +	E_CAST( 7,k,r,l,^,-,+);
        +	E_CAST( 8,k,l,r,-,+,^);
        +	E_CAST( 9,k,r,l,+,^,-);
        +	E_CAST(10,k,l,r,^,-,+);
        +	E_CAST(11,k,r,l,-,+,^);
        +	if(!key->short_key)
        +	    {
        +	    E_CAST(12,k,l,r,+,^,-);
        +	    E_CAST(13,k,r,l,^,-,+);
        +	    E_CAST(14,k,l,r,-,+,^);
        +	    E_CAST(15,k,r,l,+,^,-);
        +	    }
        +
        +	data[1]=l&0xffffffffL;
        +	data[0]=r&0xffffffffL;
        +	}
        +
        +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
        +	{
        +	register CAST_LONG l,r,t;
        +	const register CAST_LONG *k;
        +
        +	k= &(key->data[0]);
        +	l=data[0];
        +	r=data[1];
        +
        +	if(!key->short_key)
        +	    {
        +	    E_CAST(15,k,l,r,+,^,-);
        +	    E_CAST(14,k,r,l,-,+,^);
        +	    E_CAST(13,k,l,r,^,-,+);
        +	    E_CAST(12,k,r,l,+,^,-);
        +	    }
        +	E_CAST(11,k,l,r,-,+,^);
        +	E_CAST(10,k,r,l,^,-,+);
        +	E_CAST( 9,k,l,r,+,^,-);
        +	E_CAST( 8,k,r,l,-,+,^);
        +	E_CAST( 7,k,l,r,^,-,+);
        +	E_CAST( 6,k,r,l,+,^,-);
        +	E_CAST( 5,k,l,r,-,+,^);
        +	E_CAST( 4,k,r,l,^,-,+);
        +	E_CAST( 3,k,l,r,+,^,-);
        +	E_CAST( 2,k,r,l,-,+,^);
        +	E_CAST( 1,k,l,r,^,-,+);
        +	E_CAST( 0,k,r,l,+,^,-);
        +
        +	data[1]=l&0xffffffffL;
        +	data[0]=r&0xffffffffL;
        +	}
        +
        +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     const CAST_KEY *ks, unsigned char *iv, int enc)
        +	{
        +	register CAST_LONG tin0,tin1;
        +	register CAST_LONG tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	CAST_LONG tin[2];
        +
        +	if (enc)
        +		{
        +		n2l(iv,tout0);
        +		n2l(iv,tout1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			CAST_encrypt(tin,ks);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			n2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			CAST_encrypt(tin,ks);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			}
        +		l2n(tout0,iv);
        +		l2n(tout1,iv);
        +		}
        +	else
        +		{
        +		n2l(iv,xor0);
        +		n2l(iv,xor1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			CAST_decrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			CAST_decrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2nn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		l2n(xor0,iv);
        +		l2n(xor1,iv);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cast/c_ofb64.c b/vendor/openssl/openssl/crypto/cast/c_ofb64.c
        new file mode 100644
        index 000000000..cb3222456
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/c_ofb64.c
        @@ -0,0 +1,110 @@
        +/* crypto/cast/c_ofb64.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 <openssl/cast.h>
        +#include "cast_lcl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, const CAST_KEY *schedule, unsigned char *ivec,
        +			int *num)
        +	{
        +	register CAST_LONG v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned char d[8];
        +	register char *dp;
        +	CAST_LONG ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv=ivec;
        +	n2l(iv,v0);
        +	n2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=(char *)d;
        +	l2n(v0,dp);
        +	l2n(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			CAST_encrypt((CAST_LONG *)ti,schedule);
        +			dp=(char *)d;
        +			t=ti[0]; l2n(t,dp);
        +			t=ti[1]; l2n(t,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +		v0=ti[0];
        +		v1=ti[1];
        +		iv=ivec;
        +		l2n(v0,iv);
        +		l2n(v1,iv);
        +		}
        +	t=v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cast/c_skey.c b/vendor/openssl/openssl/crypto/cast/c_skey.c
        new file mode 100644
        index 000000000..cb6bf9fee
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/c_skey.c
        @@ -0,0 +1,173 @@
        +/* crypto/cast/c_skey.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 <openssl/crypto.h>
        +#include <openssl/cast.h>
        +#include "cast_lcl.h"
        +#include "cast_s.h"
        +
        +#define CAST_exp(l,A,a,n) \
        +	A[n/4]=l; \
        +	a[n+3]=(l    )&0xff; \
        +	a[n+2]=(l>> 8)&0xff; \
        +	a[n+1]=(l>>16)&0xff; \
        +	a[n+0]=(l>>24)&0xff;
        +
        +#define S4 CAST_S_table4
        +#define S5 CAST_S_table5
        +#define S6 CAST_S_table6
        +#define S7 CAST_S_table7
        +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
        +#ifdef OPENSSL_FIPS
        +	{
        +	fips_cipher_abort(CAST);
        +	private_CAST_set_key(key, len, data);
        +	}
        +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
        +#endif
        +	{
        +	CAST_LONG x[16];
        +	CAST_LONG z[16];
        +	CAST_LONG k[32];
        +	CAST_LONG X[4],Z[4];
        +	CAST_LONG l,*K;
        +	int i;
        +
        +	for (i=0; i<16; i++) x[i]=0;
        +	if (len > 16) len=16;
        +	for (i=0; i<len; i++)
        +		x[i]=data[i];
        +	if(len <= 10)
        +	    key->short_key=1;
        +	else
        +	    key->short_key=0;
        +
        +	K= &k[0];
        +	X[0]=((x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3])&0xffffffffL;
        +	X[1]=((x[ 4]<<24)|(x[ 5]<<16)|(x[ 6]<<8)|x[ 7])&0xffffffffL;
        +	X[2]=((x[ 8]<<24)|(x[ 9]<<16)|(x[10]<<8)|x[11])&0xffffffffL;
        +	X[3]=((x[12]<<24)|(x[13]<<16)|(x[14]<<8)|x[15])&0xffffffffL;
        +
        +	for (;;)
        +		{
        +	l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
        +	CAST_exp(l,Z,z, 0);
        +	l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
        +	CAST_exp(l,Z,z, 4);
        +	l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
        +	CAST_exp(l,Z,z, 8);
        +	l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
        +	CAST_exp(l,Z,z,12);
        +
        +	K[ 0]= S4[z[ 8]]^S5[z[ 9]]^S6[z[ 7]]^S7[z[ 6]]^S4[z[ 2]];
        +	K[ 1]= S4[z[10]]^S5[z[11]]^S6[z[ 5]]^S7[z[ 4]]^S5[z[ 6]];
        +	K[ 2]= S4[z[12]]^S5[z[13]]^S6[z[ 3]]^S7[z[ 2]]^S6[z[ 9]];
        +	K[ 3]= S4[z[14]]^S5[z[15]]^S6[z[ 1]]^S7[z[ 0]]^S7[z[12]];
        +
        +	l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
        +	CAST_exp(l,X,x, 0);
        +	l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
        +	CAST_exp(l,X,x, 4);
        +	l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
        +	CAST_exp(l,X,x, 8);
        +	l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
        +	CAST_exp(l,X,x,12);
        +
        +	K[ 4]= S4[x[ 3]]^S5[x[ 2]]^S6[x[12]]^S7[x[13]]^S4[x[ 8]];
        +	K[ 5]= S4[x[ 1]]^S5[x[ 0]]^S6[x[14]]^S7[x[15]]^S5[x[13]];
        +	K[ 6]= S4[x[ 7]]^S5[x[ 6]]^S6[x[ 8]]^S7[x[ 9]]^S6[x[ 3]];
        +	K[ 7]= S4[x[ 5]]^S5[x[ 4]]^S6[x[10]]^S7[x[11]]^S7[x[ 7]];
        +
        +	l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
        +	CAST_exp(l,Z,z, 0);
        +	l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
        +	CAST_exp(l,Z,z, 4);
        +	l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
        +	CAST_exp(l,Z,z, 8);
        +	l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
        +	CAST_exp(l,Z,z,12);
        +
        +	K[ 8]= S4[z[ 3]]^S5[z[ 2]]^S6[z[12]]^S7[z[13]]^S4[z[ 9]];
        +	K[ 9]= S4[z[ 1]]^S5[z[ 0]]^S6[z[14]]^S7[z[15]]^S5[z[12]];
        +	K[10]= S4[z[ 7]]^S5[z[ 6]]^S6[z[ 8]]^S7[z[ 9]]^S6[z[ 2]];
        +	K[11]= S4[z[ 5]]^S5[z[ 4]]^S6[z[10]]^S7[z[11]]^S7[z[ 6]];
        +
        +	l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
        +	CAST_exp(l,X,x, 0);
        +	l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
        +	CAST_exp(l,X,x, 4);
        +	l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
        +	CAST_exp(l,X,x, 8);
        +	l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
        +	CAST_exp(l,X,x,12);
        +
        +	K[12]= S4[x[ 8]]^S5[x[ 9]]^S6[x[ 7]]^S7[x[ 6]]^S4[x[ 3]];
        +	K[13]= S4[x[10]]^S5[x[11]]^S6[x[ 5]]^S7[x[ 4]]^S5[x[ 7]];
        +	K[14]= S4[x[12]]^S5[x[13]]^S6[x[ 3]]^S7[x[ 2]]^S6[x[ 8]];
        +	K[15]= S4[x[14]]^S5[x[15]]^S6[x[ 1]]^S7[x[ 0]]^S7[x[13]];
        +	if (K != k)  break;
        +	K+=16;
        +		}
        +
        +	for (i=0; i<16; i++)
        +		{
        +		key->data[i*2]=k[i];
        +		key->data[i*2+1]=((k[i+16])+16)&0x1f;
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/cast/cast.h b/vendor/openssl/openssl/crypto/cast/cast.h
        new file mode 100644
        index 000000000..203922ea2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/cast.h
        @@ -0,0 +1,107 @@
        +/* crypto/cast/cast.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_CAST_H
        +#define HEADER_CAST_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_CAST
        +#error CAST is disabled.
        +#endif
        +
        +#define CAST_ENCRYPT	1
        +#define CAST_DECRYPT	0
        +
        +#define CAST_LONG unsigned int
        +
        +#define CAST_BLOCK	8
        +#define CAST_KEY_LENGTH	16
        +
        +typedef struct cast_key_st
        +	{
        +	CAST_LONG data[32];
        +	int short_key;	/* Use reduced rounds for short key */
        +	} CAST_KEY;
        +
        +#ifdef OPENSSL_FIPS 
        +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
        +#endif
        +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
        +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key,
        +		      int enc);
        +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
        +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
        +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +		      const CAST_KEY *ks, unsigned char *iv, int enc);
        +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, const CAST_KEY *schedule, unsigned char *ivec,
        +			int *num, int enc);
        +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, 
        +			long length, const CAST_KEY *schedule, unsigned char *ivec,
        +			int *num);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cast/cast_lcl.h b/vendor/openssl/openssl/crypto/cast/cast_lcl.h
        new file mode 100644
        index 000000000..e756021a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/cast_lcl.h
        @@ -0,0 +1,227 @@
        +/* crypto/cast/cast_lcl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +
        +#include "e_os.h"
        +
        +#ifdef OPENSSL_SYS_WIN32
        +#include <stdlib.h>
        +#endif
        +
        +
        +#undef c2l
        +#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
        +			 l|=((unsigned long)(*((c)++)))<< 8L, \
        +			 l|=((unsigned long)(*((c)++)))<<16L, \
        +			 l|=((unsigned long)(*((c)++)))<<24L)
        +
        +/* NOTE - c is not incremented as per c2l */
        +#undef c2ln
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 5: l2|=((unsigned long)(*(--(c))));     \
        +			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 1: l1|=((unsigned long)(*(--(c))));     \
        +				} \
        +			}
        +
        +#undef l2c
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +
        +/* NOTE - c is not incremented as per l2c */
        +#undef l2cn
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per n2l */
        +#define n2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))    ; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
        +			case 4: l1 =((unsigned long)(*(--(c))))    ; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per l2n */
        +#define l2nn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +				} \
        +			}
        +
        +#undef n2l
        +#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
        +                         l|=((unsigned long)(*((c)++)))<<16L, \
        +                         l|=((unsigned long)(*((c)++)))<< 8L, \
        +                         l|=((unsigned long)(*((c)++))))
        +
        +#undef l2n
        +#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)     )&0xff))
        +
        +#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
        +#define ROTL(a,n)     (_lrotl(a,n))
        +#else
        +#define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n))))
        +#endif
        +
        +#define C_M    0x3fc
        +#define C_0    22L
        +#define C_1    14L
        +#define C_2     6L
        +#define C_3     2L /* left shift */
        +
        +/* The rotate has an extra 16 added to it to help the x86 asm */
        +#if defined(CAST_PTR)
        +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
        +	{ \
        +	int i; \
        +	t=(key[n*2] OP1 R)&0xffffffffL; \
        +	i=key[n*2+1]; \
        +	t=ROTL(t,i); \
        +	L^= (((((*(CAST_LONG *)((unsigned char *) \
        +			CAST_S_table0+((t>>C_2)&C_M)) OP2 \
        +		*(CAST_LONG *)((unsigned char *) \
        +			CAST_S_table1+((t<<C_3)&C_M)))&0xffffffffL) OP3 \
        +		*(CAST_LONG *)((unsigned char *) \
        +			CAST_S_table2+((t>>C_0)&C_M)))&0xffffffffL) OP1 \
        +		*(CAST_LONG *)((unsigned char *) \
        +			CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \
        +	}
        +#elif defined(CAST_PTR2)
        +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
        +	{ \
        +	int i; \
        +	CAST_LONG u,v,w; \
        +	w=(key[n*2] OP1 R)&0xffffffffL; \
        +	i=key[n*2+1]; \
        +	w=ROTL(w,i); \
        +	u=w>>C_2; \
        +	v=w<<C_3; \
        +	u&=C_M; \
        +	v&=C_M; \
        +	t= *(CAST_LONG *)((unsigned char *)CAST_S_table0+u); \
        +	u=w>>C_0; \
        +	t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\
        +	v=w>>C_1; \
        +	u&=C_M; \
        +	v&=C_M; \
        +	t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\
        +	t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\
        +	L^=(t&0xffffffff); \
        +	}
        +#else
        +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
        +	{ \
        +	CAST_LONG a,b,c,d; \
        +	t=(key[n*2] OP1 R)&0xffffffff; \
        +	t=ROTL(t,(key[n*2+1])); \
        +	a=CAST_S_table0[(t>> 8)&0xff]; \
        +	b=CAST_S_table1[(t    )&0xff]; \
        +	c=CAST_S_table2[(t>>24)&0xff]; \
        +	d=CAST_S_table3[(t>>16)&0xff]; \
        +	L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \
        +	}
        +#endif
        +
        +extern const CAST_LONG CAST_S_table0[256];
        +extern const CAST_LONG CAST_S_table1[256];
        +extern const CAST_LONG CAST_S_table2[256];
        +extern const CAST_LONG CAST_S_table3[256];
        +extern const CAST_LONG CAST_S_table4[256];
        +extern const CAST_LONG CAST_S_table5[256];
        +extern const CAST_LONG CAST_S_table6[256];
        +extern const CAST_LONG CAST_S_table7[256];
        diff --git a/vendor/openssl/openssl/crypto/cast/cast_s.h b/vendor/openssl/openssl/crypto/cast/cast_s.h
        new file mode 100644
        index 000000000..c483fd5e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/cast_s.h
        @@ -0,0 +1,585 @@
        +/* crypto/cast/cast_s.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.]
        + */
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256]={
        +	0x30fb40d4,0x9fa0ff0b,0x6beccd2f,0x3f258c7a,
        +	0x1e213f2f,0x9c004dd3,0x6003e540,0xcf9fc949,
        +	0xbfd4af27,0x88bbbdb5,0xe2034090,0x98d09675,
        +	0x6e63a0e0,0x15c361d2,0xc2e7661d,0x22d4ff8e,
        +	0x28683b6f,0xc07fd059,0xff2379c8,0x775f50e2,
        +	0x43c340d3,0xdf2f8656,0x887ca41a,0xa2d2bd2d,
        +	0xa1c9e0d6,0x346c4819,0x61b76d87,0x22540f2f,
        +	0x2abe32e1,0xaa54166b,0x22568e3a,0xa2d341d0,
        +	0x66db40c8,0xa784392f,0x004dff2f,0x2db9d2de,
        +	0x97943fac,0x4a97c1d8,0x527644b7,0xb5f437a7,
        +	0xb82cbaef,0xd751d159,0x6ff7f0ed,0x5a097a1f,
        +	0x827b68d0,0x90ecf52e,0x22b0c054,0xbc8e5935,
        +	0x4b6d2f7f,0x50bb64a2,0xd2664910,0xbee5812d,
        +	0xb7332290,0xe93b159f,0xb48ee411,0x4bff345d,
        +	0xfd45c240,0xad31973f,0xc4f6d02e,0x55fc8165,
        +	0xd5b1caad,0xa1ac2dae,0xa2d4b76d,0xc19b0c50,
        +	0x882240f2,0x0c6e4f38,0xa4e4bfd7,0x4f5ba272,
        +	0x564c1d2f,0xc59c5319,0xb949e354,0xb04669fe,
        +	0xb1b6ab8a,0xc71358dd,0x6385c545,0x110f935d,
        +	0x57538ad5,0x6a390493,0xe63d37e0,0x2a54f6b3,
        +	0x3a787d5f,0x6276a0b5,0x19a6fcdf,0x7a42206a,
        +	0x29f9d4d5,0xf61b1891,0xbb72275e,0xaa508167,
        +	0x38901091,0xc6b505eb,0x84c7cb8c,0x2ad75a0f,
        +	0x874a1427,0xa2d1936b,0x2ad286af,0xaa56d291,
        +	0xd7894360,0x425c750d,0x93b39e26,0x187184c9,
        +	0x6c00b32d,0x73e2bb14,0xa0bebc3c,0x54623779,
        +	0x64459eab,0x3f328b82,0x7718cf82,0x59a2cea6,
        +	0x04ee002e,0x89fe78e6,0x3fab0950,0x325ff6c2,
        +	0x81383f05,0x6963c5c8,0x76cb5ad6,0xd49974c9,
        +	0xca180dcf,0x380782d5,0xc7fa5cf6,0x8ac31511,
        +	0x35e79e13,0x47da91d0,0xf40f9086,0xa7e2419e,
        +	0x31366241,0x051ef495,0xaa573b04,0x4a805d8d,
        +	0x548300d0,0x00322a3c,0xbf64cddf,0xba57a68e,
        +	0x75c6372b,0x50afd341,0xa7c13275,0x915a0bf5,
        +	0x6b54bfab,0x2b0b1426,0xab4cc9d7,0x449ccd82,
        +	0xf7fbf265,0xab85c5f3,0x1b55db94,0xaad4e324,
        +	0xcfa4bd3f,0x2deaa3e2,0x9e204d02,0xc8bd25ac,
        +	0xeadf55b3,0xd5bd9e98,0xe31231b2,0x2ad5ad6c,
        +	0x954329de,0xadbe4528,0xd8710f69,0xaa51c90f,
        +	0xaa786bf6,0x22513f1e,0xaa51a79b,0x2ad344cc,
        +	0x7b5a41f0,0xd37cfbad,0x1b069505,0x41ece491,
        +	0xb4c332e6,0x032268d4,0xc9600acc,0xce387e6d,
        +	0xbf6bb16c,0x6a70fb78,0x0d03d9c9,0xd4df39de,
        +	0xe01063da,0x4736f464,0x5ad328d8,0xb347cc96,
        +	0x75bb0fc3,0x98511bfb,0x4ffbcc35,0xb58bcf6a,
        +	0xe11f0abc,0xbfc5fe4a,0xa70aec10,0xac39570a,
        +	0x3f04442f,0x6188b153,0xe0397a2e,0x5727cb79,
        +	0x9ceb418f,0x1cacd68d,0x2ad37c96,0x0175cb9d,
        +	0xc69dff09,0xc75b65f0,0xd9db40d8,0xec0e7779,
        +	0x4744ead4,0xb11c3274,0xdd24cb9e,0x7e1c54bd,
        +	0xf01144f9,0xd2240eb1,0x9675b3fd,0xa3ac3755,
        +	0xd47c27af,0x51c85f4d,0x56907596,0xa5bb15e6,
        +	0x580304f0,0xca042cf1,0x011a37ea,0x8dbfaadb,
        +	0x35ba3e4a,0x3526ffa0,0xc37b4d09,0xbc306ed9,
        +	0x98a52666,0x5648f725,0xff5e569d,0x0ced63d0,
        +	0x7c63b2cf,0x700b45e1,0xd5ea50f1,0x85a92872,
        +	0xaf1fbda7,0xd4234870,0xa7870bf3,0x2d3b4d79,
        +	0x42e04198,0x0cd0ede7,0x26470db8,0xf881814c,
        +	0x474d6ad7,0x7c0c5e5c,0xd1231959,0x381b7298,
        +	0xf5d2f4db,0xab838653,0x6e2f1e23,0x83719c9e,
        +	0xbd91e046,0x9a56456e,0xdc39200c,0x20c8c571,
        +	0x962bda1c,0xe1e696ff,0xb141ab08,0x7cca89b9,
        +	0x1a69e783,0x02cc4843,0xa2f7c579,0x429ef47d,
        +	0x427b169c,0x5ac9f049,0xdd8f0f00,0x5c8165bf,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256]={
        +	0x1f201094,0xef0ba75b,0x69e3cf7e,0x393f4380,
        +	0xfe61cf7a,0xeec5207a,0x55889c94,0x72fc0651,
        +	0xada7ef79,0x4e1d7235,0xd55a63ce,0xde0436ba,
        +	0x99c430ef,0x5f0c0794,0x18dcdb7d,0xa1d6eff3,
        +	0xa0b52f7b,0x59e83605,0xee15b094,0xe9ffd909,
        +	0xdc440086,0xef944459,0xba83ccb3,0xe0c3cdfb,
        +	0xd1da4181,0x3b092ab1,0xf997f1c1,0xa5e6cf7b,
        +	0x01420ddb,0xe4e7ef5b,0x25a1ff41,0xe180f806,
        +	0x1fc41080,0x179bee7a,0xd37ac6a9,0xfe5830a4,
        +	0x98de8b7f,0x77e83f4e,0x79929269,0x24fa9f7b,
        +	0xe113c85b,0xacc40083,0xd7503525,0xf7ea615f,
        +	0x62143154,0x0d554b63,0x5d681121,0xc866c359,
        +	0x3d63cf73,0xcee234c0,0xd4d87e87,0x5c672b21,
        +	0x071f6181,0x39f7627f,0x361e3084,0xe4eb573b,
        +	0x602f64a4,0xd63acd9c,0x1bbc4635,0x9e81032d,
        +	0x2701f50c,0x99847ab4,0xa0e3df79,0xba6cf38c,
        +	0x10843094,0x2537a95e,0xf46f6ffe,0xa1ff3b1f,
        +	0x208cfb6a,0x8f458c74,0xd9e0a227,0x4ec73a34,
        +	0xfc884f69,0x3e4de8df,0xef0e0088,0x3559648d,
        +	0x8a45388c,0x1d804366,0x721d9bfd,0xa58684bb,
        +	0xe8256333,0x844e8212,0x128d8098,0xfed33fb4,
        +	0xce280ae1,0x27e19ba5,0xd5a6c252,0xe49754bd,
        +	0xc5d655dd,0xeb667064,0x77840b4d,0xa1b6a801,
        +	0x84db26a9,0xe0b56714,0x21f043b7,0xe5d05860,
        +	0x54f03084,0x066ff472,0xa31aa153,0xdadc4755,
        +	0xb5625dbf,0x68561be6,0x83ca6b94,0x2d6ed23b,
        +	0xeccf01db,0xa6d3d0ba,0xb6803d5c,0xaf77a709,
        +	0x33b4a34c,0x397bc8d6,0x5ee22b95,0x5f0e5304,
        +	0x81ed6f61,0x20e74364,0xb45e1378,0xde18639b,
        +	0x881ca122,0xb96726d1,0x8049a7e8,0x22b7da7b,
        +	0x5e552d25,0x5272d237,0x79d2951c,0xc60d894c,
        +	0x488cb402,0x1ba4fe5b,0xa4b09f6b,0x1ca815cf,
        +	0xa20c3005,0x8871df63,0xb9de2fcb,0x0cc6c9e9,
        +	0x0beeff53,0xe3214517,0xb4542835,0x9f63293c,
        +	0xee41e729,0x6e1d2d7c,0x50045286,0x1e6685f3,
        +	0xf33401c6,0x30a22c95,0x31a70850,0x60930f13,
        +	0x73f98417,0xa1269859,0xec645c44,0x52c877a9,
        +	0xcdff33a6,0xa02b1741,0x7cbad9a2,0x2180036f,
        +	0x50d99c08,0xcb3f4861,0xc26bd765,0x64a3f6ab,
        +	0x80342676,0x25a75e7b,0xe4e6d1fc,0x20c710e6,
        +	0xcdf0b680,0x17844d3b,0x31eef84d,0x7e0824e4,
        +	0x2ccb49eb,0x846a3bae,0x8ff77888,0xee5d60f6,
        +	0x7af75673,0x2fdd5cdb,0xa11631c1,0x30f66f43,
        +	0xb3faec54,0x157fd7fa,0xef8579cc,0xd152de58,
        +	0xdb2ffd5e,0x8f32ce19,0x306af97a,0x02f03ef8,
        +	0x99319ad5,0xc242fa0f,0xa7e3ebb0,0xc68e4906,
        +	0xb8da230c,0x80823028,0xdcdef3c8,0xd35fb171,
        +	0x088a1bc8,0xbec0c560,0x61a3c9e8,0xbca8f54d,
        +	0xc72feffa,0x22822e99,0x82c570b4,0xd8d94e89,
        +	0x8b1c34bc,0x301e16e6,0x273be979,0xb0ffeaa6,
        +	0x61d9b8c6,0x00b24869,0xb7ffce3f,0x08dc283b,
        +	0x43daf65a,0xf7e19798,0x7619b72f,0x8f1c9ba4,
        +	0xdc8637a0,0x16a7d3b1,0x9fc393b7,0xa7136eeb,
        +	0xc6bcc63e,0x1a513742,0xef6828bc,0x520365d6,
        +	0x2d6a77ab,0x3527ed4b,0x821fd216,0x095c6e2e,
        +	0xdb92f2fb,0x5eea29cb,0x145892f5,0x91584f7f,
        +	0x5483697b,0x2667a8cc,0x85196048,0x8c4bacea,
        +	0x833860d4,0x0d23e0f9,0x6c387e8a,0x0ae6d249,
        +	0xb284600c,0xd835731d,0xdcb1c647,0xac4c56ea,
        +	0x3ebd81b3,0x230eabb0,0x6438bc87,0xf0b5b1fa,
        +	0x8f5ea2b3,0xfc184642,0x0a036b7a,0x4fb089bd,
        +	0x649da589,0xa345415e,0x5c038323,0x3e5d3bb9,
        +	0x43d79572,0x7e6dd07c,0x06dfdf1e,0x6c6cc4ef,
        +	0x7160a539,0x73bfbe70,0x83877605,0x4523ecf1,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256]={
        +	0x8defc240,0x25fa5d9f,0xeb903dbf,0xe810c907,
        +	0x47607fff,0x369fe44b,0x8c1fc644,0xaececa90,
        +	0xbeb1f9bf,0xeefbcaea,0xe8cf1950,0x51df07ae,
        +	0x920e8806,0xf0ad0548,0xe13c8d83,0x927010d5,
        +	0x11107d9f,0x07647db9,0xb2e3e4d4,0x3d4f285e,
        +	0xb9afa820,0xfade82e0,0xa067268b,0x8272792e,
        +	0x553fb2c0,0x489ae22b,0xd4ef9794,0x125e3fbc,
        +	0x21fffcee,0x825b1bfd,0x9255c5ed,0x1257a240,
        +	0x4e1a8302,0xbae07fff,0x528246e7,0x8e57140e,
        +	0x3373f7bf,0x8c9f8188,0xa6fc4ee8,0xc982b5a5,
        +	0xa8c01db7,0x579fc264,0x67094f31,0xf2bd3f5f,
        +	0x40fff7c1,0x1fb78dfc,0x8e6bd2c1,0x437be59b,
        +	0x99b03dbf,0xb5dbc64b,0x638dc0e6,0x55819d99,
        +	0xa197c81c,0x4a012d6e,0xc5884a28,0xccc36f71,
        +	0xb843c213,0x6c0743f1,0x8309893c,0x0feddd5f,
        +	0x2f7fe850,0xd7c07f7e,0x02507fbf,0x5afb9a04,
        +	0xa747d2d0,0x1651192e,0xaf70bf3e,0x58c31380,
        +	0x5f98302e,0x727cc3c4,0x0a0fb402,0x0f7fef82,
        +	0x8c96fdad,0x5d2c2aae,0x8ee99a49,0x50da88b8,
        +	0x8427f4a0,0x1eac5790,0x796fb449,0x8252dc15,
        +	0xefbd7d9b,0xa672597d,0xada840d8,0x45f54504,
        +	0xfa5d7403,0xe83ec305,0x4f91751a,0x925669c2,
        +	0x23efe941,0xa903f12e,0x60270df2,0x0276e4b6,
        +	0x94fd6574,0x927985b2,0x8276dbcb,0x02778176,
        +	0xf8af918d,0x4e48f79e,0x8f616ddf,0xe29d840e,
        +	0x842f7d83,0x340ce5c8,0x96bbb682,0x93b4b148,
        +	0xef303cab,0x984faf28,0x779faf9b,0x92dc560d,
        +	0x224d1e20,0x8437aa88,0x7d29dc96,0x2756d3dc,
        +	0x8b907cee,0xb51fd240,0xe7c07ce3,0xe566b4a1,
        +	0xc3e9615e,0x3cf8209d,0x6094d1e3,0xcd9ca341,
        +	0x5c76460e,0x00ea983b,0xd4d67881,0xfd47572c,
        +	0xf76cedd9,0xbda8229c,0x127dadaa,0x438a074e,
        +	0x1f97c090,0x081bdb8a,0x93a07ebe,0xb938ca15,
        +	0x97b03cff,0x3dc2c0f8,0x8d1ab2ec,0x64380e51,
        +	0x68cc7bfb,0xd90f2788,0x12490181,0x5de5ffd4,
        +	0xdd7ef86a,0x76a2e214,0xb9a40368,0x925d958f,
        +	0x4b39fffa,0xba39aee9,0xa4ffd30b,0xfaf7933b,
        +	0x6d498623,0x193cbcfa,0x27627545,0x825cf47a,
        +	0x61bd8ba0,0xd11e42d1,0xcead04f4,0x127ea392,
        +	0x10428db7,0x8272a972,0x9270c4a8,0x127de50b,
        +	0x285ba1c8,0x3c62f44f,0x35c0eaa5,0xe805d231,
        +	0x428929fb,0xb4fcdf82,0x4fb66a53,0x0e7dc15b,
        +	0x1f081fab,0x108618ae,0xfcfd086d,0xf9ff2889,
        +	0x694bcc11,0x236a5cae,0x12deca4d,0x2c3f8cc5,
        +	0xd2d02dfe,0xf8ef5896,0xe4cf52da,0x95155b67,
        +	0x494a488c,0xb9b6a80c,0x5c8f82bc,0x89d36b45,
        +	0x3a609437,0xec00c9a9,0x44715253,0x0a874b49,
        +	0xd773bc40,0x7c34671c,0x02717ef6,0x4feb5536,
        +	0xa2d02fff,0xd2bf60c4,0xd43f03c0,0x50b4ef6d,
        +	0x07478cd1,0x006e1888,0xa2e53f55,0xb9e6d4bc,
        +	0xa2048016,0x97573833,0xd7207d67,0xde0f8f3d,
        +	0x72f87b33,0xabcc4f33,0x7688c55d,0x7b00a6b0,
        +	0x947b0001,0x570075d2,0xf9bb88f8,0x8942019e,
        +	0x4264a5ff,0x856302e0,0x72dbd92b,0xee971b69,
        +	0x6ea22fde,0x5f08ae2b,0xaf7a616d,0xe5c98767,
        +	0xcf1febd2,0x61efc8c2,0xf1ac2571,0xcc8239c2,
        +	0x67214cb8,0xb1e583d1,0xb7dc3e62,0x7f10bdce,
        +	0xf90a5c38,0x0ff0443d,0x606e6dc6,0x60543a49,
        +	0x5727c148,0x2be98a1d,0x8ab41738,0x20e1be24,
        +	0xaf96da0f,0x68458425,0x99833be5,0x600d457d,
        +	0x282f9350,0x8334b362,0xd91d1120,0x2b6d8da0,
        +	0x642b1e31,0x9c305a00,0x52bce688,0x1b03588a,
        +	0xf7baefd5,0x4142ed9c,0xa4315c11,0x83323ec5,
        +	0xdfef4636,0xa133c501,0xe9d3531c,0xee353783,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256]={
        +	0x9db30420,0x1fb6e9de,0xa7be7bef,0xd273a298,
        +	0x4a4f7bdb,0x64ad8c57,0x85510443,0xfa020ed1,
        +	0x7e287aff,0xe60fb663,0x095f35a1,0x79ebf120,
        +	0xfd059d43,0x6497b7b1,0xf3641f63,0x241e4adf,
        +	0x28147f5f,0x4fa2b8cd,0xc9430040,0x0cc32220,
        +	0xfdd30b30,0xc0a5374f,0x1d2d00d9,0x24147b15,
        +	0xee4d111a,0x0fca5167,0x71ff904c,0x2d195ffe,
        +	0x1a05645f,0x0c13fefe,0x081b08ca,0x05170121,
        +	0x80530100,0xe83e5efe,0xac9af4f8,0x7fe72701,
        +	0xd2b8ee5f,0x06df4261,0xbb9e9b8a,0x7293ea25,
        +	0xce84ffdf,0xf5718801,0x3dd64b04,0xa26f263b,
        +	0x7ed48400,0x547eebe6,0x446d4ca0,0x6cf3d6f5,
        +	0x2649abdf,0xaea0c7f5,0x36338cc1,0x503f7e93,
        +	0xd3772061,0x11b638e1,0x72500e03,0xf80eb2bb,
        +	0xabe0502e,0xec8d77de,0x57971e81,0xe14f6746,
        +	0xc9335400,0x6920318f,0x081dbb99,0xffc304a5,
        +	0x4d351805,0x7f3d5ce3,0xa6c866c6,0x5d5bcca9,
        +	0xdaec6fea,0x9f926f91,0x9f46222f,0x3991467d,
        +	0xa5bf6d8e,0x1143c44f,0x43958302,0xd0214eeb,
        +	0x022083b8,0x3fb6180c,0x18f8931e,0x281658e6,
        +	0x26486e3e,0x8bd78a70,0x7477e4c1,0xb506e07c,
        +	0xf32d0a25,0x79098b02,0xe4eabb81,0x28123b23,
        +	0x69dead38,0x1574ca16,0xdf871b62,0x211c40b7,
        +	0xa51a9ef9,0x0014377b,0x041e8ac8,0x09114003,
        +	0xbd59e4d2,0xe3d156d5,0x4fe876d5,0x2f91a340,
        +	0x557be8de,0x00eae4a7,0x0ce5c2ec,0x4db4bba6,
        +	0xe756bdff,0xdd3369ac,0xec17b035,0x06572327,
        +	0x99afc8b0,0x56c8c391,0x6b65811c,0x5e146119,
        +	0x6e85cb75,0xbe07c002,0xc2325577,0x893ff4ec,
        +	0x5bbfc92d,0xd0ec3b25,0xb7801ab7,0x8d6d3b24,
        +	0x20c763ef,0xc366a5fc,0x9c382880,0x0ace3205,
        +	0xaac9548a,0xeca1d7c7,0x041afa32,0x1d16625a,
        +	0x6701902c,0x9b757a54,0x31d477f7,0x9126b031,
        +	0x36cc6fdb,0xc70b8b46,0xd9e66a48,0x56e55a79,
        +	0x026a4ceb,0x52437eff,0x2f8f76b4,0x0df980a5,
        +	0x8674cde3,0xedda04eb,0x17a9be04,0x2c18f4df,
        +	0xb7747f9d,0xab2af7b4,0xefc34d20,0x2e096b7c,
        +	0x1741a254,0xe5b6a035,0x213d42f6,0x2c1c7c26,
        +	0x61c2f50f,0x6552daf9,0xd2c231f8,0x25130f69,
        +	0xd8167fa2,0x0418f2c8,0x001a96a6,0x0d1526ab,
        +	0x63315c21,0x5e0a72ec,0x49bafefd,0x187908d9,
        +	0x8d0dbd86,0x311170a7,0x3e9b640c,0xcc3e10d7,
        +	0xd5cad3b6,0x0caec388,0xf73001e1,0x6c728aff,
        +	0x71eae2a1,0x1f9af36e,0xcfcbd12f,0xc1de8417,
        +	0xac07be6b,0xcb44a1d8,0x8b9b0f56,0x013988c3,
        +	0xb1c52fca,0xb4be31cd,0xd8782806,0x12a3a4e2,
        +	0x6f7de532,0x58fd7eb6,0xd01ee900,0x24adffc2,
        +	0xf4990fc5,0x9711aac5,0x001d7b95,0x82e5e7d2,
        +	0x109873f6,0x00613096,0xc32d9521,0xada121ff,
        +	0x29908415,0x7fbb977f,0xaf9eb3db,0x29c9ed2a,
        +	0x5ce2a465,0xa730f32c,0xd0aa3fe8,0x8a5cc091,
        +	0xd49e2ce7,0x0ce454a9,0xd60acd86,0x015f1919,
        +	0x77079103,0xdea03af6,0x78a8565e,0xdee356df,
        +	0x21f05cbe,0x8b75e387,0xb3c50651,0xb8a5c3ef,
        +	0xd8eeb6d2,0xe523be77,0xc2154529,0x2f69efdf,
        +	0xafe67afb,0xf470c4b2,0xf3e0eb5b,0xd6cc9876,
        +	0x39e4460c,0x1fda8538,0x1987832f,0xca007367,
        +	0xa99144f8,0x296b299e,0x492fc295,0x9266beab,
        +	0xb5676e69,0x9bd3ddda,0xdf7e052f,0xdb25701c,
        +	0x1b5e51ee,0xf65324e6,0x6afce36c,0x0316cc04,
        +	0x8644213e,0xb7dc59d0,0x7965291f,0xccd6fd43,
        +	0x41823979,0x932bcdf6,0xb657c34d,0x4edfd282,
        +	0x7ae5290c,0x3cb9536b,0x851e20fe,0x9833557e,
        +	0x13ecf0b0,0xd3ffb372,0x3f85c5c1,0x0aef7ed2,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256]={
        +	0x7ec90c04,0x2c6e74b9,0x9b0e66df,0xa6337911,
        +	0xb86a7fff,0x1dd358f5,0x44dd9d44,0x1731167f,
        +	0x08fbf1fa,0xe7f511cc,0xd2051b00,0x735aba00,
        +	0x2ab722d8,0x386381cb,0xacf6243a,0x69befd7a,
        +	0xe6a2e77f,0xf0c720cd,0xc4494816,0xccf5c180,
        +	0x38851640,0x15b0a848,0xe68b18cb,0x4caadeff,
        +	0x5f480a01,0x0412b2aa,0x259814fc,0x41d0efe2,
        +	0x4e40b48d,0x248eb6fb,0x8dba1cfe,0x41a99b02,
        +	0x1a550a04,0xba8f65cb,0x7251f4e7,0x95a51725,
        +	0xc106ecd7,0x97a5980a,0xc539b9aa,0x4d79fe6a,
        +	0xf2f3f763,0x68af8040,0xed0c9e56,0x11b4958b,
        +	0xe1eb5a88,0x8709e6b0,0xd7e07156,0x4e29fea7,
        +	0x6366e52d,0x02d1c000,0xc4ac8e05,0x9377f571,
        +	0x0c05372a,0x578535f2,0x2261be02,0xd642a0c9,
        +	0xdf13a280,0x74b55bd2,0x682199c0,0xd421e5ec,
        +	0x53fb3ce8,0xc8adedb3,0x28a87fc9,0x3d959981,
        +	0x5c1ff900,0xfe38d399,0x0c4eff0b,0x062407ea,
        +	0xaa2f4fb1,0x4fb96976,0x90c79505,0xb0a8a774,
        +	0xef55a1ff,0xe59ca2c2,0xa6b62d27,0xe66a4263,
        +	0xdf65001f,0x0ec50966,0xdfdd55bc,0x29de0655,
        +	0x911e739a,0x17af8975,0x32c7911c,0x89f89468,
        +	0x0d01e980,0x524755f4,0x03b63cc9,0x0cc844b2,
        +	0xbcf3f0aa,0x87ac36e9,0xe53a7426,0x01b3d82b,
        +	0x1a9e7449,0x64ee2d7e,0xcddbb1da,0x01c94910,
        +	0xb868bf80,0x0d26f3fd,0x9342ede7,0x04a5c284,
        +	0x636737b6,0x50f5b616,0xf24766e3,0x8eca36c1,
        +	0x136e05db,0xfef18391,0xfb887a37,0xd6e7f7d4,
        +	0xc7fb7dc9,0x3063fcdf,0xb6f589de,0xec2941da,
        +	0x26e46695,0xb7566419,0xf654efc5,0xd08d58b7,
        +	0x48925401,0xc1bacb7f,0xe5ff550f,0xb6083049,
        +	0x5bb5d0e8,0x87d72e5a,0xab6a6ee1,0x223a66ce,
        +	0xc62bf3cd,0x9e0885f9,0x68cb3e47,0x086c010f,
        +	0xa21de820,0xd18b69de,0xf3f65777,0xfa02c3f6,
        +	0x407edac3,0xcbb3d550,0x1793084d,0xb0d70eba,
        +	0x0ab378d5,0xd951fb0c,0xded7da56,0x4124bbe4,
        +	0x94ca0b56,0x0f5755d1,0xe0e1e56e,0x6184b5be,
        +	0x580a249f,0x94f74bc0,0xe327888e,0x9f7b5561,
        +	0xc3dc0280,0x05687715,0x646c6bd7,0x44904db3,
        +	0x66b4f0a3,0xc0f1648a,0x697ed5af,0x49e92ff6,
        +	0x309e374f,0x2cb6356a,0x85808573,0x4991f840,
        +	0x76f0ae02,0x083be84d,0x28421c9a,0x44489406,
        +	0x736e4cb8,0xc1092910,0x8bc95fc6,0x7d869cf4,
        +	0x134f616f,0x2e77118d,0xb31b2be1,0xaa90b472,
        +	0x3ca5d717,0x7d161bba,0x9cad9010,0xaf462ba2,
        +	0x9fe459d2,0x45d34559,0xd9f2da13,0xdbc65487,
        +	0xf3e4f94e,0x176d486f,0x097c13ea,0x631da5c7,
        +	0x445f7382,0x175683f4,0xcdc66a97,0x70be0288,
        +	0xb3cdcf72,0x6e5dd2f3,0x20936079,0x459b80a5,
        +	0xbe60e2db,0xa9c23101,0xeba5315c,0x224e42f2,
        +	0x1c5c1572,0xf6721b2c,0x1ad2fff3,0x8c25404e,
        +	0x324ed72f,0x4067b7fd,0x0523138e,0x5ca3bc78,
        +	0xdc0fd66e,0x75922283,0x784d6b17,0x58ebb16e,
        +	0x44094f85,0x3f481d87,0xfcfeae7b,0x77b5ff76,
        +	0x8c2302bf,0xaaf47556,0x5f46b02a,0x2b092801,
        +	0x3d38f5f7,0x0ca81f36,0x52af4a8a,0x66d5e7c0,
        +	0xdf3b0874,0x95055110,0x1b5ad7a8,0xf61ed5ad,
        +	0x6cf6e479,0x20758184,0xd0cefa65,0x88f7be58,
        +	0x4a046826,0x0ff6f8f3,0xa09c7f70,0x5346aba0,
        +	0x5ce96c28,0xe176eda3,0x6bac307f,0x376829d2,
        +	0x85360fa9,0x17e3fe2a,0x24b79767,0xf5a96b20,
        +	0xd6cd2595,0x68ff1ebf,0x7555442c,0xf19f06be,
        +	0xf9e0659a,0xeeb9491d,0x34010718,0xbb30cab8,
        +	0xe822fe15,0x88570983,0x750e6249,0xda627e55,
        +	0x5e76ffa8,0xb1534546,0x6d47de08,0xefe9e7d4,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256]={
        +	0xf6fa8f9d,0x2cac6ce1,0x4ca34867,0xe2337f7c,
        +	0x95db08e7,0x016843b4,0xeced5cbc,0x325553ac,
        +	0xbf9f0960,0xdfa1e2ed,0x83f0579d,0x63ed86b9,
        +	0x1ab6a6b8,0xde5ebe39,0xf38ff732,0x8989b138,
        +	0x33f14961,0xc01937bd,0xf506c6da,0xe4625e7e,
        +	0xa308ea99,0x4e23e33c,0x79cbd7cc,0x48a14367,
        +	0xa3149619,0xfec94bd5,0xa114174a,0xeaa01866,
        +	0xa084db2d,0x09a8486f,0xa888614a,0x2900af98,
        +	0x01665991,0xe1992863,0xc8f30c60,0x2e78ef3c,
        +	0xd0d51932,0xcf0fec14,0xf7ca07d2,0xd0a82072,
        +	0xfd41197e,0x9305a6b0,0xe86be3da,0x74bed3cd,
        +	0x372da53c,0x4c7f4448,0xdab5d440,0x6dba0ec3,
        +	0x083919a7,0x9fbaeed9,0x49dbcfb0,0x4e670c53,
        +	0x5c3d9c01,0x64bdb941,0x2c0e636a,0xba7dd9cd,
        +	0xea6f7388,0xe70bc762,0x35f29adb,0x5c4cdd8d,
        +	0xf0d48d8c,0xb88153e2,0x08a19866,0x1ae2eac8,
        +	0x284caf89,0xaa928223,0x9334be53,0x3b3a21bf,
        +	0x16434be3,0x9aea3906,0xefe8c36e,0xf890cdd9,
        +	0x80226dae,0xc340a4a3,0xdf7e9c09,0xa694a807,
        +	0x5b7c5ecc,0x221db3a6,0x9a69a02f,0x68818a54,
        +	0xceb2296f,0x53c0843a,0xfe893655,0x25bfe68a,
        +	0xb4628abc,0xcf222ebf,0x25ac6f48,0xa9a99387,
        +	0x53bddb65,0xe76ffbe7,0xe967fd78,0x0ba93563,
        +	0x8e342bc1,0xe8a11be9,0x4980740d,0xc8087dfc,
        +	0x8de4bf99,0xa11101a0,0x7fd37975,0xda5a26c0,
        +	0xe81f994f,0x9528cd89,0xfd339fed,0xb87834bf,
        +	0x5f04456d,0x22258698,0xc9c4c83b,0x2dc156be,
        +	0x4f628daa,0x57f55ec5,0xe2220abe,0xd2916ebf,
        +	0x4ec75b95,0x24f2c3c0,0x42d15d99,0xcd0d7fa0,
        +	0x7b6e27ff,0xa8dc8af0,0x7345c106,0xf41e232f,
        +	0x35162386,0xe6ea8926,0x3333b094,0x157ec6f2,
        +	0x372b74af,0x692573e4,0xe9a9d848,0xf3160289,
        +	0x3a62ef1d,0xa787e238,0xf3a5f676,0x74364853,
        +	0x20951063,0x4576698d,0xb6fad407,0x592af950,
        +	0x36f73523,0x4cfb6e87,0x7da4cec0,0x6c152daa,
        +	0xcb0396a8,0xc50dfe5d,0xfcd707ab,0x0921c42f,
        +	0x89dff0bb,0x5fe2be78,0x448f4f33,0x754613c9,
        +	0x2b05d08d,0x48b9d585,0xdc049441,0xc8098f9b,
        +	0x7dede786,0xc39a3373,0x42410005,0x6a091751,
        +	0x0ef3c8a6,0x890072d6,0x28207682,0xa9a9f7be,
        +	0xbf32679d,0xd45b5b75,0xb353fd00,0xcbb0e358,
        +	0x830f220a,0x1f8fb214,0xd372cf08,0xcc3c4a13,
        +	0x8cf63166,0x061c87be,0x88c98f88,0x6062e397,
        +	0x47cf8e7a,0xb6c85283,0x3cc2acfb,0x3fc06976,
        +	0x4e8f0252,0x64d8314d,0xda3870e3,0x1e665459,
        +	0xc10908f0,0x513021a5,0x6c5b68b7,0x822f8aa0,
        +	0x3007cd3e,0x74719eef,0xdc872681,0x073340d4,
        +	0x7e432fd9,0x0c5ec241,0x8809286c,0xf592d891,
        +	0x08a930f6,0x957ef305,0xb7fbffbd,0xc266e96f,
        +	0x6fe4ac98,0xb173ecc0,0xbc60b42a,0x953498da,
        +	0xfba1ae12,0x2d4bd736,0x0f25faab,0xa4f3fceb,
        +	0xe2969123,0x257f0c3d,0x9348af49,0x361400bc,
        +	0xe8816f4a,0x3814f200,0xa3f94043,0x9c7a54c2,
        +	0xbc704f57,0xda41e7f9,0xc25ad33a,0x54f4a084,
        +	0xb17f5505,0x59357cbe,0xedbd15c8,0x7f97c5ab,
        +	0xba5ac7b5,0xb6f6deaf,0x3a479c3a,0x5302da25,
        +	0x653d7e6a,0x54268d49,0x51a477ea,0x5017d55b,
        +	0xd7d25d88,0x44136c76,0x0404a8c8,0xb8e5a121,
        +	0xb81a928a,0x60ed5869,0x97c55b96,0xeaec991b,
        +	0x29935913,0x01fdb7f1,0x088e8dfa,0x9ab6f6f5,
        +	0x3b4cbf9f,0x4a5de3ab,0xe6051d35,0xa0e1d855,
        +	0xd36b4cf1,0xf544edeb,0xb0e93524,0xbebb8fbd,
        +	0xa2d762cf,0x49c92f54,0x38b5f331,0x7128a454,
        +	0x48392905,0xa65b1db8,0x851c97bd,0xd675cf2f,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256]={
        +	0x85e04019,0x332bf567,0x662dbfff,0xcfc65693,
        +	0x2a8d7f6f,0xab9bc912,0xde6008a1,0x2028da1f,
        +	0x0227bce7,0x4d642916,0x18fac300,0x50f18b82,
        +	0x2cb2cb11,0xb232e75c,0x4b3695f2,0xb28707de,
        +	0xa05fbcf6,0xcd4181e9,0xe150210c,0xe24ef1bd,
        +	0xb168c381,0xfde4e789,0x5c79b0d8,0x1e8bfd43,
        +	0x4d495001,0x38be4341,0x913cee1d,0x92a79c3f,
        +	0x089766be,0xbaeeadf4,0x1286becf,0xb6eacb19,
        +	0x2660c200,0x7565bde4,0x64241f7a,0x8248dca9,
        +	0xc3b3ad66,0x28136086,0x0bd8dfa8,0x356d1cf2,
        +	0x107789be,0xb3b2e9ce,0x0502aa8f,0x0bc0351e,
        +	0x166bf52a,0xeb12ff82,0xe3486911,0xd34d7516,
        +	0x4e7b3aff,0x5f43671b,0x9cf6e037,0x4981ac83,
        +	0x334266ce,0x8c9341b7,0xd0d854c0,0xcb3a6c88,
        +	0x47bc2829,0x4725ba37,0xa66ad22b,0x7ad61f1e,
        +	0x0c5cbafa,0x4437f107,0xb6e79962,0x42d2d816,
        +	0x0a961288,0xe1a5c06e,0x13749e67,0x72fc081a,
        +	0xb1d139f7,0xf9583745,0xcf19df58,0xbec3f756,
        +	0xc06eba30,0x07211b24,0x45c28829,0xc95e317f,
        +	0xbc8ec511,0x38bc46e9,0xc6e6fa14,0xbae8584a,
        +	0xad4ebc46,0x468f508b,0x7829435f,0xf124183b,
        +	0x821dba9f,0xaff60ff4,0xea2c4e6d,0x16e39264,
        +	0x92544a8b,0x009b4fc3,0xaba68ced,0x9ac96f78,
        +	0x06a5b79a,0xb2856e6e,0x1aec3ca9,0xbe838688,
        +	0x0e0804e9,0x55f1be56,0xe7e5363b,0xb3a1f25d,
        +	0xf7debb85,0x61fe033c,0x16746233,0x3c034c28,
        +	0xda6d0c74,0x79aac56c,0x3ce4e1ad,0x51f0c802,
        +	0x98f8f35a,0x1626a49f,0xeed82b29,0x1d382fe3,
        +	0x0c4fb99a,0xbb325778,0x3ec6d97b,0x6e77a6a9,
        +	0xcb658b5c,0xd45230c7,0x2bd1408b,0x60c03eb7,
        +	0xb9068d78,0xa33754f4,0xf430c87d,0xc8a71302,
        +	0xb96d8c32,0xebd4e7be,0xbe8b9d2d,0x7979fb06,
        +	0xe7225308,0x8b75cf77,0x11ef8da4,0xe083c858,
        +	0x8d6b786f,0x5a6317a6,0xfa5cf7a0,0x5dda0033,
        +	0xf28ebfb0,0xf5b9c310,0xa0eac280,0x08b9767a,
        +	0xa3d9d2b0,0x79d34217,0x021a718d,0x9ac6336a,
        +	0x2711fd60,0x438050e3,0x069908a8,0x3d7fedc4,
        +	0x826d2bef,0x4eeb8476,0x488dcf25,0x36c9d566,
        +	0x28e74e41,0xc2610aca,0x3d49a9cf,0xbae3b9df,
        +	0xb65f8de6,0x92aeaf64,0x3ac7d5e6,0x9ea80509,
        +	0xf22b017d,0xa4173f70,0xdd1e16c3,0x15e0d7f9,
        +	0x50b1b887,0x2b9f4fd5,0x625aba82,0x6a017962,
        +	0x2ec01b9c,0x15488aa9,0xd716e740,0x40055a2c,
        +	0x93d29a22,0xe32dbf9a,0x058745b9,0x3453dc1e,
        +	0xd699296e,0x496cff6f,0x1c9f4986,0xdfe2ed07,
        +	0xb87242d1,0x19de7eae,0x053e561a,0x15ad6f8c,
        +	0x66626c1c,0x7154c24c,0xea082b2a,0x93eb2939,
        +	0x17dcb0f0,0x58d4f2ae,0x9ea294fb,0x52cf564c,
        +	0x9883fe66,0x2ec40581,0x763953c3,0x01d6692e,
        +	0xd3a0c108,0xa1e7160e,0xe4f2dfa6,0x693ed285,
        +	0x74904698,0x4c2b0edd,0x4f757656,0x5d393378,
        +	0xa132234f,0x3d321c5d,0xc3f5e194,0x4b269301,
        +	0xc79f022f,0x3c997e7e,0x5e4f9504,0x3ffafbbd,
        +	0x76f7ad0e,0x296693f4,0x3d1fce6f,0xc61e45be,
        +	0xd3b5ab34,0xf72bf9b7,0x1b0434c0,0x4e72b567,
        +	0x5592a33d,0xb5229301,0xcfd2a87f,0x60aeb767,
        +	0x1814386b,0x30bcc33d,0x38a0c07d,0xfd1606f2,
        +	0xc363519b,0x589dd390,0x5479f8e6,0x1cb8d647,
        +	0x97fd61a9,0xea7759f4,0x2d57539d,0x569a58cf,
        +	0xe84e63ad,0x462e1b78,0x6580f87e,0xf3817914,
        +	0x91da55f4,0x40a230f3,0xd1988f35,0xb6e318d2,
        +	0x3ffa50bc,0x3d40f021,0xc3c0bdae,0x4958c24c,
        +	0x518f36b2,0x84b1d370,0x0fedce83,0x878ddada,
        +	0xf2a279c7,0x94e01be8,0x90716f4b,0x954b8aa3,
        +	};
        +OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256]={
        +	0xe216300d,0xbbddfffc,0xa7ebdabd,0x35648095,
        +	0x7789f8b7,0xe6c1121b,0x0e241600,0x052ce8b5,
        +	0x11a9cfb0,0xe5952f11,0xece7990a,0x9386d174,
        +	0x2a42931c,0x76e38111,0xb12def3a,0x37ddddfc,
        +	0xde9adeb1,0x0a0cc32c,0xbe197029,0x84a00940,
        +	0xbb243a0f,0xb4d137cf,0xb44e79f0,0x049eedfd,
        +	0x0b15a15d,0x480d3168,0x8bbbde5a,0x669ded42,
        +	0xc7ece831,0x3f8f95e7,0x72df191b,0x7580330d,
        +	0x94074251,0x5c7dcdfa,0xabbe6d63,0xaa402164,
        +	0xb301d40a,0x02e7d1ca,0x53571dae,0x7a3182a2,
        +	0x12a8ddec,0xfdaa335d,0x176f43e8,0x71fb46d4,
        +	0x38129022,0xce949ad4,0xb84769ad,0x965bd862,
        +	0x82f3d055,0x66fb9767,0x15b80b4e,0x1d5b47a0,
        +	0x4cfde06f,0xc28ec4b8,0x57e8726e,0x647a78fc,
        +	0x99865d44,0x608bd593,0x6c200e03,0x39dc5ff6,
        +	0x5d0b00a3,0xae63aff2,0x7e8bd632,0x70108c0c,
        +	0xbbd35049,0x2998df04,0x980cf42a,0x9b6df491,
        +	0x9e7edd53,0x06918548,0x58cb7e07,0x3b74ef2e,
        +	0x522fffb1,0xd24708cc,0x1c7e27cd,0xa4eb215b,
        +	0x3cf1d2e2,0x19b47a38,0x424f7618,0x35856039,
        +	0x9d17dee7,0x27eb35e6,0xc9aff67b,0x36baf5b8,
        +	0x09c467cd,0xc18910b1,0xe11dbf7b,0x06cd1af8,
        +	0x7170c608,0x2d5e3354,0xd4de495a,0x64c6d006,
        +	0xbcc0c62c,0x3dd00db3,0x708f8f34,0x77d51b42,
        +	0x264f620f,0x24b8d2bf,0x15c1b79e,0x46a52564,
        +	0xf8d7e54e,0x3e378160,0x7895cda5,0x859c15a5,
        +	0xe6459788,0xc37bc75f,0xdb07ba0c,0x0676a3ab,
        +	0x7f229b1e,0x31842e7b,0x24259fd7,0xf8bef472,
        +	0x835ffcb8,0x6df4c1f2,0x96f5b195,0xfd0af0fc,
        +	0xb0fe134c,0xe2506d3d,0x4f9b12ea,0xf215f225,
        +	0xa223736f,0x9fb4c428,0x25d04979,0x34c713f8,
        +	0xc4618187,0xea7a6e98,0x7cd16efc,0x1436876c,
        +	0xf1544107,0xbedeee14,0x56e9af27,0xa04aa441,
        +	0x3cf7c899,0x92ecbae6,0xdd67016d,0x151682eb,
        +	0xa842eedf,0xfdba60b4,0xf1907b75,0x20e3030f,
        +	0x24d8c29e,0xe139673b,0xefa63fb8,0x71873054,
        +	0xb6f2cf3b,0x9f326442,0xcb15a4cc,0xb01a4504,
        +	0xf1e47d8d,0x844a1be5,0xbae7dfdc,0x42cbda70,
        +	0xcd7dae0a,0x57e85b7a,0xd53f5af6,0x20cf4d8c,
        +	0xcea4d428,0x79d130a4,0x3486ebfb,0x33d3cddc,
        +	0x77853b53,0x37effcb5,0xc5068778,0xe580b3e6,
        +	0x4e68b8f4,0xc5c8b37e,0x0d809ea2,0x398feb7c,
        +	0x132a4f94,0x43b7950e,0x2fee7d1c,0x223613bd,
        +	0xdd06caa2,0x37df932b,0xc4248289,0xacf3ebc3,
        +	0x5715f6b7,0xef3478dd,0xf267616f,0xc148cbe4,
        +	0x9052815e,0x5e410fab,0xb48a2465,0x2eda7fa4,
        +	0xe87b40e4,0xe98ea084,0x5889e9e1,0xefd390fc,
        +	0xdd07d35b,0xdb485694,0x38d7e5b2,0x57720101,
        +	0x730edebc,0x5b643113,0x94917e4f,0x503c2fba,
        +	0x646f1282,0x7523d24a,0xe0779695,0xf9c17a8f,
        +	0x7a5b2121,0xd187b896,0x29263a4d,0xba510cdf,
        +	0x81f47c9f,0xad1163ed,0xea7b5965,0x1a00726e,
        +	0x11403092,0x00da6d77,0x4a0cdd61,0xad1f4603,
        +	0x605bdfb0,0x9eedc364,0x22ebe6a8,0xcee7d28a,
        +	0xa0e736a0,0x5564a6b9,0x10853209,0xc7eb8f37,
        +	0x2de705ca,0x8951570f,0xdf09822b,0xbd691a6c,
        +	0xaa12e4f2,0x87451c0f,0xe0f6a27a,0x3ada4819,
        +	0x4cf1764f,0x0d771c2b,0x67cdb156,0x350d8384,
        +	0x5938fa0f,0x42399ef3,0x36997b07,0x0e84093d,
        +	0x4aa93e61,0x8360d87b,0x1fa98b0c,0x1149382c,
        +	0xe97625a5,0x0614d1b7,0x0e25244b,0x0c768347,
        +	0x589e8d82,0x0d2059d1,0xa466bb1e,0xf8da0a82,
        +	0x04f19130,0xba6e4ec0,0x99265164,0x1ee7230d,
        +	0x50b2ad80,0xeaee6801,0x8db2a283,0xea8bf59e,
        +	};
        diff --git a/vendor/openssl/openssl/crypto/cast/cast_spd.c b/vendor/openssl/openssl/crypto/cast/cast_spd.c
        new file mode 100644
        index 000000000..d650af475
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/cast_spd.c
        @@ -0,0 +1,278 @@
        +/* crypto/cast/cast_spd.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/cast.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +#ifndef CLK_TCK
        +#define HZ	100.0
        +#else /* CLK_TCK */
        +#define HZ ((double)CLK_TCK)
        +#endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static unsigned char key[] ={
        +			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
        +			};
        +	CAST_KEY sch;
        +	double a,b,c,d;
        +#ifndef SIGALRM
        +	long ca,cb,cc;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	CAST_set_key(&sch,16,key);
        +	count=10;
        +	do	{
        +		long i;
        +		CAST_LONG data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			CAST_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count/512;
        +	cb=count;
        +	cc=count*8/BUFSIZE+1;
        +	printf("Doing CAST_set_key %ld times\n",ca);
        +#define COND(d)	(count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing CAST_set_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count+=4)
        +		{
        +		CAST_set_key(&sch,16,key);
        +		CAST_set_key(&sch,16,key);
        +		CAST_set_key(&sch,16,key);
        +		CAST_set_key(&sch,16,key);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld cast set_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing CAST_encrypt's for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing CAST_encrypt %ld times\n",cb);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cb); count+=4)
        +		{
        +		CAST_LONG data[2];
        +
        +		CAST_encrypt(data,&sch);
        +		CAST_encrypt(data,&sch);
        +		CAST_encrypt(data,&sch);
        +		CAST_encrypt(data,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld CAST_encrypt's in %.2f second\n",count,d);
        +	b=((double)COUNT(cb)*8)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing CAST_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing CAST_cbc_encrypt %ld times on %ld byte blocks\n",cc,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		CAST_cbc_encrypt(buf,buf,BUFSIZE,&sch,
        +			&(key[0]),CAST_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld CAST_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +	printf("CAST set_key       per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("CAST raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
        +	printf("CAST cbc     bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/cast/castopts.c b/vendor/openssl/openssl/crypto/cast/castopts.c
        new file mode 100644
        index 000000000..33b2c7b06
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/castopts.c
        @@ -0,0 +1,342 @@
        +/* crypto/cast/castopts.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.]
        + */
        +
        +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
        + * This is for machines with 64k code segment size restrictions. */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC))
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/cast.h>
        +
        +#define CAST_DEFAULT_OPTIONS
        +
        +#undef E_CAST
        +#define CAST_encrypt  CAST_encrypt_normal
        +#define CAST_decrypt  CAST_decrypt_normal
        +#define CAST_cbc_encrypt  CAST_cbc_encrypt_normal
        +#undef HEADER_CAST_LOCL_H
        +#include "c_enc.c"
        +
        +#define CAST_PTR
        +#undef CAST_PTR2
        +#undef E_CAST
        +#undef CAST_encrypt
        +#undef CAST_decrypt
        +#undef CAST_cbc_encrypt
        +#define CAST_encrypt  CAST_encrypt_ptr
        +#define CAST_decrypt  CAST_decrypt_ptr
        +#define CAST_cbc_encrypt  CAST_cbc_encrypt_ptr
        +#undef HEADER_CAST_LOCL_H
        +#include "c_enc.c"
        +
        +#undef CAST_PTR
        +#define CAST_PTR2
        +#undef E_CAST
        +#undef CAST_encrypt
        +#undef CAST_decrypt
        +#undef CAST_cbc_encrypt
        +#define CAST_encrypt  CAST_encrypt_ptr2
        +#define CAST_decrypt  CAST_decrypt_ptr2
        +#define CAST_cbc_encrypt  CAST_cbc_encrypt_ptr2
        +#undef HEADER_CAST_LOCL_H
        +#include "c_enc.c"
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +# ifndef CLK_TCK
        +#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
        +#   define HZ	100.0
        +#  else /* _BSD_CLK_TCK_ */
        +#   define HZ ((double)_BSD_CLK_TCK_)
        +#  endif
        +# else /* CLK_TCK */
        +#  define HZ ((double)CLK_TCK)
        +# endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +#ifdef SIGALRM
        +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
        +#else
        +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
        +#endif
        +	
        +#define time_it(func,name,index) \
        +	print_name(name); \
        +	Time_F(START); \
        +	for (count=0,run=1; COND(cb); count+=4) \
        +		{ \
        +		unsigned long d[2]; \
        +		func(d,&sch); \
        +		func(d,&sch); \
        +		func(d,&sch); \
        +		func(d,&sch); \
        +		} \
        +	tm[index]=Time_F(STOP); \
        +	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
        +	tm[index]=((double)COUNT(cb))/tm[index];
        +
        +#define print_it(name,index) \
        +	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
        +		tm[index]*8,1.0e6/tm[index]);
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static char key[16]={	0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +				0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
        +	CAST_KEY sch;
        +	double d,tm[16],max=0;
        +	int rank[16];
        +	char *str[16];
        +	int max_idx=0,i,num=0,j;
        +#ifndef SIGALARM
        +	long ca,cb,cc,cd,ce;
        +#endif
        +
        +	for (i=0; i<12; i++)
        +		{
        +		tm[i]=0.0;
        +		rank[i]=0;
        +		}
        +
        +#ifndef TIMES
        +	fprintf(stderr,"To get the most accurate results, try to run this\n");
        +	fprintf(stderr,"program when this computer is idle.\n");
        +#endif
        +
        +	CAST_set_key(&sch,16,key);
        +
        +#ifndef SIGALRM
        +	fprintf(stderr,"First we calculate the approximate speed ...\n");
        +	count=10;
        +	do	{
        +		long i;
        +		unsigned long data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			CAST_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count;
        +	cb=count*3;
        +	cc=count*3*8/BUFSIZE+1;
        +	cd=count*8/BUFSIZE+1;
        +
        +	ce=count/20+1;
        +#define COND(d) (count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c) (run)
        +#define COUNT(d) (count)
        +        signal(SIGALRM,sig_done);
        +        alarm(10);
        +#endif
        +
        +	time_it(CAST_encrypt_normal,	"CAST_encrypt_normal ", 0);
        +	time_it(CAST_encrypt_ptr,	"CAST_encrypt_ptr    ", 1);
        +	time_it(CAST_encrypt_ptr2,	"CAST_encrypt_ptr2   ", 2);
        +	num+=3;
        +
        +	str[0]="<nothing>";
        +	print_it("CAST_encrypt_normal ",0);
        +	max=tm[0];
        +	max_idx=0;
        +	str[1]="ptr      ";
        +	print_it("CAST_encrypt_ptr ",1);
        +	if (max < tm[1]) { max=tm[1]; max_idx=1; }
        +	str[2]="ptr2     ";
        +	print_it("CAST_encrypt_ptr2 ",2);
        +	if (max < tm[2]) { max=tm[2]; max_idx=2; }
        +
        +	printf("options    CAST ecb/s\n");
        +	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
        +	d=tm[max_idx];
        +	tm[max_idx]= -2.0;
        +	max= -1.0;
        +	for (;;)
        +		{
        +		for (i=0; i<3; i++)
        +			{
        +			if (max < tm[i]) { max=tm[i]; j=i; }
        +			}
        +		if (max < 0.0) break;
        +		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
        +		tm[j]= -2.0;
        +		max= -1.0;
        +		}
        +
        +	switch (max_idx)
        +		{
        +	case 0:
        +		printf("-DCAST_DEFAULT_OPTIONS\n");
        +		break;
        +	case 1:
        +		printf("-DCAST_PTR\n");
        +		break;
        +	case 2:
        +		printf("-DCAST_PTR2\n");
        +		break;
        +		}
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/cast/casts.cpp b/vendor/openssl/openssl/crypto/cast/casts.cpp
        new file mode 100644
        index 000000000..8d7bd468d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/casts.cpp
        @@ -0,0 +1,70 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/cast.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	CAST_KEY key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +	static unsigned char d[16]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
        +
        +	CAST_set_key(&key, 16,d);
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			CAST_encrypt(&data[0],&key);
        +			GetTSC(s1);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			GetTSC(e2);
        +			CAST_encrypt(&data[0],&key);
        +			}
        +
        +		printf("cast %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/cast/casttest.c b/vendor/openssl/openssl/crypto/cast/casttest.c
        new file mode 100644
        index 000000000..0d020d697
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cast/casttest.c
        @@ -0,0 +1,233 @@
        +/* crypto/cast/casttest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_CAST is defined */
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_CAST
        +int main(int argc, char *argv[])
        +{
        +    printf("No CAST support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/cast.h>
        +
        +#define FULL_TEST
        +
        +static unsigned char k[16]={
        +	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
        +	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A
        +	};
        +
        +static unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
        +
        +static int k_len[3]={16,10,5};
        +static unsigned char c[3][8]={
        +	{0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2},
        +	{0xEB,0x6A,0x71,0x1A,0x2C,0x02,0x27,0x1B},
        +	{0x7A,0xC8,0x16,0xD1,0x6E,0x9B,0x30,0x2E},
        +	};
        +static unsigned char out[80];
        +
        +static unsigned char in_a[16]={
        +	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
        +	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
        +static unsigned char in_b[16]={
        +	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
        +	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
        +
        +static unsigned char c_a[16]={
        +	0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
        +	0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92};
        +static unsigned char c_b[16]={
        +	0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
        +	0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E};
        +
        +#if 0
        +char *text="Hello to all people out there";
        +
        +static unsigned char cfb_key[16]={
        +	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
        +	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
        +	};
        +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +#define CFB_TEST_SIZE 24
        +static unsigned char plain[CFB_TEST_SIZE]=
        +        {
        +        0x4e,0x6f,0x77,0x20,0x69,0x73,
        +        0x20,0x74,0x68,0x65,0x20,0x74,
        +        0x69,0x6d,0x65,0x20,0x66,0x6f,
        +        0x72,0x20,0x61,0x6c,0x6c,0x20
        +        };
        +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
        +	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
        +	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
        +	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
        +
        +/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
        +	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
        +	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
        +	}; 
        +#endif
        +
        +int main(int argc, char *argv[])
        +    {
        +#ifdef FULL_TEST
        +    long l;
        +    CAST_KEY key_b;
        +#endif
        +    int i,z,err=0;
        +    CAST_KEY key;
        +
        +    for (z=0; z<3; z++)
        +	{
        +	CAST_set_key(&key,k_len[z],k);
        +
        +	CAST_ecb_encrypt(in,out,&key,CAST_ENCRYPT);
        +	if (memcmp(out,&(c[z][0]),8) != 0)
        +	    {
        +	    printf("ecb cast error encrypting for keysize %d\n",k_len[z]*8);
        +	    printf("got     :");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",out[i]);
        +	    printf("\n");
        +	    printf("expected:");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",c[z][i]);
        +	    err=20;
        +	    printf("\n");
        +	    }
        +
        +	CAST_ecb_encrypt(out,out,&key,CAST_DECRYPT);
        +	if (memcmp(out,in,8) != 0)
        +	    {
        +	    printf("ecb cast error decrypting for keysize %d\n",k_len[z]*8);
        +	    printf("got     :");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",out[i]);
        +	    printf("\n");
        +	    printf("expected:");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",in[i]);
        +	    printf("\n");
        +	    err=3;
        +	    }
        +	}
        +    if (err == 0)
        +	printf("ecb cast5 ok\n");
        +
        +#ifdef FULL_TEST
        +      {
        +      unsigned char out_a[16],out_b[16];
        +      static char *hex="0123456789ABCDEF";
        +      
        +      printf("This test will take some time....");
        +      fflush(stdout);
        +      memcpy(out_a,in_a,sizeof(in_a));
        +      memcpy(out_b,in_b,sizeof(in_b));
        +      i=1;
        +
        +      for (l=0; l<1000000L; l++)
        +	  {
        +	  CAST_set_key(&key_b,16,out_b);
        +	  CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT);
        +	  CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT);
        +	  CAST_set_key(&key,16,out_a);
        +	  CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT);
        +	  CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT);
        +	  if ((l & 0xffff) == 0xffff)
        +	      {
        +	      printf("%c",hex[i&0x0f]);
        +	      fflush(stdout);
        +	      i++;
        +	      }
        +	  }
        +
        +      if (	(memcmp(out_a,c_a,sizeof(c_a)) != 0) ||
        +		(memcmp(out_b,c_b,sizeof(c_b)) != 0))
        +	  {
        +	  printf("\n");
        +	  printf("Error\n");
        +
        +	  printf("A out =");
        +	  for (i=0; i<16; i++) printf("%02X ",out_a[i]);
        +	  printf("\nactual=");
        +	  for (i=0; i<16; i++) printf("%02X ",c_a[i]);
        +	  printf("\n");
        +
        +	  printf("B out =");
        +	  for (i=0; i<16; i++) printf("%02X ",out_b[i]);
        +	  printf("\nactual=");
        +	  for (i=0; i<16; i++) printf("%02X ",c_b[i]);
        +	  printf("\n");
        +	  }
        +      else
        +	  printf(" ok\n");
        +      }
        +#endif
        +
        +    EXIT(err);
        +    return(err);
        +    }
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cmac/Makefile b/vendor/openssl/openssl/crypto/cmac/Makefile
        new file mode 100644
        index 000000000..54e7cc39d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cmac/Makefile
        @@ -0,0 +1,111 @@
        +#
        +# OpenSSL/crypto/cmac/Makefile
        +#
        +
        +DIR=	cmac
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=cmac.c cm_ameth.c cm_pmeth.c
        +LIBOBJ=cmac.o cm_ameth.o cm_pmeth.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= cmac.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +cm_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
        +cm_ameth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cm_ameth.o: ../../include/openssl/cmac.h ../../include/openssl/crypto.h
        +cm_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +cm_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cm_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cm_ameth.o: ../../include/openssl/opensslconf.h
        +cm_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cm_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cm_ameth.o: ../../include/openssl/symhacks.h ../asn1/asn1_locl.h ../cryptlib.h
        +cm_ameth.o: cm_ameth.c
        +cm_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +cm_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cm_pmeth.o: ../../include/openssl/cmac.h ../../include/openssl/conf.h
        +cm_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cm_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cm_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cm_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cm_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cm_pmeth.o: ../../include/openssl/opensslconf.h
        +cm_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cm_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +cm_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cm_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cm_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cm_pmeth.o: ../cryptlib.h ../evp/evp_locl.h cm_pmeth.c
        +cmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +cmac.o: ../../include/openssl/buffer.h ../../include/openssl/cmac.h
        +cmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cmac.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +cmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cmac.o: ../../include/openssl/symhacks.h ../cryptlib.h cmac.c
        diff --git a/vendor/openssl/openssl/crypto/cmac/cm_ameth.c b/vendor/openssl/openssl/crypto/cmac/cm_ameth.c
        new file mode 100644
        index 000000000..0b8e5670b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cmac/cm_ameth.c
        @@ -0,0 +1,97 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2010.
        + */
        +/* ====================================================================
        + * Copyright (c) 2010 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.
        + * ====================================================================
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/cmac.h>
        +#include "asn1_locl.h"
        +
        +/* CMAC "ASN1" method. This is just here to indicate the
        + * maximum CMAC output length and to free up a CMAC
        + * key.
        + */
        +
        +static int cmac_size(const EVP_PKEY *pkey)
        +	{
        +	return EVP_MAX_BLOCK_LENGTH;
        +	}
        +
        +static void cmac_key_free(EVP_PKEY *pkey)
        +	{
        +	CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr;
        +	if (cmctx)
        +		CMAC_CTX_free(cmctx);
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = 
        +	{
        +	EVP_PKEY_CMAC,
        +	EVP_PKEY_CMAC,
        +	0,
        +
        +	"CMAC",
        +	"OpenSSL CMAC method",
        +
        +	0,0,0,0,
        +
        +	0,0,0,
        +
        +	cmac_size,
        +	0,
        +	0,0,0,0,0,0,0,
        +
        +	cmac_key_free,
        +	0,
        +	0,0
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/cmac/cm_pmeth.c b/vendor/openssl/openssl/crypto/cmac/cm_pmeth.c
        new file mode 100644
        index 000000000..072228ec7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cmac/cm_pmeth.c
        @@ -0,0 +1,224 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2010.
        + */
        +/* ====================================================================
        + * Copyright (c) 2010 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.
        + * ====================================================================
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/evp.h>
        +#include <openssl/cmac.h>
        +#include "evp_locl.h"
        +
        +/* The context structure and "key" is simply a CMAC_CTX */
        +
        +static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
        +	{
        +	ctx->data = CMAC_CTX_new();
        +	if (!ctx->data)
        +		return 0;
        +	ctx->keygen_info_count = 0;
        +	return 1;
        +	}
        +
        +static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	if (!pkey_cmac_init(dst))
        +		return 0;
        +	if (!CMAC_CTX_copy(dst->data, src->data))
        +		return 0;
        +	return 1;
        +	}
        +
        +static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
        +	{
        +	CMAC_CTX_free(ctx->data);
        +	}
        +
        +static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	CMAC_CTX *cmkey = CMAC_CTX_new();
        +	CMAC_CTX *cmctx = ctx->data;
        +	if (!cmkey)
        +		return 0;
        +	if (!CMAC_CTX_copy(cmkey, cmctx))
        +		{
        +		CMAC_CTX_free(cmkey);
        +		return 0;
        +		}
        +	EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
        +	
        +	return 1;
        +	}
        +
        +static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{
        +	if (!CMAC_Update(ctx->pctx->data, data, count))
        +		return 0;
        +	return 1;
        +	}
        +
        +static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
        +	{
        +	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
        +	mctx->update = int_update;
        +	return 1;
        +	}
        +
        +static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					EVP_MD_CTX *mctx)
        +	{
        +	return CMAC_Final(ctx->data, sig, siglen);
        +	}
        +
        +static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	CMAC_CTX *cmctx = ctx->data;
        +	switch (type)
        +		{
        +
        +		case EVP_PKEY_CTRL_SET_MAC_KEY:
        +		if (!p2 || p1 < 0)
        +			return 0;
        +		if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
        +			return 0;
        +		break;
        +
        +		case EVP_PKEY_CTRL_CIPHER:
        +		if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
        +			return 0;
        +		break;
        +
        +		case EVP_PKEY_CTRL_MD:
        +		if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
        +					(CMAC_CTX *)ctx->pkey->pkey.ptr))
        +			return 0;
        +		if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
        +			return 0;
        +		break;
        +
        +		default:
        +		return -2;
        +
        +		}
        +	return 1;
        +	}
        +
        +static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
        +			const char *type, const char *value)
        +	{
        +	if (!value)
        +		{
        +		return 0;
        +		}
        +	if (!strcmp(type, "key"))
        +		{
        +		void *p = (void *)value;
        +		return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
        +								strlen(p), p);
        +		}
        +	if (!strcmp(type, "cipher"))
        +		{
        +		const EVP_CIPHER *c;
        +		c = EVP_get_cipherbyname(value);
        +		if (!c)
        +			return 0;
        +		return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
        +		}
        +	if (!strcmp(type, "hexkey"))
        +		{
        +		unsigned char *key;
        +		int r;
        +		long keylen;
        +		key = string_to_hex(value, &keylen);
        +		if (!key)
        +			return 0;
        +		r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
        +		OPENSSL_free(key);
        +		return r;
        +		}
        +	return -2;
        +	}
        +
        +const EVP_PKEY_METHOD cmac_pkey_meth = 
        +	{
        +	EVP_PKEY_CMAC,
        +	EVP_PKEY_FLAG_SIGCTX_CUSTOM,
        +	pkey_cmac_init,
        +	pkey_cmac_copy,
        +	pkey_cmac_cleanup,
        +
        +	0, 0,
        +
        +	0,
        +	pkey_cmac_keygen,
        +
        +	0, 0,
        +
        +	0, 0,
        +
        +	0,0,
        +
        +	cmac_signctx_init,
        +	cmac_signctx,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	pkey_cmac_ctrl,
        +	pkey_cmac_ctrl_str
        +
        +	};
        diff --git a/vendor/openssl/openssl/crypto/cmac/cmac.c b/vendor/openssl/openssl/crypto/cmac/cmac.c
        new file mode 100644
        index 000000000..8b72b0968
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cmac/cmac.c
        @@ -0,0 +1,308 @@
        +/* crypto/cmac/cmac.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2010 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.
        + * ====================================================================
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/cmac.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +struct CMAC_CTX_st
        +	{
        +	/* Cipher context to use */
        +	EVP_CIPHER_CTX cctx;
        +	/* Keys k1 and k2 */
        +	unsigned char k1[EVP_MAX_BLOCK_LENGTH];
        +	unsigned char k2[EVP_MAX_BLOCK_LENGTH];
        +	/* Temporary block */
        +	unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
        +	/* Last (possibly partial) block */
        +	unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
        +	/* Number of bytes in last block: -1 means context not initialised */
        +	int nlast_block;
        +	};
        +
        +
        +/* Make temporary keys K1 and K2 */
        +
        +static void make_kn(unsigned char *k1, unsigned char *l, int bl)
        +	{
        +	int i;
        +	/* Shift block to left, including carry */
        +	for (i = 0; i < bl; i++)
        +		{
        +		k1[i] = l[i] << 1;
        +		if (i < bl - 1 && l[i + 1] & 0x80)
        +			k1[i] |= 1;
        +		}
        +	/* If MSB set fixup with R */
        +	if (l[0] & 0x80)
        +		k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
        +	}
        +
        +CMAC_CTX *CMAC_CTX_new(void)
        +	{
        +	CMAC_CTX *ctx;
        +	ctx = OPENSSL_malloc(sizeof(CMAC_CTX));
        +	if (!ctx)
        +		return NULL;
        +	EVP_CIPHER_CTX_init(&ctx->cctx);
        +	ctx->nlast_block = -1;
        +	return ctx;
        +	}
        +
        +void CMAC_CTX_cleanup(CMAC_CTX *ctx)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !ctx->cctx.engine)
        +		{
        +		FIPS_cmac_ctx_cleanup(ctx);
        +		return;
        +		}
        +#endif
        +	EVP_CIPHER_CTX_cleanup(&ctx->cctx);
        +	OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
        +	OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
        +	OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
        +	OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
        +	ctx->nlast_block = -1;
        +	}
        +
        +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
        +	{
        +	return &ctx->cctx;
        +	}
        +
        +void CMAC_CTX_free(CMAC_CTX *ctx)
        +	{
        +	CMAC_CTX_cleanup(ctx);
        +	OPENSSL_free(ctx);
        +	}
        +
        +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
        +	{
        +	int bl;
        +	if (in->nlast_block == -1)
        +		return 0;
        +	if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
        +		return 0;
        +	bl = EVP_CIPHER_CTX_block_size(&in->cctx);
        +	memcpy(out->k1, in->k1, bl);
        +	memcpy(out->k2, in->k2, bl);
        +	memcpy(out->tbl, in->tbl, bl);
        +	memcpy(out->last_block, in->last_block, bl);
        +	out->nlast_block = in->nlast_block;
        +	return 1;
        +	}
        +
        +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, 
        +			const EVP_CIPHER *cipher, ENGINE *impl)
        +	{
        +	static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		{
        +		/* If we have an ENGINE need to allow non FIPS */
        +		if ((impl || ctx->cctx.engine)
        +			&& !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
        +
        +			{
        +			EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
        +			return 0;
        +			}
        +		/* Other algorithm blocking will be done in FIPS_cmac_init,
        +		 * via FIPS_cipherinit().
        +		 */
        +		if (!impl && !ctx->cctx.engine)
        +			return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
        +		}
        +#endif
        +	/* All zeros means restart */
        +	if (!key && !cipher && !impl && keylen == 0)
        +		{
        +		/* Not initialised */
        +		if (ctx->nlast_block == -1)
        +			return 0;
        +		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
        +			return 0;
        +		memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
        +		ctx->nlast_block = 0;
        +		return 1;
        +		}
        +	/* Initialiase context */
        +	if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
        +		return 0;
        +	/* Non-NULL key means initialisation complete */
        +	if (key)
        +		{
        +		int bl;
        +		if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
        +			return 0;
        +		if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
        +			return 0;
        +		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
        +			return 0;
        +		bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
        +		if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
        +			return 0;
        +		make_kn(ctx->k1, ctx->tbl, bl);
        +		make_kn(ctx->k2, ctx->k1, bl);
        +		OPENSSL_cleanse(ctx->tbl, bl);
        +		/* Reset context again ready for first data block */
        +		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
        +			return 0;
        +		/* Zero tbl so resume works */
        +		memset(ctx->tbl, 0, bl);
        +		ctx->nlast_block = 0;
        +		}
        +	return 1;
        +	}
        +
        +int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
        +	{
        +	const unsigned char *data = in;
        +	size_t bl;
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !ctx->cctx.engine)
        +		return FIPS_cmac_update(ctx, in, dlen);
        +#endif
        +	if (ctx->nlast_block == -1)
        +		return 0;
        +	if (dlen == 0)
        +		return 1;
        +	bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
        +	/* Copy into partial block if we need to */
        +	if (ctx->nlast_block > 0)
        +		{
        +		size_t nleft;
        +		nleft = bl - ctx->nlast_block;
        +		if (dlen < nleft)
        +			nleft = dlen;
        +		memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
        +		dlen -= nleft;
        +		ctx->nlast_block += nleft;
        +		/* If no more to process return */
        +		if (dlen == 0)
        +			return 1;
        +		data += nleft;
        +		/* Else not final block so encrypt it */
        +		if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl))
        +			return 0;
        +		}
        +	/* Encrypt all but one of the complete blocks left */
        +	while(dlen > bl)
        +		{
        +		if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
        +			return 0;
        +		dlen -= bl;
        +		data += bl;
        +		}
        +	/* Copy any data left to last block buffer */
        +	memcpy(ctx->last_block, data, dlen);
        +	ctx->nlast_block = dlen;
        +	return 1;
        +
        +	}
        +
        +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
        +	{
        +	int i, bl, lb;
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !ctx->cctx.engine)
        +		return FIPS_cmac_final(ctx, out, poutlen);
        +#endif
        +	if (ctx->nlast_block == -1)
        +		return 0;
        +	bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
        +	*poutlen = (size_t)bl;
        +	if (!out)
        +		return 1;
        +	lb = ctx->nlast_block;
        +	/* Is last block complete? */
        +	if (lb == bl)
        +		{
        +		for (i = 0; i < bl; i++)
        +			out[i] = ctx->last_block[i] ^ ctx->k1[i];
        +		}
        +	else
        +		{
        +		ctx->last_block[lb] = 0x80;
        +		if (bl - lb > 1)
        +			memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
        +		for (i = 0; i < bl; i++)
        +			out[i] = ctx->last_block[i] ^ ctx->k2[i];
        +		}
        +	if (!EVP_Cipher(&ctx->cctx, out, out, bl))
        +		{
        +		OPENSSL_cleanse(out, bl);	
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int CMAC_resume(CMAC_CTX *ctx)
        +	{
        +	if (ctx->nlast_block == -1)
        +		return 0;
        +	/* The buffer "tbl" containes the last fully encrypted block
        +	 * which is the last IV (or all zeroes if no last encrypted block).
        +	 * The last block has not been modified since CMAC_final().
        +	 * So reinitliasing using the last decrypted block will allow
        +	 * CMAC to continue after calling CMAC_Final(). 
        +	 */
        +	return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cmac/cmac.h b/vendor/openssl/openssl/crypto/cmac/cmac.h
        new file mode 100644
        index 000000000..712e92dce
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cmac/cmac.h
        @@ -0,0 +1,82 @@
        +/* crypto/cmac/cmac.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2010 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.
        + * ====================================================================
        + */
        +
        +
        +#ifndef HEADER_CMAC_H
        +#define HEADER_CMAC_H
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +#include <openssl/evp.h>
        +
        +/* Opaque */
        +typedef struct CMAC_CTX_st CMAC_CTX;
        +
        +CMAC_CTX *CMAC_CTX_new(void);
        +void CMAC_CTX_cleanup(CMAC_CTX *ctx);
        +void CMAC_CTX_free(CMAC_CTX *ctx);
        +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
        +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);
        +
        +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, 
        +			const EVP_CIPHER *cipher, ENGINE *impl);
        +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
        +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
        +int CMAC_resume(CMAC_CTX *ctx);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cms/Makefile b/vendor/openssl/openssl/crypto/cms/Makefile
        new file mode 100644
        index 000000000..9820adb21
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/Makefile
        @@ -0,0 +1,284 @@
        +#
        +# OpenSSL/crypto/cms/Makefile
        +#
        +
        +DIR=	cms
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
        +	cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \
        +	cms_pwri.c
        +LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
        +	cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o \
        +	cms_pwri.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER=  cms.h
        +HEADER=	cms_lcl.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +test:
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +cms_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +cms_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cms_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_asn1.o: ../../include/openssl/opensslconf.h
        +cms_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_asn1.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +cms_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cms_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cms_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cms_asn1.o: cms.h cms_asn1.c cms_lcl.h
        +cms_att.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +cms_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cms_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cms_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cms_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +cms_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_att.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +cms_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cms_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cms_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cms_att.o: cms.h cms_att.c cms_lcl.h
        +cms_cd.o: ../../e_os.h ../../include/openssl/asn1.h
        +cms_cd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +cms_cd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_cd.o: ../../include/openssl/comp.h ../../include/openssl/conf.h
        +cms_cd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cms_cd.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cms_cd.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cms_cd.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_cd.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_cd.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +cms_cd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +cms_cd.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +cms_cd.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_cd.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_cd.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +cms_cd.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_cd.c cms_lcl.h
        +cms_dd.o: ../../e_os.h ../../include/openssl/asn1.h
        +cms_dd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +cms_dd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_dd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_dd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_dd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_dd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cms_dd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cms_dd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +cms_dd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_dd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_dd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +cms_dd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cms_dd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cms_dd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cms_dd.o: ../cryptlib.h cms_dd.c cms_lcl.h
        +cms_enc.o: ../../e_os.h ../../include/openssl/asn1.h
        +cms_enc.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +cms_enc.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_enc.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_enc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cms_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cms_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +cms_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_enc.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +cms_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +cms_enc.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_enc.c cms_lcl.h
        +cms_env.o: ../../e_os.h ../../include/openssl/aes.h
        +cms_env.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +cms_env.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cms_env.o: ../../include/openssl/cms.h ../../include/openssl/conf.h
        +cms_env.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cms_env.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cms_env.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cms_env.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_env.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_env.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +cms_env.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +cms_env.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +cms_env.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +cms_env.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cms_env.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cms_env.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cms_env.o: ../asn1/asn1_locl.h ../cryptlib.h cms_env.c cms_lcl.h
        +cms_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +cms_err.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cms_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cms_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cms_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +cms_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +cms_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +cms_err.o: cms_err.c
        +cms_ess.o: ../../e_os.h ../../include/openssl/asn1.h
        +cms_ess.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +cms_ess.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_ess.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_ess.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_ess.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_ess.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cms_ess.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cms_ess.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +cms_ess.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_ess.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_ess.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +cms_ess.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_ess.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_ess.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +cms_ess.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_ess.c cms_lcl.h
        +cms_io.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +cms_io.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cms_io.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cms_io.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cms_io.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cms_io.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_io.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_io.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +cms_io.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +cms_io.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +cms_io.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_io.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_io.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
        +cms_io.o: cms_io.c cms_lcl.h
        +cms_lib.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +cms_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cms_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cms_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cms_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cms_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +cms_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +cms_lib.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +cms_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
        +cms_lib.o: cms_lcl.h cms_lib.c
        +cms_pwri.o: ../../e_os.h ../../include/openssl/aes.h
        +cms_pwri.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +cms_pwri.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +cms_pwri.o: ../../include/openssl/cms.h ../../include/openssl/conf.h
        +cms_pwri.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cms_pwri.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +cms_pwri.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +cms_pwri.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +cms_pwri.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +cms_pwri.o: ../../include/openssl/opensslconf.h
        +cms_pwri.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_pwri.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_pwri.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +cms_pwri.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +cms_pwri.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cms_pwri.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +cms_pwri.o: ../../include/openssl/x509v3.h ../asn1/asn1_locl.h ../cryptlib.h
        +cms_pwri.o: cms_lcl.h cms_pwri.c
        +cms_sd.o: ../../e_os.h ../../include/openssl/asn1.h
        +cms_sd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +cms_sd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_sd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_sd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_sd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_sd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cms_sd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cms_sd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +cms_sd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_sd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +cms_sd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +cms_sd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cms_sd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cms_sd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cms_sd.o: ../asn1/asn1_locl.h ../cryptlib.h cms_lcl.h cms_sd.c
        +cms_smime.o: ../../e_os.h ../../include/openssl/asn1.h
        +cms_smime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +cms_smime.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +cms_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +cms_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +cms_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +cms_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +cms_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +cms_smime.o: ../../include/openssl/objects.h
        +cms_smime.o: ../../include/openssl/opensslconf.h
        +cms_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cms_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +cms_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +cms_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +cms_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +cms_smime.o: ../cryptlib.h cms_lcl.h cms_smime.c
        diff --git a/vendor/openssl/openssl/crypto/cms/cms.h b/vendor/openssl/openssl/crypto/cms/cms.h
        new file mode 100644
        index 000000000..36994fa6a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms.h
        @@ -0,0 +1,501 @@
        +/* crypto/cms/cms.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +
        +#ifndef HEADER_CMS_H
        +#define HEADER_CMS_H
        +
        +#include <openssl/x509.h>
        +
        +#ifdef OPENSSL_NO_CMS
        +#error CMS is disabled.
        +#endif
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +typedef struct CMS_ContentInfo_st CMS_ContentInfo;
        +typedef struct CMS_SignerInfo_st CMS_SignerInfo;
        +typedef struct CMS_CertificateChoices CMS_CertificateChoices;
        +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
        +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
        +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
        +typedef struct CMS_Receipt_st CMS_Receipt;
        +
        +DECLARE_STACK_OF(CMS_SignerInfo)
        +DECLARE_STACK_OF(GENERAL_NAMES)
        +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
        +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
        +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
        +
        +#define CMS_SIGNERINFO_ISSUER_SERIAL	0
        +#define CMS_SIGNERINFO_KEYIDENTIFIER	1
        +
        +#define CMS_RECIPINFO_TRANS		0
        +#define CMS_RECIPINFO_AGREE		1
        +#define CMS_RECIPINFO_KEK		2
        +#define CMS_RECIPINFO_PASS		3
        +#define CMS_RECIPINFO_OTHER		4
        +
        +/* S/MIME related flags */
        +
        +#define CMS_TEXT			0x1
        +#define CMS_NOCERTS			0x2
        +#define CMS_NO_CONTENT_VERIFY		0x4
        +#define CMS_NO_ATTR_VERIFY		0x8
        +#define CMS_NOSIGS			\
        +			(CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
        +#define CMS_NOINTERN			0x10
        +#define CMS_NO_SIGNER_CERT_VERIFY	0x20
        +#define CMS_NOVERIFY			0x20
        +#define CMS_DETACHED			0x40
        +#define CMS_BINARY			0x80
        +#define CMS_NOATTR			0x100
        +#define	CMS_NOSMIMECAP			0x200
        +#define CMS_NOOLDMIMETYPE		0x400
        +#define CMS_CRLFEOL			0x800
        +#define CMS_STREAM			0x1000
        +#define CMS_NOCRL			0x2000
        +#define CMS_PARTIAL			0x4000
        +#define CMS_REUSE_DIGEST		0x8000
        +#define CMS_USE_KEYID			0x10000
        +#define CMS_DEBUG_DECRYPT		0x20000
        +
        +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
        +
        +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
        +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
        +
        +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
        +int CMS_is_detached(CMS_ContentInfo *cms);
        +int CMS_set_detached(CMS_ContentInfo *cms, int detached);
        +
        +#ifdef HEADER_PEM_H
        +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
        +#endif
        +
        +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
        +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
        +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
        +
        +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
        +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
        +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
        +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
        +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
        +
        +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
        +
        +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
        +						BIO *data, unsigned int flags);
        +
        +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
        +					X509 *signcert, EVP_PKEY *pkey,
        +					STACK_OF(X509) *certs,
        +					unsigned int flags);
        +
        +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
        +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
        +
        +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
        +							unsigned int flags);
        +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
        +							unsigned int flags);
        +
        +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
        +				const unsigned char *key, size_t keylen,
        +				BIO *dcont, BIO *out, unsigned int flags);
        +
        +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
        +					const unsigned char *key, size_t keylen,
        +					unsigned int flags);
        +
        +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
        +				const unsigned char *key, size_t keylen);
        +
        +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
        +		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
        +
        +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
        +			STACK_OF(X509) *certs,
        +			X509_STORE *store, unsigned int flags);
        +
        +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
        +
        +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
        +				const EVP_CIPHER *cipher, unsigned int flags);
        +
        +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
        +				BIO *dcont, BIO *out,
        +				unsigned int flags);
        +	
        +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
        +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
        +				unsigned char *key, size_t keylen,
        +				unsigned char *id, size_t idlen);
        +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, 
        +				unsigned char *pass, ossl_ssize_t passlen);
        +
        +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
        +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
        +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
        +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
        +					X509 *recip, unsigned int flags);
        +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
        +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
        +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
        +					EVP_PKEY **pk, X509 **recip,
        +					X509_ALGOR **palg);
        +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
        +					ASN1_OCTET_STRING **keyid,
        +					X509_NAME **issuer, ASN1_INTEGER **sno);
        +
        +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
        +					unsigned char *key, size_t keylen,
        +					unsigned char *id, size_t idlen,
        +					ASN1_GENERALIZEDTIME *date,
        +					ASN1_OBJECT *otherTypeId,
        +					ASN1_TYPE *otherType);
        +
        +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
        +					X509_ALGOR **palg,
        +					ASN1_OCTET_STRING **pid,
        +					ASN1_GENERALIZEDTIME **pdate,
        +					ASN1_OBJECT **potherid,
        +					ASN1_TYPE **pothertype);
        +
        +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
        +				unsigned char *key, size_t keylen);
        +
        +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
        +					const unsigned char *id, size_t idlen);
        +
        +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 
        +					unsigned char *pass,
        +					ossl_ssize_t passlen);
        +
        +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
        +					int iter, int wrap_nid, int pbe_nid,
        +					unsigned char *pass,
        +					ossl_ssize_t passlen,
        +					const EVP_CIPHER *kekciph);
        +
        +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
        +	
        +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
        +							unsigned int flags);
        +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
        +
        +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
        +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
        +
        +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
        +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
        +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
        +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
        +
        +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
        +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
        +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
        +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
        +
        +int CMS_SignedData_init(CMS_ContentInfo *cms);
        +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
        +			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
        +			unsigned int flags);
        +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
        +
        +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
        +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
        +					ASN1_OCTET_STRING **keyid,
        +					X509_NAME **issuer, ASN1_INTEGER **sno);
        +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
        +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
        +					unsigned int flags);
        +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
        +					X509_ALGOR **pdig, X509_ALGOR **psig);
        +int CMS_SignerInfo_sign(CMS_SignerInfo *si);
        +int CMS_SignerInfo_verify(CMS_SignerInfo *si);
        +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
        +
        +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
        +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
        +				int algnid, int keysize);
        +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
        +
        +int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
        +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
        +			  int lastpos);
        +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
        +			  int lastpos);
        +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
        +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
        +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
        +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
        +			const ASN1_OBJECT *obj, int type,
        +			const void *bytes, int len);
        +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
        +			int nid, int type,
        +			const void *bytes, int len);
        +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
        +			const char *attrname, int type,
        +			const void *bytes, int len);
        +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
        +					int lastpos, int type);
        +
        +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
        +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
        +			  int lastpos);
        +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
        +			  int lastpos);
        +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
        +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
        +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
        +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
        +			const ASN1_OBJECT *obj, int type,
        +			const void *bytes, int len);
        +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
        +			int nid, int type,
        +			const void *bytes, int len);
        +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
        +			const char *attrname, int type,
        +			const void *bytes, int len);
        +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
        +					int lastpos, int type);
        +
        +#ifdef HEADER_X509V3_H
        +
        +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
        +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
        +				int allorfirst,
        +				STACK_OF(GENERAL_NAMES) *receiptList,
        +				STACK_OF(GENERAL_NAMES) *receiptsTo);
        +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
        +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
        +					ASN1_STRING **pcid,
        +					int *pallorfirst,
        +					STACK_OF(GENERAL_NAMES) **plist,
        +					STACK_OF(GENERAL_NAMES) **prto);
        +
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_CMS_strings(void);
        +
        +/* Error codes for the CMS functions. */
        +
        +/* Function codes. */
        +#define CMS_F_CHECK_CONTENT				 99
        +#define CMS_F_CMS_ADD0_CERT				 164
        +#define CMS_F_CMS_ADD0_RECIPIENT_KEY			 100
        +#define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD		 165
        +#define CMS_F_CMS_ADD1_RECEIPTREQUEST			 158
        +#define CMS_F_CMS_ADD1_RECIPIENT_CERT			 101
        +#define CMS_F_CMS_ADD1_SIGNER				 102
        +#define CMS_F_CMS_ADD1_SIGNINGTIME			 103
        +#define CMS_F_CMS_COMPRESS				 104
        +#define CMS_F_CMS_COMPRESSEDDATA_CREATE			 105
        +#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO		 106
        +#define CMS_F_CMS_COPY_CONTENT				 107
        +#define CMS_F_CMS_COPY_MESSAGEDIGEST			 108
        +#define CMS_F_CMS_DATA					 109
        +#define CMS_F_CMS_DATAFINAL				 110
        +#define CMS_F_CMS_DATAINIT				 111
        +#define CMS_F_CMS_DECRYPT				 112
        +#define CMS_F_CMS_DECRYPT_SET1_KEY			 113
        +#define CMS_F_CMS_DECRYPT_SET1_PASSWORD			 166
        +#define CMS_F_CMS_DECRYPT_SET1_PKEY			 114
        +#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX		 115
        +#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116
        +#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL			 117
        +#define CMS_F_CMS_DIGEST_VERIFY				 118
        +#define CMS_F_CMS_ENCODE_RECEIPT			 161
        +#define CMS_F_CMS_ENCRYPT				 119
        +#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO		 120
        +#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT			 121
        +#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT			 122
        +#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY		 123
        +#define CMS_F_CMS_ENVELOPEDDATA_CREATE			 124
        +#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO		 125
        +#define CMS_F_CMS_ENVELOPED_DATA_INIT			 126
        +#define CMS_F_CMS_FINAL					 127
        +#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES		 128
        +#define CMS_F_CMS_GET0_CONTENT				 129
        +#define CMS_F_CMS_GET0_ECONTENT_TYPE			 130
        +#define CMS_F_CMS_GET0_ENVELOPED			 131
        +#define CMS_F_CMS_GET0_REVOCATION_CHOICES		 132
        +#define CMS_F_CMS_GET0_SIGNED				 133
        +#define CMS_F_CMS_MSGSIGDIGEST_ADD1			 162
        +#define CMS_F_CMS_RECEIPTREQUEST_CREATE0		 159
        +#define CMS_F_CMS_RECEIPT_VERIFY			 160
        +#define CMS_F_CMS_RECIPIENTINFO_DECRYPT			 134
        +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT		 135
        +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT		 136
        +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID		 137
        +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP		 138
        +#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP		 139
        +#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT		 140
        +#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT		 141
        +#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS		 142
        +#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID	 143
        +#define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT		 167
        +#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY		 144
        +#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD		 168
        +#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145
        +#define CMS_F_CMS_SET1_SIGNERIDENTIFIER			 146
        +#define CMS_F_CMS_SET_DETACHED				 147
        +#define CMS_F_CMS_SIGN					 148
        +#define CMS_F_CMS_SIGNED_DATA_INIT			 149
        +#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN		 150
        +#define CMS_F_CMS_SIGNERINFO_SIGN			 151
        +#define CMS_F_CMS_SIGNERINFO_VERIFY			 152
        +#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT		 153
        +#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT		 154
        +#define CMS_F_CMS_SIGN_RECEIPT				 163
        +#define CMS_F_CMS_STREAM				 155
        +#define CMS_F_CMS_UNCOMPRESS				 156
        +#define CMS_F_CMS_VERIFY				 157
        +
        +/* Reason codes. */
        +#define CMS_R_ADD_SIGNER_ERROR				 99
        +#define CMS_R_CERTIFICATE_ALREADY_PRESENT		 175
        +#define CMS_R_CERTIFICATE_HAS_NO_KEYID			 160
        +#define CMS_R_CERTIFICATE_VERIFY_ERROR			 100
        +#define CMS_R_CIPHER_INITIALISATION_ERROR		 101
        +#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR	 102
        +#define CMS_R_CMS_DATAFINAL_ERROR			 103
        +#define CMS_R_CMS_LIB					 104
        +#define CMS_R_CONTENTIDENTIFIER_MISMATCH		 170
        +#define CMS_R_CONTENT_NOT_FOUND				 105
        +#define CMS_R_CONTENT_TYPE_MISMATCH			 171
        +#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA		 106
        +#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA		 107
        +#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA		 108
        +#define CMS_R_CONTENT_VERIFY_ERROR			 109
        +#define CMS_R_CTRL_ERROR				 110
        +#define CMS_R_CTRL_FAILURE				 111
        +#define CMS_R_DECRYPT_ERROR				 112
        +#define CMS_R_DIGEST_ERROR				 161
        +#define CMS_R_ERROR_GETTING_PUBLIC_KEY			 113
        +#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE	 114
        +#define CMS_R_ERROR_SETTING_KEY				 115
        +#define CMS_R_ERROR_SETTING_RECIPIENTINFO		 116
        +#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH		 117
        +#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER		 176
        +#define CMS_R_INVALID_KEY_LENGTH			 118
        +#define CMS_R_MD_BIO_INIT_ERROR				 119
        +#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH	 120
        +#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH		 121
        +#define CMS_R_MSGSIGDIGEST_ERROR			 172
        +#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE		 162
        +#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH			 163
        +#define CMS_R_NEED_ONE_SIGNER				 164
        +#define CMS_R_NOT_A_SIGNED_RECEIPT			 165
        +#define CMS_R_NOT_ENCRYPTED_DATA			 122
        +#define CMS_R_NOT_KEK					 123
        +#define CMS_R_NOT_KEY_TRANSPORT				 124
        +#define CMS_R_NOT_PWRI					 177
        +#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE		 125
        +#define CMS_R_NO_CIPHER					 126
        +#define CMS_R_NO_CONTENT				 127
        +#define CMS_R_NO_CONTENT_TYPE				 173
        +#define CMS_R_NO_DEFAULT_DIGEST				 128
        +#define CMS_R_NO_DIGEST_SET				 129
        +#define CMS_R_NO_KEY					 130
        +#define CMS_R_NO_KEY_OR_CERT				 174
        +#define CMS_R_NO_MATCHING_DIGEST			 131
        +#define CMS_R_NO_MATCHING_RECIPIENT			 132
        +#define CMS_R_NO_MATCHING_SIGNATURE			 166
        +#define CMS_R_NO_MSGSIGDIGEST				 167
        +#define CMS_R_NO_PASSWORD				 178
        +#define CMS_R_NO_PRIVATE_KEY				 133
        +#define CMS_R_NO_PUBLIC_KEY				 134
        +#define CMS_R_NO_RECEIPT_REQUEST			 168
        +#define CMS_R_NO_SIGNERS				 135
        +#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 136
        +#define CMS_R_RECEIPT_DECODE_ERROR			 169
        +#define CMS_R_RECIPIENT_ERROR				 137
        +#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND		 138
        +#define CMS_R_SIGNFINAL_ERROR				 139
        +#define CMS_R_SMIME_TEXT_ERROR				 140
        +#define CMS_R_STORE_INIT_ERROR				 141
        +#define CMS_R_TYPE_NOT_COMPRESSED_DATA			 142
        +#define CMS_R_TYPE_NOT_DATA				 143
        +#define CMS_R_TYPE_NOT_DIGESTED_DATA			 144
        +#define CMS_R_TYPE_NOT_ENCRYPTED_DATA			 145
        +#define CMS_R_TYPE_NOT_ENVELOPED_DATA			 146
        +#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT		 147
        +#define CMS_R_UNKNOWN_CIPHER				 148
        +#define CMS_R_UNKNOWN_DIGEST_ALGORIHM			 149
        +#define CMS_R_UNKNOWN_ID				 150
        +#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 151
        +#define CMS_R_UNSUPPORTED_CONTENT_TYPE			 152
        +#define CMS_R_UNSUPPORTED_KEK_ALGORITHM			 153
        +#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM	 179
        +#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE		 154
        +#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE		 155
        +#define CMS_R_UNSUPPORTED_TYPE				 156
        +#define CMS_R_UNWRAP_ERROR				 157
        +#define CMS_R_UNWRAP_FAILURE				 180
        +#define CMS_R_VERIFICATION_FAILURE			 158
        +#define CMS_R_WRAP_ERROR				 159
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_asn1.c b/vendor/openssl/openssl/crypto/cms/cms_asn1.c
        new file mode 100644
        index 000000000..cfe67fb6c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_asn1.c
        @@ -0,0 +1,389 @@
        +/* crypto/cms/cms_asn1.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include "cms.h"
        +#include "cms_lcl.h"
        +
        +
        +ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
        +	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
        +	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
        +
        +ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
        +	ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
        +	ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
        +} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
        +
        +ASN1_CHOICE(CMS_CertificateChoices) = {
        +	ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
        +	ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
        +	ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
        +	ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
        +	ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
        +} ASN1_CHOICE_END(CMS_CertificateChoices)
        +
        +ASN1_CHOICE(CMS_SignerIdentifier) = {
        +	ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
        +	ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
        +} ASN1_CHOICE_END(CMS_SignerIdentifier)
        +
        +ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
        +	ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
        +	ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
        +} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
        +
        +/* Minor tweak to operation: free up signer key, cert */
        +static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +	{
        +	if(operation == ASN1_OP_FREE_POST)
        +		{
        +		CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
        +		if (si->pkey)
        +			EVP_PKEY_free(si->pkey);
        +		if (si->signer)
        +			X509_free(si->signer);
        +		}
        +	return 1;
        +	}
        +
        +ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
        +	ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
        +	ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
        +	ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
        +	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
        +	ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
        +	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
        +} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
        +
        +ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
        +	ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
        +	ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
        +} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
        +
        +ASN1_CHOICE(CMS_RevocationInfoChoice) = {
        +	ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
        +	ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
        +} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
        +
        +ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
        +	ASN1_SIMPLE(CMS_SignedData, version, LONG),
        +	ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
        +	ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
        +	ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
        +	ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
        +} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
        +
        +ASN1_SEQUENCE(CMS_OriginatorInfo) = {
        +	ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
        +	ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
        +} ASN1_SEQUENCE_END(CMS_OriginatorInfo)
        +
        +ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
        +	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
        +	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
        +	ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
        +} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
        +
        +ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
        +	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
        +	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
        +	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
        +
        +ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
        +	ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
        +	ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
        +} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
        +
        +ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
        +	ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
        +	ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
        +	ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
        +} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
        +
        +ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
        +  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
        +  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
        +} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
        +
        +ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = {
        +	ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
        +	ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey)
        +
        +ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
        +  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
        +  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
        +
        +ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
        +  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
        +  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
        +  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
        +} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
        +
        +ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = {
        +	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
        +	ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
        +	ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
        +	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
        +	ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
        +} ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo)
        +
        +ASN1_SEQUENCE(CMS_KEKIdentifier) = {
        +	ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
        +	ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
        +	ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
        +} ASN1_SEQUENCE_END(CMS_KEKIdentifier)
        +
        +ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
        +	ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
        +	ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
        +	ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
        +
        +ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
        +	ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
        +	ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
        +	ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
        +
        +ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
        +  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
        +  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
        +} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
        +
        +/* Free up RecipientInfo additional data */
        +static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +	{
        +	if(operation == ASN1_OP_FREE_PRE)
        +		{
        +		CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
        +		if (ri->type == CMS_RECIPINFO_TRANS)
        +			{
        +			CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
        +			if (ktri->pkey)
        +				EVP_PKEY_free(ktri->pkey);
        +			if (ktri->recip)
        +				X509_free(ktri->recip);
        +			}
        +		else if (ri->type == CMS_RECIPINFO_KEK)
        +			{
        +			CMS_KEKRecipientInfo *kekri = ri->d.kekri;
        +			if (kekri->key)
        +				{
        +				OPENSSL_cleanse(kekri->key, kekri->keylen);
        +				OPENSSL_free(kekri->key);
        +				}
        +			}
        +		else if (ri->type == CMS_RECIPINFO_PASS)
        +			{
        +			CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
        +			if (pwri->pass)
        +				{
        +				OPENSSL_cleanse(pwri->pass, pwri->passlen);
        +				OPENSSL_free(pwri->pass);
        +				}
        +			}
        +		}
        +	return 1;
        +	}
        +
        +ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
        +	ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
        +	ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
        +	ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
        +	ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
        +	ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
        +} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
        +
        +ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
        +	ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
        +	ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
        +	ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
        +	ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
        +	ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
        +} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
        +
        +ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
        +	ASN1_SIMPLE(CMS_DigestedData, version, LONG),
        +	ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
        +	ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
        +} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
        +
        +ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
        +	ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
        +	ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
        +	ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
        +} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
        +
        +ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
        +	ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
        +	ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
        +	ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
        +	ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
        +	ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
        +	ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
        +	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
        +	ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
        +	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
        +} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
        +
        +ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
        +	ASN1_SIMPLE(CMS_CompressedData, version, LONG),
        +	ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
        +} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
        +
        +/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
        +
        +ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
        +
        +ASN1_ADB(CMS_ContentInfo) = {
        +	ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
        +	ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
        +	ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
        +	ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
        +	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
        +	ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
        +	ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
        +} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
        +
        +/* CMS streaming support */
        +static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +	{
        +	ASN1_STREAM_ARG *sarg = exarg;
        +	CMS_ContentInfo *cms = NULL;
        +	if (pval)
        +		cms = (CMS_ContentInfo *)*pval;
        +	else
        +		return 1;
        +	switch(operation)
        +		{
        +
        +		case ASN1_OP_STREAM_PRE:
        +		if (CMS_stream(&sarg->boundary, cms) <= 0)
        +			return 0;
        +		case ASN1_OP_DETACHED_PRE:
        +		sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
        +		if (!sarg->ndef_bio)
        +			return 0;
        +		break;
        +
        +		case ASN1_OP_STREAM_POST:
        +		case ASN1_OP_DETACHED_POST:
        +		if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
        +			return 0;
        +		break;
        +
        +		}
        +	return 1;
        +	}
        +
        +ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
        +	ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(CMS_ContentInfo)
        +} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
        +
        +/* Specials for signed attributes */
        +
        +/* When signing attributes we want to reorder them to match the sorted
        + * encoding.
        + */
        +
        +ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
        +ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
        +
        +/* When verifying attributes we need to use the received order. So 
        + * we use SEQUENCE OF and tag it to SET OF
        + */
        +
        +ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
        +				V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
        +ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
        +
        +
        +
        +ASN1_CHOICE(CMS_ReceiptsFrom) = {
        +  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
        +  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
        +} ASN1_CHOICE_END(CMS_ReceiptsFrom)
        +
        +ASN1_SEQUENCE(CMS_ReceiptRequest) = {
        +  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
        +  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
        +  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
        +} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
        +
        +ASN1_SEQUENCE(CMS_Receipt) = {
        +  ASN1_SIMPLE(CMS_Receipt, version, LONG),
        +  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
        +  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
        +  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(CMS_Receipt)
        +
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_att.c b/vendor/openssl/openssl/crypto/cms/cms_att.c
        new file mode 100644
        index 000000000..5b71722eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_att.c
        @@ -0,0 +1,195 @@
        +/* crypto/cms/cms_att.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include "cms.h"
        +#include "cms_lcl.h"
        +
        +/* CMS SignedData Attribute utilities */
        +
        +int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
        +{
        +	return X509at_get_attr_count(si->signedAttrs);
        +}
        +
        +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
        +}
        +
        +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
        +}
        +
        +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
        +{
        +	return X509at_get_attr(si->signedAttrs, loc);
        +}
        +
        +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
        +{
        +	return X509at_delete_attr(si->signedAttrs, loc);
        +}
        +
        +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
        +{
        +	if(X509at_add1_attr(&si->signedAttrs, attr)) return 1;
        +	return 0;
        +}
        +
        +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
        +			const ASN1_OBJECT *obj, int type,
        +			const void *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_OBJ(&si->signedAttrs, obj,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
        +			int nid, int type,
        +			const void *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_NID(&si->signedAttrs, nid,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
        +			const char *attrname, int type,
        +			const void *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_txt(&si->signedAttrs, attrname,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
        +					int lastpos, int type)
        +{
        +	return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
        +}
        +
        +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
        +{
        +	return X509at_get_attr_count(si->unsignedAttrs);
        +}
        +
        +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
        +}
        +
        +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
        +}
        +
        +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
        +{
        +	return X509at_get_attr(si->unsignedAttrs, loc);
        +}
        +
        +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
        +{
        +	return X509at_delete_attr(si->unsignedAttrs, loc);
        +}
        +
        +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
        +{
        +	if(X509at_add1_attr(&si->unsignedAttrs, attr)) return 1;
        +	return 0;
        +}
        +
        +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
        +			const ASN1_OBJECT *obj, int type,
        +			const void *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
        +			int nid, int type,
        +			const void *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_NID(&si->unsignedAttrs, nid,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
        +			const char *attrname, int type,
        +			const void *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
        +					int lastpos, int type)
        +{
        +	return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
        +}
        +
        +/* Specific attribute cases */
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_cd.c b/vendor/openssl/openssl/crypto/cms/cms_cd.c
        new file mode 100644
        index 000000000..202168810
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_cd.c
        @@ -0,0 +1,136 @@
        +/* crypto/cms/cms_cd.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include <openssl/bio.h>
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#include "cms_lcl.h"
        +
        +DECLARE_ASN1_ITEM(CMS_CompressedData)
        +
        +#ifdef ZLIB
        +
        +/* CMS CompressedData Utilities */
        +
        +CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
        +	{
        +	CMS_ContentInfo *cms;
        +	CMS_CompressedData *cd;
        +	/* Will need something cleverer if there is ever more than one
        +	 * compression algorithm or parameters have some meaning...
        +	 */
        +	if (comp_nid != NID_zlib_compression)
        +		{
        +		CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
        +				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
        +		return NULL;
        +		}
        +	cms = CMS_ContentInfo_new();
        +	if (!cms)
        +		return NULL;
        +
        +	cd = M_ASN1_new_of(CMS_CompressedData);
        +
        +	if (!cd)
        +		goto err;
        +
        +	cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
        +	cms->d.compressedData = cd;
        +
        +	cd->version = 0;
        +
        +	X509_ALGOR_set0(cd->compressionAlgorithm,
        +			OBJ_nid2obj(NID_zlib_compression),
        +			V_ASN1_UNDEF, NULL);
        +
        +	cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
        +
        +	return cms;
        +
        +	err:
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +
        +	return NULL;
        +	}
        +
        +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
        +	{
        +	CMS_CompressedData *cd;
        +	ASN1_OBJECT *compoid;
        +	if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData)
        +		{
        +		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
        +				CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
        +		return NULL;
        +		}
        +	cd = cms->d.compressedData;
        +	X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
        +	if (OBJ_obj2nid(compoid) != NID_zlib_compression)
        +		{
        +		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
        +				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
        +		return NULL;
        +		}
        +	return BIO_new(BIO_f_zlib());
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_dd.c b/vendor/openssl/openssl/crypto/cms/cms_dd.c
        new file mode 100644
        index 000000000..8919c15be
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_dd.c
        @@ -0,0 +1,148 @@
        +/* crypto/cms/cms_dd.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include "cms_lcl.h"
        +
        +DECLARE_ASN1_ITEM(CMS_DigestedData)
        +
        +/* CMS DigestedData Utilities */
        +
        +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
        +	{
        +	CMS_ContentInfo *cms;
        +	CMS_DigestedData *dd;
        +	cms = CMS_ContentInfo_new();
        +	if (!cms)
        +		return NULL;
        +
        +	dd = M_ASN1_new_of(CMS_DigestedData);
        +
        +	if (!dd)
        +		goto err;
        +
        +	cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
        +	cms->d.digestedData = dd;
        +
        +	dd->version = 0;
        +	dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
        +
        +	cms_DigestAlgorithm_set(dd->digestAlgorithm, md);
        +
        +	return cms;
        +
        +	err:
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +
        +	return NULL;
        +	}
        +
        +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
        +	{
        +	CMS_DigestedData *dd;
        +	dd = cms->d.digestedData;
        +	return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
        +	}
        +
        +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
        +	{
        +	EVP_MD_CTX mctx;
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +	unsigned int mdlen;
        +	int r = 0;
        +	CMS_DigestedData *dd;
        +	EVP_MD_CTX_init(&mctx);
        +
        +	dd = cms->d.digestedData;
        +
        +	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
        +		goto err;
        +
        +	if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
        +		goto err;
        +
        +	if (verify)
        +		{
        +		if (mdlen != (unsigned int)dd->digest->length)
        +			{
        +			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
        +				CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
        +			goto err;
        +			}
        +
        +		if (memcmp(md, dd->digest->data, mdlen))
        +			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
        +				CMS_R_VERIFICATION_FAILURE);
        +		else
        +			r = 1;
        +		}
        +	else
        +		{
        +		if (!ASN1_STRING_set(dd->digest, md, mdlen))
        +			goto err;
        +		r = 1;
        +		}
        +
        +	err:
        +	EVP_MD_CTX_cleanup(&mctx);
        +
        +	return r;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_enc.c b/vendor/openssl/openssl/crypto/cms/cms_enc.c
        new file mode 100644
        index 000000000..bebeaf29c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_enc.c
        @@ -0,0 +1,294 @@
        +/* crypto/cms/cms_enc.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include <openssl/rand.h>
        +#include "cms_lcl.h"
        +
        +/* CMS EncryptedData Utilities */
        +
        +DECLARE_ASN1_ITEM(CMS_EncryptedData)
        +
        +/* Return BIO based on EncryptedContentInfo and key */
        +
        +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
        +	{
        +	BIO *b;
        +	EVP_CIPHER_CTX *ctx;
        +	const EVP_CIPHER *ciph;
        +	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
        +	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
        +	unsigned char *tkey = NULL;
        +	size_t tkeylen = 0;
        +
        +	int ok = 0;
        +
        +	int enc, keep_key = 0;
        +
        +	enc = ec->cipher ? 1 : 0;
        +
        +	b = BIO_new(BIO_f_cipher());
        +	if (!b)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +							ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	BIO_get_cipher_ctx(b, &ctx);
        +
        +	if (enc)
        +		{
        +		ciph = ec->cipher;
        +		/* If not keeping key set cipher to NULL so subsequent calls
        +		 * decrypt.
        +		 */
        +		if (ec->key)
        +			ec->cipher = NULL;
        +		}
        +	else
        +		{
        +		ciph = EVP_get_cipherbyobj(calg->algorithm);
        +
        +		if (!ciph)
        +			{
        +			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +							CMS_R_UNKNOWN_CIPHER);
        +			goto err;
        +			}
        +		}
        +
        +	if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +				CMS_R_CIPHER_INITIALISATION_ERROR);
        +		goto err;
        +		}
        +
        +	if (enc)
        +		{
        +		int ivlen;
        +		calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
        +		/* Generate a random IV if we need one */
        +		ivlen = EVP_CIPHER_CTX_iv_length(ctx);
        +		if (ivlen > 0)
        +			{
        +			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
        +				goto err;
        +			piv = iv;
        +			}
        +		}
        +	else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
        +		goto err;
        +		}
        +	tkeylen = EVP_CIPHER_CTX_key_length(ctx);
        +	/* Generate random session key */
        +	if (!enc || !ec->key)
        +		{
        +		tkey = OPENSSL_malloc(tkeylen);
        +		if (!tkey)
        +			{
        +			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +							ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
        +			goto err;
        +		}
        +
        +	if (!ec->key)
        +		{
        +		ec->key = tkey;
        +		ec->keylen = tkeylen;
        +		tkey = NULL;
        +		if (enc)
        +			keep_key = 1;
        +		else
        +			ERR_clear_error();
        +		
        +		}
        +
        +	if (ec->keylen != tkeylen)
        +		{
        +		/* If necessary set key length */
        +		if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
        +			{
        +			/* Only reveal failure if debugging so we don't
        +			 * leak information which may be useful in MMA.
        +			 */
        +			if (enc || ec->debug)
        +				{
        +				CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +						CMS_R_INVALID_KEY_LENGTH);
        +				goto err;
        +				}
        +			else
        +				{
        +				/* Use random key */
        +				OPENSSL_cleanse(ec->key, ec->keylen);
        +				OPENSSL_free(ec->key);
        +				ec->key = tkey;
        +				ec->keylen = tkeylen;
        +				tkey = NULL;
        +				ERR_clear_error();
        +				}
        +			}
        +		}
        +
        +	if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +				CMS_R_CIPHER_INITIALISATION_ERROR);
        +		goto err;
        +		}
        +
        +	if (piv)
        +		{
        +		calg->parameter = ASN1_TYPE_new();
        +		if (!calg->parameter)
        +			{
        +			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +							ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
        +				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
        +			goto err;
        +			}
        +		}
        +	ok = 1;
        +
        +	err:
        +	if (ec->key && !keep_key)
        +		{
        +		OPENSSL_cleanse(ec->key, ec->keylen);
        +		OPENSSL_free(ec->key);
        +		ec->key = NULL;
        +		}
        +	if (tkey)
        +		{
        +		OPENSSL_cleanse(tkey, tkeylen);
        +		OPENSSL_free(tkey);
        +		}
        +	if (ok)
        +		return b;
        +	BIO_free(b);
        +	return NULL;
        +	}
        +
        +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
        +				const EVP_CIPHER *cipher,
        +				const unsigned char *key, size_t keylen)
        +	{
        +	ec->cipher = cipher;
        +	if (key)
        +		{
        +		ec->key = OPENSSL_malloc(keylen);
        +		if (!ec->key)
        +			return 0;
        +		memcpy(ec->key, key, keylen);
        +		}
        +	ec->keylen = keylen;
        +	if (cipher)
        +		ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
        +	return 1;
        +	}
        +
        +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
        +				const unsigned char *key, size_t keylen)
        +	{
        +	CMS_EncryptedContentInfo *ec;
        +	if (!key || !keylen)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
        +		return 0;
        +		}
        +	if (ciph)
        +		{
        +		cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
        +		if (!cms->d.encryptedData)
        +			{
        +			CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
        +				ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
        +		cms->d.encryptedData->version = 0;
        +		}
        +	else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
        +						CMS_R_NOT_ENCRYPTED_DATA);
        +		return 0;
        +		}
        +	ec = cms->d.encryptedData->encryptedContentInfo;
        +	return cms_EncryptedContent_init(ec, ciph, key, keylen);
        +	}
        +
        +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
        +	{
        +	CMS_EncryptedData *enc = cms->d.encryptedData;
        +	if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
        +		enc->version = 2;
        +	return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_env.c b/vendor/openssl/openssl/crypto/cms/cms_env.c
        new file mode 100644
        index 000000000..be20b1c02
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_env.c
        @@ -0,0 +1,876 @@
        +/* crypto/cms/cms_env.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include <openssl/rand.h>
        +#include <openssl/aes.h>
        +#include "cms_lcl.h"
        +#include "asn1_locl.h"
        +
        +/* CMS EnvelopedData Utilities */
        +
        +DECLARE_ASN1_ITEM(CMS_EnvelopedData)
        +DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
        +DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
        +DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
        +
        +DECLARE_STACK_OF(CMS_RecipientInfo)
        +
        +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
        +	{
        +	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
        +		{
        +		CMSerr(CMS_F_CMS_GET0_ENVELOPED,
        +				CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
        +		return NULL;
        +		}
        +	return cms->d.envelopedData;
        +	}
        +
        +static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
        +	{
        +	if (cms->d.other == NULL)
        +		{
        +		cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
        +		if (!cms->d.envelopedData)
        +			{
        +			CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
        +							ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +			}
        +		cms->d.envelopedData->version = 0;
        +		cms->d.envelopedData->encryptedContentInfo->contentType =
        +						OBJ_nid2obj(NID_pkcs7_data);
        +		ASN1_OBJECT_free(cms->contentType);
        +		cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
        +		return cms->d.envelopedData;
        +		}
        +	return cms_get0_enveloped(cms);
        +	}
        +
        +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
        +	{
        +	CMS_EnvelopedData *env;
        +	env = cms_get0_enveloped(cms);
        +	if (!env)
        +		return NULL;
        +	return env->recipientInfos;
        +	}
        +
        +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
        +	{
        +	return ri->type;
        +	}
        +
        +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
        +	{
        +	CMS_ContentInfo *cms;
        +	CMS_EnvelopedData *env;
        +	cms = CMS_ContentInfo_new();
        +	if (!cms)
        +		goto merr;
        +	env = cms_enveloped_data_init(cms);
        +	if (!env)
        +		goto merr;
        +	if (!cms_EncryptedContent_init(env->encryptedContentInfo,
        +					cipher, NULL, 0))
        +		goto merr;
        +	return cms;
        +	merr:
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +	}
        +
        +/* Key Transport Recipient Info (KTRI) routines */
        +
        +/* Add a recipient certificate. For now only handle key transport.
        + * If we ever handle key agreement will need updating.
        + */
        +
        +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
        +					X509 *recip, unsigned int flags)
        +	{
        +	CMS_RecipientInfo *ri = NULL;
        +	CMS_KeyTransRecipientInfo *ktri;
        +	CMS_EnvelopedData *env;
        +	EVP_PKEY *pk = NULL;
        +	int i, type;
        +	env = cms_get0_enveloped(cms);
        +	if (!env)
        +		goto err;
        +
        +	/* Initialize recipient info */
        +	ri = M_ASN1_new_of(CMS_RecipientInfo);
        +	if (!ri)
        +		goto merr;
        +
        +	/* Initialize and add key transport recipient info */
        +
        +	ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
        +	if (!ri->d.ktri)
        +		goto merr;
        +	ri->type = CMS_RECIPINFO_TRANS;
        +
        +	ktri = ri->d.ktri;
        +
        +	X509_check_purpose(recip, -1, -1);
        +	pk = X509_get_pubkey(recip);
        +	if (!pk)
        +		{
        +		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
        +				CMS_R_ERROR_GETTING_PUBLIC_KEY);
        +		goto err;
        +		}
        +	CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
        +	ktri->pkey = pk;
        +	ktri->recip = recip;
        +
        +	if (flags & CMS_USE_KEYID)
        +		{
        +		ktri->version = 2;
        +		type = CMS_RECIPINFO_KEYIDENTIFIER;
        +		}
        +	else
        +		{
        +		ktri->version = 0;
        +		type = CMS_RECIPINFO_ISSUER_SERIAL;
        +		}
        +
        +	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
        +	 * same structure.
        +	 */
        +
        +	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
        +		goto err;
        +
        +	if (pk->ameth && pk->ameth->pkey_ctrl)
        +		{
        +		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
        +						0, ri);
        +		if (i == -2)
        +			{
        +			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
        +				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
        +			goto err;
        +			}
        +		if (i <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
        +				CMS_R_CTRL_FAILURE);
        +			goto err;
        +			}
        +		}
        +
        +	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
        +		goto merr;
        +
        +	return ri;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
        +	err:
        +	if (ri)
        +		M_ASN1_free_of(ri, CMS_RecipientInfo);
        +	return NULL;
        +
        +	}
        +
        +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
        +					EVP_PKEY **pk, X509 **recip,
        +					X509_ALGOR **palg)
        +	{
        +	CMS_KeyTransRecipientInfo *ktri;
        +	if (ri->type != CMS_RECIPINFO_TRANS)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
        +			CMS_R_NOT_KEY_TRANSPORT);
        +		return 0;
        +		}
        +
        +	ktri = ri->d.ktri;
        +
        +	if (pk)
        +		*pk = ktri->pkey;
        +	if (recip)
        +		*recip = ktri->recip;
        +	if (palg)
        +		*palg = ktri->keyEncryptionAlgorithm;
        +	return 1;
        +	}
        +
        +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
        +					ASN1_OCTET_STRING **keyid,
        +					X509_NAME **issuer, ASN1_INTEGER **sno)
        +	{
        +	CMS_KeyTransRecipientInfo *ktri;
        +	if (ri->type != CMS_RECIPINFO_TRANS)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
        +			CMS_R_NOT_KEY_TRANSPORT);
        +		return 0;
        +		}
        +	ktri = ri->d.ktri;
        +
        +	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
        +							keyid, issuer, sno);
        +	}
        +
        +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
        +	{
        +	if (ri->type != CMS_RECIPINFO_TRANS)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
        +			CMS_R_NOT_KEY_TRANSPORT);
        +		return -2;
        +		}
        +	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
        +	}
        +
        +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
        +	{
        +	if (ri->type != CMS_RECIPINFO_TRANS)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
        +			CMS_R_NOT_KEY_TRANSPORT);
        +		return 0;
        +		}
        +	ri->d.ktri->pkey = pkey;
        +	return 1;
        +	}
        +
        +/* Encrypt content key in key transport recipient info */
        +
        +static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
        +					CMS_RecipientInfo *ri)
        +	{
        +	CMS_KeyTransRecipientInfo *ktri;
        +	CMS_EncryptedContentInfo *ec;
        +	EVP_PKEY_CTX *pctx = NULL;
        +	unsigned char *ek = NULL;
        +	size_t eklen;
        +
        +	int ret = 0;
        +
        +	if (ri->type != CMS_RECIPINFO_TRANS)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
        +			CMS_R_NOT_KEY_TRANSPORT);
        +		return 0;
        +		}
        +	ktri = ri->d.ktri;
        +	ec = cms->d.envelopedData->encryptedContentInfo;
        +
        +	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
        +	if (!pctx)
        +		return 0;
        +
        +	if (EVP_PKEY_encrypt_init(pctx) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
        +				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
        +		goto err;
        +
        +	ek = OPENSSL_malloc(eklen);
        +
        +	if (ek == NULL)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
        +							ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
        +		goto err;
        +
        +	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
        +	ek = NULL;
        +
        +	ret = 1;
        +
        +	err:
        +	if (pctx)
        +		EVP_PKEY_CTX_free(pctx);
        +	if (ek)
        +		OPENSSL_free(ek);
        +	return ret;
        +
        +	}
        +
        +/* Decrypt content key from KTRI */
        +
        +static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
        +							CMS_RecipientInfo *ri)
        +	{
        +	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
        +	EVP_PKEY_CTX *pctx = NULL;
        +	unsigned char *ek = NULL;
        +	size_t eklen;
        +	int ret = 0;
        +	CMS_EncryptedContentInfo *ec;
        +	ec = cms->d.envelopedData->encryptedContentInfo;
        +
        +	if (ktri->pkey == NULL)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
        +			CMS_R_NO_PRIVATE_KEY);
        +		return 0;
        +		}
        +
        +	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
        +	if (!pctx)
        +		return 0;
        +
        +	if (EVP_PKEY_decrypt_init(pctx) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
        +				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
        +				ktri->encryptedKey->data,
        +				ktri->encryptedKey->length) <= 0)
        +		goto err;
        +
        +	ek = OPENSSL_malloc(eklen);
        +
        +	if (ek == NULL)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
        +							ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
        +				ktri->encryptedKey->data,
        +				ktri->encryptedKey->length) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +
        +	if (ec->key)
        +		{
        +		OPENSSL_cleanse(ec->key, ec->keylen);
        +		OPENSSL_free(ec->key);
        +		}
        +
        +	ec->key = ek;
        +	ec->keylen = eklen;
        +
        +	err:
        +	if (pctx)
        +		EVP_PKEY_CTX_free(pctx);
        +	if (!ret && ek)
        +		OPENSSL_free(ek);
        +
        +	return ret;
        +	}
        +
        +/* Key Encrypted Key (KEK) RecipientInfo routines */
        +
        +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
        +					const unsigned char *id, size_t idlen)
        +	{
        +	ASN1_OCTET_STRING tmp_os;
        +	CMS_KEKRecipientInfo *kekri;
        +	if (ri->type != CMS_RECIPINFO_KEK)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
        +		return -2;
        +		}
        +	kekri = ri->d.kekri;
        +	tmp_os.type = V_ASN1_OCTET_STRING;
        +	tmp_os.flags = 0;
        +	tmp_os.data = (unsigned char *)id;
        +	tmp_os.length = (int)idlen;
        +	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
        +	}
        +
        +/* For now hard code AES key wrap info */
        +
        +static size_t aes_wrap_keylen(int nid)
        +	{
        +	switch (nid)
        +		{
        +		case NID_id_aes128_wrap:
        +		return 16;
        +
        +		case NID_id_aes192_wrap:
        +		return  24;
        +
        +		case NID_id_aes256_wrap:
        +		return  32;
        +
        +		default:
        +		return 0;
        +		}
        +	}
        +
        +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
        +					unsigned char *key, size_t keylen,
        +					unsigned char *id, size_t idlen,
        +					ASN1_GENERALIZEDTIME *date,
        +					ASN1_OBJECT *otherTypeId,
        +					ASN1_TYPE *otherType)
        +	{
        +	CMS_RecipientInfo *ri = NULL;
        +	CMS_EnvelopedData *env;
        +	CMS_KEKRecipientInfo *kekri;
        +	env = cms_get0_enveloped(cms);
        +	if (!env)
        +		goto err;
        +
        +	if (nid == NID_undef)
        +		{
        +		switch (keylen)
        +			{
        +			case 16:
        +			nid = NID_id_aes128_wrap;
        +			break;
        +
        +			case  24:
        +			nid = NID_id_aes192_wrap;
        +			break;
        +
        +			case  32:
        +			nid = NID_id_aes256_wrap;
        +			break;
        +
        +			default:
        +			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
        +						CMS_R_INVALID_KEY_LENGTH);
        +			goto err;
        +			}
        +
        +		}
        +	else
        +		{
        +
        +		size_t exp_keylen = aes_wrap_keylen(nid);
        +
        +		if (!exp_keylen)
        +			{
        +			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
        +					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
        +			goto err;
        +			}
        +
        +		if (keylen != exp_keylen)
        +			{
        +			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
        +					CMS_R_INVALID_KEY_LENGTH);
        +			goto err;
        +			}
        +
        +		}
        +
        +	/* Initialize recipient info */
        +	ri = M_ASN1_new_of(CMS_RecipientInfo);
        +	if (!ri)
        +		goto merr;
        +
        +	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
        +	if (!ri->d.kekri)
        +		goto merr;
        +	ri->type = CMS_RECIPINFO_KEK;
        +
        +	kekri = ri->d.kekri;
        +
        +	if (otherTypeId)
        +		{
        +		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
        +		if (kekri->kekid->other == NULL)
        +			goto merr;
        +		}
        +
        +	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
        +		goto merr;
        +
        +
        +	/* After this point no calls can fail */
        +
        +	kekri->version = 4;
        +
        +	kekri->key = key;
        +	kekri->keylen = keylen;
        +
        +	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
        +
        +	kekri->kekid->date = date;
        +
        +	if (kekri->kekid->other)
        +		{
        +		kekri->kekid->other->keyAttrId = otherTypeId;
        +		kekri->kekid->other->keyAttr = otherType;
        +		}
        +
        +	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
        +				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
        +
        +	return ri;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
        +	err:
        +	if (ri)
        +		M_ASN1_free_of(ri, CMS_RecipientInfo);
        +	return NULL;
        +
        +	}
        +
        +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
        +					X509_ALGOR **palg,
        +					ASN1_OCTET_STRING **pid,
        +					ASN1_GENERALIZEDTIME **pdate,
        +					ASN1_OBJECT **potherid,
        +					ASN1_TYPE **pothertype)
        +	{
        +	CMS_KEKIdentifier *rkid;
        +	if (ri->type != CMS_RECIPINFO_KEK)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
        +		return 0;
        +		}
        +	rkid =  ri->d.kekri->kekid;
        +	if (palg)
        +		*palg = ri->d.kekri->keyEncryptionAlgorithm;
        +	if (pid)
        +		*pid = rkid->keyIdentifier;
        +	if (pdate)
        +		*pdate = rkid->date;
        +	if (potherid)
        +		{
        +		if (rkid->other)
        +			*potherid = rkid->other->keyAttrId;
        +		else
        +			*potherid = NULL;
        +		}
        +	if (pothertype)
        +		{
        +		if (rkid->other)
        +			*pothertype = rkid->other->keyAttr;
        +		else
        +			*pothertype = NULL;
        +		}
        +	return 1;
        +	}
        +
        +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
        +				unsigned char *key, size_t keylen)
        +	{
        +	CMS_KEKRecipientInfo *kekri;
        +	if (ri->type != CMS_RECIPINFO_KEK)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
        +		return 0;
        +		}
        +
        +	kekri = ri->d.kekri;
        +	kekri->key = key;
        +	kekri->keylen = keylen;
        +	return 1;
        +	}
        +
        +
        +/* Encrypt content key in KEK recipient info */
        +
        +static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
        +					CMS_RecipientInfo *ri)
        +	{
        +	CMS_EncryptedContentInfo *ec;
        +	CMS_KEKRecipientInfo *kekri;
        +	AES_KEY actx;
        +	unsigned char *wkey = NULL;
        +	int wkeylen;
        +	int r = 0;
        +
        +	ec = cms->d.envelopedData->encryptedContentInfo;
        +
        +	kekri = ri->d.kekri;
        +
        +	if (!kekri->key)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
        +		return 0;
        +		}
        +
        +	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
        +		{ 
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
        +						CMS_R_ERROR_SETTING_KEY);
        +		goto err;
        +		}
        +
        +	wkey = OPENSSL_malloc(ec->keylen + 8);
        +
        +	if (!wkey)
        +		{ 
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
        +						ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
        +
        +	if (wkeylen <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
        +		goto err;
        +		}
        +
        +	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
        +
        +	r = 1;
        +
        +	err:
        +
        +	if (!r && wkey)
        +		OPENSSL_free(wkey);
        +	OPENSSL_cleanse(&actx, sizeof(actx));
        +
        +	return r;
        +
        +	}
        +
        +/* Decrypt content key in KEK recipient info */
        +
        +static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
        +					CMS_RecipientInfo *ri)
        +	{
        +	CMS_EncryptedContentInfo *ec;
        +	CMS_KEKRecipientInfo *kekri;
        +	AES_KEY actx;
        +	unsigned char *ukey = NULL;
        +	int ukeylen;
        +	int r = 0, wrap_nid;
        +
        +	ec = cms->d.envelopedData->encryptedContentInfo;
        +
        +	kekri = ri->d.kekri;
        +
        +	if (!kekri->key)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
        +		return 0;
        +		}
        +
        +	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
        +	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
        +			CMS_R_INVALID_KEY_LENGTH);
        +		return 0;
        +		}
        +
        +	/* If encrypted key length is invalid don't bother */
        +
        +	if (kekri->encryptedKey->length < 16)
        +		{ 
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
        +					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
        +		goto err;
        +		}
        +
        +	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
        +		{ 
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
        +						CMS_R_ERROR_SETTING_KEY);
        +		goto err;
        +		}
        +
        +	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
        +
        +	if (!ukey)
        +		{ 
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
        +						ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
        +					kekri->encryptedKey->data,
        +					kekri->encryptedKey->length);
        +
        +	if (ukeylen <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
        +							CMS_R_UNWRAP_ERROR);
        +		goto err;
        +		}
        +
        +	ec->key = ukey;
        +	ec->keylen = ukeylen;
        +
        +	r = 1;
        +
        +	err:
        +
        +	if (!r && ukey)
        +		OPENSSL_free(ukey);
        +	OPENSSL_cleanse(&actx, sizeof(actx));
        +
        +	return r;
        +
        +	}
        +
        +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
        +	{
        +	switch(ri->type)
        +		{
        +		case CMS_RECIPINFO_TRANS:
        +		return cms_RecipientInfo_ktri_decrypt(cms, ri);
        +
        +		case CMS_RECIPINFO_KEK:
        +		return cms_RecipientInfo_kekri_decrypt(cms, ri);
        +
        +		case CMS_RECIPINFO_PASS:
        +		return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
        +
        +		default:
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
        +			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
        +		return 0;
        +		}
        +	}
        +
        +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
        +	{
        +	CMS_EncryptedContentInfo *ec;
        +	STACK_OF(CMS_RecipientInfo) *rinfos;
        +	CMS_RecipientInfo *ri;
        +	int i, r, ok = 0;
        +	BIO *ret;
        +
        +	/* Get BIO first to set up key */
        +
        +	ec = cms->d.envelopedData->encryptedContentInfo;
        +	ret = cms_EncryptedContent_init_bio(ec);
        +
        +	/* If error or no cipher end of processing */
        +
        +	if (!ret || !ec->cipher)
        +		return ret;
        +
        +	/* Now encrypt content key according to each RecipientInfo type */
        +
        +	rinfos = cms->d.envelopedData->recipientInfos;
        +
        +	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
        +		{
        +		ri = sk_CMS_RecipientInfo_value(rinfos, i);
        +
        +		switch (ri->type)
        +			{
        +			case CMS_RECIPINFO_TRANS:
        +			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
        +			break;
        +
        +			case CMS_RECIPINFO_KEK:
        +			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
        +			break;
        +
        +			case CMS_RECIPINFO_PASS:
        +			r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
        +			break;
        +
        +			default:
        +			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
        +				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
        +			goto err;
        +			}
        +
        +		if (r <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
        +				CMS_R_ERROR_SETTING_RECIPIENTINFO);
        +			goto err;
        +			}
        +		}
        +
        +	ok = 1;
        +
        +	err:
        +	ec->cipher = NULL;
        +	if (ec->key)
        +		{
        +		OPENSSL_cleanse(ec->key, ec->keylen);
        +		OPENSSL_free(ec->key);
        +		ec->key = NULL;
        +		ec->keylen = 0;
        +		}
        +	if (ok)
        +		return ret;
        +	BIO_free(ret);
        +	return NULL;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_err.c b/vendor/openssl/openssl/crypto/cms/cms_err.c
        new file mode 100644
        index 000000000..8330ead7e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_err.c
        @@ -0,0 +1,245 @@
        +/* crypto/cms/cms_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2009 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
        +
        +static ERR_STRING_DATA CMS_str_functs[]=
        +	{
        +{ERR_FUNC(CMS_F_CHECK_CONTENT),	"CHECK_CONTENT"},
        +{ERR_FUNC(CMS_F_CMS_ADD0_CERT),	"CMS_add0_cert"},
        +{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY),	"CMS_add0_recipient_key"},
        +{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD),	"CMS_add0_recipient_password"},
        +{ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST),	"CMS_add1_ReceiptRequest"},
        +{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),	"CMS_add1_recipient_cert"},
        +{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),	"CMS_add1_signer"},
        +{ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME),	"CMS_ADD1_SIGNINGTIME"},
        +{ERR_FUNC(CMS_F_CMS_COMPRESS),	"CMS_compress"},
        +{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE),	"cms_CompressedData_create"},
        +{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),	"cms_CompressedData_init_bio"},
        +{ERR_FUNC(CMS_F_CMS_COPY_CONTENT),	"CMS_COPY_CONTENT"},
        +{ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST),	"CMS_COPY_MESSAGEDIGEST"},
        +{ERR_FUNC(CMS_F_CMS_DATA),	"CMS_data"},
        +{ERR_FUNC(CMS_F_CMS_DATAFINAL),	"CMS_dataFinal"},
        +{ERR_FUNC(CMS_F_CMS_DATAINIT),	"CMS_dataInit"},
        +{ERR_FUNC(CMS_F_CMS_DECRYPT),	"CMS_decrypt"},
        +{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY),	"CMS_decrypt_set1_key"},
        +{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD),	"CMS_decrypt_set1_password"},
        +{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY),	"CMS_decrypt_set1_pkey"},
        +{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),	"cms_DigestAlgorithm_find_ctx"},
        +{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"cms_DigestAlgorithm_init_bio"},
        +{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL),	"cms_DigestedData_do_final"},
        +{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY),	"CMS_digest_verify"},
        +{ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT),	"cms_encode_Receipt"},
        +{ERR_FUNC(CMS_F_CMS_ENCRYPT),	"CMS_encrypt"},
        +{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),	"cms_EncryptedContent_init_bio"},
        +{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT),	"CMS_EncryptedData_decrypt"},
        +{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT),	"CMS_EncryptedData_encrypt"},
        +{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),	"CMS_EncryptedData_set1_key"},
        +{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE),	"CMS_EnvelopedData_create"},
        +{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),	"cms_EnvelopedData_init_bio"},
        +{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT),	"CMS_ENVELOPED_DATA_INIT"},
        +{ERR_FUNC(CMS_F_CMS_FINAL),	"CMS_final"},
        +{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),	"CMS_GET0_CERTIFICATE_CHOICES"},
        +{ERR_FUNC(CMS_F_CMS_GET0_CONTENT),	"CMS_get0_content"},
        +{ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE),	"CMS_GET0_ECONTENT_TYPE"},
        +{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"cms_get0_enveloped"},
        +{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"},
        +{ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"},
        +{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"cms_msgSigDigest_add1"},
        +{ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),	"CMS_ReceiptRequest_create0"},
        +{ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY),	"cms_Receipt_verify"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),	"CMS_RecipientInfo_decrypt"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),	"CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),	"CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),	"CMS_RecipientInfo_kekri_get0_id"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),	"CMS_RecipientInfo_kekri_id_cmp"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),	"CMS_RecipientInfo_ktri_cert_cmp"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),	"CMS_RECIPIENTINFO_KTRI_DECRYPT"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),	"CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),	"CMS_RecipientInfo_ktri_get0_algs"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),	"CMS_RecipientInfo_ktri_get0_signer_id"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT),	"cms_RecipientInfo_pwri_crypt"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),	"CMS_RecipientInfo_set0_key"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD),	"CMS_RecipientInfo_set0_password"},
        +{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),	"CMS_RecipientInfo_set0_pkey"},
        +{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),	"cms_set1_SignerIdentifier"},
        +{ERR_FUNC(CMS_F_CMS_SET_DETACHED),	"CMS_set_detached"},
        +{ERR_FUNC(CMS_F_CMS_SIGN),	"CMS_sign"},
        +{ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT),	"CMS_SIGNED_DATA_INIT"},
        +{ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),	"CMS_SIGNERINFO_CONTENT_SIGN"},
        +{ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN),	"CMS_SignerInfo_sign"},
        +{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY),	"CMS_SignerInfo_verify"},
        +{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),	"CMS_SIGNERINFO_VERIFY_CERT"},
        +{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),	"CMS_SignerInfo_verify_content"},
        +{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT),	"CMS_sign_receipt"},
        +{ERR_FUNC(CMS_F_CMS_STREAM),	"CMS_stream"},
        +{ERR_FUNC(CMS_F_CMS_UNCOMPRESS),	"CMS_uncompress"},
        +{ERR_FUNC(CMS_F_CMS_VERIFY),	"CMS_verify"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CMS_str_reasons[]=
        +	{
        +{ERR_REASON(CMS_R_ADD_SIGNER_ERROR)      ,"add signer error"},
        +{ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),"certificate already present"},
        +{ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID),"certificate has no keyid"},
        +{ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
        +{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
        +{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
        +{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR)   ,"cms datafinal error"},
        +{ERR_REASON(CMS_R_CMS_LIB)               ,"cms lib"},
        +{ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"},
        +{ERR_REASON(CMS_R_CONTENT_NOT_FOUND)     ,"content not found"},
        +{ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"},
        +{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
        +{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
        +{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"},
        +{ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR)  ,"content verify error"},
        +{ERR_REASON(CMS_R_CTRL_ERROR)            ,"ctrl error"},
        +{ERR_REASON(CMS_R_CTRL_FAILURE)          ,"ctrl failure"},
        +{ERR_REASON(CMS_R_DECRYPT_ERROR)         ,"decrypt error"},
        +{ERR_REASON(CMS_R_DIGEST_ERROR)          ,"digest error"},
        +{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
        +{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
        +{ERR_REASON(CMS_R_ERROR_SETTING_KEY)     ,"error setting key"},
        +{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
        +{ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"},
        +{ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),"invalid key encryption parameter"},
        +{ERR_REASON(CMS_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
        +{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR)     ,"md bio init error"},
        +{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
        +{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"},
        +{ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR)    ,"msgsigdigest error"},
        +{ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"},
        +{ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"},
        +{ERR_REASON(CMS_R_NEED_ONE_SIGNER)       ,"need one signer"},
        +{ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT)  ,"not a signed receipt"},
        +{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA)    ,"not encrypted data"},
        +{ERR_REASON(CMS_R_NOT_KEK)               ,"not kek"},
        +{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT)     ,"not key transport"},
        +{ERR_REASON(CMS_R_NOT_PWRI)              ,"not pwri"},
        +{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
        +{ERR_REASON(CMS_R_NO_CIPHER)             ,"no cipher"},
        +{ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"},
        +{ERR_REASON(CMS_R_NO_CONTENT_TYPE)       ,"no content type"},
        +{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
        +{ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
        +{ERR_REASON(CMS_R_NO_KEY)                ,"no key"},
        +{ERR_REASON(CMS_R_NO_KEY_OR_CERT)        ,"no key or cert"},
        +{ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
        +{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
        +{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
        +{ERR_REASON(CMS_R_NO_MSGSIGDIGEST)       ,"no msgsigdigest"},
        +{ERR_REASON(CMS_R_NO_PASSWORD)           ,"no password"},
        +{ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"},
        +{ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"},
        +{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST)    ,"no receipt request"},
        +{ERR_REASON(CMS_R_NO_SIGNERS)            ,"no signers"},
        +{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
        +{ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR)  ,"receipt decode error"},
        +{ERR_REASON(CMS_R_RECIPIENT_ERROR)       ,"recipient error"},
        +{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
        +{ERR_REASON(CMS_R_SIGNFINAL_ERROR)       ,"signfinal error"},
        +{ERR_REASON(CMS_R_SMIME_TEXT_ERROR)      ,"smime text error"},
        +{ERR_REASON(CMS_R_STORE_INIT_ERROR)      ,"store init error"},
        +{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
        +{ERR_REASON(CMS_R_TYPE_NOT_DATA)         ,"type not data"},
        +{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
        +{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
        +{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
        +{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
        +{ERR_REASON(CMS_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
        +{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
        +{ERR_REASON(CMS_R_UNKNOWN_ID)            ,"unknown id"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),"unsupported key encryption algorithm"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
        +{ERR_REASON(CMS_R_UNSUPPORTED_TYPE)      ,"unsupported type"},
        +{ERR_REASON(CMS_R_UNWRAP_ERROR)          ,"unwrap error"},
        +{ERR_REASON(CMS_R_UNWRAP_FAILURE)        ,"unwrap failure"},
        +{ERR_REASON(CMS_R_VERIFICATION_FAILURE)  ,"verification failure"},
        +{ERR_REASON(CMS_R_WRAP_ERROR)            ,"wrap error"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_CMS_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(CMS_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,CMS_str_functs);
        +		ERR_load_strings(0,CMS_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_ess.c b/vendor/openssl/openssl/crypto/cms/cms_ess.c
        new file mode 100644
        index 000000000..90c0b82fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_ess.c
        @@ -0,0 +1,420 @@
        +/* crypto/cms/cms_ess.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include "cms_lcl.h"
        +
        +DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
        +DECLARE_ASN1_ITEM(CMS_Receipt)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
        +
        +/* ESS services: for now just Signed Receipt related */
        +
        +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
        +	{
        +	ASN1_STRING *str;
        +	CMS_ReceiptRequest *rr = NULL;
        +	if (prr)
        +		*prr = NULL;
        +	str = CMS_signed_get0_data_by_OBJ(si,
        +				OBJ_nid2obj(NID_id_smime_aa_receiptRequest),
        +					-3, V_ASN1_SEQUENCE);
        +	if (!str)
        +		return 0;
        +
        +	rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
        +	if (!rr)
        +		return -1;
        +	if (prr)
        +		*prr = rr;
        +	else
        +		CMS_ReceiptRequest_free(rr);
        +	return 1;
        +	}
        +
        +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
        +				int allorfirst,
        +				STACK_OF(GENERAL_NAMES) *receiptList,
        +				STACK_OF(GENERAL_NAMES) *receiptsTo)
        +	{
        +	CMS_ReceiptRequest *rr = NULL;
        +
        +	rr = CMS_ReceiptRequest_new();
        +	if (!rr)
        +		goto merr;
        +	if (id)
        +		ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
        +	else
        +		{
        +		if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
        +			goto merr;
        +		if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) 
        +					<= 0)
        +			goto err;
        +		}
        +
        +	sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
        +	rr->receiptsTo = receiptsTo;
        +
        +	if (receiptList)
        +		{
        +		rr->receiptsFrom->type = 1;
        +		rr->receiptsFrom->d.receiptList = receiptList;
        +		}
        +	else
        +		{
        +		rr->receiptsFrom->type = 0;
        +		rr->receiptsFrom->d.allOrFirstTier = allorfirst;
        +		}
        +
        +	return rr;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
        +
        +	err:
        +	if (rr)
        +		CMS_ReceiptRequest_free(rr);
        +
        +	return NULL;
        +	
        +	}
        +
        +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
        +	{
        +	unsigned char *rrder = NULL;
        +	int rrderlen, r = 0;
        +
        +	rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
        +	if (rrderlen < 0)
        +		goto merr;
        +
        +	if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
        +					V_ASN1_SEQUENCE, rrder, rrderlen))
        +		goto merr;
        +
        +	r = 1;
        +
        +	merr:
        +	if (!r)
        +		CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
        +
        +	if (rrder)
        +		OPENSSL_free(rrder);
        +
        +	return r;
        +	
        +	}
        +
        +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
        +					ASN1_STRING **pcid,
        +					int *pallorfirst,
        +					STACK_OF(GENERAL_NAMES) **plist,
        +					STACK_OF(GENERAL_NAMES) **prto)
        +	{
        +	if (pcid)
        +		*pcid = rr->signedContentIdentifier;
        +	if (rr->receiptsFrom->type == 0)
        +		{
        +		if (pallorfirst)
        +			*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
        +		if (plist)
        +			*plist = NULL;
        +		}
        +	else
        +		{
        +		if (pallorfirst)
        +			*pallorfirst = -1;
        +		if (plist)
        +			*plist = rr->receiptsFrom->d.receiptList;
        +		}
        +	if (prto)
        +		*prto = rr->receiptsTo;
        +	}
        +
        +/* Digest a SignerInfo structure for msgSigDigest attribute processing */
        +
        +static int cms_msgSigDigest(CMS_SignerInfo *si,
        +				unsigned char *dig, unsigned int *diglen)
        +	{
        +	const EVP_MD *md;
        +	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
        +	if (md == NULL)
        +		return 0;
        +	if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
        +						si->signedAttrs, dig, diglen))
        +		return 0;
        +	return 1;
        +	}
        +
        +/* Add a msgSigDigest attribute to a SignerInfo */
        +
        +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
        +	{
        +	unsigned char dig[EVP_MAX_MD_SIZE];
        +	unsigned int diglen;
        +	if (!cms_msgSigDigest(src, dig, &diglen))
        +		{
        +		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
        +		return 0;
        +		}
        +	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
        +					V_ASN1_OCTET_STRING, dig, diglen))
        +		{
        +		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* Verify signed receipt after it has already passed normal CMS verify */
        +
        +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
        +	{
        +	int r = 0, i;
        +	CMS_ReceiptRequest *rr = NULL;
        +	CMS_Receipt *rct = NULL;
        +	STACK_OF(CMS_SignerInfo) *sis, *osis;
        +	CMS_SignerInfo *si, *osi = NULL;
        +	ASN1_OCTET_STRING *msig, **pcont;
        +	ASN1_OBJECT *octype;
        +	unsigned char dig[EVP_MAX_MD_SIZE];
        +	unsigned int diglen;
        +
        +	/* Get SignerInfos, also checks SignedData content type */
        +	osis = CMS_get0_SignerInfos(req_cms);
        +	sis = CMS_get0_SignerInfos(cms);
        +	if (!osis || !sis)
        +		goto err;
        +
        +	if (sk_CMS_SignerInfo_num(sis) != 1)
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
        +		goto err;
        +		}
        +
        +	/* Check receipt content type */
        +	if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
        +		goto err;
        +		}
        +
        +	/* Extract and decode receipt content */
        +	pcont = CMS_get0_content(cms);
        +	if (!pcont || !*pcont)
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
        +		goto err;
        +		}
        +
        +	rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
        +
        +	if (!rct)	
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	/* Locate original request */
        +
        +	for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
        +		{
        +		osi = sk_CMS_SignerInfo_value(osis, i);
        +		if (!ASN1_STRING_cmp(osi->signature,
        +					rct->originatorSignatureValue))
        +			break;
        +		}
        +
        +	if (i == sk_CMS_SignerInfo_num(osis))
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
        +		goto err;
        +		}
        +
        +	si = sk_CMS_SignerInfo_value(sis, 0);
        +
        +	/* Get msgSigDigest value and compare */
        +
        +	msig = CMS_signed_get0_data_by_OBJ(si,
        +				OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
        +					-3, V_ASN1_OCTET_STRING);
        +
        +	if (!msig)
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
        +		goto err;
        +		}
        +
        +	if (!cms_msgSigDigest(osi, dig, &diglen))
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
        +		goto err;
        +		}
        +
        +	if (diglen != (unsigned int)msig->length)
        +			{
        +			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
        +				CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
        +			goto err;
        +			}
        +
        +	if (memcmp(dig, msig->data, diglen))
        +			{
        +			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
        +				CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
        +			goto err;
        +			}
        +
        +	/* Compare content types */
        +
        +	octype = CMS_signed_get0_data_by_OBJ(osi,
        +				OBJ_nid2obj(NID_pkcs9_contentType),
        +					-3, V_ASN1_OBJECT);
        +	if (!octype)
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
        +		goto err;
        +		}
        +
        +	/* Compare details in receipt request */
        +
        +	if (OBJ_cmp(octype, rct->contentType))
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
        +		goto err;
        +		}
        +
        +	/* Get original receipt request details */
        +
        +	if (CMS_get1_ReceiptRequest(osi, &rr) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
        +		goto err;
        +		}
        +
        +	if (ASN1_STRING_cmp(rr->signedContentIdentifier,
        +					rct->signedContentIdentifier))
        +		{
        +		CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
        +					CMS_R_CONTENTIDENTIFIER_MISMATCH);
        +		goto err;
        +		}
        +
        +	r = 1;
        +
        +	err:
        +	if (rr)
        +		CMS_ReceiptRequest_free(rr);
        +	if (rct)
        +		M_ASN1_free_of(rct, CMS_Receipt);
        +
        +	return r;
        +
        +	}
        +
        +/* Encode a Receipt into an OCTET STRING read for including into content of
        + * a SignedData ContentInfo.
        + */
        +
        +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
        +	{
        +	CMS_Receipt rct;
        +	CMS_ReceiptRequest *rr = NULL;
        +	ASN1_OBJECT *ctype;
        +	ASN1_OCTET_STRING *os = NULL;
        +
        +	/* Get original receipt request */
        +
        +	/* Get original receipt request details */
        +
        +	if (CMS_get1_ReceiptRequest(si, &rr) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
        +		goto err;
        +		}
        +
        +	/* Get original content type */
        +
        +	ctype = CMS_signed_get0_data_by_OBJ(si,
        +				OBJ_nid2obj(NID_pkcs9_contentType),
        +					-3, V_ASN1_OBJECT);
        +	if (!ctype)
        +		{
        +		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
        +		goto err;
        +		}
        +
        +	rct.version = 1;
        +	rct.contentType = ctype;
        +	rct.signedContentIdentifier = rr->signedContentIdentifier;
        +	rct.originatorSignatureValue = si->signature;
        +
        +	os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
        +
        +	err:
        +	if (rr)
        +		CMS_ReceiptRequest_free(rr);
        +
        +	return os;
        +
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_io.c b/vendor/openssl/openssl/crypto/cms/cms_io.c
        new file mode 100644
        index 000000000..1cb0264cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_io.c
        @@ -0,0 +1,133 @@
        +/* crypto/cms/cms_io.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include "cms.h"
        +#include "cms_lcl.h"
        +
        +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
        +	{
        +	ASN1_OCTET_STRING **pos;
        +	pos = CMS_get0_content(cms);
        +	if (!pos)
        +		return 0;
        +	if (!*pos)
        +		*pos = ASN1_OCTET_STRING_new();
        +	if (*pos)
        +		{
        +		(*pos)->flags |= ASN1_STRING_FLAG_NDEF;
        +		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
        +		*boundary = &(*pos)->data;
        +		return 1;
        +		}
        +	CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
        +	}
        +
        +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
        +	}
        +
        +IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
        +
        +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) 
        +	{
        +	return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
        +				ASN1_ITEM_rptr(CMS_ContentInfo));
        +	}
        +
        +/* CMS wrappers round generalised stream and MIME routines */
        +
        +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
        +	{
        +	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
        +					ASN1_ITEM_rptr(CMS_ContentInfo));
        +	}
        +
        +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
        +	{
        +	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags,
        +					"CMS",
        +					ASN1_ITEM_rptr(CMS_ContentInfo));
        +	}
        +
        +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
        +	{
        +	STACK_OF(X509_ALGOR) *mdalgs;
        +	int ctype_nid = OBJ_obj2nid(cms->contentType);
        +	int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
        +	if (ctype_nid == NID_pkcs7_signed)
        +		mdalgs = cms->d.signedData->digestAlgorithms;
        +	else
        +		mdalgs = NULL;
        +
        +	return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
        +					ctype_nid, econt_nid, mdalgs,
        +					ASN1_ITEM_rptr(CMS_ContentInfo));	
        +	}
        +
        +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
        +	{
        +	return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
        +					ASN1_ITEM_rptr(CMS_ContentInfo));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_lcl.h b/vendor/openssl/openssl/crypto/cms/cms_lcl.h
        new file mode 100644
        index 000000000..a9f973015
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_lcl.h
        @@ -0,0 +1,473 @@
        +/* crypto/cms/cms_lcl.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#ifndef HEADER_CMS_LCL_H
        +#define HEADER_CMS_LCL_H
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +#include <openssl/x509.h>
        +
        +/* Cryptographic message syntax (CMS) structures: taken
        + * from RFC3852
        + */
        +
        +/* Forward references */
        +
        +typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
        +typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
        +typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
        +typedef struct CMS_SignedData_st CMS_SignedData;
        +typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
        +typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
        +typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
        +typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
        +typedef struct CMS_DigestedData_st CMS_DigestedData;
        +typedef struct CMS_EncryptedData_st CMS_EncryptedData;
        +typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
        +typedef struct CMS_CompressedData_st CMS_CompressedData;
        +typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
        +typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
        +typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
        +typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
        +typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
        +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
        +typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
        +typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier;
        +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
        +typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
        +typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
        +typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
        +typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
        +typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
        +
        +struct CMS_ContentInfo_st
        +	{
        +	ASN1_OBJECT *contentType;
        +	union	{
        +		ASN1_OCTET_STRING *data;
        +		CMS_SignedData *signedData;
        +		CMS_EnvelopedData *envelopedData;
        +		CMS_DigestedData *digestedData;
        +		CMS_EncryptedData *encryptedData;
        +		CMS_AuthenticatedData *authenticatedData;
        +		CMS_CompressedData *compressedData;
        +		ASN1_TYPE *other;
        +		/* Other types ... */
        +		void *otherData;
        +		} d;
        +	};
        +
        +struct CMS_SignedData_st
        +	{
        +	long version;
        +	STACK_OF(X509_ALGOR) *digestAlgorithms;
        +	CMS_EncapsulatedContentInfo *encapContentInfo;
        +	STACK_OF(CMS_CertificateChoices) *certificates;
        +	STACK_OF(CMS_RevocationInfoChoice) *crls;
        +	STACK_OF(CMS_SignerInfo) *signerInfos;
        +	};
        + 
        +struct CMS_EncapsulatedContentInfo_st
        +	{
        +	ASN1_OBJECT *eContentType;
        +	ASN1_OCTET_STRING *eContent;
        +	/* Set to 1 if incomplete structure only part set up */
        +	int partial;
        +	};
        +
        +struct CMS_SignerInfo_st
        +	{
        +	long version;
        +	CMS_SignerIdentifier *sid;
        +	X509_ALGOR *digestAlgorithm;
        +	STACK_OF(X509_ATTRIBUTE) *signedAttrs;
        +	X509_ALGOR *signatureAlgorithm;
        +	ASN1_OCTET_STRING *signature;
        +	STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
        +	/* Signing certificate and key */
        +	X509 *signer;
        +	EVP_PKEY *pkey;
        +	};
        +
        +struct CMS_SignerIdentifier_st
        +	{
        +	int type;
        +	union	{
        +		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
        +		ASN1_OCTET_STRING *subjectKeyIdentifier;
        +		} d;
        +	};
        +
        +struct CMS_EnvelopedData_st
        +	{
        +	long version;
        +	CMS_OriginatorInfo *originatorInfo;
        +	STACK_OF(CMS_RecipientInfo) *recipientInfos;
        +	CMS_EncryptedContentInfo *encryptedContentInfo;
        +	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
        +	};
        +
        +struct CMS_OriginatorInfo_st
        +	{
        +	STACK_OF(CMS_CertificateChoices) *certificates;
        +	STACK_OF(CMS_RevocationInfoChoice) *crls;
        +	};
        +
        +struct CMS_EncryptedContentInfo_st
        +	{
        +	ASN1_OBJECT *contentType;
        +	X509_ALGOR *contentEncryptionAlgorithm;
        +	ASN1_OCTET_STRING *encryptedContent;
        +	/* Content encryption algorithm and key */
        +	const EVP_CIPHER *cipher;
        +	unsigned char *key;
        +	size_t keylen;
        +	/* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
        +	int debug;
        +	};
        +
        +struct CMS_RecipientInfo_st
        +	{
        + 	int type;
        + 	union	{
        +  	 	CMS_KeyTransRecipientInfo *ktri;
        +   		CMS_KeyAgreeRecipientInfo *kari;
        +   		CMS_KEKRecipientInfo *kekri;
        +		CMS_PasswordRecipientInfo *pwri;
        +		CMS_OtherRecipientInfo *ori;
        +		} d;
        +	};
        +
        +typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
        +
        +struct CMS_KeyTransRecipientInfo_st
        +	{
        +	long version;
        +	CMS_RecipientIdentifier *rid;
        +	X509_ALGOR *keyEncryptionAlgorithm;
        +	ASN1_OCTET_STRING *encryptedKey;
        +	/* Recipient Key and cert */
        +	X509 *recip;
        +	EVP_PKEY *pkey;
        +	};
        +
        +struct CMS_KeyAgreeRecipientInfo_st
        +	{
        +	long version;
        +	CMS_OriginatorIdentifierOrKey *originator;
        +	ASN1_OCTET_STRING *ukm;
        + 	X509_ALGOR *keyEncryptionAlgorithm;
        +	STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
        +	};
        +
        +struct CMS_OriginatorIdentifierOrKey_st
        +	{
        +	int type;
        +	union	{
        +		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
        +		ASN1_OCTET_STRING *subjectKeyIdentifier;
        +		CMS_OriginatorPublicKey *originatorKey;
        +		} d;
        +	};
        +
        +struct CMS_OriginatorPublicKey_st
        +	{
        +	X509_ALGOR *algorithm;
        +	ASN1_BIT_STRING *publicKey;
        +	};
        +
        +struct CMS_RecipientEncryptedKey_st
        +	{
        + 	CMS_KeyAgreeRecipientIdentifier *rid;
        + 	ASN1_OCTET_STRING *encryptedKey;
        +	};
        +
        +struct CMS_KeyAgreeRecipientIdentifier_st
        +	{
        +	int type;
        +	union	{
        +		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
        +		CMS_RecipientKeyIdentifier *rKeyId;
        +		} d;
        +	};
        +
        +struct CMS_RecipientKeyIdentifier_st
        +	{
        + 	ASN1_OCTET_STRING *subjectKeyIdentifier;
        + 	ASN1_GENERALIZEDTIME *date;
        + 	CMS_OtherKeyAttribute *other;
        +	};
        +
        +struct CMS_KEKRecipientInfo_st
        +	{
        + 	long version;
        + 	CMS_KEKIdentifier *kekid;
        + 	X509_ALGOR *keyEncryptionAlgorithm;
        + 	ASN1_OCTET_STRING *encryptedKey;
        +	/* Extra info: symmetric key to use */
        +	unsigned char *key;
        +	size_t keylen;
        +	};
        +
        +struct CMS_KEKIdentifier_st
        +	{
        + 	ASN1_OCTET_STRING *keyIdentifier;
        + 	ASN1_GENERALIZEDTIME *date;
        + 	CMS_OtherKeyAttribute *other;
        +	};
        +
        +struct CMS_PasswordRecipientInfo_st
        +	{
        + 	long version;
        + 	X509_ALGOR *keyDerivationAlgorithm;
        + 	X509_ALGOR *keyEncryptionAlgorithm;
        + 	ASN1_OCTET_STRING *encryptedKey;
        +	/* Extra info: password to use */
        +	unsigned char *pass;
        +	size_t passlen;
        +	};
        +
        +struct CMS_OtherRecipientInfo_st
        +	{
        + 	ASN1_OBJECT *oriType;
        + 	ASN1_TYPE *oriValue;
        +	};
        +
        +struct CMS_DigestedData_st
        +	{
        +	long version;
        +	X509_ALGOR *digestAlgorithm;
        +	CMS_EncapsulatedContentInfo *encapContentInfo;
        +	ASN1_OCTET_STRING *digest;
        +	};
        +
        +struct CMS_EncryptedData_st
        +	{
        +	long version;
        +	CMS_EncryptedContentInfo *encryptedContentInfo;
        +	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
        +	};
        +
        +struct CMS_AuthenticatedData_st
        +	{
        +	long version;
        +	CMS_OriginatorInfo *originatorInfo;
        +	STACK_OF(CMS_RecipientInfo) *recipientInfos;
        +	X509_ALGOR *macAlgorithm;
        +	X509_ALGOR *digestAlgorithm;
        +	CMS_EncapsulatedContentInfo *encapContentInfo;
        +	STACK_OF(X509_ATTRIBUTE) *authAttrs;
        +	ASN1_OCTET_STRING *mac;
        +	STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
        +	};
        +
        +struct CMS_CompressedData_st
        +	{
        +	long version;
        +	X509_ALGOR *compressionAlgorithm;
        +	STACK_OF(CMS_RecipientInfo) *recipientInfos;
        +	CMS_EncapsulatedContentInfo *encapContentInfo;
        +	};
        +
        +struct CMS_RevocationInfoChoice_st
        +	{
        +	int type;
        +	union	{
        +		X509_CRL *crl;
        +		CMS_OtherRevocationInfoFormat *other;
        +		} d;
        +	};
        +
        +#define CMS_REVCHOICE_CRL		0
        +#define CMS_REVCHOICE_OTHER		1
        +
        +struct CMS_OtherRevocationInfoFormat_st
        +	{
        +	ASN1_OBJECT *otherRevInfoFormat;
        + 	ASN1_TYPE *otherRevInfo;
        +	};
        +
        +struct CMS_CertificateChoices
        +	{
        +	int type;
        +		union {
        +		X509 *certificate;
        +		ASN1_STRING *extendedCertificate;	/* Obsolete */
        +		ASN1_STRING *v1AttrCert;	/* Left encoded for now */
        +		ASN1_STRING *v2AttrCert;	/* Left encoded for now */
        +		CMS_OtherCertificateFormat *other;
        +		} d;
        +	};
        +
        +#define CMS_CERTCHOICE_CERT		0
        +#define CMS_CERTCHOICE_EXCERT		1
        +#define CMS_CERTCHOICE_V1ACERT		2
        +#define CMS_CERTCHOICE_V2ACERT		3
        +#define CMS_CERTCHOICE_OTHER		4
        +
        +struct CMS_OtherCertificateFormat_st
        +	{
        +	ASN1_OBJECT *otherCertFormat;
        + 	ASN1_TYPE *otherCert;
        +	};
        +
        +/* This is also defined in pkcs7.h but we duplicate it
        + * to allow the CMS code to be independent of PKCS#7
        + */
        +
        +struct CMS_IssuerAndSerialNumber_st
        +	{
        +	X509_NAME *issuer;
        +	ASN1_INTEGER *serialNumber;
        +	};
        +
        +struct CMS_OtherKeyAttribute_st
        +	{
        +	ASN1_OBJECT *keyAttrId;
        + 	ASN1_TYPE *keyAttr;
        +	};
        +
        +/* ESS structures */
        +
        +#ifdef HEADER_X509V3_H
        +
        +struct CMS_ReceiptRequest_st
        +	{
        +	ASN1_OCTET_STRING *signedContentIdentifier;
        +	CMS_ReceiptsFrom *receiptsFrom;
        +	STACK_OF(GENERAL_NAMES) *receiptsTo;
        +	};
        +
        +
        +struct CMS_ReceiptsFrom_st
        +	{
        +	int type;
        +	union
        +		{
        +		long allOrFirstTier;
        +		STACK_OF(GENERAL_NAMES) *receiptList;
        +		} d;
        +	};
        +#endif
        +
        +struct CMS_Receipt_st
        +	{
        +	long version;
        +	ASN1_OBJECT *contentType;
        +	ASN1_OCTET_STRING *signedContentIdentifier;
        +	ASN1_OCTET_STRING *originatorSignatureValue;
        +	};
        +
        +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
        +DECLARE_ASN1_ITEM(CMS_SignerInfo)
        +DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
        +DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
        +DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
        +DECLARE_ASN1_ITEM(CMS_RecipientInfo)
        +DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
        +DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
        +
        +#define CMS_SIGNERINFO_ISSUER_SERIAL	0
        +#define CMS_SIGNERINFO_KEYIDENTIFIER	1
        +
        +#define CMS_RECIPINFO_ISSUER_SERIAL	0
        +#define CMS_RECIPINFO_KEYIDENTIFIER	1
        +
        +BIO *cms_content_bio(CMS_ContentInfo *cms);
        +
        +CMS_ContentInfo *cms_Data_create(void);
        +
        +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
        +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
        +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
        +
        +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
        +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
        +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type);
        +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
        +					ASN1_OCTET_STRING **keyid,
        +					X509_NAME **issuer, ASN1_INTEGER **sno);
        +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
        +
        +CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
        +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
        +
        +void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
        +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
        +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
        +					X509_ALGOR *mdalg);
        +
        +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
        +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
        +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
        +				const EVP_CIPHER *cipher,
        +				const unsigned char *key, size_t keylen);
        +
        +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
        +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
        +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
        +
        +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
        +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
        +
        +/* PWRI routines */
        +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
        +							int en_de);
        +	
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_lib.c b/vendor/openssl/openssl/crypto/cms/cms_lib.c
        new file mode 100644
        index 000000000..b62d1bfac
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_lib.c
        @@ -0,0 +1,624 @@
        +/* crypto/cms/cms_lib.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/bio.h>
        +#include <openssl/asn1.h>
        +#include "cms.h"
        +#include "cms_lcl.h"
        +
        +IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
        +IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
        +
        +DECLARE_ASN1_ITEM(CMS_CertificateChoices)
        +DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
        +DECLARE_STACK_OF(CMS_CertificateChoices)
        +DECLARE_STACK_OF(CMS_RevocationInfoChoice)
        +
        +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
        +	{
        +	return cms->contentType;
        +	}
        +
        +CMS_ContentInfo *cms_Data_create(void)
        +	{
        +	CMS_ContentInfo *cms;
        +	cms = CMS_ContentInfo_new();
        +	if (cms)
        +		{
        +		cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
        +		/* Never detached */
        +		CMS_set_detached(cms, 0);
        +		}
        +	return cms;
        +	}
        +
        +BIO *cms_content_bio(CMS_ContentInfo *cms)
        +	{
        +	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
        +	if (!pos)
        +		return NULL;
        +	/* If content detached data goes nowhere: create NULL BIO */
        +	if (!*pos)
        +		return BIO_new(BIO_s_null());
        +	/* If content not detached and created return memory BIO
        +	 */
        +	if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
        +		return BIO_new(BIO_s_mem());
        +	/* Else content was read in: return read only BIO for it */
        +	return BIO_new_mem_buf((*pos)->data, (*pos)->length);
        +	}
        +
        +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
        +	{
        +	BIO *cmsbio, *cont;
        +	if (icont)
        +		cont = icont;
        +	else
        +		cont = cms_content_bio(cms);
        +	if (!cont)
        +		{
        +		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
        +		return NULL;
        +		}
        +	switch (OBJ_obj2nid(cms->contentType))
        +		{
        +
        +		case NID_pkcs7_data:
        +		return cont;
        +
        +		case NID_pkcs7_signed:
        +		cmsbio = cms_SignedData_init_bio(cms);
        +		break;
        +
        +		case NID_pkcs7_digest:
        +		cmsbio = cms_DigestedData_init_bio(cms);
        +		break;
        +#ifdef ZLIB
        +		case NID_id_smime_ct_compressedData:
        +		cmsbio = cms_CompressedData_init_bio(cms);
        +		break;
        +#endif
        +
        +		case NID_pkcs7_encrypted:
        +		cmsbio = cms_EncryptedData_init_bio(cms);
        +		break;
        +
        +		case NID_pkcs7_enveloped:
        +		cmsbio = cms_EnvelopedData_init_bio(cms);
        +		break;
        +
        +		default:
        +		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
        +		return NULL;
        +		}
        +
        +	if (cmsbio)
        +		return BIO_push(cmsbio, cont);
        +
        +	if (!icont)
        +		BIO_free(cont);
        +	return NULL;
        +
        +	}
        +
        +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
        +	{
        +	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
        +	if (!pos)
        +		return 0;
        +	/* If ebmedded content find memory BIO and set content */
        +	if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
        +		{
        +		BIO *mbio;
        +		unsigned char *cont;
        +		long contlen;
        +		mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
        +		if (!mbio)
        +			{
        +			CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
        +			return 0;
        +			}
        +		contlen = BIO_get_mem_data(mbio, &cont);
        +		/* Set bio as read only so its content can't be clobbered */
        +		BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
        +		BIO_set_mem_eof_return(mbio, 0);
        +		ASN1_STRING_set0(*pos, cont, contlen);
        +		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
        +		}
        +
        +	switch (OBJ_obj2nid(cms->contentType))
        +		{
        +
        +		case NID_pkcs7_data:
        +		case NID_pkcs7_enveloped:
        +		case NID_pkcs7_encrypted:
        +		case NID_id_smime_ct_compressedData:
        +		/* Nothing to do */
        +		return 1;
        +
        +		case NID_pkcs7_signed:
        +		return cms_SignedData_final(cms, cmsbio);
        +
        +		case NID_pkcs7_digest:
        +		return cms_DigestedData_do_final(cms, cmsbio, 0);
        +
        +		default:
        +		CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
        +		return 0;
        +		}
        +	}
        +
        +/* Return an OCTET STRING pointer to content. This allows it to
        + * be accessed or set later.
        + */
        +
        +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
        +	{
        +	switch (OBJ_obj2nid(cms->contentType))
        +		{
        +
        +		case NID_pkcs7_data:
        +		return &cms->d.data;
        +
        +		case NID_pkcs7_signed:
        +		return &cms->d.signedData->encapContentInfo->eContent;
        +
        +		case NID_pkcs7_enveloped:
        +		return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
        +
        +		case NID_pkcs7_digest:
        +		return &cms->d.digestedData->encapContentInfo->eContent;
        +
        +		case NID_pkcs7_encrypted:
        +		return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
        +
        +		case NID_id_smime_ct_authData:
        +		return &cms->d.authenticatedData->encapContentInfo->eContent;
        +
        +		case NID_id_smime_ct_compressedData:
        +		return &cms->d.compressedData->encapContentInfo->eContent;
        +
        +		default:
        +		if (cms->d.other->type == V_ASN1_OCTET_STRING)
        +			return &cms->d.other->value.octet_string;
        +		CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
        +		return NULL;
        +
        +		}
        +	}
        +
        +/* Return an ASN1_OBJECT pointer to content type. This allows it to
        + * be accessed or set later.
        + */
        +
        +static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
        +	{
        +	switch (OBJ_obj2nid(cms->contentType))
        +		{
        +
        +		case NID_pkcs7_signed:
        +		return &cms->d.signedData->encapContentInfo->eContentType;
        +
        +		case NID_pkcs7_enveloped:
        +		return &cms->d.envelopedData->encryptedContentInfo->contentType;
        +
        +		case NID_pkcs7_digest:
        +		return &cms->d.digestedData->encapContentInfo->eContentType;
        +
        +		case NID_pkcs7_encrypted:
        +		return &cms->d.encryptedData->encryptedContentInfo->contentType;
        +
        +		case NID_id_smime_ct_authData:
        +		return &cms->d.authenticatedData->encapContentInfo->eContentType;
        +
        +		case NID_id_smime_ct_compressedData:
        +		return &cms->d.compressedData->encapContentInfo->eContentType;
        +
        +		default:
        +		CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
        +					CMS_R_UNSUPPORTED_CONTENT_TYPE);
        +		return NULL;
        +
        +		}
        +	}
        +
        +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
        +	{
        +	ASN1_OBJECT **petype;
        +	petype = cms_get0_econtent_type(cms);
        +	if (petype)
        +		return *petype;
        +	return NULL;
        +	}
        +
        +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
        +	{
        +	ASN1_OBJECT **petype, *etype;
        +	petype = cms_get0_econtent_type(cms);
        +	if (!petype)
        +		return 0;
        +	if (!oid)
        +		return 1;
        +	etype = OBJ_dup(oid);
        +	if (!etype)
        +		return 0;
        +	ASN1_OBJECT_free(*petype);
        +	*petype = etype;
        +	return 1;
        +	}
        +
        +int CMS_is_detached(CMS_ContentInfo *cms)
        +	{
        +	ASN1_OCTET_STRING **pos;
        +	pos = CMS_get0_content(cms);
        +	if (!pos)
        +		return -1;
        +	if (*pos)
        +		return 0;
        +	return 1;
        +	}
        +
        +int CMS_set_detached(CMS_ContentInfo *cms, int detached)
        +	{
        +	ASN1_OCTET_STRING **pos;
        +	pos = CMS_get0_content(cms);
        +	if (!pos)
        +		return 0;
        +	if (detached)
        +		{
        +		if (*pos)
        +			{
        +			ASN1_OCTET_STRING_free(*pos);
        +			*pos = NULL;
        +			}
        +		return 1;
        +		}
        +	if (!*pos)
        +		*pos = ASN1_OCTET_STRING_new();
        +	if (*pos)
        +		{
        +		/* NB: special flag to show content is created and not
        +		 * read in.
        +		 */
        +		(*pos)->flags |= ASN1_STRING_FLAG_CONT;
        +		return 1;
        +		}
        +	CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
        +
        +void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
        +	{
        +	int param_type;
        +
        +	if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
        +		param_type = V_ASN1_UNDEF;
        +	else
        +		param_type = V_ASN1_NULL;
        +
        +	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
        +
        +	}
        +
        +/* Create a digest BIO from an X509_ALGOR structure */
        +
        +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
        +	{
        +	BIO *mdbio = NULL;
        +	ASN1_OBJECT *digestoid;
        +	const EVP_MD *digest;
        +	X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
        +	digest = EVP_get_digestbyobj(digestoid);
        +	if (!digest)
        +		{
        +		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
        +				CMS_R_UNKNOWN_DIGEST_ALGORIHM);
        +		goto err;	
        +		}
        +	mdbio = BIO_new(BIO_f_md());
        +	if (!mdbio || !BIO_set_md(mdbio, digest))
        +		{
        +		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
        +				CMS_R_MD_BIO_INIT_ERROR);
        +		goto err;	
        +		}
        +	return mdbio;
        +	err:
        +	if (mdbio)
        +		BIO_free(mdbio);
        +	return NULL;
        +	}
        +
        +/* Locate a message digest content from a BIO chain based on SignerInfo */
        +
        +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
        +					X509_ALGOR *mdalg)
        +	{
        +	int nid;
        +	ASN1_OBJECT *mdoid;
        +	X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
        +	nid = OBJ_obj2nid(mdoid);
        +	/* Look for digest type to match signature */
        +	for (;;)
        +		{
        +		EVP_MD_CTX *mtmp;
        +		chain = BIO_find_type(chain, BIO_TYPE_MD);
        +		if (chain == NULL)
        +			{
        +			CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
        +						CMS_R_NO_MATCHING_DIGEST);
        +			return 0;
        +			}
        +		BIO_get_md_ctx(chain, &mtmp);
        +		if (EVP_MD_CTX_type(mtmp) == nid
        +		/* Workaround for broken implementations that use signature
        +		 * algorithm  OID instead of digest.
        +		 */
        +			|| EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
        +			return EVP_MD_CTX_copy_ex(mctx, mtmp);
        +		chain = BIO_next(chain);
        +		}
        +	}
        +
        +static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
        +	{
        +	switch (OBJ_obj2nid(cms->contentType))
        +		{
        +
        +		case NID_pkcs7_signed:
        +		return &cms->d.signedData->certificates;
        +
        +		case NID_pkcs7_enveloped:
        +		return &cms->d.envelopedData->originatorInfo->certificates;
        +
        +		default:
        +		CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
        +					CMS_R_UNSUPPORTED_CONTENT_TYPE);
        +		return NULL;
        +
        +		}
        +	}
        +
        +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
        +	{
        +	STACK_OF(CMS_CertificateChoices) **pcerts;
        +	CMS_CertificateChoices *cch;
        +	pcerts = cms_get0_certificate_choices(cms);
        +	if (!pcerts)
        +		return NULL;
        +	if (!*pcerts)
        +		*pcerts = sk_CMS_CertificateChoices_new_null();
        +	if (!*pcerts)
        +		return NULL;
        +	cch = M_ASN1_new_of(CMS_CertificateChoices);
        +	if (!cch)
        +		return NULL;
        +	if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
        +		{
        +		M_ASN1_free_of(cch, CMS_CertificateChoices);
        +		return NULL;
        +		}
        +	return cch;
        +	}
        +
        +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
        +	{
        +	CMS_CertificateChoices *cch;
        +	STACK_OF(CMS_CertificateChoices) **pcerts;
        +	int i;
        +	pcerts = cms_get0_certificate_choices(cms);
        +	if (!pcerts)
        +		return 0;
        +	if (!pcerts)
        +		return 0;
        +	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
        +		{
        +		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
        +		if (cch->type == CMS_CERTCHOICE_CERT)
        +			{
        +			if (!X509_cmp(cch->d.certificate, cert))
        +				{
        +				CMSerr(CMS_F_CMS_ADD0_CERT, 
        +					CMS_R_CERTIFICATE_ALREADY_PRESENT);
        +				return 0;
        +				}
        +			}
        +		}
        +	cch = CMS_add0_CertificateChoices(cms);
        +	if (!cch)
        +		return 0;
        +	cch->type = CMS_CERTCHOICE_CERT;
        +	cch->d.certificate = cert;
        +	return 1;
        +	}
        +
        +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
        +	{
        +	int r;
        +	r = CMS_add0_cert(cms, cert);
        +	if (r > 0)
        +		CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
        +	return r;
        +	}
        +
        +static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
        +	{
        +	switch (OBJ_obj2nid(cms->contentType))
        +		{
        +
        +		case NID_pkcs7_signed:
        +		return &cms->d.signedData->crls;
        +
        +		case NID_pkcs7_enveloped:
        +		return &cms->d.envelopedData->originatorInfo->crls;
        +
        +		default:
        +		CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
        +					CMS_R_UNSUPPORTED_CONTENT_TYPE);
        +		return NULL;
        +
        +		}
        +	}
        +
        +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
        +	{
        +	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
        +	CMS_RevocationInfoChoice *rch;
        +	pcrls = cms_get0_revocation_choices(cms);
        +	if (!pcrls)
        +		return NULL;
        +	if (!*pcrls)
        +		*pcrls = sk_CMS_RevocationInfoChoice_new_null();
        +	if (!*pcrls)
        +		return NULL;
        +	rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
        +	if (!rch)
        +		return NULL;
        +	if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
        +		{
        +		M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
        +		return NULL;
        +		}
        +	return rch;
        +	}
        +
        +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
        +	{
        +	CMS_RevocationInfoChoice *rch;
        +	rch = CMS_add0_RevocationInfoChoice(cms);
        +	if (!rch)
        +		return 0;
        +	rch->type = CMS_REVCHOICE_CRL;
        +	rch->d.crl = crl;
        +	return 1;
        +	}
        +
        +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
        +	{
        +	int r;
        +	r = CMS_add0_crl(cms, crl);
        +	if (r > 0)
        +		CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
        +	return r;
        +	}
        +
        +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
        +	{
        +	STACK_OF(X509) *certs = NULL;
        +	CMS_CertificateChoices *cch;
        +	STACK_OF(CMS_CertificateChoices) **pcerts;
        +	int i;
        +	pcerts = cms_get0_certificate_choices(cms);
        +	if (!pcerts)
        +		return NULL;
        +	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
        +		{
        +		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
        +		if (cch->type == 0)
        +			{
        +			if (!certs)
        +				{
        +				certs = sk_X509_new_null();
        +				if (!certs)
        +					return NULL;
        +				}
        +			if (!sk_X509_push(certs, cch->d.certificate))
        +				{
        +				sk_X509_pop_free(certs, X509_free);
        +				return NULL;
        +				}
        +			CRYPTO_add(&cch->d.certificate->references,
        +						1, CRYPTO_LOCK_X509);
        +			}
        +		}
        +	return certs;
        +
        +	}
        +
        +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
        +	{
        +	STACK_OF(X509_CRL) *crls = NULL;
        +	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
        +	CMS_RevocationInfoChoice *rch;
        +	int i;
        +	pcrls = cms_get0_revocation_choices(cms);
        +	if (!pcrls)
        +		return NULL;
        +	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
        +		{
        +		rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
        +		if (rch->type == 0)
        +			{
        +			if (!crls)
        +				{
        +				crls = sk_X509_CRL_new_null();
        +				if (!crls)
        +					return NULL;
        +				}
        +			if (!sk_X509_CRL_push(crls, rch->d.crl))
        +				{
        +				sk_X509_CRL_pop_free(crls, X509_CRL_free);
        +				return NULL;
        +				}
        +			CRYPTO_add(&rch->d.crl->references,
        +						1, CRYPTO_LOCK_X509_CRL);
        +			}
        +		}
        +	return crls;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_pwri.c b/vendor/openssl/openssl/crypto/cms/cms_pwri.c
        new file mode 100644
        index 000000000..b79612a12
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_pwri.c
        @@ -0,0 +1,454 @@
        +/* crypto/cms/cms_pwri.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2009 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include <openssl/rand.h>
        +#include <openssl/aes.h>
        +#include "cms_lcl.h"
        +#include "asn1_locl.h"
        +
        +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 
        +				unsigned char *pass, ossl_ssize_t passlen)
        +	{
        +	CMS_PasswordRecipientInfo *pwri;
        +	if (ri->type != CMS_RECIPINFO_PASS)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
        +		return 0;
        +		}
        +
        +	pwri = ri->d.pwri;
        +	pwri->pass = pass;
        +	if (pass && passlen < 0)
        +		passlen = strlen((char *)pass);
        +	pwri->passlen = passlen;
        +	return 1;
        +	}
        +
        +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
        +					int iter, int wrap_nid, int pbe_nid,
        +					unsigned char *pass,
        +					ossl_ssize_t passlen,
        +					const EVP_CIPHER *kekciph)
        +	{
        +	CMS_RecipientInfo *ri = NULL;
        +	CMS_EnvelopedData *env;
        +	CMS_PasswordRecipientInfo *pwri;
        +	EVP_CIPHER_CTX ctx;
        +	X509_ALGOR *encalg = NULL;
        +	unsigned char iv[EVP_MAX_IV_LENGTH];
        +	int ivlen;
        +	env = cms_get0_enveloped(cms);
        +	if (!env)
        +		goto err;
        +
        +	if (wrap_nid <= 0)
        +		wrap_nid = NID_id_alg_PWRI_KEK;
        +
        +	if (pbe_nid <= 0)
        +		pbe_nid = NID_id_pbkdf2;
        +
        +	/* Get from enveloped data */
        +	if (kekciph == NULL)
        +		kekciph = env->encryptedContentInfo->cipher;
        +
        +	if (kekciph == NULL)
        +		{
        +		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
        +		return NULL;
        +		}
        +	if (wrap_nid != NID_id_alg_PWRI_KEK)
        +		{
        +		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
        +				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
        +		return NULL;
        +		}
        +
        +	/* Setup algorithm identifier for cipher */
        +	encalg = X509_ALGOR_new();
        +	EVP_CIPHER_CTX_init(&ctx);
        +
        +	if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +
        +	ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
        +
        +	if (ivlen > 0)
        +		{
        +		if (RAND_pseudo_bytes(iv, ivlen) <= 0)
        +			goto err;
        +		if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
        +							ERR_R_EVP_LIB);
        +			goto err;
        +			}
        +		encalg->parameter = ASN1_TYPE_new();
        +		if (!encalg->parameter)
        +			{
        +			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
        +							ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
        +				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
        +			goto err;
        +			}
        +		}
        +
        +
        +	encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));
        +
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +
        +	/* Initialize recipient info */
        +	ri = M_ASN1_new_of(CMS_RecipientInfo);
        +	if (!ri)
        +		goto merr;
        +
        +	ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
        +	if (!ri->d.pwri)
        +		goto merr;
        +	ri->type = CMS_RECIPINFO_PASS;
        +
        +	pwri = ri->d.pwri;
        +	/* Since this is overwritten, free up empty structure already there */
        +	X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
        +	pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
        +	if (!pwri->keyEncryptionAlgorithm)
        +		goto merr;
        +	pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
        +	pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
        +	if (!pwri->keyEncryptionAlgorithm->parameter)
        +		goto merr;
        +
        +        if(!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
        +	    &pwri->keyEncryptionAlgorithm->parameter->value.sequence))
        +		goto merr;
        +        pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
        +
        +	X509_ALGOR_free(encalg);
        +	encalg = NULL;
        +
        +	/* Setup PBE algorithm */
        +
        +	pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
        +
        +	if (!pwri->keyDerivationAlgorithm)
        +		goto err;
        +
        +	CMS_RecipientInfo_set0_password(ri, pass, passlen);
        +	pwri->version = 0;
        +
        +	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
        +		goto merr;
        +
        +	return ri;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
        +	err:
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	if (ri)
        +		M_ASN1_free_of(ri, CMS_RecipientInfo);
        +	if (encalg)
        +		X509_ALGOR_free(encalg);
        +	return NULL;
        +
        +	}
        +
        +/* This is an implementation of the key wrapping mechanism in RFC3211,
        + * at some point this should go into EVP.
        + */
        +
        +static int kek_unwrap_key(unsigned char *out, size_t *outlen,
        +		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
        +	{
        +	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
        +	unsigned char *tmp;
        +	int outl, rv = 0;
        +	if (inlen < 2 * blocklen)
        +		{
        +		/* too small */
        +		return 0;
        +		}
        +	if (inlen % blocklen)
        +		{
        +		/* Invalid size */
        +		return 0;
        +		}
        +	tmp = OPENSSL_malloc(inlen);
        +	/* setup IV by decrypting last two blocks */
        +	EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
        +				in  + inlen - 2 * blocklen, blocklen * 2);
        +	/* Do a decrypt of last decrypted block to set IV to correct value
        +	 * output it to start of buffer so we don't corrupt decrypted block
        +	 * this works because buffer is at least two block lengths long.
        +	 */
        +	EVP_DecryptUpdate(ctx, tmp, &outl,
        +				tmp  + inlen - blocklen, blocklen);
        +	/* Can now decrypt first n - 1 blocks */
        +	EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen);
        +
        +	/* Reset IV to original value */
        +	EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
        +	/* Decrypt again */
        +	EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen);
        +	/* Check check bytes */
        +	if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff)
        +		{
        +		/* Check byte failure */
        +		goto err;
        +		}
        +	if (inlen < (size_t)(tmp[0] - 4 ))
        +		{
        +		/* Invalid length value */
        +		goto err;
        +		}
        +	*outlen = (size_t)tmp[0];
        +	memcpy(out, tmp + 4, *outlen);
        +	rv = 1;
        +	err:
        +	OPENSSL_cleanse(tmp, inlen);
        +	OPENSSL_free(tmp);
        +	return rv;
        +
        +	}
        +
        +static int kek_wrap_key(unsigned char *out, size_t *outlen,
        +		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
        +	{
        +	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
        +	size_t olen;
        +	int dummy;
        +	/* First decide length of output buffer: need header and round up to
        +	 * multiple of block length.
        +	 */
        +	olen = (inlen + 4 + blocklen - 1)/blocklen;
        +	olen *= blocklen;
        +	if (olen < 2 * blocklen)
        +		{
        +		/* Key too small */
        +		return 0;
        +		}
        +	if (inlen > 0xFF)
        +		{
        +		/* Key too large */
        +		return 0;
        +		}
        +	if (out)
        +		{
        +		/* Set header */
        +		out[0] = (unsigned char)inlen;
        +		out[1] = in[0] ^ 0xFF;
        +		out[2] = in[1] ^ 0xFF;
        +		out[3] = in[2] ^ 0xFF;
        +		memcpy(out + 4, in, inlen);
        +		/* Add random padding to end */
        +		if (olen > inlen + 4)
        +			RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen);
        +		/* Encrypt twice */
        +		EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
        +		EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
        +		}
        +
        +	*outlen = olen;
        +
        +	return 1;
        +	}
        +
        +/* Encrypt/Decrypt content key in PWRI recipient info */
        +
        +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
        +							int en_de)
        +	{
        +	CMS_EncryptedContentInfo *ec;
        +	CMS_PasswordRecipientInfo *pwri;
        +	const unsigned char *p = NULL;
        +	int plen;
        +	int r = 0;
        +	X509_ALGOR *algtmp, *kekalg = NULL;
        +	EVP_CIPHER_CTX kekctx;
        +	const EVP_CIPHER *kekcipher;
        +	unsigned char *key = NULL;
        +	size_t keylen;
        +
        +	ec = cms->d.envelopedData->encryptedContentInfo;
        +
        +	pwri = ri->d.pwri;
        +	EVP_CIPHER_CTX_init(&kekctx);
        +
        +	if (!pwri->pass)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
        +		return 0;
        +		}
        +	algtmp = pwri->keyEncryptionAlgorithm;
        +
        +	if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
        +				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
        +		return 0;
        +		}
        +
        +	if (algtmp->parameter->type == V_ASN1_SEQUENCE)
        +		{
        +		p = algtmp->parameter->value.sequence->data;
        +		plen = algtmp->parameter->value.sequence->length;
        +		kekalg = d2i_X509_ALGOR(NULL, &p, plen);
        +		}
        +	if (kekalg == NULL)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
        +				CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
        +		return 0;
        +		}
        +
        +	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
        +		
        +	if(!kekcipher)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
        +				CMS_R_UNKNOWN_CIPHER);
        +		goto err;
        +		}
        +
        +	/* Fixup cipher based on AlgorithmIdentifier to set IV etc */
        +	if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
        +		goto err;
        +	EVP_CIPHER_CTX_set_padding(&kekctx, 0);
        +	if(EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
        +				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
        +		goto err;
        +		}
        +
        +	algtmp = pwri->keyDerivationAlgorithm;
        +
        +	/* Finish password based key derivation to setup key in "ctx" */
        +
        +	if (EVP_PBE_CipherInit(algtmp->algorithm,
        +				(char *)pwri->pass, pwri->passlen,
        +				algtmp->parameter, &kekctx, en_de) < 0)
        +		{
        +		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +
        +	/* Finally wrap/unwrap the key */
        +
        +	if (en_de)
        +		{
        +
        +		if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
        +			goto err;
        +
        +		key = OPENSSL_malloc(keylen);
        +
        +		if (!key)
        +			goto err;
        +
        +		if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
        +			goto err;
        +		pwri->encryptedKey->data = key;
        +		pwri->encryptedKey->length = keylen;
        +		}
        +	else
        +		{
        +		key = OPENSSL_malloc(pwri->encryptedKey->length);
        +
        +		if (!key)
        +			{
        +			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
        +							ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (!kek_unwrap_key(key, &keylen,
        +					pwri->encryptedKey->data,
        +					pwri->encryptedKey->length, &kekctx))
        +			{
        +			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
        +							CMS_R_UNWRAP_FAILURE);
        +			goto err;
        +			}
        +
        +		ec->key = key;
        +		ec->keylen = keylen;
        +
        +		}
        +
        +	r = 1;
        +
        +	err:
        +
        +	EVP_CIPHER_CTX_cleanup(&kekctx);
        +
        +	if (!r && key)
        +		OPENSSL_free(key);
        +	X509_ALGOR_free(kekalg);
        +
        +	return r;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_sd.c b/vendor/openssl/openssl/crypto/cms/cms_sd.c
        new file mode 100644
        index 000000000..77fbd1359
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_sd.c
        @@ -0,0 +1,985 @@
        +/* crypto/cms/cms_sd.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include "cms_lcl.h"
        +#include "asn1_locl.h"
        +
        +/* CMS SignedData Utilities */
        +
        +DECLARE_ASN1_ITEM(CMS_SignedData)
        +
        +static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
        +	{
        +	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)
        +		{
        +		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
        +		return NULL;
        +		}
        +	return cms->d.signedData;
        +	}
        +
        +static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
        +	{
        +	if (cms->d.other == NULL)
        +		{
        +		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
        +		if (!cms->d.signedData)
        +			{
        +			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +			}
        +		cms->d.signedData->version = 1;
        +		cms->d.signedData->encapContentInfo->eContentType =
        +						OBJ_nid2obj(NID_pkcs7_data);
        +		cms->d.signedData->encapContentInfo->partial = 1;
        +		ASN1_OBJECT_free(cms->contentType);
        +		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
        +		return cms->d.signedData;
        +		}
        +	return cms_get0_signed(cms);
        +	}
        +
        +/* Just initialize SignedData e.g. for certs only structure */
        +
        +int CMS_SignedData_init(CMS_ContentInfo *cms)
        +	{
        +	if (cms_signed_data_init(cms))
        +		return 1;
        +	else
        +		return 0;
        +	}
        +
        +/* Check structures and fixup version numbers (if necessary) */
        +
        +static void cms_sd_set_version(CMS_SignedData *sd)
        +	{
        +	int i;
        +	CMS_CertificateChoices *cch;
        +	CMS_RevocationInfoChoice *rch;
        +	CMS_SignerInfo *si;
        +
        +	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)
        +		{
        +		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
        +		if (cch->type == CMS_CERTCHOICE_OTHER)
        +			{
        +			if (sd->version < 5)
        +				sd->version = 5;
        +			}
        +		else if (cch->type == CMS_CERTCHOICE_V2ACERT)
        +			{
        +			if (sd->version < 4)
        +				sd->version = 4;
        +			}
        +		else if (cch->type == CMS_CERTCHOICE_V1ACERT)
        +			{
        +			if (sd->version < 3)
        +				sd->version = 3;
        +			}
        +		}
        +
        +	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)
        +		{
        +		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
        +		if (rch->type == CMS_REVCHOICE_OTHER)
        +			{
        +			if (sd->version < 5)
        +				sd->version = 5;
        +			}
        +		}
        +
        +	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
        +			&& (sd->version < 3))
        +		sd->version = 3;
        +
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
        +		{
        +		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
        +		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
        +			{
        +			if (si->version < 3)
        +				si->version = 3;
        +			if (sd->version < 3)
        +				sd->version = 3;
        +			}
        +		else
        +			sd->version = 1;
        +		}
        +
        +	if (sd->version < 1)
        +		sd->version = 1;
        +
        +	}
        +	
        +/* Copy an existing messageDigest value */
        +
        +static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
        +	{
        +	STACK_OF(CMS_SignerInfo) *sinfos;
        +	CMS_SignerInfo *sitmp;
        +	int i;
        +	sinfos = CMS_get0_SignerInfos(cms);
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +		{
        +		ASN1_OCTET_STRING *messageDigest;
        +		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
        +		if (sitmp == si)
        +			continue;
        +		if (CMS_signed_get_attr_count(sitmp) < 0)
        +			continue;
        +		if (OBJ_cmp(si->digestAlgorithm->algorithm,
        +				sitmp->digestAlgorithm->algorithm))
        +			continue;
        +		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
        +					OBJ_nid2obj(NID_pkcs9_messageDigest),
        +					-3, V_ASN1_OCTET_STRING);
        +		if (!messageDigest)
        +			{
        +			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
        +				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
        +			return 0;
        +			}
        +
        +		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
        +						V_ASN1_OCTET_STRING,
        +						messageDigest, -1))
        +			return 1;
        +		else
        +			return 0;
        +		}
        +		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
        +		return 0;
        +	}
        +
        +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
        +	{
        +	switch(type)
        +		{
        +		case CMS_SIGNERINFO_ISSUER_SERIAL:
        +		sid->d.issuerAndSerialNumber =
        +			M_ASN1_new_of(CMS_IssuerAndSerialNumber);
        +		if (!sid->d.issuerAndSerialNumber)
        +			goto merr;
        +		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
        +					X509_get_issuer_name(cert)))
        +			goto merr;
        +		if (!ASN1_STRING_copy(
        +			sid->d.issuerAndSerialNumber->serialNumber,
        +				X509_get_serialNumber(cert)))
        +			goto merr;
        +		break;
        +
        +		case CMS_SIGNERINFO_KEYIDENTIFIER:
        +		if (!cert->skid)
        +			{
        +			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
        +					CMS_R_CERTIFICATE_HAS_NO_KEYID);
        +			return 0;
        +			}
        +		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
        +		if (!sid->d.subjectKeyIdentifier)
        +			goto merr;
        +		break;
        +
        +		default:
        +		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
        +		return 0;
        +		}
        +
        +	sid->type = type;
        +
        +	return 1;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +
        +	}
        +
        +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
        +					ASN1_OCTET_STRING **keyid,
        +					X509_NAME **issuer, ASN1_INTEGER **sno)
        +	{
        +	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
        +		{
        +		if (issuer)
        +			*issuer = sid->d.issuerAndSerialNumber->issuer;
        +		if (sno)
        +			*sno = sid->d.issuerAndSerialNumber->serialNumber;
        +		}
        +	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
        +		{
        +		if (keyid)
        +			*keyid = sid->d.subjectKeyIdentifier;
        +		}
        +	else
        +		return 0;
        +	return 1;
        +	}
        +
        +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
        +	{
        +	int ret;
        +	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
        +		{
        +		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
        +					X509_get_issuer_name(cert));
        +		if (ret)
        +			return ret;
        +		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
        +					X509_get_serialNumber(cert));
        +		}
        +	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
        +		{
        +		X509_check_purpose(cert, -1, -1);
        +		if (!cert->skid)
        +			return -1;
        +		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,
        +							cert->skid);
        +		}
        +	else
        +		return -1;
        +	}
        +
        +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
        +			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
        +			unsigned int flags)
        +	{
        +	CMS_SignedData *sd;
        +	CMS_SignerInfo *si = NULL;
        +	X509_ALGOR *alg;
        +	int i, type;
        +	if(!X509_check_private_key(signer, pk))
        +		{
        +		CMSerr(CMS_F_CMS_ADD1_SIGNER,
        +			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        +                return NULL;
        +		}
        +	sd = cms_signed_data_init(cms);
        +	if (!sd)
        +		goto err;
        +	si = M_ASN1_new_of(CMS_SignerInfo);
        +	if (!si)
        +		goto merr;
        +	X509_check_purpose(signer, -1, -1);
        +
        +	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
        +	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
        +
        +	si->pkey = pk;
        +	si->signer = signer;
        +
        +	if (flags & CMS_USE_KEYID)
        +		{
        +		si->version = 3;
        +		if (sd->version < 3)
        +			sd->version = 3;
        +		type = CMS_SIGNERINFO_KEYIDENTIFIER;
        +		}
        +	else
        +		{
        +		type = CMS_SIGNERINFO_ISSUER_SERIAL;
        +		si->version = 1;
        +		}
        +
        +	if (!cms_set1_SignerIdentifier(si->sid, signer, type))
        +		goto err;
        +
        +	if (md == NULL)
        +		{
        +		int def_nid;
        +		if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
        +			goto err;
        +		md = EVP_get_digestbynid(def_nid);
        +		if (md == NULL)
        +			{
        +			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
        +			goto err;
        +			}
        +		}
        +
        +	if (!md)
        +		{
        +		CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
        +		goto err;
        +		}
        +
        +	cms_DigestAlgorithm_set(si->digestAlgorithm, md);
        +
        +	/* See if digest is present in digestAlgorithms */
        +	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
        +		{
        +		ASN1_OBJECT *aoid;
        +		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
        +		X509_ALGOR_get0(&aoid, NULL, NULL, alg);
        +		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
        +			break;
        +		}
        +
        +	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))
        +		{
        +		alg = X509_ALGOR_new();
        +		if (!alg)
        +			goto merr;
        +		cms_DigestAlgorithm_set(alg, md);
        +		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))
        +			{
        +			X509_ALGOR_free(alg);
        +			goto merr;
        +			}
        +		}
        +
        +	if (pk->ameth && pk->ameth->pkey_ctrl)
        +		{
        +		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
        +						0, si);
        +		if (i == -2)
        +			{
        +			CMSerr(CMS_F_CMS_ADD1_SIGNER,
        +				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
        +			goto err;
        +			}
        +		if (i <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
        +			goto err;
        +			}
        +		}
        +
        +	if (!(flags & CMS_NOATTR))
        +		{
        +		/* Initialialize signed attributes strutucture so other
        +		 * attributes such as signing time etc are added later
        +		 * even if we add none here.
        +		 */
        +		if (!si->signedAttrs)
        +			{
        +			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
        +			if (!si->signedAttrs)
        +				goto merr;
        +			}
        +
        +		if (!(flags & CMS_NOSMIMECAP))
        +			{
        +			STACK_OF(X509_ALGOR) *smcap = NULL;
        +			i = CMS_add_standard_smimecap(&smcap);
        +			if (i)
        +				i = CMS_add_smimecap(si, smcap);
        +			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
        +			if (!i)
        +				goto merr;
        +			}
        +		if (flags & CMS_REUSE_DIGEST)
        +			{
        +			if (!cms_copy_messageDigest(cms, si))
        +				goto err;
        +			if (!(flags & CMS_PARTIAL) &&
        +					!CMS_SignerInfo_sign(si))
        +				goto err;
        +			}
        +		}
        +
        +	if (!(flags & CMS_NOCERTS))
        +		{
        +		/* NB ignore -1 return for duplicate cert */
        +		if (!CMS_add1_cert(cms, signer))
        +			goto merr;
        +		}
        +
        +	if (!sd->signerInfos)
        +		sd->signerInfos = sk_CMS_SignerInfo_new_null();
        +	if (!sd->signerInfos ||
        +		!sk_CMS_SignerInfo_push(sd->signerInfos, si))
        +		goto merr;
        +
        +	return si;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
        +	err:
        +	if (si)
        +		M_ASN1_free_of(si, CMS_SignerInfo);
        +	return NULL;
        +
        +	}
        +
        +static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
        +	{
        +	ASN1_TIME *tt;
        +	int r = 0;
        +	if (t)
        +		tt = t;
        +	else
        +		tt = X509_gmtime_adj(NULL, 0);
        +
        +	if (!tt)
        +		goto merr;
        +
        +	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
        +						tt->type, tt, -1) <= 0)
        +		goto merr;
        +
        +	r = 1;
        +
        +	merr:
        +
        +	if (!t)
        +		ASN1_TIME_free(tt);
        +
        +	if (!r)
        +		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
        +
        +	return r;
        +
        +	}
        +
        +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
        +	{
        +	CMS_SignedData *sd;
        +	sd = cms_get0_signed(cms);
        +	if (!sd)
        +		return NULL;
        +	return sd->signerInfos;
        +	}
        +
        +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
        +	{
        +	STACK_OF(X509) *signers = NULL;
        +	STACK_OF(CMS_SignerInfo) *sinfos;
        +	CMS_SignerInfo *si;
        +	int i;
        +	sinfos = CMS_get0_SignerInfos(cms);
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +		{
        +		si = sk_CMS_SignerInfo_value(sinfos, i);
        +		if (si->signer)
        +			{
        +			if (!signers)
        +				{
        +				signers = sk_X509_new_null();
        +				if (!signers)
        +					return NULL;
        +				}
        +			if (!sk_X509_push(signers, si->signer))
        +				{
        +				sk_X509_free(signers);
        +				return NULL;
        +				}
        +			}
        +		}
        +	return signers;
        +	}
        +
        +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
        +	{
        +	if (signer)
        +		{
        +		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
        +		if (si->pkey)
        +			EVP_PKEY_free(si->pkey);
        +		si->pkey = X509_get_pubkey(signer);
        +		}
        +	if (si->signer)
        +		X509_free(si->signer);
        +	si->signer = signer;
        +	}
        +
        +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
        +					ASN1_OCTET_STRING **keyid,
        +					X509_NAME **issuer, ASN1_INTEGER **sno)
        +	{
        +	return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
        +	}
        +
        +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
        +	{
        +	return cms_SignerIdentifier_cert_cmp(si->sid, cert);
        +	}
        +
        +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
        +				unsigned int flags)
        +	{
        +	CMS_SignedData *sd;
        +	CMS_SignerInfo *si;
        +	CMS_CertificateChoices *cch;
        +	STACK_OF(CMS_CertificateChoices) *certs;
        +	X509 *x;
        +	int i, j;
        +	int ret = 0;
        +	sd = cms_get0_signed(cms);
        +	if (!sd)
        +		return -1;
        +	certs = sd->certificates;
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
        +		{
        +		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
        +		if (si->signer)
        +			continue;
        +
        +		for (j = 0; j < sk_X509_num(scerts); j++)
        +			{
        +			x = sk_X509_value(scerts, j);
        +			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
        +				{
        +				CMS_SignerInfo_set1_signer_cert(si, x);
        +				ret++;
        +				break;
        +				}
        +			}
        +
        +		if (si->signer || (flags & CMS_NOINTERN))
        +			continue;
        +
        +		for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++)
        +			{
        +			cch = sk_CMS_CertificateChoices_value(certs, j);
        +			if (cch->type != 0)
        +				continue;
        +			x = cch->d.certificate;
        +			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
        +				{
        +				CMS_SignerInfo_set1_signer_cert(si, x);
        +				ret++;
        +				break;
        +				}
        +			}
        +		}
        +	return ret;
        +	}
        +
        +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
        +					X509_ALGOR **pdig, X509_ALGOR **psig)
        +	{
        +	if (pk)
        +		*pk = si->pkey;
        +	if (signer)
        +		*signer = si->signer;
        +	if (pdig)
        +		*pdig = si->digestAlgorithm;
        +	if (psig)
        +		*psig = si->signatureAlgorithm;
        +	}
        +
        +static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
        +					CMS_SignerInfo *si, BIO *chain)
        +	{
        +	EVP_MD_CTX mctx;
        +	int r = 0;
        +	EVP_MD_CTX_init(&mctx);
        +
        +
        +	if (!si->pkey)
        +		{
        +		CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
        +		return 0;
        +		}
        +
        +	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
        +		goto err;
        +
        +	/* If any signed attributes calculate and add messageDigest attribute */
        +
        +	if (CMS_signed_get_attr_count(si) >= 0)
        +		{
        +		ASN1_OBJECT *ctype =
        +			cms->d.signedData->encapContentInfo->eContentType; 
        +		unsigned char md[EVP_MAX_MD_SIZE];
        +		unsigned int mdlen;
        +		if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
        +			goto err;
        +		if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
        +						V_ASN1_OCTET_STRING,
        +						md, mdlen))
        +			goto err;
        +		/* Copy content type across */
        +		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
        +					V_ASN1_OBJECT, ctype, -1) <= 0)
        +			goto err;
        +		if (!CMS_SignerInfo_sign(si))
        +			goto err;
        +		}
        +	else
        +		{
        +		unsigned char *sig;
        +		unsigned int siglen;
        +		sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
        +		if (!sig)
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
        +					ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
        +					CMS_R_SIGNFINAL_ERROR);
        +			OPENSSL_free(sig);
        +			goto err;
        +			}
        +		ASN1_STRING_set0(si->signature, sig, siglen);
        +		}
        +
        +	r = 1;
        +
        +	err:
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return r;
        +
        +	}
        +
        +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
        +	{
        +	STACK_OF(CMS_SignerInfo) *sinfos;
        +	CMS_SignerInfo *si;
        +	int i;
        +	sinfos = CMS_get0_SignerInfos(cms);
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +		{
        +		si = sk_CMS_SignerInfo_value(sinfos, i);
        +		if (!cms_SignerInfo_content_sign(cms, si, chain))
        +			return 0;
        +		}
        +	cms->d.signedData->encapContentInfo->partial = 0;
        +	return 1;
        +	}
        +
        +int CMS_SignerInfo_sign(CMS_SignerInfo *si)
        +	{
        +	EVP_MD_CTX mctx;
        +	EVP_PKEY_CTX *pctx;
        +	unsigned char *abuf = NULL;
        +	int alen;
        +	size_t siglen;
        +	const EVP_MD *md = NULL;
        +
        +	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
        +	if (md == NULL)
        +		return 0;
        +
        +	EVP_MD_CTX_init(&mctx);
        +
        +	if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
        +		{
        +		if (!cms_add1_signingTime(si, NULL))
        +			goto err;
        +		}
        +
        +	if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
        +				EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
        +				ASN1_ITEM_rptr(CMS_Attributes_Sign));
        +	if(!abuf)
        +		goto err;
        +	if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
        +		goto err;
        +	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
        +		goto err;
        +	OPENSSL_free(abuf);
        +	abuf = OPENSSL_malloc(siglen);
        +	if(!abuf)
        +		goto err;
        +	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
        +				EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	EVP_MD_CTX_cleanup(&mctx);
        +
        +	ASN1_STRING_set0(si->signature, abuf, siglen);
        +
        +	return 1;
        +
        +	err:
        +	if (abuf)
        +		OPENSSL_free(abuf);
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return 0;
        +
        +	}
        +
        +int CMS_SignerInfo_verify(CMS_SignerInfo *si)
        +	{
        +	EVP_MD_CTX mctx;
        +	EVP_PKEY_CTX *pctx;
        +	unsigned char *abuf = NULL;
        +	int alen, r = -1;
        +	const EVP_MD *md = NULL;
        +
        +	if (!si->pkey)
        +		{
        +		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
        +		return -1;
        +		}
        +
        +	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
        +	if (md == NULL)
        +		return -1;
        +	EVP_MD_CTX_init(&mctx);
        +	if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
        +		goto err;
        +
        +	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
        +				ASN1_ITEM_rptr(CMS_Attributes_Verify));
        +	if(!abuf)
        +		goto err;
        +	r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
        +	OPENSSL_free(abuf);
        +	if (r <= 0)
        +		{
        +		r = -1;
        +		goto err;
        +		}
        +	r = EVP_DigestVerifyFinal(&mctx,
        +			si->signature->data, si->signature->length);
        +	if (r <= 0)
        +		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
        +	err:
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return r;
        +	}
        +
        +/* Create a chain of digest BIOs from a CMS ContentInfo */
        +
        +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
        +	{
        +	int i;
        +	CMS_SignedData *sd;
        +	BIO *chain = NULL;
        +	sd = cms_get0_signed(cms);
        +	if (!sd)
        +		return NULL;
        +	if (cms->d.signedData->encapContentInfo->partial)
        +		cms_sd_set_version(sd);
        +	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
        +		{
        +		X509_ALGOR *digestAlgorithm;
        +		BIO *mdbio;
        +		digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
        +		mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
        +		if (!mdbio)
        +			goto err;	
        +		if (chain)
        +			 BIO_push(chain, mdbio);
        +		else
        +			chain = mdbio;
        +		}
        +	return chain;
        +	err:
        +	if (chain)
        +		BIO_free_all(chain);
        +	return NULL;
        +	}
        +
        +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
        +	{
        +	ASN1_OCTET_STRING *os = NULL;
        +	EVP_MD_CTX mctx;
        +	int r = -1;
        +	EVP_MD_CTX_init(&mctx);
        +	/* If we have any signed attributes look for messageDigest value */
        +	if (CMS_signed_get_attr_count(si) >= 0)
        +		{
        +		os = CMS_signed_get0_data_by_OBJ(si,
        +					OBJ_nid2obj(NID_pkcs9_messageDigest),
        +					-3, V_ASN1_OCTET_STRING);
        +		if (!os)
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
        +				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
        +			goto err;
        +			}
        +		}
        +
        +	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
        +		goto err;
        +
        +	/* If messageDigest found compare it */
        +
        +	if (os)
        +		{
        +		unsigned char mval[EVP_MAX_MD_SIZE];
        +		unsigned int mlen;
        +		if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
        +				CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
        +			goto err;
        +			}
        +		if (mlen != (unsigned int)os->length)
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
        +				CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
        +			goto err;
        +			}
        +
        +		if (memcmp(mval, os->data, mlen))
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
        +				CMS_R_VERIFICATION_FAILURE);
        +			r = 0;
        +			}
        +		else
        +			r = 1;
        +		}
        +	else
        +		{
        +		r = EVP_VerifyFinal(&mctx, si->signature->data,
        +					si->signature->length, si->pkey);
        +		if (r <= 0)
        +			{
        +			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
        +				CMS_R_VERIFICATION_FAILURE);
        +			r = 0;
        +			}
        +		}
        +
        +	err:
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return r;
        +
        +	}
        +
        +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
        +	{
        +	unsigned char *smder = NULL;
        +	int smderlen, r;
        +	smderlen = i2d_X509_ALGORS(algs, &smder);
        +	if (smderlen <= 0)
        +		return 0;
        +	r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
        +					V_ASN1_SEQUENCE, smder, smderlen);
        +	OPENSSL_free(smder);
        +	return r;
        +	}
        +
        +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
        +				int algnid, int keysize)
        +	{
        +	X509_ALGOR *alg;
        +	ASN1_INTEGER *key = NULL;
        +	if (keysize > 0)
        +		{
        +		key = ASN1_INTEGER_new();
        +		if (!key || !ASN1_INTEGER_set(key, keysize))
        +			return 0;
        +		}
        +	alg = X509_ALGOR_new();
        +	if (!alg)
        +		{
        +		if (key)
        +			ASN1_INTEGER_free(key);
        +		return 0;
        +		}
        +		
        +	X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
        +				key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
        +	if (!*algs)
        +		*algs = sk_X509_ALGOR_new_null();
        +	if (!*algs || !sk_X509_ALGOR_push(*algs, alg))
        +		{
        +		X509_ALGOR_free(alg);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* Check to see if a cipher exists and if so add S/MIME capabilities */
        +
        +static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
        +	{
        +	if (EVP_get_cipherbynid(nid))
        +		return CMS_add_simple_smimecap(sk, nid, arg);
        +	return 1;
        +	}
        +
        +static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
        +	{
        +	if (EVP_get_digestbynid(nid))
        +		return CMS_add_simple_smimecap(sk, nid, arg);
        +	return 1;
        +	}
        +
        +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
        +	{
        +	if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
        +		|| !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
        +		|| !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
        +		|| !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
        +		|| !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
        +		|| !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
        +		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
        +		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
        +		|| !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
        +		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
        +		return 0;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cms/cms_smime.c b/vendor/openssl/openssl/crypto/cms/cms_smime.c
        new file mode 100644
        index 000000000..8c56e3a85
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cms/cms_smime.c
        @@ -0,0 +1,850 @@
        +/* crypto/cms/cms_smime.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +#include <openssl/cms.h>
        +#include "cms_lcl.h"
        +
        +static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
        +	{
        +	unsigned char buf[4096];
        +	int r = 0, i;
        +	BIO *tmpout = NULL;
        +
        +	if (out == NULL)
        +		tmpout = BIO_new(BIO_s_null());
        +	else if (flags & CMS_TEXT)
        +		{
        +		tmpout = BIO_new(BIO_s_mem());
        +		BIO_set_mem_eof_return(tmpout, 0);
        +		}
        +	else
        +		tmpout = out;
        +
        +	if(!tmpout)
        +		{
        +		CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	/* Read all content through chain to process digest, decrypt etc */
        +	for (;;)
        +	{
        +		i=BIO_read(in,buf,sizeof(buf));
        +		if (i <= 0)
        +			{
        +			if (BIO_method_type(in) == BIO_TYPE_CIPHER)
        +				{
        +				if (!BIO_get_cipher_status(in))
        +					goto err;
        +				}
        +			if (i < 0)
        +				goto err;
        +			break;
        +			}
        +				
        +		if (tmpout && (BIO_write(tmpout, buf, i) != i))
        +			goto err;
        +	}
        +
        +	if(flags & CMS_TEXT)
        +		{
        +		if(!SMIME_text(tmpout, out))
        +			{
        +			CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR);
        +			goto err;
        +			}
        +		}
        +
        +	r = 1;
        +
        +	err:
        +	if (tmpout && (tmpout != out))
        +		BIO_free(tmpout);
        +	return r;
        +
        +	}
        +
        +static int check_content(CMS_ContentInfo *cms)
        +	{
        +	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
        +	if (!pos || !*pos)
        +		{
        +		CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +static void do_free_upto(BIO *f, BIO *upto)
        +	{
        +	if (upto)
        +		{
        +		BIO *tbio;
        +		do 
        +			{
        +			tbio = BIO_pop(f);
        +			BIO_free(f);
        +			f = tbio;
        +			}
        +		while (f != upto);
        +		}
        +	else
        +		BIO_free_all(f);
        +	}
        +
        +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
        +	{
        +	BIO *cont;
        +	int r;
        +	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data)
        +		{
        +		CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
        +		return 0;
        +		}
        +	cont = CMS_dataInit(cms, NULL);
        +	if (!cont)
        +		return 0;
        +	r = cms_copy_content(out, cont, flags);
        +	BIO_free_all(cont);
        +	return r;
        +	}
        +
        +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
        +	{
        +	CMS_ContentInfo *cms;
        +	cms = cms_Data_create();
        +	if (!cms)
        +		return NULL;
        +
        +	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
        +		return cms;
        +
        +	CMS_ContentInfo_free(cms);
        +
        +	return NULL;
        +	}
        +
        +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
        +							unsigned int flags)
        +	{
        +	BIO *cont;
        +	int r;
        +	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest)
        +		{
        +		CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
        +		return 0;
        +		}
        +
        +	if (!dcont && !check_content(cms))
        +		return 0;
        +
        +	cont = CMS_dataInit(cms, dcont);
        +	if (!cont)
        +		return 0;
        +	r = cms_copy_content(out, cont, flags);
        +	if (r)
        +		r = cms_DigestedData_do_final(cms, cont, 1);
        +	do_free_upto(cont, dcont);
        +	return r;
        +	}
        +
        +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
        +					unsigned int flags)
        +	{
        +	CMS_ContentInfo *cms;
        +	if (!md)
        +		md = EVP_sha1();
        +	cms = cms_DigestedData_create(md);
        +	if (!cms)
        +		return NULL;
        +
        +	if(!(flags & CMS_DETACHED))
        +		CMS_set_detached(cms, 0);
        +
        +	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
        +		return cms;
        +
        +	CMS_ContentInfo_free(cms);
        +	return NULL;
        +	}
        +
        +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
        +				const unsigned char *key, size_t keylen,
        +				BIO *dcont, BIO *out, unsigned int flags)
        +	{
        +	BIO *cont;
        +	int r;
        +	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
        +					CMS_R_TYPE_NOT_ENCRYPTED_DATA);
        +		return 0;
        +		}
        +
        +	if (!dcont && !check_content(cms))
        +		return 0;
        +
        +	if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
        +		return 0;
        +	cont = CMS_dataInit(cms, dcont);
        +	if (!cont)
        +		return 0;
        +	r = cms_copy_content(out, cont, flags);
        +	do_free_upto(cont, dcont);
        +	return r;
        +	}
        +
        +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
        +					const unsigned char *key, size_t keylen,
        +					unsigned int flags)
        +	{
        +	CMS_ContentInfo *cms;
        +	if (!cipher)
        +		{
        +		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
        +		return NULL;
        +		}
        +	cms = CMS_ContentInfo_new();
        +	if (!cms)
        +		return NULL;
        +	if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
        +		return NULL;
        +
        +	if(!(flags & CMS_DETACHED))
        +		CMS_set_detached(cms, 0);
        +
        +	if ((flags & (CMS_STREAM|CMS_PARTIAL))
        +		|| CMS_final(cms, in, NULL, flags))
        +		return cms;
        +
        +	CMS_ContentInfo_free(cms);
        +	return NULL;
        +	}
        +
        +static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
        +					X509_STORE *store,
        +					STACK_OF(X509) *certs,
        +					STACK_OF(X509_CRL) *crls,
        +					unsigned int flags)
        +	{
        +	X509_STORE_CTX ctx;
        +	X509 *signer;
        +	int i, j, r = 0;
        +	CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
        +	if (!X509_STORE_CTX_init(&ctx, store, signer, certs))
        +		{
        +		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
        +						CMS_R_STORE_INIT_ERROR);
        +		goto err;
        +		}
        +	X509_STORE_CTX_set_default(&ctx, "smime_sign");
        +	if (crls)
        +		X509_STORE_CTX_set0_crls(&ctx, crls);
        +
        +	i = X509_verify_cert(&ctx);
        +	if (i <= 0)
        +		{
        +		j = X509_STORE_CTX_get_error(&ctx);
        +		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
        +						CMS_R_CERTIFICATE_VERIFY_ERROR);
        +		ERR_add_error_data(2, "Verify error:",
        +					 X509_verify_cert_error_string(j));
        +		goto err;
        +		}
        +	r = 1;
        +	err:
        +	X509_STORE_CTX_cleanup(&ctx);
        +	return r;
        +
        +	}
        +
        +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
        +		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
        +	{
        +	CMS_SignerInfo *si;
        +	STACK_OF(CMS_SignerInfo) *sinfos;
        +	STACK_OF(X509) *cms_certs = NULL;
        +	STACK_OF(X509_CRL) *crls = NULL;
        +	X509 *signer;
        +	int i, scount = 0, ret = 0;
        +	BIO *cmsbio = NULL, *tmpin = NULL;
        +
        +	if (!dcont && !check_content(cms))
        +		return 0;
        +
        +	/* Attempt to find all signer certificates */
        +
        +	sinfos = CMS_get0_SignerInfos(cms);
        +
        +	if (sk_CMS_SignerInfo_num(sinfos) <= 0)
        +		{
        +		CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
        +		goto err;
        +		}
        +
        +	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +		{
        +		si = sk_CMS_SignerInfo_value(sinfos, i);
        +		CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
        +		if (signer)
        +			scount++;
        +		}
        +
        +	if (scount != sk_CMS_SignerInfo_num(sinfos))
        +		scount += CMS_set1_signers_certs(cms, certs, flags);
        +
        +	if (scount != sk_CMS_SignerInfo_num(sinfos))
        +		{
        +		CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
        +		goto err;
        +		}
        +
        +	/* Attempt to verify all signers certs */
        +
        +	if (!(flags & CMS_NO_SIGNER_CERT_VERIFY))
        +		{
        +		cms_certs = CMS_get1_certs(cms);
        +		if (!(flags & CMS_NOCRL))
        +			crls = CMS_get1_crls(cms);
        +		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +			{
        +			si = sk_CMS_SignerInfo_value(sinfos, i);
        +			if (!cms_signerinfo_verify_cert(si, store,
        +							cms_certs, crls, flags))
        +				goto err;
        +			}
        +		}
        +
        +	/* Attempt to verify all SignerInfo signed attribute signatures */
        +
        +	if (!(flags & CMS_NO_ATTR_VERIFY))
        +		{
        +		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +			{
        +			si = sk_CMS_SignerInfo_value(sinfos, i);
        +			if (CMS_signed_get_attr_count(si) < 0)
        +				continue;
        +			if (CMS_SignerInfo_verify(si) <= 0)
        +				goto err;
        +			}
        +		}
        +
        +	/* Performance optimization: if the content is a memory BIO then
        +	 * store its contents in a temporary read only memory BIO. This
        +	 * avoids potentially large numbers of slow copies of data which will
        +	 * occur when reading from a read write memory BIO when signatures
        +	 * are calculated.
        +	 */
        +
        +	if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM))
        +		{
        +		char *ptr;
        +		long len;
        +		len = BIO_get_mem_data(dcont, &ptr);
        +		tmpin = BIO_new_mem_buf(ptr, len);
        +		if (tmpin == NULL)
        +			{
        +			CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		}
        +	else
        +		tmpin = dcont;
        +		
        +
        +	cmsbio=CMS_dataInit(cms, tmpin);
        +	if (!cmsbio)
        +		goto err;
        +
        +	if (!cms_copy_content(out, cmsbio, flags))
        +		goto err;
        +
        +	if (!(flags & CMS_NO_CONTENT_VERIFY))
        +		{
        +		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
        +			{
        +			si = sk_CMS_SignerInfo_value(sinfos, i);
        +			if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0)
        +				{
        +				CMSerr(CMS_F_CMS_VERIFY,
        +					CMS_R_CONTENT_VERIFY_ERROR);
        +				goto err;
        +				}
        +			}
        +		}
        +
        +	ret = 1;
        +
        +	err:
        +	
        +	if (dcont && (tmpin == dcont))
        +		do_free_upto(cmsbio, dcont);
        +	else
        +		BIO_free_all(cmsbio);
        +
        +	if (cms_certs)
        +		sk_X509_pop_free(cms_certs, X509_free);
        +	if (crls)
        +		sk_X509_CRL_pop_free(crls, X509_CRL_free);
        +
        +	return ret;
        +	}
        +
        +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
        +			STACK_OF(X509) *certs,
        +			X509_STORE *store, unsigned int flags)
        +	{
        +	int r;
        +	flags &= ~(CMS_DETACHED|CMS_TEXT);
        +	r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
        +	if (r <= 0)
        +		return r;
        +	return cms_Receipt_verify(rcms, ocms);
        +	}
        +
        +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
        +						BIO *data, unsigned int flags)
        +	{
        +	CMS_ContentInfo *cms;
        +	int i;
        +
        +	cms = CMS_ContentInfo_new();
        +	if (!cms || !CMS_SignedData_init(cms))
        +		goto merr;
        +
        +	if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
        +		{
        +		CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
        +		goto err;
        +		}
        +
        +	for (i = 0; i < sk_X509_num(certs); i++)
        +		{
        +		X509 *x = sk_X509_value(certs, i);
        +		if (!CMS_add1_cert(cms, x))
        +			goto merr;
        +		}
        +
        +	if(!(flags & CMS_DETACHED))
        +		CMS_set_detached(cms, 0);
        +
        +	if ((flags & (CMS_STREAM|CMS_PARTIAL))
        +		|| CMS_final(cms, data, NULL, flags))
        +		return cms;
        +	else
        +		goto err;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
        +
        +	err:
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	return NULL;
        +	}
        +
        +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
        +					X509 *signcert, EVP_PKEY *pkey,
        +					STACK_OF(X509) *certs,
        +					unsigned int flags)
        +	{
        +	CMS_SignerInfo *rct_si;
        +	CMS_ContentInfo *cms = NULL;
        +	ASN1_OCTET_STRING **pos, *os;
        +	BIO *rct_cont = NULL;
        +	int r = 0;
        +
        +	flags &= ~(CMS_STREAM|CMS_TEXT);
        +	/* Not really detached but avoids content being allocated */
        +	flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
        +	if (!pkey || !signcert)
        +		{
        +		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
        +		return NULL;
        +		}
        +
        +	/* Initialize signed data */
        +
        +	cms = CMS_sign(NULL, NULL, certs, NULL, flags);
        +	if (!cms)
        +		goto err;
        +
        +	/* Set inner content type to signed receipt */
        +	if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
        +		goto err;
        +
        +	rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
        +	if (!rct_si)
        +		{
        +		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
        +		goto err;
        +		}
        +
        +	os = cms_encode_Receipt(si);
        +
        +	if (!os)
        +		goto err;
        +
        +	/* Set content to digest */
        +	rct_cont = BIO_new_mem_buf(os->data, os->length);
        +	if (!rct_cont)
        +		goto err;
        +
        +	/* Add msgSigDigest attribute */
        +
        +	if (!cms_msgSigDigest_add1(rct_si, si))
        +		goto err;
        +
        +	/* Finalize structure */
        +	if (!CMS_final(cms, rct_cont, NULL, flags))
        +		goto err;
        +
        +	/* Set embedded content */
        +	pos = CMS_get0_content(cms);
        +	*pos = os;
        +
        +	r = 1;
        +
        +	err:
        +	if (rct_cont)
        +		BIO_free(rct_cont);
        +	if (r)
        +		return cms;
        +	CMS_ContentInfo_free(cms);
        +	return NULL;
        +
        +	}
        +
        +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
        +				const EVP_CIPHER *cipher, unsigned int flags)
        +	{
        +	CMS_ContentInfo *cms;
        +	int i;
        +	X509 *recip;
        +	cms = CMS_EnvelopedData_create(cipher);
        +	if (!cms)
        +		goto merr;
        +	for (i = 0; i < sk_X509_num(certs); i++)
        +		{
        +		recip = sk_X509_value(certs, i);
        +		if (!CMS_add1_recipient_cert(cms, recip, flags))
        +			{
        +			CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
        +			goto err;
        +			}
        +		}
        +
        +	if(!(flags & CMS_DETACHED))
        +		CMS_set_detached(cms, 0);
        +
        +	if ((flags & (CMS_STREAM|CMS_PARTIAL))
        +		|| CMS_final(cms, data, NULL, flags))
        +		return cms;
        +	else
        +		goto err;
        +
        +	merr:
        +	CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
        +	err:
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	return NULL;
        +	}
        +
        +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
        +	{
        +	STACK_OF(CMS_RecipientInfo) *ris;
        +	CMS_RecipientInfo *ri;
        +	int i, r;
        +	int debug = 0;
        +	ris = CMS_get0_RecipientInfos(cms);
        +	if (ris)
        +		debug = cms->d.envelopedData->encryptedContentInfo->debug;
        +	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
        +		{
        +		ri = sk_CMS_RecipientInfo_value(ris, i);
        +		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
        +				continue;
        +		/* If we have a cert try matching RecipientInfo
        +		 * otherwise try them all.
        +		 */
        +		if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
        +			{
        +			CMS_RecipientInfo_set0_pkey(ri, pk);
        +			r = CMS_RecipientInfo_decrypt(cms, ri);
        +			CMS_RecipientInfo_set0_pkey(ri, NULL);
        +			if (cert)
        +				{
        +				/* If not debugging clear any error and
        +				 * return success to avoid leaking of
        +				 * information useful to MMA
        +				 */
        +				if (!debug)
        +					{
        +					ERR_clear_error();
        +					return 1;
        +					}
        +				if (r > 0)
        +					return 1;
        +				CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
        +						CMS_R_DECRYPT_ERROR);
        +				return 0;
        +				}
        +			/* If no cert and not debugging don't leave loop
        +			 * after first successful decrypt. Always attempt
        +			 * to decrypt all recipients to avoid leaking timing
        +			 * of a successful decrypt.
        +			 */
        +			else if (r > 0 && debug)
        +				return 1;
        +			}
        +		}
        +	/* If no cert and not debugging always return success */
        +	if (!cert && !debug)
        +		{
        +		ERR_clear_error();
        +		return 1;
        +		}
        +
        +	CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
        +	return 0;
        +
        +	}
        +
        +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
        +				unsigned char *key, size_t keylen,
        +				unsigned char *id, size_t idlen)
        +	{
        +	STACK_OF(CMS_RecipientInfo) *ris;
        +	CMS_RecipientInfo *ri;
        +	int i, r;
        +	ris = CMS_get0_RecipientInfos(cms);
        +	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
        +		{
        +		ri = sk_CMS_RecipientInfo_value(ris, i);
        +		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
        +				continue;
        +
        +		/* If we have an id try matching RecipientInfo
        +		 * otherwise try them all.
        +		 */
        +		if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0))
        +			{
        +			CMS_RecipientInfo_set0_key(ri, key, keylen);
        +			r = CMS_RecipientInfo_decrypt(cms, ri);
        +			CMS_RecipientInfo_set0_key(ri, NULL, 0);
        +			if (r > 0)
        +				return 1;
        +			if (id)
        +				{
        +				CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY,
        +						CMS_R_DECRYPT_ERROR);
        +				return 0;
        +				}
        +			ERR_clear_error();
        +			}
        +		}
        +
        +	CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
        +	return 0;
        +
        +	}
        +
        +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, 
        +				unsigned char *pass, ossl_ssize_t passlen)
        +	{
        +	STACK_OF(CMS_RecipientInfo) *ris;
        +	CMS_RecipientInfo *ri;
        +	int i, r;
        +	ris = CMS_get0_RecipientInfos(cms);
        +	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
        +		{
        +		ri = sk_CMS_RecipientInfo_value(ris, i);
        +		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
        +				continue;
        +		CMS_RecipientInfo_set0_password(ri, pass, passlen);
        +		r = CMS_RecipientInfo_decrypt(cms, ri);
        +		CMS_RecipientInfo_set0_password(ri, NULL, 0);
        +		if (r > 0)
        +			return 1;
        +		}
        +
        +	CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
        +	return 0;
        +
        +	}
        +	
        +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
        +				BIO *dcont, BIO *out,
        +				unsigned int flags)
        +	{
        +	int r;
        +	BIO *cont;
        +	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
        +		{
        +		CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
        +		return 0;
        +		}
        +	if (!dcont && !check_content(cms))
        +		return 0;
        +	if (flags & CMS_DEBUG_DECRYPT)
        +		cms->d.envelopedData->encryptedContentInfo->debug = 1;
        +	else
        +		cms->d.envelopedData->encryptedContentInfo->debug = 0;
        +	if (!pk && !cert && !dcont && !out)
        +		return 1;
        +	if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
        +		return 0;
        +	cont = CMS_dataInit(cms, dcont);
        +	if (!cont)
        +		return 0;
        +	r = cms_copy_content(out, cont, flags);
        +	do_free_upto(cont, dcont);
        +	return r;
        +	}
        +
        +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
        +	{
        +	BIO *cmsbio;
        +	int ret = 0;
        +	if (!(cmsbio = CMS_dataInit(cms, dcont)))
        +		{
        +		CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	SMIME_crlf_copy(data, cmsbio, flags);
        +
        +	(void)BIO_flush(cmsbio);
        +
        +
        +        if (!CMS_dataFinal(cms, cmsbio))
        +		{
        +		CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +
        +	err:
        +	do_free_upto(cmsbio, dcont);
        +
        +	return ret;
        +
        +	}
        +
        +#ifdef ZLIB
        +
        +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
        +							unsigned int flags)
        +	{
        +	BIO *cont;
        +	int r;
        +	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData)
        +		{
        +		CMSerr(CMS_F_CMS_UNCOMPRESS,
        +					CMS_R_TYPE_NOT_COMPRESSED_DATA);
        +		return 0;
        +		}
        +
        +	if (!dcont && !check_content(cms))
        +		return 0;
        +
        +	cont = CMS_dataInit(cms, dcont);
        +	if (!cont)
        +		return 0;
        +	r = cms_copy_content(out, cont, flags);
        +	do_free_upto(cont, dcont);
        +	return r;
        +	}
        +
        +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
        +	{
        +	CMS_ContentInfo *cms;
        +	if (comp_nid <= 0)
        +		comp_nid = NID_zlib_compression;
        +	cms = cms_CompressedData_create(comp_nid);
        +	if (!cms)
        +		return NULL;
        +
        +	if(!(flags & CMS_DETACHED))
        +		CMS_set_detached(cms, 0);
        +
        +	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
        +		return cms;
        +
        +	CMS_ContentInfo_free(cms);
        +	return NULL;
        +	}
        +
        +#else
        +
        +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
        +							unsigned int flags)
        +	{
        +	CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
        +	return 0;
        +	}
        +
        +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
        +	{
        +	CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
        +	return NULL;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/comp/Makefile b/vendor/openssl/openssl/crypto/comp/Makefile
        new file mode 100644
        index 000000000..efda832dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/comp/Makefile
        @@ -0,0 +1,108 @@
        +#
        +# OpenSSL/crypto/comp/Makefile
        +#
        +
        +DIR=	comp
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= comp_lib.c comp_err.c \
        +	c_rle.c c_zlib.c
        +
        +LIBOBJ=	comp_lib.o comp_err.o \
        +	c_rle.o c_zlib.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= comp.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +c_rle.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +c_rle.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
        +c_rle.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
        +c_rle.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +c_rle.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +c_rle.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +c_rle.o: ../../include/openssl/symhacks.h c_rle.c
        +c_zlib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +c_zlib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
        +c_zlib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +c_zlib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +c_zlib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +c_zlib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +c_zlib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +c_zlib.o: ../../include/openssl/symhacks.h c_zlib.c
        +comp_err.o: ../../include/openssl/bio.h ../../include/openssl/comp.h
        +comp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +comp_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +comp_err.o: ../../include/openssl/opensslconf.h
        +comp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +comp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +comp_err.o: ../../include/openssl/symhacks.h comp_err.c
        +comp_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +comp_lib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
        +comp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
        +comp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +comp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +comp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +comp_lib.o: ../../include/openssl/symhacks.h comp_lib.c
        diff --git a/vendor/openssl/openssl/crypto/comp/c_rle.c b/vendor/openssl/openssl/crypto/comp/c_rle.c
        new file mode 100644
        index 000000000..47dfb67fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/comp/c_rle.c
        @@ -0,0 +1,61 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/objects.h>
        +#include <openssl/comp.h>
        +
        +static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen);
        +static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen);
        +
        +static COMP_METHOD rle_method={
        +	NID_rle_compression,
        +	LN_rle_compression,
        +	NULL,
        +	NULL,
        +	rle_compress_block,
        +	rle_expand_block,
        +	NULL,
        +	NULL,
        +	};
        +
        +COMP_METHOD *COMP_rle(void)
        +	{
        +	return(&rle_method);
        +	}
        +
        +static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
        +	     unsigned int olen, unsigned char *in, unsigned int ilen)
        +	{
        +	/* int i; */
        +
        +	if (ilen == 0 || olen < (ilen-1))
        +		{
        +		/* ZZZZZZZZZZZZZZZZZZZZZZ */
        +		return(-1);
        +		}
        +
        +	*(out++)=0;
        +	memcpy(out,in,ilen);
        +	return(ilen+1);
        +	}
        +
        +static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
        +	     unsigned int olen, unsigned char *in, unsigned int ilen)
        +	{
        +	int i;
        +
        +	if (olen < (ilen-1))
        +		{
        +		/* ZZZZZZZZZZZZZZZZZZZZZZ */
        +		return(-1);
        +		}
        +
        +	i= *(in++);
        +	if (i == 0)
        +		{
        +		memcpy(out,in,ilen-1);
        +		}
        +	return(ilen-1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/comp/c_zlib.c b/vendor/openssl/openssl/crypto/comp/c_zlib.c
        new file mode 100644
        index 000000000..8adf35f3f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/comp/c_zlib.c
        @@ -0,0 +1,799 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/objects.h>
        +#include <openssl/comp.h>
        +#include <openssl/err.h>
        +
        +COMP_METHOD *COMP_zlib(void );
        +
        +static COMP_METHOD zlib_method_nozlib={
        +	NID_undef,
        +	"(undef)",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	};
        +
        +#ifndef ZLIB
        +#undef ZLIB_SHARED
        +#else
        +
        +#include <zlib.h>
        +
        +static int zlib_stateful_init(COMP_CTX *ctx);
        +static void zlib_stateful_finish(COMP_CTX *ctx);
        +static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen);
        +static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen);
        +
        +
        +/* memory allocations functions for zlib intialization */
        +static void* zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
        +{
        +	void *p;
        +	
        +	p=OPENSSL_malloc(no*size);
        +	if (p)
        +		memset(p, 0, no*size);
        +	return p;
        +}
        +
        +
        +static void zlib_zfree(void* opaque, void* address)
        +{
        +	OPENSSL_free(address);
        +}
        +
        +#if 0
        +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen);
        +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen);
        +
        +static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
        +	uLong sourceLen);
        +
        +static COMP_METHOD zlib_stateless_method={
        +	NID_zlib_compression,
        +	LN_zlib_compression,
        +	NULL,
        +	NULL,
        +	zlib_compress_block,
        +	zlib_expand_block,
        +	NULL,
        +	NULL,
        +	};
        +#endif
        +
        +static COMP_METHOD zlib_stateful_method={
        +	NID_zlib_compression,
        +	LN_zlib_compression,
        +	zlib_stateful_init,
        +	zlib_stateful_finish,
        +	zlib_stateful_compress_block,
        +	zlib_stateful_expand_block,
        +	NULL,
        +	NULL,
        +	};
        +
        +/* 
        + * When OpenSSL is built on Windows, we do not want to require that
        + * the ZLIB.DLL be available in order for the OpenSSL DLLs to
        + * work.  Therefore, all ZLIB routines are loaded at run time
        + * and we do not link to a .LIB file when ZLIB_SHARED is set.
        + */
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
        +# include <windows.h>
        +#endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */
        +
        +#ifdef ZLIB_SHARED
        +#include <openssl/dso.h>
        +
        +/* Function pointers */
        +typedef int (*compress_ft)(Bytef *dest,uLongf *destLen,
        +	const Bytef *source, uLong sourceLen);
        +typedef int (*inflateEnd_ft)(z_streamp strm);
        +typedef int (*inflate_ft)(z_streamp strm, int flush);
        +typedef int (*inflateInit__ft)(z_streamp strm,
        +	const char * version, int stream_size);
        +typedef int (*deflateEnd_ft)(z_streamp strm);
        +typedef int (*deflate_ft)(z_streamp strm, int flush);
        +typedef int (*deflateInit__ft)(z_streamp strm, int level,
        +	const char * version, int stream_size);
        +typedef const char * (*zError__ft)(int err);
        +static compress_ft	p_compress=NULL;
        +static inflateEnd_ft	p_inflateEnd=NULL;
        +static inflate_ft	p_inflate=NULL;
        +static inflateInit__ft	p_inflateInit_=NULL;
        +static deflateEnd_ft	p_deflateEnd=NULL;
        +static deflate_ft	p_deflate=NULL;
        +static deflateInit__ft	p_deflateInit_=NULL;
        +static zError__ft	p_zError=NULL;
        +
        +static int zlib_loaded = 0;     /* only attempt to init func pts once */
        +static DSO *zlib_dso = NULL;
        +
        +#define compress                p_compress
        +#define inflateEnd              p_inflateEnd
        +#define inflate                 p_inflate
        +#define inflateInit_            p_inflateInit_
        +#define deflateEnd              p_deflateEnd
        +#define deflate                 p_deflate
        +#define deflateInit_            p_deflateInit_
        +#define zError			p_zError
        +#endif /* ZLIB_SHARED */
        +
        +struct zlib_state
        +	{
        +	z_stream istream;
        +	z_stream ostream;
        +	};
        +
        +static int zlib_stateful_ex_idx = -1;
        +
        +static int zlib_stateful_init(COMP_CTX *ctx)
        +	{
        +	int err;
        +	struct zlib_state *state =
        +		(struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
        +
        +	if (state == NULL)
        +		goto err;
        +
        +	state->istream.zalloc = zlib_zalloc;
        +	state->istream.zfree = zlib_zfree;
        +	state->istream.opaque = Z_NULL;
        +	state->istream.next_in = Z_NULL;
        +	state->istream.next_out = Z_NULL;
        +	state->istream.avail_in = 0;
        +	state->istream.avail_out = 0;
        +	err = inflateInit_(&state->istream,
        +		ZLIB_VERSION, sizeof(z_stream));
        +	if (err != Z_OK)
        +		goto err;
        +
        +	state->ostream.zalloc = zlib_zalloc;
        +	state->ostream.zfree = zlib_zfree;
        +	state->ostream.opaque = Z_NULL;
        +	state->ostream.next_in = Z_NULL;
        +	state->ostream.next_out = Z_NULL;
        +	state->ostream.avail_in = 0;
        +	state->ostream.avail_out = 0;
        +	err = deflateInit_(&state->ostream,Z_DEFAULT_COMPRESSION,
        +		ZLIB_VERSION, sizeof(z_stream));
        +	if (err != Z_OK)
        +		goto err;
        +
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
        +	CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
        +	return 1;
        + err:
        +	if (state) OPENSSL_free(state);
        +	return 0;
        +	}
        +
        +static void zlib_stateful_finish(COMP_CTX *ctx)
        +	{
        +	struct zlib_state *state =
        +		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
        +			zlib_stateful_ex_idx);
        +	inflateEnd(&state->istream);
        +	deflateEnd(&state->ostream);
        +	OPENSSL_free(state);
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
        +	}
        +
        +static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen)
        +	{
        +	int err = Z_OK;
        +	struct zlib_state *state =
        +		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
        +			zlib_stateful_ex_idx);
        +
        +	if (state == NULL)
        +		return -1;
        +
        +	state->ostream.next_in = in;
        +	state->ostream.avail_in = ilen;
        +	state->ostream.next_out = out;
        +	state->ostream.avail_out = olen;
        +	if (ilen > 0)
        +		err = deflate(&state->ostream, Z_SYNC_FLUSH);
        +	if (err != Z_OK)
        +		return -1;
        +#ifdef DEBUG_ZLIB
        +	fprintf(stderr,"compress(%4d)->%4d %s\n",
        +		ilen,olen - state->ostream.avail_out,
        +		(ilen != olen - state->ostream.avail_out)?"zlib":"clear");
        +#endif
        +	return olen - state->ostream.avail_out;
        +	}
        +
        +static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen)
        +	{
        +	int err = Z_OK;
        +
        +	struct zlib_state *state =
        +		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
        +			zlib_stateful_ex_idx);
        +
        +	if (state == NULL)
        +		return 0;
        +
        +	state->istream.next_in = in;
        +	state->istream.avail_in = ilen;
        +	state->istream.next_out = out;
        +	state->istream.avail_out = olen;
        +	if (ilen > 0)
        +		err = inflate(&state->istream, Z_SYNC_FLUSH);
        +	if (err != Z_OK)
        +		return -1;
        +#ifdef DEBUG_ZLIB
        +	fprintf(stderr,"expand(%4d)->%4d %s\n",
        +		ilen,olen - state->istream.avail_out,
        +		(ilen != olen - state->istream.avail_out)?"zlib":"clear");
        +#endif
        +	return olen - state->istream.avail_out;
        +	}
        +
        +#if 0
        +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen)
        +	{
        +	unsigned long l;
        +	int i;
        +	int clear=1;
        +
        +	if (ilen > 128)
        +		{
        +		out[0]=1;
        +		l=olen-1;
        +		i=compress(&(out[1]),&l,in,(unsigned long)ilen);
        +		if (i != Z_OK)
        +			return(-1);
        +		if (ilen > l)
        +			{
        +			clear=0;
        +			l++;
        +			}
        +		}
        +	if (clear)
        +		{
        +		out[0]=0;
        +		memcpy(&(out[1]),in,ilen);
        +		l=ilen+1;
        +		}
        +#ifdef DEBUG_ZLIB
        +	fprintf(stderr,"compress(%4d)->%4d %s\n",
        +		ilen,(int)l,(clear)?"clear":"zlib");
        +#endif
        +	return((int)l);
        +	}
        +
        +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
        +	unsigned int olen, unsigned char *in, unsigned int ilen)
        +	{
        +	unsigned long l;
        +	int i;
        +
        +	if (in[0])
        +		{
        +		l=olen;
        +		i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
        +		if (i != Z_OK)
        +			return(-1);
        +		}
        +	else
        +		{
        +		memcpy(out,&(in[1]),ilen-1);
        +		l=ilen-1;
        +		}
        +#ifdef DEBUG_ZLIB
        +        fprintf(stderr,"expand  (%4d)->%4d %s\n",
        +		ilen,(int)l,in[0]?"zlib":"clear");
        +#endif
        +	return((int)l);
        +	}
        +
        +static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
        +	     uLong sourceLen)
        +{
        +    z_stream stream;
        +    int err;
        +
        +    stream.next_in = (Bytef*)source;
        +    stream.avail_in = (uInt)sourceLen;
        +    /* Check for source > 64K on 16-bit machine: */
        +    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
        +
        +    stream.next_out = dest;
        +    stream.avail_out = (uInt)*destLen;
        +    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
        +
        +    stream.zalloc = (alloc_func)0;
        +    stream.zfree = (free_func)0;
        +
        +    err = inflateInit_(&stream,
        +	    ZLIB_VERSION, sizeof(z_stream));
        +    if (err != Z_OK) return err;
        +
        +    err = inflate(&stream, Z_FINISH);
        +    if (err != Z_STREAM_END) {
        +        inflateEnd(&stream);
        +        return err;
        +    }
        +    *destLen = stream.total_out;
        +
        +    err = inflateEnd(&stream);
        +    return err;
        +}
        +#endif
        +
        +#endif
        +
        +COMP_METHOD *COMP_zlib(void)
        +	{
        +	COMP_METHOD *meth = &zlib_method_nozlib;
        +
        +#ifdef ZLIB_SHARED
        +	if (!zlib_loaded)
        +		{
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
        +		zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
        +#else
        +		zlib_dso = DSO_load(NULL, "z", NULL, 0);
        +#endif
        +		if (zlib_dso != NULL)
        +			{
        +			p_compress
        +				= (compress_ft) DSO_bind_func(zlib_dso,
        +					"compress");
        +			p_inflateEnd
        +				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
        +					"inflateEnd");
        +			p_inflate
        +				= (inflate_ft) DSO_bind_func(zlib_dso,
        +					"inflate");
        +			p_inflateInit_
        +				= (inflateInit__ft) DSO_bind_func(zlib_dso,
        +					"inflateInit_");
        +			p_deflateEnd
        +				= (deflateEnd_ft) DSO_bind_func(zlib_dso,
        +					"deflateEnd");
        +			p_deflate
        +				= (deflate_ft) DSO_bind_func(zlib_dso,
        +					"deflate");
        +			p_deflateInit_
        +				= (deflateInit__ft) DSO_bind_func(zlib_dso,
        +					"deflateInit_");
        +			p_zError
        +				= (zError__ft) DSO_bind_func(zlib_dso,
        +					"zError");
        +
        +			if (p_compress && p_inflateEnd && p_inflate
        +				&& p_inflateInit_ && p_deflateEnd
        +				&& p_deflate && p_deflateInit_ && p_zError)
        +				zlib_loaded++;
        +			}
        +		}
        +
        +#endif
        +#ifdef ZLIB_SHARED
        +	if (zlib_loaded)
        +#endif
        +#if defined(ZLIB) || defined(ZLIB_SHARED)
        +		{
        +		/* init zlib_stateful_ex_idx here so that in a multi-process
        +		 * application it's enough to intialize openssl before forking
        +		 * (idx will be inherited in all the children) */
        +		if (zlib_stateful_ex_idx == -1)
        +			{
        +			CRYPTO_w_lock(CRYPTO_LOCK_COMP);
        +			if (zlib_stateful_ex_idx == -1)
        +				zlib_stateful_ex_idx =
        +					CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
        +						0,NULL,NULL,NULL,NULL);
        +			CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
        +			if (zlib_stateful_ex_idx == -1)
        +				goto err;
        +			}
        +		
        +		meth = &zlib_stateful_method;
        +		}
        +err:	
        +#endif
        +
        +	return(meth);
        +	}
        +
        +void COMP_zlib_cleanup(void)
        +	{
        +#ifdef ZLIB_SHARED
        +	if (zlib_dso)
        +		DSO_free(zlib_dso);
        +#endif
        +	}
        +
        +#ifdef ZLIB
        +
        +/* Zlib based compression/decompression filter BIO */
        +
        +typedef struct
        +	{
        +	unsigned char *ibuf;	/* Input buffer */
        +	int ibufsize;		/* Buffer size */
        +	z_stream zin;		/* Input decompress context */
        +	unsigned char *obuf;	/* Output buffer */
        +	int obufsize;		/* Output buffer size */
        +	unsigned char *optr;	/* Position in output buffer */
        +	int ocount;		/* Amount of data in output buffer */
        +	int odone;		/* deflate EOF */
        +	int comp_level;		/* Compression level to use */
        +	z_stream zout;		/* Output compression context */
        +	} BIO_ZLIB_CTX;
        +
        +#define ZLIB_DEFAULT_BUFSIZE 1024
        +
        +static int bio_zlib_new(BIO *bi);
        +static int bio_zlib_free(BIO *bi);
        +static int bio_zlib_read(BIO *b, char *out, int outl);
        +static int bio_zlib_write(BIO *b, const char *in, int inl);
        +static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
        +static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
        +
        +static BIO_METHOD bio_meth_zlib = 
        +	{
        +	BIO_TYPE_COMP,
        +	"zlib",
        +	bio_zlib_write,
        +	bio_zlib_read,
        +	NULL,
        +	NULL,
        +	bio_zlib_ctrl,
        +	bio_zlib_new,
        +	bio_zlib_free,
        +	bio_zlib_callback_ctrl
        +	};
        +
        +BIO_METHOD *BIO_f_zlib(void)
        +	{
        +	return &bio_meth_zlib;
        +	}
        +
        +
        +static int bio_zlib_new(BIO *bi)
        +	{
        +	BIO_ZLIB_CTX *ctx;
        +#ifdef ZLIB_SHARED
        +	(void)COMP_zlib();
        +	if (!zlib_loaded)
        +		{
        +		COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
        +		return 0;
        +		}
        +#endif
        +	ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
        +	if(!ctx)
        +		{
        +		COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ctx->ibuf = NULL;
        +	ctx->obuf = NULL;
        +	ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
        +	ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
        +	ctx->zin.zalloc = Z_NULL;
        +	ctx->zin.zfree = Z_NULL;
        +	ctx->zin.next_in = NULL;
        +	ctx->zin.avail_in = 0;
        +	ctx->zin.next_out = NULL;
        +	ctx->zin.avail_out = 0;
        +	ctx->zout.zalloc = Z_NULL;
        +	ctx->zout.zfree = Z_NULL;
        +	ctx->zout.next_in = NULL;
        +	ctx->zout.avail_in = 0;
        +	ctx->zout.next_out = NULL;
        +	ctx->zout.avail_out = 0;
        +	ctx->odone = 0;
        +	ctx->comp_level = Z_DEFAULT_COMPRESSION;
        +	bi->init = 1;
        +	bi->ptr = (char *)ctx;
        +	bi->flags = 0;
        +	return 1;
        +	}
        +
        +static int bio_zlib_free(BIO *bi)
        +	{
        +	BIO_ZLIB_CTX *ctx;
        +	if(!bi) return 0;
        +	ctx = (BIO_ZLIB_CTX *)bi->ptr;
        +	if(ctx->ibuf)
        +		{
        +		/* Destroy decompress context */
        +		inflateEnd(&ctx->zin);
        +		OPENSSL_free(ctx->ibuf);
        +		}
        +	if(ctx->obuf)
        +		{
        +		/* Destroy compress context */
        +		deflateEnd(&ctx->zout);
        +		OPENSSL_free(ctx->obuf);
        +		}
        +	OPENSSL_free(ctx);
        +	bi->ptr = NULL;
        +	bi->init = 0;
        +	bi->flags = 0;
        +	return 1;
        +	}
        +
        +static int bio_zlib_read(BIO *b, char *out, int outl)
        +	{
        +	BIO_ZLIB_CTX *ctx;
        +	int ret;
        +	z_stream *zin;
        +	if(!out || !outl) return 0;
        +	ctx = (BIO_ZLIB_CTX *)b->ptr;
        +	zin = &ctx->zin;
        +	BIO_clear_retry_flags(b);
        +	if(!ctx->ibuf)
        +		{
        +		ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
        +		if(!ctx->ibuf)
        +			{
        +			COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		inflateInit(zin);
        +		zin->next_in = ctx->ibuf;
        +		zin->avail_in = 0;
        +		}
        +
        +	/* Copy output data directly to supplied buffer */
        +	zin->next_out = (unsigned char *)out;
        +	zin->avail_out = (unsigned int)outl;
        +	for(;;)
        +		{
        +		/* Decompress while data available */
        +		while(zin->avail_in)
        +			{
        +			ret = inflate(zin, 0);
        +			if((ret != Z_OK) && (ret != Z_STREAM_END))
        +				{
        +				COMPerr(COMP_F_BIO_ZLIB_READ,
        +						COMP_R_ZLIB_INFLATE_ERROR);
        +				ERR_add_error_data(2, "zlib error:",
        +							zError(ret));
        +				return 0;
        +				}
        +			/* If EOF or we've read everything then return */
        +			if((ret == Z_STREAM_END) || !zin->avail_out)
        +				return outl - zin->avail_out;
        +			}
        +
        +		/* No data in input buffer try to read some in,
        +		 * if an error then return the total data read.
        +		 */
        +		ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
        +		if(ret <= 0)
        +			{
        +			/* Total data read */
        +			int tot = outl - zin->avail_out;
        +			BIO_copy_next_retry(b);
        +			if(ret < 0) return (tot > 0) ? tot : ret;
        +			return tot;
        +			}
        +		zin->avail_in = ret;
        +		zin->next_in = ctx->ibuf;
        +		}
        +	}
        +
        +static int bio_zlib_write(BIO *b, const char *in, int inl)
        +	{
        +	BIO_ZLIB_CTX *ctx;
        +	int ret;
        +	z_stream *zout;
        +	if(!in || !inl) return 0;
        +	ctx = (BIO_ZLIB_CTX *)b->ptr;
        +	if(ctx->odone) return 0;
        +	zout = &ctx->zout;
        +	BIO_clear_retry_flags(b);
        +	if(!ctx->obuf)
        +		{
        +		ctx->obuf = OPENSSL_malloc(ctx->obufsize);
        +		/* Need error here */
        +		if(!ctx->obuf)
        +			{
        +			COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		ctx->optr = ctx->obuf;
        +		ctx->ocount = 0;
        +		deflateInit(zout, ctx->comp_level);
        +		zout->next_out = ctx->obuf;
        +		zout->avail_out = ctx->obufsize;
        +		}
        +	/* Obtain input data directly from supplied buffer */
        +	zout->next_in = (void *)in;
        +	zout->avail_in = inl;
        +	for(;;)
        +		{
        +		/* If data in output buffer write it first */
        +		while(ctx->ocount) {
        +			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
        +			if(ret <= 0)
        +				{
        +				/* Total data written */
        +				int tot = inl - zout->avail_in;
        +				BIO_copy_next_retry(b);
        +				if(ret < 0) return (tot > 0) ? tot : ret;
        +				return tot;
        +				}
        +			ctx->optr += ret;
        +			ctx->ocount -= ret;
        +		}
        +
        +		/* Have we consumed all supplied data? */
        +		if(!zout->avail_in)
        +			return inl;
        +
        +		/* Compress some more */
        +
        +		/* Reset buffer */
        +		ctx->optr = ctx->obuf;
        +		zout->next_out = ctx->obuf;
        +		zout->avail_out = ctx->obufsize;
        +		/* Compress some more */
        +		ret = deflate(zout, 0);
        +		if(ret != Z_OK)
        +			{
        +			COMPerr(COMP_F_BIO_ZLIB_WRITE,
        +						COMP_R_ZLIB_DEFLATE_ERROR);
        +			ERR_add_error_data(2, "zlib error:", zError(ret));
        +			return 0;
        +			}
        +		ctx->ocount = ctx->obufsize - zout->avail_out;
        +		}
        +	}
        +
        +static int bio_zlib_flush(BIO *b)
        +	{
        +	BIO_ZLIB_CTX *ctx;
        +	int ret;
        +	z_stream *zout;
        +	ctx = (BIO_ZLIB_CTX *)b->ptr;
        +	/* If no data written or already flush show success */
        +	if(!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1;
        +	zout = &ctx->zout;
        +	BIO_clear_retry_flags(b);
        +	/* No more input data */
        +	zout->next_in = NULL;
        +	zout->avail_in = 0;
        +	for(;;)
        +		{
        +		/* If data in output buffer write it first */
        +		while(ctx->ocount)
        +			{
        +			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
        +			if(ret <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				return ret;
        +				}
        +			ctx->optr += ret;
        +			ctx->ocount -= ret;
        +			}
        +		if(ctx->odone) return 1;
        +
        +		/* Compress some more */
        +
        +		/* Reset buffer */
        +		ctx->optr = ctx->obuf;
        +		zout->next_out = ctx->obuf;
        +		zout->avail_out = ctx->obufsize;
        +		/* Compress some more */
        +		ret = deflate(zout, Z_FINISH);
        +		if(ret == Z_STREAM_END) ctx->odone = 1;
        +		else if(ret != Z_OK)
        +			{
        +			COMPerr(COMP_F_BIO_ZLIB_FLUSH,
        +						COMP_R_ZLIB_DEFLATE_ERROR);
        +			ERR_add_error_data(2, "zlib error:", zError(ret));
        +			return 0;
        +			}
        +		ctx->ocount = ctx->obufsize - zout->avail_out;
        +		}
        +	}
        +
        +static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	BIO_ZLIB_CTX *ctx;
        +	int ret, *ip;
        +	int ibs, obs;
        +	if(!b->next_bio) return 0;
        +	ctx = (BIO_ZLIB_CTX *)b->ptr;
        +	switch (cmd)
        +		{
        +
        +	case BIO_CTRL_RESET:
        +		ctx->ocount = 0;
        +		ctx->odone = 0;
        +		ret = 1;
        +		break;
        +
        +	case BIO_CTRL_FLUSH:
        +		ret = bio_zlib_flush(b);
        +		if (ret > 0)
        +			ret = BIO_flush(b->next_bio);
        +		break;
        +
        +	case BIO_C_SET_BUFF_SIZE:
        +		ibs = -1;
        +		obs = -1;
        +		if (ptr != NULL)
        +			{
        +			ip = ptr;
        +			if (*ip == 0)
        +				ibs = (int) num;
        +			else 
        +				obs = (int) num;
        +			}
        +		else
        +			{
        +			ibs = (int)num;
        +			obs = ibs;
        +			}
        +
        +		if (ibs != -1)
        +			{
        +			if (ctx->ibuf)
        +				{
        +				OPENSSL_free(ctx->ibuf);
        +				ctx->ibuf = NULL;
        +				}
        +			ctx->ibufsize = ibs;
        +			}
        +
        +		if (obs != -1)
        +			{
        +			if (ctx->obuf)
        +				{
        +				OPENSSL_free(ctx->obuf);
        +				ctx->obuf = NULL;
        +				}
        +			ctx->obufsize = obs;
        +			}
        +		ret = 1;
        +		break;
        +
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +
        +	default:
        +		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        +		break;
        +
        +		}
        +
        +	return ret;
        +	}
        +
        +
        +static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
        +	{
        +	if(!b->next_bio)
        +		return 0;
        +	return
        +		BIO_callback_ctrl(b->next_bio, cmd, fp);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/comp/comp.h b/vendor/openssl/openssl/crypto/comp/comp.h
        new file mode 100644
        index 000000000..4b405c7d4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/comp/comp.h
        @@ -0,0 +1,80 @@
        +
        +#ifndef HEADER_COMP_H
        +#define HEADER_COMP_H
        +
        +#include <openssl/crypto.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct comp_ctx_st COMP_CTX;
        +
        +typedef struct comp_method_st
        +	{
        +	int type;		/* NID for compression library */
        +	const char *name;	/* A text string to identify the library */
        +	int (*init)(COMP_CTX *ctx);
        +	void (*finish)(COMP_CTX *ctx);
        +	int (*compress)(COMP_CTX *ctx,
        +			unsigned char *out, unsigned int olen,
        +			unsigned char *in, unsigned int ilen);
        +	int (*expand)(COMP_CTX *ctx,
        +		      unsigned char *out, unsigned int olen,
        +		      unsigned char *in, unsigned int ilen);
        +	/* The following two do NOTHING, but are kept for backward compatibility */
        +	long (*ctrl)(void);
        +	long (*callback_ctrl)(void);
        +	} COMP_METHOD;
        +
        +struct comp_ctx_st
        +	{
        +	COMP_METHOD *meth;
        +	unsigned long compress_in;
        +	unsigned long compress_out;
        +	unsigned long expand_in;
        +	unsigned long expand_out;
        +
        +	CRYPTO_EX_DATA	ex_data;
        +	};
        +
        +
        +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
        +void COMP_CTX_free(COMP_CTX *ctx);
        +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
        +	unsigned char *in, int ilen);
        +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
        +	unsigned char *in, int ilen);
        +COMP_METHOD *COMP_rle(void );
        +COMP_METHOD *COMP_zlib(void );
        +void COMP_zlib_cleanup(void);
        +
        +#ifdef HEADER_BIO_H
        +#ifdef ZLIB
        +BIO_METHOD *BIO_f_zlib(void);
        +#endif
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_COMP_strings(void);
        +
        +/* Error codes for the COMP functions. */
        +
        +/* Function codes. */
        +#define COMP_F_BIO_ZLIB_FLUSH				 99
        +#define COMP_F_BIO_ZLIB_NEW				 100
        +#define COMP_F_BIO_ZLIB_READ				 101
        +#define COMP_F_BIO_ZLIB_WRITE				 102
        +
        +/* Reason codes. */
        +#define COMP_R_ZLIB_DEFLATE_ERROR			 99
        +#define COMP_R_ZLIB_INFLATE_ERROR			 100
        +#define COMP_R_ZLIB_NOT_SUPPORTED			 101
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/comp/comp_err.c b/vendor/openssl/openssl/crypto/comp/comp_err.c
        new file mode 100644
        index 000000000..661c94c3a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/comp/comp_err.c
        @@ -0,0 +1,100 @@
        +/* crypto/comp/comp_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/comp.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason)
        +
        +static ERR_STRING_DATA COMP_str_functs[]=
        +	{
        +{ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH),	"BIO_ZLIB_FLUSH"},
        +{ERR_FUNC(COMP_F_BIO_ZLIB_NEW),	"BIO_ZLIB_NEW"},
        +{ERR_FUNC(COMP_F_BIO_ZLIB_READ),	"BIO_ZLIB_READ"},
        +{ERR_FUNC(COMP_F_BIO_ZLIB_WRITE),	"BIO_ZLIB_WRITE"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA COMP_str_reasons[]=
        +	{
        +{ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR)   ,"zlib deflate error"},
        +{ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR)   ,"zlib inflate error"},
        +{ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED)   ,"zlib not supported"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_COMP_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(COMP_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,COMP_str_functs);
        +		ERR_load_strings(0,COMP_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/comp/comp_lib.c b/vendor/openssl/openssl/crypto/comp/comp_lib.c
        new file mode 100644
        index 000000000..b60ae371e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/comp/comp_lib.c
        @@ -0,0 +1,72 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/objects.h>
        +#include <openssl/comp.h>
        +
        +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth)
        +	{
        +	COMP_CTX *ret;
        +
        +	if ((ret=(COMP_CTX *)OPENSSL_malloc(sizeof(COMP_CTX))) == NULL)
        +		{
        +		/* ZZZZZZZZZZZZZZZZ */
        +		return(NULL);
        +		}
        +	memset(ret,0,sizeof(COMP_CTX));
        +	ret->meth=meth;
        +	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
        +		{
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +		}
        +	return(ret);
        +	}
        +
        +void COMP_CTX_free(COMP_CTX *ctx)
        +	{
        +	if(ctx == NULL)
        +	    return;
        +
        +	if (ctx->meth->finish != NULL)
        +		ctx->meth->finish(ctx);
        +
        +	OPENSSL_free(ctx);
        +	}
        +
        +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
        +	     unsigned char *in, int ilen)
        +	{
        +	int ret;
        +	if (ctx->meth->compress == NULL)
        +		{
        +		/* ZZZZZZZZZZZZZZZZZ */
        +		return(-1);
        +		}
        +	ret=ctx->meth->compress(ctx,out,olen,in,ilen);
        +	if (ret > 0)
        +		{
        +		ctx->compress_in+=ilen;
        +		ctx->compress_out+=ret;
        +		}
        +	return(ret);
        +	}
        +
        +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
        +	     unsigned char *in, int ilen)
        +	{
        +	int ret;
        +
        +	if (ctx->meth->expand == NULL)
        +		{
        +		/* ZZZZZZZZZZZZZZZZZ */
        +		return(-1);
        +		}
        +	ret=ctx->meth->expand(ctx,out,olen,in,ilen);
        +	if (ret > 0)
        +		{
        +		ctx->expand_in+=ilen;
        +		ctx->expand_out+=ret;
        +		}
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/conf/Makefile b/vendor/openssl/openssl/crypto/conf/Makefile
        new file mode 100644
        index 000000000..78bb32410
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/Makefile
        @@ -0,0 +1,152 @@
        +#
        +# OpenSSL/crypto/conf/Makefile
        +#
        +
        +DIR=	conf
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= conf_err.c conf_lib.c conf_api.c conf_def.c conf_mod.c \
        +	 conf_mall.c conf_sap.c
        +
        +LIBOBJ=	conf_err.o conf_lib.o conf_api.o conf_def.o conf_mod.o \
        +	conf_mall.o conf_sap.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= conf.h conf_api.h
        +HEADER=	conf_def.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +conf_api.o: ../../e_os.h ../../include/openssl/bio.h
        +conf_api.o: ../../include/openssl/conf.h ../../include/openssl/conf_api.h
        +conf_api.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +conf_api.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_api.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +conf_api.o: ../../include/openssl/symhacks.h conf_api.c
        +conf_def.o: ../../e_os.h ../../include/openssl/bio.h
        +conf_def.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +conf_def.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
        +conf_def.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +conf_def.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +conf_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_def.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +conf_def.o: ../../include/openssl/symhacks.h ../cryptlib.h conf_def.c
        +conf_def.o: conf_def.h
        +conf_err.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
        +conf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +conf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +conf_err.o: ../../include/openssl/opensslconf.h
        +conf_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +conf_err.o: ../../include/openssl/symhacks.h conf_err.c
        +conf_lib.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
        +conf_lib.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
        +conf_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +conf_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +conf_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +conf_lib.o: ../../include/openssl/symhacks.h conf_lib.c
        +conf_mall.o: ../../e_os.h ../../include/openssl/asn1.h
        +conf_mall.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +conf_mall.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +conf_mall.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +conf_mall.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +conf_mall.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +conf_mall.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +conf_mall.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +conf_mall.o: ../../include/openssl/objects.h
        +conf_mall.o: ../../include/openssl/opensslconf.h
        +conf_mall.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_mall.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +conf_mall.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +conf_mall.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +conf_mall.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_mall.c
        +conf_mod.o: ../../e_os.h ../../include/openssl/asn1.h
        +conf_mod.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +conf_mod.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +conf_mod.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +conf_mod.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +conf_mod.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +conf_mod.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +conf_mod.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +conf_mod.o: ../../include/openssl/opensslconf.h
        +conf_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_mod.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +conf_mod.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +conf_mod.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +conf_mod.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_mod.c
        +conf_sap.o: ../../e_os.h ../../include/openssl/asn1.h
        +conf_sap.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +conf_sap.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +conf_sap.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +conf_sap.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +conf_sap.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +conf_sap.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +conf_sap.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +conf_sap.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +conf_sap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +conf_sap.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +conf_sap.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +conf_sap.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +conf_sap.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_sap.c
        diff --git a/vendor/openssl/openssl/crypto/conf/README b/vendor/openssl/openssl/crypto/conf/README
        new file mode 100644
        index 000000000..96e53b34e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/README
        @@ -0,0 +1,73 @@
        +Configuration modules. These are a set of modules which can perform
        +various configuration functions.
        +
        +Currently the routines should be called at most once when an application
        +starts up: that is before it starts any threads.
        +
        +The routines read a configuration file set up like this:
        +
        +-----
        +#default section
        +openssl_conf=init_section
        +
        +[init_section]
        +
        +module1=value1
        +#Second instance of module1
        +module1.1=valueX
        +module2=value2
        +module3=dso_literal
        +module4=dso_section
        +
        +[dso_section]
        +
        +path=/some/path/to/some/dso.so
        +other_stuff=other_value
        +----
        +
        +When this file is loaded a configuration module with the specified string
        +(module* in the above example) is looked up and its init function called as:
        +
        +int conf_init_func(CONF_IMODULE *md, CONF *cnf);
        +
        +The function can then take whatever action is appropriate, for example further
        +lookups based on the value. Multiple instances of the same config module can be
        +loaded.
        +
        +When the application closes down the modules are cleaned up by calling an
        +optional finish function:
        +
        +void conf_finish_func(CONF_IMODULE *md);
        +
        +The finish functions are called in reverse order: that is the last module
        +loaded is the first one cleaned up.
        +
        +If no module exists with a given name then an attempt is made to load a DSO
        +with the supplied name. This might mean that "module3" attempts to load a DSO
        +called libmodule3.so or module3.dll for example. An explicit DSO name can be
        +given by including a separate section as in the module4 example above.
        +
        +The DSO is expected to at least contain an initialization function:
        +
        +int OPENSSL_init(CONF_IMODULE *md, CONF *cnf);
        +
        +and may also include a finish function:
        +
        +void OPENSSL_finish(CONF_IMODULE *md);
        +
        +Static modules can also be added using,
        +
        +int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func
        +*ffunc);
        +
        +where "name" is the name in the configuration file this function corresponds
        +to.
        +
        +A set of builtin modules (currently only an ASN1 non functional test module)
        +can be added by calling OPENSSL_load_builtin_modules(). 
        +
        +The function OPENSSL_config() is intended as a simple configuration function
        +that any application can call to perform various default configuration tasks.
        +It uses the file openssl.cnf in the usual locations.
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/cnf_save.c b/vendor/openssl/openssl/crypto/conf/cnf_save.c
        new file mode 100644
        index 000000000..143948752
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/cnf_save.c
        @@ -0,0 +1,106 @@
        +/* crypto/conf/cnf_save.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/conf.h>
        +
        +static void print_conf(CONF_VALUE *cv);
        +static IMPLEMENT_LHASH_DOALL_FN(print_conf, CONF_VALUE *);
        +
        +main()
        +	{
        +	LHASH *conf;
        +	long l;
        +
        +	conf=CONF_load(NULL,"../../apps/openssl.cnf",&l);
        +	if (conf == NULL)
        +		{
        +		fprintf(stderr,"error loading config, line %ld\n",l);
        +		exit(1);
        +		}
        +
        +	lh_doall(conf,LHASH_DOALL_FN(print_conf));
        +	}
        +
        +
        +static void print_conf(CONF_VALUE *cv)
        +	{
        +	int i;
        +	CONF_VALUE *v;
        +	char *section;
        +	char *name;
        +	char *value;
        +	STACK *s;
        +
        +	/* If it is a single entry, return */
        +
        +	if (cv->name != NULL) return;
        +
        +	printf("[ %s ]\n",cv->section);
        +	s=(STACK *)cv->value;
        +
        +	for (i=0; i<sk_num(s); i++)
        +		{
        +		v=(CONF_VALUE *)sk_value(s,i);
        +		section=(v->section == NULL)?"None":v->section;
        +		name=(v->name == NULL)?"None":v->name;
        +		value=(v->value == NULL)?"None":v->value;
        +		printf("%s=%s\n",name,value);
        +		}
        +	printf("\n");
        +	}
        diff --git a/vendor/openssl/openssl/crypto/conf/conf.h b/vendor/openssl/openssl/crypto/conf/conf.h
        new file mode 100644
        index 000000000..c2199978a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf.h
        @@ -0,0 +1,263 @@
        +/* crypto/conf/conf.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_H
        +#define HEADER_CONF_H
        +
        +#include <openssl/bio.h>
        +#include <openssl/lhash.h>
        +#include <openssl/stack.h>
        +#include <openssl/safestack.h>
        +#include <openssl/e_os2.h>
        +
        +#include <openssl/ossl_typ.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct
        +	{
        +	char *section;
        +	char *name;
        +	char *value;
        +	} CONF_VALUE;
        +
        +DECLARE_STACK_OF(CONF_VALUE)
        +DECLARE_LHASH_OF(CONF_VALUE);
        +
        +struct conf_st;
        +struct conf_method_st;
        +typedef struct conf_method_st CONF_METHOD;
        +
        +struct conf_method_st
        +	{
        +	const char *name;
        +	CONF *(*create)(CONF_METHOD *meth);
        +	int (*init)(CONF *conf);
        +	int (*destroy)(CONF *conf);
        +	int (*destroy_data)(CONF *conf);
        +	int (*load_bio)(CONF *conf, BIO *bp, long *eline);
        +	int (*dump)(const CONF *conf, BIO *bp);
        +	int (*is_number)(const CONF *conf, char c);
        +	int (*to_int)(const CONF *conf, char c);
        +	int (*load)(CONF *conf, const char *name, long *eline);
        +	};
        +
        +/* Module definitions */
        +
        +typedef struct conf_imodule_st CONF_IMODULE;
        +typedef struct conf_module_st CONF_MODULE;
        +
        +DECLARE_STACK_OF(CONF_MODULE)
        +DECLARE_STACK_OF(CONF_IMODULE)
        +
        +/* DSO module function typedefs */
        +typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
        +typedef void conf_finish_func(CONF_IMODULE *md);
        +
        +#define	CONF_MFLAGS_IGNORE_ERRORS	0x1
        +#define CONF_MFLAGS_IGNORE_RETURN_CODES	0x2
        +#define CONF_MFLAGS_SILENT		0x4
        +#define CONF_MFLAGS_NO_DSO		0x8
        +#define CONF_MFLAGS_IGNORE_MISSING_FILE	0x10
        +#define CONF_MFLAGS_DEFAULT_SECTION	0x20
        +
        +int CONF_set_default_method(CONF_METHOD *meth);
        +void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash);
        +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file,
        +				long *eline);
        +#ifndef OPENSSL_NO_FP_API
        +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
        +				   long *eline);
        +#endif
        +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline);
        +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
        +				       const char *section);
        +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
        +		      const char *name);
        +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
        +		     const char *name);
        +void CONF_free(LHASH_OF(CONF_VALUE) *conf);
        +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
        +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
        +
        +void OPENSSL_config(const char *config_name);
        +void OPENSSL_no_config(void);
        +
        +/* New conf code.  The semantics are different from the functions above.
        +   If that wasn't the case, the above functions would have been replaced */
        +
        +struct conf_st
        +	{
        +	CONF_METHOD *meth;
        +	void *meth_data;
        +	LHASH_OF(CONF_VALUE) *data;
        +	};
        +
        +CONF *NCONF_new(CONF_METHOD *meth);
        +CONF_METHOD *NCONF_default(void);
        +CONF_METHOD *NCONF_WIN32(void);
        +#if 0 /* Just to give you an idea of what I have in mind */
        +CONF_METHOD *NCONF_XML(void);
        +#endif
        +void NCONF_free(CONF *conf);
        +void NCONF_free_data(CONF *conf);
        +
        +int NCONF_load(CONF *conf,const char *file,long *eline);
        +#ifndef OPENSSL_NO_FP_API
        +int NCONF_load_fp(CONF *conf, FILE *fp,long *eline);
        +#endif
        +int NCONF_load_bio(CONF *conf, BIO *bp,long *eline);
        +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section);
        +char *NCONF_get_string(const CONF *conf,const char *group,const char *name);
        +int NCONF_get_number_e(const CONF *conf,const char *group,const char *name,
        +		       long *result);
        +int NCONF_dump_fp(const CONF *conf, FILE *out);
        +int NCONF_dump_bio(const CONF *conf, BIO *out);
        +
        +#if 0 /* The following function has no error checking,
        +	 and should therefore be avoided */
        +long NCONF_get_number(CONF *conf,char *group,char *name);
        +#else
        +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
        +#endif
        +  
        +/* Module functions */
        +
        +int CONF_modules_load(const CONF *cnf, const char *appname,
        +		      unsigned long flags);
        +int CONF_modules_load_file(const char *filename, const char *appname,
        +			   unsigned long flags);
        +void CONF_modules_unload(int all);
        +void CONF_modules_finish(void);
        +void CONF_modules_free(void);
        +int CONF_module_add(const char *name, conf_init_func *ifunc,
        +		    conf_finish_func *ffunc);
        +
        +const char *CONF_imodule_get_name(const CONF_IMODULE *md);
        +const char *CONF_imodule_get_value(const CONF_IMODULE *md);
        +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
        +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
        +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
        +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
        +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
        +void *CONF_module_get_usr_data(CONF_MODULE *pmod);
        +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
        +
        +char *CONF_get1_default_config_file(void);
        +
        +int CONF_parse_list(const char *list, int sep, int nospc,
        +	int (*list_cb)(const char *elem, int len, void *usr), void *arg);
        +
        +void OPENSSL_load_builtin_modules(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.
        + */
        +void ERR_load_CONF_strings(void);
        +
        +/* Error codes for the CONF functions. */
        +
        +/* Function codes. */
        +#define CONF_F_CONF_DUMP_FP				 104
        +#define CONF_F_CONF_LOAD				 100
        +#define CONF_F_CONF_LOAD_BIO				 102
        +#define CONF_F_CONF_LOAD_FP				 103
        +#define CONF_F_CONF_MODULES_LOAD			 116
        +#define CONF_F_CONF_PARSE_LIST				 119
        +#define CONF_F_DEF_LOAD					 120
        +#define CONF_F_DEF_LOAD_BIO				 121
        +#define CONF_F_MODULE_INIT				 115
        +#define CONF_F_MODULE_LOAD_DSO				 117
        +#define CONF_F_MODULE_RUN				 118
        +#define CONF_F_NCONF_DUMP_BIO				 105
        +#define CONF_F_NCONF_DUMP_FP				 106
        +#define CONF_F_NCONF_GET_NUMBER				 107
        +#define CONF_F_NCONF_GET_NUMBER_E			 112
        +#define CONF_F_NCONF_GET_SECTION			 108
        +#define CONF_F_NCONF_GET_STRING				 109
        +#define CONF_F_NCONF_LOAD				 113
        +#define CONF_F_NCONF_LOAD_BIO				 110
        +#define CONF_F_NCONF_LOAD_FP				 114
        +#define CONF_F_NCONF_NEW				 111
        +#define CONF_F_STR_COPY					 101
        +
        +/* Reason codes. */
        +#define CONF_R_ERROR_LOADING_DSO			 110
        +#define CONF_R_LIST_CANNOT_BE_NULL			 115
        +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
        +#define CONF_R_MISSING_EQUAL_SIGN			 101
        +#define CONF_R_MISSING_FINISH_FUNCTION			 111
        +#define CONF_R_MISSING_INIT_FUNCTION			 112
        +#define CONF_R_MODULE_INITIALIZATION_ERROR		 109
        +#define CONF_R_NO_CLOSE_BRACE				 102
        +#define CONF_R_NO_CONF					 105
        +#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE		 106
        +#define CONF_R_NO_SECTION				 107
        +#define CONF_R_NO_SUCH_FILE				 114
        +#define CONF_R_NO_VALUE					 108
        +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION		 103
        +#define CONF_R_UNKNOWN_MODULE_NAME			 113
        +#define CONF_R_VARIABLE_HAS_NO_VALUE			 104
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_api.c b/vendor/openssl/openssl/crypto/conf/conf_api.c
        new file mode 100644
        index 000000000..f5fcbb9f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_api.c
        @@ -0,0 +1,301 @@
        +/* 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 <assert.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/conf.h>
        +#include <openssl/conf_api.h>
        +#include "e_os.h"
        +
        +static void value_free_hash_doall_arg(CONF_VALUE *a,
        +				      LHASH_OF(CONF_VALUE) *conf);
        +static void value_free_stack_doall(CONF_VALUE *a);
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
        +				    LHASH_OF(CONF_VALUE))
        +static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
        +
        +/* Up until OpenSSL 0.9.5a, this was get_section */
        +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
        +	{
        +	CONF_VALUE *v,vv;
        +
        +	if ((conf == NULL) || (section == NULL)) return(NULL);
        +	vv.name=NULL;
        +	vv.section=(char *)section;
        +	v=lh_CONF_VALUE_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(const CONF *conf,
        +					       const 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 = lh_CONF_VALUE_insert(conf->data, value);
        +	if (v != NULL)
        +		{
        +		(void)sk_CONF_VALUE_delete_ptr(ts,v);
        +		OPENSSL_free(v->name);
        +		OPENSSL_free(v->value);
        +		OPENSSL_free(v);
        +		}
        +	return 1;
        +	}
        +
        +char *_CONF_get_string(const CONF *conf, const char *section, const char *name)
        +	{
        +	CONF_VALUE *v,vv;
        +	char *p;
        +
        +	if (name == NULL) return(NULL);
        +	if (conf != NULL)
        +		{
        +		if (section != NULL)
        +			{
        +			vv.name=(char *)name;
        +			vv.section=(char *)section;
        +			v=lh_CONF_VALUE_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=(char *)name;
        +		v=lh_CONF_VALUE_retrieve(conf->data,&vv);
        +		if (v != NULL)
        +			return(v->value);
        +		else
        +			return(NULL);
        +		}
        +	else
        +		return(getenv(name));
        +	}
        +
        +#if 0 /* There's no way to provide error checking with this function, so
        +	 force implementors of the higher levels to get a string and read
        +	 the number themselves. */
        +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++;
        +		}
        +	}
        +#endif
        +
        +static unsigned long conf_value_hash(const CONF_VALUE *v)
        +	{
        +	return (lh_strhash(v->section)<<2)^lh_strhash(v->name);
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
        +
        +static int conf_value_cmp(const CONF_VALUE *a, const 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);
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
        +
        +int _CONF_new_data(CONF *conf)
        +	{
        +	if (conf == NULL)
        +		{
        +		return 0;
        +		}
        +	if (conf->data == NULL)
        +		if ((conf->data = lh_CONF_VALUE_new()) == NULL)
        +			{
        +			return 0;
        +			}
        +	return 1;
        +	}
        +
        +void _CONF_free_data(CONF *conf)
        +	{
        +	if (conf == NULL || conf->data == NULL) return;
        +
        +	lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make
        +				  * sure the 'OPENSSL_free()' works as
        +				  * expected */
        +	lh_CONF_VALUE_doall_arg(conf->data,
        +				LHASH_DOALL_ARG_FN(value_free_hash),
        +				LHASH_OF(CONF_VALUE), conf->data);
        +
        +	/* We now have only 'section' entries in the hash table.
        +	 * Due to problems with */
        +
        +	lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
        +	lh_CONF_VALUE_free(conf->data);
        +	}
        +
        +static void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
        +	{
        +	if (a->name != NULL)
        +		(void)lh_CONF_VALUE_delete(conf,a);
        +	}
        +
        +static void value_free_stack_doall(CONF_VALUE *a)
        +	{
        +	CONF_VALUE *vv;
        +	STACK_OF(CONF_VALUE) *sk;
        +	int i;
        +
        +	if (a->name != NULL) return;
        +
        +	sk=(STACK_OF(CONF_VALUE) *)a->value;
        +	for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--)
        +		{
        +		vv=sk_CONF_VALUE_value(sk,i);
        +		OPENSSL_free(vv->value);
        +		OPENSSL_free(vv->name);
        +		OPENSSL_free(vv);
        +		}
        +	if (sk != NULL) sk_CONF_VALUE_free(sk);
        +	OPENSSL_free(a->section);
        +	OPENSSL_free(a);
        +	}
        +
        +/* Up until OpenSSL 0.9.5a, this was new_section */
        +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
        +	{
        +	STACK_OF(CONF_VALUE) *sk=NULL;
        +	int ok=0,i;
        +	CONF_VALUE *v=NULL,*vv;
        +
        +	if ((sk=sk_CONF_VALUE_new_null()) == NULL)
        +		goto err;
        +	if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
        +		goto err;
        +	i=strlen(section)+1;
        +	if ((v->section=OPENSSL_malloc(i)) == NULL)
        +		goto err;
        +
        +	memcpy(v->section,section,i);
        +	v->name=NULL;
        +	v->value=(char *)sk;
        +	
        +	vv=lh_CONF_VALUE_insert(conf->data,v);
        +	OPENSSL_assert(vv == NULL);
        +	ok=1;
        +err:
        +	if (!ok)
        +		{
        +		if (sk != NULL) sk_CONF_VALUE_free(sk);
        +		if (v != NULL) OPENSSL_free(v);
        +		v=NULL;
        +		}
        +	return(v);
        +	}
        +
        +IMPLEMENT_STACK_OF(CONF_VALUE)
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_api.h b/vendor/openssl/openssl/crypto/conf/conf_api.h
        new file mode 100644
        index 000000000..87a954aff
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_api.h
        @@ -0,0 +1,89 @@
        +/* 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 <openssl/lhash.h>
        +#include <openssl/conf.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Up until OpenSSL 0.9.5a, this was new_section */
        +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
        +/* Up until OpenSSL 0.9.5a, this was get_section */
        +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
        +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
        +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
        +					       const char *section);
        +
        +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
        +char *_CONF_get_string(const CONF *conf, const char *section,
        +		       const char *name);
        +long _CONF_get_number(const CONF *conf, const char *section, const char *name);
        +
        +int _CONF_new_data(CONF *conf);
        +void _CONF_free_data(CONF *conf);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_def.c b/vendor/openssl/openssl/crypto/conf/conf_def.c
        new file mode 100644
        index 000000000..cf951320a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_def.c
        @@ -0,0 +1,740 @@
        +/* 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 <stdio.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/stack.h>
        +#include <openssl/lhash.h>
        +#include <openssl/conf.h>
        +#include <openssl/conf_api.h>
        +#include "conf_def.h"
        +#include <openssl/buffer.h>
        +#include <openssl/err.h>
        +
        +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, const char *name, long *eline);
        +static int def_load_bio(CONF *conf, BIO *bp, long *eline);
        +static int def_dump(const CONF *conf, BIO *bp);
        +static int def_is_number(const CONF *conf, char c);
        +static int def_to_int(const 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_bio,
        +	def_dump,
        +	def_is_number,
        +	def_to_int,
        +	def_load
        +	};
        +
        +static CONF_METHOD WIN32_method = {
        +	"WIN32",
        +	def_create,
        +	def_init_WIN32,
        +	def_destroy,
        +	def_destroy_data,
        +	def_load_bio,
        +	def_dump,
        +	def_is_number,
        +	def_to_int,
        +	def_load
        +	};
        +
        +CONF_METHOD *NCONF_default()
        +	{
        +	return &default_method;
        +	}
        +CONF_METHOD *NCONF_WIN32()
        +	{
        +	return &WIN32_method;
        +	}
        +
        +static CONF *def_create(CONF_METHOD *meth)
        +	{
        +	CONF *ret;
        +
        +	ret = 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 = 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, const char *name, long *line)
        +	{
        +	int ret;
        +	BIO *in=NULL;
        +
        +#ifdef OPENSSL_SYS_VMS
        +	in=BIO_new_file(name, "r");
        +#else
        +	in=BIO_new_file(name, "rb");
        +#endif
        +	if (in == NULL)
        +		{
        +		if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
        +			CONFerr(CONF_F_DEF_LOAD,CONF_R_NO_SUCH_FILE);
        +		else
        +			CONFerr(CONF_F_DEF_LOAD,ERR_R_SYS_LIB);
        +		return 0;
        +		}
        +
        +	ret = def_load_bio(conf, in, line);
        +	BIO_free(in);
        +
        +	return ret;
        +	}
        +
        +static int def_load_bio(CONF *conf, BIO *in, long *line)
        +	{
        +/* The macro BUFSIZE conflicts with a system macro in VxWorks */
        +#define CONFBUFSIZE	512
        +	int bufnum=0,i,ii;
        +	BUF_MEM *buff=NULL;
        +	char *s,*p,*end;
        +	int again;
        +	long eline=0;
        +	char btmp[DECIMAL_SIZE(eline)+1];
        +	CONF_VALUE *v=NULL,*tv;
        +	CONF_VALUE *sv=NULL;
        +	char *section=NULL,*buf;
        +	char *start,*psection,*pname;
        +	void *h = (void *)(conf->data);
        +
        +	if ((buff=BUF_MEM_new()) == NULL)
        +		{
        +		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
        +		goto err;
        +		}
        +
        +	section=(char *)OPENSSL_malloc(10);
        +	if (section == NULL)
        +		{
        +		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	BUF_strlcpy(section,"default",10);
        +
        +	if (_CONF_new_data(conf) == 0)
        +		{
        +		CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	sv=_CONF_new_section(conf,section);
        +	if (sv == NULL)
        +		{
        +		CONFerr(CONF_F_DEF_LOAD_BIO,
        +					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
        +		goto err;
        +		}
        +
        +	bufnum=0;
        +	again=0;
        +	for (;;)
        +		{
        +		if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE))
        +			{
        +			CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB);
        +			goto err;
        +			}
        +		p= &(buff->data[bufnum]);
        +		*p='\0';
        +		BIO_gets(in, p, CONFBUFSIZE-1);
        +		p[CONFBUFSIZE-1]='\0';
        +		ii=i=strlen(p);
        +		if (i == 0 && !again) break;
        +		again=0;
        +		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 (ii && 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);
        +		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_DEF_LOAD_BIO,
        +					CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
        +				goto err;
        +				}
        +			*end='\0';
        +			if (!str_copy(conf,NULL,&section,start)) goto err;
        +			if ((sv=_CONF_get_section(conf,section)) == NULL)
        +				sv=_CONF_new_section(conf,section);
        +			if (sv == NULL)
        +				{
        +				CONFerr(CONF_F_DEF_LOAD_BIO,
        +					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
        +				goto err;
        +				}
        +			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_DEF_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_DEF_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_DEF_LOAD_BIO,
        +							ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			BUF_strlcpy(v->name,pname,strlen(pname)+1);
        +			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_DEF_LOAD_BIO,
        +					   CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
        +					goto err;
        +					}
        +				}
        +			else
        +				tv=sv;
        +#if 1
        +			if (_CONF_add_string(conf, tv, v) == 0)
        +				{
        +				CONFerr(CONF_F_DEF_LOAD_BIO,
        +							ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +#else
        +			v->section=tv->section;	
        +			if (!sk_CONF_VALUE_push(ts,v))
        +				{
        +				CONFerr(CONF_F_DEF_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;
        +	BIO_snprintf(btmp,sizeof btmp,"%ld",eline);
        +	ERR_add_error_data(2,"line ",btmp);
        +	if ((h != conf->data) && (conf->data != NULL))
        +		{
        +		CONF_free(conf->data);
        +		conf->data=NULL;
        +		}
        +	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)
        +	{
        +	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
        +			 * np which is the start of the name string which is
        +			 *   '\0' terminated. 
        +			 * cp which is the start of the section string which is
        +			 *   '\0' terminated.
        +			 * e is the 'next point after'.
        +			 * r and rr are the chars replaced by the '\0'
        +			 * rp and rrp is where 'r' and 'rr' 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_clean(buf,(strlen(p)+buf->length-(e-from)));
        +			while (*p)
        +				buf->data[to++]= *(p++);
        +
        +			/* Since we change the pointer 'from', we also have
        +			   to change the perceived length of the string it
        +			   points at.  /RL */
        +			len -= e-from;
        +			from=e;
        +
        +			/* In case there were no braces or parenthesis around
        +			   the variable reference, we have to put back the
        +			   character that was replaced with a '\0'.  /RL */
        +			*rp = r;
        +			}
        +		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_doall_arg(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 IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
        +
        +static int def_dump(const CONF *conf, BIO *out)
        +	{
        +	lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
        +				BIO, out);
        +	return 1;
        +	}
        +
        +static int def_is_number(const CONF *conf, char c)
        +	{
        +	return IS_NUMBER(conf,c);
        +	}
        +
        +static int def_to_int(const CONF *conf, char c)
        +	{
        +	return c - '0';
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_def.h b/vendor/openssl/openssl/crypto/conf/conf_def.h
        new file mode 100644
        index 000000000..92a7d8ad7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_def.h
        @@ -0,0 +1,180 @@
        +/* 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_HIGHBIT		4096
        +#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)&0xff]&CONF_COMMENT)
        +#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
        +#define IS_EOF(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_EOF)
        +#define IS_ESC(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_ESC)
        +#define IS_NUMBER(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
        +#define IS_WS(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_WS)
        +#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
        +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \
        +				(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
        +#define IS_QUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
        +#define IS_DQUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
        +#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
        +
        +#else /*CHARSET_EBCDIC*/
        +
        +#define IS_COMMENT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
        +#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
        +#define IS_EOF(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
        +#define IS_ESC(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
        +#define IS_NUMBER(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
        +#define IS_WS(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
        +#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
        +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \
        +				(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
        +#define IS_QUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
        +#define IS_DQUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
        +#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
        +#endif /*CHARSET_EBCDIC*/
        +
        +static unsigned short CONF_type_default[256]={
        +	0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
        +	0x0000,0x0010,0x0010,0x0000,0x0000,0x0010,0x0000,0x0000,
        +	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
        +	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
        +	0x0010,0x0200,0x0040,0x0080,0x0000,0x0200,0x0200,0x0040,
        +	0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,
        +	0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
        +	0x0001,0x0001,0x0000,0x0200,0x0000,0x0000,0x0000,0x0200,
        +	0x0200,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
        +	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
        +	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
        +	0x0002,0x0002,0x0002,0x0000,0x0020,0x0000,0x0200,0x0100,
        +	0x0040,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
        +	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
        +	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
        +	0x0004,0x0004,0x0004,0x0000,0x0200,0x0000,0x0200,0x0000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	};
        +
        +static unsigned short CONF_type_win32[256]={
        +	0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
        +	0x0000,0x0010,0x0010,0x0000,0x0000,0x0010,0x0000,0x0000,
        +	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
        +	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
        +	0x0010,0x0200,0x0400,0x0000,0x0000,0x0200,0x0200,0x0000,
        +	0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,
        +	0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
        +	0x0001,0x0001,0x0000,0x0A00,0x0000,0x0000,0x0000,0x0200,
        +	0x0200,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
        +	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
        +	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
        +	0x0002,0x0002,0x0002,0x0000,0x0000,0x0000,0x0200,0x0100,
        +	0x0000,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
        +	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
        +	0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
        +	0x0004,0x0004,0x0004,0x0000,0x0200,0x0000,0x0200,0x0000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_err.c b/vendor/openssl/openssl/crypto/conf/conf_err.c
        new file mode 100644
        index 000000000..25bb5dc9a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_err.c
        @@ -0,0 +1,131 @@
        +/* crypto/conf/conf_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/conf.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason)
        +
        +static ERR_STRING_DATA CONF_str_functs[]=
        +	{
        +{ERR_FUNC(CONF_F_CONF_DUMP_FP),	"CONF_dump_fp"},
        +{ERR_FUNC(CONF_F_CONF_LOAD),	"CONF_load"},
        +{ERR_FUNC(CONF_F_CONF_LOAD_BIO),	"CONF_load_bio"},
        +{ERR_FUNC(CONF_F_CONF_LOAD_FP),	"CONF_load_fp"},
        +{ERR_FUNC(CONF_F_CONF_MODULES_LOAD),	"CONF_modules_load"},
        +{ERR_FUNC(CONF_F_CONF_PARSE_LIST),	"CONF_parse_list"},
        +{ERR_FUNC(CONF_F_DEF_LOAD),	"DEF_LOAD"},
        +{ERR_FUNC(CONF_F_DEF_LOAD_BIO),	"DEF_LOAD_BIO"},
        +{ERR_FUNC(CONF_F_MODULE_INIT),	"MODULE_INIT"},
        +{ERR_FUNC(CONF_F_MODULE_LOAD_DSO),	"MODULE_LOAD_DSO"},
        +{ERR_FUNC(CONF_F_MODULE_RUN),	"MODULE_RUN"},
        +{ERR_FUNC(CONF_F_NCONF_DUMP_BIO),	"NCONF_dump_bio"},
        +{ERR_FUNC(CONF_F_NCONF_DUMP_FP),	"NCONF_dump_fp"},
        +{ERR_FUNC(CONF_F_NCONF_GET_NUMBER),	"NCONF_get_number"},
        +{ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E),	"NCONF_get_number_e"},
        +{ERR_FUNC(CONF_F_NCONF_GET_SECTION),	"NCONF_get_section"},
        +{ERR_FUNC(CONF_F_NCONF_GET_STRING),	"NCONF_get_string"},
        +{ERR_FUNC(CONF_F_NCONF_LOAD),	"NCONF_load"},
        +{ERR_FUNC(CONF_F_NCONF_LOAD_BIO),	"NCONF_load_bio"},
        +{ERR_FUNC(CONF_F_NCONF_LOAD_FP),	"NCONF_load_fp"},
        +{ERR_FUNC(CONF_F_NCONF_NEW),	"NCONF_new"},
        +{ERR_FUNC(CONF_F_STR_COPY),	"STR_COPY"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CONF_str_reasons[]=
        +	{
        +{ERR_REASON(CONF_R_ERROR_LOADING_DSO)    ,"error loading dso"},
        +{ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL)  ,"list cannot be null"},
        +{ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),"missing close square bracket"},
        +{ERR_REASON(CONF_R_MISSING_EQUAL_SIGN)   ,"missing equal sign"},
        +{ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION),"missing finish function"},
        +{ERR_REASON(CONF_R_MISSING_INIT_FUNCTION),"missing init function"},
        +{ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR),"module initialization error"},
        +{ERR_REASON(CONF_R_NO_CLOSE_BRACE)       ,"no close brace"},
        +{ERR_REASON(CONF_R_NO_CONF)              ,"no conf"},
        +{ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE),"no conf or environment variable"},
        +{ERR_REASON(CONF_R_NO_SECTION)           ,"no section"},
        +{ERR_REASON(CONF_R_NO_SUCH_FILE)         ,"no such file"},
        +{ERR_REASON(CONF_R_NO_VALUE)             ,"no value"},
        +{ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),"unable to create new section"},
        +{ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME)  ,"unknown module name"},
        +{ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE),"variable has no value"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_CONF_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(CONF_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,CONF_str_functs);
        +		ERR_load_strings(0,CONF_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_lib.c b/vendor/openssl/openssl/crypto/conf/conf_lib.c
        new file mode 100644
        index 000000000..54046defc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_lib.c
        @@ -0,0 +1,407 @@
        +/* 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 <stdio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/conf.h>
        +#include <openssl/conf_api.h>
        +#include <openssl/lhash.h>
        +
        +const char CONF_version[]="CONF" OPENSSL_VERSION_PTEXT;
        +
        +static CONF_METHOD *default_CONF_method=NULL;
        +
        +/* Init a 'CONF' structure from an old LHASH */
        +
        +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
        +	{
        +	if (default_CONF_method == NULL)
        +		default_CONF_method = NCONF_default();
        +
        +	default_CONF_method->init(conf);
        +	conf->data = hash;
        +	}
        +
        +/* 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_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
        +				long *eline)
        +	{
        +	LHASH_OF(CONF_VALUE) *ltmp;
        +	BIO *in=NULL;
        +
        +#ifdef OPENSSL_SYS_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 OPENSSL_NO_FP_API
        +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
        +				   long *eline)
        +	{
        +	BIO *btmp;
        +	LHASH_OF(CONF_VALUE) *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_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
        +				    long *eline)
        +	{
        +	CONF ctmp;
        +	int ret;
        +
        +	CONF_set_nconf(&ctmp, conf);
        +
        +	ret = NCONF_load_bio(&ctmp, bp, eline);
        +	if (ret)
        +		return ctmp.data;
        +	return NULL;
        +	}
        +
        +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
        +				       const char *section)
        +	{
        +	if (conf == NULL)
        +		{
        +		return NULL;
        +		}
        +	else
        +		{
        +		CONF ctmp;
        +		CONF_set_nconf(&ctmp, conf);
        +		return NCONF_get_section(&ctmp, section);
        +		}
        +	}
        +
        +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
        +		      const char *name)
        +	{
        +	if (conf == NULL)
        +		{
        +		return NCONF_get_string(NULL, group, name);
        +		}
        +	else
        +		{
        +		CONF ctmp;
        +		CONF_set_nconf(&ctmp, conf);
        +		return NCONF_get_string(&ctmp, group, name);
        +		}
        +	}
        +
        +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
        +		     const char *name)
        +	{
        +	int status;
        +	long result = 0;
        +
        +	if (conf == NULL)
        +		{
        +		status = NCONF_get_number_e(NULL, group, name, &result);
        +		}
        +	else
        +		{
        +		CONF ctmp;
        +		CONF_set_nconf(&ctmp, conf);
        +		status = NCONF_get_number_e(&ctmp, group, name, &result);
        +		}
        +
        +	if (status == 0)
        +		{
        +		/* This function does not believe in errors... */
        +		ERR_clear_error();
        +		}
        +	return result;
        +	}
        +
        +void CONF_free(LHASH_OF(CONF_VALUE) *conf)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, conf);
        +	NCONF_free_data(&ctmp);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *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_OF(CONF_VALUE) *conf, BIO *out)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, 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)
        +	{
        +	if (conf == NULL)
        +		{
        +		CONFerr(CONF_F_NCONF_LOAD,CONF_R_NO_CONF);
        +		return 0;
        +		}
        +
        +	return conf->meth->load(conf, file, eline);
        +	}
        +
        +#ifndef OPENSSL_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_NCONF_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_bio(conf, bp, eline);
        +	}
        +
        +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section)
        +	{
        +	if (conf == NULL)
        +		{
        +		CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_CONF);
        +		return NULL;
        +		}
        +
        +	if (section == NULL)
        +		{
        +		CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_SECTION);
        +		return NULL;
        +		}
        +
        +	return _CONF_get_section_values(conf, section);
        +	}
        +
        +char *NCONF_get_string(const CONF *conf,const char *group,const char *name)
        +	{
        +	char *s = _CONF_get_string(conf, group, name);
        +
        +        /* Since we may get a value from an environment variable even
        +           if conf is NULL, let's check the value first */
        +        if (s) return s;
        +
        +	if (conf == NULL)
        +		{
        +		CONFerr(CONF_F_NCONF_GET_STRING,
        +                        CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
        +		return NULL;
        +		}
        +	CONFerr(CONF_F_NCONF_GET_STRING,
        +		CONF_R_NO_VALUE);
        +	ERR_add_error_data(4,"group=",group," name=",name);
        +	return NULL;
        +	}
        +
        +int NCONF_get_number_e(const CONF *conf,const char *group,const char *name,
        +		       long *result)
        +	{
        +	char *str;
        +
        +	if (result == NULL)
        +		{
        +		CONFerr(CONF_F_NCONF_GET_NUMBER_E,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +
        +	str = NCONF_get_string(conf,group,name);
        +
        +	if (str == NULL)
        +		return 0;
        +
        +	for (*result = 0;conf->meth->is_number(conf, *str);)
        +		{
        +		*result = (*result)*10 + conf->meth->to_int(conf, *str);
        +		str++;
        +		}
        +
        +	return 1;
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int NCONF_dump_fp(const 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(const 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);
        +	}
        +
        +
        +/* This function should be avoided */
        +#if 0
        +long NCONF_get_number(CONF *conf,char *group,char *name)
        +	{
        +	int status;
        +	long ret=0;
        +
        +	status = NCONF_get_number_e(conf, group, name, &ret);
        +	if (status == 0)
        +		{
        +		/* This function does not believe in errors... */
        +		ERR_get_error();
        +		}
        +	return ret;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_mall.c b/vendor/openssl/openssl/crypto/conf/conf_mall.c
        new file mode 100644
        index 000000000..213890e0c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_mall.c
        @@ -0,0 +1,81 @@
        +/* conf_mall.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/dso.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +/* Load all OpenSSL builtin modules */
        +
        +void OPENSSL_load_builtin_modules(void)
        +	{
        +	/* Add builtin modules here */
        +	ASN1_add_oid_module();
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_add_conf_module();
        +#endif
        +	EVP_add_alg_module();
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_mod.c b/vendor/openssl/openssl/crypto/conf/conf_mod.c
        new file mode 100644
        index 000000000..df1642a0a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_mod.c
        @@ -0,0 +1,623 @@
        +/* conf_mod.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <ctype.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/dso.h>
        +#include <openssl/x509.h>
        +
        +
        +#define DSO_mod_init_name "OPENSSL_init"
        +#define DSO_mod_finish_name "OPENSSL_finish"
        +
        +
        +/* This structure contains a data about supported modules.
        + * entries in this table correspond to either dynamic or
        + * static modules.
        + */
        +
        +struct conf_module_st
        +	{
        +	/* DSO of this module or NULL if static */
        +	DSO *dso;
        +	/* Name of the module */
        +	char *name;
        +	/* Init function */
        +	conf_init_func *init; 
        +	/* Finish function */
        +	conf_finish_func *finish;
        +	/* Number of successfully initialized modules */
        +	int links;
        +	void *usr_data;
        +	};
        +
        +
        +/* This structure contains information about modules that have been
        + * successfully initialized. There may be more than one entry for a
        + * given module.
        + */
        +
        +struct conf_imodule_st
        +	{
        +	CONF_MODULE *pmod;
        +	char *name;
        +	char *value;
        +	unsigned long flags;
        +	void *usr_data;
        +	};
        +
        +static STACK_OF(CONF_MODULE) *supported_modules = NULL;
        +static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
        +
        +static void module_free(CONF_MODULE *md);
        +static void module_finish(CONF_IMODULE *imod);
        +static int module_run(const CONF *cnf, char *name, char *value,
        +					  unsigned long flags);
        +static CONF_MODULE *module_add(DSO *dso, const char *name,
        +			conf_init_func *ifunc, conf_finish_func *ffunc);
        +static CONF_MODULE *module_find(char *name);
        +static int module_init(CONF_MODULE *pmod, char *name, char *value,
        +					   const CONF *cnf);
        +static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
        +									unsigned long flags);
        +
        +/* Main function: load modules from a CONF structure */
        +
        +int CONF_modules_load(const CONF *cnf, const char *appname,
        +		      unsigned long flags)
        +	{
        +	STACK_OF(CONF_VALUE) *values;
        +	CONF_VALUE *vl;
        +	char *vsection = NULL;
        +
        +	int ret, i;
        +
        +	if (!cnf)
        +		return 1;
        +
        +	if (appname)
        +		vsection = NCONF_get_string(cnf, NULL, appname);
        +
        +	if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
        +		vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
        +
        +	if (!vsection)
        +		{
        +		ERR_clear_error();
        +		return 1;
        +		}
        +
        +	values = NCONF_get_section(cnf, vsection);
        +
        +	if (!values)
        +		return 0;
        +
        +	for (i = 0; i < sk_CONF_VALUE_num(values); i++)
        +		{
        +		vl = sk_CONF_VALUE_value(values, i);
        +		ret = module_run(cnf, vl->name, vl->value, flags);
        +		if (ret <= 0)
        +			if(!(flags & CONF_MFLAGS_IGNORE_ERRORS))
        +				return ret;
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +int CONF_modules_load_file(const char *filename, const char *appname,
        +			   unsigned long flags)
        +	{
        +	char *file = NULL;
        +	CONF *conf = NULL;
        +	int ret = 0;
        +	conf = NCONF_new(NULL);
        +	if (!conf)
        +		goto err;
        +
        +	if (filename == NULL)
        +		{
        +		file = CONF_get1_default_config_file();
        +		if (!file)
        +			goto err;
        +		}
        +	else
        +		file = (char *)filename;
        +
        +	if (NCONF_load(conf, file, NULL) <= 0)
        +		{
        +		if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
        +		  (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE))
        +			{
        +			ERR_clear_error();
        +			ret = 1;
        +			}
        +		goto err;
        +		}
        +
        +	ret = CONF_modules_load(conf, appname, flags);
        +
        +	err:
        +	if (filename == NULL)
        +		OPENSSL_free(file);
        +	NCONF_free(conf);
        +
        +	return ret;
        +	}
        +
        +static int module_run(const CONF *cnf, char *name, char *value,
        +		      unsigned long flags)
        +	{
        +	CONF_MODULE *md;
        +	int ret;
        +
        +	md = module_find(name);
        +
        +	/* Module not found: try to load DSO */
        +	if (!md && !(flags & CONF_MFLAGS_NO_DSO))
        +		md = module_load_dso(cnf, name, value, flags);
        +
        +	if (!md)
        +		{
        +		if (!(flags & CONF_MFLAGS_SILENT))
        +			{
        +			CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
        +			ERR_add_error_data(2, "module=", name);
        +			}
        +		return -1;
        +		}
        +
        +	ret = module_init(md, name, value, cnf);
        +
        +	if (ret <= 0)
        +		{
        +		if (!(flags & CONF_MFLAGS_SILENT))
        +			{
        +			char rcode[DECIMAL_SIZE(ret)+1];
        +			CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
        +			BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
        +			ERR_add_error_data(6, "module=", name, ", value=", value, ", retcode=", rcode);
        +			}
        +		}
        +
        +	return ret;
        +	}
        +
        +/* Load a module from a DSO */
        +static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
        +				    unsigned long flags)
        +	{
        +	DSO *dso = NULL;
        +	conf_init_func *ifunc;
        +	conf_finish_func *ffunc;
        +	char *path = NULL;
        +	int errcode = 0;
        +	CONF_MODULE *md;
        +	/* Look for alternative path in module section */
        +	path = NCONF_get_string(cnf, value, "path");
        +	if (!path)
        +		{
        +		ERR_clear_error();
        +		path = name;
        +		}
        +	dso = DSO_load(NULL, path, NULL, 0);
        +	if (!dso)
        +		{
        +		errcode = CONF_R_ERROR_LOADING_DSO;
        +		goto err;
        +		}
        +        ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
        +	if (!ifunc)
        +		{
        +		errcode = CONF_R_MISSING_INIT_FUNCTION;
        +		goto err;
        +		}
        +        ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
        +	/* All OK, add module */
        +	md = module_add(dso, name, ifunc, ffunc);
        +
        +	if (!md)
        +		goto err;
        +
        +	return md;
        +
        +	err:
        +	if (dso)
        +		DSO_free(dso);
        +	CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
        +	ERR_add_error_data(4, "module=", name, ", path=", path);
        +	return NULL;
        +	}
        +
        +/* add module to list */
        +static CONF_MODULE *module_add(DSO *dso, const char *name,
        +			       conf_init_func *ifunc, conf_finish_func *ffunc)
        +	{
        +	CONF_MODULE *tmod = NULL;
        +	if (supported_modules == NULL)
        +		supported_modules = sk_CONF_MODULE_new_null();
        +	if (supported_modules == NULL)
        +		return NULL;
        +	tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
        +	if (tmod == NULL)
        +		return NULL;
        +
        +	tmod->dso = dso;
        +	tmod->name = BUF_strdup(name);
        +	tmod->init = ifunc;
        +	tmod->finish = ffunc;
        +	tmod->links = 0;
        +
        +	if (!sk_CONF_MODULE_push(supported_modules, tmod))
        +		{
        +		OPENSSL_free(tmod);
        +		return NULL;
        +		}
        +
        +	return tmod;
        +	}
        +
        +/* Find a module from the list. We allow module names of the
        + * form modname.XXXX to just search for modname to allow the
        + * same module to be initialized more than once.
        + */
        +
        +static CONF_MODULE *module_find(char *name)
        +	{
        +	CONF_MODULE *tmod;
        +	int i, nchar;
        +	char *p;
        +	p = strrchr(name, '.');
        +
        +	if (p)
        +		nchar = p - name;
        +	else 
        +		nchar = strlen(name);
        +
        +	for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++)
        +		{
        +		tmod = sk_CONF_MODULE_value(supported_modules, i);
        +		if (!strncmp(tmod->name, name, nchar))
        +			return tmod;
        +		}
        +
        +	return NULL;
        +
        +	}
        +
        +/* initialize a module */
        +static int module_init(CONF_MODULE *pmod, char *name, char *value,
        +		       const CONF *cnf)
        +	{
        +	int ret = 1;
        +	int init_called = 0;
        +	CONF_IMODULE *imod = NULL;
        +
        +	/* Otherwise add initialized module to list */
        +	imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
        +	if (!imod)
        +		goto err;
        +
        +	imod->pmod = pmod;
        +	imod->name = BUF_strdup(name);
        +	imod->value = BUF_strdup(value);
        +	imod->usr_data = NULL;
        +
        +	if (!imod->name || !imod->value)
        +		goto memerr;
        +
        +	/* Try to initialize module */
        +	if(pmod->init)
        +		{
        +		ret = pmod->init(imod, cnf);
        +		init_called = 1;
        +		/* Error occurred, exit */
        +		if (ret <= 0)
        +			goto err;
        +		}
        +
        +	if (initialized_modules == NULL)
        +		{
        +		initialized_modules = sk_CONF_IMODULE_new_null();
        +		if (!initialized_modules)
        +			{
        +			CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +
        +	if (!sk_CONF_IMODULE_push(initialized_modules, imod))
        +		{
        +		CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	pmod->links++;
        +
        +	return ret;
        +
        +	err:
        +
        +	/* We've started the module so we'd better finish it */
        +	if (pmod->finish && init_called)
        +		pmod->finish(imod);
        +
        +	memerr:
        +	if (imod)
        +		{
        +		if (imod->name)
        +			OPENSSL_free(imod->name);
        +		if (imod->value)
        +			OPENSSL_free(imod->value);
        +		OPENSSL_free(imod);
        +		}
        +
        +	return -1;
        +
        +	}
        +
        +/* Unload any dynamic modules that have a link count of zero:
        + * i.e. have no active initialized modules. If 'all' is set
        + * then all modules are unloaded including static ones.
        + */
        +
        +void CONF_modules_unload(int all)
        +	{
        +	int i;
        +	CONF_MODULE *md;
        +	CONF_modules_finish();
        +	/* unload modules in reverse order */
        +	for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--)
        +		{
        +		md = sk_CONF_MODULE_value(supported_modules, i);
        +		/* If static or in use and 'all' not set ignore it */
        +		if (((md->links > 0) || !md->dso) && !all)
        +			continue;
        +		/* Since we're working in reverse this is OK */
        +		(void)sk_CONF_MODULE_delete(supported_modules, i);
        +		module_free(md);
        +		}
        +	if (sk_CONF_MODULE_num(supported_modules) == 0)
        +		{
        +		sk_CONF_MODULE_free(supported_modules);
        +		supported_modules = NULL;
        +		}
        +	}
        +
        +/* unload a single module */
        +static void module_free(CONF_MODULE *md)
        +	{
        +	if (md->dso)
        +		DSO_free(md->dso);
        +	OPENSSL_free(md->name);
        +	OPENSSL_free(md);
        +	}
        +
        +/* finish and free up all modules instances */
        +
        +void CONF_modules_finish(void)
        +	{
        +	CONF_IMODULE *imod;
        +	while (sk_CONF_IMODULE_num(initialized_modules) > 0)
        +		{
        +		imod = sk_CONF_IMODULE_pop(initialized_modules);
        +		module_finish(imod);
        +		}
        +	sk_CONF_IMODULE_free(initialized_modules);
        +	initialized_modules = NULL;
        +	}
        +
        +/* finish a module instance */
        +
        +static void module_finish(CONF_IMODULE *imod)
        +	{
        +	if (imod->pmod->finish)
        +		imod->pmod->finish(imod);
        +	imod->pmod->links--;
        +	OPENSSL_free(imod->name);
        +	OPENSSL_free(imod->value);
        +	OPENSSL_free(imod);
        +	}
        +
        +/* Add a static module to OpenSSL */
        +
        +int CONF_module_add(const char *name, conf_init_func *ifunc, 
        +		    conf_finish_func *ffunc)
        +	{
        +	if (module_add(NULL, name, ifunc, ffunc))
        +		return 1;
        +	else
        +		return 0;
        +	}
        +
        +void CONF_modules_free(void)
        +	{
        +	CONF_modules_finish();
        +	CONF_modules_unload(1);
        +	}
        +
        +/* Utility functions */
        +
        +const char *CONF_imodule_get_name(const CONF_IMODULE *md)
        +	{
        +	return md->name;
        +	}
        +
        +const char *CONF_imodule_get_value(const CONF_IMODULE *md)
        +	{
        +	return md->value;
        +	}
        +
        +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
        +	{
        +	return md->usr_data;
        +	}
        +
        +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
        +	{
        +	md->usr_data = usr_data;
        +	}
        +
        +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
        +	{
        +	return md->pmod;
        +	}
        +
        +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
        +	{
        +	return md->flags;
        +	}
        +
        +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
        +	{
        +	md->flags = flags;
        +	}
        +
        +void *CONF_module_get_usr_data(CONF_MODULE *pmod)
        +	{
        +	return pmod->usr_data;
        +	}
        +
        +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
        +	{
        +	pmod->usr_data = usr_data;
        +	}
        +
        +/* Return default config file name */
        +
        +char *CONF_get1_default_config_file(void)
        +	{
        +	char *file;
        +	int len;
        +
        +	file = getenv("OPENSSL_CONF");
        +	if (file) 
        +		return BUF_strdup(file);
        +
        +	len = strlen(X509_get_default_cert_area());
        +#ifndef OPENSSL_SYS_VMS
        +	len++;
        +#endif
        +	len += strlen(OPENSSL_CONF);
        +
        +	file = OPENSSL_malloc(len + 1);
        +
        +	if (!file)
        +		return NULL;
        +	BUF_strlcpy(file,X509_get_default_cert_area(),len + 1);
        +#ifndef OPENSSL_SYS_VMS
        +	BUF_strlcat(file,"/",len + 1);
        +#endif
        +	BUF_strlcat(file,OPENSSL_CONF,len + 1);
        +
        +	return file;
        +	}
        +
        +/* This function takes a list separated by 'sep' and calls the
        + * callback function giving the start and length of each member
        + * optionally stripping leading and trailing whitespace. This can
        + * be used to parse comma separated lists for example.
        + */
        +
        +int CONF_parse_list(const char *list_, int sep, int nospc,
        +	int (*list_cb)(const char *elem, int len, void *usr), void *arg)
        +	{
        +	int ret;
        +	const char *lstart, *tmpend, *p;
        +
        +	if(list_ == NULL)
        +		{
        +		CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
        +		return 0;
        +		}
        +
        +	lstart = list_;
        +	for(;;)
        +		{
        +		if (nospc)
        +			{
        +			while(*lstart && isspace((unsigned char)*lstart))
        +				lstart++;
        +			}
        +		p = strchr(lstart, sep);
        +		if (p == lstart || !*lstart)
        +			ret = list_cb(NULL, 0, arg);
        +		else
        +			{
        +			if (p)
        +				tmpend = p - 1;
        +			else 
        +				tmpend = lstart + strlen(lstart) - 1;
        +			if (nospc)
        +				{
        +				while(isspace((unsigned char)*tmpend))
        +					tmpend--;
        +				}
        +			ret = list_cb(lstart, tmpend - lstart + 1, arg);
        +			}
        +		if (ret <= 0)
        +			return ret;
        +		if (p == NULL)
        +			return 1;
        +		lstart = p + 1;
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/conf_sap.c b/vendor/openssl/openssl/crypto/conf/conf_sap.c
        new file mode 100644
        index 000000000..760dc2632
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/conf_sap.c
        @@ -0,0 +1,111 @@
        +/* conf_sap.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/dso.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +/* This is the automatic configuration loader: it is called automatically by
        + * OpenSSL when any of a number of standard initialisation functions are called,
        + * unless this is overridden by calling OPENSSL_no_config()
        + */
        +
        +static int openssl_configured = 0;
        +
        +void OPENSSL_config(const char *config_name)
        +	{
        +	if (openssl_configured)
        +		return;
        +
        +	OPENSSL_load_builtin_modules();
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Need to load ENGINEs */
        +	ENGINE_load_builtin_engines();
        +#endif
        +	/* Add others here? */
        +
        +
        +	ERR_clear_error();
        +	if (CONF_modules_load_file(NULL, config_name,
        +	CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0)
        +		{
        +		BIO *bio_err;
        +		ERR_load_crypto_strings();
        +		if ((bio_err=BIO_new_fp(stderr, BIO_NOCLOSE)) != NULL)
        +			{
        +			BIO_printf(bio_err,"Auto configuration failed\n");
        +			ERR_print_errors(bio_err);
        +			BIO_free(bio_err);
        +			}
        +		exit(1);
        +		}
        +
        +	return;
        +	}
        +
        +void OPENSSL_no_config()
        +	{
        +	openssl_configured = 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/conf/keysets.pl b/vendor/openssl/openssl/crypto/conf/keysets.pl
        new file mode 100644
        index 000000000..50ed67fa5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/keysets.pl
        @@ -0,0 +1,185 @@
        +#!/usr/local/bin/perl
        +
        +$NUMBER=0x01;
        +$UPPER=0x02;
        +$LOWER=0x04;
        +$UNDER=0x100;
        +$PUNCTUATION=0x200;
        +$WS=0x10;
        +$ESC=0x20;
        +$QUOTE=0x40;
        +$DQUOTE=0x400;
        +$COMMENT=0x80;
        +$FCOMMENT=0x800;
        +$EOF=0x08;
        +$HIGHBIT=0x1000;
        +
        +foreach (0 .. 255)
        +	{
        +	$v=0;
        +	$c=sprintf("%c",$_);
        +	$v|=$NUMBER	if ($c =~ /[0-9]/);
        +	$v|=$UPPER	if ($c =~ /[A-Z]/);
        +	$v|=$LOWER	if ($c =~ /[a-z]/);
        +	$v|=$UNDER	if ($c =~ /_/);
        +	$v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/);
        +	$v|=$WS		if ($c =~ /[ \t\r\n]/);
        +	$v|=$ESC	if ($c =~ /\\/);
        +	$v|=$QUOTE	if ($c =~ /['`"]/); # for emacs: "`'}/)
        +	$v|=$COMMENT	if ($c =~ /\#/);
        +	$v|=$EOF	if ($c =~ /\0/);
        +	$v|=$HIGHBIT	if ($c =~/[\x80-\xff]/);
        +
        +	push(@V_def,$v);
        +	}
        +
        +foreach (0 .. 255)
        +	{
        +	$v=0;
        +	$c=sprintf("%c",$_);
        +	$v|=$NUMBER	if ($c =~ /[0-9]/);
        +	$v|=$UPPER	if ($c =~ /[A-Z]/);
        +	$v|=$LOWER	if ($c =~ /[a-z]/);
        +	$v|=$UNDER	if ($c =~ /_/);
        +	$v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/);
        +	$v|=$WS		if ($c =~ /[ \t\r\n]/);
        +	$v|=$DQUOTE	if ($c =~ /["]/); # for emacs: "}/)
        +	$v|=$FCOMMENT	if ($c =~ /;/);
        +	$v|=$EOF	if ($c =~ /\0/);
        +	$v|=$HIGHBIT	if ($c =~/[\x80-\xff]/);
        +
        +	push(@V_w32,$v);
        +	}
        +
        +print <<"EOF";
        +/* 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		$NUMBER
        +#define CONF_UPPER		$UPPER
        +#define CONF_LOWER		$LOWER
        +#define CONF_UNDER		$UNDER
        +#define CONF_PUNCTUATION	$PUNCTUATION
        +#define CONF_WS			$WS
        +#define CONF_ESC		$ESC
        +#define CONF_QUOTE		$QUOTE
        +#define CONF_DQUOTE		$DQUOTE
        +#define CONF_COMMENT		$COMMENT
        +#define CONF_FCOMMENT		$FCOMMENT
        +#define CONF_EOF		$EOF
        +#define CONF_HIGHBIT		$HIGHBIT
        +#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)&0xff]&CONF_COMMENT)
        +#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
        +#define IS_EOF(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_EOF)
        +#define IS_ESC(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_ESC)
        +#define IS_NUMBER(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
        +#define IS_WS(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_WS)
        +#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
        +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\
        +				(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
        +#define IS_QUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
        +#define IS_DQUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
        +#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
        +
        +#else /*CHARSET_EBCDIC*/
        +
        +#define IS_COMMENT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
        +#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
        +#define IS_EOF(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
        +#define IS_ESC(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
        +#define IS_NUMBER(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
        +#define IS_WS(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
        +#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
        +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\
        +				(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
        +#define IS_QUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
        +#define IS_DQUOTE(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
        +#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
        +#endif /*CHARSET_EBCDIC*/
        +
        +EOF
        +
        +print "static unsigned short CONF_type_default[256]={";
        +
        +for ($i=0; $i<256; $i++)
        +	{
        +	print "\n\t" if ($i % 8) == 0;
        +	printf "0x%04X,",$V_def[$i];
        +	}
        +
        +print "\n\t};\n\n";
        +
        +print "static unsigned short CONF_type_win32[256]={";
        +
        +for ($i=0; $i<256; $i++)
        +	{
        +	print "\n\t" if ($i % 8) == 0;
        +	printf "0x%04X,",$V_w32[$i];
        +	}
        +
        +print "\n\t};\n\n";
        diff --git a/vendor/openssl/openssl/crypto/conf/ssleay.cnf b/vendor/openssl/openssl/crypto/conf/ssleay.cnf
        new file mode 100644
        index 000000000..ed33af601
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/ssleay.cnf
        @@ -0,0 +1,78 @@
        +#
        +# This is a test configuration file for use in SSLeay etc...
        +#
        +
        +init = 5
        +in\#it1 =10
        +init2='10'
        +init3='10\''
        +init4="10'"
        +init5='='10\'' again'
        +
        +SSLeay::version = 0.5.0
        +
        +[genrsa]
        +default_bits	= 512
        +SSLEAY::version = 0.5.0
        +
        +[gendh]
        +default_bits	= 512
        +def_generator	= 2
        +
        +[s_client]
        +cipher1		= DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5\
        +cipher2		= 'DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5'
        +cipher3		= "DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5"
        +cipher4		= DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5
        +
        +[ default ]
        +cert_dir	= $ENV::HOME/.ca_certs
        +
        +HOME		= /tmp/eay
        +
        +tmp_cert_dir	= $HOME/.ca_certs
        +tmp2_cert_dir	= thisis$(HOME)stuff
        +
        +LOGNAME	= Eric Young (home=$HOME)
        +
        +[ special ]
        +
        +H=$HOME
        +H=$default::HOME
        +H=$ENV::HOME
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +RANDFILE		= $HOME/.rand
        +
        +[ req ]
        +default_bits		= 512
        +default_keyfile 	= privkey.pem
        +
        +Attribute_type_1	= countryName
        +Attribute_text_1	= Country Name (2 letter code)
        +Attribute_default_1	= AU
        +
        +Attribute_type_2	= stateOrProvinceName
        +Attribute_text_2	= State or Province Name (full name)
        +Attribute_default_2	= Queensland
        +
        +Attribute_type_3	= localityName
        +Attribute_text_3	= Locality Name (eg, city)
        +
        +Attribute_type_4	= organizationName
        +Attribute_text_4	= Organization Name (eg, company)
        +Attribute_default_4	= Mincom Pty Ltd
        +
        +Attribute_type_5	= organizationalUnitName
        +Attribute_text_5	= Organizational Unit Name (eg, section)
        +Attribute_default_5	= TR
        +
        +Attribute_type_6	= commonName
        +Attribute_text_6	= Common Name (eg, YOUR name)
        +
        +Attribute_type_7	= emailAddress
        +Attribute_text_7	= Email Address
        +
        diff --git a/vendor/openssl/openssl/crypto/conf/test.c b/vendor/openssl/openssl/crypto/conf/test.c
        new file mode 100644
        index 000000000..7fab85053
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/conf/test.c
        @@ -0,0 +1,98 @@
        +/* crypto/conf/test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/conf.h>
        +#include <openssl/err.h>
        +
        +main()
        +	{
        +	LHASH *conf;
        +	long eline;
        +	char *s,*s2;
        +
        +#ifdef USE_WIN32
        +	CONF_set_default_method(CONF_WIN32);
        +#endif
        +	conf=CONF_load(NULL,"ssleay.cnf",&eline);
        +	if (conf == NULL)
        +		{
        +		ERR_load_crypto_strings();
        +		printf("unable to load configuration, line %ld\n",eline);
        +		ERR_print_errors_fp(stderr);
        +		exit(1);
        +		}
        +	lh_stats(conf,stdout);
        +	lh_node_stats(conf,stdout);
        +	lh_node_usage_stats(conf,stdout);
        +
        +	s=CONF_get_string(conf,NULL,"init2");
        +	printf("init2=%s\n",(s == NULL)?"NULL":s);
        +
        +	s=CONF_get_string(conf,NULL,"cipher1");
        +	printf("cipher1=%s\n",(s == NULL)?"NULL":s);
        +
        +	s=CONF_get_string(conf,"s_client","cipher1");
        +	printf("s_client:cipher1=%s\n",(s == NULL)?"NULL":s);
        +
        +	printf("---------------------------- DUMP ------------------------\n");
        +	CONF_dump_fp(conf, stdout);
        +
        +	exit(0);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cpt_err.c b/vendor/openssl/openssl/crypto/cpt_err.c
        new file mode 100644
        index 000000000..289005f66
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cpt_err.c
        @@ -0,0 +1,105 @@
        +/* crypto/cpt_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/crypto.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason)
        +
        +static ERR_STRING_DATA CRYPTO_str_functs[]=
        +	{
        +{ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX),	"CRYPTO_get_ex_new_index"},
        +{ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID),	"CRYPTO_get_new_dynlockid"},
        +{ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID),	"CRYPTO_get_new_lockid"},
        +{ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA),	"CRYPTO_set_ex_data"},
        +{ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX),	"DEF_ADD_INDEX"},
        +{ERR_FUNC(CRYPTO_F_DEF_GET_CLASS),	"DEF_GET_CLASS"},
        +{ERR_FUNC(CRYPTO_F_FIPS_MODE_SET),	"FIPS_mode_set"},
        +{ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA),	"INT_DUP_EX_DATA"},
        +{ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA),	"INT_FREE_EX_DATA"},
        +{ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA),	"INT_NEW_EX_DATA"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CRYPTO_str_reasons[]=
        +	{
        +{ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
        +{ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK),"no dynlock create callback"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_CRYPTO_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,CRYPTO_str_functs);
        +		ERR_load_strings(0,CRYPTO_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cryptlib.c b/vendor/openssl/openssl/crypto/cryptlib.c
        new file mode 100644
        index 000000000..304c6b706
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cryptlib.c
        @@ -0,0 +1,940 @@
        +/* crypto/cryptlib.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/safestack.h>
        +
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
        +static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
        +#endif
        +
        +DECLARE_STACK_OF(CRYPTO_dynlock)
        +
        +/* real #defines in crypto.h, keep these upto date */
        +static const char* const lock_names[CRYPTO_NUM_LOCKS] =
        +	{
        +	"<<ERROR>>",
        +	"err",
        +	"ex_data",
        +	"x509",
        +	"x509_info",
        +	"x509_pkey",
        +	"x509_crl",
        +	"x509_req",
        +	"dsa",
        +	"rsa",
        +	"evp_pkey",
        +	"x509_store",
        +	"ssl_ctx",
        +	"ssl_cert",
        +	"ssl_session",
        +	"ssl_sess_cert",
        +	"ssl",
        +	"ssl_method",
        +	"rand",
        +	"rand2",
        +	"debug_malloc",
        +	"BIO",
        +	"gethostbyname",
        +	"getservbyname",
        +	"readdir",
        +	"RSA_blinding",
        +	"dh",
        +	"debug_malloc2",
        +	"dso",
        +	"dynlock",
        +	"engine",
        +	"ui",
        +	"ecdsa",
        +	"ec",
        +	"ecdh",
        +	"bn",
        +	"ec_pre_comp",
        +	"store",
        +	"comp",
        +	"fips",
        +	"fips2",
        +#if CRYPTO_NUM_LOCKS != 41
        +# error "Inconsistency between crypto.h and cryptlib.c"
        +#endif
        +	};
        +
        +/* This is for applications to allocate new type names in the non-dynamic
        +   array of lock names.  These are numbered with positive numbers.  */
        +static STACK_OF(OPENSSL_STRING) *app_locks=NULL;
        +
        +/* For applications that want a more dynamic way of handling threads, the
        +   following stack is used.  These are externally numbered with negative
        +   numbers.  */
        +static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
        +
        +
        +static void (MS_FAR *locking_callback)(int mode,int type,
        +	const char *file,int line)=0;
        +static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
        +	int type,const char *file,int line)=0;
        +#ifndef OPENSSL_NO_DEPRECATED
        +static unsigned long (MS_FAR *id_callback)(void)=0;
        +#endif
        +static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
        +static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
        +	(const char *file,int line)=0;
        +static void (MS_FAR *dynlock_lock_callback)(int mode,
        +	struct CRYPTO_dynlock_value *l, const char *file,int line)=0;
        +static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
        +	const char *file,int line)=0;
        +
        +int CRYPTO_get_new_lockid(char *name)
        +	{
        +	char *str;
        +	int i;
        +
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
        +	/* A hack to make Visual C++ 5.0 work correctly when linking as
        +	 * a DLL using /MT. Without this, the application cannot use
        +	 * any floating point printf's.
        +	 * It also seems to be needed for Visual C 1.5 (win16) */
        +	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
        +#endif
        +
        +	if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) == NULL))
        +		{
        +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	if ((str=BUF_strdup(name)) == NULL)
        +		{
        +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	i=sk_OPENSSL_STRING_push(app_locks,str);
        +	if (!i)
        +		OPENSSL_free(str);
        +	else
        +		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
        +	return(i);
        +	}
        +
        +int CRYPTO_num_locks(void)
        +	{
        +	return CRYPTO_NUM_LOCKS;
        +	}
        +
        +int CRYPTO_get_new_dynlockid(void)
        +	{
        +	int i = 0;
        +	CRYPTO_dynlock *pointer = NULL;
        +
        +	if (dynlock_create_callback == NULL)
        +		{
        +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
        +		return(0);
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
        +	if ((dyn_locks == NULL)
        +		&& ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
        +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
        +
        +	pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
        +	if (pointer == NULL)
        +		{
        +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	pointer->references = 1;
        +	pointer->data = dynlock_create_callback(__FILE__,__LINE__);
        +	if (pointer->data == NULL)
        +		{
        +		OPENSSL_free(pointer);
        +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
        +	/* First, try to find an existing empty slot */
        +	i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
        +	/* If there was none, push, thereby creating a new one */
        +	if (i == -1)
        +		/* Since sk_push() returns the number of items on the
        +		   stack, not the location of the pushed item, we need
        +		   to transform the returned number into a position,
        +		   by decreasing it.  */
        +		i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
        +	else
        +		/* If we found a place with a NULL pointer, put our pointer
        +		   in it.  */
        +		(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
        +
        +	if (i == -1)
        +		{
        +		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
        +		OPENSSL_free(pointer);
        +		}
        +	else
        +		i += 1; /* to avoid 0 */
        +	return -i;
        +	}
        +
        +void CRYPTO_destroy_dynlockid(int i)
        +	{
        +	CRYPTO_dynlock *pointer = NULL;
        +	if (i)
        +		i = -i-1;
        +	if (dynlock_destroy_callback == NULL)
        +		return;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
        +
        +	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
        +		return;
        +		}
        +	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
        +	if (pointer != NULL)
        +		{
        +		--pointer->references;
        +#ifdef REF_CHECK
        +		if (pointer->references < 0)
        +			{
        +			fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
        +			abort();
        +			}
        +		else
        +#endif
        +			if (pointer->references <= 0)
        +				{
        +				(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
        +				}
        +			else
        +				pointer = NULL;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
        +
        +	if (pointer)
        +		{
        +		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
        +		OPENSSL_free(pointer);
        +		}
        +	}
        +
        +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
        +	{
        +	CRYPTO_dynlock *pointer = NULL;
        +	if (i)
        +		i = -i-1;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
        +
        +	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
        +		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
        +	if (pointer)
        +		pointer->references++;
        +
        +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
        +
        +	if (pointer)
        +		return pointer->data;
        +	return NULL;
        +	}
        +
        +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
        +	(const char *file,int line)
        +	{
        +	return(dynlock_create_callback);
        +	}
        +
        +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
        +	struct CRYPTO_dynlock_value *l, const char *file,int line)
        +	{
        +	return(dynlock_lock_callback);
        +	}
        +
        +void (*CRYPTO_get_dynlock_destroy_callback(void))
        +	(struct CRYPTO_dynlock_value *l, const char *file,int line)
        +	{
        +	return(dynlock_destroy_callback);
        +	}
        +
        +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
        +	(const char *file, int line))
        +	{
        +	dynlock_create_callback=func;
        +	}
        +
        +void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
        +	struct CRYPTO_dynlock_value *l, const char *file, int line))
        +	{
        +	dynlock_lock_callback=func;
        +	}
        +
        +void CRYPTO_set_dynlock_destroy_callback(void (*func)
        +	(struct CRYPTO_dynlock_value *l, const char *file, int line))
        +	{
        +	dynlock_destroy_callback=func;
        +	}
        +
        +
        +void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
        +		int line)
        +	{
        +	return(locking_callback);
        +	}
        +
        +int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
        +					  const char *file,int line)
        +	{
        +	return(add_lock_callback);
        +	}
        +
        +void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
        +					      const char *file,int line))
        +	{
        +	/* Calling this here ensures initialisation before any threads
        +	 * are started.
        +	 */
        +	OPENSSL_init();
        +	locking_callback=func;
        +	}
        +
        +void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
        +					      const char *file,int line))
        +	{
        +	add_lock_callback=func;
        +	}
        +
        +/* the memset() here and in set_pointer() seem overkill, but for the sake of
        + * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
        + * "equal" THREADID structs to not be memcmp()-identical. */
        +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
        +	{
        +	memset(id, 0, sizeof(*id));
        +	id->val = val;
        +	}
        +
        +static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
        +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
        +	{
        +	unsigned char *dest = (void *)&id->val;
        +	unsigned int accum = 0;
        +	unsigned char dnum = sizeof(id->val);
        +
        +	memset(id, 0, sizeof(*id));
        +	id->ptr = ptr;
        +	if (sizeof(id->val) >= sizeof(id->ptr))
        +		{
        +		/* 'ptr' can be embedded in 'val' without loss of uniqueness */
        +		id->val = (unsigned long)id->ptr;
        +		return;
        +		}
        +	/* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
        +	 * linear function over the bytes in 'ptr', the co-efficients of which
        +	 * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
        +	 * the starting prime for the sequence varies for each byte of 'val'
        +	 * (unique polynomials unless pointers are >64-bit). For added spice,
        +	 * the totals accumulate rather than restarting from zero, and the index
        +	 * of the 'val' byte is added each time (position dependence). If I was
        +	 * a black-belt, I'd scan big-endian pointers in reverse to give
        +	 * low-order bits more play, but this isn't crypto and I'd prefer nobody
        +	 * mistake it as such. Plus I'm lazy. */
        +	while (dnum--)
        +		{
        +		const unsigned char *src = (void *)&id->ptr;
        +		unsigned char snum = sizeof(id->ptr);
        +		while (snum--)
        +			accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
        +		accum += dnum;
        +		*(dest++) = accum & 255;
        +		}
        +	}
        +
        +int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
        +	{
        +	if (threadid_callback)
        +		return 0;
        +	threadid_callback = func;
        +	return 1;
        +	}
        +
        +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
        +	{
        +	return threadid_callback;
        +	}
        +
        +void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
        +	{
        +	if (threadid_callback)
        +		{
        +		threadid_callback(id);
        +		return;
        +		}
        +#ifndef OPENSSL_NO_DEPRECATED
        +	/* If the deprecated callback was set, fall back to that */
        +	if (id_callback)
        +		{
        +		CRYPTO_THREADID_set_numeric(id, id_callback());
        +		return;
        +		}
        +#endif
        +	/* Else pick a backup */
        +#ifdef OPENSSL_SYS_WIN16
        +	CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
        +#elif defined(OPENSSL_SYS_WIN32)
        +	CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
        +#elif defined(OPENSSL_SYS_BEOS)
        +	CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
        +#else
        +	/* For everything else, default to using the address of 'errno' */
        +	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
        +#endif
        +	}
        +
        +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
        +	{
        +	return memcmp(a, b, sizeof(*a));
        +	}
        +
        +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
        +	{
        +	memcpy(dest, src, sizeof(*src));
        +	}
        +
        +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
        +	{
        +	return id->val;
        +	}
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +unsigned long (*CRYPTO_get_id_callback(void))(void)
        +	{
        +	return(id_callback);
        +	}
        +
        +void CRYPTO_set_id_callback(unsigned long (*func)(void))
        +	{
        +	id_callback=func;
        +	}
        +
        +unsigned long CRYPTO_thread_id(void)
        +	{
        +	unsigned long ret=0;
        +
        +	if (id_callback == NULL)
        +		{
        +#ifdef OPENSSL_SYS_WIN16
        +		ret=(unsigned long)GetCurrentTask();
        +#elif defined(OPENSSL_SYS_WIN32)
        +		ret=(unsigned long)GetCurrentThreadId();
        +#elif defined(GETPID_IS_MEANINGLESS)
        +		ret=1L;
        +#elif defined(OPENSSL_SYS_BEOS)
        +		ret=(unsigned long)find_thread(NULL);
        +#else
        +		ret=(unsigned long)getpid();
        +#endif
        +		}
        +	else
        +		ret=id_callback();
        +	return(ret);
        +	}
        +#endif
        +
        +void CRYPTO_lock(int mode, int type, const char *file, int line)
        +	{
        +#ifdef LOCK_DEBUG
        +		{
        +		CRYPTO_THREADID id;
        +		char *rw_text,*operation_text;
        +
        +		if (mode & CRYPTO_LOCK)
        +			operation_text="lock  ";
        +		else if (mode & CRYPTO_UNLOCK)
        +			operation_text="unlock";
        +		else
        +			operation_text="ERROR ";
        +
        +		if (mode & CRYPTO_READ)
        +			rw_text="r";
        +		else if (mode & CRYPTO_WRITE)
        +			rw_text="w";
        +		else
        +			rw_text="ERROR";
        +
        +		CRYPTO_THREADID_current(&id);
        +		fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
        +			CRYPTO_THREADID_hash(&id), rw_text, operation_text,
        +			CRYPTO_get_lock_name(type), file, line);
        +		}
        +#endif
        +	if (type < 0)
        +		{
        +		if (dynlock_lock_callback != NULL)
        +			{
        +			struct CRYPTO_dynlock_value *pointer
        +				= CRYPTO_get_dynlock_value(type);
        +
        +			OPENSSL_assert(pointer != NULL);
        +
        +			dynlock_lock_callback(mode, pointer, file, line);
        +
        +			CRYPTO_destroy_dynlockid(type);
        +			}
        +		}
        +	else
        +		if (locking_callback != NULL)
        +			locking_callback(mode,type,file,line);
        +	}
        +
        +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
        +	     int line)
        +	{
        +	int ret = 0;
        +
        +	if (add_lock_callback != NULL)
        +		{
        +#ifdef LOCK_DEBUG
        +		int before= *pointer;
        +#endif
        +
        +		ret=add_lock_callback(pointer,amount,type,file,line);
        +#ifdef LOCK_DEBUG
        +		{
        +		CRYPTO_THREADID id;
        +		CRYPTO_THREADID_current(&id);
        +		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
        +			CRYPTO_THREADID_hash(&id), before,amount,ret,
        +			CRYPTO_get_lock_name(type),
        +			file,line);
        +		}
        +#endif
        +		}
        +	else
        +		{
        +		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
        +
        +		ret= *pointer+amount;
        +#ifdef LOCK_DEBUG
        +		{
        +		CRYPTO_THREADID id;
        +		CRYPTO_THREADID_current(&id);
        +		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
        +			CRYPTO_THREADID_hash(&id),
        +			*pointer,amount,ret,
        +			CRYPTO_get_lock_name(type),
        +			file,line);
        +		}
        +#endif
        +		*pointer=ret;
        +		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
        +		}
        +	return(ret);
        +	}
        +
        +const char *CRYPTO_get_lock_name(int type)
        +	{
        +	if (type < 0)
        +		return("dynamic");
        +	else if (type < CRYPTO_NUM_LOCKS)
        +		return(lock_names[type]);
        +	else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
        +		return("ERROR");
        +	else
        +		return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS));
        +	}
        +
        +#if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
        +	defined(__INTEL__) || \
        +	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
        +
        +unsigned int  OPENSSL_ia32cap_P[2];
        +unsigned long *OPENSSL_ia32cap_loc(void)
        +{   if (sizeof(long)==4)
        +	/*
        +	 * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
        +	 * clear second element to maintain the illusion that vector
        +	 * is 32-bit.
        +	 */
        +	OPENSSL_ia32cap_P[1]=0;
        +    return (unsigned long *)OPENSSL_ia32cap_P;
        +}
        +
        +#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
        +#define OPENSSL_CPUID_SETUP
        +#if defined(_WIN32)
        +typedef unsigned __int64 IA32CAP;
        +#else
        +typedef unsigned long long IA32CAP;
        +#endif
        +void OPENSSL_cpuid_setup(void)
        +{ static int trigger=0;
        +  IA32CAP OPENSSL_ia32_cpuid(void);
        +  IA32CAP vec;
        +  char *env;
        +
        +    if (trigger)	return;
        +
        +    trigger=1;
        +    if ((env=getenv("OPENSSL_ia32cap"))) {
        +	int off = (env[0]=='~')?1:0;
        +#if defined(_WIN32)
        +	if (!sscanf(env+off,"%I64i",&vec)) vec = strtoul(env+off,NULL,0);
        +#else
        +	if (!sscanf(env+off,"%lli",(long long *)&vec)) vec = strtoul(env+off,NULL,0);
        +#endif
        +	if (off) vec = OPENSSL_ia32_cpuid()&~vec;
        +    }
        +    else
        +	vec = OPENSSL_ia32_cpuid();
        +
        +    /*
        +     * |(1<<10) sets a reserved bit to signal that variable
        +     * was initialized already... This is to avoid interference
        +     * with cpuid snippets in ELF .init segment.
        +     */
        +    OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
        +    OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
        +}
        +#endif
        +
        +#else
        +unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
        +#endif
        +int OPENSSL_NONPIC_relocated = 0;
        +#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
        +void OPENSSL_cpuid_setup(void) {}
        +#endif
        +
        +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
        +#ifdef __CYGWIN__
        +/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
        +#include <windows.h>
        +/* this has side-effect of _WIN32 getting defined, which otherwise
        + * is mutually exclusive with __CYGWIN__... */
        +#endif
        +
        +/* All we really need to do is remove the 'error' state when a thread
        + * detaches */
        +
        +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
        +	     LPVOID lpvReserved)
        +	{
        +	switch(fdwReason)
        +		{
        +	case DLL_PROCESS_ATTACH:
        +		OPENSSL_cpuid_setup();
        +#if defined(_WIN32_WINNT)
        +		{
        +		IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL;
        +		IMAGE_NT_HEADERS *nt_headers;
        +
        +		if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
        +			{
        +			nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
        +						+ dos_header->e_lfanew);
        +			if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
        +			    hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase))
        +				OPENSSL_NONPIC_relocated=1;
        +			}
        +		}
        +#endif
        +		break;
        +	case DLL_THREAD_ATTACH:
        +		break;
        +	case DLL_THREAD_DETACH:
        +		break;
        +	case DLL_PROCESS_DETACH:
        +		break;
        +		}
        +	return(TRUE);
        +	}
        +#endif
        +
        +#if defined(_WIN32) && !defined(__CYGWIN__)
        +#include <tchar.h>
        +#include <signal.h>
        +#ifdef __WATCOMC__
        +#if defined(_UNICODE) || defined(__UNICODE__)
        +#define _vsntprintf _vsnwprintf
        +#else
        +#define _vsntprintf _vsnprintf
        +#endif
        +#endif
        +#ifdef _MSC_VER
        +#define alloca _alloca
        +#endif
        +
        +#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
        +int OPENSSL_isservice(void)
        +{ HWINSTA h;
        +  DWORD len;
        +  WCHAR *name;
        +  static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
        +
        +    if (_OPENSSL_isservice.p == NULL) {
        +	HANDLE h = GetModuleHandle(NULL);
        +	if (h != NULL)
        +	    _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
        +	if (_OPENSSL_isservice.p == NULL)
        +	    _OPENSSL_isservice.p = (void *)-1;
        +    }
        +
        +    if (_OPENSSL_isservice.p != (void *)-1)
        +	return (*_OPENSSL_isservice.f)();
        +
        +    (void)GetDesktopWindow(); /* return value is ignored */
        +
        +    h = GetProcessWindowStation();
        +    if (h==NULL) return -1;
        +
        +    if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
        +	GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        +	return -1;
        +
        +    if (len>512) return -1;		/* paranoia */
        +    len++,len&=~1;			/* paranoia */
        +    name=(WCHAR *)alloca(len+sizeof(WCHAR));
        +    if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
        +	return -1;
        +
        +    len++,len&=~1;			/* paranoia */
        +    name[len/sizeof(WCHAR)]=L'\0';	/* paranoia */
        +#if 1
        +    /* This doesn't cover "interactive" services [working with real
        +     * WinSta0's] nor programs started non-interactively by Task
        +     * Scheduler [those are working with SAWinSta]. */
        +    if (wcsstr(name,L"Service-0x"))	return 1;
        +#else
        +    /* This covers all non-interactive programs such as services. */
        +    if (!wcsstr(name,L"WinSta0"))	return 1;
        +#endif
        +    else				return 0;
        +}
        +#else
        +int OPENSSL_isservice(void) { return 0; }
        +#endif
        +
        +void OPENSSL_showfatal (const char *fmta,...)
        +{ va_list ap;
        +  TCHAR buf[256];
        +  const TCHAR *fmt;
        +#ifdef STD_ERROR_HANDLE	/* what a dirty trick! */
        +  HANDLE h;
        +
        +    if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
        +	GetFileType(h)!=FILE_TYPE_UNKNOWN)
        +    {	/* must be console application */
        +	va_start (ap,fmta);
        +	vfprintf (stderr,fmta,ap);
        +	va_end (ap);
        +	return;
        +    }
        +#endif
        +
        +    if (sizeof(TCHAR)==sizeof(char))
        +	fmt=(const TCHAR *)fmta;
        +    else do
        +    { int    keepgoing;
        +      size_t len_0=strlen(fmta)+1,i;
        +      WCHAR *fmtw;
        +
        +	fmtw = (WCHAR *)alloca(len_0*sizeof(WCHAR));
        +	if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; }
        +
        +#ifndef OPENSSL_NO_MULTIBYTE
        +	if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0))
        +#endif
        +	    for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i];
        +
        +	for (i=0;i<len_0;i++)
        +	{   if (fmtw[i]==L'%') do
        +	    {	keepgoing=0;
        +		switch (fmtw[i+1])
        +		{   case L'0': case L'1': case L'2': case L'3': case L'4':
        +		    case L'5': case L'6': case L'7': case L'8': case L'9':
        +		    case L'.': case L'*':
        +		    case L'-':	i++; keepgoing=1; break;
        +		    case L's':	fmtw[i+1]=L'S';   break;
        +		    case L'S':	fmtw[i+1]=L's';   break;
        +		    case L'c':	fmtw[i+1]=L'C';   break;
        +		    case L'C':	fmtw[i+1]=L'c';   break;
        +		}
        +	    } while (keepgoing);
        +	}
        +	fmt = (const TCHAR *)fmtw;
        +    } while (0);
        +
        +    va_start (ap,fmta);
        +    _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap);
        +    buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0');
        +    va_end (ap);
        +
        +#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
        +    /* this -------------v--- guards NT-specific calls */
        +    if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0)
        +    {	HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
        +	const TCHAR *pmsg=buf;
        +	ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
        +	DeregisterEventSource(h);
        +    }
        +    else
        +#endif
        +	MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP);
        +}
        +#else
        +void OPENSSL_showfatal (const char *fmta,...)
        +{ va_list ap;
        +
        +    va_start (ap,fmta);
        +    vfprintf (stderr,fmta,ap);
        +    va_end (ap);
        +}
        +int OPENSSL_isservice (void) { return 0; }
        +#endif
        +
        +void OpenSSLDie(const char *file,int line,const char *assertion)
        +	{
        +	OPENSSL_showfatal(
        +		"%s(%d): OpenSSL internal error, assertion failed: %s\n",
        +		file,line,assertion);
        +#if !defined(_WIN32) || defined(__CYGWIN__)
        +	abort();
        +#else
        +	/* Win32 abort() customarily shows a dialog, but we just did that... */
        +	raise(SIGABRT);
        +	_exit(3);
        +#endif
        +	}
        +
        +void *OPENSSL_stderr(void)	{ return stderr; }
        +
        +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
        +	{
        +	size_t i;
        +	const unsigned char *a = in_a;
        +	const unsigned char *b = in_b;
        +	unsigned char x = 0;
        +
        +	for (i = 0; i < len; i++)
        +		x |= a[i] ^ b[i];
        +
        +	return x;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/cryptlib.h b/vendor/openssl/openssl/crypto/cryptlib.h
        new file mode 100644
        index 000000000..d26f9630e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cryptlib.h
        @@ -0,0 +1,111 @@
        +/* crypto/cryptlib.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_CRYPTLIB_H
        +#define HEADER_CRYPTLIB_H
        +
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +
        +#ifdef OPENSSL_USE_APPLINK
        +#define BIO_FLAGS_UPLINK 0x8000
        +#include "ms/uplink.h"
        +#endif
        +
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h> 
        +#include <openssl/bio.h> 
        +#include <openssl/err.h>
        +#include <openssl/opensslconf.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifndef OPENSSL_SYS_VMS
        +#define X509_CERT_AREA		OPENSSLDIR
        +#define X509_CERT_DIR		OPENSSLDIR "/certs"
        +#define X509_CERT_FILE		OPENSSLDIR "/cert.pem"
        +#define X509_PRIVATE_DIR	OPENSSLDIR "/private"
        +#else
        +#define X509_CERT_AREA		"SSLROOT:[000000]"
        +#define X509_CERT_DIR		"SSLCERTS:"
        +#define X509_CERT_FILE		"SSLCERTS:cert.pem"
        +#define X509_PRIVATE_DIR        "SSLPRIVATE:"
        +#endif
        +
        +#define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
        +#define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
        +
        +/* size of string representations */
        +#define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)
        +#define HEX_SIZE(type)		(sizeof(type)*2)
        +
        +void OPENSSL_cpuid_setup(void);
        +extern unsigned int OPENSSL_ia32cap_P[];
        +void OPENSSL_showfatal(const char *fmta,...);
        +void *OPENSSL_stderr(void);
        +extern int OPENSSL_NONPIC_relocated;
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/crypto-lib.com b/vendor/openssl/openssl/crypto/crypto-lib.com
        new file mode 100644
        index 000000000..dc8a8c174
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/crypto-lib.com
        @@ -0,0 +1,1516 @@
        +$!
        +$!  CRYPTO-LIB.COM
        +$!  Written By:  Robert Byer
        +$!               Vice-President
        +$!               A-Com Computing, Inc.
        +$!               byer@mail.all-net.net
        +$!
        +$!  Changes by Richard Levitte <richard@levitte.org>
        +$!             Zoltan Arpadffy <arpadffy@polarhome.com>
        +$!
        +$!  This command files compiles and creates the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" 
        +$!  library for OpenSSL.  The "xxx" denotes the machine architecture, ALPHA,
        +$!  IA64 or VAX.
        +$!
        +$!  It was re-written so it would try to determine what "C" compiler to use 
        +$!  or you can specify which "C" compiler to use.
        +$!
        +$!  Specify the following as P1 to build just that part or ALL to just
        +$!  build everything.
        +$!
        +$!    	LIBRARY    To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
        +$!    	APPS       To just compile the [.xxx.EXE.CRYPTO]*.EXE
        +$!	ALL	   To do both LIBRARY and APPS
        +$!
        +$!  Specify DEBUG or NODEBUG as P2 to compile with or without debugger
        +$!  information.
        +$!
        +$!  Specify which compiler at P3 to try to compile under.
        +$!
        +$!	VAXC	   For VAX C.
        +$!	DECC	   For DEC C.
        +$!	GNUC	   For GNU C.
        +$!
        +$!  If you don't specify a compiler, it will try to determine which
        +$!  "C" compiler to use.
        +$!
        +$!  P4, if defined, sets a TCP/IP library to use, through one of the following
        +$!  keywords:
        +$!
        +$!	UCX	   For UCX
        +$!	TCPIP	   For TCPIP (post UCX)
        +$!	SOCKETSHR  For SOCKETSHR+NETLIB
        +$!
        +$!  P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
        +$!
        +$!  P6, if defined, sets a choice of crypto methods to compile.
        +$!  WARNING: this should only be done to recompile some part of an already
        +$!  fully compiled library.
        +$!
        +$!  P7, if defined, specifies the C pointer size.  Ignored on VAX.
        +$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
        +$!      Supported values are:
        +$!
        +$!      ""       Compile with default (/NOPOINTER_SIZE)
        +$!      32       Compile with /POINTER_SIZE=32 (SHORT)
        +$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]).
        +$!               (Automatically select ARGV if compiler supports it.)
        +$!      64=      Compile with /POINTER_SIZE=64 (LONG).
        +$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
        +$!
        +$!  P8, if defined, specifies a directory where ZLIB files (zlib.h,
        +$!  libz.olb) may be found.  Optionally, a non-default object library
        +$!  name may be included ("dev:[dir]libz_64.olb", for example).
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$! Define A TCP/IP Library That We Will Need To Link To.
        +$! (That Is, If We Need To Link To One.)
        +$!
        +$ TCPIP_LIB = ""
        +$ ZLIB_LIB = ""
        +$!
        +$! Check Which Architecture We Are Using.
        +$!
        +$ IF (F$GETSYI("CPU").LT.128)
        +$ THEN
        +$!
        +$!  The Architecture Is VAX
        +$!
        +$   ARCH = "VAX"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
        +$!
        +$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
        +$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
        +$!
        +$! End The Architecture Check.
        +$!
        +$ ENDIF
        +$!
        +$ ARCHD = ARCH
        +$ LIB32 = "32"
        +$ OPT_FILE = ""
        +$ POINTER_SIZE = ""
        +$!
        +$! Define The Different Encryption Types.
        +$! NOTE: Some might think this list ugly.  However, it's made this way to
        +$! reflect the SDIRS variable in [-]Makefile.org as closely as possible,
        +$! thereby making it fairly easy to verify that the lists are the same.
        +$!
        +$ ET_WHIRLPOOL = "WHRLPOOL"
        +$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = ""
        +$ ENCRYPT_TYPES = "Basic,"+ -
        +		  "OBJECTS,"+ -
        +		  "MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
        +		  "DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
        +		  "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
        +		  "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
        +		  "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
        +		  "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
        +		  "CMS,PQUEUE,TS,JPAKE,SRP,STORE,CMAC"
        +$!
        +$! Check To Make Sure We Have Valid Command Line Parameters.
        +$!
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Define The OBJ and EXE Directories.
        +$!
        +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.CRYPTO]
        +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]
        +$!
        +$! Specify the destination directory in any /MAP option.
        +$!
        +$ if (LINKMAP .eqs. "MAP")
        +$ then
        +$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
        +$ endif
        +$!
        +$! Add the location prefix to the linker options file name.
        +$!
        +$ if (OPT_FILE .nes. "")
        +$ then
        +$   OPT_FILE = EXE_DIR+ OPT_FILE
        +$ endif
        +$!
        +$! Initialise logical names and such
        +$!
        +$ GOSUB INITIALISE
        +$!
        +$! Tell The User What Kind of Machine We Run On.
        +$!
        +$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
        +$!
        +$!
        +$! Check To See If The Architecture Specific OBJ Directory Exists.
        +$!
        +$ IF (F$PARSE(OBJ_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIR 'OBJ_DIR'
        +$!
        +$! End The Architecture Specific OBJ Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If The Architecture Specific Directory Exists.
        +$!
        +$ IF (F$PARSE(EXE_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIRECTORY 'EXE_DIR'
        +$!
        +$! End The Architecture Specific Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Define The Library Name.
        +$!
        +$ LIB_NAME := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB
        +$!
        +$! Define The CRYPTO-LIB We Are To Use.
        +$!
        +$ CRYPTO_LIB := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB
        +$!
        +$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library...
        +$!
        +$ IF (F$SEARCH(LIB_NAME).EQS."")
        +$ THEN
        +$!
        +$! Guess Not, Create The Library.
        +$!
        +$   LIBRARY/CREATE/OBJECT 'LIB_NAME'
        +$!
        +$! End The Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Build our options file for the application
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Define The Different Encryption "library" Strings.
        +$!
        +$ APPS_DES = "DES/DES,CBC3_ENC"
        +$ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
        +$
        +$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,"+ -
        +	"ebcdic,uid,o_time,o_str,o_dir,o_fips.c,o_init,fips_ers"
        +$ LIB_MD2 = "md2_dgst,md2_one"
        +$ LIB_MD4 = "md4_dgst,md4_one"
        +$ LIB_MD5 = "md5_dgst,md5_one"
        +$ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512"
        +$ LIB_MDC2 = "mdc2dgst,mdc2_one"
        +$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth"
        +$ LIB_RIPEMD = "rmd_dgst,rmd_one"
        +$ LIB_WHRLPOOL = "wp_dgst,wp_block"
        +$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
        +	"ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
        +	"enc_read,enc_writ,ofb64enc,"+ -
        +	"ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
        +	"des_enc,fcrypt_b,"+ -
        +	"fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
        +	"ede_cbcm_enc,des_old,des_old2,read2pwd"
        +$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
        +$ LIB_RC4 = "rc4_skey,rc4_enc,rc4_utl"
        +$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
        +$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
        +$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
        +$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
        +$ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
        +	"cmll_cfb,cmll_ctr,cmll_utl"
        +$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
        +$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128,gcm128,"+ -
        +	"ccm128,xts128"
        +$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
        +$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
        +     LIB_BN_ASM = "bn_asm"
        +$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
        +	"bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
        +	"bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
        +	"bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
        +	"bn_depr,bn_const,bn_x931p"
        +$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
        +	"ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
        +	"ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn,"+ -
        +	"ecp_nistp224,ecp_nistp256,ecp_nistp521,ecp_nistputil,"+ -
        +	"ecp_oct,ec2_oct,ec_oct"
        +$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
        +	"rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
        +	"rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
        +	"rsa_pmeth,rsa_crpt"
        +$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
        +	"dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
        +$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
        +$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ -
        +	"dh_ameth,dh_pmeth,dh_prn"
        +$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
        +$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
        +	"dso_openssl,dso_win32,dso_vms,dso_beos"
        +$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
        +	"eng_table,eng_pkey,eng_fat,eng_all,"+ -
        +	"tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
        +	"tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
        +	"eng_openssl,eng_dyn,eng_cnf,eng_cryptodev,"+ -
        +	"eng_rsax,eng_rdrand"
        +$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr,"+ -
        +	"aes_ige,aes_wrap"
        +$ LIB_BUFFER = "buffer,buf_str,buf_err"
        +$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
        +	"bss_mem,bss_null,bss_fd,"+ -
        +	"bss_file,bss_sock,bss_conn,"+ -
        +	"bf_null,bf_buff,b_print,b_dump,"+ -
        +	"b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log,"+ -
        +	"bss_dgram,"+ -
        +	"bf_lbuf"
        +$ LIB_STACK = "stack"
        +$ LIB_LHASH = "lhash,lh_stats"
        +$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
        +	"rand_vms"
        +$ LIB_ERR = "err,err_all,err_prn"
        +$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
        +$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,evp_cnf,"+ -
        +	"e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
        +	"e_rc4,e_aes,names,e_seed,"+ -
        +	"e_xcbc_d,e_rc2,e_cast,e_rc5"
        +$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
        +	"m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
        +	"p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
        +	"bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
        +	"c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
        +	"evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
        +$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver,evp_fips,"+ -
        +	"e_aes_cbc_hmac_sha1,e_rc4_hmac_md5"
        +$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
        +	"a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
        +	"a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
        +	"x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ -
        +	"x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ -
        +	"x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr"
        +$ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
        +	"tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
        +	"tasn_prn,ameth_lib,"+ -
        +	"f_int,f_string,n_pkey,"+ -
        +	"f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ -
        +	"asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ -
        +	"evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
        +$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
        +	"pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt"
        +$ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
        +	"x509_obj,x509_req,x509spki,x509_vfy,"+ -
        +	"x509_set,x509cset,x509rset,x509_err,"+ -
        +	"x509name,x509_v3,x509_ext,x509_att,"+ -
        +	"x509type,x509_lu,x_all,x509_txt,"+ -
        +	"x509_trs,by_file,by_dir,x509_vpm"
        +$ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ -
        +	"v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ -
        +	"v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ -
        +	"v3_ocsp,v3_akeya,v3_pmaps,v3_pcons,v3_ncons,v3_pcia,v3_pci,"+ -
        +	"pcy_cache,pcy_node,pcy_data,pcy_map,pcy_tree,pcy_lib,"+ -
        +	"v3_asid,v3_addr"
        +$ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
        +$ LIB_TXT_DB = "txt_db"
        +$ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
        +	"pk7_mime,bio_pk7"
        +$ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ -
        +	"p12_init,p12_key,p12_kiss,p12_mutl,"+ -
        +	"p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e"
        +$ LIB_COMP = "comp_lib,comp_err,"+ -
        +	"c_rle,c_zlib"
        +$ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ -
        +	"ocsp_srv,ocsp_prn,ocsp_vfy,ocsp_err"
        +$ LIB_UI_COMPAT = ",ui_compat"
        +$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT
        +$ LIB_KRB5 = "krb5_asn"
        +$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
        +	"cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess,"+ -
        +	"cms_pwri"
        +$ LIB_PQUEUE = "pqueue"
        +$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
        +	"ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
        +	"ts_asn1"
        +$ LIB_JPAKE = "jpake,jpake_err"
        +$ LIB_SRP = "srp_lib,srp_vfy"
        +$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
        +$ LIB_CMAC = "cmac,cm_ameth.c,cm_pmeth"
        +$!
        +$! Setup exceptional compilations
        +$!
        +$ CC3_SHOWN = 0
        +$ CC4_SHOWN = 0
        +$ CC5_SHOWN = 0
        +$ CC6_SHOWN = 0
        +$!
        +$! The following lists must have leading and trailing commas, and no
        +$! embedded spaces.  (They are scanned for ",name,".)
        +$!
        +$ ! Add definitions for no threads on OpenVMS 7.1 and higher.
        +$ COMPILEWITH_CC3 = ",bss_rtcp,"
        +$ ! Disable the DOLLARID warning.  Not needed with /STANDARD=RELAXED.
        +$ COMPILEWITH_CC4 = "" !!! ",a_utctm,bss_log,o_time,o_dir,"
        +$ ! Disable disjoint optimization on VAX with DECC.
        +$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + -
        +                    "seed,sha_dgst,sha1dgst,rmd_dgst,bf_enc,"
        +$ ! Disable the MIXLINKAGE warning.
        +$ COMPILEWITH_CC6 = "" !!! ",enc_read,set_key,"
        +$!
        +$! Figure Out What Other Modules We Are To Build.
        +$!
        +$ BUILD_SET:
        +$!
        +$! Define A Module Counter.
        +$!
        +$ MODULE_COUNTER = 0
        +$!
        +$! Top Of The Loop.
        +$!
        +$ MODULE_NEXT:
        +$!
        +$! Extract The Module Name From The Encryption List.
        +$!
        +$ MODULE_NAME = F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES)
        +$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = ""
        +$ MODULE_NAME1 = MODULE_NAME
        +$!
        +$! Check To See If We Are At The End Of The Module List.
        +$!
        +$ IF (MODULE_NAME.EQS.",") 
        +$ THEN 
        +$!
        +$!  We Are At The End Of The Module List, Go To MODULE_DONE.
        +$!
        +$   GOTO MODULE_DONE
        +$!
        +$! End The Module List Check.
        +$!
        +$ ENDIF
        +$!
        +$! Increment The Moudle Counter.
        +$!
        +$ MODULE_COUNTER = MODULE_COUNTER + 1
        +$!
        +$! Create The Library and Apps Module Names.
        +$!
        +$ LIB_MODULE = "LIB_" + MODULE_NAME
        +$ APPS_MODULE = "APPS_" + MODULE_NAME
        +$ IF (F$EXTRACT(0,5,MODULE_NAME).EQS."ASN1_")
        +$ THEN
        +$   MODULE_NAME = "ASN1"
        +$ ENDIF
        +$ IF (F$EXTRACT(0,4,MODULE_NAME).EQS."EVP_")
        +$ THEN
        +$   MODULE_NAME = "EVP"
        +$ ENDIF
        +$!
        +$! Set state (can be LIB and APPS)
        +$!
        +$ STATE = "LIB"
        +$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS"
        +$!
        +$! Check if the library module name actually is defined
        +$!
        +$ IF F$TYPE('LIB_MODULE') .EQS. ""
        +$ THEN
        +$   WRITE SYS$ERROR ""
        +$   WRITE SYS$ERROR "The module ",MODULE_NAME1," does not exist.  Continuing..."
        +$   WRITE SYS$ERROR ""
        +$   GOTO MODULE_NEXT
        +$ ENDIF
        +$!
        +$! Top Of The Module Loop.
        +$!
        +$ MODULE_AGAIN:
        +$!
        +$! Tell The User What Module We Are Building.
        +$!
        +$ IF (MODULE_NAME1.NES."") 
        +$ THEN
        +$   IF STATE .EQS. "LIB"
        +$   THEN
        +$     WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")"
        +$   ELSE IF F$TYPE('APPS_MODULE') .NES. ""
        +$     THEN
        +$       WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")"
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$!  Define A File Counter And Set It To "0".
        +$!
        +$ FILE_COUNTER = 0
        +$ APPLICATION = ""
        +$ APPLICATION_COUNTER = 0
        +$!
        +$! Top Of The File Loop.
        +$!
        +$ NEXT_FILE:
        +$!
        +$! Look in the LIB_MODULE is we're in state LIB
        +$!
        +$ IF STATE .EQS. "LIB"
        +$ THEN
        +$!
        +$!   O.K, Extract The File Name From The File List.
        +$!
        +$   FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE')
        +$!
        +$!   else
        +$!
        +$ ELSE
        +$   FILE_NAME = ","
        +$!
        +$   IF F$TYPE('APPS_MODULE') .NES. ""
        +$   THEN
        +$!
        +$!     Extract The File Name From The File List.
        +$!     This part is a bit more complicated.
        +$!
        +$     IF APPLICATION .EQS. ""
        +$     THEN
        +$       APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
        +$       APPLICATION_COUNTER = APPLICATION_COUNTER + 1
        +$       APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
        +$       APPLICATION = F$ELEMENT(0,"/",APPLICATION)
        +$       FILE_COUNTER = 0
        +$     ENDIF
        +$
        +$!     WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
        +$!     SHOW SYMBOL APPLICATION*
        +$!
        +$     IF APPLICATION .NES. ";"
        +$     THEN
        +$       FILE_NAME = F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS)
        +$       IF FILE_NAME .EQS. ","
        +$       THEN
        +$         APPLICATION = ""
        +$         GOTO NEXT_FILE
        +$       ENDIF
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Check To See If We Are At The End Of The File List.
        +$!
        +$ IF (FILE_NAME.EQS.",") 
        +$ THEN 
        +$!
        +$!  We Are At The End Of The File List, Change State Or Goto FILE_DONE.
        +$!
        +$   IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY"
        +$   THEN
        +$     STATE = "APPS"
        +$     GOTO MODULE_AGAIN
        +$   ELSE
        +$     GOTO FILE_DONE
        +$   ENDIF
        +$!
        +$! End The File List Check.
        +$!
        +$ ENDIF
        +$!
        +$! Increment The Counter.
        +$!
        +$ FILE_COUNTER = FILE_COUNTER + 1
        +$!
        +$! Create The Source File Name.
        +$!
        +$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME)
        +$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME
        +$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN -
        +	FILE_NAME = FILE_NAME + ".c"
        +$ IF (MODULE_NAME.NES."")
        +$ THEN
        +$   SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME
        +$ ELSE
        +$   SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME
        +$ ENDIF
        +$ SOURCE_FILE = SOURCE_FILE - "]["
        +$!
        +$! Create The Object File Name.
        +$!
        +$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
        +$ ON WARNING THEN GOTO NEXT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Is Actually There.
        +$!
        +$ IF (F$SEARCH(SOURCE_FILE).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Doesn't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   GOTO EXIT
        +$!
        +$! End The File Exist Check.
        +$!
        +$ ENDIF
        +$!
        +$! Tell The User We Are Compiling The File.
        +$!
        +$ IF (MODULE_NAME.EQS."")
        +$ THEN
        +$   WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File.  (",BUILDALL,",",STATE,")"
        +$ ENDIF
        +$ IF (MODULE_NAME.NES."")
        +$ THEN 
        +$   WRITE SYS$OUTPUT "        ",FILE_NAME,""
        +$ ENDIF
        +$!
        +$! Compile The File.
        +$!
        +$ ON ERROR THEN GOTO NEXT_FILE
        +$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ ","
        +$ IF FILE_NAME - ".mar" .NES. FILE_NAME
        +$ THEN
        +$   MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$ ELSE
        +$   IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3
        +$   THEN
        +$     write sys$output "        \Using special rule (3)"
        +$     if (.not. CC3_SHOWN)
        +$     then
        +$       CC3_SHOWN = 1
        +$       x = "    "+ CC3
        +$       write /symbol sys$output x
        +$     endif
        +$     CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$   ELSE
        +$     IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4
        +$     THEN
        +$       write /symbol sys$output "        \Using special rule (4)"
        +$       if (.not. CC4_SHOWN)
        +$       then
        +$         CC4_SHOWN = 1
        +$         x = "    "+ CC4
        +$         write /symbol sys$output x
        +$       endif
        +$       CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$     ELSE
        +$       IF CC5_DIFFERENT .AND. -
        +         (COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5)
        +$       THEN
        +$         write sys$output "        \Using special rule (5)"
        +$         if (.not. CC5_SHOWN)
        +$         then
        +$           CC5_SHOWN = 1
        +$           x = "    "+ CC5
        +$           write /symbol sys$output x
        +$         endif
        +$         CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$       ELSE
        +$         IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6
        +$         THEN
        +$           write sys$output "        \Using special rule (6)"
        +$           if (.not. CC6_SHOWN)
        +$           then
        +$             CC6_SHOWN = 1
        +$             x = "    "+ CC6
        +$             write /symbol sys$output x
        +$           endif
        +$           CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$         ELSE
        +$           CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$         ENDIF
        +$       ENDIF
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$ IF STATE .EQS. "LIB"
        +$ THEN 
        +$!
        +$!   Add It To The Library.
        +$!
        +$   LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE'
        +$!
        +$!   Time To Clean Up The Object File.
        +$!
        +$   DELETE 'OBJECT_FILE';*
        +$ ENDIF
        +$!
        +$! Go Back And Do It Again.
        +$!
        +$ GOTO NEXT_FILE
        +$!
        +$! All Done With This Library Part.
        +$!
        +$ FILE_DONE:
        +$!
        +$! Time To Build Some Applications
        +$!
        +$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY"
        +$ THEN
        +$   APPLICATION_COUNTER = 0
        +$ NEXT_APPLICATION:
        +$   APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
        +$   IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE
        +$
        +$   APPLICATION_COUNTER = APPLICATION_COUNTER + 1
        +$   APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
        +$   APPLICATION = F$ELEMENT(0,"/",APPLICATION)
        +$
        +$!   WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
        +$!   SHOW SYMBOL APPLICATION*
        +$!
        +$! Tell the user what happens
        +$!
        +$   WRITE SYS$OUTPUT "        ",APPLICATION,".exe"
        +$!
        +$! Link The Program.
        +$!
        +$   ON ERROR THEN GOTO NEXT_APPLICATION
        +$!
        +$!  Link With A TCP/IP Library.
        +$!
        +$   LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' -
        +     /EXE='EXE_DIR''APPLICATION'.EXE -
        +     'OBJ_DIR''APPLICATION_OBJECTS', -
        +     'CRYPTO_LIB'/LIBRARY -
        +     'TCPIP_LIB' -
        +     'ZLIB_LIB' -
        +     ,'OPT_FILE' /OPTIONS
        +$!
        +$   GOTO NEXT_APPLICATION
        +$  APPLICATION_DONE:
        +$ ENDIF
        +$!
        +$! Go Back And Get The Next Module.
        +$!
        +$ GOTO MODULE_NEXT
        +$!
        +$! All Done With This Module.
        +$!
        +$ MODULE_DONE:
        +$!
        +$! Tell The User That We Are All Done.
        +$!
        +$ WRITE SYS$OUTPUT "All Done..."
        +$ EXIT:
        +$ GOSUB CLEANUP
        +$ EXIT
        +$!
        +$! Check For The Link Option FIle.
        +$!
        +$ CHECK_OPT_FILE:
        +$!
        +$! Check To See If We Need To Make A VAX C Option File.
        +$!
        +$ IF (COMPILER.EQS."VAXC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A VAX C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A VAX C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable VAX C Runtime Library.
        +!
        +SYS$SHARE:VAXCRTL.EXE/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The VAXC Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A GNU C Option File.
        +$!
        +$ IF (COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A GNU C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A GNU C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +GNU_CC:[000000]GCCLIB/LIBRARY
        +SYS$SHARE:VAXCRTL/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The GNU C Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A DEC C Option File.
        +$!
        +$ IF (COMPILER.EQS."DECC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A DEC C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
        +$!
        +$     IF ARCH .EQS. "VAX"
        +$     THEN
        +$!
        +$!      We Need A DEC C Linker Option File For VAX.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable DEC C Runtime Library.
        +!
        +SYS$SHARE:DECC$SHR.EXE/SHARE
        +$EOD
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Create The non-VAX Linker Option File.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File For non-VAX To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
        +SYS$SHARE:CMA$OPEN_RTL/SHARE
        +$EOD
        +$!
        +$!    End The DEC C Option File Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The Option File Search.
        +$!
        +$   ENDIF
        +$!
        +$! End The DEC C Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What Linker Option File We Are Using.
        +$!
        +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Check To See If P1 Is Blank.
        +$!
        +$ IF (P1.EQS."ALL")
        +$ THEN
        +$!
        +$!   P1 Is Blank, So Build Everything.
        +$!
        +$    BUILDALL = "TRUE"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Else, Check To See If P1 Has A Valid Argument.
        +$!
        +$   IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS")
        +$   THEN
        +$!
        +$!    A Valid Argument.
        +$!
        +$     BUILDALL = P1
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
        +$     WRITE SYS$OUTPUT "    LIBRARY  :  To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
        +$     WRITE SYS$OUTPUT "    APPS     :  To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs."
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha Architecture."
        +$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 Architecture."
        +$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P1 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If P2 Is Blank.
        +$!
        +$ IF (P2.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!  P2 Is NODEBUG, So Compile Without The Debugger Information.
        +$!
        +$   DEBUGGER = "NODEBUG"
        +$   LINKMAP = "NOMAP"
        +$   TRACEBACK = "NOTRACEBACK" 
        +$   GCC_OPTIMIZE = "OPTIMIZE"
        +$   CC_OPTIMIZE = "OPTIMIZE"
        +$   MACRO_OPTIMIZE = "OPTIMIZE"
        +$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
        +$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (P2.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER = "DEBUG"
        +$     LINKMAP = "MAP"
        +$     TRACEBACK = "TRACEBACK"
        +$     GCC_OPTIMIZE = "NOOPTIMIZE"
        +$     CC_OPTIMIZE = "NOOPTIMIZE"
        +$     MACRO_OPTIMIZE = "NOOPTIMIZE"
        +$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
        +$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
        +$   ELSE 
        +$!
        +$!    They Entered An Invalid Option.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "     DEBUG   :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "     NODEBUG :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P2 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For P5.
        +$!
        +$ IF (P5.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN :=
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P5 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check P7 (POINTER_SIZE).
        +$!
        +$ IF (P7 .NES. "") .AND. (ARCH .NES. "VAX")
        +$ THEN
        +$!
        +$   IF (P7 .EQS. "32")
        +$   THEN
        +$     POINTER_SIZE = " /POINTER_SIZE=32"
        +$   ELSE
        +$     POINTER_SIZE = F$EDIT( P7, "COLLAPSE, UPCASE")
        +$     IF ((POINTER_SIZE .EQS. "64") .OR. -
        +       (POINTER_SIZE .EQS. "64=") .OR. -
        +       (POINTER_SIZE .EQS. "64=ARGV"))
        +$     THEN
        +$       ARCHD = ARCH+ "_64"
        +$       LIB32 = ""
        +$       POINTER_SIZE = " /POINTER_SIZE=64"
        +$     ELSE
        +$!
        +$!      Tell The User Entered An Invalid Option.
        +$!
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", P7, -
        +         " Is Invalid.  The Valid Options Are:"
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT -
        +         "    """"       :  Compile with default (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    32       :  Compile with 32-bit (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
        +$       WRITE SYS$OUTPUT ""
        +$! 
        +$!      Time To EXIT.
        +$!
        +$       EXIT
        +$!
        +$     ENDIF
        +$!
        +$   ENDIF
        +$!
        +$! End The P7 (POINTER_SIZE) Check.
        +$!
        +$ ENDIF
        +$!
        +$! Set basic C compiler /INCLUDE directories.
        +$!
        +$ CC_INCLUDES = "SYS$DISK:[.''ARCHD'],SYS$DISK:[],SYS$DISK:[-],"+ -
        +   "SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.MODES],SYS$DISK:[.ASN1],SYS$DISK:[.EVP]"
        +$!
        +$! Check To See If P3 Is Blank.
        +$!
        +$ IF (P3.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     P3 = "GNUC"
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Check To See If We Have VAXC Or DECC.
        +$!
        +$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
        +$     THEN 
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       P3 = "DECC"
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       P3 = "VAXC"
        +$!
        +$!    End The VAXC Compiler Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  End The Compiler Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Have A Option For P4.
        +$!
        +$ IF (P4.EQS."")
        +$ THEN
        +$!
        +$!  Find out what socket library we have available
        +$!
        +$   IF F$PARSE("SOCKETSHR:") .NES. ""
        +$   THEN
        +$!
        +$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
        +$!
        +$     P4 = "SOCKETSHR"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
        +$!
        +$!    Else, let's look for something else
        +$!
        +$   ELSE
        +$!
        +$!    Like UCX (the reason to do this before Multinet is that the UCX
        +$!    emulation is easier to use...)
        +$!
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
        +	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
        +	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
        +$     THEN
        +$!
        +$!	Last resort: a UCX or UCX-compatible library
        +$!
        +$	P4 = "UCX"
        +$!
        +$!      Tell the user
        +$!
        +$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
        +$!
        +$!	That was all...
        +$!
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Set Up Initial CC Definitions, Possibly With User Ones
        +$!
        +$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS"
        +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
        +$ CCEXTRAFLAGS = ""
        +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
        +$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
        +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
        +	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
        +$!
        +$! Check To See If We Have A ZLIB Option.
        +$!
        +$ ZLIB = P8
        +$ IF (ZLIB .NES. "")
        +$ THEN
        +$!
        +$!  Check for expected ZLIB files.
        +$!
        +$   err = 0
        +$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
        +$   if (f$search( file1) .eqs. "")
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
        +$     err = 1
        +$   endif
        +$   file1 = f$parse( "A.;", ZLIB)- "A.;"
        +$!
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     if (err .eq. 0)
        +$     then
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     endif
        +$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
        +$     WRITE SYS$OUTPUT ""
        +$     err = err+ 2
        +$   endif
        +$   if (err .eq. 1)
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$   endif
        +$!
        +$   if (err .ne. 0)
        +$   then
        +$     EXIT
        +$   endif
        +$!
        +$   CCDEFS = """ZLIB=1"", "+ CCDEFS
        +$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
        +$   ZLIB_LIB = ", ''file2' /library"
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
        +$!
        +$! End The ZLIB Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Check To See If The User Entered A Valid Parameter.
        +$!
        +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
        +$ THEN
        +$!
        +$!    Check To See If The User Wanted DECC.
        +$!
        +$   IF (P3.EQS."DECC")
        +$   THEN
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    Use DECC...
        +$!
        +$     CC = "CC"
        +$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
        +	 THEN CC = "CC/DECC"
        +$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
        +       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
        +       " /INCLUDE=(''CC_INCLUDES')"+ -
        +       CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
        +$!
        +$!  End DECC Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use VAXC.
        +$!
        +$   IF (P3.EQS."VAXC")
        +$   THEN
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$!
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    Compile Using VAXC.
        +$!
        +$     CC = "CC"
        +$     IF ARCH.NES."VAX"
        +$     THEN
        +$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
        +$	EXIT
        +$     ENDIF
        +$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
        +$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +       "/INCLUDE=(''CC_INCLUDES')"+ -
        +	   CCEXTRAFLAGS
        +$     CCDEFS = """VAXC""," + CCDEFS
        +$!
        +$!    Define <sys> As SYS$COMMON:[SYSLIB]
        +$!
        +$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
        +$!
        +$!  End VAXC Check
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use GNU C.
        +$!
        +$   IF (P3.EQS."GNUC")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    Use GNU C...
        +$!
        +$     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +       "/INCLUDE=(''CC_INCLUDES')"+ -
        +	   CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
        +$!
        +$!  End The GNU C Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Set up default defines
        +$!
        +$   CCDEFS = """FLAT_INC=1""," + CCDEFS
        +$!
        +$!  Finish up the definition of CC.
        +$!
        +$   IF COMPILER .EQS. "DECC"
        +$   THEN
        +$     IF CCDISABLEWARNINGS .EQS. ""
        +$     THEN
        +$       CC4DISABLEWARNINGS = "DOLLARID"
        +$       CC6DISABLEWARNINGS = "MIXLINKAGE"
        +$     ELSE
        +$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
        +$       CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE"
        +$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
        +$     ENDIF
        +$     CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
        +$     CC6DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))"
        +$   ELSE
        +$     CCDISABLEWARNINGS = ""
        +$     CC4DISABLEWARNINGS = ""
        +$     CC6DISABLEWARNINGS = ""
        +$   ENDIF
        +$   CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
        +$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
        +$   IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG"
        +$   THEN
        +$     CC5 = CC + " /OPTIMIZE=NODISJOINT"
        +$     CC5_DIFFERENT = 1
        +$   ELSE
        +$     CC5 = CC
        +$     CC5_DIFFERENT = 0
        +$   ENDIF
        +$   CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
        +$   CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS
        +$!
        +$!  Show user the result
        +$!
        +$   WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$! End The Valid Argument Check.
        +$!
        +$ ENDIF
        +$!
        +$! Build a MACRO command for the architecture at hand
        +$!
        +$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
        +$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
        +$!
        +$!  Show user the result
        +$!
        +$   WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
        +$!
        +$! Time to check the contents, and to make sure we get the correct library.
        +$!
        +$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
        +     .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
        +$ THEN
        +$!
        +$!  Check to see if SOCKETSHR was chosen
        +$!
        +$   IF P4.EQS."SOCKETSHR"
        +$   THEN
        +$!
        +$!    Set the library to use SOCKETSHR
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
        +$!
        +$!    Done with SOCKETSHR
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if MULTINET was chosen
        +$!
        +$   IF P4.EQS."MULTINET"
        +$   THEN
        +$!
        +$!    Set the library to use UCX emulation.
        +$!
        +$     P4 = "UCX"
        +$!
        +$!    Done with MULTINET
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if UCX was chosen
        +$!
        +$   IF P4.EQS."UCX"
        +$   THEN
        +$!
        +$!    Set the library to use UCX.
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
        +$     THEN
        +$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
        +$     ELSE
        +$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
        +	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
        +$     ENDIF
        +$!
        +$!    Done with UCX
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if TCPIP was chosen
        +$!
        +$   IF P4.EQS."TCPIP"
        +$   THEN
        +$!
        +$!    Set the library to use TCPIP (post UCX).
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if NONE was chosen
        +$!
        +$   IF P4.EQS."NONE"
        +$   THEN
        +$!
        +$!    Do not use a TCPIP library.
        +$!
        +$     TCPIP_LIB = ""
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P4," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
        +$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
        +$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$!  Done with TCP/IP libraries
        +$!
        +$ ENDIF
        +$!
        +$! Check if the user wanted to compile just a subset of all the encryption
        +$! methods.
        +$!
        +$ IF P6 .NES. ""
        +$ THEN
        +$   ENCRYPT_TYPES = P6
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        +$!
        +$ INITIALISE:
        +$!
        +$! Save old value of the logical name OPENSSL
        +$!
        +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
        +$!
        +$! Save directory information
        +$!
        +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
        +$ __HERE = F$EDIT(__HERE,"UPCASE")
        +$ __TOP = __HERE - "CRYPTO]"
        +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
        +$!
        +$! Set up the logical name OPENSSL to point at the include directory
        +$!
        +$ DEFINE OPENSSL/NOLOG '__INCLUDE'
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        +$ CLEANUP:
        +$!
        +$! Restore the logical name OPENSSL if it had a value
        +$!
        +$ IF __SAVE_OPENSSL .EQS. ""
        +$ THEN
        +$   DEASSIGN OPENSSL
        +$ ELSE
        +$   DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
        +$ ENDIF
        +$!
        +$! Done
        +$!
        +$ RETURN
        diff --git a/vendor/openssl/openssl/crypto/crypto.h b/vendor/openssl/openssl/crypto/crypto.h
        new file mode 100644
        index 000000000..f92fc5182
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/crypto.h
        @@ -0,0 +1,611 @@
        +/* crypto/crypto.h */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#ifndef HEADER_CRYPTO_H
        +#define HEADER_CRYPTO_H
        +
        +#include <stdlib.h>
        +
        +#include <openssl/e_os2.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +#include <stdio.h>
        +#endif
        +
        +#include <openssl/stack.h>
        +#include <openssl/safestack.h>
        +#include <openssl/opensslv.h>
        +#include <openssl/ossl_typ.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +/* Resolve problems on some operating systems with symbol names that clash
        +   one way or another */
        +#include <openssl/symhacks.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Backward compatibility to SSLeay */
        +/* This is more to be used to check the correct DLL is being used
        + * in the MS world. */
        +#define SSLEAY_VERSION_NUMBER	OPENSSL_VERSION_NUMBER
        +#define SSLEAY_VERSION		0
        +/* #define SSLEAY_OPTIONS	1 no longer supported */
        +#define SSLEAY_CFLAGS		2
        +#define SSLEAY_BUILT_ON		3
        +#define SSLEAY_PLATFORM		4
        +#define SSLEAY_DIR		5
        +
        +/* Already declared in ossl_typ.h */
        +#if 0
        +typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
        +/* Called when a new object is created */
        +typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +					int idx, long argl, void *argp);
        +/* Called when an object is free()ed */
        +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +					int idx, long argl, void *argp);
        +/* Called when we need to dup an object */
        +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
        +					int idx, long argl, void *argp);
        +#endif
        +
        +/* A generic structure to pass assorted data in a expandable way */
        +typedef struct openssl_item_st
        +	{
        +	int code;
        +	void *value;		/* Not used for flag attributes */
        +	size_t value_size;	/* Max size of value for output, length for input */
        +	size_t *value_length;	/* Returned length of value for output */
        +	} OPENSSL_ITEM;
        +
        +
        +/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
        + * names in cryptlib.c
        + */
        +
        +#define	CRYPTO_LOCK_ERR			1
        +#define	CRYPTO_LOCK_EX_DATA		2
        +#define	CRYPTO_LOCK_X509		3
        +#define	CRYPTO_LOCK_X509_INFO		4
        +#define	CRYPTO_LOCK_X509_PKEY		5
        +#define CRYPTO_LOCK_X509_CRL		6
        +#define CRYPTO_LOCK_X509_REQ		7
        +#define CRYPTO_LOCK_DSA			8
        +#define CRYPTO_LOCK_RSA			9
        +#define CRYPTO_LOCK_EVP_PKEY		10
        +#define CRYPTO_LOCK_X509_STORE		11
        +#define CRYPTO_LOCK_SSL_CTX		12
        +#define CRYPTO_LOCK_SSL_CERT		13
        +#define CRYPTO_LOCK_SSL_SESSION		14
        +#define CRYPTO_LOCK_SSL_SESS_CERT	15
        +#define CRYPTO_LOCK_SSL			16
        +#define CRYPTO_LOCK_SSL_METHOD		17
        +#define CRYPTO_LOCK_RAND		18
        +#define CRYPTO_LOCK_RAND2		19
        +#define CRYPTO_LOCK_MALLOC		20
        +#define CRYPTO_LOCK_BIO			21
        +#define CRYPTO_LOCK_GETHOSTBYNAME	22
        +#define CRYPTO_LOCK_GETSERVBYNAME	23
        +#define CRYPTO_LOCK_READDIR		24
        +#define CRYPTO_LOCK_RSA_BLINDING	25
        +#define CRYPTO_LOCK_DH			26
        +#define CRYPTO_LOCK_MALLOC2		27
        +#define CRYPTO_LOCK_DSO			28
        +#define CRYPTO_LOCK_DYNLOCK		29
        +#define CRYPTO_LOCK_ENGINE		30
        +#define CRYPTO_LOCK_UI			31
        +#define CRYPTO_LOCK_ECDSA               32
        +#define CRYPTO_LOCK_EC			33
        +#define CRYPTO_LOCK_ECDH		34
        +#define CRYPTO_LOCK_BN  		35
        +#define CRYPTO_LOCK_EC_PRE_COMP		36
        +#define CRYPTO_LOCK_STORE		37
        +#define CRYPTO_LOCK_COMP		38
        +#define CRYPTO_LOCK_FIPS		39
        +#define CRYPTO_LOCK_FIPS2		40
        +#define CRYPTO_NUM_LOCKS		41
        +
        +#define CRYPTO_LOCK		1
        +#define CRYPTO_UNLOCK		2
        +#define CRYPTO_READ		4
        +#define CRYPTO_WRITE		8
        +
        +#ifndef OPENSSL_NO_LOCKING
        +#ifndef CRYPTO_w_lock
        +#define CRYPTO_w_lock(type)	\
        +	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
        +#define CRYPTO_w_unlock(type)	\
        +	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
        +#define CRYPTO_r_lock(type)	\
        +	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
        +#define CRYPTO_r_unlock(type)	\
        +	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
        +#define CRYPTO_add(addr,amount,type)	\
        +	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
        +#endif
        +#else
        +#define CRYPTO_w_lock(a)
        +#define CRYPTO_w_unlock(a)
        +#define CRYPTO_r_lock(a)
        +#define CRYPTO_r_unlock(a)
        +#define CRYPTO_add(a,b,c)	((*(a))+=(b))
        +#endif
        +
        +/* Some applications as well as some parts of OpenSSL need to allocate
        +   and deallocate locks in a dynamic fashion.  The following typedef
        +   makes this possible in a type-safe manner.  */
        +/* struct CRYPTO_dynlock_value has to be defined by the application. */
        +typedef struct
        +	{
        +	int references;
        +	struct CRYPTO_dynlock_value *data;
        +	} CRYPTO_dynlock;
        +
        +
        +/* The following can be used to detect memory leaks in the SSLeay library.
        + * It used, it turns on malloc checking */
        +
        +#define CRYPTO_MEM_CHECK_OFF	0x0	/* an enume */
        +#define CRYPTO_MEM_CHECK_ON	0x1	/* a bit */
        +#define CRYPTO_MEM_CHECK_ENABLE	0x2	/* a bit */
        +#define CRYPTO_MEM_CHECK_DISABLE 0x3	/* an enume */
        +
        +/* The following are bit values to turn on or off options connected to the
        + * malloc checking functionality */
        +
        +/* Adds time to the memory checking information */
        +#define V_CRYPTO_MDEBUG_TIME	0x1 /* a bit */
        +/* Adds thread number to the memory checking information */
        +#define V_CRYPTO_MDEBUG_THREAD	0x2 /* a bit */
        +
        +#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
        +
        +
        +/* predec of the BIO type */
        +typedef struct bio_st BIO_dummy;
        +
        +struct crypto_ex_data_st
        +	{
        +	STACK_OF(void) *sk;
        +	int dummy; /* gcc is screwing up this data structure :-( */
        +	};
        +DECLARE_STACK_OF(void)
        +
        +/* This stuff is basically class callback functions
        + * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
        +
        +typedef struct crypto_ex_data_func_st
        +	{
        +	long argl;	/* Arbitary long */
        +	void *argp;	/* Arbitary void * */
        +	CRYPTO_EX_new *new_func;
        +	CRYPTO_EX_free *free_func;
        +	CRYPTO_EX_dup *dup_func;
        +	} CRYPTO_EX_DATA_FUNCS;
        +
        +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
        +
        +/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
        + * entry.
        + */
        +
        +#define CRYPTO_EX_INDEX_BIO		0
        +#define CRYPTO_EX_INDEX_SSL		1
        +#define CRYPTO_EX_INDEX_SSL_CTX		2
        +#define CRYPTO_EX_INDEX_SSL_SESSION	3
        +#define CRYPTO_EX_INDEX_X509_STORE	4
        +#define CRYPTO_EX_INDEX_X509_STORE_CTX	5
        +#define CRYPTO_EX_INDEX_RSA		6
        +#define CRYPTO_EX_INDEX_DSA		7
        +#define CRYPTO_EX_INDEX_DH		8
        +#define CRYPTO_EX_INDEX_ENGINE		9
        +#define CRYPTO_EX_INDEX_X509		10
        +#define CRYPTO_EX_INDEX_UI		11
        +#define CRYPTO_EX_INDEX_ECDSA		12
        +#define CRYPTO_EX_INDEX_ECDH		13
        +#define CRYPTO_EX_INDEX_COMP		14
        +#define CRYPTO_EX_INDEX_STORE		15
        +
        +/* Dynamically assigned indexes start from this value (don't use directly, use
        + * via CRYPTO_ex_data_new_class). */
        +#define CRYPTO_EX_INDEX_USER		100
        +
        +
        +/* This is the default callbacks, but we can have others as well:
        + * this is needed in Win32 where the application malloc and the
        + * library malloc may not be the same.
        + */
        +#define CRYPTO_malloc_init()	CRYPTO_set_mem_functions(\
        +	malloc, realloc, free)
        +
        +#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
        +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */
        +#  define CRYPTO_MDEBUG
        +# endif
        +#endif
        +
        +/* Set standard debugging functions (not done by default
        + * unless CRYPTO_MDEBUG is defined) */
        +#define CRYPTO_malloc_debug_init()	do {\
        +	CRYPTO_set_mem_debug_functions(\
        +		CRYPTO_dbg_malloc,\
        +		CRYPTO_dbg_realloc,\
        +		CRYPTO_dbg_free,\
        +		CRYPTO_dbg_set_options,\
        +		CRYPTO_dbg_get_options);\
        +	} while(0)
        +
        +int CRYPTO_mem_ctrl(int mode);
        +int CRYPTO_is_mem_check_on(void);
        +
        +/* for applications */
        +#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
        +#define MemCheck_stop()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
        +
        +/* for library-internal use */
        +#define MemCheck_on()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
        +#define MemCheck_off()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
        +#define is_MemCheck_on() CRYPTO_is_mem_check_on()
        +
        +#define OPENSSL_malloc(num)	CRYPTO_malloc((int)num,__FILE__,__LINE__)
        +#define OPENSSL_strdup(str)	CRYPTO_strdup((str),__FILE__,__LINE__)
        +#define OPENSSL_realloc(addr,num) \
        +	CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
        +#define OPENSSL_realloc_clean(addr,old_num,num) \
        +	CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
        +#define OPENSSL_remalloc(addr,num) \
        +	CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
        +#define OPENSSL_freeFunc	CRYPTO_free
        +#define OPENSSL_free(addr)	CRYPTO_free(addr)
        +
        +#define OPENSSL_malloc_locked(num) \
        +	CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
        +#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
        +
        +
        +const char *SSLeay_version(int type);
        +unsigned long SSLeay(void);
        +
        +int OPENSSL_issetugid(void);
        +
        +/* An opaque type representing an implementation of "ex_data" support */
        +typedef struct st_CRYPTO_EX_DATA_IMPL	CRYPTO_EX_DATA_IMPL;
        +/* Return an opaque pointer to the current "ex_data" implementation */
        +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
        +/* Sets the "ex_data" implementation to be used (if it's not too late) */
        +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
        +/* Get a new "ex_data" class, and return the corresponding "class_index" */
        +int CRYPTO_ex_data_new_class(void);
        +/* Within a given class, get/register a new index */
        +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
        +		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func);
        +/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given
        + * class (invokes whatever per-class callbacks are applicable) */
        +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
        +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
        +		CRYPTO_EX_DATA *from);
        +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
        +/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index
        + * (relative to the class type involved) */
        +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
        +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad,int idx);
        +/* This function cleans up all "ex_data" state. It mustn't be called under
        + * potential race-conditions. */
        +void CRYPTO_cleanup_all_ex_data(void);
        +
        +int CRYPTO_get_new_lockid(char *name);
        +
        +int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
        +void CRYPTO_lock(int mode, int type,const char *file,int line);
        +void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
        +					      const char *file,int line));
        +void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
        +		int line);
        +void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
        +					      const char *file, int line));
        +int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
        +					  const char *file,int line);
        +
        +/* Don't use this structure directly. */
        +typedef struct crypto_threadid_st
        +	{
        +	void *ptr;
        +	unsigned long val;
        +	} CRYPTO_THREADID;
        +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
        +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
        +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
        +int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
        +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
        +void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
        +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
        +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
        +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
        +#ifndef OPENSSL_NO_DEPRECATED
        +void CRYPTO_set_id_callback(unsigned long (*func)(void));
        +unsigned long (*CRYPTO_get_id_callback(void))(void);
        +unsigned long CRYPTO_thread_id(void);
        +#endif
        +
        +const char *CRYPTO_get_lock_name(int type);
        +int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
        +		    int line);
        +
        +int CRYPTO_get_new_dynlockid(void);
        +void CRYPTO_destroy_dynlockid(int i);
        +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
        +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line));
        +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line));
        +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line));
        +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file,int line);
        +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file,int line);
        +void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file,int line);
        +
        +/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions --
        + * call the latter last if you need different functions */
        +int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
        +int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *));
        +int CRYPTO_set_mem_ex_functions(void *(*m)(size_t,const char *,int),
        +                                void *(*r)(void *,size_t,const char *,int),
        +                                void (*f)(void *));
        +int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t,const char *,int),
        +                                       void (*free_func)(void *));
        +int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
        +				   void (*r)(void *,void *,int,const char *,int,int),
        +				   void (*f)(void *,int),
        +				   void (*so)(long),
        +				   long (*go)(void));
        +void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
        +void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
        +void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int),
        +                                 void *(**r)(void *, size_t,const char *,int),
        +                                 void (**f)(void *));
        +void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t,const char *,int),
        +                                        void (**f)(void *));
        +void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
        +				    void (**r)(void *,void *,int,const char *,int,int),
        +				    void (**f)(void *,int),
        +				    void (**so)(long),
        +				    long (**go)(void));
        +
        +void *CRYPTO_malloc_locked(int num, const char *file, int line);
        +void CRYPTO_free_locked(void *ptr);
        +void *CRYPTO_malloc(int num, const char *file, int line);
        +char *CRYPTO_strdup(const char *str, const char *file, int line);
        +void CRYPTO_free(void *ptr);
        +void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
        +void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
        +			   int line);
        +void *CRYPTO_remalloc(void *addr,int num, const char *file, int line);
        +
        +void OPENSSL_cleanse(void *ptr, size_t len);
        +
        +void CRYPTO_set_mem_debug_options(long bits);
        +long CRYPTO_get_mem_debug_options(void);
        +
        +#define CRYPTO_push_info(info) \
        +        CRYPTO_push_info_(info, __FILE__, __LINE__);
        +int CRYPTO_push_info_(const char *info, const char *file, int line);
        +int CRYPTO_pop_info(void);
        +int CRYPTO_remove_all_info(void);
        +
        +
        +/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
        + * used as default in CRYPTO_MDEBUG compilations): */
        +/* The last argument has the following significance:
        + *
        + * 0:	called before the actual memory allocation has taken place
        + * 1:	called after the actual memory allocation has taken place
        + */
        +void CRYPTO_dbg_malloc(void *addr,int num,const char *file,int line,int before_p);
        +void CRYPTO_dbg_realloc(void *addr1,void *addr2,int num,const char *file,int line,int before_p);
        +void CRYPTO_dbg_free(void *addr,int before_p);
        +/* Tell the debugging code about options.  By default, the following values
        + * apply:
        + *
        + * 0:                           Clear all options.
        + * V_CRYPTO_MDEBUG_TIME (1):    Set the "Show Time" option.
        + * V_CRYPTO_MDEBUG_THREAD (2):  Set the "Show Thread Number" option.
        + * V_CRYPTO_MDEBUG_ALL (3):     1 + 2
        + */
        +void CRYPTO_dbg_set_options(long bits);
        +long CRYPTO_dbg_get_options(void);
        +
        +
        +#ifndef OPENSSL_NO_FP_API
        +void CRYPTO_mem_leaks_fp(FILE *);
        +#endif
        +void CRYPTO_mem_leaks(struct bio_st *bio);
        +/* unsigned long order, char *file, int line, int num_bytes, char *addr */
        +typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *);
        +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);
        +
        +/* die if we have to */
        +void OpenSSLDie(const char *file,int line,const char *assertion);
        +#define OPENSSL_assert(e)       (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1))
        +
        +unsigned long *OPENSSL_ia32cap_loc(void);
        +#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
        +int OPENSSL_isservice(void);
        +
        +int FIPS_mode(void);
        +int FIPS_mode_set(int r);
        +
        +void OPENSSL_init(void);
        +
        +#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
        +
        +#ifdef OPENSSL_FIPS
        +#define fips_md_init_ctx(alg, cx) \
        +	int alg##_Init(cx##_CTX *c) \
        +	{ \
        +	if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
        +		"Low level API call to digest " #alg " forbidden in FIPS mode!"); \
        +	return private_##alg##_Init(c); \
        +	} \
        +	int private_##alg##_Init(cx##_CTX *c)
        +
        +#define fips_cipher_abort(alg) \
        +	if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
        +		"Low level API call to cipher " #alg " forbidden in FIPS mode!")
        +
        +#else
        +#define fips_md_init_ctx(alg, cx) \
        +	int alg##_Init(cx##_CTX *c)
        +#define fips_cipher_abort(alg) while(0)
        +#endif
        +
        +/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
        + * takes an amount of time dependent on |len|, but independent of the contents
        + * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
        + * defined order as the return value when a != b is undefined, other than to be
        + * non-zero. */
        +int CRYPTO_memcmp(const void *a, const void *b, size_t len);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_CRYPTO_strings(void);
        +
        +/* Error codes for the CRYPTO functions. */
        +
        +/* Function codes. */
        +#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX		 100
        +#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID		 103
        +#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID			 101
        +#define CRYPTO_F_CRYPTO_SET_EX_DATA			 102
        +#define CRYPTO_F_DEF_ADD_INDEX				 104
        +#define CRYPTO_F_DEF_GET_CLASS				 105
        +#define CRYPTO_F_FIPS_MODE_SET				 109
        +#define CRYPTO_F_INT_DUP_EX_DATA			 106
        +#define CRYPTO_F_INT_FREE_EX_DATA			 107
        +#define CRYPTO_F_INT_NEW_EX_DATA			 108
        +
        +/* Reason codes. */
        +#define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED		 101
        +#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK		 100
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/cversion.c b/vendor/openssl/openssl/crypto/cversion.c
        new file mode 100644
        index 000000000..ea9f25fd1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/cversion.c
        @@ -0,0 +1,117 @@
        +/* crypto/cversion.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 "cryptlib.h"
        +
        +#ifndef NO_WINDOWS_BRAINDEATH
        +#include "buildinf.h"
        +#endif
        +
        +const char *SSLeay_version(int t)
        +	{
        +	if (t == SSLEAY_VERSION)
        +		return OPENSSL_VERSION_TEXT;
        +	if (t == SSLEAY_BUILT_ON)
        +		{
        +#ifdef DATE
        +		static char buf[sizeof(DATE)+11];
        +
        +		BIO_snprintf(buf,sizeof buf,"built on: %s",DATE);
        +		return(buf);
        +#else
        +		return("built on: date not available");
        +#endif
        +		}
        +	if (t == SSLEAY_CFLAGS)
        +		{
        +#ifdef CFLAGS
        +		static char buf[sizeof(CFLAGS)+11];
        +
        +		BIO_snprintf(buf,sizeof buf,"compiler: %s",CFLAGS);
        +		return(buf);
        +#else
        +		return("compiler: information not available");
        +#endif
        +		}
        +	if (t == SSLEAY_PLATFORM)
        +		{
        +#ifdef PLATFORM
        +		static char buf[sizeof(PLATFORM)+11];
        +
        +		BIO_snprintf(buf,sizeof buf,"platform: %s", PLATFORM);
        +		return(buf);
        +#else
        +		return("platform: information not available");
        +#endif
        +		}
        +	if (t == SSLEAY_DIR)
        +		{
        +#ifdef OPENSSLDIR
        +		return "OPENSSLDIR: \"" OPENSSLDIR "\"";
        +#else
        +		return "OPENSSLDIR: N/A";
        +#endif
        +		}
        +	return("not available");
        +	}
        +
        +unsigned long SSLeay(void)
        +	{
        +	return(SSLEAY_VERSION_NUMBER);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/COPYRIGHT b/vendor/openssl/openssl/crypto/des/COPYRIGHT
        new file mode 100644
        index 000000000..5469e1e46
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/COPYRIGHT
        @@ -0,0 +1,50 @@
        +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        +All rights reserved.
        +
        +This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
        +The implementation was written so as to conform with MIT's libdes.
        +
        +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.
        +
        +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 that the SSL library.  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 software developed by Eric Young (eay@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 license 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 distrubution license
        +[including the GNU Public License.]
        +
        +The reason behind this being stated in this direct manner is past
        +experience in code simply being copied and the attribution removed
        +from it and then being distributed as part of other packages. This
        +implementation was a non-trivial and unpaid effort.
        diff --git a/vendor/openssl/openssl/crypto/des/DES.pm b/vendor/openssl/openssl/crypto/des/DES.pm
        new file mode 100644
        index 000000000..6a175b6ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/DES.pm
        @@ -0,0 +1,19 @@
        +package DES;
        +
        +require Exporter;
        +require DynaLoader;
        +@ISA = qw(Exporter DynaLoader);
        +# Items to export into callers namespace by default
        +# (move infrequently used names to @EXPORT_OK below)
        +@EXPORT = qw(
        +);
        +# Other items we are prepared to export if requested
        +@EXPORT_OK = qw(
        +crypt
        +);
        +
        +# Preloaded methods go here.  Autoload methods go after __END__, and are
        +# processed by the autosplit program.
        +bootstrap DES;
        +1;
        +__END__
        diff --git a/vendor/openssl/openssl/crypto/des/DES.xs b/vendor/openssl/openssl/crypto/des/DES.xs
        new file mode 100644
        index 000000000..b8050b9ed
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/DES.xs
        @@ -0,0 +1,268 @@
        +#include "EXTERN.h"
        +#include "perl.h"
        +#include "XSUB.h"
        +#include "des.h"
        +
        +#define deschar	char
        +static STRLEN len;
        +
        +static int
        +not_here(s)
        +char *s;
        +{
        +    croak("%s not implemented on this architecture", s);
        +    return -1;
        +}
        +
        +MODULE = DES	PACKAGE = DES	PREFIX = des_
        +
        +char *
        +des_crypt(buf,salt)
        +	char *	buf
        +	char *	salt
        +
        +void
        +des_set_odd_parity(key)
        +	des_cblock *	key
        +PPCODE:
        +	{
        +	SV *s;
        +
        +	s=sv_newmortal();
        +	sv_setpvn(s,(char *)key,8);
        +	des_set_odd_parity((des_cblock *)SvPV(s,na));
        +	PUSHs(s);
        +	}
        +
        +int
        +des_is_weak_key(key)
        +	des_cblock *	key
        +
        +des_key_schedule
        +des_set_key(key)
        +	des_cblock *	key
        +CODE:
        +	des_set_key(key,RETVAL);
        +OUTPUT:
        +RETVAL
        +
        +des_cblock
        +des_ecb_encrypt(input,ks,encrypt)
        +	des_cblock *	input
        +	des_key_schedule *	ks
        +	int	encrypt
        +CODE:
        +	des_ecb_encrypt(input,&RETVAL,*ks,encrypt);
        +OUTPUT:
        +RETVAL
        +
        +void
        +des_cbc_encrypt(input,ks,ivec,encrypt)
        +	char *	input
        +	des_key_schedule *	ks
        +	des_cblock *	ivec
        +	int	encrypt
        +PPCODE:
        +	{
        +	SV *s;
        +	STRLEN len,l;
        +	char *c;
        +
        +	l=SvCUR(ST(0));
        +	len=((((unsigned long)l)+7)/8)*8;
        +	s=sv_newmortal();
        +	sv_setpvn(s,"",0);
        +	SvGROW(s,len);
        +	SvCUR_set(s,len);
        +	c=(char *)SvPV(s,na);
        +	des_cbc_encrypt((des_cblock *)input,(des_cblock *)c,
        +		l,*ks,ivec,encrypt);
        +	sv_setpvn(ST(2),(char *)c[len-8],8);
        +	PUSHs(s);
        +	}
        +
        +void
        +des_cbc3_encrypt(input,ks1,ks2,ivec1,ivec2,encrypt)
        +	char *	input
        +	des_key_schedule *	ks1
        +	des_key_schedule *	ks2
        +	des_cblock *	ivec1
        +	des_cblock *	ivec2
        +	int	encrypt
        +PPCODE:
        +	{
        +	SV *s;
        +	STRLEN len,l;
        +
        +	l=SvCUR(ST(0));
        +	len=((((unsigned long)l)+7)/8)*8;
        +	s=sv_newmortal();
        +	sv_setpvn(s,"",0);
        +	SvGROW(s,len);
        +	SvCUR_set(s,len);
        +	des_3cbc_encrypt((des_cblock *)input,(des_cblock *)SvPV(s,na),
        +		l,*ks1,*ks2,ivec1,ivec2,encrypt);
        +	sv_setpvn(ST(3),(char *)ivec1,8);
        +	sv_setpvn(ST(4),(char *)ivec2,8);
        +	PUSHs(s);
        +	}
        +
        +void
        +des_cbc_cksum(input,ks,ivec)
        +	char *	input
        +	des_key_schedule *	ks
        +	des_cblock *	ivec
        +PPCODE:
        +	{
        +	SV *s1,*s2;
        +	STRLEN len,l;
        +	des_cblock c;
        +	unsigned long i1,i2;
        +
        +	s1=sv_newmortal();
        +	s2=sv_newmortal();
        +	l=SvCUR(ST(0));
        +	des_cbc_cksum((des_cblock *)input,(des_cblock *)c,
        +		l,*ks,ivec);
        +	i1=c[4]|(c[5]<<8)|(c[6]<<16)|(c[7]<<24);
        +	i2=c[0]|(c[1]<<8)|(c[2]<<16)|(c[3]<<24);
        +	sv_setiv(s1,i1);
        +	sv_setiv(s2,i2);
        +	sv_setpvn(ST(2),(char *)c,8);
        +	PUSHs(s1);
        +	PUSHs(s2);
        +	}
        +
        +void
        +des_cfb_encrypt(input,numbits,ks,ivec,encrypt)
        +	char *	input
        +	int	numbits
        +	des_key_schedule *	ks
        +	des_cblock *	ivec
        +	int	encrypt
        +PPCODE:
        +	{
        +	SV *s;
        +	STRLEN len;
        +	char *c;
        +
        +	len=SvCUR(ST(0));
        +	s=sv_newmortal();
        +	sv_setpvn(s,"",0);
        +	SvGROW(s,len);
        +	SvCUR_set(s,len);
        +	c=(char *)SvPV(s,na);
        +	des_cfb_encrypt((unsigned char *)input,(unsigned char *)c,
        +		(int)numbits,(long)len,*ks,ivec,encrypt);
        +	sv_setpvn(ST(3),(char *)ivec,8);
        +	PUSHs(s);
        +	}
        +
        +des_cblock *
        +des_ecb3_encrypt(input,ks1,ks2,encrypt)
        +	des_cblock *	input
        +	des_key_schedule *	ks1
        +	des_key_schedule *	ks2
        +	int	encrypt
        +CODE:
        +	{
        +	des_cblock c;
        +
        +	des_ecb3_encrypt((des_cblock *)input,(des_cblock *)&c,
        +		*ks1,*ks2,encrypt);
        +	RETVAL= &c;
        +	}
        +OUTPUT:
        +RETVAL
        +
        +void
        +des_ofb_encrypt(input,numbits,ks,ivec)
        +	unsigned char *	input
        +	int	numbits
        +	des_key_schedule *	ks
        +	des_cblock *	ivec
        +PPCODE:
        +	{
        +	SV *s;
        +	STRLEN len,l;
        +	unsigned char *c;
        +
        +	len=SvCUR(ST(0));
        +	s=sv_newmortal();
        +	sv_setpvn(s,"",0);
        +	SvGROW(s,len);
        +	SvCUR_set(s,len);
        +	c=(unsigned char *)SvPV(s,na);
        +	des_ofb_encrypt((unsigned char *)input,(unsigned char *)c,
        +		numbits,len,*ks,ivec);
        +	sv_setpvn(ST(3),(char *)ivec,8);
        +	PUSHs(s);
        +	}
        +
        +void
        +des_pcbc_encrypt(input,ks,ivec,encrypt)
        +	char *	input
        +	des_key_schedule *	ks
        +	des_cblock *	ivec
        +	int	encrypt
        +PPCODE:
        +	{
        +	SV *s;
        +	STRLEN len,l;
        +	char *c;
        +
        +	l=SvCUR(ST(0));
        +	len=((((unsigned long)l)+7)/8)*8;
        +	s=sv_newmortal();
        +	sv_setpvn(s,"",0);
        +	SvGROW(s,len);
        +	SvCUR_set(s,len);
        +	c=(char *)SvPV(s,na);
        +	des_pcbc_encrypt((des_cblock *)input,(des_cblock *)c,
        +		l,*ks,ivec,encrypt);
        +	sv_setpvn(ST(2),(char *)c[len-8],8);
        +	PUSHs(s);
        +	}
        +
        +des_cblock *
        +des_random_key()
        +CODE:
        +	{
        +	des_cblock c;
        +
        +	des_random_key(c);
        +	RETVAL=&c;
        +	}
        +OUTPUT:
        +RETVAL
        +
        +des_cblock *
        +des_string_to_key(str)
        +char *	str
        +CODE:
        +	{
        +	des_cblock c;
        +
        +	des_string_to_key(str,&c);
        +	RETVAL=&c;
        +	}
        +OUTPUT:
        +RETVAL
        +
        +void
        +des_string_to_2keys(str)
        +char *	str
        +PPCODE:
        +	{
        +	des_cblock c1,c2;
        +	SV *s1,*s2;
        +
        +	des_string_to_2keys(str,&c1,&c2);
        +	EXTEND(sp,2);
        +	s1=sv_newmortal();
        +	sv_setpvn(s1,(char *)c1,8);
        +	s2=sv_newmortal();
        +	sv_setpvn(s2,(char *)c2,8);
        +	PUSHs(s1);
        +	PUSHs(s2);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/FILES0 b/vendor/openssl/openssl/crypto/des/FILES0
        new file mode 100644
        index 000000000..4c7ea2de7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/FILES0
        @@ -0,0 +1,96 @@
        +/* General stuff */
        +COPYRIGHT	- Copyright info.
        +MODES.DES	- A description of the features of the different modes of DES.
        +FILES		- This file.
        +INSTALL		- How to make things compile.
        +Imakefile	- For use with kerberos.
        +README		- What this package is.
        +VERSION		- Which version this is and what was changed.
        +KERBEROS	- Kerberos version 4 notes.
        +Makefile.PL	- An old makefile to build with perl5, not current.
        +Makefile.ssl	- The SSLeay makefile
        +Makefile.uni	- The normal unix makefile.
        +GNUmakefile	- The makefile for use with glibc.
        +makefile.bc	- A Borland C makefile
        +times		- Some outputs from 'speed' on some machines.
        +vms.com		- For use when compiling under VMS
        +
        +/* My SunOS des(1) replacement */
        +des.c		- des(1) source code.
        +des.man		- des(1) manual.
        +
        +/* Testing and timing programs. */
        +destest.c	- Source for libdes.a test program.
        +speed.c		- Source for libdes.a timing program.
        +rpw.c		- Source for libdes.a testing password reading routines.
        +
        +/* libdes.a source code */
        +des_crypt.man	- libdes.a manual page.
        +des.h		- Public libdes.a header file.
        +ecb_enc.c	- des_ecb_encrypt() source, this contains the basic DES code.
        +ecb3_enc.c	- des_ecb3_encrypt() source.
        +cbc_ckm.c	- des_cbc_cksum() source.
        +cbc_enc.c	- des_cbc_encrypt() source.
        +ncbc_enc.c	- des_cbc_encrypt() that is 'normal' in that it copies
        +		  the new iv values back in the passed iv vector.
        +ede_enc.c	- des_ede3_cbc_encrypt() cbc mode des using triple DES.
        +cbc3_enc.c	- des_3cbc_encrypt() source, don't use this function.
        +cfb_enc.c	- des_cfb_encrypt() source.
        +cfb64enc.c	- des_cfb64_encrypt() cfb in 64 bit mode but setup to be
        +		  used as a stream cipher.
        +cfb64ede.c	- des_ede3_cfb64_encrypt() cfb in 64 bit mode but setup to be
        +		  used as a stream cipher and using triple DES.
        +ofb_enc.c	- des_cfb_encrypt() source.
        +ofb64_enc.c	- des_ofb_encrypt() ofb in 64 bit mode but setup to be
        +		  used as a stream cipher.
        +ofb64ede.c	- des_ede3_ofb64_encrypt() ofb in 64 bit mode but setup to be
        +		  used as a stream cipher and using triple DES.
        +enc_read.c	- des_enc_read() source.
        +enc_writ.c	- des_enc_write() source.
        +pcbc_enc.c	- des_pcbc_encrypt() source.
        +qud_cksm.c	- quad_cksum() source.
        +rand_key.c	- des_random_key() source.
        +read_pwd.c	- Source for des_read_password() plus related functions.
        +set_key.c	- Source for des_set_key().
        +str2key.c	- Covert a string of any length into a key.
        +fcrypt.c	- A small, fast version of crypt(3).
        +des_locl.h	- Internal libdes.a header file.
        +podd.h		- Odd parity tables - used in des_set_key().
        +sk.h		- Lookup tables used in des_set_key().
        +spr.h		- What is left of the S tables - used in ecb_encrypt().
        +des_ver.h	- header file for the external definition of the
        +		  version string.
        +des.doc		- SSLeay documentation for the library.
        +
        +/* The perl scripts - you can ignore these files they are only
        + * included for the curious */
        +des.pl		- des in perl anyone? des_set_key and des_ecb_encrypt
        +		  both done in a perl library.
        +testdes.pl	- Testing program for des.pl
        +doIP		- Perl script used to develop IP xor/shift code.
        +doPC1		- Perl script used to develop PC1 xor/shift code.
        +doPC2		- Generates sk.h.
        +PC1		- Output of doPC1 should be the same as output from PC1.
        +PC2		- used in development of doPC2.
        +shifts.pl	- Perl library used by my perl scripts.
        +
        +/* I started making a perl5 dynamic library for libdes
        + * but did not fully finish, these files are part of that effort. */
        +DES.pm
        +DES.pod
        +DES.xs
        +t
        +typemap
        +
        +/* The following are for use with sun RPC implementaions. */
        +rpc_des.h
        +rpc_enc.c
        +
        +/* The following are contibuted by Mark Murray <mark@grondar.za>.  They
        + * are not normally built into libdes due to machine specific routines
        + * contained in them.  They are for use in the most recent incarnation of
        + * export kerberos v 4 (eBones). */
        +supp.c
        +new_rkey.c
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/des/INSTALL b/vendor/openssl/openssl/crypto/des/INSTALL
        new file mode 100644
        index 000000000..8aebdfe11
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/INSTALL
        @@ -0,0 +1,69 @@
        +Check the CC and CFLAGS lines in the makefile
        +
        +If your C library does not support the times(3) function, change the
        +#define TIMES to
        +#undef TIMES in speed.c
        +If it does, check the HZ value for the times(3) function.
        +If your system does not define CLK_TCK it will be assumed to
        +be 100.0.
        +
        +If possible use gcc v 2.7.?
        +Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
        +In recent times, some system compilers give better performace.
        +
        +type 'make'
        +
        +run './destest' to check things are ok.
        +run './rpw' to check the tty code for reading passwords works.
        +run './speed' to see how fast those optimisations make the library run :-)
        +run './des_opts' to determin the best compile time options.
        +
        +The output from des_opts should be put in the makefile options and des_enc.c
        +should be rebuilt.  For 64 bit computers, do not use the DES_PTR option.
        +For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
        +and then you can use the 'DES_PTR' option.
        +
        +The file options.txt has the options listed for best speed on quite a
        +few systems.  Look and the options (UNROLL, PTR, RISC2 etc) and then
        +turn on the relevant option in the Makefile.
        +
        +There are some special Makefile targets that make life easier.
        +make cc		- standard cc build
        +make gcc	- standard gcc build
        +make x86-elf	- x86 assembler (elf), linux-elf.
        +make x86-out	- x86 assembler (a.out), FreeBSD
        +make x86-solaris- x86 assembler
        +make x86-bsdi	- x86 assembler (a.out with primative assembler).
        +
        +If at all possible use the assembler (for Windows NT/95, use
        +asm/win32.obj to link with).  The x86 assembler is very very fast.
        +
        +A make install will by default install
        +libdes.a      in /usr/local/lib/libdes.a
        +des           in /usr/local/bin/des
        +des_crypt.man in /usr/local/man/man3/des_crypt.3
        +des.man       in /usr/local/man/man1/des.1
        +des.h         in /usr/include/des.h
        +
        +des(1) should be compatible with sunOS's but I have been unable to
        +test it.
        +
        +These routines should compile on MSDOS, most 32bit and 64bit version
        +of Unix (BSD and SYSV) and VMS, without modification.
        +The only problems should be #include files that are in the wrong places.
        +
        +These routines can be compiled under MSDOS.
        +I have successfully encrypted files using des(1) under MSDOS and then
        +decrypted the files on a SparcStation.
        +I have been able to compile and test the routines with
        +Microsoft C v 5.1 and Turbo C v 2.0.
        +The code in this library is in no way optimised for the 16bit
        +operation of MSDOS.
        +
        +When building for glibc, ignore all of the above and just unpack into
        +glibc-1.??/des and then gmake as per normal.
        +
        +As a final note on performace.  Certain CPUs like sparcs and Alpha often give
        +a %10 speed difference depending on the link order.  It is rather anoying
        +when one program reports 'x' DES encrypts a second and another reports
        +'x*0.9' the speed.
        diff --git a/vendor/openssl/openssl/crypto/des/Imakefile b/vendor/openssl/openssl/crypto/des/Imakefile
        new file mode 100644
        index 000000000..1b9b5629e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/Imakefile
        @@ -0,0 +1,35 @@
        +# This Imakefile has not been tested for a while but it should still
        +# work when placed in the correct directory in the kerberos v 4 distribution
        +
        +SRCS=   cbc_cksm.c cbc_enc.c ecb_enc.c pcbc_enc.c \
        +        qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \
        +        enc_read.c enc_writ.c fcrypt.c cfb_enc.c \
        +	ecb3_enc.c ofb_enc.c ofb64enc.c
        +
        +OBJS=   cbc_cksm.o cbc_enc.o ecb_enc.o pcbc_enc.o \
        +	qud_cksm.o rand_key.o read_pwd.o set_key.o str2key.o \
        +	enc_read.o enc_writ.o fcrypt.o cfb_enc.o \
        +	ecb3_enc.o ofb_enc.o ofb64enc.o
        +
        +GENERAL=COPYRIGHT FILES INSTALL Imakefile README VERSION makefile times \
        +	vms.com KERBEROS
        +DES=    des.c des.man
        +TESTING=destest.c speed.c rpw.c
        +LIBDES= des_crypt.man des.h des_locl.h podd.h sk.h spr.h
        +
        +PERL=   des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl
        +
        +CODE=    $(GENERAL) $(DES) $(TESTING) $(SRCS) $(LIBDES) $(PERL)
        +
        +SRCDIR=$(SRCTOP)/lib/des
        +
        +DBG= -O
        +INCLUDE= -I$(SRCDIR)
        +CC= cc
        +
        +library_obj_rule()
        +
        +install_library_target(des,$(OBJS),$(SRCS),)
        +
        +test(destest,libdes.a,)
        +test(rpw,libdes.a,)
        diff --git a/vendor/openssl/openssl/crypto/des/KERBEROS b/vendor/openssl/openssl/crypto/des/KERBEROS
        new file mode 100644
        index 000000000..f401b1001
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/KERBEROS
        @@ -0,0 +1,41 @@
        + [ This is an old file, I don't know if it is true anymore
        +   but I will leave the file here - eay 21/11/95 ]
        +
        +To use this library with Bones (kerberos without DES):
        +1) Get my modified Bones - eBones.  It can be found on
        +   gondwana.ecr.mu.oz.au (128.250.1.63) /pub/athena/eBones-p9.tar.Z
        +   and
        +   nic.funet.fi (128.214.6.100) /pub/unix/security/Kerberos/eBones-p9.tar.Z
        +
        +2) Unpack this library in src/lib/des, makeing sure it is version
        +   3.00 or greater (libdes.tar.93-10-07.Z).  This versions differences
        +   from the version in comp.sources.misc volume 29 patchlevel2.
        +   The primarily difference is that it should compile under kerberos :-).
        +   It can be found at.
        +   ftp.psy.uq.oz.au (130.102.32.1) /pub/DES/libdes.tar.93-10-07.Z
        +
        +Now do a normal kerberos build and things should work.
        +
        +One problem I found when I was build on my local sun.
        +---
        +For sunOS 4.1.1 apply the following patch to src/util/ss/make_commands.c
        +
        +*** make_commands.c.orig	Fri Jul  3 04:18:35 1987
        +--- make_commands.c	Wed May 20 08:47:42 1992
        +***************
        +*** 98,104 ****
        +       if (!rename(o_file, z_file)) {
        +  	  if (!vfork()) {
        +  	       chdir("/tmp");
        +! 	       execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", "-n",
        +  		     z_file+5, 0);
        +  	       perror("/bin/ld");
        +  	       _exit(1);
        +--- 98,104 ----
        +       if (!rename(o_file, z_file)) {
        +  	  if (!vfork()) {
        +  	       chdir("/tmp");
        +! 	       execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r",
        +  		     z_file+5, 0);
        +  	       perror("/bin/ld");
        +  	       _exit(1);
        diff --git a/vendor/openssl/openssl/crypto/des/Makefile b/vendor/openssl/openssl/crypto/des/Makefile
        new file mode 100644
        index 000000000..a6e100132
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/Makefile
        @@ -0,0 +1,279 @@
        +#
        +# OpenSSL/crypto/des/Makefile
        +#
        +
        +DIR=	des
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=-I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +RANLIB=		ranlib
        +DES_ENC=	des_enc.o fcrypt_b.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=destest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	cbc_cksm.c cbc_enc.c  cfb64enc.c cfb_enc.c  \
        +	ecb3_enc.c ecb_enc.c  enc_read.c enc_writ.c \
        +	fcrypt.c ofb64enc.c ofb_enc.c  pcbc_enc.c \
        +	qud_cksm.c rand_key.c rpc_enc.c  set_key.c  \
        +	des_enc.c fcrypt_b.c \
        +	xcbc_enc.c \
        +	str2key.c  cfb64ede.c ofb64ede.c ede_cbcm_enc.c des_old.c des_old2.c \
        +	read2pwd.c
        +
        +LIBOBJ= set_key.o  ecb_enc.o  cbc_enc.o \
        +	ecb3_enc.o cfb64enc.o cfb64ede.o cfb_enc.o  ofb64ede.o \
        +	enc_read.o enc_writ.o ofb64enc.o \
        +	ofb_enc.o  str2key.o  pcbc_enc.o qud_cksm.o rand_key.o \
        +	${DES_ENC} \
        +	fcrypt.o xcbc_enc.o rpc_enc.o  cbc_cksm.o \
        +	ede_cbcm_enc.o des_old.o des_old2.o read2pwd.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= des.h des_old.h
        +HEADER=	des_locl.h rpc_des.h spr.h des_ver.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +des: des.o cbc3_enc.o lib
        +	$(CC) $(CFLAGS) -o des des.o cbc3_enc.o $(LIB)
        +
        +des_enc-sparc.S:	asm/des_enc.m4
        +	m4 -B 8192 asm/des_enc.m4 > des_enc-sparc.S
        +
        +des-586.s:	asm/des-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
        +	$(PERL) asm/des-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
        +crypt586.s:	asm/crypt586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
        +	$(PERL) asm/crypt586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +# We need to use force because 'install' matches 'INSTALL' on case
        +# insensitive systems
        +FRC.install:
        +install: FRC.install
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +cbc_cksm.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +cbc_cksm.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +cbc_cksm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +cbc_cksm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cbc_cksm.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +cbc_cksm.o: cbc_cksm.c des_locl.h
        +cbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +cbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +cbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +cbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +cbc_enc.o: cbc_enc.c des_locl.h ncbc_enc.c
        +cfb64ede.o: ../../e_os.h ../../include/openssl/des.h
        +cfb64ede.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +cfb64ede.o: ../../include/openssl/opensslconf.h
        +cfb64ede.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +cfb64ede.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cfb64ede.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +cfb64ede.o: cfb64ede.c des_locl.h
        +cfb64enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +cfb64enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +cfb64enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +cfb64enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +cfb64enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +cfb64enc.o: cfb64enc.c des_locl.h
        +cfb_enc.o: ../../e_os.h ../../include/openssl/des.h
        +cfb_enc.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +cfb_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/ossl_typ.h
        +cfb_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cfb_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +cfb_enc.o: ../../include/openssl/ui_compat.h cfb_enc.c des_locl.h
        +des_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +des_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +des_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +des_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +des_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +des_enc.o: des_enc.c des_locl.h ncbc_enc.c spr.h
        +des_old.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +des_old.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +des_old.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +des_old.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +des_old.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +des_old.o: ../../include/openssl/ui_compat.h des_old.c
        +des_old2.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +des_old2.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +des_old2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +des_old2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +des_old2.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +des_old2.o: ../../include/openssl/ui_compat.h des_old2.c
        +ecb3_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +ecb3_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +ecb3_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ecb3_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ecb3_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +ecb3_enc.o: des_locl.h ecb3_enc.c
        +ecb_enc.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +ecb_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +ecb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +ecb_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecb_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecb_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +ecb_enc.o: ../../include/openssl/ui_compat.h des_locl.h des_ver.h ecb_enc.c
        +ede_cbcm_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +ede_cbcm_enc.o: ../../include/openssl/e_os2.h
        +ede_cbcm_enc.o: ../../include/openssl/opensslconf.h
        +ede_cbcm_enc.o: ../../include/openssl/ossl_typ.h
        +ede_cbcm_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ede_cbcm_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +ede_cbcm_enc.o: ../../include/openssl/ui_compat.h des_locl.h ede_cbcm_enc.c
        +enc_read.o: ../../e_os.h ../../include/openssl/bio.h
        +enc_read.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +enc_read.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +enc_read.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +enc_read.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +enc_read.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +enc_read.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +enc_read.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +enc_read.o: ../../include/openssl/ui_compat.h ../cryptlib.h des_locl.h
        +enc_read.o: enc_read.c
        +enc_writ.o: ../../e_os.h ../../include/openssl/bio.h
        +enc_writ.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +enc_writ.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +enc_writ.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +enc_writ.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +enc_writ.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +enc_writ.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +enc_writ.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +enc_writ.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +enc_writ.o: ../cryptlib.h des_locl.h enc_writ.c
        +fcrypt.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +fcrypt.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +fcrypt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +fcrypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +fcrypt.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +fcrypt.o: des_locl.h fcrypt.c
        +fcrypt_b.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +fcrypt_b.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +fcrypt_b.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +fcrypt_b.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +fcrypt_b.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +fcrypt_b.o: des_locl.h fcrypt_b.c
        +ofb64ede.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +ofb64ede.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +ofb64ede.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ofb64ede.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ofb64ede.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +ofb64ede.o: des_locl.h ofb64ede.c
        +ofb64enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +ofb64enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +ofb64enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ofb64enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ofb64enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +ofb64enc.o: des_locl.h ofb64enc.c
        +ofb_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +ofb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +ofb_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ofb_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ofb_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +ofb_enc.o: des_locl.h ofb_enc.c
        +pcbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +pcbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +pcbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +pcbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pcbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +pcbc_enc.o: des_locl.h pcbc_enc.c
        +qud_cksm.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +qud_cksm.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +qud_cksm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +qud_cksm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +qud_cksm.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +qud_cksm.o: des_locl.h qud_cksm.c
        +rand_key.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +rand_key.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +rand_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +rand_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rand_key.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +rand_key.o: ../../include/openssl/ui_compat.h rand_key.c
        +read2pwd.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
        +read2pwd.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +read2pwd.o: ../../include/openssl/opensslconf.h
        +read2pwd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +read2pwd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +read2pwd.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +read2pwd.o: ../../include/openssl/ui_compat.h read2pwd.c
        +rpc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +rpc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +rpc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +rpc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rpc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +rpc_enc.o: des_locl.h des_ver.h rpc_des.h rpc_enc.c
        +set_key.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
        +set_key.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +set_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +set_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +set_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +set_key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +set_key.o: des_locl.h set_key.c
        +str2key.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
        +str2key.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +str2key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +str2key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +str2key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +str2key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +str2key.o: des_locl.h str2key.c
        +xcbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +xcbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +xcbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +xcbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +xcbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
        +xcbc_enc.o: des_locl.h xcbc_enc.c
        diff --git a/vendor/openssl/openssl/crypto/des/README b/vendor/openssl/openssl/crypto/des/README
        new file mode 100644
        index 000000000..621a5ab46
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/README
        @@ -0,0 +1,54 @@
        +
        +		libdes, Version 4.01 10-Jan-97
        +
        +		Copyright (c) 1997, Eric Young
        +			  All rights reserved.
        +
        +    This program is free software; you can redistribute it and/or modify
        +    it under the terms specified in COPYRIGHT.
        +    
        +--
        +The primary ftp site for this library is
        +ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
        +libdes is now also shipped with SSLeay.  Primary ftp site of
        +ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
        +
        +The best way to build this library is to build it as part of SSLeay.
        +
        +This kit builds a DES encryption library and a DES encryption program.
        +It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
        +triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
        +implementation of crypt(3).
        +It contains support routines to read keys from a terminal,
        +generate a random key, generate a key from an arbitrary length string,
        +read/write encrypted data from/to a file descriptor.
        +
        +The implementation was written so as to conform with the manual entry
        +for the des_crypt(3) library routines from MIT's project Athena.
        +
        +destest should be run after compilation to test the des routines.
        +rpw should be run after compilation to test the read password routines.
        +The des program is a replacement for the sun des command.  I believe it
        +conforms to the sun version.
        +
        +The Imakefile is setup for use in the kerberos distribution.
        +
        +These routines are best compiled with gcc or any other good
        +optimising compiler.
        +Just turn you optimiser up to the highest settings and run destest
        +after the build to make sure everything works.
        +
        +I believe these routines are close to the fastest and most portable DES
        +routines that use small lookup tables (4.5k) that are publicly available.
        +The fcrypt routine is faster than ufc's fcrypt (when compiling with
        +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
        +(on a sun3/260 168 vs 336).  It is a function of CPU on chip cache size.
        +[ 10-Jan-97 and a function of an incorrect speed testing program in
        +  ufc which gave much better test figures that reality ].
        +
        +It is worth noting that on sparc and Alpha CPUs, performance of the DES
        +library can vary by upto %10 due to the positioning of files after application
        +linkage.
        +
        +Eric Young (eay@cryptsoft.com)
        +
        diff --git a/vendor/openssl/openssl/crypto/des/VERSION b/vendor/openssl/openssl/crypto/des/VERSION
        new file mode 100644
        index 000000000..c7d01542b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/VERSION
        @@ -0,0 +1,412 @@
        +	Fixed the weak key values which were wrong :-(
        +	Defining SIGACTION causes sigaction() to be used instead of signal().
        +	SIGUSR1/SIGUSR2 are no longer mapped in the read tty stuff because it
        +	can cause problems.  This should hopefully not affect normal
        +	applications.
        +
        +Version 4.04
        +	Fixed a few tests in destest.  Also added x86 assember for
        +	des_ncbc_encrypt() which is the standard cbc mode function.
        +	This makes a very very large performace difference.
        +	Ariel Glenn ariel@columbia.edu reports that the terminal
        +	'turn echo off' can return (errno == EINVAL) under solaris
        +	when redirection is used.  So I now catch that as well as ENOTTY.
        +
        +
        +Version 4.03
        +	Left a static out of enc_write.c, which caused to buffer to be
        +	continiously malloc()ed.  Does anyone use these functions?  I keep
        +	on feeling like removing them since I only had these in there
        +	for a version of kerberised login.  Anyway, this was pointed out
        +	by Theo de Raadt <deraadt@cvs.openbsd.org>
        +	The 'n' bit ofb code was wrong, it was not shifting the shift
        +	register. It worked correctly for n == 64.  Thanks to
        +	Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
        +
        +Version 4.02
        +	I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
        +	when checking for weak keys which is wrong :-(, pointed out by
        +	Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
        +
        +Version 4.01
        +	Even faster inner loop in the DES assembler for x86 and a modification
        +	for IP/FP which is faster on x86.  Both of these changes are
        +	from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>.  His
        +	changes make the assembler run %40 faster on a pentium.  This is just
        +	a case of getting the instruction sequence 'just right'.
        +	All credit to 'Svend' :-)
        +	Quite a few special x86 'make' targets.
        +	A libdes-l (lite) distribution.
        +
        +Version 4.00
        +	After a bit of a pause, I'll up the major version number since this
        +	is mostly a performace release.  I've added x86 assembler and
        +	added more options for performance.  A %28 speedup for gcc 
        +	on a pentium and the assembler is a %50 speedup.
        +	MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
        +	Run des_opts to work out which options should be used.
        +	DES_RISC1/DES_RISC2 use alternative inner loops which use
        +	more registers but should give speedups on any CPU that does
        +	dual issue (pentium).  DES_UNROLL unrolls the inner loop,
        +	which costs in code size.
        +
        +Version 3.26
        +	I've finally removed one of the shifts in D_ENCRYPT.  This
        +	meant I've changed the des_SPtrans table (spr.h), the set_key()
        +	function and some things in des_enc.c.  This has definitly
        +	made things faster :-).  I've known about this one for some
        +	time but I've been too lazy to follow it up :-).
        +	Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
        +	instead of L^=((..)|(..)|(..)..  This should save a register at
        +	least.
        +	Assember for x86.  The file to replace is des_enc.c, which is replaced
        +	by one of the assembler files found in asm.  Look at des/asm/readme
        +	for more info.
        +
        +	/* Modification to fcrypt so it can be compiled to support
        +	HPUX 10.x's long password format, define -DLONGCRYPT to use this.
        +	Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
        +
        +	SIGWINCH case put in des_read_passwd() so the function does not
        +	'exit' if this function is recieved.
        +
        +Version 3.25 17/07/96
        +	Modified read_pwd.c so that stdin can be read if not a tty.
        +	Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
        +	des_init_random_number_generator() shortened due to VMS linker
        +	limits.
        +	Added RSA's DESX cbc mode.  It is a form of cbc encryption, with 2
        +	8 byte quantites xored before and after encryption.
        +	des_xcbc_encryption() - the name is funny to preserve the des_
        +	prefix on all functions.
        +
        +Version 3.24 20/04/96
        +	The DES_PTR macro option checked and used by SSLeay configuration
        +
        +Version 3.23 11/04/96
        +	Added DES_LONG.  If defined to 'unsigned int' on the DEC Alpha,
        +	it gives a %20 speedup :-)
        +	Fixed the problem with des.pl under perl5.  The patches were
        +	sent by Ed Kubaitis (ejk@uiuc.edu).
        +	if fcrypt.c, changed values to handle illegal salt values the way
        +	normal crypt() implementations do.  Some programs apparently use
        +	them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
        +
        +Version 3.22 29/11/95
        +	Bug in des(1), an error with the uuencoding stuff when the
        +	'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
        +	for the patch.
        +
        +Version 3.21 22/11/95
        +	After some emailing back and forth with 
        +	Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
        +	and in a future version I will probably put in some of the
        +	optimisation he suggested for use with the DES_USE_PTR option.
        +	Extra routines from Mark Murray <mark@grondar.za> for use in
        +	freeBSD.  They mostly involve random number generation for use
        +	with kerberos.  They involve evil machine specific system calls
        +	etc so I would normally suggest pushing this stuff into the
        +	application and/or using RAND_seed()/RAND_bytes() if you are
        +	using this DES library as part of SSLeay.
        +	Redone the read_pw() function so that it is cleaner and
        +	supports termios, thanks to Sameer Parekh <sameer@c2.org>
        +	for the initial patches for this.
        +	Renamed 3ecb_encrypt() to ecb3_encrypt().  This has been
        +	 done just to make things more consistent.
        +	I have also now added triple DES versions of cfb and ofb.
        +
        +Version 3.20
        +	Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
        +	my des_random_seed() function was only copying 4 bytes of the
        +	passed seed into the init structure.  It is now fixed to copy 8.
        +	My own suggestion is to used something like MD5 :-)
        +
        +Version 3.19 
        +	While looking at my code one day, I though, why do I keep on
        +	calling des_encrypt(in,out,ks,enc) when every function that
        +	calls it has in and out the same.  So I dropped the 'out'
        +	parameter, people should not be using this function.
        +
        +Version 3.18 30/08/95
        +	Fixed a few bit with the distribution and the filenames.
        +	3.17 had been munged via a move to DOS and back again.
        +	NO CODE CHANGES
        +
        +Version 3.17 14/07/95
        +	Fixed ede3 cbc which I had broken in 3.16.  I have also
        +	removed some unneeded variables in 7-8 of the routines.
        +
        +Version 3.16 26/06/95
        +	Added des_encrypt2() which does not use IP/FP, used by triple
        +	des routines.  Tweaked things a bit elsewhere. %13 speedup on
        +	sparc and %6 on a R4400 for ede3 cbc mode.
        +
        +Version 3.15 06/06/95
        +	Added des_ncbc_encrypt(), it is des_cbc mode except that it is
        +	'normal' and copies the new iv value back over the top of the
        +	passed parameter.
        +	CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
        +	the iv.  THIS WILL BREAK EXISTING CODE, but since this function
        +	only new, I feel I can change it, not so with des_cbc_encrypt :-(.
        +	I need to update the documentation.
        +
        +Version 3.14 31/05/95
        +	New release upon the world, as part of my SSL implementation.
        +	New copyright and usage stuff.  Basically free for all to use
        +	as long as you say it came from me :-)
        +
        +Version 3.13 31/05/95
        +	A fix in speed.c, if HZ is not defined, I set it to 100.0
        +	which is reasonable for most unixes except SunOS 4.x.
        +	I now have a #ifdef sun but timing for SunOS 4.x looked very
        +	good :-(.  At my last job where I used SunOS 4.x, it was
        +	defined to be 60.0 (look at the old INSTALL documentation), at
        +	the last release had it changed to 100.0 since I now work with
        +	Solaris2 and SVR4 boxes.
        +	Thanks to  Rory Chisholm <rchishol@math.ethz.ch> for pointing this
        +	one out.
        +
        +Version 3.12 08/05/95
        +	As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
        +	my D_ENCRYPT macro in crypt() had an un-necessary variable.
        +	It has been removed.
        +
        +Version 3.11 03/05/95
        +	Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
        +	and one iv.  It is a standard and I needed it for my SSL code.
        +	It makes more sense to use this for triple DES than
        +	3cbc_encrypt().  I have also added (or should I say tested :-)
        +	cfb64_encrypt() which is cfb64 but it will encrypt a partial
        +	number of bytes - 3 bytes in 3 bytes out.  Again this is for
        +	my SSL library, as a form of encryption to use with SSL
        +	telnet.
        +
        +Version 3.10 22/03/95
        +	Fixed a bug in 3cbc_encrypt() :-(.  When making repeated calls
        +	to cbc3_encrypt, the 2 iv values that were being returned to
        +	be used in the next call were reversed :-(.
        +	Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
        +	this error.
        +
        +Version 3.09 01/02/95
        +	Fixed des_random_key to far more random, it was rather feeble
        +	with regards to picking the initial seed.  The problem was
        +	pointed out by Olaf Kirch <okir@monad.swb.de>.
        +
        +Version 3.08 14/12/94
        +	Added Makefile.PL so libdes can be built into perl5.
        +	Changed des_locl.h so RAND is always defined.
        +
        +Version 3.07 05/12/94
        +	Added GNUmake and stuff so the library can be build with
        +	glibc.
        +
        +Version 3.06 30/08/94
        +	Added rpc_enc.c which contains _des_crypt.  This is for use in
        +	secure_rpc v 4.0
        +	Finally fixed the cfb_enc problems.
        +	Fixed a few parameter parsing bugs in des (-3 and -b), thanks
        +	to Rob McMillan <R.McMillan@its.gu.edu.au>
        +
        +Version 3.05 21/04/94
        +	for unsigned long l; gcc does not produce ((l>>34) == 0)
        +	This causes bugs in cfb_enc.
        +	Thanks to Hadmut Danisch <danisch@ira.uka.de>
        +
        +Version 3.04 20/04/94
        +	Added a version number to des.c and libdes.a
        +
        +Version 3.03 12/01/94
        +	Fixed a bug in non zero iv in 3cbc_enc.
        +
        +Version 3.02 29/10/93
        +	I now work in a place where there are 6+ architectures and 14+
        +	OS versions :-).
        +	Fixed TERMIO definition so the most sys V boxes will work :-)
        +
        +Release upon comp.sources.misc
        +Version 3.01 08/10/93
        +	Added des_3cbc_encrypt()
        +
        +Version 3.00 07/10/93
        +	Fixed up documentation.
        +	quad_cksum definitely compatible with MIT's now.
        +
        +Version 2.30 24/08/93
        +	Triple DES now defaults to triple cbc but can do triple ecb
        +	 with the -b flag.
        +	Fixed some MSDOS uuen/uudecoding problems, thanks to
        +	Added prototypes.
        +	
        +Version 2.22 29/06/93
        +	Fixed a bug in des_is_weak_key() which stopped it working :-(
        +	thanks to engineering@MorningStar.Com.
        +
        +Version 2.21 03/06/93
        +	des(1) with no arguments gives quite a bit of help.
        +	Added -c (generate ckecksum) flag to des(1).
        +	Added -3 (triple DES) flag to des(1).
        +	Added cfb and ofb routines to the library.
        +
        +Version 2.20 11/03/93
        +	Added -u (uuencode) flag to des(1).
        +	I have been playing with byte order in quad_cksum to make it
        +	 compatible with MIT's version.  All I can say is avid this
        +	 function if possible since MIT's output is endian dependent.
        +
        +Version 2.12 14/10/92
        +	Added MSDOS specific macro in ecb_encrypt which gives a %70
        +	 speed up when the code is compiled with turbo C.
        +
        +Version 2.11 12/10/92
        +	Speedup in set_key (recoding of PC-1)
        +	 I now do it in 47 simple operations, down from 60.
        +	 Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
        +	 for motivating me to look for a faster system :-)
        +	 The speedup is probably less that 1% but it is still 13
        +	 instructions less :-).
        +
        +Version 2.10 06/10/92
        +	The code now works on the 64bit ETA10 and CRAY without modifications or
        +	 #defines.  I believe the code should work on any machine that
        +	 defines long, int or short to be 8 bytes long.
        +	Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
        +	 for helping me fix the code to run on 64bit machines (he had
        +	 access to an ETA10).
        +	Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
        +	 for testing the routines on a CRAY.
        +	read_password.c has been renamed to read_passwd.c
        +	string_to_key.c has been renamed to string2key.c
        +
        +Version 2.00 14/09/92
        +	Made mods so that the library should work on 64bit CPU's.
        +	Removed all my uchar and ulong defs.  To many different
        +	 versions of unix define them in their header files in too many
        +	 different combinations :-)
        +	IRIX - Sillicon Graphics mods (mostly in read_password.c).
        +	 Thanks to Andrew Daviel (advax@erich.triumf.ca)
        +
        +Version 1.99 26/08/92
        +	Fixed a bug or 2 in enc_read.c
        +	Fixed a bug in enc_write.c
        +	Fixed a pseudo bug in fcrypt.c (very obscure).
        +
        +Version 1.98 31/07/92
        +	Support for the ETA10.  This is a strange machine that defines
        +	longs and ints as 8 bytes and shorts as 4 bytes.
        +	Since I do evil things with long * that assume that they are 4
        +	bytes.  Look in the Makefile for the option to compile for
        +	this machine.  quad_cksum appears to have problems but I
        +	will don't have the time to fix it right now, and this is not
        +	a function that uses DES and so will not effect the main uses
        +	of the library.
        +
        +Version 1.97 20/05/92 eay
        +	Fixed the Imakefile and made some changes to des.h to fix some
        +	problems when building this package with Kerberos v 4.
        +
        +Version 1.96 18/05/92 eay
        +	Fixed a small bug in string_to_key() where problems could
        +	occur if des_check_key was set to true and the string
        +	generated a weak key.
        +
        +Patch2 posted to comp.sources.misc
        +Version 1.95 13/05/92 eay
        +	Added an alternative version of the D_ENCRYPT macro in
        +	ecb_encrypt and fcrypt.  Depending on the compiler, one version or the
        +	other will be faster.  This was inspired by 
        +	Dana How <how@isl.stanford.edu>, and her pointers about doing the
        +	*(ulong *)((uchar *)ptr+(value&0xfc))
        +	vs
        +	ptr[value&0x3f]
        +	to stop the C compiler doing a <<2 to convert the long array index.
        +
        +Version 1.94 05/05/92 eay
        +	Fixed an incompatibility between my string_to_key and the MIT
        +	 version.  When the key is longer than 8 chars, I was wrapping
        +	 with a different method.  To use the old version, define
        +	 OLD_STR_TO_KEY in the makefile.  Thanks to
        +	 viktor@newsu.shearson.com (Viktor Dukhovni).
        +
        +Version 1.93 28/04/92 eay
        +	Fixed the VMS mods so that echo is now turned off in
        +	 read_password.  Thanks again to brennan@coco.cchs.su.oz.AU.
        +	MSDOS support added.  The routines can be compiled with
        +	 Turbo C (v2.0) and MSC (v5.1).  Make sure MSDOS is defined.
        +
        +Patch1 posted to comp.sources.misc
        +Version 1.92 13/04/92 eay
        +	Changed D_ENCRYPT so that the rotation of R occurs outside of
        +	 the loop.  This required rotating all the longs in sp.h (now
        +	 called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
        +	speed.c has been changed so it will work without SIGALRM.  If
        +	 times(3) is not present it will try to use ftime() instead.
        +
        +Version 1.91 08/04/92 eay
        +	Added -E/-D options to des(1) so it can use string_to_key.
        +	Added SVR4 mods suggested by witr@rwwa.COM
        +	Added VMS mods suggested by brennan@coco.cchs.su.oz.AU.  If
        +	anyone knows how to turn of tty echo in VMS please tell me or
        +	implement it yourself :-).
        +	Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
        +	does not like IN/OUT being used.
        +
        +Libdes posted to comp.sources.misc
        +Version 1.9 24/03/92 eay
        +	Now contains a fast small crypt replacement.
        +	Added des(1) command.
        +	Added des_rw_mode so people can use cbc encryption with
        +	enc_read and enc_write.
        +
        +Version 1.8 15/10/91 eay
        +	Bug in cbc_cksum.
        +	Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
        +	one out.
        +
        +Version 1.7 24/09/91 eay
        +	Fixed set_key :-)
        +	set_key is 4 times faster and takes less space.
        +	There are a few minor changes that could be made.
        +
        +Version 1.6 19/09/1991 eay
        +	Finally go IP and FP finished.
        +	Now I need to fix set_key.
        +	This version is quite a bit faster that 1.51
        +
        +Version 1.52 15/06/1991 eay
        +	20% speedup in ecb_encrypt by changing the E bit selection
        +	to use 2 32bit words.  This also required modification of the
        +	sp table.  There is still a way to speedup the IP and IP-1
        +	(hints from outer@sq.com) still working on this one :-(.
        +
        +Version 1.51 07/06/1991 eay
        +	Faster des_encrypt by loop unrolling
        +	Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
        +
        +Version 1.50 28/05/1991 eay
        +	Optimised the code a bit more for the sparc.  I have improved the
        +	speed of the inner des_encrypt by speeding up the initial and
        +	final permutations.
        +
        +Version 1.40 23/10/1990 eay
        +	Fixed des_random_key, it did not produce a random key :-(
        +
        +Version 1.30  2/10/1990 eay
        +	Have made des_quad_cksum the same as MIT's, the full package
        +	should be compatible with MIT's
        +	Have tested on a DECstation 3100
        +	Still need to fix des_set_key (make it faster).
        +	Does des_cbc_encrypts at 70.5k/sec on a 3100.
        +
        +Version 1.20 18/09/1990 eay
        +	Fixed byte order dependencies.
        +	Fixed (I hope) all the word alignment problems.
        +	Speedup in des_ecb_encrypt.
        +
        +Version 1.10 11/09/1990 eay
        +	Added des_enc_read and des_enc_write.
        +	Still need to fix des_quad_cksum.
        +	Still need to document des_enc_read and des_enc_write.
        +
        +Version 1.00 27/08/1990 eay
        +
        diff --git a/vendor/openssl/openssl/crypto/des/asm/crypt586.pl b/vendor/openssl/openssl/crypto/des/asm/crypt586.pl
        new file mode 100644
        index 000000000..e36f7d44b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/asm/crypt586.pl
        @@ -0,0 +1,209 @@
        +#!/usr/local/bin/perl
        +#
        +# The inner loop instruction sequence and the IP/FP modifications are from
        +# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
        +# I've added the stuff needed for crypt() but I've not worried about making
        +# things perfect.
        +#
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"crypt586.pl");
        +
        +$L="edi";
        +$R="esi";
        +
        +&external_label("DES_SPtrans");
        +&fcrypt_body("fcrypt_body");
        +&asm_finish();
        +
        +sub fcrypt_body
        +	{
        +	local($name,$do_ip)=@_;
        +
        +	&function_begin($name);
        +
        +	&comment("");
        +	&comment("Load the 2 words");
        +	$trans="ebp";
        +
        +	&xor(	$L,	$L);
        +	&xor(	$R,	$R);
        +
        +	# PIC-ification:-)
        +	&picmeup("edx","DES_SPtrans");
        +	#if ($cpp)	{ &picmeup("edx","DES_SPtrans");   }
        +	#else		{ &lea("edx",&DWP("DES_SPtrans")); }
        +	&push("edx");	# becomes &swtmp(1)
        +	#
        +	&mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT
        +
        +	&push(&DWC(25)); # add a variable
        +
        +	&set_label("start");
        +	for ($i=0; $i<16; $i+=2)
        +		{
        +		&comment("");
        +		&comment("Round $i");
        +		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
        +
        +		&comment("");
        +		&comment("Round ".sprintf("%d",$i+1));
        +		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
        +		}
        +	 &mov("ebx",	&swtmp(0));
        +	&mov("eax",	$L);
        +	 &dec("ebx");
        +	&mov($L,	$R);
        +	 &mov($R,	"eax");
        +	&mov(&swtmp(0),	"ebx");
        +	 &jnz(&label("start"));
        +
        +	&comment("");
        +	&comment("FP");
        +	&mov("edx",&wparam(0));
        +
        +	&FP_new($R,$L,"eax",3);
        +	&mov(&DWP(0,"edx","",0),"eax");
        +	&mov(&DWP(4,"edx","",0),$L);
        +
        +	&add("esp",8);	# remove variables
        +
        +	&function_end($name);
        +	}
        +
        +sub D_ENCRYPT
        +	{
        +	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
        +
        +	&mov(	$u,		&wparam(2));			# 2
        +	&mov(	$t,		$R);
        +	&shr(	$t,		16);				# 1
        +	&mov(	$tmp2,		&wparam(3));			# 2
        +	&xor(	$t,		$R);				# 1
        +
        +	&and(	$u,		$t);				# 2
        +	&and(	$t,		$tmp2);				# 2
        +
        +	&mov(	$tmp1,		$u);
        +	&shl(	$tmp1,		16); 				# 1
        +	&mov(	$tmp2,		$t);
        +	&shl(	$tmp2,		16); 				# 1
        +	&xor(	$u,		$tmp1);				# 2
        +	&xor(	$t,		$tmp2);				# 2
        +	&mov(	$tmp1,		&DWP(&n2a($S*4),$trans,"",0));	# 2
        +	&xor(	$u,		$tmp1);
        +	&mov(	$tmp2,		&DWP(&n2a(($S+1)*4),$trans,"",0));	# 2
        +	&xor(	$u,		$R);
        +	&xor(	$t,		$R);
        +	&xor(	$t,		$tmp2);
        +
        +	&and(	$u,		"0xfcfcfcfc"	);		# 2
        +	&xor(	$tmp1,		$tmp1);				# 1
        +	&and(	$t,		"0xcfcfcfcf"	);		# 2
        +	&xor(	$tmp2,		$tmp2);	
        +	&movb(	&LB($tmp1),	&LB($u)	);
        +	&movb(	&LB($tmp2),	&HB($u)	);
        +	&rotr(	$t,		4		);
        +	&mov(	$trans,		&swtmp(1));
        +	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
        +	&movb(	&LB($tmp1),	&LB($t)	);
        +	&xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
        +	&movb(	&LB($tmp2),	&HB($t)	);
        +	&shr(	$u,		16);
        +	&xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
        +	&movb(	&LB($tmp1),	&HB($u)	);
        +	&shr(	$t,		16);
        +	&xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
        +	&movb(	&LB($tmp2),	&HB($t)	);
        +	&and(	$u,		"0xff"	);
        +	&and(	$t,		"0xff"	);
        +	&mov(	$tmp1,		&DWP("0x600",$trans,$tmp1,0));
        +	&xor(	$L,		$tmp1);
        +	&mov(	$tmp1,		&DWP("0x700",$trans,$tmp2,0));
        +	&xor(	$L,		$tmp1);
        +	&mov(	$tmp1,		&DWP("0x400",$trans,$u,0));
        +	&xor(	$L,		$tmp1);
        +	&mov(	$tmp1,		&DWP("0x500",$trans,$t,0));
        +	&xor(	$L,		$tmp1);
        +	&mov(	$trans,		&wparam(1));
        +	}
        +
        +sub n2a
        +	{
        +	sprintf("%d",$_[0]);
        +	}
        +
        +# now has a side affect of rotating $a by $shift
        +sub R_PERM_OP
        +	{
        +	local($a,$b,$tt,$shift,$mask,$last)=@_;
        +
        +	&rotl(	$a,		$shift		) if ($shift != 0);
        +	&mov(	$tt,		$a		);
        +	&xor(	$a,		$b		);
        +	&and(	$a,		$mask		);
        +	if ($notlast eq $b)
        +		{
        +		&xor(	$b,		$a		);
        +		&xor(	$tt,		$a		);
        +		}
        +	else
        +		{
        +		&xor(	$tt,		$a		);
        +		&xor(	$b,		$a		);
        +		}
        +	&comment("");
        +	}
        +
        +sub IP_new
        +	{
        +	local($l,$r,$tt,$lr)=@_;
        +
        +	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
        +	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
        +	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
        +	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
        +	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
        +	
        +	if ($lr != 3)
        +		{
        +		if (($lr-3) < 0)
        +			{ &rotr($tt,	3-$lr); }
        +		else	{ &rotl($tt,	$lr-3); }
        +		}
        +	if ($lr != 2)
        +		{
        +		if (($lr-2) < 0)
        +			{ &rotr($r,	2-$lr); }
        +		else	{ &rotl($r,	$lr-2); }
        +		}
        +	}
        +
        +sub FP_new
        +	{
        +	local($l,$r,$tt,$lr)=@_;
        +
        +	if ($lr != 2)
        +		{
        +		if (($lr-2) < 0)
        +			{ &rotl($r,	2-$lr); }
        +		else	{ &rotr($r,	$lr-2); }
        +		}
        +	if ($lr != 3)
        +		{
        +		if (($lr-3) < 0)
        +			{ &rotl($l,	3-$lr); }
        +		else	{ &rotr($l,	$lr-3); }
        +		}
        +
        +	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
        +	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
        +	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
        +	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
        +	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
        +	&rotr($tt	, 4);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/asm/des-586.pl b/vendor/openssl/openssl/crypto/des/asm/des-586.pl
        new file mode 100644
        index 000000000..5b5f39ceb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/asm/des-586.pl
        @@ -0,0 +1,453 @@
        +#!/usr/local/bin/perl
        +#
        +# The inner loop instruction sequence and the IP/FP modifications are from
        +# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
        +#
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +require "cbc.pl";
        +require "desboth.pl";
        +
        +# base code is in microsft
        +# op dest, source
        +# format.
        +#
        +
        +&asm_init($ARGV[0],"des-586.pl");
        +
        +$L="edi";
        +$R="esi";
        +$trans="ebp";
        +$small_footprint=1 if (grep(/\-DOPENSSL_SMALL_FOOTPRINT/,@ARGV));
        +# one can discuss setting this variable to 1 unconditionally, as
        +# the folded loop is only 3% slower than unrolled, but >7 times smaller
        +
        +&public_label("DES_SPtrans");
        +
        +&DES_encrypt_internal();
        +&DES_decrypt_internal();
        +&DES_encrypt("DES_encrypt1",1);
        +&DES_encrypt("DES_encrypt2",0);
        +&DES_encrypt3("DES_encrypt3",1);
        +&DES_encrypt3("DES_decrypt3",0);
        +&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1);
        +&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5);
        +&DES_SPtrans();
        +
        +&asm_finish();
        +
        +sub DES_encrypt_internal()
        +	{
        +	&function_begin_B("_x86_DES_encrypt");
        +
        +	if ($small_footprint)
        +	    {
        +	    &lea("edx",&DWP(128,"ecx"));
        +	    &push("edx");
        +	    &push("ecx");
        +	    &set_label("eloop");
        +		&D_ENCRYPT(0,$L,$R,0,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		&comment("");
        +		&D_ENCRYPT(1,$R,$L,2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		&comment("");
        +		&add("ecx",16);
        +		&cmp("ecx",&swtmp(1));
        +		&mov(&swtmp(0),"ecx");
        +		&jb(&label("eloop"));
        +	    &add("esp",8);
        +	    }
        +	else
        +	    {
        +	    &push("ecx");
        +	    for ($i=0; $i<16; $i+=2)
        +		{
        +		&comment("Round $i");
        +		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		&comment("Round ".sprintf("%d",$i+1));
        +		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		}
        +	    &add("esp",4);
        +	}
        +	&ret();
        +
        +	&function_end_B("_x86_DES_encrypt");
        +	}
        +	
        +sub DES_decrypt_internal()
        +	{
        +	&function_begin_B("_x86_DES_decrypt");
        +
        +	if ($small_footprint)
        +	    {
        +	    &push("ecx");
        +	    &lea("ecx",&DWP(128,"ecx"));
        +	    &push("ecx");
        +	    &set_label("dloop");
        +		&D_ENCRYPT(0,$L,$R,-2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		&comment("");
        +		&D_ENCRYPT(1,$R,$L,-4,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		&comment("");
        +		&sub("ecx",16);
        +		&cmp("ecx",&swtmp(1));
        +		&mov(&swtmp(0),"ecx");
        +		&ja(&label("dloop"));
        +	    &add("esp",8);
        +	    }
        +	else
        +	    {
        +	    &push("ecx");
        +	    for ($i=15; $i>0; $i-=2)
        +		{
        +		&comment("Round $i");
        +		&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		&comment("Round ".sprintf("%d",$i-1));
        +		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
        +		}
        +	    &add("esp",4);
        +	    }
        +	&ret();
        +
        +	&function_end_B("_x86_DES_decrypt");
        +	}
        +	
        +sub DES_encrypt
        +	{
        +	local($name,$do_ip)=@_;
        +
        +	&function_begin_B($name);
        +
        +	&push("esi");
        +	&push("edi");
        +
        +	&comment("");
        +	&comment("Load the 2 words");
        +
        +	if ($do_ip)
        +		{
        +		&mov($R,&wparam(0));
        +		 &xor(	"ecx",		"ecx"		);
        +
        +		&push("ebx");
        +		&push("ebp");
        +
        +		&mov("eax",&DWP(0,$R,"",0));
        +		 &mov("ebx",&wparam(2));	# get encrypt flag
        +		&mov($L,&DWP(4,$R,"",0));
        +		&comment("");
        +		&comment("IP");
        +		&IP_new("eax",$L,$R,3);
        +		}
        +	else
        +		{
        +		&mov("eax",&wparam(0));
        +		 &xor(	"ecx",		"ecx"		);
        +
        +		&push("ebx");
        +		&push("ebp");
        +
        +		&mov($R,&DWP(0,"eax","",0));
        +		 &mov("ebx",&wparam(2));	# get encrypt flag
        +		&rotl($R,3);
        +		&mov($L,&DWP(4,"eax","",0));
        +		&rotl($L,3);
        +		}
        +
        +	# PIC-ification:-)
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop($trans);
        +	&lea	($trans,&DWP(&label("DES_SPtrans")."-".&label("pic_point"),$trans));
        +
        +	&mov(	"ecx",	&wparam(1)	);
        +
        +	&cmp("ebx","0");
        +	&je(&label("decrypt"));
        +	&call("_x86_DES_encrypt");
        +	&jmp(&label("done"));
        +	&set_label("decrypt");
        +	&call("_x86_DES_decrypt");
        +	&set_label("done");
        +
        +	if ($do_ip)
        +		{
        +		&comment("");
        +		&comment("FP");
        +		&mov("edx",&wparam(0));
        +		&FP_new($L,$R,"eax",3);
        +
        +		&mov(&DWP(0,"edx","",0),"eax");
        +		&mov(&DWP(4,"edx","",0),$R);
        +		}
        +	else
        +		{
        +		&comment("");
        +		&comment("Fixup");
        +		&rotr($L,3);		# r
        +		 &mov("eax",&wparam(0));
        +		&rotr($R,3);		# l
        +		 &mov(&DWP(0,"eax","",0),$L);
        +		 &mov(&DWP(4,"eax","",0),$R);
        +		}
        +
        +	&pop("ebp");
        +	&pop("ebx");
        +	&pop("edi");
        +	&pop("esi");
        +	&ret();
        +
        +	&function_end_B($name);
        +	}
        +
        +sub D_ENCRYPT
        +	{
        +	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t,$wp1)=@_;
        +
        +	 &mov(	$u,		&DWP(&n2a($S*4),$tmp2,"",0));
        +	&xor(	$tmp1,		$tmp1);
        +	 &mov(	$t,		&DWP(&n2a(($S+1)*4),$tmp2,"",0));
        +	&xor(	$u,		$R);
        +	&xor(	$tmp2,		$tmp2);
        +	 &xor(	$t,		$R);
        +	&and(	$u,		"0xfcfcfcfc"	);
        +	 &and(	$t,		"0xcfcfcfcf"	);
        +	&movb(	&LB($tmp1),	&LB($u)	);
        +	 &movb(	&LB($tmp2),	&HB($u)	);
        +	&rotr(	$t,		4		);
        +	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
        +	 &movb(	&LB($tmp1),	&LB($t)	);
        +	 &xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
        +	 &movb(	&LB($tmp2),	&HB($t)	);
        +	&shr(	$u,		16);
        +	 &xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
        +	 &movb(	&LB($tmp1),	&HB($u)	);
        +	&shr(	$t,		16);
        +	 &xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
        +	&movb(	&LB($tmp2),	&HB($t)	);
        +	 &and(	$u,		"0xff"	);
        +	&and(	$t,		"0xff"	);
        +	 &xor(	$L,		&DWP("0x600",$trans,$tmp1,0));
        +	 &xor(	$L,		&DWP("0x700",$trans,$tmp2,0));
        +	&mov(	$tmp2,		$wp1	);
        +	 &xor(	$L,		&DWP("0x400",$trans,$u,0));
        +	 &xor(	$L,		&DWP("0x500",$trans,$t,0));
        +	}
        +
        +sub n2a
        +	{
        +	sprintf("%d",$_[0]);
        +	}
        +
        +# now has a side affect of rotating $a by $shift
        +sub R_PERM_OP
        +	{
        +	local($a,$b,$tt,$shift,$mask,$last)=@_;
        +
        +	&rotl(	$a,		$shift		) if ($shift != 0);
        +	&mov(	$tt,		$a		);
        +	&xor(	$a,		$b		);
        +	&and(	$a,		$mask		);
        +	# This can never succeed, and besides it is difficult to see what the
        +	# idea was - Ben 13 Feb 99
        +	if (!$last eq $b)
        +		{
        +		&xor(	$b,		$a		);
        +		&xor(	$tt,		$a		);
        +		}
        +	else
        +		{
        +		&xor(	$tt,		$a		);
        +		&xor(	$b,		$a		);
        +		}
        +	&comment("");
        +	}
        +
        +sub IP_new
        +	{
        +	local($l,$r,$tt,$lr)=@_;
        +
        +	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
        +	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
        +	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
        +	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
        +	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
        +	
        +	if ($lr != 3)
        +		{
        +		if (($lr-3) < 0)
        +			{ &rotr($tt,	3-$lr); }
        +		else	{ &rotl($tt,	$lr-3); }
        +		}
        +	if ($lr != 2)
        +		{
        +		if (($lr-2) < 0)
        +			{ &rotr($r,	2-$lr); }
        +		else	{ &rotl($r,	$lr-2); }
        +		}
        +	}
        +
        +sub FP_new
        +	{
        +	local($l,$r,$tt,$lr)=@_;
        +
        +	if ($lr != 2)
        +		{
        +		if (($lr-2) < 0)
        +			{ &rotl($r,	2-$lr); }
        +		else	{ &rotr($r,	$lr-2); }
        +		}
        +	if ($lr != 3)
        +		{
        +		if (($lr-3) < 0)
        +			{ &rotl($l,	3-$lr); }
        +		else	{ &rotr($l,	$lr-3); }
        +		}
        +
        +	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
        +	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
        +	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
        +	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
        +	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
        +	&rotr($tt	, 4);
        +	}
        +
        +sub DES_SPtrans
        +	{
        +	&set_label("DES_SPtrans",64);
        +	&data_word(0x02080800, 0x00080000, 0x02000002, 0x02080802);
        +	&data_word(0x02000000, 0x00080802, 0x00080002, 0x02000002);
        +	&data_word(0x00080802, 0x02080800, 0x02080000, 0x00000802);
        +	&data_word(0x02000802, 0x02000000, 0x00000000, 0x00080002);
        +	&data_word(0x00080000, 0x00000002, 0x02000800, 0x00080800);
        +	&data_word(0x02080802, 0x02080000, 0x00000802, 0x02000800);
        +	&data_word(0x00000002, 0x00000800, 0x00080800, 0x02080002);
        +	&data_word(0x00000800, 0x02000802, 0x02080002, 0x00000000);
        +	&data_word(0x00000000, 0x02080802, 0x02000800, 0x00080002);
        +	&data_word(0x02080800, 0x00080000, 0x00000802, 0x02000800);
        +	&data_word(0x02080002, 0x00000800, 0x00080800, 0x02000002);
        +	&data_word(0x00080802, 0x00000002, 0x02000002, 0x02080000);
        +	&data_word(0x02080802, 0x00080800, 0x02080000, 0x02000802);
        +	&data_word(0x02000000, 0x00000802, 0x00080002, 0x00000000);
        +	&data_word(0x00080000, 0x02000000, 0x02000802, 0x02080800);
        +	&data_word(0x00000002, 0x02080002, 0x00000800, 0x00080802);
        +	# nibble 1
        +	&data_word(0x40108010, 0x00000000, 0x00108000, 0x40100000);
        +	&data_word(0x40000010, 0x00008010, 0x40008000, 0x00108000);
        +	&data_word(0x00008000, 0x40100010, 0x00000010, 0x40008000);
        +	&data_word(0x00100010, 0x40108000, 0x40100000, 0x00000010);
        +	&data_word(0x00100000, 0x40008010, 0x40100010, 0x00008000);
        +	&data_word(0x00108010, 0x40000000, 0x00000000, 0x00100010);
        +	&data_word(0x40008010, 0x00108010, 0x40108000, 0x40000010);
        +	&data_word(0x40000000, 0x00100000, 0x00008010, 0x40108010);
        +	&data_word(0x00100010, 0x40108000, 0x40008000, 0x00108010);
        +	&data_word(0x40108010, 0x00100010, 0x40000010, 0x00000000);
        +	&data_word(0x40000000, 0x00008010, 0x00100000, 0x40100010);
        +	&data_word(0x00008000, 0x40000000, 0x00108010, 0x40008010);
        +	&data_word(0x40108000, 0x00008000, 0x00000000, 0x40000010);
        +	&data_word(0x00000010, 0x40108010, 0x00108000, 0x40100000);
        +	&data_word(0x40100010, 0x00100000, 0x00008010, 0x40008000);
        +	&data_word(0x40008010, 0x00000010, 0x40100000, 0x00108000);
        +	# nibble 2
        +	&data_word(0x04000001, 0x04040100, 0x00000100, 0x04000101);
        +	&data_word(0x00040001, 0x04000000, 0x04000101, 0x00040100);
        +	&data_word(0x04000100, 0x00040000, 0x04040000, 0x00000001);
        +	&data_word(0x04040101, 0x00000101, 0x00000001, 0x04040001);
        +	&data_word(0x00000000, 0x00040001, 0x04040100, 0x00000100);
        +	&data_word(0x00000101, 0x04040101, 0x00040000, 0x04000001);
        +	&data_word(0x04040001, 0x04000100, 0x00040101, 0x04040000);
        +	&data_word(0x00040100, 0x00000000, 0x04000000, 0x00040101);
        +	&data_word(0x04040100, 0x00000100, 0x00000001, 0x00040000);
        +	&data_word(0x00000101, 0x00040001, 0x04040000, 0x04000101);
        +	&data_word(0x00000000, 0x04040100, 0x00040100, 0x04040001);
        +	&data_word(0x00040001, 0x04000000, 0x04040101, 0x00000001);
        +	&data_word(0x00040101, 0x04000001, 0x04000000, 0x04040101);
        +	&data_word(0x00040000, 0x04000100, 0x04000101, 0x00040100);
        +	&data_word(0x04000100, 0x00000000, 0x04040001, 0x00000101);
        +	&data_word(0x04000001, 0x00040101, 0x00000100, 0x04040000);
        +	# nibble 3
        +	&data_word(0x00401008, 0x10001000, 0x00000008, 0x10401008);
        +	&data_word(0x00000000, 0x10400000, 0x10001008, 0x00400008);
        +	&data_word(0x10401000, 0x10000008, 0x10000000, 0x00001008);
        +	&data_word(0x10000008, 0x00401008, 0x00400000, 0x10000000);
        +	&data_word(0x10400008, 0x00401000, 0x00001000, 0x00000008);
        +	&data_word(0x00401000, 0x10001008, 0x10400000, 0x00001000);
        +	&data_word(0x00001008, 0x00000000, 0x00400008, 0x10401000);
        +	&data_word(0x10001000, 0x10400008, 0x10401008, 0x00400000);
        +	&data_word(0x10400008, 0x00001008, 0x00400000, 0x10000008);
        +	&data_word(0x00401000, 0x10001000, 0x00000008, 0x10400000);
        +	&data_word(0x10001008, 0x00000000, 0x00001000, 0x00400008);
        +	&data_word(0x00000000, 0x10400008, 0x10401000, 0x00001000);
        +	&data_word(0x10000000, 0x10401008, 0x00401008, 0x00400000);
        +	&data_word(0x10401008, 0x00000008, 0x10001000, 0x00401008);
        +	&data_word(0x00400008, 0x00401000, 0x10400000, 0x10001008);
        +	&data_word(0x00001008, 0x10000000, 0x10000008, 0x10401000);
        +	# nibble 4
        +	&data_word(0x08000000, 0x00010000, 0x00000400, 0x08010420);
        +	&data_word(0x08010020, 0x08000400, 0x00010420, 0x08010000);
        +	&data_word(0x00010000, 0x00000020, 0x08000020, 0x00010400);
        +	&data_word(0x08000420, 0x08010020, 0x08010400, 0x00000000);
        +	&data_word(0x00010400, 0x08000000, 0x00010020, 0x00000420);
        +	&data_word(0x08000400, 0x00010420, 0x00000000, 0x08000020);
        +	&data_word(0x00000020, 0x08000420, 0x08010420, 0x00010020);
        +	&data_word(0x08010000, 0x00000400, 0x00000420, 0x08010400);
        +	&data_word(0x08010400, 0x08000420, 0x00010020, 0x08010000);
        +	&data_word(0x00010000, 0x00000020, 0x08000020, 0x08000400);
        +	&data_word(0x08000000, 0x00010400, 0x08010420, 0x00000000);
        +	&data_word(0x00010420, 0x08000000, 0x00000400, 0x00010020);
        +	&data_word(0x08000420, 0x00000400, 0x00000000, 0x08010420);
        +	&data_word(0x08010020, 0x08010400, 0x00000420, 0x00010000);
        +	&data_word(0x00010400, 0x08010020, 0x08000400, 0x00000420);
        +	&data_word(0x00000020, 0x00010420, 0x08010000, 0x08000020);
        +	# nibble 5
        +	&data_word(0x80000040, 0x00200040, 0x00000000, 0x80202000);
        +	&data_word(0x00200040, 0x00002000, 0x80002040, 0x00200000);
        +	&data_word(0x00002040, 0x80202040, 0x00202000, 0x80000000);
        +	&data_word(0x80002000, 0x80000040, 0x80200000, 0x00202040);
        +	&data_word(0x00200000, 0x80002040, 0x80200040, 0x00000000);
        +	&data_word(0x00002000, 0x00000040, 0x80202000, 0x80200040);
        +	&data_word(0x80202040, 0x80200000, 0x80000000, 0x00002040);
        +	&data_word(0x00000040, 0x00202000, 0x00202040, 0x80002000);
        +	&data_word(0x00002040, 0x80000000, 0x80002000, 0x00202040);
        +	&data_word(0x80202000, 0x00200040, 0x00000000, 0x80002000);
        +	&data_word(0x80000000, 0x00002000, 0x80200040, 0x00200000);
        +	&data_word(0x00200040, 0x80202040, 0x00202000, 0x00000040);
        +	&data_word(0x80202040, 0x00202000, 0x00200000, 0x80002040);
        +	&data_word(0x80000040, 0x80200000, 0x00202040, 0x00000000);
        +	&data_word(0x00002000, 0x80000040, 0x80002040, 0x80202000);
        +	&data_word(0x80200000, 0x00002040, 0x00000040, 0x80200040);
        +	# nibble 6
        +	&data_word(0x00004000, 0x00000200, 0x01000200, 0x01000004);
        +	&data_word(0x01004204, 0x00004004, 0x00004200, 0x00000000);
        +	&data_word(0x01000000, 0x01000204, 0x00000204, 0x01004000);
        +	&data_word(0x00000004, 0x01004200, 0x01004000, 0x00000204);
        +	&data_word(0x01000204, 0x00004000, 0x00004004, 0x01004204);
        +	&data_word(0x00000000, 0x01000200, 0x01000004, 0x00004200);
        +	&data_word(0x01004004, 0x00004204, 0x01004200, 0x00000004);
        +	&data_word(0x00004204, 0x01004004, 0x00000200, 0x01000000);
        +	&data_word(0x00004204, 0x01004000, 0x01004004, 0x00000204);
        +	&data_word(0x00004000, 0x00000200, 0x01000000, 0x01004004);
        +	&data_word(0x01000204, 0x00004204, 0x00004200, 0x00000000);
        +	&data_word(0x00000200, 0x01000004, 0x00000004, 0x01000200);
        +	&data_word(0x00000000, 0x01000204, 0x01000200, 0x00004200);
        +	&data_word(0x00000204, 0x00004000, 0x01004204, 0x01000000);
        +	&data_word(0x01004200, 0x00000004, 0x00004004, 0x01004204);
        +	&data_word(0x01000004, 0x01004200, 0x01004000, 0x00004004);
        +	# nibble 7
        +	&data_word(0x20800080, 0x20820000, 0x00020080, 0x00000000);
        +	&data_word(0x20020000, 0x00800080, 0x20800000, 0x20820080);
        +	&data_word(0x00000080, 0x20000000, 0x00820000, 0x00020080);
        +	&data_word(0x00820080, 0x20020080, 0x20000080, 0x20800000);
        +	&data_word(0x00020000, 0x00820080, 0x00800080, 0x20020000);
        +	&data_word(0x20820080, 0x20000080, 0x00000000, 0x00820000);
        +	&data_word(0x20000000, 0x00800000, 0x20020080, 0x20800080);
        +	&data_word(0x00800000, 0x00020000, 0x20820000, 0x00000080);
        +	&data_word(0x00800000, 0x00020000, 0x20000080, 0x20820080);
        +	&data_word(0x00020080, 0x20000000, 0x00000000, 0x00820000);
        +	&data_word(0x20800080, 0x20020080, 0x20020000, 0x00800080);
        +	&data_word(0x20820000, 0x00000080, 0x00800080, 0x20020000);
        +	&data_word(0x20820080, 0x00800000, 0x20800000, 0x20000080);
        +	&data_word(0x00820000, 0x00020080, 0x20020080, 0x20800000);
        +	&data_word(0x00000080, 0x20820000, 0x00820080, 0x00000000);
        +	&data_word(0x20000000, 0x20800080, 0x00020000, 0x00820080);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/asm/des_enc.m4 b/vendor/openssl/openssl/crypto/des/asm/des_enc.m4
        new file mode 100644
        index 000000000..328059547
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/asm/des_enc.m4
        @@ -0,0 +1,2099 @@
        +!  des_enc.m4
        +!  des_enc.S  (generated from des_enc.m4)
        +!
        +!  UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
        +!
        +!  Version 1.0. 32-bit version.
        +!
        +!  June 8, 2000.
        +!
        +!  Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
        +!		by Andy Polyakov.
        +!
        +!  January 1, 2003.
        +!
        +!  Assembler version: Copyright Svend Olaf Mikkelsen.
        +!
        +!  Original C code: Copyright Eric A. Young.
        +!
        +!  This code can be freely used by LibDES/SSLeay/OpenSSL users.
        +!
        +!  The LibDES/SSLeay/OpenSSL copyright notices must be respected.
        +!
        +!  This version can be redistributed.
        +!
        +!  To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
        +!
        +!  Global registers 1 to 5 are used. This is the same as done by the
        +!  cc compiler. The UltraSPARC load/store little endian feature is used.
        +!
        +!  Instruction grouping often refers to one CPU cycle.
        +!
        +!  Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
        +!
        +!  Assemble through cc:  cc -c -xarch=v8plusa -o des_enc.o des_enc.S
        +!
        +!  Performance improvement according to './apps/openssl speed des'
        +!
        +!	32-bit build:
        +!		23%  faster than cc-5.2 -xarch=v8plus -xO5
        +!		115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
        +!	64-bit build:
        +!		50%  faster than cc-5.2 -xarch=v9 -xO5
        +!		100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
        +!
        +
        +.ident "des_enc.m4 2.1"
        +.file  "des_enc-sparc.S"
        +
        +#if defined(__SUNPRO_C) && defined(__sparcv9)
        +# define ABI64  /* They've said -xarch=v9 at command line */
        +#elif defined(__GNUC__) && defined(__arch64__)
        +# define ABI64  /* They've said -m64 at command line */
        +#endif
        +
        +#ifdef ABI64
        +  .register	%g2,#scratch
        +  .register	%g3,#scratch
        +# define	FRAME	-192
        +# define	BIAS	2047
        +# define	LDPTR	ldx
        +# define	STPTR	stx
        +# define	ARG0	128
        +# define	ARGSZ	8
        +# ifndef OPENSSL_SYSNAME_ULTRASPARC
        +# define OPENSSL_SYSNAME_ULTRASPARC
        +# endif
        +#else
        +# define	FRAME	-96
        +# define	BIAS	0
        +# define	LDPTR	ld
        +# define	STPTR	st
        +# define	ARG0	68
        +# define	ARGSZ	4
        +#endif
        +
        +#define LOOPS 7
        +
        +#define global0 %g0
        +#define global1 %g1
        +#define global2 %g2
        +#define global3 %g3
        +#define global4 %g4
        +#define global5 %g5
        +
        +#define local0 %l0
        +#define local1 %l1
        +#define local2 %l2
        +#define local3 %l3
        +#define local4 %l4
        +#define local5 %l5
        +#define local7 %l6
        +#define local6 %l7
        +
        +#define in0 %i0
        +#define in1 %i1
        +#define in2 %i2
        +#define in3 %i3
        +#define in4 %i4
        +#define in5 %i5
        +#define in6 %i6
        +#define in7 %i7
        +
        +#define out0 %o0
        +#define out1 %o1
        +#define out2 %o2
        +#define out3 %o3
        +#define out4 %o4
        +#define out5 %o5
        +#define out6 %o6
        +#define out7 %o7
        +
        +#define stub stb
        +
        +changequote({,})
        +
        +
        +! Macro definitions:
        +
        +
        +! {ip_macro}
        +!
        +! The logic used in initial and final permutations is the same as in
        +! the C code. The permutations are done with a clever shift, xor, and
        +! technique.
        +!
        +! The macro also loads address sbox 1 to 5 to global 1 to 5, address
        +! sbox 6 to local6, and addres sbox 8 to out3.
        +!
        +! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
        +!
        +! Loads key first round from address in parameter 5 to out0, out1.
        +!
        +! After the the original LibDES initial permutation, the resulting left
        +! is in the variable initially used for right and vice versa. The macro
        +! implements the possibility to keep the halfs in the original registers.
        +!
        +! parameter 1  left
        +! parameter 2  right
        +! parameter 3  result left (modify in first round)
        +! parameter 4  result right (use in first round)
        +! parameter 5  key address
        +! parameter 6  1/2 for include encryption/decryption
        +! parameter 7  1 for move in1 to in3
        +! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
        +! parameter 9  1 for load ks3 and ks2 to in4 and in3
        +
        +define(ip_macro, {
        +
        +! {ip_macro}
        +! $1 $2 $4 $3 $5 $6 $7 $8 $9
        +
        +	ld	[out2+256], local1
        +	srl	$2, 4, local4
        +
        +	xor	local4, $1, local4
        +	ifelse($7,1,{mov in1, in3},{nop})
        +
        +	ld	[out2+260], local2
        +	and	local4, local1, local4
        +	ifelse($8,1,{mov in3, in4},{})
        +	ifelse($8,2,{mov in4, in3},{})
        +
        +	ld	[out2+280], out4          ! loop counter
        +	sll	local4, 4, local1
        +	xor	$1, local4, $1
        +
        +	ld	[out2+264], local3
        +	srl	$1, 16, local4
        +	xor	$2, local1, $2
        +
        +	ifelse($9,1,{LDPTR	KS3, in4},{})
        +	xor	local4, $2, local4
        +	nop	!sethi	%hi(DES_SPtrans), global1 ! sbox addr
        +
        +	ifelse($9,1,{LDPTR	KS2, in3},{})
        +	and	local4, local2, local4
        +	nop	!or	global1, %lo(DES_SPtrans), global1   ! sbox addr
        +
        +	sll	local4, 16, local1
        +	xor	$2, local4, $2
        +
        +	srl	$2, 2, local4
        +	xor	$1, local1, $1
        +
        +	sethi	%hi(16711680), local5
        +	xor	local4, $1, local4
        +
        +	and	local4, local3, local4
        +	or	local5, 255, local5
        +
        +	sll	local4, 2, local2
        +	xor	$1, local4, $1
        +
        +	srl	$1, 8, local4
        +	xor	$2, local2, $2
        +
        +	xor	local4, $2, local4
        +	add	global1, 768, global4
        +
        +	and	local4, local5, local4
        +	add	global1, 1024, global5
        +
        +	ld	[out2+272], local7
        +	sll	local4, 8, local1
        +	xor	$2, local4, $2
        +
        +	srl	$2, 1, local4
        +	xor	$1, local1, $1
        +
        +	ld	[$5], out0                ! key 7531
        +	xor	local4, $1, local4
        +	add	global1, 256, global2
        +
        +	ld	[$5+4], out1              ! key 8642
        +	and	local4, local7, local4
        +	add	global1, 512, global3
        +
        +	sll	local4, 1, local1
        +	xor	$1, local4, $1
        +
        +	sll	$1, 3, local3
        +	xor	$2, local1, $2
        +
        +	sll	$2, 3, local2
        +	add	global1, 1280, local6     ! address sbox 8
        +
        +	srl	$1, 29, local4
        +	add	global1, 1792, out3       ! address sbox 8
        +
        +	srl	$2, 29, local1
        +	or	local4, local3, $4
        +
        +	or	local2, local1, $3
        +
        +	ifelse($6, 1, {
        +
        +		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
        +		or	local2, local1, $3
        +		xor	$4, out0, local1
        +
        +		call .des_enc.1
        +		and	local1, 252, local1
        +
        +	},{})
        +
        +	ifelse($6, 2, {
        +
        +		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
        +		or	local2, local1, $3
        +		xor	$4, out0, local1
        +
        +		call .des_dec.1
        +		and	local1, 252, local1
        +
        +	},{})
        +})
        +
        +
        +! {rounds_macro}
        +!
        +! The logic used in the DES rounds is the same as in the C code,
        +! except that calculations for sbox 1 and sbox 5 begin before
        +! the previous round is finished.
        +!
        +! In each round one half (work) is modified based on key and the
        +! other half (use).
        +!
        +! In this version we do two rounds in a loop repeated 7 times
        +! and two rounds seperately.
        +!
        +! One half has the bits for the sboxes in the following positions:
        +!
        +!	777777xx555555xx333333xx111111xx
        +!
        +!	88xx666666xx444444xx222222xx8888
        +!
        +! The bits for each sbox are xor-ed with the key bits for that box.
        +! The above xx bits are cleared, and the result used for lookup in
        +! the sbox table. Each sbox entry contains the 4 output bits permuted
        +! into 32 bits according to the P permutation.
        +!
        +! In the description of DES, left and right are switched after
        +! each round, except after last round. In this code the original
        +! left and right are kept in the same register in all rounds, meaning
        +! that after the 16 rounds the result for right is in the register
        +! originally used for left.
        +!
        +! parameter 1  first work (left in first round)
        +! parameter 2  first use (right in first round)
        +! parameter 3  enc/dec  1/-1
        +! parameter 4  loop label
        +! parameter 5  key address register
        +! parameter 6  optional address for key next encryption/decryption
        +! parameter 7  not empty for include retl
        +!
        +! also compares in2 to 8
        +
        +define(rounds_macro, {
        +
        +! {rounds_macro}
        +! $1 $2 $3 $4 $5 $6 $7 $8 $9
        +
        +	xor	$2, out0, local1
        +
        +	ld	[out2+284], local5        ! 0x0000FC00
        +	ba	$4
        +	and	local1, 252, local1
        +
        +	.align 32
        +
        +$4:
        +	! local6 is address sbox 6
        +	! out3   is address sbox 8
        +	! out4   is loop counter
        +
        +	ld	[global1+local1], local1
        +	xor	$2, out1, out1            ! 8642
        +	xor	$2, out0, out0            ! 7531
        +	! fmovs	%f0, %f0                  ! fxor used for alignment
        +
        +	srl	out1, 4, local0           ! rotate 4 right
        +	and	out0, local5, local3      ! 3
        +	! fmovs	%f0, %f0
        +
        +	ld	[$5+$3*8], local7         ! key 7531 next round
        +	srl	local3, 8, local3         ! 3
        +	and	local0, 252, local2       ! 2
        +	! fmovs	%f0, %f0
        +
        +	ld	[global3+local3],local3   ! 3
        +	sll	out1, 28, out1            ! rotate
        +	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
        +
        +	ld	[global2+local2], local2  ! 2 
        +	srl	out0, 24, local1          ! 7
        +	or	out1, local0, out1        ! rotate
        +
        +	ldub	[out2+local1], local1     ! 7 (and 0xFC)
        +	srl	out1, 24, local0          ! 8
        +	and	out1, local5, local4      ! 4
        +
        +	ldub	[out2+local0], local0     ! 8 (and 0xFC)
        +	srl	local4, 8, local4         ! 4
        +	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
        +
        +	ld	[global4+local4],local4   ! 4
        +	srl	out1, 16, local2          ! 6
        +	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
        +
        +	ld	[out3+local0],local0      ! 8
        +	and	local2, 252, local2       ! 6
        +	add	global1, 1536, local5     ! address sbox 7
        +
        +	ld	[local6+local2], local2   ! 6
        +	srl	out0, 16, local3          ! 5
        +	xor	$1, local4, $1            ! 4 finished
        +
        +	ld	[local5+local1],local1    ! 7
        +	and	local3, 252, local3       ! 5
        +	xor	$1, local0, $1            ! 8 finished
        +
        +	ld	[global5+local3],local3   ! 5
        +	xor	$1, local2, $1            ! 6 finished
        +	subcc	out4, 1, out4
        +
        +	ld	[$5+$3*8+4], out0         ! key 8642 next round
        +	xor	$1, local7, local2        ! sbox 5 next round
        +	xor	$1, local1, $1            ! 7 finished
        +
        +	srl	local2, 16, local2        ! sbox 5 next round
        +	xor	$1, local3, $1            ! 5 finished
        +
        +	ld	[$5+$3*16+4], out1        ! key 8642 next round again
        +	and	local2, 252, local2       ! sbox5 next round
        +! next round
        +	xor	$1, local7, local7        ! 7531
        +
        +	ld	[global5+local2], local2  ! 5
        +	srl	local7, 24, local3        ! 7
        +	xor	$1, out0, out0            ! 8642
        +
        +	ldub	[out2+local3], local3     ! 7 (and 0xFC)
        +	srl	out0, 4, local0           ! rotate 4 right
        +	and	local7, 252, local1       ! 1
        +
        +	sll	out0, 28, out0            ! rotate
        +	xor	$2, local2, $2            ! 5 finished local2 used
        +
        +	srl	local0, 8, local4         ! 4
        +	and	local0, 252, local2       ! 2
        +	ld	[local5+local3], local3   ! 7
        +
        +	srl	local0, 16, local5        ! 6
        +	or	out0, local0, out0        ! rotate
        +	ld	[global2+local2], local2  ! 2
        +
        +	srl	out0, 24, local0
        +	ld	[$5+$3*16], out0          ! key 7531 next round
        +	and	local4, 252, local4	  ! 4
        +
        +	and	local5, 252, local5       ! 6
        +	ld	[global4+local4], local4  ! 4
        +	xor	$2, local3, $2            ! 7 finished local3 used
        +
        +	and	local0, 252, local0       ! 8
        +	ld	[local6+local5], local5   ! 6
        +	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
        +
        +	srl	local7, 8, local2         ! 3 start
        +	ld	[out3+local0], local0     ! 8
        +	xor	$2, local4, $2            ! 4 finished
        +
        +	and	local2, 252, local2       ! 3
        +	ld	[global1+local1], local1  ! 1
        +	xor	$2, local5, $2            ! 6 finished local5 used
        +
        +	ld	[global3+local2], local2  ! 3
        +	xor	$2, local0, $2            ! 8 finished
        +	add	$5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
        +
        +	ld	[out2+284], local5        ! 0x0000FC00
        +	xor	$2, out0, local4          ! sbox 1 next round
        +	xor	$2, local1, $2            ! 1 finished
        +
        +	xor	$2, local2, $2            ! 3 finished
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bne,pt	%icc, $4
        +#else
        +	bne	$4
        +#endif
        +	and	local4, 252, local1       ! sbox 1 next round
        +
        +! two rounds more:
        +
        +	ld	[global1+local1], local1
        +	xor	$2, out1, out1
        +	xor	$2, out0, out0
        +
        +	srl	out1, 4, local0           ! rotate
        +	and	out0, local5, local3
        +
        +	ld	[$5+$3*8], local7         ! key 7531
        +	srl	local3, 8, local3
        +	and	local0, 252, local2
        +
        +	ld	[global3+local3],local3
        +	sll	out1, 28, out1            ! rotate
        +	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
        +
        +	ld	[global2+local2], local2
        +	srl	out0, 24, local1
        +	or	out1, local0, out1        ! rotate
        +
        +	ldub	[out2+local1], local1
        +	srl	out1, 24, local0
        +	and	out1, local5, local4
        +
        +	ldub	[out2+local0], local0
        +	srl	local4, 8, local4
        +	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
        +
        +	ld	[global4+local4],local4
        +	srl	out1, 16, local2
        +	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
        +
        +	ld	[out3+local0],local0
        +	and	local2, 252, local2
        +	add	global1, 1536, local5     ! address sbox 7
        +
        +	ld	[local6+local2], local2
        +	srl	out0, 16, local3
        +	xor	$1, local4, $1            ! 4 finished
        +
        +	ld	[local5+local1],local1
        +	and	local3, 252, local3
        +	xor	$1, local0, $1
        +
        +	ld	[global5+local3],local3
        +	xor	$1, local2, $1            ! 6 finished
        +	cmp	in2, 8
        +
        +	ifelse($6,{}, {}, {ld	[out2+280], out4})  ! loop counter
        +	xor	$1, local7, local2        ! sbox 5 next round
        +	xor	$1, local1, $1            ! 7 finished
        +
        +	ld	[$5+$3*8+4], out0
        +	srl	local2, 16, local2        ! sbox 5 next round
        +	xor	$1, local3, $1            ! 5 finished
        +
        +	and	local2, 252, local2
        +! next round (two rounds more)
        +	xor	$1, local7, local7        ! 7531
        +
        +	ld	[global5+local2], local2
        +	srl	local7, 24, local3
        +	xor	$1, out0, out0            ! 8642
        +
        +	ldub	[out2+local3], local3
        +	srl	out0, 4, local0           ! rotate
        +	and	local7, 252, local1
        +
        +	sll	out0, 28, out0            ! rotate
        +	xor	$2, local2, $2            ! 5 finished local2 used
        +
        +	srl	local0, 8, local4
        +	and	local0, 252, local2
        +	ld	[local5+local3], local3
        +
        +	srl	local0, 16, local5
        +	or	out0, local0, out0        ! rotate
        +	ld	[global2+local2], local2
        +
        +	srl	out0, 24, local0
        +	ifelse($6,{}, {}, {ld	[$6], out0})   ! key next encryption/decryption
        +	and	local4, 252, local4
        +
        +	and	local5, 252, local5
        +	ld	[global4+local4], local4
        +	xor	$2, local3, $2            ! 7 finished local3 used
        +
        +	and	local0, 252, local0
        +	ld	[local6+local5], local5
        +	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
        +
        +	srl	local7, 8, local2         ! 3 start
        +	ld	[out3+local0], local0
        +	xor	$2, local4, $2
        +
        +	and	local2, 252, local2
        +	ld	[global1+local1], local1
        +	xor	$2, local5, $2            ! 6 finished local5 used
        +
        +	ld	[global3+local2], local2
        +	srl	$1, 3, local3
        +	xor	$2, local0, $2
        +
        +	ifelse($6,{}, {}, {ld	[$6+4], out1}) ! key next encryption/decryption
        +	sll	$1, 29, local4
        +	xor	$2, local1, $2
        +
        +	ifelse($7,{}, {}, {retl})
        +	xor	$2, local2, $2
        +})
        +
        +
        +! {fp_macro}
        +!
        +!  parameter 1   right (original left)
        +!  parameter 2   left (original right)
        +!  parameter 3   1 for optional store to [in0]
        +!  parameter 4   1 for load input/output address to local5/7
        +!
        +!  The final permutation logic switches the halfes, meaning that
        +!  left and right ends up the the registers originally used.
        +
        +define(fp_macro, {
        +
        +! {fp_macro}
        +! $1 $2 $3 $4 $5 $6 $7 $8 $9
        +
        +	! initially undo the rotate 3 left done after initial permutation
        +	! original left is received shifted 3 right and 29 left in local3/4
        +
        +	sll	$2, 29, local1
        +	or	local3, local4, $1
        +
        +	srl	$2, 3, $2
        +	sethi	%hi(0x55555555), local2
        +
        +	or	$2, local1, $2
        +	or	local2, %lo(0x55555555), local2
        +
        +	srl	$2, 1, local3
        +	sethi	%hi(0x00ff00ff), local1
        +	xor	local3, $1, local3
        +	or	local1, %lo(0x00ff00ff), local1
        +	and	local3, local2, local3
        +	sethi	%hi(0x33333333), local4
        +	sll	local3, 1, local2
        +
        +	xor	$1, local3, $1
        +
        +	srl	$1, 8, local3
        +	xor	$2, local2, $2
        +	xor	local3, $2, local3
        +	or	local4, %lo(0x33333333), local4
        +	and	local3, local1, local3
        +	sethi	%hi(0x0000ffff), local1
        +	sll	local3, 8, local2
        +
        +	xor	$2, local3, $2
        +
        +	srl	$2, 2, local3
        +	xor	$1, local2, $1
        +	xor	local3, $1, local3
        +	or	local1, %lo(0x0000ffff), local1
        +	and	local3, local4, local3
        +	sethi	%hi(0x0f0f0f0f), local4
        +	sll	local3, 2, local2
        +
        +	ifelse($4,1, {LDPTR INPUT, local5})
        +	xor	$1, local3, $1
        +
        +	ifelse($4,1, {LDPTR OUTPUT, local7})
        +	srl	$1, 16, local3
        +	xor	$2, local2, $2
        +	xor	local3, $2, local3
        +	or	local4, %lo(0x0f0f0f0f), local4
        +	and	local3, local1, local3
        +	sll	local3, 16, local2
        +
        +	xor	$2, local3, local1
        +
        +	srl	local1, 4, local3
        +	xor	$1, local2, $1
        +	xor	local3, $1, local3
        +	and	local3, local4, local3
        +	sll	local3, 4, local2
        +
        +	xor	$1, local3, $1
        +
        +	! optional store:
        +
        +	ifelse($3,1, {st $1, [in0]})
        +
        +	xor	local1, local2, $2
        +
        +	ifelse($3,1, {st $2, [in0+4]})
        +
        +})
        +
        +
        +! {fp_ip_macro}
        +!
        +! Does initial permutation for next block mixed with
        +! final permutation for current block.
        +!
        +! parameter 1   original left
        +! parameter 2   original right
        +! parameter 3   left ip
        +! parameter 4   right ip
        +! parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
        +!                2: mov in4 to in3
        +!
        +! also adds -8 to length in2 and loads loop counter to out4
        +
        +define(fp_ip_macro, {
        +
        +! {fp_ip_macro}
        +! $1 $2 $3 $4 $5 $6 $7 $8 $9
        +
        +	define({temp1},{out4})
        +	define({temp2},{local3})
        +
        +	define({ip1},{local1})
        +	define({ip2},{local2})
        +	define({ip4},{local4})
        +	define({ip5},{local5})
        +
        +	! $1 in local3, local4
        +
        +	ld	[out2+256], ip1
        +	sll	out5, 29, temp1
        +	or	local3, local4, $1
        +
        +	srl	out5, 3, $2
        +	ifelse($5,2,{mov in4, in3})
        +
        +	ld	[out2+272], ip5
        +	srl	$4, 4, local0
        +	or	$2, temp1, $2
        +
        +	srl	$2, 1, temp1
        +	xor	temp1, $1, temp1
        +
        +	and	temp1, ip5, temp1
        +	xor	local0, $3, local0
        +
        +	sll	temp1, 1, temp2
        +	xor	$1, temp1, $1
        +
        +	and	local0, ip1, local0
        +	add	in2, -8, in2
        +
        +	sll	local0, 4, local7
        +	xor	$3, local0, $3
        +
        +	ld	[out2+268], ip4
        +	srl	$1, 8, temp1
        +	xor	$2, temp2, $2
        +	ld	[out2+260], ip2
        +	srl	$3, 16, local0
        +	xor	$4, local7, $4
        +	xor	temp1, $2, temp1
        +	xor	local0, $4, local0
        +	and	temp1, ip4, temp1
        +	and	local0, ip2, local0
        +	sll	temp1, 8, temp2
        +	xor	$2, temp1, $2
        +	sll	local0, 16, local7
        +	xor	$4, local0, $4
        +
        +	srl	$2, 2, temp1
        +	xor	$1, temp2, $1
        +
        +	ld	[out2+264], temp2         ! ip3
        +	srl	$4, 2, local0
        +	xor	$3, local7, $3
        +	xor	temp1, $1, temp1
        +	xor	local0, $3, local0
        +	and	temp1, temp2, temp1
        +	and	local0, temp2, local0
        +	sll	temp1, 2, temp2
        +	xor	$1, temp1, $1
        +	sll	local0, 2, local7
        +	xor	$3, local0, $3
        +
        +	srl	$1, 16, temp1
        +	xor	$2, temp2, $2
        +	srl	$3, 8, local0
        +	xor	$4, local7, $4
        +	xor	temp1, $2, temp1
        +	xor	local0, $4, local0
        +	and	temp1, ip2, temp1
        +	and	local0, ip4, local0
        +	sll	temp1, 16, temp2
        +	xor	$2, temp1, local4
        +	sll	local0, 8, local7
        +	xor	$4, local0, $4
        +
        +	srl	$4, 1, local0
        +	xor	$3, local7, $3
        +
        +	srl	local4, 4, temp1
        +	xor	local0, $3, local0
        +
        +	xor	$1, temp2, $1
        +	and	local0, ip5, local0
        +
        +	sll	local0, 1, local7
        +	xor	temp1, $1, temp1
        +
        +	xor	$3, local0, $3
        +	xor	$4, local7, $4
        +
        +	sll	$3, 3, local5
        +	and	temp1, ip1, temp1
        +
        +	sll	temp1, 4, temp2
        +	xor	$1, temp1, $1
        +
        +	ifelse($5,1,{LDPTR	KS2, in4})
        +	sll	$4, 3, local2
        +	xor	local4, temp2, $2
        +
        +	! reload since used as temporar:
        +
        +	ld	[out2+280], out4          ! loop counter
        +
        +	srl	$3, 29, local0
        +	ifelse($5,1,{add in4, 120, in4})
        +
        +	ifelse($5,1,{LDPTR	KS1, in3})
        +	srl	$4, 29, local7
        +
        +	or	local0, local5, $4
        +	or	local2, local7, $3
        +
        +})
        +
        +
        +
        +! {load_little_endian}
        +!
        +! parameter 1  address
        +! parameter 2  destination left
        +! parameter 3  destination right
        +! parameter 4  temporar
        +! parameter 5  label
        +
        +define(load_little_endian, {
        +
        +! {load_little_endian}
        +! $1 $2 $3 $4 $5 $6 $7 $8 $9
        +
        +	! first in memory to rightmost in register
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	andcc	$1, 3, global0
        +	bne,pn	%icc, $5
        +	nop
        +
        +	lda	[$1] 0x88, $2
        +	add	$1, 4, $4
        +
        +	ba,pt	%icc, $5a
        +	lda	[$4] 0x88, $3
        +#endif
        +
        +$5:
        +	ldub	[$1+3], $2
        +
        +	ldub	[$1+2], $4
        +	sll	$2, 8, $2
        +	or	$2, $4, $2
        +
        +	ldub	[$1+1], $4
        +	sll	$2, 8, $2
        +	or	$2, $4, $2
        +
        +	ldub	[$1+0], $4
        +	sll	$2, 8, $2
        +	or	$2, $4, $2
        +
        +
        +	ldub	[$1+3+4], $3
        +
        +	ldub	[$1+2+4], $4
        +	sll	$3, 8, $3
        +	or	$3, $4, $3
        +
        +	ldub	[$1+1+4], $4
        +	sll	$3, 8, $3
        +	or	$3, $4, $3
        +
        +	ldub	[$1+0+4], $4
        +	sll	$3, 8, $3
        +	or	$3, $4, $3
        +$5a:
        +
        +})
        +
        +
        +! {load_little_endian_inc}
        +!
        +! parameter 1  address
        +! parameter 2  destination left
        +! parameter 3  destination right
        +! parameter 4  temporar
        +! parameter 4  label
        +!
        +! adds 8 to address
        +
        +define(load_little_endian_inc, {
        +
        +! {load_little_endian_inc}
        +! $1 $2 $3 $4 $5 $6 $7 $8 $9
        +
        +	! first in memory to rightmost in register
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	andcc	$1, 3, global0
        +	bne,pn	%icc, $5
        +	nop
        +
        +	lda	[$1] 0x88, $2
        +	add	$1, 4, $1
        +
        +	lda	[$1] 0x88, $3
        +	ba,pt	%icc, $5a
        +	add	$1, 4, $1
        +#endif
        +
        +$5:
        +	ldub	[$1+3], $2
        +
        +	ldub	[$1+2], $4
        +	sll	$2, 8, $2
        +	or	$2, $4, $2
        +
        +	ldub	[$1+1], $4
        +	sll	$2, 8, $2
        +	or	$2, $4, $2
        +
        +	ldub	[$1+0], $4
        +	sll	$2, 8, $2
        +	or	$2, $4, $2
        +
        +	ldub	[$1+3+4], $3
        +	add	$1, 8, $1
        +
        +	ldub	[$1+2+4-8], $4
        +	sll	$3, 8, $3
        +	or	$3, $4, $3
        +
        +	ldub	[$1+1+4-8], $4
        +	sll	$3, 8, $3
        +	or	$3, $4, $3
        +
        +	ldub	[$1+0+4-8], $4
        +	sll	$3, 8, $3
        +	or	$3, $4, $3
        +$5a:
        +
        +})
        +
        +
        +! {load_n_bytes}
        +!
        +! Loads 1 to 7 bytes little endian
        +! Remaining bytes are zeroed.
        +!
        +! parameter 1  address
        +! parameter 2  length
        +! parameter 3  destination register left
        +! parameter 4  destination register right
        +! parameter 5  temp
        +! parameter 6  temp2
        +! parameter 7  label
        +! parameter 8  return label
        +
        +define(load_n_bytes, {
        +
        +! {load_n_bytes}
        +! $1 $2 $5 $6 $7 $8 $7 $8 $9
        +
        +$7.0:	call	.+8
        +	sll	$2, 2, $6
        +
        +	add	%o7,$7.jmp.table-$7.0,$5
        +
        +	add	$5, $6, $5
        +	mov	0, $4
        +
        +	ld	[$5], $5
        +
        +	jmp	%o7+$5
        +	mov	0, $3
        +
        +$7.7:
        +	ldub	[$1+6], $5
        +	sll	$5, 16, $5
        +	or	$3, $5, $3
        +$7.6:
        +	ldub	[$1+5], $5
        +	sll	$5, 8, $5
        +	or	$3, $5, $3
        +$7.5:
        +	ldub	[$1+4], $5
        +	or	$3, $5, $3
        +$7.4:
        +	ldub	[$1+3], $5
        +	sll	$5, 24, $5
        +	or	$4, $5, $4
        +$7.3:
        +	ldub	[$1+2], $5
        +	sll	$5, 16, $5
        +	or	$4, $5, $4
        +$7.2:
        +	ldub	[$1+1], $5
        +	sll	$5, 8, $5
        +	or	$4, $5, $4
        +$7.1:
        +	ldub	[$1+0], $5
        +	ba	$8
        +	or	$4, $5, $4
        +
        +	.align 4
        +
        +$7.jmp.table:
        +	.word	0
        +	.word	$7.1-$7.0
        +	.word	$7.2-$7.0
        +	.word	$7.3-$7.0
        +	.word	$7.4-$7.0
        +	.word	$7.5-$7.0
        +	.word	$7.6-$7.0
        +	.word	$7.7-$7.0
        +})
        +
        +
        +! {store_little_endian}
        +!
        +! parameter 1  address
        +! parameter 2  source left
        +! parameter 3  source right
        +! parameter 4  temporar
        +
        +define(store_little_endian, {
        +
        +! {store_little_endian}
        +! $1 $2 $3 $4 $5 $6 $7 $8 $9
        +
        +	! rightmost in register to first in memory
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	andcc	$1, 3, global0
        +	bne,pn	%icc, $5
        +	nop
        +
        +	sta	$2, [$1] 0x88
        +	add	$1, 4, $4
        +
        +	ba,pt	%icc, $5a
        +	sta	$3, [$4] 0x88
        +#endif
        +
        +$5:
        +	and	$2, 255, $4
        +	stub	$4, [$1+0]
        +
        +	srl	$2, 8, $4
        +	and	$4, 255, $4
        +	stub	$4, [$1+1]
        +
        +	srl	$2, 16, $4
        +	and	$4, 255, $4
        +	stub	$4, [$1+2]
        +
        +	srl	$2, 24, $4
        +	stub	$4, [$1+3]
        +
        +
        +	and	$3, 255, $4
        +	stub	$4, [$1+0+4]
        +
        +	srl	$3, 8, $4
        +	and	$4, 255, $4
        +	stub	$4, [$1+1+4]
        +
        +	srl	$3, 16, $4
        +	and	$4, 255, $4
        +	stub	$4, [$1+2+4]
        +
        +	srl	$3, 24, $4
        +	stub	$4, [$1+3+4]
        +
        +$5a:
        +
        +})
        +
        +
        +! {store_n_bytes}
        +!
        +! Stores 1 to 7 bytes little endian
        +!
        +! parameter 1  address
        +! parameter 2  length
        +! parameter 3  source register left
        +! parameter 4  source register right
        +! parameter 5  temp
        +! parameter 6  temp2
        +! parameter 7  label
        +! parameter 8  return label
        +
        +define(store_n_bytes, {
        +
        +! {store_n_bytes}
        +! $1 $2 $5 $6 $7 $8 $7 $8 $9
        +
        +$7.0:	call	.+8
        +	sll	$2, 2, $6
        +
        +	add	%o7,$7.jmp.table-$7.0,$5
        +
        +	add	$5, $6, $5
        +
        +	ld	[$5], $5
        +
        +	jmp	%o7+$5
        +	nop
        +
        +$7.7:
        +	srl	$3, 16, $5
        +	and	$5, 0xff, $5
        +	stub	$5, [$1+6]
        +$7.6:
        +	srl	$3, 8, $5
        +	and	$5, 0xff, $5
        +	stub	$5, [$1+5]
        +$7.5:
        +	and	$3, 0xff, $5
        +	stub	$5, [$1+4]
        +$7.4:
        +	srl	$4, 24, $5
        +	stub	$5, [$1+3]
        +$7.3:
        +	srl	$4, 16, $5
        +	and	$5, 0xff, $5
        +	stub	$5, [$1+2]
        +$7.2:
        +	srl	$4, 8, $5
        +	and	$5, 0xff, $5
        +	stub	$5, [$1+1]
        +$7.1:
        +	and	$4, 0xff, $5
        +
        +
        +	ba	$8
        +	stub	$5, [$1]
        +
        +	.align 4
        +
        +$7.jmp.table:
        +
        +	.word	0
        +	.word	$7.1-$7.0
        +	.word	$7.2-$7.0
        +	.word	$7.3-$7.0
        +	.word	$7.4-$7.0
        +	.word	$7.5-$7.0
        +	.word	$7.6-$7.0
        +	.word	$7.7-$7.0
        +})
        +
        +
        +define(testvalue,{1})
        +
        +define(register_init, {
        +
        +! For test purposes:
        +
        +	sethi	%hi(testvalue), local0
        +	or	local0, %lo(testvalue), local0
        +
        +	ifelse($1,{},{}, {mov	local0, $1})
        +	ifelse($2,{},{}, {mov	local0, $2})
        +	ifelse($3,{},{}, {mov	local0, $3})
        +	ifelse($4,{},{}, {mov	local0, $4})
        +	ifelse($5,{},{}, {mov	local0, $5})
        +	ifelse($6,{},{}, {mov	local0, $6})
        +	ifelse($7,{},{}, {mov	local0, $7})
        +	ifelse($8,{},{}, {mov	local0, $8})
        +
        +	mov	local0, local1
        +	mov	local0, local2
        +	mov	local0, local3
        +	mov	local0, local4
        +	mov	local0, local5
        +	mov	local0, local7
        +	mov	local0, local6
        +	mov	local0, out0
        +	mov	local0, out1
        +	mov	local0, out2
        +	mov	local0, out3
        +	mov	local0, out4
        +	mov	local0, out5
        +	mov	local0, global1
        +	mov	local0, global2
        +	mov	local0, global3
        +	mov	local0, global4
        +	mov	local0, global5
        +
        +})
        +
        +.section	".text"
        +
        +	.align 32
        +
        +.des_enc:
        +
        +	! key address in3
        +	! loads key next encryption/decryption first round from [in4]
        +
        +	rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
        +
        +
        +	.align 32
        +
        +.des_dec:
        +
        +	! implemented with out5 as first parameter to avoid
        +	! register exchange in ede modes
        +
        +	! key address in4
        +	! loads key next encryption/decryption first round from [in3]
        +
        +	rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
        +
        +
        +
        +! void DES_encrypt1(data, ks, enc)
        +! *******************************
        +
        +	.align 32
        +	.global DES_encrypt1
        +	.type	 DES_encrypt1,#function
        +
        +DES_encrypt1:
        +
        +	save	%sp, FRAME, %sp
        +
        +	sethi	%hi(.PIC.DES_SPtrans-1f),global1
        +	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
        +1:	call	.+8
        +	add	%o7,global1,global1
        +	sub	global1,.PIC.DES_SPtrans-.des_and,out2
        +
        +	ld	[in0], in5                ! left
        +	cmp	in2, 0                    ! enc
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	be,pn	%icc, .encrypt.dec        ! enc/dec
        +#else
        +	be	.encrypt.dec
        +#endif
        +	ld	[in0+4], out5             ! right
        +
        +	! parameter 6  1/2 for include encryption/decryption
        +	! parameter 7  1 for move in1 to in3
        +	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
        +
        +	ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
        +
        +	rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
        +
        +	fp_macro(in5, out5, 1)            ! 1 for store to [in0]
        +
        +	ret
        +	restore
        +
        +.encrypt.dec:
        +
        +	add	in1, 120, in3             ! use last subkey for first round
        +
        +	! parameter 6  1/2 for include encryption/decryption
        +	! parameter 7  1 for move in1 to in3
        +	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
        +
        +	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
        +
        +	fp_macro(out5, in5, 1)            ! 1 for store to [in0]
        +
        +	ret
        +	restore
        +
        +.DES_encrypt1.end:
        +	.size	 DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
        +
        +
        +! void DES_encrypt2(data, ks, enc)
        +!*********************************
        +
        +	! encrypts/decrypts without initial/final permutation
        +
        +	.align 32
        +	.global DES_encrypt2
        +	.type	 DES_encrypt2,#function
        +
        +DES_encrypt2:
        +
        +	save	%sp, FRAME, %sp
        +
        +	sethi	%hi(.PIC.DES_SPtrans-1f),global1
        +	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
        +1:	call	.+8
        +	add	%o7,global1,global1
        +	sub	global1,.PIC.DES_SPtrans-.des_and,out2
        +
        +	! Set sbox address 1 to 6 and rotate halfs 3 left
        +	! Errors caught by destest? Yes. Still? *NO*
        +
        +	!sethi	%hi(DES_SPtrans), global1 ! address sbox 1
        +
        +	!or	global1, %lo(DES_SPtrans), global1  ! sbox 1
        +
        +	add	global1, 256, global2     ! sbox 2
        +	add	global1, 512, global3     ! sbox 3
        +
        +	ld	[in0], out5               ! right
        +	add	global1, 768, global4     ! sbox 4
        +	add	global1, 1024, global5    ! sbox 5
        +
        +	ld	[in0+4], in5              ! left
        +	add	global1, 1280, local6     ! sbox 6
        +	add	global1, 1792, out3       ! sbox 8
        +
        +	! rotate
        +
        +	sll	in5, 3, local5
        +	mov	in1, in3                  ! key address to in3
        +
        +	sll	out5, 3, local7
        +	srl	in5, 29, in5
        +
        +	srl	out5, 29, out5
        +	add	in5, local5, in5
        +
        +	add	out5, local7, out5
        +	cmp	in2, 0
        +
        +	! we use our own stackframe
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	be,pn	%icc, .encrypt2.dec       ! decryption
        +#else
        +	be	.encrypt2.dec
        +#endif
        +	STPTR	in0, [%sp+BIAS+ARG0+0*ARGSZ]
        +
        +	ld	[in3], out0               ! key 7531 first round
        +	mov	LOOPS, out4               ! loop counter
        +
        +	ld	[in3+4], out1             ! key 8642 first round
        +	sethi	%hi(0x0000FC00), local5
        +
        +	call .des_enc
        +	mov	in3, in4
        +
        +	! rotate
        +	sll	in5, 29, in0
        +	srl	in5, 3, in5
        +	sll	out5, 29, in1
        +	add	in5, in0, in5
        +	srl	out5, 3, out5
        +	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
        +	add	out5, in1, out5
        +	st	in5, [in0]
        +	st	out5, [in0+4]
        +
        +	ret
        +	restore
        +
        +
        +.encrypt2.dec:
        +
        +	add in3, 120, in4
        +
        +	ld	[in4], out0               ! key 7531 first round
        +	mov	LOOPS, out4               ! loop counter
        +
        +	ld	[in4+4], out1             ! key 8642 first round
        +	sethi	%hi(0x0000FC00), local5
        +
        +	mov	in5, local1               ! left expected in out5
        +	mov	out5, in5
        +
        +	call .des_dec
        +	mov	local1, out5
        +
        +.encrypt2.finish:
        +
        +	! rotate
        +	sll	in5, 29, in0
        +	srl	in5, 3, in5
        +	sll	out5, 29, in1
        +	add	in5, in0, in5
        +	srl	out5, 3, out5
        +	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
        +	add	out5, in1, out5
        +	st	out5, [in0]
        +	st	in5, [in0+4]
        +
        +	ret
        +	restore
        +
        +.DES_encrypt2.end:
        +	.size	 DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
        +
        +
        +! void DES_encrypt3(data, ks1, ks2, ks3)
        +! **************************************
        +
        +	.align 32
        +	.global DES_encrypt3
        +	.type	 DES_encrypt3,#function
        +
        +DES_encrypt3:
        +
        +	save	%sp, FRAME, %sp
        +	
        +	sethi	%hi(.PIC.DES_SPtrans-1f),global1
        +	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
        +1:	call	.+8
        +	add	%o7,global1,global1
        +	sub	global1,.PIC.DES_SPtrans-.des_and,out2
        +
        +	ld	[in0], in5                ! left
        +	add	in2, 120, in4             ! ks2
        +
        +	ld	[in0+4], out5             ! right
        +	mov	in3, in2                  ! save ks3
        +
        +	! parameter 6  1/2 for include encryption/decryption
        +	! parameter 7  1 for mov in1 to in3
        +	! parameter 8  1 for mov in3 to in4
        +	! parameter 9  1 for load ks3 and ks2 to in4 and in3
        +
        +	ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
        +
        +	call	.des_dec
        +	mov	in2, in3                  ! preload ks3
        +
        +	call	.des_enc
        +	nop
        +
        +	fp_macro(in5, out5, 1)
        +
        +	ret
        +	restore
        +
        +.DES_encrypt3.end:
        +	.size	 DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
        +
        +
        +! void DES_decrypt3(data, ks1, ks2, ks3)
        +! **************************************
        +
        +	.align 32
        +	.global DES_decrypt3
        +	.type	 DES_decrypt3,#function
        +
        +DES_decrypt3:
        +
        +	save	%sp, FRAME, %sp
        +	
        +	sethi	%hi(.PIC.DES_SPtrans-1f),global1
        +	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
        +1:	call	.+8
        +	add	%o7,global1,global1
        +	sub	global1,.PIC.DES_SPtrans-.des_and,out2
        +
        +	ld	[in0], in5                ! left
        +	add	in3, 120, in4             ! ks3
        +
        +	ld	[in0+4], out5             ! right
        +	mov	in2, in3                  ! ks2
        +
        +	! parameter 6  1/2 for include encryption/decryption
        +	! parameter 7  1 for mov in1 to in3
        +	! parameter 8  1 for mov in3 to in4
        +	! parameter 9  1 for load ks3 and ks2 to in4 and in3
        +
        +	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
        +
        +	call	.des_enc
        +	add	in1, 120, in4             ! preload ks1
        +
        +	call	.des_dec
        +	nop
        +
        +	fp_macro(out5, in5, 1)
        +
        +	ret
        +	restore
        +
        +.DES_decrypt3.end:
        +	.size	 DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
        +
        +! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
        +! *****************************************************************
        +
        +
        +	.align 32
        +	.global DES_ncbc_encrypt
        +	.type	 DES_ncbc_encrypt,#function
        +
        +DES_ncbc_encrypt:
        +
        +	save	%sp, FRAME, %sp
        +	
        +	define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
        +	define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
        +	define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
        +
        +	sethi	%hi(.PIC.DES_SPtrans-1f),global1
        +	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
        +1:	call	.+8
        +	add	%o7,global1,global1
        +	sub	global1,.PIC.DES_SPtrans-.des_and,out2
        +
        +	cmp	in5, 0                    ! enc   
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	be,pn	%icc, .ncbc.dec
        +#else
        +	be	.ncbc.dec
        +#endif
        +	STPTR	in4, IVEC
        +
        +	! addr  left  right  temp  label
        +	load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
        +
        +	addcc	in2, -8, in2              ! bytes missing when first block done
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bl,pn	%icc, .ncbc.enc.seven.or.less
        +#else
        +	bl	.ncbc.enc.seven.or.less
        +#endif
        +	mov	in3, in4                  ! schedule
        +
        +.ncbc.enc.next.block:
        +
        +	load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
        +
        +.ncbc.enc.next.block_1:
        +
        +	xor	in5, out4, in5            ! iv xor
        +	xor	out5, global4, out5       ! iv xor
        +
        +	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
        +	ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
        +
        +.ncbc.enc.next.block_2:
        +
        +!//	call .des_enc                     ! compares in2 to 8
        +!	rounds inlined for alignment purposes
        +
        +	add	global1, 768, global4     ! address sbox 4 since register used below
        +
        +	rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bl,pn	%icc, .ncbc.enc.next.block_fp
        +#else
        +	bl	.ncbc.enc.next.block_fp
        +#endif
        +	add	in0, 8, in0               ! input address
        +
        +	! If 8 or more bytes are to be encrypted after this block,
        +	! we combine final permutation for this block with initial
        +	! permutation for next block. Load next block:
        +
        +	load_little_endian(in0, global3, global4, local5, .LLE12)
        +
        +	!  parameter 1   original left
        +	!  parameter 2   original right
        +	!  parameter 3   left ip
        +	!  parameter 4   right ip
        +	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
        +	!                2: mov in4 to in3
        +	!
        +	! also adds -8 to length in2 and loads loop counter to out4
        +
        +	fp_ip_macro(out0, out1, global3, global4, 2)
        +
        +	store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
        +
        +	ld	[in3], out0               ! key 7531 first round next block
        +	mov 	in5, local1
        +	xor	global3, out5, in5        ! iv xor next block
        +
        +	ld	[in3+4], out1             ! key 8642
        +	add	global1, 512, global3     ! address sbox 3 since register used
        +	xor	global4, local1, out5     ! iv xor next block
        +
        +	ba	.ncbc.enc.next.block_2
        +	add	in1, 8, in1               ! output adress
        +
        +.ncbc.enc.next.block_fp:
        +
        +	fp_macro(in5, out5)
        +
        +	store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
        +
        +	addcc   in2, -8, in2              ! bytes missing when next block done
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bpos,pt	%icc, .ncbc.enc.next.block  ! also jumps if 0
        +#else
        +	bpos	.ncbc.enc.next.block
        +#endif
        +	add	in1, 8, in1
        +
        +.ncbc.enc.seven.or.less:
        +
        +	cmp	in2, -8
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	ble,pt	%icc, .ncbc.enc.finish
        +#else
        +	ble	.ncbc.enc.finish
        +#endif
        +	nop
        +
        +	add	in2, 8, local1            ! bytes to load
        +
        +	! addr, length, dest left, dest right, temp, temp2, label, ret label
        +	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
        +
        +	! Loads 1 to 7 bytes little endian to global4, out4
        +
        +
        +.ncbc.enc.finish:
        +
        +	LDPTR	IVEC, local4
        +	store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
        +
        +	ret
        +	restore
        +
        +
        +.ncbc.dec:
        +
        +	STPTR	in0, INPUT
        +	cmp	in2, 0                    ! length
        +	add	in3, 120, in3
        +
        +	LDPTR	IVEC, local7              ! ivec
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	ble,pn	%icc, .ncbc.dec.finish
        +#else
        +	ble	.ncbc.dec.finish
        +#endif
        +	mov	in3, in4                  ! schedule
        +
        +	STPTR	in1, OUTPUT
        +	mov	in0, local5               ! input
        +
        +	load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
        +
        +.ncbc.dec.next.block:
        +
        +	load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
        +
        +	! parameter 6  1/2 for include encryption/decryption
        +	! parameter 7  1 for mov in1 to in3
        +	! parameter 8  1 for mov in3 to in4
        +
        +	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
        +
        +	fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
        +
        +	! in2 is bytes left to be stored
        +	! in2 is compared to 8 in the rounds
        +
        +	xor	out5, in0, out4           ! iv xor
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bl,pn	%icc, .ncbc.dec.seven.or.less
        +#else
        +	bl	.ncbc.dec.seven.or.less
        +#endif
        +	xor	in5, in1, global4         ! iv xor
        +
        +	! Load ivec next block now, since input and output address might be the same.
        +
        +	load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
        +
        +	store_little_endian(local7, out4, global4, local3, .SLE3)
        +
        +	STPTR	local5, INPUT
        +	add	local7, 8, local7
        +	addcc   in2, -8, in2
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bg,pt	%icc, .ncbc.dec.next.block
        +#else
        +	bg	.ncbc.dec.next.block
        +#endif
        +	STPTR	local7, OUTPUT
        +
        +
        +.ncbc.dec.store.iv:
        +
        +	LDPTR	IVEC, local4              ! ivec
        +	store_little_endian(local4, in0, in1, local5, .SLE4)
        +
        +.ncbc.dec.finish:
        +
        +	ret
        +	restore
        +
        +.ncbc.dec.seven.or.less:
        +
        +	load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
        +
        +	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
        +
        +
        +.DES_ncbc_encrypt.end:
        +	.size	 DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
        +
        +
        +! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
        +! **************************************************************************
        +
        +
        +	.align 32
        +	.global DES_ede3_cbc_encrypt
        +	.type	 DES_ede3_cbc_encrypt,#function
        +
        +DES_ede3_cbc_encrypt:
        +
        +	save	%sp, FRAME, %sp
        +
        +	define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
        +	define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
        +	define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
        +
        +	sethi	%hi(.PIC.DES_SPtrans-1f),global1
        +	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
        +1:	call	.+8
        +	add	%o7,global1,global1
        +	sub	global1,.PIC.DES_SPtrans-.des_and,out2
        +
        +	LDPTR	[%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
        +	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
        +	cmp	local3, 0                 ! enc
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	be,pn	%icc, .ede3.dec
        +#else
        +	be	.ede3.dec
        +#endif
        +	STPTR	in4, KS2
        +
        +	STPTR	in5, KS3
        +
        +	load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
        +
        +	addcc	in2, -8, in2              ! bytes missing after next block
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bl,pn	%icc,  .ede3.enc.seven.or.less
        +#else
        +	bl	.ede3.enc.seven.or.less
        +#endif
        +	STPTR	in3, KS1
        +
        +.ede3.enc.next.block:
        +
        +	load_little_endian(in0, out4, global4, local3, .LLE7)
        +
        +.ede3.enc.next.block_1:
        +
        +	LDPTR	KS2, in4
        +	xor	in5, out4, in5            ! iv xor
        +	xor	out5, global4, out5       ! iv xor
        +
        +	LDPTR	KS1, in3
        +	add	in4, 120, in4             ! for decryption we use last subkey first
        +	nop
        +
        +	ip_macro(in5, out5, in5, out5, in3)
        +
        +.ede3.enc.next.block_2:
        +
        +	call .des_enc                     ! ks1 in3
        +	nop
        +
        +	call .des_dec                     ! ks2 in4
        +	LDPTR	KS3, in3
        +
        +	call .des_enc                     ! ks3 in3  compares in2 to 8
        +	nop
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bl,pn	%icc, .ede3.enc.next.block_fp
        +#else
        +	bl	.ede3.enc.next.block_fp
        +#endif
        +	add	in0, 8, in0
        +
        +	! If 8 or more bytes are to be encrypted after this block,
        +	! we combine final permutation for this block with initial
        +	! permutation for next block. Load next block:
        +
        +	load_little_endian(in0, global3, global4, local5, .LLE11)
        +
        +	!  parameter 1   original left
        +	!  parameter 2   original right
        +	!  parameter 3   left ip
        +	!  parameter 4   right ip
        +	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
        +	!                2: mov in4 to in3
        +	!
        +	! also adds -8 to length in2 and loads loop counter to out4
        +
        +	fp_ip_macro(out0, out1, global3, global4, 1)
        +
        +	store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
        +
        +	mov 	in5, local1
        +	xor	global3, out5, in5        ! iv xor next block
        +
        +	ld	[in3], out0               ! key 7531
        +	add	global1, 512, global3     ! address sbox 3
        +	xor	global4, local1, out5     ! iv xor next block
        +
        +	ld	[in3+4], out1             ! key 8642
        +	add	global1, 768, global4     ! address sbox 4
        +	ba	.ede3.enc.next.block_2
        +	add	in1, 8, in1
        +
        +.ede3.enc.next.block_fp:
        +
        +	fp_macro(in5, out5)
        +
        +	store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
        +
        +	addcc   in2, -8, in2              ! bytes missing when next block done
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bpos,pt	%icc, .ede3.enc.next.block
        +#else
        +	bpos	.ede3.enc.next.block
        +#endif
        +	add	in1, 8, in1
        +
        +.ede3.enc.seven.or.less:
        +
        +	cmp	in2, -8
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	ble,pt	%icc, .ede3.enc.finish
        +#else
        +	ble	.ede3.enc.finish
        +#endif
        +	nop
        +
        +	add	in2, 8, local1            ! bytes to load
        +
        +	! addr, length, dest left, dest right, temp, temp2, label, ret label
        +	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
        +
        +.ede3.enc.finish:
        +
        +	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
        +	store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
        +
        +	ret
        +	restore
        +
        +.ede3.dec:
        +
        +	STPTR	in0, INPUT
        +	add	in5, 120, in5
        +
        +	STPTR	in1, OUTPUT
        +	mov	in0, local5
        +	add	in3, 120, in3
        +
        +	STPTR	in3, KS1
        +	cmp	in2, 0
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	ble	%icc, .ede3.dec.finish
        +#else
        +	ble	.ede3.dec.finish
        +#endif
        +	STPTR	in5, KS3
        +
        +	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
        +	load_little_endian(local7, in0, in1, local3, .LLE8)
        +
        +.ede3.dec.next.block:
        +
        +	load_little_endian(local5, in5, out5, local3, .LLE9)
        +
        +	! parameter 6  1/2 for include encryption/decryption
        +	! parameter 7  1 for mov in1 to in3
        +	! parameter 8  1 for mov in3 to in4
        +	! parameter 9  1 for load ks3 and ks2 to in4 and in3
        +
        +	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
        +
        +	call .des_enc                     ! ks2 in3
        +	LDPTR	KS1, in4
        +
        +	call .des_dec                     ! ks1 in4
        +	nop
        +
        +	fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
        +
        +	! in2 is bytes left to be stored
        +	! in2 is compared to 8 in the rounds
        +
        +	xor	out5, in0, out4
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bl,pn	%icc, .ede3.dec.seven.or.less
        +#else
        +	bl	.ede3.dec.seven.or.less
        +#endif
        +	xor	in5, in1, global4
        +
        +	load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
        +
        +	store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
        +
        +	STPTR	local5, INPUT
        +	addcc   in2, -8, in2
        +	add	local7, 8, local7
        +
        +#ifdef OPENSSL_SYSNAME_ULTRASPARC
        +	bg,pt	%icc, .ede3.dec.next.block
        +#else
        +	bg	.ede3.dec.next.block
        +#endif
        +	STPTR	local7, OUTPUT
        +
        +.ede3.dec.store.iv:
        +
        +	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
        +	store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
        +
        +.ede3.dec.finish:
        +
        +	ret
        +	restore
        +
        +.ede3.dec.seven.or.less:
        +
        +	load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
        +
        +	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
        +
        +
        +.DES_ede3_cbc_encrypt.end:
        +	.size	 DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
        +
        +	.align	256
        +	.type	 .des_and,#object
        +	.size	 .des_and,284
        +
        +.des_and:
        +
        +! This table is used for AND 0xFC when it is known that register
        +! bits 8-31 are zero. Makes it possible to do three arithmetic
        +! operations in one cycle.
        +
        +	.byte  0, 0, 0, 0, 4, 4, 4, 4
        +	.byte  8, 8, 8, 8, 12, 12, 12, 12
        +	.byte  16, 16, 16, 16, 20, 20, 20, 20
        +	.byte  24, 24, 24, 24, 28, 28, 28, 28
        +	.byte  32, 32, 32, 32, 36, 36, 36, 36
        +	.byte  40, 40, 40, 40, 44, 44, 44, 44
        +	.byte  48, 48, 48, 48, 52, 52, 52, 52
        +	.byte  56, 56, 56, 56, 60, 60, 60, 60
        +	.byte  64, 64, 64, 64, 68, 68, 68, 68
        +	.byte  72, 72, 72, 72, 76, 76, 76, 76
        +	.byte  80, 80, 80, 80, 84, 84, 84, 84
        +	.byte  88, 88, 88, 88, 92, 92, 92, 92
        +	.byte  96, 96, 96, 96, 100, 100, 100, 100
        +	.byte  104, 104, 104, 104, 108, 108, 108, 108
        +	.byte  112, 112, 112, 112, 116, 116, 116, 116
        +	.byte  120, 120, 120, 120, 124, 124, 124, 124
        +	.byte  128, 128, 128, 128, 132, 132, 132, 132
        +	.byte  136, 136, 136, 136, 140, 140, 140, 140
        +	.byte  144, 144, 144, 144, 148, 148, 148, 148
        +	.byte  152, 152, 152, 152, 156, 156, 156, 156
        +	.byte  160, 160, 160, 160, 164, 164, 164, 164
        +	.byte  168, 168, 168, 168, 172, 172, 172, 172
        +	.byte  176, 176, 176, 176, 180, 180, 180, 180
        +	.byte  184, 184, 184, 184, 188, 188, 188, 188
        +	.byte  192, 192, 192, 192, 196, 196, 196, 196
        +	.byte  200, 200, 200, 200, 204, 204, 204, 204
        +	.byte  208, 208, 208, 208, 212, 212, 212, 212
        +	.byte  216, 216, 216, 216, 220, 220, 220, 220
        +	.byte  224, 224, 224, 224, 228, 228, 228, 228
        +	.byte  232, 232, 232, 232, 236, 236, 236, 236
        +	.byte  240, 240, 240, 240, 244, 244, 244, 244
        +	.byte  248, 248, 248, 248, 252, 252, 252, 252
        +
        +	! 5 numbers for initil/final permutation
        +
        +	.word   0x0f0f0f0f                ! offset 256
        +	.word	0x0000ffff                ! 260
        +	.word	0x33333333                ! 264
        +	.word	0x00ff00ff                ! 268
        +	.word	0x55555555                ! 272
        +
        +	.word	0                         ! 276
        +	.word	LOOPS                     ! 280
        +	.word	0x0000FC00                ! 284
        +
        +	.global	DES_SPtrans
        +	.type	DES_SPtrans,#object
        +	.size	DES_SPtrans,2048
        +.align	64
        +DES_SPtrans:
        +.PIC.DES_SPtrans:
        +	! nibble 0
        +	.word	0x02080800, 0x00080000, 0x02000002, 0x02080802
        +	.word	0x02000000, 0x00080802, 0x00080002, 0x02000002
        +	.word	0x00080802, 0x02080800, 0x02080000, 0x00000802
        +	.word	0x02000802, 0x02000000, 0x00000000, 0x00080002
        +	.word	0x00080000, 0x00000002, 0x02000800, 0x00080800
        +	.word	0x02080802, 0x02080000, 0x00000802, 0x02000800
        +	.word	0x00000002, 0x00000800, 0x00080800, 0x02080002
        +	.word	0x00000800, 0x02000802, 0x02080002, 0x00000000
        +	.word	0x00000000, 0x02080802, 0x02000800, 0x00080002
        +	.word	0x02080800, 0x00080000, 0x00000802, 0x02000800
        +	.word	0x02080002, 0x00000800, 0x00080800, 0x02000002
        +	.word	0x00080802, 0x00000002, 0x02000002, 0x02080000
        +	.word	0x02080802, 0x00080800, 0x02080000, 0x02000802
        +	.word	0x02000000, 0x00000802, 0x00080002, 0x00000000
        +	.word	0x00080000, 0x02000000, 0x02000802, 0x02080800
        +	.word	0x00000002, 0x02080002, 0x00000800, 0x00080802
        +	! nibble 1
        +	.word	0x40108010, 0x00000000, 0x00108000, 0x40100000
        +	.word	0x40000010, 0x00008010, 0x40008000, 0x00108000
        +	.word	0x00008000, 0x40100010, 0x00000010, 0x40008000
        +	.word	0x00100010, 0x40108000, 0x40100000, 0x00000010
        +	.word	0x00100000, 0x40008010, 0x40100010, 0x00008000
        +	.word	0x00108010, 0x40000000, 0x00000000, 0x00100010
        +	.word	0x40008010, 0x00108010, 0x40108000, 0x40000010
        +	.word	0x40000000, 0x00100000, 0x00008010, 0x40108010
        +	.word	0x00100010, 0x40108000, 0x40008000, 0x00108010
        +	.word	0x40108010, 0x00100010, 0x40000010, 0x00000000
        +	.word	0x40000000, 0x00008010, 0x00100000, 0x40100010
        +	.word	0x00008000, 0x40000000, 0x00108010, 0x40008010
        +	.word	0x40108000, 0x00008000, 0x00000000, 0x40000010
        +	.word	0x00000010, 0x40108010, 0x00108000, 0x40100000
        +	.word	0x40100010, 0x00100000, 0x00008010, 0x40008000
        +	.word	0x40008010, 0x00000010, 0x40100000, 0x00108000
        +	! nibble 2
        +	.word	0x04000001, 0x04040100, 0x00000100, 0x04000101
        +	.word	0x00040001, 0x04000000, 0x04000101, 0x00040100
        +	.word	0x04000100, 0x00040000, 0x04040000, 0x00000001
        +	.word	0x04040101, 0x00000101, 0x00000001, 0x04040001
        +	.word	0x00000000, 0x00040001, 0x04040100, 0x00000100
        +	.word	0x00000101, 0x04040101, 0x00040000, 0x04000001
        +	.word	0x04040001, 0x04000100, 0x00040101, 0x04040000
        +	.word	0x00040100, 0x00000000, 0x04000000, 0x00040101
        +	.word	0x04040100, 0x00000100, 0x00000001, 0x00040000
        +	.word	0x00000101, 0x00040001, 0x04040000, 0x04000101
        +	.word	0x00000000, 0x04040100, 0x00040100, 0x04040001
        +	.word	0x00040001, 0x04000000, 0x04040101, 0x00000001
        +	.word	0x00040101, 0x04000001, 0x04000000, 0x04040101
        +	.word	0x00040000, 0x04000100, 0x04000101, 0x00040100
        +	.word	0x04000100, 0x00000000, 0x04040001, 0x00000101
        +	.word	0x04000001, 0x00040101, 0x00000100, 0x04040000
        +	! nibble 3
        +	.word	0x00401008, 0x10001000, 0x00000008, 0x10401008
        +	.word	0x00000000, 0x10400000, 0x10001008, 0x00400008
        +	.word	0x10401000, 0x10000008, 0x10000000, 0x00001008
        +	.word	0x10000008, 0x00401008, 0x00400000, 0x10000000
        +	.word	0x10400008, 0x00401000, 0x00001000, 0x00000008
        +	.word	0x00401000, 0x10001008, 0x10400000, 0x00001000
        +	.word	0x00001008, 0x00000000, 0x00400008, 0x10401000
        +	.word	0x10001000, 0x10400008, 0x10401008, 0x00400000
        +	.word	0x10400008, 0x00001008, 0x00400000, 0x10000008
        +	.word	0x00401000, 0x10001000, 0x00000008, 0x10400000
        +	.word	0x10001008, 0x00000000, 0x00001000, 0x00400008
        +	.word	0x00000000, 0x10400008, 0x10401000, 0x00001000
        +	.word	0x10000000, 0x10401008, 0x00401008, 0x00400000
        +	.word	0x10401008, 0x00000008, 0x10001000, 0x00401008
        +	.word	0x00400008, 0x00401000, 0x10400000, 0x10001008
        +	.word	0x00001008, 0x10000000, 0x10000008, 0x10401000
        +	! nibble 4
        +	.word	0x08000000, 0x00010000, 0x00000400, 0x08010420
        +	.word	0x08010020, 0x08000400, 0x00010420, 0x08010000
        +	.word	0x00010000, 0x00000020, 0x08000020, 0x00010400
        +	.word	0x08000420, 0x08010020, 0x08010400, 0x00000000
        +	.word	0x00010400, 0x08000000, 0x00010020, 0x00000420
        +	.word	0x08000400, 0x00010420, 0x00000000, 0x08000020
        +	.word	0x00000020, 0x08000420, 0x08010420, 0x00010020
        +	.word	0x08010000, 0x00000400, 0x00000420, 0x08010400
        +	.word	0x08010400, 0x08000420, 0x00010020, 0x08010000
        +	.word	0x00010000, 0x00000020, 0x08000020, 0x08000400
        +	.word	0x08000000, 0x00010400, 0x08010420, 0x00000000
        +	.word	0x00010420, 0x08000000, 0x00000400, 0x00010020
        +	.word	0x08000420, 0x00000400, 0x00000000, 0x08010420
        +	.word	0x08010020, 0x08010400, 0x00000420, 0x00010000
        +	.word	0x00010400, 0x08010020, 0x08000400, 0x00000420
        +	.word	0x00000020, 0x00010420, 0x08010000, 0x08000020
        +	! nibble 5
        +	.word	0x80000040, 0x00200040, 0x00000000, 0x80202000
        +	.word	0x00200040, 0x00002000, 0x80002040, 0x00200000
        +	.word	0x00002040, 0x80202040, 0x00202000, 0x80000000
        +	.word	0x80002000, 0x80000040, 0x80200000, 0x00202040
        +	.word	0x00200000, 0x80002040, 0x80200040, 0x00000000
        +	.word	0x00002000, 0x00000040, 0x80202000, 0x80200040
        +	.word	0x80202040, 0x80200000, 0x80000000, 0x00002040
        +	.word	0x00000040, 0x00202000, 0x00202040, 0x80002000
        +	.word	0x00002040, 0x80000000, 0x80002000, 0x00202040
        +	.word	0x80202000, 0x00200040, 0x00000000, 0x80002000
        +	.word	0x80000000, 0x00002000, 0x80200040, 0x00200000
        +	.word	0x00200040, 0x80202040, 0x00202000, 0x00000040
        +	.word	0x80202040, 0x00202000, 0x00200000, 0x80002040
        +	.word	0x80000040, 0x80200000, 0x00202040, 0x00000000
        +	.word	0x00002000, 0x80000040, 0x80002040, 0x80202000
        +	.word	0x80200000, 0x00002040, 0x00000040, 0x80200040
        +	! nibble 6
        +	.word	0x00004000, 0x00000200, 0x01000200, 0x01000004
        +	.word	0x01004204, 0x00004004, 0x00004200, 0x00000000
        +	.word	0x01000000, 0x01000204, 0x00000204, 0x01004000
        +	.word	0x00000004, 0x01004200, 0x01004000, 0x00000204
        +	.word	0x01000204, 0x00004000, 0x00004004, 0x01004204
        +	.word	0x00000000, 0x01000200, 0x01000004, 0x00004200
        +	.word	0x01004004, 0x00004204, 0x01004200, 0x00000004
        +	.word	0x00004204, 0x01004004, 0x00000200, 0x01000000
        +	.word	0x00004204, 0x01004000, 0x01004004, 0x00000204
        +	.word	0x00004000, 0x00000200, 0x01000000, 0x01004004
        +	.word	0x01000204, 0x00004204, 0x00004200, 0x00000000
        +	.word	0x00000200, 0x01000004, 0x00000004, 0x01000200
        +	.word	0x00000000, 0x01000204, 0x01000200, 0x00004200
        +	.word	0x00000204, 0x00004000, 0x01004204, 0x01000000
        +	.word	0x01004200, 0x00000004, 0x00004004, 0x01004204
        +	.word	0x01000004, 0x01004200, 0x01004000, 0x00004004
        +	! nibble 7
        +	.word	0x20800080, 0x20820000, 0x00020080, 0x00000000
        +	.word	0x20020000, 0x00800080, 0x20800000, 0x20820080
        +	.word	0x00000080, 0x20000000, 0x00820000, 0x00020080
        +	.word	0x00820080, 0x20020080, 0x20000080, 0x20800000
        +	.word	0x00020000, 0x00820080, 0x00800080, 0x20020000
        +	.word	0x20820080, 0x20000080, 0x00000000, 0x00820000
        +	.word	0x20000000, 0x00800000, 0x20020080, 0x20800080
        +	.word	0x00800000, 0x00020000, 0x20820000, 0x00000080
        +	.word	0x00800000, 0x00020000, 0x20000080, 0x20820080
        +	.word	0x00020080, 0x20000000, 0x00000000, 0x00820000
        +	.word	0x20800080, 0x20020080, 0x20020000, 0x00800080
        +	.word	0x20820000, 0x00000080, 0x00800080, 0x20020000
        +	.word	0x20820080, 0x00800000, 0x20800000, 0x20000080
        +	.word	0x00820000, 0x00020080, 0x20020080, 0x20800000
        +	.word	0x00000080, 0x20820000, 0x00820080, 0x00000000
        +	.word	0x20000000, 0x20800080, 0x00020000, 0x00820080
        +
        diff --git a/vendor/openssl/openssl/crypto/des/asm/desboth.pl b/vendor/openssl/openssl/crypto/des/asm/desboth.pl
        new file mode 100644
        index 000000000..eec00886e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/asm/desboth.pl
        @@ -0,0 +1,79 @@
        +#!/usr/local/bin/perl
        +
        +$L="edi";
        +$R="esi";
        +
        +sub DES_encrypt3
        +	{
        +	local($name,$enc)=@_;
        +
        +	&function_begin_B($name,"");
        +	&push("ebx");
        +	&mov("ebx",&wparam(0));
        +
        +	&push("ebp");
        +	&push("esi");
        +
        +	&push("edi");
        +
        +	&comment("");
        +	&comment("Load the data words");
        +	&mov($L,&DWP(0,"ebx","",0));
        +	&mov($R,&DWP(4,"ebx","",0));
        +	&stack_push(3);
        +
        +	&comment("");
        +	&comment("IP");
        +	&IP_new($L,$R,"edx",0);
        +
        +	# put them back
        +	
        +	if ($enc)
        +		{
        +		&mov(&DWP(4,"ebx","",0),$R);
        +		 &mov("eax",&wparam(1));
        +		&mov(&DWP(0,"ebx","",0),"edx");
        +		 &mov("edi",&wparam(2));
        +		 &mov("esi",&wparam(3));
        +		}
        +	else
        +		{
        +		&mov(&DWP(4,"ebx","",0),$R);
        +		 &mov("esi",&wparam(1));
        +		&mov(&DWP(0,"ebx","",0),"edx");
        +		 &mov("edi",&wparam(2));
        +		 &mov("eax",&wparam(3));
        +		}
        +	&mov(&swtmp(2),	(DWC(($enc)?"1":"0")));
        +	&mov(&swtmp(1),	"eax");
        +	&mov(&swtmp(0),	"ebx");
        +	&call("DES_encrypt2");
        +	&mov(&swtmp(2),	(DWC(($enc)?"0":"1")));
        +	&mov(&swtmp(1),	"edi");
        +	&mov(&swtmp(0),	"ebx");
        +	&call("DES_encrypt2");
        +	&mov(&swtmp(2),	(DWC(($enc)?"1":"0")));
        +	&mov(&swtmp(1),	"esi");
        +	&mov(&swtmp(0),	"ebx");
        +	&call("DES_encrypt2");
        +
        +	&stack_pop(3);
        +	&mov($L,&DWP(0,"ebx","",0));
        +	&mov($R,&DWP(4,"ebx","",0));
        +
        +	&comment("");
        +	&comment("FP");
        +	&FP_new($L,$R,"eax",0);
        +
        +	&mov(&DWP(0,"ebx","",0),"eax");
        +	&mov(&DWP(4,"ebx","",0),$R);
        +
        +	&pop("edi");
        +	&pop("esi");
        +	&pop("ebp");
        +	&pop("ebx");
        +	&ret();
        +	&function_end_B($name);
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/des/asm/readme b/vendor/openssl/openssl/crypto/des/asm/readme
        new file mode 100644
        index 000000000..1beafe253
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/asm/readme
        @@ -0,0 +1,131 @@
        +First up, let me say I don't like writing in assembler.  It is not portable,
        +dependant on the particular CPU architecture release and is generally a pig
        +to debug and get right.  Having said that, the x86 architecture is probably
        +the most important for speed due to number of boxes and since
        +it appears to be the worst architecture to to get
        +good C compilers for.  So due to this, I have lowered myself to do
        +assembler for the inner DES routines in libdes :-).
        +
        +The file to implement in assembler is des_enc.c.  Replace the following
        +4 functions
        +des_encrypt1(DES_LONG data[2],des_key_schedule ks, int encrypt);
        +des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
        +des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
        +des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
        +
        +They encrypt/decrypt the 64 bits held in 'data' using
        +the 'ks' key schedules.   The only difference between the 4 functions is that
        +des_encrypt2() does not perform IP() or FP() on the data (this is an
        +optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
        +perform triple des.  The triple DES routines are in here because it does
        +make a big difference to have them located near the des_encrypt2 function
        +at link time..
        +
        +Now as we all know, there are lots of different operating systems running on
        +x86 boxes, and unfortunately they normally try to make sure their assembler
        +formating is not the same as the other peoples.
        +The 4 main formats I know of are
        +Microsoft	Windows 95/Windows NT
        +Elf		Includes Linux and FreeBSD(?).
        +a.out		The older Linux.
        +Solaris		Same as Elf but different comments :-(.
        +
        +Now I was not overly keen to write 4 different copies of the same code,
        +so I wrote a few perl routines to output the correct assembler, given
        +a target assembler type.  This code is ugly and is just a hack.
        +The libraries are x86unix.pl and x86ms.pl.
        +des586.pl, des686.pl and des-som[23].pl are the programs to actually
        +generate the assembler.
        +
        +So to generate elf assembler
        +perl des-som3.pl elf >dx86-elf.s
        +For Windows 95/NT
        +perl des-som2.pl win32 >win32.asm
        +
        +[ update 4 Jan 1996 ]
        +I have added another way to do things.
        +perl des-som3.pl cpp >dx86-cpp.s
        +generates a file that will be included by dx86unix.cpp when it is compiled.
        +To build for elf, a.out, solaris, bsdi etc,
        +cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
        +cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
        +cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
        +cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
        +This was done to cut down the number of files in the distribution.
        +
        +Now the ugly part.  I acquired my copy of Intels
        +"Optimization's For Intel's 32-Bit Processors" and found a few interesting
        +things.  First, the aim of the exersize is to 'extract' one byte at a time
        +from a word and do an array lookup.  This involves getting the byte from
        +the 4 locations in the word and moving it to a new word and doing the lookup.
        +The most obvious way to do this is
        +xor	eax,	eax				# clear word
        +movb	al,	cl				# get low byte
        +xor	edi	DWORD PTR 0x100+des_SP[eax] 	# xor in word
        +movb	al,	ch				# get next byte
        +xor	edi	DWORD PTR 0x300+des_SP[eax] 	# xor in word
        +shr	ecx	16
        +which seems ok.  For the pentium, this system appears to be the best.
        +One has to do instruction interleaving to keep both functional units
        +operating, but it is basically very efficient.
        +
        +Now the crunch.  When a full register is used after a partial write, eg.
        +mov	al,	cl
        +xor	edi,	DWORD PTR 0x100+des_SP[eax]
        +386	- 1 cycle stall
        +486	- 1 cycle stall
        +586	- 0 cycle stall
        +686	- at least 7 cycle stall (page 22 of the above mentioned document).
        +
        +So the technique that produces the best results on a pentium, according to
        +the documentation, will produce hideous results on a pentium pro.
        +
        +To get around this, des686.pl will generate code that is not as fast on
        +a pentium, should be very good on a pentium pro.
        +mov	eax,	ecx				# copy word 
        +shr	ecx,	8				# line up next byte
        +and	eax,	0fch				# mask byte
        +xor	edi	DWORD PTR 0x100+des_SP[eax] 	# xor in array lookup
        +mov	eax,	ecx				# get word
        +shr	ecx	8				# line up next byte
        +and	eax,	0fch				# mask byte
        +xor	edi	DWORD PTR 0x300+des_SP[eax] 	# xor in array lookup
        +
        +Due to the execution units in the pentium, this actually works quite well.
        +For a pentium pro it should be very good.  This is the type of output
        +Visual C++ generates.
        +
        +There is a third option.  instead of using
        +mov	al,	ch
        +which is bad on the pentium pro, one may be able to use
        +movzx	eax,	ch
        +which may not incur the partial write penalty.  On the pentium,
        +this instruction takes 4 cycles so is not worth using but on the
        +pentium pro it appears it may be worth while.  I need access to one to
        +experiment :-).
        +
        +eric (20 Oct 1996)
        +
        +22 Nov 1996 - I have asked people to run the 2 different version on pentium
        +pros and it appears that the intel documentation is wrong.  The
        +mov al,bh is still faster on a pentium pro, so just use the des586.pl
        +install des686.pl
        +
        +3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
        +functions into des_enc.c because it does make a massive performance
        +difference on some boxes to have the functions code located close to
        +the des_encrypt2() function.
        +
        +9 Jan 1997 - des-som2.pl is now the correct perl script to use for
        +pentiums.  It contains an inner loop from
        +Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
        +273,000 per second.  He had a previous version at 250,000 and the best
        +I was able to get was 203,000.  The content has not changed, this is all
        +due to instruction sequencing (and actual instructions choice) which is able
        +to keep both functional units of the pentium going.
        +We may have lost the ugly register usage restrictions when x86 went 32 bit
        +but for the pentium it has been replaced by evil instruction ordering tricks.
        +
        +13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
        +raw DES at 281,000 per second on a pentium 100.
        +
        diff --git a/vendor/openssl/openssl/crypto/des/cbc3_enc.c b/vendor/openssl/openssl/crypto/des/cbc3_enc.c
        new file mode 100644
        index 000000000..b5db4e14f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/cbc3_enc.c
        @@ -0,0 +1,99 @@
        +/* crypto/des/cbc3_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +
        +/* HAS BUGS! DON'T USE - this is only present for use in des.c */
        +void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length,
        +	     DES_key_schedule ks1, DES_key_schedule ks2, DES_cblock *iv1,
        +	     DES_cblock *iv2, int enc)
        +	{
        +	int off=((int)length-1)/8;
        +	long l8=((length+7)/8)*8;
        +	DES_cblock niv1,niv2;
        +
        +	if (enc == DES_ENCRYPT)
        +		{
        +		DES_cbc_encrypt((unsigned char*)input,
        +				(unsigned char*)output,length,&ks1,iv1,enc);
        +		if (length >= sizeof(DES_cblock))
        +			memcpy(niv1,output[off],sizeof(DES_cblock));
        +		DES_cbc_encrypt((unsigned char*)output,
        +				(unsigned char*)output,l8,&ks2,iv1,!enc);
        +		DES_cbc_encrypt((unsigned char*)output,
        +				(unsigned char*)output,l8,&ks1,iv2,enc);
        +		if (length >= sizeof(DES_cblock))
        +			memcpy(niv2,output[off],sizeof(DES_cblock));
        +		}
        +	else
        +		{
        +		if (length >= sizeof(DES_cblock))
        +			memcpy(niv2,input[off],sizeof(DES_cblock));
        +		DES_cbc_encrypt((unsigned char*)input,
        +				(unsigned char*)output,l8,&ks1,iv2,enc);
        +		DES_cbc_encrypt((unsigned char*)output,
        +				(unsigned char*)output,l8,&ks2,iv1,!enc);
        +		if (length >= sizeof(DES_cblock))
        +			memcpy(niv1,output[off],sizeof(DES_cblock));
        +		DES_cbc_encrypt((unsigned char*)output,
        +				(unsigned char*)output,length,&ks1,iv1,enc);
        +		}
        +	memcpy(*iv1,niv1,sizeof(DES_cblock));
        +	memcpy(*iv2,niv2,sizeof(DES_cblock));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/cbc_cksm.c b/vendor/openssl/openssl/crypto/des/cbc_cksm.c
        new file mode 100644
        index 000000000..09a7ba56a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/cbc_cksm.c
        @@ -0,0 +1,106 @@
        +/* crypto/des/cbc_cksm.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 "des_locl.h"
        +
        +DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output,
        +		       long length, DES_key_schedule *schedule,
        +		       const_DES_cblock *ivec)
        +	{
        +	register DES_LONG tout0,tout1,tin0,tin1;
        +	register long l=length;
        +	DES_LONG tin[2];
        +	unsigned char *out = &(*output)[0];
        +	const unsigned char *iv = &(*ivec)[0];
        +
        +	c2l(iv,tout0);
        +	c2l(iv,tout1);
        +	for (; l>0; l-=8)
        +		{
        +		if (l >= 8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			}
        +		else
        +			c2ln(in,tin0,tin1,l);
        +			
        +		tin0^=tout0; tin[0]=tin0;
        +		tin1^=tout1; tin[1]=tin1;
        +		DES_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
        +		/* fix 15/10/91 eay - thanks to keithr@sco.COM */
        +		tout0=tin[0];
        +		tout1=tin[1];
        +		}
        +	if (out != NULL)
        +		{
        +		l2c(tout0,out);
        +		l2c(tout1,out);
        +		}
        +	tout0=tin0=tin1=tin[0]=tin[1]=0;
        +	/*
        +	  Transform the data in tout1 so that it will
        +	  match the return value that the MIT Kerberos
        +	  mit_des_cbc_cksum API returns.
        +	*/
        +	tout1 = ((tout1 >> 24L) & 0x000000FF)
        +	      | ((tout1 >> 8L)  & 0x0000FF00)
        +	      | ((tout1 << 8L)  & 0x00FF0000)
        +	      | ((tout1 << 24L) & 0xFF000000);
        +	return(tout1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/cbc_enc.c b/vendor/openssl/openssl/crypto/des/cbc_enc.c
        new file mode 100644
        index 000000000..677903ae4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/cbc_enc.c
        @@ -0,0 +1,61 @@
        +/* crypto/des/cbc_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#define CBC_ENC_C__DONT_UPDATE_IV
        +
        +#include "ncbc_enc.c" /* des_cbc_encrypt */
        diff --git a/vendor/openssl/openssl/crypto/des/cfb64ede.c b/vendor/openssl/openssl/crypto/des/cfb64ede.c
        new file mode 100644
        index 000000000..de34ecceb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/cfb64ede.c
        @@ -0,0 +1,254 @@
        +/* crypto/des/cfb64ede.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 "des_locl.h"
        +#include "e_os.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +			    long length, DES_key_schedule *ks1,
        +			    DES_key_schedule *ks2, DES_key_schedule *ks3,
        +			    DES_cblock *ivec, int *num, int enc)
        +	{
        +	register DES_LONG v0,v1;
        +	register long l=length;
        +	register int n= *num;
        +	DES_LONG ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv=&(*ivec)[0];
        +	if (enc)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0);
        +				c2l(iv,v1);
        +
        +				ti[0]=v0;
        +				ti[1]=v1;
        +				DES_encrypt3(ti,ks1,ks2,ks3);
        +				v0=ti[0];
        +				v1=ti[1];
        +
        +				iv = &(*ivec)[0];
        +				l2c(v0,iv);
        +				l2c(v1,iv);
        +				iv = &(*ivec)[0];
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0);
        +				c2l(iv,v1);
        +
        +				ti[0]=v0;
        +				ti[1]=v1;
        +				DES_encrypt3(ti,ks1,ks2,ks3);
        +				v0=ti[0];
        +				v1=ti[1];
        +
        +				iv = &(*ivec)[0];
        +				l2c(v0,iv);
        +				l2c(v1,iv);
        +				iv = &(*ivec)[0];
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=c=cc=0;
        +	*num=n;
        +	}
        +
        +#ifdef undef /* MACRO */
        +void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
        +	     DES_key_schedule ks1, DES_key_schedule ks2, DES_cblock (*ivec),
        +	     int *num, int enc)
        +	{
        +	DES_ede3_cfb64_encrypt(in,out,length,ks1,ks2,ks1,ivec,num,enc);
        +	}
        +#endif
        +
        +/* This is compatible with the single key CFB-r for DES, even thought that's
        + * not what EVP needs.
        + */
        +
        +void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
        +			  int numbits,long length,DES_key_schedule *ks1,
        +			  DES_key_schedule *ks2,DES_key_schedule *ks3,
        +			  DES_cblock *ivec,int enc)
        +	{
        +	register DES_LONG d0,d1,v0,v1;
        +	register unsigned long l=length,n=((unsigned int)numbits+7)/8;
        +	register int num=numbits,i;
        +	DES_LONG ti[2];
        +	unsigned char *iv;
        +	unsigned char ovec[16];
        +
        +	if (num > 64) return;
        +	iv = &(*ivec)[0];
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	if (enc)
        +		{
        +		while (l >= n)
        +			{
        +			l-=n;
        +			ti[0]=v0;
        +			ti[1]=v1;
        +			DES_encrypt3(ti,ks1,ks2,ks3);
        +			c2ln(in,d0,d1,n);
        +			in+=n;
        +			d0^=ti[0];
        +			d1^=ti[1];
        +			l2cn(d0,d1,out,n);
        +			out+=n;
        +			/* 30-08-94 - eay - changed because l>>32 and
        +			 * l<<32 are bad under gcc :-( */
        +			if (num == 32)
        +				{ v0=v1; v1=d0; }
        +			else if (num == 64)
        +				{ v0=d0; v1=d1; }
        +			else
        +				{
        +				iv=&ovec[0];
        +				l2c(v0,iv);
        +				l2c(v1,iv);
        +				l2c(d0,iv);
        +				l2c(d1,iv);
        +				/* shift ovec left most of the bits... */
        +				memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
        +				/* now the remaining bits */
        +				if(num%8 != 0)
        +					for(i=0 ; i < 8 ; ++i)
        +						{
        +						ovec[i]<<=num%8;
        +						ovec[i]|=ovec[i+1]>>(8-num%8);
        +						}
        +				iv=&ovec[0];
        +				c2l(iv,v0);
        +				c2l(iv,v1);
        +				}
        +			}
        +		}
        +	else
        +		{
        +		while (l >= n)
        +			{
        +			l-=n;
        +			ti[0]=v0;
        +			ti[1]=v1;
        +			DES_encrypt3(ti,ks1,ks2,ks3);
        +			c2ln(in,d0,d1,n);
        +			in+=n;
        +			/* 30-08-94 - eay - changed because l>>32 and
        +			 * l<<32 are bad under gcc :-( */
        +			if (num == 32)
        +				{ v0=v1; v1=d0; }
        +			else if (num == 64)
        +				{ v0=d0; v1=d1; }
        +			else
        +				{
        +				iv=&ovec[0];
        +				l2c(v0,iv);
        +				l2c(v1,iv);
        +				l2c(d0,iv);
        +				l2c(d1,iv);
        +				/* shift ovec left most of the bits... */
        +				memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
        +				/* now the remaining bits */
        +				if(num%8 != 0)
        +					for(i=0 ; i < 8 ; ++i)
        +						{
        +						ovec[i]<<=num%8;
        +						ovec[i]|=ovec[i+1]>>(8-num%8);
        +						}
        +				iv=&ovec[0];
        +				c2l(iv,v0);
        +				c2l(iv,v1);
        +				}
        +			d0^=ti[0];
        +			d1^=ti[1];
        +			l2cn(d0,d1,out,n);
        +			out+=n;
        +			}
        +		}
        +	iv = &(*ivec)[0];
        +	l2c(v0,iv);
        +	l2c(v1,iv);
        +	v0=v1=d0=d1=ti[0]=ti[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/cfb64enc.c b/vendor/openssl/openssl/crypto/des/cfb64enc.c
        new file mode 100644
        index 000000000..5ec8683e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/cfb64enc.c
        @@ -0,0 +1,121 @@
        +/* crypto/des/cfb64enc.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 "des_locl.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +		       long length, DES_key_schedule *schedule,
        +		       DES_cblock *ivec, int *num, int enc)
        +	{
        +	register DES_LONG v0,v1;
        +	register long l=length;
        +	register int n= *num;
        +	DES_LONG ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv = &(*ivec)[0];
        +	if (enc)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0); ti[0]=v0;
        +				c2l(iv,v1); ti[1]=v1;
        +				DES_encrypt1(ti,schedule,DES_ENCRYPT);
        +				iv = &(*ivec)[0];
        +				v0=ti[0]; l2c(v0,iv);
        +				v0=ti[1]; l2c(v0,iv);
        +				iv = &(*ivec)[0];
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0); ti[0]=v0;
        +				c2l(iv,v1); ti[1]=v1;
        +				DES_encrypt1(ti,schedule,DES_ENCRYPT);
        +				iv = &(*ivec)[0];
        +				v0=ti[0]; l2c(v0,iv);
        +				v0=ti[1]; l2c(v0,iv);
        +				iv = &(*ivec)[0];
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=c=cc=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/cfb_enc.c b/vendor/openssl/openssl/crypto/des/cfb_enc.c
        new file mode 100644
        index 000000000..720f29a28
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/cfb_enc.c
        @@ -0,0 +1,195 @@
        +/* crypto/des/cfb_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "e_os.h"
        +#include "des_locl.h"
        +#include <assert.h>
        +
        +/* The input and output are loaded in multiples of 8 bits.
        + * What this means is that if you hame numbits=12 and length=2
        + * the first 12 bits will be retrieved from the first byte and half
        + * the second.  The second 12 bits will come from the 3rd and half the 4th
        + * byte.
        + */
        +/* Until Aug 1 2003 this function did not correctly implement CFB-r, so it
        + * will not be compatible with any encryption prior to that date. Ben. */
        +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
        +		     long length, DES_key_schedule *schedule, DES_cblock *ivec,
        +		     int enc)
        +	{
        +	register DES_LONG d0,d1,v0,v1;
        +	register unsigned long l=length;
        +	register int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8;
        +	DES_LONG ti[2];
        +	unsigned char *iv;
        +#ifndef L_ENDIAN
        +	unsigned char ovec[16];
        +#else
        +	unsigned int  sh[4];
        +	unsigned char *ovec=(unsigned char *)sh;
        +
        +	/* I kind of count that compiler optimizes away this assertioni,*/
        +	assert (sizeof(sh[0])==4);	/* as this holds true for all,	*/
        +					/* but 16-bit platforms...	*/
        +					
        +#endif
        +
        +	if (numbits<=0 || numbits > 64) return;
        +	iv = &(*ivec)[0];
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	if (enc)
        +		{
        +		while (l >= (unsigned long)n)
        +			{
        +			l-=n;
        +			ti[0]=v0;
        +			ti[1]=v1;
        +			DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
        +			c2ln(in,d0,d1,n);
        +			in+=n;
        +			d0^=ti[0];
        +			d1^=ti[1];
        +			l2cn(d0,d1,out,n);
        +			out+=n;
        +			/* 30-08-94 - eay - changed because l>>32 and
        +			 * l<<32 are bad under gcc :-( */
        +			if (numbits == 32)
        +				{ v0=v1; v1=d0; }
        +			else if (numbits == 64)
        +				{ v0=d0; v1=d1; }
        +			else
        +				{
        +#ifndef L_ENDIAN
        +				iv=&ovec[0];
        +				l2c(v0,iv);
        +				l2c(v1,iv);
        +				l2c(d0,iv);
        +				l2c(d1,iv);
        +#else
        +				sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
        +#endif
        +				if (rem==0)
        +					memmove(ovec,ovec+num,8);
        +				else
        +					for(i=0 ; i < 8 ; ++i)
        +						ovec[i]=ovec[i+num]<<rem |
        +							ovec[i+num+1]>>(8-rem);
        +#ifdef L_ENDIAN
        +				v0=sh[0], v1=sh[1];
        +#else
        +				iv=&ovec[0];
        +				c2l(iv,v0);
        +				c2l(iv,v1);
        +#endif
        +				}
        +			}
        +		}
        +	else
        +		{
        +		while (l >= (unsigned long)n)
        +			{
        +			l-=n;
        +			ti[0]=v0;
        +			ti[1]=v1;
        +			DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
        +			c2ln(in,d0,d1,n);
        +			in+=n;
        +			/* 30-08-94 - eay - changed because l>>32 and
        +			 * l<<32 are bad under gcc :-( */
        +			if (numbits == 32)
        +				{ v0=v1; v1=d0; }
        +			else if (numbits == 64)
        +				{ v0=d0; v1=d1; }
        +			else
        +				{
        +#ifndef L_ENDIAN
        +				iv=&ovec[0];
        +				l2c(v0,iv);
        +				l2c(v1,iv);
        +				l2c(d0,iv);
        +				l2c(d1,iv);
        +#else
        +				sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
        +#endif
        +				if (rem==0)
        +					memmove(ovec,ovec+num,8);
        +				else
        +					for(i=0 ; i < 8 ; ++i)
        +						ovec[i]=ovec[i+num]<<rem |
        +							ovec[i+num+1]>>(8-rem);
        +#ifdef L_ENDIAN
        +				v0=sh[0], v1=sh[1];
        +#else
        +				iv=&ovec[0];
        +				c2l(iv,v0);
        +				c2l(iv,v1);
        +#endif
        +				}
        +			d0^=ti[0];
        +			d1^=ti[1];
        +			l2cn(d0,d1,out,n);
        +			out+=n;
        +			}
        +		}
        +	iv = &(*ivec)[0];
        +	l2c(v0,iv);
        +	l2c(v1,iv);
        +	v0=v1=d0=d1=ti[0]=ti[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/des-lib.com b/vendor/openssl/openssl/crypto/des/des-lib.com
        new file mode 100644
        index 000000000..348f1c047
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des-lib.com
        @@ -0,0 +1,1005 @@
        +$!
        +$!  DES-LIB.COM
        +$!  Written By:  Robert Byer
        +$!               Vice-President
        +$!               A-Com Computing, Inc.
        +$!               byer@mail.all-net.net
        +$!
        +$!  Changes by Richard Levitte <richard@levitte.org>
        +$!
        +$!  This command files compiles and creates the 
        +$!  "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" library.  The "xxx" denotes the machine 
        +$!  architecture of ALPHA, IA64 or VAX.
        +$!
        +$!  It was re-written to try to determine which "C" compiler to try to use
        +$!  or the user can specify a compiler in P3.
        +$!
        +$!  Specify one of the following to build just that part, specify "ALL" to
        +$!  just build everything.
        +$!
        +$!         ALL       To Just Build "Everything".
        +$!         LIBRARY   To Just Build The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library.
        +$!         DESTEST   To Just Build The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program.
        +$!         SPEED     To Just Build The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program.
        +$!         RPW       To Just Build The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program.
        +$!         DES       To Just Build The [.xxx.EXE.CRYPTO.DES]DES.EXE Program.
        +$!         DES_OPTS  To Just Build The [.xxx.EXE.CRYPTO.DES]DES_OPTS.EXE Program.
        +$!
        +$!  Specify either DEBUG or NODEBUG as P2 to compile with or without
        +$!  debugging information.
        +$!
        +$!  Specify which compiler at P3 to try to compile under.
        +$!
        +$!	   VAXC	 For VAX C.
        +$!	   DECC	 For DEC C.
        +$!	   GNUC	 For GNU C.
        +$!
        +$!  If you don't speficy a compiler, it will try to determine which
        +$!  "C" compiler to try to use.
        +$!
        +$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
        +$!
        +$!
        +$! Make sure we know what architecture we run on.
        +$!
        +$!
        +$! Check Which Architecture We Are Using.
        +$!
        +$ IF (F$GETSYI("CPU").LT.128)
        +$ THEN
        +$!
        +$!  The Architecture Is VAX
        +$!
        +$   ARCH := VAX
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
        +$!
        +$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
        +$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
        +$!
        +$! End The Architecture Check.
        +$!
        +$ ENDIF
        +$!
        +$! Define The OBJ Directory Name.
        +$!
        +$ OBJ_DIR := SYS$DISK:[--.'ARCH'.OBJ.CRYPTO.DES]
        +$!
        +$! Define The EXE Directory Name.
        +$!
        +$ EXE_DIR :== SYS$DISK:[--.'ARCH'.EXE.CRYPTO.DES]
        +$!
        +$! Check To Make Sure We Have Valid Command Line Parameters.
        +$!
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Tell The User What Kind of Machine We Run On.
        +$!
        +$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
        +$!
        +$! Check To See If The Architecture Specific OBJ Directory Exists.
        +$!
        +$ IF (F$PARSE(OBJ_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIR 'OBJ_DIR'
        +$!
        +$! End The Architecture Specific OBJ Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If The Architecture Specific Directory Exists.
        +$!
        +$ IF (F$PARSE(EXE_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIR 'EXE_DIR'
        +$!
        +$! End The Architecture Specific Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Define The Library Name.
        +$!
        +$ LIB_NAME := 'EXE_DIR'LIBDES.OLB
        +$!
        +$! Check To See What We Are To Do.
        +$!
        +$ IF (BUILDALL.EQS."TRUE")
        +$ THEN
        +$!
        +$!  Since Nothing Special Was Specified, Do Everything.
        +$!
        +$   GOSUB LIBRARY
        +$   GOSUB DESTEST
        +$   GOSUB SPEED
        +$   GOSUB RPW
        +$   GOSUB DES
        +$   GOSUB DES_OPTS
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!    Build Just What The User Wants Us To Build.
        +$!
        +$     GOSUB 'BUILDALL'
        +$!
        +$! End The BUILDALL Check.
        +$!
        +$ ENDIF
        +$!
        +$! Time To EXIT.
        +$!
        +$ EXIT
        +$ LIBRARY:
        +$!
        +$! Tell The User That We Are Compiling.
        +$!
        +$ WRITE SYS$OUTPUT "Compiling The ",LIB_NAME," Files."
        +$!
        +$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" Library...
        +$!
        +$ IF (F$SEARCH(LIB_NAME).EQS."")
        +$ THEN
        +$!
        +$! Guess Not, Create The Library.
        +$!
        +$   LIBRARY/CREATE/OBJECT 'LIB_NAME'
        +$!
        +$! End The Library Exist Check.
        +$!
        +$ ENDIF
        +$!
        +$! Define The DES Library Files.
        +$!
        +$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
        +		"ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
        +		"enc_read,enc_writ,ofb64enc,"+ -
        +		"ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
        +		"des_enc,fcrypt_b,read2pwd,"+ -
        +		"fcrypt,xcbc_enc,read_pwd,rpc_enc,cbc_cksm,supp"
        +$!
        +$!  Define A File Counter And Set It To "0".
        +$!
        +$ FILE_COUNTER = 0
        +$!
        +$! Top Of The File Loop.
        +$!
        +$ NEXT_FILE:
        +$!
        +$! O.K, Extract The File Name From The File List.
        +$!
        +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_DES)
        +$!
        +$! Check To See If We Are At The End Of The File List.
        +$!
        +$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
        +$!
        +$! Increment The Counter.
        +$!
        +$ FILE_COUNTER = FILE_COUNTER + 1
        +$!
        +$! Create The Source File Name.
        +$!
        +$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
        +$!
        +$!  Tell The User We Are Compiling The Source File.
        +$!
        +$ WRITE SYS$OUTPUT "	",FILE_NAME,".C"
        +$!
        +$! Create The Object File Name.
        +$!
        +$ OBJECT_FILE = OBJ_DIR + FILE_NAME + "." + ARCH + "OBJ"
        +$ ON WARNING THEN GOTO NEXT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH(SOURCE_FILE).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The File Exists Check.
        +$!
        +$ ENDIF
        +$!
        +$! Compile The File.
        +$!
        +$ ON ERROR THEN GOTO NEXT_FILE
        +$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$!
        +$! Add It To The Library.
        +$!
        +$ LIBRARY/REPLACE/OBJECT 'LIB_NAME' 'OBJECT_FILE'
        +$!
        +$! Time To Clean Up The Object File.
        +$!
        +$ DELETE 'OBJECT_FILE';*
        +$!
        +$! Go Back And Do It Again.
        +$!
        +$ GOTO NEXT_FILE
        +$!
        +$! All Done With This Library Part.
        +$!
        +$ FILE_DONE:
        +$!
        +$! Tell The User That We Are All Done.
        +$!
        +$ WRITE SYS$OUTPUT "Library ",LIB_NAME," Built."
        +$!
        +$! All Done, Time To Return.
        +$!
        +$ RETURN
        +$!
        +$!  Compile The DESTEST Program.
        +$!
        +$ DESTEST:
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH("SYS$DISK:[]DESTEST.C").EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File DESTEST.C Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The DESTEST.C File Check.
        +$!
        +$ ENDIF
        +$!
        +$! Tell The User What We Are Building.
        +$!
        +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DESTEST.EXE"
        +$!
        +$! Compile The DESTEST Program.
        +$!
        +$ CC/OBJECT='OBJ_DIR'DESTEST.OBJ SYS$DISK:[]DESTEST.C
        +$!
        +$! Link The DESTEST Program.
        +$!
        +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DESTEST.EXE -
        +      'OBJ_DIR'DESTEST.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
        +$!
        +$! All Done, Time To Return.
        +$!
        +$ RETURN
        +$!
        +$!  Compile The SPEED Program.
        +$!
        +$ SPEED:
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH("SYS$DISK:[]SPEED.C").EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File SPEED.C Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The SPEED.C File Check.
        +$!
        +$ ENDIF
        +$!
        +$! Tell The User What We Are Building.
        +$!
        +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"SPEED.EXE"
        +$!
        +$! Compile The SPEED Program.
        +$!
        +$ CC/OBJECT='OBJ_DIR'SPEED.OBJ SYS$DISK:[]SPEED.C
        +$!
        +$! Link The SPEED Program.
        +$!
        +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'SPEED.EXE -
        +      'OBJ_DIR'SPEED.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
        +$!
        +$! All Done, Time To Return.
        +$!
        +$ RETURN
        +$!
        +$!  Compile The RPW Program.
        +$!
        +$ RPW:
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH("SYS$DISK:[]RPW.C").EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File RPW.C Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The RPW.C File Check.
        +$!
        +$ ENDIF
        +$!
        +$! Tell The User What We Are Building.
        +$!
        +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"RPW.EXE"
        +$!
        +$! Compile The RPW Program.
        +$!
        +$ CC/OBJECT='OBJ_DIR'RPW.OBJ SYS$DISK:[]RPW.C
        +$!
        +$! Link The RPW Program.
        +$!
        +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'RPW.EXE -
        +      'OBJ_DIR'RPW.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
        +$!
        +$! All Done, Time To Return.
        +$!
        +$ RETURN
        +$!
        +$!  Compile The DES Program.
        +$!
        +$ DES:
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH("SYS$DISK:[]DES.C").EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File DES.C Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The DES.C File Check.
        +$!
        +$ ENDIF
        +$!
        +$! Tell The User What We Are Building.
        +$!
        +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES.EXE"
        +$!
        +$! Compile The DES Program.
        +$!
        +$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]DES.C
        +$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]CBC3_ENC.C
        +$!
        +$! Link The DES Program.
        +$!
        +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES.EXE -
        +      'OBJ_DIR'DES.OBJ,'OBJ_DIR'CBC3_ENC.OBJ,-
        +      'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
        +$!
        +$! All Done, Time To Return.
        +$!
        +$ RETURN
        +$!
        +$!  Compile The DES_OPTS Program.
        +$!
        +$ DES_OPTS:
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH("SYS$DISK:[]DES_OPTS.C").EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File DES_OPTS.C Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The DES_OPTS.C File Check.
        +$!
        +$ ENDIF
        +$!
        +$! Tell The User What We Are Building.
        +$!
        +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES_OPTS.EXE"
        +$!
        +$! Compile The DES_OPTS Program.
        +$!
        +$ CC/OBJECT='OBJ_DIR'DES_OPTS.OBJ SYS$DISK:[]DES_OPTS.C
        +$!
        +$! Link The DES_OPTS Program.
        +$!
        +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES_OPTS.EXE -
        +      'OBJ_DIR'DES_OPTS.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
        +$!
        +$! All Done, Time To Return.
        +$!
        +$ RETURN
        +$ EXIT
        +$!
        +$! Check For The Link Option FIle.
        +$!
        +$ CHECK_OPT_FILE:
        +$!
        +$! Check To See If We Need To Make A VAX C Option File.
        +$!
        +$ IF (COMPILER.EQS."VAXC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A VAX C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A VAX C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Agianst 
        +! The Sharable VAX C Runtime Library.
        +!
        +SYS$SHARE:VAXCRTL.EXE/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The VAXC Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A GNU C Option File.
        +$!
        +$ IF (COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A GNU C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A GNU C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Agianst 
        +! The Sharable C Runtime Library.
        +!
        +GNU_CC:[000000]GCCLIB/LIBRARY
        +SYS$SHARE:VAXCRTL/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The GNU C Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A DEC C Option File.
        +$!
        +$ IF (COMPILER.EQS."DECC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A DEC C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Figure Out If We Need An non-VAX Or A VAX Linker Option File.
        +$!
        +$     IF (F$GETSYI("CPU").LT.128)
        +$     THEN
        +$!
        +$!      We Need A DEC C Linker Option File For VAX.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Agianst 
        +! The Sharable DEC C Runtime Library.
        +!
        +SYS$SHARE:DECC$SHR.EXE/SHARE
        +$EOD
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Create The non-VAX Linker Option File.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File For non-VAX To Link Agianst 
        +! The Sharable C Runtime Library.
        +!
        +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
        +SYS$SHARE:CMA$OPEN_RTL/SHARE
        +$EOD
        +$!
        +$!    End The DEC C Option File Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The Option File Search.
        +$!
        +$   ENDIF
        +$!
        +$! End The DEC C Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What Linker Option File We Are Using.
        +$!
        +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Library Check.
        +$!
        +$ LIB_CHECK:
        +$!
        +$!  Look For The Library LIBDES.OLB.
        +$!
        +$ IF (F$SEARCH(LIB_NAME).EQS."")
        +$ THEN
        +$!
        +$!    Tell The User We Can't Find The [.xxx.CRYPTO.DES]LIBDES.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",LIB_NAME,"."
        +$   WRITE SYS$OUTPUT "We Can't Link Without It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!    Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$ ENDIF
        +$!
        +$! Time To Return.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Check To See If We Are To "Just Build Everything".
        +$!
        +$ IF (P1.EQS."ALL")
        +$ THEN
        +$!
        +$!   P1 Is "ALL", So Build Everything.
        +$!
        +$    BUILDALL = "TRUE"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Else, Check To See If P1 Has A Valid Argument.
        +$!
        +$   IF (P1.EQS."LIBRARY").OR.(P1.EQS."DESTEST").OR.(P1.EQS."SPEED") -
        +       .OR.(P1.EQS."RPW").OR.(P1.EQS."DES").OR.(P1.EQS."DES_OPTS")
        +$   THEN
        +$!
        +$!    A Valid Argument.
        +$!
        +$     BUILDALL = P1
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
        +$     WRITE SYS$OUTPUT "    LIBRARY  :  To Compile Just The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library."
        +$     WRITE SYS$OUTPUT "    DESTEST  :  To Compile Just The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program."
        +$     WRITE SYS$OUTPUT "    SPEED    :  To Compile Just The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program."
        +$     WRITE SYS$OUTPUT "    RPW      :  To Compile Just The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program."
        +$     WRITE SYS$OUTPUT "    DES      :  To Compile Just The [.xxx.EXE.CRYPTO.DES]DES.EXE Program."
        +$     WRITE SYS$OUTPUT "    DES_OPTS :  To Compile Just The [.xxx.EXE.CRYTPO.DES]DES_OPTS.EXE Program."
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT " Where 'xxx' Stands For: "
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALPHA    :  Alpha Architecture."
        +$     WRITE SYS$OUTPUT "    IA64     :  IA64 Architecture."
        +$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P1 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Are To Compile Without Debugger Information.
        +$!
        +$ IF (P2.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!   P2 Is Blank, So Compile Without Debugger Information.
        +$!
        +$    DEBUGGER  = "NODEBUG"
        +$    TRACEBACK = "NOTRACEBACK" 
        +$    GCC_OPTIMIZE = "OPTIMIZE"
        +$    CC_OPTIMIZE = "OPTIMIZE"
        +$    WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
        +$    WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (P2.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER  = "DEBUG"
        +$     TRACEBACK = "TRACEBACK"
        +$     GCC_OPTIMIZE = "NOOPTIMIZE"
        +$     CC_OPTIMIZE = "NOOPTIMIZE"
        +$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
        +$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User Entered An Invalid Option..
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P2 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later.
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For P4.
        +$!
        +$ IF (P4.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN := ""
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P4 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If P3 Is Blank.
        +$!
        +$ IF (P3.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     P3 = "GNUC"
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Check To See If We Have VAXC Or DECC.
        +$!
        +$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
        +$     THEN 
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       P3 = "DECC"
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       P3 = "VAXC"
        +$!
        +$!    End The VAXC Compiler Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  End The Compiler Check.
        +$!
        +$ ENDIF
        +$!
        +$! Set Up Initial CC Definitions, Possibly With User Ones
        +$!
        +$ CCDEFS = ""
        +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = USER_CCDEFS
        +$ CCEXTRAFLAGS = ""
        +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
        +$ CCDISABLEWARNINGS = ""
        +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
        +	CCDISABLEWARNINGS = USER_CCDISABLEWARNINGS
        +$!
        +$!  Check To See If The User Entered A Valid Paramter.
        +$!
        +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
        +$ THEN
        +$!
        +$!    Check To See If The User Wanted DECC.
        +$!
        +$   IF (P3.EQS."DECC")
        +$   THEN
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    Use DECC...
        +$!
        +$     CC = "CC"
        +$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
        +	 THEN CC = "CC/DECC"
        +$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
        +           "/NOLIST/PREFIX=ALL" + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
        +$!
        +$!  End DECC Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use VAXC.
        +$!
        +$   IF (P3.EQS."VAXC")
        +$   THEN
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$!
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    Compile Using VAXC.
        +$!
        +$     CC = "CC"
        +$     IF ARCH.NES."VAX"
        +$     THEN
        +$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
        +$	EXIT
        +$     ENDIF
        +$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
        +$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS
        +$     CCDEFS = """VAXC""," + CCDEFS
        +$!
        +$!    Define <sys> As SYS$COMMON:[SYSLIB]
        +$!
        +$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
        +$!
        +$!  End VAXC Check
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use GNU C.
        +$!
        +$   IF (P3.EQS."GNUC")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    Use GNU C...
        +$!
        +$     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
        +$!
        +$!  End The GNU C Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Set up default defines
        +$!
        +$   CCDEFS = """FLAT_INC=1""," + CCDEFS
        +$!
        +$!  Finish up the definition of CC.
        +$!
        +$   IF COMPILER .EQS. "DECC"
        +$   THEN
        +$     IF CCDISABLEWARNINGS .EQS. ""
        +$     THEN
        +$       CC4DISABLEWARNINGS = "DOLLARID"
        +$     ELSE
        +$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
        +$       CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
        +$     ENDIF
        +$     CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
        +$   ELSE
        +$     CCDISABLEWARNINGS = ""
        +$     CC4DISABLEWARNINGS = ""
        +$   ENDIF
        +$   CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
        +$!
        +$!  Show user the result
        +$!
        +$   WRITE SYS$OUTPUT "Main Compiling Command: ",CC
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$! End The P3 Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        diff --git a/vendor/openssl/openssl/crypto/des/des.c b/vendor/openssl/openssl/crypto/des/des.c
        new file mode 100644
        index 000000000..343135ff9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des.c
        @@ -0,0 +1,932 @@
        +/* crypto/des/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.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_SYS_MSDOS
        +#ifndef OPENSSL_SYS_VMS
        +#include OPENSSL_UNISTD
        +#else /* OPENSSL_SYS_VMS */
        +#ifdef __DECC
        +#include <unistd.h>
        +#else /* not __DECC */
        +#include <math.h>
        +#endif /* __DECC */
        +#endif /* OPENSSL_SYS_VMS */
        +#else /* OPENSSL_SYS_MSDOS */
        +#include <io.h>
        +#endif
        +
        +#include <time.h>
        +#include "des_ver.h"
        +
        +#ifdef OPENSSL_SYS_VMS
        +#include <types.h>
        +#include <stat.h>
        +#else
        +#ifndef _IRIX
        +#include <sys/types.h>
        +#endif
        +#include <sys/stat.h>
        +#endif
        +#include <openssl/des.h>
        +#include <openssl/rand.h>
        +#include <openssl/ui_compat.h>
        +
        +void usage(void);
        +void doencryption(void);
        +int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
        +void uufwriteEnd(FILE *fp);
        +int uufread(unsigned char *out,int size,unsigned int num,FILE *fp);
        +int uuencode(unsigned char *in,int num,unsigned char *out);
        +int uudecode(unsigned char *in,int num,unsigned char *out);
        +void DES_3cbc_encrypt(DES_cblock *input,DES_cblock *output,long length,
        +	DES_key_schedule sk1,DES_key_schedule sk2,
        +	DES_cblock *ivec1,DES_cblock *ivec2,int enc);
        +#ifdef OPENSSL_SYS_VMS
        +#define EXIT(a) exit(a&0x10000000L)
        +#else
        +#define EXIT(a) exit(a)
        +#endif
        +
        +#define BUFSIZE (8*1024)
        +#define VERIFY  1
        +#define KEYSIZ	8
        +#define KEYSIZB 1024 /* should hit tty line limit first :-) */
        +char key[KEYSIZB+1];
        +int do_encrypt,longk=0;
        +FILE *DES_IN,*DES_OUT,*CKSUM_OUT;
        +char uuname[200];
        +unsigned char uubuf[50];
        +int uubufnum=0;
        +#define INUUBUFN	(45*100)
        +#define OUTUUBUF	(65*100)
        +unsigned char b[OUTUUBUF];
        +unsigned char bb[300];
        +DES_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        +char cksumname[200]="";
        +
        +int vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;
        +
        +int main(int argc, char **argv)
        +	{
        +	int i;
        +	struct stat ins,outs;
        +	char *p;
        +	char *in=NULL,*out=NULL;
        +
        +	vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0;
        +	error=0;
        +	memset(key,0,sizeof(key));
        +
        +	for (i=1; i<argc; i++)
        +		{
        +		p=argv[i];
        +		if ((p[0] == '-') && (p[1] != '\0'))
        +			{
        +			p++;
        +			while (*p)
        +				{
        +				switch (*(p++))
        +					{
        +				case '3':
        +					flag3=1;
        +					longk=1;
        +					break;
        +				case 'c':
        +					cflag=1;
        +					strncpy(cksumname,p,200);
        +					cksumname[sizeof(cksumname)-1]='\0';
        +					p+=strlen(cksumname);
        +					break;
        +				case 'C':
        +					cflag=1;
        +					longk=1;
        +					strncpy(cksumname,p,200);
        +					cksumname[sizeof(cksumname)-1]='\0';
        +					p+=strlen(cksumname);
        +					break;
        +				case 'e':
        +					eflag=1;
        +					break;
        +				case 'v':
        +					vflag=1;
        +					break;
        +				case 'E':
        +					eflag=1;
        +					longk=1;
        +					break;
        +				case 'd':
        +					dflag=1;
        +					break;
        +				case 'D':
        +					dflag=1;
        +					longk=1;
        +					break;
        +				case 'b':
        +					bflag=1;
        +					break;
        +				case 'f':
        +					fflag=1;
        +					break;
        +				case 's':
        +					sflag=1;
        +					break;
        +				case 'u':
        +					uflag=1;
        +					strncpy(uuname,p,200);
        +					uuname[sizeof(uuname)-1]='\0';
        +					p+=strlen(uuname);
        +					break;
        +				case 'h':
        +					hflag=1;
        +					break;
        +				case 'k':
        +					kflag=1;
        +					if ((i+1) == argc)
        +						{
        +						fputs("must have a key with the -k option\n",stderr);
        +						error=1;
        +						}
        +					else
        +						{
        +						int j;
        +
        +						i++;
        +						strncpy(key,argv[i],KEYSIZB);
        +						for (j=strlen(argv[i])-1; j>=0; j--)
        +							argv[i][j]='\0';
        +						}
        +					break;
        +				default:
        +					fprintf(stderr,"'%c' unknown flag\n",p[-1]);
        +					error=1;
        +					break;
        +					}
        +				}
        +			}
        +		else
        +			{
        +			if (in == NULL)
        +				in=argv[i];
        +			else if (out == NULL)
        +				out=argv[i];
        +			else
        +				error=1;
        +			}
        +		}
        +	if (error) usage();
        +	/* We either
        +	 * do checksum or
        +	 * do encrypt or
        +	 * do decrypt or
        +	 * do decrypt then ckecksum or
        +	 * do checksum then encrypt
        +	 */
        +	if (((eflag+dflag) == 1) || cflag)
        +		{
        +		if (eflag) do_encrypt=DES_ENCRYPT;
        +		if (dflag) do_encrypt=DES_DECRYPT;
        +		}
        +	else
        +		{
        +		if (vflag) 
        +			{
        +#ifndef _Windows			
        +			fprintf(stderr,"des(1) built with %s\n",libdes_version);
        +#endif			
        +			EXIT(1);
        +			}
        +		else usage();
        +		}
        +
        +#ifndef _Windows			
        +	if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version);
        +#endif			
        +	if (	(in != NULL) &&
        +		(out != NULL) &&
        +#ifndef OPENSSL_SYS_MSDOS
        +		(stat(in,&ins) != -1) &&
        +		(stat(out,&outs) != -1) &&
        +		(ins.st_dev == outs.st_dev) &&
        +		(ins.st_ino == outs.st_ino))
        +#else /* OPENSSL_SYS_MSDOS */
        +		(strcmp(in,out) == 0))
        +#endif
        +			{
        +			fputs("input and output file are the same\n",stderr);
        +			EXIT(3);
        +			}
        +
        +	if (!kflag)
        +		if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0))
        +			{
        +			fputs("password error\n",stderr);
        +			EXIT(2);
        +			}
        +
        +	if (in == NULL)
        +		DES_IN=stdin;
        +	else if ((DES_IN=fopen(in,"r")) == NULL)
        +		{
        +		perror("opening input file");
        +		EXIT(4);
        +		}
        +
        +	CKSUM_OUT=stdout;
        +	if (out == NULL)
        +		{
        +		DES_OUT=stdout;
        +		CKSUM_OUT=stderr;
        +		}
        +	else if ((DES_OUT=fopen(out,"w")) == NULL)
        +		{
        +		perror("opening output file");
        +		EXIT(5);
        +		}
        +
        +#ifdef OPENSSL_SYS_MSDOS
        +	/* This should set the file to binary mode. */
        +	{
        +#include <fcntl.h>
        +	if (!(uflag && dflag))
        +		setmode(fileno(DES_IN),O_BINARY);
        +	if (!(uflag && eflag))
        +		setmode(fileno(DES_OUT),O_BINARY);
        +	}
        +#endif
        +
        +	doencryption();
        +	fclose(DES_IN);
        +	fclose(DES_OUT);
        +	EXIT(0);
        +	}
        +
        +void usage(void)
        +	{
        +	char **u;
        +	static const char *Usage[]={
        +"des <options> [input-file [output-file]]",
        +"options:",
        +"-v         : des(1) version number",
        +"-e         : encrypt using SunOS compatible user key to DES key conversion.",
        +"-E         : encrypt ",
        +"-d         : decrypt using SunOS compatible user key to DES key conversion.",
        +"-D         : decrypt ",
        +"-c[ckname] : generate a cbc_cksum using SunOS compatible user key to",
        +"             DES key conversion and output to ckname (stdout default,",
        +"             stderr if data being output on stdout).  The checksum is",
        +"             generated before encryption and after decryption if used",
        +"             in conjunction with -[eEdD].",
        +"-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
        +"-k key     : use key 'key'",
        +"-h         : the key that is entered will be a hexadecimal number",
        +"             that is used directly as the des key",
        +"-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
        +"             (uuname is the filename to put in the uuencode header).",
        +"-b         : encrypt using DES in ecb encryption mode, the default is cbc mode.",
        +"-3         : encrypt using triple DES encryption.  This uses 2 keys",
        +"             generated from the input key.  If the input key is less",
        +"             than 8 characters long, this is equivalent to normal",
        +"             encryption.  Default is triple cbc, -b makes it triple ecb.",
        +NULL
        +};
        +	for (u=(char **)Usage; *u; u++)
        +		{
        +		fputs(*u,stderr);
        +		fputc('\n',stderr);
        +		}
        +
        +	EXIT(1);
        +	}
        +
        +void doencryption(void)
        +	{
        +#ifdef _LIBC
        +	extern unsigned long time();
        +#endif
        +
        +	register int i;
        +	DES_key_schedule ks,ks2;
        +	DES_cblock iv,iv2;
        +	char *p;
        +	int num=0,j,k,l,rem,ll,len,last,ex=0;
        +	DES_cblock kk,k2;
        +	FILE *O;
        +	int Exit=0;
        +#ifndef OPENSSL_SYS_MSDOS
        +	static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8];
        +#else
        +	static unsigned char *buf=NULL,*obuf=NULL;
        +
        +	if (buf == NULL)
        +		{
        +		if (    (( buf=OPENSSL_malloc(BUFSIZE+8)) == NULL) ||
        +			((obuf=OPENSSL_malloc(BUFSIZE+8)) == NULL))
        +			{
        +			fputs("Not enough memory\n",stderr);
        +			Exit=10;
        +			goto problems;
        +			}
        +		}
        +#endif
        +
        +	if (hflag)
        +		{
        +		j=(flag3?16:8);
        +		p=key;
        +		for (i=0; i<j; i++)
        +			{
        +			k=0;
        +			if ((*p <= '9') && (*p >= '0'))
        +				k=(*p-'0')<<4;
        +			else if ((*p <= 'f') && (*p >= 'a'))
        +				k=(*p-'a'+10)<<4;
        +			else if ((*p <= 'F') && (*p >= 'A'))
        +				k=(*p-'A'+10)<<4;
        +			else
        +				{
        +				fputs("Bad hex key\n",stderr);
        +				Exit=9;
        +				goto problems;
        +				}
        +			p++;
        +			if ((*p <= '9') && (*p >= '0'))
        +				k|=(*p-'0');
        +			else if ((*p <= 'f') && (*p >= 'a'))
        +				k|=(*p-'a'+10);
        +			else if ((*p <= 'F') && (*p >= 'A'))
        +				k|=(*p-'A'+10);
        +			else
        +				{
        +				fputs("Bad hex key\n",stderr);
        +				Exit=9;
        +				goto problems;
        +				}
        +			p++;
        +			if (i < 8)
        +				kk[i]=k;
        +			else
        +				k2[i-8]=k;
        +			}
        +		DES_set_key_unchecked(&k2,&ks2);
        +		OPENSSL_cleanse(k2,sizeof(k2));
        +		}
        +	else if (longk || flag3)
        +		{
        +		if (flag3)
        +			{
        +			DES_string_to_2keys(key,&kk,&k2);
        +			DES_set_key_unchecked(&k2,&ks2);
        +			OPENSSL_cleanse(k2,sizeof(k2));
        +			}
        +		else
        +			DES_string_to_key(key,&kk);
        +		}
        +	else
        +		for (i=0; i<KEYSIZ; i++)
        +			{
        +			l=0;
        +			k=key[i];
        +			for (j=0; j<8; j++)
        +				{
        +				if (k&1) l++;
        +				k>>=1;
        +				}
        +			if (l & 1)
        +				kk[i]=key[i]&0x7f;
        +			else
        +				kk[i]=key[i]|0x80;
        +			}
        +
        +	DES_set_key_unchecked(&kk,&ks);
        +	OPENSSL_cleanse(key,sizeof(key));
        +	OPENSSL_cleanse(kk,sizeof(kk));
        +	/* woops - A bug that does not showup under unix :-( */
        +	memset(iv,0,sizeof(iv));
        +	memset(iv2,0,sizeof(iv2));
        +
        +	l=1;
        +	rem=0;
        +	/* first read */
        +	if (eflag || (!dflag && cflag))
        +		{
        +		for (;;)
        +			{
        +			num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
        +			l+=rem;
        +			num+=rem;
        +			if (l < 0)
        +				{
        +				perror("read error");
        +				Exit=6;
        +				goto problems;
        +				}
        +
        +			rem=l%8;
        +			len=l-rem;
        +			if (feof(DES_IN))
        +				{
        +				for (i=7-rem; i>0; i--)
        +					RAND_pseudo_bytes(buf + l++, 1);
        +				buf[l++]=rem;
        +				ex=1;
        +				len+=rem;
        +				}
        +			else
        +				l-=rem;
        +
        +			if (cflag)
        +				{
        +				DES_cbc_cksum(buf,&cksum,
        +					(long)len,&ks,&cksum);
        +				if (!eflag)
        +					{
        +					if (feof(DES_IN)) break;
        +					else continue;
        +					}
        +				}
        +
        +			if (bflag && !flag3)
        +				for (i=0; i<l; i+=8)
        +					DES_ecb_encrypt(
        +						(DES_cblock *)&(buf[i]),
        +						(DES_cblock *)&(obuf[i]),
        +						&ks,do_encrypt);
        +			else if (flag3 && bflag)
        +				for (i=0; i<l; i+=8)
        +					DES_ecb2_encrypt(
        +						(DES_cblock *)&(buf[i]),
        +						(DES_cblock *)&(obuf[i]),
        +						&ks,&ks2,do_encrypt);
        +			else if (flag3 && !bflag)
        +				{
        +				char tmpbuf[8];
        +
        +				if (rem) memcpy(tmpbuf,&(buf[l]),
        +					(unsigned int)rem);
        +				DES_3cbc_encrypt(
        +					(DES_cblock *)buf,(DES_cblock *)obuf,
        +					(long)l,ks,ks2,&iv,
        +					&iv2,do_encrypt);
        +				if (rem) memcpy(&(buf[l]),tmpbuf,
        +					(unsigned int)rem);
        +				}
        +			else
        +				{
        +				DES_cbc_encrypt(
        +					buf,obuf,
        +					(long)l,&ks,&iv,do_encrypt);
        +				if (l >= 8) memcpy(iv,&(obuf[l-8]),8);
        +				}
        +			if (rem) memcpy(buf,&(buf[l]),(unsigned int)rem);
        +
        +			i=0;
        +			while (i < l)
        +				{
        +				if (uflag)
        +					j=uufwrite(obuf,1,(unsigned int)l-i,
        +						DES_OUT);
        +				else
        +					j=fwrite(obuf,1,(unsigned int)l-i,
        +						DES_OUT);
        +				if (j == -1)
        +					{
        +					perror("Write error");
        +					Exit=7;
        +					goto problems;
        +					}
        +				i+=j;
        +				}
        +			if (feof(DES_IN))
        +				{
        +				if (uflag) uufwriteEnd(DES_OUT);
        +				break;
        +				}
        +			}
        +		}
        +	else /* decrypt */
        +		{
        +		ex=1;
        +		for (;;)
        +			{
        +			if (ex) {
        +				if (uflag)
        +					l=uufread(buf,1,BUFSIZE,DES_IN);
        +				else
        +					l=fread(buf,1,BUFSIZE,DES_IN);
        +				ex=0;
        +				rem=l%8;
        +				l-=rem;
        +				}
        +			if (l < 0)
        +				{
        +				perror("read error");
        +				Exit=6;
        +				goto problems;
        +				}
        +
        +			if (bflag && !flag3)
        +				for (i=0; i<l; i+=8)
        +					DES_ecb_encrypt(
        +						(DES_cblock *)&(buf[i]),
        +						(DES_cblock *)&(obuf[i]),
        +						&ks,do_encrypt);
        +			else if (flag3 && bflag)
        +				for (i=0; i<l; i+=8)
        +					DES_ecb2_encrypt(
        +						(DES_cblock *)&(buf[i]),
        +						(DES_cblock *)&(obuf[i]),
        +						&ks,&ks2,do_encrypt);
        +			else if (flag3 && !bflag)
        +				{
        +				DES_3cbc_encrypt(
        +					(DES_cblock *)buf,(DES_cblock *)obuf,
        +					(long)l,ks,ks2,&iv,
        +					&iv2,do_encrypt);
        +				}
        +			else
        +				{
        +				DES_cbc_encrypt(
        +					buf,obuf,
        +				 	(long)l,&ks,&iv,do_encrypt);
        +				if (l >= 8) memcpy(iv,&(buf[l-8]),8);
        +				}
        +
        +			if (uflag)
        +				ll=uufread(&(buf[rem]),1,BUFSIZE,DES_IN);
        +			else
        +				ll=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
        +			ll+=rem;
        +			rem=ll%8;
        +			ll-=rem;
        +			if (feof(DES_IN) && (ll == 0))
        +				{
        +				last=obuf[l-1];
        +
        +				if ((last > 7) || (last < 0))
        +					{
        +					fputs("The file was not decrypted correctly.\n",
        +						stderr);
        +					Exit=8;
        +					last=0;
        +					}
        +				l=l-8+last;
        +				}
        +			i=0;
        +			if (cflag) DES_cbc_cksum(obuf,
        +				(DES_cblock *)cksum,(long)l/8*8,&ks,
        +				(DES_cblock *)cksum);
        +			while (i != l)
        +				{
        +				j=fwrite(obuf,1,(unsigned int)l-i,DES_OUT);
        +				if (j == -1)
        +					{
        +					perror("Write error");
        +					Exit=7;
        +					goto problems;
        +					}
        +				i+=j;
        +				}
        +			l=ll;
        +			if ((l == 0) && feof(DES_IN)) break;
        +			}
        +		}
        +	if (cflag)
        +		{
        +		l=0;
        +		if (cksumname[0] != '\0')
        +			{
        +			if ((O=fopen(cksumname,"w")) != NULL)
        +				{
        +				CKSUM_OUT=O;
        +				l=1;
        +				}
        +			}
        +		for (i=0; i<8; i++)
        +			fprintf(CKSUM_OUT,"%02X",cksum[i]);
        +		fprintf(CKSUM_OUT,"\n");
        +		if (l) fclose(CKSUM_OUT);
        +		}
        +problems:
        +	OPENSSL_cleanse(buf,sizeof(buf));
        +	OPENSSL_cleanse(obuf,sizeof(obuf));
        +	OPENSSL_cleanse(&ks,sizeof(ks));
        +	OPENSSL_cleanse(&ks2,sizeof(ks2));
        +	OPENSSL_cleanse(iv,sizeof(iv));
        +	OPENSSL_cleanse(iv2,sizeof(iv2));
        +	OPENSSL_cleanse(kk,sizeof(kk));
        +	OPENSSL_cleanse(k2,sizeof(k2));
        +	OPENSSL_cleanse(uubuf,sizeof(uubuf));
        +	OPENSSL_cleanse(b,sizeof(b));
        +	OPENSSL_cleanse(bb,sizeof(bb));
        +	OPENSSL_cleanse(cksum,sizeof(cksum));
        +	if (Exit) EXIT(Exit);
        +	}
        +
        +/*    We ignore this parameter but it should be > ~50 I believe    */
        +int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
        +	{
        +	int i,j,left,rem,ret=num;
        +	static int start=1;
        +
        +	if (start)
        +		{
        +		fprintf(fp,"begin 600 %s\n",
        +			(uuname[0] == '\0')?"text.d":uuname);
        +		start=0;
        +		}
        +
        +	if (uubufnum)
        +		{
        +		if (uubufnum+num < 45)
        +			{
        +			memcpy(&(uubuf[uubufnum]),data,(unsigned int)num);
        +			uubufnum+=num;
        +			return(num);
        +			}
        +		else
        +			{
        +			i=45-uubufnum;
        +			memcpy(&(uubuf[uubufnum]),data,(unsigned int)i);
        +			j=uuencode((unsigned char *)uubuf,45,b);
        +			fwrite(b,1,(unsigned int)j,fp);
        +			uubufnum=0;
        +			data+=i;
        +			num-=i;
        +			}
        +		}
        +
        +	for (i=0; i<(((int)num)-INUUBUFN); i+=INUUBUFN)
        +		{
        +		j=uuencode(&(data[i]),INUUBUFN,b);
        +		fwrite(b,1,(unsigned int)j,fp);
        +		}
        +	rem=(num-i)%45;
        +	left=(num-i-rem);
        +	if (left)
        +		{
        +		j=uuencode(&(data[i]),left,b);
        +		fwrite(b,1,(unsigned int)j,fp);
        +		i+=left;
        +		}
        +	if (i != num)
        +		{
        +		memcpy(uubuf,&(data[i]),(unsigned int)rem);
        +		uubufnum=rem;
        +		}
        +	return(ret);
        +	}
        +
        +void uufwriteEnd(FILE *fp)
        +	{
        +	int j;
        +	static const char *end=" \nend\n";
        +
        +	if (uubufnum != 0)
        +		{
        +		uubuf[uubufnum]='\0';
        +		uubuf[uubufnum+1]='\0';
        +		uubuf[uubufnum+2]='\0';
        +		j=uuencode(uubuf,uubufnum,b);
        +		fwrite(b,1,(unsigned int)j,fp);
        +		}
        +	fwrite(end,1,strlen(end),fp);
        +	}
        +
        +/* int size:  should always be > ~ 60; I actually ignore this parameter :-)    */
        +int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
        +	{
        +	int i,j,tot;
        +	static int done=0;
        +	static int valid=0;
        +	static int start=1;
        +
        +	if (start)
        +		{
        +		for (;;)
        +			{
        +			b[0]='\0';
        +			fgets((char *)b,300,fp);
        +			if (b[0] == '\0')
        +				{
        +				fprintf(stderr,"no 'begin' found in uuencoded input\n");
        +				return(-1);
        +				}
        +			if (strncmp((char *)b,"begin ",6) == 0) break;
        +			}
        +		start=0;
        +		}
        +	if (done) return(0);
        +	tot=0;
        +	if (valid)
        +		{
        +		memcpy(out,bb,(unsigned int)valid);
        +		tot=valid;
        +		valid=0;
        +		}
        +	for (;;)
        +		{
        +		b[0]='\0';
        +		fgets((char *)b,300,fp);
        +		if (b[0] == '\0') break;
        +		i=strlen((char *)b);
        +		if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd'))
        +			{
        +			done=1;
        +			while (!feof(fp))
        +				{
        +				fgets((char *)b,300,fp);
        +				}
        +			break;
        +			}
        +		i=uudecode(b,i,bb);
        +		if (i < 0) break;
        +		if ((i+tot+8) > num)
        +			{
        +			/* num to copy to make it a multiple of 8 */
        +			j=(num/8*8)-tot-8;
        +			memcpy(&(out[tot]),bb,(unsigned int)j);
        +			tot+=j;
        +			memcpy(bb,&(bb[j]),(unsigned int)i-j);
        +			valid=i-j;
        +			break;
        +			}
        +		memcpy(&(out[tot]),bb,(unsigned int)i);
        +		tot+=i;
        +		}
        +	return(tot);
        +	}
        +
        +#define ccc2l(c,l)      (l =((DES_LONG)(*((c)++)))<<16, \
        +			 l|=((DES_LONG)(*((c)++)))<< 8, \
        +		 	 l|=((DES_LONG)(*((c)++))))
        +
        +#define l2ccc(l,c)      (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
        +                    *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
        +                    *((c)++)=(unsigned char)(((l)    )&0xff))
        +
        +
        +int uuencode(unsigned char *in, int num, unsigned char *out)
        +	{
        +	int j,i,n,tot=0;
        +	DES_LONG l;
        +	register unsigned char *p;
        +	p=out;
        +
        +	for (j=0; j<num; j+=45)
        +		{
        +		if (j+45 > num)
        +			i=(num-j);
        +		else	i=45;
        +		*(p++)=i+' ';
        +		for (n=0; n<i; n+=3)
        +			{
        +			ccc2l(in,l);
        +			*(p++)=((l>>18)&0x3f)+' ';
        +			*(p++)=((l>>12)&0x3f)+' ';
        +			*(p++)=((l>> 6)&0x3f)+' ';
        +			*(p++)=((l    )&0x3f)+' ';
        +			tot+=4;
        +			}
        +		*(p++)='\n';
        +		tot+=2;
        +		}
        +	*p='\0';
        +	l=0;
        +	return(tot);
        +	}
        +
        +int uudecode(unsigned char *in, int num, unsigned char *out)
        +	{
        +	int j,i,k;
        +	unsigned int n=0,space=0;
        +	DES_LONG l;
        +	DES_LONG w,x,y,z;
        +	unsigned int blank=(unsigned int)'\n'-' ';
        +
        +	for (j=0; j<num; )
        +		{
        +		n= *(in++)-' ';
        +		if (n == blank)
        +			{
        +			n=0;
        +			in--;
        +			}
        +		if (n > 60)
        +			{
        +			fprintf(stderr,"uuencoded line length too long\n");
        +			return(-1);
        +			}
        +		j++;
        +
        +		for (i=0; i<n; j+=4,i+=3)
        +			{
        +			/* the following is for cases where spaces are
        +			 * removed from lines.
        +			 */
        +			if (space)
        +				{
        +				w=x=y=z=0;
        +				}
        +			else
        +				{
        +				w= *(in++)-' ';
        +				x= *(in++)-' ';
        +				y= *(in++)-' ';
        +				z= *(in++)-' ';
        +				}
        +			if ((w > 63) || (x > 63) || (y > 63) || (z > 63))
        +				{
        +				k=0;
        +				if (w == blank) k=1;
        +				if (x == blank) k=2;
        +				if (y == blank) k=3;
        +				if (z == blank) k=4;
        +				space=1;
        +				switch (k) {
        +				case 1:	w=0; in--;
        +				case 2: x=0; in--;
        +				case 3: y=0; in--;
        +				case 4: z=0; in--;
        +					break;
        +				case 0:
        +					space=0;
        +					fprintf(stderr,"bad uuencoded data values\n");
        +					w=x=y=z=0;
        +					return(-1);
        +					break;
        +					}
        +				}
        +			l=(w<<18)|(x<<12)|(y<< 6)|(z    );
        +			l2ccc(l,out);
        +			}
        +		if (*(in++) != '\n')
        +			{
        +			fprintf(stderr,"missing nl in uuencoded line\n");
        +			w=x=y=z=0;
        +			return(-1);
        +			}
        +		j++;
        +		}
        +	*out='\0';
        +	w=x=y=z=0;
        +	return(n);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/des.h b/vendor/openssl/openssl/crypto/des/des.h
        new file mode 100644
        index 000000000..1eaedcbd2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des.h
        @@ -0,0 +1,248 @@
        +/* crypto/des/des.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_NEW_DES_H
        +#define HEADER_NEW_DES_H
        +
        +#include <openssl/e_os2.h>	/* OPENSSL_EXTERN, OPENSSL_NO_DES,
        +				   DES_LONG (via openssl/opensslconf.h */
        +
        +#ifdef OPENSSL_NO_DES
        +#error DES is disabled.
        +#endif
        +
        +#ifdef OPENSSL_BUILD_SHLIBCRYPTO
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef unsigned char DES_cblock[8];
        +typedef /* const */ unsigned char const_DES_cblock[8];
        +/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock *
        + * and const_DES_cblock * are incompatible pointer types. */
        +
        +typedef struct DES_ks
        +    {
        +    union
        +	{
        +	DES_cblock cblock;
        +	/* make sure things are correct size on machines with
        +	 * 8 byte longs */
        +	DES_LONG deslong[2];
        +	} ks[16];
        +    } DES_key_schedule;
        +
        +#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
        +# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
        +#  define OPENSSL_ENABLE_OLD_DES_SUPPORT
        +# endif
        +#endif
        +
        +#ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
        +# include <openssl/des_old.h>
        +#endif
        +
        +#define DES_KEY_SZ 	(sizeof(DES_cblock))
        +#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
        +
        +#define DES_ENCRYPT	1
        +#define DES_DECRYPT	0
        +
        +#define DES_CBC_MODE	0
        +#define DES_PCBC_MODE	1
        +
        +#define DES_ecb2_encrypt(i,o,k1,k2,e) \
        +	DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
        +
        +#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        +	DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
        +
        +#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        +	DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
        +
        +#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        +	DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
        +
        +OPENSSL_DECLARE_GLOBAL(int,DES_check_key);	/* defaults to false */
        +#define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
        +OPENSSL_DECLARE_GLOBAL(int,DES_rw_mode);	/* defaults to DES_PCBC_MODE */
        +#define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)
        +
        +const char *DES_options(void);
        +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
        +		      DES_key_schedule *ks1,DES_key_schedule *ks2,
        +		      DES_key_schedule *ks3, int enc);
        +DES_LONG DES_cbc_cksum(const unsigned char *input,DES_cblock *output,
        +		       long length,DES_key_schedule *schedule,
        +		       const_DES_cblock *ivec);
        +/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
        +void DES_cbc_encrypt(const unsigned char *input,unsigned char *output,
        +		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
        +		     int enc);
        +void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
        +		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
        +		      int enc);
        +void DES_xcbc_encrypt(const unsigned char *input,unsigned char *output,
        +		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
        +		      const_DES_cblock *inw,const_DES_cblock *outw,int enc);
        +void DES_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
        +		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
        +		     int enc);
        +void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output,
        +		     DES_key_schedule *ks,int enc);
        +
        +/* 	This is the DES encryption function that gets called by just about
        +	every other DES routine in the library.  You should not use this
        +	function except to implement 'modes' of DES.  I say this because the
        +	functions that call this routine do the conversion from 'char *' to
        +	long, and this needs to be done to make sure 'non-aligned' memory
        +	access do not occur.  The characters are loaded 'little endian'.
        +	Data is a pointer to 2 unsigned long's and ks is the
        +	DES_key_schedule to use.  enc, is non zero specifies encryption,
        +	zero if decryption. */
        +void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc);
        +
        +/* 	This functions is the same as DES_encrypt1() except that the DES
        +	initial permutation (IP) and final permutation (FP) have been left
        +	out.  As for DES_encrypt1(), you should not use this function.
        +	It is used by the routines in the library that implement triple DES.
        +	IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same
        +	as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */
        +void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc);
        +
        +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
        +		  DES_key_schedule *ks2, DES_key_schedule *ks3);
        +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
        +		  DES_key_schedule *ks2, DES_key_schedule *ks3);
        +void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, 
        +			  long length,
        +			  DES_key_schedule *ks1,DES_key_schedule *ks2,
        +			  DES_key_schedule *ks3,DES_cblock *ivec,int enc);
        +void DES_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out,
        +			   long length,
        +			   DES_key_schedule *ks1,DES_key_schedule *ks2,
        +			   DES_key_schedule *ks3,
        +			   DES_cblock *ivec1,DES_cblock *ivec2,
        +			   int enc);
        +void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out,
        +			    long length,DES_key_schedule *ks1,
        +			    DES_key_schedule *ks2,DES_key_schedule *ks3,
        +			    DES_cblock *ivec,int *num,int enc);
        +void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
        +			  int numbits,long length,DES_key_schedule *ks1,
        +			  DES_key_schedule *ks2,DES_key_schedule *ks3,
        +			  DES_cblock *ivec,int enc);
        +void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out,
        +			    long length,DES_key_schedule *ks1,
        +			    DES_key_schedule *ks2,DES_key_schedule *ks3,
        +			    DES_cblock *ivec,int *num);
        +#if 0
        +void DES_xwhite_in2out(const_DES_cblock *DES_key,const_DES_cblock *in_white,
        +		       DES_cblock *out_white);
        +#endif
        +
        +int DES_enc_read(int fd,void *buf,int len,DES_key_schedule *sched,
        +		 DES_cblock *iv);
        +int DES_enc_write(int fd,const void *buf,int len,DES_key_schedule *sched,
        +		  DES_cblock *iv);
        +char *DES_fcrypt(const char *buf,const char *salt, char *ret);
        +char *DES_crypt(const char *buf,const char *salt);
        +void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
        +		     long length,DES_key_schedule *schedule,DES_cblock *ivec);
        +void DES_pcbc_encrypt(const unsigned char *input,unsigned char *output,
        +		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
        +		      int enc);
        +DES_LONG DES_quad_cksum(const unsigned char *input,DES_cblock output[],
        +			long length,int out_count,DES_cblock *seed);
        +int DES_random_key(DES_cblock *ret);
        +void DES_set_odd_parity(DES_cblock *key);
        +int DES_check_key_parity(const_DES_cblock *key);
        +int DES_is_weak_key(const_DES_cblock *key);
        +/* DES_set_key (= set_key = DES_key_sched = key_sched) calls
        + * DES_set_key_checked if global variable DES_check_key is set,
        + * DES_set_key_unchecked otherwise. */
        +int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
        +int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule);
        +int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule);
        +void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
        +#ifdef OPENSSL_FIPS
        +void private_DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
        +#endif
        +void DES_string_to_key(const char *str,DES_cblock *key);
        +void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2);
        +void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length,
        +		       DES_key_schedule *schedule,DES_cblock *ivec,int *num,
        +		       int enc);
        +void DES_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length,
        +		       DES_key_schedule *schedule,DES_cblock *ivec,int *num);
        +
        +int DES_read_password(DES_cblock *key, const char *prompt, int verify);
        +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
        +	int verify);
        +
        +#define DES_fixup_key_parity DES_set_odd_parity
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/des/des.pod b/vendor/openssl/openssl/crypto/des/des.pod
        new file mode 100644
        index 000000000..bf479e83d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des.pod
        @@ -0,0 +1,217 @@
        +=pod
        +
        +=head1 NAME
        +
        +des - encrypt or decrypt data using Data Encryption Standard
        +
        +=head1 SYNOPSIS
        +
        +B<des>
        +(
        +B<-e>
        +|
        +B<-E>
        +) | (
        +B<-d>
        +|
        +B<-D>
        +) | (
        +B<->[B<cC>][B<ckname>]
        +) |
        +[
        +B<-b3hfs>
        +] [
        +B<-k>
        +I<key>
        +]
        +] [
        +B<-u>[I<uuname>]
        +[
        +I<input-file>
        +[
        +I<output-file>
        +] ]
        +
        +=head1 NOTE
        +
        +This page describes the B<des> stand-alone program, not the B<openssl des>
        +command.
        +
        +=head1 DESCRIPTION
        +
        +B<des>
        +encrypts and decrypts data using the
        +Data Encryption Standard algorithm.
        +One of
        +B<-e>, B<-E>
        +(for encrypt) or
        +B<-d>, B<-D>
        +(for decrypt) must be specified.
        +It is also possible to use
        +B<-c>
        +or
        +B<-C>
        +in conjunction or instead of the a encrypt/decrypt option to generate
        +a 16 character hexadecimal checksum, generated via the
        +I<des_cbc_cksum>.
        +
        +Two standard encryption modes are supported by the
        +B<des>
        +program, Cipher Block Chaining (the default) and Electronic Code Book
        +(specified with
        +B<-b>).
        +
        +The key used for the DES
        +algorithm is obtained by prompting the user unless the
        +B<-k>
        +I<key>
        +option is given.
        +If the key is an argument to the
        +B<des>
        +command, it is potentially visible to users executing
        +ps(1)
        +or a derivative.  To minimise this possibility,
        +B<des>
        +takes care to destroy the key argument immediately upon entry.
        +If your shell keeps a history file be careful to make sure it is not
        +world readable.
        +
        +Since this program attempts to maintain compatibility with sunOS's
        +des(1) command, there are 2 different methods used to convert the user
        +supplied key to a des key.
        +Whenever and one or more of
        +B<-E>, B<-D>, B<-C>
        +or
        +B<-3>
        +options are used, the key conversion procedure will not be compatible
        +with the sunOS des(1) version but will use all the user supplied
        +character to generate the des key.
        +B<des>
        +command reads from standard input unless
        +I<input-file>
        +is specified and writes to standard output unless
        +I<output-file>
        +is given.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-b>
        +
        +Select ECB
        +(eight bytes at a time) encryption mode.
        +
        +=item B<-3>
        +
        +Encrypt using triple encryption.
        +By default triple cbc encryption is used but if the
        +B<-b>
        +option is used then triple ECB encryption is performed.
        +If the key is less than 8 characters long, the flag has no effect.
        +
        +=item B<-e>
        +
        +Encrypt data using an 8 byte key in a manner compatible with sunOS
        +des(1).
        +
        +=item B<-E>
        +
        +Encrypt data using a key of nearly unlimited length (1024 bytes).
        +This will product a more secure encryption.
        +
        +=item B<-d>
        +
        +Decrypt data that was encrypted with the B<-e> option.
        +
        +=item B<-D>
        +
        +Decrypt data that was encrypted with the B<-E> option.
        +
        +=item B<-c>
        +
        +Generate a 16 character hexadecimal cbc checksum and output this to
        +stderr.
        +If a filename was specified after the
        +B<-c>
        +option, the checksum is output to that file.
        +The checksum is generated using a key generated in a sunOS compatible
        +manner.
        +
        +=item B<-C>
        +
        +A cbc checksum is generated in the same manner as described for the
        +B<-c>
        +option but the DES key is generated in the same manner as used for the
        +B<-E>
        +and
        +B<-D>
        +options
        +
        +=item B<-f>
        +
        +Does nothing - allowed for compatibility with sunOS des(1) command.
        +
        +=item B<-s>
        +
        +Does nothing - allowed for compatibility with sunOS des(1) command.
        +
        +=item B<-k> I<key>
        +
        +Use the encryption 
        +I<key>
        +specified.
        +
        +=item B<-h>
        +
        +The
        +I<key>
        +is assumed to be a 16 character hexadecimal number.
        +If the
        +B<-3>
        +option is used the key is assumed to be a 32 character hexadecimal
        +number.
        +
        +=item B<-u>
        +
        +This flag is used to read and write uuencoded files.  If decrypting,
        +the input file is assumed to contain uuencoded, DES encrypted data.
        +If encrypting, the characters following the B<-u> are used as the name of
        +the uuencoded file to embed in the begin line of the uuencoded
        +output.  If there is no name specified after the B<-u>, the name text.des
        +will be embedded in the header.
        +
        +=head1 SEE ALSO
        +
        +ps(1),
        +L<des_crypt(3)|des_crypt(3)>
        +
        +=head1 BUGS
        +
        +The problem with using the
        +B<-e>
        +option is the short key length.
        +It would be better to use a real 56-bit key rather than an
        +ASCII-based 56-bit pattern.  Knowing that the key was derived from ASCII
        +radically reduces the time necessary for a brute-force cryptographic attack.
        +My attempt to remove this problem is to add an alternative text-key to
        +DES-key function.  This alternative function (accessed via
        +B<-E>, B<-D>, B<-S>
        +and
        +B<-3>)
        +uses DES to help generate the key.
        +
        +Be carefully when using the B<-u> option.  Doing B<des -ud> I<filename> will
        +not decrypt filename (the B<-u> option will gobble the B<-d> option).
        +
        +The VMS operating system operates in a world where files are always a
        +multiple of 512 bytes.  This causes problems when encrypted data is
        +send from Unix to VMS since a 88 byte file will suddenly be padded
        +with 424 null bytes.  To get around this problem, use the B<-u> option
        +to uuencode the data before it is send to the VMS system.
        +
        +=head1 AUTHOR
        +
        +Eric Young (eay@cryptsoft.com)
        +
        +=cut
        diff --git a/vendor/openssl/openssl/crypto/des/des3s.cpp b/vendor/openssl/openssl/crypto/des/des3s.cpp
        new file mode 100644
        index 000000000..02d527c05
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des3s.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/des.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	des_key_schedule key1,key2,key3;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			GetTSC(s1);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			GetTSC(e2);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			}
        +
        +		printf("des %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/des_enc.c b/vendor/openssl/openssl/crypto/des/des_enc.c
        new file mode 100644
        index 000000000..828feba20
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_enc.c
        @@ -0,0 +1,400 @@
        +/* crypto/des/des_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +#include "spr.h"
        +
        +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
        +	{
        +	register DES_LONG l,r,t,u;
        +#ifdef DES_PTR
        +	register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
        +#endif
        +#ifndef DES_UNROLL
        +	register int i;
        +#endif
        +	register DES_LONG *s;
        +
        +	r=data[0];
        +	l=data[1];
        +
        +	IP(r,l);
        +	/* Things have been modified so that the initial rotate is
        +	 * done outside the loop.  This required the
        +	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
        +	 * One perl script later and things have a 5% speed up on a sparc2.
        +	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
        +	 * for pointing this out. */
        +	/* clear the top bits on machines with 8byte longs */
        +	/* shift left by 2 */
        +	r=ROTATE(r,29)&0xffffffffL;
        +	l=ROTATE(l,29)&0xffffffffL;
        +
        +	s=ks->ks->deslong;
        +	/* I don't know if it is worth the effort of loop unrolling the
        +	 * inner loop */
        +	if (enc)
        +		{
        +#ifdef DES_UNROLL
        +		D_ENCRYPT(l,r, 0); /*  1 */
        +		D_ENCRYPT(r,l, 2); /*  2 */
        +		D_ENCRYPT(l,r, 4); /*  3 */
        +		D_ENCRYPT(r,l, 6); /*  4 */
        +		D_ENCRYPT(l,r, 8); /*  5 */
        +		D_ENCRYPT(r,l,10); /*  6 */
        +		D_ENCRYPT(l,r,12); /*  7 */
        +		D_ENCRYPT(r,l,14); /*  8 */
        +		D_ENCRYPT(l,r,16); /*  9 */
        +		D_ENCRYPT(r,l,18); /*  10 */
        +		D_ENCRYPT(l,r,20); /*  11 */
        +		D_ENCRYPT(r,l,22); /*  12 */
        +		D_ENCRYPT(l,r,24); /*  13 */
        +		D_ENCRYPT(r,l,26); /*  14 */
        +		D_ENCRYPT(l,r,28); /*  15 */
        +		D_ENCRYPT(r,l,30); /*  16 */
        +#else
        +		for (i=0; i<32; i+=4)
        +			{
        +			D_ENCRYPT(l,r,i+0); /*  1 */
        +			D_ENCRYPT(r,l,i+2); /*  2 */
        +			}
        +#endif
        +		}
        +	else
        +		{
        +#ifdef DES_UNROLL
        +		D_ENCRYPT(l,r,30); /* 16 */
        +		D_ENCRYPT(r,l,28); /* 15 */
        +		D_ENCRYPT(l,r,26); /* 14 */
        +		D_ENCRYPT(r,l,24); /* 13 */
        +		D_ENCRYPT(l,r,22); /* 12 */
        +		D_ENCRYPT(r,l,20); /* 11 */
        +		D_ENCRYPT(l,r,18); /* 10 */
        +		D_ENCRYPT(r,l,16); /*  9 */
        +		D_ENCRYPT(l,r,14); /*  8 */
        +		D_ENCRYPT(r,l,12); /*  7 */
        +		D_ENCRYPT(l,r,10); /*  6 */
        +		D_ENCRYPT(r,l, 8); /*  5 */
        +		D_ENCRYPT(l,r, 6); /*  4 */
        +		D_ENCRYPT(r,l, 4); /*  3 */
        +		D_ENCRYPT(l,r, 2); /*  2 */
        +		D_ENCRYPT(r,l, 0); /*  1 */
        +#else
        +		for (i=30; i>0; i-=4)
        +			{
        +			D_ENCRYPT(l,r,i-0); /* 16 */
        +			D_ENCRYPT(r,l,i-2); /* 15 */
        +			}
        +#endif
        +		}
        +
        +	/* rotate and clear the top bits on machines with 8byte longs */
        +	l=ROTATE(l,3)&0xffffffffL;
        +	r=ROTATE(r,3)&0xffffffffL;
        +
        +	FP(r,l);
        +	data[0]=l;
        +	data[1]=r;
        +	l=r=t=u=0;
        +	}
        +
        +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
        +	{
        +	register DES_LONG l,r,t,u;
        +#ifdef DES_PTR
        +	register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
        +#endif
        +#ifndef DES_UNROLL
        +	register int i;
        +#endif
        +	register DES_LONG *s;
        +
        +	r=data[0];
        +	l=data[1];
        +
        +	/* Things have been modified so that the initial rotate is
        +	 * done outside the loop.  This required the
        +	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
        +	 * One perl script later and things have a 5% speed up on a sparc2.
        +	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
        +	 * for pointing this out. */
        +	/* clear the top bits on machines with 8byte longs */
        +	r=ROTATE(r,29)&0xffffffffL;
        +	l=ROTATE(l,29)&0xffffffffL;
        +
        +	s=ks->ks->deslong;
        +	/* I don't know if it is worth the effort of loop unrolling the
        +	 * inner loop */
        +	if (enc)
        +		{
        +#ifdef DES_UNROLL
        +		D_ENCRYPT(l,r, 0); /*  1 */
        +		D_ENCRYPT(r,l, 2); /*  2 */
        +		D_ENCRYPT(l,r, 4); /*  3 */
        +		D_ENCRYPT(r,l, 6); /*  4 */
        +		D_ENCRYPT(l,r, 8); /*  5 */
        +		D_ENCRYPT(r,l,10); /*  6 */
        +		D_ENCRYPT(l,r,12); /*  7 */
        +		D_ENCRYPT(r,l,14); /*  8 */
        +		D_ENCRYPT(l,r,16); /*  9 */
        +		D_ENCRYPT(r,l,18); /*  10 */
        +		D_ENCRYPT(l,r,20); /*  11 */
        +		D_ENCRYPT(r,l,22); /*  12 */
        +		D_ENCRYPT(l,r,24); /*  13 */
        +		D_ENCRYPT(r,l,26); /*  14 */
        +		D_ENCRYPT(l,r,28); /*  15 */
        +		D_ENCRYPT(r,l,30); /*  16 */
        +#else
        +		for (i=0; i<32; i+=4)
        +			{
        +			D_ENCRYPT(l,r,i+0); /*  1 */
        +			D_ENCRYPT(r,l,i+2); /*  2 */
        +			}
        +#endif
        +		}
        +	else
        +		{
        +#ifdef DES_UNROLL
        +		D_ENCRYPT(l,r,30); /* 16 */
        +		D_ENCRYPT(r,l,28); /* 15 */
        +		D_ENCRYPT(l,r,26); /* 14 */
        +		D_ENCRYPT(r,l,24); /* 13 */
        +		D_ENCRYPT(l,r,22); /* 12 */
        +		D_ENCRYPT(r,l,20); /* 11 */
        +		D_ENCRYPT(l,r,18); /* 10 */
        +		D_ENCRYPT(r,l,16); /*  9 */
        +		D_ENCRYPT(l,r,14); /*  8 */
        +		D_ENCRYPT(r,l,12); /*  7 */
        +		D_ENCRYPT(l,r,10); /*  6 */
        +		D_ENCRYPT(r,l, 8); /*  5 */
        +		D_ENCRYPT(l,r, 6); /*  4 */
        +		D_ENCRYPT(r,l, 4); /*  3 */
        +		D_ENCRYPT(l,r, 2); /*  2 */
        +		D_ENCRYPT(r,l, 0); /*  1 */
        +#else
        +		for (i=30; i>0; i-=4)
        +			{
        +			D_ENCRYPT(l,r,i-0); /* 16 */
        +			D_ENCRYPT(r,l,i-2); /* 15 */
        +			}
        +#endif
        +		}
        +	/* rotate and clear the top bits on machines with 8byte longs */
        +	data[0]=ROTATE(l,3)&0xffffffffL;
        +	data[1]=ROTATE(r,3)&0xffffffffL;
        +	l=r=t=u=0;
        +	}
        +
        +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
        +		  DES_key_schedule *ks2, DES_key_schedule *ks3)
        +	{
        +	register DES_LONG l,r;
        +
        +	l=data[0];
        +	r=data[1];
        +	IP(l,r);
        +	data[0]=l;
        +	data[1]=r;
        +	DES_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
        +	DES_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
        +	DES_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
        +	l=data[0];
        +	r=data[1];
        +	FP(r,l);
        +	data[0]=l;
        +	data[1]=r;
        +	}
        +
        +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
        +		  DES_key_schedule *ks2, DES_key_schedule *ks3)
        +	{
        +	register DES_LONG l,r;
        +
        +	l=data[0];
        +	r=data[1];
        +	IP(l,r);
        +	data[0]=l;
        +	data[1]=r;
        +	DES_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
        +	DES_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
        +	DES_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
        +	l=data[0];
        +	r=data[1];
        +	FP(r,l);
        +	data[0]=l;
        +	data[1]=r;
        +	}
        +
        +#ifndef DES_DEFAULT_OPTIONS
        +
        +#undef CBC_ENC_C__DONT_UPDATE_IV
        +#include "ncbc_enc.c" /* DES_ncbc_encrypt */
        +
        +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
        +			  long length, DES_key_schedule *ks1,
        +			  DES_key_schedule *ks2, DES_key_schedule *ks3,
        +			  DES_cblock *ivec, int enc)
        +	{
        +	register DES_LONG tin0,tin1;
        +	register DES_LONG tout0,tout1,xor0,xor1;
        +	register const unsigned char *in;
        +	unsigned char *out;
        +	register long l=length;
        +	DES_LONG tin[2];
        +	unsigned char *iv;
        +
        +	in=input;
        +	out=output;
        +	iv = &(*ivec)[0];
        +
        +	if (enc)
        +		{
        +		c2l(iv,tout0);
        +		c2l(iv,tout1);
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			c2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			}
        +		iv = &(*ivec)[0];
        +		l2c(tout0,iv);
        +		l2c(tout1,iv);
        +		}
        +	else
        +		{
        +		register DES_LONG t0,t1;
        +
        +		c2l(iv,xor0);
        +		c2l(iv,xor1);
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +
        +			t0=tin0;
        +			t1=tin1;
        +
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +
        +			tout0^=xor0;
        +			tout1^=xor1;
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			xor0=t0;
        +			xor1=t1;
        +			}
        +		if (l != -8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			
        +			t0=tin0;
        +			t1=tin1;
        +
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +		
        +			tout0^=xor0;
        +			tout1^=xor1;
        +			l2cn(tout0,tout1,out,l+8);
        +			xor0=t0;
        +			xor1=t1;
        +			}
        +
        +		iv = &(*ivec)[0];
        +		l2c(xor0,iv);
        +		l2c(xor1,iv);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        +#endif /* DES_DEFAULT_OPTIONS */
        diff --git a/vendor/openssl/openssl/crypto/des/des_locl.h b/vendor/openssl/openssl/crypto/des/des_locl.h
        new file mode 100644
        index 000000000..a3b512e9b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_locl.h
        @@ -0,0 +1,432 @@
        +/* crypto/des/des_locl.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_DES_LOCL_H
        +#define HEADER_DES_LOCL_H
        +
        +#include <openssl/e_os2.h>
        +
        +#if defined(OPENSSL_SYS_WIN32)
        +#ifndef OPENSSL_SYS_MSDOS
        +#define OPENSSL_SYS_MSDOS
        +#endif
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#ifndef OPENSSL_SYS_MSDOS
        +#if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
        +#ifdef OPENSSL_UNISTD
        +# include OPENSSL_UNISTD
        +#else
        +# include <unistd.h>
        +#endif
        +#include <math.h>
        +#endif
        +#endif
        +#include <openssl/des.h>
        +
        +#ifdef OPENSSL_SYS_MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
        +#include <stdlib.h>
        +#include <errno.h>
        +#include <time.h>
        +#include <io.h>
        +#endif
        +
        +#if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
        +#include <string.h>
        +#endif
        +
        +#ifdef OPENSSL_BUILD_SHLIBCRYPTO
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +#define ITERATIONS 16
        +#define HALF_ITERATIONS 8
        +
        +/* used in des_read and des_write */
        +#define MAXWRITE	(1024*16)
        +#define BSIZE		(MAXWRITE+4)
        +
        +#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
        +			 l|=((DES_LONG)(*((c)++)))<< 8L, \
        +			 l|=((DES_LONG)(*((c)++)))<<16L, \
        +			 l|=((DES_LONG)(*((c)++)))<<24L)
        +
        +/* NOTE - c is not incremented as per c2l */
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
        +			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
        +			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
        +			case 5: l2|=((DES_LONG)(*(--(c))));     \
        +			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
        +			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
        +			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
        +			case 1: l1|=((DES_LONG)(*(--(c))));     \
        +				} \
        +			}
        +
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +
        +/* replacements for htonl and ntohl since I have no idea what to do
        + * when faced with machines with 8 byte longs. */
        +#define HDRSIZE 4
        +
        +#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
        +			 l|=((DES_LONG)(*((c)++)))<<16L, \
        +			 l|=((DES_LONG)(*((c)++)))<< 8L, \
        +			 l|=((DES_LONG)(*((c)++))))
        +
        +#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)     )&0xff))
        +
        +/* NOTE - c is not incremented as per l2c */
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
        +				} \
        +			}
        +
        +#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
        +#define	ROTATE(a,n)	(_lrotr(a,n))
        +#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
        +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
        +#  define ROTATE(a,n)	({ register unsigned int ret;	\
        +				asm ("rorl %1,%0"	\
        +					: "=r"(ret)	\
        +					: "I"(n),"0"(a)	\
        +					: "cc");	\
        +			   ret;				\
        +			})
        +# endif
        +#endif
        +#ifndef ROTATE
        +#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
        +#endif
        +
        +/* Don't worry about the LOAD_DATA() stuff, that is used by
        + * fcrypt() to add it's little bit to the front */
        +
        +#ifdef DES_FCRYPT
        +
        +#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
        +	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
        +
        +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
        +	t=R^(R>>16L); \
        +	u=t&E0; t&=E1; \
        +	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
        +	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
        +#else
        +#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
        +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
        +	u=R^s[S  ]; \
        +	t=R^s[S+1]
        +#endif
        +
        +/* The changes to this macro may help or hinder, depending on the
        + * compiler and the architecture.  gcc2 always seems to do well :-).
        + * Inspired by Dana How <how@isl.stanford.edu>
        + * DO NOT use the alternative version on machines with 8 byte longs.
        + * It does not seem to work on the Alpha, even when DES_LONG is 4
        + * bytes, probably an issue of accessing non-word aligned objects :-( */
        +#ifdef DES_PTR
        +
        +/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
        + * is no reason to not xor all the sub items together.  This potentially
        + * saves a register since things can be xored directly into L */
        +
        +#if defined(DES_RISC1) || defined(DES_RISC2)
        +#ifdef DES_RISC1
        +#define D_ENCRYPT(LL,R,S) { \
        +	unsigned int u1,u2,u3; \
        +	LOAD_DATA(R,S,u,t,E0,E1,u1); \
        +	u2=(int)u>>8L; \
        +	u1=(int)u&0xfc; \
        +	u2&=0xfc; \
        +	t=ROTATE(t,4); \
        +	u>>=16L; \
        +	LL^= *(const DES_LONG *)(des_SP      +u1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
        +	u3=(int)(u>>8L); \
        +	u1=(int)u&0xfc; \
        +	u3&=0xfc; \
        +	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
        +	u2=(int)t>>8L; \
        +	u1=(int)t&0xfc; \
        +	u2&=0xfc; \
        +	t>>=16L; \
        +	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
        +	u3=(int)t>>8L; \
        +	u1=(int)t&0xfc; \
        +	u3&=0xfc; \
        +	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
        +#endif
        +#ifdef DES_RISC2
        +#define D_ENCRYPT(LL,R,S) { \
        +	unsigned int u1,u2,s1,s2; \
        +	LOAD_DATA(R,S,u,t,E0,E1,u1); \
        +	u2=(int)u>>8L; \
        +	u1=(int)u&0xfc; \
        +	u2&=0xfc; \
        +	t=ROTATE(t,4); \
        +	LL^= *(const DES_LONG *)(des_SP      +u1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
        +	s1=(int)(u>>16L); \
        +	s2=(int)(u>>24L); \
        +	s1&=0xfc; \
        +	s2&=0xfc; \
        +	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
        +	u2=(int)t>>8L; \
        +	u1=(int)t&0xfc; \
        +	u2&=0xfc; \
        +	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
        +	s1=(int)(t>>16L); \
        +	s2=(int)(t>>24L); \
        +	s1&=0xfc; \
        +	s2&=0xfc; \
        +	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
        +	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
        +#endif
        +#else
        +#define D_ENCRYPT(LL,R,S) { \
        +	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
        +	t=ROTATE(t,4); \
        +	LL^= \
        +	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
        +	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
        +#endif
        +
        +#else /* original version */
        +
        +#if defined(DES_RISC1) || defined(DES_RISC2)
        +#ifdef DES_RISC1
        +#define D_ENCRYPT(LL,R,S) {\
        +	unsigned int u1,u2,u3; \
        +	LOAD_DATA(R,S,u,t,E0,E1,u1); \
        +	u>>=2L; \
        +	t=ROTATE(t,6); \
        +	u2=(int)u>>8L; \
        +	u1=(int)u&0x3f; \
        +	u2&=0x3f; \
        +	u>>=16L; \
        +	LL^=DES_SPtrans[0][u1]; \
        +	LL^=DES_SPtrans[2][u2]; \
        +	u3=(int)u>>8L; \
        +	u1=(int)u&0x3f; \
        +	u3&=0x3f; \
        +	LL^=DES_SPtrans[4][u1]; \
        +	LL^=DES_SPtrans[6][u3]; \
        +	u2=(int)t>>8L; \
        +	u1=(int)t&0x3f; \
        +	u2&=0x3f; \
        +	t>>=16L; \
        +	LL^=DES_SPtrans[1][u1]; \
        +	LL^=DES_SPtrans[3][u2]; \
        +	u3=(int)t>>8L; \
        +	u1=(int)t&0x3f; \
        +	u3&=0x3f; \
        +	LL^=DES_SPtrans[5][u1]; \
        +	LL^=DES_SPtrans[7][u3]; }
        +#endif
        +#ifdef DES_RISC2
        +#define D_ENCRYPT(LL,R,S) {\
        +	unsigned int u1,u2,s1,s2; \
        +	LOAD_DATA(R,S,u,t,E0,E1,u1); \
        +	u>>=2L; \
        +	t=ROTATE(t,6); \
        +	u2=(int)u>>8L; \
        +	u1=(int)u&0x3f; \
        +	u2&=0x3f; \
        +	LL^=DES_SPtrans[0][u1]; \
        +	LL^=DES_SPtrans[2][u2]; \
        +	s1=(int)u>>16L; \
        +	s2=(int)u>>24L; \
        +	s1&=0x3f; \
        +	s2&=0x3f; \
        +	LL^=DES_SPtrans[4][s1]; \
        +	LL^=DES_SPtrans[6][s2]; \
        +	u2=(int)t>>8L; \
        +	u1=(int)t&0x3f; \
        +	u2&=0x3f; \
        +	LL^=DES_SPtrans[1][u1]; \
        +	LL^=DES_SPtrans[3][u2]; \
        +	s1=(int)t>>16; \
        +	s2=(int)t>>24L; \
        +	s1&=0x3f; \
        +	s2&=0x3f; \
        +	LL^=DES_SPtrans[5][s1]; \
        +	LL^=DES_SPtrans[7][s2]; }
        +#endif
        +
        +#else
        +
        +#define D_ENCRYPT(LL,R,S) {\
        +	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
        +	t=ROTATE(t,4); \
        +	LL^=\
        +		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
        +		DES_SPtrans[2][(u>>10L)&0x3f]^ \
        +		DES_SPtrans[4][(u>>18L)&0x3f]^ \
        +		DES_SPtrans[6][(u>>26L)&0x3f]^ \
        +		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
        +		DES_SPtrans[3][(t>>10L)&0x3f]^ \
        +		DES_SPtrans[5][(t>>18L)&0x3f]^ \
        +		DES_SPtrans[7][(t>>26L)&0x3f]; }
        +#endif
        +#endif
        +
        +	/* IP and FP
        +	 * The problem is more of a geometric problem that random bit fiddling.
        +	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
        +	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
        +	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
        +	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
        +
        +	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
        +	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
        +	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
        +	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
        +
        +	The output has been subject to swaps of the form
        +	0 1 -> 3 1 but the odd and even bits have been put into
        +	2 3    2 0
        +	different words.  The main trick is to remember that
        +	t=((l>>size)^r)&(mask);
        +	r^=t;
        +	l^=(t<<size);
        +	can be used to swap and move bits between words.
        +
        +	So l =  0  1  2  3  r = 16 17 18 19
        +	        4  5  6  7      20 21 22 23
        +	        8  9 10 11      24 25 26 27
        +	       12 13 14 15      28 29 30 31
        +	becomes (for size == 2 and mask == 0x3333)
        +	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
        +		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
        +		10^24 11^25 -- --        8  9 24 25      10 11 24 25
        +		14^28 15^29 -- --       12 13 28 29      14 15 28 29
        +
        +	Thanks for hints from Richard Outerbridge - he told me IP&FP
        +	could be done in 15 xor, 10 shifts and 5 ands.
        +	When I finally started to think of the problem in 2D
        +	I first got ~42 operations without xors.  When I remembered
        +	how to use xors :-) I got it to its final state.
        +	*/
        +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
        +	(b)^=(t),\
        +	(a)^=((t)<<(n)))
        +
        +#define IP(l,r) \
        +	{ \
        +	register DES_LONG tt; \
        +	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
        +	PERM_OP(l,r,tt,16,0x0000ffffL); \
        +	PERM_OP(r,l,tt, 2,0x33333333L); \
        +	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
        +	PERM_OP(r,l,tt, 1,0x55555555L); \
        +	}
        +
        +#define FP(l,r) \
        +	{ \
        +	register DES_LONG tt; \
        +	PERM_OP(l,r,tt, 1,0x55555555L); \
        +	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
        +	PERM_OP(l,r,tt, 2,0x33333333L); \
        +	PERM_OP(r,l,tt,16,0x0000ffffL); \
        +	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
        +	}
        +
        +extern const DES_LONG DES_SPtrans[8][64];
        +
        +void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
        +		 DES_LONG Eswap0, DES_LONG Eswap1);
        +
        +#ifdef OPENSSL_SMALL_FOOTPRINT
        +#undef DES_UNROLL
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/des/des_old.c b/vendor/openssl/openssl/crypto/des/des_old.c
        new file mode 100644
        index 000000000..7c33ed7a9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_old.c
        @@ -0,0 +1,273 @@
        +/* crypto/des/des_old.c -*- mode:C; c-file-style: "eay" -*- */
        +
        +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        + *
        + * The function names in here are deprecated and are only present to
        + * provide an interface compatible with libdes.  OpenSSL now provides
        + * functions where "des_" has been replaced with "DES_" in the names,
        + * to make it possible to make incompatible changes that are needed
        + * for C type security and other stuff.
        + *
        + * Please consider starting to use the DES_ functions rather than the
        + * des_ ones.  The des_ functions will dissapear completely before
        + * OpenSSL 1.0!
        + *
        + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        + */
        +
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#define OPENSSL_DES_LIBDES_COMPATIBILITY
        +#include <openssl/des.h>
        +#include <openssl/rand.h>
        +
        +const char *_ossl_old_des_options(void)
        +	{
        +	return DES_options();
        +	}
        +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	des_key_schedule ks1,des_key_schedule ks2,
        +	des_key_schedule ks3, int enc)
        +	{
        +	DES_ecb3_encrypt((const_DES_cblock *)input, output,
        +		(DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
        +		(DES_key_schedule *)ks3, enc);
        +	}
        +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	long length,des_key_schedule schedule,_ossl_old_des_cblock *ivec)
        +	{
        +	return DES_cbc_cksum((unsigned char *)input, output, length,
        +		(DES_key_schedule *)schedule, ivec);
        +	}
        +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
        +	{
        +	DES_cbc_encrypt((unsigned char *)input, (unsigned char *)output,
        +		length, (DES_key_schedule *)schedule, ivec, enc);
        +	}
        +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
        +	{
        +	DES_ncbc_encrypt((unsigned char *)input, (unsigned char *)output,
        +		length, (DES_key_schedule *)schedule, ivec, enc);
        +	}
        +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	des_key_schedule schedule,_ossl_old_des_cblock *ivec,
        +	_ossl_old_des_cblock *inw,_ossl_old_des_cblock *outw,int enc)
        +	{
        +	DES_xcbc_encrypt((unsigned char *)input, (unsigned char *)output,
        +		length, (DES_key_schedule *)schedule, ivec, inw, outw, enc);
        +	}
        +void _ossl_old_des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
        +	long length,des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
        +	{
        +	DES_cfb_encrypt(in, out, numbits, length,
        +		(DES_key_schedule *)schedule, ivec, enc);
        +	}
        +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	des_key_schedule ks,int enc)
        +	{
        +	DES_ecb_encrypt(input, output, (DES_key_schedule *)ks, enc);
        +	}
        +void _ossl_old_des_encrypt(DES_LONG *data,des_key_schedule ks, int enc)
        +	{
        +	DES_encrypt1(data, (DES_key_schedule *)ks, enc);
        +	}
        +void _ossl_old_des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc)
        +	{
        +	DES_encrypt2(data, (DES_key_schedule *)ks, enc);
        +	}
        +void _ossl_old_des_encrypt3(DES_LONG *data, des_key_schedule ks1,
        +	des_key_schedule ks2, des_key_schedule ks3)
        +	{
        +	DES_encrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
        +		(DES_key_schedule *)ks3);
        +	}
        +void _ossl_old_des_decrypt3(DES_LONG *data, des_key_schedule ks1,
        +	des_key_schedule ks2, des_key_schedule ks3)
        +	{
        +	DES_decrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
        +		(DES_key_schedule *)ks3);
        +	}
        +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, _ossl_old_des_cblock *output, 
        +	long length, des_key_schedule ks1, des_key_schedule ks2, 
        +	des_key_schedule ks3, _ossl_old_des_cblock *ivec, int enc)
        +	{
        +	DES_ede3_cbc_encrypt((unsigned char *)input, (unsigned char *)output,
        +		length, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
        +		(DES_key_schedule *)ks3, ivec, enc);
        +	}
        +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
        +	long length, des_key_schedule ks1, des_key_schedule ks2,
        +	des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc)
        +	{
        +	DES_ede3_cfb64_encrypt(in, out, length,
        +		(DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
        +		(DES_key_schedule *)ks3, ivec, num, enc);
        +	}
        +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
        +	long length, des_key_schedule ks1, des_key_schedule ks2,
        +	des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num)
        +	{
        +	DES_ede3_ofb64_encrypt(in, out, length,
        +		(DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
        +		(DES_key_schedule *)ks3, ivec, num);
        +	}
        +
        +#if 0 /* broken code, preserved just in case anyone specifically looks for this */
        +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), _ossl_old_des_cblock (*in_white),
        +	_ossl_old_des_cblock (*out_white))
        +	{
        +	DES_xwhite_in2out(des_key, in_white, out_white);
        +	}
        +#endif
        +
        +int _ossl_old_des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
        +	_ossl_old_des_cblock *iv)
        +	{
        +	return DES_enc_read(fd, buf, len, (DES_key_schedule *)sched, iv);
        +	}
        +int _ossl_old_des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
        +	_ossl_old_des_cblock *iv)
        +	{
        +	return DES_enc_write(fd, buf, len, (DES_key_schedule *)sched, iv);
        +	}
        +char *_ossl_old_des_fcrypt(const char *buf,const char *salt, char *ret)
        +	{
        +	return DES_fcrypt(buf, salt, ret);
        +	}
        +char *_ossl_old_des_crypt(const char *buf,const char *salt)
        +	{
        +	return DES_crypt(buf, salt);
        +	}
        +char *_ossl_old_crypt(const char *buf,const char *salt)
        +	{
        +	return DES_crypt(buf, salt);
        +	}
        +void _ossl_old_des_ofb_encrypt(unsigned char *in,unsigned char *out,
        +	int numbits,long length,des_key_schedule schedule,_ossl_old_des_cblock *ivec)
        +	{
        +	DES_ofb_encrypt(in, out, numbits, length, (DES_key_schedule *)schedule,
        +		ivec);
        +	}
        +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc)
        +	{
        +	DES_pcbc_encrypt((unsigned char *)input, (unsigned char *)output,
        +		length, (DES_key_schedule *)schedule, ivec, enc);
        +	}
        +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	long length,int out_count,_ossl_old_des_cblock *seed)
        +	{
        +	return DES_quad_cksum((unsigned char *)input, output, length,
        +		out_count, seed);
        +	}
        +void _ossl_old_des_random_seed(_ossl_old_des_cblock key)
        +	{
        +	RAND_seed(key, sizeof(_ossl_old_des_cblock));
        +	}
        +void _ossl_old_des_random_key(_ossl_old_des_cblock ret)
        +	{
        +	DES_random_key((DES_cblock *)ret);
        +	}
        +int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt,
        +				int verify)
        +	{
        +	return DES_read_password(key, prompt, verify);
        +	}
        +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, _ossl_old_des_cblock *key2,
        +	const char *prompt, int verify)
        +	{
        +	return DES_read_2passwords(key1, key2, prompt, verify);
        +	}
        +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key)
        +	{
        +	DES_set_odd_parity(key);
        +	}
        +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key)
        +	{
        +	return DES_is_weak_key(key);
        +	}
        +int _ossl_old_des_set_key(_ossl_old_des_cblock *key,des_key_schedule schedule)
        +	{
        +	return DES_set_key(key, (DES_key_schedule *)schedule);
        +	}
        +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,des_key_schedule schedule)
        +	{
        +	return DES_key_sched(key, (DES_key_schedule *)schedule);
        +	}
        +void _ossl_old_des_string_to_key(char *str,_ossl_old_des_cblock *key)
        +	{
        +	DES_string_to_key(str, key);
        +	}
        +void _ossl_old_des_string_to_2keys(char *str,_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2)
        +	{
        +	DES_string_to_2keys(str, key1, key2);
        +	}
        +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
        +	des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num, int enc)
        +	{
        +	DES_cfb64_encrypt(in, out, length, (DES_key_schedule *)schedule,
        +		ivec, num, enc);
        +	}
        +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
        +	des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num)
        +	{
        +	DES_ofb64_encrypt(in, out, length, (DES_key_schedule *)schedule,
        +		ivec, num);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/des_old.h b/vendor/openssl/openssl/crypto/des/des_old.h
        new file mode 100644
        index 000000000..2b2c37235
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_old.h
        @@ -0,0 +1,446 @@
        +/* crypto/des/des_old.h -*- mode:C; c-file-style: "eay" -*- */
        +
        +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        + *
        + * The function names in here are deprecated and are only present to
        + * provide an interface compatible with openssl 0.9.6 and older as
        + * well as libdes.  OpenSSL now provides functions where "des_" has
        + * been replaced with "DES_" in the names, to make it possible to
        + * make incompatible changes that are needed for C type security and
        + * other stuff.
        + *
        + * This include files has two compatibility modes:
        + *
        + *   - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API
        + *     that is compatible with libdes and SSLeay.
        + *   - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an
        + *     API that is compatible with OpenSSL 0.9.5x to 0.9.6x.
        + *
        + * Note that these modes break earlier snapshots of OpenSSL, where
        + * libdes compatibility was the only available mode or (later on) the
        + * prefered compatibility mode.  However, after much consideration
        + * (and more or less violent discussions with external parties), it
        + * was concluded that OpenSSL should be compatible with earlier versions
        + * of itself before anything else.  Also, in all honesty, libdes is
        + * an old beast that shouldn't really be used any more.
        + *
        + * Please consider starting to use the DES_ functions rather than the
        + * des_ ones.  The des_ functions will disappear completely before
        + * OpenSSL 1.0!
        + *
        + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        + */
        +
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * 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_DES_H
        +#define HEADER_DES_H
        +
        +#include <openssl/e_os2.h>	/* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */
        +
        +#ifdef OPENSSL_NO_DES
        +#error DES is disabled.
        +#endif
        +
        +#ifndef HEADER_NEW_DES_H
        +#error You must include des.h, not des_old.h directly.
        +#endif
        +
        +#ifdef _KERBEROS_DES_H
        +#error <openssl/des_old.h> replaces <kerberos/des.h>.
        +#endif
        +
        +#include <openssl/symhacks.h>
        +
        +#ifdef OPENSSL_BUILD_SHLIBCRYPTO
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef _
        +#undef _
        +#endif
        +
        +typedef unsigned char _ossl_old_des_cblock[8];
        +typedef struct _ossl_old_des_ks_struct
        +	{
        +	union	{
        +		_ossl_old_des_cblock _;
        +		/* make sure things are correct size on machines with
        +		 * 8 byte longs */
        +		DES_LONG pad[2];
        +		} ks;
        +	} _ossl_old_des_key_schedule[16];
        +
        +#ifndef OPENSSL_DES_LIBDES_COMPATIBILITY
        +#define des_cblock DES_cblock
        +#define const_des_cblock const_DES_cblock
        +#define des_key_schedule DES_key_schedule
        +#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
        +	DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e))
        +#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
        +	DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e))
        +#define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\
        +	DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e))
        +#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
        +	DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e))
        +#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
        +	DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n))
        +#define des_options()\
        +	DES_options()
        +#define des_cbc_cksum(i,o,l,k,iv)\
        +	DES_cbc_cksum((i),(o),(l),&(k),(iv))
        +#define des_cbc_encrypt(i,o,l,k,iv,e)\
        +	DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
        +#define des_ncbc_encrypt(i,o,l,k,iv,e)\
        +	DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e))
        +#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
        +	DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e))
        +#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
        +	DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e))
        +#define des_ecb_encrypt(i,o,k,e)\
        +	DES_ecb_encrypt((i),(o),&(k),(e))
        +#define des_encrypt1(d,k,e)\
        +	DES_encrypt1((d),&(k),(e))
        +#define des_encrypt2(d,k,e)\
        +	DES_encrypt2((d),&(k),(e))
        +#define des_encrypt3(d,k1,k2,k3)\
        +	DES_encrypt3((d),&(k1),&(k2),&(k3))
        +#define des_decrypt3(d,k1,k2,k3)\
        +	DES_decrypt3((d),&(k1),&(k2),&(k3))
        +#define des_xwhite_in2out(k,i,o)\
        +	DES_xwhite_in2out((k),(i),(o))
        +#define des_enc_read(f,b,l,k,iv)\
        +	DES_enc_read((f),(b),(l),&(k),(iv))
        +#define des_enc_write(f,b,l,k,iv)\
        +	DES_enc_write((f),(b),(l),&(k),(iv))
        +#define des_fcrypt(b,s,r)\
        +	DES_fcrypt((b),(s),(r))
        +#if 0
        +#define des_crypt(b,s)\
        +	DES_crypt((b),(s))
        +#if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
        +#define crypt(b,s)\
        +	DES_crypt((b),(s))
        +#endif
        +#endif
        +#define des_ofb_encrypt(i,o,n,l,k,iv)\
        +	DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv))
        +#define des_pcbc_encrypt(i,o,l,k,iv,e)\
        +	DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e))
        +#define des_quad_cksum(i,o,l,c,s)\
        +	DES_quad_cksum((i),(o),(l),(c),(s))
        +#define des_random_seed(k)\
        +	_ossl_096_des_random_seed((k))
        +#define des_random_key(r)\
        +	DES_random_key((r))
        +#define des_read_password(k,p,v) \
        +	DES_read_password((k),(p),(v))
        +#define des_read_2passwords(k1,k2,p,v) \
        +	DES_read_2passwords((k1),(k2),(p),(v))
        +#define des_set_odd_parity(k)\
        +	DES_set_odd_parity((k))
        +#define des_check_key_parity(k)\
        +	DES_check_key_parity((k))
        +#define des_is_weak_key(k)\
        +	DES_is_weak_key((k))
        +#define des_set_key(k,ks)\
        +	DES_set_key((k),&(ks))
        +#define des_key_sched(k,ks)\
        +	DES_key_sched((k),&(ks))
        +#define des_set_key_checked(k,ks)\
        +	DES_set_key_checked((k),&(ks))
        +#define des_set_key_unchecked(k,ks)\
        +	DES_set_key_unchecked((k),&(ks))
        +#define des_string_to_key(s,k)\
        +	DES_string_to_key((s),(k))
        +#define des_string_to_2keys(s,k1,k2)\
        +	DES_string_to_2keys((s),(k1),(k2))
        +#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
        +	DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e))
        +#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
        +	DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n))
        +		
        +
        +#define des_ecb2_encrypt(i,o,k1,k2,e) \
        +	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
        +
        +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        +	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
        +
        +#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        +	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
        +
        +#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        +	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
        +
        +#define des_check_key DES_check_key
        +#define des_rw_mode DES_rw_mode
        +#else /* libdes compatibility */
        +/* Map all symbol names to _ossl_old_des_* form, so we avoid all
        +   clashes with libdes */
        +#define des_cblock _ossl_old_des_cblock
        +#define des_key_schedule _ossl_old_des_key_schedule
        +#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
        +	_ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e))
        +#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
        +	_ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e))
        +#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
        +	_ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e))
        +#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
        +	_ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n))
        +#define des_options()\
        +	_ossl_old_des_options()
        +#define des_cbc_cksum(i,o,l,k,iv)\
        +	_ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv))
        +#define des_cbc_encrypt(i,o,l,k,iv,e)\
        +	_ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e))
        +#define des_ncbc_encrypt(i,o,l,k,iv,e)\
        +	_ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e))
        +#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
        +	_ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e))
        +#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
        +	_ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e))
        +#define des_ecb_encrypt(i,o,k,e)\
        +	_ossl_old_des_ecb_encrypt((i),(o),(k),(e))
        +#define des_encrypt(d,k,e)\
        +	_ossl_old_des_encrypt((d),(k),(e))
        +#define des_encrypt2(d,k,e)\
        +	_ossl_old_des_encrypt2((d),(k),(e))
        +#define des_encrypt3(d,k1,k2,k3)\
        +	_ossl_old_des_encrypt3((d),(k1),(k2),(k3))
        +#define des_decrypt3(d,k1,k2,k3)\
        +	_ossl_old_des_decrypt3((d),(k1),(k2),(k3))
        +#define des_xwhite_in2out(k,i,o)\
        +	_ossl_old_des_xwhite_in2out((k),(i),(o))
        +#define des_enc_read(f,b,l,k,iv)\
        +	_ossl_old_des_enc_read((f),(b),(l),(k),(iv))
        +#define des_enc_write(f,b,l,k,iv)\
        +	_ossl_old_des_enc_write((f),(b),(l),(k),(iv))
        +#define des_fcrypt(b,s,r)\
        +	_ossl_old_des_fcrypt((b),(s),(r))
        +#define des_crypt(b,s)\
        +	_ossl_old_des_crypt((b),(s))
        +#if 0
        +#define crypt(b,s)\
        +	_ossl_old_crypt((b),(s))
        +#endif
        +#define des_ofb_encrypt(i,o,n,l,k,iv)\
        +	_ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv))
        +#define des_pcbc_encrypt(i,o,l,k,iv,e)\
        +	_ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e))
        +#define des_quad_cksum(i,o,l,c,s)\
        +	_ossl_old_des_quad_cksum((i),(o),(l),(c),(s))
        +#define des_random_seed(k)\
        +	_ossl_old_des_random_seed((k))
        +#define des_random_key(r)\
        +	_ossl_old_des_random_key((r))
        +#define des_read_password(k,p,v) \
        +	_ossl_old_des_read_password((k),(p),(v))
        +#define des_read_2passwords(k1,k2,p,v) \
        +	_ossl_old_des_read_2passwords((k1),(k2),(p),(v))
        +#define des_set_odd_parity(k)\
        +	_ossl_old_des_set_odd_parity((k))
        +#define des_is_weak_key(k)\
        +	_ossl_old_des_is_weak_key((k))
        +#define des_set_key(k,ks)\
        +	_ossl_old_des_set_key((k),(ks))
        +#define des_key_sched(k,ks)\
        +	_ossl_old_des_key_sched((k),(ks))
        +#define des_string_to_key(s,k)\
        +	_ossl_old_des_string_to_key((s),(k))
        +#define des_string_to_2keys(s,k1,k2)\
        +	_ossl_old_des_string_to_2keys((s),(k1),(k2))
        +#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
        +	_ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e))
        +#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
        +	_ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n))
        +		
        +
        +#define des_ecb2_encrypt(i,o,k1,k2,e) \
        +	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
        +
        +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        +	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
        +
        +#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        +	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
        +
        +#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        +	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
        +
        +#define des_check_key DES_check_key
        +#define des_rw_mode DES_rw_mode
        +#endif
        +
        +const char *_ossl_old_des_options(void);
        +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	_ossl_old_des_key_schedule ks1,_ossl_old_des_key_schedule ks2,
        +	_ossl_old_des_key_schedule ks3, int enc);
        +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
        +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
        +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
        +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,
        +	_ossl_old_des_cblock *inw,_ossl_old_des_cblock *outw,int enc);
        +void _ossl_old_des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
        +	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
        +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	_ossl_old_des_key_schedule ks,int enc);
        +void _ossl_old_des_encrypt(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
        +void _ossl_old_des_encrypt2(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
        +void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
        +	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
        +void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
        +	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
        +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, _ossl_old_des_cblock *output, 
        +	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2, 
        +	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int enc);
        +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
        +	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
        +	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc);
        +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
        +	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
        +	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num);
        +#if 0
        +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), _ossl_old_des_cblock (*in_white),
        +	_ossl_old_des_cblock (*out_white));
        +#endif
        +
        +int _ossl_old_des_enc_read(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
        +	_ossl_old_des_cblock *iv);
        +int _ossl_old_des_enc_write(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
        +	_ossl_old_des_cblock *iv);
        +char *_ossl_old_des_fcrypt(const char *buf,const char *salt, char *ret);
        +char *_ossl_old_des_crypt(const char *buf,const char *salt);
        +#if !defined(PERL5) && !defined(NeXT)
        +char *_ossl_old_crypt(const char *buf,const char *salt);
        +#endif
        +void _ossl_old_des_ofb_encrypt(unsigned char *in,unsigned char *out,
        +	int numbits,long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
        +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
        +	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
        +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
        +	long length,int out_count,_ossl_old_des_cblock *seed);
        +void _ossl_old_des_random_seed(_ossl_old_des_cblock key);
        +void _ossl_old_des_random_key(_ossl_old_des_cblock ret);
        +int _ossl_old_des_read_password(_ossl_old_des_cblock *key,const char *prompt,int verify);
        +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2,
        +	const char *prompt,int verify);
        +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key);
        +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key);
        +int _ossl_old_des_set_key(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
        +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
        +void _ossl_old_des_string_to_key(char *str,_ossl_old_des_cblock *key);
        +void _ossl_old_des_string_to_2keys(char *str,_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2);
        +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
        +	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num, int enc);
        +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
        +	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num);
        +
        +void _ossl_096_des_random_seed(des_cblock *key);
        +
        +/* The following definitions provide compatibility with the MIT Kerberos
        + * library. The _ossl_old_des_key_schedule structure is not binary compatible. */
        +
        +#define _KERBEROS_DES_H
        +
        +#define KRBDES_ENCRYPT DES_ENCRYPT
        +#define KRBDES_DECRYPT DES_DECRYPT
        +
        +#ifdef KERBEROS
        +#  define ENCRYPT DES_ENCRYPT
        +#  define DECRYPT DES_DECRYPT
        +#endif
        +
        +#ifndef NCOMPAT
        +#  define C_Block des_cblock
        +#  define Key_schedule des_key_schedule
        +#  define KEY_SZ DES_KEY_SZ
        +#  define string_to_key des_string_to_key
        +#  define read_pw_string des_read_pw_string
        +#  define random_key des_random_key
        +#  define pcbc_encrypt des_pcbc_encrypt
        +#  define set_key des_set_key
        +#  define key_sched des_key_sched
        +#  define ecb_encrypt des_ecb_encrypt
        +#  define cbc_encrypt des_cbc_encrypt
        +#  define ncbc_encrypt des_ncbc_encrypt
        +#  define xcbc_encrypt des_xcbc_encrypt
        +#  define cbc_cksum des_cbc_cksum
        +#  define quad_cksum des_quad_cksum
        +#  define check_parity des_check_key_parity
        +#endif
        +
        +#define des_fixup_key_parity DES_fixup_key_parity
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +/* for DES_read_pw_string et al */
        +#include <openssl/ui_compat.h>
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/des/des_old2.c b/vendor/openssl/openssl/crypto/des/des_old2.c
        new file mode 100644
        index 000000000..c8fa3ee13
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_old2.c
        @@ -0,0 +1,82 @@
        +/* crypto/des/des_old.c -*- mode:C; c-file-style: "eay" -*- */
        +
        +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        + *
        + * The function names in here are deprecated and are only present to
        + * provide an interface compatible with OpenSSL 0.9.6c.  OpenSSL now
        + * provides functions where "des_" has been replaced with "DES_" in
        + * the names, to make it possible to make incompatible changes that
        + * are needed for C type security and other stuff.
        + *
        + * Please consider starting to use the DES_ functions rather than the
        + * des_ ones.  The des_ functions will dissapear completely before
        + * OpenSSL 1.0!
        + *
        + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        + */
        +
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#undef OPENSSL_DES_LIBDES_COMPATIBILITY
        +#include <openssl/des.h>
        +#include <openssl/rand.h>
        +
        +void _ossl_096_des_random_seed(DES_cblock *key)
        +	{
        +	RAND_seed(key, sizeof(DES_cblock));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/des_opts.c b/vendor/openssl/openssl/crypto/des/des_opts.c
        new file mode 100644
        index 000000000..2df82962c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_opts.c
        @@ -0,0 +1,608 @@
        +/* crypto/des/des_opts.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.]
        + */
        +
        +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
        + * This is for machines with 64k code segment size restrictions. */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +#ifndef OPENSSL_SYS_MSDOS
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD
        +#else
        +#include <io.h>
        +extern void exit();
        +#endif
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/des.h>
        +#include "spr.h"
        +
        +#define DES_DEFAULT_OPTIONS
        +
        +#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
        +#define PART1
        +#define PART2
        +#define PART3
        +#define PART4
        +#endif
        +
        +#ifdef PART1
        +
        +#undef DES_UNROLL
        +#undef DES_RISC1
        +#undef DES_RISC2
        +#undef DES_PTR
        +#undef D_ENCRYPT
        +#define DES_encrypt1 des_encrypt_u4_cisc_idx
        +#define DES_encrypt2 des_encrypt2_u4_cisc_idx
        +#define DES_encrypt3 des_encrypt3_u4_cisc_idx
        +#define DES_decrypt3 des_decrypt3_u4_cisc_idx
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#define DES_UNROLL
        +#undef DES_RISC1
        +#undef DES_RISC2
        +#undef DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u16_cisc_idx
        +#define DES_encrypt2 des_encrypt2_u16_cisc_idx
        +#define DES_encrypt3 des_encrypt3_u16_cisc_idx
        +#define DES_decrypt3 des_decrypt3_u16_cisc_idx
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#undef DES_UNROLL
        +#define DES_RISC1
        +#undef DES_RISC2
        +#undef DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u4_risc1_idx
        +#define DES_encrypt2 des_encrypt2_u4_risc1_idx
        +#define DES_encrypt3 des_encrypt3_u4_risc1_idx
        +#define DES_decrypt3 des_decrypt3_u4_risc1_idx
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#endif
        +
        +#ifdef PART2
        +
        +#undef DES_UNROLL
        +#undef DES_RISC1
        +#define DES_RISC2
        +#undef DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u4_risc2_idx
        +#define DES_encrypt2 des_encrypt2_u4_risc2_idx
        +#define DES_encrypt3 des_encrypt3_u4_risc2_idx
        +#define DES_decrypt3 des_decrypt3_u4_risc2_idx
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#define DES_UNROLL
        +#define DES_RISC1
        +#undef DES_RISC2
        +#undef DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u16_risc1_idx
        +#define DES_encrypt2 des_encrypt2_u16_risc1_idx
        +#define DES_encrypt3 des_encrypt3_u16_risc1_idx
        +#define DES_decrypt3 des_decrypt3_u16_risc1_idx
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#define DES_UNROLL
        +#undef DES_RISC1
        +#define DES_RISC2
        +#undef DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u16_risc2_idx
        +#define DES_encrypt2 des_encrypt2_u16_risc2_idx
        +#define DES_encrypt3 des_encrypt3_u16_risc2_idx
        +#define DES_decrypt3 des_decrypt3_u16_risc2_idx
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#endif
        +
        +#ifdef PART3
        +
        +#undef DES_UNROLL
        +#undef DES_RISC1
        +#undef DES_RISC2
        +#define DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u4_cisc_ptr
        +#define DES_encrypt2 des_encrypt2_u4_cisc_ptr
        +#define DES_encrypt3 des_encrypt3_u4_cisc_ptr
        +#define DES_decrypt3 des_decrypt3_u4_cisc_ptr
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#define DES_UNROLL
        +#undef DES_RISC1
        +#undef DES_RISC2
        +#define DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u16_cisc_ptr
        +#define DES_encrypt2 des_encrypt2_u16_cisc_ptr
        +#define DES_encrypt3 des_encrypt3_u16_cisc_ptr
        +#define DES_decrypt3 des_decrypt3_u16_cisc_ptr
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#undef DES_UNROLL
        +#define DES_RISC1
        +#undef DES_RISC2
        +#define DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u4_risc1_ptr
        +#define DES_encrypt2 des_encrypt2_u4_risc1_ptr
        +#define DES_encrypt3 des_encrypt3_u4_risc1_ptr
        +#define DES_decrypt3 des_decrypt3_u4_risc1_ptr
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#endif
        +
        +#ifdef PART4
        +
        +#undef DES_UNROLL
        +#undef DES_RISC1
        +#define DES_RISC2
        +#define DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u4_risc2_ptr
        +#define DES_encrypt2 des_encrypt2_u4_risc2_ptr
        +#define DES_encrypt3 des_encrypt3_u4_risc2_ptr
        +#define DES_decrypt3 des_decrypt3_u4_risc2_ptr
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#define DES_UNROLL
        +#define DES_RISC1
        +#undef DES_RISC2
        +#define DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u16_risc1_ptr
        +#define DES_encrypt2 des_encrypt2_u16_risc1_ptr
        +#define DES_encrypt3 des_encrypt3_u16_risc1_ptr
        +#define DES_decrypt3 des_decrypt3_u16_risc1_ptr
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#define DES_UNROLL
        +#undef DES_RISC1
        +#define DES_RISC2
        +#define DES_PTR
        +#undef D_ENCRYPT
        +#undef DES_encrypt1
        +#undef DES_encrypt2
        +#undef DES_encrypt3
        +#undef DES_decrypt3
        +#define DES_encrypt1 des_encrypt_u16_risc2_ptr
        +#define DES_encrypt2 des_encrypt2_u16_risc2_ptr
        +#define DES_encrypt3 des_encrypt3_u16_risc2_ptr
        +#define DES_decrypt3 des_decrypt3_u16_risc2_ptr
        +#undef HEADER_DES_LOCL_H
        +#include "des_enc.c"
        +
        +#endif
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +# ifndef CLK_TCK
        +#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
        +#   define HZ	100.0
        +#  else /* _BSD_CLK_TCK_ */
        +#   define HZ ((double)_BSD_CLK_TCK_)
        +#  endif
        +# else /* CLK_TCK */
        +#  define HZ ((double)CLK_TCK)
        +# endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +#ifdef SIGALRM
        +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
        +#else
        +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
        +#endif
        +	
        +#define time_it(func,name,index) \
        +	print_name(name); \
        +	Time_F(START); \
        +	for (count=0,run=1; COND(cb); count++) \
        +		{ \
        +		unsigned long d[2]; \
        +		func(d,&sch,DES_ENCRYPT); \
        +		} \
        +	tm[index]=Time_F(STOP); \
        +	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
        +	tm[index]=((double)COUNT(cb))/tm[index];
        +
        +#define print_it(name,index) \
        +	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
        +		tm[index]*8,1.0e6/tm[index]);
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
        +	static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
        +	static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
        +	DES_key_schedule sch,sch2,sch3;
        +	double d,tm[16],max=0;
        +	int rank[16];
        +	char *str[16];
        +	int max_idx=0,i,num=0,j;
        +#ifndef SIGALARM
        +	long ca,cb,cc,cd,ce;
        +#endif
        +
        +	for (i=0; i<12; i++)
        +		{
        +		tm[i]=0.0;
        +		rank[i]=0;
        +		}
        +
        +#ifndef TIMES
        +	fprintf(stderr,"To get the most accurate results, try to run this\n");
        +	fprintf(stderr,"program when this computer is idle.\n");
        +#endif
        +
        +	DES_set_key_unchecked(&key,&sch);
        +	DES_set_key_unchecked(&key2,&sch2);
        +	DES_set_key_unchecked(&key3,&sch3);
        +
        +#ifndef SIGALRM
        +	fprintf(stderr,"First we calculate the approximate speed ...\n");
        +	DES_set_key_unchecked(&key,sch);
        +	count=10;
        +	do	{
        +		long i;
        +		unsigned long data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			DES_encrypt1(data,&(sch[0]),DES_ENCRYPT);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count;
        +	cb=count*3;
        +	cc=count*3*8/BUFSIZE+1;
        +	cd=count*8/BUFSIZE+1;
        +
        +	ce=count/20+1;
        +#define COND(d) (count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c) (run)
        +#define COUNT(d) (count)
        +        signal(SIGALRM,sig_done);
        +        alarm(10);
        +#endif
        +
        +#ifdef PART1
        +	time_it(des_encrypt_u4_cisc_idx,  "des_encrypt_u4_cisc_idx  ", 0);
        +	time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
        +	time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
        +	num+=3;
        +#endif
        +#ifdef PART2
        +	time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
        +	time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
        +	time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
        +	num+=3;
        +#endif
        +#ifdef PART3
        +	time_it(des_encrypt_u4_cisc_ptr,  "des_encrypt_u4_cisc_ptr  ", 6);
        +	time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
        +	time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
        +	num+=3;
        +#endif
        +#ifdef PART4
        +	time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
        +	time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
        +	time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
        +	num+=3;
        +#endif
        +
        +#ifdef PART1
        +	str[0]=" 4  c i";
        +	print_it("des_encrypt_u4_cisc_idx  ",0);
        +	max=tm[0];
        +	max_idx=0;
        +	str[1]="16  c i";
        +	print_it("des_encrypt_u16_cisc_idx ",1);
        +	if (max < tm[1]) { max=tm[1]; max_idx=1; }
        +	str[2]=" 4 r1 i";
        +	print_it("des_encrypt_u4_risc1_idx ",2);
        +	if (max < tm[2]) { max=tm[2]; max_idx=2; }
        +#endif
        +#ifdef PART2
        +	str[3]="16 r1 i";
        +	print_it("des_encrypt_u16_risc1_idx",3);
        +	if (max < tm[3]) { max=tm[3]; max_idx=3; }
        +	str[4]=" 4 r2 i";
        +	print_it("des_encrypt_u4_risc2_idx ",4);
        +	if (max < tm[4]) { max=tm[4]; max_idx=4; }
        +	str[5]="16 r2 i";
        +	print_it("des_encrypt_u16_risc2_idx",5);
        +	if (max < tm[5]) { max=tm[5]; max_idx=5; }
        +#endif
        +#ifdef PART3
        +	str[6]=" 4  c p";
        +	print_it("des_encrypt_u4_cisc_ptr  ",6);
        +	if (max < tm[6]) { max=tm[6]; max_idx=6; }
        +	str[7]="16  c p";
        +	print_it("des_encrypt_u16_cisc_ptr ",7);
        +	if (max < tm[7]) { max=tm[7]; max_idx=7; }
        +	str[8]=" 4 r1 p";
        +	print_it("des_encrypt_u4_risc1_ptr ",8);
        +	if (max < tm[8]) { max=tm[8]; max_idx=8; }
        +#endif
        +#ifdef PART4
        +	str[9]="16 r1 p";
        +	print_it("des_encrypt_u16_risc1_ptr",9);
        +	if (max < tm[9]) { max=tm[9]; max_idx=9; }
        +	str[10]=" 4 r2 p";
        +	print_it("des_encrypt_u4_risc2_ptr ",10);
        +	if (max < tm[10]) { max=tm[10]; max_idx=10; }
        +	str[11]="16 r2 p";
        +	print_it("des_encrypt_u16_risc2_ptr",11);
        +	if (max < tm[11]) { max=tm[11]; max_idx=11; }
        +#endif
        +	printf("options    des ecb/s\n");
        +	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
        +	d=tm[max_idx];
        +	tm[max_idx]= -2.0;
        +	max= -1.0;
        +	for (;;)
        +		{
        +		for (i=0; i<12; i++)
        +			{
        +			if (max < tm[i]) { max=tm[i]; j=i; }
        +			}
        +		if (max < 0.0) break;
        +		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
        +		tm[j]= -2.0;
        +		max= -1.0;
        +		}
        +
        +	switch (max_idx)
        +		{
        +	case 0:
        +		printf("-DDES_DEFAULT_OPTIONS\n");
        +		break;
        +	case 1:
        +		printf("-DDES_UNROLL\n");
        +		break;
        +	case 2:
        +		printf("-DDES_RISC1\n");
        +		break;
        +	case 3:
        +		printf("-DDES_UNROLL -DDES_RISC1\n");
        +		break;
        +	case 4:
        +		printf("-DDES_RISC2\n");
        +		break;
        +	case 5:
        +		printf("-DDES_UNROLL -DDES_RISC2\n");
        +		break;
        +	case 6:
        +		printf("-DDES_PTR\n");
        +		break;
        +	case 7:
        +		printf("-DDES_UNROLL -DDES_PTR\n");
        +		break;
        +	case 8:
        +		printf("-DDES_RISC1 -DDES_PTR\n");
        +		break;
        +	case 9:
        +		printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
        +		break;
        +	case 10:
        +		printf("-DDES_RISC2 -DDES_PTR\n");
        +		break;
        +	case 11:
        +		printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
        +		break;
        +		}
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/des_ver.h b/vendor/openssl/openssl/crypto/des/des_ver.h
        new file mode 100644
        index 000000000..d1ada258a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/des_ver.h
        @@ -0,0 +1,71 @@
        +/* crypto/des/des_ver.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 <openssl/e_os2.h>
        +
        +#ifdef OPENSSL_BUILD_SHLIBCRYPTO
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +/* The following macros make sure the names are different from libdes names */
        +#define DES_version OSSL_DES_version
        +#define libdes_version OSSL_libdes_version
        +
        +OPENSSL_EXTERN const char OSSL_DES_version[];	/* SSLeay version string */
        +OPENSSL_EXTERN const char OSSL_libdes_version[];	/* old libdes version string */
        diff --git a/vendor/openssl/openssl/crypto/des/dess.cpp b/vendor/openssl/openssl/crypto/des/dess.cpp
        new file mode 100644
        index 000000000..5549bab90
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/dess.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/des.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	des_key_schedule key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			des_encrypt1(&data[0],key,1);
        +			GetTSC(s1);
        +			des_encrypt1(&data[0],key,1);
        +			des_encrypt1(&data[0],key,1);
        +			des_encrypt1(&data[0],key,1);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			des_encrypt1(&data[0],key,1);
        +			des_encrypt1(&data[0],key,1);
        +			des_encrypt1(&data[0],key,1);
        +			des_encrypt1(&data[0],key,1);
        +			GetTSC(e2);
        +			des_encrypt1(&data[0],key,1);
        +			}
        +
        +		printf("des %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/destest.c b/vendor/openssl/openssl/crypto/des/destest.c
        new file mode 100644
        index 000000000..64b92a34f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/destest.c
        @@ -0,0 +1,952 @@
        +/* crypto/des/destest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include <openssl/e_os2.h>
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_WINDOWS)
        +#ifndef OPENSSL_SYS_MSDOS
        +#define OPENSSL_SYS_MSDOS
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_SYS_MSDOS
        +#if !defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VMS_DECC)
        +#include OPENSSL_UNISTD
        +#endif
        +#else
        +#include <io.h>
        +#endif
        +#include <string.h>
        +
        +#ifdef OPENSSL_NO_DES
        +int main(int argc, char *argv[])
        +{
        +    printf("No DES support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/des.h>
        +
        +#define crypt(c,s) (DES_crypt((c),(s)))
        +
        +/* tisk tisk - the test keys don't all have odd parity :-( */
        +/* test data */
        +#define NUM_TESTS 34
        +static unsigned char key_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
        +	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
        +	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
        +	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
        +	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
        +	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
        +	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
        +	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
        +	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
        +	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
        +	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
        +	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
        +	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
        +	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
        +	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
        +	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
        +	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
        +	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
        +	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
        +	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
        +	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
        +	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
        +	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
        +
        +static unsigned char plain_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
        +	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
        +	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
        +	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
        +	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
        +	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
        +	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
        +	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
        +	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
        +	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
        +	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
        +	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
        +	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
        +	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
        +	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
        +	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
        +	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
        +	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
        +	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
        +
        +static unsigned char cipher_data[NUM_TESTS][8]={
        +	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
        +	{0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
        +	{0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
        +	{0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
        +	{0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
        +	{0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
        +	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
        +	{0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
        +	{0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
        +	{0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
        +	{0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
        +	{0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
        +	{0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
        +	{0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
        +	{0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
        +	{0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
        +	{0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
        +	{0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
        +	{0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
        +	{0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
        +	{0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
        +	{0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
        +	{0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
        +	{0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
        +	{0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
        +	{0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
        +	{0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
        +	{0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
        +	{0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
        +	{0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
        +	{0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
        +	{0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
        +	{0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
        +	{0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
        +
        +static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
        +	{0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
        +	{0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
        +	{0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
        +	{0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
        +	{0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
        +	{0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
        +	{0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
        +	{0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
        +	{0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
        +	{0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
        +	{0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
        +	{0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
        +	{0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
        +	{0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
        +	{0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
        +	{0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
        +	{0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
        +	{0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
        +	{0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
        +	{0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
        +	{0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
        +	{0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
        +	{0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
        +	{0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
        +	{0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
        +	{0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
        +	{0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
        +	{0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
        +	{0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
        +	{0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
        +	{0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
        +	{0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
        +	{0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
        +
        +static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
        +static unsigned char cbc2_key[8]={0xf1,0xe0,0xd3,0xc2,0xb5,0xa4,0x97,0x86};
        +static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
        +static unsigned char cbc_iv  [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
        +/* Changed the following text constant to binary so it will work on ebcdic
        + * machines :-) */
        +/* static char cbc_data[40]="7654321 Now is the time for \0001"; */
        +static unsigned char cbc_data[40]={
        +	0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x20,
        +	0x4E,0x6F,0x77,0x20,0x69,0x73,0x20,0x74,
        +	0x68,0x65,0x20,0x74,0x69,0x6D,0x65,0x20,
        +	0x66,0x6F,0x72,0x20,0x00,0x31,0x00,0x00,
        +	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	};
        +
        +static unsigned char cbc_ok[32]={
        +	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
        +	0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
        +	0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
        +	0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
        +
        +#ifdef SCREW_THE_PARITY
        +#error "SCREW_THE_PARITY is not ment to be defined."
        +#error "Original vectors are preserved for reference only."
        +static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
        +static unsigned char xcbc_ok[32]={
        +	0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
        +	0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
        +	0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
        +	0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
        +	};
        +#else
        +static unsigned char xcbc_ok[32]={
        +	0x84,0x6B,0x29,0x14,0x85,0x1E,0x9A,0x29,
        +	0x54,0x73,0x2F,0x8A,0xA0,0xA6,0x11,0xC1,
        +	0x15,0xCD,0xC2,0xD7,0x95,0x1B,0x10,0x53,
        +	0xA6,0x3C,0x5E,0x03,0xB2,0x1A,0xA3,0xC4,
        +	};
        +#endif
        +
        +static unsigned char cbc3_ok[32]={
        +	0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
        +	0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
        +	0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
        +	0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
        +
        +static unsigned char pcbc_ok[32]={
        +	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
        +	0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
        +	0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
        +	0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
        +
        +static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
        +static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +static unsigned char plain[24]=
        +	{
        +	0x4e,0x6f,0x77,0x20,0x69,0x73,
        +	0x20,0x74,0x68,0x65,0x20,0x74,
        +	0x69,0x6d,0x65,0x20,0x66,0x6f,
        +	0x72,0x20,0x61,0x6c,0x6c,0x20
        +	};
        +static unsigned char cfb_cipher8[24]= {
        +	0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
        +	0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
        +static unsigned char cfb_cipher16[24]={
        +	0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
        +	0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
        +static unsigned char cfb_cipher32[24]={
        +	0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
        +	0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
        +static unsigned char cfb_cipher48[24]={
        +	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
        +	0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
        +static unsigned char cfb_cipher64[24]={
        +	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
        +	0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
        +
        +static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
        +static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
        +static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
        +static unsigned char ofb_cipher[24]=
        +	{
        +	0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
        +	0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
        +	0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
        +	};
        +
        +#if 0
        +static DES_LONG cbc_cksum_ret=0xB462FEF7L;
        +#else
        +static DES_LONG cbc_cksum_ret=0xF7FE62B4L;
        +#endif
        +static unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
        +
        +static char *pt(unsigned char *p);
        +static int cfb_test(int bits, unsigned char *cfb_cipher);
        +static int cfb64_test(unsigned char *cfb_cipher);
        +static int ede_cfb64_test(unsigned char *cfb_cipher);
        +int main(int argc, char *argv[])
        +	{
        +	int j,err=0;
        +	unsigned int i;
        +	des_cblock in,out,outin,iv3,iv2;
        +	des_key_schedule ks,ks2,ks3;
        +	unsigned char cbc_in[40];
        +	unsigned char cbc_out[40];
        +	DES_LONG cs;
        +	unsigned char cret[8];
        +#ifdef _CRAY
        +        struct {
        +            int a:32;
        +            int b:32;
        +        } lqret[2];
        +#else
        +        DES_LONG lqret[4];
        +#endif
        +	int num;
        +	char *str;
        +
        +#ifndef OPENSSL_NO_DESCBCM
        +	printf("Doing cbcm\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	i=strlen((char *)cbc_data)+1;
        +	/* i=((i+7)/8)*8; */
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	memset(iv2,'\0',sizeof iv2);
        +
        +	DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2,
        +			      DES_ENCRYPT);
        +	DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3,
        +			      &iv3,&iv2,DES_ENCRYPT);
        +	/*	if (memcmp(cbc_out,cbc3_ok,
        +		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
        +		{
        +		printf("des_ede3_cbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	*/
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	memset(iv2,'\0',sizeof iv2);
        +	DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		unsigned int n;
        +
        +		printf("des_ede3_cbcm_encrypt decrypt error\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_data[n]);
        +		printf("\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_in[n]);
        +		printf("\n");
        +		err=1;
        +		}
        +#endif
        +
        +	printf("Doing ecb\n");
        +	for (i=0; i<NUM_TESTS; i++)
        +		{
        +		DES_set_key_unchecked(&key_data[i],&ks);
        +		memcpy(in,plain_data[i],8);
        +		memset(out,0,8);
        +		memset(outin,0,8);
        +		des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
        +		des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);
        +
        +		if (memcmp(out,cipher_data[i],8) != 0)
        +			{
        +			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
        +				pt(out));
        +			err=1;
        +			}
        +		if (memcmp(in,outin,8) != 0)
        +			{
        +			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
        +			err=1;
        +			}
        +		}
        +
        +#ifndef LIBDES_LIT
        +	printf("Doing ede ecb\n");
        +	for (i=0; i<(NUM_TESTS-2); i++)
        +		{
        +		DES_set_key_unchecked(&key_data[i],&ks);
        +		DES_set_key_unchecked(&key_data[i+1],&ks2);
        +		DES_set_key_unchecked(&key_data[i+2],&ks3);
        +		memcpy(in,plain_data[i],8);
        +		memset(out,0,8);
        +		memset(outin,0,8);
        +		des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
        +		des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);
        +
        +		if (memcmp(out,cipher_ecb2[i],8) != 0)
        +			{
        +			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
        +				pt(out));
        +			err=1;
        +			}
        +		if (memcmp(in,outin,8) != 0)
        +			{
        +			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
        +			err=1;
        +			}
        +		}
        +#endif
        +
        +	printf("Doing cbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_ncbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,DES_ENCRYPT);
        +	if (memcmp(cbc_out,cbc_ok,32) != 0)
        +		{
        +		printf("cbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_ncbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
        +		{
        +		printf("cbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +#ifndef LIBDES_LIT
        +	printf("Doing desx cbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_xcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
        +	if (memcmp(cbc_out,xcbc_ok,32) != 0)
        +		{
        +		printf("des_xcbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_xcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		printf("des_xcbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +#endif
        +
        +	printf("Doing ede cbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	i=strlen((char *)cbc_data)+1;
        +	/* i=((i+7)/8)*8; */
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +
        +	des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,
        +			     DES_ENCRYPT);
        +	des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3,
        +			     &iv3,DES_ENCRYPT);
        +	if (memcmp(cbc_out,cbc3_ok,
        +		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
        +		{
        +		unsigned int n;
        +
        +		printf("des_ede3_cbc_encrypt encrypt error\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_out[n]);
        +		printf("\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc3_ok[n]);
        +		printf("\n");
        +		err=1;
        +		}
        +
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		unsigned int n;
        +
        +		printf("des_ede3_cbc_encrypt decrypt error\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_data[n]);
        +		printf("\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_in[n]);
        +		printf("\n");
        +		err=1;
        +		}
        +
        +#ifndef LIBDES_LIT
        +	printf("Doing pcbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	des_pcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
        +			 &cbc_iv,DES_ENCRYPT);
        +	if (memcmp(cbc_out,pcbc_ok,32) != 0)
        +		{
        +		printf("pcbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	des_pcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,&cbc_iv,
        +			 DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		printf("pcbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("Doing ");
        +	printf("cfb8 ");
        +	err+=cfb_test(8,cfb_cipher8);
        +	printf("cfb16 ");
        +	err+=cfb_test(16,cfb_cipher16);
        +	printf("cfb32 ");
        +	err+=cfb_test(32,cfb_cipher32);
        +	printf("cfb48 ");
        +	err+=cfb_test(48,cfb_cipher48);
        +	printf("cfb64 ");
        +	err+=cfb_test(64,cfb_cipher64);
        +
        +	printf("cfb64() ");
        +	err+=cfb64_test(cfb_cipher64);
        +
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	for (i=0; i<sizeof(plain); i++)
        +		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
        +			8,1,ks,&cfb_tmp,DES_ENCRYPT);
        +	if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		printf("cfb_encrypt small encrypt error\n");
        +		err=1;
        +		}
        +
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	for (i=0; i<sizeof(plain); i++)
        +		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
        +			8,1,ks,&cfb_tmp,DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		printf("cfb_encrypt small decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("ede_cfb64() ");
        +	err+=ede_cfb64_test(cfb_cipher64);
        +
        +	printf("done\n");
        +
        +	printf("Doing ofb\n");
        +	DES_set_key_checked(&ofb_key,&ks);
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp);
        +	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
        +		{
        +		printf("ofb_encrypt encrypt error\n");
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
        +ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
        +ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
        +		err=1;
        +		}
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp);
        +	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
        +		{
        +		printf("ofb_encrypt decrypt error\n");
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
        +ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +plain[8+0], plain[8+1], plain[8+2], plain[8+3],
        +plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
        +		err=1;
        +		}
        +
        +	printf("Doing ofb64\n");
        +	DES_set_key_checked(&ofb_key,&ks);
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	memset(ofb_buf1,0,sizeof(ofb_buf1));
        +	memset(ofb_buf2,0,sizeof(ofb_buf1));
        +	num=0;
        +	for (i=0; i<sizeof(plain); i++)
        +		{
        +		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,&ofb_tmp,
        +				  &num);
        +		}
        +	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
        +		{
        +		printf("ofb64_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	num=0;
        +	des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp,
        +			  &num);
        +	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
        +		{
        +		printf("ofb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("Doing ede_ofb64\n");
        +	DES_set_key_checked(&ofb_key,&ks);
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	memset(ofb_buf1,0,sizeof(ofb_buf1));
        +	memset(ofb_buf2,0,sizeof(ofb_buf1));
        +	num=0;
        +	for (i=0; i<sizeof(plain); i++)
        +		{
        +		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,
        +				       ks,&ofb_tmp,&num);
        +		}
        +	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
        +		{
        +		printf("ede_ofb64_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	num=0;
        +	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,ks,ks,
        +			       &ofb_tmp,&num);
        +	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
        +		{
        +		printf("ede_ofb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("Doing cbc_cksum\n");
        +	DES_set_key_checked(&cbc_key,&ks);
        +	cs=des_cbc_cksum(cbc_data,&cret,strlen((char *)cbc_data),ks,&cbc_iv);
        +	if (cs != cbc_cksum_ret)
        +		{
        +		printf("bad return value (%08lX), should be %08lX\n",
        +			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
        +		err=1;
        +		}
        +	if (memcmp(cret,cbc_cksum_data,8) != 0)
        +		{
        +		printf("bad cbc_cksum block returned\n");
        +		err=1;
        +		}
        +
        +	printf("Doing quad_cksum\n");
        +	cs=des_quad_cksum(cbc_data,(des_cblock *)lqret,
        +		(long)strlen((char *)cbc_data),2,(des_cblock *)cbc_iv);
        +	if (cs != 0x70d7a63aL)
        +		{
        +		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
        +			(unsigned long)cs);
        +		err=1;
        +		}
        +#ifdef _CRAY
        +	if (lqret[0].a != 0x327eba8dL)
        +		{
        +		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
        +			(unsigned long)lqret[0].a,0x327eba8dUL);
        +		err=1;
        +		}
        +	if (lqret[0].b != 0x201a49ccL)
        +		{
        +		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
        +			(unsigned long)lqret[0].b,0x201a49ccUL);
        +		err=1;
        +		}
        +	if (lqret[1].a != 0x70d7a63aL)
        +		{
        +		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
        +			(unsigned long)lqret[1].a,0x70d7a63aUL);
        +		err=1;
        +		}
        +	if (lqret[1].b != 0x501c2c26L)
        +		{
        +		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
        +			(unsigned long)lqret[1].b,0x501c2c26UL);
        +		err=1;
        +		}
        +#else
        +	if (lqret[0] != 0x327eba8dL)
        +		{
        +		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
        +			(unsigned long)lqret[0],0x327eba8dUL);
        +		err=1;
        +		}
        +	if (lqret[1] != 0x201a49ccL)
        +		{
        +		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
        +			(unsigned long)lqret[1],0x201a49ccUL);
        +		err=1;
        +		}
        +	if (lqret[2] != 0x70d7a63aL)
        +		{
        +		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
        +			(unsigned long)lqret[2],0x70d7a63aUL);
        +		err=1;
        +		}
        +	if (lqret[3] != 0x501c2c26L)
        +		{
        +		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
        +			(unsigned long)lqret[3],0x501c2c26UL);
        +		err=1;
        +		}
        +#endif
        +#endif
        +
        +	printf("input word alignment test");
        +	for (i=0; i<4; i++)
        +		{
        +		printf(" %d",i);
        +		des_ncbc_encrypt(&(cbc_out[i]),cbc_in,
        +				 strlen((char *)cbc_data)+1,ks,
        +				 &cbc_iv,DES_ENCRYPT);
        +		}
        +	printf("\noutput word alignment test");
        +	for (i=0; i<4; i++)
        +		{
        +		printf(" %d",i);
        +		des_ncbc_encrypt(cbc_out,&(cbc_in[i]),
        +				 strlen((char *)cbc_data)+1,ks,
        +				 &cbc_iv,DES_ENCRYPT);
        +		}
        +	printf("\n");
        +	printf("fast crypt test ");
        +	str=crypt("testing","ef");
        +	if (strcmp("efGnQx2725bI2",str) != 0)
        +		{
        +		printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
        +		err=1;
        +		}
        +	str=crypt("bca76;23","yA");
        +	if (strcmp("yA1Rp/1hZXIJk",str) != 0)
        +		{
        +		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
        +		err=1;
        +		}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	printf("\n");
        +	return(err);
        +	}
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +
        +#ifndef LIBDES_LIT
        +
        +static int cfb_test(int bits, unsigned char *cfb_cipher)
        +	{
        +	des_key_schedule ks;
        +	int i,err=0;
        +
        +	DES_set_key_checked(&cfb_key,&ks);
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	des_cfb_encrypt(plain,cfb_buf1,bits,sizeof(plain),ks,&cfb_tmp,
        +			DES_ENCRYPT);
        +	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt encrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,sizeof(plain),ks,&cfb_tmp,
        +			DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt decrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	return(err);
        +	}
        +
        +static int cfb64_test(unsigned char *cfb_cipher)
        +	{
        +	des_key_schedule ks;
        +	int err=0,i,n;
        +
        +	DES_set_key_checked(&cfb_key,&ks);
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_cfb64_encrypt(plain,cfb_buf1,12,ks,&cfb_tmp,&n,DES_ENCRYPT);
        +	des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),sizeof(plain)-12,ks,
        +			  &cfb_tmp,&n,DES_ENCRYPT);
        +	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt encrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_cfb64_encrypt(cfb_buf1,cfb_buf2,17,ks,&cfb_tmp,&n,DES_DECRYPT);
        +	des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +			  sizeof(plain)-17,ks,&cfb_tmp,&n,DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt decrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf2[i])));
        +		}
        +	return(err);
        +	}
        +
        +static int ede_cfb64_test(unsigned char *cfb_cipher)
        +	{
        +	des_key_schedule ks;
        +	int err=0,i,n;
        +
        +	DES_set_key_checked(&cfb_key,&ks);
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_ede3_cfb64_encrypt(plain,cfb_buf1,12,ks,ks,ks,&cfb_tmp,&n,
        +			       DES_ENCRYPT);
        +	des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +			       sizeof(plain)-12,ks,ks,ks,
        +			       &cfb_tmp,&n,DES_ENCRYPT);
        +	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("ede_cfb_encrypt encrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
        +			       &cfb_tmp,&n,DES_DECRYPT);
        +	des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +			       sizeof(plain)-17,ks,ks,ks,
        +			       &cfb_tmp,&n,DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("ede_cfb_encrypt decrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf2[i])));
        +		}
        +	return(err);
        +	}
        +
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/des/ecb3_enc.c b/vendor/openssl/openssl/crypto/des/ecb3_enc.c
        new file mode 100644
        index 000000000..c3437bc60
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ecb3_enc.c
        @@ -0,0 +1,83 @@
        +/* crypto/des/ecb3_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +
        +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
        +		      DES_key_schedule *ks1, DES_key_schedule *ks2,
        +		      DES_key_schedule *ks3,
        +	     int enc)
        +	{
        +	register DES_LONG l0,l1;
        +	DES_LONG ll[2];
        +	const unsigned char *in = &(*input)[0];
        +	unsigned char *out = &(*output)[0];
        +
        +	c2l(in,l0);
        +	c2l(in,l1);
        +	ll[0]=l0;
        +	ll[1]=l1;
        +	if (enc)
        +		DES_encrypt3(ll,ks1,ks2,ks3);
        +	else
        +		DES_decrypt3(ll,ks1,ks2,ks3);
        +	l0=ll[0];
        +	l1=ll[1];
        +	l2c(l0,out);
        +	l2c(l1,out);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/ecb_enc.c b/vendor/openssl/openssl/crypto/des/ecb_enc.c
        new file mode 100644
        index 000000000..0684e769b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ecb_enc.c
        @@ -0,0 +1,122 @@
        +/* crypto/des/ecb_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +#include "des_ver.h"
        +#include <openssl/opensslv.h>
        +#include <openssl/bio.h>
        +
        +OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
        +OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
        +
        +const char *DES_options(void)
        +	{
        +	static int init=1;
        +	static char buf[32];
        +
        +	if (init)
        +		{
        +		const char *ptr,*unroll,*risc,*size;
        +
        +#ifdef DES_PTR
        +		ptr="ptr";
        +#else
        +		ptr="idx";
        +#endif
        +#if defined(DES_RISC1) || defined(DES_RISC2)
        +#ifdef DES_RISC1
        +		risc="risc1";
        +#endif
        +#ifdef DES_RISC2
        +		risc="risc2";
        +#endif
        +#else
        +		risc="cisc";
        +#endif
        +#ifdef DES_UNROLL
        +		unroll="16";
        +#else
        +		unroll="2";
        +#endif
        +		if (sizeof(DES_LONG) != sizeof(long))
        +			size="int";
        +		else
        +			size="long";
        +		BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
        +			     size);
        +		init=0;
        +		}
        +	return(buf);
        +	}
        +		
        +
        +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
        +		     DES_key_schedule *ks, int enc)
        +	{
        +	register DES_LONG l;
        +	DES_LONG ll[2];
        +	const unsigned char *in = &(*input)[0];
        +	unsigned char *out = &(*output)[0];
        +
        +	c2l(in,l); ll[0]=l;
        +	c2l(in,l); ll[1]=l;
        +	DES_encrypt1(ll,ks,enc);
        +	l=ll[0]; l2c(l,out);
        +	l=ll[1]; l2c(l,out);
        +	l=ll[0]=ll[1]=0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/ede_cbcm_enc.c b/vendor/openssl/openssl/crypto/des/ede_cbcm_enc.c
        new file mode 100644
        index 000000000..adfcb75cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ede_cbcm_enc.c
        @@ -0,0 +1,199 @@
        +/* ede_cbcm_enc.c */
        +/* Written by Ben Laurie <ben@algroup.co.uk> for the OpenSSL
        + * project 13 Feb 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +/*
        +
        +This is an implementation of Triple DES Cipher Block Chaining with Output
        +Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom).
        +
        +Note that there is a known attack on this by Biham and Knudsen but it takes
        +a lot of work:
        +
        +http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz
        +
        +*/
        +
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_DESCBCM is defined */
        +
        +#ifndef OPENSSL_NO_DESCBCM
        +#include "des_locl.h"
        +
        +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out,
        +	     long length, DES_key_schedule *ks1, DES_key_schedule *ks2,
        +	     DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2,
        +	     int enc)
        +    {
        +    register DES_LONG tin0,tin1;
        +    register DES_LONG tout0,tout1,xor0,xor1,m0,m1;
        +    register long l=length;
        +    DES_LONG tin[2];
        +    unsigned char *iv1,*iv2;
        +
        +    iv1 = &(*ivec1)[0];
        +    iv2 = &(*ivec2)[0];
        +
        +    if (enc)
        +	{
        +	c2l(iv1,m0);
        +	c2l(iv1,m1);
        +	c2l(iv2,tout0);
        +	c2l(iv2,tout1);
        +	for (l-=8; l>=-7; l-=8)
        +	    {
        +	    tin[0]=m0;
        +	    tin[1]=m1;
        +	    DES_encrypt1(tin,ks3,1);
        +	    m0=tin[0];
        +	    m1=tin[1];
        +
        +	    if(l < 0)
        +		{
        +		c2ln(in,tin0,tin1,l+8);
        +		}
        +	    else
        +		{
        +		c2l(in,tin0);
        +		c2l(in,tin1);
        +		}
        +	    tin0^=tout0;
        +	    tin1^=tout1;
        +
        +	    tin[0]=tin0;
        +	    tin[1]=tin1;
        +	    DES_encrypt1(tin,ks1,1);
        +	    tin[0]^=m0;
        +	    tin[1]^=m1;
        +	    DES_encrypt1(tin,ks2,0);
        +	    tin[0]^=m0;
        +	    tin[1]^=m1;
        +	    DES_encrypt1(tin,ks1,1);
        +	    tout0=tin[0];
        +	    tout1=tin[1];
        +
        +	    l2c(tout0,out);
        +	    l2c(tout1,out);
        +	    }
        +	iv1=&(*ivec1)[0];
        +	l2c(m0,iv1);
        +	l2c(m1,iv1);
        +
        +	iv2=&(*ivec2)[0];
        +	l2c(tout0,iv2);
        +	l2c(tout1,iv2);
        +	}
        +    else
        +	{
        +	register DES_LONG t0,t1;
        +
        +	c2l(iv1,m0);
        +	c2l(iv1,m1);
        +	c2l(iv2,xor0);
        +	c2l(iv2,xor1);
        +	for (l-=8; l>=-7; l-=8)
        +	    {
        +	    tin[0]=m0;
        +	    tin[1]=m1;
        +	    DES_encrypt1(tin,ks3,1);
        +	    m0=tin[0];
        +	    m1=tin[1];
        +
        +	    c2l(in,tin0);
        +	    c2l(in,tin1);
        +
        +	    t0=tin0;
        +	    t1=tin1;
        +
        +	    tin[0]=tin0;
        +	    tin[1]=tin1;
        +	    DES_encrypt1(tin,ks1,0);
        +	    tin[0]^=m0;
        +	    tin[1]^=m1;
        +	    DES_encrypt1(tin,ks2,1);
        +	    tin[0]^=m0;
        +	    tin[1]^=m1;
        +	    DES_encrypt1(tin,ks1,0);
        +	    tout0=tin[0];
        +	    tout1=tin[1];
        +
        +	    tout0^=xor0;
        +	    tout1^=xor1;
        +	    if(l < 0)
        +		{
        +		l2cn(tout0,tout1,out,l+8);
        +		}
        +	    else
        +		{
        +		l2c(tout0,out);
        +		l2c(tout1,out);
        +		}
        +	    xor0=t0;
        +	    xor1=t1;
        +	    }
        +
        +	iv1=&(*ivec1)[0];
        +	l2c(m0,iv1);
        +	l2c(m1,iv1);
        +
        +	iv2=&(*ivec2)[0];
        +	l2c(xor0,iv2);
        +	l2c(xor1,iv2);
        +	}
        +    tin0=tin1=tout0=tout1=xor0=xor1=0;
        +    tin[0]=tin[1]=0;
        +    }
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/des/enc_read.c b/vendor/openssl/openssl/crypto/des/enc_read.c
        new file mode 100644
        index 000000000..edb6620d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/enc_read.c
        @@ -0,0 +1,240 @@
        +/* crypto/des/enc_read.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include "des_locl.h"
        +
        +/* This has some uglies in it but it works - even over sockets. */
        +/*extern int errno;*/
        +OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode,DES_PCBC_MODE)
        +
        +
        +/*
        + * WARNINGS:
        + *
        + *  -  The data format used by DES_enc_write() and DES_enc_read()
        + *     has a cryptographic weakness: When asked to write more
        + *     than MAXWRITE bytes, DES_enc_write will split the data
        + *     into several chunks that are all encrypted
        + *     using the same IV.  So don't use these functions unless you
        + *     are sure you know what you do (in which case you might
        + *     not want to use them anyway).
        + *
        + *  -  This code cannot handle non-blocking sockets.
        + *
        + *  -  This function uses an internal state and thus cannot be
        + *     used on multiple files.
        + */
        +
        +
        +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
        +		 DES_cblock *iv)
        +	{
        +#if defined(OPENSSL_NO_POSIX_IO)
        +	return(0);
        +#else
        +	/* data to be unencrypted */
        +	int net_num=0;
        +	static unsigned char *net=NULL;
        +	/* extra unencrypted data 
        +	 * for when a block of 100 comes in but is des_read one byte at
        +	 * a time. */
        +	static unsigned char *unnet=NULL;
        +	static int unnet_start=0;
        +	static int unnet_left=0;
        +	static unsigned char *tmpbuf=NULL;
        +	int i;
        +	long num=0,rnum;
        +	unsigned char *p;
        +
        +	if (tmpbuf == NULL)
        +		{
        +		tmpbuf=OPENSSL_malloc(BSIZE);
        +		if (tmpbuf == NULL) return(-1);
        +		}
        +	if (net == NULL)
        +		{
        +		net=OPENSSL_malloc(BSIZE);
        +		if (net == NULL) return(-1);
        +		}
        +	if (unnet == NULL)
        +		{
        +		unnet=OPENSSL_malloc(BSIZE);
        +		if (unnet == NULL) return(-1);
        +		}
        +	/* left over data from last decrypt */
        +	if (unnet_left != 0)
        +		{
        +		if (unnet_left < len)
        +			{
        +			/* we still still need more data but will return
        +			 * with the number of bytes we have - should always
        +			 * check the return value */
        +			memcpy(buf,&(unnet[unnet_start]),
        +			       unnet_left);
        +			/* eay 26/08/92 I had the next 2 lines
        +			 * reversed :-( */
        +			i=unnet_left;
        +			unnet_start=unnet_left=0;
        +			}
        +		else
        +			{
        +			memcpy(buf,&(unnet[unnet_start]),len);
        +			unnet_start+=len;
        +			unnet_left-=len;
        +			i=len;
        +			}
        +		return(i);
        +		}
        +
        +	/* We need to get more data. */
        +	if (len > MAXWRITE) len=MAXWRITE;
        +
        +	/* first - get the length */
        +	while (net_num < HDRSIZE) 
        +		{
        +#ifndef OPENSSL_SYS_WIN32
        +		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
        +#else
        +		i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
        +#endif
        +#ifdef EINTR
        +		if ((i == -1) && (errno == EINTR)) continue;
        +#endif
        +		if (i <= 0) return(0);
        +		net_num+=i;
        +		}
        +
        +	/* we now have at net_num bytes in net */
        +	p=net;
        +	/* num=0;  */
        +	n2l(p,num);
        +	/* num should be rounded up to the next group of eight
        +	 * we make sure that we have read a multiple of 8 bytes from the net.
        +	 */
        +	if ((num > MAXWRITE) || (num < 0)) /* error */
        +		return(-1);
        +	rnum=(num < 8)?8:((num+7)/8*8);
        +
        +	net_num=0;
        +	while (net_num < rnum)
        +		{
        +#ifndef OPENSSL_SYS_WIN32
        +		i=read(fd,(void *)&(net[net_num]),rnum-net_num);
        +#else
        +		i=_read(fd,(void *)&(net[net_num]),rnum-net_num);
        +#endif
        +#ifdef EINTR
        +		if ((i == -1) && (errno == EINTR)) continue;
        +#endif
        +		if (i <= 0) return(0);
        +		net_num+=i;
        +		}
        +
        +	/* Check if there will be data left over. */
        +	if (len < num)
        +		{
        +		if (DES_rw_mode & DES_PCBC_MODE)
        +			DES_pcbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
        +		else
        +			DES_cbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
        +		memcpy(buf,unnet,len);
        +		unnet_start=len;
        +		unnet_left=num-len;
        +
        +		/* The following line is done because we return num
        +		 * as the number of bytes read. */
        +		num=len;
        +		}
        +	else
        +		{
        +		/* >output is a multiple of 8 byes, if len < rnum
        +		 * >we must be careful.  The user must be aware that this
        +		 * >routine will write more bytes than he asked for.
        +		 * >The length of the buffer must be correct.
        +		 * FIXED - Should be ok now 18-9-90 - eay */
        +		if (len < rnum)
        +			{
        +
        +			if (DES_rw_mode & DES_PCBC_MODE)
        +				DES_pcbc_encrypt(net,tmpbuf,num,sched,iv,
        +						 DES_DECRYPT);
        +			else
        +				DES_cbc_encrypt(net,tmpbuf,num,sched,iv,
        +						DES_DECRYPT);
        +
        +			/* eay 26/08/92 fix a bug that returned more
        +			 * bytes than you asked for (returned len bytes :-( */
        +			memcpy(buf,tmpbuf,num);
        +			}
        +		else
        +			{
        +			if (DES_rw_mode & DES_PCBC_MODE)
        +				DES_pcbc_encrypt(net,buf,num,sched,iv,
        +						 DES_DECRYPT);
        +			else
        +				DES_cbc_encrypt(net,buf,num,sched,iv,
        +						DES_DECRYPT);
        +			}
        +		}
        +	return num;
        +#endif /* OPENSSL_NO_POSIX_IO */
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/enc_writ.c b/vendor/openssl/openssl/crypto/des/enc_writ.c
        new file mode 100644
        index 000000000..2353ac1e8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/enc_writ.c
        @@ -0,0 +1,179 @@
        +/* crypto/des/enc_writ.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 <errno.h>
        +#include <time.h>
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include "des_locl.h"
        +#include <openssl/rand.h>
        +
        +/*
        + * WARNINGS:
        + *
        + *  -  The data format used by DES_enc_write() and DES_enc_read()
        + *     has a cryptographic weakness: When asked to write more
        + *     than MAXWRITE bytes, DES_enc_write will split the data
        + *     into several chunks that are all encrypted
        + *     using the same IV.  So don't use these functions unless you
        + *     are sure you know what you do (in which case you might
        + *     not want to use them anyway).
        + *
        + *  -  This code cannot handle non-blocking sockets.
        + */
        +
        +int DES_enc_write(int fd, const void *_buf, int len,
        +		  DES_key_schedule *sched, DES_cblock *iv)
        +	{
        +#if defined(OPENSSL_NO_POSIX_IO)
        +	return (-1);
        +#else
        +#ifdef _LIBC
        +	extern unsigned long time();
        +	extern int write();
        +#endif
        +	const unsigned char *buf=_buf;
        +	long rnum;
        +	int i,j,k,outnum;
        +	static unsigned char *outbuf=NULL;
        +	unsigned char shortbuf[8];
        +	unsigned char *p;
        +	const unsigned char *cp;
        +	static int start=1;
        +
        +	if (outbuf == NULL)
        +		{
        +		outbuf=OPENSSL_malloc(BSIZE+HDRSIZE);
        +		if (outbuf == NULL) return(-1);
        +		}
        +	/* If we are sending less than 8 bytes, the same char will look
        +	 * the same if we don't pad it out with random bytes */
        +	if (start)
        +		{
        +		start=0;
        +		}
        +
        +	/* lets recurse if we want to send the data in small chunks */
        +	if (len > MAXWRITE)
        +		{
        +		j=0;
        +		for (i=0; i<len; i+=k)
        +			{
        +			k=DES_enc_write(fd,&(buf[i]),
        +				((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);
        +			if (k < 0)
        +				return(k);
        +			else
        +				j+=k;
        +			}
        +		return(j);
        +		}
        +
        +	/* write length first */
        +	p=outbuf;
        +	l2n(len,p);
        +
        +	/* pad short strings */
        +	if (len < 8)
        +		{
        +		cp=shortbuf;
        +		memcpy(shortbuf,buf,len);
        +		RAND_pseudo_bytes(shortbuf+len, 8-len);
        +		rnum=8;
        +		}
        +	else
        +		{
        +		cp=buf;
        +		rnum=((len+7)/8*8); /* round up to nearest eight */
        +		}
        +
        +	if (DES_rw_mode & DES_PCBC_MODE)
        +		DES_pcbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv,
        +				 DES_ENCRYPT); 
        +	else
        +		DES_cbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv,
        +				DES_ENCRYPT); 
        +
        +	/* output */
        +	outnum=rnum+HDRSIZE;
        +
        +	for (j=0; j<outnum; j+=i)
        +		{
        +		/* eay 26/08/92 I was not doing writing from where we
        +		 * got up to. */
        +#ifndef _WIN32
        +		i=write(fd,(void *)&(outbuf[j]),outnum-j);
        +#else
        +		i=_write(fd,(void *)&(outbuf[j]),outnum-j);
        +#endif
        +		if (i == -1)
        +			{
        +#ifdef EINTR
        +			if (errno == EINTR)
        +				i=0;
        +			else
        +#endif
        +			        /* This is really a bad error - very bad
        +				 * It will stuff-up both ends. */
        +				return(-1);
        +			}
        +		}
        +
        +	return(len);
        +#endif /* OPENSSL_NO_POSIX_IO */
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/fcrypt.c b/vendor/openssl/openssl/crypto/des/fcrypt.c
        new file mode 100644
        index 000000000..ccbdff250
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/fcrypt.c
        @@ -0,0 +1,170 @@
        +/* NOCW */
        +#include <stdio.h>
        +#ifdef _OSD_POSIX
        +#ifndef CHARSET_EBCDIC
        +#define CHARSET_EBCDIC 1
        +#endif
        +#endif
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +/* This version of crypt has been developed from my MIT compatible
        + * DES library.
        + * Eric Young (eay@cryptsoft.com)
        + */
        +
        +/* Modification by Jens Kupferschmidt (Cu)
        + * I have included directive PARA for shared memory computers.
        + * I have included a directive LONGCRYPT to using this routine to cipher
        + * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
        + * definition is the maximum of length of password and can changed. I have
        + * defined 24.
        + */
        +
        +#include "des_locl.h"
        +
        +/* Added more values to handle illegal salt values the way normal
        + * crypt() implementations do.  The patch was sent by 
        + * Bjorn Gronvall <bg@sics.se>
        + */
        +static unsigned const char con_salt[128]={
        +0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
        +0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
        +0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
        +0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
        +0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
        +0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
        +0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
        +0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
        +0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
        +0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
        +0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
        +0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
        +0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
        +0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
        +0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
        +0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
        +};
        +
        +static unsigned const char cov_2char[64]={
        +0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
        +0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
        +0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
        +0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
        +0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
        +0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
        +0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
        +0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
        +};
        +
        +char *DES_crypt(const char *buf, const char *salt)
        +	{
        +	static char buff[14];
        +
        +#ifndef CHARSET_EBCDIC
        +	return(DES_fcrypt(buf,salt,buff));
        +#else
        +	char e_salt[2+1];
        +	char e_buf[32+1];	/* replace 32 by 8 ? */
        +	char *ret;
        +
        +	/* Copy at most 2 chars of salt */
        +	if ((e_salt[0] = salt[0]) != '\0')
        +	    e_salt[1] = salt[1];
        +
        +	/* Copy at most 32 chars of password */
        +	strncpy (e_buf, buf, sizeof(e_buf));
        +
        +	/* Make sure we have a delimiter */
        +	e_salt[sizeof(e_salt)-1] = e_buf[sizeof(e_buf)-1] = '\0';
        +
        +	/* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */
        +	ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
        +
        +	/* Convert the cleartext password to ASCII */
        +	ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
        +
        +	/* Encrypt it (from/to ASCII) */
        +	ret = DES_fcrypt(e_buf,e_salt,buff);
        +
        +	/* Convert the result back to EBCDIC */
        +	ascii2ebcdic(ret, ret, strlen(ret));
        +	
        +	return ret;
        +#endif
        +	}
        +
        +
        +char *DES_fcrypt(const char *buf, const char *salt, char *ret)
        +	{
        +	unsigned int i,j,x,y;
        +	DES_LONG Eswap0,Eswap1;
        +	DES_LONG out[2],ll;
        +	DES_cblock key;
        +	DES_key_schedule ks;
        +	unsigned char bb[9];
        +	unsigned char *b=bb;
        +	unsigned char c,u;
        +
        +	/* eay 25/08/92
        +	 * If you call crypt("pwd","*") as often happens when you
        +	 * have * as the pwd field in /etc/passwd, the function
        +	 * returns *\0XXXXXXXXX
        +	 * The \0 makes the string look like * so the pwd "*" would
        +	 * crypt to "*".  This was found when replacing the crypt in
        +	 * our shared libraries.  People found that the disabled
        +	 * accounts effectively had no passwd :-(. */
        +#ifndef CHARSET_EBCDIC
        +	x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
        +	Eswap0=con_salt[x]<<2;
        +	x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
        +	Eswap1=con_salt[x]<<6;
        +#else
        +	x=ret[0]=((salt[0] == '\0')?os_toascii['A']:salt[0]);
        +	Eswap0=con_salt[x]<<2;
        +	x=ret[1]=((salt[1] == '\0')?os_toascii['A']:salt[1]);
        +	Eswap1=con_salt[x]<<6;
        +#endif
        +
        +/* EAY
        +r=strlen(buf);
        +r=(r+7)/8;
        +*/
        +	for (i=0; i<8; i++)
        +		{
        +		c= *(buf++);
        +		if (!c) break;
        +		key[i]=(c<<1);
        +		}
        +	for (; i<8; i++)
        +		key[i]=0;
        +
        +	DES_set_key_unchecked(&key,&ks);
        +	fcrypt_body(&(out[0]),&ks,Eswap0,Eswap1);
        +
        +	ll=out[0]; l2c(ll,b);
        +	ll=out[1]; l2c(ll,b);
        +	y=0;
        +	u=0x80;
        +	bb[8]=0;
        +	for (i=2; i<13; i++)
        +		{
        +		c=0;
        +		for (j=0; j<6; j++)
        +			{
        +			c<<=1;
        +			if (bb[y] & u) c|=1;
        +			u>>=1;
        +			if (!u)
        +				{
        +				y++;
        +				u=0x80;
        +				}
        +			}
        +		ret[i]=cov_2char[c];
        +		}
        +	ret[13]='\0';
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/fcrypt_b.c b/vendor/openssl/openssl/crypto/des/fcrypt_b.c
        new file mode 100644
        index 000000000..882281693
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/fcrypt_b.c
        @@ -0,0 +1,143 @@
        +/* crypto/des/fcrypt_b.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +
        +/* This version of crypt has been developed from my MIT compatible
        + * DES library.
        + * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
        + * Eric Young (eay@cryptsoft.com)
        + */
        +
        +#define DES_FCRYPT
        +#include "des_locl.h"
        +#undef DES_FCRYPT
        +
        +#undef PERM_OP
        +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
        +	(b)^=(t),\
        +	(a)^=((t)<<(n)))
        +
        +#undef HPERM_OP
        +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
        +	(a)=(a)^(t)^(t>>(16-(n))))\
        +
        +void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
        +		 DES_LONG Eswap1)
        +	{
        +	register DES_LONG l,r,t,u;
        +#ifdef DES_PTR
        +	register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
        +#endif
        +	register DES_LONG *s;
        +	register int j;
        +	register DES_LONG E0,E1;
        +
        +	l=0;
        +	r=0;
        +
        +	s=(DES_LONG *)ks;
        +	E0=Eswap0;
        +	E1=Eswap1;
        +
        +	for (j=0; j<25; j++)
        +		{
        +#ifndef DES_UNROLL
        +		register int i;
        +
        +		for (i=0; i<32; i+=4)
        +			{
        +			D_ENCRYPT(l,r,i+0); /*  1 */
        +			D_ENCRYPT(r,l,i+2); /*  2 */
        +			}
        +#else
        +		D_ENCRYPT(l,r, 0); /*  1 */
        +		D_ENCRYPT(r,l, 2); /*  2 */
        +		D_ENCRYPT(l,r, 4); /*  3 */
        +		D_ENCRYPT(r,l, 6); /*  4 */
        +		D_ENCRYPT(l,r, 8); /*  5 */
        +		D_ENCRYPT(r,l,10); /*  6 */
        +		D_ENCRYPT(l,r,12); /*  7 */
        +		D_ENCRYPT(r,l,14); /*  8 */
        +		D_ENCRYPT(l,r,16); /*  9 */
        +		D_ENCRYPT(r,l,18); /*  10 */
        +		D_ENCRYPT(l,r,20); /*  11 */
        +		D_ENCRYPT(r,l,22); /*  12 */
        +		D_ENCRYPT(l,r,24); /*  13 */
        +		D_ENCRYPT(r,l,26); /*  14 */
        +		D_ENCRYPT(l,r,28); /*  15 */
        +		D_ENCRYPT(r,l,30); /*  16 */
        +#endif
        +
        +		t=l;
        +		l=r;
        +		r=t;
        +		}
        +	l=ROTATE(l,3)&0xffffffffL;
        +	r=ROTATE(r,3)&0xffffffffL;
        +
        +	PERM_OP(l,r,t, 1,0x55555555L);
        +	PERM_OP(r,l,t, 8,0x00ff00ffL);
        +	PERM_OP(l,r,t, 2,0x33333333L);
        +	PERM_OP(r,l,t,16,0x0000ffffL);
        +	PERM_OP(l,r,t, 4,0x0f0f0f0fL);
        +
        +	out[0]=r;
        +	out[1]=l;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/makefile.bc b/vendor/openssl/openssl/crypto/des/makefile.bc
        new file mode 100644
        index 000000000..1fe6d4915
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/makefile.bc
        @@ -0,0 +1,50 @@
        +#
        +# Origional BC Makefile from Teun <Teun.Nijssen@kub.nl>
        +#
        +#
        +CC      = bcc
        +TLIB    = tlib /0 /C
        +# note: the -3 flag produces code for 386, 486, Pentium etc; omit it for 286s
        +OPTIMIZE= -3 -O2
        +#WINDOWS= -W
        +CFLAGS  = -c -ml -d $(OPTIMIZE) $(WINDOWS) -DMSDOS
        +LFLAGS  = -ml $(WINDOWS)
        +
        +.c.obj:
        +	$(CC) $(CFLAGS) $*.c
        +
        +.obj.exe:
        +	$(CC) $(LFLAGS) -e$*.exe $*.obj libdes.lib  
        +
        +all: $(LIB) destest.exe rpw.exe des.exe speed.exe
        +
        +# "make clean": use a directory containing only libdes .exe and .obj files...
        +clean:
        +	del *.exe
        +	del *.obj
        +	del libdes.lib
        +	del libdes.rsp
        +
        +OBJS=   cbc_cksm.obj cbc_enc.obj  ecb_enc.obj  pcbc_enc.obj \
        +	qud_cksm.obj rand_key.obj set_key.obj  str2key.obj \
        +	enc_read.obj enc_writ.obj fcrypt.obj   cfb_enc.obj \
        +	ecb3_enc.obj ofb_enc.obj  cbc3_enc.obj read_pwd.obj\
        +	cfb64enc.obj ofb64enc.obj ede_enc.obj  cfb64ede.obj\
        +	ofb64ede.obj supp.obj
        +
        +LIB=    libdes.lib
        +
        +$(LIB): $(OBJS)
        +	del $(LIB)
        +	makersp "+%s &\n" &&|
        +	$(OBJS)
        +|       >libdes.rsp
        +	$(TLIB) libdes.lib @libdes.rsp,nul
        +	del libdes.rsp
        +
        +destest.exe: destest.obj libdes.lib
        +rpw.exe:     rpw.obj libdes.lib
        +speed.exe:   speed.obj libdes.lib
        +des.exe:     des.obj libdes.lib
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/des/ncbc_enc.c b/vendor/openssl/openssl/crypto/des/ncbc_enc.c
        new file mode 100644
        index 000000000..fda23d522
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ncbc_enc.c
        @@ -0,0 +1,148 @@
        +/* crypto/des/ncbc_enc.c */
        +/*
        + * #included by:
        + *    cbc_enc.c  (DES_cbc_encrypt)
        + *    des_enc.c  (DES_ncbc_encrypt)
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +
        +#ifdef CBC_ENC_C__DONT_UPDATE_IV
        +void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +		     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
        +#else
        +void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +		     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
        +#endif
        +	{
        +	register DES_LONG tin0,tin1;
        +	register DES_LONG tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	DES_LONG tin[2];
        +	unsigned char *iv;
        +
        +	iv = &(*ivec)[0];
        +
        +	if (enc)
        +		{
        +		c2l(iv,tout0);
        +		c2l(iv,tout1);
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			tin0^=tout0; tin[0]=tin0;
        +			tin1^=tout1; tin[1]=tin1;
        +			DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
        +			tout0=tin[0]; l2c(tout0,out);
        +			tout1=tin[1]; l2c(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			c2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0; tin[0]=tin0;
        +			tin1^=tout1; tin[1]=tin1;
        +			DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
        +			tout0=tin[0]; l2c(tout0,out);
        +			tout1=tin[1]; l2c(tout1,out);
        +			}
        +#ifndef CBC_ENC_C__DONT_UPDATE_IV
        +		iv = &(*ivec)[0];
        +		l2c(tout0,iv);
        +		l2c(tout1,iv);
        +#endif
        +		}
        +	else
        +		{
        +		c2l(iv,xor0);
        +		c2l(iv,xor1);
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0;
        +			c2l(in,tin1); tin[1]=tin1;
        +			DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0;
        +			c2l(in,tin1); tin[1]=tin1;
        +			DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2cn(tout0,tout1,out,l+8);
        +#ifndef CBC_ENC_C__DONT_UPDATE_IV
        +			xor0=tin0;
        +			xor1=tin1;
        +#endif
        +			}
        +#ifndef CBC_ENC_C__DONT_UPDATE_IV 
        +		iv = &(*ivec)[0];
        +		l2c(xor0,iv);
        +		l2c(xor1,iv);
        +#endif
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/ofb64ede.c b/vendor/openssl/openssl/crypto/des/ofb64ede.c
        new file mode 100644
        index 000000000..26bbf9a6a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ofb64ede.c
        @@ -0,0 +1,125 @@
        +/* crypto/des/ofb64ede.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 "des_locl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void DES_ede3_ofb64_encrypt(register const unsigned char *in,
        +			    register unsigned char *out, long length,
        +			    DES_key_schedule *k1, DES_key_schedule *k2,
        +			    DES_key_schedule *k3, DES_cblock *ivec,
        +			    int *num)
        +	{
        +	register DES_LONG v0,v1;
        +	register int n= *num;
        +	register long l=length;
        +	DES_cblock d;
        +	register char *dp;
        +	DES_LONG ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv = &(*ivec)[0];
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=(char *)d;
        +	l2c(v0,dp);
        +	l2c(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			/* ti[0]=v0; */
        +			/* ti[1]=v1; */
        +			DES_encrypt3(ti,k1,k2,k3);
        +			v0=ti[0];
        +			v1=ti[1];
        +
        +			dp=(char *)d;
        +			l2c(v0,dp);
        +			l2c(v1,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +/*		v0=ti[0];
        +		v1=ti[1];*/
        +		iv = &(*ivec)[0];
        +		l2c(v0,iv);
        +		l2c(v1,iv);
        +		}
        +	v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        +
        +#ifdef undef /* MACRO */
        +void DES_ede2_ofb64_encrypt(register unsigned char *in,
        +	     register unsigned char *out, long length, DES_key_schedule k1,
        +	     DES_key_schedule k2, DES_cblock (*ivec), int *num)
        +	{
        +	DES_ede3_ofb64_encrypt(in, out, length, k1,k2,k1, ivec, num);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/des/ofb64enc.c b/vendor/openssl/openssl/crypto/des/ofb64enc.c
        new file mode 100644
        index 000000000..8ca3d49de
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ofb64enc.c
        @@ -0,0 +1,110 @@
        +/* crypto/des/ofb64enc.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 "des_locl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void DES_ofb64_encrypt(register const unsigned char *in,
        +		       register unsigned char *out, long length,
        +		       DES_key_schedule *schedule, DES_cblock *ivec, int *num)
        +	{
        +	register DES_LONG v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	DES_cblock d;
        +	register unsigned char *dp;
        +	DES_LONG ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv = &(*ivec)[0];
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=d;
        +	l2c(v0,dp);
        +	l2c(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			DES_encrypt1(ti,schedule,DES_ENCRYPT);
        +			dp=d;
        +			t=ti[0]; l2c(t,dp);
        +			t=ti[1]; l2c(t,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +		v0=ti[0];
        +		v1=ti[1];
        +		iv = &(*ivec)[0];
        +		l2c(v0,iv);
        +		l2c(v1,iv);
        +		}
        +	t=v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/ofb_enc.c b/vendor/openssl/openssl/crypto/des/ofb_enc.c
        new file mode 100644
        index 000000000..e887a3c6f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/ofb_enc.c
        @@ -0,0 +1,135 @@
        +/* crypto/des/ofb_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +
        +/* The input and output are loaded in multiples of 8 bits.
        + * What this means is that if you hame numbits=12 and length=2
        + * the first 12 bits will be retrieved from the first byte and half
        + * the second.  The second 12 bits will come from the 3rd and half the 4th
        + * byte.
        + */
        +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
        +		     long length, DES_key_schedule *schedule,
        +		     DES_cblock *ivec)
        +	{
        +	register DES_LONG d0,d1,vv0,vv1,v0,v1,n=(numbits+7)/8;
        +	register DES_LONG mask0,mask1;
        +	register long l=length;
        +	register int num=numbits;
        +	DES_LONG ti[2];
        +	unsigned char *iv;
        +
        +	if (num > 64) return;
        +	if (num > 32)
        +		{
        +		mask0=0xffffffffL;
        +		if (num >= 64)
        +			mask1=mask0;
        +		else
        +			mask1=(1L<<(num-32))-1;
        +		}
        +	else
        +		{
        +		if (num == 32)
        +			mask0=0xffffffffL;
        +		else
        +			mask0=(1L<<num)-1;
        +		mask1=0x00000000L;
        +		}
        +
        +	iv = &(*ivec)[0];
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	while (l-- > 0)
        +		{
        +		ti[0]=v0;
        +		ti[1]=v1;
        +		DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
        +		vv0=ti[0];
        +		vv1=ti[1];
        +		c2ln(in,d0,d1,n);
        +		in+=n;
        +		d0=(d0^vv0)&mask0;
        +		d1=(d1^vv1)&mask1;
        +		l2cn(d0,d1,out,n);
        +		out+=n;
        +
        +		if (num == 32)
        +			{ v0=v1; v1=vv0; }
        +		else if (num == 64)
        +				{ v0=vv0; v1=vv1; }
        +		else if (num > 32) /* && num != 64 */
        +			{
        +			v0=((v1>>(num-32))|(vv0<<(64-num)))&0xffffffffL;
        +			v1=((vv0>>(num-32))|(vv1<<(64-num)))&0xffffffffL;
        +			}
        +		else /* num < 32 */
        +			{
        +			v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL;
        +			v1=((v1>>num)|(vv0<<(32-num)))&0xffffffffL;
        +			}
        +		}
        +	iv = &(*ivec)[0];
        +	l2c(v0,iv);
        +	l2c(v1,iv);
        +	v0=v1=d0=d1=ti[0]=ti[1]=vv0=vv1=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/options.txt b/vendor/openssl/openssl/crypto/des/options.txt
        new file mode 100644
        index 000000000..6e2b50f76
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/options.txt
        @@ -0,0 +1,39 @@
        +Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds
        +instead of the default 4.
        +RISC1 and RISC2 are 2 alternatives for the inner loop and
        +PTR means to use pointers arithmatic instead of arrays.
        +
        +FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler		577,000 4620k/s
        +IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR	496,000 3968k/s
        +solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1]	459,400 3672k/s
        +FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1	433,000 3468k/s
        +solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 		380,000 3041k/s
        +linux - pentium 100mhz - gcc 2.7.0 - assembler			281,000 2250k/s
        +NT 4.0 - pentium 100mhz - VC 4.2 - assembler			281,000 2250k/s
        +AIX 4.1? - PPC604 100mhz - cc - UNROLL 				275,000 2200k/s
        +IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR		235,300 1882k/s
        +IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR			233,700 1869k/s
        +NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR		191,000 1528k/s
        +DEC Alpha 165mhz??  - cc - RISC2 PTR [2]			181,000 1448k/s
        +linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR		158,500 1268k/s
        +HPUX 10 - 9000/887 - cc - UNROLL [3]	 			148,000	1190k/s
        +solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL		123,600  989k/s
        +IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR			101,000  808k/s
        +DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL			 81,000  648k/s
        +solaris 2.4 486 50mhz - gcc 2.6.3 - assembler			 65,000  522k/s
        +HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR	 76,000	 608k/s
        +solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2		 43,500  344k/s
        +AIX - old slow one :-) - cc -					 39,000  312k/s
        +
        +Notes.
        +[1] For the ultra sparc, SunC 4.0 
        +    cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts'
        +    gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s.
        +    I'll record the higher since it is coming from the library but it
        +    is all rather weird.
        +[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000.
        +[3] I was unable to get access to this machine when it was not heavily loaded.
        +    As such, my timing program was never able to get more that %30 of the CPU.
        +    This would cause the program to give much lower speed numbers because
        +    it would be 'fighting' to stay in the cache with the other CPU burning
        +    processes.
        diff --git a/vendor/openssl/openssl/crypto/des/pcbc_enc.c b/vendor/openssl/openssl/crypto/des/pcbc_enc.c
        new file mode 100644
        index 000000000..17a40f952
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/pcbc_enc.c
        @@ -0,0 +1,123 @@
        +/* crypto/des/pcbc_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +
        +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
        +		      long length, DES_key_schedule *schedule,
        +		      DES_cblock *ivec, int enc)
        +	{
        +	register DES_LONG sin0,sin1,xor0,xor1,tout0,tout1;
        +	DES_LONG tin[2];
        +	const unsigned char *in;
        +	unsigned char *out,*iv;
        +
        +	in=input;
        +	out=output;
        +	iv = &(*ivec)[0];
        +
        +	if (enc)
        +		{
        +		c2l(iv,xor0);
        +		c2l(iv,xor1);
        +		for (; length>0; length-=8)
        +			{
        +			if (length >= 8)
        +				{
        +				c2l(in,sin0);
        +				c2l(in,sin1);
        +				}
        +			else
        +				c2ln(in,sin0,sin1,length);
        +			tin[0]=sin0^xor0;
        +			tin[1]=sin1^xor1;
        +			DES_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
        +			tout0=tin[0];
        +			tout1=tin[1];
        +			xor0=sin0^tout0;
        +			xor1=sin1^tout1;
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			}
        +		}
        +	else
        +		{
        +		c2l(iv,xor0); c2l(iv,xor1);
        +		for (; length>0; length-=8)
        +			{
        +			c2l(in,sin0);
        +			c2l(in,sin1);
        +			tin[0]=sin0;
        +			tin[1]=sin1;
        +			DES_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			if (length >= 8)
        +				{
        +				l2c(tout0,out);
        +				l2c(tout1,out);
        +				}
        +			else
        +				l2cn(tout0,tout1,out,length);
        +			xor0=tout0^sin0;
        +			xor1=tout1^sin1;
        +			}
        +		}
        +	tin[0]=tin[1]=0;
        +	sin0=sin1=xor0=xor1=tout0=tout1=0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/qud_cksm.c b/vendor/openssl/openssl/crypto/des/qud_cksm.c
        new file mode 100644
        index 000000000..dac201227
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/qud_cksm.c
        @@ -0,0 +1,139 @@
        +/* crypto/des/qud_cksm.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.]
        + */
        +
        +/* From "Message Authentication"  R.R. Jueneman, S.M. Matyas, C.H. Meyer
        + * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40
        + * This module in only based on the code in this paper and is
        + * almost definitely not the same as the MIT implementation.
        + */
        +#include "des_locl.h"
        +
        +/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
        +#define Q_B0(a)	(((DES_LONG)(a)))
        +#define Q_B1(a)	(((DES_LONG)(a))<<8)
        +#define Q_B2(a)	(((DES_LONG)(a))<<16)
        +#define Q_B3(a)	(((DES_LONG)(a))<<24)
        +
        +/* used to scramble things a bit */
        +/* Got the value MIT uses via brute force :-) 2/10/90 eay */
        +#define NOISE	((DES_LONG)83653421L)
        +
        +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
        +	     long length, int out_count, DES_cblock *seed)
        +	{
        +	DES_LONG z0,z1,t0,t1;
        +	int i;
        +	long l;
        +	const unsigned char *cp;
        +#ifdef _CRAY
        +	struct lp_st { int a:32; int b:32; } *lp;
        +#else
        +	DES_LONG *lp;
        +#endif
        +
        +	if (out_count < 1) out_count=1;
        +#ifdef _CRAY
        +	lp = (struct lp_st *) &(output[0])[0];
        +#else
        +	lp = (DES_LONG *) &(output[0])[0];
        +#endif
        +
        +	z0=Q_B0((*seed)[0])|Q_B1((*seed)[1])|Q_B2((*seed)[2])|Q_B3((*seed)[3]);
        +	z1=Q_B0((*seed)[4])|Q_B1((*seed)[5])|Q_B2((*seed)[6])|Q_B3((*seed)[7]);
        +
        +	for (i=0; ((i<4)&&(i<out_count)); i++)
        +		{
        +		cp=input;
        +		l=length;
        +		while (l > 0)
        +			{
        +			if (l > 1)
        +				{
        +				t0= (DES_LONG)(*(cp++));
        +				t0|=(DES_LONG)Q_B1(*(cp++));
        +				l--;
        +				}
        +			else
        +				t0= (DES_LONG)(*(cp++));
        +			l--;
        +			/* add */
        +			t0+=z0;
        +			t0&=0xffffffffL;
        +			t1=z1;
        +			/* square, well sort of square */
        +			z0=((((t0*t0)&0xffffffffL)+((t1*t1)&0xffffffffL))
        +				&0xffffffffL)%0x7fffffffL; 
        +			z1=((t0*((t1+NOISE)&0xffffffffL))&0xffffffffL)%0x7fffffffL;
        +			}
        +		if (lp != NULL)
        +			{
        +			/* The MIT library assumes that the checksum is
        +			 * composed of 2*out_count 32 bit ints */
        +#ifdef _CRAY
        +			(*lp).a = z0;
        +			(*lp).b = z1;
        +			lp++;
        +#else
        +			*lp++ = z0;
        +			*lp++ = z1;
        +#endif
        +			}
        +		}
        +	return(z0);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/rand_key.c b/vendor/openssl/openssl/crypto/des/rand_key.c
        new file mode 100644
        index 000000000..239816556
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/rand_key.c
        @@ -0,0 +1,68 @@
        +/* crypto/des/rand_key.c */
        +/* ====================================================================
        + * 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 <openssl/des.h>
        +#include <openssl/rand.h>
        +
        +int DES_random_key(DES_cblock *ret)
        +	{
        +	do
        +		{
        +		if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1)
        +			return (0);
        +		} while (DES_is_weak_key(ret));
        +	DES_set_odd_parity(ret);
        +	return (1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/read2pwd.c b/vendor/openssl/openssl/crypto/des/read2pwd.c
        new file mode 100644
        index 000000000..ee6969f76
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/read2pwd.c
        @@ -0,0 +1,140 @@
        +/* crypto/des/read2pwd.c */
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <string.h>
        +#include <openssl/des.h>
        +#include <openssl/ui.h>
        +#include <openssl/crypto.h>
        +
        +int DES_read_password(DES_cblock *key, const char *prompt, int verify)
        +	{
        +	int ok;
        +	char buf[BUFSIZ],buff[BUFSIZ];
        +
        +	if ((ok=UI_UTIL_read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
        +		DES_string_to_key(buf,key);
        +	OPENSSL_cleanse(buf,BUFSIZ);
        +	OPENSSL_cleanse(buff,BUFSIZ);
        +	return(ok);
        +	}
        +
        +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
        +	     int verify)
        +	{
        +	int ok;
        +	char buf[BUFSIZ],buff[BUFSIZ];
        +
        +	if ((ok=UI_UTIL_read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)
        +		DES_string_to_2keys(buf,key1,key2);
        +	OPENSSL_cleanse(buf,BUFSIZ);
        +	OPENSSL_cleanse(buff,BUFSIZ);
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/read_pwd.c b/vendor/openssl/openssl/crypto/des/read_pwd.c
        new file mode 100644
        index 000000000..ce5fa00a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/read_pwd.c
        @@ -0,0 +1,521 @@
        +/* crypto/des/read_pwd.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 <openssl/e_os2.h>
        +#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32)
        +#ifdef OPENSSL_UNISTD
        +# include OPENSSL_UNISTD
        +#else
        +# include <unistd.h>
        +#endif
        +/* If unistd.h defines _POSIX_VERSION, we conclude that we
        + * are on a POSIX system and have sigaction and termios. */
        +#if defined(_POSIX_VERSION)
        +
        +# define SIGACTION
        +# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
        +# define TERMIOS
        +# endif
        +
        +#endif
        +#endif
        +
        +/* #define SIGACTION */ /* Define this if you have sigaction() */
        +
        +#ifdef WIN16TTY
        +#undef OPENSSL_SYS_WIN16
        +#undef _WINDOWS
        +#include <graph.h>
        +#endif
        +
        +/* 06-Apr-92 Luke Brennan    Support for VMS */
        +#include "des_locl.h"
        +#include "cryptlib.h"
        +#include <signal.h>
        +#include <stdio.h>
        +#include <string.h>
        +#include <setjmp.h>
        +#include <errno.h>
        +
        +#ifdef OPENSSL_SYS_VMS			/* prototypes for sys$whatever */
        +#include <starlet.h>
        +#ifdef __DECC
        +#pragma message disable DOLLARID
        +#endif
        +#endif
        +
        +#ifdef WIN_CONSOLE_BUG
        +#include <windows.h>
        +#ifndef OPENSSL_SYS_WINCE
        +#include <wincon.h>
        +#endif
        +#endif
        +
        +
        +/* There are 5 types of terminal interface supported,
        + * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
        + */
        +
        +#if defined(__sgi) && !defined(TERMIOS)
        +#define TERMIOS
        +#undef  TERMIO
        +#undef  SGTTY
        +#endif
        +
        +#if defined(linux) && !defined(TERMIO)
        +#undef  TERMIOS
        +#define TERMIO
        +#undef  SGTTY
        +#endif
        +
        +#ifdef _LIBC
        +#undef  TERMIOS
        +#define TERMIO
        +#undef  SGTTY
        +#endif
        +
        +#if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE)
        +#undef  TERMIOS
        +#undef  TERMIO
        +#define SGTTY
        +#endif
        +
        +#if defined(OPENSSL_SYS_VXWORKS)
        +#undef TERMIOS
        +#undef TERMIO
        +#undef SGTTY
        +#endif
        +
        +#ifdef TERMIOS
        +#include <termios.h>
        +#define TTY_STRUCT		struct termios
        +#define TTY_FLAGS		c_lflag
        +#define	TTY_get(tty,data)	tcgetattr(tty,data)
        +#define TTY_set(tty,data)	tcsetattr(tty,TCSANOW,data)
        +#endif
        +
        +#ifdef TERMIO
        +#include <termio.h>
        +#define TTY_STRUCT		struct termio
        +#define TTY_FLAGS		c_lflag
        +#define TTY_get(tty,data)	ioctl(tty,TCGETA,data)
        +#define TTY_set(tty,data)	ioctl(tty,TCSETA,data)
        +#endif
        +
        +#ifdef SGTTY
        +#include <sgtty.h>
        +#define TTY_STRUCT		struct sgttyb
        +#define TTY_FLAGS		sg_flags
        +#define TTY_get(tty,data)	ioctl(tty,TIOCGETP,data)
        +#define TTY_set(tty,data)	ioctl(tty,TIOCSETP,data)
        +#endif
        +
        +#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X)
        +#include <sys/ioctl.h>
        +#endif
        +
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE)
        +#include <conio.h>
        +#define fgets(a,b,c) noecho_fgets(a,b,c)
        +#endif
        +
        +#ifdef OPENSSL_SYS_VMS
        +#include <ssdef.h>
        +#include <iodef.h>
        +#include <ttdef.h>
        +#include <descrip.h>
        +struct IOSB {
        +	short iosb$w_value;
        +	short iosb$w_count;
        +	long  iosb$l_info;
        +	};
        +#endif
        +
        +#if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE)
        +/*
        + * This one needs work. As a matter of fact the code is unoperational
        + * and this is only a trick to get it compiled.
        + *					<appro@fy.chalmers.se>
        + */
        +#define TTY_STRUCT int
        +#endif
        +
        +#ifndef NX509_SIG
        +#define NX509_SIG 32
        +#endif
        +
        +static void read_till_nl(FILE *);
        +static void recsig(int);
        +static void pushsig(void);
        +static void popsig(void);
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16)
        +static int noecho_fgets(char *buf, int size, FILE *tty);
        +#endif
        +#ifdef SIGACTION
        + static struct sigaction savsig[NX509_SIG];
        +#else
        +  static void (*savsig[NX509_SIG])(int );
        +#endif
        +static jmp_buf save;
        +
        +int des_read_pw_string(char *buf, int length, const char *prompt,
        +	     int verify)
        +	{
        +	char buff[BUFSIZ];
        +	int ret;
        +
        +	ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
        +	OPENSSL_cleanse(buff,BUFSIZ);
        +	return(ret);
        +	}
        +
        +#ifdef OPENSSL_SYS_WINCE
        +
        +int des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify)
        +	{ 
        +	memset(buf,0,size);
        +	memset(buff,0,size);
        +	return(0);
        +	}
        +
        +#elif defined(OPENSSL_SYS_WIN16)
        +
        +int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify)
        +	{ 
        +	memset(buf,0,size);
        +	memset(buff,0,size);
        +	return(0);
        +	}
        +
        +#else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */
        +
        +static void read_till_nl(FILE *in)
        +	{
        +#define SIZE 4
        +	char buf[SIZE+1];
        +
        +	do	{
        +		fgets(buf,SIZE,in);
        +		} while (strchr(buf,'\n') == NULL);
        +	}
        +
        +
        +/* return 0 if ok, 1 (or -1) otherwise */
        +int des_read_pw(char *buf, char *buff, int size, const char *prompt,
        +	     int verify)
        +	{
        +#ifdef OPENSSL_SYS_VMS
        +	struct IOSB iosb;
        +	$DESCRIPTOR(terminal,"TT");
        +	long tty_orig[3], tty_new[3];
        +	long status;
        +	unsigned short channel = 0;
        +#else
        +#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
        +	TTY_STRUCT tty_orig,tty_new;
        +#endif
        +#endif
        +	int number;
        +	int ok;
        +	/* statics are simply to avoid warnings about longjmp clobbering
        +	   things */
        +	static int ps;
        +	int is_a_tty;
        +	static FILE *tty;
        +	char *p;
        +
        +	if (setjmp(save))
        +		{
        +		ok=0;
        +		goto error;
        +		}
        +
        +	number=5;
        +	ok=0;
        +	ps=0;
        +	is_a_tty=1;
        +	tty=NULL;
        +
        +#ifdef OPENSSL_SYS_MSDOS
        +	if ((tty=fopen("con","r")) == NULL)
        +		tty=stdin;
        +#elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS)
        +	tty=stdin;
        +#else
        +#ifndef OPENSSL_SYS_MPE
        +	if ((tty=fopen("/dev/tty","r")) == NULL)
        +#endif
        +		tty=stdin;
        +#endif
        +
        +#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
        +	if (TTY_get(fileno(tty),&tty_orig) == -1)
        +		{
        +#ifdef ENOTTY
        +		if (errno == ENOTTY)
        +			is_a_tty=0;
        +		else
        +#endif
        +#ifdef EINVAL
        +		/* Ariel Glenn ariel@columbia.edu reports that solaris
        +		 * can return EINVAL instead.  This should be ok */
        +		if (errno == EINVAL)
        +			is_a_tty=0;
        +		else
        +#endif
        +			return(-1);
        +		}
        +	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
        +#endif
        +#ifdef OPENSSL_SYS_VMS
        +	status = sys$assign(&terminal,&channel,0,0);
        +	if (status != SS$_NORMAL)
        +		return(-1);
        +	status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
        +	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
        +		return(-1);
        +#endif
        +
        +	pushsig();
        +	ps=1;
        +
        +#ifdef TTY_FLAGS
        +	tty_new.TTY_FLAGS &= ~ECHO;
        +#endif
        +
        +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
        +	if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))
        +#ifdef OPENSSL_SYS_MPE 
        +		; /* MPE lies -- echo really has been disabled */
        +#else
        +		return(-1);
        +#endif
        +#endif
        +#ifdef OPENSSL_SYS_VMS
        +	tty_new[0] = tty_orig[0];
        +	tty_new[1] = tty_orig[1] | TT$M_NOECHO;
        +	tty_new[2] = tty_orig[2];
        +	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
        +	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
        +		return(-1);
        +#endif
        +	ps=2;
        +
        +	while ((!ok) && (number--))
        +		{
        +		fputs(prompt,stderr);
        +		fflush(stderr);
        +
        +		buf[0]='\0';
        +		fgets(buf,size,tty);
        +		if (feof(tty)) goto error;
        +		if (ferror(tty)) goto error;
        +		if ((p=(char *)strchr(buf,'\n')) != NULL)
        +			*p='\0';
        +		else	read_till_nl(tty);
        +		if (verify)
        +			{
        +			fprintf(stderr,"\nVerifying password - %s",prompt);
        +			fflush(stderr);
        +			buff[0]='\0';
        +			fgets(buff,size,tty);
        +			if (feof(tty)) goto error;
        +			if ((p=(char *)strchr(buff,'\n')) != NULL)
        +				*p='\0';
        +			else	read_till_nl(tty);
        +				
        +			if (strcmp(buf,buff) != 0)
        +				{
        +				fprintf(stderr,"\nVerify failure");
        +				fflush(stderr);
        +				break;
        +				/* continue; */
        +				}
        +			}
        +		ok=1;
        +		}
        +
        +error:
        +	fprintf(stderr,"\n");
        +#if 0
        +	perror("fgets(tty)");
        +#endif
        +	/* What can we do if there is an error? */
        +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
        +	if (ps >= 2) TTY_set(fileno(tty),&tty_orig);
        +#endif
        +#ifdef OPENSSL_SYS_VMS
        +	if (ps >= 2)
        +		status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0
        +			,tty_orig,12,0,0,0,0);
        +#endif
        +	
        +	if (ps >= 1) popsig();
        +	if (stdin != tty) fclose(tty);
        +#ifdef OPENSSL_SYS_VMS
        +	status = sys$dassgn(channel);
        +#endif
        +	return(!ok);
        +	}
        +
        +static void pushsig(void)
        +	{
        +	int i;
        +#ifdef SIGACTION
        +	struct sigaction sa;
        +
        +	memset(&sa,0,sizeof sa);
        +	sa.sa_handler=recsig;
        +#endif
        +
        +	for (i=1; i<NX509_SIG; i++)
        +		{
        +#ifdef SIGUSR1
        +		if (i == SIGUSR1)
        +			continue;
        +#endif
        +#ifdef SIGUSR2
        +		if (i == SIGUSR2)
        +			continue;
        +#endif
        +#ifdef SIGACTION
        +		sigaction(i,&sa,&savsig[i]);
        +#else
        +		savsig[i]=signal(i,recsig);
        +#endif
        +		}
        +
        +#ifdef SIGWINCH
        +	signal(SIGWINCH,SIG_DFL);
        +#endif
        +	}
        +
        +static void popsig(void)
        +	{
        +	int i;
        +
        +	for (i=1; i<NX509_SIG; i++)
        +		{
        +#ifdef SIGUSR1
        +		if (i == SIGUSR1)
        +			continue;
        +#endif
        +#ifdef SIGUSR2
        +		if (i == SIGUSR2)
        +			continue;
        +#endif
        +#ifdef SIGACTION
        +		sigaction(i,&savsig[i],NULL);
        +#else
        +		signal(i,savsig[i]);
        +#endif
        +		}
        +	}
        +
        +static void recsig(int i)
        +	{
        +	longjmp(save,1);
        +#ifdef LINT
        +	i=i;
        +#endif
        +	}
        +
        +#ifdef OPENSSL_SYS_MSDOS
        +static int noecho_fgets(char *buf, int size, FILE *tty)
        +	{
        +	int i;
        +	char *p;
        +
        +	p=buf;
        +	for (;;)
        +		{
        +		if (size == 0)
        +			{
        +			*p='\0';
        +			break;
        +			}
        +		size--;
        +#ifdef WIN16TTY
        +		i=_inchar();
        +#else
        +		i=getch();
        +#endif
        +		if (i == '\r') i='\n';
        +		*(p++)=i;
        +		if (i == '\n')
        +			{
        +			*p='\0';
        +			break;
        +			}
        +		}
        +#ifdef WIN_CONSOLE_BUG
        +/* Win95 has several evil console bugs: one of these is that the
        + * last character read using getch() is passed to the next read: this is
        + * usually a CR so this can be trouble. No STDIO fix seems to work but
        + * flushing the console appears to do the trick.
        + */
        +		{
        +			HANDLE inh;
        +			inh = GetStdHandle(STD_INPUT_HANDLE);
        +			FlushConsoleInputBuffer(inh);
        +		}
        +#endif
        +	return(strlen(buf));
        +	}
        +#endif
        +#endif /* !OPENSSL_SYS_WINCE && !WIN16 */
        diff --git a/vendor/openssl/openssl/crypto/des/rpc_des.h b/vendor/openssl/openssl/crypto/des/rpc_des.h
        new file mode 100644
        index 000000000..41328d796
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/rpc_des.h
        @@ -0,0 +1,131 @@
        +/* crypto/des/rpc_des.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.]
        + */
        +
        +/*  @(#)des.h	2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI  */
        +/*
        + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
        + * unrestricted use provided that this legend is included on all tape
        + * media and as a part of the software program in whole or part.  Users
        + * may copy or modify Sun RPC without charge, but are not authorized
        + * to license or distribute it to anyone else except as part of a product or
        + * program developed by the user.
        + * 
        + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
        + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
        + * 
        + * Sun RPC is provided with no support and without any obligation on the
        + * part of Sun Microsystems, Inc. to assist in its use, correction,
        + * modification or enhancement.
        + * 
        + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
        + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
        + * OR ANY PART THEREOF.
        + * 
        + * In no event will Sun Microsystems, Inc. be liable for any lost revenue
        + * or profits or other special, indirect and consequential damages, even if
        + * Sun has been advised of the possibility of such damages.
        + * 
        + * Sun Microsystems, Inc.
        + * 2550 Garcia Avenue
        + * Mountain View, California  94043
        + */
        +/*
        + * Generic DES driver interface
        + * Keep this file hardware independent!
        + * Copyright (c) 1986 by Sun Microsystems, Inc.
        + */
        +
        +#define DES_MAXLEN 	65536	/* maximum # of bytes to encrypt  */
        +#define DES_QUICKLEN	16	/* maximum # of bytes to encrypt quickly */
        +
        +#ifdef HEADER_DES_H
        +#undef ENCRYPT
        +#undef DECRYPT
        +#endif
        +
        +enum desdir { ENCRYPT, DECRYPT };
        +enum desmode { CBC, ECB };
        +
        +/*
        + * parameters to ioctl call
        + */
        +struct desparams {
        +	unsigned char des_key[8];	/* key (with low bit parity) */
        +	enum desdir des_dir;	/* direction */
        +	enum desmode des_mode;	/* mode */
        +	unsigned char des_ivec[8];	/* input vector */
        +	unsigned des_len;	/* number of bytes to crypt */
        +	union {
        +		unsigned char UDES_data[DES_QUICKLEN];
        +		unsigned char *UDES_buf;
        +	} UDES;
        +#	define des_data UDES.UDES_data	/* direct data here if quick */
        +#	define des_buf	UDES.UDES_buf	/* otherwise, pointer to data */
        +};
        +
        +/*
        + * Encrypt an arbitrary sized buffer
        + */
        +#define	DESIOCBLOCK	_IOWR('d', 6, struct desparams)
        +
        +/* 
        + * Encrypt of small amount of data, quickly
        + */
        +#define DESIOCQUICK	_IOWR('d', 7, struct desparams) 
        +
        diff --git a/vendor/openssl/openssl/crypto/des/rpc_enc.c b/vendor/openssl/openssl/crypto/des/rpc_enc.c
        new file mode 100644
        index 000000000..d937d08da
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/rpc_enc.c
        @@ -0,0 +1,98 @@
        +/* crypto/des/rpc_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "rpc_des.h"
        +#include "des_locl.h"
        +#include "des_ver.h"
        +
        +int _des_crypt(char *buf,int len,struct desparams *desp);
        +int _des_crypt(char *buf, int len, struct desparams *desp)
        +	{
        +	DES_key_schedule ks;
        +	int enc;
        +
        +	DES_set_key_unchecked(&desp->des_key,&ks);
        +	enc=(desp->des_dir == ENCRYPT)?DES_ENCRYPT:DES_DECRYPT;
        +
        +	if (desp->des_mode == CBC)
        +		DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf,
        +				(DES_cblock *)desp->UDES.UDES_buf,&ks,
        +				enc);
        +	else
        +		{
        +		DES_ncbc_encrypt(desp->UDES.UDES_buf,desp->UDES.UDES_buf,
        +				len,&ks,&desp->des_ivec,enc);
        +#ifdef undef
        +		/* len will always be %8 if called from common_crypt
        +		 * in secure_rpc.
        +		 * Libdes's cbc encrypt does not copy back the iv,
        +		 * so we have to do it here. */
        +		/* It does now :-) eay 20/09/95 */
        +
        +		a=(char *)&(desp->UDES.UDES_buf[len-8]);
        +		b=(char *)&(desp->des_ivec[0]);
        +
        +		*(a++)= *(b++); *(a++)= *(b++);
        +		*(a++)= *(b++); *(a++)= *(b++);
        +		*(a++)= *(b++); *(a++)= *(b++);
        +		*(a++)= *(b++); *(a++)= *(b++);
        +#endif
        +		}
        +	return(1);	
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/des/rpw.c b/vendor/openssl/openssl/crypto/des/rpw.c
        new file mode 100644
        index 000000000..8a9473c4f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/rpw.c
        @@ -0,0 +1,99 @@
        +/* crypto/des/rpw.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/des.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	DES_cblock k,k1;
        +	int i;
        +
        +	printf("read passwd\n");
        +	if ((i=des_read_password(&k,"Enter password:",0)) == 0)
        +		{
        +		printf("password = ");
        +		for (i=0; i<8; i++)
        +			printf("%02x ",k[i]);
        +		}
        +	else
        +		printf("error %d\n",i);
        +	printf("\n");
        +	printf("read 2passwds and verify\n");
        +	if ((i=des_read_2passwords(&k,&k1,
        +		"Enter verified password:",1)) == 0)
        +		{
        +		printf("password1 = ");
        +		for (i=0; i<8; i++)
        +			printf("%02x ",k[i]);
        +		printf("\n");
        +		printf("password2 = ");
        +		for (i=0; i<8; i++)
        +			printf("%02x ",k1[i]);
        +		printf("\n");
        +		exit(1);
        +		}
        +	else
        +		{
        +		printf("error %d\n",i);
        +		exit(0);
        +		}
        +#ifdef LINT
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/set_key.c b/vendor/openssl/openssl/crypto/des/set_key.c
        new file mode 100644
        index 000000000..da4d62e11
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/set_key.c
        @@ -0,0 +1,415 @@
        +/* crypto/des/set_key.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* set_key.c v 1.4 eay 24/9/91
        + * 1.4 Speed up by 400% :-)
        + * 1.3 added register declarations.
        + * 1.2 unrolled make_key_sched a bit more
        + * 1.1 added norm_expand_bits
        + * 1.0 First working version
        + */
        +#include <openssl/crypto.h>
        +#include "des_locl.h"
        +
        +OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0)	/* defaults to false */
        +
        +static const unsigned char odd_parity[256]={
        +  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
        + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
        + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
        + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
        + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
        + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
        + 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
        +112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
        +128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
        +145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
        +161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
        +176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
        +193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
        +208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
        +224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
        +241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
        +
        +void DES_set_odd_parity(DES_cblock *key)
        +	{
        +	unsigned int i;
        +
        +	for (i=0; i<DES_KEY_SZ; i++)
        +		(*key)[i]=odd_parity[(*key)[i]];
        +	}
        +
        +int DES_check_key_parity(const_DES_cblock *key)
        +	{
        +	unsigned int i;
        +
        +	for (i=0; i<DES_KEY_SZ; i++)
        +		{
        +		if ((*key)[i] != odd_parity[(*key)[i]])
        +			return(0);
        +		}
        +	return(1);
        +	}
        +
        +/* Weak and semi week keys as take from
        + * %A D.W. Davies
        + * %A W.L. Price
        + * %T Security for Computer Networks
        + * %I John Wiley & Sons
        + * %D 1984
        + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
        + * (and actual cblock values).
        + */
        +#define NUM_WEAK_KEY	16
        +static const DES_cblock weak_keys[NUM_WEAK_KEY]={
        +	/* weak keys */
        +	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
        +	{0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
        +	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
        +	{0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
        +	/* semi-weak keys */
        +	{0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
        +	{0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
        +	{0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
        +	{0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
        +	{0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
        +	{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
        +	{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
        +	{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
        +	{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
        +	{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
        +	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
        +	{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
        +
        +int DES_is_weak_key(const_DES_cblock *key)
        +	{
        +	int i;
        +
        +	for (i=0; i<NUM_WEAK_KEY; i++)
        +		/* Added == 0 to comparison, I obviously don't run
        +		 * this section very often :-(, thanks to
        +		 * engineering@MorningStar.Com for the fix
        +		 * eay 93/06/29
        +		 * Another problem, I was comparing only the first 4
        +		 * bytes, 97/03/18 */
        +		if (memcmp(weak_keys[i],key,sizeof(DES_cblock)) == 0) return(1);
        +	return(0);
        +	}
        +
        +/* NOW DEFINED IN des_local.h
        + * See ecb_encrypt.c for a pseudo description of these macros. 
        + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
        + * 	(b)^=(t),\
        + * 	(a)=((a)^((t)<<(n))))
        + */
        +
        +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
        +	(a)=(a)^(t)^(t>>(16-(n))))
        +
        +static const DES_LONG des_skb[8][64]={
        +	{
        +	/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
        +	0x00000000L,0x00000010L,0x20000000L,0x20000010L,
        +	0x00010000L,0x00010010L,0x20010000L,0x20010010L,
        +	0x00000800L,0x00000810L,0x20000800L,0x20000810L,
        +	0x00010800L,0x00010810L,0x20010800L,0x20010810L,
        +	0x00000020L,0x00000030L,0x20000020L,0x20000030L,
        +	0x00010020L,0x00010030L,0x20010020L,0x20010030L,
        +	0x00000820L,0x00000830L,0x20000820L,0x20000830L,
        +	0x00010820L,0x00010830L,0x20010820L,0x20010830L,
        +	0x00080000L,0x00080010L,0x20080000L,0x20080010L,
        +	0x00090000L,0x00090010L,0x20090000L,0x20090010L,
        +	0x00080800L,0x00080810L,0x20080800L,0x20080810L,
        +	0x00090800L,0x00090810L,0x20090800L,0x20090810L,
        +	0x00080020L,0x00080030L,0x20080020L,0x20080030L,
        +	0x00090020L,0x00090030L,0x20090020L,0x20090030L,
        +	0x00080820L,0x00080830L,0x20080820L,0x20080830L,
        +	0x00090820L,0x00090830L,0x20090820L,0x20090830L,
        +	},{
        +	/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
        +	0x00000000L,0x02000000L,0x00002000L,0x02002000L,
        +	0x00200000L,0x02200000L,0x00202000L,0x02202000L,
        +	0x00000004L,0x02000004L,0x00002004L,0x02002004L,
        +	0x00200004L,0x02200004L,0x00202004L,0x02202004L,
        +	0x00000400L,0x02000400L,0x00002400L,0x02002400L,
        +	0x00200400L,0x02200400L,0x00202400L,0x02202400L,
        +	0x00000404L,0x02000404L,0x00002404L,0x02002404L,
        +	0x00200404L,0x02200404L,0x00202404L,0x02202404L,
        +	0x10000000L,0x12000000L,0x10002000L,0x12002000L,
        +	0x10200000L,0x12200000L,0x10202000L,0x12202000L,
        +	0x10000004L,0x12000004L,0x10002004L,0x12002004L,
        +	0x10200004L,0x12200004L,0x10202004L,0x12202004L,
        +	0x10000400L,0x12000400L,0x10002400L,0x12002400L,
        +	0x10200400L,0x12200400L,0x10202400L,0x12202400L,
        +	0x10000404L,0x12000404L,0x10002404L,0x12002404L,
        +	0x10200404L,0x12200404L,0x10202404L,0x12202404L,
        +	},{
        +	/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
        +	0x00000000L,0x00000001L,0x00040000L,0x00040001L,
        +	0x01000000L,0x01000001L,0x01040000L,0x01040001L,
        +	0x00000002L,0x00000003L,0x00040002L,0x00040003L,
        +	0x01000002L,0x01000003L,0x01040002L,0x01040003L,
        +	0x00000200L,0x00000201L,0x00040200L,0x00040201L,
        +	0x01000200L,0x01000201L,0x01040200L,0x01040201L,
        +	0x00000202L,0x00000203L,0x00040202L,0x00040203L,
        +	0x01000202L,0x01000203L,0x01040202L,0x01040203L,
        +	0x08000000L,0x08000001L,0x08040000L,0x08040001L,
        +	0x09000000L,0x09000001L,0x09040000L,0x09040001L,
        +	0x08000002L,0x08000003L,0x08040002L,0x08040003L,
        +	0x09000002L,0x09000003L,0x09040002L,0x09040003L,
        +	0x08000200L,0x08000201L,0x08040200L,0x08040201L,
        +	0x09000200L,0x09000201L,0x09040200L,0x09040201L,
        +	0x08000202L,0x08000203L,0x08040202L,0x08040203L,
        +	0x09000202L,0x09000203L,0x09040202L,0x09040203L,
        +	},{
        +	/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
        +	0x00000000L,0x00100000L,0x00000100L,0x00100100L,
        +	0x00000008L,0x00100008L,0x00000108L,0x00100108L,
        +	0x00001000L,0x00101000L,0x00001100L,0x00101100L,
        +	0x00001008L,0x00101008L,0x00001108L,0x00101108L,
        +	0x04000000L,0x04100000L,0x04000100L,0x04100100L,
        +	0x04000008L,0x04100008L,0x04000108L,0x04100108L,
        +	0x04001000L,0x04101000L,0x04001100L,0x04101100L,
        +	0x04001008L,0x04101008L,0x04001108L,0x04101108L,
        +	0x00020000L,0x00120000L,0x00020100L,0x00120100L,
        +	0x00020008L,0x00120008L,0x00020108L,0x00120108L,
        +	0x00021000L,0x00121000L,0x00021100L,0x00121100L,
        +	0x00021008L,0x00121008L,0x00021108L,0x00121108L,
        +	0x04020000L,0x04120000L,0x04020100L,0x04120100L,
        +	0x04020008L,0x04120008L,0x04020108L,0x04120108L,
        +	0x04021000L,0x04121000L,0x04021100L,0x04121100L,
        +	0x04021008L,0x04121008L,0x04021108L,0x04121108L,
        +	},{
        +	/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
        +	0x00000000L,0x10000000L,0x00010000L,0x10010000L,
        +	0x00000004L,0x10000004L,0x00010004L,0x10010004L,
        +	0x20000000L,0x30000000L,0x20010000L,0x30010000L,
        +	0x20000004L,0x30000004L,0x20010004L,0x30010004L,
        +	0x00100000L,0x10100000L,0x00110000L,0x10110000L,
        +	0x00100004L,0x10100004L,0x00110004L,0x10110004L,
        +	0x20100000L,0x30100000L,0x20110000L,0x30110000L,
        +	0x20100004L,0x30100004L,0x20110004L,0x30110004L,
        +	0x00001000L,0x10001000L,0x00011000L,0x10011000L,
        +	0x00001004L,0x10001004L,0x00011004L,0x10011004L,
        +	0x20001000L,0x30001000L,0x20011000L,0x30011000L,
        +	0x20001004L,0x30001004L,0x20011004L,0x30011004L,
        +	0x00101000L,0x10101000L,0x00111000L,0x10111000L,
        +	0x00101004L,0x10101004L,0x00111004L,0x10111004L,
        +	0x20101000L,0x30101000L,0x20111000L,0x30111000L,
        +	0x20101004L,0x30101004L,0x20111004L,0x30111004L,
        +	},{
        +	/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
        +	0x00000000L,0x08000000L,0x00000008L,0x08000008L,
        +	0x00000400L,0x08000400L,0x00000408L,0x08000408L,
        +	0x00020000L,0x08020000L,0x00020008L,0x08020008L,
        +	0x00020400L,0x08020400L,0x00020408L,0x08020408L,
        +	0x00000001L,0x08000001L,0x00000009L,0x08000009L,
        +	0x00000401L,0x08000401L,0x00000409L,0x08000409L,
        +	0x00020001L,0x08020001L,0x00020009L,0x08020009L,
        +	0x00020401L,0x08020401L,0x00020409L,0x08020409L,
        +	0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
        +	0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
        +	0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
        +	0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
        +	0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
        +	0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
        +	0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
        +	0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
        +	},{
        +	/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
        +	0x00000000L,0x00000100L,0x00080000L,0x00080100L,
        +	0x01000000L,0x01000100L,0x01080000L,0x01080100L,
        +	0x00000010L,0x00000110L,0x00080010L,0x00080110L,
        +	0x01000010L,0x01000110L,0x01080010L,0x01080110L,
        +	0x00200000L,0x00200100L,0x00280000L,0x00280100L,
        +	0x01200000L,0x01200100L,0x01280000L,0x01280100L,
        +	0x00200010L,0x00200110L,0x00280010L,0x00280110L,
        +	0x01200010L,0x01200110L,0x01280010L,0x01280110L,
        +	0x00000200L,0x00000300L,0x00080200L,0x00080300L,
        +	0x01000200L,0x01000300L,0x01080200L,0x01080300L,
        +	0x00000210L,0x00000310L,0x00080210L,0x00080310L,
        +	0x01000210L,0x01000310L,0x01080210L,0x01080310L,
        +	0x00200200L,0x00200300L,0x00280200L,0x00280300L,
        +	0x01200200L,0x01200300L,0x01280200L,0x01280300L,
        +	0x00200210L,0x00200310L,0x00280210L,0x00280310L,
        +	0x01200210L,0x01200310L,0x01280210L,0x01280310L,
        +	},{
        +	/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
        +	0x00000000L,0x04000000L,0x00040000L,0x04040000L,
        +	0x00000002L,0x04000002L,0x00040002L,0x04040002L,
        +	0x00002000L,0x04002000L,0x00042000L,0x04042000L,
        +	0x00002002L,0x04002002L,0x00042002L,0x04042002L,
        +	0x00000020L,0x04000020L,0x00040020L,0x04040020L,
        +	0x00000022L,0x04000022L,0x00040022L,0x04040022L,
        +	0x00002020L,0x04002020L,0x00042020L,0x04042020L,
        +	0x00002022L,0x04002022L,0x00042022L,0x04042022L,
        +	0x00000800L,0x04000800L,0x00040800L,0x04040800L,
        +	0x00000802L,0x04000802L,0x00040802L,0x04040802L,
        +	0x00002800L,0x04002800L,0x00042800L,0x04042800L,
        +	0x00002802L,0x04002802L,0x00042802L,0x04042802L,
        +	0x00000820L,0x04000820L,0x00040820L,0x04040820L,
        +	0x00000822L,0x04000822L,0x00040822L,0x04040822L,
        +	0x00002820L,0x04002820L,0x00042820L,0x04042820L,
        +	0x00002822L,0x04002822L,0x00042822L,0x04042822L,
        +	}};
        +
        +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
        +	{
        +	if (DES_check_key)
        +		{
        +		return DES_set_key_checked(key, schedule);
        +		}
        +	else
        +		{
        +		DES_set_key_unchecked(key, schedule);
        +		return 0;
        +		}
        +	}
        +
        +/* return 0 if key parity is odd (correct),
        + * return -1 if key parity error,
        + * return -2 if illegal weak key.
        + */
        +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
        +	{
        +	if (!DES_check_key_parity(key))
        +		return(-1);
        +	if (DES_is_weak_key(key))
        +		return(-2);
        +	DES_set_key_unchecked(key, schedule);
        +	return 0;
        +	}
        +
        +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
        +#ifdef OPENSSL_FIPS
        +	{
        +	fips_cipher_abort(DES);
        +	private_DES_set_key_unchecked(key, schedule);
        +	}
        +void private_DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
        +#endif
        +	{
        +	static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
        +	register DES_LONG c,d,t,s,t2;
        +	register const unsigned char *in;
        +	register DES_LONG *k;
        +	register int i;
        +
        +#ifdef OPENBSD_DEV_CRYPTO
        +	memcpy(schedule->key,key,sizeof schedule->key);
        +	schedule->session=NULL;
        +#endif
        +	k = &schedule->ks->deslong[0];
        +	in = &(*key)[0];
        +
        +	c2l(in,c);
        +	c2l(in,d);
        +
        +	/* do PC1 in 47 simple operations :-)
        +	 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
        +	 * for the inspiration. :-) */
        +	PERM_OP (d,c,t,4,0x0f0f0f0fL);
        +	HPERM_OP(c,t,-2,0xcccc0000L);
        +	HPERM_OP(d,t,-2,0xcccc0000L);
        +	PERM_OP (d,c,t,1,0x55555555L);
        +	PERM_OP (c,d,t,8,0x00ff00ffL);
        +	PERM_OP (d,c,t,1,0x55555555L);
        +	d=	(((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
        +		 ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
        +	c&=0x0fffffffL;
        +
        +	for (i=0; i<ITERATIONS; i++)
        +		{
        +		if (shifts2[i])
        +			{ c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
        +		else
        +			{ c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
        +		c&=0x0fffffffL;
        +		d&=0x0fffffffL;
        +		/* could be a few less shifts but I am to lazy at this
        +		 * point in time to investigate */
        +		s=	des_skb[0][ (c    )&0x3f                ]|
        +			des_skb[1][((c>> 6L)&0x03)|((c>> 7L)&0x3c)]|
        +			des_skb[2][((c>>13L)&0x0f)|((c>>14L)&0x30)]|
        +			des_skb[3][((c>>20L)&0x01)|((c>>21L)&0x06) |
        +						  ((c>>22L)&0x38)];
        +		t=	des_skb[4][ (d    )&0x3f                ]|
        +			des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
        +			des_skb[6][ (d>>15L)&0x3f                ]|
        +			des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
        +
        +		/* table contained 0213 4657 */
        +		t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
        +		*(k++)=ROTATE(t2,30)&0xffffffffL;
        +
        +		t2=((s>>16L)|(t&0xffff0000L));
        +		*(k++)=ROTATE(t2,26)&0xffffffffL;
        +		}
        +	}
        +
        +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
        +	{
        +	return(DES_set_key(key,schedule));
        +	}
        +/*
        +#undef des_fixup_key_parity
        +void des_fixup_key_parity(des_cblock *key)
        +	{
        +	des_set_odd_parity(key);
        +	}
        +*/
        diff --git a/vendor/openssl/openssl/crypto/des/speed.c b/vendor/openssl/openssl/crypto/des/speed.c
        new file mode 100644
        index 000000000..1616f4b7c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/speed.c
        @@ -0,0 +1,314 @@
        +/* crypto/des/speed.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#define crypt(c,s) (des_crypt((c),(s)))
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/des.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +# ifndef CLK_TCK
        +#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
        +#   define HZ	100.0
        +#  else /* _BSD_CLK_TCK_ */
        +#   define HZ ((double)_BSD_CLK_TCK_)
        +#  endif
        +# else /* CLK_TCK */
        +#  define HZ ((double)CLK_TCK)
        +# endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static DES_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
        +	static DES_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
        +	static DES_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
        +	DES_key_schedule sch,sch2,sch3;
        +	double a,b,c,d,e;
        +#ifndef SIGALRM
        +	long ca,cb,cc,cd,ce;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +	DES_set_key_unchecked(&key2,&sch2);
        +	DES_set_key_unchecked(&key3,&sch3);
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	DES_set_key_unchecked(&key,&sch);
        +	count=10;
        +	do	{
        +		long i;
        +		DES_LONG data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			DES_encrypt1(data,&sch,DES_ENCRYPT);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count;
        +	cb=count*3;
        +	cc=count*3*8/BUFSIZE+1;
        +	cd=count*8/BUFSIZE+1;
        +	ce=count/20+1;
        +	printf("Doing set_key %ld times\n",ca);
        +#define COND(d)	(count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing set_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count++)
        +		DES_set_key_unchecked(&key,&sch);
        +	d=Time_F(STOP);
        +	printf("%ld set_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing DES_encrypt's for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing DES_encrypt %ld times\n",cb);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cb); count++)
        +		{
        +		DES_LONG data[2];
        +
        +		DES_encrypt1(data,&sch,DES_ENCRYPT);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld DES_encrypt's in %.2f second\n",count,d);
        +	b=((double)COUNT(cb)*8)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing DES_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing DES_cbc_encrypt %ld times on %ld byte blocks\n",cc,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		DES_ncbc_encrypt(buf,buf,BUFSIZE,&sch,
        +			&key,DES_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld DES_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing DES_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing DES_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cd); count++)
        +		DES_ede3_cbc_encrypt(buf,buf,BUFSIZE,
        +			&sch,
        +			&sch2,
        +			&sch3,
        +			&key,
        +			DES_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld DES_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	d=((double)COUNT(cd)*BUFSIZE)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing crypt for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing crypt %ld times\n",ce);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(ce); count++)
        +		crypt("testing1","ef");
        +	e=Time_F(STOP);
        +	printf("%ld crypts in %.2f second\n",count,e);
        +	e=((double)COUNT(ce))/e;
        +
        +	printf("set_key            per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("DES raw ecb bytes  per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
        +	printf("DES cbc bytes      per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
        +	printf("DES ede cbc bytes  per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
        +	printf("crypt              per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/spr.h b/vendor/openssl/openssl/crypto/des/spr.h
        new file mode 100644
        index 000000000..b91936a5a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/spr.h
        @@ -0,0 +1,204 @@
        +/* crypto/des/spr.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64]={
        +{
        +/* nibble 0 */
        +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
        +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
        +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
        +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
        +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
        +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
        +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
        +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
        +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
        +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
        +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
        +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
        +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
        +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
        +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
        +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
        +},{
        +/* nibble 1 */
        +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
        +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
        +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
        +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
        +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
        +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
        +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
        +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
        +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
        +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
        +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
        +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
        +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
        +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
        +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
        +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
        +},{
        +/* nibble 2 */
        +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
        +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
        +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
        +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
        +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
        +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
        +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
        +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
        +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
        +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
        +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
        +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
        +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
        +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
        +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
        +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
        +},{
        +/* nibble 3 */
        +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
        +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
        +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
        +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
        +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
        +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
        +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
        +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
        +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
        +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
        +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
        +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
        +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
        +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
        +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
        +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
        +},{
        +/* nibble 4 */
        +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
        +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
        +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
        +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
        +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
        +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
        +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
        +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
        +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
        +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
        +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
        +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
        +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
        +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
        +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
        +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
        +},{
        +/* nibble 5 */
        +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
        +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
        +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
        +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
        +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
        +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
        +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
        +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
        +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
        +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
        +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
        +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
        +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
        +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
        +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
        +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
        +},{
        +/* nibble 6 */
        +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
        +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
        +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
        +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
        +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
        +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
        +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
        +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
        +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
        +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
        +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
        +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
        +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
        +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
        +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
        +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
        +},{
        +/* nibble 7 */
        +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
        +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
        +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
        +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
        +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
        +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
        +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
        +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
        +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
        +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
        +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
        +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
        +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
        +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
        +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
        +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
        +}};
        diff --git a/vendor/openssl/openssl/crypto/des/str2key.c b/vendor/openssl/openssl/crypto/des/str2key.c
        new file mode 100644
        index 000000000..1077f99d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/str2key.c
        @@ -0,0 +1,174 @@
        +/* crypto/des/str2key.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 <openssl/crypto.h>
        +#include "des_locl.h"
        +
        +void DES_string_to_key(const char *str, DES_cblock *key)
        +	{
        +	DES_key_schedule ks;
        +	int i,length;
        +	register unsigned char j;
        +
        +	memset(key,0,8);
        +	length=strlen(str);
        +#ifdef OLD_STR_TO_KEY
        +	for (i=0; i<length; i++)
        +		(*key)[i%8]^=(str[i]<<1);
        +#else /* MIT COMPATIBLE */
        +	for (i=0; i<length; i++)
        +		{
        +		j=str[i];
        +		if ((i%16) < 8)
        +			(*key)[i%8]^=(j<<1);
        +		else
        +			{
        +			/* Reverse the bit order 05/05/92 eay */
        +			j=((j<<4)&0xf0)|((j>>4)&0x0f);
        +			j=((j<<2)&0xcc)|((j>>2)&0x33);
        +			j=((j<<1)&0xaa)|((j>>1)&0x55);
        +			(*key)[7-(i%8)]^=j;
        +			}
        +		}
        +#endif
        +	DES_set_odd_parity(key);
        +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
        +	if(DES_is_weak_key(key))
        +	    (*key)[7] ^= 0xF0;
        +	DES_set_key(key,&ks);
        +#else
        +	DES_set_key_unchecked(key,&ks);
        +#endif
        +	DES_cbc_cksum((const unsigned char*)str,key,length,&ks,key);
        +	OPENSSL_cleanse(&ks,sizeof(ks));
        +	DES_set_odd_parity(key);
        +	}
        +
        +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2)
        +	{
        +	DES_key_schedule ks;
        +	int i,length;
        +	register unsigned char j;
        +
        +	memset(key1,0,8);
        +	memset(key2,0,8);
        +	length=strlen(str);
        +#ifdef OLD_STR_TO_KEY
        +	if (length <= 8)
        +		{
        +		for (i=0; i<length; i++)
        +			{
        +			(*key2)[i]=(*key1)[i]=(str[i]<<1);
        +			}
        +		}
        +	else
        +		{
        +		for (i=0; i<length; i++)
        +			{
        +			if ((i/8)&1)
        +				(*key2)[i%8]^=(str[i]<<1);
        +			else
        +				(*key1)[i%8]^=(str[i]<<1);
        +			}
        +		}
        +#else /* MIT COMPATIBLE */
        +	for (i=0; i<length; i++)
        +		{
        +		j=str[i];
        +		if ((i%32) < 16)
        +			{
        +			if ((i%16) < 8)
        +				(*key1)[i%8]^=(j<<1);
        +			else
        +				(*key2)[i%8]^=(j<<1);
        +			}
        +		else
        +			{
        +			j=((j<<4)&0xf0)|((j>>4)&0x0f);
        +			j=((j<<2)&0xcc)|((j>>2)&0x33);
        +			j=((j<<1)&0xaa)|((j>>1)&0x55);
        +			if ((i%16) < 8)
        +				(*key1)[7-(i%8)]^=j;
        +			else
        +				(*key2)[7-(i%8)]^=j;
        +			}
        +		}
        +	if (length <= 8) memcpy(key2,key1,8);
        +#endif
        +	DES_set_odd_parity(key1);
        +	DES_set_odd_parity(key2);
        +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
        +	if(DES_is_weak_key(key1))
        +	    (*key1)[7] ^= 0xF0;
        +	DES_set_key(key1,&ks);
        +#else
        +	DES_set_key_unchecked(key1,&ks);
        +#endif
        +	DES_cbc_cksum((const unsigned char*)str,key1,length,&ks,key1);
        +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
        +	if(DES_is_weak_key(key2))
        +	    (*key2)[7] ^= 0xF0;
        +	DES_set_key(key2,&ks);
        +#else
        +	DES_set_key_unchecked(key2,&ks);
        +#endif
        +	DES_cbc_cksum((const unsigned char*)str,key2,length,&ks,key2);
        +	OPENSSL_cleanse(&ks,sizeof(ks));
        +	DES_set_odd_parity(key1);
        +	DES_set_odd_parity(key2);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/des/t/test b/vendor/openssl/openssl/crypto/des/t/test
        new file mode 100644
        index 000000000..97acd0552
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/t/test
        @@ -0,0 +1,27 @@
        +#!./perl
        +
        +BEGIN { push(@INC, qw(../../../lib ../../lib ../lib lib)); }
        +
        +use DES;
        +
        +$key='00000000';
        +$ks=DES::set_key($key);
        +@a=split(//,$ks);
        +foreach (@a) { printf "%02x-",ord($_); }
        +print "\n";
        +
        +
        +$key=DES::random_key();
        +print "($_)\n";
        +@a=split(//,$key);
        +foreach (@a) { printf "%02x-",ord($_); }
        +print "\n";
        +$str="this is and again into the breach";
        +($k1,$k2)=DES::string_to_2keys($str);
        +@a=split(//,$k1);
        +foreach (@a) { printf "%02x-",ord($_); }
        +print "\n";
        +@a=split(//,$k2);
        +foreach (@a) { printf "%02x-",ord($_); }
        +print "\n";
        +
        diff --git a/vendor/openssl/openssl/crypto/des/times/486-50.sol b/vendor/openssl/openssl/crypto/des/times/486-50.sol
        new file mode 100644
        index 000000000..0de62d6db
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/486-50.sol
        @@ -0,0 +1,16 @@
        +Solaris 2.4, 486 50mhz, gcc 2.6.3
        +options    des ecb/s
        +16 r2 i     43552.51 100.0%
        +16 r1 i     43487.45  99.9%
        +16  c p     43003.23  98.7%
        +16 r2 p     42339.00  97.2%
        +16  c i     41900.91  96.2%
        +16 r1 p     41360.64  95.0%
        + 4  c i     38728.48  88.9%
        + 4  c p     38225.63  87.8%
        + 4 r1 i     38085.79  87.4%
        + 4 r2 i     37825.64  86.9%
        + 4 r2 p     34611.00  79.5%
        + 4 r1 p     31802.00  73.0%
        +-DDES_UNROLL -DDES_RISC2
        +
        diff --git a/vendor/openssl/openssl/crypto/des/times/586-100.lnx b/vendor/openssl/openssl/crypto/des/times/586-100.lnx
        new file mode 100644
        index 000000000..4323914a1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/586-100.lnx
        @@ -0,0 +1,20 @@
        +Pentium 100
        +Linux 2 kernel
        +gcc 2.7.0 -O3 -fomit-frame-pointer
        +No X server running, just a console, it makes the top speed jump from 151,000
        +to 158,000 :-).
        +options    des ecb/s
        +assember   281000.00 177.1%
        +16 r1 p    158667.40 100.0%
        +16 r1 i    148471.70  93.6%
        +16 r2 p    143961.80  90.7%
        +16 r2 i    141689.20  89.3%
        + 4 r1 i    140100.00  88.3%
        + 4 r2 i    134049.40  84.5%
        +16  c i    124145.20  78.2%
        +16  c p    121584.20  76.6%
        + 4  c i    118116.00  74.4%
        + 4 r2 p    117977.90  74.4%
        + 4  c p    114971.40  72.5%
        + 4 r1 p    114578.40  72.2%
        +-DDES_UNROLL -DDES_RISC1 -DDES_PTR
        diff --git a/vendor/openssl/openssl/crypto/des/times/686-200.fre b/vendor/openssl/openssl/crypto/des/times/686-200.fre
        new file mode 100644
        index 000000000..7d83f6ade
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/686-200.fre
        @@ -0,0 +1,18 @@
        +Pentium 100
        +Free BSD 2.1.5 kernel
        +gcc 2.7.2.2 -O3 -fomit-frame-pointer
        +options    des ecb/s
        +assember   578000.00 133.1%
        +16 r2 i    434454.80 100.0%
        +16 r1 i    433621.43  99.8%
        +16 r2 p    431375.69  99.3%
        + 4 r1 i    423722.30  97.5%
        + 4 r2 i    422399.40  97.2%
        +16 r1 p    421739.40  97.1%
        +16  c i    399027.94  91.8%
        +16  c p    372251.70  85.7%
        + 4  c i    365118.35  84.0%
        + 4  c p    352880.51  81.2%
        + 4 r2 p    255104.90  58.7%
        + 4 r1 p    251289.18  57.8%
        +-DDES_UNROLL -DDES_RISC2
        diff --git a/vendor/openssl/openssl/crypto/des/times/aix.cc b/vendor/openssl/openssl/crypto/des/times/aix.cc
        new file mode 100644
        index 000000000..d96b74e2c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/aix.cc
        @@ -0,0 +1,26 @@
        +From: Paco Garcia <pgarcia@cam.es>
        +
        +This machine is a Bull Estrella  Minitower Model MT604-100
        +Processor        : PPC604 
        +P.Speed          : 100Mhz 
        +Data/Instr Cache :    16 K
        +L2 Cache         :   256 K
        +PCI BUS Speed    :    33 Mhz
        +TransfRate PCI   :   132 MB/s
        +Memory           :    96 MB
        +
        +options    des ecb/s       
        + 4  c p    275118.61 100.0%
        + 4  c i    273545.07  99.4%
        + 4 r2 p    270441.02  98.3%
        + 4 r1 p    253052.15  92.0%
        + 4 r2 i    240842.97  87.5%
        + 4 r1 i    240556.66  87.4%
        +16  c i    224603.99  81.6%
        +16  c p    224483.98  81.6%
        +16 r2 p    215691.19  78.4%
        +16 r1 p    208332.83  75.7%
        +16 r1 i    199206.50  72.4%
        +16 r2 i    198963.70  72.3%
        +-DDES_PTR
        +
        diff --git a/vendor/openssl/openssl/crypto/des/times/alpha.cc b/vendor/openssl/openssl/crypto/des/times/alpha.cc
        new file mode 100644
        index 000000000..95c17efae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/alpha.cc
        @@ -0,0 +1,18 @@
        +cc -O2
        +DES_LONG is 'unsigned int'
        +
        +options    des ecb/s
        + 4 r2 p    181146.14 100.0%
        +16 r2 p    172102.94  95.0%
        + 4 r2 i    165424.11  91.3%
        +16  c p    160468.64  88.6%
        + 4  c p    156653.59  86.5%
        + 4  c i    155245.18  85.7%
        + 4 r1 p    154729.68  85.4%
        +16 r2 i    154137.69  85.1%
        +16 r1 p    152357.96  84.1%
        +16  c i    148743.91  82.1%
        + 4 r1 i    146695.59  81.0%
        +16 r1 i    144961.00  80.0%
        +-DDES_RISC2 -DDES_PTR
        +
        diff --git a/vendor/openssl/openssl/crypto/des/times/hpux.cc b/vendor/openssl/openssl/crypto/des/times/hpux.cc
        new file mode 100644
        index 000000000..3de856dda
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/hpux.cc
        @@ -0,0 +1,17 @@
        +HPUX 10 - 9000/887 - cc -D_HPUX_SOURCE -Aa +ESlit +O2 -Wl,-a,archive
        +
        +options    des ecb/s
        +16  c i    149448.90 100.0%
        + 4  c i    145861.79  97.6%
        +16 r2 i    141710.96  94.8%
        +16 r1 i    139455.33  93.3%
        + 4 r2 i    138800.00  92.9%
        + 4 r1 i    136692.65  91.5%
        +16 r2 p    110228.17  73.8%
        +16 r1 p    109397.07  73.2%
        +16  c p    109209.89  73.1%
        + 4  c p    108014.71  72.3%
        + 4 r2 p    107873.88  72.2%
        + 4 r1 p    107685.83  72.1%
        +-DDES_UNROLL
        +
        diff --git a/vendor/openssl/openssl/crypto/des/times/sparc.gcc b/vendor/openssl/openssl/crypto/des/times/sparc.gcc
        new file mode 100644
        index 000000000..8eaa04210
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/sparc.gcc
        @@ -0,0 +1,17 @@
        +solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2
        +
        +options    des ecb/s
        +16  c i    124382.70 100.0%
        + 4  c i    118884.68  95.6%
        +16  c p    112261.20  90.3%
        +16 r2 i    111777.10  89.9%
        +16 r2 p    108896.30  87.5%
        +16 r1 p    108791.59  87.5%
        + 4  c p    107290.10  86.3%
        + 4 r1 p    104583.80  84.1%
        +16 r1 i    104206.20  83.8%
        + 4 r2 p    103709.80  83.4%
        + 4 r2 i     98306.43  79.0%
        + 4 r1 i     91525.80  73.6%
        +-DDES_UNROLL
        +      
        diff --git a/vendor/openssl/openssl/crypto/des/times/usparc.cc b/vendor/openssl/openssl/crypto/des/times/usparc.cc
        new file mode 100644
        index 000000000..0864285ef
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/times/usparc.cc
        @@ -0,0 +1,31 @@
        +solaris 2.5.1 usparc 167mhz?? - SC4.0 cc -fast -Xa -xO5
        +
        +For the ultra sparc, SunC 4.0 cc -fast -Xa -xO5, running 'des_opts'
        +gives a speed of 475,000 des/s while 'speed' gives 417,000 des/s.
        +I believe the difference is tied up in optimisation that the compiler
        +is able to perform when the code is 'inlined'.  For 'speed', the DES
        +routines are being linked from a library.  I'll record the higher
        +speed since if performance is everything, you can always inline
        +'des_enc.c'.
        +
        +[ 16-Jan-06 - I've been playing with the
        +  '-xtarget=ultra -xarch=v8plus -Xa -xO5 -Xa'
        +  and while it makes the des_opts numbers much slower, it makes the
        +  actual 'speed' numbers look better which is a realistic version of
        +  using the libraries. ]
        +
        +options    des ecb/s
        +16 r1 p    475516.90 100.0%
        +16 r2 p    439388.10  92.4%
        +16  c i    427001.40  89.8%
        +16  c p    419516.50  88.2%
        + 4 r2 p    409491.70  86.1%
        + 4 r1 p    404266.90  85.0%
        + 4  c p    398121.00  83.7%
        + 4  c i    370588.40  77.9%
        + 4 r1 i    362742.20  76.3%
        +16 r2 i    331275.50  69.7%
        +16 r1 i    324730.60  68.3%
        + 4 r2 i     63535.10  13.4%	<-- very very weird, must be cache problems.
        +-DDES_UNROLL -DDES_RISC1 -DDES_PTR
        +
        diff --git a/vendor/openssl/openssl/crypto/des/typemap b/vendor/openssl/openssl/crypto/des/typemap
        new file mode 100644
        index 000000000..a524f5363
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/typemap
        @@ -0,0 +1,34 @@
        +#
        +# DES SECTION
        +#
        +deschar *	T_DESCHARP
        +des_cblock *	T_CBLOCK
        +des_cblock	T_CBLOCK
        +des_key_schedule	T_SCHEDULE
        +des_key_schedule *	T_SCHEDULE
        +
        +INPUT
        +T_CBLOCK
        +	$var=(des_cblock *)SvPV($arg,len);
        +	if (len < DES_KEY_SZ)
        +		{
        +		croak(\"$var needs to be at least %u bytes long\",DES_KEY_SZ);
        +		}
        +
        +T_SCHEDULE
        +	$var=(des_key_schedule *)SvPV($arg,len);
        +	if (len < DES_SCHEDULE_SZ)
        +		{
        +		croak(\"$var needs to be at least %u bytes long\",
        +			DES_SCHEDULE_SZ);
        +		}
        +
        +OUTPUT
        +T_CBLOCK
        +	sv_setpvn($arg,(char *)$var,DES_KEY_SZ);
        +
        +T_SCHEDULE
        +	sv_setpvn($arg,(char *)$var,DES_SCHEDULE_SZ);
        +
        +T_DESCHARP
        +	sv_setpvn($arg,(char *)$var,len);
        diff --git a/vendor/openssl/openssl/crypto/des/xcbc_enc.c b/vendor/openssl/openssl/crypto/des/xcbc_enc.c
        new file mode 100644
        index 000000000..058cab6bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/des/xcbc_enc.c
        @@ -0,0 +1,197 @@
        +/* crypto/des/xcbc_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "des_locl.h"
        +
        +/* RSA's DESX */
        +
        +#if 0 /* broken code, preserved just in case anyone specifically looks for this */
        +static const unsigned char desx_white_in2out[256]={
        +0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0,
        +0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,
        +0x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
        +0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0,0xA6,0x3F,0xD8,0x0C,
        +0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17,0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,
        +0x48,0xE6,0x1E,0x53,0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA,
        +0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12,0xBA,0x3C,0x06,0x4E,
        +0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B,0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,
        +0x3A,0xDE,0x96,0x0E,0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6,
        +0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02,0x75,0xD5,0x61,0xE3,
        +0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E,0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,
        +0xB4,0xC5,0xCC,0x70,0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2,
        +0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B,0x82,0xF9,0x40,0xB5,
        +0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97,0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,
        +0x64,0x6D,0x7A,0xD4,0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F,
        +0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9,0x4C,0xFF,0x43,0xAB,
        +	};
        +
        +void DES_xwhite_in2out(const_DES_cblock *des_key, const_DES_cblock *in_white,
        +	     DES_cblock *out_white)
        +	{
        +	int out0,out1;
        +	int i;
        +	const unsigned char *key = &(*des_key)[0];
        +	const unsigned char *in = &(*in_white)[0];
        +	unsigned char *out = &(*out_white)[0];
        +
        +	out[0]=out[1]=out[2]=out[3]=out[4]=out[5]=out[6]=out[7]=0;
        +	out0=out1=0;
        +	for (i=0; i<8; i++)
        +		{
        +		out[i]=key[i]^desx_white_in2out[out0^out1];
        +		out0=out1;
        +		out1=(int)out[i&0x07];
        +		}
        +
        +	out0=out[0];
        +	out1=out[i]; /* BUG: out-of-bounds read */
        +	for (i=0; i<8; i++)
        +		{
        +		out[i]=in[i]^desx_white_in2out[out0^out1];
        +		out0=out1;
        +		out1=(int)out[i&0x07];
        +		}
        +	}
        +#endif
        +
        +void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
        +		      long length, DES_key_schedule *schedule,
        +		      DES_cblock *ivec, const_DES_cblock *inw,
        +		      const_DES_cblock *outw, int enc)
        +	{
        +	register DES_LONG tin0,tin1;
        +	register DES_LONG tout0,tout1,xor0,xor1;
        +	register DES_LONG inW0,inW1,outW0,outW1;
        +	register const unsigned char *in2;
        +	register long l=length;
        +	DES_LONG tin[2];
        +	unsigned char *iv;
        +
        +	in2 = &(*inw)[0];
        +	c2l(in2,inW0);
        +	c2l(in2,inW1);
        +	in2 = &(*outw)[0];
        +	c2l(in2,outW0);
        +	c2l(in2,outW1);
        +
        +	iv = &(*ivec)[0];
        +
        +	if (enc)
        +		{
        +		c2l(iv,tout0);
        +		c2l(iv,tout1);
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			tin0^=tout0^inW0; tin[0]=tin0;
        +			tin1^=tout1^inW1; tin[1]=tin1;
        +			DES_encrypt1(tin,schedule,DES_ENCRYPT);
        +			tout0=tin[0]^outW0; l2c(tout0,out);
        +			tout1=tin[1]^outW1; l2c(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			c2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0^inW0; tin[0]=tin0;
        +			tin1^=tout1^inW1; tin[1]=tin1;
        +			DES_encrypt1(tin,schedule,DES_ENCRYPT);
        +			tout0=tin[0]^outW0; l2c(tout0,out);
        +			tout1=tin[1]^outW1; l2c(tout1,out);
        +			}
        +		iv = &(*ivec)[0];
        +		l2c(tout0,iv);
        +		l2c(tout1,iv);
        +		}
        +	else
        +		{
        +		c2l(iv,xor0);
        +		c2l(iv,xor1);
        +		for (l-=8; l>0; l-=8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0^outW0;
        +			c2l(in,tin1); tin[1]=tin1^outW1;
        +			DES_encrypt1(tin,schedule,DES_DECRYPT);
        +			tout0=tin[0]^xor0^inW0;
        +			tout1=tin[1]^xor1^inW1;
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0^outW0;
        +			c2l(in,tin1); tin[1]=tin1^outW1;
        +			DES_encrypt1(tin,schedule,DES_DECRYPT);
        +			tout0=tin[0]^xor0^inW0;
        +			tout1=tin[1]^xor1^inW1;
        +			l2cn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +
        +		iv = &(*ivec)[0];
        +		l2c(xor0,iv);
        +		l2c(xor1,iv);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	inW0=inW1=outW0=outW1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/dh/Makefile b/vendor/openssl/openssl/crypto/dh/Makefile
        new file mode 100644
        index 000000000..f23b4f7fd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/Makefile
        @@ -0,0 +1,180 @@
        +#
        +# OpenSSL/crypto/dh/Makefile
        +#
        +
        +DIR=	dh
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST= dhtest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \
        +	dh_ameth.c dh_pmeth.c dh_prn.c
        +LIBOBJ= dh_asn1.o dh_gen.o dh_key.o dh_lib.o dh_check.o dh_err.o dh_depr.o \
        +	dh_ameth.o dh_pmeth.o dh_prn.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= dh.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +dh_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
        +dh_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dh_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dh_ameth.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +dh_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +dh_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +dh_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +dh_ameth.o: ../../include/openssl/opensslconf.h
        +dh_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dh_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +dh_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dh_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +dh_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +dh_ameth.o: dh_ameth.c
        +dh_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
        +dh_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +dh_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +dh_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +dh_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +dh_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dh_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +dh_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dh_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dh_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_asn1.c
        +dh_check.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dh_check.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dh_check.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dh_check.o: ../../include/openssl/opensslconf.h
        +dh_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dh_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dh_check.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_check.c
        +dh_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dh_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dh_depr.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_depr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dh_depr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dh_depr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dh_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dh_depr.o: ../cryptlib.h dh_depr.c
        +dh_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +dh_err.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dh_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dh_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dh_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dh_err.o: dh_err.c
        +dh_gen.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dh_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dh_gen.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_gen.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dh_gen.o: ../cryptlib.h dh_gen.c
        +dh_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dh_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dh_key.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dh_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dh_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_key.c
        +dh_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +dh_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +dh_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +dh_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +dh_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +dh_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +dh_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +dh_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dh_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +dh_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dh_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +dh_lib.o: ../cryptlib.h dh_lib.c
        +dh_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +dh_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +dh_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +dh_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +dh_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +dh_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +dh_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +dh_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dh_pmeth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +dh_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dh_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +dh_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dh_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +dh_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
        +dh_pmeth.o: dh_pmeth.c
        +dh_prn.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +dh_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dh_prn.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
        +dh_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +dh_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dh_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +dh_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dh_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dh_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_prn.c
        diff --git a/vendor/openssl/openssl/crypto/dh/dh.h b/vendor/openssl/openssl/crypto/dh/dh.h
        new file mode 100644
        index 000000000..ea59e610e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh.h
        @@ -0,0 +1,280 @@
        +/* crypto/dh/dh.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_DH_H
        +#define HEADER_DH_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifdef OPENSSL_NO_DH
        +#error DH is disabled.
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#endif
        +	
        +#ifndef OPENSSL_DH_MAX_MODULUS_BITS
        +# define OPENSSL_DH_MAX_MODULUS_BITS	10000
        +#endif
        +
        +#define DH_FLAG_CACHE_MONT_P     0x01
        +#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
        +                                       * implementation now uses constant time
        +                                       * modular exponentiation for secret exponents
        +                                       * by default. This flag causes the
        +                                       * faster variable sliding window method to
        +                                       * be used for all exponents.
        +                                       */
        +
        +/* If this flag is set the DH method is FIPS compliant and can be used
        + * in FIPS mode. This is set in the validated module method. If an
        + * application sets this flag in its own methods it is its reposibility
        + * to ensure the result is compliant.
        + */
        +
        +#define DH_FLAG_FIPS_METHOD			0x0400
        +
        +/* If this flag is set the operations normally disabled in FIPS mode are
        + * permitted it is then the applications responsibility to ensure that the
        + * usage is compliant.
        + */
        +
        +#define DH_FLAG_NON_FIPS_ALLOW			0x0400
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Already defined in ossl_typ.h */
        +/* typedef struct dh_st DH; */
        +/* typedef struct dh_method DH_METHOD; */
        +
        +struct dh_method
        +	{
        +	const char *name;
        +	/* Methods here */
        +	int (*generate_key)(DH *dh);
        +	int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh);
        +	int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +				const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +				BN_MONT_CTX *m_ctx); /* Can be null */
        +
        +	int (*init)(DH *dh);
        +	int (*finish)(DH *dh);
        +	int flags;
        +	char *app_data;
        +	/* If this is non-NULL, it will be used to generate parameters */
        +	int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb);
        +	};
        +
        +struct dh_st
        +	{
        +	/* This first argument is used to pick up errors when
        +	 * a DH is passed instead of a EVP_PKEY */
        +	int pad;
        +	int version;
        +	BIGNUM *p;
        +	BIGNUM *g;
        +	long length; /* optional */
        +	BIGNUM *pub_key;	/* g^x */
        +	BIGNUM *priv_key;	/* x */
        +
        +	int flags;
        +	BN_MONT_CTX *method_mont_p;
        +	/* Place holders if we want to do X9.42 DH */
        +	BIGNUM *q;
        +	BIGNUM *j;
        +	unsigned char *seed;
        +	int seedlen;
        +	BIGNUM *counter;
        +
        +	int references;
        +	CRYPTO_EX_DATA ex_data;
        +	const DH_METHOD *meth;
        +	ENGINE *engine;
        +	};
        +
        +#define DH_GENERATOR_2		2
        +/* #define DH_GENERATOR_3	3 */
        +#define DH_GENERATOR_5		5
        +
        +/* DH_check error codes */
        +#define DH_CHECK_P_NOT_PRIME		0x01
        +#define DH_CHECK_P_NOT_SAFE_PRIME	0x02
        +#define DH_UNABLE_TO_CHECK_GENERATOR	0x04
        +#define DH_NOT_SUITABLE_GENERATOR	0x08
        +
        +/* DH_check_pub_key error codes */
        +#define DH_CHECK_PUBKEY_TOO_SMALL	0x01
        +#define DH_CHECK_PUBKEY_TOO_LARGE	0x02
        +
        +/* primes p where (p-1)/2 is prime too are called "safe"; we define
        +   this for backward compatibility: */
        +#define DH_CHECK_P_NOT_STRONG_PRIME	DH_CHECK_P_NOT_SAFE_PRIME
        +
        +#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
        +		(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
        +#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
        +		(unsigned char *)(x))
        +#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
        +#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
        +
        +DH *DHparams_dup(DH *);
        +
        +const DH_METHOD *DH_OpenSSL(void);
        +
        +void DH_set_default_method(const DH_METHOD *meth);
        +const DH_METHOD *DH_get_default_method(void);
        +int DH_set_method(DH *dh, const DH_METHOD *meth);
        +DH *DH_new_method(ENGINE *engine);
        +
        +DH *	DH_new(void);
        +void	DH_free(DH *dh);
        +int	DH_up_ref(DH *dh);
        +int	DH_size(const DH *dh);
        +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int DH_set_ex_data(DH *d, int idx, void *arg);
        +void *DH_get_ex_data(DH *d, int idx);
        +
        +/* Deprecated version */
        +#ifndef OPENSSL_NO_DEPRECATED
        +DH *	DH_generate_parameters(int prime_len,int generator,
        +		void (*callback)(int,int,void *),void *cb_arg);
        +#endif /* !defined(OPENSSL_NO_DEPRECATED) */
        +
        +/* New version */
        +int	DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb);
        +
        +int	DH_check(const DH *dh,int *codes);
        +int	DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes);
        +int	DH_generate_key(DH *dh);
        +int	DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
        +DH *	d2i_DHparams(DH **a,const unsigned char **pp, long length);
        +int	i2d_DHparams(const DH *a,unsigned char **pp);
        +#ifndef OPENSSL_NO_FP_API
        +int	DHparams_print_fp(FILE *fp, const DH *x);
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +int	DHparams_print(BIO *bp, const DH *x);
        +#else
        +int	DHparams_print(char *bp, const DH *x);
        +#endif
        +
        +#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
        +			EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
        +
        +#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
        +			EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
        +
        +#define	EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN	(EVP_PKEY_ALG_CTRL + 1)
        +#define	EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR	(EVP_PKEY_ALG_CTRL + 2)
        +		
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_DH_strings(void);
        +
        +/* Error codes for the DH functions. */
        +
        +/* Function codes. */
        +#define DH_F_COMPUTE_KEY				 102
        +#define DH_F_DHPARAMS_PRINT_FP				 101
        +#define DH_F_DH_BUILTIN_GENPARAMS			 106
        +#define DH_F_DH_COMPUTE_KEY				 114
        +#define DH_F_DH_GENERATE_KEY				 115
        +#define DH_F_DH_GENERATE_PARAMETERS_EX			 116
        +#define DH_F_DH_NEW_METHOD				 105
        +#define DH_F_DH_PARAM_DECODE				 107
        +#define DH_F_DH_PRIV_DECODE				 110
        +#define DH_F_DH_PRIV_ENCODE				 111
        +#define DH_F_DH_PUB_DECODE				 108
        +#define DH_F_DH_PUB_ENCODE				 109
        +#define DH_F_DO_DH_PRINT				 100
        +#define DH_F_GENERATE_KEY				 103
        +#define DH_F_GENERATE_PARAMETERS			 104
        +#define DH_F_PKEY_DH_DERIVE				 112
        +#define DH_F_PKEY_DH_KEYGEN				 113
        +
        +/* Reason codes. */
        +#define DH_R_BAD_GENERATOR				 101
        +#define DH_R_BN_DECODE_ERROR				 109
        +#define DH_R_BN_ERROR					 106
        +#define DH_R_DECODE_ERROR				 104
        +#define DH_R_INVALID_PUBKEY				 102
        +#define DH_R_KEYS_NOT_SET				 108
        +#define DH_R_KEY_SIZE_TOO_SMALL				 110
        +#define DH_R_MODULUS_TOO_LARGE				 103
        +#define DH_R_NON_FIPS_METHOD				 111
        +#define DH_R_NO_PARAMETERS_SET				 107
        +#define DH_R_NO_PRIVATE_VALUE				 100
        +#define DH_R_PARAMETER_ENCODING_ERROR			 105
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dh/dh1024.pem b/vendor/openssl/openssl/crypto/dh/dh1024.pem
        new file mode 100644
        index 000000000..81d43f6a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh1024.pem
        @@ -0,0 +1,5 @@
        +-----BEGIN DH PARAMETERS-----
        +MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
        +/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
        +/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
        +-----END DH PARAMETERS-----
        diff --git a/vendor/openssl/openssl/crypto/dh/dh192.pem b/vendor/openssl/openssl/crypto/dh/dh192.pem
        new file mode 100644
        index 000000000..521c07271
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh192.pem
        @@ -0,0 +1,3 @@
        +-----BEGIN DH PARAMETERS-----
        +MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
        +-----END DH PARAMETERS-----
        diff --git a/vendor/openssl/openssl/crypto/dh/dh2048.pem b/vendor/openssl/openssl/crypto/dh/dh2048.pem
        new file mode 100644
        index 000000000..295460f50
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh2048.pem
        @@ -0,0 +1,16 @@
        +-----BEGIN DH PARAMETERS-----
        +MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o
        +AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh
        +z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo
        +pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW
        +aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA
        +Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==
        +-----END DH PARAMETERS-----
        +-----BEGIN DH PARAMETERS-----
        +MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5
        +8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F
        +SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt
        +gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok
        +yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N
        +a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg==
        +-----END DH PARAMETERS-----
        diff --git a/vendor/openssl/openssl/crypto/dh/dh4096.pem b/vendor/openssl/openssl/crypto/dh/dh4096.pem
        new file mode 100644
        index 000000000..390943a21
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh4096.pem
        @@ -0,0 +1,14 @@
        +-----BEGIN DH PARAMETERS-----
        +MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7
        +vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H
        +TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF
        +bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1
        +rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE
        +EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9
        +bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3
        +W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH
        +ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb
        +NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR
        +jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=
        +-----END DH PARAMETERS-----
        +
        diff --git a/vendor/openssl/openssl/crypto/dh/dh512.pem b/vendor/openssl/openssl/crypto/dh/dh512.pem
        new file mode 100644
        index 000000000..0a4d863eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh512.pem
        @@ -0,0 +1,4 @@
        +-----BEGIN DH PARAMETERS-----
        +MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
        +a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
        +-----END DH PARAMETERS-----
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_ameth.c b/vendor/openssl/openssl/crypto/dh/dh_ameth.c
        new file mode 100644
        index 000000000..02ec2d47b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_ameth.c
        @@ -0,0 +1,501 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include <openssl/dh.h>
        +#include <openssl/bn.h>
        +#include "asn1_locl.h"
        +
        +static void int_dh_free(EVP_PKEY *pkey)
        +	{
        +	DH_free(pkey->pkey.dh);
        +	}
        +
        +static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
        +	{
        +	const unsigned char *p, *pm;
        +	int pklen, pmlen;
        +	int ptype;
        +	void *pval;
        +	ASN1_STRING *pstr;
        +	X509_ALGOR *palg;
        +	ASN1_INTEGER *public_key = NULL;
        +
        +	DH *dh = NULL;
        +
        +	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
        +		return 0;
        +	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
        +
        +	if (ptype != V_ASN1_SEQUENCE)
        +		{
        +		DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
        +		goto err;
        +		}
        +
        +	pstr = pval;	
        +	pm = pstr->data;
        +	pmlen = pstr->length;
        +
        +	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
        +		{
        +		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
        +		{
        +		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	/* We have parameters now set public key */
        +	if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
        +		{
        +		DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	ASN1_INTEGER_free(public_key);
        +	EVP_PKEY_assign_DH(pkey, dh);
        +	return 1;
        +
        +	err:
        +	if (public_key)
        +		ASN1_INTEGER_free(public_key);
        +	if (dh)
        +		DH_free(dh);
        +	return 0;
        +
        +	}
        +
        +static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
        +	{
        +	DH *dh;
        +	void *pval = NULL;
        +	int ptype;
        +	unsigned char *penc = NULL;
        +	int penclen;
        +	ASN1_STRING *str;
        +	ASN1_INTEGER *pub_key = NULL;
        +
        +	dh=pkey->pkey.dh;
        +
        +	str = ASN1_STRING_new();
        +	str->length = i2d_DHparams(dh, &str->data);
        +	if (str->length <= 0)
        +		{
        +		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	pval = str;
        +	ptype = V_ASN1_SEQUENCE;
        +
        +	pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
        +	if (!pub_key)
        +		goto err;
        +
        +	penclen = i2d_ASN1_INTEGER(pub_key, &penc);
        +
        +	ASN1_INTEGER_free(pub_key);
        +
        +	if (penclen <= 0)
        +		{
        +		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH),
        +				ptype, pval, penc, penclen))
        +		return 1;
        +
        +	err:
        +	if (penc)
        +		OPENSSL_free(penc);
        +	if (pval)
        +		ASN1_STRING_free(pval);
        +
        +	return 0;
        +	}
        +
        +
        +/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
        + * that the AlgorithmIdentifier contains the paramaters, the private key
        + * is explcitly included and the pubkey must be recalculated.
        + */
        +	
        +static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
        +	{
        +	const unsigned char *p, *pm;
        +	int pklen, pmlen;
        +	int ptype;
        +	void *pval;
        +	ASN1_STRING *pstr;
        +	X509_ALGOR *palg;
        +	ASN1_INTEGER *privkey = NULL;
        +
        +	DH *dh = NULL;
        +
        +	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
        +		return 0;
        +
        +	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
        +
        +	if (ptype != V_ASN1_SEQUENCE)
        +			goto decerr;
        +
        +	if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
        +		goto decerr;
        +
        +
        +	pstr = pval;	
        +	pm = pstr->data;
        +	pmlen = pstr->length;
        +	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
        +		goto decerr;
        +	/* We have parameters now set private key */
        +	if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
        +		{
        +		DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
        +		goto dherr;
        +		}
        +	/* Calculate public key */
        +	if (!DH_generate_key(dh))
        +		goto dherr;
        +
        +	EVP_PKEY_assign_DH(pkey, dh);
        +
        +	ASN1_INTEGER_free(privkey);
        +
        +	return 1;
        +
        +	decerr:
        +	DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
        +	dherr:
        +	DH_free(dh);
        +	return 0;
        +	}
        +
        +static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
        +{
        +	ASN1_STRING *params = NULL;
        +	ASN1_INTEGER *prkey = NULL;
        +	unsigned char *dp = NULL;
        +	int dplen;
        +
        +	params = ASN1_STRING_new();
        +
        +	if (!params)
        +		{
        +		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
        +	if (params->length <= 0)
        +		{
        +		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	params->type = V_ASN1_SEQUENCE;
        +
        +	/* Get private key into integer */
        +	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
        +
        +	if (!prkey)
        +		{
        +		DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
        +		goto err;
        +		}
        +
        +	dplen = i2d_ASN1_INTEGER(prkey, &dp);
        +
        +	ASN1_INTEGER_free(prkey);
        +
        +	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
        +				V_ASN1_SEQUENCE, params, dp, dplen))
        +		goto err;
        +
        +	return 1;
        +
        +err:
        +	if (dp != NULL)
        +		OPENSSL_free(dp);
        +	if (params != NULL)
        +		ASN1_STRING_free(params);
        +	if (prkey != NULL)
        +		ASN1_INTEGER_free(prkey);
        +	return 0;
        +}
        +
        +
        +static void update_buflen(const BIGNUM *b, size_t *pbuflen)
        +	{
        +	size_t i;
        +	if (!b)
        +		return;
        +	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
        +			*pbuflen = i;
        +	}
        +
        +static int dh_param_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	DH *dh;
        +	if (!(dh = d2i_DHparams(NULL, pder, derlen)))
        +		{
        +		DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_DH(pkey, dh);
        +	return 1;
        +	}
        +
        +static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	return i2d_DHparams(pkey->pkey.dh, pder);
        +	}
        +
        +static int do_dh_print(BIO *bp, const DH *x, int indent,
        +						ASN1_PCTX *ctx, int ptype)
        +	{
        +	unsigned char *m=NULL;
        +	int reason=ERR_R_BUF_LIB,ret=0;
        +	size_t buf_len=0;
        +
        +	const char *ktype = NULL;
        +
        +	BIGNUM *priv_key, *pub_key;
        +
        +	if (ptype == 2)
        +		priv_key = x->priv_key;
        +	else
        +		priv_key = NULL;
        +
        +	if (ptype > 0)
        +		pub_key = x->pub_key;
        +	else
        +		pub_key = NULL;
        +
        +	update_buflen(x->p, &buf_len);
        +
        +	if (buf_len == 0)
        +		{
        +		reason = ERR_R_PASSED_NULL_PARAMETER;
        +		goto err;
        +		}
        +
        +	update_buflen(x->g, &buf_len);
        +	update_buflen(pub_key, &buf_len);
        +	update_buflen(priv_key, &buf_len);
        +
        +	if (ptype == 2)
        +		ktype = "PKCS#3 DH Private-Key";
        +	else if (ptype == 1)
        +		ktype = "PKCS#3 DH Public-Key";
        +	else
        +		ktype = "PKCS#3 DH Parameters";
        +
        +	m= OPENSSL_malloc(buf_len+10);
        +	if (m == NULL)
        +		{
        +		reason=ERR_R_MALLOC_FAILURE;
        +		goto err;
        +		}
        +
        +	BIO_indent(bp, indent, 128);
        +	if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
        +		goto err;
        +	indent += 4;
        +
        +	if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
        +	if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
        +
        +	if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
        +	if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
        +	if (x->length != 0)
        +		{
        +		BIO_indent(bp, indent, 128);
        +		if (BIO_printf(bp,"recommended-private-length: %d bits\n",
        +			(int)x->length) <= 0) goto err;
        +		}
        +
        +
        +	ret=1;
        +	if (0)
        +		{
        +err:
        +		DHerr(DH_F_DO_DH_PRINT,reason);
        +		}
        +	if (m != NULL) OPENSSL_free(m);
        +	return(ret);
        +	}
        +
        +static int int_dh_size(const EVP_PKEY *pkey)
        +	{
        +	return(DH_size(pkey->pkey.dh));
        +	}
        +
        +static int dh_bits(const EVP_PKEY *pkey)
        +	{
        +	return BN_num_bits(pkey->pkey.dh->p);
        +	}
        +
        +static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (	BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
        +		BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
        +	{
        +	BIGNUM *a;
        +
        +	if ((a=BN_dup(from->pkey.dh->p)) == NULL)
        +		return 0;
        +	if (to->pkey.dh->p != NULL)
        +		BN_free(to->pkey.dh->p);
        +	to->pkey.dh->p=a;
        +
        +	if ((a=BN_dup(from->pkey.dh->g)) == NULL)
        +		return 0;
        +	if (to->pkey.dh->g != NULL)
        +		BN_free(to->pkey.dh->g);
        +	to->pkey.dh->g=a;
        +
        +	return 1;
        +	}
        +
        +static int dh_missing_parameters(const EVP_PKEY *a)
        +	{
        +	if (!a->pkey.dh->p || !a->pkey.dh->g)
        +		return 1;
        +	return 0;
        +	}
        +
        +static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (dh_cmp_parameters(a, b) == 0)
        +		return 0;
        +	if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
        +	}
        +
        +static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
        +	}
        +
        +static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
        +	}
        +
        +int DHparams_print(BIO *bp, const DH *x)
        +	{
        +	return do_dh_print(bp, x, 4, NULL, 0);
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD dh_asn1_meth = 
        +	{
        +	EVP_PKEY_DH,
        +	EVP_PKEY_DH,
        +	0,
        +
        +	"DH",
        +	"OpenSSL PKCS#3 DH method",
        +
        +	dh_pub_decode,
        +	dh_pub_encode,
        +	dh_pub_cmp,
        +	dh_public_print,
        +
        +	dh_priv_decode,
        +	dh_priv_encode,
        +	dh_private_print,
        +
        +	int_dh_size,
        +	dh_bits,
        +
        +	dh_param_decode,
        +	dh_param_encode,
        +	dh_missing_parameters,
        +	dh_copy_parameters,
        +	dh_cmp_parameters,
        +	dh_param_print,
        +	0,
        +
        +	int_dh_free,
        +	0
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_asn1.c b/vendor/openssl/openssl/crypto/dh/dh_asn1.c
        new file mode 100644
        index 000000000..0b4357d60
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_asn1.c
        @@ -0,0 +1,93 @@
        +/* dh_asn1.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +#include <openssl/objects.h>
        +#include <openssl/asn1t.h>
        +
        +/* Override the default free and new methods */
        +static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +						void *exarg)
        +{
        +	if(operation == ASN1_OP_NEW_PRE) {
        +		*pval = (ASN1_VALUE *)DH_new();
        +		if(*pval) return 2;
        +		return 0;
        +	} else if(operation == ASN1_OP_FREE_PRE) {
        +		DH_free((DH *)*pval);
        +		*pval = NULL;
        +		return 2;
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
        +	ASN1_SIMPLE(DH, p, BIGNUM),
        +	ASN1_SIMPLE(DH, g, BIGNUM),
        +	ASN1_OPT(DH, length, ZLONG),
        +} ASN1_SEQUENCE_END_cb(DH, DHparams)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
        +
        +DH *DHparams_dup(DH *dh)
        +	{
        +	return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_check.c b/vendor/openssl/openssl/crypto/dh/dh_check.c
        new file mode 100644
        index 000000000..066898174
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_check.c
        @@ -0,0 +1,142 @@
        +/* crypto/dh/dh_check.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +
        +/* Check that p is a safe prime and
        + * if g is 2, 3 or 5, check that it is a suitable generator
        + * where
        + * for 2, p mod 24 == 11
        + * for 3, p mod 12 == 5
        + * for 5, p mod 10 == 3 or 7
        + * should hold.
        + */
        +
        +int DH_check(const DH *dh, int *ret)
        +	{
        +	int ok=0;
        +	BN_CTX *ctx=NULL;
        +	BN_ULONG l;
        +	BIGNUM *q=NULL;
        +
        +	*ret=0;
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +	q=BN_new();
        +	if (q == NULL) goto err;
        +
        +	if (BN_is_word(dh->g,DH_GENERATOR_2))
        +		{
        +		l=BN_mod_word(dh->p,24);
        +		if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR;
        +		}
        +#if 0
        +	else if (BN_is_word(dh->g,DH_GENERATOR_3))
        +		{
        +		l=BN_mod_word(dh->p,12);
        +		if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR;
        +		}
        +#endif
        +	else if (BN_is_word(dh->g,DH_GENERATOR_5))
        +		{
        +		l=BN_mod_word(dh->p,10);
        +		if ((l != 3) && (l != 7))
        +			*ret|=DH_NOT_SUITABLE_GENERATOR;
        +		}
        +	else
        +		*ret|=DH_UNABLE_TO_CHECK_GENERATOR;
        +
        +	if (!BN_is_prime_ex(dh->p,BN_prime_checks,ctx,NULL))
        +		*ret|=DH_CHECK_P_NOT_PRIME;
        +	else
        +		{
        +		if (!BN_rshift1(q,dh->p)) goto err;
        +		if (!BN_is_prime_ex(q,BN_prime_checks,ctx,NULL))
        +			*ret|=DH_CHECK_P_NOT_SAFE_PRIME;
        +		}
        +	ok=1;
        +err:
        +	if (ctx != NULL) BN_CTX_free(ctx);
        +	if (q != NULL) BN_free(q);
        +	return(ok);
        +	}
        +
        +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
        +	{
        +	int ok=0;
        +	BIGNUM *q=NULL;
        +
        +	*ret=0;
        +	q=BN_new();
        +	if (q == NULL) goto err;
        +	BN_set_word(q,1);
        +	if (BN_cmp(pub_key,q)<=0)
        +		*ret|=DH_CHECK_PUBKEY_TOO_SMALL;
        +	BN_copy(q,dh->p);
        +	BN_sub_word(q,1);
        +	if (BN_cmp(pub_key,q)>=0)
        +		*ret|=DH_CHECK_PUBKEY_TOO_LARGE;
        +
        +	ok = 1;
        +err:
        +	if (q != NULL) BN_free(q);
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_depr.c b/vendor/openssl/openssl/crypto/dh/dh_depr.c
        new file mode 100644
        index 000000000..acc05f252
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_depr.c
        @@ -0,0 +1,83 @@
        +/* crypto/dh/dh_depr.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +
        +/* This file contains deprecated functions as wrappers to the new ones */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +
        +static void *dummy=&dummy;
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +DH *DH_generate_parameters(int prime_len, int generator,
        +	     void (*callback)(int,int,void *), void *cb_arg)
        +	{
        +	BN_GENCB cb;
        +	DH *ret=NULL;
        +
        +	if((ret=DH_new()) == NULL)
        +		return NULL;
        +
        +	BN_GENCB_set_old(&cb, callback, cb_arg);
        +
        +	if(DH_generate_parameters_ex(ret, prime_len, generator, &cb))
        +		return ret;
        +	DH_free(ret);
        +	return NULL;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_err.c b/vendor/openssl/openssl/crypto/dh/dh_err.c
        new file mode 100644
        index 000000000..56d3df735
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_err.c
        @@ -0,0 +1,122 @@
        +/* crypto/dh/dh_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/dh.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
        +
        +static ERR_STRING_DATA DH_str_functs[]=
        +	{
        +{ERR_FUNC(DH_F_COMPUTE_KEY),	"COMPUTE_KEY"},
        +{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP),	"DHparams_print_fp"},
        +{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
        +{ERR_FUNC(DH_F_DH_COMPUTE_KEY),	"DH_compute_key"},
        +{ERR_FUNC(DH_F_DH_GENERATE_KEY),	"DH_generate_key"},
        +{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX),	"DH_generate_parameters_ex"},
        +{ERR_FUNC(DH_F_DH_NEW_METHOD),	"DH_new_method"},
        +{ERR_FUNC(DH_F_DH_PARAM_DECODE),	"DH_PARAM_DECODE"},
        +{ERR_FUNC(DH_F_DH_PRIV_DECODE),	"DH_PRIV_DECODE"},
        +{ERR_FUNC(DH_F_DH_PRIV_ENCODE),	"DH_PRIV_ENCODE"},
        +{ERR_FUNC(DH_F_DH_PUB_DECODE),	"DH_PUB_DECODE"},
        +{ERR_FUNC(DH_F_DH_PUB_ENCODE),	"DH_PUB_ENCODE"},
        +{ERR_FUNC(DH_F_DO_DH_PRINT),	"DO_DH_PRINT"},
        +{ERR_FUNC(DH_F_GENERATE_KEY),	"GENERATE_KEY"},
        +{ERR_FUNC(DH_F_GENERATE_PARAMETERS),	"GENERATE_PARAMETERS"},
        +{ERR_FUNC(DH_F_PKEY_DH_DERIVE),	"PKEY_DH_DERIVE"},
        +{ERR_FUNC(DH_F_PKEY_DH_KEYGEN),	"PKEY_DH_KEYGEN"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA DH_str_reasons[]=
        +	{
        +{ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
        +{ERR_REASON(DH_R_BN_DECODE_ERROR)        ,"bn decode error"},
        +{ERR_REASON(DH_R_BN_ERROR)               ,"bn error"},
        +{ERR_REASON(DH_R_DECODE_ERROR)           ,"decode error"},
        +{ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
        +{ERR_REASON(DH_R_KEYS_NOT_SET)           ,"keys not set"},
        +{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL)     ,"key size too small"},
        +{ERR_REASON(DH_R_MODULUS_TOO_LARGE)      ,"modulus too large"},
        +{ERR_REASON(DH_R_NON_FIPS_METHOD)        ,"non fips method"},
        +{ERR_REASON(DH_R_NO_PARAMETERS_SET)      ,"no parameters set"},
        +{ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
        +{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_DH_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(DH_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,DH_str_functs);
        +		ERR_load_strings(0,DH_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_gen.c b/vendor/openssl/openssl/crypto/dh/dh_gen.c
        new file mode 100644
        index 000000000..7b1fe9c9c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_gen.c
        @@ -0,0 +1,192 @@
        +/* crypto/dh/dh_gen.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* NB: These functions have been upgraded - the previous prototypes are in
        + * dh_depr.c as wrappers to these ones.
        + *  - Geoff
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
        +
        +int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD)
        +			&& !(ret->flags & DH_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD);
        +		return 0;
        +		}
        +#endif
        +	if(ret->meth->generate_params)
        +		return ret->meth->generate_params(ret, prime_len, generator, cb);
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		return FIPS_dh_generate_parameters_ex(ret, prime_len,
        +							generator, cb);
        +#endif
        +	return dh_builtin_genparams(ret, prime_len, generator, cb);
        +	}
        +
        +/* We generate DH parameters as follows
        + * find a prime q which is prime_len/2 bits long.
        + * p=(2*q)+1 or (p-1)/2 = q
        + * For this case, g is a generator if
        + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
        + * Since the factors of p-1 are q and 2, we just need to check
        + * g^2 mod p != 1 and g^q mod p != 1.
        + *
        + * Having said all that,
        + * there is another special case method for the generators 2, 3 and 5.
        + * for 2, p mod 24 == 11
        + * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
        + * for 5, p mod 10 == 3 or 7
        + *
        + * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
        + * special generators and for answering some of my questions.
        + *
        + * I've implemented the second simple method :-).
        + * Since DH should be using a safe prime (both p and q are prime),
        + * this generator function can take a very very long time to run.
        + */
        +/* Actually there is no reason to insist that 'generator' be a generator.
        + * It's just as OK (and in some sense better) to use a generator of the
        + * order-q subgroup.
        + */
        +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
        +	{
        +	BIGNUM *t1,*t2;
        +	int g,ok= -1;
        +	BN_CTX *ctx=NULL;
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	t1 = BN_CTX_get(ctx);
        +	t2 = BN_CTX_get(ctx);
        +	if (t1 == NULL || t2 == NULL) goto err;
        +
        +	/* Make sure 'ret' has the necessary elements */
        +	if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
        +	if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
        +	
        +	if (generator <= 1)
        +		{
        +		DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
        +		goto err;
        +		}
        +	if (generator == DH_GENERATOR_2)
        +		{
        +		if (!BN_set_word(t1,24)) goto err;
        +		if (!BN_set_word(t2,11)) goto err;
        +		g=2;
        +		}
        +#if 0 /* does not work for safe primes */
        +	else if (generator == DH_GENERATOR_3)
        +		{
        +		if (!BN_set_word(t1,12)) goto err;
        +		if (!BN_set_word(t2,5)) goto err;
        +		g=3;
        +		}
        +#endif
        +	else if (generator == DH_GENERATOR_5)
        +		{
        +		if (!BN_set_word(t1,10)) goto err;
        +		if (!BN_set_word(t2,3)) goto err;
        +		/* BN_set_word(t3,7); just have to miss
        +		 * out on these ones :-( */
        +		g=5;
        +		}
        +	else
        +		{
        +		/* in the general case, don't worry if 'generator' is a
        +		 * generator or not: since we are using safe primes,
        +		 * it will generate either an order-q or an order-2q group,
        +		 * which both is OK */
        +		if (!BN_set_word(t1,2)) goto err;
        +		if (!BN_set_word(t2,1)) goto err;
        +		g=generator;
        +		}
        +	
        +	if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
        +	if(!BN_GENCB_call(cb, 3, 0)) goto err;
        +	if (!BN_set_word(ret->g,g)) goto err;
        +	ok=1;
        +err:
        +	if (ok == -1)
        +		{
        +		DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
        +		ok=0;
        +		}
        +
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	return ok;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_key.c b/vendor/openssl/openssl/crypto/dh/dh_key.c
        new file mode 100644
        index 000000000..89a74db4e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_key.c
        @@ -0,0 +1,292 @@
        +/* crypto/dh/dh_key.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/dh.h>
        +
        +static int generate_key(DH *dh);
        +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
        +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
        +			const BIGNUM *a, const BIGNUM *p,
        +			const BIGNUM *m, BN_CTX *ctx,
        +			BN_MONT_CTX *m_ctx);
        +static int dh_init(DH *dh);
        +static int dh_finish(DH *dh);
        +
        +int DH_generate_key(DH *dh)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
        +			&& !(dh->flags & DH_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD);
        +		return 0;
        +		}
        +#endif
        +	return dh->meth->generate_key(dh);
        +	}
        +
        +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
        +			&& !(dh->flags & DH_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD);
        +		return 0;
        +		}
        +#endif
        +	return dh->meth->compute_key(key, pub_key, dh);
        +	}
        +
        +static DH_METHOD dh_ossl = {
        +"OpenSSL DH Method",
        +generate_key,
        +compute_key,
        +dh_bn_mod_exp,
        +dh_init,
        +dh_finish,
        +0,
        +NULL,
        +NULL
        +};
        +
        +const DH_METHOD *DH_OpenSSL(void)
        +{
        +	return &dh_ossl;
        +}
        +
        +static int generate_key(DH *dh)
        +	{
        +	int ok=0;
        +	int generate_new_key=0;
        +	unsigned l;
        +	BN_CTX *ctx;
        +	BN_MONT_CTX *mont=NULL;
        +	BIGNUM *pub_key=NULL,*priv_key=NULL;
        +
        +	ctx = BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +
        +	if (dh->priv_key == NULL)
        +		{
        +		priv_key=BN_new();
        +		if (priv_key == NULL) goto err;
        +		generate_new_key=1;
        +		}
        +	else
        +		priv_key=dh->priv_key;
        +
        +	if (dh->pub_key == NULL)
        +		{
        +		pub_key=BN_new();
        +		if (pub_key == NULL) goto err;
        +		}
        +	else
        +		pub_key=dh->pub_key;
        +
        +
        +	if (dh->flags & DH_FLAG_CACHE_MONT_P)
        +		{
        +		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
        +				CRYPTO_LOCK_DH, dh->p, ctx);
        +		if (!mont)
        +			goto err;
        +		}
        +
        +	if (generate_new_key)
        +		{
        +		if (dh->q)
        +			{
        +			do
        +				{
        +				if (!BN_rand_range(priv_key, dh->q))
        +					goto err;
        +				}
        +			while (BN_is_zero(priv_key) || BN_is_one(priv_key));
        +			}
        +		else
        +			{
        +			/* secret exponent length */
        +			l = dh->length ? dh->length : BN_num_bits(dh->p)-1;
        +			if (!BN_rand(priv_key, l, 0, 0)) goto err;
        +			}
        +		}
        +
        +	{
        +		BIGNUM local_prk;
        +		BIGNUM *prk;
        +
        +		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
        +			{
        +			BN_init(&local_prk);
        +			prk = &local_prk;
        +			BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
        +			}
        +		else
        +			prk = priv_key;
        +
        +		if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err;
        +	}
        +		
        +	dh->pub_key=pub_key;
        +	dh->priv_key=priv_key;
        +	ok=1;
        +err:
        +	if (ok != 1)
        +		DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);
        +
        +	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
        +	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
        +	BN_CTX_free(ctx);
        +	return(ok);
        +	}
        +
        +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
        +	{
        +	BN_CTX *ctx=NULL;
        +	BN_MONT_CTX *mont=NULL;
        +	BIGNUM *tmp;
        +	int ret= -1;
        +        int check_result;
        +
        +	if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
        +		{
        +		DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
        +		goto err;
        +		}
        +
        +	ctx = BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	tmp = BN_CTX_get(ctx);
        +	
        +	if (dh->priv_key == NULL)
        +		{
        +		DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
        +		goto err;
        +		}
        +
        +	if (dh->flags & DH_FLAG_CACHE_MONT_P)
        +		{
        +		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
        +				CRYPTO_LOCK_DH, dh->p, ctx);
        +		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
        +			{
        +			/* XXX */
        +			BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
        +			}
        +		if (!mont)
        +			goto err;
        +		}
        +
        +        if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result)
        +		{
        +		DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY);
        +		goto err;
        +		}
        +
        +	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
        +		{
        +		DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);
        +		goto err;
        +		}
        +
        +	ret=BN_bn2bin(tmp,key);
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	return(ret);
        +	}
        +
        +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
        +			const BIGNUM *a, const BIGNUM *p,
        +			const BIGNUM *m, BN_CTX *ctx,
        +			BN_MONT_CTX *m_ctx)
        +	{
        +	/* If a is only one word long and constant time is false, use the faster
        +	 * exponenentiation function.
        +	 */
        +	if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0))
        +		{
        +		BN_ULONG A = a->d[0];
        +		return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
        +		}
        +	else
        +		return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
        +	}
        +
        +
        +static int dh_init(DH *dh)
        +	{
        +	dh->flags |= DH_FLAG_CACHE_MONT_P;
        +	return(1);
        +	}
        +
        +static int dh_finish(DH *dh)
        +	{
        +	if(dh->method_mont_p)
        +		BN_MONT_CTX_free(dh->method_mont_p);
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_lib.c b/vendor/openssl/openssl/crypto/dh/dh_lib.c
        new file mode 100644
        index 000000000..00218f2b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_lib.c
        @@ -0,0 +1,260 @@
        +/* crypto/dh/dh_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/dh.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +const char DH_version[]="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
        +
        +static const DH_METHOD *default_DH_method = NULL;
        +
        +void DH_set_default_method(const DH_METHOD *meth)
        +	{
        +	default_DH_method = meth;
        +	}
        +
        +const DH_METHOD *DH_get_default_method(void)
        +	{
        +	if(!default_DH_method)
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return FIPS_dh_openssl();
        +		else
        +			return DH_OpenSSL();
        +#else
        +		default_DH_method = DH_OpenSSL();
        +#endif
        +		}
        +	return default_DH_method;
        +	}
        +
        +int DH_set_method(DH *dh, const DH_METHOD *meth)
        +	{
        +	/* NB: The caller is specifically setting a method, so it's not up to us
        +	 * to deal with which ENGINE it comes from. */
        +        const DH_METHOD *mtmp;
        +        mtmp = dh->meth;
        +        if (mtmp->finish) mtmp->finish(dh);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (dh->engine)
        +		{
        +		ENGINE_finish(dh->engine);
        +		dh->engine = NULL;
        +		}
        +#endif
        +        dh->meth = meth;
        +        if (meth->init) meth->init(dh);
        +        return 1;
        +	}
        +
        +DH *DH_new(void)
        +	{
        +	return DH_new_method(NULL);
        +	}
        +
        +DH *DH_new_method(ENGINE *engine)
        +	{
        +	DH *ret;
        +
        +	ret=(DH *)OPENSSL_malloc(sizeof(DH));
        +	if (ret == NULL)
        +		{
        +		DHerr(DH_F_DH_NEW_METHOD,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +
        +	ret->meth = DH_get_default_method();
        +#ifndef OPENSSL_NO_ENGINE
        +	if (engine)
        +		{
        +		if (!ENGINE_init(engine))
        +			{
        +			DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		ret->engine = engine;
        +		}
        +	else
        +		ret->engine = ENGINE_get_default_DH();
        +	if(ret->engine)
        +		{
        +		ret->meth = ENGINE_get_DH(ret->engine);
        +		if(!ret->meth)
        +			{
        +			DHerr(DH_F_DH_NEW_METHOD,ERR_R_ENGINE_LIB);
        +			ENGINE_finish(ret->engine);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		}
        +#endif
        +
        +	ret->pad=0;
        +	ret->version=0;
        +	ret->p=NULL;
        +	ret->g=NULL;
        +	ret->length=0;
        +	ret->pub_key=NULL;
        +	ret->priv_key=NULL;
        +	ret->q=NULL;
        +	ret->j=NULL;
        +	ret->seed = NULL;
        +	ret->seedlen = 0;
        +	ret->counter = NULL;
        +	ret->method_mont_p=NULL;
        +	ret->references = 1;
        +	ret->flags=ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW;
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
        +	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		if (ret->engine)
        +			ENGINE_finish(ret->engine);
        +#endif
        +		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +		}
        +	return(ret);
        +	}
        +
        +void DH_free(DH *r)
        +	{
        +	int i;
        +	if(r == NULL) return;
        +	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH);
        +#ifdef REF_PRINT
        +	REF_PRINT("DH",r);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"DH_free, bad reference count\n");
        +		abort();
        +	}
        +#endif
        +
        +	if (r->meth->finish)
        +		r->meth->finish(r);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (r->engine)
        +		ENGINE_finish(r->engine);
        +#endif
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
        +
        +	if (r->p != NULL) BN_clear_free(r->p);
        +	if (r->g != NULL) BN_clear_free(r->g);
        +	if (r->q != NULL) BN_clear_free(r->q);
        +	if (r->j != NULL) BN_clear_free(r->j);
        +	if (r->seed) OPENSSL_free(r->seed);
        +	if (r->counter != NULL) BN_clear_free(r->counter);
        +	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
        +	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
        +	OPENSSL_free(r);
        +	}
        +
        +int DH_up_ref(DH *r)
        +	{
        +	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
        +#ifdef REF_PRINT
        +	REF_PRINT("DH",r);
        +#endif
        +#ifdef REF_CHECK
        +	if (i < 2)
        +		{
        +		fprintf(stderr, "DH_up, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +	return ((i > 1) ? 1 : 0);
        +	}
        +
        +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +        {
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp,
        +				new_func, dup_func, free_func);
        +        }
        +
        +int DH_set_ex_data(DH *d, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&d->ex_data,idx,arg));
        +	}
        +
        +void *DH_get_ex_data(DH *d, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&d->ex_data,idx));
        +	}
        +
        +int DH_size(const DH *dh)
        +	{
        +	return(BN_num_bytes(dh->p));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_pmeth.c b/vendor/openssl/openssl/crypto/dh/dh_pmeth.c
        new file mode 100644
        index 000000000..5ae72b7d4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_pmeth.c
        @@ -0,0 +1,254 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/evp.h>
        +#include <openssl/dh.h>
        +#include <openssl/bn.h>
        +#include "evp_locl.h"
        +
        +/* DH pkey context structure */
        +
        +typedef struct
        +	{
        +	/* Parameter gen parameters */
        +	int prime_len;
        +	int generator;
        +	int use_dsa;
        +	/* Keygen callback info */
        +	int gentmp[2];
        +	/* message digest */
        +	} DH_PKEY_CTX;
        +
        +static int pkey_dh_init(EVP_PKEY_CTX *ctx)
        +	{
        +	DH_PKEY_CTX *dctx;
        +	dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
        +	if (!dctx)
        +		return 0;
        +	dctx->prime_len = 1024;
        +	dctx->generator = 2;
        +	dctx->use_dsa = 0;
        +
        +	ctx->data = dctx;
        +	ctx->keygen_info = dctx->gentmp;
        +	ctx->keygen_info_count = 2;
        +	
        +	return 1;
        +	}
        +
        +static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	DH_PKEY_CTX *dctx, *sctx;
        +	if (!pkey_dh_init(dst))
        +		return 0;
        +       	sctx = src->data;
        +	dctx = dst->data;
        +	dctx->prime_len = sctx->prime_len;
        +	dctx->generator = sctx->generator;
        +	dctx->use_dsa = sctx->use_dsa;
        +	return 1;
        +	}
        +
        +static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
        +	{
        +	DH_PKEY_CTX *dctx = ctx->data;
        +	if (dctx)
        +		OPENSSL_free(dctx);
        +	}
        +
        +static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	DH_PKEY_CTX *dctx = ctx->data;
        +	switch (type)
        +		{
        +		case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
        +		if (p1 < 256)
        +			return -2;
        +		dctx->prime_len = p1;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
        +		dctx->generator = p1;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_PEER_KEY:
        +		/* Default behaviour is OK */
        +		return 1;
        +
        +		default:
        +		return -2;
        +
        +		}
        +	}
        +
        +			
        +static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
        +			const char *type, const char *value)
        +	{
        +	if (!strcmp(type, "dh_paramgen_prime_len"))
        +		{
        +		int len;
        +		len = atoi(value);
        +		return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
        +		}
        +	if (!strcmp(type, "dh_paramgen_generator"))
        +		{
        +		int len;
        +		len = atoi(value);
        +		return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
        +		}
        +	return -2;
        +	}
        +
        +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	DH *dh = NULL;
        +	DH_PKEY_CTX *dctx = ctx->data;
        +	BN_GENCB *pcb, cb;
        +	int ret;
        +	if (ctx->pkey_gencb)
        +		{
        +		pcb = &cb;
        +		evp_pkey_set_cb_translate(pcb, ctx);
        +		}
        +	else
        +		pcb = NULL;
        +	dh = DH_new();
        +	if (!dh)
        +		return 0;
        +	ret = DH_generate_parameters_ex(dh,
        +					dctx->prime_len, dctx->generator, pcb);
        +	if (ret)
        +		EVP_PKEY_assign_DH(pkey, dh);
        +	else
        +		DH_free(dh);
        +	return ret;
        +	}
        +
        +static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	DH *dh = NULL;
        +	if (ctx->pkey == NULL)
        +		{
        +		DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
        +		return 0;
        +		}
        +	dh = DH_new();
        +	if (!dh)
        +		return 0;
        +	EVP_PKEY_assign_DH(pkey, dh);
        +	/* Note: if error return, pkey is freed by parent routine */
        +	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
        +		return 0;
        +	return DH_generate_key(pkey->pkey.dh);
        +	}
        +
        +static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
        +	{
        +	int ret;
        +	if (!ctx->pkey || !ctx->peerkey)
        +		{
        +		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
        +		return 0;
        +		}
        +	ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
        +							ctx->pkey->pkey.dh);
        +	if (ret < 0)
        +		return ret;
        +	*keylen = ret;
        +	return 1;
        +	}
        +
        +const EVP_PKEY_METHOD dh_pkey_meth = 
        +	{
        +	EVP_PKEY_DH,
        +	EVP_PKEY_FLAG_AUTOARGLEN,
        +	pkey_dh_init,
        +	pkey_dh_copy,
        +	pkey_dh_cleanup,
        +
        +	0,
        +	pkey_dh_paramgen,
        +
        +	0,
        +	pkey_dh_keygen,
        +
        +	0,
        +	0,
        +
        +	0,
        +	0,
        +
        +	0,0,
        +
        +	0,0,0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,
        +	pkey_dh_derive,
        +
        +	pkey_dh_ctrl,
        +	pkey_dh_ctrl_str
        +
        +	};
        diff --git a/vendor/openssl/openssl/crypto/dh/dh_prn.c b/vendor/openssl/openssl/crypto/dh/dh_prn.c
        new file mode 100644
        index 000000000..ae58c2ac8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dh_prn.c
        @@ -0,0 +1,80 @@
        +/* crypto/asn1/t_pkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/dh.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +int DHparams_print_fp(FILE *fp, const DH *x)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	ret=DHparams_print(b, x);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dh/dhtest.c b/vendor/openssl/openssl/crypto/dh/dhtest.c
        new file mode 100644
        index 000000000..882f5c310
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/dhtest.c
        @@ -0,0 +1,226 @@
        +/* crypto/dh/dhtest.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.]
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +#ifdef OPENSSL_NO_DH
        +int main(int argc, char *argv[])
        +{
        +    printf("No DH support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/dh.h>
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define MS_CALLBACK	_far _loadds
        +#else
        +#define MS_CALLBACK
        +#endif
        +
        +static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg);
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_GENCB _cb;
        +	DH *a;
        +	DH *b=NULL;
        +	char buf[12];
        +	unsigned char *abuf=NULL,*bbuf=NULL;
        +	int i,alen,blen,aout,bout,ret=1;
        +	BIO *out;
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +#ifdef OPENSSL_SYS_WIN32
        +	CRYPTO_malloc_init();
        +#endif
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) EXIT(1);
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +
        +	BN_GENCB_set(&_cb, &cb, out);
        +	if(((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64,
        +				DH_GENERATOR_5, &_cb))
        +		goto err;
        +
        +	if (!DH_check(a, &i)) goto err;
        +	if (i & DH_CHECK_P_NOT_PRIME)
        +		BIO_puts(out, "p value is not prime\n");
        +	if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        +		BIO_puts(out, "p value is not a safe prime\n");
        +	if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        +		BIO_puts(out, "unable to check the generator value\n");
        +	if (i & DH_NOT_SUITABLE_GENERATOR)
        +		BIO_puts(out, "the g value is not a generator\n");
        +
        +	BIO_puts(out,"\np    =");
        +	BN_print(out,a->p);
        +	BIO_puts(out,"\ng    =");
        +	BN_print(out,a->g);
        +	BIO_puts(out,"\n");
        +
        +	b=DH_new();
        +	if (b == NULL) goto err;
        +
        +	b->p=BN_dup(a->p);
        +	b->g=BN_dup(a->g);
        +	if ((b->p == NULL) || (b->g == NULL)) goto err;
        +
        +	/* Set a to run with normal modexp and b to use constant time */
        +	a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
        +	b->flags |= DH_FLAG_NO_EXP_CONSTTIME;
        +
        +	if (!DH_generate_key(a)) goto err;
        +	BIO_puts(out,"pri 1=");
        +	BN_print(out,a->priv_key);
        +	BIO_puts(out,"\npub 1=");
        +	BN_print(out,a->pub_key);
        +	BIO_puts(out,"\n");
        +
        +	if (!DH_generate_key(b)) goto err;
        +	BIO_puts(out,"pri 2=");
        +	BN_print(out,b->priv_key);
        +	BIO_puts(out,"\npub 2=");
        +	BN_print(out,b->pub_key);
        +	BIO_puts(out,"\n");
        +
        +	alen=DH_size(a);
        +	abuf=(unsigned char *)OPENSSL_malloc(alen);
        +	aout=DH_compute_key(abuf,b->pub_key,a);
        +
        +	BIO_puts(out,"key1 =");
        +	for (i=0; i<aout; i++)
        +		{
        +		sprintf(buf,"%02X",abuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +
        +	blen=DH_size(b);
        +	bbuf=(unsigned char *)OPENSSL_malloc(blen);
        +	bout=DH_compute_key(bbuf,a->pub_key,b);
        +
        +	BIO_puts(out,"key2 =");
        +	for (i=0; i<bout; i++)
        +		{
        +		sprintf(buf,"%02X",bbuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
        +		{
        +		fprintf(stderr,"Error in DH routines\n");
        +		ret=1;
        +		}
        +	else
        +		ret=0;
        +err:
        +	ERR_print_errors_fp(stderr);
        +
        +	if (abuf != NULL) OPENSSL_free(abuf);
        +	if (bbuf != NULL) OPENSSL_free(bbuf);
        +	if(b != NULL) DH_free(b);
        +	if(a != NULL) DH_free(a);
        +	BIO_free(out);
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (ret) printf("ERROR: %d\n", ret);
        +#endif
        +	EXIT(ret);
        +	return(ret);
        +	}
        +
        +static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(arg->arg,&c,1);
        +	(void)BIO_flush(arg->arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dh/example b/vendor/openssl/openssl/crypto/dh/example
        new file mode 100644
        index 000000000..16a33d291
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/example
        @@ -0,0 +1,50 @@
        +From owner-cypherpunks@toad.com Mon Sep 25 10:50:51 1995
        +Received: from minbne.mincom.oz.au by orb.mincom.oz.au with SMTP id AA10562
        +  (5.65c/IDA-1.4.4 for eay); Wed, 27 Sep 1995 19:41:55 +1000
        +Received: by minbne.mincom.oz.au id AA19958
        +  (5.65c/IDA-1.4.4 for eay@orb.mincom.oz.au); Wed, 27 Sep 1995 19:34:59 +1000
        +Received: from relay3.UU.NET by bunyip.cc.uq.oz.au with SMTP (PP);
        +          Wed, 27 Sep 1995 19:13:05 +1000
        +Received: from toad.com by relay3.UU.NET with SMTP id QQzizb16156;
        +          Wed, 27 Sep 1995 04:48:46 -0400
        +Received: by toad.com id AA07905; Tue, 26 Sep 95 06:31:45 PDT
        +Received: from by toad.com id AB07851; Tue, 26 Sep 95 06:31:40 PDT
        +Received: from servo.qualcomm.com (servo.qualcomm.com [129.46.128.14]) 
        +          by cygnus.com (8.6.12/8.6.9) with ESMTP id RAA18442 
        +          for <cypherpunks@toad.com>; Mon, 25 Sep 1995 17:52:47 -0700
        +Received: (karn@localhost) by servo.qualcomm.com (8.6.12/QC-BSD-2.5.1) 
        +          id RAA14732; Mon, 25 Sep 1995 17:50:51 -0700
        +Date: Mon, 25 Sep 1995 17:50:51 -0700
        +From: Phil Karn <karn@qualcomm.com>
        +Message-Id: <199509260050.RAA14732@servo.qualcomm.com>
        +To: cypherpunks@toad.com, ipsec-dev@eit.com
        +Subject: Primality verification needed
        +Sender: owner-cypherpunks@toad.com
        +Precedence: bulk
        +Status: RO
        +X-Status: 
        +
        +Hi. I've generated a 2047-bit "strong" prime number that I would like to
        +use with Diffie-Hellman key exchange. I assert that not only is this number
        +'p' prime, but so is (p-1)/2.
        +
        +I've used the mpz_probab_prime() function in the Gnu Math Package (GMP) version
        +1.3.2 to test this number. This function uses the Miller-Rabin primality test.
        +However, to increase my confidence that this number really is a strong prime,
        +I'd like to ask others to confirm it with other tests. Here's the number in hex:
        +
        +72a925f760b2f954ed287f1b0953f3e6aef92e456172f9fe86fdd8822241b9c9788fbc289982743e
        +fbcd2ccf062b242d7a567ba8bbb40d79bca7b8e0b6c05f835a5b938d985816bc648985adcff5402a
        +a76756b36c845a840a1d059ce02707e19cf47af0b5a882f32315c19d1b86a56c5389c5e9bee16b65
        +fde7b1a8d74a7675de9b707d4c5a4633c0290c95ff30a605aeb7ae864ff48370f13cf01d49adb9f2
        +3d19a439f753ee7703cf342d87f431105c843c78ca4df639931f3458fae8a94d1687e99a76ed99d0
        +ba87189f42fd31ad8262c54a8cf5914ae6c28c540d714a5f6087a171fb74f4814c6f968d72386ef3
        +56a05180c3bec7ddd5ef6fe76b1f717b
        +
        +The generator, g, for this prime is 2.
        +
        +Thanks!
        +
        +Phil Karn
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/dh/generate b/vendor/openssl/openssl/crypto/dh/generate
        new file mode 100644
        index 000000000..5d407231d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/generate
        @@ -0,0 +1,65 @@
        +From: stewarts@ix.netcom.com (Bill Stewart)
        +Newsgroups: sci.crypt
        +Subject: Re: Diffie-Hellman key exchange
        +Date: Wed, 11 Oct 1995 23:08:28 GMT
        +Organization: Freelance Information Architect
        +Lines: 32
        +Message-ID: <45hir2$7l8@ixnews7.ix.netcom.com>
        +References: <458rhn$76m$1@mhadf.production.compuserve.com>
        +NNTP-Posting-Host: ix-pl4-16.ix.netcom.com
        +X-NETCOM-Date: Wed Oct 11  4:09:22 PM PDT 1995
        +X-Newsreader: Forte Free Agent 1.0.82
        +
        +Kent Briggs <72124.3234@CompuServe.COM> wrote:
        +
        +>I have a copy of the 1976 IEEE article describing the
        +>Diffie-Hellman public key exchange algorithm: y=a^x mod q.  I'm
        +>looking for sources that give examples of secure a,q pairs and
        +>possible some source code that I could examine.
        +
        +q should be prime, and ideally should be a "strong prime",
        +which means it's of the form 2n+1 where n is also prime.
        +q also needs to be long enough to prevent the attacks LaMacchia and
        +Odlyzko described (some variant on a factoring attack which generates
        +a large pile of simultaneous equations and then solves them);
        +long enough is about the same size as factoring, so 512 bits may not
        +be secure enough for most applications.  (The 192 bits used by
        +"secure NFS" was certainly not long enough.)
        +
        +a should be a generator for q, which means it needs to be
        +relatively prime to q-1.   Usually a small prime like 2, 3 or 5 will
        +work.  
        +
        +....
        +
        +Date: Tue, 26 Sep 1995 13:52:36 MST
        +From: "Richard Schroeppel" <rcs@cs.arizona.edu>
        +To: karn
        +Cc: ho@cs.arizona.edu
        +Subject: random large primes
        +
        +Since your prime is really random, proving it is hard.
        +My personal limit on rigorously proved primes is ~350 digits.
        +If you really want a proof, we should talk to Francois Morain,
        +or the Australian group.
        +
        +If you want 2 to be a generator (mod P), then you need it
        +to be a non-square.  If (P-1)/2 is also prime, then
        +non-square == primitive-root for bases << P.
        +
        +In the case at hand, this means 2 is a generator iff P = 11 (mod 24).
        +If you want this, you should restrict your sieve accordingly.
        +
        +3 is a generator iff P = 5 (mod 12).
        +
        +5 is a generator iff P = 3 or 7 (mod 10).
        +
        +2 is perfectly usable as a base even if it's a non-generator, since
        +it still covers half the space of possible residues.  And an
        +eavesdropper can always determine the low-bit of your exponent for
        +a generator anyway.
        +
        +Rich  rcs@cs.arizona.edu
        +
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/dh/p1024.c b/vendor/openssl/openssl/crypto/dh/p1024.c
        new file mode 100644
        index 000000000..368ceca4e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/p1024.c
        @@ -0,0 +1,92 @@
        +/* crypto/dh/p1024.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/bn.h>
        +#include <openssl/asn1.h>
        +#include <openssl/dh.h>
        +#include <openssl/pem.h>
        +
        +unsigned char data[]={0x97,0xF6,0x42,0x61,0xCA,0xB5,0x05,0xDD,
        +	0x28,0x28,0xE1,0x3F,0x1D,0x68,0xB6,0xD3,
        +	0xDB,0xD0,0xF3,0x13,0x04,0x7F,0x40,0xE8,
        +	0x56,0xDA,0x58,0xCB,0x13,0xB8,0xA1,0xBF,
        +	0x2B,0x78,0x3A,0x4C,0x6D,0x59,0xD5,0xF9,
        +	0x2A,0xFC,0x6C,0xFF,0x3D,0x69,0x3F,0x78,
        +	0xB2,0x3D,0x4F,0x31,0x60,0xA9,0x50,0x2E,
        +	0x3E,0xFA,0xF7,0xAB,0x5E,0x1A,0xD5,0xA6,
        +	0x5E,0x55,0x43,0x13,0x82,0x8D,0xA8,0x3B,
        +	0x9F,0xF2,0xD9,0x41,0xDE,0xE9,0x56,0x89,
        +	0xFA,0xDA,0xEA,0x09,0x36,0xAD,0xDF,0x19,
        +	0x71,0xFE,0x63,0x5B,0x20,0xAF,0x47,0x03,
        +	0x64,0x60,0x3C,0x2D,0xE0,0x59,0xF5,0x4B,
        +	0x65,0x0A,0xD8,0xFA,0x0C,0xF7,0x01,0x21,
        +	0xC7,0x47,0x99,0xD7,0x58,0x71,0x32,0xBE,
        +	0x9B,0x99,0x9B,0xB9,0xB7,0x87,0xE8,0xAB,
        +	};
        +
        +main()
        +	{
        +	DH *dh;
        +
        +	dh=DH_new();
        +	dh->p=BN_bin2bn(data,sizeof(data),NULL);
        +	dh->g=BN_new();
        +	BN_set_word(dh->g,2);
        +	PEM_write_DHparams(stdout,dh);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/p192.c b/vendor/openssl/openssl/crypto/dh/p192.c
        new file mode 100644
        index 000000000..7bdf40410
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/p192.c
        @@ -0,0 +1,80 @@
        +/* crypto/dh/p192.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/bn.h>
        +#include <openssl/asn1.h>
        +#include <openssl/dh.h>
        +#include <openssl/pem.h>
        +
        +unsigned char data[]={
        +0xD4,0xA0,0xBA,0x02,0x50,0xB6,0xFD,0x2E,
        +0xC6,0x26,0xE7,0xEF,0xD6,0x37,0xDF,0x76,
        +0xC7,0x16,0xE2,0x2D,0x09,0x44,0xB8,0x8B,
        +	};
        +
        +main()
        +	{
        +	DH *dh;
        +
        +	dh=DH_new();
        +	dh->p=BN_bin2bn(data,sizeof(data),NULL);
        +	dh->g=BN_new();
        +	BN_set_word(dh->g,3);
        +	PEM_write_DHparams(stdout,dh);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dh/p512.c b/vendor/openssl/openssl/crypto/dh/p512.c
        new file mode 100644
        index 000000000..a9b6aa83f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dh/p512.c
        @@ -0,0 +1,85 @@
        +/* crypto/dh/p512.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/bn.h>
        +#include <openssl/asn1.h>
        +#include <openssl/dh.h>
        +#include <openssl/pem.h>
        +
        +unsigned char data[]={
        +0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,
        +0xD0,0xE4,0xAF,0x75,0x6F,0x4C,0xCA,0x92,
        +0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
        +0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,
        +0x57,0x46,0x50,0xD3,0x69,0x99,0xDB,0x29,
        +0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
        +0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,
        +0xD8,0x00,0x3E,0x7C,0x47,0x74,0xE8,0x33,
        +	};
        +
        +main()
        +	{
        +	DH *dh;
        +
        +	dh=DH_new();
        +	dh->p=BN_bin2bn(data,sizeof(data),NULL);
        +	dh->g=BN_new();
        +	BN_set_word(dh->g,2);
        +	PEM_write_DHparams(stdout,dh);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dsa/Makefile b/vendor/openssl/openssl/crypto/dsa/Makefile
        new file mode 100644
        index 000000000..5fef4ca5a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/Makefile
        @@ -0,0 +1,209 @@
        +#
        +# OpenSSL/crypto/dsa/Makefile
        +#
        +
        +DIR=	dsa
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=dsatest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
        +	dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c
        +LIBOBJ= dsa_gen.o dsa_key.o dsa_lib.o dsa_asn1.o dsa_vrf.o dsa_sign.o \
        +	dsa_err.o dsa_ossl.o dsa_depr.o dsa_ameth.o dsa_pmeth.o dsa_prn.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= dsa.h
        +HEADER=	dsa_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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +dsa_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +dsa_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +dsa_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +dsa_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +dsa_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +dsa_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dsa_ameth.o: ../../include/openssl/objects.h
        +dsa_ameth.o: ../../include/openssl/opensslconf.h
        +dsa_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +dsa_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dsa_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +dsa_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +dsa_ameth.o: dsa_ameth.c
        +dsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +dsa_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dsa_asn1.o: ../../include/openssl/opensslconf.h
        +dsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_asn1.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +dsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dsa_asn1.o: ../cryptlib.h dsa_asn1.c
        +dsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_depr.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_depr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +dsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dsa_depr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +dsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_depr.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +dsa_depr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dsa_depr.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_depr.c
        +dsa_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +dsa_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dsa_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dsa_err.o: dsa_err.c
        +dsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +dsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dsa_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +dsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_gen.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +dsa_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dsa_gen.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_gen.c dsa_locl.h
        +dsa_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dsa_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dsa_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_key.c
        +dsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +dsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +dsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +dsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +dsa_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +dsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +dsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dsa_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +dsa_lib.o: ../cryptlib.h dsa_lib.c
        +dsa_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_ossl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dsa_ossl.o: ../../include/openssl/opensslconf.h
        +dsa_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dsa_ossl.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_ossl.c
        +dsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +dsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +dsa_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +dsa_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +dsa_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +dsa_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +dsa_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +dsa_pmeth.o: ../../include/openssl/objects.h
        +dsa_pmeth.o: ../../include/openssl/opensslconf.h
        +dsa_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +dsa_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +dsa_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +dsa_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
        +dsa_pmeth.o: dsa_locl.h dsa_pmeth.c
        +dsa_prn.o: ../../e_os.h ../../include/openssl/asn1.h
        +dsa_prn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +dsa_prn.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +dsa_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +dsa_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +dsa_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +dsa_prn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dsa_prn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dsa_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dsa_prn.o: ../cryptlib.h dsa_prn.c
        +dsa_sign.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dsa_sign.o: ../../include/openssl/opensslconf.h
        +dsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dsa_sign.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dsa_sign.o: ../cryptlib.h dsa_sign.c
        +dsa_vrf.o: ../../e_os.h ../../include/openssl/bio.h
        +dsa_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dsa_vrf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +dsa_vrf.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dsa_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dsa_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dsa_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dsa_vrf.o: ../cryptlib.h dsa_vrf.c
        diff --git a/vendor/openssl/openssl/crypto/dsa/README b/vendor/openssl/openssl/crypto/dsa/README
        new file mode 100644
        index 000000000..6a7e9c170
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/README
        @@ -0,0 +1,4 @@
        +The stuff in here is based on patches supplied to me by
        +Steven Schoch <schoch@sheba.arc.nasa.gov> to do DSS.
        +I have since modified a them a little but a debt of gratitude
        +is due for doing the initial work.
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa.h b/vendor/openssl/openssl/crypto/dsa/dsa.h
        new file mode 100644
        index 000000000..a6f6d0b0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa.h
        @@ -0,0 +1,327 @@
        +/* crypto/dsa/dsa.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/*
        + * The DSS routines are based on patches supplied by
        + * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
        + * work and I have just tweaked them a little to fit into my
        + * stylistic vision for SSLeay :-) */
        +
        +#ifndef HEADER_DSA_H
        +#define HEADER_DSA_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifdef OPENSSL_NO_DSA
        +#error DSA is disabled.
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/crypto.h>
        +#include <openssl/ossl_typ.h>
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_DH
        +# include <openssl/dh.h>
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_DSA_MAX_MODULUS_BITS
        +# define OPENSSL_DSA_MAX_MODULUS_BITS	10000
        +#endif
        +
        +#define DSA_FLAG_CACHE_MONT_P	0x01
        +#define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
        +                                              * implementation now uses constant time
        +                                              * modular exponentiation for secret exponents
        +                                              * by default. This flag causes the
        +                                              * faster variable sliding window method to
        +                                              * be used for all exponents.
        +                                              */
        +
        +/* If this flag is set the DSA method is FIPS compliant and can be used
        + * in FIPS mode. This is set in the validated module method. If an
        + * application sets this flag in its own methods it is its reposibility
        + * to ensure the result is compliant.
        + */
        +
        +#define DSA_FLAG_FIPS_METHOD			0x0400
        +
        +/* If this flag is set the operations normally disabled in FIPS mode are
        + * permitted it is then the applications responsibility to ensure that the
        + * usage is compliant.
        + */
        +
        +#define DSA_FLAG_NON_FIPS_ALLOW			0x0400
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Already defined in ossl_typ.h */
        +/* typedef struct dsa_st DSA; */
        +/* typedef struct dsa_method DSA_METHOD; */
        +
        +typedef struct DSA_SIG_st
        +	{
        +	BIGNUM *r;
        +	BIGNUM *s;
        +	} DSA_SIG;
        +
        +struct dsa_method
        +	{
        +	const char *name;
        +	DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
        +	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
        +								BIGNUM **rp);
        +	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
        +			     DSA_SIG *sig, DSA *dsa);
        +	int (*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);
        +	int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
        +				const BIGNUM *m, BN_CTX *ctx,
        +				BN_MONT_CTX *m_ctx); /* Can be null */
        +	int (*init)(DSA *dsa);
        +	int (*finish)(DSA *dsa);
        +	int flags;
        +	char *app_data;
        +	/* If this is non-NULL, it is used to generate DSA parameters */
        +	int (*dsa_paramgen)(DSA *dsa, int bits,
        +			const unsigned char *seed, int seed_len,
        +			int *counter_ret, unsigned long *h_ret,
        +			BN_GENCB *cb);
        +	/* If this is non-NULL, it is used to generate DSA keys */
        +	int (*dsa_keygen)(DSA *dsa);
        +	};
        +
        +struct dsa_st
        +	{
        +	/* This first variable is used to pick up errors where
        +	 * a DSA is passed instead of of a EVP_PKEY */
        +	int pad;
        +	long version;
        +	int write_params;
        +	BIGNUM *p;
        +	BIGNUM *q;	/* == 20 */
        +	BIGNUM *g;
        +
        +	BIGNUM *pub_key;  /* y public key */
        +	BIGNUM *priv_key; /* x private key */
        +
        +	BIGNUM *kinv;	/* Signing pre-calc */
        +	BIGNUM *r;	/* Signing pre-calc */
        +
        +	int flags;
        +	/* Normally used to cache montgomery values */
        +	BN_MONT_CTX *method_mont_p;
        +	int references;
        +	CRYPTO_EX_DATA ex_data;
        +	const DSA_METHOD *meth;
        +	/* functional reference if 'meth' is ENGINE-provided */
        +	ENGINE *engine;
        +	};
        +
        +#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
        +		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
        +#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
        +		(unsigned char *)(x))
        +#define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
        +#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
        +
        +
        +DSA *DSAparams_dup(DSA *x);
        +DSA_SIG * DSA_SIG_new(void);
        +void	DSA_SIG_free(DSA_SIG *a);
        +int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
        +DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
        +
        +DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa);
        +int	DSA_do_verify(const unsigned char *dgst,int dgst_len,
        +		      DSA_SIG *sig,DSA *dsa);
        +
        +const DSA_METHOD *DSA_OpenSSL(void);
        +
        +void	DSA_set_default_method(const DSA_METHOD *);
        +const DSA_METHOD *DSA_get_default_method(void);
        +int	DSA_set_method(DSA *dsa, const DSA_METHOD *);
        +
        +DSA *	DSA_new(void);
        +DSA *	DSA_new_method(ENGINE *engine);
        +void	DSA_free (DSA *r);
        +/* "up" the DSA object's reference count */
        +int	DSA_up_ref(DSA *r);
        +int	DSA_size(const DSA *);
        +	/* next 4 return -1 on error */
        +int	DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
        +int	DSA_sign(int type,const unsigned char *dgst,int dlen,
        +		unsigned char *sig, unsigned int *siglen, DSA *dsa);
        +int	DSA_verify(int type,const unsigned char *dgst,int dgst_len,
        +		const unsigned char *sigbuf, int siglen, DSA *dsa);
        +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int DSA_set_ex_data(DSA *d, int idx, void *arg);
        +void *DSA_get_ex_data(DSA *d, int idx);
        +
        +DSA *	d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
        +DSA *	d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
        +DSA * 	d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
        +
        +/* Deprecated version */
        +#ifndef OPENSSL_NO_DEPRECATED
        +DSA *	DSA_generate_parameters(int bits,
        +		unsigned char *seed,int seed_len,
        +		int *counter_ret, unsigned long *h_ret,void
        +		(*callback)(int, int, void *),void *cb_arg);
        +#endif /* !defined(OPENSSL_NO_DEPRECATED) */
        +
        +/* New version */
        +int	DSA_generate_parameters_ex(DSA *dsa, int bits,
        +		const unsigned char *seed,int seed_len,
        +		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
        +
        +int	DSA_generate_key(DSA *a);
        +int	i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
        +int 	i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
        +int	i2d_DSAparams(const DSA *a,unsigned char **pp);
        +
        +#ifndef OPENSSL_NO_BIO
        +int	DSAparams_print(BIO *bp, const DSA *x);
        +int	DSA_print(BIO *bp, const DSA *x, int off);
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +int	DSAparams_print_fp(FILE *fp, const DSA *x);
        +int	DSA_print_fp(FILE *bp, const DSA *x, int off);
        +#endif
        +
        +#define DSS_prime_checks 50
        +/* Primality test according to FIPS PUB 186[-1], Appendix 2.1:
        + * 50 rounds of Rabin-Miller */
        +#define DSA_is_prime(n, callback, cb_arg) \
        +	BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
        +
        +#ifndef OPENSSL_NO_DH
        +/* Convert DSA structure (key or just parameters) into DH structure
        + * (be careful to avoid small subgroup attacks when using this!) */
        +DH *DSA_dup_DH(const DSA *r);
        +#endif
        +
        +#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
        +				EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
        +
        +#define	EVP_PKEY_CTRL_DSA_PARAMGEN_BITS		(EVP_PKEY_ALG_CTRL + 1)
        +#define	EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS	(EVP_PKEY_ALG_CTRL + 2)
        +#define	EVP_PKEY_CTRL_DSA_PARAMGEN_MD		(EVP_PKEY_ALG_CTRL + 3)
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_DSA_strings(void);
        +
        +/* Error codes for the DSA functions. */
        +
        +/* Function codes. */
        +#define DSA_F_D2I_DSA_SIG				 110
        +#define DSA_F_DO_DSA_PRINT				 104
        +#define DSA_F_DSAPARAMS_PRINT				 100
        +#define DSA_F_DSAPARAMS_PRINT_FP			 101
        +#define DSA_F_DSA_DO_SIGN				 112
        +#define DSA_F_DSA_DO_VERIFY				 113
        +#define DSA_F_DSA_GENERATE_KEY				 124
        +#define DSA_F_DSA_GENERATE_PARAMETERS_EX		 123
        +#define DSA_F_DSA_NEW_METHOD				 103
        +#define DSA_F_DSA_PARAM_DECODE				 119
        +#define DSA_F_DSA_PRINT_FP				 105
        +#define DSA_F_DSA_PRIV_DECODE				 115
        +#define DSA_F_DSA_PRIV_ENCODE				 116
        +#define DSA_F_DSA_PUB_DECODE				 117
        +#define DSA_F_DSA_PUB_ENCODE				 118
        +#define DSA_F_DSA_SIGN					 106
        +#define DSA_F_DSA_SIGN_SETUP				 107
        +#define DSA_F_DSA_SIG_NEW				 109
        +#define DSA_F_DSA_SIG_PRINT				 125
        +#define DSA_F_DSA_VERIFY				 108
        +#define DSA_F_I2D_DSA_SIG				 111
        +#define DSA_F_OLD_DSA_PRIV_DECODE			 122
        +#define DSA_F_PKEY_DSA_CTRL				 120
        +#define DSA_F_PKEY_DSA_KEYGEN				 121
        +#define DSA_F_SIG_CB					 114
        +
        +/* Reason codes. */
        +#define DSA_R_BAD_Q_VALUE				 102
        +#define DSA_R_BN_DECODE_ERROR				 108
        +#define DSA_R_BN_ERROR					 109
        +#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
        +#define DSA_R_DECODE_ERROR				 104
        +#define DSA_R_INVALID_DIGEST_TYPE			 106
        +#define DSA_R_MISSING_PARAMETERS			 101
        +#define DSA_R_MODULUS_TOO_LARGE				 103
        +#define DSA_R_NEED_NEW_SETUP_VALUES			 110
        +#define DSA_R_NON_FIPS_DSA_METHOD			 111
        +#define DSA_R_NO_PARAMETERS_SET				 107
        +#define DSA_R_PARAMETER_ENCODING_ERROR			 105
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_ameth.c b/vendor/openssl/openssl/crypto/dsa/dsa_ameth.c
        new file mode 100644
        index 000000000..376156ec5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_ameth.c
        @@ -0,0 +1,704 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +#include <openssl/dsa.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_CMS
        +#include <openssl/cms.h>
        +#endif
        +#include "asn1_locl.h"
        +
        +static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
        +	{
        +	const unsigned char *p, *pm;
        +	int pklen, pmlen;
        +	int ptype;
        +	void *pval;
        +	ASN1_STRING *pstr;
        +	X509_ALGOR *palg;
        +	ASN1_INTEGER *public_key = NULL;
        +
        +	DSA *dsa = NULL;
        +
        +	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
        +		return 0;
        +	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
        +
        +
        +	if (ptype == V_ASN1_SEQUENCE)
        +		{
        +		pstr = pval;	
        +		pm = pstr->data;
        +		pmlen = pstr->length;
        +
        +		if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
        +			{
        +			DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
        +			goto err;
        +			}
        +
        +		}
        +	else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF))
        +		{
        +		if (!(dsa = DSA_new()))
        +			{
        +			DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
        +		goto err;
        +		}
        +
        +	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
        +		{
        +		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
        +		{
        +		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	ASN1_INTEGER_free(public_key);
        +	EVP_PKEY_assign_DSA(pkey, dsa);
        +	return 1;
        +
        +	err:
        +	if (public_key)
        +		ASN1_INTEGER_free(public_key);
        +	if (dsa)
        +		DSA_free(dsa);
        +	return 0;
        +
        +	}
        +
        +static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
        +	{
        +	DSA *dsa;
        +	void *pval = NULL;
        +	int ptype;
        +	unsigned char *penc = NULL;
        +	int penclen;
        +
        +	dsa=pkey->pkey.dsa;
        +	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g)
        +		{
        +		ASN1_STRING *str;
        +		str = ASN1_STRING_new();
        +		str->length = i2d_DSAparams(dsa, &str->data);
        +		if (str->length <= 0)
        +			{
        +			DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		pval = str;
        +		ptype = V_ASN1_SEQUENCE;
        +		}
        +	else
        +		ptype = V_ASN1_UNDEF;
        +
        +	dsa->write_params=0;
        +
        +	penclen = i2d_DSAPublicKey(dsa, &penc);
        +
        +	if (penclen <= 0)
        +		{
        +		DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
        +				ptype, pval, penc, penclen))
        +		return 1;
        +
        +	err:
        +	if (penc)
        +		OPENSSL_free(penc);
        +	if (pval)
        +		ASN1_STRING_free(pval);
        +
        +	return 0;
        +	}
        +
        +/* In PKCS#8 DSA: you just get a private key integer and parameters in the
        + * AlgorithmIdentifier the pubkey must be recalculated.
        + */
        +	
        +static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
        +	{
        +	const unsigned char *p, *pm;
        +	int pklen, pmlen;
        +	int ptype;
        +	void *pval;
        +	ASN1_STRING *pstr;
        +	X509_ALGOR *palg;
        +	ASN1_INTEGER *privkey = NULL;
        +	BN_CTX *ctx = NULL;
        +
        +	STACK_OF(ASN1_TYPE) *ndsa = NULL;
        +	DSA *dsa = NULL;
        +
        +	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
        +		return 0;
        +	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
        +
        +	/* Check for broken DSA PKCS#8, UGH! */
        +	if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
        +		{
        +		ASN1_TYPE *t1, *t2;
        +	    	if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)))
        +			goto decerr;
        +		if (sk_ASN1_TYPE_num(ndsa) != 2)
        +			goto decerr;
        +		/* Handle Two broken types:
        +	    	 * SEQUENCE {parameters, priv_key}
        +		 * SEQUENCE {pub_key, priv_key}
        +		 */
        +
        +		t1 = sk_ASN1_TYPE_value(ndsa, 0);
        +		t2 = sk_ASN1_TYPE_value(ndsa, 1);
        +		if (t1->type == V_ASN1_SEQUENCE)
        +			{
        +			p8->broken = PKCS8_EMBEDDED_PARAM;
        +			pval = t1->value.ptr;
        +			}
        +		else if (ptype == V_ASN1_SEQUENCE)
        +			p8->broken = PKCS8_NS_DB;
        +		else
        +			goto decerr;
        +
        +		if (t2->type != V_ASN1_INTEGER)
        +			goto decerr;
        +
        +		privkey = t2->value.integer;
        +		}
        +	else
        +		{
        +		const unsigned char *q = p;
        +		if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
        +			goto decerr;
        +		if (privkey->type == V_ASN1_NEG_INTEGER)
        +			{
        +			p8->broken = PKCS8_NEG_PRIVKEY;
        +			ASN1_INTEGER_free(privkey);
        +			if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen)))
        +				goto decerr;
        +			}
        +		if (ptype != V_ASN1_SEQUENCE)
        +			goto decerr;
        +		}
        +
        +	pstr = pval;	
        +	pm = pstr->data;
        +	pmlen = pstr->length;
        +	if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
        +		goto decerr;
        +	/* We have parameters now set private key */
        +	if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
        +		goto dsaerr;
        +		}
        +	/* Calculate public key */
        +	if (!(dsa->pub_key = BN_new()))
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
        +		goto dsaerr;
        +		}
        +	if (!(ctx = BN_CTX_new()))
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
        +		goto dsaerr;
        +		}
        +			
        +	if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
        +		goto dsaerr;
        +		}
        +
        +	EVP_PKEY_assign_DSA(pkey, dsa);
        +	BN_CTX_free (ctx);
        +	if(ndsa)
        +		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
        +	else
        +		ASN1_INTEGER_free(privkey);
        +
        +	return 1;
        +
        +	decerr:
        +	DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
        +	dsaerr:
        +	BN_CTX_free (ctx);
        +	if (privkey)
        +		ASN1_INTEGER_free(privkey);
        +	sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
        +	DSA_free(dsa);
        +	return 0;
        +	}
        +
        +static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
        +{
        +	ASN1_STRING *params = NULL;
        +	ASN1_INTEGER *prkey = NULL;
        +	unsigned char *dp = NULL;
        +	int dplen;
        +
        +	params = ASN1_STRING_new();
        +
        +	if (!params)
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
        +	if (params->length <= 0)
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	params->type = V_ASN1_SEQUENCE;
        +
        +	/* Get private key into integer */
        +	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
        +
        +	if (!prkey)
        +		{
        +		DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
        +		goto err;
        +		}
        +
        +	dplen = i2d_ASN1_INTEGER(prkey, &dp);
        +
        +	ASN1_INTEGER_free(prkey);
        +
        +	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
        +				V_ASN1_SEQUENCE, params, dp, dplen))
        +		goto err;
        +
        +	return 1;
        +
        +err:
        +	if (dp != NULL)
        +		OPENSSL_free(dp);
        +	if (params != NULL)
        +		ASN1_STRING_free(params);
        +	if (prkey != NULL)
        +		ASN1_INTEGER_free(prkey);
        +	return 0;
        +}
        +
        +static int int_dsa_size(const EVP_PKEY *pkey)
        +	{
        +	return(DSA_size(pkey->pkey.dsa));
        +	}
        +
        +static int dsa_bits(const EVP_PKEY *pkey)
        +	{
        +	return BN_num_bits(pkey->pkey.dsa->p);
        +	}
        +
        +static int dsa_missing_parameters(const EVP_PKEY *pkey)
        +	{
        +	DSA *dsa;
        +	dsa=pkey->pkey.dsa;
        +	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
        +			return 1;
        +	return 0;
        +	}
        +
        +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
        +	{
        +	BIGNUM *a;
        +
        +	if ((a=BN_dup(from->pkey.dsa->p)) == NULL)
        +		return 0;
        +	if (to->pkey.dsa->p != NULL)
        +		BN_free(to->pkey.dsa->p);
        +	to->pkey.dsa->p=a;
        +
        +	if ((a=BN_dup(from->pkey.dsa->q)) == NULL)
        +		return 0;
        +	if (to->pkey.dsa->q != NULL)
        +		BN_free(to->pkey.dsa->q);
        +	to->pkey.dsa->q=a;
        +
        +	if ((a=BN_dup(from->pkey.dsa->g)) == NULL)
        +		return 0;
        +	if (to->pkey.dsa->g != NULL)
        +		BN_free(to->pkey.dsa->g);
        +	to->pkey.dsa->g=a;
        +	return 1;
        +	}
        +
        +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (	BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
        +		BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
        +		BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static void int_dsa_free(EVP_PKEY *pkey)
        +	{
        +	DSA_free(pkey->pkey.dsa);
        +	}
        +
        +static void update_buflen(const BIGNUM *b, size_t *pbuflen)
        +	{
        +	size_t i;
        +	if (!b)
        +		return;
        +	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
        +			*pbuflen = i;
        +	}
        +
        +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
        +	{
        +	unsigned char *m=NULL;
        +	int ret=0;
        +	size_t buf_len=0;
        +	const char *ktype = NULL;
        +
        +	const BIGNUM *priv_key, *pub_key;
        +
        +	if (ptype == 2)
        +		priv_key = x->priv_key;
        +	else
        +		priv_key = NULL;
        +
        +	if (ptype > 0)
        +		pub_key = x->pub_key;
        +	else
        +		pub_key = NULL;
        +
        +	if (ptype == 2)
        +		ktype = "Private-Key";
        +	else if (ptype == 1)
        +		ktype = "Public-Key";
        +	else
        +		ktype = "DSA-Parameters";
        +
        +	update_buflen(x->p, &buf_len);
        +	update_buflen(x->q, &buf_len);
        +	update_buflen(x->g, &buf_len);
        +	update_buflen(priv_key, &buf_len);
        +	update_buflen(pub_key, &buf_len);
        +
        +	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
        +	if (m == NULL)
        +		{
        +		DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (priv_key)
        +		{
        +		if(!BIO_indent(bp,off,128))
        +		   goto err;
        +		if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p))
        +			<= 0) goto err;
        +		}
        +
        +	if (!ASN1_bn_print(bp,"priv:",priv_key,m,off))
        +		goto err;
        +	if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off))
        +		goto err;
        +	if (!ASN1_bn_print(bp,"P:   ",x->p,m,off)) goto err;
        +	if (!ASN1_bn_print(bp,"Q:   ",x->q,m,off)) goto err;
        +	if (!ASN1_bn_print(bp,"G:   ",x->g,m,off)) goto err;
        +	ret=1;
        +err:
        +	if (m != NULL) OPENSSL_free(m);
        +	return(ret);
        +	}
        +
        +static int dsa_param_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	DSA *dsa;
        +	if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
        +		{
        +		DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_DSA(pkey, dsa);
        +	return 1;
        +	}
        +
        +static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	return i2d_DSAparams(pkey->pkey.dsa, pder);
        +	}
        +
        +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
        +	}
        +
        +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
        +	}
        +
        +
        +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
        +	}
        +
        +static int old_dsa_priv_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	DSA *dsa;
        +	if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
        +		{
        +		DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_DSA(pkey, dsa);
        +	return 1;
        +	}
        +
        +static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
        +	}
        +
        +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
        +					const ASN1_STRING *sig,
        +					int indent, ASN1_PCTX *pctx)
        +	{
        +	DSA_SIG *dsa_sig;
        +	const unsigned char *p;
        +	if (!sig)
        +		{
        +		if (BIO_puts(bp, "\n") <= 0)
        +			return 0;
        +		else
        +			return 1;
        +		}
        +	p = sig->data;
        +	dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
        +	if (dsa_sig)
        +		{
        +		int rv = 0;
        +		size_t buf_len = 0;
        +		unsigned char *m=NULL;
        +		update_buflen(dsa_sig->r, &buf_len);
        +		update_buflen(dsa_sig->s, &buf_len);
        +		m = OPENSSL_malloc(buf_len+10);
        +		if (m == NULL)
        +			{
        +			DSAerr(DSA_F_DSA_SIG_PRINT,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		if (BIO_write(bp, "\n", 1) != 1)
        +			goto err;
        +
        +		if (!ASN1_bn_print(bp,"r:   ",dsa_sig->r,m,indent))
        +			goto err;
        +		if (!ASN1_bn_print(bp,"s:   ",dsa_sig->s,m,indent))
        +			goto err;
        +		rv = 1;
        +		err:
        +		if (m)
        +			OPENSSL_free(m);
        +		DSA_SIG_free(dsa_sig);
        +		return rv;
        +		}
        +	return X509_signature_dump(bp, sig, indent);
        +	}
        +
        +static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        +	{
        +	switch (op)
        +		{
        +		case ASN1_PKEY_CTRL_PKCS7_SIGN:
        +		if (arg1 == 0)
        +			{
        +			int snid, hnid;
        +			X509_ALGOR *alg1, *alg2;
        +			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
        +			if (alg1 == NULL || alg1->algorithm == NULL)
        +				return -1;
        +			hnid = OBJ_obj2nid(alg1->algorithm);
        +			if (hnid == NID_undef)
        +				return -1;
        +			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
        +				return -1; 
        +			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
        +			}
        +		return 1;
        +#ifndef OPENSSL_NO_CMS
        +		case ASN1_PKEY_CTRL_CMS_SIGN:
        +		if (arg1 == 0)
        +			{
        +			int snid, hnid;
        +			X509_ALGOR *alg1, *alg2;
        +			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
        +			if (alg1 == NULL || alg1->algorithm == NULL)
        +				return -1;
        +			hnid = OBJ_obj2nid(alg1->algorithm);
        +			if (hnid == NID_undef)
        +				return -1;
        +			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
        +				return -1; 
        +			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
        +			}
        +		return 1;
        +#endif
        +
        +		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        +		*(int *)arg2 = NID_sha1;
        +		return 2;
        +
        +		default:
        +		return -2;
        +
        +		}
        +
        +	}
        +
        +/* NB these are sorted in pkey_id order, lowest first */
        +
        +const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = 
        +	{
        +
        +		{
        +		EVP_PKEY_DSA2,
        +		EVP_PKEY_DSA,
        +		ASN1_PKEY_ALIAS
        +		},
        +
        +		{
        +		EVP_PKEY_DSA1,
        +		EVP_PKEY_DSA,
        +		ASN1_PKEY_ALIAS
        +		},
        +
        +		{
        +		EVP_PKEY_DSA4,
        +		EVP_PKEY_DSA,
        +		ASN1_PKEY_ALIAS
        +		},
        +
        +		{
        +		EVP_PKEY_DSA3,
        +		EVP_PKEY_DSA,
        +		ASN1_PKEY_ALIAS
        +		},
        +
        +		{
        +		EVP_PKEY_DSA,
        +		EVP_PKEY_DSA,
        +		0,
        +
        +		"DSA",
        +		"OpenSSL DSA method",
        +
        +		dsa_pub_decode,
        +		dsa_pub_encode,
        +		dsa_pub_cmp,
        +		dsa_pub_print,
        +
        +		dsa_priv_decode,
        +		dsa_priv_encode,
        +		dsa_priv_print,
        +
        +		int_dsa_size,
        +		dsa_bits,
        +
        +		dsa_param_decode,
        +		dsa_param_encode,
        +		dsa_missing_parameters,
        +		dsa_copy_parameters,
        +		dsa_cmp_parameters,
        +		dsa_param_print,
        +		dsa_sig_print,
        +
        +		int_dsa_free,
        +		dsa_pkey_ctrl,
        +		old_dsa_priv_decode,
        +		old_dsa_priv_encode
        +		}
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_asn1.c b/vendor/openssl/openssl/crypto/dsa/dsa_asn1.c
        new file mode 100644
        index 000000000..605853437
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_asn1.c
        @@ -0,0 +1,188 @@
        +/* dsa_asn1.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/dsa.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/rand.h>
        +
        +/* Override the default new methods */
        +static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +{
        +	if(operation == ASN1_OP_NEW_PRE) {
        +		DSA_SIG *sig;
        +		sig = OPENSSL_malloc(sizeof(DSA_SIG));
        +		if (!sig)
        +			{
        +			DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		sig->r = NULL;
        +		sig->s = NULL;
        +		*pval = (ASN1_VALUE *)sig;
        +		return 2;
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {
        +	ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
        +	ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
        +} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)
        +
        +/* Override the default free and new methods */
        +static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +{
        +	if(operation == ASN1_OP_NEW_PRE) {
        +		*pval = (ASN1_VALUE *)DSA_new();
        +		if(*pval) return 2;
        +		return 0;
        +	} else if(operation == ASN1_OP_FREE_PRE) {
        +		DSA_free((DSA *)*pval);
        +		*pval = NULL;
        +		return 2;
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
        +	ASN1_SIMPLE(DSA, version, LONG),
        +	ASN1_SIMPLE(DSA, p, BIGNUM),
        +	ASN1_SIMPLE(DSA, q, BIGNUM),
        +	ASN1_SIMPLE(DSA, g, BIGNUM),
        +	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
        +	ASN1_SIMPLE(DSA, priv_key, BIGNUM)
        +} ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
        +
        +ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
        +	ASN1_SIMPLE(DSA, p, BIGNUM),
        +	ASN1_SIMPLE(DSA, q, BIGNUM),
        +	ASN1_SIMPLE(DSA, g, BIGNUM),
        +} ASN1_SEQUENCE_END_cb(DSA, DSAparams)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams)
        +
        +/* DSA public key is a bit trickier... its effectively a CHOICE type
        + * decided by a field called write_params which can either write out
        + * just the public key as an INTEGER or the parameters and public key
        + * in a SEQUENCE
        + */
        +
        +ASN1_SEQUENCE(dsa_pub_internal) = {
        +	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
        +	ASN1_SIMPLE(DSA, p, BIGNUM),
        +	ASN1_SIMPLE(DSA, q, BIGNUM),
        +	ASN1_SIMPLE(DSA, g, BIGNUM)
        +} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal)
        +
        +ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = {
        +	ASN1_SIMPLE(DSA, pub_key, BIGNUM),
        +	ASN1_EX_COMBINE(0, 0, dsa_pub_internal)
        +} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
        +
        +DSA *DSAparams_dup(DSA *dsa)
        +	{
        +	return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
        +	}
        +
        +int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
        +	     unsigned int *siglen, DSA *dsa)
        +	{
        +	DSA_SIG *s;
        +	RAND_seed(dgst, dlen);
        +	s=DSA_do_sign(dgst,dlen,dsa);
        +	if (s == NULL)
        +		{
        +		*siglen=0;
        +		return(0);
        +		}
        +	*siglen=i2d_DSA_SIG(s,&sig);
        +	DSA_SIG_free(s);
        +	return(1);
        +	}
        +
        +/* data has already been hashed (probably with SHA or SHA-1). */
        +/* returns
        + *      1: correct signature
        + *      0: incorrect signature
        + *     -1: error
        + */
        +int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
        +	     const unsigned char *sigbuf, int siglen, DSA *dsa)
        +	{
        +	DSA_SIG *s;
        +	int ret=-1;
        +
        +	s = DSA_SIG_new();
        +	if (s == NULL) return(ret);
        +	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
        +	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
        +err:
        +	DSA_SIG_free(s);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_depr.c b/vendor/openssl/openssl/crypto/dsa/dsa_depr.c
        new file mode 100644
        index 000000000..f2da680eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_depr.c
        @@ -0,0 +1,106 @@
        +/* crypto/dsa/dsa_depr.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +/* This file contains deprecated function(s) that are now wrappers to the new
        + * version(s). */
        +
        +#undef GENUINE_DSA
        +
        +#ifdef GENUINE_DSA
        +/* Parameter generation follows the original release of FIPS PUB 186,
        + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
        +#define HASH    EVP_sha()
        +#else
        +/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
        + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
        + * FIPS PUB 180-1) */
        +#define HASH    EVP_sha1()
        +#endif 
        +
        +static void *dummy=&dummy;
        +
        +#ifndef OPENSSL_NO_SHA
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/dsa.h>
        +#include <openssl/rand.h>
        +#include <openssl/sha.h>
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +DSA *DSA_generate_parameters(int bits,
        +		unsigned char *seed_in, int seed_len,
        +		int *counter_ret, unsigned long *h_ret,
        +		void (*callback)(int, int, void *),
        +		void *cb_arg)
        +	{
        +	BN_GENCB cb;
        +	DSA *ret;
        +
        +	if ((ret=DSA_new()) == NULL) return NULL;
        +
        +	BN_GENCB_set_old(&cb, callback, cb_arg);
        +
        +	if(DSA_generate_parameters_ex(ret, bits, seed_in, seed_len,
        +				counter_ret, h_ret, &cb))
        +		return ret;
        +	DSA_free(ret);
        +	return NULL;
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_err.c b/vendor/openssl/openssl/crypto/dsa/dsa_err.c
        new file mode 100644
        index 000000000..00545b7b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_err.c
        @@ -0,0 +1,130 @@
        +/* crypto/dsa/dsa_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/dsa.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason)
        +
        +static ERR_STRING_DATA DSA_str_functs[]=
        +	{
        +{ERR_FUNC(DSA_F_D2I_DSA_SIG),	"d2i_DSA_SIG"},
        +{ERR_FUNC(DSA_F_DO_DSA_PRINT),	"DO_DSA_PRINT"},
        +{ERR_FUNC(DSA_F_DSAPARAMS_PRINT),	"DSAparams_print"},
        +{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),	"DSAparams_print_fp"},
        +{ERR_FUNC(DSA_F_DSA_DO_SIGN),	"DSA_do_sign"},
        +{ERR_FUNC(DSA_F_DSA_DO_VERIFY),	"DSA_do_verify"},
        +{ERR_FUNC(DSA_F_DSA_GENERATE_KEY),	"DSA_generate_key"},
        +{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX),	"DSA_generate_parameters_ex"},
        +{ERR_FUNC(DSA_F_DSA_NEW_METHOD),	"DSA_new_method"},
        +{ERR_FUNC(DSA_F_DSA_PARAM_DECODE),	"DSA_PARAM_DECODE"},
        +{ERR_FUNC(DSA_F_DSA_PRINT_FP),	"DSA_print_fp"},
        +{ERR_FUNC(DSA_F_DSA_PRIV_DECODE),	"DSA_PRIV_DECODE"},
        +{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE),	"DSA_PRIV_ENCODE"},
        +{ERR_FUNC(DSA_F_DSA_PUB_DECODE),	"DSA_PUB_DECODE"},
        +{ERR_FUNC(DSA_F_DSA_PUB_ENCODE),	"DSA_PUB_ENCODE"},
        +{ERR_FUNC(DSA_F_DSA_SIGN),	"DSA_sign"},
        +{ERR_FUNC(DSA_F_DSA_SIGN_SETUP),	"DSA_sign_setup"},
        +{ERR_FUNC(DSA_F_DSA_SIG_NEW),	"DSA_SIG_new"},
        +{ERR_FUNC(DSA_F_DSA_SIG_PRINT),	"DSA_SIG_PRINT"},
        +{ERR_FUNC(DSA_F_DSA_VERIFY),	"DSA_verify"},
        +{ERR_FUNC(DSA_F_I2D_DSA_SIG),	"i2d_DSA_SIG"},
        +{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE),	"OLD_DSA_PRIV_DECODE"},
        +{ERR_FUNC(DSA_F_PKEY_DSA_CTRL),	"PKEY_DSA_CTRL"},
        +{ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN),	"PKEY_DSA_KEYGEN"},
        +{ERR_FUNC(DSA_F_SIG_CB),	"SIG_CB"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA DSA_str_reasons[]=
        +	{
        +{ERR_REASON(DSA_R_BAD_Q_VALUE)           ,"bad q value"},
        +{ERR_REASON(DSA_R_BN_DECODE_ERROR)       ,"bn decode error"},
        +{ERR_REASON(DSA_R_BN_ERROR)              ,"bn error"},
        +{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
        +{ERR_REASON(DSA_R_DECODE_ERROR)          ,"decode error"},
        +{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE)   ,"invalid digest type"},
        +{ERR_REASON(DSA_R_MISSING_PARAMETERS)    ,"missing parameters"},
        +{ERR_REASON(DSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
        +{ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"},
        +{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD)   ,"non fips dsa method"},
        +{ERR_REASON(DSA_R_NO_PARAMETERS_SET)     ,"no parameters set"},
        +{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_DSA_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(DSA_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,DSA_str_functs);
        +		ERR_load_strings(0,DSA_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_gen.c b/vendor/openssl/openssl/crypto/dsa/dsa_gen.c
        new file mode 100644
        index 000000000..c398761d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_gen.c
        @@ -0,0 +1,371 @@
        +/* crypto/dsa/dsa_gen.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#undef GENUINE_DSA
        +
        +#ifdef GENUINE_DSA
        +/* Parameter generation follows the original release of FIPS PUB 186,
        + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
        +#define HASH    EVP_sha()
        +#else
        +/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
        + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
        + * FIPS PUB 180-1) */
        +#define HASH    EVP_sha1()
        +#endif 
        +
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
        +
        +#ifndef OPENSSL_NO_SHA
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/sha.h>
        +#include "dsa_locl.h"
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +int DSA_generate_parameters_ex(DSA *ret, int bits,
        +		const unsigned char *seed_in, int seed_len,
        +		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)
        +			&& !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD);
        +		return 0;
        +		}
        +#endif
        +	if(ret->meth->dsa_paramgen)
        +		return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
        +				counter_ret, h_ret, cb);
        +#ifdef OPENSSL_FIPS
        +	else if (FIPS_mode())
        +		{
        +		return FIPS_dsa_generate_parameters_ex(ret, bits, 
        +							seed_in, seed_len,
        +							counter_ret, h_ret, cb);
        +		}
        +#endif
        +	else
        +		{
        +		const EVP_MD *evpmd;
        +		size_t qbits = bits >= 2048 ? 256 : 160;
        +
        +		if (bits >= 2048)
        +			{
        +			qbits = 256;
        +			evpmd = EVP_sha256();
        +			}
        +		else
        +			{
        +			qbits = 160;
        +			evpmd = EVP_sha1();
        +			}
        +
        +		return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
        +			seed_in, seed_len, NULL, counter_ret, h_ret, cb);
        +		}
        +	}
        +
        +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
        +	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
        +	unsigned char *seed_out,
        +	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
        +	{
        +	int ok=0;
        +	unsigned char seed[SHA256_DIGEST_LENGTH];
        +	unsigned char md[SHA256_DIGEST_LENGTH];
        +	unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH];
        +	BIGNUM *r0,*W,*X,*c,*test;
        +	BIGNUM *g=NULL,*q=NULL,*p=NULL;
        +	BN_MONT_CTX *mont=NULL;
        +	int i, k, n=0, m=0, qsize = qbits >> 3;
        +	int counter=0;
        +	int r=0;
        +	BN_CTX *ctx=NULL;
        +	unsigned int h=2;
        +
        +	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
        +	    qsize != SHA256_DIGEST_LENGTH)
        +		/* invalid q size */
        +		return 0;
        +
        +	if (evpmd == NULL)
        +		/* use SHA1 as default */
        +		evpmd = EVP_sha1();
        +
        +	if (bits < 512)
        +		bits = 512;
        +
        +	bits = (bits+63)/64*64;
        +
        +	/* NB: seed_len == 0 is special case: copy generated seed to
        + 	 * seed_in if it is not NULL.
        + 	 */
        +	if (seed_len && (seed_len < (size_t)qsize))
        +		seed_in = NULL;		/* seed buffer too small -- ignore */
        +	if (seed_len > (size_t)qsize) 
        +		seed_len = qsize;	/* App. 2.2 of FIPS PUB 186 allows larger SEED,
        +					 * but our internal buffers are restricted to 160 bits*/
        +	if (seed_in != NULL)
        +		memcpy(seed, seed_in, seed_len);
        +
        +	if ((ctx=BN_CTX_new()) == NULL)
        +		goto err;
        +
        +	if ((mont=BN_MONT_CTX_new()) == NULL)
        +		goto err;
        +
        +	BN_CTX_start(ctx);
        +	r0 = BN_CTX_get(ctx);
        +	g = BN_CTX_get(ctx);
        +	W = BN_CTX_get(ctx);
        +	q = BN_CTX_get(ctx);
        +	X = BN_CTX_get(ctx);
        +	c = BN_CTX_get(ctx);
        +	p = BN_CTX_get(ctx);
        +	test = BN_CTX_get(ctx);
        +
        +	if (!BN_lshift(test,BN_value_one(),bits-1))
        +		goto err;
        +
        +	for (;;)
        +		{
        +		for (;;) /* find q */
        +			{
        +			int seed_is_random;
        +
        +			/* step 1 */
        +			if(!BN_GENCB_call(cb, 0, m++))
        +				goto err;
        +
        +			if (!seed_len)
        +				{
        +				RAND_pseudo_bytes(seed, qsize);
        +				seed_is_random = 1;
        +				}
        +			else
        +				{
        +				seed_is_random = 0;
        +				seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
        +				}
        +			memcpy(buf , seed, qsize);
        +			memcpy(buf2, seed, qsize);
        +			/* precompute "SEED + 1" for step 7: */
        +			for (i = qsize-1; i >= 0; i--)
        +				{
        +				buf[i]++;
        +				if (buf[i] != 0)
        +					break;
        +				}
        +
        +			/* step 2 */
        +			if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL))
        +				goto err;
        +			if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL))
        +				goto err;
        +			for (i = 0; i < qsize; i++)
        +				md[i]^=buf2[i];
        +
        +			/* step 3 */
        +			md[0] |= 0x80;
        +			md[qsize-1] |= 0x01;
        +			if (!BN_bin2bn(md, qsize, q))
        +				goto err;
        +
        +			/* step 4 */
        +			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
        +					seed_is_random, cb);
        +			if (r > 0)
        +				break;
        +			if (r != 0)
        +				goto err;
        +
        +			/* do a callback call */
        +			/* step 5 */
        +			}
        +
        +		if(!BN_GENCB_call(cb, 2, 0)) goto err;
        +		if(!BN_GENCB_call(cb, 3, 0)) goto err;
        +
        +		/* step 6 */
        +		counter=0;
        +		/* "offset = 2" */
        +
        +		n=(bits-1)/160;
        +
        +		for (;;)
        +			{
        +			if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
        +				goto err;
        +
        +			/* step 7 */
        +			BN_zero(W);
        +			/* now 'buf' contains "SEED + offset - 1" */
        +			for (k=0; k<=n; k++)
        +				{
        +				/* obtain "SEED + offset + k" by incrementing: */
        +				for (i = qsize-1; i >= 0; i--)
        +					{
        +					buf[i]++;
        +					if (buf[i] != 0)
        +						break;
        +					}
        +
        +				if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
        +									NULL))
        +					goto err;
        +
        +				/* step 8 */
        +				if (!BN_bin2bn(md, qsize, r0))
        +					goto err;
        +				if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err;
        +				if (!BN_add(W,W,r0)) goto err;
        +				}
        +
        +			/* more of step 8 */
        +			if (!BN_mask_bits(W,bits-1)) goto err;
        +			if (!BN_copy(X,W)) goto err;
        +			if (!BN_add(X,X,test)) goto err;
        +
        +			/* step 9 */
        +			if (!BN_lshift1(r0,q)) goto err;
        +			if (!BN_mod(c,X,r0,ctx)) goto err;
        +			if (!BN_sub(r0,c,BN_value_one())) goto err;
        +			if (!BN_sub(p,X,r0)) goto err;
        +
        +			/* step 10 */
        +			if (BN_cmp(p,test) >= 0)
        +				{
        +				/* step 11 */
        +				r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
        +						ctx, 1, cb);
        +				if (r > 0)
        +						goto end; /* found it */
        +				if (r != 0)
        +					goto err;
        +				}
        +
        +			/* step 13 */
        +			counter++;
        +			/* "offset = offset + n + 1" */
        +
        +			/* step 14 */
        +			if (counter >= 4096) break;
        +			}
        +		}
        +end:
        +	if(!BN_GENCB_call(cb, 2, 1))
        +		goto err;
        +
        +	/* We now need to generate g */
        +	/* Set r0=(p-1)/q */
        +	if (!BN_sub(test,p,BN_value_one())) goto err;
        +	if (!BN_div(r0,NULL,test,q,ctx)) goto err;
        +
        +	if (!BN_set_word(test,h)) goto err;
        +	if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;
        +
        +	for (;;)
        +		{
        +		/* g=test^r0%p */
        +		if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
        +		if (!BN_is_one(g)) break;
        +		if (!BN_add(test,test,BN_value_one())) goto err;
        +		h++;
        +		}
        +
        +	if(!BN_GENCB_call(cb, 3, 1))
        +		goto err;
        +
        +	ok=1;
        +err:
        +	if (ok)
        +		{
        +		if(ret->p) BN_free(ret->p);
        +		if(ret->q) BN_free(ret->q);
        +		if(ret->g) BN_free(ret->g);
        +		ret->p=BN_dup(p);
        +		ret->q=BN_dup(q);
        +		ret->g=BN_dup(g);
        +		if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
        +			{
        +			ok=0;
        +			goto err;
        +			}
        +		if (counter_ret != NULL) *counter_ret=counter;
        +		if (h_ret != NULL) *h_ret=h;
        +		if (seed_out)
        +			memcpy(seed_out, seed, qsize);
        +		}
        +	if(ctx)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	if (mont != NULL) BN_MONT_CTX_free(mont);
        +	return ok;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_key.c b/vendor/openssl/openssl/crypto/dsa/dsa_key.c
        new file mode 100644
        index 000000000..9cf669b92
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_key.c
        @@ -0,0 +1,144 @@
        +/* crypto/dsa/dsa_key.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#ifndef OPENSSL_NO_SHA
        +#include <openssl/bn.h>
        +#include <openssl/dsa.h>
        +#include <openssl/rand.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +static int dsa_builtin_keygen(DSA *dsa);
        +
        +int DSA_generate_key(DSA *dsa)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
        +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD);
        +		return 0;
        +		}
        +#endif
        +	if(dsa->meth->dsa_keygen)
        +		return dsa->meth->dsa_keygen(dsa);
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		return FIPS_dsa_generate_key(dsa);
        +#endif
        +	return dsa_builtin_keygen(dsa);
        +	}
        +
        +static int dsa_builtin_keygen(DSA *dsa)
        +	{
        +	int ok=0;
        +	BN_CTX *ctx=NULL;
        +	BIGNUM *pub_key=NULL,*priv_key=NULL;
        +
        +	if ((ctx=BN_CTX_new()) == NULL) goto err;
        +
        +	if (dsa->priv_key == NULL)
        +		{
        +		if ((priv_key=BN_new()) == NULL) goto err;
        +		}
        +	else
        +		priv_key=dsa->priv_key;
        +
        +	do
        +		if (!BN_rand_range(priv_key,dsa->q)) goto err;
        +	while (BN_is_zero(priv_key));
        +
        +	if (dsa->pub_key == NULL)
        +		{
        +		if ((pub_key=BN_new()) == NULL) goto err;
        +		}
        +	else
        +		pub_key=dsa->pub_key;
        +	
        +	{
        +		BIGNUM local_prk;
        +		BIGNUM *prk;
        +
        +		if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
        +			{
        +			BN_init(&local_prk);
        +			prk = &local_prk;
        +			BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
        +			}
        +		else
        +			prk = priv_key;
        +
        +		if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err;
        +	}
        +
        +	dsa->priv_key=priv_key;
        +	dsa->pub_key=pub_key;
        +	ok=1;
        +
        +err:
        +	if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
        +	if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
        +	if (ctx != NULL) BN_CTX_free(ctx);
        +	return(ok);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_lib.c b/vendor/openssl/openssl/crypto/dsa/dsa_lib.c
        new file mode 100644
        index 000000000..96d8d0c4b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_lib.c
        @@ -0,0 +1,329 @@
        +/* crypto/dsa/dsa_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/dsa.h>
        +#include <openssl/asn1.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
        +
        +static const DSA_METHOD *default_DSA_method = NULL;
        +
        +void DSA_set_default_method(const DSA_METHOD *meth)
        +	{
        +	default_DSA_method = meth;
        +	}
        +
        +const DSA_METHOD *DSA_get_default_method(void)
        +	{
        +	if(!default_DSA_method)
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return FIPS_dsa_openssl();
        +		else
        +			return DSA_OpenSSL();
        +#else
        +		default_DSA_method = DSA_OpenSSL();
        +#endif
        +		}
        +	return default_DSA_method;
        +	}
        +
        +DSA *DSA_new(void)
        +	{
        +	return DSA_new_method(NULL);
        +	}
        +
        +int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
        +	{
        +	/* NB: The caller is specifically setting a method, so it's not up to us
        +	 * to deal with which ENGINE it comes from. */
        +        const DSA_METHOD *mtmp;
        +        mtmp = dsa->meth;
        +        if (mtmp->finish) mtmp->finish(dsa);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (dsa->engine)
        +		{
        +		ENGINE_finish(dsa->engine);
        +		dsa->engine = NULL;
        +		}
        +#endif
        +        dsa->meth = meth;
        +        if (meth->init) meth->init(dsa);
        +        return 1;
        +	}
        +
        +DSA *DSA_new_method(ENGINE *engine)
        +	{
        +	DSA *ret;
        +
        +	ret=(DSA *)OPENSSL_malloc(sizeof(DSA));
        +	if (ret == NULL)
        +		{
        +		DSAerr(DSA_F_DSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	ret->meth = DSA_get_default_method();
        +#ifndef OPENSSL_NO_ENGINE
        +	if (engine)
        +		{
        +		if (!ENGINE_init(engine))
        +			{
        +			DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		ret->engine = engine;
        +		}
        +	else
        +		ret->engine = ENGINE_get_default_DSA();
        +	if(ret->engine)
        +		{
        +		ret->meth = ENGINE_get_DSA(ret->engine);
        +		if(!ret->meth)
        +			{
        +			DSAerr(DSA_F_DSA_NEW_METHOD,
        +				ERR_R_ENGINE_LIB);
        +			ENGINE_finish(ret->engine);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		}
        +#endif
        +
        +	ret->pad=0;
        +	ret->version=0;
        +	ret->write_params=1;
        +	ret->p=NULL;
        +	ret->q=NULL;
        +	ret->g=NULL;
        +
        +	ret->pub_key=NULL;
        +	ret->priv_key=NULL;
        +
        +	ret->kinv=NULL;
        +	ret->r=NULL;
        +	ret->method_mont_p=NULL;
        +
        +	ret->references=1;
        +	ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
        +	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		if (ret->engine)
        +			ENGINE_finish(ret->engine);
        +#endif
        +		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +		}
        +	
        +	return(ret);
        +	}
        +
        +void DSA_free(DSA *r)
        +	{
        +	int i;
        +
        +	if (r == NULL) return;
        +
        +	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_DSA);
        +#ifdef REF_PRINT
        +	REF_PRINT("DSA",r);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"DSA_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +
        +	if(r->meth->finish)
        +		r->meth->finish(r);
        +#ifndef OPENSSL_NO_ENGINE
        +	if(r->engine)
        +		ENGINE_finish(r->engine);
        +#endif
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
        +
        +	if (r->p != NULL) BN_clear_free(r->p);
        +	if (r->q != NULL) BN_clear_free(r->q);
        +	if (r->g != NULL) BN_clear_free(r->g);
        +	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
        +	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
        +	if (r->kinv != NULL) BN_clear_free(r->kinv);
        +	if (r->r != NULL) BN_clear_free(r->r);
        +	OPENSSL_free(r);
        +	}
        +
        +int DSA_up_ref(DSA *r)
        +	{
        +	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA);
        +#ifdef REF_PRINT
        +	REF_PRINT("DSA",r);
        +#endif
        +#ifdef REF_CHECK
        +	if (i < 2)
        +		{
        +		fprintf(stderr, "DSA_up_ref, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +	return ((i > 1) ? 1 : 0);
        +	}
        +
        +int DSA_size(const DSA *r)
        +	{
        +	int ret,i;
        +	ASN1_INTEGER bs;
        +	unsigned char buf[4];	/* 4 bytes looks really small.
        +				   However, i2d_ASN1_INTEGER() will not look
        +				   beyond the first byte, as long as the second
        +				   parameter is NULL. */
        +
        +	i=BN_num_bits(r->q);
        +	bs.length=(i+7)/8;
        +	bs.data=buf;
        +	bs.type=V_ASN1_INTEGER;
        +	/* If the top bit is set the asn1 encoding is 1 larger. */
        +	buf[0]=0xff;	
        +
        +	i=i2d_ASN1_INTEGER(&bs,NULL);
        +	i+=i; /* r and s */
        +	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
        +	return(ret);
        +	}
        +
        +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +        {
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp,
        +				new_func, dup_func, free_func);
        +        }
        +
        +int DSA_set_ex_data(DSA *d, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&d->ex_data,idx,arg));
        +	}
        +
        +void *DSA_get_ex_data(DSA *d, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&d->ex_data,idx));
        +	}
        +
        +#ifndef OPENSSL_NO_DH
        +DH *DSA_dup_DH(const DSA *r)
        +	{
        +	/* DSA has p, q, g, optional pub_key, optional priv_key.
        +	 * DH has p, optional length, g, optional pub_key, optional priv_key,
        +	 * optional q.
        +	 */ 
        +
        +	DH *ret = NULL;
        +
        +	if (r == NULL)
        +		goto err;
        +	ret = DH_new();
        +	if (ret == NULL)
        +		goto err;
        +	if (r->p != NULL) 
        +		if ((ret->p = BN_dup(r->p)) == NULL)
        +			goto err;
        +	if (r->q != NULL)
        +		{
        +		ret->length = BN_num_bits(r->q);
        +		if ((ret->q = BN_dup(r->q)) == NULL)
        +			goto err;
        +		}
        +	if (r->g != NULL)
        +		if ((ret->g = BN_dup(r->g)) == NULL)
        +			goto err;
        +	if (r->pub_key != NULL)
        +		if ((ret->pub_key = BN_dup(r->pub_key)) == NULL)
        +			goto err;
        +	if (r->priv_key != NULL)
        +		if ((ret->priv_key = BN_dup(r->priv_key)) == NULL)
        +			goto err;
        +
        +	return ret;
        +
        + err:
        +	if (ret != NULL)
        +		DH_free(ret);
        +	return NULL;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_locl.h b/vendor/openssl/openssl/crypto/dsa/dsa_locl.h
        new file mode 100644
        index 000000000..21e2e4524
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_locl.h
        @@ -0,0 +1,60 @@
        +/* ====================================================================
        + * Copyright (c) 2007 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 <openssl/dsa.h>
        +
        +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
        +	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
        +	unsigned char *seed_out,
        +	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_ossl.c b/vendor/openssl/openssl/crypto/dsa/dsa_ossl.c
        new file mode 100644
        index 000000000..b3d78e524
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_ossl.c
        @@ -0,0 +1,412 @@
        +/* crypto/dsa/dsa_ossl.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/sha.h>
        +#include <openssl/dsa.h>
        +#include <openssl/rand.h>
        +#include <openssl/asn1.h>
        +
        +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
        +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
        +			 DSA *dsa);
        +static int dsa_init(DSA *dsa);
        +static int dsa_finish(DSA *dsa);
        +
        +static DSA_METHOD openssl_dsa_meth = {
        +"OpenSSL DSA method",
        +dsa_do_sign,
        +dsa_sign_setup,
        +dsa_do_verify,
        +NULL, /* dsa_mod_exp, */
        +NULL, /* dsa_bn_mod_exp, */
        +dsa_init,
        +dsa_finish,
        +0,
        +NULL,
        +NULL,
        +NULL
        +};
        +
        +/* These macro wrappers replace attempts to use the dsa_mod_exp() and
        + * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
        + * having a the macro work as an expression by bundling an "err_instr". So;
        + * 
        + *     if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
        + *                 dsa->method_mont_p)) goto err;
        + *
        + * can be replaced by;
        + *
        + *     DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
        + *                 dsa->method_mont_p);
        + */
        +
        +#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
        +	do { \
        +	int _tmp_res53; \
        +	if((dsa)->meth->dsa_mod_exp) \
        +		_tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
        +				(a2), (p2), (m), (ctx), (in_mont)); \
        +	else \
        +		_tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
        +				(m), (ctx), (in_mont)); \
        +	if(!_tmp_res53) err_instr; \
        +	} while(0)
        +#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
        +	do { \
        +	int _tmp_res53; \
        +	if((dsa)->meth->bn_mod_exp) \
        +		_tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
        +				(m), (ctx), (m_ctx)); \
        +	else \
        +		_tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
        +	if(!_tmp_res53) err_instr; \
        +	} while(0)
        +
        +const DSA_METHOD *DSA_OpenSSL(void)
        +{
        +	return &openssl_dsa_meth;
        +}
        +
        +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        +	{
        +	BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
        +	BIGNUM m;
        +	BIGNUM xr;
        +	BN_CTX *ctx=NULL;
        +	int reason=ERR_R_BN_LIB;
        +	DSA_SIG *ret=NULL;
        +	int noredo = 0;
        +
        +	BN_init(&m);
        +	BN_init(&xr);
        +
        +	if (!dsa->p || !dsa->q || !dsa->g)
        +		{
        +		reason=DSA_R_MISSING_PARAMETERS;
        +		goto err;
        +		}
        +
        +	s=BN_new();
        +	if (s == NULL) goto err;
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +redo:
        +	if ((dsa->kinv == NULL) || (dsa->r == NULL))
        +		{
        +		if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
        +		}
        +	else
        +		{
        +		kinv=dsa->kinv;
        +		dsa->kinv=NULL;
        +		r=dsa->r;
        +		dsa->r=NULL;
        +		noredo = 1;
        +		}
        +
        +	
        +	if (dlen > BN_num_bytes(dsa->q))
        +		/* if the digest length is greater than the size of q use the
        +		 * BN_num_bits(dsa->q) leftmost bits of the digest, see
        +		 * fips 186-3, 4.2 */
        +		dlen = BN_num_bytes(dsa->q);
        +	if (BN_bin2bn(dgst,dlen,&m) == NULL)
        +		goto err;
        +
        +	/* Compute  s = inv(k) (m + xr) mod q */
        +	if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
        +	if (!BN_add(s, &xr, &m)) goto err;		/* s = m + xr */
        +	if (BN_cmp(s,dsa->q) > 0)
        +		if (!BN_sub(s,s,dsa->q)) goto err;
        +	if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
        +
        +	ret=DSA_SIG_new();
        +	if (ret == NULL) goto err;
        +	/* Redo if r or s is zero as required by FIPS 186-3: this is
        +	 * very unlikely.
        +	 */
        +	if (BN_is_zero(r) || BN_is_zero(s))
        +		{
        +		if (noredo)
        +			{
        +			reason = DSA_R_NEED_NEW_SETUP_VALUES;
        +			goto err;
        +			}
        +		goto redo;
        +		}
        +	ret->r = r;
        +	ret->s = s;
        +	
        +err:
        +	if (!ret)
        +		{
        +		DSAerr(DSA_F_DSA_DO_SIGN,reason);
        +		BN_free(r);
        +		BN_free(s);
        +		}
        +	if (ctx != NULL) BN_CTX_free(ctx);
        +	BN_clear_free(&m);
        +	BN_clear_free(&xr);
        +	if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
        +	    BN_clear_free(kinv);
        +	return(ret);
        +	}
        +
        +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        +	{
        +	BN_CTX *ctx;
        +	BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
        +	int ret=0;
        +
        +	if (!dsa->p || !dsa->q || !dsa->g)
        +		{
        +		DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
        +		return 0;
        +		}
        +
        +	BN_init(&k);
        +	BN_init(&kq);
        +
        +	if (ctx_in == NULL)
        +		{
        +		if ((ctx=BN_CTX_new()) == NULL) goto err;
        +		}
        +	else
        +		ctx=ctx_in;
        +
        +	if ((r=BN_new()) == NULL) goto err;
        +
        +	/* Get random k */
        +	do
        +		if (!BN_rand_range(&k, dsa->q)) goto err;
        +	while (BN_is_zero(&k));
        +	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
        +		{
        +		BN_set_flags(&k, BN_FLG_CONSTTIME);
        +		}
        +
        +	if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
        +		{
        +		if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
        +						CRYPTO_LOCK_DSA,
        +						dsa->p, ctx))
        +			goto err;
        +		}
        +
        +	/* Compute r = (g^k mod p) mod q */
        +
        +	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
        +		{
        +		if (!BN_copy(&kq, &k)) goto err;
        +
        +		/* We do not want timing information to leak the length of k,
        +		 * so we compute g^k using an equivalent exponent of fixed length.
        +		 *
        +		 * (This is a kludge that we need because the BN_mod_exp_mont()
        +		 * does not let us specify the desired timing behaviour.) */
        +
        +		if (!BN_add(&kq, &kq, dsa->q)) goto err;
        +		if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
        +			{
        +			if (!BN_add(&kq, &kq, dsa->q)) goto err;
        +			}
        +
        +		K = &kq;
        +		}
        +	else
        +		{
        +		K = &k;
        +		}
        +	DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
        +			dsa->method_mont_p);
        +	if (!BN_mod(r,r,dsa->q,ctx)) goto err;
        +
        +	/* Compute  part of 's = inv(k) (m + xr) mod q' */
        +	if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
        +
        +	if (*kinvp != NULL) BN_clear_free(*kinvp);
        +	*kinvp=kinv;
        +	kinv=NULL;
        +	if (*rp != NULL) BN_clear_free(*rp);
        +	*rp=r;
        +	ret=1;
        +err:
        +	if (!ret)
        +		{
        +		DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
        +		if (r != NULL)
        +			BN_clear_free(r);
        +		}
        +	if (ctx_in == NULL) BN_CTX_free(ctx);
        +	BN_clear_free(&k);
        +	BN_clear_free(&kq);
        +	return(ret);
        +	}
        +
        +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
        +			 DSA *dsa)
        +	{
        +	BN_CTX *ctx;
        +	BIGNUM u1,u2,t1;
        +	BN_MONT_CTX *mont=NULL;
        +	int ret = -1, i;
        +	if (!dsa->p || !dsa->q || !dsa->g)
        +		{
        +		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
        +		return -1;
        +		}
        +
        +	i = BN_num_bits(dsa->q);
        +	/* fips 186-3 allows only different sizes for q */
        +	if (i != 160 && i != 224 && i != 256)
        +		{
        +		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
        +		return -1;
        +		}
        +
        +	if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
        +		{
        +		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
        +		return -1;
        +		}
        +	BN_init(&u1);
        +	BN_init(&u2);
        +	BN_init(&t1);
        +
        +	if ((ctx=BN_CTX_new()) == NULL) goto err;
        +
        +	if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
        +	    BN_ucmp(sig->r, dsa->q) >= 0)
        +		{
        +		ret = 0;
        +		goto err;
        +		}
        +	if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
        +	    BN_ucmp(sig->s, dsa->q) >= 0)
        +		{
        +		ret = 0;
        +		goto err;
        +		}
        +
        +	/* Calculate W = inv(S) mod Q
        +	 * save W in u2 */
        +	if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
        +
        +	/* save M in u1 */
        +	if (dgst_len > (i >> 3))
        +		/* if the digest length is greater than the size of q use the
        +		 * BN_num_bits(dsa->q) leftmost bits of the digest, see
        +		 * fips 186-3, 4.2 */
        +		dgst_len = (i >> 3);
        +	if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
        +
        +	/* u1 = M * w mod q */
        +	if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
        +
        +	/* u2 = r * w mod q */
        +	if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
        +
        +
        +	if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
        +		{
        +		mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
        +					CRYPTO_LOCK_DSA, dsa->p, ctx);
        +		if (!mont)
        +			goto err;
        +		}
        +
        +
        +	DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
        +	/* BN_copy(&u1,&t1); */
        +	/* let u1 = u1 mod q */
        +	if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
        +
        +	/* V is now in u1.  If the signature is correct, it will be
        +	 * equal to R. */
        +	ret=(BN_ucmp(&u1, sig->r) == 0);
        +
        +	err:
        +	/* XXX: surely this is wrong - if ret is 0, it just didn't verify;
        +	   there is no error in BN. Test should be ret == -1 (Ben) */
        +	if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
        +	if (ctx != NULL) BN_CTX_free(ctx);
        +	BN_free(&u1);
        +	BN_free(&u2);
        +	BN_free(&t1);
        +	return(ret);
        +	}
        +
        +static int dsa_init(DSA *dsa)
        +{
        +	dsa->flags|=DSA_FLAG_CACHE_MONT_P;
        +	return(1);
        +}
        +
        +static int dsa_finish(DSA *dsa)
        +{
        +	if(dsa->method_mont_p)
        +		BN_MONT_CTX_free(dsa->method_mont_p);
        +	return(1);
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_pmeth.c b/vendor/openssl/openssl/crypto/dsa/dsa_pmeth.c
        new file mode 100644
        index 000000000..715d8d675
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_pmeth.c
        @@ -0,0 +1,318 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include "evp_locl.h"
        +#include "dsa_locl.h"
        +
        +/* DSA pkey context structure */
        +
        +typedef struct
        +	{
        +	/* Parameter gen parameters */
        +	int nbits;		/* size of p in bits (default: 1024) */
        +	int qbits;		/* size of q in bits (default: 160)  */
        +	const EVP_MD *pmd;	/* MD for parameter generation */
        +	/* Keygen callback info */
        +	int gentmp[2];
        +	/* message digest */
        +	const EVP_MD *md;	/* MD for the signature */
        +	} DSA_PKEY_CTX;
        +
        +static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
        +	{
        +	DSA_PKEY_CTX *dctx;
        +	dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX));
        +	if (!dctx)
        +		return 0;
        +	dctx->nbits = 1024;
        +	dctx->qbits = 160;
        +	dctx->pmd = NULL;
        +	dctx->md = NULL;
        +
        +	ctx->data = dctx;
        +	ctx->keygen_info = dctx->gentmp;
        +	ctx->keygen_info_count = 2;
        +	
        +	return 1;
        +	}
        +
        +static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	DSA_PKEY_CTX *dctx, *sctx;
        +	if (!pkey_dsa_init(dst))
        +		return 0;
        +       	sctx = src->data;
        +	dctx = dst->data;
        +	dctx->nbits = sctx->nbits;
        +	dctx->qbits = sctx->qbits;
        +	dctx->pmd = sctx->pmd;
        +	dctx->md  = sctx->md;
        +	return 1;
        +	}
        +
        +static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
        +	{
        +	DSA_PKEY_CTX *dctx = ctx->data;
        +	if (dctx)
        +		OPENSSL_free(dctx);
        +	}
        +
        +static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen)
        +	{
        +	int ret, type;
        +	unsigned int sltmp;
        +	DSA_PKEY_CTX *dctx = ctx->data;
        +	DSA *dsa = ctx->pkey->pkey.dsa;
        +
        +	if (dctx->md)
        +		type = EVP_MD_type(dctx->md);
        +	else
        +		type = NID_sha1;
        +
        +	ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa);
        +
        +	if (ret <= 0)
        +		return ret;
        +	*siglen = sltmp;
        +	return 1;
        +	}
        +
        +static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
        +					const unsigned char *sig, size_t siglen,
        +					const unsigned char *tbs, size_t tbslen)
        +	{
        +	int ret, type;
        +	DSA_PKEY_CTX *dctx = ctx->data;
        +	DSA *dsa = ctx->pkey->pkey.dsa;
        +
        +	if (dctx->md)
        +		type = EVP_MD_type(dctx->md);
        +	else
        +		type = NID_sha1;
        +
        +	ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa);
        +
        +	return ret;
        +	}
        +
        +static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	DSA_PKEY_CTX *dctx = ctx->data;
        +	switch (type)
        +		{
        +		case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
        +		if (p1 < 256)
        +			return -2;
        +		dctx->nbits = p1;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
        +		if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
        +			return -2;
        +		dctx->qbits = p1;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
        +		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1   &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
        +			{
        +			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
        +			return 0;
        +			}
        +		dctx->md = p2;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_MD:
        +		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1   &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_dsa    &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA    &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
        +			{
        +			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
        +			return 0;
        +			}
        +		dctx->md = p2;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_DIGESTINIT:
        +		case EVP_PKEY_CTRL_PKCS7_SIGN:
        +		case EVP_PKEY_CTRL_CMS_SIGN:
        +		return 1;
        +		
        +		case EVP_PKEY_CTRL_PEER_KEY:
        +			DSAerr(DSA_F_PKEY_DSA_CTRL,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +			return -2;	
        +		default:
        +		return -2;
        +
        +		}
        +	}
        +			
        +static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
        +			const char *type, const char *value)
        +	{
        +	if (!strcmp(type, "dsa_paramgen_bits"))
        +		{
        +		int nbits;
        +		nbits = atoi(value);
        +		return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
        +		}
        +	if (!strcmp(type, "dsa_paramgen_q_bits"))
        +		{
        +		int qbits = atoi(value);
        +		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
        +		                         EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL);
        +		}
        +	if (!strcmp(type, "dsa_paramgen_md"))
        +		{
        +		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
        +		                         EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 
        +		                         (void *)EVP_get_digestbyname(value));
        +		}
        +	return -2;
        +	}
        +
        +static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	DSA *dsa = NULL;
        +	DSA_PKEY_CTX *dctx = ctx->data;
        +	BN_GENCB *pcb, cb;
        +	int ret;
        +	if (ctx->pkey_gencb)
        +		{
        +		pcb = &cb;
        +		evp_pkey_set_cb_translate(pcb, ctx);
        +		}
        +	else
        +		pcb = NULL;
        +	dsa = DSA_new();
        +	if (!dsa)
        +		return 0;
        +	ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
        +	                           NULL, 0, NULL, NULL, NULL, pcb);
        +	if (ret)
        +		EVP_PKEY_assign_DSA(pkey, dsa);
        +	else
        +		DSA_free(dsa);
        +	return ret;
        +	}
        +
        +static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	DSA *dsa = NULL;
        +	if (ctx->pkey == NULL)
        +		{
        +		DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
        +		return 0;
        +		}
        +	dsa = DSA_new();
        +	if (!dsa)
        +		return 0;
        +	EVP_PKEY_assign_DSA(pkey, dsa);
        +	/* Note: if error return, pkey is freed by parent routine */
        +	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
        +		return 0;
        +	return DSA_generate_key(pkey->pkey.dsa);
        +	}
        +
        +const EVP_PKEY_METHOD dsa_pkey_meth = 
        +	{
        +	EVP_PKEY_DSA,
        +	EVP_PKEY_FLAG_AUTOARGLEN,
        +	pkey_dsa_init,
        +	pkey_dsa_copy,
        +	pkey_dsa_cleanup,
        +
        +	0,
        +	pkey_dsa_paramgen,
        +
        +	0,
        +	pkey_dsa_keygen,
        +
        +	0,
        +	pkey_dsa_sign,
        +
        +	0,
        +	pkey_dsa_verify,
        +
        +	0,0,
        +
        +	0,0,0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	pkey_dsa_ctrl,
        +	pkey_dsa_ctrl_str
        +
        +
        +	};
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_prn.c b/vendor/openssl/openssl/crypto/dsa/dsa_prn.c
        new file mode 100644
        index 000000000..6f29f5e24
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_prn.c
        @@ -0,0 +1,121 @@
        +/* crypto/dsa/dsa_prn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/dsa.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +int DSA_print_fp(FILE *fp, const DSA *x, int off)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	ret=DSA_print(b,x,off);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +
        +int DSAparams_print_fp(FILE *fp, const DSA *x)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	ret=DSAparams_print(b, x);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +#endif
        +
        +int DSA_print(BIO *bp, const DSA *x, int off)
        +	{
        +	EVP_PKEY *pk;
        +	int ret;
        +	pk = EVP_PKEY_new();
        +	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
        +		return 0;
        +	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
        +	EVP_PKEY_free(pk);
        +	return ret;
        +	}
        +
        +int DSAparams_print(BIO *bp, const DSA *x)
        +	{
        +	EVP_PKEY *pk;
        +	int ret;
        +	pk = EVP_PKEY_new();
        +	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
        +		return 0;
        +	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
        +	EVP_PKEY_free(pk);
        +	return ret;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_sign.c b/vendor/openssl/openssl/crypto/dsa/dsa_sign.c
        new file mode 100644
        index 000000000..c3cc3642c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_sign.c
        @@ -0,0 +1,114 @@
        +/* crypto/dsa/dsa_sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
        +
        +#include "cryptlib.h"
        +#include <openssl/dsa.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +
        +DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
        +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD);
        +		return NULL;
        +		}
        +#endif
        +	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
        +	}
        +
        +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
        +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD);
        +		return 0;
        +		}
        +#endif
        +	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
        +	}
        +
        +DSA_SIG *DSA_SIG_new(void)
        +	{
        +	DSA_SIG *sig;
        +	sig = OPENSSL_malloc(sizeof(DSA_SIG));
        +	if (!sig)
        +		return NULL;
        +	sig->r = NULL;
        +	sig->s = NULL;
        +	return sig;
        +	}
        +
        +void DSA_SIG_free(DSA_SIG *sig)
        +	{
        +	if (sig)
        +		{
        +		if (sig->r)
        +			BN_free(sig->r);
        +		if (sig->s)
        +			BN_free(sig->s);
        +		OPENSSL_free(sig);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsa_vrf.c b/vendor/openssl/openssl/crypto/dsa/dsa_vrf.c
        new file mode 100644
        index 000000000..674cb5fa5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsa_vrf.c
        @@ -0,0 +1,76 @@
        +/* crypto/dsa/dsa_vrf.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
        +
        +#include "cryptlib.h"
        +#include <openssl/dsa.h>
        +
        +int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
        +		  DSA *dsa)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
        +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD);
        +		return -1;
        +		}
        +#endif
        +	return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsagen.c b/vendor/openssl/openssl/crypto/dsa/dsagen.c
        new file mode 100644
        index 000000000..1b6a1cca0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsagen.c
        @@ -0,0 +1,111 @@
        +/* crypto/dsa/dsagen.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/dsa.h>
        +
        +#define TEST
        +#define GENUINE_DSA
        +
        +#ifdef GENUINE_DSA
        +#define LAST_VALUE 0xbd
        +#else
        +#define LAST_VALUE 0xd3
        +#endif
        +
        +#ifdef TEST
        +unsigned char seed[20]={
        +	0xd5,0x01,0x4e,0x4b,
        +	0x60,0xef,0x2b,0xa8,
        +	0xb6,0x21,0x1b,0x40,
        +	0x62,0xba,0x32,0x24,
        +	0xe0,0x42,0x7d,LAST_VALUE};
        +#endif
        +
        +int cb(int p, int n)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	printf("%c",c);
        +	fflush(stdout);
        +	}
        +
        +main()
        +	{
        +	int i;
        +	BIGNUM *n;
        +	BN_CTX *ctx;
        +	unsigned char seed_buf[20];
        +	DSA *dsa;
        +	int counter,h;
        +	BIO *bio_err=NULL;
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	memcpy(seed_buf,seed,20);
        +	dsa=DSA_generate_parameters(1024,seed,20,&counter,&h,cb,bio_err);
        +
        +	if (dsa == NULL)
        +		DSA_print(bio_err,dsa,0);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/dsa/dsatest.c b/vendor/openssl/openssl/crypto/dsa/dsatest.c
        new file mode 100644
        index 000000000..edffd24e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/dsatest.c
        @@ -0,0 +1,259 @@
        +/* crypto/dsa/dsatest.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.]
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include <sys/stat.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/rand.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +
        +#ifdef OPENSSL_NO_DSA
        +int main(int argc, char *argv[])
        +{
        +    printf("No DSA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/dsa.h>
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define MS_CALLBACK     _far _loadds
        +#else
        +#define MS_CALLBACK
        +#endif
        +
        +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg);
        +
        +/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
        + * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
        +static unsigned char seed[20]={
        +	0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
        +	0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
        +	};
        +
        +static unsigned char out_p[]={
        +	0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
        +	0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
        +	0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
        +	0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
        +	0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
        +	0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
        +	0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
        +	0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
        +	};
        +
        +static unsigned char out_q[]={
        +	0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
        +	0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
        +	0xda,0xce,0x91,0x5f,
        +	};
        +
        +static unsigned char out_g[]={
        +	0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
        +	0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
        +	0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
        +	0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
        +	0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
        +	0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
        +	0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
        +	0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
        +	};
        +
        +static const unsigned char str1[]="12345678901234567890";
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +static BIO *bio_err=NULL;
        +
        +int main(int argc, char **argv)
        +	{
        +	BN_GENCB cb;
        +	DSA *dsa=NULL;
        +	int counter,ret=0,i,j;
        +	unsigned char buf[256];
        +	unsigned long h;
        +	unsigned char sig[256];
        +	unsigned int siglen;
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	ERR_load_crypto_strings();
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	BIO_printf(bio_err,"test generation of DSA parameters\n");
        +
        +	BN_GENCB_set(&cb, dsa_cb, bio_err);
        +	if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
        +				seed, 20, &counter, &h, &cb))
        +		goto end;
        +
        +	BIO_printf(bio_err,"seed\n");
        +	for (i=0; i<20; i+=4)
        +		{
        +		BIO_printf(bio_err,"%02X%02X%02X%02X ",
        +			seed[i],seed[i+1],seed[i+2],seed[i+3]);
        +		}
        +	BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h);
        +		
        +	DSA_print(bio_err,dsa,0);
        +	if (counter != 105) 
        +		{
        +		BIO_printf(bio_err,"counter should be 105\n");
        +		goto end;
        +		}
        +	if (h != 2)
        +		{
        +		BIO_printf(bio_err,"h should be 2\n");
        +		goto end;
        +		}
        +
        +	i=BN_bn2bin(dsa->q,buf);
        +	j=sizeof(out_q);
        +	if ((i != j) || (memcmp(buf,out_q,i) != 0))
        +		{
        +		BIO_printf(bio_err,"q value is wrong\n");
        +		goto end;
        +		}
        +
        +	i=BN_bn2bin(dsa->p,buf);
        +	j=sizeof(out_p);
        +	if ((i != j) || (memcmp(buf,out_p,i) != 0))
        +		{
        +		BIO_printf(bio_err,"p value is wrong\n");
        +		goto end;
        +		}
        +
        +	i=BN_bn2bin(dsa->g,buf);
        +	j=sizeof(out_g);
        +	if ((i != j) || (memcmp(buf,out_g,i) != 0))
        +		{
        +		BIO_printf(bio_err,"g value is wrong\n");
        +		goto end;
        +		}
        +
        +	dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
        +	DSA_generate_key(dsa);
        +	DSA_sign(0, str1, 20, sig, &siglen, dsa);
        +	if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
        +		ret=1;
        +
        +	dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
        +	DSA_generate_key(dsa);
        +	DSA_sign(0, str1, 20, sig, &siglen, dsa);
        +	if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
        +		ret=1;
        +
        +end:
        +	if (!ret)
        +		ERR_print_errors(bio_err);
        +	if (dsa != NULL) DSA_free(dsa);
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	ERR_free_strings();
        +	CRYPTO_mem_leaks(bio_err);
        +	if (bio_err != NULL)
        +		{
        +		BIO_free(bio_err);
        +		bio_err = NULL;
        +		}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (!ret) printf("ERROR\n");
        +#endif
        +	EXIT(!ret);
        +	return(0);
        +	}
        +
        +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg)
        +	{
        +	char c='*';
        +	static int ok=0,num=0;
        +
        +	if (p == 0) { c='.'; num++; };
        +	if (p == 1) c='+';
        +	if (p == 2) { c='*'; ok++; }
        +	if (p == 3) c='\n';
        +	BIO_write(arg->arg,&c,1);
        +	(void)BIO_flush(arg->arg);
        +
        +	if (!ok && (p == 0) && (num > 1))
        +		{
        +		BIO_printf((BIO *)arg,"error in dsatest\n");
        +		return 0;
        +		}
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dsa/fips186a.txt b/vendor/openssl/openssl/crypto/dsa/fips186a.txt
        new file mode 100644
        index 000000000..3a2e0a0d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dsa/fips186a.txt
        @@ -0,0 +1,122 @@
        +The origional FIPE 180 used SHA-0 (FIPS 180) for its appendix 5
        +examples.  This is an updated version that uses SHA-1 (FIPS 180-1)
        +supplied to me by Wei Dai
        +--
        +		     APPENDIX 5. EXAMPLE OF THE DSA
        +
        +
        +This appendix is for informational purposes only and is not required to meet
        +the standard.
        +
        +Let L = 512 (size of p).  The values in this example are expressed in
        +hexadecimal notation.  The p and q given here were generated by the prime
        +generation standard described in appendix 2 using the 160-bit SEED:
        +
        +          d5014e4b 60ef2ba8 b6211b40 62ba3224 e0427dd3
        +
        +With this SEED, the algorithm found p and q when the counter was at 105.
        +
        +x was generated by the algorithm described in appendix 3, section 3.1, using
        +the SHA to construct G (as in appendix 3, section 3.3) and a 160-bit XSEED:
        +
        +XSEED =   
        +
        +	bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
        +
        +t =
        +	67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0
        +
        +x = G(t,XSEED) mod q
        +
        +k was generated by the algorithm described in appendix 3, section 3.2, using
        +the SHA to construct G (as in appendix 3, section 3.3) and a 160-bit KSEED:
        +
        +KSEED =
        +
        +	687a66d9 0648f993 867e121f 4ddf9ddb 01205584
        +
        +t =
        +	EFCDAB89 98BADCFE 10325476 C3D2E1F0 67452301
        +
        +k = G(t,KSEED) mod q
        +
        +Finally:
        +
        +h = 2
        +
        +p =
        +	8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
        +	cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
        +	49693dfb f83724c2 ec0736ee 31c80291
        +
        +
        +q =
        +	c773218c 737ec8ee 993b4f2d ed30f48e dace915f
        +
        +
        +g =
        +	626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
        +	3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
        +	c42e9f6f 464b088c c572af53 e6d78802
        +
        +
        +x =
        +	2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
        +
        +
        +k =
        +	358dad57 1462710f 50e254cf 1a376b2b deaadfbf
        +
        +
        +kinv = 
        +
        +	0d516729 8202e49b 4116ac10 4fc3f415 ae52f917
        +
        +M = ASCII form of "abc" (See FIPS PUB 180-1, Appendix A)
        +
        +SHA(M) =  
        +
        +	a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
        +
        +
        +y =
        +
        +	19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85 
        +	9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
        +	858fba33 f44c0669 9630a76b 030ee333
        +
        +
        +r =
        +	8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0
        +
        +s =
        +	41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8
        +
        +
        +w =
        +	9df4ece5 826be95f ed406d41 b43edc0b 1c18841b
        +
        +
        +u1 =
        +	bf655bd0 46f0b35e c791b004 804afcbb 8ef7d69d
        +
        +
        +u2 =
        +	821a9263 12e97ade abcc8d08 2b527897 8a2df4b0
        +
        +
        +gu1 mod p =
        +
        +	51b1bf86 7888e5f3 af6fb476 9dd016bc fe667a65 aafc2753
        +	9063bd3d 2b138b4c e02cc0c0 2ec62bb6 7306c63e 4db95bbf
        +	6f96662a 1987a21b e4ec1071 010b6069
        +
        +
        +yu2 mod p =
        +
        +	8b510071 2957e950 50d6b8fd 376a668e 4b0d633c 1e46e665
        +	5c611a72 e2b28483 be52c74d 4b30de61 a668966e dc307a67 
        +	c19441f4 22bf3c34 08aeba1f 0a4dbec7
        +
        +v =
        +	8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0
        diff --git a/vendor/openssl/openssl/crypto/dso/Makefile b/vendor/openssl/openssl/crypto/dso/Makefile
        new file mode 100644
        index 000000000..fb2709ed6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/Makefile
        @@ -0,0 +1,150 @@
        +#
        +# OpenSSL/crypto/dso/Makefile
        +#
        +
        +DIR=	dso
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +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 dso_beos.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 dso_beos.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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_beos.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_beos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_beos.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +dso_beos.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dso_beos.o: ../../include/openssl/opensslconf.h
        +dso_beos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +dso_beos.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dso_beos.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_beos.c
        +dso_dl.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_dl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_dl.o: ../../include/openssl/dso.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/ossl_typ.h ../../include/openssl/safestack.h
        +dso_dl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dso_dl.o: ../cryptlib.h dso_dl.c
        +dso_dlfcn.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_dlfcn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_dlfcn.o: ../../include/openssl/dso.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/ossl_typ.h
        +dso_dlfcn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dso_dlfcn.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_dlfcn.c
        +dso_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +dso_err.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +dso_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +dso_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +dso_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +dso_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dso_err.o: dso_err.c
        +dso_lib.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_lib.o: ../../include/openssl/dso.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/ossl_typ.h ../../include/openssl/safestack.h
        +dso_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dso_lib.o: ../cryptlib.h dso_lib.c
        +dso_null.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_null.o: ../../include/openssl/dso.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/ossl_typ.h
        +dso_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dso_null.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_null.c
        +dso_openssl.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_openssl.o: ../../include/openssl/dso.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/ossl_typ.h
        +dso_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dso_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_openssl.c
        +dso_vms.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_vms.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_vms.o: ../../include/openssl/dso.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/ossl_typ.h ../../include/openssl/safestack.h
        +dso_vms.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +dso_vms.o: ../cryptlib.h dso_vms.c
        +dso_win32.o: ../../e_os.h ../../include/openssl/bio.h
        +dso_win32.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +dso_win32.o: ../../include/openssl/dso.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/ossl_typ.h
        +dso_win32.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +dso_win32.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_win32.c
        diff --git a/vendor/openssl/openssl/crypto/dso/README b/vendor/openssl/openssl/crypto/dso/README
        new file mode 100644
        index 000000000..d0bc9a89f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/README
        @@ -0,0 +1,22 @@
        +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.
        +
        +There is now a callback scheme in place where filename conversion can
        +(a) be turned off altogether through the use of the
        +    DSO_FLAG_NO_NAME_TRANSLATION flag,
        +(b) be handled by default using the default DSO_METHOD's converter
        +(c) overriden per-DSO by setting the override callback
        +(d) a mix of (b) and (c) - eg. implement an override callback that;
        +    (i) checks if we're win32 (if(strstr(dso->meth->name, "win32")....)
        +        and if so, convert "blah" into "blah32.dll" (the default is
        +	otherwise to make it "blah.dll").
        +    (ii) default to the normal behaviour - we're not on win32, eg.
        +         finish with (return dso->meth->dso_name_converter(dso,NULL)).
        +
        diff --git a/vendor/openssl/openssl/crypto/dso/dso.h b/vendor/openssl/openssl/crypto/dso/dso.h
        new file mode 100644
        index 000000000..839f2e061
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso.h
        @@ -0,0 +1,409 @@
        +/* dso.h -*- mode:C; c-file-style: "eay" -*- */
        +/* 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 <openssl/crypto.h>
        +
        +#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
        +
        +/* By default, DSO_load() will translate the provided filename into a form
        + * typical for the platform (more specifically the DSO_METHOD) using the
        + * dso_name_converter function of the method. Eg. win32 will transform "blah"
        + * into "blah.dll", and dlfcn will transform it into "libblah.so". The
        + * behaviour can be overriden by setting the name_converter callback in the DSO
        + * object (using DSO_set_name_converter()). This callback could even utilise
        + * the DSO_METHOD's converter too if it only wants to override behaviour for
        + * one or two possible DSO methods. However, the following flag can be set in a
        + * DSO to prevent *any* native name-translation at all - eg. if the caller has
        + * prompted the user for a path to a driver library so the filename should be
        + * interpreted as-is. */
        +#define DSO_FLAG_NO_NAME_TRANSLATION		0x01
        +/* An extra flag to give if only the extension should be added as
        + * translation.  This is obviously only of importance on Unix and
        + * other operating systems where the translation also may prefix
        + * the name with something, like 'lib', and ignored everywhere else.
        + * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used
        + * at the same time. */
        +#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY	0x02
        +
        +/* 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			0x10
        +
        +/* This flag loads the library with public symbols.
        + * Meaning: The exported symbols of this library are public
        + * to all libraries loaded after this library.
        + * At the moment only implemented in unix.
        + */
        +#define DSO_FLAG_GLOBAL_SYMBOLS			0x20
        +
        +
        +typedef void (*DSO_FUNC_TYPE)(void);
        +
        +typedef struct dso_st DSO;
        +
        +/* The function prototype used for method functions (or caller-provided
        + * callbacks) that transform filenames. They are passed a DSO structure pointer
        + * (or NULL if they are to be used independantly of a DSO object) and a
        + * filename to transform. They should either return NULL (if there is an error
        + * condition) or a newly allocated string containing the transformed form that
        + * the caller will need to free with OPENSSL_free() when done. */
        +typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
        +/* The function prototype used for method functions (or caller-provided
        + * callbacks) that merge two file specifications. They are passed a
        + * DSO structure pointer (or NULL if they are to be used independantly of
        + * a DSO object) and two file specifications to merge. They should
        + * either return NULL (if there is an error condition) or a newly allocated
        + * string containing the result of merging that the caller will need
        + * to free with OPENSSL_free() when done.
        + * Here, merging means that bits and pieces are taken from each of the
        + * file specifications and added together in whatever fashion that is
        + * sensible for the DSO method in question.  The only rule that really
        + * applies is that if the two specification contain pieces of the same
        + * type, the copy from the first string takes priority.  One could see
        + * it as the first specification is the one given by the user and the
        + * second being a bunch of defaults to add on if they're missing in the
        + * first. */
        +typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
        +
        +typedef struct dso_meth_st
        +	{
        +	const char *name;
        +	/* Loads a shared library, NB: new DSO_METHODs must ensure that a
        +	 * successful load populates the loaded_filename field, and likewise a
        +	 * successful unload OPENSSL_frees and NULLs it out. */
        +	int (*dso_load)(DSO *dso);
        +	/* 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);
        +	/* The default DSO_METHOD-specific function for converting filenames to
        +	 * a canonical native form. */
        +	DSO_NAME_CONVERTER_FUNC dso_name_converter;
        +	/* The default DSO_METHOD-specific function for converting filenames to
        +	 * a canonical native form. */
        +	DSO_MERGER_FUNC dso_merger;
        +
        +	/* [De]Initialisation handlers. */
        +	int (*init)(DSO *dso);
        +	int (*finish)(DSO *dso);
        +
        +	/* Return pathname of the module containing location */
        +	int (*pathbyaddr)(void *addr,char *path,int sz);
        +	/* Perform global symbol lookup, i.e. among *all* modules */
        +	void *(*globallookup)(const char *symname);
        +	} 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_OF(void) *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;
        +	/* If this callback function pointer is set to non-NULL, then it will
        +	 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
        +	 * should normally set using DSO_set_name_converter(). */
        +	DSO_NAME_CONVERTER_FUNC name_converter;
        +	/* If this callback function pointer is set to non-NULL, then it will
        +	 * be used in DSO_load() in place of meth->dso_merger. NB: This
        +	 * should normally set using DSO_set_merger(). */
        +	DSO_MERGER_FUNC merger;
        +	/* This is populated with (a copy of) the platform-independant
        +	 * filename used for this DSO. */
        +	char *filename;
        +	/* This is populated with (a copy of) the translated filename by which
        +	 * the DSO was actually loaded. It is NULL iff the DSO is not currently
        +	 * loaded. NB: This is here because the filename translation process
        +	 * may involve a callback being invoked more than once not only to
        +	 * convert to a platform-specific form, but also to try different
        +	 * filenames in the process of trying to perform a load. As such, this
        +	 * variable can be used to indicate (a) whether this DSO structure
        +	 * corresponds to a loaded library or not, and (b) the filename with
        +	 * which it was actually loaded. */
        +	char *loaded_filename;
        +	};
        +
        +
        +DSO *	DSO_new(void);
        +DSO *	DSO_new_method(DSO_METHOD *method);
        +int	DSO_free(DSO *dso);
        +int	DSO_flags(DSO *dso);
        +int	DSO_up_ref(DSO *dso);
        +long	DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
        +
        +/* This function sets the DSO's name_converter callback. If it is non-NULL,
        + * then it will be used instead of the associated DSO_METHOD's function. If
        + * oldcb is non-NULL then it is set to the function pointer value being
        + * replaced. Return value is non-zero for success. */
        +int	DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
        +				DSO_NAME_CONVERTER_FUNC *oldcb);
        +/* These functions can be used to get/set the platform-independant filename
        + * used for a DSO. NB: set will fail if the DSO is already loaded. */
        +const char *DSO_get_filename(DSO *dso);
        +int	DSO_set_filename(DSO *dso, const char *filename);
        +/* This function will invoke the DSO's name_converter callback to translate a
        + * filename, or if the callback isn't set it will instead use the DSO_METHOD's
        + * converter. If "filename" is NULL, the "filename" in the DSO itself will be
        + * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
        + * simply duplicated. NB: This function is usually called from within a
        + * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that
        + * caller-created DSO_METHODs can do the same thing. A non-NULL return value
        + * will need to be OPENSSL_free()'d. */
        +char	*DSO_convert_filename(DSO *dso, const char *filename);
        +/* This function will invoke the DSO's merger callback to merge two file
        + * specifications, or if the callback isn't set it will instead use the
        + * DSO_METHOD's merger.  A non-NULL return value will need to be
        + * OPENSSL_free()'d. */
        +char	*DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
        +/* If the DSO is currently loaded, this returns the filename that it was loaded
        + * under, otherwise it returns NULL. So it is also useful as a test as to
        + * whether the DSO is currently loaded. NB: This will not necessarily return
        + * the same value as DSO_convert_filename(dso, dso->filename), because the
        + * DSO_METHOD's load function may have tried a variety of filenames (with
        + * and/or without the aid of the converters) before settling on the one it
        + * actually loaded. */
        +const char *DSO_get_loaded_filename(DSO *dso);
        +
        +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. If 'dso' is non-NULL, 'flags' is ignored. */
        +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);
        +
        +/* This function writes null-terminated pathname of DSO module
        + * containing 'addr' into 'sz' large caller-provided 'path' and
        + * returns the number of characters [including trailing zero]
        + * written to it. If 'sz' is 0 or negative, 'path' is ignored and
        + * required amount of charachers [including trailing zero] to
        + * accomodate pathname is returned. If 'addr' is NULL, then
        + * pathname of cryptolib itself is returned. Negative or zero
        + * return value denotes error.
        + */
        +int DSO_pathbyaddr(void *addr,char *path,int sz);
        +
        +/* This function should be used with caution! It looks up symbols in
        + * *all* loaded modules and if module gets unloaded by somebody else
        + * attempt to dereference the pointer is doomed to have fatal
        + * consequences. Primary usage for this function is to probe *core*
        + * system functionality, e.g. check if getnameinfo(3) is available
        + * at run-time without bothering about OS-specific details such as
        + * libc.so.versioning or where does it actually reside: in libc
        + * itself or libsocket. */
        +void *DSO_global_lookup(const char *name);
        +
        +/* If BeOS is defined, use shared images. If not, return NULL. */
        +DSO_METHOD *DSO_METHOD_beos(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.
        + */
        +void ERR_load_DSO_strings(void);
        +
        +/* Error codes for the DSO functions. */
        +
        +/* Function codes. */
        +#define DSO_F_BEOS_BIND_FUNC				 144
        +#define DSO_F_BEOS_BIND_VAR				 145
        +#define DSO_F_BEOS_LOAD					 146
        +#define DSO_F_BEOS_NAME_CONVERTER			 147
        +#define DSO_F_BEOS_UNLOAD				 148
        +#define DSO_F_DLFCN_BIND_FUNC				 100
        +#define DSO_F_DLFCN_BIND_VAR				 101
        +#define DSO_F_DLFCN_LOAD				 102
        +#define DSO_F_DLFCN_MERGER				 130
        +#define DSO_F_DLFCN_NAME_CONVERTER			 123
        +#define DSO_F_DLFCN_UNLOAD				 103
        +#define DSO_F_DL_BIND_FUNC				 104
        +#define DSO_F_DL_BIND_VAR				 105
        +#define DSO_F_DL_LOAD					 106
        +#define DSO_F_DL_MERGER					 131
        +#define DSO_F_DL_NAME_CONVERTER				 124
        +#define DSO_F_DL_UNLOAD					 107
        +#define DSO_F_DSO_BIND_FUNC				 108
        +#define DSO_F_DSO_BIND_VAR				 109
        +#define DSO_F_DSO_CONVERT_FILENAME			 126
        +#define DSO_F_DSO_CTRL					 110
        +#define DSO_F_DSO_FREE					 111
        +#define DSO_F_DSO_GET_FILENAME				 127
        +#define DSO_F_DSO_GET_LOADED_FILENAME			 128
        +#define DSO_F_DSO_GLOBAL_LOOKUP				 139
        +#define DSO_F_DSO_LOAD					 112
        +#define DSO_F_DSO_MERGE					 132
        +#define DSO_F_DSO_NEW_METHOD				 113
        +#define DSO_F_DSO_PATHBYADDR				 140
        +#define DSO_F_DSO_SET_FILENAME				 129
        +#define DSO_F_DSO_SET_NAME_CONVERTER			 122
        +#define DSO_F_DSO_UP_REF				 114
        +#define DSO_F_GLOBAL_LOOKUP_FUNC			 138
        +#define DSO_F_PATHBYADDR				 137
        +#define DSO_F_VMS_BIND_SYM				 115
        +#define DSO_F_VMS_LOAD					 116
        +#define DSO_F_VMS_MERGER				 133
        +#define DSO_F_VMS_UNLOAD				 117
        +#define DSO_F_WIN32_BIND_FUNC				 118
        +#define DSO_F_WIN32_BIND_VAR				 119
        +#define DSO_F_WIN32_GLOBALLOOKUP			 142
        +#define DSO_F_WIN32_GLOBALLOOKUP_FUNC			 143
        +#define DSO_F_WIN32_JOINER				 135
        +#define DSO_F_WIN32_LOAD				 120
        +#define DSO_F_WIN32_MERGER				 134
        +#define DSO_F_WIN32_NAME_CONVERTER			 125
        +#define DSO_F_WIN32_PATHBYADDR				 141
        +#define DSO_F_WIN32_SPLITTER				 136
        +#define DSO_F_WIN32_UNLOAD				 121
        +
        +/* Reason codes. */
        +#define DSO_R_CTRL_FAILED				 100
        +#define DSO_R_DSO_ALREADY_LOADED			 110
        +#define DSO_R_EMPTY_FILE_STRUCTURE			 113
        +#define DSO_R_FAILURE					 114
        +#define DSO_R_FILENAME_TOO_BIG				 101
        +#define DSO_R_FINISH_FAILED				 102
        +#define DSO_R_INCORRECT_FILE_SYNTAX			 115
        +#define DSO_R_LOAD_FAILED				 103
        +#define DSO_R_NAME_TRANSLATION_FAILED			 109
        +#define DSO_R_NO_FILENAME				 111
        +#define DSO_R_NO_FILE_SPECIFICATION			 116
        +#define DSO_R_NULL_HANDLE				 104
        +#define DSO_R_SET_FILENAME_FAILED			 112
        +#define DSO_R_STACK_ERROR				 105
        +#define DSO_R_SYM_FAILURE				 106
        +#define DSO_R_UNLOAD_FAILED				 107
        +#define DSO_R_UNSUPPORTED				 108
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_beos.c b/vendor/openssl/openssl/crypto/dso/dso_beos.c
        new file mode 100644
        index 000000000..553966e69
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_beos.c
        @@ -0,0 +1,270 @@
        +/* dso_beos.c */
        +/* Written by Marcin Konicki (ahwayakchih@neoni.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 <stdio.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +#if !defined(OPENSSL_SYS_BEOS)
        +DSO_METHOD *DSO_METHOD_beos(void)
        +	{
        +	return NULL;
        +	}
        +#else
        +
        +#include <kernel/image.h>
        +
        +static int beos_load(DSO *dso);
        +static int beos_unload(DSO *dso);
        +static void *beos_bind_var(DSO *dso, const char *symname);
        +static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname);
        +#if 0
        +static int beos_unbind_var(DSO *dso, char *symname, void *symptr);
        +static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
        +static int beos_init(DSO *dso);
        +static int beos_finish(DSO *dso);
        +static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg);
        +#endif
        +static char *beos_name_converter(DSO *dso, const char *filename);
        +
        +static DSO_METHOD dso_meth_beos = {
        +	"OpenSSL 'beos' shared library method",
        +	beos_load,
        +	beos_unload,
        +	beos_bind_var,
        +	beos_bind_func,
        +/* For now, "unbind" doesn't exist */
        +#if 0
        +	NULL, /* unbind_var */
        +	NULL, /* unbind_func */
        +#endif
        +	NULL, /* ctrl */
        +	beos_name_converter,
        +	NULL, /* init */
        +	NULL  /* finish */
        +	};
        +
        +DSO_METHOD *DSO_METHOD_beos(void)
        +	{
        +	return(&dso_meth_beos);
        +	}
        +
        +/* For this DSO_METHOD, our meth_data STACK will contain;
        + * (i) a pointer to the handle (image_id) returned from
        + *     load_add_on().
        + */
        +
        +static int beos_load(DSO *dso)
        +	{
        +	image_id id;
        +	/* See applicable comments from dso_dl.c */
        +	char *filename = DSO_convert_filename(dso, NULL);
        +
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_BEOS_LOAD,DSO_R_NO_FILENAME);
        +		goto err;
        +		}
        +	id = load_add_on(filename);
        +	if(id < 1)
        +		{
        +		DSOerr(DSO_F_BEOS_LOAD,DSO_R_LOAD_FAILED);
        +		ERR_add_error_data(3, "filename(", filename, ")");
        +		goto err;
        +		}
        +	if(!sk_push(dso->meth_data, (char *)id))
        +		{
        +		DSOerr(DSO_F_BEOS_LOAD,DSO_R_STACK_ERROR);
        +		goto err;
        +		}
        +	/* Success */
        +	dso->loaded_filename = filename;
        +	return(1);
        +err:
        +	/* Cleanup !*/
        +	if(filename != NULL)
        +		OPENSSL_free(filename);
        +	if(id > 0)
        +		unload_add_on(id);
        +	return(0);
        +	}
        +
        +static int beos_unload(DSO *dso)
        +	{
        +	image_id id;
        +	if(dso == NULL)
        +		{
        +		DSOerr(DSO_F_BEOS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if(sk_num(dso->meth_data) < 1)
        +		return(1);
        +	id = (image_id)sk_pop(dso->meth_data);
        +	if(id < 1)
        +		{
        +		DSOerr(DSO_F_BEOS_UNLOAD,DSO_R_NULL_HANDLE);
        +		return(0);
        +		}
        +	if(unload_add_on(id) != B_OK)
        +		{
        +		DSOerr(DSO_F_BEOS_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 *)id);
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +static void *beos_bind_var(DSO *dso, const char *symname)
        +	{
        +	image_id id;
        +	void *sym;
        +
        +	if((dso == NULL) || (symname == NULL))
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if(sk_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_STACK_ERROR);
        +		return(NULL);
        +		}
        +	id = (image_id)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
        +	if(id < 1)
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_NULL_HANDLE);
        +		return(NULL);
        +		}
        +	if(get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK)
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_SYM_FAILURE);
        +		ERR_add_error_data(3, "symname(", symname, ")");
        +		return(NULL);
        +		}
        +	return(sym);
        +	}
        +
        +static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname)
        +	{
        +	image_id id;
        +	void *sym;
        +
        +	if((dso == NULL) || (symname == NULL))
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if(sk_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_STACK_ERROR);
        +		return(NULL);
        +		}
        +	id = (image_id)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
        +	if(id < 1)
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_NULL_HANDLE);
        +		return(NULL);
        +		}
        +	if(get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK)
        +		{
        +		DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_SYM_FAILURE);
        +		ERR_add_error_data(3, "symname(", symname, ")");
        +		return(NULL);
        +		}
        +	return((DSO_FUNC_TYPE)sym);
        +	}
        +
        +/* This one is the same as the one in dlfcn */
        +static char *beos_name_converter(DSO *dso, const char *filename)
        +	{
        +	char *translated;
        +	int len, rsize, transform;
        +
        +	len = strlen(filename);
        +	rsize = len + 1;
        +	transform = (strstr(filename, "/") == NULL);
        +	if(transform)
        +		{
        +		/* We will convert this to "%s.so" or "lib%s.so" */
        +		rsize += 3;	/* The length of ".so" */
        +		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
        +			rsize += 3; /* The length of "lib" */
        +		}
        +	translated = OPENSSL_malloc(rsize);
        +	if(translated == NULL)
        +		{
        +		DSOerr(DSO_F_BEOS_NAME_CONVERTER,
        +				DSO_R_NAME_TRANSLATION_FAILED);
        +		return(NULL);
        +		}
        +	if(transform)
        +		{
        +		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
        +			sprintf(translated, "lib%s.so", filename);
        +		else
        +			sprintf(translated, "%s.so", filename);
        +		}
        +	else
        +		sprintf(translated, "%s", filename);
        +	return(translated);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_dl.c b/vendor/openssl/openssl/crypto/dso/dso_dl.c
        new file mode 100644
        index 000000000..fc4236bd9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_dl.c
        @@ -0,0 +1,393 @@
        +/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +#ifndef DSO_DL
        +DSO_METHOD *DSO_METHOD_dl(void)
        +       {
        +       return NULL;
        +       }
        +#else
        +
        +#include <dl.h>
        +
        +/* Part of the hack in "dl_load" ... */
        +#define DSO_MAX_TRANSLATED_SIZE 256
        +
        +static int dl_load(DSO *dso);
        +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);
        +static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
        +#endif
        +static char *dl_name_converter(DSO *dso, const char *filename);
        +static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
        +static int dl_pathbyaddr(void *addr,char *path,int sz);
        +static void *dl_globallookup(const char *name);
        +
        +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
        +	NULL, /* ctrl */
        +	dl_name_converter,
        +	dl_merger,
        +	NULL, /* init */
        +	NULL, /* finish */
        +	dl_pathbyaddr,
        +	dl_globallookup
        +	};
        +
        +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)
        +	{
        +	shl_t ptr = NULL;
        +	/* We don't do any fancy retries or anything, just take the method's
        +	 * (or DSO's if it has the callback set) best translation of the
        +	 * platform-independant filename and try once with that. */
        +	char *filename= DSO_convert_filename(dso, NULL);
        +
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_DL_LOAD,DSO_R_NO_FILENAME);
        +		goto err;
        +		}
        +	ptr = shl_load(filename, BIND_IMMEDIATE |
        +		(dso->flags&DSO_FLAG_NO_NAME_TRANSLATION?0:DYNAMIC_PATH), 0L);
        +	if(ptr == NULL)
        +		{
        +		DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
        +		ERR_add_error_data(4, "filename(", filename, "): ",
        +			strerror(errno));
        +		goto err;
        +		}
        +	if(!sk_push(dso->meth_data, (char *)ptr))
        +		{
        +		DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR);
        +		goto err;
        +		}
        +	/* Success, stick the converted filename we've loaded under into the DSO
        +	 * (it also serves as the indicator that we are currently loaded). */
        +	dso->loaded_filename = filename;
        +	return(1);
        +err:
        +	/* Cleanup! */
        +	if(filename != NULL)
        +		OPENSSL_free(filename);
        +	if(ptr != NULL)
        +		shl_unload(ptr);
        +	return(0);
        +	}
        +
        +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);
        +		ERR_add_error_data(4, "symname(", symname, "): ",
        +			strerror(errno));
        +		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);
        +		ERR_add_error_data(4, "symname(", symname, "): ",
        +			strerror(errno));
        +		return(NULL);
        +		}
        +	return((DSO_FUNC_TYPE)sym);
        +	}
        +
        +static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
        +	{
        +	char *merged;
        +
        +	if(!filespec1 && !filespec2)
        +		{
        +		DSOerr(DSO_F_DL_MERGER,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	/* If the first file specification is a rooted path, it rules.
        +	   same goes if the second file specification is missing. */
        +	if (!filespec2 || filespec1[0] == '/')
        +		{
        +		merged = OPENSSL_malloc(strlen(filespec1) + 1);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_DL_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec1);
        +		}
        +	/* If the first file specification is missing, the second one rules. */
        +	else if (!filespec1)
        +		{
        +		merged = OPENSSL_malloc(strlen(filespec2) + 1);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_DL_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec2);
        +		}
        +	else
        +		/* This part isn't as trivial as it looks.  It assumes that
        +		   the second file specification really is a directory, and
        +		   makes no checks whatsoever.  Therefore, the result becomes
        +		   the concatenation of filespec2 followed by a slash followed
        +		   by filespec1. */
        +		{
        +		int spec2len, len;
        +
        +		spec2len = (filespec2 ? strlen(filespec2) : 0);
        +		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
        +
        +		if(filespec2 && filespec2[spec2len - 1] == '/')
        +			{
        +			spec2len--;
        +			len--;
        +			}
        +		merged = OPENSSL_malloc(len + 2);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_DL_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec2);
        +		merged[spec2len] = '/';
        +		strcpy(&merged[spec2len + 1], filespec1);
        +		}
        +	return(merged);
        +	}
        +
        +/* This function is identical to the one in dso_dlfcn.c, but as it is highly
        + * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
        + * same time, there's no great duplicating the code. Figuring out an elegant 
        + * way to share one copy of the code would be more difficult and would not
        + * leave the implementations independant. */
        +#if defined(__hpux)
        +static const char extension[] = ".sl";
        +#else
        +static const char extension[] = ".so";
        +#endif
        +static char *dl_name_converter(DSO *dso, const char *filename)
        +	{
        +	char *translated;
        +	int len, rsize, transform;
        +
        +	len = strlen(filename);
        +	rsize = len + 1;
        +	transform = (strstr(filename, "/") == NULL);
        +		{
        +		/* We will convert this to "%s.s?" or "lib%s.s?" */
        +		rsize += strlen(extension);/* The length of ".s?" */
        +		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
        +			rsize += 3; /* The length of "lib" */
        +		}
        +	translated = OPENSSL_malloc(rsize);
        +	if(translated == NULL)
        +		{
        +		DSOerr(DSO_F_DL_NAME_CONVERTER,
        +				DSO_R_NAME_TRANSLATION_FAILED); 
        +		return(NULL);   
        +		}
        +	if(transform)
        +		{
        +		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
        +			sprintf(translated, "lib%s%s", filename, extension);
        +		else
        +			sprintf(translated, "%s%s", filename, extension);
        +		}
        +	else
        +		sprintf(translated, "%s", filename);
        +	return(translated);
        +	}
        +
        +static int dl_pathbyaddr(void *addr,char *path,int sz)
        +	{
        +	struct shl_descriptor inf;
        +	int i,len;
        +
        +	if (addr == NULL)
        +		{
        +		union	{ int(*f)(void*,char*,int); void *p; } t =
        +			{ dl_pathbyaddr };
        +		addr = t.p;
        +		}
        +
        +	for (i=-1;shl_get_r(i,&inf)==0;i++)
        +		{
        +		if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
        +		    ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
        +			{
        +			len = (int)strlen(inf.filename);
        +			if (sz <= 0) return len+1;
        +			if (len >= sz) len=sz-1;
        +			memcpy(path,inf.filename,len);
        +			path[len++] = 0;
        +			return len;
        +			}
        +		}
        +
        +	return -1;
        +	}
        +
        +static void *dl_globallookup(const char *name)
        +	{
        +	void *ret;
        +	shl_t h = NULL;
        +
        +	return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
        +	}
        +#endif /* DSO_DL */
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_dlfcn.c b/vendor/openssl/openssl/crypto/dso/dso_dlfcn.c
        new file mode 100644
        index 000000000..5f2254806
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_dlfcn.c
        @@ -0,0 +1,484 @@
        +/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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).
        + *
        + */
        +
        +/* We need to do this early, because stdio.h includes the header files
        +   that handle _GNU_SOURCE and other similar macros.  Defining it later
        +   is simply too late, because those headers are protected from re-
        +   inclusion.  */
        +#ifdef __linux
        +# ifndef _GNU_SOURCE
        +#  define _GNU_SOURCE	/* make sure dladdr is declared */
        +# endif
        +#endif
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +#ifndef DSO_DLFCN
        +DSO_METHOD *DSO_METHOD_dlfcn(void)
        +	{
        +	return NULL;
        +	}
        +#else
        +
        +#ifdef HAVE_DLFCN_H
        +# ifdef __osf__
        +#  define __EXTENSIONS__
        +# endif
        +# include <dlfcn.h>
        +# define HAVE_DLINFO 1
        +# if defined(_AIX) || defined(__CYGWIN__) || \
        +     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
        +     (defined(__osf__) && !defined(RTLD_NEXT))     || \
        +     (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
        +	defined(__ANDROID__)
        +#  undef HAVE_DLINFO
        +# endif
        +#endif
        +
        +/* Part of the hack in "dlfcn_load" ... */
        +#define DSO_MAX_TRANSLATED_SIZE 256
        +
        +static int dlfcn_load(DSO *dso);
        +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);
        +static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
        +#endif
        +static char *dlfcn_name_converter(DSO *dso, const char *filename);
        +static char *dlfcn_merger(DSO *dso, const char *filespec1,
        +	const char *filespec2);
        +static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
        +static void *dlfcn_globallookup(const char *name);
        +
        +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
        +	NULL, /* ctrl */
        +	dlfcn_name_converter,
        +	dlfcn_merger,
        +	NULL, /* init */
        +	NULL, /* finish */
        +	dlfcn_pathbyaddr,
        +	dlfcn_globallookup
        +	};
        +
        +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. */
        +#if defined(__OpenBSD__) || defined(__NetBSD__)
        +#	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
        +#	ifdef OPENSSL_SYS_SUNOS
        +#		define DLOPEN_FLAG 1
        +#	else
        +#		define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
        +#	endif
        +#endif
        +
        +/* For this DSO_METHOD, our meth_data STACK will contain;
        + * (i) the handle (void*) returned from dlopen().
        + */
        +
        +static int dlfcn_load(DSO *dso)
        +	{
        +	void *ptr = NULL;
        +	/* See applicable comments in dso_dl.c */
        +	char *filename = DSO_convert_filename(dso, NULL);
        +	int flags = DLOPEN_FLAG;
        +
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
        +		goto err;
        +		}
        +
        +#ifdef RTLD_GLOBAL
        +	if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
        +		flags |= RTLD_GLOBAL;
        +#endif
        +	ptr = dlopen(filename, flags);
        +	if(ptr == NULL)
        +		{
        +		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
        +		ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
        +		goto err;
        +		}
        +	if(!sk_void_push(dso->meth_data, (char *)ptr))
        +		{
        +		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
        +		goto err;
        +		}
        +	/* Success */
        +	dso->loaded_filename = filename;
        +	return(1);
        +err:
        +	/* Cleanup! */
        +	if(filename != NULL)
        +		OPENSSL_free(filename);
        +	if(ptr != NULL)
        +		dlclose(ptr);
        +	return(0);
        +}
        +
        +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_void_num(dso->meth_data) < 1)
        +		return(1);
        +	ptr = sk_void_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_void_push(dso->meth_data, 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_void_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
        +		return(NULL);
        +		}
        +	ptr = sk_void_value(dso->meth_data, sk_void_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);
        +		ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
        +		return(NULL);
        +		}
        +	return(sym);
        +	}
        +
        +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
        +	{
        +	void *ptr;
        +	union {
        +		DSO_FUNC_TYPE sym;
        +		void *dlret;
        +	} u;
        +
        +	if((dso == NULL) || (symname == NULL))
        +		{
        +		DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if(sk_void_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
        +		return(NULL);
        +		}
        +	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
        +	if(ptr == NULL)
        +		{
        +		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
        +		return(NULL);
        +		}
        +	u.dlret = dlsym(ptr, symname);
        +	if(u.dlret == NULL)
        +		{
        +		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
        +		ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
        +		return(NULL);
        +		}
        +	return u.sym;
        +	}
        +
        +static char *dlfcn_merger(DSO *dso, const char *filespec1,
        +	const char *filespec2)
        +	{
        +	char *merged;
        +
        +	if(!filespec1 && !filespec2)
        +		{
        +		DSOerr(DSO_F_DLFCN_MERGER,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	/* If the first file specification is a rooted path, it rules.
        +	   same goes if the second file specification is missing. */
        +	if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
        +		{
        +		merged = OPENSSL_malloc(strlen(filespec1) + 1);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec1);
        +		}
        +	/* If the first file specification is missing, the second one rules. */
        +	else if (!filespec1)
        +		{
        +		merged = OPENSSL_malloc(strlen(filespec2) + 1);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_DLFCN_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec2);
        +		}
        +	else
        +		/* This part isn't as trivial as it looks.  It assumes that
        +		   the second file specification really is a directory, and
        +		   makes no checks whatsoever.  Therefore, the result becomes
        +		   the concatenation of filespec2 followed by a slash followed
        +		   by filespec1. */
        +		{
        +		int spec2len, len;
        +
        +		spec2len = strlen(filespec2);
        +		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
        +
        +		if(filespec2 && filespec2[spec2len - 1] == '/')
        +			{
        +			spec2len--;
        +			len--;
        +			}
        +		merged = OPENSSL_malloc(len + 2);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_DLFCN_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec2);
        +		merged[spec2len] = '/';
        +		strcpy(&merged[spec2len + 1], filespec1);
        +		}
        +	return(merged);
        +	}
        +
        +#ifdef OPENSSL_SYS_MACOSX
        +#define DSO_ext	".dylib"
        +#define DSO_extlen 6
        +#else
        +#define DSO_ext	".so"
        +#define DSO_extlen 3
        +#endif
        +
        +
        +static char *dlfcn_name_converter(DSO *dso, const char *filename)
        +	{
        +	char *translated;
        +	int len, rsize, transform;
        +
        +	len = strlen(filename);
        +	rsize = len + 1;
        +	transform = (strstr(filename, "/") == NULL);
        +	if(transform)
        +		{
        +		/* We will convert this to "%s.so" or "lib%s.so" etc */
        +		rsize += DSO_extlen;	/* The length of ".so" */
        +		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
        +			rsize += 3; /* The length of "lib" */
        +		}
        +	translated = OPENSSL_malloc(rsize);
        +	if(translated == NULL)
        +		{
        +		DSOerr(DSO_F_DLFCN_NAME_CONVERTER,
        +				DSO_R_NAME_TRANSLATION_FAILED);
        +		return(NULL);
        +		}
        +	if(transform)
        +		{
        +		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
        +			sprintf(translated, "lib%s" DSO_ext, filename);
        +		else
        +			sprintf(translated, "%s" DSO_ext, filename);
        +		}
        +	else
        +		sprintf(translated, "%s", filename);
        +	return(translated);
        +	}
        +
        +#ifdef __sgi
        +/*
        +This is a quote from IRIX manual for dladdr(3c):
        +
        +     <dlfcn.h> does not contain a prototype for dladdr or definition of
        +     Dl_info.  The #include <dlfcn.h>  in the SYNOPSIS line is traditional,
        +     but contains no dladdr prototype and no IRIX library contains an
        +     implementation.  Write your own declaration based on the code below.
        +
        +     The following code is dependent on internal interfaces that are not
        +     part of the IRIX compatibility guarantee; however, there is no future
        +     intention to change this interface, so on a practical level, the code
        +     below is safe to use on IRIX.
        +*/
        +#include <rld_interface.h>
        +#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
        +#define _RLD_INTERFACE_DLFCN_H_DLADDR
        +typedef struct Dl_info {
        +    const char * dli_fname;
        +    void       * dli_fbase;
        +    const char * dli_sname;
        +    void       * dli_saddr;
        +    int          dli_version;
        +    int          dli_reserved1;
        +    long         dli_reserved[4];
        +} Dl_info;
        +#else
        +typedef struct Dl_info Dl_info;
        +#endif
        +#define _RLD_DLADDR             14
        +
        +static int dladdr(void *address, Dl_info *dl)
        +{
        +	void *v;
        +	v = _rld_new_interface(_RLD_DLADDR,address,dl);
        +	return (int)v;
        +}
        +#endif /* __sgi */
        +
        +static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
        +	{
        +#ifdef HAVE_DLINFO
        +	Dl_info dli;
        +	int len;
        +
        +	if (addr == NULL)
        +		{
        +		union	{ int(*f)(void*,char*,int); void *p; } t =
        +			{ dlfcn_pathbyaddr };
        +		addr = t.p;
        +		}
        +
        +	if (dladdr(addr,&dli))
        +		{
        +		len = (int)strlen(dli.dli_fname);
        +		if (sz <= 0) return len+1;
        +		if (len >= sz) len=sz-1;
        +		memcpy(path,dli.dli_fname,len);
        +		path[len++]=0;
        +		return len;
        +		}
        +
        +	ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
        +#endif
        +	return -1;
        +	}
        +
        +static void *dlfcn_globallookup(const char *name)
        +	{
        +	void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
        +	
        +	if (handle)
        +		{
        +		ret = dlsym(handle,name);
        +		dlclose(handle);
        +		}
        +
        +	return ret;
        +	}
        +#endif /* DSO_DLFCN */
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_err.c b/vendor/openssl/openssl/crypto/dso/dso_err.c
        new file mode 100644
        index 000000000..2bb07c251
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_err.c
        @@ -0,0 +1,159 @@
        +/* crypto/dso/dso_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/dso.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
        +
        +static ERR_STRING_DATA DSO_str_functs[]=
        +	{
        +{ERR_FUNC(DSO_F_BEOS_BIND_FUNC),	"BEOS_BIND_FUNC"},
        +{ERR_FUNC(DSO_F_BEOS_BIND_VAR),	"BEOS_BIND_VAR"},
        +{ERR_FUNC(DSO_F_BEOS_LOAD),	"BEOS_LOAD"},
        +{ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER),	"BEOS_NAME_CONVERTER"},
        +{ERR_FUNC(DSO_F_BEOS_UNLOAD),	"BEOS_UNLOAD"},
        +{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC),	"DLFCN_BIND_FUNC"},
        +{ERR_FUNC(DSO_F_DLFCN_BIND_VAR),	"DLFCN_BIND_VAR"},
        +{ERR_FUNC(DSO_F_DLFCN_LOAD),	"DLFCN_LOAD"},
        +{ERR_FUNC(DSO_F_DLFCN_MERGER),	"DLFCN_MERGER"},
        +{ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER),	"DLFCN_NAME_CONVERTER"},
        +{ERR_FUNC(DSO_F_DLFCN_UNLOAD),	"DLFCN_UNLOAD"},
        +{ERR_FUNC(DSO_F_DL_BIND_FUNC),	"DL_BIND_FUNC"},
        +{ERR_FUNC(DSO_F_DL_BIND_VAR),	"DL_BIND_VAR"},
        +{ERR_FUNC(DSO_F_DL_LOAD),	"DL_LOAD"},
        +{ERR_FUNC(DSO_F_DL_MERGER),	"DL_MERGER"},
        +{ERR_FUNC(DSO_F_DL_NAME_CONVERTER),	"DL_NAME_CONVERTER"},
        +{ERR_FUNC(DSO_F_DL_UNLOAD),	"DL_UNLOAD"},
        +{ERR_FUNC(DSO_F_DSO_BIND_FUNC),	"DSO_bind_func"},
        +{ERR_FUNC(DSO_F_DSO_BIND_VAR),	"DSO_bind_var"},
        +{ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME),	"DSO_convert_filename"},
        +{ERR_FUNC(DSO_F_DSO_CTRL),	"DSO_ctrl"},
        +{ERR_FUNC(DSO_F_DSO_FREE),	"DSO_free"},
        +{ERR_FUNC(DSO_F_DSO_GET_FILENAME),	"DSO_get_filename"},
        +{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME),	"DSO_get_loaded_filename"},
        +{ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP),	"DSO_global_lookup"},
        +{ERR_FUNC(DSO_F_DSO_LOAD),	"DSO_load"},
        +{ERR_FUNC(DSO_F_DSO_MERGE),	"DSO_merge"},
        +{ERR_FUNC(DSO_F_DSO_NEW_METHOD),	"DSO_new_method"},
        +{ERR_FUNC(DSO_F_DSO_PATHBYADDR),	"DSO_pathbyaddr"},
        +{ERR_FUNC(DSO_F_DSO_SET_FILENAME),	"DSO_set_filename"},
        +{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER),	"DSO_set_name_converter"},
        +{ERR_FUNC(DSO_F_DSO_UP_REF),	"DSO_up_ref"},
        +{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC),	"GLOBAL_LOOKUP_FUNC"},
        +{ERR_FUNC(DSO_F_PATHBYADDR),	"PATHBYADDR"},
        +{ERR_FUNC(DSO_F_VMS_BIND_SYM),	"VMS_BIND_SYM"},
        +{ERR_FUNC(DSO_F_VMS_LOAD),	"VMS_LOAD"},
        +{ERR_FUNC(DSO_F_VMS_MERGER),	"VMS_MERGER"},
        +{ERR_FUNC(DSO_F_VMS_UNLOAD),	"VMS_UNLOAD"},
        +{ERR_FUNC(DSO_F_WIN32_BIND_FUNC),	"WIN32_BIND_FUNC"},
        +{ERR_FUNC(DSO_F_WIN32_BIND_VAR),	"WIN32_BIND_VAR"},
        +{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP),	"WIN32_GLOBALLOOKUP"},
        +{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC),	"WIN32_GLOBALLOOKUP_FUNC"},
        +{ERR_FUNC(DSO_F_WIN32_JOINER),	"WIN32_JOINER"},
        +{ERR_FUNC(DSO_F_WIN32_LOAD),	"WIN32_LOAD"},
        +{ERR_FUNC(DSO_F_WIN32_MERGER),	"WIN32_MERGER"},
        +{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER),	"WIN32_NAME_CONVERTER"},
        +{ERR_FUNC(DSO_F_WIN32_PATHBYADDR),	"WIN32_PATHBYADDR"},
        +{ERR_FUNC(DSO_F_WIN32_SPLITTER),	"WIN32_SPLITTER"},
        +{ERR_FUNC(DSO_F_WIN32_UNLOAD),	"WIN32_UNLOAD"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA DSO_str_reasons[]=
        +	{
        +{ERR_REASON(DSO_R_CTRL_FAILED)           ,"control command failed"},
        +{ERR_REASON(DSO_R_DSO_ALREADY_LOADED)    ,"dso already loaded"},
        +{ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE)  ,"empty file structure"},
        +{ERR_REASON(DSO_R_FAILURE)               ,"failure"},
        +{ERR_REASON(DSO_R_FILENAME_TOO_BIG)      ,"filename too big"},
        +{ERR_REASON(DSO_R_FINISH_FAILED)         ,"cleanup method function failed"},
        +{ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX) ,"incorrect file syntax"},
        +{ERR_REASON(DSO_R_LOAD_FAILED)           ,"could not load the shared library"},
        +{ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED),"name translation failed"},
        +{ERR_REASON(DSO_R_NO_FILENAME)           ,"no filename"},
        +{ERR_REASON(DSO_R_NO_FILE_SPECIFICATION) ,"no file specification"},
        +{ERR_REASON(DSO_R_NULL_HANDLE)           ,"a null shared library handle was used"},
        +{ERR_REASON(DSO_R_SET_FILENAME_FAILED)   ,"set filename failed"},
        +{ERR_REASON(DSO_R_STACK_ERROR)           ,"the meth_data stack is corrupt"},
        +{ERR_REASON(DSO_R_SYM_FAILURE)           ,"could not bind to the requested symbol name"},
        +{ERR_REASON(DSO_R_UNLOAD_FAILED)         ,"could not unload the shared library"},
        +{ERR_REASON(DSO_R_UNSUPPORTED)           ,"functionality not supported"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_DSO_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(DSO_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,DSO_str_functs);
        +		ERR_load_strings(0,DSO_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_lib.c b/vendor/openssl/openssl/crypto/dso/dso_lib.c
        new file mode 100644
        index 000000000..8a15b794a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_lib.c
        @@ -0,0 +1,483 @@
        +/* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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 <stdio.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +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_void_new_null();
        +	if(ret->meth_data == 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_void_free(dso->meth_data);
        +	if(dso->filename != NULL)
        +		OPENSSL_free(dso->filename);
        +	if(dso->loaded_filename != NULL)
        +		OPENSSL_free(dso->loaded_filename);
        + 
        +	OPENSSL_free(dso);
        +	return(1);
        +	}
        +
        +int DSO_flags(DSO *dso)
        +	{
        +	return((dso == NULL) ? 0 : dso->flags);
        +	}
        +
        +
        +int DSO_up_ref(DSO *dso)
        +	{
        +	if (dso == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_UP_REF,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(dso == NULL)
        +		{
        +		ret = DSO_new_method(meth);
        +		if(ret == NULL)
        +			{
        +			DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		allocated = 1;
        +		/* Pass the provided flags to the new DSO object */
        +		if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
        +			{
        +			DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
        +			goto err;
        +			}
        +		}
        +	else
        +		ret = dso;
        +	/* Don't load if we're currently already loaded */
        +	if(ret->filename != NULL)
        +		{
        +		DSOerr(DSO_F_DSO_LOAD,DSO_R_DSO_ALREADY_LOADED);
        +		goto err;
        +		}
        +	/* filename can only be NULL if we were passed a dso that already has
        +	 * one set. */
        +	if(filename != NULL)
        +		if(!DSO_set_filename(ret, filename))
        +			{
        +			DSOerr(DSO_F_DSO_LOAD,DSO_R_SET_FILENAME_FAILED);
        +			goto err;
        +			}
        +	filename = ret->filename;
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_LOAD,DSO_R_NO_FILENAME);
        +		goto err;
        +		}
        +	if(ret->meth->dso_load == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
        +		goto err;
        +		}
        +	if(!ret->meth->dso_load(ret))
        +		{
        +		DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
        +		goto err;
        +		}
        +	/* Load succeeded */
        +	return(ret);
        +err:
        +	if(allocated)
        +		DSO_free(ret);
        +	return(NULL);
        +	}
        +
        +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);
        +		}
        +	/* We should intercept certain generic commands and only pass control
        +	 * to the method-specific ctrl() function if it's something we don't
        +	 * handle. */
        +	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;
        +		}
        +	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));
        +	}
        +
        +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
        +			DSO_NAME_CONVERTER_FUNC *oldcb)
        +	{
        +	if(dso == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if(oldcb)
        +		*oldcb = dso->name_converter;
        +	dso->name_converter = cb;
        +	return(1);
        +	}
        +
        +const char *DSO_get_filename(DSO *dso)
        +	{
        +	if(dso == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_GET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	return(dso->filename);
        +	}
        +
        +int DSO_set_filename(DSO *dso, const char *filename)
        +	{
        +	char *copied;
        +
        +	if((dso == NULL) || (filename == NULL))
        +		{
        +		DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if(dso->loaded_filename)
        +		{
        +		DSOerr(DSO_F_DSO_SET_FILENAME,DSO_R_DSO_ALREADY_LOADED);
        +		return(0);
        +		}
        +	/* We'll duplicate filename */
        +	copied = OPENSSL_malloc(strlen(filename) + 1);
        +	if(copied == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	BUF_strlcpy(copied, filename, strlen(filename) + 1);
        +	if(dso->filename)
        +		OPENSSL_free(dso->filename);
        +	dso->filename = copied;
        +	return(1);
        +	}
        +
        +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
        +	{
        +	char *result = NULL;
        +
        +	if(dso == NULL || filespec1 == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
        +		{
        +		if(dso->merger != NULL)
        +			result = dso->merger(dso, filespec1, filespec2);
        +		else if(dso->meth->dso_merger != NULL)
        +			result = dso->meth->dso_merger(dso,
        +				filespec1, filespec2);
        +		}
        +	return(result);
        +	}
        +
        +char *DSO_convert_filename(DSO *dso, const char *filename)
        +	{
        +	char *result = NULL;
        +
        +	if(dso == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_CONVERT_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if(filename == NULL)
        +		filename = dso->filename;
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
        +		return(NULL);
        +		}
        +	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
        +		{
        +		if(dso->name_converter != NULL)
        +			result = dso->name_converter(dso, filename);
        +		else if(dso->meth->dso_name_converter != NULL)
        +			result = dso->meth->dso_name_converter(dso, filename);
        +		}
        +	if(result == NULL)
        +		{
        +		result = OPENSSL_malloc(strlen(filename) + 1);
        +		if(result == NULL)
        +			{
        +			DSOerr(DSO_F_DSO_CONVERT_FILENAME,
        +					ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		BUF_strlcpy(result, filename, strlen(filename) + 1);
        +		}
        +	return(result);
        +	}
        +
        +const char *DSO_get_loaded_filename(DSO *dso)
        +	{
        +	if(dso == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	return(dso->loaded_filename);
        +	}
        +
        +int DSO_pathbyaddr(void *addr,char *path,int sz)
        +	{
        +	DSO_METHOD *meth = default_DSO_meth;
        +	if (meth == NULL) meth = DSO_METHOD_openssl();
        +	if (meth->pathbyaddr == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_PATHBYADDR,DSO_R_UNSUPPORTED);
        +		return -1;
        +		}
        +	return (*meth->pathbyaddr)(addr,path,sz);
        +	}
        +
        +void *DSO_global_lookup(const char *name)
        +	{
        +	DSO_METHOD *meth = default_DSO_meth;
        +	if (meth == NULL) meth = DSO_METHOD_openssl();
        +	if (meth->globallookup == NULL)
        +		{
        +		DSOerr(DSO_F_DSO_GLOBAL_LOOKUP,DSO_R_UNSUPPORTED);
        +		return NULL;
        +		}
        +	return (*meth->globallookup)(name);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_null.c b/vendor/openssl/openssl/crypto/dso/dso_null.c
        new file mode 100644
        index 000000000..49d842d1f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_null.c
        @@ -0,0 +1,90 @@
        +/* 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +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, /* dso_name_converter */
        +	NULL, /* dso_merger */
        +	NULL, /* init */
        +	NULL, /* finish */
        +	NULL, /* pathbyaddr */
        +	NULL  /* globallookup */
        +	};
        +
        +DSO_METHOD *DSO_METHOD_null(void)
        +	{
        +	return(&dso_meth_null);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_openssl.c b/vendor/openssl/openssl/crypto/dso/dso_openssl.c
        new file mode 100644
        index 000000000..b17e8e8e9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_openssl.c
        @@ -0,0 +1,83 @@
        +/* 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +/* 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());
        +#elif defined(DSO_BEOS)
        +	return(DSO_METHOD_beos());
        +#else
        +	return(DSO_METHOD_null());
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_vms.c b/vendor/openssl/openssl/crypto/dso/dso_vms.c
        new file mode 100644
        index 000000000..eee20d14f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_vms.c
        @@ -0,0 +1,525 @@
        +/* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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 <stdio.h>
        +#include <string.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +#ifdef OPENSSL_SYS_VMS
        +#pragma message disable DOLLARID
        +#include <rms.h>
        +#include <lib$routines.h>
        +#include <stsdef.h>
        +#include <descrip.h>
        +#include <starlet.h>
        +#include "vms_rms.h"
        +#endif
        +
        +/* Some compiler options may mask the declaration of "_malloc32". */
        +#if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
        +# if __INITIAL_POINTER_SIZE == 64
        +#  pragma pointer_size save
        +#  pragma pointer_size 32
        +    void * _malloc32  (__size_t);
        +#  pragma pointer_size restore
        +# endif /* __INITIAL_POINTER_SIZE == 64 */
        +#endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */
        +
        +
        +#ifndef OPENSSL_SYS_VMS
        +DSO_METHOD *DSO_METHOD_vms(void)
        +	{
        +	return NULL;
        +	}
        +#else
        +#pragma message disable DOLLARID
        +
        +static int vms_load(DSO *dso);
        +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);
        +static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
        +#endif
        +static char *vms_name_converter(DSO *dso, const char *filename);
        +static char *vms_merger(DSO *dso, const char *filespec1,
        +	const char *filespec2);
        +
        +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
        +	NULL, /* ctrl */
        +	vms_name_converter,
        +	vms_merger,
        +	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[ NAMX_MAXRSS+ 1];
        +	/* This contains whatever is not in filename, if needed.
        +	 * Normally not defined. */
        +	struct dsc$descriptor_s imagename_dsc;
        +	char imagename[ NAMX_MAXRSS+ 1];
        +	} DSO_VMS_INTERNAL;
        +
        +DSO_METHOD *DSO_METHOD_vms(void)
        +	{
        +	return(&dso_meth_vms);
        +	}
        +
        +static int vms_load(DSO *dso)
        +	{
        +	void *ptr = NULL;
        +	/* See applicable comments in dso_dl.c */
        +	char *filename = DSO_convert_filename(dso, NULL);
        +
        +/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
        +#if __INITIAL_POINTER_SIZE == 64
        +# define DSO_MALLOC _malloc32
        +# pragma pointer_size save
        +# pragma pointer_size 32
        +#else /* __INITIAL_POINTER_SIZE == 64 */
        +# define DSO_MALLOC OPENSSL_malloc
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +	DSO_VMS_INTERNAL *p = NULL;
        +
        +#if __INITIAL_POINTER_SIZE == 64
        +# pragma pointer_size restore
        +#endif /* __INITIAL_POINTER_SIZE == 64 */
        +
        +	const char *sp1, *sp2;	/* Search result */
        +
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME);
        +		goto err;
        +		}
        +
        +	/* A file specification may look like this:
        +	 *
        +	 *	node::dev:[dir-spec]name.type;ver
        +	 *
        +	 * or (for compatibility with TOPS-20):
        +	 *
        +	 *	node::dev:<dir-spec>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.]<dir2>
        +	 *
        +	 * 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);
        +		goto err;
        +		}
        +
        +	p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL));
        +	if(p == NULL)
        +		{
        +		DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	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_void_push(dso->meth_data, (char *)p))
        +		{
        +		DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR);
        +		goto err;
        +		}
        +
        +	/* Success (for now, we lie.  We actually do not know...) */
        +	dso->loaded_filename = filename;
        +	return(1);
        +err:
        +	/* Cleanup! */
        +	if(p != NULL)
        +		OPENSSL_free(p);
        +	if(filename != NULL)
        +		OPENSSL_free(filename);
        +	return(0);
        +	}
        +
        +/* 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_void_num(dso->meth_data) < 1)
        +		return(1);
        +	p = (DSO_VMS_INTERNAL *)sk_void_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;
        +#if 0
        +	int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't
        +                               defined in VMS older than 7.0 or so */
        +#else
        +	int flags = 0;
        +#endif
        +	struct dsc$descriptor_s symname_dsc;
        +
        +/* Arrange 32-bit pointer to (copied) string storage, if needed. */
        +#if __INITIAL_POINTER_SIZE == 64
        +# define SYMNAME symname_32p
        +# pragma pointer_size save
        +# pragma pointer_size 32
        +	char *symname_32p;
        +# pragma pointer_size restore
        +	char symname_32[ NAMX_MAXRSS+ 1];
        +#else /* __INITIAL_POINTER_SIZE == 64 */
        +# define SYMNAME ((char *) symname)
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +	*sym = NULL;
        +
        +	if((dso == NULL) || (symname == NULL))
        +		{
        +		DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
        +		return;
        +		}
        +
        +#if __INITIAL_POINTER_SIZE == 64
        +	/* Copy the symbol name to storage with a 32-bit pointer. */
        +	symname_32p = symname_32;
        +	strcpy( symname_32p, symname);
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +	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 = SYMNAME;
        +
        +	if(sk_void_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
        +		return;
        +		}
        +	ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
        +		sk_void_num(dso->meth_data) - 1);
        +	if(ptr == NULL)
        +		{
        +		DSOerr(DSO_F_VMS_BIND_SYM,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_SYM,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 char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2)
        +	{
        +	int status;
        +	int filespec1len, filespec2len;
        +	struct FAB fab;
        +	struct NAMX_STRUCT nam;
        +	char esa[ NAMX_MAXRSS+ 1];
        +	char *merged;
        +
        +/* Arrange 32-bit pointer to (copied) string storage, if needed. */
        +#if __INITIAL_POINTER_SIZE == 64
        +# define FILESPEC1 filespec1_32p;
        +# define FILESPEC2 filespec2_32p;
        +# pragma pointer_size save
        +# pragma pointer_size 32
        +	char *filespec1_32p;
        +	char *filespec2_32p;
        +# pragma pointer_size restore
        +	char filespec1_32[ NAMX_MAXRSS+ 1];
        +	char filespec2_32[ NAMX_MAXRSS+ 1];
        +#else /* __INITIAL_POINTER_SIZE == 64 */
        +# define FILESPEC1 ((char *) filespec1)
        +# define FILESPEC2 ((char *) filespec2)
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +	if (!filespec1) filespec1 = "";
        +	if (!filespec2) filespec2 = "";
        +	filespec1len = strlen(filespec1);
        +	filespec2len = strlen(filespec2);
        +
        +#if __INITIAL_POINTER_SIZE == 64
        +	/* Copy the file names to storage with a 32-bit pointer. */
        +	filespec1_32p = filespec1_32;
        +	filespec2_32p = filespec2_32;
        +	strcpy( filespec1_32p, filespec1);
        +	strcpy( filespec2_32p, filespec2);
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +	fab = cc$rms_fab;
        +	nam = CC_RMS_NAMX;
        +
        +	FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
        +	FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = filespec1len;
        +	FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
        +	FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = filespec2len;
        +	NAMX_DNA_FNA_SET( fab)
        +
        +	nam.NAMX_ESA = esa;
        +	nam.NAMX_ESS = NAMX_MAXRSS;
        +	nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
        +	SET_NAMX_NO_SHORT_UPCASE( nam);
        +
        +	fab.FAB_NAMX = &nam;
        +
        +	status = sys$parse(&fab, 0, 0);
        +
        +	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;
        +
        +		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_MERGER,DSO_R_FAILURE);
        +			ERR_add_error_data(7,
        +					   "filespec \"", filespec1, "\", ",
        +					   "defaults \"", filespec2, "\": ",
        +					   errstring);
        +			}
        +		return(NULL);
        +		}
        +
        +	merged = OPENSSL_malloc( nam.NAMX_ESL+ 1);
        +	if(!merged)
        +		goto malloc_err;
        +	strncpy( merged, nam.NAMX_ESA, nam.NAMX_ESL);
        +	merged[ nam.NAMX_ESL] = '\0';
        +	return(merged);
        + malloc_err:
        +	DSOerr(DSO_F_VMS_MERGER,
        +		ERR_R_MALLOC_FAILURE);
        +	}
        +
        +static char *vms_name_converter(DSO *dso, const char *filename)
        +	{
        +        int len = strlen(filename);
        +        char *not_translated = OPENSSL_malloc(len+1);
        +        strcpy(not_translated,filename);
        +	return(not_translated);
        +	}
        +
        +#endif /* OPENSSL_SYS_VMS */
        diff --git a/vendor/openssl/openssl/crypto/dso/dso_win32.c b/vendor/openssl/openssl/crypto/dso/dso_win32.c
        new file mode 100644
        index 000000000..6fb6c5418
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/dso/dso_win32.c
        @@ -0,0 +1,844 @@
        +/* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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 <stdio.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/dso.h>
        +
        +#if !defined(DSO_WIN32)
        +DSO_METHOD *DSO_METHOD_win32(void)
        +	{
        +	return NULL;
        +	}
        +#else
        +
        +#ifdef _WIN32_WCE
        +# if _WIN32_WCE < 300
        +static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
        +	{
        +	WCHAR lpProcNameW[64];
        +	int i;
        +
        +	for (i=0;lpProcName[i] && i<64;i++)
        +		lpProcNameW[i] = (WCHAR)lpProcName[i];
        +	if (i==64) return NULL;
        +	lpProcNameW[i] = 0;
        +
        +	return GetProcAddressW(hModule,lpProcNameW);
        +	}
        +# endif
        +# undef GetProcAddress
        +# define GetProcAddress GetProcAddressA
        +
        +static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
        +	{
        +	WCHAR *fnamw;
        +	size_t len_0=strlen(lpLibFileName)+1,i;
        +
        +#ifdef _MSC_VER
        +	fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
        +#else
        +	fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
        +#endif
        +	if (fnamw == NULL)
        +		{
        +		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        +		return NULL;
        +		}
        +
        +#if defined(_WIN32_WCE) && _WIN32_WCE>=101
        +	if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
        +#endif
        +		for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i];
        +
        +	return LoadLibraryW(fnamw);
        +	}
        +#endif
        +
        +/* Part of the hack in "win32_load" ... */
        +#define DSO_MAX_TRANSLATED_SIZE 256
        +
        +static int win32_load(DSO *dso);
        +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);
        +static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
        +#endif
        +static char *win32_name_converter(DSO *dso, const char *filename);
        +static char *win32_merger(DSO *dso, const char *filespec1,
        +	const char *filespec2);
        +static int win32_pathbyaddr(void *addr,char *path,int sz);
        +static void *win32_globallookup(const char *name);
        +
        +static const char *openssl_strnchr(const char *string, int c, size_t len);
        +
        +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
        +	NULL, /* ctrl */
        +	win32_name_converter,
        +	win32_merger,
        +	NULL, /* init */
        +	NULL, /* finish */
        +	win32_pathbyaddr,
        +	win32_globallookup
        +	};
        +
        +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)
        +	{
        +	HINSTANCE h = NULL, *p = NULL;
        +	/* See applicable comments from dso_dl.c */
        +	char *filename = DSO_convert_filename(dso, NULL);
        +
        +	if(filename == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
        +		goto err;
        +		}
        +	h = LoadLibraryA(filename);
        +	if(h == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
        +		ERR_add_error_data(3, "filename(", filename, ")");
        +		goto err;
        +		}
        +	p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
        +	if(p == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	*p = h;
        +	if(!sk_void_push(dso->meth_data, p))
        +		{
        +		DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
        +		goto err;
        +		}
        +	/* Success */
        +	dso->loaded_filename = filename;
        +	return(1);
        +err:
        +	/* Cleanup !*/
        +	if(filename != NULL)
        +		OPENSSL_free(filename);
        +	if(p != NULL)
        +		OPENSSL_free(p);
        +	if(h != NULL)
        +		FreeLibrary(h);
        +	return(0);
        +	}
        +
        +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_void_num(dso->meth_data) < 1)
        +		return(1);
        +	p = sk_void_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_void_push(dso->meth_data, 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_void_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
        +		return(NULL);
        +		}
        +	ptr = sk_void_value(dso->meth_data, sk_void_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);
        +		ERR_add_error_data(3, "symname(", symname, ")");
        +		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_void_num(dso->meth_data) < 1)
        +		{
        +		DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
        +		return(NULL);
        +		}
        +	ptr = sk_void_value(dso->meth_data, sk_void_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);
        +		ERR_add_error_data(3, "symname(", symname, ")");
        +		return(NULL);
        +		}
        +	return((DSO_FUNC_TYPE)sym);
        +	}
        +
        +struct file_st
        +	{
        +	const char *node; int nodelen;
        +	const char *device; int devicelen;
        +	const char *predir; int predirlen;
        +	const char *dir; int dirlen;
        +	const char *file; int filelen;
        +	};
        +
        +static struct file_st *win32_splitter(DSO *dso, const char *filename,
        +	int assume_last_is_dir)
        +	{
        +	struct file_st *result = NULL;
        +	enum { IN_NODE, IN_DEVICE, IN_FILE } position;
        +	const char *start = filename;
        +	char last;
        +
        +	if (!filename)
        +		{
        +		DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME);
        +		/*goto err;*/
        +		return(NULL);
        +		}
        +
        +	result = OPENSSL_malloc(sizeof(struct file_st));
        +	if(result == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_SPLITTER,
        +			ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +
        +	memset(result, 0, sizeof(struct file_st));
        +	position = IN_DEVICE;
        +
        +	if((filename[0] == '\\' && filename[1] == '\\')
        +		|| (filename[0] == '/' && filename[1] == '/'))
        +		{
        +		position = IN_NODE;
        +		filename += 2;
        +		start = filename;
        +		result->node = start;
        +		}
        +
        +	do
        +		{
        +		last = filename[0];
        +		switch(last)
        +			{
        +		case ':':
        +			if(position != IN_DEVICE)
        +				{
        +				DSOerr(DSO_F_WIN32_SPLITTER,
        +					DSO_R_INCORRECT_FILE_SYNTAX);
        +				/*goto err;*/
        +				OPENSSL_free(result);
        +				return(NULL);
        +				}
        +			result->device = start;
        +			result->devicelen = (int)(filename - start);
        +			position = IN_FILE;
        +			start = ++filename;
        +			result->dir = start;
        +			break;
        +		case '\\':
        +		case '/':
        +			if(position == IN_NODE)
        +				{
        +				result->nodelen = (int)(filename - start);
        +				position = IN_FILE;
        +				start = ++filename;
        +				result->dir = start;
        +				}
        +			else if(position == IN_DEVICE)
        +				{
        +				position = IN_FILE;
        +				filename++;
        +				result->dir = start;
        +				result->dirlen = (int)(filename - start);
        +				start = filename;
        +				}
        +			else
        +				{
        +				filename++;
        +				result->dirlen += (int)(filename - start);
        +				start = filename;
        +				}
        +			break;
        +		case '\0':
        +			if(position == IN_NODE)
        +				{
        +				result->nodelen = (int)(filename - start);
        +				}
        +			else
        +				{
        +				if(filename - start > 0)
        +					{
        +					if (assume_last_is_dir)
        +						{
        +						if (position == IN_DEVICE)
        +							{
        +							result->dir = start;
        +							result->dirlen = 0;
        +							}
        +						result->dirlen +=
        +							(int)(filename - start);
        +						}
        +					else
        +						{
        +						result->file = start;
        +						result->filelen =
        +							(int)(filename - start);
        +						}
        +					}
        +				}
        +			break;
        +		default:
        +			filename++;
        +			break;
        +			}
        +		}
        +	while(last);
        +
        +	if(!result->nodelen) result->node = NULL;
        +	if(!result->devicelen) result->device = NULL;
        +	if(!result->dirlen) result->dir = NULL;
        +	if(!result->filelen) result->file = NULL;
        +
        +	return(result);
        +	}
        +
        +static char *win32_joiner(DSO *dso, const struct file_st *file_split)
        +	{
        +	int len = 0, offset = 0;
        +	char *result = NULL;
        +	const char *start;
        +
        +	if(!file_split)
        +		{
        +		DSOerr(DSO_F_WIN32_JOINER,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if(file_split->node)
        +		{
        +		len += 2 + file_split->nodelen;	/* 2 for starting \\ */
        +		if(file_split->predir || file_split->dir || file_split->file)
        +			len++;	/* 1 for ending \ */
        +		}
        +	else if(file_split->device)
        +		{
        +		len += file_split->devicelen + 1; /* 1 for ending : */
        +		}
        +	len += file_split->predirlen;
        +	if(file_split->predir && (file_split->dir || file_split->file))
        +		{
        +		len++;	/* 1 for ending \ */
        +		}
        +	len += file_split->dirlen;
        +	if(file_split->dir && file_split->file)
        +		{
        +		len++;	/* 1 for ending \ */
        +		}
        +	len += file_split->filelen;
        +
        +	if(!len)
        +		{
        +		DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
        +		return(NULL);
        +		}
        +
        +	result = OPENSSL_malloc(len + 1);
        +	if (!result)
        +		{
        +		DSOerr(DSO_F_WIN32_JOINER,
        +			ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +
        +	if(file_split->node)
        +		{
        +		strcpy(&result[offset], "\\\\"); offset += 2;
        +		strncpy(&result[offset], file_split->node,
        +			file_split->nodelen); offset += file_split->nodelen;
        +		if(file_split->predir || file_split->dir || file_split->file)
        +			{
        +			result[offset] = '\\'; offset++;
        +			}
        +		}
        +	else if(file_split->device)
        +		{
        +		strncpy(&result[offset], file_split->device,
        +			file_split->devicelen); offset += file_split->devicelen;
        +		result[offset] = ':'; offset++;
        +		}
        +	start = file_split->predir;
        +	while(file_split->predirlen > (start - file_split->predir))
        +		{
        +		const char *end = openssl_strnchr(start, '/',
        +			file_split->predirlen - (start - file_split->predir));
        +		if(!end)
        +			end = start
        +				+ file_split->predirlen
        +				- (start - file_split->predir);
        +		strncpy(&result[offset], start,
        +			end - start); offset += (int)(end - start);
        +		result[offset] = '\\'; offset++;
        +		start = end + 1;
        +		}
        +#if 0 /* Not needed, since the directory converter above already appeneded
        +	 a backslash */
        +	if(file_split->predir && (file_split->dir || file_split->file))
        +		{
        +		result[offset] = '\\'; offset++;
        +		}
        +#endif
        +	start = file_split->dir;
        +	while(file_split->dirlen > (start - file_split->dir))
        +		{
        +		const char *end = openssl_strnchr(start, '/',
        +			file_split->dirlen - (start - file_split->dir));
        +		if(!end)
        +			end = start
        +				+ file_split->dirlen
        +				- (start - file_split->dir);
        +		strncpy(&result[offset], start,
        +			end - start); offset += (int)(end - start);
        +		result[offset] = '\\'; offset++;
        +		start = end + 1;
        +		}
        +#if 0 /* Not needed, since the directory converter above already appeneded
        +	 a backslash */
        +	if(file_split->dir && file_split->file)
        +		{
        +		result[offset] = '\\'; offset++;
        +		}
        +#endif
        +	strncpy(&result[offset], file_split->file,
        +		file_split->filelen); offset += file_split->filelen;
        +	result[offset] = '\0';
        +	return(result);
        +	}
        +
        +static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
        +	{
        +	char *merged = NULL;
        +	struct file_st *filespec1_split = NULL;
        +	struct file_st *filespec2_split = NULL;
        +
        +	if(!filespec1 && !filespec2)
        +		{
        +		DSOerr(DSO_F_WIN32_MERGER,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +		return(NULL);
        +		}
        +	if (!filespec2)
        +		{
        +		merged = OPENSSL_malloc(strlen(filespec1) + 1);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_WIN32_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec1);
        +		}
        +	else if (!filespec1)
        +		{
        +		merged = OPENSSL_malloc(strlen(filespec2) + 1);
        +		if(!merged)
        +			{
        +			DSOerr(DSO_F_WIN32_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		strcpy(merged, filespec2);
        +		}
        +	else
        +		{
        +		filespec1_split = win32_splitter(dso, filespec1, 0);
        +		if (!filespec1_split)
        +			{
        +			DSOerr(DSO_F_WIN32_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		filespec2_split = win32_splitter(dso, filespec2, 1);
        +		if (!filespec2_split)
        +			{
        +			DSOerr(DSO_F_WIN32_MERGER,
        +				ERR_R_MALLOC_FAILURE);
        +			OPENSSL_free(filespec1_split);
        +			return(NULL);
        +			}
        +
        +		/* Fill in into filespec1_split */
        +		if (!filespec1_split->node && !filespec1_split->device)
        +			{
        +			filespec1_split->node = filespec2_split->node;
        +			filespec1_split->nodelen = filespec2_split->nodelen;
        +			filespec1_split->device = filespec2_split->device;
        +			filespec1_split->devicelen = filespec2_split->devicelen;
        +			}
        +		if (!filespec1_split->dir)
        +			{
        +			filespec1_split->dir = filespec2_split->dir;
        +			filespec1_split->dirlen = filespec2_split->dirlen;
        +			}
        +		else if (filespec1_split->dir[0] != '\\'
        +			&& filespec1_split->dir[0] != '/')
        +			{
        +			filespec1_split->predir = filespec2_split->dir;
        +			filespec1_split->predirlen = filespec2_split->dirlen;
        +			}
        +		if (!filespec1_split->file)
        +			{
        +			filespec1_split->file = filespec2_split->file;
        +			filespec1_split->filelen = filespec2_split->filelen;
        +			}
        +
        +		merged = win32_joiner(dso, filespec1_split);
        +		}
        +	OPENSSL_free(filespec1_split);
        +	OPENSSL_free(filespec2_split);
        +	return(merged);
        +	}
        +
        +static char *win32_name_converter(DSO *dso, const char *filename)
        +	{
        +	char *translated;
        +	int len, transform;
        +
        +	len = strlen(filename);
        +	transform = ((strstr(filename, "/") == NULL) &&
        +			(strstr(filename, "\\") == NULL) &&
        +			(strstr(filename, ":") == NULL));
        +	if(transform)
        +		/* We will convert this to "%s.dll" */
        +		translated = OPENSSL_malloc(len + 5);
        +	else
        +		/* We will simply duplicate filename */
        +		translated = OPENSSL_malloc(len + 1);
        +	if(translated == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_NAME_CONVERTER,
        +				DSO_R_NAME_TRANSLATION_FAILED); 
        +		return(NULL);   
        +		}
        +	if(transform)
        +		sprintf(translated, "%s.dll", filename);
        +	else
        +		sprintf(translated, "%s", filename);
        +	return(translated);
        +	}
        +
        +static const char *openssl_strnchr(const char *string, int c, size_t len)
        +	{
        +	size_t i;
        +	const char *p;
        +	for (i = 0, p = string; i < len && *p; i++, p++)
        +		{
        +		if (*p == c)
        +			return p;
        +		}
        +	return NULL;
        +	}
        +
        +#include <tlhelp32.h>
        +#ifdef _WIN32_WCE
        +# define DLLNAME "TOOLHELP.DLL"
        +#else
        +# ifdef MODULEENTRY32
        +# undef MODULEENTRY32	/* unmask the ASCII version! */
        +# endif
        +# define DLLNAME "KERNEL32.DLL"
        +#endif
        +
        +typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
        +typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
        +typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
        +
        +static int win32_pathbyaddr(void *addr,char *path,int sz)
        +	{
        +	HMODULE dll;
        +	HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 
        +	MODULEENTRY32 me32; 
        +	CREATETOOLHELP32SNAPSHOT create_snap;
        +	CLOSETOOLHELP32SNAPSHOT  close_snap;
        +	MODULE32 module_first, module_next;
        +	int len;
        + 
        +	if (addr == NULL)
        +		{
        +		union	{ int(*f)(void*,char*,int); void *p; } t =
        +			{ win32_pathbyaddr };
        +		addr = t.p;
        +		}
        +
        +	dll = LoadLibrary(TEXT(DLLNAME));
        +	if (dll == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
        +		return -1;
        +		}
        +
        +	create_snap = (CREATETOOLHELP32SNAPSHOT)
        +		GetProcAddress(dll,"CreateToolhelp32Snapshot");
        +	if (create_snap == NULL)
        +		{
        +		FreeLibrary(dll);
        +		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
        +		return -1;
        +		}
        +	/* We take the rest for granted... */
        +#ifdef _WIN32_WCE
        +	close_snap = (CLOSETOOLHELP32SNAPSHOT)
        +		GetProcAddress(dll,"CloseToolhelp32Snapshot");
        +#else
        +	close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
        +#endif
        +	module_first = (MODULE32)GetProcAddress(dll,"Module32First");
        +	module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
        +
        +	hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); 
        +	if( hModuleSnap == INVALID_HANDLE_VALUE ) 
        +		{ 
        +		FreeLibrary(dll);
        +		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
        +		return -1;
        +		} 
        + 
        +	me32.dwSize = sizeof(me32); 
        + 
        +	if(!(*module_first)(hModuleSnap,&me32)) 
        +		{ 
        +		(*close_snap)(hModuleSnap);
        +		FreeLibrary(dll);
        +		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_FAILURE);
        +		return -1;
        +		}
        + 
        +	do	{ 
        +		if ((BYTE *)addr >= me32.modBaseAddr &&
        +		    (BYTE *)addr <  me32.modBaseAddr+me32.modBaseSize)
        +			{
        +			(*close_snap)(hModuleSnap);
        +			FreeLibrary(dll);
        +#ifdef _WIN32_WCE
        +# if _WIN32_WCE >= 101
        +			return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1,
        +							path,sz,NULL,NULL);
        +# else
        +			len = (int)wcslen(me32.szExePath);
        +			if (sz <= 0) return len+1;
        +			if (len >= sz) len=sz-1;
        +			for(i=0;i<len;i++)
        +				path[i] = (char)me32.szExePath[i];
        +			path[len++] = 0;
        +			return len;
        +# endif
        +#else
        +			len = (int)strlen(me32.szExePath);
        +			if (sz <= 0) return len+1;
        +			if (len >= sz) len=sz-1;
        +			memcpy(path,me32.szExePath,len);
        +			path[len++] = 0;
        +			return len;
        +#endif
        +			} 
        +		} while((*module_next)(hModuleSnap, &me32)); 
        + 
        +	(*close_snap)(hModuleSnap); 
        +	FreeLibrary(dll);
        +	return 0;
        +	}
        +
        +static void *win32_globallookup(const char *name)
        +	{
        +	HMODULE dll;
        +	HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
        +	MODULEENTRY32 me32;
        +	CREATETOOLHELP32SNAPSHOT create_snap;
        +	CLOSETOOLHELP32SNAPSHOT  close_snap;
        +	MODULE32 module_first, module_next;
        +	FARPROC ret=NULL;
        +
        +	dll = LoadLibrary(TEXT(DLLNAME));
        +	if (dll == NULL)
        +		{
        +		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
        +		return NULL;
        +		}
        +
        +	create_snap = (CREATETOOLHELP32SNAPSHOT)
        +		GetProcAddress(dll,"CreateToolhelp32Snapshot");
        +	if (create_snap == NULL)
        +		{
        +		FreeLibrary(dll);
        +		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
        +		return NULL;
        +		}
        +	/* We take the rest for granted... */
        +#ifdef _WIN32_WCE
        +	close_snap = (CLOSETOOLHELP32SNAPSHOT)
        +		GetProcAddress(dll,"CloseToolhelp32Snapshot");
        +#else
        +	close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
        +#endif
        +	module_first = (MODULE32)GetProcAddress(dll,"Module32First");
        +	module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
        +
        +	hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
        +	if( hModuleSnap == INVALID_HANDLE_VALUE )
        +		{
        +		FreeLibrary(dll);
        +		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
        +		return NULL;
        +		}
        +
        +	me32.dwSize = sizeof(me32);
        +
        +	if (!(*module_first)(hModuleSnap,&me32))
        +		{
        +		(*close_snap)(hModuleSnap);
        +		FreeLibrary(dll);
        +		return NULL;
        +		}
        +
        +	do	{
        +		if ((ret = GetProcAddress(me32.hModule,name)))
        +			{
        +			(*close_snap)(hModuleSnap);
        +			FreeLibrary(dll);
        +			return ret;
        +			}
        +		} while((*module_next)(hModuleSnap,&me32));
        +
        +	(*close_snap)(hModuleSnap); 
        +	FreeLibrary(dll);
        +	return NULL;
        +	}
        +#endif /* DSO_WIN32 */
        diff --git a/vendor/openssl/openssl/crypto/ebcdic.c b/vendor/openssl/openssl/crypto/ebcdic.c
        new file mode 100644
        index 000000000..43e53bcaf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ebcdic.c
        @@ -0,0 +1,221 @@
        +/* crypto/ebcdic.c */
        +
        +#ifndef CHARSET_EBCDIC
        +
        +#include <openssl/e_os2.h>
        +#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
        +static void *dummy=&dummy;
        +#endif
        +
        +#else /*CHARSET_EBCDIC*/
        +
        +#include "ebcdic.h"
        +/*      Initial Port for  Apache-1.3     by <Martin.Kraemer@Mch.SNI.De>
        + *      Adapted for       OpenSSL-0.9.4  by <Martin.Kraemer@Mch.SNI.De>
        + */
        +
        +#ifdef _OSD_POSIX
        +/*
        +    "BS2000 OSD" is a POSIX subsystem on a main frame.
        +    It is made by Siemens AG, Germany, for their BS2000 mainframe machines.
        +    Within the POSIX subsystem, the same character set was chosen as in
        +    "native BS2000", namely EBCDIC. (EDF04)
        +
        +    The name "ASCII" in these routines is misleading: actually, conversion
        +    is not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1;
        +    that means that (western european) national characters are preserved.
        +
        +    This table is identical to the one used by rsh/rcp/ftp and other POSIX tools.
        +*/
        +
        +/* Here's the bijective ebcdic-to-ascii table: */
        +const unsigned char os_toascii[256] = {
        +/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
        +       0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/
        +/*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
        +       0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/
        +/*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
        +       0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/
        +/*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
        +       0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/
        +/*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
        +       0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/
        +/*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
        +       0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/
        +/*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
        +       0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/
        +/*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
        +       0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/
        +/*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
        +       0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/
        +/*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
        +       0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/
        +/*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
        +       0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/
        +/*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
        +       0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/
        +/*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
        +       0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/
        +/*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
        +       0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/
        +/*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
        +       0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/
        +/*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        +       0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e  /*0123456789.{.}.~*/
        +};
        +
        +
        +/* The ascii-to-ebcdic table: */
        +const unsigned char os_toebcdic[256] = {
        +/*00*/  0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
        +	0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,  /*................*/
        +/*10*/  0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
        +	0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,  /*................*/
        +/*20*/  0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
        +	0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,  /* !"#$%&'()*+,-./ */
        +/*30*/  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
        +	0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,  /*0123456789:;<=>?*/
        +/*40*/  0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        +	0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,  /*@ABCDEFGHIJKLMNO*/
        +/*50*/  0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
        +	0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d,  /*PQRSTUVWXYZ[\]^_*/
        +/*60*/  0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
        +	0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,  /*`abcdefghijklmno*/
        +/*70*/  0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
        +	0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07,  /*pqrstuvwxyz{|}~.*/
        +/*80*/  0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
        +	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14,  /*................*/
        +/*90*/  0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
        +	0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f,  /*................*/
        +/*a0*/  0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
        +	0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1,  /*................*/
        +/*b0*/  0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
        +	0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,  /*................*/
        +/*c0*/  0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
        +	0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,  /*................*/
        +/*d0*/  0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
        +	0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59,  /*................*/
        +/*e0*/  0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
        +	0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,  /*................*/
        +/*f0*/  0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
        +	0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf   /*................*/
        +};
        +
        +#else  /*_OSD_POSIX*/
        +
        +/*
        +This code does basic character mapping for IBM's TPF and OS/390 operating systems.
        +It is a modified version of the BS2000 table.
        +
        +Bijective EBCDIC (character set IBM-1047) to US-ASCII table:
        +This table is bijective - there are no ambigous or duplicate characters.
        +*/
        +const unsigned char os_toascii[256] = {
        +    0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f:           */
        +    0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
        +    0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f:           */
        +    0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
        +    0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f:           */
        +    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
        +    0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f:           */
        +    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
        +    0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f:           */
        +    0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /*  ...........<(+| */
        +    0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f:           */
        +    0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
        +    0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f:           */
        +    0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
        +    0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f:           */
        +    0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
        +    0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f:           */
        +    0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
        +    0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f:           */
        +    0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
        +    0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af:           */
        +    0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
        +    0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf:           */
        +    0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
        +    0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf:           */
        +    0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
        +    0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df:           */
        +    0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
        +    0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef:           */
        +    0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
        +    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff:           */
        +    0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f  /* 0123456789...... */
        +};
        +
        +
        +/*
        +The US-ASCII to EBCDIC (character set IBM-1047) table:
        +This table is bijective (no ambiguous or duplicate characters)
        +*/
        +const unsigned char os_toebcdic[256] = {
        +    0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f:           */
        +    0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
        +    0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f:           */
        +    0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
        +    0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f:           */
        +    0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /*  !"#$%&'()*+,-./ */
        +    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f:           */
        +    0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
        +    0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f:           */
        +    0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
        +    0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f:           */
        +    0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */
        +    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f:           */
        +    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
        +    0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f:           */
        +    0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */
        +    0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f:           */
        +    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
        +    0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f:           */
        +    0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */
        +    0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af:           */
        +    0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */
        +    0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf:           */
        +    0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
        +    0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf:           */
        +    0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
        +    0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df:           */
        +    0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */
        +    0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef:           */
        +    0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
        +    0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff:           */
        +    0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf  /* ................ */
        +};
        +#endif /*_OSD_POSIX*/
        +
        +/* Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
        + * dest and srce may be identical, or separate memory blocks, but
        + * should not overlap. These functions intentionally have an interface
        + * compatible to memcpy(3).
        + */
        +
        +void *
        +ebcdic2ascii(void *dest, const void *srce, size_t count)
        +{
        +    unsigned char *udest = dest;
        +    const unsigned char *usrce = srce;
        +
        +    while (count-- != 0) {
        +        *udest++ = os_toascii[*usrce++];
        +    }
        +
        +    return dest;
        +}
        +
        +void *
        +ascii2ebcdic(void *dest, const void *srce, size_t count)
        +{
        +    unsigned char *udest = dest;
        +    const unsigned char *usrce = srce;
        +
        +    while (count-- != 0) {
        +        *udest++ = os_toebcdic[*usrce++];
        +    }
        +
        +    return dest;
        +}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ebcdic.h b/vendor/openssl/openssl/crypto/ebcdic.h
        new file mode 100644
        index 000000000..6d65afcf9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ebcdic.h
        @@ -0,0 +1,19 @@
        +/* crypto/ebcdic.h */
        +
        +#ifndef HEADER_EBCDIC_H
        +#define HEADER_EBCDIC_H
        +
        +#include <sys/types.h>
        +
        +/* Avoid name clashes with other applications */
        +#define os_toascii   _openssl_os_toascii
        +#define os_toebcdic  _openssl_os_toebcdic
        +#define ebcdic2ascii _openssl_ebcdic2ascii
        +#define ascii2ebcdic _openssl_ascii2ebcdic
        +
        +extern const unsigned char os_toascii[256];
        +extern const unsigned char os_toebcdic[256];
        +void *ebcdic2ascii(void *dest, const void *srce, size_t count);
        +void *ascii2ebcdic(void *dest, const void *srce, size_t count);
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/Makefile b/vendor/openssl/openssl/crypto/ec/Makefile
        new file mode 100644
        index 000000000..f85fc845c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/Makefile
        @@ -0,0 +1,263 @@
        +#
        +# crypto/ec/Makefile
        +#
        +
        +DIR=	ec
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=ectest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
        +	ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
        +	ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
        +	ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
        +	ecp_oct.c ec2_oct.c ec_oct.c
        +
        +LIBOBJ=	ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
        +	ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
        +	ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o \
        +	ecp_nistp224.o ecp_nistp256.o ecp_nistp521.o ecp_nistputil.o \
        +	ecp_oct.o ec2_oct.o ec_oct.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ec.h
        +HEADER=	ec_lcl.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
        +ec2_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec2_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec2_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec2_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec2_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec2_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec2_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec2_oct.o: ../../include/openssl/symhacks.h ec2_oct.c ec_lcl.h
        +ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec_lcl.h
        +ec_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
        +ec_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +ec_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +ec_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ec_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ec_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ec_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ec_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ec_ameth.o: ../../include/openssl/opensslconf.h
        +ec_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ec_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ec_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ec_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +ec_ameth.o: ec_ameth.c
        +ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
        +ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
        +ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
        +ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
        +ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
        +ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
        +ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_err.o: ../../include/openssl/symhacks.h ec_err.c
        +ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
        +ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
        +ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
        +ec_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ec_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_oct.o: ../../include/openssl/symhacks.h ec_lcl.h ec_oct.c
        +ec_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +ec_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +ec_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ec_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ec_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ec_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ec_pmeth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ec_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ec_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ec_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ec_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
        +ec_pmeth.o: ec_pmeth.c
        +ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
        +eck_prn.o: ../../e_os.h ../../include/openssl/asn1.h
        +eck_prn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +eck_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +eck_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eck_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eck_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eck_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eck_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eck_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +eck_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h eck_prn.c
        +ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
        +ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
        +ecp_nistp224.o: ../../include/openssl/opensslconf.h ecp_nistp224.c
        +ecp_nistp256.o: ../../include/openssl/opensslconf.h ecp_nistp256.c
        +ecp_nistp521.o: ../../include/openssl/opensslconf.h ecp_nistp521.c
        +ecp_nistputil.o: ../../include/openssl/opensslconf.h ecp_nistputil.c
        +ecp_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecp_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ecp_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecp_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ecp_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ecp_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecp_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecp_oct.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_oct.c
        +ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
        +ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
        diff --git a/vendor/openssl/openssl/crypto/ec/ec.h b/vendor/openssl/openssl/crypto/ec/ec.h
        new file mode 100644
        index 000000000..dfe8710d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec.h
        @@ -0,0 +1,1167 @@
        +/* crypto/ec/ec.h */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/**
        + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
        + * \author Originally written by Bodo Moeller for the OpenSSL project
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#ifndef HEADER_EC_H
        +#define HEADER_EC_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_EC
        +#error EC is disabled.
        +#endif
        +
        +#include <openssl/asn1.h>
        +#include <openssl/symhacks.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#elif defined(__SUNPRO_C)
        +# if __SUNPRO_C >= 0x520
        +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
        +# endif
        +#endif
        +
        +  
        +#ifndef OPENSSL_ECC_MAX_FIELD_BITS
        +# define OPENSSL_ECC_MAX_FIELD_BITS 661
        +#endif
        +
        +/** Enum for the point conversion form as defined in X9.62 (ECDSA)
        + *  for the encoding of a elliptic curve point (x,y) */
        +typedef enum {
        +	/** the point is encoded as z||x, where the octet z specifies 
        +	 *  which solution of the quadratic equation y is  */
        +	POINT_CONVERSION_COMPRESSED = 2,
        +	/** the point is encoded as z||x||y, where z is the octet 0x02  */
        +	POINT_CONVERSION_UNCOMPRESSED = 4,
        +	/** the point is encoded as z||x||y, where the octet z specifies
        +         *  which solution of the quadratic equation y is  */
        +	POINT_CONVERSION_HYBRID = 6
        +} point_conversion_form_t;
        +
        +
        +typedef struct ec_method_st EC_METHOD;
        +
        +typedef struct ec_group_st
        +	/*
        +	 EC_METHOD *meth;
        +	 -- field definition
        +	 -- curve coefficients
        +	 -- optional generator with associated information (order, cofactor)
        +	 -- optional extra data (precomputed table for fast computation of multiples of generator)
        +	 -- ASN1 stuff
        +	*/
        +	EC_GROUP;
        +
        +typedef struct ec_point_st EC_POINT;
        +
        +
        +/********************************************************************/
        +/*               EC_METHODs for curves over GF(p)                   */       
        +/********************************************************************/
        +
        +/** Returns the basic GFp ec methods which provides the basis for the
        + *  optimized methods. 
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GFp_simple_method(void);
        +
        +/** Returns GFp methods using montgomery multiplication.
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GFp_mont_method(void);
        +
        +/** Returns GFp methods using optimized methods for NIST recommended curves
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GFp_nist_method(void);
        +
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +/** Returns 64-bit optimized methods for nistp224
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GFp_nistp224_method(void);
        +
        +/** Returns 64-bit optimized methods for nistp256
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GFp_nistp256_method(void);
        +
        +/** Returns 64-bit optimized methods for nistp521
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GFp_nistp521_method(void);
        +#endif
        +
        +#ifndef OPENSSL_NO_EC2M
        +/********************************************************************/ 
        +/*           EC_METHOD for curves over GF(2^m)                      */
        +/********************************************************************/
        +
        +/** Returns the basic GF2m ec method 
        + *  \return  EC_METHOD object
        + */
        +const EC_METHOD *EC_GF2m_simple_method(void);
        +
        +#endif
        +
        +
        +/********************************************************************/
        +/*                   EC_GROUP functions                             */
        +/********************************************************************/
        +
        +/** Creates a new EC_GROUP object
        + *  \param   meth  EC_METHOD to use
        + *  \return  newly created EC_GROUP object or NULL in case of an error.
        + */
        +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
        +
        +/** Frees a EC_GROUP object
        + *  \param  group  EC_GROUP object to be freed.
        + */
        +void EC_GROUP_free(EC_GROUP *group);
        +
        +/** Clears and frees a EC_GROUP object
        + *  \param  group  EC_GROUP object to be cleared and freed.
        + */
        +void EC_GROUP_clear_free(EC_GROUP *group);
        +
        +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
        + *  \param  dst  destination EC_GROUP object
        + *  \param  src  source EC_GROUP object
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
        +
        +/** Creates a new EC_GROUP object and copies the copies the content
        + *  form src to the newly created EC_KEY object
        + *  \param  src  source EC_GROUP object
        + *  \return newly created EC_GROUP object or NULL in case of an error.
        + */
        +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
        +
        +/** Returns the EC_METHOD of the EC_GROUP object.
        + *  \param  group  EC_GROUP object 
        + *  \return EC_METHOD used in this EC_GROUP object.
        + */
        +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
        +
        +/** Returns the field type of the EC_METHOD.
        + *  \param  meth  EC_METHOD object
        + *  \return NID of the underlying field type OID.
        + */
        +int EC_METHOD_get_field_type(const EC_METHOD *meth);
        +
        +/** Sets the generator and it's order/cofactor of a EC_GROUP object.
        + *  \param  group      EC_GROUP object 
        + *  \param  generator  EC_POINT object with the generator.
        + *  \param  order      the order of the group generated by the generator.
        + *  \param  cofactor   the index of the sub-group generated by the generator
        + *                     in the group of all points on the elliptic curve.
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
        +
        +/** Returns the generator of a EC_GROUP object.
        + *  \param  group  EC_GROUP object
        + *  \return the currently used generator (possibly NULL).
        + */
        +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
        +
        +/** Gets the order of a EC_GROUP
        + *  \param  group  EC_GROUP object
        + *  \param  order  BIGNUM to which the order is copied
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
        +
        +/** Gets the cofactor of a EC_GROUP
        + *  \param  group     EC_GROUP object
        + *  \param  cofactor  BIGNUM to which the cofactor is copied
        + *  \param  ctx       BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
        +
        +/** Sets the name of a EC_GROUP object
        + *  \param  group  EC_GROUP object
        + *  \param  nid    NID of the curve name OID
        + */
        +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
        +
        +/** Returns the curve name of a EC_GROUP object
        + *  \param  group  EC_GROUP object
        + *  \return NID of the curve name OID or 0 if not set.
        + */
        +int EC_GROUP_get_curve_name(const EC_GROUP *group);
        +
        +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
        +int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
        +
        +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form);
        +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
        +
        +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
        +size_t EC_GROUP_get_seed_len(const EC_GROUP *);
        +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
        +
        +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
        + *  \param  group  EC_GROUP object
        + *  \param  p      BIGNUM with the prime number
        + *  \param  a      BIGNUM with parameter a of the equation
        + *  \param  b      BIGNUM with parameter b of the equation
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
        +
        +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
        + *  \param  group  EC_GROUP object
        + *  \param  p      BIGNUM for the prime number
        + *  \param  a      BIGNUM for parameter a of the equation
        + *  \param  b      BIGNUM for parameter b of the equation
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
        +
        +#ifndef OPENSSL_NO_EC2M
        +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
        + *  \param  group  EC_GROUP object
        + *  \param  p      BIGNUM with the polynomial defining the underlying field
        + *  \param  a      BIGNUM with parameter a of the equation
        + *  \param  b      BIGNUM with parameter b of the equation
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
        +
        +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
        + *  \param  group  EC_GROUP object
        + *  \param  p      BIGNUM for the polynomial defining the underlying field
        + *  \param  a      BIGNUM for parameter a of the equation
        + *  \param  b      BIGNUM for parameter b of the equation
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
        +#endif
        +/** Returns the number of bits needed to represent a field element 
        + *  \param  group  EC_GROUP object
        + *  \return number of bits needed to represent a field element
        + */
        +int EC_GROUP_get_degree(const EC_GROUP *group);
        +
        +/** Checks whether the parameter in the EC_GROUP define a valid ec group
        + *  \param  group  EC_GROUP object
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 if group is a valid ec group and 0 otherwise
        + */
        +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
        +
        +/** Checks whether the discriminant of the elliptic curve is zero or not
        + *  \param  group  EC_GROUP object
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 if the discriminant is not zero and 0 otherwise
        + */
        +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
        +
        +/** Compares two EC_GROUP objects
        + *  \param  a    first EC_GROUP object
        + *  \param  b    second EC_GROUP object
        + *  \param  ctx  BN_CTX object (optional)
        + *  \return 0 if both groups are equal and 1 otherwise
        + */
        +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
        +
        +/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
        + * after choosing an appropriate EC_METHOD */
        +
        +/** Creates a new EC_GROUP object with the specified parameters defined
        + *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
        + *  \param  p    BIGNUM with the prime number
        + *  \param  a    BIGNUM with the parameter a of the equation
        + *  \param  b    BIGNUM with the parameter b of the equation
        + *  \param  ctx  BN_CTX object (optional)
        + *  \return newly created EC_GROUP object with the specified parameters
        + */
        +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
        +#ifndef OPENSSL_NO_EC2M
        +/** Creates a new EC_GROUP object with the specified parameters defined
        + *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
        + *  \param  p    BIGNUM with the polynomial defining the underlying field
        + *  \param  a    BIGNUM with the parameter a of the equation
        + *  \param  b    BIGNUM with the parameter b of the equation
        + *  \param  ctx  BN_CTX object (optional)
        + *  \return newly created EC_GROUP object with the specified parameters
        + */
        +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
        +#endif
        +/** Creates a EC_GROUP object with a curve specified by a NID
        + *  \param  nid  NID of the OID of the curve name
        + *  \return newly created EC_GROUP object with specified curve or NULL
        + *          if an error occurred
        + */
        +EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
        +
        +
        +/********************************************************************/
        +/*               handling of internal curves                        */
        +/********************************************************************/
        +
        +typedef struct { 
        +	int nid;
        +	const char *comment;
        +	} EC_builtin_curve;
        +
        +/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 
        + * of all available curves or zero if a error occurred. 
        + * In case r ist not zero nitems EC_builtin_curve structures 
        + * are filled with the data of the first nitems internal groups */
        +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
        +
        +
        +/********************************************************************/
        +/*                    EC_POINT functions                            */
        +/********************************************************************/
        +
        +/** Creates a new EC_POINT object for the specified EC_GROUP
        + *  \param  group  EC_GROUP the underlying EC_GROUP object
        + *  \return newly created EC_POINT object or NULL if an error occurred
        + */
        +EC_POINT *EC_POINT_new(const EC_GROUP *group);
        +
        +/** Frees a EC_POINT object
        + *  \param  point  EC_POINT object to be freed
        + */
        +void EC_POINT_free(EC_POINT *point);
        +
        +/** Clears and frees a EC_POINT object
        + *  \param  point  EC_POINT object to be cleared and freed
        + */
        +void EC_POINT_clear_free(EC_POINT *point);
        +
        +/** Copies EC_POINT object
        + *  \param  dst  destination EC_POINT object
        + *  \param  src  source EC_POINT object
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
        +
        +/** Creates a new EC_POINT object and copies the content of the supplied
        + *  EC_POINT
        + *  \param  src    source EC_POINT object
        + *  \param  group  underlying the EC_GROUP object
        + *  \return newly created EC_POINT object or NULL if an error occurred 
        + */
        +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
        + 
        +/** Returns the EC_METHOD used in EC_POINT object 
        + *  \param  point  EC_POINT object
        + *  \return the EC_METHOD used
        + */
        +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
        +
        +/** Sets a point to infinity (neutral element)
        + *  \param  group  underlying EC_GROUP object
        + *  \param  point  EC_POINT to set to infinity
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
        +
        +/** Sets the jacobian projective coordinates of a EC_POINT over GFp
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM with the x-coordinate
        + *  \param  y      BIGNUM with the y-coordinate
        + *  \param  z      BIGNUM with the z-coordinate
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
        +	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
        +
        +/** Gets the jacobian projective coordinates of a EC_POINT over GFp
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM for the x-coordinate
        + *  \param  y      BIGNUM for the y-coordinate
        + *  \param  z      BIGNUM for the z-coordinate
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
        +	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
        +
        +/** Sets the affine coordinates of a EC_POINT over GFp
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM with the x-coordinate
        + *  \param  y      BIGNUM with the y-coordinate
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
        +
        +/** Gets the affine coordinates of a EC_POINT over GFp
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM for the x-coordinate
        + *  \param  y      BIGNUM for the y-coordinate
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
        +	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
        +
        +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM with x-coordinate
        + *  \param  y_bit  integer with the y-Bit (either 0 or 1)
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
        +	const BIGNUM *x, int y_bit, BN_CTX *ctx);
        +#ifndef OPENSSL_NO_EC2M
        +/** Sets the affine coordinates of a EC_POINT over GF2m
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM with the x-coordinate
        + *  \param  y      BIGNUM with the y-coordinate
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
        +
        +/** Gets the affine coordinates of a EC_POINT over GF2m
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM for the x-coordinate
        + *  \param  y      BIGNUM for the y-coordinate
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
        +	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
        +
        +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  x      BIGNUM with x-coordinate
        + *  \param  y_bit  integer with the y-Bit (either 0 or 1)
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
        +	const BIGNUM *x, int y_bit, BN_CTX *ctx);
        +#endif
        +/** Encodes a EC_POINT object to a octet string
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  form   point conversion form
        + *  \param  buf    memory buffer for the result. If NULL the function returns
        + *                 required buffer size.
        + *  \param  len    length of the memory buffer
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return the length of the encoded octet string or 0 if an error occurred
        + */
        +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
        +	point_conversion_form_t form,
        +        unsigned char *buf, size_t len, BN_CTX *ctx);
        +
        +/** Decodes a EC_POINT from a octet string
        + *  \param  group  underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \param  buf    memory buffer with the encoded ec point
        + *  \param  len    length of the encoded ec point
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
        +        const unsigned char *buf, size_t len, BN_CTX *ctx);
        +
        +/* other interfaces to point2oct/oct2point: */
        +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
        +	point_conversion_form_t form, BIGNUM *, BN_CTX *);
        +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
        +	EC_POINT *, BN_CTX *);
        +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
        +	point_conversion_form_t form, BN_CTX *);
        +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
        +	EC_POINT *, BN_CTX *);
        +
        +
        +/********************************************************************/
        +/*         functions for doing EC_POINT arithmetic                  */
        +/********************************************************************/
        +
        +/** Computes the sum of two EC_POINT 
        + *  \param  group  underlying EC_GROUP object
        + *  \param  r      EC_POINT object for the result (r = a + b)
        + *  \param  a      EC_POINT object with the first summand
        + *  \param  b      EC_POINT object with the second summand
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
        +
        +/** Computes the double of a EC_POINT
        + *  \param  group  underlying EC_GROUP object
        + *  \param  r      EC_POINT object for the result (r = 2 * a)
        + *  \param  a      EC_POINT object 
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
        +
        +/** Computes the inverse of a EC_POINT
        + *  \param  group  underlying EC_GROUP object
        + *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
        +
        +/** Checks whether the point is the neutral element of the group
        + *  \param  group  the underlying EC_GROUP object
        + *  \param  p      EC_POINT object
        + *  \return 1 if the point is the neutral element and 0 otherwise
        + */
        +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
        +
        +/** Checks whether the point is on the curve 
        + *  \param  group  underlying EC_GROUP object
        + *  \param  point  EC_POINT object to check
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 if point if on the curve and 0 otherwise
        + */
        +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
        +
        +/** Compares two EC_POINTs 
        + *  \param  group  underlying EC_GROUP object
        + *  \param  a      first EC_POINT object
        + *  \param  b      second EC_POINT object
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 0 if both points are equal and a value != 0 otherwise
        + */
        +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
        +
        +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
        +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
        +
        +/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
        + *  \param  group  underlying EC_GROUP object
        + *  \param  r      EC_POINT object for the result
        + *  \param  n      BIGNUM with the multiplier for the group generator (optional)
        + *  \param  num    number futher summands
        + *  \param  p      array of size num of EC_POINT objects
        + *  \param  m      array of size num of BIGNUM objects
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
        +
        +/** Computes r = generator * n + q * m
        + *  \param  group  underlying EC_GROUP object
        + *  \param  r      EC_POINT object for the result
        + *  \param  n      BIGNUM with the multiplier for the group generator (optional)
        + *  \param  q      EC_POINT object with the first factor of the second summand
        + *  \param  m      BIGNUM with the second factor of the second summand
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
        +
        +/** Stores multiples of generator for faster point multiplication
        + *  \param  group  EC_GROUP object
        + *  \param  ctx    BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occured
        + */
        +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
        +
        +/** Reports whether a precomputation has been done
        + *  \param  group  EC_GROUP object
        + *  \return 1 if a pre-computation has been done and 0 otherwise
        + */
        +int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
        +
        +
        +/********************************************************************/
        +/*                       ASN1 stuff                                 */
        +/********************************************************************/
        +
        +/* EC_GROUP_get_basis_type() returns the NID of the basis type
        + * used to represent the field elements */
        +int EC_GROUP_get_basis_type(const EC_GROUP *);
        +#ifndef OPENSSL_NO_EC2M
        +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
        +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, 
        +	unsigned int *k2, unsigned int *k3);
        +#endif
        +
        +#define OPENSSL_EC_NAMED_CURVE	0x001
        +
        +typedef struct ecpk_parameters_st ECPKPARAMETERS;
        +
        +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
        +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
        +
        +#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
        +#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
        +#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
        +                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
        +#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
        +		(unsigned char *)(x))
        +
        +#ifndef OPENSSL_NO_BIO
        +int     ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +int     ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
        +#endif
        +
        +
        +/********************************************************************/
        +/*                      EC_KEY functions                            */
        +/********************************************************************/
        +
        +typedef struct ec_key_st EC_KEY;
        +
        +/* some values for the encoding_flag */
        +#define EC_PKEY_NO_PARAMETERS	0x001
        +#define EC_PKEY_NO_PUBKEY	0x002
        +
        +/* some values for the flags field */
        +#define EC_FLAG_NON_FIPS_ALLOW	0x1
        +#define EC_FLAG_FIPS_CHECKED	0x2
        +
        +/** Creates a new EC_KEY object.
        + *  \return EC_KEY object or NULL if an error occurred.
        + */
        +EC_KEY *EC_KEY_new(void);
        +
        +int EC_KEY_get_flags(const EC_KEY *key);
        +
        +void EC_KEY_set_flags(EC_KEY *key, int flags);
        +
        +void EC_KEY_clear_flags(EC_KEY *key, int flags);
        +
        +/** Creates a new EC_KEY object using a named curve as underlying
        + *  EC_GROUP object.
        + *  \param  nid  NID of the named curve.
        + *  \return EC_KEY object or NULL if an error occurred. 
        + */
        +EC_KEY *EC_KEY_new_by_curve_name(int nid);
        +
        +/** Frees a EC_KEY object.
        + *  \param  key  EC_KEY object to be freed.
        + */
        +void EC_KEY_free(EC_KEY *key);
        +
        +/** Copies a EC_KEY object.
        + *  \param  dst  destination EC_KEY object
        + *  \param  src  src EC_KEY object
        + *  \return dst or NULL if an error occurred.
        + */
        +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
        +
        +/** Creates a new EC_KEY object and copies the content from src to it.
        + *  \param  src  the source EC_KEY object
        + *  \return newly created EC_KEY object or NULL if an error occurred.
        + */
        +EC_KEY *EC_KEY_dup(const EC_KEY *src);
        +
        +/** Increases the internal reference count of a EC_KEY object.
        + *  \param  key  EC_KEY object
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_KEY_up_ref(EC_KEY *key);
        +
        +/** Returns the EC_GROUP object of a EC_KEY object
        + *  \param  key  EC_KEY object
        + *  \return the EC_GROUP object (possibly NULL).
        + */
        +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
        +
        +/** Sets the EC_GROUP of a EC_KEY object.
        + *  \param  key    EC_KEY object
        + *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
        + *                 object will use an own copy of the EC_GROUP).
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
        +
        +/** Returns the private key of a EC_KEY object.
        + *  \param  key  EC_KEY object
        + *  \return a BIGNUM with the private key (possibly NULL).
        + */
        +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
        +
        +/** Sets the private key of a EC_KEY object.
        + *  \param  key  EC_KEY object
        + *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
        + *               will use an own copy of the BIGNUM).
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
        +
        +/** Returns the public key of a EC_KEY object.
        + *  \param  key  the EC_KEY object
        + *  \return a EC_POINT object with the public key (possibly NULL)
        + */
        +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
        +
        +/** Sets the public key of a EC_KEY object.
        + *  \param  key  EC_KEY object
        + *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
        + *               will use an own copy of the EC_POINT object).
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
        +
        +unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
        +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
        +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
        +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
        +/* functions to set/get method specific data  */
        +void *EC_KEY_get_key_method_data(EC_KEY *key, 
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
        +/** Sets the key method data of an EC_KEY object, if none has yet been set.
        + *  \param  key              EC_KEY object
        + *  \param  data             opaque data to install.
        + *  \param  dup_func         a function that duplicates |data|.
        + *  \param  free_func        a function that frees |data|.
        + *  \param  clear_free_func  a function that wipes and frees |data|.
        + *  \return the previously set data pointer, or NULL if |data| was inserted.
        + */
        +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
        +/* wrapper functions for the underlying EC_GROUP object */
        +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
        +
        +/** Creates a table of pre-computed multiples of the generator to 
        + *  accelerate further EC_KEY operations.
        + *  \param  key  EC_KEY object
        + *  \param  ctx  BN_CTX object (optional)
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
        +
        +/** Creates a new ec private (and optional a new public) key.
        + *  \param  key  EC_KEY object
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int EC_KEY_generate_key(EC_KEY *key);
        +
        +/** Verifies that a private and/or public key is valid.
        + *  \param  key  the EC_KEY object
        + *  \return 1 on success and 0 otherwise.
        + */
        +int EC_KEY_check_key(const EC_KEY *key);
        +
        +/** Sets a public key from affine coordindates performing
        + *  neccessary NIST PKV tests.
        + *  \param  key  the EC_KEY object
        + *  \param  x    public key x coordinate
        + *  \param  y    public key y coordinate
        + *  \return 1 on success and 0 otherwise.
        + */
        +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
        +
        +
        +/********************************************************************/
        +/*        de- and encoding functions for SEC1 ECPrivateKey          */
        +/********************************************************************/
        +
        +/** Decodes a private key from a memory buffer.
        + *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
        + *  \param  in   pointer to memory with the DER encoded private key
        + *  \param  len  length of the DER encoded private key
        + *  \return the decoded private key or NULL if an error occurred.
        + */
        +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
        +
        +/** Encodes a private key object and stores the result in a buffer.
        + *  \param  key  the EC_KEY object to encode
        + *  \param  out  the buffer for the result (if NULL the function returns number
        + *               of bytes needed).
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
        +
        +
        +/********************************************************************/
        +/*        de- and encoding functions for EC parameters              */
        +/********************************************************************/
        +
        +/** Decodes ec parameter from a memory buffer.
        + *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
        + *  \param  in   pointer to memory with the DER encoded ec parameters
        + *  \param  len  length of the DER encoded ec parameters
        + *  \return a EC_KEY object with the decoded parameters or NULL if an error
        + *          occurred.
        + */
        +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
        +
        +/** Encodes ec parameter and stores the result in a buffer.
        + *  \param  key  the EC_KEY object with ec paramters to encode
        + *  \param  out  the buffer for the result (if NULL the function returns number
        + *               of bytes needed).
        + *  \return 1 on success and 0 if an error occurred.
        + */
        +int i2d_ECParameters(EC_KEY *key, unsigned char **out);
        +
        +
        +/********************************************************************/
        +/*         de- and encoding functions for EC public key             */
        +/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
        +/********************************************************************/
        +
        +/** Decodes a ec public key from a octet string.
        + *  \param  key  a pointer to a EC_KEY object which should be used
        + *  \param  in   memory buffer with the encoded public key
        + *  \param  len  length of the encoded public key
        + *  \return EC_KEY object with decoded public key or NULL if an error
        + *          occurred.
        + */
        +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
        +
        +/** Encodes a ec public key in an octet string.
        + *  \param  key  the EC_KEY object with the public key
        + *  \param  out  the buffer for the result (if NULL the function returns number
        + *               of bytes needed).
        + *  \return 1 on success and 0 if an error occurred
        + */
        +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
        +
        +#ifndef OPENSSL_NO_BIO
        +/** Prints out the ec parameters on human readable form.
        + *  \param  bp   BIO object to which the information is printed
        + *  \param  key  EC_KEY object
        + *  \return 1 on success and 0 if an error occurred
        + */
        +int	ECParameters_print(BIO *bp, const EC_KEY *key);
        +
        +/** Prints out the contents of a EC_KEY object
        + *  \param  bp   BIO object to which the information is printed
        + *  \param  key  EC_KEY object
        + *  \param  off  line offset 
        + *  \return 1 on success and 0 if an error occurred
        + */
        +int	EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
        +
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +/** Prints out the ec parameters on human readable form.
        + *  \param  fp   file descriptor to which the information is printed
        + *  \param  key  EC_KEY object
        + *  \return 1 on success and 0 if an error occurred
        + */
        +int	ECParameters_print_fp(FILE *fp, const EC_KEY *key);
        +
        +/** Prints out the contents of a EC_KEY object
        + *  \param  fp   file descriptor to which the information is printed
        + *  \param  key  EC_KEY object
        + *  \param  off  line offset 
        + *  \return 1 on success and 0 if an error occurred
        + */
        +int	EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
        +
        +#endif
        +
        +#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
        +
        +#ifndef __cplusplus
        +#if defined(__SUNPRO_C)
        +#  if __SUNPRO_C >= 0x520
        +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
        +#  endif
        +# endif
        +#endif
        +
        +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
        +				EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
        +
        +
        +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID		(EVP_PKEY_ALG_CTRL + 1)
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_EC_strings(void);
        +
        +/* Error codes for the EC functions. */
        +
        +/* Function codes. */
        +#define EC_F_BN_TO_FELEM				 224
        +#define EC_F_COMPUTE_WNAF				 143
        +#define EC_F_D2I_ECPARAMETERS				 144
        +#define EC_F_D2I_ECPKPARAMETERS				 145
        +#define EC_F_D2I_ECPRIVATEKEY				 146
        +#define EC_F_DO_EC_KEY_PRINT				 221
        +#define EC_F_ECKEY_PARAM2TYPE				 223
        +#define EC_F_ECKEY_PARAM_DECODE				 212
        +#define EC_F_ECKEY_PRIV_DECODE				 213
        +#define EC_F_ECKEY_PRIV_ENCODE				 214
        +#define EC_F_ECKEY_PUB_DECODE				 215
        +#define EC_F_ECKEY_PUB_ENCODE				 216
        +#define EC_F_ECKEY_TYPE2PARAM				 220
        +#define EC_F_ECPARAMETERS_PRINT				 147
        +#define EC_F_ECPARAMETERS_PRINT_FP			 148
        +#define EC_F_ECPKPARAMETERS_PRINT			 149
        +#define EC_F_ECPKPARAMETERS_PRINT_FP			 150
        +#define EC_F_ECP_NIST_MOD_192				 203
        +#define EC_F_ECP_NIST_MOD_224				 204
        +#define EC_F_ECP_NIST_MOD_256				 205
        +#define EC_F_ECP_NIST_MOD_521				 206
        +#define EC_F_EC_ASN1_GROUP2CURVE			 153
        +#define EC_F_EC_ASN1_GROUP2FIELDID			 154
        +#define EC_F_EC_ASN1_GROUP2PARAMETERS			 155
        +#define EC_F_EC_ASN1_GROUP2PKPARAMETERS			 156
        +#define EC_F_EC_ASN1_PARAMETERS2GROUP			 157
        +#define EC_F_EC_ASN1_PKPARAMETERS2GROUP			 158
        +#define EC_F_EC_EX_DATA_SET_DATA			 211
        +#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY		 208
        +#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT	 159
        +#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE		 195
        +#define EC_F_EC_GF2M_SIMPLE_OCT2POINT			 160
        +#define EC_F_EC_GF2M_SIMPLE_POINT2OCT			 161
        +#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
        +#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
        +#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES	 164
        +#define EC_F_EC_GFP_MONT_FIELD_DECODE			 133
        +#define EC_F_EC_GFP_MONT_FIELD_ENCODE			 134
        +#define EC_F_EC_GFP_MONT_FIELD_MUL			 131
        +#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE		 209
        +#define EC_F_EC_GFP_MONT_FIELD_SQR			 132
        +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE		 189
        +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP		 135
        +#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE		 225
        +#define EC_F_EC_GFP_NISTP224_POINTS_MUL			 228
        +#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
        +#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE		 230
        +#define EC_F_EC_GFP_NISTP256_POINTS_MUL			 231
        +#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
        +#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE		 233
        +#define EC_F_EC_GFP_NISTP521_POINTS_MUL			 234
        +#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
        +#define EC_F_EC_GFP_NIST_FIELD_MUL			 200
        +#define EC_F_EC_GFP_NIST_FIELD_SQR			 201
        +#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE		 202
        +#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT	 165
        +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE		 166
        +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP		 100
        +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR		 101
        +#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE			 102
        +#define EC_F_EC_GFP_SIMPLE_OCT2POINT			 103
        +#define EC_F_EC_GFP_SIMPLE_POINT2OCT			 104
        +#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE		 137
        +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES	 167
        +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
        +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES	 168
        +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
        +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES	 169
        +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
        +#define EC_F_EC_GROUP_CHECK				 170
        +#define EC_F_EC_GROUP_CHECK_DISCRIMINANT		 171
        +#define EC_F_EC_GROUP_COPY				 106
        +#define EC_F_EC_GROUP_GET0_GENERATOR			 139
        +#define EC_F_EC_GROUP_GET_COFACTOR			 140
        +#define EC_F_EC_GROUP_GET_CURVE_GF2M			 172
        +#define EC_F_EC_GROUP_GET_CURVE_GFP			 130
        +#define EC_F_EC_GROUP_GET_DEGREE			 173
        +#define EC_F_EC_GROUP_GET_ORDER				 141
        +#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS		 193
        +#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS		 194
        +#define EC_F_EC_GROUP_NEW				 108
        +#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME			 174
        +#define EC_F_EC_GROUP_NEW_FROM_DATA			 175
        +#define EC_F_EC_GROUP_PRECOMPUTE_MULT			 142
        +#define EC_F_EC_GROUP_SET_CURVE_GF2M			 176
        +#define EC_F_EC_GROUP_SET_CURVE_GFP			 109
        +#define EC_F_EC_GROUP_SET_EXTRA_DATA			 110
        +#define EC_F_EC_GROUP_SET_GENERATOR			 111
        +#define EC_F_EC_KEY_CHECK_KEY				 177
        +#define EC_F_EC_KEY_COPY				 178
        +#define EC_F_EC_KEY_GENERATE_KEY			 179
        +#define EC_F_EC_KEY_NEW					 182
        +#define EC_F_EC_KEY_PRINT				 180
        +#define EC_F_EC_KEY_PRINT_FP				 181
        +#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES	 229
        +#define EC_F_EC_POINTS_MAKE_AFFINE			 136
        +#define EC_F_EC_POINT_ADD				 112
        +#define EC_F_EC_POINT_CMP				 113
        +#define EC_F_EC_POINT_COPY				 114
        +#define EC_F_EC_POINT_DBL				 115
        +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M	 183
        +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP	 116
        +#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP	 117
        +#define EC_F_EC_POINT_INVERT				 210
        +#define EC_F_EC_POINT_IS_AT_INFINITY			 118
        +#define EC_F_EC_POINT_IS_ON_CURVE			 119
        +#define EC_F_EC_POINT_MAKE_AFFINE			 120
        +#define EC_F_EC_POINT_MUL				 184
        +#define EC_F_EC_POINT_NEW				 121
        +#define EC_F_EC_POINT_OCT2POINT				 122
        +#define EC_F_EC_POINT_POINT2OCT				 123
        +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M	 185
        +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP	 124
        +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M	 186
        +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP	 125
        +#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP	 126
        +#define EC_F_EC_POINT_SET_TO_INFINITY			 127
        +#define EC_F_EC_PRE_COMP_DUP				 207
        +#define EC_F_EC_PRE_COMP_NEW				 196
        +#define EC_F_EC_WNAF_MUL				 187
        +#define EC_F_EC_WNAF_PRECOMPUTE_MULT			 188
        +#define EC_F_I2D_ECPARAMETERS				 190
        +#define EC_F_I2D_ECPKPARAMETERS				 191
        +#define EC_F_I2D_ECPRIVATEKEY				 192
        +#define EC_F_I2O_ECPUBLICKEY				 151
        +#define EC_F_NISTP224_PRE_COMP_NEW			 227
        +#define EC_F_NISTP256_PRE_COMP_NEW			 236
        +#define EC_F_NISTP521_PRE_COMP_NEW			 237
        +#define EC_F_O2I_ECPUBLICKEY				 152
        +#define EC_F_OLD_EC_PRIV_DECODE				 222
        +#define EC_F_PKEY_EC_CTRL				 197
        +#define EC_F_PKEY_EC_CTRL_STR				 198
        +#define EC_F_PKEY_EC_DERIVE				 217
        +#define EC_F_PKEY_EC_KEYGEN				 199
        +#define EC_F_PKEY_EC_PARAMGEN				 219
        +#define EC_F_PKEY_EC_SIGN				 218
        +
        +/* Reason codes. */
        +#define EC_R_ASN1_ERROR					 115
        +#define EC_R_ASN1_UNKNOWN_FIELD				 116
        +#define EC_R_BIGNUM_OUT_OF_RANGE			 144
        +#define EC_R_BUFFER_TOO_SMALL				 100
        +#define EC_R_COORDINATES_OUT_OF_RANGE			 146
        +#define EC_R_D2I_ECPKPARAMETERS_FAILURE			 117
        +#define EC_R_DECODE_ERROR				 142
        +#define EC_R_DISCRIMINANT_IS_ZERO			 118
        +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE		 119
        +#define EC_R_FIELD_TOO_LARGE				 143
        +#define EC_R_GF2M_NOT_SUPPORTED				 147
        +#define EC_R_GROUP2PKPARAMETERS_FAILURE			 120
        +#define EC_R_I2D_ECPKPARAMETERS_FAILURE			 121
        +#define EC_R_INCOMPATIBLE_OBJECTS			 101
        +#define EC_R_INVALID_ARGUMENT				 112
        +#define EC_R_INVALID_COMPRESSED_POINT			 110
        +#define EC_R_INVALID_COMPRESSION_BIT			 109
        +#define EC_R_INVALID_CURVE				 141
        +#define EC_R_INVALID_DIGEST_TYPE			 138
        +#define EC_R_INVALID_ENCODING				 102
        +#define EC_R_INVALID_FIELD				 103
        +#define EC_R_INVALID_FORM				 104
        +#define EC_R_INVALID_GROUP_ORDER			 122
        +#define EC_R_INVALID_PENTANOMIAL_BASIS			 132
        +#define EC_R_INVALID_PRIVATE_KEY			 123
        +#define EC_R_INVALID_TRINOMIAL_BASIS			 137
        +#define EC_R_KEYS_NOT_SET				 140
        +#define EC_R_MISSING_PARAMETERS				 124
        +#define EC_R_MISSING_PRIVATE_KEY			 125
        +#define EC_R_NOT_A_NIST_PRIME				 135
        +#define EC_R_NOT_A_SUPPORTED_NIST_PRIME			 136
        +#define EC_R_NOT_IMPLEMENTED				 126
        +#define EC_R_NOT_INITIALIZED				 111
        +#define EC_R_NO_FIELD_MOD				 133
        +#define EC_R_NO_PARAMETERS_SET				 139
        +#define EC_R_PASSED_NULL_PARAMETER			 134
        +#define EC_R_PKPARAMETERS2GROUP_FAILURE			 127
        +#define EC_R_POINT_AT_INFINITY				 106
        +#define EC_R_POINT_IS_NOT_ON_CURVE			 107
        +#define EC_R_SLOT_FULL					 108
        +#define EC_R_UNDEFINED_GENERATOR			 113
        +#define EC_R_UNDEFINED_ORDER				 128
        +#define EC_R_UNKNOWN_GROUP				 129
        +#define EC_R_UNKNOWN_ORDER				 114
        +#define EC_R_UNSUPPORTED_FIELD				 131
        +#define EC_R_WRONG_CURVE_PARAMETERS			 145
        +#define EC_R_WRONG_ORDER				 130
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ec2_mult.c b/vendor/openssl/openssl/crypto/ec/ec2_mult.c
        new file mode 100644
        index 000000000..26f4a783f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec2_mult.c
        @@ -0,0 +1,390 @@
        +/* crypto/ec/ec2_mult.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The software is originally written by Sheueling Chang Shantz and
        + * Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <openssl/err.h>
        +
        +#include "ec_lcl.h"
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +
        +/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective 
        + * coordinates.
        + * Uses algorithm Mdouble in appendix of 
        + *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
        + *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
        + * modified to not require precomputation of c=b^{2^{m-1}}.
        + */
        +static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
        +	{
        +	BIGNUM *t1;
        +	int ret = 0;
        +	
        +	/* Since Mdouble is static we can guarantee that ctx != NULL. */
        +	BN_CTX_start(ctx);
        +	t1 = BN_CTX_get(ctx);
        +	if (t1 == NULL) goto err;
        +
        +	if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
        +	if (!group->meth->field_sqr(group, t1, z, ctx)) goto err;
        +	if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err;
        +	if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
        +	if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err;
        +	if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err;
        +	if (!BN_GF2m_add(x, x, t1)) goto err;
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery 
        + * projective coordinates.
        + * Uses algorithm Madd in appendix of 
        + *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
        + *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
        + */
        +static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, 
        +	const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
        +	{
        +	BIGNUM *t1, *t2;
        +	int ret = 0;
        +	
        +	/* Since Madd is static we can guarantee that ctx != NULL. */
        +	BN_CTX_start(ctx);
        +	t1 = BN_CTX_get(ctx);
        +	t2 = BN_CTX_get(ctx);
        +	if (t2 == NULL) goto err;
        +
        +	if (!BN_copy(t1, x)) goto err;
        +	if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err;
        +	if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err;
        +	if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err;
        +	if (!BN_GF2m_add(z1, z1, x1)) goto err;
        +	if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err;
        +	if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err;
        +	if (!BN_GF2m_add(x1, x1, t2)) goto err;
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) 
        + * using Montgomery point multiplication algorithm Mxy() in appendix of 
        + *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
        + *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
        + * Returns:
        + *     0 on error
        + *     1 if return value should be the point at infinity
        + *     2 otherwise
        + */
        +static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1, 
        +	BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
        +	{
        +	BIGNUM *t3, *t4, *t5;
        +	int ret = 0;
        +	
        +	if (BN_is_zero(z1))
        +		{
        +		BN_zero(x2);
        +		BN_zero(z2);
        +		return 1;
        +		}
        +	
        +	if (BN_is_zero(z2))
        +		{
        +		if (!BN_copy(x2, x)) return 0;
        +		if (!BN_GF2m_add(z2, x, y)) return 0;
        +		return 2;
        +		}
        +		
        +	/* Since Mxy is static we can guarantee that ctx != NULL. */
        +	BN_CTX_start(ctx);
        +	t3 = BN_CTX_get(ctx);
        +	t4 = BN_CTX_get(ctx);
        +	t5 = BN_CTX_get(ctx);
        +	if (t5 == NULL) goto err;
        +
        +	if (!BN_one(t5)) goto err;
        +
        +	if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;
        +
        +	if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
        +	if (!BN_GF2m_add(z1, z1, x1)) goto err;
        +	if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
        +	if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
        +	if (!BN_GF2m_add(z2, z2, x2)) goto err;
        +
        +	if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
        +	if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
        +	if (!BN_GF2m_add(t4, t4, y)) goto err;
        +	if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
        +	if (!BN_GF2m_add(t4, t4, z2)) goto err;
        +
        +	if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
        +	if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
        +	if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
        +	if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
        +	if (!BN_GF2m_add(z2, x2, x)) goto err;
        +
        +	if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
        +	if (!BN_GF2m_add(z2, z2, y)) goto err;
        +
        +	ret = 2;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +/* Computes scalar*point and stores the result in r.
        + * point can not equal r.
        + * Uses algorithm 2P of
        + *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
        + *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
        + */
        +static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	const EC_POINT *point, BN_CTX *ctx)
        +	{
        +	BIGNUM *x1, *x2, *z1, *z2;
        +	int ret = 0, i;
        +	BN_ULONG mask,word;
        +
        +	if (r == point)
        +		{
        +		ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
        +		return 0;
        +		}
        +	
        +	/* if result should be point at infinity */
        +	if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || 
        +		EC_POINT_is_at_infinity(group, point))
        +		{
        +		return EC_POINT_set_to_infinity(group, r);
        +		}
        +
        +	/* only support affine coordinates */
        +	if (!point->Z_is_one) return 0;
        +
        +	/* Since point_multiply is static we can guarantee that ctx != NULL. */
        +	BN_CTX_start(ctx);
        +	x1 = BN_CTX_get(ctx);
        +	z1 = BN_CTX_get(ctx);
        +	if (z1 == NULL) goto err;
        +
        +	x2 = &r->X;
        +	z2 = &r->Y;
        +
        +	if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
        +	if (!BN_one(z1)) goto err; /* z1 = 1 */
        +	if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
        +	if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err;
        +	if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
        +
        +	/* find top most bit and go one past it */
        +	i = scalar->top - 1;
        +	mask = BN_TBIT;
        +	word = scalar->d[i];
        +	while (!(word & mask)) mask >>= 1;
        +	mask >>= 1;
        +	/* if top most bit was at word break, go to next word */
        +	if (!mask) 
        +		{
        +		i--;
        +		mask = BN_TBIT;
        +		}
        +
        +	for (; i >= 0; i--)
        +		{
        +		word = scalar->d[i];
        +		while (mask)
        +			{
        +			if (word & mask)
        +				{
        +				if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
        +				if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
        +				}
        +			else
        +				{
        +				if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
        +				if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
        +				}
        +			mask >>= 1;
        +			}
        +		mask = BN_TBIT;
        +		}
        +
        +	/* convert out of "projective" coordinates */
        +	i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
        +	if (i == 0) goto err;
        +	else if (i == 1) 
        +		{
        +		if (!EC_POINT_set_to_infinity(group, r)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_one(&r->Z)) goto err;
        +		r->Z_is_one = 1;
        +		}
        +
        +	/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
        +	BN_set_negative(&r->X, 0);
        +	BN_set_negative(&r->Y, 0);
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +	}
        +
        +
        +/* Computes the sum
        + *     scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
        + * gracefully ignoring NULL scalar values.
        + */
        +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	int ret = 0;
        +	size_t i;
        +	EC_POINT *p=NULL;
        +	EC_POINT *acc = NULL;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	/* This implementation is more efficient than the wNAF implementation for 2
        +	 * or fewer points.  Use the ec_wNAF_mul implementation for 3 or more points,
        +	 * or if we can perform a fast multiplication based on precomputation.
        +	 */
        +	if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
        +		{
        +		ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
        +		goto err;
        +		}
        +
        +	if ((p = EC_POINT_new(group)) == NULL) goto err;
        +	if ((acc = EC_POINT_new(group)) == NULL) goto err;
        +
        +	if (!EC_POINT_set_to_infinity(group, acc)) goto err;
        +
        +	if (scalar)
        +		{
        +		if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
        +		if (BN_is_negative(scalar))
        +			if (!group->meth->invert(group, p, ctx)) goto err;
        +		if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
        +		}
        +
        +	for (i = 0; i < num; i++)
        +		{
        +		if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
        +		if (BN_is_negative(scalars[i]))
        +			if (!group->meth->invert(group, p, ctx)) goto err;
        +		if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
        +		}
        +
        +	if (!EC_POINT_copy(r, acc)) goto err;
        +
        +	ret = 1;
        +
        +  err:
        +	if (p) EC_POINT_free(p);
        +	if (acc) EC_POINT_free(acc);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Precomputation for point multiplication: fall back to wNAF methods
        + * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
        +
        +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	return ec_wNAF_precompute_mult(group, ctx);
        + 	}
        +
        +int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
        +	{
        +	return ec_wNAF_have_precompute_mult(group);
        + 	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ec2_oct.c b/vendor/openssl/openssl/crypto/ec/ec2_oct.c
        new file mode 100644
        index 000000000..f1d75e5dd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec2_oct.c
        @@ -0,0 +1,407 @@
        +/* crypto/ec/ec2_oct.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The software is originally written by Sheueling Chang Shantz and
        + * Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 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 <openssl/err.h>
        +
        +#include "ec_lcl.h"
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +/* Calculates and sets the affine coordinates of an EC_POINT from the given
        + * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1. 
        + * Note that the simple implementation only uses affine coordinates.
        + *
        + * The method is from the following publication:
        + * 
        + *     Harper, Menezes, Vanstone:
        + *     "Public-Key Cryptosystems with Very Small Key Lengths",
        + *     EUROCRYPT '92, Springer-Verlag LNCS 658,
        + *     published February 1993
        + *
        + * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
        + * the same method, but claim no priority date earlier than July 29, 1994
        + * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
        + */
        +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x_, int y_bit, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *tmp, *x, *y, *z;
        +	int ret = 0, z0;
        +
        +	/* clear error queue */
        +	ERR_clear_error();
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	y_bit = (y_bit != 0) ? 1 : 0;
        +
        +	BN_CTX_start(ctx);
        +	tmp = BN_CTX_get(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	z = BN_CTX_get(ctx);
        +	if (z == NULL) goto err;
        +
        +	if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
        +	if (BN_is_zero(x))
        +		{
        +		if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
        +		if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
        +		if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
        +		if (!BN_GF2m_add(tmp, x, tmp)) goto err;
        +		if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
        +			{
        +			unsigned long err = ERR_peek_last_error();
        +			
        +			if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
        +				{
        +				ERR_clear_error();
        +				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
        +				}
        +			else
        +				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		z0 = (BN_is_odd(z)) ? 1 : 0;
        +		if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
        +		if (z0 != y_bit)
        +			{
        +			if (!BN_GF2m_add(y, y, x)) goto err;
        +			}
        +		}
        +
        +	if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Converts an EC_POINT to an octet string.  
        + * If buf is NULL, the encoded length will be returned.
        + * If the length len of buf is smaller than required an error will be returned.
        + */
        +size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
        +	unsigned char *buf, size_t len, BN_CTX *ctx)
        +	{
        +	size_t ret;
        +	BN_CTX *new_ctx = NULL;
        +	int used_ctx = 0;
        +	BIGNUM *x, *y, *yxi;
        +	size_t field_len, i, skip;
        +
        +	if ((form != POINT_CONVERSION_COMPRESSED)
        +		&& (form != POINT_CONVERSION_UNCOMPRESSED)
        +		&& (form != POINT_CONVERSION_HYBRID))
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
        +		goto err;
        +		}
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		/* encodes to a single 0 octet */
        +		if (buf != NULL)
        +			{
        +			if (len < 1)
        +				{
        +				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
        +				return 0;
        +				}
        +			buf[0] = 0;
        +			}
        +		return 1;
        +		}
        +
        +
        +	/* ret := required output buffer length */
        +	field_len = (EC_GROUP_get_degree(group) + 7) / 8;
        +	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
        +
        +	/* if 'buf' is NULL, just return required length */
        +	if (buf != NULL)
        +		{
        +		if (len < ret)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
        +			goto err;
        +			}
        +
        +		if (ctx == NULL)
        +			{
        +			ctx = new_ctx = BN_CTX_new();
        +			if (ctx == NULL)
        +				return 0;
        +			}
        +
        +		BN_CTX_start(ctx);
        +		used_ctx = 1;
        +		x = BN_CTX_get(ctx);
        +		y = BN_CTX_get(ctx);
        +		yxi = BN_CTX_get(ctx);
        +		if (yxi == NULL) goto err;
        +
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
        +
        +		buf[0] = form;
        +		if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
        +			{
        +			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
        +			if (BN_is_odd(yxi)) buf[0]++;
        +			}
        +
        +		i = 1;
        +		
        +		skip = field_len - BN_num_bytes(x);
        +		if (skip > field_len)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		while (skip > 0)
        +			{
        +			buf[i++] = 0;
        +			skip--;
        +			}
        +		skip = BN_bn2bin(x, buf + i);
        +		i += skip;
        +		if (i != 1 + field_len)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +
        +		if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
        +			{
        +			skip = field_len - BN_num_bytes(y);
        +			if (skip > field_len)
        +				{
        +				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			while (skip > 0)
        +				{
        +				buf[i++] = 0;
        +				skip--;
        +				}
        +			skip = BN_bn2bin(y, buf + i);
        +			i += skip;
        +			}
        +
        +		if (i != ret)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		}
        +	
        +	if (used_ctx)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +
        + err:
        +	if (used_ctx)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return 0;
        +	}
        +
        +
        +/* Converts an octet string representation to an EC_POINT. 
        + * Note that the simple implementation only uses affine coordinates.
        + */
        +int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
        +	const unsigned char *buf, size_t len, BN_CTX *ctx)
        +	{
        +	point_conversion_form_t form;
        +	int y_bit;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y, *yxi;
        +	size_t field_len, enc_len;
        +	int ret = 0;
        +
        +	if (len == 0)
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
        +		return 0;
        +		}
        +	form = buf[0];
        +	y_bit = form & 1;
        +	form = form & ~1U;
        +	if ((form != 0)	&& (form != POINT_CONVERSION_COMPRESSED)
        +		&& (form != POINT_CONVERSION_UNCOMPRESSED)
        +		&& (form != POINT_CONVERSION_HYBRID))
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		return 0;
        +		}
        +	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		return 0;
        +		}
        +
        +	if (form == 0)
        +		{
        +		if (len != 1)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +			return 0;
        +			}
        +
        +		return EC_POINT_set_to_infinity(group, point);
        +		}
        +	
        +	field_len = (EC_GROUP_get_degree(group) + 7) / 8;
        +	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
        +
        +	if (len != enc_len)
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		return 0;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	yxi = BN_CTX_get(ctx);
        +	if (yxi == NULL) goto err;
        +
        +	if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
        +	if (BN_ucmp(x, &group->field) >= 0)
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		goto err;
        +		}
        +
        +	if (form == POINT_CONVERSION_COMPRESSED)
        +		{
        +		if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
        +		if (BN_ucmp(y, &group->field) >= 0)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +			goto err;
        +			}
        +		if (form == POINT_CONVERSION_HYBRID)
        +			{
        +			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
        +			if (y_bit != BN_is_odd(yxi))
        +				{
        +				ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +				goto err;
        +				}
        +			}
        +
        +		if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
        +		}
        +	
        +	if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +	
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ec2_smpl.c b/vendor/openssl/openssl/crypto/ec/ec2_smpl.c
        new file mode 100644
        index 000000000..e0e59c7d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec2_smpl.c
        @@ -0,0 +1,719 @@
        +/* crypto/ec/ec2_smpl.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The software is originally written by Sheueling Chang Shantz and
        + * Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 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 <openssl/err.h>
        +
        +#include "ec_lcl.h"
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +
        +const EC_METHOD *EC_GF2m_simple_method(void)
        +	{
        +#ifdef OPENSSL_FIPS
        +	return fips_ec_gf2m_simple_method();
        +#else
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_characteristic_two_field,
        +		ec_GF2m_simple_group_init,
        +		ec_GF2m_simple_group_finish,
        +		ec_GF2m_simple_group_clear_finish,
        +		ec_GF2m_simple_group_copy,
        +		ec_GF2m_simple_group_set_curve,
        +		ec_GF2m_simple_group_get_curve,
        +		ec_GF2m_simple_group_get_degree,
        +		ec_GF2m_simple_group_check_discriminant,
        +		ec_GF2m_simple_point_init,
        +		ec_GF2m_simple_point_finish,
        +		ec_GF2m_simple_point_clear_finish,
        +		ec_GF2m_simple_point_copy,
        +		ec_GF2m_simple_point_set_to_infinity,
        +		0 /* set_Jprojective_coordinates_GFp */,
        +		0 /* get_Jprojective_coordinates_GFp */,
        +		ec_GF2m_simple_point_set_affine_coordinates,
        +		ec_GF2m_simple_point_get_affine_coordinates,
        +		0,0,0,
        +		ec_GF2m_simple_add,
        +		ec_GF2m_simple_dbl,
        +		ec_GF2m_simple_invert,
        +		ec_GF2m_simple_is_at_infinity,
        +		ec_GF2m_simple_is_on_curve,
        +		ec_GF2m_simple_cmp,
        +		ec_GF2m_simple_make_affine,
        +		ec_GF2m_simple_points_make_affine,
        +
        +		/* the following three method functions are defined in ec2_mult.c */
        +		ec_GF2m_simple_mul,
        +		ec_GF2m_precompute_mult,
        +		ec_GF2m_have_precompute_mult,
        +
        +		ec_GF2m_simple_field_mul,
        +		ec_GF2m_simple_field_sqr,
        +		ec_GF2m_simple_field_div,
        +		0 /* field_encode */,
        +		0 /* field_decode */,
        +		0 /* field_set_to_one */ };
        +
        +	return &ret;
        +#endif
        +	}
        +
        +
        +/* Initialize a GF(2^m)-based EC_GROUP structure.
        + * Note that all other members are handled by EC_GROUP_new.
        + */
        +int ec_GF2m_simple_group_init(EC_GROUP *group)
        +	{
        +	BN_init(&group->field);
        +	BN_init(&group->a);
        +	BN_init(&group->b);
        +	return 1;
        +	}
        +
        +
        +/* Free a GF(2^m)-based EC_GROUP structure.
        + * Note that all other members are handled by EC_GROUP_free.
        + */
        +void ec_GF2m_simple_group_finish(EC_GROUP *group)
        +	{
        +	BN_free(&group->field);
        +	BN_free(&group->a);
        +	BN_free(&group->b);
        +	}
        +
        +
        +/* Clear and free a GF(2^m)-based EC_GROUP structure.
        + * Note that all other members are handled by EC_GROUP_clear_free.
        + */
        +void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
        +	{
        +	BN_clear_free(&group->field);
        +	BN_clear_free(&group->a);
        +	BN_clear_free(&group->b);
        +	group->poly[0] = 0;
        +	group->poly[1] = 0;
        +	group->poly[2] = 0;
        +	group->poly[3] = 0;
        +	group->poly[4] = 0;
        +	group->poly[5] = -1;
        +	}
        +
        +
        +/* Copy a GF(2^m)-based EC_GROUP structure.
        + * Note that all other members are handled by EC_GROUP_copy.
        + */
        +int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
        +	{
        +	int i;
        +	if (!BN_copy(&dest->field, &src->field)) return 0;
        +	if (!BN_copy(&dest->a, &src->a)) return 0;
        +	if (!BN_copy(&dest->b, &src->b)) return 0;
        +	dest->poly[0] = src->poly[0];
        +	dest->poly[1] = src->poly[1];
        +	dest->poly[2] = src->poly[2];
        +	dest->poly[3] = src->poly[3];
        +	dest->poly[4] = src->poly[4];
        +	dest->poly[5] = src->poly[5];
        +	if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
        +	if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
        +	for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
        +	for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
        +	return 1;
        +	}
        +
        +
        +/* Set the curve parameters of an EC_GROUP structure. */
        +int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
        +	const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0, i;
        +
        +	/* group->field */
        +	if (!BN_copy(&group->field, p)) goto err;
        +	i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
        +	if ((i != 5) && (i != 3))
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
        +		goto err;
        +		}
        +
        +	/* group->a */
        +	if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
        +	if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
        +	for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
        +	
        +	/* group->b */
        +	if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
        +	if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
        +	for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
        +		
        +	ret = 1;
        +  err:
        +	return ret;
        +	}
        +
        +
        +/* Get the curve parameters of an EC_GROUP structure.
        + * If p, a, or b are NULL then there values will not be set but the method will return with success.
        + */
        +int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	
        +	if (p != NULL)
        +		{
        +		if (!BN_copy(p, &group->field)) return 0;
        +		}
        +
        +	if (a != NULL)
        +		{
        +		if (!BN_copy(a, &group->a)) goto err;
        +		}
        +
        +	if (b != NULL)
        +		{
        +		if (!BN_copy(b, &group->b)) goto err;
        +		}
        +	
        +	ret = 1;
        +	
        +  err:
        +	return ret;
        +	}
        +
        +
        +/* Gets the degree of the field.  For a curve over GF(2^m) this is the value m. */
        +int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
        +	{
        +	return BN_num_bits(&group->field)-1;
        +	}
        +
        +
        +/* Checks the discriminant of the curve.
        + * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) 
        + */
        +int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BIGNUM *b;
        +	BN_CTX *new_ctx = NULL;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			{
        +			ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	BN_CTX_start(ctx);
        +	b = BN_CTX_get(ctx);
        +	if (b == NULL) goto err;
        +
        +	if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
        +	
        +	/* check the discriminant:
        +	 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) 
        +	 */
        +	if (BN_is_zero(b)) goto err;
        +
        +	ret = 1;
        +
        +err:
        +	if (ctx != NULL)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Initializes an EC_POINT. */
        +int ec_GF2m_simple_point_init(EC_POINT *point)
        +	{
        +	BN_init(&point->X);
        +	BN_init(&point->Y);
        +	BN_init(&point->Z);
        +	return 1;
        +	}
        +
        +
        +/* Frees an EC_POINT. */
        +void ec_GF2m_simple_point_finish(EC_POINT *point)
        +	{
        +	BN_free(&point->X);
        +	BN_free(&point->Y);
        +	BN_free(&point->Z);
        +	}
        +
        +
        +/* Clears and frees an EC_POINT. */
        +void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
        +	{
        +	BN_clear_free(&point->X);
        +	BN_clear_free(&point->Y);
        +	BN_clear_free(&point->Z);
        +	point->Z_is_one = 0;
        +	}
        +
        +
        +/* Copy the contents of one EC_POINT into another.  Assumes dest is initialized. */
        +int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
        +	{
        +	if (!BN_copy(&dest->X, &src->X)) return 0;
        +	if (!BN_copy(&dest->Y, &src->Y)) return 0;
        +	if (!BN_copy(&dest->Z, &src->Z)) return 0;
        +	dest->Z_is_one = src->Z_is_one;
        +
        +	return 1;
        +	}
        +
        +
        +/* Set an EC_POINT to the point at infinity.  
        + * A point at infinity is represented by having Z=0.
        + */
        +int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
        +	{
        +	point->Z_is_one = 0;
        +	BN_zero(&point->Z);
        +	return 1;
        +	}
        +
        +
        +/* Set the coordinates of an EC_POINT using affine coordinates. 
        + * Note that the simple implementation only uses affine coordinates.
        + */
        +int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
        +	{
        +	int ret = 0;	
        +	if (x == NULL || y == NULL)
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +
        +	if (!BN_copy(&point->X, x)) goto err;
        +	BN_set_negative(&point->X, 0);
        +	if (!BN_copy(&point->Y, y)) goto err;
        +	BN_set_negative(&point->Y, 0);
        +	if (!BN_copy(&point->Z, BN_value_one())) goto err;
        +	BN_set_negative(&point->Z, 0);
        +	point->Z_is_one = 1;
        +	ret = 1;
        +
        +  err:
        +	return ret;
        +	}
        +
        +
        +/* Gets the affine coordinates of an EC_POINT. 
        + * Note that the simple implementation only uses affine coordinates.
        + */
        +int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
        +	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
        +		return 0;
        +		}
        +
        +	if (BN_cmp(&point->Z, BN_value_one())) 
        +		{
        +		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (x != NULL)
        +		{
        +		if (!BN_copy(x, &point->X)) goto err;
        +		BN_set_negative(x, 0);
        +		}
        +	if (y != NULL)
        +		{
        +		if (!BN_copy(y, &point->Y)) goto err;
        +		BN_set_negative(y, 0);
        +		}
        +	ret = 1;
        +		
        + err:
        +	return ret;
        +	}
        +
        +/* Computes a + b and stores the result in r.  r could be a or b, a could be b.
        + * Uses algorithm A.10.2 of IEEE P1363.
        + */
        +int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
        +	int ret = 0;
        +	
        +	if (EC_POINT_is_at_infinity(group, a))
        +		{
        +		if (!EC_POINT_copy(r, b)) return 0;
        +		return 1;
        +		}
        +
        +	if (EC_POINT_is_at_infinity(group, b))
        +		{
        +		if (!EC_POINT_copy(r, a)) return 0;
        +		return 1;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	x0 = BN_CTX_get(ctx);
        +	y0 = BN_CTX_get(ctx);
        +	x1 = BN_CTX_get(ctx);
        +	y1 = BN_CTX_get(ctx);
        +	x2 = BN_CTX_get(ctx);
        +	y2 = BN_CTX_get(ctx);
        +	s = BN_CTX_get(ctx);
        +	t = BN_CTX_get(ctx);
        +	if (t == NULL) goto err;
        +
        +	if (a->Z_is_one) 
        +		{
        +		if (!BN_copy(x0, &a->X)) goto err;
        +		if (!BN_copy(y0, &a->Y)) goto err;
        +		}
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
        +		}
        +	if (b->Z_is_one) 
        +		{
        +		if (!BN_copy(x1, &b->X)) goto err;
        +		if (!BN_copy(y1, &b->Y)) goto err;
        +		}
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
        +		}
        +
        +
        +	if (BN_GF2m_cmp(x0, x1))
        +		{
        +		if (!BN_GF2m_add(t, x0, x1)) goto err;
        +		if (!BN_GF2m_add(s, y0, y1)) goto err;
        +		if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
        +		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
        +		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
        +		if (!BN_GF2m_add(x2, x2, s)) goto err;
        +		if (!BN_GF2m_add(x2, x2, t)) goto err;
        +		}
        +	else
        +		{
        +		if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
        +			{
        +			if (!EC_POINT_set_to_infinity(group, r)) goto err;
        +			ret = 1;
        +			goto err;
        +			}
        +		if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
        +		if (!BN_GF2m_add(s, s, x1)) goto err;
        +		
        +		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
        +		if (!BN_GF2m_add(x2, x2, s)) goto err;
        +		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
        +		}
        +
        +	if (!BN_GF2m_add(y2, x1, x2)) goto err;
        +	if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
        +	if (!BN_GF2m_add(y2, y2, x2)) goto err;
        +	if (!BN_GF2m_add(y2, y2, y1)) goto err;
        +
        +	if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Computes 2 * a and stores the result in r.  r could be a.
        + * Uses algorithm A.10.2 of IEEE P1363.
        + */
        +int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
        +	{
        +	return ec_GF2m_simple_add(group, r, a, a, ctx);
        +	}
        +
        +
        +int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
        +	{
        +	if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
        +		/* point is its own inverse */
        +		return 1;
        +	
        +	if (!EC_POINT_make_affine(group, point, ctx)) return 0;
        +	return BN_GF2m_add(&point->Y, &point->X, &point->Y);
        +	}
        +
        +
        +/* Indicates whether the given point is the point at infinity. */
        +int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
        +	{
        +	return BN_is_zero(&point->Z);
        +	}
        +
        +
        +/* Determines whether the given EC_POINT is an actual point on the curve defined
        + * in the EC_GROUP.  A point is valid if it satisfies the Weierstrass equation:
        + *      y^2 + x*y = x^3 + a*x^2 + b.
        + */
        +int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
        +	{
        +	int ret = -1;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *lh, *y2;
        +	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
        +	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		return 1;
        +
        +	field_mul = group->meth->field_mul;
        +	field_sqr = group->meth->field_sqr;	
        +
        +	/* only support affine coordinates */
        +	if (!point->Z_is_one) return -1;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return -1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	y2 = BN_CTX_get(ctx);
        +	lh = BN_CTX_get(ctx);
        +	if (lh == NULL) goto err;
        +
        +	/* We have a curve defined by a Weierstrass equation
        +	 *      y^2 + x*y = x^3 + a*x^2 + b.
        +	 *  <=> x^3 + a*x^2 + x*y + b + y^2 = 0
        +	 *  <=> ((x + a) * x + y ) * x + b + y^2 = 0
        +	 */
        +	if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
        +	if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
        +	if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
        +	if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
        +	if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
        +	if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
        +	if (!BN_GF2m_add(lh, lh, y2)) goto err;
        +	ret = BN_is_zero(lh);
        + err:
        +	if (ctx) BN_CTX_end(ctx);
        +	if (new_ctx) BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Indicates whether two points are equal.
        + * Return values:
        + *  -1   error
        + *   0   equal (in affine coordinates)
        + *   1   not equal
        + */
        +int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
        +	{
        +	BIGNUM *aX, *aY, *bX, *bY;
        +	BN_CTX *new_ctx = NULL;
        +	int ret = -1;
        +
        +	if (EC_POINT_is_at_infinity(group, a))
        +		{
        +		return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
        +		}
        +
        +	if (EC_POINT_is_at_infinity(group, b))
        +		return 1;
        +	
        +	if (a->Z_is_one && b->Z_is_one)
        +		{
        +		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return -1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	aX = BN_CTX_get(ctx);
        +	aY = BN_CTX_get(ctx);
        +	bX = BN_CTX_get(ctx);
        +	bY = BN_CTX_get(ctx);
        +	if (bY == NULL) goto err;
        +
        +	if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
        +	if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
        +	ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
        +
        +  err:	
        +	if (ctx) BN_CTX_end(ctx);
        +	if (new_ctx) BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Forces the given EC_POINT to internally use affine coordinates. */
        +int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y;
        +	int ret = 0;
        +
        +	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
        +		return 1;
        +	
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	if (y == NULL) goto err;
        +	
        +	if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
        +	if (!BN_copy(&point->X, x)) goto err;
        +	if (!BN_copy(&point->Y, y)) goto err;
        +	if (!BN_one(&point->Z)) goto err;
        +	
        +	ret = 1;		
        +
        +  err:
        +	if (ctx) BN_CTX_end(ctx);
        +	if (new_ctx) BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
        +int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
        +	{
        +	size_t i;
        +
        +	for (i = 0; i < num; i++)
        +		{
        +		if (!group->meth->make_affine(group, points[i], ctx)) return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +
        +/* Wrapper to simple binary polynomial field multiplication implementation. */
        +int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
        +	}
        +
        +
        +/* Wrapper to simple binary polynomial field squaring implementation. */
        +int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        +	{
        +	return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
        +	}
        +
        +
        +/* Wrapper to simple binary polynomial field division implementation. */
        +int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_ameth.c b/vendor/openssl/openssl/crypto/ec/ec_ameth.c
        new file mode 100644
        index 000000000..83909c185
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_ameth.c
        @@ -0,0 +1,660 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/ec.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_CMS
        +#include <openssl/cms.h>
        +#endif
        +#include "asn1_locl.h"
        +
        +static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
        +	{
        +	const EC_GROUP  *group;
        +	int nid;
        +	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
        +	{
        +		ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
        +		return 0;
        +	}
        +	if (EC_GROUP_get_asn1_flag(group)
        +                     && (nid = EC_GROUP_get_curve_name(group)))
        +		/* we have a 'named curve' => just set the OID */
        +		{
        +		*ppval = OBJ_nid2obj(nid);
        +		*pptype = V_ASN1_OBJECT;
        +		}
        +	else	/* explicit parameters */
        +		{
        +		ASN1_STRING *pstr = NULL;
        +		pstr = ASN1_STRING_new();
        +		if (!pstr)
        +			return 0;
        +		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
        +		if (pstr->length < 0)
        +			{
        +			ASN1_STRING_free(pstr);
        +			ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
        +			return 0;
        +			}
        +		*ppval = pstr;
        +		*pptype = V_ASN1_SEQUENCE;
        +		}
        +	return 1;
        +	}
        +
        +static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
        +	{
        +	EC_KEY *ec_key = pkey->pkey.ec;
        +	void *pval = NULL;
        +	int ptype;
        +	unsigned char *penc = NULL, *p;
        +	int penclen;
        +
        +	if (!eckey_param2type(&ptype, &pval, ec_key))
        +		{
        +		ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
        +		return 0;
        +		}
        +	penclen = i2o_ECPublicKey(ec_key, NULL);
        +	if (penclen <= 0)
        +		goto err;
        +	penc = OPENSSL_malloc(penclen);
        +	if (!penc)
        +		goto err;
        +	p = penc;
        +	penclen = i2o_ECPublicKey(ec_key, &p);
        +	if (penclen <= 0)
        +		goto err;
        +	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
        +				ptype, pval, penc, penclen))
        +		return 1;
        +	err:
        +	if (ptype == V_ASN1_OBJECT)
        +		ASN1_OBJECT_free(pval);
        +	else
        +		ASN1_STRING_free(pval);
        +	if (penc)
        +		OPENSSL_free(penc);
        +	return 0;
        +	}
        +
        +static EC_KEY *eckey_type2param(int ptype, void *pval)
        +	{
        +	EC_KEY *eckey = NULL;
        +	if (ptype == V_ASN1_SEQUENCE)
        +		{
        +		ASN1_STRING *pstr = pval;
        +		const unsigned char *pm = NULL;
        +		int pmlen;
        +		pm = pstr->data;
        +		pmlen = pstr->length;
        +		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
        +			{
        +			ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
        +			goto ecerr;
        +			}
        +		}
        +	else if (ptype == V_ASN1_OBJECT)
        +		{
        +		ASN1_OBJECT *poid = pval;
        +		EC_GROUP *group;
        +
        +		/* type == V_ASN1_OBJECT => the parameters are given
        +		 * by an asn1 OID
        +		 */
        +		if ((eckey = EC_KEY_new()) == NULL)
        +			{
        +			ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
        +			goto ecerr;
        +			}
        +		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
        +		if (group == NULL)
        +			goto ecerr;
        +		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
        +		if (EC_KEY_set_group(eckey, group) == 0)
        +			goto ecerr;
        +		EC_GROUP_free(group);
        +		}
        +	else
        +		{
        +		ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
        +		goto ecerr;
        +		}
        +
        +	return eckey;
        +
        +	ecerr:
        +	if (eckey)
        +		EC_KEY_free(eckey);
        +	return NULL;
        +	}
        +
        +static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
        +	{
        +	const unsigned char *p = NULL;
        +	void *pval;
        +	int ptype, pklen;
        +	EC_KEY *eckey = NULL;
        +	X509_ALGOR *palg;
        +
        +	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
        +		return 0;
        +	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
        +
        +	eckey = eckey_type2param(ptype, pval);
        +
        +	if (!eckey)
        +		{
        +		ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
        +		return 0;
        +		}
        +
        +	/* We have parameters now set public key */
        +	if (!o2i_ECPublicKey(&eckey, &p, pklen))
        +		{
        +		ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
        +		goto ecerr;
        +		}
        +
        +	EVP_PKEY_assign_EC_KEY(pkey, eckey);
        +	return 1;
        +
        +	ecerr:
        +	if (eckey)
        +		EC_KEY_free(eckey);
        +	return 0;
        +	}
        +
        +static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	int  r;
        +	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
        +	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
        +	               *pb = EC_KEY_get0_public_key(b->pkey.ec);
        +	r = EC_POINT_cmp(group, pa, pb, NULL);
        +	if (r == 0)
        +		return 1;
        +	if (r == 1)
        +		return 0;
        +	return -2;
        +	}
        +
        +static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
        +	{
        +	const unsigned char *p = NULL;
        +	void *pval;
        +	int ptype, pklen;
        +	EC_KEY *eckey = NULL;
        +	X509_ALGOR *palg;
        +
        +	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
        +		return 0;
        +	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
        +
        +	eckey = eckey_type2param(ptype, pval);
        +
        +	if (!eckey)
        +		goto ecliberr;
        +
        +	/* We have parameters now set private key */
        +	if (!d2i_ECPrivateKey(&eckey, &p, pklen))
        +		{
        +		ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
        +		goto ecerr;
        +		}
        +
        +	/* calculate public key (if necessary) */
        +	if (EC_KEY_get0_public_key(eckey) == NULL)
        +		{
        +		const BIGNUM *priv_key;
        +		const EC_GROUP *group;
        +		EC_POINT *pub_key;
        +		/* the public key was not included in the SEC1 private
        +		 * key => calculate the public key */
        +		group   = EC_KEY_get0_group(eckey);
        +		pub_key = EC_POINT_new(group);
        +		if (pub_key == NULL)
        +			{
        +			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
        +			goto ecliberr;
        +			}
        +		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
        +			{
        +			EC_POINT_free(pub_key);
        +			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
        +			goto ecliberr;
        +			}
        +		priv_key = EC_KEY_get0_private_key(eckey);
        +		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
        +			{
        +			EC_POINT_free(pub_key);
        +			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
        +			goto ecliberr;
        +			}
        +		if (EC_KEY_set_public_key(eckey, pub_key) == 0)
        +			{
        +			EC_POINT_free(pub_key);
        +			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
        +			goto ecliberr;
        +			}
        +		EC_POINT_free(pub_key);
        +		}
        +
        +	EVP_PKEY_assign_EC_KEY(pkey, eckey);
        +	return 1;
        +
        +	ecliberr:
        +	ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
        +	ecerr:
        +	if (eckey)
        +		EC_KEY_free(eckey);
        +	return 0;
        +	}
        +
        +static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
        +{
        +	EC_KEY		*ec_key;
        +	unsigned char	*ep, *p;
        +	int 		eplen, ptype;
        +	void		*pval;
        +	unsigned int    tmp_flags, old_flags;
        +
        +	ec_key = pkey->pkey.ec;
        +
        +	if (!eckey_param2type(&ptype, &pval, ec_key))
        +		{
        +		ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
        +		return 0;
        +		}
        +
        +	/* set the private key */
        +
        +	/* do not include the parameters in the SEC1 private key
        +	 * see PKCS#11 12.11 */
        +	old_flags = EC_KEY_get_enc_flags(ec_key);
        +	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
        +	EC_KEY_set_enc_flags(ec_key, tmp_flags);
        +	eplen = i2d_ECPrivateKey(ec_key, NULL);
        +	if (!eplen)
        +	{
        +		EC_KEY_set_enc_flags(ec_key, old_flags);
        +		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
        +		return 0;
        +	}
        +	ep = (unsigned char *) OPENSSL_malloc(eplen);
        +	if (!ep)
        +	{
        +		EC_KEY_set_enc_flags(ec_key, old_flags);
        +		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	p = ep;
        +	if (!i2d_ECPrivateKey(ec_key, &p))
        +	{
        +		EC_KEY_set_enc_flags(ec_key, old_flags);
        +		OPENSSL_free(ep);
        +		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
        +	}
        +	/* restore old encoding flags */
        +	EC_KEY_set_enc_flags(ec_key, old_flags);
        +
        +	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
        +				ptype, pval, ep, eplen))
        +		return 0;
        +
        +	return 1;
        +}
        +
        +static int int_ec_size(const EVP_PKEY *pkey)
        +	{
        +	return ECDSA_size(pkey->pkey.ec);
        +	}
        +
        +static int ec_bits(const EVP_PKEY *pkey)
        +	{
        +	BIGNUM *order = BN_new();
        +	const EC_GROUP *group;
        +	int ret;
        +
        +	if (!order)
        +		{
        +		ERR_clear_error();
        +		return 0;
        +		}
        +	group = EC_KEY_get0_group(pkey->pkey.ec);
        +	if (!EC_GROUP_get_order(group, order, NULL))
        +		{
        +		ERR_clear_error();
        +		return 0;
        +		}
        +
        +	ret = BN_num_bits(order);
        +	BN_free(order);
        +	return ret;
        +	}
        +
        +static int ec_missing_parameters(const EVP_PKEY *pkey)
        +	{
        +	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
        +		return 1;
        +	return 0;
        +	}
        +
        +static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
        +	{
        +	EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
        +	if (group == NULL)
        +		return 0;
        +	if (EC_KEY_set_group(to->pkey.ec, group) == 0)
        +		return 0;
        +	EC_GROUP_free(group);
        +	return 1;
        +	}
        +
        +static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
        +	               *group_b = EC_KEY_get0_group(b->pkey.ec);
        +	if (EC_GROUP_cmp(group_a, group_b, NULL))
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static void int_ec_free(EVP_PKEY *pkey)
        +	{
        +	EC_KEY_free(pkey->pkey.ec);
        +	}
        +
        +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
        +	{
        +	unsigned char *buffer=NULL;
        +	const char *ecstr;
        +	size_t	buf_len=0, i;
        +	int     ret=0, reason=ERR_R_BIO_LIB;
        +	BIGNUM  *pub_key=NULL, *order=NULL;
        +	BN_CTX  *ctx=NULL;
        +	const EC_GROUP *group;
        +	const EC_POINT *public_key;
        +	const BIGNUM *priv_key;
        + 
        +	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
        +		{
        +		reason = ERR_R_PASSED_NULL_PARAMETER;
        +		goto err;
        +		}
        +
        +	ctx = BN_CTX_new();
        +	if (ctx == NULL)
        +		{
        +		reason = ERR_R_MALLOC_FAILURE;
        +		goto err;
        +		}
        +
        +	if (ktype > 0)
        +		{
        +		public_key = EC_KEY_get0_public_key(x);
        +		if ((pub_key = EC_POINT_point2bn(group, public_key,
        +			EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
        +			{
        +			reason = ERR_R_EC_LIB;
        +			goto err;
        +			}
        +		if (pub_key)
        +			buf_len = (size_t)BN_num_bytes(pub_key);
        +		}
        +
        +	if (ktype == 2)
        +		{
        +		priv_key = EC_KEY_get0_private_key(x);
        +		if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
        +			buf_len = i;
        +		}
        +	else
        +		priv_key = NULL;
        +
        +	if (ktype > 0)
        +		{
        +		buf_len += 10;
        +		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
        +			{
        +			reason = ERR_R_MALLOC_FAILURE;
        +			goto err;
        +			}
        +		}
        +	if (ktype == 2)
        +		ecstr = "Private-Key";
        +	else if (ktype == 1)
        +		ecstr = "Public-Key";
        +	else
        +		ecstr = "ECDSA-Parameters";
        +
        +	if (!BIO_indent(bp, off, 128))
        +		goto err;
        +	if ((order = BN_new()) == NULL)
        +		goto err;
        +	if (!EC_GROUP_get_order(group, order, NULL))
        +		goto err;
        +	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
        +		BN_num_bits(order)) <= 0) goto err;
        +  
        +	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 
        +		buffer, off))
        +		goto err;
        +	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
        +		buffer, off))
        +		goto err;
        +	if (!ECPKParameters_print(bp, group, off))
        +		goto err;
        +	ret=1;
        +err:
        +	if (!ret)
        + 		ECerr(EC_F_DO_EC_KEY_PRINT, reason);
        +	if (pub_key) 
        +		BN_free(pub_key);
        +	if (order)
        +		BN_free(order);
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	if (buffer != NULL)
        +		OPENSSL_free(buffer);
        +	return(ret);
        +	}
        +
        +static int eckey_param_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	EC_KEY *eckey;
        +	if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
        +		{
        +		ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_EC_KEY(pkey, eckey);
        +	return 1;
        +	}
        +
        +static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	return i2d_ECParameters(pkey->pkey.ec, pder);
        +	}
        +
        +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
        +	}
        +
        +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
        +	}
        +
        +
        +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
        +	}
        +
        +static int old_ec_priv_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	EC_KEY *ec;
        +	if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
        +		{
        +		ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_EC_KEY(pkey, ec);
        +	return 1;
        +	}
        +
        +static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	return i2d_ECPrivateKey(pkey->pkey.ec, pder);
        +	}
        +
        +static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        +	{
        +	switch (op)
        +		{
        +		case ASN1_PKEY_CTRL_PKCS7_SIGN:
        +		if (arg1 == 0)
        +			{
        +			int snid, hnid;
        +			X509_ALGOR *alg1, *alg2;
        +			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
        +			if (alg1 == NULL || alg1->algorithm == NULL)
        +				return -1;
        +			hnid = OBJ_obj2nid(alg1->algorithm);
        +			if (hnid == NID_undef)
        +				return -1;
        +			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
        +				return -1; 
        +			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
        +			}
        +		return 1;
        +#ifndef OPENSSL_NO_CMS
        +		case ASN1_PKEY_CTRL_CMS_SIGN:
        +		if (arg1 == 0)
        +			{
        +			int snid, hnid;
        +			X509_ALGOR *alg1, *alg2;
        +			CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
        +								&alg1, &alg2);
        +			if (alg1 == NULL || alg1->algorithm == NULL)
        +				return -1;
        +			hnid = OBJ_obj2nid(alg1->algorithm);
        +			if (hnid == NID_undef)
        +				return -1;
        +			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
        +				return -1; 
        +			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
        +			}
        +		return 1;
        +#endif
        +
        +		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        +		*(int *)arg2 = NID_sha1;
        +		return 2;
        +
        +		default:
        +		return -2;
        +
        +		}
        +
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = 
        +	{
        +	EVP_PKEY_EC,
        +	EVP_PKEY_EC,
        +	0,
        +	"EC",
        +	"OpenSSL EC algorithm",
        +
        +	eckey_pub_decode,
        +	eckey_pub_encode,
        +	eckey_pub_cmp,
        +	eckey_pub_print,
        +
        +	eckey_priv_decode,
        +	eckey_priv_encode,
        +	eckey_priv_print,
        +
        +	int_ec_size,
        +	ec_bits,
        +
        +	eckey_param_decode,
        +	eckey_param_encode,
        +	ec_missing_parameters,
        +	ec_copy_parameters,
        +	ec_cmp_parameters,
        +	eckey_param_print,
        +	0,
        +
        +	int_ec_free,
        +	ec_pkey_ctrl,
        +	old_ec_priv_decode,
        +	old_ec_priv_encode
        +	};
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_asn1.c b/vendor/openssl/openssl/crypto/ec/ec_asn1.c
        new file mode 100644
        index 000000000..175eec534
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_asn1.c
        @@ -0,0 +1,1443 @@
        +/* crypto/ec/ec_asn1.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <string.h>
        +#include "ec_lcl.h"
        +#include <openssl/err.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/objects.h>
        +
        +
        +int EC_GROUP_get_basis_type(const EC_GROUP *group)
        +	{
        +	int i=0;
        +
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
        +		NID_X9_62_characteristic_two_field)
        +		/* everything else is currently not supported */
        +		return 0;
        +
        +	while (group->poly[i] != 0)
        +		i++;
        +
        +	if (i == 4)
        +		return NID_X9_62_ppBasis;
        +	else if (i == 2)
        +		return NID_X9_62_tpBasis;
        +	else
        +		/* everything else is currently not supported */
        +		return 0;
        +	}
        +#ifndef OPENSSL_NO_EC2M
        +int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
        +	{
        +	if (group == NULL)
        +		return 0;
        +
        +	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
        +	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
        +		{
        +		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +
        +	if (k)
        +		*k = group->poly[1];
        +
        +	return 1;
        +	}
        +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
        +	unsigned int *k2, unsigned int *k3)
        +	{
        +	if (group == NULL)
        +		return 0;
        +
        +	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
        +	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
        +		{
        +		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +
        +	if (k1)
        +		*k1 = group->poly[3];
        +	if (k2)
        +		*k2 = group->poly[2];
        +	if (k3)
        +		*k3 = group->poly[1];
        +
        +	return 1;
        +	}
        +#endif
        +
        +
        +/* some structures needed for the asn1 encoding */
        +typedef struct x9_62_pentanomial_st {
        +	long k1;
        +	long k2;
        +	long k3;
        +	} X9_62_PENTANOMIAL;
        +
        +typedef struct x9_62_characteristic_two_st {
        +	long m;
        +	ASN1_OBJECT  *type;
        +	union	{
        +		char *ptr;
        +		/* NID_X9_62_onBasis */
        +		ASN1_NULL    *onBasis;
        +		/* NID_X9_62_tpBasis */
        +		ASN1_INTEGER *tpBasis;
        +		/* NID_X9_62_ppBasis */
        +		X9_62_PENTANOMIAL *ppBasis;
        +		/* anything else */
        +		ASN1_TYPE *other;
        +		} p;
        +	} X9_62_CHARACTERISTIC_TWO;
        +
        +typedef struct x9_62_fieldid_st {
        +        ASN1_OBJECT *fieldType;
        +	union	{
        +		char *ptr;
        +		/* NID_X9_62_prime_field */
        +		ASN1_INTEGER *prime;
        +		/* NID_X9_62_characteristic_two_field */
        +		X9_62_CHARACTERISTIC_TWO *char_two;
        +		/* anything else */
        +		ASN1_TYPE *other;
        +		} p;
        +	} X9_62_FIELDID;
        +
        +typedef struct x9_62_curve_st {
        +        ASN1_OCTET_STRING *a;
        +        ASN1_OCTET_STRING *b;
        +        ASN1_BIT_STRING   *seed;
        +        } X9_62_CURVE;
        +
        +typedef struct ec_parameters_st {
        +        long              version;
        +        X9_62_FIELDID     *fieldID;
        +        X9_62_CURVE       *curve;
        +        ASN1_OCTET_STRING *base;
        +        ASN1_INTEGER      *order;
        +        ASN1_INTEGER      *cofactor;
        +        } ECPARAMETERS;
        +
        +struct ecpk_parameters_st {
        +	int	type;
        +	union {
        +		ASN1_OBJECT  *named_curve;
        +		ECPARAMETERS *parameters;
        +		ASN1_NULL    *implicitlyCA;
        +	} value;
        +	}/* ECPKPARAMETERS */;
        +
        +/* SEC1 ECPrivateKey */
        +typedef struct ec_privatekey_st {
        +	long              version;
        +	ASN1_OCTET_STRING *privateKey;
        +        ECPKPARAMETERS    *parameters;
        +	ASN1_BIT_STRING   *publicKey;
        +	} EC_PRIVATEKEY;
        +
        +/* the OpenSSL ASN.1 definitions */
        +ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
        +	ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
        +	ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
        +	ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
        +} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
        +
        +DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
        +
        +ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
        +
        +ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
        +	ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
        +	ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
        +	ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
        +} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
        +
        +ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
        +	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
        +	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
        +} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
        +
        +DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
        +
        +ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
        +
        +ASN1_ADB(X9_62_FIELDID) = {
        +	ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
        +	ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
        +} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
        +
        +ASN1_SEQUENCE(X9_62_FIELDID) = {
        +	ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(X9_62_FIELDID)
        +} ASN1_SEQUENCE_END(X9_62_FIELDID)
        +
        +ASN1_SEQUENCE(X9_62_CURVE) = {
        +	ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
        +	ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END(X9_62_CURVE)
        +
        +ASN1_SEQUENCE(ECPARAMETERS) = {
        +	ASN1_SIMPLE(ECPARAMETERS, version, LONG),
        +	ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
        +	ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
        +	ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
        +	ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(ECPARAMETERS)
        +
        +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
        +
        +ASN1_CHOICE(ECPKPARAMETERS) = {
        +	ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
        +	ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
        +	ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
        +} ASN1_CHOICE_END(ECPKPARAMETERS)
        +
        +DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
        +IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
        +
        +ASN1_SEQUENCE(EC_PRIVATEKEY) = {
        +	ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
        +	ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
        +	ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
        +	ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
        +} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
        +
        +DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
        +IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
        +
        +/* some declarations of internal function */
        +
        +/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 
        +static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
        +/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 
        +static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
        +/* ec_asn1_parameters2group() creates a EC_GROUP object from a
        + * ECPARAMETERS object */
        +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); 
        +/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a 
        + * EC_GROUP object */
        +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
        +/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
        + * ECPKPARAMETERS object */
        +static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); 
        +/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a 
        + * EC_GROUP object */
        +static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, 
        +	ECPKPARAMETERS *);
        +
        +
        +/* the function definitions */
        +
        +static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
        +	{
        +	int			ok=0, nid;
        +	BIGNUM			*tmp = NULL;
        +	
        +	if (group == NULL || field == NULL)
        +		return 0;
        +
        +	/* clear the old values (if necessary) */
        +	if (field->fieldType != NULL)
        +		ASN1_OBJECT_free(field->fieldType);
        +	if (field->p.other != NULL)
        +		ASN1_TYPE_free(field->p.other);
        +
        +	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
        +	/* set OID for the field */
        +	if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
        +		goto err;
        +		}
        +
        +	if (nid == NID_X9_62_prime_field)
        +		{
        +		if ((tmp = BN_new()) == NULL) 
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		/* the parameters are specified by the prime number p */
        +		if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		/* set the prime number */
        +		field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
        +		if (field->p.prime == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		}
        +	else	/* nid == NID_X9_62_characteristic_two_field */
        +#ifdef OPENSSL_NO_EC2M
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
        +		goto err;
        +		}
        +#else
        +		{
        +		int		field_type;
        +		X9_62_CHARACTERISTIC_TWO *char_two;
        +
        +		field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
        +		char_two = field->p.char_two;
        +
        +		if (char_two == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +	
        +		char_two->m = (long)EC_GROUP_get_degree(group);
        +
        +		field_type = EC_GROUP_get_basis_type(group);
        +
        +		if (field_type == 0)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		/* set base type OID */
        +		if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
        +			goto err;
        +			}
        +
        +		if (field_type == NID_X9_62_tpBasis)
        +			{
        +			unsigned int k;
        +
        +			if (!EC_GROUP_get_trinomial_basis(group, &k))
        +				goto err;
        +
        +			char_two->p.tpBasis = ASN1_INTEGER_new();
        +			if (!char_two->p.tpBasis)
        +				{
        +				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
        +				{
        +				ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
        +					ERR_R_ASN1_LIB);
        +				goto err;
        +				}
        +			}
        +		else if (field_type == NID_X9_62_ppBasis)
        +			{
        +			unsigned int k1, k2, k3;
        +
        +			if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
        +				goto err;
        +
        +			char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
        +			if (!char_two->p.ppBasis)
        +				{
        +				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +			/* set k? values */
        +			char_two->p.ppBasis->k1 = (long)k1;
        +			char_two->p.ppBasis->k2 = (long)k2;
        +			char_two->p.ppBasis->k3 = (long)k3;
        +			}
        +		else /* field_type == NID_X9_62_onBasis */
        +			{
        +			/* for ONB the parameters are (asn1) NULL */
        +			char_two->p.onBasis = ASN1_NULL_new();
        +			if (!char_two->p.onBasis)
        +				{
        +				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			}
        +		}
        +#endif
        +
        +	ok = 1;
        +
        +err :	if (tmp)
        +		BN_free(tmp);
        +	return(ok);
        +}
        +
        +static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
        +	{
        +	int           ok=0, nid;
        +	BIGNUM        *tmp_1=NULL, *tmp_2=NULL;
        +	unsigned char *buffer_1=NULL, *buffer_2=NULL,
        +	              *a_buf=NULL, *b_buf=NULL;
        +	size_t        len_1, len_2;
        +	unsigned char char_zero = 0;
        +
        +	if (!group || !curve || !curve->a || !curve->b)
        +		return 0;
        +
        +	if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
        +
        +	/* get a and b */
        +	if (nid == NID_X9_62_prime_field)
        +		{
        +		if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else	/* nid == NID_X9_62_characteristic_two_field */
        +		{
        +		if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +#endif
        +	len_1 = (size_t)BN_num_bytes(tmp_1);
        +	len_2 = (size_t)BN_num_bytes(tmp_2);
        +
        +	if (len_1 == 0)
        +		{
        +		/* len_1 == 0 => a == 0 */
        +		a_buf = &char_zero;
        +		len_1 = 1;
        +		}
        +	else
        +		{
        +		if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
        +			      ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		a_buf = buffer_1;
        +		}
        +
        +	if (len_2 == 0)
        +		{
        +		/* len_2 == 0 => b == 0 */
        +		b_buf = &char_zero;
        +		len_2 = 1;
        +		}
        +	else
        +		{
        +		if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
        +			      ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		b_buf = buffer_2;
        +		}
        +	
        +	/* set a and b */
        +	if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
        +	    !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
        +		goto err;
        +		}
        +	
        +	/* set the seed (optional) */
        +	if (group->seed)
        +		{	
        +		if (!curve->seed)
        +			if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
        +				{
        +				ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +		curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        +		curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        +		if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 
        +		                         (int)group->seed_len))
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		if (curve->seed)
        +			{
        +			ASN1_BIT_STRING_free(curve->seed);
        +			curve->seed = NULL;
        +			}
        +		}
        +
        +	ok = 1;
        +
        +err:	if (buffer_1)
        +		OPENSSL_free(buffer_1);
        +	if (buffer_2)
        +		OPENSSL_free(buffer_2);
        +	if (tmp_1)
        +		BN_free(tmp_1);
        +	if (tmp_2)
        +		BN_free(tmp_2);
        +	return(ok);
        +	}
        +
        +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
        +                                              ECPARAMETERS *param)
        +	{
        +	int	ok=0;
        +	size_t  len=0;
        +	ECPARAMETERS   *ret=NULL;
        +	BIGNUM	       *tmp=NULL;
        +	unsigned char  *buffer=NULL;
        +	const EC_POINT *point=NULL;
        +	point_conversion_form_t form;
        +
        +	if ((tmp = BN_new()) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (param == NULL)
        +	{
        +		if ((ret = ECPARAMETERS_new()) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, 
        +			      ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +	}
        +	else
        +		ret = param;
        +
        +	/* set the version (always one) */
        +	ret->version = (long)0x1;
        +
        +	/* set the fieldID */
        +	if (!ec_asn1_group2fieldid(group, ret->fieldID))
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	/* set the curve */
        +	if (!ec_asn1_group2curve(group, ret->curve))
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	/* set the base point */
        +	if ((point = EC_GROUP_get0_generator(group)) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
        +		goto err;
        +		}
        +
        +	form = EC_GROUP_get_point_conversion_form(group);
        +
        +	len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
        +	if (len == 0)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	if ((buffer = OPENSSL_malloc(len)) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
        +		goto err;
        +		}
        +
        +	/* set the order */
        +	if (!EC_GROUP_get_order(group, tmp, NULL))
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
        +	if (ret->order == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
        +		goto err;
        +		}
        +
        +	/* set the cofactor (optional) */
        +	if (EC_GROUP_get_cofactor(group, tmp, NULL))
        +		{
        +		ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
        +		if (ret->cofactor == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		}
        +
        +	ok = 1;
        +
        +err :	if(!ok)
        +		{
        +		if (ret && !param)
        +			ECPARAMETERS_free(ret);
        +		ret = NULL;
        +		}
        +	if (tmp)
        +		BN_free(tmp);
        +	if (buffer)
        +		OPENSSL_free(buffer);
        +	return(ret);
        +	}
        +
        +ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 
        +                                           ECPKPARAMETERS *params)
        +	{
        +	int            ok = 1, tmp;
        +	ECPKPARAMETERS *ret = params;
        +
        +	if (ret == NULL)
        +		{
        +		if ((ret = ECPKPARAMETERS_new()) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, 
        +			      ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +			}
        +		}
        +	else
        +		{
        +		if (ret->type == 0 && ret->value.named_curve)
        +			ASN1_OBJECT_free(ret->value.named_curve);
        +		else if (ret->type == 1 && ret->value.parameters)
        +			ECPARAMETERS_free(ret->value.parameters);
        +		}
        +
        +	if (EC_GROUP_get_asn1_flag(group))
        +		{
        +		/* use the asn1 OID to describe the
        +		 * the elliptic curve parameters
        +		 */
        +		tmp = EC_GROUP_get_curve_name(group);
        +		if (tmp)
        +			{
        +			ret->type = 0;
        +			if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
        +				ok = 0;
        +			}
        +		else
        +			/* we don't kmow the nid => ERROR */
        +			ok = 0;
        +		}
        +	else
        +		{	
        +		/* use the ECPARAMETERS structure */
        +		ret->type = 1;
        +		if ((ret->value.parameters = ec_asn1_group2parameters(
        +		     group, NULL)) == NULL)
        +			ok = 0;
        +		}
        +
        +	if (!ok)
        +		{
        +		ECPKPARAMETERS_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
        +	{
        +	int			ok = 0, tmp;
        +	EC_GROUP		*ret = NULL;
        +	BIGNUM			*p = NULL, *a = NULL, *b = NULL;
        +	EC_POINT		*point=NULL;
        +	long    		field_bits;
        +
        +	if (!params->fieldID || !params->fieldID->fieldType || 
        +	    !params->fieldID->p.ptr)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +		goto err;
        +		}
        +
        +	/* now extract the curve parameters a and b */
        +	if (!params->curve || !params->curve->a || 
        +	    !params->curve->a->data || !params->curve->b ||
        +	    !params->curve->b->data)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +		goto err;
        +		}
        +	a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
        +	if (a == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
        +	if (b == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +
        +	/* get the field parameters */
        +	tmp = OBJ_obj2nid(params->fieldID->fieldType);
        +	if (tmp == NID_X9_62_characteristic_two_field)
        +#ifdef OPENSSL_NO_EC2M
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
        +		goto err;
        +		}
        +#else
        +		{
        +		X9_62_CHARACTERISTIC_TWO *char_two;
        +
        +		char_two = params->fieldID->p.char_two;
        +
        +		field_bits = char_two->m;
        +		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
        +			goto err;
        +			}
        +
        +		if ((p = BN_new()) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* get the base type */
        +		tmp = OBJ_obj2nid(char_two->type);
        +
        +		if (tmp ==  NID_X9_62_tpBasis)
        +			{
        +			long tmp_long;
        +
        +			if (!char_two->p.tpBasis)
        +				{
        +				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +				goto err;
        +				}
        +
        +			tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
        +
        +			if (!(char_two->m > tmp_long && tmp_long > 0))
        +				{
        +				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
        +				goto err;
        +				}
        +			
        +			/* create the polynomial */
        +			if (!BN_set_bit(p, (int)char_two->m))
        +				goto err;
        +			if (!BN_set_bit(p, (int)tmp_long))
        +				goto err;
        +			if (!BN_set_bit(p, 0))
        +				goto err;
        +			}
        +		else if (tmp == NID_X9_62_ppBasis)
        +			{
        +			X9_62_PENTANOMIAL *penta;
        +
        +			penta = char_two->p.ppBasis;
        +			if (!penta)
        +				{
        +				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +				goto err;
        +				}
        +
        +			if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
        +				{
        +				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
        +				goto err;
        +				}
        +			
        +			/* create the polynomial */
        +			if (!BN_set_bit(p, (int)char_two->m)) goto err;
        +			if (!BN_set_bit(p, (int)penta->k1)) goto err;
        +			if (!BN_set_bit(p, (int)penta->k2)) goto err;
        +			if (!BN_set_bit(p, (int)penta->k3)) goto err;
        +			if (!BN_set_bit(p, 0)) goto err;
        +			}
        +		else if (tmp == NID_X9_62_onBasis)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
        +			goto err;
        +			}
        +		else /* error */
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +			goto err;
        +			}
        +
        +		/* create the EC_GROUP structure */
        +		ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
        +		}
        +#endif
        +	else if (tmp == NID_X9_62_prime_field)
        +		{
        +		/* we have a curve over a prime field */
        +		/* extract the prime number */
        +		if (!params->fieldID->p.prime)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +			goto err;
        +			}
        +		p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
        +		if (p == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +
        +		if (BN_is_negative(p) || BN_is_zero(p))
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
        +			goto err;
        +			}
        +
        +		field_bits = BN_num_bits(p);
        +		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
        +			goto err;
        +			}
        +
        +		/* create the EC_GROUP structure */
        +		ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
        +		}
        +	else
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
        +		goto err;
        +		}
        +
        +	if (ret == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	/* extract seed (optional) */
        +	if (params->curve->seed != NULL)
        +		{
        +		if (ret->seed != NULL)
        +			OPENSSL_free(ret->seed);
        +		if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
        +			      ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		memcpy(ret->seed, params->curve->seed->data, 
        +		       params->curve->seed->length);
        +		ret->seed_len = params->curve->seed->length;
        +		}
        +
        +	if (!params->order || !params->base || !params->base->data)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +		goto err;
        +		}
        +
        +	if ((point = EC_POINT_new(ret)) == NULL) goto err;
        +
        +	/* set the point conversion form */
        +	EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
        +				(params->base->data[0] & ~0x01));
        +
        +	/* extract the ec point */
        +	if (!EC_POINT_oct2point(ret, point, params->base->data, 
        +		                params->base->length, NULL))
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	/* extract the order */
        +	if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
        +		goto err;
        +		}
        +	if (BN_is_negative(a) || BN_is_zero(a))
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
        +		goto err;
        +		}
        +	if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
        +		goto err;
        +		}
        +	
        +	/* extract the cofactor (optional) */
        +	if (params->cofactor == NULL)
        +		{
        +		if (b)
        +			{
        +			BN_free(b);
        +			b = NULL;
        +			}
        +		}
        +	else
        +		if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +	/* set the generator, order and cofactor (if present) */
        +	if (!EC_GROUP_set_generator(ret, point, a, b))
        +		{
        +		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	ok = 1;
        +
        +err:	if (!ok)
        +		{
        +		if (ret) 
        +			EC_GROUP_clear_free(ret);
        +		ret = NULL;
        +		}
        +
        +	if (p)	
        +		BN_free(p);
        +	if (a)	
        +		BN_free(a);
        +	if (b)	
        +		BN_free(b);
        +	if (point)	
        +		EC_POINT_free(point);
        +	return(ret);
        +}
        +
        +EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
        +	{
        +	EC_GROUP *ret=NULL;
        +	int      tmp=0;
        +
        +	if (params == NULL)
        +		{
        +		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
        +		      EC_R_MISSING_PARAMETERS);
        +		return NULL;
        +		}
        +
        +	if (params->type == 0)
        +		{ /* the curve is given by an OID */
        +		tmp = OBJ_obj2nid(params->value.named_curve);
        +		if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
        +			{
        +			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
        +			      EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
        +			return NULL;
        +			}
        +		EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
        +		}
        +	else if (params->type == 1)
        +		{ /* the parameters are given by a ECPARAMETERS
        +		   * structure */
        +		ret = ec_asn1_parameters2group(params->value.parameters);
        +		if (!ret)
        +			{
        +			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
        +			return NULL;
        +			}
        +		EC_GROUP_set_asn1_flag(ret, 0x0);
        +		}
        +	else if (params->type == 2)
        +		{ /* implicitlyCA */
        +		return NULL;
        +		}
        +	else
        +		{
        +		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
        +		return NULL;
        +		}
        +
        +	return ret;
        +	}
        +
        +/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
        +
        +EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
        +	{
        +	EC_GROUP	*group  = NULL;
        +	ECPKPARAMETERS	*params = NULL;
        +
        +	if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
        +		{
        +		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
        +		ECPKPARAMETERS_free(params);
        +		return NULL;
        +		}
        +	
        +	if ((group = ec_asn1_pkparameters2group(params)) == NULL)
        +		{
        +		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
        +		ECPKPARAMETERS_free(params);
        +		return NULL; 
        +		}
        +
        +	
        +	if (a && *a)
        +		EC_GROUP_clear_free(*a);
        +	if (a)
        +		*a = group;
        +
        +	ECPKPARAMETERS_free(params);
        +	return(group);
        +	}
        +
        +int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
        +	{
        +	int		ret=0;
        +	ECPKPARAMETERS	*tmp = ec_asn1_group2pkparameters(a, NULL);
        +	if (tmp == NULL)
        +		{
        +		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
        +		return 0;
        +		}
        +	if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
        +		{
        +		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
        +		ECPKPARAMETERS_free(tmp);
        +		return 0;
        +		}	
        +	ECPKPARAMETERS_free(tmp);
        +	return(ret);
        +	}
        +
        +/* some EC_KEY functions */
        +
        +EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
        +	{
        +	int             ok=0;
        +	EC_KEY          *ret=NULL;
        +	EC_PRIVATEKEY   *priv_key=NULL;
        +
        +	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
        +		{
        +		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
        +		{
        +		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
        +		EC_PRIVATEKEY_free(priv_key);
        +		return NULL;
        +		}
        +
        +	if (a == NULL || *a == NULL)
        +		{
        +		if ((ret = EC_KEY_new()) == NULL)	
        +			{
        +			ECerr(EC_F_D2I_ECPRIVATEKEY,
        +                                 ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (a)
        +			*a = ret;
        +		}
        +	else
        +		ret = *a;
        +
        +	if (priv_key->parameters)
        +		{
        +		if (ret->group)
        +			EC_GROUP_clear_free(ret->group);
        +		ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
        +		}
        +
        +	if (ret->group == NULL)
        +		{
        +		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	ret->version = priv_key->version;
        +
        +	if (priv_key->privateKey)
        +		{
        +		ret->priv_key = BN_bin2bn(
        +			M_ASN1_STRING_data(priv_key->privateKey),
        +			M_ASN1_STRING_length(priv_key->privateKey),
        +			ret->priv_key);
        +		if (ret->priv_key == NULL)
        +			{
        +			ECerr(EC_F_D2I_ECPRIVATEKEY,
        +                              ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		ECerr(EC_F_D2I_ECPRIVATEKEY, 
        +                      EC_R_MISSING_PRIVATE_KEY);
        +		goto err;
        +		}
        +
        +	if (priv_key->publicKey)
        +		{
        +		const unsigned char *pub_oct;
        +		size_t pub_oct_len;
        +
        +		if (ret->pub_key)
        +			EC_POINT_clear_free(ret->pub_key);
        +		ret->pub_key = EC_POINT_new(ret->group);
        +		if (ret->pub_key == NULL)
        +			{
        +			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
        +		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
        +		/* save the point conversion form */
        +		ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
        +		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
        +			pub_oct, pub_oct_len, NULL))
        +			{
        +			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +
        +	ok = 1;
        +err:
        +	if (!ok)
        +		{
        +		if (ret)
        +			EC_KEY_free(ret);
        +		ret = NULL;
        +		}
        +
        +	if (priv_key)
        +		EC_PRIVATEKEY_free(priv_key);
        +
        +	return(ret);
        +	}
        +
        +int	i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
        +	{
        +	int             ret=0, ok=0;
        +	unsigned char   *buffer=NULL;
        +	size_t          buf_len=0, tmp_len;
        +	EC_PRIVATEKEY   *priv_key=NULL;
        +
        +	if (a == NULL || a->group == NULL || a->priv_key == NULL)
        +		{
        +		ECerr(EC_F_I2D_ECPRIVATEKEY,
        +                      ERR_R_PASSED_NULL_PARAMETER);
        +		goto err;
        +		}
        +
        +	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
        +		{
        +		ECerr(EC_F_I2D_ECPRIVATEKEY,
        +                      ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	priv_key->version = a->version;
        +
        +	buf_len = (size_t)BN_num_bytes(a->priv_key);
        +	buffer = OPENSSL_malloc(buf_len);
        +	if (buffer == NULL)
        +		{
        +		ECerr(EC_F_I2D_ECPRIVATEKEY,
        +                      ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	
        +	if (!BN_bn2bin(a->priv_key, buffer))
        +		{
        +		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +
        +	if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
        +		{
        +		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
        +		goto err;
        +		}	
        +
        +	if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
        +		{
        +		if ((priv_key->parameters = ec_asn1_group2pkparameters(
        +			a->group, priv_key->parameters)) == NULL)
        +			{
        +			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +
        +	if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
        +		{
        +		priv_key->publicKey = M_ASN1_BIT_STRING_new();
        +		if (priv_key->publicKey == NULL)
        +			{
        +			ECerr(EC_F_I2D_ECPRIVATEKEY,
        +				ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 
        +				a->conv_form, NULL, 0, NULL);
        +
        +		if (tmp_len > buf_len)
        +			{
        +			unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
        +			if (!tmp_buffer)
        +				{
        +				ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			buffer = tmp_buffer;
        +			buf_len = tmp_len;
        +			}
        +
        +		if (!EC_POINT_point2oct(a->group, a->pub_key, 
        +			a->conv_form, buffer, buf_len, NULL))
        +			{
        +			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +
        +		priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
        +		priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        +		if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
        +				buf_len))
        +			{
        +			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		}
        +
        +	if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
        +		{
        +		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	ok=1;
        +err:
        +	if (buffer)
        +		OPENSSL_free(buffer);
        +	if (priv_key)
        +		EC_PRIVATEKEY_free(priv_key);
        +	return(ok?ret:0);
        +	}
        +
        +int i2d_ECParameters(EC_KEY *a, unsigned char **out)
        +	{
        +	if (a == NULL)
        +		{
        +		ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	return i2d_ECPKParameters(a->group, out);
        +	}
        +
        +EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
        +	{
        +	EC_KEY   *ret;
        +
        +	if (in == NULL || *in == NULL)
        +		{
        +		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +
        +	if (a == NULL || *a == NULL)
        +		{
        +		if ((ret = EC_KEY_new()) == NULL)
        +			{
        +			ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +			}
        +		if (a)
        +			*a = ret;
        +		}
        +	else
        +		ret = *a;
        +
        +	if (!d2i_ECPKParameters(&ret->group, in, len))
        +		{
        +		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
        +		return NULL;
        +		}
        +
        +	return ret;
        +	}
        +
        +EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
        +	{
        +	EC_KEY *ret=NULL;
        +
        +	if (a == NULL || (*a) == NULL || (*a)->group == NULL)
        +		{
        +		/* sorry, but a EC_GROUP-structur is necessary
        +                 * to set the public key */
        +		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	ret = *a;
        +	if (ret->pub_key == NULL && 
        +		(ret->pub_key = EC_POINT_new(ret->group)) == NULL)
        +		{
        +		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
        +		{
        +		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
        +		return 0;
        +		}
        +	/* save the point conversion form */
        +	ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
        +	*in += len;
        +	return ret;
        +	}
        +
        +int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
        +	{
        +        size_t buf_len=0;
        +	int new_buffer = 0;
        +
        +        if (a == NULL) 
        +		{
        +		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +
        +        buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
        +                              a->conv_form, NULL, 0, NULL);
        +
        +	if (out == NULL || buf_len == 0)
        +	/* out == NULL => just return the length of the octet string */
        +		return buf_len;
        +
        +	if (*out == NULL)
        +		{
        +		if ((*out = OPENSSL_malloc(buf_len)) == NULL)
        +			{
        +			ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		new_buffer = 1;
        +		}
        +        if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
        +				*out, buf_len, NULL))
        +		{
        +		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
        +		OPENSSL_free(*out);
        +		*out = NULL;
        +		return 0;
        +		}
        +	if (!new_buffer)
        +		*out += buf_len;
        +	return buf_len;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_check.c b/vendor/openssl/openssl/crypto/ec/ec_check.c
        new file mode 100644
        index 000000000..0e316b4b3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_check.c
        @@ -0,0 +1,123 @@
        +/* crypto/ec/ec_check.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ec_lcl.h"
        +#include <openssl/err.h>
        +
        +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BIGNUM *order;
        +	BN_CTX *new_ctx = NULL;
        +	EC_POINT *point = NULL;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			{
        +			ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	BN_CTX_start(ctx);
        +	if ((order = BN_CTX_get(ctx)) == NULL) goto err;
        +
        +	/* check the discriminant */
        +	if (!EC_GROUP_check_discriminant(group, ctx))
        +		{
        +		ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
        +		goto err;
        +		}
        +
        +	/* check the generator */
        +	if (group->generator == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
        +		goto err;
        +		}
        +	if (!EC_POINT_is_on_curve(group, group->generator, ctx))
        +		{
        +		ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
        +		goto err;
        +		}
        +
        +	/* check the order of the generator */
        +	if ((point = EC_POINT_new(group)) == NULL) goto err;
        +	if (!EC_GROUP_get_order(group, order, ctx)) goto err; 
        +	if (BN_is_zero(order))
        +		{
        +		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
        +		goto err;
        +		}
        +	
        +	if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
        +	if (!EC_POINT_is_at_infinity(group, point))
        +		{
        +		ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +
        +err:
        +	if (ctx != NULL)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (point)
        +		EC_POINT_free(point);
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_curve.c b/vendor/openssl/openssl/crypto/ec/ec_curve.c
        new file mode 100644
        index 000000000..c72fb2697
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_curve.c
        @@ -0,0 +1,2100 @@
        +/* crypto/ec/ec_curve.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include "ec_lcl.h"
        +#include <openssl/err.h>
        +#include <openssl/obj_mac.h>
        +#include <openssl/opensslconf.h>
        +
        +typedef struct {
        +	int	field_type,	/* either NID_X9_62_prime_field or
        +				 * NID_X9_62_characteristic_two_field */
        +		seed_len,
        +		param_len;
        +	unsigned int cofactor;	/* promoted to BN_ULONG */
        +} EC_CURVE_DATA;
        +
        +/* the nist prime curves */
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
        +	_EC_NIST_PRIME_192 = {
        +	{ NID_X9_62_prime_field,20,24,1 },
        +	{ 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57,	/* seed */
        +	  0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5,
        +
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFC,
        +	  0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7,	/* b */
        +	  0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC,
        +	  0xC1,0x46,0xB9,0xB1,
        +	  0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF,	/* x */
        +	  0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD,
        +	  0x82,0xFF,0x10,0x12,
        +	  0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10,	/* y */
        +	  0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1,
        +	  0x1e,0x79,0x48,0x11,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1,
        +	  0xB4,0xD2,0x28,0x31 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; }
        +	_EC_NIST_PRIME_224 = {
        +	{ NID_X9_62_prime_field,20,28,1 },
        +	{ 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45,	/* seed */
        +	  0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5,
        +
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
        +	  0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,	/* b */
        +	  0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
        +	  0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
        +	  0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,	/* x */
        +	  0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
        +	  0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
        +	  0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,	/* y */
        +	  0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
        +	  0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
        +	  0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
        +	_EC_NIST_PRIME_384 = {
        +	{ NID_X9_62_prime_field,20,48,1 },
        +	{ 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00,	/* seed */
        +	  0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73,
        +
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,
        +	  0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E,	/* b */
        +	  0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E,
        +	  0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13,
        +	  0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D,
        +	  0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF,
        +	  0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1,	/* x */
        +	  0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62,
        +	  0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54,
        +	  0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C,
        +	  0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7,
        +	  0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e,	/* y */
        +	  0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd,
        +	  0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0,
        +	  0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d,
        +	  0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37,
        +	  0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A,
        +	  0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; }
        +	_EC_NIST_PRIME_521 = {
        +	{ NID_X9_62_prime_field,20,66,1 },
        +	{ 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC,	/* seed */
        +	  0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA,
        +
        +	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
        +	  0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F,	/* b */
        +	  0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA,
        +	  0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91,
        +	  0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E,
        +	  0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07,
        +	  0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45,
        +	  0x1F,0xD4,0x6B,0x50,0x3F,0x00,
        +	  0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD,	/* x */
        +	  0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64,
        +	  0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60,
        +	  0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7,
        +	  0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE,
        +	  0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E,
        +	  0x7E,0x31,0xC2,0xE5,0xBD,0x66,
        +	  0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04,	/* y */
        +	  0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5,
        +	  0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17,
        +	  0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4,
        +	  0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61,
        +	  0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe,
        +	  0x94,0x76,0x9f,0xd1,0x66,0x50,
        +	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F,
        +	  0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0,
        +	  0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F,
        +	  0xB7,0x1E,0x91,0x38,0x64,0x09 }
        +	};
        +
        +/* the x9.62 prime curves (minus the nist prime curves) */
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
        +	_EC_X9_62_PRIME_192V2 = {
        +	{ NID_X9_62_prime_field,20,24,1 },
        +	{ 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B,	/* seed */
        +	  0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6,
        +
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFC,
        +	  0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C,	/* b */
        +	  0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2,
        +	  0x16,0x68,0xD9,0x53,
        +	  0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE,	/* x */
        +	  0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69,
        +	  0x6F,0x48,0x03,0x4A,
        +	  0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b,	/* y */
        +	  0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9,
        +	  0x70,0xb2,0xde,0x15,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86,
        +	  0x48,0xD8,0xDD,0x31 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
        +	_EC_X9_62_PRIME_192V3 = {
        +	{ NID_X9_62_prime_field,20,24,1 },
        +	{ 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6,	/* seed */
        +	  0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E,
        +
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFC,
        +	  0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42,	/* b */
        +	  0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25,
        +	  0x6B,0xD5,0x69,0x16,
        +	  0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78,	/* x */
        +	  0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E,
        +	  0x22,0x8F,0x18,0x96,
        +	  0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49,	/* y */
        +	  0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76,
        +	  0x48,0xa9,0x43,0xb0,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94,
        +	  0xF6,0x40,0xEC,0x13 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_X9_62_PRIME_239V1 = {
        +	{ NID_X9_62_prime_field,20,30,1 },
        +	{ 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0,	/* seed */
        +	  0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
        +	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
        +	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
        +
        +	  0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6,	/* b */
        +	  0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2,
        +	  0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A,
        +
        +	  0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33,	/* x */
        +	  0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57,
        +	  0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF,
        +
        +	  0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40,	/* y */
        +	  0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18,
        +	  0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D,
        +	  0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_X9_62_PRIME_239V2 = {
        +	{ NID_X9_62_prime_field,20,30,1 },
        +	{ 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B,	/* seed */
        +	  0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
        +	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
        +	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
        +
        +	  0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5,	/* b */
        +	  0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B,
        +	  0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C,
        +
        +	  0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9,	/* x */
        +	  0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2,
        +	  0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7,
        +
        +	  0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d,	/* y */
        +	  0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55,
        +	  0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43,
        +	  0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_X9_62_PRIME_239V3 = {
        +	{ NID_X9_62_prime_field,20,30,1 },
        +	{ 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A,	/* seed */
        +	  0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
        +	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
        +	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
        +
        +	  0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4,	/* b */
        +	  0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02,
        +	  0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E,
        +
        +	  0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00,	/* x */
        +	  0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6,
        +	  0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A,
        +
        +	  0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d,	/* y */
        +	  0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b,
        +	  0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3,
        +
        +	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3,
        +	  0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 }
        +	};
        +
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; }
        +	_EC_X9_62_PRIME_256V1 = {
        +	{ NID_X9_62_prime_field,20,32,1 },
        +	{ 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66,	/* seed */
        +	  0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90,
        +
        +	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFC,
        +	  0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB,	/* b */
        +	  0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,
        +	  0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2,
        +	  0x60,0x4B,
        +	  0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC,	/* x */
        +	  0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,
        +	  0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,
        +	  0xC2,0x96,
        +	  0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7,	/* y */
        +	  0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,
        +	  0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,
        +	  0x51,0xf5,
        +	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,
        +	  0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63,
        +	  0x25,0x51 }
        +	};
        +
        +/* the secg prime curves (minus the nist and x9.62 prime curves) */
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
        +	_EC_SECG_PRIME_112R1 = {
        +	{ NID_X9_62_prime_field,20,14,1 },
        +	{ 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68,	/* seed */
        +	  0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1,
        +
        +	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* p */
        +	  0xBE,0xAD,0x20,0x8B,
        +	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* a */
        +	  0xBE,0xAD,0x20,0x88,
        +	  0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89,	/* b */
        +	  0x11,0x70,0x2B,0x22,
        +	  0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55,	/* x */
        +	  0xF9,0xC2,0xF0,0x98,
        +	  0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e,	/* y */
        +	  0x0f,0xf7,0x75,0x00,
        +	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF,	/* order */
        +	  0xAC,0x65,0x61,0xC5 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
        +	_EC_SECG_PRIME_112R2 = {
        +	{ NID_X9_62_prime_field,20,14,4 },
        +	{ 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68,	/* seed */
        +	  0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4,
        +
        +	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* p */
        +	  0xBE,0xAD,0x20,0x8B,
        +	  0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6,	/* a */
        +	  0x5C,0x0E,0xF0,0x2C,
        +	  0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3,	/* b */
        +	  0x4C,0x85,0xD7,0x09,
        +	  0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D,	/* x */
        +	  0xD0,0x92,0x86,0x43,
        +	  0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3,	/* y */
        +	  0x6e,0x95,0x6e,0x97,
        +	  0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1,	/* order */
        +	  0x05,0x20,0xD0,0x4B }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
        +	_EC_SECG_PRIME_128R1 = {
        +	{ NID_X9_62_prime_field,20,16,1 },
        +	{ 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
        +	  0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79,
        +
        +	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
        +	  0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24,	/* b */
        +	  0x99,0x3C,0x2C,0xEE,0x5E,0xD3,
        +	  0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28,	/* x */
        +	  0x60,0x7C,0xA5,0x2C,0x5B,0x86,
        +	  0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d,	/* y */
        +	  0xa2,0x92,0xdd,0xed,0x7a,0x83,
        +	  0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3,	/* order */
        +	  0x0D,0x1B,0x90,0x38,0xA1,0x15 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
        +	_EC_SECG_PRIME_128R2 = {
        +	{ NID_X9_62_prime_field,20,16,4 },
        +	{ 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,	/* seed */
        +	  0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4,
        +
        +	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59,	/* a */
        +	  0xCC,0x9B,0xBF,0xF9,0xAE,0xE1,
        +	  0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C,	/* b */
        +	  0x65,0x58,0xBB,0x6D,0x8A,0x5D,
        +	  0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB,	/* x */
        +	  0x32,0xA7,0xCD,0xEB,0xC1,0x40,
        +	  0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06,	/* y */
        +	  0xfe,0x80,0x5f,0xc3,0x4b,0x44,
        +	  0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00,	/* order */
        +	  0x24,0x72,0x06,0x13,0xB5,0xA3 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
        +	_EC_SECG_PRIME_160K1 = {
        +	{ NID_X9_62_prime_field,0,21,1 },
        +	{							/* no seed */
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
        +	  0x73,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x07,
        +	  0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4,	/* x */
        +	  0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E,
        +	  0xBB,
        +	  0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b,	/* y */
        +	  0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f,
        +	  0xee,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6,
        +	  0xB3 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
        +	_EC_SECG_PRIME_160R1 = {
        +	{ NID_X9_62_prime_field,20,21,1 },
        +	{ 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45,
        +
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
        +	  0xFF,
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
        +	  0xFC,
        +	  0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65,	/* b */
        +	  0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA,
        +	  0x45,
        +	  0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46,	/* x */
        +	  0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC,
        +	  0x82,
        +	  0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59,	/* y */
        +	  0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb,
        +	  0x32,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22,
        +	  0x57 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
        +	_EC_SECG_PRIME_160R2 = {
        +	{ NID_X9_62_prime_field,20,21,1 },
        +	{ 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09,	/* seed */
        +	  0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51,
        +
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
        +	  0x73,
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
        +	  0x70,
        +	  0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB,	/* b */
        +	  0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88,
        +	  0xBA,
        +	  0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F,	/* x */
        +	  0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE,
        +	  0x6D,
        +	  0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0,	/* y */
        +	  0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f,
        +	  0x2e,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1,
        +	  0x6B }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
        +	_EC_SECG_PRIME_192K1 = {
        +	{ NID_X9_62_prime_field,0,24,1 },
        +	{							/* no seed */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
        +	  0xFF,0xFF,0xEE,0x37,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x03,
        +	  0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0,	/* x */
        +	  0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1,
        +	  0xEA,0xE0,0x6C,0x7D,
        +	  0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41,	/* y */
        +	  0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88,
        +	  0xd9,0x5e,0x2f,0x9d,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A,
        +	  0x74,0xDE,0xFD,0x8D }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; }
        +	_EC_SECG_PRIME_224K1 = {
        +	{ NID_X9_62_prime_field,0,29,1 },
        +	{							/* no seed */
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
        +	  0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30,	/* x */
        +	  0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75,
        +	  0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C,
        +	  0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82,	/* y */
        +	  0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd,
        +	  0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61,
        +	  0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
        +	_EC_SECG_PRIME_256K1 = {
        +	{ NID_X9_62_prime_field,0,32,1 },
        +	{							/* no seed */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
        +	  0xFC,0x2F,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x07,
        +	  0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,	/* x */
        +	  0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
        +	  0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
        +	  0x17,0x98,
        +	  0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4,	/* y */
        +	  0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
        +	  0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
        +	  0xd4,0xb8,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
        +	  0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
        +	  0x41,0x41 }
        +	};
        +
        +/* some wap/wtls curves */
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
        +	_EC_WTLS_8 = {
        +	{ NID_X9_62_prime_field,0,15,1 },
        +	{							/* no seed */
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFD,0xE7,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x03,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
        +	  0x00,0x00,0x00,0x00,0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
        +	  0x00,0x00,0x00,0x00,0x02,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA,	/* order */
        +	  0x55,0x1A,0xD8,0x37,0xE9 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
        +	_EC_WTLS_9 = {
        +	{ NID_X9_62_prime_field,0,21,1 },
        +	{							/* no seed */
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80,
        +	  0x8F,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x03,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x02,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF,
        +	  0x33 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
        +	_EC_WTLS_12 = {
        +	{ NID_X9_62_prime_field,0,28,1 },
        +	{							/* no seed */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
        +	  0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,	/* b */
        +	  0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
        +	  0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
        +	  0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,	/* x */
        +	  0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
        +	  0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
        +	  0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,	/* y */
        +	  0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
        +	  0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
        +	  0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
        +	};
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +/* characteristic two curves */
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
        +	_EC_SECG_CHAR2_113R1 = {
        +	{ NID_X9_62_characteristic_two_field,20,15,2 },
        +	{ 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87,	/* seed */
        +	  0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9,
        +
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x02,0x01,
        +	  0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64,	/* a */
        +	  0x9C,0xE8,0x58,0x20,0xF7,
        +	  0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18,	/* b */
        +	  0x8B,0xE0,0xE9,0xC7,0x23,
        +	  0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07,	/* x */
        +	  0xD7,0x35,0x62,0xC1,0x0F,
        +	  0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1,	/* y */
        +	  0x31,0x5E,0xD3,0x18,0x86,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC,	/* order */
        +	  0xEC,0x8A,0x39,0xE5,0x6F }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
        +	_EC_SECG_CHAR2_113R2 = {
        +	{ NID_X9_62_characteristic_two_field,20,15,2 },
        +	{ 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,	/* seed */
        +	  0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D,
        +
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x02,0x01,
        +	  0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6,	/* a */
        +	  0xDF,0xC0,0xAA,0x55,0xC7,
        +	  0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF,	/* b */
        +	  0x36,0xE0,0x59,0x18,0x4F,
        +	  0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F,	/* x */
        +	  0xCD,0xB8,0x16,0x47,0x97,
        +	  0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06,	/* y */
        +	  0xE6,0x95,0xBA,0xBA,0x1D,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78,	/* order */
        +	  0x9B,0x24,0x96,0xAF,0x93 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
        +	_EC_SECG_CHAR2_131R1 = {
        +	{ NID_X9_62_characteristic_two_field,20,17,2 },
        +	{ 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98,	/* seed */
        +	  0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2,
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
        +	  0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41,	/* a */
        +	  0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8,
        +	  0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6,	/* b */
        +	  0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41,
        +	  0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F,	/* x */
        +	  0x9C,0x18,0x13,0x43,0x63,0x83,0x99,
        +	  0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8,	/* y */
        +	  0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31,	/* order */
        +	  0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
        +	_EC_SECG_CHAR2_131R2 = {
        +	{ NID_X9_62_characteristic_two_field,20,17,2 },
        +	{ 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3,
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
        +	  0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41,	/* a */
        +	  0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2,
        +	  0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73,	/* b */
        +	  0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92,
        +	  0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65,	/* x */
        +	  0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8,
        +	  0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D,	/* y */
        +	  0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69,	/* order */
        +	  0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
        +	_EC_NIST_CHAR2_163K = {
        +	{ NID_X9_62_characteristic_two_field,0,21,2 },
        +	{							/* no seed */
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0xC9,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x01,
        +	  0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA,	/* x */
        +	  0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE,
        +	  0xE8,
        +	  0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32,	/* y */
        +	  0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3,
        +	  0xD9,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5,
        +	  0xEF }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
        +	_EC_SECG_CHAR2_163R1 = {
        +	{ NID_X9_62_characteristic_two_field,0,21,2 },
        +	{							/* no seed */
        +#if 0
        +/* The algorithm used to derive the curve parameters from
        + * the seed used here is slightly different than the
        + * algorithm described in X9.62 . */
        +	  0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
        +	  0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C,
        +#endif
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0xC9,
        +	  0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54,	/* a */
        +	  0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A,
        +	  0xE2,
        +	  0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94,	/* b */
        +	  0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF,
        +	  0xD9,
        +	  0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89,	/* x */
        +	  0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6,
        +	  0x54,
        +	  0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D,	/* y */
        +	  0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8,
        +	  0x83,
        +	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27,
        +	  0x9B }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
        +	_EC_NIST_CHAR2_163B = {
        +	{ NID_X9_62_characteristic_two_field,0,21,2 },
        +	{							/* no seed */
        +#if 0
        +/* The seed here was used to created the curve parameters in normal
        + * basis representation (and not the polynomial representation used here) */
        +	  0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
        +	  0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68,
        +#endif
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0xC9,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x01,
        +	  0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14,	/* b */
        +	  0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05,
        +	  0xFD,
        +	  0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0,	/* x */
        +	  0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E,
        +	  0x36,
        +	  0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2,	/* y */
        +	  0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24,
        +	  0xF1,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C,
        +	  0x33 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
        +	_EC_SECG_CHAR2_193R1 = {
        +	{ NID_X9_62_characteristic_two_field,20,25,2 },
        +	{ 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75,	/* seed */
        +	  0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30,
        +
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x80,0x01,
        +	  0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69,	/* a */
        +	  0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8,
        +	  0xA9,0x11,0xDF,0x7B,0x01,
        +	  0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC,	/* b */
        +	  0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5,
        +	  0xD8,0x31,0x47,0x88,0x14,
        +	  0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD,	/* x */
        +	  0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53,
        +	  0x72,0xD8,0xC0,0xC5,0xE1,
        +	  0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3,	/* y */
        +	  0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B,
        +	  0x6A,0xF7,0xCE,0x1B,0x05,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A,
        +	  0xCC,0x92,0x0E,0xBA,0x49 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
        +	_EC_SECG_CHAR2_193R2 = {
        +	{ NID_X9_62_characteristic_two_field,20,25,2 },
        +	{ 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,	/* seed */
        +	  0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11,
        +
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x80,0x01,
        +	  0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6,	/* a */
        +	  0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69,
        +	  0x97,0x77,0x02,0x70,0x9B,
        +	  0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37,	/* b */
        +	  0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7,
        +	  0xF6,0x1D,0x43,0x16,0xAE,
        +	  0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03,	/* x */
        +	  0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35,
        +	  0x0A,0xAE,0x61,0x7E,0x8F,
        +	  0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29,	/* y */
        +	  0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27,
        +	  0x22,0x4C,0xDE,0xCF,0x6C,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13,
        +	  0xCC,0xD4,0xEE,0x99,0xD5 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
        +	_EC_NIST_CHAR2_233K = {
        +	{ NID_X9_62_characteristic_two_field,0,30,4 },
        +	{							/* no seed */
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1,	/* x */
        +	  0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2,
        +	  0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26,
        +
        +	  0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F,	/* y */
        +	  0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A,
        +	  0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3,
        +
        +	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15,
        +	  0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_NIST_CHAR2_233B = {
        +	{ NID_X9_62_characteristic_two_field,20,30,2 },
        +	{ 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1,	/* seed */
        +	  0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3,
        +
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C,	/* b */
        +	  0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9,
        +	  0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD,
        +
        +	  0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21,	/* x */
        +	  0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F,
        +	  0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B,
        +
        +	  0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78,	/* y */
        +	  0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67,
        +	  0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52,
        +
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F,
        +	  0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
        +	_EC_SECG_CHAR2_239K1 = {
        +	{ NID_X9_62_characteristic_two_field,0,30,4 },
        +	{							/* no seed */
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09,	/* x */
        +	  0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C,
        +	  0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC,
        +
        +	  0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01,	/* y */
        +	  0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75,
        +	  0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA,
        +
        +	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C,
        +	  0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; }
        +	_EC_NIST_CHAR2_283K = {
        +	{ NID_X9_62_characteristic_two_field,0,36,4 },
        +	{							/* no seed */
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x10,0xA1,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A,	/* x */
        +	  0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F,
        +	  0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2,
        +	  0xAC,0x24,0x58,0x49,0x28,0x36,
        +	  0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90,	/* y */
        +	  0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0,
        +	  0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34,
        +	  0x11,0x61,0x77,0xDD,0x22,0x59,
        +	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE,
        +	  0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45,
        +	  0x1E,0x06,0x1E,0x16,0x3C,0x61 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; }
        +	_EC_NIST_CHAR2_283B = {
        +	{ NID_X9_62_characteristic_two_field,20,36,2 },
        +	{ 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D,	/* no seed */
        +	  0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE,
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x10,0xA1,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4,	/* b */
        +	  0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76,
        +	  0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26,
        +	  0x3E,0x31,0x3B,0x79,0xA2,0xF5,
        +	  0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93,	/* x */
        +	  0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8,
        +	  0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD,
        +	  0xBE,0xCD,0x86,0xB1,0x20,0x53,
        +	  0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F,	/* y */
        +	  0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02,
        +	  0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0,
        +	  0xDF,0x45,0xBE,0x81,0x12,0xF4,
        +	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90,
        +	  0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04,
        +	  0x2A,0x7C,0xEF,0xAD,0xB3,0x07 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; }
        +	_EC_NIST_CHAR2_409K = {
        +	{ NID_X9_62_characteristic_two_field,0,52,4 },
        +	{							/* no seed */
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x01,
        +	  0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A,	/* x */
        +	  0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87,
        +	  0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6,
        +	  0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62,
        +	  0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02,
        +	  0x37,0x46,
        +	  0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA,	/* y */
        +	  0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F,
        +	  0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA,
        +	  0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15,
        +	  0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0,
        +	  0x28,0x6B,
        +	  0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2,
        +	  0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3,
        +	  0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E,
        +	  0x5F,0xCF }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; }
        +	_EC_NIST_CHAR2_409B = {
        +	{ NID_X9_62_characteristic_two_field,20,52,2 },
        +	{ 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21,	/* seed */
        +	  0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B,
        +
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x01,
        +	  0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B,	/* b */
        +	  0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E,
        +	  0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC,
        +	  0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C,
        +	  0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13,
        +	  0x54,0x5F,
        +	  0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B,	/* x */
        +	  0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A,
        +	  0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5,
        +	  0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51,
        +	  0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79,
        +	  0x96,0xA7,
        +	  0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF,	/* y */
        +	  0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5,
        +	  0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88,
        +	  0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40,
        +	  0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73,
        +	  0xC7,0x06,
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6,
        +	  0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C,
        +	  0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2,
        +	  0x11,0x73 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; }
        +	_EC_NIST_CHAR2_571K = {
        +	{ NID_X9_62_characteristic_two_field,0,72,4 },
        +	{							/* no seed */
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x04,0x25,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x01,
        +	  0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18,	/* x */
        +	  0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97,
        +	  0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84,
        +	  0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6,
        +	  0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1,
        +	  0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17,
        +	  0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C,
        +	  0x89,0x72,
        +	  0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A,	/* y */
        +	  0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC,
        +	  0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D,
        +	  0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7,
        +	  0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20,
        +	  0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8,
        +	  0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1,
        +	  0xC7,0xA3,
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1,
        +	  0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F,
        +	  0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38,
        +	  0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C,
        +	  0x10,0x01 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; }
        +	_EC_NIST_CHAR2_571B = {
        +	{ NID_X9_62_characteristic_two_field,20,72,2 },
        +	{ 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B,	/* seed */
        +	  0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10,
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x04,0x25,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x01,
        +	  0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29,	/* b */
        +	  0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF,
        +	  0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A,
        +	  0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33,
        +	  0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD,
        +	  0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7,
        +	  0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55,
        +	  0x72,0x7A,
        +	  0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16,	/* x */
        +	  0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2,
        +	  0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B,
        +	  0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93,
        +	  0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE,
        +	  0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4,
        +	  0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC,
        +	  0x2D,0x19,
        +	  0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC,	/* y */
        +	  0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6,
        +	  0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21,
        +	  0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57,
        +	  0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53,
        +	  0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51,
        +	  0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A,
        +	  0xC1,0x5B,
        +	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18,
        +	  0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23,
        +	  0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D,
        +	  0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8,
        +	  0x4E,0x47 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
        +	_EC_X9_62_CHAR2_163V1 = {
        +	{ NID_X9_62_characteristic_two_field,20,21,2 },
        +	{ 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
        +	  0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54,	/* seed */
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0x07,
        +	  0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0,	/* a */
        +	  0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52,
        +	  0x42,
        +	  0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF,	/* b */
        +	  0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4,
        +	  0xD9,
        +	  0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32,	/* x */
        +	  0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03,
        +	  0xCB,
        +	  0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D,	/* y */
        +	  0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA,
        +	  0x9F,
        +	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF,
        +	  0xC1 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
        +	_EC_X9_62_CHAR2_163V2 = {
        +	{ NID_X9_62_characteristic_two_field,20,21,2 },
        +	{ 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0x07,
        +	  0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9,	/* a */
        +	  0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0,
        +	  0x72,
        +	  0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40,	/* b */
        +	  0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF,
        +	  0x20,
        +	  0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96,	/* x */
        +	  0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C,
        +	  0xC5,
        +	  0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25,	/* y */
        +	  0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F,
        +	  0xC5,
        +	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10,
        +	  0xA7 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
        +	_EC_X9_62_CHAR2_163V3 = {
        +	{ NID_X9_62_characteristic_two_field,20,21,2 },
        +	{ 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67,	/* seed */
        +	  0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8,
        +
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +	  0x07,
        +	  0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0,	/* a */
        +	  0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5,
        +	  0x0E,
        +	  0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD,	/* b */
        +	  0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25,
        +	  0x2B,
        +	  0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF,	/* x */
        +	  0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD,
        +	  0xCB,
        +	  0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48,	/* y */
        +	  0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05,
        +	  0xD0,
        +	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13,
        +	  0x09 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; }
        +	_EC_X9_62_CHAR2_176V1 = {
        +	{ NID_X9_62_characteristic_two_field,0,23,0xFF6E },
        +	{							/* no seed */
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
        +	  0x00,0x00,0x07,
        +	  0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D,	/* a */
        +	  0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8,
        +	  0xE9,0xC9,0x0B,
        +	  0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E,	/* b */
        +	  0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A,
        +	  0xE0,0xFF,0xF2,
        +	  0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9,	/* x */
        +	  0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0,
        +	  0x4A,0x57,0x98,
        +	  0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA,	/* y */
        +	  0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1,
        +	  0x6A,0x56,0x2C,
        +	  0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4,	/* order */
        +	  0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06,
        +	  0xFE,0x26,0xAD }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
        +	_EC_X9_62_CHAR2_191V1 = {
        +	{ NID_X9_62_characteristic_two_field,20,24,2 },
        +	{ 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x02,0x01,
        +	  0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68,	/* a */
        +	  0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E,
        +	  0xF7,0x52,0x62,0x67,
        +	  0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0,	/* b */
        +	  0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE,
        +	  0x0A,0xA1,0x85,0xEC,
        +	  0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2,	/* x */
        +	  0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8,
        +	  0x4A,0xE1,0xAA,0x0D,
        +	  0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29,	/* y */
        +	  0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E,
        +	  0xF9,0x80,0x18,0xFB,
        +	  0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8,
        +	  0x93,0xBB,0xB9,0xA5 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
        +	_EC_X9_62_CHAR2_191V2 = {
        +	{ NID_X9_62_characteristic_two_field,20,24,4 },
        +	{ 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x02,0x01,
        +	  0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66,	/* a */
        +	  0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89,
        +	  0xFF,0x01,0xE7,0x18,
        +	  0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24,	/* b */
        +	  0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3,
        +	  0x62,0xC4,0x6A,0x01,
        +	  0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87,	/* x */
        +	  0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2,
        +	  0xC9,0xE3,0xBF,0x10,
        +	  0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0,	/* y */
        +	  0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC,
        +	  0x43,0x7D,0x66,0x8A,
        +	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24,
        +	  0xE0,0x6B,0x81,0x73 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
        +	_EC_X9_62_CHAR2_191V3 = {
        +	{ NID_X9_62_characteristic_two_field,20,24,6 },
        +	{ 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x02,0x01,
        +	  0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10,	/* a */
        +	  0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7,
        +	  0xE7,0xE7,0x7F,0xCB,
        +	  0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF,	/* b */
        +	  0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32,
        +	  0xAD,0x3F,0x15,0xE8,
        +	  0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE,	/* x */
        +	  0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E,
        +	  0x38,0xA9,0x26,0xDD,
        +	  0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59,	/* y */
        +	  0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7,
        +	  0x12,0x7B,0x06,0xBE,
        +	  0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,	/* order */
        +	  0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6,
        +	  0x28,0x8A,0x3E,0xA3 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; }
        +	_EC_X9_62_CHAR2_208W1 = {
        +	{ NID_X9_62_characteristic_two_field,0,27,0xFE48 },
        +	{							/* no seed */
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x07,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E,	/* b */
        +	  0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA,
        +	  0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E,
        +	  0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95,	/* x */
        +	  0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27,
        +	  0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A,
        +	  0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3,	/* y */
        +	  0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE,
        +	  0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3,
        +	  0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5,	/* order */
        +	  0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88,
        +	  0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_X9_62_CHAR2_239V1 = {
        +	{ NID_X9_62_characteristic_two_field,20,30,4 },
        +	{ 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
        +	  0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
        +
        +	  0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A,	/* a */
        +	  0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E,
        +	  0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76,
        +
        +	  0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12,	/* b */
        +	  0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C,
        +	  0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16,
        +
        +	  0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96,	/* x */
        +	  0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56,
        +	  0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D,
        +
        +	  0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1,	/* y */
        +	  0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E,
        +	  0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05,
        +
        +	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
        +	  0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1,
        +	  0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_X9_62_CHAR2_239V2 = {
        +	{ NID_X9_62_characteristic_two_field,20,30,6 },
        +	{ 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
        +
        +	  0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23,	/* a */
        +	  0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF,
        +	  0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F,
        +
        +	  0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82,	/* b */
        +	  0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52,
        +	  0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B,
        +
        +	  0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47,	/* x */
        +	  0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7,
        +	  0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05,
        +
        +	  0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B,	/* y */
        +	  0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56,
        +	  0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33,
        +
        +	  0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,	/* order */
        +	  0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25,
        +	  0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
        +	_EC_X9_62_CHAR2_239V3 = {
        +	{ NID_X9_62_characteristic_two_field,20,30,0xA },
        +	{ 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
        +	  0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
        +
        +	  0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66,	/* a */
        +	  0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66,
        +	  0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F,
        +
        +	  0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99,	/* b */
        +	  0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5,
        +	  0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40,
        +
        +	  0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91,	/* x */
        +	  0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42,
        +	  0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92,
        +
        +	  0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00,	/* y */
        +	  0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08,
        +	  0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61,
        +
        +	  0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,	/* order */
        +	  0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9,
        +	  0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; }
        +	_EC_X9_62_CHAR2_272W1 = {
        +	{ NID_X9_62_characteristic_two_field,0,35,0xFF06 },
        +	{							/* no seed */
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x0B,
        +	  0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2,	/* a */
        +	  0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71,
        +	  0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA,
        +	  0xCD,0xB5,0x86,0xFB,0x20,
        +	  0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C,	/* b */
        +	  0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03,
        +	  0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC,
        +	  0x84,0x82,0xE5,0x40,0xF7,
        +	  0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87,	/* x */
        +	  0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77,
        +	  0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D,
        +	  0x10,0xD1,0x71,0xDD,0x8D,
        +	  0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B,	/* y */
        +	  0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8,
        +	  0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02,
        +	  0x00,0x5D,0xDE,0x9D,0x23,
        +	  0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3,	/* order */
        +	  0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16,
        +	  0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B,
        +	  0x8F,0x1E,0x62,0x95,0x21 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; }
        +	_EC_X9_62_CHAR2_304W1 = {
        +	{ NID_X9_62_characteristic_two_field,0,39,0xFE2E },
        +	{							/* no seed */
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,
        +	  0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51,	/* a */
        +	  0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88,
        +	  0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28,
        +	  0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81,
        +	  0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E,	/* b */
        +	  0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F,
        +	  0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1,
        +	  0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE,
        +	  0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A,	/* x */
        +	  0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E,
        +	  0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD,
        +	  0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14,
        +	  0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51,	/* y */
        +	  0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10,
        +	  0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80,
        +	  0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B,
        +	  0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,	/* order */
        +	  0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80,
        +	  0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5,
        +	  0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; }
        +	_EC_X9_62_CHAR2_359V1 = {
        +	{ NID_X9_62_characteristic_two_field,20,45,0x4C },
        +	{ 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76,	/* seed */
        +	  0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6,
        +
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x01,
        +	  0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35,	/* a */
        +	  0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67,
        +	  0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67,
        +	  0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16,
        +	  0xA9,0x66,0x56,0xA5,0x57,
        +	  0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F,	/* b */
        +	  0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D,
        +	  0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34,
        +	  0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7,
        +	  0x06,0x80,0x23,0x19,0x88,
        +	  0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0,	/* x */
        +	  0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A,
        +	  0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF,
        +	  0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A,
        +	  0x22,0x39,0xB1,0xB0,0x97,
        +	  0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E,	/* y */
        +	  0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48,
        +	  0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC,
        +	  0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30,
        +	  0x5A,0x40,0x71,0x04,0xBD,
        +	  0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,	/* order */
        +	  0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF,
        +	  0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89,
        +	  0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74,
        +	  0xF4,0x90,0x75,0x8D,0x3B }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; }
        +	_EC_X9_62_CHAR2_368W1 = {
        +	{ NID_X9_62_characteristic_two_field,0,47,0xFF70 },
        +	{							/* no seed */
        +	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x07,
        +	  0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2,	/* a */
        +	  0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0,
        +	  0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9,
        +	  0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C,
        +	  0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D,
        +	  0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C,	/* b */
        +	  0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B,
        +	  0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5,
        +	  0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4,
        +	  0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A,
        +	  0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3,	/* x */
        +	  0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82,
        +	  0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B,
        +	  0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21,
        +	  0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F,
        +	  0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8,	/* y */
        +	  0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C,
        +	  0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE,
        +	  0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A,
        +	  0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10,
        +	  0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72,	/* order */
        +	  0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53,
        +	  0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A,
        +	  0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1,
        +	  0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; }
        +	_EC_X9_62_CHAR2_431R1 = {
        +	{ NID_X9_62_characteristic_two_field,0,54,0x2760 },
        +	{							/* no seed */
        +	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x01,
        +	  0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C,	/* a */
        +	  0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23,
        +	  0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9,
        +	  0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F,
        +	  0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D,
        +	  0xE2,0x96,0xCD,0x8F,
        +	  0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43,	/* b */
        +	  0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB,
        +	  0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67,
        +	  0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD,
        +	  0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8,
        +	  0x07,0xBF,0x26,0x18,
        +	  0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61,	/* x */
        +	  0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4,
        +	  0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2,
        +	  0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65,
        +	  0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB,
        +	  0xD7,0x0C,0xE6,0xB7,
        +	  0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2,	/* y */
        +	  0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93,
        +	  0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B,
        +	  0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C,
        +	  0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A,
        +	  0x59,0x8B,0x37,0x60,
        +	  0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,	/* order */
        +	  0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,
        +	  0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23,
        +	  0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6,
        +	  0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49,
        +	  0xC1,0xAD,0x4A,0x91 }
        +	};
        +
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
        +	_EC_WTLS_1 = {
        +	{ NID_X9_62_characteristic_two_field,0,15,2 },
        +	{							/* no seed */
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x02,0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x01,
        +	  0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5,	/* x */
        +	  0xC2,0x70,0x78,0x06,0x17,
        +	  0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08,	/* y */
        +	  0x78,0x5C,0xEB,0xCC,0x15,
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,	/* order */
        +	  0x91,0xAF,0x6D,0xEA,0x73 }
        +	};
        +
        +/* IPSec curves */
        +/* NOTE: The of curves over a extension field of non prime degree
        + * is not recommended (Weil-descent).
        + * As the group order is not a prime this curve is not suitable
        + * for ECDSA.
        + */
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; }
        +	_EC_IPSEC_155_ID3 = {
        +	{ NID_X9_62_characteristic_two_field,0,20,3 },
        +	{							/* no seed */
        +	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,
        +
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8,
        +
        +	  0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,	/* order */
        +	  0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C }
        +	};
        +
        +/* NOTE: The of curves over a extension field of non prime degree
        + * is not recommended (Weil-descent).
        + * As the group order is not a prime this curve is not suitable
        + * for ECDSA.
        + */
        +static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
        +	_EC_IPSEC_185_ID4 = {
        +	{ NID_X9_62_characteristic_two_field,0,24,2 },
        +	{							/* no seed */
        +	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
        +	  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x01,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x1e,0xe9,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x18,
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
        +	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	  0x00,0x00,0x00,0x0d,
        +	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
        +	  0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20,
        +	  0xBA,0xFC,0xA7,0x5E }
        +	};
        +
        +#endif
        +
        +typedef struct _ec_list_element_st {
        +	int	nid;
        +	const EC_CURVE_DATA *data;
        +	const EC_METHOD *(*meth)(void);
        +	const char *comment;
        +	} ec_list_element;
        +
        +static const ec_list_element curve_list[] = {
        +	/* prime field curves */
        +	/* secg curves */
        +	{ NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
        +	{ NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, "SECG curve over a 112 bit prime field" },
        +	{ NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, "SECG curve over a 128 bit prime field" },
        +	{ NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, "SECG curve over a 128 bit prime field" },
        +	{ NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, "SECG curve over a 160 bit prime field" },
        +	{ NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, "SECG curve over a 160 bit prime field" },
        +	{ NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
        +	/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
        +	{ NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field" },
        +	{ NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field" },
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +	{ NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field" },
        +#else
        +	{ NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field" },
        +#endif
        +	{ NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" },
        +	/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
        +	{ NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" },
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +	{ NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field" },
        +#else
        +	{ NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field" },
        +#endif
        +	/* X9.62 curves */
        +	{ NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field" },
        +	{ NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field" },
        +	{ NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, "X9.62 curve over a 192 bit prime field" },
        +	{ NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field" },
        +	{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" },
        +	{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" },
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field" },
        +#else
        +	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" },
        +#endif
        +#ifndef OPENSSL_NO_EC2M
        +	/* characteristic two field curves */
        +	/* NIST/SECG curves */
        +	{ NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
        +	{ NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, "SECG curve over a 113 bit binary field" },
        +	{ NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, "SECG/WTLS curve over a 131 bit binary field" },
        +	{ NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, "SECG curve over a 131 bit binary field" },
        +	{ NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
        +	{ NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, "SECG curve over a 163 bit binary field" },
        +	{ NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, "NIST/SECG curve over a 163 bit binary field" },
        +	{ NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, "SECG curve over a 193 bit binary field" },
        +	{ NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, "SECG curve over a 193 bit binary field" },
        +	{ NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
        +	{ NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
        +	{ NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, "SECG curve over a 239 bit binary field" },
        +	{ NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, "NIST/SECG curve over a 283 bit binary field" },
        +	{ NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, "NIST/SECG curve over a 283 bit binary field" },
        +	{ NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, "NIST/SECG curve over a 409 bit binary field" },
        +	{ NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, "NIST/SECG curve over a 409 bit binary field" },
        +	{ NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, "NIST/SECG curve over a 571 bit binary field" },
        +	{ NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, "NIST/SECG curve over a 571 bit binary field" },
        +	/* X9.62 curves */
        +	{ NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
        +	{ NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, "X9.62 curve over a 163 bit binary field" },
        +	{ NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, "X9.62 curve over a 163 bit binary field" },
        +	{ NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, "X9.62 curve over a 176 bit binary field" },
        +	{ NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, "X9.62 curve over a 191 bit binary field" },
        +	{ NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, "X9.62 curve over a 191 bit binary field" },
        +	{ NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, "X9.62 curve over a 191 bit binary field" },
        +	{ NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, "X9.62 curve over a 208 bit binary field" },
        +	{ NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, "X9.62 curve over a 239 bit binary field" },
        +	{ NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, "X9.62 curve over a 239 bit binary field" },
        +	{ NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, "X9.62 curve over a 239 bit binary field" },
        +	{ NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, "X9.62 curve over a 272 bit binary field" },
        +	{ NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, "X9.62 curve over a 304 bit binary field" },
        +	{ NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, "X9.62 curve over a 359 bit binary field" },
        +	{ NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, "X9.62 curve over a 368 bit binary field" },
        +	{ NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, "X9.62 curve over a 431 bit binary field" },
        +	/* the WAP/WTLS curves
        +	 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
        +	{ NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, "WTLS curve over a 113 bit binary field" },
        +	{ NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
        +	{ NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
        +	{ NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
        +#endif
        +	{ NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
        +	{ NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
        +	{ NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field" },
        +	{ NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field" },
        +#ifndef OPENSSL_NO_EC2M
        +	{ NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
        +	{ NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
        +#endif
        +	{ NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curvs over a 224 bit prime field" },
        +#ifndef OPENSSL_NO_EC2M
        +	/* IPSec curves */
        +	{ NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
        +	  "\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
        +	{ NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
        +	  "\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
        +#endif
        +};
        +
        +#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
        +
        +static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
        +	{
        +	EC_GROUP *group=NULL;
        +	EC_POINT *P=NULL;
        +	BN_CTX	 *ctx=NULL;
        +	BIGNUM	 *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
        +	int	 ok=0;
        +	int	 seed_len,param_len;
        +	const EC_METHOD *meth;
        +	const EC_CURVE_DATA *data;
        +	const unsigned char *params;
        +
        +	if ((ctx = BN_CTX_new()) == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	data = curve.data;
        +	seed_len  = data->seed_len;
        +	param_len = data->param_len;
        +	params	  = (const unsigned char *)(data+1);	/* skip header */
        +	params	 += seed_len;				/* skip seed   */
        +
        +	if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
        +		|| !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
        +		|| !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +
        +	if (curve.meth != 0)
        +		{
        +		meth = curve.meth();
        +		if (((group = EC_GROUP_new(meth)) == NULL) ||
        +			(!(group->meth->group_set_curve(group, p, a, b, ctx))))
        +			{
        +			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +	else if (data->field_type == NID_X9_62_prime_field)
        +		{
        +		if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
        +			{
        +			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else	/* field_type == NID_X9_62_characteristic_two_field */
        +		{
        +		if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
        +			{
        +			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +#endif
        +
        +	if ((P = EC_POINT_new(group)) == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +
        +	if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
        +		|| !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
        +		|| !BN_set_word(x, (BN_ULONG)data->cofactor))
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	if (!EC_GROUP_set_generator(group, P, order, x))
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	if (seed_len)
        +		{
        +		if (!EC_GROUP_set_seed(group, params-seed_len, seed_len))
        +			{
        +			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +	ok=1;
        +err:
        +	if (!ok)
        +		{
        +		EC_GROUP_free(group);
        +		group = NULL;
        +		}
        +	if (P)
        +		EC_POINT_free(P);
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	if (p)
        +		BN_free(p);
        +	if (a)
        +		BN_free(a);
        +	if (b)
        +		BN_free(b);
        +	if (order)
        +		BN_free(order);
        +	if (x)
        +		BN_free(x);
        +	if (y)
        +		BN_free(y);
        +	return group;
        +	}
        +
        +EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
        +	{
        +	size_t i;
        +	EC_GROUP *ret = NULL;
        +
        +	if (nid <= 0)
        +		return NULL;
        +
        +	for (i=0; i<curve_list_length; i++)
        +		if (curve_list[i].nid == nid)
        +			{
        +			ret = ec_group_new_from_data(curve_list[i]);
        +			break;
        +			}
        +
        +	if (ret == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
        +		return NULL;
        +		}
        +
        +	EC_GROUP_set_curve_name(ret, nid);
        +
        +	return ret;
        +	}
        +
        +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
        +	{
        +	size_t	i, min;
        +
        +	if (r == NULL || nitems == 0)
        +		return curve_list_length;
        +
        +	min = nitems < curve_list_length ? nitems : curve_list_length;
        +
        +	for (i = 0; i < min; i++)
        +		{
        +		r[i].nid = curve_list[i].nid;
        +		r[i].comment = curve_list[i].comment;
        +		}
        +
        +	return curve_list_length;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_cvt.c b/vendor/openssl/openssl/crypto/ec/ec_cvt.c
        new file mode 100644
        index 000000000..bfcbab35f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_cvt.c
        @@ -0,0 +1,170 @@
        +/* crypto/ec/ec_cvt.c */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include <openssl/err.h>
        +#include "ec_lcl.h"
        +
        +
        +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	const EC_METHOD *meth;
        +	EC_GROUP *ret;
        +
        +#if defined(OPENSSL_BN_ASM_MONT)
        +	/*
        +	 * This might appear controversial, but the fact is that generic
        +	 * prime method was observed to deliver better performance even
        +	 * for NIST primes on a range of platforms, e.g.: 60%-15%
        +	 * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
        +	 * in 32-bit build and 35%--12% in 64-bit build on Core2...
        +	 * Coefficients are relative to optimized bn_nist.c for most
        +	 * intensive ECDSA verify and ECDH operations for 192- and 521-
        +	 * bit keys respectively. Choice of these boundary values is
        +	 * arguable, because the dependency of improvement coefficient
        +	 * from key length is not a "monotone" curve. For example while
        +	 * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
        +	 * generally faster, sometimes "respectfully" faster, sometimes
        +	 * "tolerably" slower... What effectively happens is that loop
        +	 * with bn_mul_add_words is put against bn_mul_mont, and the
        +	 * latter "wins" on short vectors. Correct solution should be
        +	 * implementing dedicated NxN multiplication subroutines for
        +	 * small N. But till it materializes, let's stick to generic
        +	 * prime method...
        +	 *						<appro>
        +	 */
        +	meth = EC_GFp_mont_method();
        +#else
        +	meth = EC_GFp_nist_method();
        +#endif
        +	
        +	ret = EC_GROUP_new(meth);
        +	if (ret == NULL)
        +		return NULL;
        +
        +	if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
        +		{
        +		unsigned long err;
        +		  
        +		err = ERR_peek_last_error();
        +
        +		if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
        +			((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
        +			 (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME))))
        +			{
        +			/* real error */
        +			
        +			EC_GROUP_clear_free(ret);
        +			return NULL;
        +			}
        +			
        +		
        +		/* not an actual error, we just cannot use EC_GFp_nist_method */
        +
        +		ERR_clear_error();
        +
        +		EC_GROUP_clear_free(ret);
        +		meth = EC_GFp_mont_method();
        +
        +		ret = EC_GROUP_new(meth);
        +		if (ret == NULL)
        +			return NULL;
        +
        +		if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
        +			{
        +			EC_GROUP_clear_free(ret);
        +			return NULL;
        +			}
        +		}
        +
        +	return ret;
        +	}
        +
        +#ifndef OPENSSL_NO_EC2M
        +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	const EC_METHOD *meth;
        +	EC_GROUP *ret;
        +	
        +	meth = EC_GF2m_simple_method();
        +	
        +	ret = EC_GROUP_new(meth);
        +	if (ret == NULL)
        +		return NULL;
        +
        +	if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx))
        +		{
        +		EC_GROUP_clear_free(ret);
        +		return NULL;
        +		}
        +
        +	return ret;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_err.c b/vendor/openssl/openssl/crypto/ec/ec_err.c
        new file mode 100644
        index 000000000..0d1939873
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_err.c
        @@ -0,0 +1,276 @@
        +/* crypto/ec/ec_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ec.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
        +
        +static ERR_STRING_DATA EC_str_functs[]=
        +	{
        +{ERR_FUNC(EC_F_BN_TO_FELEM),	"BN_TO_FELEM"},
        +{ERR_FUNC(EC_F_COMPUTE_WNAF),	"COMPUTE_WNAF"},
        +{ERR_FUNC(EC_F_D2I_ECPARAMETERS),	"d2i_ECParameters"},
        +{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS),	"d2i_ECPKParameters"},
        +{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY),	"d2i_ECPrivateKey"},
        +{ERR_FUNC(EC_F_DO_EC_KEY_PRINT),	"DO_EC_KEY_PRINT"},
        +{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE),	"ECKEY_PARAM2TYPE"},
        +{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE),	"ECKEY_PARAM_DECODE"},
        +{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE),	"ECKEY_PRIV_DECODE"},
        +{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE),	"ECKEY_PRIV_ENCODE"},
        +{ERR_FUNC(EC_F_ECKEY_PUB_DECODE),	"ECKEY_PUB_DECODE"},
        +{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE),	"ECKEY_PUB_ENCODE"},
        +{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM),	"ECKEY_TYPE2PARAM"},
        +{ERR_FUNC(EC_F_ECPARAMETERS_PRINT),	"ECParameters_print"},
        +{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP),	"ECParameters_print_fp"},
        +{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT),	"ECPKParameters_print"},
        +{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP),	"ECPKParameters_print_fp"},
        +{ERR_FUNC(EC_F_ECP_NIST_MOD_192),	"ECP_NIST_MOD_192"},
        +{ERR_FUNC(EC_F_ECP_NIST_MOD_224),	"ECP_NIST_MOD_224"},
        +{ERR_FUNC(EC_F_ECP_NIST_MOD_256),	"ECP_NIST_MOD_256"},
        +{ERR_FUNC(EC_F_ECP_NIST_MOD_521),	"ECP_NIST_MOD_521"},
        +{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE),	"EC_ASN1_GROUP2CURVE"},
        +{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID),	"EC_ASN1_GROUP2FIELDID"},
        +{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS),	"EC_ASN1_GROUP2PARAMETERS"},
        +{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS),	"EC_ASN1_GROUP2PKPARAMETERS"},
        +{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP),	"EC_ASN1_PARAMETERS2GROUP"},
        +{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP),	"EC_ASN1_PKPARAMETERS2GROUP"},
        +{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA),	"EC_EX_DATA_set_data"},
        +{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),	"EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),	"ec_GF2m_simple_group_check_discriminant"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),	"ec_GF2m_simple_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT),	"ec_GF2m_simple_oct2point"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT),	"ec_GF2m_simple_point2oct"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),	"ec_GF2m_simple_point_get_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),	"ec_GF2m_simple_point_set_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),	"ec_GF2m_simple_set_compressed_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE),	"ec_GFp_mont_field_decode"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE),	"ec_GFp_mont_field_encode"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL),	"ec_GFp_mont_field_mul"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),	"ec_GFp_mont_field_set_to_one"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR),	"ec_GFp_mont_field_sqr"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),	"ec_GFp_mont_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP),	"EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),	"ec_GFp_nistp224_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL),	"ec_GFp_nistp224_points_mul"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_nistp224_point_get_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),	"ec_GFp_nistp256_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL),	"ec_GFp_nistp256_points_mul"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_nistp256_point_get_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),	"ec_GFp_nistp521_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL),	"ec_GFp_nistp521_points_mul"},
        +{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_nistp521_point_get_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL),	"ec_GFp_nist_field_mul"},
        +{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR),	"ec_GFp_nist_field_sqr"},
        +{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),	"ec_GFp_nist_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),	"ec_GFp_simple_group_check_discriminant"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),	"ec_GFp_simple_group_set_curve"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP),	"EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR),	"EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE),	"ec_GFp_simple_make_affine"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT),	"ec_GFp_simple_oct2point"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT),	"ec_GFp_simple_point2oct"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),	"ec_GFp_simple_points_make_affine"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),	"ec_GFp_simple_point_get_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP),	"EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),	"ec_GFp_simple_point_set_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP),	"EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),	"ec_GFp_simple_set_compressed_coordinates"},
        +{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP),	"EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
        +{ERR_FUNC(EC_F_EC_GROUP_CHECK),	"EC_GROUP_check"},
        +{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),	"EC_GROUP_check_discriminant"},
        +{ERR_FUNC(EC_F_EC_GROUP_COPY),	"EC_GROUP_copy"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR),	"EC_GROUP_get0_generator"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR),	"EC_GROUP_get_cofactor"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M),	"EC_GROUP_get_curve_GF2m"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP),	"EC_GROUP_get_curve_GFp"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE),	"EC_GROUP_get_degree"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER),	"EC_GROUP_get_order"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),	"EC_GROUP_get_pentanomial_basis"},
        +{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),	"EC_GROUP_get_trinomial_basis"},
        +{ERR_FUNC(EC_F_EC_GROUP_NEW),	"EC_GROUP_new"},
        +{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME),	"EC_GROUP_new_by_curve_name"},
        +{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA),	"EC_GROUP_NEW_FROM_DATA"},
        +{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT),	"EC_GROUP_precompute_mult"},
        +{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M),	"EC_GROUP_set_curve_GF2m"},
        +{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP),	"EC_GROUP_set_curve_GFp"},
        +{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA),	"EC_GROUP_SET_EXTRA_DATA"},
        +{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR),	"EC_GROUP_set_generator"},
        +{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY),	"EC_KEY_check_key"},
        +{ERR_FUNC(EC_F_EC_KEY_COPY),	"EC_KEY_copy"},
        +{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY),	"EC_KEY_generate_key"},
        +{ERR_FUNC(EC_F_EC_KEY_NEW),	"EC_KEY_new"},
        +{ERR_FUNC(EC_F_EC_KEY_PRINT),	"EC_KEY_print"},
        +{ERR_FUNC(EC_F_EC_KEY_PRINT_FP),	"EC_KEY_print_fp"},
        +{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),	"EC_KEY_set_public_key_affine_coordinates"},
        +{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE),	"EC_POINTs_make_affine"},
        +{ERR_FUNC(EC_F_EC_POINT_ADD),	"EC_POINT_add"},
        +{ERR_FUNC(EC_F_EC_POINT_CMP),	"EC_POINT_cmp"},
        +{ERR_FUNC(EC_F_EC_POINT_COPY),	"EC_POINT_copy"},
        +{ERR_FUNC(EC_F_EC_POINT_DBL),	"EC_POINT_dbl"},
        +{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),	"EC_POINT_get_affine_coordinates_GF2m"},
        +{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),	"EC_POINT_get_affine_coordinates_GFp"},
        +{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),	"EC_POINT_get_Jprojective_coordinates_GFp"},
        +{ERR_FUNC(EC_F_EC_POINT_INVERT),	"EC_POINT_invert"},
        +{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY),	"EC_POINT_is_at_infinity"},
        +{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE),	"EC_POINT_is_on_curve"},
        +{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE),	"EC_POINT_make_affine"},
        +{ERR_FUNC(EC_F_EC_POINT_MUL),	"EC_POINT_mul"},
        +{ERR_FUNC(EC_F_EC_POINT_NEW),	"EC_POINT_new"},
        +{ERR_FUNC(EC_F_EC_POINT_OCT2POINT),	"EC_POINT_oct2point"},
        +{ERR_FUNC(EC_F_EC_POINT_POINT2OCT),	"EC_POINT_point2oct"},
        +{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),	"EC_POINT_set_affine_coordinates_GF2m"},
        +{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),	"EC_POINT_set_affine_coordinates_GFp"},
        +{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),	"EC_POINT_set_compressed_coordinates_GF2m"},
        +{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),	"EC_POINT_set_compressed_coordinates_GFp"},
        +{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),	"EC_POINT_set_Jprojective_coordinates_GFp"},
        +{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY),	"EC_POINT_set_to_infinity"},
        +{ERR_FUNC(EC_F_EC_PRE_COMP_DUP),	"EC_PRE_COMP_DUP"},
        +{ERR_FUNC(EC_F_EC_PRE_COMP_NEW),	"EC_PRE_COMP_NEW"},
        +{ERR_FUNC(EC_F_EC_WNAF_MUL),	"ec_wNAF_mul"},
        +{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT),	"ec_wNAF_precompute_mult"},
        +{ERR_FUNC(EC_F_I2D_ECPARAMETERS),	"i2d_ECParameters"},
        +{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS),	"i2d_ECPKParameters"},
        +{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY),	"i2d_ECPrivateKey"},
        +{ERR_FUNC(EC_F_I2O_ECPUBLICKEY),	"i2o_ECPublicKey"},
        +{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW),	"NISTP224_PRE_COMP_NEW"},
        +{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW),	"NISTP256_PRE_COMP_NEW"},
        +{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW),	"NISTP521_PRE_COMP_NEW"},
        +{ERR_FUNC(EC_F_O2I_ECPUBLICKEY),	"o2i_ECPublicKey"},
        +{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE),	"OLD_EC_PRIV_DECODE"},
        +{ERR_FUNC(EC_F_PKEY_EC_CTRL),	"PKEY_EC_CTRL"},
        +{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR),	"PKEY_EC_CTRL_STR"},
        +{ERR_FUNC(EC_F_PKEY_EC_DERIVE),	"PKEY_EC_DERIVE"},
        +{ERR_FUNC(EC_F_PKEY_EC_KEYGEN),	"PKEY_EC_KEYGEN"},
        +{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN),	"PKEY_EC_PARAMGEN"},
        +{ERR_FUNC(EC_F_PKEY_EC_SIGN),	"PKEY_EC_SIGN"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA EC_str_reasons[]=
        +	{
        +{ERR_REASON(EC_R_ASN1_ERROR)             ,"asn1 error"},
        +{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD)     ,"asn1 unknown field"},
        +{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE)    ,"bignum out of range"},
        +{ERR_REASON(EC_R_BUFFER_TOO_SMALL)       ,"buffer too small"},
        +{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE),"coordinates out of range"},
        +{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
        +{ERR_REASON(EC_R_DECODE_ERROR)           ,"decode error"},
        +{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO)   ,"discriminant is zero"},
        +{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
        +{ERR_REASON(EC_R_FIELD_TOO_LARGE)        ,"field too large"},
        +{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED)     ,"gf2m not supported"},
        +{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
        +{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
        +{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS)   ,"incompatible objects"},
        +{ERR_REASON(EC_R_INVALID_ARGUMENT)       ,"invalid argument"},
        +{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
        +{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
        +{ERR_REASON(EC_R_INVALID_CURVE)          ,"invalid curve"},
        +{ERR_REASON(EC_R_INVALID_DIGEST_TYPE)    ,"invalid digest type"},
        +{ERR_REASON(EC_R_INVALID_ENCODING)       ,"invalid encoding"},
        +{ERR_REASON(EC_R_INVALID_FIELD)          ,"invalid field"},
        +{ERR_REASON(EC_R_INVALID_FORM)           ,"invalid form"},
        +{ERR_REASON(EC_R_INVALID_GROUP_ORDER)    ,"invalid group order"},
        +{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
        +{ERR_REASON(EC_R_INVALID_PRIVATE_KEY)    ,"invalid private key"},
        +{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
        +{ERR_REASON(EC_R_KEYS_NOT_SET)           ,"keys not set"},
        +{ERR_REASON(EC_R_MISSING_PARAMETERS)     ,"missing parameters"},
        +{ERR_REASON(EC_R_MISSING_PRIVATE_KEY)    ,"missing private key"},
        +{ERR_REASON(EC_R_NOT_A_NIST_PRIME)       ,"not a NIST prime"},
        +{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),"not a supported NIST prime"},
        +{ERR_REASON(EC_R_NOT_IMPLEMENTED)        ,"not implemented"},
        +{ERR_REASON(EC_R_NOT_INITIALIZED)        ,"not initialized"},
        +{ERR_REASON(EC_R_NO_FIELD_MOD)           ,"no field mod"},
        +{ERR_REASON(EC_R_NO_PARAMETERS_SET)      ,"no parameters set"},
        +{ERR_REASON(EC_R_PASSED_NULL_PARAMETER)  ,"passed null parameter"},
        +{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
        +{ERR_REASON(EC_R_POINT_AT_INFINITY)      ,"point at infinity"},
        +{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE)  ,"point is not on curve"},
        +{ERR_REASON(EC_R_SLOT_FULL)              ,"slot full"},
        +{ERR_REASON(EC_R_UNDEFINED_GENERATOR)    ,"undefined generator"},
        +{ERR_REASON(EC_R_UNDEFINED_ORDER)        ,"undefined order"},
        +{ERR_REASON(EC_R_UNKNOWN_GROUP)          ,"unknown group"},
        +{ERR_REASON(EC_R_UNKNOWN_ORDER)          ,"unknown order"},
        +{ERR_REASON(EC_R_UNSUPPORTED_FIELD)      ,"unsupported field"},
        +{ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS) ,"wrong curve parameters"},
        +{ERR_REASON(EC_R_WRONG_ORDER)            ,"wrong order"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_EC_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(EC_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,EC_str_functs);
        +		ERR_load_strings(0,EC_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_key.c b/vendor/openssl/openssl/crypto/ec/ec_key.c
        new file mode 100644
        index 000000000..7fa247593
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_key.c
        @@ -0,0 +1,572 @@
        +/* crypto/ec/ec_key.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions originally developed by SUN MICROSYSTEMS, INC., and 
        + * contributed to the OpenSSL project.
        + */
        +
        +#include <string.h>
        +#include "ec_lcl.h"
        +#include <openssl/err.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +EC_KEY *EC_KEY_new(void)
        +	{
        +	EC_KEY *ret;
        +
        +	ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
        +	if (ret == NULL)
        +		{
        +		ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +
        +	ret->version = 1;	
        +	ret->flags = 0;
        +	ret->group   = NULL;
        +	ret->pub_key = NULL;
        +	ret->priv_key= NULL;
        +	ret->enc_flag= 0; 
        +	ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
        +	ret->references= 1;
        +	ret->method_data = NULL;
        +	return(ret);
        +	}
        +
        +EC_KEY *EC_KEY_new_by_curve_name(int nid)
        +	{
        +	EC_KEY *ret = EC_KEY_new();
        +	if (ret == NULL)
        +		return NULL;
        +	ret->group = EC_GROUP_new_by_curve_name(nid);
        +	if (ret->group == NULL)
        +		{
        +		EC_KEY_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void EC_KEY_free(EC_KEY *r)
        +	{
        +	int i;
        +
        +	if (r == NULL) return;
        +
        +	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
        +#ifdef REF_PRINT
        +	REF_PRINT("EC_KEY",r);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"EC_KEY_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +
        +	if (r->group    != NULL) 
        +		EC_GROUP_free(r->group);
        +	if (r->pub_key  != NULL)
        +		EC_POINT_free(r->pub_key);
        +	if (r->priv_key != NULL)
        +		BN_clear_free(r->priv_key);
        +
        +	EC_EX_DATA_free_all_data(&r->method_data);
        +
        +	OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
        +
        +	OPENSSL_free(r);
        +	}
        +
        +EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
        +	{
        +	EC_EXTRA_DATA *d;
        +
        +	if (dest == NULL || src == NULL)
        +		{
        +		ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	/* copy the parameters */
        +	if (src->group)
        +		{
        +		const EC_METHOD *meth = EC_GROUP_method_of(src->group);
        +		/* clear the old group */
        +		if (dest->group)
        +			EC_GROUP_free(dest->group);
        +		dest->group = EC_GROUP_new(meth);
        +		if (dest->group == NULL)
        +			return NULL;
        +		if (!EC_GROUP_copy(dest->group, src->group))
        +			return NULL;
        +		}
        +	/*  copy the public key */
        +	if (src->pub_key && src->group)
        +		{
        +		if (dest->pub_key)
        +			EC_POINT_free(dest->pub_key);
        +		dest->pub_key = EC_POINT_new(src->group);
        +		if (dest->pub_key == NULL)
        +			return NULL;
        +		if (!EC_POINT_copy(dest->pub_key, src->pub_key))
        +			return NULL;
        +		}
        +	/* copy the private key */
        +	if (src->priv_key)
        +		{
        +		if (dest->priv_key == NULL)
        +			{
        +			dest->priv_key = BN_new();
        +			if (dest->priv_key == NULL)
        +				return NULL;
        +			}
        +		if (!BN_copy(dest->priv_key, src->priv_key))
        +			return NULL;
        +		}
        +	/* copy method/extra data */
        +	EC_EX_DATA_free_all_data(&dest->method_data);
        +
        +	for (d = src->method_data; d != NULL; d = d->next)
        +		{
        +		void *t = d->dup_func(d->data);
        +		
        +		if (t == NULL)
        +			return 0;
        +		if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
        +			return 0;
        +		}
        +
        +	/* copy the rest */
        +	dest->enc_flag  = src->enc_flag;
        +	dest->conv_form = src->conv_form;
        +	dest->version   = src->version;
        +	dest->flags = src->flags;
        +
        +	return dest;
        +	}
        +
        +EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
        +	{
        +	EC_KEY *ret = EC_KEY_new();
        +	if (ret == NULL)
        +		return NULL;
        +	if (EC_KEY_copy(ret, ec_key) == NULL)
        +		{
        +		EC_KEY_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +int EC_KEY_up_ref(EC_KEY *r)
        +	{
        +	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
        +#ifdef REF_PRINT
        +	REF_PRINT("EC_KEY",r);
        +#endif
        +#ifdef REF_CHECK
        +	if (i < 2)
        +		{
        +		fprintf(stderr, "EC_KEY_up, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +	return ((i > 1) ? 1 : 0);
        +	}
        +
        +int EC_KEY_generate_key(EC_KEY *eckey)
        +	{	
        +	int	ok = 0;
        +	BN_CTX	*ctx = NULL;
        +	BIGNUM	*priv_key = NULL, *order = NULL;
        +	EC_POINT *pub_key = NULL;
        +
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		return FIPS_ec_key_generate_key(eckey);
        +#endif
        +
        +	if (!eckey || !eckey->group)
        +		{
        +		ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +
        +	if ((order = BN_new()) == NULL) goto err;
        +	if ((ctx = BN_CTX_new()) == NULL) goto err;
        +
        +	if (eckey->priv_key == NULL)
        +		{
        +		priv_key = BN_new();
        +		if (priv_key == NULL)
        +			goto err;
        +		}
        +	else
        +		priv_key = eckey->priv_key;
        +
        +	if (!EC_GROUP_get_order(eckey->group, order, ctx))
        +		goto err;
        +
        +	do
        +		if (!BN_rand_range(priv_key, order))
        +			goto err;
        +	while (BN_is_zero(priv_key));
        +
        +	if (eckey->pub_key == NULL)
        +		{
        +		pub_key = EC_POINT_new(eckey->group);
        +		if (pub_key == NULL)
        +			goto err;
        +		}
        +	else
        +		pub_key = eckey->pub_key;
        +
        +	if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
        +		goto err;
        +
        +	eckey->priv_key = priv_key;
        +	eckey->pub_key  = pub_key;
        +
        +	ok=1;
        +
        +err:	
        +	if (order)
        +		BN_free(order);
        +	if (pub_key  != NULL && eckey->pub_key  == NULL)
        +		EC_POINT_free(pub_key);
        +	if (priv_key != NULL && eckey->priv_key == NULL)
        +		BN_free(priv_key);
        +	if (ctx != NULL)
        +		BN_CTX_free(ctx);
        +	return(ok);
        +	}
        +
        +int EC_KEY_check_key(const EC_KEY *eckey)
        +	{
        +	int	ok   = 0;
        +	BN_CTX	*ctx = NULL;
        +	const BIGNUM	*order  = NULL;
        +	EC_POINT *point = NULL;
        +
        +	if (!eckey || !eckey->group || !eckey->pub_key)
        +		{
        +		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +
        +	if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
        +		{
        +		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
        +		goto err;
        +		}
        +
        +	if ((ctx = BN_CTX_new()) == NULL)
        +		goto err;
        +	if ((point = EC_POINT_new(eckey->group)) == NULL)
        +		goto err;
        +
        +	/* testing whether the pub_key is on the elliptic curve */
        +	if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
        +		{
        +		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
        +		goto err;
        +		}
        +	/* testing whether pub_key * order is the point at infinity */
        +	order = &eckey->group->order;
        +	if (BN_is_zero(order))
        +		{
        +		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
        +		goto err;
        +		}
        +	if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
        +		{
        +		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	if (!EC_POINT_is_at_infinity(eckey->group, point))
        +		{
        +		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
        +		goto err;
        +		}
        +	/* in case the priv_key is present : 
        +	 * check if generator * priv_key == pub_key 
        +	 */
        +	if (eckey->priv_key)
        +		{
        +		if (BN_cmp(eckey->priv_key, order) >= 0)
        +			{
        +			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
        +			goto err;
        +			}
        +		if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
        +			NULL, NULL, ctx))
        +			{
        +			ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 
        +			ctx) != 0)
        +			{
        +			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
        +			goto err;
        +			}
        +		}
        +	ok = 1;
        +err:
        +	if (ctx   != NULL)
        +		BN_CTX_free(ctx);
        +	if (point != NULL)
        +		EC_POINT_free(point);
        +	return(ok);
        +	}
        +
        +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y)
        +	{
        +	BN_CTX *ctx = NULL;
        +	BIGNUM *tx, *ty;
        +	EC_POINT *point = NULL;
        +	int ok = 0, tmp_nid, is_char_two = 0;
        +
        +	if (!key || !key->group || !x || !y)
        +		{
        +		ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
        +						ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	ctx = BN_CTX_new();
        +	if (!ctx)
        +		goto err;
        +
        +	point = EC_POINT_new(key->group);
        +
        +	if (!point)
        +		goto err;
        +
        +	tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
        +
        +        if (tmp_nid == NID_X9_62_characteristic_two_field)
        +		is_char_two = 1;
        +
        +	tx = BN_CTX_get(ctx);
        +	ty = BN_CTX_get(ctx);
        +#ifndef OPENSSL_NO_EC2M
        +	if (is_char_two)
        +		{
        +		if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
        +								x, y, ctx))
        +			goto err;
        +		if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
        +								tx, ty, ctx))
        +			goto err;
        +		}
        +	else
        +#endif
        +		{
        +		if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
        +								x, y, ctx))
        +			goto err;
        +		if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
        +								tx, ty, ctx))
        +			goto err;
        +		}
        +	/* Check if retrieved coordinates match originals: if not values
        +	 * are out of range.
        +	 */
        +	if (BN_cmp(x, tx) || BN_cmp(y, ty))
        +		{
        +		ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
        +			EC_R_COORDINATES_OUT_OF_RANGE);
        +		goto err;
        +		}
        +
        +	if (!EC_KEY_set_public_key(key, point))
        +		goto err;
        +
        +	if (EC_KEY_check_key(key) == 0)
        +		goto err;
        +
        +	ok = 1;
        +
        +	err:
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	if (point)
        +		EC_POINT_free(point);
        +	return ok;
        +
        +	}
        +
        +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
        +	{
        +	return key->group;
        +	}
        +
        +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
        +	{
        +	if (key->group != NULL)
        +		EC_GROUP_free(key->group);
        +	key->group = EC_GROUP_dup(group);
        +	return (key->group == NULL) ? 0 : 1;
        +	}
        +
        +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
        +	{
        +	return key->priv_key;
        +	}
        +
        +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
        +	{
        +	if (key->priv_key)
        +		BN_clear_free(key->priv_key);
        +	key->priv_key = BN_dup(priv_key);
        +	return (key->priv_key == NULL) ? 0 : 1;
        +	}
        +
        +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
        +	{
        +	return key->pub_key;
        +	}
        +
        +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
        +	{
        +	if (key->pub_key != NULL)
        +		EC_POINT_free(key->pub_key);
        +	key->pub_key = EC_POINT_dup(pub_key, key->group);
        +	return (key->pub_key == NULL) ? 0 : 1;
        +	}
        +
        +unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
        +	{
        +	return key->enc_flag;
        +	}
        +
        +void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
        +	{
        +	key->enc_flag = flags;
        +	}
        +
        +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
        +	{
        +	return key->conv_form;
        +	}
        +
        +void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
        +	{
        +	key->conv_form = cform;
        +	if (key->group != NULL)
        +		EC_GROUP_set_point_conversion_form(key->group, cform);
        +	}
        +
        +void *EC_KEY_get_key_method_data(EC_KEY *key,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        +	{
        +	void *ret;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_EC);
        +	ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
        +	CRYPTO_r_unlock(CRYPTO_LOCK_EC);
        +
        +	return ret;
        +	}
        +
        +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        +	{
        +	EC_EXTRA_DATA *ex_data;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_EC);
        +	ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
        +	if (ex_data == NULL)
        +		EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EC);
        +
        +	return ex_data;
        +	}
        +
        +void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
        +	{
        +	if (key->group != NULL)
        +		EC_GROUP_set_asn1_flag(key->group, flag);
        +	}
        +
        +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
        +	{
        +	if (key->group == NULL)
        +		return 0;
        +	return EC_GROUP_precompute_mult(key->group, ctx);
        +	}
        +
        +int EC_KEY_get_flags(const EC_KEY *key)
        +	{
        +	return key->flags;
        +	}
        +
        +void EC_KEY_set_flags(EC_KEY *key, int flags)
        +	{
        +	key->flags |= flags;
        +	}
        +
        +void EC_KEY_clear_flags(EC_KEY *key, int flags)
        +	{
        +	key->flags &= ~flags;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_lcl.h b/vendor/openssl/openssl/crypto/ec/ec_lcl.h
        new file mode 100644
        index 000000000..da7967df3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_lcl.h
        @@ -0,0 +1,446 @@
        +/* crypto/ec/ec_lcl.h */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +
        +#include <stdlib.h>
        +
        +#include <openssl/obj_mac.h>
        +#include <openssl/ec.h>
        +#include <openssl/bn.h>
        +
        +#if defined(__SUNPRO_C)
        +# if __SUNPRO_C >= 0x520
        +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
        +# endif
        +#endif
        +
        +/* Use default functions for poin2oct, oct2point and compressed coordinates */
        +#define EC_FLAGS_DEFAULT_OCT	0x1
        +
        +/* Structure details are not part of the exported interface,
        + * so all this may change in future versions. */
        +
        +struct ec_method_st {
        +	/* Various method flags */
        +	int flags;
        +	/* used by EC_METHOD_get_field_type: */
        +	int field_type; /* a NID */
        +
        +	/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
        +	int (*group_init)(EC_GROUP *);
        +	void (*group_finish)(EC_GROUP *);
        +	void (*group_clear_finish)(EC_GROUP *);
        +	int (*group_copy)(EC_GROUP *, const EC_GROUP *);
        +
        +	/* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
        +	/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
        +	int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +	int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
        +
        +	/* used by EC_GROUP_get_degree: */
        +	int (*group_get_degree)(const EC_GROUP *);
        +
        +	/* used by EC_GROUP_check: */
        +	int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
        +
        +	/* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
        +	int (*point_init)(EC_POINT *);
        +	void (*point_finish)(EC_POINT *);
        +	void (*point_clear_finish)(EC_POINT *);
        +	int (*point_copy)(EC_POINT *, const EC_POINT *);
        +
        +	/* used by EC_POINT_set_to_infinity,
        +	 * EC_POINT_set_Jprojective_coordinates_GFp,
        +	 * EC_POINT_get_Jprojective_coordinates_GFp,
        +	 * EC_POINT_set_affine_coordinates_GFp,     ..._GF2m,
        +	 * EC_POINT_get_affine_coordinates_GFp,     ..._GF2m,
        +	 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
        +	 */
        +	int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
        +	int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
        +		const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
        +	int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
        +		BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
        +	int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
        +		const BIGNUM *x, const BIGNUM *y, BN_CTX *);
        +	int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
        +		BIGNUM *x, BIGNUM *y, BN_CTX *);
        +	int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
        +		const BIGNUM *x, int y_bit, BN_CTX *);
        +
        +	/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
        +	size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
        +	        unsigned char *buf, size_t len, BN_CTX *);
        +	int (*oct2point)(const EC_GROUP *, EC_POINT *,
        +	        const unsigned char *buf, size_t len, BN_CTX *);
        +
        +	/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
        +	int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
        +	int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
        +	int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
        +
        +	/* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
        +	int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
        +	int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
        +	int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
        +
        +	/* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
        +	int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
        +	int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
        +
        +	/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
        +	 * (default implementations are used if the 'mul' pointer is 0): */
        +	int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +		size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +	int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
        +	int (*have_precompute_mult)(const EC_GROUP *group);
        +
        +
        +	/* internal functions */
        +
        +	/* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
        +	 * the same implementations of point operations can be used with different
        +	 * optimized implementations of expensive field operations: */
        +	int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +	int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +	int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +
        +	int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
        +	int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
        +	int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
        +} /* EC_METHOD */;
        +
        +typedef struct ec_extra_data_st {
        +	struct ec_extra_data_st *next;
        +	void *data;
        +	void *(*dup_func)(void *);
        +	void (*free_func)(void *);
        +	void (*clear_free_func)(void *);
        +} EC_EXTRA_DATA; /* used in EC_GROUP */
        +
        +struct ec_group_st {
        +	const EC_METHOD *meth;
        +
        +	EC_POINT *generator; /* optional */
        +	BIGNUM order, cofactor;
        +
        +	int curve_name;/* optional NID for named curve */
        +	int asn1_flag; /* flag to control the asn1 encoding */
        +	point_conversion_form_t asn1_form;
        +
        +	unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
        +	size_t seed_len;
        +
        +	EC_EXTRA_DATA *extra_data; /* linked list */
        +
        +	/* The following members are handled by the method functions,
        +	 * even if they appear generic */
        +	
        +	BIGNUM field; /* Field specification.
        +	               * For curves over GF(p), this is the modulus;
        +	               * for curves over GF(2^m), this is the 
        +	               * irreducible polynomial defining the field.
        +	               */
        +
        +	int poly[6]; /* Field specification for curves over GF(2^m).
        +	              * The irreducible f(t) is then of the form:
        +	              *     t^poly[0] + t^poly[1] + ... + t^poly[k]
        +	              * where m = poly[0] > poly[1] > ... > poly[k] = 0.
        +	              * The array is terminated with poly[k+1]=-1.
        +	              * All elliptic curve irreducibles have at most 5
        +	              * non-zero terms.
        +	              */
        +
        +	BIGNUM a, b; /* Curve coefficients.
        +	              * (Here the assumption is that BIGNUMs can be used
        +	              * or abused for all kinds of fields, not just GF(p).)
        +	              * For characteristic  > 3,  the curve is defined
        +	              * by a Weierstrass equation of the form
        +	              *     y^2 = x^3 + a*x + b.
        +	              * For characteristic  2,  the curve is defined by
        +	              * an equation of the form
        +	              *     y^2 + x*y = x^3 + a*x^2 + b.
        +	              */
        +
        +	int a_is_minus3; /* enable optimized point arithmetics for special case */
        +
        +	void *field_data1; /* method-specific (e.g., Montgomery structure) */
        +	void *field_data2; /* method-specific */
        +	int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *,	BN_CTX *); /* method-specific */
        +} /* EC_GROUP */;
        +
        +struct ec_key_st {
        +	int version;
        +
        +	EC_GROUP *group;
        +
        +	EC_POINT *pub_key;
        +	BIGNUM	 *priv_key;
        +
        +	unsigned int enc_flag;
        +	point_conversion_form_t conv_form;
        +
        +	int 	references;
        +	int	flags;
        +
        +	EC_EXTRA_DATA *method_data;
        +} /* EC_KEY */;
        +
        +/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
        + * (with visibility limited to 'package' level for now).
        + * We use the function pointers as index for retrieval; this obviates
        + * global ex_data-style index tables.
        + */
        +int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
        +void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
        +void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
        +void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
        +void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
        +void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
        +
        +
        +
        +struct ec_point_st {
        +	const EC_METHOD *meth;
        +
        +	/* All members except 'meth' are handled by the method functions,
        +	 * even if they appear generic */
        +
        +	BIGNUM X;
        +	BIGNUM Y;
        +	BIGNUM Z; /* Jacobian projective coordinates:
        +	           * (X, Y, Z)  represents  (X/Z^2, Y/Z^3)  if  Z != 0 */
        +	int Z_is_one; /* enable optimized point arithmetics for special case */
        +} /* EC_POINT */;
        +
        +
        +
        +/* method functions in ec_mult.c
        + * (ec_lib.c uses these as defaults if group->method->mul is 0) */
        +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
        +int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
        +
        +
        +/* method functions in ecp_smpl.c */
        +int ec_GFp_simple_group_init(EC_GROUP *);
        +void ec_GFp_simple_group_finish(EC_GROUP *);
        +void ec_GFp_simple_group_clear_finish(EC_GROUP *);
        +int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
        +int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
        +int ec_GFp_simple_group_get_degree(const EC_GROUP *);
        +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
        +int ec_GFp_simple_point_init(EC_POINT *);
        +void ec_GFp_simple_point_finish(EC_POINT *);
        +void ec_GFp_simple_point_clear_finish(EC_POINT *);
        +int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
        +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
        +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
        +	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
        +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
        +	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
        +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
        +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
        +	BIGNUM *x, BIGNUM *y, BN_CTX *);
        +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
        +	const BIGNUM *x, int y_bit, BN_CTX *);
        +size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
        +	unsigned char *buf, size_t len, BN_CTX *);
        +int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
        +	const unsigned char *buf, size_t len, BN_CTX *);
        +int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
        +int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
        +int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
        +int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
        +int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
        +int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
        +int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
        +int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
        +int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +
        +
        +/* method functions in ecp_mont.c */
        +int ec_GFp_mont_group_init(EC_GROUP *);
        +int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +void ec_GFp_mont_group_finish(EC_GROUP *);
        +void ec_GFp_mont_group_clear_finish(EC_GROUP *);
        +int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
        +int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
        +
        +
        +/* method functions in ecp_nist.c */
        +int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
        +int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +
        +
        +/* method functions in ec2_smpl.c */
        +int ec_GF2m_simple_group_init(EC_GROUP *);
        +void ec_GF2m_simple_group_finish(EC_GROUP *);
        +void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
        +int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
        +int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
        +int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
        +int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
        +int ec_GF2m_simple_point_init(EC_POINT *);
        +void ec_GF2m_simple_point_finish(EC_POINT *);
        +void ec_GF2m_simple_point_clear_finish(EC_POINT *);
        +int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
        +int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
        +int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
        +int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
        +	BIGNUM *x, BIGNUM *y, BN_CTX *);
        +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
        +	const BIGNUM *x, int y_bit, BN_CTX *);
        +size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
        +	unsigned char *buf, size_t len, BN_CTX *);
        +int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
        +	const unsigned char *buf, size_t len, BN_CTX *);
        +int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
        +int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
        +int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
        +int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
        +int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
        +int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
        +int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
        +int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
        +int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
        +int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
        +
        +
        +/* method functions in ec2_mult.c */
        +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
        +int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
        +
        +/* method functions in ec2_mult.c */
        +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
        +int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
        +
        +#ifndef OPENSSL_EC_NISTP_64_GCC_128
        +/* method functions in ecp_nistp224.c */
        +int ec_GFp_nistp224_group_init(EC_GROUP *group);
        +int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
        +int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
        +int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
        +int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
        +int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
        +
        +/* method functions in ecp_nistp256.c */
        +int ec_GFp_nistp256_group_init(EC_GROUP *group);
        +int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
        +int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
        +int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
        +int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
        +int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
        +
        +/* method functions in ecp_nistp521.c */
        +int ec_GFp_nistp521_group_init(EC_GROUP *group);
        +int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
        +int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
        +int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
        +int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
        +int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
        +int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
        +
        +/* utility functions in ecp_nistputil.c */
        +void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
        +	size_t felem_size, void *tmp_felems,
        +	void (*felem_one)(void *out),
        +	int (*felem_is_zero)(const void *in),
        +	void (*felem_assign)(void *out, const void *in),
        +	void (*felem_square)(void *out, const void *in),
        +	void (*felem_mul)(void *out, const void *in1, const void *in2),
        +	void (*felem_inv)(void *out, const void *in),
        +	void (*felem_contract)(void *out, const void *in));
        +void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in);
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_lib.c b/vendor/openssl/openssl/crypto/ec/ec_lib.c
        new file mode 100644
        index 000000000..25247b580
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_lib.c
        @@ -0,0 +1,1096 @@
        +/* crypto/ec/ec_lib.c */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Binary polynomial ECC support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include <string.h>
        +
        +#include <openssl/err.h>
        +#include <openssl/opensslv.h>
        +
        +#include "ec_lcl.h"
        +
        +static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
        +
        +
        +/* functions for EC_GROUP objects */
        +
        +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
        +	{
        +	EC_GROUP *ret;
        +
        +	if (meth == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
        +		return NULL;
        +		}
        +	if (meth->group_init == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return NULL;
        +		}
        +
        +	ret = OPENSSL_malloc(sizeof *ret);
        +	if (ret == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	ret->meth = meth;
        +
        +	ret->extra_data = NULL;
        +
        +	ret->generator = NULL;
        +	BN_init(&ret->order);
        +	BN_init(&ret->cofactor);
        +
        +	ret->curve_name = 0;	
        +	ret->asn1_flag  = 0;
        +	ret->asn1_form  = POINT_CONVERSION_UNCOMPRESSED;
        +
        +	ret->seed = NULL;
        +	ret->seed_len = 0;
        +
        +	if (!meth->group_init(ret))
        +		{
        +		OPENSSL_free(ret);
        +		return NULL;
        +		}
        +	
        +	return ret;
        +	}
        +
        +
        +void EC_GROUP_free(EC_GROUP *group)
        +	{
        +	if (!group) return;
        +
        +	if (group->meth->group_finish != 0)
        +		group->meth->group_finish(group);
        +
        +	EC_EX_DATA_free_all_data(&group->extra_data);
        +
        +	if (group->generator != NULL)
        +		EC_POINT_free(group->generator);
        +	BN_free(&group->order);
        +	BN_free(&group->cofactor);
        +
        +	if (group->seed)
        +		OPENSSL_free(group->seed);
        +
        +	OPENSSL_free(group);
        +	}
        + 
        +
        +void EC_GROUP_clear_free(EC_GROUP *group)
        +	{
        +	if (!group) return;
        +
        +	if (group->meth->group_clear_finish != 0)
        +		group->meth->group_clear_finish(group);
        +	else if (group->meth->group_finish != 0)
        +		group->meth->group_finish(group);
        +
        +	EC_EX_DATA_clear_free_all_data(&group->extra_data);
        +
        +	if (group->generator != NULL)
        +		EC_POINT_clear_free(group->generator);
        +	BN_clear_free(&group->order);
        +	BN_clear_free(&group->cofactor);
        +
        +	if (group->seed)
        +		{
        +		OPENSSL_cleanse(group->seed, group->seed_len);
        +		OPENSSL_free(group->seed);
        +		}
        +
        +	OPENSSL_cleanse(group, sizeof *group);
        +	OPENSSL_free(group);
        +	}
        +
        +
        +int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
        +	{
        +	EC_EXTRA_DATA *d;
        +
        +	if (dest->meth->group_copy == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (dest->meth != src->meth)
        +		{
        +		ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	if (dest == src)
        +		return 1;
        +	
        +	EC_EX_DATA_free_all_data(&dest->extra_data);
        +
        +	for (d = src->extra_data; d != NULL; d = d->next)
        +		{
        +		void *t = d->dup_func(d->data);
        +		
        +		if (t == NULL)
        +			return 0;
        +		if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, d->free_func, d->clear_free_func))
        +			return 0;
        +		}
        +
        +	if (src->generator != NULL)
        +		{
        +		if (dest->generator == NULL)
        +			{
        +			dest->generator = EC_POINT_new(dest);
        +			if (dest->generator == NULL) return 0;
        +			}
        +		if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
        +		}
        +	else
        +		{
        +		/* src->generator == NULL */
        +		if (dest->generator != NULL)
        +			{
        +			EC_POINT_clear_free(dest->generator);
        +			dest->generator = NULL;
        +			}
        +		}
        +
        +	if (!BN_copy(&dest->order, &src->order)) return 0;
        +	if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
        +
        +	dest->curve_name = src->curve_name;
        +	dest->asn1_flag  = src->asn1_flag;
        +	dest->asn1_form  = src->asn1_form;
        +
        +	if (src->seed)
        +		{
        +		if (dest->seed)
        +			OPENSSL_free(dest->seed);
        +		dest->seed = OPENSSL_malloc(src->seed_len);
        +		if (dest->seed == NULL)
        +			return 0;
        +		if (!memcpy(dest->seed, src->seed, src->seed_len))
        +			return 0;
        +		dest->seed_len = src->seed_len;
        +		}
        +	else
        +		{
        +		if (dest->seed)
        +			OPENSSL_free(dest->seed);
        +		dest->seed = NULL;
        +		dest->seed_len = 0;
        +		}
        +	
        +
        +	return dest->meth->group_copy(dest, src);
        +	}
        +
        +
        +EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
        +	{
        +	EC_GROUP *t = NULL;
        +	int ok = 0;
        +
        +	if (a == NULL) return NULL;
        +
        +	if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
        +	if (!EC_GROUP_copy(t, a)) goto err;
        +
        +	ok = 1;
        +
        +  err:	
        +	if (!ok)
        +		{
        +		if (t) EC_GROUP_free(t);
        +		return NULL;
        +		}
        +	else return t;
        +	}
        +
        +
        +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
        +	{
        +	return group->meth;
        +	}
        +
        +
        +int EC_METHOD_get_field_type(const EC_METHOD *meth)
        +        {
        +        return meth->field_type;
        +        }
        +
        +
        +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
        +	{
        +	if (generator == NULL)
        +		{
        +		ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0   ;
        +		}
        +
        +	if (group->generator == NULL)
        +		{
        +		group->generator = EC_POINT_new(group);
        +		if (group->generator == NULL) return 0;
        +		}
        +	if (!EC_POINT_copy(group->generator, generator)) return 0;
        +
        +	if (order != NULL)
        +		{ if (!BN_copy(&group->order, order)) return 0; }	
        +	else
        +		BN_zero(&group->order);
        +
        +	if (cofactor != NULL)
        +		{ if (!BN_copy(&group->cofactor, cofactor)) return 0; }	
        +	else
        +		BN_zero(&group->cofactor);
        +
        +	return 1;
        +	}
        +
        +
        +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
        +	{
        +	return group->generator;
        +	}
        +
        +
        +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
        +	{
        +	if (!BN_copy(order, &group->order))
        +		return 0;
        +
        +	return !BN_is_zero(order);
        +	}
        +
        +
        +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
        +	{
        +	if (!BN_copy(cofactor, &group->cofactor))
        +		return 0;
        +
        +	return !BN_is_zero(&group->cofactor);
        +	}
        +
        +
        +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
        +	{
        +	group->curve_name = nid;
        +	}
        +
        +
        +int EC_GROUP_get_curve_name(const EC_GROUP *group)
        +	{
        +	return group->curve_name;
        +	}
        +
        +
        +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
        +	{
        +	group->asn1_flag = flag;
        +	}
        +
        +
        +int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
        +	{
        +	return group->asn1_flag;
        +	}
        +
        +
        +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 
        +                                        point_conversion_form_t form)
        +	{
        +	group->asn1_form = form;
        +	}
        +
        +
        +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
        +	{
        +	return group->asn1_form;
        +	}
        +
        +
        +size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
        +	{
        +	if (group->seed)
        +		{
        +		OPENSSL_free(group->seed);
        +		group->seed = NULL;
        +		group->seed_len = 0;
        +		}
        +
        +	if (!len || !p)
        +		return 1;
        +
        +	if ((group->seed = OPENSSL_malloc(len)) == NULL)
        +		return 0;
        +	memcpy(group->seed, p, len);
        +	group->seed_len = len;
        +
        +	return len;
        +	}
        +
        +
        +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
        +	{
        +	return group->seed;
        +	}
        +
        +
        +size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
        +	{
        +	return group->seed_len;
        +	}
        +
        +
        +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	if (group->meth->group_set_curve == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	return group->meth->group_set_curve(group, p, a, b, ctx);
        +	}
        +
        +
        +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
        +	{
        +	if (group->meth->group_get_curve == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	return group->meth->group_get_curve(group, p, a, b, ctx);
        +	}
        +
        +#ifndef OPENSSL_NO_EC2M
        +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	if (group->meth->group_set_curve == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	return group->meth->group_set_curve(group, p, a, b, ctx);
        +	}
        +
        +
        +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
        +	{
        +	if (group->meth->group_get_curve == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	return group->meth->group_get_curve(group, p, a, b, ctx);
        +	}
        +#endif
        +
        +int EC_GROUP_get_degree(const EC_GROUP *group)
        +	{
        +	if (group->meth->group_get_degree == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	return group->meth->group_get_degree(group);
        +	}
        +
        +
        +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	if (group->meth->group_check_discriminant == 0)
        +		{
        +		ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	return group->meth->group_check_discriminant(group, ctx);
        +	}
        +
        +
        +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
        +	{
        +	int    r = 0;
        +	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
        +	BN_CTX *ctx_new = NULL;
        +
        +	/* compare the field types*/
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
        +	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
        +		return 1;
        +	/* compare the curve name (if present) */
        +	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
        +	    EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
        +		return 0;
        +
        +	if (!ctx)
        +		ctx_new = ctx = BN_CTX_new();
        +	if (!ctx)
        +		return -1;
        +	
        +	BN_CTX_start(ctx);
        +	a1 = BN_CTX_get(ctx);
        +	a2 = BN_CTX_get(ctx);
        +	a3 = BN_CTX_get(ctx);
        +	b1 = BN_CTX_get(ctx);
        +	b2 = BN_CTX_get(ctx);
        +	b3 = BN_CTX_get(ctx);
        +	if (!b3)
        +		{
        +		BN_CTX_end(ctx);
        +		if (ctx_new)
        +			BN_CTX_free(ctx);
        +		return -1;
        +		}
        +
        +	/* XXX This approach assumes that the external representation
        +	 * of curves over the same field type is the same.
        +	 */
        +	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
        +	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
        +		r = 1;
        +
        +	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
        +		r = 1;
        +
        +	/* XXX EC_POINT_cmp() assumes that the methods are equal */
        +	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
        +	    EC_GROUP_get0_generator(b), ctx))
        +		r = 1;
        +
        +	if (!r)
        +		{
        +		/* compare the order and cofactor */
        +		if (!EC_GROUP_get_order(a, a1, ctx) ||
        +		    !EC_GROUP_get_order(b, b1, ctx) ||
        +		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
        +		    !EC_GROUP_get_cofactor(b, b2, ctx))
        +			{
        +			BN_CTX_end(ctx);
        +			if (ctx_new)
        +				BN_CTX_free(ctx);
        +			return -1;
        +			}
        +		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
        +			r = 1;
        +		}
        +
        +	BN_CTX_end(ctx);
        +	if (ctx_new)
        +		BN_CTX_free(ctx);
        +
        +	return r;
        +	}
        +
        +
        +/* this has 'package' visibility */
        +int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        +	{
        +	EC_EXTRA_DATA *d;
        +
        +	if (ex_data == NULL)
        +		return 0;
        +
        +	for (d = *ex_data; d != NULL; d = d->next)
        +		{
        +		if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
        +			{
        +			ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
        +			return 0;
        +			}
        +		}
        +
        +	if (data == NULL)
        +		/* no explicit entry needed */
        +		return 1;
        +
        +	d = OPENSSL_malloc(sizeof *d);
        +	if (d == NULL)
        +		return 0;
        +
        +	d->data = data;
        +	d->dup_func = dup_func;
        +	d->free_func = free_func;
        +	d->clear_free_func = clear_free_func;
        +
        +	d->next = *ex_data;
        +	*ex_data = d;
        +
        +	return 1;
        +	}
        +
        +/* this has 'package' visibility */
        +void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        +	{
        +	const EC_EXTRA_DATA *d;
        +
        +	for (d = ex_data; d != NULL; d = d->next)
        +		{
        +		if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
        +			return d->data;
        +		}
        +	
        +	return NULL;
        +	}
        +
        +/* this has 'package' visibility */
        +void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        +	{
        +	EC_EXTRA_DATA **p;
        +
        +	if (ex_data == NULL)
        +		return;
        +
        +	for (p = ex_data; *p != NULL; p = &((*p)->next))
        +		{
        +		if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
        +			{
        +			EC_EXTRA_DATA *next = (*p)->next;
        +
        +			(*p)->free_func((*p)->data);
        +			OPENSSL_free(*p);
        +			
        +			*p = next;
        +			return;
        +			}
        +		}
        +	}
        +
        +/* this has 'package' visibility */
        +void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
        +	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        +	{
        +	EC_EXTRA_DATA **p;
        +
        +	if (ex_data == NULL)
        +		return;
        +
        +	for (p = ex_data; *p != NULL; p = &((*p)->next))
        +		{
        +		if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
        +			{
        +			EC_EXTRA_DATA *next = (*p)->next;
        +
        +			(*p)->clear_free_func((*p)->data);
        +			OPENSSL_free(*p);
        +			
        +			*p = next;
        +			return;
        +			}
        +		}
        +	}
        +
        +/* this has 'package' visibility */
        +void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
        +	{
        +	EC_EXTRA_DATA *d;
        +
        +	if (ex_data == NULL)
        +		return;
        +
        +	d = *ex_data;
        +	while (d)
        +		{
        +		EC_EXTRA_DATA *next = d->next;
        +		
        +		d->free_func(d->data);
        +		OPENSSL_free(d);
        +		
        +		d = next;
        +		}
        +	*ex_data = NULL;
        +	}
        +
        +/* this has 'package' visibility */
        +void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
        +	{
        +	EC_EXTRA_DATA *d;
        +
        +	if (ex_data == NULL)
        +		return;
        +
        +	d = *ex_data;
        +	while (d)
        +		{
        +		EC_EXTRA_DATA *next = d->next;
        +		
        +		d->clear_free_func(d->data);
        +		OPENSSL_free(d);
        +		
        +		d = next;
        +		}
        +	*ex_data = NULL;
        +	}
        +
        +
        +/* functions for EC_POINT objects */
        +
        +EC_POINT *EC_POINT_new(const EC_GROUP *group)
        +	{
        +	EC_POINT *ret;
        +
        +	if (group == NULL)
        +		{
        +		ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if (group->meth->point_init == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return NULL;
        +		}
        +
        +	ret = OPENSSL_malloc(sizeof *ret);
        +	if (ret == NULL)
        +		{
        +		ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	ret->meth = group->meth;
        +	
        +	if (!ret->meth->point_init(ret))
        +		{
        +		OPENSSL_free(ret);
        +		return NULL;
        +		}
        +	
        +	return ret;
        +	}
        +
        +
        +void EC_POINT_free(EC_POINT *point)
        +	{
        +	if (!point) return;
        +
        +	if (point->meth->point_finish != 0)
        +		point->meth->point_finish(point);
        +	OPENSSL_free(point);
        +	}
        + 
        +
        +void EC_POINT_clear_free(EC_POINT *point)
        +	{
        +	if (!point) return;
        +
        +	if (point->meth->point_clear_finish != 0)
        +		point->meth->point_clear_finish(point);
        +	else if (point->meth->point_finish != 0)
        +		point->meth->point_finish(point);
        +	OPENSSL_cleanse(point, sizeof *point);
        +	OPENSSL_free(point);
        +	}
        +
        +
        +int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
        +	{
        +	if (dest->meth->point_copy == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (dest->meth != src->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	if (dest == src)
        +		return 1;
        +	return dest->meth->point_copy(dest, src);
        +	}
        +
        +
        +EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
        +	{
        +	EC_POINT *t;
        +	int r;
        +
        +	if (a == NULL) return NULL;
        +
        +	t = EC_POINT_new(group);
        +	if (t == NULL) return(NULL);
        +	r = EC_POINT_copy(t, a);
        +	if (!r)
        +		{
        +		EC_POINT_free(t);
        +		return NULL;
        +		}
        +	else return t;
        +	}
        +
        +
        +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
        +	{
        +	return point->meth;
        +	}
        +
        +
        +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
        +	{
        +	if (group->meth->point_set_to_infinity == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_set_to_infinity(group, point);
        +	}
        +
        +
        +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_set_Jprojective_coordinates_GFp == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
        +	}
        +
        +
        +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
        +	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_get_Jprojective_coordinates_GFp == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
        +	}
        +
        +
        +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_set_affine_coordinates == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
        +	}
        +
        +#ifndef OPENSSL_NO_EC2M
        +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_set_affine_coordinates == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
        +	}
        +#endif
        +
        +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
        +	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_get_affine_coordinates == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
        +	}
        +
        +#ifndef OPENSSL_NO_EC2M
        +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
        +	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_get_affine_coordinates == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
        +	}
        +#endif
        +
        +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
        +	{
        +	if (group->meth->add == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
        +		{
        +		ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->add(group, r, a, b, ctx);
        +	}
        +
        +
        +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
        +	{
        +	if (group->meth->dbl == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if ((group->meth != r->meth) || (r->meth != a->meth))
        +		{
        +		ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->dbl(group, r, a, ctx);
        +	}
        +
        +
        +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
        +	{
        +	if (group->meth->dbl == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != a->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->invert(group, a, ctx);
        +	}
        +
        +
        +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
        +	{
        +	if (group->meth->is_at_infinity == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->is_at_infinity(group, point);
        +	}
        +
        +
        +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
        +	{
        +	if (group->meth->is_on_curve == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->is_on_curve(group, point, ctx);
        +	}
        +
        +
        +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_cmp == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if ((group->meth != a->meth) || (a->meth != b->meth))
        +		{
        +		ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->point_cmp(group, a, b, ctx);
        +	}
        +
        +
        +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
        +	{
        +	if (group->meth->make_affine == 0)
        +		{
        +		ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	return group->meth->make_affine(group, point, ctx);
        +	}
        +
        +
        +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
        +	{
        +	size_t i;
        +
        +	if (group->meth->points_make_affine == 0)
        +		{
        +		ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	for (i = 0; i < num; i++)
        +		{
        +		if (group->meth != points[i]->meth)
        +			{
        +			ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
        +			return 0;
        +			}
        +		}
        +	return group->meth->points_make_affine(group, num, points, ctx);
        +	}
        +
        +
        +/* Functions for point multiplication.
        + *
        + * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
        + * otherwise we dispatch through methods.
        + */
        +
        +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
        +	{
        +	if (group->meth->mul == 0)
        +		/* use default */
        +		return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
        +
        +	return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
        +	}
        +
        +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
        +	const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
        +	{
        +	/* just a convenient interface to EC_POINTs_mul() */
        +
        +	const EC_POINT *points[1];
        +	const BIGNUM *scalars[1];
        +
        +	points[0] = point;
        +	scalars[0] = p_scalar;
        +
        +	return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
        +	}
        +
        +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	if (group->meth->mul == 0)
        +		/* use default */
        +		return ec_wNAF_precompute_mult(group, ctx);
        +
        +	if (group->meth->precompute_mult != 0)
        +		return group->meth->precompute_mult(group, ctx);
        +	else
        +		return 1; /* nothing to do, so report success */
        +	}
        +
        +int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
        +	{
        +	if (group->meth->mul == 0)
        +		/* use default */
        +		return ec_wNAF_have_precompute_mult(group);
        +
        +	if (group->meth->have_precompute_mult != 0)
        +		return group->meth->have_precompute_mult(group);
        +	else
        +		return 0; /* cannot tell whether precomputation has been performed */
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_mult.c b/vendor/openssl/openssl/crypto/ec/ec_mult.c
        new file mode 100644
        index 000000000..19f21675f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_mult.c
        @@ -0,0 +1,940 @@
        +/* crypto/ec/ec_mult.c */
        +/*
        + * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions of this software developed by SUN MICROSYSTEMS, INC.,
        + * and contributed to the OpenSSL project.
        + */
        +
        +#include <string.h>
        +
        +#include <openssl/err.h>
        +
        +#include "ec_lcl.h"
        +
        +
        +/*
        + * This file implements the wNAF-based interleaving multi-exponentation method
        + * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
        + * for multiplication with precomputation, we use wNAF splitting
        + * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
        + */
        +
        +
        +
        +
        +/* structure for precomputed multiples of the generator */
        +typedef struct ec_pre_comp_st {
        +	const EC_GROUP *group; /* parent EC_GROUP object */
        +	size_t blocksize;      /* block size for wNAF splitting */
        +	size_t numblocks;      /* max. number of blocks for which we have precomputation */
        +	size_t w;              /* window size */
        +	EC_POINT **points;     /* array with pre-calculated multiples of generator:
        +	                        * 'num' pointers to EC_POINT objects followed by a NULL */
        +	size_t num;            /* numblocks * 2^(w-1) */
        +	int references;
        +} EC_PRE_COMP;
        + 
        +/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
        +static void *ec_pre_comp_dup(void *);
        +static void ec_pre_comp_free(void *);
        +static void ec_pre_comp_clear_free(void *);
        +
        +static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
        +	{
        +	EC_PRE_COMP *ret = NULL;
        +
        +	if (!group)
        +		return NULL;
        +
        +	ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
        +	if (!ret)
        +		{
        +		ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
        +		return ret;
        +		}
        +	ret->group = group;
        +	ret->blocksize = 8; /* default */
        +	ret->numblocks = 0;
        +	ret->w = 4; /* default */
        +	ret->points = NULL;
        +	ret->num = 0;
        +	ret->references = 1;
        +	return ret;
        +	}
        +
        +static void *ec_pre_comp_dup(void *src_)
        +	{
        +	EC_PRE_COMP *src = src_;
        +
        +	/* no need to actually copy, these objects never change! */
        +
        +	CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
        +
        +	return src_;
        +	}
        +
        +static void ec_pre_comp_free(void *pre_)
        +	{
        +	int i;
        +	EC_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	if (pre->points)
        +		{
        +		EC_POINT **p;
        +
        +		for (p = pre->points; *p != NULL; p++)
        +			EC_POINT_free(*p);
        +		OPENSSL_free(pre->points);
        +		}
        +	OPENSSL_free(pre);
        +	}
        +
        +static void ec_pre_comp_clear_free(void *pre_)
        +	{
        +	int i;
        +	EC_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	if (pre->points)
        +		{
        +		EC_POINT **p;
        +
        +		for (p = pre->points; *p != NULL; p++)
        +			{
        +			EC_POINT_clear_free(*p);
        +			OPENSSL_cleanse(p, sizeof *p);
        +			}
        +		OPENSSL_free(pre->points);
        +		}
        +	OPENSSL_cleanse(pre, sizeof *pre);
        +	OPENSSL_free(pre);
        +	}
        +
        +
        +
        +
        +/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
        + * This is an array  r[]  of values that are either zero or odd with an
        + * absolute value less than  2^w  satisfying
        + *     scalar = \sum_j r[j]*2^j
        + * where at most one of any  w+1  consecutive digits is non-zero
        + * with the exception that the most significant digit may be only
        + * w-1 zeros away from that next non-zero digit.
        + */
        +static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
        +	{
        +	int window_val;
        +	int ok = 0;
        +	signed char *r = NULL;
        +	int sign = 1;
        +	int bit, next_bit, mask;
        +	size_t len = 0, j;
        +	
        +	if (BN_is_zero(scalar))
        +		{
        +		r = OPENSSL_malloc(1);
        +		if (!r)
        +			{
        +			ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		r[0] = 0;
        +		*ret_len = 1;
        +		return r;
        +		}
        +		
        +	if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */
        +		{
        +		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +	bit = 1 << w; /* at most 128 */
        +	next_bit = bit << 1; /* at most 256 */
        +	mask = next_bit - 1; /* at most 255 */
        +
        +	if (BN_is_negative(scalar))
        +		{
        +		sign = -1;
        +		}
        +
        +	if (scalar->d == NULL || scalar->top == 0)
        +		{
        +		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +
        +	len = BN_num_bits(scalar);
        +	r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation
        +	                              * (*ret_len will be set to the actual length, i.e. at most
        +	                              * BN_num_bits(scalar) + 1) */
        +	if (r == NULL)
        +		{
        +		ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	window_val = scalar->d[0] & mask;
        +	j = 0;
        +	while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */
        +		{
        +		int digit = 0;
        +
        +		/* 0 <= window_val <= 2^(w+1) */
        +
        +		if (window_val & 1)
        +			{
        +			/* 0 < window_val < 2^(w+1) */
        +
        +			if (window_val & bit)
        +				{
        +				digit = window_val - next_bit; /* -2^w < digit < 0 */
        +
        +#if 1 /* modified wNAF */
        +				if (j + w + 1 >= len)
        +					{
        +					/* special case for generating modified wNAFs:
        +					 * no new bits will be added into window_val,
        +					 * so using a positive digit here will decrease
        +					 * the total length of the representation */
        +					
        +					digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
        +					}
        +#endif
        +				}
        +			else
        +				{
        +				digit = window_val; /* 0 < digit < 2^w */
        +				}
        +			
        +			if (digit <= -bit || digit >= bit || !(digit & 1))
        +				{
        +				ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			window_val -= digit;
        +
        +			/* now window_val is 0 or 2^(w+1) in standard wNAF generation;
        +			 * for modified window NAFs, it may also be 2^w
        +			 */
        +			if (window_val != 0 && window_val != next_bit && window_val != bit)
        +				{
        +				ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			}
        +
        +		r[j++] = sign * digit;
        +
        +		window_val >>= 1;
        +		window_val += bit * BN_is_bit_set(scalar, j + w);
        +
        +		if (window_val > next_bit)
        +			{
        +			ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		}
        +
        +	if (j > len + 1)
        +		{
        +		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +	len = j;
        +	ok = 1;
        +
        + err:
        +	if (!ok)
        +		{
        +		OPENSSL_free(r);
        +		r = NULL;
        +		}
        +	if (ok)
        +		*ret_len = len;
        +	return r;
        +	}
        +
        +
        +/* TODO: table should be optimised for the wNAF-based implementation,
        + *       sometimes smaller windows will give better performance
        + *       (thus the boundaries should be increased)
        + */
        +#define EC_window_bits_for_scalar_size(b) \
        +		((size_t) \
        +		 ((b) >= 2000 ? 6 : \
        +		  (b) >=  800 ? 5 : \
        +		  (b) >=  300 ? 4 : \
        +		  (b) >=   70 ? 3 : \
        +		  (b) >=   20 ? 2 : \
        +		  1))
        +
        +/* Compute
        + *      \sum scalars[i]*points[i],
        + * also including
        + *      scalar*generator
        + * in the addition if scalar != NULL
        + */
        +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        +	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	const EC_POINT *generator = NULL;
        +	EC_POINT *tmp = NULL;
        +	size_t totalnum;
        +	size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
        +	size_t pre_points_per_block = 0;
        +	size_t i, j;
        +	int k;
        +	int r_is_inverted = 0;
        +	int r_is_at_infinity = 1;
        +	size_t *wsize = NULL; /* individual window sizes */
        +	signed char **wNAF = NULL; /* individual wNAFs */
        +	size_t *wNAF_len = NULL;
        +	size_t max_len = 0;
        +	size_t num_val;
        +	EC_POINT **val = NULL; /* precomputation */
        +	EC_POINT **v;
        +	EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
        +	const EC_PRE_COMP *pre_comp = NULL;
        +	int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like other scalars,
        +	                     * i.e. precomputation is not available */
        +	int ret = 0;
        +	
        +	if (group->meth != r->meth)
        +		{
        +		ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +
        +	if ((scalar == NULL) && (num == 0))
        +		{
        +		return EC_POINT_set_to_infinity(group, r);
        +		}
        +
        +	for (i = 0; i < num; i++)
        +		{
        +		if (group->meth != points[i]->meth)
        +			{
        +			ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
        +			return 0;
        +			}
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			goto err;
        +		}
        +
        +	if (scalar != NULL)
        +		{
        +		generator = EC_GROUP_get0_generator(group);
        +		if (generator == NULL)
        +			{
        +			ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
        +			goto err;
        +			}
        +		
        +		/* look if we can use precomputed multiples of generator */
        +
        +		pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
        +
        +		if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0))
        +			{
        +			blocksize = pre_comp->blocksize;
        +
        +			/* determine maximum number of blocks that wNAF splitting may yield
        +			 * (NB: maximum wNAF length is bit length plus one) */
        +			numblocks = (BN_num_bits(scalar) / blocksize) + 1;
        +
        +			/* we cannot use more blocks than we have precomputation for */
        +			if (numblocks > pre_comp->numblocks)
        +				numblocks = pre_comp->numblocks;
        +
        +			pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
        +
        +			/* check that pre_comp looks sane */
        +			if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block))
        +				{
        +				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			}
        +		else
        +			{
        +			/* can't use precomputation */
        +			pre_comp = NULL;
        +			numblocks = 1;
        +			num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
        +			}
        +		}
        +	
        +	totalnum = num + numblocks;
        +
        +	wsize    = OPENSSL_malloc(totalnum * sizeof wsize[0]);
        +	wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
        +	wNAF     = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */
        +	val_sub  = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
        +		 
        +	if (!wsize || !wNAF_len || !wNAF || !val_sub)
        +		{
        +		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	wNAF[0] = NULL;	/* preliminary pivot */
        +
        +	/* num_val will be the total number of temporarily precomputed points */
        +	num_val = 0;
        +
        +	for (i = 0; i < num + num_scalar; i++)
        +		{
        +		size_t bits;
        +
        +		bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
        +		wsize[i] = EC_window_bits_for_scalar_size(bits);
        +		num_val += (size_t)1 << (wsize[i] - 1);
        +		wNAF[i + 1] = NULL; /* make sure we always have a pivot */
        +		wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
        +		if (wNAF[i] == NULL)
        +			goto err;
        +		if (wNAF_len[i] > max_len)
        +			max_len = wNAF_len[i];
        +		}
        +
        +	if (numblocks)
        +		{
        +		/* we go here iff scalar != NULL */
        +		
        +		if (pre_comp == NULL)
        +			{
        +			if (num_scalar != 1)
        +				{
        +				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			/* we have already generated a wNAF for 'scalar' */
        +			}
        +		else
        +			{
        +			signed char *tmp_wNAF = NULL;
        +			size_t tmp_len = 0;
        +			
        +			if (num_scalar != 0)
        +				{
        +				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			/* use the window size for which we have precomputation */
        +			wsize[num] = pre_comp->w;
        +			tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
        +			if (!tmp_wNAF)
        +				goto err;
        +
        +			if (tmp_len <= max_len)
        +				{
        +				/* One of the other wNAFs is at least as long
        +				 * as the wNAF belonging to the generator,
        +				 * so wNAF splitting will not buy us anything. */
        +
        +				numblocks = 1;
        +				totalnum = num + 1; /* don't use wNAF splitting */
        +				wNAF[num] = tmp_wNAF;
        +				wNAF[num + 1] = NULL;
        +				wNAF_len[num] = tmp_len;
        +				if (tmp_len > max_len)
        +					max_len = tmp_len;
        +				/* pre_comp->points starts with the points that we need here: */
        +				val_sub[num] = pre_comp->points;
        +				}
        +			else
        +				{
        +				/* don't include tmp_wNAF directly into wNAF array
        +				 * - use wNAF splitting and include the blocks */
        +
        +				signed char *pp;
        +				EC_POINT **tmp_points;
        +				
        +				if (tmp_len < numblocks * blocksize)
        +					{
        +					/* possibly we can do with fewer blocks than estimated */
        +					numblocks = (tmp_len + blocksize - 1) / blocksize;
        +					if (numblocks > pre_comp->numblocks)
        +						{
        +						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +						goto err;
        +						}
        +					totalnum = num + numblocks;
        +					}
        +				
        +				/* split wNAF in 'numblocks' parts */
        +				pp = tmp_wNAF;
        +				tmp_points = pre_comp->points;
        +
        +				for (i = num; i < totalnum; i++)
        +					{
        +					if (i < totalnum - 1)
        +						{
        +						wNAF_len[i] = blocksize;
        +						if (tmp_len < blocksize)
        +							{
        +							ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +							goto err;
        +							}
        +						tmp_len -= blocksize;
        +						}
        +					else
        +						/* last block gets whatever is left
        +						 * (this could be more or less than 'blocksize'!) */
        +						wNAF_len[i] = tmp_len;
        +					
        +					wNAF[i + 1] = NULL;
        +					wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
        +					if (wNAF[i] == NULL)
        +						{
        +						ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
        +						OPENSSL_free(tmp_wNAF);
        +						goto err;
        +						}
        +					memcpy(wNAF[i], pp, wNAF_len[i]);
        +					if (wNAF_len[i] > max_len)
        +						max_len = wNAF_len[i];
        +
        +					if (*tmp_points == NULL)
        +						{
        +						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +						OPENSSL_free(tmp_wNAF);
        +						goto err;
        +						}
        +					val_sub[i] = tmp_points;
        +					tmp_points += pre_points_per_block;
        +					pp += blocksize;
        +					}
        +				OPENSSL_free(tmp_wNAF);
        +				}
        +			}
        +		}
        +
        +	/* All points we precompute now go into a single array 'val'.
        +	 * 'val_sub[i]' is a pointer to the subarray for the i-th point,
        +	 * or to a subarray of 'pre_comp->points' if we already have precomputation. */
        +	val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
        +	if (val == NULL)
        +		{
        +		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	val[num_val] = NULL; /* pivot element */
        +
        +	/* allocate points for precomputation */
        +	v = val;
        +	for (i = 0; i < num + num_scalar; i++)
        +		{
        +		val_sub[i] = v;
        +		for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++)
        +			{
        +			*v = EC_POINT_new(group);
        +			if (*v == NULL) goto err;
        +			v++;
        +			}
        +		}
        +	if (!(v == val + num_val))
        +		{
        +		ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +
        +	if (!(tmp = EC_POINT_new(group)))
        +		goto err;
        +
        +	/* prepare precomputed values:
        +	 *    val_sub[i][0] :=     points[i]
        +	 *    val_sub[i][1] := 3 * points[i]
        +	 *    val_sub[i][2] := 5 * points[i]
        +	 *    ...
        +	 */
        +	for (i = 0; i < num + num_scalar; i++)
        +		{
        +		if (i < num)
        +			{
        +			if (!EC_POINT_copy(val_sub[i][0], points[i])) goto err;
        +			}
        +		else
        +			{
        +			if (!EC_POINT_copy(val_sub[i][0], generator)) goto err;
        +			}
        +
        +		if (wsize[i] > 1)
        +			{
        +			if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err;
        +			for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++)
        +				{
        +				if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;
        +				}
        +			}
        +		}
        +
        +#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */
        +	if (!EC_POINTs_make_affine(group, num_val, val, ctx))
        +		goto err;
        +#endif
        +
        +	r_is_at_infinity = 1;
        +
        +	for (k = max_len - 1; k >= 0; k--)
        +		{
        +		if (!r_is_at_infinity)
        +			{
        +			if (!EC_POINT_dbl(group, r, r, ctx)) goto err;
        +			}
        +		
        +		for (i = 0; i < totalnum; i++)
        +			{
        +			if (wNAF_len[i] > (size_t)k)
        +				{
        +				int digit = wNAF[i][k];
        +				int is_neg;
        +
        +				if (digit) 
        +					{
        +					is_neg = digit < 0;
        +
        +					if (is_neg)
        +						digit = -digit;
        +
        +					if (is_neg != r_is_inverted)
        +						{
        +						if (!r_is_at_infinity)
        +							{
        +							if (!EC_POINT_invert(group, r, ctx)) goto err;
        +							}
        +						r_is_inverted = !r_is_inverted;
        +						}
        +
        +					/* digit > 0 */
        +
        +					if (r_is_at_infinity)
        +						{
        +						if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err;
        +						r_is_at_infinity = 0;
        +						}
        +					else
        +						{
        +						if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) goto err;
        +						}
        +					}
        +				}
        +			}
        +		}
        +
        +	if (r_is_at_infinity)
        +		{
        +		if (!EC_POINT_set_to_infinity(group, r)) goto err;
        +		}
        +	else
        +		{
        +		if (r_is_inverted)
        +			if (!EC_POINT_invert(group, r, ctx)) goto err;
        +		}
        +	
        +	ret = 1;
        +
        + err:
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (tmp != NULL)
        +		EC_POINT_free(tmp);
        +	if (wsize != NULL)
        +		OPENSSL_free(wsize);
        +	if (wNAF_len != NULL)
        +		OPENSSL_free(wNAF_len);
        +	if (wNAF != NULL)
        +		{
        +		signed char **w;
        +		
        +		for (w = wNAF; *w != NULL; w++)
        +			OPENSSL_free(*w);
        +		
        +		OPENSSL_free(wNAF);
        +		}
        +	if (val != NULL)
        +		{
        +		for (v = val; *v != NULL; v++)
        +			EC_POINT_clear_free(*v);
        +
        +		OPENSSL_free(val);
        +		}
        +	if (val_sub != NULL)
        +		{
        +		OPENSSL_free(val_sub);
        +		}
        +	return ret;
        +	}
        +
        +
        +/* ec_wNAF_precompute_mult()
        + * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
        + * for use with wNAF splitting as implemented in ec_wNAF_mul().
        + * 
        + * 'pre_comp->points' is an array of multiples of the generator
        + * of the following form:
        + * points[0] =     generator;
        + * points[1] = 3 * generator;
        + * ...
        + * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;
        + * points[2^(w-1)]   =     2^blocksize * generator;
        + * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
        + * ...
        + * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator
        + * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator
        + * ...
        + * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator
        + * points[2^(w-1)*numblocks]       = NULL
        + */
        +int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	const EC_POINT *generator;
        +	EC_POINT *tmp_point = NULL, *base = NULL, **var;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *order;
        +	size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
        +	EC_POINT **points = NULL;
        +	EC_PRE_COMP *pre_comp;
        +	int ret = 0;
        +
        +	/* if there is an old EC_PRE_COMP object, throw it away */
        +	EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
        +
        +	if ((pre_comp = ec_pre_comp_new(group)) == NULL)
        +		return 0;
        +
        +	generator = EC_GROUP_get0_generator(group);
        +	if (generator == NULL)
        +		{
        +		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
        +		goto err;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			goto err;
        +		}
        +	
        +	BN_CTX_start(ctx);
        +	order = BN_CTX_get(ctx);
        +	if (order == NULL) goto err;
        +	
        +	if (!EC_GROUP_get_order(group, order, ctx)) goto err;		
        +	if (BN_is_zero(order))
        +		{
        +		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
        +		goto err;
        +		}
        +
        +	bits = BN_num_bits(order);
        +	/* The following parameters mean we precompute (approximately)
        +	 * one point per bit.
        +	 *
        +	 * TBD: The combination  8, 4  is perfect for 160 bits; for other
        +	 * bit lengths, other parameter combinations might provide better
        +	 * efficiency.
        +	 */
        +	blocksize = 8;
        +	w = 4;
        +	if (EC_window_bits_for_scalar_size(bits) > w)
        +		{
        +		/* let's not make the window too small ... */
        +		w = EC_window_bits_for_scalar_size(bits);
        +		}
        +
        +	numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */
        +	
        +	pre_points_per_block = (size_t)1 << (w - 1);
        +	num = pre_points_per_block * numblocks; /* number of points to compute and store */
        +
        +	points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));
        +	if (!points)
        +		{
        +		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	var = points;
        +	var[num] = NULL; /* pivot */
        +	for (i = 0; i < num; i++)
        +		{
        +		if ((var[i] = EC_POINT_new(group)) == NULL)
        +			{
        +			ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +
        +	if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group)))
        +		{
        +		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}	
        +	
        +	if (!EC_POINT_copy(base, generator))
        +		goto err;
        +	
        +	/* do the precomputation */
        +	for (i = 0; i < numblocks; i++)
        +		{
        +		size_t j;
        +
        +		if (!EC_POINT_dbl(group, tmp_point, base, ctx))
        +			goto err;
        +
        +		if (!EC_POINT_copy(*var++, base))
        +			goto err;
        +
        +		for (j = 1; j < pre_points_per_block; j++, var++)
        +			{
        +			/* calculate odd multiples of the current base point */
        +			if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
        +				goto err;
        +			}
        +
        +		if (i < numblocks - 1)
        +			{
        +			/* get the next base (multiply current one by 2^blocksize) */
        +			size_t k;
        +
        +			if (blocksize <= 2)
        +				{
        +				ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}				
        +
        +			if (!EC_POINT_dbl(group, base, tmp_point, ctx))
        +				goto err;
        +			for (k = 2; k < blocksize; k++)
        +				{
        +				if (!EC_POINT_dbl(group,base,base,ctx))
        +					goto err;
        +				}
        +			}
        + 		}
        +
        +	if (!EC_POINTs_make_affine(group, num, points, ctx))
        +		goto err;
        +	
        +	pre_comp->group = group;
        +	pre_comp->blocksize = blocksize;
        +	pre_comp->numblocks = numblocks;
        +	pre_comp->w = w;
        +	pre_comp->points = points;
        +	points = NULL;
        +	pre_comp->num = num;
        +
        +	if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
        +		ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
        +		goto err;
        +	pre_comp = NULL;
        +
        +	ret = 1;
        + err:
        +	if (ctx != NULL)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (pre_comp)
        +		ec_pre_comp_free(pre_comp);
        +	if (points)
        +		{
        +		EC_POINT **p;
        +
        +		for (p = points; *p != NULL; p++)
        +			EC_POINT_free(*p);
        +		OPENSSL_free(points);
        +		}
        +	if (tmp_point)
        +		EC_POINT_free(tmp_point);
        +	if (base)
        +		EC_POINT_free(base);
        +	return ret;
        +	}
        +
        +
        +int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
        +	{
        +	if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
        +		return 1;
        +	else
        +		return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_oct.c b/vendor/openssl/openssl/crypto/ec/ec_oct.c
        new file mode 100644
        index 000000000..fd9db0798
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_oct.c
        @@ -0,0 +1,199 @@
        +/* crypto/ec/ec_lib.c */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Binary polynomial ECC support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include <string.h>
        +
        +#include <openssl/err.h>
        +#include <openssl/opensslv.h>
        +
        +#include "ec_lcl.h"
        +
        +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, int y_bit, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_set_compressed_coordinates == 0
        +		&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
        +		{
        +		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
        +		{
        +		if (group->meth->field_type == NID_X9_62_prime_field)
        +			return ec_GFp_simple_set_compressed_coordinates(
        +					group, point, x, y_bit, ctx);
        +		else
        +#ifdef OPENSSL_NO_EC2M
        +			{
        +			ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_GF2M_NOT_SUPPORTED);
        +			return 0;
        +			}
        +#else
        +			return ec_GF2m_simple_set_compressed_coordinates(
        +					group, point, x, y_bit, ctx);
        +#endif
        +		}
        +	return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
        +	}
        +
        +#ifndef OPENSSL_NO_EC2M
        +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, int y_bit, BN_CTX *ctx)
        +	{
        +	if (group->meth->point_set_compressed_coordinates == 0
        +		&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
        +		{
        +		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
        +		{
        +		if (group->meth->field_type == NID_X9_62_prime_field)
        +			return ec_GFp_simple_set_compressed_coordinates(
        +					group, point, x, y_bit, ctx);
        +		else
        +			return ec_GF2m_simple_set_compressed_coordinates(
        +					group, point, x, y_bit, ctx);
        +		}
        +	return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
        +	}
        +#endif
        +
        +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
        +        unsigned char *buf, size_t len, BN_CTX *ctx)
        +	{
        +	if (group->meth->point2oct == 0
        +		&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
        +		{
        +		ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
        +		{
        +		if (group->meth->field_type == NID_X9_62_prime_field)
        +			return ec_GFp_simple_point2oct(group, point,
        +							form, buf, len, ctx);
        +		else
        +#ifdef OPENSSL_NO_EC2M
        +			{
        +			ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
        +			return 0;
        +			}
        +#else
        +			return ec_GF2m_simple_point2oct(group, point,
        +							form, buf, len, ctx);
        +#endif
        +		}
        +			
        +	return group->meth->point2oct(group, point, form, buf, len, ctx);
        +	}
        +
        +
        +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
        +        const unsigned char *buf, size_t len, BN_CTX *ctx)
        +	{
        +	if (group->meth->oct2point == 0
        +		&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
        +		{
        +		ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return 0;
        +		}
        +	if (group->meth != point->meth)
        +		{
        +		ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
        +		return 0;
        +		}
        +	if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
        +		{
        +		if (group->meth->field_type == NID_X9_62_prime_field)
        +			return ec_GFp_simple_oct2point(group, point,
        +							buf, len, ctx);
        +		else
        +#ifdef OPENSSL_NO_EC2M
        +			{
        +			ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
        +			return 0;
        +			}
        +#else
        +			return ec_GF2m_simple_oct2point(group, point,
        +							buf, len, ctx);
        +#endif
        +		}
        +	return group->meth->oct2point(group, point, buf, len, ctx);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_pmeth.c b/vendor/openssl/openssl/crypto/ec/ec_pmeth.c
        new file mode 100644
        index 000000000..66ee397d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_pmeth.c
        @@ -0,0 +1,341 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/ec.h>
        +#include <openssl/ecdsa.h>
        +#include <openssl/evp.h>
        +#include "evp_locl.h"
        +
        +/* EC pkey context structure */
        +
        +typedef struct
        +	{
        +	/* Key and paramgen group */
        +	EC_GROUP *gen_group;
        +	/* message digest */
        +	const EVP_MD *md;
        +	} EC_PKEY_CTX;
        +
        +static int pkey_ec_init(EVP_PKEY_CTX *ctx)
        +	{
        +	EC_PKEY_CTX *dctx;
        +	dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
        +	if (!dctx)
        +		return 0;
        +	dctx->gen_group = NULL;
        +	dctx->md = NULL;
        +
        +	ctx->data = dctx;
        +
        +	return 1;
        +	}
        +
        +static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	EC_PKEY_CTX *dctx, *sctx;
        +	if (!pkey_ec_init(dst))
        +		return 0;
        +       	sctx = src->data;
        +	dctx = dst->data;
        +	if (sctx->gen_group)
        +		{
        +		dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
        +		if (!dctx->gen_group)
        +			return 0;
        +		}
        +	dctx->md = sctx->md;
        +	return 1;
        +	}
        +
        +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
        +	{
        +	EC_PKEY_CTX *dctx = ctx->data;
        +	if (dctx)
        +		{
        +		if (dctx->gen_group)
        +			EC_GROUP_free(dctx->gen_group);
        +		OPENSSL_free(dctx);
        +		}
        +	}
        +
        +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen)
        +	{
        +	int ret, type;
        +	unsigned int sltmp;
        +	EC_PKEY_CTX *dctx = ctx->data;
        +	EC_KEY *ec = ctx->pkey->pkey.ec;
        +
        +	if (!sig)
        +		{
        +		*siglen = ECDSA_size(ec);
        +		return 1;
        +		}
        +	else if(*siglen < (size_t)ECDSA_size(ec))
        +		{
        +		ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
        +		return 0;
        +		}
        +
        +	if (dctx->md)
        +		type = EVP_MD_type(dctx->md);
        +	else
        +		type = NID_sha1;
        +
        +
        +	ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
        +
        +	if (ret <= 0)
        +		return ret;
        +	*siglen = (size_t)sltmp;
        +	return 1;
        +	}
        +
        +static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
        +					const unsigned char *sig, size_t siglen,
        +					const unsigned char *tbs, size_t tbslen)
        +	{
        +	int ret, type;
        +	EC_PKEY_CTX *dctx = ctx->data;
        +	EC_KEY *ec = ctx->pkey->pkey.ec;
        +
        +	if (dctx->md)
        +		type = EVP_MD_type(dctx->md);
        +	else
        +		type = NID_sha1;
        +
        +	ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
        +
        +	return ret;
        +	}
        +
        +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
        +	{
        +	int ret;
        +	size_t outlen;
        +	const EC_POINT *pubkey = NULL;
        +	if (!ctx->pkey || !ctx->peerkey)
        +		{
        +		ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
        +		return 0;
        +		}
        +
        +	if (!key)
        +		{
        +		const EC_GROUP *group;
        +		group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
        +		*keylen = (EC_GROUP_get_degree(group) + 7)/8;
        +		return 1;
        +		}
        +
        +	pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
        +
        +	/* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
        +	 * not an error, the result is truncated.
        +	 */
        +
        +	outlen = *keylen;
        +		
        +	ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
        +	if (ret < 0)
        +		return ret;
        +	*keylen = ret;
        +	return 1;
        +	}
        +
        +static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	EC_PKEY_CTX *dctx = ctx->data;
        +	EC_GROUP *group;
        +	switch (type)
        +		{
        +		case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
        +		group = EC_GROUP_new_by_curve_name(p1);
        +		if (group == NULL)
        +			{
        +			ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
        +			return 0;
        +			}
        +		if (dctx->gen_group)
        +			EC_GROUP_free(dctx->gen_group);
        +		dctx->gen_group = group;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_MD:
        +		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
        +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
        +			{
        +			ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
        +			return 0;
        +			}
        +		dctx->md = p2;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_PEER_KEY:
        +		/* Default behaviour is OK */
        +		case EVP_PKEY_CTRL_DIGESTINIT:
        +		case EVP_PKEY_CTRL_PKCS7_SIGN:
        +		case EVP_PKEY_CTRL_CMS_SIGN:
        +		return 1;
        +
        +		default:
        +		return -2;
        +
        +		}
        +	}
        +			
        +static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
        +			const char *type, const char *value)
        +	{
        +	if (!strcmp(type, "ec_paramgen_curve"))
        +		{
        +		int nid;
        +		nid = OBJ_sn2nid(value);
        +		if (nid == NID_undef)
        +			nid = OBJ_ln2nid(value);
        +		if (nid == NID_undef)
        +			{
        +			ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
        +			return 0;
        +			}
        +		return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
        +		}
        +	return -2;
        +	}
        +
        +static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	EC_KEY *ec = NULL;
        +	EC_PKEY_CTX *dctx = ctx->data;
        +	int ret = 0;
        +	if (dctx->gen_group == NULL)
        +		{
        +		ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
        +		return 0;
        +		}
        +	ec = EC_KEY_new();
        +	if (!ec)
        +		return 0;
        +	ret = EC_KEY_set_group(ec, dctx->gen_group);
        +	if (ret)
        +		EVP_PKEY_assign_EC_KEY(pkey, ec);
        +	else
        +		EC_KEY_free(ec);
        +	return ret;
        +	}
        +
        +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	EC_KEY *ec = NULL;
        +	if (ctx->pkey == NULL)
        +		{
        +		ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
        +		return 0;
        +		}
        +	ec = EC_KEY_new();
        +	if (!ec)
        +		return 0;
        +	EVP_PKEY_assign_EC_KEY(pkey, ec);
        +	/* Note: if error return, pkey is freed by parent routine */
        +	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
        +		return 0;
        +	return EC_KEY_generate_key(pkey->pkey.ec);
        +	}
        +
        +const EVP_PKEY_METHOD ec_pkey_meth = 
        +	{
        +	EVP_PKEY_EC,
        +	0,
        +	pkey_ec_init,
        +	pkey_ec_copy,
        +	pkey_ec_cleanup,
        +
        +	0,
        +	pkey_ec_paramgen,
        +
        +	0,
        +	pkey_ec_keygen,
        +
        +	0,
        +	pkey_ec_sign,
        +
        +	0,
        +	pkey_ec_verify,
        +
        +	0,0,
        +
        +	0,0,0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,
        +	pkey_ec_derive,
        +
        +	pkey_ec_ctrl,
        +	pkey_ec_ctrl_str
        +
        +	};
        diff --git a/vendor/openssl/openssl/crypto/ec/ec_print.c b/vendor/openssl/openssl/crypto/ec/ec_print.c
        new file mode 100644
        index 000000000..f7c8a303a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ec_print.c
        @@ -0,0 +1,195 @@
        +/* crypto/ec/ec_print.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <openssl/crypto.h>
        +#include "ec_lcl.h"
        +
        +BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, 
        +                          const EC_POINT *point, 
        +                          point_conversion_form_t form,
        +                          BIGNUM *ret,
        +                          BN_CTX *ctx)
        +	{
        +	size_t        buf_len=0;
        +	unsigned char *buf;
        +
        +	buf_len = EC_POINT_point2oct(group, point, form,
        +                                     NULL, 0, ctx);
        +	if (buf_len == 0)
        +		return NULL;
        +
        +	if ((buf = OPENSSL_malloc(buf_len)) == NULL)
        +		return NULL;
        +
        +	if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
        +		{
        +		OPENSSL_free(buf);
        +		return NULL;
        +		}
        +
        +	ret = BN_bin2bn(buf, buf_len, ret);
        +
        +	OPENSSL_free(buf);
        +
        +	return ret;
        +}
        +
        +EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
        +                            const BIGNUM *bn,
        +                            EC_POINT *point, 
        +                            BN_CTX *ctx)
        +	{
        +	size_t        buf_len=0;
        +	unsigned char *buf;
        +	EC_POINT      *ret;
        +
        +	if ((buf_len = BN_num_bytes(bn)) == 0) return NULL;
        +	buf = OPENSSL_malloc(buf_len);
        +	if (buf == NULL)
        +		return NULL;
        +
        +	if (!BN_bn2bin(bn, buf)) 
        +		{
        +		OPENSSL_free(buf);
        +		return NULL;
        +		}
        +
        +	if (point == NULL)
        +		{
        +		if ((ret = EC_POINT_new(group)) == NULL)
        +			{
        +			OPENSSL_free(buf);
        +			return NULL;
        +			}
        +		}
        +	else
        +		ret = point;
        +
        +	if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx))
        +		{
        +		if (point == NULL)
        +			EC_POINT_clear_free(ret);
        +		OPENSSL_free(buf);
        +		return NULL;
        +		}
        +
        +	OPENSSL_free(buf);
        +	return ret;
        +	}
        +
        +static const char *HEX_DIGITS = "0123456789ABCDEF";
        +
        +/* the return value must be freed (using OPENSSL_free()) */
        +char *EC_POINT_point2hex(const EC_GROUP *group,
        +                         const EC_POINT *point,
        +                         point_conversion_form_t form,
        +                         BN_CTX *ctx)
        +	{
        +	char          *ret, *p;
        +	size_t        buf_len=0,i;
        +	unsigned char *buf, *pbuf;
        +
        +	buf_len = EC_POINT_point2oct(group, point, form,
        +                                     NULL, 0, ctx);
        +	if (buf_len == 0)
        +		return NULL;
        +
        +	if ((buf = OPENSSL_malloc(buf_len)) == NULL)
        +		return NULL;
        +
        +	if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
        +		{
        +		OPENSSL_free(buf);
        +		return NULL;
        +		}
        +
        +	ret = (char *)OPENSSL_malloc(buf_len*2+2);
        +	if (ret == NULL)
        +		{
        +		OPENSSL_free(buf);
        +		return NULL;
        +		}
        +	p = ret;
        +	pbuf = buf;
        +	for (i=buf_len; i > 0; i--)
        +		{
        +			int v = (int) *(pbuf++);
        +			*(p++)=HEX_DIGITS[v>>4];
        +			*(p++)=HEX_DIGITS[v&0x0F];
        +		}
        +	*p='\0';
        +
        +	OPENSSL_free(buf);
        +
        +	return ret;
        +	}
        +
        +EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
        +                             const char *buf,
        +                             EC_POINT *point,
        +                             BN_CTX *ctx)
        +	{
        +	EC_POINT *ret=NULL;
        +	BIGNUM   *tmp_bn=NULL;
        +
        +	if (!BN_hex2bn(&tmp_bn, buf))
        +		return NULL;
        +
        +	ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
        +
        +	BN_clear_free(tmp_bn);
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/eck_prn.c b/vendor/openssl/openssl/crypto/ec/eck_prn.c
        new file mode 100644
        index 000000000..06de8f395
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/eck_prn.c
        @@ -0,0 +1,392 @@
        +/* crypto/ec/eck_prn.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions originally developed by SUN MICROSYSTEMS, INC., and 
        + * contributed to the OpenSSL project.
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/ec.h>
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b, fp, BIO_NOCLOSE);
        +	ret = ECPKParameters_print(b, x, off);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +
        +int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
        +	{
        +	BIO *b;
        +	int ret;
        + 
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b, fp, BIO_NOCLOSE);
        +	ret = EC_KEY_print(b, x, off);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +
        +int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
        +	{
        +	BIO *b;
        +	int ret;
        + 
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b, fp, BIO_NOCLOSE);
        +	ret = ECParameters_print(b, x);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +#endif
        +
        +int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
        +	{
        +	EVP_PKEY *pk;
        +	int ret;
        +	pk = EVP_PKEY_new();
        +	if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
        +		return 0;
        +	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
        +	EVP_PKEY_free(pk);
        +	return ret;
        +	}
        +
        +int ECParameters_print(BIO *bp, const EC_KEY *x)
        +	{
        +	EVP_PKEY *pk;
        +	int ret;
        +	pk = EVP_PKEY_new();
        +	if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
        +		return 0;
        +	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
        +	EVP_PKEY_free(pk);
        +	return ret;
        +	}
        +
        +static int print_bin(BIO *fp, const char *str, const unsigned char *num,
        +		size_t len, int off);
        +
        +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
        +	{
        +	unsigned char *buffer=NULL;
        +	size_t	buf_len=0, i;
        +	int     ret=0, reason=ERR_R_BIO_LIB;
        +	BN_CTX  *ctx=NULL;
        +	const EC_POINT *point=NULL;
        +	BIGNUM	*p=NULL, *a=NULL, *b=NULL, *gen=NULL,
        +		*order=NULL, *cofactor=NULL;
        +	const unsigned char *seed;
        +	size_t	seed_len=0;
        +	
        +	static const char *gen_compressed = "Generator (compressed):";
        +	static const char *gen_uncompressed = "Generator (uncompressed):";
        +	static const char *gen_hybrid = "Generator (hybrid):";
        + 
        +	if (!x)
        +		{
        +		reason = ERR_R_PASSED_NULL_PARAMETER;
        +		goto err;
        +		}
        +
        +	ctx = BN_CTX_new();
        +	if (ctx == NULL)
        +		{
        +		reason = ERR_R_MALLOC_FAILURE;
        +		goto err;
        +		}
        +
        +	if (EC_GROUP_get_asn1_flag(x))
        +		{
        +		/* the curve parameter are given by an asn1 OID */
        +		int nid;
        +
        +		if (!BIO_indent(bp, off, 128))
        +			goto err;
        +
        +		nid = EC_GROUP_get_curve_name(x);
        +		if (nid == 0)
        +			goto err;
        +
        +		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
        +			goto err;
        +		if (BIO_printf(bp, "\n") <= 0)
        +			goto err;
        +		}
        +	else
        +		{
        +		/* explicit parameters */
        +		int is_char_two = 0;
        +		point_conversion_form_t form;
        +		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
        +
        +		if (tmp_nid == NID_X9_62_characteristic_two_field)
        +			is_char_two = 1;
        +
        +		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
        +			(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
        +			(cofactor = BN_new()) == NULL)
        +			{
        +			reason = ERR_R_MALLOC_FAILURE;
        +			goto err;
        +			}
        +#ifndef OPENSSL_NO_EC2M
        +		if (is_char_two)
        +			{
        +			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
        +				{
        +				reason = ERR_R_EC_LIB;
        +				goto err;
        +				}
        +			}
        +		else /* prime field */
        +#endif
        +			{
        +			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
        +				{
        +				reason = ERR_R_EC_LIB;
        +				goto err;
        +				}
        +			}
        +
        +		if ((point = EC_GROUP_get0_generator(x)) == NULL)
        +			{
        +			reason = ERR_R_EC_LIB;
        +			goto err;
        +			}
        +		if (!EC_GROUP_get_order(x, order, NULL) || 
        +            		!EC_GROUP_get_cofactor(x, cofactor, NULL))
        +			{
        +			reason = ERR_R_EC_LIB;
        +			goto err;
        +			}
        +		
        +		form = EC_GROUP_get_point_conversion_form(x);
        +
        +		if ((gen = EC_POINT_point2bn(x, point, 
        +				form, NULL, ctx)) == NULL)
        +			{
        +			reason = ERR_R_EC_LIB;
        +			goto err;
        +			}
        +
        +		buf_len = (size_t)BN_num_bytes(p);
        +		if (buf_len < (i = (size_t)BN_num_bytes(a)))
        +			buf_len = i;
        +		if (buf_len < (i = (size_t)BN_num_bytes(b)))
        +			buf_len = i;
        +		if (buf_len < (i = (size_t)BN_num_bytes(gen)))
        +			buf_len = i;
        +		if (buf_len < (i = (size_t)BN_num_bytes(order)))
        +			buf_len = i;
        +		if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 
        +			buf_len = i;
        +
        +		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
        +			seed_len = EC_GROUP_get_seed_len(x);
        +
        +		buf_len += 10;
        +		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
        +			{
        +			reason = ERR_R_MALLOC_FAILURE;
        +			goto err;
        +			}
        +
        +		if (!BIO_indent(bp, off, 128))
        +			goto err;
        +
        +		/* print the 'short name' of the field type */
        +		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
        +			<= 0)
        +			goto err;  
        +
        +		if (is_char_two)
        +			{
        +			/* print the 'short name' of the base type OID */
        +			int basis_type = EC_GROUP_get_basis_type(x);
        +			if (basis_type == 0)
        +				goto err;
        +
        +			if (!BIO_indent(bp, off, 128))
        +				goto err;
        +
        +			if (BIO_printf(bp, "Basis Type: %s\n", 
        +				OBJ_nid2sn(basis_type)) <= 0)
        +				goto err;
        +
        +			/* print the polynomial */
        +			if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
        +				off))
        +				goto err;
        +			}
        +		else
        +			{
        +			if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
        +				goto err;
        +			}
        +		if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, buffer, off)) 
        +			goto err;
        +		if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, buffer, off))
        +			goto err;
        +		if (form == POINT_CONVERSION_COMPRESSED)
        +			{
        +			if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
        +				buffer, off))
        +				goto err;
        +			}
        +		else if (form == POINT_CONVERSION_UNCOMPRESSED)
        +			{
        +			if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
        +				buffer, off))
        +				goto err;
        +			}
        +		else /* form == POINT_CONVERSION_HYBRID */
        +			{
        +			if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
        +				buffer, off))
        +				goto err;
        +			}
        +		if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, 
        +			buffer, off)) goto err;
        +		if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, 
        +			buffer, off)) goto err;
        +		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
        +			goto err;
        +		}
        +	ret=1;
        +err:
        +	if (!ret)
        + 		ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
        +	if (p) 
        +		BN_free(p);
        +	if (a) 
        +		BN_free(a);
        +	if (b)
        +		BN_free(b);
        +	if (gen)
        +		BN_free(gen);
        +	if (order)
        +		BN_free(order);
        +	if (cofactor)
        +		BN_free(cofactor);
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	if (buffer != NULL) 
        +		OPENSSL_free(buffer);
        +	return(ret);	
        +	}
        +
        +static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
        +		size_t len, int off)
        +	{
        +	size_t i;
        +	char str[128];
        +
        +	if (buf == NULL)
        +		return 1;
        +	if (off)
        +		{
        +		if (off > 128)
        +			off=128;
        +		memset(str,' ',off);
        +		if (BIO_write(fp, str, off) <= 0)
        +			return 0;
        +		}
        +
        +	if (BIO_printf(fp,"%s", name) <= 0)
        +		return 0;
        +
        +	for (i=0; i<len; i++)
        +		{
        +		if ((i%15) == 0)
        +			{
        +			str[0]='\n';
        +			memset(&(str[1]),' ',off+4);
        +			if (BIO_write(fp, str, off+1+4) <= 0)
        +				return 0;
        +			}
        +		if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
        +			return 0;
        +		}
        +	if (BIO_write(fp,"\n",1) <= 0)
        +		return 0;
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_mont.c b/vendor/openssl/openssl/crypto/ec/ecp_mont.c
        new file mode 100644
        index 000000000..f04f132c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_mont.c
        @@ -0,0 +1,322 @@
        +/* crypto/ec/ecp_mont.c */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions of this software developed by SUN MICROSYSTEMS, INC.,
        + * and contributed to the OpenSSL project.
        + */
        +
        +#include <openssl/err.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +#include "ec_lcl.h"
        +
        +
        +const EC_METHOD *EC_GFp_mont_method(void)
        +	{
        +#ifdef OPENSSL_FIPS
        +	return fips_ec_gfp_mont_method();
        +#else
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_prime_field,
        +		ec_GFp_mont_group_init,
        +		ec_GFp_mont_group_finish,
        +		ec_GFp_mont_group_clear_finish,
        +		ec_GFp_mont_group_copy,
        +		ec_GFp_mont_group_set_curve,
        +		ec_GFp_simple_group_get_curve,
        +		ec_GFp_simple_group_get_degree,
        +		ec_GFp_simple_group_check_discriminant,
        +		ec_GFp_simple_point_init,
        +		ec_GFp_simple_point_finish,
        +		ec_GFp_simple_point_clear_finish,
        +		ec_GFp_simple_point_copy,
        +		ec_GFp_simple_point_set_to_infinity,
        +		ec_GFp_simple_set_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_get_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_point_set_affine_coordinates,
        +		ec_GFp_simple_point_get_affine_coordinates,
        +		0,0,0,
        +		ec_GFp_simple_add,
        +		ec_GFp_simple_dbl,
        +		ec_GFp_simple_invert,
        +		ec_GFp_simple_is_at_infinity,
        +		ec_GFp_simple_is_on_curve,
        +		ec_GFp_simple_cmp,
        +		ec_GFp_simple_make_affine,
        +		ec_GFp_simple_points_make_affine,
        +		0 /* mul */,
        +		0 /* precompute_mult */,
        +		0 /* have_precompute_mult */,	
        +		ec_GFp_mont_field_mul,
        +		ec_GFp_mont_field_sqr,
        +		0 /* field_div */,
        +		ec_GFp_mont_field_encode,
        +		ec_GFp_mont_field_decode,
        +		ec_GFp_mont_field_set_to_one };
        +
        +	return &ret;
        +#endif
        +	}
        +
        +
        +int ec_GFp_mont_group_init(EC_GROUP *group)
        +	{
        +	int ok;
        +
        +	ok = ec_GFp_simple_group_init(group);
        +	group->field_data1 = NULL;
        +	group->field_data2 = NULL;
        +	return ok;
        +	}
        +
        +
        +void ec_GFp_mont_group_finish(EC_GROUP *group)
        +	{
        +	if (group->field_data1 != NULL)
        +		{
        +		BN_MONT_CTX_free(group->field_data1);
        +		group->field_data1 = NULL;
        +		}
        +	if (group->field_data2 != NULL)
        +		{
        +		BN_free(group->field_data2);
        +		group->field_data2 = NULL;
        +		}
        +	ec_GFp_simple_group_finish(group);
        +	}
        +
        +
        +void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
        +	{
        +	if (group->field_data1 != NULL)
        +		{
        +		BN_MONT_CTX_free(group->field_data1);
        +		group->field_data1 = NULL;
        +		}
        +	if (group->field_data2 != NULL)
        +		{
        +		BN_clear_free(group->field_data2);
        +		group->field_data2 = NULL;
        +		}
        +	ec_GFp_simple_group_clear_finish(group);
        +	}
        +
        +
        +int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
        +	{
        +	if (dest->field_data1 != NULL)
        +		{
        +		BN_MONT_CTX_free(dest->field_data1);
        +		dest->field_data1 = NULL;
        +		}
        +	if (dest->field_data2 != NULL)
        +		{
        +		BN_clear_free(dest->field_data2);
        +		dest->field_data2 = NULL;
        +		}
        +
        +	if (!ec_GFp_simple_group_copy(dest, src)) return 0;
        +
        +	if (src->field_data1 != NULL)
        +		{
        +		dest->field_data1 = BN_MONT_CTX_new();
        +		if (dest->field_data1 == NULL) return 0;
        +		if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
        +		}
        +	if (src->field_data2 != NULL)
        +		{
        +		dest->field_data2 = BN_dup(src->field_data2);
        +		if (dest->field_data2 == NULL) goto err;
        +		}
        +
        +	return 1;
        +
        + err:
        +	if (dest->field_data1 != NULL)
        +		{
        +		BN_MONT_CTX_free(dest->field_data1);
        +		dest->field_data1 = NULL;
        +		}
        +	return 0;	
        +	}
        +
        +
        +int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BN_MONT_CTX *mont = NULL;
        +	BIGNUM *one = NULL;
        +	int ret = 0;
        +
        +	if (group->field_data1 != NULL)
        +		{
        +		BN_MONT_CTX_free(group->field_data1);
        +		group->field_data1 = NULL;
        +		}
        +	if (group->field_data2 != NULL)
        +		{
        +		BN_free(group->field_data2);
        +		group->field_data2 = NULL;
        +		}
        +	
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	mont = BN_MONT_CTX_new();
        +	if (mont == NULL) goto err;
        +	if (!BN_MONT_CTX_set(mont, p, ctx))
        +		{
        +		ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	one = BN_new();
        +	if (one == NULL) goto err;
        +	if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
        +
        +	group->field_data1 = mont;
        +	mont = NULL;
        +	group->field_data2 = one;
        +	one = NULL;
        +
        +	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
        +
        +	if (!ret)
        +		{
        +		BN_MONT_CTX_free(group->field_data1);
        +		group->field_data1 = NULL;
        +		BN_free(group->field_data2);
        +		group->field_data2 = NULL;
        +		}
        +
        + err:
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (mont != NULL)
        +		BN_MONT_CTX_free(mont);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	if (group->field_data1 == NULL)
        +		{
        +		ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
        +		return 0;
        +		}
        +
        +	return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
        +	}
        +
        +
        +int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        +	{
        +	if (group->field_data1 == NULL)
        +		{
        +		ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
        +		return 0;
        +		}
        +
        +	return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
        +	}
        +
        +
        +int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        +	{
        +	if (group->field_data1 == NULL)
        +		{
        +		ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
        +		return 0;
        +		}
        +
        +	return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
        +	}
        +
        +
        +int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        +	{
        +	if (group->field_data1 == NULL)
        +		{
        +		ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
        +		return 0;
        +		}
        +
        +	return BN_from_montgomery(r, a, group->field_data1, ctx);
        +	}
        +
        +
        +int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
        +	{
        +	if (group->field_data2 == NULL)
        +		{
        +		ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
        +		return 0;
        +		}
        +
        +	if (!BN_copy(r, group->field_data2)) return 0;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_nist.c b/vendor/openssl/openssl/crypto/ec/ecp_nist.c
        new file mode 100644
        index 000000000..aad2d5f44
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_nist.c
        @@ -0,0 +1,217 @@
        +/* crypto/ec/ecp_nist.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions of this software developed by SUN MICROSYSTEMS, INC.,
        + * and contributed to the OpenSSL project.
        + */
        +
        +#include <limits.h>
        +
        +#include <openssl/err.h>
        +#include <openssl/obj_mac.h>
        +#include "ec_lcl.h"
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +const EC_METHOD *EC_GFp_nist_method(void)
        +	{
        +#ifdef OPENSSL_FIPS
        +	return fips_ec_gfp_nist_method();
        +#else
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_prime_field,
        +		ec_GFp_simple_group_init,
        +		ec_GFp_simple_group_finish,
        +		ec_GFp_simple_group_clear_finish,
        +		ec_GFp_nist_group_copy,
        +		ec_GFp_nist_group_set_curve,
        +		ec_GFp_simple_group_get_curve,
        +		ec_GFp_simple_group_get_degree,
        +		ec_GFp_simple_group_check_discriminant,
        +		ec_GFp_simple_point_init,
        +		ec_GFp_simple_point_finish,
        +		ec_GFp_simple_point_clear_finish,
        +		ec_GFp_simple_point_copy,
        +		ec_GFp_simple_point_set_to_infinity,
        +		ec_GFp_simple_set_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_get_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_point_set_affine_coordinates,
        +		ec_GFp_simple_point_get_affine_coordinates,
        +		0,0,0,
        +		ec_GFp_simple_add,
        +		ec_GFp_simple_dbl,
        +		ec_GFp_simple_invert,
        +		ec_GFp_simple_is_at_infinity,
        +		ec_GFp_simple_is_on_curve,
        +		ec_GFp_simple_cmp,
        +		ec_GFp_simple_make_affine,
        +		ec_GFp_simple_points_make_affine,
        +		0 /* mul */,
        +		0 /* precompute_mult */,
        +		0 /* have_precompute_mult */,	
        +		ec_GFp_nist_field_mul,
        +		ec_GFp_nist_field_sqr,
        +		0 /* field_div */,
        +		0 /* field_encode */,
        +		0 /* field_decode */,
        +		0 /* field_set_to_one */ };
        +
        +	return &ret;
        +#endif
        +	}
        +
        +int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
        +	{
        +	dest->field_mod_func = src->field_mod_func;
        +
        +	return ec_GFp_simple_group_copy(dest, src);
        +	}
        +
        +int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
        +	const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *tmp_bn;
        +	
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +
        +	BN_CTX_start(ctx);
        +	if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
        +
        +	if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
        +		group->field_mod_func = BN_nist_mod_192;
        +	else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
        +		group->field_mod_func = BN_nist_mod_224;
        +	else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
        +		group->field_mod_func = BN_nist_mod_256;
        +	else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
        +		group->field_mod_func = BN_nist_mod_384;
        +	else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
        +		group->field_mod_func = BN_nist_mod_521;
        +	else
        +		{
        +		ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
        +		goto err;
        +		}
        +
        +	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
        +	const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int	ret=0;
        +	BN_CTX	*ctx_new=NULL;
        +
        +	if (!group || !r || !a || !b)
        +		{
        +		ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
        +		goto err;
        +		}
        +	if (!ctx)
        +		if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
        +
        +	if (!BN_mul(r, a, b, ctx)) goto err;
        +	if (!group->field_mod_func(r, r, &group->field, ctx))
        +		goto err;
        +
        +	ret=1;
        +err:
        +	if (ctx_new)
        +		BN_CTX_free(ctx_new);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
        +	BN_CTX *ctx)
        +	{
        +	int	ret=0;
        +	BN_CTX	*ctx_new=NULL;
        +
        +	if (!group || !r || !a)
        +		{
        +		ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
        +		goto err;
        +		}
        +	if (!ctx)
        +		if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
        +
        +	if (!BN_sqr(r, a, ctx)) goto err;
        +	if (!group->field_mod_func(r, r, &group->field, ctx))
        +		goto err;
        +
        +	ret=1;
        +err:
        +	if (ctx_new)
        +		BN_CTX_free(ctx_new);
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_nistp224.c b/vendor/openssl/openssl/crypto/ec/ecp_nistp224.c
        new file mode 100644
        index 000000000..b5ff56c25
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_nistp224.c
        @@ -0,0 +1,1658 @@
        +/* crypto/ec/ecp_nistp224.c */
        +/*
        + * Written by Emilia Kasper (Google) for the OpenSSL project.
        + */
        +/* Copyright 2011 Google Inc.
        + *
        + * Licensed under the Apache License, Version 2.0 (the "License");
        + *
        + * you may not use this file except in compliance with the License.
        + * You may obtain a copy of the License at
        + *
        + *     http://www.apache.org/licenses/LICENSE-2.0
        + *
        + *  Unless required by applicable law or agreed to in writing, software
        + *  distributed under the License is distributed on an "AS IS" BASIS,
        + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        + *  See the License for the specific language governing permissions and
        + *  limitations under the License.
        + */
        +
        +/*
        + * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
        + *
        + * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
        + * and Adam Langley's public domain 64-bit C implementation of curve25519
        + */
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +
        +#ifndef OPENSSL_SYS_VMS
        +#include <stdint.h>
        +#else
        +#include <inttypes.h>
        +#endif
        +
        +#include <string.h>
        +#include <openssl/err.h>
        +#include "ec_lcl.h"
        +
        +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
        +  /* even with gcc, the typedef won't work for 32-bit platforms */
        +  typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
        +#else
        +  #error "Need GCC 3.1 or later to define type uint128_t"
        +#endif
        +
        +typedef uint8_t u8;
        +typedef uint64_t u64;
        +typedef int64_t s64;
        +
        +
        +/******************************************************************************/
        +/*		    INTERNAL REPRESENTATION OF FIELD ELEMENTS
        + *
        + * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
        + * using 64-bit coefficients called 'limbs',
        + * and sometimes (for multiplication results) as
        + * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
        + * using 128-bit coefficients called 'widelimbs'.
        + * A 4-limb representation is an 'felem';
        + * a 7-widelimb representation is a 'widefelem'.
        + * Even within felems, bits of adjacent limbs overlap, and we don't always
        + * reduce the representations: we ensure that inputs to each felem
        + * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
        + * and fit into a 128-bit word without overflow. The coefficients are then
        + * again partially reduced to obtain an felem satisfying a_i < 2^57.
        + * We only reduce to the unique minimal representation at the end of the
        + * computation.
        + */
        +
        +typedef uint64_t limb;
        +typedef uint128_t widelimb;
        +
        +typedef limb felem[4];
        +typedef widelimb widefelem[7];
        +
        +/* Field element represented as a byte arrary.
        + * 28*8 = 224 bits is also the group order size for the elliptic curve,
        + * and we also use this type for scalars for point multiplication.
        +  */
        +typedef u8 felem_bytearray[28];
        +
        +static const felem_bytearray nistp224_curve_params[5] = {
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,    /* p */
        +	 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,    /* a */
        +	 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
        +	 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},
        +	{0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,    /* b */
        +	 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
        +	 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4},
        +	{0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,    /* x */
        +	 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
        +	 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21},
        +	{0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,    /* y */
        +	 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
        +	 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34}
        +};
        +
        +/* Precomputed multiples of the standard generator
        + * Points are given in coordinates (X, Y, Z) where Z normally is 1
        + * (0 for the point at infinity).
        + * For each field element, slice a_0 is word 0, etc.
        + *
        + * The table has 2 * 16 elements, starting with the following:
        + * index | bits    | point
        + * ------+---------+------------------------------
        + *     0 | 0 0 0 0 | 0G
        + *     1 | 0 0 0 1 | 1G
        + *     2 | 0 0 1 0 | 2^56G
        + *     3 | 0 0 1 1 | (2^56 + 1)G
        + *     4 | 0 1 0 0 | 2^112G
        + *     5 | 0 1 0 1 | (2^112 + 1)G
        + *     6 | 0 1 1 0 | (2^112 + 2^56)G
        + *     7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
        + *     8 | 1 0 0 0 | 2^168G
        + *     9 | 1 0 0 1 | (2^168 + 1)G
        + *    10 | 1 0 1 0 | (2^168 + 2^56)G
        + *    11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
        + *    12 | 1 1 0 0 | (2^168 + 2^112)G
        + *    13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
        + *    14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
        + *    15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
        + * followed by a copy of this with each element multiplied by 2^28.
        + *
        + * The reason for this is so that we can clock bits into four different
        + * locations when doing simple scalar multiplies against the base point,
        + * and then another four locations using the second 16 elements.
        + */
        +static const felem gmul[2][16][3] =
        +{{{{0, 0, 0, 0},
        +   {0, 0, 0, 0},
        +   {0, 0, 0, 0}},
        +  {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
        +   {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
        +   {1, 0, 0, 0}},
        +  {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
        +   {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
        +   {1, 0, 0, 0}},
        +  {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
        +   {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
        +   {1, 0, 0, 0}},
        +  {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
        +   {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
        +   {1, 0, 0, 0}},
        +  {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
        +   {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
        +   {1, 0, 0, 0}},
        +  {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
        +   {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
        +   {1, 0, 0, 0}},
        +  {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
        +   {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
        +   {1, 0, 0, 0}},
        +  {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
        +   {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
        +   {1, 0, 0, 0}},
        +  {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
        +   {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
        +   {1, 0, 0, 0}},
        +  {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
        +   {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
        +   {1, 0, 0, 0}},
        +  {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
        +   {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
        +   {1, 0, 0, 0}},
        +  {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
        +   {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
        +   {1, 0, 0, 0}},
        +  {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
        +   {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
        +   {1, 0, 0, 0}},
        +  {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
        +   {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
        +   {1, 0, 0, 0}},
        +  {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
        +   {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
        +   {1, 0, 0, 0}}},
        + {{{0, 0, 0, 0},
        +   {0, 0, 0, 0},
        +   {0, 0, 0, 0}},
        +  {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
        +   {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
        +   {1, 0, 0, 0}},
        +  {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
        +   {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
        +   {1, 0, 0, 0}},
        +  {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
        +   {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
        +   {1, 0, 0, 0}},
        +  {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
        +   {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
        +   {1, 0, 0, 0}},
        +  {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
        +   {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
        +   {1, 0, 0, 0}},
        +  {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
        +   {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
        +   {1, 0, 0, 0}},
        +  {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
        +   {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
        +   {1, 0, 0, 0}},
        +  {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
        +   {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
        +   {1, 0, 0, 0}},
        +  {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
        +   {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
        +   {1, 0, 0, 0}},
        +  {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
        +   {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
        +   {1, 0, 0, 0}},
        +  {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
        +   {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
        +   {1, 0, 0, 0}},
        +  {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
        +   {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
        +   {1, 0, 0, 0}},
        +  {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
        +   {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
        +   {1, 0, 0, 0}},
        +  {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
        +   {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
        +   {1, 0, 0, 0}},
        +  {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
        +   {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
        +   {1, 0, 0, 0}}}};
        +
        +/* Precomputation for the group generator. */
        +typedef struct {
        +	felem g_pre_comp[2][16][3];
        +	int references;
        +} NISTP224_PRE_COMP;
        +
        +const EC_METHOD *EC_GFp_nistp224_method(void)
        +	{
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_prime_field,
        +		ec_GFp_nistp224_group_init,
        +		ec_GFp_simple_group_finish,
        +		ec_GFp_simple_group_clear_finish,
        +		ec_GFp_nist_group_copy,
        +		ec_GFp_nistp224_group_set_curve,
        +		ec_GFp_simple_group_get_curve,
        +		ec_GFp_simple_group_get_degree,
        +		ec_GFp_simple_group_check_discriminant,
        +		ec_GFp_simple_point_init,
        +		ec_GFp_simple_point_finish,
        +		ec_GFp_simple_point_clear_finish,
        +		ec_GFp_simple_point_copy,
        +		ec_GFp_simple_point_set_to_infinity,
        +		ec_GFp_simple_set_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_get_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_point_set_affine_coordinates,
        +		ec_GFp_nistp224_point_get_affine_coordinates,
        +		0 /* point_set_compressed_coordinates */,
        +		0 /* point2oct */,
        +		0 /* oct2point */,
        +		ec_GFp_simple_add,
        +		ec_GFp_simple_dbl,
        +		ec_GFp_simple_invert,
        +		ec_GFp_simple_is_at_infinity,
        +		ec_GFp_simple_is_on_curve,
        +		ec_GFp_simple_cmp,
        +		ec_GFp_simple_make_affine,
        +		ec_GFp_simple_points_make_affine,
        +		ec_GFp_nistp224_points_mul,
        +		ec_GFp_nistp224_precompute_mult,
        +		ec_GFp_nistp224_have_precompute_mult,
        +		ec_GFp_nist_field_mul,
        +		ec_GFp_nist_field_sqr,
        +		0 /* field_div */,
        +		0 /* field_encode */,
        +		0 /* field_decode */,
        +		0 /* field_set_to_one */ };
        +
        +	return &ret;
        +	}
        +
        +/* Helper functions to convert field elements to/from internal representation */
        +static void bin28_to_felem(felem out, const u8 in[28])
        +	{
        +	out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
        +	out[1] = (*((const uint64_t *)(in+7))) & 0x00ffffffffffffff;
        +	out[2] = (*((const uint64_t *)(in+14))) & 0x00ffffffffffffff;
        +	out[3] = (*((const uint64_t *)(in+21))) & 0x00ffffffffffffff;
        +	}
        +
        +static void felem_to_bin28(u8 out[28], const felem in)
        +	{
        +	unsigned i;
        +	for (i = 0; i < 7; ++i)
        +		{
        +		out[i]	  = in[0]>>(8*i);
        +		out[i+7]  = in[1]>>(8*i);
        +		out[i+14] = in[2]>>(8*i);
        +		out[i+21] = in[3]>>(8*i);
        +		}
        +	}
        +
        +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
        +static void flip_endian(u8 *out, const u8 *in, unsigned len)
        +	{
        +	unsigned i;
        +	for (i = 0; i < len; ++i)
        +		out[i] = in[len-1-i];
        +	}
        +
        +/* From OpenSSL BIGNUM to internal representation */
        +static int BN_to_felem(felem out, const BIGNUM *bn)
        +	{
        +	felem_bytearray b_in;
        +	felem_bytearray b_out;
        +	unsigned num_bytes;
        +
        +	/* BN_bn2bin eats leading zeroes */
        +	memset(b_out, 0, sizeof b_out);
        +	num_bytes = BN_num_bytes(bn);
        +	if (num_bytes > sizeof b_out)
        +		{
        +		ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
        +		return 0;
        +		}
        +	if (BN_is_negative(bn))
        +		{
        +		ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
        +		return 0;
        +		}
        +	num_bytes = BN_bn2bin(bn, b_in);
        +	flip_endian(b_out, b_in, num_bytes);
        +	bin28_to_felem(out, b_out);
        +	return 1;
        +	}
        +
        +/* From internal representation to OpenSSL BIGNUM */
        +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
        +	{
        +	felem_bytearray b_in, b_out;
        +	felem_to_bin28(b_in, in);
        +	flip_endian(b_out, b_in, sizeof b_out);
        +	return BN_bin2bn(b_out, sizeof b_out, out);
        +	}
        +
        +/******************************************************************************/
        +/*				FIELD OPERATIONS
        + *
        + * Field operations, using the internal representation of field elements.
        + * NB! These operations are specific to our point multiplication and cannot be
        + * expected to be correct in general - e.g., multiplication with a large scalar
        + * will cause an overflow.
        + *
        + */
        +
        +static void felem_one(felem out)
        +	{
        +	out[0] = 1;
        +	out[1] = 0;
        +	out[2] = 0;
        +	out[3] = 0;
        +	}
        +
        +static void felem_assign(felem out, const felem in)
        +	{
        +	out[0] = in[0];
        +	out[1] = in[1];
        +	out[2] = in[2];
        +	out[3] = in[3];
        +	}
        +
        +/* Sum two field elements: out += in */
        +static void felem_sum(felem out, const felem in)
        +	{
        +	out[0] += in[0];
        +	out[1] += in[1];
        +	out[2] += in[2];
        +	out[3] += in[3];
        +	}
        +
        +/* Get negative value: out = -in */
        +/* Assumes in[i] < 2^57 */
        +static void felem_neg(felem out, const felem in)
        +	{
        +	static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
        +	static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
        +	static const limb two58m42m2 = (((limb) 1) << 58) -
        +	    (((limb) 1) << 42) - (((limb) 1) << 2);
        +
        +	/* Set to 0 mod 2^224-2^96+1 to ensure out > in */
        +	out[0] = two58p2 - in[0];
        +	out[1] = two58m42m2 - in[1];
        +	out[2] = two58m2 - in[2];
        +	out[3] = two58m2 - in[3];
        +	}
        +
        +/* Subtract field elements: out -= in */
        +/* Assumes in[i] < 2^57 */
        +static void felem_diff(felem out, const felem in)
        +	{
        +	static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
        +	static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
        +	static const limb two58m42m2 = (((limb) 1) << 58) -
        +	    (((limb) 1) << 42) - (((limb) 1) << 2);
        +
        +	/* Add 0 mod 2^224-2^96+1 to ensure out > in */
        +	out[0] += two58p2;
        +	out[1] += two58m42m2;
        +	out[2] += two58m2;
        +	out[3] += two58m2;
        +
        +	out[0] -= in[0];
        +	out[1] -= in[1];
        +	out[2] -= in[2];
        +	out[3] -= in[3];
        +	}
        +
        +/* Subtract in unreduced 128-bit mode: out -= in */
        +/* Assumes in[i] < 2^119 */
        +static void widefelem_diff(widefelem out, const widefelem in)
        +	{
        +	static const widelimb two120 = ((widelimb) 1) << 120;
        +	static const widelimb two120m64 = (((widelimb) 1) << 120) -
        +		(((widelimb) 1) << 64);
        +	static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
        +		(((widelimb) 1) << 104) - (((widelimb) 1) << 64);
        +
        +	/* Add 0 mod 2^224-2^96+1 to ensure out > in */
        +	out[0] += two120;
        +	out[1] += two120m64;
        +	out[2] += two120m64;
        +	out[3] += two120;
        +	out[4] += two120m104m64;
        +	out[5] += two120m64;
        +	out[6] += two120m64;
        +
        +	out[0] -= in[0];
        +	out[1] -= in[1];
        +	out[2] -= in[2];
        +	out[3] -= in[3];
        +	out[4] -= in[4];
        +	out[5] -= in[5];
        +	out[6] -= in[6];
        +	}
        +
        +/* Subtract in mixed mode: out128 -= in64 */
        +/* in[i] < 2^63 */
        +static void felem_diff_128_64(widefelem out, const felem in)
        +	{
        +	static const widelimb two64p8 = (((widelimb) 1) << 64) +
        +		(((widelimb) 1) << 8);
        +	static const widelimb two64m8 = (((widelimb) 1) << 64) -
        +		(((widelimb) 1) << 8);
        +	static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
        +		(((widelimb) 1) << 48) - (((widelimb) 1) << 8);
        +
        +	/* Add 0 mod 2^224-2^96+1 to ensure out > in */
        +	out[0] += two64p8;
        +	out[1] += two64m48m8;
        +	out[2] += two64m8;
        +	out[3] += two64m8;
        +
        +	out[0] -= in[0];
        +	out[1] -= in[1];
        +	out[2] -= in[2];
        +	out[3] -= in[3];
        +	}
        +
        +/* Multiply a field element by a scalar: out = out * scalar
        + * The scalars we actually use are small, so results fit without overflow */
        +static void felem_scalar(felem out, const limb scalar)
        +	{
        +	out[0] *= scalar;
        +	out[1] *= scalar;
        +	out[2] *= scalar;
        +	out[3] *= scalar;
        +	}
        +
        +/* Multiply an unreduced field element by a scalar: out = out * scalar
        + * The scalars we actually use are small, so results fit without overflow */
        +static void widefelem_scalar(widefelem out, const widelimb scalar)
        +	{
        +	out[0] *= scalar;
        +	out[1] *= scalar;
        +	out[2] *= scalar;
        +	out[3] *= scalar;
        +	out[4] *= scalar;
        +	out[5] *= scalar;
        +	out[6] *= scalar;
        +	}
        +
        +/* Square a field element: out = in^2 */
        +static void felem_square(widefelem out, const felem in)
        +	{
        +	limb tmp0, tmp1, tmp2;
        +	tmp0 = 2 * in[0]; tmp1 = 2 * in[1]; tmp2 = 2 * in[2];
        +	out[0] = ((widelimb) in[0]) * in[0];
        +	out[1] = ((widelimb) in[0]) * tmp1;
        +	out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
        +	out[3] = ((widelimb) in[3]) * tmp0 +
        +		((widelimb) in[1]) * tmp2;
        +	out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
        +	out[5] = ((widelimb) in[3]) * tmp2;
        +	out[6] = ((widelimb) in[3]) * in[3];
        +	}
        +
        +/* Multiply two field elements: out = in1 * in2 */
        +static void felem_mul(widefelem out, const felem in1, const felem in2)
        +	{
        +	out[0] = ((widelimb) in1[0]) * in2[0];
        +	out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
        +	out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
        +		((widelimb) in1[2]) * in2[0];
        +	out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
        +		((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
        +	out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
        +		((widelimb) in1[3]) * in2[1];
        +	out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
        +	out[6] = ((widelimb) in1[3]) * in2[3];
        +	}
        +
        +/* Reduce seven 128-bit coefficients to four 64-bit coefficients.
        + * Requires in[i] < 2^126,
        + * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
        +static void felem_reduce(felem out, const widefelem in)
        +	{
        +	static const widelimb two127p15 = (((widelimb) 1) << 127) +
        +		(((widelimb) 1) << 15);
        +	static const widelimb two127m71 = (((widelimb) 1) << 127) -
        +		(((widelimb) 1) << 71);
        +	static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
        +		(((widelimb) 1) << 71) - (((widelimb) 1) << 55);
        +	widelimb output[5];
        +
        +	/* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
        +	output[0] = in[0] + two127p15;
        +	output[1] = in[1] + two127m71m55;
        +	output[2] = in[2] + two127m71;
        +	output[3] = in[3];
        +	output[4] = in[4];
        +
        +	/* Eliminate in[4], in[5], in[6] */
        +	output[4] += in[6] >> 16;
        +	output[3] += (in[6] & 0xffff) << 40;
        +	output[2] -= in[6];
        +
        +	output[3] += in[5] >> 16;
        +	output[2] += (in[5] & 0xffff) << 40;
        +	output[1] -= in[5];
        +
        +	output[2] += output[4] >> 16;
        +	output[1] += (output[4] & 0xffff) << 40;
        +	output[0] -= output[4];
        +
        +	/* Carry 2 -> 3 -> 4 */
        +	output[3] += output[2] >> 56;
        +	output[2] &= 0x00ffffffffffffff;
        +
        +	output[4] = output[3] >> 56;
        +	output[3] &= 0x00ffffffffffffff;
        +
        +	/* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
        +
        +	/* Eliminate output[4] */
        +	output[2] += output[4] >> 16;
        +	/* output[2] < 2^56 + 2^56 = 2^57 */
        +	output[1] += (output[4] & 0xffff) << 40;
        +	output[0] -= output[4];
        +
        +	/* Carry 0 -> 1 -> 2 -> 3 */
        +	output[1] += output[0] >> 56;
        +	out[0] = output[0] & 0x00ffffffffffffff;
        +
        +	output[2] += output[1] >> 56;
        +	/* output[2] < 2^57 + 2^72 */
        +	out[1] = output[1] & 0x00ffffffffffffff;
        +	output[3] += output[2] >> 56;
        +	/* output[3] <= 2^56 + 2^16 */
        +	out[2] = output[2] & 0x00ffffffffffffff;
        +
        +	/* out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
        +	 * out[3] <= 2^56 + 2^16 (due to final carry),
        +	 * so out < 2*p */
        +	out[3] = output[3];
        +	}
        +
        +static void felem_square_reduce(felem out, const felem in)
        +	{
        +	widefelem tmp;
        +	felem_square(tmp, in);
        +	felem_reduce(out, tmp);
        +	}
        +
        +static void felem_mul_reduce(felem out, const felem in1, const felem in2)
        +	{
        +	widefelem tmp;
        +	felem_mul(tmp, in1, in2);
        +	felem_reduce(out, tmp);
        +	}
        +
        +/* Reduce to unique minimal representation.
        + * Requires 0 <= in < 2*p (always call felem_reduce first) */
        +static void felem_contract(felem out, const felem in)
        +	{
        +	static const int64_t two56 = ((limb) 1) << 56;
        +	/* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
        +	/* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
        +	int64_t tmp[4], a;
        +	tmp[0] = in[0];
        +	tmp[1] = in[1];
        +	tmp[2] = in[2];
        +	tmp[3] = in[3];
        +	/* Case 1: a = 1 iff in >= 2^224 */
        +	a = (in[3] >> 56);
        +	tmp[0] -= a;
        +	tmp[1] += a << 40;
        +	tmp[3] &= 0x00ffffffffffffff;
        +	/* Case 2: a = 0 iff p <= in < 2^224, i.e.,
        +	 * the high 128 bits are all 1 and the lower part is non-zero */
        +	a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
        +		(((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
        +	a &= 0x00ffffffffffffff;
        +	/* turn a into an all-one mask (if a = 0) or an all-zero mask */
        +	a = (a - 1) >> 63;
        +	/* subtract 2^224 - 2^96 + 1 if a is all-one*/
        +	tmp[3] &= a ^ 0xffffffffffffffff;
        +	tmp[2] &= a ^ 0xffffffffffffffff;
        +	tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
        +	tmp[0] -= 1 & a;
        +
        +	/* eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
        +	 * be non-zero, so we only need one step */
        +	a = tmp[0] >> 63;
        +	tmp[0] += two56 & a;
        +	tmp[1] -= 1 & a;
        +
        +	/* carry 1 -> 2 -> 3 */
        +	tmp[2] += tmp[1] >> 56;
        +	tmp[1] &= 0x00ffffffffffffff;
        +
        +	tmp[3] += tmp[2] >> 56;
        +	tmp[2] &= 0x00ffffffffffffff;
        +
        +	/* Now 0 <= out < p */
        +	out[0] = tmp[0];
        +	out[1] = tmp[1];
        +	out[2] = tmp[2];
        +	out[3] = tmp[3];
        +	}
        +
        +/* Zero-check: returns 1 if input is 0, and 0 otherwise.
        + * We know that field elements are reduced to in < 2^225,
        + * so we only need to check three cases: 0, 2^224 - 2^96 + 1,
        + * and 2^225 - 2^97 + 2 */
        +static limb felem_is_zero(const felem in)
        +	{
        +	limb zero, two224m96p1, two225m97p2;
        +
        +	zero = in[0] | in[1] | in[2] | in[3];
        +	zero = (((int64_t)(zero) - 1) >> 63) & 1;
        +	two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
        +		| (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
        +	two224m96p1 = (((int64_t)(two224m96p1) - 1) >> 63) & 1;
        +	two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
        +		| (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
        +	two225m97p2 = (((int64_t)(two225m97p2) - 1) >> 63) & 1;
        +	return (zero | two224m96p1 | two225m97p2);
        +	}
        +
        +static limb felem_is_zero_int(const felem in)
        +	{
        +	return (int) (felem_is_zero(in) & ((limb)1));
        +	}
        +
        +/* Invert a field element */
        +/* Computation chain copied from djb's code */
        +static void felem_inv(felem out, const felem in)
        +	{
        +	felem ftmp, ftmp2, ftmp3, ftmp4;
        +	widefelem tmp;
        +	unsigned i;
        +
        +	felem_square(tmp, in); felem_reduce(ftmp, tmp);		/* 2 */
        +	felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp);	/* 2^2 - 1 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);	/* 2^3 - 2 */
        +	felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp);	/* 2^3 - 1 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp2, tmp);	/* 2^4 - 2 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);	/* 2^5 - 4 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);	/* 2^6 - 8 */
        +	felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp, tmp);	/* 2^6 - 1 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp2, tmp);	/* 2^7 - 2 */
        +	for (i = 0; i < 5; ++i)					/* 2^12 - 2^6 */
        +		{
        +		felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
        +		}
        +	felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp2, tmp);	/* 2^12 - 1 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^13 - 2 */
        +	for (i = 0; i < 11; ++i)				/* 2^24 - 2^12 */
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^25 - 2 */
        +	for (i = 0; i < 23; ++i)				/* 2^48 - 2^24 */
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp4, tmp);	/* 2^49 - 2 */
        +	for (i = 0; i < 47; ++i)				/* 2^96 - 2^48 */
        +		{
        +		felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);
        +		}
        +	felem_mul(tmp, ftmp3, ftmp4); felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp4, tmp);	/* 2^97 - 2 */
        +	for (i = 0; i < 23; ++i)				/* 2^120 - 2^24 */
        +		{
        +		felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);
        +		}
        +	felem_mul(tmp, ftmp2, ftmp4); felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
        +	for (i = 0; i < 6; ++i)					/* 2^126 - 2^6 */
        +		{
        +		felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
        +		}
        +	felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp, tmp);	/* 2^126 - 1 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);	/* 2^127 - 2 */
        +	felem_mul(tmp, ftmp, in); felem_reduce(ftmp, tmp);	/* 2^127 - 1 */
        +	for (i = 0; i < 97; ++i)				/* 2^224 - 2^97 */
        +		{
        +		felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
        +		}
        +	felem_mul(tmp, ftmp, ftmp3); felem_reduce(out, tmp);	/* 2^224 - 2^96 - 1 */
        +	}
        +
        +/* Copy in constant time:
        + * if icopy == 1, copy in to out,
        + * if icopy == 0, copy out to itself. */
        +static void
        +copy_conditional(felem out, const felem in, limb icopy)
        +	{
        +	unsigned i;
        +	/* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
        +	const limb copy = -icopy;
        +	for (i = 0; i < 4; ++i)
        +		{
        +		const limb tmp = copy & (in[i] ^ out[i]);
        +		out[i] ^= tmp;
        +		}
        +	}
        +
        +/******************************************************************************/
        +/*			 ELLIPTIC CURVE POINT OPERATIONS
        + *
        + * Points are represented in Jacobian projective coordinates:
        + * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
        + * or to the point at infinity if Z == 0.
        + *
        + */
        +
        +/* Double an elliptic curve point:
        + * (X', Y', Z') = 2 * (X, Y, Z), where
        + * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
        + * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
        + * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
        + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
        + * while x_out == y_in is not (maybe this works, but it's not tested). */
        +static void
        +point_double(felem x_out, felem y_out, felem z_out,
        +             const felem x_in, const felem y_in, const felem z_in)
        +	{
        +	widefelem tmp, tmp2;
        +	felem delta, gamma, beta, alpha, ftmp, ftmp2;
        +
        +	felem_assign(ftmp, x_in);
        +	felem_assign(ftmp2, x_in);
        +
        +	/* delta = z^2 */
        +	felem_square(tmp, z_in);
        +	felem_reduce(delta, tmp);
        +
        +	/* gamma = y^2 */
        +	felem_square(tmp, y_in);
        +	felem_reduce(gamma, tmp);
        +
        +	/* beta = x*gamma */
        +	felem_mul(tmp, x_in, gamma);
        +	felem_reduce(beta, tmp);
        +
        +	/* alpha = 3*(x-delta)*(x+delta) */
        +	felem_diff(ftmp, delta);
        +	/* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
        +	felem_sum(ftmp2, delta);
        +	/* ftmp2[i] < 2^57 + 2^57 = 2^58 */
        +	felem_scalar(ftmp2, 3);
        +	/* ftmp2[i] < 3 * 2^58 < 2^60 */
        +	felem_mul(tmp, ftmp, ftmp2);
        +	/* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
        +	felem_reduce(alpha, tmp);
        +
        +	/* x' = alpha^2 - 8*beta */
        +	felem_square(tmp, alpha);
        +	/* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
        +	felem_assign(ftmp, beta);
        +	felem_scalar(ftmp, 8);
        +	/* ftmp[i] < 8 * 2^57 = 2^60 */
        +	felem_diff_128_64(tmp, ftmp);
        +	/* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
        +	felem_reduce(x_out, tmp);
        +
        +	/* z' = (y + z)^2 - gamma - delta */
        +	felem_sum(delta, gamma);
        +	/* delta[i] < 2^57 + 2^57 = 2^58 */
        +	felem_assign(ftmp, y_in);
        +	felem_sum(ftmp, z_in);
        +	/* ftmp[i] < 2^57 + 2^57 = 2^58 */
        +	felem_square(tmp, ftmp);
        +	/* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
        +	felem_diff_128_64(tmp, delta);
        +	/* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
        +	felem_reduce(z_out, tmp);
        +
        +	/* y' = alpha*(4*beta - x') - 8*gamma^2 */
        +	felem_scalar(beta, 4);
        +	/* beta[i] < 4 * 2^57 = 2^59 */
        +	felem_diff(beta, x_out);
        +	/* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
        +	felem_mul(tmp, alpha, beta);
        +	/* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
        +	felem_square(tmp2, gamma);
        +	/* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
        +	widefelem_scalar(tmp2, 8);
        +	/* tmp2[i] < 8 * 2^116 = 2^119 */
        +	widefelem_diff(tmp, tmp2);
        +	/* tmp[i] < 2^119 + 2^120 < 2^121 */
        +	felem_reduce(y_out, tmp);
        +	}
        +
        +/* Add two elliptic curve points:
        + * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
        + * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
        + * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
        + * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
        + *        Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
        + * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
        + *
        + * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
        + */
        +
        +/* This function is not entirely constant-time:
        + * it includes a branch for checking whether the two input points are equal,
        + * (while not equal to the point at infinity).
        + * This case never happens during single point multiplication,
        + * so there is no timing leak for ECDH or ECDSA signing. */
        +static void point_add(felem x3, felem y3, felem z3,
        +	const felem x1, const felem y1, const felem z1,
        +	const int mixed, const felem x2, const felem y2, const felem z2)
        +	{
        +	felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
        +	widefelem tmp, tmp2;
        +	limb z1_is_zero, z2_is_zero, x_equal, y_equal;
        +
        +	if (!mixed)
        +		{
        +		/* ftmp2 = z2^2 */
        +		felem_square(tmp, z2);
        +		felem_reduce(ftmp2, tmp);
        +
        +		/* ftmp4 = z2^3 */
        +		felem_mul(tmp, ftmp2, z2);
        +		felem_reduce(ftmp4, tmp);
        +
        +		/* ftmp4 = z2^3*y1 */
        +		felem_mul(tmp2, ftmp4, y1);
        +		felem_reduce(ftmp4, tmp2);
        +
        +		/* ftmp2 = z2^2*x1 */
        +		felem_mul(tmp2, ftmp2, x1);
        +		felem_reduce(ftmp2, tmp2);
        +		}
        +	else
        +		{
        +		/* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
        +
        +		/* ftmp4 = z2^3*y1 */
        +		felem_assign(ftmp4, y1);
        +
        +		/* ftmp2 = z2^2*x1 */
        +		felem_assign(ftmp2, x1);
        +		}
        +
        +	/* ftmp = z1^2 */
        +	felem_square(tmp, z1);
        +	felem_reduce(ftmp, tmp);
        +
        +	/* ftmp3 = z1^3 */
        +	felem_mul(tmp, ftmp, z1);
        +	felem_reduce(ftmp3, tmp);
        +
        +	/* tmp = z1^3*y2 */
        +	felem_mul(tmp, ftmp3, y2);
        +	/* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
        +
        +	/* ftmp3 = z1^3*y2 - z2^3*y1 */
        +	felem_diff_128_64(tmp, ftmp4);
        +	/* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
        +	felem_reduce(ftmp3, tmp);
        +
        +	/* tmp = z1^2*x2 */
        +	felem_mul(tmp, ftmp, x2);
        +	/* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
        +
        +	/* ftmp = z1^2*x2 - z2^2*x1 */
        +	felem_diff_128_64(tmp, ftmp2);
        +	/* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
        +	felem_reduce(ftmp, tmp);
        +
        +	/* the formulae are incorrect if the points are equal
        +	 * so we check for this and do doubling if this happens */
        +	x_equal = felem_is_zero(ftmp);
        +	y_equal = felem_is_zero(ftmp3);
        +	z1_is_zero = felem_is_zero(z1);
        +	z2_is_zero = felem_is_zero(z2);
        +	/* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
        +	if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
        +		{
        +		point_double(x3, y3, z3, x1, y1, z1);
        +		return;
        +		}
        +
        +	/* ftmp5 = z1*z2 */
        +	if (!mixed)
        +		{
        +		felem_mul(tmp, z1, z2);
        +		felem_reduce(ftmp5, tmp);
        +		}
        +	else
        +		{
        +		/* special case z2 = 0 is handled later */
        +		felem_assign(ftmp5, z1);
        +		}
        +
        +	/* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
        +	felem_mul(tmp, ftmp, ftmp5);
        +	felem_reduce(z_out, tmp);
        +
        +	/* ftmp = (z1^2*x2 - z2^2*x1)^2 */
        +	felem_assign(ftmp5, ftmp);
        +	felem_square(tmp, ftmp);
        +	felem_reduce(ftmp, tmp);
        +
        +	/* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
        +	felem_mul(tmp, ftmp, ftmp5);
        +	felem_reduce(ftmp5, tmp);
        +
        +	/* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
        +	felem_mul(tmp, ftmp2, ftmp);
        +	felem_reduce(ftmp2, tmp);
        +
        +	/* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
        +	felem_mul(tmp, ftmp4, ftmp5);
        +	/* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
        +
        +	/* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
        +	felem_square(tmp2, ftmp3);
        +	/* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
        +
        +	/* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
        +	felem_diff_128_64(tmp2, ftmp5);
        +	/* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
        +
        +	/* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
        +	felem_assign(ftmp5, ftmp2);
        +	felem_scalar(ftmp5, 2);
        +	/* ftmp5[i] < 2 * 2^57 = 2^58 */
        +
        +	/* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
        +	   2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
        +	felem_diff_128_64(tmp2, ftmp5);
        +	/* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
        +	felem_reduce(x_out, tmp2);
        +
        +	/* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
        +	felem_diff(ftmp2, x_out);
        +	/* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
        +
        +	/* tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) */
        +	felem_mul(tmp2, ftmp3, ftmp2);
        +	/* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
        +
        +	/* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
        +	   z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
        +	widefelem_diff(tmp2, tmp);
        +	/* tmp2[i] < 2^118 + 2^120 < 2^121 */
        +	felem_reduce(y_out, tmp2);
        +
        +	/* the result (x_out, y_out, z_out) is incorrect if one of the inputs is
        +	 * the point at infinity, so we need to check for this separately */
        +
        +	/* if point 1 is at infinity, copy point 2 to output, and vice versa */
        +	copy_conditional(x_out, x2, z1_is_zero);
        +	copy_conditional(x_out, x1, z2_is_zero);
        +	copy_conditional(y_out, y2, z1_is_zero);
        +	copy_conditional(y_out, y1, z2_is_zero);
        +	copy_conditional(z_out, z2, z1_is_zero);
        +	copy_conditional(z_out, z1, z2_is_zero);
        +	felem_assign(x3, x_out);
        +	felem_assign(y3, y_out);
        +	felem_assign(z3, z_out);
        +	}
        +
        +/* select_point selects the |idx|th point from a precomputation table and
        + * copies it to out. */
        +static void select_point(const u64 idx, unsigned int size, const felem pre_comp[/*size*/][3], felem out[3])
        +	{
        +	unsigned i, j;
        +	limb *outlimbs = &out[0][0];
        +	memset(outlimbs, 0, 3 * sizeof(felem));
        +
        +	for (i = 0; i < size; i++)
        +		{
        +		const limb *inlimbs = &pre_comp[i][0][0];
        +		u64 mask = i ^ idx;
        +		mask |= mask >> 4;
        +		mask |= mask >> 2;
        +		mask |= mask >> 1;
        +		mask &= 1;
        +		mask--;
        +		for (j = 0; j < 4 * 3; j++)
        +			outlimbs[j] |= inlimbs[j] & mask;
        +		}
        +	}
        +
        +/* get_bit returns the |i|th bit in |in| */
        +static char get_bit(const felem_bytearray in, unsigned i)
        +	{
        +	if (i >= 224)
        +		return 0;
        +	return (in[i >> 3] >> (i & 7)) & 1;
        +	}
        +
        +/* Interleaved point multiplication using precomputed point multiples:
        + * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
        + * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
        + * of the generator, using certain (large) precomputed multiples in g_pre_comp.
        + * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
        +static void batch_mul(felem x_out, felem y_out, felem z_out,
        +	const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
        +	const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[2][16][3])
        +	{
        +	int i, skip;
        +	unsigned num;
        +	unsigned gen_mul = (g_scalar != NULL);
        +	felem nq[3], tmp[4];
        +	u64 bits;
        +	u8 sign, digit;
        +
        +	/* set nq to the point at infinity */
        +	memset(nq, 0, 3 * sizeof(felem));
        +
        +	/* Loop over all scalars msb-to-lsb, interleaving additions
        +	 * of multiples of the generator (two in each of the last 28 rounds)
        +	 * and additions of other points multiples (every 5th round).
        +	 */
        +	skip = 1; /* save two point operations in the first round */
        +	for (i = (num_points ? 220 : 27); i >= 0; --i)
        +		{
        +		/* double */
        +		if (!skip)
        +			point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
        +
        +		/* add multiples of the generator */
        +		if (gen_mul && (i <= 27))
        +			{
        +			/* first, look 28 bits upwards */
        +			bits = get_bit(g_scalar, i + 196) << 3;
        +			bits |= get_bit(g_scalar, i + 140) << 2;
        +			bits |= get_bit(g_scalar, i + 84) << 1;
        +			bits |= get_bit(g_scalar, i + 28);
        +			/* select the point to add, in constant time */
        +			select_point(bits, 16, g_pre_comp[1], tmp);
        +
        +			if (!skip)
        +				{
        +				point_add(nq[0], nq[1], nq[2],
        +					nq[0], nq[1], nq[2],
        +					1 /* mixed */, tmp[0], tmp[1], tmp[2]);
        +				}
        +			else
        +				{
        +				memcpy(nq, tmp, 3 * sizeof(felem));
        +				skip = 0;
        +				}
        +
        +			/* second, look at the current position */
        +			bits = get_bit(g_scalar, i + 168) << 3;
        +			bits |= get_bit(g_scalar, i + 112) << 2;
        +			bits |= get_bit(g_scalar, i + 56) << 1;
        +			bits |= get_bit(g_scalar, i);
        +			/* select the point to add, in constant time */
        +			select_point(bits, 16, g_pre_comp[0], tmp);
        +			point_add(nq[0], nq[1], nq[2],
        +				nq[0], nq[1], nq[2],
        +				1 /* mixed */, tmp[0], tmp[1], tmp[2]);
        +			}
        +
        +		/* do other additions every 5 doublings */
        +		if (num_points && (i % 5 == 0))
        +			{
        +			/* loop over all scalars */
        +			for (num = 0; num < num_points; ++num)
        +				{
        +				bits = get_bit(scalars[num], i + 4) << 5;
        +				bits |= get_bit(scalars[num], i + 3) << 4;
        +				bits |= get_bit(scalars[num], i + 2) << 3;
        +				bits |= get_bit(scalars[num], i + 1) << 2;
        +				bits |= get_bit(scalars[num], i) << 1;
        +				bits |= get_bit(scalars[num], i - 1);
        +				ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
        +
        +				/* select the point to add or subtract */
        +				select_point(digit, 17, pre_comp[num], tmp);
        +				felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
        +				copy_conditional(tmp[1], tmp[3], sign);
        +
        +				if (!skip)
        +					{
        +					point_add(nq[0], nq[1], nq[2],
        +						nq[0], nq[1], nq[2],
        +						mixed, tmp[0], tmp[1], tmp[2]);
        +					}
        +				else
        +					{
        +					memcpy(nq, tmp, 3 * sizeof(felem));
        +					skip = 0;
        +					}
        +				}
        +			}
        +		}
        +	felem_assign(x_out, nq[0]);
        +	felem_assign(y_out, nq[1]);
        +	felem_assign(z_out, nq[2]);
        +	}
        +
        +/******************************************************************************/
        +/*		       FUNCTIONS TO MANAGE PRECOMPUTATION
        + */
        +
        +static NISTP224_PRE_COMP *nistp224_pre_comp_new()
        +	{
        +	NISTP224_PRE_COMP *ret = NULL;
        +	ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
        +	if (!ret)
        +		{
        +		ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
        +		return ret;
        +		}
        +	memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
        +	ret->references = 1;
        +	return ret;
        +	}
        +
        +static void *nistp224_pre_comp_dup(void *src_)
        +	{
        +	NISTP224_PRE_COMP *src = src_;
        +
        +	/* no need to actually copy, these objects never change! */
        +	CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
        +
        +	return src_;
        +	}
        +
        +static void nistp224_pre_comp_free(void *pre_)
        +	{
        +	int i;
        +	NISTP224_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	OPENSSL_free(pre);
        +	}
        +
        +static void nistp224_pre_comp_clear_free(void *pre_)
        +	{
        +	int i;
        +	NISTP224_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	OPENSSL_cleanse(pre, sizeof *pre);
        +	OPENSSL_free(pre);
        +	}
        +
        +/******************************************************************************/
        +/*			   OPENSSL EC_METHOD FUNCTIONS
        + */
        +
        +int ec_GFp_nistp224_group_init(EC_GROUP *group)
        +	{
        +	int ret;
        +	ret = ec_GFp_simple_group_init(group);
        +	group->a_is_minus3 = 1;
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
        +	const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *curve_p, *curve_a, *curve_b;
        +
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
        +		((curve_a = BN_CTX_get(ctx)) == NULL) ||
        +		((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
        +	BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
        +	BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
        +	BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
        +	if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
        +		(BN_cmp(curve_b, b)))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
        +			EC_R_WRONG_CURVE_PARAMETERS);
        +		goto err;
        +		}
        +	group->field_mod_func = BN_nist_mod_224;
        +	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
        +err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
        + * (X', Y') = (X/Z^2, Y/Z^3) */
        +int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
        +	const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	felem z1, z2, x_in, y_in, x_out, y_out;
        +	widefelem tmp;
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
        +			EC_R_POINT_AT_INFINITY);
        +		return 0;
        +		}
        +	if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
        +		(!BN_to_felem(z1, &point->Z))) return 0;
        +	felem_inv(z2, z1);
        +	felem_square(tmp, z2); felem_reduce(z1, tmp);
        +	felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
        +	felem_contract(x_out, x_in);
        +	if (x != NULL)
        +		{
        +		if (!felem_to_BN(x, x_out)) {
        +		ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
        +			ERR_R_BN_LIB);
        +		return 0;
        +		}
        +		}
        +	felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
        +	felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
        +	felem_contract(y_out, y_in);
        +	if (y != NULL)
        +		{
        +		if (!felem_to_BN(y, y_out)) {
        +		ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
        +			ERR_R_BN_LIB);
        +		return 0;
        +		}
        +		}
        +	return 1;
        +	}
        +
        +static void make_points_affine(size_t num, felem points[/*num*/][3], felem tmp_felems[/*num+1*/])
        +	{
        +	/* Runs in constant time, unless an input is the point at infinity
        +	 * (which normally shouldn't happen). */
        +	ec_GFp_nistp_points_make_affine_internal(
        +		num,
        +		points,
        +		sizeof(felem),
        +		tmp_felems,
        +		(void (*)(void *)) felem_one,
        +		(int (*)(const void *)) felem_is_zero_int,
        +		(void (*)(void *, const void *)) felem_assign,
        +		(void (*)(void *, const void *)) felem_square_reduce,
        +		(void (*)(void *, const void *, const void *)) felem_mul_reduce,
        +		(void (*)(void *, const void *)) felem_inv,
        +		(void (*)(void *, const void *)) felem_contract);
        +	}
        +
        +/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
        + * Result is stored in r (r can equal one of the inputs). */
        +int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
        +	const BIGNUM *scalar, size_t num, const EC_POINT *points[],
        +	const BIGNUM *scalars[], BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	int j;
        +	unsigned i;
        +	int mixed = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y, *z, *tmp_scalar;
        +	felem_bytearray g_secret;
        +	felem_bytearray *secrets = NULL;
        +	felem (*pre_comp)[17][3] = NULL;
        +	felem *tmp_felems = NULL;
        +	felem_bytearray tmp;
        +	unsigned num_bytes;
        +	int have_pre_comp = 0;
        +	size_t num_points = num;
        +	felem x_in, y_in, z_in, x_out, y_out, z_out;
        +	NISTP224_PRE_COMP *pre = NULL;
        +	const felem (*g_pre_comp)[16][3] = NULL;
        +	EC_POINT *generator = NULL;
        +	const EC_POINT *p = NULL;
        +	const BIGNUM *p_scalar = NULL;
        +
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((x = BN_CTX_get(ctx)) == NULL) ||
        +		((y = BN_CTX_get(ctx)) == NULL) ||
        +		((z = BN_CTX_get(ctx)) == NULL) ||
        +		((tmp_scalar = BN_CTX_get(ctx)) == NULL))
        +		goto err;
        +
        +	if (scalar != NULL)
        +		{
        +		pre = EC_EX_DATA_get_data(group->extra_data,
        +			nistp224_pre_comp_dup, nistp224_pre_comp_free,
        +			nistp224_pre_comp_clear_free);
        +		if (pre)
        +			/* we have precomputation, try to use it */
        +			g_pre_comp = (const felem (*)[16][3]) pre->g_pre_comp;
        +		else
        +			/* try to use the standard precomputation */
        +			g_pre_comp = &gmul[0];
        +		generator = EC_POINT_new(group);
        +		if (generator == NULL)
        +			goto err;
        +		/* get the generator from precomputation */
        +		if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
        +			!felem_to_BN(y, g_pre_comp[0][1][1]) ||
        +			!felem_to_BN(z, g_pre_comp[0][1][2]))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
        +				generator, x, y, z, ctx))
        +			goto err;
        +		if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
        +			/* precomputation matches generator */
        +			have_pre_comp = 1;
        +		else
        +			/* we don't have valid precomputation:
        +			 * treat the generator as a random point */
        +			num_points = num_points + 1;
        +		}
        +
        +	if (num_points > 0)
        +		{
        +		if (num_points >= 3)
        +			{
        +			/* unless we precompute multiples for just one or two points,
        +			 * converting those into affine form is time well spent  */
        +			mixed = 1;
        +			}
        +		secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
        +		pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
        +		if (mixed)
        +			tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
        +		if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL)))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* we treat NULL scalars as 0, and NULL points as points at infinity,
        +		 * i.e., they contribute nothing to the linear combination */
        +		memset(secrets, 0, num_points * sizeof(felem_bytearray));
        +		memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
        +		for (i = 0; i < num_points; ++i)
        +			{
        +			if (i == num)
        +				/* the generator */
        +				{
        +				p = EC_GROUP_get0_generator(group);
        +				p_scalar = scalar;
        +				}
        +			else
        +				/* the i^th point */
        +				{
        +				p = points[i];
        +				p_scalar = scalars[i];
        +				}
        +			if ((p_scalar != NULL) && (p != NULL))
        +				{
        +				/* reduce scalar to 0 <= scalar < 2^224 */
        +				if ((BN_num_bits(p_scalar) > 224) || (BN_is_negative(p_scalar)))
        +					{
        +					/* this is an unusual input, and we don't guarantee
        +					 * constant-timeness */
        +					if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
        +						{
        +						ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
        +						goto err;
        +						}
        +					num_bytes = BN_bn2bin(tmp_scalar, tmp);
        +					}
        +				else
        +					num_bytes = BN_bn2bin(p_scalar, tmp);
        +				flip_endian(secrets[i], tmp, num_bytes);
        +				/* precompute multiples */
        +				if ((!BN_to_felem(x_out, &p->X)) ||
        +					(!BN_to_felem(y_out, &p->Y)) ||
        +					(!BN_to_felem(z_out, &p->Z))) goto err;
        +				felem_assign(pre_comp[i][1][0], x_out);
        +				felem_assign(pre_comp[i][1][1], y_out);
        +				felem_assign(pre_comp[i][1][2], z_out);
        +				for (j = 2; j <= 16; ++j)
        +					{
        +					if (j & 1)
        +						{
        +						point_add(
        +							pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
        +							pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
        +							0, pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
        +						}
        +					else
        +						{
        +						point_double(
        +							pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
        +							pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
        +						}
        +					}
        +				}
        +			}
        +		if (mixed)
        +			make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
        +		}
        +
        +	/* the scalar for the generator */
        +	if ((scalar != NULL) && (have_pre_comp))
        +		{
        +		memset(g_secret, 0, sizeof g_secret);
        +		/* reduce scalar to 0 <= scalar < 2^224 */
        +		if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar)))
        +			{
        +			/* this is an unusual input, and we don't guarantee
        +			 * constant-timeness */
        +			if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
        +				{
        +				ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
        +				goto err;
        +				}
        +			num_bytes = BN_bn2bin(tmp_scalar, tmp);
        +			}
        +		else
        +			num_bytes = BN_bn2bin(scalar, tmp);
        +		flip_endian(g_secret, tmp, num_bytes);
        +		/* do the multiplication with generator precomputation*/
        +		batch_mul(x_out, y_out, z_out,
        +			(const felem_bytearray (*)) secrets, num_points,
        +			g_secret,
        +			mixed, (const felem (*)[17][3]) pre_comp,
        +			g_pre_comp);
        +		}
        +	else
        +		/* do the multiplication without generator precomputation */
        +		batch_mul(x_out, y_out, z_out,
        +			(const felem_bytearray (*)) secrets, num_points,
        +			NULL, mixed, (const felem (*)[17][3]) pre_comp, NULL);
        +	/* reduce the output to its unique minimal representation */
        +	felem_contract(x_in, x_out);
        +	felem_contract(y_in, y_out);
        +	felem_contract(z_in, z_out);
        +	if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
        +		(!felem_to_BN(z, z_in)))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	if (generator != NULL)
        +		EC_POINT_free(generator);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (secrets != NULL)
        +		OPENSSL_free(secrets);
        +	if (pre_comp != NULL)
        +		OPENSSL_free(pre_comp);
        +	if (tmp_felems != NULL)
        +		OPENSSL_free(tmp_felems);
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	NISTP224_PRE_COMP *pre = NULL;
        +	int i, j;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y;
        +	EC_POINT *generator = NULL;
        +	felem tmp_felems[32];
        +
        +	/* throw away old precomputation */
        +	EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup,
        +		nistp224_pre_comp_free, nistp224_pre_comp_clear_free);
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((x = BN_CTX_get(ctx)) == NULL) ||
        +		((y = BN_CTX_get(ctx)) == NULL))
        +		goto err;
        +	/* get the generator */
        +	if (group->generator == NULL) goto err;
        +	generator = EC_POINT_new(group);
        +	if (generator == NULL)
        +		goto err;
        +	BN_bin2bn(nistp224_curve_params[3], sizeof (felem_bytearray), x);
        +	BN_bin2bn(nistp224_curve_params[4], sizeof (felem_bytearray), y);
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
        +		goto err;
        +	if ((pre = nistp224_pre_comp_new()) == NULL)
        +		goto err;
        +	/* if the generator is the standard one, use built-in precomputation */
        +	if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
        +		{
        +		memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
        +		ret = 1;
        +		goto err;
        +		}
        +	if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) ||
        +		(!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) ||
        +		(!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z)))
        +		goto err;
        +	/* compute 2^56*G, 2^112*G, 2^168*G for the first table,
        +	 * 2^28*G, 2^84*G, 2^140*G, 2^196*G for the second one
        +	 */
        +	for (i = 1; i <= 8; i <<= 1)
        +		{
        +		point_double(
        +			pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
        +			pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
        +		for (j = 0; j < 27; ++j)
        +			{
        +			point_double(
        +				pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
        +				pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
        +			}
        +		if (i == 8)
        +			break;
        +		point_double(
        +			pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
        +			pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
        +		for (j = 0; j < 27; ++j)
        +			{
        +			point_double(
        +				pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
        +				pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2]);
        +			}
        +		}
        +	for (i = 0; i < 2; i++)
        +		{
        +		/* g_pre_comp[i][0] is the point at infinity */
        +		memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
        +		/* the remaining multiples */
        +		/* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
        +		point_add(
        +			pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
        +			pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
        +			pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
        +			0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
        +			pre->g_pre_comp[i][2][2]);
        +		/* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
        +		point_add(
        +			pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
        +			pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
        +			pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
        +			0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
        +			pre->g_pre_comp[i][2][2]);
        +		/* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
        +		point_add(
        +			pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
        +			pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
        +			pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
        +			0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
        +			pre->g_pre_comp[i][4][2]);
        +		/* 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G */
        +		point_add(
        +			pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
        +			pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
        +			pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
        +			0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
        +			pre->g_pre_comp[i][2][2]);
        +		for (j = 1; j < 8; ++j)
        +			{
        +			/* odd multiples: add G resp. 2^28*G */
        +			point_add(
        +				pre->g_pre_comp[i][2*j+1][0], pre->g_pre_comp[i][2*j+1][1],
        +				pre->g_pre_comp[i][2*j+1][2], pre->g_pre_comp[i][2*j][0],
        +				pre->g_pre_comp[i][2*j][1], pre->g_pre_comp[i][2*j][2],
        +				0, pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
        +				pre->g_pre_comp[i][1][2]);
        +			}
        +		}
        +	make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
        +
        +	if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup,
        +			nistp224_pre_comp_free, nistp224_pre_comp_clear_free))
        +		goto err;
        +	ret = 1;
        +	pre = NULL;
        + err:
        +	BN_CTX_end(ctx);
        +	if (generator != NULL)
        +		EC_POINT_free(generator);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (pre)
        +		nistp224_pre_comp_free(pre);
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
        +	{
        +	if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup,
        +			nistp224_pre_comp_free, nistp224_pre_comp_clear_free)
        +		!= NULL)
        +		return 1;
        +	else
        +		return 0;
        +	}
        +
        +#else
        +static void *dummy=&dummy;
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_nistp256.c b/vendor/openssl/openssl/crypto/ec/ecp_nistp256.c
        new file mode 100644
        index 000000000..4bc0f5dce
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_nistp256.c
        @@ -0,0 +1,2171 @@
        +/* crypto/ec/ecp_nistp256.c */
        +/*
        + * Written by Adam Langley (Google) for the OpenSSL project
        + */
        +/* Copyright 2011 Google Inc.
        + *
        + * Licensed under the Apache License, Version 2.0 (the "License");
        + *
        + * you may not use this file except in compliance with the License.
        + * You may obtain a copy of the License at
        + *
        + *     http://www.apache.org/licenses/LICENSE-2.0
        + *
        + *  Unless required by applicable law or agreed to in writing, software
        + *  distributed under the License is distributed on an "AS IS" BASIS,
        + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        + *  See the License for the specific language governing permissions and
        + *  limitations under the License.
        + */
        +
        +/*
        + * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
        + *
        + * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
        + * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
        + * work which got its smarts from Daniel J. Bernstein's work on the same.
        + */
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +
        +#ifndef OPENSSL_SYS_VMS
        +#include <stdint.h>
        +#else
        +#include <inttypes.h>
        +#endif
        +
        +#include <string.h>
        +#include <openssl/err.h>
        +#include "ec_lcl.h"
        +
        +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
        +  /* even with gcc, the typedef won't work for 32-bit platforms */
        +  typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
        +  typedef __int128_t int128_t;
        +#else
        +  #error "Need GCC 3.1 or later to define type uint128_t"
        +#endif
        +
        +typedef uint8_t u8;
        +typedef uint32_t u32;
        +typedef uint64_t u64;
        +typedef int64_t s64;
        +
        +/* The underlying field.
        + *
        + * P256 operates over GF(2^256-2^224+2^192+2^96-1). We can serialise an element
        + * of this field into 32 bytes. We call this an felem_bytearray. */
        +
        +typedef u8 felem_bytearray[32];
        +
        +/* These are the parameters of P256, taken from FIPS 186-3, page 86. These
        + * values are big-endian. */
        +static const felem_bytearray nistp256_curve_params[5] = {
        +	{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,       /* p */
        +	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +	 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
        +	{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,       /* a = -3 */
        +	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +	 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc},      /* b */
        +	{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
        +	 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
        +	 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
        +	 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
        +	{0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,       /* x */
        +	 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
        +	 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
        +	 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
        +	{0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,       /* y */
        +	 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
        +	 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
        +	 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
        +};
        +
        +/* The representation of field elements.
        + * ------------------------------------
        + *
        + * We represent field elements with either four 128-bit values, eight 128-bit
        + * values, or four 64-bit values. The field element represented is:
        + *   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192  (mod p)
        + * or:
        + *   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512  (mod p)
        + *
        + * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
        + * apart, but are 128-bits wide, the most significant bits of each limb overlap
        + * with the least significant bits of the next.
        + *
        + * A field element with four limbs is an 'felem'. One with eight limbs is a
        + * 'longfelem'
        + *
        + * A field element with four, 64-bit values is called a 'smallfelem'. Small
        + * values are used as intermediate values before multiplication.
        + */
        +
        +#define NLIMBS 4
        +
        +typedef uint128_t limb;
        +typedef limb felem[NLIMBS];
        +typedef limb longfelem[NLIMBS * 2];
        +typedef u64 smallfelem[NLIMBS];
        +
        +/* This is the value of the prime as four 64-bit words, little-endian. */
        +static const u64 kPrime[4] = { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
        +static const limb bottom32bits = 0xffffffff;
        +static const u64 bottom63bits = 0x7ffffffffffffffful;
        +
        +/* bin32_to_felem takes a little-endian byte array and converts it into felem
        + * form. This assumes that the CPU is little-endian. */
        +static void bin32_to_felem(felem out, const u8 in[32])
        +	{
        +	out[0] = *((u64*) &in[0]);
        +	out[1] = *((u64*) &in[8]);
        +	out[2] = *((u64*) &in[16]);
        +	out[3] = *((u64*) &in[24]);
        +	}
        +
        +/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
        + * 32 byte array. This assumes that the CPU is little-endian. */
        +static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
        +	{
        +	*((u64*) &out[0]) = in[0];
        +	*((u64*) &out[8]) = in[1];
        +	*((u64*) &out[16]) = in[2];
        +	*((u64*) &out[24]) = in[3];
        +	}
        +
        +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
        +static void flip_endian(u8 *out, const u8 *in, unsigned len)
        +	{
        +	unsigned i;
        +	for (i = 0; i < len; ++i)
        +		out[i] = in[len-1-i];
        +	}
        +
        +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
        +static int BN_to_felem(felem out, const BIGNUM *bn)
        +	{
        +	felem_bytearray b_in;
        +	felem_bytearray b_out;
        +	unsigned num_bytes;
        +
        +	/* BN_bn2bin eats leading zeroes */
        +	memset(b_out, 0, sizeof b_out);
        +	num_bytes = BN_num_bytes(bn);
        +	if (num_bytes > sizeof b_out)
        +		{
        +		ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
        +		return 0;
        +		}
        +	if (BN_is_negative(bn))
        +		{
        +		ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
        +		return 0;
        +		}
        +	num_bytes = BN_bn2bin(bn, b_in);
        +	flip_endian(b_out, b_in, num_bytes);
        +	bin32_to_felem(out, b_out);
        +	return 1;
        +	}
        +
        +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
        +static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
        +	{
        +	felem_bytearray b_in, b_out;
        +	smallfelem_to_bin32(b_in, in);
        +	flip_endian(b_out, b_in, sizeof b_out);
        +	return BN_bin2bn(b_out, sizeof b_out, out);
        +	}
        +
        +
        +/* Field operations
        + * ---------------- */
        +
        +static void smallfelem_one(smallfelem out)
        +	{
        +	out[0] = 1;
        +	out[1] = 0;
        +	out[2] = 0;
        +	out[3] = 0;
        +	}
        +
        +static void smallfelem_assign(smallfelem out, const smallfelem in)
        +	{
        +	out[0] = in[0];
        +	out[1] = in[1];
        +	out[2] = in[2];
        +	out[3] = in[3];
        +	}
        +
        +static void felem_assign(felem out, const felem in)
        +	{
        +	out[0] = in[0];
        +	out[1] = in[1];
        +	out[2] = in[2];
        +	out[3] = in[3];
        +	}
        +
        +/* felem_sum sets out = out + in. */
        +static void felem_sum(felem out, const felem in)
        +	{
        +	out[0] += in[0];
        +	out[1] += in[1];
        +	out[2] += in[2];
        +	out[3] += in[3];
        +	}
        +
        +/* felem_small_sum sets out = out + in. */
        +static void felem_small_sum(felem out, const smallfelem in)
        +	{
        +	out[0] += in[0];
        +	out[1] += in[1];
        +	out[2] += in[2];
        +	out[3] += in[3];
        +	}
        +
        +/* felem_scalar sets out = out * scalar */
        +static void felem_scalar(felem out, const u64 scalar)
        +	{
        +	out[0] *= scalar;
        +	out[1] *= scalar;
        +	out[2] *= scalar;
        +	out[3] *= scalar;
        +	}
        +
        +/* longfelem_scalar sets out = out * scalar */
        +static void longfelem_scalar(longfelem out, const u64 scalar)
        +	{
        +	out[0] *= scalar;
        +	out[1] *= scalar;
        +	out[2] *= scalar;
        +	out[3] *= scalar;
        +	out[4] *= scalar;
        +	out[5] *= scalar;
        +	out[6] *= scalar;
        +	out[7] *= scalar;
        +	}
        +
        +#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
        +#define two105 (((limb)1) << 105)
        +#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
        +
        +/* zero105 is 0 mod p */
        +static const felem zero105 = { two105m41m9, two105, two105m41p9, two105m41p9 };
        +
        +/* smallfelem_neg sets |out| to |-small|
        + * On exit:
        + *   out[i] < out[i] + 2^105
        + */
        +static void smallfelem_neg(felem out, const smallfelem small)
        +	{
        +	/* In order to prevent underflow, we subtract from 0 mod p. */
        +	out[0] = zero105[0] - small[0];
        +	out[1] = zero105[1] - small[1];
        +	out[2] = zero105[2] - small[2];
        +	out[3] = zero105[3] - small[3];
        +	}
        +
        +/* felem_diff subtracts |in| from |out|
        + * On entry:
        + *   in[i] < 2^104
        + * On exit:
        + *   out[i] < out[i] + 2^105
        + */
        +static void felem_diff(felem out, const felem in)
        +	{
        +	/* In order to prevent underflow, we add 0 mod p before subtracting. */
        +	out[0] += zero105[0];
        +	out[1] += zero105[1];
        +	out[2] += zero105[2];
        +	out[3] += zero105[3];
        +
        +	out[0] -= in[0];
        +	out[1] -= in[1];
        +	out[2] -= in[2];
        +	out[3] -= in[3];
        +	}
        +
        +#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
        +#define two107 (((limb)1) << 107)
        +#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
        +
        +/* zero107 is 0 mod p */
        +static const felem zero107 = { two107m43m11, two107, two107m43p11, two107m43p11 };
        +
        +/* An alternative felem_diff for larger inputs |in|
        + * felem_diff_zero107 subtracts |in| from |out|
        + * On entry:
        + *   in[i] < 2^106
        + * On exit:
        + *   out[i] < out[i] + 2^107
        + */
        +static void felem_diff_zero107(felem out, const felem in)
        +	{
        +	/* In order to prevent underflow, we add 0 mod p before subtracting. */
        +	out[0] += zero107[0];
        +	out[1] += zero107[1];
        +	out[2] += zero107[2];
        +	out[3] += zero107[3];
        +
        +	out[0] -= in[0];
        +	out[1] -= in[1];
        +	out[2] -= in[2];
        +	out[3] -= in[3];
        +	}
        +
        +/* longfelem_diff subtracts |in| from |out|
        + * On entry:
        + *   in[i] < 7*2^67
        + * On exit:
        + *   out[i] < out[i] + 2^70 + 2^40
        + */
        +static void longfelem_diff(longfelem out, const longfelem in)
        +	{
        +	static const limb two70m8p6 = (((limb)1) << 70) - (((limb)1) << 8) + (((limb)1) << 6);
        +	static const limb two70p40 = (((limb)1) << 70) + (((limb)1) << 40);
        +	static const limb two70 = (((limb)1) << 70);
        +	static const limb two70m40m38p6 = (((limb)1) << 70) - (((limb)1) << 40) - (((limb)1) << 38) + (((limb)1) << 6);
        +	static const limb two70m6 = (((limb)1) << 70) - (((limb)1) << 6);
        +
        +	/* add 0 mod p to avoid underflow */
        +	out[0] += two70m8p6;
        +	out[1] += two70p40;
        +	out[2] += two70;
        +	out[3] += two70m40m38p6;
        +	out[4] += two70m6;
        +	out[5] += two70m6;
        +	out[6] += two70m6;
        +	out[7] += two70m6;
        +
        +	/* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
        +	out[0] -= in[0];
        +	out[1] -= in[1];
        +	out[2] -= in[2];
        +	out[3] -= in[3];
        +	out[4] -= in[4];
        +	out[5] -= in[5];
        +	out[6] -= in[6];
        +	out[7] -= in[7];
        +	}
        +
        +#define two64m0 (((limb)1) << 64) - 1
        +#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
        +#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
        +#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
        +
        +/* zero110 is 0 mod p */
        +static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
        +
        +/* felem_shrink converts an felem into a smallfelem. The result isn't quite
        + * minimal as the value may be greater than p.
        + *
        + * On entry:
        + *   in[i] < 2^109
        + * On exit:
        + *   out[i] < 2^64
        + */
        +static void felem_shrink(smallfelem out, const felem in)
        +	{
        +	felem tmp;
        +	u64 a, b, mask;
        +	s64 high, low;
        +	static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
        +
        +	/* Carry 2->3 */
        +	tmp[3] = zero110[3] + in[3] + ((u64) (in[2] >> 64));
        +	/* tmp[3] < 2^110 */
        +
        +	tmp[2] = zero110[2] + (u64) in[2];
        +	tmp[0] = zero110[0] + in[0];
        +	tmp[1] = zero110[1] + in[1];
        +	/* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
        +
        +	/* We perform two partial reductions where we eliminate the
        +	 * high-word of tmp[3]. We don't update the other words till the end.
        +	 */
        +	a = tmp[3] >> 64; /* a < 2^46 */
        +	tmp[3] = (u64) tmp[3];
        +	tmp[3] -= a;
        +	tmp[3] += ((limb)a) << 32;
        +	/* tmp[3] < 2^79 */
        +
        +	b = a;
        +	a = tmp[3] >> 64; /* a < 2^15 */
        +	b += a; /* b < 2^46 + 2^15 < 2^47 */
        +	tmp[3] = (u64) tmp[3];
        +	tmp[3] -= a;
        +	tmp[3] += ((limb)a) << 32;
        +	/* tmp[3] < 2^64 + 2^47 */
        +
        +	/* This adjusts the other two words to complete the two partial
        +	 * reductions. */
        +	tmp[0] += b;
        +	tmp[1] -= (((limb)b) << 32);
        +
        +	/* In order to make space in tmp[3] for the carry from 2 -> 3, we
        +	 * conditionally subtract kPrime if tmp[3] is large enough. */
        +	high = tmp[3] >> 64;
        +	/* As tmp[3] < 2^65, high is either 1 or 0 */
        +	high <<= 63;
        +	high >>= 63;
        +	/* high is:
        +	 *   all ones   if the high word of tmp[3] is 1
        +	 *   all zeros  if the high word of tmp[3] if 0 */
        +	low = tmp[3];
        +	mask = low >> 63;
        +	/* mask is:
        +	 *   all ones   if the MSB of low is 1
        +	 *   all zeros  if the MSB of low if 0 */
        +	low &= bottom63bits;
        +	low -= kPrime3Test;
        +	/* if low was greater than kPrime3Test then the MSB is zero */
        +	low = ~low;
        +	low >>= 63;
        +	/* low is:
        +	 *   all ones   if low was > kPrime3Test
        +	 *   all zeros  if low was <= kPrime3Test */
        +	mask = (mask & low) | high;
        +	tmp[0] -= mask & kPrime[0];
        +	tmp[1] -= mask & kPrime[1];
        +	/* kPrime[2] is zero, so omitted */
        +	tmp[3] -= mask & kPrime[3];
        +	/* tmp[3] < 2**64 - 2**32 + 1 */
        +
        +	tmp[1] += ((u64) (tmp[0] >> 64)); tmp[0] = (u64) tmp[0];
        +	tmp[2] += ((u64) (tmp[1] >> 64)); tmp[1] = (u64) tmp[1];
        +	tmp[3] += ((u64) (tmp[2] >> 64)); tmp[2] = (u64) tmp[2];
        +	/* tmp[i] < 2^64 */
        +
        +	out[0] = tmp[0];
        +	out[1] = tmp[1];
        +	out[2] = tmp[2];
        +	out[3] = tmp[3];
        +	}
        +
        +/* smallfelem_expand converts a smallfelem to an felem */
        +static void smallfelem_expand(felem out, const smallfelem in)
        +	{
        +	out[0] = in[0];
        +	out[1] = in[1];
        +	out[2] = in[2];
        +	out[3] = in[3];
        +	}
        +
        +/* smallfelem_square sets |out| = |small|^2
        + * On entry:
        + *   small[i] < 2^64
        + * On exit:
        + *   out[i] < 7 * 2^64 < 2^67
        + */
        +static void smallfelem_square(longfelem out, const smallfelem small)
        +	{
        +	limb a;
        +	u64 high, low;
        +
        +	a = ((uint128_t) small[0]) * small[0];
        +	low = a;
        +	high = a >> 64;
        +	out[0] = low;
        +	out[1] = high;
        +
        +	a = ((uint128_t) small[0]) * small[1];
        +	low = a;
        +	high = a >> 64;
        +	out[1] += low;
        +	out[1] += low;
        +	out[2] = high;
        +
        +	a = ((uint128_t) small[0]) * small[2];
        +	low = a;
        +	high = a >> 64;
        +	out[2] += low;
        +	out[2] *= 2;
        +	out[3] = high;
        +
        +	a = ((uint128_t) small[0]) * small[3];
        +	low = a;
        +	high = a >> 64;
        +	out[3] += low;
        +	out[4] = high;
        +
        +	a = ((uint128_t) small[1]) * small[2];
        +	low = a;
        +	high = a >> 64;
        +	out[3] += low;
        +	out[3] *= 2;
        +	out[4] += high;
        +
        +	a = ((uint128_t) small[1]) * small[1];
        +	low = a;
        +	high = a >> 64;
        +	out[2] += low;
        +	out[3] += high;
        +
        +	a = ((uint128_t) small[1]) * small[3];
        +	low = a;
        +	high = a >> 64;
        +	out[4] += low;
        +	out[4] *= 2;
        +	out[5] = high;
        +
        +	a = ((uint128_t) small[2]) * small[3];
        +	low = a;
        +	high = a >> 64;
        +	out[5] += low;
        +	out[5] *= 2;
        +	out[6] = high;
        +	out[6] += high;
        +
        +	a = ((uint128_t) small[2]) * small[2];
        +	low = a;
        +	high = a >> 64;
        +	out[4] += low;
        +	out[5] += high;
        +
        +	a = ((uint128_t) small[3]) * small[3];
        +	low = a;
        +	high = a >> 64;
        +	out[6] += low;
        +	out[7] = high;
        +	}
        +
        +/* felem_square sets |out| = |in|^2
        + * On entry:
        + *   in[i] < 2^109
        + * On exit:
        + *   out[i] < 7 * 2^64 < 2^67
        + */
        +static void felem_square(longfelem out, const felem in)
        +	{
        +	u64 small[4];
        +	felem_shrink(small, in);
        +	smallfelem_square(out, small);
        +	}
        +
        +/* smallfelem_mul sets |out| = |small1| * |small2|
        + * On entry:
        + *   small1[i] < 2^64
        + *   small2[i] < 2^64
        + * On exit:
        + *   out[i] < 7 * 2^64 < 2^67
        + */
        +static void smallfelem_mul(longfelem out, const smallfelem small1, const smallfelem small2)
        +	{
        +	limb a;
        +	u64 high, low;
        +
        +	a = ((uint128_t) small1[0]) * small2[0];
        +	low = a;
        +	high = a >> 64;
        +	out[0] = low;
        +	out[1] = high;
        +
        +
        +	a = ((uint128_t) small1[0]) * small2[1];
        +	low = a;
        +	high = a >> 64;
        +	out[1] += low;
        +	out[2] = high;
        +
        +	a = ((uint128_t) small1[1]) * small2[0];
        +	low = a;
        +	high = a >> 64;
        +	out[1] += low;
        +	out[2] += high;
        +
        +
        +	a = ((uint128_t) small1[0]) * small2[2];
        +	low = a;
        +	high = a >> 64;
        +	out[2] += low;
        +	out[3] = high;
        +
        +	a = ((uint128_t) small1[1]) * small2[1];
        +	low = a;
        +	high = a >> 64;
        +	out[2] += low;
        +	out[3] += high;
        +
        +	a = ((uint128_t) small1[2]) * small2[0];
        +	low = a;
        +	high = a >> 64;
        +	out[2] += low;
        +	out[3] += high;
        +
        +
        +	a = ((uint128_t) small1[0]) * small2[3];
        +	low = a;
        +	high = a >> 64;
        +	out[3] += low;
        +	out[4] = high;
        +
        +	a = ((uint128_t) small1[1]) * small2[2];
        +	low = a;
        +	high = a >> 64;
        +	out[3] += low;
        +	out[4] += high;
        +
        +	a = ((uint128_t) small1[2]) * small2[1];
        +	low = a;
        +	high = a >> 64;
        +	out[3] += low;
        +	out[4] += high;
        +
        +	a = ((uint128_t) small1[3]) * small2[0];
        +	low = a;
        +	high = a >> 64;
        +	out[3] += low;
        +	out[4] += high;
        +
        +
        +	a = ((uint128_t) small1[1]) * small2[3];
        +	low = a;
        +	high = a >> 64;
        +	out[4] += low;
        +	out[5] = high;
        +
        +	a = ((uint128_t) small1[2]) * small2[2];
        +	low = a;
        +	high = a >> 64;
        +	out[4] += low;
        +	out[5] += high;
        +
        +	a = ((uint128_t) small1[3]) * small2[1];
        +	low = a;
        +	high = a >> 64;
        +	out[4] += low;
        +	out[5] += high;
        +
        +
        +	a = ((uint128_t) small1[2]) * small2[3];
        +	low = a;
        +	high = a >> 64;
        +	out[5] += low;
        +	out[6] = high;
        +
        +	a = ((uint128_t) small1[3]) * small2[2];
        +	low = a;
        +	high = a >> 64;
        +	out[5] += low;
        +	out[6] += high;
        +
        +
        +	a = ((uint128_t) small1[3]) * small2[3];
        +	low = a;
        +	high = a >> 64;
        +	out[6] += low;
        +	out[7] = high;
        +	}
        +
        +/* felem_mul sets |out| = |in1| * |in2|
        + * On entry:
        + *   in1[i] < 2^109
        + *   in2[i] < 2^109
        + * On exit:
        + *   out[i] < 7 * 2^64 < 2^67
        + */
        +static void felem_mul(longfelem out, const felem in1, const felem in2)
        +	{
        +	smallfelem small1, small2;
        +	felem_shrink(small1, in1);
        +	felem_shrink(small2, in2);
        +	smallfelem_mul(out, small1, small2);
        +	}
        +
        +/* felem_small_mul sets |out| = |small1| * |in2|
        + * On entry:
        + *   small1[i] < 2^64
        + *   in2[i] < 2^109
        + * On exit:
        + *   out[i] < 7 * 2^64 < 2^67
        + */
        +static void felem_small_mul(longfelem out, const smallfelem small1, const felem in2)
        +	{
        +	smallfelem small2;
        +	felem_shrink(small2, in2);
        +	smallfelem_mul(out, small1, small2);
        +	}
        +
        +#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
        +#define two100 (((limb)1) << 100)
        +#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
        +/* zero100 is 0 mod p */
        +static const felem zero100 = { two100m36m4, two100, two100m36p4, two100m36p4 };
        +
        +/* Internal function for the different flavours of felem_reduce.
        + * felem_reduce_ reduces the higher coefficients in[4]-in[7].
        + * On entry:
        + *   out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7] 
        + *   out[1] >= in[7] + 2^32*in[4]
        + *   out[2] >= in[5] + 2^32*in[5]
        + *   out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
        + * On exit:
        + *   out[0] <= out[0] + in[4] + 2^32*in[5]
        + *   out[1] <= out[1] + in[5] + 2^33*in[6]
        + *   out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
        + *   out[3] <= out[3] + 2^32*in[4] + 3*in[7]
        + */
        +static void felem_reduce_(felem out, const longfelem in)
        +	{
        +	int128_t c;
        +	/* combine common terms from below */
        +	c = in[4] + (in[5] << 32);
        +	out[0] += c;
        +	out[3] -= c;
        +
        +	c = in[5] - in[7];
        +	out[1] += c;
        +	out[2] -= c;
        +
        +	/* the remaining terms */
        +	/* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
        +	out[1] -= (in[4] << 32);
        +	out[3] += (in[4] << 32);
        +
        +	/* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
        +	out[2] -= (in[5] << 32);
        +
        +	/* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
        +	out[0] -= in[6];
        +	out[0] -= (in[6] << 32);
        +	out[1] += (in[6] << 33);
        +	out[2] += (in[6] * 2);
        +	out[3] -= (in[6] << 32);
        +
        +	/* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
        +	out[0] -= in[7];
        +	out[0] -= (in[7] << 32);
        +	out[2] += (in[7] << 33);
        +	out[3] += (in[7] * 3);
        +	}
        +
        +/* felem_reduce converts a longfelem into an felem.
        + * To be called directly after felem_square or felem_mul.
        + * On entry:
        + *   in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
        + *   in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
        + * On exit:
        + *   out[i] < 2^101
        + */
        +static void felem_reduce(felem out, const longfelem in)
        +	{
        +	out[0] = zero100[0] + in[0];
        +	out[1] = zero100[1] + in[1];
        +	out[2] = zero100[2] + in[2];
        +	out[3] = zero100[3] + in[3];
        +
        +	felem_reduce_(out, in);
        +
        +	/* out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
        +	 * out[1] > 2^100 - 2^64 - 7*2^96 > 0
        +	 * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
        +	 * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
        +	 *
        +	 * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
        +	 * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
        +	 * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
        +	 * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
        +	 */
        +	}
        +
        +/* felem_reduce_zero105 converts a larger longfelem into an felem.
        + * On entry:
        + *   in[0] < 2^71
        + * On exit:
        + *   out[i] < 2^106
        + */
        +static void felem_reduce_zero105(felem out, const longfelem in)
        +	{
        +	out[0] = zero105[0] + in[0];
        +	out[1] = zero105[1] + in[1];
        +	out[2] = zero105[2] + in[2];
        +	out[3] = zero105[3] + in[3];
        +
        +	felem_reduce_(out, in);
        +
        +	/* out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
        +	 * out[1] > 2^105 - 2^71 - 2^103 > 0
        +	 * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
        +	 * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
        +	 *
        +	 * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
        +	 * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
        +	 * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
        +	 * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
        +	 */
        +	}
        +
        +/* subtract_u64 sets *result = *result - v and *carry to one if the subtraction
        + * underflowed. */
        +static void subtract_u64(u64* result, u64* carry, u64 v)
        +	{
        +	uint128_t r = *result;
        +	r -= v;
        +	*carry = (r >> 64) & 1;
        +	*result = (u64) r;
        +	}
        +
        +/* felem_contract converts |in| to its unique, minimal representation.
        + * On entry:
        + *   in[i] < 2^109
        + */
        +static void felem_contract(smallfelem out, const felem in)
        +	{
        +	unsigned i;
        +	u64 all_equal_so_far = 0, result = 0, carry;
        +
        +	felem_shrink(out, in);
        +	/* small is minimal except that the value might be > p */
        +
        +	all_equal_so_far--;
        +	/* We are doing a constant time test if out >= kPrime. We need to
        +	 * compare each u64, from most-significant to least significant. For
        +	 * each one, if all words so far have been equal (m is all ones) then a
        +	 * non-equal result is the answer. Otherwise we continue. */
        +	for (i = 3; i < 4; i--)
        +		{
        +		u64 equal;
        +		uint128_t a = ((uint128_t) kPrime[i]) - out[i];
        +		/* if out[i] > kPrime[i] then a will underflow and the high
        +		 * 64-bits will all be set. */
        +		result |= all_equal_so_far & ((u64) (a >> 64));
        +
        +		/* if kPrime[i] == out[i] then |equal| will be all zeros and
        +		 * the decrement will make it all ones. */
        +		equal = kPrime[i] ^ out[i];
        +		equal--;
        +		equal &= equal << 32;
        +		equal &= equal << 16;
        +		equal &= equal << 8;
        +		equal &= equal << 4;
        +		equal &= equal << 2;
        +		equal &= equal << 1;
        +		equal = ((s64) equal) >> 63;
        +
        +		all_equal_so_far &= equal;
        +		}
        +
        +	/* if all_equal_so_far is still all ones then the two values are equal
        +	 * and so out >= kPrime is true. */
        +	result |= all_equal_so_far;
        +
        +	/* if out >= kPrime then we subtract kPrime. */
        +	subtract_u64(&out[0], &carry, result & kPrime[0]);
        +	subtract_u64(&out[1], &carry, carry);
        +	subtract_u64(&out[2], &carry, carry);
        +	subtract_u64(&out[3], &carry, carry);
        +
        +	subtract_u64(&out[1], &carry, result & kPrime[1]);
        +	subtract_u64(&out[2], &carry, carry);
        +	subtract_u64(&out[3], &carry, carry);
        +
        +	subtract_u64(&out[2], &carry, result & kPrime[2]);
        +	subtract_u64(&out[3], &carry, carry);
        +
        +	subtract_u64(&out[3], &carry, result & kPrime[3]);
        +	}
        +
        +static void smallfelem_square_contract(smallfelem out, const smallfelem in)
        +	{
        +	longfelem longtmp;
        +	felem tmp;
        +
        +	smallfelem_square(longtmp, in);
        +	felem_reduce(tmp, longtmp);
        +	felem_contract(out, tmp);
        +	}
        +
        +static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, const smallfelem in2)
        +	{
        +	longfelem longtmp;
        +	felem tmp;
        +
        +	smallfelem_mul(longtmp, in1, in2);
        +	felem_reduce(tmp, longtmp);
        +	felem_contract(out, tmp);
        +	}
        +
        +/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
        + * otherwise.
        + * On entry:
        + *   small[i] < 2^64
        + */
        +static limb smallfelem_is_zero(const smallfelem small)
        +	{
        +	limb result;
        +	u64 is_p;
        +
        +	u64 is_zero = small[0] | small[1] | small[2] | small[3];
        +	is_zero--;
        +	is_zero &= is_zero << 32;
        +	is_zero &= is_zero << 16;
        +	is_zero &= is_zero << 8;
        +	is_zero &= is_zero << 4;
        +	is_zero &= is_zero << 2;
        +	is_zero &= is_zero << 1;
        +	is_zero = ((s64) is_zero) >> 63;
        +
        +	is_p = (small[0] ^ kPrime[0]) |
        +	       (small[1] ^ kPrime[1]) |
        +	       (small[2] ^ kPrime[2]) |
        +	       (small[3] ^ kPrime[3]);
        +	is_p--;
        +	is_p &= is_p << 32;
        +	is_p &= is_p << 16;
        +	is_p &= is_p << 8;
        +	is_p &= is_p << 4;
        +	is_p &= is_p << 2;
        +	is_p &= is_p << 1;
        +	is_p = ((s64) is_p) >> 63;
        +
        +	is_zero |= is_p;
        +
        +	result = is_zero;
        +	result |= ((limb) is_zero) << 64;
        +	return result;
        +	}
        +
        +static int smallfelem_is_zero_int(const smallfelem small)
        +	{
        +	return (int) (smallfelem_is_zero(small) & ((limb)1));
        +	}
        +
        +/* felem_inv calculates |out| = |in|^{-1}
        + *
        + * Based on Fermat's Little Theorem:
        + *   a^p = a (mod p)
        + *   a^{p-1} = 1 (mod p)
        + *   a^{p-2} = a^{-1} (mod p)
        + */
        +static void felem_inv(felem out, const felem in)
        +	{
        +	felem ftmp, ftmp2;
        +	/* each e_I will hold |in|^{2^I - 1} */
        +	felem e2, e4, e8, e16, e32, e64;
        +	longfelem tmp;
        +	unsigned i;
        +
        +	felem_square(tmp, in); felem_reduce(ftmp, tmp);			/* 2^1 */
        +	felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp);		/* 2^2 - 2^0 */
        +	felem_assign(e2, ftmp);
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);		/* 2^3 - 2^1 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);		/* 2^4 - 2^2 */
        +	felem_mul(tmp, ftmp, e2); felem_reduce(ftmp, tmp);		/* 2^4 - 2^0 */
        +	felem_assign(e4, ftmp);
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);		/* 2^5 - 2^1 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);		/* 2^6 - 2^2 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);		/* 2^7 - 2^3 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);		/* 2^8 - 2^4 */
        +	felem_mul(tmp, ftmp, e4); felem_reduce(ftmp, tmp);		/* 2^8 - 2^0 */
        +	felem_assign(e8, ftmp);
        +	for (i = 0; i < 8; i++) {
        +		felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
        +	}								/* 2^16 - 2^8 */
        +	felem_mul(tmp, ftmp, e8); felem_reduce(ftmp, tmp);		/* 2^16 - 2^0 */
        +	felem_assign(e16, ftmp);
        +	for (i = 0; i < 16; i++) {
        +		felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
        +	}								/* 2^32 - 2^16 */
        +	felem_mul(tmp, ftmp, e16); felem_reduce(ftmp, tmp);		/* 2^32 - 2^0 */
        +	felem_assign(e32, ftmp);
        +	for (i = 0; i < 32; i++) {
        +		felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
        +	}								/* 2^64 - 2^32 */
        +	felem_assign(e64, ftmp);
        +	felem_mul(tmp, ftmp, in); felem_reduce(ftmp, tmp);		/* 2^64 - 2^32 + 2^0 */
        +	for (i = 0; i < 192; i++) {
        +		felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
        +	}								/* 2^256 - 2^224 + 2^192 */
        +
        +	felem_mul(tmp, e64, e32); felem_reduce(ftmp2, tmp);		/* 2^64 - 2^0 */
        +	for (i = 0; i < 16; i++) {
        +		felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
        +	}								/* 2^80 - 2^16 */
        +	felem_mul(tmp, ftmp2, e16); felem_reduce(ftmp2, tmp);		/* 2^80 - 2^0 */
        +	for (i = 0; i < 8; i++) {
        +		felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
        +	}								/* 2^88 - 2^8 */
        +	felem_mul(tmp, ftmp2, e8); felem_reduce(ftmp2, tmp);		/* 2^88 - 2^0 */
        +	for (i = 0; i < 4; i++) {
        +		felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
        +	}								/* 2^92 - 2^4 */
        +	felem_mul(tmp, ftmp2, e4); felem_reduce(ftmp2, tmp);		/* 2^92 - 2^0 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);		/* 2^93 - 2^1 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);		/* 2^94 - 2^2 */
        +	felem_mul(tmp, ftmp2, e2); felem_reduce(ftmp2, tmp);		/* 2^94 - 2^0 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);		/* 2^95 - 2^1 */
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);		/* 2^96 - 2^2 */
        +	felem_mul(tmp, ftmp2, in); felem_reduce(ftmp2, tmp);		/* 2^96 - 3 */
        +
        +	felem_mul(tmp, ftmp2, ftmp); felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
        +	}
        +
        +static void smallfelem_inv_contract(smallfelem out, const smallfelem in)
        +	{
        +	felem tmp;
        +
        +	smallfelem_expand(tmp, in);
        +	felem_inv(tmp, tmp);
        +	felem_contract(out, tmp);
        +	}
        +
        +/* Group operations
        + * ----------------
        + *
        + * Building on top of the field operations we have the operations on the
        + * elliptic curve group itself. Points on the curve are represented in Jacobian
        + * coordinates */
        +
        +/* point_double calculates 2*(x_in, y_in, z_in)
        + *
        + * The method is taken from:
        + *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
        + *
        + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
        + * while x_out == y_in is not (maybe this works, but it's not tested). */
        +static void
        +point_double(felem x_out, felem y_out, felem z_out,
        +	     const felem x_in, const felem y_in, const felem z_in)
        +	{
        +	longfelem tmp, tmp2;
        +	felem delta, gamma, beta, alpha, ftmp, ftmp2;
        +	smallfelem small1, small2;
        +
        +	felem_assign(ftmp, x_in);
        +	/* ftmp[i] < 2^106 */
        +	felem_assign(ftmp2, x_in);
        +	/* ftmp2[i] < 2^106 */
        +
        +	/* delta = z^2 */
        +	felem_square(tmp, z_in);
        +	felem_reduce(delta, tmp);
        +	/* delta[i] < 2^101 */
        +
        +	/* gamma = y^2 */
        +	felem_square(tmp, y_in);
        +	felem_reduce(gamma, tmp);
        +	/* gamma[i] < 2^101 */
        +	felem_shrink(small1, gamma);
        +
        +	/* beta = x*gamma */
        +	felem_small_mul(tmp, small1, x_in);
        +	felem_reduce(beta, tmp);
        +	/* beta[i] < 2^101 */
        +
        +	/* alpha = 3*(x-delta)*(x+delta) */
        +	felem_diff(ftmp, delta);
        +	/* ftmp[i] < 2^105 + 2^106 < 2^107 */
        +	felem_sum(ftmp2, delta);
        +	/* ftmp2[i] < 2^105 + 2^106 < 2^107 */
        +	felem_scalar(ftmp2, 3);
        +	/* ftmp2[i] < 3 * 2^107 < 2^109 */
        +	felem_mul(tmp, ftmp, ftmp2);
        +	felem_reduce(alpha, tmp);
        +	/* alpha[i] < 2^101 */
        +	felem_shrink(small2, alpha);
        +
        +	/* x' = alpha^2 - 8*beta */
        +	smallfelem_square(tmp, small2);
        +	felem_reduce(x_out, tmp);
        +	felem_assign(ftmp, beta);
        +	felem_scalar(ftmp, 8);
        +	/* ftmp[i] < 8 * 2^101 = 2^104 */
        +	felem_diff(x_out, ftmp);
        +	/* x_out[i] < 2^105 + 2^101 < 2^106 */
        +
        +	/* z' = (y + z)^2 - gamma - delta */
        +	felem_sum(delta, gamma);
        +	/* delta[i] < 2^101 + 2^101 = 2^102 */
        +	felem_assign(ftmp, y_in);
        +	felem_sum(ftmp, z_in);
        +	/* ftmp[i] < 2^106 + 2^106 = 2^107 */
        +	felem_square(tmp, ftmp);
        +	felem_reduce(z_out, tmp);
        +	felem_diff(z_out, delta);
        +	/* z_out[i] < 2^105 + 2^101 < 2^106 */
        +
        +	/* y' = alpha*(4*beta - x') - 8*gamma^2 */
        +	felem_scalar(beta, 4);
        +	/* beta[i] < 4 * 2^101 = 2^103 */
        +	felem_diff_zero107(beta, x_out);
        +	/* beta[i] < 2^107 + 2^103 < 2^108 */
        +	felem_small_mul(tmp, small2, beta);
        +	/* tmp[i] < 7 * 2^64 < 2^67 */
        +	smallfelem_square(tmp2, small1);
        +	/* tmp2[i] < 7 * 2^64 */
        +	longfelem_scalar(tmp2, 8);
        +	/* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
        +	longfelem_diff(tmp, tmp2);
        +	/* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
        +	felem_reduce_zero105(y_out, tmp);
        +	/* y_out[i] < 2^106 */
        +	}
        +
        +/* point_double_small is the same as point_double, except that it operates on
        + * smallfelems */
        +static void
        +point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
        +		   const smallfelem x_in, const smallfelem y_in, const smallfelem z_in)
        +	{
        +	felem felem_x_out, felem_y_out, felem_z_out;
        +	felem felem_x_in, felem_y_in, felem_z_in;
        +
        +	smallfelem_expand(felem_x_in, x_in);
        +	smallfelem_expand(felem_y_in, y_in);
        +	smallfelem_expand(felem_z_in, z_in);
        +	point_double(felem_x_out, felem_y_out, felem_z_out,
        +		     felem_x_in, felem_y_in, felem_z_in);
        +	felem_shrink(x_out, felem_x_out);
        +	felem_shrink(y_out, felem_y_out);
        +	felem_shrink(z_out, felem_z_out);
        +	}
        +
        +/* copy_conditional copies in to out iff mask is all ones. */
        +static void
        +copy_conditional(felem out, const felem in, limb mask)
        +	{
        +	unsigned i;
        +	for (i = 0; i < NLIMBS; ++i)
        +		{
        +		const limb tmp = mask & (in[i] ^ out[i]);
        +		out[i] ^= tmp;
        +		}
        +	}
        +
        +/* copy_small_conditional copies in to out iff mask is all ones. */
        +static void
        +copy_small_conditional(felem out, const smallfelem in, limb mask)
        +	{
        +	unsigned i;
        +	const u64 mask64 = mask;
        +	for (i = 0; i < NLIMBS; ++i)
        +		{
        +		out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
        +		}
        +	}
        +
        +/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
        + *
        + * The method is taken from:
        + *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
        + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
        + *
        + * This function includes a branch for checking whether the two input points
        + * are equal, (while not equal to the point at infinity). This case never
        + * happens during single point multiplication, so there is no timing leak for
        + * ECDH or ECDSA signing. */
        +static void point_add(felem x3, felem y3, felem z3,
        +	const felem x1, const felem y1, const felem z1,
        +	const int mixed, const smallfelem x2, const smallfelem y2, const smallfelem z2)
        +	{
        +	felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
        +	longfelem tmp, tmp2;
        +	smallfelem small1, small2, small3, small4, small5;
        +	limb x_equal, y_equal, z1_is_zero, z2_is_zero;
        +
        +	felem_shrink(small3, z1);
        +
        +	z1_is_zero = smallfelem_is_zero(small3);
        +	z2_is_zero = smallfelem_is_zero(z2);
        +
        +	/* ftmp = z1z1 = z1**2 */
        +	smallfelem_square(tmp, small3);
        +	felem_reduce(ftmp, tmp);
        +	/* ftmp[i] < 2^101 */
        +	felem_shrink(small1, ftmp);
        +
        +	if(!mixed)
        +		{
        +		/* ftmp2 = z2z2 = z2**2 */
        +		smallfelem_square(tmp, z2);
        +		felem_reduce(ftmp2, tmp);
        +		/* ftmp2[i] < 2^101 */
        +		felem_shrink(small2, ftmp2);
        +
        +		felem_shrink(small5, x1);
        +
        +		/* u1 = ftmp3 = x1*z2z2 */
        +		smallfelem_mul(tmp, small5, small2);
        +		felem_reduce(ftmp3, tmp);
        +		/* ftmp3[i] < 2^101 */
        +
        +		/* ftmp5 = z1 + z2 */
        +		felem_assign(ftmp5, z1);
        +		felem_small_sum(ftmp5, z2);
        +		/* ftmp5[i] < 2^107 */
        +
        +		/* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
        +		felem_square(tmp, ftmp5);
        +		felem_reduce(ftmp5, tmp);
        +		/* ftmp2 = z2z2 + z1z1 */
        +		felem_sum(ftmp2, ftmp);
        +		/* ftmp2[i] < 2^101 + 2^101 = 2^102 */
        +		felem_diff(ftmp5, ftmp2);
        +		/* ftmp5[i] < 2^105 + 2^101 < 2^106 */
        +
        +		/* ftmp2 = z2 * z2z2 */
        +		smallfelem_mul(tmp, small2, z2);
        +		felem_reduce(ftmp2, tmp);
        +
        +		/* s1 = ftmp2 = y1 * z2**3 */
        +		felem_mul(tmp, y1, ftmp2);
        +		felem_reduce(ftmp6, tmp);
        +		/* ftmp6[i] < 2^101 */
        +		}
        +	else
        +		{
        +		/* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
        +
        +		/* u1 = ftmp3 = x1*z2z2 */
        +		felem_assign(ftmp3, x1);
        +		/* ftmp3[i] < 2^106 */
        +
        +		/* ftmp5 = 2z1z2 */
        +		felem_assign(ftmp5, z1);
        +		felem_scalar(ftmp5, 2);
        +		/* ftmp5[i] < 2*2^106 = 2^107 */
        +
        +		/* s1 = ftmp2 = y1 * z2**3 */
        +		felem_assign(ftmp6, y1);
        +		/* ftmp6[i] < 2^106 */
        +		}
        +
        +	/* u2 = x2*z1z1 */
        +	smallfelem_mul(tmp, x2, small1);
        +	felem_reduce(ftmp4, tmp);
        +
        +	/* h = ftmp4 = u2 - u1 */
        +	felem_diff_zero107(ftmp4, ftmp3);
        +	/* ftmp4[i] < 2^107 + 2^101 < 2^108 */
        +	felem_shrink(small4, ftmp4);
        +
        +	x_equal = smallfelem_is_zero(small4);
        +
        +	/* z_out = ftmp5 * h */
        +	felem_small_mul(tmp, small4, ftmp5);
        +	felem_reduce(z_out, tmp);
        +	/* z_out[i] < 2^101 */
        +
        +	/* ftmp = z1 * z1z1 */
        +	smallfelem_mul(tmp, small1, small3);
        +	felem_reduce(ftmp, tmp);
        +
        +	/* s2 = tmp = y2 * z1**3 */
        +	felem_small_mul(tmp, y2, ftmp);
        +	felem_reduce(ftmp5, tmp);
        +
        +	/* r = ftmp5 = (s2 - s1)*2 */
        +	felem_diff_zero107(ftmp5, ftmp6);
        +	/* ftmp5[i] < 2^107 + 2^107 = 2^108*/
        +	felem_scalar(ftmp5, 2);
        +	/* ftmp5[i] < 2^109 */
        +	felem_shrink(small1, ftmp5);
        +	y_equal = smallfelem_is_zero(small1);
        +
        +	if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
        +		{
        +		point_double(x3, y3, z3, x1, y1, z1);
        +		return;
        +		}
        +
        +	/* I = ftmp = (2h)**2 */
        +	felem_assign(ftmp, ftmp4);
        +	felem_scalar(ftmp, 2);
        +	/* ftmp[i] < 2*2^108 = 2^109 */
        +	felem_square(tmp, ftmp);
        +	felem_reduce(ftmp, tmp);
        +
        +	/* J = ftmp2 = h * I */
        +	felem_mul(tmp, ftmp4, ftmp);
        +	felem_reduce(ftmp2, tmp);
        +
        +	/* V = ftmp4 = U1 * I */
        +	felem_mul(tmp, ftmp3, ftmp);
        +	felem_reduce(ftmp4, tmp);
        +
        +	/* x_out = r**2 - J - 2V */
        +	smallfelem_square(tmp, small1);
        +	felem_reduce(x_out, tmp);
        +	felem_assign(ftmp3, ftmp4);
        +	felem_scalar(ftmp4, 2);
        +	felem_sum(ftmp4, ftmp2);
        +	/* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
        +	felem_diff(x_out, ftmp4);
        +	/* x_out[i] < 2^105 + 2^101 */
        +
        +	/* y_out = r(V-x_out) - 2 * s1 * J */
        +	felem_diff_zero107(ftmp3, x_out);
        +	/* ftmp3[i] < 2^107 + 2^101 < 2^108 */
        +	felem_small_mul(tmp, small1, ftmp3);
        +	felem_mul(tmp2, ftmp6, ftmp2);
        +	longfelem_scalar(tmp2, 2);
        +	/* tmp2[i] < 2*2^67 = 2^68 */
        +	longfelem_diff(tmp, tmp2);
        +	/* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
        +	felem_reduce_zero105(y_out, tmp);
        +	/* y_out[i] < 2^106 */
        +
        +	copy_small_conditional(x_out, x2, z1_is_zero);
        +	copy_conditional(x_out, x1, z2_is_zero);
        +	copy_small_conditional(y_out, y2, z1_is_zero);
        +	copy_conditional(y_out, y1, z2_is_zero);
        +	copy_small_conditional(z_out, z2, z1_is_zero);
        +	copy_conditional(z_out, z1, z2_is_zero);
        +	felem_assign(x3, x_out);
        +	felem_assign(y3, y_out);
        +	felem_assign(z3, z_out);
        +	}
        +
        +/* point_add_small is the same as point_add, except that it operates on
        + * smallfelems */
        +static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
        +			    smallfelem x1, smallfelem y1, smallfelem z1,
        +			    smallfelem x2, smallfelem y2, smallfelem z2)
        +	{
        +	felem felem_x3, felem_y3, felem_z3;
        +	felem felem_x1, felem_y1, felem_z1;
        +	smallfelem_expand(felem_x1, x1);
        +	smallfelem_expand(felem_y1, y1);
        +	smallfelem_expand(felem_z1, z1);
        +	point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, x2, y2, z2);
        +	felem_shrink(x3, felem_x3);
        +	felem_shrink(y3, felem_y3);
        +	felem_shrink(z3, felem_z3);
        +	}
        +
        +/* Base point pre computation
        + * --------------------------
        + *
        + * Two different sorts of precomputed tables are used in the following code.
        + * Each contain various points on the curve, where each point is three field
        + * elements (x, y, z).
        + *
        + * For the base point table, z is usually 1 (0 for the point at infinity).
        + * This table has 2 * 16 elements, starting with the following:
        + * index | bits    | point
        + * ------+---------+------------------------------
        + *     0 | 0 0 0 0 | 0G
        + *     1 | 0 0 0 1 | 1G
        + *     2 | 0 0 1 0 | 2^64G
        + *     3 | 0 0 1 1 | (2^64 + 1)G
        + *     4 | 0 1 0 0 | 2^128G
        + *     5 | 0 1 0 1 | (2^128 + 1)G
        + *     6 | 0 1 1 0 | (2^128 + 2^64)G
        + *     7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
        + *     8 | 1 0 0 0 | 2^192G
        + *     9 | 1 0 0 1 | (2^192 + 1)G
        + *    10 | 1 0 1 0 | (2^192 + 2^64)G
        + *    11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
        + *    12 | 1 1 0 0 | (2^192 + 2^128)G
        + *    13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
        + *    14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
        + *    15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
        + * followed by a copy of this with each element multiplied by 2^32.
        + *
        + * The reason for this is so that we can clock bits into four different
        + * locations when doing simple scalar multiplies against the base point,
        + * and then another four locations using the second 16 elements.
        + *
        + * Tables for other points have table[i] = iG for i in 0 .. 16. */
        +
        +/* gmul is the table of precomputed base points */
        +static const smallfelem gmul[2][16][3] =
        +{{{{0, 0, 0, 0},
        +   {0, 0, 0, 0},
        +   {0, 0, 0, 0}},
        +  {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, 0x6b17d1f2e12c4247},
        +   {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, 0x4fe342e2fe1a7f9b},
        +   {1, 0, 0, 0}},
        +  {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, 0x0fa822bc2811aaa5},
        +   {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, 0xbff44ae8f5dba80d},
        +   {1, 0, 0, 0}},
        +  {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, 0x300a4bbc89d6726f},
        +   {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, 0x72aac7e0d09b4644},
        +   {1, 0, 0, 0}},
        +  {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, 0x447d739beedb5e67},
        +   {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, 0x2d4825ab834131ee},
        +   {1, 0, 0, 0}},
        +  {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, 0xef9519328a9c72ff},
        +   {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, 0x611e9fc37dbb2c9b},
        +   {1, 0, 0, 0}},
        +  {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, 0x550663797b51f5d8},
        +   {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, 0x157164848aecb851},
        +   {1, 0, 0, 0}},
        +  {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, 0xeb5d7745b21141ea},
        +   {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, 0xeafd72ebdbecc17b},
        +   {1, 0, 0, 0}},
        +  {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, 0xa6d39677a7849276},
        +   {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, 0x674f84749b0b8816},
        +   {1, 0, 0, 0}},
        +  {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, 0x4e769e7672c9ddad},
        +   {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, 0x42b99082de830663},
        +   {1, 0, 0, 0}},
        +  {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, 0x78878ef61c6ce04d},
        +   {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, 0xb6cb3f5d7b72c321},
        +   {1, 0, 0, 0}},
        +  {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, 0x0c88bc4d716b1287},
        +   {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, 0xdd5ddea3f3901dc6},
        +   {1, 0, 0, 0}},
        +  {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, 0x68f344af6b317466},
        +   {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, 0x31b9c405f8540a20},
        +   {1, 0, 0, 0}},
        +  {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, 0x4052bf4b6f461db9},
        +   {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, 0xfecf4d5190b0fc61},
        +   {1, 0, 0, 0}},
        +  {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, 0x1eddbae2c802e41a},
        +   {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, 0x43104d86560ebcfc},
        +   {1, 0, 0, 0}},
        +  {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, 0xb48e26b484f7a21c},
        +   {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, 0xfac015404d4d3dab},
        +   {1, 0, 0, 0}}},
        + {{{0, 0, 0, 0},
        +   {0, 0, 0, 0},
        +   {0, 0, 0, 0}},
        +  {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, 0x7fe36b40af22af89},
        +   {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, 0xe697d45825b63624},
        +   {1, 0, 0, 0}},
        +  {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, 0x4a5b506612a677a6},
        +   {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, 0xeb13461ceac089f1},
        +   {1, 0, 0, 0}},
        +  {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, 0x0781b8291c6a220a},
        +   {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, 0x690cde8df0151593},
        +   {1, 0, 0, 0}},
        +  {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, 0x8a535f566ec73617},
        +   {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, 0x0455c08468b08bd7},
        +   {1, 0, 0, 0}},
        +  {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, 0x06bada7ab77f8276},
        +   {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, 0x5b476dfd0e6cb18a},
        +   {1, 0, 0, 0}},
        +  {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, 0x3e29864e8a2ec908},
        +   {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, 0x239b90ea3dc31e7e},
        +   {1, 0, 0, 0}},
        +  {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, 0x820f4dd949f72ff7},
        +   {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, 0x140406ec783a05ec},
        +   {1, 0, 0, 0}},
        +  {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, 0x68f6b8542783dfee},
        +   {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, 0xcbe1feba92e40ce6},
        +   {1, 0, 0, 0}},
        +  {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, 0xd0b2f94d2f420109},
        +   {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, 0x971459828b0719e5},
        +   {1, 0, 0, 0}},
        +  {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, 0x961610004a866aba},
        +   {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, 0x7acb9fadcee75e44},
        +   {1, 0, 0, 0}},
        +  {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, 0x24eb9acca333bf5b},
        +   {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, 0x69f891c5acd079cc},
        +   {1, 0, 0, 0}},
        +  {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, 0xe51f547c5972a107},
        +   {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, 0x1c309a2b25bb1387},
        +   {1, 0, 0, 0}},
        +  {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, 0x20b87b8aa2c4e503},
        +   {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, 0xf5c6fa49919776be},
        +   {1, 0, 0, 0}},
        +  {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, 0x1ed7d1b9332010b9},
        +   {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, 0x3a2b03f03217257a},
        +   {1, 0, 0, 0}},
        +  {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, 0x15fee545c78dd9f6},
        +   {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81},
        +   {1, 0, 0, 0}}}};
        +
        +/* select_point selects the |idx|th point from a precomputation table and
        + * copies it to out. */
        +static void select_point(const u64 idx, unsigned int size, const smallfelem pre_comp[16][3], smallfelem out[3])
        +	{
        +	unsigned i, j;
        +	u64 *outlimbs = &out[0][0];
        +	memset(outlimbs, 0, 3 * sizeof(smallfelem));
        +
        +	for (i = 0; i < size; i++)
        +		{
        +		const u64 *inlimbs = (u64*) &pre_comp[i][0][0];
        +		u64 mask = i ^ idx;
        +		mask |= mask >> 4;
        +		mask |= mask >> 2;
        +		mask |= mask >> 1;
        +		mask &= 1;
        +		mask--;
        +		for (j = 0; j < NLIMBS * 3; j++)
        +			outlimbs[j] |= inlimbs[j] & mask;
        +		}
        +	}
        +
        +/* get_bit returns the |i|th bit in |in| */
        +static char get_bit(const felem_bytearray in, int i)
        +	{
        +	if ((i < 0) || (i >= 256))
        +		return 0;
        +	return (in[i >> 3] >> (i & 7)) & 1;
        +	}
        +
        +/* Interleaved point multiplication using precomputed point multiples:
        + * The small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[],
        + * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
        + * of the generator, using certain (large) precomputed multiples in g_pre_comp.
        + * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
        +static void batch_mul(felem x_out, felem y_out, felem z_out,
        +	const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
        +	const int mixed, const smallfelem pre_comp[][17][3], const smallfelem g_pre_comp[2][16][3])
        +	{
        +	int i, skip;
        +	unsigned num, gen_mul = (g_scalar != NULL);
        +	felem nq[3], ftmp;
        +	smallfelem tmp[3];
        +	u64 bits;
        +	u8 sign, digit;
        +
        +	/* set nq to the point at infinity */
        +	memset(nq, 0, 3 * sizeof(felem));
        +
        +	/* Loop over all scalars msb-to-lsb, interleaving additions
        +	 * of multiples of the generator (two in each of the last 32 rounds)
        +	 * and additions of other points multiples (every 5th round).
        +	 */
        +	skip = 1; /* save two point operations in the first round */
        +	for (i = (num_points ? 255 : 31); i >= 0; --i)
        +		{
        +		/* double */
        +		if (!skip)
        +			point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
        +
        +		/* add multiples of the generator */
        +		if (gen_mul && (i <= 31))
        +			{
        +			/* first, look 32 bits upwards */
        +			bits = get_bit(g_scalar, i + 224) << 3;
        +			bits |= get_bit(g_scalar, i + 160) << 2;
        +			bits |= get_bit(g_scalar, i + 96) << 1;
        +			bits |= get_bit(g_scalar, i + 32);
        +			/* select the point to add, in constant time */
        +			select_point(bits, 16, g_pre_comp[1], tmp);
        +
        +			if (!skip)
        +				{
        +				point_add(nq[0], nq[1], nq[2],
        +					nq[0], nq[1], nq[2],
        +					1 /* mixed */, tmp[0], tmp[1], tmp[2]);
        +				}
        +			else
        +				{
        +				smallfelem_expand(nq[0], tmp[0]);
        +				smallfelem_expand(nq[1], tmp[1]);
        +				smallfelem_expand(nq[2], tmp[2]);
        +				skip = 0;
        +				}
        +
        +			/* second, look at the current position */
        +			bits = get_bit(g_scalar, i + 192) << 3;
        +			bits |= get_bit(g_scalar, i + 128) << 2;
        +			bits |= get_bit(g_scalar, i + 64) << 1;
        +			bits |= get_bit(g_scalar, i);
        +			/* select the point to add, in constant time */
        +			select_point(bits, 16, g_pre_comp[0], tmp);
        +			point_add(nq[0], nq[1], nq[2],
        +				nq[0], nq[1], nq[2],
        +				1 /* mixed */, tmp[0], tmp[1], tmp[2]);
        +			}
        +
        +		/* do other additions every 5 doublings */
        +		if (num_points && (i % 5 == 0))
        +			{
        +			/* loop over all scalars */
        +			for (num = 0; num < num_points; ++num)
        +				{
        +				bits = get_bit(scalars[num], i + 4) << 5;
        +				bits |= get_bit(scalars[num], i + 3) << 4;
        +				bits |= get_bit(scalars[num], i + 2) << 3;
        +				bits |= get_bit(scalars[num], i + 1) << 2;
        +				bits |= get_bit(scalars[num], i) << 1;
        +				bits |= get_bit(scalars[num], i - 1);
        +				ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
        +
        +				/* select the point to add or subtract, in constant time */
        +				select_point(digit, 17, pre_comp[num], tmp);
        +				smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative point */
        +				copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
        +				felem_contract(tmp[1], ftmp);
        +
        +				if (!skip)
        +					{
        +					point_add(nq[0], nq[1], nq[2],
        +						nq[0], nq[1], nq[2],
        +						mixed, tmp[0], tmp[1], tmp[2]);
        +					}
        +				else
        +					{
        +					smallfelem_expand(nq[0], tmp[0]);
        +					smallfelem_expand(nq[1], tmp[1]);
        +					smallfelem_expand(nq[2], tmp[2]);
        +					skip = 0;
        +					}
        +				}
        +			}
        +		}
        +	felem_assign(x_out, nq[0]);
        +	felem_assign(y_out, nq[1]);
        +	felem_assign(z_out, nq[2]);
        +	}
        +
        +/* Precomputation for the group generator. */
        +typedef struct {
        +	smallfelem g_pre_comp[2][16][3];
        +	int references;
        +} NISTP256_PRE_COMP;
        +
        +const EC_METHOD *EC_GFp_nistp256_method(void)
        +	{
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_prime_field,
        +		ec_GFp_nistp256_group_init,
        +		ec_GFp_simple_group_finish,
        +		ec_GFp_simple_group_clear_finish,
        +		ec_GFp_nist_group_copy,
        +		ec_GFp_nistp256_group_set_curve,
        +		ec_GFp_simple_group_get_curve,
        +		ec_GFp_simple_group_get_degree,
        +		ec_GFp_simple_group_check_discriminant,
        +		ec_GFp_simple_point_init,
        +		ec_GFp_simple_point_finish,
        +		ec_GFp_simple_point_clear_finish,
        +		ec_GFp_simple_point_copy,
        +		ec_GFp_simple_point_set_to_infinity,
        +		ec_GFp_simple_set_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_get_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_point_set_affine_coordinates,
        +		ec_GFp_nistp256_point_get_affine_coordinates,
        +		0 /* point_set_compressed_coordinates */,
        +		0 /* point2oct */,
        +		0 /* oct2point */,
        +		ec_GFp_simple_add,
        +		ec_GFp_simple_dbl,
        +		ec_GFp_simple_invert,
        +		ec_GFp_simple_is_at_infinity,
        +		ec_GFp_simple_is_on_curve,
        +		ec_GFp_simple_cmp,
        +		ec_GFp_simple_make_affine,
        +		ec_GFp_simple_points_make_affine,
        +		ec_GFp_nistp256_points_mul,
        +		ec_GFp_nistp256_precompute_mult,
        +		ec_GFp_nistp256_have_precompute_mult,
        +		ec_GFp_nist_field_mul,
        +		ec_GFp_nist_field_sqr,
        +		0 /* field_div */,
        +		0 /* field_encode */,
        +		0 /* field_decode */,
        +		0 /* field_set_to_one */ };
        +
        +	return &ret;
        +	}
        +
        +/******************************************************************************/
        +/*		       FUNCTIONS TO MANAGE PRECOMPUTATION
        + */
        +
        +static NISTP256_PRE_COMP *nistp256_pre_comp_new()
        +	{
        +	NISTP256_PRE_COMP *ret = NULL;
        +	ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
        +	if (!ret)
        +		{
        +		ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
        +		return ret;
        +		}
        +	memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
        +	ret->references = 1;
        +	return ret;
        +	}
        +
        +static void *nistp256_pre_comp_dup(void *src_)
        +	{
        +	NISTP256_PRE_COMP *src = src_;
        +
        +	/* no need to actually copy, these objects never change! */
        +	CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
        +
        +	return src_;
        +	}
        +
        +static void nistp256_pre_comp_free(void *pre_)
        +	{
        +	int i;
        +	NISTP256_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	OPENSSL_free(pre);
        +	}
        +
        +static void nistp256_pre_comp_clear_free(void *pre_)
        +	{
        +	int i;
        +	NISTP256_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	OPENSSL_cleanse(pre, sizeof *pre);
        +	OPENSSL_free(pre);
        +	}
        +
        +/******************************************************************************/
        +/*			   OPENSSL EC_METHOD FUNCTIONS
        + */
        +
        +int ec_GFp_nistp256_group_init(EC_GROUP *group)
        +	{
        +	int ret;
        +	ret = ec_GFp_simple_group_init(group);
        +	group->a_is_minus3 = 1;
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
        +	const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *curve_p, *curve_a, *curve_b;
        +
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
        +		((curve_a = BN_CTX_get(ctx)) == NULL) ||
        +		((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
        +	BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
        +	BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
        +	BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
        +	if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
        +		(BN_cmp(curve_b, b)))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
        +			EC_R_WRONG_CURVE_PARAMETERS);
        +		goto err;
        +		}
        +	group->field_mod_func = BN_nist_mod_256;
        +	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
        +err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
        + * (X', Y') = (X/Z^2, Y/Z^3) */
        +int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
        +	const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	felem z1, z2, x_in, y_in;
        +	smallfelem x_out, y_out;
        +	longfelem tmp;
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
        +			EC_R_POINT_AT_INFINITY);
        +		return 0;
        +		}
        +	if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
        +		(!BN_to_felem(z1, &point->Z))) return 0;
        +	felem_inv(z2, z1);
        +	felem_square(tmp, z2); felem_reduce(z1, tmp);
        +	felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
        +	felem_contract(x_out, x_in);
        +	if (x != NULL)
        +		{
        +		if (!smallfelem_to_BN(x, x_out)) {
        +		ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
        +			ERR_R_BN_LIB);
        +		return 0;
        +		}
        +		}
        +	felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
        +	felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
        +	felem_contract(y_out, y_in);
        +	if (y != NULL)
        +		{
        +		if (!smallfelem_to_BN(y, y_out))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
        +				ERR_R_BN_LIB);
        +			return 0;
        +			}
        +		}
        +	return 1;
        +	}
        +
        +static void make_points_affine(size_t num, smallfelem points[/* num */][3], smallfelem tmp_smallfelems[/* num+1 */])
        +	{
        +	/* Runs in constant time, unless an input is the point at infinity
        +	 * (which normally shouldn't happen). */
        +	ec_GFp_nistp_points_make_affine_internal(
        +		num,
        +		points,
        +		sizeof(smallfelem),
        +		tmp_smallfelems,
        +		(void (*)(void *)) smallfelem_one,
        +		(int (*)(const void *)) smallfelem_is_zero_int,
        +		(void (*)(void *, const void *)) smallfelem_assign,
        +		(void (*)(void *, const void *)) smallfelem_square_contract,
        +		(void (*)(void *, const void *, const void *)) smallfelem_mul_contract,
        +		(void (*)(void *, const void *)) smallfelem_inv_contract,
        +		(void (*)(void *, const void *)) smallfelem_assign /* nothing to contract */);
        +	}
        +
        +/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
        + * Result is stored in r (r can equal one of the inputs). */
        +int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
        +	const BIGNUM *scalar, size_t num, const EC_POINT *points[],
        +	const BIGNUM *scalars[], BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	int j;
        +	int mixed = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y, *z, *tmp_scalar;
        +	felem_bytearray g_secret;
        +	felem_bytearray *secrets = NULL;
        +	smallfelem (*pre_comp)[17][3] = NULL;
        +	smallfelem *tmp_smallfelems = NULL;
        +	felem_bytearray tmp;
        +	unsigned i, num_bytes;
        +	int have_pre_comp = 0;
        +	size_t num_points = num;
        +	smallfelem x_in, y_in, z_in;
        +	felem x_out, y_out, z_out;
        +	NISTP256_PRE_COMP *pre = NULL;
        +	const smallfelem (*g_pre_comp)[16][3] = NULL;
        +	EC_POINT *generator = NULL;
        +	const EC_POINT *p = NULL;
        +	const BIGNUM *p_scalar = NULL;
        +
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((x = BN_CTX_get(ctx)) == NULL) ||
        +		((y = BN_CTX_get(ctx)) == NULL) ||
        +		((z = BN_CTX_get(ctx)) == NULL) ||
        +		((tmp_scalar = BN_CTX_get(ctx)) == NULL))
        +		goto err;
        +
        +	if (scalar != NULL)
        +		{
        +		pre = EC_EX_DATA_get_data(group->extra_data,
        +			nistp256_pre_comp_dup, nistp256_pre_comp_free,
        +			nistp256_pre_comp_clear_free);
        +		if (pre)
        +			/* we have precomputation, try to use it */
        +			g_pre_comp = (const smallfelem (*)[16][3]) pre->g_pre_comp;
        +		else
        +			/* try to use the standard precomputation */
        +			g_pre_comp = &gmul[0];
        +		generator = EC_POINT_new(group);
        +		if (generator == NULL)
        +			goto err;
        +		/* get the generator from precomputation */
        +		if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
        +			!smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
        +			!smallfelem_to_BN(z, g_pre_comp[0][1][2]))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
        +				generator, x, y, z, ctx))
        +			goto err;
        +		if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
        +			/* precomputation matches generator */
        +			have_pre_comp = 1;
        +		else
        +			/* we don't have valid precomputation:
        +			 * treat the generator as a random point */
        +			num_points++;
        +		}
        +	if (num_points > 0)
        +		{
        +		if (num_points >= 3)
        +			{
        +			/* unless we precompute multiples for just one or two points,
        +			 * converting those into affine form is time well spent  */
        +			mixed = 1;
        +			}
        +		secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
        +		pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
        +		if (mixed)
        +			tmp_smallfelems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
        +		if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_smallfelems == NULL)))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* we treat NULL scalars as 0, and NULL points as points at infinity,
        +		 * i.e., they contribute nothing to the linear combination */
        +		memset(secrets, 0, num_points * sizeof(felem_bytearray));
        +		memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
        +		for (i = 0; i < num_points; ++i)
        +			{
        +			if (i == num)
        +				/* we didn't have a valid precomputation, so we pick
        +				 * the generator */
        +				{
        +				p = EC_GROUP_get0_generator(group);
        +				p_scalar = scalar;
        +				}
        +			else
        +				/* the i^th point */
        +				{
        +				p = points[i];
        +				p_scalar = scalars[i];
        +				}
        +			if ((p_scalar != NULL) && (p != NULL))
        +				{
        +				/* reduce scalar to 0 <= scalar < 2^256 */
        +				if ((BN_num_bits(p_scalar) > 256) || (BN_is_negative(p_scalar)))
        +					{
        +					/* this is an unusual input, and we don't guarantee
        +					 * constant-timeness */
        +					if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
        +						{
        +						ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
        +						goto err;
        +						}
        +					num_bytes = BN_bn2bin(tmp_scalar, tmp);
        +					}
        +				else
        +					num_bytes = BN_bn2bin(p_scalar, tmp);
        +				flip_endian(secrets[i], tmp, num_bytes);
        +				/* precompute multiples */
        +				if ((!BN_to_felem(x_out, &p->X)) ||
        +					(!BN_to_felem(y_out, &p->Y)) ||
        +					(!BN_to_felem(z_out, &p->Z))) goto err;
        +				felem_shrink(pre_comp[i][1][0], x_out);
        +				felem_shrink(pre_comp[i][1][1], y_out);
        +				felem_shrink(pre_comp[i][1][2], z_out);
        +				for (j = 2; j <= 16; ++j)
        +					{
        +					if (j & 1)
        +						{
        +						point_add_small(
        +							pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
        +							pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
        +							pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
        +						}
        +					else
        +						{
        +						point_double_small(
        +							pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
        +							pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
        +						}
        +					}
        +				}
        +			}
        +		if (mixed)
        +			make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
        +		}
        +
        +	/* the scalar for the generator */
        +	if ((scalar != NULL) && (have_pre_comp))
        +		{
        +		memset(g_secret, 0, sizeof(g_secret));
        +		/* reduce scalar to 0 <= scalar < 2^256 */
        +		if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar)))
        +			{
        +			/* this is an unusual input, and we don't guarantee
        +			 * constant-timeness */
        +			if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
        +				{
        +				ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
        +				goto err;
        +				}
        +			num_bytes = BN_bn2bin(tmp_scalar, tmp);
        +			}
        +		else
        +			num_bytes = BN_bn2bin(scalar, tmp);
        +		flip_endian(g_secret, tmp, num_bytes);
        +		/* do the multiplication with generator precomputation*/
        +		batch_mul(x_out, y_out, z_out,
        +			(const felem_bytearray (*)) secrets, num_points,
        +			g_secret,
        +			mixed, (const smallfelem (*)[17][3]) pre_comp,
        +			g_pre_comp);
        +		}
        +	else
        +		/* do the multiplication without generator precomputation */
        +		batch_mul(x_out, y_out, z_out,
        +			(const felem_bytearray (*)) secrets, num_points,
        +			NULL, mixed, (const smallfelem (*)[17][3]) pre_comp, NULL);
        +	/* reduce the output to its unique minimal representation */
        +	felem_contract(x_in, x_out);
        +	felem_contract(y_in, y_out);
        +	felem_contract(z_in, z_out);
        +	if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
        +		(!smallfelem_to_BN(z, z_in)))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	if (generator != NULL)
        +		EC_POINT_free(generator);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (secrets != NULL)
        +		OPENSSL_free(secrets);
        +	if (pre_comp != NULL)
        +		OPENSSL_free(pre_comp);
        +	if (tmp_smallfelems != NULL)
        +		OPENSSL_free(tmp_smallfelems);
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	NISTP256_PRE_COMP *pre = NULL;
        +	int i, j;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y;
        +	EC_POINT *generator = NULL;
        +	smallfelem tmp_smallfelems[32];
        +	felem x_tmp, y_tmp, z_tmp;
        +
        +	/* throw away old precomputation */
        +	EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup,
        +		nistp256_pre_comp_free, nistp256_pre_comp_clear_free);
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((x = BN_CTX_get(ctx)) == NULL) ||
        +		((y = BN_CTX_get(ctx)) == NULL))
        +		goto err;
        +	/* get the generator */
        +	if (group->generator == NULL) goto err;
        +	generator = EC_POINT_new(group);
        +	if (generator == NULL)
        +		goto err;
        +	BN_bin2bn(nistp256_curve_params[3], sizeof (felem_bytearray), x);
        +	BN_bin2bn(nistp256_curve_params[4], sizeof (felem_bytearray), y);
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
        +		goto err;
        +	if ((pre = nistp256_pre_comp_new()) == NULL)
        +		goto err;
        +	/* if the generator is the standard one, use built-in precomputation */
        +	if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
        +		{
        +		memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
        +		ret = 1;
        +		goto err;
        +		}
        +	if ((!BN_to_felem(x_tmp, &group->generator->X)) ||
        +		(!BN_to_felem(y_tmp, &group->generator->Y)) ||
        +		(!BN_to_felem(z_tmp, &group->generator->Z)))
        +		goto err;
        +	felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
        +	felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
        +	felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
        +	/* compute 2^64*G, 2^128*G, 2^192*G for the first table,
        +	 * 2^32*G, 2^96*G, 2^160*G, 2^224*G for the second one
        +	 */
        +	for (i = 1; i <= 8; i <<= 1)
        +		{
        +		point_double_small(
        +			pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
        +			pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
        +		for (j = 0; j < 31; ++j)
        +			{
        +			point_double_small(
        +				pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
        +				pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
        +			}
        +		if (i == 8)
        +			break;
        +		point_double_small(
        +			pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
        +			pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
        +		for (j = 0; j < 31; ++j)
        +			{
        +			point_double_small(
        +				pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
        +				pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2]);
        +			}
        +		}
        +	for (i = 0; i < 2; i++)
        +		{
        +		/* g_pre_comp[i][0] is the point at infinity */
        +		memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
        +		/* the remaining multiples */
        +		/* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
        +		point_add_small(
        +			pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], pre->g_pre_comp[i][6][2],
        +			pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
        +			pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
        +		/* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
        +		point_add_small(
        +			pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], pre->g_pre_comp[i][10][2],
        +			pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
        +			pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
        +		/* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
        +		point_add_small(
        +			pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
        +			pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
        +			pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2]);
        +		/* 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G */
        +		point_add_small(
        +			pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], pre->g_pre_comp[i][14][2],
        +			pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
        +			pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
        +		for (j = 1; j < 8; ++j)
        +			{
        +			/* odd multiples: add G resp. 2^32*G */
        +			point_add_small(
        +				pre->g_pre_comp[i][2*j+1][0], pre->g_pre_comp[i][2*j+1][1], pre->g_pre_comp[i][2*j+1][2],
        +				pre->g_pre_comp[i][2*j][0], pre->g_pre_comp[i][2*j][1], pre->g_pre_comp[i][2*j][2],
        +				pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], pre->g_pre_comp[i][1][2]);
        +			}
        +		}
        +	make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
        +
        +	if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup,
        +			nistp256_pre_comp_free, nistp256_pre_comp_clear_free))
        +		goto err;
        +	ret = 1;
        +	pre = NULL;
        + err:
        +	BN_CTX_end(ctx);
        +	if (generator != NULL)
        +		EC_POINT_free(generator);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (pre)
        +		nistp256_pre_comp_free(pre);
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
        +	{
        +	if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup,
        +			nistp256_pre_comp_free, nistp256_pre_comp_clear_free)
        +		!= NULL)
        +		return 1;
        +	else
        +		return 0;
        +	}
        +#else
        +static void *dummy=&dummy;
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_nistp521.c b/vendor/openssl/openssl/crypto/ec/ecp_nistp521.c
        new file mode 100644
        index 000000000..178b655f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_nistp521.c
        @@ -0,0 +1,2025 @@
        +/* crypto/ec/ecp_nistp521.c */
        +/*
        + * Written by Adam Langley (Google) for the OpenSSL project
        + */
        +/* Copyright 2011 Google Inc.
        + *
        + * Licensed under the Apache License, Version 2.0 (the "License");
        + *
        + * you may not use this file except in compliance with the License.
        + * You may obtain a copy of the License at
        + *
        + *     http://www.apache.org/licenses/LICENSE-2.0
        + *
        + *  Unless required by applicable law or agreed to in writing, software
        + *  distributed under the License is distributed on an "AS IS" BASIS,
        + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        + *  See the License for the specific language governing permissions and
        + *  limitations under the License.
        + */
        +
        +/*
        + * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
        + *
        + * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
        + * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
        + * work which got its smarts from Daniel J. Bernstein's work on the same.
        + */
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +
        +#ifndef OPENSSL_SYS_VMS
        +#include <stdint.h>
        +#else
        +#include <inttypes.h>
        +#endif
        +
        +#include <string.h>
        +#include <openssl/err.h>
        +#include "ec_lcl.h"
        +
        +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
        +  /* even with gcc, the typedef won't work for 32-bit platforms */
        +  typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
        +#else
        +  #error "Need GCC 3.1 or later to define type uint128_t"
        +#endif
        +
        +typedef uint8_t u8;
        +typedef uint64_t u64;
        +typedef int64_t s64;
        +
        +/* The underlying field.
        + *
        + * P521 operates over GF(2^521-1). We can serialise an element of this field
        + * into 66 bytes where the most significant byte contains only a single bit. We
        + * call this an felem_bytearray. */
        +
        +typedef u8 felem_bytearray[66];
        +
        +/* These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
        + * These values are big-endian. */
        +static const felem_bytearray nistp521_curve_params[5] =
        +	{
        +	{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  /* p */
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff},
        +	{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  /* a = -3 */
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        +	 0xff, 0xfc},
        +	{0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,  /* b */
        +	 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
        +	 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
        +	 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
        +	 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
        +	 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
        +	 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
        +	 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
        +	 0x3f, 0x00},
        +	{0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,  /* x */
        +	 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
        +	 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
        +	 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
        +	 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
        +	 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
        +	 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
        +	 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
        +	 0xbd, 0x66},
        +	{0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,  /* y */
        +	 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
        +	 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
        +	 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
        +	 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
        +	 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
        +	 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
        +	 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
        +	 0x66, 0x50}
        +	};
        +
        +/* The representation of field elements.
        + * ------------------------------------
        + *
        + * We represent field elements with nine values. These values are either 64 or
        + * 128 bits and the field element represented is:
        + *   v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464  (mod p)
        + * Each of the nine values is called a 'limb'. Since the limbs are spaced only
        + * 58 bits apart, but are greater than 58 bits in length, the most significant
        + * bits of each limb overlap with the least significant bits of the next.
        + *
        + * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
        + * 'largefelem' */
        +
        +#define NLIMBS 9
        +
        +typedef uint64_t limb;
        +typedef limb felem[NLIMBS];
        +typedef uint128_t largefelem[NLIMBS];
        +
        +static const limb bottom57bits = 0x1ffffffffffffff;
        +static const limb bottom58bits = 0x3ffffffffffffff;
        +
        +/* bin66_to_felem takes a little-endian byte array and converts it into felem
        + * form. This assumes that the CPU is little-endian. */
        +static void bin66_to_felem(felem out, const u8 in[66])
        +	{
        +	out[0] = (*((limb*) &in[0])) & bottom58bits;
        +	out[1] = (*((limb*) &in[7]) >> 2) & bottom58bits;
        +	out[2] = (*((limb*) &in[14]) >> 4) & bottom58bits;
        +	out[3] = (*((limb*) &in[21]) >> 6) & bottom58bits;
        +	out[4] = (*((limb*) &in[29])) & bottom58bits;
        +	out[5] = (*((limb*) &in[36]) >> 2) & bottom58bits;
        +	out[6] = (*((limb*) &in[43]) >> 4) & bottom58bits;
        +	out[7] = (*((limb*) &in[50]) >> 6) & bottom58bits;
        +	out[8] = (*((limb*) &in[58])) & bottom57bits;
        +	}
        +
        +/* felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
        + * array. This assumes that the CPU is little-endian. */
        +static void felem_to_bin66(u8 out[66], const felem in)
        +	{
        +	memset(out, 0, 66);
        +	(*((limb*) &out[0])) = in[0];
        +	(*((limb*) &out[7])) |= in[1] << 2;
        +	(*((limb*) &out[14])) |= in[2] << 4;
        +	(*((limb*) &out[21])) |= in[3] << 6;
        +	(*((limb*) &out[29])) = in[4];
        +	(*((limb*) &out[36])) |= in[5] << 2;
        +	(*((limb*) &out[43])) |= in[6] << 4;
        +	(*((limb*) &out[50])) |= in[7] << 6;
        +	(*((limb*) &out[58])) = in[8];
        +	}
        +
        +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
        +static void flip_endian(u8 *out, const u8 *in, unsigned len)
        +	{
        +	unsigned i;
        +	for (i = 0; i < len; ++i)
        +		out[i] = in[len-1-i];
        +	}
        +
        +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
        +static int BN_to_felem(felem out, const BIGNUM *bn)
        +	{
        +	felem_bytearray b_in;
        +	felem_bytearray b_out;
        +	unsigned num_bytes;
        +
        +	/* BN_bn2bin eats leading zeroes */
        +	memset(b_out, 0, sizeof b_out);
        +	num_bytes = BN_num_bytes(bn);
        +	if (num_bytes > sizeof b_out)
        +		{
        +		ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
        +		return 0;
        +		}
        +	if (BN_is_negative(bn))
        +		{
        +		ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
        +		return 0;
        +		}
        +	num_bytes = BN_bn2bin(bn, b_in);
        +	flip_endian(b_out, b_in, num_bytes);
        +	bin66_to_felem(out, b_out);
        +	return 1;
        +	}
        +
        +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
        +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
        +	{
        +	felem_bytearray b_in, b_out;
        +	felem_to_bin66(b_in, in);
        +	flip_endian(b_out, b_in, sizeof b_out);
        +	return BN_bin2bn(b_out, sizeof b_out, out);
        +	}
        +
        +
        +/* Field operations
        + * ---------------- */
        +
        +static void felem_one(felem out)
        +	{
        +	out[0] = 1;
        +	out[1] = 0;
        +	out[2] = 0;
        +	out[3] = 0;
        +	out[4] = 0;
        +	out[5] = 0;
        +	out[6] = 0;
        +	out[7] = 0;
        +	out[8] = 0;
        +	}
        +
        +static void felem_assign(felem out, const felem in)
        +	{
        +	out[0] = in[0];
        +	out[1] = in[1];
        +	out[2] = in[2];
        +	out[3] = in[3];
        +	out[4] = in[4];
        +	out[5] = in[5];
        +	out[6] = in[6];
        +	out[7] = in[7];
        +	out[8] = in[8];
        +	}
        +
        +/* felem_sum64 sets out = out + in. */
        +static void felem_sum64(felem out, const felem in)
        +	{
        +	out[0] += in[0];
        +	out[1] += in[1];
        +	out[2] += in[2];
        +	out[3] += in[3];
        +	out[4] += in[4];
        +	out[5] += in[5];
        +	out[6] += in[6];
        +	out[7] += in[7];
        +	out[8] += in[8];
        +	}
        +
        +/* felem_scalar sets out = in * scalar */
        +static void felem_scalar(felem out, const felem in, limb scalar)
        +	{
        +	out[0] = in[0] * scalar;
        +	out[1] = in[1] * scalar;
        +	out[2] = in[2] * scalar;
        +	out[3] = in[3] * scalar;
        +	out[4] = in[4] * scalar;
        +	out[5] = in[5] * scalar;
        +	out[6] = in[6] * scalar;
        +	out[7] = in[7] * scalar;
        +	out[8] = in[8] * scalar;
        +	}
        +
        +/* felem_scalar64 sets out = out * scalar */
        +static void felem_scalar64(felem out, limb scalar)
        +	{
        +	out[0] *= scalar;
        +	out[1] *= scalar;
        +	out[2] *= scalar;
        +	out[3] *= scalar;
        +	out[4] *= scalar;
        +	out[5] *= scalar;
        +	out[6] *= scalar;
        +	out[7] *= scalar;
        +	out[8] *= scalar;
        +	}
        +
        +/* felem_scalar128 sets out = out * scalar */
        +static void felem_scalar128(largefelem out, limb scalar)
        +	{
        +	out[0] *= scalar;
        +	out[1] *= scalar;
        +	out[2] *= scalar;
        +	out[3] *= scalar;
        +	out[4] *= scalar;
        +	out[5] *= scalar;
        +	out[6] *= scalar;
        +	out[7] *= scalar;
        +	out[8] *= scalar;
        +	}
        +
        +/* felem_neg sets |out| to |-in|
        + * On entry:
        + *   in[i] < 2^59 + 2^14
        + * On exit:
        + *   out[i] < 2^62
        + */
        +static void felem_neg(felem out, const felem in)
        +	{
        +	/* In order to prevent underflow, we subtract from 0 mod p. */
        +	static const limb two62m3 = (((limb)1) << 62) - (((limb)1) << 5);
        +	static const limb two62m2 = (((limb)1) << 62) - (((limb)1) << 4);
        +
        +	out[0] = two62m3 - in[0];
        +	out[1] = two62m2 - in[1];
        +	out[2] = two62m2 - in[2];
        +	out[3] = two62m2 - in[3];
        +	out[4] = two62m2 - in[4];
        +	out[5] = two62m2 - in[5];
        +	out[6] = two62m2 - in[6];
        +	out[7] = two62m2 - in[7];
        +	out[8] = two62m2 - in[8];
        +	}
        +
        +/* felem_diff64 subtracts |in| from |out|
        + * On entry:
        + *   in[i] < 2^59 + 2^14
        + * On exit:
        + *   out[i] < out[i] + 2^62
        + */
        +static void felem_diff64(felem out, const felem in)
        +	{
        +	/* In order to prevent underflow, we add 0 mod p before subtracting. */
        +	static const limb two62m3 = (((limb)1) << 62) - (((limb)1) << 5);
        +	static const limb two62m2 = (((limb)1) << 62) - (((limb)1) << 4);
        +
        +	out[0] += two62m3 - in[0];
        +	out[1] += two62m2 - in[1];
        +	out[2] += two62m2 - in[2];
        +	out[3] += two62m2 - in[3];
        +	out[4] += two62m2 - in[4];
        +	out[5] += two62m2 - in[5];
        +	out[6] += two62m2 - in[6];
        +	out[7] += two62m2 - in[7];
        +	out[8] += two62m2 - in[8];
        +	}
        +
        +/* felem_diff_128_64 subtracts |in| from |out|
        + * On entry:
        + *   in[i] < 2^62 + 2^17
        + * On exit:
        + *   out[i] < out[i] + 2^63
        + */
        +static void felem_diff_128_64(largefelem out, const felem in)
        +	{
        +	/* In order to prevent underflow, we add 0 mod p before subtracting. */
        +	static const limb two63m6 = (((limb)1) << 62) - (((limb)1) << 5);
        +	static const limb two63m5 = (((limb)1) << 62) - (((limb)1) << 4);
        +
        +	out[0] += two63m6 - in[0];
        +	out[1] += two63m5 - in[1];
        +	out[2] += two63m5 - in[2];
        +	out[3] += two63m5 - in[3];
        +	out[4] += two63m5 - in[4];
        +	out[5] += two63m5 - in[5];
        +	out[6] += two63m5 - in[6];
        +	out[7] += two63m5 - in[7];
        +	out[8] += two63m5 - in[8];
        +	}
        +
        +/* felem_diff_128_64 subtracts |in| from |out|
        + * On entry:
        + *   in[i] < 2^126
        + * On exit:
        + *   out[i] < out[i] + 2^127 - 2^69
        + */
        +static void felem_diff128(largefelem out, const largefelem in)
        +	{
        +	/* In order to prevent underflow, we add 0 mod p before subtracting. */
        +	static const uint128_t two127m70 = (((uint128_t)1) << 127) - (((uint128_t)1) << 70);
        +	static const uint128_t two127m69 = (((uint128_t)1) << 127) - (((uint128_t)1) << 69);
        +
        +	out[0] += (two127m70 - in[0]);
        +	out[1] += (two127m69 - in[1]);
        +	out[2] += (two127m69 - in[2]);
        +	out[3] += (two127m69 - in[3]);
        +	out[4] += (two127m69 - in[4]);
        +	out[5] += (two127m69 - in[5]);
        +	out[6] += (two127m69 - in[6]);
        +	out[7] += (two127m69 - in[7]);
        +	out[8] += (two127m69 - in[8]);
        +	}
        +
        +/* felem_square sets |out| = |in|^2
        + * On entry:
        + *   in[i] < 2^62
        + * On exit:
        + *   out[i] < 17 * max(in[i]) * max(in[i])
        + */
        +static void felem_square(largefelem out, const felem in)
        +	{
        +	felem inx2, inx4;
        +	felem_scalar(inx2, in, 2);
        +	felem_scalar(inx4, in, 4);
        +
        +	/* We have many cases were we want to do
        +	 *   in[x] * in[y] +
        +	 *   in[y] * in[x]
        +	 * This is obviously just
        +	 *   2 * in[x] * in[y]
        +	 * However, rather than do the doubling on the 128 bit result, we
        +	 * double one of the inputs to the multiplication by reading from
        +	 * |inx2| */
        +
        +	out[0] = ((uint128_t) in[0]) * in[0];
        +	out[1] = ((uint128_t) in[0]) * inx2[1];
        +	out[2] = ((uint128_t) in[0]) * inx2[2] +
        +		 ((uint128_t) in[1]) * in[1];
        +	out[3] = ((uint128_t) in[0]) * inx2[3] +
        +		 ((uint128_t) in[1]) * inx2[2];
        +	out[4] = ((uint128_t) in[0]) * inx2[4] +
        +		 ((uint128_t) in[1]) * inx2[3] +
        +		 ((uint128_t) in[2]) * in[2];
        +	out[5] = ((uint128_t) in[0]) * inx2[5] +
        +		 ((uint128_t) in[1]) * inx2[4] +
        +		 ((uint128_t) in[2]) * inx2[3];
        +	out[6] = ((uint128_t) in[0]) * inx2[6] +
        +		 ((uint128_t) in[1]) * inx2[5] +
        +		 ((uint128_t) in[2]) * inx2[4] +
        +		 ((uint128_t) in[3]) * in[3];
        +	out[7] = ((uint128_t) in[0]) * inx2[7] +
        +		 ((uint128_t) in[1]) * inx2[6] +
        +		 ((uint128_t) in[2]) * inx2[5] +
        +		 ((uint128_t) in[3]) * inx2[4];
        +	out[8] = ((uint128_t) in[0]) * inx2[8] +
        +		 ((uint128_t) in[1]) * inx2[7] +
        +		 ((uint128_t) in[2]) * inx2[6] +
        +		 ((uint128_t) in[3]) * inx2[5] +
        +		 ((uint128_t) in[4]) * in[4];
        +
        +	/* The remaining limbs fall above 2^521, with the first falling at
        +	 * 2^522. They correspond to locations one bit up from the limbs
        +	 * produced above so we would have to multiply by two to align them.
        +	 * Again, rather than operate on the 128-bit result, we double one of
        +	 * the inputs to the multiplication. If we want to double for both this
        +	 * reason, and the reason above, then we end up multiplying by four. */
        +
        +	/* 9 */
        +	out[0] += ((uint128_t) in[1]) * inx4[8] +
        +		  ((uint128_t) in[2]) * inx4[7] +
        +		  ((uint128_t) in[3]) * inx4[6] +
        +		  ((uint128_t) in[4]) * inx4[5];
        +
        +	/* 10 */
        +	out[1] += ((uint128_t) in[2]) * inx4[8] +
        +		  ((uint128_t) in[3]) * inx4[7] +
        +		  ((uint128_t) in[4]) * inx4[6] +
        +		  ((uint128_t) in[5]) * inx2[5];
        +
        +	/* 11 */
        +	out[2] += ((uint128_t) in[3]) * inx4[8] +
        +		  ((uint128_t) in[4]) * inx4[7] +
        +		  ((uint128_t) in[5]) * inx4[6];
        +
        +	/* 12 */
        +	out[3] += ((uint128_t) in[4]) * inx4[8] +
        +		  ((uint128_t) in[5]) * inx4[7] +
        +		  ((uint128_t) in[6]) * inx2[6];
        +
        +	/* 13 */
        +	out[4] += ((uint128_t) in[5]) * inx4[8] +
        +		  ((uint128_t) in[6]) * inx4[7];
        +
        +	/* 14 */
        +	out[5] += ((uint128_t) in[6]) * inx4[8] +
        +		  ((uint128_t) in[7]) * inx2[7];
        +
        +	/* 15 */
        +	out[6] += ((uint128_t) in[7]) * inx4[8];
        +
        +	/* 16 */
        +	out[7] += ((uint128_t) in[8]) * inx2[8];
        +	}
        +
        +/* felem_mul sets |out| = |in1| * |in2|
        + * On entry:
        + *   in1[i] < 2^64
        + *   in2[i] < 2^63
        + * On exit:
        + *   out[i] < 17 * max(in1[i]) * max(in2[i])
        + */
        +static void felem_mul(largefelem out, const felem in1, const felem in2)
        +	{
        +	felem in2x2;
        +	felem_scalar(in2x2, in2, 2);
        +
        +	out[0] = ((uint128_t) in1[0]) * in2[0];
        +
        +	out[1] = ((uint128_t) in1[0]) * in2[1] +
        +	         ((uint128_t) in1[1]) * in2[0];
        +
        +	out[2] = ((uint128_t) in1[0]) * in2[2] +
        +		 ((uint128_t) in1[1]) * in2[1] +
        +	         ((uint128_t) in1[2]) * in2[0];
        +
        +	out[3] = ((uint128_t) in1[0]) * in2[3] +
        +		 ((uint128_t) in1[1]) * in2[2] +
        +		 ((uint128_t) in1[2]) * in2[1] +
        +		 ((uint128_t) in1[3]) * in2[0];
        +
        +	out[4] = ((uint128_t) in1[0]) * in2[4] +
        +		 ((uint128_t) in1[1]) * in2[3] +
        +		 ((uint128_t) in1[2]) * in2[2] +
        +		 ((uint128_t) in1[3]) * in2[1] +
        +		 ((uint128_t) in1[4]) * in2[0];
        +
        +	out[5] = ((uint128_t) in1[0]) * in2[5] +
        +		 ((uint128_t) in1[1]) * in2[4] +
        +		 ((uint128_t) in1[2]) * in2[3] +
        +		 ((uint128_t) in1[3]) * in2[2] +
        +		 ((uint128_t) in1[4]) * in2[1] +
        +		 ((uint128_t) in1[5]) * in2[0];
        +
        +	out[6] = ((uint128_t) in1[0]) * in2[6] +
        +		 ((uint128_t) in1[1]) * in2[5] +
        +		 ((uint128_t) in1[2]) * in2[4] +
        +		 ((uint128_t) in1[3]) * in2[3] +
        +		 ((uint128_t) in1[4]) * in2[2] +
        +		 ((uint128_t) in1[5]) * in2[1] +
        +		 ((uint128_t) in1[6]) * in2[0];
        +
        +	out[7] = ((uint128_t) in1[0]) * in2[7] +
        +		 ((uint128_t) in1[1]) * in2[6] +
        +		 ((uint128_t) in1[2]) * in2[5] +
        +		 ((uint128_t) in1[3]) * in2[4] +
        +		 ((uint128_t) in1[4]) * in2[3] +
        +		 ((uint128_t) in1[5]) * in2[2] +
        +		 ((uint128_t) in1[6]) * in2[1] +
        +		 ((uint128_t) in1[7]) * in2[0];
        +
        +	out[8] = ((uint128_t) in1[0]) * in2[8] +
        +		 ((uint128_t) in1[1]) * in2[7] +
        +		 ((uint128_t) in1[2]) * in2[6] +
        +		 ((uint128_t) in1[3]) * in2[5] +
        +		 ((uint128_t) in1[4]) * in2[4] +
        +		 ((uint128_t) in1[5]) * in2[3] +
        +		 ((uint128_t) in1[6]) * in2[2] +
        +		 ((uint128_t) in1[7]) * in2[1] +
        +		 ((uint128_t) in1[8]) * in2[0];
        +
        +	/* See comment in felem_square about the use of in2x2 here */
        +
        +	out[0] += ((uint128_t) in1[1]) * in2x2[8] +
        +		  ((uint128_t) in1[2]) * in2x2[7] +
        +		  ((uint128_t) in1[3]) * in2x2[6] +
        +		  ((uint128_t) in1[4]) * in2x2[5] +
        +		  ((uint128_t) in1[5]) * in2x2[4] +
        +		  ((uint128_t) in1[6]) * in2x2[3] +
        +		  ((uint128_t) in1[7]) * in2x2[2] +
        +		  ((uint128_t) in1[8]) * in2x2[1];
        +
        +	out[1] += ((uint128_t) in1[2]) * in2x2[8] +
        +		  ((uint128_t) in1[3]) * in2x2[7] +
        +		  ((uint128_t) in1[4]) * in2x2[6] +
        +		  ((uint128_t) in1[5]) * in2x2[5] +
        +		  ((uint128_t) in1[6]) * in2x2[4] +
        +		  ((uint128_t) in1[7]) * in2x2[3] +
        +		  ((uint128_t) in1[8]) * in2x2[2];
        +
        +	out[2] += ((uint128_t) in1[3]) * in2x2[8] +
        +		  ((uint128_t) in1[4]) * in2x2[7] +
        +		  ((uint128_t) in1[5]) * in2x2[6] +
        +		  ((uint128_t) in1[6]) * in2x2[5] +
        +		  ((uint128_t) in1[7]) * in2x2[4] +
        +		  ((uint128_t) in1[8]) * in2x2[3];
        +
        +	out[3] += ((uint128_t) in1[4]) * in2x2[8] +
        +		  ((uint128_t) in1[5]) * in2x2[7] +
        +		  ((uint128_t) in1[6]) * in2x2[6] +
        +		  ((uint128_t) in1[7]) * in2x2[5] +
        +		  ((uint128_t) in1[8]) * in2x2[4];
        +
        +	out[4] += ((uint128_t) in1[5]) * in2x2[8] +
        +		  ((uint128_t) in1[6]) * in2x2[7] +
        +		  ((uint128_t) in1[7]) * in2x2[6] +
        +		  ((uint128_t) in1[8]) * in2x2[5];
        +
        +	out[5] += ((uint128_t) in1[6]) * in2x2[8] +
        +		  ((uint128_t) in1[7]) * in2x2[7] +
        +		  ((uint128_t) in1[8]) * in2x2[6];
        +
        +	out[6] += ((uint128_t) in1[7]) * in2x2[8] +
        +		  ((uint128_t) in1[8]) * in2x2[7];
        +
        +	out[7] += ((uint128_t) in1[8]) * in2x2[8];
        +	}
        +
        +static const limb bottom52bits = 0xfffffffffffff;
        +
        +/* felem_reduce converts a largefelem to an felem.
        + * On entry:
        + *   in[i] < 2^128
        + * On exit:
        + *   out[i] < 2^59 + 2^14
        + */
        +static void felem_reduce(felem out, const largefelem in)
        +	{
        +	u64 overflow1, overflow2;
        +
        +	out[0] = ((limb) in[0]) & bottom58bits;
        +	out[1] = ((limb) in[1]) & bottom58bits;
        +	out[2] = ((limb) in[2]) & bottom58bits;
        +	out[3] = ((limb) in[3]) & bottom58bits;
        +	out[4] = ((limb) in[4]) & bottom58bits;
        +	out[5] = ((limb) in[5]) & bottom58bits;
        +	out[6] = ((limb) in[6]) & bottom58bits;
        +	out[7] = ((limb) in[7]) & bottom58bits;
        +	out[8] = ((limb) in[8]) & bottom58bits;
        +
        +	/* out[i] < 2^58 */
        +
        +	out[1] += ((limb) in[0]) >> 58;
        +	out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
        +	/* out[1] < 2^58 + 2^6 + 2^58
        +	 *        = 2^59 + 2^6 */
        +	out[2] += ((limb) (in[0] >> 64)) >> 52;
        +
        +	out[2] += ((limb) in[1]) >> 58;
        +	out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
        +	out[3] += ((limb) (in[1] >> 64)) >> 52;
        +
        +	out[3] += ((limb) in[2]) >> 58;
        +	out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
        +	out[4] += ((limb) (in[2] >> 64)) >> 52;
        +
        +	out[4] += ((limb) in[3]) >> 58;
        +	out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
        +	out[5] += ((limb) (in[3] >> 64)) >> 52;
        +
        +	out[5] += ((limb) in[4]) >> 58;
        +	out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
        +	out[6] += ((limb) (in[4] >> 64)) >> 52;
        +
        +	out[6] += ((limb) in[5]) >> 58;
        +	out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
        +	out[7] += ((limb) (in[5] >> 64)) >> 52;
        +
        +	out[7] += ((limb) in[6]) >> 58;
        +	out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
        +	out[8] += ((limb) (in[6] >> 64)) >> 52;
        +
        +	out[8] += ((limb) in[7]) >> 58;
        +	out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
        +	/* out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
        +	 *            < 2^59 + 2^13 */
        +	overflow1 = ((limb) (in[7] >> 64)) >> 52;
        +
        +	overflow1 += ((limb) in[8]) >> 58;
        +	overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
        +	overflow2 = ((limb) (in[8] >> 64)) >> 52;
        +
        +	overflow1 <<= 1;  /* overflow1 < 2^13 + 2^7 + 2^59 */
        +	overflow2 <<= 1;  /* overflow2 < 2^13 */
        +
        +	out[0] += overflow1;  /* out[0] < 2^60 */
        +	out[1] += overflow2;  /* out[1] < 2^59 + 2^6 + 2^13 */
        +
        +	out[1] += out[0] >> 58; out[0] &= bottom58bits;
        +	/* out[0] < 2^58
        +	 * out[1] < 2^59 + 2^6 + 2^13 + 2^2
        +	 *        < 2^59 + 2^14 */
        +	}
        +
        +static void felem_square_reduce(felem out, const felem in)
        +	{
        +	largefelem tmp;
        +	felem_square(tmp, in);
        +	felem_reduce(out, tmp);
        +	}
        +
        +static void felem_mul_reduce(felem out, const felem in1, const felem in2)
        +	{
        +	largefelem tmp;
        +	felem_mul(tmp, in1, in2);
        +	felem_reduce(out, tmp);
        +	}
        +
        +/* felem_inv calculates |out| = |in|^{-1}
        + *
        + * Based on Fermat's Little Theorem:
        + *   a^p = a (mod p)
        + *   a^{p-1} = 1 (mod p)
        + *   a^{p-2} = a^{-1} (mod p)
        + */
        +static void felem_inv(felem out, const felem in)
        +	{
        +	felem ftmp, ftmp2, ftmp3, ftmp4;
        +	largefelem tmp;
        +	unsigned i;
        +
        +	felem_square(tmp, in); felem_reduce(ftmp, tmp);		/* 2^1 */
        +	felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp);	/* 2^2 - 2^0 */
        +	felem_assign(ftmp2, ftmp);
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);	/* 2^3 - 2^1 */
        +	felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp);	/* 2^3 - 2^0 */
        +	felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);	/* 2^4 - 2^1 */
        +
        +	felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^3 - 2^1 */
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^4 - 2^2 */
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^4 - 2^0 */
        +
        +	felem_assign(ftmp2, ftmp3);
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^5 - 2^1 */
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^6 - 2^2 */
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^7 - 2^3 */
        +	felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^8 - 2^4 */
        +	felem_assign(ftmp4, ftmp3);
        +	felem_mul(tmp, ftmp3, ftmp); felem_reduce(ftmp4, tmp);	/* 2^8 - 2^1 */
        +	felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);	/* 2^9 - 2^2 */
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^8 - 2^0 */
        +	felem_assign(ftmp2, ftmp3);
        +
        +	for (i = 0; i < 8; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^16 - 2^8 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^16 - 2^0 */
        +	felem_assign(ftmp2, ftmp3);
        +
        +	for (i = 0; i < 16; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^32 - 2^16 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^32 - 2^0 */
        +	felem_assign(ftmp2, ftmp3);
        +
        +	for (i = 0; i < 32; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^64 - 2^32 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^64 - 2^0 */
        +	felem_assign(ftmp2, ftmp3);
        +
        +	for (i = 0; i < 64; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^128 - 2^64 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^128 - 2^0 */
        +	felem_assign(ftmp2, ftmp3);
        +
        +	for (i = 0; i < 128; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^256 - 2^128 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^256 - 2^0 */
        +	felem_assign(ftmp2, ftmp3);
        +
        +	for (i = 0; i < 256; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^512 - 2^256 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp);	/* 2^512 - 2^0 */
        +
        +	for (i = 0; i < 9; i++)
        +		{
        +		felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);	/* 2^521 - 2^9 */
        +		}
        +	felem_mul(tmp, ftmp3, ftmp4); felem_reduce(ftmp3, tmp);	/* 2^512 - 2^2 */
        +	felem_mul(tmp, ftmp3, in); felem_reduce(out, tmp);	/* 2^512 - 3 */
        +}
        +
        +/* This is 2^521-1, expressed as an felem */
        +static const felem kPrime =
        +	{
        +	0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
        +	0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
        +	0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
        +	};
        +
        +/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
        + * otherwise.
        + * On entry:
        + *   in[i] < 2^59 + 2^14
        + */
        +static limb felem_is_zero(const felem in)
        +	{
        +	felem ftmp;
        +	limb is_zero, is_p;
        +	felem_assign(ftmp, in);
        +
        +	ftmp[0] += ftmp[8] >> 57; ftmp[8] &= bottom57bits;
        +	/* ftmp[8] < 2^57 */
        +	ftmp[1] += ftmp[0] >> 58; ftmp[0] &= bottom58bits;
        +	ftmp[2] += ftmp[1] >> 58; ftmp[1] &= bottom58bits;
        +	ftmp[3] += ftmp[2] >> 58; ftmp[2] &= bottom58bits;
        +	ftmp[4] += ftmp[3] >> 58; ftmp[3] &= bottom58bits;
        +	ftmp[5] += ftmp[4] >> 58; ftmp[4] &= bottom58bits;
        +	ftmp[6] += ftmp[5] >> 58; ftmp[5] &= bottom58bits;
        +	ftmp[7] += ftmp[6] >> 58; ftmp[6] &= bottom58bits;
        +	ftmp[8] += ftmp[7] >> 58; ftmp[7] &= bottom58bits;
        +	/* ftmp[8] < 2^57 + 4 */
        +
        +	/* The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is
        +	 * greater than our bound for ftmp[8]. Therefore we only have to check
        +	 * if the zero is zero or 2^521-1. */
        +
        +	is_zero = 0;
        +	is_zero |= ftmp[0];
        +	is_zero |= ftmp[1];
        +	is_zero |= ftmp[2];
        +	is_zero |= ftmp[3];
        +	is_zero |= ftmp[4];
        +	is_zero |= ftmp[5];
        +	is_zero |= ftmp[6];
        +	is_zero |= ftmp[7];
        +	is_zero |= ftmp[8];
        +
        +	is_zero--;
        +	/* We know that ftmp[i] < 2^63, therefore the only way that the top bit
        +	 * can be set is if is_zero was 0 before the decrement. */
        +	is_zero = ((s64) is_zero) >> 63;
        +
        +	is_p = ftmp[0] ^ kPrime[0];
        +	is_p |= ftmp[1] ^ kPrime[1];
        +	is_p |= ftmp[2] ^ kPrime[2];
        +	is_p |= ftmp[3] ^ kPrime[3];
        +	is_p |= ftmp[4] ^ kPrime[4];
        +	is_p |= ftmp[5] ^ kPrime[5];
        +	is_p |= ftmp[6] ^ kPrime[6];
        +	is_p |= ftmp[7] ^ kPrime[7];
        +	is_p |= ftmp[8] ^ kPrime[8];
        +
        +	is_p--;
        +	is_p = ((s64) is_p) >> 63;
        +
        +	is_zero |= is_p;
        +	return is_zero;
        +	}
        +
        +static int felem_is_zero_int(const felem in)
        +	{
        +	return (int) (felem_is_zero(in) & ((limb)1));
        +	}
        +
        +/* felem_contract converts |in| to its unique, minimal representation.
        + * On entry:
        + *   in[i] < 2^59 + 2^14
        + */
        +static void felem_contract(felem out, const felem in)
        +	{
        +	limb is_p, is_greater, sign;
        +	static const limb two58 = ((limb)1) << 58;
        +
        +	felem_assign(out, in);
        +
        +	out[0] += out[8] >> 57; out[8] &= bottom57bits;
        +	/* out[8] < 2^57 */
        +	out[1] += out[0] >> 58; out[0] &= bottom58bits;
        +	out[2] += out[1] >> 58; out[1] &= bottom58bits;
        +	out[3] += out[2] >> 58; out[2] &= bottom58bits;
        +	out[4] += out[3] >> 58; out[3] &= bottom58bits;
        +	out[5] += out[4] >> 58; out[4] &= bottom58bits;
        +	out[6] += out[5] >> 58; out[5] &= bottom58bits;
        +	out[7] += out[6] >> 58; out[6] &= bottom58bits;
        +	out[8] += out[7] >> 58; out[7] &= bottom58bits;
        +	/* out[8] < 2^57 + 4 */
        +
        +	/* If the value is greater than 2^521-1 then we have to subtract
        +	 * 2^521-1 out. See the comments in felem_is_zero regarding why we
        +	 * don't test for other multiples of the prime. */
        +
        +	/* First, if |out| is equal to 2^521-1, we subtract it out to get zero. */
        +
        +	is_p = out[0] ^ kPrime[0];
        +	is_p |= out[1] ^ kPrime[1];
        +	is_p |= out[2] ^ kPrime[2];
        +	is_p |= out[3] ^ kPrime[3];
        +	is_p |= out[4] ^ kPrime[4];
        +	is_p |= out[5] ^ kPrime[5];
        +	is_p |= out[6] ^ kPrime[6];
        +	is_p |= out[7] ^ kPrime[7];
        +	is_p |= out[8] ^ kPrime[8];
        +
        +	is_p--;
        +	is_p &= is_p << 32;
        +	is_p &= is_p << 16;
        +	is_p &= is_p << 8;
        +	is_p &= is_p << 4;
        +	is_p &= is_p << 2;
        +	is_p &= is_p << 1;
        +	is_p = ((s64) is_p) >> 63;
        +	is_p = ~is_p;
        +
        +	/* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
        +
        +	out[0] &= is_p;
        +	out[1] &= is_p;
        +	out[2] &= is_p;
        +	out[3] &= is_p;
        +	out[4] &= is_p;
        +	out[5] &= is_p;
        +	out[6] &= is_p;
        +	out[7] &= is_p;
        +	out[8] &= is_p;
        +
        +	/* In order to test that |out| >= 2^521-1 we need only test if out[8]
        +	 * >> 57 is greater than zero as (2^521-1) + x >= 2^522 */
        +	is_greater = out[8] >> 57;
        +	is_greater |= is_greater << 32;
        +	is_greater |= is_greater << 16;
        +	is_greater |= is_greater << 8;
        +	is_greater |= is_greater << 4;
        +	is_greater |= is_greater << 2;
        +	is_greater |= is_greater << 1;
        +	is_greater = ((s64) is_greater) >> 63;
        +
        +	out[0] -= kPrime[0] & is_greater;
        +	out[1] -= kPrime[1] & is_greater;
        +	out[2] -= kPrime[2] & is_greater;
        +	out[3] -= kPrime[3] & is_greater;
        +	out[4] -= kPrime[4] & is_greater;
        +	out[5] -= kPrime[5] & is_greater;
        +	out[6] -= kPrime[6] & is_greater;
        +	out[7] -= kPrime[7] & is_greater;
        +	out[8] -= kPrime[8] & is_greater;
        +
        +	/* Eliminate negative coefficients */
        +	sign = -(out[0] >> 63); out[0] += (two58 & sign); out[1] -= (1 & sign);
        +	sign = -(out[1] >> 63); out[1] += (two58 & sign); out[2] -= (1 & sign);
        +	sign = -(out[2] >> 63); out[2] += (two58 & sign); out[3] -= (1 & sign);
        +	sign = -(out[3] >> 63); out[3] += (two58 & sign); out[4] -= (1 & sign);
        +	sign = -(out[4] >> 63); out[4] += (two58 & sign); out[5] -= (1 & sign);
        +	sign = -(out[0] >> 63); out[5] += (two58 & sign); out[6] -= (1 & sign);
        +	sign = -(out[6] >> 63); out[6] += (two58 & sign); out[7] -= (1 & sign);
        +	sign = -(out[7] >> 63); out[7] += (two58 & sign); out[8] -= (1 & sign);
        +	sign = -(out[5] >> 63); out[5] += (two58 & sign); out[6] -= (1 & sign);
        +	sign = -(out[6] >> 63); out[6] += (two58 & sign); out[7] -= (1 & sign);
        +	sign = -(out[7] >> 63); out[7] += (two58 & sign); out[8] -= (1 & sign);
        +	}
        +
        +/* Group operations
        + * ----------------
        + *
        + * Building on top of the field operations we have the operations on the
        + * elliptic curve group itself. Points on the curve are represented in Jacobian
        + * coordinates */
        +
        +/* point_double calcuates 2*(x_in, y_in, z_in)
        + *
        + * The method is taken from:
        + *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
        + *
        + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
        + * while x_out == y_in is not (maybe this works, but it's not tested). */
        +static void
        +point_double(felem x_out, felem y_out, felem z_out,
        +	     const felem x_in, const felem y_in, const felem z_in)
        +	{
        +	largefelem tmp, tmp2;
        +	felem delta, gamma, beta, alpha, ftmp, ftmp2;
        +
        +	felem_assign(ftmp, x_in);
        +	felem_assign(ftmp2, x_in);
        +
        +	/* delta = z^2 */
        +	felem_square(tmp, z_in);
        +	felem_reduce(delta, tmp);  /* delta[i] < 2^59 + 2^14 */
        +
        +	/* gamma = y^2 */
        +	felem_square(tmp, y_in);
        +	felem_reduce(gamma, tmp);  /* gamma[i] < 2^59 + 2^14 */
        +
        +	/* beta = x*gamma */
        +	felem_mul(tmp, x_in, gamma);
        +	felem_reduce(beta, tmp);  /* beta[i] < 2^59 + 2^14 */
        +
        +	/* alpha = 3*(x-delta)*(x+delta) */
        +	felem_diff64(ftmp, delta);
        +	/* ftmp[i] < 2^61 */
        +	felem_sum64(ftmp2, delta);
        +	/* ftmp2[i] < 2^60 + 2^15 */
        +	felem_scalar64(ftmp2, 3);
        +	/* ftmp2[i] < 3*2^60 + 3*2^15 */
        +	felem_mul(tmp, ftmp, ftmp2);
        +	/* tmp[i] < 17(3*2^121 + 3*2^76)
        +	 *        = 61*2^121 + 61*2^76
        +	 *        < 64*2^121 + 64*2^76
        +	 *        = 2^127 + 2^82
        +	 *        < 2^128 */
        +	felem_reduce(alpha, tmp);
        +
        +	/* x' = alpha^2 - 8*beta */
        +	felem_square(tmp, alpha);
        +	/* tmp[i] < 17*2^120
        +	 *        < 2^125 */
        +	felem_assign(ftmp, beta);
        +	felem_scalar64(ftmp, 8);
        +	/* ftmp[i] < 2^62 + 2^17 */
        +	felem_diff_128_64(tmp, ftmp);
        +	/* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
        +	felem_reduce(x_out, tmp);
        +
        +	/* z' = (y + z)^2 - gamma - delta */
        +	felem_sum64(delta, gamma);
        +	/* delta[i] < 2^60 + 2^15 */
        +	felem_assign(ftmp, y_in);
        +	felem_sum64(ftmp, z_in);
        +	/* ftmp[i] < 2^60 + 2^15 */
        +	felem_square(tmp, ftmp);
        +	/* tmp[i] < 17(2^122)
        +	 *        < 2^127 */
        +	felem_diff_128_64(tmp, delta);
        +	/* tmp[i] < 2^127 + 2^63 */
        +	felem_reduce(z_out, tmp);
        +
        +	/* y' = alpha*(4*beta - x') - 8*gamma^2 */
        +	felem_scalar64(beta, 4);
        +	/* beta[i] < 2^61 + 2^16 */
        +	felem_diff64(beta, x_out);
        +	/* beta[i] < 2^61 + 2^60 + 2^16 */
        +	felem_mul(tmp, alpha, beta);
        +	/* tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16))
        +	 *        = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30) 
        +	 *        = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
        +	 *        < 2^128 */
        +	felem_square(tmp2, gamma);
        +	/* tmp2[i] < 17*(2^59 + 2^14)^2
        +	 *         = 17*(2^118 + 2^74 + 2^28) */
        +	felem_scalar128(tmp2, 8);
        +	/* tmp2[i] < 8*17*(2^118 + 2^74 + 2^28)
        +	 *         = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31
        +	 *         < 2^126 */
        +	felem_diff128(tmp, tmp2);
        +	/* tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
        +	 *        = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 +
        +	 *          2^74 + 2^69 + 2^34 + 2^30
        +	 *        < 2^128 */
        +	felem_reduce(y_out, tmp);
        +	}
        +
        +/* copy_conditional copies in to out iff mask is all ones. */
        +static void
        +copy_conditional(felem out, const felem in, limb mask)
        +	{
        +	unsigned i;
        +	for (i = 0; i < NLIMBS; ++i)
        +		{
        +		const limb tmp = mask & (in[i] ^ out[i]);
        +		out[i] ^= tmp;
        +		}
        +	}
        +
        +/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
        + *
        + * The method is taken from
        + *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
        + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
        + *
        + * This function includes a branch for checking whether the two input points
        + * are equal (while not equal to the point at infinity). This case never
        + * happens during single point multiplication, so there is no timing leak for
        + * ECDH or ECDSA signing. */
        +static void point_add(felem x3, felem y3, felem z3,
        +	const felem x1, const felem y1, const felem z1,
        +	const int mixed, const felem x2, const felem y2, const felem z2)
        +	{
        +	felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
        +	largefelem tmp, tmp2;
        +	limb x_equal, y_equal, z1_is_zero, z2_is_zero;
        +
        +	z1_is_zero = felem_is_zero(z1);
        +	z2_is_zero = felem_is_zero(z2);
        +
        +	/* ftmp = z1z1 = z1**2 */
        +	felem_square(tmp, z1);
        +	felem_reduce(ftmp, tmp);
        +
        +	if (!mixed)
        +		{
        +		/* ftmp2 = z2z2 = z2**2 */
        +		felem_square(tmp, z2);
        +		felem_reduce(ftmp2, tmp);
        +
        +		/* u1 = ftmp3 = x1*z2z2 */
        +		felem_mul(tmp, x1, ftmp2);
        +		felem_reduce(ftmp3, tmp);
        +
        +		/* ftmp5 = z1 + z2 */
        +		felem_assign(ftmp5, z1);
        +		felem_sum64(ftmp5, z2);
        +		/* ftmp5[i] < 2^61 */
        +
        +		/* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
        +		felem_square(tmp, ftmp5);
        +		/* tmp[i] < 17*2^122 */
        +		felem_diff_128_64(tmp, ftmp);
        +		/* tmp[i] < 17*2^122 + 2^63 */
        +		felem_diff_128_64(tmp, ftmp2);
        +		/* tmp[i] < 17*2^122 + 2^64 */
        +		felem_reduce(ftmp5, tmp);
        +
        +		/* ftmp2 = z2 * z2z2 */
        +		felem_mul(tmp, ftmp2, z2);
        +		felem_reduce(ftmp2, tmp);
        +
        +		/* s1 = ftmp6 = y1 * z2**3 */
        +		felem_mul(tmp, y1, ftmp2);
        +		felem_reduce(ftmp6, tmp);
        +		}
        +	else
        +		{
        +		/* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
        +
        +		/* u1 = ftmp3 = x1*z2z2 */
        +		felem_assign(ftmp3, x1);
        +
        +		/* ftmp5 = 2*z1z2 */
        +		felem_scalar(ftmp5, z1, 2);
        +
        +		/* s1 = ftmp6 = y1 * z2**3 */
        +		felem_assign(ftmp6, y1);
        +		}
        +
        +	/* u2 = x2*z1z1 */
        +	felem_mul(tmp, x2, ftmp);
        +	/* tmp[i] < 17*2^120 */
        +
        +	/* h = ftmp4 = u2 - u1 */
        +	felem_diff_128_64(tmp, ftmp3);
        +	/* tmp[i] < 17*2^120 + 2^63 */
        +	felem_reduce(ftmp4, tmp);
        +
        +	x_equal = felem_is_zero(ftmp4);
        +
        +	/* z_out = ftmp5 * h */
        +	felem_mul(tmp, ftmp5, ftmp4);
        +	felem_reduce(z_out, tmp);
        +
        +	/* ftmp = z1 * z1z1 */
        +	felem_mul(tmp, ftmp, z1);
        +	felem_reduce(ftmp, tmp);
        +
        +	/* s2 = tmp = y2 * z1**3 */
        +	felem_mul(tmp, y2, ftmp);
        +	/* tmp[i] < 17*2^120 */
        +
        +	/* r = ftmp5 = (s2 - s1)*2 */
        +	felem_diff_128_64(tmp, ftmp6);
        +	/* tmp[i] < 17*2^120 + 2^63 */
        +	felem_reduce(ftmp5, tmp);
        +	y_equal = felem_is_zero(ftmp5);
        +	felem_scalar64(ftmp5, 2);
        +	/* ftmp5[i] < 2^61 */
        +
        +	if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
        +		{
        +		point_double(x3, y3, z3, x1, y1, z1);
        +		return;
        +		}
        +
        +	/* I = ftmp = (2h)**2 */
        +	felem_assign(ftmp, ftmp4);
        +	felem_scalar64(ftmp, 2);
        +	/* ftmp[i] < 2^61 */
        +	felem_square(tmp, ftmp);
        +	/* tmp[i] < 17*2^122 */
        +	felem_reduce(ftmp, tmp);
        +
        +	/* J = ftmp2 = h * I */
        +	felem_mul(tmp, ftmp4, ftmp);
        +	felem_reduce(ftmp2, tmp);
        +
        +	/* V = ftmp4 = U1 * I */
        +	felem_mul(tmp, ftmp3, ftmp);
        +	felem_reduce(ftmp4, tmp);
        +
        +	/* x_out = r**2 - J - 2V */
        +	felem_square(tmp, ftmp5);
        +	/* tmp[i] < 17*2^122 */
        +	felem_diff_128_64(tmp, ftmp2);
        +	/* tmp[i] < 17*2^122 + 2^63 */
        +	felem_assign(ftmp3, ftmp4);
        +	felem_scalar64(ftmp4, 2);
        +	/* ftmp4[i] < 2^61 */
        +	felem_diff_128_64(tmp, ftmp4);
        +	/* tmp[i] < 17*2^122 + 2^64 */
        +	felem_reduce(x_out, tmp);
        +
        +	/* y_out = r(V-x_out) - 2 * s1 * J */
        +	felem_diff64(ftmp3, x_out);
        +	/* ftmp3[i] < 2^60 + 2^60
        +	 *          = 2^61 */
        +	felem_mul(tmp, ftmp5, ftmp3);
        +	/* tmp[i] < 17*2^122 */
        +	felem_mul(tmp2, ftmp6, ftmp2);
        +	/* tmp2[i] < 17*2^120 */
        +	felem_scalar128(tmp2, 2);
        +	/* tmp2[i] < 17*2^121 */
        +	felem_diff128(tmp, tmp2);
        +	/* tmp[i] < 2^127 - 2^69 + 17*2^122
        +	 *        = 2^126 - 2^122 - 2^6 - 2^2 - 1
        +	 *        < 2^127 */
        +	felem_reduce(y_out, tmp);
        +
        +	copy_conditional(x_out, x2, z1_is_zero);
        +	copy_conditional(x_out, x1, z2_is_zero);
        +	copy_conditional(y_out, y2, z1_is_zero);
        +	copy_conditional(y_out, y1, z2_is_zero);
        +	copy_conditional(z_out, z2, z1_is_zero);
        +	copy_conditional(z_out, z1, z2_is_zero);
        +	felem_assign(x3, x_out);
        +	felem_assign(y3, y_out);
        +	felem_assign(z3, z_out);
        +	}
        +
        +/* Base point pre computation
        + * --------------------------
        + *
        + * Two different sorts of precomputed tables are used in the following code.
        + * Each contain various points on the curve, where each point is three field
        + * elements (x, y, z).
        + *
        + * For the base point table, z is usually 1 (0 for the point at infinity).
        + * This table has 16 elements:
        + * index | bits    | point
        + * ------+---------+------------------------------
        + *     0 | 0 0 0 0 | 0G
        + *     1 | 0 0 0 1 | 1G
        + *     2 | 0 0 1 0 | 2^130G
        + *     3 | 0 0 1 1 | (2^130 + 1)G
        + *     4 | 0 1 0 0 | 2^260G
        + *     5 | 0 1 0 1 | (2^260 + 1)G
        + *     6 | 0 1 1 0 | (2^260 + 2^130)G
        + *     7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
        + *     8 | 1 0 0 0 | 2^390G
        + *     9 | 1 0 0 1 | (2^390 + 1)G
        + *    10 | 1 0 1 0 | (2^390 + 2^130)G
        + *    11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
        + *    12 | 1 1 0 0 | (2^390 + 2^260)G
        + *    13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
        + *    14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
        + *    15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
        + *
        + * The reason for this is so that we can clock bits into four different
        + * locations when doing simple scalar multiplies against the base point.
        + *
        + * Tables for other points have table[i] = iG for i in 0 .. 16. */
        +
        +/* gmul is the table of precomputed base points */
        +static const felem gmul[16][3] =
        +	{{{0, 0, 0, 0, 0, 0, 0, 0, 0},
        +	  {0, 0, 0, 0, 0, 0, 0, 0, 0},
        +	  {0, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
        +	   0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
        +	   0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
        +	  {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
        +	   0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
        +	   0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
        +	   0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
        +	   0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
        +	  {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
        +	   0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
        +	   0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
        +	   0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
        +	   0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
        +	  {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
        +	   0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
        +	   0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
        +	   0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
        +	   0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
        +	  {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
        +	   0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
        +	   0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
        +	   0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
        +	   0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
        +	  {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
        +	   0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
        +	   0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
        +	   0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
        +	   0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
        +	  {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
        +	   0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
        +	   0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
        +	   0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
        +	   0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
        +	  {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
        +	   0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
        +	   0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
        +	   0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
        +	   0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
        +	  {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
        +	   0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
        +	   0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
        +	   0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
        +	   0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
        +	  {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
        +	   0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
        +	   0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
        +	   0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
        +	   0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
        +	  {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
        +	   0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
        +	   0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
        +	   0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
        +	   0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
        +	  {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
        +	   0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
        +	   0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
        +	   0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
        +	   0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
        +	  {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
        +	   0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
        +	   0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
        +	   0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
        +	   0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
        +	  {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
        +	   0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
        +	   0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
        +	   0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
        +	   0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
        +	  {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
        +	   0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
        +	   0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
        +	  {1, 0, 0, 0, 0, 0, 0, 0, 0}},
        +	 {{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
        +	   0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
        +	   0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
        +	  {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
        +	   0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
        +	   0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
        +	 {1, 0, 0, 0, 0, 0, 0, 0, 0}}};
        +
        +/* select_point selects the |idx|th point from a precomputation table and
        + * copies it to out. */
        +static void select_point(const limb idx, unsigned int size, const felem pre_comp[/* size */][3],
        +			 felem out[3])
        +	{
        +	unsigned i, j;
        +	limb *outlimbs = &out[0][0];
        +	memset(outlimbs, 0, 3 * sizeof(felem));
        +
        +	for (i = 0; i < size; i++)
        +		{
        +		const limb *inlimbs = &pre_comp[i][0][0];
        +		limb mask = i ^ idx;
        +		mask |= mask >> 4;
        +		mask |= mask >> 2;
        +		mask |= mask >> 1;
        +		mask &= 1;
        +		mask--;
        +		for (j = 0; j < NLIMBS * 3; j++)
        +			outlimbs[j] |= inlimbs[j] & mask;
        +		}
        +	}
        +
        +/* get_bit returns the |i|th bit in |in| */
        +static char get_bit(const felem_bytearray in, int i)
        +	{
        +	if (i < 0)
        +		return 0;
        +	return (in[i >> 3] >> (i & 7)) & 1;
        +	}
        +
        +/* Interleaved point multiplication using precomputed point multiples:
        + * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
        + * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
        + * of the generator, using certain (large) precomputed multiples in g_pre_comp.
        + * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
        +static void batch_mul(felem x_out, felem y_out, felem z_out,
        +	const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
        +	const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[16][3])
        +	{
        +	int i, skip;
        +	unsigned num, gen_mul = (g_scalar != NULL);
        +	felem nq[3], tmp[4];
        +	limb bits;
        +	u8 sign, digit;
        +
        +	/* set nq to the point at infinity */
        +	memset(nq, 0, 3 * sizeof(felem));
        +
        +	/* Loop over all scalars msb-to-lsb, interleaving additions
        +	 * of multiples of the generator (last quarter of rounds)
        +	 * and additions of other points multiples (every 5th round).
        +	 */
        +	skip = 1; /* save two point operations in the first round */
        +	for (i = (num_points ? 520 : 130); i >= 0; --i)
        +		{
        +		/* double */
        +		if (!skip)
        +			point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
        +
        +		/* add multiples of the generator */
        +		if (gen_mul && (i <= 130))
        +			{
        +			bits = get_bit(g_scalar, i + 390) << 3;
        +			if (i < 130)
        +				{
        +				bits |= get_bit(g_scalar, i + 260) << 2;
        +				bits |= get_bit(g_scalar, i + 130) << 1;
        +				bits |= get_bit(g_scalar, i);
        +				}
        +			/* select the point to add, in constant time */
        +			select_point(bits, 16, g_pre_comp, tmp);
        +			if (!skip)
        +				{
        +				point_add(nq[0], nq[1], nq[2],
        +					nq[0], nq[1], nq[2],
        +					1 /* mixed */, tmp[0], tmp[1], tmp[2]);
        +				}
        +			else
        +				{
        +				memcpy(nq, tmp, 3 * sizeof(felem));
        +				skip = 0;
        +				}
        +			}
        +
        +		/* do other additions every 5 doublings */
        +		if (num_points && (i % 5 == 0))
        +			{
        +			/* loop over all scalars */
        +			for (num = 0; num < num_points; ++num)
        +				{
        +				bits = get_bit(scalars[num], i + 4) << 5;
        +				bits |= get_bit(scalars[num], i + 3) << 4;
        +				bits |= get_bit(scalars[num], i + 2) << 3;
        +				bits |= get_bit(scalars[num], i + 1) << 2;
        +				bits |= get_bit(scalars[num], i) << 1;
        +				bits |= get_bit(scalars[num], i - 1);
        +				ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
        +
        +				/* select the point to add or subtract, in constant time */
        +				select_point(digit, 17, pre_comp[num], tmp);
        +				felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
        +				copy_conditional(tmp[1], tmp[3], (-(limb) sign));
        +
        +				if (!skip)
        +					{
        +					point_add(nq[0], nq[1], nq[2],
        +						nq[0], nq[1], nq[2],
        +						mixed, tmp[0], tmp[1], tmp[2]);
        +					}
        +				else
        +					{
        +					memcpy(nq, tmp, 3 * sizeof(felem));
        +					skip = 0;
        +					}
        +				}
        +			}
        +		}
        +	felem_assign(x_out, nq[0]);
        +	felem_assign(y_out, nq[1]);
        +	felem_assign(z_out, nq[2]);
        +	}
        +
        +
        +/* Precomputation for the group generator. */
        +typedef struct {
        +	felem g_pre_comp[16][3];
        +	int references;
        +} NISTP521_PRE_COMP;
        +
        +const EC_METHOD *EC_GFp_nistp521_method(void)
        +	{
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_prime_field,
        +		ec_GFp_nistp521_group_init,
        +		ec_GFp_simple_group_finish,
        +		ec_GFp_simple_group_clear_finish,
        +		ec_GFp_nist_group_copy,
        +		ec_GFp_nistp521_group_set_curve,
        +		ec_GFp_simple_group_get_curve,
        +		ec_GFp_simple_group_get_degree,
        +		ec_GFp_simple_group_check_discriminant,
        +		ec_GFp_simple_point_init,
        +		ec_GFp_simple_point_finish,
        +		ec_GFp_simple_point_clear_finish,
        +		ec_GFp_simple_point_copy,
        +		ec_GFp_simple_point_set_to_infinity,
        +		ec_GFp_simple_set_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_get_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_point_set_affine_coordinates,
        +		ec_GFp_nistp521_point_get_affine_coordinates,
        +		0 /* point_set_compressed_coordinates */,
        +		0 /* point2oct */,
        +		0 /* oct2point */,
        +		ec_GFp_simple_add,
        +		ec_GFp_simple_dbl,
        +		ec_GFp_simple_invert,
        +		ec_GFp_simple_is_at_infinity,
        +		ec_GFp_simple_is_on_curve,
        +		ec_GFp_simple_cmp,
        +		ec_GFp_simple_make_affine,
        +		ec_GFp_simple_points_make_affine,
        +		ec_GFp_nistp521_points_mul,
        +		ec_GFp_nistp521_precompute_mult,
        +		ec_GFp_nistp521_have_precompute_mult,
        +		ec_GFp_nist_field_mul,
        +		ec_GFp_nist_field_sqr,
        +		0 /* field_div */,
        +		0 /* field_encode */,
        +		0 /* field_decode */,
        +		0 /* field_set_to_one */ };
        +
        +	return &ret;
        +	}
        +
        +
        +/******************************************************************************/
        +/*		       FUNCTIONS TO MANAGE PRECOMPUTATION
        + */
        +
        +static NISTP521_PRE_COMP *nistp521_pre_comp_new()
        +	{
        +	NISTP521_PRE_COMP *ret = NULL;
        +	ret = (NISTP521_PRE_COMP *)OPENSSL_malloc(sizeof(NISTP521_PRE_COMP));
        +	if (!ret)
        +		{
        +		ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
        +		return ret;
        +		}
        +	memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
        +	ret->references = 1;
        +	return ret;
        +	}
        +
        +static void *nistp521_pre_comp_dup(void *src_)
        +	{
        +	NISTP521_PRE_COMP *src = src_;
        +
        +	/* no need to actually copy, these objects never change! */
        +	CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
        +
        +	return src_;
        +	}
        +
        +static void nistp521_pre_comp_free(void *pre_)
        +	{
        +	int i;
        +	NISTP521_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	OPENSSL_free(pre);
        +	}
        +
        +static void nistp521_pre_comp_clear_free(void *pre_)
        +	{
        +	int i;
        +	NISTP521_PRE_COMP *pre = pre_;
        +
        +	if (!pre)
        +		return;
        +
        +	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
        +	if (i > 0)
        +		return;
        +
        +	OPENSSL_cleanse(pre, sizeof(*pre));
        +	OPENSSL_free(pre);
        +	}
        +
        +/******************************************************************************/
        +/*			   OPENSSL EC_METHOD FUNCTIONS
        + */
        +
        +int ec_GFp_nistp521_group_init(EC_GROUP *group)
        +	{
        +	int ret;
        +	ret = ec_GFp_simple_group_init(group);
        +	group->a_is_minus3 = 1;
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
        +	const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *curve_p, *curve_a, *curve_b;
        +
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
        +		((curve_a = BN_CTX_get(ctx)) == NULL) ||
        +		((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
        +	BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
        +	BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
        +	BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
        +	if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
        +		(BN_cmp(curve_b, b)))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
        +			EC_R_WRONG_CURVE_PARAMETERS);
        +		goto err;
        +		}
        +	group->field_mod_func = BN_nist_mod_521;
        +	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
        +err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
        + * (X', Y') = (X/Z^2, Y/Z^3) */
        +int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
        +	const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	felem z1, z2, x_in, y_in, x_out, y_out;
        +	largefelem tmp;
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
        +			EC_R_POINT_AT_INFINITY);
        +		return 0;
        +		}
        +	if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
        +		(!BN_to_felem(z1, &point->Z))) return 0;
        +	felem_inv(z2, z1);
        +	felem_square(tmp, z2); felem_reduce(z1, tmp);
        +	felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
        +	felem_contract(x_out, x_in);
        +	if (x != NULL)
        +		{
        +		if (!felem_to_BN(x, x_out))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
        +			return 0;
        +			}
        +		}
        +	felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
        +	felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
        +	felem_contract(y_out, y_in);
        +	if (y != NULL)
        +		{
        +		if (!felem_to_BN(y, y_out))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
        +			return 0;
        +			}
        +		}
        +	return 1;
        +	}
        +
        +static void make_points_affine(size_t num, felem points[/* num */][3], felem tmp_felems[/* num+1 */])
        +	{
        +	/* Runs in constant time, unless an input is the point at infinity
        +	 * (which normally shouldn't happen). */
        +	ec_GFp_nistp_points_make_affine_internal(
        +		num,
        +		points,
        +		sizeof(felem),
        +		tmp_felems,
        +		(void (*)(void *)) felem_one,
        +		(int (*)(const void *)) felem_is_zero_int,
        +		(void (*)(void *, const void *)) felem_assign,
        +		(void (*)(void *, const void *)) felem_square_reduce,
        +		(void (*)(void *, const void *, const void *)) felem_mul_reduce,
        +		(void (*)(void *, const void *)) felem_inv,
        +		(void (*)(void *, const void *)) felem_contract);
        +	}
        +
        +/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
        + * Result is stored in r (r can equal one of the inputs). */
        +int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
        +	const BIGNUM *scalar, size_t num, const EC_POINT *points[],
        +	const BIGNUM *scalars[], BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	int j;
        +	int mixed = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y, *z, *tmp_scalar;
        +	felem_bytearray g_secret;
        +	felem_bytearray *secrets = NULL;
        +	felem (*pre_comp)[17][3] = NULL;
        +	felem *tmp_felems = NULL;
        +	felem_bytearray tmp;
        +	unsigned i, num_bytes;
        +	int have_pre_comp = 0;
        +	size_t num_points = num;
        +	felem x_in, y_in, z_in, x_out, y_out, z_out;
        +	NISTP521_PRE_COMP *pre = NULL;
        +	felem (*g_pre_comp)[3] = NULL;
        +	EC_POINT *generator = NULL;
        +	const EC_POINT *p = NULL;
        +	const BIGNUM *p_scalar = NULL;
        +
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((x = BN_CTX_get(ctx)) == NULL) ||
        +		((y = BN_CTX_get(ctx)) == NULL) ||
        +		((z = BN_CTX_get(ctx)) == NULL) ||
        +		((tmp_scalar = BN_CTX_get(ctx)) == NULL))
        +		goto err;
        +
        +	if (scalar != NULL)
        +		{
        +		pre = EC_EX_DATA_get_data(group->extra_data,
        +			nistp521_pre_comp_dup, nistp521_pre_comp_free,
        +			nistp521_pre_comp_clear_free);
        +		if (pre)
        +			/* we have precomputation, try to use it */
        +			g_pre_comp = &pre->g_pre_comp[0];
        +		else
        +			/* try to use the standard precomputation */
        +			g_pre_comp = (felem (*)[3]) gmul;
        +		generator = EC_POINT_new(group);
        +		if (generator == NULL)
        +			goto err;
        +		/* get the generator from precomputation */
        +		if (!felem_to_BN(x, g_pre_comp[1][0]) ||
        +			!felem_to_BN(y, g_pre_comp[1][1]) ||
        +			!felem_to_BN(z, g_pre_comp[1][2]))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
        +				generator, x, y, z, ctx))
        +			goto err;
        +		if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
        +			/* precomputation matches generator */
        +			have_pre_comp = 1;
        +		else
        +			/* we don't have valid precomputation:
        +			 * treat the generator as a random point */
        +			num_points++;
        +		}
        +
        +	if (num_points > 0)
        +		{
        +		if (num_points >= 2)
        +			{
        +			/* unless we precompute multiples for just one point,
        +			 * converting those into affine form is time well spent  */
        +			mixed = 1;
        +			}
        +		secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
        +		pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
        +		if (mixed)
        +			tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
        +		if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL)))
        +			{
        +			ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* we treat NULL scalars as 0, and NULL points as points at infinity,
        +		 * i.e., they contribute nothing to the linear combination */
        +		memset(secrets, 0, num_points * sizeof(felem_bytearray));
        +		memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
        +		for (i = 0; i < num_points; ++i)
        +			{
        +			if (i == num)
        +				/* we didn't have a valid precomputation, so we pick
        +				 * the generator */
        +				{
        +				p = EC_GROUP_get0_generator(group);
        +				p_scalar = scalar;
        +				}
        +			else
        +				/* the i^th point */
        +				{
        +				p = points[i];
        +				p_scalar = scalars[i];
        +				}
        +			if ((p_scalar != NULL) && (p != NULL))
        +				{
        +				/* reduce scalar to 0 <= scalar < 2^521 */
        +				if ((BN_num_bits(p_scalar) > 521) || (BN_is_negative(p_scalar)))
        +					{
        +					/* this is an unusual input, and we don't guarantee
        +					 * constant-timeness */
        +					if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
        +						{
        +						ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
        +						goto err;
        +						}
        +					num_bytes = BN_bn2bin(tmp_scalar, tmp);
        +					}
        +				else
        +					num_bytes = BN_bn2bin(p_scalar, tmp);
        +				flip_endian(secrets[i], tmp, num_bytes);
        +				/* precompute multiples */
        +				if ((!BN_to_felem(x_out, &p->X)) ||
        +					(!BN_to_felem(y_out, &p->Y)) ||
        +					(!BN_to_felem(z_out, &p->Z))) goto err;
        +				memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
        +				memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
        +				memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
        +				for (j = 2; j <= 16; ++j)
        +					{
        +					if (j & 1)
        +						{
        +						point_add(
        +							pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
        +							pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
        +							0, pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
        +						}
        +					else
        +						{
        +						point_double(
        +							pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
        +							pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
        +						}
        +					}
        +				}
        +			}
        +		if (mixed)
        +			make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
        +		}
        +
        +	/* the scalar for the generator */
        +	if ((scalar != NULL) && (have_pre_comp))
        +		{
        +		memset(g_secret, 0, sizeof(g_secret));
        +		/* reduce scalar to 0 <= scalar < 2^521 */
        +		if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar)))
        +			{
        +			/* this is an unusual input, and we don't guarantee
        +			 * constant-timeness */
        +			if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
        +				{
        +				ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
        +				goto err;
        +				}
        +			num_bytes = BN_bn2bin(tmp_scalar, tmp);
        +			}
        +		else
        +			num_bytes = BN_bn2bin(scalar, tmp);
        +		flip_endian(g_secret, tmp, num_bytes);
        +		/* do the multiplication with generator precomputation*/
        +		batch_mul(x_out, y_out, z_out,
        +			(const felem_bytearray (*)) secrets, num_points,
        +			g_secret,
        +			mixed, (const felem (*)[17][3]) pre_comp,
        +			(const felem (*)[3]) g_pre_comp);
        +		}
        +	else
        +		/* do the multiplication without generator precomputation */
        +		batch_mul(x_out, y_out, z_out,
        +			(const felem_bytearray (*)) secrets, num_points,
        +			NULL, mixed, (const felem (*)[17][3]) pre_comp, NULL);
        +	/* reduce the output to its unique minimal representation */
        +	felem_contract(x_in, x_out);
        +	felem_contract(y_in, y_out);
        +	felem_contract(z_in, z_out);
        +	if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
        +		(!felem_to_BN(z, z_in)))
        +		{
        +		ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
        +
        +err:
        +	BN_CTX_end(ctx);
        +	if (generator != NULL)
        +		EC_POINT_free(generator);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (secrets != NULL)
        +		OPENSSL_free(secrets);
        +	if (pre_comp != NULL)
        +		OPENSSL_free(pre_comp);
        +	if (tmp_felems != NULL)
        +		OPENSSL_free(tmp_felems);
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	NISTP521_PRE_COMP *pre = NULL;
        +	int i, j;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y;
        +	EC_POINT *generator = NULL;
        +	felem tmp_felems[16];
        +
        +	/* throw away old precomputation */
        +	EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup,
        +		nistp521_pre_comp_free, nistp521_pre_comp_clear_free);
        +	if (ctx == NULL)
        +		if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
        +	BN_CTX_start(ctx);
        +	if (((x = BN_CTX_get(ctx)) == NULL) ||
        +		((y = BN_CTX_get(ctx)) == NULL))
        +		goto err;
        +	/* get the generator */
        +	if (group->generator == NULL) goto err;
        +	generator = EC_POINT_new(group);
        +	if (generator == NULL)
        +		goto err;
        +	BN_bin2bn(nistp521_curve_params[3], sizeof (felem_bytearray), x);
        +	BN_bin2bn(nistp521_curve_params[4], sizeof (felem_bytearray), y);
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
        +		goto err;
        +	if ((pre = nistp521_pre_comp_new()) == NULL)
        +		goto err;
        +	/* if the generator is the standard one, use built-in precomputation */
        +	if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
        +		{
        +		memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
        +		ret = 1;
        +		goto err;
        +		}
        +	if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) ||
        +		(!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) ||
        +		(!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z)))
        +		goto err;
        +	/* compute 2^130*G, 2^260*G, 2^390*G */
        +	for (i = 1; i <= 4; i <<= 1)
        +		{
        +		point_double(pre->g_pre_comp[2*i][0], pre->g_pre_comp[2*i][1],
        +			pre->g_pre_comp[2*i][2], pre->g_pre_comp[i][0],
        +			pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
        +		for (j = 0; j < 129; ++j)
        +			{
        +			point_double(pre->g_pre_comp[2*i][0],
        +				pre->g_pre_comp[2*i][1],
        +				pre->g_pre_comp[2*i][2],
        +				pre->g_pre_comp[2*i][0],
        +				pre->g_pre_comp[2*i][1],
        +				pre->g_pre_comp[2*i][2]);
        +			}
        +		}
        +	/* g_pre_comp[0] is the point at infinity */
        +	memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
        +	/* the remaining multiples */
        +	/* 2^130*G + 2^260*G */
        +	point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
        +		pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
        +		pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
        +		0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
        +		pre->g_pre_comp[2][2]);
        +	/* 2^130*G + 2^390*G */
        +	point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
        +		pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
        +		pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
        +		0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
        +		pre->g_pre_comp[2][2]);
        +	/* 2^260*G + 2^390*G */
        +	point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
        +		pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
        +		pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
        +		0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
        +		pre->g_pre_comp[4][2]);
        +	/* 2^130*G + 2^260*G + 2^390*G */
        +	point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
        +		pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
        +		pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
        +		0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
        +		pre->g_pre_comp[2][2]);
        +	for (i = 1; i < 8; ++i)
        +		{
        +		/* odd multiples: add G */
        +		point_add(pre->g_pre_comp[2*i+1][0], pre->g_pre_comp[2*i+1][1],
        +			pre->g_pre_comp[2*i+1][2], pre->g_pre_comp[2*i][0],
        +			pre->g_pre_comp[2*i][1], pre->g_pre_comp[2*i][2],
        +			0, pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
        +			pre->g_pre_comp[1][2]);
        +		}
        +	make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
        +
        +	if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup,
        +			nistp521_pre_comp_free, nistp521_pre_comp_clear_free))
        +		goto err;
        +	ret = 1;
        +	pre = NULL;
        + err:
        +	BN_CTX_end(ctx);
        +	if (generator != NULL)
        +		EC_POINT_free(generator);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (pre)
        +		nistp521_pre_comp_free(pre);
        +	return ret;
        +	}
        +
        +int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
        +	{
        +	if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup,
        +			nistp521_pre_comp_free, nistp521_pre_comp_clear_free)
        +		!= NULL)
        +		return 1;
        +	else
        +		return 0;
        +	}
        +
        +#else
        +static void *dummy=&dummy;
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_nistputil.c b/vendor/openssl/openssl/crypto/ec/ecp_nistputil.c
        new file mode 100644
        index 000000000..c8140c807
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_nistputil.c
        @@ -0,0 +1,197 @@
        +/* crypto/ec/ecp_nistputil.c */
        +/*
        + * Written by Bodo Moeller for the OpenSSL project.
        + */
        +/* Copyright 2011 Google Inc.
        + *
        + * Licensed under the Apache License, Version 2.0 (the "License");
        + *
        + * you may not use this file except in compliance with the License.
        + * You may obtain a copy of the License at
        + *
        + *     http://www.apache.org/licenses/LICENSE-2.0
        + *
        + *  Unless required by applicable law or agreed to in writing, software
        + *  distributed under the License is distributed on an "AS IS" BASIS,
        + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        + *  See the License for the specific language governing permissions and
        + *  limitations under the License.
        + */
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +
        +/*
        + * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
        + */
        +
        +#include <stddef.h>
        +#include "ec_lcl.h"
        +
        +/* Convert an array of points into affine coordinates.
        + * (If the point at infinity is found (Z = 0), it remains unchanged.)
        + * This function is essentially an equivalent to EC_POINTs_make_affine(), but
        + * works with the internal representation of points as used by ecp_nistp###.c
        + * rather than with (BIGNUM-based) EC_POINT data structures.
        + *
        + * point_array is the input/output buffer ('num' points in projective form,
        + * i.e. three coordinates each), based on an internal representation of
        + * field elements of size 'felem_size'.
        + *
        + * tmp_felems needs to point to a temporary array of 'num'+1 field elements
        + * for storage of intermediate values.
        + */
        +void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
        +	size_t felem_size, void *tmp_felems,
        +	void (*felem_one)(void *out),
        +	int (*felem_is_zero)(const void *in),
        +	void (*felem_assign)(void *out, const void *in),
        +	void (*felem_square)(void *out, const void *in),
        +	void (*felem_mul)(void *out, const void *in1, const void *in2),
        +	void (*felem_inv)(void *out, const void *in),
        +	void (*felem_contract)(void *out, const void *in))
        +	{
        +	int i = 0;
        +
        +#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
        +#define X(I) (&((char *)point_array)[3*(I) * felem_size])
        +#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
        +#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
        +
        +	if (!felem_is_zero(Z(0)))
        +		felem_assign(tmp_felem(0), Z(0));
        +	else
        +		felem_one(tmp_felem(0));
        +	for (i = 1; i < (int)num; i++)
        +		{
        +		if (!felem_is_zero(Z(i)))
        +			felem_mul(tmp_felem(i), tmp_felem(i-1), Z(i));
        +		else
        +			felem_assign(tmp_felem(i), tmp_felem(i-1));
        +		}
        +	/* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any zero-valued factors:
        +	 * if Z(i) = 0, we essentially pretend that Z(i) = 1 */
        +
        +	felem_inv(tmp_felem(num-1), tmp_felem(num-1));
        +	for (i = num - 1; i >= 0; i--)
        +		{
        +		if (i > 0)
        +			/* tmp_felem(i-1) is the product of Z(0) .. Z(i-1),
        +			 * tmp_felem(i) is the inverse of the product of Z(0) .. Z(i)
        +			 */
        +			felem_mul(tmp_felem(num), tmp_felem(i-1), tmp_felem(i)); /* 1/Z(i) */
        +		else
        +			felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
        +
        +		if (!felem_is_zero(Z(i)))
        +			{
        +			if (i > 0)
        +				/* For next iteration, replace tmp_felem(i-1) by its inverse */
        +				felem_mul(tmp_felem(i-1), tmp_felem(i), Z(i));
        +
        +			/* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) */
        +			felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
        +			felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
        +			felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
        +			felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
        +			felem_contract(X(i), X(i));
        +			felem_contract(Y(i), Y(i));
        +			felem_one(Z(i));
        +			}
        +		else
        +			{
        +			if (i > 0)
        +				/* For next iteration, replace tmp_felem(i-1) by its inverse */
        +				felem_assign(tmp_felem(i-1), tmp_felem(i));
        +			}
        +		}
        +	}
        +
        +/*
        + * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
        + * significant bit), and recodes them into a signed digit for use in fast point
        + * multiplication: the use of signed rather than unsigned digits means that
        + * fewer points need to be precomputed, given that point inversion is easy
        + * (a precomputed point dP makes -dP available as well).
        + *
        + * BACKGROUND:
        + *
        + * Signed digits for multiplication were introduced by Booth ("A signed binary
        + * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
        + * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
        + * Booth's original encoding did not generally improve the density of nonzero
        + * digits over the binary representation, and was merely meant to simplify the
        + * handling of signed factors given in two's complement; but it has since been
        + * shown to be the basis of various signed-digit representations that do have
        + * further advantages, including the wNAF, using the following general approach:
        + *
        + * (1) Given a binary representation
        + *
        + *       b_k  ...  b_2  b_1  b_0,
        + *
        + *     of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
        + *     by using bit-wise subtraction as follows:
        + *
        + *        b_k b_(k-1)  ...  b_2  b_1  b_0
        + *      -     b_k      ...  b_3  b_2  b_1  b_0
        + *       -------------------------------------
        + *        s_k b_(k-1)  ...  s_3  s_2  s_1  s_0
        + *
        + *     A left-shift followed by subtraction of the original value yields a new
        + *     representation of the same value, using signed bits s_i = b_(i+1) - b_i.
        + *     This representation from Booth's paper has since appeared in the
        + *     literature under a variety of different names including "reversed binary
        + *     form", "alternating greedy expansion", "mutual opposite form", and
        + *     "sign-alternating {+-1}-representation".
        + *
        + *     An interesting property is that among the nonzero bits, values 1 and -1
        + *     strictly alternate.
        + *
        + * (2) Various window schemes can be applied to the Booth representation of
        + *     integers: for example, right-to-left sliding windows yield the wNAF
        + *     (a signed-digit encoding independently discovered by various researchers
        + *     in the 1990s), and left-to-right sliding windows yield a left-to-right
        + *     equivalent of the wNAF (independently discovered by various researchers
        + *     around 2004).
        + *
        + * To prevent leaking information through side channels in point multiplication,
        + * we need to recode the given integer into a regular pattern: sliding windows
        + * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
        + * decades older: we'll be using the so-called "modified Booth encoding" due to
        + * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
        + * (1961), pp. 67-91), in a radix-2^5 setting.  That is, we always combine five
        + * signed bits into a signed digit:
        + *
        + *       s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
        + *
        + * The sign-alternating property implies that the resulting digit values are
        + * integers from -16 to 16.
        + *
        + * Of course, we don't actually need to compute the signed digits s_i as an
        + * intermediate step (that's just a nice way to see how this scheme relates
        + * to the wNAF): a direct computation obtains the recoded digit from the
        + * six bits b_(4j + 4) ... b_(4j - 1).
        + *
        + * This function takes those five bits as an integer (0 .. 63), writing the
        + * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
        + * value, in the range 0 .. 8).  Note that this integer essentially provides the
        + * input bits "shifted to the left" by one position: for example, the input to
        + * compute the least significant recoded digit, given that there's no bit b_-1,
        + * has to be b_4 b_3 b_2 b_1 b_0 0.
        + *
        + */
        +void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in)
        +	{
        +	unsigned char s, d;
        +
        +	s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as 6-bit value */
        +	d = (1 << 6) - in - 1;
        +	d = (d & s) | (in & ~s);
        +	d = (d >> 1) + (d & 1);
        +
        +	*sign = s & 1;
        +	*digit = d;
        +	}
        +#else
        +static void *dummy=&dummy;
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_oct.c b/vendor/openssl/openssl/crypto/ec/ecp_oct.c
        new file mode 100644
        index 000000000..374a0ee73
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_oct.c
        @@ -0,0 +1,433 @@
        +/* crypto/ec/ecp_oct.c */
        +/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
        + * for the OpenSSL project. 
        + * Includes code written by Bodo Moeller for the OpenSSL project.
        +*/
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions of this software developed by SUN MICROSYSTEMS, INC.,
        + * and contributed to the OpenSSL project.
        + */
        +
        +#include <openssl/err.h>
        +#include <openssl/symhacks.h>
        +
        +#include "ec_lcl.h"
        +
        +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x_, int y_bit, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *tmp1, *tmp2, *x, *y;
        +	int ret = 0;
        +
        +	/* clear error queue*/
        +	ERR_clear_error();
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	y_bit = (y_bit != 0);
        +
        +	BN_CTX_start(ctx);
        +	tmp1 = BN_CTX_get(ctx);
        +	tmp2 = BN_CTX_get(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	if (y == NULL) goto err;
        +
        +	/* Recover y.  We have a Weierstrass equation
        +	 *     y^2 = x^3 + a*x + b,
        +	 * so  y  is one of the square roots of  x^3 + a*x + b.
        +	 */
        +
        +	/* tmp1 := x^3 */
        +	if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
        +	if (group->meth->field_decode == 0)
        +		{
        +		/* field_{sqr,mul} work on standard representation */
        +		if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
        +		if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
        +		if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
        +		}
        +	
        +	/* tmp1 := tmp1 + a*x */
        +	if (group->a_is_minus3)
        +		{
        +		if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
        +		if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
        +		if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
        +		}
        +	else
        +		{
        +		if (group->meth->field_decode)
        +			{
        +			if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
        +			if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
        +			}
        +		else
        +			{
        +			/* field_mul works on standard representation */
        +			if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
        +			}
        +		
        +		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
        +		}
        +	
        +	/* tmp1 := tmp1 + b */
        +	if (group->meth->field_decode)
        +		{
        +		if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
        +		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
        +		}
        +	
        +	if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
        +		{
        +		unsigned long err = ERR_peek_last_error();
        +		
        +		if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
        +			{
        +			ERR_clear_error();
        +			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
        +			}
        +		else
        +			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +
        +	if (y_bit != BN_is_odd(y))
        +		{
        +		if (BN_is_zero(y))
        +			{
        +			int kron;
        +
        +			kron = BN_kronecker(x, &group->field, ctx);
        +			if (kron == -2) goto err;
        +
        +			if (kron == 1)
        +				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
        +			else
        +				/* BN_mod_sqrt() should have cought this error (not a square) */
        +				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
        +			goto err;
        +			}
        +		if (!BN_usub(y, &group->field, y)) goto err;
        +		}
        +	if (y_bit != BN_is_odd(y))
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
        +	unsigned char *buf, size_t len, BN_CTX *ctx)
        +	{
        +	size_t ret;
        +	BN_CTX *new_ctx = NULL;
        +	int used_ctx = 0;
        +	BIGNUM *x, *y;
        +	size_t field_len, i, skip;
        +
        +	if ((form != POINT_CONVERSION_COMPRESSED)
        +		&& (form != POINT_CONVERSION_UNCOMPRESSED)
        +		&& (form != POINT_CONVERSION_HYBRID))
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
        +		goto err;
        +		}
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		/* encodes to a single 0 octet */
        +		if (buf != NULL)
        +			{
        +			if (len < 1)
        +				{
        +				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
        +				return 0;
        +				}
        +			buf[0] = 0;
        +			}
        +		return 1;
        +		}
        +
        +
        +	/* ret := required output buffer length */
        +	field_len = BN_num_bytes(&group->field);
        +	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
        +
        +	/* if 'buf' is NULL, just return required length */
        +	if (buf != NULL)
        +		{
        +		if (len < ret)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
        +			goto err;
        +			}
        +
        +		if (ctx == NULL)
        +			{
        +			ctx = new_ctx = BN_CTX_new();
        +			if (ctx == NULL)
        +				return 0;
        +			}
        +
        +		BN_CTX_start(ctx);
        +		used_ctx = 1;
        +		x = BN_CTX_get(ctx);
        +		y = BN_CTX_get(ctx);
        +		if (y == NULL) goto err;
        +
        +		if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
        +
        +		if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
        +			buf[0] = form + 1;
        +		else
        +			buf[0] = form;
        +	
        +		i = 1;
        +		
        +		skip = field_len - BN_num_bytes(x);
        +		if (skip > field_len)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		while (skip > 0)
        +			{
        +			buf[i++] = 0;
        +			skip--;
        +			}
        +		skip = BN_bn2bin(x, buf + i);
        +		i += skip;
        +		if (i != 1 + field_len)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +
        +		if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
        +			{
        +			skip = field_len - BN_num_bytes(y);
        +			if (skip > field_len)
        +				{
        +				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			while (skip > 0)
        +				{
        +				buf[i++] = 0;
        +				skip--;
        +				}
        +			skip = BN_bn2bin(y, buf + i);
        +			i += skip;
        +			}
        +
        +		if (i != ret)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		}
        +	
        +	if (used_ctx)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +
        + err:
        +	if (used_ctx)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return 0;
        +	}
        +
        +
        +int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
        +	const unsigned char *buf, size_t len, BN_CTX *ctx)
        +	{
        +	point_conversion_form_t form;
        +	int y_bit;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y;
        +	size_t field_len, enc_len;
        +	int ret = 0;
        +
        +	if (len == 0)
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
        +		return 0;
        +		}
        +	form = buf[0];
        +	y_bit = form & 1;
        +	form = form & ~1U;
        +	if ((form != 0)	&& (form != POINT_CONVERSION_COMPRESSED)
        +		&& (form != POINT_CONVERSION_UNCOMPRESSED)
        +		&& (form != POINT_CONVERSION_HYBRID))
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		return 0;
        +		}
        +	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		return 0;
        +		}
        +
        +	if (form == 0)
        +		{
        +		if (len != 1)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +			return 0;
        +			}
        +
        +		return EC_POINT_set_to_infinity(group, point);
        +		}
        +	
        +	field_len = BN_num_bytes(&group->field);
        +	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
        +
        +	if (len != enc_len)
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		return 0;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	if (y == NULL) goto err;
        +
        +	if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
        +	if (BN_ucmp(x, &group->field) >= 0)
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +		goto err;
        +		}
        +
        +	if (form == POINT_CONVERSION_COMPRESSED)
        +		{
        +		if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
        +		if (BN_ucmp(y, &group->field) >= 0)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +			goto err;
        +			}
        +		if (form == POINT_CONVERSION_HYBRID)
        +			{
        +			if (y_bit != BN_is_odd(y))
        +				{
        +				ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
        +				goto err;
        +				}
        +			}
        +
        +		if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
        +		}
        +	
        +	if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +	
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ec/ecp_smpl.c b/vendor/openssl/openssl/crypto/ec/ecp_smpl.c
        new file mode 100644
        index 000000000..7cbb321f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ecp_smpl.c
        @@ -0,0 +1,1360 @@
        +/* crypto/ec/ecp_smpl.c */
        +/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
        + * for the OpenSSL project. 
        + * Includes code written by Bodo Moeller for the OpenSSL project.
        +*/
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * Portions of this software developed by SUN MICROSYSTEMS, INC.,
        + * and contributed to the OpenSSL project.
        + */
        +
        +#include <openssl/err.h>
        +#include <openssl/symhacks.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +#include "ec_lcl.h"
        +
        +const EC_METHOD *EC_GFp_simple_method(void)
        +	{
        +#ifdef OPENSSL_FIPS
        +	return fips_ec_gfp_simple_method();
        +#else
        +	static const EC_METHOD ret = {
        +		EC_FLAGS_DEFAULT_OCT,
        +		NID_X9_62_prime_field,
        +		ec_GFp_simple_group_init,
        +		ec_GFp_simple_group_finish,
        +		ec_GFp_simple_group_clear_finish,
        +		ec_GFp_simple_group_copy,
        +		ec_GFp_simple_group_set_curve,
        +		ec_GFp_simple_group_get_curve,
        +		ec_GFp_simple_group_get_degree,
        +		ec_GFp_simple_group_check_discriminant,
        +		ec_GFp_simple_point_init,
        +		ec_GFp_simple_point_finish,
        +		ec_GFp_simple_point_clear_finish,
        +		ec_GFp_simple_point_copy,
        +		ec_GFp_simple_point_set_to_infinity,
        +		ec_GFp_simple_set_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_get_Jprojective_coordinates_GFp,
        +		ec_GFp_simple_point_set_affine_coordinates,
        +		ec_GFp_simple_point_get_affine_coordinates,
        +		0,0,0,
        +		ec_GFp_simple_add,
        +		ec_GFp_simple_dbl,
        +		ec_GFp_simple_invert,
        +		ec_GFp_simple_is_at_infinity,
        +		ec_GFp_simple_is_on_curve,
        +		ec_GFp_simple_cmp,
        +		ec_GFp_simple_make_affine,
        +		ec_GFp_simple_points_make_affine,
        +		0 /* mul */,
        +		0 /* precompute_mult */,
        +		0 /* have_precompute_mult */,	
        +		ec_GFp_simple_field_mul,
        +		ec_GFp_simple_field_sqr,
        +		0 /* field_div */,
        +		0 /* field_encode */,
        +		0 /* field_decode */,
        +		0 /* field_set_to_one */ };
        +
        +	return &ret;
        +#endif
        +	}
        +
        +
        +/* Most method functions in this file are designed to work with
        + * non-trivial representations of field elements if necessary
        + * (see ecp_mont.c): while standard modular addition and subtraction
        + * are used, the field_mul and field_sqr methods will be used for
        + * multiplication, and field_encode and field_decode (if defined)
        + * will be used for converting between representations.
        +
        + * Functions ec_GFp_simple_points_make_affine() and
        + * ec_GFp_simple_point_get_affine_coordinates() specifically assume
        + * that if a non-trivial representation is used, it is a Montgomery
        + * representation (i.e. 'encoding' means multiplying by some factor R).
        + */
        +
        +
        +int ec_GFp_simple_group_init(EC_GROUP *group)
        +	{
        +	BN_init(&group->field);
        +	BN_init(&group->a);
        +	BN_init(&group->b);
        +	group->a_is_minus3 = 0;
        +	return 1;
        +	}
        +
        +
        +void ec_GFp_simple_group_finish(EC_GROUP *group)
        +	{
        +	BN_free(&group->field);
        +	BN_free(&group->a);
        +	BN_free(&group->b);
        +	}
        +
        +
        +void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
        +	{
        +	BN_clear_free(&group->field);
        +	BN_clear_free(&group->a);
        +	BN_clear_free(&group->b);
        +	}
        +
        +
        +int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
        +	{
        +	if (!BN_copy(&dest->field, &src->field)) return 0;
        +	if (!BN_copy(&dest->a, &src->a)) return 0;
        +	if (!BN_copy(&dest->b, &src->b)) return 0;
        +
        +	dest->a_is_minus3 = src->a_is_minus3;
        +
        +	return 1;
        +	}
        +
        +
        +int ec_GFp_simple_group_set_curve(EC_GROUP *group,
        +	const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *tmp_a;
        +	
        +	/* p must be a prime > 3 */
        +	if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
        +		return 0;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	tmp_a = BN_CTX_get(ctx);
        +	if (tmp_a == NULL) goto err;
        +
        +	/* group->field */
        +	if (!BN_copy(&group->field, p)) goto err;
        +	BN_set_negative(&group->field, 0);
        +
        +	/* group->a */
        +	if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
        +	if (group->meth->field_encode)
        +		{ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }	
        +	else
        +		if (!BN_copy(&group->a, tmp_a)) goto err;
        +	
        +	/* group->b */
        +	if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
        +	if (group->meth->field_encode)
        +		if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
        +	
        +	/* group->a_is_minus3 */
        +	if (!BN_add_word(tmp_a, 3)) goto err;
        +	group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BN_CTX *new_ctx = NULL;
        +	
        +	if (p != NULL)
        +		{
        +		if (!BN_copy(p, &group->field)) return 0;
        +		}
        +
        +	if (a != NULL || b != NULL)
        +		{
        +		if (group->meth->field_decode)
        +			{
        +			if (ctx == NULL)
        +				{
        +				ctx = new_ctx = BN_CTX_new();
        +				if (ctx == NULL)
        +					return 0;
        +				}
        +			if (a != NULL)
        +				{
        +				if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
        +				}
        +			if (b != NULL)
        +				{
        +				if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
        +				}
        +			}
        +		else
        +			{
        +			if (a != NULL)
        +				{
        +				if (!BN_copy(a, &group->a)) goto err;
        +				}
        +			if (b != NULL)
        +				{
        +				if (!BN_copy(b, &group->b)) goto err;
        +				}
        +			}
        +		}
        +	
        +	ret = 1;
        +	
        + err:
        +	if (new_ctx)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
        +	{
        +	return BN_num_bits(&group->field);
        +	}
        +
        +
        +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
        +	{
        +	int ret = 0;
        +	BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
        +	const BIGNUM *p = &group->field;
        +	BN_CTX *new_ctx = NULL;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	BN_CTX_start(ctx);
        +	a = BN_CTX_get(ctx);
        +	b = BN_CTX_get(ctx);
        +	tmp_1 = BN_CTX_get(ctx);
        +	tmp_2 = BN_CTX_get(ctx);
        +	order = BN_CTX_get(ctx);
        +	if (order == NULL) goto err;
        +
        +	if (group->meth->field_decode)
        +		{
        +		if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
        +		if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_copy(a, &group->a)) goto err;
        +		if (!BN_copy(b, &group->b)) goto err;
        +		}
        +	
        +	/* check the discriminant:
        +	 * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) 
        +         * 0 =< a, b < p */
        +	if (BN_is_zero(a))
        +		{
        +		if (BN_is_zero(b)) goto err;
        +		}
        +	else if (!BN_is_zero(b))
        +		{
        +		if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
        +		if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
        +		if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
        +		/* tmp_1 = 4*a^3 */
        +
        +		if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
        +		if (!BN_mul_word(tmp_2, 27)) goto err;
        +		/* tmp_2 = 27*b^2 */
        +
        +		if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
        +		if (BN_is_zero(a)) goto err;
        +		}
        +	ret = 1;
        +
        +err:
        +	if (ctx != NULL)
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_point_init(EC_POINT *point)
        +	{
        +	BN_init(&point->X);
        +	BN_init(&point->Y);
        +	BN_init(&point->Z);
        +	point->Z_is_one = 0;
        +
        +	return 1;
        +	}
        +
        +
        +void ec_GFp_simple_point_finish(EC_POINT *point)
        +	{
        +	BN_free(&point->X);
        +	BN_free(&point->Y);
        +	BN_free(&point->Z);
        +	}
        +
        +
        +void ec_GFp_simple_point_clear_finish(EC_POINT *point)
        +	{
        +	BN_clear_free(&point->X);
        +	BN_clear_free(&point->Y);
        +	BN_clear_free(&point->Z);
        +	point->Z_is_one = 0;
        +	}
        +
        +
        +int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
        +	{
        +	if (!BN_copy(&dest->X, &src->X)) return 0;
        +	if (!BN_copy(&dest->Y, &src->Y)) return 0;
        +	if (!BN_copy(&dest->Z, &src->Z)) return 0;
        +	dest->Z_is_one = src->Z_is_one;
        +
        +	return 1;
        +	}
        +
        +
        +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
        +	{
        +	point->Z_is_one = 0;
        +	BN_zero(&point->Z);
        +	return 1;
        +	}
        +
        +
        +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	int ret = 0;
        +	
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	if (x != NULL)
        +		{
        +		if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
        +		if (group->meth->field_encode)
        +			{
        +			if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
        +			}
        +		}
        +	
        +	if (y != NULL)
        +		{
        +		if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
        +		if (group->meth->field_encode)
        +			{
        +			if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
        +			}
        +		}
        +	
        +	if (z != NULL)
        +		{
        +		int Z_is_one;
        +
        +		if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
        +		Z_is_one = BN_is_one(&point->Z);
        +		if (group->meth->field_encode)
        +			{
        +			if (Z_is_one && (group->meth->field_set_to_one != 0))
        +				{
        +				if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
        +				}
        +			else
        +				{
        +				if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
        +				}
        +			}
        +		point->Z_is_one = Z_is_one;
        +		}
        +	
        +	ret = 1;
        +	
        + err:
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
        +	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	int ret = 0;
        +	
        +	if (group->meth->field_decode != 0)
        +		{
        +		if (ctx == NULL)
        +			{
        +			ctx = new_ctx = BN_CTX_new();
        +			if (ctx == NULL)
        +				return 0;
        +			}
        +
        +		if (x != NULL)
        +			{
        +			if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
        +			}
        +		if (y != NULL)
        +			{
        +			if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
        +			}
        +		if (z != NULL)
        +			{
        +			if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
        +			}
        +		}
        +	else	
        +		{
        +		if (x != NULL)
        +			{
        +			if (!BN_copy(x, &point->X)) goto err;
        +			}
        +		if (y != NULL)
        +			{
        +			if (!BN_copy(y, &point->Y)) goto err;
        +			}
        +		if (z != NULL)
        +			{
        +			if (!BN_copy(z, &point->Z)) goto err;
        +			}
        +		}
        +	
        +	ret = 1;
        +
        + err:
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
        +	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
        +	{
        +	if (x == NULL || y == NULL)
        +		{
        +		/* unlike for projective coordinates, we do not tolerate this */
        +		ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +
        +	return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
        +	}
        +
        +
        +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
        +	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *Z, *Z_1, *Z_2, *Z_3;
        +	const BIGNUM *Z_;
        +	int ret = 0;
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
        +		return 0;
        +		}
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	Z = BN_CTX_get(ctx);
        +	Z_1 = BN_CTX_get(ctx);
        +	Z_2 = BN_CTX_get(ctx);
        +	Z_3 = BN_CTX_get(ctx);
        +	if (Z_3 == NULL) goto err;
        +
        +	/* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
        +	
        +	if (group->meth->field_decode)
        +		{
        +		if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
        +		Z_ = Z;
        +		}
        +	else
        +		{
        +		Z_ = &point->Z;
        +		}
        +	
        +	if (BN_is_one(Z_))
        +		{
        +		if (group->meth->field_decode)
        +			{
        +			if (x != NULL)
        +				{
        +				if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
        +				}
        +			if (y != NULL)
        +				{
        +				if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
        +				}
        +			}
        +		else
        +			{
        +			if (x != NULL)
        +				{
        +				if (!BN_copy(x, &point->X)) goto err;
        +				}
        +			if (y != NULL)
        +				{
        +				if (!BN_copy(y, &point->Y)) goto err;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		
        +		if (group->meth->field_encode == 0)
        +			{
        +			/* field_sqr works on standard representation */
        +			if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
        +			}
        +		else
        +			{
        +			if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
        +			}
        +	
        +		if (x != NULL)
        +			{
        +			/* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
        +			if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
        +			}
        +
        +		if (y != NULL)
        +			{
        +			if (group->meth->field_encode == 0)
        +				{
        +				/* field_mul works on standard representation */
        +				if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
        +				}
        +			else
        +				{
        +				if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
        +				}
        +
        +			/* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
        +			if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
        +			}
        +		}
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
        +	{
        +	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
        +	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
        +	const BIGNUM *p;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
        +	int ret = 0;
        +	
        +	if (a == b)
        +		return EC_POINT_dbl(group, r, a, ctx);
        +	if (EC_POINT_is_at_infinity(group, a))
        +		return EC_POINT_copy(r, b);
        +	if (EC_POINT_is_at_infinity(group, b))
        +		return EC_POINT_copy(r, a);
        +	
        +	field_mul = group->meth->field_mul;
        +	field_sqr = group->meth->field_sqr;
        +	p = &group->field;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	n0 = BN_CTX_get(ctx);
        +	n1 = BN_CTX_get(ctx);
        +	n2 = BN_CTX_get(ctx);
        +	n3 = BN_CTX_get(ctx);
        +	n4 = BN_CTX_get(ctx);
        +	n5 = BN_CTX_get(ctx);
        +	n6 = BN_CTX_get(ctx);
        +	if (n6 == NULL) goto end;
        +
        +	/* Note that in this function we must not read components of 'a' or 'b'
        +	 * once we have written the corresponding components of 'r'.
        +	 * ('r' might be one of 'a' or 'b'.)
        +	 */
        +
        +	/* n1, n2 */
        +	if (b->Z_is_one)
        +		{
        +		if (!BN_copy(n1, &a->X)) goto end;
        +		if (!BN_copy(n2, &a->Y)) goto end;
        +		/* n1 = X_a */
        +		/* n2 = Y_a */
        +		}
        +	else
        +		{
        +		if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
        +		if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
        +		/* n1 = X_a * Z_b^2 */
        +
        +		if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
        +		if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
        +		/* n2 = Y_a * Z_b^3 */
        +		}
        +
        +	/* n3, n4 */
        +	if (a->Z_is_one)
        +		{
        +		if (!BN_copy(n3, &b->X)) goto end;
        +		if (!BN_copy(n4, &b->Y)) goto end;
        +		/* n3 = X_b */
        +		/* n4 = Y_b */
        +		}
        +	else
        +		{
        +		if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
        +		if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
        +		/* n3 = X_b * Z_a^2 */
        +
        +		if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
        +		if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
        +		/* n4 = Y_b * Z_a^3 */
        +		}
        +
        +	/* n5, n6 */
        +	if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
        +	if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
        +	/* n5 = n1 - n3 */
        +	/* n6 = n2 - n4 */
        +
        +	if (BN_is_zero(n5))
        +		{
        +		if (BN_is_zero(n6))
        +			{
        +			/* a is the same point as b */
        +			BN_CTX_end(ctx);
        +			ret = EC_POINT_dbl(group, r, a, ctx);
        +			ctx = NULL;
        +			goto end;
        +			}
        +		else
        +			{
        +			/* a is the inverse of b */
        +			BN_zero(&r->Z);
        +			r->Z_is_one = 0;
        +			ret = 1;
        +			goto end;
        +			}
        +		}
        +
        +	/* 'n7', 'n8' */
        +	if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
        +	if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
        +	/* 'n7' = n1 + n3 */
        +	/* 'n8' = n2 + n4 */
        +
        +	/* Z_r */
        +	if (a->Z_is_one && b->Z_is_one)
        +		{
        +		if (!BN_copy(&r->Z, n5)) goto end;
        +		}
        +	else
        +		{
        +		if (a->Z_is_one)
        +			{ if (!BN_copy(n0, &b->Z)) goto end; }
        +		else if (b->Z_is_one)
        +			{ if (!BN_copy(n0, &a->Z)) goto end; }
        +		else
        +			{ if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
        +		if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
        +		}
        +	r->Z_is_one = 0;
        +	/* Z_r = Z_a * Z_b * n5 */
        +
        +	/* X_r */
        +	if (!field_sqr(group, n0, n6, ctx)) goto end;
        +	if (!field_sqr(group, n4, n5, ctx)) goto end;
        +	if (!field_mul(group, n3, n1, n4, ctx)) goto end;
        +	if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
        +	/* X_r = n6^2 - n5^2 * 'n7' */
        +	
        +	/* 'n9' */
        +	if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
        +	if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
        +	/* n9 = n5^2 * 'n7' - 2 * X_r */
        +
        +	/* Y_r */
        +	if (!field_mul(group, n0, n0, n6, ctx)) goto end;
        +	if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
        +	if (!field_mul(group, n1, n2, n5, ctx)) goto end;
        +	if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
        +	if (BN_is_odd(n0))
        +		if (!BN_add(n0, n0, p)) goto end;
        +	/* now  0 <= n0 < 2*p,  and n0 is even */
        +	if (!BN_rshift1(&r->Y, n0)) goto end;
        +	/* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
        +
        +	ret = 1;
        +
        + end:
        +	if (ctx) /* otherwise we already called BN_CTX_end */
        +		BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
        +	{
        +	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
        +	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
        +	const BIGNUM *p;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *n0, *n1, *n2, *n3;
        +	int ret = 0;
        +	
        +	if (EC_POINT_is_at_infinity(group, a))
        +		{
        +		BN_zero(&r->Z);
        +		r->Z_is_one = 0;
        +		return 1;
        +		}
        +
        +	field_mul = group->meth->field_mul;
        +	field_sqr = group->meth->field_sqr;
        +	p = &group->field;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	n0 = BN_CTX_get(ctx);
        +	n1 = BN_CTX_get(ctx);
        +	n2 = BN_CTX_get(ctx);
        +	n3 = BN_CTX_get(ctx);
        +	if (n3 == NULL) goto err;
        +
        +	/* Note that in this function we must not read components of 'a'
        +	 * once we have written the corresponding components of 'r'.
        +	 * ('r' might the same as 'a'.)
        +	 */
        +
        +	/* n1 */
        +	if (a->Z_is_one)
        +		{
        +		if (!field_sqr(group, n0, &a->X, ctx)) goto err;
        +		if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
        +		if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
        +		if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
        +		/* n1 = 3 * X_a^2 + a_curve */
        +		}
        +	else if (group->a_is_minus3)
        +		{
        +		if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
        +		if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
        +		if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
        +		if (!field_mul(group, n1, n0, n2, ctx)) goto err;
        +		if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
        +		if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
        +		/* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
        +		 *    = 3 * X_a^2 - 3 * Z_a^4 */
        +		}
        +	else
        +		{
        +		if (!field_sqr(group, n0, &a->X, ctx)) goto err;
        +		if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
        +		if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
        +		if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
        +		if (!field_sqr(group, n1, n1, ctx)) goto err;
        +		if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
        +		if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
        +		/* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
        +		}
        +
        +	/* Z_r */
        +	if (a->Z_is_one)
        +		{
        +		if (!BN_copy(n0, &a->Y)) goto err;
        +		}
        +	else
        +		{
        +		if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
        +		}
        +	if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
        +	r->Z_is_one = 0;
        +	/* Z_r = 2 * Y_a * Z_a */
        +
        +	/* n2 */
        +	if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
        +	if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
        +	if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
        +	/* n2 = 4 * X_a * Y_a^2 */
        +
        +	/* X_r */
        +	if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
        +	if (!field_sqr(group, &r->X, n1, ctx)) goto err;
        +	if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
        +	/* X_r = n1^2 - 2 * n2 */
        +	
        +	/* n3 */
        +	if (!field_sqr(group, n0, n3, ctx)) goto err;
        +	if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
        +	/* n3 = 8 * Y_a^4 */
        +	
        +	/* Y_r */
        +	if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
        +	if (!field_mul(group, n0, n1, n0, ctx)) goto err;
        +	if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
        +	/* Y_r = n1 * (n2 - X_r) - n3 */
        +
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
        +	{
        +	if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
        +		/* point is its own inverse */
        +		return 1;
        +	
        +	return BN_usub(&point->Y, &group->field, &point->Y);
        +	}
        +
        +
        +int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
        +	{
        +	return BN_is_zero(&point->Z);
        +	}
        +
        +
        +int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
        +	{
        +	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
        +	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
        +	const BIGNUM *p;
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *rh, *tmp, *Z4, *Z6;
        +	int ret = -1;
        +
        +	if (EC_POINT_is_at_infinity(group, point))
        +		return 1;
        +	
        +	field_mul = group->meth->field_mul;
        +	field_sqr = group->meth->field_sqr;
        +	p = &group->field;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return -1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	rh = BN_CTX_get(ctx);
        +	tmp = BN_CTX_get(ctx);
        +	Z4 = BN_CTX_get(ctx);
        +	Z6 = BN_CTX_get(ctx);
        +	if (Z6 == NULL) goto err;
        +
        +	/* We have a curve defined by a Weierstrass equation
        +	 *      y^2 = x^3 + a*x + b.
        +	 * The point to consider is given in Jacobian projective coordinates
        +	 * where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
        +	 * Substituting this and multiplying by  Z^6  transforms the above equation into
        +	 *      Y^2 = X^3 + a*X*Z^4 + b*Z^6.
        +	 * To test this, we add up the right-hand side in 'rh'.
        +	 */
        +
        +	/* rh := X^2 */
        +	if (!field_sqr(group, rh, &point->X, ctx)) goto err;
        +
        +	if (!point->Z_is_one)
        +		{
        +		if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
        +		if (!field_sqr(group, Z4, tmp, ctx)) goto err;
        +		if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
        +
        +		/* rh := (rh + a*Z^4)*X */
        +		if (group->a_is_minus3)
        +			{
        +			if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
        +			if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
        +			if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
        +			if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
        +			}
        +		else
        +			{
        +			if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
        +			if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
        +			if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
        +			}
        +
        +		/* rh := rh + b*Z^6 */
        +		if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
        +		if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
        +		}
        +	else
        +		{
        +		/* point->Z_is_one */
        +
        +		/* rh := (rh + a)*X */
        +		if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
        +		if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
        +		/* rh := rh + b */
        +		if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
        +		}
        +
        +	/* 'lh' := Y^2 */
        +	if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
        +
        +	ret = (0 == BN_ucmp(tmp, rh));
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
        +	{
        +	/* return values:
        +	 *  -1   error
        +	 *   0   equal (in affine coordinates)
        +	 *   1   not equal
        +	 */
        +
        +	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
        +	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
        +	const BIGNUM *tmp1_, *tmp2_;
        +	int ret = -1;
        +	
        +	if (EC_POINT_is_at_infinity(group, a))
        +		{
        +		return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
        +		}
        +
        +	if (EC_POINT_is_at_infinity(group, b))
        +		return 1;
        +	
        +	if (a->Z_is_one && b->Z_is_one)
        +		{
        +		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
        +		}
        +
        +	field_mul = group->meth->field_mul;
        +	field_sqr = group->meth->field_sqr;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return -1;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	tmp1 = BN_CTX_get(ctx);
        +	tmp2 = BN_CTX_get(ctx);
        +	Za23 = BN_CTX_get(ctx);
        +	Zb23 = BN_CTX_get(ctx);
        +	if (Zb23 == NULL) goto end;
        +
        +	/* We have to decide whether
        +	 *     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
        +	 * or equivalently, whether
        +	 *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
        +	 */
        +
        +	if (!b->Z_is_one)
        +		{
        +		if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
        +		if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
        +		tmp1_ = tmp1;
        +		}
        +	else
        +		tmp1_ = &a->X;
        +	if (!a->Z_is_one)
        +		{
        +		if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
        +		if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
        +		tmp2_ = tmp2;
        +		}
        +	else
        +		tmp2_ = &b->X;
        +	
        +	/* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
        +	if (BN_cmp(tmp1_, tmp2_) != 0)
        +		{
        +		ret = 1; /* points differ */
        +		goto end;
        +		}
        +
        +
        +	if (!b->Z_is_one)
        +		{
        +		if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
        +		if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
        +		/* tmp1_ = tmp1 */
        +		}
        +	else
        +		tmp1_ = &a->Y;
        +	if (!a->Z_is_one)
        +		{
        +		if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
        +		if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
        +		/* tmp2_ = tmp2 */
        +		}
        +	else
        +		tmp2_ = &b->Y;
        +
        +	/* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
        +	if (BN_cmp(tmp1_, tmp2_) != 0)
        +		{
        +		ret = 1; /* points differ */
        +		goto end;
        +		}
        +
        +	/* points are equal */
        +	ret = 0;
        +
        + end:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *x, *y;
        +	int ret = 0;
        +
        +	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
        +		return 1;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	if (y == NULL) goto err;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
        +	if (!point->Z_is_one)
        +		{
        +		ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +	
        +	ret = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
        +	{
        +	BN_CTX *new_ctx = NULL;
        +	BIGNUM *tmp0, *tmp1;
        +	size_t pow2 = 0;
        +	BIGNUM **heap = NULL;
        +	size_t i;
        +	int ret = 0;
        +
        +	if (num == 0)
        +		return 1;
        +
        +	if (ctx == NULL)
        +		{
        +		ctx = new_ctx = BN_CTX_new();
        +		if (ctx == NULL)
        +			return 0;
        +		}
        +
        +	BN_CTX_start(ctx);
        +	tmp0 = BN_CTX_get(ctx);
        +	tmp1 = BN_CTX_get(ctx);
        +	if (tmp0  == NULL || tmp1 == NULL) goto err;
        +
        +	/* Before converting the individual points, compute inverses of all Z values.
        +	 * Modular inversion is rather slow, but luckily we can do with a single
        +	 * explicit inversion, plus about 3 multiplications per input value.
        +	 */
        +
        +	pow2 = 1;
        +	while (num > pow2)
        +		pow2 <<= 1;
        +	/* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
        +	 * We need twice that. */
        +	pow2 <<= 1;
        +
        +	heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
        +	if (heap == NULL) goto err;
        +	
        +	/* The array is used as a binary tree, exactly as in heapsort:
        +	 *
        +	 *                               heap[1]
        +	 *                 heap[2]                     heap[3]
        +	 *          heap[4]       heap[5]       heap[6]       heap[7]
        +	 *   heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
        +	 *
        +	 * We put the Z's in the last line;
        +	 * then we set each other node to the product of its two child-nodes (where
        +	 * empty or 0 entries are treated as ones);
        +	 * then we invert heap[1];
        +	 * then we invert each other node by replacing it by the product of its
        +	 * parent (after inversion) and its sibling (before inversion).
        +	 */
        +	heap[0] = NULL;
        +	for (i = pow2/2 - 1; i > 0; i--)
        +		heap[i] = NULL;
        +	for (i = 0; i < num; i++)
        +		heap[pow2/2 + i] = &points[i]->Z;
        +	for (i = pow2/2 + num; i < pow2; i++)
        +		heap[i] = NULL;
        +	
        +	/* set each node to the product of its children */
        +	for (i = pow2/2 - 1; i > 0; i--)
        +		{
        +		heap[i] = BN_new();
        +		if (heap[i] == NULL) goto err;
        +		
        +		if (heap[2*i] != NULL)
        +			{
        +			if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
        +				{
        +				if (!BN_copy(heap[i], heap[2*i])) goto err;
        +				}
        +			else
        +				{
        +				if (BN_is_zero(heap[2*i]))
        +					{
        +					if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
        +					}
        +				else
        +					{
        +					if (!group->meth->field_mul(group, heap[i],
        +						heap[2*i], heap[2*i + 1], ctx)) goto err;
        +					}
        +				}
        +			}
        +		}
        +
        +	/* invert heap[1] */
        +	if (!BN_is_zero(heap[1]))
        +		{
        +		if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
        +			{
        +			ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		}
        +	if (group->meth->field_encode != 0)
        +		{
        +		/* in the Montgomery case, we just turned  R*H  (representing H)
        +		 * into  1/(R*H),  but we need  R*(1/H)  (representing 1/H);
        +		 * i.e. we have need to multiply by the Montgomery factor twice */
        +		if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
        +		if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
        +		}
        +
        +	/* set other heap[i]'s to their inverses */
        +	for (i = 2; i < pow2/2 + num; i += 2)
        +		{
        +		/* i is even */
        +		if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
        +			{
        +			if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
        +			if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
        +			if (!BN_copy(heap[i], tmp0)) goto err;
        +			if (!BN_copy(heap[i + 1], tmp1)) goto err;
        +			}
        +		else
        +			{
        +			if (!BN_copy(heap[i], heap[i/2])) goto err;
        +			}
        +		}
        +
        +	/* we have replaced all non-zero Z's by their inverses, now fix up all the points */
        +	for (i = 0; i < num; i++)
        +		{
        +		EC_POINT *p = points[i];
        +		
        +		if (!BN_is_zero(&p->Z))
        +			{
        +			/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
        +
        +			if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
        +			if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
        +
        +			if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
        +			if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
        +		
        +			if (group->meth->field_set_to_one != 0)
        +				{
        +				if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
        +				}
        +			else
        +				{
        +				if (!BN_one(&p->Z)) goto err;
        +				}
        +			p->Z_is_one = 1;
        +			}
        +		}
        +
        +	ret = 1;
        +		
        + err:
        +	BN_CTX_end(ctx);
        +	if (new_ctx != NULL)
        +		BN_CTX_free(new_ctx);
        +	if (heap != NULL)
        +		{
        +		/* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
        +		for (i = pow2/2 - 1; i > 0; i--)
        +			{
        +			if (heap[i] != NULL)
        +				BN_clear_free(heap[i]);
        +			}
        +		OPENSSL_free(heap);
        +		}
        +	return ret;
        +	}
        +
        +
        +int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        +	{
        +	return BN_mod_mul(r, a, b, &group->field, ctx);
        +	}
        +
        +
        +int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
        +	{
        +	return BN_mod_sqr(r, a, &group->field, ctx);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ec/ectest.c b/vendor/openssl/openssl/crypto/ec/ectest.c
        new file mode 100644
        index 000000000..102eaa9b2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ec/ectest.c
        @@ -0,0 +1,1489 @@
        +/* crypto/ec/ectest.c */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#ifdef FLAT_INC
        +#include "e_os.h"
        +#else
        +#include "../e_os.h"
        +#endif
        +#include <string.h>
        +#include <time.h>
        +
        +
        +#ifdef OPENSSL_NO_EC
        +int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
        +#else
        +
        +
        +#include <openssl/ec.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/obj_mac.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +#include <openssl/opensslconf.h>
        +
        +#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
        +/* suppress "too big too optimize" warning */
        +#pragma warning(disable:4959)
        +#endif
        +
        +#define ABORT do { \
        +	fflush(stdout); \
        +	fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
        +	ERR_print_errors_fp(stderr); \
        +	EXIT(1); \
        +} while (0)
        +
        +#define TIMING_BASE_PT 0
        +#define TIMING_RAND_PT 1
        +#define TIMING_SIMUL 2
        +
        +#if 0
        +static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
        +	{
        +	clock_t clck;
        +	int i, j;
        +	BIGNUM *s;
        +	BIGNUM *r[10], *r0[10];
        +	EC_POINT *P;
        +		
        +	s = BN_new();
        +	if (s == NULL) ABORT;
        +
        +	fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
        +	if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
        +	fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
        +	fflush(stdout);
        +
        +	P = EC_POINT_new(group);
        +	if (P == NULL) ABORT;
        +	EC_POINT_copy(P, EC_GROUP_get0_generator(group));
        +
        +	for (i = 0; i < 10; i++)
        +		{
        +		if ((r[i] = BN_new()) == NULL) ABORT;
        +		if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
        +		if (type != TIMING_BASE_PT)
        +			{
        +			if ((r0[i] = BN_new()) == NULL) ABORT;
        +			if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
        +			}
        +		}
        +
        +	clck = clock();
        +	for (i = 0; i < 10; i++)
        +		{
        +		for (j = 0; j < 10; j++)
        +			{
        +			if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, 
        +				(type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
        +			}
        +		}
        +	clck = clock() - clck;
        +
        +	fprintf(stdout, "\n");
        +
        +#ifdef CLOCKS_PER_SEC
        +	/* "To determine the time in seconds, the value returned
        +	 * by the clock function should be divided by the value
        +	 * of the macro CLOCKS_PER_SEC."
        +	 *                                       -- ISO/IEC 9899 */
        +#	define UNIT "s"
        +#else
        +	/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
        +	 *                            -- cc on NeXTstep/OpenStep */
        +#	define UNIT "units"
        +#	define CLOCKS_PER_SEC 1
        +#endif
        +
        +	if (type == TIMING_BASE_PT) {
        +		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
        +			"base point multiplications", (double)clck/CLOCKS_PER_SEC);
        +	} else if (type == TIMING_RAND_PT) {
        +		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
        +			"random point multiplications", (double)clck/CLOCKS_PER_SEC);
        +	} else if (type == TIMING_SIMUL) {
        +		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
        +			"s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
        +	}
        +	fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
        +
        +	EC_POINT_free(P);
        +	BN_free(s);
        +	for (i = 0; i < 10; i++)
        +		{
        +		BN_free(r[i]);
        +		if (type != TIMING_BASE_PT) BN_free(r0[i]);
        +		}
        +	}
        +#endif
        +
        +/* test multiplication with group order, long and negative scalars */
        +static void group_order_tests(EC_GROUP *group)
        +	{
        +	BIGNUM *n1, *n2, *order;
        +	EC_POINT *P = EC_POINT_new(group);
        +	EC_POINT *Q = EC_POINT_new(group);
        +	BN_CTX *ctx = BN_CTX_new();
        +
        +	n1 = BN_new(); n2 = BN_new(); order = BN_new();
        +	fprintf(stdout, "verify group order ...");
        +	fflush(stdout);
        +	if (!EC_GROUP_get_order(group, order, ctx)) ABORT;
        +	if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	fprintf(stdout, ".");
        +	fflush(stdout);
        +	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
        +	if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	fprintf(stdout, " ok\n");
        +	fprintf(stdout, "long/negative scalar tests ... ");
        +	if (!BN_one(n1)) ABORT;
        +	/* n1 = 1 - order */
        +	if (!BN_sub(n1, n1, order)) ABORT;
        +	if(!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
        +	/* n2 = 1 + order */
        +	if (!BN_add(n2, order, BN_value_one())) ABORT;
        +	if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
        +	/* n2 = (1 - order) * (1 + order) */
        +	if (!BN_mul(n2, n1, n2, ctx)) ABORT;
        +	if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
        +	fprintf(stdout, "ok\n");
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	BN_free(n1);
        +	BN_free(n2);
        +	BN_free(order);
        +	BN_CTX_free(ctx);
        +	}
        +
        +static void prime_field_tests(void)
        +	{
        +	BN_CTX *ctx = NULL;
        +	BIGNUM *p, *a, *b;
        +	EC_GROUP *group;
        +	EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
        +	EC_POINT *P, *Q, *R;
        +	BIGNUM *x, *y, *z;
        +	unsigned char buf[100];
        +	size_t i, len;
        +	int k;
        +	
        +#if 1 /* optional */
        +	ctx = BN_CTX_new();
        +	if (!ctx) ABORT;
        +#endif
        +
        +	p = BN_new();
        +	a = BN_new();
        +	b = BN_new();
        +	if (!p || !a || !b) ABORT;
        +
        +	if (!BN_hex2bn(&p, "17")) ABORT;
        +	if (!BN_hex2bn(&a, "1")) ABORT;
        +	if (!BN_hex2bn(&b, "1")) ABORT;
        +	
        +	group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
        +	                                             * so that the library gets to choose the EC_METHOD */
        +	if (!group) ABORT;
        +
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	{
        +		EC_GROUP *tmp;
        +		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
        +		if (!tmp) ABORT;
        +		if (!EC_GROUP_copy(tmp, group)) ABORT;
        +		EC_GROUP_free(group);
        +		group = tmp;
        +	}
        +	
        +	if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
        +	BN_print_fp(stdout, p);
        +	fprintf(stdout, ")\n     a = 0x");
        +	BN_print_fp(stdout, a);
        +	fprintf(stdout, "\n     b = 0x");
        +	BN_print_fp(stdout, b);
        +	fprintf(stdout, "\n");
        +
        +	P = EC_POINT_new(group);
        +	Q = EC_POINT_new(group);
        +	R = EC_POINT_new(group);
        +	if (!P || !Q || !R) ABORT;
        +	
        +	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	buf[0] = 0;
        +	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
        +
        +	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	x = BN_new();
        +	y = BN_new();
        +	z = BN_new();
        +	if (!x || !y || !z) ABORT;
        +
        +	if (!BN_hex2bn(&x, "D")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, Q, ctx))
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
        +		fprintf(stderr, "Point is not on curve: x = 0x");
        +		BN_print_fp(stderr, x);
        +		fprintf(stderr, ", y = 0x");
        +		BN_print_fp(stderr, y);
        +		fprintf(stderr, "\n");
        +		ABORT;
        +		}
        +
        +	fprintf(stdout, "A cyclic subgroup:\n");
        +	k = 100;
        +	do
        +		{
        +		if (k-- == 0) ABORT;
        +
        +		if (EC_POINT_is_at_infinity(group, P))
        +			fprintf(stdout, "     point at infinity\n");
        +		else
        +			{
        +			if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +
        +			fprintf(stdout, "     x = 0x");
        +			BN_print_fp(stdout, x);
        +			fprintf(stdout, ", y = 0x");
        +			BN_print_fp(stdout, y);
        +			fprintf(stdout, "\n");
        +			}
        +		
        +		if (!EC_POINT_copy(R, P)) ABORT;
        +		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +
        +#if 0 /* optional */
        +		{
        +			EC_POINT *points[3];
        +		
        +			points[0] = R;
        +			points[1] = Q;
        +			points[2] = P;
        +			if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
        +		}
        +#endif
        +
        +		}
        +	while (!EC_POINT_is_at_infinity(group, P));
        +
        +	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +	if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
        +	fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, ", Y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, ", Z = 0x");
        +	BN_print_fp(stdout, z);
        +	fprintf(stdout, "\n");
        +
        +	if (!EC_POINT_invert(group, P, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +
        +
        +	/* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
        +	 * -- not a NIST curve, but commonly used */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
        +	if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 160) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_160, group)) ABORT;
        +
        +
        +	/* Curve P-192 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 192) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_192, group)) ABORT;
        +
        +
        +	/* Curve P-224 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
        +	if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 224) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_224, group)) ABORT;
        +
        +
        +	/* Curve P-256 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
        +		"84F3B9CAC2FC632551")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 256) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_256, group)) ABORT;
        +
        +
        +	/* Curve P-384 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
        +		"120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
        +		"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
        +		"7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 384) ABORT;
        +	fprintf(stdout, " ok\n");
        +
        +	group_order_tests(group);
        +
        +	if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_384, group)) ABORT;
        +
        +
        +	/* Curve P-521 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
        +		"315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
        +		"DF883D2C34F1EF451FD46B503F00")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
        +		"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
        +		"3C1856A429BF97E7E31C2E5BD66")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
        +		"C9B8899C47AEBB6FB71E91386409")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
        +		"B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
        +		"7086A272C24088BE94769FD16650")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 521) ABORT;
        +	fprintf(stdout, " ok\n");
        +
        + 	group_order_tests(group);
        +
        +	if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_521, group)) ABORT;
        +
        +
        +	/* more tests using the last curve */
        +
        +	if (!EC_POINT_copy(Q, P)) ABORT;
        +	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
        +
        +	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
        +
        +	{
        +		const EC_POINT *points[4];
        +		const BIGNUM *scalars[4];
        +		BIGNUM scalar3;
        +	
        +		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +		points[0] = Q;
        +		points[1] = Q;
        +		points[2] = Q;
        +		points[3] = Q;
        +
        +		if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
        +		if (!BN_add(y, z, BN_value_one())) ABORT;
        +		if (BN_is_odd(y)) ABORT;
        +		if (!BN_rshift1(y, y)) ABORT;
        +		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
        +		scalars[1] = y;
        +
        +		fprintf(stdout, "combined multiplication ...");
        +		fflush(stdout);
        +
        +		/* z is still the group order */
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
        +		if (!BN_add(z, z, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = y;
        +		scalars[1] = z; /* z = -(order + y) */
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
        +		if (!BN_add(z, x, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = x;
        +		scalars[1] = y;
        +		scalars[2] = z; /* z = -(x+y) */
        +
        +		BN_init(&scalar3);
        +		BN_zero(&scalar3);
        +		scalars[3] = &scalar3;
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, " ok\n\n");
        +
        +		BN_free(&scalar3);
        +	}
        +
        +
        +#if 0
        +	timings(P_160, TIMING_BASE_PT, ctx);
        +	timings(P_160, TIMING_RAND_PT, ctx);
        +	timings(P_160, TIMING_SIMUL, ctx);
        +	timings(P_192, TIMING_BASE_PT, ctx);
        +	timings(P_192, TIMING_RAND_PT, ctx);
        +	timings(P_192, TIMING_SIMUL, ctx);
        +	timings(P_224, TIMING_BASE_PT, ctx);
        +	timings(P_224, TIMING_RAND_PT, ctx);
        +	timings(P_224, TIMING_SIMUL, ctx);
        +	timings(P_256, TIMING_BASE_PT, ctx);
        +	timings(P_256, TIMING_RAND_PT, ctx);
        +	timings(P_256, TIMING_SIMUL, ctx);
        +	timings(P_384, TIMING_BASE_PT, ctx);
        +	timings(P_384, TIMING_RAND_PT, ctx);
        +	timings(P_384, TIMING_SIMUL, ctx);
        +	timings(P_521, TIMING_BASE_PT, ctx);
        +	timings(P_521, TIMING_RAND_PT, ctx);
        +	timings(P_521, TIMING_SIMUL, ctx);
        +#endif
        +
        +
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	BN_free(p); BN_free(a);	BN_free(b);
        +	EC_GROUP_free(group);
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	EC_POINT_free(R);
        +	BN_free(x); BN_free(y); BN_free(z);
        +
        +	if (P_160) EC_GROUP_free(P_160);
        +	if (P_192) EC_GROUP_free(P_192);
        +	if (P_224) EC_GROUP_free(P_224);
        +	if (P_256) EC_GROUP_free(P_256);
        +	if (P_384) EC_GROUP_free(P_384);
        +	if (P_521) EC_GROUP_free(P_521);
        +
        +	}
        +
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	if (!BN_hex2bn(&x, _x)) ABORT; \
        +	if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
        +	if (!BN_hex2bn(&z, _order)) ABORT; \
        +	if (!BN_hex2bn(&cof, _cof)) ABORT; \
        +	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
        +	if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
        +	fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
        +	BN_print_fp(stdout, x); \
        +	fprintf(stdout, "\n     y = 0x"); \
        +	BN_print_fp(stdout, y); \
        +	fprintf(stdout, "\n"); \
        +	/* G_y value taken from the standard: */ \
        +	if (!BN_hex2bn(&z, _y)) ABORT; \
        +	if (0 != BN_cmp(y, z)) ABORT;
        +#else 
        +#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	if (!BN_hex2bn(&x, _x)) ABORT; \
        +	if (!BN_hex2bn(&y, _y)) ABORT; \
        +	if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
        +	if (!BN_hex2bn(&z, _order)) ABORT; \
        +	if (!BN_hex2bn(&cof, _cof)) ABORT; \
        +	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
        +	fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
        +	BN_print_fp(stdout, x); \
        +	fprintf(stdout, "\n     y = 0x"); \
        +	BN_print_fp(stdout, y); \
        +	fprintf(stdout, "\n");
        +#endif
        +
        +#define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	if (!BN_hex2bn(&p, _p)) ABORT; \
        +	if (!BN_hex2bn(&a, _a)) ABORT; \
        +	if (!BN_hex2bn(&b, _b)) ABORT; \
        +	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
        +	CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	fprintf(stdout, "verify degree ..."); \
        +	if (EC_GROUP_get_degree(group) != _degree) ABORT; \
        +	fprintf(stdout, " ok\n"); \
        +	group_order_tests(group); \
        +	if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
        +	if (!EC_GROUP_copy(_variable, group)) ABORT; \
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +static void char2_field_tests(void)
        +	{
        +	BN_CTX *ctx = NULL;
        +	BIGNUM *p, *a, *b;
        +	EC_GROUP *group;
        +	EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
        +	EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
        +	EC_POINT *P, *Q, *R;
        +	BIGNUM *x, *y, *z, *cof;
        +	unsigned char buf[100];
        +	size_t i, len;
        +	int k;
        +	
        +#if 1 /* optional */
        +	ctx = BN_CTX_new();
        +	if (!ctx) ABORT;
        +#endif
        +
        +	p = BN_new();
        +	a = BN_new();
        +	b = BN_new();
        +	if (!p || !a || !b) ABORT;
        +
        +	if (!BN_hex2bn(&p, "13")) ABORT;
        +	if (!BN_hex2bn(&a, "3")) ABORT;
        +	if (!BN_hex2bn(&b, "1")) ABORT;
        +	
        +	group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
        +	                                                * so that the library gets to choose the EC_METHOD */
        +	if (!group) ABORT;
        +	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;
        +
        +	{
        +		EC_GROUP *tmp;
        +		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
        +		if (!tmp) ABORT;
        +		if (!EC_GROUP_copy(tmp, group)) ABORT;
        +		EC_GROUP_free(group);
        +		group = tmp;
        +	}
        +	
        +	if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;
        +
        +	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
        +	BN_print_fp(stdout, p);
        +	fprintf(stdout, ")\n     a = 0x");
        +	BN_print_fp(stdout, a);
        +	fprintf(stdout, "\n     b = 0x");
        +	BN_print_fp(stdout, b);
        +	fprintf(stdout, "\n(0x... means binary polynomial)\n");
        +
        +	P = EC_POINT_new(group);
        +	Q = EC_POINT_new(group);
        +	R = EC_POINT_new(group);
        +	if (!P || !Q || !R) ABORT;
        +	
        +	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	buf[0] = 0;
        +	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
        +
        +	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	x = BN_new();
        +	y = BN_new();
        +	z = BN_new();
        +	cof = BN_new();
        +	if (!x || !y || !z || !cof) ABORT;
        +
        +	if (!BN_hex2bn(&x, "6")) ABORT;
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +	if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
        +#else
        +	if (!BN_hex2bn(&y, "8")) ABORT;
        +	if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
        +#endif
        +	if (!EC_POINT_is_on_curve(group, Q, ctx))
        +		{
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
        +#endif
        +		fprintf(stderr, "Point is not on curve: x = 0x");
        +		BN_print_fp(stderr, x);
        +		fprintf(stderr, ", y = 0x");
        +		BN_print_fp(stderr, y);
        +		fprintf(stderr, "\n");
        +		ABORT;
        +		}
        +
        +	fprintf(stdout, "A cyclic subgroup:\n");
        +	k = 100;
        +	do
        +		{
        +		if (k-- == 0) ABORT;
        +
        +		if (EC_POINT_is_at_infinity(group, P))
        +			fprintf(stdout, "     point at infinity\n");
        +		else
        +			{
        +			if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;
        +
        +			fprintf(stdout, "     x = 0x");
        +			BN_print_fp(stdout, x);
        +			fprintf(stdout, ", y = 0x");
        +			BN_print_fp(stdout, y);
        +			fprintf(stdout, "\n");
        +			}
        +		
        +		if (!EC_POINT_copy(R, P)) ABORT;
        +		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +		}
        +	while (!EC_POINT_is_at_infinity(group, P));
        +
        +	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +#endif
        +	
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +#endif
        +
        +	fprintf(stdout, "\n");
        +	
        +	if (!EC_POINT_invert(group, P, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +
        +
        +	/* Curve K-163 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-163",
        +		"0800000000000000000000000000000000000000C9",
        +		"1",
        +		"1",
        +		"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
        +		"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
        +		1,
        +		"04000000000000000000020108A2E0CC0D99F8A5EF",
        +		"2",
        +		163,
        +		C2_K163
        +		);
        +
        +	/* Curve B-163 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-163",
        +		"0800000000000000000000000000000000000000C9",
        +		"1",
        +		"020A601907B8C953CA1481EB10512F78744A3205FD",
        +		"03F0EBA16286A2D57EA0991168D4994637E8343E36",
        +		"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
        +		1,
        +		"040000000000000000000292FE77E70C12A4234C33",
        +		"2",
        +		163,
        +		C2_B163
        +		);
        +
        +	/* Curve K-233 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-233",
        +		"020000000000000000000000000000000000000004000000000000000001",
        +		"0",
        +		"1",
        +		"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
        +		"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
        +		0,
        +		"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
        +		"4",
        +		233,
        +		C2_K233
        +		);
        +
        +	/* Curve B-233 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-233",
        +		"020000000000000000000000000000000000000004000000000000000001",
        +		"000000000000000000000000000000000000000000000000000000000001",
        +		"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
        +		"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
        +		"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
        +		1,
        +		"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
        +		"2",
        +		233,
        +		C2_B233
        +		);
        +
        +	/* Curve K-283 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-283",
        +		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
        +		"0",
        +		"1",
        +		"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
        +		"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
        +		0,
        +		"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
        +		"4",
        +		283,
        +		C2_K283
        +		);
        +
        +	/* Curve B-283 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-283",
        +		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
        +		"000000000000000000000000000000000000000000000000000000000000000000000001",
        +		"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
        +		"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
        +		"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
        +		1,
        +		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
        +		"2",
        +		283,
        +		C2_B283
        +		);
        +
        +	/* Curve K-409 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-409",
        +		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
        +		"0",
        +		"1",
        +		"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
        +		"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
        +		1,
        +		"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
        +		"4",
        +		409,
        +		C2_K409
        +		);
        +
        +	/* Curve B-409 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-409",
        +		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
        +		"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
        +		"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
        +		"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
        +		"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
        +		1,
        +		"010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
        +		"2",
        +		409,
        +		C2_B409
        +		);
        +
        +	/* Curve K-571 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-571",
        +		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
        +		"0",
        +		"1",
        +		"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
        +		"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
        +		0,
        +		"020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
        +		"4",
        +		571,
        +		C2_K571
        +		);
        +
        +	/* Curve B-571 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-571",
        +		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
        +		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
        +		"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
        +		"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
        +		"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
        +		1,
        +		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
        +		"2",
        +		571,
        +		C2_B571
        +		);
        +
        +	/* more tests using the last curve */
        +
        +	if (!EC_POINT_copy(Q, P)) ABORT;
        +	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
        +
        +	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
        +
        +	{
        +		const EC_POINT *points[3];
        +		const BIGNUM *scalars[3];
        +	
        +		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +		points[0] = Q;
        +		points[1] = Q;
        +		points[2] = Q;
        +
        +		if (!BN_add(y, z, BN_value_one())) ABORT;
        +		if (BN_is_odd(y)) ABORT;
        +		if (!BN_rshift1(y, y)) ABORT;
        +		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
        +		scalars[1] = y;
        +
        +		fprintf(stdout, "combined multiplication ...");
        +		fflush(stdout);
        +
        +		/* z is still the group order */
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
        +		if (!BN_add(z, z, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = y;
        +		scalars[1] = z; /* z = -(order + y) */
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
        +		if (!BN_add(z, x, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = x;
        +		scalars[1] = y;
        +		scalars[2] = z; /* z = -(x+y) */
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, " ok\n\n");
        +	}
        +
        +
        +#if 0
        +	timings(C2_K163, TIMING_BASE_PT, ctx);
        +	timings(C2_K163, TIMING_RAND_PT, ctx);
        +	timings(C2_K163, TIMING_SIMUL, ctx);
        +	timings(C2_B163, TIMING_BASE_PT, ctx);
        +	timings(C2_B163, TIMING_RAND_PT, ctx);
        +	timings(C2_B163, TIMING_SIMUL, ctx);
        +	timings(C2_K233, TIMING_BASE_PT, ctx);
        +	timings(C2_K233, TIMING_RAND_PT, ctx);
        +	timings(C2_K233, TIMING_SIMUL, ctx);
        +	timings(C2_B233, TIMING_BASE_PT, ctx);
        +	timings(C2_B233, TIMING_RAND_PT, ctx);
        +	timings(C2_B233, TIMING_SIMUL, ctx);
        +	timings(C2_K283, TIMING_BASE_PT, ctx);
        +	timings(C2_K283, TIMING_RAND_PT, ctx);
        +	timings(C2_K283, TIMING_SIMUL, ctx);
        +	timings(C2_B283, TIMING_BASE_PT, ctx);
        +	timings(C2_B283, TIMING_RAND_PT, ctx);
        +	timings(C2_B283, TIMING_SIMUL, ctx);
        +	timings(C2_K409, TIMING_BASE_PT, ctx);
        +	timings(C2_K409, TIMING_RAND_PT, ctx);
        +	timings(C2_K409, TIMING_SIMUL, ctx);
        +	timings(C2_B409, TIMING_BASE_PT, ctx);
        +	timings(C2_B409, TIMING_RAND_PT, ctx);
        +	timings(C2_B409, TIMING_SIMUL, ctx);
        +	timings(C2_K571, TIMING_BASE_PT, ctx);
        +	timings(C2_K571, TIMING_RAND_PT, ctx);
        +	timings(C2_K571, TIMING_SIMUL, ctx);
        +	timings(C2_B571, TIMING_BASE_PT, ctx);
        +	timings(C2_B571, TIMING_RAND_PT, ctx);
        +	timings(C2_B571, TIMING_SIMUL, ctx);
        +#endif
        +
        +
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	BN_free(p); BN_free(a);	BN_free(b);
        +	EC_GROUP_free(group);
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	EC_POINT_free(R);
        +	BN_free(x); BN_free(y); BN_free(z); BN_free(cof);
        +
        +	if (C2_K163) EC_GROUP_free(C2_K163);
        +	if (C2_B163) EC_GROUP_free(C2_B163);
        +	if (C2_K233) EC_GROUP_free(C2_K233);
        +	if (C2_B233) EC_GROUP_free(C2_B233);
        +	if (C2_K283) EC_GROUP_free(C2_K283);
        +	if (C2_B283) EC_GROUP_free(C2_B283);
        +	if (C2_K409) EC_GROUP_free(C2_K409);
        +	if (C2_B409) EC_GROUP_free(C2_B409);
        +	if (C2_K571) EC_GROUP_free(C2_K571);
        +	if (C2_B571) EC_GROUP_free(C2_B571);
        +
        +	}
        +#endif
        +
        +static void internal_curve_test(void)
        +	{
        +	EC_builtin_curve *curves = NULL;
        +	size_t crv_len = 0, n = 0;
        +	int    ok = 1;
        +
        +	crv_len = EC_get_builtin_curves(NULL, 0);
        +
        +	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
        +
        +	if (curves == NULL)
        +		return;
        +
        +	if (!EC_get_builtin_curves(curves, crv_len))
        +		{
        +		OPENSSL_free(curves);
        +		return;
        +		}
        +
        +	fprintf(stdout, "testing internal curves: ");
        +		
        +	for (n = 0; n < crv_len; n++)
        +		{
        +		EC_GROUP *group = NULL;
        +		int nid = curves[n].nid;
        +		if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
        +			{
        +			ok = 0;
        +			fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
        +				" curve %s\n", OBJ_nid2sn(nid));
        +			/* try next curve */
        +			continue;
        +			}
        +		if (!EC_GROUP_check(group, NULL))
        +			{
        +			ok = 0;
        +			fprintf(stdout, "\nEC_GROUP_check() failed with"
        +				" curve %s\n", OBJ_nid2sn(nid));
        +			EC_GROUP_free(group);
        +			/* try the next curve */
        +			continue;
        +			}
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +		EC_GROUP_free(group);
        +		}
        +	if (ok)
        +		fprintf(stdout, " ok\n\n");
        +	else
        +		{
        +		fprintf(stdout, " failed\n\n");
        +		ABORT;
        +		}
        +	OPENSSL_free(curves);
        +	return;
        +	}
        +
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +/* nistp_test_params contains magic numbers for testing our optimized
        + * implementations of several NIST curves with characteristic > 3. */
        +struct nistp_test_params
        +	{
        +	const EC_METHOD* (*meth) ();
        +	int degree;
        +	/* Qx, Qy and D are taken from
        +	 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
        +	 * Otherwise, values are standard curve parameters from FIPS 180-3 */
        +	const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
        +	};
        +
        +static const struct nistp_test_params nistp_tests_params[] =
        +	{
        +		{
        +		/* P-224 */
        +		EC_GFp_nistp224_method,
        +		224,
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */
        +		"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */
        +		"E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */
        +		"4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */
        +		"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
        +		"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
        +		"3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */
        +		},
        +		{
        +		/* P-256 */
        +		EC_GFp_nistp256_method,
        +		256,
        +		"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */
        +		"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */
        +		"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */
        +		"b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */
        +		"3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */
        +		"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */
        +		"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */
        +		"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */
        +		"c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */
        +		},
        +		{
        +		/* P-521 */
        +		EC_GFp_nistp521_method,
        +		521,
        +		"1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */
        +		"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */
        +		"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */
        +		"0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */
        +		"0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */
        +		"c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */
        +		"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */
        +		"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */
        +		"0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */
        +		},
        +	};
        +
        +void nistp_single_test(const struct nistp_test_params *test)
        +	{
        +	BN_CTX *ctx;
        +	BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
        +	EC_GROUP *NISTP;
        +	EC_POINT *G, *P, *Q, *Q_CHECK;
        +
        +	fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree);
        +	ctx = BN_CTX_new();
        +	p = BN_new();
        +	a = BN_new();
        +	b = BN_new();
        +	x = BN_new(); y = BN_new();
        +	m = BN_new(); n = BN_new(); order = BN_new();
        +
        +	NISTP = EC_GROUP_new(test->meth());
        +	if(!NISTP) ABORT;
        +	if (!BN_hex2bn(&p, test->p)) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, test->a)) ABORT;
        +	if (!BN_hex2bn(&b, test->b)) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) ABORT;
        +	G = EC_POINT_new(NISTP);
        +	P = EC_POINT_new(NISTP);
        +	Q = EC_POINT_new(NISTP);
        +	Q_CHECK = EC_POINT_new(NISTP);
        +	if(!BN_hex2bn(&x, test->Qx)) ABORT;
        +	if(!BN_hex2bn(&y, test->Qy)) ABORT;
        +	if(!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) ABORT;
        +	if (!BN_hex2bn(&x, test->Gx)) ABORT;
        +	if (!BN_hex2bn(&y, test->Gy)) ABORT;
        +	if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) ABORT;
        +	if (!BN_hex2bn(&order, test->order)) ABORT;
        +	if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
        +
        +	fprintf(stdout, "verify degree ... ");
        +	if (EC_GROUP_get_degree(NISTP) != test->degree) ABORT;
        +	fprintf(stdout, "ok\n");
        +
        +	fprintf(stdout, "NIST test vectors ... ");
        +	if (!BN_hex2bn(&n, test->d)) ABORT;
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	/* set generator to P = 2*G, where G is the standard generator */
        +	if (!EC_POINT_dbl(NISTP, P, G, ctx)) ABORT;
        +	if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) ABORT;
        +	/* set the scalar to m=n/2, where n is the NIST test scalar */
        +	if (!BN_rshift(m, n, 1)) ABORT;
        +
        +	/* test the non-standard generator */
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	/* now repeat all tests with precomputation */
        +	if (!EC_GROUP_precompute_mult(NISTP, ctx)) ABORT;
        +
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	/* reset generator */
        +	if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	fprintf(stdout, "ok\n");
        +	group_order_tests(NISTP);
        +#if 0
        +	timings(NISTP, TIMING_BASE_PT, ctx);
        +	timings(NISTP, TIMING_RAND_PT, ctx);
        +#endif
        +	EC_GROUP_free(NISTP);
        +	EC_POINT_free(G);
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	EC_POINT_free(Q_CHECK);
        +	BN_free(n);
        +	BN_free(m);
        +	BN_free(p);
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(x);
        +	BN_free(y);
        +	BN_free(order);
        +	BN_CTX_free(ctx);
        +	}
        +
        +void nistp_tests()
        +	{
        +	unsigned i;
        +
        +	for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++)
        +		{
        +		nistp_single_test(&nistp_tests_params[i]);
        +		}
        +	}
        +#endif
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +	{	
        +	
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +	ERR_load_crypto_strings();
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
        +
        +	prime_field_tests();
        +	puts("");
        +#ifndef OPENSSL_NO_EC2M
        +	char2_field_tests();
        +#endif
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +	nistp_tests();
        +#endif
        +	/* test the internal curves */
        +	internal_curve_test();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_cleanup();
        +#endif
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_free_strings();
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks_fp(stderr);
        +	
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ecdh/Makefile b/vendor/openssl/openssl/crypto/ecdh/Makefile
        new file mode 100644
        index 000000000..ba05fea05
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/Makefile
        @@ -0,0 +1,116 @@
        +#
        +# crypto/ecdh/Makefile
        +#
        +
        +DIR=	ecdh
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g -Wall
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=ecdhtest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	ech_lib.c ech_ossl.c ech_key.c ech_err.c
        +
        +LIBOBJ=	ech_lib.o ech_ossl.o ech_key.o ech_err.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ecdh.h
        +HEADER=	ech_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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +ech_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ech_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ech_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ech_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ech_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ech_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ech_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ech_err.o: ech_err.c
        +ech_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ech_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ech_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ech_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ech_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ech_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ech_key.o: ech_key.c ech_locl.h
        +ech_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ech_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ech_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ech_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ech_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +ech_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ech_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ech_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ech_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ech_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ech_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ech_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ech_lib.o: ech_lib.c ech_locl.h
        +ech_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
        +ech_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +ech_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ech_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ech_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/err.h
        +ech_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ech_ossl.o: ../../include/openssl/opensslconf.h
        +ech_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ech_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ech_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ech_ossl.o: ../cryptlib.h ech_locl.h ech_ossl.c
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ecdh.h b/vendor/openssl/openssl/crypto/ecdh/ecdh.h
        new file mode 100644
        index 000000000..8887102c0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ecdh.h
        @@ -0,0 +1,125 @@
        +/* crypto/ecdh/ecdh.h */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH software is originally written by Douglas Stebila of
        + * Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +#ifndef HEADER_ECDH_H
        +#define HEADER_ECDH_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_ECDH
        +#error ECDH is disabled.
        +#endif
        +
        +#include <openssl/ec.h>
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#endif
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +const ECDH_METHOD *ECDH_OpenSSL(void);
        +
        +void	  ECDH_set_default_method(const ECDH_METHOD *);
        +const ECDH_METHOD *ECDH_get_default_method(void);
        +int 	  ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
        +
        +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
        +                     void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
        +
        +int 	  ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
        +		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int 	  ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
        +void 	  *ECDH_get_ex_data(EC_KEY *d, int idx);
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_ECDH_strings(void);
        +
        +/* Error codes for the ECDH functions. */
        +
        +/* Function codes. */
        +#define ECDH_F_ECDH_CHECK				 102
        +#define ECDH_F_ECDH_COMPUTE_KEY				 100
        +#define ECDH_F_ECDH_DATA_NEW_METHOD			 101
        +
        +/* Reason codes. */
        +#define ECDH_R_KDF_FAILED				 102
        +#define ECDH_R_NON_FIPS_METHOD				 103
        +#define ECDH_R_NO_PRIVATE_VALUE				 100
        +#define ECDH_R_POINT_ARITHMETIC_FAILURE			 101
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ecdhtest.c b/vendor/openssl/openssl/crypto/ecdh/ecdhtest.c
        new file mode 100644
        index 000000000..823d7baa6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ecdhtest.c
        @@ -0,0 +1,374 @@
        +/* crypto/ecdh/ecdhtest.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH software is originally written by Douglas Stebila of
        + * Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/opensslconf.h>	/* for OPENSSL_NO_ECDH */
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/sha.h>
        +#include <openssl/err.h>
        +
        +#ifdef OPENSSL_NO_ECDH
        +int main(int argc, char *argv[])
        +{
        +    printf("No ECDH support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/ec.h>
        +#include <openssl/ecdh.h>
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define MS_CALLBACK	_far _loadds
        +#else
        +#define MS_CALLBACK
        +#endif
        +
        +#if 0
        +static void MS_CALLBACK cb(int p, int n, void *arg);
        +#endif
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +
        +static const int KDF1_SHA1_len = 20;
        +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
        +	{
        +#ifndef OPENSSL_NO_SHA
        +	if (*outlen < SHA_DIGEST_LENGTH)
        +		return NULL;
        +	else
        +		*outlen = SHA_DIGEST_LENGTH;
        +	return SHA1(in, inlen, out);
        +#else
        +	return NULL;
        +#endif
        +	}
        +
        +
        +static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
        +	{
        +	EC_KEY *a=NULL;
        +	EC_KEY *b=NULL;
        +	BIGNUM *x_a=NULL, *y_a=NULL,
        +	       *x_b=NULL, *y_b=NULL;
        +	char buf[12];
        +	unsigned char *abuf=NULL,*bbuf=NULL;
        +	int i,alen,blen,aout,bout,ret=0;
        +	const EC_GROUP *group;
        +
        +	a = EC_KEY_new_by_curve_name(nid);
        +	b = EC_KEY_new_by_curve_name(nid);
        +	if (a == NULL || b == NULL)
        +		goto err;
        +
        +	group = EC_KEY_get0_group(a);
        +
        +	if ((x_a=BN_new()) == NULL) goto err;
        +	if ((y_a=BN_new()) == NULL) goto err;
        +	if ((x_b=BN_new()) == NULL) goto err;
        +	if ((y_b=BN_new()) == NULL) goto err;
        +
        +	BIO_puts(out,"Testing key generation with ");
        +	BIO_puts(out,text);
        +#ifdef NOISY
        +	BIO_puts(out,"\n");
        +#else
        +	(void)BIO_flush(out);
        +#endif
        +
        +	if (!EC_KEY_generate_key(a)) goto err;
        +	
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group,
        +			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group,
        +			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
        +		}
        +#endif
        +#ifdef NOISY
        +	BIO_puts(out,"  pri 1=");
        +	BN_print(out,a->priv_key);
        +	BIO_puts(out,"\n  pub 1=");
        +	BN_print(out,x_a);
        +	BIO_puts(out,",");
        +	BN_print(out,y_a);
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out," .");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	if (!EC_KEY_generate_key(b)) goto err;
        +
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group, 
        +			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, 
        +			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
        +		}
        +#endif
        +
        +#ifdef NOISY
        +	BIO_puts(out,"  pri 2=");
        +	BN_print(out,b->priv_key);
        +	BIO_puts(out,"\n  pub 2=");
        +	BN_print(out,x_b);
        +	BIO_puts(out,",");
        +	BN_print(out,y_b);
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out,".");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	alen=KDF1_SHA1_len;
        +	abuf=(unsigned char *)OPENSSL_malloc(alen);
        +	aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);
        +
        +#ifdef NOISY
        +	BIO_puts(out,"  key1 =");
        +	for (i=0; i<aout; i++)
        +		{
        +		sprintf(buf,"%02X",abuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out,".");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	blen=KDF1_SHA1_len;
        +	bbuf=(unsigned char *)OPENSSL_malloc(blen);
        +	bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);
        +
        +#ifdef NOISY
        +	BIO_puts(out,"  key2 =");
        +	for (i=0; i<bout; i++)
        +		{
        +		sprintf(buf,"%02X",bbuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out,".");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
        +		{
        +#ifndef NOISY
        +		BIO_printf(out, " failed\n\n");
        +		BIO_printf(out, "key a:\n");
        +		BIO_printf(out, "private key: ");
        +		BN_print(out, EC_KEY_get0_private_key(a));
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "public key (x,y): ");
        +		BN_print(out, x_a);
        +		BIO_printf(out, ",");
        +		BN_print(out, y_a);
        +		BIO_printf(out, "\nkey b:\n");
        +		BIO_printf(out, "private key: ");
        +		BN_print(out, EC_KEY_get0_private_key(b));
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "public key (x,y): ");
        +		BN_print(out, x_b);
        +		BIO_printf(out, ",");
        +		BN_print(out, y_b);
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "generated key a: ");
        +		for (i=0; i<bout; i++)
        +			{
        +			sprintf(buf, "%02X", bbuf[i]);
        +			BIO_puts(out, buf);
        +			}
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "generated key b: ");
        +		for (i=0; i<aout; i++)
        +			{
        +			sprintf(buf, "%02X", abuf[i]);
        +			BIO_puts(out,buf);
        +			}
        +		BIO_printf(out, "\n");
        +#endif
        +		fprintf(stderr,"Error in ECDH routines\n");
        +		ret=0;
        +		}
        +	else
        +		{
        +#ifndef NOISY
        +		BIO_printf(out, " ok\n");
        +#endif
        +		ret=1;
        +		}
        +err:
        +	ERR_print_errors_fp(stderr);
        +
        +	if (abuf != NULL) OPENSSL_free(abuf);
        +	if (bbuf != NULL) OPENSSL_free(bbuf);
        +	if (x_a) BN_free(x_a);
        +	if (y_a) BN_free(y_a);
        +	if (x_b) BN_free(x_b);
        +	if (y_b) BN_free(y_b);
        +	if (b) EC_KEY_free(b);
        +	if (a) EC_KEY_free(a);
        +	return(ret);
        +	}
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_CTX *ctx=NULL;
        +	int ret=1;
        +	BIO *out;
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +#ifdef OPENSSL_SYS_WIN32
        +	CRYPTO_malloc_init();
        +#endif
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) EXIT(1);
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +
        +	if ((ctx=BN_CTX_new()) == NULL) goto err;
        +
        +	/* NIST PRIME CURVES TESTS */
        +	if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
        +#ifndef OPENSSL_NO_EC2M
        +	/* NIST BINARY CURVES TESTS */
        +	if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
        +#endif
        +
        +	ret = 0;
        +
        +err:
        +	ERR_print_errors_fp(stderr);
        +	if (ctx) BN_CTX_free(ctx);
        +	BIO_free(out);
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks_fp(stderr);
        +	EXIT(ret);
        +	return(ret);
        +	}
        +
        +#if 0
        +static void MS_CALLBACK cb(int p, int n, void *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write((BIO *)arg,&c,1);
        +	(void)BIO_flush((BIO *)arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ech_err.c b/vendor/openssl/openssl/crypto/ecdh/ech_err.c
        new file mode 100644
        index 000000000..3bd247398
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ech_err.c
        @@ -0,0 +1,100 @@
        +/* crypto/ecdh/ech_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ecdh.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason)
        +
        +static ERR_STRING_DATA ECDH_str_functs[]=
        +	{
        +{ERR_FUNC(ECDH_F_ECDH_CHECK),	"ECDH_CHECK"},
        +{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY),	"ECDH_compute_key"},
        +{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),	"ECDH_DATA_new_method"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ECDH_str_reasons[]=
        +	{
        +{ERR_REASON(ECDH_R_KDF_FAILED)           ,"KDF failed"},
        +{ERR_REASON(ECDH_R_NON_FIPS_METHOD)      ,"non fips method"},
        +{ERR_REASON(ECDH_R_NO_PRIVATE_VALUE)     ,"no private value"},
        +{ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE),"point arithmetic failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_ECDH_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,ECDH_str_functs);
        +		ERR_load_strings(0,ECDH_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ech_key.c b/vendor/openssl/openssl/crypto/ecdh/ech_key.c
        new file mode 100644
        index 000000000..2988899ea
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ech_key.c
        @@ -0,0 +1,80 @@
        +/* crypto/ecdh/ecdh_key.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH software is originally written by Douglas Stebila of
        + * Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "ech_locl.h"
        +
        +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
        +	EC_KEY *eckey,
        +	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
        +{
        +	ECDH_DATA *ecdh = ecdh_check(eckey);
        +	if (ecdh == NULL)
        +		return 0;
        +	return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF);
        +}
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ech_lib.c b/vendor/openssl/openssl/crypto/ecdh/ech_lib.c
        new file mode 100644
        index 000000000..0644431b7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ech_lib.c
        @@ -0,0 +1,273 @@
        +/* crypto/ecdh/ech_lib.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH software is originally written by Douglas Stebila of
        + * Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "ech_locl.h"
        +#include <string.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
        +
        +static const ECDH_METHOD *default_ECDH_method = NULL;
        +
        +static void *ecdh_data_new(void);
        +static void *ecdh_data_dup(void *);
        +static void  ecdh_data_free(void *);
        +
        +void ECDH_set_default_method(const ECDH_METHOD *meth)
        +	{
        +	default_ECDH_method = meth;
        +	}
        +
        +const ECDH_METHOD *ECDH_get_default_method(void)
        +	{
        +	if(!default_ECDH_method) 
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return FIPS_ecdh_openssl();
        +		else
        +			return ECDH_OpenSSL();
        +#else
        +		default_ECDH_method = ECDH_OpenSSL();
        +#endif
        +		}
        +	return default_ECDH_method;
        +	}
        +
        +int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
        +	{
        +	ECDH_DATA *ecdh;
        +
        +	ecdh = ecdh_check(eckey);
        +
        +	if (ecdh == NULL)
        +		return 0;
        +
        +#if 0
        +        mtmp = ecdh->meth;
        +        if (mtmp->finish)
        +		mtmp->finish(eckey);
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +	if (ecdh->engine)
        +		{
        +		ENGINE_finish(ecdh->engine);
        +		ecdh->engine = NULL;
        +		}
        +#endif
        +        ecdh->meth = meth;
        +#if 0
        +        if (meth->init) 
        +		meth->init(eckey);
        +#endif
        +        return 1;
        +	}
        +
        +static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
        +	{
        +	ECDH_DATA *ret;
        +
        +	ret=(ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA));
        +	if (ret == NULL)
        +		{
        +		ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +
        +	ret->init = NULL;
        +
        +	ret->meth = ECDH_get_default_method();
        +	ret->engine = engine;
        +#ifndef OPENSSL_NO_ENGINE
        +	if (!ret->engine)
        +		ret->engine = ENGINE_get_default_ECDH();
        +	if (ret->engine)
        +		{
        +		ret->meth = ENGINE_get_ECDH(ret->engine);
        +		if (!ret->meth)
        +			{
        +			ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
        +			ENGINE_finish(ret->engine);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		}
        +#endif
        +
        +	ret->flags = ret->meth->flags;
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
        +#if 0
        +	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
        +		{
        +		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +		}
        +#endif	
        +	return(ret);
        +	}
        +
        +static void *ecdh_data_new(void)
        +	{
        +	return (void *)ECDH_DATA_new_method(NULL);
        +	}
        +
        +static void *ecdh_data_dup(void *data)
        +{
        +	ECDH_DATA *r = (ECDH_DATA *)data;
        +
        +	/* XXX: dummy operation */
        +	if (r == NULL)
        +		return NULL;
        +
        +	return (void *)ecdh_data_new();
        +}
        +
        +void ecdh_data_free(void *data)
        +	{
        +	ECDH_DATA *r = (ECDH_DATA *)data;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	if (r->engine)
        +		ENGINE_finish(r->engine);
        +#endif
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data);
        +
        +	OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA));
        +
        +	OPENSSL_free(r);
        +	}
        +
        +ECDH_DATA *ecdh_check(EC_KEY *key)
        +	{
        +	ECDH_DATA *ecdh_data;
        + 
        +	void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
        +					ecdh_data_free, ecdh_data_free);
        +	if (data == NULL)
        +	{
        +		ecdh_data = (ECDH_DATA *)ecdh_data_new();
        +		if (ecdh_data == NULL)
        +			return NULL;
        +		data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
        +			   ecdh_data_dup, ecdh_data_free, ecdh_data_free);
        +		if (data != NULL)
        +			{
        +			/* Another thread raced us to install the key_method
        +			 * data and won. */
        +			ecdh_data_free(ecdh_data);
        +			ecdh_data = (ECDH_DATA *)data;
        +			}
        +	}
        +	else
        +		ecdh_data = (ECDH_DATA *)data;
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD)
        +			&& !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW))
        +		{
        +		ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD);
        +		return NULL;
        +		}
        +#endif
        +	
        +
        +	return ecdh_data;
        +	}
        +
        +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +	{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp,
        +				new_func, dup_func, free_func);
        +	}
        +
        +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg)
        +	{
        +	ECDH_DATA *ecdh;
        +	ecdh = ecdh_check(d);
        +	if (ecdh == NULL)
        +		return 0;
        +	return(CRYPTO_set_ex_data(&ecdh->ex_data,idx,arg));
        +	}
        +
        +void *ECDH_get_ex_data(EC_KEY *d, int idx)
        +	{
        +	ECDH_DATA *ecdh;
        +	ecdh = ecdh_check(d);
        +	if (ecdh == NULL)
        +		return NULL;
        +	return(CRYPTO_get_ex_data(&ecdh->ex_data,idx));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ech_locl.h b/vendor/openssl/openssl/crypto/ecdh/ech_locl.h
        new file mode 100644
        index 000000000..f6cad6a89
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ech_locl.h
        @@ -0,0 +1,102 @@
        +/* crypto/ecdh/ech_locl.h */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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_ECH_LOCL_H
        +#define HEADER_ECH_LOCL_H
        +
        +#include <openssl/ecdh.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +struct ecdh_method 
        +	{
        +	const char *name;
        +	int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
        +	                   void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
        +#if 0
        +	int (*init)(EC_KEY *eckey);
        +	int (*finish)(EC_KEY *eckey);
        +#endif
        +	int flags;
        +	char *app_data;
        +	};
        +
        +/* If this flag is set the ECDH method is FIPS compliant and can be used
        + * in FIPS mode. This is set in the validated module method. If an
        + * application sets this flag in its own methods it is its responsibility
        + * to ensure the result is compliant.
        + */
        +
        +#define ECDH_FLAG_FIPS_METHOD	0x1
        +
        +typedef struct ecdh_data_st {
        +	/* EC_KEY_METH_DATA part */
        +	int (*init)(EC_KEY *);
        +	/* method specific part */
        +	ENGINE	*engine;
        +	int	flags;
        +	const ECDH_METHOD *meth;
        +	CRYPTO_EX_DATA ex_data;
        +} ECDH_DATA;
        +
        +ECDH_DATA *ecdh_check(EC_KEY *);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* HEADER_ECH_LOCL_H */
        diff --git a/vendor/openssl/openssl/crypto/ecdh/ech_ossl.c b/vendor/openssl/openssl/crypto/ecdh/ech_ossl.c
        new file mode 100644
        index 000000000..4a30628fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdh/ech_ossl.c
        @@ -0,0 +1,215 @@
        +/* crypto/ecdh/ech_ossl.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH software is originally written by Douglas Stebila of
        + * Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <string.h>
        +#include <limits.h>
        +
        +#include "cryptlib.h"
        +
        +#include "ech_locl.h"
        +#include <openssl/err.h>
        +#include <openssl/sha.h>
        +#include <openssl/obj_mac.h>
        +#include <openssl/bn.h>
        +
        +static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key,
        +	EC_KEY *ecdh, 
        +	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
        +
        +static ECDH_METHOD openssl_ecdh_meth = {
        +	"OpenSSL ECDH method",
        +	ecdh_compute_key,
        +#if 0
        +	NULL, /* init     */
        +	NULL, /* finish   */
        +#endif
        +	0,    /* flags    */
        +	NULL  /* app_data */
        +};
        +
        +const ECDH_METHOD *ECDH_OpenSSL(void)
        +	{
        +	return &openssl_ecdh_meth;
        +	}
        +
        +
        +/* This implementation is based on the following primitives in the IEEE 1363 standard:
        + *  - ECKAS-DH1
        + *  - ECSVDP-DH
        + * Finally an optional KDF is applied.
        + */
        +static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
        +	EC_KEY *ecdh,
        +	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
        +	{
        +	BN_CTX *ctx;
        +	EC_POINT *tmp=NULL;
        +	BIGNUM *x=NULL, *y=NULL;
        +	const BIGNUM *priv_key;
        +	const EC_GROUP* group;
        +	int ret= -1;
        +	size_t buflen, len;
        +	unsigned char *buf=NULL;
        +
        +	if (outlen > INT_MAX)
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
        +		return -1;
        +		}
        +
        +	if ((ctx = BN_CTX_new()) == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	x = BN_CTX_get(ctx);
        +	y = BN_CTX_get(ctx);
        +	
        +	priv_key = EC_KEY_get0_private_key(ecdh);
        +	if (priv_key == NULL)
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
        +		goto err;
        +		}
        +
        +	group = EC_KEY_get0_group(ecdh);
        +	if ((tmp=EC_POINT_new(group)) == NULL)
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) 
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
        +		goto err;
        +		}
        +		
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) 
        +			{
        +			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
        +			goto err;
        +			}
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) 
        +			{
        +			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
        +			goto err;
        +			}
        +		}
        +#endif
        +
        +	buflen = (EC_GROUP_get_degree(group) + 7)/8;
        +	len = BN_num_bytes(x);
        +	if (len > buflen)
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +	if ((buf = OPENSSL_malloc(buflen)) == NULL)
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	
        +	memset(buf, 0, buflen - len);
        +	if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
        +		{
        +		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
        +		goto err;
        +		}
        +
        +	if (KDF != 0)
        +		{
        +		if (KDF(buf, buflen, out, &outlen) == NULL)
        +			{
        +			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
        +			goto err;
        +			}
        +		ret = outlen;
        +		}
        +	else
        +		{
        +		/* no KDF, just copy as much as we can */
        +		if (outlen > buflen)
        +			outlen = buflen;
        +		memcpy(out, buf, outlen);
        +		ret = outlen;
        +		}
        +	
        +err:
        +	if (tmp) EC_POINT_free(tmp);
        +	if (ctx) BN_CTX_end(ctx);
        +	if (ctx) BN_CTX_free(ctx);
        +	if (buf) OPENSSL_free(buf);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/Makefile b/vendor/openssl/openssl/crypto/ecdsa/Makefile
        new file mode 100644
        index 000000000..e89e0c010
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/Makefile
        @@ -0,0 +1,140 @@
        +#
        +# crypto/ecdsa/Makefile
        +#
        +
        +DIR=	ecdsa
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g -Wall
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=ecdsatest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	ecs_lib.c ecs_asn1.c ecs_ossl.c ecs_sign.c ecs_vrf.c ecs_err.c
        +
        +LIBOBJ=	ecs_lib.o ecs_asn1.o ecs_ossl.o ecs_sign.o ecs_vrf.o ecs_err.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ecdsa.h
        +HEADER=	ecs_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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +ecs_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +ecs_asn1.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +ecs_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecs_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ecs_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +ecs_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecs_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecs_asn1.o: ../../include/openssl/symhacks.h ecs_asn1.c ecs_locl.h
        +ecs_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecs_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ecs_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h
        +ecs_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +ecs_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ecs_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ecs_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ecs_err.o: ecs_err.c
        +ecs_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecs_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +ecs_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ecs_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ecs_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +ecs_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ecs_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ecs_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ecs_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecs_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ecs_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ecs_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ecs_lib.o: ../../include/openssl/x509_vfy.h ecs_lib.c ecs_locl.h
        +ecs_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecs_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +ecs_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecs_ossl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ecs_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ecs_ossl.o: ../../include/openssl/opensslconf.h
        +ecs_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecs_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ecs_ossl.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_ossl.c
        +ecs_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecs_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ecs_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecs_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ecs_sign.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
        +ecs_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ecs_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ecs_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecs_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ecs_sign.o: ecs_locl.h ecs_sign.c
        +ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
        +ecs_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ecs_vrf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ecs_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ecs_vrf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ecs_vrf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ecs_vrf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ecs_vrf.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_vrf.c
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecdsa.h b/vendor/openssl/openssl/crypto/ecdsa/ecdsa.h
        new file mode 100644
        index 000000000..7fb5254b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecdsa.h
        @@ -0,0 +1,260 @@
        +/* crypto/ecdsa/ecdsa.h */
        +/**
        + * \file   crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
        + * \author Written by Nils Larsch for the OpenSSL project
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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_ECDSA_H
        +#define HEADER_ECDSA_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_ECDSA
        +#error ECDSA is disabled.
        +#endif
        +
        +#include <openssl/ec.h>
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#endif
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct ECDSA_SIG_st
        +	{
        +	BIGNUM *r;
        +	BIGNUM *s;
        +	} ECDSA_SIG;
        +
        +/** Allocates and initialize a ECDSA_SIG structure
        + *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
        + */
        +ECDSA_SIG *ECDSA_SIG_new(void);
        +
        +/** frees a ECDSA_SIG structure
        + *  \param  sig  pointer to the ECDSA_SIG structure
        + */
        +void	  ECDSA_SIG_free(ECDSA_SIG *sig);
        +
        +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
        + *  (*pp += length of the DER encoded signature)).
        + *  \param  sig  pointer to the ECDSA_SIG object
        + *  \param  pp   pointer to a unsigned char pointer for the output or NULL
        + *  \return the length of the DER encoded ECDSA_SIG object or 0 
        + */
        +int	  i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
        +
        +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
        + *  (*pp += len)). 
        + *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
        + *  \param  pp   memory buffer with the DER encoded signature
        + *  \param  len  length of the buffer
        + *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
        + */
        +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
        +
        +/** Computes the ECDSA signature of the given hash value using
        + *  the supplied private key and returns the created signature.
        + *  \param  dgst      pointer to the hash value
        + *  \param  dgst_len  length of the hash value
        + *  \param  eckey     EC_KEY object containing a private EC key
        + *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
        + */
        +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
        +
        +/** Computes ECDSA signature of a given hash value using the supplied
        + *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
        + *  \param  dgst     pointer to the hash value to sign
        + *  \param  dgstlen  length of the hash value
        + *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
        + *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
        + *                   see ECDSA_sign_setup
        + *  \param  eckey    EC_KEY object containing a private EC key
        + *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
        + */
        +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
        +		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
        +
        +/** Verifies that the supplied signature is a valid ECDSA
        + *  signature of the supplied hash value using the supplied public key.
        + *  \param  dgst      pointer to the hash value
        + *  \param  dgst_len  length of the hash value
        + *  \param  sig       ECDSA_SIG structure
        + *  \param  eckey     EC_KEY object containing a public EC key
        + *  \return 1 if the signature is valid, 0 if the signature is invalid
        + *          and -1 on error
        + */
        +int	  ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
        +		const ECDSA_SIG *sig, EC_KEY* eckey);
        +
        +const ECDSA_METHOD *ECDSA_OpenSSL(void);
        +
        +/** Sets the default ECDSA method
        + *  \param  meth  new default ECDSA_METHOD
        + */
        +void	  ECDSA_set_default_method(const ECDSA_METHOD *meth);
        +
        +/** Returns the default ECDSA method
        + *  \return pointer to ECDSA_METHOD structure containing the default method
        + */
        +const ECDSA_METHOD *ECDSA_get_default_method(void);
        +
        +/** Sets method to be used for the ECDSA operations
        + *  \param  eckey  EC_KEY object
        + *  \param  meth   new method
        + *  \return 1 on success and 0 otherwise 
        + */
        +int 	  ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
        +
        +/** Returns the maximum length of the DER encoded signature
        + *  \param  eckey  EC_KEY object
        + *  \return numbers of bytes required for the DER encoded signature
        + */
        +int	  ECDSA_size(const EC_KEY *eckey);
        +
        +/** Precompute parts of the signing operation
        + *  \param  eckey  EC_KEY object containing a private EC key
        + *  \param  ctx    BN_CTX object (optional)
        + *  \param  kinv   BIGNUM pointer for the inverse of k
        + *  \param  rp     BIGNUM pointer for x coordinate of k * generator
        + *  \return 1 on success and 0 otherwise
        + */
        +int 	  ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
        +		BIGNUM **rp);
        +
        +/** Computes ECDSA signature of a given hash value using the supplied
        + *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
        + *  \param  type     this parameter is ignored
        + *  \param  dgst     pointer to the hash value to sign
        + *  \param  dgstlen  length of the hash value
        + *  \param  sig      memory for the DER encoded created signature
        + *  \param  siglen   pointer to the length of the returned signature
        + *  \param  eckey    EC_KEY object containing a private EC key
        + *  \return 1 on success and 0 otherwise
        + */
        +int	  ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 
        +		unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
        +
        +
        +/** Computes ECDSA signature of a given hash value using the supplied
        + *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
        + *  \param  type     this parameter is ignored
        + *  \param  dgst     pointer to the hash value to sign
        + *  \param  dgstlen  length of the hash value
        + *  \param  sig      buffer to hold the DER encoded signature
        + *  \param  siglen   pointer to the length of the returned signature
        + *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
        + *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
        + *                   see ECDSA_sign_setup
        + *  \param  eckey    EC_KEY object containing a private EC key
        + *  \return 1 on success and 0 otherwise
        + */
        +int	  ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 
        +		unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
        +		const BIGNUM *rp, EC_KEY *eckey);
        +
        +/** Verifies that the given signature is valid ECDSA signature
        + *  of the supplied hash value using the specified public key.
        + *  \param  type     this parameter is ignored
        + *  \param  dgst     pointer to the hash value 
        + *  \param  dgstlen  length of the hash value
        + *  \param  sig      pointer to the DER encoded signature
        + *  \param  siglen   length of the DER encoded signature
        + *  \param  eckey    EC_KEY object containing a public EC key
        + *  \return 1 if the signature is valid, 0 if the signature is invalid
        + *          and -1 on error
        + */
        +int 	  ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 
        +		const unsigned char *sig, int siglen, EC_KEY *eckey);
        +
        +/* the standard ex_data functions */
        +int 	  ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
        +		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int 	  ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
        +void 	  *ECDSA_get_ex_data(EC_KEY *d, int idx);
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_ECDSA_strings(void);
        +
        +/* Error codes for the ECDSA functions. */
        +
        +/* Function codes. */
        +#define ECDSA_F_ECDSA_CHECK				 104
        +#define ECDSA_F_ECDSA_DATA_NEW_METHOD			 100
        +#define ECDSA_F_ECDSA_DO_SIGN				 101
        +#define ECDSA_F_ECDSA_DO_VERIFY				 102
        +#define ECDSA_F_ECDSA_SIGN_SETUP			 103
        +
        +/* Reason codes. */
        +#define ECDSA_R_BAD_SIGNATURE				 100
        +#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 101
        +#define ECDSA_R_ERR_EC_LIB				 102
        +#define ECDSA_R_MISSING_PARAMETERS			 103
        +#define ECDSA_R_NEED_NEW_SETUP_VALUES			 106
        +#define ECDSA_R_NON_FIPS_METHOD				 107
        +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED		 104
        +#define ECDSA_R_SIGNATURE_MALLOC_FAILED			 105
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecdsatest.c b/vendor/openssl/openssl/crypto/ecdsa/ecdsatest.c
        new file mode 100644
        index 000000000..537bb3036
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecdsatest.c
        @@ -0,0 +1,572 @@
        +/* crypto/ecdsa/ecdsatest.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */
        +
        +#ifdef OPENSSL_NO_ECDSA
        +int main(int argc, char * argv[])
        +	{
        +	puts("Elliptic curves are disabled.");
        +	return 0;
        +	}
        +#else
        +
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/ecdsa.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +
        +static const char rnd_seed[] = "string to make the random number generator "
        +	"think it has entropy";
        +
        +/* declaration of the test functions */
        +int x9_62_tests(BIO *);
        +int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s);
        +int test_builtin(BIO *);
        +
        +/* functions to change the RAND_METHOD */
        +int change_rand(void);
        +int restore_rand(void);
        +int fbytes(unsigned char *buf, int num);
        +
        +RAND_METHOD	fake_rand;
        +const RAND_METHOD *old_rand;
        +
        +int change_rand(void)
        +	{
        +	/* save old rand method */
        +	if ((old_rand = RAND_get_rand_method()) == NULL)
        +		return 0;
        +
        +	fake_rand.seed    = old_rand->seed;
        +	fake_rand.cleanup = old_rand->cleanup;
        +	fake_rand.add     = old_rand->add;
        +	fake_rand.status  = old_rand->status;
        +	/* use own random function */
        +	fake_rand.bytes      = fbytes;
        +	fake_rand.pseudorand = old_rand->bytes;
        +	/* set new RAND_METHOD */
        +	if (!RAND_set_rand_method(&fake_rand))
        +		return 0;
        +	return 1;
        +	}
        +
        +int restore_rand(void)
        +	{
        +	if (!RAND_set_rand_method(old_rand))
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static int fbytes_counter = 0;
        +static const char *numbers[8] = {
        +	"651056770906015076056810763456358567190100156695615665659",
        +	"6140507067065001063065065565667405560006161556565665656654",
        +	"8763001015071075675010661307616710783570106710677817767166"
        +	"71676178726717",
        +	"7000000175690566466555057817571571075705015757757057795755"
        +	"55657156756655",
        +	"1275552191113212300012030439187146164646146646466749494799",
        +	"1542725565216523985789236956265265265235675811949404040041",
        +	"1456427555219115346513212300075341203043918714616464614664"
        +	"64667494947990",
        +	"1712787255652165239672857892369562652652652356758119494040"
        +	"40041670216363"};
        +
        +int fbytes(unsigned char *buf, int num)
        +	{
        +	int	ret;
        +	BIGNUM	*tmp = NULL;
        +
        +	if (fbytes_counter >= 8)
        +		return 0;
        +	tmp = BN_new();
        +	if (!tmp)
        +		return 0;
        +	if (!BN_dec2bn(&tmp, numbers[fbytes_counter]))
        +		{
        +		BN_free(tmp);
        +		return 0;
        +		}
        +	fbytes_counter ++;
        +	if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
        +		ret = 0;
        +	else 
        +		ret = 1;
        +	if (tmp)
        +		BN_free(tmp);
        +	return ret;
        +	}
        +
        +/* some tests from the X9.62 draft */
        +int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
        +	{
        +	int	ret = 0;
        +	const char message[] = "abc";
        +	unsigned char digest[20];
        +	unsigned int  dgst_len = 0;
        +	EVP_MD_CTX md_ctx;
        +	EC_KEY    *key = NULL;
        +	ECDSA_SIG *signature = NULL;
        +	BIGNUM    *r = NULL, *s = NULL;
        +
        +	EVP_MD_CTX_init(&md_ctx);
        +	/* get the message digest */
        +	EVP_DigestInit(&md_ctx, EVP_ecdsa());
        +	EVP_DigestUpdate(&md_ctx, (const void*)message, 3);
        +	EVP_DigestFinal(&md_ctx, digest, &dgst_len);
        +
        +	BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
        +	/* create the key */
        +	if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
        +		goto x962_int_err;
        +	if (!EC_KEY_generate_key(key))
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +	/* create the signature */
        +	signature = ECDSA_do_sign(digest, 20, key);
        +	if (signature == NULL)
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +	/* compare the created signature with the expected signature */
        +	if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
        +		goto x962_int_err;
        +	if (!BN_dec2bn(&r, r_in) ||
        +	    !BN_dec2bn(&s, s_in))
        +		goto x962_int_err;
        +	if (BN_cmp(signature->r ,r) || BN_cmp(signature->s, s))
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +	/* verify the signature */
        +	if (ECDSA_do_verify(digest, 20, signature, key) != 1)
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +
        +	BIO_printf(out, " ok\n");
        +	ret = 1;
        +x962_int_err:
        +	if (!ret)
        +		BIO_printf(out, " failed\n");
        +	if (key)
        +		EC_KEY_free(key);
        +	if (signature)
        +		ECDSA_SIG_free(signature);
        +	if (r)
        +		BN_free(r);
        +	if (s)
        +		BN_free(s);
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return ret;
        +	}
        +
        +int x9_62_tests(BIO *out)
        +	{
        +	int ret = 0;
        +
        +	BIO_printf(out, "some tests from X9.62:\n");
        +
        +	/* set own rand method */
        +	if (!change_rand())
        +		goto x962_err;
        +
        +	if (!x9_62_test_internal(out, NID_X9_62_prime192v1,
        +		"3342403536405981729393488334694600415596881826869351677613",
        +		"5735822328888155254683894997897571951568553642892029982342"))
        +		goto x962_err;
        +	if (!x9_62_test_internal(out, NID_X9_62_prime239v1,
        +		"3086361431751678114926225473006680188549593787585317781474"
        +		"62058306432176",
        +		"3238135532097973577080787768312505059318910517550078427819"
        +		"78505179448783"))
        +		goto x962_err;
        +#ifndef OPENSSL_NO_EC2M
        +	if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
        +		"87194383164871543355722284926904419997237591535066528048",
        +		"308992691965804947361541664549085895292153777025772063598"))
        +		goto x962_err;
        +	if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1,
        +		"2159633321041961198501834003903461262881815148684178964245"
        +		"5876922391552",
        +		"1970303740007316867383349976549972270528498040721988191026"
        +		"49413465737174"))
        +		goto x962_err;
        +#endif
        +	ret = 1;
        +x962_err:
        +	if (!restore_rand())
        +		ret = 0;
        +	return ret;
        +	}
        +
        +int test_builtin(BIO *out)
        +	{
        +	EC_builtin_curve *curves = NULL;
        +	size_t		crv_len = 0, n = 0;
        +	EC_KEY		*eckey = NULL, *wrong_eckey = NULL;
        +	EC_GROUP	*group;
        +	ECDSA_SIG	*ecdsa_sig = NULL;
        +	unsigned char	digest[20], wrong_digest[20];
        +	unsigned char	*signature = NULL;
        +	const unsigned char	*sig_ptr;
        +	unsigned char	*sig_ptr2;
        +	unsigned char	*raw_buf = NULL;
        +	unsigned int	sig_len, degree, r_len, s_len, bn_len, buf_len;
        +	int		nid, ret =  0;
        +	
        +	/* fill digest values with some random data */
        +	if (!RAND_pseudo_bytes(digest, 20) ||
        +	    !RAND_pseudo_bytes(wrong_digest, 20))
        +		{
        +		BIO_printf(out, "ERROR: unable to get random data\n");
        +		goto builtin_err;
        +		}
        +
        +	/* create and verify a ecdsa signature with every availble curve
        +	 * (with ) */
        +	BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
        +		"with some internal curves:\n");
        +
        +	/* get a list of all internal curves */
        +	crv_len = EC_get_builtin_curves(NULL, 0);
        +
        +	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
        +
        +	if (curves == NULL)
        +		{
        +		BIO_printf(out, "malloc error\n");
        +		goto builtin_err;
        +		}
        +	
        +	if (!EC_get_builtin_curves(curves, crv_len))
        +		{
        +		BIO_printf(out, "unable to get internal curves\n");
        +		goto builtin_err;
        +		}
        +
        +	/* now create and verify a signature for every curve */
        +	for (n = 0; n < crv_len; n++)
        +		{
        +		unsigned char dirt, offset;
        +
        +		nid = curves[n].nid;
        +		if (nid == NID_ipsec4)
        +			continue;
        +		/* create new ecdsa key (== EC_KEY) */
        +		if ((eckey = EC_KEY_new()) == NULL)
        +			goto builtin_err;
        +		group = EC_GROUP_new_by_curve_name(nid);
        +		if (group == NULL)
        +			goto builtin_err;
        +		if (EC_KEY_set_group(eckey, group) == 0)
        +			goto builtin_err;
        +		EC_GROUP_free(group);
        +		degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
        +		if (degree < 160)
        +			/* drop the curve */ 
        +			{
        +			EC_KEY_free(eckey);
        +			eckey = NULL;
        +			continue;
        +			}
        +		BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
        +		/* create key */
        +		if (!EC_KEY_generate_key(eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		/* create second key */
        +		if ((wrong_eckey = EC_KEY_new()) == NULL)
        +			goto builtin_err;
        +		group = EC_GROUP_new_by_curve_name(nid);
        +		if (group == NULL)
        +			goto builtin_err;
        +		if (EC_KEY_set_group(wrong_eckey, group) == 0)
        +			goto builtin_err;
        +		EC_GROUP_free(group);
        +		if (!EC_KEY_generate_key(wrong_eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* check key */
        +		if (!EC_KEY_check_key(eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* create signature */
        +		sig_len = ECDSA_size(eckey);
        +		if ((signature = OPENSSL_malloc(sig_len)) == NULL)
        +			goto builtin_err;
        +                if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* verify signature */
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* verify signature with the wrong key */
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, 
        +			wrong_eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* wrong digest */
        +		if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
        +			eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* wrong length */
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
        +			eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +
        +		/* Modify a single byte of the signature: to ensure we don't
        +		 * garble the ASN1 structure, we read the raw signature and
        +		 * modify a byte in one of the bignums directly. */
        +		sig_ptr = signature;
        +		if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +
        +		/* Store the two BIGNUMs in raw_buf. */
        +		r_len = BN_num_bytes(ecdsa_sig->r);
        +		s_len = BN_num_bytes(ecdsa_sig->s);
        +		bn_len = (degree + 7) / 8;
        +		if ((r_len > bn_len) || (s_len > bn_len))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		buf_len = 2 * bn_len;
        +		if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
        +			goto builtin_err;
        +		/* Pad the bignums with leading zeroes. */
        +		memset(raw_buf, 0, buf_len);
        +		BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
        +		BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
        +
        +		/* Modify a single byte in the buffer. */
        +		offset = raw_buf[10] % buf_len;
        +		dirt   = raw_buf[11] ? raw_buf[11] : 1;
        +		raw_buf[offset] ^= dirt;
        +		/* Now read the BIGNUMs back in from raw_buf. */
        +		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
        +			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
        +			goto builtin_err;
        +
        +		sig_ptr2 = signature;
        +		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		/* Sanity check: undo the modification and verify signature. */
        +		raw_buf[offset] ^= dirt;
        +		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
        +			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
        +			goto builtin_err;
        +
        +		sig_ptr2 = signature;
        +		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		
        +		BIO_printf(out, " ok\n");
        +		/* cleanup */
        +		/* clean bogus errors */
        +		ERR_clear_error();
        +		OPENSSL_free(signature);
        +		signature = NULL;
        +		EC_KEY_free(eckey);
        +		eckey = NULL;
        +		EC_KEY_free(wrong_eckey);
        +		wrong_eckey = NULL;
        +		ECDSA_SIG_free(ecdsa_sig);
        +		ecdsa_sig = NULL;
        +		OPENSSL_free(raw_buf);
        +		raw_buf = NULL;
        +		}
        +
        +	ret = 1;	
        +builtin_err:
        +	if (eckey)
        +		EC_KEY_free(eckey);
        +	if (wrong_eckey)
        +		EC_KEY_free(wrong_eckey);
        +	if (ecdsa_sig)
        +		ECDSA_SIG_free(ecdsa_sig);
        +	if (signature)
        +		OPENSSL_free(signature);
        +	if (raw_buf)
        +		OPENSSL_free(raw_buf);
        +	if (curves)
        +		OPENSSL_free(curves);
        +
        +	return ret;
        +	}
        +
        +int main(void)
        +	{
        +	int 	ret = 1;
        +	BIO	*out;
        +
        +	out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +	
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && 
        +		(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	ERR_load_crypto_strings();
        +
        +	/* initialize the prng */
        +	RAND_seed(rnd_seed, sizeof(rnd_seed));
        +
        +	/* the tests */
        +	if (!x9_62_tests(out))  goto err;
        +	if (!test_builtin(out)) goto err;
        +	
        +	ret = 0;
        +err:	
        +	if (ret) 	
        +		BIO_printf(out, "\nECDSA test failed\n");
        +	else 
        +		BIO_printf(out, "\nECDSA test passed\n");
        +	if (ret)
        +		ERR_print_errors(out);
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	ERR_free_strings();
        +	CRYPTO_mem_leaks(out);
        +	if (out != NULL)
        +		BIO_free(out);
        +	return ret;
        +	}	
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_asn1.c b/vendor/openssl/openssl/crypto/ecdsa/ecs_asn1.c
        new file mode 100644
        index 000000000..b29548940
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_asn1.c
        @@ -0,0 +1,67 @@
        +/* crypto/ecdsa/ecs_asn1.c */
        +/* ====================================================================
        + * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ecs_locl.h"
        +#include <openssl/err.h>
        +#include <openssl/asn1t.h>
        +
        +ASN1_SEQUENCE(ECDSA_SIG) = {
        +	ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
        +	ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
        +} ASN1_SEQUENCE_END(ECDSA_SIG)
        +
        +DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
        +IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG)
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_err.c b/vendor/openssl/openssl/crypto/ecdsa/ecs_err.c
        new file mode 100644
        index 000000000..81542e6d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_err.c
        @@ -0,0 +1,106 @@
        +/* crypto/ecdsa/ecs_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ecdsa.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason)
        +
        +static ERR_STRING_DATA ECDSA_str_functs[]=
        +	{
        +{ERR_FUNC(ECDSA_F_ECDSA_CHECK),	"ECDSA_CHECK"},
        +{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD),	"ECDSA_DATA_NEW_METHOD"},
        +{ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN),	"ECDSA_do_sign"},
        +{ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY),	"ECDSA_do_verify"},
        +{ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP),	"ECDSA_sign_setup"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ECDSA_str_reasons[]=
        +	{
        +{ERR_REASON(ECDSA_R_BAD_SIGNATURE)       ,"bad signature"},
        +{ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
        +{ERR_REASON(ECDSA_R_ERR_EC_LIB)          ,"err ec lib"},
        +{ERR_REASON(ECDSA_R_MISSING_PARAMETERS)  ,"missing parameters"},
        +{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"},
        +{ERR_REASON(ECDSA_R_NON_FIPS_METHOD)     ,"non fips method"},
        +{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"},
        +{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_ECDSA_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,ECDSA_str_functs);
        +		ERR_load_strings(0,ECDSA_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_lib.c b/vendor/openssl/openssl/crypto/ecdsa/ecs_lib.c
        new file mode 100644
        index 000000000..814a6bf40
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_lib.c
        @@ -0,0 +1,285 @@
        +/* crypto/ecdsa/ecs_lib.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 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 <string.h>
        +#include "ecs_locl.h"
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
        +
        +static const ECDSA_METHOD *default_ECDSA_method = NULL;
        +
        +static void *ecdsa_data_new(void);
        +static void *ecdsa_data_dup(void *);
        +static void  ecdsa_data_free(void *);
        +
        +void ECDSA_set_default_method(const ECDSA_METHOD *meth)
        +{
        +	default_ECDSA_method = meth;
        +}
        +
        +const ECDSA_METHOD *ECDSA_get_default_method(void)
        +{
        +	if(!default_ECDSA_method) 
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return FIPS_ecdsa_openssl();
        +		else
        +			return ECDSA_OpenSSL();
        +#else
        +		default_ECDSA_method = ECDSA_OpenSSL();
        +#endif
        +		}
        +	return default_ECDSA_method;
        +}
        +
        +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
        +{
        +	ECDSA_DATA *ecdsa;
        +
        +	ecdsa = ecdsa_check(eckey);
        +
        +	if (ecdsa == NULL)
        +		return 0;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	if (ecdsa->engine)
        +	{
        +		ENGINE_finish(ecdsa->engine);
        +		ecdsa->engine = NULL;
        +	}
        +#endif
        +        ecdsa->meth = meth;
        +
        +        return 1;
        +}
        +
        +static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
        +{
        +	ECDSA_DATA *ret;
        +
        +	ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA));
        +	if (ret == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +	}
        +
        +	ret->init = NULL;
        +
        +	ret->meth = ECDSA_get_default_method();
        +	ret->engine = engine;
        +#ifndef OPENSSL_NO_ENGINE
        +	if (!ret->engine)
        +		ret->engine = ENGINE_get_default_ECDSA();
        +	if (ret->engine)
        +	{
        +		ret->meth = ENGINE_get_ECDSA(ret->engine);
        +		if (!ret->meth)
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
        +			ENGINE_finish(ret->engine);
        +			OPENSSL_free(ret);
        +			return NULL;
        +		}
        +	}
        +#endif
        +
        +	ret->flags = ret->meth->flags;
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
        +#if 0
        +	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
        +	{
        +		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +	}
        +#endif	
        +	return(ret);
        +}
        +
        +static void *ecdsa_data_new(void)
        +{
        +	return (void *)ECDSA_DATA_new_method(NULL);
        +}
        +
        +static void *ecdsa_data_dup(void *data)
        +{
        +	ECDSA_DATA *r = (ECDSA_DATA *)data;
        +
        +	/* XXX: dummy operation */
        +	if (r == NULL)
        +		return NULL;
        +
        +	return ecdsa_data_new();
        +}
        +
        +static void ecdsa_data_free(void *data)
        +{
        +	ECDSA_DATA *r = (ECDSA_DATA *)data;
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	if (r->engine)
        +		ENGINE_finish(r->engine);
        +#endif
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
        +
        +	OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
        +
        +	OPENSSL_free(r);
        +}
        +
        +ECDSA_DATA *ecdsa_check(EC_KEY *key)
        +{
        +	ECDSA_DATA *ecdsa_data;
        + 
        +	void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
        +					ecdsa_data_free, ecdsa_data_free);
        +	if (data == NULL)
        +	{
        +		ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
        +		if (ecdsa_data == NULL)
        +			return NULL;
        +		data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
        +			   ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
        +		if (data != NULL)
        +			{
        +			/* Another thread raced us to install the key_method
        +			 * data and won. */
        +			ecdsa_data_free(ecdsa_data);
        +			ecdsa_data = (ECDSA_DATA *)data;
        +			}
        +	}
        +	else
        +		ecdsa_data = (ECDSA_DATA *)data;
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD)
        +			&& !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW))
        +		{
        +		ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD);
        +		return NULL;
        +		}
        +#endif
        +
        +	return ecdsa_data;
        +}
        +
        +int ECDSA_size(const EC_KEY *r)
        +{
        +	int ret,i;
        +	ASN1_INTEGER bs;
        +	BIGNUM	*order=NULL;
        +	unsigned char buf[4];
        +	const EC_GROUP *group;
        +
        +	if (r == NULL)
        +		return 0;
        +	group = EC_KEY_get0_group(r);
        +	if (group == NULL)
        +		return 0;
        +
        +	if ((order = BN_new()) == NULL) return 0;
        +	if (!EC_GROUP_get_order(group,order,NULL))
        +	{
        +		BN_clear_free(order);
        +		return 0;
        +	} 
        +	i=BN_num_bits(order);
        +	bs.length=(i+7)/8;
        +	bs.data=buf;
        +	bs.type=V_ASN1_INTEGER;
        +	/* If the top bit is set the asn1 encoding is 1 larger. */
        +	buf[0]=0xff;	
        +
        +	i=i2d_ASN1_INTEGER(&bs,NULL);
        +	i+=i; /* r and s */
        +	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
        +	BN_clear_free(order);
        +	return(ret);
        +}
        +
        +
        +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
        +				new_func, dup_func, free_func);
        +}
        +
        +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
        +{
        +	ECDSA_DATA *ecdsa;
        +	ecdsa = ecdsa_check(d);
        +	if (ecdsa == NULL)
        +		return 0;
        +	return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg));
        +}
        +
        +void *ECDSA_get_ex_data(EC_KEY *d, int idx)
        +{
        +	ECDSA_DATA *ecdsa;
        +	ecdsa = ecdsa_check(d);
        +	if (ecdsa == NULL)
        +		return NULL;
        +	return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx));
        +}
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_locl.h b/vendor/openssl/openssl/crypto/ecdsa/ecs_locl.h
        new file mode 100644
        index 000000000..cb3be13cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_locl.h
        @@ -0,0 +1,115 @@
        +/* crypto/ecdsa/ecs_locl.h */
        +/*
        + * Written by Nils Larsch for the OpenSSL project
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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_ECS_LOCL_H
        +#define HEADER_ECS_LOCL_H
        +
        +#include <openssl/ecdsa.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +struct ecdsa_method 
        +	{
        +	const char *name;
        +	ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, 
        +			const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey);
        +	int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
        +			BIGNUM **r);
        +	int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, 
        +			const ECDSA_SIG *sig, EC_KEY *eckey);
        +#if 0
        +	int (*init)(EC_KEY *eckey);
        +	int (*finish)(EC_KEY *eckey);
        +#endif
        +	int flags;
        +	char *app_data;
        +	};
        +
        +/* If this flag is set the ECDSA method is FIPS compliant and can be used
        + * in FIPS mode. This is set in the validated module method. If an
        + * application sets this flag in its own methods it is its responsibility
        + * to ensure the result is compliant.
        + */
        +
        +#define ECDSA_FLAG_FIPS_METHOD	0x1
        +
        +typedef struct ecdsa_data_st {
        +	/* EC_KEY_METH_DATA part */
        +	int (*init)(EC_KEY *);
        +	/* method (ECDSA) specific part */
        +	ENGINE	*engine;
        +	int	flags;
        +	const ECDSA_METHOD *meth;
        +	CRYPTO_EX_DATA ex_data;
        +} ECDSA_DATA;
        +
        +/** ecdsa_check
        + * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
        + * and if not it removes the old meth_data and creates a ECDSA_DATA structure.
        + * \param  eckey pointer to a EC_KEY object
        + * \return pointer to a ECDSA_DATA structure
        + */
        +ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* HEADER_ECS_LOCL_H */
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_ossl.c b/vendor/openssl/openssl/crypto/ecdsa/ecs_ossl.c
        new file mode 100644
        index 000000000..772593561
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_ossl.c
        @@ -0,0 +1,483 @@
        +/* crypto/ecdsa/ecs_ossl.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2004 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 "ecs_locl.h"
        +#include <openssl/err.h>
        +#include <openssl/obj_mac.h>
        +#include <openssl/bn.h>
        +
        +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, 
        +		const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
        +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 
        +		BIGNUM **rp);
        +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 
        +		const ECDSA_SIG *sig, EC_KEY *eckey);
        +
        +static ECDSA_METHOD openssl_ecdsa_meth = {
        +	"OpenSSL ECDSA method",
        +	ecdsa_do_sign,
        +	ecdsa_sign_setup,
        +	ecdsa_do_verify,
        +#if 0
        +	NULL, /* init     */
        +	NULL, /* finish   */
        +#endif
        +	0,    /* flags    */
        +	NULL  /* app_data */
        +};
        +
        +const ECDSA_METHOD *ECDSA_OpenSSL(void)
        +{
        +	return &openssl_ecdsa_meth;
        +}
        +
        +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
        +		BIGNUM **rp)
        +{
        +	BN_CTX   *ctx = NULL;
        +	BIGNUM	 *k = NULL, *r = NULL, *order = NULL, *X = NULL;
        +	EC_POINT *tmp_point=NULL;
        +	const EC_GROUP *group;
        +	int 	 ret = 0;
        +
        +	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +	}
        +
        +	if (ctx_in == NULL) 
        +	{
        +		if ((ctx = BN_CTX_new()) == NULL)
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +	}
        +	else
        +		ctx = ctx_in;
        +
        +	k     = BN_new();	/* this value is later returned in *kinvp */
        +	r     = BN_new();	/* this value is later returned in *rp    */
        +	order = BN_new();
        +	X     = BN_new();
        +	if (!k || !r || !order || !X)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +	if ((tmp_point = EC_POINT_new(group)) == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        +		goto err;
        +	}
        +	if (!EC_GROUP_get_order(group, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        +		goto err;
        +	}
        +	
        +	do
        +	{
        +		/* get random k */	
        +		do
        +			if (!BN_rand_range(k, order))
        +			{
        +				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
        +				 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);	
        +				goto err;
        +			}
        +		while (BN_is_zero(k));
        +
        +		/* We do not want timing information to leak the length of k,
        +		 * so we compute G*k using an equivalent scalar of fixed
        +		 * bit-length. */
        +
        +		if (!BN_add(k, k, order)) goto err;
        +		if (BN_num_bits(k) <= BN_num_bits(order))
        +			if (!BN_add(k, k, order)) goto err;
        +
        +		/* compute r the x-coordinate of generator * k */
        +		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        +			goto err;
        +		}
        +		if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
        +		{
        +			if (!EC_POINT_get_affine_coordinates_GFp(group,
        +				tmp_point, X, NULL, ctx))
        +			{
        +				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
        +				goto err;
        +			}
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +		else /* NID_X9_62_characteristic_two_field */
        +		{
        +			if (!EC_POINT_get_affine_coordinates_GF2m(group,
        +				tmp_point, X, NULL, ctx))
        +			{
        +				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
        +				goto err;
        +			}
        +		}
        +#endif
        +		if (!BN_nnmod(r, X, order, ctx))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
        +			goto err;
        +		}
        +	}
        +	while (BN_is_zero(r));
        +
        +	/* compute the inverse of k */
        +	if (!BN_mod_inverse(k, k, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
        +		goto err;	
        +	}
        +	/* clear old values if necessary */
        +	if (*rp != NULL)
        +		BN_clear_free(*rp);
        +	if (*kinvp != NULL) 
        +		BN_clear_free(*kinvp);
        +	/* save the pre-computed values  */
        +	*rp    = r;
        +	*kinvp = k;
        +	ret = 1;
        +err:
        +	if (!ret)
        +	{
        +		if (k != NULL) BN_clear_free(k);
        +		if (r != NULL) BN_clear_free(r);
        +	}
        +	if (ctx_in == NULL) 
        +		BN_CTX_free(ctx);
        +	if (order != NULL)
        +		BN_free(order);
        +	if (tmp_point != NULL) 
        +		EC_POINT_free(tmp_point);
        +	if (X)
        +		BN_clear_free(X);
        +	return(ret);
        +}
        +
        +
        +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 
        +		const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
        +{
        +	int     ok = 0, i;
        +	BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
        +	const BIGNUM *ckinv;
        +	BN_CTX     *ctx = NULL;
        +	const EC_GROUP   *group;
        +	ECDSA_SIG  *ret;
        +	ECDSA_DATA *ecdsa;
        +	const BIGNUM *priv_key;
        +
        +	ecdsa    = ecdsa_check(eckey);
        +	group    = EC_KEY_get0_group(eckey);
        +	priv_key = EC_KEY_get0_private_key(eckey);
        +	
        +	if (group == NULL || priv_key == NULL || ecdsa == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +	}
        +
        +	ret = ECDSA_SIG_new();
        +	if (!ret)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	s = ret->s;
        +
        +	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
        +		(tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +
        +	if (!EC_GROUP_get_order(group, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
        +		goto err;
        +	}
        +	i = BN_num_bits(order);
        +	/* Need to truncate digest if it is too long: first truncate whole
        +	 * bytes.
        +	 */
        +	if (8 * dgst_len > i)
        +		dgst_len = (i + 7)/8;
        +	if (!BN_bin2bn(dgst, dgst_len, m))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	/* If still too long truncate remaining bits with a shift */
        +	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	do
        +	{
        +		if (in_kinv == NULL || in_r == NULL)
        +		{
        +			if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r))
        +			{
        +				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
        +				goto err;
        +			}
        +			ckinv = kinv;
        +		}
        +		else
        +		{
        +			ckinv  = in_kinv;
        +			if (BN_copy(ret->r, in_r) == NULL)
        +			{
        +				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
        +				goto err;
        +			}
        +		}
        +
        +		if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
        +			goto err;
        +		}
        +		if (!BN_mod_add_quick(s, tmp, m, order))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
        +			goto err;
        +		}
        +		if (!BN_mod_mul(s, s, ckinv, order, ctx))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
        +			goto err;
        +		}
        +		if (BN_is_zero(s))
        +		{
        +			/* if kinv and r have been supplied by the caller
        +			 * don't to generate new kinv and r values */
        +			if (in_kinv != NULL && in_r != NULL)
        +			{
        +				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
        +				goto err;
        +			}
        +		}
        +		else
        +			/* s != 0 => we have a valid signature */
        +			break;
        +	}
        +	while (1);
        +
        +	ok = 1;
        +err:
        +	if (!ok)
        +	{
        +		ECDSA_SIG_free(ret);
        +		ret = NULL;
        +	}
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	if (m)
        +		BN_clear_free(m);
        +	if (tmp)
        +		BN_clear_free(tmp);
        +	if (order)
        +		BN_free(order);
        +	if (kinv)
        +		BN_clear_free(kinv);
        +	return ret;
        +}
        +
        +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
        +		const ECDSA_SIG *sig, EC_KEY *eckey)
        +{
        +	int ret = -1, i;
        +	BN_CTX   *ctx;
        +	BIGNUM   *order, *u1, *u2, *m, *X;
        +	EC_POINT *point = NULL;
        +	const EC_GROUP *group;
        +	const EC_POINT *pub_key;
        +
        +	/* check input values */
        +	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
        +	    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
        +		return -1;
        +	}
        +
        +	ctx = BN_CTX_new();
        +	if (!ctx)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
        +		return -1;
        +	}
        +	BN_CTX_start(ctx);
        +	order = BN_CTX_get(ctx);	
        +	u1    = BN_CTX_get(ctx);
        +	u2    = BN_CTX_get(ctx);
        +	m     = BN_CTX_get(ctx);
        +	X     = BN_CTX_get(ctx);
        +	if (!X)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	
        +	if (!EC_GROUP_get_order(group, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
        +		goto err;
        +	}
        +
        +	if (BN_is_zero(sig->r)          || BN_is_negative(sig->r) || 
        +	    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||
        +	    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
        +		ret = 0;	/* signature is invalid */
        +		goto err;
        +	}
        +	/* calculate tmp1 = inv(S) mod order */
        +	if (!BN_mod_inverse(u2, sig->s, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	/* digest -> m */
        +	i = BN_num_bits(order);
        +	/* Need to truncate digest if it is too long: first truncate whole
        +	 * bytes.
        +	 */
        +	if (8 * dgst_len > i)
        +		dgst_len = (i + 7)/8;
        +	if (!BN_bin2bn(dgst, dgst_len, m))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	/* If still too long truncate remaining bits with a shift */
        +	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	/* u1 = m * tmp mod order */
        +	if (!BN_mod_mul(u1, m, u2, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	/* u2 = r * w mod q */
        +	if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +
        +	if ((point = EC_POINT_new(group)) == NULL)
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
        +		goto err;
        +	}
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
        +	{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group,
        +			point, X, NULL, ctx))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
        +			goto err;
        +		}
        +	}
        +#ifndef OPENSSL_NO_EC2M
        +	else /* NID_X9_62_characteristic_two_field */
        +	{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group,
        +			point, X, NULL, ctx))
        +		{
        +			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
        +			goto err;
        +		}
        +	}
        +#endif	
        +	if (!BN_nnmod(u1, X, order, ctx))
        +	{
        +		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
        +		goto err;
        +	}
        +	/*  if the signature is correct u1 is equal to sig->r */
        +	ret = (BN_ucmp(u1, sig->r) == 0);
        +err:
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	if (point)
        +		EC_POINT_free(point);
        +	return ret;
        +}
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_sign.c b/vendor/openssl/openssl/crypto/ecdsa/ecs_sign.c
        new file mode 100644
        index 000000000..353d5af51
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_sign.c
        @@ -0,0 +1,106 @@
        +/* crypto/ecdsa/ecdsa_sign.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ecs_locl.h"
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/rand.h>
        +
        +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
        +{
        +	return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
        +}
        +
        +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
        +	const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey)
        +{
        +	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
        +	if (ecdsa == NULL)
        +		return NULL;
        +	return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey);
        +}
        +
        +int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char 
        +		*sig, unsigned int *siglen, EC_KEY *eckey)
        +{
        +	return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
        +}
        +
        +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char 
        +	*sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, 
        +	EC_KEY *eckey)
        +{
        +	ECDSA_SIG *s;
        +	RAND_seed(dgst, dlen);
        +	s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
        +	if (s == NULL)
        +	{
        +		*siglen=0;
        +		return 0;
        +	}
        +	*siglen = i2d_ECDSA_SIG(s, &sig);
        +	ECDSA_SIG_free(s);
        +	return 1;
        +}
        +
        +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 
        +		BIGNUM **rp)
        +{
        +	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
        +	if (ecdsa == NULL)
        +		return 0;
        +	return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); 
        +}
        diff --git a/vendor/openssl/openssl/crypto/ecdsa/ecs_vrf.c b/vendor/openssl/openssl/crypto/ecdsa/ecs_vrf.c
        new file mode 100644
        index 000000000..ef9acf7b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ecdsa/ecs_vrf.c
        @@ -0,0 +1,96 @@
        +/* crypto/ecdsa/ecdsa_vrf.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ecs_locl.h"
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +/* returns
        + *      1: correct signature
        + *      0: incorrect signature
        + *     -1: error
        + */
        +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, 
        +		const ECDSA_SIG *sig, EC_KEY *eckey)
        +	{
        +	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
        +	if (ecdsa == NULL)
        +		return 0;
        +	return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey);
        +	}
        +
        +/* returns
        + *      1: correct signature
        + *      0: incorrect signature
        + *     -1: error
        + */
        +int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
        +		const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
        + 	{
        +	ECDSA_SIG *s;
        +	int ret=-1;
        +
        +	s = ECDSA_SIG_new();
        +	if (s == NULL) return(ret);
        +	if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
        +	ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
        +err:
        +	ECDSA_SIG_free(s);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/Makefile b/vendor/openssl/openssl/crypto/engine/Makefile
        new file mode 100644
        index 000000000..d29bdd09a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/Makefile
        @@ -0,0 +1,447 @@
        +#
        +# OpenSSL/crypto/engine/Makefile
        +#
        +
        +DIR=	engine
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST= enginetest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
        +	eng_table.c eng_pkey.c eng_fat.c eng_all.c \
        +	tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
        +	tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
        +	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
        +	eng_rsax.c eng_rdrand.c
        +LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
        +	eng_table.o eng_pkey.o eng_fat.o eng_all.o \
        +	tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
        +	tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
        +	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \
        +	eng_rsax.o eng_rdrand.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +eng_all.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_all.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +eng_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_all.c eng_int.h
        +eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +eng_cnf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eng_cnf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +eng_cnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_cnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +eng_cnf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +eng_cnf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_cnf.o: ../cryptlib.h eng_cnf.c eng_int.h
        +eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_cryptodev.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_cryptodev.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_cryptodev.o: ../../include/openssl/obj_mac.h
        +eng_cryptodev.o: ../../include/openssl/objects.h
        +eng_cryptodev.o: ../../include/openssl/opensslconf.h
        +eng_cryptodev.o: ../../include/openssl/opensslv.h
        +eng_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +eng_cryptodev.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_cryptodev.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_cryptodev.o: eng_cryptodev.c
        +eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_ctrl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_ctrl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_ctrl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_ctrl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_ctrl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_ctrl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +eng_ctrl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_ctrl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_ctrl.c eng_int.h
        +eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_dyn.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h
        +eng_dyn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eng_dyn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +eng_dyn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_dyn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +eng_dyn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +eng_dyn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_dyn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_dyn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h
        +eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +eng_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eng_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +eng_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +eng_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +eng_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_err.o: eng_err.c
        +eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_fat.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +eng_fat.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eng_fat.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +eng_fat.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_fat.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +eng_fat.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +eng_fat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_fat.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_fat.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h
        +eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_init.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_init.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_init.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_init.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +eng_init.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_init.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_init.c eng_int.h
        +eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +eng_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_lib.o: ../cryptlib.h eng_int.h eng_lib.c
        +eng_list.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_list.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_list.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_list.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_list.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_list.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_list.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_list.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_list.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +eng_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_list.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_list.c
        +eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
        +eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eng_openssl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +eng_openssl.o: ../../include/openssl/opensslconf.h
        +eng_openssl.o: ../../include/openssl/opensslv.h
        +eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
        +eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_openssl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_openssl.c
        +eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
        +eng_rdrand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +eng_rdrand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +eng_rdrand.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +eng_rdrand.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +eng_rdrand.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +eng_rdrand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +eng_rdrand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +eng_rdrand.o: ../../include/openssl/opensslconf.h
        +eng_rdrand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_rdrand.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +eng_rdrand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_rdrand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_rdrand.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_rdrand.o: eng_rdrand.c
        +eng_rsax.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +eng_rsax.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +eng_rsax.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_rsax.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_rsax.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_rsax.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_rsax.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_rsax.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +eng_rsax.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_rsax.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +eng_rsax.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +eng_rsax.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +eng_rsax.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +eng_rsax.o: eng_rsax.c
        +eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
        +eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +eng_table.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +eng_table.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +eng_table.o: ../../include/openssl/objects.h
        +eng_table.o: ../../include/openssl/opensslconf.h
        +eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +eng_table.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +eng_table.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
        +eng_table.o: eng_table.c
        +tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_asnmth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_asnmth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_asnmth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_asnmth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_asnmth.o: ../../include/openssl/objects.h
        +tb_asnmth.o: ../../include/openssl/opensslconf.h
        +tb_asnmth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_asnmth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_asnmth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_asnmth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_asnmth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +tb_asnmth.o: eng_int.h tb_asnmth.c
        +tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_cipher.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_cipher.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_cipher.o: ../../include/openssl/objects.h
        +tb_cipher.o: ../../include/openssl/opensslconf.h
        +tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_cipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_cipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_cipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
        +tb_cipher.o: tb_cipher.c
        +tb_dh.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +tb_dh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +tb_dh.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +tb_dh.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +tb_dh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +tb_dh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +tb_dh.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +tb_dh.o: ../cryptlib.h eng_int.h tb_dh.c
        +tb_digest.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_digest.o: ../../include/openssl/objects.h
        +tb_digest.o: ../../include/openssl/opensslconf.h
        +tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
        +tb_digest.o: tb_digest.c
        +tb_dsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +tb_dsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +tb_dsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +tb_dsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +tb_dsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +tb_dsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +tb_dsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +tb_dsa.o: ../cryptlib.h eng_int.h tb_dsa.c
        +tb_ecdh.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_ecdh.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_ecdh.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_ecdh.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_ecdh.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_ecdh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_ecdh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tb_ecdh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_ecdh.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_ecdh.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_ecdh.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_ecdh.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdh.c
        +tb_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_ecdsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_ecdsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tb_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_ecdsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_ecdsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_ecdsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_ecdsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdsa.c
        +tb_pkmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_pkmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_pkmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_pkmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_pkmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_pkmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_pkmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_pkmeth.o: ../../include/openssl/objects.h
        +tb_pkmeth.o: ../../include/openssl/opensslconf.h
        +tb_pkmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_pkmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_pkmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_pkmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_pkmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
        +tb_pkmeth.o: tb_pkmeth.c
        +tb_rand.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_rand.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_rand.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_rand.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_rand.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_rand.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_rand.c
        +tb_rsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +tb_rsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +tb_rsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +tb_rsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +tb_rsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +tb_rsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +tb_rsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +tb_rsa.o: ../cryptlib.h eng_int.h tb_rsa.c
        +tb_store.o: ../../e_os.h ../../include/openssl/asn1.h
        +tb_store.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +tb_store.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +tb_store.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +tb_store.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +tb_store.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +tb_store.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +tb_store.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +tb_store.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +tb_store.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +tb_store.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +tb_store.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +tb_store.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_store.c
        diff --git a/vendor/openssl/openssl/crypto/engine/README b/vendor/openssl/openssl/crypto/engine/README
        new file mode 100644
        index 000000000..6b69b70f5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/README
        @@ -0,0 +1,211 @@
        +Notes: 2001-09-24
        +-----------------
        +
        +This "description" (if one chooses to call it that) needed some major updating
        +so here goes. This update addresses a change being made at the same time to
        +OpenSSL, and it pretty much completely restructures the underlying mechanics of
        +the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
        +for masochists" document *and* a rather extensive commit log message. (I'd get
        +lynched for sticking all this in CHANGES or the commit mails :-).
        +
        +ENGINE_TABLE underlies this restructuring, as described in the internal header
        +"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
        +tb_rsa.c, tb_dsa.c, etc.
        +
        +However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
        +I'll mention a bit about that first. EVP_CIPHER (and most of this applies
        +equally to EVP_MD for digests) is both a "method" and a algorithm/mode
        +identifier that, in the current API, "lingers". These cipher description +
        +implementation structures can be defined or obtained directly by applications,
        +or can be loaded "en masse" into EVP storage so that they can be catalogued and
        +searched in various ways, ie. two ways of encrypting with the "des_cbc"
        +algorithm/mode pair are;
        +
        +(i) directly;
        +     const EVP_CIPHER *cipher = EVP_des_cbc();
        +     EVP_EncryptInit(&ctx, cipher, key, iv);
        +     [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
        +
        +(ii) indirectly; 
        +     OpenSSL_add_all_ciphers();
        +     cipher = EVP_get_cipherbyname("des_cbc");
        +     EVP_EncryptInit(&ctx, cipher, key, iv);
        +     [ ... etc ... ]
        +
        +The latter is more generally used because it also allows ciphers/digests to be
        +looked up based on other identifiers which can be useful for automatic cipher
        +selection, eg. in SSL/TLS, or by user-controllable configuration.
        +
        +The important point about this is that EVP_CIPHER definitions and structures are
        +passed around with impunity and there is no safe way, without requiring massive
        +rewrites of many applications, to assume that EVP_CIPHERs can be reference
        +counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
        +comes from can "safely" be destroyed. Unless of course the way of getting to
        +such ciphers is via entirely distinct API calls that didn't exist before.
        +However existing API usage cannot be made to understand when an EVP_CIPHER
        +pointer, that has been passed to the caller, is no longer being used.
        +
        +The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
        +into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
        +ciphers simultaneously registers cipher *types* and cipher *implementations* -
        +they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
        +hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
        +solution is necessarily that ENGINE-provided ciphers simply are not registered,
        +stored, or exposed to the caller in the same manner as existing ciphers. This is
        +especially necessary considering the fact ENGINE uses reference counts to allow
        +for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
        +callers in the current API, support no such controls.
        +
        +Another sticking point for integrating cipher support into ENGINE is linkage.
        +Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
        +they are available *because* they're part of a giant ENGINE called "openssl".
        +Ie. all implementations *have* to come from an ENGINE, but we get round that by
        +having a giant ENGINE with all the software support encapsulated. This creates
        +linker hassles if nothing else - linking a 1-line application that calls 2 basic
        +RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
        +ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
        +continue with this approach for EVP_CIPHER support (even if it *was* possible)
        +we would lose our ability to link selectively by selectively loading certain
        +implementations of certain functionality. Touching any part of any kind of
        +crypto would result in massive static linkage of everything else. So the
        +solution is to change the way ENGINE feeds existing "classes", ie. how the
        +hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
        +for EVP_CIPHER, and EVP_MD.
        +
        +The way this is now being done is by mostly reverting back to how things used to
        +work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
        +was previously replaced by an "ENGINE" pointer and all RSA code that required
        +the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
        +temporarily get and use the ENGINE's RSA implementation. Apart from being more
        +efficient, switching back to each RSA having an RSA_METHOD pointer also allows
        +us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
        +for a fallback ENGINE that encapsulates default implementations - we can simply
        +have our RSA structure pointing its RSA_METHOD pointer to the software
        +implementation and have its ENGINE pointer set to NULL.
        +
        +A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
        +turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
        +and the existing EVP API functions that return "software" implementations and
        +descriptions remain untouched. However, the storage takes more meaning in terms
        +of "cipher description" and less meaning in terms of "implementation". When an
        +EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
        +begin en/decryption, the hooking to ENGINE comes into play. What happens is that
        +cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
        +reference) for any ENGINE that is registered to perform the algo/mode that the
        +provided EVP_CIPHER structure represents. Under normal circumstances, that
        +ENGINE code will return NULL because no ENGINEs will have had any cipher
        +implementations *registered*. As such, a NULL ENGINE pointer is stored in the
        +EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
        +context and so is used as the implementation. Pretty much how things work now
        +except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
        +
        +Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
        +combination represented by the provided EVP_CIPHER, then a functional reference
        +to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
        +That functional reference will be stored in the context (and released on
        +cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
        +definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
        +application will actually be replaced by an EVP_CIPHER from the registered
        +ENGINE - it will support the same algorithm/mode as the original but will be a
        +completely different implementation. Because this EVP_CIPHER isn't stored in the
        +EVP storage, nor is it returned to applications from traditional API functions,
        +there is no associated problem with it not having reference counts. And of
        +course, when one of these "private" cipher implementations is hooked into
        +EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional
        +reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is
        +safe.
        +
        +The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but
        +in essence it is simply an instantiation of "ENGINE_TABLE" code for use by
        +EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for
        +use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of
        +ENGINE_TABLE essentially provide linker-separation of the classes so that even
        +if ENGINEs implement *all* possible algorithms, an application using only
        +EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core
        +ENGINE code that is independant of class, and of course the ENGINE
        +implementation that the application loaded. It will *not* however link any
        +class-specific ENGINE code for digests, RSA, etc nor will it bleed over into
        +other APIs, such as the RSA/DSA/etc library code.
        +
        +ENGINE_TABLE is a little more complicated than may seem necessary but this is
        +mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load
        +DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and*
        +to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for
        +example tb_cipher.c, implements a hash-table keyed by integer "nid" values.
        +These nids provide the uniquenness of an algorithm/mode - and each nid will hash
        +to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of
        +pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some
        +caching tricks such that requests on that 'nid' will be cached and all future
        +requests will return immediately (well, at least with minimal operation) unless
        +a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is
        +that an application could have support for 10 ENGINEs statically linked
        +in, and the machine in question may not have any of the hardware those 10
        +ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we
        +want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise
        +each of those 10 ENGINEs. Instead, the first such request will try to do that
        +and will either return (and cache) a NULL ENGINE pointer or will return a
        +functional reference to the first that successfully initialised. In the latter
        +case it will also cache an extra functional reference to the ENGINE as a
        +"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable
        +that is unset only if un/registration takes place on that pile. Ie. if
        +implementations of "des_cbc" are added or removed. This behaviour can be
        +tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to
        +ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will
        +try to initialise from the "pile" will be those that are already initialised
        +(ie. it's simply an increment of the functional reference count, and no real
        +"initialisation" will take place).
        +
        +RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the
        +difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are
        +actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
        +not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
        +necessarily interoperable and don't have different flavours, only different
        +implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
        +or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
        +represents ENGINEs that implement the single "type" of RSA there is.
        +
        +Cleanup - the registration and unregistration may pose questions about how
        +cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the
        +application or EVP_CIPHER code releases its last reference to an ENGINE, the
        +ENGINE_PILE code may still have references and thus those ENGINEs will stay
        +hooked in forever). The way this is handled is via "unregistration". With these
        +new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that
        +is an algorithm-agnostic process. Even if initialised, it will not have
        +registered any of its implementations (to do so would link all class "table"
        +code despite the fact the application may use only ciphers, for example). This
        +is deliberately a distinct step. Moreover, registration and unregistration has
        +nothing to do with whether an ENGINE is *functional* or not (ie. you can even
        +register an ENGINE and its implementations without it being operational, you may
        +not even have the drivers to make it operate). What actually happens with
        +respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***"
        +functions. These functions are internal-only and each part of ENGINE code that
        +could require cleanup will, upon performing its first allocation, register a
        +callback with the "engine_cleanup" code. The other part of this that makes it
        +tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their
        +initialised state. So if RSA code asks for an ENGINE and no ENGINE has
        +registered an implementation, the code will simply return NULL and the tb_rsa.c
        +state will be unchanged. Thus, no cleanup is required unless registration takes
        +place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
        +callbacks calling each in turn, and will then internally delete its own storage
        +(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
        +part of a gracefull restart and the application wants to cleanup all state then
        +start again), the internal STACK storage will be freshly allocated. This is much
        +the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
        +initialised state, so only modification operations (not queries) will cause that
        +code to have to register a cleanup.
        +
        +What else? The bignum callbacks and associated ENGINE functions have been
        +removed for two obvious reasons; (i) there was no way to generalise them to the
        +mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM
        +method, and (ii) because of (i), there was no meaningful way for library or
        +application code to automatically hook and use ENGINE supplied bignum functions
        +anyway. Also, ENGINE_cpy() has been removed (although an internal-only version
        +exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
        +one and now certainly doesn't make sense in any generalised way. Some of the
        +RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
        +changes have now, as a consequence, been reverted back. This is because the
        +hooking of ENGINE is now automatic (and passive, it can interally use a NULL
        +ENGINE pointer to simply ignore ENGINE from then on).
        +
        +Hell, that should be enough for now ... comments welcome: geoff@openssl.org
        +
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_all.c b/vendor/openssl/openssl/crypto/engine/eng_all.c
        new file mode 100644
        index 000000000..6093376df
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_all.c
        @@ -0,0 +1,135 @@
        +/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "cryptlib.h"
        +#include "eng_int.h"
        +
        +void ENGINE_load_builtin_engines(void)
        +	{
        +	/* Some ENGINEs need this */
        +	OPENSSL_cpuid_setup();
        +#if 0
        +	/* There's no longer any need for an "openssl" ENGINE unless, one day,
        +	 * it is the *only* way for standard builtin implementations to be be
        +	 * accessed (ie. it would be possible to statically link binaries with
        +	 * *no* builtin implementations). */
        +	ENGINE_load_openssl();
        +#endif
        +#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
        +	ENGINE_load_cryptodev();
        +#endif
        +#ifndef OPENSSL_NO_RSAX
        +	ENGINE_load_rsax();
        +#endif
        +#ifndef OPENSSL_NO_RDRAND
        +	ENGINE_load_rdrand();
        +#endif
        +	ENGINE_load_dynamic();
        +#ifndef OPENSSL_NO_STATIC_ENGINE
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_4758_CCA
        +	ENGINE_load_4758cca();
        +#endif
        +#ifndef OPENSSL_NO_HW_AEP
        +	ENGINE_load_aep();
        +#endif
        +#ifndef OPENSSL_NO_HW_ATALLA
        +	ENGINE_load_atalla();
        +#endif
        +#ifndef OPENSSL_NO_HW_CSWIFT
        +	ENGINE_load_cswift();
        +#endif
        +#ifndef OPENSSL_NO_HW_NCIPHER
        +	ENGINE_load_chil();
        +#endif
        +#ifndef OPENSSL_NO_HW_NURON
        +	ENGINE_load_nuron();
        +#endif
        +#ifndef OPENSSL_NO_HW_SUREWARE
        +	ENGINE_load_sureware();
        +#endif
        +#ifndef OPENSSL_NO_HW_UBSEC
        +	ENGINE_load_ubsec();
        +#endif
        +#ifndef OPENSSL_NO_HW_PADLOCK
        +	ENGINE_load_padlock();
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_GOST
        +	ENGINE_load_gost();
        +#endif
        +#ifndef OPENSSL_NO_GMP
        +	ENGINE_load_gmp();
        +#endif
        +#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
        +	ENGINE_load_capi();
        +#endif
        +#endif
        +	ENGINE_register_all_complete();
        +	}
        +
        +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
        +void ENGINE_setup_bsd_cryptodev(void) {
        +	static int bsd_cryptodev_default_loaded = 0;
        +	if (!bsd_cryptodev_default_loaded) {
        +		ENGINE_load_cryptodev();
        +		ENGINE_register_all_complete();
        +	}
        +	bsd_cryptodev_default_loaded=1;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_cnf.c b/vendor/openssl/openssl/crypto/engine/eng_cnf.c
        new file mode 100644
        index 000000000..95c407001
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_cnf.c
        @@ -0,0 +1,259 @@
        +/* eng_cnf.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "eng_int.h"
        +#include <openssl/conf.h>
        +
        +/* #define ENGINE_CONF_DEBUG */
        +
        +/* ENGINE config module */
        +
        +static char *skip_dot(char *name)
        +	{
        +	char *p;
        +	p = strchr(name, '.');
        +	if (p)
        +		return p + 1;
        +	return name;
        +	}
        +
        +static STACK_OF(ENGINE) *initialized_engines = NULL;
        +
        +static int int_engine_init(ENGINE *e)
        +	{
        +	if (!ENGINE_init(e))
        +		return 0;
        +	if (!initialized_engines)
        +		initialized_engines = sk_ENGINE_new_null();
        +	if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
        +		{
        +		ENGINE_finish(e);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +	
        +
        +static int int_engine_configure(char *name, char *value, const CONF *cnf)
        +	{
        +	int i;
        +	int ret = 0;
        +	long do_init = -1;
        +	STACK_OF(CONF_VALUE) *ecmds;
        +	CONF_VALUE *ecmd = NULL;
        +	char *ctrlname, *ctrlvalue;
        +	ENGINE *e = NULL;
        +	int soft = 0;
        +
        +	name = skip_dot(name);
        +#ifdef ENGINE_CONF_DEBUG
        +	fprintf(stderr, "Configuring engine %s\n", name);
        +#endif
        +	/* Value is a section containing ENGINE commands */
        +	ecmds = NCONF_get_section(cnf, value);
        +
        +	if (!ecmds)
        +		{
        +		ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
        +		return 0;
        +		}
        +
        +	for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
        +		{
        +		ecmd = sk_CONF_VALUE_value(ecmds, i);
        +		ctrlname = skip_dot(ecmd->name);
        +		ctrlvalue = ecmd->value;
        +#ifdef ENGINE_CONF_DEBUG
        +	fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
        +#endif
        +
        +		/* First handle some special pseudo ctrls */
        +
        +		/* Override engine name to use */
        +		if (!strcmp(ctrlname, "engine_id"))
        +			name = ctrlvalue;
        +		else if (!strcmp(ctrlname, "soft_load"))
        +			soft = 1;
        +		/* Load a dynamic ENGINE */
        +		else if (!strcmp(ctrlname, "dynamic_path"))
        +			{
        +			e = ENGINE_by_id("dynamic");
        +			if (!e)
        +				goto err;
        +			if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
        +				goto err;
        +			if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
        +				goto err;
        +			if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
        +				goto err;
        +			}
        +		/* ... add other pseudos here ... */
        +		else
        +			{
        +			/* At this point we need an ENGINE structural reference
        +			 * if we don't already have one.
        +			 */
        +			if (!e)
        +				{
        +				e = ENGINE_by_id(name);
        +				if (!e && soft)
        +					{
        +					ERR_clear_error();
        +					return 1;
        +					}
        +				if (!e)
        +					goto err;
        +				}
        +			/* Allow "EMPTY" to mean no value: this allows a valid
        +			 * "value" to be passed to ctrls of type NO_INPUT
        +		 	 */
        +			if (!strcmp(ctrlvalue, "EMPTY"))
        +				ctrlvalue = NULL;
        +			if (!strcmp(ctrlname, "init"))
        +				{
        +				if (!NCONF_get_number_e(cnf, value, "init", &do_init))
        +					goto err;
        +				if (do_init == 1)
        +					{
        +					if (!int_engine_init(e))
        +						goto err;
        +					}
        +				else if (do_init != 0)
        +					{
        +					ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
        +					goto err;
        +					}
        +				}
        +			else if (!strcmp(ctrlname, "default_algorithms"))
        +				{
        +				if (!ENGINE_set_default_string(e, ctrlvalue))
        +					goto err;
        +				}
        +			else if (!ENGINE_ctrl_cmd_string(e,
        +					ctrlname, ctrlvalue, 0))
        +				goto err;
        +			}
        +
        +
        +
        +		}
        +	if (e && (do_init == -1) && !int_engine_init(e))
        +		{
        +		ecmd = NULL;
        +		goto err;
        +		}
        +	ret = 1;
        +	err:
        +	if (ret != 1)
        +		{
        +		ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
        +		if (ecmd)
        +			ERR_add_error_data(6, "section=", ecmd->section, 
        +						", name=", ecmd->name,
        +						", value=", ecmd->value);
        +		}
        +	if (e)
        +		ENGINE_free(e);
        +	return ret;
        +	}
        +
        +
        +static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
        +	{
        +	STACK_OF(CONF_VALUE) *elist;
        +	CONF_VALUE *cval;
        +	int i;
        +#ifdef ENGINE_CONF_DEBUG
        +	fprintf(stderr, "Called engine module: name %s, value %s\n",
        +			CONF_imodule_get_name(md), CONF_imodule_get_value(md));
        +#endif
        +	/* Value is a section containing ENGINEs to configure */
        +	elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
        +
        +	if (!elist)
        +		{
        +		ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
        +		return 0;
        +		}
        +
        +	for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
        +		{
        +		cval = sk_CONF_VALUE_value(elist, i);
        +		if (!int_engine_configure(cval->name, cval->value, cnf))
        +			return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static void int_engine_module_finish(CONF_IMODULE *md)
        +	{
        +	ENGINE *e;
        +	while ((e = sk_ENGINE_pop(initialized_engines)))
        +		ENGINE_finish(e);
        +	sk_ENGINE_free(initialized_engines);
        +	initialized_engines = NULL;
        +	}
        +	
        +
        +void ENGINE_add_conf_module(void)
        +	{
        +	CONF_module_add("engines",
        +			int_engine_module_init,
        +			int_engine_module_finish);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_cryptodev.c b/vendor/openssl/openssl/crypto/engine/eng_cryptodev.c
        new file mode 100644
        index 000000000..5a715aca4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_cryptodev.c
        @@ -0,0 +1,1450 @@
        +/*
        + * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
        + * Copyright (c) 2002 Theo de Raadt
        + * Copyright (c) 2002 Markus Friedl
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
        + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        + * DISCLAIMED.  IN NO EVENT SHALL THE 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.
        + *
        + */
        +
        +#include <openssl/objects.h>
        +#include <openssl/engine.h>
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +
        +#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
        +	(defined(OpenBSD) || defined(__FreeBSD__))
        +#include <sys/param.h>
        +# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
        +#  define HAVE_CRYPTODEV
        +# endif
        +# if (OpenBSD >= 200110)
        +#  define HAVE_SYSLOG_R
        +# endif
        +#endif
        +
        +#ifndef HAVE_CRYPTODEV
        +
        +void
        +ENGINE_load_cryptodev(void)
        +{
        +	/* This is a NOP on platforms without /dev/crypto */
        +	return;
        +}
        +
        +#else 
        + 
        +#include <sys/types.h>
        +#include <crypto/cryptodev.h>
        +#include <crypto/dh/dh.h>
        +#include <crypto/dsa/dsa.h>
        +#include <crypto/err/err.h>
        +#include <crypto/rsa/rsa.h>
        +#include <sys/ioctl.h>
        +#include <errno.h>
        +#include <stdio.h>
        +#include <unistd.h>
        +#include <fcntl.h>
        +#include <stdarg.h>
        +#include <syslog.h>
        +#include <errno.h>
        +#include <string.h>
        +
        +struct dev_crypto_state {
        +	struct session_op d_sess;
        +	int d_fd;
        +
        +#ifdef USE_CRYPTODEV_DIGESTS
        +	char dummy_mac_key[HASH_MAX_LEN];
        +
        +	unsigned char digest_res[HASH_MAX_LEN];
        +	char *mac_data;
        +	int mac_len;
        +#endif
        +};
        +
        +static u_int32_t cryptodev_asymfeat = 0;
        +
        +static int get_asym_dev_crypto(void);
        +static int open_dev_crypto(void);
        +static int get_dev_crypto(void);
        +static int get_cryptodev_ciphers(const int **cnids);
        +#ifdef USE_CRYPTODEV_DIGESTS
        +static int get_cryptodev_digests(const int **cnids);
        +#endif
        +static int cryptodev_usable_ciphers(const int **nids);
        +static int cryptodev_usable_digests(const int **nids);
        +static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +    const unsigned char *in, size_t inl);
        +static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +    const unsigned char *iv, int enc);
        +static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
        +static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +    const int **nids, int nid);
        +static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
        +    const int **nids, int nid);
        +static int bn2crparam(const BIGNUM *a, struct crparam *crp);
        +static int crparam2bn(struct crparam *crp, BIGNUM *a);
        +static void zapparams(struct crypt_kop *kop);
        +static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
        +    int slen, BIGNUM *s);
        +
        +static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
        +    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
        +    RSA *rsa, BN_CTX *ctx);
        +static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
        +    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
        +    BN_CTX *ctx, BN_MONT_CTX *mont);
        +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
        +    int dlen, DSA *dsa);
        +static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
        +    DSA_SIG *sig, DSA *dsa);
        +static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +    BN_MONT_CTX *m_ctx);
        +static int cryptodev_dh_compute_key(unsigned char *key,
        +    const BIGNUM *pub_key, DH *dh);
        +static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
        +    void (*f)(void));
        +void ENGINE_load_cryptodev(void);
        +
        +static const ENGINE_CMD_DEFN cryptodev_defns[] = {
        +	{ 0, NULL, NULL, 0 }
        +};
        +
        +static struct {
        +	int	id;
        +	int	nid;
        +	int	ivmax;
        +	int	keylen;
        +} ciphers[] = {
        +	{ CRYPTO_ARC4,			NID_rc4,		0,	16, },
        +	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
        +	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
        +	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
        +	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
        +	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
        +	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
        +	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
        +	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
        +	{ 0,				NID_undef,		0,	 0, },
        +};
        +
        +#ifdef USE_CRYPTODEV_DIGESTS
        +static struct {
        +	int	id;
        +	int	nid;
        +	int 	keylen;
        +} digests[] = {
        +	{ CRYPTO_MD5_HMAC,		NID_hmacWithMD5,	16},
        +	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20},
        +	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
        +	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
        +	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
        +	{ CRYPTO_MD5,			NID_md5,		16},
        +	{ CRYPTO_SHA1,			NID_sha1,		20},
        +	{ 0,				NID_undef,		0},
        +};
        +#endif
        +
        +/*
        + * Return a fd if /dev/crypto seems usable, 0 otherwise.
        + */
        +static int
        +open_dev_crypto(void)
        +{
        +	static int fd = -1;
        +
        +	if (fd == -1) {
        +		if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
        +			return (-1);
        +		/* close on exec */
        +		if (fcntl(fd, F_SETFD, 1) == -1) {
        +			close(fd);
        +			fd = -1;
        +			return (-1);
        +		}
        +	}
        +	return (fd);
        +}
        +
        +static int
        +get_dev_crypto(void)
        +{
        +	int fd, retfd;
        +
        +	if ((fd = open_dev_crypto()) == -1)
        +		return (-1);
        +#ifndef CRIOGET_NOT_NEEDED
        +	if (ioctl(fd, CRIOGET, &retfd) == -1)
        +		return (-1);
        +
        +	/* close on exec */
        +	if (fcntl(retfd, F_SETFD, 1) == -1) {
        +		close(retfd);
        +		return (-1);
        +	}
        +#else
        +        retfd = fd;
        +#endif
        +	return (retfd);
        +}
        +
        +static void put_dev_crypto(int fd)
        +{
        +#ifndef CRIOGET_NOT_NEEDED
        +	close(fd);
        +#endif
        +}
        +
        +/* Caching version for asym operations */
        +static int
        +get_asym_dev_crypto(void)
        +{
        +	static int fd = -1;
        +
        +	if (fd == -1)
        +		fd = get_dev_crypto();
        +	return fd;
        +}
        +
        +/*
        + * Find out what ciphers /dev/crypto will let us have a session for.
        + * XXX note, that some of these openssl doesn't deal with yet!
        + * returning them here is harmless, as long as we return NULL
        + * when asked for a handler in the cryptodev_engine_ciphers routine
        + */
        +static int
        +get_cryptodev_ciphers(const int **cnids)
        +{
        +	static int nids[CRYPTO_ALGORITHM_MAX];
        +	struct session_op sess;
        +	int fd, i, count = 0;
        +
        +	if ((fd = get_dev_crypto()) < 0) {
        +		*cnids = NULL;
        +		return (0);
        +	}
        +	memset(&sess, 0, sizeof(sess));
        +	sess.key = (caddr_t)"123456789abcdefghijklmno";
        +
        +	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
        +		if (ciphers[i].nid == NID_undef)
        +			continue;
        +		sess.cipher = ciphers[i].id;
        +		sess.keylen = ciphers[i].keylen;
        +		sess.mac = 0;
        +		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
        +		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
        +			nids[count++] = ciphers[i].nid;
        +	}
        +	put_dev_crypto(fd);
        +
        +	if (count > 0)
        +		*cnids = nids;
        +	else
        +		*cnids = NULL;
        +	return (count);
        +}
        +
        +#ifdef USE_CRYPTODEV_DIGESTS
        +/*
        + * Find out what digests /dev/crypto will let us have a session for.
        + * XXX note, that some of these openssl doesn't deal with yet!
        + * returning them here is harmless, as long as we return NULL
        + * when asked for a handler in the cryptodev_engine_digests routine
        + */
        +static int
        +get_cryptodev_digests(const int **cnids)
        +{
        +	static int nids[CRYPTO_ALGORITHM_MAX];
        +	struct session_op sess;
        +	int fd, i, count = 0;
        +
        +	if ((fd = get_dev_crypto()) < 0) {
        +		*cnids = NULL;
        +		return (0);
        +	}
        +	memset(&sess, 0, sizeof(sess));
        +	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
        +	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
        +		if (digests[i].nid == NID_undef)
        +			continue;
        +		sess.mac = digests[i].id;
        +		sess.mackeylen = digests[i].keylen;
        +		sess.cipher = 0;
        +		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
        +		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
        +			nids[count++] = digests[i].nid;
        +	}
        +	put_dev_crypto(fd);
        +
        +	if (count > 0)
        +		*cnids = nids;
        +	else
        +		*cnids = NULL;
        +	return (count);
        +}
        +#endif  /* 0 */
        +
        +/*
        + * Find the useable ciphers|digests from dev/crypto - this is the first
        + * thing called by the engine init crud which determines what it
        + * can use for ciphers from this engine. We want to return
        + * only what we can do, anythine else is handled by software.
        + *
        + * If we can't initialize the device to do anything useful for
        + * any reason, we want to return a NULL array, and 0 length,
        + * which forces everything to be done is software. By putting
        + * the initalization of the device in here, we ensure we can
        + * use this engine as the default, and if for whatever reason
        + * /dev/crypto won't do what we want it will just be done in
        + * software
        + *
        + * This can (should) be greatly expanded to perhaps take into
        + * account speed of the device, and what we want to do.
        + * (although the disabling of particular alg's could be controlled
        + * by the device driver with sysctl's.) - this is where we
        + * want most of the decisions made about what we actually want
        + * to use from /dev/crypto.
        + */
        +static int
        +cryptodev_usable_ciphers(const int **nids)
        +{
        +	return (get_cryptodev_ciphers(nids));
        +}
        +
        +static int
        +cryptodev_usable_digests(const int **nids)
        +{
        +#ifdef USE_CRYPTODEV_DIGESTS
        +	return (get_cryptodev_digests(nids));
        +#else
        +	/*
        +	 * XXXX just disable all digests for now, because it sucks.
        +	 * we need a better way to decide this - i.e. I may not
        +	 * want digests on slow cards like hifn on fast machines,
        +	 * but might want them on slow or loaded machines, etc.
        +	 * will also want them when using crypto cards that don't
        +	 * suck moose gonads - would be nice to be able to decide something
        +	 * as reasonable default without having hackery that's card dependent.
        +	 * of course, the default should probably be just do everything,
        +	 * with perhaps a sysctl to turn algoritms off (or have them off
        +	 * by default) on cards that generally suck like the hifn.
        +	 */
        +	*nids = NULL;
        +	return (0);
        +#endif
        +}
        +
        +static int
        +cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +    const unsigned char *in, size_t inl)
        +{
        +	struct crypt_op cryp;
        +	struct dev_crypto_state *state = ctx->cipher_data;
        +	struct session_op *sess = &state->d_sess;
        +	const void *iiv;
        +	unsigned char save_iv[EVP_MAX_IV_LENGTH];
        +
        +	if (state->d_fd < 0)
        +		return (0);
        +	if (!inl)
        +		return (1);
        +	if ((inl % ctx->cipher->block_size) != 0)
        +		return (0);
        +
        +	memset(&cryp, 0, sizeof(cryp));
        +
        +	cryp.ses = sess->ses;
        +	cryp.flags = 0;
        +	cryp.len = inl;
        +	cryp.src = (caddr_t) in;
        +	cryp.dst = (caddr_t) out;
        +	cryp.mac = 0;
        +
        +	cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
        +
        +	if (ctx->cipher->iv_len) {
        +		cryp.iv = (caddr_t) ctx->iv;
        +		if (!ctx->encrypt) {
        +			iiv = in + inl - ctx->cipher->iv_len;
        +			memcpy(save_iv, iiv, ctx->cipher->iv_len);
        +		}
        +	} else
        +		cryp.iv = NULL;
        +
        +	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
        +		/* XXX need better errror handling
        +		 * this can fail for a number of different reasons.
        +		 */
        +		return (0);
        +	}
        +
        +	if (ctx->cipher->iv_len) {
        +		if (ctx->encrypt)
        +			iiv = out + inl - ctx->cipher->iv_len;
        +		else
        +			iiv = save_iv;
        +		memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
        +	}
        +	return (1);
        +}
        +
        +static int
        +cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +    const unsigned char *iv, int enc)
        +{
        +	struct dev_crypto_state *state = ctx->cipher_data;
        +	struct session_op *sess = &state->d_sess;
        +	int cipher = -1, i;
        +
        +	for (i = 0; ciphers[i].id; i++)
        +		if (ctx->cipher->nid == ciphers[i].nid &&
        +		    ctx->cipher->iv_len <= ciphers[i].ivmax &&
        +		    ctx->key_len == ciphers[i].keylen) {
        +			cipher = ciphers[i].id;
        +			break;
        +		}
        +
        +	if (!ciphers[i].id) {
        +		state->d_fd = -1;
        +		return (0);
        +	}
        +
        +	memset(sess, 0, sizeof(struct session_op));
        +
        +	if ((state->d_fd = get_dev_crypto()) < 0)
        +		return (0);
        +
        +	sess->key = (caddr_t)key;
        +	sess->keylen = ctx->key_len;
        +	sess->cipher = cipher;
        +
        +	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
        +		put_dev_crypto(state->d_fd);
        +		state->d_fd = -1;
        +		return (0);
        +	}
        +	return (1);
        +}
        +
        +/*
        + * free anything we allocated earlier when initting a
        + * session, and close the session.
        + */
        +static int
        +cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
        +{
        +	int ret = 0;
        +	struct dev_crypto_state *state = ctx->cipher_data;
        +	struct session_op *sess = &state->d_sess;
        +
        +	if (state->d_fd < 0)
        +		return (0);
        +
        +	/* XXX if this ioctl fails, someting's wrong. the invoker
        +	 * may have called us with a bogus ctx, or we could
        +	 * have a device that for whatever reason just doesn't
        +	 * want to play ball - it's not clear what's right
        +	 * here - should this be an error? should it just
        +	 * increase a counter, hmm. For right now, we return
        +	 * 0 - I don't believe that to be "right". we could
        +	 * call the gorpy openssl lib error handlers that
        +	 * print messages to users of the library. hmm..
        +	 */
        +
        +	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
        +		ret = 0;
        +	} else {
        +		ret = 1;
        +	}
        +	put_dev_crypto(state->d_fd);
        +	state->d_fd = -1;
        +
        +	return (ret);
        +}
        +
        +/*
        + * libcrypto EVP stuff - this is how we get wired to EVP so the engine
        + * gets called when libcrypto requests a cipher NID.
        + */
        +
        +/* RC4 */
        +const EVP_CIPHER cryptodev_rc4 = {
        +	NID_rc4,
        +	1, 16, 0,
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	NULL,
        +	NULL,
        +	NULL
        +};
        +
        +/* DES CBC EVP */
        +const EVP_CIPHER cryptodev_des_cbc = {
        +	NID_des_cbc,
        +	8, 8, 8,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +/* 3DES CBC EVP */
        +const EVP_CIPHER cryptodev_3des_cbc = {
        +	NID_des_ede3_cbc,
        +	8, 24, 8,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +const EVP_CIPHER cryptodev_bf_cbc = {
        +	NID_bf_cbc,
        +	8, 16, 8,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +const EVP_CIPHER cryptodev_cast_cbc = {
        +	NID_cast5_cbc,
        +	8, 16, 8,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +const EVP_CIPHER cryptodev_aes_cbc = {
        +	NID_aes_128_cbc,
        +	16, 16, 16,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +const EVP_CIPHER cryptodev_aes_192_cbc = {
        +	NID_aes_192_cbc,
        +	16, 24, 16,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +const EVP_CIPHER cryptodev_aes_256_cbc = {
        +	NID_aes_256_cbc,
        +	16, 32, 16,
        +	EVP_CIPH_CBC_MODE,
        +	cryptodev_init_key,
        +	cryptodev_cipher,
        +	cryptodev_cleanup,
        +	sizeof(struct dev_crypto_state),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL
        +};
        +
        +/*
        + * Registered by the ENGINE when used to find out how to deal with
        + * a particular NID in the ENGINE. this says what we'll do at the
        + * top level - note, that list is restricted by what we answer with
        + */
        +static int
        +cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +    const int **nids, int nid)
        +{
        +	if (!cipher)
        +		return (cryptodev_usable_ciphers(nids));
        +
        +	switch (nid) {
        +	case NID_rc4:
        +		*cipher = &cryptodev_rc4;
        +		break;
        +	case NID_des_ede3_cbc:
        +		*cipher = &cryptodev_3des_cbc;
        +		break;
        +	case NID_des_cbc:
        +		*cipher = &cryptodev_des_cbc;
        +		break;
        +	case NID_bf_cbc:
        +		*cipher = &cryptodev_bf_cbc;
        +		break;
        +	case NID_cast5_cbc:
        +		*cipher = &cryptodev_cast_cbc;
        +		break;
        +	case NID_aes_128_cbc:
        +		*cipher = &cryptodev_aes_cbc;
        +		break;
        +	case NID_aes_192_cbc:
        +		*cipher = &cryptodev_aes_192_cbc;
        +		break;
        +	case NID_aes_256_cbc:
        +		*cipher = &cryptodev_aes_256_cbc;
        +		break;
        +	default:
        +		*cipher = NULL;
        +		break;
        +	}
        +	return (*cipher != NULL);
        +}
        +
        +
        +#ifdef USE_CRYPTODEV_DIGESTS
        +
        +/* convert digest type to cryptodev */
        +static int
        +digest_nid_to_cryptodev(int nid)
        +{
        +	int i;
        +
        +	for (i = 0; digests[i].id; i++)
        +		if (digests[i].nid == nid)
        +			return (digests[i].id);
        +	return (0);
        +}
        +
        +
        +static int
        +digest_key_length(int nid)
        +{
        +	int i;
        +
        +	for (i = 0; digests[i].id; i++)
        +		if (digests[i].nid == nid)
        +			return digests[i].keylen;
        +	return (0);
        +}
        +
        +
        +static int cryptodev_digest_init(EVP_MD_CTX *ctx)
        +{
        +	struct dev_crypto_state *state = ctx->md_data;
        +	struct session_op *sess = &state->d_sess;
        +	int digest;
        +
        +	if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
        +		printf("cryptodev_digest_init: Can't get digest \n");
        +		return (0);
        +	}
        +
        +	memset(state, 0, sizeof(struct dev_crypto_state));
        +
        +	if ((state->d_fd = get_dev_crypto()) < 0) {
        +		printf("cryptodev_digest_init: Can't get Dev \n");
        +		return (0);
        +	}
        +
        +	sess->mackey = state->dummy_mac_key;
        +	sess->mackeylen = digest_key_length(ctx->digest->type);
        +	sess->mac = digest;
        +
        +	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
        +		put_dev_crypto(state->d_fd);
        +		state->d_fd = -1;
        +		printf("cryptodev_digest_init: Open session failed\n");
        +		return (0);
        +	}
        +
        +	return (1);
        +}
        +
        +static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
        +		size_t count)
        +{
        +	struct crypt_op cryp;
        +	struct dev_crypto_state *state = ctx->md_data;
        +	struct session_op *sess = &state->d_sess;
        +
        +	if (!data || state->d_fd < 0) {
        +		printf("cryptodev_digest_update: illegal inputs \n");
        +		return (0);
        +	}
        +
        +	if (!count) {
        +		return (0);
        +	}
        +
        +	if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
        +		/* if application doesn't support one buffer */
        +		state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
        +
        +		if (!state->mac_data) {
        +			printf("cryptodev_digest_update: realloc failed\n");
        +			return (0);
        +		}
        +
        +		memcpy(state->mac_data + state->mac_len, data, count);
        +   		state->mac_len += count;
        +	
        +		return (1);
        +	}
        +
        +	memset(&cryp, 0, sizeof(cryp));
        +
        +	cryp.ses = sess->ses;
        +	cryp.flags = 0;
        +	cryp.len = count;
        +	cryp.src = (caddr_t) data;
        +	cryp.dst = NULL;
        +	cryp.mac = (caddr_t) state->digest_res;
        +	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
        +		printf("cryptodev_digest_update: digest failed\n");
        +		return (0);
        +	}
        +	return (1);
        +}
        +
        +
        +static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
        +{
        +	struct crypt_op cryp;
        +	struct dev_crypto_state *state = ctx->md_data;
        +	struct session_op *sess = &state->d_sess;
        +
        +	int ret = 1;
        +
        +	if (!md || state->d_fd < 0) {
        +		printf("cryptodev_digest_final: illegal input\n");
        +		return(0);
        +	}
        +
        +	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
        +		/* if application doesn't support one buffer */
        +		memset(&cryp, 0, sizeof(cryp));
        +		cryp.ses = sess->ses;
        +		cryp.flags = 0;
        +		cryp.len = state->mac_len;
        +		cryp.src = state->mac_data;
        +		cryp.dst = NULL;
        +		cryp.mac = (caddr_t)md;
        +		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
        +			printf("cryptodev_digest_final: digest failed\n");
        +			return (0);
        +		}
        +
        +		return 1;
        +	}
        +
        +	memcpy(md, state->digest_res, ctx->digest->md_size);
        +
        +	return (ret);
        +}
        +
        +
        +static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
        +{
        +	int ret = 1;
        +	struct dev_crypto_state *state = ctx->md_data;
        +	struct session_op *sess = &state->d_sess;
        +
        +	if (state == NULL)
        +	  return 0;
        +
        +	if (state->d_fd < 0) {
        +		printf("cryptodev_digest_cleanup: illegal input\n");
        +		return (0);
        +	}
        +
        +	if (state->mac_data) {
        +		OPENSSL_free(state->mac_data);
        +		state->mac_data = NULL;
        +		state->mac_len = 0;
        +	}
        +
        +	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
        +		printf("cryptodev_digest_cleanup: failed to close session\n");
        +		ret = 0;
        +	} else {
        +		ret = 1;
        +	}
        +	put_dev_crypto(state->d_fd);	
        +	state->d_fd = -1;
        +
        +	return (ret);
        +}
        +
        +static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
        +{
        +	struct dev_crypto_state *fstate = from->md_data;
        +	struct dev_crypto_state *dstate = to->md_data;
        +	struct session_op *sess;
        +	int digest;
        +
        +	if (dstate == NULL || fstate == NULL)
        +	  return 1;
        +
        +       	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
        +
        +	sess = &dstate->d_sess;
        +
        +	digest = digest_nid_to_cryptodev(to->digest->type);
        +
        +	sess->mackey = dstate->dummy_mac_key;
        +	sess->mackeylen = digest_key_length(to->digest->type);
        +	sess->mac = digest;
        +
        +	dstate->d_fd = get_dev_crypto();
        +
        +	if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
        +		put_dev_crypto(dstate->d_fd);
        +		dstate->d_fd = -1;
        +		printf("cryptodev_digest_init: Open session failed\n");
        +		return (0);
        +	}
        +
        +	if (fstate->mac_len != 0) {
        +	        if (fstate->mac_data != NULL)
        +	                {
        +        		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
        +	        	memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
        +           		dstate->mac_len = fstate->mac_len;
        +	        	}
        +	}
        +
        +	return 1;
        +}
        +
        +
        +const EVP_MD cryptodev_sha1 = {
        +	NID_sha1,
        +	NID_undef, 
        +	SHA_DIGEST_LENGTH, 
        +	EVP_MD_FLAG_ONESHOT,
        +	cryptodev_digest_init,
        +	cryptodev_digest_update,
        +	cryptodev_digest_final,
        +	cryptodev_digest_copy,
        +	cryptodev_digest_cleanup,
        +	EVP_PKEY_NULL_method,
        +	SHA_CBLOCK,
        +	sizeof(struct dev_crypto_state),
        +};
        +
        +const EVP_MD cryptodev_md5 = {
        +	NID_md5,
        +	NID_undef, 
        +	16 /* MD5_DIGEST_LENGTH */, 
        +	EVP_MD_FLAG_ONESHOT,
        +	cryptodev_digest_init,
        +	cryptodev_digest_update,
        +	cryptodev_digest_final,
        +	cryptodev_digest_copy,
        +	cryptodev_digest_cleanup,
        +	EVP_PKEY_NULL_method,
        +	64 /* MD5_CBLOCK */,
        +	sizeof(struct dev_crypto_state),
        +};
        +
        +#endif /* USE_CRYPTODEV_DIGESTS */
        +
        +
        +static int
        +cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
        +    const int **nids, int nid)
        +{
        +	if (!digest)
        +		return (cryptodev_usable_digests(nids));
        +
        +	switch (nid) {
        +#ifdef USE_CRYPTODEV_DIGESTS
        +	case NID_md5:
        +		*digest = &cryptodev_md5; 
        +		break;
        +	case NID_sha1:
        +		*digest = &cryptodev_sha1;
        + 		break;
        +	default:
        +#endif /* USE_CRYPTODEV_DIGESTS */
        +		*digest = NULL;
        +		break;
        +	}
        +	return (*digest != NULL);
        +}
        +
        +/*
        + * Convert a BIGNUM to the representation that /dev/crypto needs.
        + * Upon completion of use, the caller is responsible for freeing
        + * crp->crp_p.
        + */
        +static int
        +bn2crparam(const BIGNUM *a, struct crparam *crp)
        +{
        +	int i, j, k;
        +	ssize_t bytes, bits;
        +	u_char *b;
        +
        +	crp->crp_p = NULL;
        +	crp->crp_nbits = 0;
        +
        +	bits = BN_num_bits(a);
        +	bytes = (bits + 7) / 8;
        +
        +	b = malloc(bytes);
        +	if (b == NULL)
        +		return (1);
        +	memset(b, 0, bytes);
        +
        +	crp->crp_p = (caddr_t) b;
        +	crp->crp_nbits = bits;
        +
        +	for (i = 0, j = 0; i < a->top; i++) {
        +		for (k = 0; k < BN_BITS2 / 8; k++) {
        +			if ((j + k) >= bytes)
        +				return (0);
        +			b[j + k] = a->d[i] >> (k * 8);
        +		}
        +		j += BN_BITS2 / 8;
        +	}
        +	return (0);
        +}
        +
        +/* Convert a /dev/crypto parameter to a BIGNUM */
        +static int
        +crparam2bn(struct crparam *crp, BIGNUM *a)
        +{
        +	u_int8_t *pd;
        +	int i, bytes;
        +
        +	bytes = (crp->crp_nbits + 7) / 8;
        +
        +	if (bytes == 0)
        +		return (-1);
        +
        +	if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
        +		return (-1);
        +
        +	for (i = 0; i < bytes; i++)
        +		pd[i] = crp->crp_p[bytes - i - 1];
        +
        +	BN_bin2bn(pd, bytes, a);
        +	free(pd);
        +
        +	return (0);
        +}
        +
        +static void
        +zapparams(struct crypt_kop *kop)
        +{
        +	int i;
        +
        +	for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
        +		if (kop->crk_param[i].crp_p)
        +			free(kop->crk_param[i].crp_p);
        +		kop->crk_param[i].crp_p = NULL;
        +		kop->crk_param[i].crp_nbits = 0;
        +	}
        +}
        +
        +static int
        +cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
        +{
        +	int fd, ret = -1;
        +
        +	if ((fd = get_asym_dev_crypto()) < 0)
        +		return (ret);
        +
        +	if (r) {
        +		kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
        +		kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
        +		kop->crk_oparams++;
        +	}
        +	if (s) {
        +		kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
        +		kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
        +		kop->crk_oparams++;
        +	}
        +
        +	if (ioctl(fd, CIOCKEY, kop) == 0) {
        +		if (r)
        +			crparam2bn(&kop->crk_param[kop->crk_iparams], r);
        +		if (s)
        +			crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
        +		ret = 0;
        +	}
        +
        +	return (ret);
        +}
        +
        +static int
        +cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        +{
        +	struct crypt_kop kop;
        +	int ret = 1;
        +
        +	/* Currently, we know we can do mod exp iff we can do any
        +	 * asymmetric operations at all.
        +	 */
        +	if (cryptodev_asymfeat == 0) {
        +		ret = BN_mod_exp(r, a, p, m, ctx);
        +		return (ret);
        +	}
        +
        +	memset(&kop, 0, sizeof kop);
        +	kop.crk_op = CRK_MOD_EXP;
        +
        +	/* inputs: a^p % m */
        +	if (bn2crparam(a, &kop.crk_param[0]))
        +		goto err;
        +	if (bn2crparam(p, &kop.crk_param[1]))
        +		goto err;
        +	if (bn2crparam(m, &kop.crk_param[2]))
        +		goto err;
        +	kop.crk_iparams = 3;
        +
        +	if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
        +		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +		printf("OCF asym process failed, Running in software\n");
        +		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
        +
        +	} else if (ECANCELED == kop.crk_status) {
        +		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +		printf("OCF hardware operation cancelled. Running in Software\n");
        +		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
        +	}
        +	/* else cryptodev operation worked ok ==> ret = 1*/
        +
        +err:
        +	zapparams(&kop);
        +	return (ret);
        +}
        +
        +static int
        +cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +{
        +	int r;
        +	ctx = BN_CTX_new();
        +	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
        +	BN_CTX_free(ctx);
        +	return (r);
        +}
        +
        +static int
        +cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +{
        +	struct crypt_kop kop;
        +	int ret = 1;
        +
        +	if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
        +		/* XXX 0 means failure?? */
        +		return (0);
        +	}
        +
        +	memset(&kop, 0, sizeof kop);
        +	kop.crk_op = CRK_MOD_EXP_CRT;
        +	/* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
        +	if (bn2crparam(rsa->p, &kop.crk_param[0]))
        +		goto err;
        +	if (bn2crparam(rsa->q, &kop.crk_param[1]))
        +		goto err;
        +	if (bn2crparam(I, &kop.crk_param[2]))
        +		goto err;
        +	if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
        +		goto err;
        +	if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
        +		goto err;
        +	if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
        +		goto err;
        +	kop.crk_iparams = 6;
        +
        +	if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
        +		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +		printf("OCF asym process failed, running in Software\n");
        +		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
        +
        +	} else if (ECANCELED == kop.crk_status) {
        +		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +		printf("OCF hardware operation cancelled. Running in Software\n");
        +		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
        +	}
        +	/* else cryptodev operation worked ok ==> ret = 1*/
        +
        +err:
        +	zapparams(&kop);
        +	return (ret);
        +}
        +
        +static RSA_METHOD cryptodev_rsa = {
        +	"cryptodev RSA method",
        +	NULL,				/* rsa_pub_enc */
        +	NULL,				/* rsa_pub_dec */
        +	NULL,				/* rsa_priv_enc */
        +	NULL,				/* rsa_priv_dec */
        +	NULL,
        +	NULL,
        +	NULL,				/* init */
        +	NULL,				/* finish */
        +	0,				/* flags */
        +	NULL,				/* app_data */
        +	NULL,				/* rsa_sign */
        +	NULL				/* rsa_verify */
        +};
        +
        +static int
        +cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
        +    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +{
        +	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
        +}
        +
        +static int
        +cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
        +    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
        +    BN_CTX *ctx, BN_MONT_CTX *mont)
        +{
        +	BIGNUM t2;
        +	int ret = 0;
        +
        +	BN_init(&t2);
        +
        +	/* v = ( g^u1 * y^u2 mod p ) mod q */
        +	/* let t1 = g ^ u1 mod p */
        +	ret = 0;
        +
        +	if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
        +		goto err;
        +
        +	/* let t2 = y ^ u2 mod p */
        +	if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
        +		goto err;
        +	/* let u1 = t1 * t2 mod p */
        +	if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
        +		goto err;
        +
        +	BN_copy(t1,u1);
        +
        +	ret = 1;
        +err:
        +	BN_free(&t2);
        +	return(ret);
        +}
        +
        +static DSA_SIG *
        +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        +{
        +	struct crypt_kop kop;
        +	BIGNUM *r = NULL, *s = NULL;
        +	DSA_SIG *dsaret = NULL;
        +
        +	if ((r = BN_new()) == NULL)
        +		goto err;
        +	if ((s = BN_new()) == NULL) {
        +		BN_free(r);
        +		goto err;
        +	}
        +
        +	memset(&kop, 0, sizeof kop);
        +	kop.crk_op = CRK_DSA_SIGN;
        +
        +	/* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
        +	kop.crk_param[0].crp_p = (caddr_t)dgst;
        +	kop.crk_param[0].crp_nbits = dlen * 8;
        +	if (bn2crparam(dsa->p, &kop.crk_param[1]))
        +		goto err;
        +	if (bn2crparam(dsa->q, &kop.crk_param[2]))
        +		goto err;
        +	if (bn2crparam(dsa->g, &kop.crk_param[3]))
        +		goto err;
        +	if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
        +		goto err;
        +	kop.crk_iparams = 5;
        +
        +	if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
        +	    BN_num_bytes(dsa->q), s) == 0) {
        +		dsaret = DSA_SIG_new();
        +		dsaret->r = r;
        +		dsaret->s = s;
        +	} else {
        +		const DSA_METHOD *meth = DSA_OpenSSL();
        +		BN_free(r);
        +		BN_free(s);
        +		dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
        +	}
        +err:
        +	kop.crk_param[0].crp_p = NULL;
        +	zapparams(&kop);
        +	return (dsaret);
        +}
        +
        +static int
        +cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
        +    DSA_SIG *sig, DSA *dsa)
        +{
        +	struct crypt_kop kop;
        +	int dsaret = 1;
        +
        +	memset(&kop, 0, sizeof kop);
        +	kop.crk_op = CRK_DSA_VERIFY;
        +
        +	/* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
        +	kop.crk_param[0].crp_p = (caddr_t)dgst;
        +	kop.crk_param[0].crp_nbits = dlen * 8;
        +	if (bn2crparam(dsa->p, &kop.crk_param[1]))
        +		goto err;
        +	if (bn2crparam(dsa->q, &kop.crk_param[2]))
        +		goto err;
        +	if (bn2crparam(dsa->g, &kop.crk_param[3]))
        +		goto err;
        +	if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
        +		goto err;
        +	if (bn2crparam(sig->r, &kop.crk_param[5]))
        +		goto err;
        +	if (bn2crparam(sig->s, &kop.crk_param[6]))
        +		goto err;
        +	kop.crk_iparams = 7;
        +
        +	if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
        +/*OCF success value is 0, if not zero, change dsaret to fail*/
        +		if(0 != kop.crk_status) dsaret  = 0;
        +	} else {
        +		const DSA_METHOD *meth = DSA_OpenSSL();
        +
        +		dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
        +	}
        +err:
        +	kop.crk_param[0].crp_p = NULL;
        +	zapparams(&kop);
        +	return (dsaret);
        +}
        +
        +static DSA_METHOD cryptodev_dsa = {
        +	"cryptodev DSA method",
        +	NULL,
        +	NULL,				/* dsa_sign_setup */
        +	NULL,
        +	NULL,				/* dsa_mod_exp */
        +	NULL,
        +	NULL,				/* init */
        +	NULL,				/* finish */
        +	0,	/* flags */
        +	NULL	/* app_data */
        +};
        +
        +static int
        +cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +    BN_MONT_CTX *m_ctx)
        +{
        +	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
        +}
        +
        +static int
        +cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
        +{
        +	struct crypt_kop kop;
        +	int dhret = 1;
        +	int fd, keylen;
        +
        +	if ((fd = get_asym_dev_crypto()) < 0) {
        +		const DH_METHOD *meth = DH_OpenSSL();
        +
        +		return ((meth->compute_key)(key, pub_key, dh));
        +	}
        +
        +	keylen = BN_num_bits(dh->p);
        +
        +	memset(&kop, 0, sizeof kop);
        +	kop.crk_op = CRK_DH_COMPUTE_KEY;
        +
        +	/* inputs: dh->priv_key pub_key dh->p key */
        +	if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
        +		goto err;
        +	if (bn2crparam(pub_key, &kop.crk_param[1]))
        +		goto err;
        +	if (bn2crparam(dh->p, &kop.crk_param[2]))
        +		goto err;
        +	kop.crk_iparams = 3;
        +
        +	kop.crk_param[3].crp_p = (caddr_t) key;
        +	kop.crk_param[3].crp_nbits = keylen * 8;
        +	kop.crk_oparams = 1;
        +
        +	if (ioctl(fd, CIOCKEY, &kop) == -1) {
        +		const DH_METHOD *meth = DH_OpenSSL();
        +
        +		dhret = (meth->compute_key)(key, pub_key, dh);
        +	}
        +err:
        +	kop.crk_param[3].crp_p = NULL;
        +	zapparams(&kop);
        +	return (dhret);
        +}
        +
        +static DH_METHOD cryptodev_dh = {
        +	"cryptodev DH method",
        +	NULL,				/* cryptodev_dh_generate_key */
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	0,	/* flags */
        +	NULL	/* app_data */
        +};
        +
        +/*
        + * ctrl right now is just a wrapper that doesn't do much
        + * but I expect we'll want some options soon.
        + */
        +static int
        +cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +{
        +#ifdef HAVE_SYSLOG_R
        +	struct syslog_data sd = SYSLOG_DATA_INIT;
        +#endif
        +
        +	switch (cmd) {
        +	default:
        +#ifdef HAVE_SYSLOG_R
        +		syslog_r(LOG_ERR, &sd,
        +		    "cryptodev_ctrl: unknown command %d", cmd);
        +#else
        +		syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
        +#endif
        +		break;
        +	}
        +	return (1);
        +}
        +
        +void
        +ENGINE_load_cryptodev(void)
        +{
        +	ENGINE *engine = ENGINE_new();
        +	int fd;
        +
        +	if (engine == NULL)
        +		return;
        +	if ((fd = get_dev_crypto()) < 0) {
        +		ENGINE_free(engine);
        +		return;
        +	}
        +
        +	/*
        +	 * find out what asymmetric crypto algorithms we support
        +	 */
        +	if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
        +		put_dev_crypto(fd);
        +		ENGINE_free(engine);
        +		return;
        +	}
        +	put_dev_crypto(fd);
        +
        +	if (!ENGINE_set_id(engine, "cryptodev") ||
        +	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||
        +	    !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
        +	    !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
        +	    !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
        +	    !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
        +		ENGINE_free(engine);
        +		return;
        +	}
        +
        +	if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
        +		const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
        +
        +		cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
        +		cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
        +		cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
        +		cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
        +		cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
        +		cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
        +		if (cryptodev_asymfeat & CRF_MOD_EXP) {
        +			cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
        +			if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
        +				cryptodev_rsa.rsa_mod_exp =
        +				    cryptodev_rsa_mod_exp;
        +			else
        +				cryptodev_rsa.rsa_mod_exp =
        +				    cryptodev_rsa_nocrt_mod_exp;
        +		}
        +	}
        +
        +	if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
        +		const DSA_METHOD *meth = DSA_OpenSSL();
        +
        +		memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
        +		if (cryptodev_asymfeat & CRF_DSA_SIGN)
        +			cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
        +		if (cryptodev_asymfeat & CRF_MOD_EXP) {
        +			cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
        +			cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
        +		}
        +		if (cryptodev_asymfeat & CRF_DSA_VERIFY)
        +			cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
        +	}
        +
        +	if (ENGINE_set_DH(engine, &cryptodev_dh)){
        +		const DH_METHOD *dh_meth = DH_OpenSSL();
        +
        +		cryptodev_dh.generate_key = dh_meth->generate_key;
        +		cryptodev_dh.compute_key = dh_meth->compute_key;
        +		cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
        +		if (cryptodev_asymfeat & CRF_MOD_EXP) {
        +			cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
        +			if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
        +				cryptodev_dh.compute_key =
        +				    cryptodev_dh_compute_key;
        +		}
        +	}
        +
        +	ENGINE_add(engine);
        +	ENGINE_free(engine);
        +	ERR_clear_error();
        +}
        +
        +#endif /* HAVE_CRYPTODEV */
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_ctrl.c b/vendor/openssl/openssl/crypto/engine/eng_ctrl.c
        new file mode 100644
        index 000000000..5ce25d92e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_ctrl.c
        @@ -0,0 +1,389 @@
        +/* crypto/engine/eng_ctrl.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "eng_int.h"
        +
        +/* When querying a ENGINE-specific control command's 'description', this string
        + * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
        +static const char *int_no_description = "";
        +
        +/* These internal functions handle 'CMD'-related control commands when the
        + * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
        + * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
        +
        +static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
        +	{
        +	if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
        +		return 1;
        +	return 0;
        +	}
        +
        +static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
        +	{
        +	int idx = 0;
        +	while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
        +		{
        +		idx++;
        +		defn++;
        +		}
        +	if(int_ctrl_cmd_is_null(defn))
        +		/* The given name wasn't found */
        +		return -1;
        +	return idx;
        +	}
        +
        +static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
        +	{
        +	int idx = 0;
        +	/* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
        +	 * our searches don't need to take any longer than necessary. */
        +	while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
        +		{
        +		idx++;
        +		defn++;
        +		}
        +	if(defn->cmd_num == num)
        +		return idx;
        +	/* The given cmd_num wasn't found */
        +	return -1;
        +	}
        +
        +static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
        +			   void (*f)(void))
        +	{
        +	int idx;
        +	char *s = (char *)p;
        +	/* Take care of the easy one first (eg. it requires no searches) */
        +	if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
        +		{
        +		if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
        +			return 0;
        +		return e->cmd_defns->cmd_num;
        +		}
        +	/* One or two commands require that "p" be a valid string buffer */
        +	if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
        +			(cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
        +			(cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
        +		{
        +		if(s == NULL)
        +			{
        +			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +			return -1;
        +			}
        +		}
        +	/* Now handle cmd_name -> cmd_num conversion */
        +	if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
        +		{
        +		if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
        +						e->cmd_defns, s)) < 0))
        +			{
        +			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
        +				ENGINE_R_INVALID_CMD_NAME);
        +			return -1;
        +			}
        +		return e->cmd_defns[idx].cmd_num;
        +		}
        +	/* For the rest of the commands, the 'long' argument must specify a
        +	 * valie command number - so we need to conduct a search. */
        +	if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
        +					(unsigned int)i)) < 0))
        +		{
        +		ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
        +			ENGINE_R_INVALID_CMD_NUMBER);
        +		return -1;
        +		}
        +	/* Now the logic splits depending on command type */
        +	switch(cmd)
        +		{
        +	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
        +		idx++;
        +		if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
        +			/* end-of-list */
        +			return 0;
        +		else
        +			return e->cmd_defns[idx].cmd_num;
        +	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
        +		return strlen(e->cmd_defns[idx].cmd_name);
        +	case ENGINE_CTRL_GET_NAME_FROM_CMD:
        +		return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
        +				    "%s", e->cmd_defns[idx].cmd_name);
        +	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
        +		if(e->cmd_defns[idx].cmd_desc)
        +			return strlen(e->cmd_defns[idx].cmd_desc);
        +		return strlen(int_no_description);
        +	case ENGINE_CTRL_GET_DESC_FROM_CMD:
        +		if(e->cmd_defns[idx].cmd_desc)
        +			return BIO_snprintf(s,
        +					    strlen(e->cmd_defns[idx].cmd_desc) + 1,
        +					    "%s", e->cmd_defns[idx].cmd_desc);
        +		return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
        +				    int_no_description);
        +	case ENGINE_CTRL_GET_CMD_FLAGS:
        +		return e->cmd_defns[idx].cmd_flags;
        +		}
        +	/* Shouldn't really be here ... */
        +	ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
        +	return -1;
        +	}
        +
        +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int ctrl_exists, ref_exists;
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	ref_exists = ((e->struct_ref > 0) ? 1 : 0);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
        +	if(!ref_exists)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
        +		return 0;
        +		}
        +	/* Intercept any "root-level" commands before trying to hand them on to
        +	 * ctrl() handlers. */
        +	switch(cmd)
        +		{
        +	case ENGINE_CTRL_HAS_CTRL_FUNCTION:
        +		return ctrl_exists;
        +	case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
        +	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
        +	case ENGINE_CTRL_GET_CMD_FROM_NAME:
        +	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
        +	case ENGINE_CTRL_GET_NAME_FROM_CMD:
        +	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
        +	case ENGINE_CTRL_GET_DESC_FROM_CMD:
        +	case ENGINE_CTRL_GET_CMD_FLAGS:
        +		if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
        +			return int_ctrl_helper(e,cmd,i,p,f);
        +		if(!ctrl_exists)
        +			{
        +			ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
        +			/* For these cmd-related functions, failure is indicated
        +			 * by a -1 return value (because 0 is used as a valid
        +			 * return in some places). */
        +			return -1;
        +			}
        +	default:
        +		break;
        +		}
        +	/* Anything else requires a ctrl() handler to exist. */
        +	if(!ctrl_exists)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
        +		return 0;
        +		}
        +	return e->ctrl(e, cmd, i, p, f);
        +	}
        +
        +int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
        +	{
        +	int flags;
        +	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
        +			ENGINE_R_INVALID_CMD_NUMBER);
        +		return 0;
        +		}
        +	if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
        +			!(flags & ENGINE_CMD_FLAG_NUMERIC) &&
        +			!(flags & ENGINE_CMD_FLAG_STRING))
        +		return 0;
        +	return 1;
        +	}
        +
        +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
        +        long i, void *p, void (*f)(void), int cmd_optional)
        +        {
        +	int num;
        +
        +	if((e == NULL) || (cmd_name == NULL))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
        +					ENGINE_CTRL_GET_CMD_FROM_NAME,
        +					0, (void *)cmd_name, NULL)) <= 0))
        +		{
        +		/* If the command didn't *have* to be supported, we fake
        +		 * success. This allows certain settings to be specified for
        +		 * multiple ENGINEs and only require a change of ENGINE id
        +		 * (without having to selectively apply settings). Eg. changing
        +		 * from a hardware device back to the regular software ENGINE
        +		 * without editing the config file, etc. */
        +		if(cmd_optional)
        +			{
        +			ERR_clear_error();
        +			return 1;
        +			}
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
        +			ENGINE_R_INVALID_CMD_NAME);
        +		return 0;
        +		}
        +	/* Force the result of the control command to 0 or 1, for the reasons
        +	 * mentioned before. */
        +        if (ENGINE_ctrl(e, num, i, p, f) > 0)
        +                return 1;
        +        return 0;
        +        }
        +
        +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
        +				int cmd_optional)
        +	{
        +	int num, flags;
        +	long l;
        +	char *ptr;
        +	if((e == NULL) || (cmd_name == NULL))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
        +					ENGINE_CTRL_GET_CMD_FROM_NAME,
        +					0, (void *)cmd_name, NULL)) <= 0))
        +		{
        +		/* If the command didn't *have* to be supported, we fake
        +		 * success. This allows certain settings to be specified for
        +		 * multiple ENGINEs and only require a change of ENGINE id
        +		 * (without having to selectively apply settings). Eg. changing
        +		 * from a hardware device back to the regular software ENGINE
        +		 * without editing the config file, etc. */
        +		if(cmd_optional)
        +			{
        +			ERR_clear_error();
        +			return 1;
        +			}
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ENGINE_R_INVALID_CMD_NAME);
        +		return 0;
        +		}
        +	if(!ENGINE_cmd_is_executable(e, num))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ENGINE_R_CMD_NOT_EXECUTABLE);
        +		return 0;
        +		}
        +	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
        +		{
        +		/* Shouldn't happen, given that ENGINE_cmd_is_executable()
        +		 * returned success. */
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ENGINE_R_INTERNAL_LIST_ERROR);
        +		return 0;
        +		}
        +	/* If the command takes no input, there must be no input. And vice
        +	 * versa. */
        +	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
        +		{
        +		if(arg != NULL)
        +			{
        +			ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +				ENGINE_R_COMMAND_TAKES_NO_INPUT);
        +			return 0;
        +			}
        +		/* We deliberately force the result of ENGINE_ctrl() to 0 or 1
        +		 * rather than returning it as "return data". This is to ensure
        +		 * usage of these commands is consistent across applications and
        +		 * that certain applications don't understand it one way, and
        +		 * others another. */
        +		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
        +			return 1;
        +		return 0;
        +		}
        +	/* So, we require input */
        +	if(arg == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ENGINE_R_COMMAND_TAKES_INPUT);
        +		return 0;
        +		}
        +	/* If it takes string input, that's easy */
        +	if(flags & ENGINE_CMD_FLAG_STRING)
        +		{
        +		/* Same explanation as above */
        +		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
        +			return 1;
        +		return 0;
        +		}
        +	/* If it doesn't take numeric either, then it is unsupported for use in
        +	 * a config-setting situation, which is what this function is for. This
        +	 * should never happen though, because ENGINE_cmd_is_executable() was
        +	 * used. */
        +	if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ENGINE_R_INTERNAL_LIST_ERROR);
        +		return 0;
        +		}
        +	l = strtol(arg, &ptr, 10);
        +	if((arg == ptr) || (*ptr != '\0'))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
        +			ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
        +		return 0;
        +		}
        +	/* Force the result of the control command to 0 or 1, for the reasons
        +	 * mentioned before. */
        +	if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
        +		return 1;
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_dyn.c b/vendor/openssl/openssl/crypto/engine/eng_dyn.c
        new file mode 100644
        index 000000000..807da7a5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_dyn.c
        @@ -0,0 +1,548 @@
        +/* crypto/engine/eng_dyn.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "eng_int.h"
        +#include <openssl/dso.h>
        +
        +/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
        + * should implement the hook-up functions with the following prototypes. */
        +
        +/* Our ENGINE handlers */
        +static int dynamic_init(ENGINE *e);
        +static int dynamic_finish(ENGINE *e);
        +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +/* Predeclare our context type */
        +typedef struct st_dynamic_data_ctx dynamic_data_ctx;
        +/* The implementation for the important control command */
        +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
        +
        +#define DYNAMIC_CMD_SO_PATH		ENGINE_CMD_BASE
        +#define DYNAMIC_CMD_NO_VCHECK		(ENGINE_CMD_BASE + 1)
        +#define DYNAMIC_CMD_ID			(ENGINE_CMD_BASE + 2)
        +#define DYNAMIC_CMD_LIST_ADD		(ENGINE_CMD_BASE + 3)
        +#define DYNAMIC_CMD_DIR_LOAD		(ENGINE_CMD_BASE + 4)
        +#define DYNAMIC_CMD_DIR_ADD		(ENGINE_CMD_BASE + 5)
        +#define DYNAMIC_CMD_LOAD		(ENGINE_CMD_BASE + 6)
        +
        +/* The constants used when creating the ENGINE */
        +static const char *engine_dynamic_id = "dynamic";
        +static const char *engine_dynamic_name = "Dynamic engine loading support";
        +static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
        +	{DYNAMIC_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the new ENGINE shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{DYNAMIC_CMD_NO_VCHECK,
        +		"NO_VCHECK",
        +		"Specifies to continue even if version checking fails (boolean)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{DYNAMIC_CMD_ID,
        +		"ID",
        +		"Specifies an ENGINE id name for loading",
        +		ENGINE_CMD_FLAG_STRING},
        +	{DYNAMIC_CMD_LIST_ADD,
        +		"LIST_ADD",
        +		"Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{DYNAMIC_CMD_DIR_LOAD,
        +		"DIR_LOAD",
        +		"Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{DYNAMIC_CMD_DIR_ADD,
        +		"DIR_ADD",
        +		"Adds a directory from which ENGINEs can be loaded",
        +		ENGINE_CMD_FLAG_STRING},
        +	{DYNAMIC_CMD_LOAD,
        +		"LOAD",
        +		"Load up the ENGINE specified by other settings",
        +		ENGINE_CMD_FLAG_NO_INPUT},
        +	{0, NULL, NULL, 0}
        +	};
        +static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
        +	{0, NULL, NULL, 0}
        +	};
        +
        +/* Loading code stores state inside the ENGINE structure via the "ex_data"
        + * element. We load all our state into a single structure and use that as a
        + * single context in the "ex_data" stack. */
        +struct st_dynamic_data_ctx
        +	{
        +	/* The DSO object we load that supplies the ENGINE code */
        +	DSO *dynamic_dso;
        +	/* The function pointer to the version checking shared library function */
        +	dynamic_v_check_fn v_check;
        +	/* The function pointer to the engine-binding shared library function */
        +	dynamic_bind_engine bind_engine;
        +	/* The default name/path for loading the shared library */
        +	const char *DYNAMIC_LIBNAME;
        +	/* Whether to continue loading on a version check failure */
        +	int no_vcheck;
        +	/* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
        +	const char *engine_id;
        +	/* If non-zero, a successfully loaded ENGINE should be added to the internal
        +	 * ENGINE list. If 2, the add must succeed or the entire load should fail. */
        +	int list_add_value;
        +	/* The symbol name for the version checking function */
        +	const char *DYNAMIC_F1;
        +	/* The symbol name for the "initialise ENGINE structure" function */
        +	const char *DYNAMIC_F2;
        +	/* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
        +	 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
        +	int dir_load;
        +	/* A stack of directories from which ENGINEs could be loaded */
        +	STACK_OF(OPENSSL_STRING) *dirs;
        +	};
        +
        +/* This is the "ex_data" index we obtain and reserve for use with our context
        + * structure. */
        +static int dynamic_ex_data_idx = -1;
        +
        +static void int_free_str(char *s) { OPENSSL_free(s); }
        +/* Because our ex_data element may or may not get allocated depending on whether
        + * a "first-use" occurs before the ENGINE is freed, we have a memory leak
        + * problem to solve. We can't declare a "new" handler for the ex_data as we
        + * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
        + * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
        + * handler and that will get called if an ENGINE is being destroyed and there
        + * was an ex_data element corresponding to our context type. */
        +static void dynamic_data_ctx_free_func(void *parent, void *ptr,
        +			CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
        +	{
        +	if(ptr)
        +		{
        +		dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
        +		if(ctx->dynamic_dso)
        +			DSO_free(ctx->dynamic_dso);
        +		if(ctx->DYNAMIC_LIBNAME)
        +			OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
        +		if(ctx->engine_id)
        +			OPENSSL_free((void*)ctx->engine_id);
        +		if(ctx->dirs)
        +			sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
        +		OPENSSL_free(ctx);
        +		}
        +	}
        +
        +/* Construct the per-ENGINE context. We create it blindly and then use a lock to
        + * check for a race - if so, all but one of the threads "racing" will have
        + * wasted their time. The alternative involves creating everything inside the
        + * lock which is far worse. */
        +static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
        +	{
        +	dynamic_data_ctx *c;
        +	c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
        +	if(!c)
        +		{
        +		ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	memset(c, 0, sizeof(dynamic_data_ctx));
        +	c->dynamic_dso = NULL;
        +	c->v_check = NULL;
        +	c->bind_engine = NULL;
        +	c->DYNAMIC_LIBNAME = NULL;
        +	c->no_vcheck = 0;
        +	c->engine_id = NULL;
        +	c->list_add_value = 0;
        +	c->DYNAMIC_F1 = "v_check";
        +	c->DYNAMIC_F2 = "bind_engine";
        +	c->dir_load = 1;
        +	c->dirs = sk_OPENSSL_STRING_new_null();
        +	if(!c->dirs)
        +		{
        +		ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
        +		OPENSSL_free(c);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
        +				dynamic_ex_data_idx)) == NULL)
        +		{
        +		/* Good, we're the first */
        +		ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
        +		*ctx = c;
        +		c = NULL;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	/* If we lost the race to set the context, c is non-NULL and *ctx is the
        +	 * context of the thread that won. */
        +	if(c)
        +		OPENSSL_free(c);
        +	return 1;
        +	}
        +
        +/* This function retrieves the context structure from an ENGINE's "ex_data", or
        + * if it doesn't exist yet, sets it up. */
        +static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
        +	{
        +	dynamic_data_ctx *ctx;
        +	if(dynamic_ex_data_idx < 0)
        +		{
        +		/* Create and register the ENGINE ex_data, and associate our
        +		 * "free" function with it to ensure any allocated contexts get
        +		 * freed when an ENGINE goes underground. */
        +		int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
        +					dynamic_data_ctx_free_func);
        +		if(new_idx == -1)
        +			{
        +			ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
        +			return NULL;
        +			}
        +		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +		/* Avoid a race by checking again inside this lock */
        +		if(dynamic_ex_data_idx < 0)
        +			{
        +			/* Good, someone didn't beat us to it */
        +			dynamic_ex_data_idx = new_idx;
        +			new_idx = -1;
        +			}
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		/* In theory we could "give back" the index here if
        +		 * (new_idx>-1), but it's not possible and wouldn't gain us much
        +		 * if it were. */
        +		}
        +	ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
        +	/* Check if the context needs to be created */
        +	if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
        +		/* "set_data" will set errors if necessary */
        +		return NULL;
        +	return ctx;
        +	}
        +
        +static ENGINE *engine_dynamic(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!ENGINE_set_id(ret, engine_dynamic_id) ||
        +			!ENGINE_set_name(ret, engine_dynamic_name) ||
        +			!ENGINE_set_init_function(ret, dynamic_init) ||
        +			!ENGINE_set_finish_function(ret, dynamic_finish) ||
        +			!ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
        +			!ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
        +			!ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_dynamic(void)
        +	{
        +	ENGINE *toadd = engine_dynamic();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	/* If the "add" worked, it gets a structural reference. So either way,
        +	 * we release our just-created reference. */
        +	ENGINE_free(toadd);
        +	/* If the "add" didn't work, it was probably a conflict because it was
        +	 * already added (eg. someone calling ENGINE_load_blah then calling
        +	 * ENGINE_load_builtin_engines() perhaps). */
        +	ERR_clear_error();
        +	}
        +
        +static int dynamic_init(ENGINE *e)
        +	{
        +	/* We always return failure - the "dyanamic" engine itself can't be used
        +	 * for anything. */
        +	return 0;
        +	}
        +
        +static int dynamic_finish(ENGINE *e)
        +	{
        +	/* This should never be called on account of "dynamic_init" always
        +	 * failing. */
        +	return 0;
        +	}
        +
        +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
        +	int initialised;
        +	
        +	if(!ctx)
        +		{
        +		ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
        +		return 0;
        +		}
        +	initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
        +	/* All our control commands require the ENGINE to be uninitialised */
        +	if(initialised)
        +		{
        +		ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
        +			ENGINE_R_ALREADY_LOADED);
        +		return 0;
        +		}
        +	switch(cmd)
        +		{
        +	case DYNAMIC_CMD_SO_PATH:
        +		/* a NULL 'p' or a string of zero-length is the same thing */
        +		if(p && (strlen((const char *)p) < 1))
        +			p = NULL;
        +		if(ctx->DYNAMIC_LIBNAME)
        +			OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
        +		if(p)
        +			ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
        +		else
        +			ctx->DYNAMIC_LIBNAME = NULL;
        +		return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
        +	case DYNAMIC_CMD_NO_VCHECK:
        +		ctx->no_vcheck = ((i == 0) ? 0 : 1);
        +		return 1;
        +	case DYNAMIC_CMD_ID:
        +		/* a NULL 'p' or a string of zero-length is the same thing */
        +		if(p && (strlen((const char *)p) < 1))
        +			p = NULL;
        +		if(ctx->engine_id)
        +			OPENSSL_free((void*)ctx->engine_id);
        +		if(p)
        +			ctx->engine_id = BUF_strdup(p);
        +		else
        +			ctx->engine_id = NULL;
        +		return (ctx->engine_id ? 1 : 0);
        +	case DYNAMIC_CMD_LIST_ADD:
        +		if((i < 0) || (i > 2))
        +			{
        +			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
        +				ENGINE_R_INVALID_ARGUMENT);
        +			return 0;
        +			}
        +		ctx->list_add_value = (int)i;
        +		return 1;
        +	case DYNAMIC_CMD_LOAD:
        +		return dynamic_load(e, ctx);
        +	case DYNAMIC_CMD_DIR_LOAD:
        +		if((i < 0) || (i > 2))
        +			{
        +			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
        +				ENGINE_R_INVALID_ARGUMENT);
        +			return 0;
        +			}
        +		ctx->dir_load = (int)i;
        +		return 1;
        +	case DYNAMIC_CMD_DIR_ADD:
        +		/* a NULL 'p' or a string of zero-length is the same thing */
        +		if(!p || (strlen((const char *)p) < 1))
        +			{
        +			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
        +				ENGINE_R_INVALID_ARGUMENT);
        +			return 0;
        +			}
        +		{
        +		char *tmp_str = BUF_strdup(p);
        +		if(!tmp_str)
        +			{
        +			ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
        +				ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
        +		}
        +		return 1;
        +	default:
        +		break;
        +		}
        +	ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +static int int_load(dynamic_data_ctx *ctx)
        +	{
        +	int num, loop;
        +	/* Unless told not to, try a direct load */
        +	if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
        +				ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
        +		return 1;
        +	/* If we're not allowed to use 'dirs' or we have none, fail */
        +	if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
        +		return 0;
        +	for(loop = 0; loop < num; loop++)
        +		{
        +		const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
        +		char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
        +		if(!merge)
        +			return 0;
        +		if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
        +			{
        +			/* Found what we're looking for */
        +			OPENSSL_free(merge);
        +			return 1;
        +			}
        +		OPENSSL_free(merge);
        +		}
        +	return 0;
        +	}
        +
        +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
        +	{
        +	ENGINE cpy;
        +	dynamic_fns fns;
        +
        +	if(!ctx->dynamic_dso)
        +		ctx->dynamic_dso = DSO_new();
        +	if(!ctx->DYNAMIC_LIBNAME)
        +		{
        +		if(!ctx->engine_id)
        +			return 0;
        +		ctx->DYNAMIC_LIBNAME =
        +			DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
        +		}
        +	if(!int_load(ctx))
        +		{
        +		ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
        +			ENGINE_R_DSO_NOT_FOUND);
        +		DSO_free(ctx->dynamic_dso);
        +		ctx->dynamic_dso = NULL;
        +		return 0;
        +		}
        +	/* We have to find a bind function otherwise it'll always end badly */
        +	if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
        +					ctx->dynamic_dso, ctx->DYNAMIC_F2)))
        +		{
        +		ctx->bind_engine = NULL;
        +		DSO_free(ctx->dynamic_dso);
        +		ctx->dynamic_dso = NULL;
        +		ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
        +			ENGINE_R_DSO_FAILURE);
        +		return 0;
        +		}
        +	/* Do we perform version checking? */
        +	if(!ctx->no_vcheck)
        +		{
        +		unsigned long vcheck_res = 0;
        +		/* Now we try to find a version checking function and decide how
        +		 * to cope with failure if/when it fails. */
        +		ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
        +				ctx->dynamic_dso, ctx->DYNAMIC_F1);
        +		if(ctx->v_check)
        +			vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
        +		/* We fail if the version checker veto'd the load *or* if it is
        +		 * deferring to us (by returning its version) and we think it is
        +		 * too old. */
        +		if(vcheck_res < OSSL_DYNAMIC_OLDEST)
        +			{
        +			/* Fail */
        +			ctx->bind_engine = NULL;
        +			ctx->v_check = NULL;
        +			DSO_free(ctx->dynamic_dso);
        +			ctx->dynamic_dso = NULL;
        +			ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
        +				ENGINE_R_VERSION_INCOMPATIBILITY);
        +			return 0;
        +			}
        +		}
        +	/* First binary copy the ENGINE structure so that we can roll back if
        +	 * the hand-over fails */
        +	memcpy(&cpy, e, sizeof(ENGINE));
        +	/* Provide the ERR, "ex_data", memory, and locking callbacks so the
        +	 * loaded library uses our state rather than its own. FIXME: As noted in
        +	 * engine.h, much of this would be simplified if each area of code
        +	 * provided its own "summary" structure of all related callbacks. It
        +	 * would also increase opaqueness. */
        +	fns.static_state = ENGINE_get_static_state();
        +	fns.err_fns = ERR_get_implementation();
        +	fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
        +	CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
        +				&fns.mem_fns.realloc_cb,
        +				&fns.mem_fns.free_cb);
        +	fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
        +	fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
        +	fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
        +	fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
        +	fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
        +	/* Now that we've loaded the dynamic engine, make sure no "dynamic"
        +	 * ENGINE elements will show through. */
        +	engine_set_all_null(e);
        +
        +	/* Try to bind the ENGINE onto our own ENGINE structure */
        +	if(!ctx->bind_engine(e, ctx->engine_id, &fns))
        +		{
        +		ctx->bind_engine = NULL;
        +		ctx->v_check = NULL;
        +		DSO_free(ctx->dynamic_dso);
        +		ctx->dynamic_dso = NULL;
        +		ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
        +		/* Copy the original ENGINE structure back */
        +		memcpy(e, &cpy, sizeof(ENGINE));
        +		return 0;
        +		}
        +	/* Do we try to add this ENGINE to the internal list too? */
        +	if(ctx->list_add_value > 0)
        +		{
        +		if(!ENGINE_add(e))
        +			{
        +			/* Do we tolerate this or fail? */
        +			if(ctx->list_add_value > 1)
        +				{
        +				/* Fail - NB: By this time, it's too late to
        +				 * rollback, and trying to do so allows the
        +				 * bind_engine() code to have created leaks. We
        +				 * just have to fail where we are, after the
        +				 * ENGINE has changed. */
        +				ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
        +					ENGINE_R_CONFLICTING_ENGINE_ID);
        +				return 0;
        +				}
        +			/* Tolerate */
        +			ERR_clear_error();
        +			}
        +		}
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_err.c b/vendor/openssl/openssl/crypto/engine/eng_err.c
        new file mode 100644
        index 000000000..81c70acfa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_err.c
        @@ -0,0 +1,173 @@
        +/* crypto/engine/eng_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2010 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/engine.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
        +
        +static ERR_STRING_DATA ENGINE_str_functs[]=
        +	{
        +{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL),	"DYNAMIC_CTRL"},
        +{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX),	"DYNAMIC_GET_DATA_CTX"},
        +{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD),	"DYNAMIC_LOAD"},
        +{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX),	"DYNAMIC_SET_DATA_CTX"},
        +{ERR_FUNC(ENGINE_F_ENGINE_ADD),	"ENGINE_add"},
        +{ERR_FUNC(ENGINE_F_ENGINE_BY_ID),	"ENGINE_by_id"},
        +{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE),	"ENGINE_cmd_is_executable"},
        +{ERR_FUNC(ENGINE_F_ENGINE_CTRL),	"ENGINE_ctrl"},
        +{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD),	"ENGINE_ctrl_cmd"},
        +{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING),	"ENGINE_ctrl_cmd_string"},
        +{ERR_FUNC(ENGINE_F_ENGINE_FINISH),	"ENGINE_finish"},
        +{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL),	"ENGINE_FREE_UTIL"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER),	"ENGINE_get_cipher"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE),	"ENGINE_GET_DEFAULT_TYPE"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST),	"ENGINE_get_digest"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT),	"ENGINE_get_next"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),	"ENGINE_get_pkey_asn1_meth"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH),	"ENGINE_get_pkey_meth"},
        +{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV),	"ENGINE_get_prev"},
        +{ERR_FUNC(ENGINE_F_ENGINE_INIT),	"ENGINE_init"},
        +{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD),	"ENGINE_LIST_ADD"},
        +{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE),	"ENGINE_LIST_REMOVE"},
        +{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY),	"ENGINE_load_private_key"},
        +{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY),	"ENGINE_load_public_key"},
        +{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),	"ENGINE_load_ssl_client_cert"},
        +{ERR_FUNC(ENGINE_F_ENGINE_NEW),	"ENGINE_new"},
        +{ERR_FUNC(ENGINE_F_ENGINE_REMOVE),	"ENGINE_remove"},
        +{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),	"ENGINE_set_default_string"},
        +{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE),	"ENGINE_SET_DEFAULT_TYPE"},
        +{ERR_FUNC(ENGINE_F_ENGINE_SET_ID),	"ENGINE_set_id"},
        +{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME),	"ENGINE_set_name"},
        +{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER),	"ENGINE_TABLE_REGISTER"},
        +{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY),	"ENGINE_UNLOAD_KEY"},
        +{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH),	"ENGINE_UNLOCKED_FINISH"},
        +{ERR_FUNC(ENGINE_F_ENGINE_UP_REF),	"ENGINE_up_ref"},
        +{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER),	"INT_CTRL_HELPER"},
        +{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE),	"INT_ENGINE_CONFIGURE"},
        +{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT),	"INT_ENGINE_MODULE_INIT"},
        +{ERR_FUNC(ENGINE_F_LOG_MESSAGE),	"LOG_MESSAGE"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ENGINE_str_reasons[]=
        +	{
        +{ERR_REASON(ENGINE_R_ALREADY_LOADED)     ,"already loaded"},
        +{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),"argument is not a number"},
        +{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) ,"cmd not executable"},
        +{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT),"command takes input"},
        +{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT),"command takes no input"},
        +{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID),"conflicting engine id"},
        +{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) ,"dh not implemented"},
        +{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED),"dsa not implemented"},
        +{ERR_REASON(ENGINE_R_DSO_FAILURE)        ,"DSO failure"},
        +{ERR_REASON(ENGINE_R_DSO_NOT_FOUND)      ,"dso not found"},
        +{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
        +{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
        +{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
        +{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
        +{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
        +{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
        +{ERR_REASON(ENGINE_R_FINISH_FAILED)      ,"finish failed"},
        +{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED)  ,"could not obtain hardware handle"},
        +{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) ,"'id' or 'name' missing"},
        +{ERR_REASON(ENGINE_R_INIT_FAILED)        ,"init failed"},
        +{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR),"internal list error"},
        +{ERR_REASON(ENGINE_R_INVALID_ARGUMENT)   ,"invalid argument"},
        +{ERR_REASON(ENGINE_R_INVALID_CMD_NAME)   ,"invalid cmd name"},
        +{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) ,"invalid cmd number"},
        +{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) ,"invalid init value"},
        +{ERR_REASON(ENGINE_R_INVALID_STRING)     ,"invalid string"},
        +{ERR_REASON(ENGINE_R_NOT_INITIALISED)    ,"not initialised"},
        +{ERR_REASON(ENGINE_R_NOT_LOADED)         ,"not loaded"},
        +{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION),"no control function"},
        +{ERR_REASON(ENGINE_R_NO_INDEX)           ,"no index"},
        +{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION)   ,"no load function"},
        +{ERR_REASON(ENGINE_R_NO_REFERENCE)       ,"no reference"},
        +{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE)     ,"no such engine"},
        +{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) ,"no unload function"},
        +{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) ,"provide parameters"},
        +{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
        +{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
        +{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
        +{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
        +{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_ENGINE_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,ENGINE_str_functs);
        +		ERR_load_strings(0,ENGINE_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_fat.c b/vendor/openssl/openssl/crypto/engine/eng_fat.c
        new file mode 100644
        index 000000000..789b8d57e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_fat.c
        @@ -0,0 +1,182 @@
        +/* crypto/engine/eng_fat.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include "eng_int.h"
        +#include <openssl/conf.h>
        +
        +int ENGINE_set_default(ENGINE *e, unsigned int flags)
        +	{
        +	if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
        +		return 0;
        +	if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
        +		return 0;
        +#ifndef OPENSSL_NO_RSA
        +	if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
        +		return 0;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
        +		return 0;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
        +		return 0;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
        +		return 0;
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
        +		return 0;
        +#endif
        +	if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
        +		return 0;
        +	if((flags & ENGINE_METHOD_PKEY_METHS)
        +				&& !ENGINE_set_default_pkey_meths(e))
        +		return 0;
        +	if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
        +				&& !ENGINE_set_default_pkey_asn1_meths(e))
        +		return 0;
        +	return 1;
        +	}
        +
        +/* Set default algorithms using a string */
        +
        +static int int_def_cb(const char *alg, int len, void *arg)
        +	{
        +	unsigned int *pflags = arg;
        +	if (!strncmp(alg, "ALL", len))
        +		*pflags |= ENGINE_METHOD_ALL;
        +	else if (!strncmp(alg, "RSA", len))
        +		*pflags |= ENGINE_METHOD_RSA;
        +	else if (!strncmp(alg, "DSA", len))
        +		*pflags |= ENGINE_METHOD_DSA;
        +	else if (!strncmp(alg, "ECDH", len))
        +		*pflags |= ENGINE_METHOD_ECDH;
        +	else if (!strncmp(alg, "ECDSA", len))
        +		*pflags |= ENGINE_METHOD_ECDSA;
        +	else if (!strncmp(alg, "DH", len))
        +		*pflags |= ENGINE_METHOD_DH;
        +	else if (!strncmp(alg, "RAND", len))
        +		*pflags |= ENGINE_METHOD_RAND;
        +	else if (!strncmp(alg, "CIPHERS", len))
        +		*pflags |= ENGINE_METHOD_CIPHERS;
        +	else if (!strncmp(alg, "DIGESTS", len))
        +		*pflags |= ENGINE_METHOD_DIGESTS;
        +	else if (!strncmp(alg, "PKEY", len))
        +		*pflags |=
        +			ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
        +	else if (!strncmp(alg, "PKEY_CRYPTO", len))
        +		*pflags |= ENGINE_METHOD_PKEY_METHS;
        +	else if (!strncmp(alg, "PKEY_ASN1", len))
        +		*pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
        +	else
        +		return 0;
        +	return 1;
        +	}
        +
        +
        +int ENGINE_set_default_string(ENGINE *e, const char *def_list)
        +	{
        +	unsigned int flags = 0;
        +	if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
        +					ENGINE_R_INVALID_STRING);
        +		ERR_add_error_data(2, "str=",def_list);
        +		return 0;
        +		}
        +	return ENGINE_set_default(e, flags);
        +	}
        +
        +int ENGINE_register_complete(ENGINE *e)
        +	{
        +	ENGINE_register_ciphers(e);
        +	ENGINE_register_digests(e);
        +#ifndef OPENSSL_NO_RSA
        +	ENGINE_register_RSA(e);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	ENGINE_register_DSA(e);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	ENGINE_register_DH(e);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	ENGINE_register_ECDH(e);
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	ENGINE_register_ECDSA(e);
        +#endif
        +	ENGINE_register_RAND(e);
        +	ENGINE_register_pkey_meths(e);
        +	return 1;
        +	}
        +
        +int ENGINE_register_all_complete(void)
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
        +			ENGINE_register_complete(e);
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_init.c b/vendor/openssl/openssl/crypto/engine/eng_init.c
        new file mode 100644
        index 000000000..7633cf5f1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_init.c
        @@ -0,0 +1,154 @@
        +/* crypto/engine/eng_init.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "eng_int.h"
        +
        +/* Initialise a engine type for use (or up its functional reference count
        + * if it's already in use). This version is only used internally. */
        +int engine_unlocked_init(ENGINE *e)
        +	{
        +	int to_return = 1;
        +
        +	if((e->funct_ref == 0) && e->init)
        +		/* This is the first functional reference and the engine
        +		 * requires initialisation so we do it now. */
        +		to_return = e->init(e);
        +	if(to_return)
        +		{
        +		/* OK, we return a functional reference which is also a
        +		 * structural reference. */
        +		e->struct_ref++;
        +		e->funct_ref++;
        +		engine_ref_debug(e, 0, 1)
        +		engine_ref_debug(e, 1, 1)
        +		}
        +	return to_return;
        +	}
        +
        +/* Free a functional reference to a engine type. This version is only used
        + * internally. */
        +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
        +	{
        +	int to_return = 1;
        +
        +	/* Reduce the functional reference count here so if it's the terminating
        +	 * case, we can release the lock safely and call the finish() handler
        +	 * without risk of a race. We get a race if we leave the count until
        +	 * after and something else is calling "finish" at the same time -
        +	 * there's a chance that both threads will together take the count from
        +	 * 2 to 0 without either calling finish(). */
        +	e->funct_ref--;
        +	engine_ref_debug(e, 1, -1);
        +	if((e->funct_ref == 0) && e->finish)
        +		{
        +		if(unlock_for_handlers)
        +			CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		to_return = e->finish(e);
        +		if(unlock_for_handlers)
        +			CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +		if(!to_return)
        +			return 0;
        +		}
        +#ifdef REF_CHECK
        +	if(e->funct_ref < 0)
        +		{
        +		fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
        +		abort();
        +		}
        +#endif
        +	/* Release the structural reference too */
        +	if(!engine_free_util(e, 0))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
        +		return 0;
        +		}
        +	return to_return;
        +	}
        +
        +/* The API (locked) version of "init" */
        +int ENGINE_init(ENGINE *e)
        +	{
        +	int ret;
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	ret = engine_unlocked_init(e);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return ret;
        +	}
        +
        +/* The API (locked) version of "finish" */
        +int ENGINE_finish(ENGINE *e)
        +	{
        +	int to_return = 1;
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	to_return = engine_unlocked_finish(e, 1);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	if(!to_return)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
        +		return 0;
        +		}
        +	return to_return;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_int.h b/vendor/openssl/openssl/crypto/engine/eng_int.h
        new file mode 100644
        index 000000000..451ef8feb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_int.h
        @@ -0,0 +1,206 @@
        +/* crypto/engine/eng_int.h */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#ifndef HEADER_ENGINE_INT_H
        +#define HEADER_ENGINE_INT_H
        +
        +#include "cryptlib.h"
        +/* Take public definitions from engine.h */
        +#include <openssl/engine.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* If we compile with this symbol defined, then both reference counts in the
        + * ENGINE structure will be monitored with a line of output on stderr for each
        + * change. This prints the engine's pointer address (truncated to unsigned int),
        + * "struct" or "funct" to indicate the reference type, the before and after
        + * reference count, and the file:line-number pair. The "engine_ref_debug"
        + * statements must come *after* the change. */
        +#ifdef ENGINE_REF_COUNT_DEBUG
        +
        +#define engine_ref_debug(e, isfunct, diff) \
        +	fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
        +		(unsigned int)(e), (isfunct ? "funct" : "struct"), \
        +		((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
        +		((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
        +		(__FILE__), (__LINE__));
        +
        +#else
        +
        +#define engine_ref_debug(e, isfunct, diff)
        +
        +#endif
        +
        +/* Any code that will need cleanup operations should use these functions to
        + * register callbacks. ENGINE_cleanup() will call all registered callbacks in
        + * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
        + * held (in "write" mode). */
        +typedef void (ENGINE_CLEANUP_CB)(void);
        +typedef struct st_engine_cleanup_item
        +	{
        +	ENGINE_CLEANUP_CB *cb;
        +	} ENGINE_CLEANUP_ITEM;
        +DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
        +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
        +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
        +
        +/* We need stacks of ENGINEs for use in eng_table.c */
        +DECLARE_STACK_OF(ENGINE)
        +
        +/* If this symbol is defined then engine_table_select(), the function that is
        + * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
        + * functional references (etc), will display debugging summaries to stderr. */
        +/* #define ENGINE_TABLE_DEBUG */
        +
        +/* This represents an implementation table. Dependent code should instantiate it
        + * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
        +typedef struct st_engine_table ENGINE_TABLE;
        +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
        +		ENGINE *e, const int *nids, int num_nids, int setdefault);
        +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
        +void engine_table_cleanup(ENGINE_TABLE **table);
        +#ifndef ENGINE_TABLE_DEBUG
        +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
        +#else
        +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
        +#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
        +#endif
        +typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
        +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
        +
        +/* Internal versions of API functions that have control over locking. These are
        + * used between C files when functionality needs to be shared but the caller may
        + * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
        +int engine_unlocked_init(ENGINE *e);
        +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
        +int engine_free_util(ENGINE *e, int locked);
        +
        +/* This function will reset all "set"able values in an ENGINE to NULL. This
        + * won't touch reference counts or ex_data, but is equivalent to calling all the
        + * ENGINE_set_***() functions with a NULL value. */
        +void engine_set_all_null(ENGINE *e);
        +
        +/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
        + * in engine.h. */
        +
        +/* Free up dynamically allocated public key methods associated with ENGINE */
        +
        +void engine_pkey_meths_free(ENGINE *e);
        +void engine_pkey_asn1_meths_free(ENGINE *e);
        +
        +/* This is a structure for storing implementations of various crypto
        + * algorithms and functions. */
        +struct engine_st
        +	{
        +	const char *id;
        +	const char *name;
        +	const RSA_METHOD *rsa_meth;
        +	const DSA_METHOD *dsa_meth;
        +	const DH_METHOD *dh_meth;
        +	const ECDH_METHOD *ecdh_meth;
        +	const ECDSA_METHOD *ecdsa_meth;
        +	const RAND_METHOD *rand_meth;
        +	const STORE_METHOD *store_meth;
        +	/* Cipher handling is via this callback */
        +	ENGINE_CIPHERS_PTR ciphers;
        +	/* Digest handling is via this callback */
        +	ENGINE_DIGESTS_PTR digests;
        +	/* Public key handling via this callback */
        +	ENGINE_PKEY_METHS_PTR pkey_meths;
        +	/* ASN1 public key handling via this callback */
        +	ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
        +
        +	ENGINE_GEN_INT_FUNC_PTR	destroy;
        +
        +	ENGINE_GEN_INT_FUNC_PTR init;
        +	ENGINE_GEN_INT_FUNC_PTR finish;
        +	ENGINE_CTRL_FUNC_PTR ctrl;
        +	ENGINE_LOAD_KEY_PTR load_privkey;
        +	ENGINE_LOAD_KEY_PTR load_pubkey;
        +
        +	ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
        +
        +	const ENGINE_CMD_DEFN *cmd_defns;
        +	int flags;
        +	/* reference count on the structure itself */
        +	int struct_ref;
        +	/* reference count on usability of the engine type. NB: This
        +	 * controls the loading and initialisation of any functionlity
        +	 * required by this engine, whereas the previous count is
        +	 * simply to cope with (de)allocation of this structure. Hence,
        +	 * running_ref <= struct_ref at all times. */
        +	int funct_ref;
        +	/* A place to store per-ENGINE data */
        +	CRYPTO_EX_DATA ex_data;
        +	/* Used to maintain the linked-list of engines. */
        +	struct engine_st *prev;
        +	struct engine_st *next;
        +	};
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* HEADER_ENGINE_INT_H */
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_lib.c b/vendor/openssl/openssl/crypto/engine/eng_lib.c
        new file mode 100644
        index 000000000..18a666464
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_lib.c
        @@ -0,0 +1,332 @@
        +/* crypto/engine/eng_lib.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "eng_int.h"
        +#include <openssl/rand.h>
        +
        +/* The "new"/"free" stuff first */
        +
        +ENGINE *ENGINE_new(void)
        +	{
        +	ENGINE *ret;
        +
        +	ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
        +	if(ret == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	memset(ret, 0, sizeof(ENGINE));
        +	ret->struct_ref = 1;
        +	engine_ref_debug(ret, 0, 1)
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
        +	return ret;
        +	}
        +
        +/* Placed here (close proximity to ENGINE_new) so that modifications to the
        + * elements of the ENGINE structure are more likely to be caught and changed
        + * here. */
        +void engine_set_all_null(ENGINE *e)
        +	{
        +	e->id = NULL;
        +	e->name = NULL;
        +	e->rsa_meth = NULL;
        +	e->dsa_meth = NULL;
        +	e->dh_meth = NULL;
        +	e->rand_meth = NULL;
        +	e->store_meth = NULL;
        +	e->ciphers = NULL;
        +	e->digests = NULL;
        +	e->destroy = NULL;
        +	e->init = NULL;
        +	e->finish = NULL;
        +	e->ctrl = NULL;
        +	e->load_privkey = NULL;
        +	e->load_pubkey = NULL;
        +	e->cmd_defns = NULL;
        +	e->flags = 0;
        +	}
        +
        +int engine_free_util(ENGINE *e, int locked)
        +	{
        +	int i;
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if(locked)
        +		i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
        +	else
        +		i = --e->struct_ref;
        +	engine_ref_debug(e, 0, -1)
        +	if (i > 0) return 1;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"ENGINE_free, bad structural reference count\n");
        +		abort();
        +		}
        +#endif
        +	/* Free up any dynamically allocated public key methods */
        +	engine_pkey_meths_free(e);
        +	engine_pkey_asn1_meths_free(e);
        +	/* Give the ENGINE a chance to do any structural cleanup corresponding
        +	 * to allocation it did in its constructor (eg. unload error strings) */
        +	if(e->destroy)
        +		e->destroy(e);
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
        +	OPENSSL_free(e);
        +	return 1;
        +	}
        +
        +int ENGINE_free(ENGINE *e)
        +	{
        +	return engine_free_util(e, 1);
        +	}
        +
        +/* Cleanup stuff */
        +
        +/* ENGINE_cleanup() is coded such that anything that does work that will need
        + * cleanup can register a "cleanup" callback here. That way we don't get linker
        + * bloat by referring to all *possible* cleanups, but any linker bloat into code
        + * "X" will cause X's cleanup function to end up here. */
        +static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
        +static int int_cleanup_check(int create)
        +	{
        +	if(cleanup_stack) return 1;
        +	if(!create) return 0;
        +	cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
        +	return (cleanup_stack ? 1 : 0);
        +	}
        +static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
        +	{
        +	ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
        +					ENGINE_CLEANUP_ITEM));
        +	if(!item) return NULL;
        +	item->cb = cb;
        +	return item;
        +	}
        +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
        +	{
        +	ENGINE_CLEANUP_ITEM *item;
        +	if(!int_cleanup_check(1)) return;
        +	item = int_cleanup_item(cb);
        +	if(item)
        +		sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
        +	}
        +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
        +	{
        +	ENGINE_CLEANUP_ITEM *item;
        +	if(!int_cleanup_check(1)) return;
        +	item = int_cleanup_item(cb);
        +	if(item)
        +		sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
        +	}
        +/* The API function that performs all cleanup */
        +static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
        +	{
        +	(*(item->cb))();
        +	OPENSSL_free(item);
        +	}
        +void ENGINE_cleanup(void)
        +	{
        +	if(int_cleanup_check(0))
        +		{
        +		sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
        +			engine_cleanup_cb_free);
        +		cleanup_stack = NULL;
        +		}
        +	/* FIXME: This should be handled (somehow) through RAND, eg. by it
        +	 * registering a cleanup callback. */
        +	RAND_set_rand_method(NULL);
        +	}
        +
        +/* Now the "ex_data" support */
        +
        +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +		CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +	{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
        +			new_func, dup_func, free_func);
        +	}
        +
        +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
        +	}
        +
        +void *ENGINE_get_ex_data(const ENGINE *e, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&e->ex_data, idx));
        +	}
        +
        +/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
        + * ENGINE structure itself. */
        +
        +int ENGINE_set_id(ENGINE *e, const char *id)
        +	{
        +	if(id == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_SET_ID,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	e->id = id;
        +	return 1;
        +	}
        +
        +int ENGINE_set_name(ENGINE *e, const char *name)
        +	{
        +	if(name == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	e->name = name;
        +	return 1;
        +	}
        +
        +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
        +	{
        +	e->destroy = destroy_f;
        +	return 1;
        +	}
        +
        +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
        +	{
        +	e->init = init_f;
        +	return 1;
        +	}
        +
        +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
        +	{
        +	e->finish = finish_f;
        +	return 1;
        +	}
        +
        +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
        +	{
        +	e->ctrl = ctrl_f;
        +	return 1;
        +	}
        +
        +int ENGINE_set_flags(ENGINE *e, int flags)
        +	{
        +	e->flags = flags;
        +	return 1;
        +	}
        +
        +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
        +	{
        +	e->cmd_defns = defns;
        +	return 1;
        +	}
        +
        +const char *ENGINE_get_id(const ENGINE *e)
        +	{
        +	return e->id;
        +	}
        +
        +const char *ENGINE_get_name(const ENGINE *e)
        +	{
        +	return e->name;
        +	}
        +
        +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
        +	{
        +	return e->destroy;
        +	}
        +
        +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
        +	{
        +	return e->init;
        +	}
        +
        +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
        +	{
        +	return e->finish;
        +	}
        +
        +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
        +	{
        +	return e->ctrl;
        +	}
        +
        +int ENGINE_get_flags(const ENGINE *e)
        +	{
        +	return e->flags;
        +	}
        +
        +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
        +	{
        +	return e->cmd_defns;
        +	}
        +
        +/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
        + * put the "static_state" hack here. */
        +
        +static int internal_static_hack = 0;
        +
        +void *ENGINE_get_static_state(void)
        +	{
        +	return &internal_static_hack;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_list.c b/vendor/openssl/openssl/crypto/engine/eng_list.c
        new file mode 100644
        index 000000000..27846edb1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_list.c
        @@ -0,0 +1,433 @@
        +/* crypto/engine/eng_list.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include "eng_int.h"
        +
        +/* The linked-list of pointers to engine types. engine_list_head
        + * incorporates an implicit structural reference but engine_list_tail
        + * does not - the latter is a computational niceity and only points
        + * to something that is already pointed to by its predecessor in the
        + * list (or engine_list_head itself). In the same way, the use of the
        + * "prev" pointer in each ENGINE is to save excessive list iteration,
        + * it doesn't correspond to an extra structural reference. Hence,
        + * engine_list_head, and each non-null "next" pointer account for
        + * the list itself assuming exactly 1 structural reference on each
        + * list member. */
        +static ENGINE *engine_list_head = NULL;
        +static ENGINE *engine_list_tail = NULL;
        +
        +/* This cleanup function is only needed internally. If it should be called, we
        + * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
        +
        +static void engine_list_cleanup(void)
        +	{
        +	ENGINE *iterator = engine_list_head;
        +
        +	while(iterator != NULL)
        +		{
        +		ENGINE_remove(iterator);
        +		iterator = engine_list_head;
        +		}
        +	return;
        +	}
        +
        +/* These static functions starting with a lower case "engine_" always
        + * take place when CRYPTO_LOCK_ENGINE has been locked up. */
        +static int engine_list_add(ENGINE *e)
        +	{
        +	int conflict = 0;
        +	ENGINE *iterator = NULL;
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	iterator = engine_list_head;
        +	while(iterator && !conflict)
        +		{
        +		conflict = (strcmp(iterator->id, e->id) == 0);
        +		iterator = iterator->next;
        +		}
        +	if(conflict)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
        +			ENGINE_R_CONFLICTING_ENGINE_ID);
        +		return 0;
        +		}
        +	if(engine_list_head == NULL)
        +		{
        +		/* We are adding to an empty list. */
        +		if(engine_list_tail)
        +			{
        +			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
        +				ENGINE_R_INTERNAL_LIST_ERROR);
        +			return 0;
        +			}
        +		engine_list_head = e;
        +		e->prev = NULL;
        +		/* The first time the list allocates, we should register the
        +		 * cleanup. */
        +		engine_cleanup_add_last(engine_list_cleanup);
        +		}
        +	else
        +		{
        +		/* We are adding to the tail of an existing list. */
        +		if((engine_list_tail == NULL) ||
        +				(engine_list_tail->next != NULL))
        +			{
        +			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
        +				ENGINE_R_INTERNAL_LIST_ERROR);
        +			return 0;
        +			}
        +		engine_list_tail->next = e;
        +		e->prev = engine_list_tail;
        +		}
        +	/* Having the engine in the list assumes a structural
        +	 * reference. */
        +	e->struct_ref++;
        +	engine_ref_debug(e, 0, 1)
        +	/* However it came to be, e is the last item in the list. */
        +	engine_list_tail = e;
        +	e->next = NULL;
        +	return 1;
        +	}
        +
        +static int engine_list_remove(ENGINE *e)
        +	{
        +	ENGINE *iterator;
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	/* We need to check that e is in our linked list! */
        +	iterator = engine_list_head;
        +	while(iterator && (iterator != e))
        +		iterator = iterator->next;
        +	if(iterator == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
        +			ENGINE_R_ENGINE_IS_NOT_IN_LIST);
        +		return 0;
        +		}
        +	/* un-link e from the chain. */
        +	if(e->next)
        +		e->next->prev = e->prev;
        +	if(e->prev)
        +		e->prev->next = e->next;
        +	/* Correct our head/tail if necessary. */
        +	if(engine_list_head == e)
        +		engine_list_head = e->next;
        +	if(engine_list_tail == e)
        +		engine_list_tail = e->prev;
        +	engine_free_util(e, 0);
        +	return 1;
        +	}
        +
        +/* Get the first/last "ENGINE" type available. */
        +ENGINE *ENGINE_get_first(void)
        +	{
        +	ENGINE *ret;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	ret = engine_list_head;
        +	if(ret)
        +		{
        +		ret->struct_ref++;
        +		engine_ref_debug(ret, 0, 1)
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return ret;
        +	}
        +
        +ENGINE *ENGINE_get_last(void)
        +	{
        +	ENGINE *ret;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	ret = engine_list_tail;
        +	if(ret)
        +		{
        +		ret->struct_ref++;
        +		engine_ref_debug(ret, 0, 1)
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return ret;
        +	}
        +
        +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
        +ENGINE *ENGINE_get_next(ENGINE *e)
        +	{
        +	ENGINE *ret = NULL;
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	ret = e->next;
        +	if(ret)
        +		{
        +		/* Return a valid structural refernce to the next ENGINE */
        +		ret->struct_ref++;
        +		engine_ref_debug(ret, 0, 1)
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	/* Release the structural reference to the previous ENGINE */
        +	ENGINE_free(e);
        +	return ret;
        +	}
        +
        +ENGINE *ENGINE_get_prev(ENGINE *e)
        +	{
        +	ENGINE *ret = NULL;
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	ret = e->prev;
        +	if(ret)
        +		{
        +		/* Return a valid structural reference to the next ENGINE */
        +		ret->struct_ref++;
        +		engine_ref_debug(ret, 0, 1)
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	/* Release the structural reference to the previous ENGINE */
        +	ENGINE_free(e);
        +	return ret;
        +	}
        +
        +/* Add another "ENGINE" type into the list. */
        +int ENGINE_add(ENGINE *e)
        +	{
        +	int to_return = 1;
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_ADD,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if((e->id == NULL) || (e->name == NULL))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_ADD,
        +			ENGINE_R_ID_OR_NAME_MISSING);
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(!engine_list_add(e))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_ADD,
        +			ENGINE_R_INTERNAL_LIST_ERROR);
        +		to_return = 0;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return to_return;
        +	}
        +
        +/* Remove an existing "ENGINE" type from the array. */
        +int ENGINE_remove(ENGINE *e)
        +	{
        +	int to_return = 1;
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(!engine_list_remove(e))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
        +			ENGINE_R_INTERNAL_LIST_ERROR);
        +		to_return = 0;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return to_return;
        +	}
        +
        +static void engine_cpy(ENGINE *dest, const ENGINE *src)
        +	{
        +	dest->id = src->id;
        +	dest->name = src->name;
        +#ifndef OPENSSL_NO_RSA
        +	dest->rsa_meth = src->rsa_meth;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	dest->dsa_meth = src->dsa_meth;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	dest->dh_meth = src->dh_meth;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	dest->ecdh_meth = src->ecdh_meth;
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	dest->ecdsa_meth = src->ecdsa_meth;
        +#endif
        +	dest->rand_meth = src->rand_meth;
        +	dest->store_meth = src->store_meth;
        +	dest->ciphers = src->ciphers;
        +	dest->digests = src->digests;
        +	dest->pkey_meths = src->pkey_meths;
        +	dest->destroy = src->destroy;
        +	dest->init = src->init;
        +	dest->finish = src->finish;
        +	dest->ctrl = src->ctrl;
        +	dest->load_privkey = src->load_privkey;
        +	dest->load_pubkey = src->load_pubkey;
        +	dest->cmd_defns = src->cmd_defns;
        +	dest->flags = src->flags;
        +	}
        +
        +ENGINE *ENGINE_by_id(const char *id)
        +	{
        +	ENGINE *iterator;
        +	char *load_dir = NULL;
        +	if(id == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	iterator = engine_list_head;
        +	while(iterator && (strcmp(id, iterator->id) != 0))
        +		iterator = iterator->next;
        +	if(iterator)
        +		{
        +		/* We need to return a structural reference. If this is an
        +		 * ENGINE type that returns copies, make a duplicate - otherwise
        +		 * increment the existing ENGINE's reference count. */
        +		if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
        +			{
        +			ENGINE *cp = ENGINE_new();
        +			if(!cp)
        +				iterator = NULL;
        +			else
        +				{
        +				engine_cpy(cp, iterator);
        +				iterator = cp;
        +				}
        +			}
        +		else
        +			{
        +			iterator->struct_ref++;
        +			engine_ref_debug(iterator, 0, 1)
        +			}
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +#if 0
        +	if(iterator == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
        +			ENGINE_R_NO_SUCH_ENGINE);
        +		ERR_add_error_data(2, "id=", id);
        +		}
        +	return iterator;
        +#else
        +	/* EEK! Experimental code starts */
        +	if(iterator) return iterator;
        +	/* Prevent infinite recusrion if we're looking for the dynamic engine. */
        +	if (strcmp(id, "dynamic"))
        +		{
        +#ifdef OPENSSL_SYS_VMS
        +		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
        +#else
        +		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
        +#endif
        +		iterator = ENGINE_by_id("dynamic");
        +		if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
        +				!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
        +				!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
        +					load_dir, 0) ||
        +				!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
        +				goto notfound;
        +		return iterator;
        +		}
        +notfound:
        +	ENGINE_free(iterator);
        +	ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
        +	ERR_add_error_data(2, "id=", id);
        +	return NULL;
        +	/* EEK! Experimental code ends */
        +#endif
        +	}
        +
        +int ENGINE_up_ref(ENGINE *e)
        +	{
        +	if (e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_openssl.c b/vendor/openssl/openssl/crypto/engine/eng_openssl.c
        new file mode 100644
        index 000000000..9abb95cc2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_openssl.c
        @@ -0,0 +1,384 @@
        +/* crypto/engine/eng_openssl.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +
        +#include <stdio.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/engine.h>
        +#include <openssl/dso.h>
        +#include <openssl/pem.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +/* This testing gunk is implemented (and explained) lower down. It also assumes
        + * the application explicitly calls "ENGINE_load_openssl()" because this is no
        + * longer automatic in ENGINE_load_builtin_engines(). */
        +#define TEST_ENG_OPENSSL_RC4
        +#define TEST_ENG_OPENSSL_PKEY
        +/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
        +#define TEST_ENG_OPENSSL_RC4_P_INIT
        +/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
        +#define TEST_ENG_OPENSSL_SHA
        +/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
        +/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
        +/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
        +/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
        +
        +/* Now check what of those algorithms are actually enabled */
        +#ifdef OPENSSL_NO_RC4
        +#undef TEST_ENG_OPENSSL_RC4
        +#undef TEST_ENG_OPENSSL_RC4_OTHERS
        +#undef TEST_ENG_OPENSSL_RC4_P_INIT
        +#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
        +#endif
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
        +#undef TEST_ENG_OPENSSL_SHA
        +#undef TEST_ENG_OPENSSL_SHA_OTHERS
        +#undef TEST_ENG_OPENSSL_SHA_P_INIT
        +#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
        +#undef TEST_ENG_OPENSSL_SHA_P_FINAL 
        +#endif
        +
        +#ifdef TEST_ENG_OPENSSL_RC4
        +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +				const int **nids, int nid);
        +#endif
        +#ifdef TEST_ENG_OPENSSL_SHA
        +static int openssl_digests(ENGINE *e, const EVP_MD **digest,
        +				const int **nids, int nid);
        +#endif
        +
        +#ifdef TEST_ENG_OPENSSL_PKEY
        +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +#endif
        +
        +/* The constants used when creating the ENGINE */
        +static const char *engine_openssl_id = "openssl";
        +static const char *engine_openssl_name = "Software engine support";
        +
        +/* This internal function is used by ENGINE_openssl() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +	if(!ENGINE_set_id(e, engine_openssl_id)
        +			|| !ENGINE_set_name(e, engine_openssl_name)
        +#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
        +#ifndef OPENSSL_NO_RSA
        +			|| !ENGINE_set_RSA(e, RSA_get_default_method())
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			|| !ENGINE_set_DSA(e, DSA_get_default_method())
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +			|| !ENGINE_set_ECDH(e, ECDH_OpenSSL())
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +			|| !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			|| !ENGINE_set_DH(e, DH_get_default_method())
        +#endif
        +			|| !ENGINE_set_RAND(e, RAND_SSLeay())
        +#ifdef TEST_ENG_OPENSSL_RC4
        +			|| !ENGINE_set_ciphers(e, openssl_ciphers)
        +#endif
        +#ifdef TEST_ENG_OPENSSL_SHA
        +			|| !ENGINE_set_digests(e, openssl_digests)
        +#endif
        +#endif
        +#ifdef TEST_ENG_OPENSSL_PKEY
        +			|| !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
        +#endif
        +			)
        +		return 0;
        +	/* If we add errors to this ENGINE, ensure the error handling is setup here */
        +	/* openssl_load_error_strings(); */
        +	return 1;
        +	}
        +
        +static ENGINE *engine_openssl(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_openssl(void)
        +	{
        +	ENGINE *toadd = engine_openssl();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	/* If the "add" worked, it gets a structural reference. So either way,
        +	 * we release our just-created reference. */
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_openssl_id) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* ENGINE_DYNAMIC_SUPPORT */
        +
        +#ifdef TEST_ENG_OPENSSL_RC4
        +/* This section of code compiles an "alternative implementation" of two modes of
        + * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
        + * should under normal circumstances go via this support rather than the default
        + * EVP support. There are other symbols to tweak the testing;
        + *    TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
        + *        we're asked for a cipher we don't support (should not happen).
        + *    TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
        + *        the "init_key" handler is called.
        + *    TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
        + */
        +#include <openssl/rc4.h>
        +#define TEST_RC4_KEY_SIZE		16
        +static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
        +static int test_cipher_nids_number = 2;
        +typedef struct {
        +	unsigned char key[TEST_RC4_KEY_SIZE];
        +	RC4_KEY ks;
        +	} TEST_RC4_KEY;
        +#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
        +static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			const unsigned char *iv, int enc)
        +	{
        +#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
        +	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
        +#endif
        +	memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
        +	RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
        +		test(ctx)->key);
        +	return 1;
        +	}
        +static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		      const unsigned char *in, size_t inl)
        +	{
        +#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
        +	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
        +#endif
        +	RC4(&test(ctx)->ks,inl,in,out);
        +	return 1;
        +	}
        +static const EVP_CIPHER test_r4_cipher=
        +	{
        +	NID_rc4,
        +	1,TEST_RC4_KEY_SIZE,0,
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	test_rc4_init_key,
        +	test_rc4_cipher,
        +	NULL,
        +	sizeof(TEST_RC4_KEY),
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +static const EVP_CIPHER test_r4_40_cipher=
        +	{
        +	NID_rc4_40,
        +	1,5 /* 40 bit */,0,
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	test_rc4_init_key,
        +	test_rc4_cipher,
        +	NULL,
        +	sizeof(TEST_RC4_KEY),
        +	NULL, 
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +			const int **nids, int nid)
        +	{
        +	if(!cipher)
        +		{
        +		/* We are returning a list of supported nids */
        +		*nids = test_cipher_nids;
        +		return test_cipher_nids_number;
        +		}
        +	/* We are being asked for a specific cipher */
        +	if(nid == NID_rc4)
        +		*cipher = &test_r4_cipher;
        +	else if(nid == NID_rc4_40)
        +		*cipher = &test_r4_40_cipher;
        +	else
        +		{
        +#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
        +		fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
        +				"nid %d\n", nid);
        +#endif
        +		*cipher = NULL;
        +		return 0;
        +		}
        +	return 1;
        +	}
        +#endif
        +
        +#ifdef TEST_ENG_OPENSSL_SHA
        +/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
        +#include <openssl/sha.h>
        +static int test_digest_nids[] = {NID_sha1};
        +static int test_digest_nids_number = 1;
        +static int test_sha1_init(EVP_MD_CTX *ctx)
        +	{
        +#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
        +	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
        +#endif
        +	return SHA1_Init(ctx->md_data);
        +	}
        +static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{
        +#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
        +	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
        +#endif
        +	return SHA1_Update(ctx->md_data,data,count);
        +	}
        +static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{
        +#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
        +	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
        +#endif
        +	return SHA1_Final(md,ctx->md_data);
        +	}
        +static const EVP_MD test_sha_md=
        +	{
        +	NID_sha1,
        +	NID_sha1WithRSAEncryption,
        +	SHA_DIGEST_LENGTH,
        +	0,
        +	test_sha1_init,
        +	test_sha1_update,
        +	test_sha1_final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA_CTX),
        +	};
        +static int openssl_digests(ENGINE *e, const EVP_MD **digest,
        +			const int **nids, int nid)
        +	{
        +	if(!digest)
        +		{
        +		/* We are returning a list of supported nids */
        +		*nids = test_digest_nids;
        +		return test_digest_nids_number;
        +		}
        +	/* We are being asked for a specific digest */
        +	if(nid == NID_sha1)
        +		*digest = &test_sha_md;
        +	else
        +		{
        +#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
        +		fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
        +				"nid %d\n", nid);
        +#endif
        +		*digest = NULL;
        +		return 0;
        +		}
        +	return 1;
        +	}
        +#endif
        +
        +#ifdef TEST_ENG_OPENSSL_PKEY
        +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data)
        +	{
        +	BIO *in;
        +	EVP_PKEY *key;
        +	fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
        +	in = BIO_new_file(key_id, "r");
        +	if (!in)
        +		return NULL;
        +	key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
        +	BIO_free(in);
        +	return key;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_pkey.c b/vendor/openssl/openssl/crypto/engine/eng_pkey.c
        new file mode 100644
        index 000000000..1dfa2e366
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_pkey.c
        @@ -0,0 +1,196 @@
        +/* crypto/engine/eng_pkey.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "eng_int.h"
        +
        +/* Basic get/set stuff */
        +
        +int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
        +	{
        +	e->load_privkey = loadpriv_f;
        +	return 1;
        +	}
        +
        +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
        +	{
        +	e->load_pubkey = loadpub_f;
        +	return 1;
        +	}
        +
        +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
        +				ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
        +	{
        +	e->load_ssl_client_cert = loadssl_f;
        +	return 1;
        +	}
        +
        +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
        +	{
        +	return e->load_privkey;
        +	}
        +
        +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
        +	{
        +	return e->load_pubkey;
        +	}
        +
        +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
        +	{
        +	return e->load_ssl_client_cert;
        +	}
        +
        +/* API functions to load public/private keys */
        +
        +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data)
        +	{
        +	EVP_PKEY *pkey;
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(e->funct_ref == 0)
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
        +			ENGINE_R_NOT_INITIALISED);
        +		return 0;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	if (!e->load_privkey)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
        +			ENGINE_R_NO_LOAD_FUNCTION);
        +		return 0;
        +		}
        +	pkey = e->load_privkey(e, key_id, ui_method, callback_data);
        +	if (!pkey)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
        +			ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
        +		return 0;
        +		}
        +	return pkey;
        +	}
        +
        +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data)
        +	{
        +	EVP_PKEY *pkey;
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(e->funct_ref == 0)
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
        +			ENGINE_R_NOT_INITIALISED);
        +		return 0;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	if (!e->load_pubkey)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
        +			ENGINE_R_NO_LOAD_FUNCTION);
        +		return 0;
        +		}
        +	pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
        +	if (!pkey)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
        +			ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
        +		return 0;
        +		}
        +	return pkey;
        +	}
        +
        +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
        +	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
        +	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
        +	{
        +
        +	if(e == NULL)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(e->funct_ref == 0)
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
        +			ENGINE_R_NOT_INITIALISED);
        +		return 0;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	if (!e->load_ssl_client_cert)
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
        +			ENGINE_R_NO_LOAD_FUNCTION);
        +		return 0;
        +		}
        +	return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
        +					ui_method, callback_data);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_rdrand.c b/vendor/openssl/openssl/crypto/engine/eng_rdrand.c
        new file mode 100644
        index 000000000..a9ba5ae6f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_rdrand.c
        @@ -0,0 +1,142 @@
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/opensslconf.h>
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/engine.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +#if (defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
        +     defined(__x86_64) || defined(__x86_64__) || \
        +     defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
        +
        +size_t OPENSSL_ia32_rdrand(void);
        +
        +static int get_random_bytes (unsigned char *buf, int num)
        +	{
        +	size_t rnd;
        +
        +	while (num>=(int)sizeof(size_t)) {
        +		if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
        +
        +		*((size_t *)buf) = rnd;
        +		buf += sizeof(size_t);
        +		num -= sizeof(size_t);
        +	}
        +	if (num) {
        +		if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
        +
        +		memcpy (buf,&rnd,num);
        +	}
        +
        +	return 1;
        +	}
        +
        +static int random_status (void)
        +{	return 1;	}
        +
        +static RAND_METHOD rdrand_meth =
        +	{
        +	NULL,	/* seed */
        +	get_random_bytes,
        +	NULL,	/* cleanup */
        +	NULL,	/* add */
        +	get_random_bytes,
        +	random_status,
        +	};
        +
        +static int rdrand_init(ENGINE *e)
        +{	return 1;	}
        +
        +static const char *engine_e_rdrand_id = "rdrand";
        +static const char *engine_e_rdrand_name = "Intel RDRAND engine";
        +
        +static int bind_helper(ENGINE *e)
        +	{
        +	if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
        +	    !ENGINE_set_name(e, engine_e_rdrand_name) ||
        +	    !ENGINE_set_init_function(e, rdrand_init) ||
        +	    !ENGINE_set_RAND(e, &rdrand_meth) )
        +		return 0;
        +
        +	return 1;
        +	}
        +
        +static ENGINE *ENGINE_rdrand(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_rdrand (void)
        +	{
        +	extern unsigned int OPENSSL_ia32cap_P[];
        +
        +	if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
        +		{
        +		ENGINE *toadd = ENGINE_rdrand();
        +		if(!toadd) return;
        +		ENGINE_add(toadd);
        +		ENGINE_free(toadd);
        +		ERR_clear_error();
        +		}
        +	}
        +#else
        +void ENGINE_load_rdrand (void) {}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_rsax.c b/vendor/openssl/openssl/crypto/engine/eng_rsax.c
        new file mode 100644
        index 000000000..96e63477e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_rsax.c
        @@ -0,0 +1,668 @@
        +/* crypto/engine/eng_rsax.c */
        +/* Copyright (c) 2010-2010 Intel Corp.
        + *   Author: Vinodh.Gopal@intel.com
        + *           Jim Guilford
        + *           Erdinc.Ozturk@intel.com
        + *           Maxim.Perminov@intel.com
        + *           Ying.Huang@intel.com
        + *
        + * More information about algorithm used can be found at:
        + *   http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <openssl/opensslconf.h>
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/bn.h>
        +#include <openssl/err.h>
        +
        +/* RSAX is available **ONLY* on x86_64 CPUs */
        +#undef COMPILE_RSAX
        +
        +#if (defined(__x86_64) || defined(__x86_64__) || \
        +     defined(_M_AMD64) || defined (_M_X64)) && !defined(OPENSSL_NO_ASM)
        +#define COMPILE_RSAX
        +static ENGINE *ENGINE_rsax (void);
        +#endif
        +
        +void ENGINE_load_rsax (void)
        +	{
        +/* On non-x86 CPUs it just returns. */
        +#ifdef COMPILE_RSAX
        +	ENGINE *toadd = ENGINE_rsax();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +#endif
        +	}
        +
        +#ifdef COMPILE_RSAX
        +#define E_RSAX_LIB_NAME "rsax engine"
        +
        +static int e_rsax_destroy(ENGINE *e);
        +static int e_rsax_init(ENGINE *e);
        +static int e_rsax_finish(ENGINE *e);
        +static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +
        +#ifndef OPENSSL_NO_RSA
        +/* RSA stuff */
        +static int e_rsax_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +static int e_rsax_rsa_finish(RSA *r);
        +#endif
        +
        +static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = {
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD e_rsax_rsa =
        +	{
        +	"Intel RSA-X method",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	e_rsax_rsa_mod_exp,
        +	NULL,
        +	NULL,
        +	e_rsax_rsa_finish,
        +	RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_e_rsax_id = "rsax";
        +static const char *engine_e_rsax_name = "RSAX engine support";
        +
        +/* This internal function is used by ENGINE_rsax() */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +	if(!ENGINE_set_id(e, engine_e_rsax_id) ||
        +			!ENGINE_set_name(e, engine_e_rsax_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &e_rsax_rsa) ||
        +#endif
        +			!ENGINE_set_destroy_function(e, e_rsax_destroy) ||
        +			!ENGINE_set_init_function(e, e_rsax_init) ||
        +			!ENGINE_set_finish_function(e, e_rsax_finish) ||
        +			!ENGINE_set_ctrl_function(e, e_rsax_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, e_rsax_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	meth1 = RSA_PKCS1_SSLeay();
        +	e_rsax_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
        +	e_rsax_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
        +	e_rsax_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
        +	e_rsax_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
        +	e_rsax_rsa.bn_mod_exp = meth1->bn_mod_exp;
        +#endif
        +	return 1;
        +	}
        +
        +static ENGINE *ENGINE_rsax(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Used to attach our own key-data to an RSA structure */
        +static int rsax_ex_data_idx = -1;
        +#endif
        +
        +static int e_rsax_destroy(ENGINE *e)
        +	{
        +	return 1;
        +	}
        +
        +/* (de)initialisation functions. */
        +static int e_rsax_init(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	if (rsax_ex_data_idx == -1)
        +		rsax_ex_data_idx = RSA_get_ex_new_index(0,
        +			NULL,
        +			NULL, NULL, NULL);
        +#endif
        +	if (rsax_ex_data_idx  == -1)
        +		return 0;
        +	return 1;
        +	}
        +
        +static int e_rsax_finish(ENGINE *e)
        +	{
        +	return 1;
        +	}
        +
        +static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int to_return = 1;
        +
        +	switch(cmd)
        +		{
        +	/* The command isn't understood by this engine */
        +	default:
        +		to_return = 0;
        +		break;
        +		}
        +
        +	return to_return;
        +	}
        +
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +#ifdef _WIN32
        +typedef unsigned __int64 UINT64;
        +#else
        +typedef unsigned long long UINT64;
        +#endif
        +typedef unsigned short UINT16;
        +
        +/* Table t is interleaved in the following manner:
        + * The order in memory is t[0][0], t[0][1], ..., t[0][7], t[1][0], ...
        + * A particular 512-bit value is stored in t[][index] rather than the more
        + * normal t[index][]; i.e. the qwords of a particular entry in t are not
        + * adjacent in memory
        + */
        +
        +/* Init BIGNUM b from the interleaved UINT64 array */
        +static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array);
        +
        +/* Extract array elements from BIGNUM b
        + * To set the whole array from b, call with n=8
        + */
        +static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array);
        +
        +struct mod_ctx_512 {
        +    UINT64 t[8][8];
        +    UINT64 m[8];
        +    UINT64 m1[8]; /* 2^278 % m */
        +    UINT64 m2[8]; /* 2^640 % m */
        +    UINT64 k1[2]; /* (- 1/m) % 2^128 */
        +};
        +
        +static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data);
        +
        +void mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */
        +		 UINT64 *g,      /* 512 bits, 8 qwords */
        +		 UINT64 *exp,    /* 512 bits, 8 qwords */
        +		 struct mod_ctx_512 *data);
        +
        +typedef struct st_e_rsax_mod_ctx
        +{
        +  UINT64 type;
        +  union {
        +    struct mod_ctx_512 b512;
        +  } ctx;
        +
        +} E_RSAX_MOD_CTX;
        +
        +static E_RSAX_MOD_CTX *e_rsax_get_ctx(RSA *rsa, int idx, BIGNUM* m)
        +{
        +	E_RSAX_MOD_CTX *hptr;
        +
        +        if (idx < 0 || idx > 2)
        +           return NULL;
        +
        +	hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
        +	if (!hptr) {
        +	    hptr = OPENSSL_malloc(3*sizeof(E_RSAX_MOD_CTX));
        +	    if (!hptr) return NULL;
        +            hptr[2].type = hptr[1].type= hptr[0].type = 0;
        +	    RSA_set_ex_data(rsa, rsax_ex_data_idx, hptr);
        +        }
        +
        +        if (hptr[idx].type == (UINT64)BN_num_bits(m))
        +            return hptr+idx;
        +
        +        if (BN_num_bits(m) == 512) {
        +  	    UINT64 _m[8];
        +	    bn_extract_to_array_512(m, 8, _m);
        +	    memset( &hptr[idx].ctx.b512, 0, sizeof(struct mod_ctx_512));
        +	    mod_exp_pre_compute_data_512(_m, &hptr[idx].ctx.b512);
        +	}
        +
        +        hptr[idx].type = BN_num_bits(m);
        +	return hptr+idx;
        +}
        +
        +static int e_rsax_rsa_finish(RSA *rsa)
        +	{
        +	E_RSAX_MOD_CTX *hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
        +	if(hptr)
        +		{
        +		OPENSSL_free(hptr);
        +		RSA_set_ex_data(rsa, rsax_ex_data_idx, NULL);
        +		}
        +	if (rsa->_method_mod_n)
        +		BN_MONT_CTX_free(rsa->_method_mod_n);
        +	if (rsa->_method_mod_p)
        +		BN_MONT_CTX_free(rsa->_method_mod_p);
        +	if (rsa->_method_mod_q)
        +		BN_MONT_CTX_free(rsa->_method_mod_q);
        +	return 1;
        +	}
        +
        +
        +static int e_rsax_bn_mod_exp(BIGNUM *r, const BIGNUM *g, const BIGNUM *e,
        +                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, E_RSAX_MOD_CTX* rsax_mod_ctx )
        +{
        +	if (rsax_mod_ctx && BN_get_flags(e, BN_FLG_CONSTTIME) != 0) {
        +	   if (BN_num_bits(m) == 512) {
        +  		UINT64 _r[8];
        +   	  	UINT64 _g[8];
        +		UINT64 _e[8];
        +
        +		/* Init the arrays from the BIGNUMs */
        +		bn_extract_to_array_512(g, 8, _g);
        +		bn_extract_to_array_512(e, 8, _e);
        +
        +		mod_exp_512(_r, _g, _e, &rsax_mod_ctx->ctx.b512);
        +		/* Return the result in the BIGNUM */
        +		interleaved_array_to_bn_512(r, _r);
        +                return 1;
        +           }
        +        }
        +
        +	return BN_mod_exp_mont(r, g, e, m, ctx, in_mont);
        +}
        +
        +/* Declares for the Intel CIAP 512-bit / CRT / 1024 bit RSA modular
        + * exponentiation routine precalculations and a structure to hold the
        + * necessary values.  These files are meant to live in crypto/rsa/ in
        + * the target openssl.
        + */
        +
        +/*
        + * Local method: extracts a piece from a BIGNUM, to fit it into
        + * an array. Call with n=8 to extract an entire 512-bit BIGNUM
        + */
        +static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array)
        +{
        +	int i;
        +	UINT64 tmp;
        +	unsigned char bn_buff[64];
        +	memset(bn_buff, 0, 64);
        +	if (BN_num_bytes(b) > 64) {
        +		printf ("Can't support this byte size\n");
        +		return 0; }
        +	if (BN_num_bytes(b)!=0) {
        +		if (!BN_bn2bin(b, bn_buff+(64-BN_num_bytes(b)))) {
        +			printf ("Error's in bn2bin\n");
        +			/* We have to error, here */
        +			return 0; } }
        +	while (n-- > 0) {
        +		array[n] = 0;
        +		for (i=7; i>=0; i--) {
        +			tmp = bn_buff[63-(n*8+i)];
        +			array[n] |= tmp << (8*i); } }
        +	return 1;
        +}
        +
        +/* Init a 512-bit BIGNUM from the UINT64*_ (8 * 64) interleaved array */
        +static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array)
        +{
        +	unsigned char tmp[64];
        +	int n=8;
        +	int i;
        +	while (n-- > 0) {
        +		for (i = 7; i>=0; i--) {
        +			tmp[63-(n*8+i)] = (unsigned char)(array[n]>>(8*i)); } }
        +	BN_bin2bn(tmp, 64, b);
        +        return 0;
        +}
        +
        +
        +/* The main 512bit precompute call */
        +static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data)
        + {
        +    BIGNUM two_768, two_640, two_128, two_512, tmp, _m, tmp2;
        +
        +    /* We need a BN_CTX for the modulo functions */
        +    BN_CTX* ctx;
        +    /* Some tmps */
        +    UINT64 _t[8];
        +    int i, j, ret = 0;
        +
        +    /* Init _m with m */
        +    BN_init(&_m);
        +    interleaved_array_to_bn_512(&_m, m);
        +    memset(_t, 0, 64);
        +
        +    /* Inits */
        +    BN_init(&two_768);
        +    BN_init(&two_640);
        +    BN_init(&two_128);
        +    BN_init(&two_512);
        +    BN_init(&tmp);
        +    BN_init(&tmp2);
        +
        +    /* Create our context */
        +    if ((ctx=BN_CTX_new()) == NULL) { goto err; }
        +	BN_CTX_start(ctx);
        +
        +    /*
        +     * For production, if you care, these only need to be set once,
        +     * and may be made constants.
        +     */
        +    BN_lshift(&two_768, BN_value_one(), 768);
        +    BN_lshift(&two_640, BN_value_one(), 640);
        +    BN_lshift(&two_128, BN_value_one(), 128);
        +    BN_lshift(&two_512, BN_value_one(), 512);
        +
        +    if (0 == (m[7] & 0x8000000000000000)) {
        +        exit(1);
        +    }
        +    if (0 == (m[0] & 0x1)) { /* Odd modulus required for Mont */
        +        exit(1);
        +    }
        +
        +    /* Precompute m1 */
        +    BN_mod(&tmp, &two_768, &_m, ctx);
        +    if (!bn_extract_to_array_512(&tmp, 8, &data->m1[0])) {
        +	    goto err; }
        +
        +    /* Precompute m2 */
        +    BN_mod(&tmp, &two_640, &_m, ctx);
        +    if (!bn_extract_to_array_512(&tmp, 8, &data->m2[0])) {
        +	    goto err;
        +    }
        +
        +    /*
        +     * Precompute k1, a 128b number = ((-1)* m-1 ) mod 2128; k1 should
        +     * be non-negative.
        +     */
        +    BN_mod_inverse(&tmp, &_m, &two_128, ctx);
        +    if (!BN_is_zero(&tmp)) { BN_sub(&tmp, &two_128, &tmp); }
        +    if (!bn_extract_to_array_512(&tmp, 2, &data->k1[0])) {
        +	    goto err; }
        +
        +    /* Precompute t */
        +    for (i=0; i<8; i++) {
        +        BN_zero(&tmp);
        +        if (i & 1) { BN_add(&tmp, &two_512, &tmp); }
        +        if (i & 2) { BN_add(&tmp, &two_512, &tmp); }
        +        if (i & 4) { BN_add(&tmp, &two_640, &tmp); }
        +
        +        BN_nnmod(&tmp2, &tmp, &_m, ctx);
        +        if (!bn_extract_to_array_512(&tmp2, 8, _t)) {
        +	        goto err; }
        +        for (j=0; j<8; j++) data->t[j][i] = _t[j]; }
        +
        +    /* Precompute m */
        +    for (i=0; i<8; i++) {
        +        data->m[i] = m[i]; }
        +
        +    ret = 1;
        +
        +err:
        +    /* Cleanup */
        +	if (ctx != NULL) {
        +		BN_CTX_end(ctx); BN_CTX_free(ctx); }
        +    BN_free(&two_768);
        +    BN_free(&two_640);
        +    BN_free(&two_128);
        +    BN_free(&two_512);
        +    BN_free(&tmp);
        +    BN_free(&tmp2);
        +    BN_free(&_m);
        +
        +    return ret;
        +}
        +
        +
        +static int e_rsax_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	BIGNUM *r1,*m1,*vrfy;
        +	BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
        +	BIGNUM *dmp1,*dmq1,*c,*pr1;
        +	int ret=0;
        +
        +	BN_CTX_start(ctx);
        +	r1 = BN_CTX_get(ctx);
        +	m1 = BN_CTX_get(ctx);
        +	vrfy = BN_CTX_get(ctx);
        +
        +	{
        +		BIGNUM local_p, local_q;
        +		BIGNUM *p = NULL, *q = NULL;
        +		int error = 0;
        +
        +		/* Make sure BN_mod_inverse in Montgomery
        +		 * intialization uses the BN_FLG_CONSTTIME flag
        +		 * (unless RSA_FLAG_NO_CONSTTIME is set)
        +		 */
        +		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +			{
        +			BN_init(&local_p);
        +			p = &local_p;
        +			BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
        +
        +			BN_init(&local_q);
        +			q = &local_q;
        +			BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
        +			}
        +		else
        +			{
        +			p = rsa->p;
        +			q = rsa->q;
        +			}
        +
        +		if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
        +			{
        +			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
        +				error = 1;
        +			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
        +				error = 1;
        +			}
        +
        +		/* clean up */
        +		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +			{
        +			BN_free(&local_p);
        +			BN_free(&local_q);
        +			}
        +		if ( error )
        +			goto err;
        +	}
        +
        +	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
        +		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
        +			goto err;
        +
        +	/* compute I mod q */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		c = &local_c;
        +		BN_with_flags(c, I, BN_FLG_CONSTTIME);
        +		if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
        +		}
        +
        +	/* compute r1^dmq1 mod q */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		dmq1 = &local_dmq1;
        +		BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		dmq1 = rsa->dmq1;
        +
        +	if (!e_rsax_bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
        +		rsa->_method_mod_q, e_rsax_get_ctx(rsa, 0, rsa->q) )) goto err;
        +
        +	/* compute I mod p */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		c = &local_c;
        +		BN_with_flags(c, I, BN_FLG_CONSTTIME);
        +		if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
        +		}
        +
        +	/* compute r1^dmp1 mod p */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		dmp1 = &local_dmp1;
        +		BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		dmp1 = rsa->dmp1;
        +
        +	if (!e_rsax_bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
        +		rsa->_method_mod_p, e_rsax_get_ctx(rsa, 1, rsa->p) )) goto err;
        +
        +	if (!BN_sub(r0,r0,m1)) goto err;
        +	/* This will help stop the size of r0 increasing, which does
        +	 * affect the multiply if it optimised for a power of 2 size */
        +	if (BN_is_negative(r0))
        +		if (!BN_add(r0,r0,rsa->p)) goto err;
        +
        +	if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
        +
        +	/* Turn BN_FLG_CONSTTIME flag on before division operation */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		pr1 = &local_r1;
        +		BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		pr1 = r1;
        +	if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
        +
        +	/* If p < q it is occasionally possible for the correction of
        +         * adding 'p' if r0 is negative above to leave the result still
        +	 * negative. This can break the private key operations: the following
        +	 * second correction should *always* correct this rare occurrence.
        +	 * This will *never* happen with OpenSSL generated keys because
        +         * they ensure p > q [steve]
        +         */
        +	if (BN_is_negative(r0))
        +		if (!BN_add(r0,r0,rsa->p)) goto err;
        +	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
        +	if (!BN_add(r0,r1,m1)) goto err;
        +
        +	if (rsa->e && rsa->n)
        +		{
        +		if (!e_rsax_bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) ))
        +                    goto err;
        +
        +		/* If 'I' was greater than (or equal to) rsa->n, the operation
        +		 * will be equivalent to using 'I mod n'. However, the result of
        +		 * the verify will *always* be less than 'n' so we don't check
        +		 * for absolute equality, just congruency. */
        +		if (!BN_sub(vrfy, vrfy, I)) goto err;
        +		if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
        +		if (BN_is_negative(vrfy))
        +			if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
        +		if (!BN_is_zero(vrfy))
        +			{
        +			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
        +			 * miscalculated CRT output, just do a raw (slower)
        +			 * mod_exp and return that instead. */
        +
        +			BIGNUM local_d;
        +			BIGNUM *d = NULL;
        +
        +			if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +				{
        +				d = &local_d;
        +				BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
        +				}
        +			else
        +				d = rsa->d;
        +			if (!e_rsax_bn_mod_exp(r0,I,d,rsa->n,ctx,
        +						   rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) )) goto err;
        +			}
        +		}
        +	ret=1;
        +
        +err:
        +	BN_CTX_end(ctx);
        +
        +	return ret;
        +	}
        +#endif /* !OPENSSL_NO_RSA */
        +#endif /* !COMPILE_RSAX */
        diff --git a/vendor/openssl/openssl/crypto/engine/eng_table.c b/vendor/openssl/openssl/crypto/engine/eng_table.c
        new file mode 100644
        index 000000000..4fde94818
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/eng_table.c
        @@ -0,0 +1,351 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/lhash.h>
        +#include "eng_int.h"
        +
        +/* The type of the items in the table */
        +typedef struct st_engine_pile
        +	{
        +	/* The 'nid' of this algorithm/mode */
        +	int nid;
        +	/* ENGINEs that implement this algorithm/mode. */
        +	STACK_OF(ENGINE) *sk;
        +	/* The default ENGINE to perform this algorithm/mode. */
        +	ENGINE *funct;
        +	/* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
        +	int uptodate;
        +	} ENGINE_PILE;
        +
        +DECLARE_LHASH_OF(ENGINE_PILE);
        +
        +/* The type exposed in eng_int.h */
        +struct st_engine_table
        +	{
        +	LHASH_OF(ENGINE_PILE) piles;
        +	}; /* ENGINE_TABLE */
        +
        +
        +typedef struct st_engine_pile_doall
        +	{
        +	engine_table_doall_cb *cb;
        +	void *arg;
        +	} ENGINE_PILE_DOALL;
        +	
        +
        +/* Global flags (ENGINE_TABLE_FLAG_***). */
        +static unsigned int table_flags = 0;
        +
        +/* API function manipulating 'table_flags' */
        +unsigned int ENGINE_get_table_flags(void)
        +	{
        +	return table_flags;
        +	}
        +
        +void ENGINE_set_table_flags(unsigned int flags)
        +	{
        +	table_flags = flags;
        +	}
        +
        +/* Internal functions for the "piles" hash table */
        +static unsigned long engine_pile_hash(const ENGINE_PILE *c)
        +	{
        +	return c->nid;
        +	}
        +
        +static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
        +	{
        +	return a->nid - b->nid;
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
        +static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
        +
        +static int int_table_check(ENGINE_TABLE **t, int create)
        +	{
        +	LHASH_OF(ENGINE_PILE) *lh;
        +
        +	if(*t) return 1;
        +	if(!create) return 0;
        +	if((lh = lh_ENGINE_PILE_new()) == NULL)
        +		return 0;
        +	*t = (ENGINE_TABLE *)lh;
        +	return 1;
        +	}
        +
        +/* Privately exposed (via eng_int.h) functions for adding and/or removing
        + * ENGINEs from the implementation table */
        +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
        +		ENGINE *e, const int *nids, int num_nids, int setdefault)
        +	{
        +	int ret = 0, added = 0;
        +	ENGINE_PILE tmplate, *fnd;
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(!(*table))
        +		added = 1;
        +	if(!int_table_check(table, 1))
        +		goto end;
        +	if(added)
        +		/* The cleanup callback needs to be added */
        +		engine_cleanup_add_first(cleanup);
        +	while(num_nids--)
        +		{
        +		tmplate.nid = *nids;
        +		fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
        +		if(!fnd)
        +			{
        +			fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
        +			if(!fnd) goto end;
        +			fnd->uptodate = 1;
        +			fnd->nid = *nids;
        +			fnd->sk = sk_ENGINE_new_null();
        +			if(!fnd->sk)
        +				{
        +				OPENSSL_free(fnd);
        +				goto end;
        +				}
        +			fnd->funct = NULL;
        +			(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
        +			}
        +		/* A registration shouldn't add duplciate entries */
        +		(void)sk_ENGINE_delete_ptr(fnd->sk, e);
        +		/* if 'setdefault', this ENGINE goes to the head of the list */
        +		if(!sk_ENGINE_push(fnd->sk, e))
        +			goto end;
        +		/* "touch" this ENGINE_PILE */
        +		fnd->uptodate = 0;
        +		if(setdefault)
        +			{
        +			if(!engine_unlocked_init(e))
        +				{
        +				ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
        +						ENGINE_R_INIT_FAILED);
        +				goto end;
        +				}
        +			if(fnd->funct)
        +				engine_unlocked_finish(fnd->funct, 0);
        +			fnd->funct = e;
        +			fnd->uptodate = 1;
        +			}
        +		nids++;
        +		}
        +	ret = 1;
        +end:
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return ret;
        +	}
        +static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
        +	{
        +	int n;
        +	/* Iterate the 'c->sk' stack removing any occurance of 'e' */
        +	while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
        +		{
        +		(void)sk_ENGINE_delete(pile->sk, n);
        +		pile->uptodate = 0;
        +		}
        +	if(pile->funct == e)
        +		{
        +		engine_unlocked_finish(e, 0);
        +		pile->funct = NULL;
        +		}
        +	}
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
        +
        +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(int_table_check(table, 0))
        +		lh_ENGINE_PILE_doall_arg(&(*table)->piles,
        +					 LHASH_DOALL_ARG_FN(int_unregister_cb),
        +					 ENGINE, e);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	}
        +
        +static void int_cleanup_cb_doall(ENGINE_PILE *p)
        +	{
        +	sk_ENGINE_free(p->sk);
        +	if(p->funct)
        +		engine_unlocked_finish(p->funct, 0);
        +	OPENSSL_free(p);
        +	}
        +static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
        +
        +void engine_table_cleanup(ENGINE_TABLE **table)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	if(*table)
        +		{
        +		lh_ENGINE_PILE_doall(&(*table)->piles,
        +				     LHASH_DOALL_FN(int_cleanup_cb));
        +		lh_ENGINE_PILE_free(&(*table)->piles);
        +		*table = NULL;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	}
        +
        +/* return a functional reference for a given 'nid' */
        +#ifndef ENGINE_TABLE_DEBUG
        +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
        +#else
        +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
        +#endif
        +	{
        +	ENGINE *ret = NULL;
        +	ENGINE_PILE tmplate, *fnd=NULL;
        +	int initres, loop = 0;
        +
        +	if(!(*table))
        +		{
        +#ifdef ENGINE_TABLE_DEBUG
        +		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
        +			"registered!\n", f, l, nid);
        +#endif
        +		return NULL;
        +		}
        +	ERR_set_mark();
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	/* Check again inside the lock otherwise we could race against cleanup
        +	 * operations. But don't worry about a fprintf(stderr). */
        +	if(!int_table_check(table, 0)) goto end;
        +	tmplate.nid = nid;
        +	fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
        +	if(!fnd) goto end;
        +	if(fnd->funct && engine_unlocked_init(fnd->funct))
        +		{
        +#ifdef ENGINE_TABLE_DEBUG
        +		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
        +			"ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
        +#endif
        +		ret = fnd->funct;
        +		goto end;
        +		}
        +	if(fnd->uptodate)
        +		{
        +		ret = fnd->funct;
        +		goto end;
        +		}
        +trynext:
        +	ret = sk_ENGINE_value(fnd->sk, loop++);
        +	if(!ret)
        +		{
        +#ifdef ENGINE_TABLE_DEBUG
        +		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
        +				"registered implementations would initialise\n",
        +				f, l, nid);
        +#endif
        +		goto end;
        +		}
        +	/* Try to initialise the ENGINE? */
        +	if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
        +		initres = engine_unlocked_init(ret);
        +	else
        +		initres = 0;
        +	if(initres)
        +		{
        +		/* Update 'funct' */
        +		if((fnd->funct != ret) && engine_unlocked_init(ret))
        +			{
        +			/* If there was a previous default we release it. */
        +			if(fnd->funct)
        +				engine_unlocked_finish(fnd->funct, 0);
        +			fnd->funct = ret;
        +#ifdef ENGINE_TABLE_DEBUG
        +			fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
        +				"setting default to '%s'\n", f, l, nid, ret->id);
        +#endif
        +			}
        +#ifdef ENGINE_TABLE_DEBUG
        +		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
        +				"newly initialised '%s'\n", f, l, nid, ret->id);
        +#endif
        +		goto end;
        +		}
        +	goto trynext;
        +end:
        +	/* If it failed, it is unlikely to succeed again until some future
        +	 * registrations have taken place. In all cases, we cache. */
        +	if(fnd) fnd->uptodate = 1;
        +#ifdef ENGINE_TABLE_DEBUG
        +	if(ret)
        +		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
        +				"ENGINE '%s'\n", f, l, nid, ret->id);
        +	else
        +		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
        +				"'no matching ENGINE'\n", f, l, nid);
        +#endif
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	/* Whatever happened, any failed init()s are not failures in this
        +	 * context, so clear our error state. */
        +	ERR_pop_to_mark();
        +	return ret;
        +	}
        +
        +/* Table enumeration */
        +
        +static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
        +	{
        +	dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
        +	}
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
        +
        +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
        +								void *arg)
        +	{
        +	ENGINE_PILE_DOALL dall;
        +	dall.cb = cb;
        +	dall.arg = arg;
        +	lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
        +				 ENGINE_PILE_DOALL, &dall);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/engine.h b/vendor/openssl/openssl/crypto/engine/engine.h
        new file mode 100644
        index 000000000..f8be49772
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/engine.h
        @@ -0,0 +1,842 @@
        +/* openssl/engine.h */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#ifndef HEADER_ENGINE_H
        +#define HEADER_ENGINE_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_ENGINE
        +#error ENGINE is disabled.
        +#endif
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +#include <openssl/ecdh.h>
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +#include <openssl/ecdsa.h>
        +#endif
        +#include <openssl/rand.h>
        +#include <openssl/ui.h>
        +#include <openssl/err.h>
        +#endif
        +
        +#include <openssl/ossl_typ.h>
        +#include <openssl/symhacks.h>
        +
        +#include <openssl/x509.h>
        +
        +#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_ECDH		(unsigned int)0x0010
        +#define ENGINE_METHOD_ECDSA		(unsigned int)0x0020
        +#define ENGINE_METHOD_CIPHERS		(unsigned int)0x0040
        +#define ENGINE_METHOD_DIGESTS		(unsigned int)0x0080
        +#define ENGINE_METHOD_STORE		(unsigned int)0x0100
        +#define ENGINE_METHOD_PKEY_METHS	(unsigned int)0x0200
        +#define ENGINE_METHOD_PKEY_ASN1_METHS	(unsigned int)0x0400
        +/* Obvious all-or-nothing cases. */
        +#define ENGINE_METHOD_ALL		(unsigned int)0xFFFF
        +#define ENGINE_METHOD_NONE		(unsigned int)0x0000
        +
        +/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
        + * internally to control registration of ENGINE implementations, and can be set
        + * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
        + * initialise registered ENGINEs if they are not already initialised. */
        +#define ENGINE_TABLE_FLAG_NOINIT	(unsigned int)0x0001
        +
        +/* ENGINE flags that can be set by ENGINE_set_flags(). */
        +/* #define ENGINE_FLAGS_MALLOCED	0x0001 */ /* Not used */
        +
        +/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
        + * control commands on their own. Without this flag, ENGINE_ctrl() handles these
        + * control commands on behalf of the ENGINE using their "cmd_defns" data. */
        +#define ENGINE_FLAGS_MANUAL_CMD_CTRL	(int)0x0002
        +
        +/* This flag is for ENGINEs who return new duplicate structures when found via
        + * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
        + * commands are called in sequence as part of some stateful process like
        + * key-generation setup and execution), it can set this flag - then each attempt
        + * to obtain the ENGINE will result in it being copied into a new structure.
        + * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
        + * the existing ENGINE's structural reference count. */
        +#define ENGINE_FLAGS_BY_ID_COPY		(int)0x0004
        +
        +/* This flag if for an ENGINE that does not want its methods registered as 
        + * part of ENGINE_register_all_complete() for example if the methods are
        + * not usable as default methods.
        + */
        +
        +#define ENGINE_FLAGS_NO_REGISTER_ALL	(int)0x0008
        +
        +/* ENGINEs can support their own command types, and these flags are used in
        + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
        + * command expects. Currently only numeric and string input is supported. If a
        + * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
        + * then it is regarded as an "internal" control command - and not for use in
        + * config setting situations. As such, they're not available to the
        + * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
        + * this list of 'command types' should be reflected carefully in
        + * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
        +
        +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
        +#define ENGINE_CMD_FLAG_NUMERIC		(unsigned int)0x0001
        +/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
        + * ENGINE_ctrl) */
        +#define ENGINE_CMD_FLAG_STRING		(unsigned int)0x0002
        +/* Indicates that the control command takes *no* input. Ie. the control command
        + * is unparameterised. */
        +#define ENGINE_CMD_FLAG_NO_INPUT	(unsigned int)0x0004
        +/* Indicates that the control command is internal. This control command won't
        + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
        + * function. */
        +#define ENGINE_CMD_FLAG_INTERNAL	(unsigned int)0x0008
        +
        +/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
        + * relying on these commands should compile conditional support for
        + * compatibility (eg. if these symbols are defined) but should also migrate the
        + * same functionality to their own ENGINE-specific control functions that can be
        + * "discovered" by calling applications. The fact these control commands
        + * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
        + * fact that application code can find and use them without requiring per-ENGINE
        + * hacking. */
        +
        +/* 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
        +#define ENGINE_CTRL_HUP				3 /* Close and reinitialise any
        +						     handles/connections etc. */
        +#define ENGINE_CTRL_SET_USER_INTERFACE          4 /* Alternative to callback */
        +#define ENGINE_CTRL_SET_CALLBACK_DATA           5 /* User-specific data, used
        +						     when calling the password
        +						     callback and the user
        +						     interface */
        +#define ENGINE_CTRL_LOAD_CONFIGURATION		6 /* Load a configuration, given
        +						     a string that represents a
        +						     file name or so */
        +#define ENGINE_CTRL_LOAD_SECTION		7 /* Load data from a given
        +						     section in the already loaded
        +						     configuration */
        +
        +/* These control commands allow an application to deal with an arbitrary engine
        + * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
        + * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
        + * including ENGINE-specific command types, return zero for an error.
        + *
        + * An ENGINE can choose to implement these ctrl functions, and can internally
        + * manage things however it chooses - it does so by setting the
        + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
        + * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
        + * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
        + * handler need only implement its own commands - the above "meta" commands will
        + * be taken care of. */
        +
        +/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
        + * all the remaining control commands will return failure, so it is worth
        + * checking this first if the caller is trying to "discover" the engine's
        + * capabilities and doesn't want errors generated unnecessarily. */
        +#define ENGINE_CTRL_HAS_CTRL_FUNCTION		10
        +/* Returns a positive command number for the first command supported by the
        + * engine. Returns zero if no ctrl commands are supported. */
        +#define ENGINE_CTRL_GET_FIRST_CMD_TYPE		11
        +/* The 'long' argument specifies a command implemented by the engine, and the
        + * return value is the next command supported, or zero if there are no more. */
        +#define ENGINE_CTRL_GET_NEXT_CMD_TYPE		12
        +/* The 'void*' argument is a command name (cast from 'const char *'), and the
        + * return value is the command that corresponds to it. */
        +#define ENGINE_CTRL_GET_CMD_FROM_NAME		13
        +/* The next two allow a command to be converted into its corresponding string
        + * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
        + * case, the return value is the length of the command name (not counting a
        + * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
        + * large enough, and it will be populated with the name of the command (WITH a
        + * trailing EOL). */
        +#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD	14
        +#define ENGINE_CTRL_GET_NAME_FROM_CMD		15
        +/* The next two are similar but give a "short description" of a command. */
        +#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD	16
        +#define ENGINE_CTRL_GET_DESC_FROM_CMD		17
        +/* With this command, the return value is the OR'd combination of
        + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
        + * engine-specific ctrl command expects. */
        +#define ENGINE_CTRL_GET_CMD_FLAGS		18
        +
        +/* ENGINE implementations should start the numbering of their own control
        + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
        +#define ENGINE_CMD_BASE				200
        +
        +/* NB: These 2 nCipher "chil" control commands are deprecated, and their
        + * functionality is now available through ENGINE-specific control commands
        + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
        + * commands should be migrated to the more general command handling before these
        + * are removed. */
        +
        +/* 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. */
        +
        +/* If an ENGINE supports its own specific control commands and wishes the
        + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
        + * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
        + * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
        + * supports the stated commands (ie. the "cmd_num" entries as described by the
        + * array). NB: The array must be ordered in increasing order of cmd_num.
        + * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
        + * to zero and/or cmd_name set to NULL. */
        +typedef struct ENGINE_CMD_DEFN_st
        +	{
        +	unsigned int cmd_num; /* The command number */
        +	const char *cmd_name; /* The command name itself */
        +	const char *cmd_desc; /* A short description of the command */
        +	unsigned int cmd_flags; /* The input the command expects */
        +	} ENGINE_CMD_DEFN;
        +
        +/* Generic function pointer */
        +typedef int (*ENGINE_GEN_FUNC_PTR)(void);
        +/* Generic function pointer taking no arguments */
        +typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
        +/* Specific control function pointer */
        +typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
        +/* Generic load_key function pointer */
        +typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
        +	UI_METHOD *ui_method, void *callback_data);
        +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
        +	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
        +	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
        +/* These callback types are for an ENGINE's handler for cipher and digest logic.
        + * These handlers have these prototypes;
        + *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
        + *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
        + * Looking at how to implement these handlers in the case of cipher support, if
        + * the framework wants the EVP_CIPHER for 'nid', it will call;
        + *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
        + * If the framework wants a list of supported 'nid's, it will call;
        + *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
        + */
        +/* Returns to a pointer to the array of supported cipher 'nid's. If the second
        + * parameter is non-NULL it is set to the size of the returned array. */
        +typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
        +typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
        +typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
        +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
        +/* 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 allowed 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_by_id 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);
        +/* Add all the built-in engines. */
        +void ENGINE_load_openssl(void);
        +void ENGINE_load_dynamic(void);
        +#ifndef OPENSSL_NO_STATIC_ENGINE
        +void ENGINE_load_4758cca(void);
        +void ENGINE_load_aep(void);
        +void ENGINE_load_atalla(void);
        +void ENGINE_load_chil(void);
        +void ENGINE_load_cswift(void);
        +void ENGINE_load_nuron(void);
        +void ENGINE_load_sureware(void);
        +void ENGINE_load_ubsec(void);
        +void ENGINE_load_padlock(void);
        +void ENGINE_load_capi(void);
        +#ifndef OPENSSL_NO_GMP
        +void ENGINE_load_gmp(void);
        +#endif
        +#ifndef OPENSSL_NO_GOST
        +void ENGINE_load_gost(void);
        +#endif
        +#endif
        +void ENGINE_load_cryptodev(void);
        +void ENGINE_load_rsax(void);
        +void ENGINE_load_rdrand(void);
        +void ENGINE_load_builtin_engines(void);
        +
        +/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
        + * "registry" handling. */
        +unsigned int ENGINE_get_table_flags(void);
        +void ENGINE_set_table_flags(unsigned int flags);
        +
        +/* Manage registration of ENGINEs per "table". For each type, there are 3
        + * functions;
        + *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
        + *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
        + *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
        + * Cleanup is automatically registered from each table when required, so
        + * ENGINE_cleanup() will reverse any "register" operations. */
        +
        +int ENGINE_register_RSA(ENGINE *e);
        +void ENGINE_unregister_RSA(ENGINE *e);
        +void ENGINE_register_all_RSA(void);
        +
        +int ENGINE_register_DSA(ENGINE *e);
        +void ENGINE_unregister_DSA(ENGINE *e);
        +void ENGINE_register_all_DSA(void);
        +
        +int ENGINE_register_ECDH(ENGINE *e);
        +void ENGINE_unregister_ECDH(ENGINE *e);
        +void ENGINE_register_all_ECDH(void);
        +
        +int ENGINE_register_ECDSA(ENGINE *e);
        +void ENGINE_unregister_ECDSA(ENGINE *e);
        +void ENGINE_register_all_ECDSA(void);
        +
        +int ENGINE_register_DH(ENGINE *e);
        +void ENGINE_unregister_DH(ENGINE *e);
        +void ENGINE_register_all_DH(void);
        +
        +int ENGINE_register_RAND(ENGINE *e);
        +void ENGINE_unregister_RAND(ENGINE *e);
        +void ENGINE_register_all_RAND(void);
        +
        +int ENGINE_register_STORE(ENGINE *e);
        +void ENGINE_unregister_STORE(ENGINE *e);
        +void ENGINE_register_all_STORE(void);
        +
        +int ENGINE_register_ciphers(ENGINE *e);
        +void ENGINE_unregister_ciphers(ENGINE *e);
        +void ENGINE_register_all_ciphers(void);
        +
        +int ENGINE_register_digests(ENGINE *e);
        +void ENGINE_unregister_digests(ENGINE *e);
        +void ENGINE_register_all_digests(void);
        +
        +int ENGINE_register_pkey_meths(ENGINE *e);
        +void ENGINE_unregister_pkey_meths(ENGINE *e);
        +void ENGINE_register_all_pkey_meths(void);
        +
        +int ENGINE_register_pkey_asn1_meths(ENGINE *e);
        +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
        +void ENGINE_register_all_pkey_asn1_meths(void);
        +
        +/* These functions register all support from the above categories. Note, use of
        + * these functions can result in static linkage of code your application may not
        + * need. If you only need a subset of functionality, consider using more
        + * selective initialisation. */
        +int ENGINE_register_complete(ENGINE *e);
        +int ENGINE_register_all_complete(void);
        +
        +/* Send parametrised control 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. In
        + * actuality, this function only requires a structural (rather than functional)
        + * reference to an engine, but many control commands may require the engine be
        + * functional. The caller should be aware of trying commands that require an
        + * operational ENGINE, and only use functional references in such situations. */
        +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +
        +/* This function tests if an ENGINE-specific command is usable as a "setting".
        + * Eg. in an application's config file that gets processed through
        + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
        + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
        +int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
        +
        +/* This function works like ENGINE_ctrl() with the exception of taking a
        + * command name instead of a command number, and can handle optional commands.
        + * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
        + * use the cmd_name and cmd_optional. */
        +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
        +        long i, void *p, void (*f)(void), int cmd_optional);
        +
        +/* This function passes a command-name and argument to an ENGINE. The cmd_name
        + * is converted to a command number and the control command is called using
        + * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
        + * which case no control command is called). The command is checked for input
        + * flags, and if necessary the argument will be converted to a numeric value. If
        + * cmd_optional is non-zero, then if the ENGINE doesn't support the given
        + * cmd_name the return value will be success anyway. This function is intended
        + * for applications to use so that users (or config files) can supply
        + * engine-specific config data to the ENGINE at run-time to control behaviour of
        + * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
        + * functions that return data, deal with binary data, or that are otherwise
        + * supposed to be used directly through ENGINE_ctrl() in application code. Any
        + * "return" data from an ENGINE_ctrl() operation in this function will be lost -
        + * the return value is interpreted as failure if the return value is zero,
        + * success otherwise, and this function returns a boolean value as a result. In
        + * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
        + * implementations with parameterisations that work in this scheme, so that
        + * compliant ENGINE-based applications can work consistently with the same
        + * configuration for the same ENGINE-enabled devices, across applications. */
        +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
        +				int cmd_optional);
        +
        +/* 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! */
        +ENGINE *ENGINE_new(void);
        +int ENGINE_free(ENGINE *e);
        +int ENGINE_up_ref(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, const RSA_METHOD *rsa_meth);
        +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
        +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
        +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
        +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
        +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
        +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
        +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
        +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);
        +int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
        +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
        +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
        +				ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
        +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
        +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
        +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
        +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
        +int ENGINE_set_flags(ENGINE *e, int flags);
        +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
        +/* These functions allow control over any per-structure ENGINE data. */
        +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +		CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
        +void *ENGINE_get_ex_data(const ENGINE *e, int idx);
        +
        +/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
        + * automatically ensures the list cleanup function is registered to be called
        + * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
        + * ENGINE_cleanup() will clean up after them. */
        +void ENGINE_cleanup(void);
        +
        +/* 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(const ENGINE *e);
        +const char *ENGINE_get_name(const ENGINE *e);
        +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
        +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
        +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
        +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
        +const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
        +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
        +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
        +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
        +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
        +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
        +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
        +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
        +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
        +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
        +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
        +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
        +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
        +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
        +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
        +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
        +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
        +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
        +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
        +					const char *str, int len);
        +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
        +					const char *str, int len);
        +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
        +int ENGINE_get_flags(const ENGINE *e);
        +
        +/* 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);
        +
        +/* 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,
        +	UI_METHOD *ui_method, void *callback_data);
        +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
        +	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
        +	STACK_OF(X509) **pother,
        +	UI_METHOD *ui_method, void *callback_data);
        +
        +/* 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_ECDH(void);
        +ENGINE *ENGINE_get_default_ECDSA(void);
        +ENGINE *ENGINE_get_default_DH(void);
        +ENGINE *ENGINE_get_default_RAND(void);
        +/* These functions can be used to get a functional reference to perform
        + * ciphering or digesting corresponding to "nid". */
        +ENGINE *ENGINE_get_cipher_engine(int nid);
        +ENGINE *ENGINE_get_digest_engine(int nid);
        +ENGINE *ENGINE_get_pkey_meth_engine(int nid);
        +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
        +
        +/* 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);
        +int ENGINE_set_default_string(ENGINE *e, const char *def_list);
        +/* Same for the other "methods" */
        +int ENGINE_set_default_DSA(ENGINE *e);
        +int ENGINE_set_default_ECDH(ENGINE *e);
        +int ENGINE_set_default_ECDSA(ENGINE *e);
        +int ENGINE_set_default_DH(ENGINE *e);
        +int ENGINE_set_default_RAND(ENGINE *e);
        +int ENGINE_set_default_ciphers(ENGINE *e);
        +int ENGINE_set_default_digests(ENGINE *e);
        +int ENGINE_set_default_pkey_meths(ENGINE *e);
        +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
        +
        +/* The combination "set" - the flags are bitwise "OR"d from the
        + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
        + * function, this function can result in unnecessary static linkage. If your
        + * application requires only specific functionality, consider using more
        + * selective functions. */
        +int ENGINE_set_default(ENGINE *e, unsigned int flags);
        +
        +void ENGINE_add_conf_module(void);
        +
        +/* Deprecated functions ... */
        +/* int ENGINE_clear_defaults(void); */
        +
        +/**************************/
        +/* DYNAMIC ENGINE SUPPORT */
        +/**************************/
        +
        +/* Binary/behaviour compatibility levels */
        +#define OSSL_DYNAMIC_VERSION		(unsigned long)0x00020000
        +/* Binary versions older than this are too old for us (whether we're a loader or
        + * a loadee) */
        +#define OSSL_DYNAMIC_OLDEST		(unsigned long)0x00020000
        +
        +/* When compiling an ENGINE entirely as an external shared library, loadable by
        + * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
        + * type provides the calling application's (or library's) error functionality
        + * and memory management function pointers to the loaded library. These should
        + * be used/set in the loaded library code so that the loading application's
        + * 'state' will be used/changed in all operations. The 'static_state' pointer
        + * allows the loaded library to know if it shares the same static data as the
        + * calling application (or library), and thus whether these callbacks need to be
        + * set or not. */
        +typedef void *(*dyn_MEM_malloc_cb)(size_t);
        +typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
        +typedef void (*dyn_MEM_free_cb)(void *);
        +typedef struct st_dynamic_MEM_fns {
        +	dyn_MEM_malloc_cb			malloc_cb;
        +	dyn_MEM_realloc_cb			realloc_cb;
        +	dyn_MEM_free_cb				free_cb;
        +	} dynamic_MEM_fns;
        +/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
        + * these types so we (and any other dependant code) can simplify a bit?? */
        +typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
        +typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
        +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
        +						const char *,int);
        +typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
        +						const char *,int);
        +typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
        +						const char *,int);
        +typedef struct st_dynamic_LOCK_fns {
        +	dyn_lock_locking_cb			lock_locking_cb;
        +	dyn_lock_add_lock_cb			lock_add_lock_cb;
        +	dyn_dynlock_create_cb			dynlock_create_cb;
        +	dyn_dynlock_lock_cb			dynlock_lock_cb;
        +	dyn_dynlock_destroy_cb			dynlock_destroy_cb;
        +	} dynamic_LOCK_fns;
        +/* The top-level structure */
        +typedef struct st_dynamic_fns {
        +	void 					*static_state;
        +	const ERR_FNS				*err_fns;
        +	const CRYPTO_EX_DATA_IMPL		*ex_data_fns;
        +	dynamic_MEM_fns				mem_fns;
        +	dynamic_LOCK_fns			lock_fns;
        +	} dynamic_fns;
        +
        +/* The version checking function should be of this prototype. NB: The
        + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
        + * If this function returns zero, it indicates a (potential) version
        + * incompatibility and the loaded library doesn't believe it can proceed.
        + * Otherwise, the returned value is the (latest) version supported by the
        + * loading library. The loader may still decide that the loaded code's version
        + * is unsatisfactory and could veto the load. The function is expected to
        + * be implemented with the symbol name "v_check", and a default implementation
        + * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
        +typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
        +#define IMPLEMENT_DYNAMIC_CHECK_FN() \
        +	OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
        +	OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
        +		if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
        +		return 0; }
        +
        +/* This function is passed the ENGINE structure to initialise with its own
        + * function and command settings. It should not adjust the structural or
        + * functional reference counts. If this function returns zero, (a) the load will
        + * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
        + * structure, and (c) the shared library will be unloaded. So implementations
        + * should do their own internal cleanup in failure circumstances otherwise they
        + * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
        + * the loader is looking for. If this is NULL, the shared library can choose to
        + * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
        + * library must initialise only an ENGINE matching the passed 'id'. The function
        + * is expected to be implemented with the symbol name "bind_engine". A standard
        + * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
        + * the parameter 'fn' is a callback function that populates the ENGINE structure
        + * and returns an int value (zero for failure). 'fn' should have prototype;
        + *    [static] int fn(ENGINE *e, const char *id); */
        +typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
        +				const dynamic_fns *fns);
        +#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
        +	OPENSSL_EXPORT \
        +	int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
        +	OPENSSL_EXPORT \
        +	int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
        +		if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
        +		if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
        +			fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
        +			return 0; \
        +		CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
        +		CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
        +		CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
        +		CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
        +		CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
        +		if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
        +			return 0; \
        +		if(!ERR_set_implementation(fns->err_fns)) return 0; \
        +	skip_cbs: \
        +		if(!fn(e,id)) return 0; \
        +		return 1; }
        +
        +/* If the loading application (or library) and the loaded ENGINE library share
        + * the same static data (eg. they're both dynamically linked to the same
        + * libcrypto.so) we need a way to avoid trying to set system callbacks - this
        + * would fail, and for the same reason that it's unnecessary to try. If the
        + * loaded ENGINE has (or gets from through the loader) its own copy of the
        + * libcrypto static data, we will need to set the callbacks. The easiest way to
        + * detect this is to have a function that returns a pointer to some static data
        + * and let the loading application and loaded ENGINE compare their respective
        + * values. */
        +void *ENGINE_get_static_state(void);
        +
        +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
        +void ENGINE_setup_bsd_cryptodev(void);
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_ENGINE_strings(void);
        +
        +/* Error codes for the ENGINE functions. */
        +
        +/* Function codes. */
        +#define ENGINE_F_DYNAMIC_CTRL				 180
        +#define ENGINE_F_DYNAMIC_GET_DATA_CTX			 181
        +#define ENGINE_F_DYNAMIC_LOAD				 182
        +#define ENGINE_F_DYNAMIC_SET_DATA_CTX			 183
        +#define ENGINE_F_ENGINE_ADD				 105
        +#define ENGINE_F_ENGINE_BY_ID				 106
        +#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE		 170
        +#define ENGINE_F_ENGINE_CTRL				 142
        +#define ENGINE_F_ENGINE_CTRL_CMD			 178
        +#define ENGINE_F_ENGINE_CTRL_CMD_STRING			 171
        +#define ENGINE_F_ENGINE_FINISH				 107
        +#define ENGINE_F_ENGINE_FREE_UTIL			 108
        +#define ENGINE_F_ENGINE_GET_CIPHER			 185
        +#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE		 177
        +#define ENGINE_F_ENGINE_GET_DIGEST			 186
        +#define ENGINE_F_ENGINE_GET_NEXT			 115
        +#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH		 193
        +#define ENGINE_F_ENGINE_GET_PKEY_METH			 192
        +#define ENGINE_F_ENGINE_GET_PREV			 116
        +#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_LOAD_SSL_CLIENT_CERT		 194
        +#define ENGINE_F_ENGINE_NEW				 122
        +#define ENGINE_F_ENGINE_REMOVE				 123
        +#define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
        +#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE		 126
        +#define ENGINE_F_ENGINE_SET_ID				 129
        +#define ENGINE_F_ENGINE_SET_NAME			 130
        +#define ENGINE_F_ENGINE_TABLE_REGISTER			 184
        +#define ENGINE_F_ENGINE_UNLOAD_KEY			 152
        +#define ENGINE_F_ENGINE_UNLOCKED_FINISH			 191
        +#define ENGINE_F_ENGINE_UP_REF				 190
        +#define ENGINE_F_INT_CTRL_HELPER			 172
        +#define ENGINE_F_INT_ENGINE_CONFIGURE			 188
        +#define ENGINE_F_INT_ENGINE_MODULE_INIT			 187
        +#define ENGINE_F_LOG_MESSAGE				 141
        +
        +/* Reason codes. */
        +#define ENGINE_R_ALREADY_LOADED				 100
        +#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER		 133
        +#define ENGINE_R_CMD_NOT_EXECUTABLE			 134
        +#define ENGINE_R_COMMAND_TAKES_INPUT			 135
        +#define ENGINE_R_COMMAND_TAKES_NO_INPUT			 136
        +#define ENGINE_R_CONFLICTING_ENGINE_ID			 103
        +#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED		 119
        +#define ENGINE_R_DH_NOT_IMPLEMENTED			 139
        +#define ENGINE_R_DSA_NOT_IMPLEMENTED			 140
        +#define ENGINE_R_DSO_FAILURE				 104
        +#define ENGINE_R_DSO_NOT_FOUND				 132
        +#define ENGINE_R_ENGINES_SECTION_ERROR			 148
        +#define ENGINE_R_ENGINE_CONFIGURATION_ERROR		 102
        +#define ENGINE_R_ENGINE_IS_NOT_IN_LIST			 105
        +#define ENGINE_R_ENGINE_SECTION_ERROR			 149
        +#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_INVALID_ARGUMENT			 143
        +#define ENGINE_R_INVALID_CMD_NAME			 137
        +#define ENGINE_R_INVALID_CMD_NUMBER			 138
        +#define ENGINE_R_INVALID_INIT_VALUE			 151
        +#define ENGINE_R_INVALID_STRING				 150
        +#define ENGINE_R_NOT_INITIALISED			 117
        +#define ENGINE_R_NOT_LOADED				 112
        +#define ENGINE_R_NO_CONTROL_FUNCTION			 120
        +#define ENGINE_R_NO_INDEX				 144
        +#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_RSA_NOT_IMPLEMENTED			 141
        +#define ENGINE_R_UNIMPLEMENTED_CIPHER			 146
        +#define ENGINE_R_UNIMPLEMENTED_DIGEST			 147
        +#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD	 101
        +#define ENGINE_R_VERSION_INCOMPATIBILITY		 145
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/engine/enginetest.c b/vendor/openssl/openssl/crypto/engine/enginetest.c
        new file mode 100644
        index 000000000..f4d70e7e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/enginetest.c
        @@ -0,0 +1,283 @@
        +/* crypto/engine/enginetest.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/e_os2.h>
        +
        +#ifdef OPENSSL_NO_ENGINE
        +int main(int argc, char *argv[])
        +{
        +    printf("No ENGINE support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/buffer.h>
        +#include <openssl/crypto.h>
        +#include <openssl/engine.h>
        +#include <openssl/err.h>
        +
        +static void display_engine_list(void)
        +	{
        +	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");
        +	/* ENGINE_get_first() increases the struct_ref counter, so we 
        +           must call ENGINE_free() to decrease it again */
        +	ENGINE_free(h);
        +	}
        +
        +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;
        +
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +	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;
        +		}
        +	if (ptr)
        +		ENGINE_free(ptr);
        +	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");
        +	ERR_clear_error();
        +	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");
        +	if (ptr)
        +		ENGINE_free(ptr);
        +	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 = BUF_strdup(buf);
        +		sprintf(buf, "Fake engine type %i", loop);
        +		name = BUF_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;
        +			}
        +		ENGINE_free(ptr);
        +		printf("."); fflush(stdout);
        +		}
        +	for(loop = 0; loop < 512; loop++)
        +		{
        +		OPENSSL_free((void *)ENGINE_get_id(block[loop]));
        +		OPENSSL_free((void *)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]);
        +	ENGINE_cleanup();
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_free_strings();
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks_fp(stderr);
        +	return to_return;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_asnmth.c b/vendor/openssl/openssl/crypto/engine/tb_asnmth.c
        new file mode 100644
        index 000000000..75090339f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_asnmth.c
        @@ -0,0 +1,246 @@
        +/* ====================================================================
        + * Copyright (c) 2006 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 "eng_int.h"
        +#include "asn1_locl.h"
        +#include <openssl/evp.h>
        +
        +/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
        + * function that is used by EVP to hook in pkey_asn1_meth code and cache
        + * defaults (etc), will display brief debugging summaries to stderr with the
        + * 'nid'. */
        +/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
        +
        +static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
        +
        +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
        +	{
        +	engine_table_unregister(&pkey_asn1_meth_table, e);
        +	}
        +
        +static void engine_unregister_all_pkey_asn1_meths(void)
        +	{
        +	engine_table_cleanup(&pkey_asn1_meth_table);
        +	}
        +
        +int ENGINE_register_pkey_asn1_meths(ENGINE *e)
        +	{
        +	if(e->pkey_asn1_meths)
        +		{
        +		const int *nids;
        +		int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&pkey_asn1_meth_table,
        +				engine_unregister_all_pkey_asn1_meths, e, nids,
        +					num_nids, 0);
        +		}
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_pkey_asn1_meths(void)
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_pkey_asn1_meths(e);
        +	}
        +
        +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
        +	{
        +	if(e->pkey_asn1_meths)
        +		{
        +		const int *nids;
        +		int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&pkey_asn1_meth_table,
        +				engine_unregister_all_pkey_asn1_meths, e, nids,
        +					num_nids, 1);
        +		}
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references) for a given pkey_asn1_meth 'nid' */
        +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
        +	{
        +	return engine_table_select(&pkey_asn1_meth_table, nid);
        +	}
        +
        +/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
        +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
        +	{
        +	EVP_PKEY_ASN1_METHOD *ret;
        +	ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
        +	if(!fn || !fn(e, &ret, NULL, nid))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
        +				ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +/* Gets the pkey_asn1_meth callback from an ENGINE structure */
        +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
        +	{
        +	return e->pkey_asn1_meths;
        +	}
        +
        +/* Sets the pkey_asn1_meth callback in an ENGINE structure */
        +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
        +	{
        +	e->pkey_asn1_meths = f;
        +	return 1;
        +	}
        +
        +/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
        + * ENGINE is destroyed
        + */
        +
        +void engine_pkey_asn1_meths_free(ENGINE *e)
        +	{
        +	int i;
        +	EVP_PKEY_ASN1_METHOD *pkm;
        +	if (e->pkey_asn1_meths)
        +		{
        +		const int *pknids;
        +		int npknids;
        +		npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
        +		for (i = 0; i < npknids; i++)
        +			{
        +			if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
        +				{
        +				EVP_PKEY_asn1_free(pkm);
        +				}
        +			}
        +		}
        +	}
        +
        +/* Find a method based on a string. This does a linear search through
        + * all implemented algorithms. This is OK in practice because only
        + * a small number of algorithms are likely to be implemented in an engine
        + * and it is not used for speed critical operations.
        + */
        +
        +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
        +					const char *str, int len)
        +	{
        +	int i, nidcount;
        +	const int *nids;
        +	EVP_PKEY_ASN1_METHOD *ameth;
        +	if (!e->pkey_asn1_meths)
        +		return NULL;
        +	if (len == -1)
        +		len = strlen(str);
        +	nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
        +	for (i = 0; i < nidcount; i++)
        +		{
        +		e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
        +		if (((int)strlen(ameth->pem_str) == len) && 
        +					!strncasecmp(ameth->pem_str, str, len))
        +			return ameth;
        +		}
        +	return NULL;
        +	}
        +
        +typedef struct 
        +	{
        +	ENGINE *e;
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	const char *str;
        +	int len;
        +	} ENGINE_FIND_STR;
        +
        +static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
        +	{
        +	ENGINE_FIND_STR *lk = arg;
        +	int i;
        +	if (lk->ameth)
        +		return;
        +	for (i = 0; i < sk_ENGINE_num(sk); i++)
        +		{
        +		ENGINE *e = sk_ENGINE_value(sk, i);
        +		EVP_PKEY_ASN1_METHOD *ameth;
        +		e->pkey_asn1_meths(e, &ameth, NULL, nid);
        +		if (((int)strlen(ameth->pem_str) == lk->len) && 
        +				!strncasecmp(ameth->pem_str, lk->str, lk->len))
        +			{
        +			lk->e = e;
        +			lk->ameth = ameth;
        +			return;
        +			}
        +		}
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
        +					const char *str, int len)
        +	{
        +	ENGINE_FIND_STR fstr;
        +	fstr.e = NULL;
        +	fstr.ameth = NULL;
        +	fstr.str = str;
        +	fstr.len = len;
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
        +	/* If found obtain a structural reference to engine */
        +	if (fstr.e)
        +		{
        +		fstr.e->struct_ref++;
        +		engine_ref_debug(fstr.e, 0, 1)
        +		}
        +	*pe = fstr.e;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return fstr.ameth;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_cipher.c b/vendor/openssl/openssl/crypto/engine/tb_cipher.c
        new file mode 100644
        index 000000000..177fc1fb7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_cipher.c
        @@ -0,0 +1,143 @@
        +/* ====================================================================
        + * 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 "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
        + * is used by EVP to hook in cipher code and cache defaults (etc), will display
        + * brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_CIPHER_DEBUG */
        +
        +static ENGINE_TABLE *cipher_table = NULL;
        +
        +void ENGINE_unregister_ciphers(ENGINE *e)
        +	{
        +	engine_table_unregister(&cipher_table, e);
        +	}
        +
        +static void engine_unregister_all_ciphers(void)
        +	{
        +	engine_table_cleanup(&cipher_table);
        +	}
        +
        +int ENGINE_register_ciphers(ENGINE *e)
        +	{
        +	if(e->ciphers)
        +		{
        +		const int *nids;
        +		int num_nids = e->ciphers(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&cipher_table,
        +					engine_unregister_all_ciphers, e, nids,
        +					num_nids, 0);
        +		}
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_ciphers()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_ciphers(e);
        +	}
        +
        +int ENGINE_set_default_ciphers(ENGINE *e)
        +	{
        +	if(e->ciphers)
        +		{
        +		const int *nids;
        +		int num_nids = e->ciphers(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&cipher_table,
        +					engine_unregister_all_ciphers, e, nids,
        +					num_nids, 1);
        +		}
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references) for a given cipher 'nid' */
        +ENGINE *ENGINE_get_cipher_engine(int nid)
        +	{
        +	return engine_table_select(&cipher_table, nid);
        +	}
        +
        +/* Obtains a cipher implementation from an ENGINE functional reference */
        +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
        +	{
        +	const EVP_CIPHER *ret;
        +	ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
        +	if(!fn || !fn(e, &ret, NULL, nid))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
        +				ENGINE_R_UNIMPLEMENTED_CIPHER);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +/* Gets the cipher callback from an ENGINE structure */
        +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
        +	{
        +	return e->ciphers;
        +	}
        +
        +/* Sets the cipher callback in an ENGINE structure */
        +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
        +	{
        +	e->ciphers = f;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_dh.c b/vendor/openssl/openssl/crypto/engine/tb_dh.c
        new file mode 100644
        index 000000000..6e9d42876
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_dh.c
        @@ -0,0 +1,118 @@
        +/* ====================================================================
        + * 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 "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
        + * used by DH to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_DH_DEBUG */
        +
        +static ENGINE_TABLE *dh_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_DH(ENGINE *e)
        +	{
        +	engine_table_unregister(&dh_table, e);
        +	}
        +
        +static void engine_unregister_all_DH(void)
        +	{
        +	engine_table_cleanup(&dh_table);
        +	}
        +
        +int ENGINE_register_DH(ENGINE *e)
        +	{
        +	if(e->dh_meth)
        +		return engine_table_register(&dh_table,
        +				engine_unregister_all_DH, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_DH()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_DH(e);
        +	}
        +
        +int ENGINE_set_default_DH(ENGINE *e)
        +	{
        +	if(e->dh_meth)
        +		return engine_table_register(&dh_table,
        +				engine_unregister_all_DH, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_DH(void)
        +	{
        +	return engine_table_select(&dh_table, dummy_nid);
        +	}
        +
        +/* Obtains an DH implementation from an ENGINE functional reference */
        +const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
        +	{
        +	return e->dh_meth;
        +	}
        +
        +/* Sets an DH implementation in an ENGINE structure */
        +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
        +	{
        +	e->dh_meth = dh_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_digest.c b/vendor/openssl/openssl/crypto/engine/tb_digest.c
        new file mode 100644
        index 000000000..d3f4bb274
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_digest.c
        @@ -0,0 +1,143 @@
        +/* ====================================================================
        + * 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 "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
        + * is used by EVP to hook in digest code and cache defaults (etc), will display
        + * brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_DIGEST_DEBUG */
        +
        +static ENGINE_TABLE *digest_table = NULL;
        +
        +void ENGINE_unregister_digests(ENGINE *e)
        +	{
        +	engine_table_unregister(&digest_table, e);
        +	}
        +
        +static void engine_unregister_all_digests(void)
        +	{
        +	engine_table_cleanup(&digest_table);
        +	}
        +
        +int ENGINE_register_digests(ENGINE *e)
        +	{
        +	if(e->digests)
        +		{
        +		const int *nids;
        +		int num_nids = e->digests(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&digest_table,
        +					engine_unregister_all_digests, e, nids,
        +					num_nids, 0);
        +		}
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_digests()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_digests(e);
        +	}
        +
        +int ENGINE_set_default_digests(ENGINE *e)
        +	{
        +	if(e->digests)
        +		{
        +		const int *nids;
        +		int num_nids = e->digests(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&digest_table,
        +					engine_unregister_all_digests, e, nids,
        +					num_nids, 1);
        +		}
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references) for a given digest 'nid' */
        +ENGINE *ENGINE_get_digest_engine(int nid)
        +	{
        +	return engine_table_select(&digest_table, nid);
        +	}
        +
        +/* Obtains a digest implementation from an ENGINE functional reference */
        +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
        +	{
        +	const EVP_MD *ret;
        +	ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
        +	if(!fn || !fn(e, &ret, NULL, nid))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
        +				ENGINE_R_UNIMPLEMENTED_DIGEST);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +/* Gets the digest callback from an ENGINE structure */
        +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
        +	{
        +	return e->digests;
        +	}
        +
        +/* Sets the digest callback in an ENGINE structure */
        +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
        +	{
        +	e->digests = f;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_dsa.c b/vendor/openssl/openssl/crypto/engine/tb_dsa.c
        new file mode 100644
        index 000000000..e4674f5f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_dsa.c
        @@ -0,0 +1,118 @@
        +/* ====================================================================
        + * 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 "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
        + * used by DSA to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_DSA_DEBUG */
        +
        +static ENGINE_TABLE *dsa_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_DSA(ENGINE *e)
        +	{
        +	engine_table_unregister(&dsa_table, e);
        +	}
        +
        +static void engine_unregister_all_DSA(void)
        +	{
        +	engine_table_cleanup(&dsa_table);
        +	}
        +
        +int ENGINE_register_DSA(ENGINE *e)
        +	{
        +	if(e->dsa_meth)
        +		return engine_table_register(&dsa_table,
        +				engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_DSA()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_DSA(e);
        +	}
        +
        +int ENGINE_set_default_DSA(ENGINE *e)
        +	{
        +	if(e->dsa_meth)
        +		return engine_table_register(&dsa_table,
        +				engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_DSA(void)
        +	{
        +	return engine_table_select(&dsa_table, dummy_nid);
        +	}
        +
        +/* Obtains an DSA implementation from an ENGINE functional reference */
        +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
        +	{
        +	return e->dsa_meth;
        +	}
        +
        +/* Sets an DSA implementation in an ENGINE structure */
        +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
        +	{
        +	e->dsa_meth = dsa_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_ecdh.c b/vendor/openssl/openssl/crypto/engine/tb_ecdh.c
        new file mode 100644
        index 000000000..c8ec7812c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_ecdh.c
        @@ -0,0 +1,133 @@
        +/* crypto/engine/tb_ecdh.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH engine software is originally written by Nils Gura and
        + * Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
        + * used by ECDH to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_ECDH_DEBUG */
        +
        +static ENGINE_TABLE *ecdh_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_ECDH(ENGINE *e)
        +	{
        +	engine_table_unregister(&ecdh_table, e);
        +	}
        +
        +static void engine_unregister_all_ECDH(void)
        +	{
        +	engine_table_cleanup(&ecdh_table);
        +	}
        +
        +int ENGINE_register_ECDH(ENGINE *e)
        +	{
        +	if(e->ecdh_meth)
        +		return engine_table_register(&ecdh_table,
        +				engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_ECDH()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_ECDH(e);
        +	}
        +
        +int ENGINE_set_default_ECDH(ENGINE *e)
        +	{
        +	if(e->ecdh_meth)
        +		return engine_table_register(&ecdh_table,
        +				engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_ECDH(void)
        +	{
        +	return engine_table_select(&ecdh_table, dummy_nid);
        +	}
        +
        +/* Obtains an ECDH implementation from an ENGINE functional reference */
        +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e)
        +	{
        +	return e->ecdh_meth;
        +	}
        +
        +/* Sets an ECDH implementation in an ENGINE structure */
        +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
        +	{
        +	e->ecdh_meth = ecdh_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_ecdsa.c b/vendor/openssl/openssl/crypto/engine/tb_ecdsa.c
        new file mode 100644
        index 000000000..005ecb622
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_ecdsa.c
        @@ -0,0 +1,118 @@
        +/* ====================================================================
        + * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
        + * used by ECDSA to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_ECDSA_DEBUG */
        +
        +static ENGINE_TABLE *ecdsa_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_ECDSA(ENGINE *e)
        +	{
        +	engine_table_unregister(&ecdsa_table, e);
        +	}
        +
        +static void engine_unregister_all_ECDSA(void)
        +	{
        +	engine_table_cleanup(&ecdsa_table);
        +	}
        +
        +int ENGINE_register_ECDSA(ENGINE *e)
        +	{
        +	if(e->ecdsa_meth)
        +		return engine_table_register(&ecdsa_table,
        +				engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_ECDSA()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_ECDSA(e);
        +	}
        +
        +int ENGINE_set_default_ECDSA(ENGINE *e)
        +	{
        +	if(e->ecdsa_meth)
        +		return engine_table_register(&ecdsa_table,
        +				engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_ECDSA(void)
        +	{
        +	return engine_table_select(&ecdsa_table, dummy_nid);
        +	}
        +
        +/* Obtains an ECDSA implementation from an ENGINE functional reference */
        +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e)
        +	{
        +	return e->ecdsa_meth;
        +	}
        +
        +/* Sets an ECDSA implementation in an ENGINE structure */
        +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
        +	{
        +	e->ecdsa_meth = ecdsa_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_pkmeth.c b/vendor/openssl/openssl/crypto/engine/tb_pkmeth.c
        new file mode 100644
        index 000000000..1cdb967f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_pkmeth.c
        @@ -0,0 +1,167 @@
        +/* ====================================================================
        + * Copyright (c) 2006 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 "eng_int.h"
        +#include <openssl/evp.h>
        +
        +/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
        + * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_PKEY_METH_DEBUG */
        +
        +static ENGINE_TABLE *pkey_meth_table = NULL;
        +
        +void ENGINE_unregister_pkey_meths(ENGINE *e)
        +	{
        +	engine_table_unregister(&pkey_meth_table, e);
        +	}
        +
        +static void engine_unregister_all_pkey_meths(void)
        +	{
        +	engine_table_cleanup(&pkey_meth_table);
        +	}
        +
        +int ENGINE_register_pkey_meths(ENGINE *e)
        +	{
        +	if(e->pkey_meths)
        +		{
        +		const int *nids;
        +		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&pkey_meth_table,
        +				engine_unregister_all_pkey_meths, e, nids,
        +					num_nids, 0);
        +		}
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_pkey_meths()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_pkey_meths(e);
        +	}
        +
        +int ENGINE_set_default_pkey_meths(ENGINE *e)
        +	{
        +	if(e->pkey_meths)
        +		{
        +		const int *nids;
        +		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
        +		if(num_nids > 0)
        +			return engine_table_register(&pkey_meth_table,
        +				engine_unregister_all_pkey_meths, e, nids,
        +					num_nids, 1);
        +		}
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references) for a given pkey_meth 'nid' */
        +ENGINE *ENGINE_get_pkey_meth_engine(int nid)
        +	{
        +	return engine_table_select(&pkey_meth_table, nid);
        +	}
        +
        +/* Obtains a pkey_meth implementation from an ENGINE functional reference */
        +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
        +	{
        +	EVP_PKEY_METHOD *ret;
        +	ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
        +	if(!fn || !fn(e, &ret, NULL, nid))
        +		{
        +		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
        +				ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +/* Gets the pkey_meth callback from an ENGINE structure */
        +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
        +	{
        +	return e->pkey_meths;
        +	}
        +
        +/* Sets the pkey_meth callback in an ENGINE structure */
        +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
        +	{
        +	e->pkey_meths = f;
        +	return 1;
        +	}
        +
        +/* Internal function to free up EVP_PKEY_METHOD structures before an
        + * ENGINE is destroyed
        + */
        +
        +void engine_pkey_meths_free(ENGINE *e)
        +	{
        +	int i;
        +	EVP_PKEY_METHOD *pkm;
        +	if (e->pkey_meths)
        +		{
        +		const int *pknids;
        +		int npknids;
        +		npknids = e->pkey_meths(e, NULL, &pknids, 0);
        +		for (i = 0; i < npknids; i++)
        +			{
        +			if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
        +				{
        +				EVP_PKEY_meth_free(pkm);
        +				}
        +			}
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_rand.c b/vendor/openssl/openssl/crypto/engine/tb_rand.c
        new file mode 100644
        index 000000000..f36f67c0f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_rand.c
        @@ -0,0 +1,118 @@
        +/* ====================================================================
        + * 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 "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
        + * used by RAND to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_RAND_DEBUG */
        +
        +static ENGINE_TABLE *rand_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_RAND(ENGINE *e)
        +	{
        +	engine_table_unregister(&rand_table, e);
        +	}
        +
        +static void engine_unregister_all_RAND(void)
        +	{
        +	engine_table_cleanup(&rand_table);
        +	}
        +
        +int ENGINE_register_RAND(ENGINE *e)
        +	{
        +	if(e->rand_meth)
        +		return engine_table_register(&rand_table,
        +				engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_RAND()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_RAND(e);
        +	}
        +
        +int ENGINE_set_default_RAND(ENGINE *e)
        +	{
        +	if(e->rand_meth)
        +		return engine_table_register(&rand_table,
        +				engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_RAND(void)
        +	{
        +	return engine_table_select(&rand_table, dummy_nid);
        +	}
        +
        +/* Obtains an RAND implementation from an ENGINE functional reference */
        +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
        +	{
        +	return e->rand_meth;
        +	}
        +
        +/* Sets an RAND implementation in an ENGINE structure */
        +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
        +	{
        +	e->rand_meth = rand_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_rsa.c b/vendor/openssl/openssl/crypto/engine/tb_rsa.c
        new file mode 100644
        index 000000000..fbc707fd2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_rsa.c
        @@ -0,0 +1,118 @@
        +/* ====================================================================
        + * 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 "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
        + * used by RSA to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_RSA_DEBUG */
        +
        +static ENGINE_TABLE *rsa_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_RSA(ENGINE *e)
        +	{
        +	engine_table_unregister(&rsa_table, e);
        +	}
        +
        +static void engine_unregister_all_RSA(void)
        +	{
        +	engine_table_cleanup(&rsa_table);
        +	}
        +
        +int ENGINE_register_RSA(ENGINE *e)
        +	{
        +	if(e->rsa_meth)
        +		return engine_table_register(&rsa_table,
        +				engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_RSA()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_RSA(e);
        +	}
        +
        +int ENGINE_set_default_RSA(ENGINE *e)
        +	{
        +	if(e->rsa_meth)
        +		return engine_table_register(&rsa_table,
        +				engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_RSA(void)
        +	{
        +	return engine_table_select(&rsa_table, dummy_nid);
        +	}
        +
        +/* Obtains an RSA implementation from an ENGINE functional reference */
        +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
        +	{
        +	return e->rsa_meth;
        +	}
        +
        +/* Sets an RSA implementation in an ENGINE structure */
        +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
        +	{
        +	e->rsa_meth = rsa_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/engine/tb_store.c b/vendor/openssl/openssl/crypto/engine/tb_store.c
        new file mode 100644
        index 000000000..8cc435c93
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/engine/tb_store.c
        @@ -0,0 +1,123 @@
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "eng_int.h"
        +
        +/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
        + * used by STORE to hook in implementation code and cache defaults (etc), will
        + * display brief debugging summaries to stderr with the 'nid'. */
        +/* #define ENGINE_STORE_DEBUG */
        +
        +static ENGINE_TABLE *store_table = NULL;
        +static const int dummy_nid = 1;
        +
        +void ENGINE_unregister_STORE(ENGINE *e)
        +	{
        +	engine_table_unregister(&store_table, e);
        +	}
        +
        +static void engine_unregister_all_STORE(void)
        +	{
        +	engine_table_cleanup(&store_table);
        +	}
        +
        +int ENGINE_register_STORE(ENGINE *e)
        +	{
        +	if(e->store_meth)
        +		return engine_table_register(&store_table,
        +				engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
        +	return 1;
        +	}
        +
        +void ENGINE_register_all_STORE()
        +	{
        +	ENGINE *e;
        +
        +	for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
        +		ENGINE_register_STORE(e);
        +	}
        +
        +/* The following two functions are removed because they're useless. */
        +#if 0
        +int ENGINE_set_default_STORE(ENGINE *e)
        +	{
        +	if(e->store_meth)
        +		return engine_table_register(&store_table,
        +				engine_unregister_all_STORE, e, &dummy_nid, 1, 1);
        +	return 1;
        +	}
        +#endif
        +
        +#if 0
        +/* Exposed API function to get a functional reference from the implementation
        + * table (ie. try to get a functional reference from the tabled structural
        + * references). */
        +ENGINE *ENGINE_get_default_STORE(void)
        +	{
        +	return engine_table_select(&store_table, dummy_nid);
        +	}
        +#endif
        +
        +/* Obtains an STORE implementation from an ENGINE functional reference */
        +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e)
        +	{
        +	return e->store_meth;
        +	}
        +
        +/* Sets an STORE implementation in an ENGINE structure */
        +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
        +	{
        +	e->store_meth = store_meth;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/err/Makefile b/vendor/openssl/openssl/crypto/err/Makefile
        new file mode 100644
        index 000000000..862b23ba1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/err/Makefile
        @@ -0,0 +1,110 @@
        +#
        +# OpenSSL/crypto/err/Makefile
        +#
        +
        +DIR=	err
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=err.c err_all.c err_prn.c
        +LIBOBJ=err.o err_all.o err_prn.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= err.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +err.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +err.o: ../cryptlib.h err.c
        +err_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +err_all.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +err_all.o: ../../include/openssl/cms.h ../../include/openssl/comp.h
        +err_all.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +err_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +err_all.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +err_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +err_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +err_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +err_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
        +err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +err_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem2.h
        +err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +err_all.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +err_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +err_all.o: ../../include/openssl/ts.h ../../include/openssl/ui.h
        +err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +err_all.o: ../../include/openssl/x509v3.h err_all.c
        +err_prn.o: ../../e_os.h ../../include/openssl/bio.h
        +err_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +err_prn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +err_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +err_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +err_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h err_prn.c
        diff --git a/vendor/openssl/openssl/crypto/err/err.c b/vendor/openssl/openssl/crypto/err/err.c
        new file mode 100644
        index 000000000..fcdb24400
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/err/err.c
        @@ -0,0 +1,1138 @@
        +/* crypto/err/err.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 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 <stdio.h>
        +#include <stdarg.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +
        +DECLARE_LHASH_OF(ERR_STRING_DATA);
        +DECLARE_LHASH_OF(ERR_STATE);
        +
        +static void err_load_strings(int lib, ERR_STRING_DATA *str);
        +
        +static void ERR_STATE_free(ERR_STATE *s);
        +#ifndef OPENSSL_NO_ERR
        +static ERR_STRING_DATA ERR_str_libraries[]=
        +	{
        +{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
        +{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
        +{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
        +{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
        +{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
        +{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
        +{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
        +{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
        +{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
        +{ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
        +{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
        +{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
        +{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
        +{ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
        +{ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
        +{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
        +{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
        +{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
        +{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
        +{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
        +{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
        +{ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
        +{ERR_PACK(ERR_LIB_TS,0,0)		,"time stamp routines"},
        +{ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
        +{ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
        +{ERR_PACK(ERR_LIB_FIPS,0,0)		,"FIPS routines"},
        +{ERR_PACK(ERR_LIB_CMS,0,0)		,"CMS routines"},
        +{ERR_PACK(ERR_LIB_HMAC,0,0)		,"HMAC routines"},
        +{0,NULL},
        +	};
        +
        +static ERR_STRING_DATA ERR_str_functs[]=
        +	{
        +	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
        +	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
        +	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
        +	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
        +	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
        +	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
        +	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
        +	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
        +#ifdef OPENSSL_SYS_WINDOWS
        +	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
        +#endif
        +	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
        +	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
        +	{0,NULL},
        +	};
        +
        +static ERR_STRING_DATA ERR_str_reasons[]=
        +	{
        +{ERR_R_SYS_LIB				,"system lib"},
        +{ERR_R_BN_LIB				,"BN lib"},
        +{ERR_R_RSA_LIB				,"RSA lib"},
        +{ERR_R_DH_LIB				,"DH lib"},
        +{ERR_R_EVP_LIB				,"EVP lib"},
        +{ERR_R_BUF_LIB				,"BUF lib"},
        +{ERR_R_OBJ_LIB				,"OBJ lib"},
        +{ERR_R_PEM_LIB				,"PEM lib"},
        +{ERR_R_DSA_LIB				,"DSA lib"},
        +{ERR_R_X509_LIB				,"X509 lib"},
        +{ERR_R_ASN1_LIB				,"ASN1 lib"},
        +{ERR_R_CONF_LIB				,"CONF lib"},
        +{ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
        +{ERR_R_EC_LIB				,"EC lib"},
        +{ERR_R_SSL_LIB				,"SSL lib"},
        +{ERR_R_BIO_LIB				,"BIO lib"},
        +{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
        +{ERR_R_X509V3_LIB			,"X509V3 lib"},
        +{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
        +{ERR_R_RAND_LIB				,"RAND lib"},
        +{ERR_R_DSO_LIB				,"DSO lib"},
        +{ERR_R_ENGINE_LIB			,"ENGINE lib"},
        +{ERR_R_OCSP_LIB				,"OCSP lib"},
        +{ERR_R_TS_LIB				,"TS lib"},
        +
        +{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
        +{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
        +{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
        +{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
        +{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
        +{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
        +
        +{ERR_R_FATAL                            ,"fatal"},
        +{ERR_R_MALLOC_FAILURE			,"malloc failure"},
        +{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
        +{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
        +{ERR_R_INTERNAL_ERROR			,"internal error"},
        +{ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
        +
        +{0,NULL},
        +	};
        +#endif
        +
        +
        +/* Define the predeclared (but externally opaque) "ERR_FNS" type */
        +struct st_ERR_FNS
        +	{
        +	/* Works on the "error_hash" string table */
        +	LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
        +	void (*cb_err_del)(void);
        +	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
        +	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
        +	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
        +	/* Works on the "thread_hash" error-state table */
        +	LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
        +	void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
        +	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
        +	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
        +	void (*cb_thread_del_item)(const ERR_STATE *);
        +	/* Returns the next available error "library" numbers */
        +	int (*cb_get_next_lib)(void);
        +	};
        +
        +/* Predeclarations of the "err_defaults" functions */
        +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
        +static void int_err_del(void);
        +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
        +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
        +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
        +static LHASH_OF(ERR_STATE) *int_thread_get(int create);
        +static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
        +static ERR_STATE *int_thread_get_item(const ERR_STATE *);
        +static ERR_STATE *int_thread_set_item(ERR_STATE *);
        +static void int_thread_del_item(const ERR_STATE *);
        +static int int_err_get_next_lib(void);
        +/* The static ERR_FNS table using these defaults functions */
        +static const ERR_FNS err_defaults =
        +	{
        +	int_err_get,
        +	int_err_del,
        +	int_err_get_item,
        +	int_err_set_item,
        +	int_err_del_item,
        +	int_thread_get,
        +	int_thread_release,
        +	int_thread_get_item,
        +	int_thread_set_item,
        +	int_thread_del_item,
        +	int_err_get_next_lib
        +	};
        +
        +/* The replacable table of ERR_FNS functions we use at run-time */
        +static const ERR_FNS *err_fns = NULL;
        +
        +/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
        +#define ERRFN(a) err_fns->cb_##a
        +
        +/* The internal state used by "err_defaults" - as such, the setting, reading,
        + * creating, and deleting of this data should only be permitted via the
        + * "err_defaults" functions. This way, a linked module can completely defer all
        + * ERR state operation (together with requisite locking) to the implementations
        + * and state in the loading application. */
        +static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
        +static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
        +static int int_thread_hash_references = 0;
        +static int int_err_library_number= ERR_LIB_USER;
        +
        +/* Internal function that checks whether "err_fns" is set and if not, sets it to
        + * the defaults. */
        +static void err_fns_check(void)
        +	{
        +	if (err_fns) return;
        +	
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	if (!err_fns)
        +		err_fns = &err_defaults;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +	}
        +
        +/* API functions to get or set the underlying ERR functions. */
        +
        +const ERR_FNS *ERR_get_implementation(void)
        +	{
        +	err_fns_check();
        +	return err_fns;
        +	}
        +
        +int ERR_set_implementation(const ERR_FNS *fns)
        +	{
        +	int ret = 0;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
        +	 * an error is there?! */
        +	if (!err_fns)
        +		{
        +		err_fns = fns;
        +		ret = 1;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +	return ret;
        +	}
        +
        +/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
        + * internal to the "err_defaults" implementation. */
        +
        +static unsigned long get_error_values(int inc,int top,const char **file,int *line,
        +				      const char **data,int *flags);
        +
        +/* The internal functions used in the "err_defaults" implementation */
        +
        +static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
        +	{
        +	unsigned long ret,l;
        +
        +	l=a->error;
        +	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
        +	return(ret^ret%19*13);
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
        +
        +static int err_string_data_cmp(const ERR_STRING_DATA *a,
        +			       const ERR_STRING_DATA *b)
        +	{
        +	return (int)(a->error - b->error);
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
        +
        +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
        +	{
        +	LHASH_OF(ERR_STRING_DATA) *ret = NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	if (!int_error_hash && create)
        +		{
        +		CRYPTO_push_info("int_err_get (err.c)");
        +		int_error_hash = lh_ERR_STRING_DATA_new();
        +		CRYPTO_pop_info();
        +		}
        +	if (int_error_hash)
        +		ret = int_error_hash;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +
        +	return ret;
        +	}
        +
        +static void int_err_del(void)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	if (int_error_hash)
        +		{
        +		lh_ERR_STRING_DATA_free(int_error_hash);
        +		int_error_hash = NULL;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +	}
        +
        +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
        +	{
        +	ERR_STRING_DATA *p;
        +	LHASH_OF(ERR_STRING_DATA) *hash;
        +
        +	err_fns_check();
        +	hash = ERRFN(err_get)(0);
        +	if (!hash)
        +		return NULL;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
        +	p = lh_ERR_STRING_DATA_retrieve(hash, d);
        +	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
        +
        +	return p;
        +	}
        +
        +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
        +	{
        +	ERR_STRING_DATA *p;
        +	LHASH_OF(ERR_STRING_DATA) *hash;
        +
        +	err_fns_check();
        +	hash = ERRFN(err_get)(1);
        +	if (!hash)
        +		return NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	p = lh_ERR_STRING_DATA_insert(hash, d);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +
        +	return p;
        +	}
        +
        +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
        +	{
        +	ERR_STRING_DATA *p;
        +	LHASH_OF(ERR_STRING_DATA) *hash;
        +
        +	err_fns_check();
        +	hash = ERRFN(err_get)(0);
        +	if (!hash)
        +		return NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	p = lh_ERR_STRING_DATA_delete(hash, d);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +
        +	return p;
        +	}
        +
        +static unsigned long err_state_hash(const ERR_STATE *a)
        +	{
        +	return CRYPTO_THREADID_hash(&a->tid) * 13;
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
        +
        +static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
        +	{
        +	return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
        +
        +static LHASH_OF(ERR_STATE) *int_thread_get(int create)
        +	{
        +	LHASH_OF(ERR_STATE) *ret = NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	if (!int_thread_hash && create)
        +		{
        +		CRYPTO_push_info("int_thread_get (err.c)");
        +		int_thread_hash = lh_ERR_STATE_new();
        +		CRYPTO_pop_info();
        +		}
        +	if (int_thread_hash)
        +		{
        +		int_thread_hash_references++;
        +		ret = int_thread_hash;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +	return ret;
        +	}
        +
        +static void int_thread_release(LHASH_OF(ERR_STATE) **hash)
        +	{
        +	int i;
        +
        +	if (hash == NULL || *hash == NULL)
        +		return;
        +
        +	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
        +
        +#ifdef REF_PRINT
        +	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"int_thread_release, bad reference count\n");
        +		abort(); /* ok */
        +		}
        +#endif
        +	*hash = NULL;
        +	}
        +
        +static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
        +	{
        +	ERR_STATE *p;
        +	LHASH_OF(ERR_STATE) *hash;
        +
        +	err_fns_check();
        +	hash = ERRFN(thread_get)(0);
        +	if (!hash)
        +		return NULL;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
        +	p = lh_ERR_STATE_retrieve(hash, d);
        +	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
        +
        +	ERRFN(thread_release)(&hash);
        +	return p;
        +	}
        +
        +static ERR_STATE *int_thread_set_item(ERR_STATE *d)
        +	{
        +	ERR_STATE *p;
        +	LHASH_OF(ERR_STATE) *hash;
        +
        +	err_fns_check();
        +	hash = ERRFN(thread_get)(1);
        +	if (!hash)
        +		return NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	p = lh_ERR_STATE_insert(hash, d);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +
        +	ERRFN(thread_release)(&hash);
        +	return p;
        +	}
        +
        +static void int_thread_del_item(const ERR_STATE *d)
        +	{
        +	ERR_STATE *p;
        +	LHASH_OF(ERR_STATE) *hash;
        +
        +	err_fns_check();
        +	hash = ERRFN(thread_get)(0);
        +	if (!hash)
        +		return;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	p = lh_ERR_STATE_delete(hash, d);
        +	/* make sure we don't leak memory */
        +	if (int_thread_hash_references == 1
        +	    && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
        +		{
        +		lh_ERR_STATE_free(int_thread_hash);
        +		int_thread_hash = NULL;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +
        +	ERRFN(thread_release)(&hash);
        +	if (p)
        +		ERR_STATE_free(p);
        +	}
        +
        +static int int_err_get_next_lib(void)
        +	{
        +	int ret;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	ret = int_err_library_number++;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +
        +	return ret;
        +	}
        +
        +
        +#ifndef OPENSSL_NO_ERR
        +#define NUM_SYS_STR_REASONS 127
        +#define LEN_SYS_STR_REASON 32
        +
        +static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
        +/* SYS_str_reasons is filled with copies of strerror() results at
        + * initialization.
        + * 'errno' values up to 127 should cover all usual errors,
        + * others will be displayed numerically by ERR_error_string.
        + * It is crucial that we have something for each reason code
        + * that occurs in ERR_str_reasons, or bogus reason strings
        + * will be returned for SYSerr(), which always gets an errno
        + * value and never one of those 'standard' reason codes. */
        +
        +static void build_SYS_str_reasons(void)
        +	{
        +	/* OPENSSL_malloc cannot be used here, use static storage instead */
        +	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
        +	int i;
        +	static int init = 1;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
        +	if (!init)
        +		{
        +		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
        +		return;
        +		}
        +	
        +	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
        +	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
        +	if (!init)
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +		return;
        +		}
        +
        +	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
        +		{
        +		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
        +
        +		str->error = (unsigned long)i;
        +		if (str->string == NULL)
        +			{
        +			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
        +			char *src = strerror(i);
        +			if (src != NULL)
        +				{
        +				strncpy(*dest, src, sizeof *dest);
        +				(*dest)[sizeof *dest - 1] = '\0';
        +				str->string = *dest;
        +				}
        +			}
        +		if (str->string == NULL)
        +			str->string = "unknown";
        +		}
        +
        +	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
        +	 * as required by ERR_load_strings. */
        +
        +	init = 0;
        +	
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
        +	}
        +#endif
        +
        +#define err_clear_data(p,i) \
        +	do { \
        +	if (((p)->err_data[i] != NULL) && \
        +		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
        +		{  \
        +		OPENSSL_free((p)->err_data[i]); \
        +		(p)->err_data[i]=NULL; \
        +		} \
        +	(p)->err_data_flags[i]=0; \
        +	} while(0)
        +
        +#define err_clear(p,i) \
        +	do { \
        +	(p)->err_flags[i]=0; \
        +	(p)->err_buffer[i]=0; \
        +	err_clear_data(p,i); \
        +	(p)->err_file[i]=NULL; \
        +	(p)->err_line[i]= -1; \
        +	} while(0)
        +
        +static void ERR_STATE_free(ERR_STATE *s)
        +	{
        +	int i;
        +
        +	if (s == NULL)
        +	    return;
        +
        +	for (i=0; i<ERR_NUM_ERRORS; i++)
        +		{
        +		err_clear_data(s,i);
        +		}
        +	OPENSSL_free(s);
        +	}
        +
        +void ERR_load_ERR_strings(void)
        +	{
        +	err_fns_check();
        +#ifndef OPENSSL_NO_ERR
        +	err_load_strings(0,ERR_str_libraries);
        +	err_load_strings(0,ERR_str_reasons);
        +	err_load_strings(ERR_LIB_SYS,ERR_str_functs);
        +	build_SYS_str_reasons();
        +	err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
        +#endif
        +	}
        +
        +static void err_load_strings(int lib, ERR_STRING_DATA *str)
        +	{
        +	while (str->error)
        +		{
        +		if (lib)
        +			str->error|=ERR_PACK(lib,0,0);
        +		ERRFN(err_set_item)(str);
        +		str++;
        +		}
        +	}
        +
        +void ERR_load_strings(int lib, ERR_STRING_DATA *str)
        +	{
        +	ERR_load_ERR_strings();
        +	err_load_strings(lib, str);
        +	}
        +
        +void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
        +	{
        +	while (str->error)
        +		{
        +		if (lib)
        +			str->error|=ERR_PACK(lib,0,0);
        +		ERRFN(err_del_item)(str);
        +		str++;
        +		}
        +	}
        +
        +void ERR_free_strings(void)
        +	{
        +	err_fns_check();
        +	ERRFN(err_del)();
        +	}
        +
        +/********************************************************/
        +
        +void ERR_put_error(int lib, int func, int reason, const char *file,
        +	     int line)
        +	{
        +	ERR_STATE *es;
        +
        +#ifdef _OSD_POSIX
        +	/* In the BS2000-OSD POSIX subsystem, the compiler generates
        +	 * path names in the form "*POSIX(/etc/passwd)".
        +	 * This dirty hack strips them to something sensible.
        +	 * @@@ We shouldn't modify a const string, though.
        +	 */
        +	if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
        +		char *end;
        +
        +		/* Skip the "*POSIX(" prefix */
        +		file += sizeof("*POSIX(")-1;
        +		end = &file[strlen(file)-1];
        +		if (*end == ')')
        +			*end = '\0';
        +		/* Optional: use the basename of the path only. */
        +		if ((end = strrchr(file, '/')) != NULL)
        +			file = &end[1];
        +	}
        +#endif
        +	es=ERR_get_state();
        +
        +	es->top=(es->top+1)%ERR_NUM_ERRORS;
        +	if (es->top == es->bottom)
        +		es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
        +	es->err_flags[es->top]=0;
        +	es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
        +	es->err_file[es->top]=file;
        +	es->err_line[es->top]=line;
        +	err_clear_data(es,es->top);
        +	}
        +
        +void ERR_clear_error(void)
        +	{
        +	int i;
        +	ERR_STATE *es;
        +
        +	es=ERR_get_state();
        +
        +	for (i=0; i<ERR_NUM_ERRORS; i++)
        +		{
        +		err_clear(es,i);
        +		}
        +	es->top=es->bottom=0;
        +	}
        +
        +
        +unsigned long ERR_get_error(void)
        +	{ return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
        +
        +unsigned long ERR_get_error_line(const char **file,
        +	     int *line)
        +	{ return(get_error_values(1,0,file,line,NULL,NULL)); }
        +
        +unsigned long ERR_get_error_line_data(const char **file, int *line,
        +	     const char **data, int *flags)
        +	{ return(get_error_values(1,0,file,line,data,flags)); }
        +
        +
        +unsigned long ERR_peek_error(void)
        +	{ return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
        +
        +unsigned long ERR_peek_error_line(const char **file, int *line)
        +	{ return(get_error_values(0,0,file,line,NULL,NULL)); }
        +
        +unsigned long ERR_peek_error_line_data(const char **file, int *line,
        +	     const char **data, int *flags)
        +	{ return(get_error_values(0,0,file,line,data,flags)); }
        +
        +
        +unsigned long ERR_peek_last_error(void)
        +	{ return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
        +
        +unsigned long ERR_peek_last_error_line(const char **file, int *line)
        +	{ return(get_error_values(0,1,file,line,NULL,NULL)); }
        +
        +unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
        +	     const char **data, int *flags)
        +	{ return(get_error_values(0,1,file,line,data,flags)); }
        +
        +
        +static unsigned long get_error_values(int inc, int top, const char **file, int *line,
        +	     const char **data, int *flags)
        +	{	
        +	int i=0;
        +	ERR_STATE *es;
        +	unsigned long ret;
        +
        +	es=ERR_get_state();
        +
        +	if (inc && top)
        +		{
        +		if (file) *file = "";
        +		if (line) *line = 0;
        +		if (data) *data = "";
        +		if (flags) *flags = 0;
        +			
        +		return ERR_R_INTERNAL_ERROR;
        +		}
        +
        +	if (es->bottom == es->top) return 0;
        +	if (top)
        +		i=es->top;			 /* last error */
        +	else
        +		i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
        +
        +	ret=es->err_buffer[i];
        +	if (inc)
        +		{
        +		es->bottom=i;
        +		es->err_buffer[i]=0;
        +		}
        +
        +	if ((file != NULL) && (line != NULL))
        +		{
        +		if (es->err_file[i] == NULL)
        +			{
        +			*file="NA";
        +			if (line != NULL) *line=0;
        +			}
        +		else
        +			{
        +			*file=es->err_file[i];
        +			if (line != NULL) *line=es->err_line[i];
        +			}
        +		}
        +
        +	if (data == NULL)
        +		{
        +		if (inc)
        +			{
        +			err_clear_data(es, i);
        +			}
        +		}
        +	else
        +		{
        +		if (es->err_data[i] == NULL)
        +			{
        +			*data="";
        +			if (flags != NULL) *flags=0;
        +			}
        +		else
        +			{
        +			*data=es->err_data[i];
        +			if (flags != NULL) *flags=es->err_data_flags[i];
        +			}
        +		}
        +	return ret;
        +	}
        +
        +void ERR_error_string_n(unsigned long e, char *buf, size_t len)
        +	{
        +	char lsbuf[64], fsbuf[64], rsbuf[64];
        +	const char *ls,*fs,*rs;
        +	unsigned long l,f,r;
        +
        +	l=ERR_GET_LIB(e);
        +	f=ERR_GET_FUNC(e);
        +	r=ERR_GET_REASON(e);
        +
        +	ls=ERR_lib_error_string(e);
        +	fs=ERR_func_error_string(e);
        +	rs=ERR_reason_error_string(e);
        +
        +	if (ls == NULL) 
        +		BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
        +	if (fs == NULL)
        +		BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
        +	if (rs == NULL)
        +		BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
        +
        +	BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, 
        +		fs?fs:fsbuf, rs?rs:rsbuf);
        +	if (strlen(buf) == len-1)
        +		{
        +		/* output may be truncated; make sure we always have 5 
        +		 * colon-separated fields, i.e. 4 colons ... */
        +#define NUM_COLONS 4
        +		if (len > NUM_COLONS) /* ... if possible */
        +			{
        +			int i;
        +			char *s = buf;
        +			
        +			for (i = 0; i < NUM_COLONS; i++)
        +				{
        +				char *colon = strchr(s, ':');
        +				if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
        +					{
        +					/* set colon no. i at last possible position
        +					 * (buf[len-1] is the terminating 0)*/
        +					colon = &buf[len-1] - NUM_COLONS + i;
        +					*colon = ':';
        +					}
        +				s = colon + 1;
        +				}
        +			}
        +		}
        +	}
        +
        +/* BAD for multi-threading: uses a local buffer if ret == NULL */
        +/* ERR_error_string_n should be used instead for ret != NULL
        + * as ERR_error_string cannot know how large the buffer is */
        +char *ERR_error_string(unsigned long e, char *ret)
        +	{
        +	static char buf[256];
        +
        +	if (ret == NULL) ret=buf;
        +	ERR_error_string_n(e, ret, 256);
        +
        +	return ret;
        +	}
        +
        +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
        +	{
        +	err_fns_check();
        +	return ERRFN(err_get)(0);
        +	}
        +
        +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
        +	{
        +	err_fns_check();
        +	return ERRFN(thread_get)(0);
        +	}
        +
        +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
        +	{
        +	err_fns_check();
        +	ERRFN(thread_release)(hash);
        +	}
        +
        +const char *ERR_lib_error_string(unsigned long e)
        +	{
        +	ERR_STRING_DATA d,*p;
        +	unsigned long l;
        +
        +	err_fns_check();
        +	l=ERR_GET_LIB(e);
        +	d.error=ERR_PACK(l,0,0);
        +	p=ERRFN(err_get_item)(&d);
        +	return((p == NULL)?NULL:p->string);
        +	}
        +
        +const char *ERR_func_error_string(unsigned long e)
        +	{
        +	ERR_STRING_DATA d,*p;
        +	unsigned long l,f;
        +
        +	err_fns_check();
        +	l=ERR_GET_LIB(e);
        +	f=ERR_GET_FUNC(e);
        +	d.error=ERR_PACK(l,f,0);
        +	p=ERRFN(err_get_item)(&d);
        +	return((p == NULL)?NULL:p->string);
        +	}
        +
        +const char *ERR_reason_error_string(unsigned long e)
        +	{
        +	ERR_STRING_DATA d,*p=NULL;
        +	unsigned long l,r;
        +
        +	err_fns_check();
        +	l=ERR_GET_LIB(e);
        +	r=ERR_GET_REASON(e);
        +	d.error=ERR_PACK(l,0,r);
        +	p=ERRFN(err_get_item)(&d);
        +	if (!p)
        +		{
        +		d.error=ERR_PACK(0,0,r);
        +		p=ERRFN(err_get_item)(&d);
        +		}
        +	return((p == NULL)?NULL:p->string);
        +	}
        +
        +void ERR_remove_thread_state(const CRYPTO_THREADID *id)
        +	{
        +	ERR_STATE tmp;
        +
        +	if (id)
        +		CRYPTO_THREADID_cpy(&tmp.tid, id);
        +	else
        +		CRYPTO_THREADID_current(&tmp.tid);
        +	err_fns_check();
        +	/* thread_del_item automatically destroys the LHASH if the number of
        +	 * items reaches zero. */
        +	ERRFN(thread_del_item)(&tmp);
        +	}
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +void ERR_remove_state(unsigned long pid)
        +	{
        +	ERR_remove_thread_state(NULL);
        +	}
        +#endif
        +
        +ERR_STATE *ERR_get_state(void)
        +	{
        +	static ERR_STATE fallback;
        +	ERR_STATE *ret,tmp,*tmpp=NULL;
        +	int i;
        +	CRYPTO_THREADID tid;
        +
        +	err_fns_check();
        +	CRYPTO_THREADID_current(&tid);
        +	CRYPTO_THREADID_cpy(&tmp.tid, &tid);
        +	ret=ERRFN(thread_get_item)(&tmp);
        +
        +	/* ret == the error state, if NULL, make a new one */
        +	if (ret == NULL)
        +		{
        +		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
        +		if (ret == NULL) return(&fallback);
        +		CRYPTO_THREADID_cpy(&ret->tid, &tid);
        +		ret->top=0;
        +		ret->bottom=0;
        +		for (i=0; i<ERR_NUM_ERRORS; i++)
        +			{
        +			ret->err_data[i]=NULL;
        +			ret->err_data_flags[i]=0;
        +			}
        +		tmpp = ERRFN(thread_set_item)(ret);
        +		/* To check if insertion failed, do a get. */
        +		if (ERRFN(thread_get_item)(ret) != ret)
        +			{
        +			ERR_STATE_free(ret); /* could not insert it */
        +			return(&fallback);
        +			}
        +		/* If a race occured in this function and we came second, tmpp
        +		 * is the first one that we just replaced. */
        +		if (tmpp)
        +			ERR_STATE_free(tmpp);
        +		}
        +	return ret;
        +	}
        +
        +int ERR_get_next_error_library(void)
        +	{
        +	err_fns_check();
        +	return ERRFN(get_next_lib)();
        +	}
        +
        +void ERR_set_error_data(char *data, int flags)
        +	{
        +	ERR_STATE *es;
        +	int i;
        +
        +	es=ERR_get_state();
        +
        +	i=es->top;
        +	if (i == 0)
        +		i=ERR_NUM_ERRORS-1;
        +
        +	err_clear_data(es,i);
        +	es->err_data[i]=data;
        +	es->err_data_flags[i]=flags;
        +	}
        +
        +void ERR_add_error_data(int num, ...)
        +	{
        +	va_list args;
        +	va_start(args, num);
        +	ERR_add_error_vdata(num, args);
        +	va_end(args);
        +	}
        +
        +void ERR_add_error_vdata(int num, va_list args)
        +	{
        +	int i,n,s;
        +	char *str,*p,*a;
        +
        +	s=80;
        +	str=OPENSSL_malloc(s+1);
        +	if (str == NULL) return;
        +	str[0]='\0';
        +
        +	n=0;
        +	for (i=0; i<num; i++)
        +		{
        +		a=va_arg(args, char*);
        +		/* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
        +		if (a != NULL)
        +			{
        +			n+=strlen(a);
        +			if (n > s)
        +				{
        +				s=n+20;
        +				p=OPENSSL_realloc(str,s+1);
        +				if (p == NULL)
        +					{
        +					OPENSSL_free(str);
        +					return;
        +					}
        +				else
        +					str=p;
        +				}
        +			BUF_strlcat(str,a,(size_t)s+1);
        +			}
        +		}
        +	ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
        +	}
        +
        +int ERR_set_mark(void)
        +	{
        +	ERR_STATE *es;
        +
        +	es=ERR_get_state();
        +
        +	if (es->bottom == es->top) return 0;
        +	es->err_flags[es->top]|=ERR_FLAG_MARK;
        +	return 1;
        +	}
        +
        +int ERR_pop_to_mark(void)
        +	{
        +	ERR_STATE *es;
        +
        +	es=ERR_get_state();
        +
        +	while(es->bottom != es->top
        +		&& (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
        +		{
        +		err_clear(es,es->top);
        +		es->top-=1;
        +		if (es->top == -1) es->top=ERR_NUM_ERRORS-1;
        +		}
        +		
        +	if (es->bottom == es->top) return 0;
        +	es->err_flags[es->top]&=~ERR_FLAG_MARK;
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/err/err.h b/vendor/openssl/openssl/crypto/err/err.h
        new file mode 100644
        index 000000000..974cc9cc6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/err/err.h
        @@ -0,0 +1,386 @@
        +/* crypto/err/err.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 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_ERR_H
        +#define HEADER_ERR_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +#include <stdio.h>
        +#include <stdlib.h>
        +#endif
        +
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#ifndef OPENSSL_NO_LHASH
        +#include <openssl/lhash.h>
        +#endif
        +
        +#ifdef	__cplusplus
        +extern "C" {
        +#endif
        +
        +#ifndef OPENSSL_NO_ERR
        +#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,d,e)
        +#else
        +#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,NULL,0)
        +#endif
        +
        +#include <errno.h>
        +
        +#define ERR_TXT_MALLOCED	0x01
        +#define ERR_TXT_STRING		0x02
        +
        +#define ERR_FLAG_MARK		0x01
        +
        +#define ERR_NUM_ERRORS	16
        +typedef struct err_state_st
        +	{
        +	CRYPTO_THREADID tid;
        +	int err_flags[ERR_NUM_ERRORS];
        +	unsigned long err_buffer[ERR_NUM_ERRORS];
        +	char *err_data[ERR_NUM_ERRORS];
        +	int err_data_flags[ERR_NUM_ERRORS];
        +	const char *err_file[ERR_NUM_ERRORS];
        +	int err_line[ERR_NUM_ERRORS];
        +	int top,bottom;
        +	} ERR_STATE;
        +
        +/* library */
        +#define ERR_LIB_NONE		1
        +#define ERR_LIB_SYS		2
        +#define ERR_LIB_BN		3
        +#define ERR_LIB_RSA		4
        +#define ERR_LIB_DH		5
        +#define ERR_LIB_EVP		6
        +#define ERR_LIB_BUF		7
        +#define ERR_LIB_OBJ		8
        +#define ERR_LIB_PEM		9
        +#define ERR_LIB_DSA		10
        +#define ERR_LIB_X509		11
        +/* #define ERR_LIB_METH         12 */
        +#define ERR_LIB_ASN1		13
        +#define ERR_LIB_CONF		14
        +#define ERR_LIB_CRYPTO		15
        +#define ERR_LIB_EC		16
        +#define ERR_LIB_SSL		20
        +/* #define ERR_LIB_SSL23        21 */
        +/* #define ERR_LIB_SSL2         22 */
        +/* #define ERR_LIB_SSL3         23 */
        +/* #define ERR_LIB_RSAREF       30 */
        +/* #define ERR_LIB_PROXY        31 */
        +#define ERR_LIB_BIO		32
        +#define ERR_LIB_PKCS7		33
        +#define ERR_LIB_X509V3		34
        +#define ERR_LIB_PKCS12		35
        +#define ERR_LIB_RAND		36
        +#define ERR_LIB_DSO		37
        +#define ERR_LIB_ENGINE		38
        +#define ERR_LIB_OCSP            39
        +#define ERR_LIB_UI              40
        +#define ERR_LIB_COMP            41
        +#define ERR_LIB_ECDSA		42
        +#define ERR_LIB_ECDH		43
        +#define ERR_LIB_STORE           44
        +#define ERR_LIB_FIPS		45
        +#define ERR_LIB_CMS		46
        +#define ERR_LIB_TS		47
        +#define ERR_LIB_HMAC		48
        +#define ERR_LIB_JPAKE		49
        +
        +#define ERR_LIB_USER		128
        +
        +#define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__)
        +#define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__)
        +#define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__)
        +#define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__)
        +#define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__)
        +#define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__)
        +#define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
        +#define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__)
        +#define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__)
        +#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__)
        +#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
        +#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__)
        +#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__)
        +#define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__)
        +#define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__)
        +#define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__)
        +#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__)
        +#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__)
        +#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__)
        +#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__)
        +#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__)
        +#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__)
        +#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__)
        +#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__)
        +#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__)
        +#define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
        +#define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
        +#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
        +#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__)
        +#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
        +#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
        +#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__)
        +#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)
        +
        +/* Borland C seems too stupid to be able to shift and do longs in
        + * the pre-processor :-( */
        +#define ERR_PACK(l,f,r)		(((((unsigned long)l)&0xffL)*0x1000000)| \
        +				((((unsigned long)f)&0xfffL)*0x1000)| \
        +				((((unsigned long)r)&0xfffL)))
        +#define ERR_GET_LIB(l)		(int)((((unsigned long)l)>>24L)&0xffL)
        +#define ERR_GET_FUNC(l)		(int)((((unsigned long)l)>>12L)&0xfffL)
        +#define ERR_GET_REASON(l)	(int)((l)&0xfffL)
        +#define ERR_FATAL_ERROR(l)	(int)((l)&ERR_R_FATAL)
        +
        +
        +/* OS functions */
        +#define SYS_F_FOPEN		1
        +#define SYS_F_CONNECT		2
        +#define SYS_F_GETSERVBYNAME	3
        +#define SYS_F_SOCKET		4
        +#define SYS_F_IOCTLSOCKET	5
        +#define SYS_F_BIND		6
        +#define SYS_F_LISTEN		7
        +#define SYS_F_ACCEPT		8
        +#define SYS_F_WSASTARTUP	9 /* Winsock stuff */
        +#define SYS_F_OPENDIR		10
        +#define SYS_F_FREAD		11
        +
        +
        +/* reasons */
        +#define ERR_R_SYS_LIB	ERR_LIB_SYS       /* 2 */
        +#define ERR_R_BN_LIB	ERR_LIB_BN        /* 3 */
        +#define ERR_R_RSA_LIB	ERR_LIB_RSA       /* 4 */
        +#define ERR_R_DH_LIB	ERR_LIB_DH        /* 5 */
        +#define ERR_R_EVP_LIB	ERR_LIB_EVP       /* 6 */
        +#define ERR_R_BUF_LIB	ERR_LIB_BUF       /* 7 */
        +#define ERR_R_OBJ_LIB	ERR_LIB_OBJ       /* 8 */
        +#define ERR_R_PEM_LIB	ERR_LIB_PEM       /* 9 */
        +#define ERR_R_DSA_LIB	ERR_LIB_DSA      /* 10 */
        +#define ERR_R_X509_LIB	ERR_LIB_X509     /* 11 */
        +#define ERR_R_ASN1_LIB	ERR_LIB_ASN1     /* 13 */
        +#define ERR_R_CONF_LIB	ERR_LIB_CONF     /* 14 */
        +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO  /* 15 */
        +#define ERR_R_EC_LIB	ERR_LIB_EC       /* 16 */
        +#define ERR_R_SSL_LIB	ERR_LIB_SSL      /* 20 */
        +#define ERR_R_BIO_LIB	ERR_LIB_BIO      /* 32 */
        +#define ERR_R_PKCS7_LIB	ERR_LIB_PKCS7    /* 33 */
        +#define ERR_R_X509V3_LIB ERR_LIB_X509V3  /* 34 */
        +#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12  /* 35 */
        +#define ERR_R_RAND_LIB	ERR_LIB_RAND     /* 36 */
        +#define ERR_R_DSO_LIB	ERR_LIB_DSO      /* 37 */
        +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE  /* 38 */
        +#define ERR_R_OCSP_LIB  ERR_LIB_OCSP     /* 39 */
        +#define ERR_R_UI_LIB    ERR_LIB_UI       /* 40 */
        +#define ERR_R_COMP_LIB	ERR_LIB_COMP     /* 41 */
        +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA	 /* 42 */
        +#define ERR_R_ECDH_LIB  ERR_LIB_ECDH	 /* 43 */
        +#define ERR_R_STORE_LIB ERR_LIB_STORE    /* 44 */
        +#define ERR_R_TS_LIB	ERR_LIB_TS       /* 45 */
        +
        +#define ERR_R_NESTED_ASN1_ERROR			58
        +#define ERR_R_BAD_ASN1_OBJECT_HEADER		59
        +#define ERR_R_BAD_GET_ASN1_OBJECT_CALL		60
        +#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE	61
        +#define ERR_R_ASN1_LENGTH_MISMATCH		62
        +#define ERR_R_MISSING_ASN1_EOS			63
        +
        +/* fatal error */
        +#define ERR_R_FATAL				64
        +#define	ERR_R_MALLOC_FAILURE			(1|ERR_R_FATAL)
        +#define	ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	(2|ERR_R_FATAL)
        +#define	ERR_R_PASSED_NULL_PARAMETER		(3|ERR_R_FATAL)
        +#define	ERR_R_INTERNAL_ERROR			(4|ERR_R_FATAL)
        +#define	ERR_R_DISABLED				(5|ERR_R_FATAL)
        +
        +/* 99 is the maximum possible ERR_R_... code, higher values
        + * are reserved for the individual libraries */
        +
        +
        +typedef struct ERR_string_data_st
        +	{
        +	unsigned long error;
        +	const char *string;
        +	} ERR_STRING_DATA;
        +
        +void ERR_put_error(int lib, int func,int reason,const char *file,int line);
        +void ERR_set_error_data(char *data,int flags);
        +
        +unsigned long ERR_get_error(void);
        +unsigned long ERR_get_error_line(const char **file,int *line);
        +unsigned long ERR_get_error_line_data(const char **file,int *line,
        +				      const char **data, int *flags);
        +unsigned long ERR_peek_error(void);
        +unsigned long ERR_peek_error_line(const char **file,int *line);
        +unsigned long ERR_peek_error_line_data(const char **file,int *line,
        +				       const char **data,int *flags);
        +unsigned long ERR_peek_last_error(void);
        +unsigned long ERR_peek_last_error_line(const char **file,int *line);
        +unsigned long ERR_peek_last_error_line_data(const char **file,int *line,
        +				       const char **data,int *flags);
        +void ERR_clear_error(void );
        +char *ERR_error_string(unsigned long e,char *buf);
        +void ERR_error_string_n(unsigned long e, char *buf, size_t len);
        +const char *ERR_lib_error_string(unsigned long e);
        +const char *ERR_func_error_string(unsigned long e);
        +const char *ERR_reason_error_string(unsigned long e);
        +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
        +			 void *u);
        +#ifndef OPENSSL_NO_FP_API
        +void ERR_print_errors_fp(FILE *fp);
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +void ERR_print_errors(BIO *bp);
        +#endif
        +void ERR_add_error_data(int num, ...);
        +void ERR_add_error_vdata(int num, va_list args);
        +void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
        +void ERR_unload_strings(int lib,ERR_STRING_DATA str[]);
        +void ERR_load_ERR_strings(void);
        +void ERR_load_crypto_strings(void);
        +void ERR_free_strings(void);
        +
        +void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
        +#ifndef OPENSSL_NO_DEPRECATED
        +void ERR_remove_state(unsigned long pid); /* if zero we look it up */
        +#endif
        +ERR_STATE *ERR_get_state(void);
        +
        +#ifndef OPENSSL_NO_LHASH
        +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
        +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
        +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
        +#endif
        +
        +int ERR_get_next_error_library(void);
        +
        +int ERR_set_mark(void);
        +int ERR_pop_to_mark(void);
        +
        +/* Already defined in ossl_typ.h */
        +/* typedef struct st_ERR_FNS ERR_FNS; */
        +/* An application can use this function and provide the return value to loaded
        + * modules that should use the application's ERR state/functionality */
        +const ERR_FNS *ERR_get_implementation(void);
        +/* A loaded module should call this function prior to any ERR operations using
        + * the application's "ERR_FNS". */
        +int ERR_set_implementation(const ERR_FNS *fns);
        +
        +#ifdef	__cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/err/err_all.c b/vendor/openssl/openssl/crypto/err/err_all.c
        new file mode 100644
        index 000000000..8eb547d98
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/err/err_all.c
        @@ -0,0 +1,168 @@
        +/* crypto/err/err_all.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/asn1.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_EC
        +#include <openssl/ec.h>
        +#endif
        +#include <openssl/buffer.h>
        +#include <openssl/bio.h>
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +#include <openssl/ecdsa.h>
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +#include <openssl/ecdh.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/pem2.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/conf.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/rand.h>
        +#include <openssl/dso.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/ui.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/err.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +#include <openssl/ts.h>
        +#ifndef OPENSSL_NO_CMS
        +#include <openssl/cms.h>
        +#endif
        +#ifndef OPENSSL_NO_JPAKE
        +#include <openssl/jpake.h>
        +#endif
        +
        +void ERR_load_crypto_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +	ERR_load_ERR_strings(); /* include error strings for SYSerr */
        +	ERR_load_BN_strings();
        +#ifndef OPENSSL_NO_RSA
        +	ERR_load_RSA_strings();
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	ERR_load_DH_strings();
        +#endif
        +	ERR_load_EVP_strings();
        +	ERR_load_BUF_strings();
        +	ERR_load_OBJ_strings();
        +	ERR_load_PEM_strings();
        +#ifndef OPENSSL_NO_DSA
        +	ERR_load_DSA_strings();
        +#endif
        +	ERR_load_X509_strings();
        +	ERR_load_ASN1_strings();
        +	ERR_load_CONF_strings();
        +	ERR_load_CRYPTO_strings();
        +#ifndef OPENSSL_NO_COMP
        +	ERR_load_COMP_strings();
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	ERR_load_EC_strings();
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	ERR_load_ECDSA_strings();
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	ERR_load_ECDH_strings();
        +#endif
        +	/* skip ERR_load_SSL_strings() because it is not in this library */
        +	ERR_load_BIO_strings();
        +	ERR_load_PKCS7_strings();	
        +	ERR_load_X509V3_strings();
        +	ERR_load_PKCS12_strings();
        +	ERR_load_RAND_strings();
        +	ERR_load_DSO_strings();
        +	ERR_load_TS_strings();
        +#ifndef OPENSSL_NO_ENGINE
        +	ERR_load_ENGINE_strings();
        +#endif
        +	ERR_load_OCSP_strings();
        +	ERR_load_UI_strings();
        +#ifdef OPENSSL_FIPS
        +	ERR_load_FIPS_strings();
        +#endif
        +#ifndef OPENSSL_NO_CMS
        +	ERR_load_CMS_strings();
        +#endif
        +#ifndef OPENSSL_NO_JPAKE
        +	ERR_load_JPAKE_strings();
        +#endif
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/err/err_prn.c b/vendor/openssl/openssl/crypto/err/err_prn.c
        new file mode 100644
        index 000000000..a0168ac8e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/err/err_prn.c
        @@ -0,0 +1,114 @@
        +/* crypto/err/err_prn.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/err.h>
        +
        +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
        +			 void *u)
        +	{
        +	unsigned long l;
        +	char buf[256];
        +	char buf2[4096];
        +	const char *file,*data;
        +	int line,flags;
        +	unsigned long es;
        +	CRYPTO_THREADID cur;
        +
        +	CRYPTO_THREADID_current(&cur);
        +	es=CRYPTO_THREADID_hash(&cur);
        +	while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
        +		{
        +		ERR_error_string_n(l, buf, sizeof buf);
        +		BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf,
        +			file, line, (flags & ERR_TXT_STRING) ? data : "");
        +		if (cb(buf2, strlen(buf2), u) <= 0)
        +			break; /* abort outputting the error report */
        +		}
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +static int print_fp(const char *str, size_t len, void *fp)
        +	{
        +	BIO bio;
        +
        +	BIO_set(&bio,BIO_s_file());
        +	BIO_set_fp(&bio,fp,BIO_NOCLOSE);
        +
        +	return BIO_printf(&bio, "%s", str);
        +	}
        +void ERR_print_errors_fp(FILE *fp)
        +	{
        +	ERR_print_errors_cb(print_fp, fp);
        +	}
        +#endif
        +
        +static int print_bio(const char *str, size_t len, void *bp)
        +	{
        +	return BIO_write((BIO *)bp, str, len);
        +	}
        +void ERR_print_errors(BIO *bp)
        +	{
        +	ERR_print_errors_cb(print_bio, bp);
        +	}
        +
        +	
        diff --git a/vendor/openssl/openssl/crypto/err/openssl.ec b/vendor/openssl/openssl/crypto/err/openssl.ec
        new file mode 100644
        index 000000000..e0554b434
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/err/openssl.ec
        @@ -0,0 +1,96 @@
        +# crypto/err/openssl.ec
        +
        +# configuration file for util/mkerr.pl
        +
        +# files that may have to be rewritten by util/mkerr.pl
        +L ERR		NONE				NONE
        +L BN		crypto/bn/bn.h			crypto/bn/bn_err.c
        +L RSA		crypto/rsa/rsa.h		crypto/rsa/rsa_err.c
        +L DH		crypto/dh/dh.h			crypto/dh/dh_err.c
        +L EVP		crypto/evp/evp.h		crypto/evp/evp_err.c
        +L BUF		crypto/buffer/buffer.h		crypto/buffer/buf_err.c
        +L OBJ		crypto/objects/objects.h	crypto/objects/obj_err.c
        +L PEM		crypto/pem/pem.h		crypto/pem/pem_err.c
        +L DSA		crypto/dsa/dsa.h		crypto/dsa/dsa_err.c
        +L X509		crypto/x509/x509.h		crypto/x509/x509_err.c
        +L ASN1		crypto/asn1/asn1.h		crypto/asn1/asn1_err.c
        +L CONF		crypto/conf/conf.h		crypto/conf/conf_err.c
        +L CRYPTO	crypto/crypto.h			crypto/cpt_err.c
        +L EC		crypto/ec/ec.h			crypto/ec/ec_err.c
        +L SSL		ssl/ssl.h			ssl/ssl_err.c
        +L BIO		crypto/bio/bio.h		crypto/bio/bio_err.c
        +L PKCS7		crypto/pkcs7/pkcs7.h		crypto/pkcs7/pkcs7err.c
        +L X509V3	crypto/x509v3/x509v3.h		crypto/x509v3/v3err.c
        +L PKCS12	crypto/pkcs12/pkcs12.h		crypto/pkcs12/pk12err.c
        +L RAND		crypto/rand/rand.h		crypto/rand/rand_err.c
        +L DSO		crypto/dso/dso.h		crypto/dso/dso_err.c
        +L ENGINE	crypto/engine/engine.h		crypto/engine/eng_err.c
        +L OCSP		crypto/ocsp/ocsp.h		crypto/ocsp/ocsp_err.c
        +L UI		crypto/ui/ui.h			crypto/ui/ui_err.c
        +L COMP		crypto/comp/comp.h		crypto/comp/comp_err.c
        +L ECDSA		crypto/ecdsa/ecdsa.h		crypto/ecdsa/ecs_err.c
        +L ECDH		crypto/ecdh/ecdh.h		crypto/ecdh/ech_err.c
        +L STORE		crypto/store/store.h		crypto/store/str_err.c
        +L TS		crypto/ts/ts.h			crypto/ts/ts_err.c
        +L HMAC		crypto/hmac/hmac.h		crypto/hmac/hmac_err.c
        +L CMS		crypto/cms/cms.h		crypto/cms/cms_err.c
        +L JPAKE		crypto/jpake/jpake.h		crypto/jpake/jpake_err.c
        +
        +# additional header files to be scanned for function names
        +L NONE		crypto/x509/x509_vfy.h		NONE
        +L NONE		crypto/ec/ec_lcl.h		NONE
        +L NONE		crypto/asn1/asn_lcl.h		NONE
        +L NONE		crypto/cms/cms_lcl.h		NONE
        +
        +
        +F RSAREF_F_RSA_BN2BIN
        +F RSAREF_F_RSA_PRIVATE_DECRYPT
        +F RSAREF_F_RSA_PRIVATE_ENCRYPT
        +F RSAREF_F_RSA_PUBLIC_DECRYPT
        +F RSAREF_F_RSA_PUBLIC_ENCRYPT
        +#F SSL_F_CLIENT_CERTIFICATE
        +
        +R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		1010
        +R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC		1020
        +R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		1021
        +R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		1022
        +R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE	1030
        +R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE		1040
        +R SSL_R_SSLV3_ALERT_NO_CERTIFICATE		1041
        +R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		1042
        +R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE	1043
        +R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED		1044
        +R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED		1045
        +R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN		1046
        +R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER		1047
        +R SSL_R_TLSV1_ALERT_UNKNOWN_CA			1048
        +R SSL_R_TLSV1_ALERT_ACCESS_DENIED		1049
        +R SSL_R_TLSV1_ALERT_DECODE_ERROR		1050
        +R SSL_R_TLSV1_ALERT_DECRYPT_ERROR		1051
        +R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		1060
        +R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		1070
        +R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY	1071
        +R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
        +R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
        +R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
        +R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110
        +R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		1111
        +R SSL_R_TLSV1_UNRECOGNIZED_NAME			1112
        +R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	1113
        +R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE	1114
        +
        +R RSAREF_R_CONTENT_ENCODING			0x0400
        +R RSAREF_R_DATA					0x0401
        +R RSAREF_R_DIGEST_ALGORITHM			0x0402
        +R RSAREF_R_ENCODING				0x0403
        +R RSAREF_R_KEY					0x0404
        +R RSAREF_R_KEY_ENCODING				0x0405
        +R RSAREF_R_LEN					0x0406
        +R RSAREF_R_MODULUS_LEN				0x0407
        +R RSAREF_R_NEED_RANDOM				0x0408
        +R RSAREF_R_PRIVATE_KEY				0x0409
        +R RSAREF_R_PUBLIC_KEY				0x040a
        +R RSAREF_R_SIGNATURE				0x040b
        +R RSAREF_R_SIGNATURE_ENCODING			0x040c
        +R RSAREF_R_ENCRYPTION_ALGORITHM			0x040d
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/Makefile b/vendor/openssl/openssl/crypto/evp/Makefile
        new file mode 100644
        index 000000000..1e46cebf5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/Makefile
        @@ -0,0 +1,776 @@
        +#
        +# OpenSSL/crypto/evp/Makefile
        +#
        +
        +DIR=	evp
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=evp_test.c
        +TESTDATA=evptests.txt
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c evp_cnf.c \
        +	e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
        +	e_rc4.c e_aes.c names.c e_seed.c \
        +	e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
        +	m_null.c m_md2.c m_md4.c m_md5.c m_sha.c m_sha1.c m_wp.c \
        +	m_dss.c m_dss1.c m_mdc2.c m_ripemd.c m_ecdsa.c\
        +	p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
        +	bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
        +	c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
        +	evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
        +	e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c evp_fips.c	\
        +	e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c
        +
        +LIBOBJ=	encode.o digest.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \
        +	e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\
        +	e_rc4.o e_aes.o names.o e_seed.o \
        +	e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o \
        +	m_null.o m_md2.o m_md4.o m_md5.o m_sha.o m_sha1.o m_wp.o \
        +	m_dss.o m_dss1.o m_mdc2.o m_ripemd.o m_ecdsa.o\
        +	p_open.o p_seal.o p_sign.o p_verify.o p_lib.o p_enc.o p_dec.o \
        +	bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \
        +	c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
        +	evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \
        +	e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o evp_fips.o \
        +	e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= evp.h
        +HEADER=	evp_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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	[ ! -f $(TESTDATA) ] || cp $(TESTDATA) ../../test
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +bio_b64.o: ../../e_os.h ../../include/openssl/asn1.h
        +bio_b64.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +bio_b64.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bio_b64.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +bio_b64.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +bio_b64.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +bio_b64.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_b64.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_b64.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_b64.c
        +bio_enc.o: ../../e_os.h ../../include/openssl/asn1.h
        +bio_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +bio_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bio_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +bio_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +bio_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +bio_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +bio_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_enc.c
        +bio_md.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +bio_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bio_md.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bio_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +bio_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +bio_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +bio_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +bio_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +bio_md.o: ../cryptlib.h bio_md.c
        +bio_ok.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +bio_ok.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +bio_ok.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +bio_ok.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +bio_ok.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +bio_ok.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +bio_ok.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +bio_ok.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_ok.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_ok.c
        +c_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +c_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +c_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +c_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +c_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +c_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +c_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +c_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +c_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +c_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +c_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +c_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +c_all.o: ../cryptlib.h c_all.c
        +c_allc.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +c_allc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +c_allc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +c_allc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +c_allc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +c_allc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +c_allc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +c_allc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +c_allc.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +c_allc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +c_allc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +c_allc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +c_allc.o: ../cryptlib.h c_allc.c
        +c_alld.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +c_alld.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +c_alld.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +c_alld.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +c_alld.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +c_alld.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +c_alld.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +c_alld.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +c_alld.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +c_alld.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +c_alld.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +c_alld.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +c_alld.o: ../cryptlib.h c_alld.c
        +digest.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +digest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +digest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +digest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +digest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +digest.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +digest.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +digest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +digest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +digest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +digest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +digest.o: ../cryptlib.h digest.c
        +e_aes.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
        +e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_aes.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_aes.o: ../../include/openssl/modes.h ../../include/openssl/obj_mac.h
        +e_aes.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +e_aes.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_aes.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +e_aes.o: ../modes/modes_lcl.h e_aes.c evp_locl.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/bio.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/crypto.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/e_os2.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/evp.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/obj_mac.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/objects.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/opensslconf.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/opensslv.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/ossl_typ.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/safestack.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/sha.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/stack.h
        +e_aes_cbc_hmac_sha1.o: ../../include/openssl/symhacks.h e_aes_cbc_hmac_sha1.c
        +e_aes_cbc_hmac_sha1.o: evp_locl.h
        +e_bf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_bf.o: ../../include/openssl/blowfish.h ../../include/openssl/buffer.h
        +e_bf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +e_bf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +e_bf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +e_bf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +e_bf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_bf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_bf.o: ../../include/openssl/symhacks.h ../cryptlib.h e_bf.c evp_locl.h
        +e_camellia.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_camellia.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
        +e_camellia.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_camellia.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_camellia.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +e_camellia.o: ../../include/openssl/opensslconf.h
        +e_camellia.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_camellia.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_camellia.o: ../../include/openssl/symhacks.h e_camellia.c evp_locl.h
        +e_cast.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_cast.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
        +e_cast.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +e_cast.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +e_cast.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +e_cast.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +e_cast.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_cast.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_cast.o: ../../include/openssl/symhacks.h ../cryptlib.h e_cast.c evp_locl.h
        +e_des.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_des.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_des.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +e_des.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_des.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_des.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +e_des.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +e_des.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +e_des.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_des.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +e_des.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_des.c evp_locl.h
        +e_des3.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_des3.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_des3.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +e_des3.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_des3.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_des3.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +e_des3.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +e_des3.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +e_des3.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_des3.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +e_des3.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_des3.c evp_locl.h
        +e_idea.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_idea.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_idea.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_idea.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
        +e_idea.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +e_idea.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +e_idea.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_idea.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_idea.o: ../../include/openssl/symhacks.h ../cryptlib.h e_idea.c evp_locl.h
        +e_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_null.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_null.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +e_null.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +e_null.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +e_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +e_null.o: ../cryptlib.h e_null.c
        +e_old.o: e_old.c
        +e_rc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_rc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_rc2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_rc2.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_rc2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +e_rc2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +e_rc2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc2.h
        +e_rc2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_rc2.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc2.c evp_locl.h
        +e_rc4.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_rc4.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_rc4.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_rc4.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +e_rc4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +e_rc4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +e_rc4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
        +e_rc4.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_rc4.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc4.c evp_locl.h
        +e_rc4_hmac_md5.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_rc4_hmac_md5.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +e_rc4_hmac_md5.o: ../../include/openssl/evp.h ../../include/openssl/md5.h
        +e_rc4_hmac_md5.o: ../../include/openssl/obj_mac.h
        +e_rc4_hmac_md5.o: ../../include/openssl/objects.h
        +e_rc4_hmac_md5.o: ../../include/openssl/opensslconf.h
        +e_rc4_hmac_md5.o: ../../include/openssl/opensslv.h
        +e_rc4_hmac_md5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
        +e_rc4_hmac_md5.o: ../../include/openssl/safestack.h
        +e_rc4_hmac_md5.o: ../../include/openssl/stack.h
        +e_rc4_hmac_md5.o: ../../include/openssl/symhacks.h e_rc4_hmac_md5.c
        +e_rc5.o: ../../e_os.h ../../include/openssl/bio.h
        +e_rc5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +e_rc5.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +e_rc5.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +e_rc5.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_rc5.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_rc5.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc5.c
        +e_seed.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +e_seed.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +e_seed.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +e_seed.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +e_seed.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +e_seed.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_seed.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
        +e_seed.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +e_seed.o: e_seed.c evp_locl.h
        +e_xcbc_d.o: ../../e_os.h ../../include/openssl/asn1.h
        +e_xcbc_d.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +e_xcbc_d.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
        +e_xcbc_d.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +e_xcbc_d.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +e_xcbc_d.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +e_xcbc_d.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +e_xcbc_d.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +e_xcbc_d.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +e_xcbc_d.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +e_xcbc_d.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_xcbc_d.c
        +e_xcbc_d.o: evp_locl.h
        +encode.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +encode.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +encode.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +encode.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +encode.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +encode.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +encode.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +encode.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +encode.o: ../cryptlib.h encode.c
        +evp_acnf.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_acnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_acnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +evp_acnf.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +evp_acnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +evp_acnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +evp_acnf.o: ../../include/openssl/opensslconf.h
        +evp_acnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_acnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +evp_acnf.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_acnf.c
        +evp_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +evp_cnf.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
        +evp_cnf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +evp_cnf.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +evp_cnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +evp_cnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +evp_cnf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +evp_cnf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +evp_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +evp_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +evp_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +evp_cnf.o: ../../include/openssl/x509v3.h ../cryptlib.h evp_cnf.c
        +evp_enc.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_enc.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +evp_enc.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +evp_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +evp_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +evp_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +evp_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +evp_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
        +evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +evp_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +evp_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +evp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +evp_err.o: ../../include/openssl/symhacks.h evp_err.c
        +evp_fips.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +evp_fips.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_fips.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h
        +evp_fips.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +evp_fips.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_fips.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +evp_fips.o: ../../include/openssl/symhacks.h evp_fips.c
        +evp_key.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_key.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +evp_key.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +evp_key.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +evp_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +evp_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +evp_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +evp_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +evp_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +evp_key.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
        +evp_key.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_key.c
        +evp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +evp_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +evp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +evp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +evp_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_lib.c
        +evp_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_pbe.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_pbe.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_pbe.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +evp_pbe.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +evp_pbe.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +evp_pbe.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +evp_pbe.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +evp_pbe.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
        +evp_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +evp_pbe.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +evp_pbe.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +evp_pbe.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h evp_pbe.c
        +evp_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +evp_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +evp_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +evp_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +evp_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +evp_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +evp_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +evp_pkey.o: ../../include/openssl/opensslconf.h
        +evp_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +evp_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +evp_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +evp_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +evp_pkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +evp_pkey.o: ../asn1/asn1_locl.h ../cryptlib.h evp_pkey.c
        +m_dss.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_dss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_dss.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +m_dss.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_dss.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +m_dss.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +m_dss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_dss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +m_dss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +m_dss.o: ../cryptlib.h m_dss.c
        +m_dss1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_dss1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_dss1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +m_dss1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_dss1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +m_dss1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +m_dss1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_dss1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +m_dss1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +m_dss1.o: ../cryptlib.h m_dss1.c
        +m_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
        +m_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +m_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +m_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +m_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +m_ecdsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +m_ecdsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_ecdsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +m_ecdsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +m_ecdsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +m_ecdsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +m_ecdsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +m_ecdsa.o: ../cryptlib.h m_ecdsa.c
        +m_md2.o: ../../e_os.h ../../include/openssl/bio.h
        +m_md2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_md2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +m_md2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +m_md2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_md2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +m_md2.o: ../../include/openssl/symhacks.h ../cryptlib.h m_md2.c
        +m_md4.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_md4.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_md4.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +m_md4.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +m_md4.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_md4.o: ../../include/openssl/lhash.h ../../include/openssl/md4.h
        +m_md4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_md4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +m_md4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +m_md4.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +m_md4.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_md4.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +m_md4.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_md4.c
        +m_md5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_md5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_md5.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +m_md5.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +m_md5.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_md5.o: ../../include/openssl/lhash.h ../../include/openssl/md5.h
        +m_md5.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_md5.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +m_md5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +m_md5.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +m_md5.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_md5.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +m_md5.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_md5.c
        +m_mdc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_mdc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_mdc2.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +m_mdc2.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +m_mdc2.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +m_mdc2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_mdc2.o: ../../include/openssl/lhash.h ../../include/openssl/mdc2.h
        +m_mdc2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_mdc2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +m_mdc2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +m_mdc2.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +m_mdc2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_mdc2.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +m_mdc2.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
        +m_mdc2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_mdc2.c
        +m_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_null.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +m_null.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +m_null.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_null.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +m_null.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +m_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_null.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +m_null.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_null.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +m_null.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_null.c
        +m_ripemd.o: ../../e_os.h ../../include/openssl/asn1.h
        +m_ripemd.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +m_ripemd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +m_ripemd.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +m_ripemd.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +m_ripemd.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +m_ripemd.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_ripemd.o: ../../include/openssl/opensslconf.h
        +m_ripemd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_ripemd.o: ../../include/openssl/pkcs7.h ../../include/openssl/ripemd.h
        +m_ripemd.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +m_ripemd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_ripemd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +m_ripemd.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h
        +m_ripemd.o: m_ripemd.c
        +m_sha.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_sha.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_sha.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +m_sha.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +m_sha.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_sha.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +m_sha.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +m_sha.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_sha.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +m_sha.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +m_sha.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +m_sha.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +m_sha.o: ../cryptlib.h evp_locl.h m_sha.c
        +m_sha1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_sha1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +m_sha1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +m_sha1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_sha1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +m_sha1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
        +m_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +m_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +m_sha1.o: ../cryptlib.h m_sha1.c
        +m_sigver.o: ../../e_os.h ../../include/openssl/asn1.h
        +m_sigver.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +m_sigver.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +m_sigver.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +m_sigver.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +m_sigver.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +m_sigver.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +m_sigver.o: ../../include/openssl/opensslconf.h
        +m_sigver.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_sigver.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +m_sigver.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_sigver.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +m_sigver.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h
        +m_sigver.o: m_sigver.c
        +m_wp.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +m_wp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +m_wp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +m_wp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +m_wp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +m_wp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +m_wp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +m_wp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +m_wp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +m_wp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +m_wp.o: ../../include/openssl/symhacks.h ../../include/openssl/whrlpool.h
        +m_wp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +m_wp.o: ../cryptlib.h evp_locl.h m_wp.c
        +names.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +names.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +names.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +names.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +names.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +names.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +names.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +names.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +names.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +names.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +names.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +names.o: ../../include/openssl/x509_vfy.h ../cryptlib.h names.c
        +p5_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
        +p5_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p5_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p5_crpt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p5_crpt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p5_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p5_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p5_crpt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +p5_crpt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +p5_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p5_crpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p5_crpt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p5_crpt.o: ../cryptlib.h p5_crpt.c
        +p5_crpt2.o: ../../e_os.h ../../include/openssl/asn1.h
        +p5_crpt2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p5_crpt2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p5_crpt2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p5_crpt2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p5_crpt2.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
        +p5_crpt2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p5_crpt2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p5_crpt2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p5_crpt2.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p5_crpt2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p5_crpt2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p5_crpt2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h
        +p5_crpt2.o: p5_crpt2.c
        +p_dec.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +p_dec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p_dec.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p_dec.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p_dec.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p_dec.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p_dec.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_dec.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +p_dec.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +p_dec.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p_dec.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p_dec.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_dec.c
        +p_enc.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +p_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p_enc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +p_enc.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +p_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_enc.c
        +p_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +p_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
        +p_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +p_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +p_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +p_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +p_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +p_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p_lib.o: ../asn1/asn1_locl.h ../cryptlib.h p_lib.c
        +p_open.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +p_open.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p_open.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p_open.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p_open.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p_open.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p_open.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p_open.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_open.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +p_open.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p_open.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p_open.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p_open.o: ../cryptlib.h p_open.c
        +p_seal.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +p_seal.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p_seal.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p_seal.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p_seal.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p_seal.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p_seal.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p_seal.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_seal.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +p_seal.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +p_seal.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p_seal.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p_seal.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_seal.c
        +p_sign.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +p_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p_sign.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_sign.c
        +p_verify.o: ../../e_os.h ../../include/openssl/asn1.h
        +p_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p_verify.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p_verify.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p_verify.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p_verify.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p_verify.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p_verify.o: ../../include/openssl/opensslconf.h
        +p_verify.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p_verify.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_verify.c
        +pmeth_fn.o: ../../e_os.h ../../include/openssl/asn1.h
        +pmeth_fn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pmeth_fn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pmeth_fn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pmeth_fn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pmeth_fn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pmeth_fn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pmeth_fn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +pmeth_fn.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_locl.h
        +pmeth_fn.o: pmeth_fn.c
        +pmeth_gn.o: ../../e_os.h ../../include/openssl/asn1.h
        +pmeth_gn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +pmeth_gn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +pmeth_gn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +pmeth_gn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pmeth_gn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pmeth_gn.o: ../../include/openssl/opensslconf.h
        +pmeth_gn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pmeth_gn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +pmeth_gn.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_locl.h
        +pmeth_gn.o: pmeth_gn.c
        +pmeth_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +pmeth_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pmeth_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pmeth_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pmeth_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +pmeth_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pmeth_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pmeth_lib.o: ../../include/openssl/objects.h
        +pmeth_lib.o: ../../include/openssl/opensslconf.h
        +pmeth_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pmeth_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pmeth_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pmeth_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pmeth_lib.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +pmeth_lib.o: evp_locl.h pmeth_lib.c
        diff --git a/vendor/openssl/openssl/crypto/evp/bio_b64.c b/vendor/openssl/openssl/crypto/evp/bio_b64.c
        new file mode 100644
        index 000000000..72a2a6727
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/bio_b64.c
        @@ -0,0 +1,598 @@
        +/* crypto/evp/bio_b64.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +
        +static int b64_write(BIO *h, const char *buf, int num);
        +static int b64_read(BIO *h, char *buf, int size);
        +static int b64_puts(BIO *h, const char *str);
        +/*static int b64_gets(BIO *h, char *str, int size); */
        +static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int b64_new(BIO *h);
        +static int b64_free(BIO *data);
        +static long b64_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
        +#define B64_BLOCK_SIZE	1024
        +#define B64_BLOCK_SIZE2	768
        +#define B64_NONE	0
        +#define B64_ENCODE	1
        +#define B64_DECODE	2
        +
        +typedef struct b64_struct
        +	{
        +	/*BIO *bio; moved to the BIO structure */
        +	int buf_len;
        +	int buf_off;
        +	int tmp_len;		/* used to find the start when decoding */
        +	int tmp_nl;		/* If true, scan until '\n' */
        +	int encode;
        +	int start;		/* have we started decoding yet? */
        +	int cont;		/* <= 0 when finished */
        +	EVP_ENCODE_CTX base64;
        +	char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE)+10];
        +	char tmp[B64_BLOCK_SIZE];
        +	} BIO_B64_CTX;
        +
        +static BIO_METHOD methods_b64=
        +	{
        +	BIO_TYPE_BASE64,"base64 encoding",
        +	b64_write,
        +	b64_read,
        +	b64_puts,
        +	NULL, /* b64_gets, */
        +	b64_ctrl,
        +	b64_new,
        +	b64_free,
        +	b64_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_base64(void)
        +	{
        +	return(&methods_b64);
        +	}
        +
        +static int b64_new(BIO *bi)
        +	{
        +	BIO_B64_CTX *ctx;
        +
        +	ctx=(BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX));
        +	if (ctx == NULL) return(0);
        +
        +	ctx->buf_len=0;
        +	ctx->tmp_len=0;
        +	ctx->tmp_nl=0;
        +	ctx->buf_off=0;
        +	ctx->cont=1;
        +	ctx->start=1;
        +	ctx->encode=0;
        +
        +	bi->init=1;
        +	bi->ptr=(char *)ctx;
        +	bi->flags=0;
        +	bi->num = 0;
        +	return(1);
        +	}
        +
        +static int b64_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	OPENSSL_free(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +	}
        +	
        +static int b64_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0,i,ii,j,k,x,n,num,ret_code=0;
        +	BIO_B64_CTX *ctx;
        +	unsigned char *p,*q;
        +
        +	if (out == NULL) return(0);
        +	ctx=(BIO_B64_CTX *)b->ptr;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
        +
        +	BIO_clear_retry_flags(b);
        +
        +	if (ctx->encode != B64_DECODE)
        +		{
        +		ctx->encode=B64_DECODE;
        +		ctx->buf_len=0;
        +		ctx->buf_off=0;
        +		ctx->tmp_len=0;
        +		EVP_DecodeInit(&(ctx->base64));
        +		}
        +
        +	/* First check if there are bytes decoded/encoded */
        +	if (ctx->buf_len > 0)
        +		{
        +		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +		i=ctx->buf_len-ctx->buf_off;
        +		if (i > outl) i=outl;
        +		OPENSSL_assert(ctx->buf_off+i < (int)sizeof(ctx->buf));
        +		memcpy(out,&(ctx->buf[ctx->buf_off]),i);
        +		ret=i;
        +		out+=i;
        +		outl-=i;
        +		ctx->buf_off+=i;
        +		if (ctx->buf_len == ctx->buf_off)
        +			{
        +			ctx->buf_len=0;
        +			ctx->buf_off=0;
        +			}
        +		}
        +
        +	/* At this point, we have room of outl bytes and an empty
        +	 * buffer, so we should read in some more. */
        +
        +	ret_code=0;
        +	while (outl > 0)
        +		{
        +		if (ctx->cont <= 0)
        +			break;
        +
        +		i=BIO_read(b->next_bio,&(ctx->tmp[ctx->tmp_len]),
        +			B64_BLOCK_SIZE-ctx->tmp_len);
        +
        +		if (i <= 0)
        +			{
        +			ret_code=i;
        +
        +			/* Should we continue next time we are called? */
        +			if (!BIO_should_retry(b->next_bio))
        +				{
        +				ctx->cont=i;
        +				/* If buffer empty break */
        +				if(ctx->tmp_len == 0)
        +					break;
        +				/* Fall through and process what we have */
        +				else
        +					i = 0;
        +				}
        +			/* else we retry and add more data to buffer */
        +			else
        +				break;
        +			}
        +		i+=ctx->tmp_len;
        +		ctx->tmp_len = i;
        +
        +		/* We need to scan, a line at a time until we
        +		 * have a valid line if we are starting. */
        +		if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL))
        +			{
        +			/* ctx->start=1; */
        +			ctx->tmp_len=0;
        +			}
        +		else if (ctx->start)
        +			{
        +			q=p=(unsigned char *)ctx->tmp;
        +			for (j=0; j<i; j++)
        +				{
        +				if (*(q++) != '\n') continue;
        +
        +				/* due to a previous very long line,
        +				 * we need to keep on scanning for a '\n'
        +				 * before we even start looking for
        +				 * base64 encoded stuff. */
        +				if (ctx->tmp_nl)
        +					{
        +					p=q;
        +					ctx->tmp_nl=0;
        +					continue;
        +					}
        +
        +				k=EVP_DecodeUpdate(&(ctx->base64),
        +					(unsigned char *)ctx->buf,
        +					&num,p,q-p);
        +				if ((k <= 0) && (num == 0) && (ctx->start))
        +					EVP_DecodeInit(&ctx->base64);
        +				else 
        +					{
        +					if (p != (unsigned char *)
        +						&(ctx->tmp[0]))
        +						{
        +						i-=(p- (unsigned char *)
        +							&(ctx->tmp[0]));
        +						for (x=0; x < i; x++)
        +							ctx->tmp[x]=p[x];
        +						}
        +					EVP_DecodeInit(&ctx->base64);
        +					ctx->start=0;
        +					break;
        +					}
        +				p=q;
        +				}
        +
        +			/* we fell off the end without starting */
        +			if (j == i)
        +				{
        +				/* Is this is one long chunk?, if so, keep on
        +				 * reading until a new line. */
        +				if (p == (unsigned char *)&(ctx->tmp[0]))
        +					{
        +					/* Check buffer full */
        +					if (i == B64_BLOCK_SIZE)
        +						{
        +						ctx->tmp_nl=1;
        +						ctx->tmp_len=0;
        +						}
        +					}
        +				else if (p != q) /* finished on a '\n' */
        +					{
        +					n=q-p;
        +					for (ii=0; ii<n; ii++)
        +						ctx->tmp[ii]=p[ii];
        +					ctx->tmp_len=n;
        +					}
        +				/* else finished on a '\n' */
        +				continue;
        +				}
        +			else
        +			{
        +				ctx->tmp_len=0;
        +			}
        +		}
        +		else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0))
        +		{
        +			/* If buffer isn't full and we can retry then
        +			 * restart to read in more data.
        +			 */
        +			continue;
        +		}
        +
        +		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
        +			{
        +			int z,jj;
        +
        +#if 0
        +			jj=(i>>2)<<2;
        +#else
        +			jj = i & ~3; /* process per 4 */
        +#endif
        +			z=EVP_DecodeBlock((unsigned char *)ctx->buf,
        +				(unsigned char *)ctx->tmp,jj);
        +			if (jj > 2)
        +				{
        +				if (ctx->tmp[jj-1] == '=')
        +					{
        +					z--;
        +					if (ctx->tmp[jj-2] == '=')
        +						z--;
        +					}
        +				}
        +			/* z is now number of output bytes and jj is the
        +			 * number consumed */
        +			if (jj != i)
        +				{
        +				memmove(ctx->tmp, &ctx->tmp[jj], i-jj);
        +				ctx->tmp_len=i-jj;
        +				}
        +			ctx->buf_len=0;
        +			if (z > 0)
        +				{
        +				ctx->buf_len=z;
        +				}
        +			i=z;
        +			}
        +		else
        +			{
        +			i=EVP_DecodeUpdate(&(ctx->base64),
        +				(unsigned char *)ctx->buf,&ctx->buf_len,
        +				(unsigned char *)ctx->tmp,i);
        +			ctx->tmp_len = 0;
        +			}
        +		ctx->buf_off=0;
        +		if (i < 0)
        +			{
        +			ret_code=0;
        +			ctx->buf_len=0;
        +			break;
        +			}
        +
        +		if (ctx->buf_len <= outl)
        +			i=ctx->buf_len;
        +		else
        +			i=outl;
        +
        +		memcpy(out,ctx->buf,i);
        +		ret+=i;
        +		ctx->buf_off=i;
        +		if (ctx->buf_off == ctx->buf_len)
        +			{
        +			ctx->buf_len=0;
        +			ctx->buf_off=0;
        +			}
        +		outl-=i;
        +		out+=i;
        +		}
        +	/* BIO_clear_retry_flags(b); */
        +	BIO_copy_next_retry(b);
        +	return((ret == 0)?ret_code:ret);
        +	}
        +
        +static int b64_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret=0;
        +	int n;
        +	int i;
        +	BIO_B64_CTX *ctx;
        +
        +	ctx=(BIO_B64_CTX *)b->ptr;
        +	BIO_clear_retry_flags(b);
        +
        +	if (ctx->encode != B64_ENCODE)
        +		{
        +		ctx->encode=B64_ENCODE;
        +		ctx->buf_len=0;
        +		ctx->buf_off=0;
        +		ctx->tmp_len=0;
        +		EVP_EncodeInit(&(ctx->base64));
        +		}
        +
        +	OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
        +	OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
        +	OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +	n=ctx->buf_len-ctx->buf_off;
        +	while (n > 0)
        +		{
        +		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +		if (i <= 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			return(i);
        +			}
        +		OPENSSL_assert(i <= n);
        +		ctx->buf_off+=i;
        +		OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
        +		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +		n-=i;
        +		}
        +	/* at this point all pending data has been written */
        +	ctx->buf_off=0;
        +	ctx->buf_len=0;
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +
        +	while (inl > 0)
        +		{
        +		n=(inl > B64_BLOCK_SIZE)?B64_BLOCK_SIZE:inl;
        +
        +		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
        +			{
        +			if (ctx->tmp_len > 0)
        +				{
        +				OPENSSL_assert(ctx->tmp_len <= 3);
        +				n=3-ctx->tmp_len;
        +				/* There's a theoretical possibility for this */
        +				if (n > inl) 
        +					n=inl;
        +				memcpy(&(ctx->tmp[ctx->tmp_len]),in,n);
        +				ctx->tmp_len+=n;
        +				ret += n;
        +				if (ctx->tmp_len < 3)
        +					break;
        +				ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(unsigned char *)ctx->tmp,ctx->tmp_len);
        +				OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
        +				OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +				/* Since we're now done using the temporary
        +				   buffer, the length should be 0'd */
        +				ctx->tmp_len=0;
        +				}
        +			else
        +				{
        +				if (n < 3)
        +					{
        +					memcpy(ctx->tmp,in,n);
        +					ctx->tmp_len=n;
        +					ret += n;
        +					break;
        +					}
        +				n-=n%3;
        +				ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(const unsigned char *)in,n);
        +				OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
        +				OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +				ret += n;
        +				}
        +			}
        +		else
        +			{
        +			EVP_EncodeUpdate(&(ctx->base64),
        +				(unsigned char *)ctx->buf,&ctx->buf_len,
        +				(unsigned char *)in,n);
        +			OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
        +			OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +			ret += n;
        +			}
        +		inl-=n;
        +		in+=n;
        +
        +		ctx->buf_off=0;
        +		n=ctx->buf_len;
        +		while (n > 0)
        +			{
        +			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				return((ret == 0)?i:ret);
        +				}
        +			OPENSSL_assert(i <= n);
        +			n-=i;
        +			ctx->buf_off+=i;
        +			OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
        +			OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +			}
        +		ctx->buf_len=0;
        +		ctx->buf_off=0;
        +		}
        +	return(ret);
        +	}
        +
        +static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	BIO_B64_CTX *ctx;
        +	long ret=1;
        +	int i;
        +
        +	ctx=(BIO_B64_CTX *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ctx->cont=1;
        +		ctx->start=1;
        +		ctx->encode=B64_NONE;
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_EOF:	/* More to read */
        +		if (ctx->cont <= 0)
        +			ret=1;
        +		else
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_WPENDING: /* More to write in buffer */
        +		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +		ret=ctx->buf_len-ctx->buf_off;
        +		if ((ret == 0) && (ctx->encode != B64_NONE)
        +			&& (ctx->base64.num != 0))
        +			ret=1;
        +		else if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_PENDING: /* More to read in buffer */
        +		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        +		ret=ctx->buf_len-ctx->buf_off;
        +		if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		/* do a final write */
        +again:
        +		while (ctx->buf_len != ctx->buf_off)
        +			{
        +			i=b64_write(b,NULL,0);
        +			if (i < 0)
        +				return i;
        +			}
        +		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
        +			{
        +			if (ctx->tmp_len != 0)
        +				{
        +				ctx->buf_len=EVP_EncodeBlock(
        +					(unsigned char *)ctx->buf,
        +					(unsigned char *)ctx->tmp,
        +					ctx->tmp_len);
        +				ctx->buf_off=0;
        +				ctx->tmp_len=0;
        +				goto again;
        +				}
        +			}
        +		else if (ctx->encode != B64_NONE && ctx->base64.num != 0)
        +			{
        +			ctx->buf_off=0;
        +			EVP_EncodeFinal(&(ctx->base64),
        +				(unsigned char *)ctx->buf,
        +				&(ctx->buf_len));
        +			/* push out the bytes */
        +			goto again;
        +			}
        +		/* Finally flush the underlying BIO */
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +
        +	case BIO_CTRL_DUP:
        +		break;
        +	case BIO_CTRL_INFO:
        +	case BIO_CTRL_GET:
        +	case BIO_CTRL_SET:
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long b64_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 b64_puts(BIO *b, const char *str)
        +	{
        +	return b64_write(b,str,strlen(str));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/bio_enc.c b/vendor/openssl/openssl/crypto/evp/bio_enc.c
        new file mode 100644
        index 000000000..b6efb5fbc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/bio_enc.c
        @@ -0,0 +1,428 @@
        +/* crypto/evp/bio_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +
        +static int enc_write(BIO *h, const char *buf, int num);
        +static int enc_read(BIO *h, char *buf, int size);
        +/*static int enc_puts(BIO *h, const char *str); */
        +/*static int enc_gets(BIO *h, char *str, int size); */
        +static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int enc_new(BIO *h);
        +static int enc_free(BIO *data);
        +static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
        +#define ENC_BLOCK_SIZE	(1024*4)
        +#define BUF_OFFSET	(EVP_MAX_BLOCK_LENGTH*2)
        +
        +typedef struct enc_struct
        +	{
        +	int buf_len;
        +	int buf_off;
        +	int cont;		/* <= 0 when finished */
        +	int finished;
        +	int ok;			/* bad decrypt */
        +	EVP_CIPHER_CTX cipher;
        +	/* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
        +	 * can return up to a block more data than is presented to it
        +	 */
        +	char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2];
        +	} BIO_ENC_CTX;
        +
        +static BIO_METHOD methods_enc=
        +	{
        +	BIO_TYPE_CIPHER,"cipher",
        +	enc_write,
        +	enc_read,
        +	NULL, /* enc_puts, */
        +	NULL, /* enc_gets, */
        +	enc_ctrl,
        +	enc_new,
        +	enc_free,
        +	enc_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_cipher(void)
        +	{
        +	return(&methods_enc);
        +	}
        +
        +static int enc_new(BIO *bi)
        +	{
        +	BIO_ENC_CTX *ctx;
        +
        +	ctx=(BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX));
        +	if (ctx == NULL) return(0);
        +	EVP_CIPHER_CTX_init(&ctx->cipher);
        +
        +	ctx->buf_len=0;
        +	ctx->buf_off=0;
        +	ctx->cont=1;
        +	ctx->finished=0;
        +	ctx->ok=1;
        +
        +	bi->init=0;
        +	bi->ptr=(char *)ctx;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int enc_free(BIO *a)
        +	{
        +	BIO_ENC_CTX *b;
        +
        +	if (a == NULL) return(0);
        +	b=(BIO_ENC_CTX *)a->ptr;
        +	EVP_CIPHER_CTX_cleanup(&(b->cipher));
        +	OPENSSL_cleanse(a->ptr,sizeof(BIO_ENC_CTX));
        +	OPENSSL_free(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +	}
        +	
        +static int enc_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0,i;
        +	BIO_ENC_CTX *ctx;
        +
        +	if (out == NULL) return(0);
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
        +
        +	/* First check if there are bytes decoded/encoded */
        +	if (ctx->buf_len > 0)
        +		{
        +		i=ctx->buf_len-ctx->buf_off;
        +		if (i > outl) i=outl;
        +		memcpy(out,&(ctx->buf[ctx->buf_off]),i);
        +		ret=i;
        +		out+=i;
        +		outl-=i;
        +		ctx->buf_off+=i;
        +		if (ctx->buf_len == ctx->buf_off)
        +			{
        +			ctx->buf_len=0;
        +			ctx->buf_off=0;
        +			}
        +		}
        +
        +	/* At this point, we have room of outl bytes and an empty
        +	 * buffer, so we should read in some more. */
        +
        +	while (outl > 0)
        +		{
        +		if (ctx->cont <= 0) break;
        +
        +		/* read in at IV offset, read the EVP_Cipher
        +		 * documentation about why */
        +		i=BIO_read(b->next_bio,&(ctx->buf[BUF_OFFSET]),ENC_BLOCK_SIZE);
        +
        +		if (i <= 0)
        +			{
        +			/* Should be continue next time we are called? */
        +			if (!BIO_should_retry(b->next_bio))
        +				{
        +				ctx->cont=i;
        +				i=EVP_CipherFinal_ex(&(ctx->cipher),
        +					(unsigned char *)ctx->buf,
        +					&(ctx->buf_len));
        +				ctx->ok=i;
        +				ctx->buf_off=0;
        +				}
        +			else 
        +				{
        +				ret=(ret == 0)?i:ret;
        +				break;
        +				}
        +			}
        +		else
        +			{
        +			EVP_CipherUpdate(&(ctx->cipher),
        +				(unsigned char *)ctx->buf,&ctx->buf_len,
        +				(unsigned char *)&(ctx->buf[BUF_OFFSET]),i);
        +			ctx->cont=1;
        +			/* Note: it is possible for EVP_CipherUpdate to
        +			 * decrypt zero bytes because this is or looks like
        +			 * the final block: if this happens we should retry
        +			 * and either read more data or decrypt the final
        +			 * block
        +			 */
        +			if(ctx->buf_len == 0) continue;
        +			}
        +
        +		if (ctx->buf_len <= outl)
        +			i=ctx->buf_len;
        +		else
        +			i=outl;
        +		if (i <= 0) break;
        +		memcpy(out,ctx->buf,i);
        +		ret+=i;
        +		ctx->buf_off=i;
        +		outl-=i;
        +		out+=i;
        +		}
        +
        +	BIO_clear_retry_flags(b);
        +	BIO_copy_next_retry(b);
        +	return((ret == 0)?ctx->cont:ret);
        +	}
        +
        +static int enc_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret=0,n,i;
        +	BIO_ENC_CTX *ctx;
        +
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +	ret=inl;
        +
        +	BIO_clear_retry_flags(b);
        +	n=ctx->buf_len-ctx->buf_off;
        +	while (n > 0)
        +		{
        +		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +		if (i <= 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			return(i);
        +			}
        +		ctx->buf_off+=i;
        +		n-=i;
        +		}
        +	/* at this point all pending data has been written */
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +
        +	ctx->buf_off=0;
        +	while (inl > 0)
        +		{
        +		n=(inl > ENC_BLOCK_SIZE)?ENC_BLOCK_SIZE:inl;
        +		EVP_CipherUpdate(&(ctx->cipher),
        +			(unsigned char *)ctx->buf,&ctx->buf_len,
        +			(unsigned char *)in,n);
        +		inl-=n;
        +		in+=n;
        +
        +		ctx->buf_off=0;
        +		n=ctx->buf_len;
        +		while (n > 0)
        +			{
        +			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				return (ret == inl) ? i : ret - inl;
        +				}
        +			n-=i;
        +			ctx->buf_off+=i;
        +			}
        +		ctx->buf_len=0;
        +		ctx->buf_off=0;
        +		}
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	BIO *dbio;
        +	BIO_ENC_CTX *ctx,*dctx;
        +	long ret=1;
        +	int i;
        +	EVP_CIPHER_CTX **c_ctx;
        +
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ctx->ok=1;
        +		ctx->finished=0;
        +		EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
        +			ctx->cipher.encrypt);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_EOF:	/* More to read */
        +		if (ctx->cont <= 0)
        +			ret=1;
        +		else
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_WPENDING:
        +		ret=ctx->buf_len-ctx->buf_off;
        +		if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_PENDING: /* More to read in buffer */
        +		ret=ctx->buf_len-ctx->buf_off;
        +		if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		/* do a final write */
        +again:
        +		while (ctx->buf_len != ctx->buf_off)
        +			{
        +			i=enc_write(b,NULL,0);
        +			if (i < 0)
        +				return i;
        +			}
        +
        +		if (!ctx->finished)
        +			{
        +			ctx->finished=1;
        +			ctx->buf_off=0;
        +			ret=EVP_CipherFinal_ex(&(ctx->cipher),
        +				(unsigned char *)ctx->buf,
        +				&(ctx->buf_len));
        +			ctx->ok=(int)ret;
        +			if (ret <= 0) break;
        +
        +			/* push out the bytes */
        +			goto again;
        +			}
        +		
        +		/* Finally flush the underlying BIO */
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_C_GET_CIPHER_STATUS:
        +		ret=(long)ctx->ok;
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +	case BIO_C_GET_CIPHER_CTX:
        +		c_ctx=(EVP_CIPHER_CTX **)ptr;
        +		(*c_ctx)= &(ctx->cipher);
        +		b->init=1;
        +		break;
        +	case BIO_CTRL_DUP:
        +		dbio=(BIO *)ptr;
        +		dctx=(BIO_ENC_CTX *)dbio->ptr;
        +		EVP_CIPHER_CTX_init(&dctx->cipher);
        +		ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher);
        +		if (ret)
        +			dbio->init=1;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long enc_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);
        +	}
        +
        +/*
        +void BIO_set_cipher_ctx(b,c)
        +BIO *b;
        +EVP_CIPHER_ctx *c;
        +	{
        +	if (b == NULL) return;
        +
        +	if ((b->callback != NULL) &&
        +		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
        +		return;
        +
        +	b->init=1;
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
        +	
        +	if (b->callback != NULL)
        +		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
        +	}
        +*/
        +
        +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
        +	     const unsigned char *i, int e)
        +	{
        +	BIO_ENC_CTX *ctx;
        +
        +	if (b == NULL) return;
        +
        +	if ((b->callback != NULL) &&
        +		(b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,0L) <= 0))
        +		return;
        +
        +	b->init=1;
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +	EVP_CipherInit_ex(&(ctx->cipher),c,NULL, k,i,e);
        +	
        +	if (b->callback != NULL)
        +		b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,1L);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/bio_md.c b/vendor/openssl/openssl/crypto/evp/bio_md.c
        new file mode 100644
        index 000000000..144fdfd56
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/bio_md.c
        @@ -0,0 +1,275 @@
        +/* crypto/evp/bio_md.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +
        +/* BIO_put and BIO_get both add to the digest,
        + * BIO_gets returns the digest */
        +
        +static int md_write(BIO *h, char const *buf, int num);
        +static int md_read(BIO *h, char *buf, int size);
        +/*static int md_puts(BIO *h, const char *str); */
        +static int md_gets(BIO *h, char *str, int size);
        +static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int md_new(BIO *h);
        +static int md_free(BIO *data);
        +static long md_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp);
        +
        +static BIO_METHOD methods_md=
        +	{
        +	BIO_TYPE_MD,"message digest",
        +	md_write,
        +	md_read,
        +	NULL, /* md_puts, */
        +	md_gets,
        +	md_ctrl,
        +	md_new,
        +	md_free,
        +	md_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_md(void)
        +	{
        +	return(&methods_md);
        +	}
        +
        +static int md_new(BIO *bi)
        +	{
        +	EVP_MD_CTX *ctx;
        +
        +	ctx=EVP_MD_CTX_create();
        +	if (ctx == NULL) return(0);
        +
        +	bi->init=0;
        +	bi->ptr=(char *)ctx;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int md_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	EVP_MD_CTX_destroy(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +	}
        +	
        +static int md_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0;
        +	EVP_MD_CTX *ctx;
        +
        +	if (out == NULL) return(0);
        +	ctx=b->ptr;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
        +
        +	ret=BIO_read(b->next_bio,out,outl);
        +	if (b->init)
        +		{
        +		if (ret > 0)
        +			{
        +			if (EVP_DigestUpdate(ctx,(unsigned char *)out,
        +				(unsigned int)ret)<=0) return (-1);
        +			}
        +		}
        +	BIO_clear_retry_flags(b);
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static int md_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret=0;
        +	EVP_MD_CTX *ctx;
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +	ctx=b->ptr;
        +
        +	if ((ctx != NULL) && (b->next_bio != NULL))
        +		ret=BIO_write(b->next_bio,in,inl);
        +	if (b->init)
        +		{
        +		if (ret > 0)
        +			{
        +			if (!EVP_DigestUpdate(ctx,(const unsigned char *)in,
        +				(unsigned int)ret))
        +				{
        +				BIO_clear_retry_flags(b);
        +				return 0;
        +				}
        +			}
        +		}
        +	if(b->next_bio != NULL)
        +		{
        +		BIO_clear_retry_flags(b);
        +		BIO_copy_next_retry(b);
        +		}
        +	return(ret);
        +	}
        +
        +static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	EVP_MD_CTX *ctx,*dctx,**pctx;
        +	const EVP_MD **ppmd;
        +	EVP_MD *md;
        +	long ret=1;
        +	BIO *dbio;
        +
        +	ctx=b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		if (b->init)
        +			ret = EVP_DigestInit_ex(ctx,ctx->digest, NULL);
        +		else
        +			ret=0;
        +		if (ret > 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_C_GET_MD:
        +		if (b->init)
        +			{
        +			ppmd=ptr;
        +			*ppmd=ctx->digest;
        +			}
        +		else
        +			ret=0;
        +		break;
        +	case BIO_C_GET_MD_CTX:
        +		pctx=ptr;
        +		*pctx=ctx;
        +		b->init = 1;
        +		break;
        +	case BIO_C_SET_MD_CTX:
        +		if (b->init)
        +			b->ptr=ptr;
        +		else
        +			ret=0;
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +
        +	case BIO_C_SET_MD:
        +		md=ptr;
        +		ret = EVP_DigestInit_ex(ctx,md, NULL);
        +		if (ret > 0)
        +			b->init=1;
        +		break;
        +	case BIO_CTRL_DUP:
        +		dbio=ptr;
        +		dctx=dbio->ptr;
        +		if (!EVP_MD_CTX_copy_ex(dctx,ctx))
        +			return 0;
        +		b->init=1;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long md_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 md_gets(BIO *bp, char *buf, int size)
        +	{
        +	EVP_MD_CTX *ctx;
        +	unsigned int ret;
        +
        +
        +	ctx=bp->ptr;
        +	if (size < ctx->digest->md_size)
        +		return(0);
        +	if (EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret)<=0) 
        +		return -1;
        +		
        +	return((int)ret);
        +	}
        +
        +/*
        +static int md_puts(bp,str)
        +BIO *bp;
        +char *str;
        +	{
        +	return(-1);
        +	}
        +*/
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/bio_ok.c b/vendor/openssl/openssl/crypto/evp/bio_ok.c
        new file mode 100644
        index 000000000..e64335353
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/bio_ok.c
        @@ -0,0 +1,624 @@
        +/* crypto/evp/bio_ok.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.]
        + */
        +
        +/*
        +	From: Arne Ansper <arne@cyber.ee>
        +
        +	Why BIO_f_reliable?
        +
        +	I wrote function which took BIO* as argument, read data from it
        +	and processed it. Then I wanted to store the input file in 
        +	encrypted form. OK I pushed BIO_f_cipher to the BIO stack
        +	and everything was OK. BUT if user types wrong password 
        +	BIO_f_cipher outputs only garbage and my function crashes. Yes
        +	I can and I should fix my function, but BIO_f_cipher is 
        +	easy way to add encryption support to many existing applications
        +	and it's hard to debug and fix them all. 
        +
        +	So I wanted another BIO which would catch the incorrect passwords and
        +	file damages which cause garbage on BIO_f_cipher's output. 
        +
        +	The easy way is to push the BIO_f_md and save the checksum at 
        +	the end of the file. However there are several problems with this
        +	approach:
        +
        +	1) you must somehow separate checksum from actual data. 
        +	2) you need lot's of memory when reading the file, because you 
        +	must read to the end of the file and verify the checksum before
        +	letting the application to read the data. 
        +	
        +	BIO_f_reliable tries to solve both problems, so that you can 
        +	read and write arbitrary long streams using only fixed amount
        +	of memory.
        +
        +	BIO_f_reliable splits data stream into blocks. Each block is prefixed
        +	with it's length and suffixed with it's digest. So you need only 
        +	several Kbytes of memory to buffer single block before verifying 
        +	it's digest. 
        +
        +	BIO_f_reliable goes further and adds several important capabilities:
        +
        +	1) the digest of the block is computed over the whole stream 
        +	-- so nobody can rearrange the blocks or remove or replace them.
        +
        +	2) to detect invalid passwords right at the start BIO_f_reliable 
        +	adds special prefix to the stream. In order to avoid known plain-text
        +	attacks this prefix is generated as follows:
        +
        +		*) digest is initialized with random seed instead of 
        +		standardized one.
        +		*) same seed is written to output
        +		*) well-known text is then hashed and the output 
        +		of the digest is also written to output.
        +
        +	reader can now read the seed from stream, hash the same string
        +	and then compare the digest output.
        +
        +	Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I 
        +	initially wrote and tested this code on x86 machine and wrote the
        +	digests out in machine-dependent order :( There are people using
        +	this code and I cannot change this easily without making existing
        +	data files unreadable.
        +
        +*/
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include <assert.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +
        +static int ok_write(BIO *h, const char *buf, int num);
        +static int ok_read(BIO *h, char *buf, int size);
        +static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int ok_new(BIO *h);
        +static int ok_free(BIO *data);
        +static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
        +
        +static int sig_out(BIO* b);
        +static int sig_in(BIO* b);
        +static int block_out(BIO* b);
        +static int block_in(BIO* b);
        +#define OK_BLOCK_SIZE	(1024*4)
        +#define OK_BLOCK_BLOCK	4
        +#define IOBS		(OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
        +#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
        +
        +typedef struct ok_struct
        +	{
        +	size_t buf_len;
        +	size_t buf_off;
        +	size_t buf_len_save;
        +	size_t buf_off_save;
        +	int cont;		/* <= 0 when finished */
        +	int finished;
        +	EVP_MD_CTX md;
        +	int blockout;		/* output block is ready */ 
        +	int sigio;		/* must process signature */
        +	unsigned char buf[IOBS];
        +	} BIO_OK_CTX;
        +
        +static BIO_METHOD methods_ok=
        +	{
        +	BIO_TYPE_CIPHER,"reliable",
        +	ok_write,
        +	ok_read,
        +	NULL, /* ok_puts, */
        +	NULL, /* ok_gets, */
        +	ok_ctrl,
        +	ok_new,
        +	ok_free,
        +	ok_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_reliable(void)
        +	{
        +	return(&methods_ok);
        +	}
        +
        +static int ok_new(BIO *bi)
        +	{
        +	BIO_OK_CTX *ctx;
        +
        +	ctx=(BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
        +	if (ctx == NULL) return(0);
        +
        +	ctx->buf_len=0;
        +	ctx->buf_off=0;
        +	ctx->buf_len_save=0;
        +	ctx->buf_off_save=0;
        +	ctx->cont=1;
        +	ctx->finished=0;
        +	ctx->blockout= 0;
        +	ctx->sigio=1;
        +
        +	EVP_MD_CTX_init(&ctx->md);
        +
        +	bi->init=0;
        +	bi->ptr=(char *)ctx;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int ok_free(BIO *a)
        +	{
        +	if (a == NULL) return(0);
        +	EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
        +	OPENSSL_cleanse(a->ptr,sizeof(BIO_OK_CTX));
        +	OPENSSL_free(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +	}
        +	
        +static int ok_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0,i,n;
        +	BIO_OK_CTX *ctx;
        +
        +	if (out == NULL) return(0);
        +	ctx=(BIO_OK_CTX *)b->ptr;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
        +
        +	while(outl > 0)
        +		{
        +
        +		/* copy clean bytes to output buffer */
        +		if (ctx->blockout)
        +			{
        +			i=ctx->buf_len-ctx->buf_off;
        +			if (i > outl) i=outl;
        +			memcpy(out,&(ctx->buf[ctx->buf_off]),i);
        +			ret+=i;
        +			out+=i;
        +			outl-=i;
        +			ctx->buf_off+=i;
        +
        +			/* all clean bytes are out */
        +			if (ctx->buf_len == ctx->buf_off)
        +				{
        +				ctx->buf_off=0;
        +
        +				/* copy start of the next block into proper place */
        +				if(ctx->buf_len_save- ctx->buf_off_save > 0)
        +					{
        +					ctx->buf_len= ctx->buf_len_save- ctx->buf_off_save;
        +					memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
        +							ctx->buf_len);
        +					}
        +				else
        +					{
        +					ctx->buf_len=0;
        +					}
        +				ctx->blockout= 0;
        +				}
        +			}
        +	
        +		/* output buffer full -- cancel */
        +		if (outl == 0) break;
        +
        +		/* no clean bytes in buffer -- fill it */
        +		n=IOBS- ctx->buf_len;
        +		i=BIO_read(b->next_bio,&(ctx->buf[ctx->buf_len]),n);
        +
        +		if (i <= 0) break;	/* nothing new */
        +
        +		ctx->buf_len+= i;
        +
        +		/* no signature yet -- check if we got one */
        +		if (ctx->sigio == 1)
        +			{
        +			if (!sig_in(b))
        +				{
        +				BIO_clear_retry_flags(b);
        +				return 0;
        +				}
        +			}
        +
        +		/* signature ok -- check if we got block */
        +		if (ctx->sigio == 0)
        +			{
        +			if (!block_in(b))
        +				{
        +				BIO_clear_retry_flags(b);
        +				return 0;
        +				}
        +			}
        +
        +		/* invalid block -- cancel */
        +		if (ctx->cont <= 0) break;
        +
        +		}
        +
        +	BIO_clear_retry_flags(b);
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static int ok_write(BIO *b, const char *in, int inl)
        +	{
        +	int ret=0,n,i;
        +	BIO_OK_CTX *ctx;
        +
        +	if (inl <= 0) return inl;
        +
        +	ctx=(BIO_OK_CTX *)b->ptr;
        +	ret=inl;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
        +
        +	if(ctx->sigio && !sig_out(b))
        +		return 0;
        +
        +	do{
        +		BIO_clear_retry_flags(b);
        +		n=ctx->buf_len-ctx->buf_off;
        +		while (ctx->blockout && n > 0)
        +			{
        +			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				if(!BIO_should_retry(b))
        +					ctx->cont= 0;
        +				return(i);
        +				}
        +			ctx->buf_off+=i;
        +			n-=i;
        +			}
        +
        +		/* at this point all pending data has been written */
        +		ctx->blockout= 0;
        +		if (ctx->buf_len == ctx->buf_off)
        +			{
        +			ctx->buf_len=OK_BLOCK_BLOCK;
        +			ctx->buf_off=0;
        +			}
        +	
        +		if ((in == NULL) || (inl <= 0)) return(0);
        +
        +		n= (inl+ ctx->buf_len > OK_BLOCK_SIZE+ OK_BLOCK_BLOCK) ? 
        +			(int)(OK_BLOCK_SIZE+OK_BLOCK_BLOCK-ctx->buf_len) : inl;
        +
        +		memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),(unsigned char *)in,n);
        +		ctx->buf_len+= n;
        +		inl-=n;
        +		in+=n;
        +
        +		if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
        +			{
        +			if (!block_out(b))
        +				{
        +				BIO_clear_retry_flags(b);
        +				return 0;
        +				}
        +			}
        +	}while(inl > 0);
        +
        +	BIO_clear_retry_flags(b);
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	BIO_OK_CTX *ctx;
        +	EVP_MD *md;
        +	const EVP_MD **ppmd;
        +	long ret=1;
        +	int i;
        +
        +	ctx=b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ctx->buf_len=0;
        +		ctx->buf_off=0;
        +		ctx->buf_len_save=0;
        +		ctx->buf_off_save=0;
        +		ctx->cont=1;
        +		ctx->finished=0;
        +		ctx->blockout= 0;
        +		ctx->sigio=1;
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_EOF:	/* More to read */
        +		if (ctx->cont <= 0)
        +			ret=1;
        +		else
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_PENDING: /* More to read in buffer */
        +	case BIO_CTRL_WPENDING: /* More to read in buffer */
        +		ret=ctx->blockout ? ctx->buf_len-ctx->buf_off : 0;
        +		if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		/* do a final write */
        +		if(ctx->blockout == 0)
        +			if (!block_out(b))
        +				return 0;
        +
        +		while (ctx->blockout)
        +			{
        +			i=ok_write(b,NULL,0);
        +			if (i < 0)
        +				{
        +				ret=i;
        +				break;
        +				}
        +			}
        +
        +		ctx->finished=1;
        +		ctx->buf_off=ctx->buf_len=0;
        +		ctx->cont=(int)ret;
        +		
        +		/* Finally flush the underlying BIO */
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +	case BIO_CTRL_INFO:
        +		ret=(long)ctx->cont;
        +		break;
        +	case BIO_C_SET_MD:
        +		md=ptr;
        +		if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
        +			return 0;
        +		b->init=1;
        +		break;
        +	case BIO_C_GET_MD:
        +		if (b->init)
        +			{
        +			ppmd=ptr;
        +			*ppmd=ctx->md.digest;
        +			}
        +		else
        +			ret=0;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long ok_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 void longswap(void *_ptr, size_t len)
        +{	const union { long one; char little; } is_endian = {1};
        +
        +	if (is_endian.little) {
        +		size_t i;
        +		unsigned char *p=_ptr,c;
        +
        +		for(i= 0;i < len;i+= 4) {
        +			c=p[0],p[0]=p[3],p[3]=c;
        +			c=p[1],p[1]=p[2],p[2]=c;
        +		}
        +	}
        +}
        +
        +static int sig_out(BIO* b)
        +	{
        +	BIO_OK_CTX *ctx;
        +	EVP_MD_CTX *md;
        +
        +	ctx=b->ptr;
        +	md=&ctx->md;
        +
        +	if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return 1;
        +
        +	if (!EVP_DigestInit_ex(md, md->digest, NULL))
        +		goto berr;
        +	/* FIXME: there's absolutely no guarantee this makes any sense at all,
        +	 * particularly now EVP_MD_CTX has been restructured.
        +	 */
        +	RAND_pseudo_bytes(md->md_data, md->digest->md_size);
        +	memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
        +	longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
        +	ctx->buf_len+= md->digest->md_size;
        +
        +	if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
        +		goto berr;
        +	if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
        +		goto berr;
        +	ctx->buf_len+= md->digest->md_size;
        +	ctx->blockout= 1;
        +	ctx->sigio= 0;
        +	return 1;
        +	berr:
        +	BIO_clear_retry_flags(b);
        +	return 0;
        +	}
        +
        +static int sig_in(BIO* b)
        +	{
        +	BIO_OK_CTX *ctx;
        +	EVP_MD_CTX *md;
        +	unsigned char tmp[EVP_MAX_MD_SIZE];
        +	int ret= 0;
        +
        +	ctx=b->ptr;
        +	md=&ctx->md;
        +
        +	if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return 1;
        +
        +	if (!EVP_DigestInit_ex(md, md->digest, NULL))
        +		goto berr;
        +	memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
        +	longswap(md->md_data, md->digest->md_size);
        +	ctx->buf_off+= md->digest->md_size;
        +
        +	if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
        +		goto berr;
        +	if (!EVP_DigestFinal_ex(md, tmp, NULL))
        +		goto berr;
        +	ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
        +	ctx->buf_off+= md->digest->md_size;
        +	if(ret == 1)
        +		{
        +		ctx->sigio= 0;
        +		if(ctx->buf_len != ctx->buf_off)
        +			{
        +			memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), ctx->buf_len- ctx->buf_off);
        +			}
        +		ctx->buf_len-= ctx->buf_off;
        +		ctx->buf_off= 0;
        +		}
        +	else
        +		{
        +		ctx->cont= 0;
        +		}
        +	return 1;
        +	berr:
        +	BIO_clear_retry_flags(b);
        +	return 0;
        +	}
        +
        +static int block_out(BIO* b)
        +	{
        +	BIO_OK_CTX *ctx;
        +	EVP_MD_CTX *md;
        +	unsigned long tl;
        +
        +	ctx=b->ptr;
        +	md=&ctx->md;
        +
        +	tl= ctx->buf_len- OK_BLOCK_BLOCK;
        +	ctx->buf[0]=(unsigned char)(tl>>24);
        +	ctx->buf[1]=(unsigned char)(tl>>16);
        +	ctx->buf[2]=(unsigned char)(tl>>8);
        +	ctx->buf[3]=(unsigned char)(tl);
        +	if (!EVP_DigestUpdate(md,
        +		(unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl))
        +		goto berr;
        +	if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
        +		goto berr;
        +	ctx->buf_len+= md->digest->md_size;
        +	ctx->blockout= 1;
        +	return 1;
        +	berr:
        +	BIO_clear_retry_flags(b);
        +	return 0;
        +	}
        +
        +static int block_in(BIO* b)
        +	{
        +	BIO_OK_CTX *ctx;
        +	EVP_MD_CTX *md;
        +	unsigned long tl= 0;
        +	unsigned char tmp[EVP_MAX_MD_SIZE];
        +
        +	ctx=b->ptr;
        +	md=&ctx->md;
        +
        +	assert(sizeof(tl)>=OK_BLOCK_BLOCK);	/* always true */
        +	tl =ctx->buf[0]; tl<<=8;
        +	tl|=ctx->buf[1]; tl<<=8;
        +	tl|=ctx->buf[2]; tl<<=8;
        +	tl|=ctx->buf[3];
        +
        +	if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return 1;
        + 
        +	if (!EVP_DigestUpdate(md,
        +			(unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl))
        +		goto berr;
        +	if (!EVP_DigestFinal_ex(md, tmp, NULL))
        +		goto berr;
        +	if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
        +		{
        +		/* there might be parts from next block lurking around ! */
        +		ctx->buf_off_save= tl+ OK_BLOCK_BLOCK+ md->digest->md_size;
        +		ctx->buf_len_save= ctx->buf_len;
        +		ctx->buf_off= OK_BLOCK_BLOCK;
        +		ctx->buf_len= tl+ OK_BLOCK_BLOCK;
        +		ctx->blockout= 1;
        +		}
        +	else
        +		{
        +		ctx->cont= 0;
        +		}
        +	return 1;
        +	berr:
        +	BIO_clear_retry_flags(b);
        +	return 0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/c_all.c b/vendor/openssl/openssl/crypto/evp/c_all.c
        new file mode 100644
        index 000000000..766c4cecd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/c_all.c
        @@ -0,0 +1,90 @@
        +/* crypto/evp/c_all.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +#if 0
        +#undef OpenSSL_add_all_algorithms
        +
        +void OpenSSL_add_all_algorithms(void)
        +	{
        +	OPENSSL_add_all_algorithms_noconf();
        +	}
        +#endif
        +
        +void OPENSSL_add_all_algorithms_noconf(void)
        +	{
        +	/*
        +	 * For the moment OPENSSL_cpuid_setup does something
        +	 * only on IA-32, but we reserve the option for all
        +	 * platforms...
        +	 */
        +	OPENSSL_cpuid_setup();
        +	OpenSSL_add_all_ciphers();
        +	OpenSSL_add_all_digests();
        +#ifndef OPENSSL_NO_ENGINE
        +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
        +	ENGINE_setup_bsd_cryptodev();
        +# endif
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/c_allc.c b/vendor/openssl/openssl/crypto/evp/c_allc.c
        new file mode 100644
        index 000000000..2a45d435e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/c_allc.c
        @@ -0,0 +1,230 @@
        +/* crypto/evp/c_allc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/objects.h>
        +
        +void OpenSSL_add_all_ciphers(void)
        +	{
        +
        +#ifndef OPENSSL_NO_DES
        +	EVP_add_cipher(EVP_des_cfb());
        +	EVP_add_cipher(EVP_des_cfb1());
        +	EVP_add_cipher(EVP_des_cfb8());
        +	EVP_add_cipher(EVP_des_ede_cfb());
        +	EVP_add_cipher(EVP_des_ede3_cfb());
        +	EVP_add_cipher(EVP_des_ede3_cfb1());
        +	EVP_add_cipher(EVP_des_ede3_cfb8());
        +
        +	EVP_add_cipher(EVP_des_ofb());
        +	EVP_add_cipher(EVP_des_ede_ofb());
        +	EVP_add_cipher(EVP_des_ede3_ofb());
        +
        +	EVP_add_cipher(EVP_desx_cbc());
        +	EVP_add_cipher_alias(SN_desx_cbc,"DESX");
        +	EVP_add_cipher_alias(SN_desx_cbc,"desx");
        +
        +	EVP_add_cipher(EVP_des_cbc());
        +	EVP_add_cipher_alias(SN_des_cbc,"DES");
        +	EVP_add_cipher_alias(SN_des_cbc,"des");
        +	EVP_add_cipher(EVP_des_ede_cbc());
        +	EVP_add_cipher(EVP_des_ede3_cbc());
        +	EVP_add_cipher_alias(SN_des_ede3_cbc,"DES3");
        +	EVP_add_cipher_alias(SN_des_ede3_cbc,"des3");
        +
        +	EVP_add_cipher(EVP_des_ecb());
        +	EVP_add_cipher(EVP_des_ede());
        +	EVP_add_cipher(EVP_des_ede3());
        +#endif
        +
        +#ifndef OPENSSL_NO_RC4
        +	EVP_add_cipher(EVP_rc4());
        +	EVP_add_cipher(EVP_rc4_40());
        +#ifndef OPENSSL_NO_MD5
        +	EVP_add_cipher(EVP_rc4_hmac_md5());
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_IDEA
        +	EVP_add_cipher(EVP_idea_ecb());
        +	EVP_add_cipher(EVP_idea_cfb());
        +	EVP_add_cipher(EVP_idea_ofb());
        +	EVP_add_cipher(EVP_idea_cbc());
        +	EVP_add_cipher_alias(SN_idea_cbc,"IDEA");
        +	EVP_add_cipher_alias(SN_idea_cbc,"idea");
        +#endif
        +
        +#ifndef OPENSSL_NO_SEED
        +	EVP_add_cipher(EVP_seed_ecb());
        +	EVP_add_cipher(EVP_seed_cfb());
        +	EVP_add_cipher(EVP_seed_ofb());
        +	EVP_add_cipher(EVP_seed_cbc());
        +	EVP_add_cipher_alias(SN_seed_cbc,"SEED");
        +	EVP_add_cipher_alias(SN_seed_cbc,"seed");
        +#endif
        +
        +#ifndef OPENSSL_NO_RC2
        +	EVP_add_cipher(EVP_rc2_ecb());
        +	EVP_add_cipher(EVP_rc2_cfb());
        +	EVP_add_cipher(EVP_rc2_ofb());
        +	EVP_add_cipher(EVP_rc2_cbc());
        +	EVP_add_cipher(EVP_rc2_40_cbc());
        +	EVP_add_cipher(EVP_rc2_64_cbc());
        +	EVP_add_cipher_alias(SN_rc2_cbc,"RC2");
        +	EVP_add_cipher_alias(SN_rc2_cbc,"rc2");
        +#endif
        +
        +#ifndef OPENSSL_NO_BF
        +	EVP_add_cipher(EVP_bf_ecb());
        +	EVP_add_cipher(EVP_bf_cfb());
        +	EVP_add_cipher(EVP_bf_ofb());
        +	EVP_add_cipher(EVP_bf_cbc());
        +	EVP_add_cipher_alias(SN_bf_cbc,"BF");
        +	EVP_add_cipher_alias(SN_bf_cbc,"bf");
        +	EVP_add_cipher_alias(SN_bf_cbc,"blowfish");
        +#endif
        +
        +#ifndef OPENSSL_NO_CAST
        +	EVP_add_cipher(EVP_cast5_ecb());
        +	EVP_add_cipher(EVP_cast5_cfb());
        +	EVP_add_cipher(EVP_cast5_ofb());
        +	EVP_add_cipher(EVP_cast5_cbc());
        +	EVP_add_cipher_alias(SN_cast5_cbc,"CAST");
        +	EVP_add_cipher_alias(SN_cast5_cbc,"cast");
        +	EVP_add_cipher_alias(SN_cast5_cbc,"CAST-cbc");
        +	EVP_add_cipher_alias(SN_cast5_cbc,"cast-cbc");
        +#endif
        +
        +#ifndef OPENSSL_NO_RC5
        +	EVP_add_cipher(EVP_rc5_32_12_16_ecb());
        +	EVP_add_cipher(EVP_rc5_32_12_16_cfb());
        +	EVP_add_cipher(EVP_rc5_32_12_16_ofb());
        +	EVP_add_cipher(EVP_rc5_32_12_16_cbc());
        +	EVP_add_cipher_alias(SN_rc5_cbc,"rc5");
        +	EVP_add_cipher_alias(SN_rc5_cbc,"RC5");
        +#endif
        +
        +#ifndef OPENSSL_NO_AES
        +	EVP_add_cipher(EVP_aes_128_ecb());
        +	EVP_add_cipher(EVP_aes_128_cbc());
        +	EVP_add_cipher(EVP_aes_128_cfb());
        +	EVP_add_cipher(EVP_aes_128_cfb1());
        +	EVP_add_cipher(EVP_aes_128_cfb8());
        +	EVP_add_cipher(EVP_aes_128_ofb());
        +	EVP_add_cipher(EVP_aes_128_ctr());
        +	EVP_add_cipher(EVP_aes_128_gcm());
        +	EVP_add_cipher(EVP_aes_128_xts());
        +	EVP_add_cipher_alias(SN_aes_128_cbc,"AES128");
        +	EVP_add_cipher_alias(SN_aes_128_cbc,"aes128");
        +	EVP_add_cipher(EVP_aes_192_ecb());
        +	EVP_add_cipher(EVP_aes_192_cbc());
        +	EVP_add_cipher(EVP_aes_192_cfb());
        +	EVP_add_cipher(EVP_aes_192_cfb1());
        +	EVP_add_cipher(EVP_aes_192_cfb8());
        +	EVP_add_cipher(EVP_aes_192_ofb());
        +	EVP_add_cipher(EVP_aes_192_ctr());
        +	EVP_add_cipher(EVP_aes_192_gcm());
        +	EVP_add_cipher_alias(SN_aes_192_cbc,"AES192");
        +	EVP_add_cipher_alias(SN_aes_192_cbc,"aes192");
        +	EVP_add_cipher(EVP_aes_256_ecb());
        +	EVP_add_cipher(EVP_aes_256_cbc());
        +	EVP_add_cipher(EVP_aes_256_cfb());
        +	EVP_add_cipher(EVP_aes_256_cfb1());
        +	EVP_add_cipher(EVP_aes_256_cfb8());
        +	EVP_add_cipher(EVP_aes_256_ofb());
        +	EVP_add_cipher(EVP_aes_256_ctr());
        +	EVP_add_cipher(EVP_aes_256_gcm());
        +	EVP_add_cipher(EVP_aes_256_xts());
        +	EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
        +	EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
        +	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
        +	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_CAMELLIA
        +	EVP_add_cipher(EVP_camellia_128_ecb());
        +	EVP_add_cipher(EVP_camellia_128_cbc());
        +	EVP_add_cipher(EVP_camellia_128_cfb());
        +	EVP_add_cipher(EVP_camellia_128_cfb1());
        +	EVP_add_cipher(EVP_camellia_128_cfb8());
        +	EVP_add_cipher(EVP_camellia_128_ofb());
        +	EVP_add_cipher_alias(SN_camellia_128_cbc,"CAMELLIA128");
        +	EVP_add_cipher_alias(SN_camellia_128_cbc,"camellia128");
        +	EVP_add_cipher(EVP_camellia_192_ecb());
        +	EVP_add_cipher(EVP_camellia_192_cbc());
        +	EVP_add_cipher(EVP_camellia_192_cfb());
        +	EVP_add_cipher(EVP_camellia_192_cfb1());
        +	EVP_add_cipher(EVP_camellia_192_cfb8());
        +	EVP_add_cipher(EVP_camellia_192_ofb());
        +	EVP_add_cipher_alias(SN_camellia_192_cbc,"CAMELLIA192");
        +	EVP_add_cipher_alias(SN_camellia_192_cbc,"camellia192");
        +	EVP_add_cipher(EVP_camellia_256_ecb());
        +	EVP_add_cipher(EVP_camellia_256_cbc());
        +	EVP_add_cipher(EVP_camellia_256_cfb());
        +	EVP_add_cipher(EVP_camellia_256_cfb1());
        +	EVP_add_cipher(EVP_camellia_256_cfb8());
        +	EVP_add_cipher(EVP_camellia_256_ofb());
        +	EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256");
        +	EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256");
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/c_alld.c b/vendor/openssl/openssl/crypto/evp/c_alld.c
        new file mode 100644
        index 000000000..311e1fe2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/c_alld.c
        @@ -0,0 +1,114 @@
        +/* crypto/evp/c_alld.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/objects.h>
        +
        +void OpenSSL_add_all_digests(void)
        +	{
        +#ifndef OPENSSL_NO_MD4
        +	EVP_add_digest(EVP_md4());
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +	EVP_add_digest(EVP_md5());
        +	EVP_add_digest_alias(SN_md5,"ssl2-md5");
        +	EVP_add_digest_alias(SN_md5,"ssl3-md5");
        +#endif
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
        +	EVP_add_digest(EVP_sha());
        +#ifndef OPENSSL_NO_DSA
        +	EVP_add_digest(EVP_dss());
        +#endif
        +#endif
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
        +	EVP_add_digest(EVP_sha1());
        +	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
        +	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
        +#ifndef OPENSSL_NO_DSA
        +	EVP_add_digest(EVP_dss1());
        +	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
        +	EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
        +	EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	EVP_add_digest(EVP_ecdsa());
        +#endif
        +#endif
        +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
        +	EVP_add_digest(EVP_mdc2());
        +#endif
        +#ifndef OPENSSL_NO_RIPEMD
        +	EVP_add_digest(EVP_ripemd160());
        +	EVP_add_digest_alias(SN_ripemd160,"ripemd");
        +	EVP_add_digest_alias(SN_ripemd160,"rmd160");
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +	EVP_add_digest(EVP_sha224());
        +	EVP_add_digest(EVP_sha256());
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +	EVP_add_digest(EVP_sha384());
        +	EVP_add_digest(EVP_sha512());
        +#endif
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +	EVP_add_digest(EVP_whirlpool());
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/digest.c b/vendor/openssl/openssl/crypto/evp/digest.c
        new file mode 100644
        index 000000000..6fc469f9c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/digest.c
        @@ -0,0 +1,404 @@
        +/* crypto/evp/digest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
        +	{
        +	memset(ctx,'\0',sizeof *ctx);
        +	}
        +
        +EVP_MD_CTX *EVP_MD_CTX_create(void)
        +	{
        +	EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
        +
        +	if (ctx)
        +		EVP_MD_CTX_init(ctx);
        +
        +	return ctx;
        +	}
        +
        +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
        +	{
        +	EVP_MD_CTX_init(ctx);
        +	return EVP_DigestInit_ex(ctx, type, NULL);
        +	}
        +
        +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
        +	{
        +	EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
        +	 * so this context may already have an ENGINE! Try to avoid releasing
        +	 * the previous handle, re-querying for an ENGINE, and having a
        +	 * reinitialisation, when it may all be unecessary. */
        +	if (ctx->engine && ctx->digest && (!type ||
        +			(type && (type->type == ctx->digest->type))))
        +		goto skip_to_init;
        +	if (type)
        +		{
        +		/* Ensure an ENGINE left lying around from last time is cleared
        +		 * (the previous check attempted to avoid this if the same
        +		 * ENGINE and EVP_MD could be used). */
        +		if(ctx->engine)
        +			ENGINE_finish(ctx->engine);
        +		if(impl)
        +			{
        +			if (!ENGINE_init(impl))
        +				{
        +				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
        +				return 0;
        +				}
        +			}
        +		else
        +			/* Ask if an ENGINE is reserved for this job */
        +			impl = ENGINE_get_digest_engine(type->type);
        +		if(impl)
        +			{
        +			/* There's an ENGINE for this job ... (apparently) */
        +			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
        +			if(!d)
        +				{
        +				/* Same comment from evp_enc.c */
        +				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
        +				ENGINE_finish(impl);
        +				return 0;
        +				}
        +			/* We'll use the ENGINE's private digest definition */
        +			type = d;
        +			/* Store the ENGINE functional reference so we know
        +			 * 'type' came from an ENGINE and we need to release
        +			 * it when done. */
        +			ctx->engine = impl;
        +			}
        +		else
        +			ctx->engine = NULL;
        +		}
        +	else
        +	if(!ctx->digest)
        +		{
        +		EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
        +		return 0;
        +		}
        +#endif
        +	if (ctx->digest != type)
        +		{
        +		if (ctx->digest && ctx->digest->ctx_size)
        +			OPENSSL_free(ctx->md_data);
        +		ctx->digest=type;
        +		if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
        +			{
        +			ctx->update = type->update;
        +			ctx->md_data=OPENSSL_malloc(type->ctx_size);
        +			if (ctx->md_data == NULL)
        +				{
        +				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
        +							ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +			}
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +skip_to_init:
        +#endif
        +	if (ctx->pctx)
        +		{
        +		int r;
        +		r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
        +					EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
        +		if (r <= 0 && (r != -2))
        +			return 0;
        +		}
        +	if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
        +		return 1;
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		{
        +		if (FIPS_digestinit(ctx, type))
        +			return 1;
        +		OPENSSL_free(ctx->md_data);
        +		ctx->md_data = NULL;
        +		return 0;
        +		}
        +#endif
        +	return ctx->digest->init(ctx);
        +	}
        +
        +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
        +	{
        +#ifdef OPENSSL_FIPS
        +	return FIPS_digestupdate(ctx, data, count);
        +#else
        +	return ctx->update(ctx,data,count);
        +#endif
        +	}
        +
        +/* The caller can assume that this removes any secret data from the context */
        +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        +	{
        +	int ret;
        +	ret = EVP_DigestFinal_ex(ctx, md, size);
        +	EVP_MD_CTX_cleanup(ctx);
        +	return ret;
        +	}
        +
        +/* The caller can assume that this removes any secret data from the context */
        +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        +	{
        +#ifdef OPENSSL_FIPS
        +	return FIPS_digestfinal(ctx, md, size);
        +#else
        +	int ret;
        +
        +	OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
        +	ret=ctx->digest->final(ctx,md);
        +	if (size != NULL)
        +		*size=ctx->digest->md_size;
        +	if (ctx->digest->cleanup)
        +		{
        +		ctx->digest->cleanup(ctx);
        +		EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
        +		}
        +	memset(ctx->md_data,0,ctx->digest->ctx_size);
        +	return ret;
        +#endif
        +	}
        +
        +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
        +	{
        +	EVP_MD_CTX_init(out);
        +	return EVP_MD_CTX_copy_ex(out, in);
        +	}
        +
        +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
        +	{
        +	unsigned char *tmp_buf;
        +	if ((in == NULL) || (in->digest == NULL))
        +		{
        +		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,EVP_R_INPUT_NOT_INITIALIZED);
        +		return 0;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Make sure it's safe to copy a digest context using an ENGINE */
        +	if (in->engine && !ENGINE_init(in->engine))
        +		{
        +		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
        +		return 0;
        +		}
        +#endif
        +
        +	if (out->digest == in->digest)
        +		{
        +		tmp_buf = out->md_data;
        +	    	EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
        +		}
        +	else tmp_buf = NULL;
        +	EVP_MD_CTX_cleanup(out);
        +	memcpy(out,in,sizeof *out);
        +
        +	if (in->md_data && out->digest->ctx_size)
        +		{
        +		if (tmp_buf)
        +			out->md_data = tmp_buf;
        +		else
        +			{
        +			out->md_data=OPENSSL_malloc(out->digest->ctx_size);
        +			if (!out->md_data)
        +				{
        +				EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +			}
        +		memcpy(out->md_data,in->md_data,out->digest->ctx_size);
        +		}
        +
        +	out->update = in->update;
        +
        +	if (in->pctx)
        +		{
        +		out->pctx = EVP_PKEY_CTX_dup(in->pctx);
        +		if (!out->pctx)
        +			{
        +			EVP_MD_CTX_cleanup(out);
        +			return 0;
        +			}
        +		}
        +
        +	if (out->digest->copy)
        +		return out->digest->copy(out,in);
        +	
        +	return 1;
        +	}
        +
        +int EVP_Digest(const void *data, size_t count,
        +		unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl)
        +	{
        +	EVP_MD_CTX ctx;
        +	int ret;
        +
        +	EVP_MD_CTX_init(&ctx);
        +	EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
        +	ret=EVP_DigestInit_ex(&ctx, type, impl)
        +	  && EVP_DigestUpdate(&ctx, data, count)
        +	  && EVP_DigestFinal_ex(&ctx, md, size);
        +	EVP_MD_CTX_cleanup(&ctx);
        +
        +	return ret;
        +	}
        +
        +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
        +	{
        +	EVP_MD_CTX_cleanup(ctx);
        +	OPENSSL_free(ctx);
        +	}
        +
        +/* This call frees resources associated with the context */
        +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
        +	{
        +#ifndef OPENSSL_FIPS
        +	/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
        +	 * because sometimes only copies of the context are ever finalised.
        +	 */
        +	if (ctx->digest && ctx->digest->cleanup
        +	    && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
        +		ctx->digest->cleanup(ctx);
        +	if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
        +	    && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
        +		{
        +		OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
        +		OPENSSL_free(ctx->md_data);
        +		}
        +#endif
        +	if (ctx->pctx)
        +		EVP_PKEY_CTX_free(ctx->pctx);
        +#ifndef OPENSSL_NO_ENGINE
        +	if(ctx->engine)
        +		/* The EVP_MD we used belongs to an ENGINE, release the
        +		 * functional reference we held for this reason. */
        +		ENGINE_finish(ctx->engine);
        +#endif
        +#ifdef OPENSSL_FIPS
        +	FIPS_md_ctx_cleanup(ctx);
        +#endif
        +	memset(ctx,'\0',sizeof *ctx);
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/e_aes.c b/vendor/openssl/openssl/crypto/evp/e_aes.c
        new file mode 100644
        index 000000000..1bfb5d92b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_aes.c
        @@ -0,0 +1,1314 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2011 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_AES
        +#include <openssl/evp.h>
        +#include <openssl/err.h>
        +#include <string.h>
        +#include <assert.h>
        +#include <openssl/aes.h>
        +#include "evp_locl.h"
        +#ifndef OPENSSL_FIPS
        +#include "modes_lcl.h"
        +#include <openssl/rand.h>
        +
        +typedef struct
        +	{
        +	AES_KEY ks;
        +	block128_f block;
        +	union {
        +		cbc128_f cbc;
        +		ctr128_f ctr;
        +	} stream;
        +	} EVP_AES_KEY;
        +
        +typedef struct
        +	{
        +	AES_KEY ks;		/* AES key schedule to use */
        +	int key_set;		/* Set if key initialised */
        +	int iv_set;		/* Set if an iv is set */
        +	GCM128_CONTEXT gcm;
        +	unsigned char *iv;	/* Temporary IV store */
        +	int ivlen;		/* IV length */
        +	int taglen;
        +	int iv_gen;		/* It is OK to generate IVs */
        +	int tls_aad_len;	/* TLS AAD length */
        +	ctr128_f ctr;
        +	} EVP_AES_GCM_CTX;
        +
        +typedef struct
        +	{
        +	AES_KEY ks1, ks2;	/* AES key schedules to use */
        +	XTS128_CONTEXT xts;
        +	void     (*stream)(const unsigned char *in,
        +			unsigned char *out, size_t length,
        +			const AES_KEY *key1, const AES_KEY *key2,
        +			const unsigned char iv[16]);
        +	} EVP_AES_XTS_CTX;
        +
        +typedef struct
        +	{
        +	AES_KEY ks;		/* AES key schedule to use */
        +	int key_set;		/* Set if key initialised */
        +	int iv_set;		/* Set if an iv is set */
        +	int tag_set;		/* Set if tag is valid */
        +	int len_set;		/* Set if message length set */
        +	int L, M;		/* L and M parameters from RFC3610 */
        +	CCM128_CONTEXT ccm;
        +	ccm128_f str;
        +	} EVP_AES_CCM_CTX;
        +
        +#define MAXBITCHUNK	((size_t)1<<(sizeof(size_t)*8-4))
        +
        +#ifdef VPAES_ASM
        +int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
        +			AES_KEY *key);
        +int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
        +			AES_KEY *key);
        +
        +void vpaes_encrypt(const unsigned char *in, unsigned char *out,
        +			const AES_KEY *key);
        +void vpaes_decrypt(const unsigned char *in, unsigned char *out,
        +			const AES_KEY *key);
        +
        +void vpaes_cbc_encrypt(const unsigned char *in,
        +			unsigned char *out,
        +			size_t length,
        +			const AES_KEY *key,
        +			unsigned char *ivec, int enc);
        +#endif
        +#ifdef BSAES_ASM
        +void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t length, const AES_KEY *key,
        +			unsigned char ivec[16], int enc);
        +void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
        +			size_t len, const AES_KEY *key,
        +			const unsigned char ivec[16]);
        +void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
        +			size_t len, const AES_KEY *key1,
        +			const AES_KEY *key2, const unsigned char iv[16]);
        +void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
        +			size_t len, const AES_KEY *key1,
        +			const AES_KEY *key2, const unsigned char iv[16]);
        +#endif
        +#ifdef AES_CTR_ASM
        +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t blocks, const AES_KEY *key,
        +			const unsigned char ivec[AES_BLOCK_SIZE]);
        +#endif
        +#ifdef AES_XTS_ASM
        +void AES_xts_encrypt(const char *inp,char *out,size_t len,
        +			const AES_KEY *key1, const AES_KEY *key2,
        +			const unsigned char iv[16]);
        +void AES_xts_decrypt(const char *inp,char *out,size_t len,
        +			const AES_KEY *key1, const AES_KEY *key2,
        +			const unsigned char iv[16]);
        +#endif
        +
        +#if	defined(AES_ASM) && !defined(I386_ONLY) &&	(  \
        +	((defined(__i386)	|| defined(__i386__)	|| \
        +	  defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
        +	defined(__x86_64)	|| defined(__x86_64__)	|| \
        +	defined(_M_AMD64)	|| defined(_M_X64)	|| \
        +	defined(__INTEL__)				)
        +
        +extern unsigned int OPENSSL_ia32cap_P[2];
        +
        +#ifdef VPAES_ASM
        +#define VPAES_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(41-32)))
        +#endif
        +#ifdef BSAES_ASM
        +#define BSAES_CAPABLE	VPAES_CAPABLE
        +#endif
        +/*
        + * AES-NI section
        + */
        +#define	AESNI_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(57-32)))
        +
        +int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
        +			AES_KEY *key);
        +int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
        +			AES_KEY *key);
        +
        +void aesni_encrypt(const unsigned char *in, unsigned char *out,
        +			const AES_KEY *key);
        +void aesni_decrypt(const unsigned char *in, unsigned char *out,
        +			const AES_KEY *key);
        +
        +void aesni_ecb_encrypt(const unsigned char *in,
        +			unsigned char *out,
        +			size_t length,
        +			const AES_KEY *key,
        +			int enc);
        +void aesni_cbc_encrypt(const unsigned char *in,
        +			unsigned char *out,
        +			size_t length,
        +			const AES_KEY *key,
        +			unsigned char *ivec, int enc);
        +
        +void aesni_ctr32_encrypt_blocks(const unsigned char *in,
        +			unsigned char *out,
        +			size_t blocks,
        +			const void *key,
        +			const unsigned char *ivec);
        +
        +void aesni_xts_encrypt(const unsigned char *in,
        +			unsigned char *out,
        +			size_t length,
        +			const AES_KEY *key1, const AES_KEY *key2,
        +			const unsigned char iv[16]);
        +
        +void aesni_xts_decrypt(const unsigned char *in,
        +			unsigned char *out,
        +			size_t length,
        +			const AES_KEY *key1, const AES_KEY *key2,
        +			const unsigned char iv[16]);
        +
        +void aesni_ccm64_encrypt_blocks (const unsigned char *in,
        +			unsigned char *out,
        +			size_t blocks,
        +			const void *key,
        +			const unsigned char ivec[16],
        +			unsigned char cmac[16]);
        +
        +void aesni_ccm64_decrypt_blocks (const unsigned char *in,
        +			unsigned char *out,
        +			size_t blocks,
        +			const void *key,
        +			const unsigned char ivec[16],
        +			unsigned char cmac[16]);
        +
        +static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +		   const unsigned char *iv, int enc)
        +	{
        +	int ret, mode;
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	mode = ctx->cipher->flags & EVP_CIPH_MODE;
        +	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
        +	    && !enc)
        +		{ 
        +		ret = aesni_set_decrypt_key(key, ctx->key_len*8, ctx->cipher_data);
        +		dat->block	= (block128_f)aesni_decrypt;
        +		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
        +					(cbc128_f)aesni_cbc_encrypt :
        +					NULL;
        +		}
        +	else	{
        +		ret = aesni_set_encrypt_key(key, ctx->key_len*8, ctx->cipher_data);
        +		dat->block	= (block128_f)aesni_encrypt;
        +		if (mode==EVP_CIPH_CBC_MODE)
        +			dat->stream.cbc	= (cbc128_f)aesni_cbc_encrypt;
        +		else if (mode==EVP_CIPH_CTR_MODE)
        +			dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
        +		else
        +			dat->stream.cbc = NULL;
        +		}
        +
        +	if(ret < 0)
        +		{
        +		EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in, size_t len)
        +{
        +	aesni_cbc_encrypt(in,out,len,ctx->cipher_data,ctx->iv,ctx->encrypt);
        +
        +	return 1;
        +}
        +
        +static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in, size_t len)
        +{
        +	size_t	bl = ctx->cipher->block_size;
        +
        +	if (len<bl)	return 1;
        +
        +	aesni_ecb_encrypt(in,out,len,ctx->cipher_data,ctx->encrypt);
        +
        +	return 1;
        +}
        +
        +#define aesni_ofb_cipher aes_ofb_cipher
        +static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len);
        +
        +#define aesni_cfb_cipher aes_cfb_cipher
        +static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len);
        +
        +#define aesni_cfb8_cipher aes_cfb8_cipher
        +static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len);
        +
        +#define aesni_cfb1_cipher aes_cfb1_cipher
        +static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len);
        +
        +#define aesni_ctr_cipher aes_ctr_cipher
        +static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len);
        +
        +static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                        const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
        +	if (!iv && !key)
        +		return 1;
        +	if (key)
        +		{
        +		aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
        +		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
        +				(block128_f)aesni_encrypt);
        +		gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
        +		/* If we have an iv can set it directly, otherwise use
        +		 * saved IV.
        +		 */
        +		if (iv == NULL && gctx->iv_set)
        +			iv = gctx->iv;
        +		if (iv)
        +			{
        +			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
        +			gctx->iv_set = 1;
        +			}
        +		gctx->key_set = 1;
        +		}
        +	else
        +		{
        +		/* If key set use IV, otherwise copy */
        +		if (gctx->key_set)
        +			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
        +		else
        +			memcpy(gctx->iv, iv, gctx->ivlen);
        +		gctx->iv_set = 1;
        +		gctx->iv_gen = 0;
        +		}
        +	return 1;
        +	}
        +
        +#define aesni_gcm_cipher aes_gcm_cipher
        +static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len);
        +
        +static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                        const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
        +	if (!iv && !key)
        +		return 1;
        +
        +	if (key)
        +		{
        +		/* key_len is two AES keys */
        +		if (enc)
        +			{
        +			aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
        +			xctx->xts.block1 = (block128_f)aesni_encrypt;
        +			xctx->stream = aesni_xts_encrypt;
        +			}
        +		else
        +			{
        +			aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
        +			xctx->xts.block1 = (block128_f)aesni_decrypt;
        +			xctx->stream = aesni_xts_decrypt;
        +			}
        +
        +		aesni_set_encrypt_key(key + ctx->key_len/2,
        +						ctx->key_len * 4, &xctx->ks2);
        +		xctx->xts.block2 = (block128_f)aesni_encrypt;
        +
        +		xctx->xts.key1 = &xctx->ks1;
        +		}
        +
        +	if (iv)
        +		{
        +		xctx->xts.key2 = &xctx->ks2;
        +		memcpy(ctx->iv, iv, 16);
        +		}
        +
        +	return 1;
        +	}
        +
        +#define aesni_xts_cipher aes_xts_cipher
        +static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len);
        +
        +static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                        const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
        +	if (!iv && !key)
        +		return 1;
        +	if (key)
        +		{
        +		aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
        +		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
        +					&cctx->ks, (block128_f)aesni_encrypt);
        +		cctx->str = enc?(ccm128_f)aesni_ccm64_encrypt_blocks :
        +				(ccm128_f)aesni_ccm64_decrypt_blocks;
        +		cctx->key_set = 1;
        +		}
        +	if (iv)
        +		{
        +		memcpy(ctx->iv, iv, 15 - cctx->L);
        +		cctx->iv_set = 1;
        +		}
        +	return 1;
        +	}
        +
        +#define aesni_ccm_cipher aes_ccm_cipher
        +static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len);
        +
        +#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
        +static const EVP_CIPHER aesni_##keylen##_##mode = { \
        +	nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
        +	flags|EVP_CIPH_##MODE##_MODE,	\
        +	aesni_init_key,			\
        +	aesni_##mode##_cipher,		\
        +	NULL,				\
        +	sizeof(EVP_AES_KEY),		\
        +	NULL,NULL,NULL,NULL }; \
        +static const EVP_CIPHER aes_##keylen##_##mode = { \
        +	nid##_##keylen##_##nmode,blocksize,	\
        +	keylen/8,ivlen, \
        +	flags|EVP_CIPH_##MODE##_MODE,	\
        +	aes_init_key,			\
        +	aes_##mode##_cipher,		\
        +	NULL,				\
        +	sizeof(EVP_AES_KEY),		\
        +	NULL,NULL,NULL,NULL }; \
        +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
        +{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
        +
        +#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
        +static const EVP_CIPHER aesni_##keylen##_##mode = { \
        +	nid##_##keylen##_##mode,blocksize, \
        +	(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
        +	flags|EVP_CIPH_##MODE##_MODE,	\
        +	aesni_##mode##_init_key,	\
        +	aesni_##mode##_cipher,		\
        +	aes_##mode##_cleanup,		\
        +	sizeof(EVP_AES_##MODE##_CTX),	\
        +	NULL,NULL,aes_##mode##_ctrl,NULL }; \
        +static const EVP_CIPHER aes_##keylen##_##mode = { \
        +	nid##_##keylen##_##mode,blocksize, \
        +	(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
        +	flags|EVP_CIPH_##MODE##_MODE,	\
        +	aes_##mode##_init_key,		\
        +	aes_##mode##_cipher,		\
        +	aes_##mode##_cleanup,		\
        +	sizeof(EVP_AES_##MODE##_CTX),	\
        +	NULL,NULL,aes_##mode##_ctrl,NULL }; \
        +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
        +{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
        +
        +#else
        +
        +#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
        +static const EVP_CIPHER aes_##keylen##_##mode = { \
        +	nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
        +	flags|EVP_CIPH_##MODE##_MODE,	\
        +	aes_init_key,			\
        +	aes_##mode##_cipher,		\
        +	NULL,				\
        +	sizeof(EVP_AES_KEY),		\
        +	NULL,NULL,NULL,NULL }; \
        +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
        +{ return &aes_##keylen##_##mode; }
        +
        +#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
        +static const EVP_CIPHER aes_##keylen##_##mode = { \
        +	nid##_##keylen##_##mode,blocksize, \
        +	(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
        +	flags|EVP_CIPH_##MODE##_MODE,	\
        +	aes_##mode##_init_key,		\
        +	aes_##mode##_cipher,		\
        +	aes_##mode##_cleanup,		\
        +	sizeof(EVP_AES_##MODE##_CTX),	\
        +	NULL,NULL,aes_##mode##_ctrl,NULL }; \
        +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
        +{ return &aes_##keylen##_##mode; }
        +#endif
        +
        +#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)		\
        +	BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
        +	BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
        +	BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
        +	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
        +	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)	\
        +	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)	\
        +	BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
        +
        +static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +		   const unsigned char *iv, int enc)
        +	{
        +	int ret, mode;
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	mode = ctx->cipher->flags & EVP_CIPH_MODE;
        +	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
        +	    && !enc)
        +#ifdef BSAES_CAPABLE
        +	    if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
        +		{
        +		ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
        +		dat->block	= (block128_f)AES_decrypt;
        +		dat->stream.cbc	= (cbc128_f)bsaes_cbc_encrypt;
        +		}
        +	    else
        +#endif
        +#ifdef VPAES_CAPABLE
        +	    if (VPAES_CAPABLE)
        +		{
        +		ret = vpaes_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
        +		dat->block	= (block128_f)vpaes_decrypt;
        +		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
        +					(cbc128_f)vpaes_cbc_encrypt :
        +					NULL;
        +		}
        +	    else
        +#endif
        +		{
        +		ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
        +		dat->block	= (block128_f)AES_decrypt;
        +		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
        +					(cbc128_f)AES_cbc_encrypt :
        +					NULL;
        +		}
        +	else
        +#ifdef BSAES_CAPABLE
        +	    if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
        +		{
        +		ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
        +		dat->block	= (block128_f)AES_encrypt;
        +		dat->stream.ctr	= (ctr128_f)bsaes_ctr32_encrypt_blocks;
        +		}
        +	    else
        +#endif
        +#ifdef VPAES_CAPABLE
        +	    if (VPAES_CAPABLE)
        +		{
        +		ret = vpaes_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
        +		dat->block	= (block128_f)vpaes_encrypt;
        +		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
        +					(cbc128_f)vpaes_cbc_encrypt :
        +					NULL;
        +		}
        +	    else
        +#endif
        +		{
        +		ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
        +		dat->block	= (block128_f)AES_encrypt;
        +		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
        +					(cbc128_f)AES_cbc_encrypt :
        +					NULL;
        +#ifdef AES_CTR_ASM
        +		if (mode==EVP_CIPH_CTR_MODE)
        +			dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
        +#endif
        +		}
        +
        +	if(ret < 0)
        +		{
        +		EVPerr(EVP_F_AES_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in, size_t len)
        +{
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	if (dat->stream.cbc)
        +		(*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
        +	else if (ctx->encrypt)
        +		CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
        +	else
        +		CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
        +
        +	return 1;
        +}
        +
        +static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in, size_t len)
        +{
        +	size_t	bl = ctx->cipher->block_size;
        +	size_t	i;
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	if (len<bl)	return 1;
        +
        +	for (i=0,len-=bl;i<=len;i+=bl)
        +		(*dat->block)(in+i,out+i,&dat->ks);
        +
        +	return 1;
        +}
        +
        +static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len)
        +{
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
        +			ctx->iv,&ctx->num,dat->block);
        +	return 1;
        +}
        +
        +static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len)
        +{
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
        +			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
        +	return 1;
        +}
        +
        +static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len)
        +{
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
        +			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
        +	return 1;
        +}
        +
        +static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +	const unsigned char *in,size_t len)
        +{
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
        +		CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
        +			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
        +		return 1;
        +	}
        +
        +	while (len>=MAXBITCHUNK) {
        +		CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
        +			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
        +		len-=MAXBITCHUNK;
        +	}
        +	if (len)
        +		CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
        +			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
        +	
        +	return 1;
        +}
        +
        +static int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len)
        +{
        +	unsigned int num = ctx->num;
        +	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
        +
        +	if (dat->stream.ctr)
        +		CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
        +			ctx->iv,ctx->buf,&num,dat->stream.ctr);
        +	else
        +		CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
        +			ctx->iv,ctx->buf,&num,dat->block);
        +	ctx->num = (size_t)num;
        +	return 1;
        +}
        +
        +BLOCK_CIPHER_generic_pack(NID_aes,128,EVP_CIPH_FLAG_FIPS)
        +BLOCK_CIPHER_generic_pack(NID_aes,192,EVP_CIPH_FLAG_FIPS)
        +BLOCK_CIPHER_generic_pack(NID_aes,256,EVP_CIPH_FLAG_FIPS)
        +
        +static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
        +	{
        +	EVP_AES_GCM_CTX *gctx = c->cipher_data;
        +	OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
        +	if (gctx->iv != c->iv)
        +		OPENSSL_free(gctx->iv);
        +	return 1;
        +	}
        +
        +/* increment counter (64-bit int) by 1 */
        +static void ctr64_inc(unsigned char *counter) {
        +	int n=8;
        +	unsigned char  c;
        +
        +	do {
        +		--n;
        +		c = counter[n];
        +		++c;
        +		counter[n] = c;
        +		if (c) return;
        +	} while (n);
        +}
        +
        +static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
        +	{
        +	EVP_AES_GCM_CTX *gctx = c->cipher_data;
        +	switch (type)
        +		{
        +	case EVP_CTRL_INIT:
        +		gctx->key_set = 0;
        +		gctx->iv_set = 0;
        +		gctx->ivlen = c->cipher->iv_len;
        +		gctx->iv = c->iv;
        +		gctx->taglen = -1;
        +		gctx->iv_gen = 0;
        +		gctx->tls_aad_len = -1;
        +		return 1;
        +
        +	case EVP_CTRL_GCM_SET_IVLEN:
        +		if (arg <= 0)
        +			return 0;
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
        +						 && arg < 12)
        +			return 0;
        +#endif
        +		/* Allocate memory for IV if needed */
        +		if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen))
        +			{
        +			if (gctx->iv != c->iv)
        +				OPENSSL_free(gctx->iv);
        +			gctx->iv = OPENSSL_malloc(arg);
        +			if (!gctx->iv)
        +				return 0;
        +			}
        +		gctx->ivlen = arg;
        +		return 1;
        +
        +	case EVP_CTRL_GCM_SET_TAG:
        +		if (arg <= 0 || arg > 16 || c->encrypt)
        +			return 0;
        +		memcpy(c->buf, ptr, arg);
        +		gctx->taglen = arg;
        +		return 1;
        +
        +	case EVP_CTRL_GCM_GET_TAG:
        +		if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
        +			return 0;
        +		memcpy(ptr, c->buf, arg);
        +		return 1;
        +
        +	case EVP_CTRL_GCM_SET_IV_FIXED:
        +		/* Special case: -1 length restores whole IV */
        +		if (arg == -1)
        +			{
        +			memcpy(gctx->iv, ptr, gctx->ivlen);
        +			gctx->iv_gen = 1;
        +			return 1;
        +			}
        +		/* Fixed field must be at least 4 bytes and invocation field
        +		 * at least 8.
        +		 */
        +		if ((arg < 4) || (gctx->ivlen - arg) < 8)
        +			return 0;
        +		if (arg)
        +			memcpy(gctx->iv, ptr, arg);
        +		if (c->encrypt &&
        +			RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
        +			return 0;
        +		gctx->iv_gen = 1;
        +		return 1;
        +
        +	case EVP_CTRL_GCM_IV_GEN:
        +		if (gctx->iv_gen == 0 || gctx->key_set == 0)
        +			return 0;
        +		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
        +		if (arg <= 0 || arg > gctx->ivlen)
        +			arg = gctx->ivlen;
        +		memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
        +		/* Invocation field will be at least 8 bytes in size and
        +		 * so no need to check wrap around or increment more than
        +		 * last 8 bytes.
        +		 */
        +		ctr64_inc(gctx->iv + gctx->ivlen - 8);
        +		gctx->iv_set = 1;
        +		return 1;
        +
        +	case EVP_CTRL_GCM_SET_IV_INV:
        +		if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
        +			return 0;
        +		memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
        +		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
        +		gctx->iv_set = 1;
        +		return 1;
        +
        +	case EVP_CTRL_AEAD_TLS1_AAD:
        +		/* Save the AAD for later use */
        +		if (arg != 13)
        +			return 0;
        +		memcpy(c->buf, ptr, arg);
        +		gctx->tls_aad_len = arg;
        +			{
        +			unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1];
        +			/* Correct length for explicit IV */
        +			len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +			/* If decrypting correct for tag too */
        +			if (!c->encrypt)
        +				len -= EVP_GCM_TLS_TAG_LEN;
        +                        c->buf[arg-2] = len>>8;
        +                        c->buf[arg-1] = len & 0xff;
        +			}
        +		/* Extra padding: tag appended to record */
        +		return EVP_GCM_TLS_TAG_LEN;
        +
        +	default:
        +		return -1;
        +
        +		}
        +	}
        +
        +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                        const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
        +	if (!iv && !key)
        +		return 1;
        +	if (key)
        +		{ do {
        +#ifdef BSAES_CAPABLE
        +		if (BSAES_CAPABLE)
        +			{
        +			AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
        +			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
        +					(block128_f)AES_encrypt);
        +			gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
        +			break;
        +			}
        +		else
        +#endif
        +#ifdef VPAES_CAPABLE
        +		if (VPAES_CAPABLE)
        +			{
        +			vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
        +			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
        +					(block128_f)vpaes_encrypt);
        +			gctx->ctr = NULL;
        +			break;
        +			}
        +#endif
        +		AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
        +		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
        +#ifdef AES_CTR_ASM
        +		gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
        +#else
        +		gctx->ctr = NULL;
        +#endif
        +		} while (0);
        +
        +		/* If we have an iv can set it directly, otherwise use
        +		 * saved IV.
        +		 */
        +		if (iv == NULL && gctx->iv_set)
        +			iv = gctx->iv;
        +		if (iv)
        +			{
        +			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
        +			gctx->iv_set = 1;
        +			}
        +		gctx->key_set = 1;
        +		}
        +	else
        +		{
        +		/* If key set use IV, otherwise copy */
        +		if (gctx->key_set)
        +			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
        +		else
        +			memcpy(gctx->iv, iv, gctx->ivlen);
        +		gctx->iv_set = 1;
        +		gctx->iv_gen = 0;
        +		}
        +	return 1;
        +	}
        +
        +/* Handle TLS GCM packet format. This consists of the last portion of the IV
        + * followed by the payload and finally the tag. On encrypt generate IV,
        + * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
        + * and verify tag.
        + */
        +
        +static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len)
        +	{
        +	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
        +	int rv = -1;
        +	/* Encrypt/decrypt must be performed in place */
        +	if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN+EVP_GCM_TLS_TAG_LEN))
        +		return -1;
        +	/* Set IV from start of buffer or generate IV and write to start
        +	 * of buffer.
        +	 */
        +	if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
        +				EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
        +				EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
        +		goto err;
        +	/* Use saved AAD */
        +	if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
        +		goto err;
        +	/* Fix buffer and length to point to payload */
        +	in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +	out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +	len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
        +	if (ctx->encrypt)
        +		{
        +		/* Encrypt payload */
        +		if (gctx->ctr)
        +			{
        +			if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
        +							in, out, len,
        +							gctx->ctr))
        +				goto err;
        +			}
        +		else	{
        +			if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
        +				goto err;
        +			}
        +		out += len;
        +		/* Finally write tag */
        +		CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
        +		rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
        +		}
        +	else
        +		{
        +		/* Decrypt */
        +		if (gctx->ctr)
        +			{
        +			if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
        +							in, out, len,
        +							gctx->ctr))
        +				goto err;
        +			}
        +		else	{
        +			if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
        +				goto err;
        +			}
        +		/* Retrieve tag */
        +		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
        +					EVP_GCM_TLS_TAG_LEN);
        +		/* If tag mismatch wipe buffer */
        +		if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
        +			{
        +			OPENSSL_cleanse(out, len);
        +			goto err;
        +			}
        +		rv = len;
        +		}
        +
        +	err:
        +	gctx->iv_set = 0;
        +	gctx->tls_aad_len = -1;
        +	return rv;
        +	}
        +
        +static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len)
        +	{
        +	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
        +	/* If not set up, return error */
        +	if (!gctx->key_set)
        +		return -1;
        +
        +	if (gctx->tls_aad_len >= 0)
        +		return aes_gcm_tls_cipher(ctx, out, in, len);
        +
        +	if (!gctx->iv_set)
        +		return -1;
        +	if (in)
        +		{
        +		if (out == NULL)
        +			{
        +			if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
        +				return -1;
        +			}
        +		else if (ctx->encrypt)
        +			{
        +			if (gctx->ctr)
        +				{
        +				if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
        +							in, out, len,
        +							gctx->ctr))
        +					return -1;
        +				}
        +			else	{
        +				if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
        +					return -1;
        +				}
        +			}
        +		else
        +			{
        +			if (gctx->ctr)
        +				{
        +				if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
        +							in, out, len,
        +							gctx->ctr))
        +					return -1;
        +				}
        +			else	{
        +				if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
        +					return -1;
        +				}
        +			}
        +		return len;
        +		}
        +	else
        +		{
        +		if (!ctx->encrypt)
        +			{
        +			if (gctx->taglen < 0)
        +				return -1;
        +			if (CRYPTO_gcm128_finish(&gctx->gcm,
        +					ctx->buf, gctx->taglen) != 0)
        +				return -1;
        +			gctx->iv_set = 0;
        +			return 0;
        +			}
        +		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
        +		gctx->taglen = 16;
        +		/* Don't reuse the IV */
        +		gctx->iv_set = 0;
        +		return 0;
        +		}
        +
        +	}
        +
        +#define CUSTOM_FLAGS	(EVP_CIPH_FLAG_DEFAULT_ASN1 \
        +		| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
        +		| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
        +
        +BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,
        +		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
        +BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,
        +		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
        +BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,
        +		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
        +
        +static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
        +	{
        +	EVP_AES_XTS_CTX *xctx = c->cipher_data;
        +	if (type != EVP_CTRL_INIT)
        +		return -1;
        +	/* key1 and key2 are used as an indicator both key and IV are set */
        +	xctx->xts.key1 = NULL;
        +	xctx->xts.key2 = NULL;
        +	return 1;
        +	}
        +
        +static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                        const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
        +	if (!iv && !key)
        +		return 1;
        +
        +	if (key) do
        +		{
        +#ifdef AES_XTS_ASM
        +		xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
        +#else
        +		xctx->stream = NULL;
        +#endif
        +		/* key_len is two AES keys */
        +#ifdef BSAES_CAPABLE
        +		if (BSAES_CAPABLE)
        +			xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
        +		else
        +#endif
        +#ifdef VPAES_CAPABLE
        +		if (VPAES_CAPABLE)
        +		    {
        +		    if (enc)
        +			{
        +			vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
        +			xctx->xts.block1 = (block128_f)vpaes_encrypt;
        +			}
        +		    else
        +			{
        +			vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
        +			xctx->xts.block1 = (block128_f)vpaes_decrypt;
        +			}
        +
        +		vpaes_set_encrypt_key(key + ctx->key_len/2,
        +						ctx->key_len * 4, &xctx->ks2);
        +		xctx->xts.block2 = (block128_f)vpaes_encrypt;
        +
        +		xctx->xts.key1 = &xctx->ks1;
        +		break;
        +		}
        +#endif
        +		if (enc)
        +			{
        +			AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
        +			xctx->xts.block1 = (block128_f)AES_encrypt;
        +			}
        +		else
        +			{
        +			AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
        +			xctx->xts.block1 = (block128_f)AES_decrypt;
        +			}
        +
        +		AES_set_encrypt_key(key + ctx->key_len/2,
        +						ctx->key_len * 4, &xctx->ks2);
        +		xctx->xts.block2 = (block128_f)AES_encrypt;
        +
        +		xctx->xts.key1 = &xctx->ks1;
        +		} while (0);
        +
        +	if (iv)
        +		{
        +		xctx->xts.key2 = &xctx->ks2;
        +		memcpy(ctx->iv, iv, 16);
        +		}
        +
        +	return 1;
        +	}
        +
        +static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len)
        +	{
        +	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
        +	if (!xctx->xts.key1 || !xctx->xts.key2)
        +		return 0;
        +	if (!out || !in || len<AES_BLOCK_SIZE)
        +		return 0;
        +#ifdef OPENSSL_FIPS
        +	/* Requirement of SP800-38E */
        +	if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
        +			(len > (1UL<<20)*16))
        +		{
        +		EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
        +		return 0;
        +		}
        +#endif
        +	if (xctx->stream)
        +		(*xctx->stream)(in, out, len,
        +				xctx->xts.key1, xctx->xts.key2, ctx->iv);
        +	else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
        +								ctx->encrypt))
        +		return 0;
        +	return 1;
        +	}
        +
        +#define aes_xts_cleanup NULL
        +
        +#define XTS_FLAGS	(EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
        +			 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
        +
        +BLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
        +BLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
        +
        +static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
        +	{
        +	EVP_AES_CCM_CTX *cctx = c->cipher_data;
        +	switch (type)
        +		{
        +	case EVP_CTRL_INIT:
        +		cctx->key_set = 0;
        +		cctx->iv_set = 0;
        +		cctx->L = 8;
        +		cctx->M = 12;
        +		cctx->tag_set = 0;
        +		cctx->len_set = 0;
        +		return 1;
        +
        +	case EVP_CTRL_CCM_SET_IVLEN:
        +		arg = 15 - arg;
        +	case EVP_CTRL_CCM_SET_L:
        +		if (arg < 2 || arg > 8)
        +			return 0;
        +		cctx->L = arg;
        +		return 1;
        +
        +	case EVP_CTRL_CCM_SET_TAG:
        +		if ((arg & 1) || arg < 4 || arg > 16)
        +			return 0;
        +		if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
        +			return 0;
        +		if (ptr)
        +			{
        +			cctx->tag_set = 1;
        +			memcpy(c->buf, ptr, arg);
        +			}
        +		cctx->M = arg;
        +		return 1;
        +
        +	case EVP_CTRL_CCM_GET_TAG:
        +		if (!c->encrypt || !cctx->tag_set)
        +			return 0;
        +		if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
        +			return 0;
        +		cctx->tag_set = 0;
        +		cctx->iv_set = 0;
        +		cctx->len_set = 0;
        +		return 1;
        +
        +	default:
        +		return -1;
        +
        +		}
        +	}
        +
        +static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                        const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
        +	if (!iv && !key)
        +		return 1;
        +	if (key) do
        +		{
        +#ifdef VPAES_CAPABLE
        +		if (VPAES_CAPABLE)
        +			{
        +			vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
        +			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
        +					&cctx->ks, (block128_f)vpaes_encrypt);
        +			cctx->str = NULL;
        +			cctx->key_set = 1;
        +			break;
        +			}
        +#endif
        +		AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
        +		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
        +					&cctx->ks, (block128_f)AES_encrypt);
        +		cctx->str = NULL;
        +		cctx->key_set = 1;
        +		} while (0);
        +	if (iv)
        +		{
        +		memcpy(ctx->iv, iv, 15 - cctx->L);
        +		cctx->iv_set = 1;
        +		}
        +	return 1;
        +	}
        +
        +static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		const unsigned char *in, size_t len)
        +	{
        +	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
        +	CCM128_CONTEXT *ccm = &cctx->ccm;
        +	/* If not set up, return error */
        +	if (!cctx->iv_set && !cctx->key_set)
        +		return -1;
        +	if (!ctx->encrypt && !cctx->tag_set)
        +		return -1;
        +	if (!out)
        +		{
        +		if (!in)
        +			{
        +			if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,len))
        +				return -1;
        +			cctx->len_set = 1;
        +			return len;
        +			}
        +		/* If have AAD need message length */
        +		if (!cctx->len_set && len)
        +			return -1;
        +		CRYPTO_ccm128_aad(ccm, in, len);
        +		return len;
        +		}
        +	/* EVP_*Final() doesn't return any data */
        +	if (!in)
        +		return 0;
        +	/* If not set length yet do it */
        +	if (!cctx->len_set)
        +		{
        +		if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
        +			return -1;
        +		cctx->len_set = 1;
        +		}
        +	if (ctx->encrypt)
        +		{
        +		if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
        +						cctx->str) :
        +				CRYPTO_ccm128_encrypt(ccm, in, out, len))
        +			return -1;
        +		cctx->tag_set = 1;
        +		return len;
        +		}
        +	else
        +		{
        +		int rv = -1;
        +		if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
        +						cctx->str) :
        +				!CRYPTO_ccm128_decrypt(ccm, in, out, len))
        +			{
        +			unsigned char tag[16];
        +			if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
        +				{
        +				if (!memcmp(tag, ctx->buf, cctx->M))
        +					rv = len;
        +				}
        +			}
        +		if (rv == -1)
        +			OPENSSL_cleanse(out, len);
        +		cctx->iv_set = 0;
        +		cctx->tag_set = 0;
        +		cctx->len_set = 0;
        +		return rv;
        +		}
        +
        +	}
        +
        +#define aes_ccm_cleanup NULL
        +
        +BLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
        +BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
        +BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
        +
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/vendor/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
        new file mode 100644
        index 000000000..483e04b60
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
        @@ -0,0 +1,580 @@
        +/* ====================================================================
        + * Copyright (c) 2011-2013 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/opensslconf.h>
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/aes.h>
        +#include <openssl/sha.h>
        +#include "evp_locl.h"
        +
        +#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
        +#define EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
        +#define EVP_CTRL_AEAD_TLS1_AAD		0x16
        +#define EVP_CTRL_AEAD_SET_MAC_KEY	0x17
        +#endif
        +
        +#if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
        +#define EVP_CIPH_FLAG_DEFAULT_ASN1 0
        +#endif
        +
        +#define TLS1_1_VERSION 0x0302
        +
        +typedef struct
        +    {
        +    AES_KEY		ks;
        +    SHA_CTX		head,tail,md;
        +    size_t		payload_length;	/* AAD length in decrypt case */
        +    union {
        +	unsigned int	tls_ver;
        +    	unsigned char	tls_aad[16];	/* 13 used */
        +    } aux;
        +    } EVP_AES_HMAC_SHA1;
        +
        +#define NO_PAYLOAD_LENGTH	((size_t)-1)
        +
        +#if	defined(AES_ASM) &&	( \
        +	defined(__x86_64)	|| defined(__x86_64__)	|| \
        +	defined(_M_AMD64)	|| defined(_M_X64)	|| \
        +	defined(__INTEL__)	)
        +
        +#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
        +# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
        +#endif
        +
        +extern unsigned int OPENSSL_ia32cap_P[2];
        +#define AESNI_CAPABLE   (1<<(57-32))
        +
        +int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
        +			      AES_KEY *key);
        +int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
        +			      AES_KEY *key);
        +
        +void aesni_cbc_encrypt(const unsigned char *in,
        +			   unsigned char *out,
        +			   size_t length,
        +			   const AES_KEY *key,
        +			   unsigned char *ivec, int enc);
        +
        +void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
        +		const AES_KEY *key, unsigned char iv[16],
        +		SHA_CTX *ctx,const void *in0);
        +
        +#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
        +
        +static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
        +			const unsigned char *inkey,
        +			const unsigned char *iv, int enc)
        +	{
        +	EVP_AES_HMAC_SHA1 *key = data(ctx);
        +	int ret;
        +
        +	if (enc)
        +		ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
        +	else
        +		ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
        +
        +	SHA1_Init(&key->head);	/* handy when benchmarking */
        +	key->tail = key->head;
        +	key->md   = key->head;
        +
        +	key->payload_length = NO_PAYLOAD_LENGTH;
        +
        +	return ret<0?0:1;
        +	}
        +
        +#define	STITCHED_CALL
        +
        +#if !defined(STITCHED_CALL)
        +#define	aes_off 0
        +#endif
        +
        +void sha1_block_data_order (void *c,const void *p,size_t len);
        +
        +static void sha1_update(SHA_CTX *c,const void *data,size_t len)
        +{	const unsigned char *ptr = data;
        +	size_t res;
        +
        +	if ((res = c->num)) {
        +		res = SHA_CBLOCK-res;
        +		if (len<res) res=len;
        +		SHA1_Update (c,ptr,res);
        +		ptr += res;
        +		len -= res;
        +	}
        +
        +	res = len % SHA_CBLOCK;
        +	len -= res;
        +
        +	if (len) {
        +		sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
        +
        +		ptr += len;
        +		c->Nh += len>>29;
        +		c->Nl += len<<=3;
        +		if (c->Nl<(unsigned int)len) c->Nh++;
        +	}
        +
        +	if (res)
        +		SHA1_Update(c,ptr,res);
        +}
        +
        +#ifdef SHA1_Update
        +#undef SHA1_Update
        +#endif
        +#define SHA1_Update sha1_update
        +
        +static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		      const unsigned char *in, size_t len)
        +	{
        +	EVP_AES_HMAC_SHA1 *key = data(ctx);
        +	unsigned int l;
        +	size_t	plen = key->payload_length,
        +		iv = 0,		/* explicit IV in TLS 1.1 and later */
        +		sha_off = 0;
        +#if defined(STITCHED_CALL)
        +	size_t	aes_off = 0,
        +		blocks;
        +
        +	sha_off = SHA_CBLOCK-key->md.num;
        +#endif
        +
        +	key->payload_length = NO_PAYLOAD_LENGTH;
        +
        +	if (len%AES_BLOCK_SIZE) return 0;
        +
        +	if (ctx->encrypt) {
        +		if (plen==NO_PAYLOAD_LENGTH)
        +			plen = len;
        +		else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
        +			return 0;
        +		else if (key->aux.tls_ver >= TLS1_1_VERSION)
        +			iv = AES_BLOCK_SIZE;
        +
        +#if defined(STITCHED_CALL)
        +		if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
        +			SHA1_Update(&key->md,in+iv,sha_off);
        +
        +			aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
        +				ctx->iv,&key->md,in+iv+sha_off);
        +			blocks *= SHA_CBLOCK;
        +			aes_off += blocks;
        +			sha_off += blocks;
        +			key->md.Nh += blocks>>29;
        +			key->md.Nl += blocks<<=3;
        +			if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
        +		} else {
        +			sha_off = 0;
        +		}
        +#endif
        +		sha_off += iv;
        +		SHA1_Update(&key->md,in+sha_off,plen-sha_off);
        +
        +		if (plen!=len)	{	/* "TLS" mode of operation */
        +			if (in!=out)
        +				memcpy(out+aes_off,in+aes_off,plen-aes_off);
        +
        +			/* calculate HMAC and append it to payload */
        +			SHA1_Final(out+plen,&key->md);
        +			key->md = key->tail;
        +			SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
        +			SHA1_Final(out+plen,&key->md);
        +
        +			/* pad the payload|hmac */
        +			plen += SHA_DIGEST_LENGTH;
        +			for (l=len-plen-1;plen<len;plen++) out[plen]=l;
        +			/* encrypt HMAC|padding at once */
        +			aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
        +					&key->ks,ctx->iv,1);
        +		} else {
        +			aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
        +					&key->ks,ctx->iv,1);
        +		}
        +	} else {
        +		union { unsigned int  u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
        +			unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac;
        +
        +		/* arrange cache line alignment */
        +		pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32));
        +
        +		/* decrypt HMAC|padding at once */
        +		aesni_cbc_encrypt(in,out,len,
        +				&key->ks,ctx->iv,0);
        +
        +		if (plen) {	/* "TLS" mode of operation */
        +			size_t inp_len, mask, j, i;
        +			unsigned int res, maxpad, pad, bitlen;
        +			int ret = 1;
        +			union {	unsigned int  u[SHA_LBLOCK];
        +				unsigned char c[SHA_CBLOCK]; }
        +				*data = (void *)key->md.data;
        +
        +			if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
        +			    >= TLS1_1_VERSION)
        +				iv = AES_BLOCK_SIZE;
        +
        +			if (len<(iv+SHA_DIGEST_LENGTH+1))
        +				return 0;
        +
        +			/* omit explicit iv */
        +			out += iv;
        +			len -= iv;
        +
        +			/* figure out payload length */
        +			pad = out[len-1];
        +			maxpad = len-(SHA_DIGEST_LENGTH+1);
        +			maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
        +			maxpad &= 255;
        +
        +			inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
        +			mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
        +			inp_len &= mask;
        +			ret &= (int)mask;
        +
        +			key->aux.tls_aad[plen-2] = inp_len>>8;
        +			key->aux.tls_aad[plen-1] = inp_len;
        +
        +			/* calculate HMAC */
        +			key->md = key->head;
        +			SHA1_Update(&key->md,key->aux.tls_aad,plen);
        +
        +#if 1
        +			len -= SHA_DIGEST_LENGTH;		/* amend mac */
        +			if (len>=(256+SHA_CBLOCK)) {
        +				j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
        +				j += SHA_CBLOCK-key->md.num;
        +				SHA1_Update(&key->md,out,j);
        +				out += j;
        +				len -= j;
        +				inp_len -= j;
        +			}
        +
        +			/* but pretend as if we hashed padded payload */
        +			bitlen = key->md.Nl+(inp_len<<3);	/* at most 18 bits */
        +#ifdef BSWAP
        +			bitlen = BSWAP(bitlen);
        +#else
        +			mac.c[0] = 0;
        +			mac.c[1] = (unsigned char)(bitlen>>16);
        +			mac.c[2] = (unsigned char)(bitlen>>8);
        +			mac.c[3] = (unsigned char)bitlen;
        +			bitlen = mac.u[0];
        +#endif
        +
        +			pmac->u[0]=0;
        +			pmac->u[1]=0;
        +			pmac->u[2]=0;
        +			pmac->u[3]=0;
        +			pmac->u[4]=0;
        +
        +			for (res=key->md.num, j=0;j<len;j++) {
        +				size_t c = out[j];
        +				mask = (j-inp_len)>>(sizeof(j)*8-8);
        +				c &= mask;
        +				c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
        +				data->c[res++]=(unsigned char)c;
        +
        +				if (res!=SHA_CBLOCK) continue;
        +
        +				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
        +				data->u[SHA_LBLOCK-1] |= bitlen&mask;
        +				sha1_block_data_order(&key->md,data,1);
        +				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
        +				pmac->u[0] |= key->md.h0 & mask;
        +				pmac->u[1] |= key->md.h1 & mask;
        +				pmac->u[2] |= key->md.h2 & mask;
        +				pmac->u[3] |= key->md.h3 & mask;
        +				pmac->u[4] |= key->md.h4 & mask;
        +				res=0;
        +			}
        +
        +			for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
        +
        +			if (res>SHA_CBLOCK-8) {
        +				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
        +				data->u[SHA_LBLOCK-1] |= bitlen&mask;
        +				sha1_block_data_order(&key->md,data,1);
        +				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
        +				pmac->u[0] |= key->md.h0 & mask;
        +				pmac->u[1] |= key->md.h1 & mask;
        +				pmac->u[2] |= key->md.h2 & mask;
        +				pmac->u[3] |= key->md.h3 & mask;
        +				pmac->u[4] |= key->md.h4 & mask;
        +
        +				memset(data,0,SHA_CBLOCK);
        +				j+=64;
        +			}
        +			data->u[SHA_LBLOCK-1] = bitlen;
        +			sha1_block_data_order(&key->md,data,1);
        +			mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
        +			pmac->u[0] |= key->md.h0 & mask;
        +			pmac->u[1] |= key->md.h1 & mask;
        +			pmac->u[2] |= key->md.h2 & mask;
        +			pmac->u[3] |= key->md.h3 & mask;
        +			pmac->u[4] |= key->md.h4 & mask;
        +
        +#ifdef BSWAP
        +			pmac->u[0] = BSWAP(pmac->u[0]);
        +			pmac->u[1] = BSWAP(pmac->u[1]);
        +			pmac->u[2] = BSWAP(pmac->u[2]);
        +			pmac->u[3] = BSWAP(pmac->u[3]);
        +			pmac->u[4] = BSWAP(pmac->u[4]);
        +#else
        +			for (i=0;i<5;i++) {
        +				res = pmac->u[i];
        +				pmac->c[4*i+0]=(unsigned char)(res>>24);
        +				pmac->c[4*i+1]=(unsigned char)(res>>16);
        +				pmac->c[4*i+2]=(unsigned char)(res>>8);
        +				pmac->c[4*i+3]=(unsigned char)res;
        +			}
        +#endif
        +			len += SHA_DIGEST_LENGTH;
        +#else
        +			SHA1_Update(&key->md,out,inp_len);
        +			res = key->md.num;
        +			SHA1_Final(pmac->c,&key->md);
        +
        +			{
        +			unsigned int inp_blocks, pad_blocks;
        +
        +			/* but pretend as if we hashed padded payload */
        +			inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
        +			res += (unsigned int)(len-inp_len);
        +			pad_blocks = res / SHA_CBLOCK;
        +			res %= SHA_CBLOCK;
        +			pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
        +			for (;inp_blocks<pad_blocks;inp_blocks++)
        +				sha1_block_data_order(&key->md,data,1);
        +			}
        +#endif
        +			key->md = key->tail;
        +			SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
        +			SHA1_Final(pmac->c,&key->md);
        +
        +			/* verify HMAC */
        +			out += inp_len;
        +			len -= inp_len;
        +#if 1
        +			{
        +			unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
        +			size_t off = out-p;
        +			unsigned int c, cmask;
        +
        +			maxpad += SHA_DIGEST_LENGTH;
        +			for (res=0,i=0,j=0;j<maxpad;j++) {
        +				c = p[j];
        +				cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
        +				res |= (c^pad)&~cmask;	/* ... and padding */
        +				cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
        +				res |= (c^pmac->c[i])&cmask;
        +				i += 1&cmask;
        +			}
        +			maxpad -= SHA_DIGEST_LENGTH;
        +
        +			res = 0-((0-res)>>(sizeof(res)*8-1));
        +			ret &= (int)~res;
        +			}
        +#else
        +			for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
        +				res |= out[i]^pmac->c[i];
        +			res = 0-((0-res)>>(sizeof(res)*8-1));
        +			ret &= (int)~res;
        +
        +			/* verify padding */
        +			pad = (pad&~res) | (maxpad&res);
        +			out = out+len-1-pad;
        +			for (res=0,i=0;i<pad;i++)
        +				res |= out[i]^pad;
        +
        +			res = (0-res)>>(sizeof(res)*8-1);
        +			ret &= (int)~res;
        +#endif
        +			return ret;
        +		} else {
        +			SHA1_Update(&key->md,out,len);
        +		}
        +	}
        +
        +	return 1;
        +	}
        +
        +static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
        +	{
        +	EVP_AES_HMAC_SHA1 *key = data(ctx);
        +
        +	switch (type)
        +		{
        +	case EVP_CTRL_AEAD_SET_MAC_KEY:
        +		{
        +		unsigned int  i;
        +		unsigned char hmac_key[64];
        +
        +		memset (hmac_key,0,sizeof(hmac_key));
        +
        +		if (arg > (int)sizeof(hmac_key)) {
        +			SHA1_Init(&key->head);
        +			SHA1_Update(&key->head,ptr,arg);
        +			SHA1_Final(hmac_key,&key->head);
        +		} else {
        +			memcpy(hmac_key,ptr,arg);
        +		}
        +
        +		for (i=0;i<sizeof(hmac_key);i++)
        +			hmac_key[i] ^= 0x36;		/* ipad */
        +		SHA1_Init(&key->head);
        +		SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
        +
        +		for (i=0;i<sizeof(hmac_key);i++)
        +			hmac_key[i] ^= 0x36^0x5c;	/* opad */
        +		SHA1_Init(&key->tail);
        +		SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
        +
        +		OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
        +
        +		return 1;
        +		}
        +	case EVP_CTRL_AEAD_TLS1_AAD:
        +		{
        +		unsigned char *p=ptr;
        +		unsigned int   len=p[arg-2]<<8|p[arg-1];
        +
        +		if (ctx->encrypt)
        +			{
        +			key->payload_length = len;
        +			if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
        +				len -= AES_BLOCK_SIZE;
        +				p[arg-2] = len>>8;
        +				p[arg-1] = len;
        +			}
        +			key->md = key->head;
        +			SHA1_Update(&key->md,p,arg);
        +
        +			return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
        +				- len);
        +			}
        +		else
        +			{
        +			if (arg>13) arg = 13;
        +			memcpy(key->aux.tls_aad,ptr,arg);
        +			key->payload_length = arg;
        +
        +			return SHA_DIGEST_LENGTH;
        +			}
        +		}
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
        +	{
        +#ifdef NID_aes_128_cbc_hmac_sha1
        +	NID_aes_128_cbc_hmac_sha1,
        +#else
        +	NID_undef,
        +#endif
        +	16,16,16,
        +	EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
        +	aesni_cbc_hmac_sha1_init_key,
        +	aesni_cbc_hmac_sha1_cipher,
        +	NULL,
        +	sizeof(EVP_AES_HMAC_SHA1),
        +	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
        +	aesni_cbc_hmac_sha1_ctrl,
        +	NULL
        +	};
        +
        +static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
        +	{
        +#ifdef NID_aes_256_cbc_hmac_sha1
        +	NID_aes_256_cbc_hmac_sha1,
        +#else
        +	NID_undef,
        +#endif
        +	16,32,16,
        +	EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
        +	aesni_cbc_hmac_sha1_init_key,
        +	aesni_cbc_hmac_sha1_cipher,
        +	NULL,
        +	sizeof(EVP_AES_HMAC_SHA1),
        +	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
        +	aesni_cbc_hmac_sha1_ctrl,
        +	NULL
        +	};
        +
        +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
        +	{
        +	return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
        +		&aesni_128_cbc_hmac_sha1_cipher:NULL);
        +	}
        +
        +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
        +	{
        +	return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
        +		&aesni_256_cbc_hmac_sha1_cipher:NULL);
        +	}
        +#else
        +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
        +	{
        +	return NULL;
        +	}
        +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
        +	{
        +	return NULL;
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_bf.c b/vendor/openssl/openssl/crypto/evp/e_bf.c
        new file mode 100644
        index 000000000..cc224e536
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_bf.c
        @@ -0,0 +1,88 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#ifndef OPENSSL_NO_BF
        +#include <openssl/evp.h>
        +#include "evp_locl.h"
        +#include <openssl/objects.h>
        +#include <openssl/blowfish.h>
        +
        +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +		       const unsigned char *iv, int enc);
        +
        +typedef struct
        +	{
        +	BF_KEY ks;
        +	} EVP_BF_KEY;
        +
        +#define data(ctx)	EVP_C_DATA(EVP_BF_KEY,ctx)
        +
        +IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
        +			EVP_CIPH_VARIABLE_LENGTH, 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(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),key);
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_camellia.c b/vendor/openssl/openssl/crypto/evp/e_camellia.c
        new file mode 100644
        index 000000000..a7b40d1c6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_camellia.c
        @@ -0,0 +1,131 @@
        +/* crypto/evp/e_camellia.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_CAMELLIA
        +#include <openssl/evp.h>
        +#include <openssl/err.h>
        +#include <string.h>
        +#include <assert.h>
        +#include <openssl/camellia.h>
        +#include "evp_locl.h"
        +
        +static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc);
        +
        +/* Camellia subkey Structure */
        +typedef struct
        +	{
        +	CAMELLIA_KEY ks;
        +	} EVP_CAMELLIA_KEY;
        +
        +/* Attribute operation for Camellia */
        +#define data(ctx)	EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
        +
        +IMPLEMENT_BLOCK_CIPHER(camellia_128, ks, Camellia, EVP_CAMELLIA_KEY,
        +	NID_camellia_128, 16, 16, 16, 128,
        +	0, camellia_init_key, NULL, 
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL)
        +IMPLEMENT_BLOCK_CIPHER(camellia_192, ks, Camellia, EVP_CAMELLIA_KEY,
        +	NID_camellia_192, 16, 24, 16, 128,
        +	0, camellia_init_key, NULL, 
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL)
        +IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY,
        +	NID_camellia_256, 16, 32, 16, 128,
        +	0, camellia_init_key, NULL, 
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL)
        +
        +#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits)	IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
        +
        +IMPLEMENT_CAMELLIA_CFBR(128,1)
        +IMPLEMENT_CAMELLIA_CFBR(192,1)
        +IMPLEMENT_CAMELLIA_CFBR(256,1)
        +
        +IMPLEMENT_CAMELLIA_CFBR(128,8)
        +IMPLEMENT_CAMELLIA_CFBR(192,8)
        +IMPLEMENT_CAMELLIA_CFBR(256,8)
        +
        +
        +
        +/* The subkey for Camellia is generated. */ 
        +static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc)
        +	{
        +	int ret;
        +
        +	ret=Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data);
        +
        +	if(ret < 0)
        +		{
        +		EVPerr(EVP_F_CAMELLIA_INIT_KEY,EVP_R_CAMELLIA_KEY_SETUP_FAILED);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +#else
        +
        +# ifdef PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_cast.c b/vendor/openssl/openssl/crypto/evp/e_cast.c
        new file mode 100644
        index 000000000..d77bcd929
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_cast.c
        @@ -0,0 +1,90 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_CAST
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/cast.h>
        +
        +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			 const unsigned char *iv,int enc);
        +
        +typedef struct
        +	{
        +	CAST_KEY ks;
        +	} EVP_CAST_KEY;
        +
        +#define data(ctx)	EVP_C_DATA(EVP_CAST_KEY,ctx)
        +
        +IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY, 
        +			NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
        +			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(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),key);
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_des.c b/vendor/openssl/openssl/crypto/evp/e_des.c
        new file mode 100644
        index 000000000..ca009f2c5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_des.c
        @@ -0,0 +1,224 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#ifndef OPENSSL_NO_DES
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/des.h>
        +#include <openssl/rand.h>
        +
        +static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			const unsigned char *iv, int enc);
        +static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
        +
        +/* 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, size_t inl)
        +{
        +	BLOCK_CIPHER_ecb_loop()
        +		DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt);
        +	return 1;
        +}
        +
        +static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			  const unsigned char *in, size_t inl)
        +{
        +	while(inl>=EVP_MAXCHUNK)
        +		{
        +		DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
        +				(DES_cblock *)ctx->iv, &ctx->num);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
        +				(DES_cblock *)ctx->iv, &ctx->num);
        +	return 1;
        +}
        +
        +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			  const unsigned char *in, size_t inl)
        +{
        +	while(inl>=EVP_MAXCHUNK)
        +		{
        +		DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
        +				(DES_cblock *)ctx->iv, ctx->encrypt);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
        +				(DES_cblock *)ctx->iv, ctx->encrypt);
        +	return 1;
        +}
        +
        +static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			    const unsigned char *in, size_t inl)
        +{
        +	while(inl>=EVP_MAXCHUNK)
        +		{
        +		DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data,
        +				(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
        +			  (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
        +	return 1;
        +}
        +
        +/* Although we have a CFB-r implementation for DES, it doesn't pack the right
        +   way, so wrap it here */
        +static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			   const unsigned char *in, size_t inl)
        +    {
        +    size_t n,chunk=EVP_MAXCHUNK/8;
        +    unsigned char c[1],d[1];
        +
        +    if (inl<chunk) chunk=inl;
        +
        +    while (inl && inl>=chunk)
        +	{
        +	for(n=0 ; n < chunk*8; ++n)
        +	    {
        +	    c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
        +	    DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
        +			ctx->encrypt);
        +	    out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
        +		     ((d[0]&0x80) >> (unsigned int)(n%8));
        +	    }
        +	inl-=chunk;
        +	in +=chunk;
        +	out+=chunk;
        +	if (inl<chunk) chunk=inl;
        +	}
        +
        +    return 1;
        +    }
        +
        +static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			   const unsigned char *in, size_t inl)
        +    {
        +    while (inl>=EVP_MAXCHUNK)
        +	{
        +	DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data,
        +			(DES_cblock *)ctx->iv,ctx->encrypt);
        +	inl-=EVP_MAXCHUNK;
        +	in +=EVP_MAXCHUNK;
        +	out+=EVP_MAXCHUNK;
        +	}
        +    if (inl)
        +	DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data,
        +			(DES_cblock *)ctx->iv,ctx->encrypt);
        +    return 1;
        +    }
        +
        +BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
        +			EVP_CIPH_RAND_KEY, des_init_key, NULL,
        +			EVP_CIPHER_set_asn1_iv,
        +			EVP_CIPHER_get_asn1_iv,
        +			des_ctrl)
        +
        +BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,
        +		     EVP_CIPH_RAND_KEY, des_init_key,NULL,
        +		     EVP_CIPHER_set_asn1_iv,
        +		     EVP_CIPHER_get_asn1_iv,des_ctrl)
        +
        +BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,
        +		     EVP_CIPH_RAND_KEY,des_init_key,NULL,
        +		     EVP_CIPHER_set_asn1_iv,
        +		     EVP_CIPHER_get_asn1_iv,des_ctrl)
        +
        +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;
        +#ifdef EVP_CHECK_DES_KEY
        +	if(DES_set_key_checked(deskey,ctx->cipher_data) != 0)
        +		return 0;
        +#else
        +	DES_set_key_unchecked(deskey,ctx->cipher_data);
        +#endif
        +	return 1;
        +	}
        +
        +static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
        +	{
        +	
        +	switch(type)
        +		{
        +	case EVP_CTRL_RAND_KEY:
        +		if (RAND_bytes(ptr, 8) <= 0)
        +			return 0;
        +		DES_set_odd_parity((DES_cblock *)ptr);
        +		return 1;
        +
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_des3.c b/vendor/openssl/openssl/crypto/evp/e_des3.c
        new file mode 100644
        index 000000000..1e6997266
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_des3.c
        @@ -0,0 +1,316 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#ifndef OPENSSL_NO_DES
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/des.h>
        +#include <openssl/rand.h>
        +
        +#ifndef OPENSSL_FIPS
        +
        +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);
        +
        +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
        +
        +typedef struct
        +    {
        +    DES_key_schedule ks1;/* key schedule */
        +    DES_key_schedule ks2;/* key schedule (for ede) */
        +    DES_key_schedule ks3;/* key schedule (for ede3) */
        +    } DES_EDE_KEY;
        +
        +#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
        +
        +/* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
        +
        +static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			      const unsigned char *in, size_t inl)
        +{
        +	BLOCK_CIPHER_ecb_loop()
        +		DES_ecb3_encrypt((const_DES_cblock *)(in + i),
        +				 (DES_cblock *)(out + i),
        +				 &data(ctx)->ks1, &data(ctx)->ks2,
        +				 &data(ctx)->ks3,
        +				 ctx->encrypt);
        +	return 1;
        +}
        +
        +static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			      const unsigned char *in, size_t inl)
        +{
        +	if (inl>=EVP_MAXCHUNK)
        +		{
        +		DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
        +			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
        +			       (DES_cblock *)ctx->iv, &ctx->num);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_ede3_ofb64_encrypt(in, out, (long)inl,
        +				&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
        +                               (DES_cblock *)ctx->iv, &ctx->num);
        +
        +	return 1;
        +}
        +
        +static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			      const unsigned char *in, size_t inl)
        +{
        +#ifdef KSSL_DEBUG
        +	{
        +        int i;
        +        char *cp;
        +	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
        +	printf("\t iv= ");
        +        for(i=0;i<8;i++)
        +                printf("%02X",ctx->iv[i]);
        +	printf("\n");
        +	}
        +#endif    /* KSSL_DEBUG */
        +	if (inl>=EVP_MAXCHUNK)
        +		{
        +		DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
        +			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
        +			     (DES_cblock *)ctx->iv, ctx->encrypt);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_ede3_cbc_encrypt(in, out, (long)inl,
        +			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
        +                             (DES_cblock *)ctx->iv, ctx->encrypt);
        +	return 1;
        +}
        +
        +static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			      const unsigned char *in, size_t inl)
        +{
        +	if (inl>=EVP_MAXCHUNK)
        +		{
        +		DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 
        +			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
        +			       (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_ede3_cfb64_encrypt(in, out, (long)inl,
        +			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
        +                               (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
        +	return 1;
        +}
        +
        +/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
        +   way, so wrap it here */
        +static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +				const unsigned char *in, size_t inl)
        +    {
        +    size_t n;
        +    unsigned char c[1],d[1];
        +
        +    for(n=0 ; n < inl ; ++n)
        +	{
        +	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
        +	DES_ede3_cfb_encrypt(c,d,1,1,
        +			     &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
        +			     (DES_cblock *)ctx->iv,ctx->encrypt);
        +	out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
        +		 ((d[0]&0x80) >> (unsigned int)(n%8));
        +	}
        +
        +    return 1;
        +    }
        +
        +static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +				const unsigned char *in, size_t inl)
        +    {
        +    while (inl>=EVP_MAXCHUNK)
        +	{
        +	DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,
        +			 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
        +			 (DES_cblock *)ctx->iv,ctx->encrypt);
        +	inl-=EVP_MAXCHUNK;
        +	in +=EVP_MAXCHUNK;
        +	out+=EVP_MAXCHUNK;
        +	}
        +    if (inl)
        +	DES_ede3_cfb_encrypt(in,out,8,(long)inl,
        +			&data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
        +			(DES_cblock *)ctx->iv,ctx->encrypt);
        +    return 1;
        +    }
        +
        +BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
        +			EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, 
        +			EVP_CIPHER_set_asn1_iv,
        +			EVP_CIPHER_get_asn1_iv,
        +			des3_ctrl)
        +
        +#define des_ede3_cfb64_cipher des_ede_cfb64_cipher
        +#define des_ede3_ofb_cipher des_ede_ofb_cipher
        +#define des_ede3_cbc_cipher des_ede_cbc_cipher
        +#define des_ede3_ecb_cipher des_ede_ecb_cipher
        +
        +BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
        +			EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 
        +			EVP_CIPHER_set_asn1_iv,
        +			EVP_CIPHER_get_asn1_iv,
        +			des3_ctrl)
        +
        +BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
        +		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
        +		     EVP_CIPHER_set_asn1_iv,
        +		     EVP_CIPHER_get_asn1_iv,
        +		     des3_ctrl)
        +
        +BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
        +		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
        +		     EVP_CIPHER_set_asn1_iv,
        +		     EVP_CIPHER_get_asn1_iv,
        +		     des3_ctrl)
        +
        +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;
        +#ifdef EVP_CHECK_DES_KEY
        +	if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1)
        +		!! DES_set_key_checked(&deskey[1],&data(ctx)->ks2))
        +		return 0;
        +#else
        +	DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
        +	DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
        +#endif
        +	memcpy(&data(ctx)->ks3,&data(ctx)->ks1,
        +	       sizeof(data(ctx)->ks1));
        +	return 1;
        +	}
        +
        +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			     const unsigned char *iv, int enc)
        +	{
        +	DES_cblock *deskey = (DES_cblock *)key;
        +#ifdef KSSL_DEBUG
        +	{
        +        int i;
        +        printf("des_ede3_init_key(ctx=%lx)\n", ctx);
        +	printf("\tKEY= ");
        +        for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
        +	printf("\t IV= ");
        +        for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n");
        +	}
        +#endif	/* KSSL_DEBUG */
        +
        +#ifdef EVP_CHECK_DES_KEY
        +	if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1)
        +		|| DES_set_key_checked(&deskey[1],&data(ctx)->ks2)
        +		|| DES_set_key_checked(&deskey[2],&data(ctx)->ks3))
        +		return 0;
        +#else
        +	DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
        +	DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
        +	DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3);
        +#endif
        +	return 1;
        +	}
        +
        +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
        +	{
        +
        +	DES_cblock *deskey = ptr;
        +
        +	switch(type)
        +		{
        +	case EVP_CTRL_RAND_KEY:
        +		if (RAND_bytes(ptr, c->key_len) <= 0)
        +			return 0;
        +		DES_set_odd_parity(deskey);
        +		if (c->key_len >= 16)
        +			DES_set_odd_parity(deskey + 1);
        +		if (c->key_len >= 24)
        +			DES_set_odd_parity(deskey + 2);
        +		return 1;
        +
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +const EVP_CIPHER *EVP_des_ede(void)
        +{
        +	return &des_ede_ecb;
        +}
        +
        +const EVP_CIPHER *EVP_des_ede3(void)
        +{
        +	return &des_ede3_ecb;
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_dsa.c b/vendor/openssl/openssl/crypto/evp/e_dsa.c
        new file mode 100644
        index 000000000..b96f2738b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_dsa.c
        @@ -0,0 +1,71 @@
        +/* crypto/evp/e_dsa.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +static EVP_PKEY_METHOD dss_method=
        +	{
        +	DSA_sign,
        +	DSA_verify,
        +	{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3,NULL},
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/e_idea.c b/vendor/openssl/openssl/crypto/evp/e_idea.c
        new file mode 100644
        index 000000000..806b08036
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_idea.c
        @@ -0,0 +1,118 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_IDEA
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/idea.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, size_t inl)
        +{
        +	BLOCK_CIPHER_ecb_loop()
        +		idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
        +	return 1;
        +}
        +
        +/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */
        +
        +typedef struct
        +	{
        +	IDEA_KEY_SCHEDULE ks;
        +	} EVP_IDEA_KEY;
        +
        +BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks)
        +BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks)
        +BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks)
        +
        +BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
        +			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->cipher_data);
        +	else
        +		{
        +		IDEA_KEY_SCHEDULE tmp;
        +
        +		idea_set_encrypt_key(key,&tmp);
        +		idea_set_decrypt_key(&tmp,ctx->cipher_data);
        +		OPENSSL_cleanse((unsigned char *)&tmp,
        +				sizeof(IDEA_KEY_SCHEDULE));
        +		}
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_null.c b/vendor/openssl/openssl/crypto/evp/e_null.c
        new file mode 100644
        index 000000000..f0c1f78b5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_null.c
        @@ -0,0 +1,104 @@
        +/* crypto/evp/e_null.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +
        +#ifndef OPENSSL_FIPS
        +
        +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv,int enc);
        +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, size_t inl);
        +static const EVP_CIPHER n_cipher=
        +	{
        +	NID_undef,
        +	1,0,0,
        +	0,
        +	null_init_key,
        +	null_cipher,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +const EVP_CIPHER *EVP_enc_null(void)
        +	{
        +	return(&n_cipher);
        +	}
        +
        +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	     const unsigned char *iv, int enc)
        +	{
        +	/*	memset(&(ctx->c),0,sizeof(ctx->c));*/
        +	return 1;
        +	}
        +
        +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	     const unsigned char *in, size_t inl)
        +	{
        +	if (in != out)
        +		memcpy((char *)out,(const char *)in,inl);
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_old.c b/vendor/openssl/openssl/crypto/evp/e_old.c
        new file mode 100644
        index 000000000..1642af486
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_old.c
        @@ -0,0 +1,125 @@
        +/* crypto/evp/e_old.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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).
        + *
        + */
        +
        +#ifdef OPENSSL_NO_DEPRECATED
        +static void *dummy = &dummy;
        +#else
        +
        +#include <openssl/evp.h>
        +
        +/* Define some deprecated functions, so older programs
        +   don't crash and burn too quickly.  On Windows and VMS,
        +   these will never be used, since functions and variables
        +   in shared libraries are selected by entry point location,
        +   not by name.  */
        +
        +#ifndef OPENSSL_NO_BF
        +#undef EVP_bf_cfb
        +const EVP_CIPHER *EVP_bf_cfb(void);
        +const EVP_CIPHER *EVP_bf_cfb(void) { return EVP_bf_cfb64(); }
        +#endif
        +
        +#ifndef OPENSSL_NO_DES
        +#undef EVP_des_cfb
        +const EVP_CIPHER *EVP_des_cfb(void);
        +const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); }
        +#undef EVP_des_ede3_cfb
        +const EVP_CIPHER *EVP_des_ede3_cfb(void);
        +const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); }
        +#undef EVP_des_ede_cfb
        +const EVP_CIPHER *EVP_des_ede_cfb(void);
        +const EVP_CIPHER *EVP_des_ede_cfb(void) { return EVP_des_ede_cfb64(); }
        +#endif
        +
        +#ifndef OPENSSL_NO_IDEA
        +#undef EVP_idea_cfb
        +const EVP_CIPHER *EVP_idea_cfb(void);
        +const EVP_CIPHER *EVP_idea_cfb(void) { return EVP_idea_cfb64(); }
        +#endif
        +
        +#ifndef OPENSSL_NO_RC2
        +#undef EVP_rc2_cfb
        +const EVP_CIPHER *EVP_rc2_cfb(void);
        +const EVP_CIPHER *EVP_rc2_cfb(void) { return EVP_rc2_cfb64(); }
        +#endif
        +
        +#ifndef OPENSSL_NO_CAST
        +#undef EVP_cast5_cfb
        +const EVP_CIPHER *EVP_cast5_cfb(void);
        +const EVP_CIPHER *EVP_cast5_cfb(void) { return EVP_cast5_cfb64(); }
        +#endif
        +
        +#ifndef OPENSSL_NO_RC5
        +#undef EVP_rc5_32_12_16_cfb
        +const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
        +const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) { return EVP_rc5_32_12_16_cfb64(); }
        +#endif
        +
        +#ifndef OPENSSL_NO_AES
        +#undef EVP_aes_128_cfb
        +const EVP_CIPHER *EVP_aes_128_cfb(void);
        +const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); }
        +#undef EVP_aes_192_cfb
        +const EVP_CIPHER *EVP_aes_192_cfb(void);
        +const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); }
        +#undef EVP_aes_256_cfb
        +const EVP_CIPHER *EVP_aes_256_cfb(void);
        +const EVP_CIPHER *EVP_aes_256_cfb(void) { return EVP_aes_256_cfb128(); }
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_rc2.c b/vendor/openssl/openssl/crypto/evp/e_rc2.c
        new file mode 100644
        index 000000000..d4c33b58d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_rc2.c
        @@ -0,0 +1,238 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_RC2
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/rc2.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);
        +
        +typedef struct
        +	{
        +	int key_bits;	/* effective key bits */
        +	RC2_KEY ks;	/* key schedule */
        +	} EVP_RC2_KEY;
        +
        +#define data(ctx)	((EVP_RC2_KEY *)(ctx)->cipher_data)
        +
        +IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
        +			8,
        +			RC2_KEY_LENGTH, 8, 64,
        +			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 const 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_RC2_KEY),
        +	rc2_set_asn1_type_and_iv,
        +	rc2_get_asn1_type_and_iv,
        +	rc2_ctrl,
        +	NULL
        +	};
        +
        +static const 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_RC2_KEY),
        +	rc2_set_asn1_type_and_iv,
        +	rc2_get_asn1_type_and_iv,
        +	rc2_ctrl,
        +	NULL
        +	};
        +
        +const EVP_CIPHER *EVP_rc2_64_cbc(void)
        +	{
        +	return(&r2_64_cbc_cipher);
        +	}
        +
        +const 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(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
        +		    key,data(ctx)->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;
        +	int key_bits;
        +	unsigned int l;
        +	unsigned char iv[EVP_MAX_IV_LENGTH];
        +
        +	if (type != NULL)
        +		{
        +		l=EVP_CIPHER_CTX_iv_length(c);
        +		OPENSSL_assert(l <= sizeof(iv));
        +		i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l);
        +		if (i != (int)l)
        +			return(-1);
        +		key_bits =rc2_magic_to_meth((int)num);
        +		if (!key_bits)
        +			return(-1);
        +		if(i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
        +			return -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:
        +		data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
        +		return 1;
        +
        +	case EVP_CTRL_GET_RC2_KEY_BITS:
        +		*(int *)ptr = data(c)->key_bits;
        +		return 1;
        +			
        +	case EVP_CTRL_SET_RC2_KEY_BITS:
        +		if(arg > 0)
        +			{
        +			data(c)->key_bits = arg;
        +			return 1;
        +			}
        +		return 0;
        +#ifdef PBE_PRF_TEST
        +	case EVP_CTRL_PBE_PRF_NID:
        +		*(int *)ptr = NID_hmacWithMD5;
        +		return 1;
        +#endif
        +
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_rc4.c b/vendor/openssl/openssl/crypto/evp/e_rc4.c
        new file mode 100644
        index 000000000..b4f6bda82
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_rc4.c
        @@ -0,0 +1,137 @@
        +/* crypto/evp/e_rc4.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_RC4
        +
        +#include <openssl/evp.h>
        +#include "evp_locl.h"
        +#include <openssl/objects.h>
        +#include <openssl/rc4.h>
        +
        +/* FIXME: surely this is available elsewhere? */
        +#define EVP_RC4_KEY_SIZE		16
        +
        +typedef struct
        +    {
        +    RC4_KEY ks;	/* working key */
        +    } EVP_RC4_KEY;
        +
        +#define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data)
        +
        +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			const unsigned char *iv,int enc);
        +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		      const unsigned char *in, size_t inl);
        +static const EVP_CIPHER r4_cipher=
        +	{
        +	NID_rc4,
        +	1,EVP_RC4_KEY_SIZE,0,
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	rc4_init_key,
        +	rc4_cipher,
        +	NULL,
        +	sizeof(EVP_RC4_KEY),
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +static const EVP_CIPHER r4_40_cipher=
        +	{
        +	NID_rc4_40,
        +	1,5 /* 40 bit */,0,
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	rc4_init_key,
        +	rc4_cipher,
        +	NULL,
        +	sizeof(EVP_RC4_KEY),
        +	NULL, 
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +const EVP_CIPHER *EVP_rc4(void)
        +	{
        +	return(&r4_cipher);
        +	}
        +
        +const EVP_CIPHER *EVP_rc4_40(void)
        +	{
        +	return(&r4_40_cipher);
        +	}
        +
        +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			const unsigned char *iv, int enc)
        +	{
        +	RC4_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
        +		    key);
        +	return 1;
        +	}
        +
        +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		      const unsigned char *in, size_t inl)
        +	{
        +	RC4(&data(ctx)->ks,inl,in,out);
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c b/vendor/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c
        new file mode 100644
        index 000000000..56563191b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_rc4_hmac_md5.c
        @@ -0,0 +1,298 @@
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/opensslconf.h>
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/rc4.h>
        +#include <openssl/md5.h>
        +
        +#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
        +#define EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
        +#define EVP_CTRL_AEAD_TLS1_AAD		0x16
        +#define EVP_CTRL_AEAD_SET_MAC_KEY	0x17
        +#endif
        +
        +/* FIXME: surely this is available elsewhere? */
        +#define EVP_RC4_KEY_SIZE		16
        +
        +typedef struct
        +    {
        +    RC4_KEY		ks;
        +    MD5_CTX		head,tail,md;
        +    size_t		payload_length;
        +    } EVP_RC4_HMAC_MD5;
        +
        +#define NO_PAYLOAD_LENGTH	((size_t)-1)
        +
        +void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out,
        +		MD5_CTX *ctx,const void *inp,size_t blocks);
        +
        +#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
        +
        +static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
        +			const unsigned char *inkey,
        +			const unsigned char *iv, int enc)
        +	{
        +	EVP_RC4_HMAC_MD5 *key = data(ctx);
        +
        +	RC4_set_key(&key->ks,EVP_CIPHER_CTX_key_length(ctx),
        +		    inkey);
        +
        +	MD5_Init(&key->head);	/* handy when benchmarking */
        +	key->tail = key->head;
        +	key->md   = key->head;
        +
        +	key->payload_length = NO_PAYLOAD_LENGTH;
        +
        +	return 1;
        +	}
        +
        +#if	!defined(OPENSSL_NO_ASM) &&	( \
        +	defined(__x86_64)	|| defined(__x86_64__)	|| \
        +	defined(_M_AMD64)	|| defined(_M_X64)	|| \
        +	defined(__INTEL__)		) && \
        +	!(defined(__APPLE__) && defined(__MACH__))
        +#define	STITCHED_CALL
        +#endif
        +
        +#if !defined(STITCHED_CALL)
        +#define	rc4_off 0
        +#define	md5_off 0
        +#endif
        +
        +static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		      const unsigned char *in, size_t len)
        +	{
        +	EVP_RC4_HMAC_MD5 *key = data(ctx);
        +#if defined(STITCHED_CALL)
        +	size_t	rc4_off = 32-1-(key->ks.x&(32-1)),	/* 32 is $MOD from rc4_md5-x86_64.pl */
        +		md5_off = MD5_CBLOCK-key->md.num,
        +		blocks;
        +	unsigned int l;
        +	extern unsigned int OPENSSL_ia32cap_P[];
        +#endif
        +	size_t	plen = key->payload_length;
        +
        +	if (plen!=NO_PAYLOAD_LENGTH && len!=(plen+MD5_DIGEST_LENGTH)) return 0;
        +
        +	if (ctx->encrypt) {
        +		if (plen==NO_PAYLOAD_LENGTH) plen = len;
        +#if defined(STITCHED_CALL)
        +		/* cipher has to "fall behind" */
        +		if (rc4_off>md5_off) md5_off+=MD5_CBLOCK;
        +
        +		if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK) &&
        +		    (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
        +			MD5_Update(&key->md,in,md5_off);
        +			RC4(&key->ks,rc4_off,in,out);
        +
        +			rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off,
        +				&key->md,in+md5_off,blocks);
        +			blocks *= MD5_CBLOCK;
        +			rc4_off += blocks;
        +			md5_off += blocks;
        +			key->md.Nh += blocks>>29;
        +			key->md.Nl += blocks<<=3;
        +			if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
        +		} else {
        +			rc4_off = 0;
        +			md5_off = 0;
        +		}
        +#endif
        +		MD5_Update(&key->md,in+md5_off,plen-md5_off);
        +
        +		if (plen!=len) {	/* "TLS" mode of operation */
        +			if (in!=out)
        +				memcpy(out+rc4_off,in+rc4_off,plen-rc4_off);
        +
        +			/* calculate HMAC and append it to payload */
        +			MD5_Final(out+plen,&key->md);
        +			key->md = key->tail;
        +			MD5_Update(&key->md,out+plen,MD5_DIGEST_LENGTH);
        +			MD5_Final(out+plen,&key->md);
        +			/* encrypt HMAC at once */
        +			RC4(&key->ks,len-rc4_off,out+rc4_off,out+rc4_off);
        +		} else {
        +			RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
        +		}
        +	} else {
        +		unsigned char mac[MD5_DIGEST_LENGTH];
        +#if defined(STITCHED_CALL)
        +		/* digest has to "fall behind" */
        +		if (md5_off>rc4_off)	rc4_off += 2*MD5_CBLOCK;
        +		else			rc4_off += MD5_CBLOCK;
        +
        +		if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK) &&
        +		    (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
        +			RC4(&key->ks,rc4_off,in,out);
        +			MD5_Update(&key->md,out,md5_off);
        +
        +			rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off,
        +				&key->md,out+md5_off,blocks);
        +			blocks *= MD5_CBLOCK;
        +			rc4_off += blocks;
        +			md5_off += blocks;
        +			l = (key->md.Nl+(blocks<<3))&0xffffffffU;
        +			if (l<key->md.Nl) key->md.Nh++;
        +			key->md.Nl  = l;
        +			key->md.Nh += blocks>>29;
        +		} else {
        +			md5_off=0;
        +			rc4_off=0;
        +		}
        +#endif
        +		/* decrypt HMAC at once */
        +		RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
        +		if (plen!=NO_PAYLOAD_LENGTH) {	/* "TLS" mode of operation */
        +			MD5_Update(&key->md,out+md5_off,plen-md5_off);
        +
        +			/* calculate HMAC and verify it */
        +			MD5_Final(mac,&key->md);
        +			key->md = key->tail;
        +			MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH);
        +			MD5_Final(mac,&key->md);
        +
        +			if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH))
        +				return 0;
        +		} else {
        +			MD5_Update(&key->md,out+md5_off,len-md5_off);
        +		}
        +	}
        +
        +	key->payload_length = NO_PAYLOAD_LENGTH;
        +
        +	return 1;
        +	}
        +
        +static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
        +	{
        +	EVP_RC4_HMAC_MD5 *key = data(ctx);
        +
        +	switch (type)
        +		{
        +	case EVP_CTRL_AEAD_SET_MAC_KEY:
        +		{
        +		unsigned int  i;
        +		unsigned char hmac_key[64];
        +
        +		memset (hmac_key,0,sizeof(hmac_key));
        +
        +		if (arg > (int)sizeof(hmac_key)) {
        +			MD5_Init(&key->head);
        +			MD5_Update(&key->head,ptr,arg);
        +			MD5_Final(hmac_key,&key->head);
        +		} else {
        +			memcpy(hmac_key,ptr,arg);
        +		}
        +
        +		for (i=0;i<sizeof(hmac_key);i++)
        +			hmac_key[i] ^= 0x36;		/* ipad */
        +		MD5_Init(&key->head);
        +		MD5_Update(&key->head,hmac_key,sizeof(hmac_key));
        +
        +		for (i=0;i<sizeof(hmac_key);i++)
        +			hmac_key[i] ^= 0x36^0x5c;	/* opad */
        +		MD5_Init(&key->tail);
        +		MD5_Update(&key->tail,hmac_key,sizeof(hmac_key));
        +
        +		return 1;
        +		}
        +	case EVP_CTRL_AEAD_TLS1_AAD:
        +		{
        +		unsigned char *p=ptr;
        +		unsigned int   len=p[arg-2]<<8|p[arg-1];
        +
        +		if (!ctx->encrypt)
        +			{
        +			len -= MD5_DIGEST_LENGTH;
        +			p[arg-2] = len>>8;
        +			p[arg-1] = len;
        +			}
        +		key->payload_length=len;
        +		key->md = key->head;
        +		MD5_Update(&key->md,p,arg);
        +
        +		return MD5_DIGEST_LENGTH;
        +		}
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +static EVP_CIPHER r4_hmac_md5_cipher=
        +	{
        +#ifdef NID_rc4_hmac_md5
        +	NID_rc4_hmac_md5,
        +#else
        +	NID_undef,
        +#endif
        +	1,EVP_RC4_KEY_SIZE,0,
        +	EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH|EVP_CIPH_FLAG_AEAD_CIPHER,
        +	rc4_hmac_md5_init_key,
        +	rc4_hmac_md5_cipher,
        +	NULL,
        +	sizeof(EVP_RC4_HMAC_MD5),
        +	NULL,
        +	NULL,
        +	rc4_hmac_md5_ctrl,
        +	NULL
        +	};
        +
        +const EVP_CIPHER *EVP_rc4_hmac_md5(void)
        +	{
        +	return(&r4_hmac_md5_cipher);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_rc5.c b/vendor/openssl/openssl/crypto/evp/e_rc5.c
        new file mode 100644
        index 000000000..19a10c640
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_rc5.c
        @@ -0,0 +1,126 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_RC5
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/rc5.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);
        +
        +typedef struct
        +	{
        +	int rounds;	/* number of rounds */
        +	RC5_32_KEY ks;	/* key schedule */
        +	} EVP_RC5_KEY;
        +
        +#define data(ctx)	EVP_C_DATA(EVP_RC5_KEY,ctx)
        +
        +IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
        +		       8, RC5_32_KEY_LENGTH, 8, 64,
        +		       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:
        +		data(c)->rounds = RC5_12_ROUNDS;
        +		return 1;
        +
        +	case EVP_CTRL_GET_RC5_ROUNDS:
        +		*(int *)ptr = data(c)->rounds;
        +		return 1;
        +			
        +	case EVP_CTRL_SET_RC5_ROUNDS:
        +		switch(arg)
        +			{
        +		case RC5_8_ROUNDS:
        +		case RC5_12_ROUNDS:
        +		case RC5_16_ROUNDS:
        +			data(c)->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(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
        +		       key,data(ctx)->rounds);
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_seed.c b/vendor/openssl/openssl/crypto/evp/e_seed.c
        new file mode 100644
        index 000000000..2d1759d27
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_seed.c
        @@ -0,0 +1,83 @@
        +/* crypto/evp/e_seed.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2007 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 <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_SEED
        +#include <openssl/evp.h>
        +#include <openssl/err.h>
        +#include <string.h>
        +#include <assert.h>
        +#include <openssl/seed.h>
        +#include "evp_locl.h"
        +
        +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,	const unsigned char *iv, int enc);
        +
        +typedef struct
        +	{
        +	SEED_KEY_SCHEDULE ks;
        +	} EVP_SEED_KEY;
        +
        +IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
        +                       16, 16, 16, 128,
        +                       0, seed_init_key, 0, 0, 0, 0)
        +
        +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +                         const unsigned char *iv, int enc)
        +	{
        +	SEED_set_key(key, ctx->cipher_data);
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/e_xcbc_d.c b/vendor/openssl/openssl/crypto/evp/e_xcbc_d.c
        new file mode 100644
        index 000000000..250e88c8c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/e_xcbc_d.c
        @@ -0,0 +1,138 @@
        +/* crypto/evp/e_xcbc_d.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_DES
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include "evp_locl.h"
        +#include <openssl/des.h>
        +
        +static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +			     const unsigned char *iv,int enc);
        +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			   const unsigned char *in, size_t inl);
        +
        +
        +typedef struct
        +    {
        +    DES_key_schedule ks;/* key schedule */
        +    DES_cblock inw;
        +    DES_cblock outw;
        +    } DESX_CBC_KEY;
        +
        +#define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data)
        +
        +static const EVP_CIPHER d_xcbc_cipher=
        +	{
        +	NID_desx_cbc,
        +	8,24,8,
        +	EVP_CIPH_CBC_MODE,
        +	desx_cbc_init_key,
        +	desx_cbc_cipher,
        +	NULL,
        +	sizeof(DESX_CBC_KEY),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL,
        +	NULL
        +	};
        +
        +const EVP_CIPHER *EVP_desx_cbc(void)
        +	{
        +	return(&d_xcbc_cipher);
        +	}
        +	
        +static int desx_cbc_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,&data(ctx)->ks);
        +	memcpy(&data(ctx)->inw[0],&key[8],8);
        +	memcpy(&data(ctx)->outw[0],&key[16],8);
        +
        +	return 1;
        +	}
        +
        +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			   const unsigned char *in, size_t inl)
        +	{
        +	while (inl>=EVP_MAXCHUNK)
        +		{
        +		DES_xcbc_encrypt(in,out,(long)EVP_MAXCHUNK,&data(ctx)->ks,
        +			 (DES_cblock *)&(ctx->iv[0]),
        +			 &data(ctx)->inw,
        +			 &data(ctx)->outw,
        +			 ctx->encrypt);
        +		inl-=EVP_MAXCHUNK;
        +		in +=EVP_MAXCHUNK;
        +		out+=EVP_MAXCHUNK;
        +		}
        +	if (inl)
        +		DES_xcbc_encrypt(in,out,(long)inl,&data(ctx)->ks,
        +			(DES_cblock *)&(ctx->iv[0]),
        +			&data(ctx)->inw,
        +			&data(ctx)->outw,
        +			ctx->encrypt);
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/encode.c b/vendor/openssl/openssl/crypto/evp/encode.c
        new file mode 100644
        index 000000000..28546a84b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/encode.c
        @@ -0,0 +1,445 @@
        +/* crypto/evp/encode.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +
        +#ifndef CHARSET_EBCDIC
        +#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])
        +#define conv_ascii2bin(a)	(data_ascii2bin[(a)&0x7f])
        +#else
        +/* We assume that PEM encoded files are EBCDIC files
        + * (i.e., printable text files). Convert them here while decoding.
        + * When encoding, output is EBCDIC (text) format again.
        + * (No need for conversion in the conv_bin2ascii macro, as the
        + * underlying textstring data_bin2ascii[] is already EBCDIC)
        + */
        +#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])
        +#define conv_ascii2bin(a)	(data_ascii2bin[os_toascii[a]&0x7f])
        +#endif
        +
        +/* 64 char lines
        + * pad input with 0
        + * left over chars are set to =
        + * 1 byte  => xx==
        + * 2 bytes => xxx=
        + * 3 bytes => xxxx
        + */
        +#define BIN_PER_LINE    (64/4*3)
        +#define CHUNKS_PER_LINE (64/4)
        +#define CHAR_PER_LINE   (64+1)
        +
        +static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
        +abcdefghijklmnopqrstuvwxyz0123456789+/";
        +
        +/* 0xF0 is a EOLN
        + * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
        + * 0xF2 is EOF
        + * 0xE0 is ignore at start of line.
        + * 0xFF is error
        + */
        +
        +#define B64_EOLN		0xF0
        +#define B64_CR			0xF1
        +#define B64_EOF			0xF2
        +#define B64_WS			0xE0
        +#define B64_ERROR       	0xFF
        +#define B64_NOT_BASE64(a)	(((a)|0x13) == 0xF3)
        +
        +static const unsigned char data_ascii2bin[128]={
        +	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,
        +	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	0xFF,0xFF,0xFF,0x3E,0xFF,0xF2,0xFF,0x3F,
        +	0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
        +	0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
        +	0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
        +	0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
        +	0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
        +	0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
        +	0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
        +	0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
        +	0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
        +	};
        +
        +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
        +	{
        +	ctx->length=48;
        +	ctx->num=0;
        +	ctx->line_num=0;
        +	}
        +
        +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
        +	     const unsigned char *in, int inl)
        +	{
        +	int i,j;
        +	unsigned int total=0;
        +
        +	*outl=0;
        +	if (inl == 0) return;
        +	OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
        +	if ((ctx->num+inl) < ctx->length)
        +		{
        +		memcpy(&(ctx->enc_data[ctx->num]),in,inl);
        +		ctx->num+=inl;
        +		return;
        +		}
        +	if (ctx->num != 0)
        +		{
        +		i=ctx->length-ctx->num;
        +		memcpy(&(ctx->enc_data[ctx->num]),in,i);
        +		in+=i;
        +		inl-=i;
        +		j=EVP_EncodeBlock(out,ctx->enc_data,ctx->length);
        +		ctx->num=0;
        +		out+=j;
        +		*(out++)='\n';
        +		*out='\0';
        +		total=j+1;
        +		}
        +	while (inl >= ctx->length)
        +		{
        +		j=EVP_EncodeBlock(out,in,ctx->length);
        +		in+=ctx->length;
        +		inl-=ctx->length;
        +		out+=j;
        +		*(out++)='\n';
        +		*out='\0';
        +		total+=j+1;
        +		}
        +	if (inl != 0)
        +		memcpy(&(ctx->enc_data[0]),in,inl);
        +	ctx->num=inl;
        +	*outl=total;
        +	}
        +
        +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	unsigned int ret=0;
        +
        +	if (ctx->num != 0)
        +		{
        +		ret=EVP_EncodeBlock(out,ctx->enc_data,ctx->num);
        +		out[ret++]='\n';
        +		out[ret]='\0';
        +		ctx->num=0;
        +		}
        +	*outl=ret;
        +	}
        +
        +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
        +	{
        +	int i,ret=0;
        +	unsigned long l;
        +
        +	for (i=dlen; i > 0; i-=3)
        +		{
        +		if (i >= 3)
        +			{
        +			l=	(((unsigned long)f[0])<<16L)|
        +				(((unsigned long)f[1])<< 8L)|f[2];
        +			*(t++)=conv_bin2ascii(l>>18L);
        +			*(t++)=conv_bin2ascii(l>>12L);
        +			*(t++)=conv_bin2ascii(l>> 6L);
        +			*(t++)=conv_bin2ascii(l     );
        +			}
        +		else
        +			{
        +			l=((unsigned long)f[0])<<16L;
        +			if (i == 2) l|=((unsigned long)f[1]<<8L);
        +
        +			*(t++)=conv_bin2ascii(l>>18L);
        +			*(t++)=conv_bin2ascii(l>>12L);
        +			*(t++)=(i == 1)?'=':conv_bin2ascii(l>> 6L);
        +			*(t++)='=';
        +			}
        +		ret+=4;
        +		f+=3;
        +		}
        +
        +	*t='\0';
        +	return(ret);
        +	}
        +
        +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
        +	{
        +	ctx->length=30;
        +	ctx->num=0;
        +	ctx->line_num=0;
        +	ctx->expect_nl=0;
        +	}
        +
        +/* -1 for error
        + *  0 for last line
        + *  1 for full line
        + */
        +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
        +	     const unsigned char *in, int inl)
        +	{
        +	int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,exp_nl;
        +	unsigned char *d;
        +
        +	n=ctx->num;
        +	d=ctx->enc_data;
        +	ln=ctx->line_num;
        +	exp_nl=ctx->expect_nl;
        +
        +	/* last line of input. */
        +	if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF)))
        +		{ rv=0; goto end; }
        +		
        +	/* We parse the input data */
        +	for (i=0; i<inl; i++)
        +		{
        +		/* If the current line is > 80 characters, scream alot */
        +		if (ln >= 80) { rv= -1; goto end; }
        +
        +		/* Get char and put it into the buffer */
        +		tmp= *(in++);
        +		v=conv_ascii2bin(tmp);
        +		/* only save the good data :-) */
        +		if (!B64_NOT_BASE64(v))
        +			{
        +			OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
        +			d[n++]=tmp;
        +			ln++;
        +			}
        +		else if (v == B64_ERROR)
        +			{
        +			rv= -1;
        +			goto end;
        +			}
        +
        +		/* have we seen a '=' which is 'definitly' the last
        +		 * input line.  seof will point to the character that
        +		 * holds it. and eof will hold how many characters to
        +		 * chop off. */
        +		if (tmp == '=')
        +			{
        +			if (seof == -1) seof=n;
        +			eof++;
        +			}
        +
        +		if (v == B64_CR)
        +			{
        +			ln = 0;
        +			if (exp_nl)
        +				continue;
        +			}
        +
        +		/* eoln */
        +		if (v == B64_EOLN)
        +			{
        +			ln=0;
        +			if (exp_nl)
        +				{
        +				exp_nl=0;
        +				continue;
        +				}
        +			}
        +		exp_nl=0;
        +
        +		/* If we are at the end of input and it looks like a
        +		 * line, process it. */
        +		if (((i+1) == inl) && (((n&3) == 0) || eof))
        +			{
        +			v=B64_EOF;
        +			/* In case things were given us in really small
        +			   records (so two '=' were given in separate
        +			   updates), eof may contain the incorrect number
        +			   of ending bytes to skip, so let's redo the count */
        +			eof = 0;
        +			if (d[n-1] == '=') eof++;
        +			if (d[n-2] == '=') eof++;
        +			/* There will never be more than two '=' */
        +			}
        +
        +		if ((v == B64_EOF && (n&3) == 0) || (n >= 64))
        +			{
        +			/* This is needed to work correctly on 64 byte input
        +			 * lines.  We process the line and then need to
        +			 * accept the '\n' */
        +			if ((v != B64_EOF) && (n >= 64)) exp_nl=1;
        +			if (n > 0)
        +				{
        +				v=EVP_DecodeBlock(out,d,n);
        +				n=0;
        +				if (v < 0) { rv=0; goto end; }
        +				ret+=(v-eof);
        +				}
        +			else
        +				{
        +				eof=1;
        +				v=0;
        +				}
        +
        +			/* This is the case where we have had a short
        +			 * but valid input line */
        +			if ((v < ctx->length) && eof)
        +				{
        +				rv=0;
        +				goto end;
        +				}
        +			else
        +				ctx->length=v;
        +
        +			if (seof >= 0) { rv=0; goto end; }
        +			out+=v;
        +			}
        +		}
        +	rv=1;
        +end:
        +	*outl=ret;
        +	ctx->num=n;
        +	ctx->line_num=ln;
        +	ctx->expect_nl=exp_nl;
        +	return(rv);
        +	}
        +
        +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
        +	{
        +	int i,ret=0,a,b,c,d;
        +	unsigned long l;
        +
        +	/* trim white space from the start of the line. */
        +	while ((conv_ascii2bin(*f) == B64_WS) && (n > 0))
        +		{
        +		f++;
        +		n--;
        +		}
        +
        +	/* strip off stuff at the end of the line
        +	 * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
        +	while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n-1]))))
        +		n--;
        +
        +	if (n%4 != 0) return(-1);
        +
        +	for (i=0; i<n; i+=4)
        +		{
        +		a=conv_ascii2bin(*(f++));
        +		b=conv_ascii2bin(*(f++));
        +		c=conv_ascii2bin(*(f++));
        +		d=conv_ascii2bin(*(f++));
        +		if (	(a & 0x80) || (b & 0x80) ||
        +			(c & 0x80) || (d & 0x80))
        +			return(-1);
        +		l=(	(((unsigned long)a)<<18L)|
        +			(((unsigned long)b)<<12L)|
        +			(((unsigned long)c)<< 6L)|
        +			(((unsigned long)d)     ));
        +		*(t++)=(unsigned char)(l>>16L)&0xff;
        +		*(t++)=(unsigned char)(l>> 8L)&0xff;
        +		*(t++)=(unsigned char)(l     )&0xff;
        +		ret+=3;
        +		}
        +	return(ret);
        +	}
        +
        +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int i;
        +
        +	*outl=0;
        +	if (ctx->num != 0)
        +		{
        +		i=EVP_DecodeBlock(out,ctx->enc_data,ctx->num);
        +		if (i < 0) return(-1);
        +		ctx->num=0;
        +		*outl=i;
        +		return(1);
        +		}
        +	else
        +		return(1);
        +	}
        +
        +#ifdef undef
        +int EVP_DecodeValid(unsigned char *buf, int len)
        +	{
        +	int i,num=0,bad=0;
        +
        +	if (len == 0) return(-1);
        +	while (conv_ascii2bin(*buf) == B64_WS)
        +		{
        +		buf++;
        +		len--;
        +		if (len == 0) return(-1);
        +		}
        +
        +	for (i=len; i >= 4; i-=4)
        +		{
        +		if (	(conv_ascii2bin(buf[0]) >= 0x40) ||
        +			(conv_ascii2bin(buf[1]) >= 0x40) ||
        +			(conv_ascii2bin(buf[2]) >= 0x40) ||
        +			(conv_ascii2bin(buf[3]) >= 0x40))
        +			return(-1);
        +		buf+=4;
        +		num+=1+(buf[2] != '=')+(buf[3] != '=');
        +		}
        +	if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN))
        +		return(num);
        +	if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) &&
        +		(conv_ascii2bin(buf[0]) == B64_EOLN))
        +		return(num);
        +	return(1);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/evp.h b/vendor/openssl/openssl/crypto/evp/evp.h
        new file mode 100644
        index 000000000..faeb3c24e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp.h
        @@ -0,0 +1,1409 @@
        +/* crypto/evp/evp.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_ENVELOPE_H
        +#define HEADER_ENVELOPE_H
        +
        +#ifdef OPENSSL_ALGORITHM_DEFINES
        +# include <openssl/opensslconf.h>
        +#else
        +# define OPENSSL_ALGORITHM_DEFINES
        +# include <openssl/opensslconf.h>
        +# undef OPENSSL_ALGORITHM_DEFINES
        +#endif
        +
        +#include <openssl/ossl_typ.h>
        +
        +#include <openssl/symhacks.h>
        +
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +
        +/*
        +#define EVP_RC2_KEY_SIZE		16
        +#define EVP_RC4_KEY_SIZE		16
        +#define EVP_BLOWFISH_KEY_SIZE		16
        +#define EVP_CAST5_KEY_SIZE		16
        +#define EVP_RC5_32_12_16_KEY_SIZE	16
        +*/
        +#define EVP_MAX_MD_SIZE			64	/* longest known is SHA512 */
        +#define EVP_MAX_KEY_LENGTH		64
        +#define EVP_MAX_IV_LENGTH		16
        +#define EVP_MAX_BLOCK_LENGTH		32
        +
        +#define PKCS5_SALT_LEN			8
        +/* Default PKCS#5 iteration count */
        +#define PKCS5_DEFAULT_ITER		2048
        +
        +#include <openssl/objects.h>
        +
        +#define EVP_PK_RSA	0x0001
        +#define EVP_PK_DSA	0x0002
        +#define EVP_PK_DH	0x0004
        +#define EVP_PK_EC	0x0008
        +#define EVP_PKT_SIGN	0x0010
        +#define EVP_PKT_ENC	0x0020
        +#define EVP_PKT_EXCH	0x0040
        +#define EVP_PKS_RSA	0x0100
        +#define EVP_PKS_DSA	0x0200
        +#define EVP_PKS_EC	0x0400
        +#define EVP_PKT_EXP	0x1000 /* <= 512 bit key */
        +
        +#define EVP_PKEY_NONE	NID_undef
        +#define EVP_PKEY_RSA	NID_rsaEncryption
        +#define EVP_PKEY_RSA2	NID_rsa
        +#define EVP_PKEY_DSA	NID_dsa
        +#define EVP_PKEY_DSA1	NID_dsa_2
        +#define EVP_PKEY_DSA2	NID_dsaWithSHA
        +#define EVP_PKEY_DSA3	NID_dsaWithSHA1
        +#define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
        +#define EVP_PKEY_DH	NID_dhKeyAgreement
        +#define EVP_PKEY_EC	NID_X9_62_id_ecPublicKey
        +#define EVP_PKEY_HMAC	NID_hmac
        +#define EVP_PKEY_CMAC	NID_cmac
        +
        +#ifdef	__cplusplus
        +extern "C" {
        +#endif
        +
        +/* Type needs to be a bit field
        + * Sub-type needs to be for variations on the method, as in, can it do
        + * arbitrary encryption.... */
        +struct evp_pkey_st
        +	{
        +	int type;
        +	int save_type;
        +	int references;
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	ENGINE *engine;
        +	union	{
        +		char *ptr;
        +#ifndef OPENSSL_NO_RSA
        +		struct rsa_st *rsa;	/* RSA */
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +		struct dsa_st *dsa;	/* DSA */
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		struct dh_st *dh;	/* DH */
        +#endif
        +#ifndef OPENSSL_NO_EC
        +		struct ec_key_st *ec;	/* ECC */
        +#endif
        +		} pkey;
        +	int save_parameters;
        +	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
        +	} /* EVP_PKEY */;
        +
        +#define EVP_PKEY_MO_SIGN	0x0001
        +#define EVP_PKEY_MO_VERIFY	0x0002
        +#define EVP_PKEY_MO_ENCRYPT	0x0004
        +#define EVP_PKEY_MO_DECRYPT	0x0008
        +
        +#ifndef EVP_MD
        +struct env_md_st
        +	{
        +	int type;
        +	int pkey_type;
        +	int md_size;
        +	unsigned long flags;
        +	int (*init)(EVP_MD_CTX *ctx);
        +	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
        +	int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
        +	int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
        +	int (*cleanup)(EVP_MD_CTX *ctx);
        +
        +	/* FIXME: prototype these some day */
        +	int (*sign)(int type, const unsigned char *m, unsigned int m_length,
        +		    unsigned char *sigret, unsigned int *siglen, void *key);
        +	int (*verify)(int type, const unsigned char *m, unsigned int m_length,
        +		      const unsigned char *sigbuf, unsigned int siglen,
        +		      void *key);
        +	int required_pkey_type[5]; /*EVP_PKEY_xxx */
        +	int block_size;
        +	int ctx_size; /* how big does the ctx->md_data need to be */
        +	/* control function */
        +	int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
        +	} /* EVP_MD */;
        +
        +typedef int evp_sign_method(int type,const unsigned char *m,
        +			    unsigned int m_length,unsigned char *sigret,
        +			    unsigned int *siglen, void *key);
        +typedef int evp_verify_method(int type,const unsigned char *m,
        +			    unsigned int m_length,const unsigned char *sigbuf,
        +			    unsigned int siglen, void *key);
        +
        +#define EVP_MD_FLAG_ONESHOT	0x0001 /* digest can only handle a single
        +					* block */
        +
        +#define EVP_MD_FLAG_PKEY_DIGEST	0x0002 /* digest is a "clone" digest used
        +					* which is a copy of an existing
        +					* one for a specific public key type.
        +					* EVP_dss1() etc */
        +
        +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
        +
        +#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE	0x0004
        +
        +/* DigestAlgorithmIdentifier flags... */
        +
        +#define EVP_MD_FLAG_DIGALGID_MASK		0x0018
        +
        +/* NULL or absent parameter accepted. Use NULL */
        +
        +#define EVP_MD_FLAG_DIGALGID_NULL		0x0000
        +
        +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
        +
        +#define EVP_MD_FLAG_DIGALGID_ABSENT		0x0008
        +
        +/* Custom handling via ctrl */
        +
        +#define EVP_MD_FLAG_DIGALGID_CUSTOM		0x0018
        +
        +#define EVP_MD_FLAG_FIPS	0x0400 /* Note if suitable for use in FIPS mode */
        +
        +/* Digest ctrls */
        +
        +#define	EVP_MD_CTRL_DIGALGID			0x1
        +#define	EVP_MD_CTRL_MICALG			0x2
        +
        +/* Minimum Algorithm specific ctrl value */
        +
        +#define	EVP_MD_CTRL_ALG_CTRL			0x1000
        +
        +#define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
        +
        +#ifndef OPENSSL_NO_DSA
        +#define EVP_PKEY_DSA_method	(evp_sign_method *)DSA_sign, \
        +				(evp_verify_method *)DSA_verify, \
        +				{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
        +					EVP_PKEY_DSA4,0}
        +#else
        +#define EVP_PKEY_DSA_method	EVP_PKEY_NULL_method
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +#define EVP_PKEY_ECDSA_method   (evp_sign_method *)ECDSA_sign, \
        +				(evp_verify_method *)ECDSA_verify, \
        +                                 {EVP_PKEY_EC,0,0,0}
        +#else   
        +#define EVP_PKEY_ECDSA_method   EVP_PKEY_NULL_method
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +#define EVP_PKEY_RSA_method	(evp_sign_method *)RSA_sign, \
        +				(evp_verify_method *)RSA_verify, \
        +				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
        +#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
        +				(evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
        +				(evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
        +				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
        +#else
        +#define EVP_PKEY_RSA_method	EVP_PKEY_NULL_method
        +#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
        +#endif
        +
        +#endif /* !EVP_MD */
        +
        +struct env_md_ctx_st
        +	{
        +	const EVP_MD *digest;
        +	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
        +	unsigned long flags;
        +	void *md_data;
        +	/* Public key context for sign/verify */
        +	EVP_PKEY_CTX *pctx;
        +	/* Update function: usually copied from EVP_MD */
        +	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
        +	} /* EVP_MD_CTX */;
        +
        +/* values for EVP_MD_CTX flags */
        +
        +#define EVP_MD_CTX_FLAG_ONESHOT		0x0001 /* digest update will be called
        +						* once only */
        +#define EVP_MD_CTX_FLAG_CLEANED		0x0002 /* context has already been
        +						* cleaned */
        +#define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
        +						* in EVP_MD_CTX_cleanup */
        +/* FIPS and pad options are ignored in 1.0.0, definitions are here
        + * so we don't accidentally reuse the values for other purposes.
        + */
        +
        +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW	0x0008	/* Allow use of non FIPS digest
        +						 * in FIPS mode */
        +
        +/* The following PAD options are also currently ignored in 1.0.0, digest
        + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
        + * instead.
        + */
        +#define EVP_MD_CTX_FLAG_PAD_MASK	0xF0	/* RSA mode to use */
        +#define EVP_MD_CTX_FLAG_PAD_PKCS1	0x00	/* PKCS#1 v1.5 mode */
        +#define EVP_MD_CTX_FLAG_PAD_X931	0x10	/* X9.31 mode */
        +#define EVP_MD_CTX_FLAG_PAD_PSS		0x20	/* PSS mode */
        +
        +#define EVP_MD_CTX_FLAG_NO_INIT		0x0100 /* Don't initialize md_data */
        +
        +struct evp_cipher_st
        +	{
        +	int nid;
        +	int block_size;
        +	int key_len;		/* Default value for variable length ciphers */
        +	int iv_len;
        +	unsigned long flags;	/* Various flags */
        +	int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +		    const unsigned char *iv, int enc);	/* init key */
        +	int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
        +	int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
        +	int ctx_size;		/* how big ctx->cipher_data needs to be */
        +	int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
        +	int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
        +	int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
        +	void *app_data;		/* Application data */
        +	} /* EVP_CIPHER */;
        +
        +/* Values for cipher flags */
        +
        +/* Modes for ciphers */
        +
        +#define		EVP_CIPH_STREAM_CIPHER		0x0
        +#define		EVP_CIPH_ECB_MODE		0x1
        +#define		EVP_CIPH_CBC_MODE		0x2
        +#define		EVP_CIPH_CFB_MODE		0x3
        +#define		EVP_CIPH_OFB_MODE		0x4
        +#define		EVP_CIPH_CTR_MODE		0x5
        +#define		EVP_CIPH_GCM_MODE		0x6
        +#define		EVP_CIPH_CCM_MODE		0x7
        +#define		EVP_CIPH_XTS_MODE		0x10001
        +#define 	EVP_CIPH_MODE			0xF0007
        +/* Set if variable length cipher */
        +#define 	EVP_CIPH_VARIABLE_LENGTH	0x8
        +/* Set if the iv handling should be done by the cipher itself */
        +#define 	EVP_CIPH_CUSTOM_IV		0x10
        +/* Set if the cipher's init() function should be called if key is NULL */
        +#define 	EVP_CIPH_ALWAYS_CALL_INIT	0x20
        +/* Call ctrl() to init cipher parameters */
        +#define 	EVP_CIPH_CTRL_INIT		0x40
        +/* Don't use standard key length function */
        +#define 	EVP_CIPH_CUSTOM_KEY_LENGTH	0x80
        +/* Don't use standard block padding */
        +#define 	EVP_CIPH_NO_PADDING		0x100
        +/* cipher handles random key generation */
        +#define 	EVP_CIPH_RAND_KEY		0x200
        +/* cipher has its own additional copying logic */
        +#define 	EVP_CIPH_CUSTOM_COPY		0x400
        +/* Allow use default ASN1 get/set iv */
        +#define		EVP_CIPH_FLAG_DEFAULT_ASN1	0x1000
        +/* Buffer length in bits not bytes: CFB1 mode only */
        +#define		EVP_CIPH_FLAG_LENGTH_BITS	0x2000
        +/* Note if suitable for use in FIPS mode */
        +#define		EVP_CIPH_FLAG_FIPS		0x4000
        +/* Allow non FIPS cipher in FIPS mode */
        +#define		EVP_CIPH_FLAG_NON_FIPS_ALLOW	0x8000
        +/* Cipher handles any and all padding logic as well
        + * as finalisation.
        + */
        +#define 	EVP_CIPH_FLAG_CUSTOM_CIPHER	0x100000
        +#define		EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
        +
        +/* ctrl() values */
        +
        +#define		EVP_CTRL_INIT			0x0
        +#define 	EVP_CTRL_SET_KEY_LENGTH		0x1
        +#define 	EVP_CTRL_GET_RC2_KEY_BITS	0x2
        +#define 	EVP_CTRL_SET_RC2_KEY_BITS	0x3
        +#define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
        +#define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
        +#define 	EVP_CTRL_RAND_KEY		0x6
        +#define 	EVP_CTRL_PBE_PRF_NID		0x7
        +#define 	EVP_CTRL_COPY			0x8
        +#define 	EVP_CTRL_GCM_SET_IVLEN		0x9
        +#define 	EVP_CTRL_GCM_GET_TAG		0x10
        +#define 	EVP_CTRL_GCM_SET_TAG		0x11
        +#define		EVP_CTRL_GCM_SET_IV_FIXED	0x12
        +#define		EVP_CTRL_GCM_IV_GEN		0x13
        +#define		EVP_CTRL_CCM_SET_IVLEN		EVP_CTRL_GCM_SET_IVLEN
        +#define		EVP_CTRL_CCM_GET_TAG		EVP_CTRL_GCM_GET_TAG
        +#define		EVP_CTRL_CCM_SET_TAG		EVP_CTRL_GCM_SET_TAG
        +#define		EVP_CTRL_CCM_SET_L		0x14
        +#define		EVP_CTRL_CCM_SET_MSGLEN		0x15
        +/* AEAD cipher deduces payload length and returns number of bytes
        + * required to store MAC and eventual padding. Subsequent call to
        + * EVP_Cipher even appends/verifies MAC.
        + */
        +#define		EVP_CTRL_AEAD_TLS1_AAD		0x16
        +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
        +#define		EVP_CTRL_AEAD_SET_MAC_KEY	0x17
        +/* Set the GCM invocation field, decrypt only */
        +#define		EVP_CTRL_GCM_SET_IV_INV		0x18
        +
        +/* GCM TLS constants */
        +/* Length of fixed part of IV derived from PRF */
        +#define EVP_GCM_TLS_FIXED_IV_LEN			4
        +/* Length of explicit part of IV part of TLS records */
        +#define EVP_GCM_TLS_EXPLICIT_IV_LEN			8
        +/* Length of tag for TLS */
        +#define EVP_GCM_TLS_TAG_LEN				16
        +
        +typedef struct evp_cipher_info_st
        +	{
        +	const EVP_CIPHER *cipher;
        +	unsigned char iv[EVP_MAX_IV_LENGTH];
        +	} EVP_CIPHER_INFO;
        +
        +struct evp_cipher_ctx_st
        +	{
        +	const EVP_CIPHER *cipher;
        +	ENGINE *engine;	/* functional reference if 'cipher' is ENGINE-provided */
        +	int encrypt;		/* encrypt or decrypt */
        +	int buf_len;		/* number we have left */
        +
        +	unsigned char  oiv[EVP_MAX_IV_LENGTH];	/* original iv */
        +	unsigned char  iv[EVP_MAX_IV_LENGTH];	/* working iv */
        +	unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
        +	int num;				/* used by cfb/ofb/ctr mode */
        +
        +	void *app_data;		/* application stuff */
        +	int key_len;		/* May change for variable length cipher */
        +	unsigned long flags;	/* Various flags */
        +	void *cipher_data; /* per EVP data */
        +	int final_used;
        +	int block_mask;
        +	unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
        +	} /* EVP_CIPHER_CTX */;
        +
        +typedef struct evp_Encode_Ctx_st
        +	{
        +	int num;	/* number saved in a partial encode/decode */
        +	int length;	/* The length is either the output line length
        +			 * (in input bytes) or the shortest input line
        +			 * length that is ok.  Once decoding begins,
        +			 * the length is adjusted up each time a longer
        +			 * line is decoded */
        +	unsigned char enc_data[80];	/* data to encode */
        +	int line_num;	/* number read on current line */
        +	int expect_nl;
        +	} EVP_ENCODE_CTX;
        +
        +/* Password based encryption function */
        +typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +		ASN1_TYPE *param, const EVP_CIPHER *cipher,
        +                const EVP_MD *md, int en_de);
        +
        +#ifndef OPENSSL_NO_RSA
        +#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
        +					(char *)(rsa))
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
        +					(char *)(dsa))
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
        +					(char *)(dh))
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
        +                                        (char *)(eckey))
        +#endif
        +
        +/* Add some extra combinations */
        +#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
        +#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
        +#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
        +#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
        +
        +int EVP_MD_type(const EVP_MD *md);
        +#define EVP_MD_nid(e)			EVP_MD_type(e)
        +#define EVP_MD_name(e)			OBJ_nid2sn(EVP_MD_nid(e))
        +int EVP_MD_pkey_type(const EVP_MD *md);	
        +int EVP_MD_size(const EVP_MD *md);
        +int EVP_MD_block_size(const EVP_MD *md);
        +unsigned long EVP_MD_flags(const EVP_MD *md);
        +
        +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
        +#define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
        +#define EVP_MD_CTX_block_size(e)	EVP_MD_block_size(EVP_MD_CTX_md(e))
        +#define EVP_MD_CTX_type(e)		EVP_MD_type(EVP_MD_CTX_md(e))
        +
        +int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
        +#define EVP_CIPHER_name(e)		OBJ_nid2sn(EVP_CIPHER_nid(e))
        +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
        +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
        +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
        +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
        +#define EVP_CIPHER_mode(e)		(EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
        +
        +const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
        +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
        +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
        +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
        +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
        +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
        +void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
        +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
        +#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
        +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
        +#define EVP_CIPHER_CTX_mode(e)		(EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
        +
        +#define EVP_ENCODE_LENGTH(l)	(((l+2)/3*4)+(l/48+1)*2+80)
        +#define EVP_DECODE_LENGTH(l)	((l+3)/4*3+80)
        +
        +#define EVP_SignInit_ex(a,b,c)		EVP_DigestInit_ex(a,b,c)
        +#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
        +#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
        +#define	EVP_VerifyInit_ex(a,b,c)	EVP_DigestInit_ex(a,b,c)
        +#define	EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
        +#define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
        +#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
        +#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
        +#define EVP_DigestSignUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
        +#define EVP_DigestVerifyUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
        +
        +#ifdef CONST_STRICT
        +void BIO_set_md(BIO *,const EVP_MD *md);
        +#else
        +# define BIO_set_md(b,md)		BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
        +#endif
        +#define BIO_get_md(b,mdp)		BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
        +#define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
        +#define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
        +#define BIO_get_cipher_status(b)	BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
        +#define BIO_get_cipher_ctx(b,c_pp)	BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
        +
        +int EVP_Cipher(EVP_CIPHER_CTX *c,
        +		unsigned char *out,
        +		const unsigned char *in,
        +		unsigned int inl);
        +
        +#define EVP_add_cipher_alias(n,alias) \
        +	OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
        +#define EVP_add_digest_alias(n,alias) \
        +	OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
        +#define EVP_delete_cipher_alias(alias) \
        +	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
        +#define EVP_delete_digest_alias(alias) \
        +	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
        +
        +void	EVP_MD_CTX_init(EVP_MD_CTX *ctx);
        +int	EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
        +EVP_MD_CTX *EVP_MD_CTX_create(void);
        +void	EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
        +int     EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
        +void	EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
        +void	EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
        +int 	EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags);
        +int	EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
        +int	EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
        +			 size_t cnt);
        +int	EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
        +int	EVP_Digest(const void *data, size_t count,
        +		unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl);
        +
        +int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
        +int	EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
        +int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
        +
        +int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
        +int	EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify);
        +void	EVP_set_pw_prompt(const char *prompt);
        +char *	EVP_get_pw_prompt(void);
        +
        +int	EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
        +		const unsigned char *salt, const unsigned char *data,
        +		int datal, int count, unsigned char *key,unsigned char *iv);
        +
        +void	EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
        +void	EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
        +int 	EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx,int flags);
        +
        +int	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
        +		const unsigned char *key, const unsigned char *iv);
        +int	EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
        +		const unsigned char *key, const unsigned char *iv);
        +int	EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		int *outl, const unsigned char *in, int inl);
        +int	EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
        +int	EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
        +
        +int	EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
        +		const unsigned char *key, const unsigned char *iv);
        +int	EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
        +		const unsigned char *key, const unsigned char *iv);
        +int	EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		int *outl, const unsigned char *in, int inl);
        +int	EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
        +int	EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
        +
        +int	EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
        +		       const unsigned char *key,const unsigned char *iv,
        +		       int enc);
        +int	EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
        +		       const unsigned char *key,const unsigned char *iv,
        +		       int enc);
        +int	EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +		int *outl, const unsigned char *in, int inl);
        +int	EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
        +int	EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
        +
        +int	EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
        +		EVP_PKEY *pkey);
        +
        +int	EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
        +		unsigned int siglen,EVP_PKEY *pkey);
        +
        +int	EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
        +int	EVP_DigestSignFinal(EVP_MD_CTX *ctx,
        +			unsigned char *sigret, size_t *siglen);
        +
        +int	EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
        +int	EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
        +			unsigned char *sig, size_t siglen);
        +
        +int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
        +		const unsigned char *ek, int ekl, const unsigned char *iv,
        +		EVP_PKEY *priv);
        +int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
        +
        +int	EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +		 unsigned char **ek, int *ekl, unsigned char *iv,
        +		EVP_PKEY **pubk, int npubk);
        +int	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
        +
        +void	EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
        +void	EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
        +		const unsigned char *in,int inl);
        +void	EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
        +int	EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
        +
        +void	EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
        +int	EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
        +		const unsigned char *in, int inl);
        +int	EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
        +		char *out, int *outl);
        +int	EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
        +
        +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
        +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
        +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
        +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
        +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
        +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
        +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
        +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
        +
        +#ifndef OPENSSL_NO_BIO
        +BIO_METHOD *BIO_f_md(void);
        +BIO_METHOD *BIO_f_base64(void);
        +BIO_METHOD *BIO_f_cipher(void);
        +BIO_METHOD *BIO_f_reliable(void);
        +void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,const unsigned char *k,
        +		const unsigned char *i, int enc);
        +#endif
        +
        +const EVP_MD *EVP_md_null(void);
        +#ifndef OPENSSL_NO_MD2
        +const EVP_MD *EVP_md2(void);
        +#endif
        +#ifndef OPENSSL_NO_MD4
        +const EVP_MD *EVP_md4(void);
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +const EVP_MD *EVP_md5(void);
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +const EVP_MD *EVP_sha(void);
        +const EVP_MD *EVP_sha1(void);
        +const EVP_MD *EVP_dss(void);
        +const EVP_MD *EVP_dss1(void);
        +const EVP_MD *EVP_ecdsa(void);
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +const EVP_MD *EVP_sha224(void);
        +const EVP_MD *EVP_sha256(void);
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +const EVP_MD *EVP_sha384(void);
        +const EVP_MD *EVP_sha512(void);
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +const EVP_MD *EVP_mdc2(void);
        +#endif
        +#ifndef OPENSSL_NO_RIPEMD
        +const EVP_MD *EVP_ripemd160(void);
        +#endif
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +const EVP_MD *EVP_whirlpool(void);
        +#endif
        +const EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
        +#ifndef OPENSSL_NO_DES
        +const EVP_CIPHER *EVP_des_ecb(void);
        +const EVP_CIPHER *EVP_des_ede(void);
        +const EVP_CIPHER *EVP_des_ede3(void);
        +const EVP_CIPHER *EVP_des_ede_ecb(void);
        +const EVP_CIPHER *EVP_des_ede3_ecb(void);
        +const EVP_CIPHER *EVP_des_cfb64(void);
        +# define EVP_des_cfb EVP_des_cfb64
        +const EVP_CIPHER *EVP_des_cfb1(void);
        +const EVP_CIPHER *EVP_des_cfb8(void);
        +const EVP_CIPHER *EVP_des_ede_cfb64(void);
        +# define EVP_des_ede_cfb EVP_des_ede_cfb64
        +#if 0
        +const EVP_CIPHER *EVP_des_ede_cfb1(void);
        +const EVP_CIPHER *EVP_des_ede_cfb8(void);
        +#endif
        +const EVP_CIPHER *EVP_des_ede3_cfb64(void);
        +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64
        +const EVP_CIPHER *EVP_des_ede3_cfb1(void);
        +const EVP_CIPHER *EVP_des_ede3_cfb8(void);
        +const EVP_CIPHER *EVP_des_ofb(void);
        +const EVP_CIPHER *EVP_des_ede_ofb(void);
        +const EVP_CIPHER *EVP_des_ede3_ofb(void);
        +const EVP_CIPHER *EVP_des_cbc(void);
        +const EVP_CIPHER *EVP_des_ede_cbc(void);
        +const EVP_CIPHER *EVP_des_ede3_cbc(void);
        +const EVP_CIPHER *EVP_desx_cbc(void);
        +/* This should now be supported through the dev_crypto ENGINE. But also, why are
        + * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */
        +#if 0
        +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
        +const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
        +const EVP_CIPHER *EVP_dev_crypto_rc4(void);
        +const EVP_MD *EVP_dev_crypto_md5(void);
        +# endif
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +const EVP_CIPHER *EVP_rc4(void);
        +const EVP_CIPHER *EVP_rc4_40(void);
        +#ifndef OPENSSL_NO_MD5
        +const EVP_CIPHER *EVP_rc4_hmac_md5(void);
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +const EVP_CIPHER *EVP_idea_ecb(void);
        +const EVP_CIPHER *EVP_idea_cfb64(void);
        +# define EVP_idea_cfb EVP_idea_cfb64
        +const EVP_CIPHER *EVP_idea_ofb(void);
        +const EVP_CIPHER *EVP_idea_cbc(void);
        +#endif
        +#ifndef OPENSSL_NO_RC2
        +const EVP_CIPHER *EVP_rc2_ecb(void);
        +const EVP_CIPHER *EVP_rc2_cbc(void);
        +const EVP_CIPHER *EVP_rc2_40_cbc(void);
        +const EVP_CIPHER *EVP_rc2_64_cbc(void);
        +const EVP_CIPHER *EVP_rc2_cfb64(void);
        +# define EVP_rc2_cfb EVP_rc2_cfb64
        +const EVP_CIPHER *EVP_rc2_ofb(void);
        +#endif
        +#ifndef OPENSSL_NO_BF
        +const EVP_CIPHER *EVP_bf_ecb(void);
        +const EVP_CIPHER *EVP_bf_cbc(void);
        +const EVP_CIPHER *EVP_bf_cfb64(void);
        +# define EVP_bf_cfb EVP_bf_cfb64
        +const EVP_CIPHER *EVP_bf_ofb(void);
        +#endif
        +#ifndef OPENSSL_NO_CAST
        +const EVP_CIPHER *EVP_cast5_ecb(void);
        +const EVP_CIPHER *EVP_cast5_cbc(void);
        +const EVP_CIPHER *EVP_cast5_cfb64(void);
        +# define EVP_cast5_cfb EVP_cast5_cfb64
        +const EVP_CIPHER *EVP_cast5_ofb(void);
        +#endif
        +#ifndef OPENSSL_NO_RC5
        +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
        +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
        +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
        +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
        +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
        +#endif
        +#ifndef OPENSSL_NO_AES
        +const EVP_CIPHER *EVP_aes_128_ecb(void);
        +const EVP_CIPHER *EVP_aes_128_cbc(void);
        +const EVP_CIPHER *EVP_aes_128_cfb1(void);
        +const EVP_CIPHER *EVP_aes_128_cfb8(void);
        +const EVP_CIPHER *EVP_aes_128_cfb128(void);
        +# define EVP_aes_128_cfb EVP_aes_128_cfb128
        +const EVP_CIPHER *EVP_aes_128_ofb(void);
        +const EVP_CIPHER *EVP_aes_128_ctr(void);
        +const EVP_CIPHER *EVP_aes_128_ccm(void);
        +const EVP_CIPHER *EVP_aes_128_gcm(void);
        +const EVP_CIPHER *EVP_aes_128_xts(void);
        +const EVP_CIPHER *EVP_aes_192_ecb(void);
        +const EVP_CIPHER *EVP_aes_192_cbc(void);
        +const EVP_CIPHER *EVP_aes_192_cfb1(void);
        +const EVP_CIPHER *EVP_aes_192_cfb8(void);
        +const EVP_CIPHER *EVP_aes_192_cfb128(void);
        +# define EVP_aes_192_cfb EVP_aes_192_cfb128
        +const EVP_CIPHER *EVP_aes_192_ofb(void);
        +const EVP_CIPHER *EVP_aes_192_ctr(void);
        +const EVP_CIPHER *EVP_aes_192_ccm(void);
        +const EVP_CIPHER *EVP_aes_192_gcm(void);
        +const EVP_CIPHER *EVP_aes_256_ecb(void);
        +const EVP_CIPHER *EVP_aes_256_cbc(void);
        +const EVP_CIPHER *EVP_aes_256_cfb1(void);
        +const EVP_CIPHER *EVP_aes_256_cfb8(void);
        +const EVP_CIPHER *EVP_aes_256_cfb128(void);
        +# define EVP_aes_256_cfb EVP_aes_256_cfb128
        +const EVP_CIPHER *EVP_aes_256_ofb(void);
        +const EVP_CIPHER *EVP_aes_256_ctr(void);
        +const EVP_CIPHER *EVP_aes_256_ccm(void);
        +const EVP_CIPHER *EVP_aes_256_gcm(void);
        +const EVP_CIPHER *EVP_aes_256_xts(void);
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
        +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
        +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
        +#endif
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +const EVP_CIPHER *EVP_camellia_128_ecb(void);
        +const EVP_CIPHER *EVP_camellia_128_cbc(void);
        +const EVP_CIPHER *EVP_camellia_128_cfb1(void);
        +const EVP_CIPHER *EVP_camellia_128_cfb8(void);
        +const EVP_CIPHER *EVP_camellia_128_cfb128(void);
        +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128
        +const EVP_CIPHER *EVP_camellia_128_ofb(void);
        +const EVP_CIPHER *EVP_camellia_192_ecb(void);
        +const EVP_CIPHER *EVP_camellia_192_cbc(void);
        +const EVP_CIPHER *EVP_camellia_192_cfb1(void);
        +const EVP_CIPHER *EVP_camellia_192_cfb8(void);
        +const EVP_CIPHER *EVP_camellia_192_cfb128(void);
        +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128
        +const EVP_CIPHER *EVP_camellia_192_ofb(void);
        +const EVP_CIPHER *EVP_camellia_256_ecb(void);
        +const EVP_CIPHER *EVP_camellia_256_cbc(void);
        +const EVP_CIPHER *EVP_camellia_256_cfb1(void);
        +const EVP_CIPHER *EVP_camellia_256_cfb8(void);
        +const EVP_CIPHER *EVP_camellia_256_cfb128(void);
        +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128
        +const EVP_CIPHER *EVP_camellia_256_ofb(void);
        +#endif
        +
        +#ifndef OPENSSL_NO_SEED
        +const EVP_CIPHER *EVP_seed_ecb(void);
        +const EVP_CIPHER *EVP_seed_cbc(void);
        +const EVP_CIPHER *EVP_seed_cfb128(void);
        +# define EVP_seed_cfb EVP_seed_cfb128
        +const EVP_CIPHER *EVP_seed_ofb(void);
        +#endif
        +
        +void OPENSSL_add_all_algorithms_noconf(void);
        +void OPENSSL_add_all_algorithms_conf(void);
        +
        +#ifdef OPENSSL_LOAD_CONF
        +#define OpenSSL_add_all_algorithms() \
        +		OPENSSL_add_all_algorithms_conf()
        +#else
        +#define OpenSSL_add_all_algorithms() \
        +		OPENSSL_add_all_algorithms_noconf()
        +#endif
        +
        +void OpenSSL_add_all_ciphers(void);
        +void OpenSSL_add_all_digests(void);
        +#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
        +#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
        +#define SSLeay_add_all_digests() OpenSSL_add_all_digests()
        +
        +int EVP_add_cipher(const EVP_CIPHER *cipher);
        +int EVP_add_digest(const EVP_MD *digest);
        +
        +const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
        +const EVP_MD *EVP_get_digestbyname(const char *name);
        +void EVP_cleanup(void);
        +
        +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
        +		const char *from, const char *to, void *x), void *arg);
        +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
        +		const char *from, const char *to, void *x), void *arg);
        +
        +void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph,
        +		const char *from, const char *to, void *x), void *arg);
        +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph,
        +		const char *from, const char *to, void *x), void *arg);
        +
        +int		EVP_PKEY_decrypt_old(unsigned char *dec_key,
        +			const unsigned char *enc_key,int enc_key_len,
        +			EVP_PKEY *private_key);
        +int		EVP_PKEY_encrypt_old(unsigned char *enc_key,
        +			const unsigned char *key,int key_len,
        +			EVP_PKEY *pub_key);
        +int		EVP_PKEY_type(int type);
        +int		EVP_PKEY_id(const EVP_PKEY *pkey);
        +int		EVP_PKEY_base_id(const EVP_PKEY *pkey);
        +int		EVP_PKEY_bits(EVP_PKEY *pkey);
        +int		EVP_PKEY_size(EVP_PKEY *pkey);
        +int 		EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
        +int		EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
        +int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
        +void *		EVP_PKEY_get0(EVP_PKEY *pkey);
        +
        +#ifndef OPENSSL_NO_RSA
        +struct rsa_st;
        +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,struct rsa_st *key);
        +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +struct dsa_st;
        +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,struct dsa_st *key);
        +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +struct dh_st;
        +int EVP_PKEY_set1_DH(EVP_PKEY *pkey,struct dh_st *key);
        +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
        +#endif
        +#ifndef OPENSSL_NO_EC
        +struct ec_key_st;
        +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,struct ec_key_st *key);
        +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
        +#endif
        +
        +EVP_PKEY *	EVP_PKEY_new(void);
        +void		EVP_PKEY_free(EVP_PKEY *pkey);
        +
        +EVP_PKEY *	d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
        +			long length);
        +int		i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
        +
        +EVP_PKEY *	d2i_PrivateKey(int type,EVP_PKEY **a, const unsigned char **pp,
        +			long length);
        +EVP_PKEY *	d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
        +			long length);
        +int		i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
        +
        +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
        +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
        +int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
        +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
        +
        +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
        +
        +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx);
        +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx);
        +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx);
        +
        +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
        +
        +int EVP_CIPHER_type(const EVP_CIPHER *ctx);
        +
        +/* calls methods */
        +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
        +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
        +
        +/* These are used by EVP_CIPHER methods */
        +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
        +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
        +
        +/* PKCS5 password based encryption */
        +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
        +			 int en_de);
        +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
        +			   const unsigned char *salt, int saltlen, int iter,
        +			   int keylen, unsigned char *out);
        +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
        +			   const unsigned char *salt, int saltlen, int iter,
        +			   const EVP_MD *digest,
        +		      int keylen, unsigned char *out);
        +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
        +			 int en_de);
        +
        +void PKCS5_PBE_add(void);
        +
        +int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
        +	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
        +
        +/* PBE type */
        +
        +/* Can appear as the outermost AlgorithmIdentifier */
        +#define EVP_PBE_TYPE_OUTER	0x0
        +/* Is an PRF type OID */
        +#define EVP_PBE_TYPE_PRF	0x1
        +
        +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
        +	     EVP_PBE_KEYGEN *keygen);
        +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
        +		    EVP_PBE_KEYGEN *keygen);
        +int EVP_PBE_find(int type, int pbe_nid,
        +			int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen);
        +void EVP_PBE_cleanup(void);
        +
        +#define ASN1_PKEY_ALIAS		0x1
        +#define ASN1_PKEY_DYNAMIC	0x2
        +#define ASN1_PKEY_SIGPARAM_NULL	0x4
        +
        +#define ASN1_PKEY_CTRL_PKCS7_SIGN	0x1
        +#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT	0x2
        +#define ASN1_PKEY_CTRL_DEFAULT_MD_NID	0x3
        +#define ASN1_PKEY_CTRL_CMS_SIGN		0x5
        +#define ASN1_PKEY_CTRL_CMS_ENVELOPE	0x7
        +
        +int EVP_PKEY_asn1_get_count(void);
        +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
        +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
        +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
        +					const char *str, int len);
        +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
        +int EVP_PKEY_asn1_add_alias(int to, int from);
        +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
        +				const char **pinfo, const char **ppem_str,
        +					const EVP_PKEY_ASN1_METHOD *ameth);
        +
        +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
        +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
        +					const char *pem_str, const char *info);
        +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
        +			const EVP_PKEY_ASN1_METHOD *src);
        +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
        +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
        +		int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
        +		int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
        +		int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx),
        +		int (*pkey_size)(const EVP_PKEY *pk),
        +		int (*pkey_bits)(const EVP_PKEY *pk));
        +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
        +		int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
        +		int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx));
        +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*param_decode)(EVP_PKEY *pkey,
        +				const unsigned char **pder, int derlen),
        +		int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
        +		int (*param_missing)(const EVP_PKEY *pk),
        +		int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
        +		int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
        +		int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *pctx));
        +
        +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
        +		void (*pkey_free)(EVP_PKEY *pkey));
        +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
        +		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
        +							long arg1, void *arg2));
        +
        +
        +#define EVP_PKEY_OP_UNDEFINED		0
        +#define EVP_PKEY_OP_PARAMGEN		(1<<1)
        +#define EVP_PKEY_OP_KEYGEN		(1<<2)
        +#define EVP_PKEY_OP_SIGN		(1<<3)
        +#define EVP_PKEY_OP_VERIFY		(1<<4)
        +#define EVP_PKEY_OP_VERIFYRECOVER	(1<<5)
        +#define EVP_PKEY_OP_SIGNCTX		(1<<6)
        +#define EVP_PKEY_OP_VERIFYCTX		(1<<7)
        +#define EVP_PKEY_OP_ENCRYPT		(1<<8)
        +#define EVP_PKEY_OP_DECRYPT		(1<<9)
        +#define EVP_PKEY_OP_DERIVE		(1<<10)
        +
        +#define EVP_PKEY_OP_TYPE_SIG	\
        +	(EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
        +		| EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
        +
        +#define EVP_PKEY_OP_TYPE_CRYPT \
        +	(EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
        +
        +#define EVP_PKEY_OP_TYPE_NOGEN \
        +	(EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
        +
        +#define EVP_PKEY_OP_TYPE_GEN \
        +		(EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
        +
        +#define	 EVP_PKEY_CTX_set_signature_md(ctx, md)	\
        +		EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
        +					EVP_PKEY_CTRL_MD, 0, (void *)md)
        +
        +#define EVP_PKEY_CTRL_MD		1
        +#define EVP_PKEY_CTRL_PEER_KEY		2
        +
        +#define EVP_PKEY_CTRL_PKCS7_ENCRYPT	3
        +#define EVP_PKEY_CTRL_PKCS7_DECRYPT	4
        +
        +#define EVP_PKEY_CTRL_PKCS7_SIGN	5
        +
        +#define EVP_PKEY_CTRL_SET_MAC_KEY	6
        +
        +#define EVP_PKEY_CTRL_DIGESTINIT	7
        +
        +/* Used by GOST key encryption in TLS */
        +#define EVP_PKEY_CTRL_SET_IV 		8
        +
        +#define EVP_PKEY_CTRL_CMS_ENCRYPT	9
        +#define EVP_PKEY_CTRL_CMS_DECRYPT	10
        +#define EVP_PKEY_CTRL_CMS_SIGN		11
        +
        +#define EVP_PKEY_CTRL_CIPHER		12
        +
        +#define EVP_PKEY_ALG_CTRL		0x1000
        +
        +
        +#define EVP_PKEY_FLAG_AUTOARGLEN	2
        +/* Method handles all operations: don't assume any digest related
        + * defaults.
        + */
        +#define EVP_PKEY_FLAG_SIGCTX_CUSTOM	4
        +
        +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
        +EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
        +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
        +				const EVP_PKEY_METHOD *meth);
        +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
        +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
        +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
        +
        +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
        +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
        +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
        +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
        +
        +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
        +				int cmd, int p1, void *p2);
        +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
        +						const char *value);
        +
        +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
        +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
        +
        +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
        +				const unsigned char *key, int keylen);
        +
        +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
        +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
        +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
        +
        +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
        +
        +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
        +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
        +
        +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
        +			unsigned char *sig, size_t *siglen,
        +			const unsigned char *tbs, size_t tbslen);
        +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
        +			const unsigned char *sig, size_t siglen,
        +			const unsigned char *tbs, size_t tbslen);
        +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
        +			unsigned char *rout, size_t *routlen,
        +			const unsigned char *sig, size_t siglen);
        +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
        +			unsigned char *out, size_t *outlen,
        +			const unsigned char *in, size_t inlen);
        +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
        +			unsigned char *out, size_t *outlen,
        +			const unsigned char *in, size_t inlen);
        +
        +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
        +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
        +
        +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
        +
        +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
        +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
        +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
        +
        +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
        +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
        +
        +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
        +
        +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
        +	int (*init)(EVP_PKEY_CTX *ctx));
        +
        +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
        +	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src));
        +
        +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
        +	void (*cleanup)(EVP_PKEY_CTX *ctx));
        +
        +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
        +	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
        +	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
        +
        +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
        +	int (*keygen_init)(EVP_PKEY_CTX *ctx),
        +	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
        +
        +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
        +	int (*sign_init)(EVP_PKEY_CTX *ctx),
        +	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen));
        +
        +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
        +	int (*verify_init)(EVP_PKEY_CTX *ctx),
        +	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
        +					const unsigned char *tbs, size_t tbslen));
        +
        +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
        +	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
        +	int (*verify_recover)(EVP_PKEY_CTX *ctx,
        +					unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen));
        +
        +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
        +	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
        +	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					EVP_MD_CTX *mctx));
        +
        +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
        +	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
        +	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
        +					EVP_MD_CTX *mctx));
        +
        +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
        +	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
        +	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen));
        +
        +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
        +	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
        +	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen));
        +
        +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
        +	int (*derive_init)(EVP_PKEY_CTX *ctx),
        +	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
        +
        +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
        +	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
        +	int (*ctrl_str)(EVP_PKEY_CTX *ctx,
        +					const char *type, const char *value));
        +
        +void EVP_add_alg_module(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.
        + */
        +void ERR_load_EVP_strings(void);
        +
        +/* Error codes for the EVP functions. */
        +
        +/* Function codes. */
        +#define EVP_F_AESNI_INIT_KEY				 165
        +#define EVP_F_AESNI_XTS_CIPHER				 176
        +#define EVP_F_AES_INIT_KEY				 133
        +#define EVP_F_AES_XTS					 172
        +#define EVP_F_AES_XTS_CIPHER				 175
        +#define EVP_F_ALG_MODULE_INIT				 177
        +#define EVP_F_CAMELLIA_INIT_KEY				 159
        +#define EVP_F_CMAC_INIT					 173
        +#define EVP_F_D2I_PKEY					 100
        +#define EVP_F_DO_SIGVER_INIT				 161
        +#define EVP_F_DSAPKEY2PKCS8				 134
        +#define EVP_F_DSA_PKEY2PKCS8				 135
        +#define EVP_F_ECDSA_PKEY2PKCS8				 129
        +#define EVP_F_ECKEY_PKEY2PKCS8				 132
        +#define EVP_F_EVP_CIPHERINIT_EX				 123
        +#define EVP_F_EVP_CIPHER_CTX_COPY			 163
        +#define EVP_F_EVP_CIPHER_CTX_CTRL			 124
        +#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH		 122
        +#define EVP_F_EVP_DECRYPTFINAL_EX			 101
        +#define EVP_F_EVP_DIGESTINIT_EX				 128
        +#define EVP_F_EVP_ENCRYPTFINAL_EX			 127
        +#define EVP_F_EVP_MD_CTX_COPY_EX			 110
        +#define EVP_F_EVP_MD_SIZE				 162
        +#define EVP_F_EVP_OPENINIT				 102
        +#define EVP_F_EVP_PBE_ALG_ADD				 115
        +#define EVP_F_EVP_PBE_ALG_ADD_TYPE			 160
        +#define EVP_F_EVP_PBE_CIPHERINIT			 116
        +#define EVP_F_EVP_PKCS82PKEY				 111
        +#define EVP_F_EVP_PKCS82PKEY_BROKEN			 136
        +#define EVP_F_EVP_PKEY2PKCS8_BROKEN			 113
        +#define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
        +#define EVP_F_EVP_PKEY_CTX_CTRL				 137
        +#define EVP_F_EVP_PKEY_CTX_CTRL_STR			 150
        +#define EVP_F_EVP_PKEY_CTX_DUP				 156
        +#define EVP_F_EVP_PKEY_DECRYPT				 104
        +#define EVP_F_EVP_PKEY_DECRYPT_INIT			 138
        +#define EVP_F_EVP_PKEY_DECRYPT_OLD			 151
        +#define EVP_F_EVP_PKEY_DERIVE				 153
        +#define EVP_F_EVP_PKEY_DERIVE_INIT			 154
        +#define EVP_F_EVP_PKEY_DERIVE_SET_PEER			 155
        +#define EVP_F_EVP_PKEY_ENCRYPT				 105
        +#define EVP_F_EVP_PKEY_ENCRYPT_INIT			 139
        +#define EVP_F_EVP_PKEY_ENCRYPT_OLD			 152
        +#define EVP_F_EVP_PKEY_GET1_DH				 119
        +#define EVP_F_EVP_PKEY_GET1_DSA				 120
        +#define EVP_F_EVP_PKEY_GET1_ECDSA			 130
        +#define EVP_F_EVP_PKEY_GET1_EC_KEY			 131
        +#define EVP_F_EVP_PKEY_GET1_RSA				 121
        +#define EVP_F_EVP_PKEY_KEYGEN				 146
        +#define EVP_F_EVP_PKEY_KEYGEN_INIT			 147
        +#define EVP_F_EVP_PKEY_NEW				 106
        +#define EVP_F_EVP_PKEY_PARAMGEN				 148
        +#define EVP_F_EVP_PKEY_PARAMGEN_INIT			 149
        +#define EVP_F_EVP_PKEY_SIGN				 140
        +#define EVP_F_EVP_PKEY_SIGN_INIT			 141
        +#define EVP_F_EVP_PKEY_VERIFY				 142
        +#define EVP_F_EVP_PKEY_VERIFY_INIT			 143
        +#define EVP_F_EVP_PKEY_VERIFY_RECOVER			 144
        +#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT		 145
        +#define EVP_F_EVP_RIJNDAEL				 126
        +#define EVP_F_EVP_SIGNFINAL				 107
        +#define EVP_F_EVP_VERIFYFINAL				 108
        +#define EVP_F_FIPS_CIPHERINIT				 166
        +#define EVP_F_FIPS_CIPHER_CTX_COPY			 170
        +#define EVP_F_FIPS_CIPHER_CTX_CTRL			 167
        +#define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH		 171
        +#define EVP_F_FIPS_DIGESTINIT				 168
        +#define EVP_F_FIPS_MD_CTX_COPY				 169
        +#define EVP_F_HMAC_INIT_EX				 174
        +#define EVP_F_INT_CTX_NEW				 157
        +#define EVP_F_PKCS5_PBE_KEYIVGEN			 117
        +#define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
        +#define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN			 164
        +#define EVP_F_PKCS8_SET_BROKEN				 112
        +#define EVP_F_PKEY_SET_TYPE				 158
        +#define EVP_F_RC2_MAGIC_TO_METH				 109
        +#define EVP_F_RC5_CTRL					 125
        +
        +/* Reason codes. */
        +#define EVP_R_AES_IV_SETUP_FAILED			 162
        +#define EVP_R_AES_KEY_SETUP_FAILED			 143
        +#define EVP_R_ASN1_LIB					 140
        +#define EVP_R_BAD_BLOCK_LENGTH				 136
        +#define EVP_R_BAD_DECRYPT				 100
        +#define EVP_R_BAD_KEY_LENGTH				 137
        +#define EVP_R_BN_DECODE_ERROR				 112
        +#define EVP_R_BN_PUBKEY_ERROR				 113
        +#define EVP_R_BUFFER_TOO_SMALL				 155
        +#define EVP_R_CAMELLIA_KEY_SETUP_FAILED			 157
        +#define EVP_R_CIPHER_PARAMETER_ERROR			 122
        +#define EVP_R_COMMAND_NOT_SUPPORTED			 147
        +#define EVP_R_CTRL_NOT_IMPLEMENTED			 132
        +#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED		 133
        +#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH		 138
        +#define EVP_R_DECODE_ERROR				 114
        +#define EVP_R_DIFFERENT_KEY_TYPES			 101
        +#define EVP_R_DIFFERENT_PARAMETERS			 153
        +#define EVP_R_DISABLED_FOR_FIPS				 163
        +#define EVP_R_ENCODE_ERROR				 115
        +#define EVP_R_ERROR_LOADING_SECTION			 165
        +#define EVP_R_ERROR_SETTING_FIPS_MODE			 166
        +#define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
        +#define EVP_R_EXPECTING_AN_RSA_KEY			 127
        +#define EVP_R_EXPECTING_A_DH_KEY			 128
        +#define EVP_R_EXPECTING_A_DSA_KEY			 129
        +#define EVP_R_EXPECTING_A_ECDSA_KEY			 141
        +#define EVP_R_EXPECTING_A_EC_KEY			 142
        +#define EVP_R_FIPS_MODE_NOT_SUPPORTED			 167
        +#define EVP_R_INITIALIZATION_ERROR			 134
        +#define EVP_R_INPUT_NOT_INITIALIZED			 111
        +#define EVP_R_INVALID_DIGEST				 152
        +#define EVP_R_INVALID_FIPS_MODE				 168
        +#define EVP_R_INVALID_KEY_LENGTH			 130
        +#define EVP_R_INVALID_OPERATION				 148
        +#define EVP_R_IV_TOO_LARGE				 102
        +#define EVP_R_KEYGEN_FAILURE				 120
        +#define EVP_R_MESSAGE_DIGEST_IS_NULL			 159
        +#define EVP_R_METHOD_NOT_SUPPORTED			 144
        +#define EVP_R_MISSING_PARAMETERS			 103
        +#define EVP_R_NO_CIPHER_SET				 131
        +#define EVP_R_NO_DEFAULT_DIGEST				 158
        +#define EVP_R_NO_DIGEST_SET				 139
        +#define EVP_R_NO_DSA_PARAMETERS				 116
        +#define EVP_R_NO_KEY_SET				 154
        +#define EVP_R_NO_OPERATION_SET				 149
        +#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
        +#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
        +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 150
        +#define EVP_R_OPERATON_NOT_INITIALIZED			 151
        +#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
        +#define EVP_R_PRIVATE_KEY_DECODE_ERROR			 145
        +#define EVP_R_PRIVATE_KEY_ENCODE_ERROR			 146
        +#define EVP_R_PUBLIC_KEY_NOT_RSA			 106
        +#define EVP_R_TOO_LARGE					 164
        +#define EVP_R_UNKNOWN_CIPHER				 160
        +#define EVP_R_UNKNOWN_DIGEST				 161
        +#define EVP_R_UNKNOWN_OPTION				 169
        +#define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
        +#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
        +#define EVP_R_UNSUPPORTED_ALGORITHM			 156
        +#define EVP_R_UNSUPPORTED_CIPHER			 107
        +#define EVP_R_UNSUPPORTED_KEYLENGTH			 123
        +#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
        +#define EVP_R_UNSUPPORTED_KEY_SIZE			 108
        +#define EVP_R_UNSUPPORTED_PRF				 125
        +#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM		 118
        +#define EVP_R_UNSUPPORTED_SALT_TYPE			 126
        +#define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
        +#define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_acnf.c b/vendor/openssl/openssl/crypto/evp/evp_acnf.c
        new file mode 100644
        index 000000000..643a1864e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_acnf.c
        @@ -0,0 +1,73 @@
        +/* evp_acnf.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/conf.h>
        +
        +
        +/* Load all algorithms and configure OpenSSL.
        + * This function is called automatically when
        + * OPENSSL_LOAD_CONF is set.
        + */
        +
        +void OPENSSL_add_all_algorithms_conf(void)
        +	{
        +	OPENSSL_add_all_algorithms_noconf();
        +	OPENSSL_config(NULL);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_cnf.c b/vendor/openssl/openssl/crypto/evp/evp_cnf.c
        new file mode 100644
        index 000000000..2e4db3023
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_cnf.c
        @@ -0,0 +1,125 @@
        +/* evp_cnf.c */
        +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
        + * project 2007.
        + */
        +/* ====================================================================
        + * Copyright (c) 2007 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 <stdio.h>
        +#include <ctype.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/dso.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +
        +/* Algorithm configuration module. */
        +
        +static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
        +	{
        +	int i;
        +	const char *oid_section;
        +	STACK_OF(CONF_VALUE) *sktmp;
        +	CONF_VALUE *oval;
        +	oid_section = CONF_imodule_get_value(md);
        +	if(!(sktmp = NCONF_get_section(cnf, oid_section)))
        +		{
        +		EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
        +		return 0;
        +		}
        +	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
        +		{
        +		oval = sk_CONF_VALUE_value(sktmp, i);
        +		if (!strcmp(oval->name, "fips_mode"))
        +			{
        +			int m;
        +			if (!X509V3_get_value_bool(oval, &m))
        +				{
        +				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
        +				return 0;
        +				}
        +			if (m > 0)
        +				{
        +#ifdef OPENSSL_FIPS
        +				if (!FIPS_mode() && !FIPS_mode_set(1))
        +					{
        +					EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
        +					return 0;
        +					}
        +#else
        +				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
        +				return 0;
        +#endif
        +				}
        +			}
        +		else
        +			{
        +			EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
        +			ERR_add_error_data(4, "name=", oval->name,
        +						", value=", oval->value);
        +			}
        +				
        +		}
        +	return 1;
        +	}
        +
        +void EVP_add_alg_module(void)
        +	{
        +	CONF_module_add("alg_section", alg_module_init, 0);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_enc.c b/vendor/openssl/openssl/crypto/evp/evp_enc.c
        new file mode 100644
        index 000000000..0c54f05e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_enc.c
        @@ -0,0 +1,681 @@
        +/* crypto/evp/evp_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +#include "evp_locl.h"
        +
        +#ifdef OPENSSL_FIPS
        +#define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
        +#else
        +#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
        +#endif
        +
        +
        +const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
        +
        +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
        +	{
        +	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
        +	/* ctx->cipher=NULL; */
        +	}
        +
        +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
        +	{
        +	EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
        +	if (ctx)
        +		EVP_CIPHER_CTX_init(ctx);
        +	return ctx;
        +	}
        +
        +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
        +	     const unsigned char *key, const unsigned char *iv, int enc)
        +	{
        +	if (cipher)
        +		EVP_CIPHER_CTX_init(ctx);
        +	return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
        +	}
        +
        +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
        +	     const unsigned char *key, const unsigned char *iv, int enc)
        +	{
        +	if (enc == -1)
        +		enc = ctx->encrypt;
        +	else
        +		{
        +		if (enc)
        +			enc = 1;
        +		ctx->encrypt = enc;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
        +	 * so this context may already have an ENGINE! Try to avoid releasing
        +	 * the previous handle, re-querying for an ENGINE, and having a
        +	 * reinitialisation, when it may all be unecessary. */
        +	if (ctx->engine && ctx->cipher && (!cipher ||
        +			(cipher && (cipher->nid == ctx->cipher->nid))))
        +		goto skip_to_init;
        +#endif
        +	if (cipher)
        +		{
        +		/* Ensure a context left lying around from last time is cleared
        +		 * (the previous check attempted to avoid this if the same
        +		 * ENGINE and EVP_CIPHER could be used). */
        +		if (ctx->cipher)
        +			{
        +			unsigned long flags = ctx->flags;
        +			EVP_CIPHER_CTX_cleanup(ctx);
        +			/* Restore encrypt and flags */
        +			ctx->encrypt = enc;
        +			ctx->flags = flags;
        +			}
        +#ifndef OPENSSL_NO_ENGINE
        +		if(impl)
        +			{
        +			if (!ENGINE_init(impl))
        +				{
        +				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
        +				return 0;
        +				}
        +			}
        +		else
        +			/* Ask if an ENGINE is reserved for this job */
        +			impl = ENGINE_get_cipher_engine(cipher->nid);
        +		if(impl)
        +			{
        +			/* There's an ENGINE for this job ... (apparently) */
        +			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
        +			if(!c)
        +				{
        +				/* One positive side-effect of US's export
        +				 * control history, is that we should at least
        +				 * be able to avoid using US mispellings of
        +				 * "initialisation"? */
        +				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
        +				return 0;
        +				}
        +			/* We'll use the ENGINE's private cipher definition */
        +			cipher = c;
        +			/* Store the ENGINE functional reference so we know
        +			 * 'cipher' came from an ENGINE and we need to release
        +			 * it when done. */
        +			ctx->engine = impl;
        +			}
        +		else
        +			ctx->engine = NULL;
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return FIPS_cipherinit(ctx, cipher, key, iv, enc);
        +#endif
        +		ctx->cipher=cipher;
        +		if (ctx->cipher->ctx_size)
        +			{
        +			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
        +			if (!ctx->cipher_data)
        +				{
        +				EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +			}
        +		else
        +			{
        +			ctx->cipher_data = NULL;
        +			}
        +		ctx->key_len = cipher->key_len;
        +		ctx->flags = 0;
        +		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
        +			{
        +			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
        +				{
        +				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
        +				return 0;
        +				}
        +			}
        +		}
        +	else if(!ctx->cipher)
        +		{
        +		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
        +		return 0;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +skip_to_init:
        +#endif
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		return FIPS_cipherinit(ctx, cipher, key, iv, enc);
        +#endif
        +	/* we assume block size is a power of 2 in *cryptUpdate */
        +	OPENSSL_assert(ctx->cipher->block_size == 1
        +	    || ctx->cipher->block_size == 8
        +	    || ctx->cipher->block_size == 16);
        +
        +	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
        +		switch(EVP_CIPHER_CTX_mode(ctx)) {
        +
        +			case EVP_CIPH_STREAM_CIPHER:
        +			case EVP_CIPH_ECB_MODE:
        +			break;
        +
        +			case EVP_CIPH_CFB_MODE:
        +			case EVP_CIPH_OFB_MODE:
        +
        +			ctx->num = 0;
        +			/* fall-through */
        +
        +			case EVP_CIPH_CBC_MODE:
        +
        +			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
        +					(int)sizeof(ctx->iv));
        +			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
        +			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
        +			break;
        +
        +			case EVP_CIPH_CTR_MODE:
        +			ctx->num = 0;
        +			/* Don't reuse IV for CTR mode */
        +			if(iv)
        +				memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
        +			break;
        +
        +			default:
        +			return 0;
        +			break;
        +		}
        +	}
        +
        +	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
        +		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
        +	}
        +	ctx->buf_len=0;
        +	ctx->final_used=0;
        +	ctx->block_mask=ctx->cipher->block_size-1;
        +	return 1;
        +	}
        +
        +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        +	     const unsigned char *in, int inl)
        +	{
        +	if (ctx->encrypt)
        +		return EVP_EncryptUpdate(ctx,out,outl,in,inl);
        +	else	return EVP_DecryptUpdate(ctx,out,outl,in,inl);
        +	}
        +
        +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	if (ctx->encrypt)
        +		return EVP_EncryptFinal_ex(ctx,out,outl);
        +	else	return EVP_DecryptFinal_ex(ctx,out,outl);
        +	}
        +
        +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	if (ctx->encrypt)
        +		return EVP_EncryptFinal(ctx,out,outl);
        +	else	return EVP_DecryptFinal(ctx,out,outl);
        +	}
        +
        +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
        +	     const unsigned char *key, const unsigned char *iv)
        +	{
        +	return EVP_CipherInit(ctx, cipher, key, iv, 1);
        +	}
        +
        +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
        +		const unsigned char *key, const unsigned char *iv)
        +	{
        +	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
        +	}
        +
        +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
        +	     const unsigned char *key, const unsigned char *iv)
        +	{
        +	return EVP_CipherInit(ctx, cipher, key, iv, 0);
        +	}
        +
        +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
        +	     const unsigned char *key, const unsigned char *iv)
        +	{
        +	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
        +	}
        +
        +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        +	     const unsigned char *in, int inl)
        +	{
        +	int i,j,bl;
        +
        +	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
        +		{
        +		i = M_do_cipher(ctx, out, in, inl);
        +		if (i < 0)
        +			return 0;
        +		else
        +			*outl = i;
        +		return 1;
        +		}
        +
        +	if (inl <= 0)
        +		{
        +		*outl = 0;
        +		return inl == 0;
        +		}
        +
        +	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
        +		{
        +		if(M_do_cipher(ctx,out,in,inl))
        +			{
        +			*outl=inl;
        +			return 1;
        +			}
        +		else
        +			{
        +			*outl=0;
        +			return 0;
        +			}
        +		}
        +	i=ctx->buf_len;
        +	bl=ctx->cipher->block_size;
        +	OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
        +	if (i != 0)
        +		{
        +		if (i+inl < bl)
        +			{
        +			memcpy(&(ctx->buf[i]),in,inl);
        +			ctx->buf_len+=inl;
        +			*outl=0;
        +			return 1;
        +			}
        +		else
        +			{
        +			j=bl-i;
        +			memcpy(&(ctx->buf[i]),in,j);
        +			if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
        +			inl-=j;
        +			in+=j;
        +			out+=bl;
        +			*outl=bl;
        +			}
        +		}
        +	else
        +		*outl = 0;
        +	i=inl&(bl-1);
        +	inl-=i;
        +	if (inl > 0)
        +		{
        +		if(!M_do_cipher(ctx,out,in,inl)) return 0;
        +		*outl+=inl;
        +		}
        +
        +	if (i != 0)
        +		memcpy(ctx->buf,&(in[inl]),i);
        +	ctx->buf_len=i;
        +	return 1;
        +	}
        +
        +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int ret;
        +	ret = EVP_EncryptFinal_ex(ctx, out, outl);
        +	return ret;
        +	}
        +
        +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int n,ret;
        +	unsigned int i, b, bl;
        +
        +	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
        +		{
        +		ret = M_do_cipher(ctx, out, NULL, 0);
        +		if (ret < 0)
        +			return 0;
        +		else 
        +			*outl = ret;
        +		return 1;
        +		}
        +
        +	b=ctx->cipher->block_size;
        +	OPENSSL_assert(b <= sizeof ctx->buf);
        +	if (b == 1)
        +		{
        +		*outl=0;
        +		return 1;
        +		}
        +	bl=ctx->buf_len;
        +	if (ctx->flags & EVP_CIPH_NO_PADDING)
        +		{
        +		if(bl)
        +			{
        +			EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
        +			return 0;
        +			}
        +		*outl = 0;
        +		return 1;
        +		}
        +
        +	n=b-bl;
        +	for (i=bl; i<b; i++)
        +		ctx->buf[i]=n;
        +	ret=M_do_cipher(ctx,out,ctx->buf,b);
        +
        +
        +	if(ret)
        +		*outl=b;
        +
        +	return ret;
        +	}
        +
        +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        +	     const unsigned char *in, int inl)
        +	{
        +	int fix_len;
        +	unsigned int b;
        +
        +	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
        +		{
        +		fix_len = M_do_cipher(ctx, out, in, inl);
        +		if (fix_len < 0)
        +			{
        +			*outl = 0;
        +			return 0;
        +			}
        +		else
        +			*outl = fix_len;
        +		return 1;
        +		}
        +
        +	if (inl <= 0)
        +		{
        +		*outl = 0;
        +		return inl == 0;
        +		}
        +
        +	if (ctx->flags & EVP_CIPH_NO_PADDING)
        +		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
        +
        +	b=ctx->cipher->block_size;
        +	OPENSSL_assert(b <= sizeof ctx->final);
        +
        +	if(ctx->final_used)
        +		{
        +		memcpy(out,ctx->final,b);
        +		out+=b;
        +		fix_len = 1;
        +		}
        +	else
        +		fix_len = 0;
        +
        +
        +	if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
        +		return 0;
        +
        +	/* if we have 'decrypted' a multiple of block size, make sure
        +	 * we have a copy of this last block */
        +	if (b > 1 && !ctx->buf_len)
        +		{
        +		*outl-=b;
        +		ctx->final_used=1;
        +		memcpy(ctx->final,&out[*outl],b);
        +		}
        +	else
        +		ctx->final_used = 0;
        +
        +	if (fix_len)
        +		*outl += b;
        +		
        +	return 1;
        +	}
        +
        +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int ret;
        +	ret = EVP_DecryptFinal_ex(ctx, out, outl);
        +	return ret;
        +	}
        +
        +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int i,n;
        +	unsigned int b;
        +	*outl=0;
        +
        +	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
        +		{
        +		i = M_do_cipher(ctx, out, NULL, 0);
        +		if (i < 0)
        +			return 0;
        +		else
        +			*outl = i;
        +		return 1;
        +		}
        +
        +	b=ctx->cipher->block_size;
        +	if (ctx->flags & EVP_CIPH_NO_PADDING)
        +		{
        +		if(ctx->buf_len)
        +			{
        +			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
        +			return 0;
        +			}
        +		*outl = 0;
        +		return 1;
        +		}
        +	if (b > 1)
        +		{
        +		if (ctx->buf_len || !ctx->final_used)
        +			{
        +			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
        +			return(0);
        +			}
        +		OPENSSL_assert(b <= sizeof ctx->final);
        +		n=ctx->final[b-1];
        +		if (n == 0 || n > (int)b)
        +			{
        +			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
        +			return(0);
        +			}
        +		for (i=0; i<n; i++)
        +			{
        +			if (ctx->final[--b] != n)
        +				{
        +				EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
        +				return(0);
        +				}
        +			}
        +		n=ctx->cipher->block_size-n;
        +		for (i=0; i<n; i++)
        +			out[i]=ctx->final[i];
        +		*outl=n;
        +		}
        +	else
        +		*outl=0;
        +	return(1);
        +	}
        +
        +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
        +	{
        +	if (ctx)
        +		{
        +		EVP_CIPHER_CTX_cleanup(ctx);
        +		OPENSSL_free(ctx);
        +		}
        +	}
        +
        +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
        +	{
        +#ifndef OPENSSL_FIPS
        +	if (c->cipher != NULL)
        +		{
        +		if(c->cipher->cleanup && !c->cipher->cleanup(c))
        +			return 0;
        +		/* Cleanse cipher context data */
        +		if (c->cipher_data)
        +			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
        +		}
        +	if (c->cipher_data)
        +		OPENSSL_free(c->cipher_data);
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +	if (c->engine)
        +		/* The EVP_CIPHER we used belongs to an ENGINE, release the
        +		 * functional reference we held for this reason. */
        +		ENGINE_finish(c->engine);
        +#endif
        +#ifdef OPENSSL_FIPS
        +	FIPS_cipher_ctx_cleanup(c);
        +#endif
        +	memset(c,0,sizeof(EVP_CIPHER_CTX));
        +	return 1;
        +	}
        +
        +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
        +	{
        +	if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
        +		return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
        +	if(c->key_len == keylen) return 1;
        +	if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
        +		{
        +		c->key_len = keylen;
        +		return 1;
        +		}
        +	EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
        +	return 0;
        +	}
        +
        +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
        +	{
        +	if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
        +	else ctx->flags |= EVP_CIPH_NO_PADDING;
        +	return 1;
        +	}
        +
        +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
        +{
        +	int ret;
        +	if(!ctx->cipher) {
        +		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
        +		return 0;
        +	}
        +
        +	if(!ctx->cipher->ctrl) {
        +		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
        +		return 0;
        +	}
        +
        +	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
        +	if(ret == -1) {
        +		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
        +		return 0;
        +	}
        +	return ret;
        +}
        +
        +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
        +	{
        +	if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
        +		return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
        +	if (RAND_bytes(key, ctx->key_len) <= 0)
        +		return 0;
        +	return 1;
        +	}
        +
        +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
        +	{
        +	if ((in == NULL) || (in->cipher == NULL))
        +		{
        +		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
        +		return 0;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Make sure it's safe to copy a cipher context using an ENGINE */
        +	if (in->engine && !ENGINE_init(in->engine))
        +		{
        +		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
        +		return 0;
        +		}
        +#endif
        +
        +	EVP_CIPHER_CTX_cleanup(out);
        +	memcpy(out,in,sizeof *out);
        +
        +	if (in->cipher_data && in->cipher->ctx_size)
        +		{
        +		out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
        +		if (!out->cipher_data)
        +			{
        +			EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
        +		}
        +
        +	if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
        +		return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_err.c b/vendor/openssl/openssl/crypto/evp/evp_err.c
        new file mode 100644
        index 000000000..08eab9882
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_err.c
        @@ -0,0 +1,240 @@
        +/* crypto/evp/evp_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
        +
        +static ERR_STRING_DATA EVP_str_functs[]=
        +	{
        +{ERR_FUNC(EVP_F_AESNI_INIT_KEY),	"AESNI_INIT_KEY"},
        +{ERR_FUNC(EVP_F_AESNI_XTS_CIPHER),	"AESNI_XTS_CIPHER"},
        +{ERR_FUNC(EVP_F_AES_INIT_KEY),	"AES_INIT_KEY"},
        +{ERR_FUNC(EVP_F_AES_XTS),	"AES_XTS"},
        +{ERR_FUNC(EVP_F_AES_XTS_CIPHER),	"AES_XTS_CIPHER"},
        +{ERR_FUNC(EVP_F_ALG_MODULE_INIT),	"ALG_MODULE_INIT"},
        +{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),	"CAMELLIA_INIT_KEY"},
        +{ERR_FUNC(EVP_F_CMAC_INIT),	"CMAC_INIT"},
        +{ERR_FUNC(EVP_F_D2I_PKEY),	"D2I_PKEY"},
        +{ERR_FUNC(EVP_F_DO_SIGVER_INIT),	"DO_SIGVER_INIT"},
        +{ERR_FUNC(EVP_F_DSAPKEY2PKCS8),	"DSAPKEY2PKCS8"},
        +{ERR_FUNC(EVP_F_DSA_PKEY2PKCS8),	"DSA_PKEY2PKCS8"},
        +{ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8),	"ECDSA_PKEY2PKCS8"},
        +{ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8),	"ECKEY_PKEY2PKCS8"},
        +{ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX),	"EVP_CipherInit_ex"},
        +{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY),	"EVP_CIPHER_CTX_copy"},
        +{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL),	"EVP_CIPHER_CTX_ctrl"},
        +{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),	"EVP_CIPHER_CTX_set_key_length"},
        +{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX),	"EVP_DecryptFinal_ex"},
        +{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX),	"EVP_DigestInit_ex"},
        +{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX),	"EVP_EncryptFinal_ex"},
        +{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX),	"EVP_MD_CTX_copy_ex"},
        +{ERR_FUNC(EVP_F_EVP_MD_SIZE),	"EVP_MD_size"},
        +{ERR_FUNC(EVP_F_EVP_OPENINIT),	"EVP_OpenInit"},
        +{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD),	"EVP_PBE_alg_add"},
        +{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE),	"EVP_PBE_alg_add_type"},
        +{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT),	"EVP_PBE_CipherInit"},
        +{ERR_FUNC(EVP_F_EVP_PKCS82PKEY),	"EVP_PKCS82PKEY"},
        +{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN),	"EVP_PKCS82PKEY_BROKEN"},
        +{ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN),	"EVP_PKEY2PKCS8_broken"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS),	"EVP_PKEY_copy_parameters"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL),	"EVP_PKEY_CTX_ctrl"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR),	"EVP_PKEY_CTX_ctrl_str"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP),	"EVP_PKEY_CTX_dup"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT),	"EVP_PKEY_decrypt"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT),	"EVP_PKEY_decrypt_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD),	"EVP_PKEY_decrypt_old"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE),	"EVP_PKEY_derive"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT),	"EVP_PKEY_derive_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER),	"EVP_PKEY_derive_set_peer"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT),	"EVP_PKEY_encrypt"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT),	"EVP_PKEY_encrypt_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD),	"EVP_PKEY_encrypt_old"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH),	"EVP_PKEY_get1_DH"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA),	"EVP_PKEY_get1_DSA"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA),	"EVP_PKEY_GET1_ECDSA"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY),	"EVP_PKEY_get1_EC_KEY"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA),	"EVP_PKEY_get1_RSA"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN),	"EVP_PKEY_keygen"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT),	"EVP_PKEY_keygen_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_NEW),	"EVP_PKEY_new"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN),	"EVP_PKEY_paramgen"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT),	"EVP_PKEY_paramgen_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_SIGN),	"EVP_PKEY_sign"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT),	"EVP_PKEY_sign_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY),	"EVP_PKEY_verify"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT),	"EVP_PKEY_verify_init"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER),	"EVP_PKEY_verify_recover"},
        +{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT),	"EVP_PKEY_verify_recover_init"},
        +{ERR_FUNC(EVP_F_EVP_RIJNDAEL),	"EVP_RIJNDAEL"},
        +{ERR_FUNC(EVP_F_EVP_SIGNFINAL),	"EVP_SignFinal"},
        +{ERR_FUNC(EVP_F_EVP_VERIFYFINAL),	"EVP_VerifyFinal"},
        +{ERR_FUNC(EVP_F_FIPS_CIPHERINIT),	"FIPS_CIPHERINIT"},
        +{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY),	"FIPS_CIPHER_CTX_COPY"},
        +{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL),	"FIPS_CIPHER_CTX_CTRL"},
        +{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH),	"FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
        +{ERR_FUNC(EVP_F_FIPS_DIGESTINIT),	"FIPS_DIGESTINIT"},
        +{ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY),	"FIPS_MD_CTX_COPY"},
        +{ERR_FUNC(EVP_F_HMAC_INIT_EX),	"HMAC_Init_ex"},
        +{ERR_FUNC(EVP_F_INT_CTX_NEW),	"INT_CTX_NEW"},
        +{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN),	"PKCS5_PBE_keyivgen"},
        +{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN),	"PKCS5_v2_PBE_keyivgen"},
        +{ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN),	"PKCS5_V2_PBKDF2_KEYIVGEN"},
        +{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN),	"PKCS8_set_broken"},
        +{ERR_FUNC(EVP_F_PKEY_SET_TYPE),	"PKEY_SET_TYPE"},
        +{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH),	"RC2_MAGIC_TO_METH"},
        +{ERR_FUNC(EVP_F_RC5_CTRL),	"RC5_CTRL"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA EVP_str_reasons[]=
        +	{
        +{ERR_REASON(EVP_R_AES_IV_SETUP_FAILED)   ,"aes iv setup failed"},
        +{ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED)  ,"aes key setup failed"},
        +{ERR_REASON(EVP_R_ASN1_LIB)              ,"asn1 lib"},
        +{ERR_REASON(EVP_R_BAD_BLOCK_LENGTH)      ,"bad block length"},
        +{ERR_REASON(EVP_R_BAD_DECRYPT)           ,"bad decrypt"},
        +{ERR_REASON(EVP_R_BAD_KEY_LENGTH)        ,"bad key length"},
        +{ERR_REASON(EVP_R_BN_DECODE_ERROR)       ,"bn decode error"},
        +{ERR_REASON(EVP_R_BN_PUBKEY_ERROR)       ,"bn pubkey error"},
        +{ERR_REASON(EVP_R_BUFFER_TOO_SMALL)      ,"buffer too small"},
        +{ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),"camellia key setup failed"},
        +{ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR),"cipher parameter error"},
        +{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) ,"command not supported"},
        +{ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED)  ,"ctrl not implemented"},
        +{ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),"ctrl operation not implemented"},
        +{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"},
        +{ERR_REASON(EVP_R_DECODE_ERROR)          ,"decode error"},
        +{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES)   ,"different key types"},
        +{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS)  ,"different parameters"},
        +{ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     ,"disabled for fips"},
        +{ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
        +{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
        +{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
        +{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
        +{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
        +{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
        +{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
        +{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
        +{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
        +{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
        +{ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
        +{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
        +{ERR_REASON(EVP_R_INVALID_DIGEST)        ,"invalid digest"},
        +{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     ,"invalid fips mode"},
        +{ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
        +{ERR_REASON(EVP_R_INVALID_OPERATION)     ,"invalid operation"},
        +{ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
        +{ERR_REASON(EVP_R_KEYGEN_FAILURE)        ,"keygen failure"},
        +{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL),"message digest is null"},
        +{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED)  ,"method not supported"},
        +{ERR_REASON(EVP_R_MISSING_PARAMETERS)    ,"missing parameters"},
        +{ERR_REASON(EVP_R_NO_CIPHER_SET)         ,"no cipher set"},
        +{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
        +{ERR_REASON(EVP_R_NO_DIGEST_SET)         ,"no digest set"},
        +{ERR_REASON(EVP_R_NO_DSA_PARAMETERS)     ,"no dsa parameters"},
        +{ERR_REASON(EVP_R_NO_KEY_SET)            ,"no key set"},
        +{ERR_REASON(EVP_R_NO_OPERATION_SET)      ,"no operation set"},
        +{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
        +{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
        +{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
        +{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED),"operaton not initialized"},
        +{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
        +{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
        +{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
        +{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
        +{ERR_REASON(EVP_R_TOO_LARGE)             ,"too large"},
        +{ERR_REASON(EVP_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
        +{ERR_REASON(EVP_R_UNKNOWN_DIGEST)        ,"unknown digest"},
        +{ERR_REASON(EVP_R_UNKNOWN_OPTION)        ,"unknown option"},
        +{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
        +{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE)  ,"unsupported key size"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_PRF)       ,"unsupported prf"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),"unsupported private key algorithm"},
        +{ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) ,"unsupported salt type"},
        +{ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH),"wrong final block length"},
        +{ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) ,"wrong public key type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_EVP_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(EVP_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,EVP_str_functs);
        +		ERR_load_strings(0,EVP_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_fips.c b/vendor/openssl/openssl/crypto/evp/evp_fips.c
        new file mode 100644
        index 000000000..cb7f4fc0f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_fips.c
        @@ -0,0 +1,113 @@
        +/* crypto/evp/evp_fips.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + */
        +
        +
        +#include <openssl/evp.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +
        +const EVP_CIPHER *EVP_aes_128_cbc(void)  { return FIPS_evp_aes_128_cbc(); }
        +const EVP_CIPHER *EVP_aes_128_ccm(void)  { return FIPS_evp_aes_128_ccm(); }
        +const EVP_CIPHER *EVP_aes_128_cfb1(void)  { return FIPS_evp_aes_128_cfb1(); }
        +const EVP_CIPHER *EVP_aes_128_cfb128(void)  { return FIPS_evp_aes_128_cfb128(); }
        +const EVP_CIPHER *EVP_aes_128_cfb8(void)  { return FIPS_evp_aes_128_cfb8(); }
        +const EVP_CIPHER *EVP_aes_128_ctr(void)  { return FIPS_evp_aes_128_ctr(); }
        +const EVP_CIPHER *EVP_aes_128_ecb(void)  { return FIPS_evp_aes_128_ecb(); }
        +const EVP_CIPHER *EVP_aes_128_gcm(void)  { return FIPS_evp_aes_128_gcm(); }
        +const EVP_CIPHER *EVP_aes_128_ofb(void)  { return FIPS_evp_aes_128_ofb(); }
        +const EVP_CIPHER *EVP_aes_128_xts(void)  { return FIPS_evp_aes_128_xts(); }
        +const EVP_CIPHER *EVP_aes_192_cbc(void)  { return FIPS_evp_aes_192_cbc(); }
        +const EVP_CIPHER *EVP_aes_192_ccm(void)  { return FIPS_evp_aes_192_ccm(); }
        +const EVP_CIPHER *EVP_aes_192_cfb1(void)  { return FIPS_evp_aes_192_cfb1(); }
        +const EVP_CIPHER *EVP_aes_192_cfb128(void)  { return FIPS_evp_aes_192_cfb128(); }
        +const EVP_CIPHER *EVP_aes_192_cfb8(void)  { return FIPS_evp_aes_192_cfb8(); }
        +const EVP_CIPHER *EVP_aes_192_ctr(void)  { return FIPS_evp_aes_192_ctr(); }
        +const EVP_CIPHER *EVP_aes_192_ecb(void)  { return FIPS_evp_aes_192_ecb(); }
        +const EVP_CIPHER *EVP_aes_192_gcm(void)  { return FIPS_evp_aes_192_gcm(); }
        +const EVP_CIPHER *EVP_aes_192_ofb(void)  { return FIPS_evp_aes_192_ofb(); }
        +const EVP_CIPHER *EVP_aes_256_cbc(void)  { return FIPS_evp_aes_256_cbc(); }
        +const EVP_CIPHER *EVP_aes_256_ccm(void)  { return FIPS_evp_aes_256_ccm(); }
        +const EVP_CIPHER *EVP_aes_256_cfb1(void)  { return FIPS_evp_aes_256_cfb1(); }
        +const EVP_CIPHER *EVP_aes_256_cfb128(void)  { return FIPS_evp_aes_256_cfb128(); }
        +const EVP_CIPHER *EVP_aes_256_cfb8(void)  { return FIPS_evp_aes_256_cfb8(); }
        +const EVP_CIPHER *EVP_aes_256_ctr(void)  { return FIPS_evp_aes_256_ctr(); }
        +const EVP_CIPHER *EVP_aes_256_ecb(void)  { return FIPS_evp_aes_256_ecb(); }
        +const EVP_CIPHER *EVP_aes_256_gcm(void)  { return FIPS_evp_aes_256_gcm(); }
        +const EVP_CIPHER *EVP_aes_256_ofb(void)  { return FIPS_evp_aes_256_ofb(); }
        +const EVP_CIPHER *EVP_aes_256_xts(void)  { return FIPS_evp_aes_256_xts(); }
        +const EVP_CIPHER *EVP_des_ede(void)  { return FIPS_evp_des_ede(); }
        +const EVP_CIPHER *EVP_des_ede3(void)  { return FIPS_evp_des_ede3(); }
        +const EVP_CIPHER *EVP_des_ede3_cbc(void)  { return FIPS_evp_des_ede3_cbc(); }
        +const EVP_CIPHER *EVP_des_ede3_cfb1(void)  { return FIPS_evp_des_ede3_cfb1(); }
        +const EVP_CIPHER *EVP_des_ede3_cfb64(void)  { return FIPS_evp_des_ede3_cfb64(); }
        +const EVP_CIPHER *EVP_des_ede3_cfb8(void)  { return FIPS_evp_des_ede3_cfb8(); }
        +const EVP_CIPHER *EVP_des_ede3_ecb(void)  { return FIPS_evp_des_ede3_ecb(); }
        +const EVP_CIPHER *EVP_des_ede3_ofb(void)  { return FIPS_evp_des_ede3_ofb(); }
        +const EVP_CIPHER *EVP_des_ede_cbc(void)  { return FIPS_evp_des_ede_cbc(); }
        +const EVP_CIPHER *EVP_des_ede_cfb64(void)  { return FIPS_evp_des_ede_cfb64(); }
        +const EVP_CIPHER *EVP_des_ede_ecb(void)  { return FIPS_evp_des_ede_ecb(); }
        +const EVP_CIPHER *EVP_des_ede_ofb(void)  { return FIPS_evp_des_ede_ofb(); }
        +const EVP_CIPHER *EVP_enc_null(void)  { return FIPS_evp_enc_null(); }
        +
        +const EVP_MD *EVP_sha1(void)  { return FIPS_evp_sha1(); }
        +const EVP_MD *EVP_sha224(void)  { return FIPS_evp_sha224(); }
        +const EVP_MD *EVP_sha256(void)  { return FIPS_evp_sha256(); }
        +const EVP_MD *EVP_sha384(void)  { return FIPS_evp_sha384(); }
        +const EVP_MD *EVP_sha512(void)  { return FIPS_evp_sha512(); }
        +
        +const EVP_MD *EVP_dss(void)  { return FIPS_evp_dss(); }
        +const EVP_MD *EVP_dss1(void)  { return FIPS_evp_dss1(); }
        +const EVP_MD *EVP_ecdsa(void)  { return FIPS_evp_ecdsa(); }
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_key.c b/vendor/openssl/openssl/crypto/evp/evp_key.c
        new file mode 100644
        index 000000000..7961fbebf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_key.c
        @@ -0,0 +1,189 @@
        +/* crypto/evp/evp_key.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/ui.h>
        +
        +/* should be init to zeros. */
        +static char prompt_string[80];
        +
        +void EVP_set_pw_prompt(const char *prompt)
        +	{
        +	if (prompt == NULL)
        +		prompt_string[0]='\0';
        +	else
        +		{
        +		strncpy(prompt_string,prompt,79);
        +		prompt_string[79]='\0';
        +		}
        +	}
        +
        +char *EVP_get_pw_prompt(void)
        +	{
        +	if (prompt_string[0] == '\0')
        +		return(NULL);
        +	else
        +		return(prompt_string);
        +	}
        +
        +/* For historical reasons, the standard function for reading passwords is
        + * in the DES library -- if someone ever wants to disable DES,
        + * this function will fail */
        +int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
        +	{
        +	return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
        +	}
        +
        +int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify)
        +	{
        +	int ret;
        +	char buff[BUFSIZ];
        +	UI *ui;
        +
        +	if ((prompt == NULL) && (prompt_string[0] != '\0'))
        +		prompt=prompt_string;
        +	ui = UI_new();
        +	UI_add_input_string(ui,prompt,0,buf,min,(len>=BUFSIZ)?BUFSIZ-1:len);
        +	if (verify)
        +		UI_add_verify_string(ui,prompt,0,
        +			buff,min,(len>=BUFSIZ)?BUFSIZ-1:len,buf);
        +	ret = UI_process(ui);
        +	UI_free(ui);
        +	OPENSSL_cleanse(buff,BUFSIZ);
        +	return ret;
        +	}
        +
        +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, 
        +	     const unsigned char *salt, const unsigned char *data, int datal,
        +	     int count, unsigned char *key, unsigned char *iv)
        +	{
        +	EVP_MD_CTX c;
        +	unsigned char md_buf[EVP_MAX_MD_SIZE];
        +	int niv,nkey,addmd=0;
        +	unsigned int mds=0,i;
        +	int rv = 0;
        +	nkey=type->key_len;
        +	niv=type->iv_len;
        +	OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
        +	OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
        +
        +	if (data == NULL) return(nkey);
        +
        +	EVP_MD_CTX_init(&c);
        +	for (;;)
        +		{
        +		if (!EVP_DigestInit_ex(&c,md, NULL))
        +			return 0;
        +		if (addmd++)
        +			if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds))
        +				goto err;
        +		if (!EVP_DigestUpdate(&c,data,datal))
        +			goto err;
        +		if (salt != NULL)
        +			if (!EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN))
        +				goto err;
        +		if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds))
        +			goto err;
        +
        +		for (i=1; i<(unsigned int)count; i++)
        +			{
        +			if (!EVP_DigestInit_ex(&c,md, NULL))
        +				goto err;
        +			if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds))
        +				goto err;
        +			if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds))
        +				goto err;
        +			}
        +		i=0;
        +		if (nkey)
        +			{
        +			for (;;)
        +				{
        +				if (nkey == 0) break;
        +				if (i == mds) break;
        +				if (key != NULL)
        +					*(key++)=md_buf[i];
        +				nkey--;
        +				i++;
        +				}
        +			}
        +		if (niv && (i != mds))
        +			{
        +			for (;;)
        +				{
        +				if (niv == 0) break;
        +				if (i == mds) break;
        +				if (iv != NULL)
        +					*(iv++)=md_buf[i];
        +				niv--;
        +				i++;
        +				}
        +			}
        +		if ((nkey == 0) && (niv == 0)) break;
        +		}
        +	rv = type->key_len;
        +	err:
        +	EVP_MD_CTX_cleanup(&c);
        +	OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE);
        +	return rv;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_lib.c b/vendor/openssl/openssl/crypto/evp/evp_lib.c
        new file mode 100644
        index 000000000..b180e4828
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_lib.c
        @@ -0,0 +1,316 @@
        +/* crypto/evp/evp_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +
        +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
        +	{
        +	int ret;
        +
        +	if (c->cipher->set_asn1_parameters != NULL)
        +		ret=c->cipher->set_asn1_parameters(c,type);
        +	else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
        +		ret=EVP_CIPHER_set_asn1_iv(c, type);
        +	else
        +		ret=-1;
        +	return(ret);
        +	}
        +
        +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
        +	{
        +	int ret;
        +
        +	if (c->cipher->get_asn1_parameters != NULL)
        +		ret=c->cipher->get_asn1_parameters(c,type);
        +	else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
        +		ret=EVP_CIPHER_get_asn1_iv(c, type);
        +	else
        +		ret=-1;
        +	return(ret);
        +	}
        +
        +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
        +	{
        +	int i=0;
        +	unsigned int l;
        +
        +	if (type != NULL) 
        +		{
        +		l=EVP_CIPHER_CTX_iv_length(c);
        +		OPENSSL_assert(l <= sizeof(c->iv));
        +		i=ASN1_TYPE_get_octetstring(type,c->oiv,l);
        +		if (i != (int)l)
        +			return(-1);
        +		else if (i > 0)
        +			memcpy(c->iv,c->oiv,l);
        +		}
        +	return(i);
        +	}
        +
        +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
        +	{
        +	int i=0;
        +	unsigned int j;
        +
        +	if (type != NULL)
        +		{
        +		j=EVP_CIPHER_CTX_iv_length(c);
        +		OPENSSL_assert(j <= sizeof(c->iv));
        +		i=ASN1_TYPE_set_octetstring(type,c->oiv,j);
        +		}
        +	return(i);
        +	}
        +
        +/* Convert the various cipher NIDs and dummies to a proper OID NID */
        +int EVP_CIPHER_type(const EVP_CIPHER *ctx)
        +{
        +	int nid;
        +	ASN1_OBJECT *otmp;
        +	nid = EVP_CIPHER_nid(ctx);
        +
        +	switch(nid) {
        +
        +		case NID_rc2_cbc:
        +		case NID_rc2_64_cbc:
        +		case NID_rc2_40_cbc:
        +
        +		return NID_rc2_cbc;
        +
        +		case NID_rc4:
        +		case NID_rc4_40:
        +
        +		return NID_rc4;
        +
        +		case NID_aes_128_cfb128:
        +		case NID_aes_128_cfb8:
        +		case NID_aes_128_cfb1:
        +
        +		return NID_aes_128_cfb128;
        +
        +		case NID_aes_192_cfb128:
        +		case NID_aes_192_cfb8:
        +		case NID_aes_192_cfb1:
        +
        +		return NID_aes_192_cfb128;
        +
        +		case NID_aes_256_cfb128:
        +		case NID_aes_256_cfb8:
        +		case NID_aes_256_cfb1:
        +
        +		return NID_aes_256_cfb128;
        +
        +		case NID_des_cfb64:
        +		case NID_des_cfb8:
        +		case NID_des_cfb1:
        +
        +		return NID_des_cfb64;
        +
        +		case NID_des_ede3_cfb64:
        +		case NID_des_ede3_cfb8:
        +		case NID_des_ede3_cfb1:
        +
        +		return NID_des_cfb64;
        +
        +		default:
        +		/* Check it has an OID and it is valid */
        +		otmp = OBJ_nid2obj(nid);
        +		if(!otmp || !otmp->data) nid = NID_undef;
        +		ASN1_OBJECT_free(otmp);
        +		return nid;
        +	}
        +}
        +
        +int EVP_CIPHER_block_size(const EVP_CIPHER *e)
        +	{
        +	return e->block_size;
        +	}
        +
        +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->cipher->block_size;
        +	}
        +
        +int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
        +	{
        +	return ctx->cipher->do_cipher(ctx,out,in,inl);
        +	}
        +
        +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->cipher;
        +	}
        +
        +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
        +	{
        +	return cipher->flags;
        +	}
        +
        +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->cipher->flags;
        +	}
        +
        +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->app_data;
        +	}
        +
        +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
        +	{
        +	ctx->app_data = data;
        +	}
        +
        +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
        +	{
        +	return cipher->iv_len;
        +	}
        +
        +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->cipher->iv_len;
        +	}
        +
        +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
        +	{
        +	return cipher->key_len;
        +	}
        +
        +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->key_len;
        +	}
        +
        +int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
        +	{
        +	return cipher->nid;
        +	}
        +
        +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
        +	{
        +	return ctx->cipher->nid;
        +	}
        +
        +int EVP_MD_block_size(const EVP_MD *md) 
        +	{
        +	return md->block_size;
        +	}
        +
        +int EVP_MD_type(const EVP_MD *md)
        +	{
        +	return md->type;
        +	}
        +
        +int EVP_MD_pkey_type(const EVP_MD *md)
        +	{
        +	return md->pkey_type;
        +	}
        +
        +int EVP_MD_size(const EVP_MD *md)
        +	{
        +	if (!md)
        +		{
        +		EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
        +		return -1;
        +		}
        +	return md->md_size;
        +	}
        +
        +unsigned long EVP_MD_flags(const EVP_MD *md)
        +	{
        +	return md->flags;
        +	}
        +
        +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
        +	{
        +	if (!ctx)
        +		return NULL;
        +	return ctx->digest;
        +	}
        +
        +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
        +	{
        +	ctx->flags |= flags;
        +	}
        +
        +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
        +	{
        +	ctx->flags &= ~flags;
        +	}
        +
        +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
        +	{
        +	return (ctx->flags & flags);
        +	}
        +
        +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
        +	{
        +	ctx->flags |= flags;
        +	}
        +
        +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
        +	{
        +	ctx->flags &= ~flags;
        +	}
        +
        +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
        +	{
        +	return (ctx->flags & flags);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_locl.h b/vendor/openssl/openssl/crypto/evp/evp_locl.h
        new file mode 100644
        index 000000000..08c0a66d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_locl.h
        @@ -0,0 +1,385 @@
        +/* evp_locl.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) 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() \
        +	size_t i, bl; \
        +	bl = ctx->cipher->block_size;\
        +	if(inl < bl) return 1;\
        +	inl -= bl; \
        +	for(i=0; i <= inl; i+=bl) 
        +
        +#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
        +static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
        +{\
        +	BLOCK_CIPHER_ecb_loop() \
        +		cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
        +	return 1;\
        +}
        +
        +#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
        +
        +#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
        +static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
        +{\
        +	while(inl>=EVP_MAXCHUNK)\
        +	    {\
        +	    cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
        +	    inl-=EVP_MAXCHUNK;\
        +	    in +=EVP_MAXCHUNK;\
        +	    out+=EVP_MAXCHUNK;\
        +	    }\
        +	if (inl)\
        +	    cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
        +	return 1;\
        +}
        +
        +#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
        +static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
        +{\
        +	while(inl>=EVP_MAXCHUNK) \
        +	    {\
        +	    cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
        +	    inl-=EVP_MAXCHUNK;\
        +	    in +=EVP_MAXCHUNK;\
        +	    out+=EVP_MAXCHUNK;\
        +	    }\
        +	if (inl)\
        +	    cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
        +	return 1;\
        +}
        +
        +#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
        +static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
        +{\
        +	size_t chunk=EVP_MAXCHUNK;\
        +	if (cbits==1)  chunk>>=3;\
        +	if (inl<chunk) chunk=inl;\
        +	while(inl && inl>=chunk)\
        +	    {\
        +            cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
        +	    inl-=chunk;\
        +	    in +=chunk;\
        +	    out+=chunk;\
        +	    if(inl<chunk) chunk=inl;\
        +	    }\
        +	return 1;\
        +}
        +
        +#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
        +	BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
        +	BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
        +	BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
        +	BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
        +
        +#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
        +			  key_len, iv_len, flags, init_key, cleanup, \
        +			  set_asn1, get_asn1, ctrl) \
        +static const EVP_CIPHER cname##_##mode = { \
        +	nid##_##nmode, block_size, key_len, iv_len, \
        +	flags | EVP_CIPH_##MODE##_MODE, \
        +	init_key, \
        +	cname##_##mode##_cipher, \
        +	cleanup, \
        +	sizeof(kstruct), \
        +	set_asn1, get_asn1,\
        +	ctrl, \
        +	NULL \
        +}; \
        +const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
        +
        +#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
        +			     iv_len, flags, init_key, cleanup, set_asn1, \
        +			     get_asn1, ctrl) \
        +BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
        +		  iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
        +
        +#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
        +			     iv_len, cbits, flags, init_key, cleanup, \
        +			     set_asn1, get_asn1, ctrl) \
        +BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
        +		  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
        +		  get_asn1, ctrl)
        +
        +#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
        +			     iv_len, cbits, flags, init_key, cleanup, \
        +			     set_asn1, get_asn1, ctrl) \
        +BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
        +		  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
        +		  get_asn1, ctrl)
        +
        +#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
        +			     flags, init_key, cleanup, set_asn1, \
        +			     get_asn1, ctrl) \
        +BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
        +		  0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
        +
        +#define BLOCK_CIPHER_defs(cname, kstruct, \
        +			  nid, block_size, key_len, iv_len, cbits, flags, \
        +			  init_key, cleanup, set_asn1, get_asn1, ctrl) \
        +BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
        +		     init_key, cleanup, set_asn1, get_asn1, ctrl) \
        +BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
        +		     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
        +BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
        +		     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
        +BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
        +		     init_key, cleanup, set_asn1, get_asn1, ctrl)
        +
        +
        +/*
        +#define BLOCK_CIPHER_defs(cname, kstruct, \
        +				nid, block_size, key_len, iv_len, flags,\
        +				 init_key, cleanup, set_asn1, get_asn1, ctrl)\
        +static const EVP_CIPHER cname##_cbc = {\
        +	nid##_cbc, block_size, key_len, iv_len, \
        +	flags | EVP_CIPH_CBC_MODE,\
        +	init_key,\
        +	cname##_cbc_cipher,\
        +	cleanup,\
        +	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
        +		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
        +	set_asn1, get_asn1,\
        +	ctrl, \
        +	NULL \
        +};\
        +const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
        +static const EVP_CIPHER cname##_cfb = {\
        +	nid##_cfb64, 1, key_len, iv_len, \
        +	flags | EVP_CIPH_CFB_MODE,\
        +	init_key,\
        +	cname##_cfb_cipher,\
        +	cleanup,\
        +	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
        +		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
        +	set_asn1, get_asn1,\
        +	ctrl,\
        +	NULL \
        +};\
        +const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
        +static const EVP_CIPHER cname##_ofb = {\
        +	nid##_ofb64, 1, key_len, iv_len, \
        +	flags | EVP_CIPH_OFB_MODE,\
        +	init_key,\
        +	cname##_ofb_cipher,\
        +	cleanup,\
        +	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
        +		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
        +	set_asn1, get_asn1,\
        +	ctrl,\
        +	NULL \
        +};\
        +const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
        +static const EVP_CIPHER cname##_ecb = {\
        +	nid##_ecb, block_size, key_len, iv_len, \
        +	flags | EVP_CIPH_ECB_MODE,\
        +	init_key,\
        +	cname##_ecb_cipher,\
        +	cleanup,\
        +	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
        +		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
        +	set_asn1, get_asn1,\
        +	ctrl,\
        +	NULL \
        +};\
        +const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
        +*/
        +
        +#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
        +			       block_size, key_len, iv_len, cbits, \
        +			       flags, init_key, \
        +			       cleanup, set_asn1, get_asn1, ctrl) \
        +	BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
        +	BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
        +			  cbits, flags, init_key, cleanup, set_asn1, \
        +			  get_asn1, ctrl)
        +
        +#define EVP_C_DATA(kstruct, ctx)	((kstruct *)(ctx)->cipher_data)
        +
        +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
        +	BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
        +	BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
        +			     NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
        +			     0, cipher##_init_key, NULL, \
        +			     EVP_CIPHER_set_asn1_iv, \
        +			     EVP_CIPHER_get_asn1_iv, \
        +			     NULL)
        +
        +struct evp_pkey_ctx_st
        +	{
        +	/* Method associated with this operation */
        +	const EVP_PKEY_METHOD *pmeth;
        +	/* Engine that implements this method or NULL if builtin */
        +	ENGINE *engine;
        +	/* Key: may be NULL */
        +	EVP_PKEY *pkey;
        +	/* Peer key for key agreement, may be NULL */
        +	EVP_PKEY *peerkey;
        +	/* Actual operation */
        +	int operation;
        +	/* Algorithm specific data */
        +	void *data;
        +	/* Application specific data */
        +	void *app_data;
        +	/* Keygen callback */
        +	EVP_PKEY_gen_cb *pkey_gencb;
        +	/* implementation specific keygen data */
        +	int *keygen_info;
        +	int keygen_info_count;
        +	} /* EVP_PKEY_CTX */;
        +
        +#define EVP_PKEY_FLAG_DYNAMIC	1
        +
        +struct evp_pkey_method_st
        +	{
        +	int pkey_id;
        +	int flags;
        +
        +	int (*init)(EVP_PKEY_CTX *ctx);
        +	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
        +	void (*cleanup)(EVP_PKEY_CTX *ctx);
        +
        +	int (*paramgen_init)(EVP_PKEY_CTX *ctx);
        +	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
        +
        +	int (*keygen_init)(EVP_PKEY_CTX *ctx);
        +	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
        +
        +	int (*sign_init)(EVP_PKEY_CTX *ctx);
        +	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +				const unsigned char *tbs, size_t tbslen);
        +
        +	int (*verify_init)(EVP_PKEY_CTX *ctx);
        +	int (*verify)(EVP_PKEY_CTX *ctx,
        +				const unsigned char *sig, size_t siglen,
        +				const unsigned char *tbs, size_t tbslen);
        +
        +	int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
        +	int (*verify_recover)(EVP_PKEY_CTX *ctx,
        +				unsigned char *rout, size_t *routlen,
        +				const unsigned char *sig, size_t siglen);
        +
        +	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
        +	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					EVP_MD_CTX *mctx);
        +
        +	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
        +	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
        +					EVP_MD_CTX *mctx);
        +
        +	int (*encrypt_init)(EVP_PKEY_CTX *ctx);
        +	int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen);
        +
        +	int (*decrypt_init)(EVP_PKEY_CTX *ctx);
        +	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen);
        +
        +	int (*derive_init)(EVP_PKEY_CTX *ctx);
        +	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
        +
        +	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
        +	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
        +
        +
        +	} /* EVP_PKEY_METHOD */;
        +
        +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
        +
        +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +			     ASN1_TYPE *param,
        +			     const EVP_CIPHER *c, const EVP_MD *md, int en_de);
        +
        +#ifdef OPENSSL_FIPS
        +
        +#ifdef OPENSSL_DOING_MAKEDEPEND
        +#undef SHA1_Init
        +#undef SHA1_Update
        +#undef SHA224_Init
        +#undef SHA256_Init
        +#undef SHA384_Init
        +#undef SHA512_Init
        +#undef DES_set_key_unchecked
        +#endif
        +
        +#define RIPEMD160_Init	private_RIPEMD160_Init
        +#define WHIRLPOOL_Init	private_WHIRLPOOL_Init
        +#define MD5_Init	private_MD5_Init
        +#define MD4_Init	private_MD4_Init
        +#define MD2_Init	private_MD2_Init
        +#define MDC2_Init	private_MDC2_Init
        +#define SHA_Init	private_SHA_Init
        +#define SHA1_Init	private_SHA1_Init
        +#define SHA224_Init	private_SHA224_Init
        +#define SHA256_Init	private_SHA256_Init
        +#define SHA384_Init	private_SHA384_Init
        +#define SHA512_Init	private_SHA512_Init
        +
        +#define BF_set_key	private_BF_set_key
        +#define CAST_set_key	private_CAST_set_key
        +#define idea_set_encrypt_key	private_idea_set_encrypt_key
        +#define SEED_set_key	private_SEED_set_key
        +#define RC2_set_key	private_RC2_set_key
        +#define RC4_set_key	private_RC4_set_key
        +#define DES_set_key_unchecked	private_DES_set_key_unchecked
        +#define Camellia_set_key	private_Camellia_set_key
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_pbe.c b/vendor/openssl/openssl/crypto/evp/evp_pbe.c
        new file mode 100644
        index 000000000..f8c32d825
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_pbe.c
        @@ -0,0 +1,316 @@
        +/* evp_pbe.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/x509.h>
        +#include "evp_locl.h"
        +
        +/* Password based encryption (PBE) functions */
        +
        +DECLARE_STACK_OF(EVP_PBE_CTL)
        +static STACK_OF(EVP_PBE_CTL) *pbe_algs;
        +
        +/* Setup a cipher context from a PBE algorithm */
        +
        +typedef struct
        +	{
        +	int pbe_type;
        +	int pbe_nid;
        +	int cipher_nid;
        +	int md_nid;
        +	EVP_PBE_KEYGEN *keygen;
        +	} EVP_PBE_CTL;
        +
        +static const EVP_PBE_CTL builtin_pbe[] = 
        +	{
        +	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
        +			NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
        +			NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
        +			NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
        +
        +#ifndef OPENSSL_NO_HMAC
        +	{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
        +#endif
        +
        +	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
        +			NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
        +			NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
        +		 	NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 
        +			NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
        +			NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
        +			NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
        +
        +#ifndef OPENSSL_NO_HMAC
        +	{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
        +#endif
        +	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
        +			NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
        +			NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
        +	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
        +			NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
        +
        +
        +	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
        +	{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
        +	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
        +	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
        +	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
        +	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
        +	{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
        +	};
        +
        +#ifdef TEST
        +int main(int argc, char **argv)
        +	{
        +	int i, nid_md, nid_cipher;
        +	EVP_PBE_CTL *tpbe, *tpbe2;
        +	/*OpenSSL_add_all_algorithms();*/
        +
        +	for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
        +		{
        +		tpbe = builtin_pbe + i;
        +		fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
        +						OBJ_nid2sn(tpbe->pbe_nid));
        +		if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
        +					&nid_cipher ,&nid_md,0))
        +			fprintf(stderr, "Found %s %s\n",
        +					OBJ_nid2sn(nid_cipher),
        +					OBJ_nid2sn(nid_md));
        +		else
        +			fprintf(stderr, "Find ERROR!!\n");
        +		}
        +
        +	return 0;
        +	}
        +#endif
        +		
        +
        +
        +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
        +		       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
        +	{
        +	const EVP_CIPHER *cipher;
        +	const EVP_MD *md;
        +	int cipher_nid, md_nid;
        +	EVP_PBE_KEYGEN *keygen;
        +
        +	if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
        +					&cipher_nid, &md_nid, &keygen))
        +		{
        +		char obj_tmp[80];
        +		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
        +		if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
        +		else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
        +		ERR_add_error_data(2, "TYPE=", obj_tmp);
        +		return 0;
        +		}
        +
        +	if(!pass)
        +		passlen = 0;
        +	else if (passlen == -1)
        +		passlen = strlen(pass);
        +
        +	if (cipher_nid == -1)
        +		cipher = NULL;
        +	else
        +		{
        +		cipher = EVP_get_cipherbynid(cipher_nid);
        +		if (!cipher)
        +			{
        +			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
        +			return 0;
        +			}
        +		}
        +
        +	if (md_nid == -1)
        +		md = NULL;
        +	else
        +		{
        +		md = EVP_get_digestbynid(md_nid);
        +		if (!md)
        +			{
        +			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
        +			return 0;
        +			}
        +		}
        +
        +	if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
        +		{
        +		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
        +		return 0;
        +		}
        +	return 1;	
        +}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
        +
        +static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
        +	{
        +	int ret = pbe1->pbe_type - pbe2->pbe_type;
        +	if (ret)
        +		return ret;
        +	else
        +		return pbe1->pbe_nid - pbe2->pbe_nid;
        +	}
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
        +
        +static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
        +	{
        +	int ret = (*a)->pbe_type - (*b)->pbe_type;
        +	if (ret)
        +		return ret;
        +	else
        +		return (*a)->pbe_nid - (*b)->pbe_nid;
        +	}
        +
        +/* Add a PBE algorithm */
        +
        +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
        +			 EVP_PBE_KEYGEN *keygen)
        +	{
        +	EVP_PBE_CTL *pbe_tmp;
        +	if (!pbe_algs)
        +		pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
        +	if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
        +		{
        +		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	pbe_tmp->pbe_type = pbe_type;
        +	pbe_tmp->pbe_nid = pbe_nid;
        +	pbe_tmp->cipher_nid = cipher_nid;
        +	pbe_tmp->md_nid = md_nid;
        +	pbe_tmp->keygen = keygen;
        +
        +
        +	sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
        +	return 1;
        +	}
        +
        +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
        +		    EVP_PBE_KEYGEN *keygen)
        +	{
        +	int cipher_nid, md_nid;
        +	if (cipher)
        +		cipher_nid = EVP_CIPHER_type(cipher);
        +	else
        +		cipher_nid = -1;
        +	if (md)
        +		md_nid = EVP_MD_type(md);
        +	else
        +		md_nid = -1;
        +
        +	return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
        +					cipher_nid, md_nid, keygen);
        +	}
        +
        +int EVP_PBE_find(int type, int pbe_nid,
        +		 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
        +	{
        +	EVP_PBE_CTL *pbetmp = NULL, pbelu;
        +	int i;
        +	if (pbe_nid == NID_undef)
        +		return 0;
        +
        +	pbelu.pbe_type = type;
        +	pbelu.pbe_nid = pbe_nid;
        +
        +	if (pbe_algs)
        +		{
        +		i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
        +		if (i != -1)
        +			pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
        +		}
        +	if (pbetmp == NULL)
        +		{
        +		pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
        +				     sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
        +		}
        +	if (pbetmp == NULL)
        +		return 0;
        +	if (pcnid)
        +		*pcnid = pbetmp->cipher_nid;
        +	if (pmnid)
        +		*pmnid = pbetmp->md_nid;
        +	if (pkeygen)
        +		*pkeygen = pbetmp->keygen;
        +	return 1;
        +	}
        +
        +static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
        +	 {
        +	 OPENSSL_freeFunc(pbe);
        +	 }
        +
        +void EVP_PBE_cleanup(void)
        +	{
        +	sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
        +	pbe_algs = NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_pkey.c b/vendor/openssl/openssl/crypto/evp/evp_pkey.c
        new file mode 100644
        index 000000000..ceebf6928
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_pkey.c
        @@ -0,0 +1,242 @@
        +/* evp_pkey.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/rand.h>
        +#include "asn1_locl.h"
        +
        +/* Extract a private key from a PKCS8 structure */
        +
        +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
        +{
        +	EVP_PKEY *pkey = NULL;
        +	ASN1_OBJECT *algoid;
        +	char obj_tmp[80];
        +
        +	if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
        +		return NULL;
        +
        +	if (!(pkey = EVP_PKEY_new())) {
        +		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
        +		{
        +		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
        +		i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
        +		ERR_add_error_data(2, "TYPE=", obj_tmp);
        +		goto error;
        +		}
        +
        +	if (pkey->ameth->priv_decode)
        +		{
        +		if (!pkey->ameth->priv_decode(pkey, p8))
        +			{
        +			EVPerr(EVP_F_EVP_PKCS82PKEY,
        +					EVP_R_PRIVATE_KEY_DECODE_ERROR);
        +			goto error;
        +			}
        +		}
        +	else
        +		{
        +		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
        +		goto error;
        +		}
        +
        +	return pkey;
        +
        +	error:
        +	EVP_PKEY_free (pkey);
        +	return NULL;
        +}
        +
        +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
        +{
        +	return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
        +}
        +
        +/* Turn a private key into a PKCS8 structure */
        +
        +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
        +{
        +	PKCS8_PRIV_KEY_INFO *p8;
        +
        +	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {	
        +		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	p8->broken = broken;
        +
        +	if (pkey->ameth)
        +		{
        +		if (pkey->ameth->priv_encode)
        +			{
        +			if (!pkey->ameth->priv_encode(p8, pkey))
        +				{
        +				EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
        +					EVP_R_PRIVATE_KEY_ENCODE_ERROR);
        +				goto error;
        +				}
        +			}
        +		else
        +			{
        +			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
        +					EVP_R_METHOD_NOT_SUPPORTED);
        +			goto error;
        +			}
        +		}
        +	else
        +		{
        +		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
        +				EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
        +		goto error;
        +		}
        +	RAND_add(p8->pkey->value.octet_string->data,
        +		 p8->pkey->value.octet_string->length, 0.0);
        +	return p8;
        +	error:
        +	PKCS8_PRIV_KEY_INFO_free(p8);
        +	return NULL;
        +}
        +
        +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
        +{
        +	switch (broken) {
        +
        +		case PKCS8_OK:
        +		p8->broken = PKCS8_OK;
        +		return p8;
        +		break;
        +
        +		case PKCS8_NO_OCTET:
        +		p8->broken = PKCS8_NO_OCTET;
        +		p8->pkey->type = V_ASN1_SEQUENCE;
        +		return p8;
        +		break;
        +
        +		default:
        +		EVPerr(EVP_F_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
        +		return NULL;
        +	}
        +}
        +
        +/* EVP_PKEY attribute functions */
        +
        +int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
        +{
        +	return X509at_get_attr_count(key->attributes);
        +}
        +
        +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
        +}
        +
        +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
        +}
        +
        +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
        +{
        +	return X509at_get_attr(key->attributes, loc);
        +}
        +
        +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
        +{
        +	return X509at_delete_attr(key->attributes, loc);
        +}
        +
        +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
        +{
        +	if(X509at_add1_attr(&key->attributes, attr)) return 1;
        +	return 0;
        +}
        +
        +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
        +			const ASN1_OBJECT *obj, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_OBJ(&key->attributes, obj,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
        +			int nid, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_NID(&key->attributes, nid,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
        +			const char *attrname, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_txt(&key->attributes, attrname,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/evp/evp_test.c b/vendor/openssl/openssl/crypto/evp/evp_test.c
        new file mode 100644
        index 000000000..55c7cdfdc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evp_test.c
        @@ -0,0 +1,450 @@
        +/* Written by Ben Laurie, 2001 */
        +/*
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/conf.h>
        +
        +static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
        +    {
        +    int n=0;
        +
        +    fprintf(f,"%s",title);
        +    for( ; n < l ; ++n)
        +	{
        +	if((n%16) == 0)
        +	    fprintf(f,"\n%04x",n);
        +	fprintf(f," %02x",s[n]);
        +	}
        +    fprintf(f,"\n");
        +    }
        +
        +static int convert(unsigned char *s)
        +    {
        +    unsigned char *d;
        +
        +    for(d=s ; *s ; s+=2,++d)
        +	{
        +	unsigned int n;
        +
        +	if(!s[1])
        +	    {
        +	    fprintf(stderr,"Odd number of hex digits!");
        +	    EXIT(4);
        +	    }
        +	sscanf((char *)s,"%2x",&n);
        +	*d=(unsigned char)n;
        +	}
        +    return s-d;
        +    }
        +
        +static char *sstrsep(char **string, const char *delim)
        +    {
        +    char isdelim[256];
        +    char *token = *string;
        +
        +    if (**string == 0)
        +        return NULL;
        +
        +    memset(isdelim, 0, 256);
        +    isdelim[0] = 1;
        +
        +    while (*delim)
        +        {
        +        isdelim[(unsigned char)(*delim)] = 1;
        +        delim++;
        +        }
        +
        +    while (!isdelim[(unsigned char)(**string)])
        +        {
        +        (*string)++;
        +        }
        +
        +    if (**string)
        +        {
        +        **string = 0;
        +        (*string)++;
        +        }
        +
        +    return token;
        +    }
        +
        +static unsigned char *ustrsep(char **p,const char *sep)
        +    { return (unsigned char *)sstrsep(p,sep); }
        +
        +static int test1_exit(int ec)
        +	{
        +	EXIT(ec);
        +	return(0);		/* To keep some compilers quiet */
        +	}
        +
        +static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
        +		  const unsigned char *iv,int in,
        +		  const unsigned char *plaintext,int pn,
        +		  const unsigned char *ciphertext,int cn,
        +		  int encdec)
        +    {
        +    EVP_CIPHER_CTX ctx;
        +    unsigned char out[4096];
        +    int outl,outl2;
        +
        +    printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
        +	   (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
        +    hexdump(stdout,"Key",key,kn);
        +    if(in)
        +	hexdump(stdout,"IV",iv,in);
        +    hexdump(stdout,"Plaintext",plaintext,pn);
        +    hexdump(stdout,"Ciphertext",ciphertext,cn);
        +    
        +    if(kn != c->key_len)
        +	{
        +	fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn,
        +		(unsigned long)c->key_len);
        +	test1_exit(5);
        +	}
        +    EVP_CIPHER_CTX_init(&ctx);
        +    if (encdec != 0)
        +        {
        +	if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
        +	    {
        +	    fprintf(stderr,"EncryptInit failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(10);
        +	    }
        +	EVP_CIPHER_CTX_set_padding(&ctx,0);
        +
        +	if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
        +	    {
        +	    fprintf(stderr,"Encrypt failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(6);
        +	    }
        +	if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
        +	    {
        +	    fprintf(stderr,"EncryptFinal failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(7);
        +	    }
        +
        +	if(outl+outl2 != cn)
        +	    {
        +	    fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
        +		    outl+outl2,cn);
        +	    test1_exit(8);
        +	    }
        +
        +	if(memcmp(out,ciphertext,cn))
        +	    {
        +	    fprintf(stderr,"Ciphertext mismatch\n");
        +	    hexdump(stderr,"Got",out,cn);
        +	    hexdump(stderr,"Expected",ciphertext,cn);
        +	    test1_exit(9);
        +	    }
        +	}
        +
        +    if (encdec <= 0)
        +        {
        +	if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
        +	    {
        +	    fprintf(stderr,"DecryptInit failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(11);
        +	    }
        +	EVP_CIPHER_CTX_set_padding(&ctx,0);
        +
        +	if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
        +	    {
        +	    fprintf(stderr,"Decrypt failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(6);
        +	    }
        +	if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
        +	    {
        +	    fprintf(stderr,"DecryptFinal failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(7);
        +	    }
        +
        +	if(outl+outl2 != pn)
        +	    {
        +	    fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
        +		    outl+outl2,pn);
        +	    test1_exit(8);
        +	    }
        +
        +	if(memcmp(out,plaintext,pn))
        +	    {
        +	    fprintf(stderr,"Plaintext mismatch\n");
        +	    hexdump(stderr,"Got",out,pn);
        +	    hexdump(stderr,"Expected",plaintext,pn);
        +	    test1_exit(9);
        +	    }
        +	}
        +
        +    EVP_CIPHER_CTX_cleanup(&ctx);
        +
        +    printf("\n");
        +    }
        +
        +static int test_cipher(const char *cipher,const unsigned char *key,int kn,
        +		       const unsigned char *iv,int in,
        +		       const unsigned char *plaintext,int pn,
        +		       const unsigned char *ciphertext,int cn,
        +		       int encdec)
        +    {
        +    const EVP_CIPHER *c;
        +
        +    c=EVP_get_cipherbyname(cipher);
        +    if(!c)
        +	return 0;
        +
        +    test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec);
        +
        +    return 1;
        +    }
        +
        +static int test_digest(const char *digest,
        +		       const unsigned char *plaintext,int pn,
        +		       const unsigned char *ciphertext, unsigned int cn)
        +    {
        +    const EVP_MD *d;
        +    EVP_MD_CTX ctx;
        +    unsigned char md[EVP_MAX_MD_SIZE];
        +    unsigned int mdn;
        +
        +    d=EVP_get_digestbyname(digest);
        +    if(!d)
        +	return 0;
        +
        +    printf("Testing digest %s\n",EVP_MD_name(d));
        +    hexdump(stdout,"Plaintext",plaintext,pn);
        +    hexdump(stdout,"Digest",ciphertext,cn);
        +
        +    EVP_MD_CTX_init(&ctx);
        +    if(!EVP_DigestInit_ex(&ctx,d, NULL))
        +	{
        +	fprintf(stderr,"DigestInit failed\n");
        +	ERR_print_errors_fp(stderr);
        +	EXIT(100);
        +	}
        +    if(!EVP_DigestUpdate(&ctx,plaintext,pn))
        +	{
        +	fprintf(stderr,"DigestUpdate failed\n");
        +	ERR_print_errors_fp(stderr);
        +	EXIT(101);
        +	}
        +    if(!EVP_DigestFinal_ex(&ctx,md,&mdn))
        +	{
        +	fprintf(stderr,"DigestFinal failed\n");
        +	ERR_print_errors_fp(stderr);
        +	EXIT(101);
        +	}
        +    EVP_MD_CTX_cleanup(&ctx);
        +
        +    if(mdn != cn)
        +	{
        +	fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn);
        +	EXIT(102);
        +	}
        +
        +    if(memcmp(md,ciphertext,cn))
        +	{
        +	fprintf(stderr,"Digest mismatch\n");
        +	hexdump(stderr,"Got",md,cn);
        +	hexdump(stderr,"Expected",ciphertext,cn);
        +	EXIT(103);
        +	}
        +
        +    printf("\n");
        +
        +    EVP_MD_CTX_cleanup(&ctx);
        +
        +    return 1;
        +    }
        +
        +int main(int argc,char **argv)
        +    {
        +    const char *szTestFile;
        +    FILE *f;
        +
        +    if(argc != 2)
        +	{
        +	fprintf(stderr,"%s <test file>\n",argv[0]);
        +	EXIT(1);
        +	}
        +    CRYPTO_malloc_debug_init();
        +    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +    szTestFile=argv[1];
        +
        +    f=fopen(szTestFile,"r");
        +    if(!f)
        +	{
        +	perror(szTestFile);
        +	EXIT(2);
        +	}
        +
        +    /* Load up the software EVP_CIPHER and EVP_MD definitions */
        +    OpenSSL_add_all_ciphers();
        +    OpenSSL_add_all_digests();
        +#ifndef OPENSSL_NO_ENGINE
        +    /* Load all compiled-in ENGINEs */
        +    ENGINE_load_builtin_engines();
        +#endif
        +#if 0
        +    OPENSSL_config();
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +    /* Register all available ENGINE implementations of ciphers and digests.
        +     * This could perhaps be changed to "ENGINE_register_all_complete()"? */
        +    ENGINE_register_all_ciphers();
        +    ENGINE_register_all_digests();
        +    /* If we add command-line options, this statement should be switchable.
        +     * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
        +     * they weren't already initialised. */
        +    /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
        +#endif
        +
        +    for( ; ; )
        +	{
        +	char line[4096];
        +	char *p;
        +	char *cipher;
        +	unsigned char *iv,*key,*plaintext,*ciphertext;
        +	int encdec;
        +	int kn,in,pn,cn;
        +
        +	if(!fgets((char *)line,sizeof line,f))
        +	    break;
        +	if(line[0] == '#' || line[0] == '\n')
        +	    continue;
        +	p=line;
        +	cipher=sstrsep(&p,":");	
        +	key=ustrsep(&p,":");
        +	iv=ustrsep(&p,":");
        +	plaintext=ustrsep(&p,":");
        +	ciphertext=ustrsep(&p,":");
        +	if (p[-1] == '\n') {
        +	    p[-1] = '\0';
        +	    encdec = -1;
        +	} else {
        +	    encdec = atoi(sstrsep(&p,"\n"));
        +	}
        +	      
        +
        +	kn=convert(key);
        +	in=convert(iv);
        +	pn=convert(plaintext);
        +	cn=convert(ciphertext);
        +
        +	if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
        +	   && !test_digest(cipher,plaintext,pn,ciphertext,cn))
        +	    {
        +#ifdef OPENSSL_NO_AES
        +	    if (strstr(cipher, "AES") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_DES
        +	    if (strstr(cipher, "DES") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_RC4
        +	    if (strstr(cipher, "RC4") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_CAMELLIA
        +	    if (strstr(cipher, "CAMELLIA") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_SEED
        +	    if (strstr(cipher, "SEED") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +	    fprintf(stderr,"Can't find %s\n",cipher);
        +	    EXIT(3);
        +	    }
        +	}
        +	fclose(f);
        +
        +#ifndef OPENSSL_NO_ENGINE
        +    ENGINE_cleanup();
        +#endif
        +    EVP_cleanup();
        +    CRYPTO_cleanup_all_ex_data();
        +    ERR_remove_thread_state(NULL);
        +    ERR_free_strings();
        +    CRYPTO_mem_leaks_fp(stderr);
        +
        +    return 0;
        +    }
        diff --git a/vendor/openssl/openssl/crypto/evp/evptests.txt b/vendor/openssl/openssl/crypto/evp/evptests.txt
        new file mode 100644
        index 000000000..c273707c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/evptests.txt
        @@ -0,0 +1,334 @@
        +#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt)
        +#digest:::input:output
        +
        +# SHA(1) tests (from shatest.c)
        +SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d
        +
        +# MD5 tests (from md5test.c)
        +MD5::::d41d8cd98f00b204e9800998ecf8427e
        +MD5:::61:0cc175b9c0f1b6a831c399e269772661
        +MD5:::616263:900150983cd24fb0d6963f7d28e17f72
        +MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0
        +MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b
        +MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f
        +MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a
        +
        +# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
        +
        +AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
        +
        +# AES 192 ECB tests (from FIPS-197 test vectors, encrypt)
        +
        +AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
        +
        +# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
        +
        +AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
        +
        +# AES 128 ECB tests (from NIST test vectors, encrypt)
        +
        +#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1
        +
        +# AES 128 ECB tests (from NIST test vectors, decrypt)
        +
        +#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0
        +
        +# AES 192 ECB tests (from NIST test vectors, decrypt)
        +
        +#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0
        +
        +# AES 256 ECB tests (from NIST test vectors, decrypt)
        +
        +#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0
        +
        +# AES 128 CBC tests (from NIST test vectors, encrypt)
        +
        +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1
        +
        +# AES 192 CBC tests (from NIST test vectors, encrypt)
        +
        +#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1
        +
        +# AES 256 CBC tests (from NIST test vectors, encrypt)
        +
        +#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1
        +
        +# AES 128 CBC tests (from NIST test vectors, decrypt)
        +
        +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0
        +
        +# AES tests from NIST document SP800-38A
        +# For all ECB encrypts and decrypts, the transformed sequence is
        +#   AES-bits-ECB:key::plaintext:ciphertext:encdec
        +# ECB-AES128.Encrypt and ECB-AES128.Decrypt
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
        +# ECB-AES192.Encrypt and ECB-AES192.Decrypt 
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
        +# ECB-AES256.Encrypt and ECB-AES256.Decrypt 
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
        +# For all CBC encrypts and decrypts, the transformed sequence is
        +#   AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CBC-AES128.Encrypt and CBC-AES128.Decrypt 
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
        +# CBC-AES192.Encrypt and CBC-AES192.Decrypt 
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
        +# CBC-AES256.Encrypt and CBC-AES256.Decrypt 
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
        +# We don't support CFB{1,8}-AESxxx.{En,De}crypt
        +# For all CFB128 encrypts and decrypts, the transformed sequence is
        +#   AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CFB128-AES128.Encrypt 
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
        +# CFB128-AES128.Decrypt 
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0
        +# CFB128-AES192.Encrypt
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1
        +# CFB128-AES192.Decrypt
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
        +# CFB128-AES256.Encrypt 
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
        +# CFB128-AES256.Decrypt 
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
        +# For all OFB encrypts and decrypts, the transformed sequence is
        +#   AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
        +# OFB-AES128.Encrypt 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 
        +# OFB-AES128.Decrypt 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
        +# OFB-AES192.Encrypt 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 
        +# OFB-AES192.Decrypt 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 
        +# OFB-AES256.Encrypt 
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
        +# OFB-AES256.Decrypt 
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
        +
        +# AES Counter test vectors from RFC3686
        +aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
        +aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
        +aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
        +
        +aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1
        +aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1
        +aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1
        +
        +aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
        +aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
        +aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
        +
        +# DES ECB tests (from destest)
        +
        +DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
        +DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58
        +DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B
        +DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533
        +DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D
        +DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD
        +DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4
        +
        +# DESX-CBC tests (from destest)
        +DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4
        +
        +# DES EDE3 CBC tests (from destest)
        +DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
        +
        +# RC4 tests (from rc4test)
        +RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
        +RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
        +RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
        +RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
        +RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
        +RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
        +
        +
        +# Camellia tests from RFC3713
        +# For all ECB encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec
        +CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43
        +CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9
        +CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509
        +
        +# ECB-CAMELLIA128.Encrypt
        +CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1
        +CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
        +CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
        +
        +# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt 
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
        +
        +# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt 
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
        +
        +# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt 
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B
        +
        +# For all CBC encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt 
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
        +
        +# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt 
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
        +
        +# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt 
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F
        +
        +# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
        +# For all CFB128 encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CFB128-CAMELLIA128.Encrypt 
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
        +
        +# CFB128-CAMELLIA128.Decrypt 
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0
        +
        +# CFB128-CAMELLIA192.Encrypt
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1
        +
        +# CFB128-CAMELLIA192.Decrypt
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
        +
        +# CFB128-CAMELLIA256.Encrypt 
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
        +
        +# CFB128-CAMELLIA256.Decrypt 
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0
        +
        +# For all OFB encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
        +# OFB-CAMELLIA128.Encrypt 
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
        +
        +# OFB-CAMELLIA128.Decrypt 
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
        +
        +# OFB-CAMELLIA192.Encrypt 
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
        +
        +# OFB-CAMELLIA192.Decrypt 
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
        +
        +# OFB-CAMELLIA256.Encrypt 
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
        +
        +# OFB-CAMELLIA256.Decrypt 
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0
        +
        +# SEED test vectors from RFC4269
        +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0
        +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0
        +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0
        +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0
        +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1
        +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1
        +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1
        +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1
        diff --git a/vendor/openssl/openssl/crypto/evp/m_dss.c b/vendor/openssl/openssl/crypto/evp/m_dss.c
        new file mode 100644
        index 000000000..6fb7e9a86
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_dss.c
        @@ -0,0 +1,101 @@
        +/* crypto/evp/m_dss.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/sha.h>
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA
        +#ifndef OPENSSL_FIPS
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return SHA1_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA1_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA1_Final(md,ctx->md_data); }
        +
        +static const EVP_MD dsa_md=
        +	{
        +	NID_dsaWithSHA,
        +	NID_dsaWithSHA,
        +	SHA_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_DIGEST,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_DSA_method,
        +	SHA_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA_CTX),
        +	};
        +
        +const EVP_MD *EVP_dss(void)
        +	{
        +	return(&dsa_md);
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_dss1.c b/vendor/openssl/openssl/crypto/evp/m_dss1.c
        new file mode 100644
        index 000000000..2df362a67
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_dss1.c
        @@ -0,0 +1,103 @@
        +/* crypto/evp/m_dss1.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_SHA
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/sha.h>
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#ifndef OPENSSL_FIPS 
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return SHA1_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA1_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA1_Final(md,ctx->md_data); }
        +
        +static const EVP_MD dss1_md=
        +	{
        +	NID_dsa,
        +	NID_dsaWithSHA1,
        +	SHA_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_DIGEST,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_DSA_method,
        +	SHA_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA_CTX),
        +	};
        +
        +const EVP_MD *EVP_dss1(void)
        +	{
        +	return(&dss1_md);
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_ecdsa.c b/vendor/openssl/openssl/crypto/evp/m_ecdsa.c
        new file mode 100644
        index 000000000..4b15fb0f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_ecdsa.c
        @@ -0,0 +1,151 @@
        +/* crypto/evp/m_ecdsa.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +#ifndef OPENSSL_NO_SHA
        +#ifndef OPENSSL_FIPS
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return SHA1_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA1_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA1_Final(md,ctx->md_data); }
        +
        +static const EVP_MD ecdsa_md=
        +	{
        +	NID_ecdsa_with_SHA1,
        +	NID_ecdsa_with_SHA1,
        +	SHA_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_DIGEST,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_ECDSA_method,
        +	SHA_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA_CTX),
        +	};
        +
        +const EVP_MD *EVP_ecdsa(void)
        +	{
        +	return(&ecdsa_md);
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_md2.c b/vendor/openssl/openssl/crypto/evp/m_md2.c
        new file mode 100644
        index 000000000..5ce849f16
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_md2.c
        @@ -0,0 +1,101 @@
        +/* crypto/evp/m_md2.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_MD2
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/md2.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return MD2_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return MD2_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return MD2_Final(md,ctx->md_data); }
        +
        +static const EVP_MD md2_md=
        +	{
        +	NID_md2,
        +	NID_md2WithRSAEncryption,
        +	MD2_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	MD2_BLOCK,
        +	sizeof(EVP_MD *)+sizeof(MD2_CTX),
        +	};
        +
        +const EVP_MD *EVP_md2(void)
        +	{
        +	return(&md2_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_md4.c b/vendor/openssl/openssl/crypto/evp/m_md4.c
        new file mode 100644
        index 000000000..6d47f61b2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_md4.c
        @@ -0,0 +1,103 @@
        +/* 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.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_MD4
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/md4.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +
        +#include "evp_locl.h"
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return MD4_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return MD4_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return MD4_Final(md,ctx->md_data); }
        +
        +static const EVP_MD md4_md=
        +	{
        +	NID_md4,
        +	NID_md4WithRSAEncryption,
        +	MD4_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	MD4_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(MD4_CTX),
        +	};
        +
        +const EVP_MD *EVP_md4(void)
        +	{
        +	return(&md4_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_md5.c b/vendor/openssl/openssl/crypto/evp/m_md5.c
        new file mode 100644
        index 000000000..9a8bae025
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_md5.c
        @@ -0,0 +1,102 @@
        +/* crypto/evp/m_md5.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_MD5
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/md5.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include "evp_locl.h"
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return MD5_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return MD5_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return MD5_Final(md,ctx->md_data); }
        +
        +static const EVP_MD md5_md=
        +	{
        +	NID_md5,
        +	NID_md5WithRSAEncryption,
        +	MD5_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	MD5_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(MD5_CTX),
        +	};
        +
        +const EVP_MD *EVP_md5(void)
        +	{
        +	return(&md5_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_mdc2.c b/vendor/openssl/openssl/crypto/evp/m_mdc2.c
        new file mode 100644
        index 000000000..3602bed31
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_mdc2.c
        @@ -0,0 +1,103 @@
        +/* crypto/evp/m_mdc2.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_MDC2
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/mdc2.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +
        +#include "evp_locl.h"
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return MDC2_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return MDC2_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return MDC2_Final(md,ctx->md_data); }
        +
        +static const EVP_MD mdc2_md=
        +	{
        +	NID_mdc2,
        +	NID_mdc2WithRSA,
        +	MDC2_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_ASN1_OCTET_STRING_method,
        +	MDC2_BLOCK,
        +	sizeof(EVP_MD *)+sizeof(MDC2_CTX),
        +	};
        +
        +const EVP_MD *EVP_mdc2(void)
        +	{
        +	return(&mdc2_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_null.c b/vendor/openssl/openssl/crypto/evp/m_null.c
        new file mode 100644
        index 000000000..cb0721699
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_null.c
        @@ -0,0 +1,95 @@
        +/* crypto/evp/m_null.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return 1; }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return 1; }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return 1; }
        +
        +static const EVP_MD null_md=
        +	{
        +	NID_undef,
        +	NID_undef,
        +	0,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_NULL_method,
        +	0,
        +	sizeof(EVP_MD *),
        +	};
        +
        +const EVP_MD *EVP_md_null(void)
        +	{
        +	return(&null_md);
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/m_ripemd.c b/vendor/openssl/openssl/crypto/evp/m_ripemd.c
        new file mode 100644
        index 000000000..7bf4804cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_ripemd.c
        @@ -0,0 +1,102 @@
        +/* crypto/evp/m_ripemd.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_RIPEMD
        +
        +#include <openssl/ripemd.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include "evp_locl.h"
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return RIPEMD160_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return RIPEMD160_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return RIPEMD160_Final(md,ctx->md_data); }
        +
        +static const EVP_MD ripemd160_md=
        +	{
        +	NID_ripemd160,
        +	NID_ripemd160WithRSA,
        +	RIPEMD160_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	RIPEMD160_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(RIPEMD160_CTX),
        +	};
        +
        +const EVP_MD *EVP_ripemd160(void)
        +	{
        +	return(&ripemd160_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_sha.c b/vendor/openssl/openssl/crypto/evp/m_sha.c
        new file mode 100644
        index 000000000..8769cdd42
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_sha.c
        @@ -0,0 +1,101 @@
        +/* crypto/evp/m_sha.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include "evp_locl.h"
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return SHA_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA_Final(md,ctx->md_data); }
        +
        +static const EVP_MD sha_md=
        +	{
        +	NID_sha,
        +	NID_shaWithRSAEncryption,
        +	SHA_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA_CTX),
        +	};
        +
        +const EVP_MD *EVP_sha(void)
        +	{
        +	return(&sha_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_sha1.c b/vendor/openssl/openssl/crypto/evp/m_sha1.c
        new file mode 100644
        index 000000000..bd0c01ad3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_sha1.c
        @@ -0,0 +1,209 @@
        +/* crypto/evp/m_sha1.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_FIPS
        +
        +#ifndef OPENSSL_NO_SHA
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/sha.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return SHA1_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA1_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA1_Final(md,ctx->md_data); }
        +
        +static const EVP_MD sha1_md=
        +	{
        +	NID_sha1,
        +	NID_sha1WithRSAEncryption,
        +	SHA_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA_CTX),
        +	};
        +
        +const EVP_MD *EVP_sha1(void)
        +	{
        +	return(&sha1_md);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA256
        +static int init224(EVP_MD_CTX *ctx)
        +	{ return SHA224_Init(ctx->md_data); }
        +static int init256(EVP_MD_CTX *ctx)
        +	{ return SHA256_Init(ctx->md_data); }
        +/*
        + * Even though there're separate SHA224_[Update|Final], we call
        + * SHA256 functions even in SHA224 context. This is what happens
        + * there anyway, so we can spare few CPU cycles:-)
        + */
        +static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA256_Update(ctx->md_data,data,count); }
        +static int final256(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA256_Final(md,ctx->md_data); }
        +
        +static const EVP_MD sha224_md=
        +	{
        +	NID_sha224,
        +	NID_sha224WithRSAEncryption,
        +	SHA224_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
        +	init224,
        +	update256,
        +	final256,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA256_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA256_CTX),
        +	};
        +
        +const EVP_MD *EVP_sha224(void)
        +	{ return(&sha224_md); }
        +
        +static const EVP_MD sha256_md=
        +	{
        +	NID_sha256,
        +	NID_sha256WithRSAEncryption,
        +	SHA256_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
        +	init256,
        +	update256,
        +	final256,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA256_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA256_CTX),
        +	};
        +
        +const EVP_MD *EVP_sha256(void)
        +	{ return(&sha256_md); }
        +#endif	/* ifndef OPENSSL_NO_SHA256 */
        +
        +#ifndef OPENSSL_NO_SHA512
        +static int init384(EVP_MD_CTX *ctx)
        +	{ return SHA384_Init(ctx->md_data); }
        +static int init512(EVP_MD_CTX *ctx)
        +	{ return SHA512_Init(ctx->md_data); }
        +/* See comment in SHA224/256 section */
        +static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return SHA512_Update(ctx->md_data,data,count); }
        +static int final512(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return SHA512_Final(md,ctx->md_data); }
        +
        +static const EVP_MD sha384_md=
        +	{
        +	NID_sha384,
        +	NID_sha384WithRSAEncryption,
        +	SHA384_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
        +	init384,
        +	update512,
        +	final512,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA512_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA512_CTX),
        +	};
        +
        +const EVP_MD *EVP_sha384(void)
        +	{ return(&sha384_md); }
        +
        +static const EVP_MD sha512_md=
        +	{
        +	NID_sha512,
        +	NID_sha512WithRSAEncryption,
        +	SHA512_DIGEST_LENGTH,
        +	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
        +	init512,
        +	update512,
        +	final512,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	SHA512_CBLOCK,
        +	sizeof(EVP_MD *)+sizeof(SHA512_CTX),
        +	};
        +
        +const EVP_MD *EVP_sha512(void)
        +	{ return(&sha512_md); }
        +#endif	/* ifndef OPENSSL_NO_SHA512 */
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/m_sigver.c b/vendor/openssl/openssl/crypto/evp/m_sigver.c
        new file mode 100644
        index 000000000..7e2731f4a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_sigver.c
        @@ -0,0 +1,200 @@
        +/* m_sigver.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006,2007 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include "evp_locl.h"
        +
        +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			  const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
        +			  int ver)
        +	{
        +	if (ctx->pctx == NULL)
        +		ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
        +	if (ctx->pctx == NULL)
        +		return 0;
        +
        +	if (type == NULL)
        +		{
        +		int def_nid;
        +		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
        +			type = EVP_get_digestbynid(def_nid);
        +		}
        +
        +	if (type == NULL)
        +		{
        +		EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
        +		return 0;
        +		}
        +
        +	if (ver)
        +		{
        +		if (ctx->pctx->pmeth->verifyctx_init)
        +			{
        +			if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0)
        +				return 0;
        +			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
        +			}
        +		else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
        +			return 0;
        +		}
        +	else
        +		{
        +		if (ctx->pctx->pmeth->signctx_init)
        +			{
        +			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
        +				return 0;
        +			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
        +			}
        +		else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
        +			return 0;
        +		}
        +	if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
        +		return 0;
        +	if (pctx)
        +		*pctx = ctx->pctx;
        +	if (!EVP_DigestInit_ex(ctx, type, e))
        +		return 0;
        +	return 1;
        +	}
        +
        +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
        +	{
        +	return do_sigver_init(ctx, pctx, type, e, pkey, 0);
        +	}
        +
        +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
        +	{
        +	return do_sigver_init(ctx, pctx, type, e, pkey, 1);
        +	}
        +
        +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
        +	{
        +	int sctx, r = 0;
        +	if (ctx->pctx->pmeth->signctx)
        +		sctx = 1;
        +	else
        +		sctx = 0;
        +	if (sigret)
        +		{
        +		EVP_MD_CTX tmp_ctx;
        +		unsigned char md[EVP_MAX_MD_SIZE];
        +		unsigned int mdlen;
        +		EVP_MD_CTX_init(&tmp_ctx);
        +		if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
        +		     	return 0;
        +		if (sctx)
        +			r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
        +					sigret, siglen, &tmp_ctx);
        +		else
        +			r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
        +		EVP_MD_CTX_cleanup(&tmp_ctx);
        +		if (sctx || !r)
        +			return r;
        +		if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
        +			return 0;
        +		}
        +	else
        +		{
        +		if (sctx)
        +			{
        +			if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0)
        +				return 0;
        +			}
        +		else
        +			{
        +			int s = EVP_MD_size(ctx->digest);
        +			if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0)
        +				return 0;
        +			}
        +		}
        +	return 1;
        +	}
        +
        +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
        +	{
        +	EVP_MD_CTX tmp_ctx;
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +	int r;
        +	unsigned int mdlen;
        +	int vctx;
        +
        +	if (ctx->pctx->pmeth->verifyctx)
        +		vctx = 1;
        +	else
        +		vctx = 0;
        +	EVP_MD_CTX_init(&tmp_ctx);
        +	if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
        +		return -1;	
        +	if (vctx)
        +		{
        +		r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
        +					sig, siglen, &tmp_ctx);
        +		}
        +	else
        +		r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
        +	EVP_MD_CTX_cleanup(&tmp_ctx);
        +	if (vctx || !r)
        +		return r;
        +	return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/m_wp.c b/vendor/openssl/openssl/crypto/evp/m_wp.c
        new file mode 100644
        index 000000000..c51bc2d5d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/m_wp.c
        @@ -0,0 +1,43 @@
        +/* crypto/evp/m_wp.c */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/whrlpool.h>
        +#include "evp_locl.h"
        +
        +static int init(EVP_MD_CTX *ctx)
        +	{ return WHIRLPOOL_Init(ctx->md_data); }
        +
        +static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{ return WHIRLPOOL_Update(ctx->md_data,data,count); }
        +
        +static int final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{ return WHIRLPOOL_Final(md,ctx->md_data); }
        +
        +static const EVP_MD whirlpool_md=
        +	{
        +	NID_whirlpool,
        +	0,
        +	WHIRLPOOL_DIGEST_LENGTH,
        +	0,
        +	init,
        +	update,
        +	final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_NULL_method,
        +	WHIRLPOOL_BBLOCK/8,
        +	sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX),
        +	};
        +
        +const EVP_MD *EVP_whirlpool(void)
        +	{
        +	return(&whirlpool_md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/names.c b/vendor/openssl/openssl/crypto/evp/names.c
        new file mode 100644
        index 000000000..6311ad7cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/names.c
        @@ -0,0 +1,206 @@
        +/* crypto/evp/names.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int EVP_add_cipher(const EVP_CIPHER *c)
        +	{
        +	int r;
        +
        +	if (c == NULL) return 0;
        +
        +	OPENSSL_init();
        +
        +	r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
        +	if (r == 0) return(0);
        +	check_defer(c->nid);
        +	r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
        +	return(r);
        +	}
        +
        +
        +int EVP_add_digest(const EVP_MD *md)
        +	{
        +	int r;
        +	const char *name;
        +	OPENSSL_init();
        +
        +	name=OBJ_nid2sn(md->type);
        +	r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
        +	if (r == 0) return(0);
        +	check_defer(md->type);
        +	r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md);
        +	if (r == 0) return(0);
        +
        +	if (md->pkey_type && md->type != md->pkey_type)
        +		{
        +		r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
        +			OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
        +		if (r == 0) return(0);
        +		check_defer(md->pkey_type);
        +		r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
        +			OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
        +		}
        +	return(r);
        +	}
        +
        +const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
        +	{
        +	const EVP_CIPHER *cp;
        +
        +	cp=(const EVP_CIPHER *)OBJ_NAME_get(name,OBJ_NAME_TYPE_CIPHER_METH);
        +	return(cp);
        +	}
        +
        +const EVP_MD *EVP_get_digestbyname(const char *name)
        +	{
        +	const EVP_MD *cp;
        +
        +	cp=(const EVP_MD *)OBJ_NAME_get(name,OBJ_NAME_TYPE_MD_METH);
        +	return(cp);
        +	}
        +
        +void EVP_cleanup(void)
        +	{
        +	OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
        +	OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
        +	/* The above calls will only clean out the contents of the name
        +	   hash table, but not the hash table itself.  The following line
        +	   does that part.  -- Richard Levitte */
        +	OBJ_NAME_cleanup(-1);
        +
        +	EVP_PBE_cleanup();
        +	if (obj_cleanup_defer == 2)
        +		{
        +		obj_cleanup_defer = 0;
        +		OBJ_cleanup();
        +		}
        +	OBJ_sigid_free();
        +	}
        +
        +struct doall_cipher
        +	{
        +	void *arg;
        +	void (*fn)(const EVP_CIPHER *ciph,
        +			const char *from, const char *to, void *arg);
        +	};
        +
        +static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
        +	{
        +	struct doall_cipher *dc = arg;
        +	if (nm->alias)
        +		dc->fn(NULL, nm->name, nm->data, dc->arg);
        +	else
        +		dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
        +	}
        +
        +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
        +		const char *from, const char *to, void *x), void *arg)
        +	{
        +	struct doall_cipher dc;
        +	dc.fn = fn;
        +	dc.arg = arg;
        +	OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
        +	}
        +
        +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
        +		const char *from, const char *to, void *x), void *arg)
        +	{
        +	struct doall_cipher dc;
        +	dc.fn = fn;
        +	dc.arg = arg;
        +	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn,&dc);
        +	}
        +
        +struct doall_md
        +	{
        +	void *arg;
        +	void (*fn)(const EVP_MD *ciph,
        +			const char *from, const char *to, void *arg);
        +	};
        +
        +static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
        +	{
        +	struct doall_md *dc = arg;
        +	if (nm->alias)
        +		dc->fn(NULL, nm->name, nm->data, dc->arg);
        +	else
        +		dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
        +	}
        +
        +void EVP_MD_do_all(void (*fn)(const EVP_MD *md,
        +		const char *from, const char *to, void *x), void *arg)
        +	{
        +	struct doall_md dc;
        +	dc.fn = fn;
        +	dc.arg = arg;
        +	OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
        +	}
        +
        +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md,
        +		const char *from, const char *to, void *x), void *arg)
        +	{
        +	struct doall_md dc;
        +	dc.fn = fn;
        +	dc.arg = arg;
        +	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/openbsd_hw.c b/vendor/openssl/openssl/crypto/evp/openbsd_hw.c
        new file mode 100644
        index 000000000..3831a5731
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/openbsd_hw.c
        @@ -0,0 +1,446 @@
        +/* Written by Ben Laurie, 2001 */
        +/*
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/rsa.h>
        +#include "evp_locl.h"
        +
        +/* This stuff should now all be supported through
        + * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up */
        +static void *dummy=&dummy;
        +
        +#if 0
        +
        +/* check flag after OpenSSL headers to ensure make depend works */
        +#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
        +
        +#include <fcntl.h>
        +#include <stdio.h>
        +#include <errno.h>
        +#include <sys/ioctl.h>
        +#include <crypto/cryptodev.h>
        +#include <unistd.h>
        +#include <assert.h>
        +
        +/* longest key supported in hardware */
        +#define MAX_HW_KEY	24
        +#define MAX_HW_IV	8
        +
        +#define MD5_DIGEST_LENGTH	16
        +#define MD5_CBLOCK		64
        +
        +static int fd;
        +static int dev_failed;
        +
        +typedef struct session_op session_op;
        +
        +#define CDATA(ctx) EVP_C_DATA(session_op,ctx)
        +
        +static void err(const char *str)
        +    {
        +    fprintf(stderr,"%s: errno %d\n",str,errno);
        +    }
        +
        +static int dev_crypto_init(session_op *ses)
        +    {
        +    if(dev_failed)
        +	return 0;
        +    if(!fd)
        +	{
        +	int cryptodev_fd;
        +
        +        if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0)
        +	    {
        +	    err("/dev/crypto");
        +	    dev_failed=1;
        +	    return 0;
        +	    }
        +        if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1)
        +	    {
        +	    err("CRIOGET failed");
        +	    close(cryptodev_fd);
        +	    dev_failed=1;
        +	    return 0;
        +	    }
        +	close(cryptodev_fd);
        +	}
        +    assert(ses);
        +    memset(ses,'\0',sizeof *ses);
        +
        +    return 1;
        +    }
        +
        +static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
        +    {
        +    if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1)
        +	err("CIOCFSESSION failed");
        +
        +    OPENSSL_free(CDATA(ctx)->key);
        +
        +    return 1;
        +    }
        +
        +static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
        +			       const unsigned char *key,int klen)
        +    {
        +    if(!dev_crypto_init(CDATA(ctx)))
        +	return 0;
        +
        +    CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
        +
        +    assert(ctx->cipher->iv_len <= MAX_HW_IV);
        +
        +    memcpy(CDATA(ctx)->key,key,klen);
        +    
        +    CDATA(ctx)->cipher=cipher;
        +    CDATA(ctx)->keylen=klen;
        +
        +    if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1)
        +	{
        +	err("CIOCGSESSION failed");
        +	return 0;
        +	}
        +    return 1;
        +    }
        +
        +static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        +			     const unsigned char *in,unsigned int inl)
        +    {
        +    struct crypt_op cryp;
        +    unsigned char lb[MAX_HW_IV];
        +
        +    if(!inl)
        +	return 1;
        +
        +    assert(CDATA(ctx));
        +    assert(!dev_failed);
        +
        +    memset(&cryp,'\0',sizeof cryp);
        +    cryp.ses=CDATA(ctx)->ses;
        +    cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
        +    cryp.flags=0;
        +    cryp.len=inl;
        +    assert((inl&(ctx->cipher->block_size-1)) == 0);
        +    cryp.src=(caddr_t)in;
        +    cryp.dst=(caddr_t)out;
        +    cryp.mac=0;
        +    if(ctx->cipher->iv_len)
        +	cryp.iv=(caddr_t)ctx->iv;
        +
        +    if(!ctx->encrypt)
        +	memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
        +
        +    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
        +	{
        +	if(errno == EINVAL) /* buffers are misaligned */
        +	    {
        +	    unsigned int cinl=0;
        +	    char *cin=NULL;
        +	    char *cout=NULL;
        +
        +	    /* NB: this can only make cinl != inl with stream ciphers */
        +	    cinl=(inl+3)/4*4;
        +
        +	    if(((unsigned long)in&3) || cinl != inl)
        +		{
        +		cin=OPENSSL_malloc(cinl);
        +		memcpy(cin,in,inl);
        +		cryp.src=cin;
        +		}
        +
        +	    if(((unsigned long)out&3) || cinl != inl)
        +		{
        +		cout=OPENSSL_malloc(cinl);
        +		cryp.dst=cout;
        +		}
        +
        +	    cryp.len=cinl;
        +
        +	    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
        +		{
        +		err("CIOCCRYPT(2) failed");
        +		printf("src=%p dst=%p\n",cryp.src,cryp.dst);
        +		abort();
        +		return 0;
        +		}
        +		
        +	    if(cout)
        +		{
        +		memcpy(out,cout,inl);
        +		OPENSSL_free(cout);
        +		}
        +	    if(cin)
        +		OPENSSL_free(cin);
        +	    }
        +	else 
        +	    {	    
        +	    err("CIOCCRYPT failed");
        +	    abort();
        +	    return 0;
        +	    }
        +	}
        +
        +    if(ctx->encrypt)
        +	memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
        +    else
        +	memcpy(ctx->iv,lb,ctx->cipher->iv_len);
        +
        +    return 1;
        +    }
        +
        +static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
        +					const unsigned char *key,
        +					const unsigned char *iv, int enc)
        +    { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); }
        +
        +#define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher
        +
        +BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8,
        +		     0, dev_crypto_des_ede3_init_key,
        +		     dev_crypto_cleanup, 
        +		     EVP_CIPHER_set_asn1_iv,
        +		     EVP_CIPHER_get_asn1_iv,
        +		     NULL)
        +
        +static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx,
        +					const unsigned char *key,
        +					const unsigned char *iv, int enc)
        +    { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); }
        +
        +static const EVP_CIPHER r4_cipher=
        +    {
        +    NID_rc4,
        +    1,16,0,	/* FIXME: key should be up to 256 bytes */
        +    EVP_CIPH_VARIABLE_LENGTH,
        +    dev_crypto_rc4_init_key,
        +    dev_crypto_cipher,
        +    dev_crypto_cleanup,
        +    sizeof(session_op),
        +    NULL,
        +    NULL,
        +    NULL
        +    };
        +
        +const EVP_CIPHER *EVP_dev_crypto_rc4(void)
        +    { return &r4_cipher; }
        +
        +typedef struct
        +    {
        +    session_op sess;
        +    char *data;
        +    int len;
        +    unsigned char md[EVP_MAX_MD_SIZE];
        +    } MD_DATA;
        +
        +static int dev_crypto_init_digest(MD_DATA *md_data,int mac)
        +    {
        +    if(!dev_crypto_init(&md_data->sess))
        +	return 0;
        +
        +    md_data->len=0;
        +    md_data->data=NULL;
        +
        +    md_data->sess.mac=mac;
        +
        +    if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1)
        +	{
        +	err("CIOCGSESSION failed");
        +	return 0;
        +	}
        +    return 1;
        +    }
        +
        +static int dev_crypto_cleanup_digest(MD_DATA *md_data)
        +    {
        +    if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1)
        +	{
        +	err("CIOCFSESSION failed");
        +	return 0;
        +	}
        +
        +    return 1;
        +    }
        +
        +/* FIXME: if device can do chained MACs, then don't accumulate */
        +/* FIXME: move accumulation to the framework */
        +static int dev_crypto_md5_init(EVP_MD_CTX *ctx)
        +    { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); }
        +
        +static int do_digest(int ses,unsigned char *md,const void *data,int len)
        +    {
        +    struct crypt_op cryp;
        +    static unsigned char md5zero[16]=
        +	{
        +	0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,
        +	0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e
        +	};
        +
        +    /* some cards can't do zero length */
        +    if(!len)
        +	{
        +	memcpy(md,md5zero,16);
        +	return 1;
        +	}
        +
        +    memset(&cryp,'\0',sizeof cryp);
        +    cryp.ses=ses;
        +    cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */
        +    cryp.len=len;
        +    cryp.src=(caddr_t)data;
        +    cryp.dst=(caddr_t)data; // FIXME!!!
        +    cryp.mac=(caddr_t)md;
        +
        +    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
        +	{
        +	if(errno == EINVAL) /* buffer is misaligned */
        +	    {
        +	    char *dcopy;
        +
        +	    dcopy=OPENSSL_malloc(len);
        +	    memcpy(dcopy,data,len);
        +	    cryp.src=dcopy;
        +	    cryp.dst=cryp.src; // FIXME!!!
        +
        +	    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
        +		{
        +		err("CIOCCRYPT(MAC2) failed");
        +		abort();
        +		return 0;
        +		}
        +	    OPENSSL_free(dcopy);
        +	    }
        +	else
        +	    {
        +	    err("CIOCCRYPT(MAC) failed");
        +	    abort();
        +	    return 0;
        +	    }
        +	}
        +    //    printf("done\n");
        +
        +    return 1;
        +    }
        +
        +static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data,
        +				 unsigned long len)
        +    {
        +    MD_DATA *md_data=ctx->md_data;
        +
        +    if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
        +	return do_digest(md_data->sess.ses,md_data->md,data,len);
        +
        +    md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len);
        +    memcpy(md_data->data+md_data->len,data,len);
        +    md_data->len+=len;
        +
        +    return 1;
        +    }	
        +
        +static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
        +    {
        +    int ret;
        +    MD_DATA *md_data=ctx->md_data;
        +
        +    if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
        +	{
        +	memcpy(md,md_data->md,MD5_DIGEST_LENGTH);
        +	ret=1;
        +	}
        +    else
        +	{
        +	ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len);
        +	OPENSSL_free(md_data->data);
        +	md_data->data=NULL;
        +	md_data->len=0;
        +	}
        +
        +    return ret;
        +    }
        +
        +static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
        +    {
        +    const MD_DATA *from_md=from->md_data;
        +    MD_DATA *to_md=to->md_data;
        +
        +    // How do we copy sessions?
        +    assert(from->digest->flags&EVP_MD_FLAG_ONESHOT);
        +
        +    to_md->data=OPENSSL_malloc(from_md->len);
        +    memcpy(to_md->data,from_md->data,from_md->len);
        +
        +    return 1;
        +    }
        +
        +static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx)
        +    {
        +    return dev_crypto_cleanup_digest(ctx->md_data);
        +    }
        +
        +static const EVP_MD md5_md=
        +    {
        +    NID_md5,
        +    NID_md5WithRSAEncryption,
        +    MD5_DIGEST_LENGTH,
        +    EVP_MD_FLAG_ONESHOT,	// XXX: set according to device info...
        +    dev_crypto_md5_init,
        +    dev_crypto_md5_update,
        +    dev_crypto_md5_final,
        +    dev_crypto_md5_copy,
        +    dev_crypto_md5_cleanup,
        +    EVP_PKEY_RSA_method,
        +    MD5_CBLOCK,
        +    sizeof(MD_DATA),
        +    };
        +
        +const EVP_MD *EVP_dev_crypto_md5(void)
        +    { return &md5_md; }
        +
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/p5_crpt.c b/vendor/openssl/openssl/crypto/evp/p5_crpt.c
        new file mode 100644
        index 000000000..294cc90d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p5_crpt.c
        @@ -0,0 +1,143 @@
        +/* p5_crpt.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/evp.h>
        +
        +/* Doesn't do anything now: Builtin PBE algorithms in static table.
        + */
        +
        +void PKCS5_PBE_add(void)
        +{
        +}
        +
        +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
        +			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
        +			 int en_de)
        +{
        +	EVP_MD_CTX ctx;
        +	unsigned char md_tmp[EVP_MAX_MD_SIZE];
        +	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
        +	int i;
        +	PBEPARAM *pbe;
        +	int saltlen, iter;
        +	unsigned char *salt;
        +	const unsigned char *pbuf;
        +	int mdsize;
        +	int rv = 0;
        +	EVP_MD_CTX_init(&ctx);
        +
        +	/* Extract useful info from parameter */
        +	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
        +	    param->value.sequence == NULL) {
        +		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
        +		return 0;
        +	}
        +
        +	pbuf = param->value.sequence->data;
        +	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
        +		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
        +		return 0;
        +	}
        +
        +	if (!pbe->iter) iter = 1;
        +	else iter = ASN1_INTEGER_get (pbe->iter);
        +	salt = pbe->salt->data;
        +	saltlen = pbe->salt->length;
        +
        +	if(!pass) passlen = 0;
        +	else if(passlen == -1) passlen = strlen(pass);
        +
        +	if (!EVP_DigestInit_ex(&ctx, md, NULL))
        +		goto err;
        +	if (!EVP_DigestUpdate(&ctx, pass, passlen))
        +		goto err;
        +	if (!EVP_DigestUpdate(&ctx, salt, saltlen))
        +		goto err;
        +	PBEPARAM_free(pbe);
        +	if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
        +		goto err;
        +	mdsize = EVP_MD_size(md);
        +	if (mdsize < 0)
        +	    return 0;
        +	for (i = 1; i < iter; i++) {
        +		if (!EVP_DigestInit_ex(&ctx, md, NULL))
        +			goto err;
        +		if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
        +			goto err;
        +		if (!EVP_DigestFinal_ex (&ctx, md_tmp, NULL))
        +			goto err;
        +	}
        +	OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
        +	memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
        +	OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
        +	memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
        +						 EVP_CIPHER_iv_length(cipher));
        +	if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
        +		goto err;
        +	OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
        +	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
        +	OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
        +	rv = 1;
        +	err:
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return rv;
        +}
        diff --git a/vendor/openssl/openssl/crypto/evp/p5_crpt2.c b/vendor/openssl/openssl/crypto/evp/p5_crpt2.c
        new file mode 100644
        index 000000000..975d004df
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p5_crpt2.c
        @@ -0,0 +1,322 @@
        +/* p5_crpt2.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
        +#include <openssl/x509.h>
        +#include <openssl/evp.h>
        +#include <openssl/hmac.h>
        +#include "evp_locl.h"
        +
        +/* set this to print out info about the keygen algorithm */
        +/* #define DEBUG_PKCS5V2 */
        +
        +#ifdef DEBUG_PKCS5V2
        +	static void h__dump (const unsigned char *p, int len);
        +#endif
        +
        +/* This is an implementation of PKCS#5 v2.0 password based encryption key
        + * derivation function PBKDF2.
        + * SHA1 version verified against test vectors posted by Peter Gutmann
        + * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
        + */
        +
        +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
        +			   const unsigned char *salt, int saltlen, int iter,
        +			   const EVP_MD *digest,
        +			   int keylen, unsigned char *out)
        +	{
        +	unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
        +	int cplen, j, k, tkeylen, mdlen;
        +	unsigned long i = 1;
        +	HMAC_CTX hctx;
        +
        +	mdlen = EVP_MD_size(digest);
        +	if (mdlen < 0)
        +		return 0;
        +
        +	HMAC_CTX_init(&hctx);
        +	p = out;
        +	tkeylen = keylen;
        +	if(!pass)
        +		passlen = 0;
        +	else if(passlen == -1)
        +		passlen = strlen(pass);
        +	while(tkeylen)
        +		{
        +		if(tkeylen > mdlen)
        +			cplen = mdlen;
        +		else
        +			cplen = tkeylen;
        +		/* We are unlikely to ever use more than 256 blocks (5120 bits!)
        +		 * but just in case...
        +		 */
        +		itmp[0] = (unsigned char)((i >> 24) & 0xff);
        +		itmp[1] = (unsigned char)((i >> 16) & 0xff);
        +		itmp[2] = (unsigned char)((i >> 8) & 0xff);
        +		itmp[3] = (unsigned char)(i & 0xff);
        +		if (!HMAC_Init_ex(&hctx, pass, passlen, digest, NULL)
        +			|| !HMAC_Update(&hctx, salt, saltlen)
        +			|| !HMAC_Update(&hctx, itmp, 4)
        +			|| !HMAC_Final(&hctx, digtmp, NULL))
        +			{
        +			HMAC_CTX_cleanup(&hctx);
        +			return 0;
        +			}
        +		memcpy(p, digtmp, cplen);
        +		for(j = 1; j < iter; j++)
        +			{
        +			HMAC(digest, pass, passlen,
        +				 digtmp, mdlen, digtmp, NULL);
        +			for(k = 0; k < cplen; k++)
        +				p[k] ^= digtmp[k];
        +			}
        +		tkeylen-= cplen;
        +		i++;
        +		p+= cplen;
        +		}
        +	HMAC_CTX_cleanup(&hctx);
        +#ifdef DEBUG_PKCS5V2
        +	fprintf(stderr, "Password:\n");
        +	h__dump (pass, passlen);
        +	fprintf(stderr, "Salt:\n");
        +	h__dump (salt, saltlen);
        +	fprintf(stderr, "Iteration count %d\n", iter);
        +	fprintf(stderr, "Key:\n");
        +	h__dump (out, keylen);
        +#endif
        +	return 1;
        +	}
        +
        +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
        +			   const unsigned char *salt, int saltlen, int iter,
        +			   int keylen, unsigned char *out)
        +	{
        +	return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
        +					keylen, out);
        +	}
        +
        +#ifdef DO_TEST
        +main()
        +{
        +	unsigned char out[4];
        +	unsigned char salt[] = {0x12, 0x34, 0x56, 0x78};
        +	PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
        +	fprintf(stderr, "Out %02X %02X %02X %02X\n",
        +					 out[0], out[1], out[2], out[3]);
        +}
        +
        +#endif
        +
        +/* Now the key derivation function itself. This is a bit evil because
        + * it has to check the ASN1 parameters are valid: and there are quite a
        + * few of them...
        + */
        +
        +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +                         ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md,
        +                         int en_de)
        +{
        +	const unsigned char *pbuf;
        +	int plen;
        +	PBE2PARAM *pbe2 = NULL;
        +	const EVP_CIPHER *cipher;
        +
        +	int rv = 0;
        +
        +	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
        +	    param->value.sequence == NULL) {
        +		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
        +		goto err;
        +	}
        +
        +	pbuf = param->value.sequence->data;
        +	plen = param->value.sequence->length;
        +	if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
        +		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
        +		goto err;
        +	}
        +
        +	/* See if we recognise the key derivation function */
        +
        +	if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
        +		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
        +				EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
        +		goto err;
        +	}
        +
        +	/* lets see if we recognise the encryption algorithm.
        +	 */
        +
        +	cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
        +
        +	if(!cipher) {
        +		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
        +						EVP_R_UNSUPPORTED_CIPHER);
        +		goto err;
        +	}
        +
        +	/* Fixup cipher based on AlgorithmIdentifier */
        +	if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
        +		goto err;
        +	if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
        +		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
        +					EVP_R_CIPHER_PARAMETER_ERROR);
        +		goto err;
        +	}
        +	rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
        +					pbe2->keyfunc->parameter, c, md, en_de);
        +	err:
        +	PBE2PARAM_free(pbe2);
        +	return rv;
        +}
        +
        +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +                         ASN1_TYPE *param,
        +			 const EVP_CIPHER *c, const EVP_MD *md, int en_de)
        +{
        +	unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
        +	const unsigned char *pbuf;
        +	int saltlen, iter, plen;
        +	int rv = 0;
        +	unsigned int keylen = 0;
        +	int prf_nid, hmac_md_nid;
        +	PBKDF2PARAM *kdf = NULL;
        +	const EVP_MD *prfmd;
        +
        +	if (EVP_CIPHER_CTX_cipher(ctx) == NULL)
        +		{
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_NO_CIPHER_SET);
        +		goto err;
        +		}
        +	keylen = EVP_CIPHER_CTX_key_length(ctx);
        +	OPENSSL_assert(keylen <= sizeof key);
        +
        +	/* Decode parameter */
        +
        +	if(!param || (param->type != V_ASN1_SEQUENCE))
        +		{
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
        +		goto err;
        +		}
        +
        +	pbuf = param->value.sequence->data;
        +	plen = param->value.sequence->length;
        +
        +	if(!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
        +		goto err;
        +	}
        +
        +	keylen = EVP_CIPHER_CTX_key_length(ctx);
        +
        +	/* Now check the parameters of the kdf */
        +
        +	if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
        +						EVP_R_UNSUPPORTED_KEYLENGTH);
        +		goto err;
        +	}
        +
        +	if (kdf->prf)
        +		prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
        +	else
        +		prf_nid = NID_hmacWithSHA1;
        +
        +	if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
        +		{
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
        +		goto err;
        +		}
        +
        +	prfmd = EVP_get_digestbynid(hmac_md_nid);
        +	if (prfmd == NULL)
        +		{
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
        +		goto err;
        +		}
        +
        +	if(kdf->salt->type != V_ASN1_OCTET_STRING) {
        +		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
        +						EVP_R_UNSUPPORTED_SALT_TYPE);
        +		goto err;
        +	}
        +
        +	/* it seems that its all OK */
        +	salt = kdf->salt->value.octet_string->data;
        +	saltlen = kdf->salt->value.octet_string->length;
        +	iter = ASN1_INTEGER_get(kdf->iter);
        +	if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
        +						   keylen, key))
        +		goto err;
        +	rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
        +	err:
        +	OPENSSL_cleanse(key, keylen);
        +	PBKDF2PARAM_free(kdf);
        +	return rv;
        +}
        +
        +#ifdef DEBUG_PKCS5V2
        +static void h__dump (const unsigned char *p, int len)
        +{
        +        for (; len --; p++) fprintf(stderr, "%02X ", *p);
        +        fprintf(stderr, "\n");
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/p_dec.c b/vendor/openssl/openssl/crypto/evp/p_dec.c
        new file mode 100644
        index 000000000..4201dcbad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_dec.c
        @@ -0,0 +1,87 @@
        +/* crypto/evp/p_dec.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
        +	     EVP_PKEY *priv)
        +	{
        +	int ret= -1;
        +	
        +#ifndef OPENSSL_NO_RSA
        +	if (priv->type != EVP_PKEY_RSA)
        +		{
        +#endif
        +		EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
        +#ifndef OPENSSL_NO_RSA
        +		goto err;
        +                }
        +
        +	ret=RSA_private_decrypt(ekl,ek,key,priv->pkey.rsa,RSA_PKCS1_PADDING);
        +err:
        +#endif
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/p_enc.c b/vendor/openssl/openssl/crypto/evp/p_enc.c
        new file mode 100644
        index 000000000..b5a3a84c4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_enc.c
        @@ -0,0 +1,86 @@
        +/* crypto/evp/p_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len,
        +	     EVP_PKEY *pubk)
        +	{
        +	int ret=0;
        +	
        +#ifndef OPENSSL_NO_RSA
        +	if (pubk->type != EVP_PKEY_RSA)
        +		{
        +#endif
        +		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
        +#ifndef OPENSSL_NO_RSA
        +		goto err;
        +		}
        +	ret=RSA_public_encrypt(key_len,key,ek,pubk->pkey.rsa,RSA_PKCS1_PADDING);
        +err:
        +#endif
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/p_lib.c b/vendor/openssl/openssl/crypto/evp/p_lib.c
        new file mode 100644
        index 000000000..e26ccd0d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_lib.c
        @@ -0,0 +1,469 @@
        +/* crypto/evp/p_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/err.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/asn1_mac.h>
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +#include "asn1_locl.h"
        +
        +static void EVP_PKEY_free_it(EVP_PKEY *x);
        +
        +int EVP_PKEY_bits(EVP_PKEY *pkey)
        +	{
        +	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
        +		return pkey->ameth->pkey_bits(pkey);
        +	return 0;
        +	}
        +
        +int EVP_PKEY_size(EVP_PKEY *pkey)
        +	{
        +	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
        +		return pkey->ameth->pkey_size(pkey);
        +	return 0;
        +	}
        +
        +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
        +	{
        +#ifndef OPENSSL_NO_DSA
        +	if (pkey->type == EVP_PKEY_DSA)
        +		{
        +		int ret=pkey->save_parameters;
        +
        +		if (mode >= 0)
        +			pkey->save_parameters=mode;
        +		return(ret);
        +		}
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	if (pkey->type == EVP_PKEY_EC)
        +		{
        +		int ret = pkey->save_parameters;
        +
        +		if (mode >= 0)
        +			pkey->save_parameters = mode;
        +		return(ret);
        +		}
        +#endif
        +	return(0);
        +	}
        +
        +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
        +	{
        +	if (to->type != from->type)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_missing_parameters(from))
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
        +		goto err;
        +		}
        +	if (from->ameth && from->ameth->param_copy)
        +		return from->ameth->param_copy(to, from);
        +err:
        +	return 0;
        +	}
        +
        +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
        +	{
        +	if (pkey->ameth && pkey->ameth->param_missing)
        +		return pkey->ameth->param_missing(pkey);
        +	return 0;
        +	}
        +
        +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (a->type != b->type)
        +		return -1;
        +	if (a->ameth && a->ameth->param_cmp)
        +		return a->ameth->param_cmp(a, b);
        +	return -2;
        +	}
        +
        +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (a->type != b->type)
        +		return -1;
        +
        +	if (a->ameth)
        +		{
        +		int ret;
        +		/* Compare parameters if the algorithm has them */
        +		if (a->ameth->param_cmp)
        +			{
        +			ret = a->ameth->param_cmp(a, b);
        +			if (ret <= 0)
        +				return ret;
        +			}
        +
        +		if (a->ameth->pub_cmp)
        +			return a->ameth->pub_cmp(a, b);
        +		}
        +
        +	return -2;
        +	}
        +
        +EVP_PKEY *EVP_PKEY_new(void)
        +	{
        +	EVP_PKEY *ret;
        +
        +	ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
        +	if (ret == NULL)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	ret->type=EVP_PKEY_NONE;
        +	ret->save_type=EVP_PKEY_NONE;
        +	ret->references=1;
        +	ret->ameth=NULL;
        +	ret->engine=NULL;
        +	ret->pkey.ptr=NULL;
        +	ret->attributes=NULL;
        +	ret->save_parameters=1;
        +	return(ret);
        +	}
        +
        +/* Setup a public key ASN1 method and ENGINE from a NID or a string.
        + * If pkey is NULL just return 1 or 0 if the algorithm exists.
        + */
        +
        +static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
        +	{
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	ENGINE *e = NULL;
        +	if (pkey)
        +		{
        +		if (pkey->pkey.ptr)
        +			EVP_PKEY_free_it(pkey);
        +		/* If key type matches and a method exists then this
        +		 * lookup has succeeded once so just indicate success.
        +		 */
        +		if ((type == pkey->save_type) && pkey->ameth)
        +			return 1;
        +#ifndef OPENSSL_NO_ENGINE
        +		/* If we have an ENGINE release it */
        +		if (pkey->engine)
        +			{
        +			ENGINE_finish(pkey->engine);
        +			pkey->engine = NULL;
        +			}
        +#endif
        +		}
        +	if (str)
        +		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
        +	else
        +		ameth = EVP_PKEY_asn1_find(&e, type);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (!pkey && e)
        +		ENGINE_finish(e);
        +#endif
        +	if (!ameth)
        +		{
        +		EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
        +		return 0;
        +		}
        +	if (pkey)
        +		{
        +		pkey->ameth = ameth;
        +		pkey->engine = e;
        +
        +		pkey->type = pkey->ameth->pkey_id;
        +		pkey->save_type=type;
        +		}
        +	return 1;
        +	}
        +
        +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
        +	{
        +	return pkey_set_type(pkey, type, NULL, -1);
        +	}
        +
        +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
        +	{
        +	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
        +	}
        +
        +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
        +	{
        +	if (!EVP_PKEY_set_type(pkey, type))
        +		return 0;
        +	pkey->pkey.ptr=key;
        +	return (key != NULL);
        +	}
        +
        +void *EVP_PKEY_get0(EVP_PKEY *pkey)
        +	{
        +	return pkey->pkey.ptr;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
        +{
        +	int ret = EVP_PKEY_assign_RSA(pkey, key);
        +	if(ret)
        +		RSA_up_ref(key);
        +	return ret;
        +}
        +
        +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
        +	{
        +	if(pkey->type != EVP_PKEY_RSA) {
        +		EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
        +		return NULL;
        +	}
        +	RSA_up_ref(pkey->pkey.rsa);
        +	return pkey->pkey.rsa;
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
        +{
        +	int ret = EVP_PKEY_assign_DSA(pkey, key);
        +	if(ret)
        +		DSA_up_ref(key);
        +	return ret;
        +}
        +
        +DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
        +	{
        +	if(pkey->type != EVP_PKEY_DSA) {
        +		EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
        +		return NULL;
        +	}
        +	DSA_up_ref(pkey->pkey.dsa);
        +	return pkey->pkey.dsa;
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +
        +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
        +{
        +	int ret = EVP_PKEY_assign_EC_KEY(pkey,key);
        +	if (ret)
        +		EC_KEY_up_ref(key);
        +	return ret;
        +}
        +
        +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
        +{
        +	if (pkey->type != EVP_PKEY_EC)
        +	{
        +		EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
        +		return NULL;
        +	}
        +	EC_KEY_up_ref(pkey->pkey.ec);
        +	return pkey->pkey.ec;
        +}
        +#endif
        +
        +
        +#ifndef OPENSSL_NO_DH
        +
        +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
        +{
        +	int ret = EVP_PKEY_assign_DH(pkey, key);
        +	if(ret)
        +		DH_up_ref(key);
        +	return ret;
        +}
        +
        +DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
        +	{
        +	if(pkey->type != EVP_PKEY_DH) {
        +		EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
        +		return NULL;
        +	}
        +	DH_up_ref(pkey->pkey.dh);
        +	return pkey->pkey.dh;
        +}
        +#endif
        +
        +int EVP_PKEY_type(int type)
        +	{
        +	int ret;
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	ENGINE *e;
        +	ameth = EVP_PKEY_asn1_find(&e, type);
        +	if (ameth)
        +		ret = ameth->pkey_id;
        +	else
        +		ret = NID_undef;
        +#ifndef OPENSSL_NO_ENGINE
        +	if (e)
        +		ENGINE_finish(e);
        +#endif
        +	return ret;
        +	}
        +
        +int EVP_PKEY_id(const EVP_PKEY *pkey)
        +	{
        +	return pkey->type;
        +	}
        +
        +int EVP_PKEY_base_id(const EVP_PKEY *pkey)
        +	{
        +	return EVP_PKEY_type(pkey->type);
        +	}
        +
        +void EVP_PKEY_free(EVP_PKEY *x)
        +	{
        +	int i;
        +
        +	if (x == NULL) return;
        +
        +	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",x);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"EVP_PKEY_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +	EVP_PKEY_free_it(x);
        +	if (x->attributes)
        +		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
        +	OPENSSL_free(x);
        +	}
        +
        +static void EVP_PKEY_free_it(EVP_PKEY *x)
        +	{
        +	if (x->ameth && x->ameth->pkey_free)
        +		{
        +		x->ameth->pkey_free(x);
        +		x->pkey.ptr = NULL;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	if (x->engine)
        +		{
        +		ENGINE_finish(x->engine);
        +		x->engine = NULL;
        +		}
        +#endif
        +	}
        +
        +static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
        +				const char *kstr)
        +	{
        +	BIO_indent(out, indent, 128);
        +	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
        +						kstr, OBJ_nid2ln(pkey->type));
        +	return 1;
        +	}
        +
        +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx)
        +	{
        +	if (pkey->ameth && pkey->ameth->pub_print)
        +		return pkey->ameth->pub_print(out, pkey, indent, pctx);
        +	
        +	return unsup_alg(out, pkey, indent, "Public Key");
        +	}
        +
        +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx)
        +	{
        +	if (pkey->ameth && pkey->ameth->priv_print)
        +		return pkey->ameth->priv_print(out, pkey, indent, pctx);
        +	
        +	return unsup_alg(out, pkey, indent, "Private Key");
        +	}
        +
        +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx)
        +	{
        +	if (pkey->ameth && pkey->ameth->param_print)
        +		return pkey->ameth->param_print(out, pkey, indent, pctx);
        +	return unsup_alg(out, pkey, indent, "Parameters");
        +	}
        +
        +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
        +	{
        +	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
        +		return -2;
        +	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
        +						0, pnid);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/p_open.c b/vendor/openssl/openssl/crypto/evp/p_open.c
        new file mode 100644
        index 000000000..c748fbea8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_open.c
        @@ -0,0 +1,128 @@
        +/* crypto/evp/p_open.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/rsa.h>
        +
        +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +	const unsigned char *ek, int ekl, const unsigned char *iv,
        +	EVP_PKEY *priv)
        +	{
        +	unsigned char *key=NULL;
        +	int i,size=0,ret=0;
        +
        +	if(type) {	
        +		EVP_CIPHER_CTX_init(ctx);
        +		if(!EVP_DecryptInit_ex(ctx,type,NULL, NULL,NULL)) return 0;
        +	}
        +
        +	if(!priv) return 1;
        +
        +	if (priv->type != EVP_PKEY_RSA)
        +		{
        +		EVPerr(EVP_F_EVP_OPENINIT,EVP_R_PUBLIC_KEY_NOT_RSA);
        +		goto err;
        +                }
        +
        +	size=RSA_size(priv->pkey.rsa);
        +	key=(unsigned char *)OPENSSL_malloc(size+2);
        +	if (key == NULL)
        +		{
        +		/* ERROR */
        +		EVPerr(EVP_F_EVP_OPENINIT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	i=EVP_PKEY_decrypt_old(key,ek,ekl,priv);
        +	if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i))
        +		{
        +		/* ERROR */
        +		goto err;
        +		}
        +	if(!EVP_DecryptInit_ex(ctx,NULL,NULL,key,iv)) goto err;
        +
        +	ret=1;
        +err:
        +	if (key != NULL) OPENSSL_cleanse(key,size);
        +	OPENSSL_free(key);
        +	return(ret);
        +	}
        +
        +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int i;
        +
        +	i=EVP_DecryptFinal_ex(ctx,out,outl);
        +	if (i)
        +		i = EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL);
        +	return(i);
        +	}
        +#else /* !OPENSSL_NO_RSA */
        +
        +# ifdef PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/evp/p_seal.c b/vendor/openssl/openssl/crypto/evp/p_seal.c
        new file mode 100644
        index 000000000..e5919b0fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_seal.c
        @@ -0,0 +1,116 @@
        +/* crypto/evp/p_seal.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
        +	     int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
        +	{
        +	unsigned char key[EVP_MAX_KEY_LENGTH];
        +	int i;
        +	
        +	if(type) {
        +		EVP_CIPHER_CTX_init(ctx);
        +		if(!EVP_EncryptInit_ex(ctx,type,NULL,NULL,NULL)) return 0;
        +	}
        +	if ((npubk <= 0) || !pubk)
        +		return 1;
        +	if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
        +		return 0;
        +	if (EVP_CIPHER_CTX_iv_length(ctx))
        +		RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx));
        +
        +	if(!EVP_EncryptInit_ex(ctx,NULL,NULL,key,iv)) return 0;
        +
        +	for (i=0; i<npubk; i++)
        +		{
        +		ekl[i]=EVP_PKEY_encrypt_old(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
        +			pubk[i]);
        +		if (ekl[i] <= 0) return(-1);
        +		}
        +	return(npubk);
        +	}
        +
        +/* MACRO
        +void EVP_SealUpdate(ctx,out,outl,in,inl)
        +EVP_CIPHER_CTX *ctx;
        +unsigned char *out;
        +int *outl;
        +unsigned char *in;
        +int inl;
        +	{
        +	EVP_EncryptUpdate(ctx,out,outl,in,inl);
        +	}
        +*/
        +
        +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        +	{
        +	int i;
        +	i = EVP_EncryptFinal_ex(ctx,out,outl);
        +	if (i) 
        +		i = EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL);
        +	return i;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/p_sign.c b/vendor/openssl/openssl/crypto/evp/p_sign.c
        new file mode 100644
        index 000000000..8afb66430
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_sign.c
        @@ -0,0 +1,139 @@
        +/* crypto/evp/p_sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +#ifdef undef
        +void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
        +	{
        +	EVP_DigestInit_ex(ctx,type);
        +	}
        +
        +void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
        +	     unsigned int count)
        +	{
        +	EVP_DigestUpdate(ctx,data,count);
        +	}
        +#endif
        +
        +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
        +	     EVP_PKEY *pkey)
        +	{
        +	unsigned char m[EVP_MAX_MD_SIZE];
        +	unsigned int m_len;
        +	int i = 0,ok = 0,v;
        +	EVP_MD_CTX tmp_ctx;
        +	EVP_PKEY_CTX *pkctx = NULL;
        +
        +	*siglen=0;
        +	EVP_MD_CTX_init(&tmp_ctx);
        +	if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
        +		goto err;  
        +	if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
        +		goto err;
        +	EVP_MD_CTX_cleanup(&tmp_ctx);
        +
        +	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
        +		{
        +		size_t sltmp = (size_t)EVP_PKEY_size(pkey);
        +		i = 0;
        +		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
        +		if (!pkctx)
        +			goto err;
        +		if (EVP_PKEY_sign_init(pkctx) <= 0)
        +			goto err;
        +		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
        +			goto err;
        +		if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
        +			goto err;
        +		*siglen = sltmp;
        +		i = 1;
        +		err:
        +		EVP_PKEY_CTX_free(pkctx);
        +		return i;
        +		}
        +
        +	for (i=0; i<4; i++)
        +		{
        +		v=ctx->digest->required_pkey_type[i];
        +		if (v == 0) break;
        +		if (pkey->type == v)
        +			{
        +			ok=1;
        +			break;
        +			}
        +		}
        +	if (!ok)
        +		{
        +		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
        +		return(0);
        +		}
        +
        +	if (ctx->digest->sign == NULL)
        +		{
        +		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
        +		return(0);
        +		}
        +	return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
        +		pkey->pkey.ptr));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/p_verify.c b/vendor/openssl/openssl/crypto/evp/p_verify.c
        new file mode 100644
        index 000000000..c66d63ccf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/p_verify.c
        @@ -0,0 +1,121 @@
        +/* crypto/evp/p_verify.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
        +	     unsigned int siglen, EVP_PKEY *pkey)
        +	{
        +	unsigned char m[EVP_MAX_MD_SIZE];
        +	unsigned int m_len;
        +	int i = 0,ok = 0,v;
        +	EVP_MD_CTX tmp_ctx;
        +	EVP_PKEY_CTX *pkctx = NULL;
        +
        +	EVP_MD_CTX_init(&tmp_ctx);
        +	if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
        +		goto err;    
        +	if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
        +		goto err;
        +	EVP_MD_CTX_cleanup(&tmp_ctx);
        +
        +	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
        +		{
        +		i = -1;
        +		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
        +		if (!pkctx)
        +			goto err;
        +		if (EVP_PKEY_verify_init(pkctx) <= 0)
        +			goto err;
        +		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
        +			goto err;
        +		i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
        +		err:
        +		EVP_PKEY_CTX_free(pkctx);
        +		return i;
        +		}
        +
        +	for (i=0; i<4; i++)
        +		{
        +		v=ctx->digest->required_pkey_type[i];
        +		if (v == 0) break;
        +		if (pkey->type == v)
        +			{
        +			ok=1;
        +			break;
        +			}
        +		}
        +	if (!ok)
        +		{
        +		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
        +		return(-1);
        +		}
        +        if (ctx->digest->verify == NULL)
        +                {
        +		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
        +		return(0);
        +		}
        +
        +	return(ctx->digest->verify(ctx->digest->type,m,m_len,
        +		sigbuf,siglen,pkey->pkey.ptr));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/pmeth_fn.c b/vendor/openssl/openssl/crypto/evp/pmeth_fn.c
        new file mode 100644
        index 000000000..c4676f2f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/pmeth_fn.c
        @@ -0,0 +1,368 @@
        +/* pmeth_fn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include "evp_locl.h"
        +
        +#define M_check_autoarg(ctx, arg, arglen, err) \
        +	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
        +		{ \
        +		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
        +		if (!arg) \
        +			{ \
        +			*arglen = pksize; \
        +			return 1; \
        +			} \
        +		else if (*arglen < pksize) \
        +			{ \
        +			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
        +			return 0; \
        +			} \
        +		}
        +
        +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_SIGN;
        +	if (!ctx->pmeth->sign_init)
        +		return 1;
        +	ret = ctx->pmeth->sign_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
        +			unsigned char *sig, size_t *siglen,
        +			const unsigned char *tbs, size_t tbslen)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_SIGN,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_SIGN)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
        +	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
        +	}
        +
        +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_VERIFY;
        +	if (!ctx->pmeth->verify_init)
        +		return 1;
        +	ret = ctx->pmeth->verify_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
        +			const unsigned char *sig, size_t siglen,
        +			const unsigned char *tbs, size_t tbslen)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_VERIFY,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_VERIFY)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
        +	}
        +
        +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
        +	if (!ctx->pmeth->verify_recover_init)
        +		return 1;
        +	ret = ctx->pmeth->verify_recover_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
        +			unsigned char *rout, size_t *routlen,
        +			const unsigned char *sig, size_t siglen)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
        +	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
        +	}
        +
        +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_ENCRYPT;
        +	if (!ctx->pmeth->encrypt_init)
        +		return 1;
        +	ret = ctx->pmeth->encrypt_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
        +			unsigned char *out, size_t *outlen,
        +			const unsigned char *in, size_t inlen)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
        +	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
        +	}
        +
        +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_DECRYPT;
        +	if (!ctx->pmeth->decrypt_init)
        +		return 1;
        +	ret = ctx->pmeth->decrypt_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
        +			unsigned char *out, size_t *outlen,
        +			const unsigned char *in, size_t inlen)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_DECRYPT)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
        +	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
        +	}
        +
        +
        +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_DERIVE;
        +	if (!ctx->pmeth->derive_init)
        +		return 1;
        +	ret = ctx->pmeth->derive_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
        +					EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +
        +	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
        +
        +	if (ret <= 0)
        +		return ret;
        +
        +	if (ret == 2)
        +		return 1;
        +
        +	if (!ctx->pkey)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
        +		return -1;
        +		}
        +
        +	if (ctx->pkey->type != peer->type)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
        +						EVP_R_DIFFERENT_KEY_TYPES);
        +		return -1;
        +		}
        +
        +	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
        +	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
        +	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
        +	 * (different key types) is impossible here because it is checked earlier.
        +	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
        +	if (!EVP_PKEY_missing_parameters(peer) &&
        +		!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
        +						EVP_R_DIFFERENT_PARAMETERS);
        +		return -1;
        +		}
        +
        +	if (ctx->peerkey)
        +		EVP_PKEY_free(ctx->peerkey);
        +	ctx->peerkey = peer;
        +
        +	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
        +
        +	if (ret <= 0)
        +		{
        +		ctx->peerkey = NULL;
        +		return ret;
        +		}
        +
        +	CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
        +	return 1;
        +	}
        +
        +
        +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_DERIVE)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
        +	return ctx->pmeth->derive(ctx, key, pkeylen);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/evp/pmeth_gn.c b/vendor/openssl/openssl/crypto/evp/pmeth_gn.c
        new file mode 100644
        index 000000000..4651c8137
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/pmeth_gn.c
        @@ -0,0 +1,221 @@
        +/* pmeth_gn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include "evp_locl.h"
        +
        +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_PARAMGEN;
        +	if (!ctx->pmeth->paramgen_init)
        +		return 1;
        +	ret = ctx->pmeth->paramgen_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +
        +	if (ctx->operation != EVP_PKEY_OP_PARAMGEN)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +
        +	if (!ppkey)
        +		return -1;
        +
        +	if (!*ppkey)
        +		*ppkey = EVP_PKEY_new();
        +
        +	ret = ctx->pmeth->paramgen(ctx, *ppkey);
        +	if (ret <= 0)
        +		{
        +		EVP_PKEY_free(*ppkey);
        +		*ppkey = NULL;
        +		}
        +	return ret;
        +	}
        +
        +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	ctx->operation = EVP_PKEY_OP_KEYGEN;
        +	if (!ctx->pmeth->keygen_init)
        +		return 1;
        +	ret = ctx->pmeth->keygen_init(ctx);
        +	if (ret <= 0)
        +		ctx->operation = EVP_PKEY_OP_UNDEFINED;
        +	return ret;
        +	}
        +
        +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
        +	{
        +	int ret;
        +
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_KEYGEN,
        +			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +		return -2;
        +		}
        +	if (ctx->operation != EVP_PKEY_OP_KEYGEN)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
        +		return -1;
        +		}
        +
        +	if (!ppkey)
        +		return -1;
        +
        +	if (!*ppkey)
        +		*ppkey = EVP_PKEY_new();
        +
        +	ret = ctx->pmeth->keygen(ctx, *ppkey);
        +	if (ret <= 0)
        +		{
        +		EVP_PKEY_free(*ppkey);
        +		*ppkey = NULL;
        +		}
        +	return ret;
        +	}
        +
        +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
        +	{
        +	ctx->pkey_gencb = cb;
        +	}
        +
        +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
        +	{
        +	return ctx->pkey_gencb;
        +	}
        +
        +/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
        + * style callbacks.
        + */
        +
        +static int trans_cb(int a, int b, BN_GENCB *gcb)
        +	{
        +	EVP_PKEY_CTX *ctx = gcb->arg;
        +	ctx->keygen_info[0] = a;
        +	ctx->keygen_info[1] = b;
        +	return ctx->pkey_gencb(ctx);
        +	}	
        +
        +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
        +	{
        +	BN_GENCB_set(cb, trans_cb, ctx)
        +	}
        +
        +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
        +	{
        +	if (idx == -1)
        +		return ctx->keygen_info_count; 
        +	if (idx < 0 || idx > ctx->keygen_info_count)
        +		return 0;
        +	return ctx->keygen_info[idx];
        +	}
        +
        +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
        +				const unsigned char *key, int keylen)
        +	{
        +	EVP_PKEY_CTX *mac_ctx = NULL;
        +	EVP_PKEY *mac_key = NULL;
        +	mac_ctx = EVP_PKEY_CTX_new_id(type, e);
        +	if (!mac_ctx)
        +		return NULL;
        +	if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
        +		goto merr;
        +	if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
        +				EVP_PKEY_CTRL_SET_MAC_KEY,
        +				keylen, (void *)key) <= 0)
        +		goto merr;
        +	if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
        +		goto merr;
        +	merr:
        +	if (mac_ctx)
        +		EVP_PKEY_CTX_free(mac_ctx);
        +	return mac_key;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/evp/pmeth_lib.c b/vendor/openssl/openssl/crypto/evp/pmeth_lib.c
        new file mode 100644
        index 000000000..acfa7b6f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/evp/pmeth_lib.c
        @@ -0,0 +1,593 @@
        +/* pmeth_lib.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <stdlib.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include "asn1_locl.h"
        +#include "evp_locl.h"
        +
        +typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
        +
        +DECLARE_STACK_OF(EVP_PKEY_METHOD)
        +STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
        +
        +extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
        +extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
        +
        +static const EVP_PKEY_METHOD *standard_methods[] =
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	&rsa_pkey_meth,
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	&dh_pkey_meth,
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	&dsa_pkey_meth,
        +#endif
        +#ifndef OPENSSL_NO_EC
        +	&ec_pkey_meth,
        +#endif
        +	&hmac_pkey_meth,
        +	&cmac_pkey_meth
        +	};
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
        +			   pmeth);
        +
        +static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
        +		     const EVP_PKEY_METHOD * const *b)
        +	{
        +        return ((*a)->pkey_id - (*b)->pkey_id);
        +	}
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
        +			     pmeth);
        +
        +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
        +	{
        +	EVP_PKEY_METHOD tmp;
        +	const EVP_PKEY_METHOD *t = &tmp, **ret;
        +	tmp.pkey_id = type;
        +	if (app_pkey_methods)
        +		{
        +		int idx;
        +		idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
        +		if (idx >= 0)
        +			return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
        +		}
        +	ret = OBJ_bsearch_pmeth(&t, standard_methods,
        +			  sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
        +	if (!ret || !*ret)
        +		return NULL;
        +	return *ret;
        +	}
        +
        +static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
        +	{
        +	EVP_PKEY_CTX *ret;
        +	const EVP_PKEY_METHOD *pmeth;
        +	if (id == -1)
        +		{
        +		if (!pkey || !pkey->ameth)
        +			return NULL;
        +		id = pkey->ameth->pkey_id;
        +		}
        +#ifndef OPENSSL_NO_ENGINE
        +	if (pkey && pkey->engine)
        +		e = pkey->engine;
        +	/* Try to find an ENGINE which implements this method */
        +	if (e)
        +		{
        +		if (!ENGINE_init(e))
        +			{
        +			EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB);
        +			return NULL;
        +			}
        +		}
        +	else
        +		e = ENGINE_get_pkey_meth_engine(id);
        +
        +	/* If an ENGINE handled this method look it up. Othewise
        +	 * use internal tables.
        +	 */
        +
        +	if (e)
        +		pmeth = ENGINE_get_pkey_meth(e, id);
        +	else
        +#endif
        +		pmeth = EVP_PKEY_meth_find(id);
        +
        +	if (pmeth == NULL)
        +		{
        +		EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
        +		return NULL;
        +		}
        +
        +	ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
        +	if (!ret)
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		if (e)
        +			ENGINE_finish(e);
        +#endif
        +		EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	ret->engine = e;
        +	ret->pmeth = pmeth;
        +	ret->operation = EVP_PKEY_OP_UNDEFINED;
        +	ret->pkey = pkey;
        +	ret->peerkey = NULL;
        +	ret->pkey_gencb = 0;
        +	if (pkey)
        +		CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        +	ret->data = NULL;
        +
        +	if (pmeth->init)
        +		{
        +		if (pmeth->init(ret) <= 0)
        +			{
        +			EVP_PKEY_CTX_free(ret);
        +			return NULL;
        +			}
        +		}
        +
        +	return ret;
        +	}
        +
        +EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
        +	{
        +	EVP_PKEY_METHOD *pmeth;
        +	pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
        +	if (!pmeth)
        +		return NULL;
        +
        +	memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));
        +
        +	pmeth->pkey_id = id;
        +	pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
        +
        +	pmeth->init = 0;
        +	pmeth->copy = 0;
        +	pmeth->cleanup = 0;
        +	pmeth->paramgen_init = 0;
        +	pmeth->paramgen = 0;
        +	pmeth->keygen_init = 0;
        +	pmeth->keygen = 0;
        +	pmeth->sign_init = 0;
        +	pmeth->sign = 0;
        +	pmeth->verify_init = 0;
        +	pmeth->verify = 0;
        +	pmeth->verify_recover_init = 0;
        +	pmeth->verify_recover = 0;
        +	pmeth->signctx_init = 0;
        +	pmeth->signctx = 0;
        +	pmeth->verifyctx_init = 0;
        +	pmeth->verifyctx = 0;
        +	pmeth->encrypt_init = 0;
        +	pmeth->encrypt = 0;
        +	pmeth->decrypt_init = 0;
        +	pmeth->decrypt = 0;
        +	pmeth->derive_init = 0;
        +	pmeth->derive = 0;
        +	pmeth->ctrl = 0;
        +	pmeth->ctrl_str = 0;
        +
        +	return pmeth;
        +	}
        +
        +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
        +				const EVP_PKEY_METHOD *meth)
        +	{
        +	if (ppkey_id)
        +		*ppkey_id = meth->pkey_id;
        +	if (pflags)
        +		*pflags = meth->flags;
        +	}
        +
        +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
        +	{
        +
        +	dst->init = src->init;
        +	dst->copy = src->copy;
        +	dst->cleanup = src->cleanup;
        +
        +	dst->paramgen_init = src->paramgen_init;
        +	dst->paramgen = src->paramgen;
        +
        +	dst->keygen_init = src->keygen_init;
        +	dst->keygen = src->keygen;
        +
        +	dst->sign_init = src->sign_init;
        +	dst->sign = src->sign;
        +
        +	dst->verify_init = src->verify_init;
        +	dst->verify = src->verify;
        +
        +	dst->verify_recover_init = src->verify_recover_init;
        +	dst->verify_recover = src->verify_recover;
        +
        +	dst->signctx_init = src->signctx_init;
        +	dst->signctx = src->signctx;
        +
        +	dst->verifyctx_init = src->verifyctx_init;
        +	dst->verifyctx = src->verifyctx;
        +
        +	dst->encrypt_init = src->encrypt_init;
        +	dst->encrypt = src->encrypt;
        +
        +	dst->decrypt_init = src->decrypt_init;
        +	dst->decrypt = src->decrypt;
        +
        +	dst->derive_init = src->derive_init;
        +	dst->derive = src->derive;
        +
        +	dst->ctrl = src->ctrl;
        +	dst->ctrl_str = src->ctrl_str;
        +	}
        +
        +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
        +	{
        +	if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
        +		OPENSSL_free(pmeth);
        +	}
        +
        +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
        +	{
        +	return int_ctx_new(pkey, e, -1);
        +	}
        +
        +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
        +	{
        +	return int_ctx_new(NULL, e, id);
        +	}
        +
        +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
        +	{
        +	EVP_PKEY_CTX *rctx;
        +	if (!pctx->pmeth || !pctx->pmeth->copy)
        +		return NULL;
        +#ifndef OPENSSL_NO_ENGINE
        +	/* Make sure it's safe to copy a pkey context using an ENGINE */
        +	if (pctx->engine && !ENGINE_init(pctx->engine))
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB);
        +		return 0;
        +		}
        +#endif
        +	rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
        +	if (!rctx)
        +		return NULL;
        +
        +	rctx->pmeth = pctx->pmeth;
        +#ifndef OPENSSL_NO_ENGINE
        +	rctx->engine = pctx->engine;
        +#endif
        +
        +	if (pctx->pkey)
        +		CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        +
        +	rctx->pkey = pctx->pkey;
        +
        +	if (pctx->peerkey)
        +		CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        +
        +	rctx->peerkey = pctx->peerkey;
        +
        +	rctx->data = NULL;
        +	rctx->app_data = NULL;
        +	rctx->operation = pctx->operation;
        +
        +	if (pctx->pmeth->copy(rctx, pctx) > 0)
        +		return rctx;
        +
        +	EVP_PKEY_CTX_free(rctx);
        +	return NULL;
        +
        +	}
        +
        +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
        +	{
        +	if (app_pkey_methods == NULL)
        +		{
        +		app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
        +		if (!app_pkey_methods)
        +			return 0;
        +		}
        +	if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
        +		return 0;
        +	sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
        +	return 1;
        +	}
        +
        +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
        +	{
        +	if (ctx == NULL)
        +		return;
        +	if (ctx->pmeth && ctx->pmeth->cleanup)
        +		ctx->pmeth->cleanup(ctx);
        +	if (ctx->pkey)
        +		EVP_PKEY_free(ctx->pkey);
        +	if (ctx->peerkey)
        +		EVP_PKEY_free(ctx->peerkey);
        +#ifndef OPENSSL_NO_ENGINE
        +	if(ctx->engine)
        +		/* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
        +		 * functional reference we held for this reason. */
        +		ENGINE_finish(ctx->engine);
        +#endif
        +	OPENSSL_free(ctx);
        +	}
        +
        +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
        +				int cmd, int p1, void *p2)
        +	{
        +	int ret;
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
        +		return -2;
        +		}
        +	if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
        +		return -1;
        +
        +	if (ctx->operation == EVP_PKEY_OP_UNDEFINED)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
        +		return -1;
        +		}
        +
        +	if ((optype != -1) && !(ctx->operation & optype))
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
        +		return -1;
        +		}
        +
        +	ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
        +
        +	if (ret == -2)
        +		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
        +
        +	return ret;
        +
        +	}
        +
        +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
        +					const char *name, const char *value)
        +	{
        +	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str)
        +		{
        +		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
        +						EVP_R_COMMAND_NOT_SUPPORTED);
        +		return -2;
        +		}
        +	if (!strcmp(name, "digest"))
        +		{
        +		const EVP_MD *md;
        +		if (!value || !(md = EVP_get_digestbyname(value)))
        +			{
        +			EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
        +						EVP_R_INVALID_DIGEST);
        +			return 0;
        +			}
        +		return EVP_PKEY_CTX_set_signature_md(ctx, md);
        +		}
        +	return ctx->pmeth->ctrl_str(ctx, name, value);
        +	}
        +
        +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
        +	{
        +	return ctx->operation;
        +	}
        +
        +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
        +	{
        +	ctx->keygen_info = dat;
        +	ctx->keygen_info_count = datlen;
        +	}
        +
        +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
        +	{
        +	ctx->data = data;
        +	}
        +
        +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
        +	{
        +	return ctx->data;
        +	}
        +
        +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
        +	{
        +	return ctx->pkey;
        +	}
        +
        +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
        +	{
        +	return ctx->peerkey;
        +	}
        +	
        +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
        +	{
        +	ctx->app_data = data;
        +	}
        +
        +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
        +	{
        +	return ctx->app_data;
        +	}
        +
        +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
        +	int (*init)(EVP_PKEY_CTX *ctx))
        +	{
        +	pmeth->init = init;
        +	}
        +
        +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
        +	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
        +	{
        +	pmeth->copy = copy;
        +	}
        +
        +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
        +	void (*cleanup)(EVP_PKEY_CTX *ctx))
        +	{
        +	pmeth->cleanup = cleanup;
        +	}
        +
        +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
        +	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
        +	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
        +	{
        +	pmeth->paramgen_init = paramgen_init;
        +	pmeth->paramgen = paramgen;
        +	}
        +
        +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
        +	int (*keygen_init)(EVP_PKEY_CTX *ctx),
        +	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
        +	{
        +	pmeth->keygen_init = keygen_init;
        +	pmeth->keygen = keygen;
        +	}
        +
        +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
        +	int (*sign_init)(EVP_PKEY_CTX *ctx),
        +	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen))
        +	{
        +	pmeth->sign_init = sign_init;
        +	pmeth->sign = sign;
        +	}
        +
        +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
        +	int (*verify_init)(EVP_PKEY_CTX *ctx),
        +	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
        +					const unsigned char *tbs, size_t tbslen))
        +	{
        +	pmeth->verify_init = verify_init;
        +	pmeth->verify = verify;
        +	}
        +
        +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
        +	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
        +	int (*verify_recover)(EVP_PKEY_CTX *ctx,
        +					unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen))
        +	{
        +	pmeth->verify_recover_init = verify_recover_init;
        +	pmeth->verify_recover = verify_recover;
        +	}
        +
        +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
        +	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
        +	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					EVP_MD_CTX *mctx))
        +	{
        +	pmeth->signctx_init = signctx_init;
        +	pmeth->signctx = signctx;
        +	}
        +
        +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
        +	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
        +	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
        +					EVP_MD_CTX *mctx))
        +	{
        +	pmeth->verifyctx_init = verifyctx_init;
        +	pmeth->verifyctx = verifyctx;
        +	}
        +
        +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
        +	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
        +	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen))
        +	{
        +	pmeth->encrypt_init = encrypt_init;
        +	pmeth->encrypt = encryptfn;
        +	}
        +
        +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
        +	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
        +	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen))
        +	{
        +	pmeth->decrypt_init = decrypt_init;
        +	pmeth->decrypt = decrypt;
        +	}
        +
        +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
        +	int (*derive_init)(EVP_PKEY_CTX *ctx),
        +	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
        +	{
        +	pmeth->derive_init = derive_init;
        +	pmeth->derive = derive;
        +	}
        +
        +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
        +	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
        +	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
        +	{
        +	pmeth->ctrl = ctrl;
        +	pmeth->ctrl_str = ctrl_str;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ex_data.c b/vendor/openssl/openssl/crypto/ex_data.c
        new file mode 100644
        index 000000000..e2bc8298d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ex_data.c
        @@ -0,0 +1,636 @@
        +/* crypto/ex_data.c */
        +
        +/*
        + * Overhaul notes;
        + *
        + * This code is now *mostly* thread-safe. It is now easier to understand in what
        + * ways it is safe and in what ways it is not, which is an improvement. Firstly,
        + * all per-class stacks and index-counters for ex_data are stored in the same
        + * global LHASH table (keyed by class). This hash table uses locking for all
        + * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be
        + * called when no other threads can possibly race against it (even if it was
        + * locked, the race would mean it's possible the hash table might have been
        + * recreated after the cleanup). As classes can only be added to the hash table,
        + * and within each class, the stack of methods can only be incremented, the
        + * locking mechanics are simpler than they would otherwise be. For example, the
        + * new/dup/free ex_data functions will lock the hash table, copy the method
        + * pointers it needs from the relevant class, then unlock the hash table before
        + * actually applying those method pointers to the task of the new/dup/free
        + * operations. As they can't be removed from the method-stack, only
        + * supplemented, there's no race conditions associated with using them outside
        + * the lock. The get/set_ex_data functions are not locked because they do not
        + * involve this global state at all - they operate directly with a previously
        + * obtained per-class method index and a particular "ex_data" variable. These
        + * variables are usually instantiated per-context (eg. each RSA structure has
        + * one) so locking on read/write access to that variable can be locked locally
        + * if required (eg. using the "RSA" lock to synchronise access to a
        + * per-RSA-structure ex_data variable if required).
        + * [Geoff]
        + */
        +
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +
        +/* What an "implementation of ex_data functionality" looks like */
        +struct st_CRYPTO_EX_DATA_IMPL
        +	{
        +	/*********************/
        +	/* GLOBAL OPERATIONS */
        +	/* Return a new class index */
        +	int (*cb_new_class)(void);
        +	/* Cleanup all state used by the implementation */
        +	void (*cb_cleanup)(void);
        +	/************************/
        +	/* PER-CLASS OPERATIONS */
        +	/* Get a new method index within a class */
        +	int (*cb_get_new_index)(int class_index, long argl, void *argp,
        +			CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
        +			CRYPTO_EX_free *free_func);
        +	/* Initialise a new CRYPTO_EX_DATA of a given class */
        +	int (*cb_new_ex_data)(int class_index, void *obj,
        +			CRYPTO_EX_DATA *ad);
        +	/* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
        +	int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to,
        +			CRYPTO_EX_DATA *from);
        +	/* Cleanup a CRYPTO_EX_DATA of a given class */
        +	void (*cb_free_ex_data)(int class_index, void *obj,
        +			CRYPTO_EX_DATA *ad);
        +	};
        +
        +/* The implementation we use at run-time */
        +static const CRYPTO_EX_DATA_IMPL *impl = NULL;
        +
        +/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg.
        + * EX_IMPL(get_new_index)(...); */
        +#define EX_IMPL(a) impl->cb_##a
        +
        +/* Predeclare the "default" ex_data implementation */
        +static int int_new_class(void);
        +static void int_cleanup(void);
        +static int int_get_new_index(int class_index, long argl, void *argp,
        +		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func);
        +static int int_new_ex_data(int class_index, void *obj,
        +		CRYPTO_EX_DATA *ad);
        +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
        +		CRYPTO_EX_DATA *from);
        +static void int_free_ex_data(int class_index, void *obj,
        +		CRYPTO_EX_DATA *ad);
        +static CRYPTO_EX_DATA_IMPL impl_default =
        +	{
        +	int_new_class,
        +	int_cleanup,
        +	int_get_new_index,
        +	int_new_ex_data,
        +	int_dup_ex_data,
        +	int_free_ex_data
        +	};
        +
        +/* Internal function that checks whether "impl" is set and if not, sets it to
        + * the default. */
        +static void impl_check(void)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
        +	if(!impl)
        +		impl = &impl_default;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        +	}
        +/* A macro wrapper for impl_check that first uses a non-locked test before
        + * invoking the function (which checks again inside a lock). */
        +#define IMPL_CHECK if(!impl) impl_check();
        +
        +/* API functions to get/set the "ex_data" implementation */
        +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void)
        +	{
        +	IMPL_CHECK
        +	return impl;
        +	}
        +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
        +	{
        +	int toret = 0;
        +	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
        +	if(!impl)
        +		{
        +		impl = i;
        +		toret = 1;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        +	return toret;
        +	}
        +
        +/****************************************************************************/
        +/* Interal (default) implementation of "ex_data" support. API functions are
        + * further down. */
        +
        +/* The type that represents what each "class" used to implement locally. A STACK
        + * of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is the global
        + * value representing the class that is used to distinguish these items. */
        +typedef struct st_ex_class_item {
        +	int class_index;
        +	STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
        +	int meth_num;
        +} EX_CLASS_ITEM;
        +
        +/* When assigning new class indexes, this is our counter */
        +static int ex_class = CRYPTO_EX_INDEX_USER;
        +
        +/* The global hash table of EX_CLASS_ITEM items */
        +DECLARE_LHASH_OF(EX_CLASS_ITEM);
        +static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
        +
        +/* The callbacks required in the "ex_data" hash table */
        +static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a)
        +	{
        +	return a->class_index;
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
        +
        +static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
        +	{
        +	return a->class_index - b->class_index;
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
        +
        +/* Internal functions used by the "impl_default" implementation to access the
        + * state */
        +
        +static int ex_data_check(void)
        +	{
        +	int toret = 1;
        +	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
        +	if(!ex_data
        +	   && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
        +		toret = 0;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        +	return toret;
        +	}
        +/* This macros helps reduce the locking from repeated checks because the
        + * ex_data_check() function checks ex_data again inside a lock. */
        +#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
        +
        +/* This "inner" callback is used by the callback function that follows it */
        +static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
        +	{
        +	OPENSSL_free(funcs);
        +	}
        +
        +/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
        + * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do
        + * any locking. */
        +static void def_cleanup_cb(void *a_void)
        +	{
        +	EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
        +	sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
        +	OPENSSL_free(item);
        +	}
        +
        +/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a
        + * given class. Handles locking. */
        +static EX_CLASS_ITEM *def_get_class(int class_index)
        +	{
        +	EX_CLASS_ITEM d, *p, *gen;
        +	EX_DATA_CHECK(return NULL;)
        +	d.class_index = class_index;
        +	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
        +	p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
        +	if(!p)
        +		{
        +		gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
        +		if(gen)
        +			{
        +			gen->class_index = class_index;
        +			gen->meth_num = 0;
        +			gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
        +			if(!gen->meth)
        +				OPENSSL_free(gen);
        +			else
        +				{
        +				/* Because we're inside the ex_data lock, the
        +				 * return value from the insert will be NULL */
        +				(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
        +				p = gen;
        +				}
        +			}
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        +	if(!p)
        +		CRYPTOerr(CRYPTO_F_DEF_GET_CLASS,ERR_R_MALLOC_FAILURE);
        +	return p;
        +	}
        +
        +/* Add a new method to the given EX_CLASS_ITEM and return the corresponding
        + * index (or -1 for error). Handles locking. */
        +static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
        +		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func)
        +	{
        +	int toret = -1;
        +	CRYPTO_EX_DATA_FUNCS *a = (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(
        +					sizeof(CRYPTO_EX_DATA_FUNCS));
        +	if(!a)
        +		{
        +		CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
        +		return -1;
        +		}
        +	a->argl=argl;
        +	a->argp=argp;
        +	a->new_func=new_func;
        +	a->dup_func=dup_func;
        +	a->free_func=free_func;
        +	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
        +	while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num)
        +		{
        +		if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL))
        +			{
        +			CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
        +			OPENSSL_free(a);
        +			goto err;
        +			}
        +		}
        +	toret = item->meth_num++;
        +	(void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
        +err:
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        +	return toret;
        +	}
        +
        +/**************************************************************/
        +/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
        +
        +static int int_new_class(void)
        +	{
        +	int toret;
        +	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
        +	toret = ex_class++;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        +	return toret;
        +	}
        +
        +static void int_cleanup(void)
        +	{
        +	EX_DATA_CHECK(return;)
        +	lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
        +	lh_EX_CLASS_ITEM_free(ex_data);
        +	ex_data = NULL;
        +	impl = NULL;
        +	}
        +
        +static int int_get_new_index(int class_index, long argl, void *argp,
        +		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func)
        +	{
        +	EX_CLASS_ITEM *item = def_get_class(class_index);
        +	if(!item)
        +		return -1;
        +	return def_add_index(item, argl, argp, new_func, dup_func, free_func);
        +	}
        +
        +/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in
        + * the lock, then using them outside the lock. NB: Thread-safety only applies to
        + * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad'
        + * itself. */
        +static int int_new_ex_data(int class_index, void *obj,
        +		CRYPTO_EX_DATA *ad)
        +	{
        +	int mx,i;
        +	void *ptr;
        +	CRYPTO_EX_DATA_FUNCS **storage = NULL;
        +	EX_CLASS_ITEM *item = def_get_class(class_index);
        +	if(!item)
        +		/* error is already set */
        +		return 0;
        +	ad->sk = NULL;
        +	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
        +	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
        +	if(mx > 0)
        +		{
        +		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
        +		if(!storage)
        +			goto skip;
        +		for(i = 0; i < mx; i++)
        +			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
        +		}
        +skip:
        +	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
        +	if((mx > 0) && !storage)
        +		{
        +		CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	for(i = 0; i < mx; i++)
        +		{
        +		if(storage[i] && storage[i]->new_func)
        +			{
        +			ptr = CRYPTO_get_ex_data(ad, i);
        +			storage[i]->new_func(obj,ptr,ad,i,
        +				storage[i]->argl,storage[i]->argp);
        +			}
        +		}
        +	if(storage)
        +		OPENSSL_free(storage);
        +	return 1;
        +	}
        +
        +/* Same thread-safety notes as for "int_new_ex_data" */
        +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
        +		CRYPTO_EX_DATA *from)
        +	{
        +	int mx, j, i;
        +	char *ptr;
        +	CRYPTO_EX_DATA_FUNCS **storage = NULL;
        +	EX_CLASS_ITEM *item;
        +	if(!from->sk)
        +		/* 'to' should be "blank" which *is* just like 'from' */
        +		return 1;
        +	if((item = def_get_class(class_index)) == NULL)
        +		return 0;
        +	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
        +	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
        +	j = sk_void_num(from->sk);
        +	if(j < mx)
        +		mx = j;
        +	if(mx > 0)
        +		{
        +		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
        +		if(!storage)
        +			goto skip;
        +		for(i = 0; i < mx; i++)
        +			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
        +		}
        +skip:
        +	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
        +	if((mx > 0) && !storage)
        +		{
        +		CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	for(i = 0; i < mx; i++)
        +		{
        +		ptr = CRYPTO_get_ex_data(from, i);
        +		if(storage[i] && storage[i]->dup_func)
        +			storage[i]->dup_func(to,from,&ptr,i,
        +				storage[i]->argl,storage[i]->argp);
        +		CRYPTO_set_ex_data(to,i,ptr);
        +		}
        +	if(storage)
        +		OPENSSL_free(storage);
        +	return 1;
        +	}
        +
        +/* Same thread-safety notes as for "int_new_ex_data" */
        +static void int_free_ex_data(int class_index, void *obj,
        +		CRYPTO_EX_DATA *ad)
        +	{
        +	int mx,i;
        +	EX_CLASS_ITEM *item;
        +	void *ptr;
        +	CRYPTO_EX_DATA_FUNCS **storage = NULL;
        +	if((item = def_get_class(class_index)) == NULL)
        +		return;
        +	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
        +	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
        +	if(mx > 0)
        +		{
        +		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
        +		if(!storage)
        +			goto skip;
        +		for(i = 0; i < mx; i++)
        +			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
        +		}
        +skip:
        +	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
        +	if((mx > 0) && !storage)
        +		{
        +		CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA,ERR_R_MALLOC_FAILURE);
        +		return;
        +		}
        +	for(i = 0; i < mx; i++)
        +		{
        +		if(storage[i] && storage[i]->free_func)
        +			{
        +			ptr = CRYPTO_get_ex_data(ad,i);
        +			storage[i]->free_func(obj,ptr,ad,i,
        +				storage[i]->argl,storage[i]->argp);
        +			}
        +		}
        +	if(storage)
        +		OPENSSL_free(storage);
        +	if(ad->sk)
        +		{
        +		sk_void_free(ad->sk);
        +		ad->sk=NULL;
        +		}
        +	}
        +
        +/********************************************************************/
        +/* API functions that defer all "state" operations to the "ex_data"
        + * implementation we have set. */
        +
        +/* Obtain an index for a new class (not the same as getting a new index within
        + * an existing class - this is actually getting a new *class*) */
        +int CRYPTO_ex_data_new_class(void)
        +	{
        +	IMPL_CHECK
        +	return EX_IMPL(new_class)();
        +	}
        +
        +/* Release all "ex_data" state to prevent memory leaks. This can't be made
        + * thread-safe without overhauling a lot of stuff, and shouldn't really be
        + * called under potential race-conditions anyway (it's for program shutdown
        + * after all). */
        +void CRYPTO_cleanup_all_ex_data(void)
        +	{
        +	IMPL_CHECK
        +	EX_IMPL(cleanup)();
        +	}
        +
        +/* Inside an existing class, get/register a new index. */
        +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
        +		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func)
        +	{
        +	int ret = -1;
        +
        +	IMPL_CHECK
        +	ret = EX_IMPL(get_new_index)(class_index,
        +			argl, argp, new_func, dup_func, free_func);
        +	return ret;
        +	}
        +
        +/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
        + * calling new() callbacks for each index in the class used by this variable */
        +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
        +	{
        +	IMPL_CHECK
        +	return EX_IMPL(new_ex_data)(class_index, obj, ad);
        +	}
        +
        +/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for
        + * each index in the class used by this variable */
        +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
        +	     CRYPTO_EX_DATA *from)
        +	{
        +	IMPL_CHECK
        +	return EX_IMPL(dup_ex_data)(class_index, to, from);
        +	}
        +
        +/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
        + * each index in the class used by this variable */
        +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
        +	{
        +	IMPL_CHECK
        +	EX_IMPL(free_ex_data)(class_index, obj, ad);
        +	}
        +
        +/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
        + * particular index in the class used by this variable */
        +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
        +	{
        +	int i;
        +
        +	if (ad->sk == NULL)
        +		{
        +		if ((ad->sk=sk_void_new_null()) == NULL)
        +			{
        +			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		}
        +	i=sk_void_num(ad->sk);
        +
        +	while (i <= idx)
        +		{
        +		if (!sk_void_push(ad->sk,NULL))
        +			{
        +			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		i++;
        +		}
        +	sk_void_set(ad->sk,idx,val);
        +	return(1);
        +	}
        +
        +/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
        + * particular index in the class used by this variable */
        +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
        +	{
        +	if (ad->sk == NULL)
        +		return(0);
        +	else if (idx >= sk_void_num(ad->sk))
        +		return(0);
        +	else
        +		return(sk_void_value(ad->sk,idx));
        +	}
        +
        +IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
        diff --git a/vendor/openssl/openssl/crypto/fips_err.h b/vendor/openssl/openssl/crypto/fips_err.h
        new file mode 100644
        index 000000000..c671691b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/fips_err.h
        @@ -0,0 +1,209 @@
        +/* crypto/fips_err.h */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/fips.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason)
        +
        +static ERR_STRING_DATA FIPS_str_functs[]=
        +	{
        +{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
        +{ERR_FUNC(FIPS_F_DH_INIT),	"DH_INIT"},
        +{ERR_FUNC(FIPS_F_DRBG_RESEED),	"DRBG_RESEED"},
        +{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN),	"DSA_BUILTIN_PARAMGEN"},
        +{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2),	"DSA_BUILTIN_PARAMGEN2"},
        +{ERR_FUNC(FIPS_F_DSA_DO_SIGN),	"DSA_do_sign"},
        +{ERR_FUNC(FIPS_F_DSA_DO_VERIFY),	"DSA_do_verify"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA),	"FIPS_CHECK_DSA"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA_PRNG),	"fips_check_dsa_prng"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_EC),	"FIPS_CHECK_EC"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_EC_PRNG),	"fips_check_ec_prng"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT),	"FIPS_check_incore_fingerprint"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA),	"fips_check_rsa"},
        +{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA_PRNG),	"fips_check_rsa_prng"},
        +{ERR_FUNC(FIPS_F_FIPS_CIPHER),	"FIPS_cipher"},
        +{ERR_FUNC(FIPS_F_FIPS_CIPHERINIT),	"FIPS_cipherinit"},
        +{ERR_FUNC(FIPS_F_FIPS_CIPHER_CTX_CTRL),	"FIPS_CIPHER_CTX_CTRL"},
        +{ERR_FUNC(FIPS_F_FIPS_DIGESTFINAL),	"FIPS_digestfinal"},
        +{ERR_FUNC(FIPS_F_FIPS_DIGESTINIT),	"FIPS_digestinit"},
        +{ERR_FUNC(FIPS_F_FIPS_DIGESTUPDATE),	"FIPS_digestupdate"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES),	"FIPS_DRBG_BYTES"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK),	"FIPS_DRBG_CHECK"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST),	"FIPS_DRBG_CPRNG_TEST"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_ERROR_CHECK),	"FIPS_DRBG_ERROR_CHECK"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE),	"FIPS_drbg_generate"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_INIT),	"FIPS_drbg_init"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE),	"FIPS_drbg_instantiate"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_NEW),	"FIPS_drbg_new"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED),	"FIPS_drbg_reseed"},
        +{ERR_FUNC(FIPS_F_FIPS_DRBG_SINGLE_KAT),	"FIPS_DRBG_SINGLE_KAT"},
        +{ERR_FUNC(FIPS_F_FIPS_DSA_SIGN_DIGEST),	"FIPS_dsa_sign_digest"},
        +{ERR_FUNC(FIPS_F_FIPS_DSA_VERIFY_DIGEST),	"FIPS_dsa_verify_digest"},
        +{ERR_FUNC(FIPS_F_FIPS_GET_ENTROPY),	"FIPS_GET_ENTROPY"},
        +{ERR_FUNC(FIPS_F_FIPS_MODULE_MODE_SET),	"FIPS_module_mode_set"},
        +{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST),	"fips_pkey_signature_test"},
        +{ERR_FUNC(FIPS_F_FIPS_RAND_ADD),	"FIPS_rand_add"},
        +{ERR_FUNC(FIPS_F_FIPS_RAND_BYTES),	"FIPS_rand_bytes"},
        +{ERR_FUNC(FIPS_F_FIPS_RAND_PSEUDO_BYTES),	"FIPS_rand_pseudo_bytes"},
        +{ERR_FUNC(FIPS_F_FIPS_RAND_SEED),	"FIPS_rand_seed"},
        +{ERR_FUNC(FIPS_F_FIPS_RAND_SET_METHOD),	"FIPS_rand_set_method"},
        +{ERR_FUNC(FIPS_F_FIPS_RAND_STATUS),	"FIPS_rand_status"},
        +{ERR_FUNC(FIPS_F_FIPS_RSA_SIGN_DIGEST),	"FIPS_rsa_sign_digest"},
        +{ERR_FUNC(FIPS_F_FIPS_RSA_VERIFY_DIGEST),	"FIPS_rsa_verify_digest"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES),	"FIPS_selftest_aes"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_CCM),	"FIPS_selftest_aes_ccm"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_GCM),	"FIPS_selftest_aes_gcm"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_XTS),	"FIPS_selftest_aes_xts"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_CMAC),	"FIPS_selftest_cmac"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES),	"FIPS_selftest_des"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA),	"FIPS_selftest_dsa"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA),	"FIPS_selftest_ecdsa"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC),	"FIPS_selftest_hmac"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1),	"FIPS_selftest_sha1"},
        +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_X931),	"FIPS_selftest_x931"},
        +{ERR_FUNC(FIPS_F_FIPS_SET_PRNG_KEY),	"FIPS_SET_PRNG_KEY"},
        +{ERR_FUNC(FIPS_F_HASH_FINAL),	"HASH_FINAL"},
        +{ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
        +{ERR_FUNC(FIPS_F_RSA_EAY_INIT),	"RSA_EAY_INIT"},
        +{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT),	"RSA_EAY_PRIVATE_DECRYPT"},
        +{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT),	"RSA_EAY_PRIVATE_ENCRYPT"},
        +{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT),	"RSA_EAY_PUBLIC_DECRYPT"},
        +{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT),	"RSA_EAY_PUBLIC_ENCRYPT"},
        +{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX),	"RSA_X931_generate_key_ex"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA FIPS_str_reasons[]=
        +	{
        +{ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED),"additional input error undetected"},
        +{ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG),"additional input too long"},
        +{ERR_REASON(FIPS_R_ALREADY_INSTANTIATED) ,"already instantiated"},
        +{ERR_REASON(FIPS_R_AUTHENTICATION_FAILURE),"authentication failure"},
        +{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
        +{ERR_REASON(FIPS_R_DRBG_NOT_INITIALISED) ,"drbg not initialised"},
        +{ERR_REASON(FIPS_R_DRBG_STUCK)           ,"drbg stuck"},
        +{ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED),"entropy error undetected"},
        +{ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED),"entropy not requested for reseed"},
        +{ERR_REASON(FIPS_R_ENTROPY_SOURCE_STUCK) ,"entropy source stuck"},
        +{ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
        +{ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
        +{ERR_REASON(FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT),"error retrieving additional input"},
        +{ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY),"error retrieving entropy"},
        +{ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE),"error retrieving nonce"},
        +{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"},
        +{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"},
        +{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"},
        +{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"},
        +{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"},
        +{ERR_REASON(FIPS_R_FUNCTION_ERROR)       ,"function error"},
        +{ERR_REASON(FIPS_R_GENERATE_ERROR)       ,"generate error"},
        +{ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED),"generate error undetected"},
        +{ERR_REASON(FIPS_R_INSTANTIATE_ERROR)    ,"instantiate error"},
        +{ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH),"insufficient security strength"},
        +{ERR_REASON(FIPS_R_INTERNAL_ERROR)       ,"internal error"},
        +{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH)   ,"invalid key length"},
        +{ERR_REASON(FIPS_R_INVALID_PARAMETERS)   ,"invalid parameters"},
        +{ERR_REASON(FIPS_R_IN_ERROR_STATE)       ,"in error state"},
        +{ERR_REASON(FIPS_R_KEY_TOO_SHORT)        ,"key too short"},
        +{ERR_REASON(FIPS_R_NONCE_ERROR_UNDETECTED),"nonce error undetected"},
        +{ERR_REASON(FIPS_R_NON_FIPS_METHOD)      ,"non fips method"},
        +{ERR_REASON(FIPS_R_NOPR_TEST1_FAILURE)   ,"nopr test1 failure"},
        +{ERR_REASON(FIPS_R_NOPR_TEST2_FAILURE)   ,"nopr test2 failure"},
        +{ERR_REASON(FIPS_R_NOT_INSTANTIATED)     ,"not instantiated"},
        +{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"},
        +{ERR_REASON(FIPS_R_PERSONALISATION_ERROR_UNDETECTED),"personalisation error undetected"},
        +{ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG),"personalisation string too long"},
        +{ERR_REASON(FIPS_R_PRNG_STRENGTH_TOO_LOW),"prng strength too low"},
        +{ERR_REASON(FIPS_R_PR_TEST1_FAILURE)     ,"pr test1 failure"},
        +{ERR_REASON(FIPS_R_PR_TEST2_FAILURE)     ,"pr test2 failure"},
        +{ERR_REASON(FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED),"request length error undetected"},
        +{ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG),"request too large for drbg"},
        +{ERR_REASON(FIPS_R_RESEED_COUNTER_ERROR) ,"reseed counter error"},
        +{ERR_REASON(FIPS_R_RESEED_ERROR)         ,"reseed error"},
        +{ERR_REASON(FIPS_R_SELFTEST_FAILED)      ,"selftest failed"},
        +{ERR_REASON(FIPS_R_SELFTEST_FAILURE)     ,"selftest failure"},
        +{ERR_REASON(FIPS_R_STRENGTH_ERROR_UNDETECTED),"strength error undetected"},
        +{ERR_REASON(FIPS_R_TEST_FAILURE)         ,"test failure"},
        +{ERR_REASON(FIPS_R_UNINSTANTIATE_ERROR)  ,"uninstantiate error"},
        +{ERR_REASON(FIPS_R_UNINSTANTIATE_ZEROISE_ERROR),"uninstantiate zeroise error"},
        +{ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE),"unsupported drbg type"},
        +{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_FIPS_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,FIPS_str_functs);
        +		ERR_load_strings(0,FIPS_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/fips_ers.c b/vendor/openssl/openssl/crypto/fips_ers.c
        new file mode 100644
        index 000000000..09f11748f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/fips_ers.c
        @@ -0,0 +1,7 @@
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_FIPS
        +# include "fips_err.h"
        +#else
        +static void *dummy=&dummy;
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/hmac/Makefile b/vendor/openssl/openssl/crypto/hmac/Makefile
        new file mode 100644
        index 000000000..0e91709f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/hmac/Makefile
        @@ -0,0 +1,110 @@
        +#
        +# OpenSSL/crypto/md/Makefile
        +#
        +
        +DIR=	hmac
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=hmactest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=hmac.c hm_ameth.c hm_pmeth.c
        +LIBOBJ=hmac.o hm_ameth.o hm_pmeth.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= hmac.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +hm_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
        +hm_ameth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +hm_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +hm_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +hm_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +hm_ameth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +hm_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +hm_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +hm_ameth.o: ../../include/openssl/symhacks.h ../asn1/asn1_locl.h ../cryptlib.h
        +hm_ameth.o: hm_ameth.c
        +hm_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +hm_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +hm_pmeth.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +hm_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +hm_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +hm_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +hm_pmeth.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
        +hm_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +hm_pmeth.o: ../../include/openssl/opensslconf.h
        +hm_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +hm_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +hm_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +hm_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +hm_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +hm_pmeth.o: ../cryptlib.h ../evp/evp_locl.h hm_pmeth.c
        +hmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +hmac.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +hmac.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
        +hmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +hmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +hmac.o: ../../include/openssl/symhacks.h ../cryptlib.h hmac.c
        diff --git a/vendor/openssl/openssl/crypto/hmac/hm_ameth.c b/vendor/openssl/openssl/crypto/hmac/hm_ameth.c
        new file mode 100644
        index 000000000..e03f24aed
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/hmac/hm_ameth.c
        @@ -0,0 +1,167 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2007.
        + */
        +/* ====================================================================
        + * Copyright (c) 2007 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include "asn1_locl.h"
        +
        +#define HMAC_TEST_PRIVATE_KEY_FORMAT
        +
        +/* HMAC "ASN1" method. This is just here to indicate the
        + * maximum HMAC output length and to free up an HMAC
        + * key.
        + */
        +
        +static int hmac_size(const EVP_PKEY *pkey)
        +	{
        +	return EVP_MAX_MD_SIZE;
        +	}
        +
        +static void hmac_key_free(EVP_PKEY *pkey)
        +	{
        +	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
        +	if (os)
        +		{
        +		if (os->data)
        +			OPENSSL_cleanse(os->data, os->length);
        +		ASN1_OCTET_STRING_free(os);
        +		}
        +	}
        +
        +
        +static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        +	{
        +	switch (op)
        +		{
        +		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        +		*(int *)arg2 = NID_sha1;
        +		return 1;
        +
        +		default:
        +		return -2;
        +		}
        +	}
        +
        +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
        +/* A bogus private key format for test purposes. This is simply the
        + * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the
        + * genpkey utility can be used to "generate" HMAC keys.
        + */
        +
        +static int old_hmac_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	ASN1_OCTET_STRING *os;
        +	os = ASN1_OCTET_STRING_new();
        +	if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen))
        +		return 0;
        +	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os);
        +	return 1;
        +	}
        +
        +static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	int inc;
        +	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
        +	if (pder)
        +		{
        +		if (!*pder)
        +			{
        +			*pder = OPENSSL_malloc(os->length);
        +			inc = 0;
        +			}
        +		else inc = 1;
        +
        +		memcpy(*pder, os->data, os->length);
        +
        +		if (inc)
        +			*pder += os->length;
        +		}
        +			
        +	return os->length;
        +	}
        +
        +#endif
        +
        +const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = 
        +	{
        +	EVP_PKEY_HMAC,
        +	EVP_PKEY_HMAC,
        +	0,
        +
        +	"HMAC",
        +	"OpenSSL HMAC method",
        +
        +	0,0,0,0,
        +
        +	0,0,0,
        +
        +	hmac_size,
        +	0,
        +	0,0,0,0,0,0,0,
        +
        +	hmac_key_free,
        +	hmac_pkey_ctrl,
        +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
        +	old_hmac_decode,
        +	old_hmac_encode
        +#else
        +	0,0
        +#endif
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/hmac/hm_pmeth.c b/vendor/openssl/openssl/crypto/hmac/hm_pmeth.c
        new file mode 100644
        index 000000000..0daa44511
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/hmac/hm_pmeth.c
        @@ -0,0 +1,271 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2007.
        + */
        +/* ====================================================================
        + * Copyright (c) 2007 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/evp.h>
        +#include <openssl/hmac.h>
        +#include "evp_locl.h"
        +
        +/* HMAC pkey context structure */
        +
        +typedef struct
        +	{
        +	const EVP_MD *md;	/* MD for HMAC use */
        +	ASN1_OCTET_STRING ktmp; /* Temp storage for key */
        +	HMAC_CTX ctx;
        +	} HMAC_PKEY_CTX;
        +
        +static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
        +	{
        +	HMAC_PKEY_CTX *hctx;
        +	hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
        +	if (!hctx)
        +		return 0;
        +	hctx->md = NULL;
        +	hctx->ktmp.data = NULL;
        +	hctx->ktmp.length = 0;
        +	hctx->ktmp.flags = 0;
        +	hctx->ktmp.type = V_ASN1_OCTET_STRING;
        +	HMAC_CTX_init(&hctx->ctx);
        +
        +	ctx->data = hctx;
        +	ctx->keygen_info_count = 0;
        +
        +	return 1;
        +	}
        +
        +static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	HMAC_PKEY_CTX *sctx, *dctx;
        +	if (!pkey_hmac_init(dst))
        +		return 0;
        +       	sctx = src->data;
        +	dctx = dst->data;
        +	dctx->md = sctx->md;
        +	HMAC_CTX_init(&dctx->ctx);
        +	if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
        +		return 0;
        +	if (sctx->ktmp.data)
        +		{
        +		if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
        +					sctx->ktmp.data, sctx->ktmp.length))
        +			return 0;
        +		}
        +	return 1;
        +	}
        +
        +static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
        +	{
        +	HMAC_PKEY_CTX *hctx = ctx->data;
        +	HMAC_CTX_cleanup(&hctx->ctx);
        +	if (hctx->ktmp.data)
        +		{
        +		if (hctx->ktmp.length)
        +			OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
        +		OPENSSL_free(hctx->ktmp.data);
        +		hctx->ktmp.data = NULL;
        +		}
        +	OPENSSL_free(hctx);
        +	}
        +
        +static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	ASN1_OCTET_STRING *hkey = NULL;
        +	HMAC_PKEY_CTX *hctx = ctx->data;
        +	if (!hctx->ktmp.data)
        +		return 0;
        +	hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
        +	if (!hkey)
        +		return 0;
        +	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
        +	
        +	return 1;
        +	}
        +
        +static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
        +	{
        +	HMAC_PKEY_CTX *hctx = ctx->pctx->data;
        +	if (!HMAC_Update(&hctx->ctx, data, count))
        +		return 0;
        +	return 1;
        +	}
        +
        +static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
        +	{
        +	HMAC_PKEY_CTX *hctx = ctx->data;
        +	HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
        +	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
        +	mctx->update = int_update;
        +	return 1;
        +	}
        +
        +static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					EVP_MD_CTX *mctx)
        +	{
        +	unsigned int hlen;
        +	HMAC_PKEY_CTX *hctx = ctx->data;
        +	int l = EVP_MD_CTX_size(mctx);
        +
        +	if (l < 0)
        +		return 0;
        +	*siglen = l;
        +	if (!sig)
        +		return 1;
        +
        +	if (!HMAC_Final(&hctx->ctx, sig, &hlen))
        +		return 0;
        +	*siglen = (size_t)hlen;
        +	return 1;
        +	}
        +
        +static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	HMAC_PKEY_CTX *hctx = ctx->data;
        +	ASN1_OCTET_STRING *key;
        +	switch (type)
        +		{
        +
        +		case EVP_PKEY_CTRL_SET_MAC_KEY:
        +		if ((!p2 && p1 > 0) || (p1 < -1))
        +			return 0;
        +		if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
        +			return 0;
        +		break;
        +
        +		case EVP_PKEY_CTRL_MD:
        +		hctx->md = p2;
        +		break;
        +
        +		case EVP_PKEY_CTRL_DIGESTINIT:
        +		key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
        +		if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
        +				ctx->engine))
        +			return 0;
        +		break;
        +
        +		default:
        +		return -2;
        +
        +		}
        +	return 1;
        +	}
        +
        +static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
        +			const char *type, const char *value)
        +	{
        +	if (!value)
        +		{
        +		return 0;
        +		}
        +	if (!strcmp(type, "key"))
        +		{
        +		void *p = (void *)value;
        +		return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
        +				-1, p);
        +		}
        +	if (!strcmp(type, "hexkey"))
        +		{
        +		unsigned char *key;
        +		int r;
        +		long keylen;
        +		key = string_to_hex(value, &keylen);
        +		if (!key)
        +			return 0;
        +		r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
        +		OPENSSL_free(key);
        +		return r;
        +		}
        +	return -2;
        +	}
        +
        +const EVP_PKEY_METHOD hmac_pkey_meth = 
        +	{
        +	EVP_PKEY_HMAC,
        +	0,
        +	pkey_hmac_init,
        +	pkey_hmac_copy,
        +	pkey_hmac_cleanup,
        +
        +	0, 0,
        +
        +	0,
        +	pkey_hmac_keygen,
        +
        +	0, 0,
        +
        +	0, 0,
        +
        +	0,0,
        +
        +	hmac_signctx_init,
        +	hmac_signctx,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	0,0,
        +
        +	pkey_hmac_ctrl,
        +	pkey_hmac_ctrl_str
        +
        +	};
        diff --git a/vendor/openssl/openssl/crypto/hmac/hmac.c b/vendor/openssl/openssl/crypto/hmac/hmac.c
        new file mode 100644
        index 000000000..ba27cbf56
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/hmac/hmac.c
        @@ -0,0 +1,251 @@
        +/* crypto/hmac/hmac.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/hmac.h>
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
        +		  const EVP_MD *md, ENGINE *impl)
        +	{
        +	int i,j,reset=0;
        +	unsigned char pad[HMAC_MAX_MD_CBLOCK];
        +
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		{
        +		/* If we have an ENGINE need to allow non FIPS */
        +		if ((impl || ctx->i_ctx.engine)
        +			&&  !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
        +			{
        +			EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS);
        +			return 0;
        +			}
        +		/* Other algorithm blocking will be done in FIPS_cmac_init,
        +		 * via FIPS_hmac_init_ex().
        +		 */
        +		if (!impl && !ctx->i_ctx.engine)
        +			return FIPS_hmac_init_ex(ctx, key, len, md, NULL);
        +		}
        +#endif
        +
        +	if (md != NULL)
        +		{
        +		reset=1;
        +		ctx->md=md;
        +		}
        +	else
        +		md=ctx->md;
        +
        +	if (key != NULL)
        +		{
        +		reset=1;
        +		j=EVP_MD_block_size(md);
        +		OPENSSL_assert(j <= (int)sizeof(ctx->key));
        +		if (j < len)
        +			{
        +			if (!EVP_DigestInit_ex(&ctx->md_ctx,md, impl))
        +				goto err;
        +			if (!EVP_DigestUpdate(&ctx->md_ctx,key,len))
        +				goto err;
        +			if (!EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
        +				&ctx->key_length))
        +				goto err;
        +			}
        +		else
        +			{
        +			OPENSSL_assert(len>=0 && len<=(int)sizeof(ctx->key));
        +			memcpy(ctx->key,key,len);
        +			ctx->key_length=len;
        +			}
        +		if(ctx->key_length != HMAC_MAX_MD_CBLOCK)
        +			memset(&ctx->key[ctx->key_length], 0,
        +				HMAC_MAX_MD_CBLOCK - ctx->key_length);
        +		}
        +
        +	if (reset)	
        +		{
        +		for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
        +			pad[i]=0x36^ctx->key[i];
        +		if (!EVP_DigestInit_ex(&ctx->i_ctx,md, impl))
        +			goto err;
        +		if (!EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)))
        +			goto err;
        +
        +		for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
        +			pad[i]=0x5c^ctx->key[i];
        +		if (!EVP_DigestInit_ex(&ctx->o_ctx,md, impl))
        +			goto err;
        +		if (!EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)))
        +			goto err;
        +		}
        +	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx))
        +			goto err;
        +	return 1;
        +	err:
        +	return 0;
        +	}
        +
        +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
        +	{
        +	if(key && md)
        +	    HMAC_CTX_init(ctx);
        +	return HMAC_Init_ex(ctx,key,len,md, NULL);
        +	}
        +
        +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !ctx->i_ctx.engine)
        +		return FIPS_hmac_update(ctx, data, len);
        +#endif
        +	return EVP_DigestUpdate(&ctx->md_ctx,data,len);
        +	}
        +
        +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
        +	{
        +	unsigned int i;
        +	unsigned char buf[EVP_MAX_MD_SIZE];
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !ctx->i_ctx.engine)
        +		return FIPS_hmac_final(ctx, md, len);
        +#endif
        +
        +	if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i))
        +		goto err;
        +	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx))
        +		goto err;
        +	if (!EVP_DigestUpdate(&ctx->md_ctx,buf,i))
        +		goto err;
        +	if (!EVP_DigestFinal_ex(&ctx->md_ctx,md,len))
        +		goto err;
        +	return 1;
        +	err:
        +	return 0;
        +	}
        +
        +void HMAC_CTX_init(HMAC_CTX *ctx)
        +	{
        +	EVP_MD_CTX_init(&ctx->i_ctx);
        +	EVP_MD_CTX_init(&ctx->o_ctx);
        +	EVP_MD_CTX_init(&ctx->md_ctx);
        +	}
        +
        +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
        +	{
        +	if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx))
        +		goto err;
        +	if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx))
        +		goto err;
        +	if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
        +		goto err;
        +	memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
        +	dctx->key_length = sctx->key_length;
        +	dctx->md = sctx->md;
        +	return 1;
        +	err:
        +	return 0;
        +	}
        +
        +void HMAC_CTX_cleanup(HMAC_CTX *ctx)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !ctx->i_ctx.engine)
        +		{
        +		FIPS_hmac_ctx_cleanup(ctx);
        +		return;
        +		}
        +#endif
        +	EVP_MD_CTX_cleanup(&ctx->i_ctx);
        +	EVP_MD_CTX_cleanup(&ctx->o_ctx);
        +	EVP_MD_CTX_cleanup(&ctx->md_ctx);
        +	memset(ctx,0,sizeof *ctx);
        +	}
        +
        +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
        +		    const unsigned char *d, size_t n, unsigned char *md,
        +		    unsigned int *md_len)
        +	{
        +	HMAC_CTX c;
        +	static unsigned char m[EVP_MAX_MD_SIZE];
        +
        +	if (md == NULL) md=m;
        +	HMAC_CTX_init(&c);
        +	if (!HMAC_Init(&c,key,key_len,evp_md))
        +		goto err;
        +	if (!HMAC_Update(&c,d,n))
        +		goto err;
        +	if (!HMAC_Final(&c,md,md_len))
        +		goto err;
        +	HMAC_CTX_cleanup(&c);
        +	return md;
        +	err:
        +	return NULL;
        +	}
        +
        +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
        +	{
        +	EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
        +	EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
        +	EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/hmac/hmac.h b/vendor/openssl/openssl/crypto/hmac/hmac.h
        new file mode 100644
        index 000000000..1be002219
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/hmac/hmac.h
        @@ -0,0 +1,110 @@
        +/* crypto/hmac/hmac.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +#ifndef HEADER_HMAC_H
        +#define HEADER_HMAC_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_HMAC
        +#error HMAC is disabled.
        +#endif
        +
        +#include <openssl/evp.h>
        +
        +#define HMAC_MAX_MD_CBLOCK	128	/* largest known is SHA512 */
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct hmac_ctx_st
        +	{
        +	const EVP_MD *md;
        +	EVP_MD_CTX md_ctx;
        +	EVP_MD_CTX i_ctx;
        +	EVP_MD_CTX o_ctx;
        +	unsigned int key_length;
        +	unsigned char key[HMAC_MAX_MD_CBLOCK];
        +	} HMAC_CTX;
        +
        +#define HMAC_size(e)	(EVP_MD_size((e)->md))
        +
        +
        +void HMAC_CTX_init(HMAC_CTX *ctx);
        +void HMAC_CTX_cleanup(HMAC_CTX *ctx);
        +
        +#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
        +
        +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
        +	       const EVP_MD *md); /* deprecated */
        +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
        +		  const EVP_MD *md, ENGINE *impl);
        +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
        +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
        +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
        +		    const unsigned char *d, size_t n, unsigned char *md,
        +		    unsigned int *md_len);
        +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
        +
        +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/hmac/hmactest.c b/vendor/openssl/openssl/crypto/hmac/hmactest.c
        new file mode 100644
        index 000000000..1b906b81a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/hmac/hmactest.c
        @@ -0,0 +1,175 @@
        +/* crypto/hmac/hmactest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_HMAC
        +int main(int argc, char *argv[])
        +{
        +    printf("No HMAC support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/hmac.h>
        +#ifndef OPENSSL_NO_MD5
        +#include <openssl/md5.h>
        +#endif
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_MD5
        +static struct test_st
        +	{
        +	unsigned char key[16];
        +	int key_len;
        +	unsigned char data[64];
        +	int data_len;
        +	unsigned char *digest;
        +	} test[4]={
        +	{	"",
        +		0,
        +		"More text test vectors to stuff up EBCDIC machines :-)",
        +		54,
        +		(unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
        +	},{	{0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
        +		 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
        +		16,
        +		"Hi There",
        +		8,
        +		(unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
        +	},{	"Jefe",
        +		4,
        +		"what do ya want for nothing?",
        +		28,
        +		(unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
        +	},{
        +		{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
        +		 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
        +		16,
        +		{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd},
        +		50,
        +		(unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
        +	},
        +	};
        +#endif
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +#ifndef OPENSSL_NO_MD5
        +	int i;
        +	char *p;
        +#endif
        +	int err=0;
        +
        +#ifdef OPENSSL_NO_MD5
        +	printf("test skipped: MD5 disabled\n");
        +#else
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
        +	ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
        +	ebcdic2ascii(test[2].key,  test[2].key,  test[2].key_len);
        +	ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
        +#endif
        +
        +	for (i=0; i<4; i++)
        +		{
        +		p=pt(HMAC(EVP_md5(),
        +			test[i].key, test[i].key_len,
        +			test[i].data, test[i].data_len,
        +			NULL,NULL));
        +
        +		if (strcmp(p,(char *)test[i].digest) != 0)
        +			{
        +			printf("error calculating HMAC on %d entry'\n",i);
        +			printf("got %s instead of %s\n",p,test[i].digest);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		}
        +#endif /* OPENSSL_NO_MD5 */
        +	EXIT(err);
        +	return(0);
        +	}
        +
        +#ifndef OPENSSL_NO_MD5
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<MD5_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ia64cpuid.S b/vendor/openssl/openssl/crypto/ia64cpuid.S
        new file mode 100644
        index 000000000..7832b9b64
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ia64cpuid.S
        @@ -0,0 +1,167 @@
        +// Works on all IA-64 platforms: Linux, HP-UX, Win64i...
        +// On Win64i compile with ias.exe.
        +.text
        +
        +.global	OPENSSL_cpuid_setup#
        +.proc	OPENSSL_cpuid_setup#
        +OPENSSL_cpuid_setup:
        +{ .mib;	br.ret.sptk.many	b0		};;
        +.endp	OPENSSL_cpuid_setup#
        +
        +.global	OPENSSL_rdtsc#
        +.proc	OPENSSL_rdtsc#
        +OPENSSL_rdtsc:
        +{ .mib;	mov			r8=ar.itc
        +	br.ret.sptk.many	b0		};;
        +.endp   OPENSSL_rdtsc#
        +
        +.global	OPENSSL_atomic_add#
        +.proc	OPENSSL_atomic_add#
        +.align	32
        +OPENSSL_atomic_add:
        +{ .mii;	ld4		r2=[r32]
        +	nop.i		0
        +	nop.i		0		};;
        +.Lspin:
        +{ .mii;	mov		ar.ccv=r2
        +	add		r8=r2,r33
        +	mov		r3=r2		};;
        +{ .mmi;	mf;;
        +	cmpxchg4.acq	r2=[r32],r8,ar.ccv
        +	nop.i		0		};;
        +{ .mib;	cmp.ne		p6,p0=r2,r3
        +	nop.i		0
        +(p6)	br.dpnt		.Lspin		};;
        +{ .mib;	nop.m		0
        +	sxt4		r8=r8
        +	br.ret.sptk.many	b0	};;
        +.endp	OPENSSL_atomic_add#
        +
        +// Returns a structure comprising pointer to the top of stack of
        +// the caller and pointer beyond backing storage for the current
        +// register frame. The latter is required, because it might be
        +// insufficient to wipe backing storage for the current frame
        +// (as this procedure does), one might have to go further, toward
        +// higher addresses to reach for whole "retroactively" saved
        +// context...
        +.global	OPENSSL_wipe_cpu#
        +.proc	OPENSSL_wipe_cpu#
        +.align	32
        +OPENSSL_wipe_cpu:
        +	.prologue
        +	.fframe	0
        +	.save	ar.pfs,r2
        +	.save	ar.lc,r3
        +{ .mib;	alloc		r2=ar.pfs,0,96,0,96
        +	mov		r3=ar.lc
        +	brp.loop.imp	.L_wipe_top,.L_wipe_end-16
        +					};;
        +{ .mii;	mov		r9=ar.bsp
        +	mov		r8=pr
        +	mov		ar.lc=96	};;
        +	.body
        +{ .mii;	add		r9=96*8-8,r9
        +	mov		ar.ec=1		};;
        +
        +// One can sweep double as fast, but then we can't quarantee
        +// that backing storage is wiped...
        +.L_wipe_top:
        +{ .mfi;	st8		[r9]=r0,-8
        +	mov		f127=f0
        +	mov		r127=r0		}
        +{ .mfb;	nop.m		0
        +	nop.f		0
        +	br.ctop.sptk	.L_wipe_top	};;
        +.L_wipe_end:
        +
        +{ .mfi;	mov		r11=r0
        +	mov		f6=f0
        +	mov		r14=r0		}
        +{ .mfi;	mov		r15=r0
        +	mov		f7=f0
        +	mov		r16=r0		}
        +{ .mfi;	mov		r17=r0
        +	mov		f8=f0
        +	mov		r18=r0		}
        +{ .mfi;	mov		r19=r0
        +	mov		f9=f0
        +	mov		r20=r0		}
        +{ .mfi;	mov		r21=r0
        +	mov		f10=f0
        +	mov		r22=r0		}
        +{ .mfi;	mov		r23=r0
        +	mov		f11=f0
        +	mov		r24=r0		}
        +{ .mfi;	mov		r25=r0
        +	mov		f12=f0
        +	mov		r26=r0		}
        +{ .mfi;	mov		r27=r0
        +	mov		f13=f0
        +	mov		r28=r0		}
        +{ .mfi;	mov		r29=r0
        +	mov		f14=f0
        +	mov		r30=r0		}
        +{ .mfi;	mov		r31=r0
        +	mov		f15=f0
        +	nop.i		0		}
        +{ .mfi;	mov		f16=f0		}
        +{ .mfi;	mov		f17=f0		}
        +{ .mfi;	mov		f18=f0		}
        +{ .mfi;	mov		f19=f0		}
        +{ .mfi;	mov		f20=f0		}
        +{ .mfi;	mov		f21=f0		}
        +{ .mfi;	mov		f22=f0		}
        +{ .mfi;	mov		f23=f0		}
        +{ .mfi;	mov		f24=f0		}
        +{ .mfi;	mov		f25=f0		}
        +{ .mfi;	mov		f26=f0		}
        +{ .mfi;	mov		f27=f0		}
        +{ .mfi;	mov		f28=f0		}
        +{ .mfi;	mov		f29=f0		}
        +{ .mfi;	mov		f30=f0		}
        +{ .mfi;	add		r9=96*8+8,r9
        +	mov		f31=f0
        +	mov		pr=r8,0x1ffff	}
        +{ .mib;	mov		r8=sp
        +	mov		ar.lc=r3
        +	br.ret.sptk	b0		};;
        +.endp	OPENSSL_wipe_cpu#
        +
        +.global	OPENSSL_cleanse#
        +.proc	OPENSSL_cleanse#
        +OPENSSL_cleanse:
        +{ .mib;	cmp.eq		p6,p0=0,r33	    // len==0
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +	addp4		r32=0,r32
        +#endif
        +(p6)	br.ret.spnt	b0		};;
        +{ .mib;	and		r2=7,r32
        +	cmp.leu		p6,p0=15,r33	    // len>=15
        +(p6)	br.cond.dptk	.Lot		};;
        +
        +.Little:
        +{ .mib;	st1		[r32]=r0,1
        +	cmp.ltu		p6,p7=1,r33	}  // len>1
        +{ .mbb;	add		r33=-1,r33	   // len--
        +(p6)	br.cond.dptk	.Little
        +(p7)	br.ret.sptk.many	b0	};;
        +
        +.Lot:
        +{ .mib;	cmp.eq		p6,p0=0,r2
        +(p6)	br.cond.dptk	.Laligned	};;
        +{ .mmi;	st1		[r32]=r0,1;;
        +	and		r2=7,r32	}
        +{ .mib;	add		r33=-1,r33
        +	br		.Lot		};;
        +
        +.Laligned:
        +{ .mmi;	st8		[r32]=r0,8
        +	and		r2=-8,r33	    // len&~7
        +	add		r33=-8,r33	};; // len-=8
        +{ .mib;	cmp.ltu		p6,p0=8,r2	    // ((len+8)&~7)>8
        +(p6)	br.cond.dptk	.Laligned	};;
        +
        +{ .mbb;	cmp.eq		p6,p7=r0,r33
        +(p7)	br.cond.dpnt	.Little
        +(p6)	br.ret.sptk.many	b0	};;
        +.endp	OPENSSL_cleanse#
        diff --git a/vendor/openssl/openssl/crypto/idea/Makefile b/vendor/openssl/openssl/crypto/idea/Makefile
        new file mode 100644
        index 000000000..8af0acdad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/Makefile
        @@ -0,0 +1,89 @@
        +#
        +# OpenSSL/crypto/idea/Makefile
        +#
        +
        +DIR=	idea
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=ideatest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
        +LIBOBJ=i_cbc.o i_cfb64.o i_ofb64.o i_ecb.o i_skey.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= idea.h
        +HEADER=	idea_lcl.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +i_cbc.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
        +i_cbc.o: i_cbc.c idea_lcl.h
        +i_cfb64.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
        +i_cfb64.o: i_cfb64.c idea_lcl.h
        +i_ecb.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
        +i_ecb.o: ../../include/openssl/opensslv.h i_ecb.c idea_lcl.h
        +i_ofb64.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
        +i_ofb64.o: i_ofb64.c idea_lcl.h
        +i_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +i_skey.o: ../../include/openssl/idea.h ../../include/openssl/opensslconf.h
        +i_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +i_skey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +i_skey.o: ../../include/openssl/symhacks.h i_skey.c idea_lcl.h
        diff --git a/vendor/openssl/openssl/crypto/idea/i_cbc.c b/vendor/openssl/openssl/crypto/idea/i_cbc.c
        new file mode 100644
        index 000000000..ecb9cb8b8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/i_cbc.c
        @@ -0,0 +1,168 @@
        +/* crypto/idea/i_cbc.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 <openssl/idea.h>
        +#include "idea_lcl.h"
        +
        +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int encrypt)
        +	{
        +	register unsigned long tin0,tin1;
        +	register unsigned long tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	unsigned long tin[2];
        +
        +	if (encrypt)
        +		{
        +		n2l(iv,tout0);
        +		n2l(iv,tout1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0);
        +			n2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			idea_encrypt(tin,ks);
        +			tout0=tin[0]; l2n(tout0,out);
        +			tout1=tin[1]; l2n(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			n2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			idea_encrypt(tin,ks);
        +			tout0=tin[0]; l2n(tout0,out);
        +			tout1=tin[1]; l2n(tout1,out);
        +			}
        +		l2n(tout0,iv);
        +		l2n(tout1,iv);
        +		}
        +	else
        +		{
        +		n2l(iv,xor0);
        +		n2l(iv,xor1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			n2l(in,tin0); tin[0]=tin0;
        +			n2l(in,tin1); tin[1]=tin1;
        +			idea_encrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2n(tout0,out);
        +			l2n(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			n2l(in,tin0); tin[0]=tin0;
        +			n2l(in,tin1); tin[1]=tin1;
        +			idea_encrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2nn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		l2n(xor0,iv);
        +		l2n(xor1,iv);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        +void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
        +	{
        +	register IDEA_INT *p;
        +	register unsigned long x1,x2,x3,x4,t0,t1,ul;
        +
        +	x2=d[0];
        +	x1=(x2>>16);
        +	x4=d[1];
        +	x3=(x4>>16);
        +
        +	p= &(key->data[0][0]);
        +
        +	E_IDEA(0);
        +	E_IDEA(1);
        +	E_IDEA(2);
        +	E_IDEA(3);
        +	E_IDEA(4);
        +	E_IDEA(5);
        +	E_IDEA(6);
        +	E_IDEA(7);
        +
        +	x1&=0xffff;
        +	idea_mul(x1,x1,*p,ul); p++;
        +
        +	t0= x3+ *(p++);
        +	t1= x2+ *(p++);
        +
        +	x4&=0xffff;
        +	idea_mul(x4,x4,*p,ul);
        +
        +	d[0]=(t0&0xffff)|((x1&0xffff)<<16);
        +	d[1]=(x4&0xffff)|((t1&0xffff)<<16);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/idea/i_cfb64.c b/vendor/openssl/openssl/crypto/idea/i_cfb64.c
        new file mode 100644
        index 000000000..66d49d520
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/i_cfb64.c
        @@ -0,0 +1,122 @@
        +/* crypto/idea/i_cfb64.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 <openssl/idea.h>
        +#include "idea_lcl.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, IDEA_KEY_SCHEDULE *schedule,
        +			unsigned char *ivec, int *num, int encrypt)
        +	{
        +	register unsigned long v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned long ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv=(unsigned char *)ivec;
        +	if (encrypt)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				n2l(iv,v0); ti[0]=v0;
        +				n2l(iv,v1); ti[1]=v1;
        +				idea_encrypt((unsigned long *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2n(t,iv);
        +				t=ti[1]; l2n(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				n2l(iv,v0); ti[0]=v0;
        +				n2l(iv,v1); ti[1]=v1;
        +				idea_encrypt((unsigned long *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2n(t,iv);
        +				t=ti[1]; l2n(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=t=c=cc=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/idea/i_ecb.c b/vendor/openssl/openssl/crypto/idea/i_ecb.c
        new file mode 100644
        index 000000000..fef38230a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/i_ecb.c
        @@ -0,0 +1,85 @@
        +/* crypto/idea/i_ecb.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 <openssl/idea.h>
        +#include "idea_lcl.h"
        +#include <openssl/opensslv.h>
        +
        +const char IDEA_version[]="IDEA" OPENSSL_VERSION_PTEXT;
        +
        +const char *idea_options(void)
        +	{
        +	if (sizeof(short) != sizeof(IDEA_INT))
        +		return("idea(int)");
        +	else
        +		return("idea(short)");
        +	}
        +
        +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	     IDEA_KEY_SCHEDULE *ks)
        +	{
        +	unsigned long l0,l1,d[2];
        +
        +	n2l(in,l0); d[0]=l0;
        +	n2l(in,l1); d[1]=l1;
        +	idea_encrypt(d,ks);
        +	l0=d[0]; l2n(l0,out);
        +	l1=d[1]; l2n(l1,out);
        +	l0=l1=d[0]=d[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/idea/i_ofb64.c b/vendor/openssl/openssl/crypto/idea/i_ofb64.c
        new file mode 100644
        index 000000000..e749e88e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/i_ofb64.c
        @@ -0,0 +1,111 @@
        +/* crypto/idea/i_ofb64.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 <openssl/idea.h>
        +#include "idea_lcl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, IDEA_KEY_SCHEDULE *schedule,
        +			unsigned char *ivec, int *num)
        +	{
        +	register unsigned long v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned char d[8];
        +	register char *dp;
        +	unsigned long ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv=(unsigned char *)ivec;
        +	n2l(iv,v0);
        +	n2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=(char *)d;
        +	l2n(v0,dp);
        +	l2n(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			idea_encrypt((unsigned long *)ti,schedule);
        +			dp=(char *)d;
        +			t=ti[0]; l2n(t,dp);
        +			t=ti[1]; l2n(t,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +		v0=ti[0];
        +		v1=ti[1];
        +		iv=(unsigned char *)ivec;
        +		l2n(v0,iv);
        +		l2n(v1,iv);
        +		}
        +	t=v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/idea/i_skey.c b/vendor/openssl/openssl/crypto/idea/i_skey.c
        new file mode 100644
        index 000000000..afb830964
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/i_skey.c
        @@ -0,0 +1,164 @@
        +/* crypto/idea/i_skey.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 <openssl/crypto.h>
        +#include <openssl/idea.h>
        +#include "idea_lcl.h"
        +
        +static IDEA_INT inverse(unsigned int xin);
        +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
        +#ifdef OPENSSL_FIPS
        +	{
        +	fips_cipher_abort(IDEA);
        +	private_idea_set_encrypt_key(key, ks);
        +	}
        +void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
        +#endif
        +	{
        +	int i;
        +	register IDEA_INT *kt,*kf,r0,r1,r2;
        +
        +	kt= &(ks->data[0][0]);
        +	n2s(key,kt[0]); n2s(key,kt[1]); n2s(key,kt[2]); n2s(key,kt[3]);
        +	n2s(key,kt[4]); n2s(key,kt[5]); n2s(key,kt[6]); n2s(key,kt[7]);
        +
        +	kf=kt;
        +	kt+=8;
        +	for (i=0; i<6; i++)
        +		{
        +		r2= kf[1];
        +		r1= kf[2];
        +		*(kt++)= ((r2<<9) | (r1>>7))&0xffff;
        +		r0= kf[3];
        +		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
        +		r1= kf[4];
        +		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
        +		r0= kf[5];
        +		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
        +		r1= kf[6];
        +		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
        +		r0= kf[7];
        +		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
        +		r1= kf[0];
        +		if (i >= 5) break;
        +		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
        +		*(kt++)= ((r1<<9) | (r2>>7))&0xffff;
        +		kf+=8;
        +		}
        +	}
        +
        +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
        +	{
        +	int r;
        +	register IDEA_INT *fp,*tp,t;
        +
        +	tp= &(dk->data[0][0]);
        +	fp= &(ek->data[8][0]);
        +	for (r=0; r<9; r++)
        +		{
        +		*(tp++)=inverse(fp[0]);
        +		*(tp++)=((int)(0x10000L-fp[2])&0xffff);
        +		*(tp++)=((int)(0x10000L-fp[1])&0xffff);
        +		*(tp++)=inverse(fp[3]);
        +		if (r == 8) break;
        +		fp-=6;
        +		*(tp++)=fp[4];
        +		*(tp++)=fp[5];
        +		}
        +
        +	tp= &(dk->data[0][0]);
        +	t=tp[1];
        +	tp[1]=tp[2];
        +	tp[2]=t;
        +
        +	t=tp[49];
        +	tp[49]=tp[50];
        +	tp[50]=t;
        +	}
        +
        +/* taken directly from the 'paper' I'll have a look at it later */
        +static IDEA_INT inverse(unsigned int xin)
        +	{
        +	long n1,n2,q,r,b1,b2,t;
        +
        +	if (xin == 0)
        +		b2=0;
        +	else
        +		{
        +		n1=0x10001;
        +		n2=xin;
        +		b2=1;
        +		b1=0;
        +
        +		do	{
        +			r=(n1%n2);
        +			q=(n1-r)/n2;
        +			if (r == 0)
        +				{ if (b2 < 0) b2=0x10001+b2; }
        +			else
        +				{
        +				n1=n2;
        +				n2=r;
        +				t=b2;
        +				b2=b1-q*b2;
        +				b1=t;
        +				}
        +			} while (r != 0);
        +		}
        +	return((IDEA_INT)b2);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/idea/idea.h b/vendor/openssl/openssl/crypto/idea/idea.h
        new file mode 100644
        index 000000000..e9a1e7f1a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/idea.h
        @@ -0,0 +1,103 @@
        +/* crypto/idea/idea.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_IDEA_H
        +#define HEADER_IDEA_H
        +
        +#include <openssl/opensslconf.h> /* IDEA_INT, OPENSSL_NO_IDEA */
        +
        +#ifdef OPENSSL_NO_IDEA
        +#error IDEA is disabled.
        +#endif
        +
        +#define IDEA_ENCRYPT	1
        +#define IDEA_DECRYPT	0
        +
        +#define IDEA_BLOCK	8
        +#define IDEA_KEY_LENGTH	16
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct idea_key_st
        +	{
        +	IDEA_INT data[9][6];
        +	} IDEA_KEY_SCHEDULE;
        +
        +const char *idea_options(void);
        +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +	IDEA_KEY_SCHEDULE *ks);
        +#ifdef OPENSSL_FIPS
        +void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
        +#endif
        +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
        +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
        +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc);
        +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
        +	int *num,int enc);
        +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num);
        +void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/idea/idea_lcl.h b/vendor/openssl/openssl/crypto/idea/idea_lcl.h
        new file mode 100644
        index 000000000..f3dbfa67e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/idea_lcl.h
        @@ -0,0 +1,215 @@
        +/* crypto/idea/idea_lcl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* The new form of this macro (check if the a*b == 0) was suggested by 
        + * Colin Plumb <colin@nyx10.cs.du.edu> */
        +/* Removal of the inner if from from Wei Dai 24/4/96 */
        +#define idea_mul(r,a,b,ul) \
        +ul=(unsigned long)a*b; \
        +if (ul != 0) \
        +	{ \
        +	r=(ul&0xffff)-(ul>>16); \
        +	r-=((r)>>16); \
        +	} \
        +else \
        +	r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ 
        +
        +#ifdef undef
        +#define idea_mul(r,a,b,ul,sl) \
        +if (a == 0) r=(0x10001-b)&0xffff; \
        +else if (b == 0) r=(0x10001-a)&0xffff; \
        +else	{ \
        +	ul=(unsigned long)a*b; \
        +	sl=(ul&0xffff)-(ul>>16); \
        +	if (sl <= 0) sl+=0x10001; \
        +	r=sl; \
        +	} 
        +#endif
        +
        +/*  7/12/95 - Many thanks to Rhys Weatherley <rweather@us.oracle.com>
        + * for pointing out that I was assuming little endian
        + * byte order for all quantities what idea
        + * actually used bigendian.  No where in the spec does it mention
        + * this, it is all in terms of 16 bit numbers and even the example
        + * does not use byte streams for the input example :-(.
        + * If you byte swap each pair of input, keys and iv, the functions
        + * would produce the output as the old version :-(.
        + */
        +
        +/* NOTE - c is not incremented as per n2l */
        +#define n2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))    ; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
        +			case 4: l1 =((unsigned long)(*(--(c))))    ; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per l2n */
        +#define l2nn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +				} \
        +			}
        +
        +#undef n2l
        +#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
        +                         l|=((unsigned long)(*((c)++)))<<16L, \
        +                         l|=((unsigned long)(*((c)++)))<< 8L, \
        +                         l|=((unsigned long)(*((c)++))))
        +
        +#undef l2n
        +#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)     )&0xff))
        +
        +#undef s2n
        +#define s2n(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
        +
        +#undef n2s
        +#define n2s(c,l)	(l =((IDEA_INT)(*((c)++)))<< 8L, \
        +			 l|=((IDEA_INT)(*((c)++)))      )
        +
        +#ifdef undef
        +/* NOTE - c is not incremented as per c2l */
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))<<24; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 5: l2|=((unsigned long)(*(--(c))));     \
        +			case 4: l1 =((unsigned long)(*(--(c))))<<24; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 1: l1|=((unsigned long)(*(--(c))));     \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per l2c */
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +				} \
        +			}
        +
        +#undef c2s
        +#define c2s(c,l)	(l =((unsigned long)(*((c)++)))    , \
        +			 l|=((unsigned long)(*((c)++)))<< 8L)
        +
        +#undef s2c
        +#define s2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
        +
        +#undef c2l
        +#define c2l(c,l)	(l =((unsigned long)(*((c)++)))     , \
        +			 l|=((unsigned long)(*((c)++)))<< 8L, \
        +			 l|=((unsigned long)(*((c)++)))<<16L, \
        +			 l|=((unsigned long)(*((c)++)))<<24L)
        +
        +#undef l2c
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +#endif
        +
        +#define E_IDEA(num) \
        +	x1&=0xffff; \
        +	idea_mul(x1,x1,*p,ul); p++; \
        +	x2+= *(p++); \
        +	x3+= *(p++); \
        +	x4&=0xffff; \
        +	idea_mul(x4,x4,*p,ul); p++; \
        +	t0=(x1^x3)&0xffff; \
        +	idea_mul(t0,t0,*p,ul); p++; \
        +	t1=(t0+(x2^x4))&0xffff; \
        +	idea_mul(t1,t1,*p,ul); p++; \
        +	t0+=t1; \
        +	x1^=t1; \
        +	x4^=t0; \
        +	ul=x2^t0; /* do the swap to x3 */ \
        +	x2=x3^t1; \
        +	x3=ul;
        +
        diff --git a/vendor/openssl/openssl/crypto/idea/idea_spd.c b/vendor/openssl/openssl/crypto/idea/idea_spd.c
        new file mode 100644
        index 000000000..699353e87
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/idea_spd.c
        @@ -0,0 +1,299 @@
        +/* crypto/idea/idea_spd.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/idea.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +#ifndef CLK_TCK
        +#define HZ	100.0
        +#else /* CLK_TCK */
        +#define HZ ((double)CLK_TCK)
        +#endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static unsigned char key[] ={
        +			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
        +			};
        +	IDEA_KEY_SCHEDULE sch;
        +	double a,aa,b,c,d;
        +#ifndef SIGALRM
        +	long ca,cca,cb,cc;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	idea_set_encrypt_key(key,&sch);
        +	count=10;
        +	do	{
        +		long i;
        +		IDEA_INT data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			idea_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count/4;
        +	cca=count/200;
        +	cb=count;
        +	cc=count*8/BUFSIZE+1;
        +	printf("idea_set_encrypt_key %ld times\n",ca);
        +#define COND(d)	(count <= (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing idea_set_encrypt_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count+=4)
        +		{
        +		idea_set_encrypt_key(key,&sch);
        +		idea_set_encrypt_key(key,&sch);
        +		idea_set_encrypt_key(key,&sch);
        +		idea_set_encrypt_key(key,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld idea idea_set_encrypt_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing idea_set_decrypt_key for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing idea_set_decrypt_key %ld times\n",cca);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(cca); count+=4)
        +		{
        +		idea_set_decrypt_key(&sch,&sch);
        +		idea_set_decrypt_key(&sch,&sch);
        +		idea_set_decrypt_key(&sch,&sch);
        +		idea_set_decrypt_key(&sch,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld idea idea_set_decrypt_key's in %.2f seconds\n",count,d);
        +	aa=((double)COUNT(cca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing idea_encrypt's for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing idea_encrypt %ld times\n",cb);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cb); count+=4)
        +		{
        +		unsigned long data[2];
        +
        +		idea_encrypt(data,&sch);
        +		idea_encrypt(data,&sch);
        +		idea_encrypt(data,&sch);
        +		idea_encrypt(data,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld idea_encrypt's in %.2f second\n",count,d);
        +	b=((double)COUNT(cb)*8)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing idea_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing idea_cbc_encrypt %ld times on %ld byte blocks\n",cc,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		idea_cbc_encrypt(buf,buf,BUFSIZE,&sch,
        +			&(key[0]),IDEA_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld idea_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +	printf("IDEA set_encrypt_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("IDEA set_decrypt_key per sec = %12.2f (%9.3fuS)\n",aa,1.0e6/aa);
        +	printf("IDEA raw ecb bytes   per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
        +	printf("IDEA cbc     bytes   per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/idea/ideatest.c b/vendor/openssl/openssl/crypto/idea/ideatest.c
        new file mode 100644
        index 000000000..e6ffc7025
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/ideatest.c
        @@ -0,0 +1,235 @@
        +/* crypto/idea/ideatest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_IDEA
        +int main(int argc, char *argv[])
        +{
        +    printf("No IDEA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/idea.h>
        +
        +unsigned char k[16]={
        +	0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
        +	0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
        +
        +unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
        +unsigned char  c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
        +unsigned char out[80];
        +
        +char *text="Hello to all people out there";
        +
        +static unsigned char cfb_key[16]={
        +	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
        +	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
        +	};
        +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +#define CFB_TEST_SIZE 24
        +static unsigned char plain[CFB_TEST_SIZE]=
        +        {
        +        0x4e,0x6f,0x77,0x20,0x69,0x73,
        +        0x20,0x74,0x68,0x65,0x20,0x74,
        +        0x69,0x6d,0x65,0x20,0x66,0x6f,
        +        0x72,0x20,0x61,0x6c,0x6c,0x20
        +        };
        +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
        +	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
        +	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
        +	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
        +
        +/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
        +	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
        +	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
        +	}; 
        +
        +static int cfb64_test(unsigned char *cfb_cipher);
        +static char *pt(unsigned char *p);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	IDEA_KEY_SCHEDULE key,dkey; 
        +	unsigned char iv[8];
        +
        +	idea_set_encrypt_key(k,&key);
        +	idea_ecb_encrypt(in,out,&key);
        +	if (memcmp(out,c,8) != 0)
        +		{
        +		printf("ecb idea error encrypting\n");
        +		printf("got     :");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",out[i]);
        +		printf("\n");
        +		printf("expected:");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",c[i]);
        +		err=20;
        +		printf("\n");
        +		}
        +
        +	idea_set_decrypt_key(&key,&dkey);
        +	idea_ecb_encrypt(c,out,&dkey);
        +	if (memcmp(out,in,8) != 0)
        +		{
        +		printf("ecb idea error decrypting\n");
        +		printf("got     :");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",out[i]);
        +		printf("\n");
        +		printf("expected:");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",in[i]);
        +		printf("\n");
        +		err=3;
        +		}
        +
        +	if (err == 0) printf("ecb idea ok\n");
        +
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt(out,out,8,&dkey,iv,0);
        +	idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
        +	if (memcmp(text,out,strlen(text)+1) != 0)
        +		{
        +		printf("cbc idea bad\n");
        +		err=4;
        +		}
        +	else
        +		printf("cbc idea ok\n");
        +
        +	printf("cfb64 idea ");
        +	if (cfb64_test(cfb_cipher64))
        +		{
        +		printf("bad\n");
        +		err=5;
        +		}
        +	else
        +		printf("ok\n");
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(err);
        +	}
        +
        +static int cfb64_test(unsigned char *cfb_cipher)
        +        {
        +        IDEA_KEY_SCHEDULE eks,dks;
        +        int err=0,i,n;
        +
        +        idea_set_encrypt_key(cfb_key,&eks);
        +        idea_set_decrypt_key(&eks,&dks);
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +                (long)CFB_TEST_SIZE-12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb64_encrypt encrypt error\n");
        +                for (i=0; i<CFB_TEST_SIZE; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf1[i])));
        +                }
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +                (long)CFB_TEST_SIZE-17,&dks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb_encrypt decrypt error\n");
        +                for (i=0; i<24; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf2[i])));
        +                }
        +        return(err);
        +        }
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/idea/version b/vendor/openssl/openssl/crypto/idea/version
        new file mode 100644
        index 000000000..3f2229379
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/idea/version
        @@ -0,0 +1,12 @@
        +1.1 07/12/95 - eay
        +	Many thanks to Rhys Weatherley <rweather@us.oracle.com>
        +	for pointing out that I was assuming little endian byte
        +	order for all quantities what idea actually used
        +	bigendian.  No where in the spec does it mention
        +	this, it is all in terms of 16 bit numbers and even the example
        +	does not use byte streams for the input example :-(.
        +	If you byte swap each pair of input, keys and iv, the functions
        +	would produce the output as the old version :-(.
        +
        +1.0 ??/??/95 - eay
        +	First version.
        diff --git a/vendor/openssl/openssl/crypto/install-crypto.com b/vendor/openssl/openssl/crypto/install-crypto.com
        new file mode 100644
        index 000000000..85b3d583c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/install-crypto.com
        @@ -0,0 +1,196 @@
        +$! INSTALL.COM -- Installs the files in a given directory tree
        +$!
        +$! Author: Richard Levitte <richard@levitte.org>
        +$! Time of creation: 22-MAY-1998 10:13
        +$!
        +$! Changes by Zoltan Arpadffy <zoli@polarhome.com>
        +$!
        +$! P1  root of the directory tree
        +$! P2  "64" for 64-bit pointers.
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ on error then goto tidy
        +$ on control_c then goto tidy
        +$!
        +$ if (p1 .eqs. "")
        +$ then
        +$   write sys$output "First argument missing."
        +$   write sys$output -
        +     "It should be the directory where you want things installed."
        +$     exit
        +$ endif
        +$!
        +$ if (f$getsyi( "cpu") .lt. 128)
        +$ then
        +$   arch = "VAX"
        +$ else
        +$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
        +$   if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$!
        +$ archd = arch
        +$ lib32 = "32"
        +$ shr = "_SHR32"
        +$!
        +$ if (p2 .nes. "")
        +$ then
        +$   if (p2 .eqs. "64")
        +$   then
        +$     archd = arch+ "_64"
        +$     lib32 = ""
        +$     shr = "_SHR"
        +$   else
        +$     if (p2 .nes. "32")
        +$     then
        +$       write sys$output "Second argument invalid."
        +$       write sys$output "It should be "32", "64", or nothing."
        +$       exit
        +$     endif
        +$   endif
        +$ endif
        +$!
        +$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
        +$ root_dev = f$parse( root, , , "device", "syntax_only")
        +$ root_dir = f$parse( root, , , "directory", "syntax_only") - -
        +   "[000000." - "][" - "[" - "]"
        +$ root = root_dev + "[" + root_dir
        +$!
        +$ define /nolog wrk_sslroot 'root'.] /trans=conc
        +$ define /nolog wrk_sslinclude wrk_sslroot:[include]
        +$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
        +$!
        +$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
        +   create /directory /log wrk_sslroot:[000000]
        +$ if f$parse("wrk_sslinclude:") .eqs. "" then -
        +   create /directory /log wrk_sslinclude:
        +$ if f$parse("wrk_sslxlib:") .eqs. "" then -
        +   create /directory /log wrk_sslxlib:
        +$!
        +$ sdirs := , -
        +   'archd', -
        +   objects, -
        +   md2, md4, md5, sha, mdc2, hmac, ripemd, whrlpool, -
        +   des, aes, rc2, rc4, rc5, idea, bf, cast, camellia, seed, -
        +   bn, ec, rsa, dsa, ecdsa, dh, ecdh, dso, engine, -
        +   buffer, bio, stack, lhash, rand, err, -
        +   evp, asn1, pem, x509, x509v3, conf, txt_db, pkcs7, pkcs12, comp, ocsp, -
        +   ui, krb5, -
        +   store, cms, pqueue, ts, jpake
        +$!
        +$ exheader_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
        +$ exheader_'archd' := opensslconf.h
        +$ exheader_objects := objects.h, obj_mac.h
        +$ exheader_md2 := md2.h
        +$ exheader_md4 := md4.h
        +$ exheader_md5 := md5.h
        +$ exheader_sha := sha.h
        +$ exheader_mdc2 := mdc2.h
        +$ exheader_hmac := hmac.h
        +$ exheader_ripemd := ripemd.h
        +$ exheader_whrlpool := whrlpool.h
        +$ exheader_des := des.h, des_old.h
        +$ exheader_aes := aes.h
        +$ exheader_rc2 := rc2.h
        +$ exheader_rc4 := rc4.h
        +$ exheader_rc5 := rc5.h
        +$ exheader_idea := idea.h
        +$ exheader_bf := blowfish.h
        +$ exheader_cast := cast.h
        +$ exheader_camellia := camellia.h
        +$ exheader_seed := seed.h
        +$ exheader_modes := modes.h
        +$ exheader_bn := bn.h
        +$ exheader_ec := ec.h
        +$ exheader_rsa := rsa.h
        +$ exheader_dsa := dsa.h
        +$ exheader_ecdsa := ecdsa.h
        +$ exheader_dh := dh.h
        +$ exheader_ecdh := ecdh.h
        +$ exheader_dso := dso.h
        +$ exheader_engine := engine.h
        +$ exheader_buffer := buffer.h
        +$ exheader_bio := bio.h
        +$ exheader_stack := stack.h, safestack.h
        +$ exheader_lhash := lhash.h
        +$ exheader_rand := rand.h
        +$ exheader_err := err.h
        +$ exheader_evp := evp.h
        +$ exheader_asn1 := asn1.h, asn1_mac.h, asn1t.h
        +$ exheader_pem := pem.h, pem2.h
        +$ exheader_x509 := x509.h, x509_vfy.h
        +$ exheader_x509v3 := x509v3.h
        +$ exheader_conf := conf.h, conf_api.h
        +$ exheader_txt_db := txt_db.h
        +$ exheader_pkcs7 := pkcs7.h
        +$ exheader_pkcs12 := pkcs12.h
        +$ exheader_comp := comp.h
        +$ exheader_ocsp := ocsp.h
        +$ exheader_ui := ui.h, ui_compat.h
        +$ exheader_krb5 := krb5_asn.h
        +$! exheader_store := store.h, str_compat.h
        +$ exheader_store := store.h
        +$ exheader_cms := cms.h
        +$ exheader_pqueue := pqueue.h
        +$ exheader_ts := ts.h
        +$ exheader_jpake := jpake.h
        +$ libs := ssl_libcrypto
        +$!
        +$ exe_dir := [-.'archd'.exe.crypto]
        +$!
        +$! Header files.
        +$!
        +$ i = 0
        +$ loop_sdirs: 
        +$   d = f$edit( f$element( i, ",", sdirs), "trim")
        +$   i = i + 1
        +$   if d .eqs. "," then goto loop_sdirs_end
        +$   tmp = exheader_'d'
        +$   if (d .nes. "") then d = "."+ d
        +$   copy /protection = w:re ['d']'tmp' wrk_sslinclude: /log
        +$ goto loop_sdirs
        +$ loop_sdirs_end:
        +$!
        +$! Object libraries, shareable images.
        +$!
        +$ i = 0
        +$ loop_lib: 
        +$   e = f$edit( f$element( i, ",", libs), "trim")
        +$   i = i + 1
        +$   if e .eqs. "," then goto loop_lib_end
        +$   set noon
        +$   file = exe_dir+ e+ lib32+ ".olb"
        +$   if f$search( file) .nes. ""
        +$   then
        +$     copy /protection = w:re 'file' wrk_sslxlib: /log
        +$   endif
        +$!
        +$   file = exe_dir+ e+ shr+ ".exe"
        +$   if f$search( file) .nes. ""
        +$   then
        +$     copy /protection = w:re 'file' wrk_sslxlib: /log
        +$   endif
        +$   set on
        +$ goto loop_lib
        +$ loop_lib_end:
        +$!
        +$ tidy:
        +$!
        +$ call deass wrk_sslroot
        +$ call deass wrk_sslinclude
        +$ call deass wrk_sslxlib
        +$!
        +$ exit
        +$!
        +$ deass: subroutine
        +$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
        +$ then
        +$   deassign /process 'p1'
        +$ endif
        +$ endsubroutine
        +$!
        diff --git a/vendor/openssl/openssl/crypto/jpake/Makefile b/vendor/openssl/openssl/crypto/jpake/Makefile
        new file mode 100644
        index 000000000..110c49ce0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/jpake/Makefile
        @@ -0,0 +1,64 @@
        +DIR=jpake
        +TOP=../..
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBOBJ=jpake.o jpake_err.o
        +LIBSRC=jpake.c jpake_err.c
        +
        +EXHEADER=jpake.h
        +TEST=jpaketest.c
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	do  \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +
        +depend:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff
        +
        +jpaketest: top jpaketest.c $(LIB)
        +	$(CC) $(CFLAGS) -Wall -Werror -g -o jpaketest jpaketest.c $(LIB)
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +jpake.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +jpake.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +jpake.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +jpake.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +jpake.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +jpake.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +jpake.o: ../../include/openssl/symhacks.h jpake.c jpake.h
        +jpake_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +jpake_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +jpake_err.o: ../../include/openssl/err.h ../../include/openssl/jpake.h
        +jpake_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +jpake_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +jpake_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +jpake_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +jpake_err.o: jpake_err.c
        diff --git a/vendor/openssl/openssl/crypto/jpake/jpake.c b/vendor/openssl/openssl/crypto/jpake/jpake.c
        new file mode 100644
        index 000000000..8e4b633cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/jpake/jpake.c
        @@ -0,0 +1,511 @@
        +#include "jpake.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/sha.h>
        +#include <openssl/err.h>
        +#include <memory.h>
        +
        +/*
        + * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
        + * Bob's (x3, x4, x1, x2). If you see what I mean.
        + */
        +
        +typedef struct
        +    {
        +    char *name;  /* Must be unique */
        +    char *peer_name;
        +    BIGNUM *p;
        +    BIGNUM *g;
        +    BIGNUM *q;
        +    BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
        +    BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
        +    } JPAKE_CTX_PUBLIC;
        +
        +struct JPAKE_CTX
        +    {
        +    JPAKE_CTX_PUBLIC p;
        +    BIGNUM *secret;   /* The shared secret */
        +    BN_CTX *ctx;
        +    BIGNUM *xa;       /* Alice's x1 or Bob's x3 */
        +    BIGNUM *xb;       /* Alice's x2 or Bob's x4 */
        +    BIGNUM *key;      /* The calculated (shared) key */
        +    };
        +
        +static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
        +    {
        +    zkp->gr = BN_new();
        +    zkp->b = BN_new();
        +    }
        +
        +static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
        +    {
        +    BN_free(zkp->b);
        +    BN_free(zkp->gr);
        +    }
        +
        +/* Two birds with one stone - make the global name as expected */
        +#define JPAKE_STEP_PART_init	JPAKE_STEP2_init
        +#define JPAKE_STEP_PART_release	JPAKE_STEP2_release
        +
        +void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p)
        +    {
        +    p->gx = BN_new();
        +    JPAKE_ZKP_init(&p->zkpx);
        +    }
        +
        +void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p)
        +    {
        +    JPAKE_ZKP_release(&p->zkpx);
        +    BN_free(p->gx);
        +    }
        +
        +void JPAKE_STEP1_init(JPAKE_STEP1 *s1)
        +    {
        +    JPAKE_STEP_PART_init(&s1->p1);
        +    JPAKE_STEP_PART_init(&s1->p2);
        +    }
        +
        +void JPAKE_STEP1_release(JPAKE_STEP1 *s1)
        +    {
        +    JPAKE_STEP_PART_release(&s1->p2);
        +    JPAKE_STEP_PART_release(&s1->p1);
        +    }
        +
        +static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name,
        +			   const char *peer_name, const BIGNUM *p,
        +			   const BIGNUM *g, const BIGNUM *q,
        +			   const BIGNUM *secret)
        +    {
        +    ctx->p.name = OPENSSL_strdup(name);
        +    ctx->p.peer_name = OPENSSL_strdup(peer_name);
        +    ctx->p.p = BN_dup(p);
        +    ctx->p.g = BN_dup(g);
        +    ctx->p.q = BN_dup(q);
        +    ctx->secret = BN_dup(secret);
        +
        +    ctx->p.gxc = BN_new();
        +    ctx->p.gxd = BN_new();
        +
        +    ctx->xa = BN_new();
        +    ctx->xb = BN_new();
        +    ctx->key = BN_new();
        +    ctx->ctx = BN_CTX_new();
        +    }
        +    
        +static void JPAKE_CTX_release(JPAKE_CTX *ctx)
        +    {
        +    BN_CTX_free(ctx->ctx);
        +    BN_clear_free(ctx->key);
        +    BN_clear_free(ctx->xb);
        +    BN_clear_free(ctx->xa);
        +
        +    BN_free(ctx->p.gxd);
        +    BN_free(ctx->p.gxc);
        +
        +    BN_clear_free(ctx->secret);
        +    BN_free(ctx->p.q);
        +    BN_free(ctx->p.g);
        +    BN_free(ctx->p.p);
        +    OPENSSL_free(ctx->p.peer_name);
        +    OPENSSL_free(ctx->p.name);
        +
        +    memset(ctx, '\0', sizeof *ctx);
        +    }
        +    
        +JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
        +			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
        +			 const BIGNUM *secret)
        +    {
        +    JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
        +
        +    JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);
        +
        +    return ctx;
        +    }
        +
        +void JPAKE_CTX_free(JPAKE_CTX *ctx)
        +    {
        +    JPAKE_CTX_release(ctx);
        +    OPENSSL_free(ctx);
        +    }
        +
        +static void hashlength(SHA_CTX *sha, size_t l)
        +    {
        +    unsigned char b[2];
        +
        +    OPENSSL_assert(l <= 0xffff);
        +    b[0] = l >> 8;
        +    b[1] = l&0xff;
        +    SHA1_Update(sha, b, 2);
        +    }
        +
        +static void hashstring(SHA_CTX *sha, const char *string)
        +    {
        +    size_t l = strlen(string);
        +
        +    hashlength(sha, l);
        +    SHA1_Update(sha, string, l);
        +    }
        +
        +static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
        +    {
        +    size_t l = BN_num_bytes(bn);
        +    unsigned char *bin = OPENSSL_malloc(l);
        +
        +    hashlength(sha, l);
        +    BN_bn2bin(bn, bin);
        +    SHA1_Update(sha, bin, l);
        +    OPENSSL_free(bin);
        +    }
        +
        +/* h=hash(g, g^r, g^x, name) */
        +static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
        +		     const char *proof_name)
        +    {
        +    unsigned char md[SHA_DIGEST_LENGTH];
        +    SHA_CTX sha;
        +
        +   /*
        +    * XXX: hash should not allow moving of the boundaries - Java code
        +    * is flawed in this respect. Length encoding seems simplest.
        +    */
        +    SHA1_Init(&sha);
        +    hashbn(&sha, zkpg);
        +    OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
        +    hashbn(&sha, p->zkpx.gr);
        +    hashbn(&sha, p->gx);
        +    hashstring(&sha, proof_name);
        +    SHA1_Final(md, &sha);
        +    BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
        +    }
        +
        +/*
        + * Prove knowledge of x
        + * Note that p->gx has already been calculated
        + */
        +static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
        +			 const BIGNUM *zkpg, JPAKE_CTX *ctx)
        +    {
        +    BIGNUM *r = BN_new();
        +    BIGNUM *h = BN_new();
        +    BIGNUM *t = BN_new();
        +
        +   /*
        +    * r in [0,q)
        +    * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform
        +    */
        +    BN_rand_range(r, ctx->p.q);
        +   /* g^r */
        +    BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);
        +
        +   /* h=hash... */
        +    zkp_hash(h, zkpg, p, ctx->p.name);
        +
        +   /* b = r - x*h */
        +    BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
        +    BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);
        +
        +   /* cleanup */
        +    BN_free(t);
        +    BN_free(h);
        +    BN_free(r);
        +    }
        +
        +static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
        +		      JPAKE_CTX *ctx)
        +    {
        +    BIGNUM *h = BN_new();
        +    BIGNUM *t1 = BN_new();
        +    BIGNUM *t2 = BN_new();
        +    BIGNUM *t3 = BN_new();
        +    int ret = 0;
        +
        +    zkp_hash(h, zkpg, p, ctx->p.peer_name);
        +
        +   /* t1 = g^b */
        +    BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
        +   /* t2 = (g^x)^h = g^{hx} */
        +    BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx);
        +   /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */
        +    BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx);
        +
        +   /* verify t3 == g^r */
        +    if(BN_cmp(t3, p->zkpx.gr) == 0)
        +	ret = 1;
        +    else
        +	JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);
        +
        +   /* cleanup */
        +    BN_free(t3);
        +    BN_free(t2);
        +    BN_free(t1);
        +    BN_free(h);
        +
        +    return ret;
        +    }    
        +
        +static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
        +			       const BIGNUM *g, JPAKE_CTX *ctx)
        +    {
        +    BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
        +    generate_zkp(p, x, g, ctx);
        +    }
        +
        +/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
        +static void genrand(JPAKE_CTX *ctx)
        +    {
        +    BIGNUM *qm1;
        +
        +   /* xa in [0, q) */
        +    BN_rand_range(ctx->xa, ctx->p.q);
        +
        +   /* q-1 */
        +    qm1 = BN_new();
        +    BN_copy(qm1, ctx->p.q);
        +    BN_sub_word(qm1, 1);
        +
        +   /* ... and xb in [0, q-1) */
        +    BN_rand_range(ctx->xb, qm1);
        +   /* [1, q) */
        +    BN_add_word(ctx->xb, 1);
        +
        +   /* cleanup */
        +    BN_free(qm1);
        +    }
        +
        +int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
        +    {
        +    genrand(ctx);
        +    generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
        +    generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);
        +
        +    return 1;
        +    }
        +
        +/* g^x is a legal value */
        +static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
        +    {
        +    BIGNUM *t;
        +    int res;
        +    
        +    if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
        +	return 0;
        +
        +    t = BN_new();
        +    BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
        +    res = BN_is_one(t);
        +    BN_free(t);
        +
        +    return res;
        +    }
        +
        +int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
        +    {
        +    if(!is_legal(received->p1.gx, ctx))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
        +	return 0;
        +	}
        +
        +    if(!is_legal(received->p2.gx, ctx))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
        +	return 0;
        +	}
        +
        +   /* verify their ZKP(xc) */
        +    if(!verify_zkp(&received->p1, ctx->p.g, ctx))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
        +	return 0;
        +	}
        +
        +   /* verify their ZKP(xd) */
        +    if(!verify_zkp(&received->p2, ctx->p.g, ctx))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
        +	return 0;
        +	}
        +
        +   /* g^xd != 1 */
        +    if(BN_is_one(received->p2.gx))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
        +	return 0;
        +	}
        +
        +   /* Save the bits we need for later */
        +    BN_copy(ctx->p.gxc, received->p1.gx);
        +    BN_copy(ctx->p.gxd, received->p2.gx);
        +
        +    return 1;
        +    }
        +
        +
        +int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
        +    {
        +    BIGNUM *t1 = BN_new();
        +    BIGNUM *t2 = BN_new();
        +
        +   /*
        +    * X = g^{(xa + xc + xd) * xb * s}
        +    * t1 = g^xa
        +    */
        +    BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx);
        +   /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */
        +    BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx);
        +   /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */
        +    BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx);
        +   /* t2 = xb * s */
        +    BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx);
        +
        +   /*
        +    * ZKP(xb * s)
        +    * XXX: this is kinda funky, because we're using
        +    *
        +    * g' = g^{xa + xc + xd}
        +    *
        +    * as the generator, which means X is g'^{xb * s}
        +    * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
        +    */
        +    generate_step_part(send, t2, t1, ctx);
        +
        +   /* cleanup */
        +    BN_free(t1);
        +    BN_free(t2);
        +
        +    return 1;
        +    }
        +
        +/* gx = g^{xc + xa + xb} * xd * s */
        +static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx)
        +    {
        +    BIGNUM *t1 = BN_new();
        +    BIGNUM *t2 = BN_new();
        +    BIGNUM *t3 = BN_new();
        +
        +   /*
        +    * K = (gx/g^{xb * xd * s})^{xb}
        +    *   = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb}
        +    *   = (g^{(xa + xc) * xd * s})^{xb}
        +    *   = g^{(xa + xc) * xb * xd * s}
        +    * [which is the same regardless of who calculates it]
        +    */
        +
        +   /* t1 = (g^{xd})^{xb} = g^{xb * xd} */
        +    BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx);
        +   /* t2 = -s = q-s */
        +    BN_sub(t2, ctx->p.q, ctx->secret);
        +   /* t3 = t1^t2 = g^{-xb * xd * s} */
        +    BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx);
        +   /* t1 = gx * t3 = X/g^{xb * xd * s} */
        +    BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx);
        +   /* K = t1^{xb} */
        +    BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx);
        +
        +   /* cleanup */
        +    BN_free(t3);
        +    BN_free(t2);
        +    BN_free(t1);
        +
        +    return 1;
        +    }
        +
        +int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
        +    {
        +    BIGNUM *t1 = BN_new();
        +    BIGNUM *t2 = BN_new();
        +    int ret = 0;
        +
        +   /*
        +    * g' = g^{xc + xa + xb} [from our POV]
        +    * t1 = xa + xb
        +    */
        +    BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
        +   /* t2 = g^{t1} = g^{xa+xb} */
        +    BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
        +   /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
        +    BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);
        +
        +    if(verify_zkp(received, t1, ctx))
        +	ret = 1;
        +    else
        +	JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);
        +
        +    compute_key(ctx, received->gx);
        +
        +   /* cleanup */
        +    BN_free(t2);
        +    BN_free(t1);
        +
        +    return ret;
        +    }
        +
        +static void quickhashbn(unsigned char *md, const BIGNUM *bn)
        +    {
        +    SHA_CTX sha;
        +
        +    SHA1_Init(&sha);
        +    hashbn(&sha, bn);
        +    SHA1_Final(md, &sha);
        +    }
        +
        +void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
        +    {}
        +
        +int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
        +    {
        +    quickhashbn(send->hhk, ctx->key);
        +    SHA1(send->hhk, sizeof send->hhk, send->hhk);
        +
        +    return 1;
        +    }
        +
        +int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received)
        +    {
        +    unsigned char hhk[SHA_DIGEST_LENGTH];
        +
        +    quickhashbn(hhk, ctx->key);
        +    SHA1(hhk, sizeof hhk, hhk);
        +    if(memcmp(hhk, received->hhk, sizeof hhk))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
        +	return 0;
        +	}
        +    return 1;
        +    }
        +
        +void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a)
        +    {}
        +
        +void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b)
        +    {}
        +
        +int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
        +    {
        +    quickhashbn(send->hk, ctx->key);
        +
        +    return 1;
        +    }
        +
        +int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received)
        +    {
        +    unsigned char hk[SHA_DIGEST_LENGTH];
        +
        +    quickhashbn(hk, ctx->key);
        +    if(memcmp(hk, received->hk, sizeof hk))
        +	{
        +	JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);
        +	return 0;
        +	}
        +    return 1;
        +    }
        +
        +void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b)
        +    {}
        +
        +const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx)
        +    {
        +    return ctx->key;
        +    }
        +
        diff --git a/vendor/openssl/openssl/crypto/jpake/jpake.h b/vendor/openssl/openssl/crypto/jpake/jpake.h
        new file mode 100644
        index 000000000..fd143b4d9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/jpake/jpake.h
        @@ -0,0 +1,131 @@
        +/*
        + * Implement J-PAKE, as described in
        + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
        + * 
        + * With hints from http://www.cl.cam.ac.uk/~fh240/software/JPAKE2.java.
        + */
        +
        +#ifndef HEADER_JPAKE_H
        +#define HEADER_JPAKE_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_JPAKE
        +#error JPAKE is disabled.
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#include <openssl/bn.h>
        +#include <openssl/sha.h>
        +
        +typedef struct JPAKE_CTX JPAKE_CTX;
        +
        +/* Note that "g" in the ZKPs is not necessarily the J-PAKE g. */
        +typedef struct
        +    {
        +    BIGNUM *gr; /* g^r (r random) */
        +    BIGNUM *b;  /* b = r - x*h, h=hash(g, g^r, g^x, name) */
        +    } JPAKE_ZKP;
        +
        +typedef struct
        +    {
        +    BIGNUM *gx;       /* g^x in step 1, g^(xa + xc + xd) * xb * s in step 2 */
        +    JPAKE_ZKP zkpx;   /* ZKP(x) or ZKP(xb * s) */
        +    } JPAKE_STEP_PART;
        +
        +typedef struct
        +    {
        +    JPAKE_STEP_PART p1;   /* g^x3, ZKP(x3) or g^x1, ZKP(x1) */
        +    JPAKE_STEP_PART p2;   /* g^x4, ZKP(x4) or g^x2, ZKP(x2) */
        +    } JPAKE_STEP1;
        +
        +typedef JPAKE_STEP_PART JPAKE_STEP2;
        +
        +typedef struct
        +    {
        +    unsigned char hhk[SHA_DIGEST_LENGTH];
        +    } JPAKE_STEP3A;
        +
        +typedef struct
        +    {
        +    unsigned char hk[SHA_DIGEST_LENGTH];
        +    } JPAKE_STEP3B;
        +
        +/* Parameters are copied */
        +JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
        +			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
        +			 const BIGNUM *secret);
        +void JPAKE_CTX_free(JPAKE_CTX *ctx);
        +
        +/*
        + * Note that JPAKE_STEP1 can be used multiple times before release
        + * without another init.
        + */
        +void JPAKE_STEP1_init(JPAKE_STEP1 *s1);
        +int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx);
        +int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received);
        +void JPAKE_STEP1_release(JPAKE_STEP1 *s1);
        +
        +/*
        + * Note that JPAKE_STEP2 can be used multiple times before release
        + * without another init.
        + */
        +void JPAKE_STEP2_init(JPAKE_STEP2 *s2);
        +int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx);
        +int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received);
        +void JPAKE_STEP2_release(JPAKE_STEP2 *s2);
        +
        +/*
        + * Optionally verify the shared key. If the shared secrets do not
        + * match, the two ends will disagree about the shared key, but
        + * otherwise the protocol will succeed.
        + */
        +void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a);
        +int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx);
        +int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received);
        +void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a);
        +
        +void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b);
        +int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx);
        +int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received);
        +void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b);
        +
        +/*
        + * the return value belongs to the library and will be released when
        + * ctx is released, and will change when a new handshake is performed.
        + */
        +const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_JPAKE_strings(void);
        +
        +/* Error codes for the JPAKE functions. */
        +
        +/* Function codes. */
        +#define JPAKE_F_JPAKE_STEP1_PROCESS			 101
        +#define JPAKE_F_JPAKE_STEP2_PROCESS			 102
        +#define JPAKE_F_JPAKE_STEP3A_PROCESS			 103
        +#define JPAKE_F_JPAKE_STEP3B_PROCESS			 104
        +#define JPAKE_F_VERIFY_ZKP				 100
        +
        +/* Reason codes. */
        +#define JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL		 108
        +#define JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL		 109
        +#define JPAKE_R_G_TO_THE_X4_IS_ONE			 105
        +#define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH		 106
        +#define JPAKE_R_HASH_OF_KEY_MISMATCH			 107
        +#define JPAKE_R_VERIFY_B_FAILED				 102
        +#define JPAKE_R_VERIFY_X3_FAILED			 103
        +#define JPAKE_R_VERIFY_X4_FAILED			 104
        +#define JPAKE_R_ZKP_VERIFY_FAILED			 100
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/jpake/jpake_err.c b/vendor/openssl/openssl/crypto/jpake/jpake_err.c
        new file mode 100644
        index 000000000..a9a9dee75
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/jpake/jpake_err.c
        @@ -0,0 +1,107 @@
        +/* crypto/jpake/jpake_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2010 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/jpake.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_JPAKE,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_JPAKE,0,reason)
        +
        +static ERR_STRING_DATA JPAKE_str_functs[]=
        +	{
        +{ERR_FUNC(JPAKE_F_JPAKE_STEP1_PROCESS),	"JPAKE_STEP1_process"},
        +{ERR_FUNC(JPAKE_F_JPAKE_STEP2_PROCESS),	"JPAKE_STEP2_process"},
        +{ERR_FUNC(JPAKE_F_JPAKE_STEP3A_PROCESS),	"JPAKE_STEP3A_process"},
        +{ERR_FUNC(JPAKE_F_JPAKE_STEP3B_PROCESS),	"JPAKE_STEP3B_process"},
        +{ERR_FUNC(JPAKE_F_VERIFY_ZKP),	"VERIFY_ZKP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA JPAKE_str_reasons[]=
        +	{
        +{ERR_REASON(JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL),"g to the x3 is not legal"},
        +{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL),"g to the x4 is not legal"},
        +{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE)  ,"g to the x4 is one"},
        +{ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH),"hash of hash of key mismatch"},
        +{ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH),"hash of key mismatch"},
        +{ERR_REASON(JPAKE_R_VERIFY_B_FAILED)     ,"verify b failed"},
        +{ERR_REASON(JPAKE_R_VERIFY_X3_FAILED)    ,"verify x3 failed"},
        +{ERR_REASON(JPAKE_R_VERIFY_X4_FAILED)    ,"verify x4 failed"},
        +{ERR_REASON(JPAKE_R_ZKP_VERIFY_FAILED)   ,"zkp verify failed"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_JPAKE_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(JPAKE_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,JPAKE_str_functs);
        +		ERR_load_strings(0,JPAKE_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/jpake/jpaketest.c b/vendor/openssl/openssl/crypto/jpake/jpaketest.c
        new file mode 100644
        index 000000000..eaba75ed8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/jpake/jpaketest.c
        @@ -0,0 +1,192 @@
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_JPAKE
        +
        +#include <stdio.h>
        +
        +int main(int argc, char *argv[])
        +{
        +    printf("No J-PAKE support\n");
        +    return(0);
        +}
        +
        +#else
        +
        +#include <openssl/jpake.h>
        +#include <openssl/err.h>
        +
        +static void showbn(const char *name, const BIGNUM *bn)
        +    {
        +    fputs(name, stdout);
        +    fputs(" = ", stdout);
        +    BN_print_fp(stdout, bn);
        +    putc('\n', stdout);
        +    }
        +
        +static int run_jpake(JPAKE_CTX *alice, JPAKE_CTX *bob)
        +    {
        +    JPAKE_STEP1 alice_s1;
        +    JPAKE_STEP1 bob_s1;
        +    JPAKE_STEP2 alice_s2;
        +    JPAKE_STEP2 bob_s2;
        +    JPAKE_STEP3A alice_s3a;
        +    JPAKE_STEP3B bob_s3b;
        +
        +   /* Alice -> Bob: step 1 */
        +    puts("A->B s1");
        +    JPAKE_STEP1_init(&alice_s1);
        +    JPAKE_STEP1_generate(&alice_s1, alice);
        +    if(!JPAKE_STEP1_process(bob, &alice_s1))
        +	{
        +	printf("Bob fails to process Alice's step 1\n");
        +	ERR_print_errors_fp(stdout);
        +	return 1;
        +	}
        +    JPAKE_STEP1_release(&alice_s1);
        +
        +   /* Bob -> Alice: step 1 */
        +    puts("B->A s1");
        +    JPAKE_STEP1_init(&bob_s1);
        +    JPAKE_STEP1_generate(&bob_s1, bob);
        +    if(!JPAKE_STEP1_process(alice, &bob_s1))
        +	{
        +	printf("Alice fails to process Bob's step 1\n");
        +	ERR_print_errors_fp(stdout);
        +	return 2;
        +	}
        +    JPAKE_STEP1_release(&bob_s1);
        +
        +   /* Alice -> Bob: step 2 */
        +    puts("A->B s2");
        +    JPAKE_STEP2_init(&alice_s2);
        +    JPAKE_STEP2_generate(&alice_s2, alice);
        +    if(!JPAKE_STEP2_process(bob, &alice_s2))
        +	{
        +	printf("Bob fails to process Alice's step 2\n");
        +	ERR_print_errors_fp(stdout);
        +	return 3;
        +	}
        +    JPAKE_STEP2_release(&alice_s2);
        +
        +   /* Bob -> Alice: step 2 */
        +    puts("B->A s2");
        +    JPAKE_STEP2_init(&bob_s2);
        +    JPAKE_STEP2_generate(&bob_s2, bob);
        +    if(!JPAKE_STEP2_process(alice, &bob_s2))
        +	{
        +	printf("Alice fails to process Bob's step 2\n");
        +	ERR_print_errors_fp(stdout);
        +	return 4;
        +	}
        +    JPAKE_STEP2_release(&bob_s2);
        +
        +    showbn("Alice's key", JPAKE_get_shared_key(alice));
        +    showbn("Bob's key  ", JPAKE_get_shared_key(bob));
        +
        +   /* Alice -> Bob: step 3a */
        +    puts("A->B s3a");
        +    JPAKE_STEP3A_init(&alice_s3a);
        +    JPAKE_STEP3A_generate(&alice_s3a, alice);
        +    if(!JPAKE_STEP3A_process(bob, &alice_s3a))
        +	{
        +	printf("Bob fails to process Alice's step 3a\n");
        +	ERR_print_errors_fp(stdout);
        +	return 5;
        +	}
        +    JPAKE_STEP3A_release(&alice_s3a);
        +    
        +   /* Bob -> Alice: step 3b */
        +    puts("B->A s3b");
        +    JPAKE_STEP3B_init(&bob_s3b);
        +    JPAKE_STEP3B_generate(&bob_s3b, bob);
        +    if(!JPAKE_STEP3B_process(alice, &bob_s3b))
        +	{
        +	printf("Alice fails to process Bob's step 3b\n");
        +	ERR_print_errors_fp(stdout);
        +	return 6;
        +	}
        +    JPAKE_STEP3B_release(&bob_s3b);
        +
        +    return 0;
        +    }
        +
        +int main(int argc, char **argv)
        +    {
        +    JPAKE_CTX *alice;
        +    JPAKE_CTX *bob;
        +    BIGNUM *p = NULL;
        +    BIGNUM *g = NULL;
        +    BIGNUM *q = NULL;
        +    BIGNUM *secret = BN_new();
        +    BIO *bio_err;
        +
        +    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +    CRYPTO_malloc_debug_init();
        +    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +    ERR_load_crypto_strings();
        +
        +    /*
        +    BN_hex2bn(&p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7");
        +    BN_hex2bn(&g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a");
        +    BN_hex2bn(&q, "9760508f15230bccb292b982a2eb840bf0581cf5");
        +    */
        +    /*
        +    p = BN_new();
        +    BN_generate_prime(p, 1024, 1, NULL, NULL, NULL, NULL);
        +    */
        +   /* Use a safe prime for p (that we found earlier) */
        +    BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
        +    showbn("p", p);
        +    g = BN_new();
        +    BN_set_word(g, 2);
        +    showbn("g", g);
        +    q = BN_new();
        +    BN_rshift1(q, p);
        +    showbn("q", q);
        +
        +    BN_rand(secret, 32, -1, 0);
        +
        +   /* A normal run, expect this to work... */
        +    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
        +    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
        +
        +    if(run_jpake(alice, bob) != 0)
        +	{
        +	fprintf(stderr, "Plain JPAKE run failed\n");
        +	return 1;
        +	}
        +
        +    JPAKE_CTX_free(bob);
        +    JPAKE_CTX_free(alice);
        +
        +   /* Now give Alice and Bob different secrets */
        +    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
        +    BN_add_word(secret, 1);
        +    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
        +
        +    if(run_jpake(alice, bob) != 5)
        +	{
        +	fprintf(stderr, "Mismatched secret JPAKE run failed\n");
        +	return 1;
        +	}
        +
        +    JPAKE_CTX_free(bob);
        +    JPAKE_CTX_free(alice);
        +
        +    BN_free(secret);
        +    BN_free(q);
        +    BN_free(g);
        +    BN_free(p);
        +
        +    CRYPTO_cleanup_all_ex_data();
        +    ERR_remove_thread_state(NULL);
        +    ERR_free_strings();
        +    CRYPTO_mem_leaks(bio_err);
        +
        +    return 0;
        +    }
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/krb5/Makefile b/vendor/openssl/openssl/crypto/krb5/Makefile
        new file mode 100644
        index 000000000..14077390d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/krb5/Makefile
        @@ -0,0 +1,84 @@
        +#
        +# OpenSSL/krb5/Makefile
        +#
        +
        +DIR=	krb5
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= krb5_asn.c
        +
        +LIBOBJ= krb5_asn.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= krb5_asn.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +krb5_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +krb5_asn.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +krb5_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/krb5_asn.h
        +krb5_asn.o: ../../include/openssl/opensslconf.h
        +krb5_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +krb5_asn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +krb5_asn.o: ../../include/openssl/symhacks.h krb5_asn.c
        diff --git a/vendor/openssl/openssl/crypto/krb5/krb5_asn.c b/vendor/openssl/openssl/crypto/krb5/krb5_asn.c
        new file mode 100644
        index 000000000..1fb741d2a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/krb5/krb5_asn.c
        @@ -0,0 +1,167 @@
        +/* krb5_asn.c */
        +/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
        +** using ocsp/{*.h,*asn*.c} as a starting point
        +*/
        +/* ====================================================================
        + * 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 <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/krb5_asn.h>
        +
        +
        +ASN1_SEQUENCE(KRB5_ENCDATA) = {
        +	ASN1_EXP(KRB5_ENCDATA, etype,		ASN1_INTEGER,	  0),
        +	ASN1_EXP_OPT(KRB5_ENCDATA, kvno,	ASN1_INTEGER,	  1),
        +	ASN1_EXP(KRB5_ENCDATA, cipher,		ASN1_OCTET_STRING,2)
        +} ASN1_SEQUENCE_END(KRB5_ENCDATA)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA)
        +
        +
        +ASN1_SEQUENCE(KRB5_PRINCNAME) = {
        +	ASN1_EXP(KRB5_PRINCNAME, nametype,	ASN1_INTEGER,	  0),
        +	ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1)
        +} ASN1_SEQUENCE_END(KRB5_PRINCNAME)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME)
        +
        +
        +/* [APPLICATION 1] = 0x61 */
        +ASN1_SEQUENCE(KRB5_TKTBODY) = {
        +	ASN1_EXP(KRB5_TKTBODY, tktvno,		ASN1_INTEGER,	  0),
        +	ASN1_EXP(KRB5_TKTBODY, realm, 		ASN1_GENERALSTRING, 1),
        +	ASN1_EXP(KRB5_TKTBODY, sname,		KRB5_PRINCNAME,	  2),
        +	ASN1_EXP(KRB5_TKTBODY, encdata,		KRB5_ENCDATA,	  3)
        +} ASN1_SEQUENCE_END(KRB5_TKTBODY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY)
        +
        +
        +ASN1_ITEM_TEMPLATE(KRB5_TICKET) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1,
        +			KRB5_TICKET, KRB5_TKTBODY)
        +ASN1_ITEM_TEMPLATE_END(KRB5_TICKET)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET)
        +
        +
        +/* [APPLICATION 14] = 0x6e */
        +ASN1_SEQUENCE(KRB5_APREQBODY) = {
        +	ASN1_EXP(KRB5_APREQBODY, pvno,		ASN1_INTEGER,	  0),
        +	ASN1_EXP(KRB5_APREQBODY, msgtype,	ASN1_INTEGER,	  1),
        +	ASN1_EXP(KRB5_APREQBODY, apoptions,	ASN1_BIT_STRING,  2),
        +	ASN1_EXP(KRB5_APREQBODY, ticket, 	KRB5_TICKET,	  3),
        +	ASN1_EXP(KRB5_APREQBODY, authenticator,	KRB5_ENCDATA,	  4),
        +} ASN1_SEQUENCE_END(KRB5_APREQBODY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY)
        +
        +ASN1_ITEM_TEMPLATE(KRB5_APREQ) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14,
        +			KRB5_APREQ, KRB5_APREQBODY)
        +ASN1_ITEM_TEMPLATE_END(KRB5_APREQ)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ)
        +
        +
        +/*  Authenticator stuff 	*/
        +
        +ASN1_SEQUENCE(KRB5_CHECKSUM) = {
        +	ASN1_EXP(KRB5_CHECKSUM, ctype,		ASN1_INTEGER,	  0),
        +	ASN1_EXP(KRB5_CHECKSUM, checksum,	ASN1_OCTET_STRING,1)
        +} ASN1_SEQUENCE_END(KRB5_CHECKSUM)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM)
        +
        +
        +ASN1_SEQUENCE(KRB5_ENCKEY) = {
        +	ASN1_EXP(KRB5_ENCKEY,	ktype,		ASN1_INTEGER,	  0),
        +	ASN1_EXP(KRB5_ENCKEY,	keyvalue,	ASN1_OCTET_STRING,1)
        +} ASN1_SEQUENCE_END(KRB5_ENCKEY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY)
        +
        +
        +/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */
        +ASN1_SEQUENCE(KRB5_AUTHDATA) = {
        +	ASN1_EXP(KRB5_AUTHDATA,	adtype,		ASN1_INTEGER,	  0),
        +	ASN1_EXP(KRB5_AUTHDATA,	addata, 	ASN1_OCTET_STRING,1)
        +} ASN1_SEQUENCE_END(KRB5_AUTHDATA)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA)
        +
        +
        +/* [APPLICATION 2] = 0x62 */
        +ASN1_SEQUENCE(KRB5_AUTHENTBODY) = {
        +	ASN1_EXP(KRB5_AUTHENTBODY,	avno,	ASN1_INTEGER,	  0),
        +	ASN1_EXP(KRB5_AUTHENTBODY,	crealm,	ASN1_GENERALSTRING, 1),
        +	ASN1_EXP(KRB5_AUTHENTBODY,	cname,	KRB5_PRINCNAME,	  2),
        +	ASN1_EXP_OPT(KRB5_AUTHENTBODY,	cksum,	KRB5_CHECKSUM,	  3),
        +	ASN1_EXP(KRB5_AUTHENTBODY,	cusec,	ASN1_INTEGER,	  4),
        +	ASN1_EXP(KRB5_AUTHENTBODY,	ctime,	ASN1_GENERALIZEDTIME, 5),
        +	ASN1_EXP_OPT(KRB5_AUTHENTBODY,	subkey,	KRB5_ENCKEY,	  6),
        +	ASN1_EXP_OPT(KRB5_AUTHENTBODY,	seqnum,	ASN1_INTEGER,	  7),
        +	ASN1_EXP_SEQUENCE_OF_OPT
        +		    (KRB5_AUTHENTBODY,	authorization,	KRB5_AUTHDATA, 8),
        +} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
        +
        +ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2,
        +			KRB5_AUTHENT, KRB5_AUTHENTBODY)
        +ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT)
        +
        diff --git a/vendor/openssl/openssl/crypto/krb5/krb5_asn.h b/vendor/openssl/openssl/crypto/krb5/krb5_asn.h
        new file mode 100644
        index 000000000..41725d0dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/krb5/krb5_asn.h
        @@ -0,0 +1,256 @@
        +/* krb5_asn.h */
        +/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
        +** using ocsp/{*.h,*asn*.c} as a starting point
        +*/
        +
        +/* ====================================================================
        + * 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_KRB5_ASN_H
        +#define HEADER_KRB5_ASN_H
        +
        +/*
        +#include <krb5.h>
        +*/
        +#include <openssl/safestack.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +/*	ASN.1 from Kerberos RFC 1510
        +*/
        +
        +/*	EncryptedData ::=   SEQUENCE {
        +**		etype[0]                      INTEGER, -- EncryptionType
        +**		kvno[1]                       INTEGER OPTIONAL,
        +**		cipher[2]                     OCTET STRING -- ciphertext
        +**	}
        +*/
        +typedef	struct	krb5_encdata_st
        +	{
        +	ASN1_INTEGER			*etype;
        +	ASN1_INTEGER			*kvno;
        +	ASN1_OCTET_STRING		*cipher;
        +	}	KRB5_ENCDATA;
        +
        +DECLARE_STACK_OF(KRB5_ENCDATA)
        +
        +/*	PrincipalName ::=   SEQUENCE {
        +**		name-type[0]                  INTEGER,
        +**		name-string[1]                SEQUENCE OF GeneralString
        +**	}
        +*/
        +typedef	struct	krb5_princname_st
        +	{
        +	ASN1_INTEGER			*nametype;
        +	STACK_OF(ASN1_GENERALSTRING)	*namestring;
        +	}	KRB5_PRINCNAME;
        +
        +DECLARE_STACK_OF(KRB5_PRINCNAME)
        +
        +
        +/*	Ticket ::=	[APPLICATION 1] SEQUENCE {
        +**		tkt-vno[0]                    INTEGER,
        +**		realm[1]                      Realm,
        +**		sname[2]                      PrincipalName,
        +**		enc-part[3]                   EncryptedData
        +**	}
        +*/
        +typedef	struct	krb5_tktbody_st
        +	{
        +	ASN1_INTEGER			*tktvno;
        +	ASN1_GENERALSTRING		*realm;
        +	KRB5_PRINCNAME			*sname;
        +	KRB5_ENCDATA			*encdata;
        +	}	KRB5_TKTBODY;
        +
        +typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
        +DECLARE_STACK_OF(KRB5_TKTBODY)
        +
        +
        +/*	AP-REQ ::=      [APPLICATION 14] SEQUENCE {
        +**		pvno[0]                       INTEGER,
        +**		msg-type[1]                   INTEGER,
        +**		ap-options[2]                 APOptions,
        +**		ticket[3]                     Ticket,
        +**		authenticator[4]              EncryptedData
        +**	}
        +**
        +**	APOptions ::=   BIT STRING {
        +**		reserved(0), use-session-key(1), mutual-required(2) }
        +*/
        +typedef	struct	krb5_ap_req_st
        +	{
        +	ASN1_INTEGER			*pvno;
        +	ASN1_INTEGER			*msgtype;
        +	ASN1_BIT_STRING			*apoptions;
        +	KRB5_TICKET			*ticket;
        +	KRB5_ENCDATA			*authenticator;
        +	}	KRB5_APREQBODY;
        +
        +typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
        +DECLARE_STACK_OF(KRB5_APREQBODY)
        +
        +
        +/*	Authenticator Stuff	*/
        +
        +
        +/*	Checksum ::=   SEQUENCE {
        +**		cksumtype[0]                  INTEGER,
        +**		checksum[1]                   OCTET STRING
        +**	}
        +*/
        +typedef	struct	krb5_checksum_st
        +	{
        +	ASN1_INTEGER			*ctype;
        +	ASN1_OCTET_STRING		*checksum;
        +	}	KRB5_CHECKSUM;
        +
        +DECLARE_STACK_OF(KRB5_CHECKSUM)
        +
        +
        +/*	EncryptionKey ::=   SEQUENCE {
        +**		keytype[0]                    INTEGER,
        +**		keyvalue[1]                   OCTET STRING
        +**	}
        +*/
        +typedef struct  krb5_encryptionkey_st
        +	{
        +	ASN1_INTEGER			*ktype;
        +	ASN1_OCTET_STRING		*keyvalue;
        +	}	KRB5_ENCKEY;
        +
        +DECLARE_STACK_OF(KRB5_ENCKEY)
        +
        +
        +/*	AuthorizationData ::=   SEQUENCE OF SEQUENCE {
        +**		ad-type[0]                    INTEGER,
        +**              ad-data[1]                    OCTET STRING
        +**	}
        +*/
        +typedef struct	krb5_authorization_st
        +	{
        +	ASN1_INTEGER			*adtype;
        +	ASN1_OCTET_STRING		*addata;
        +	}	KRB5_AUTHDATA;
        +
        +DECLARE_STACK_OF(KRB5_AUTHDATA)
        +
        +			
        +/*	-- Unencrypted authenticator
        +**	Authenticator ::=    [APPLICATION 2] SEQUENCE    {
        +**		authenticator-vno[0]          INTEGER,
        +**		crealm[1]                     Realm,
        +**		cname[2]                      PrincipalName,
        +**		cksum[3]                      Checksum OPTIONAL,
        +**		cusec[4]                      INTEGER,
        +**		ctime[5]                      KerberosTime,
        +**		subkey[6]                     EncryptionKey OPTIONAL,
        +**		seq-number[7]                 INTEGER OPTIONAL,
        +**		authorization-data[8]         AuthorizationData OPTIONAL
        +**	}
        +*/
        +typedef struct	krb5_authenticator_st
        +	{
        +	ASN1_INTEGER			*avno;
        +	ASN1_GENERALSTRING		*crealm;
        +	KRB5_PRINCNAME			*cname;
        +	KRB5_CHECKSUM			*cksum;
        +	ASN1_INTEGER			*cusec;
        +	ASN1_GENERALIZEDTIME		*ctime;
        +	KRB5_ENCKEY			*subkey;
        +	ASN1_INTEGER			*seqnum;
        +	KRB5_AUTHDATA			*authorization;
        +	}	KRB5_AUTHENTBODY;
        +
        +typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
        +DECLARE_STACK_OF(KRB5_AUTHENTBODY)
        +
        +
        +/*  DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
        +**	type *name##_new(void);
        +**	void name##_free(type *a);
        +**	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
        +**	 DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
        +**	  type *d2i_##name(type **a, const unsigned char **in, long len);
        +**	  int i2d_##name(type *a, unsigned char **out);
        +**	  DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
        +*/
        +
        +DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
        +DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
        +DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
        +DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
        +DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
        +DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)
        +
        +DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
        +DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
        +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
        +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
        +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)
        +
        +
        +/* 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.
        + */
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/lhash/Makefile b/vendor/openssl/openssl/crypto/lhash/Makefile
        new file mode 100644
        index 000000000..82bddac47
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/lhash/Makefile
        @@ -0,0 +1,88 @@
        +#
        +# OpenSSL/crypto/lhash/Makefile
        +#
        +
        +DIR=	lhash
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=lhash.c lh_stats.c
        +LIBOBJ=lhash.o lh_stats.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= lhash.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +lh_stats.o: ../../e_os.h ../../include/openssl/bio.h
        +lh_stats.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +lh_stats.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +lh_stats.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +lh_stats.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +lh_stats.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +lh_stats.o: ../../include/openssl/symhacks.h ../cryptlib.h lh_stats.c
        +lhash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +lhash.o: ../../include/openssl/e_os2.h ../../include/openssl/lhash.h
        +lhash.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +lhash.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +lhash.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h lhash.c
        diff --git a/vendor/openssl/openssl/crypto/lhash/lh_stats.c b/vendor/openssl/openssl/crypto/lhash/lh_stats.c
        new file mode 100644
        index 000000000..815615e33
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/lhash/lh_stats.c
        @@ -0,0 +1,248 @@
        +/* crypto/lhash/lh_stats.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +/* If you wish to build this outside of SSLeay, remove the following lines
        + * and things should work as expected */
        +#include "cryptlib.h"
        +
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/lhash.h>
        +
        +#ifdef OPENSSL_NO_BIO
        +
        +void lh_stats(LHASH *lh, FILE *out)
        +	{
        +	fprintf(out,"num_items             = %lu\n",lh->num_items);
        +	fprintf(out,"num_nodes             = %u\n",lh->num_nodes);
        +	fprintf(out,"num_alloc_nodes       = %u\n",lh->num_alloc_nodes);
        +	fprintf(out,"num_expands           = %lu\n",lh->num_expands);
        +	fprintf(out,"num_expand_reallocs   = %lu\n",lh->num_expand_reallocs);
        +	fprintf(out,"num_contracts         = %lu\n",lh->num_contracts);
        +	fprintf(out,"num_contract_reallocs = %lu\n",lh->num_contract_reallocs);
        +	fprintf(out,"num_hash_calls        = %lu\n",lh->num_hash_calls);
        +	fprintf(out,"num_comp_calls        = %lu\n",lh->num_comp_calls);
        +	fprintf(out,"num_insert            = %lu\n",lh->num_insert);
        +	fprintf(out,"num_replace           = %lu\n",lh->num_replace);
        +	fprintf(out,"num_delete            = %lu\n",lh->num_delete);
        +	fprintf(out,"num_no_delete         = %lu\n",lh->num_no_delete);
        +	fprintf(out,"num_retrieve          = %lu\n",lh->num_retrieve);
        +	fprintf(out,"num_retrieve_miss     = %lu\n",lh->num_retrieve_miss);
        +	fprintf(out,"num_hash_comps        = %lu\n",lh->num_hash_comps);
        +#if 0
        +	fprintf(out,"p                     = %u\n",lh->p);
        +	fprintf(out,"pmax                  = %u\n",lh->pmax);
        +	fprintf(out,"up_load               = %lu\n",lh->up_load);
        +	fprintf(out,"down_load             = %lu\n",lh->down_load);
        +#endif
        +	}
        +
        +void lh_node_stats(LHASH *lh, FILE *out)
        +	{
        +	LHASH_NODE *n;
        +	unsigned int i,num;
        +
        +	for (i=0; i<lh->num_nodes; i++)
        +		{
        +		for (n=lh->b[i],num=0; n != NULL; n=n->next)
        +			num++;
        +		fprintf(out,"node %6u -> %3u\n",i,num);
        +		}
        +	}
        +
        +void lh_node_usage_stats(LHASH *lh, FILE *out)
        +	{
        +	LHASH_NODE *n;
        +	unsigned long num;
        +	unsigned int i;
        +	unsigned long total=0,n_used=0;
        +
        +	for (i=0; i<lh->num_nodes; i++)
        +		{
        +		for (n=lh->b[i],num=0; n != NULL; n=n->next)
        +			num++;
        +		if (num != 0)
        +			{
        +			n_used++;
        +			total+=num;
        +			}
        +		}
        +	fprintf(out,"%lu nodes used out of %u\n",n_used,lh->num_nodes);
        +	fprintf(out,"%lu items\n",total);
        +	if (n_used == 0) return;
        +	fprintf(out,"load %d.%02d  actual load %d.%02d\n",
        +		(int)(total/lh->num_nodes),
        +		(int)((total%lh->num_nodes)*100/lh->num_nodes),
        +		(int)(total/n_used),
        +		(int)((total%n_used)*100/n_used));
        +	}
        +
        +#else
        +
        +#ifndef OPENSSL_NO_FP_API
        +void lh_stats(const _LHASH *lh, FILE *fp)
        +	{
        +	BIO *bp;
        +
        +	bp=BIO_new(BIO_s_file());
        +	if (bp == NULL) goto end;
        +	BIO_set_fp(bp,fp,BIO_NOCLOSE);
        +	lh_stats_bio(lh,bp);
        +	BIO_free(bp);
        +end:;
        +	}
        +
        +void lh_node_stats(const _LHASH *lh, FILE *fp)
        +	{
        +	BIO *bp;
        +
        +	bp=BIO_new(BIO_s_file());
        +	if (bp == NULL) goto end;
        +	BIO_set_fp(bp,fp,BIO_NOCLOSE);
        +	lh_node_stats_bio(lh,bp);
        +	BIO_free(bp);
        +end:;
        +	}
        +
        +void lh_node_usage_stats(const _LHASH *lh, FILE *fp)
        +	{
        +	BIO *bp;
        +
        +	bp=BIO_new(BIO_s_file());
        +	if (bp == NULL) goto end;
        +	BIO_set_fp(bp,fp,BIO_NOCLOSE);
        +	lh_node_usage_stats_bio(lh,bp);
        +	BIO_free(bp);
        +end:;
        +	}
        +
        +#endif
        +
        +void lh_stats_bio(const _LHASH *lh, BIO *out)
        +	{
        +	BIO_printf(out,"num_items             = %lu\n",lh->num_items);
        +	BIO_printf(out,"num_nodes             = %u\n",lh->num_nodes);
        +	BIO_printf(out,"num_alloc_nodes       = %u\n",lh->num_alloc_nodes);
        +	BIO_printf(out,"num_expands           = %lu\n",lh->num_expands);
        +	BIO_printf(out,"num_expand_reallocs   = %lu\n",
        +		   lh->num_expand_reallocs);
        +	BIO_printf(out,"num_contracts         = %lu\n",lh->num_contracts);
        +	BIO_printf(out,"num_contract_reallocs = %lu\n",
        +		   lh->num_contract_reallocs);
        +	BIO_printf(out,"num_hash_calls        = %lu\n",lh->num_hash_calls);
        +	BIO_printf(out,"num_comp_calls        = %lu\n",lh->num_comp_calls);
        +	BIO_printf(out,"num_insert            = %lu\n",lh->num_insert);
        +	BIO_printf(out,"num_replace           = %lu\n",lh->num_replace);
        +	BIO_printf(out,"num_delete            = %lu\n",lh->num_delete);
        +	BIO_printf(out,"num_no_delete         = %lu\n",lh->num_no_delete);
        +	BIO_printf(out,"num_retrieve          = %lu\n",lh->num_retrieve);
        +	BIO_printf(out,"num_retrieve_miss     = %lu\n",lh->num_retrieve_miss);
        +	BIO_printf(out,"num_hash_comps        = %lu\n",lh->num_hash_comps);
        +#if 0
        +	BIO_printf(out,"p                     = %u\n",lh->p);
        +	BIO_printf(out,"pmax                  = %u\n",lh->pmax);
        +	BIO_printf(out,"up_load               = %lu\n",lh->up_load);
        +	BIO_printf(out,"down_load             = %lu\n",lh->down_load);
        +#endif
        +	}
        +
        +void lh_node_stats_bio(const _LHASH *lh, BIO *out)
        +	{
        +	LHASH_NODE *n;
        +	unsigned int i,num;
        +
        +	for (i=0; i<lh->num_nodes; i++)
        +		{
        +		for (n=lh->b[i],num=0; n != NULL; n=n->next)
        +			num++;
        +		BIO_printf(out,"node %6u -> %3u\n",i,num);
        +		}
        +	}
        +
        +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out)
        +	{
        +	LHASH_NODE *n;
        +	unsigned long num;
        +	unsigned int i;
        +	unsigned long total=0,n_used=0;
        +
        +	for (i=0; i<lh->num_nodes; i++)
        +		{
        +		for (n=lh->b[i],num=0; n != NULL; n=n->next)
        +			num++;
        +		if (num != 0)
        +			{
        +			n_used++;
        +			total+=num;
        +			}
        +		}
        +	BIO_printf(out,"%lu nodes used out of %u\n",n_used,lh->num_nodes);
        +	BIO_printf(out,"%lu items\n",total);
        +	if (n_used == 0) return;
        +	BIO_printf(out,"load %d.%02d  actual load %d.%02d\n",
        +		   (int)(total/lh->num_nodes),
        +		   (int)((total%lh->num_nodes)*100/lh->num_nodes),
        +		   (int)(total/n_used),
        +		   (int)((total%n_used)*100/n_used));
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/lhash/lh_test.c b/vendor/openssl/openssl/crypto/lhash/lh_test.c
        new file mode 100644
        index 000000000..85700c859
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/lhash/lh_test.c
        @@ -0,0 +1,88 @@
        +/* crypto/lhash/lh_test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/lhash.h>
        +
        +main()
        +	{
        +	LHASH *conf;
        +	char buf[256];
        +	int i;
        +
        +	conf=lh_new(lh_strhash,strcmp);
        +	for (;;)
        +		{
        +		char *p;
        +
        +		buf[0]='\0';
        +		fgets(buf,256,stdin);
        +		if (buf[0] == '\0') break;
        +		i=strlen(buf);
        +		p=OPENSSL_malloc(i+1);
        +		memcpy(p,buf,i+1);
        +		lh_insert(conf,p);
        +		}
        +
        +	lh_node_stats(conf,stdout);
        +	lh_stats(conf,stdout);
        +	lh_node_usage_stats(conf,stdout);
        +	exit(0);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/lhash/lhash.c b/vendor/openssl/openssl/crypto/lhash/lhash.c
        new file mode 100644
        index 000000000..47f748081
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/lhash/lhash.c
        @@ -0,0 +1,475 @@
        +/* crypto/lhash/lhash.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Code for dynamic hash table routines
        + * Author - Eric Young v 2.0
        + *
        + * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
        + *	     present. eay 18-Jun-98
        + *
        + * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
        + *
        + * 2.0 eay - Fixed a bug that occurred when using lh_delete
        + *	     from inside lh_doall().  As entries were deleted,
        + *	     the 'table' was 'contract()ed', making some entries
        + *	     jump from the end of the table to the start, there by
        + *	     skipping the lh_doall() processing. eay - 4/12/95
        + *
        + * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
        + *	     were not being free()ed. 21/11/95
        + *
        + * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
        + *	     19/09/95
        + *
        + * 1.7 eay - Removed the fputs() for realloc failures - the code
        + *           should silently tolerate them.  I have also fixed things
        + *           lint complained about 04/05/95
        + *
        + * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
        + *
        + * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
        + *
        + * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
        + *
        + * 1.3 eay - Fixed a few lint problems 19/3/1991
        + *
        + * 1.2 eay - Fixed lh_doall problem 13/3/1991
        + *
        + * 1.1 eay - Added lh_doall
        + *
        + * 1.0 eay - First version
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include <openssl/crypto.h>
        +#include <openssl/lhash.h>
        +
        +const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT;
        +
        +#undef MIN_NODES 
        +#define MIN_NODES	16
        +#define UP_LOAD		(2*LH_LOAD_MULT) /* load times 256  (default 2) */
        +#define DOWN_LOAD	(LH_LOAD_MULT)   /* load times 256  (default 1) */
        +
        +static void expand(_LHASH *lh);
        +static void contract(_LHASH *lh);
        +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
        +
        +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
        +	{
        +	_LHASH *ret;
        +	int i;
        +
        +	if ((ret=OPENSSL_malloc(sizeof(_LHASH))) == NULL)
        +		goto err0;
        +	if ((ret->b=OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
        +		goto err1;
        +	for (i=0; i<MIN_NODES; i++)
        +		ret->b[i]=NULL;
        +	ret->comp=((c == NULL)?(LHASH_COMP_FN_TYPE)strcmp:c);
        +	ret->hash=((h == NULL)?(LHASH_HASH_FN_TYPE)lh_strhash:h);
        +	ret->num_nodes=MIN_NODES/2;
        +	ret->num_alloc_nodes=MIN_NODES;
        +	ret->p=0;
        +	ret->pmax=MIN_NODES/2;
        +	ret->up_load=UP_LOAD;
        +	ret->down_load=DOWN_LOAD;
        +	ret->num_items=0;
        +
        +	ret->num_expands=0;
        +	ret->num_expand_reallocs=0;
        +	ret->num_contracts=0;
        +	ret->num_contract_reallocs=0;
        +	ret->num_hash_calls=0;
        +	ret->num_comp_calls=0;
        +	ret->num_insert=0;
        +	ret->num_replace=0;
        +	ret->num_delete=0;
        +	ret->num_no_delete=0;
        +	ret->num_retrieve=0;
        +	ret->num_retrieve_miss=0;
        +	ret->num_hash_comps=0;
        +
        +	ret->error=0;
        +	return(ret);
        +err1:
        +	OPENSSL_free(ret);
        +err0:
        +	return(NULL);
        +	}
        +
        +void lh_free(_LHASH *lh)
        +	{
        +	unsigned int i;
        +	LHASH_NODE *n,*nn;
        +
        +	if (lh == NULL)
        +	    return;
        +
        +	for (i=0; i<lh->num_nodes; i++)
        +		{
        +		n=lh->b[i];
        +		while (n != NULL)
        +			{
        +			nn=n->next;
        +			OPENSSL_free(n);
        +			n=nn;
        +			}
        +		}
        +	OPENSSL_free(lh->b);
        +	OPENSSL_free(lh);
        +	}
        +
        +void *lh_insert(_LHASH *lh, void *data)
        +	{
        +	unsigned long hash;
        +	LHASH_NODE *nn,**rn;
        +	void *ret;
        +
        +	lh->error=0;
        +	if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))
        +		expand(lh);
        +
        +	rn=getrn(lh,data,&hash);
        +
        +	if (*rn == NULL)
        +		{
        +		if ((nn=(LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL)
        +			{
        +			lh->error++;
        +			return(NULL);
        +			}
        +		nn->data=data;
        +		nn->next=NULL;
        +#ifndef OPENSSL_NO_HASH_COMP
        +		nn->hash=hash;
        +#endif
        +		*rn=nn;
        +		ret=NULL;
        +		lh->num_insert++;
        +		lh->num_items++;
        +		}
        +	else /* replace same key */
        +		{
        +		ret= (*rn)->data;
        +		(*rn)->data=data;
        +		lh->num_replace++;
        +		}
        +	return(ret);
        +	}
        +
        +void *lh_delete(_LHASH *lh, const void *data)
        +	{
        +	unsigned long hash;
        +	LHASH_NODE *nn,**rn;
        +	void *ret;
        +
        +	lh->error=0;
        +	rn=getrn(lh,data,&hash);
        +
        +	if (*rn == NULL)
        +		{
        +		lh->num_no_delete++;
        +		return(NULL);
        +		}
        +	else
        +		{
        +		nn= *rn;
        +		*rn=nn->next;
        +		ret=nn->data;
        +		OPENSSL_free(nn);
        +		lh->num_delete++;
        +		}
        +
        +	lh->num_items--;
        +	if ((lh->num_nodes > MIN_NODES) &&
        +		(lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)))
        +		contract(lh);
        +
        +	return(ret);
        +	}
        +
        +void *lh_retrieve(_LHASH *lh, const void *data)
        +	{
        +	unsigned long hash;
        +	LHASH_NODE **rn;
        +	void *ret;
        +
        +	lh->error=0;
        +	rn=getrn(lh,data,&hash);
        +
        +	if (*rn == NULL)
        +		{
        +		lh->num_retrieve_miss++;
        +		return(NULL);
        +		}
        +	else
        +		{
        +		ret= (*rn)->data;
        +		lh->num_retrieve++;
        +		}
        +	return(ret);
        +	}
        +
        +static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
        +			  LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
        +	{
        +	int i;
        +	LHASH_NODE *a,*n;
        +
        +	if (lh == NULL)
        +		return;
        +
        +	/* reverse the order so we search from 'top to bottom'
        +	 * We were having memory leaks otherwise */
        +	for (i=lh->num_nodes-1; i>=0; i--)
        +		{
        +		a=lh->b[i];
        +		while (a != NULL)
        +			{
        +			/* 28/05/91 - eay - n added so items can be deleted
        +			 * via lh_doall */
        +			/* 22/05/08 - ben - eh? since a is not passed,
        +			 * this should not be needed */
        +			n=a->next;
        +			if(use_arg)
        +				func_arg(a->data,arg);
        +			else
        +				func(a->data);
        +			a=n;
        +			}
        +		}
        +	}
        +
        +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
        +	{
        +	doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
        +	}
        +
        +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
        +	{
        +	doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
        +	}
        +
        +static void expand(_LHASH *lh)
        +	{
        +	LHASH_NODE **n,**n1,**n2,*np;
        +	unsigned int p,i,j;
        +	unsigned long hash,nni;
        +
        +	lh->num_nodes++;
        +	lh->num_expands++;
        +	p=(int)lh->p++;
        +	n1= &(lh->b[p]);
        +	n2= &(lh->b[p+(int)lh->pmax]);
        +	*n2=NULL;        /* 27/07/92 - eay - undefined pointer bug */
        +	nni=lh->num_alloc_nodes;
        +	
        +	for (np= *n1; np != NULL; )
        +		{
        +#ifndef OPENSSL_NO_HASH_COMP
        +		hash=np->hash;
        +#else
        +		hash=lh->hash(np->data);
        +		lh->num_hash_calls++;
        +#endif
        +		if ((hash%nni) != p)
        +			{ /* move it */
        +			*n1= (*n1)->next;
        +			np->next= *n2;
        +			*n2=np;
        +			}
        +		else
        +			n1= &((*n1)->next);
        +		np= *n1;
        +		}
        +
        +	if ((lh->p) >= lh->pmax)
        +		{
        +		j=(int)lh->num_alloc_nodes*2;
        +		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
        +			(int)(sizeof(LHASH_NODE *)*j));
        +		if (n == NULL)
        +			{
        +/*			fputs("realloc error in lhash",stderr); */
        +			lh->error++;
        +			lh->p=0;
        +			return;
        +			}
        +		/* else */
        +		for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
        +			n[i]=NULL;			  /* 02/03/92 eay */
        +		lh->pmax=lh->num_alloc_nodes;
        +		lh->num_alloc_nodes=j;
        +		lh->num_expand_reallocs++;
        +		lh->p=0;
        +		lh->b=n;
        +		}
        +	}
        +
        +static void contract(_LHASH *lh)
        +	{
        +	LHASH_NODE **n,*n1,*np;
        +
        +	np=lh->b[lh->p+lh->pmax-1];
        +	lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
        +	if (lh->p == 0)
        +		{
        +		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
        +			(unsigned int)(sizeof(LHASH_NODE *)*lh->pmax));
        +		if (n == NULL)
        +			{
        +/*			fputs("realloc error in lhash",stderr); */
        +			lh->error++;
        +			return;
        +			}
        +		lh->num_contract_reallocs++;
        +		lh->num_alloc_nodes/=2;
        +		lh->pmax/=2;
        +		lh->p=lh->pmax-1;
        +		lh->b=n;
        +		}
        +	else
        +		lh->p--;
        +
        +	lh->num_nodes--;
        +	lh->num_contracts++;
        +
        +	n1=lh->b[(int)lh->p];
        +	if (n1 == NULL)
        +		lh->b[(int)lh->p]=np;
        +	else
        +		{
        +		while (n1->next != NULL)
        +			n1=n1->next;
        +		n1->next=np;
        +		}
        +	}
        +
        +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
        +	{
        +	LHASH_NODE **ret,*n1;
        +	unsigned long hash,nn;
        +	LHASH_COMP_FN_TYPE cf;
        +
        +	hash=(*(lh->hash))(data);
        +	lh->num_hash_calls++;
        +	*rhash=hash;
        +
        +	nn=hash%lh->pmax;
        +	if (nn < lh->p)
        +		nn=hash%lh->num_alloc_nodes;
        +
        +	cf=lh->comp;
        +	ret= &(lh->b[(int)nn]);
        +	for (n1= *ret; n1 != NULL; n1=n1->next)
        +		{
        +#ifndef OPENSSL_NO_HASH_COMP
        +		lh->num_hash_comps++;
        +		if (n1->hash != hash)
        +			{
        +			ret= &(n1->next);
        +			continue;
        +			}
        +#endif
        +		lh->num_comp_calls++;
        +		if(cf(n1->data,data) == 0)
        +			break;
        +		ret= &(n1->next);
        +		}
        +	return(ret);
        +	}
        +
        +/* The following hash seems to work very well on normal text strings
        + * no collisions on /usr/dict/words and it distributes on %2^n quite
        + * well, not as good as MD5, but still good.
        + */
        +unsigned long lh_strhash(const char *c)
        +	{
        +	unsigned long ret=0;
        +	long n;
        +	unsigned long v;
        +	int r;
        +
        +	if ((c == NULL) || (*c == '\0'))
        +		return(ret);
        +/*
        +	unsigned char b[16];
        +	MD5(c,strlen(c),b);
        +	return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); 
        +*/
        +
        +	n=0x100;
        +	while (*c)
        +		{
        +		v=n|(*c);
        +		n+=0x100;
        +		r= (int)((v>>2)^v)&0x0f;
        +		ret=(ret<<r)|(ret>>(32-r));
        +		ret&=0xFFFFFFFFL;
        +		ret^=v*v;
        +		c++;
        +		}
        +	return((ret>>16)^ret);
        +	}
        +
        +unsigned long lh_num_items(const _LHASH *lh)
        +	{
        +	return lh ? lh->num_items : 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/lhash/lhash.h b/vendor/openssl/openssl/crypto/lhash/lhash.h
        new file mode 100644
        index 000000000..e7d876359
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/lhash/lhash.h
        @@ -0,0 +1,241 @@
        +/* crypto/lhash/lhash.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Header for dynamic hash table routines
        + * Author - Eric Young
        + */
        +
        +#ifndef HEADER_LHASH_H
        +#define HEADER_LHASH_H
        +
        +#include <openssl/e_os2.h>
        +#ifndef OPENSSL_NO_FP_API
        +#include <stdio.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct lhash_node_st
        +	{
        +	void *data;
        +	struct lhash_node_st *next;
        +#ifndef OPENSSL_NO_HASH_COMP
        +	unsigned long hash;
        +#endif
        +	} LHASH_NODE;
        +
        +typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *);
        +typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *);
        +typedef void (*LHASH_DOALL_FN_TYPE)(void *);
        +typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *);
        +
        +/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks.
        + * This way, callbacks can be provided to LHASH structures without function
        + * pointer casting and the macro-defined callbacks provide per-variable casting
        + * before deferring to the underlying type-specific callbacks. NB: It is
        + * possible to place a "static" in front of both the DECLARE and IMPLEMENT
        + * macros if the functions are strictly internal. */
        +
        +/* First: "hash" functions */
        +#define DECLARE_LHASH_HASH_FN(name, o_type) \
        +	unsigned long name##_LHASH_HASH(const void *);
        +#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
        +	unsigned long name##_LHASH_HASH(const void *arg) { \
        +		const o_type *a = arg; \
        +		return name##_hash(a); }
        +#define LHASH_HASH_FN(name) name##_LHASH_HASH
        +
        +/* Second: "compare" functions */
        +#define DECLARE_LHASH_COMP_FN(name, o_type) \
        +	int name##_LHASH_COMP(const void *, const void *);
        +#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
        +	int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
        +		const o_type *a = arg1;		    \
        +		const o_type *b = arg2; \
        +		return name##_cmp(a,b); }
        +#define LHASH_COMP_FN(name) name##_LHASH_COMP
        +
        +/* Third: "doall" functions */
        +#define DECLARE_LHASH_DOALL_FN(name, o_type) \
        +	void name##_LHASH_DOALL(void *);
        +#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
        +	void name##_LHASH_DOALL(void *arg) { \
        +		o_type *a = arg; \
        +		name##_doall(a); }
        +#define LHASH_DOALL_FN(name) name##_LHASH_DOALL
        +
        +/* Fourth: "doall_arg" functions */
        +#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
        +	void name##_LHASH_DOALL_ARG(void *, void *);
        +#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
        +	void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
        +		o_type *a = arg1; \
        +		a_type *b = arg2; \
        +		name##_doall_arg(a, b); }
        +#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
        +
        +typedef struct lhash_st
        +	{
        +	LHASH_NODE **b;
        +	LHASH_COMP_FN_TYPE comp;
        +	LHASH_HASH_FN_TYPE hash;
        +	unsigned int num_nodes;
        +	unsigned int num_alloc_nodes;
        +	unsigned int p;
        +	unsigned int pmax;
        +	unsigned long up_load; /* load times 256 */
        +	unsigned long down_load; /* load times 256 */
        +	unsigned long num_items;
        +
        +	unsigned long num_expands;
        +	unsigned long num_expand_reallocs;
        +	unsigned long num_contracts;
        +	unsigned long num_contract_reallocs;
        +	unsigned long num_hash_calls;
        +	unsigned long num_comp_calls;
        +	unsigned long num_insert;
        +	unsigned long num_replace;
        +	unsigned long num_delete;
        +	unsigned long num_no_delete;
        +	unsigned long num_retrieve;
        +	unsigned long num_retrieve_miss;
        +	unsigned long num_hash_comps;
        +
        +	int error;
        +	} _LHASH;	/* Do not use _LHASH directly, use LHASH_OF
        +			 * and friends */
        +
        +#define LH_LOAD_MULT	256
        +
        +/* Indicates a malloc() error in the last call, this is only bad
        + * in lh_insert(). */
        +#define lh_error(lh)	((lh)->error)
        +
        +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
        +void lh_free(_LHASH *lh);
        +void *lh_insert(_LHASH *lh, void *data);
        +void *lh_delete(_LHASH *lh, const void *data);
        +void *lh_retrieve(_LHASH *lh, const void *data);
        +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
        +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
        +unsigned long lh_strhash(const char *c);
        +unsigned long lh_num_items(const _LHASH *lh);
        +
        +#ifndef OPENSSL_NO_FP_API
        +void lh_stats(const _LHASH *lh, FILE *out);
        +void lh_node_stats(const _LHASH *lh, FILE *out);
        +void lh_node_usage_stats(const _LHASH *lh, FILE *out);
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +void lh_stats_bio(const _LHASH *lh, BIO *out);
        +void lh_node_stats_bio(const _LHASH *lh, BIO *out);
        +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
        +#endif
        +
        +/* Type checking... */
        +
        +#define LHASH_OF(type) struct lhash_st_##type
        +
        +#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
        +
        +#define CHECKED_LHASH_OF(type,lh) \
        +  ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
        +
        +/* Define wrapper functions. */
        +#define LHM_lh_new(type, name) \
        +  ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
        +#define LHM_lh_error(type, lh) \
        +  lh_error(CHECKED_LHASH_OF(type,lh))
        +#define LHM_lh_insert(type, lh, inst) \
        +  ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
        +		     CHECKED_PTR_OF(type, inst)))
        +#define LHM_lh_retrieve(type, lh, inst) \
        +  ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
        +		       CHECKED_PTR_OF(type, inst)))
        +#define LHM_lh_delete(type, lh, inst) \
        +  ((type *)lh_delete(CHECKED_LHASH_OF(type, lh),			\
        +		     CHECKED_PTR_OF(type, inst)))
        +#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
        +#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
        +  lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
        +#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
        +#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
        +#define LHM_lh_node_stats_bio(type, lh, out) \
        +  lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
        +#define LHM_lh_node_usage_stats_bio(type, lh, out) \
        +  lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
        +#define LHM_lh_stats_bio(type, lh, out) \
        +  lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
        +#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
        +
        +DECLARE_LHASH_OF(OPENSSL_STRING);
        +DECLARE_LHASH_OF(OPENSSL_CSTRING);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/lhash/num.pl b/vendor/openssl/openssl/crypto/lhash/num.pl
        new file mode 100644
        index 000000000..30fedf9cd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/lhash/num.pl
        @@ -0,0 +1,17 @@
        +#!/usr/local/bin/perl
        +
        +#node     10 ->   4
        +
        +while (<>)
        +	{
        +	next unless /^node/;
        +	chop;
        +	@a=split;
        +	$num{$a[3]}++;
        +	}
        +
        +@a=sort {$a <=> $b } keys %num;
        +foreach (0 .. $a[$#a])
        +	{
        +	printf "%4d:%4d\n",$_,$num{$_};
        +	}
        diff --git a/vendor/openssl/openssl/crypto/md2/Makefile b/vendor/openssl/openssl/crypto/md2/Makefile
        new file mode 100644
        index 000000000..17f878aeb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md2/Makefile
        @@ -0,0 +1,89 @@
        +#
        +# OpenSSL/crypto/md/Makefile
        +#
        +
        +DIR=	md2
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=md2test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=md2_dgst.c md2_one.c
        +LIBOBJ=md2_dgst.o md2_one.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= md2.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +md2_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +md2_dgst.o: ../../include/openssl/md2.h ../../include/openssl/opensslconf.h
        +md2_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +md2_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +md2_dgst.o: ../../include/openssl/symhacks.h md2_dgst.c
        +md2_one.o: ../../e_os.h ../../include/openssl/bio.h
        +md2_one.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +md2_one.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +md2_one.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
        +md2_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +md2_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +md2_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +md2_one.o: ../cryptlib.h md2_one.c
        diff --git a/vendor/openssl/openssl/crypto/md2/md2.c b/vendor/openssl/openssl/crypto/md2/md2.c
        new file mode 100644
        index 000000000..f4d6f6226
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md2/md2.c
        @@ -0,0 +1,124 @@
        +/* crypto/md2/md2.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md2.h>
        +
        +#define BUFSIZE	1024*16
        +
        +void do_fp(FILE *f);
        +void pt(unsigned char *md);
        +int read(int, void *, unsigned int);
        +void exit(int);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	FILE *IN;
        +
        +	if (argc == 1)
        +		{
        +		do_fp(stdin);
        +		}
        +	else
        +		{
        +		for (i=1; i<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("MD2(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	return(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	MD2_CTX c;
        +	unsigned char md[MD2_DIGEST_LENGTH];
        +	int fd,i;
        +	static unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	MD2_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,BUFSIZE);
        +		if (i <= 0) break;
        +		MD2_Update(&c,buf,(unsigned long)i);
        +		}
        +	MD2_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<MD2_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        diff --git a/vendor/openssl/openssl/crypto/md2/md2.h b/vendor/openssl/openssl/crypto/md2/md2.h
        new file mode 100644
        index 000000000..d59c9f259
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md2/md2.h
        @@ -0,0 +1,95 @@
        +/* crypto/md/md2.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_MD2_H
        +#define HEADER_MD2_H
        +
        +#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
        +#ifdef OPENSSL_NO_MD2
        +#error MD2 is disabled.
        +#endif
        +#include <stddef.h>
        +
        +#define MD2_DIGEST_LENGTH	16
        +#define MD2_BLOCK       	16
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct MD2state_st
        +	{
        +	unsigned int num;
        +	unsigned char data[MD2_BLOCK];
        +	MD2_INT cksm[MD2_BLOCK];
        +	MD2_INT state[MD2_BLOCK];
        +	} MD2_CTX;
        +
        +const char *MD2_options(void);
        +#ifdef OPENSSL_FIPS
        +int private_MD2_Init(MD2_CTX *c);
        +#endif
        +int MD2_Init(MD2_CTX *c);
        +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
        +int MD2_Final(unsigned char *md, MD2_CTX *c);
        +unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md2/md2_dgst.c b/vendor/openssl/openssl/crypto/md2/md2_dgst.c
        new file mode 100644
        index 000000000..bf89def73
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md2/md2_dgst.c
        @@ -0,0 +1,227 @@
        +/* crypto/md2/md2_dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/md2.h>
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +
        +const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT;
        +
        +/* Implemented from RFC1319 The MD2 Message-Digest Algorithm
        + */
        +
        +#define UCHAR	unsigned char
        +
        +static void md2_block(MD2_CTX *c, const unsigned char *d);
        +/* The magic S table - I have converted it to hex since it is
        + * basically just a random byte string. */
        +static const MD2_INT S[256]={
        +	0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
        +	0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
        +	0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
        +	0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
        +	0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
        +	0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
        +	0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
        +	0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
        +	0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
        +	0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
        +	0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
        +	0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
        +	0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
        +	0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
        +	0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
        +	0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
        +	0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
        +	0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
        +	0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
        +	0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
        +	0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
        +	0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
        +	0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
        +	0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
        +	0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
        +	0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
        +	0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
        +	0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
        +	0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
        +	0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
        +	0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
        +	0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
        +	};
        +
        +const char *MD2_options(void)
        +	{
        +	if (sizeof(MD2_INT) == 1)
        +		return("md2(char)");
        +	else
        +		return("md2(int)");
        +	}
        +
        +fips_md_init(MD2)
        +	{
        +	c->num=0;
        +	memset(c->state,0,sizeof c->state);
        +	memset(c->cksm,0,sizeof c->cksm);
        +	memset(c->data,0,sizeof c->data);
        +	return 1;
        +	}
        +
        +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len)
        +	{
        +	register UCHAR *p;
        +
        +	if (len == 0) return 1;
        +
        +	p=c->data;
        +	if (c->num != 0)
        +		{
        +		if ((c->num+len) >= MD2_BLOCK)
        +			{
        +			memcpy(&(p[c->num]),data,MD2_BLOCK-c->num);
        +			md2_block(c,c->data);
        +			data+=(MD2_BLOCK - c->num);
        +			len-=(MD2_BLOCK - c->num);
        +			c->num=0;
        +			/* drop through and do the rest */
        +			}
        +		else
        +			{
        +			memcpy(&(p[c->num]),data,len);
        +			/* data+=len; */
        +			c->num+=(int)len;
        +			return 1;
        +			}
        +		}
        +	/* we now can process the input data in blocks of MD2_BLOCK
        +	 * chars and save the leftovers to c->data. */
        +	while (len >= MD2_BLOCK)
        +		{
        +		md2_block(c,data);
        +		data+=MD2_BLOCK;
        +		len-=MD2_BLOCK;
        +		}
        +	memcpy(p,data,len);
        +	c->num=(int)len;
        +	return 1;
        +	}
        +
        +static void md2_block(MD2_CTX *c, const unsigned char *d)
        +	{
        +	register MD2_INT t,*sp1,*sp2;
        +	register int i,j;
        +	MD2_INT state[48];
        +
        +	sp1=c->state;
        +	sp2=c->cksm;
        +	j=sp2[MD2_BLOCK-1];
        +	for (i=0; i<16; i++)
        +		{
        +		state[i]=sp1[i];
        +		state[i+16]=t=d[i];
        +		state[i+32]=(t^sp1[i]);
        +		j=sp2[i]^=S[t^j];
        +		}
        +	t=0;
        +	for (i=0; i<18; i++)
        +		{
        +		for (j=0; j<48; j+=8)
        +			{
        +			t= state[j+ 0]^=S[t];
        +			t= state[j+ 1]^=S[t];
        +			t= state[j+ 2]^=S[t];
        +			t= state[j+ 3]^=S[t];
        +			t= state[j+ 4]^=S[t];
        +			t= state[j+ 5]^=S[t];
        +			t= state[j+ 6]^=S[t];
        +			t= state[j+ 7]^=S[t];
        +			}
        +		t=(t+i)&0xff;
        +		}
        +	memcpy(sp1,state,16*sizeof(MD2_INT));
        +	OPENSSL_cleanse(state,48*sizeof(MD2_INT));
        +	}
        +
        +int MD2_Final(unsigned char *md, MD2_CTX *c)
        +	{
        +	int i,v;
        +	register UCHAR *cp;
        +	register MD2_INT *p1,*p2;
        +
        +	cp=c->data;
        +	p1=c->state;
        +	p2=c->cksm;
        +	v=MD2_BLOCK-c->num;
        +	for (i=c->num; i<MD2_BLOCK; i++)
        +		cp[i]=(UCHAR)v;
        +
        +	md2_block(c,cp);
        +
        +	for (i=0; i<MD2_BLOCK; i++)
        +		cp[i]=(UCHAR)p2[i];
        +	md2_block(c,cp);
        +
        +	for (i=0; i<16; i++)
        +		md[i]=(UCHAR)(p1[i]&0xff);
        +	memset((char *)&c,0,sizeof(c));
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md2/md2_one.c b/vendor/openssl/openssl/crypto/md2/md2_one.c
        new file mode 100644
        index 000000000..f7fef5cc0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md2/md2_one.c
        @@ -0,0 +1,94 @@
        +/* crypto/md2/md2_one.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/md2.h>
        +
        +/* This is a separate file so that #defines in cryptlib.h can
        + * map my MD functions to different names */
        +
        +unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	MD2_CTX c;
        +	static unsigned char m[MD2_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!MD2_Init(&c))
        +		return NULL;
        +#ifndef CHARSET_EBCDIC
        +	MD2_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);
        +			MD2_Update(&c,temp,chunk);
        +			n -= chunk;
        +			d += chunk;
        +		}
        +	}
        +#endif
        +	MD2_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));	/* Security consideration */
        +	return(md);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/md2/md2test.c b/vendor/openssl/openssl/crypto/md2/md2test.c
        new file mode 100644
        index 000000000..db5f5bc6d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md2/md2test.c
        @@ -0,0 +1,143 @@
        +/* crypto/md2/md2test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_MD2
        +int main(int argc, char *argv[])
        +{
        +    printf("No MD2 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/md2.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static char *test[]={
        +	"",
        +	"a",
        +	"abc",
        +	"message digest",
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        +	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
        +	NULL,
        +	};
        +
        +static char *ret[]={
        +	"8350e5a3e24c153df2275c9f80692773",
        +	"32ec01ec4a6dac72c0ab96fb34c0b5d1",
        +	"da853b0d3f88d99b30283a69e6ded6bb",
        +	"ab4f496bfb2a530b219ff33031fe06b0",
        +	"4e8ddff3650292ab5a4108c3aa47940b",
        +	"da33def2a42df13975352846c30338cd",
        +	"d5976f79d83d3a0dc9806c3c66f3efd8",
        +	};
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[MD2_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest((unsigned char *)*P,strlen(*P),md,NULL,EVP_md2(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,*R) != 0)
        +			{
        +			printf("error calculating MD2 on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return err;
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<MD2_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md32_common.h b/vendor/openssl/openssl/crypto/md32_common.h
        new file mode 100644
        index 000000000..bb7381952
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md32_common.h
        @@ -0,0 +1,415 @@
        +/* crypto/md32_common.h */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 is a generic 32 bit "collector" for message digest algorithms.
        + * Whenever needed it collects input character stream into chunks of
        + * 32 bit values and invokes a block function that performs actual hash
        + * calculations.
        + *
        + * Porting guide.
        + *
        + * Obligatory macros:
        + *
        + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
        + *	this macro defines byte order of input stream.
        + * HASH_CBLOCK
        + *	size of a unit chunk HASH_BLOCK operates on.
        + * HASH_LONG
        + *	has to be at lest 32 bit wide, if it's wider, then
        + *	HASH_LONG_LOG2 *has to* be defined along
        + * HASH_CTX
        + *	context structure that at least contains following
        + *	members:
        + *		typedef struct {
        + *			...
        + *			HASH_LONG	Nl,Nh;
        + *			either {
        + *			HASH_LONG	data[HASH_LBLOCK];
        + *			unsigned char	data[HASH_CBLOCK];
        + *			};
        + *			unsigned int	num;
        + *			...
        + *			} HASH_CTX;
        + *	data[] vector is expected to be zeroed upon first call to
        + *	HASH_UPDATE.
        + * HASH_UPDATE
        + *	name of "Update" function, implemented here.
        + * HASH_TRANSFORM
        + *	name of "Transform" function, implemented here.
        + * HASH_FINAL
        + *	name of "Final" function, implemented here.
        + * HASH_BLOCK_DATA_ORDER
        + *	name of "block" function capable of treating *unaligned* input
        + *	message in original (data) byte order, implemented externally.
        + * HASH_MAKE_STRING
        + *	macro convering context variables to an ASCII hash string.
        + *
        + * MD5 example:
        + *
        + *	#define DATA_ORDER_IS_LITTLE_ENDIAN
        + *
        + *	#define HASH_LONG		MD5_LONG
        + *	#define HASH_LONG_LOG2		MD5_LONG_LOG2
        + *	#define HASH_CTX		MD5_CTX
        + *	#define HASH_CBLOCK		MD5_CBLOCK
        + *	#define HASH_UPDATE		MD5_Update
        + *	#define HASH_TRANSFORM		MD5_Transform
        + *	#define HASH_FINAL		MD5_Final
        + *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order
        + *
        + *					<appro@fy.chalmers.se>
        + */
        +
        +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
        +#error "DATA_ORDER must be defined!"
        +#endif
        +
        +#ifndef HASH_CBLOCK
        +#error "HASH_CBLOCK must be defined!"
        +#endif
        +#ifndef HASH_LONG
        +#error "HASH_LONG must be defined!"
        +#endif
        +#ifndef HASH_CTX
        +#error "HASH_CTX must be defined!"
        +#endif
        +
        +#ifndef HASH_UPDATE
        +#error "HASH_UPDATE must be defined!"
        +#endif
        +#ifndef HASH_TRANSFORM
        +#error "HASH_TRANSFORM must be defined!"
        +#endif
        +#ifndef HASH_FINAL
        +#error "HASH_FINAL must be defined!"
        +#endif
        +
        +#ifndef HASH_BLOCK_DATA_ORDER
        +#error "HASH_BLOCK_DATA_ORDER must be defined!"
        +#endif
        +
        +/*
        + * Engage compiler specific rotate intrinsic function if available.
        + */
        +#undef ROTATE
        +#ifndef PEDANTIC
        +# if defined(_MSC_VER) || defined(__ICC)
        +#  define ROTATE(a,n)	_lrotl(a,n)
        +# elif defined(__MWERKS__)
        +#  if defined(__POWERPC__)
        +#   define ROTATE(a,n)	__rlwinm(a,n,0,31)
        +#  elif defined(__MC68K__)
        +    /* Motorola specific tweak. <appro@fy.chalmers.se> */
        +#   define ROTATE(a,n)	( n<24 ? __rol(a,n) : __ror(a,32-n) )
        +#  else
        +#   define ROTATE(a,n)	__rol(a,n)
        +#  endif
        +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +  /*
        +   * Some GNU C inline assembler templates. Note that these are
        +   * rotates by *constant* number of bits! But that's exactly
        +   * what we need here...
        +   * 					<appro@fy.chalmers.se>
        +   */
        +#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
        +#   define ROTATE(a,n)	({ register unsigned int ret;	\
        +				asm (			\
        +				"roll %1,%0"		\
        +				: "=r"(ret)		\
        +				: "I"(n), "0"((unsigned int)(a))	\
        +				: "cc");		\
        +			   ret;				\
        +			})
        +#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
        +	defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
        +#   define ROTATE(a,n)	({ register unsigned int ret;	\
        +				asm (			\
        +				"rlwinm %0,%1,%2,0,31"	\
        +				: "=r"(ret)		\
        +				: "r"(a), "I"(n));	\
        +			   ret;				\
        +			})
        +#  elif defined(__s390x__)
        +#   define ROTATE(a,n) ({ register unsigned int ret;	\
        +				asm ("rll %0,%1,%2"	\
        +				: "=r"(ret)		\
        +				: "r"(a), "I"(n));	\
        +			  ret;				\
        +			})
        +#  endif
        +# endif
        +#endif /* PEDANTIC */
        +
        +#ifndef ROTATE
        +#define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
        +#endif
        +
        +#if defined(DATA_ORDER_IS_BIG_ENDIAN)
        +
        +#ifndef PEDANTIC
        +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +#  if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
        +      (defined(__x86_64) || defined(__x86_64__))
        +#   if !defined(B_ENDIAN)
        +    /*
        +     * This gives ~30-40% performance improvement in SHA-256 compiled
        +     * with gcc [on P4]. Well, first macro to be frank. We can pull
        +     * this trick on x86* platforms only, because these CPUs can fetch
        +     * unaligned data without raising an exception.
        +     */
        +#   define HOST_c2l(c,l)	({ unsigned int r=*((const unsigned int *)(c));	\
        +				   asm ("bswapl %0":"=r"(r):"0"(r));	\
        +				   (c)+=4; (l)=r;			})
        +#   define HOST_l2c(l,c)	({ unsigned int r=(l);			\
        +				   asm ("bswapl %0":"=r"(r):"0"(r));	\
        +				   *((unsigned int *)(c))=r; (c)+=4; r;	})
        +#   endif
        +#  endif
        +# endif
        +#endif
        +#if defined(__s390__) || defined(__s390x__)
        +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
        +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
        +#endif
        +
        +#ifndef HOST_c2l
        +#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
        +			 l|=(((unsigned long)(*((c)++)))<<16),		\
        +			 l|=(((unsigned long)(*((c)++)))<< 8),		\
        +			 l|=(((unsigned long)(*((c)++)))    ),		\
        +			 l)
        +#endif
        +#ifndef HOST_l2c
        +#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
        +			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
        +			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
        +			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
        +			 l)
        +#endif
        +
        +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
        +
        +#ifndef PEDANTIC
        +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +#  if defined(__s390x__)
        +#   define HOST_c2l(c,l)	({ asm ("lrv	%0,%1"			\
        +				   :"=d"(l) :"m"(*(const unsigned int *)(c)));\
        +				   (c)+=4; (l);				})
        +#   define HOST_l2c(l,c)	({ asm ("strv	%1,%0"			\
        +				   :"=m"(*(unsigned int *)(c)) :"d"(l));\
        +				   (c)+=4; (l);				})
        +#  endif
        +# endif
        +#endif
        +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
        +# ifndef B_ENDIAN
        +   /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
        +#  define HOST_c2l(c,l)	((l)=*((const unsigned int *)(c)), (c)+=4, l)
        +#  define HOST_l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4, l)
        +# endif
        +#endif
        +
        +#ifndef HOST_c2l
        +#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
        +			 l|=(((unsigned long)(*((c)++)))<< 8),		\
        +			 l|=(((unsigned long)(*((c)++)))<<16),		\
        +			 l|=(((unsigned long)(*((c)++)))<<24),		\
        +			 l)
        +#endif
        +#ifndef HOST_l2c
        +#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
        +			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
        +			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
        +			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
        +			 l)
        +#endif
        +
        +#endif
        +
        +/*
        + * Time for some action:-)
        + */
        +
        +int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
        +	{
        +	const unsigned char *data=data_;
        +	unsigned char *p;
        +	HASH_LONG l;
        +	size_t n;
        +
        +	if (len==0) return 1;
        +
        +	l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
        +	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
        +	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
        +	if (l < c->Nl) /* overflow */
        +		c->Nh++;
        +	c->Nh+=(HASH_LONG)(len>>29);	/* might cause compiler warning on 16-bit */
        +	c->Nl=l;
        +
        +	n = c->num;
        +	if (n != 0)
        +		{
        +		p=(unsigned char *)c->data;
        +
        +		if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
        +			{
        +			memcpy (p+n,data,HASH_CBLOCK-n);
        +			HASH_BLOCK_DATA_ORDER (c,p,1);
        +			n      = HASH_CBLOCK-n;
        +			data  += n;
        +			len   -= n;
        +			c->num = 0;
        +			memset (p,0,HASH_CBLOCK);	/* keep it zeroed */
        +			}
        +		else
        +			{
        +			memcpy (p+n,data,len);
        +			c->num += (unsigned int)len;
        +			return 1;
        +			}
        +		}
        +
        +	n = len/HASH_CBLOCK;
        +	if (n > 0)
        +		{
        +		HASH_BLOCK_DATA_ORDER (c,data,n);
        +		n    *= HASH_CBLOCK;
        +		data += n;
        +		len  -= n;
        +		}
        +
        +	if (len != 0)
        +		{
        +		p = (unsigned char *)c->data;
        +		c->num = (unsigned int)len;
        +		memcpy (p,data,len);
        +		}
        +	return 1;
        +	}
        +
        +
        +void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
        +	{
        +	HASH_BLOCK_DATA_ORDER (c,data,1);
        +	}
        +
        +
        +int HASH_FINAL (unsigned char *md, HASH_CTX *c)
        +	{
        +	unsigned char *p = (unsigned char *)c->data;
        +	size_t n = c->num;
        +
        +	p[n] = 0x80; /* there is always room for one */
        +	n++;
        +
        +	if (n > (HASH_CBLOCK-8))
        +		{
        +		memset (p+n,0,HASH_CBLOCK-n);
        +		n=0;
        +		HASH_BLOCK_DATA_ORDER (c,p,1);
        +		}
        +	memset (p+n,0,HASH_CBLOCK-8-n);
        +
        +	p += HASH_CBLOCK-8;
        +#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
        +	(void)HOST_l2c(c->Nh,p);
        +	(void)HOST_l2c(c->Nl,p);
        +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
        +	(void)HOST_l2c(c->Nl,p);
        +	(void)HOST_l2c(c->Nh,p);
        +#endif
        +	p -= HASH_CBLOCK;
        +	HASH_BLOCK_DATA_ORDER (c,p,1);
        +	c->num=0;
        +	memset (p,0,HASH_CBLOCK);
        +
        +#ifndef HASH_MAKE_STRING
        +#error "HASH_MAKE_STRING must be defined!"
        +#else
        +	HASH_MAKE_STRING(c,md);
        +#endif
        +
        +	return 1;
        +	}
        +
        +#ifndef MD32_REG_T
        +#if defined(__alpha) || defined(__sparcv9) || defined(__mips)
        +#define MD32_REG_T long
        +/*
        + * This comment was originaly written for MD5, which is why it
        + * discusses A-D. But it basically applies to all 32-bit digests,
        + * which is why it was moved to common header file.
        + *
        + * In case you wonder why A-D are declared as long and not
        + * as MD5_LONG. Doing so results in slight performance
        + * boost on LP64 architectures. The catch is we don't
        + * really care if 32 MSBs of a 64-bit register get polluted
        + * with eventual overflows as we *save* only 32 LSBs in
        + * *either* case. Now declaring 'em long excuses the compiler
        + * from keeping 32 MSBs zeroed resulting in 13% performance
        + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
        + * Well, to be honest it should say that this *prevents* 
        + * performance degradation.
        + *				<appro@fy.chalmers.se>
        + */
        +#else
        +/*
        + * Above is not absolute and there are LP64 compilers that
        + * generate better code if MD32_REG_T is defined int. The above
        + * pre-processor condition reflects the circumstances under which
        + * the conclusion was made and is subject to further extension.
        + *				<appro@fy.chalmers.se>
        + */
        +#define MD32_REG_T int
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md4/Makefile b/vendor/openssl/openssl/crypto/md4/Makefile
        new file mode 100644
        index 000000000..e6f1e4478
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md4/Makefile
        @@ -0,0 +1,89 @@
        +#
        +# OpenSSL/crypto/md4/Makefile
        +#
        +
        +DIR=    md4
        +TOP=    ../..
        +CC=     cc
        +CPP=    $(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=       Makefile
        +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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +	rm -f ../../include/openssl/$(EXHEADER) ../../test/$(TEST) ../../apps/$(APPS)
        +
        +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/crypto.h ../../include/openssl/e_os2.h
        +md4_dgst.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
        +md4_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +md4_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +md4_dgst.o: ../../include/openssl/symhacks.h ../md32_common.h md4_dgst.c
        +md4_dgst.o: md4_locl.h
        +md4_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +md4_one.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
        +md4_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +md4_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +md4_one.o: ../../include/openssl/symhacks.h md4_one.c
        diff --git a/vendor/openssl/openssl/crypto/md4/md4.c b/vendor/openssl/openssl/crypto/md4/md4.c
        new file mode 100644
        index 000000000..141415ad4
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md4.h>
        +
        +#define BUFSIZE	1024*16
        +
        +void do_fp(FILE *f);
        +void pt(unsigned char *md);
        +#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
        +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<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("MD4(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	MD4_CTX c;
        +	unsigned char md[MD4_DIGEST_LENGTH];
        +	int fd;
        +	int i;
        +	static unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	MD4_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,sizeof buf);
        +		if (i <= 0) break;
        +		MD4_Update(&c,buf,(unsigned long)i);
        +		}
        +	MD4_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<MD4_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md4/md4.h b/vendor/openssl/openssl/crypto/md4/md4.h
        new file mode 100644
        index 000000000..a55368a79
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md4/md4.h
        @@ -0,0 +1,120 @@
        +/* crypto/md4/md4.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_MD4_H
        +#define HEADER_MD4_H
        +
        +#include <openssl/e_os2.h>
        +#include <stddef.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_NO_MD4
        +#error MD4 is disabled.
        +#endif
        +
        +/*
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then !
        + * ! MD4_LONG_LOG2 has to be defined along.			   !
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + */
        +
        +#if defined(__LP32__)
        +#define MD4_LONG unsigned long
        +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
        +#define MD4_LONG unsigned long
        +#define MD4_LONG_LOG2 3
        +/*
        + * _CRAY note. I could declare short, but I have no idea what impact
        + * does it have on performance on none-T3E machines. I could declare
        + * int, but at least on C90 sizeof(int) can be chosen at compile time.
        + * So I've chosen long...
        + *					<appro@fy.chalmers.se>
        + */
        +#else
        +#define 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];
        +	unsigned int num;
        +	} MD4_CTX;
        +
        +#ifdef OPENSSL_FIPS
        +int private_MD4_Init(MD4_CTX *c);
        +#endif
        +int MD4_Init(MD4_CTX *c);
        +int MD4_Update(MD4_CTX *c, const void *data, size_t len);
        +int MD4_Final(unsigned char *md, MD4_CTX *c);
        +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
        +void MD4_Transform(MD4_CTX *c, const unsigned char *b);
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md4/md4_dgst.c b/vendor/openssl/openssl/crypto/md4/md4_dgst.c
        new file mode 100644
        index 000000000..b5b165b05
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md4/md4_dgst.c
        @@ -0,0 +1,169 @@
        +/* 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 <stdio.h>
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +#include "md4_locl.h"
        +
        +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
        +
        +fips_md_init(MD4)
        +	{
        +	memset (c,0,sizeof(*c));
        +	c->A=INIT_DATA_A;
        +	c->B=INIT_DATA_B;
        +	c->C=INIT_DATA_C;
        +	c->D=INIT_DATA_D;
        +	return 1;
        +	}
        +
        +#ifndef md4_block_data_order
        +#ifdef X
        +#undef X
        +#endif
        +void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
        +	{
        +	const unsigned char *data=data_;
        +	register unsigned MD32_REG_T A,B,C,D,l;
        +#ifndef MD32_XARRAY
        +	/* See comment in crypto/sha/sha_locl.h for details. */
        +	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
        +				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
        +# define X(i)	XX##i
        +#else
        +	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--;)
        +		{
        +	(void)HOST_c2l(data,l); X( 0)=l;
        +	(void)HOST_c2l(data,l); X( 1)=l;
        +	/* Round 0 */
        +	R0(A,B,C,D,X( 0), 3,0);	(void)HOST_c2l(data,l); X( 2)=l;
        +	R0(D,A,B,C,X( 1), 7,0);	(void)HOST_c2l(data,l); X( 3)=l;
        +	R0(C,D,A,B,X( 2),11,0);	(void)HOST_c2l(data,l); X( 4)=l;
        +	R0(B,C,D,A,X( 3),19,0);	(void)HOST_c2l(data,l); X( 5)=l;
        +	R0(A,B,C,D,X( 4), 3,0);	(void)HOST_c2l(data,l); X( 6)=l;
        +	R0(D,A,B,C,X( 5), 7,0);	(void)HOST_c2l(data,l); X( 7)=l;
        +	R0(C,D,A,B,X( 6),11,0);	(void)HOST_c2l(data,l); X( 8)=l;
        +	R0(B,C,D,A,X( 7),19,0);	(void)HOST_c2l(data,l); X( 9)=l;
        +	R0(A,B,C,D,X( 8), 3,0);	(void)HOST_c2l(data,l); X(10)=l;
        +	R0(D,A,B,C,X( 9), 7,0);	(void)HOST_c2l(data,l); X(11)=l;
        +	R0(C,D,A,B,X(10),11,0);	(void)HOST_c2l(data,l); X(12)=l;
        +	R0(B,C,D,A,X(11),19,0);	(void)HOST_c2l(data,l); X(13)=l;
        +	R0(A,B,C,D,X(12), 3,0);	(void)HOST_c2l(data,l); X(14)=l;
        +	R0(D,A,B,C,X(13), 7,0);	(void)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
        diff --git a/vendor/openssl/openssl/crypto/md4/md4_locl.h b/vendor/openssl/openssl/crypto/md4/md4_locl.h
        new file mode 100644
        index 000000000..99c3e5004
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md4/md4_locl.h
        @@ -0,0 +1,112 @@
        +/* 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 <stdlib.h>
        +#include <string.h>
        +#include <openssl/opensslconf.h>
        +#include <openssl/md4.h>
        +
        +#ifndef MD4_LONG_LOG2
        +#define MD4_LONG_LOG2 2 /* default to 32 bits */
        +#endif
        +
        +void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
        +
        +#define DATA_ORDER_IS_LITTLE_ENDIAN
        +
        +#define HASH_LONG		MD4_LONG
        +#define HASH_CTX		MD4_CTX
        +#define HASH_CBLOCK		MD4_CBLOCK
        +#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; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
        +	} while (0)
        +#define	HASH_BLOCK_DATA_ORDER	md4_block_data_order
        +
        +#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 <weidai@eskimo.com>, the above can be
        + * simplified to the code below.  Wei attributes these optimizations
        + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
        + */
        +#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
        +#define G(b,c,d)	(((b) & (c)) | ((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/vendor/openssl/openssl/crypto/md4/md4_one.c b/vendor/openssl/openssl/crypto/md4/md4_one.c
        new file mode 100644
        index 000000000..bb6436263
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md4/md4_one.c
        @@ -0,0 +1,97 @@
        +/* 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 <stdio.h>
        +#include <string.h>
        +#include <openssl/md4.h>
        +#include <openssl/crypto.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	MD4_CTX c;
        +	static unsigned char m[MD4_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!MD4_Init(&c))
        +		return NULL;
        +#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);
        +	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
        +	return(md);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md4/md4s.cpp b/vendor/openssl/openssl/crypto/md4/md4s.cpp
        new file mode 100644
        index 000000000..c0ec97fc9
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md4.h>
        +
        +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/vendor/openssl/openssl/crypto/md4/md4test.c b/vendor/openssl/openssl/crypto/md4/md4test.c
        new file mode 100644
        index 000000000..56591728a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md4/md4test.c
        @@ -0,0 +1,136 @@
        +/* 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 <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_MD4
        +int main(int argc, char *argv[])
        +{
        +    printf("No MD4 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/md4.h>
        +
        +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;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[MD4_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md4(), NULL);
        +		p=pt(md);
        +		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<MD4_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md5/Makefile b/vendor/openssl/openssl/crypto/md5/Makefile
        new file mode 100644
        index 000000000..b9e2ce9a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/Makefile
        @@ -0,0 +1,102 @@
        +#
        +# OpenSSL/crypto/md5/Makefile
        +#
        +
        +DIR=    md5
        +TOP=    ../..
        +CC=     cc
        +CPP=    $(CC) -E
        +INCLUDES=-I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=       Makefile
        +AR=             ar r
        +
        +MD5_ASM_OBJ=
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=md5test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=md5_dgst.c md5_one.c
        +LIBOBJ=md5_dgst.o md5_one.o $(MD5_ASM_OBJ)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= md5.h
        +HEADER= md5_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) || echo Never mind.
        +	@touch lib
        +
        +md5-586.s:	asm/md5-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/md5-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
        +
        +md5-x86_64.s:	asm/md5-x86_64.pl
        +	$(PERL) asm/md5-x86_64.pl $(PERLASM_SCHEME) > $@
        +
        +md5-ia64.s: asm/md5-ia64.S
        +	$(CC) $(CFLAGS) -E asm/md5-ia64.S | \
        +	$(PERL) -ne 's/;\s+/;\n/g; print;' > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +md5_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +md5_dgst.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
        +md5_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +md5_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +md5_dgst.o: ../../include/openssl/symhacks.h ../md32_common.h md5_dgst.c
        +md5_dgst.o: md5_locl.h
        +md5_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +md5_one.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
        +md5_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +md5_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +md5_one.o: ../../include/openssl/symhacks.h md5_one.c
        diff --git a/vendor/openssl/openssl/crypto/md5/asm/md5-586.pl b/vendor/openssl/openssl/crypto/md5/asm/md5-586.pl
        new file mode 100644
        index 000000000..6cb66bb49
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/asm/md5-586.pl
        @@ -0,0 +1,307 @@
        +#!/usr/local/bin/perl
        +
        +# Normal is the
        +# md5_block_x86(MD5_CTX *c, ULONG *X);
        +# version, non-normal is the
        +# md5_block_x86(MD5_CTX *c, ULONG *X,int blocks);
        +
        +$normal=0;
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0);
        +
        +$A="eax";
        +$B="ebx";
        +$C="ecx";
        +$D="edx";
        +$tmp1="edi";
        +$tmp2="ebp";
        +$X="esi";
        +
        +# What we need to load into $tmp for the next round
        +%Ltmp1=("R0",&Np($C), "R1",&Np($C), "R2",&Np($C), "R3",&Np($D));
        +@xo=(
        + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,	# R0
        + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,	# R1
        + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,	# R2
        + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9,	# R3
        + );
        +
        +&md5_block("md5_block_asm_data_order");
        +&asm_finish();
        +
        +sub Np
        +	{
        +	local($p)=@_;
        +	local(%n)=($A,$D,$B,$A,$C,$B,$D,$C);
        +	return($n{$p});
        +	}
        +
        +sub R0
        +	{
        +	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
        +
        +	&mov($tmp1,$C)  if $pos < 0;
        +	&mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one 
        +
        +	# body proper
        +
        +	&comment("R0 $ki");
        +	&xor($tmp1,$d); # F function - part 2
        +
        +	&and($tmp1,$b); # F function - part 3
        +	&lea($a,&DWP($t,$a,$tmp2,1));
        +
        +	&xor($tmp1,$d); # F function - part 4
        +
        +	&add($a,$tmp1);
        +	&mov($tmp1,&Np($c)) if $pos < 1;	# next tmp1 for R0
        +	&mov($tmp1,&Np($c)) if $pos == 1;	# next tmp1 for R1
        +
        +	&rotl($a,$s);
        +
        +	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
        +
        +	&add($a,$b);
        +	}
        +
        +sub R1
        +	{
        +	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
        +
        +	&comment("R1 $ki");
        +
        +	&lea($a,&DWP($t,$a,$tmp2,1));
        +
        +	&xor($tmp1,$b); # G function - part 2
        +	&and($tmp1,$d); # G function - part 3
        +
        +	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
        +	&xor($tmp1,$c);			# G function - part 4
        +
        +	&add($a,$tmp1);
        +	&mov($tmp1,&Np($c)) if $pos < 1;	# G function - part 1
        +	&mov($tmp1,&Np($c)) if $pos == 1;	# G function - part 1
        +
        +	&rotl($a,$s);
        +
        +	&add($a,$b);
        +	}
        +
        +sub R2
        +	{
        +	local($n,$pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
        +	# This one is different, only 3 logical operations
        +
        +if (($n & 1) == 0)
        +	{
        +	&comment("R2 $ki");
        +	# make sure to do 'D' first, not 'B', else we clash with
        +	# the last add from the previous round.
        +
        +	&xor($tmp1,$d); # H function - part 2
        +
        +	&xor($tmp1,$b); # H function - part 3
        +	&lea($a,&DWP($t,$a,$tmp2,1));
        +
        +	&add($a,$tmp1);
        +
        +	&rotl($a,$s);
        +
        +	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0));
        +	&mov($tmp1,&Np($c));
        +	}
        +else
        +	{
        +	&comment("R2 $ki");
        +	# make sure to do 'D' first, not 'B', else we clash with
        +	# the last add from the previous round.
        +
        +	&lea($a,&DWP($t,$a,$tmp2,1));
        +
        +	&add($b,$c);			# MOVED FORWARD
        +	&xor($tmp1,$d); # H function - part 2
        +
        +	&xor($tmp1,$b); # H function - part 3
        +	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
        +
        +	&add($a,$tmp1);
        +	&mov($tmp1,&Np($c)) if $pos < 1;	# H function - part 1
        +	&mov($tmp1,-1) if $pos == 1;		# I function - part 1
        +
        +	&rotl($a,$s);
        +
        +	&add($a,$b);
        +	}
        +	}
        +
        +sub R3
        +	{
        +	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
        +
        +	&comment("R3 $ki");
        +
        +	# &not($tmp1)
        +	&xor($tmp1,$d) if $pos < 0; 	# I function - part 2
        +
        +	&or($tmp1,$b);				# I function - part 3
        +	&lea($a,&DWP($t,$a,$tmp2,1));
        +
        +	&xor($tmp1,$c); 			# I function - part 4
        +	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0))	if $pos != 2; # load X/k value
        +	&mov($tmp2,&wparam(0)) if $pos == 2;
        +
        +	&add($a,$tmp1);
        +	&mov($tmp1,-1) if $pos < 1;	# H function - part 1
        +	&add($K,64) if $pos >=1 && !$normal;
        +
        +	&rotl($a,$s);
        +
        +	&xor($tmp1,&Np($d)) if $pos <= 0; 	# I function - part = first time
        +	&mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0;
        +	&add($a,$b);
        +	}
        +
        +
        +sub md5_block
        +	{
        +	local($name)=@_;
        +
        +	&function_begin_B($name,"",3);
        +
        +	# parameter 1 is the MD5_CTX structure.
        +	# A	0
        +	# B	4
        +	# C	8
        +	# D 	12
        +
        +	&push("esi");
        +	 &push("edi");
        +	&mov($tmp1,	&wparam(0)); # edi
        +	 &mov($X,	&wparam(1)); # esi
        +	&mov($C,	&wparam(2));
        +	 &push("ebp");
        +	&shl($C,	6);
        +	&push("ebx");
        +	 &add($C,	$X); # offset we end at
        +	&sub($C,	64);
        +	 &mov($A,	&DWP( 0,$tmp1,"",0));
        +	&push($C);	# Put on the TOS
        +	 &mov($B,	&DWP( 4,$tmp1,"",0));
        +	&mov($C,	&DWP( 8,$tmp1,"",0));
        +	 &mov($D,	&DWP(12,$tmp1,"",0));
        +
        +	&set_label("start") unless $normal;
        +	&comment("");
        +	&comment("R0 section");
        +
        +	&R0(-2,$A,$B,$C,$D,$X, 0, 7,0xd76aa478);
        +	&R0( 0,$D,$A,$B,$C,$X, 1,12,0xe8c7b756);
        +	&R0( 0,$C,$D,$A,$B,$X, 2,17,0x242070db);
        +	&R0( 0,$B,$C,$D,$A,$X, 3,22,0xc1bdceee);
        +	&R0( 0,$A,$B,$C,$D,$X, 4, 7,0xf57c0faf);
        +	&R0( 0,$D,$A,$B,$C,$X, 5,12,0x4787c62a);
        +	&R0( 0,$C,$D,$A,$B,$X, 6,17,0xa8304613);
        +	&R0( 0,$B,$C,$D,$A,$X, 7,22,0xfd469501);
        +	&R0( 0,$A,$B,$C,$D,$X, 8, 7,0x698098d8);
        +	&R0( 0,$D,$A,$B,$C,$X, 9,12,0x8b44f7af);
        +	&R0( 0,$C,$D,$A,$B,$X,10,17,0xffff5bb1);
        +	&R0( 0,$B,$C,$D,$A,$X,11,22,0x895cd7be);
        +	&R0( 0,$A,$B,$C,$D,$X,12, 7,0x6b901122);
        +	&R0( 0,$D,$A,$B,$C,$X,13,12,0xfd987193);
        +	&R0( 0,$C,$D,$A,$B,$X,14,17,0xa679438e);
        +	&R0( 1,$B,$C,$D,$A,$X,15,22,0x49b40821);
        +
        +	&comment("");
        +	&comment("R1 section");
        +	&R1(-1,$A,$B,$C,$D,$X,16, 5,0xf61e2562);
        +	&R1( 0,$D,$A,$B,$C,$X,17, 9,0xc040b340);
        +	&R1( 0,$C,$D,$A,$B,$X,18,14,0x265e5a51);
        +	&R1( 0,$B,$C,$D,$A,$X,19,20,0xe9b6c7aa);
        +	&R1( 0,$A,$B,$C,$D,$X,20, 5,0xd62f105d);
        +	&R1( 0,$D,$A,$B,$C,$X,21, 9,0x02441453);
        +	&R1( 0,$C,$D,$A,$B,$X,22,14,0xd8a1e681);
        +	&R1( 0,$B,$C,$D,$A,$X,23,20,0xe7d3fbc8);
        +	&R1( 0,$A,$B,$C,$D,$X,24, 5,0x21e1cde6);
        +	&R1( 0,$D,$A,$B,$C,$X,25, 9,0xc33707d6);
        +	&R1( 0,$C,$D,$A,$B,$X,26,14,0xf4d50d87);
        +	&R1( 0,$B,$C,$D,$A,$X,27,20,0x455a14ed);
        +	&R1( 0,$A,$B,$C,$D,$X,28, 5,0xa9e3e905);
        +	&R1( 0,$D,$A,$B,$C,$X,29, 9,0xfcefa3f8);
        +	&R1( 0,$C,$D,$A,$B,$X,30,14,0x676f02d9);
        +	&R1( 1,$B,$C,$D,$A,$X,31,20,0x8d2a4c8a);
        +
        +	&comment("");
        +	&comment("R2 section");
        +	&R2( 0,-1,$A,$B,$C,$D,$X,32, 4,0xfffa3942);
        +	&R2( 1, 0,$D,$A,$B,$C,$X,33,11,0x8771f681);
        +	&R2( 2, 0,$C,$D,$A,$B,$X,34,16,0x6d9d6122);
        +	&R2( 3, 0,$B,$C,$D,$A,$X,35,23,0xfde5380c);
        +	&R2( 4, 0,$A,$B,$C,$D,$X,36, 4,0xa4beea44);
        +	&R2( 5, 0,$D,$A,$B,$C,$X,37,11,0x4bdecfa9);
        +	&R2( 6, 0,$C,$D,$A,$B,$X,38,16,0xf6bb4b60);
        +	&R2( 7, 0,$B,$C,$D,$A,$X,39,23,0xbebfbc70);
        +	&R2( 8, 0,$A,$B,$C,$D,$X,40, 4,0x289b7ec6);
        +	&R2( 9, 0,$D,$A,$B,$C,$X,41,11,0xeaa127fa);
        +	&R2(10, 0,$C,$D,$A,$B,$X,42,16,0xd4ef3085);
        +	&R2(11, 0,$B,$C,$D,$A,$X,43,23,0x04881d05);
        +	&R2(12, 0,$A,$B,$C,$D,$X,44, 4,0xd9d4d039);
        +	&R2(13, 0,$D,$A,$B,$C,$X,45,11,0xe6db99e5);
        +	&R2(14, 0,$C,$D,$A,$B,$X,46,16,0x1fa27cf8);
        +	&R2(15, 1,$B,$C,$D,$A,$X,47,23,0xc4ac5665);
        +
        +	&comment("");
        +	&comment("R3 section");
        +	&R3(-1,$A,$B,$C,$D,$X,48, 6,0xf4292244);
        +	&R3( 0,$D,$A,$B,$C,$X,49,10,0x432aff97);
        +	&R3( 0,$C,$D,$A,$B,$X,50,15,0xab9423a7);
        +	&R3( 0,$B,$C,$D,$A,$X,51,21,0xfc93a039);
        +	&R3( 0,$A,$B,$C,$D,$X,52, 6,0x655b59c3);
        +	&R3( 0,$D,$A,$B,$C,$X,53,10,0x8f0ccc92);
        +	&R3( 0,$C,$D,$A,$B,$X,54,15,0xffeff47d);
        +	&R3( 0,$B,$C,$D,$A,$X,55,21,0x85845dd1);
        +	&R3( 0,$A,$B,$C,$D,$X,56, 6,0x6fa87e4f);
        +	&R3( 0,$D,$A,$B,$C,$X,57,10,0xfe2ce6e0);
        +	&R3( 0,$C,$D,$A,$B,$X,58,15,0xa3014314);
        +	&R3( 0,$B,$C,$D,$A,$X,59,21,0x4e0811a1);
        +	&R3( 0,$A,$B,$C,$D,$X,60, 6,0xf7537e82);
        +	&R3( 0,$D,$A,$B,$C,$X,61,10,0xbd3af235);
        +	&R3( 0,$C,$D,$A,$B,$X,62,15,0x2ad7d2bb);
        +	&R3( 2,$B,$C,$D,$A,$X,63,21,0xeb86d391);
        +
        +	# &mov($tmp2,&wparam(0));	# done in the last R3
        +	# &mov($tmp1,	&DWP( 0,$tmp2,"",0)); # done is the last R3
        +
        +	&add($A,$tmp1);
        +	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));
        +
        +	&add($B,$tmp1);
        +	&mov($tmp1,	&DWP( 8,$tmp2,"",0));
        +
        +	&add($C,$tmp1);
        +	&mov($tmp1,	&DWP(12,$tmp2,"",0));
        +
        +	&add($D,$tmp1);
        +	&mov(&DWP( 0,$tmp2,"",0),$A);
        +
        +	&mov(&DWP( 4,$tmp2,"",0),$B);
        +	&mov($tmp1,&swtmp(0)) unless $normal;
        +
        +	&mov(&DWP( 8,$tmp2,"",0),$C);
        +	 &mov(&DWP(12,$tmp2,"",0),$D);
        +
        +	&cmp($tmp1,$X) unless $normal;			# check count
        +	 &jae(&label("start")) unless $normal;
        +
        +	&pop("eax"); # pop the temp variable off the stack
        +	 &pop("ebx");
        +	&pop("ebp");
        +	 &pop("edi");
        +	&pop("esi");
        +	 &ret();
        +	&function_end_B($name);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md5/asm/md5-ia64.S b/vendor/openssl/openssl/crypto/md5/asm/md5-ia64.S
        new file mode 100644
        index 000000000..e7de08d46
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/asm/md5-ia64.S
        @@ -0,0 +1,992 @@
        +/* Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
        +
        +Permission is hereby granted, free of charge, to any person obtaining
        +a copy of this software and associated documentation files (the
        +"Software"), to deal in the Software without restriction, including
        +without limitation the rights to use, copy, modify, merge, publish,
        +distribute, sublicense, and/or sell copies of the Software, and to
        +permit persons to whom the Software is furnished to do so, subject to
        +the following conditions:
        +
        +The above copyright notice and this permission notice shall be
        +included in all copies or substantial portions of the Software.
        +
        +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
        +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
        +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
        +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
        +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
        +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
        +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
        +
        +//	Common registers are assigned as follows:
        +//
        +//	COMMON
        +//
        +//	t0		Const Tbl Ptr	TPtr
        +//	t1		Round Constant	TRound
        +//	t4		Block residual	LenResid
        +//	t5		Residual Data	DTmp
        +//
        +//	{in,out}0	Block 0 Cycle	RotateM0
        +//	{in,out}1	Block Value 12	M12
        +//	{in,out}2	Block Value 8	M8
        +//	{in,out}3	Block Value 4	M4
        +//	{in,out}4	Block Value 0	M0
        +//	{in,out}5	Block 1 Cycle	RotateM1
        +//	{in,out}6	Block Value 13	M13
        +//	{in,out}7	Block Value 9	M9
        +//	{in,out}8	Block Value 5	M5
        +//	{in,out}9	Block Value 1	M1
        +//	{in,out}10	Block 2 Cycle	RotateM2
        +//	{in,out}11	Block Value 14	M14
        +//	{in,out}12	Block Value 10	M10
        +//	{in,out}13	Block Value 6	M6
        +//	{in,out}14	Block Value 2	M2
        +//	{in,out}15	Block 3 Cycle	RotateM3
        +//	{in,out}16	Block Value 15	M15
        +//	{in,out}17	Block Value 11	M11
        +//	{in,out}18	Block Value 7	M7
        +//	{in,out}19	Block Value 3	M3
        +//	{in,out}20	Scratch			Z
        +//	{in,out}21	Scratch			Y
        +//	{in,out}22	Scratch			X
        +//	{in,out}23	Scratch			W
        +//	{in,out}24	Digest A		A
        +//	{in,out}25	Digest B		B
        +//	{in,out}26	Digest C		C
        +//	{in,out}27	Digest D		D
        +//	{in,out}28	Active Data Ptr	DPtr
        +//	in28		Dummy Value		-
        +//	out28		Dummy Value		-
        +//	bt0			Coroutine Link	QUICK_RTN
        +//
        +///	These predicates are used for computing the padding block(s) and
        +///	are shared between the driver and digest co-routines
        +//
        +//	pt0			Extra Pad Block	pExtra
        +//	pt1			Load next word	pLoad
        +//	pt2			Skip next word	pSkip
        +//	pt3			Search for Pad	pNoPad
        +//	pt4			Pad Word 0		pPad0
        +//	pt5			Pad Word 1		pPad1
        +//	pt6			Pad Word 2		pPad2
        +//	pt7			Pad Word 3		pPad3
        +
        +#define	DTmp		r19
        +#define	LenResid	r18
        +#define	QUICK_RTN	b6
        +#define	TPtr		r14
        +#define	TRound		r15
        +#define	pExtra		p6
        +#define	pLoad		p7
        +#define	pNoPad		p9
        +#define	pPad0		p10
        +#define	pPad1		p11
        +#define	pPad2		p12
        +#define	pPad3		p13
        +#define	pSkip		p8
        +
        +#define	A_		out24
        +#define	B_		out25
        +#define	C_		out26
        +#define	D_		out27
        +#define	DPtr_		out28
        +#define	M0_		out4
        +#define	M1_		out9
        +#define	M10_		out12
        +#define	M11_		out17
        +#define	M12_		out1
        +#define	M13_		out6
        +#define	M14_		out11
        +#define	M15_		out16
        +#define	M2_		out14
        +#define	M3_		out19
        +#define	M4_		out3
        +#define	M5_		out8
        +#define	M6_		out13
        +#define	M7_		out18
        +#define	M8_		out2
        +#define	M9_		out7
        +#define	RotateM0_	out0
        +#define	RotateM1_	out5
        +#define	RotateM2_	out10
        +#define	RotateM3_	out15
        +#define	W_		out23
        +#define	X_		out22
        +#define	Y_		out21
        +#define	Z_		out20
        +
        +#define	A		in24
        +#define	B		in25
        +#define	C		in26
        +#define	D		in27
        +#define	DPtr		in28
        +#define	M0		in4
        +#define	M1		in9
        +#define	M10		in12
        +#define	M11		in17
        +#define	M12		in1
        +#define	M13		in6
        +#define	M14		in11
        +#define	M15		in16
        +#define	M2		in14
        +#define	M3		in19
        +#define	M4		in3
        +#define	M5		in8
        +#define	M6		in13
        +#define	M7		in18
        +#define	M8		in2
        +#define	M9		in7
        +#define	RotateM0	in0
        +#define	RotateM1	in5
        +#define	RotateM2	in10
        +#define	RotateM3	in15
        +#define	W		in23
        +#define	X		in22
        +#define	Y		in21
        +#define	Z		in20
        +
        +/* register stack configuration for md5_block_asm_data_order(): */
        +#define	MD5_NINP	3
        +#define	MD5_NLOC	0
        +#define MD5_NOUT	29
        +#define MD5_NROT	0
        +
        +/* register stack configuration for helpers: */
        +#define	_NINPUTS	MD5_NOUT
        +#define	_NLOCALS	0
        +#define _NOUTPUT	0
        +#define	_NROTATE	24	/* this must be <= _NINPUTS */
        +
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +#define	ADDP	addp4
        +#else
        +#define	ADDP	add
        +#endif
        +
        +#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
        +#define HOST_IS_BIG_ENDIAN
        +#endif
        +
        +//	Macros for getting the left and right portions of little-endian words
        +
        +#define	GETLW(dst, src, align)	dep.z dst = src, 32 - 8 * align, 8 * align
        +#define	GETRW(dst, src, align)	extr.u dst = src, 8 * align, 32 - 8 * align
        +
        +//	MD5 driver
        +//
        +//		Reads an input block, then calls the digest block
        +//		subroutine and adds the results to the accumulated
        +//		digest.  It allocates 32 outs which the subroutine
        +//		uses as it's inputs and rotating
        +//		registers. Initializes the round constant pointer and
        +//		takes care of saving/restoring ar.lc
        +//
        +///	INPUT
        +//
        +//	in0		Context Ptr		CtxPtr0
        +//	in1		Input Data Ptr		DPtrIn
        +//	in2		Integral Blocks		BlockCount
        +//	rp		Return Address		-
        +//
        +///	CODE
        +//
        +//	v2		Input Align		InAlign
        +//	t0		Shared w/digest		-
        +//	t1		Shared w/digest		-
        +//	t2		Shared w/digest		-
        +//	t3		Shared w/digest		-
        +//	t4		Shared w/digest		-
        +//	t5		Shared w/digest		-
        +//	t6		PFS Save		PFSSave
        +//	t7		ar.lc Save		LCSave
        +//	t8		Saved PR		PRSave
        +//	t9		2nd CtxPtr		CtxPtr1
        +//	t10		Table Base		CTable
        +//	t11		Table[0]		CTable0
        +//	t13		Accumulator A		AccumA
        +//	t14		Accumulator B		AccumB
        +//	t15		Accumulator C		AccumC
        +//	t16		Accumulator D		AccumD
        +//	pt0		Shared w/digest		-
        +//	pt1		Shared w/digest		-
        +//	pt2		Shared w/digest		-
        +//	pt3		Shared w/digest		-
        +//	pt4		Shared w/digest		-
        +//	pt5		Shared w/digest		-
        +//	pt6		Shared w/digest		-
        +//	pt7		Shared w/digest		-
        +//	pt8		Not Aligned		pOff
        +//	pt8		Blocks Left		pAgain
        +
        +#define	AccumA		r27
        +#define	AccumB		r28
        +#define	AccumC		r29
        +#define	AccumD		r30
        +#define	CTable		r24
        +#define	CTable0		r25
        +#define	CtxPtr0		in0
        +#define	CtxPtr1		r23
        +#define	DPtrIn		in1
        +#define	BlockCount	in2
        +#define	InAlign		r10
        +#define	LCSave		r21
        +#define	PFSSave		r20
        +#define	PRSave		r22
        +#define	pAgain		p63
        +#define	pOff		p63
        +
        +	.text
        +
        +/* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num)
        +
        +     where:
        +      c: a pointer to a structure of this type:
        +
        +	   typedef struct MD5state_st
        +	     {
        +	       MD5_LONG A,B,C,D;
        +	       MD5_LONG Nl,Nh;
        +	       MD5_LONG data[MD5_LBLOCK];
        +	       unsigned int num;
        +	     }
        +	   MD5_CTX;
        +
        +      data: a pointer to the input data (may be misaligned)
        +      num:  the number of 16-byte blocks to hash (i.e., the length
        +            of DATA is 16*NUM.
        +
        +   */
        +
        +	.type	md5_block_asm_data_order, @function
        +	.global	md5_block_asm_data_order
        +	.align	32
        +	.proc	md5_block_asm_data_order
        +md5_block_asm_data_order:
        +.md5_block:
        +	.prologue
        +{	.mmi
        +	.save	ar.pfs, PFSSave
        +	alloc	PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT
        +	ADDP	CtxPtr1 = 8, CtxPtr0
        +	mov	CTable = ip
        +}
        +{	.mmi
        +	ADDP	DPtrIn = 0, DPtrIn
        +	ADDP	CtxPtr0 = 0, CtxPtr0
        +	.save	ar.lc, LCSave
        +	mov	LCSave = ar.lc
        +}
        +;;
        +{	.mmi
        +	add	CTable = .md5_tbl_data_order#-.md5_block#, CTable
        +	and	InAlign = 0x3, DPtrIn
        +}
        +
        +{	.mmi
        +	ld4	AccumA = [CtxPtr0], 4
        +	ld4	AccumC = [CtxPtr1], 4
        +	.save pr, PRSave
        +	mov	PRSave = pr
        +	.body
        +}
        +;;
        +{	.mmi
        +	ld4	AccumB = [CtxPtr0]
        +	ld4	AccumD = [CtxPtr1]
        +	dep	DPtr_ = 0, DPtrIn, 0, 2
        +} ;;
        +#ifdef HOST_IS_BIG_ENDIAN
        +	rum	psr.be;;	// switch to little-endian
        +#endif
        +{	.mmb
        +	ld4	CTable0 = [CTable], 4
        +	cmp.ne	pOff, p0 = 0, InAlign
        +(pOff)	br.cond.spnt.many .md5_unaligned
        +} ;;
        +
        +//	The FF load/compute loop rotates values three times, so that
        +//	loading into M12 here produces the M0 value, M13 -> M1, etc.
        +
        +.md5_block_loop0:
        +{	.mmi
        +	ld4	M12_ = [DPtr_], 4
        +	mov	TPtr = CTable
        +	mov	TRound = CTable0
        +} ;;
        +{	.mmi
        +	ld4	M13_ = [DPtr_], 4
        +	mov	A_ = AccumA
        +	mov	B_ = AccumB
        +} ;;
        +{	.mmi
        +	ld4	M14_ = [DPtr_], 4
        +	mov	C_ = AccumC
        +	mov	D_ = AccumD
        +} ;;
        +{	.mmb
        +	ld4	M15_ = [DPtr_], 4
        +	add	BlockCount = -1, BlockCount
        +	br.call.sptk.many QUICK_RTN = md5_digest_block0
        +} ;;
        +
        +//	Now, we add the new digest values and do some clean-up
        +//	before checking if there's another full block to process
        +
        +{	.mmi
        +	add	AccumA = AccumA, A_
        +	add	AccumB = AccumB, B_
        +	cmp.ne	pAgain, p0 = 0, BlockCount
        +}
        +{	.mib
        +	add	AccumC = AccumC, C_
        +	add	AccumD = AccumD, D_
        +(pAgain) br.cond.dptk.many .md5_block_loop0
        +} ;;
        +
        +.md5_exit:
        +#ifdef HOST_IS_BIG_ENDIAN
        +	sum	psr.be;;	// switch back to big-endian mode
        +#endif
        +{	.mmi
        +	st4	[CtxPtr0] = AccumB, -4
        +	st4	[CtxPtr1] = AccumD, -4
        +	mov	pr = PRSave, 0x1ffff ;;
        +}
        +{	.mmi
        +	st4	[CtxPtr0] = AccumA
        +	st4	[CtxPtr1] = AccumC
        +	mov	ar.lc = LCSave
        +} ;;
        +{	.mib
        +	mov	ar.pfs = PFSSave
        +	br.ret.sptk.few	rp
        +} ;;
        +
        +#define	MD5UNALIGNED(offset)						\
        +.md5_process##offset:							\
        +{	.mib ;								\
        +	nop	0x0	;						\
        +	GETRW(DTmp, DTmp, offset) ;					\
        +} ;;									\
        +.md5_block_loop##offset:						\
        +{	.mmi ;								\
        +	ld4	Y_ = [DPtr_], 4 ;					\
        +	mov	TPtr = CTable ;						\
        +	mov	TRound = CTable0 ;					\
        +} ;;									\
        +{	.mmi ;								\
        +	ld4	M13_ = [DPtr_], 4 ;					\
        +	mov	A_ = AccumA ;						\
        +	mov	B_ = AccumB ;						\
        +} ;;									\
        +{	.mii ;								\
        +	ld4	M14_ = [DPtr_], 4 ;					\
        +	GETLW(W_, Y_, offset) ;						\
        +	mov	C_ = AccumC ;						\
        +}									\
        +{	.mmi ;								\
        +	mov	D_ = AccumD ;;						\
        +	or	M12_ = W_, DTmp ;					\
        +	GETRW(DTmp, Y_, offset) ;					\
        +}									\
        +{	.mib ;								\
        +	ld4	M15_ = [DPtr_], 4 ;					\
        +	add	BlockCount = -1, BlockCount ;				\
        +	br.call.sptk.many QUICK_RTN = md5_digest_block##offset;		\
        +} ;;									\
        +{	.mmi ;								\
        +	add	AccumA = AccumA, A_ ;					\
        +	add	AccumB = AccumB, B_ ;					\
        +	cmp.ne	pAgain, p0 = 0, BlockCount ;				\
        +}									\
        +{	.mib ;								\
        +	add	AccumC = AccumC, C_ ;					\
        +	add	AccumD = AccumD, D_ ;					\
        +(pAgain) br.cond.dptk.many .md5_block_loop##offset ;			\
        +} ;;									\
        +{	.mib ;								\
        +	nop	0x0 ;							\
        +	nop	0x0 ;							\
        +	br.cond.sptk.many .md5_exit ;					\
        +} ;;
        +
        +	.align	32
        +.md5_unaligned:
        +//
        +//	Because variable shifts are expensive, we special case each of
        +//	the four alignements. In practice, this won't hurt too much
        +//	since only one working set of code will be loaded.
        +//
        +{	.mib
        +	ld4	DTmp = [DPtr_], 4
        +	cmp.eq	pOff, p0 = 1, InAlign
        +(pOff)	br.cond.dpnt.many .md5_process1
        +} ;;
        +{	.mib
        +	cmp.eq	pOff, p0 = 2, InAlign
        +	nop	0x0
        +(pOff)	br.cond.dpnt.many .md5_process2
        +} ;;
        +	MD5UNALIGNED(3)
        +	MD5UNALIGNED(1)
        +	MD5UNALIGNED(2)
        +
        +	.endp md5_block_asm_data_order
        +
        +
        +// MD5 Perform the F function and load
        +//
        +// Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values,
        +// computes the FF() round of functions, then branches to the common
        +// digest code to finish up with GG(), HH, and II().
        +//
        +// INPUT
        +//
        +// rp Return Address -
        +//
        +// CODE
        +//
        +// v0 PFS bit bucket PFS
        +// v1 Loop Trip Count LTrip
        +// pt0 Load next word pMore
        +
        +/* For F round: */
        +#define LTrip	r9
        +#define PFS	r8
        +#define pMore	p6
        +
        +/* For GHI rounds: */
        +#define T	r9
        +#define U	r10
        +#define V	r11
        +
        +#define COMPUTE(a, b, s, M, R)			\
        +{						\
        +	.mii ;					\
        +	ld4 TRound = [TPtr], 4 ;		\
        +	dep.z Y = Z, 32, 32 ;;			\
        +	shrp Z = Z, Y, 64 - s ;			\
        +} ;;						\
        +{						\
        +	.mmi ;					\
        +	add a = Z, b ;				\
        +	mov R = M ;				\
        +	nop 0x0 ;				\
        +} ;;
        +
        +#define LOOP(a, b, s, M, R, label)		\
        +{	.mii ;					\
        +	ld4 TRound = [TPtr], 4 ;		\
        +	dep.z Y = Z, 32, 32 ;;			\
        +	shrp Z = Z, Y, 64 - s ;			\
        +} ;;						\
        +{	.mib ;					\
        +	add a = Z, b ;				\
        +	mov R = M ;				\
        +	br.ctop.sptk.many label ;		\
        +} ;;
        +
        +// G(B, C, D) = (B & D) | (C & ~D)
        +
        +#define G(a, b, c, d, M)			\
        +{	.mmi ;					\
        +	add Z = M, TRound ;			\
        +	and Y = b, d ;				\
        +	andcm X = c, d ;			\
        +} ;;						\
        +{	.mii ;					\
        +	add Z = Z, a ;				\
        +	or Y = Y, X ;;				\
        +	add Z = Z, Y ;				\
        +} ;;
        +
        +// H(B, C, D) = B ^ C ^ D
        +
        +#define H(a, b, c, d, M)			\
        +{	.mmi ;					\
        +	add Z = M, TRound ;			\
        +	xor Y = b, c ;				\
        +	nop 0x0 ;				\
        +} ;;						\
        +{	.mii ;					\
        +	add Z = Z, a ;				\
        +	xor Y = Y, d ;;				\
        +	add Z = Z, Y ;				\
        +} ;;
        +
        +// I(B, C, D) = C ^ (B | ~D)
        +//
        +// However, since we have an andcm operator, we use the fact that
        +//
        +// Y ^ Z == ~Y ^ ~Z
        +//
        +// to rewrite the expression as
        +//
        +// I(B, C, D) = ~C ^ (~B & D)
        +
        +#define I(a, b, c, d, M)			\
        +{	.mmi ;					\
        +	add Z = M, TRound ;			\
        +	andcm Y = d, b ;			\
        +	andcm X = -1, c ;			\
        +} ;;						\
        +{	.mii ;					\
        +	add Z = Z, a ;				\
        +	xor Y = Y, X ;;				\
        +	add Z = Z, Y ;				\
        +} ;;
        +
        +#define GG4(label)				\
        +	G(A, B, C, D, M0)			\
        +	COMPUTE(A, B, 5, M0, RotateM0)		\
        +	G(D, A, B, C, M1)			\
        +	COMPUTE(D, A, 9, M1, RotateM1)		\
        +	G(C, D, A, B, M2)			\
        +	COMPUTE(C, D, 14, M2, RotateM2)		\
        +	G(B, C, D, A, M3)			\
        +	LOOP(B, C, 20, M3, RotateM3, label)
        +
        +#define HH4(label)				\
        +	H(A, B, C, D, M0)			\
        +	COMPUTE(A, B, 4, M0, RotateM0)		\
        +	H(D, A, B, C, M1)			\
        +	COMPUTE(D, A, 11, M1, RotateM1)		\
        +	H(C, D, A, B, M2)			\
        +	COMPUTE(C, D, 16, M2, RotateM2)		\
        +	H(B, C, D, A, M3)			\
        +	LOOP(B, C, 23, M3, RotateM3, label)
        +
        +#define II4(label)				\
        +	I(A, B, C, D, M0)			\
        +	COMPUTE(A, B, 6, M0, RotateM0)		\
        +	I(D, A, B, C, M1)			\
        +	COMPUTE(D, A, 10, M1, RotateM1)		\
        +	I(C, D, A, B, M2)			\
        +	COMPUTE(C, D, 15, M2, RotateM2)		\
        +	I(B, C, D, A, M3)			\
        +	LOOP(B, C, 21, M3, RotateM3, label)
        +
        +#define FFLOAD(a, b, c, d, M, N, s)		\
        +{	.mii ;					\
        +(pMore) ld4 N = [DPtr], 4 ;			\
        +	add Z = M, TRound ;			\
        +	and Y = c, b ;				\
        +}						\
        +{	.mmi ;					\
        +	andcm X = d, b ;;			\
        +	add Z = Z, a ;				\
        +	or Y = Y, X ;				\
        +} ;;						\
        +{	.mii ;					\
        +	ld4 TRound = [TPtr], 4 ;		\
        +	add Z = Z, Y ;;				\
        +	dep.z Y = Z, 32, 32 ;			\
        +} ;;						\
        +{	.mii ;					\
        +	nop 0x0 ;				\
        +	shrp Z = Z, Y, 64 - s ;;		\
        +	add a = Z, b ;				\
        +} ;;
        +
        +#define FFLOOP(a, b, c, d, M, N, s, dest)	\
        +{	.mii ;					\
        +(pMore)	ld4 N = [DPtr], 4 ;			\
        +	add Z = M, TRound ;			\
        +	and Y = c, b ;				\
        +}						\
        +{	.mmi ;					\
        +	andcm X = d, b ;;			\
        +	add Z = Z, a ;				\
        +	or Y = Y, X ;				\
        +} ;;						\
        +{	.mii ;					\
        +	ld4 TRound = [TPtr], 4 ;		\
        +	add Z = Z, Y ;;				\
        +	dep.z Y = Z, 32, 32 ;			\
        +} ;;						\
        +{	.mii ;					\
        +	nop 0x0 ;				\
        +	shrp Z = Z, Y, 64 - s ;;		\
        +	add a = Z, b ;				\
        +}						\
        +{	.mib ;					\
        +	cmp.ne pMore, p0 = 0, LTrip ;		\
        +	add LTrip = -1, LTrip ;			\
        +	br.ctop.dptk.many dest ;		\
        +} ;;
        +
        +	.type md5_digest_block0, @function
        +	.align 32
        +
        +	.proc md5_digest_block0
        +	.prologue
        +md5_digest_block0:
        +	.altrp QUICK_RTN
        +	.body
        +{	.mmi
        +	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
        +	mov LTrip = 2
        +	mov ar.lc = 3
        +} ;;
        +{	.mii
        +	cmp.eq pMore, p0 = r0, r0
        +	mov ar.ec = 0
        +	nop 0x0
        +} ;;
        +
        +.md5_FF_round0:
        +	FFLOAD(A, B, C, D, M12, RotateM0, 7)
        +	FFLOAD(D, A, B, C, M13, RotateM1, 12)
        +	FFLOAD(C, D, A, B, M14, RotateM2, 17)
        +	FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0)
        +	//
        +	// !!! Fall through to md5_digest_GHI
        +	//
        +	.endp md5_digest_block0
        +
        +	.type md5_digest_GHI, @function
        +	.align 32
        +
        +	.proc md5_digest_GHI
        +	.prologue
        +	.regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
        +md5_digest_GHI:
        +	.altrp QUICK_RTN
        +	.body
        +//
        +// The following sequence shuffles the block counstants round for the
        +// next round:
        +//
        +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
        +// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
        +//
        +{	.mmi
        +	mov Z = M0
        +	mov Y = M15
        +	mov ar.lc = 3
        +}
        +{	.mmi
        +	mov X = M2
        +	mov W = M9
        +	mov V = M4
        +} ;;
        +
        +{	.mmi
        +	mov M0 = M1
        +	mov M15 = M12
        +	mov ar.ec = 1
        +}
        +{	.mmi
        +	mov M2 = M11
        +	mov M9 = M14
        +	mov M4 = M5
        +} ;;
        +
        +{	.mmi
        +	mov M1 = M6
        +	mov M12 = M13
        +	mov U = M3
        +}
        +{	.mmi
        +	mov M11 = M8
        +	mov M14 = M7
        +	mov M5 = M10
        +} ;;
        +
        +{	.mmi
        +	mov M6 = Y
        +	mov M13 = X
        +	mov M3 = Z
        +}
        +{	.mmi
        +	mov M8 = W
        +	mov M7 = V
        +	mov M10 = U
        +} ;;
        +
        +.md5_GG_round:
        +	GG4(.md5_GG_round)
        +
        +// The following sequence shuffles the block constants round for the
        +// next round:
        +//
        +// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
        +// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
        +
        +{	.mmi
        +	mov Z = M0
        +	mov Y = M1
        +	mov ar.lc = 3
        +}
        +{	.mmi
        +	mov X = M3
        +	mov W = M5
        +	mov V = M6
        +} ;;
        +
        +{	.mmi
        +	mov M0 = M4
        +	mov M1 = M11
        +	mov ar.ec = 1
        +}
        +{	.mmi
        +	mov M3 = M9
        +	mov U = M8
        +	mov T = M13
        +} ;;
        +
        +{	.mmi
        +	mov M4 = Z
        +	mov M11 = Y
        +	mov M5 = M7
        +}
        +{	.mmi
        +	mov M6 = M14
        +	mov M8 = M12
        +	mov M13 = M15
        +} ;;
        +
        +{	.mmi
        +	mov M7 = W
        +	mov M14 = V
        +	nop 0x0
        +}
        +{	.mmi
        +	mov M9 = X
        +	mov M12 = U
        +	mov M15 = T
        +} ;;
        +
        +.md5_HH_round:
        +	HH4(.md5_HH_round)
        +
        +// The following sequence shuffles the block constants round for the
        +// next round:
        +//
        +// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
        +// 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
        +
        +{	.mmi
        +	mov Z = M0
        +	mov Y = M15
        +	mov ar.lc = 3
        +}
        +{	.mmi
        +	mov X = M10
        +	mov W = M1
        +	mov V = M4
        +} ;;
        +
        +{	.mmi
        +	mov M0 = M9
        +	mov M15 = M12
        +	mov ar.ec = 1
        +}
        +{	.mmi
        +	mov M10 = M11
        +	mov M1 = M6
        +	mov M4 = M13
        +} ;;
        +
        +{	.mmi
        +	mov M9 = M14
        +	mov M12 = M5
        +	mov U = M3
        +}
        +{	.mmi
        +	mov M11 = M8
        +	mov M6 = M7
        +	mov M13 = M2
        +} ;;
        +
        +{	.mmi
        +	mov M14 = Y
        +	mov M5 = X
        +	mov M3 = Z
        +}
        +{	.mmi
        +	mov M8 = W
        +	mov M7 = V
        +	mov M2 = U
        +} ;;
        +
        +.md5_II_round:
        +	II4(.md5_II_round)
        +
        +{	.mib
        +	nop 0x0
        +	nop 0x0
        +	br.ret.sptk.many QUICK_RTN
        +} ;;
        +
        +	.endp md5_digest_GHI
        +
        +#define FFLOADU(a, b, c, d, M, P, N, s, offset)	\
        +{	.mii ;					\
        +(pMore) ld4 N = [DPtr], 4 ;			\
        +	add Z = M, TRound ;			\
        +	and Y = c, b ;				\
        +}						\
        +{	.mmi ;					\
        +	andcm X = d, b ;;			\
        +	add Z = Z, a ;				\
        +	or Y = Y, X ;				\
        +} ;;						\
        +{	.mii ;					\
        +	ld4 TRound = [TPtr], 4 ;		\
        +	GETLW(W, P, offset) ;			\
        +	add Z = Z, Y ;				\
        +} ;;						\
        +{	.mii ;					\
        +	or W = W, DTmp ;			\
        +	dep.z Y = Z, 32, 32 ;;			\
        +	shrp Z = Z, Y, 64 - s ;			\
        +} ;;						\
        +{	.mii ;					\
        +	add a = Z, b ;				\
        +	GETRW(DTmp, P, offset) ;		\
        +	mov P = W ;				\
        +} ;;
        +
        +#define FFLOOPU(a, b, c, d, M, P, N, s, offset)		\
        +{	.mii ;						\
        +(pMore) ld4 N = [DPtr], 4 ;				\
        +	add Z = M, TRound ;				\
        +	and Y = c, b ;					\
        +}							\
        +{	.mmi ;						\
        +	andcm X = d, b ;;				\
        +	add Z = Z, a ;					\
        +	or Y = Y, X ;					\
        +} ;;							\
        +{	.mii ;						\
        +	ld4 TRound = [TPtr], 4 ;			\
        +(pMore) GETLW(W, P, offset) 	;			\
        +	add Z = Z, Y ;					\
        +} ;;							\
        +{	.mii ;						\
        +(pMore) or W = W, DTmp ;				\
        +	dep.z Y = Z, 32, 32 ;;				\
        +	shrp Z = Z, Y, 64 - s ;				\
        +} ;;							\
        +{	.mii ;						\
        +	add a = Z, b ;					\
        +(pMore) GETRW(DTmp, P, offset) 	;			\
        +(pMore) mov P = W ;					\
        +}							\
        +{	.mib ;						\
        +	cmp.ne pMore, p0 = 0, LTrip ;			\
        +	add LTrip = -1, LTrip ;				\
        +	br.ctop.sptk.many .md5_FF_round##offset ;	\
        +} ;;
        +
        +#define MD5FBLOCK(offset)						\
        +	.type md5_digest_block##offset, @function ;			\
        +									\
        +	.align 32 ;							\
        +	.proc md5_digest_block##offset ;				\
        +	.prologue ;							\
        +	.altrp QUICK_RTN ;						\
        +	.body ;								\
        +md5_digest_block##offset:						\
        +{	.mmi ;								\
        +	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ;	\
        +	mov LTrip = 2 ;							\
        +	mov ar.lc = 3 ;							\
        +} ;;									\
        +{	.mii ;								\
        +	cmp.eq pMore, p0 = r0, r0 ;					\
        +	mov ar.ec = 0 ;							\
        +	nop 0x0 ;							\
        +} ;;									\
        +									\
        +	.pred.rel "mutex", pLoad, pSkip ;				\
        +.md5_FF_round##offset:							\
        +	FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset)		\
        +	FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset)		\
        +	FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset)		\
        +	FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset)	\
        +									\
        +{	.mib ;								\
        +	nop 0x0 ;							\
        +	nop 0x0 ;							\
        +	br.cond.sptk.many md5_digest_GHI ;				\
        +} ;;									\
        +	.endp md5_digest_block##offset
        +
        +MD5FBLOCK(1)
        +MD5FBLOCK(2)
        +MD5FBLOCK(3)
        +
        +	.align 64
        +	.type md5_constants, @object
        +md5_constants:
        +.md5_tbl_data_order:			// To ensure little-endian data
        +					// order, code as bytes.
        +	data1 0x78, 0xa4, 0x6a, 0xd7	//     0
        +	data1 0x56, 0xb7, 0xc7, 0xe8	//     1
        +	data1 0xdb, 0x70, 0x20, 0x24	//     2
        +	data1 0xee, 0xce, 0xbd, 0xc1	//     3
        +	data1 0xaf, 0x0f, 0x7c, 0xf5	//     4
        +	data1 0x2a, 0xc6, 0x87, 0x47	//     5
        +	data1 0x13, 0x46, 0x30, 0xa8	//     6
        +	data1 0x01, 0x95, 0x46, 0xfd	//     7
        +	data1 0xd8, 0x98, 0x80, 0x69	//     8
        +	data1 0xaf, 0xf7, 0x44, 0x8b	//     9
        +	data1 0xb1, 0x5b, 0xff, 0xff	//    10
        +	data1 0xbe, 0xd7, 0x5c, 0x89	//    11
        +	data1 0x22, 0x11, 0x90, 0x6b	//    12
        +	data1 0x93, 0x71, 0x98, 0xfd	//    13
        +	data1 0x8e, 0x43, 0x79, 0xa6	//    14
        +	data1 0x21, 0x08, 0xb4, 0x49	//    15
        +	data1 0x62, 0x25, 0x1e, 0xf6	//    16
        +	data1 0x40, 0xb3, 0x40, 0xc0	//    17
        +	data1 0x51, 0x5a, 0x5e, 0x26	//    18
        +	data1 0xaa, 0xc7, 0xb6, 0xe9	//    19
        +	data1 0x5d, 0x10, 0x2f, 0xd6	//    20
        +	data1 0x53, 0x14, 0x44, 0x02	//    21
        +	data1 0x81, 0xe6, 0xa1, 0xd8	//    22
        +	data1 0xc8, 0xfb, 0xd3, 0xe7	//    23
        +	data1 0xe6, 0xcd, 0xe1, 0x21	//    24
        +	data1 0xd6, 0x07, 0x37, 0xc3	//    25
        +	data1 0x87, 0x0d, 0xd5, 0xf4	//    26
        +	data1 0xed, 0x14, 0x5a, 0x45	//    27
        +	data1 0x05, 0xe9, 0xe3, 0xa9	//    28
        +	data1 0xf8, 0xa3, 0xef, 0xfc	//    29
        +	data1 0xd9, 0x02, 0x6f, 0x67	//    30
        +	data1 0x8a, 0x4c, 0x2a, 0x8d	//    31
        +	data1 0x42, 0x39, 0xfa, 0xff	//    32
        +	data1 0x81, 0xf6, 0x71, 0x87	//    33
        +	data1 0x22, 0x61, 0x9d, 0x6d	//    34
        +	data1 0x0c, 0x38, 0xe5, 0xfd	//    35
        +	data1 0x44, 0xea, 0xbe, 0xa4	//    36
        +	data1 0xa9, 0xcf, 0xde, 0x4b	//    37
        +	data1 0x60, 0x4b, 0xbb, 0xf6	//    38
        +	data1 0x70, 0xbc, 0xbf, 0xbe	//    39
        +	data1 0xc6, 0x7e, 0x9b, 0x28	//    40
        +	data1 0xfa, 0x27, 0xa1, 0xea	//    41
        +	data1 0x85, 0x30, 0xef, 0xd4	//    42
        +	data1 0x05, 0x1d, 0x88, 0x04	//    43
        +	data1 0x39, 0xd0, 0xd4, 0xd9	//    44
        +	data1 0xe5, 0x99, 0xdb, 0xe6	//    45
        +	data1 0xf8, 0x7c, 0xa2, 0x1f	//    46
        +	data1 0x65, 0x56, 0xac, 0xc4	//    47
        +	data1 0x44, 0x22, 0x29, 0xf4	//    48
        +	data1 0x97, 0xff, 0x2a, 0x43	//    49
        +	data1 0xa7, 0x23, 0x94, 0xab	//    50
        +	data1 0x39, 0xa0, 0x93, 0xfc	//    51
        +	data1 0xc3, 0x59, 0x5b, 0x65	//    52
        +	data1 0x92, 0xcc, 0x0c, 0x8f	//    53
        +	data1 0x7d, 0xf4, 0xef, 0xff	//    54
        +	data1 0xd1, 0x5d, 0x84, 0x85	//    55
        +	data1 0x4f, 0x7e, 0xa8, 0x6f	//    56
        +	data1 0xe0, 0xe6, 0x2c, 0xfe	//    57
        +	data1 0x14, 0x43, 0x01, 0xa3	//    58
        +	data1 0xa1, 0x11, 0x08, 0x4e	//    59
        +	data1 0x82, 0x7e, 0x53, 0xf7	//    60
        +	data1 0x35, 0xf2, 0x3a, 0xbd	//    61
        +	data1 0xbb, 0xd2, 0xd7, 0x2a	//    62
        +	data1 0x91, 0xd3, 0x86, 0xeb	//    63
        +.size	md5_constants#,64*4
        diff --git a/vendor/openssl/openssl/crypto/md5/asm/md5-x86_64.pl b/vendor/openssl/openssl/crypto/md5/asm/md5-x86_64.pl
        new file mode 100644
        index 000000000..f11224d17
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/asm/md5-x86_64.pl
        @@ -0,0 +1,370 @@
        +#!/usr/bin/perl -w
        +#
        +# MD5 optimized for AMD64.
        +#
        +# Author: Marc Bevand <bevand_m (at) epita.fr>
        +# Licence: I hereby disclaim the copyright on this code and place it
        +# in the public domain.
        +#
        +
        +use strict;
        +
        +my $code;
        +
        +# round1_step() does:
        +#   dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
        +#   %r10d = X[k_next]
        +#   %r11d = z' (copy of z for the next step)
        +# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
        +sub round1_step
        +{
        +    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
        +    $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
        +    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
        +    $code .= <<EOF;
        +	xor	$y,		%r11d		/* y ^ ... */
        +	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
        +	and	$x,		%r11d		/* x & ... */
        +	xor	$z,		%r11d		/* z ^ ... */
        +	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
        +	add	%r11d,		$dst		/* dst += ... */
        +	rol	\$$s,		$dst		/* dst <<< s */
        +	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
        +	add	$x,		$dst		/* dst += x */
        +EOF
        +}
        +
        +# round2_step() does:
        +#   dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
        +#   %r10d = X[k_next]
        +#   %r11d = z' (copy of z for the next step)
        +#   %r12d = z' (copy of z for the next step)
        +# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
        +sub round2_step
        +{
        +    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
        +    $code .= " mov	1*4(%rsi),	%r10d		/* (NEXT STEP) X[1] */\n" if ($pos == -1);
        +    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
        +    $code .= " mov	%edx,		%r12d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
        +    $code .= <<EOF;
        +	not	%r11d				/* not z */
        +	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
        +	and	$x,		%r12d		/* x & z */
        +	and	$y,		%r11d		/* y & (not z) */
        +	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
        +	or	%r11d,		%r12d		/* (y & (not z)) | (x & z) */
        +	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
        +	add	%r12d,		$dst		/* dst += ... */
        +	mov	$y,		%r12d		/* (NEXT STEP) z' = $y */
        +	rol	\$$s,		$dst		/* dst <<< s */
        +	add	$x,		$dst		/* dst += x */
        +EOF
        +}
        +
        +# round3_step() does:
        +#   dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
        +#   %r10d = X[k_next]
        +#   %r11d = y' (copy of y for the next step)
        +# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
        +sub round3_step
        +{
        +    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
        +    $code .= " mov	5*4(%rsi),	%r10d		/* (NEXT STEP) X[5] */\n" if ($pos == -1);
        +    $code .= " mov	%ecx,		%r11d		/* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
        +    $code .= <<EOF;
        +	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
        +	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
        +	xor	$z,		%r11d		/* z ^ ... */
        +	xor	$x,		%r11d		/* x ^ ... */
        +	add	%r11d,		$dst		/* dst += ... */
        +	rol	\$$s,		$dst		/* dst <<< s */
        +	mov	$x,		%r11d		/* (NEXT STEP) y' = $x */
        +	add	$x,		$dst		/* dst += x */
        +EOF
        +}
        +
        +# round4_step() does:
        +#   dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
        +#   %r10d = X[k_next]
        +#   %r11d = not z' (copy of not z for the next step)
        +# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
        +sub round4_step
        +{
        +    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
        +    $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
        +    $code .= " mov	\$0xffffffff,	%r11d\n" if ($pos == -1);
        +    $code .= " xor	%edx,		%r11d		/* (NEXT STEP) not z' = not %edx*/\n"
        +    if ($pos == -1);
        +    $code .= <<EOF;
        +	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
        +	or	$x,		%r11d		/* x | ... */
        +	xor	$y,		%r11d		/* y ^ ... */
        +	add	%r11d,		$dst		/* dst += ... */
        +	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
        +	mov	\$0xffffffff,	%r11d
        +	rol	\$$s,		$dst		/* dst <<< s */
        +	xor	$y,		%r11d		/* (NEXT STEP) not z' = not $y */
        +	add	$x,		$dst		/* dst += x */
        +EOF
        +}
        +
        +my $flavour = shift;
        +my $output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +no warnings qw(uninitialized);
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +$code .= <<EOF;
        +.text
        +.align 16
        +
        +.globl md5_block_asm_data_order
        +.type md5_block_asm_data_order,\@function,3
        +md5_block_asm_data_order:
        +	push	%rbp
        +	push	%rbx
        +	push	%r12
        +	push	%r14
        +	push	%r15
        +.Lprologue:
        +
        +	# rdi = arg #1 (ctx, MD5_CTX pointer)
        +	# rsi = arg #2 (ptr, data pointer)
        +	# rdx = arg #3 (nbr, number of 16-word blocks to process)
        +	mov	%rdi,		%rbp	# rbp = ctx
        +	shl	\$6,		%rdx	# rdx = nbr in bytes
        +	lea	(%rsi,%rdx),	%rdi	# rdi = end
        +	mov	0*4(%rbp),	%eax	# eax = ctx->A
        +	mov	1*4(%rbp),	%ebx	# ebx = ctx->B
        +	mov	2*4(%rbp),	%ecx	# ecx = ctx->C
        +	mov	3*4(%rbp),	%edx	# edx = ctx->D
        +	# end is 'rdi'
        +	# ptr is 'rsi'
        +	# A is 'eax'
        +	# B is 'ebx'
        +	# C is 'ecx'
        +	# D is 'edx'
        +
        +	cmp	%rdi,		%rsi		# cmp end with ptr
        +	je	.Lend				# jmp if ptr == end
        +
        +	# BEGIN of loop over 16-word blocks
        +.Lloop:	# save old values of A, B, C, D
        +	mov	%eax,		%r8d
        +	mov	%ebx,		%r9d
        +	mov	%ecx,		%r14d
        +	mov	%edx,		%r15d
        +EOF
        +round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7');
        +round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12');
        +round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17');
        +round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22');
        +round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7');
        +round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12');
        +round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17');
        +round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22');
        +round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7');
        +round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12');
        +round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17');
        +round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22');
        +round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7');
        +round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12');
        +round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17');
        +round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22');
        +
        +round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5');
        +round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9');
        +round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14');
        +round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20');
        +round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5');
        +round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9');
        +round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14');
        +round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20');
        +round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5');
        +round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9');
        +round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14');
        +round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20');
        +round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5');
        +round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9');
        +round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14');
        +round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20');
        +
        +round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4');
        +round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11');
        +round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16');
        +round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23');
        +round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4');
        +round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11');
        +round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16');
        +round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23');
        +round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4');
        +round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11');
        +round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16');
        +round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23');
        +round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4');
        +round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11');
        +round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16');
        +round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23');
        +
        +round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6');
        +round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10');
        +round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15');
        +round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21');
        +round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6');
        +round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10');
        +round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15');
        +round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21');
        +round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6');
        +round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10');
        +round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15');
        +round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21');
        +round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6');
        +round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10');
        +round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15');
        +round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21');
        +$code .= <<EOF;
        +	# add old values of A, B, C, D
        +	add	%r8d,	%eax
        +	add	%r9d,	%ebx
        +	add	%r14d,	%ecx
        +	add	%r15d,	%edx
        +
        +	# loop control
        +	add	\$64,		%rsi		# ptr += 64
        +	cmp	%rdi,		%rsi		# cmp end with ptr
        +	jb	.Lloop				# jmp if ptr < end
        +	# END of loop over 16-word blocks
        +
        +.Lend:
        +	mov	%eax,		0*4(%rbp)	# ctx->A = A
        +	mov	%ebx,		1*4(%rbp)	# ctx->B = B
        +	mov	%ecx,		2*4(%rbp)	# ctx->C = C
        +	mov	%edx,		3*4(%rbp)	# ctx->D = D
        +
        +	mov	(%rsp),%r15
        +	mov	8(%rsp),%r14
        +	mov	16(%rsp),%r12
        +	mov	24(%rsp),%rbx
        +	mov	32(%rsp),%rbp
        +	add	\$40,%rsp
        +.Lepilogue:
        +	ret
        +.size md5_block_asm_data_order,.-md5_block_asm_data_order
        +EOF
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +my $rec="%rcx";
        +my $frame="%rdx";
        +my $context="%r8";
        +my $disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lprologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lprologue
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
        +	jae	.Lin_prologue
        +
        +	lea	40(%rax),%rax
        +
        +	mov	-8(%rax),%rbp
        +	mov	-16(%rax),%rbx
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r14
        +	mov	-40(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_md5_block_asm_data_order
        +	.rva	.LSEH_end_md5_block_asm_data_order
        +	.rva	.LSEH_info_md5_block_asm_data_order
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_md5_block_asm_data_order:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +___
        +}
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/md5/md5.c b/vendor/openssl/openssl/crypto/md5/md5.c
        new file mode 100644
        index 000000000..563733abc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5.c
        @@ -0,0 +1,127 @@
        +/* crypto/md5/md5.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md5.h>
        +
        +#define BUFSIZE	1024*16
        +
        +void do_fp(FILE *f);
        +void pt(unsigned char *md);
        +#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
        +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<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("MD5(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	MD5_CTX c;
        +	unsigned char md[MD5_DIGEST_LENGTH];
        +	int fd;
        +	int i;
        +	static unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	MD5_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,BUFSIZE);
        +		if (i <= 0) break;
        +		MD5_Update(&c,buf,(unsigned long)i);
        +		}
        +	MD5_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<MD5_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md5/md5.h b/vendor/openssl/openssl/crypto/md5/md5.h
        new file mode 100644
        index 000000000..541cc925f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5.h
        @@ -0,0 +1,120 @@
        +/* crypto/md5/md5.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_MD5_H
        +#define HEADER_MD5_H
        +
        +#include <openssl/e_os2.h>
        +#include <stddef.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_NO_MD5
        +#error MD5 is disabled.
        +#endif
        +
        +/*
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
        + * ! MD5_LONG_LOG2 has to be defined along.			   !
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + */
        +
        +#if defined(__LP32__)
        +#define MD5_LONG unsigned long
        +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
        +#define MD5_LONG unsigned long
        +#define MD5_LONG_LOG2 3
        +/*
        + * _CRAY note. I could declare short, but I have no idea what impact
        + * does it have on performance on none-T3E machines. I could declare
        + * int, but at least on C90 sizeof(int) can be chosen at compile time.
        + * So I've chosen long...
        + *					<appro@fy.chalmers.se>
        + */
        +#else
        +#define MD5_LONG unsigned int
        +#endif
        +
        +#define MD5_CBLOCK	64
        +#define MD5_LBLOCK	(MD5_CBLOCK/4)
        +#define MD5_DIGEST_LENGTH 16
        +
        +typedef struct MD5state_st
        +	{
        +	MD5_LONG A,B,C,D;
        +	MD5_LONG Nl,Nh;
        +	MD5_LONG data[MD5_LBLOCK];
        +	unsigned int num;
        +	} MD5_CTX;
        +
        +#ifdef OPENSSL_FIPS
        +int private_MD5_Init(MD5_CTX *c);
        +#endif
        +int MD5_Init(MD5_CTX *c);
        +int MD5_Update(MD5_CTX *c, const void *data, size_t len);
        +int MD5_Final(unsigned char *md, MD5_CTX *c);
        +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
        +void MD5_Transform(MD5_CTX *c, const unsigned char *b);
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md5/md5_dgst.c b/vendor/openssl/openssl/crypto/md5/md5_dgst.c
        new file mode 100644
        index 000000000..265890de5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5_dgst.c
        @@ -0,0 +1,185 @@
        +/* crypto/md5/md5_dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "md5_locl.h"
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +
        +const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
        +
        +/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
        + */
        +
        +#define INIT_DATA_A (unsigned long)0x67452301L
        +#define INIT_DATA_B (unsigned long)0xefcdab89L
        +#define INIT_DATA_C (unsigned long)0x98badcfeL
        +#define INIT_DATA_D (unsigned long)0x10325476L
        +
        +fips_md_init(MD5)
        +	{
        +	memset (c,0,sizeof(*c));
        +	c->A=INIT_DATA_A;
        +	c->B=INIT_DATA_B;
        +	c->C=INIT_DATA_C;
        +	c->D=INIT_DATA_D;
        +	return 1;
        +	}
        +
        +#ifndef md5_block_data_order
        +#ifdef X
        +#undef X
        +#endif
        +void md5_block_data_order (MD5_CTX *c, const void *data_, size_t num)
        +	{
        +	const unsigned char *data=data_;
        +	register unsigned MD32_REG_T A,B,C,D,l;
        +#ifndef MD32_XARRAY
        +	/* See comment in crypto/sha/sha_locl.h for details. */
        +	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
        +				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
        +# define X(i)	XX##i
        +#else
        +	MD5_LONG XX[MD5_LBLOCK];
        +# define X(i)	XX[i]
        +#endif
        +
        +	A=c->A;
        +	B=c->B;
        +	C=c->C;
        +	D=c->D;
        +
        +	for (;num--;)
        +		{
        +	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
        +	/* Round 0 */
        +	R0(A,B,C,D,X( 0), 7,0xd76aa478L);	HOST_c2l(data,l); X( 2)=l;
        +	R0(D,A,B,C,X( 1),12,0xe8c7b756L);	HOST_c2l(data,l); X( 3)=l;
        +	R0(C,D,A,B,X( 2),17,0x242070dbL);	HOST_c2l(data,l); X( 4)=l;
        +	R0(B,C,D,A,X( 3),22,0xc1bdceeeL);	HOST_c2l(data,l); X( 5)=l;
        +	R0(A,B,C,D,X( 4), 7,0xf57c0fafL);	HOST_c2l(data,l); X( 6)=l;
        +	R0(D,A,B,C,X( 5),12,0x4787c62aL);	HOST_c2l(data,l); X( 7)=l;
        +	R0(C,D,A,B,X( 6),17,0xa8304613L);	HOST_c2l(data,l); X( 8)=l;
        +	R0(B,C,D,A,X( 7),22,0xfd469501L);	HOST_c2l(data,l); X( 9)=l;
        +	R0(A,B,C,D,X( 8), 7,0x698098d8L);	HOST_c2l(data,l); X(10)=l;
        +	R0(D,A,B,C,X( 9),12,0x8b44f7afL);	HOST_c2l(data,l); X(11)=l;
        +	R0(C,D,A,B,X(10),17,0xffff5bb1L);	HOST_c2l(data,l); X(12)=l;
        +	R0(B,C,D,A,X(11),22,0x895cd7beL);	HOST_c2l(data,l); X(13)=l;
        +	R0(A,B,C,D,X(12), 7,0x6b901122L);	HOST_c2l(data,l); X(14)=l;
        +	R0(D,A,B,C,X(13),12,0xfd987193L);	HOST_c2l(data,l); X(15)=l;
        +	R0(C,D,A,B,X(14),17,0xa679438eL);
        +	R0(B,C,D,A,X(15),22,0x49b40821L);
        +	/* Round 1 */
        +	R1(A,B,C,D,X( 1), 5,0xf61e2562L);
        +	R1(D,A,B,C,X( 6), 9,0xc040b340L);
        +	R1(C,D,A,B,X(11),14,0x265e5a51L);
        +	R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
        +	R1(A,B,C,D,X( 5), 5,0xd62f105dL);
        +	R1(D,A,B,C,X(10), 9,0x02441453L);
        +	R1(C,D,A,B,X(15),14,0xd8a1e681L);
        +	R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
        +	R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
        +	R1(D,A,B,C,X(14), 9,0xc33707d6L);
        +	R1(C,D,A,B,X( 3),14,0xf4d50d87L);
        +	R1(B,C,D,A,X( 8),20,0x455a14edL);
        +	R1(A,B,C,D,X(13), 5,0xa9e3e905L);
        +	R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
        +	R1(C,D,A,B,X( 7),14,0x676f02d9L);
        +	R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
        +	/* Round 2 */
        +	R2(A,B,C,D,X( 5), 4,0xfffa3942L);
        +	R2(D,A,B,C,X( 8),11,0x8771f681L);
        +	R2(C,D,A,B,X(11),16,0x6d9d6122L);
        +	R2(B,C,D,A,X(14),23,0xfde5380cL);
        +	R2(A,B,C,D,X( 1), 4,0xa4beea44L);
        +	R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
        +	R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
        +	R2(B,C,D,A,X(10),23,0xbebfbc70L);
        +	R2(A,B,C,D,X(13), 4,0x289b7ec6L);
        +	R2(D,A,B,C,X( 0),11,0xeaa127faL);
        +	R2(C,D,A,B,X( 3),16,0xd4ef3085L);
        +	R2(B,C,D,A,X( 6),23,0x04881d05L);
        +	R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
        +	R2(D,A,B,C,X(12),11,0xe6db99e5L);
        +	R2(C,D,A,B,X(15),16,0x1fa27cf8L);
        +	R2(B,C,D,A,X( 2),23,0xc4ac5665L);
        +	/* Round 3 */
        +	R3(A,B,C,D,X( 0), 6,0xf4292244L);
        +	R3(D,A,B,C,X( 7),10,0x432aff97L);
        +	R3(C,D,A,B,X(14),15,0xab9423a7L);
        +	R3(B,C,D,A,X( 5),21,0xfc93a039L);
        +	R3(A,B,C,D,X(12), 6,0x655b59c3L);
        +	R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
        +	R3(C,D,A,B,X(10),15,0xffeff47dL);
        +	R3(B,C,D,A,X( 1),21,0x85845dd1L);
        +	R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
        +	R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
        +	R3(C,D,A,B,X( 6),15,0xa3014314L);
        +	R3(B,C,D,A,X(13),21,0x4e0811a1L);
        +	R3(A,B,C,D,X( 4), 6,0xf7537e82L);
        +	R3(D,A,B,C,X(11),10,0xbd3af235L);
        +	R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
        +	R3(B,C,D,A,X( 9),21,0xeb86d391L);
        +
        +	A = c->A += A;
        +	B = c->B += B;
        +	C = c->C += C;
        +	D = c->D += D;
        +		}
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/md5/md5_locl.h b/vendor/openssl/openssl/crypto/md5/md5_locl.h
        new file mode 100644
        index 000000000..74d63d1f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5_locl.h
        @@ -0,0 +1,130 @@
        +/* crypto/md5/md5_locl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/md5.h>
        +
        +#ifndef MD5_LONG_LOG2
        +#define MD5_LONG_LOG2 2 /* default to 32 bits */
        +#endif
        +
        +#ifdef MD5_ASM
        +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \
        +     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
        +#  define md5_block_data_order md5_block_asm_data_order
        +# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
        +#  define md5_block_data_order md5_block_asm_data_order
        +# endif
        +#endif
        +
        +void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
        +
        +#define DATA_ORDER_IS_LITTLE_ENDIAN
        +
        +#define HASH_LONG		MD5_LONG
        +#define HASH_CTX		MD5_CTX
        +#define HASH_CBLOCK		MD5_CBLOCK
        +#define HASH_UPDATE		MD5_Update
        +#define HASH_TRANSFORM		MD5_Transform
        +#define HASH_FINAL		MD5_Final
        +#define	HASH_MAKE_STRING(c,s)	do {	\
        +	unsigned long ll;		\
        +	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
        +	} while (0)
        +#define	HASH_BLOCK_DATA_ORDER	md5_block_data_order
        +
        +#include "md32_common.h"
        +
        +/*
        +#define	F(x,y,z)	(((x) & (y))  |  ((~(x)) & (z)))
        +#define	G(x,y,z)	(((x) & (z))  |  ((y) & (~(z))))
        +*/
        +
        +/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
        + * simplified to the code below.  Wei attributes these optimizations
        + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
        + */
        +#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
        +#define	G(b,c,d)	((((b) ^ (c)) & (d)) ^ (c))
        +#define	H(b,c,d)	((b) ^ (c) ^ (d))
        +#define	I(b,c,d)	(((~(d)) | (b)) ^ (c))
        +
        +#define R0(a,b,c,d,k,s,t) { \
        +	a+=((k)+(t)+F((b),(c),(d))); \
        +	a=ROTATE(a,s); \
        +	a+=b; };\
        +
        +#define R1(a,b,c,d,k,s,t) { \
        +	a+=((k)+(t)+G((b),(c),(d))); \
        +	a=ROTATE(a,s); \
        +	a+=b; };
        +
        +#define R2(a,b,c,d,k,s,t) { \
        +	a+=((k)+(t)+H((b),(c),(d))); \
        +	a=ROTATE(a,s); \
        +	a+=b; };
        +
        +#define R3(a,b,c,d,k,s,t) { \
        +	a+=((k)+(t)+I((b),(c),(d))); \
        +	a=ROTATE(a,s); \
        +	a+=b; };
        diff --git a/vendor/openssl/openssl/crypto/md5/md5_one.c b/vendor/openssl/openssl/crypto/md5/md5_one.c
        new file mode 100644
        index 000000000..43fee8937
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5_one.c
        @@ -0,0 +1,97 @@
        +/* crypto/md5/md5_one.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/md5.h>
        +#include <openssl/crypto.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	MD5_CTX c;
        +	static unsigned char m[MD5_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!MD5_Init(&c))
        +		return NULL;
        +#ifndef CHARSET_EBCDIC
        +	MD5_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);
        +			MD5_Update(&c,temp,chunk);
        +			n -= chunk;
        +			d += chunk;
        +		}
        +	}
        +#endif
        +	MD5_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
        +	return(md);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md5/md5s.cpp b/vendor/openssl/openssl/crypto/md5/md5s.cpp
        new file mode 100644
        index 000000000..dd343fd4e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5s.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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md5.h>
        +
        +extern "C" {
        +void md5_block_x86(MD5_CTX *ctx, unsigned char *buffer,int num);
        +}
        +
        +void main(int argc,char *argv[])
        +	{
        +	unsigned char buffer[64*256];
        +	MD5_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++) /**/
        +			{
        +			md5_block_x86(&ctx,buffer,numm);
        +			GetTSC(s1);
        +			md5_block_x86(&ctx,buffer,numm);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			md5_block_x86(&ctx,buffer,num);
        +			GetTSC(e2);
        +			md5_block_x86(&ctx,buffer,num);
        +			}
        +		printf("md5 (%d bytes) %d %d (%.2f)\n",num,
        +			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/md5/md5test.c b/vendor/openssl/openssl/crypto/md5/md5test.c
        new file mode 100644
        index 000000000..2b37190e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/md5/md5test.c
        @@ -0,0 +1,140 @@
        +/* crypto/md5/md5test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_MD5
        +int main(int argc, char *argv[])
        +{
        +    printf("No MD5 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/md5.h>
        +
        +static char *test[]={
        +	"",
        +	"a",
        +	"abc",
        +	"message digest",
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        +	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
        +	NULL,
        +	};
        +
        +static char *ret[]={
        +	"d41d8cd98f00b204e9800998ecf8427e",
        +	"0cc175b9c0f1b6a831c399e269772661",
        +	"900150983cd24fb0d6963f7d28e17f72",
        +	"f96b697d7cb7938d525a2f31aaf161d0",
        +	"c3fcd3d76192e4007dfb496cca67e13b",
        +	"d174ab98d277d9f5a5611c2c9f419d9f",
        +	"57edf4a22be3c955ac49da2e2107b67a",
        +	};
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[MD5_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md5(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,(char *)*R) != 0)
        +			{
        +			printf("error calculating MD5 on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(0);
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<MD5_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/mdc2/Makefile b/vendor/openssl/openssl/crypto/mdc2/Makefile
        new file mode 100644
        index 000000000..141553149
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mdc2/Makefile
        @@ -0,0 +1,93 @@
        +#
        +# OpenSSL/crypto/mdc2/Makefile
        +#
        +
        +DIR=	mdc2
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST= mdc2test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=mdc2dgst.c mdc2_one.c
        +LIBOBJ=mdc2dgst.o mdc2_one.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= mdc2.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +mdc2_one.o: ../../e_os.h ../../include/openssl/bio.h
        +mdc2_one.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +mdc2_one.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
        +mdc2_one.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +mdc2_one.o: ../../include/openssl/lhash.h ../../include/openssl/mdc2.h
        +mdc2_one.o: ../../include/openssl/opensslconf.h
        +mdc2_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +mdc2_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +mdc2_one.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +mdc2_one.o: ../../include/openssl/ui_compat.h ../cryptlib.h mdc2_one.c
        +mdc2dgst.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
        +mdc2dgst.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +mdc2dgst.o: ../../include/openssl/mdc2.h ../../include/openssl/opensslconf.h
        +mdc2dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +mdc2dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +mdc2dgst.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +mdc2dgst.o: ../../include/openssl/ui_compat.h mdc2dgst.c
        diff --git a/vendor/openssl/openssl/crypto/mdc2/mdc2.h b/vendor/openssl/openssl/crypto/mdc2/mdc2.h
        new file mode 100644
        index 000000000..f3e8e579d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mdc2/mdc2.h
        @@ -0,0 +1,98 @@
        +/* crypto/mdc2/mdc2.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_MDC2_H
        +#define HEADER_MDC2_H
        +
        +#include <openssl/des.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_NO_MDC2
        +#error MDC2 is disabled.
        +#endif
        +
        +#define MDC2_BLOCK              8
        +#define MDC2_DIGEST_LENGTH      16
        + 
        +typedef struct mdc2_ctx_st
        +	{
        +	unsigned int num;
        +	unsigned char data[MDC2_BLOCK];
        +	DES_cblock h,hh;
        +	int pad_type; /* either 1 or 2, default 1 */
        +	} MDC2_CTX;
        +
        +
        +#ifdef OPENSSL_FIPS
        +int private_MDC2_Init(MDC2_CTX *c);
        +#endif
        +int MDC2_Init(MDC2_CTX *c);
        +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len);
        +int MDC2_Final(unsigned char *md, MDC2_CTX *c);
        +unsigned char *MDC2(const unsigned char *d, size_t n,
        +	unsigned char *md);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/mdc2/mdc2_one.c b/vendor/openssl/openssl/crypto/mdc2/mdc2_one.c
        new file mode 100644
        index 000000000..72647f67e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mdc2/mdc2_one.c
        @@ -0,0 +1,76 @@
        +/* crypto/mdc2/mdc2_one.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/mdc2.h>
        +
        +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	MDC2_CTX c;
        +	static unsigned char m[MDC2_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!MDC2_Init(&c))
        +		return NULL;
        +	MDC2_Update(&c,d,n);
        +        MDC2_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
        +	return(md);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/mdc2/mdc2dgst.c b/vendor/openssl/openssl/crypto/mdc2/mdc2dgst.c
        new file mode 100644
        index 000000000..d66ed6a1c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mdc2/mdc2dgst.c
        @@ -0,0 +1,200 @@
        +/* crypto/mdc2/mdc2dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/des.h>
        +#include <openssl/mdc2.h>
        +
        +#undef c2l
        +#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
        +			 l|=((DES_LONG)(*((c)++)))<< 8L, \
        +			 l|=((DES_LONG)(*((c)++)))<<16L, \
        +			 l|=((DES_LONG)(*((c)++)))<<24L)
        +
        +#undef l2c
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			*((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +
        +static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
        +fips_md_init(MDC2)
        +	{
        +	c->num=0;
        +	c->pad_type=1;
        +	memset(&(c->h[0]),0x52,MDC2_BLOCK);
        +	memset(&(c->hh[0]),0x25,MDC2_BLOCK);
        +	return 1;
        +	}
        +
        +int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
        +	{
        +	size_t i,j;
        +
        +	i=c->num;
        +	if (i != 0)
        +		{
        +		if (i+len < MDC2_BLOCK)
        +			{
        +			/* partial block */
        +			memcpy(&(c->data[i]),in,len);
        +			c->num+=(int)len;
        +			return 1;
        +			}
        +		else
        +			{
        +			/* filled one */
        +			j=MDC2_BLOCK-i;
        +			memcpy(&(c->data[i]),in,j);
        +			len-=j;
        +			in+=j;
        +			c->num=0;
        +			mdc2_body(c,&(c->data[0]),MDC2_BLOCK);
        +			}
        +		}
        +	i=len&~((size_t)MDC2_BLOCK-1);
        +	if (i > 0) mdc2_body(c,in,i);
        +	j=len-i;
        +	if (j > 0)
        +		{
        +		memcpy(&(c->data[0]),&(in[i]),j);
        +		c->num=(int)j;
        +		}
        +	return 1;
        +	}
        +
        +static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len)
        +	{
        +	register DES_LONG tin0,tin1;
        +	register DES_LONG ttin0,ttin1;
        +	DES_LONG d[2],dd[2];
        +	DES_key_schedule k;
        +	unsigned char *p;
        +	size_t i;
        +
        +	for (i=0; i<len; i+=8)
        +		{
        +		c2l(in,tin0); d[0]=dd[0]=tin0;
        +		c2l(in,tin1); d[1]=dd[1]=tin1;
        +		c->h[0]=(c->h[0]&0x9f)|0x40;
        +		c->hh[0]=(c->hh[0]&0x9f)|0x20;
        +
        +		DES_set_odd_parity(&c->h);
        +		DES_set_key_unchecked(&c->h,&k);
        +		DES_encrypt1(d,&k,1);
        +
        +		DES_set_odd_parity(&c->hh);
        +		DES_set_key_unchecked(&c->hh,&k);
        +		DES_encrypt1(dd,&k,1);
        +
        +		ttin0=tin0^dd[0];
        +		ttin1=tin1^dd[1];
        +		tin0^=d[0];
        +		tin1^=d[1];
        +
        +		p=c->h;
        +		l2c(tin0,p);
        +		l2c(ttin1,p);
        +		p=c->hh;
        +		l2c(ttin0,p);
        +		l2c(tin1,p);
        +		}
        +	}
        +
        +int MDC2_Final(unsigned char *md, MDC2_CTX *c)
        +	{
        +	unsigned int i;
        +	int j;
        +
        +	i=c->num;
        +	j=c->pad_type;
        +	if ((i > 0) || (j == 2))
        +		{
        +		if (j == 2)
        +			c->data[i++]=0x80;
        +		memset(&(c->data[i]),0,MDC2_BLOCK-i);
        +		mdc2_body(c,c->data,MDC2_BLOCK);
        +		}
        +	memcpy(md,(char *)c->h,MDC2_BLOCK);
        +	memcpy(&(md[MDC2_BLOCK]),(char *)c->hh,MDC2_BLOCK);
        +	return 1;
        +	}
        +
        +#undef TEST
        +
        +#ifdef TEST
        +main()
        +	{
        +	unsigned char md[MDC2_DIGEST_LENGTH];
        +	int i;
        +	MDC2_CTX c;
        +	static char *text="Now is the time for all ";
        +
        +	MDC2_Init(&c);
        +	MDC2_Update(&c,text,strlen(text));
        +	MDC2_Final(&(md[0]),&c);
        +
        +	for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +		printf("%02X",md[i]);
        +	printf("\n");
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/mdc2/mdc2test.c b/vendor/openssl/openssl/crypto/mdc2/mdc2test.c
        new file mode 100644
        index 000000000..017b31add
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mdc2/mdc2test.c
        @@ -0,0 +1,149 @@
        +/* crypto/mdc2/mdc2test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#if defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_MDC2)
        +#define OPENSSL_NO_MDC2
        +#endif
        +
        +#ifdef OPENSSL_NO_MDC2
        +int main(int argc, char *argv[])
        +{
        +    printf("No MDC2 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/mdc2.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static unsigned char pad1[16]={
        +	0x42,0xE5,0x0C,0xD2,0x24,0xBA,0xCE,0xBA,
        +	0x76,0x0B,0xDD,0x2B,0xD4,0x09,0x28,0x1A
        +	};
        +
        +static unsigned char pad2[16]={
        +	0x2E,0x46,0x79,0xB5,0xAD,0xD9,0xCA,0x75,
        +	0x35,0xD8,0x7A,0xFE,0xAB,0x33,0xBE,0xE2
        +	};
        +
        +int main(int argc, char *argv[])
        +	{
        +	int ret=0;
        +	unsigned char md[MDC2_DIGEST_LENGTH];
        +	int i;
        +	EVP_MD_CTX c;
        +	static char *text="Now is the time for all ";
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(text,text,strlen(text));
        +#endif
        +
        +	EVP_MD_CTX_init(&c);
        +	EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
        +	EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
        +	EVP_DigestFinal_ex(&c,&(md[0]),NULL);
        +
        +	if (memcmp(md,pad1,MDC2_DIGEST_LENGTH) != 0)
        +		{
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",md[i]);
        +		printf(" <- generated\n");
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",pad1[i]);
        +		printf(" <- correct\n");
        +		ret=1;
        +		}
        +	else
        +		printf("pad1 - ok\n");
        +
        +	EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
        +	/* FIXME: use a ctl function? */
        +	((MDC2_CTX *)c.md_data)->pad_type=2;
        +	EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
        +	EVP_DigestFinal_ex(&c,&(md[0]),NULL);
        +
        +	if (memcmp(md,pad2,MDC2_DIGEST_LENGTH) != 0)
        +		{
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",md[i]);
        +		printf(" <- generated\n");
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",pad2[i]);
        +		printf(" <- correct\n");
        +		ret=1;
        +		}
        +	else
        +		printf("pad2 - ok\n");
        +
        +	EVP_MD_CTX_cleanup(&c);
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (ret) printf("ERROR: %d\n", ret);
        +#endif
        +	EXIT(ret);
        +	return(ret);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/mem.c b/vendor/openssl/openssl/crypto/mem.c
        new file mode 100644
        index 000000000..1cc62eafd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mem.c
        @@ -0,0 +1,420 @@
        +/* crypto/mem.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +
        +
        +static int allow_customize = 1;      /* we provide flexible functions for */
        +static int allow_customize_debug = 1;/* exchanging memory-related functions at
        +                                      * run-time, but this must be done
        +                                      * before any blocks are actually
        +                                      * allocated; or we'll run into huge
        +                                      * problems when malloc/free pairs
        +                                      * don't match etc. */
        +
        +
        +
        +/* the following pointers may be changed as long as 'allow_customize' is set */
        +
        +static void *(*malloc_func)(size_t)         = malloc;
        +static void *default_malloc_ex(size_t num, const char *file, int line)
        +	{ return malloc_func(num); }
        +static void *(*malloc_ex_func)(size_t, const char *file, int line)
        +        = default_malloc_ex;
        +
        +static void *(*realloc_func)(void *, size_t)= realloc;
        +static void *default_realloc_ex(void *str, size_t num,
        +        const char *file, int line)
        +	{ return realloc_func(str,num); }
        +static void *(*realloc_ex_func)(void *, size_t, const char *file, int line)
        +        = default_realloc_ex;
        +
        +static void (*free_func)(void *)            = free;
        +
        +static void *(*malloc_locked_func)(size_t)  = malloc;
        +static void *default_malloc_locked_ex(size_t num, const char *file, int line)
        +	{ return malloc_locked_func(num); }
        +static void *(*malloc_locked_ex_func)(size_t, const char *file, int line)
        +        = default_malloc_locked_ex;
        +
        +static void (*free_locked_func)(void *)     = free;
        +
        +
        +
        +/* may be changed as long as 'allow_customize_debug' is set */
        +/* XXX use correct function pointer types */
        +#ifdef CRYPTO_MDEBUG
        +/* use default functions from mem_dbg.c */
        +static void (*malloc_debug_func)(void *,int,const char *,int,int)
        +	= CRYPTO_dbg_malloc;
        +static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
        +	= CRYPTO_dbg_realloc;
        +static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
        +static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
        +static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
        +#else
        +/* applications can use CRYPTO_malloc_debug_init() to select above case
        + * at run-time */
        +static void (*malloc_debug_func)(void *,int,const char *,int,int) = NULL;
        +static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
        +	= NULL;
        +static void (*free_debug_func)(void *,int) = NULL;
        +static void (*set_debug_options_func)(long) = NULL;
        +static long (*get_debug_options_func)(void) = NULL;
        +#endif
        +
        +int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
        +	void (*f)(void *))
        +	{
        +	/* Dummy call just to ensure OPENSSL_init() gets linked in */
        +	OPENSSL_init();
        +	if (!allow_customize)
        +		return 0;
        +	if ((m == 0) || (r == 0) || (f == 0))
        +		return 0;
        +	malloc_func=m; malloc_ex_func=default_malloc_ex;
        +	realloc_func=r; realloc_ex_func=default_realloc_ex;
        +	free_func=f;
        +	malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
        +	free_locked_func=f;
        +	return 1;
        +	}
        +
        +int CRYPTO_set_mem_ex_functions(
        +        void *(*m)(size_t,const char *,int),
        +        void *(*r)(void *, size_t,const char *,int),
        +	void (*f)(void *))
        +	{
        +	if (!allow_customize)
        +		return 0;
        +	if ((m == 0) || (r == 0) || (f == 0))
        +		return 0;
        +	malloc_func=0; malloc_ex_func=m;
        +	realloc_func=0; realloc_ex_func=r;
        +	free_func=f;
        +	malloc_locked_func=0; malloc_locked_ex_func=m;
        +	free_locked_func=f;
        +	return 1;
        +	}
        +
        +int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
        +	{
        +	if (!allow_customize)
        +		return 0;
        +	if ((m == NULL) || (f == NULL))
        +		return 0;
        +	malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
        +	free_locked_func=f;
        +	return 1;
        +	}
        +
        +int CRYPTO_set_locked_mem_ex_functions(
        +        void *(*m)(size_t,const char *,int),
        +        void (*f)(void *))
        +	{
        +	if (!allow_customize)
        +		return 0;
        +	if ((m == NULL) || (f == NULL))
        +		return 0;
        +	malloc_locked_func=0; malloc_locked_ex_func=m;
        +	free_func=f;
        +	return 1;
        +	}
        +
        +int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
        +				   void (*r)(void *,void *,int,const char *,int,int),
        +				   void (*f)(void *,int),
        +				   void (*so)(long),
        +				   long (*go)(void))
        +	{
        +	if (!allow_customize_debug)
        +		return 0;
        +	OPENSSL_init();
        +	malloc_debug_func=m;
        +	realloc_debug_func=r;
        +	free_debug_func=f;
        +	set_debug_options_func=so;
        +	get_debug_options_func=go;
        +	return 1;
        +	}
        +
        +
        +void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
        +	void (**f)(void *))
        +	{
        +	if (m != NULL) *m = (malloc_ex_func == default_malloc_ex) ? 
        +	                     malloc_func : 0;
        +	if (r != NULL) *r = (realloc_ex_func == default_realloc_ex) ? 
        +	                     realloc_func : 0;
        +	if (f != NULL) *f=free_func;
        +	}
        +
        +void CRYPTO_get_mem_ex_functions(
        +        void *(**m)(size_t,const char *,int),
        +        void *(**r)(void *, size_t,const char *,int),
        +	void (**f)(void *))
        +	{
        +	if (m != NULL) *m = (malloc_ex_func != default_malloc_ex) ?
        +	                    malloc_ex_func : 0;
        +	if (r != NULL) *r = (realloc_ex_func != default_realloc_ex) ?
        +	                    realloc_ex_func : 0;
        +	if (f != NULL) *f=free_func;
        +	}
        +
        +void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
        +	{
        +	if (m != NULL) *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? 
        +	                     malloc_locked_func : 0;
        +	if (f != NULL) *f=free_locked_func;
        +	}
        +
        +void CRYPTO_get_locked_mem_ex_functions(
        +        void *(**m)(size_t,const char *,int),
        +        void (**f)(void *))
        +	{
        +	if (m != NULL) *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
        +	                    malloc_locked_ex_func : 0;
        +	if (f != NULL) *f=free_locked_func;
        +	}
        +
        +void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
        +				    void (**r)(void *,void *,int,const char *,int,int),
        +				    void (**f)(void *,int),
        +				    void (**so)(long),
        +				    long (**go)(void))
        +	{
        +	if (m != NULL) *m=malloc_debug_func;
        +	if (r != NULL) *r=realloc_debug_func;
        +	if (f != NULL) *f=free_debug_func;
        +	if (so != NULL) *so=set_debug_options_func;
        +	if (go != NULL) *go=get_debug_options_func;
        +	}
        +
        +
        +void *CRYPTO_malloc_locked(int num, const char *file, int line)
        +	{
        +	void *ret = NULL;
        +
        +	if (num <= 0) return NULL;
        +
        +	allow_customize = 0;
        +	if (malloc_debug_func != NULL)
        +		{
        +		allow_customize_debug = 0;
        +		malloc_debug_func(NULL, num, file, line, 0);
        +		}
        +	ret = malloc_locked_ex_func(num,file,line);
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr, "LEVITTE_DEBUG_MEM:         > 0x%p (%d)\n", ret, num);
        +#endif
        +	if (malloc_debug_func != NULL)
        +		malloc_debug_func(ret, num, file, line, 1);
        +
        +#ifndef OPENSSL_CPUID_OBJ
        +        /* Create a dependency on the value of 'cleanse_ctr' so our memory
        +         * sanitisation function can't be optimised out. NB: We only do
        +         * this for >2Kb so the overhead doesn't bother us. */
        +        if(ret && (num > 2048))
        +	{	extern unsigned char cleanse_ctr;
        +		((unsigned char *)ret)[0] = cleanse_ctr;
        +	}
        +#endif
        +
        +	return ret;
        +	}
        +
        +void CRYPTO_free_locked(void *str)
        +	{
        +	if (free_debug_func != NULL)
        +		free_debug_func(str, 0);
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
        +#endif
        +	free_locked_func(str);
        +	if (free_debug_func != NULL)
        +		free_debug_func(NULL, 1);
        +	}
        +
        +void *CRYPTO_malloc(int num, const char *file, int line)
        +	{
        +	void *ret = NULL;
        +
        +	if (num <= 0) return NULL;
        +
        +	allow_customize = 0;
        +	if (malloc_debug_func != NULL)
        +		{
        +		allow_customize_debug = 0;
        +		malloc_debug_func(NULL, num, file, line, 0);
        +		}
        +	ret = malloc_ex_func(num,file,line);
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr, "LEVITTE_DEBUG_MEM:         > 0x%p (%d)\n", ret, num);
        +#endif
        +	if (malloc_debug_func != NULL)
        +		malloc_debug_func(ret, num, file, line, 1);
        +
        +#ifndef OPENSSL_CPUID_OBJ
        +        /* Create a dependency on the value of 'cleanse_ctr' so our memory
        +         * sanitisation function can't be optimised out. NB: We only do
        +         * this for >2Kb so the overhead doesn't bother us. */
        +        if(ret && (num > 2048))
        +	{	extern unsigned char cleanse_ctr;
        +                ((unsigned char *)ret)[0] = cleanse_ctr;
        +	}
        +#endif
        +
        +	return ret;
        +	}
        +char *CRYPTO_strdup(const char *str, const char *file, int line)
        +	{
        +	char *ret = CRYPTO_malloc(strlen(str)+1, file, line);
        +
        +	strcpy(ret, str);
        +	return ret;
        +	}
        +
        +void *CRYPTO_realloc(void *str, int num, const char *file, int line)
        +	{
        +	void *ret = NULL;
        +
        +	if (str == NULL)
        +		return CRYPTO_malloc(num, file, line);
        +
        +	if (num <= 0) return NULL;
        +
        +	if (realloc_debug_func != NULL)
        +		realloc_debug_func(str, NULL, num, file, line, 0);
        +	ret = realloc_ex_func(str,num,file,line);
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr, "LEVITTE_DEBUG_MEM:         | 0x%p -> 0x%p (%d)\n", str, ret, num);
        +#endif
        +	if (realloc_debug_func != NULL)
        +		realloc_debug_func(str, ret, num, file, line, 1);
        +
        +	return ret;
        +	}
        +
        +void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
        +			   int line)
        +	{
        +	void *ret = NULL;
        +
        +	if (str == NULL)
        +		return CRYPTO_malloc(num, file, line);
        +
        +	if (num <= 0) return NULL;
        +
        +	/* We don't support shrinking the buffer. Note the memcpy that copies
        +	 * |old_len| bytes to the new buffer, below. */
        +	if (num < old_len) return NULL;
        +
        +	if (realloc_debug_func != NULL)
        +		realloc_debug_func(str, NULL, num, file, line, 0);
        +	ret=malloc_ex_func(num,file,line);
        +	if(ret)
        +		{
        +		memcpy(ret,str,old_len);
        +		OPENSSL_cleanse(str,old_len);
        +		free_func(str);
        +		}
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr,
        +		"LEVITTE_DEBUG_MEM:         | 0x%p -> 0x%p (%d)\n",
        +		str, ret, num);
        +#endif
        +	if (realloc_debug_func != NULL)
        +		realloc_debug_func(str, ret, num, file, line, 1);
        +
        +	return ret;
        +	}
        +
        +void CRYPTO_free(void *str)
        +	{
        +	if (free_debug_func != NULL)
        +		free_debug_func(str, 0);
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
        +#endif
        +	free_func(str);
        +	if (free_debug_func != NULL)
        +		free_debug_func(NULL, 1);
        +	}
        +
        +void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
        +	{
        +	if (a != NULL) OPENSSL_free(a);
        +	a=(char *)OPENSSL_malloc(num);
        +	return(a);
        +	}
        +
        +void CRYPTO_set_mem_debug_options(long bits)
        +	{
        +	if (set_debug_options_func != NULL)
        +		set_debug_options_func(bits);
        +	}
        +
        +long CRYPTO_get_mem_debug_options(void)
        +	{
        +	if (get_debug_options_func != NULL)
        +		return get_debug_options_func();
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/mem_clr.c b/vendor/openssl/openssl/crypto/mem_clr.c
        new file mode 100644
        index 000000000..add1f7802
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mem_clr.c
        @@ -0,0 +1,77 @@
        +/* crypto/mem_clr.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <string.h>
        +#include <openssl/crypto.h>
        +
        +unsigned char cleanse_ctr = 0;
        +
        +void OPENSSL_cleanse(void *ptr, size_t len)
        +	{
        +	unsigned char *p = ptr;
        +	size_t loop = len, ctr = cleanse_ctr;
        +	while(loop--)
        +		{
        +		*(p++) = (unsigned char)ctr;
        +		ctr += (17 + ((size_t)p & 0xF));
        +		}
        +	p=memchr(ptr, (unsigned char)ctr, len);
        +	if(p)
        +		ctr += (63 + (size_t)p);
        +	cleanse_ctr = (unsigned char)ctr;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/mem_dbg.c b/vendor/openssl/openssl/crypto/mem_dbg.c
        new file mode 100644
        index 000000000..ac793397f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/mem_dbg.c
        @@ -0,0 +1,874 @@
        +/* crypto/mem_dbg.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-2006 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 <stdio.h>
        +#include <stdlib.h>
        +#include <time.h>	
        +#include "cryptlib.h"
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/bio.h>
        +#include <openssl/lhash.h>
        +
        +static int mh_mode=CRYPTO_MEM_CHECK_OFF;
        +/* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
        + * when the application asks for it (usually after library initialisation
        + * for which no book-keeping is desired).
        + *
        + * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
        + * thinks that certain allocations should not be checked (e.g. the data
        + * structures used for memory checking).  It is not suitable as an initial
        + * state: the library will unexpectedly enable memory checking when it
        + * executes one of those sections that want to disable checking
        + * temporarily.
        + *
        + * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
        + */
        +
        +static unsigned long order = 0; /* number of memory requests */
        +
        +DECLARE_LHASH_OF(MEM);
        +static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
        +				* (address as key); access requires
        +				* MALLOC2 lock */
        +
        +
        +typedef struct app_mem_info_st
        +/* For application-defined information (static C-string `info')
        + * to be displayed in memory leak list.
        + * Each thread has its own stack.  For applications, there is
        + *   CRYPTO_push_info("...")     to push an entry,
        + *   CRYPTO_pop_info()           to pop an entry,
        + *   CRYPTO_remove_all_info()    to pop all entries.
        + */
        +	{
        +	CRYPTO_THREADID threadid;
        +	const char *file;
        +	int line;
        +	const char *info;
        +	struct app_mem_info_st *next; /* tail of thread's stack */
        +	int references;
        +	} APP_INFO;
        +
        +static void app_info_free(APP_INFO *);
        +
        +DECLARE_LHASH_OF(APP_INFO);
        +static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
        +				       * app_mem_info_st's that are at
        +				       * the top of their thread's
        +				       * stack (with `thread' as key);
        +				       * access requires MALLOC2
        +				       * lock */
        +
        +typedef struct mem_st
        +/* memory-block description */
        +	{
        +	void *addr;
        +	int num;
        +	const char *file;
        +	int line;
        +	CRYPTO_THREADID threadid;
        +	unsigned long order;
        +	time_t time;
        +	APP_INFO *app_info;
        +	} MEM;
        +
        +static long options =             /* extra information to be recorded */
        +#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
        +	V_CRYPTO_MDEBUG_TIME |
        +#endif
        +#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
        +	V_CRYPTO_MDEBUG_THREAD |
        +#endif
        +	0;
        +
        +
        +static unsigned int num_disable = 0; /* num_disable > 0
        +                                      *     iff
        +                                      * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
        +                                      */
        +
        +/* Valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in this
        + * case (by the thread named in disabling_thread).
        + */
        +static CRYPTO_THREADID disabling_threadid;
        +
        +static void app_info_free(APP_INFO *inf)
        +	{
        +	if (--(inf->references) <= 0)
        +		{
        +		if (inf->next != NULL)
        +			{
        +			app_info_free(inf->next);
        +			}
        +		OPENSSL_free(inf);
        +		}
        +	}
        +
        +int CRYPTO_mem_ctrl(int mode)
        +	{
        +	int ret=mh_mode;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
        +	switch (mode)
        +		{
        +	/* for applications (not to be called while multiple threads
        +	 * use the library): */
        +	case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
        +		mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
        +		num_disable = 0;
        +		break;
        +	case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
        +		mh_mode = 0;
        +		num_disable = 0; /* should be true *before* MemCheck_stop is used,
        +		                    or there'll be a lot of confusion */
        +		break;
        +
        +	/* switch off temporarily (for library-internal use): */
        +	case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
        +		if (mh_mode & CRYPTO_MEM_CHECK_ON)
        +			{
        +			CRYPTO_THREADID cur;
        +			CRYPTO_THREADID_current(&cur);
        +			if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
        +				{
        +				/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
        +				 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
        +				 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
        +				 * it because we block entry to this function).
        +				 * Give them a chance, first, and then claim the locks in
        +				 * appropriate order (long-time lock first).
        +				 */
        +				CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
        +				/* Note that after we have waited for CRYPTO_LOCK_MALLOC2
        +				 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
        +				 * "case" and "if" branch because MemCheck_start and
        +				 * MemCheck_stop may never be used while there are multiple
        +				 * OpenSSL threads. */
        +				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
        +				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
        +				mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
        +				CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
        +				}
        +			num_disable++;
        +			}
        +		break;
        +	case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
        +		if (mh_mode & CRYPTO_MEM_CHECK_ON)
        +			{
        +			if (num_disable) /* always true, or something is going wrong */
        +				{
        +				num_disable--;
        +				if (num_disable == 0)
        +					{
        +					mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
        +					CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
        +					}
        +				}
        +			}
        +		break;
        +
        +	default:
        +		break;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
        +	return(ret);
        +	}
        +
        +int CRYPTO_is_mem_check_on(void)
        +	{
        +	int ret = 0;
        +
        +	if (mh_mode & CRYPTO_MEM_CHECK_ON)
        +		{
        +		CRYPTO_THREADID cur;
        +		CRYPTO_THREADID_current(&cur);
        +		CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
        +
        +		ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
        +		        || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
        +
        +		CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
        +		}
        +	return(ret);
        +	}	
        +
        +
        +void CRYPTO_dbg_set_options(long bits)
        +	{
        +	options = bits;
        +	}
        +
        +long CRYPTO_dbg_get_options(void)
        +	{
        +	return options;
        +	}
        +
        +static int mem_cmp(const MEM *a, const MEM *b)
        +	{
        +#ifdef _WIN64
        +	const char *ap=(const char *)a->addr,
        +		   *bp=(const char *)b->addr;
        +	if (ap==bp)	return 0;
        +	else if (ap>bp)	return 1;
        +	else		return -1;
        +#else
        +	return (const char *)a->addr - (const char *)b->addr;
        +#endif
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
        +
        +static unsigned long mem_hash(const MEM *a)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)a->addr;
        +
        +	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
        +	return(ret);
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
        +
        +/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
        +static int app_info_cmp(const void *a_void, const void *b_void)
        +	{
        +	return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
        +				&((const APP_INFO *)b_void)->threadid);
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
        +
        +static unsigned long app_info_hash(const APP_INFO *a)
        +	{
        +	unsigned long ret;
        +
        +	ret = CRYPTO_THREADID_hash(&a->threadid);
        +	/* This is left in as a "who am I to question legacy?" measure */
        +	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
        +	return(ret);
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
        +
        +static APP_INFO *pop_info(void)
        +	{
        +	APP_INFO tmp;
        +	APP_INFO *ret = NULL;
        +
        +	if (amih != NULL)
        +		{
        +		CRYPTO_THREADID_current(&tmp.threadid);
        +		if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
        +			{
        +			APP_INFO *next=ret->next;
        +
        +			if (next != NULL)
        +				{
        +				next->references++;
        +				(void)lh_APP_INFO_insert(amih,next);
        +				}
        +#ifdef LEVITTE_DEBUG_MEM
        +			if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
        +				{
        +				fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
        +					CRYPTO_THREADID_hash(&ret->threadid),
        +					CRYPTO_THREADID_hash(&tmp.threadid));
        +				abort();
        +				}
        +#endif
        +			if (--(ret->references) <= 0)
        +				{
        +				ret->next = NULL;
        +				if (next != NULL)
        +					next->references--;
        +				OPENSSL_free(ret);
        +				}
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +int CRYPTO_push_info_(const char *info, const char *file, int line)
        +	{
        +	APP_INFO *ami, *amim;
        +	int ret=0;
        +
        +	if (is_MemCheck_on())
        +		{
        +		MemCheck_off(); /* obtain MALLOC2 lock */
        +
        +		if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
        +			{
        +			ret=0;
        +			goto err;
        +			}
        +		if (amih == NULL)
        +			{
        +			if ((amih=lh_APP_INFO_new()) == NULL)
        +				{
        +				OPENSSL_free(ami);
        +				ret=0;
        +				goto err;
        +				}
        +			}
        +
        +		CRYPTO_THREADID_current(&ami->threadid);
        +		ami->file=file;
        +		ami->line=line;
        +		ami->info=info;
        +		ami->references=1;
        +		ami->next=NULL;
        +
        +		if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
        +			{
        +#ifdef LEVITTE_DEBUG_MEM
        +			if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
        +				{
        +				fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
        +					CRYPTO_THREADID_hash(&amim->threadid),
        +					CRYPTO_THREADID_hash(&ami->threadid));
        +				abort();
        +				}
        +#endif
        +			ami->next=amim;
        +			}
        + err:
        +		MemCheck_on(); /* release MALLOC2 lock */
        +		}
        +
        +	return(ret);
        +	}
        +
        +int CRYPTO_pop_info(void)
        +	{
        +	int ret=0;
        +
        +	if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
        +		{
        +		MemCheck_off(); /* obtain MALLOC2 lock */
        +
        +		ret=(pop_info() != NULL);
        +
        +		MemCheck_on(); /* release MALLOC2 lock */
        +		}
        +	return(ret);
        +	}
        +
        +int CRYPTO_remove_all_info(void)
        +	{
        +	int ret=0;
        +
        +	if (is_MemCheck_on()) /* _must_ be true */
        +		{
        +		MemCheck_off(); /* obtain MALLOC2 lock */
        +
        +		while(pop_info() != NULL)
        +			ret++;
        +
        +		MemCheck_on(); /* release MALLOC2 lock */
        +		}
        +	return(ret);
        +	}
        +
        +
        +static unsigned long break_order_num=0;
        +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
        +	int before_p)
        +	{
        +	MEM *m,*mm;
        +	APP_INFO tmp,*amim;
        +
        +	switch(before_p & 127)
        +		{
        +	case 0:
        +		break;
        +	case 1:
        +		if (addr == NULL)
        +			break;
        +
        +		if (is_MemCheck_on())
        +			{
        +			MemCheck_off(); /* make sure we hold MALLOC2 lock */
        +			if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
        +				{
        +				OPENSSL_free(addr);
        +				MemCheck_on(); /* release MALLOC2 lock
        +				                * if num_disabled drops to 0 */
        +				return;
        +				}
        +			if (mh == NULL)
        +				{
        +				if ((mh=lh_MEM_new()) == NULL)
        +					{
        +					OPENSSL_free(addr);
        +					OPENSSL_free(m);
        +					addr=NULL;
        +					goto err;
        +					}
        +				}
        +
        +			m->addr=addr;
        +			m->file=file;
        +			m->line=line;
        +			m->num=num;
        +			if (options & V_CRYPTO_MDEBUG_THREAD)
        +				CRYPTO_THREADID_current(&m->threadid);
        +			else
        +				memset(&m->threadid, 0, sizeof(m->threadid));
        +
        +			if (order == break_order_num)
        +				{
        +				/* BREAK HERE */
        +				m->order=order;
        +				}
        +			m->order=order++;
        +#ifdef LEVITTE_DEBUG_MEM
        +			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
        +				m->order,
        +				(before_p & 128) ? '*' : '+',
        +				m->addr, m->num);
        +#endif
        +			if (options & V_CRYPTO_MDEBUG_TIME)
        +				m->time=time(NULL);
        +			else
        +				m->time=0;
        +
        +			CRYPTO_THREADID_current(&tmp.threadid);
        +			m->app_info=NULL;
        +			if (amih != NULL
        +			    && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
        +				{
        +				m->app_info = amim;
        +				amim->references++;
        +				}
        +
        +			if ((mm=lh_MEM_insert(mh, m)) != NULL)
        +				{
        +				/* Not good, but don't sweat it */
        +				if (mm->app_info != NULL)
        +					{
        +					mm->app_info->references--;
        +					}
        +				OPENSSL_free(mm);
        +				}
        +		err:
        +			MemCheck_on(); /* release MALLOC2 lock
        +			                * if num_disabled drops to 0 */
        +			}
        +		break;
        +		}
        +	return;
        +	}
        +
        +void CRYPTO_dbg_free(void *addr, int before_p)
        +	{
        +	MEM m,*mp;
        +
        +	switch(before_p)
        +		{
        +	case 0:
        +		if (addr == NULL)
        +			break;
        +
        +		if (is_MemCheck_on() && (mh != NULL))
        +			{
        +			MemCheck_off(); /* make sure we hold MALLOC2 lock */
        +
        +			m.addr=addr;
        +			mp=lh_MEM_delete(mh,&m);
        +			if (mp != NULL)
        +				{
        +#ifdef LEVITTE_DEBUG_MEM
        +			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
        +				mp->order, mp->addr, mp->num);
        +#endif
        +				if (mp->app_info != NULL)
        +					app_info_free(mp->app_info);
        +				OPENSSL_free(mp);
        +				}
        +
        +			MemCheck_on(); /* release MALLOC2 lock
        +			                * if num_disabled drops to 0 */
        +			}
        +		break;
        +	case 1:
        +		break;
        +		}
        +	}
        +
        +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
        +	const char *file, int line, int before_p)
        +	{
        +	MEM m,*mp;
        +
        +#ifdef LEVITTE_DEBUG_MEM
        +	fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
        +		addr1, addr2, num, file, line, before_p);
        +#endif
        +
        +	switch(before_p)
        +		{
        +	case 0:
        +		break;
        +	case 1:
        +		if (addr2 == NULL)
        +			break;
        +
        +		if (addr1 == NULL)
        +			{
        +			CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
        +			break;
        +			}
        +
        +		if (is_MemCheck_on())
        +			{
        +			MemCheck_off(); /* make sure we hold MALLOC2 lock */
        +
        +			m.addr=addr1;
        +			mp=lh_MEM_delete(mh,&m);
        +			if (mp != NULL)
        +				{
        +#ifdef LEVITTE_DEBUG_MEM
        +				fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
        +					mp->order,
        +					mp->addr, mp->num,
        +					addr2, num);
        +#endif
        +				mp->addr=addr2;
        +				mp->num=num;
        +				(void)lh_MEM_insert(mh,mp);
        +				}
        +
        +			MemCheck_on(); /* release MALLOC2 lock
        +			                * if num_disabled drops to 0 */
        +			}
        +		break;
        +		}
        +	return;
        +	}
        +
        +
        +typedef struct mem_leak_st
        +	{
        +	BIO *bio;
        +	int chunks;
        +	long bytes;
        +	} MEM_LEAK;
        +
        +static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
        +	{
        +	char buf[1024];
        +	char *bufp = buf;
        +	APP_INFO *amip;
        +	int ami_cnt;
        +	struct tm *lcl = NULL;
        +	CRYPTO_THREADID ti;
        +
        +#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
        +
        +	if(m->addr == (char *)l->bio)
        +	    return;
        +
        +	if (options & V_CRYPTO_MDEBUG_TIME)
        +		{
        +		lcl = localtime(&m->time);
        +	
        +		BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
        +			lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
        +		bufp += strlen(bufp);
        +		}
        +
        +	BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
        +		m->order,m->file,m->line);
        +	bufp += strlen(bufp);
        +
        +	if (options & V_CRYPTO_MDEBUG_THREAD)
        +		{
        +		BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
        +			CRYPTO_THREADID_hash(&m->threadid));
        +		bufp += strlen(bufp);
        +		}
        +
        +	BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
        +		m->num,(unsigned long)m->addr);
        +	bufp += strlen(bufp);
        +
        +	BIO_puts(l->bio,buf);
        +	
        +	l->chunks++;
        +	l->bytes+=m->num;
        +
        +	amip=m->app_info;
        +	ami_cnt=0;
        +	if (!amip)
        +		return;
        +	CRYPTO_THREADID_cpy(&ti, &amip->threadid);
        +
        +	do
        +		{
        +		int buf_len;
        +		int info_len;
        +
        +		ami_cnt++;
        +		memset(buf,'>',ami_cnt);
        +		BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
        +			" thread=%lu, file=%s, line=%d, info=\"",
        +			CRYPTO_THREADID_hash(&amip->threadid), amip->file,
        +			amip->line);
        +		buf_len=strlen(buf);
        +		info_len=strlen(amip->info);
        +		if (128 - buf_len - 3 < info_len)
        +			{
        +			memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
        +			buf_len = 128 - 3;
        +			}
        +		else
        +			{
        +			BUF_strlcpy(buf + buf_len, amip->info,
        +				    sizeof buf - buf_len);
        +			buf_len = strlen(buf);
        +			}
        +		BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
        +		
        +		BIO_puts(l->bio,buf);
        +
        +		amip = amip->next;
        +		}
        +	while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
        +
        +#ifdef LEVITTE_DEBUG_MEM
        +	if (amip)
        +		{
        +		fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
        +		abort();
        +		}
        +#endif
        +	}
        +
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
        +
        +void CRYPTO_mem_leaks(BIO *b)
        +	{
        +	MEM_LEAK ml;
        +
        +	if (mh == NULL && amih == NULL)
        +		return;
        +
        +	MemCheck_off(); /* obtain MALLOC2 lock */
        +
        +	ml.bio=b;
        +	ml.bytes=0;
        +	ml.chunks=0;
        +	if (mh != NULL)
        +		lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
        +				 &ml);
        +	if (ml.chunks != 0)
        +		{
        +		BIO_printf(b,"%ld bytes leaked in %d chunks\n",
        +			   ml.bytes,ml.chunks);
        +#ifdef CRYPTO_MDEBUG_ABORT
        +		abort();
        +#endif
        +		}
        +	else
        +		{
        +		/* Make sure that, if we found no leaks, memory-leak debugging itself
        +		 * does not introduce memory leaks (which might irritate
        +		 * external debugging tools).
        +		 * (When someone enables leak checking, but does not call
        +		 * this function, we declare it to be their fault.)
        +		 *
        +		 * XXX    This should be in CRYPTO_mem_leaks_cb,
        +		 * and CRYPTO_mem_leaks should be implemented by
        +		 * using CRYPTO_mem_leaks_cb.
        +		 * (Also there should be a variant of lh_doall_arg
        +		 * that takes a function pointer instead of a void *;
        +		 * this would obviate the ugly and illegal
        +		 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
        +		 * Otherwise the code police will come and get us.)
        +		 */
        +		int old_mh_mode;
        +
        +		CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
        +
        +		/* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
        +		 * which uses CRYPTO_is_mem_check_on */
        +		old_mh_mode = mh_mode;
        +		mh_mode = CRYPTO_MEM_CHECK_OFF;
        +
        +		if (mh != NULL)
        +			{
        +			lh_MEM_free(mh);
        +			mh = NULL;
        +			}
        +		if (amih != NULL)
        +			{
        +			if (lh_APP_INFO_num_items(amih) == 0) 
        +				{
        +				lh_APP_INFO_free(amih);
        +				amih = NULL;
        +				}
        +			}
        +
        +		mh_mode = old_mh_mode;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
        +		}
        +	MemCheck_on(); /* release MALLOC2 lock */
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +void CRYPTO_mem_leaks_fp(FILE *fp)
        +	{
        +	BIO *b;
        +
        +	if (mh == NULL) return;
        +	/* Need to turn off memory checking when allocated BIOs ... especially
        +	 * as we're creating them at a time when we're trying to check we've not
        +	 * left anything un-free()'d!! */
        +	MemCheck_off();
        +	b = BIO_new(BIO_s_file());
        +	MemCheck_on();
        +	if(!b) return;
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	CRYPTO_mem_leaks(b);
        +	BIO_free(b);
        +	}
        +#endif
        +
        +
        +
        +/* FIXME: We really don't allow much to the callback.  For example, it has
        +   no chance of reaching the info stack for the item it processes.  Should
        +   it really be this way?  -- Richard Levitte */
        +/* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
        + * If this code is restructured, remove the callback type if it is no longer
        + * needed. -- Geoff Thorpe */
        +
        +/* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
        + * is a function pointer and conversion to void * is prohibited. Instead
        + * pass its address
        + */
        +
        +typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
        +
        +static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
        +	{
        +	(*cb)(m->order,m->file,m->line,m->num,m->addr);
        +	}
        +
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
        +
        +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
        +	{
        +	if (mh == NULL) return;
        +	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
        +	lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
        +			 &cb);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/modes/Makefile b/vendor/openssl/openssl/crypto/modes/Makefile
        new file mode 100644
        index 000000000..c825b12f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/Makefile
        @@ -0,0 +1,141 @@
        +#
        +# OpenSSL/crypto/modes/Makefile
        +#
        +
        +DIR=	modes
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +MODES_ASM_OBJ=
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \
        +	ccm128.c xts128.c
        +LIBOBJ= cbc128.o ctr128.o cts128.o cfb128.o ofb128.o gcm128.o \
        +	ccm128.o xts128.o $(MODES_ASM_OBJ)
        +
        +SRC= $(LIBSRC)
        +
        +#EXHEADER= store.h str_compat.h
        +EXHEADER= modes.h
        +HEADER=	modes_lcl.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +ghash-ia64.s:	asm/ghash-ia64.pl
        +	$(PERL) asm/ghash-ia64.pl $@ $(CFLAGS)
        +ghash-x86.s:	asm/ghash-x86.pl
        +	$(PERL) asm/ghash-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +ghash-x86_64.s:	asm/ghash-x86_64.pl
        +	$(PERL) asm/ghash-x86_64.pl $(PERLASM_SCHEME) > $@
        +ghash-sparcv9.s:	asm/ghash-sparcv9.pl
        +	$(PERL) asm/ghash-sparcv9.pl $@ $(CFLAGS)
        +ghash-alpha.s:	asm/ghash-alpha.pl
        +	$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
        +ghash-parisc.s:	asm/ghash-parisc.pl
        +	$(PERL) asm/ghash-parisc.pl $(PERLASM_SCHEME) $@
        +
        +# GNU make "catch all"
        +ghash-%.S:	asm/ghash-%.pl;	$(PERL) $< $(PERLASM_SCHEME) $@
        +
        +ghash-armv4.o:	ghash-armv4.S
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +cbc128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cbc128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +cbc128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cbc128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cbc128.o: ../../include/openssl/symhacks.h cbc128.c modes_lcl.h
        +ccm128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ccm128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +ccm128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ccm128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ccm128.o: ../../include/openssl/symhacks.h ccm128.c modes_lcl.h
        +cfb128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cfb128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +cfb128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cfb128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cfb128.o: ../../include/openssl/symhacks.h cfb128.c modes_lcl.h
        +ctr128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ctr128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +ctr128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ctr128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ctr128.o: ../../include/openssl/symhacks.h ctr128.c modes_lcl.h
        +cts128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +cts128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +cts128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +cts128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +cts128.o: ../../include/openssl/symhacks.h cts128.c modes_lcl.h
        +gcm128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +gcm128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +gcm128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gcm128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +gcm128.o: ../../include/openssl/symhacks.h gcm128.c modes_lcl.h
        +ofb128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ofb128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +ofb128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ofb128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ofb128.o: ../../include/openssl/symhacks.h modes_lcl.h ofb128.c
        +xts128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +xts128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +xts128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +xts128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +xts128.o: ../../include/openssl/symhacks.h modes_lcl.h xts128.c
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-alpha.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-alpha.pl
        new file mode 100644
        index 000000000..6358b2750
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-alpha.pl
        @@ -0,0 +1,451 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# March 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+128 bytes shared table]. Even though
        +# loops are aggressively modulo-scheduled in respect to references to
        +# Htbl and Z.hi updates for 8 cycles per byte, measured performance is
        +# ~12 cycles per processed byte on 21264 CPU. It seems to be a dynamic
        +# scheduling "glitch," because uprofile(1) indicates uniform sample
        +# distribution, as if all instruction bundles execute in 1.5 cycles.
        +# Meaning that it could have been even faster, yet 12 cycles is ~60%
        +# better than gcc-generated code and ~80% than code generated by vendor
        +# compiler.
        +
        +$cnt="v0";	# $0
        +$t0="t0";
        +$t1="t1";
        +$t2="t2";
        +$Thi0="t3";	# $4
        +$Tlo0="t4";
        +$Thi1="t5";
        +$Tlo1="t6";
        +$rem="t7";	# $8
        +#################
        +$Xi="a0";	# $16, input argument block
        +$Htbl="a1";
        +$inp="a2";
        +$len="a3";
        +$nlo="a4";	# $20
        +$nhi="a5";
        +$Zhi="t8";
        +$Zlo="t9";
        +$Xhi="t10";	# $24
        +$Xlo="t11";
        +$remp="t12";
        +$rem_4bit="AT";	# $28
        +
        +{ my $N;
        +  sub loop() {
        +
        +	$N++;
        +$code.=<<___;
        +.align	4
        +	extbl	$Xlo,7,$nlo
        +	and	$nlo,0xf0,$nhi
        +	sll	$nlo,4,$nlo
        +	and	$nlo,0xf0,$nlo
        +
        +	addq	$nlo,$Htbl,$nlo
        +	ldq	$Zlo,8($nlo)
        +	addq	$nhi,$Htbl,$nhi
        +	ldq	$Zhi,0($nlo)
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	lda	$cnt,6(zero)
        +	extbl	$Xlo,6,$nlo
        +
        +	ldq	$Tlo1,8($nhi)
        +	s8addq	$remp,$rem_4bit,$remp
        +	ldq	$Thi1,0($nhi)
        +	srl	$Zlo,4,$Zlo
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	xor	$t0,$Zlo,$Zlo
        +	and	$nlo,0xf0,$nhi
        +
        +	xor	$Tlo1,$Zlo,$Zlo
        +	sll	$nlo,4,$nlo
        +	xor	$Thi1,$Zhi,$Zhi
        +	and	$nlo,0xf0,$nlo
        +
        +	addq	$nlo,$Htbl,$nlo
        +	ldq	$Tlo0,8($nlo)
        +	addq	$nhi,$Htbl,$nhi
        +	ldq	$Thi0,0($nlo)
        +
        +.Looplo$N:
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	subq	$cnt,1,$cnt
        +	srl	$Zlo,4,$Zlo
        +
        +	ldq	$Tlo1,8($nhi)
        +	xor	$rem,$Zhi,$Zhi
        +	ldq	$Thi1,0($nhi)
        +	s8addq	$remp,$rem_4bit,$remp
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	xor	$t0,$Zlo,$Zlo
        +	extbl	$Xlo,$cnt,$nlo
        +
        +	and	$nlo,0xf0,$nhi
        +	xor	$Thi0,$Zhi,$Zhi
        +	xor	$Tlo0,$Zlo,$Zlo
        +	sll	$nlo,4,$nlo
        +
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	and	$nlo,0xf0,$nlo
        +	srl	$Zlo,4,$Zlo
        +
        +	s8addq	$remp,$rem_4bit,$remp
        +	xor	$rem,$Zhi,$Zhi
        +	addq	$nlo,$Htbl,$nlo
        +	addq	$nhi,$Htbl,$nhi
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	ldq	$Tlo0,8($nlo)
        +	xor	$t0,$Zlo,$Zlo
        +
        +	xor	$Tlo1,$Zlo,$Zlo
        +	xor	$Thi1,$Zhi,$Zhi
        +	ldq	$Thi0,0($nlo)
        +	bne	$cnt,.Looplo$N
        +
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	lda	$cnt,7(zero)
        +	srl	$Zlo,4,$Zlo
        +
        +	ldq	$Tlo1,8($nhi)
        +	xor	$rem,$Zhi,$Zhi
        +	ldq	$Thi1,0($nhi)
        +	s8addq	$remp,$rem_4bit,$remp
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	xor	$t0,$Zlo,$Zlo
        +	extbl	$Xhi,$cnt,$nlo
        +
        +	and	$nlo,0xf0,$nhi
        +	xor	$Thi0,$Zhi,$Zhi
        +	xor	$Tlo0,$Zlo,$Zlo
        +	sll	$nlo,4,$nlo
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	and	$nlo,0xf0,$nlo
        +	srl	$Zlo,4,$Zlo
        +
        +	s8addq	$remp,$rem_4bit,$remp
        +	xor	$rem,$Zhi,$Zhi
        +	addq	$nlo,$Htbl,$nlo
        +	addq	$nhi,$Htbl,$nhi
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	ldq	$Tlo0,8($nlo)
        +	xor	$t0,$Zlo,$Zlo
        +
        +	xor	$Tlo1,$Zlo,$Zlo
        +	xor	$Thi1,$Zhi,$Zhi
        +	ldq	$Thi0,0($nlo)
        +	unop
        +
        +
        +.Loophi$N:
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	subq	$cnt,1,$cnt
        +	srl	$Zlo,4,$Zlo
        +
        +	ldq	$Tlo1,8($nhi)
        +	xor	$rem,$Zhi,$Zhi
        +	ldq	$Thi1,0($nhi)
        +	s8addq	$remp,$rem_4bit,$remp
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	xor	$t0,$Zlo,$Zlo
        +	extbl	$Xhi,$cnt,$nlo
        +
        +	and	$nlo,0xf0,$nhi
        +	xor	$Thi0,$Zhi,$Zhi
        +	xor	$Tlo0,$Zlo,$Zlo
        +	sll	$nlo,4,$nlo
        +
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	and	$nlo,0xf0,$nlo
        +	srl	$Zlo,4,$Zlo
        +
        +	s8addq	$remp,$rem_4bit,$remp
        +	xor	$rem,$Zhi,$Zhi
        +	addq	$nlo,$Htbl,$nlo
        +	addq	$nhi,$Htbl,$nhi
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	ldq	$Tlo0,8($nlo)
        +	xor	$t0,$Zlo,$Zlo
        +
        +	xor	$Tlo1,$Zlo,$Zlo
        +	xor	$Thi1,$Zhi,$Zhi
        +	ldq	$Thi0,0($nlo)
        +	bne	$cnt,.Loophi$N
        +
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	srl	$Zlo,4,$Zlo
        +
        +	ldq	$Tlo1,8($nhi)
        +	xor	$rem,$Zhi,$Zhi
        +	ldq	$Thi1,0($nhi)
        +	s8addq	$remp,$rem_4bit,$remp
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	xor	$t0,$Zlo,$Zlo
        +
        +	xor	$Tlo0,$Zlo,$Zlo
        +	xor	$Thi0,$Zhi,$Zhi
        +
        +	and	$Zlo,0x0f,$remp
        +	sll	$Zhi,60,$t0
        +	srl	$Zlo,4,$Zlo
        +
        +	s8addq	$remp,$rem_4bit,$remp
        +	xor	$rem,$Zhi,$Zhi
        +
        +	ldq	$rem,0($remp)
        +	srl	$Zhi,4,$Zhi
        +	xor	$Tlo1,$Zlo,$Zlo
        +	xor	$Thi1,$Zhi,$Zhi
        +	xor	$t0,$Zlo,$Zlo
        +	xor	$rem,$Zhi,$Zhi
        +___
        +}}
        +
        +$code=<<___;
        +#ifdef __linux__
        +#include <asm/regdef.h>
        +#else
        +#include <asm.h>
        +#include <regdef.h>
        +#endif
        +
        +.text
        +
        +.set	noat
        +.set	noreorder
        +.globl	gcm_gmult_4bit
        +.align	4
        +.ent	gcm_gmult_4bit
        +gcm_gmult_4bit:
        +	.frame	sp,0,ra
        +	.prologue 0
        +
        +	ldq	$Xlo,8($Xi)
        +	ldq	$Xhi,0($Xi)
        +
        +	br	$rem_4bit,.Lpic1
        +.Lpic1:	lda	$rem_4bit,rem_4bit-.Lpic1($rem_4bit)
        +___
        +
        +	&loop();
        +
        +$code.=<<___;
        +	srl	$Zlo,24,$t0	# byte swap
        +	srl	$Zlo,8,$t1
        +
        +	sll	$Zlo,8,$t2
        +	sll	$Zlo,24,$Zlo
        +	zapnot	$t0,0x11,$t0
        +	zapnot	$t1,0x22,$t1
        +
        +	zapnot	$Zlo,0x88,$Zlo
        +	or	$t0,$t1,$t0
        +	zapnot	$t2,0x44,$t2
        +
        +	or	$Zlo,$t0,$Zlo
        +	srl	$Zhi,24,$t0
        +	srl	$Zhi,8,$t1
        +
        +	or	$Zlo,$t2,$Zlo
        +	sll	$Zhi,8,$t2
        +	sll	$Zhi,24,$Zhi
        +
        +	srl	$Zlo,32,$Xlo
        +	sll	$Zlo,32,$Zlo
        +
        +	zapnot	$t0,0x11,$t0
        +	zapnot	$t1,0x22,$t1
        +	or	$Zlo,$Xlo,$Xlo
        +
        +	zapnot	$Zhi,0x88,$Zhi
        +	or	$t0,$t1,$t0
        +	zapnot	$t2,0x44,$t2
        +
        +	or	$Zhi,$t0,$Zhi
        +	or	$Zhi,$t2,$Zhi
        +
        +	srl	$Zhi,32,$Xhi
        +	sll	$Zhi,32,$Zhi
        +
        +	or	$Zhi,$Xhi,$Xhi
        +	stq	$Xlo,8($Xi)
        +	stq	$Xhi,0($Xi)
        +
        +	ret	(ra)
        +.end	gcm_gmult_4bit
        +___
        +
        +$inhi="s0";
        +$inlo="s1";
        +
        +$code.=<<___;
        +.globl	gcm_ghash_4bit
        +.align	4
        +.ent	gcm_ghash_4bit
        +gcm_ghash_4bit:
        +	lda	sp,-32(sp)
        +	stq	ra,0(sp)
        +	stq	s0,8(sp)
        +	stq	s1,16(sp)
        +	.mask	0x04000600,-32
        +	.frame	sp,32,ra
        +	.prologue 0
        +
        +	ldq_u	$inhi,0($inp)
        +	ldq_u	$Thi0,7($inp)
        +	ldq_u	$inlo,8($inp)
        +	ldq_u	$Tlo0,15($inp)
        +	ldq	$Xhi,0($Xi)
        +	ldq	$Xlo,8($Xi)
        +
        +	br	$rem_4bit,.Lpic2
        +.Lpic2:	lda	$rem_4bit,rem_4bit-.Lpic2($rem_4bit)
        +
        +.Louter:
        +	extql	$inhi,$inp,$inhi
        +	extqh	$Thi0,$inp,$Thi0
        +	or	$inhi,$Thi0,$inhi
        +	lda	$inp,16($inp)
        +
        +	extql	$inlo,$inp,$inlo
        +	extqh	$Tlo0,$inp,$Tlo0
        +	or	$inlo,$Tlo0,$inlo
        +	subq	$len,16,$len
        +
        +	xor	$Xlo,$inlo,$Xlo
        +	xor	$Xhi,$inhi,$Xhi
        +___
        +
        +	&loop();
        +
        +$code.=<<___;
        +	srl	$Zlo,24,$t0	# byte swap
        +	srl	$Zlo,8,$t1
        +
        +	sll	$Zlo,8,$t2
        +	sll	$Zlo,24,$Zlo
        +	zapnot	$t0,0x11,$t0
        +	zapnot	$t1,0x22,$t1
        +
        +	zapnot	$Zlo,0x88,$Zlo
        +	or	$t0,$t1,$t0
        +	zapnot	$t2,0x44,$t2
        +
        +	or	$Zlo,$t0,$Zlo
        +	srl	$Zhi,24,$t0
        +	srl	$Zhi,8,$t1
        +
        +	or	$Zlo,$t2,$Zlo
        +	sll	$Zhi,8,$t2
        +	sll	$Zhi,24,$Zhi
        +
        +	srl	$Zlo,32,$Xlo
        +	sll	$Zlo,32,$Zlo
        +	beq	$len,.Ldone
        +
        +	zapnot	$t0,0x11,$t0
        +	zapnot	$t1,0x22,$t1
        +	or	$Zlo,$Xlo,$Xlo
        +	ldq_u	$inhi,0($inp)
        +
        +	zapnot	$Zhi,0x88,$Zhi
        +	or	$t0,$t1,$t0
        +	zapnot	$t2,0x44,$t2
        +	ldq_u	$Thi0,7($inp)
        +
        +	or	$Zhi,$t0,$Zhi
        +	or	$Zhi,$t2,$Zhi
        +	ldq_u	$inlo,8($inp)
        +	ldq_u	$Tlo0,15($inp)
        +
        +	srl	$Zhi,32,$Xhi
        +	sll	$Zhi,32,$Zhi
        +
        +	or	$Zhi,$Xhi,$Xhi
        +	br	zero,.Louter
        +
        +.Ldone:
        +	zapnot	$t0,0x11,$t0
        +	zapnot	$t1,0x22,$t1
        +	or	$Zlo,$Xlo,$Xlo
        +
        +	zapnot	$Zhi,0x88,$Zhi
        +	or	$t0,$t1,$t0
        +	zapnot	$t2,0x44,$t2
        +
        +	or	$Zhi,$t0,$Zhi
        +	or	$Zhi,$t2,$Zhi
        +
        +	srl	$Zhi,32,$Xhi
        +	sll	$Zhi,32,$Zhi
        +
        +	or	$Zhi,$Xhi,$Xhi
        +
        +	stq	$Xlo,8($Xi)
        +	stq	$Xhi,0($Xi)
        +
        +	.set	noreorder
        +	/*ldq	ra,0(sp)*/
        +	ldq	s0,8(sp)
        +	ldq	s1,16(sp)
        +	lda	sp,32(sp)
        +	ret	(ra)
        +.end	gcm_ghash_4bit
        +
        +.align	4
        +rem_4bit:
        +	.quad	0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48
        +	.quad	0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48
        +	.quad	0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48
        +	.quad	0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48
        +.ascii	"GHASH for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	4
        +
        +___
        +$output=shift and open STDOUT,">$output";
        +print $code;
        +close STDOUT;
        +
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-armv4.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-armv4.pl
        new file mode 100644
        index 000000000..d91586ee2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-armv4.pl
        @@ -0,0 +1,429 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# April 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+32 bytes shared table]. There is no
        +# experimental performance data available yet. The only approximation
        +# that can be made at this point is based on code size. Inner loop is
        +# 32 instructions long and on single-issue core should execute in <40
        +# cycles. Having verified that gcc 3.4 didn't unroll corresponding
        +# loop, this assembler loop body was found to be ~3x smaller than
        +# compiler-generated one...
        +#
        +# July 2010
        +#
        +# Rescheduling for dual-issue pipeline resulted in 8.5% improvement on
        +# Cortex A8 core and ~25 cycles per processed byte (which was observed
        +# to be ~3 times faster than gcc-generated code:-)
        +#
        +# February 2011
        +#
        +# Profiler-assisted and platform-specific optimization resulted in 7%
        +# improvement on Cortex A8 core and ~23.5 cycles per byte.
        +#
        +# March 2011
        +#
        +# Add NEON implementation featuring polynomial multiplication, i.e. no
        +# lookup tables involved. On Cortex A8 it was measured to process one
        +# byte in 15 cycles or 55% faster than integer-only code.
        +
        +# ====================================================================
        +# Note about "528B" variant. In ARM case it makes lesser sense to
        +# implement it for following reasons:
        +#
        +# - performance improvement won't be anywhere near 50%, because 128-
        +#   bit shift operation is neatly fused with 128-bit xor here, and
        +#   "538B" variant would eliminate only 4-5 instructions out of 32
        +#   in the inner loop (meaning that estimated improvement is ~15%);
        +# - ARM-based systems are often embedded ones and extra memory
        +#   consumption might be unappreciated (for so little improvement);
        +#
        +# Byte order [in]dependence. =========================================
        +#
        +# Caller is expected to maintain specific *dword* order in Htable,
        +# namely with *least* significant dword of 128-bit value at *lower*
        +# address. This differs completely from C code and has everything to
        +# do with ldm instruction and order in which dwords are "consumed" by
        +# algorithm. *Byte* order within these dwords in turn is whatever
        +# *native* byte order on current platform. See gcm128.c for working
        +# example...
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$Xi="r0";	# argument block
        +$Htbl="r1";
        +$inp="r2";
        +$len="r3";
        +
        +$Zll="r4";	# variables
        +$Zlh="r5";
        +$Zhl="r6";
        +$Zhh="r7";
        +$Tll="r8";
        +$Tlh="r9";
        +$Thl="r10";
        +$Thh="r11";
        +$nlo="r12";
        +################# r13 is stack pointer
        +$nhi="r14";
        +################# r15 is program counter
        +
        +$rem_4bit=$inp;	# used in gcm_gmult_4bit
        +$cnt=$len;
        +
        +sub Zsmash() {
        +  my $i=12;
        +  my @args=@_;
        +  for ($Zll,$Zlh,$Zhl,$Zhh) {
        +    $code.=<<___;
        +#if __ARM_ARCH__>=7 && defined(__ARMEL__)
        +	rev	$_,$_
        +	str	$_,[$Xi,#$i]
        +#elif defined(__ARMEB__)
        +	str	$_,[$Xi,#$i]
        +#else
        +	mov	$Tlh,$_,lsr#8
        +	strb	$_,[$Xi,#$i+3]
        +	mov	$Thl,$_,lsr#16
        +	strb	$Tlh,[$Xi,#$i+2]
        +	mov	$Thh,$_,lsr#24
        +	strb	$Thl,[$Xi,#$i+1]
        +	strb	$Thh,[$Xi,#$i]
        +#endif
        +___
        +    $code.="\t".shift(@args)."\n";
        +    $i-=4;
        +  }
        +}
        +
        +$code=<<___;
        +#include "arm_arch.h"
        +
        +.text
        +.code	32
        +
        +.type	rem_4bit,%object
        +.align	5
        +rem_4bit:
        +.short	0x0000,0x1C20,0x3840,0x2460
        +.short	0x7080,0x6CA0,0x48C0,0x54E0
        +.short	0xE100,0xFD20,0xD940,0xC560
        +.short	0x9180,0x8DA0,0xA9C0,0xB5E0
        +.size	rem_4bit,.-rem_4bit
        +
        +.type	rem_4bit_get,%function
        +rem_4bit_get:
        +	sub	$rem_4bit,pc,#8
        +	sub	$rem_4bit,$rem_4bit,#32	@ &rem_4bit
        +	b	.Lrem_4bit_got
        +	nop
        +.size	rem_4bit_get,.-rem_4bit_get
        +
        +.global	gcm_ghash_4bit
        +.type	gcm_ghash_4bit,%function
        +gcm_ghash_4bit:
        +	sub	r12,pc,#8
        +	add	$len,$inp,$len		@ $len to point at the end
        +	stmdb	sp!,{r3-r11,lr}		@ save $len/end too
        +	sub	r12,r12,#48		@ &rem_4bit
        +
        +	ldmia	r12,{r4-r11}		@ copy rem_4bit ...
        +	stmdb	sp!,{r4-r11}		@ ... to stack
        +
        +	ldrb	$nlo,[$inp,#15]
        +	ldrb	$nhi,[$Xi,#15]
        +.Louter:
        +	eor	$nlo,$nlo,$nhi
        +	and	$nhi,$nlo,#0xf0
        +	and	$nlo,$nlo,#0x0f
        +	mov	$cnt,#14
        +
        +	add	$Zhh,$Htbl,$nlo,lsl#4
        +	ldmia	$Zhh,{$Zll-$Zhh}	@ load Htbl[nlo]
        +	add	$Thh,$Htbl,$nhi
        +	ldrb	$nlo,[$inp,#14]
        +
        +	and	$nhi,$Zll,#0xf		@ rem
        +	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
        +	add	$nhi,$nhi,$nhi
        +	eor	$Zll,$Tll,$Zll,lsr#4
        +	ldrh	$Tll,[sp,$nhi]		@ rem_4bit[rem]
        +	eor	$Zll,$Zll,$Zlh,lsl#28
        +	ldrb	$nhi,[$Xi,#14]
        +	eor	$Zlh,$Tlh,$Zlh,lsr#4
        +	eor	$Zlh,$Zlh,$Zhl,lsl#28
        +	eor	$Zhl,$Thl,$Zhl,lsr#4
        +	eor	$Zhl,$Zhl,$Zhh,lsl#28
        +	eor	$Zhh,$Thh,$Zhh,lsr#4
        +	eor	$nlo,$nlo,$nhi
        +	and	$nhi,$nlo,#0xf0
        +	and	$nlo,$nlo,#0x0f
        +	eor	$Zhh,$Zhh,$Tll,lsl#16
        +
        +.Linner:
        +	add	$Thh,$Htbl,$nlo,lsl#4
        +	and	$nlo,$Zll,#0xf		@ rem
        +	subs	$cnt,$cnt,#1
        +	add	$nlo,$nlo,$nlo
        +	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nlo]
        +	eor	$Zll,$Tll,$Zll,lsr#4
        +	eor	$Zll,$Zll,$Zlh,lsl#28
        +	eor	$Zlh,$Tlh,$Zlh,lsr#4
        +	eor	$Zlh,$Zlh,$Zhl,lsl#28
        +	ldrh	$Tll,[sp,$nlo]		@ rem_4bit[rem]
        +	eor	$Zhl,$Thl,$Zhl,lsr#4
        +	ldrplb	$nlo,[$inp,$cnt]
        +	eor	$Zhl,$Zhl,$Zhh,lsl#28
        +	eor	$Zhh,$Thh,$Zhh,lsr#4
        +
        +	add	$Thh,$Htbl,$nhi
        +	and	$nhi,$Zll,#0xf		@ rem
        +	eor	$Zhh,$Zhh,$Tll,lsl#16	@ ^= rem_4bit[rem]
        +	add	$nhi,$nhi,$nhi
        +	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
        +	eor	$Zll,$Tll,$Zll,lsr#4
        +	ldrplb	$Tll,[$Xi,$cnt]
        +	eor	$Zll,$Zll,$Zlh,lsl#28
        +	eor	$Zlh,$Tlh,$Zlh,lsr#4
        +	ldrh	$Tlh,[sp,$nhi]
        +	eor	$Zlh,$Zlh,$Zhl,lsl#28
        +	eor	$Zhl,$Thl,$Zhl,lsr#4
        +	eor	$Zhl,$Zhl,$Zhh,lsl#28
        +	eorpl	$nlo,$nlo,$Tll
        +	eor	$Zhh,$Thh,$Zhh,lsr#4
        +	andpl	$nhi,$nlo,#0xf0
        +	andpl	$nlo,$nlo,#0x0f
        +	eor	$Zhh,$Zhh,$Tlh,lsl#16	@ ^= rem_4bit[rem]
        +	bpl	.Linner
        +
        +	ldr	$len,[sp,#32]		@ re-load $len/end
        +	add	$inp,$inp,#16
        +	mov	$nhi,$Zll
        +___
        +	&Zsmash("cmp\t$inp,$len","ldrneb\t$nlo,[$inp,#15]");
        +$code.=<<___;
        +	bne	.Louter
        +
        +	add	sp,sp,#36
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r11,pc}
        +#else
        +	ldmia	sp!,{r4-r11,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size	gcm_ghash_4bit,.-gcm_ghash_4bit
        +
        +.global	gcm_gmult_4bit
        +.type	gcm_gmult_4bit,%function
        +gcm_gmult_4bit:
        +	stmdb	sp!,{r4-r11,lr}
        +	ldrb	$nlo,[$Xi,#15]
        +	b	rem_4bit_get
        +.Lrem_4bit_got:
        +	and	$nhi,$nlo,#0xf0
        +	and	$nlo,$nlo,#0x0f
        +	mov	$cnt,#14
        +
        +	add	$Zhh,$Htbl,$nlo,lsl#4
        +	ldmia	$Zhh,{$Zll-$Zhh}	@ load Htbl[nlo]
        +	ldrb	$nlo,[$Xi,#14]
        +
        +	add	$Thh,$Htbl,$nhi
        +	and	$nhi,$Zll,#0xf		@ rem
        +	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
        +	add	$nhi,$nhi,$nhi
        +	eor	$Zll,$Tll,$Zll,lsr#4
        +	ldrh	$Tll,[$rem_4bit,$nhi]	@ rem_4bit[rem]
        +	eor	$Zll,$Zll,$Zlh,lsl#28
        +	eor	$Zlh,$Tlh,$Zlh,lsr#4
        +	eor	$Zlh,$Zlh,$Zhl,lsl#28
        +	eor	$Zhl,$Thl,$Zhl,lsr#4
        +	eor	$Zhl,$Zhl,$Zhh,lsl#28
        +	eor	$Zhh,$Thh,$Zhh,lsr#4
        +	and	$nhi,$nlo,#0xf0
        +	eor	$Zhh,$Zhh,$Tll,lsl#16
        +	and	$nlo,$nlo,#0x0f
        +
        +.Loop:
        +	add	$Thh,$Htbl,$nlo,lsl#4
        +	and	$nlo,$Zll,#0xf		@ rem
        +	subs	$cnt,$cnt,#1
        +	add	$nlo,$nlo,$nlo
        +	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nlo]
        +	eor	$Zll,$Tll,$Zll,lsr#4
        +	eor	$Zll,$Zll,$Zlh,lsl#28
        +	eor	$Zlh,$Tlh,$Zlh,lsr#4
        +	eor	$Zlh,$Zlh,$Zhl,lsl#28
        +	ldrh	$Tll,[$rem_4bit,$nlo]	@ rem_4bit[rem]
        +	eor	$Zhl,$Thl,$Zhl,lsr#4
        +	ldrplb	$nlo,[$Xi,$cnt]
        +	eor	$Zhl,$Zhl,$Zhh,lsl#28
        +	eor	$Zhh,$Thh,$Zhh,lsr#4
        +
        +	add	$Thh,$Htbl,$nhi
        +	and	$nhi,$Zll,#0xf		@ rem
        +	eor	$Zhh,$Zhh,$Tll,lsl#16	@ ^= rem_4bit[rem]
        +	add	$nhi,$nhi,$nhi
        +	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
        +	eor	$Zll,$Tll,$Zll,lsr#4
        +	eor	$Zll,$Zll,$Zlh,lsl#28
        +	eor	$Zlh,$Tlh,$Zlh,lsr#4
        +	ldrh	$Tll,[$rem_4bit,$nhi]	@ rem_4bit[rem]
        +	eor	$Zlh,$Zlh,$Zhl,lsl#28
        +	eor	$Zhl,$Thl,$Zhl,lsr#4
        +	eor	$Zhl,$Zhl,$Zhh,lsl#28
        +	eor	$Zhh,$Thh,$Zhh,lsr#4
        +	andpl	$nhi,$nlo,#0xf0
        +	andpl	$nlo,$nlo,#0x0f
        +	eor	$Zhh,$Zhh,$Tll,lsl#16	@ ^= rem_4bit[rem]
        +	bpl	.Loop
        +___
        +	&Zsmash();
        +$code.=<<___;
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r11,pc}
        +#else
        +	ldmia	sp!,{r4-r11,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size	gcm_gmult_4bit,.-gcm_gmult_4bit
        +___
        +{
        +my $cnt=$Htbl;	# $Htbl is used once in the very beginning
        +
        +my ($Hhi, $Hlo, $Zo, $T, $xi, $mod) = map("d$_",(0..7));
        +my ($Qhi, $Qlo, $Z,  $R, $zero, $Qpost, $IN) = map("q$_",(8..15));
        +
        +# Z:Zo keeps 128-bit result shifted by 1 to the right, with bottom bit
        +# in Zo. Or should I say "top bit", because GHASH is specified in
        +# reverse bit order? Otherwise straightforward 128-bt H by one input
        +# byte multiplication and modulo-reduction, times 16.
        +
        +sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
        +sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
        +sub Q()     { shift=~m|d([1-3]?[02468])|?"q".($1/2):""; }
        +
        +$code.=<<___;
        +#if __ARM_ARCH__>=7
        +.fpu	neon
        +
        +.global	gcm_gmult_neon
        +.type	gcm_gmult_neon,%function
        +.align	4
        +gcm_gmult_neon:
        +	sub		$Htbl,#16		@ point at H in GCM128_CTX
        +	vld1.64		`&Dhi("$IN")`,[$Xi,:64]!@ load Xi
        +	vmov.i32	$mod,#0xe1		@ our irreducible polynomial
        +	vld1.64		`&Dlo("$IN")`,[$Xi,:64]!
        +	vshr.u64	$mod,#32
        +	vldmia		$Htbl,{$Hhi-$Hlo}	@ load H
        +	veor		$zero,$zero
        +#ifdef __ARMEL__
        +	vrev64.8	$IN,$IN
        +#endif
        +	veor		$Qpost,$Qpost
        +	veor		$R,$R
        +	mov		$cnt,#16
        +	veor		$Z,$Z
        +	mov		$len,#16
        +	veor		$Zo,$Zo
        +	vdup.8		$xi,`&Dlo("$IN")`[0]	@ broadcast lowest byte
        +	b		.Linner_neon
        +.size	gcm_gmult_neon,.-gcm_gmult_neon
        +
        +.global	gcm_ghash_neon
        +.type	gcm_ghash_neon,%function
        +.align	4
        +gcm_ghash_neon:
        +	vld1.64		`&Dhi("$Z")`,[$Xi,:64]!	@ load Xi
        +	vmov.i32	$mod,#0xe1		@ our irreducible polynomial
        +	vld1.64		`&Dlo("$Z")`,[$Xi,:64]!
        +	vshr.u64	$mod,#32
        +	vldmia		$Xi,{$Hhi-$Hlo}		@ load H
        +	veor		$zero,$zero
        +	nop
        +#ifdef __ARMEL__
        +	vrev64.8	$Z,$Z
        +#endif
        +.Louter_neon:
        +	vld1.64		`&Dhi($IN)`,[$inp]!	@ load inp
        +	veor		$Qpost,$Qpost
        +	vld1.64		`&Dlo($IN)`,[$inp]!
        +	veor		$R,$R
        +	mov		$cnt,#16
        +#ifdef __ARMEL__
        +	vrev64.8	$IN,$IN
        +#endif
        +	veor		$Zo,$Zo
        +	veor		$IN,$Z			@ inp^=Xi
        +	veor		$Z,$Z
        +	vdup.8		$xi,`&Dlo("$IN")`[0]	@ broadcast lowest byte
        +.Linner_neon:
        +	subs		$cnt,$cnt,#1
        +	vmull.p8	$Qlo,$Hlo,$xi		@ H.lo·Xi[i]
        +	vmull.p8	$Qhi,$Hhi,$xi		@ H.hi·Xi[i]
        +	vext.8		$IN,$zero,#1		@ IN>>=8
        +
        +	veor		$Z,$Qpost		@ modulo-scheduled part
        +	vshl.i64	`&Dlo("$R")`,#48
        +	vdup.8		$xi,`&Dlo("$IN")`[0]	@ broadcast lowest byte
        +	veor		$T,`&Dlo("$Qlo")`,`&Dlo("$Z")`
        +
        +	veor		`&Dhi("$Z")`,`&Dlo("$R")`
        +	vuzp.8		$Qlo,$Qhi
        +	vsli.8		$Zo,$T,#1		@ compose the "carry" byte
        +	vext.8		$Z,$zero,#1		@ Z>>=8
        +
        +	vmull.p8	$R,$Zo,$mod		@ "carry"·0xe1
        +	vshr.u8		$Zo,$T,#7		@ save Z's bottom bit
        +	vext.8		$Qpost,$Qlo,$zero,#1	@ Qlo>>=8
        +	veor		$Z,$Qhi
        +	bne		.Linner_neon
        +
        +	veor		$Z,$Qpost		@ modulo-scheduled artefact
        +	vshl.i64	`&Dlo("$R")`,#48
        +	veor		`&Dhi("$Z")`,`&Dlo("$R")`
        +
        +	@ finalization, normalize Z:Zo
        +	vand		$Zo,$mod		@ suffices to mask the bit
        +	vshr.u64	`&Dhi(&Q("$Zo"))`,`&Dlo("$Z")`,#63
        +	vshl.i64	$Z,#1
        +	subs		$len,#16
        +	vorr		$Z,`&Q("$Zo")`		@ Z=Z:Zo<<1
        +	bne		.Louter_neon
        +
        +#ifdef __ARMEL__
        +	vrev64.8	$Z,$Z
        +#endif
        +	sub		$Xi,#16	
        +	vst1.64		`&Dhi("$Z")`,[$Xi,:64]!	@ write out Xi
        +	vst1.64		`&Dlo("$Z")`,[$Xi,:64]
        +
        +	bx	lr
        +.size	gcm_ghash_neon,.-gcm_ghash_neon
        +#endif
        +___
        +}
        +$code.=<<___;
        +.asciz  "GHASH for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
        +.align  2
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT; # enforce flush
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-ia64.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-ia64.pl
        new file mode 100644
        index 000000000..0354c9544
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-ia64.pl
        @@ -0,0 +1,463 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# March 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+128 bytes shared table]. Streamed
        +# GHASH performance was measured to be 6.67 cycles per processed byte
        +# on Itanium 2, which is >90% better than Microsoft compiler generated
        +# code. To anchor to something else sha1-ia64.pl module processes one
        +# byte in 5.7 cycles. On Itanium GHASH should run at ~8.5 cycles per
        +# byte.
        +
        +# September 2010
        +#
        +# It was originally thought that it makes lesser sense to implement
        +# "528B" variant on Itanium 2 for following reason. Because number of
        +# functional units is naturally limited, it appeared impossible to
        +# implement "528B" loop in 4 cycles, only in 5. This would mean that
        +# theoretically performance improvement couldn't be more than 20%.
        +# But occasionally you prove yourself wrong:-) I figured out a way to
        +# fold couple of instructions and having freed yet another instruction
        +# slot by unrolling the loop... Resulting performance is 4.45 cycles
        +# per processed byte and 50% better than "256B" version. On original
        +# Itanium performance should remain the same as the "256B" version,
        +# i.e. ~8.5 cycles.
        +
        +$output=shift and (open STDOUT,">$output" or die "can't open $output: $!");
        +
        +if ($^O eq "hpux") {
        +    $ADDP="addp4";
        +    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
        +} else { $ADDP="add"; }
        +for (@ARGV)  {  $big_endian=1 if (/\-DB_ENDIAN/);
        +                $big_endian=0 if (/\-DL_ENDIAN/);  }
        +if (!defined($big_endian))
        +             {  $big_endian=(unpack('L',pack('N',1))==1);  }
        +
        +sub loop() {
        +my $label=shift;
        +my ($p16,$p17)=(shift)?("p63","p63"):("p16","p17"); # mask references to inp
        +
        +# Loop is scheduled for 6 ticks on Itanium 2 and 8 on Itanium, i.e.
        +# in scalable manner;-) Naturally assuming data in L1 cache...
        +# Special note about 'dep' instruction, which is used to construct
        +# &rem_4bit[Zlo&0xf]. It works, because rem_4bit is aligned at 128
        +# bytes boundary and lower 7 bits of its address are guaranteed to
        +# be zero.
        +$code.=<<___;
        +$label:
        +{ .mfi;	(p18)	ld8	Hlo=[Hi[1]],-8
        +	(p19)	dep	rem=Zlo,rem_4bitp,3,4	}
        +{ .mfi;	(p19)	xor	Zhi=Zhi,Hhi
        +	($p17)	xor	xi[1]=xi[1],in[1]	};;
        +{ .mfi;	(p18)	ld8	Hhi=[Hi[1]]
        +	(p19)	shrp	Zlo=Zhi,Zlo,4		}
        +{ .mfi;	(p19)	ld8	rem=[rem]
        +	(p18)	and	Hi[1]=mask0xf0,xi[2]	};;
        +{ .mmi;	($p16)	ld1	in[0]=[inp],-1
        +	(p18)	xor	Zlo=Zlo,Hlo
        +	(p19)	shr.u	Zhi=Zhi,4		}
        +{ .mib;	(p19)	xor	Hhi=Hhi,rem
        +	(p18)	add	Hi[1]=Htbl,Hi[1]	};;
        +
        +{ .mfi;	(p18)	ld8	Hlo=[Hi[1]],-8
        +	(p18)	dep	rem=Zlo,rem_4bitp,3,4	}
        +{ .mfi;	(p17)	shladd	Hi[0]=xi[1],4,r0
        +	(p18)	xor	Zhi=Zhi,Hhi		};;
        +{ .mfi;	(p18)	ld8	Hhi=[Hi[1]]
        +	(p18)	shrp	Zlo=Zhi,Zlo,4		}
        +{ .mfi;	(p18)	ld8	rem=[rem]
        +	(p17)	and	Hi[0]=mask0xf0,Hi[0]	};;
        +{ .mmi;	(p16)	ld1	xi[0]=[Xi],-1
        +	(p18)	xor	Zlo=Zlo,Hlo
        +	(p18)	shr.u	Zhi=Zhi,4		}
        +{ .mib;	(p18)	xor	Hhi=Hhi,rem
        +	(p17)	add	Hi[0]=Htbl,Hi[0]
        +	br.ctop.sptk	$label			};;
        +___
        +}
        +
        +$code=<<___;
        +.explicit
        +.text
        +
        +prevfs=r2;	prevlc=r3;	prevpr=r8;
        +mask0xf0=r21;
        +rem=r22;	rem_4bitp=r23;
        +Xi=r24;		Htbl=r25;
        +inp=r26;	end=r27;
        +Hhi=r28;	Hlo=r29;
        +Zhi=r30;	Zlo=r31;
        +
        +.align	128
        +.skip	16					// aligns loop body
        +.global	gcm_gmult_4bit#
        +.proc	gcm_gmult_4bit#
        +gcm_gmult_4bit:
        +	.prologue
        +{ .mmi;	.save	ar.pfs,prevfs
        +	alloc	prevfs=ar.pfs,2,6,0,8
        +	$ADDP	Xi=15,in0			// &Xi[15]
        +	mov	rem_4bitp=ip		}
        +{ .mii;	$ADDP	Htbl=8,in1			// &Htbl[0].lo
        +	.save	ar.lc,prevlc
        +	mov	prevlc=ar.lc
        +	.save	pr,prevpr
        +	mov	prevpr=pr		};;
        +
        +	.body
        +	.rotr	in[3],xi[3],Hi[2]
        +
        +{ .mib;	ld1	xi[2]=[Xi],-1			// Xi[15]
        +	mov	mask0xf0=0xf0
        +	brp.loop.imp	.Loop1,.Lend1-16};;
        +{ .mmi;	ld1	xi[1]=[Xi],-1			// Xi[14]
        +					};;
        +{ .mii;	shladd	Hi[1]=xi[2],4,r0
        +	mov	pr.rot=0x7<<16
        +	mov	ar.lc=13		};;
        +{ .mii;	and	Hi[1]=mask0xf0,Hi[1]
        +	mov	ar.ec=3
        +	xor	Zlo=Zlo,Zlo		};;
        +{ .mii;	add	Hi[1]=Htbl,Hi[1]		// &Htbl[nlo].lo
        +	add	rem_4bitp=rem_4bit#-gcm_gmult_4bit#,rem_4bitp
        +	xor	Zhi=Zhi,Zhi		};;
        +___
        +	&loop	(".Loop1",1);
        +$code.=<<___;
        +.Lend1:
        +{ .mib;	xor	Zhi=Zhi,Hhi		};;	// modulo-scheduling artefact
        +{ .mib;	mux1	Zlo=Zlo,\@rev		};;
        +{ .mib;	mux1	Zhi=Zhi,\@rev		};;
        +{ .mmi;	add	Hlo=9,Xi;;			// ;; is here to prevent
        +	add	Hhi=1,Xi		};;	// pipeline flush on Itanium
        +{ .mib;	st8	[Hlo]=Zlo
        +	mov	pr=prevpr,0x1ffff	};;
        +{ .mib;	st8	[Hhi]=Zhi
        +	mov	ar.lc=prevlc
        +	br.ret.sptk.many	b0	};;
        +.endp	gcm_gmult_4bit#
        +___
        +
        +######################################################################
        +# "528B" (well, "512B" actualy) streamed GHASH
        +#
        +$Xip="in0";
        +$Htbl="in1";
        +$inp="in2";
        +$len="in3";
        +$rem_8bit="loc0";
        +$mask0xff="loc1";
        +($sum,$rum) = $big_endian ? ("nop.m","nop.m") : ("sum","rum");
        +
        +sub load_htable() {
        +    for (my $i=0;$i<8;$i++) {
        +	$code.=<<___;
        +{ .mmi;	ld8	r`16+2*$i+1`=[r8],16		// Htable[$i].hi
        +	ld8	r`16+2*$i`=[r9],16	}	// Htable[$i].lo
        +{ .mmi;	ldf8	f`32+2*$i+1`=[r10],16		// Htable[`8+$i`].hi
        +	ldf8	f`32+2*$i`=[r11],16		// Htable[`8+$i`].lo
        +___
        +	$code.=shift	if (($i+$#_)==7);
        +	$code.="\t};;\n"
        +    }
        +}
        +
        +$code.=<<___;
        +prevsp=r3;
        +
        +.align	32
        +.skip	16					// aligns loop body
        +.global	gcm_ghash_4bit#
        +.proc	gcm_ghash_4bit#
        +gcm_ghash_4bit:
        +	.prologue
        +{ .mmi;	.save	ar.pfs,prevfs
        +	alloc	prevfs=ar.pfs,4,2,0,0
        +	.vframe	prevsp
        +	mov	prevsp=sp
        +	mov	$rem_8bit=ip		};;
        +	.body
        +{ .mfi;	$ADDP	r8=0+0,$Htbl
        +	$ADDP	r9=0+8,$Htbl		}
        +{ .mfi;	$ADDP	r10=128+0,$Htbl
        +	$ADDP	r11=128+8,$Htbl		};;
        +___
        +	&load_htable(
        +	"	$ADDP	$Xip=15,$Xip",		# &Xi[15]
        +	"	$ADDP	$len=$len,$inp",	# &inp[len]
        +	"	$ADDP	$inp=15,$inp",		# &inp[15]
        +	"	mov	$mask0xff=0xff",
        +	"	add	sp=-512,sp",
        +	"	andcm	sp=sp,$mask0xff",	# align stack frame
        +	"	add	r14=0,sp",
        +	"	add	r15=8,sp");
        +$code.=<<___;
        +{ .mmi;	$sum	1<<1				// go big-endian
        +	add	r8=256+0,sp
        +	add	r9=256+8,sp		}
        +{ .mmi;	add	r10=256+128+0,sp
        +	add	r11=256+128+8,sp
        +	add	$len=-17,$len		};;
        +___
        +for($i=0;$i<8;$i++) {	# generate first half of Hshr4[]
        +my ($rlo,$rhi)=("r".eval(16+2*$i),"r".eval(16+2*$i+1));
        +$code.=<<___;
        +{ .mmi;	st8	[r8]=$rlo,16			// Htable[$i].lo
        +	st8	[r9]=$rhi,16			// Htable[$i].hi
        +	shrp	$rlo=$rhi,$rlo,4	}//;;
        +{ .mmi;	stf8	[r10]=f`32+2*$i`,16		// Htable[`8+$i`].lo
        +	stf8	[r11]=f`32+2*$i+1`,16		// Htable[`8+$i`].hi
        +	shr.u	$rhi=$rhi,4		};;
        +{ .mmi;	st8	[r14]=$rlo,16			// Htable[$i].lo>>4
        +	st8	[r15]=$rhi,16		}//;;	// Htable[$i].hi>>4
        +___
        +}
        +$code.=<<___;
        +{ .mmi;	ld8	r16=[r8],16			// Htable[8].lo
        +	ld8	r17=[r9],16		};;	// Htable[8].hi
        +{ .mmi;	ld8	r18=[r8],16			// Htable[9].lo
        +	ld8	r19=[r9],16		}	// Htable[9].hi
        +{ .mmi;	rum	1<<5				// clear um.mfh
        +	shrp	r16=r17,r16,4		};;
        +___
        +for($i=0;$i<6;$i++) {	# generate second half of Hshr4[]
        +$code.=<<___;
        +{ .mmi;	ld8	r`20+2*$i`=[r8],16		// Htable[`10+$i`].lo
        +	ld8	r`20+2*$i+1`=[r9],16		// Htable[`10+$i`].hi
        +	shr.u	r`16+2*$i+1`=r`16+2*$i+1`,4	};;
        +{ .mmi;	st8	[r14]=r`16+2*$i`,16		// Htable[`8+$i`].lo>>4
        +	st8	[r15]=r`16+2*$i+1`,16		// Htable[`8+$i`].hi>>4
        +	shrp	r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4	}
        +___
        +}
        +$code.=<<___;
        +{ .mmi;	shr.u	r`16+2*$i+1`=r`16+2*$i+1`,4	};;
        +{ .mmi;	st8	[r14]=r`16+2*$i`,16		// Htable[`8+$i`].lo>>4
        +	st8	[r15]=r`16+2*$i+1`,16		// Htable[`8+$i`].hi>>4
        +	shrp	r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4	}
        +{ .mmi;	add	$Htbl=256,sp			// &Htable[0]
        +	add	$rem_8bit=rem_8bit#-gcm_ghash_4bit#,$rem_8bit
        +	shr.u	r`18+2*$i+1`=r`18+2*$i+1`,4	};;
        +{ .mmi;	st8	[r14]=r`18+2*$i`		// Htable[`8+$i`].lo>>4
        +	st8	[r15]=r`18+2*$i+1`	}	// Htable[`8+$i`].hi>>4
        +___
        +
        +$in="r15";
        +@xi=("r16","r17");
        +@rem=("r18","r19");
        +($Alo,$Ahi,$Blo,$Bhi,$Zlo,$Zhi)=("r20","r21","r22","r23","r24","r25");
        +($Atbl,$Btbl)=("r26","r27");
        +
        +$code.=<<___;	# (p16)
        +{ .mmi;	ld1	$in=[$inp],-1			//(p16) *inp--
        +	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
        +	cmp.eq	p0,p6=r0,r0		};;	//	clear p6
        +___
        +push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
        +
        +$code.=<<___;	# (p16),(p17)
        +{ .mmi;	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
        +	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
        +{ .mii;	ld1	$in=[$inp],-1			//(p16) *inp--
        +	dep	$Atbl=$xi[1],$Htbl,4,4		//(p17) &Htable[nlo].lo
        +	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
        +.align	32
        +.LOOP:
        +{ .mmi;
        +(p6)	st8	[$Xip]=$Zhi,13
        +	xor	$Zlo=$Zlo,$Zlo
        +	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi].lo
        +___
        +push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
        +
        +$code.=<<___;	# (p16),(p17),(p18)
        +{ .mmi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
        +	ld8	$rem[0]=[$Btbl],-256		//(p18) Htable[nhi].lo,&Hshr4[nhi].lo
        +	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
        +{ .mfi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
        +	dep	$Atbl=$xi[1],$Htbl,4,4	}	//(p17) &Htable[nlo].lo
        +{ .mfi;	shladd	$rem[0]=$rem[0],4,r0		//(p18) Htable[nhi].lo<<4
        +	xor	$Zlo=$Zlo,$Alo		};;	//(p18) Z.lo^=Htable[nlo].lo
        +{ .mmi;	ld8	$Blo=[$Btbl],8			//(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
        +	ld1	$in=[$inp],-1		}	//(p16) *inp--
        +{ .mmi;	xor	$rem[0]=$rem[0],$Zlo		//(p18) Z.lo^(Htable[nhi].lo<<4)
        +	mov	$Zhi=$Ahi			//(p18) Z.hi^=Htable[nlo].hi
        +	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
        +{ .mmi;	ld8	$Bhi=[$Btbl]			//(p18) Hshr4[nhi].hi
        +	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
        +	shrp	$Zlo=$Zhi,$Zlo,8	}	//(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
        +{ .mmi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
        +	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi]
        +___
        +push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
        +
        +for ($i=1;$i<14;$i++) {
        +# Above and below fragments are derived from this one by removing
        +# unsuitable (p??) instructions.
        +$code.=<<___;	# (p16),(p17),(p18),(p19)
        +{ .mmi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
        +	ld8	$rem[0]=[$Btbl],-256		//(p18) Htable[nhi].lo,&Hshr4[nhi].lo
        +	shr.u	$Zhi=$Zhi,8		}	//(p19) Z.hi>>=8
        +{ .mmi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
        +	xor	$Zlo=$Zlo,$Blo			//(p19) Z.lo^=Hshr4[nhi].lo
        +	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
        +{ .mmi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
        +	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
        +	dep	$Atbl=$xi[1],$Htbl,4,4	}	//(p17) &Htable[nlo].lo
        +{ .mmi;	shladd	$rem[0]=$rem[0],4,r0		//(p18) Htable[nhi].lo<<4
        +	xor	$Zlo=$Zlo,$Alo			//(p18) Z.lo^=Htable[nlo].lo
        +	xor	$Zhi=$Zhi,$Bhi		};;	//(p19) Z.hi^=Hshr4[nhi].hi
        +{ .mmi;	ld8	$Blo=[$Btbl],8			//(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
        +	ld1	$in=[$inp],-1			//(p16) *inp--
        +	shl	$rem[1]=$rem[1],48	}	//(p19) rem_8bit[rem]<<48
        +{ .mmi;	xor	$rem[0]=$rem[0],$Zlo		//(p18) Z.lo^(Htable[nhi].lo<<4)
        +	xor	$Zhi=$Zhi,$Ahi			//(p18) Z.hi^=Htable[nlo].hi
        +	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
        +{ .mmi;	ld8	$Bhi=[$Btbl]			//(p18) Hshr4[nhi].hi
        +	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
        +	shrp	$Zlo=$Zhi,$Zlo,8	}	//(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
        +{ .mmi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
        +	xor	$Zhi=$Zhi,$rem[1]		//(p19) Z.hi^=rem_8bit[rem]<<48
        +	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi]
        +___
        +push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
        +}
        +
        +$code.=<<___;	# (p17),(p18),(p19)
        +{ .mmi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
        +	ld8	$rem[0]=[$Btbl],-256		//(p18) Htable[nhi].lo,&Hshr4[nhi].lo
        +	shr.u	$Zhi=$Zhi,8		}	//(p19) Z.hi>>=8
        +{ .mmi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
        +	xor	$Zlo=$Zlo,$Blo			//(p19) Z.lo^=Hshr4[nhi].lo
        +	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
        +{ .mmi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
        +	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
        +	dep	$Atbl=$xi[1],$Htbl,4,4	};;	//(p17) &Htable[nlo].lo
        +{ .mmi;	shladd	$rem[0]=$rem[0],4,r0		//(p18) Htable[nhi].lo<<4
        +	xor	$Zlo=$Zlo,$Alo			//(p18) Z.lo^=Htable[nlo].lo
        +	xor	$Zhi=$Zhi,$Bhi		};;	//(p19) Z.hi^=Hshr4[nhi].hi
        +{ .mmi;	ld8	$Blo=[$Btbl],8			//(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
        +	shl	$rem[1]=$rem[1],48	}	//(p19) rem_8bit[rem]<<48
        +{ .mmi;	xor	$rem[0]=$rem[0],$Zlo		//(p18) Z.lo^(Htable[nhi].lo<<4)
        +	xor	$Zhi=$Zhi,$Ahi			//(p18) Z.hi^=Htable[nlo].hi
        +	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
        +{ .mmi;	ld8	$Bhi=[$Btbl]			//(p18) Hshr4[nhi].hi
        +	shrp	$Zlo=$Zhi,$Zlo,8	}	//(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
        +{ .mmi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
        +	xor	$Zhi=$Zhi,$rem[1]		//(p19) Z.hi^=rem_8bit[rem]<<48
        +	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi]
        +___
        +push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
        +
        +$code.=<<___;	# (p18),(p19)
        +{ .mfi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
        +	shr.u	$Zhi=$Zhi,8		}	//(p19) Z.hi>>=8
        +{ .mfi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
        +	xor	$Zlo=$Zlo,$Blo		};;	//(p19) Z.lo^=Hshr4[nhi].lo
        +{ .mfi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
        +	xor	$Zlo=$Zlo,$Alo		}	//(p18) Z.lo^=Htable[nlo].lo
        +{ .mfi;	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
        +	xor	$Zhi=$Zhi,$Bhi		};;	//(p19) Z.hi^=Hshr4[nhi].hi
        +{ .mfi;	ld8	$Blo=[$Btbl],8			//(p18) Htable[nhi].lo,&Htable[nhi].hi
        +	shl	$rem[1]=$rem[1],48	}	//(p19) rem_8bit[rem]<<48
        +{ .mfi;	shladd	$rem[0]=$Zlo,4,r0		//(p18) Z.lo<<4
        +	xor	$Zhi=$Zhi,$Ahi		};;	//(p18) Z.hi^=Htable[nlo].hi
        +{ .mfi;	ld8	$Bhi=[$Btbl]			//(p18) Htable[nhi].hi
        +	shrp	$Zlo=$Zhi,$Zlo,4	}	//(p18) Z.lo=(Z.hi<<60)|(Z.lo>>4)
        +{ .mfi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
        +	xor	$Zhi=$Zhi,$rem[1]	};;	//(p19) Z.hi^=rem_8bit[rem]<<48
        +___
        +push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
        +
        +$code.=<<___;	# (p19)
        +{ .mmi;	cmp.ltu	p6,p0=$inp,$len
        +	add	$inp=32,$inp
        +	shr.u	$Zhi=$Zhi,4		}	//(p19) Z.hi>>=4
        +{ .mmi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
        +	xor	$Zlo=$Zlo,$Blo			//(p19) Z.lo^=Hshr4[nhi].lo
        +	add	$Xip=9,$Xip		};;	//	&Xi.lo
        +{ .mmi;	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
        +(p6)	ld1	$in=[$inp],-1			//[p16] *inp--
        +(p6)	extr.u	$xi[1]=$Zlo,8,8		}	//[p17] Xi[14]
        +{ .mmi;	xor	$Zhi=$Zhi,$Bhi			//(p19) Z.hi^=Hshr4[nhi].hi
        +(p6)	and	$xi[0]=$Zlo,$mask0xff	};;	//[p16] Xi[15]
        +{ .mmi;	st8	[$Xip]=$Zlo,-8
        +(p6)	xor	$xi[0]=$xi[0],$in		//[p17] xi=$xi[i]^inp[i]
        +	shl	$rem[1]=$rem[1],48	};;	//(p19) rem_8bit[rem]<<48
        +{ .mmi;
        +(p6)	ld1	$in=[$inp],-1			//[p16] *inp--
        +	xor	$Zhi=$Zhi,$rem[1]		//(p19) Z.hi^=rem_8bit[rem]<<48
        +(p6)	dep	$Atbl=$xi[0],$Htbl,4,4	}	//[p17] &Htable[nlo].lo
        +{ .mib;
        +(p6)	and	$xi[0]=-16,$xi[0]		//[p17] nhi=xi&0xf0
        +(p6)	br.cond.dptk.many	.LOOP	};;
        +
        +{ .mib;	st8	[$Xip]=$Zhi		};;
        +{ .mib;	$rum	1<<1				// return to little-endian
        +	.restore	sp
        +	mov	sp=prevsp
        +	br.ret.sptk.many	b0	};;
        +.endp	gcm_ghash_4bit#
        +___
        +$code.=<<___;
        +.align	128
        +.type	rem_4bit#,\@object
        +rem_4bit:
        +        data8	0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48
        +        data8	0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48
        +        data8	0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48
        +        data8	0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48
        +.size	rem_4bit#,128
        +.type	rem_8bit#,\@object
        +rem_8bit:
        +	data1	0x00,0x00, 0x01,0xC2, 0x03,0x84, 0x02,0x46, 0x07,0x08, 0x06,0xCA, 0x04,0x8C, 0x05,0x4E
        +	data1	0x0E,0x10, 0x0F,0xD2, 0x0D,0x94, 0x0C,0x56, 0x09,0x18, 0x08,0xDA, 0x0A,0x9C, 0x0B,0x5E
        +	data1	0x1C,0x20, 0x1D,0xE2, 0x1F,0xA4, 0x1E,0x66, 0x1B,0x28, 0x1A,0xEA, 0x18,0xAC, 0x19,0x6E
        +	data1	0x12,0x30, 0x13,0xF2, 0x11,0xB4, 0x10,0x76, 0x15,0x38, 0x14,0xFA, 0x16,0xBC, 0x17,0x7E
        +	data1	0x38,0x40, 0x39,0x82, 0x3B,0xC4, 0x3A,0x06, 0x3F,0x48, 0x3E,0x8A, 0x3C,0xCC, 0x3D,0x0E
        +	data1	0x36,0x50, 0x37,0x92, 0x35,0xD4, 0x34,0x16, 0x31,0x58, 0x30,0x9A, 0x32,0xDC, 0x33,0x1E
        +	data1	0x24,0x60, 0x25,0xA2, 0x27,0xE4, 0x26,0x26, 0x23,0x68, 0x22,0xAA, 0x20,0xEC, 0x21,0x2E
        +	data1	0x2A,0x70, 0x2B,0xB2, 0x29,0xF4, 0x28,0x36, 0x2D,0x78, 0x2C,0xBA, 0x2E,0xFC, 0x2F,0x3E
        +	data1	0x70,0x80, 0x71,0x42, 0x73,0x04, 0x72,0xC6, 0x77,0x88, 0x76,0x4A, 0x74,0x0C, 0x75,0xCE
        +	data1	0x7E,0x90, 0x7F,0x52, 0x7D,0x14, 0x7C,0xD6, 0x79,0x98, 0x78,0x5A, 0x7A,0x1C, 0x7B,0xDE
        +	data1	0x6C,0xA0, 0x6D,0x62, 0x6F,0x24, 0x6E,0xE6, 0x6B,0xA8, 0x6A,0x6A, 0x68,0x2C, 0x69,0xEE
        +	data1	0x62,0xB0, 0x63,0x72, 0x61,0x34, 0x60,0xF6, 0x65,0xB8, 0x64,0x7A, 0x66,0x3C, 0x67,0xFE
        +	data1	0x48,0xC0, 0x49,0x02, 0x4B,0x44, 0x4A,0x86, 0x4F,0xC8, 0x4E,0x0A, 0x4C,0x4C, 0x4D,0x8E
        +	data1	0x46,0xD0, 0x47,0x12, 0x45,0x54, 0x44,0x96, 0x41,0xD8, 0x40,0x1A, 0x42,0x5C, 0x43,0x9E
        +	data1	0x54,0xE0, 0x55,0x22, 0x57,0x64, 0x56,0xA6, 0x53,0xE8, 0x52,0x2A, 0x50,0x6C, 0x51,0xAE
        +	data1	0x5A,0xF0, 0x5B,0x32, 0x59,0x74, 0x58,0xB6, 0x5D,0xF8, 0x5C,0x3A, 0x5E,0x7C, 0x5F,0xBE
        +	data1	0xE1,0x00, 0xE0,0xC2, 0xE2,0x84, 0xE3,0x46, 0xE6,0x08, 0xE7,0xCA, 0xE5,0x8C, 0xE4,0x4E
        +	data1	0xEF,0x10, 0xEE,0xD2, 0xEC,0x94, 0xED,0x56, 0xE8,0x18, 0xE9,0xDA, 0xEB,0x9C, 0xEA,0x5E
        +	data1	0xFD,0x20, 0xFC,0xE2, 0xFE,0xA4, 0xFF,0x66, 0xFA,0x28, 0xFB,0xEA, 0xF9,0xAC, 0xF8,0x6E
        +	data1	0xF3,0x30, 0xF2,0xF2, 0xF0,0xB4, 0xF1,0x76, 0xF4,0x38, 0xF5,0xFA, 0xF7,0xBC, 0xF6,0x7E
        +	data1	0xD9,0x40, 0xD8,0x82, 0xDA,0xC4, 0xDB,0x06, 0xDE,0x48, 0xDF,0x8A, 0xDD,0xCC, 0xDC,0x0E
        +	data1	0xD7,0x50, 0xD6,0x92, 0xD4,0xD4, 0xD5,0x16, 0xD0,0x58, 0xD1,0x9A, 0xD3,0xDC, 0xD2,0x1E
        +	data1	0xC5,0x60, 0xC4,0xA2, 0xC6,0xE4, 0xC7,0x26, 0xC2,0x68, 0xC3,0xAA, 0xC1,0xEC, 0xC0,0x2E
        +	data1	0xCB,0x70, 0xCA,0xB2, 0xC8,0xF4, 0xC9,0x36, 0xCC,0x78, 0xCD,0xBA, 0xCF,0xFC, 0xCE,0x3E
        +	data1	0x91,0x80, 0x90,0x42, 0x92,0x04, 0x93,0xC6, 0x96,0x88, 0x97,0x4A, 0x95,0x0C, 0x94,0xCE
        +	data1	0x9F,0x90, 0x9E,0x52, 0x9C,0x14, 0x9D,0xD6, 0x98,0x98, 0x99,0x5A, 0x9B,0x1C, 0x9A,0xDE
        +	data1	0x8D,0xA0, 0x8C,0x62, 0x8E,0x24, 0x8F,0xE6, 0x8A,0xA8, 0x8B,0x6A, 0x89,0x2C, 0x88,0xEE
        +	data1	0x83,0xB0, 0x82,0x72, 0x80,0x34, 0x81,0xF6, 0x84,0xB8, 0x85,0x7A, 0x87,0x3C, 0x86,0xFE
        +	data1	0xA9,0xC0, 0xA8,0x02, 0xAA,0x44, 0xAB,0x86, 0xAE,0xC8, 0xAF,0x0A, 0xAD,0x4C, 0xAC,0x8E
        +	data1	0xA7,0xD0, 0xA6,0x12, 0xA4,0x54, 0xA5,0x96, 0xA0,0xD8, 0xA1,0x1A, 0xA3,0x5C, 0xA2,0x9E
        +	data1	0xB5,0xE0, 0xB4,0x22, 0xB6,0x64, 0xB7,0xA6, 0xB2,0xE8, 0xB3,0x2A, 0xB1,0x6C, 0xB0,0xAE
        +	data1	0xBB,0xF0, 0xBA,0x32, 0xB8,0x74, 0xB9,0xB6, 0xBC,0xF8, 0xBD,0x3A, 0xBF,0x7C, 0xBE,0xBE
        +.size	rem_8bit#,512
        +stringz	"GHASH for IA64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/mux1(\s+)\S+\@rev/nop.i$1 0x0/gm      if ($big_endian);
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-parisc.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-parisc.pl
        new file mode 100644
        index 000000000..8c7454ee9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-parisc.pl
        @@ -0,0 +1,730 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# April 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+128 bytes shared table]. On PA-7100LC
        +# it processes one byte in 19.6 cycles, which is more than twice as
        +# fast as code generated by gcc 3.2. PA-RISC 2.0 loop is scheduled for
        +# 8 cycles, but measured performance on PA-8600 system is ~9 cycles per
        +# processed byte. This is ~2.2x faster than 64-bit code generated by
        +# vendor compiler (which used to be very hard to beat:-).
        +#
        +# Special thanks to polarhome.com for providing HP-UX account.
        +
        +$flavour = shift;
        +$output = shift;
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$FRAME_MARKER	=80;
        +	$SAVED_RP	=16;
        +	$PUSH		="std";
        +	$PUSHMA		="std,ma";
        +	$POP		="ldd";
        +	$POPMB		="ldd,mb";
        +	$NREGS		=6;
        +} else {
        +	$LEVEL		="1.0";	#"\n\t.ALLOW\t2.0";
        +	$SIZE_T		=4;
        +	$FRAME_MARKER	=48;
        +	$SAVED_RP	=20;
        +	$PUSH		="stw";
        +	$PUSHMA		="stwm";
        +	$POP		="ldw";
        +	$POPMB		="ldwm";
        +	$NREGS		=11;
        +}
        +
        +$FRAME=10*$SIZE_T+$FRAME_MARKER;# NREGS saved regs + frame marker
        +				#                 [+ argument transfer]
        +
        +################# volatile registers
        +$Xi="%r26";	# argument block
        +$Htbl="%r25";
        +$inp="%r24";
        +$len="%r23";
        +$Hhh=$Htbl;	# variables
        +$Hll="%r22";
        +$Zhh="%r21";
        +$Zll="%r20";
        +$cnt="%r19";
        +$rem_4bit="%r28";
        +$rem="%r29";
        +$mask0xf0="%r31";
        +
        +################# preserved registers
        +$Thh="%r1";
        +$Tll="%r2";
        +$nlo="%r3";
        +$nhi="%r4";
        +$byte="%r5";
        +if ($SIZE_T==4) {
        +	$Zhl="%r6";
        +	$Zlh="%r7";
        +	$Hhl="%r8";
        +	$Hlh="%r9";
        +	$Thl="%r10";
        +	$Tlh="%r11";
        +}
        +$rem2="%r6";	# used in PA-RISC 2.0 code
        +
        +$code.=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.EXPORT	gcm_gmult_4bit,ENTRY,ARGW0=GR,ARGW1=GR
        +	.ALIGN	64
        +gcm_gmult_4bit
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=$NREGS
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
        +___
        +$code.=<<___;
        +	blr	%r0,$rem_4bit
        +	ldi	3,$rem
        +L\$pic_gmult
        +	andcm	$rem_4bit,$rem,$rem_4bit
        +	addl	$inp,$len,$len
        +	ldo	L\$rem_4bit-L\$pic_gmult($rem_4bit),$rem_4bit
        +	ldi	0xf0,$mask0xf0
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	ldi	31,$rem
        +	mtctl	$rem,%cr11
        +	extrd,u,*= $rem,%sar,1,$rem	; executes on PA-RISC 1.0
        +	b	L\$parisc1_gmult
        +	nop
        +___
        +
        +$code.=<<___;
        +	ldb	15($Xi),$nlo
        +	ldo	8($Htbl),$Hll
        +
        +	and	$mask0xf0,$nlo,$nhi
        +	depd,z	$nlo,59,4,$nlo
        +
        +	ldd	$nlo($Hll),$Zll
        +	ldd	$nlo($Hhh),$Zhh
        +
        +	depd,z	$Zll,60,4,$rem
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldb	14($Xi),$nlo
        +
        +	ldd	$nhi($Hll),$Tll
        +	ldd	$nhi($Hhh),$Thh
        +	and	$mask0xf0,$nlo,$nhi
        +	depd,z	$nlo,59,4,$nlo
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldd	$rem($rem_4bit),$rem
        +	b	L\$oop_gmult_pa2
        +	ldi	13,$cnt
        +
        +	.ALIGN	8
        +L\$oop_gmult_pa2
        +	xor	$rem,$Zhh,$Zhh		; moved here to work around gas bug
        +	depd,z	$Zll,60,4,$rem
        +
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldd	$nlo($Hll),$Tll
        +	ldd	$nlo($Hhh),$Thh
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldd	$rem($rem_4bit),$rem
        +
        +	xor	$rem,$Zhh,$Zhh
        +	depd,z	$Zll,60,4,$rem
        +	ldbx	$cnt($Xi),$nlo
        +
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldd	$nhi($Hll),$Tll
        +	ldd	$nhi($Hhh),$Thh
        +
        +	and	$mask0xf0,$nlo,$nhi
        +	depd,z	$nlo,59,4,$nlo
        +	ldd	$rem($rem_4bit),$rem
        +
        +	xor	$Tll,$Zll,$Zll
        +	addib,uv -1,$cnt,L\$oop_gmult_pa2
        +	xor	$Thh,$Zhh,$Zhh
        +
        +	xor	$rem,$Zhh,$Zhh
        +	depd,z	$Zll,60,4,$rem
        +
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldd	$nlo($Hll),$Tll
        +	ldd	$nlo($Hhh),$Thh
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldd	$rem($rem_4bit),$rem
        +
        +	xor	$rem,$Zhh,$Zhh
        +	depd,z	$Zll,60,4,$rem
        +
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldd	$nhi($Hll),$Tll
        +	ldd	$nhi($Hhh),$Thh
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldd	$rem($rem_4bit),$rem
        +
        +	xor	$rem,$Zhh,$Zhh
        +	std	$Zll,8($Xi)
        +	std	$Zhh,0($Xi)
        +___
        +
        +$code.=<<___ if ($SIZE_T==4);
        +	b	L\$done_gmult
        +	nop
        +
        +L\$parisc1_gmult
        +	ldb	15($Xi),$nlo
        +	ldo	12($Htbl),$Hll
        +	ldo	8($Htbl),$Hlh
        +	ldo	4($Htbl),$Hhl
        +
        +	and	$mask0xf0,$nlo,$nhi
        +	zdep	$nlo,27,4,$nlo
        +
        +	ldwx	$nlo($Hll),$Zll
        +	ldwx	$nlo($Hlh),$Zlh
        +	ldwx	$nlo($Hhl),$Zhl
        +	ldwx	$nlo($Hhh),$Zhh
        +	zdep	$Zll,28,4,$rem
        +	ldb	14($Xi),$nlo
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$nhi($Hll),$Tll
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	ldwx	$nhi($Hlh),$Tlh
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	ldwx	$nhi($Hhl),$Thl
        +	extru	$Zhh,27,28,$Zhh
        +	ldwx	$nhi($Hhh),$Thh
        +	xor	$rem,$Zhh,$Zhh
        +	and	$mask0xf0,$nlo,$nhi
        +	zdep	$nlo,27,4,$nlo
        +
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nlo($Hll),$Tll
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nlo($Hlh),$Tlh
        +	xor	$Thl,$Zhl,$Zhl
        +	b	L\$oop_gmult_pa1
        +	ldi	13,$cnt
        +
        +	.ALIGN	8
        +L\$oop_gmult_pa1
        +	zdep	$Zll,28,4,$rem
        +	ldwx	$nlo($Hhl),$Thl
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$nlo($Hhh),$Thh
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	ldbx	$cnt($Xi),$nlo
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nhi($Hll),$Tll
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nhi($Hlh),$Tlh
        +	extru	$Zhh,27,28,$Zhh
        +	xor	$Thl,$Zhl,$Zhl
        +	ldwx	$nhi($Hhl),$Thl
        +	xor	$rem,$Zhh,$Zhh
        +	zdep	$Zll,28,4,$rem
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$nhi($Hhh),$Thh
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	and	$mask0xf0,$nlo,$nhi
        +	extru	$Zhh,27,28,$Zhh
        +	zdep	$nlo,27,4,$nlo
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nlo($Hll),$Tll
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nlo($Hlh),$Tlh
        +	xor	$rem,$Zhh,$Zhh
        +	addib,uv -1,$cnt,L\$oop_gmult_pa1
        +	xor	$Thl,$Zhl,$Zhl
        +
        +	zdep	$Zll,28,4,$rem
        +	ldwx	$nlo($Hhl),$Thl
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$nlo($Hhh),$Thh
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nhi($Hll),$Tll
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nhi($Hlh),$Tlh
        +	extru	$Zhh,27,28,$Zhh
        +	xor	$rem,$Zhh,$Zhh
        +	xor	$Thl,$Zhl,$Zhl
        +	ldwx	$nhi($Hhl),$Thl
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$nhi($Hhh),$Thh
        +	zdep	$Zll,28,4,$rem
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	extru	$Zhh,27,28,$Zhh
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Tlh,$Zlh,$Zlh
        +	xor	$rem,$Zhh,$Zhh
        +	stw	$Zll,12($Xi)
        +	xor	$Thl,$Zhl,$Zhl
        +	stw	$Zlh,8($Xi)
        +	xor	$Thh,$Zhh,$Zhh
        +	stw	$Zhl,4($Xi)
        +	stw	$Zhh,0($Xi)
        +___
        +$code.=<<___;
        +L\$done_gmult
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2		; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
        +___
        +$code.=<<___;
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +
        +	.EXPORT	gcm_ghash_4bit,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
        +	.ALIGN	64
        +gcm_ghash_4bit
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=11
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
        +___
        +$code.=<<___;
        +	blr	%r0,$rem_4bit
        +	ldi	3,$rem
        +L\$pic_ghash
        +	andcm	$rem_4bit,$rem,$rem_4bit
        +	addl	$inp,$len,$len
        +	ldo	L\$rem_4bit-L\$pic_ghash($rem_4bit),$rem_4bit
        +	ldi	0xf0,$mask0xf0
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	ldi	31,$rem
        +	mtctl	$rem,%cr11
        +	extrd,u,*= $rem,%sar,1,$rem	; executes on PA-RISC 1.0
        +	b	L\$parisc1_ghash
        +	nop
        +___
        +
        +$code.=<<___;
        +	ldb	15($Xi),$nlo
        +	ldo	8($Htbl),$Hll
        +
        +L\$outer_ghash_pa2
        +	ldb	15($inp),$nhi
        +	xor	$nhi,$nlo,$nlo
        +	and	$mask0xf0,$nlo,$nhi
        +	depd,z	$nlo,59,4,$nlo
        +
        +	ldd	$nlo($Hll),$Zll
        +	ldd	$nlo($Hhh),$Zhh
        +
        +	depd,z	$Zll,60,4,$rem
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldb	14($Xi),$nlo
        +	ldb	14($inp),$byte
        +
        +	ldd	$nhi($Hll),$Tll
        +	ldd	$nhi($Hhh),$Thh
        +	xor	$byte,$nlo,$nlo
        +	and	$mask0xf0,$nlo,$nhi
        +	depd,z	$nlo,59,4,$nlo
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldd	$rem($rem_4bit),$rem
        +	b	L\$oop_ghash_pa2
        +	ldi	13,$cnt
        +
        +	.ALIGN	8
        +L\$oop_ghash_pa2
        +	xor	$rem,$Zhh,$Zhh		; moved here to work around gas bug
        +	depd,z	$Zll,60,4,$rem2
        +
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldd	$nlo($Hll),$Tll
        +	ldd	$nlo($Hhh),$Thh
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldbx	$cnt($Xi),$nlo
        +	ldbx	$cnt($inp),$byte
        +
        +	depd,z	$Zll,60,4,$rem
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	ldd	$rem2($rem_4bit),$rem2
        +
        +	xor	$rem2,$Zhh,$Zhh
        +	xor	$byte,$nlo,$nlo
        +	ldd	$nhi($Hll),$Tll
        +	ldd	$nhi($Hhh),$Thh
        +
        +	and	$mask0xf0,$nlo,$nhi
        +	depd,z	$nlo,59,4,$nlo
        +
        +	extrd,u	$Zhh,59,60,$Zhh
        +	xor	$Tll,$Zll,$Zll
        +
        +	ldd	$rem($rem_4bit),$rem
        +	addib,uv -1,$cnt,L\$oop_ghash_pa2
        +	xor	$Thh,$Zhh,$Zhh
        +
        +	xor	$rem,$Zhh,$Zhh
        +	depd,z	$Zll,60,4,$rem2
        +
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	extrd,u	$Zhh,59,60,$Zhh
        +	ldd	$nlo($Hll),$Tll
        +	ldd	$nlo($Hhh),$Thh
        +
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +
        +	depd,z	$Zll,60,4,$rem
        +	shrpd	$Zhh,$Zll,4,$Zll
        +	ldd	$rem2($rem_4bit),$rem2
        +
        +	xor	$rem2,$Zhh,$Zhh
        +	ldd	$nhi($Hll),$Tll
        +	ldd	$nhi($Hhh),$Thh
        +
        +	extrd,u	$Zhh,59,60,$Zhh
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Thh,$Zhh,$Zhh
        +	ldd	$rem($rem_4bit),$rem
        +
        +	xor	$rem,$Zhh,$Zhh
        +	std	$Zll,8($Xi)
        +	ldo	16($inp),$inp
        +	std	$Zhh,0($Xi)
        +	cmpb,*<> $inp,$len,L\$outer_ghash_pa2
        +	copy	$Zll,$nlo
        +___
        +
        +$code.=<<___ if ($SIZE_T==4);
        +	b	L\$done_ghash
        +	nop
        +
        +L\$parisc1_ghash
        +	ldb	15($Xi),$nlo
        +	ldo	12($Htbl),$Hll
        +	ldo	8($Htbl),$Hlh
        +	ldo	4($Htbl),$Hhl
        +
        +L\$outer_ghash_pa1
        +	ldb	15($inp),$byte
        +	xor	$byte,$nlo,$nlo
        +	and	$mask0xf0,$nlo,$nhi
        +	zdep	$nlo,27,4,$nlo
        +
        +	ldwx	$nlo($Hll),$Zll
        +	ldwx	$nlo($Hlh),$Zlh
        +	ldwx	$nlo($Hhl),$Zhl
        +	ldwx	$nlo($Hhh),$Zhh
        +	zdep	$Zll,28,4,$rem
        +	ldb	14($Xi),$nlo
        +	ldb	14($inp),$byte
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$nhi($Hll),$Tll
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	ldwx	$nhi($Hlh),$Tlh
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	ldwx	$nhi($Hhl),$Thl
        +	extru	$Zhh,27,28,$Zhh
        +	ldwx	$nhi($Hhh),$Thh
        +	xor	$byte,$nlo,$nlo
        +	xor	$rem,$Zhh,$Zhh
        +	and	$mask0xf0,$nlo,$nhi
        +	zdep	$nlo,27,4,$nlo
        +
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nlo($Hll),$Tll
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nlo($Hlh),$Tlh
        +	xor	$Thl,$Zhl,$Zhl
        +	b	L\$oop_ghash_pa1
        +	ldi	13,$cnt
        +
        +	.ALIGN	8
        +L\$oop_ghash_pa1
        +	zdep	$Zll,28,4,$rem
        +	ldwx	$nlo($Hhl),$Thl
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$nlo($Hhh),$Thh
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	ldbx	$cnt($Xi),$nlo
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nhi($Hll),$Tll
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	ldbx	$cnt($inp),$byte
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nhi($Hlh),$Tlh
        +	extru	$Zhh,27,28,$Zhh
        +	xor	$Thl,$Zhl,$Zhl
        +	ldwx	$nhi($Hhl),$Thl
        +	xor	$rem,$Zhh,$Zhh
        +	zdep	$Zll,28,4,$rem
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$nhi($Hhh),$Thh
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	xor	$byte,$nlo,$nlo
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	and	$mask0xf0,$nlo,$nhi
        +	extru	$Zhh,27,28,$Zhh
        +	zdep	$nlo,27,4,$nlo
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nlo($Hll),$Tll
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nlo($Hlh),$Tlh
        +	xor	$rem,$Zhh,$Zhh
        +	addib,uv -1,$cnt,L\$oop_ghash_pa1
        +	xor	$Thl,$Zhl,$Zhl
        +
        +	zdep	$Zll,28,4,$rem
        +	ldwx	$nlo($Hhl),$Thl
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	ldwx	$nlo($Hhh),$Thh
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	xor	$Tll,$Zll,$Zll
        +	ldwx	$nhi($Hll),$Tll
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	xor	$Tlh,$Zlh,$Zlh
        +	ldwx	$nhi($Hlh),$Tlh
        +	extru	$Zhh,27,28,$Zhh
        +	xor	$rem,$Zhh,$Zhh
        +	xor	$Thl,$Zhl,$Zhl
        +	ldwx	$nhi($Hhl),$Thl
        +	xor	$Thh,$Zhh,$Zhh
        +	ldwx	$nhi($Hhh),$Thh
        +	zdep	$Zll,28,4,$rem
        +	ldwx	$rem($rem_4bit),$rem
        +	shrpw	$Zlh,$Zll,4,$Zll
        +	shrpw	$Zhl,$Zlh,4,$Zlh
        +	shrpw	$Zhh,$Zhl,4,$Zhl
        +	extru	$Zhh,27,28,$Zhh
        +	xor	$Tll,$Zll,$Zll
        +	xor	$Tlh,$Zlh,$Zlh
        +	xor	$rem,$Zhh,$Zhh
        +	stw	$Zll,12($Xi)
        +	xor	$Thl,$Zhl,$Zhl
        +	stw	$Zlh,8($Xi)
        +	xor	$Thh,$Zhh,$Zhh
        +	stw	$Zhl,4($Xi)
        +	ldo	16($inp),$inp
        +	stw	$Zhh,0($Xi)
        +	comb,<>	$inp,$len,L\$outer_ghash_pa1
        +	copy	$Zll,$nlo
        +___
        +$code.=<<___;
        +L\$done_ghash
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2		; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +___
        +$code.=<<___ if ($SIZE_T==4);
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
        +___
        +$code.=<<___;
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +
        +	.ALIGN	64
        +L\$rem_4bit
        +	.WORD	`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0
        +	.WORD	`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0
        +	.WORD	`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0
        +	.WORD	`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0
        +	.STRINGZ "GHASH for PA-RISC, GRYPTOGAMS by <appro\@openssl.org>"
        +	.ALIGN	64
        +___
        +
        +# Explicitly encode PA-RISC 2.0 instructions used in this module, so
        +# that it can be compiled with .LEVEL 1.0. It should be noted that I
        +# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
        +# directive...
        +
        +my $ldd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "ldd$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)		# format 4
        +    {	my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3;
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)	# format 5
        +    {	my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3;
        +	$opcode|=(($1&0xF)<<17)|(($1&0x10)<<12);		# encode offset
        +	$opcode|=(1<<5)  if ($mod =~ /^,m/);
        +	$opcode|=(1<<13) if ($mod =~ /^,mb/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $std = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "std$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices
        +    {	my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $extrd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "extrd$mod\t$args";
        +
        +    # I only have ",u" completer, it's implicitly encoded...
        +    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 15
        +    {	my $opcode=(0x36<<26)|($1<<21)|($4<<16);
        +	my $len=32-$3;
        +	$opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5);		# encode pos
        +	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/)	# format 12
        +    {	my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
        +	my $len=32-$2;
        +	$opcode |= (($len&0x20)<<3)|($len&0x1f);		# encode len
        +	$opcode |= (1<<13) if ($mod =~ /,\**=/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $shrpd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "shrpd$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/)	# format 14
        +    {	my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
        +	my $cpos=63-$3;
        +	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode sa
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/)	# format 11
        +    {	sprintf "\t.WORD\t0x%08x\t; %s",
        +		(0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $depd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "depd$mod\t$args";
        +
        +    # I only have ",z" completer, it's impicitly encoded...
        +    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 16
        +    {	my $opcode=(0x3c<<26)|($4<<21)|($1<<16);
        +    	my $cpos=63-$2;
        +	my $len=32-$3;
        +	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode pos
        +	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +sub assemble {
        +  my ($mnemonic,$mod,$args)=@_;
        +  my $opcode = eval("\$$mnemonic");
        +
        +    ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
        +}
        +
        +foreach (split("\n",$code)) {
        +	s/\`([^\`]*)\`/eval $1/ge;
        +	if ($SIZE_T==4) {
        +		s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e;
        +		s/cmpb,\*/comb,/;
        +		s/,\*/,/;
        +	}
        +	print $_,"\n";
        +}
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-s390x.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-s390x.pl
        new file mode 100644
        index 000000000..6a40d5d89
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-s390x.pl
        @@ -0,0 +1,262 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# September 2010.
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+128 bytes shared table]. Performance
        +# was measured to be ~18 cycles per processed byte on z10, which is
        +# almost 40% better than gcc-generated code. It should be noted that
        +# 18 cycles is worse result than expected: loop is scheduled for 12
        +# and the result should be close to 12. In the lack of instruction-
        +# level profiling data it's impossible to tell why...
        +
        +# November 2010.
        +#
        +# Adapt for -m31 build. If kernel supports what's called "highgprs"
        +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
        +# instructions and achieve "64-bit" performance even in 31-bit legacy
        +# application context. The feature is not specific to any particular
        +# processor, as long as it's "z-CPU". Latter implies that the code
        +# remains z/Architecture specific. On z990 it was measured to perform
        +# 2.8x better than 32-bit code generated by gcc 4.3.
        +
        +# March 2011.
        +#
        +# Support for hardware KIMD-GHASH is verified to produce correct
        +# result and therefore is engaged. On z196 it was measured to process
        +# 8KB buffer ~7 faster than software implementation. It's not as
        +# impressive for smaller buffer sizes and for smallest 16-bytes buffer
        +# it's actually almost 2 times slower. Which is the reason why
        +# KIMD-GHASH is not used in gcm_gmult_4bit.
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +	$SIZE_T=4;
        +	$g="";
        +} else {
        +	$SIZE_T=8;
        +	$g="g";
        +}
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$softonly=0;
        +
        +$Zhi="%r0";
        +$Zlo="%r1";
        +
        +$Xi="%r2";	# argument block
        +$Htbl="%r3";
        +$inp="%r4";
        +$len="%r5";
        +
        +$rem0="%r6";	# variables
        +$rem1="%r7";
        +$nlo="%r8";
        +$nhi="%r9";
        +$xi="%r10";
        +$cnt="%r11";
        +$tmp="%r12";
        +$x78="%r13";
        +$rem_4bit="%r14";
        +
        +$sp="%r15";
        +
        +$code.=<<___;
        +.text
        +
        +.globl	gcm_gmult_4bit
        +.align	32
        +gcm_gmult_4bit:
        +___
        +$code.=<<___ if(!$softonly && 0);	# hardware is slow for single block...
        +	larl	%r1,OPENSSL_s390xcap_P
        +	lg	%r0,0(%r1)
        +	tmhl	%r0,0x4000	# check for message-security-assist
        +	jz	.Lsoft_gmult
        +	lghi	%r0,0
        +	la	%r1,16($sp)
        +	.long	0xb93e0004	# kimd %r0,%r4
        +	lg	%r1,24($sp)
        +	tmhh	%r1,0x4000	# check for function 65
        +	jz	.Lsoft_gmult
        +	stg	%r0,16($sp)	# arrange 16 bytes of zero input
        +	stg	%r0,24($sp)
        +	lghi	%r0,65		# function 65
        +	la	%r1,0($Xi)	# H lies right after Xi in gcm128_context
        +	la	$inp,16($sp)
        +	lghi	$len,16
        +	.long	0xb93e0004	# kimd %r0,$inp
        +	brc	1,.-4		# pay attention to "partial completion"
        +	br	%r14
        +.align	32
        +.Lsoft_gmult:
        +___
        +$code.=<<___;
        +	stm${g}	%r6,%r14,6*$SIZE_T($sp)
        +
        +	aghi	$Xi,-1
        +	lghi	$len,1
        +	lghi	$x78,`0xf<<3`
        +	larl	$rem_4bit,rem_4bit
        +
        +	lg	$Zlo,8+1($Xi)		# Xi
        +	j	.Lgmult_shortcut
        +.type	gcm_gmult_4bit,\@function
        +.size	gcm_gmult_4bit,(.-gcm_gmult_4bit)
        +
        +.globl	gcm_ghash_4bit
        +.align	32
        +gcm_ghash_4bit:
        +___
        +$code.=<<___ if(!$softonly);
        +	larl	%r1,OPENSSL_s390xcap_P
        +	lg	%r0,0(%r1)
        +	tmhl	%r0,0x4000	# check for message-security-assist
        +	jz	.Lsoft_ghash
        +	lghi	%r0,0
        +	la	%r1,16($sp)
        +	.long	0xb93e0004	# kimd %r0,%r4
        +	lg	%r1,24($sp)
        +	tmhh	%r1,0x4000	# check for function 65
        +	jz	.Lsoft_ghash
        +	lghi	%r0,65		# function 65
        +	la	%r1,0($Xi)	# H lies right after Xi in gcm128_context
        +	.long	0xb93e0004	# kimd %r0,$inp
        +	brc	1,.-4		# pay attention to "partial completion"
        +	br	%r14
        +.align	32
        +.Lsoft_ghash:
        +___
        +$code.=<<___ if ($flavour =~ /3[12]/);
        +	llgfr	$len,$len
        +___
        +$code.=<<___;
        +	stm${g}	%r6,%r14,6*$SIZE_T($sp)
        +
        +	aghi	$Xi,-1
        +	srlg	$len,$len,4
        +	lghi	$x78,`0xf<<3`
        +	larl	$rem_4bit,rem_4bit
        +
        +	lg	$Zlo,8+1($Xi)		# Xi
        +	lg	$Zhi,0+1($Xi)
        +	lghi	$tmp,0
        +.Louter:
        +	xg	$Zhi,0($inp)		# Xi ^= inp 
        +	xg	$Zlo,8($inp)
        +	xgr	$Zhi,$tmp
        +	stg	$Zlo,8+1($Xi)
        +	stg	$Zhi,0+1($Xi)
        +
        +.Lgmult_shortcut:
        +	lghi	$tmp,0xf0
        +	sllg	$nlo,$Zlo,4
        +	srlg	$xi,$Zlo,8		# extract second byte
        +	ngr	$nlo,$tmp
        +	lgr	$nhi,$Zlo
        +	lghi	$cnt,14
        +	ngr	$nhi,$tmp
        +
        +	lg	$Zlo,8($nlo,$Htbl)
        +	lg	$Zhi,0($nlo,$Htbl)
        +
        +	sllg	$nlo,$xi,4
        +	sllg	$rem0,$Zlo,3
        +	ngr	$nlo,$tmp
        +	ngr	$rem0,$x78
        +	ngr	$xi,$tmp
        +
        +	sllg	$tmp,$Zhi,60
        +	srlg	$Zlo,$Zlo,4
        +	srlg	$Zhi,$Zhi,4
        +	xg	$Zlo,8($nhi,$Htbl)
        +	xg	$Zhi,0($nhi,$Htbl)
        +	lgr	$nhi,$xi
        +	sllg	$rem1,$Zlo,3
        +	xgr	$Zlo,$tmp
        +	ngr	$rem1,$x78
        +	j	.Lghash_inner
        +.align	16
        +.Lghash_inner:
        +	srlg	$Zlo,$Zlo,4
        +	sllg	$tmp,$Zhi,60
        +	xg	$Zlo,8($nlo,$Htbl)
        +	srlg	$Zhi,$Zhi,4
        +	llgc	$xi,0($cnt,$Xi)
        +	xg	$Zhi,0($nlo,$Htbl)
        +	sllg	$nlo,$xi,4
        +	xg	$Zhi,0($rem0,$rem_4bit)
        +	nill	$nlo,0xf0
        +	sllg	$rem0,$Zlo,3
        +	xgr	$Zlo,$tmp
        +	ngr	$rem0,$x78
        +	nill	$xi,0xf0
        +
        +	sllg	$tmp,$Zhi,60
        +	srlg	$Zlo,$Zlo,4
        +	srlg	$Zhi,$Zhi,4
        +	xg	$Zlo,8($nhi,$Htbl)
        +	xg	$Zhi,0($nhi,$Htbl)
        +	lgr	$nhi,$xi
        +	xg	$Zhi,0($rem1,$rem_4bit)
        +	sllg	$rem1,$Zlo,3
        +	xgr	$Zlo,$tmp
        +	ngr	$rem1,$x78
        +	brct	$cnt,.Lghash_inner
        +
        +	sllg	$tmp,$Zhi,60
        +	srlg	$Zlo,$Zlo,4
        +	srlg	$Zhi,$Zhi,4
        +	xg	$Zlo,8($nlo,$Htbl)
        +	xg	$Zhi,0($nlo,$Htbl)
        +	sllg	$xi,$Zlo,3
        +	xg	$Zhi,0($rem0,$rem_4bit)
        +	xgr	$Zlo,$tmp
        +	ngr	$xi,$x78
        +
        +	sllg	$tmp,$Zhi,60
        +	srlg	$Zlo,$Zlo,4
        +	srlg	$Zhi,$Zhi,4
        +	xg	$Zlo,8($nhi,$Htbl)
        +	xg	$Zhi,0($nhi,$Htbl)
        +	xgr	$Zlo,$tmp
        +	xg	$Zhi,0($rem1,$rem_4bit)
        +
        +	lg	$tmp,0($xi,$rem_4bit)
        +	la	$inp,16($inp)
        +	sllg	$tmp,$tmp,4		# correct last rem_4bit[rem]
        +	brctg	$len,.Louter
        +
        +	xgr	$Zhi,$tmp
        +	stg	$Zlo,8+1($Xi)
        +	stg	$Zhi,0+1($Xi)
        +	lm${g}	%r6,%r14,6*$SIZE_T($sp)
        +	br	%r14
        +.type	gcm_ghash_4bit,\@function
        +.size	gcm_ghash_4bit,(.-gcm_ghash_4bit)
        +
        +.align	64
        +rem_4bit:
        +	.long	`0x0000<<12`,0,`0x1C20<<12`,0,`0x3840<<12`,0,`0x2460<<12`,0
        +	.long	`0x7080<<12`,0,`0x6CA0<<12`,0,`0x48C0<<12`,0,`0x54E0<<12`,0
        +	.long	`0xE100<<12`,0,`0xFD20<<12`,0,`0xD940<<12`,0,`0xC560<<12`,0
        +	.long	`0x9180<<12`,0,`0x8DA0<<12`,0,`0xA9C0<<12`,0,`0xB5E0<<12`,0
        +.type	rem_4bit,\@object
        +.size	rem_4bit,(.-rem_4bit)
        +.string	"GHASH for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl
        new file mode 100644
        index 000000000..70e7b044a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-sparcv9.pl
        @@ -0,0 +1,330 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# March 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+128 bytes shared table]. Performance
        +# results are for streamed GHASH subroutine on UltraSPARC pre-Tx CPU
        +# and are expressed in cycles per processed byte, less is better:
        +#
        +#		gcc 3.3.x	cc 5.2		this assembler
        +#
        +# 32-bit build	81.4		43.3		12.6	(+546%/+244%)
        +# 64-bit build	20.2		21.2		12.6	(+60%/+68%)
        +#
        +# Here is data collected on UltraSPARC T1 system running Linux:
        +#
        +#		gcc 4.4.1			this assembler
        +#
        +# 32-bit build	566				50	(+1000%)
        +# 64-bit build	56				50	(+12%)
        +#
        +# I don't quite understand why difference between 32-bit and 64-bit
        +# compiler-generated code is so big. Compilers *were* instructed to
        +# generate code for UltraSPARC and should have used 64-bit registers
        +# for Z vector (see C code) even in 32-bit build... Oh well, it only
        +# means more impressive improvement coefficients for this assembler
        +# module;-) Loops are aggressively modulo-scheduled in respect to
        +# references to input data and Z.hi updates to achieve 12 cycles
        +# timing. To anchor to something else, sha1-sparcv9.pl spends 11.6
        +# cycles to process one byte on UltraSPARC pre-Tx CPU and ~24 on T1.
        +
        +$bits=32;
        +for (@ARGV)     { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +if ($bits==64)  { $bias=2047; $frame=192; }
        +else            { $bias=0;    $frame=112; }
        +
        +$output=shift;
        +open STDOUT,">$output";
        +
        +$Zhi="%o0";	# 64-bit values
        +$Zlo="%o1";
        +$Thi="%o2";
        +$Tlo="%o3";
        +$rem="%o4";
        +$tmp="%o5";
        +
        +$nhi="%l0";	# small values and pointers
        +$nlo="%l1";
        +$xi0="%l2";
        +$xi1="%l3";
        +$rem_4bit="%l4";
        +$remi="%l5";
        +$Htblo="%l6";
        +$cnt="%l7";
        +
        +$Xi="%i0";	# input argument block
        +$Htbl="%i1";
        +$inp="%i2";
        +$len="%i3";
        +
        +$code.=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.align	64
        +rem_4bit:
        +	.long	`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0
        +	.long	`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0
        +	.long	`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0
        +	.long	`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0
        +.type	rem_4bit,#object
        +.size	rem_4bit,(.-rem_4bit)
        +
        +.globl	gcm_ghash_4bit
        +.align	32
        +gcm_ghash_4bit:
        +	save	%sp,-$frame,%sp
        +	ldub	[$inp+15],$nlo
        +	ldub	[$Xi+15],$xi0
        +	ldub	[$Xi+14],$xi1
        +	add	$len,$inp,$len
        +	add	$Htbl,8,$Htblo
        +
        +1:	call	.+8
        +	add	%o7,rem_4bit-1b,$rem_4bit
        +
        +.Louter:
        +	xor	$xi0,$nlo,$nlo
        +	and	$nlo,0xf0,$nhi
        +	and	$nlo,0x0f,$nlo
        +	sll	$nlo,4,$nlo
        +	ldx	[$Htblo+$nlo],$Zlo
        +	ldx	[$Htbl+$nlo],$Zhi
        +
        +	ldub	[$inp+14],$nlo
        +
        +	ldx	[$Htblo+$nhi],$Tlo
        +	and	$Zlo,0xf,$remi
        +	ldx	[$Htbl+$nhi],$Thi
        +	sll	$remi,3,$remi
        +	ldx	[$rem_4bit+$remi],$rem
        +	srlx	$Zlo,4,$Zlo
        +	mov	13,$cnt
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +
        +	xor	$xi1,$nlo,$nlo
        +	and	$Zlo,0xf,$remi
        +	and	$nlo,0xf0,$nhi
        +	and	$nlo,0x0f,$nlo
        +	ba	.Lghash_inner
        +	sll	$nlo,4,$nlo
        +.align	32
        +.Lghash_inner:
        +	ldx	[$Htblo+$nlo],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$Thi,$Zhi,$Zhi
        +	ldx	[$Htbl+$nlo],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	ldub	[$inp+$cnt],$nlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	ldub	[$Xi+$cnt],$xi1
        +	xor	$Thi,$Zhi,$Zhi
        +	and	$Zlo,0xf,$remi
        +
        +	ldx	[$Htblo+$nhi],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$Htbl+$nhi],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$xi1,$nlo,$nlo
        +	srlx	$Zhi,4,$Zhi
        +	and	$nlo,0xf0,$nhi
        +	addcc	$cnt,-1,$cnt
        +	xor	$Zlo,$tmp,$Zlo
        +	and	$nlo,0x0f,$nlo
        +	xor	$Tlo,$Zlo,$Zlo
        +	sll	$nlo,4,$nlo
        +	blu	.Lghash_inner
        +	and	$Zlo,0xf,$remi
        +
        +	ldx	[$Htblo+$nlo],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$Thi,$Zhi,$Zhi
        +	ldx	[$Htbl+$nlo],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	xor	$Thi,$Zhi,$Zhi
        +
        +	add	$inp,16,$inp
        +	cmp	$inp,$len
        +	be,pn	`$bits==64?"%xcc":"%icc"`,.Ldone
        +	and	$Zlo,0xf,$remi
        +
        +	ldx	[$Htblo+$nhi],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$Htbl+$nhi],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	ldub	[$inp+15],$nlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	xor	$Thi,$Zhi,$Zhi
        +	stx	$Zlo,[$Xi+8]
        +	xor	$rem,$Zhi,$Zhi
        +	stx	$Zhi,[$Xi]
        +	srl	$Zlo,8,$xi1
        +	and	$Zlo,0xff,$xi0
        +	ba	.Louter
        +	and	$xi1,0xff,$xi1
        +.align	32
        +.Ldone:
        +	ldx	[$Htblo+$nhi],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$Htbl+$nhi],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	xor	$Thi,$Zhi,$Zhi
        +	stx	$Zlo,[$Xi+8]
        +	xor	$rem,$Zhi,$Zhi
        +	stx	$Zhi,[$Xi]
        +
        +	ret
        +	restore
        +.type	gcm_ghash_4bit,#function
        +.size	gcm_ghash_4bit,(.-gcm_ghash_4bit)
        +___
        +
        +undef $inp;
        +undef $len;
        +
        +$code.=<<___;
        +.globl	gcm_gmult_4bit
        +.align	32
        +gcm_gmult_4bit:
        +	save	%sp,-$frame,%sp
        +	ldub	[$Xi+15],$nlo
        +	add	$Htbl,8,$Htblo
        +
        +1:	call	.+8
        +	add	%o7,rem_4bit-1b,$rem_4bit
        +
        +	and	$nlo,0xf0,$nhi
        +	and	$nlo,0x0f,$nlo
        +	sll	$nlo,4,$nlo
        +	ldx	[$Htblo+$nlo],$Zlo
        +	ldx	[$Htbl+$nlo],$Zhi
        +
        +	ldub	[$Xi+14],$nlo
        +
        +	ldx	[$Htblo+$nhi],$Tlo
        +	and	$Zlo,0xf,$remi
        +	ldx	[$Htbl+$nhi],$Thi
        +	sll	$remi,3,$remi
        +	ldx	[$rem_4bit+$remi],$rem
        +	srlx	$Zlo,4,$Zlo
        +	mov	13,$cnt
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +
        +	and	$Zlo,0xf,$remi
        +	and	$nlo,0xf0,$nhi
        +	and	$nlo,0x0f,$nlo
        +	ba	.Lgmult_inner
        +	sll	$nlo,4,$nlo
        +.align	32
        +.Lgmult_inner:
        +	ldx	[$Htblo+$nlo],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$Thi,$Zhi,$Zhi
        +	ldx	[$Htbl+$nlo],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	ldub	[$Xi+$cnt],$nlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	xor	$Thi,$Zhi,$Zhi
        +	and	$Zlo,0xf,$remi
        +
        +	ldx	[$Htblo+$nhi],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$Htbl+$nhi],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	srlx	$Zhi,4,$Zhi
        +	and	$nlo,0xf0,$nhi
        +	addcc	$cnt,-1,$cnt
        +	xor	$Zlo,$tmp,$Zlo
        +	and	$nlo,0x0f,$nlo
        +	xor	$Tlo,$Zlo,$Zlo
        +	sll	$nlo,4,$nlo
        +	blu	.Lgmult_inner
        +	and	$Zlo,0xf,$remi
        +
        +	ldx	[$Htblo+$nlo],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$Thi,$Zhi,$Zhi
        +	ldx	[$Htbl+$nlo],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	xor	$Thi,$Zhi,$Zhi
        +	and	$Zlo,0xf,$remi
        +
        +	ldx	[$Htblo+$nhi],$Tlo
        +	sll	$remi,3,$remi
        +	xor	$rem,$Zhi,$Zhi
        +	ldx	[$Htbl+$nhi],$Thi
        +	srlx	$Zlo,4,$Zlo
        +	ldx	[$rem_4bit+$remi],$rem
        +	sllx	$Zhi,60,$tmp
        +	xor	$Tlo,$Zlo,$Zlo
        +	srlx	$Zhi,4,$Zhi
        +	xor	$Zlo,$tmp,$Zlo
        +	xor	$Thi,$Zhi,$Zhi
        +	stx	$Zlo,[$Xi+8]
        +	xor	$rem,$Zhi,$Zhi
        +	stx	$Zhi,[$Xi]
        +
        +	ret
        +	restore
        +.type	gcm_gmult_4bit,#function
        +.size	gcm_gmult_4bit,(.-gcm_gmult_4bit)
        +.asciz	"GHASH for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	4
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-x86.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-x86.pl
        new file mode 100644
        index 000000000..83c727e07
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-x86.pl
        @@ -0,0 +1,1342 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# March, May, June 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that it
        +# uses 256 bytes per-key table [+64/128 bytes fixed table]. It has two
        +# code paths: vanilla x86 and vanilla MMX. Former will be executed on
        +# 486 and Pentium, latter on all others. MMX GHASH features so called
        +# "528B" variant of "4-bit" method utilizing additional 256+16 bytes
        +# of per-key storage [+512 bytes shared table]. Performance results
        +# are for streamed GHASH subroutine and are expressed in cycles per
        +# processed byte, less is better:
        +#
        +#		gcc 2.95.3(*)	MMX assembler	x86 assembler
        +#
        +# Pentium	105/111(**)	-		50
        +# PIII		68 /75		12.2		24
        +# P4		125/125		17.8		84(***)
        +# Opteron	66 /70		10.1		30
        +# Core2		54 /67		8.4		18
        +#
        +# (*)	gcc 3.4.x was observed to generate few percent slower code,
        +#	which is one of reasons why 2.95.3 results were chosen,
        +#	another reason is lack of 3.4.x results for older CPUs;
        +#	comparison with MMX results is not completely fair, because C
        +#	results are for vanilla "256B" implementation, while
        +#	assembler results are for "528B";-)
        +# (**)	second number is result for code compiled with -fPIC flag,
        +#	which is actually more relevant, because assembler code is
        +#	position-independent;
        +# (***)	see comment in non-MMX routine for further details;
        +#
        +# To summarize, it's >2-5 times faster than gcc-generated code. To
        +# anchor it to something else SHA1 assembler processes one byte in
        +# 11-13 cycles on contemporary x86 cores. As for choice of MMX in
        +# particular, see comment at the end of the file...
        +
        +# May 2010
        +#
        +# Add PCLMULQDQ version performing at 2.10 cycles per processed byte.
        +# The question is how close is it to theoretical limit? The pclmulqdq
        +# instruction latency appears to be 14 cycles and there can't be more
        +# than 2 of them executing at any given time. This means that single
        +# Karatsuba multiplication would take 28 cycles *plus* few cycles for
        +# pre- and post-processing. Then multiplication has to be followed by
        +# modulo-reduction. Given that aggregated reduction method [see
        +# "Carry-less Multiplication and Its Usage for Computing the GCM Mode"
        +# white paper by Intel] allows you to perform reduction only once in
        +# a while we can assume that asymptotic performance can be estimated
        +# as (28+Tmod/Naggr)/16, where Tmod is time to perform reduction
        +# and Naggr is the aggregation factor.
        +#
        +# Before we proceed to this implementation let's have closer look at
        +# the best-performing code suggested by Intel in their white paper.
        +# By tracing inter-register dependencies Tmod is estimated as ~19
        +# cycles and Naggr chosen by Intel is 4, resulting in 2.05 cycles per
        +# processed byte. As implied, this is quite optimistic estimate,
        +# because it does not account for Karatsuba pre- and post-processing,
        +# which for a single multiplication is ~5 cycles. Unfortunately Intel
        +# does not provide performance data for GHASH alone. But benchmarking
        +# AES_GCM_encrypt ripped out of Fig. 15 of the white paper with aadt
        +# alone resulted in 2.46 cycles per byte of out 16KB buffer. Note that
        +# the result accounts even for pre-computing of degrees of the hash
        +# key H, but its portion is negligible at 16KB buffer size.
        +#
        +# Moving on to the implementation in question. Tmod is estimated as
        +# ~13 cycles and Naggr is 2, giving asymptotic performance of ...
        +# 2.16. How is it possible that measured performance is better than
        +# optimistic theoretical estimate? There is one thing Intel failed
        +# to recognize. By serializing GHASH with CTR in same subroutine
        +# former's performance is really limited to above (Tmul + Tmod/Naggr)
        +# equation. But if GHASH procedure is detached, the modulo-reduction
        +# can be interleaved with Naggr-1 multiplications at instruction level
        +# and under ideal conditions even disappear from the equation. So that
        +# optimistic theoretical estimate for this implementation is ...
        +# 28/16=1.75, and not 2.16. Well, it's probably way too optimistic,
        +# at least for such small Naggr. I'd argue that (28+Tproc/Naggr),
        +# where Tproc is time required for Karatsuba pre- and post-processing,
        +# is more realistic estimate. In this case it gives ... 1.91 cycles.
        +# Or in other words, depending on how well we can interleave reduction
        +# and one of the two multiplications the performance should be betwen
        +# 1.91 and 2.16. As already mentioned, this implementation processes
        +# one byte out of 8KB buffer in 2.10 cycles, while x86_64 counterpart
        +# - in 2.02. x86_64 performance is better, because larger register
        +# bank allows to interleave reduction and multiplication better.
        +#
        +# Does it make sense to increase Naggr? To start with it's virtually
        +# impossible in 32-bit mode, because of limited register bank
        +# capacity. Otherwise improvement has to be weighed agiainst slower
        +# setup, as well as code size and complexity increase. As even
        +# optimistic estimate doesn't promise 30% performance improvement,
        +# there are currently no plans to increase Naggr.
        +#
        +# Special thanks to David Woodhouse <dwmw2@infradead.org> for
        +# providing access to a Westmere-based system on behalf of Intel
        +# Open Source Technology Centre.
        +
        +# January 2010
        +#
        +# Tweaked to optimize transitions between integer and FP operations
        +# on same XMM register, PCLMULQDQ subroutine was measured to process
        +# one byte in 2.07 cycles on Sandy Bridge, and in 2.12 - on Westmere.
        +# The minor regression on Westmere is outweighed by ~15% improvement
        +# on Sandy Bridge. Strangely enough attempt to modify 64-bit code in
        +# similar manner resulted in almost 20% degradation on Sandy Bridge,
        +# where original 64-bit code processes one byte in 1.95 cycles.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"ghash-x86.pl",$x86only = $ARGV[$#ARGV] eq "386");
        +
        +$sse2=0;
        +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +($Zhh,$Zhl,$Zlh,$Zll) = ("ebp","edx","ecx","ebx");
        +$inp  = "edi";
        +$Htbl = "esi";
        +
        +$unroll = 0;	# Affects x86 loop. Folded loop performs ~7% worse
        +		# than unrolled, which has to be weighted against
        +		# 2.5x x86-specific code size reduction.
        +
        +sub x86_loop {
        +    my $off = shift;
        +    my $rem = "eax";
        +
        +	&mov	($Zhh,&DWP(4,$Htbl,$Zll));
        +	&mov	($Zhl,&DWP(0,$Htbl,$Zll));
        +	&mov	($Zlh,&DWP(12,$Htbl,$Zll));
        +	&mov	($Zll,&DWP(8,$Htbl,$Zll));
        +	&xor	($rem,$rem);	# avoid partial register stalls on PIII
        +
        +	# shrd practically kills P4, 2.5x deterioration, but P4 has
        +	# MMX code-path to execute. shrd runs tad faster [than twice
        +	# the shifts, move's and or's] on pre-MMX Pentium (as well as
        +	# PIII and Core2), *but* minimizes code size, spares register
        +	# and thus allows to fold the loop...
        +	if (!$unroll) {
        +	my $cnt = $inp;
        +	&mov	($cnt,15);
        +	&jmp	(&label("x86_loop"));
        +	&set_label("x86_loop",16);
        +	    for($i=1;$i<=2;$i++) {
        +		&mov	(&LB($rem),&LB($Zll));
        +		&shrd	($Zll,$Zlh,4);
        +		&and	(&LB($rem),0xf);
        +		&shrd	($Zlh,$Zhl,4);
        +		&shrd	($Zhl,$Zhh,4);
        +		&shr	($Zhh,4);
        +		&xor	($Zhh,&DWP($off+16,"esp",$rem,4));
        +
        +		&mov	(&LB($rem),&BP($off,"esp",$cnt));
        +		if ($i&1) {
        +			&and	(&LB($rem),0xf0);
        +		} else {
        +			&shl	(&LB($rem),4);
        +		}
        +
        +		&xor	($Zll,&DWP(8,$Htbl,$rem));
        +		&xor	($Zlh,&DWP(12,$Htbl,$rem));
        +		&xor	($Zhl,&DWP(0,$Htbl,$rem));
        +		&xor	($Zhh,&DWP(4,$Htbl,$rem));
        +
        +		if ($i&1) {
        +			&dec	($cnt);
        +			&js	(&label("x86_break"));
        +		} else {
        +			&jmp	(&label("x86_loop"));
        +		}
        +	    }
        +	&set_label("x86_break",16);
        +	} else {
        +	    for($i=1;$i<32;$i++) {
        +		&comment($i);
        +		&mov	(&LB($rem),&LB($Zll));
        +		&shrd	($Zll,$Zlh,4);
        +		&and	(&LB($rem),0xf);
        +		&shrd	($Zlh,$Zhl,4);
        +		&shrd	($Zhl,$Zhh,4);
        +		&shr	($Zhh,4);
        +		&xor	($Zhh,&DWP($off+16,"esp",$rem,4));
        +
        +		if ($i&1) {
        +			&mov	(&LB($rem),&BP($off+15-($i>>1),"esp"));
        +			&and	(&LB($rem),0xf0);
        +		} else {
        +			&mov	(&LB($rem),&BP($off+15-($i>>1),"esp"));
        +			&shl	(&LB($rem),4);
        +		}
        +
        +		&xor	($Zll,&DWP(8,$Htbl,$rem));
        +		&xor	($Zlh,&DWP(12,$Htbl,$rem));
        +		&xor	($Zhl,&DWP(0,$Htbl,$rem));
        +		&xor	($Zhh,&DWP(4,$Htbl,$rem));
        +	    }
        +	}
        +	&bswap	($Zll);
        +	&bswap	($Zlh);
        +	&bswap	($Zhl);
        +	if (!$x86only) {
        +		&bswap	($Zhh);
        +	} else {
        +		&mov	("eax",$Zhh);
        +		&bswap	("eax");
        +		&mov	($Zhh,"eax");
        +	}
        +}
        +
        +if ($unroll) {
        +    &function_begin_B("_x86_gmult_4bit_inner");
        +	&x86_loop(4);
        +	&ret	();
        +    &function_end_B("_x86_gmult_4bit_inner");
        +}
        +
        +sub deposit_rem_4bit {
        +    my $bias = shift;
        +
        +	&mov	(&DWP($bias+0, "esp"),0x0000<<16);
        +	&mov	(&DWP($bias+4, "esp"),0x1C20<<16);
        +	&mov	(&DWP($bias+8, "esp"),0x3840<<16);
        +	&mov	(&DWP($bias+12,"esp"),0x2460<<16);
        +	&mov	(&DWP($bias+16,"esp"),0x7080<<16);
        +	&mov	(&DWP($bias+20,"esp"),0x6CA0<<16);
        +	&mov	(&DWP($bias+24,"esp"),0x48C0<<16);
        +	&mov	(&DWP($bias+28,"esp"),0x54E0<<16);
        +	&mov	(&DWP($bias+32,"esp"),0xE100<<16);
        +	&mov	(&DWP($bias+36,"esp"),0xFD20<<16);
        +	&mov	(&DWP($bias+40,"esp"),0xD940<<16);
        +	&mov	(&DWP($bias+44,"esp"),0xC560<<16);
        +	&mov	(&DWP($bias+48,"esp"),0x9180<<16);
        +	&mov	(&DWP($bias+52,"esp"),0x8DA0<<16);
        +	&mov	(&DWP($bias+56,"esp"),0xA9C0<<16);
        +	&mov	(&DWP($bias+60,"esp"),0xB5E0<<16);
        +}
        +
        +$suffix = $x86only ? "" : "_x86";
        +
        +&function_begin("gcm_gmult_4bit".$suffix);
        +	&stack_push(16+4+1);			# +1 for stack alignment
        +	&mov	($inp,&wparam(0));		# load Xi
        +	&mov	($Htbl,&wparam(1));		# load Htable
        +
        +	&mov	($Zhh,&DWP(0,$inp));		# load Xi[16]
        +	&mov	($Zhl,&DWP(4,$inp));
        +	&mov	($Zlh,&DWP(8,$inp));
        +	&mov	($Zll,&DWP(12,$inp));
        +
        +	&deposit_rem_4bit(16);
        +
        +	&mov	(&DWP(0,"esp"),$Zhh);		# copy Xi[16] on stack
        +	&mov	(&DWP(4,"esp"),$Zhl);
        +	&mov	(&DWP(8,"esp"),$Zlh);
        +	&mov	(&DWP(12,"esp"),$Zll);
        +	&shr	($Zll,20);
        +	&and	($Zll,0xf0);
        +
        +	if ($unroll) {
        +		&call	("_x86_gmult_4bit_inner");
        +	} else {
        +		&x86_loop(0);
        +		&mov	($inp,&wparam(0));
        +	}
        +
        +	&mov	(&DWP(12,$inp),$Zll);
        +	&mov	(&DWP(8,$inp),$Zlh);
        +	&mov	(&DWP(4,$inp),$Zhl);
        +	&mov	(&DWP(0,$inp),$Zhh);
        +	&stack_pop(16+4+1);
        +&function_end("gcm_gmult_4bit".$suffix);
        +
        +&function_begin("gcm_ghash_4bit".$suffix);
        +	&stack_push(16+4+1);			# +1 for 64-bit alignment
        +	&mov	($Zll,&wparam(0));		# load Xi
        +	&mov	($Htbl,&wparam(1));		# load Htable
        +	&mov	($inp,&wparam(2));		# load in
        +	&mov	("ecx",&wparam(3));		# load len
        +	&add	("ecx",$inp);
        +	&mov	(&wparam(3),"ecx");
        +
        +	&mov	($Zhh,&DWP(0,$Zll));		# load Xi[16]
        +	&mov	($Zhl,&DWP(4,$Zll));
        +	&mov	($Zlh,&DWP(8,$Zll));
        +	&mov	($Zll,&DWP(12,$Zll));
        +
        +	&deposit_rem_4bit(16);
        +
        +    &set_label("x86_outer_loop",16);
        +	&xor	($Zll,&DWP(12,$inp));		# xor with input
        +	&xor	($Zlh,&DWP(8,$inp));
        +	&xor	($Zhl,&DWP(4,$inp));
        +	&xor	($Zhh,&DWP(0,$inp));
        +	&mov	(&DWP(12,"esp"),$Zll);		# dump it on stack
        +	&mov	(&DWP(8,"esp"),$Zlh);
        +	&mov	(&DWP(4,"esp"),$Zhl);
        +	&mov	(&DWP(0,"esp"),$Zhh);
        +
        +	&shr	($Zll,20);
        +	&and	($Zll,0xf0);
        +
        +	if ($unroll) {
        +		&call	("_x86_gmult_4bit_inner");
        +	} else {
        +		&x86_loop(0);
        +		&mov	($inp,&wparam(2));
        +	}
        +	&lea	($inp,&DWP(16,$inp));
        +	&cmp	($inp,&wparam(3));
        +	&mov	(&wparam(2),$inp)	if (!$unroll);
        +	&jb	(&label("x86_outer_loop"));
        +
        +	&mov	($inp,&wparam(0));	# load Xi
        +	&mov	(&DWP(12,$inp),$Zll);
        +	&mov	(&DWP(8,$inp),$Zlh);
        +	&mov	(&DWP(4,$inp),$Zhl);
        +	&mov	(&DWP(0,$inp),$Zhh);
        +	&stack_pop(16+4+1);
        +&function_end("gcm_ghash_4bit".$suffix);
        +
        +if (!$x86only) {{{
        +
        +&static_label("rem_4bit");
        +
        +if (!$sse2) {{	# pure-MMX "May" version...
        +
        +$S=12;		# shift factor for rem_4bit
        +
        +&function_begin_B("_mmx_gmult_4bit_inner");
        +# MMX version performs 3.5 times better on P4 (see comment in non-MMX
        +# routine for further details), 100% better on Opteron, ~70% better
        +# on Core2 and PIII... In other words effort is considered to be well
        +# spent... Since initial release the loop was unrolled in order to
        +# "liberate" register previously used as loop counter. Instead it's
        +# used to optimize critical path in 'Z.hi ^= rem_4bit[Z.lo&0xf]'.
        +# The path involves move of Z.lo from MMX to integer register,
        +# effective address calculation and finally merge of value to Z.hi.
        +# Reference to rem_4bit is scheduled so late that I had to >>4
        +# rem_4bit elements. This resulted in 20-45% procent improvement
        +# on contemporary µ-archs.
        +{
        +    my $cnt;
        +    my $rem_4bit = "eax";
        +    my @rem = ($Zhh,$Zll);
        +    my $nhi = $Zhl;
        +    my $nlo = $Zlh;
        +
        +    my ($Zlo,$Zhi) = ("mm0","mm1");
        +    my $tmp = "mm2";
        +
        +	&xor	($nlo,$nlo);	# avoid partial register stalls on PIII
        +	&mov	($nhi,$Zll);
        +	&mov	(&LB($nlo),&LB($nhi));
        +	&shl	(&LB($nlo),4);
        +	&and	($nhi,0xf0);
        +	&movq	($Zlo,&QWP(8,$Htbl,$nlo));
        +	&movq	($Zhi,&QWP(0,$Htbl,$nlo));
        +	&movd	($rem[0],$Zlo);
        +
        +	for ($cnt=28;$cnt>=-2;$cnt--) {
        +	    my $odd = $cnt&1;
        +	    my $nix = $odd ? $nlo : $nhi;
        +
        +		&shl	(&LB($nlo),4)			if ($odd);
        +		&psrlq	($Zlo,4);
        +		&movq	($tmp,$Zhi);
        +		&psrlq	($Zhi,4);
        +		&pxor	($Zlo,&QWP(8,$Htbl,$nix));
        +		&mov	(&LB($nlo),&BP($cnt/2,$inp))	if (!$odd && $cnt>=0);
        +		&psllq	($tmp,60);
        +		&and	($nhi,0xf0)			if ($odd);
        +		&pxor	($Zhi,&QWP(0,$rem_4bit,$rem[1],8)) if ($cnt<28);
        +		&and	($rem[0],0xf);
        +		&pxor	($Zhi,&QWP(0,$Htbl,$nix));
        +		&mov	($nhi,$nlo)			if (!$odd && $cnt>=0);
        +		&movd	($rem[1],$Zlo);
        +		&pxor	($Zlo,$tmp);
        +
        +		push	(@rem,shift(@rem));		# "rotate" registers
        +	}
        +
        +	&mov	($inp,&DWP(4,$rem_4bit,$rem[1],8));	# last rem_4bit[rem]
        +
        +	&psrlq	($Zlo,32);	# lower part of Zlo is already there
        +	&movd	($Zhl,$Zhi);
        +	&psrlq	($Zhi,32);
        +	&movd	($Zlh,$Zlo);
        +	&movd	($Zhh,$Zhi);
        +	&shl	($inp,4);	# compensate for rem_4bit[i] being >>4
        +
        +	&bswap	($Zll);
        +	&bswap	($Zhl);
        +	&bswap	($Zlh);
        +	&xor	($Zhh,$inp);
        +	&bswap	($Zhh);
        +
        +	&ret	();
        +}
        +&function_end_B("_mmx_gmult_4bit_inner");
        +
        +&function_begin("gcm_gmult_4bit_mmx");
        +	&mov	($inp,&wparam(0));	# load Xi
        +	&mov	($Htbl,&wparam(1));	# load Htable
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop("eax");
        +	&lea	("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
        +
        +	&movz	($Zll,&BP(15,$inp));
        +
        +	&call	("_mmx_gmult_4bit_inner");
        +
        +	&mov	($inp,&wparam(0));	# load Xi
        +	&emms	();
        +	&mov	(&DWP(12,$inp),$Zll);
        +	&mov	(&DWP(4,$inp),$Zhl);
        +	&mov	(&DWP(8,$inp),$Zlh);
        +	&mov	(&DWP(0,$inp),$Zhh);
        +&function_end("gcm_gmult_4bit_mmx");
        +
        +# Streamed version performs 20% better on P4, 7% on Opteron,
        +# 10% on Core2 and PIII...
        +&function_begin("gcm_ghash_4bit_mmx");
        +	&mov	($Zhh,&wparam(0));	# load Xi
        +	&mov	($Htbl,&wparam(1));	# load Htable
        +	&mov	($inp,&wparam(2));	# load in
        +	&mov	($Zlh,&wparam(3));	# load len
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop("eax");
        +	&lea	("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
        +
        +	&add	($Zlh,$inp);
        +	&mov	(&wparam(3),$Zlh);	# len to point at the end of input
        +	&stack_push(4+1);		# +1 for stack alignment
        +
        +	&mov	($Zll,&DWP(12,$Zhh));	# load Xi[16]
        +	&mov	($Zhl,&DWP(4,$Zhh));
        +	&mov	($Zlh,&DWP(8,$Zhh));
        +	&mov	($Zhh,&DWP(0,$Zhh));
        +	&jmp	(&label("mmx_outer_loop"));
        +
        +    &set_label("mmx_outer_loop",16);
        +	&xor	($Zll,&DWP(12,$inp));
        +	&xor	($Zhl,&DWP(4,$inp));
        +	&xor	($Zlh,&DWP(8,$inp));
        +	&xor	($Zhh,&DWP(0,$inp));
        +	&mov	(&wparam(2),$inp);
        +	&mov	(&DWP(12,"esp"),$Zll);
        +	&mov	(&DWP(4,"esp"),$Zhl);
        +	&mov	(&DWP(8,"esp"),$Zlh);
        +	&mov	(&DWP(0,"esp"),$Zhh);
        +
        +	&mov	($inp,"esp");
        +	&shr	($Zll,24);
        +
        +	&call	("_mmx_gmult_4bit_inner");
        +
        +	&mov	($inp,&wparam(2));
        +	&lea	($inp,&DWP(16,$inp));
        +	&cmp	($inp,&wparam(3));
        +	&jb	(&label("mmx_outer_loop"));
        +
        +	&mov	($inp,&wparam(0));	# load Xi
        +	&emms	();
        +	&mov	(&DWP(12,$inp),$Zll);
        +	&mov	(&DWP(4,$inp),$Zhl);
        +	&mov	(&DWP(8,$inp),$Zlh);
        +	&mov	(&DWP(0,$inp),$Zhh);
        +
        +	&stack_pop(4+1);
        +&function_end("gcm_ghash_4bit_mmx");
        +
        +}} else {{	# "June" MMX version...
        +		# ... has slower "April" gcm_gmult_4bit_mmx with folded
        +		# loop. This is done to conserve code size...
        +$S=16;		# shift factor for rem_4bit
        +
        +sub mmx_loop() {
        +# MMX version performs 2.8 times better on P4 (see comment in non-MMX
        +# routine for further details), 40% better on Opteron and Core2, 50%
        +# better on PIII... In other words effort is considered to be well
        +# spent...
        +    my $inp = shift;
        +    my $rem_4bit = shift;
        +    my $cnt = $Zhh;
        +    my $nhi = $Zhl;
        +    my $nlo = $Zlh;
        +    my $rem = $Zll;
        +
        +    my ($Zlo,$Zhi) = ("mm0","mm1");
        +    my $tmp = "mm2";
        +
        +	&xor	($nlo,$nlo);	# avoid partial register stalls on PIII
        +	&mov	($nhi,$Zll);
        +	&mov	(&LB($nlo),&LB($nhi));
        +	&mov	($cnt,14);
        +	&shl	(&LB($nlo),4);
        +	&and	($nhi,0xf0);
        +	&movq	($Zlo,&QWP(8,$Htbl,$nlo));
        +	&movq	($Zhi,&QWP(0,$Htbl,$nlo));
        +	&movd	($rem,$Zlo);
        +	&jmp	(&label("mmx_loop"));
        +
        +    &set_label("mmx_loop",16);
        +	&psrlq	($Zlo,4);
        +	&and	($rem,0xf);
        +	&movq	($tmp,$Zhi);
        +	&psrlq	($Zhi,4);
        +	&pxor	($Zlo,&QWP(8,$Htbl,$nhi));
        +	&mov	(&LB($nlo),&BP(0,$inp,$cnt));
        +	&psllq	($tmp,60);
        +	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
        +	&dec	($cnt);
        +	&movd	($rem,$Zlo);
        +	&pxor	($Zhi,&QWP(0,$Htbl,$nhi));
        +	&mov	($nhi,$nlo);
        +	&pxor	($Zlo,$tmp);
        +	&js	(&label("mmx_break"));
        +
        +	&shl	(&LB($nlo),4);
        +	&and	($rem,0xf);
        +	&psrlq	($Zlo,4);
        +	&and	($nhi,0xf0);
        +	&movq	($tmp,$Zhi);
        +	&psrlq	($Zhi,4);
        +	&pxor	($Zlo,&QWP(8,$Htbl,$nlo));
        +	&psllq	($tmp,60);
        +	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
        +	&movd	($rem,$Zlo);
        +	&pxor	($Zhi,&QWP(0,$Htbl,$nlo));
        +	&pxor	($Zlo,$tmp);
        +	&jmp	(&label("mmx_loop"));
        +
        +    &set_label("mmx_break",16);
        +	&shl	(&LB($nlo),4);
        +	&and	($rem,0xf);
        +	&psrlq	($Zlo,4);
        +	&and	($nhi,0xf0);
        +	&movq	($tmp,$Zhi);
        +	&psrlq	($Zhi,4);
        +	&pxor	($Zlo,&QWP(8,$Htbl,$nlo));
        +	&psllq	($tmp,60);
        +	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
        +	&movd	($rem,$Zlo);
        +	&pxor	($Zhi,&QWP(0,$Htbl,$nlo));
        +	&pxor	($Zlo,$tmp);
        +
        +	&psrlq	($Zlo,4);
        +	&and	($rem,0xf);
        +	&movq	($tmp,$Zhi);
        +	&psrlq	($Zhi,4);
        +	&pxor	($Zlo,&QWP(8,$Htbl,$nhi));
        +	&psllq	($tmp,60);
        +	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
        +	&movd	($rem,$Zlo);
        +	&pxor	($Zhi,&QWP(0,$Htbl,$nhi));
        +	&pxor	($Zlo,$tmp);
        +
        +	&psrlq	($Zlo,32);	# lower part of Zlo is already there
        +	&movd	($Zhl,$Zhi);
        +	&psrlq	($Zhi,32);
        +	&movd	($Zlh,$Zlo);
        +	&movd	($Zhh,$Zhi);
        +
        +	&bswap	($Zll);
        +	&bswap	($Zhl);
        +	&bswap	($Zlh);
        +	&bswap	($Zhh);
        +}
        +
        +&function_begin("gcm_gmult_4bit_mmx");
        +	&mov	($inp,&wparam(0));	# load Xi
        +	&mov	($Htbl,&wparam(1));	# load Htable
        +
        +	&call	(&label("pic_point"));
        +	&set_label("pic_point");
        +	&blindpop("eax");
        +	&lea	("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
        +
        +	&movz	($Zll,&BP(15,$inp));
        +
        +	&mmx_loop($inp,"eax");
        +
        +	&emms	();
        +	&mov	(&DWP(12,$inp),$Zll);
        +	&mov	(&DWP(4,$inp),$Zhl);
        +	&mov	(&DWP(8,$inp),$Zlh);
        +	&mov	(&DWP(0,$inp),$Zhh);
        +&function_end("gcm_gmult_4bit_mmx");
        +
        +######################################################################
        +# Below subroutine is "528B" variant of "4-bit" GCM GHASH function
        +# (see gcm128.c for details). It provides further 20-40% performance
        +# improvement over above mentioned "May" version.
        +
        +&static_label("rem_8bit");
        +
        +&function_begin("gcm_ghash_4bit_mmx");
        +{ my ($Zlo,$Zhi) = ("mm7","mm6");
        +  my $rem_8bit = "esi";
        +  my $Htbl = "ebx";
        +
        +    # parameter block
        +    &mov	("eax",&wparam(0));		# Xi
        +    &mov	("ebx",&wparam(1));		# Htable
        +    &mov	("ecx",&wparam(2));		# inp
        +    &mov	("edx",&wparam(3));		# len
        +    &mov	("ebp","esp");			# original %esp
        +    &call	(&label("pic_point"));
        +    &set_label	("pic_point");
        +    &blindpop	($rem_8bit);
        +    &lea	($rem_8bit,&DWP(&label("rem_8bit")."-".&label("pic_point"),$rem_8bit));
        +
        +    &sub	("esp",512+16+16);		# allocate stack frame...
        +    &and	("esp",-64);			# ...and align it
        +    &sub	("esp",16);			# place for (u8)(H[]<<4)
        +
        +    &add	("edx","ecx");			# pointer to the end of input
        +    &mov	(&DWP(528+16+0,"esp"),"eax");	# save Xi
        +    &mov	(&DWP(528+16+8,"esp"),"edx");	# save inp+len
        +    &mov	(&DWP(528+16+12,"esp"),"ebp");	# save original %esp
        +
        +    { my @lo  = ("mm0","mm1","mm2");
        +      my @hi  = ("mm3","mm4","mm5");
        +      my @tmp = ("mm6","mm7");
        +      my ($off1,$off2,$i) = (0,0,);
        +
        +      &add	($Htbl,128);			# optimize for size
        +      &lea	("edi",&DWP(16+128,"esp"));
        +      &lea	("ebp",&DWP(16+256+128,"esp"));
        +
        +      # decompose Htable (low and high parts are kept separately),
        +      # generate Htable[]>>4, (u8)(Htable[]<<4), save to stack...
        +      for ($i=0;$i<18;$i++) {
        +
        +	&mov	("edx",&DWP(16*$i+8-128,$Htbl))		if ($i<16);
        +	&movq	($lo[0],&QWP(16*$i+8-128,$Htbl))	if ($i<16);
        +	&psllq	($tmp[1],60)				if ($i>1);
        +	&movq	($hi[0],&QWP(16*$i+0-128,$Htbl))	if ($i<16);
        +	&por	($lo[2],$tmp[1])			if ($i>1);
        +	&movq	(&QWP($off1-128,"edi"),$lo[1])		if ($i>0 && $i<17);
        +	&psrlq	($lo[1],4)				if ($i>0 && $i<17);
        +	&movq	(&QWP($off1,"edi"),$hi[1])		if ($i>0 && $i<17);
        +	&movq	($tmp[0],$hi[1])			if ($i>0 && $i<17);
        +	&movq	(&QWP($off2-128,"ebp"),$lo[2])		if ($i>1);
        +	&psrlq	($hi[1],4)				if ($i>0 && $i<17);
        +	&movq	(&QWP($off2,"ebp"),$hi[2])		if ($i>1);
        +	&shl	("edx",4)				if ($i<16);
        +	&mov	(&BP($i,"esp"),&LB("edx"))		if ($i<16);
        +
        +	unshift	(@lo,pop(@lo));			# "rotate" registers
        +	unshift	(@hi,pop(@hi));
        +	unshift	(@tmp,pop(@tmp));
        +	$off1 += 8	if ($i>0);
        +	$off2 += 8	if ($i>1);
        +      }
        +    }
        +
        +    &movq	($Zhi,&QWP(0,"eax"));
        +    &mov	("ebx",&DWP(8,"eax"));
        +    &mov	("edx",&DWP(12,"eax"));		# load Xi
        +
        +&set_label("outer",16);
        +  { my $nlo = "eax";
        +    my $dat = "edx";
        +    my @nhi = ("edi","ebp");
        +    my @rem = ("ebx","ecx");
        +    my @red = ("mm0","mm1","mm2");
        +    my $tmp = "mm3";
        +
        +    &xor	($dat,&DWP(12,"ecx"));		# merge input data
        +    &xor	("ebx",&DWP(8,"ecx"));
        +    &pxor	($Zhi,&QWP(0,"ecx"));
        +    &lea	("ecx",&DWP(16,"ecx"));		# inp+=16
        +    #&mov	(&DWP(528+12,"esp"),$dat);	# save inp^Xi
        +    &mov	(&DWP(528+8,"esp"),"ebx");
        +    &movq	(&QWP(528+0,"esp"),$Zhi);
        +    &mov	(&DWP(528+16+4,"esp"),"ecx");	# save inp
        +
        +    &xor	($nlo,$nlo);
        +    &rol	($dat,8);
        +    &mov	(&LB($nlo),&LB($dat));
        +    &mov	($nhi[1],$nlo);
        +    &and	(&LB($nlo),0x0f);
        +    &shr	($nhi[1],4);
        +    &pxor	($red[0],$red[0]);
        +    &rol	($dat,8);			# next byte
        +    &pxor	($red[1],$red[1]);
        +    &pxor	($red[2],$red[2]);
        +
        +    # Just like in "May" verson modulo-schedule for critical path in
        +    # 'Z.hi ^= rem_8bit[Z.lo&0xff^((u8)H[nhi]<<4)]<<48'. Final 'pxor'
        +    # is scheduled so late that rem_8bit[] has to be shifted *right*
        +    # by 16, which is why last argument to pinsrw is 2, which
        +    # corresponds to <<32=<<48>>16...
        +    for ($j=11,$i=0;$i<15;$i++) {
        +
        +      if ($i>0) {
        +	&pxor	($Zlo,&QWP(16,"esp",$nlo,8));		# Z^=H[nlo]
        +	&rol	($dat,8);				# next byte
        +	&pxor	($Zhi,&QWP(16+128,"esp",$nlo,8));
        +
        +	&pxor	($Zlo,$tmp);
        +	&pxor	($Zhi,&QWP(16+256+128,"esp",$nhi[0],8));
        +	&xor	(&LB($rem[1]),&BP(0,"esp",$nhi[0]));	# rem^(H[nhi]<<4)
        +      } else {
        +	&movq	($Zlo,&QWP(16,"esp",$nlo,8));
        +	&movq	($Zhi,&QWP(16+128,"esp",$nlo,8));
        +      }
        +
        +	&mov	(&LB($nlo),&LB($dat));
        +	&mov	($dat,&DWP(528+$j,"esp"))		if (--$j%4==0);
        +
        +	&movd	($rem[0],$Zlo);
        +	&movz	($rem[1],&LB($rem[1]))			if ($i>0);
        +	&psrlq	($Zlo,8);				# Z>>=8
        +
        +	&movq	($tmp,$Zhi);
        +	&mov	($nhi[0],$nlo);
        +	&psrlq	($Zhi,8);
        +
        +	&pxor	($Zlo,&QWP(16+256+0,"esp",$nhi[1],8));	# Z^=H[nhi]>>4
        +	&and	(&LB($nlo),0x0f);
        +	&psllq	($tmp,56);
        +
        +	&pxor	($Zhi,$red[1])				if ($i>1);
        +	&shr	($nhi[0],4);
        +	&pinsrw	($red[0],&WP(0,$rem_8bit,$rem[1],2),2)	if ($i>0);
        +
        +	unshift	(@red,pop(@red));			# "rotate" registers
        +	unshift	(@rem,pop(@rem));
        +	unshift	(@nhi,pop(@nhi));
        +    }
        +
        +    &pxor	($Zlo,&QWP(16,"esp",$nlo,8));		# Z^=H[nlo]
        +    &pxor	($Zhi,&QWP(16+128,"esp",$nlo,8));
        +    &xor	(&LB($rem[1]),&BP(0,"esp",$nhi[0]));	# rem^(H[nhi]<<4)
        +
        +    &pxor	($Zlo,$tmp);
        +    &pxor	($Zhi,&QWP(16+256+128,"esp",$nhi[0],8));
        +    &movz	($rem[1],&LB($rem[1]));
        +
        +    &pxor	($red[2],$red[2]);			# clear 2nd word
        +    &psllq	($red[1],4);
        +
        +    &movd	($rem[0],$Zlo);
        +    &psrlq	($Zlo,4);				# Z>>=4
        +
        +    &movq	($tmp,$Zhi);
        +    &psrlq	($Zhi,4);
        +    &shl	($rem[0],4);				# rem<<4
        +
        +    &pxor	($Zlo,&QWP(16,"esp",$nhi[1],8));	# Z^=H[nhi]
        +    &psllq	($tmp,60);
        +    &movz	($rem[0],&LB($rem[0]));
        +
        +    &pxor	($Zlo,$tmp);
        +    &pxor	($Zhi,&QWP(16+128,"esp",$nhi[1],8));
        +
        +    &pinsrw	($red[0],&WP(0,$rem_8bit,$rem[1],2),2);
        +    &pxor	($Zhi,$red[1]);
        +
        +    &movd	($dat,$Zlo);
        +    &pinsrw	($red[2],&WP(0,$rem_8bit,$rem[0],2),3);	# last is <<48
        +
        +    &psllq	($red[0],12);				# correct by <<16>>4
        +    &pxor	($Zhi,$red[0]);
        +    &psrlq	($Zlo,32);
        +    &pxor	($Zhi,$red[2]);
        +
        +    &mov	("ecx",&DWP(528+16+4,"esp"));	# restore inp
        +    &movd	("ebx",$Zlo);
        +    &movq	($tmp,$Zhi);			# 01234567
        +    &psllw	($Zhi,8);			# 1.3.5.7.
        +    &psrlw	($tmp,8);			# .0.2.4.6
        +    &por	($Zhi,$tmp);			# 10325476
        +    &bswap	($dat);
        +    &pshufw	($Zhi,$Zhi,0b00011011);		# 76543210
        +    &bswap	("ebx");
        +    
        +    &cmp	("ecx",&DWP(528+16+8,"esp"));	# are we done?
        +    &jne	(&label("outer"));
        +  }
        +
        +    &mov	("eax",&DWP(528+16+0,"esp"));	# restore Xi
        +    &mov	(&DWP(12,"eax"),"edx");
        +    &mov	(&DWP(8,"eax"),"ebx");
        +    &movq	(&QWP(0,"eax"),$Zhi);
        +
        +    &mov	("esp",&DWP(528+16+12,"esp"));	# restore original %esp
        +    &emms	();
        +}
        +&function_end("gcm_ghash_4bit_mmx");
        +}}
        +
        +if ($sse2) {{
        +######################################################################
        +# PCLMULQDQ version.
        +
        +$Xip="eax";
        +$Htbl="edx";
        +$const="ecx";
        +$inp="esi";
        +$len="ebx";
        +
        +($Xi,$Xhi)=("xmm0","xmm1");	$Hkey="xmm2";
        +($T1,$T2,$T3)=("xmm3","xmm4","xmm5");
        +($Xn,$Xhn)=("xmm6","xmm7");
        +
        +&static_label("bswap");
        +
        +sub clmul64x64_T2 {	# minimal "register" pressure
        +my ($Xhi,$Xi,$Hkey)=@_;
        +
        +	&movdqa		($Xhi,$Xi);		#
        +	&pshufd		($T1,$Xi,0b01001110);
        +	&pshufd		($T2,$Hkey,0b01001110);
        +	&pxor		($T1,$Xi);		#
        +	&pxor		($T2,$Hkey);
        +
        +	&pclmulqdq	($Xi,$Hkey,0x00);	#######
        +	&pclmulqdq	($Xhi,$Hkey,0x11);	#######
        +	&pclmulqdq	($T1,$T2,0x00);		#######
        +	&xorps		($T1,$Xi);		#
        +	&xorps		($T1,$Xhi);		#
        +
        +	&movdqa		($T2,$T1);		#
        +	&psrldq		($T1,8);
        +	&pslldq		($T2,8);		#
        +	&pxor		($Xhi,$T1);
        +	&pxor		($Xi,$T2);		#
        +}
        +
        +sub clmul64x64_T3 {
        +# Even though this subroutine offers visually better ILP, it
        +# was empirically found to be a tad slower than above version.
        +# At least in gcm_ghash_clmul context. But it's just as well,
        +# because loop modulo-scheduling is possible only thanks to
        +# minimized "register" pressure...
        +my ($Xhi,$Xi,$Hkey)=@_;
        +
        +	&movdqa		($T1,$Xi);		#
        +	&movdqa		($Xhi,$Xi);
        +	&pclmulqdq	($Xi,$Hkey,0x00);	#######
        +	&pclmulqdq	($Xhi,$Hkey,0x11);	#######
        +	&pshufd		($T2,$T1,0b01001110);	#
        +	&pshufd		($T3,$Hkey,0b01001110);
        +	&pxor		($T2,$T1);		#
        +	&pxor		($T3,$Hkey);
        +	&pclmulqdq	($T2,$T3,0x00);		#######
        +	&pxor		($T2,$Xi);		#
        +	&pxor		($T2,$Xhi);		#
        +
        +	&movdqa		($T3,$T2);		#
        +	&psrldq		($T2,8);
        +	&pslldq		($T3,8);		#
        +	&pxor		($Xhi,$T2);
        +	&pxor		($Xi,$T3);		#
        +}
        +
        +if (1) {		# Algorithm 9 with <<1 twist.
        +			# Reduction is shorter and uses only two
        +			# temporary registers, which makes it better
        +			# candidate for interleaving with 64x64
        +			# multiplication. Pre-modulo-scheduled loop
        +			# was found to be ~20% faster than Algorithm 5
        +			# below. Algorithm 9 was therefore chosen for
        +			# further optimization...
        +
        +sub reduction_alg9 {	# 17/13 times faster than Intel version
        +my ($Xhi,$Xi) = @_;
        +
        +	# 1st phase
        +	&movdqa		($T1,$Xi);		#
        +	&psllq		($Xi,1);
        +	&pxor		($Xi,$T1);		#
        +	&psllq		($Xi,5);		#
        +	&pxor		($Xi,$T1);		#
        +	&psllq		($Xi,57);		#
        +	&movdqa		($T2,$Xi);		#
        +	&pslldq		($Xi,8);
        +	&psrldq		($T2,8);		#
        +	&pxor		($Xi,$T1);
        +	&pxor		($Xhi,$T2);		#
        +
        +	# 2nd phase
        +	&movdqa		($T2,$Xi);
        +	&psrlq		($Xi,5);
        +	&pxor		($Xi,$T2);		#
        +	&psrlq		($Xi,1);		#
        +	&pxor		($Xi,$T2);		#
        +	&pxor		($T2,$Xhi);
        +	&psrlq		($Xi,1);		#
        +	&pxor		($Xi,$T2);		#
        +}
        +
        +&function_begin_B("gcm_init_clmul");
        +	&mov		($Htbl,&wparam(0));
        +	&mov		($Xip,&wparam(1));
        +
        +	&call		(&label("pic"));
        +&set_label("pic");
        +	&blindpop	($const);
        +	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
        +
        +	&movdqu		($Hkey,&QWP(0,$Xip));
        +	&pshufd		($Hkey,$Hkey,0b01001110);# dword swap
        +
        +	# <<1 twist
        +	&pshufd		($T2,$Hkey,0b11111111);	# broadcast uppermost dword
        +	&movdqa		($T1,$Hkey);
        +	&psllq		($Hkey,1);
        +	&pxor		($T3,$T3);		#
        +	&psrlq		($T1,63);
        +	&pcmpgtd	($T3,$T2);		# broadcast carry bit
        +	&pslldq		($T1,8);
        +	&por		($Hkey,$T1);		# H<<=1
        +
        +	# magic reduction
        +	&pand		($T3,&QWP(16,$const));	# 0x1c2_polynomial
        +	&pxor		($Hkey,$T3);		# if(carry) H^=0x1c2_polynomial
        +
        +	# calculate H^2
        +	&movdqa		($Xi,$Hkey);
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);
        +	&reduction_alg9	($Xhi,$Xi);
        +
        +	&movdqu		(&QWP(0,$Htbl),$Hkey);	# save H
        +	&movdqu		(&QWP(16,$Htbl),$Xi);	# save H^2
        +
        +	&ret		();
        +&function_end_B("gcm_init_clmul");
        +
        +&function_begin_B("gcm_gmult_clmul");
        +	&mov		($Xip,&wparam(0));
        +	&mov		($Htbl,&wparam(1));
        +
        +	&call		(&label("pic"));
        +&set_label("pic");
        +	&blindpop	($const);
        +	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
        +
        +	&movdqu		($Xi,&QWP(0,$Xip));
        +	&movdqa		($T3,&QWP(0,$const));
        +	&movups		($Hkey,&QWP(0,$Htbl));
        +	&pshufb		($Xi,$T3);
        +
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);
        +	&reduction_alg9	($Xhi,$Xi);
        +
        +	&pshufb		($Xi,$T3);
        +	&movdqu		(&QWP(0,$Xip),$Xi);
        +
        +	&ret	();
        +&function_end_B("gcm_gmult_clmul");
        +
        +&function_begin("gcm_ghash_clmul");
        +	&mov		($Xip,&wparam(0));
        +	&mov		($Htbl,&wparam(1));
        +	&mov		($inp,&wparam(2));
        +	&mov		($len,&wparam(3));
        +
        +	&call		(&label("pic"));
        +&set_label("pic");
        +	&blindpop	($const);
        +	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
        +
        +	&movdqu		($Xi,&QWP(0,$Xip));
        +	&movdqa		($T3,&QWP(0,$const));
        +	&movdqu		($Hkey,&QWP(0,$Htbl));
        +	&pshufb		($Xi,$T3);
        +
        +	&sub		($len,0x10);
        +	&jz		(&label("odd_tail"));
        +
        +	#######
        +	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
        +	#	[(H*Ii+1) + (H*Xi+1)] mod P =
        +	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
        +	#
        +	&movdqu		($T1,&QWP(0,$inp));	# Ii
        +	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
        +	&pshufb		($T1,$T3);
        +	&pshufb		($Xn,$T3);
        +	&pxor		($Xi,$T1);		# Ii+Xi
        +
        +	&clmul64x64_T2	($Xhn,$Xn,$Hkey);	# H*Ii+1
        +	&movups		($Hkey,&QWP(16,$Htbl));	# load H^2
        +
        +	&lea		($inp,&DWP(32,$inp));	# i+=2
        +	&sub		($len,0x20);
        +	&jbe		(&label("even_tail"));
        +
        +&set_label("mod_loop");
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);	# H^2*(Ii+Xi)
        +	&movdqu		($T1,&QWP(0,$inp));	# Ii
        +	&movups		($Hkey,&QWP(0,$Htbl));	# load H
        +
        +	&pxor		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
        +	&pxor		($Xhi,$Xhn);
        +
        +	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
        +	&pshufb		($T1,$T3);
        +	&pshufb		($Xn,$T3);
        +
        +	&movdqa		($T3,$Xn);		#&clmul64x64_TX	($Xhn,$Xn,$Hkey); H*Ii+1
        +	&movdqa		($Xhn,$Xn);
        +	 &pxor		($Xhi,$T1);		# "Ii+Xi", consume early
        +
        +	  &movdqa	($T1,$Xi);		#&reduction_alg9($Xhi,$Xi); 1st phase
        +	  &psllq	($Xi,1);
        +	  &pxor		($Xi,$T1);		#
        +	  &psllq	($Xi,5);		#
        +	  &pxor		($Xi,$T1);		#
        +	&pclmulqdq	($Xn,$Hkey,0x00);	#######
        +	  &psllq	($Xi,57);		#
        +	  &movdqa	($T2,$Xi);		#
        +	  &pslldq	($Xi,8);
        +	  &psrldq	($T2,8);		#	
        +	  &pxor		($Xi,$T1);
        +	&pshufd		($T1,$T3,0b01001110);
        +	  &pxor		($Xhi,$T2);		#
        +	&pxor		($T1,$T3);
        +	&pshufd		($T3,$Hkey,0b01001110);
        +	&pxor		($T3,$Hkey);		#
        +
        +	&pclmulqdq	($Xhn,$Hkey,0x11);	#######
        +	  &movdqa	($T2,$Xi);		# 2nd phase
        +	  &psrlq	($Xi,5);
        +	  &pxor		($Xi,$T2);		#
        +	  &psrlq	($Xi,1);		#
        +	  &pxor		($Xi,$T2);		#
        +	  &pxor		($T2,$Xhi);
        +	  &psrlq	($Xi,1);		#
        +	  &pxor		($Xi,$T2);		#
        +
        +	&pclmulqdq	($T1,$T3,0x00);		#######
        +	&movups		($Hkey,&QWP(16,$Htbl));	# load H^2
        +	&xorps		($T1,$Xn);		#
        +	&xorps		($T1,$Xhn);		#
        +
        +	&movdqa		($T3,$T1);		#
        +	&psrldq		($T1,8);
        +	&pslldq		($T3,8);		#
        +	&pxor		($Xhn,$T1);
        +	&pxor		($Xn,$T3);		#
        +	&movdqa		($T3,&QWP(0,$const));
        +
        +	&lea		($inp,&DWP(32,$inp));
        +	&sub		($len,0x20);
        +	&ja		(&label("mod_loop"));
        +
        +&set_label("even_tail");
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);	# H^2*(Ii+Xi)
        +
        +	&pxor		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
        +	&pxor		($Xhi,$Xhn);
        +
        +	&reduction_alg9	($Xhi,$Xi);
        +
        +	&test		($len,$len);
        +	&jnz		(&label("done"));
        +
        +	&movups		($Hkey,&QWP(0,$Htbl));	# load H
        +&set_label("odd_tail");
        +	&movdqu		($T1,&QWP(0,$inp));	# Ii
        +	&pshufb		($T1,$T3);
        +	&pxor		($Xi,$T1);		# Ii+Xi
        +
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);	# H*(Ii+Xi)
        +	&reduction_alg9	($Xhi,$Xi);
        +
        +&set_label("done");
        +	&pshufb		($Xi,$T3);
        +	&movdqu		(&QWP(0,$Xip),$Xi);
        +&function_end("gcm_ghash_clmul");
        +
        +} else {		# Algorith 5. Kept for reference purposes.
        +
        +sub reduction_alg5 {	# 19/16 times faster than Intel version
        +my ($Xhi,$Xi)=@_;
        +
        +	# <<1
        +	&movdqa		($T1,$Xi);		#
        +	&movdqa		($T2,$Xhi);
        +	&pslld		($Xi,1);
        +	&pslld		($Xhi,1);		#
        +	&psrld		($T1,31);
        +	&psrld		($T2,31);		#
        +	&movdqa		($T3,$T1);
        +	&pslldq		($T1,4);
        +	&psrldq		($T3,12);		#
        +	&pslldq		($T2,4);
        +	&por		($Xhi,$T3);		#
        +	&por		($Xi,$T1);
        +	&por		($Xhi,$T2);		#
        +
        +	# 1st phase
        +	&movdqa		($T1,$Xi);
        +	&movdqa		($T2,$Xi);
        +	&movdqa		($T3,$Xi);		#
        +	&pslld		($T1,31);
        +	&pslld		($T2,30);
        +	&pslld		($Xi,25);		#
        +	&pxor		($T1,$T2);
        +	&pxor		($T1,$Xi);		#
        +	&movdqa		($T2,$T1);		#
        +	&pslldq		($T1,12);
        +	&psrldq		($T2,4);		#
        +	&pxor		($T3,$T1);
        +
        +	# 2nd phase
        +	&pxor		($Xhi,$T3);		#
        +	&movdqa		($Xi,$T3);
        +	&movdqa		($T1,$T3);
        +	&psrld		($Xi,1);		#
        +	&psrld		($T1,2);
        +	&psrld		($T3,7);		#
        +	&pxor		($Xi,$T1);
        +	&pxor		($Xhi,$T2);
        +	&pxor		($Xi,$T3);		#
        +	&pxor		($Xi,$Xhi);		#
        +}
        +
        +&function_begin_B("gcm_init_clmul");
        +	&mov		($Htbl,&wparam(0));
        +	&mov		($Xip,&wparam(1));
        +
        +	&call		(&label("pic"));
        +&set_label("pic");
        +	&blindpop	($const);
        +	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
        +
        +	&movdqu		($Hkey,&QWP(0,$Xip));
        +	&pshufd		($Hkey,$Hkey,0b01001110);# dword swap
        +
        +	# calculate H^2
        +	&movdqa		($Xi,$Hkey);
        +	&clmul64x64_T3	($Xhi,$Xi,$Hkey);
        +	&reduction_alg5	($Xhi,$Xi);
        +
        +	&movdqu		(&QWP(0,$Htbl),$Hkey);	# save H
        +	&movdqu		(&QWP(16,$Htbl),$Xi);	# save H^2
        +
        +	&ret		();
        +&function_end_B("gcm_init_clmul");
        +
        +&function_begin_B("gcm_gmult_clmul");
        +	&mov		($Xip,&wparam(0));
        +	&mov		($Htbl,&wparam(1));
        +
        +	&call		(&label("pic"));
        +&set_label("pic");
        +	&blindpop	($const);
        +	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
        +
        +	&movdqu		($Xi,&QWP(0,$Xip));
        +	&movdqa		($Xn,&QWP(0,$const));
        +	&movdqu		($Hkey,&QWP(0,$Htbl));
        +	&pshufb		($Xi,$Xn);
        +
        +	&clmul64x64_T3	($Xhi,$Xi,$Hkey);
        +	&reduction_alg5	($Xhi,$Xi);
        +
        +	&pshufb		($Xi,$Xn);
        +	&movdqu		(&QWP(0,$Xip),$Xi);
        +
        +	&ret	();
        +&function_end_B("gcm_gmult_clmul");
        +
        +&function_begin("gcm_ghash_clmul");
        +	&mov		($Xip,&wparam(0));
        +	&mov		($Htbl,&wparam(1));
        +	&mov		($inp,&wparam(2));
        +	&mov		($len,&wparam(3));
        +
        +	&call		(&label("pic"));
        +&set_label("pic");
        +	&blindpop	($const);
        +	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
        +
        +	&movdqu		($Xi,&QWP(0,$Xip));
        +	&movdqa		($T3,&QWP(0,$const));
        +	&movdqu		($Hkey,&QWP(0,$Htbl));
        +	&pshufb		($Xi,$T3);
        +
        +	&sub		($len,0x10);
        +	&jz		(&label("odd_tail"));
        +
        +	#######
        +	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
        +	#	[(H*Ii+1) + (H*Xi+1)] mod P =
        +	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
        +	#
        +	&movdqu		($T1,&QWP(0,$inp));	# Ii
        +	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
        +	&pshufb		($T1,$T3);
        +	&pshufb		($Xn,$T3);
        +	&pxor		($Xi,$T1);		# Ii+Xi
        +
        +	&clmul64x64_T3	($Xhn,$Xn,$Hkey);	# H*Ii+1
        +	&movdqu		($Hkey,&QWP(16,$Htbl));	# load H^2
        +
        +	&sub		($len,0x20);
        +	&lea		($inp,&DWP(32,$inp));	# i+=2
        +	&jbe		(&label("even_tail"));
        +
        +&set_label("mod_loop");
        +	&clmul64x64_T3	($Xhi,$Xi,$Hkey);	# H^2*(Ii+Xi)
        +	&movdqu		($Hkey,&QWP(0,$Htbl));	# load H
        +
        +	&pxor		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
        +	&pxor		($Xhi,$Xhn);
        +
        +	&reduction_alg5	($Xhi,$Xi);
        +
        +	#######
        +	&movdqa		($T3,&QWP(0,$const));
        +	&movdqu		($T1,&QWP(0,$inp));	# Ii
        +	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
        +	&pshufb		($T1,$T3);
        +	&pshufb		($Xn,$T3);
        +	&pxor		($Xi,$T1);		# Ii+Xi
        +
        +	&clmul64x64_T3	($Xhn,$Xn,$Hkey);	# H*Ii+1
        +	&movdqu		($Hkey,&QWP(16,$Htbl));	# load H^2
        +
        +	&sub		($len,0x20);
        +	&lea		($inp,&DWP(32,$inp));
        +	&ja		(&label("mod_loop"));
        +
        +&set_label("even_tail");
        +	&clmul64x64_T3	($Xhi,$Xi,$Hkey);	# H^2*(Ii+Xi)
        +
        +	&pxor		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
        +	&pxor		($Xhi,$Xhn);
        +
        +	&reduction_alg5	($Xhi,$Xi);
        +
        +	&movdqa		($T3,&QWP(0,$const));
        +	&test		($len,$len);
        +	&jnz		(&label("done"));
        +
        +	&movdqu		($Hkey,&QWP(0,$Htbl));	# load H
        +&set_label("odd_tail");
        +	&movdqu		($T1,&QWP(0,$inp));	# Ii
        +	&pshufb		($T1,$T3);
        +	&pxor		($Xi,$T1);		# Ii+Xi
        +
        +	&clmul64x64_T3	($Xhi,$Xi,$Hkey);	# H*(Ii+Xi)
        +	&reduction_alg5	($Xhi,$Xi);
        +
        +	&movdqa		($T3,&QWP(0,$const));
        +&set_label("done");
        +	&pshufb		($Xi,$T3);
        +	&movdqu		(&QWP(0,$Xip),$Xi);
        +&function_end("gcm_ghash_clmul");
        +
        +}
        +
        +&set_label("bswap",64);
        +	&data_byte(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
        +	&data_byte(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2);	# 0x1c2_polynomial
        +}}	# $sse2
        +
        +&set_label("rem_4bit",64);
        +	&data_word(0,0x0000<<$S,0,0x1C20<<$S,0,0x3840<<$S,0,0x2460<<$S);
        +	&data_word(0,0x7080<<$S,0,0x6CA0<<$S,0,0x48C0<<$S,0,0x54E0<<$S);
        +	&data_word(0,0xE100<<$S,0,0xFD20<<$S,0,0xD940<<$S,0,0xC560<<$S);
        +	&data_word(0,0x9180<<$S,0,0x8DA0<<$S,0,0xA9C0<<$S,0,0xB5E0<<$S);
        +&set_label("rem_8bit",64);
        +	&data_short(0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E);
        +	&data_short(0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E);
        +	&data_short(0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E);
        +	&data_short(0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E);
        +	&data_short(0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E);
        +	&data_short(0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E);
        +	&data_short(0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E);
        +	&data_short(0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E);
        +	&data_short(0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE);
        +	&data_short(0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE);
        +	&data_short(0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE);
        +	&data_short(0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE);
        +	&data_short(0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E);
        +	&data_short(0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E);
        +	&data_short(0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE);
        +	&data_short(0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE);
        +	&data_short(0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E);
        +	&data_short(0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E);
        +	&data_short(0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E);
        +	&data_short(0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E);
        +	&data_short(0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E);
        +	&data_short(0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E);
        +	&data_short(0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E);
        +	&data_short(0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E);
        +	&data_short(0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE);
        +	&data_short(0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE);
        +	&data_short(0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE);
        +	&data_short(0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE);
        +	&data_short(0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E);
        +	&data_short(0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E);
        +	&data_short(0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE);
        +	&data_short(0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE);
        +}}}	# !$x86only
        +
        +&asciz("GHASH for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +&asm_finish();
        +
        +# A question was risen about choice of vanilla MMX. Or rather why wasn't
        +# SSE2 chosen instead? In addition to the fact that MMX runs on legacy
        +# CPUs such as PIII, "4-bit" MMX version was observed to provide better
        +# performance than *corresponding* SSE2 one even on contemporary CPUs.
        +# SSE2 results were provided by Peter-Michael Hager. He maintains SSE2
        +# implementation featuring full range of lookup-table sizes, but with
        +# per-invocation lookup table setup. Latter means that table size is
        +# chosen depending on how much data is to be hashed in every given call,
        +# more data - larger table. Best reported result for Core2 is ~4 cycles
        +# per processed byte out of 64KB block. This number accounts even for
        +# 64KB table setup overhead. As discussed in gcm128.c we choose to be
        +# more conservative in respect to lookup table sizes, but how do the
        +# results compare? Minimalistic "256B" MMX version delivers ~11 cycles
        +# on same platform. As also discussed in gcm128.c, next in line "8-bit
        +# Shoup's" or "4KB" method should deliver twice the performance of
        +# "256B" one, in other words not worse than ~6 cycles per byte. It
        +# should be also be noted that in SSE2 case improvement can be "super-
        +# linear," i.e. more than twice, mostly because >>8 maps to single
        +# instruction on SSE2 register. This is unlike "4-bit" case when >>4
        +# maps to same amount of instructions in both MMX and SSE2 cases.
        +# Bottom line is that switch to SSE2 is considered to be justifiable
        +# only in case we choose to implement "8-bit" method...
        diff --git a/vendor/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl b/vendor/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl
        new file mode 100644
        index 000000000..38d779edb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/asm/ghash-x86_64.pl
        @@ -0,0 +1,806 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# March, June 2010
        +#
        +# The module implements "4-bit" GCM GHASH function and underlying
        +# single multiplication operation in GF(2^128). "4-bit" means that
        +# it uses 256 bytes per-key table [+128 bytes shared table]. GHASH
        +# function features so called "528B" variant utilizing additional
        +# 256+16 bytes of per-key storage [+512 bytes shared table].
        +# Performance results are for this streamed GHASH subroutine and are
        +# expressed in cycles per processed byte, less is better:
        +#
        +#		gcc 3.4.x(*)	assembler
        +#
        +# P4		28.6		14.0		+100%
        +# Opteron	19.3		7.7		+150%
        +# Core2		17.8		8.1(**)		+120%
        +#
        +# (*)	comparison is not completely fair, because C results are
        +#	for vanilla "256B" implementation, while assembler results
        +#	are for "528B";-)
        +# (**)	it's mystery [to me] why Core2 result is not same as for
        +#	Opteron;
        +
        +# May 2010
        +#
        +# Add PCLMULQDQ version performing at 2.02 cycles per processed byte.
        +# See ghash-x86.pl for background information and details about coding
        +# techniques.
        +#
        +# Special thanks to David Woodhouse <dwmw2@infradead.org> for
        +# providing access to a Westmere-based system on behalf of Intel
        +# Open Source Technology Centre.
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +# common register layout
        +$nlo="%rax";
        +$nhi="%rbx";
        +$Zlo="%r8";
        +$Zhi="%r9";
        +$tmp="%r10";
        +$rem_4bit = "%r11";
        +
        +$Xi="%rdi";
        +$Htbl="%rsi";
        +
        +# per-function register layout
        +$cnt="%rcx";
        +$rem="%rdx";
        +
        +sub LB() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/	or
        +			$r =~ s/%[er]([sd]i)/%\1l/	or
        +			$r =~ s/%[er](bp)/%\1l/		or
        +			$r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
        +
        +sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
        +{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
        +  my $arg = pop;
        +    $arg = "\$$arg" if ($arg*1 eq $arg);
        +    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
        +}
        +
        +{ my $N;
        +  sub loop() {
        +  my $inp = shift;
        +
        +	$N++;
        +$code.=<<___;
        +	xor	$nlo,$nlo
        +	xor	$nhi,$nhi
        +	mov	`&LB("$Zlo")`,`&LB("$nlo")`
        +	mov	`&LB("$Zlo")`,`&LB("$nhi")`
        +	shl	\$4,`&LB("$nlo")`
        +	mov	\$14,$cnt
        +	mov	8($Htbl,$nlo),$Zlo
        +	mov	($Htbl,$nlo),$Zhi
        +	and	\$0xf0,`&LB("$nhi")`
        +	mov	$Zlo,$rem
        +	jmp	.Loop$N
        +
        +.align	16
        +.Loop$N:
        +	shr	\$4,$Zlo
        +	and	\$0xf,$rem
        +	mov	$Zhi,$tmp
        +	mov	($inp,$cnt),`&LB("$nlo")`
        +	shr	\$4,$Zhi
        +	xor	8($Htbl,$nhi),$Zlo
        +	shl	\$60,$tmp
        +	xor	($Htbl,$nhi),$Zhi
        +	mov	`&LB("$nlo")`,`&LB("$nhi")`
        +	xor	($rem_4bit,$rem,8),$Zhi
        +	mov	$Zlo,$rem
        +	shl	\$4,`&LB("$nlo")`
        +	xor	$tmp,$Zlo
        +	dec	$cnt
        +	js	.Lbreak$N
        +
        +	shr	\$4,$Zlo
        +	and	\$0xf,$rem
        +	mov	$Zhi,$tmp
        +	shr	\$4,$Zhi
        +	xor	8($Htbl,$nlo),$Zlo
        +	shl	\$60,$tmp
        +	xor	($Htbl,$nlo),$Zhi
        +	and	\$0xf0,`&LB("$nhi")`
        +	xor	($rem_4bit,$rem,8),$Zhi
        +	mov	$Zlo,$rem
        +	xor	$tmp,$Zlo
        +	jmp	.Loop$N
        +
        +.align	16
        +.Lbreak$N:
        +	shr	\$4,$Zlo
        +	and	\$0xf,$rem
        +	mov	$Zhi,$tmp
        +	shr	\$4,$Zhi
        +	xor	8($Htbl,$nlo),$Zlo
        +	shl	\$60,$tmp
        +	xor	($Htbl,$nlo),$Zhi
        +	and	\$0xf0,`&LB("$nhi")`
        +	xor	($rem_4bit,$rem,8),$Zhi
        +	mov	$Zlo,$rem
        +	xor	$tmp,$Zlo
        +
        +	shr	\$4,$Zlo
        +	and	\$0xf,$rem
        +	mov	$Zhi,$tmp
        +	shr	\$4,$Zhi
        +	xor	8($Htbl,$nhi),$Zlo
        +	shl	\$60,$tmp
        +	xor	($Htbl,$nhi),$Zhi
        +	xor	$tmp,$Zlo
        +	xor	($rem_4bit,$rem,8),$Zhi
        +
        +	bswap	$Zlo
        +	bswap	$Zhi
        +___
        +}}
        +
        +$code=<<___;
        +.text
        +
        +.globl	gcm_gmult_4bit
        +.type	gcm_gmult_4bit,\@function,2
        +.align	16
        +gcm_gmult_4bit:
        +	push	%rbx
        +	push	%rbp		# %rbp and %r12 are pushed exclusively in
        +	push	%r12		# order to reuse Win64 exception handler...
        +.Lgmult_prologue:
        +
        +	movzb	15($Xi),$Zlo
        +	lea	.Lrem_4bit(%rip),$rem_4bit
        +___
        +	&loop	($Xi);
        +$code.=<<___;
        +	mov	$Zlo,8($Xi)
        +	mov	$Zhi,($Xi)
        +
        +	mov	16(%rsp),%rbx
        +	lea	24(%rsp),%rsp
        +.Lgmult_epilogue:
        +	ret
        +.size	gcm_gmult_4bit,.-gcm_gmult_4bit
        +___
        +
        +# per-function register layout
        +$inp="%rdx";
        +$len="%rcx";
        +$rem_8bit=$rem_4bit;
        +
        +$code.=<<___;
        +.globl	gcm_ghash_4bit
        +.type	gcm_ghash_4bit,\@function,4
        +.align	16
        +gcm_ghash_4bit:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	sub	\$280,%rsp
        +.Lghash_prologue:
        +	mov	$inp,%r14		# reassign couple of args
        +	mov	$len,%r15
        +___
        +{ my $inp="%r14";
        +  my $dat="%edx";
        +  my $len="%r15";
        +  my @nhi=("%ebx","%ecx");
        +  my @rem=("%r12","%r13");
        +  my $Hshr4="%rbp";
        +
        +	&sub	($Htbl,-128);		# size optimization
        +	&lea	($Hshr4,"16+128(%rsp)");
        +	{ my @lo =($nlo,$nhi);
        +          my @hi =($Zlo,$Zhi);
        +
        +	  &xor	($dat,$dat);
        +	  for ($i=0,$j=-2;$i<18;$i++,$j++) {
        +	    &mov	("$j(%rsp)",&LB($dat))		if ($i>1);
        +	    &or		($lo[0],$tmp)			if ($i>1);
        +	    &mov	(&LB($dat),&LB($lo[1]))		if ($i>0 && $i<17);
        +	    &shr	($lo[1],4)			if ($i>0 && $i<17);
        +	    &mov	($tmp,$hi[1])			if ($i>0 && $i<17);
        +	    &shr	($hi[1],4)			if ($i>0 && $i<17);
        +	    &mov	("8*$j($Hshr4)",$hi[0])		if ($i>1);
        +	    &mov	($hi[0],"16*$i+0-128($Htbl)")	if ($i<16);
        +	    &shl	(&LB($dat),4)			if ($i>0 && $i<17);
        +	    &mov	("8*$j-128($Hshr4)",$lo[0])	if ($i>1);
        +	    &mov	($lo[0],"16*$i+8-128($Htbl)")	if ($i<16);
        +	    &shl	($tmp,60)			if ($i>0 && $i<17);
        +
        +	    push	(@lo,shift(@lo));
        +	    push	(@hi,shift(@hi));
        +	  }
        +	}
        +	&add	($Htbl,-128);
        +	&mov	($Zlo,"8($Xi)");
        +	&mov	($Zhi,"0($Xi)");
        +	&add	($len,$inp);		# pointer to the end of data
        +	&lea	($rem_8bit,".Lrem_8bit(%rip)");
        +	&jmp	(".Louter_loop");
        +
        +$code.=".align	16\n.Louter_loop:\n";
        +	&xor	($Zhi,"($inp)");
        +	&mov	("%rdx","8($inp)");
        +	&lea	($inp,"16($inp)");
        +	&xor	("%rdx",$Zlo);
        +	&mov	("($Xi)",$Zhi);
        +	&mov	("8($Xi)","%rdx");
        +	&shr	("%rdx",32);
        +
        +	&xor	($nlo,$nlo);
        +	&rol	($dat,8);
        +	&mov	(&LB($nlo),&LB($dat));
        +	&movz	($nhi[0],&LB($dat));
        +	&shl	(&LB($nlo),4);
        +	&shr	($nhi[0],4);
        +
        +	for ($j=11,$i=0;$i<15;$i++) {
        +	    &rol	($dat,8);
        +	    &xor	($Zlo,"8($Htbl,$nlo)")			if ($i>0);
        +	    &xor	($Zhi,"($Htbl,$nlo)")			if ($i>0);
        +	    &mov	($Zlo,"8($Htbl,$nlo)")			if ($i==0);
        +	    &mov	($Zhi,"($Htbl,$nlo)")			if ($i==0);
        +
        +	    &mov	(&LB($nlo),&LB($dat));
        +	    &xor	($Zlo,$tmp)				if ($i>0);
        +	    &movzw	($rem[1],"($rem_8bit,$rem[1],2)")	if ($i>0);
        +
        +	    &movz	($nhi[1],&LB($dat));
        +	    &shl	(&LB($nlo),4);
        +	    &movzb	($rem[0],"(%rsp,$nhi[0])");
        +
        +	    &shr	($nhi[1],4)				if ($i<14);
        +	    &and	($nhi[1],0xf0)				if ($i==14);
        +	    &shl	($rem[1],48)				if ($i>0);
        +	    &xor	($rem[0],$Zlo);
        +
        +	    &mov	($tmp,$Zhi);
        +	    &xor	($Zhi,$rem[1])				if ($i>0);
        +	    &shr	($Zlo,8);
        +
        +	    &movz	($rem[0],&LB($rem[0]));
        +	    &mov	($dat,"$j($Xi)")			if (--$j%4==0);
        +	    &shr	($Zhi,8);
        +
        +	    &xor	($Zlo,"-128($Hshr4,$nhi[0],8)");
        +	    &shl	($tmp,56);
        +	    &xor	($Zhi,"($Hshr4,$nhi[0],8)");
        +
        +	    unshift	(@nhi,pop(@nhi));		# "rotate" registers
        +	    unshift	(@rem,pop(@rem));
        +	}
        +	&movzw	($rem[1],"($rem_8bit,$rem[1],2)");
        +	&xor	($Zlo,"8($Htbl,$nlo)");
        +	&xor	($Zhi,"($Htbl,$nlo)");
        +
        +	&shl	($rem[1],48);
        +	&xor	($Zlo,$tmp);
        +
        +	&xor	($Zhi,$rem[1]);
        +	&movz	($rem[0],&LB($Zlo));
        +	&shr	($Zlo,4);
        +
        +	&mov	($tmp,$Zhi);
        +	&shl	(&LB($rem[0]),4);
        +	&shr	($Zhi,4);
        +
        +	&xor	($Zlo,"8($Htbl,$nhi[0])");
        +	&movzw	($rem[0],"($rem_8bit,$rem[0],2)");
        +	&shl	($tmp,60);
        +
        +	&xor	($Zhi,"($Htbl,$nhi[0])");
        +	&xor	($Zlo,$tmp);
        +	&shl	($rem[0],48);
        +
        +	&bswap	($Zlo);
        +	&xor	($Zhi,$rem[0]);
        +
        +	&bswap	($Zhi);
        +	&cmp	($inp,$len);
        +	&jb	(".Louter_loop");
        +}
        +$code.=<<___;
        +	mov	$Zlo,8($Xi)
        +	mov	$Zhi,($Xi)
        +
        +	lea	280(%rsp),%rsi
        +	mov	0(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lghash_epilogue:
        +	ret
        +.size	gcm_ghash_4bit,.-gcm_ghash_4bit
        +___
        +
        +######################################################################
        +# PCLMULQDQ version.
        +
        +@_4args=$win64?	("%rcx","%rdx","%r8", "%r9") :	# Win64 order
        +		("%rdi","%rsi","%rdx","%rcx");	# Unix order
        +
        +($Xi,$Xhi)=("%xmm0","%xmm1");	$Hkey="%xmm2";
        +($T1,$T2,$T3)=("%xmm3","%xmm4","%xmm5");
        +
        +sub clmul64x64_T2 {	# minimal register pressure
        +my ($Xhi,$Xi,$Hkey,$modulo)=@_;
        +
        +$code.=<<___ if (!defined($modulo));
        +	movdqa		$Xi,$Xhi		#
        +	pshufd		\$0b01001110,$Xi,$T1
        +	pshufd		\$0b01001110,$Hkey,$T2
        +	pxor		$Xi,$T1			#
        +	pxor		$Hkey,$T2
        +___
        +$code.=<<___;
        +	pclmulqdq	\$0x00,$Hkey,$Xi	#######
        +	pclmulqdq	\$0x11,$Hkey,$Xhi	#######
        +	pclmulqdq	\$0x00,$T2,$T1		#######
        +	pxor		$Xi,$T1			#
        +	pxor		$Xhi,$T1		#
        +
        +	movdqa		$T1,$T2			#
        +	psrldq		\$8,$T1
        +	pslldq		\$8,$T2			#
        +	pxor		$T1,$Xhi
        +	pxor		$T2,$Xi			#
        +___
        +}
        +
        +sub reduction_alg9 {	# 17/13 times faster than Intel version
        +my ($Xhi,$Xi) = @_;
        +
        +$code.=<<___;
        +	# 1st phase
        +	movdqa		$Xi,$T1			#
        +	psllq		\$1,$Xi
        +	pxor		$T1,$Xi			#
        +	psllq		\$5,$Xi			#
        +	pxor		$T1,$Xi			#
        +	psllq		\$57,$Xi		#
        +	movdqa		$Xi,$T2			#
        +	pslldq		\$8,$Xi
        +	psrldq		\$8,$T2			#	
        +	pxor		$T1,$Xi
        +	pxor		$T2,$Xhi		#
        +
        +	# 2nd phase
        +	movdqa		$Xi,$T2
        +	psrlq		\$5,$Xi
        +	pxor		$T2,$Xi			#
        +	psrlq		\$1,$Xi			#
        +	pxor		$T2,$Xi			#
        +	pxor		$Xhi,$T2
        +	psrlq		\$1,$Xi			#
        +	pxor		$T2,$Xi			#
        +___
        +}
        +
        +{ my ($Htbl,$Xip)=@_4args;
        +
        +$code.=<<___;
        +.globl	gcm_init_clmul
        +.type	gcm_init_clmul,\@abi-omnipotent
        +.align	16
        +gcm_init_clmul:
        +	movdqu		($Xip),$Hkey
        +	pshufd		\$0b01001110,$Hkey,$Hkey	# dword swap
        +
        +	# <<1 twist
        +	pshufd		\$0b11111111,$Hkey,$T2	# broadcast uppermost dword
        +	movdqa		$Hkey,$T1
        +	psllq		\$1,$Hkey
        +	pxor		$T3,$T3			#
        +	psrlq		\$63,$T1
        +	pcmpgtd		$T2,$T3			# broadcast carry bit
        +	pslldq		\$8,$T1
        +	por		$T1,$Hkey		# H<<=1
        +
        +	# magic reduction
        +	pand		.L0x1c2_polynomial(%rip),$T3
        +	pxor		$T3,$Hkey		# if(carry) H^=0x1c2_polynomial
        +
        +	# calculate H^2
        +	movdqa		$Hkey,$Xi
        +___
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);
        +	&reduction_alg9	($Xhi,$Xi);
        +$code.=<<___;
        +	movdqu		$Hkey,($Htbl)		# save H
        +	movdqu		$Xi,16($Htbl)		# save H^2
        +	ret
        +.size	gcm_init_clmul,.-gcm_init_clmul
        +___
        +}
        +
        +{ my ($Xip,$Htbl)=@_4args;
        +
        +$code.=<<___;
        +.globl	gcm_gmult_clmul
        +.type	gcm_gmult_clmul,\@abi-omnipotent
        +.align	16
        +gcm_gmult_clmul:
        +	movdqu		($Xip),$Xi
        +	movdqa		.Lbswap_mask(%rip),$T3
        +	movdqu		($Htbl),$Hkey
        +	pshufb		$T3,$Xi
        +___
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);
        +	&reduction_alg9	($Xhi,$Xi);
        +$code.=<<___;
        +	pshufb		$T3,$Xi
        +	movdqu		$Xi,($Xip)
        +	ret
        +.size	gcm_gmult_clmul,.-gcm_gmult_clmul
        +___
        +}
        +
        +{ my ($Xip,$Htbl,$inp,$len)=@_4args;
        +  my $Xn="%xmm6";
        +  my $Xhn="%xmm7";
        +  my $Hkey2="%xmm8";
        +  my $T1n="%xmm9";
        +  my $T2n="%xmm10";
        +
        +$code.=<<___;
        +.globl	gcm_ghash_clmul
        +.type	gcm_ghash_clmul,\@abi-omnipotent
        +.align	16
        +gcm_ghash_clmul:
        +___
        +$code.=<<___ if ($win64);
        +.LSEH_begin_gcm_ghash_clmul:
        +	# I can't trust assembler to use specific encoding:-(
        +	.byte	0x48,0x83,0xec,0x58		#sub	\$0x58,%rsp
        +	.byte	0x0f,0x29,0x34,0x24		#movaps	%xmm6,(%rsp)
        +	.byte	0x0f,0x29,0x7c,0x24,0x10	#movdqa	%xmm7,0x10(%rsp)
        +	.byte	0x44,0x0f,0x29,0x44,0x24,0x20	#movaps	%xmm8,0x20(%rsp)
        +	.byte	0x44,0x0f,0x29,0x4c,0x24,0x30	#movaps	%xmm9,0x30(%rsp)
        +	.byte	0x44,0x0f,0x29,0x54,0x24,0x40	#movaps	%xmm10,0x40(%rsp)
        +___
        +$code.=<<___;
        +	movdqa		.Lbswap_mask(%rip),$T3
        +
        +	movdqu		($Xip),$Xi
        +	movdqu		($Htbl),$Hkey
        +	pshufb		$T3,$Xi
        +
        +	sub		\$0x10,$len
        +	jz		.Lodd_tail
        +
        +	movdqu		16($Htbl),$Hkey2
        +	#######
        +	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
        +	#	[(H*Ii+1) + (H*Xi+1)] mod P =
        +	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
        +	#
        +	movdqu		($inp),$T1		# Ii
        +	movdqu		16($inp),$Xn		# Ii+1
        +	pshufb		$T3,$T1
        +	pshufb		$T3,$Xn
        +	pxor		$T1,$Xi			# Ii+Xi
        +___
        +	&clmul64x64_T2	($Xhn,$Xn,$Hkey);	# H*Ii+1
        +$code.=<<___;
        +	movdqa		$Xi,$Xhi		#
        +	pshufd		\$0b01001110,$Xi,$T1
        +	pshufd		\$0b01001110,$Hkey2,$T2
        +	pxor		$Xi,$T1			#
        +	pxor		$Hkey2,$T2
        +
        +	lea		32($inp),$inp		# i+=2
        +	sub		\$0x20,$len
        +	jbe		.Leven_tail
        +
        +.Lmod_loop:
        +___
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey2,1);	# H^2*(Ii+Xi)
        +$code.=<<___;
        +	movdqu		($inp),$T1		# Ii
        +	pxor		$Xn,$Xi			# (H*Ii+1) + H^2*(Ii+Xi)
        +	pxor		$Xhn,$Xhi
        +
        +	movdqu		16($inp),$Xn		# Ii+1
        +	pshufb		$T3,$T1
        +	pshufb		$T3,$Xn
        +
        +	movdqa		$Xn,$Xhn		#
        +	pshufd		\$0b01001110,$Xn,$T1n
        +	pshufd		\$0b01001110,$Hkey,$T2n
        +	pxor		$Xn,$T1n		#
        +	pxor		$Hkey,$T2n
        +	 pxor		$T1,$Xhi		# "Ii+Xi", consume early
        +
        +	  movdqa	$Xi,$T1			# 1st phase
        +	  psllq		\$1,$Xi
        +	  pxor		$T1,$Xi			#
        +	  psllq		\$5,$Xi			#
        +	  pxor		$T1,$Xi			#
        +	pclmulqdq	\$0x00,$Hkey,$Xn	#######
        +	  psllq		\$57,$Xi		#
        +	  movdqa	$Xi,$T2			#
        +	  pslldq	\$8,$Xi
        +	  psrldq	\$8,$T2			#	
        +	  pxor		$T1,$Xi
        +	  pxor		$T2,$Xhi		#
        +
        +	pclmulqdq	\$0x11,$Hkey,$Xhn	#######
        +	  movdqa	$Xi,$T2			# 2nd phase
        +	  psrlq		\$5,$Xi
        +	  pxor		$T2,$Xi			#
        +	  psrlq		\$1,$Xi			#
        +	  pxor		$T2,$Xi			#
        +	  pxor		$Xhi,$T2
        +	  psrlq		\$1,$Xi			#
        +	  pxor		$T2,$Xi			#
        +
        +	pclmulqdq	\$0x00,$T2n,$T1n	#######
        +	 movdqa		$Xi,$Xhi		#
        +	 pshufd		\$0b01001110,$Xi,$T1
        +	 pshufd		\$0b01001110,$Hkey2,$T2
        +	 pxor		$Xi,$T1			#
        +	 pxor		$Hkey2,$T2
        +
        +	pxor		$Xn,$T1n		#
        +	pxor		$Xhn,$T1n		#
        +	movdqa		$T1n,$T2n		#
        +	psrldq		\$8,$T1n
        +	pslldq		\$8,$T2n		#
        +	pxor		$T1n,$Xhn
        +	pxor		$T2n,$Xn		#
        +
        +	lea		32($inp),$inp
        +	sub		\$0x20,$len
        +	ja		.Lmod_loop
        +
        +.Leven_tail:
        +___
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey2,1);	# H^2*(Ii+Xi)
        +$code.=<<___;
        +	pxor		$Xn,$Xi			# (H*Ii+1) + H^2*(Ii+Xi)
        +	pxor		$Xhn,$Xhi
        +___
        +	&reduction_alg9	($Xhi,$Xi);
        +$code.=<<___;
        +	test		$len,$len
        +	jnz		.Ldone
        +
        +.Lodd_tail:
        +	movdqu		($inp),$T1		# Ii
        +	pshufb		$T3,$T1
        +	pxor		$T1,$Xi			# Ii+Xi
        +___
        +	&clmul64x64_T2	($Xhi,$Xi,$Hkey);	# H*(Ii+Xi)
        +	&reduction_alg9	($Xhi,$Xi);
        +$code.=<<___;
        +.Ldone:
        +	pshufb		$T3,$Xi
        +	movdqu		$Xi,($Xip)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	(%rsp),%xmm6
        +	movaps	0x10(%rsp),%xmm7
        +	movaps	0x20(%rsp),%xmm8
        +	movaps	0x30(%rsp),%xmm9
        +	movaps	0x40(%rsp),%xmm10
        +	add	\$0x58,%rsp
        +___
        +$code.=<<___;
        +	ret
        +.LSEH_end_gcm_ghash_clmul:
        +.size	gcm_ghash_clmul,.-gcm_ghash_clmul
        +___
        +}
        +
        +$code.=<<___;
        +.align	64
        +.Lbswap_mask:
        +	.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
        +.L0x1c2_polynomial:
        +	.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
        +.align	64
        +.type	.Lrem_4bit,\@object
        +.Lrem_4bit:
        +	.long	0,`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`
        +	.long	0,`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`
        +	.long	0,`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`
        +	.long	0,`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`
        +.type	.Lrem_8bit,\@object
        +.Lrem_8bit:
        +	.value	0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E
        +	.value	0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E
        +	.value	0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E
        +	.value	0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E
        +	.value	0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E
        +	.value	0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E
        +	.value	0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E
        +	.value	0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E
        +	.value	0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE
        +	.value	0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE
        +	.value	0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE
        +	.value	0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE
        +	.value	0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E
        +	.value	0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E
        +	.value	0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE
        +	.value	0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE
        +	.value	0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E
        +	.value	0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E
        +	.value	0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E
        +	.value	0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E
        +	.value	0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E
        +	.value	0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E
        +	.value	0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E
        +	.value	0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E
        +	.value	0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE
        +	.value	0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE
        +	.value	0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE
        +	.value	0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE
        +	.value	0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E
        +	.value	0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E
        +	.value	0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE
        +	.value	0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE
        +
        +.asciz	"GHASH for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	64
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_prologue
        +
        +	lea	24(%rax),%rax		# adjust "rsp"
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_gcm_gmult_4bit
        +	.rva	.LSEH_end_gcm_gmult_4bit
        +	.rva	.LSEH_info_gcm_gmult_4bit
        +
        +	.rva	.LSEH_begin_gcm_ghash_4bit
        +	.rva	.LSEH_end_gcm_ghash_4bit
        +	.rva	.LSEH_info_gcm_ghash_4bit
        +
        +	.rva	.LSEH_begin_gcm_ghash_clmul
        +	.rva	.LSEH_end_gcm_ghash_clmul
        +	.rva	.LSEH_info_gcm_ghash_clmul
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_gcm_gmult_4bit:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lgmult_prologue,.Lgmult_epilogue	# HandlerData
        +.LSEH_info_gcm_ghash_4bit:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +	.rva	.Lghash_prologue,.Lghash_epilogue	# HandlerData
        +.LSEH_info_gcm_ghash_clmul:
        +	.byte	0x01,0x1f,0x0b,0x00
        +	.byte	0x1f,0xa8,0x04,0x00	#movaps 0x40(rsp),xmm10
        +	.byte	0x19,0x98,0x03,0x00	#movaps 0x30(rsp),xmm9
        +	.byte	0x13,0x88,0x02,0x00	#movaps 0x20(rsp),xmm8
        +	.byte	0x0d,0x78,0x01,0x00	#movaps 0x10(rsp),xmm7
        +	.byte	0x08,0x68,0x00,0x00	#movaps (rsp),xmm6
        +	.byte	0x04,0xa2,0x00,0x00	#sub	rsp,0x58
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval($1)/gem;
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/modes/cbc128.c b/vendor/openssl/openssl/crypto/modes/cbc128.c
        new file mode 100644
        index 000000000..3d3782cbe
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/cbc128.c
        @@ -0,0 +1,202 @@
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +#ifndef STRICT_ALIGNMENT
        +#  define STRICT_ALIGNMENT 0
        +#endif
        +
        +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block)
        +{
        +	size_t n;
        +	const unsigned char *iv = ivec;
        +
        +	assert(in && out && key && ivec);
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (STRICT_ALIGNMENT &&
        +	    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
        +		while (len>=16) {
        +			for(n=0; n<16; ++n)
        +				out[n] = in[n] ^ iv[n];
        +			(*block)(out, out, key);
        +			iv = out;
        +			len -= 16;
        +			in  += 16;
        +			out += 16;
        +		}
        +	} else {
        +		while (len>=16) {
        +			for(n=0; n<16; n+=sizeof(size_t))
        +				*(size_t*)(out+n) =
        +				*(size_t*)(in+n) ^ *(size_t*)(iv+n);
        +			(*block)(out, out, key);
        +			iv = out;
        +			len -= 16;
        +			in  += 16;
        +			out += 16;
        +		}
        +	}
        +#endif
        +	while (len) {
        +		for(n=0; n<16 && n<len; ++n)
        +			out[n] = in[n] ^ iv[n];
        +		for(; n<16; ++n)
        +			out[n] = iv[n];
        +		(*block)(out, out, key);
        +		iv = out;
        +		if (len<=16) break;
        +		len -= 16;
        +		in  += 16;
        +		out += 16;
        +	}
        +	memcpy(ivec,iv,16);
        +}
        +
        +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block)
        +{
        +	size_t n;
        +	union { size_t align; unsigned char c[16]; } tmp;
        +
        +	assert(in && out && key && ivec);
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (in != out) {
        +		const unsigned char *iv = ivec;
        +
        +		if (STRICT_ALIGNMENT &&
        +		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
        +			while (len>=16) {
        +				(*block)(in, out, key);
        +				for(n=0; n<16; ++n)
        +					out[n] ^= iv[n];
        +				iv = in;
        +				len -= 16;
        +				in  += 16;
        +				out += 16;
        +			}
        +		}
        +		else {
        +			while (len>=16) {
        +				(*block)(in, out, key);
        +				for(n=0; n<16; n+=sizeof(size_t))
        +					*(size_t *)(out+n) ^= *(size_t *)(iv+n);
        +				iv = in;
        +				len -= 16;
        +				in  += 16;
        +				out += 16;
        +			}
        +		}
        +		memcpy(ivec,iv,16);
        +	} else {
        +		if (STRICT_ALIGNMENT &&
        +		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
        +			unsigned char c;
        +			while (len>=16) {
        +				(*block)(in, tmp.c, key);
        +				for(n=0; n<16; ++n) {
        +					c = in[n];
        +					out[n] = tmp.c[n] ^ ivec[n];
        +					ivec[n] = c;
        +				}
        +				len -= 16;
        +				in  += 16;
        +				out += 16;
        +			}
        +		}
        +		else {
        +			size_t c;
        +			while (len>=16) {
        +				(*block)(in, tmp.c, key);
        +				for(n=0; n<16; n+=sizeof(size_t)) {
        +					c = *(size_t *)(in+n);
        +					*(size_t *)(out+n) =
        +					*(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
        +					*(size_t *)(ivec+n) = c;
        +				}
        +				len -= 16;
        +				in  += 16;
        +				out += 16;
        +			}
        +		}
        +	}
        +#endif
        +	while (len) {
        +		unsigned char c;
        +		(*block)(in, tmp.c, key);
        +		for(n=0; n<16 && n<len; ++n) {
        +			c = in[n];
        +			out[n] = tmp.c[n] ^ ivec[n];
        +			ivec[n] = c;
        +		}
        +		if (len<=16) {
        +			for (; n<16; ++n)
        +				ivec[n] = in[n];
        +			break;
        +		}
        +		len -= 16;
        +		in  += 16;
        +		out += 16;
        +	}
        +}
        diff --git a/vendor/openssl/openssl/crypto/modes/ccm128.c b/vendor/openssl/openssl/crypto/modes/ccm128.c
        new file mode 100644
        index 000000000..c9b35e5b3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/ccm128.c
        @@ -0,0 +1,441 @@
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +/* First you setup M and L parameters and pass the key schedule.
        + * This is called once per session setup... */
        +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
        +	unsigned int M,unsigned int L,void *key,block128_f block)
        +{
        +	memset(ctx->nonce.c,0,sizeof(ctx->nonce.c));
        +	ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3;
        +	ctx->blocks = 0;
        +	ctx->block = block;
        +	ctx->key = key;
        +}
        +
        +/* !!! Following interfaces are to be called *once* per packet !!! */
        +
        +/* Then you setup per-message nonce and pass the length of the message */
        +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
        +	const unsigned char *nonce,size_t nlen,size_t mlen)
        +{
        +	unsigned int L = ctx->nonce.c[0]&7;	/* the L parameter */
        +
        +	if (nlen<(14-L)) return -1;		/* nonce is too short */
        +
        +	if (sizeof(mlen)==8 && L>=3) {
        +		ctx->nonce.c[8]  = (u8)(mlen>>(56%(sizeof(mlen)*8)));
        +		ctx->nonce.c[9]  = (u8)(mlen>>(48%(sizeof(mlen)*8)));
        +		ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8)));
        +		ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
        +	}
        +	else
        +		*(u32*)(&ctx->nonce.c[8]) = 0;
        +
        +	ctx->nonce.c[12] = (u8)(mlen>>24);
        +	ctx->nonce.c[13] = (u8)(mlen>>16);
        +	ctx->nonce.c[14] = (u8)(mlen>>8);
        +	ctx->nonce.c[15] = (u8)mlen;
        +
        +	ctx->nonce.c[0] &= ~0x40;	/* clear Adata flag */
        +	memcpy(&ctx->nonce.c[1],nonce,14-L);
        +
        +	return 0;
        +}
        +
        +/* Then you pass additional authentication data, this is optional */
        +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
        +	const unsigned char *aad,size_t alen)
        +{	unsigned int i;
        +	block128_f block = ctx->block;
        +
        +	if (alen==0) return;
        +
        +	ctx->nonce.c[0] |= 0x40;	/* set Adata flag */
        +	(*block)(ctx->nonce.c,ctx->cmac.c,ctx->key),
        +	ctx->blocks++;
        +
        +	if (alen<(0x10000-0x100)) {
        +		ctx->cmac.c[0] ^= (u8)(alen>>8);
        +		ctx->cmac.c[1] ^= (u8)alen;
        +		i=2;
        +	}
        +	else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) {
        +		ctx->cmac.c[0] ^= 0xFF;
        +		ctx->cmac.c[1] ^= 0xFF;
        +		ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8)));
        +		ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8)));
        +		ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8)));
        +		ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8)));
        +		ctx->cmac.c[6] ^= (u8)(alen>>24);
        +		ctx->cmac.c[7] ^= (u8)(alen>>16);
        +		ctx->cmac.c[8] ^= (u8)(alen>>8);
        +		ctx->cmac.c[9] ^= (u8)alen;
        +		i=10;
        +	}
        +	else {
        +		ctx->cmac.c[0] ^= 0xFF;
        +		ctx->cmac.c[1] ^= 0xFE;
        +		ctx->cmac.c[2] ^= (u8)(alen>>24);
        +		ctx->cmac.c[3] ^= (u8)(alen>>16);
        +		ctx->cmac.c[4] ^= (u8)(alen>>8);
        +		ctx->cmac.c[5] ^= (u8)alen;
        +		i=6;
        +	}
        +
        +	do {
        +		for(;i<16 && alen;++i,++aad,--alen)
        +			ctx->cmac.c[i] ^= *aad;
        +		(*block)(ctx->cmac.c,ctx->cmac.c,ctx->key),
        +		ctx->blocks++;
        +		i=0;
        +	} while (alen);
        +}
        +
        +/* Finally you encrypt or decrypt the message */
        +
        +/* counter part of nonce may not be larger than L*8 bits,
        + * L is not larger than 8, therefore 64-bit counter... */
        +static void ctr64_inc(unsigned char *counter) {
        +	unsigned int n=8;
        +	u8  c;
        +
        +	counter += 8;
        +	do {
        +		--n;
        +		c = counter[n];
        +		++c;
        +		counter[n] = c;
        +		if (c) return;
        +	} while (n);
        +}
        +
        +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out,
        +	size_t len)
        +{
        +	size_t		n;
        +	unsigned int	i,L;
        +	unsigned char	flags0	= ctx->nonce.c[0];
        +	block128_f	block	= ctx->block;
        +	void *		key	= ctx->key;
        +	union { u64 u[2]; u8 c[16]; } scratch;
        +
        +	if (!(flags0&0x40))
        +		(*block)(ctx->nonce.c,ctx->cmac.c,key),
        +		ctx->blocks++;
        +
        +	ctx->nonce.c[0] = L = flags0&7;
        +	for (n=0,i=15-L;i<15;++i) {
        +		n |= ctx->nonce.c[i];
        +		ctx->nonce.c[i]=0;
        +		n <<= 8;
        +	}
        +	n |= ctx->nonce.c[15];	/* reconstructed length */
        +	ctx->nonce.c[15]=1;
        +
        +	if (n!=len) return -1;	/* length mismatch */
        +
        +	ctx->blocks += ((len+15)>>3)|1;
        +	if (ctx->blocks > (U64(1)<<61))	return -2; /* too much data */
        +
        +	while (len>=16) {
        +#if defined(STRICT_ALIGNMENT)
        +		union { u64 u[2]; u8 c[16]; } temp;
        +
        +		memcpy (temp.c,inp,16);
        +		ctx->cmac.u[0] ^= temp.u[0];
        +		ctx->cmac.u[1] ^= temp.u[1];
        +#else
        +		ctx->cmac.u[0] ^= ((u64*)inp)[0];
        +		ctx->cmac.u[1] ^= ((u64*)inp)[1];
        +#endif
        +		(*block)(ctx->cmac.c,ctx->cmac.c,key);
        +		(*block)(ctx->nonce.c,scratch.c,key);
        +		ctr64_inc(ctx->nonce.c);
        +#if defined(STRICT_ALIGNMENT)
        +		temp.u[0] ^= scratch.u[0];
        +		temp.u[1] ^= scratch.u[1];
        +		memcpy(out,temp.c,16);
        +#else
        +		((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0];
        +		((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1];
        +#endif
        +		inp += 16;
        +		out += 16;
        +		len -= 16;
        +	}
        +
        +	if (len) {
        +		for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
        +		(*block)(ctx->cmac.c,ctx->cmac.c,key);
        +		(*block)(ctx->nonce.c,scratch.c,key);
        +		for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
        +	}
        +
        +	for (i=15-L;i<16;++i)
        +		ctx->nonce.c[i]=0;
        +
        +	(*block)(ctx->nonce.c,scratch.c,key);
        +	ctx->cmac.u[0] ^= scratch.u[0];
        +	ctx->cmac.u[1] ^= scratch.u[1];
        +
        +	ctx->nonce.c[0] = flags0;
        +
        +	return 0;
        +}
        +
        +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out,
        +	size_t len)
        +{
        +	size_t		n;
        +	unsigned int	i,L;
        +	unsigned char	flags0	= ctx->nonce.c[0];
        +	block128_f	block	= ctx->block;
        +	void *		key	= ctx->key;
        +	union { u64 u[2]; u8 c[16]; } scratch;
        +
        +	if (!(flags0&0x40))
        +		(*block)(ctx->nonce.c,ctx->cmac.c,key);
        +
        +	ctx->nonce.c[0] = L = flags0&7;
        +	for (n=0,i=15-L;i<15;++i) {
        +		n |= ctx->nonce.c[i];
        +		ctx->nonce.c[i]=0;
        +		n <<= 8;
        +	}
        +	n |= ctx->nonce.c[15];	/* reconstructed length */
        +	ctx->nonce.c[15]=1;
        +
        +	if (n!=len) return -1;
        +
        +	while (len>=16) {
        +#if defined(STRICT_ALIGNMENT)
        +		union { u64 u[2]; u8 c[16]; } temp;
        +#endif
        +		(*block)(ctx->nonce.c,scratch.c,key);
        +		ctr64_inc(ctx->nonce.c);
        +#if defined(STRICT_ALIGNMENT)
        +		memcpy (temp.c,inp,16);
        +		ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
        +		ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
        +		memcpy (out,scratch.c,16);
        +#else
        +		ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]);
        +		ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]);
        +#endif
        +		(*block)(ctx->cmac.c,ctx->cmac.c,key);
        +
        +		inp += 16;
        +		out += 16;
        +		len -= 16;
        +	}
        +
        +	if (len) {
        +		(*block)(ctx->nonce.c,scratch.c,key);
        +		for (i=0; i<len; ++i)
        +			ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
        +		(*block)(ctx->cmac.c,ctx->cmac.c,key);
        +	}
        +
        +	for (i=15-L;i<16;++i)
        +		ctx->nonce.c[i]=0;
        +
        +	(*block)(ctx->nonce.c,scratch.c,key);
        +	ctx->cmac.u[0] ^= scratch.u[0];
        +	ctx->cmac.u[1] ^= scratch.u[1];
        +
        +	ctx->nonce.c[0] = flags0;
        +
        +	return 0;
        +}
        +
        +static void ctr64_add (unsigned char *counter,size_t inc)
        +{	size_t n=8, val=0;
        +
        +	counter += 8;
        +	do {
        +		--n;
        +		val += counter[n] + (inc&0xff);
        +		counter[n] = (unsigned char)val;
        +		val >>= 8;	/* carry bit */
        +		inc >>= 8;
        +	} while(n && (inc || val));
        +}
        +
        +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out,
        +	size_t len,ccm128_f stream)
        +{
        +	size_t		n;
        +	unsigned int	i,L;
        +	unsigned char	flags0	= ctx->nonce.c[0];
        +	block128_f	block	= ctx->block;
        +	void *		key	= ctx->key;
        +	union { u64 u[2]; u8 c[16]; } scratch;
        +
        +	if (!(flags0&0x40))
        +		(*block)(ctx->nonce.c,ctx->cmac.c,key),
        +		ctx->blocks++;
        +
        +	ctx->nonce.c[0] = L = flags0&7;
        +	for (n=0,i=15-L;i<15;++i) {
        +		n |= ctx->nonce.c[i];
        +		ctx->nonce.c[i]=0;
        +		n <<= 8;
        +	}
        +	n |= ctx->nonce.c[15];	/* reconstructed length */
        +	ctx->nonce.c[15]=1;
        +
        +	if (n!=len) return -1;	/* length mismatch */
        +
        +	ctx->blocks += ((len+15)>>3)|1;
        +	if (ctx->blocks > (U64(1)<<61))	return -2; /* too much data */
        +
        +	if ((n=len/16)) {
        +		(*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
        +		n   *= 16;
        +		inp += n;
        +		out += n;
        +		len -= n;
        +		if (len) ctr64_add(ctx->nonce.c,n/16);
        +	}
        +
        +	if (len) {
        +		for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
        +		(*block)(ctx->cmac.c,ctx->cmac.c,key);
        +		(*block)(ctx->nonce.c,scratch.c,key);
        +		for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
        +	}
        +
        +	for (i=15-L;i<16;++i)
        +		ctx->nonce.c[i]=0;
        +
        +	(*block)(ctx->nonce.c,scratch.c,key);
        +	ctx->cmac.u[0] ^= scratch.u[0];
        +	ctx->cmac.u[1] ^= scratch.u[1];
        +
        +	ctx->nonce.c[0] = flags0;
        +
        +	return 0;
        +}
        +
        +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out,
        +	size_t len,ccm128_f stream)
        +{
        +	size_t		n;
        +	unsigned int	i,L;
        +	unsigned char	flags0	= ctx->nonce.c[0];
        +	block128_f	block	= ctx->block;
        +	void *		key	= ctx->key;
        +	union { u64 u[2]; u8 c[16]; } scratch;
        +
        +	if (!(flags0&0x40))
        +		(*block)(ctx->nonce.c,ctx->cmac.c,key);
        +
        +	ctx->nonce.c[0] = L = flags0&7;
        +	for (n=0,i=15-L;i<15;++i) {
        +		n |= ctx->nonce.c[i];
        +		ctx->nonce.c[i]=0;
        +		n <<= 8;
        +	}
        +	n |= ctx->nonce.c[15];	/* reconstructed length */
        +	ctx->nonce.c[15]=1;
        +
        +	if (n!=len) return -1;
        +
        +	if ((n=len/16)) {
        +		(*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
        +		n   *= 16;
        +		inp += n;
        +		out += n;
        +		len -= n;
        +		if (len) ctr64_add(ctx->nonce.c,n/16);
        +	}
        +
        +	if (len) {
        +		(*block)(ctx->nonce.c,scratch.c,key);
        +		for (i=0; i<len; ++i)
        +			ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
        +		(*block)(ctx->cmac.c,ctx->cmac.c,key);
        +	}
        +
        +	for (i=15-L;i<16;++i)
        +		ctx->nonce.c[i]=0;
        +
        +	(*block)(ctx->nonce.c,scratch.c,key);
        +	ctx->cmac.u[0] ^= scratch.u[0];
        +	ctx->cmac.u[1] ^= scratch.u[1];
        +
        +	ctx->nonce.c[0] = flags0;
        +
        +	return 0;
        +}
        +
        +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len)
        +{	unsigned int M = (ctx->nonce.c[0]>>3)&7;	/* the M parameter */
        +
        +	M *= 2; M += 2;
        +	if (len<M)	return 0;
        +	memcpy(tag,ctx->cmac.c,M);
        +	return M;
        +}
        diff --git a/vendor/openssl/openssl/crypto/modes/cfb128.c b/vendor/openssl/openssl/crypto/modes/cfb128.c
        new file mode 100644
        index 000000000..4e6f5d35e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/cfb128.c
        @@ -0,0 +1,242 @@
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +/* The input and output encrypted as though 128bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 128bit block we have used is contained in *num;
        + */
        +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], int *num,
        +			int enc, block128_f block)
        +{
        +    unsigned int n;
        +    size_t l = 0;
        +
        +    assert(in && out && key && ivec && num);
        +
        +    n = *num;
        +
        +    if (enc) {
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (16%sizeof(size_t) == 0) do {	/* always true actually */
        +		while (n && len) {
        +			*(out++) = ivec[n] ^= *(in++);
        +			--len;
        +			n = (n+1) % 16;
        +		}
        +#if defined(STRICT_ALIGNMENT)
        +		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
        +			break;
        +#endif
        +		while (len>=16) {
        +			(*block)(ivec, ivec, key);
        +			for (; n<16; n+=sizeof(size_t)) {
        +				*(size_t*)(out+n) =
        +				*(size_t*)(ivec+n) ^= *(size_t*)(in+n);
        +			}
        +			len -= 16;
        +			out += 16;
        +			in  += 16;
        +			n = 0;
        +		}
        +		if (len) {
        +			(*block)(ivec, ivec, key);
        +			while (len--) {
        +				out[n] = ivec[n] ^= in[n];
        +				++n;
        +			}
        +		}
        +		*num = n;
        +		return;
        +	} while (0);
        +	/* the rest would be commonly eliminated by x86* compiler */
        +#endif
        +	while (l<len) {
        +		if (n == 0) {
        +			(*block)(ivec, ivec, key);
        +		}
        +		out[l] = ivec[n] ^= in[l];
        +		++l;
        +		n = (n+1) % 16;
        +	}
        +	*num = n;
        +    } else {
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (16%sizeof(size_t) == 0) do {	/* always true actually */
        +		while (n && len) {
        +			unsigned char c;
        +			*(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
        +			--len;
        +			n = (n+1) % 16;
        + 		}
        +#if defined(STRICT_ALIGNMENT)
        +		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
        +			break;
        +#endif
        +		while (len>=16) {
        +			(*block)(ivec, ivec, key);
        +			for (; n<16; n+=sizeof(size_t)) {
        +				size_t t = *(size_t*)(in+n);
        +				*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
        +				*(size_t*)(ivec+n) = t;
        +			}
        +			len -= 16;
        +			out += 16;
        +			in  += 16;
        +			n = 0;
        +		}
        +		if (len) {
        +			(*block)(ivec, ivec, key);
        +			while (len--) {
        +				unsigned char c;
        +				out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
        +				++n;
        +			}
        + 		}
        +		*num = n;
        +		return;
        +	} while (0);
        +	/* the rest would be commonly eliminated by x86* compiler */
        +#endif
        +	while (l<len) {
        +		unsigned char c;
        +		if (n == 0) {
        +			(*block)(ivec, ivec, key);
        +		}
        +		out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
        +		++l;
        +		n = (n+1) % 16;
        +	}
        +	*num=n;
        +    }
        +}
        +
        +/* This expects a single block of size nbits for both in and out. Note that
        +   it corrupts any extra bits in the last byte of out */
        +static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
        +			    int nbits,const void *key,
        +			    unsigned char ivec[16],int enc,
        +			    block128_f block)
        +{
        +    int n,rem,num;
        +    unsigned char ovec[16*2 + 1];  /* +1 because we dererefence (but don't use) one byte off the end */
        +
        +    if (nbits<=0 || nbits>128) return;
        +
        +	/* fill in the first half of the new IV with the current IV */
        +	memcpy(ovec,ivec,16);
        +	/* construct the new IV */
        +	(*block)(ivec,ivec,key);
        +	num = (nbits+7)/8;
        +	if (enc)	/* encrypt the input */
        +	    for(n=0 ; n < num ; ++n)
        +		out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
        +	else		/* decrypt the input */
        +	    for(n=0 ; n < num ; ++n)
        +		out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
        +	/* shift ovec left... */
        +	rem = nbits%8;
        +	num = nbits/8;
        +	if(rem==0)
        +	    memcpy(ivec,ovec+num,16);
        +	else
        +	    for(n=0 ; n < 16 ; ++n)
        +		ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
        +
        +    /* it is not necessary to cleanse ovec, since the IV is not secret */
        +}
        +
        +/* N.B. This expects the input to be packed, MS bit first */
        +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
        +		 	size_t bits, const void *key,
        +			unsigned char ivec[16], int *num,
        +			int enc, block128_f block)
        +{
        +    size_t n;
        +    unsigned char c[1],d[1];
        +
        +    assert(in && out && key && ivec && num);
        +    assert(*num == 0);
        +
        +    for(n=0 ; n<bits ; ++n)
        +	{
        +	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
        +	cfbr_encrypt_block(c,d,1,key,ivec,enc,block);
        +	out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) |
        +		 ((d[0]&0x80) >> (unsigned int)(n%8));
        +	}
        +}
        +
        +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t length, const void *key,
        +			unsigned char ivec[16], int *num,
        +			int enc, block128_f block)
        +{
        +    size_t n;
        +
        +    assert(in && out && key && ivec && num);
        +    assert(*num == 0);
        +
        +    for(n=0 ; n<length ; ++n)
        +	cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block);
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/modes/ctr128.c b/vendor/openssl/openssl/crypto/modes/ctr128.c
        new file mode 100644
        index 000000000..ee642c586
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/ctr128.c
        @@ -0,0 +1,252 @@
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +/* NOTE: the IV/counter CTR mode is big-endian.  The code itself
        + * is endian-neutral. */
        +
        +/* increment counter (128-bit int) by 1 */
        +static void ctr128_inc(unsigned char *counter) {
        +	u32 n=16;
        +	u8  c;
        +
        +	do {
        +		--n;
        +		c = counter[n];
        +		++c;
        +		counter[n] = c;
        +		if (c) return;
        +	} while (n);
        +}
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +static void ctr128_inc_aligned(unsigned char *counter) {
        +	size_t *data,c,n;
        +	const union { long one; char little; } is_endian = {1};
        +
        +	if (is_endian.little) {
        +		ctr128_inc(counter);
        +		return;
        +	}
        +
        +	data = (size_t *)counter;
        +	n = 16/sizeof(size_t);
        +	do {
        +		--n;
        +		c = data[n];
        +		++c;
        +		data[n] = c;
        +		if (c) return;
        +	} while (n);
        +}
        +#endif
        +
        +/* The input encrypted as though 128bit counter mode is being
        + * used.  The extra state information to record how much of the
        + * 128bit block we have used is contained in *num, and the
        + * encrypted counter is kept in ecount_buf.  Both *num and
        + * ecount_buf must be initialised with zeros before the first
        + * call to CRYPTO_ctr128_encrypt().
        + *
        + * This algorithm assumes that the counter is in the x lower bits
        + * of the IV (ivec), and that the application has full control over
        + * overflow and the rest of the IV.  This implementation takes NO
        + * responsability for checking that the counter doesn't overflow
        + * into the rest of the IV when incremented.
        + */
        +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], unsigned char ecount_buf[16],
        +			unsigned int *num, block128_f block)
        +{
        +	unsigned int n;
        +	size_t l=0;
        +
        +	assert(in && out && key && ecount_buf && num);
        +	assert(*num < 16);
        +
        +	n = *num;
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (16%sizeof(size_t) == 0) do { /* always true actually */
        +		while (n && len) {
        +			*(out++) = *(in++) ^ ecount_buf[n];
        +			--len;
        +			n = (n+1) % 16;
        +		}
        +
        +#if defined(STRICT_ALIGNMENT)
        +		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
        +			break;
        +#endif
        +		while (len>=16) {
        +			(*block)(ivec, ecount_buf, key);
        +			ctr128_inc_aligned(ivec);
        +			for (; n<16; n+=sizeof(size_t))
        +				*(size_t *)(out+n) =
        +				*(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
        +			len -= 16;
        +			out += 16;
        +			in  += 16;
        +			n = 0;
        +		}
        +		if (len) {
        +			(*block)(ivec, ecount_buf, key);
        + 			ctr128_inc_aligned(ivec);
        +			while (len--) {
        +				out[n] = in[n] ^ ecount_buf[n];
        +				++n;
        +			}
        +		}
        +		*num = n;
        +		return;
        +	} while(0);
        +	/* the rest would be commonly eliminated by x86* compiler */
        +#endif
        +	while (l<len) {
        +		if (n==0) {
        +			(*block)(ivec, ecount_buf, key);
        + 			ctr128_inc(ivec);
        +		}
        +		out[l] = in[l] ^ ecount_buf[n];
        +		++l;
        +		n = (n+1) % 16;
        +	}
        +
        +	*num=n;
        +}
        +
        +/* increment upper 96 bits of 128-bit counter by 1 */
        +static void ctr96_inc(unsigned char *counter) {
        +	u32 n=12;
        +	u8  c;
        +
        +	do {
        +		--n;
        +		c = counter[n];
        +		++c;
        +		counter[n] = c;
        +		if (c) return;
        +	} while (n);
        +}
        +
        +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], unsigned char ecount_buf[16],
        +			unsigned int *num, ctr128_f func)
        +{
        +	unsigned int n,ctr32;
        +
        +	assert(in && out && key && ecount_buf && num);
        +	assert(*num < 16);
        +
        +	n = *num;
        +
        +	while (n && len) {
        +		*(out++) = *(in++) ^ ecount_buf[n];
        +		--len;
        +		n = (n+1) % 16;
        +	}
        +
        +	ctr32 = GETU32(ivec+12);
        +	while (len>=16) {
        +		size_t blocks = len/16;
        +		/*
        +		 * 1<<28 is just a not-so-small yet not-so-large number...
        +		 * Below condition is practically never met, but it has to
        +		 * be checked for code correctness.
        +		 */
        +		if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
        +			blocks = (1U<<28);
        +		/*
        +		 * As (*func) operates on 32-bit counter, caller
        +		 * has to handle overflow. 'if' below detects the
        +		 * overflow, which is then handled by limiting the
        +		 * amount of blocks to the exact overflow point...
        +		 */
        +		ctr32 += (u32)blocks;
        +		if (ctr32 < blocks) {
        +			blocks -= ctr32;
        +			ctr32   = 0;
        +		}
        +		(*func)(in,out,blocks,key,ivec);
        +		/* (*ctr) does not update ivec, caller does: */
        +		PUTU32(ivec+12,ctr32);
        +		/* ... overflow was detected, propogate carry. */
        +		if (ctr32 == 0)	ctr96_inc(ivec);
        +		blocks *= 16;
        +		len -= blocks;
        +		out += blocks;
        +		in  += blocks;
        +	}
        +	if (len) {
        +		memset(ecount_buf,0,16);
        +		(*func)(ecount_buf,ecount_buf,1,key,ivec);
        +		++ctr32;
        +		PUTU32(ivec+12,ctr32);
        +		if (ctr32 == 0)	ctr96_inc(ivec);
        +		while (len--) {
        +			out[n] = in[n] ^ ecount_buf[n];
        +			++n;
        +		}
        +	}
        +
        +	*num=n;
        +}
        diff --git a/vendor/openssl/openssl/crypto/modes/cts128.c b/vendor/openssl/openssl/crypto/modes/cts128.c
        new file mode 100644
        index 000000000..c0e1f3696
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/cts128.c
        @@ -0,0 +1,465 @@
        +/* ====================================================================
        + * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
        + *
        + * Rights for redistribution and usage in source and binary
        + * forms are granted according to the OpenSSL license.
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +/*
        + * Trouble with Ciphertext Stealing, CTS, mode is that there is no
        + * common official specification, but couple of cipher/application
        + * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
        + * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
        + * deviates from mentioned RFCs. Most notably it allows input to be
        + * of block length and it doesn't flip the order of the last two
        + * blocks. CTS is being discussed even in ECB context, but it's not
        + * adopted for any known application. This implementation provides
        + * two interfaces: one compliant with above mentioned RFCs and one
        + * compliant with the NIST proposal, both extending CBC mode.
        + */
        +
        +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block)
        +{	size_t residue, n;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len <= 16) return 0;
        +
        +	if ((residue=len%16) == 0) residue = 16;
        +
        +	len -= residue;
        +
        +	CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
        +
        +	in  += len;
        +	out += len;
        +
        +	for (n=0; n<residue; ++n)
        +		ivec[n] ^= in[n];
        +	(*block)(ivec,ivec,key);
        +	memcpy(out,out-16,residue);
        +	memcpy(out-16,ivec,16); 
        +
        +	return len+residue;
        +}
        +
        +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block)
        +{	size_t residue, n;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len < 16) return 0;
        +
        +	residue=len%16;
        +
        +	len -= residue;
        +
        +	CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
        +
        +	if (residue==0)	return len;
        +
        +	in  += len;
        +	out += len;
        +
        +	for (n=0; n<residue; ++n)
        +		ivec[n] ^= in[n];
        +	(*block)(ivec,ivec,key);
        +	memcpy(out-16+residue,ivec,16);
        +
        +	return len+residue;
        +}
        +
        +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc)
        +{	size_t residue;
        +	union { size_t align; unsigned char c[16]; } tmp;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len <= 16) return 0;
        +
        +	if ((residue=len%16) == 0) residue = 16;
        +
        +	len -= residue;
        +
        +	(*cbc)(in,out,len,key,ivec,1);
        +
        +	in  += len;
        +	out += len;
        +
        +#if defined(CBC_HANDLES_TRUNCATED_IO)
        +	memcpy(tmp.c,out-16,16);
        +	(*cbc)(in,out-16,residue,key,ivec,1);
        +	memcpy(out,tmp.c,residue);
        +#else
        +	{
        +	size_t n;
        +	for (n=0; n<16; n+=sizeof(size_t))
        +		*(size_t *)(tmp.c+n) = 0;
        +	memcpy(tmp.c,in,residue);
        +	}
        +	memcpy(out,out-16,residue);
        +	(*cbc)(tmp.c,out-16,16,key,ivec,1);
        +#endif
        +	return len+residue;
        +}
        +
        +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc)
        +{	size_t residue;
        +	union { size_t align; unsigned char c[16]; } tmp;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len < 16) return 0;
        +
        +	residue=len%16;
        +
        +	len -= residue;
        +
        +	(*cbc)(in,out,len,key,ivec,1);
        +
        +	if (residue==0) return len;
        +
        +	in  += len;
        +	out += len;
        +
        +#if defined(CBC_HANDLES_TRUNCATED_IO)
        +	(*cbc)(in,out-16+residue,residue,key,ivec,1);
        +#else
        +	{
        +	size_t n;
        +	for (n=0; n<16; n+=sizeof(size_t))
        +		*(size_t *)(tmp.c+n) = 0;
        +	memcpy(tmp.c,in,residue);
        +	}
        +	(*cbc)(tmp.c,out-16+residue,16,key,ivec,1);
        +#endif
        +	return len+residue;
        +}
        +
        +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block)
        +{	size_t residue, n;
        +	union { size_t align; unsigned char c[32]; } tmp;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len<=16) return 0;
        +
        +	if ((residue=len%16) == 0) residue = 16;
        +
        +	len -= 16+residue;
        +
        +	if (len) {
        +		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
        +		in  += len;
        +		out += len;
        +	}
        +
        +	(*block)(in,tmp.c+16,key);
        +
        +	for (n=0; n<16; n+=sizeof(size_t))
        +		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
        +	memcpy(tmp.c,in+16,residue);
        +	(*block)(tmp.c,tmp.c,key);
        +
        +	for(n=0; n<16; ++n) {
        +		unsigned char c = in[n];
        +		out[n] = tmp.c[n] ^ ivec[n];
        +		ivec[n] = c;
        +	}
        +	for(residue+=16; n<residue; ++n)
        +		out[n] = tmp.c[n] ^ in[n];
        +
        +	return 16+len+residue;
        +}
        +
        +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block)
        +{	size_t residue, n;
        +	union { size_t align; unsigned char c[32]; } tmp;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len<16) return 0;
        +
        +	residue=len%16;
        +
        +	if (residue==0) {
        +		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
        +		return len;
        +	}
        +
        +	len -= 16+residue;
        +
        +	if (len) {
        +		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
        +		in  += len;
        +		out += len;
        +	}
        +
        +	(*block)(in+residue,tmp.c+16,key);
        +
        +	for (n=0; n<16; n+=sizeof(size_t))
        +		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
        +	memcpy(tmp.c,in,residue);
        +	(*block)(tmp.c,tmp.c,key);
        +
        +	for(n=0; n<16; ++n) {
        +		unsigned char c = in[n];
        +		out[n] = tmp.c[n] ^ ivec[n];
        +		ivec[n] = in[n+residue];
        +		tmp.c[n] = c;
        +	}
        +	for(residue+=16; n<residue; ++n)
        +		out[n] = tmp.c[n] ^ tmp.c[n-16];
        +
        +	return 16+len+residue;
        +}
        +
        +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc)
        +{	size_t residue, n;
        +	union { size_t align; unsigned char c[32]; } tmp;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len<=16) return 0;
        +
        +	if ((residue=len%16) == 0) residue = 16;
        +
        +	len -= 16+residue;
        +
        +	if (len) {
        +		(*cbc)(in,out,len,key,ivec,0);
        +		in  += len;
        +		out += len;
        +	}
        +
        +	for (n=16; n<32; n+=sizeof(size_t))
        +		*(size_t *)(tmp.c+n) = 0;
        +	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
        +	(*cbc)(in,tmp.c,16,key,tmp.c+16,0);
        +
        +	memcpy(tmp.c,in+16,residue);
        +#if defined(CBC_HANDLES_TRUNCATED_IO)
        +	(*cbc)(tmp.c,out,16+residue,key,ivec,0);
        +#else
        +	(*cbc)(tmp.c,tmp.c,32,key,ivec,0);
        +	memcpy(out,tmp.c,16+residue);
        +#endif
        +	return 16+len+residue;
        +}
        +
        +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc)
        +{	size_t residue, n;
        +	union { size_t align; unsigned char c[32]; } tmp;
        +
        +	assert (in && out && key && ivec);
        +
        +	if (len<16) return 0;
        +
        +	residue=len%16;
        +
        +	if (residue==0) {
        +		(*cbc)(in,out,len,key,ivec,0);
        +		return len;
        +	}
        +
        +	len -= 16+residue;
        +
        +	if (len) {
        +		(*cbc)(in,out,len,key,ivec,0);
        +		in  += len;
        +		out += len;
        +	}
        +
        +	for (n=16; n<32; n+=sizeof(size_t))
        +		*(size_t *)(tmp.c+n) = 0;
        +	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
        +	(*cbc)(in+residue,tmp.c,16,key,tmp.c+16,0);
        +
        +	memcpy(tmp.c,in,residue);
        +#if defined(CBC_HANDLES_TRUNCATED_IO)
        +	(*cbc)(tmp.c,out,16+residue,key,ivec,0);
        +#else
        +	(*cbc)(tmp.c,tmp.c,32,key,ivec,0);
        +	memcpy(out,tmp.c,16+residue);
        +#endif
        +	return 16+len+residue;
        +}
        +
        +#if defined(SELFTEST)
        +#include <stdio.h>
        +#include <openssl/aes.h>
        +
        +/* test vectors from RFC 3962 */
        +static const unsigned char test_key[16] = "chicken teriyaki";
        +static const unsigned char test_input[64] =
        +		"I would like the" " General Gau's C"
        +		"hicken, please, " "and wonton soup.";
        +static const unsigned char test_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        +
        +static const unsigned char vector_17[17] =
        +{0xc6,0x35,0x35,0x68,0xf2,0xbf,0x8c,0xb4, 0xd8,0xa5,0x80,0x36,0x2d,0xa7,0xff,0x7f,
        + 0x97};
        +static const unsigned char vector_31[31] =
        +{0xfc,0x00,0x78,0x3e,0x0e,0xfd,0xb2,0xc1, 0xd4,0x45,0xd4,0xc8,0xef,0xf7,0xed,0x22,
        + 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5};
        +static const unsigned char vector_32[32] =
        +{0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
        + 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84};
        +static const unsigned char vector_47[47] =
        +{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
        + 0xb3,0xff,0xfd,0x94,0x0c,0x16,0xa1,0x8c, 0x1b,0x55,0x49,0xd2,0xf8,0x38,0x02,0x9e,
        + 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5};
        +static const unsigned char vector_48[48] =
        +{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
        + 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8,
        + 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8};
        +static const unsigned char vector_64[64] =
        +{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
        + 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
        + 0x48,0x07,0xef,0xe8,0x36,0xee,0x89,0xa5, 0x26,0x73,0x0d,0xbc,0x2f,0x7b,0xc8,0x40,
        + 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8};
        +
        +static AES_KEY encks, decks;
        +
        +void test_vector(const unsigned char *vector,size_t len)
        +{	unsigned char iv[sizeof(test_iv)];
        +	unsigned char cleartext[64],ciphertext[64];
        +	size_t tail;
        +
        +	printf("vector_%d\n",len); fflush(stdout);
        +
        +	if ((tail=len%16) == 0) tail = 16;
        +	tail += 16;
        +
        +	/* test block-based encryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_cts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
        +	if (memcmp(ciphertext,vector,len))
        +		fprintf(stderr,"output_%d mismatch\n",len), exit(1);
        +	if (memcmp(iv,vector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
        +
        +	/* test block-based decryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_cts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
        +	if (memcmp(cleartext,test_input,len))
        +		fprintf(stderr,"input_%d mismatch\n",len), exit(2);
        +	if (memcmp(iv,vector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
        +
        +	/* test streamed encryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_cts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
        +	if (memcmp(ciphertext,vector,len))
        +		fprintf(stderr,"output_%d mismatch\n",len), exit(3);
        +	if (memcmp(iv,vector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(3);
        +
        +	/* test streamed decryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_cts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
        +	if (memcmp(cleartext,test_input,len))
        +		fprintf(stderr,"input_%d mismatch\n",len), exit(4);
        +	if (memcmp(iv,vector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
        +}
        +
        +void test_nistvector(const unsigned char *vector,size_t len)
        +{	unsigned char iv[sizeof(test_iv)];
        +	unsigned char cleartext[64],ciphertext[64],nistvector[64];
        +	size_t tail;
        +
        +	printf("nistvector_%d\n",len); fflush(stdout);
        +
        +	if ((tail=len%16) == 0) tail = 16;
        +
        +	len -= 16 + tail;
        +	memcpy(nistvector,vector,len);
        +	/* flip two last blocks */
        +	memcpy(nistvector+len,vector+len+16,tail);
        +	memcpy(nistvector+len+tail,vector+len,16);
        +	len += 16 + tail;
        +	tail = 16;
        +
        +	/* test block-based encryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_nistcts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
        +	if (memcmp(ciphertext,nistvector,len))
        +		fprintf(stderr,"output_%d mismatch\n",len), exit(1);
        +	if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
        +
        +	/* test block-based decryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_nistcts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
        +	if (memcmp(cleartext,test_input,len))
        +		fprintf(stderr,"input_%d mismatch\n",len), exit(2);
        +	if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
        +
        +	/* test streamed encryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_nistcts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
        +	if (memcmp(ciphertext,nistvector,len))
        +		fprintf(stderr,"output_%d mismatch\n",len), exit(3);
        +	if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(3);
        +
        +	/* test streamed decryption */
        +	memcpy(iv,test_iv,sizeof(test_iv));
        +	CRYPTO_nistcts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
        +	if (memcmp(cleartext,test_input,len))
        +		fprintf(stderr,"input_%d mismatch\n",len), exit(4);
        +	if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
        +		fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
        +}
        +
        +int main()
        +{
        +	AES_set_encrypt_key(test_key,128,&encks);
        +	AES_set_decrypt_key(test_key,128,&decks);
        +
        +	test_vector(vector_17,sizeof(vector_17));
        +	test_vector(vector_31,sizeof(vector_31));
        +	test_vector(vector_32,sizeof(vector_32));
        +	test_vector(vector_47,sizeof(vector_47));
        +	test_vector(vector_48,sizeof(vector_48));
        +	test_vector(vector_64,sizeof(vector_64));
        +
        +	test_nistvector(vector_17,sizeof(vector_17));
        +	test_nistvector(vector_31,sizeof(vector_31));
        +	test_nistvector(vector_32,sizeof(vector_32));
        +	test_nistvector(vector_47,sizeof(vector_47));
        +	test_nistvector(vector_48,sizeof(vector_48));
        +	test_nistvector(vector_64,sizeof(vector_64));
        +
        +	return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/modes/gcm128.c b/vendor/openssl/openssl/crypto/modes/gcm128.c
        new file mode 100644
        index 000000000..0e6ff8b0a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/gcm128.c
        @@ -0,0 +1,1757 @@
        +/* ====================================================================
        + * Copyright (c) 2010 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.
        + * ====================================================================
        + */
        +
        +#define OPENSSL_FIPSAPI
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +#if defined(BSWAP4) && defined(STRICT_ALIGNMENT)
        +/* redefine, because alignment is ensured */
        +#undef	GETU32
        +#define	GETU32(p)	BSWAP4(*(const u32 *)(p))
        +#undef	PUTU32
        +#define	PUTU32(p,v)	*(u32 *)(p) = BSWAP4(v)
        +#endif
        +
        +#define	PACK(s)		((size_t)(s)<<(sizeof(size_t)*8-16))
        +#define REDUCE1BIT(V)	do { \
        +	if (sizeof(size_t)==8) { \
        +		u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
        +		V.lo  = (V.hi<<63)|(V.lo>>1); \
        +		V.hi  = (V.hi>>1 )^T; \
        +	} \
        +	else { \
        +		u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
        +		V.lo  = (V.hi<<63)|(V.lo>>1); \
        +		V.hi  = (V.hi>>1 )^((u64)T<<32); \
        +	} \
        +} while(0)
        +
        +/*
        + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
        + * never be set to 8. 8 is effectively reserved for testing purposes.
        + * TABLE_BITS>1 are lookup-table-driven implementations referred to as
        + * "Shoup's" in GCM specification. In other words OpenSSL does not cover
        + * whole spectrum of possible table driven implementations. Why? In
        + * non-"Shoup's" case memory access pattern is segmented in such manner,
        + * that it's trivial to see that cache timing information can reveal
        + * fair portion of intermediate hash value. Given that ciphertext is
        + * always available to attacker, it's possible for him to attempt to
        + * deduce secret parameter H and if successful, tamper with messages
        + * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
        + * not as trivial, but there is no reason to believe that it's resistant
        + * to cache-timing attack. And the thing about "8-bit" implementation is
        + * that it consumes 16 (sixteen) times more memory, 4KB per individual
        + * key + 1KB shared. Well, on pros side it should be twice as fast as
        + * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
        + * was observed to run ~75% faster, closer to 100% for commercial
        + * compilers... Yet "4-bit" procedure is preferred, because it's
        + * believed to provide better security-performance balance and adequate
        + * all-round performance. "All-round" refers to things like:
        + *
        + * - shorter setup time effectively improves overall timing for
        + *   handling short messages;
        + * - larger table allocation can become unbearable because of VM
        + *   subsystem penalties (for example on Windows large enough free
        + *   results in VM working set trimming, meaning that consequent
        + *   malloc would immediately incur working set expansion);
        + * - larger table has larger cache footprint, which can affect
        + *   performance of other code paths (not necessarily even from same
        + *   thread in Hyper-Threading world);
        + *
        + * Value of 1 is not appropriate for performance reasons.
        + */
        +#if	TABLE_BITS==8
        +
        +static void gcm_init_8bit(u128 Htable[256], u64 H[2])
        +{
        +	int  i, j;
        +	u128 V;
        +
        +	Htable[0].hi = 0;
        +	Htable[0].lo = 0;
        +	V.hi = H[0];
        +	V.lo = H[1];
        +
        +	for (Htable[128]=V, i=64; i>0; i>>=1) {
        +		REDUCE1BIT(V);
        +		Htable[i] = V;
        +	}
        +
        +	for (i=2; i<256; i<<=1) {
        +		u128 *Hi = Htable+i, H0 = *Hi;
        +		for (j=1; j<i; ++j) {
        +			Hi[j].hi = H0.hi^Htable[j].hi;
        +			Hi[j].lo = H0.lo^Htable[j].lo;
        +		}
        +	}
        +}
        +
        +static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256])
        +{
        +	u128 Z = { 0, 0};
        +	const u8 *xi = (const u8 *)Xi+15;
        +	size_t rem, n = *xi;
        +	const union { long one; char little; } is_endian = {1};
        +	static const size_t rem_8bit[256] = {
        +		PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
        +		PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
        +		PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
        +		PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
        +		PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
        +		PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
        +		PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
        +		PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
        +		PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
        +		PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
        +		PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
        +		PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
        +		PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
        +		PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
        +		PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
        +		PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
        +		PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
        +		PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
        +		PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
        +		PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
        +		PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
        +		PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
        +		PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
        +		PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
        +		PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
        +		PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
        +		PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
        +		PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
        +		PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
        +		PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
        +		PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
        +		PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
        +		PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
        +		PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
        +		PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
        +		PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
        +		PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
        +		PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
        +		PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
        +		PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
        +		PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
        +		PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
        +		PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
        +		PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
        +		PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
        +		PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
        +		PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
        +		PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
        +		PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
        +		PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
        +		PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
        +		PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
        +		PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
        +		PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
        +		PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
        +		PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
        +		PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
        +		PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
        +		PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
        +		PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
        +		PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
        +		PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
        +		PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
        +		PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) };
        +
        +	while (1) {
        +		Z.hi ^= Htable[n].hi;
        +		Z.lo ^= Htable[n].lo;
        +
        +		if ((u8 *)Xi==xi)	break;
        +
        +		n = *(--xi);
        +
        +		rem  = (size_t)Z.lo&0xff;
        +		Z.lo = (Z.hi<<56)|(Z.lo>>8);
        +		Z.hi = (Z.hi>>8);
        +		if (sizeof(size_t)==8)
        +			Z.hi ^= rem_8bit[rem];
        +		else
        +			Z.hi ^= (u64)rem_8bit[rem]<<32;
        +	}
        +
        +	if (is_endian.little) {
        +#ifdef BSWAP8
        +		Xi[0] = BSWAP8(Z.hi);
        +		Xi[1] = BSWAP8(Z.lo);
        +#else
        +		u8 *p = (u8 *)Xi;
        +		u32 v;
        +		v = (u32)(Z.hi>>32);	PUTU32(p,v);
        +		v = (u32)(Z.hi);	PUTU32(p+4,v);
        +		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
        +		v = (u32)(Z.lo);	PUTU32(p+12,v);
        +#endif
        +	}
        +	else {
        +		Xi[0] = Z.hi;
        +		Xi[1] = Z.lo;
        +	}
        +}
        +#define GCM_MUL(ctx,Xi)   gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
        +
        +#elif	TABLE_BITS==4
        +
        +static void gcm_init_4bit(u128 Htable[16], u64 H[2])
        +{
        +	u128 V;
        +#if defined(OPENSSL_SMALL_FOOTPRINT)
        +	int  i;
        +#endif
        +
        +	Htable[0].hi = 0;
        +	Htable[0].lo = 0;
        +	V.hi = H[0];
        +	V.lo = H[1];
        +
        +#if defined(OPENSSL_SMALL_FOOTPRINT)
        +	for (Htable[8]=V, i=4; i>0; i>>=1) {
        +		REDUCE1BIT(V);
        +		Htable[i] = V;
        +	}
        +
        +	for (i=2; i<16; i<<=1) {
        +		u128 *Hi = Htable+i;
        +		int   j;
        +		for (V=*Hi, j=1; j<i; ++j) {
        +			Hi[j].hi = V.hi^Htable[j].hi;
        +			Hi[j].lo = V.lo^Htable[j].lo;
        +		}
        +	}
        +#else
        +	Htable[8] = V;
        +	REDUCE1BIT(V);
        +	Htable[4] = V;
        +	REDUCE1BIT(V);
        +	Htable[2] = V;
        +	REDUCE1BIT(V);
        +	Htable[1] = V;
        +	Htable[3].hi  = V.hi^Htable[2].hi, Htable[3].lo  = V.lo^Htable[2].lo;
        +	V=Htable[4];
        +	Htable[5].hi  = V.hi^Htable[1].hi, Htable[5].lo  = V.lo^Htable[1].lo;
        +	Htable[6].hi  = V.hi^Htable[2].hi, Htable[6].lo  = V.lo^Htable[2].lo;
        +	Htable[7].hi  = V.hi^Htable[3].hi, Htable[7].lo  = V.lo^Htable[3].lo;
        +	V=Htable[8];
        +	Htable[9].hi  = V.hi^Htable[1].hi, Htable[9].lo  = V.lo^Htable[1].lo;
        +	Htable[10].hi = V.hi^Htable[2].hi, Htable[10].lo = V.lo^Htable[2].lo;
        +	Htable[11].hi = V.hi^Htable[3].hi, Htable[11].lo = V.lo^Htable[3].lo;
        +	Htable[12].hi = V.hi^Htable[4].hi, Htable[12].lo = V.lo^Htable[4].lo;
        +	Htable[13].hi = V.hi^Htable[5].hi, Htable[13].lo = V.lo^Htable[5].lo;
        +	Htable[14].hi = V.hi^Htable[6].hi, Htable[14].lo = V.lo^Htable[6].lo;
        +	Htable[15].hi = V.hi^Htable[7].hi, Htable[15].lo = V.lo^Htable[7].lo;
        +#endif
        +#if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
        +	/*
        +	 * ARM assembler expects specific dword order in Htable.
        +	 */
        +	{
        +	int j;
        +	const union { long one; char little; } is_endian = {1};
        +
        +	if (is_endian.little)
        +		for (j=0;j<16;++j) {
        +			V = Htable[j];
        +			Htable[j].hi = V.lo;
        +			Htable[j].lo = V.hi;
        +		}
        +	else
        +		for (j=0;j<16;++j) {
        +			V = Htable[j];
        +			Htable[j].hi = V.lo<<32|V.lo>>32;
        +			Htable[j].lo = V.hi<<32|V.hi>>32;
        +		}
        +	}
        +#endif
        +}
        +
        +#ifndef GHASH_ASM
        +static const size_t rem_4bit[16] = {
        +	PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
        +	PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
        +	PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
        +	PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) };
        +
        +static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
        +{
        +	u128 Z;
        +	int cnt = 15;
        +	size_t rem, nlo, nhi;
        +	const union { long one; char little; } is_endian = {1};
        +
        +	nlo  = ((const u8 *)Xi)[15];
        +	nhi  = nlo>>4;
        +	nlo &= 0xf;
        +
        +	Z.hi = Htable[nlo].hi;
        +	Z.lo = Htable[nlo].lo;
        +
        +	while (1) {
        +		rem  = (size_t)Z.lo&0xf;
        +		Z.lo = (Z.hi<<60)|(Z.lo>>4);
        +		Z.hi = (Z.hi>>4);
        +		if (sizeof(size_t)==8)
        +			Z.hi ^= rem_4bit[rem];
        +		else
        +			Z.hi ^= (u64)rem_4bit[rem]<<32;
        +
        +		Z.hi ^= Htable[nhi].hi;
        +		Z.lo ^= Htable[nhi].lo;
        +
        +		if (--cnt<0)		break;
        +
        +		nlo  = ((const u8 *)Xi)[cnt];
        +		nhi  = nlo>>4;
        +		nlo &= 0xf;
        +
        +		rem  = (size_t)Z.lo&0xf;
        +		Z.lo = (Z.hi<<60)|(Z.lo>>4);
        +		Z.hi = (Z.hi>>4);
        +		if (sizeof(size_t)==8)
        +			Z.hi ^= rem_4bit[rem];
        +		else
        +			Z.hi ^= (u64)rem_4bit[rem]<<32;
        +
        +		Z.hi ^= Htable[nlo].hi;
        +		Z.lo ^= Htable[nlo].lo;
        +	}
        +
        +	if (is_endian.little) {
        +#ifdef BSWAP8
        +		Xi[0] = BSWAP8(Z.hi);
        +		Xi[1] = BSWAP8(Z.lo);
        +#else
        +		u8 *p = (u8 *)Xi;
        +		u32 v;
        +		v = (u32)(Z.hi>>32);	PUTU32(p,v);
        +		v = (u32)(Z.hi);	PUTU32(p+4,v);
        +		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
        +		v = (u32)(Z.lo);	PUTU32(p+12,v);
        +#endif
        +	}
        +	else {
        +		Xi[0] = Z.hi;
        +		Xi[1] = Z.lo;
        +	}
        +}
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +/*
        + * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
        + * details... Compiler-generated code doesn't seem to give any
        + * performance improvement, at least not on x86[_64]. It's here
        + * mostly as reference and a placeholder for possible future
        + * non-trivial optimization[s]...
        + */
        +static void gcm_ghash_4bit(u64 Xi[2],const u128 Htable[16],
        +				const u8 *inp,size_t len)
        +{
        +    u128 Z;
        +    int cnt;
        +    size_t rem, nlo, nhi;
        +    const union { long one; char little; } is_endian = {1};
        +
        +#if 1
        +    do {
        +	cnt  = 15;
        +	nlo  = ((const u8 *)Xi)[15];
        +	nlo ^= inp[15];
        +	nhi  = nlo>>4;
        +	nlo &= 0xf;
        +
        +	Z.hi = Htable[nlo].hi;
        +	Z.lo = Htable[nlo].lo;
        +
        +	while (1) {
        +		rem  = (size_t)Z.lo&0xf;
        +		Z.lo = (Z.hi<<60)|(Z.lo>>4);
        +		Z.hi = (Z.hi>>4);
        +		if (sizeof(size_t)==8)
        +			Z.hi ^= rem_4bit[rem];
        +		else
        +			Z.hi ^= (u64)rem_4bit[rem]<<32;
        +
        +		Z.hi ^= Htable[nhi].hi;
        +		Z.lo ^= Htable[nhi].lo;
        +
        +		if (--cnt<0)		break;
        +
        +		nlo  = ((const u8 *)Xi)[cnt];
        +		nlo ^= inp[cnt];
        +		nhi  = nlo>>4;
        +		nlo &= 0xf;
        +
        +		rem  = (size_t)Z.lo&0xf;
        +		Z.lo = (Z.hi<<60)|(Z.lo>>4);
        +		Z.hi = (Z.hi>>4);
        +		if (sizeof(size_t)==8)
        +			Z.hi ^= rem_4bit[rem];
        +		else
        +			Z.hi ^= (u64)rem_4bit[rem]<<32;
        +
        +		Z.hi ^= Htable[nlo].hi;
        +		Z.lo ^= Htable[nlo].lo;
        +	}
        +#else
        +    /*
        +     * Extra 256+16 bytes per-key plus 512 bytes shared tables
        +     * [should] give ~50% improvement... One could have PACK()-ed
        +     * the rem_8bit even here, but the priority is to minimize
        +     * cache footprint...
        +     */ 
        +    u128 Hshr4[16];	/* Htable shifted right by 4 bits */
        +    u8   Hshl4[16];	/* Htable shifted left  by 4 bits */
        +    static const unsigned short rem_8bit[256] = {
        +	0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
        +	0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
        +	0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
        +	0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
        +	0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
        +	0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
        +	0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
        +	0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
        +	0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
        +	0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
        +	0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
        +	0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
        +	0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
        +	0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
        +	0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
        +	0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
        +	0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
        +	0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
        +	0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
        +	0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
        +	0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
        +	0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
        +	0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
        +	0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
        +	0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
        +	0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
        +	0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
        +	0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
        +	0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
        +	0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
        +	0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
        +	0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE };
        +    /*
        +     * This pre-processing phase slows down procedure by approximately
        +     * same time as it makes each loop spin faster. In other words
        +     * single block performance is approximately same as straightforward
        +     * "4-bit" implementation, and then it goes only faster...
        +     */
        +    for (cnt=0; cnt<16; ++cnt) {
        +	Z.hi = Htable[cnt].hi;
        +	Z.lo = Htable[cnt].lo;
        +	Hshr4[cnt].lo = (Z.hi<<60)|(Z.lo>>4);
        +	Hshr4[cnt].hi = (Z.hi>>4);
        +	Hshl4[cnt]    = (u8)(Z.lo<<4);
        +    }
        +
        +    do {
        +	for (Z.lo=0, Z.hi=0, cnt=15; cnt; --cnt) {
        +		nlo  = ((const u8 *)Xi)[cnt];
        +		nlo ^= inp[cnt];
        +		nhi  = nlo>>4;
        +		nlo &= 0xf;
        +
        +		Z.hi ^= Htable[nlo].hi;
        +		Z.lo ^= Htable[nlo].lo;
        +
        +		rem = (size_t)Z.lo&0xff;
        +
        +		Z.lo = (Z.hi<<56)|(Z.lo>>8);
        +		Z.hi = (Z.hi>>8);
        +
        +		Z.hi ^= Hshr4[nhi].hi;
        +		Z.lo ^= Hshr4[nhi].lo;
        +		Z.hi ^= (u64)rem_8bit[rem^Hshl4[nhi]]<<48;
        +	}
        +
        +	nlo  = ((const u8 *)Xi)[0];
        +	nlo ^= inp[0];
        +	nhi  = nlo>>4;
        +	nlo &= 0xf;
        +
        +	Z.hi ^= Htable[nlo].hi;
        +	Z.lo ^= Htable[nlo].lo;
        +
        +	rem = (size_t)Z.lo&0xf;
        +
        +	Z.lo = (Z.hi<<60)|(Z.lo>>4);
        +	Z.hi = (Z.hi>>4);
        +
        +	Z.hi ^= Htable[nhi].hi;
        +	Z.lo ^= Htable[nhi].lo;
        +	Z.hi ^= ((u64)rem_8bit[rem<<4])<<48;
        +#endif
        +
        +	if (is_endian.little) {
        +#ifdef BSWAP8
        +		Xi[0] = BSWAP8(Z.hi);
        +		Xi[1] = BSWAP8(Z.lo);
        +#else
        +		u8 *p = (u8 *)Xi;
        +		u32 v;
        +		v = (u32)(Z.hi>>32);	PUTU32(p,v);
        +		v = (u32)(Z.hi);	PUTU32(p+4,v);
        +		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
        +		v = (u32)(Z.lo);	PUTU32(p+12,v);
        +#endif
        +	}
        +	else {
        +		Xi[0] = Z.hi;
        +		Xi[1] = Z.lo;
        +	}
        +    } while (inp+=16, len-=16);
        +}
        +#endif
        +#else
        +void gcm_gmult_4bit(u64 Xi[2],const u128 Htable[16]);
        +void gcm_ghash_4bit(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
        +#endif
        +
        +#define GCM_MUL(ctx,Xi)   gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
        +#if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
        +#define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
        +/* GHASH_CHUNK is "stride parameter" missioned to mitigate cache
        + * trashing effect. In other words idea is to hash data while it's
        + * still in L1 cache after encryption pass... */
        +#define GHASH_CHUNK       (3*1024)
        +#endif
        +
        +#else	/* TABLE_BITS */
        +
        +static void gcm_gmult_1bit(u64 Xi[2],const u64 H[2])
        +{
        +	u128 V,Z = { 0,0 };
        +	long X;
        +	int  i,j;
        +	const long *xi = (const long *)Xi;
        +	const union { long one; char little; } is_endian = {1};
        +
        +	V.hi = H[0];	/* H is in host byte order, no byte swapping */
        +	V.lo = H[1];
        +
        +	for (j=0; j<16/sizeof(long); ++j) {
        +		if (is_endian.little) {
        +			if (sizeof(long)==8) {
        +#ifdef BSWAP8
        +				X = (long)(BSWAP8(xi[j]));
        +#else
        +				const u8 *p = (const u8 *)(xi+j);
        +				X = (long)((u64)GETU32(p)<<32|GETU32(p+4));
        +#endif
        +			}
        +			else {
        +				const u8 *p = (const u8 *)(xi+j);
        +				X = (long)GETU32(p);
        +			}
        +		}
        +		else
        +			X = xi[j];
        +
        +		for (i=0; i<8*sizeof(long); ++i, X<<=1) {
        +			u64 M = (u64)(X>>(8*sizeof(long)-1));
        +			Z.hi ^= V.hi&M;
        +			Z.lo ^= V.lo&M;
        +
        +			REDUCE1BIT(V);
        +		}
        +	}
        +
        +	if (is_endian.little) {
        +#ifdef BSWAP8
        +		Xi[0] = BSWAP8(Z.hi);
        +		Xi[1] = BSWAP8(Z.lo);
        +#else
        +		u8 *p = (u8 *)Xi;
        +		u32 v;
        +		v = (u32)(Z.hi>>32);	PUTU32(p,v);
        +		v = (u32)(Z.hi);	PUTU32(p+4,v);
        +		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
        +		v = (u32)(Z.lo);	PUTU32(p+12,v);
        +#endif
        +	}
        +	else {
        +		Xi[0] = Z.hi;
        +		Xi[1] = Z.lo;
        +	}
        +}
        +#define GCM_MUL(ctx,Xi)	  gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
        +
        +#endif
        +
        +#if	TABLE_BITS==4 && defined(GHASH_ASM)
        +# if	!defined(I386_ONLY) && \
        +	(defined(__i386)	|| defined(__i386__)	|| \
        +	 defined(__x86_64)	|| defined(__x86_64__)	|| \
        +	 defined(_M_IX86)	|| defined(_M_AMD64)	|| defined(_M_X64))
        +#  define GHASH_ASM_X86_OR_64
        +#  define GCM_FUNCREF_4BIT
        +extern unsigned int OPENSSL_ia32cap_P[2];
        +
        +void gcm_init_clmul(u128 Htable[16],const u64 Xi[2]);
        +void gcm_gmult_clmul(u64 Xi[2],const u128 Htable[16]);
        +void gcm_ghash_clmul(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
        +
        +#  if	defined(__i386) || defined(__i386__) || defined(_M_IX86)
        +#   define GHASH_ASM_X86
        +void gcm_gmult_4bit_mmx(u64 Xi[2],const u128 Htable[16]);
        +void gcm_ghash_4bit_mmx(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
        +
        +void gcm_gmult_4bit_x86(u64 Xi[2],const u128 Htable[16]);
        +void gcm_ghash_4bit_x86(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
        +#  endif
        +# elif defined(__arm__) || defined(__arm)
        +#  include "arm_arch.h"
        +#  if __ARM_ARCH__>=7
        +#   define GHASH_ASM_ARM
        +#   define GCM_FUNCREF_4BIT
        +void gcm_gmult_neon(u64 Xi[2],const u128 Htable[16]);
        +void gcm_ghash_neon(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
        +#  endif
        +# endif
        +#endif
        +
        +#ifdef GCM_FUNCREF_4BIT
        +# undef  GCM_MUL
        +# define GCM_MUL(ctx,Xi)	(*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
        +# ifdef GHASH
        +#  undef  GHASH
        +#  define GHASH(ctx,in,len)	(*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
        +# endif
        +#endif
        +
        +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +
        +	memset(ctx,0,sizeof(*ctx));
        +	ctx->block = block;
        +	ctx->key   = key;
        +
        +	(*block)(ctx->H.c,ctx->H.c,key);
        +
        +	if (is_endian.little) {
        +		/* H is stored in host byte order */
        +#ifdef BSWAP8
        +		ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
        +		ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
        +#else
        +		u8 *p = ctx->H.c;
        +		u64 hi,lo;
        +		hi = (u64)GETU32(p)  <<32|GETU32(p+4);
        +		lo = (u64)GETU32(p+8)<<32|GETU32(p+12);
        +		ctx->H.u[0] = hi;
        +		ctx->H.u[1] = lo;
        +#endif
        +	}
        +
        +#if	TABLE_BITS==8
        +	gcm_init_8bit(ctx->Htable,ctx->H.u);
        +#elif	TABLE_BITS==4
        +# if	defined(GHASH_ASM_X86_OR_64)
        +#  if	!defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
        +	if (OPENSSL_ia32cap_P[0]&(1<<24) &&	/* check FXSR bit */
        +	    OPENSSL_ia32cap_P[1]&(1<<1) ) {	/* check PCLMULQDQ bit */
        +		gcm_init_clmul(ctx->Htable,ctx->H.u);
        +		ctx->gmult = gcm_gmult_clmul;
        +		ctx->ghash = gcm_ghash_clmul;
        +		return;
        +	}
        +#  endif
        +	gcm_init_4bit(ctx->Htable,ctx->H.u);
        +#  if	defined(GHASH_ASM_X86)			/* x86 only */
        +#   if	defined(OPENSSL_IA32_SSE2)
        +	if (OPENSSL_ia32cap_P[0]&(1<<25)) {	/* check SSE bit */
        +#   else
        +	if (OPENSSL_ia32cap_P[0]&(1<<23)) {	/* check MMX bit */
        +#   endif
        +		ctx->gmult = gcm_gmult_4bit_mmx;
        +		ctx->ghash = gcm_ghash_4bit_mmx;
        +	} else {
        +		ctx->gmult = gcm_gmult_4bit_x86;
        +		ctx->ghash = gcm_ghash_4bit_x86;
        +	}
        +#  else
        +	ctx->gmult = gcm_gmult_4bit;
        +	ctx->ghash = gcm_ghash_4bit;
        +#  endif
        +# elif	defined(GHASH_ASM_ARM)
        +	if (OPENSSL_armcap_P & ARMV7_NEON) {
        +		ctx->gmult = gcm_gmult_neon;
        +		ctx->ghash = gcm_ghash_neon;
        +	} else {
        +		gcm_init_4bit(ctx->Htable,ctx->H.u);
        +		ctx->gmult = gcm_gmult_4bit;
        +		ctx->ghash = gcm_ghash_4bit;
        +	}
        +# else
        +	gcm_init_4bit(ctx->Htable,ctx->H.u);
        +# endif
        +#endif
        +}
        +
        +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx,const unsigned char *iv,size_t len)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	unsigned int ctr;
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +#endif
        +
        +	ctx->Yi.u[0]  = 0;
        +	ctx->Yi.u[1]  = 0;
        +	ctx->Xi.u[0]  = 0;
        +	ctx->Xi.u[1]  = 0;
        +	ctx->len.u[0] = 0;	/* AAD length */
        +	ctx->len.u[1] = 0;	/* message length */
        +	ctx->ares = 0;
        +	ctx->mres = 0;
        +
        +	if (len==12) {
        +		memcpy(ctx->Yi.c,iv,12);
        +		ctx->Yi.c[15]=1;
        +		ctr=1;
        +	}
        +	else {
        +		size_t i;
        +		u64 len0 = len;
        +
        +		while (len>=16) {
        +			for (i=0; i<16; ++i) ctx->Yi.c[i] ^= iv[i];
        +			GCM_MUL(ctx,Yi);
        +			iv += 16;
        +			len -= 16;
        +		}
        +		if (len) {
        +			for (i=0; i<len; ++i) ctx->Yi.c[i] ^= iv[i];
        +			GCM_MUL(ctx,Yi);
        +		}
        +		len0 <<= 3;
        +		if (is_endian.little) {
        +#ifdef BSWAP8
        +			ctx->Yi.u[1]  ^= BSWAP8(len0);
        +#else
        +			ctx->Yi.c[8]  ^= (u8)(len0>>56);
        +			ctx->Yi.c[9]  ^= (u8)(len0>>48);
        +			ctx->Yi.c[10] ^= (u8)(len0>>40);
        +			ctx->Yi.c[11] ^= (u8)(len0>>32);
        +			ctx->Yi.c[12] ^= (u8)(len0>>24);
        +			ctx->Yi.c[13] ^= (u8)(len0>>16);
        +			ctx->Yi.c[14] ^= (u8)(len0>>8);
        +			ctx->Yi.c[15] ^= (u8)(len0);
        +#endif
        +		}
        +		else
        +			ctx->Yi.u[1]  ^= len0;
        +
        +		GCM_MUL(ctx,Yi);
        +
        +		if (is_endian.little)
        +			ctr = GETU32(ctx->Yi.c+12);
        +		else
        +			ctr = ctx->Yi.d[3];
        +	}
        +
        +	(*ctx->block)(ctx->Yi.c,ctx->EK0.c,ctx->key);
        +	++ctr;
        +	if (is_endian.little)
        +		PUTU32(ctx->Yi.c+12,ctr);
        +	else
        +		ctx->Yi.d[3] = ctr;
        +}
        +
        +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx,const unsigned char *aad,size_t len)
        +{
        +	size_t i;
        +	unsigned int n;
        +	u64 alen = ctx->len.u[0];
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +# ifdef GHASH
        +	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
        +				const u8 *inp,size_t len)	= ctx->ghash;
        +# endif
        +#endif
        +
        +	if (ctx->len.u[1]) return -2;
        +
        +	alen += len;
        +	if (alen>(U64(1)<<61) || (sizeof(len)==8 && alen<len))
        +		return -1;
        +	ctx->len.u[0] = alen;
        +
        +	n = ctx->ares;
        +	if (n) {
        +		while (n && len) {
        +			ctx->Xi.c[n] ^= *(aad++);
        +			--len;
        +			n = (n+1)%16;
        +		}
        +		if (n==0) GCM_MUL(ctx,Xi);
        +		else {
        +			ctx->ares = n;
        +			return 0;
        +		}
        +	}
        +
        +#ifdef GHASH
        +	if ((i = (len&(size_t)-16))) {
        +		GHASH(ctx,aad,i);
        +		aad += i;
        +		len -= i;
        +	}
        +#else
        +	while (len>=16) {
        +		for (i=0; i<16; ++i) ctx->Xi.c[i] ^= aad[i];
        +		GCM_MUL(ctx,Xi);
        +		aad += 16;
        +		len -= 16;
        +	}
        +#endif
        +	if (len) {
        +		n = (unsigned int)len;
        +		for (i=0; i<len; ++i) ctx->Xi.c[i] ^= aad[i];
        +	}
        +
        +	ctx->ares = n;
        +	return 0;
        +}
        +
        +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
        +		const unsigned char *in, unsigned char *out,
        +		size_t len)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	unsigned int n, ctr;
        +	size_t i;
        +	u64        mlen  = ctx->len.u[1];
        +	block128_f block = ctx->block;
        +	void      *key   = ctx->key;
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +# ifdef GHASH
        +	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
        +				const u8 *inp,size_t len)	= ctx->ghash;
        +# endif
        +#endif
        +
        +#if 0
        +	n = (unsigned int)mlen%16; /* alternative to ctx->mres */
        +#endif
        +	mlen += len;
        +	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
        +		return -1;
        +	ctx->len.u[1] = mlen;
        +
        +	if (ctx->ares) {
        +		/* First call to encrypt finalizes GHASH(AAD) */
        +		GCM_MUL(ctx,Xi);
        +		ctx->ares = 0;
        +	}
        +
        +	if (is_endian.little)
        +		ctr = GETU32(ctx->Yi.c+12);
        +	else
        +		ctr = ctx->Yi.d[3];
        +
        +	n = ctx->mres;
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (16%sizeof(size_t) == 0) do {	/* always true actually */
        +		if (n) {
        +			while (n && len) {
        +				ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
        +				--len;
        +				n = (n+1)%16;
        +			}
        +			if (n==0) GCM_MUL(ctx,Xi);
        +			else {
        +				ctx->mres = n;
        +				return 0;
        +			}
        +		}
        +#if defined(STRICT_ALIGNMENT)
        +		if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
        +			break;
        +#endif
        +#if defined(GHASH) && defined(GHASH_CHUNK)
        +		while (len>=GHASH_CHUNK) {
        +		    size_t j=GHASH_CHUNK;
        +
        +		    while (j) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			for (i=0; i<16; i+=sizeof(size_t))
        +				*(size_t *)(out+i) =
        +				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
        +			out += 16;
        +			in  += 16;
        +			j   -= 16;
        +		    }
        +		    GHASH(ctx,out-GHASH_CHUNK,GHASH_CHUNK);
        +		    len -= GHASH_CHUNK;
        +		}
        +		if ((i = (len&(size_t)-16))) {
        +		    size_t j=i;
        +
        +		    while (len>=16) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			for (i=0; i<16; i+=sizeof(size_t))
        +				*(size_t *)(out+i) =
        +				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
        +			out += 16;
        +			in  += 16;
        +			len -= 16;
        +		    }
        +		    GHASH(ctx,out-j,j);
        +		}
        +#else
        +		while (len>=16) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			for (i=0; i<16; i+=sizeof(size_t))
        +				*(size_t *)(ctx->Xi.c+i) ^=
        +				*(size_t *)(out+i) =
        +				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
        +			GCM_MUL(ctx,Xi);
        +			out += 16;
        +			in  += 16;
        +			len -= 16;
        +		}
        +#endif
        +		if (len) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			while (len--) {
        +				ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
        +				++n;
        +			}
        +		}
        +
        +		ctx->mres = n;
        +		return 0;
        +	} while(0);
        +#endif
        +	for (i=0;i<len;++i) {
        +		if (n==0) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +		}
        +		ctx->Xi.c[n] ^= out[i] = in[i]^ctx->EKi.c[n];
        +		n = (n+1)%16;
        +		if (n==0)
        +			GCM_MUL(ctx,Xi);
        +	}
        +
        +	ctx->mres = n;
        +	return 0;
        +}
        +
        +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
        +		const unsigned char *in, unsigned char *out,
        +		size_t len)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	unsigned int n, ctr;
        +	size_t i;
        +	u64        mlen  = ctx->len.u[1];
        +	block128_f block = ctx->block;
        +	void      *key   = ctx->key;
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +# ifdef GHASH
        +	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
        +				const u8 *inp,size_t len)	= ctx->ghash;
        +# endif
        +#endif
        +
        +	mlen += len;
        +	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
        +		return -1;
        +	ctx->len.u[1] = mlen;
        +
        +	if (ctx->ares) {
        +		/* First call to decrypt finalizes GHASH(AAD) */
        +		GCM_MUL(ctx,Xi);
        +		ctx->ares = 0;
        +	}
        +
        +	if (is_endian.little)
        +		ctr = GETU32(ctx->Yi.c+12);
        +	else
        +		ctr = ctx->Yi.d[3];
        +
        +	n = ctx->mres;
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (16%sizeof(size_t) == 0) do {	/* always true actually */
        +		if (n) {
        +			while (n && len) {
        +				u8 c = *(in++);
        +				*(out++) = c^ctx->EKi.c[n];
        +				ctx->Xi.c[n] ^= c;
        +				--len;
        +				n = (n+1)%16;
        +			}
        +			if (n==0) GCM_MUL (ctx,Xi);
        +			else {
        +				ctx->mres = n;
        +				return 0;
        +			}
        +		}
        +#if defined(STRICT_ALIGNMENT)
        +		if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
        +			break;
        +#endif
        +#if defined(GHASH) && defined(GHASH_CHUNK)
        +		while (len>=GHASH_CHUNK) {
        +		    size_t j=GHASH_CHUNK;
        +
        +		    GHASH(ctx,in,GHASH_CHUNK);
        +		    while (j) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			for (i=0; i<16; i+=sizeof(size_t))
        +				*(size_t *)(out+i) =
        +				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
        +			out += 16;
        +			in  += 16;
        +			j   -= 16;
        +		    }
        +		    len -= GHASH_CHUNK;
        +		}
        +		if ((i = (len&(size_t)-16))) {
        +		    GHASH(ctx,in,i);
        +		    while (len>=16) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			for (i=0; i<16; i+=sizeof(size_t))
        +				*(size_t *)(out+i) =
        +				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
        +			out += 16;
        +			in  += 16;
        +			len -= 16;
        +		    }
        +		}
        +#else
        +		while (len>=16) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			for (i=0; i<16; i+=sizeof(size_t)) {
        +				size_t c = *(size_t *)(in+i);
        +				*(size_t *)(out+i) = c^*(size_t *)(ctx->EKi.c+i);
        +				*(size_t *)(ctx->Xi.c+i) ^= c;
        +			}
        +			GCM_MUL(ctx,Xi);
        +			out += 16;
        +			in  += 16;
        +			len -= 16;
        +		}
        +#endif
        +		if (len) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +			while (len--) {
        +				u8 c = in[n];
        +				ctx->Xi.c[n] ^= c;
        +				out[n] = c^ctx->EKi.c[n];
        +				++n;
        +			}
        +		}
        +
        +		ctx->mres = n;
        +		return 0;
        +	} while(0);
        +#endif
        +	for (i=0;i<len;++i) {
        +		u8 c;
        +		if (n==0) {
        +			(*block)(ctx->Yi.c,ctx->EKi.c,key);
        +			++ctr;
        +			if (is_endian.little)
        +				PUTU32(ctx->Yi.c+12,ctr);
        +			else
        +				ctx->Yi.d[3] = ctr;
        +		}
        +		c = in[i];
        +		out[i] = c^ctx->EKi.c[n];
        +		ctx->Xi.c[n] ^= c;
        +		n = (n+1)%16;
        +		if (n==0)
        +			GCM_MUL(ctx,Xi);
        +	}
        +
        +	ctx->mres = n;
        +	return 0;
        +}
        +
        +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
        +		const unsigned char *in, unsigned char *out,
        +		size_t len, ctr128_f stream)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	unsigned int n, ctr;
        +	size_t i;
        +	u64   mlen = ctx->len.u[1];
        +	void *key  = ctx->key;
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +# ifdef GHASH
        +	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
        +				const u8 *inp,size_t len)	= ctx->ghash;
        +# endif
        +#endif
        +
        +	mlen += len;
        +	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
        +		return -1;
        +	ctx->len.u[1] = mlen;
        +
        +	if (ctx->ares) {
        +		/* First call to encrypt finalizes GHASH(AAD) */
        +		GCM_MUL(ctx,Xi);
        +		ctx->ares = 0;
        +	}
        +
        +	if (is_endian.little)
        +		ctr = GETU32(ctx->Yi.c+12);
        +	else
        +		ctr = ctx->Yi.d[3];
        +
        +	n = ctx->mres;
        +	if (n) {
        +		while (n && len) {
        +			ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
        +			--len;
        +			n = (n+1)%16;
        +		}
        +		if (n==0) GCM_MUL(ctx,Xi);
        +		else {
        +			ctx->mres = n;
        +			return 0;
        +		}
        +	}
        +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
        +	while (len>=GHASH_CHUNK) {
        +		(*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
        +		ctr += GHASH_CHUNK/16;
        +		if (is_endian.little)
        +			PUTU32(ctx->Yi.c+12,ctr);
        +		else
        +			ctx->Yi.d[3] = ctr;
        +		GHASH(ctx,out,GHASH_CHUNK);
        +		out += GHASH_CHUNK;
        +		in  += GHASH_CHUNK;
        +		len -= GHASH_CHUNK;
        +	}
        +#endif
        +	if ((i = (len&(size_t)-16))) {
        +		size_t j=i/16;
        +
        +		(*stream)(in,out,j,key,ctx->Yi.c);
        +		ctr += (unsigned int)j;
        +		if (is_endian.little)
        +			PUTU32(ctx->Yi.c+12,ctr);
        +		else
        +			ctx->Yi.d[3] = ctr;
        +		in  += i;
        +		len -= i;
        +#if defined(GHASH)
        +		GHASH(ctx,out,i);
        +		out += i;
        +#else
        +		while (j--) {
        +			for (i=0;i<16;++i) ctx->Xi.c[i] ^= out[i];
        +			GCM_MUL(ctx,Xi);
        +			out += 16;
        +		}
        +#endif
        +	}
        +	if (len) {
        +		(*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
        +		++ctr;
        +		if (is_endian.little)
        +			PUTU32(ctx->Yi.c+12,ctr);
        +		else
        +			ctx->Yi.d[3] = ctr;
        +		while (len--) {
        +			ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
        +			++n;
        +		}
        +	}
        +
        +	ctx->mres = n;
        +	return 0;
        +}
        +
        +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
        +		const unsigned char *in, unsigned char *out,
        +		size_t len,ctr128_f stream)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	unsigned int n, ctr;
        +	size_t i;
        +	u64   mlen = ctx->len.u[1];
        +	void *key  = ctx->key;
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +# ifdef GHASH
        +	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
        +				const u8 *inp,size_t len)	= ctx->ghash;
        +# endif
        +#endif
        +
        +	mlen += len;
        +	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen<len))
        +		return -1;
        +	ctx->len.u[1] = mlen;
        +
        +	if (ctx->ares) {
        +		/* First call to decrypt finalizes GHASH(AAD) */
        +		GCM_MUL(ctx,Xi);
        +		ctx->ares = 0;
        +	}
        +
        +	if (is_endian.little)
        +		ctr = GETU32(ctx->Yi.c+12);
        +	else
        +		ctr = ctx->Yi.d[3];
        +
        +	n = ctx->mres;
        +	if (n) {
        +		while (n && len) {
        +			u8 c = *(in++);
        +			*(out++) = c^ctx->EKi.c[n];
        +			ctx->Xi.c[n] ^= c;
        +			--len;
        +			n = (n+1)%16;
        +		}
        +		if (n==0) GCM_MUL (ctx,Xi);
        +		else {
        +			ctx->mres = n;
        +			return 0;
        +		}
        +	}
        +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
        +	while (len>=GHASH_CHUNK) {
        +		GHASH(ctx,in,GHASH_CHUNK);
        +		(*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
        +		ctr += GHASH_CHUNK/16;
        +		if (is_endian.little)
        +			PUTU32(ctx->Yi.c+12,ctr);
        +		else
        +			ctx->Yi.d[3] = ctr;
        +		out += GHASH_CHUNK;
        +		in  += GHASH_CHUNK;
        +		len -= GHASH_CHUNK;
        +	}
        +#endif
        +	if ((i = (len&(size_t)-16))) {
        +		size_t j=i/16;
        +
        +#if defined(GHASH)
        +		GHASH(ctx,in,i);
        +#else
        +		while (j--) {
        +			size_t k;
        +			for (k=0;k<16;++k) ctx->Xi.c[k] ^= in[k];
        +			GCM_MUL(ctx,Xi);
        +			in += 16;
        +		}
        +		j   = i/16;
        +		in -= i;
        +#endif
        +		(*stream)(in,out,j,key,ctx->Yi.c);
        +		ctr += (unsigned int)j;
        +		if (is_endian.little)
        +			PUTU32(ctx->Yi.c+12,ctr);
        +		else
        +			ctx->Yi.d[3] = ctr;
        +		out += i;
        +		in  += i;
        +		len -= i;
        +	}
        +	if (len) {
        +		(*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
        +		++ctr;
        +		if (is_endian.little)
        +			PUTU32(ctx->Yi.c+12,ctr);
        +		else
        +			ctx->Yi.d[3] = ctr;
        +		while (len--) {
        +			u8 c = in[n];
        +			ctx->Xi.c[n] ^= c;
        +			out[n] = c^ctx->EKi.c[n];
        +			++n;
        +		}
        +	}
        +
        +	ctx->mres = n;
        +	return 0;
        +}
        +
        +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
        +			size_t len)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	u64 alen = ctx->len.u[0]<<3;
        +	u64 clen = ctx->len.u[1]<<3;
        +#ifdef GCM_FUNCREF_4BIT
        +	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
        +#endif
        +
        +	if (ctx->mres || ctx->ares)
        +		GCM_MUL(ctx,Xi);
        +
        +	if (is_endian.little) {
        +#ifdef BSWAP8
        +		alen = BSWAP8(alen);
        +		clen = BSWAP8(clen);
        +#else
        +		u8 *p = ctx->len.c;
        +
        +		ctx->len.u[0] = alen;
        +		ctx->len.u[1] = clen;
        +
        +		alen = (u64)GETU32(p)  <<32|GETU32(p+4);
        +		clen = (u64)GETU32(p+8)<<32|GETU32(p+12);
        +#endif
        +	}
        +
        +	ctx->Xi.u[0] ^= alen;
        +	ctx->Xi.u[1] ^= clen;
        +	GCM_MUL(ctx,Xi);
        +
        +	ctx->Xi.u[0] ^= ctx->EK0.u[0];
        +	ctx->Xi.u[1] ^= ctx->EK0.u[1];
        +
        +	if (tag && len<=sizeof(ctx->Xi))
        +		return memcmp(ctx->Xi.c,tag,len);
        +	else
        +		return -1;
        +}
        +
        +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
        +{
        +	CRYPTO_gcm128_finish(ctx, NULL, 0);
        +	memcpy(tag, ctx->Xi.c, len<=sizeof(ctx->Xi.c)?len:sizeof(ctx->Xi.c));
        +}
        +
        +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
        +{
        +	GCM128_CONTEXT *ret;
        +
        +	if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT))))
        +		CRYPTO_gcm128_init(ret,key,block);
        +
        +	return ret;
        +}
        +
        +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
        +{
        +	if (ctx) {
        +		OPENSSL_cleanse(ctx,sizeof(*ctx));
        +		OPENSSL_free(ctx);
        +	}
        +}
        +
        +#if defined(SELFTEST)
        +#include <stdio.h>
        +#include <openssl/aes.h>
        +
        +/* Test Case 1 */
        +static const u8	K1[16],
        +		*P1=NULL,
        +		*A1=NULL,
        +		IV1[12],
        +		*C1=NULL,
        +		T1[]=  {0x58,0xe2,0xfc,0xce,0xfa,0x7e,0x30,0x61,0x36,0x7f,0x1d,0x57,0xa4,0xe7,0x45,0x5a};
        +
        +/* Test Case 2 */
        +#define K2 K1
        +#define A2 A1
        +#define IV2 IV1
        +static const u8	P2[16],
        +		C2[]=  {0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78},
        +		T2[]=  {0xab,0x6e,0x47,0xd4,0x2c,0xec,0x13,0xbd,0xf5,0x3a,0x67,0xb2,0x12,0x57,0xbd,0xdf};
        +
        +/* Test Case 3 */
        +#define A3 A2
        +static const u8	K3[]=  {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08},
        +		P3[]=  {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
        +			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
        +			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
        +			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
        +		IV3[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
        +		C3[]=  {0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
        +			0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
        +			0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
        +			0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,0x3d,0x58,0xe0,0x91,0x47,0x3f,0x59,0x85},
        +		T3[]=  {0x4d,0x5c,0x2a,0xf3,0x27,0xcd,0x64,0xa6,0x2c,0xf3,0x5a,0xbd,0x2b,0xa6,0xfa,0xb4};
        +
        +/* Test Case 4 */
        +#define K4 K3
        +#define IV4 IV3
        +static const u8	P4[]=  {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
        +			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
        +			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
        +			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
        +		A4[]=  {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
        +			0xab,0xad,0xda,0xd2},
        +		C4[]=  {0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
        +			0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
        +			0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
        +			0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,0x3d,0x58,0xe0,0x91},
        +		T4[]=  {0x5b,0xc9,0x4f,0xbc,0x32,0x21,0xa5,0xdb,0x94,0xfa,0xe9,0x5a,0xe7,0x12,0x1a,0x47};
        +
        +/* Test Case 5 */
        +#define K5 K4
        +#define P5 P4
        +#define A5 A4
        +static const u8	IV5[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
        +		C5[]=  {0x61,0x35,0x3b,0x4c,0x28,0x06,0x93,0x4a,0x77,0x7f,0xf5,0x1f,0xa2,0x2a,0x47,0x55,
        +			0x69,0x9b,0x2a,0x71,0x4f,0xcd,0xc6,0xf8,0x37,0x66,0xe5,0xf9,0x7b,0x6c,0x74,0x23,
        +			0x73,0x80,0x69,0x00,0xe4,0x9f,0x24,0xb2,0x2b,0x09,0x75,0x44,0xd4,0x89,0x6b,0x42,
        +			0x49,0x89,0xb5,0xe1,0xeb,0xac,0x0f,0x07,0xc2,0x3f,0x45,0x98},
        +		T5[]=  {0x36,0x12,0xd2,0xe7,0x9e,0x3b,0x07,0x85,0x56,0x1b,0xe1,0x4a,0xac,0xa2,0xfc,0xcb};
        +
        +/* Test Case 6 */
        +#define K6 K5
        +#define P6 P5
        +#define A6 A5
        +static const u8	IV6[]= {0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
        +			0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
        +			0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
        +			0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
        +		C6[]=  {0x8c,0xe2,0x49,0x98,0x62,0x56,0x15,0xb6,0x03,0xa0,0x33,0xac,0xa1,0x3f,0xb8,0x94,
        +			0xbe,0x91,0x12,0xa5,0xc3,0xa2,0x11,0xa8,0xba,0x26,0x2a,0x3c,0xca,0x7e,0x2c,0xa7,
        +			0x01,0xe4,0xa9,0xa4,0xfb,0xa4,0x3c,0x90,0xcc,0xdc,0xb2,0x81,0xd4,0x8c,0x7c,0x6f,
        +			0xd6,0x28,0x75,0xd2,0xac,0xa4,0x17,0x03,0x4c,0x34,0xae,0xe5},
        +		T6[]=  {0x61,0x9c,0xc5,0xae,0xff,0xfe,0x0b,0xfa,0x46,0x2a,0xf4,0x3c,0x16,0x99,0xd0,0x50};
        +
        +/* Test Case 7 */
        +static const u8 K7[24],
        +		*P7=NULL,
        +		*A7=NULL,
        +		IV7[12],
        +		*C7=NULL,
        +		T7[]=  {0xcd,0x33,0xb2,0x8a,0xc7,0x73,0xf7,0x4b,0xa0,0x0e,0xd1,0xf3,0x12,0x57,0x24,0x35};
        +
        +/* Test Case 8 */
        +#define K8 K7
        +#define IV8 IV7
        +#define A8 A7
        +static const u8	P8[16],
        +		C8[]=  {0x98,0xe7,0x24,0x7c,0x07,0xf0,0xfe,0x41,0x1c,0x26,0x7e,0x43,0x84,0xb0,0xf6,0x00},
        +		T8[]=  {0x2f,0xf5,0x8d,0x80,0x03,0x39,0x27,0xab,0x8e,0xf4,0xd4,0x58,0x75,0x14,0xf0,0xfb};
        +
        +/* Test Case 9 */
        +#define A9 A8
        +static const u8	K9[]=  {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
        +			0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c},
        +		P9[]=  {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
        +			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
        +			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
        +			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
        +		IV9[]= {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
        +		C9[]=  {0x39,0x80,0xca,0x0b,0x3c,0x00,0xe8,0x41,0xeb,0x06,0xfa,0xc4,0x87,0x2a,0x27,0x57,
        +			0x85,0x9e,0x1c,0xea,0xa6,0xef,0xd9,0x84,0x62,0x85,0x93,0xb4,0x0c,0xa1,0xe1,0x9c,
        +			0x7d,0x77,0x3d,0x00,0xc1,0x44,0xc5,0x25,0xac,0x61,0x9d,0x18,0xc8,0x4a,0x3f,0x47,
        +			0x18,0xe2,0x44,0x8b,0x2f,0xe3,0x24,0xd9,0xcc,0xda,0x27,0x10,0xac,0xad,0xe2,0x56},
        +		T9[]=  {0x99,0x24,0xa7,0xc8,0x58,0x73,0x36,0xbf,0xb1,0x18,0x02,0x4d,0xb8,0x67,0x4a,0x14};
        +
        +/* Test Case 10 */
        +#define K10 K9
        +#define IV10 IV9
        +static const u8	P10[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
        +			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
        +			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
        +			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
        +		A10[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
        +			0xab,0xad,0xda,0xd2},
        +		C10[]= {0x39,0x80,0xca,0x0b,0x3c,0x00,0xe8,0x41,0xeb,0x06,0xfa,0xc4,0x87,0x2a,0x27,0x57,
        +			0x85,0x9e,0x1c,0xea,0xa6,0xef,0xd9,0x84,0x62,0x85,0x93,0xb4,0x0c,0xa1,0xe1,0x9c,
        +			0x7d,0x77,0x3d,0x00,0xc1,0x44,0xc5,0x25,0xac,0x61,0x9d,0x18,0xc8,0x4a,0x3f,0x47,
        +			0x18,0xe2,0x44,0x8b,0x2f,0xe3,0x24,0xd9,0xcc,0xda,0x27,0x10},
        +		T10[]= {0x25,0x19,0x49,0x8e,0x80,0xf1,0x47,0x8f,0x37,0xba,0x55,0xbd,0x6d,0x27,0x61,0x8c};
        +
        +/* Test Case 11 */
        +#define K11 K10
        +#define P11 P10
        +#define A11 A10
        +static const u8	IV11[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
        +		C11[]= {0x0f,0x10,0xf5,0x99,0xae,0x14,0xa1,0x54,0xed,0x24,0xb3,0x6e,0x25,0x32,0x4d,0xb8,
        +			0xc5,0x66,0x63,0x2e,0xf2,0xbb,0xb3,0x4f,0x83,0x47,0x28,0x0f,0xc4,0x50,0x70,0x57,
        +			0xfd,0xdc,0x29,0xdf,0x9a,0x47,0x1f,0x75,0xc6,0x65,0x41,0xd4,0xd4,0xda,0xd1,0xc9,
        +			0xe9,0x3a,0x19,0xa5,0x8e,0x8b,0x47,0x3f,0xa0,0xf0,0x62,0xf7},
        +		T11[]= {0x65,0xdc,0xc5,0x7f,0xcf,0x62,0x3a,0x24,0x09,0x4f,0xcc,0xa4,0x0d,0x35,0x33,0xf8};
        +
        +/* Test Case 12 */
        +#define K12 K11
        +#define P12 P11
        +#define A12 A11
        +static const u8	IV12[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
        +			0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
        +			0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
        +			0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
        +		C12[]= {0xd2,0x7e,0x88,0x68,0x1c,0xe3,0x24,0x3c,0x48,0x30,0x16,0x5a,0x8f,0xdc,0xf9,0xff,
        +			0x1d,0xe9,0xa1,0xd8,0xe6,0xb4,0x47,0xef,0x6e,0xf7,0xb7,0x98,0x28,0x66,0x6e,0x45,
        +			0x81,0xe7,0x90,0x12,0xaf,0x34,0xdd,0xd9,0xe2,0xf0,0x37,0x58,0x9b,0x29,0x2d,0xb3,
        +			0xe6,0x7c,0x03,0x67,0x45,0xfa,0x22,0xe7,0xe9,0xb7,0x37,0x3b},
        +		T12[]= {0xdc,0xf5,0x66,0xff,0x29,0x1c,0x25,0xbb,0xb8,0x56,0x8f,0xc3,0xd3,0x76,0xa6,0xd9};
        +
        +/* Test Case 13 */
        +static const u8	K13[32],
        +		*P13=NULL,
        +		*A13=NULL,
        +		IV13[12],
        +		*C13=NULL,
        +		T13[]={0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9,0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b};
        +
        +/* Test Case 14 */
        +#define K14 K13
        +#define A14 A13
        +static const u8	P14[16],
        +		IV14[12],
        +		C14[]= {0xce,0xa7,0x40,0x3d,0x4d,0x60,0x6b,0x6e,0x07,0x4e,0xc5,0xd3,0xba,0xf3,0x9d,0x18},
        +		T14[]= {0xd0,0xd1,0xc8,0xa7,0x99,0x99,0x6b,0xf0,0x26,0x5b,0x98,0xb5,0xd4,0x8a,0xb9,0x19};
        +
        +/* Test Case 15 */
        +#define A15 A14
        +static const u8	K15[]= {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
        +			0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08},
        +		P15[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
        +			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
        +			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
        +			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55},
        +		IV15[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88},
        +		C15[]= {0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
        +			0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
        +			0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
        +			0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62,0x89,0x80,0x15,0xad},
        +		T15[]= {0xb0,0x94,0xda,0xc5,0xd9,0x34,0x71,0xbd,0xec,0x1a,0x50,0x22,0x70,0xe3,0xcc,0x6c};
        +
        +/* Test Case 16 */
        +#define K16 K15
        +#define IV16 IV15
        +static const u8	P16[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
        +			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
        +			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
        +			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39},
        +		A16[]= {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
        +			0xab,0xad,0xda,0xd2},
        +		C16[]= {0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
        +			0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
        +			0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
        +			0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62},
        +		T16[]= {0x76,0xfc,0x6e,0xce,0x0f,0x4e,0x17,0x68,0xcd,0xdf,0x88,0x53,0xbb,0x2d,0x55,0x1b};
        +
        +/* Test Case 17 */
        +#define K17 K16
        +#define P17 P16
        +#define A17 A16
        +static const u8	IV17[]={0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad},
        +		C17[]= {0xc3,0x76,0x2d,0xf1,0xca,0x78,0x7d,0x32,0xae,0x47,0xc1,0x3b,0xf1,0x98,0x44,0xcb,
        +			0xaf,0x1a,0xe1,0x4d,0x0b,0x97,0x6a,0xfa,0xc5,0x2f,0xf7,0xd7,0x9b,0xba,0x9d,0xe0,
        +			0xfe,0xb5,0x82,0xd3,0x39,0x34,0xa4,0xf0,0x95,0x4c,0xc2,0x36,0x3b,0xc7,0x3f,0x78,
        +			0x62,0xac,0x43,0x0e,0x64,0xab,0xe4,0x99,0xf4,0x7c,0x9b,0x1f},
        +		T17[]= {0x3a,0x33,0x7d,0xbf,0x46,0xa7,0x92,0xc4,0x5e,0x45,0x49,0x13,0xfe,0x2e,0xa8,0xf2};
        +
        +/* Test Case 18 */
        +#define K18 K17
        +#define P18 P17
        +#define A18 A17
        +static const u8	IV18[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0x5a,0xff,0x52,0x69,0xaa,
        +			0x6a,0x7a,0x95,0x38,0x53,0x4f,0x7d,0xa1,0xe4,0xc3,0x03,0xd2,0xa3,0x18,0xa7,0x28,
        +			0xc3,0xc0,0xc9,0x51,0x56,0x80,0x95,0x39,0xfc,0xf0,0xe2,0x42,0x9a,0x6b,0x52,0x54,
        +			0x16,0xae,0xdb,0xf5,0xa0,0xde,0x6a,0x57,0xa6,0x37,0xb3,0x9b},
        +		C18[]= {0x5a,0x8d,0xef,0x2f,0x0c,0x9e,0x53,0xf1,0xf7,0x5d,0x78,0x53,0x65,0x9e,0x2a,0x20,
        +			0xee,0xb2,0xb2,0x2a,0xaf,0xde,0x64,0x19,0xa0,0x58,0xab,0x4f,0x6f,0x74,0x6b,0xf4,
        +			0x0f,0xc0,0xc3,0xb7,0x80,0xf2,0x44,0x45,0x2d,0xa3,0xeb,0xf1,0xc5,0xd8,0x2c,0xde,
        +			0xa2,0x41,0x89,0x97,0x20,0x0e,0xf8,0x2e,0x44,0xae,0x7e,0x3f},
        +		T18[]= {0xa4,0x4a,0x82,0x66,0xee,0x1c,0x8e,0xb0,0xc8,0xb5,0xd4,0xcf,0x5a,0xe9,0xf1,0x9a};
        +
        +#define TEST_CASE(n)	do {					\
        +	u8 out[sizeof(P##n)];					\
        +	AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key);		\
        +	CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);	\
        +	CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));		\
        +	memset(out,0,sizeof(out));				\
        +	if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));	\
        +	if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out));	\
        +	if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||		\
        +	    (C##n && memcmp(out,C##n,sizeof(out))))		\
        +		ret++, printf ("encrypt test#%d failed.\n",n);	\
        +	CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));		\
        +	memset(out,0,sizeof(out));				\
        +	if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));	\
        +	if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));	\
        +	if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||		\
        +	    (P##n && memcmp(out,P##n,sizeof(out))))		\
        +		ret++, printf ("decrypt test#%d failed.\n",n);	\
        +	} while(0)
        +
        +int main()
        +{
        +	GCM128_CONTEXT ctx;
        +	AES_KEY key;
        +	int ret=0;
        +
        +	TEST_CASE(1);
        +	TEST_CASE(2);
        +	TEST_CASE(3);
        +	TEST_CASE(4);
        +	TEST_CASE(5);
        +	TEST_CASE(6);
        +	TEST_CASE(7);
        +	TEST_CASE(8);
        +	TEST_CASE(9);
        +	TEST_CASE(10);
        +	TEST_CASE(11);
        +	TEST_CASE(12);
        +	TEST_CASE(13);
        +	TEST_CASE(14);
        +	TEST_CASE(15);
        +	TEST_CASE(16);
        +	TEST_CASE(17);
        +	TEST_CASE(18);
        +
        +#ifdef OPENSSL_CPUID_OBJ
        +	{
        +	size_t start,stop,gcm_t,ctr_t,OPENSSL_rdtsc();
        +	union { u64 u; u8 c[1024]; } buf;
        +	int i;
        +
        +	AES_set_encrypt_key(K1,sizeof(K1)*8,&key);
        +	CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);
        +	CRYPTO_gcm128_setiv(&ctx,IV1,sizeof(IV1));
        +
        +	CRYPTO_gcm128_encrypt(&ctx,buf.c,buf.c,sizeof(buf));
        +	start = OPENSSL_rdtsc();
        +	CRYPTO_gcm128_encrypt(&ctx,buf.c,buf.c,sizeof(buf));
        +	gcm_t = OPENSSL_rdtsc() - start;
        +
        +	CRYPTO_ctr128_encrypt(buf.c,buf.c,sizeof(buf),
        +			&key,ctx.Yi.c,ctx.EKi.c,&ctx.mres,
        +			(block128_f)AES_encrypt);
        +	start = OPENSSL_rdtsc();
        +	CRYPTO_ctr128_encrypt(buf.c,buf.c,sizeof(buf),
        +			&key,ctx.Yi.c,ctx.EKi.c,&ctx.mres,
        +			(block128_f)AES_encrypt);
        +	ctr_t = OPENSSL_rdtsc() - start;
        +
        +	printf("%.2f-%.2f=%.2f\n",
        +			gcm_t/(double)sizeof(buf),
        +			ctr_t/(double)sizeof(buf),
        +			(gcm_t-ctr_t)/(double)sizeof(buf));
        +#ifdef GHASH
        +	GHASH(&ctx,buf.c,sizeof(buf));
        +	start = OPENSSL_rdtsc();
        +	for (i=0;i<100;++i) GHASH(&ctx,buf.c,sizeof(buf));
        +	gcm_t = OPENSSL_rdtsc() - start;
        +	printf("%.2f\n",gcm_t/(double)sizeof(buf)/(double)i);
        +#endif
        +	}
        +#endif
        +
        +	return ret;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/modes/modes.h b/vendor/openssl/openssl/crypto/modes/modes.h
        new file mode 100644
        index 000000000..f18215bb2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/modes.h
        @@ -0,0 +1,135 @@
        +/* ====================================================================
        + * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
        + *
        + * Rights for redistribution and usage in source and binary
        + * forms are granted according to the OpenSSL license.
        + */
        +
        +#include <stddef.h>
        +
        +typedef void (*block128_f)(const unsigned char in[16],
        +			unsigned char out[16],
        +			const void *key);
        +
        +typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], int enc);
        +
        +typedef void (*ctr128_f)(const unsigned char *in, unsigned char *out,
        +			size_t blocks, const void *key,
        +			const unsigned char ivec[16]);
        +
        +typedef void (*ccm128_f)(const unsigned char *in, unsigned char *out,
        +			size_t blocks, const void *key,
        +			const unsigned char ivec[16],unsigned char cmac[16]);
        +
        +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block);
        +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block);
        +
        +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], unsigned char ecount_buf[16],
        +			unsigned int *num, block128_f block);
        +
        +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], unsigned char ecount_buf[16],
        +			unsigned int *num, ctr128_f ctr);
        +
        +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], int *num,
        +			block128_f block);
        +
        +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], int *num,
        +			int enc, block128_f block);
        +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t length, const void *key,
        +			unsigned char ivec[16], int *num,
        +			int enc, block128_f block);
        +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t bits, const void *key,
        +			unsigned char ivec[16], int *num,
        +			int enc, block128_f block);
        +
        +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block);
        +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc);
        +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block);
        +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc);
        +
        +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block);
        +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc);
        +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], block128_f block);
        +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], cbc128_f cbc);
        +
        +typedef struct gcm128_context GCM128_CONTEXT;
        +
        +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
        +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block);
        +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
        +			size_t len);
        +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
        +			size_t len);
        +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
        +			const unsigned char *in, unsigned char *out,
        +			size_t len);
        +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
        +			const unsigned char *in, unsigned char *out,
        +			size_t len);
        +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
        +			const unsigned char *in, unsigned char *out,
        +			size_t len, ctr128_f stream);
        +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
        +			const unsigned char *in, unsigned char *out,
        +			size_t len, ctr128_f stream);
        +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
        +			size_t len);
        +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
        +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
        +
        +typedef struct ccm128_context CCM128_CONTEXT;
        +
        +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
        +	unsigned int M, unsigned int L, void *key,block128_f block);
        +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
        +	const unsigned char *nonce, size_t nlen, size_t mlen);
        +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
        +	const unsigned char *aad, size_t alen);
        +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out, size_t len);
        +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out, size_t len);
        +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out, size_t len,
        +	ccm128_f stream);
        +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
        +	const unsigned char *inp, unsigned char *out, size_t len,
        +	ccm128_f stream);
        +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
        +
        +typedef struct xts128_context XTS128_CONTEXT;
        +
        +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
        +	const unsigned char *inp, unsigned char *out, size_t len, int enc);
        diff --git a/vendor/openssl/openssl/crypto/modes/modes_lcl.h b/vendor/openssl/openssl/crypto/modes/modes_lcl.h
        new file mode 100644
        index 000000000..b6dc3c336
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/modes_lcl.h
        @@ -0,0 +1,131 @@
        +/* ====================================================================
        + * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use is governed by OpenSSL license.
        + * ====================================================================
        + */
        +
        +#include <openssl/modes.h>
        +
        +
        +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
        +typedef __int64 i64;
        +typedef unsigned __int64 u64;
        +#define U64(C) C##UI64
        +#elif defined(__arch64__)
        +typedef long i64;
        +typedef unsigned long u64;
        +#define U64(C) C##UL
        +#else
        +typedef long long i64;
        +typedef unsigned long long u64;
        +#define U64(C) C##ULL
        +#endif
        +
        +typedef unsigned int u32;
        +typedef unsigned char u8;
        +
        +#define STRICT_ALIGNMENT 1
        +#if defined(__i386)	|| defined(__i386__)	|| \
        +    defined(__x86_64)	|| defined(__x86_64__)	|| \
        +    defined(_M_IX86)	|| defined(_M_AMD64)	|| defined(_M_X64) || \
        +    defined(__s390__)	|| defined(__s390x__)	|| \
        +    ( (defined(__arm__)	|| defined(__arm)) && \
        +      (defined(__ARM_ARCH_7__)	|| defined(__ARM_ARCH_7A__) || \
        +       defined(__ARM_ARCH_7R__)	|| defined(__ARM_ARCH_7M__)) )
        +# undef STRICT_ALIGNMENT
        +#endif
        +
        +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +#if defined(__GNUC__) && __GNUC__>=2
        +# if defined(__x86_64) || defined(__x86_64__)
        +#  define BSWAP8(x) ({	u64 ret=(x);			\
        +			asm ("bswapq %0"		\
        +			: "+r"(ret));	ret;		})
        +#  define BSWAP4(x) ({	u32 ret=(x);			\
        +			asm ("bswapl %0"		\
        +			: "+r"(ret));	ret;		})
        +# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
        +#  define BSWAP8(x) ({	u32 lo=(u64)(x)>>32,hi=(x);	\
        +			asm ("bswapl %0; bswapl %1"	\
        +			: "+r"(hi),"+r"(lo));		\
        +			(u64)hi<<32|lo;			})
        +#  define BSWAP4(x) ({	u32 ret=(x);			\
        +			asm ("bswapl %0"		\
        +			: "+r"(ret));	ret;		})
        +# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
        +#  define BSWAP8(x) ({	u32 lo=(u64)(x)>>32,hi=(x);	\
        +			asm ("rev %0,%0; rev %1,%1"	\
        +			: "+r"(hi),"+r"(lo));		\
        +			(u64)hi<<32|lo;			})
        +#  define BSWAP4(x) ({	u32 ret;			\
        +			asm ("rev %0,%1"		\
        +			: "=r"(ret) : "r"((u32)(x)));	\
        +			ret;				})
        +# endif
        +#elif defined(_MSC_VER)
        +# if _MSC_VER>=1300
        +#  pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
        +#  define BSWAP8(x)	_byteswap_uint64((u64)(x))
        +#  define BSWAP4(x)	_byteswap_ulong((u32)(x))
        +# elif defined(_M_IX86)
        +   __inline u32 _bswap4(u32 val) {
        +	_asm mov eax,val
        +	_asm bswap eax
        +   }
        +#  define BSWAP4(x)	_bswap4(x)
        +# endif
        +#endif
        +#endif
        +
        +#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
        +#define GETU32(p)	BSWAP4(*(const u32 *)(p))
        +#define PUTU32(p,v)	*(u32 *)(p) = BSWAP4(v)
        +#else
        +#define GETU32(p)	((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
        +#define PUTU32(p,v)	((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
        +#endif
        +
        +/* GCM definitions */
        +
        +typedef struct { u64 hi,lo; } u128;
        +
        +#ifdef	TABLE_BITS
        +#undef	TABLE_BITS
        +#endif
        +/*
        + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
        + * never be set to 8 [or 1]. For further information see gcm128.c.
        + */
        +#define	TABLE_BITS 4
        +
        +struct gcm128_context {
        +	/* Following 6 names follow names in GCM specification */
        +	union { u64 u[2]; u32 d[4]; u8 c[16]; }	Yi,EKi,EK0,len,
        +						Xi,H;
        +	/* Relative position of Xi, H and pre-computed Htable is used
        +	 * in some assembler modules, i.e. don't change the order! */
        +#if TABLE_BITS==8
        +	u128 Htable[256];
        +#else
        +	u128 Htable[16];
        +	void (*gmult)(u64 Xi[2],const u128 Htable[16]);
        +	void (*ghash)(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
        +#endif
        +	unsigned int mres, ares;
        +	block128_f block;
        +	void *key;
        +};
        +
        +struct xts128_context {
        +	void      *key1, *key2;
        +	block128_f block1,block2;
        +};
        +
        +struct ccm128_context {
        +	union { u64 u[2]; u8 c[16]; } nonce, cmac;
        +	u64 blocks;
        +	block128_f block;
        +	void *key;
        +};
        +
        diff --git a/vendor/openssl/openssl/crypto/modes/ofb128.c b/vendor/openssl/openssl/crypto/modes/ofb128.c
        new file mode 100644
        index 000000000..01c01702c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/ofb128.c
        @@ -0,0 +1,121 @@
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +/* The input and output encrypted as though 128bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 128bit block we have used is contained in *num;
        + */
        +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +			size_t len, const void *key,
        +			unsigned char ivec[16], int *num,
        +			block128_f block)
        +{
        +	unsigned int n;
        +	size_t l=0;
        +
        +	assert(in && out && key && ivec && num);
        +
        +	n = *num;
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	if (16%sizeof(size_t) == 0) do { /* always true actually */
        +		while (n && len) {
        +			*(out++) = *(in++) ^ ivec[n];
        +			--len;
        +			n = (n+1) % 16;
        +		}
        +#if defined(STRICT_ALIGNMENT)
        +		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
        +			break;
        +#endif
        +		while (len>=16) {
        +			(*block)(ivec, ivec, key);
        +			for (; n<16; n+=sizeof(size_t))
        +				*(size_t*)(out+n) =
        +				*(size_t*)(in+n) ^ *(size_t*)(ivec+n);
        +			len -= 16;
        +			out += 16;
        +			in  += 16;
        +			n = 0;
        +		}
        +		if (len) {
        +			(*block)(ivec, ivec, key);
        +			while (len--) {
        +				out[n] = in[n] ^ ivec[n];
        +				++n;
        +			}
        +		}
        +		*num = n;
        +		return;
        +	} while(0);
        +	/* the rest would be commonly eliminated by x86* compiler */
        +#endif
        +	while (l<len) {
        +		if (n==0) {
        +			(*block)(ivec, ivec, key);
        +		}
        +		out[l] = in[l] ^ ivec[n];
        +		++l;
        +		n = (n+1) % 16;
        +	}
        +
        +	*num=n;
        +}
        diff --git a/vendor/openssl/openssl/crypto/modes/xts128.c b/vendor/openssl/openssl/crypto/modes/xts128.c
        new file mode 100644
        index 000000000..9cf27a25e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/modes/xts128.c
        @@ -0,0 +1,187 @@
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/crypto.h>
        +#include "modes_lcl.h"
        +#include <string.h>
        +
        +#ifndef MODES_DEBUG
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
        +	const unsigned char *inp, unsigned char *out,
        +	size_t len, int enc)
        +{
        +	const union { long one; char little; } is_endian = {1};
        +	union { u64 u[2]; u32 d[4]; u8 c[16]; } tweak, scratch;
        +	unsigned int i;
        +
        +	if (len<16) return -1;
        +
        +	memcpy(tweak.c, iv, 16);
        +
        +	(*ctx->block2)(tweak.c,tweak.c,ctx->key2);
        +
        +	if (!enc && (len%16)) len-=16;
        +
        +	while (len>=16) {
        +#if defined(STRICT_ALIGNMENT)
        +		memcpy(scratch.c,inp,16);
        +		scratch.u[0] ^= tweak.u[0];
        +		scratch.u[1] ^= tweak.u[1];
        +#else
        +		scratch.u[0] = ((u64*)inp)[0]^tweak.u[0];
        +		scratch.u[1] = ((u64*)inp)[1]^tweak.u[1];
        +#endif
        +		(*ctx->block1)(scratch.c,scratch.c,ctx->key1);
        +#if defined(STRICT_ALIGNMENT)
        +		scratch.u[0] ^= tweak.u[0];
        +		scratch.u[1] ^= tweak.u[1];
        +		memcpy(out,scratch.c,16);
        +#else
        +		((u64*)out)[0] = scratch.u[0]^=tweak.u[0];
        +		((u64*)out)[1] = scratch.u[1]^=tweak.u[1];
        +#endif
        +		inp += 16;
        +		out += 16;
        +		len -= 16;
        +
        +		if (len==0)	return 0;
        +
        +		if (is_endian.little) {
        +			unsigned int carry,res;
        +			
        +			res = 0x87&(((int)tweak.d[3])>>31);
        +			carry = (unsigned int)(tweak.u[0]>>63);
        +			tweak.u[0] = (tweak.u[0]<<1)^res;
        +			tweak.u[1] = (tweak.u[1]<<1)|carry;
        +		}
        +		else {
        +			size_t c;
        +
        +			for (c=0,i=0;i<16;++i) {
        +				/*+ substitutes for |, because c is 1 bit */ 
        +				c += ((size_t)tweak.c[i])<<1;
        +				tweak.c[i] = (u8)c;
        +				c = c>>8;
        +			}
        +			tweak.c[0] ^= (u8)(0x87&(0-c));
        +		}
        +	}
        +	if (enc) {
        +		for (i=0;i<len;++i) {
        +			u8 c = inp[i];
        +			out[i] = scratch.c[i];
        +			scratch.c[i] = c;
        +		}
        +		scratch.u[0] ^= tweak.u[0];
        +		scratch.u[1] ^= tweak.u[1];
        +		(*ctx->block1)(scratch.c,scratch.c,ctx->key1);
        +		scratch.u[0] ^= tweak.u[0];
        +		scratch.u[1] ^= tweak.u[1];
        +		memcpy(out-16,scratch.c,16);
        +	}
        +	else {
        +		union { u64 u[2]; u8 c[16]; } tweak1;
        +
        +		if (is_endian.little) {
        +			unsigned int carry,res;
        +
        +			res = 0x87&(((int)tweak.d[3])>>31);
        +			carry = (unsigned int)(tweak.u[0]>>63);
        +			tweak1.u[0] = (tweak.u[0]<<1)^res;
        +			tweak1.u[1] = (tweak.u[1]<<1)|carry;
        +		}
        +		else {
        +			size_t c;
        +
        +			for (c=0,i=0;i<16;++i) {
        +				/*+ substitutes for |, because c is 1 bit */ 
        +				c += ((size_t)tweak.c[i])<<1;
        +				tweak1.c[i] = (u8)c;
        +				c = c>>8;
        +			}
        +			tweak1.c[0] ^= (u8)(0x87&(0-c));
        +		}
        +#if defined(STRICT_ALIGNMENT)
        +		memcpy(scratch.c,inp,16);
        +		scratch.u[0] ^= tweak1.u[0];
        +		scratch.u[1] ^= tweak1.u[1];
        +#else
        +		scratch.u[0] = ((u64*)inp)[0]^tweak1.u[0];
        +		scratch.u[1] = ((u64*)inp)[1]^tweak1.u[1];
        +#endif
        +		(*ctx->block1)(scratch.c,scratch.c,ctx->key1);
        +		scratch.u[0] ^= tweak1.u[0];
        +		scratch.u[1] ^= tweak1.u[1];
        +
        +		for (i=0;i<len;++i) {
        +			u8 c = inp[16+i];
        +			out[16+i] = scratch.c[i];
        +			scratch.c[i] = c;
        +		}
        +		scratch.u[0] ^= tweak.u[0];
        +		scratch.u[1] ^= tweak.u[1];
        +		(*ctx->block1)(scratch.c,scratch.c,ctx->key1);
        +#if defined(STRICT_ALIGNMENT)
        +		scratch.u[0] ^= tweak.u[0];
        +		scratch.u[1] ^= tweak.u[1];
        +		memcpy (out,scratch.c,16);
        +#else
        +		((u64*)out)[0] = scratch.u[0]^tweak.u[0];
        +		((u64*)out)[1] = scratch.u[1]^tweak.u[1];
        +#endif
        +	}
        +
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/o_dir.c b/vendor/openssl/openssl/crypto/o_dir.c
        new file mode 100644
        index 000000000..42891ea45
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_dir.c
        @@ -0,0 +1,83 @@
        +/* crypto/o_dir.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 <errno.h>
        +#include <e_os.h>
        +
        +/* The routines really come from the Levitte Programming, so to make
        +   life simple, let's just use the raw files and hack the symbols to
        +   fit our namespace.  */
        +#define LP_DIR_CTX OPENSSL_DIR_CTX
        +#define LP_dir_context_st OPENSSL_dir_context_st
        +#define LP_find_file OPENSSL_DIR_read
        +#define LP_find_file_end OPENSSL_DIR_end
        +
        +#include "o_dir.h"
        +
        +#define LPDIR_H
        +#if defined OPENSSL_SYS_UNIX || defined DJGPP
        +#include "LPdir_unix.c"
        +#elif defined OPENSSL_SYS_VMS
        +#include "LPdir_vms.c"
        +#elif defined OPENSSL_SYS_WIN32
        +#include "LPdir_win32.c"
        +#elif defined OPENSSL_SYS_WINCE
        +#include "LPdir_wince.c"
        +#else
        +#include "LPdir_nyi.c"
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/o_dir.h b/vendor/openssl/openssl/crypto/o_dir.h
        new file mode 100644
        index 000000000..4b725c031
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_dir.h
        @@ -0,0 +1,53 @@
        +/* crypto/o_dir.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Copied from Richard Levitte's (richard@levitte.org) LP library.  All
        + * symbol names have been changed, with permission from the author.
        + */
        +
        +/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + */
        +
        +
        +#ifndef O_DIR_H
        +#define O_DIR_H
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +  typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
        +
        +  /* returns NULL on error or end-of-directory.
        +     If it is end-of-directory, errno will be zero */
        +  const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory);
        +  /* returns 1 on success, 0 on error */
        +  int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
        +
        +#ifdef __cplusplus
        +}
        +#endif
        +
        +#endif /* LPDIR_H */
        diff --git a/vendor/openssl/openssl/crypto/o_dir_test.c b/vendor/openssl/openssl/crypto/o_dir_test.c
        new file mode 100644
        index 000000000..3d75ecb00
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_dir_test.c
        @@ -0,0 +1,70 @@
        +/* crypto/o_dir.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Copied from Richard Levitte's (richard@levitte.org) LP library.  All
        + * symbol names have been changed, with permission from the author.
        + */
        +
        +/* $LP: LPlib/test/test_dir.c,v 1.1 2004/06/16 22:59:47 _cvs_levitte Exp $ */
        +/*
        + * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + */
        +
        +#include <stddef.h>
        +#include <stdlib.h>
        +#include <stdio.h>
        +#include <errno.h>
        +#include "e_os2.h"
        +#include "o_dir.h"
        +
        +#if defined OPENSSL_SYS_UNIX || defined OPENSSL_SYS_WIN32 || defined OPENSSL_SYS_WINCE
        +#define CURRDIR "."
        +#elif defined OPENSSL_SYS_VMS
        +#define CURRDIR "SYS$DISK:[]"
        +#else
        +#error "No supported platform defined!"
        +#endif
        +
        +int main()
        +{
        +  OPENSSL_DIR_CTX *ctx = NULL;
        +  const char *result;
        +
        +  while((result = OPENSSL_DIR_read(&ctx, CURRDIR)) != NULL)
        +    {
        +      printf("%s\n", result);
        +    }
        +
        +  if (errno)
        +    {
        +      perror("test_dir");
        +      exit(1);
        +    }
        +
        +  if (!OPENSSL_DIR_end(&ctx))
        +    {
        +      perror("test_dir");
        +      exit(2);
        +    }
        +  exit(0);
        +}
        diff --git a/vendor/openssl/openssl/crypto/o_fips.c b/vendor/openssl/openssl/crypto/o_fips.c
        new file mode 100644
        index 000000000..f6d1b2185
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_fips.c
        @@ -0,0 +1,96 @@
        +/* Written by Stephen henson (steve@openssl.org) for the OpenSSL
        + * project 2011.
        + */
        +/* ====================================================================
        + * Copyright (c) 2011 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"
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#include <openssl/fips_rand.h>
        +#include <openssl/rand.h>
        +#endif
        +
        +int FIPS_mode(void)
        +	{
        +	OPENSSL_init();
        +#ifdef OPENSSL_FIPS
        +	return FIPS_module_mode();
        +#else
        +	return 0;
        +#endif
        +	}
        +
        +int FIPS_mode_set(int r)
        +	{
        +	OPENSSL_init();
        +#ifdef OPENSSL_FIPS
        +#ifndef FIPS_AUTH_USER_PASS
        +#define FIPS_AUTH_USER_PASS	"Default FIPS Crypto User Password"
        +#endif
        +	if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
        +		return 0;
        +	if (r)
        +		RAND_set_rand_method(FIPS_rand_get_method());
        +	else
        +		RAND_set_rand_method(NULL);
        +	return 1;
        +#else
        +	if (r == 0)
        +		return 1;
        +	CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
        +	return 0;
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/o_init.c b/vendor/openssl/openssl/crypto/o_init.c
        new file mode 100644
        index 000000000..db4cdc443
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_init.c
        @@ -0,0 +1,82 @@
        +/* o_init.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <e_os.h>
        +#include <openssl/err.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#include <openssl/rand.h>
        +#endif
        +
        +/* Perform any essential OpenSSL initialization operations.
        + * Currently only sets FIPS callbacks
        + */
        +
        +void OPENSSL_init(void)
        +	{
        +	static int done = 0;
        +	if (done)
        +		return;
        +	done = 1;
        +#ifdef OPENSSL_FIPS
        +	FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
        +	FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
        +	FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
        +	RAND_init_fips();
        +#endif
        +#if 0
        +	fprintf(stderr, "Called OPENSSL_init\n");
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/o_str.c b/vendor/openssl/openssl/crypto/o_str.c
        new file mode 100644
        index 000000000..56104a6c3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_str.c
        @@ -0,0 +1,111 @@
        +/* crypto/o_str.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <ctype.h>
        +#include <e_os.h>
        +#include "o_str.h"
        +
        +#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
        +    !defined(OPENSSL_SYSNAME_WIN32) && \
        +    !defined(NETWARE_CLIB)
        +# include <strings.h>
        +#endif
        +
        +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n)
        +	{
        +#if defined(OPENSSL_IMPLEMENTS_strncasecmp)
        +	while (*str1 && *str2 && n)
        +		{
        +		int res = toupper(*str1) - toupper(*str2);
        +		if (res) return res < 0 ? -1 : 1;
        +		str1++;
        +		str2++;
        +		n--;
        +		}
        +	if (n == 0)
        +		return 0;
        +	if (*str1)
        +		return 1;
        +	if (*str2)
        +		return -1;
        +	return 0;
        +#else
        +	/* Recursion hazard warning! Whenever strncasecmp is #defined as
        +	 * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be
        +	 * defined as well. */
        +	return strncasecmp(str1, str2, n);
        +#endif
        +	}
        +int OPENSSL_strcasecmp(const char *str1, const char *str2)
        +	{
        +#if defined(OPENSSL_IMPLEMENTS_strncasecmp)
        +	return OPENSSL_strncasecmp(str1, str2, (size_t)-1);
        +#else
        +	return strcasecmp(str1, str2);
        +#endif
        +	}
        +
        +int OPENSSL_memcmp(const void *v1,const void *v2,size_t n)
        +	{
        +	const unsigned char *c1=v1,*c2=v2;
        +	int ret=0;
        +
        +	while(n && (ret=*c1-*c2)==0) n--,c1++,c2++;
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/o_str.h b/vendor/openssl/openssl/crypto/o_str.h
        new file mode 100644
        index 000000000..dfc98494c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_str.h
        @@ -0,0 +1,68 @@
        +/* crypto/o_str.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * 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_O_STR_H
        +#define HEADER_O_STR_H
        +
        +#include <stddef.h>		/* to get size_t */
        +
        +int OPENSSL_strcasecmp(const char *str1, const char *str2);
        +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n);
        +int OPENSSL_memcmp(const void *p1,const void *p2,size_t n);
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/o_time.c b/vendor/openssl/openssl/crypto/o_time.c
        new file mode 100644
        index 000000000..9030fdef7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_time.c
        @@ -0,0 +1,372 @@
        +/* crypto/o_time.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2008.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <openssl/e_os2.h>
        +#include <string.h>
        +#include "o_time.h"
        +
        +#ifdef OPENSSL_SYS_VMS
        +# if __CRTL_VER >= 70000000 && \
        +     (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE)
        +#  define VMS_GMTIME_OK
        +# endif
        +# ifndef VMS_GMTIME_OK
        +#  include <libdtdef.h>
        +#  include <lib$routines.h>
        +#  include <lnmdef.h>
        +#  include <starlet.h>
        +#  include <descrip.h>
        +#  include <stdlib.h>
        +# endif /* ndef VMS_GMTIME_OK */
        +#endif
        +
        +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
        +	{
        +	struct tm *ts = NULL;
        +
        +#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
        +	/* should return &data, but doesn't on some systems,
        +	   so we don't even look at the return value */
        +	gmtime_r(timer,result);
        +	ts = result;
        +#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
        +	ts = gmtime(timer);
        +	if (ts == NULL)
        +		return NULL;
        +
        +	memcpy(result, ts, sizeof(struct tm));
        +	ts = result;
        +#endif
        +#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK)
        +	if (ts == NULL)
        +		{
        +		static $DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL");
        +		static $DESCRIPTOR(lognam,"SYS$TIMEZONE_DIFFERENTIAL");
        +		char logvalue[256];
        +		unsigned int reslen = 0;
        +		struct {
        +			short buflen;
        +			short code;
        +			void *bufaddr;
        +			unsigned int *reslen;
        +		} itemlist[] = {
        +			{ 0, LNM$_STRING, 0, 0 },
        +			{ 0, 0, 0, 0 },
        +		};
        +		int status;
        +		time_t t;
        +
        +		/* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
        +		itemlist[0].buflen = sizeof(logvalue);
        +		itemlist[0].bufaddr = logvalue;
        +		itemlist[0].reslen = &reslen;
        +		status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
        +		if (!(status & 1))
        +			return NULL;
        +		logvalue[reslen] = '\0';
        +
        +		t = *timer;
        +
        +/* The following is extracted from the DEC C header time.h */
        +/*
        +**  Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
        +**  have two implementations.  One implementation is provided
        +**  for compatibility and deals with time in terms of local time,
        +**  the other __utc_* deals with time in terms of UTC.
        +*/
        +/* We use the same conditions as in said time.h to check if we should
        +   assume that t contains local time (and should therefore be adjusted)
        +   or UTC (and should therefore be left untouched). */
        +#if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE
        +		/* Get the numerical value of the equivalence string */
        +		status = atoi(logvalue);
        +
        +		/* and use it to move time to GMT */
        +		t -= status;
        +#endif
        +
        +		/* then convert the result to the time structure */
        +
        +		/* Since there was no gmtime_r() to do this stuff for us,
        +		   we have to do it the hard way. */
        +		{
        +		/* The VMS epoch is the astronomical Smithsonian date,
        +		   if I remember correctly, which is November 17, 1858.
        +		   Furthermore, time is measure in thenths of microseconds
        +		   and stored in quadwords (64 bit integers).  unix_epoch
        +		   below is January 1st 1970 expressed as a VMS time.  The
        +		   following code was used to get this number:
        +
        +		   #include <stdio.h>
        +		   #include <stdlib.h>
        +		   #include <lib$routines.h>
        +		   #include <starlet.h>
        +
        +		   main()
        +		   {
        +		     unsigned long systime[2];
        +		     unsigned short epoch_values[7] =
        +		       { 1970, 1, 1, 0, 0, 0, 0 };
        +
        +		     lib$cvt_vectim(epoch_values, systime);
        +
        +		     printf("%u %u", systime[0], systime[1]);
        +		   }
        +		*/
        +		unsigned long unix_epoch[2] = { 1273708544, 8164711 };
        +		unsigned long deltatime[2];
        +		unsigned long systime[2];
        +		struct vms_vectime
        +			{
        +			short year, month, day, hour, minute, second,
        +				centi_second;
        +			} time_values;
        +		long operation;
        +
        +		/* Turn the number of seconds since January 1st 1970 to
        +		   an internal delta time.
        +		   Note that lib$cvt_to_internal_time() will assume
        +		   that t is signed, and will therefore break on 32-bit
        +		   systems some time in 2038.
        +		*/
        +		operation = LIB$K_DELTA_SECONDS;
        +		status = lib$cvt_to_internal_time(&operation,
        +			&t, deltatime);
        +
        +		/* Add the delta time with the Unix epoch and we have
        +		   the current UTC time in internal format */
        +		status = lib$add_times(unix_epoch, deltatime, systime);
        +
        +		/* Turn the internal time into a time vector */
        +		status = sys$numtim(&time_values, systime);
        +
        +		/* Fill in the struct tm with the result */
        +		result->tm_sec = time_values.second;
        +		result->tm_min = time_values.minute;
        +		result->tm_hour = time_values.hour;
        +		result->tm_mday = time_values.day;
        +		result->tm_mon = time_values.month - 1;
        +		result->tm_year = time_values.year - 1900;
        +
        +		operation = LIB$K_DAY_OF_WEEK;
        +		status = lib$cvt_from_internal_time(&operation,
        +			&result->tm_wday, systime);
        +		result->tm_wday %= 7;
        +
        +		operation = LIB$K_DAY_OF_YEAR;
        +		status = lib$cvt_from_internal_time(&operation,
        +			&result->tm_yday, systime);
        +		result->tm_yday--;
        +
        +		result->tm_isdst = 0; /* There's no way to know... */
        +
        +		ts = result;
        +		}
        +		}
        +#endif
        +	return ts;
        +	}
        +
        +/* Take a tm structure and add an offset to it. This avoids any OS issues
        + * with restricted date types and overflows which cause the year 2038
        + * problem.
        + */
        +
        +#define SECS_PER_DAY (24 * 60 * 60)
        +
        +static long date_to_julian(int y, int m, int d);
        +static void julian_to_date(long jd, int *y, int *m, int *d);
        +
        +int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
        +	{
        +	int offset_hms, offset_day;
        +	long time_jd;
        +	int time_year, time_month, time_day;
        +	/* split offset into days and day seconds */
        +	offset_day = offset_sec / SECS_PER_DAY;
        +	/* Avoid sign issues with % operator */
        +	offset_hms  = offset_sec - (offset_day * SECS_PER_DAY);
        +	offset_day += off_day;
        +	/* Add current time seconds to offset */
        +	offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
        +	/* Adjust day seconds if overflow */
        +	if (offset_hms >= SECS_PER_DAY)
        +		{
        +		offset_day++;
        +		offset_hms -= SECS_PER_DAY;
        +		}
        +	else if (offset_hms < 0)
        +		{
        +		offset_day--;
        +		offset_hms += SECS_PER_DAY;
        +		}
        +
        +	/* Convert date of time structure into a Julian day number.
        +	 */
        +
        +	time_year = tm->tm_year + 1900;
        +	time_month = tm->tm_mon + 1;
        +	time_day = tm->tm_mday;
        +
        +	time_jd = date_to_julian(time_year, time_month, time_day);
        +
        +	/* Work out Julian day of new date */
        +	time_jd += offset_day;
        +
        +	if (time_jd < 0)
        +		return 0;
        +
        +	/* Convert Julian day back to date */
        +
        +	julian_to_date(time_jd, &time_year, &time_month, &time_day);
        +
        +	if (time_year < 1900 || time_year > 9999)
        +		return 0;
        +
        +	/* Update tm structure */
        +
        +	tm->tm_year = time_year - 1900;
        +	tm->tm_mon = time_month - 1;
        +	tm->tm_mday = time_day;
        +
        +	tm->tm_hour = offset_hms / 3600;
        +	tm->tm_min = (offset_hms / 60) % 60;
        +	tm->tm_sec = offset_hms % 60;
        +
        +	return 1;
        +		
        +}
        +
        +/* Convert date to and from julian day
        + * Uses Fliegel & Van Flandern algorithm
        + */
        +static long date_to_julian(int y, int m, int d)
        +{
        +	return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
        +		(367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
        +		(3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 +
        +		d - 32075;
        +}
        +
        +static void julian_to_date(long jd, int *y, int *m, int *d)
        +	{
        +	long  L = jd + 68569;
        +	long  n = (4 * L) / 146097;
        +	long  i, j;
        +
        +	L = L - (146097 * n + 3) / 4;
        +	i = (4000 * (L + 1)) / 1461001;
        +	L = L - (1461 * i) / 4 + 31;
        +	j = (80 * L) / 2447;
        +	*d = L - (2447 * j) / 80;
        +	L = j / 11;
        +	*m = j + 2 - (12 * L);
        +	*y = 100 * (n - 49) + i + L;
        +	}
        +
        +#ifdef OPENSSL_TIME_TEST
        +
        +#include <stdio.h>
        +
        +/* Time checking test code. Check times are identical for a wide range of
        + * offsets. This should be run on a machine with 64 bit time_t or it will
        + * trigger the very errors the routines fix.
        + */
        +
        +int main(int argc, char **argv)
        +	{
        +	long offset;
        +	for (offset = 0; offset < 1000000; offset++)
        +		{
        +		check_time(offset);
        +		check_time(-offset);
        +		check_time(offset * 1000);
        +		check_time(-offset * 1000);
        +		}
        +	}
        +
        +int check_time(long offset)
        +	{
        +	struct tm tm1, tm2;
        +	time_t t1, t2;
        +	time(&t1);
        +	t2 = t1 + offset;
        +	OPENSSL_gmtime(&t2, &tm2);
        +	OPENSSL_gmtime(&t1, &tm1);
        +	OPENSSL_gmtime_adj(&tm1, 0, offset);
        +	if ((tm1.tm_year == tm2.tm_year) &&
        +	    (tm1.tm_mon == tm2.tm_mon) &&
        +	    (tm1.tm_mday == tm2.tm_mday) &&
        +	    (tm1.tm_hour == tm2.tm_hour) &&
        +	    (tm1.tm_min == tm2.tm_min) &&
        +	    (tm1.tm_sec == tm2.tm_sec))
        +		return 1;
        +	fprintf(stderr, "TIME ERROR!!\n");
        +	fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n",
        +			tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900,
        +			tm2.tm_hour, tm2.tm_min, tm2.tm_sec);
        +	fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n",
        +			tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900,
        +			tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
        +	return 0;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/o_time.h b/vendor/openssl/openssl/crypto/o_time.h
        new file mode 100644
        index 000000000..e391da750
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/o_time.h
        @@ -0,0 +1,67 @@
        +/* crypto/o_time.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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_O_TIME_H
        +#define HEADER_O_TIME_H
        +
        +#include <time.h>
        +
        +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
        +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/objects/Makefile b/vendor/openssl/openssl/crypto/objects/Makefile
        new file mode 100644
        index 000000000..a8aedbd42
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/Makefile
        @@ -0,0 +1,130 @@
        +#
        +# OpenSSL/crypto/objects/Makefile
        +#
        +
        +DIR=	objects
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +PERL=		perl
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	o_names.c obj_dat.c obj_lib.c obj_err.c obj_xref.c
        +LIBOBJ= o_names.o obj_dat.o obj_lib.o obj_err.o obj_xref.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= objects.h obj_mac.h
        +HEADER=	$(EXHEADER) obj_dat.h obj_xref.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	obj_dat.h obj_xref.h lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +obj_dat.h: obj_dat.pl obj_mac.h
        +	$(PERL) obj_dat.pl obj_mac.h obj_dat.h
        +
        +# objects.pl both reads and writes obj_mac.num
        +obj_mac.h: objects.pl objects.txt obj_mac.num
        +	$(PERL) objects.pl objects.txt obj_mac.num obj_mac.h
        +	@sleep 1; touch obj_mac.h; sleep 1
        +
        +obj_xref.h: objxref.pl obj_xref.txt obj_mac.num
        +	$(PERL) objxref.pl obj_mac.num obj_xref.txt > obj_xref.h
        +	@sleep 1; touch obj_xref.h; sleep 1
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +o_names.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +o_names.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +o_names.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +o_names.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +o_names.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +o_names.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +o_names.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +o_names.o: o_names.c
        +obj_dat.o: ../../e_os.h ../../include/openssl/asn1.h
        +obj_dat.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +obj_dat.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +obj_dat.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +obj_dat.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +obj_dat.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +obj_dat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +obj_dat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +obj_dat.o: ../../include/openssl/symhacks.h ../cryptlib.h obj_dat.c obj_dat.h
        +obj_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +obj_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +obj_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +obj_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +obj_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +obj_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +obj_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +obj_err.o: obj_err.c
        +obj_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +obj_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +obj_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +obj_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +obj_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +obj_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +obj_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +obj_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +obj_lib.o: ../cryptlib.h obj_lib.c
        +obj_xref.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +obj_xref.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +obj_xref.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +obj_xref.o: ../../include/openssl/opensslconf.h
        +obj_xref.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +obj_xref.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +obj_xref.o: ../../include/openssl/symhacks.h obj_xref.c obj_xref.h
        diff --git a/vendor/openssl/openssl/crypto/objects/o_names.c b/vendor/openssl/openssl/crypto/objects/o_names.c
        new file mode 100644
        index 000000000..4a548c2ed
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/o_names.c
        @@ -0,0 +1,372 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/err.h>
        +#include <openssl/lhash.h>
        +#include <openssl/objects.h>
        +#include <openssl/safestack.h>
        +#include <openssl/e_os2.h>
        +
        +/* Later versions of DEC C has started to add lnkage information to certain
        + * functions, which makes it tricky to use them as values to regular function
        + * pointers.  One way is to define a macro that takes care of casting them
        + * correctly.
        + */
        +#ifdef OPENSSL_SYS_VMS_DECC
        +# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
        +#else
        +# define OPENSSL_strcmp strcmp
        +#endif
        +
        +/* I use the ex_data stuff to manage the identifiers for the obj_name_types
        + * that applications may define.  I only really use the free function field.
        + */
        +DECLARE_LHASH_OF(OBJ_NAME);
        +static LHASH_OF(OBJ_NAME) *names_lh=NULL;
        +static int names_type_num=OBJ_NAME_TYPE_NUM;
        +
        +typedef struct name_funcs_st
        +	{
        +	unsigned long (*hash_func)(const char *name);
        +	int (*cmp_func)(const char *a,const char *b);
        +	void (*free_func)(const char *, int, const char *);
        +	} NAME_FUNCS;
        +
        +DECLARE_STACK_OF(NAME_FUNCS)
        +IMPLEMENT_STACK_OF(NAME_FUNCS)
        +
        +static STACK_OF(NAME_FUNCS) *name_funcs_stack;
        +
        +/* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
        + * casting in the functions. This prevents function pointer casting without the
        + * need for macro-generated wrapper functions. */
        +
        +/* static unsigned long obj_name_hash(OBJ_NAME *a); */
        +static unsigned long obj_name_hash(const void *a_void);
        +/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
        +static int obj_name_cmp(const void *a_void,const void *b_void);
        +
        +static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME)
        +static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME)
        +
        +int OBJ_NAME_init(void)
        +	{
        +	if (names_lh != NULL) return(1);
        +	MemCheck_off();
        +	names_lh=lh_OBJ_NAME_new();
        +	MemCheck_on();
        +	return(names_lh != NULL);
        +	}
        +
        +int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
        +	int (*cmp_func)(const char *, const char *),
        +	void (*free_func)(const char *, int, const char *))
        +	{
        +	int ret;
        +	int i;
        +	NAME_FUNCS *name_funcs;
        +
        +	if (name_funcs_stack == NULL)
        +		{
        +		MemCheck_off();
        +		name_funcs_stack=sk_NAME_FUNCS_new_null();
        +		MemCheck_on();
        +		}
        +	if (name_funcs_stack == NULL)
        +		{
        +		/* ERROR */
        +		return(0);
        +		}
        +	ret=names_type_num;
        +	names_type_num++;
        +	for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
        +		{
        +		MemCheck_off();
        +		name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
        +		MemCheck_on();
        +		if (!name_funcs)
        +			{
        +			OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		name_funcs->hash_func = lh_strhash;
        +		name_funcs->cmp_func = OPENSSL_strcmp;
        +		name_funcs->free_func = 0; /* NULL is often declared to
        +						* ((void *)0), which according
        +						* to Compaq C is not really
        +						* compatible with a function
        +						* pointer.	-- Richard Levitte*/
        +		MemCheck_off();
        +		sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
        +		MemCheck_on();
        +		}
        +	name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
        +	if (hash_func != NULL)
        +		name_funcs->hash_func = hash_func;
        +	if (cmp_func != NULL)
        +		name_funcs->cmp_func = cmp_func;
        +	if (free_func != NULL)
        +		name_funcs->free_func = free_func;
        +	return(ret);
        +	}
        +
        +/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
        +static int obj_name_cmp(const void *a_void, const void *b_void)
        +	{
        +	int ret;
        +	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
        +	const OBJ_NAME *b = (const OBJ_NAME *)b_void;
        +
        +	ret=a->type-b->type;
        +	if (ret == 0)
        +		{
        +		if ((name_funcs_stack != NULL)
        +			&& (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
        +			{
        +			ret=sk_NAME_FUNCS_value(name_funcs_stack,
        +				a->type)->cmp_func(a->name,b->name);
        +			}
        +		else
        +			ret=strcmp(a->name,b->name);
        +		}
        +	return(ret);
        +	}
        +
        +/* static unsigned long obj_name_hash(OBJ_NAME *a) */
        +static unsigned long obj_name_hash(const void *a_void)
        +	{
        +	unsigned long ret;
        +	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
        +
        +	if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
        +		{
        +		ret=sk_NAME_FUNCS_value(name_funcs_stack,
        +			a->type)->hash_func(a->name);
        +		}
        +	else
        +		{
        +		ret=lh_strhash(a->name);
        +		}
        +	ret^=a->type;
        +	return(ret);
        +	}
        +
        +const char *OBJ_NAME_get(const char *name, int type)
        +	{
        +	OBJ_NAME on,*ret;
        +	int num=0,alias;
        +
        +	if (name == NULL) return(NULL);
        +	if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL);
        +
        +	alias=type&OBJ_NAME_ALIAS;
        +	type&= ~OBJ_NAME_ALIAS;
        +
        +	on.name=name;
        +	on.type=type;
        +
        +	for (;;)
        +	{
        +		ret=lh_OBJ_NAME_retrieve(names_lh,&on);
        +		if (ret == NULL) return(NULL);
        +		if ((ret->alias) && !alias)
        +			{
        +			if (++num > 10) return(NULL);
        +			on.name=ret->data;
        +			}
        +		else
        +			{
        +			return(ret->data);
        +			}
        +		}
        +	}
        +
        +int OBJ_NAME_add(const char *name, int type, const char *data)
        +	{
        +	OBJ_NAME *onp,*ret;
        +	int alias;
        +
        +	if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
        +
        +	alias=type&OBJ_NAME_ALIAS;
        +	type&= ~OBJ_NAME_ALIAS;
        +
        +	onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
        +	if (onp == NULL)
        +		{
        +		/* ERROR */
        +		return(0);
        +		}
        +
        +	onp->name=name;
        +	onp->alias=alias;
        +	onp->type=type;
        +	onp->data=data;
        +
        +	ret=lh_OBJ_NAME_insert(names_lh,onp);
        +	if (ret != NULL)
        +		{
        +		/* free things */
        +		if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
        +			{
        +			/* XXX: I'm not sure I understand why the free
        +			 * function should get three arguments...
        +			 * -- Richard Levitte
        +			 */
        +			sk_NAME_FUNCS_value(name_funcs_stack,
        +				ret->type)->free_func(ret->name,ret->type,ret->data);
        +			}
        +		OPENSSL_free(ret);
        +		}
        +	else
        +		{
        +		if (lh_OBJ_NAME_error(names_lh))
        +			{
        +			/* ERROR */
        +			return(0);
        +			}
        +		}
        +	return(1);
        +	}
        +
        +int OBJ_NAME_remove(const char *name, int type)
        +	{
        +	OBJ_NAME on,*ret;
        +
        +	if (names_lh == NULL) return(0);
        +
        +	type&= ~OBJ_NAME_ALIAS;
        +	on.name=name;
        +	on.type=type;
        +	ret=lh_OBJ_NAME_delete(names_lh,&on);
        +	if (ret != NULL)
        +		{
        +		/* free things */
        +		if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
        +			{
        +			/* XXX: I'm not sure I understand why the free
        +			 * function should get three arguments...
        +			 * -- Richard Levitte
        +			 */
        +			sk_NAME_FUNCS_value(name_funcs_stack,
        +				ret->type)->free_func(ret->name,ret->type,ret->data);
        +			}
        +		OPENSSL_free(ret);
        +		return(1);
        +		}
        +	else
        +		return(0);
        +	}
        +
        +struct doall
        +	{
        +	int type;
        +	void (*fn)(const OBJ_NAME *,void *arg);
        +	void *arg;
        +	};
        +
        +static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d)
        +	{
        +	if(name->type == d->type)
        +		d->fn(name,d->arg);
        +	}
        +
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall)
        +
        +void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
        +	{
        +	struct doall d;
        +
        +	d.type=type;
        +	d.fn=fn;
        +	d.arg=arg;
        +
        +	lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
        +			      struct doall, &d);
        +	}
        +
        +struct doall_sorted
        +	{
        +	int type;
        +	int n;
        +	const OBJ_NAME **names;
        +	};
        +
        +static void do_all_sorted_fn(const OBJ_NAME *name,void *d_)
        +	{
        +	struct doall_sorted *d=d_;
        +
        +	if(name->type != d->type)
        +		return;
        +
        +	d->names[d->n++]=name;
        +	}
        +
        +static int do_all_sorted_cmp(const void *n1_,const void *n2_)
        +	{
        +	const OBJ_NAME * const *n1=n1_;
        +	const OBJ_NAME * const *n2=n2_;
        +
        +	return strcmp((*n1)->name,(*n2)->name);
        +	}
        +
        +void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
        +				void *arg)
        +	{
        +	struct doall_sorted d;
        +	int n;
        +
        +	d.type=type;
        +	d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names);
        +	d.n=0;
        +	OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
        +
        +	qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp);
        +
        +	for(n=0 ; n < d.n ; ++n)
        +		fn(d.names[n],arg);
        +
        +	OPENSSL_free((void *)d.names);
        +	}
        +
        +static int free_type;
        +
        +static void names_lh_free_doall(OBJ_NAME *onp)
        +	{
        +	if (onp == NULL)
        +		return;
        +
        +	if (free_type < 0 || free_type == onp->type)
        +		OBJ_NAME_remove(onp->name,onp->type);
        +	}
        +
        +static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME)
        +
        +static void name_funcs_free(NAME_FUNCS *ptr)
        +	{
        +	OPENSSL_free(ptr);
        +	}
        +
        +void OBJ_NAME_cleanup(int type)
        +	{
        +	unsigned long down_load;
        +
        +	if (names_lh == NULL) return;
        +
        +	free_type=type;
        +	down_load=lh_OBJ_NAME_down_load(names_lh);
        +	lh_OBJ_NAME_down_load(names_lh)=0;
        +
        +	lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
        +	if (type < 0)
        +		{
        +		lh_OBJ_NAME_free(names_lh);
        +		sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
        +		names_lh=NULL;
        +		name_funcs_stack = NULL;
        +		}
        +	else
        +		lh_OBJ_NAME_down_load(names_lh)=down_load;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_dat.c b/vendor/openssl/openssl/crypto/objects/obj_dat.c
        new file mode 100644
        index 000000000..8a342ba3e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_dat.c
        @@ -0,0 +1,810 @@
        +/* crypto/objects/obj_dat.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include <limits.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/bn.h>
        +
        +/* obj_dat.h is generated from objects.h by obj_dat.pl */
        +#ifndef OPENSSL_NO_OBJECT
        +#include "obj_dat.h"
        +#else
        +/* You will have to load all the objects needed manually in the application */
        +#define NUM_NID 0
        +#define NUM_SN 0
        +#define NUM_LN 0
        +#define NUM_OBJ 0
        +static const unsigned char lvalues[1];
        +static const ASN1_OBJECT nid_objs[1];
        +static const unsigned int sn_objs[1];
        +static const unsigned int ln_objs[1];
        +static const unsigned int obj_objs[1];
        +#endif
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
        +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
        +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
        +
        +#define ADDED_DATA	0
        +#define ADDED_SNAME	1
        +#define ADDED_LNAME	2
        +#define ADDED_NID	3
        +
        +typedef struct added_obj_st
        +	{
        +	int type;
        +	ASN1_OBJECT *obj;
        +	} ADDED_OBJ;
        +DECLARE_LHASH_OF(ADDED_OBJ);
        +
        +static int new_nid=NUM_NID;
        +static LHASH_OF(ADDED_OBJ) *added=NULL;
        +
        +static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
        +	{ return(strcmp((*a)->sn,nid_objs[*b].sn)); }
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
        +
        +static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
        +	{ return(strcmp((*a)->ln,nid_objs[*b].ln)); }
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
        +
        +static unsigned long added_obj_hash(const ADDED_OBJ *ca)
        +	{
        +	const ASN1_OBJECT *a;
        +	int i;
        +	unsigned long ret=0;
        +	unsigned char *p;
        +
        +	a=ca->obj;
        +	switch (ca->type)
        +		{
        +	case ADDED_DATA:
        +		ret=a->length<<20L;
        +		p=(unsigned char *)a->data;
        +		for (i=0; i<a->length; i++)
        +			ret^=p[i]<<((i*3)%24);
        +		break;
        +	case ADDED_SNAME:
        +		ret=lh_strhash(a->sn);
        +		break;
        +	case ADDED_LNAME:
        +		ret=lh_strhash(a->ln);
        +		break;
        +	case ADDED_NID:
        +		ret=a->nid;
        +		break;
        +	default:
        +		/* abort(); */
        +		return 0;
        +		}
        +	ret&=0x3fffffffL;
        +	ret|=ca->type<<30L;
        +	return(ret);
        +	}
        +static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
        +
        +static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
        +	{
        +	ASN1_OBJECT *a,*b;
        +	int i;
        +
        +	i=ca->type-cb->type;
        +	if (i) return(i);
        +	a=ca->obj;
        +	b=cb->obj;
        +	switch (ca->type)
        +		{
        +	case ADDED_DATA:
        +		i=(a->length - b->length);
        +		if (i) return(i);
        +		return(memcmp(a->data,b->data,(size_t)a->length));
        +	case ADDED_SNAME:
        +		if (a->sn == NULL) return(-1);
        +		else if (b->sn == NULL) return(1);
        +		else return(strcmp(a->sn,b->sn));
        +	case ADDED_LNAME:
        +		if (a->ln == NULL) return(-1);
        +		else if (b->ln == NULL) return(1);
        +		else return(strcmp(a->ln,b->ln));
        +	case ADDED_NID:
        +		return(a->nid-b->nid);
        +	default:
        +		/* abort(); */
        +		return 0;
        +		}
        +	}
        +static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
        +
        +static int init_added(void)
        +	{
        +	if (added != NULL) return(1);
        +	added=lh_ADDED_OBJ_new();
        +	return(added != NULL);
        +	}
        +
        +static void cleanup1_doall(ADDED_OBJ *a)
        +	{
        +	a->obj->nid=0;
        +	a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
        +	                ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
        +			ASN1_OBJECT_FLAG_DYNAMIC_DATA;
        +	}
        +
        +static void cleanup2_doall(ADDED_OBJ *a)
        +	{ a->obj->nid++; }
        +
        +static void cleanup3_doall(ADDED_OBJ *a)
        +	{
        +	if (--a->obj->nid == 0)
        +		ASN1_OBJECT_free(a->obj);
        +	OPENSSL_free(a);
        +	}
        +
        +static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
        +static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
        +static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
        +
        +/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting
        + * to use freed up OIDs. If neccessary the actual freeing up of OIDs is
        + * delayed.
        + */
        +
        +int obj_cleanup_defer = 0;
        +
        +void check_defer(int nid)
        +	{
        +	if (!obj_cleanup_defer && nid >= NUM_NID)
        +			obj_cleanup_defer = 1;
        +	}
        +
        +void OBJ_cleanup(void)
        +	{
        +	if (obj_cleanup_defer)
        +		{
        +		obj_cleanup_defer = 2;
        +		return ;
        +		}
        +	if (added == NULL) return;
        +	lh_ADDED_OBJ_down_load(added) = 0;
        +	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
        +	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
        +	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
        +	lh_ADDED_OBJ_free(added);
        +	added=NULL;
        +	}
        +
        +int OBJ_new_nid(int num)
        +	{
        +	int i;
        +
        +	i=new_nid;
        +	new_nid+=num;
        +	return(i);
        +	}
        +
        +int OBJ_add_object(const ASN1_OBJECT *obj)
        +	{
        +	ASN1_OBJECT *o;
        +	ADDED_OBJ *ao[4]={NULL,NULL,NULL,NULL},*aop;
        +	int i;
        +
        +	if (added == NULL)
        +		if (!init_added()) return(0);
        +	if ((o=OBJ_dup(obj)) == NULL) goto err;
        +	if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
        +	if ((o->length != 0) && (obj->data != NULL))
        +		if (!(ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
        +	if (o->sn != NULL)
        +		if (!(ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
        +	if (o->ln != NULL)
        +		if (!(ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
        +
        +	for (i=ADDED_DATA; i<=ADDED_NID; i++)
        +		{
        +		if (ao[i] != NULL)
        +			{
        +			ao[i]->type=i;
        +			ao[i]->obj=o;
        +			aop=lh_ADDED_OBJ_insert(added,ao[i]);
        +			/* memory leak, buit should not normally matter */
        +			if (aop != NULL)
        +				OPENSSL_free(aop);
        +			}
        +		}
        +	o->flags&= ~(ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
        +			ASN1_OBJECT_FLAG_DYNAMIC_DATA);
        +
        +	return(o->nid);
        +err2:
        +	OBJerr(OBJ_F_OBJ_ADD_OBJECT,ERR_R_MALLOC_FAILURE);
        +err:
        +	for (i=ADDED_DATA; i<=ADDED_NID; i++)
        +		if (ao[i] != NULL) OPENSSL_free(ao[i]);
        +	if (o != NULL) OPENSSL_free(o);
        +	return(NID_undef);
        +	}
        +
        +ASN1_OBJECT *OBJ_nid2obj(int n)
        +	{
        +	ADDED_OBJ ad,*adp;
        +	ASN1_OBJECT ob;
        +
        +	if ((n >= 0) && (n < NUM_NID))
        +		{
        +		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
        +			{
        +			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
        +			return(NULL);
        +			}
        +		return((ASN1_OBJECT *)&(nid_objs[n]));
        +		}
        +	else if (added == NULL)
        +		return(NULL);
        +	else
        +		{
        +		ad.type=ADDED_NID;
        +		ad.obj= &ob;
        +		ob.nid=n;
        +		adp=lh_ADDED_OBJ_retrieve(added,&ad);
        +		if (adp != NULL)
        +			return(adp->obj);
        +		else
        +			{
        +			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
        +			return(NULL);
        +			}
        +		}
        +	}
        +
        +const char *OBJ_nid2sn(int n)
        +	{
        +	ADDED_OBJ ad,*adp;
        +	ASN1_OBJECT ob;
        +
        +	if ((n >= 0) && (n < NUM_NID))
        +		{
        +		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
        +			{
        +			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
        +			return(NULL);
        +			}
        +		return(nid_objs[n].sn);
        +		}
        +	else if (added == NULL)
        +		return(NULL);
        +	else
        +		{
        +		ad.type=ADDED_NID;
        +		ad.obj= &ob;
        +		ob.nid=n;
        +		adp=lh_ADDED_OBJ_retrieve(added,&ad);
        +		if (adp != NULL)
        +			return(adp->obj->sn);
        +		else
        +			{
        +			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
        +			return(NULL);
        +			}
        +		}
        +	}
        +
        +const char *OBJ_nid2ln(int n)
        +	{
        +	ADDED_OBJ ad,*adp;
        +	ASN1_OBJECT ob;
        +
        +	if ((n >= 0) && (n < NUM_NID))
        +		{
        +		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
        +			{
        +			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
        +			return(NULL);
        +			}
        +		return(nid_objs[n].ln);
        +		}
        +	else if (added == NULL)
        +		return(NULL);
        +	else
        +		{
        +		ad.type=ADDED_NID;
        +		ad.obj= &ob;
        +		ob.nid=n;
        +		adp=lh_ADDED_OBJ_retrieve(added,&ad);
        +		if (adp != NULL)
        +			return(adp->obj->ln);
        +		else
        +			{
        +			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
        +			return(NULL);
        +			}
        +		}
        +	}
        +
        +static int obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp)
        +	{
        +	int j;
        +	const ASN1_OBJECT *a= *ap;
        +	const ASN1_OBJECT *b= &nid_objs[*bp];
        +
        +	j=(a->length - b->length);
        +        if (j) return(j);
        +	return(memcmp(a->data,b->data,a->length));
        +	}
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
        +
        +int OBJ_obj2nid(const ASN1_OBJECT *a)
        +	{
        +	const unsigned int *op;
        +	ADDED_OBJ ad,*adp;
        +
        +	if (a == NULL)
        +		return(NID_undef);
        +	if (a->nid != 0)
        +		return(a->nid);
        +
        +	if (added != NULL)
        +		{
        +		ad.type=ADDED_DATA;
        +		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
        +		adp=lh_ADDED_OBJ_retrieve(added,&ad);
        +		if (adp != NULL) return (adp->obj->nid);
        +		}
        +	op=OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
        +	if (op == NULL)
        +		return(NID_undef);
        +	return(nid_objs[*op].nid);
        +	}
        +
        +/* Convert an object name into an ASN1_OBJECT
        + * if "noname" is not set then search for short and long names first.
        + * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
        + * it can be used with any objects, not just registered ones.
        + */
        +
        +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
        +	{
        +	int nid = NID_undef;
        +	ASN1_OBJECT *op=NULL;
        +	unsigned char *buf;
        +	unsigned char *p;
        +	const unsigned char *cp;
        +	int i, j;
        +
        +	if(!no_name) {
        +		if( ((nid = OBJ_sn2nid(s)) != NID_undef) ||
        +			((nid = OBJ_ln2nid(s)) != NID_undef) ) 
        +					return OBJ_nid2obj(nid);
        +	}
        +
        +	/* Work out size of content octets */
        +	i=a2d_ASN1_OBJECT(NULL,0,s,-1);
        +	if (i <= 0) {
        +		/* Don't clear the error */
        +		/*ERR_clear_error();*/
        +		return NULL;
        +	}
        +	/* Work out total size */
        +	j = ASN1_object_size(0,i,V_ASN1_OBJECT);
        +
        +	if((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL;
        +
        +	p = buf;
        +	/* Write out tag+length */
        +	ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
        +	/* Write out contents */
        +	a2d_ASN1_OBJECT(p,i,s,-1);
        +
        +	cp=buf;
        +	op=d2i_ASN1_OBJECT(NULL,&cp,j);
        +	OPENSSL_free(buf);
        +	return op;
        +	}
        +
        +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
        +{
        +	int i,n=0,len,nid, first, use_bn;
        +	BIGNUM *bl;
        +	unsigned long l;
        +	const unsigned char *p;
        +	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
        +
        +	if ((a == NULL) || (a->data == NULL)) {
        +		buf[0]='\0';
        +		return(0);
        +	}
        +
        +
        +	if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
        +		{
        +		const char *s;
        +		s=OBJ_nid2ln(nid);
        +		if (s == NULL)
        +			s=OBJ_nid2sn(nid);
        +		if (s)
        +			{
        +			if (buf)
        +				BUF_strlcpy(buf,s,buf_len);
        +			n=strlen(s);
        +			return n;
        +			}
        +		}
        +
        +
        +	len=a->length;
        +	p=a->data;
        +
        +	first = 1;
        +	bl = NULL;
        +
        +	while (len > 0)
        +		{
        +		l=0;
        +		use_bn = 0;
        +		for (;;)
        +			{
        +			unsigned char c = *p++;
        +			len--;
        +			if ((len == 0) && (c & 0x80))
        +				goto err;
        +			if (use_bn)
        +				{
        +				if (!BN_add_word(bl, c & 0x7f))
        +					goto err;
        +				}
        +			else
        +				l |= c  & 0x7f;
        +			if (!(c & 0x80))
        +				break;
        +			if (!use_bn && (l > (ULONG_MAX >> 7L)))
        +				{
        +				if (!bl && !(bl = BN_new()))
        +					goto err;
        +				if (!BN_set_word(bl, l))
        +					goto err;
        +				use_bn = 1;
        +				}
        +			if (use_bn)
        +				{
        +				if (!BN_lshift(bl, bl, 7))
        +					goto err;
        +				}
        +			else
        +				l<<=7L;
        +			}
        +
        +		if (first)
        +			{
        +			first = 0;
        +			if (l >= 80)
        +				{
        +				i = 2;
        +				if (use_bn)
        +					{
        +					if (!BN_sub_word(bl, 80))
        +						goto err;
        +					}
        +				else
        +					l -= 80;
        +				}
        +			else
        +				{
        +				i=(int)(l/40);
        +				l-=(long)(i*40);
        +				}
        +			if (buf && (buf_len > 0))
        +				{
        +				*buf++ = i + '0';
        +				buf_len--;
        +				}
        +			n++;
        +			}
        +
        +		if (use_bn)
        +			{
        +			char *bndec;
        +			bndec = BN_bn2dec(bl);
        +			if (!bndec)
        +				goto err;
        +			i = strlen(bndec);
        +			if (buf)
        +				{
        +				if (buf_len > 0)
        +					{
        +					*buf++ = '.';
        +					buf_len--;
        +					}
        +				BUF_strlcpy(buf,bndec,buf_len);
        +				if (i > buf_len)
        +					{
        +					buf += buf_len;
        +					buf_len = 0;
        +					}
        +				else
        +					{
        +					buf+=i;
        +					buf_len-=i;
        +					}
        +				}
        +			n++;
        +			n += i;
        +			OPENSSL_free(bndec);
        +			}
        +		else
        +			{
        +			BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
        +			i=strlen(tbuf);
        +			if (buf && (buf_len > 0))
        +				{
        +				BUF_strlcpy(buf,tbuf,buf_len);
        +				if (i > buf_len)
        +					{
        +					buf += buf_len;
        +					buf_len = 0;
        +					}
        +				else
        +					{
        +					buf+=i;
        +					buf_len-=i;
        +					}
        +				}
        +			n+=i;
        +			l=0;
        +			}
        +		}
        +
        +	if (bl)
        +		BN_free(bl);
        +	return n;
        +
        +	err:
        +	if (bl)
        +		BN_free(bl);
        +	return -1;
        +}
        +
        +int OBJ_txt2nid(const char *s)
        +{
        +	ASN1_OBJECT *obj;
        +	int nid;
        +	obj = OBJ_txt2obj(s, 0);
        +	nid = OBJ_obj2nid(obj);
        +	ASN1_OBJECT_free(obj);
        +	return nid;
        +}
        +
        +int OBJ_ln2nid(const char *s)
        +	{
        +	ASN1_OBJECT o;
        +	const ASN1_OBJECT *oo= &o;
        +	ADDED_OBJ ad,*adp;
        +	const unsigned int *op;
        +
        +	o.ln=s;
        +	if (added != NULL)
        +		{
        +		ad.type=ADDED_LNAME;
        +		ad.obj= &o;
        +		adp=lh_ADDED_OBJ_retrieve(added,&ad);
        +		if (adp != NULL) return (adp->obj->nid);
        +		}
        +	op=OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
        +	if (op == NULL) return(NID_undef);
        +	return(nid_objs[*op].nid);
        +	}
        +
        +int OBJ_sn2nid(const char *s)
        +	{
        +	ASN1_OBJECT o;
        +	const ASN1_OBJECT *oo= &o;
        +	ADDED_OBJ ad,*adp;
        +	const unsigned int *op;
        +
        +	o.sn=s;
        +	if (added != NULL)
        +		{
        +		ad.type=ADDED_SNAME;
        +		ad.obj= &o;
        +		adp=lh_ADDED_OBJ_retrieve(added,&ad);
        +		if (adp != NULL) return (adp->obj->nid);
        +		}
        +	op=OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
        +	if (op == NULL) return(NID_undef);
        +	return(nid_objs[*op].nid);
        +	}
        +
        +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
        +			 int (*cmp)(const void *, const void *))
        +	{
        +	return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
        +	}
        +
        +const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
        +			    int size,
        +			    int (*cmp)(const void *, const void *),
        +			    int flags)
        +	{
        +	const char *base=base_;
        +	int l,h,i=0,c=0;
        +	const char *p = NULL;
        +
        +	if (num == 0) return(NULL);
        +	l=0;
        +	h=num;
        +	while (l < h)
        +		{
        +		i=(l+h)/2;
        +		p= &(base[i*size]);
        +		c=(*cmp)(key,p);
        +		if (c < 0)
        +			h=i;
        +		else if (c > 0)
        +			l=i+1;
        +		else
        +			break;
        +		}
        +#ifdef CHARSET_EBCDIC
        +/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
        + * I don't have perl (yet), we revert to a *LINEAR* search
        + * when the object wasn't found in the binary search.
        + */
        +	if (c != 0)
        +		{
        +		for (i=0; i<num; ++i)
        +			{
        +			p= &(base[i*size]);
        +			c = (*cmp)(key,p);
        +			if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
        +				return p;
        +			}
        +		}
        +#endif
        +	if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
        +		p = NULL;
        +	else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH))
        +		{
        +		while(i > 0 && (*cmp)(key,&(base[(i-1)*size])) == 0)
        +			i--;
        +		p = &(base[i*size]);
        +		}
        +	return(p);
        +	}
        +
        +int OBJ_create_objects(BIO *in)
        +	{
        +	MS_STATIC char buf[512];
        +	int i,num=0;
        +	char *o,*s,*l=NULL;
        +
        +	for (;;)
        +		{
        +		s=o=NULL;
        +		i=BIO_gets(in,buf,512);
        +		if (i <= 0) return(num);
        +		buf[i-1]='\0';
        +		if (!isalnum((unsigned char)buf[0])) return(num);
        +		o=s=buf;
        +		while (isdigit((unsigned char)*s) || (*s == '.'))
        +			s++;
        +		if (*s != '\0')
        +			{
        +			*(s++)='\0';
        +			while (isspace((unsigned char)*s))
        +				s++;
        +			if (*s == '\0')
        +				s=NULL;
        +			else
        +				{
        +				l=s;
        +				while ((*l != '\0') && !isspace((unsigned char)*l))
        +					l++;
        +				if (*l != '\0')
        +					{
        +					*(l++)='\0';
        +					while (isspace((unsigned char)*l))
        +						l++;
        +					if (*l == '\0') l=NULL;
        +					}
        +				else
        +					l=NULL;
        +				}
        +			}
        +		else
        +			s=NULL;
        +		if ((o == NULL) || (*o == '\0')) return(num);
        +		if (!OBJ_create(o,s,l)) return(num);
        +		num++;
        +		}
        +	/* return(num); */
        +	}
        +
        +int OBJ_create(const char *oid, const char *sn, const char *ln)
        +	{
        +	int ok=0;
        +	ASN1_OBJECT *op=NULL;
        +	unsigned char *buf;
        +	int i;
        +
        +	i=a2d_ASN1_OBJECT(NULL,0,oid,-1);
        +	if (i <= 0) return(0);
        +
        +	if ((buf=(unsigned char *)OPENSSL_malloc(i)) == NULL)
        +		{
        +		OBJerr(OBJ_F_OBJ_CREATE,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	i=a2d_ASN1_OBJECT(buf,i,oid,-1);
        +	if (i == 0)
        +		goto err;
        +	op=(ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1),buf,i,sn,ln);
        +	if (op == NULL) 
        +		goto err;
        +	ok=OBJ_add_object(op);
        +err:
        +	ASN1_OBJECT_free(op);
        +	OPENSSL_free(buf);
        +	return(ok);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_dat.h b/vendor/openssl/openssl/crypto/objects/obj_dat.h
        new file mode 100644
        index 000000000..d404ad07c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_dat.h
        @@ -0,0 +1,5102 @@
        +/* crypto/objects/obj_dat.h */
        +
        +/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
        + * following command:
        + * perl obj_dat.pl obj_mac.h obj_dat.h
        + */
        +
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#define NUM_NID 920
        +#define NUM_SN 913
        +#define NUM_LN 913
        +#define NUM_OBJ 857
        +
        +static const unsigned char lvalues[5980]={
        +0x00,                                        /* [  0] OBJ_undef */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,     /* [ 14] OBJ_md2 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,     /* [ 22] OBJ_md5 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,     /* [ 30] OBJ_rc4 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 38] OBJ_rsaEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 47] OBJ_md2WithRSAEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 56] OBJ_md5WithRSAEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 65] OBJ_pbeWithMD2AndDES_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 74] OBJ_pbeWithMD5AndDES_CBC */
        +0x55,                                        /* [ 83] OBJ_X500 */
        +0x55,0x04,                                   /* [ 84] OBJ_X509 */
        +0x55,0x04,0x03,                              /* [ 86] OBJ_commonName */
        +0x55,0x04,0x06,                              /* [ 89] OBJ_countryName */
        +0x55,0x04,0x07,                              /* [ 92] OBJ_localityName */
        +0x55,0x04,0x08,                              /* [ 95] OBJ_stateOrProvinceName */
        +0x55,0x04,0x0A,                              /* [ 98] OBJ_organizationName */
        +0x55,0x04,0x0B,                              /* [101] OBJ_organizationalUnitName */
        +0x55,0x08,0x01,0x01,                         /* [104] OBJ_rsa */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,     /* [108] OBJ_pkcs7 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [116] OBJ_pkcs7_data */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [125] OBJ_pkcs7_signed */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [134] OBJ_pkcs7_enveloped */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [143] OBJ_pkcs7_signedAndEnveloped */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [152] OBJ_pkcs7_digest */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [161] OBJ_pkcs7_encrypted */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,     /* [170] OBJ_pkcs3 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [178] OBJ_dhKeyAgreement */
        +0x2B,0x0E,0x03,0x02,0x06,                    /* [187] OBJ_des_ecb */
        +0x2B,0x0E,0x03,0x02,0x09,                    /* [192] OBJ_des_cfb64 */
        +0x2B,0x0E,0x03,0x02,0x07,                    /* [197] OBJ_des_cbc */
        +0x2B,0x0E,0x03,0x02,0x11,                    /* [202] OBJ_des_ede_ecb */
        +0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [207] OBJ_idea_cbc */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,     /* [218] OBJ_rc2_cbc */
        +0x2B,0x0E,0x03,0x02,0x12,                    /* [226] OBJ_sha */
        +0x2B,0x0E,0x03,0x02,0x0F,                    /* [231] OBJ_shaWithRSAEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07,     /* [236] OBJ_des_ede3_cbc */
        +0x2B,0x0E,0x03,0x02,0x08,                    /* [244] OBJ_des_ofb64 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,     /* [249] OBJ_pkcs9 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [257] OBJ_pkcs9_emailAddress */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [266] OBJ_pkcs9_unstructuredName */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [275] OBJ_pkcs9_contentType */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [284] OBJ_pkcs9_messageDigest */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [293] OBJ_pkcs9_signingTime */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [302] OBJ_pkcs9_countersignature */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [311] OBJ_pkcs9_challengePassword */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [320] OBJ_pkcs9_unstructuredAddress */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [329] OBJ_pkcs9_extCertAttributes */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,          /* [338] OBJ_netscape */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,     /* [345] OBJ_netscape_cert_extension */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,     /* [353] OBJ_netscape_data_type */
        +0x2B,0x0E,0x03,0x02,0x1A,                    /* [361] OBJ_sha1 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [366] OBJ_sha1WithRSAEncryption */
        +0x2B,0x0E,0x03,0x02,0x0D,                    /* [375] OBJ_dsaWithSHA */
        +0x2B,0x0E,0x03,0x02,0x0C,                    /* [380] OBJ_dsa_2 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [385] OBJ_pbeWithSHA1AndRC2_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [394] OBJ_id_pbkdf2 */
        +0x2B,0x0E,0x03,0x02,0x1B,                    /* [403] OBJ_dsaWithSHA1_2 */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [408] OBJ_netscape_cert_type */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [417] OBJ_netscape_base_url */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [426] OBJ_netscape_revocation_url */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [435] OBJ_netscape_ca_revocation_url */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [444] OBJ_netscape_renewal_url */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [453] OBJ_netscape_ca_policy_url */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [462] OBJ_netscape_ssl_server_name */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [471] OBJ_netscape_comment */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [480] OBJ_netscape_cert_sequence */
        +0x55,0x1D,                                   /* [489] OBJ_id_ce */
        +0x55,0x1D,0x0E,                              /* [491] OBJ_subject_key_identifier */
        +0x55,0x1D,0x0F,                              /* [494] OBJ_key_usage */
        +0x55,0x1D,0x10,                              /* [497] OBJ_private_key_usage_period */
        +0x55,0x1D,0x11,                              /* [500] OBJ_subject_alt_name */
        +0x55,0x1D,0x12,                              /* [503] OBJ_issuer_alt_name */
        +0x55,0x1D,0x13,                              /* [506] OBJ_basic_constraints */
        +0x55,0x1D,0x14,                              /* [509] OBJ_crl_number */
        +0x55,0x1D,0x20,                              /* [512] OBJ_certificate_policies */
        +0x55,0x1D,0x23,                              /* [515] OBJ_authority_key_identifier */
        +0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [518] OBJ_bf_cbc */
        +0x55,0x08,0x03,0x65,                         /* [527] OBJ_mdc2 */
        +0x55,0x08,0x03,0x64,                         /* [531] OBJ_mdc2WithRSA */
        +0x55,0x04,0x2A,                              /* [535] OBJ_givenName */
        +0x55,0x04,0x04,                              /* [538] OBJ_surname */
        +0x55,0x04,0x2B,                              /* [541] OBJ_initials */
        +0x55,0x1D,0x1F,                              /* [544] OBJ_crl_distribution_points */
        +0x2B,0x0E,0x03,0x02,0x03,                    /* [547] OBJ_md5WithRSA */
        +0x55,0x04,0x05,                              /* [552] OBJ_serialNumber */
        +0x55,0x04,0x0C,                              /* [555] OBJ_title */
        +0x55,0x04,0x0D,                              /* [558] OBJ_description */
        +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [561] OBJ_cast5_cbc */
        +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [570] OBJ_pbeWithMD5AndCast5_CBC */
        +0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,          /* [579] OBJ_dsaWithSHA1 */
        +0x2B,0x0E,0x03,0x02,0x1D,                    /* [586] OBJ_sha1WithRSA */
        +0x2A,0x86,0x48,0xCE,0x38,0x04,0x01,          /* [591] OBJ_dsa */
        +0x2B,0x24,0x03,0x02,0x01,                    /* [598] OBJ_ripemd160 */
        +0x2B,0x24,0x03,0x03,0x01,0x02,               /* [603] OBJ_ripemd160WithRSA */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08,     /* [609] OBJ_rc5_cbc */
        +0x29,0x01,0x01,0x85,0x1A,0x01,               /* [617] OBJ_rle_compression */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [623] OBJ_zlib_compression */
        +0x55,0x1D,0x25,                              /* [634] OBJ_ext_key_usage */
        +0x2B,0x06,0x01,0x05,0x05,0x07,               /* [637] OBJ_id_pkix */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,          /* [643] OBJ_id_kp */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,     /* [650] OBJ_server_auth */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,     /* [658] OBJ_client_auth */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,     /* [666] OBJ_code_sign */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,     /* [674] OBJ_email_protect */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,     /* [682] OBJ_time_stamp */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [690] OBJ_ms_code_ind */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [700] OBJ_ms_code_com */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [710] OBJ_ms_ctl_sign */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [720] OBJ_ms_sgc */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [730] OBJ_ms_efs */
        +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [740] OBJ_ns_sgc */
        +0x55,0x1D,0x1B,                              /* [749] OBJ_delta_crl */
        +0x55,0x1D,0x15,                              /* [752] OBJ_crl_reason */
        +0x55,0x1D,0x18,                              /* [755] OBJ_invalidity_date */
        +0x2B,0x65,0x01,0x04,0x01,                    /* [758] OBJ_sxnet */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [763] OBJ_pbe_WithSHA1And128BitRC4 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [773] OBJ_pbe_WithSHA1And40BitRC4 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [783] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [793] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [803] OBJ_pbe_WithSHA1And128BitRC2_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [813] OBJ_pbe_WithSHA1And40BitRC2_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [823] OBJ_keyBag */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [834] OBJ_pkcs8ShroudedKeyBag */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [845] OBJ_certBag */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [856] OBJ_crlBag */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [867] OBJ_secretBag */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [878] OBJ_safeContentsBag */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [889] OBJ_friendlyName */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [898] OBJ_localKeyID */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [907] OBJ_x509Certificate */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [917] OBJ_sdsiCertificate */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [927] OBJ_x509Crl */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [937] OBJ_pbes2 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [946] OBJ_pbmac1 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,     /* [955] OBJ_hmacWithSHA1 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,     /* [963] OBJ_id_qt_cps */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,     /* [971] OBJ_id_qt_unotice */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [979] OBJ_SMIMECapabilities */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [988] OBJ_pbeWithMD2AndRC2_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [997] OBJ_pbeWithMD5AndRC2_CBC */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1006] OBJ_pbeWithSHA1AndDES_CBC */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1015] OBJ_ms_ext_req */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1025] OBJ_ext_req */
        +0x55,0x04,0x29,                              /* [1034] OBJ_name */
        +0x55,0x04,0x2E,                              /* [1037] OBJ_dnQualifier */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,          /* [1040] OBJ_id_pe */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,          /* [1047] OBJ_id_ad */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,     /* [1054] OBJ_info_access */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,     /* [1062] OBJ_ad_OCSP */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,     /* [1070] OBJ_ad_ca_issuers */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,     /* [1078] OBJ_OCSP_sign */
        +0x28,                                        /* [1086] OBJ_iso */
        +0x2A,                                        /* [1087] OBJ_member_body */
        +0x2A,0x86,0x48,                              /* [1088] OBJ_ISO_US */
        +0x2A,0x86,0x48,0xCE,0x38,                    /* [1091] OBJ_X9_57 */
        +0x2A,0x86,0x48,0xCE,0x38,0x04,               /* [1096] OBJ_X9cm */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,     /* [1102] OBJ_pkcs1 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,     /* [1110] OBJ_pkcs5 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1118] OBJ_SMIME */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1127] OBJ_id_smime_mod */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1137] OBJ_id_smime_ct */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1147] OBJ_id_smime_aa */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1157] OBJ_id_smime_alg */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1167] OBJ_id_smime_cd */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1177] OBJ_id_smime_spq */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1187] OBJ_id_smime_cti */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1197] OBJ_id_smime_mod_cms */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1208] OBJ_id_smime_mod_ess */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1219] OBJ_id_smime_mod_oid */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1230] OBJ_id_smime_mod_msg_v3 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1241] OBJ_id_smime_mod_ets_eSignature_88 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1252] OBJ_id_smime_mod_ets_eSignature_97 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1263] OBJ_id_smime_mod_ets_eSigPolicy_88 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1274] OBJ_id_smime_mod_ets_eSigPolicy_97 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1285] OBJ_id_smime_ct_receipt */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1296] OBJ_id_smime_ct_authData */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1307] OBJ_id_smime_ct_publishCert */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1318] OBJ_id_smime_ct_TSTInfo */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1329] OBJ_id_smime_ct_TDTInfo */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1340] OBJ_id_smime_ct_contentInfo */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1351] OBJ_id_smime_ct_DVCSRequestData */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1362] OBJ_id_smime_ct_DVCSResponseData */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1373] OBJ_id_smime_aa_receiptRequest */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1384] OBJ_id_smime_aa_securityLabel */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1395] OBJ_id_smime_aa_mlExpandHistory */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1406] OBJ_id_smime_aa_contentHint */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1417] OBJ_id_smime_aa_msgSigDigest */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1428] OBJ_id_smime_aa_encapContentType */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1439] OBJ_id_smime_aa_contentIdentifier */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1450] OBJ_id_smime_aa_macValue */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1461] OBJ_id_smime_aa_equivalentLabels */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1472] OBJ_id_smime_aa_contentReference */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1483] OBJ_id_smime_aa_encrypKeyPref */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1494] OBJ_id_smime_aa_signingCertificate */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1505] OBJ_id_smime_aa_smimeEncryptCerts */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1516] OBJ_id_smime_aa_timeStampToken */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1527] OBJ_id_smime_aa_ets_sigPolicyId */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1538] OBJ_id_smime_aa_ets_commitmentType */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1549] OBJ_id_smime_aa_ets_signerLocation */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1560] OBJ_id_smime_aa_ets_signerAttr */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1571] OBJ_id_smime_aa_ets_otherSigCert */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1582] OBJ_id_smime_aa_ets_contentTimestamp */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1593] OBJ_id_smime_aa_ets_CertificateRefs */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1604] OBJ_id_smime_aa_ets_RevocationRefs */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1615] OBJ_id_smime_aa_ets_certValues */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1626] OBJ_id_smime_aa_ets_revocationValues */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1637] OBJ_id_smime_aa_ets_escTimeStamp */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1648] OBJ_id_smime_aa_ets_certCRLTimestamp */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1659] OBJ_id_smime_aa_ets_archiveTimeStamp */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1670] OBJ_id_smime_aa_signatureType */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1681] OBJ_id_smime_aa_dvcs_dvc */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1692] OBJ_id_smime_alg_ESDHwith3DES */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1703] OBJ_id_smime_alg_ESDHwithRC2 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1714] OBJ_id_smime_alg_3DESwrap */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1725] OBJ_id_smime_alg_RC2wrap */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1736] OBJ_id_smime_alg_ESDH */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1747] OBJ_id_smime_alg_CMS3DESwrap */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1758] OBJ_id_smime_alg_CMSRC2wrap */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1769] OBJ_id_smime_cd_ldap */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1780] OBJ_id_smime_spq_ets_sqt_uri */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1791] OBJ_id_smime_spq_ets_sqt_unotice */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1802] OBJ_id_smime_cti_ets_proofOfOrigin */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1813] OBJ_id_smime_cti_ets_proofOfReceipt */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1824] OBJ_id_smime_cti_ets_proofOfDelivery */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1835] OBJ_id_smime_cti_ets_proofOfSender */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1846] OBJ_id_smime_cti_ets_proofOfApproval */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1857] OBJ_id_smime_cti_ets_proofOfCreation */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,     /* [1868] OBJ_md4 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,          /* [1876] OBJ_id_pkix_mod */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,          /* [1883] OBJ_id_qt */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,          /* [1890] OBJ_id_it */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,          /* [1897] OBJ_id_pkip */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,          /* [1904] OBJ_id_alg */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,          /* [1911] OBJ_id_cmc */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,          /* [1918] OBJ_id_on */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,          /* [1925] OBJ_id_pda */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,          /* [1932] OBJ_id_aca */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,          /* [1939] OBJ_id_qcs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,          /* [1946] OBJ_id_cct */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,     /* [1953] OBJ_id_pkix1_explicit_88 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,     /* [1961] OBJ_id_pkix1_implicit_88 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,     /* [1969] OBJ_id_pkix1_explicit_93 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,     /* [1977] OBJ_id_pkix1_implicit_93 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,     /* [1985] OBJ_id_mod_crmf */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,     /* [1993] OBJ_id_mod_cmc */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,     /* [2001] OBJ_id_mod_kea_profile_88 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,     /* [2009] OBJ_id_mod_kea_profile_93 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,     /* [2017] OBJ_id_mod_cmp */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,     /* [2025] OBJ_id_mod_qualified_cert_88 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,     /* [2033] OBJ_id_mod_qualified_cert_93 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,     /* [2041] OBJ_id_mod_attribute_cert */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,     /* [2049] OBJ_id_mod_timestamp_protocol */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,     /* [2057] OBJ_id_mod_ocsp */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,     /* [2065] OBJ_id_mod_dvcs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,     /* [2073] OBJ_id_mod_cmp2000 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,     /* [2081] OBJ_biometricInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,     /* [2089] OBJ_qcStatements */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,     /* [2097] OBJ_ac_auditEntity */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,     /* [2105] OBJ_ac_targeting */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,     /* [2113] OBJ_aaControls */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,     /* [2121] OBJ_sbgp_ipAddrBlock */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,     /* [2129] OBJ_sbgp_autonomousSysNum */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,     /* [2137] OBJ_sbgp_routerIdentifier */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,     /* [2145] OBJ_textNotice */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,     /* [2153] OBJ_ipsecEndSystem */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,     /* [2161] OBJ_ipsecTunnel */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,     /* [2169] OBJ_ipsecUser */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,     /* [2177] OBJ_dvcs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,     /* [2185] OBJ_id_it_caProtEncCert */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,     /* [2193] OBJ_id_it_signKeyPairTypes */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,     /* [2201] OBJ_id_it_encKeyPairTypes */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,     /* [2209] OBJ_id_it_preferredSymmAlg */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,     /* [2217] OBJ_id_it_caKeyUpdateInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,     /* [2225] OBJ_id_it_currentCRL */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,     /* [2233] OBJ_id_it_unsupportedOIDs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,     /* [2241] OBJ_id_it_subscriptionRequest */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,     /* [2249] OBJ_id_it_subscriptionResponse */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,     /* [2257] OBJ_id_it_keyPairParamReq */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,     /* [2265] OBJ_id_it_keyPairParamRep */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,     /* [2273] OBJ_id_it_revPassphrase */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,     /* [2281] OBJ_id_it_implicitConfirm */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,     /* [2289] OBJ_id_it_confirmWaitTime */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,     /* [2297] OBJ_id_it_origPKIMessage */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,     /* [2305] OBJ_id_regCtrl */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,     /* [2313] OBJ_id_regInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2321] OBJ_id_regCtrl_regToken */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2330] OBJ_id_regCtrl_authenticator */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2339] OBJ_id_regCtrl_pkiPublicationInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2348] OBJ_id_regCtrl_pkiArchiveOptions */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2357] OBJ_id_regCtrl_oldCertID */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2366] OBJ_id_regCtrl_protocolEncrKey */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2375] OBJ_id_regInfo_utf8Pairs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2384] OBJ_id_regInfo_certReq */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,     /* [2393] OBJ_id_alg_des40 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,     /* [2401] OBJ_id_alg_noSignature */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,     /* [2409] OBJ_id_alg_dh_sig_hmac_sha1 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,     /* [2417] OBJ_id_alg_dh_pop */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,     /* [2425] OBJ_id_cmc_statusInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,     /* [2433] OBJ_id_cmc_identification */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,     /* [2441] OBJ_id_cmc_identityProof */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,     /* [2449] OBJ_id_cmc_dataReturn */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,     /* [2457] OBJ_id_cmc_transactionId */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,     /* [2465] OBJ_id_cmc_senderNonce */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,     /* [2473] OBJ_id_cmc_recipientNonce */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,     /* [2481] OBJ_id_cmc_addExtensions */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,     /* [2489] OBJ_id_cmc_encryptedPOP */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,     /* [2497] OBJ_id_cmc_decryptedPOP */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,     /* [2505] OBJ_id_cmc_lraPOPWitness */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,     /* [2513] OBJ_id_cmc_getCert */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,     /* [2521] OBJ_id_cmc_getCRL */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,     /* [2529] OBJ_id_cmc_revokeRequest */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,     /* [2537] OBJ_id_cmc_regInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,     /* [2545] OBJ_id_cmc_responseInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,     /* [2553] OBJ_id_cmc_queryPending */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,     /* [2561] OBJ_id_cmc_popLinkRandom */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,     /* [2569] OBJ_id_cmc_popLinkWitness */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,     /* [2577] OBJ_id_cmc_confirmCertAcceptance */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,     /* [2585] OBJ_id_on_personalData */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,     /* [2593] OBJ_id_pda_dateOfBirth */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,     /* [2601] OBJ_id_pda_placeOfBirth */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,     /* [2609] OBJ_id_pda_gender */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,     /* [2617] OBJ_id_pda_countryOfCitizenship */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,     /* [2625] OBJ_id_pda_countryOfResidence */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,     /* [2633] OBJ_id_aca_authenticationInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,     /* [2641] OBJ_id_aca_accessIdentity */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,     /* [2649] OBJ_id_aca_chargingIdentity */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,     /* [2657] OBJ_id_aca_group */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,     /* [2665] OBJ_id_aca_role */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,     /* [2673] OBJ_id_qcs_pkixQCSyntax_v1 */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,     /* [2681] OBJ_id_cct_crs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,     /* [2689] OBJ_id_cct_PKIData */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,     /* [2697] OBJ_id_cct_PKIResponse */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,     /* [2705] OBJ_ad_timeStamping */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,     /* [2713] OBJ_ad_dvcs */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2721] OBJ_id_pkix_OCSP_basic */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2730] OBJ_id_pkix_OCSP_Nonce */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2739] OBJ_id_pkix_OCSP_CrlID */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2748] OBJ_id_pkix_OCSP_acceptableResponses */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2757] OBJ_id_pkix_OCSP_noCheck */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2766] OBJ_id_pkix_OCSP_archiveCutoff */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2775] OBJ_id_pkix_OCSP_serviceLocator */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2784] OBJ_id_pkix_OCSP_extendedStatus */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2793] OBJ_id_pkix_OCSP_valid */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2802] OBJ_id_pkix_OCSP_path */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2811] OBJ_id_pkix_OCSP_trustRoot */
        +0x2B,0x0E,0x03,0x02,                         /* [2820] OBJ_algorithm */
        +0x2B,0x0E,0x03,0x02,0x0B,                    /* [2824] OBJ_rsaSignature */
        +0x55,0x08,                                   /* [2829] OBJ_X500algorithms */
        +0x2B,                                        /* [2831] OBJ_org */
        +0x2B,0x06,                                   /* [2832] OBJ_dod */
        +0x2B,0x06,0x01,                              /* [2834] OBJ_iana */
        +0x2B,0x06,0x01,0x01,                         /* [2837] OBJ_Directory */
        +0x2B,0x06,0x01,0x02,                         /* [2841] OBJ_Management */
        +0x2B,0x06,0x01,0x03,                         /* [2845] OBJ_Experimental */
        +0x2B,0x06,0x01,0x04,                         /* [2849] OBJ_Private */
        +0x2B,0x06,0x01,0x05,                         /* [2853] OBJ_Security */
        +0x2B,0x06,0x01,0x06,                         /* [2857] OBJ_SNMPv2 */
        +0x2B,0x06,0x01,0x07,                         /* [2861] OBJ_Mail */
        +0x2B,0x06,0x01,0x04,0x01,                    /* [2865] OBJ_Enterprises */
        +0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2870] OBJ_dcObject */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2879] OBJ_domainComponent */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2889] OBJ_Domain */
        +0x00,                                        /* [2899] OBJ_joint_iso_ccitt */
        +0x55,0x01,0x05,                              /* [2900] OBJ_selected_attribute_types */
        +0x55,0x01,0x05,0x37,                         /* [2903] OBJ_clearance */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2907] OBJ_md4WithRSAEncryption */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,     /* [2916] OBJ_ac_proxying */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,     /* [2924] OBJ_sinfo_access */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,     /* [2932] OBJ_id_aca_encAttrs */
        +0x55,0x04,0x48,                              /* [2940] OBJ_role */
        +0x55,0x1D,0x24,                              /* [2943] OBJ_policy_constraints */
        +0x55,0x1D,0x37,                              /* [2946] OBJ_target_information */
        +0x55,0x1D,0x38,                              /* [2949] OBJ_no_rev_avail */
        +0x00,                                        /* [2952] OBJ_ccitt */
        +0x2A,0x86,0x48,0xCE,0x3D,                    /* [2953] OBJ_ansi_X9_62 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,          /* [2958] OBJ_X9_62_prime_field */
        +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,          /* [2965] OBJ_X9_62_characteristic_two_field */
        +0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,          /* [2972] OBJ_X9_62_id_ecPublicKey */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,     /* [2979] OBJ_X9_62_prime192v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,     /* [2987] OBJ_X9_62_prime192v2 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,     /* [2995] OBJ_X9_62_prime192v3 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,     /* [3003] OBJ_X9_62_prime239v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,     /* [3011] OBJ_X9_62_prime239v2 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,     /* [3019] OBJ_X9_62_prime239v3 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,     /* [3027] OBJ_X9_62_prime256v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,          /* [3035] OBJ_ecdsa_with_SHA1 */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3042] OBJ_ms_csp_name */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3051] OBJ_aes_128_ecb */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3060] OBJ_aes_128_cbc */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3069] OBJ_aes_128_ofb128 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3078] OBJ_aes_128_cfb128 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3087] OBJ_aes_192_ecb */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3096] OBJ_aes_192_cbc */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3105] OBJ_aes_192_ofb128 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3114] OBJ_aes_192_cfb128 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3123] OBJ_aes_256_ecb */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3132] OBJ_aes_256_cbc */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3141] OBJ_aes_256_ofb128 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3150] OBJ_aes_256_cfb128 */
        +0x55,0x1D,0x17,                              /* [3159] OBJ_hold_instruction_code */
        +0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,          /* [3162] OBJ_hold_instruction_none */
        +0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,          /* [3169] OBJ_hold_instruction_call_issuer */
        +0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,          /* [3176] OBJ_hold_instruction_reject */
        +0x09,                                        /* [3183] OBJ_data */
        +0x09,0x92,0x26,                              /* [3184] OBJ_pss */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,          /* [3187] OBJ_ucl */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,     /* [3194] OBJ_pilot */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3202] OBJ_pilotAttributeType */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3211] OBJ_pilotAttributeSyntax */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3220] OBJ_pilotObjectClass */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3229] OBJ_pilotGroups */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3238] OBJ_iA5StringSyntax */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3248] OBJ_caseIgnoreIA5StringSyntax */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3258] OBJ_pilotObject */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3268] OBJ_pilotPerson */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3278] OBJ_account */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3288] OBJ_document */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3298] OBJ_room */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3308] OBJ_documentSeries */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3318] OBJ_rFC822localPart */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3328] OBJ_dNSDomain */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3338] OBJ_domainRelatedObject */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3348] OBJ_friendlyCountry */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3358] OBJ_simpleSecurityObject */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3368] OBJ_pilotOrganization */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3378] OBJ_pilotDSA */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3388] OBJ_qualityLabelledData */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3398] OBJ_userId */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3408] OBJ_textEncodedORAddress */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3418] OBJ_rfc822Mailbox */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3428] OBJ_info */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3438] OBJ_favouriteDrink */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3448] OBJ_roomNumber */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3458] OBJ_photo */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3468] OBJ_userClass */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3478] OBJ_host */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3488] OBJ_manager */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3498] OBJ_documentIdentifier */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3508] OBJ_documentTitle */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3518] OBJ_documentVersion */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3528] OBJ_documentAuthor */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3538] OBJ_documentLocation */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3548] OBJ_homeTelephoneNumber */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3558] OBJ_secretary */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3568] OBJ_otherMailbox */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3578] OBJ_lastModifiedTime */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3588] OBJ_lastModifiedBy */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3598] OBJ_aRecord */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3608] OBJ_pilotAttributeType27 */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3618] OBJ_mXRecord */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3628] OBJ_nSRecord */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3638] OBJ_sOARecord */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3648] OBJ_cNAMERecord */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3658] OBJ_associatedDomain */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3668] OBJ_associatedName */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3678] OBJ_homePostalAddress */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3688] OBJ_personalTitle */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3698] OBJ_mobileTelephoneNumber */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3708] OBJ_pagerTelephoneNumber */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3718] OBJ_friendlyCountryName */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3728] OBJ_organizationalStatus */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3738] OBJ_janetMailbox */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3748] OBJ_mailPreferenceOption */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3758] OBJ_buildingName */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3768] OBJ_dSAQuality */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3778] OBJ_singleLevelQuality */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3788] OBJ_subtreeMinimumQuality */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3798] OBJ_subtreeMaximumQuality */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3808] OBJ_personalSignature */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3818] OBJ_dITRedirect */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3828] OBJ_audio */
        +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3838] OBJ_documentPublisher */
        +0x55,0x04,0x2D,                              /* [3848] OBJ_x500UniqueIdentifier */
        +0x2B,0x06,0x01,0x07,0x01,                    /* [3851] OBJ_mime_mhs */
        +0x2B,0x06,0x01,0x07,0x01,0x01,               /* [3856] OBJ_mime_mhs_headings */
        +0x2B,0x06,0x01,0x07,0x01,0x02,               /* [3862] OBJ_mime_mhs_bodies */
        +0x2B,0x06,0x01,0x07,0x01,0x01,0x01,          /* [3868] OBJ_id_hex_partial_message */
        +0x2B,0x06,0x01,0x07,0x01,0x01,0x02,          /* [3875] OBJ_id_hex_multipart_message */
        +0x55,0x04,0x2C,                              /* [3882] OBJ_generationQualifier */
        +0x55,0x04,0x41,                              /* [3885] OBJ_pseudonym */
        +0x67,0x2A,                                   /* [3888] OBJ_id_set */
        +0x67,0x2A,0x00,                              /* [3890] OBJ_set_ctype */
        +0x67,0x2A,0x01,                              /* [3893] OBJ_set_msgExt */
        +0x67,0x2A,0x03,                              /* [3896] OBJ_set_attr */
        +0x67,0x2A,0x05,                              /* [3899] OBJ_set_policy */
        +0x67,0x2A,0x07,                              /* [3902] OBJ_set_certExt */
        +0x67,0x2A,0x08,                              /* [3905] OBJ_set_brand */
        +0x67,0x2A,0x00,0x00,                         /* [3908] OBJ_setct_PANData */
        +0x67,0x2A,0x00,0x01,                         /* [3912] OBJ_setct_PANToken */
        +0x67,0x2A,0x00,0x02,                         /* [3916] OBJ_setct_PANOnly */
        +0x67,0x2A,0x00,0x03,                         /* [3920] OBJ_setct_OIData */
        +0x67,0x2A,0x00,0x04,                         /* [3924] OBJ_setct_PI */
        +0x67,0x2A,0x00,0x05,                         /* [3928] OBJ_setct_PIData */
        +0x67,0x2A,0x00,0x06,                         /* [3932] OBJ_setct_PIDataUnsigned */
        +0x67,0x2A,0x00,0x07,                         /* [3936] OBJ_setct_HODInput */
        +0x67,0x2A,0x00,0x08,                         /* [3940] OBJ_setct_AuthResBaggage */
        +0x67,0x2A,0x00,0x09,                         /* [3944] OBJ_setct_AuthRevReqBaggage */
        +0x67,0x2A,0x00,0x0A,                         /* [3948] OBJ_setct_AuthRevResBaggage */
        +0x67,0x2A,0x00,0x0B,                         /* [3952] OBJ_setct_CapTokenSeq */
        +0x67,0x2A,0x00,0x0C,                         /* [3956] OBJ_setct_PInitResData */
        +0x67,0x2A,0x00,0x0D,                         /* [3960] OBJ_setct_PI_TBS */
        +0x67,0x2A,0x00,0x0E,                         /* [3964] OBJ_setct_PResData */
        +0x67,0x2A,0x00,0x10,                         /* [3968] OBJ_setct_AuthReqTBS */
        +0x67,0x2A,0x00,0x11,                         /* [3972] OBJ_setct_AuthResTBS */
        +0x67,0x2A,0x00,0x12,                         /* [3976] OBJ_setct_AuthResTBSX */
        +0x67,0x2A,0x00,0x13,                         /* [3980] OBJ_setct_AuthTokenTBS */
        +0x67,0x2A,0x00,0x14,                         /* [3984] OBJ_setct_CapTokenData */
        +0x67,0x2A,0x00,0x15,                         /* [3988] OBJ_setct_CapTokenTBS */
        +0x67,0x2A,0x00,0x16,                         /* [3992] OBJ_setct_AcqCardCodeMsg */
        +0x67,0x2A,0x00,0x17,                         /* [3996] OBJ_setct_AuthRevReqTBS */
        +0x67,0x2A,0x00,0x18,                         /* [4000] OBJ_setct_AuthRevResData */
        +0x67,0x2A,0x00,0x19,                         /* [4004] OBJ_setct_AuthRevResTBS */
        +0x67,0x2A,0x00,0x1A,                         /* [4008] OBJ_setct_CapReqTBS */
        +0x67,0x2A,0x00,0x1B,                         /* [4012] OBJ_setct_CapReqTBSX */
        +0x67,0x2A,0x00,0x1C,                         /* [4016] OBJ_setct_CapResData */
        +0x67,0x2A,0x00,0x1D,                         /* [4020] OBJ_setct_CapRevReqTBS */
        +0x67,0x2A,0x00,0x1E,                         /* [4024] OBJ_setct_CapRevReqTBSX */
        +0x67,0x2A,0x00,0x1F,                         /* [4028] OBJ_setct_CapRevResData */
        +0x67,0x2A,0x00,0x20,                         /* [4032] OBJ_setct_CredReqTBS */
        +0x67,0x2A,0x00,0x21,                         /* [4036] OBJ_setct_CredReqTBSX */
        +0x67,0x2A,0x00,0x22,                         /* [4040] OBJ_setct_CredResData */
        +0x67,0x2A,0x00,0x23,                         /* [4044] OBJ_setct_CredRevReqTBS */
        +0x67,0x2A,0x00,0x24,                         /* [4048] OBJ_setct_CredRevReqTBSX */
        +0x67,0x2A,0x00,0x25,                         /* [4052] OBJ_setct_CredRevResData */
        +0x67,0x2A,0x00,0x26,                         /* [4056] OBJ_setct_PCertReqData */
        +0x67,0x2A,0x00,0x27,                         /* [4060] OBJ_setct_PCertResTBS */
        +0x67,0x2A,0x00,0x28,                         /* [4064] OBJ_setct_BatchAdminReqData */
        +0x67,0x2A,0x00,0x29,                         /* [4068] OBJ_setct_BatchAdminResData */
        +0x67,0x2A,0x00,0x2A,                         /* [4072] OBJ_setct_CardCInitResTBS */
        +0x67,0x2A,0x00,0x2B,                         /* [4076] OBJ_setct_MeAqCInitResTBS */
        +0x67,0x2A,0x00,0x2C,                         /* [4080] OBJ_setct_RegFormResTBS */
        +0x67,0x2A,0x00,0x2D,                         /* [4084] OBJ_setct_CertReqData */
        +0x67,0x2A,0x00,0x2E,                         /* [4088] OBJ_setct_CertReqTBS */
        +0x67,0x2A,0x00,0x2F,                         /* [4092] OBJ_setct_CertResData */
        +0x67,0x2A,0x00,0x30,                         /* [4096] OBJ_setct_CertInqReqTBS */
        +0x67,0x2A,0x00,0x31,                         /* [4100] OBJ_setct_ErrorTBS */
        +0x67,0x2A,0x00,0x32,                         /* [4104] OBJ_setct_PIDualSignedTBE */
        +0x67,0x2A,0x00,0x33,                         /* [4108] OBJ_setct_PIUnsignedTBE */
        +0x67,0x2A,0x00,0x34,                         /* [4112] OBJ_setct_AuthReqTBE */
        +0x67,0x2A,0x00,0x35,                         /* [4116] OBJ_setct_AuthResTBE */
        +0x67,0x2A,0x00,0x36,                         /* [4120] OBJ_setct_AuthResTBEX */
        +0x67,0x2A,0x00,0x37,                         /* [4124] OBJ_setct_AuthTokenTBE */
        +0x67,0x2A,0x00,0x38,                         /* [4128] OBJ_setct_CapTokenTBE */
        +0x67,0x2A,0x00,0x39,                         /* [4132] OBJ_setct_CapTokenTBEX */
        +0x67,0x2A,0x00,0x3A,                         /* [4136] OBJ_setct_AcqCardCodeMsgTBE */
        +0x67,0x2A,0x00,0x3B,                         /* [4140] OBJ_setct_AuthRevReqTBE */
        +0x67,0x2A,0x00,0x3C,                         /* [4144] OBJ_setct_AuthRevResTBE */
        +0x67,0x2A,0x00,0x3D,                         /* [4148] OBJ_setct_AuthRevResTBEB */
        +0x67,0x2A,0x00,0x3E,                         /* [4152] OBJ_setct_CapReqTBE */
        +0x67,0x2A,0x00,0x3F,                         /* [4156] OBJ_setct_CapReqTBEX */
        +0x67,0x2A,0x00,0x40,                         /* [4160] OBJ_setct_CapResTBE */
        +0x67,0x2A,0x00,0x41,                         /* [4164] OBJ_setct_CapRevReqTBE */
        +0x67,0x2A,0x00,0x42,                         /* [4168] OBJ_setct_CapRevReqTBEX */
        +0x67,0x2A,0x00,0x43,                         /* [4172] OBJ_setct_CapRevResTBE */
        +0x67,0x2A,0x00,0x44,                         /* [4176] OBJ_setct_CredReqTBE */
        +0x67,0x2A,0x00,0x45,                         /* [4180] OBJ_setct_CredReqTBEX */
        +0x67,0x2A,0x00,0x46,                         /* [4184] OBJ_setct_CredResTBE */
        +0x67,0x2A,0x00,0x47,                         /* [4188] OBJ_setct_CredRevReqTBE */
        +0x67,0x2A,0x00,0x48,                         /* [4192] OBJ_setct_CredRevReqTBEX */
        +0x67,0x2A,0x00,0x49,                         /* [4196] OBJ_setct_CredRevResTBE */
        +0x67,0x2A,0x00,0x4A,                         /* [4200] OBJ_setct_BatchAdminReqTBE */
        +0x67,0x2A,0x00,0x4B,                         /* [4204] OBJ_setct_BatchAdminResTBE */
        +0x67,0x2A,0x00,0x4C,                         /* [4208] OBJ_setct_RegFormReqTBE */
        +0x67,0x2A,0x00,0x4D,                         /* [4212] OBJ_setct_CertReqTBE */
        +0x67,0x2A,0x00,0x4E,                         /* [4216] OBJ_setct_CertReqTBEX */
        +0x67,0x2A,0x00,0x4F,                         /* [4220] OBJ_setct_CertResTBE */
        +0x67,0x2A,0x00,0x50,                         /* [4224] OBJ_setct_CRLNotificationTBS */
        +0x67,0x2A,0x00,0x51,                         /* [4228] OBJ_setct_CRLNotificationResTBS */
        +0x67,0x2A,0x00,0x52,                         /* [4232] OBJ_setct_BCIDistributionTBS */
        +0x67,0x2A,0x01,0x01,                         /* [4236] OBJ_setext_genCrypt */
        +0x67,0x2A,0x01,0x03,                         /* [4240] OBJ_setext_miAuth */
        +0x67,0x2A,0x01,0x04,                         /* [4244] OBJ_setext_pinSecure */
        +0x67,0x2A,0x01,0x05,                         /* [4248] OBJ_setext_pinAny */
        +0x67,0x2A,0x01,0x07,                         /* [4252] OBJ_setext_track2 */
        +0x67,0x2A,0x01,0x08,                         /* [4256] OBJ_setext_cv */
        +0x67,0x2A,0x05,0x00,                         /* [4260] OBJ_set_policy_root */
        +0x67,0x2A,0x07,0x00,                         /* [4264] OBJ_setCext_hashedRoot */
        +0x67,0x2A,0x07,0x01,                         /* [4268] OBJ_setCext_certType */
        +0x67,0x2A,0x07,0x02,                         /* [4272] OBJ_setCext_merchData */
        +0x67,0x2A,0x07,0x03,                         /* [4276] OBJ_setCext_cCertRequired */
        +0x67,0x2A,0x07,0x04,                         /* [4280] OBJ_setCext_tunneling */
        +0x67,0x2A,0x07,0x05,                         /* [4284] OBJ_setCext_setExt */
        +0x67,0x2A,0x07,0x06,                         /* [4288] OBJ_setCext_setQualf */
        +0x67,0x2A,0x07,0x07,                         /* [4292] OBJ_setCext_PGWYcapabilities */
        +0x67,0x2A,0x07,0x08,                         /* [4296] OBJ_setCext_TokenIdentifier */
        +0x67,0x2A,0x07,0x09,                         /* [4300] OBJ_setCext_Track2Data */
        +0x67,0x2A,0x07,0x0A,                         /* [4304] OBJ_setCext_TokenType */
        +0x67,0x2A,0x07,0x0B,                         /* [4308] OBJ_setCext_IssuerCapabilities */
        +0x67,0x2A,0x03,0x00,                         /* [4312] OBJ_setAttr_Cert */
        +0x67,0x2A,0x03,0x01,                         /* [4316] OBJ_setAttr_PGWYcap */
        +0x67,0x2A,0x03,0x02,                         /* [4320] OBJ_setAttr_TokenType */
        +0x67,0x2A,0x03,0x03,                         /* [4324] OBJ_setAttr_IssCap */
        +0x67,0x2A,0x03,0x00,0x00,                    /* [4328] OBJ_set_rootKeyThumb */
        +0x67,0x2A,0x03,0x00,0x01,                    /* [4333] OBJ_set_addPolicy */
        +0x67,0x2A,0x03,0x02,0x01,                    /* [4338] OBJ_setAttr_Token_EMV */
        +0x67,0x2A,0x03,0x02,0x02,                    /* [4343] OBJ_setAttr_Token_B0Prime */
        +0x67,0x2A,0x03,0x03,0x03,                    /* [4348] OBJ_setAttr_IssCap_CVM */
        +0x67,0x2A,0x03,0x03,0x04,                    /* [4353] OBJ_setAttr_IssCap_T2 */
        +0x67,0x2A,0x03,0x03,0x05,                    /* [4358] OBJ_setAttr_IssCap_Sig */
        +0x67,0x2A,0x03,0x03,0x03,0x01,               /* [4363] OBJ_setAttr_GenCryptgrm */
        +0x67,0x2A,0x03,0x03,0x04,0x01,               /* [4369] OBJ_setAttr_T2Enc */
        +0x67,0x2A,0x03,0x03,0x04,0x02,               /* [4375] OBJ_setAttr_T2cleartxt */
        +0x67,0x2A,0x03,0x03,0x05,0x01,               /* [4381] OBJ_setAttr_TokICCsig */
        +0x67,0x2A,0x03,0x03,0x05,0x02,               /* [4387] OBJ_setAttr_SecDevSig */
        +0x67,0x2A,0x08,0x01,                         /* [4393] OBJ_set_brand_IATA_ATA */
        +0x67,0x2A,0x08,0x1E,                         /* [4397] OBJ_set_brand_Diners */
        +0x67,0x2A,0x08,0x22,                         /* [4401] OBJ_set_brand_AmericanExpress */
        +0x67,0x2A,0x08,0x23,                         /* [4405] OBJ_set_brand_JCB */
        +0x67,0x2A,0x08,0x04,                         /* [4409] OBJ_set_brand_Visa */
        +0x67,0x2A,0x08,0x05,                         /* [4413] OBJ_set_brand_MasterCard */
        +0x67,0x2A,0x08,0xAE,0x7B,                    /* [4417] OBJ_set_brand_Novus */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,     /* [4422] OBJ_des_cdmf */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4430] OBJ_rsaOAEPEncryptionSET */
        +0x00,                                        /* [4439] OBJ_itu_t */
        +0x50,                                        /* [4440] OBJ_joint_iso_itu_t */
        +0x67,                                        /* [4441] OBJ_international_organizations */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4442] OBJ_ms_smartcard_login */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4452] OBJ_ms_upn */
        +0x55,0x04,0x09,                              /* [4462] OBJ_streetAddress */
        +0x55,0x04,0x11,                              /* [4465] OBJ_postalCode */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,          /* [4468] OBJ_id_ppl */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,     /* [4475] OBJ_proxyCertInfo */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,     /* [4483] OBJ_id_ppl_anyLanguage */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,     /* [4491] OBJ_id_ppl_inheritAll */
        +0x55,0x1D,0x1E,                              /* [4499] OBJ_name_constraints */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,     /* [4502] OBJ_Independent */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4510] OBJ_sha256WithRSAEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4519] OBJ_sha384WithRSAEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4528] OBJ_sha512WithRSAEncryption */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4537] OBJ_sha224WithRSAEncryption */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4546] OBJ_sha256 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4555] OBJ_sha384 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4564] OBJ_sha512 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4573] OBJ_sha224 */
        +0x2B,                                        /* [4582] OBJ_identified_organization */
        +0x2B,0x81,0x04,                              /* [4583] OBJ_certicom_arc */
        +0x67,0x2B,                                   /* [4586] OBJ_wap */
        +0x67,0x2B,0x01,                              /* [4588] OBJ_wap_wsg */
        +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,     /* [4591] OBJ_X9_62_id_characteristic_two_basis */
        +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4599] OBJ_X9_62_onBasis */
        +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4608] OBJ_X9_62_tpBasis */
        +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4617] OBJ_X9_62_ppBasis */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,     /* [4626] OBJ_X9_62_c2pnb163v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,     /* [4634] OBJ_X9_62_c2pnb163v2 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,     /* [4642] OBJ_X9_62_c2pnb163v3 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,     /* [4650] OBJ_X9_62_c2pnb176v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,     /* [4658] OBJ_X9_62_c2tnb191v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,     /* [4666] OBJ_X9_62_c2tnb191v2 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,     /* [4674] OBJ_X9_62_c2tnb191v3 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,     /* [4682] OBJ_X9_62_c2onb191v4 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,     /* [4690] OBJ_X9_62_c2onb191v5 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,     /* [4698] OBJ_X9_62_c2pnb208w1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,     /* [4706] OBJ_X9_62_c2tnb239v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,     /* [4714] OBJ_X9_62_c2tnb239v2 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,     /* [4722] OBJ_X9_62_c2tnb239v3 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,     /* [4730] OBJ_X9_62_c2onb239v4 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,     /* [4738] OBJ_X9_62_c2onb239v5 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,     /* [4746] OBJ_X9_62_c2pnb272w1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,     /* [4754] OBJ_X9_62_c2pnb304w1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,     /* [4762] OBJ_X9_62_c2tnb359v1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,     /* [4770] OBJ_X9_62_c2pnb368w1 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,     /* [4778] OBJ_X9_62_c2tnb431r1 */
        +0x2B,0x81,0x04,0x00,0x06,                    /* [4786] OBJ_secp112r1 */
        +0x2B,0x81,0x04,0x00,0x07,                    /* [4791] OBJ_secp112r2 */
        +0x2B,0x81,0x04,0x00,0x1C,                    /* [4796] OBJ_secp128r1 */
        +0x2B,0x81,0x04,0x00,0x1D,                    /* [4801] OBJ_secp128r2 */
        +0x2B,0x81,0x04,0x00,0x09,                    /* [4806] OBJ_secp160k1 */
        +0x2B,0x81,0x04,0x00,0x08,                    /* [4811] OBJ_secp160r1 */
        +0x2B,0x81,0x04,0x00,0x1E,                    /* [4816] OBJ_secp160r2 */
        +0x2B,0x81,0x04,0x00,0x1F,                    /* [4821] OBJ_secp192k1 */
        +0x2B,0x81,0x04,0x00,0x20,                    /* [4826] OBJ_secp224k1 */
        +0x2B,0x81,0x04,0x00,0x21,                    /* [4831] OBJ_secp224r1 */
        +0x2B,0x81,0x04,0x00,0x0A,                    /* [4836] OBJ_secp256k1 */
        +0x2B,0x81,0x04,0x00,0x22,                    /* [4841] OBJ_secp384r1 */
        +0x2B,0x81,0x04,0x00,0x23,                    /* [4846] OBJ_secp521r1 */
        +0x2B,0x81,0x04,0x00,0x04,                    /* [4851] OBJ_sect113r1 */
        +0x2B,0x81,0x04,0x00,0x05,                    /* [4856] OBJ_sect113r2 */
        +0x2B,0x81,0x04,0x00,0x16,                    /* [4861] OBJ_sect131r1 */
        +0x2B,0x81,0x04,0x00,0x17,                    /* [4866] OBJ_sect131r2 */
        +0x2B,0x81,0x04,0x00,0x01,                    /* [4871] OBJ_sect163k1 */
        +0x2B,0x81,0x04,0x00,0x02,                    /* [4876] OBJ_sect163r1 */
        +0x2B,0x81,0x04,0x00,0x0F,                    /* [4881] OBJ_sect163r2 */
        +0x2B,0x81,0x04,0x00,0x18,                    /* [4886] OBJ_sect193r1 */
        +0x2B,0x81,0x04,0x00,0x19,                    /* [4891] OBJ_sect193r2 */
        +0x2B,0x81,0x04,0x00,0x1A,                    /* [4896] OBJ_sect233k1 */
        +0x2B,0x81,0x04,0x00,0x1B,                    /* [4901] OBJ_sect233r1 */
        +0x2B,0x81,0x04,0x00,0x03,                    /* [4906] OBJ_sect239k1 */
        +0x2B,0x81,0x04,0x00,0x10,                    /* [4911] OBJ_sect283k1 */
        +0x2B,0x81,0x04,0x00,0x11,                    /* [4916] OBJ_sect283r1 */
        +0x2B,0x81,0x04,0x00,0x24,                    /* [4921] OBJ_sect409k1 */
        +0x2B,0x81,0x04,0x00,0x25,                    /* [4926] OBJ_sect409r1 */
        +0x2B,0x81,0x04,0x00,0x26,                    /* [4931] OBJ_sect571k1 */
        +0x2B,0x81,0x04,0x00,0x27,                    /* [4936] OBJ_sect571r1 */
        +0x67,0x2B,0x01,0x04,0x01,                    /* [4941] OBJ_wap_wsg_idm_ecid_wtls1 */
        +0x67,0x2B,0x01,0x04,0x03,                    /* [4946] OBJ_wap_wsg_idm_ecid_wtls3 */
        +0x67,0x2B,0x01,0x04,0x04,                    /* [4951] OBJ_wap_wsg_idm_ecid_wtls4 */
        +0x67,0x2B,0x01,0x04,0x05,                    /* [4956] OBJ_wap_wsg_idm_ecid_wtls5 */
        +0x67,0x2B,0x01,0x04,0x06,                    /* [4961] OBJ_wap_wsg_idm_ecid_wtls6 */
        +0x67,0x2B,0x01,0x04,0x07,                    /* [4966] OBJ_wap_wsg_idm_ecid_wtls7 */
        +0x67,0x2B,0x01,0x04,0x08,                    /* [4971] OBJ_wap_wsg_idm_ecid_wtls8 */
        +0x67,0x2B,0x01,0x04,0x09,                    /* [4976] OBJ_wap_wsg_idm_ecid_wtls9 */
        +0x67,0x2B,0x01,0x04,0x0A,                    /* [4981] OBJ_wap_wsg_idm_ecid_wtls10 */
        +0x67,0x2B,0x01,0x04,0x0B,                    /* [4986] OBJ_wap_wsg_idm_ecid_wtls11 */
        +0x67,0x2B,0x01,0x04,0x0C,                    /* [4991] OBJ_wap_wsg_idm_ecid_wtls12 */
        +0x55,0x1D,0x20,0x00,                         /* [4996] OBJ_any_policy */
        +0x55,0x1D,0x21,                              /* [5000] OBJ_policy_mappings */
        +0x55,0x1D,0x36,                              /* [5003] OBJ_inhibit_any_policy */
        +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5006] OBJ_camellia_128_cbc */
        +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5017] OBJ_camellia_192_cbc */
        +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5028] OBJ_camellia_256_cbc */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,     /* [5039] OBJ_camellia_128_ecb */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,     /* [5047] OBJ_camellia_192_ecb */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,     /* [5055] OBJ_camellia_256_ecb */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,     /* [5063] OBJ_camellia_128_cfb128 */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,     /* [5071] OBJ_camellia_192_cfb128 */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,     /* [5079] OBJ_camellia_256_cfb128 */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,     /* [5087] OBJ_camellia_128_ofb128 */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,     /* [5095] OBJ_camellia_192_ofb128 */
        +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,     /* [5103] OBJ_camellia_256_ofb128 */
        +0x55,0x1D,0x09,                              /* [5111] OBJ_subject_directory_attributes */
        +0x55,0x1D,0x1C,                              /* [5114] OBJ_issuing_distribution_point */
        +0x55,0x1D,0x1D,                              /* [5117] OBJ_certificate_issuer */
        +0x2A,0x83,0x1A,0x8C,0x9A,0x44,               /* [5120] OBJ_kisa */
        +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,     /* [5126] OBJ_seed_ecb */
        +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,     /* [5134] OBJ_seed_cbc */
        +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,     /* [5142] OBJ_seed_ofb128 */
        +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,     /* [5150] OBJ_seed_cfb128 */
        +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,     /* [5158] OBJ_hmac_md5 */
        +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,     /* [5166] OBJ_hmac_sha1 */
        +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5174] OBJ_id_PasswordBasedMAC */
        +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5183] OBJ_id_DHBasedMac */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,     /* [5192] OBJ_id_it_suppLangTags */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,     /* [5200] OBJ_caRepository */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5208] OBJ_id_smime_ct_compressedData */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5219] OBJ_id_ct_asciiTextWithCRLF */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5230] OBJ_id_aes128_wrap */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5239] OBJ_id_aes192_wrap */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5248] OBJ_id_aes256_wrap */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,          /* [5257] OBJ_ecdsa_with_Recommended */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,          /* [5264] OBJ_ecdsa_with_Specified */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,     /* [5271] OBJ_ecdsa_with_SHA224 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,     /* [5279] OBJ_ecdsa_with_SHA256 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,     /* [5287] OBJ_ecdsa_with_SHA384 */
        +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,     /* [5295] OBJ_ecdsa_with_SHA512 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,     /* [5303] OBJ_hmacWithMD5 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,     /* [5311] OBJ_hmacWithSHA224 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,     /* [5319] OBJ_hmacWithSHA256 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,     /* [5327] OBJ_hmacWithSHA384 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,     /* [5335] OBJ_hmacWithSHA512 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5343] OBJ_dsa_with_SHA224 */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5352] OBJ_dsa_with_SHA256 */
        +0x28,0xCF,0x06,0x03,0x00,0x37,               /* [5361] OBJ_whirlpool */
        +0x2A,0x85,0x03,0x02,0x02,                    /* [5367] OBJ_cryptopro */
        +0x2A,0x85,0x03,0x02,0x09,                    /* [5372] OBJ_cryptocom */
        +0x2A,0x85,0x03,0x02,0x02,0x03,               /* [5377] OBJ_id_GostR3411_94_with_GostR3410_2001 */
        +0x2A,0x85,0x03,0x02,0x02,0x04,               /* [5383] OBJ_id_GostR3411_94_with_GostR3410_94 */
        +0x2A,0x85,0x03,0x02,0x02,0x09,               /* [5389] OBJ_id_GostR3411_94 */
        +0x2A,0x85,0x03,0x02,0x02,0x0A,               /* [5395] OBJ_id_HMACGostR3411_94 */
        +0x2A,0x85,0x03,0x02,0x02,0x13,               /* [5401] OBJ_id_GostR3410_2001 */
        +0x2A,0x85,0x03,0x02,0x02,0x14,               /* [5407] OBJ_id_GostR3410_94 */
        +0x2A,0x85,0x03,0x02,0x02,0x15,               /* [5413] OBJ_id_Gost28147_89 */
        +0x2A,0x85,0x03,0x02,0x02,0x16,               /* [5419] OBJ_id_Gost28147_89_MAC */
        +0x2A,0x85,0x03,0x02,0x02,0x17,               /* [5425] OBJ_id_GostR3411_94_prf */
        +0x2A,0x85,0x03,0x02,0x02,0x62,               /* [5431] OBJ_id_GostR3410_2001DH */
        +0x2A,0x85,0x03,0x02,0x02,0x63,               /* [5437] OBJ_id_GostR3410_94DH */
        +0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,          /* [5443] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
        +0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,          /* [5450] OBJ_id_Gost28147_89_None_KeyMeshing */
        +0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,          /* [5457] OBJ_id_GostR3411_94_TestParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,          /* [5464] OBJ_id_GostR3411_94_CryptoProParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,          /* [5471] OBJ_id_Gost28147_89_TestParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,          /* [5478] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,          /* [5485] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,          /* [5492] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,          /* [5499] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,          /* [5506] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,          /* [5513] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,          /* [5520] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x20,0x00,          /* [5527] OBJ_id_GostR3410_94_TestParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x20,0x02,          /* [5534] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x20,0x03,          /* [5541] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x20,0x04,          /* [5548] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x20,0x05,          /* [5555] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x21,0x01,          /* [5562] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x21,0x02,          /* [5569] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x21,0x03,          /* [5576] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x23,0x00,          /* [5583] OBJ_id_GostR3410_2001_TestParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x23,0x01,          /* [5590] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x23,0x02,          /* [5597] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x23,0x03,          /* [5604] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x24,0x00,          /* [5611] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x24,0x01,          /* [5618] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
        +0x2A,0x85,0x03,0x02,0x02,0x14,0x01,          /* [5625] OBJ_id_GostR3410_94_a */
        +0x2A,0x85,0x03,0x02,0x02,0x14,0x02,          /* [5632] OBJ_id_GostR3410_94_aBis */
        +0x2A,0x85,0x03,0x02,0x02,0x14,0x03,          /* [5639] OBJ_id_GostR3410_94_b */
        +0x2A,0x85,0x03,0x02,0x02,0x14,0x04,          /* [5646] OBJ_id_GostR3410_94_bBis */
        +0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,     /* [5653] OBJ_id_Gost28147_89_cc */
        +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,     /* [5661] OBJ_id_GostR3410_94_cc */
        +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,     /* [5669] OBJ_id_GostR3410_2001_cc */
        +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5677] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
        +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5685] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
        +0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5693] OBJ_id_GostR3410_2001_ParamSet_cc */
        +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5701] OBJ_LocalKeySet */
        +0x55,0x1D,0x2E,                              /* [5710] OBJ_freshest_crl */
        +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,     /* [5713] OBJ_id_on_permanentIdentifier */
        +0x55,0x04,0x0E,                              /* [5721] OBJ_searchGuide */
        +0x55,0x04,0x0F,                              /* [5724] OBJ_businessCategory */
        +0x55,0x04,0x10,                              /* [5727] OBJ_postalAddress */
        +0x55,0x04,0x12,                              /* [5730] OBJ_postOfficeBox */
        +0x55,0x04,0x13,                              /* [5733] OBJ_physicalDeliveryOfficeName */
        +0x55,0x04,0x14,                              /* [5736] OBJ_telephoneNumber */
        +0x55,0x04,0x15,                              /* [5739] OBJ_telexNumber */
        +0x55,0x04,0x16,                              /* [5742] OBJ_teletexTerminalIdentifier */
        +0x55,0x04,0x17,                              /* [5745] OBJ_facsimileTelephoneNumber */
        +0x55,0x04,0x18,                              /* [5748] OBJ_x121Address */
        +0x55,0x04,0x19,                              /* [5751] OBJ_internationaliSDNNumber */
        +0x55,0x04,0x1A,                              /* [5754] OBJ_registeredAddress */
        +0x55,0x04,0x1B,                              /* [5757] OBJ_destinationIndicator */
        +0x55,0x04,0x1C,                              /* [5760] OBJ_preferredDeliveryMethod */
        +0x55,0x04,0x1D,                              /* [5763] OBJ_presentationAddress */
        +0x55,0x04,0x1E,                              /* [5766] OBJ_supportedApplicationContext */
        +0x55,0x04,0x1F,                              /* [5769] OBJ_member */
        +0x55,0x04,0x20,                              /* [5772] OBJ_owner */
        +0x55,0x04,0x21,                              /* [5775] OBJ_roleOccupant */
        +0x55,0x04,0x22,                              /* [5778] OBJ_seeAlso */
        +0x55,0x04,0x23,                              /* [5781] OBJ_userPassword */
        +0x55,0x04,0x24,                              /* [5784] OBJ_userCertificate */
        +0x55,0x04,0x25,                              /* [5787] OBJ_cACertificate */
        +0x55,0x04,0x26,                              /* [5790] OBJ_authorityRevocationList */
        +0x55,0x04,0x27,                              /* [5793] OBJ_certificateRevocationList */
        +0x55,0x04,0x28,                              /* [5796] OBJ_crossCertificatePair */
        +0x55,0x04,0x2F,                              /* [5799] OBJ_enhancedSearchGuide */
        +0x55,0x04,0x30,                              /* [5802] OBJ_protocolInformation */
        +0x55,0x04,0x31,                              /* [5805] OBJ_distinguishedName */
        +0x55,0x04,0x32,                              /* [5808] OBJ_uniqueMember */
        +0x55,0x04,0x33,                              /* [5811] OBJ_houseIdentifier */
        +0x55,0x04,0x34,                              /* [5814] OBJ_supportedAlgorithms */
        +0x55,0x04,0x35,                              /* [5817] OBJ_deltaRevocationList */
        +0x55,0x04,0x36,                              /* [5820] OBJ_dmdName */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5823] OBJ_id_alg_PWRI_KEK */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5834] OBJ_aes_128_gcm */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5843] OBJ_aes_128_ccm */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5852] OBJ_id_aes128_wrap_pad */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5861] OBJ_aes_192_gcm */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5870] OBJ_aes_192_ccm */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5879] OBJ_id_aes192_wrap_pad */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5888] OBJ_aes_256_gcm */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5897] OBJ_aes_256_ccm */
        +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5906] OBJ_id_aes256_wrap_pad */
        +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5915] OBJ_id_camellia128_wrap */
        +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5926] OBJ_id_camellia192_wrap */
        +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5937] OBJ_id_camellia256_wrap */
        +0x55,0x1D,0x25,0x00,                         /* [5948] OBJ_anyExtendedKeyUsage */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5952] OBJ_mgf1 */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5961] OBJ_rsassaPss */
        +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5970] OBJ_rsaesOaep */
        +};
        +
        +static const ASN1_OBJECT nid_objs[NUM_NID]={
        +{"UNDEF","undefined",NID_undef,1,&(lvalues[0]),0},
        +{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[1]),0},
        +{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[7]),0},
        +{"MD2","md2",NID_md2,8,&(lvalues[14]),0},
        +{"MD5","md5",NID_md5,8,&(lvalues[22]),0},
        +{"RC4","rc4",NID_rc4,8,&(lvalues[30]),0},
        +{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[38]),0},
        +{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9,
        +	&(lvalues[47]),0},
        +{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9,
        +	&(lvalues[56]),0},
        +{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9,
        +	&(lvalues[65]),0},
        +{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9,
        +	&(lvalues[74]),0},
        +{"X500","directory services (X.500)",NID_X500,1,&(lvalues[83]),0},
        +{"X509","X509",NID_X509,2,&(lvalues[84]),0},
        +{"CN","commonName",NID_commonName,3,&(lvalues[86]),0},
        +{"C","countryName",NID_countryName,3,&(lvalues[89]),0},
        +{"L","localityName",NID_localityName,3,&(lvalues[92]),0},
        +{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[95]),0},
        +{"O","organizationName",NID_organizationName,3,&(lvalues[98]),0},
        +{"OU","organizationalUnitName",NID_organizationalUnitName,3,
        +	&(lvalues[101]),0},
        +{"RSA","rsa",NID_rsa,4,&(lvalues[104]),0},
        +{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[108]),0},
        +{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[116]),0},
        +{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9,
        +	&(lvalues[125]),0},
        +{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9,
        +	&(lvalues[134]),0},
        +{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData",
        +	NID_pkcs7_signedAndEnveloped,9,&(lvalues[143]),0},
        +{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9,
        +	&(lvalues[152]),0},
        +{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9,
        +	&(lvalues[161]),0},
        +{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[170]),0},
        +{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9,
        +	&(lvalues[178]),0},
        +{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[187]),0},
        +{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[192]),0},
        +{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[197]),0},
        +{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[202]),0},
        +{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0},
        +{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[207]),0},
        +{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0},
        +{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0},
        +{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[218]),0},
        +{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0},
        +{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0},
        +{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0},
        +{"SHA","sha",NID_sha,5,&(lvalues[226]),0},
        +{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5,
        +	&(lvalues[231]),0},
        +{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0},
        +{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[236]),0},
        +{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[244]),0},
        +{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0},
        +{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[249]),0},
        +{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9,
        +	&(lvalues[257]),0},
        +{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9,
        +	&(lvalues[266]),0},
        +{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[275]),0},
        +{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9,
        +	&(lvalues[284]),0},
        +{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[293]),0},
        +{"countersignature","countersignature",NID_pkcs9_countersignature,9,
        +	&(lvalues[302]),0},
        +{"challengePassword","challengePassword",NID_pkcs9_challengePassword,
        +	9,&(lvalues[311]),0},
        +{"unstructuredAddress","unstructuredAddress",
        +	NID_pkcs9_unstructuredAddress,9,&(lvalues[320]),0},
        +{"extendedCertificateAttributes","extendedCertificateAttributes",
        +	NID_pkcs9_extCertAttributes,9,&(lvalues[329]),0},
        +{"Netscape","Netscape Communications Corp.",NID_netscape,7,
        +	&(lvalues[338]),0},
        +{"nsCertExt","Netscape Certificate Extension",
        +	NID_netscape_cert_extension,8,&(lvalues[345]),0},
        +{"nsDataType","Netscape Data Type",NID_netscape_data_type,8,
        +	&(lvalues[353]),0},
        +{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0},
        +{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0},
        +{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0},
        +{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0},
        +{"SHA1","sha1",NID_sha1,5,&(lvalues[361]),0},
        +{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9,
        +	&(lvalues[366]),0},
        +{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[375]),0},
        +{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[380]),0},
        +{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC,
        +	9,&(lvalues[385]),0},
        +{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[394]),0},
        +{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[403]),0},
        +{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9,
        +	&(lvalues[408]),0},
        +{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9,
        +	&(lvalues[417]),0},
        +{"nsRevocationUrl","Netscape Revocation Url",
        +	NID_netscape_revocation_url,9,&(lvalues[426]),0},
        +{"nsCaRevocationUrl","Netscape CA Revocation Url",
        +	NID_netscape_ca_revocation_url,9,&(lvalues[435]),0},
        +{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9,
        +	&(lvalues[444]),0},
        +{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url,
        +	9,&(lvalues[453]),0},
        +{"nsSslServerName","Netscape SSL Server Name",
        +	NID_netscape_ssl_server_name,9,&(lvalues[462]),0},
        +{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[471]),0},
        +{"nsCertSequence","Netscape Certificate Sequence",
        +	NID_netscape_cert_sequence,9,&(lvalues[480]),0},
        +{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0},
        +{"id-ce","id-ce",NID_id_ce,2,&(lvalues[489]),0},
        +{"subjectKeyIdentifier","X509v3 Subject Key Identifier",
        +	NID_subject_key_identifier,3,&(lvalues[491]),0},
        +{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[494]),0},
        +{"privateKeyUsagePeriod","X509v3 Private Key Usage Period",
        +	NID_private_key_usage_period,3,&(lvalues[497]),0},
        +{"subjectAltName","X509v3 Subject Alternative Name",
        +	NID_subject_alt_name,3,&(lvalues[500]),0},
        +{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name,
        +	3,&(lvalues[503]),0},
        +{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints,
        +	3,&(lvalues[506]),0},
        +{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[509]),0},
        +{"certificatePolicies","X509v3 Certificate Policies",
        +	NID_certificate_policies,3,&(lvalues[512]),0},
        +{"authorityKeyIdentifier","X509v3 Authority Key Identifier",
        +	NID_authority_key_identifier,3,&(lvalues[515]),0},
        +{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[518]),0},
        +{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0},
        +{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0},
        +{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0},
        +{"MDC2","mdc2",NID_mdc2,4,&(lvalues[527]),0},
        +{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[531]),0},
        +{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0},
        +{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0},
        +{"GN","givenName",NID_givenName,3,&(lvalues[535]),0},
        +{"SN","surname",NID_surname,3,&(lvalues[538]),0},
        +{"initials","initials",NID_initials,3,&(lvalues[541]),0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{"crlDistributionPoints","X509v3 CRL Distribution Points",
        +	NID_crl_distribution_points,3,&(lvalues[544]),0},
        +{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[547]),0},
        +{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[552]),0},
        +{"title","title",NID_title,3,&(lvalues[555]),0},
        +{"description","description",NID_description,3,&(lvalues[558]),0},
        +{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[561]),0},
        +{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0},
        +{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0},
        +{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0},
        +{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC",
        +	NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[570]),0},
        +{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[579]),0},
        +{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0},
        +{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[586]),0},
        +{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[591]),0},
        +{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[598]),0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6,
        +	&(lvalues[603]),0},
        +{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[609]),0},
        +{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0},
        +{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0},
        +{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0},
        +{"RLE","run length compression",NID_rle_compression,6,&(lvalues[617]),0},
        +{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[623]),0},
        +{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3,
        +	&(lvalues[634]),0},
        +{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[637]),0},
        +{"id-kp","id-kp",NID_id_kp,7,&(lvalues[643]),0},
        +{"serverAuth","TLS Web Server Authentication",NID_server_auth,8,
        +	&(lvalues[650]),0},
        +{"clientAuth","TLS Web Client Authentication",NID_client_auth,8,
        +	&(lvalues[658]),0},
        +{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[666]),0},
        +{"emailProtection","E-mail Protection",NID_email_protect,8,
        +	&(lvalues[674]),0},
        +{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[682]),0},
        +{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10,
        +	&(lvalues[690]),0},
        +{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10,
        +	&(lvalues[700]),0},
        +{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10,
        +	&(lvalues[710]),0},
        +{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[720]),0},
        +{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10,
        +	&(lvalues[730]),0},
        +{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[740]),0},
        +{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3,
        +	&(lvalues[749]),0},
        +{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[752]),0},
        +{"invalidityDate","Invalidity Date",NID_invalidity_date,3,
        +	&(lvalues[755]),0},
        +{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[758]),0},
        +{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4",
        +	NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[763]),0},
        +{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4",
        +	NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[773]),0},
        +{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC",
        +	NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[783]),0},
        +{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC",
        +	NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[793]),0},
        +{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC",
        +	NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[803]),0},
        +{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC",
        +	NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[813]),0},
        +{"keyBag","keyBag",NID_keyBag,11,&(lvalues[823]),0},
        +{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag,
        +	11,&(lvalues[834]),0},
        +{"certBag","certBag",NID_certBag,11,&(lvalues[845]),0},
        +{"crlBag","crlBag",NID_crlBag,11,&(lvalues[856]),0},
        +{"secretBag","secretBag",NID_secretBag,11,&(lvalues[867]),0},
        +{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11,
        +	&(lvalues[878]),0},
        +{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[889]),0},
        +{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[898]),0},
        +{"x509Certificate","x509Certificate",NID_x509Certificate,10,
        +	&(lvalues[907]),0},
        +{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10,
        +	&(lvalues[917]),0},
        +{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[927]),0},
        +{"PBES2","PBES2",NID_pbes2,9,&(lvalues[937]),0},
        +{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[946]),0},
        +{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[955]),0},
        +{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[963]),0},
        +{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8,
        +	&(lvalues[971]),0},
        +{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0},
        +{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9,
        +	&(lvalues[979]),0},
        +{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9,
        +	&(lvalues[988]),0},
        +{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9,
        +	&(lvalues[997]),0},
        +{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9,
        +	&(lvalues[1006]),0},
        +{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
        +	&(lvalues[1015]),0},
        +{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1025]),0},
        +{"name","name",NID_name,3,&(lvalues[1034]),0},
        +{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1037]),0},
        +{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1040]),0},
        +{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1047]),0},
        +{"authorityInfoAccess","Authority Information Access",NID_info_access,
        +	8,&(lvalues[1054]),0},
        +{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1062]),0},
        +{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1070]),0},
        +{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1078]),0},
        +{"ISO","iso",NID_iso,1,&(lvalues[1086]),0},
        +{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1087]),0},
        +{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1088]),0},
        +{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1091]),0},
        +{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1096]),0},
        +{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1102]),0},
        +{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1110]),0},
        +{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1118]),0},
        +{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1127]),0},
        +{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1137]),0},
        +{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1147]),0},
        +{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1157]),0},
        +{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1167]),0},
        +{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1177]),0},
        +{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1187]),0},
        +{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11,
        +	&(lvalues[1197]),0},
        +{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11,
        +	&(lvalues[1208]),0},
        +{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11,
        +	&(lvalues[1219]),0},
        +{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3,
        +	11,&(lvalues[1230]),0},
        +{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88",
        +	NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1241]),0},
        +{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97",
        +	NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1252]),0},
        +{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88",
        +	NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1263]),0},
        +{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97",
        +	NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1274]),0},
        +{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt,
        +	11,&(lvalues[1285]),0},
        +{"id-smime-ct-authData","id-smime-ct-authData",
        +	NID_id_smime_ct_authData,11,&(lvalues[1296]),0},
        +{"id-smime-ct-publishCert","id-smime-ct-publishCert",
        +	NID_id_smime_ct_publishCert,11,&(lvalues[1307]),0},
        +{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo,
        +	11,&(lvalues[1318]),0},
        +{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo,
        +	11,&(lvalues[1329]),0},
        +{"id-smime-ct-contentInfo","id-smime-ct-contentInfo",
        +	NID_id_smime_ct_contentInfo,11,&(lvalues[1340]),0},
        +{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData",
        +	NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1351]),0},
        +{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData",
        +	NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1362]),0},
        +{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest",
        +	NID_id_smime_aa_receiptRequest,11,&(lvalues[1373]),0},
        +{"id-smime-aa-securityLabel","id-smime-aa-securityLabel",
        +	NID_id_smime_aa_securityLabel,11,&(lvalues[1384]),0},
        +{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory",
        +	NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1395]),0},
        +{"id-smime-aa-contentHint","id-smime-aa-contentHint",
        +	NID_id_smime_aa_contentHint,11,&(lvalues[1406]),0},
        +{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest",
        +	NID_id_smime_aa_msgSigDigest,11,&(lvalues[1417]),0},
        +{"id-smime-aa-encapContentType","id-smime-aa-encapContentType",
        +	NID_id_smime_aa_encapContentType,11,&(lvalues[1428]),0},
        +{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier",
        +	NID_id_smime_aa_contentIdentifier,11,&(lvalues[1439]),0},
        +{"id-smime-aa-macValue","id-smime-aa-macValue",
        +	NID_id_smime_aa_macValue,11,&(lvalues[1450]),0},
        +{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels",
        +	NID_id_smime_aa_equivalentLabels,11,&(lvalues[1461]),0},
        +{"id-smime-aa-contentReference","id-smime-aa-contentReference",
        +	NID_id_smime_aa_contentReference,11,&(lvalues[1472]),0},
        +{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref",
        +	NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1483]),0},
        +{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate",
        +	NID_id_smime_aa_signingCertificate,11,&(lvalues[1494]),0},
        +{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts",
        +	NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1505]),0},
        +{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken",
        +	NID_id_smime_aa_timeStampToken,11,&(lvalues[1516]),0},
        +{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId",
        +	NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1527]),0},
        +{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType",
        +	NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1538]),0},
        +{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation",
        +	NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1549]),0},
        +{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr",
        +	NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1560]),0},
        +{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert",
        +	NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1571]),0},
        +{"id-smime-aa-ets-contentTimestamp",
        +	"id-smime-aa-ets-contentTimestamp",
        +	NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1582]),0},
        +{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs",
        +	NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1593]),0},
        +{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs",
        +	NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1604]),0},
        +{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues",
        +	NID_id_smime_aa_ets_certValues,11,&(lvalues[1615]),0},
        +{"id-smime-aa-ets-revocationValues",
        +	"id-smime-aa-ets-revocationValues",
        +	NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1626]),0},
        +{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp",
        +	NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1637]),0},
        +{"id-smime-aa-ets-certCRLTimestamp",
        +	"id-smime-aa-ets-certCRLTimestamp",
        +	NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1648]),0},
        +{"id-smime-aa-ets-archiveTimeStamp",
        +	"id-smime-aa-ets-archiveTimeStamp",
        +	NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1659]),0},
        +{"id-smime-aa-signatureType","id-smime-aa-signatureType",
        +	NID_id_smime_aa_signatureType,11,&(lvalues[1670]),0},
        +{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc",
        +	NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1681]),0},
        +{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES",
        +	NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1692]),0},
        +{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2",
        +	NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1703]),0},
        +{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap",
        +	NID_id_smime_alg_3DESwrap,11,&(lvalues[1714]),0},
        +{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap",
        +	NID_id_smime_alg_RC2wrap,11,&(lvalues[1725]),0},
        +{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11,
        +	&(lvalues[1736]),0},
        +{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap",
        +	NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1747]),0},
        +{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap",
        +	NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1758]),0},
        +{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11,
        +	&(lvalues[1769]),0},
        +{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri",
        +	NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1780]),0},
        +{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice",
        +	NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1791]),0},
        +{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin",
        +	NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1802]),0},
        +{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt",
        +	NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1813]),0},
        +{"id-smime-cti-ets-proofOfDelivery",
        +	"id-smime-cti-ets-proofOfDelivery",
        +	NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1824]),0},
        +{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender",
        +	NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1835]),0},
        +{"id-smime-cti-ets-proofOfApproval",
        +	"id-smime-cti-ets-proofOfApproval",
        +	NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1846]),0},
        +{"id-smime-cti-ets-proofOfCreation",
        +	"id-smime-cti-ets-proofOfCreation",
        +	NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1857]),0},
        +{"MD4","md4",NID_md4,8,&(lvalues[1868]),0},
        +{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1876]),0},
        +{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1883]),0},
        +{"id-it","id-it",NID_id_it,7,&(lvalues[1890]),0},
        +{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1897]),0},
        +{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1904]),0},
        +{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1911]),0},
        +{"id-on","id-on",NID_id_on,7,&(lvalues[1918]),0},
        +{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1925]),0},
        +{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1932]),0},
        +{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1939]),0},
        +{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1946]),0},
        +{"id-pkix1-explicit-88","id-pkix1-explicit-88",
        +	NID_id_pkix1_explicit_88,8,&(lvalues[1953]),0},
        +{"id-pkix1-implicit-88","id-pkix1-implicit-88",
        +	NID_id_pkix1_implicit_88,8,&(lvalues[1961]),0},
        +{"id-pkix1-explicit-93","id-pkix1-explicit-93",
        +	NID_id_pkix1_explicit_93,8,&(lvalues[1969]),0},
        +{"id-pkix1-implicit-93","id-pkix1-implicit-93",
        +	NID_id_pkix1_implicit_93,8,&(lvalues[1977]),0},
        +{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1985]),0},
        +{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1993]),0},
        +{"id-mod-kea-profile-88","id-mod-kea-profile-88",
        +	NID_id_mod_kea_profile_88,8,&(lvalues[2001]),0},
        +{"id-mod-kea-profile-93","id-mod-kea-profile-93",
        +	NID_id_mod_kea_profile_93,8,&(lvalues[2009]),0},
        +{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2017]),0},
        +{"id-mod-qualified-cert-88","id-mod-qualified-cert-88",
        +	NID_id_mod_qualified_cert_88,8,&(lvalues[2025]),0},
        +{"id-mod-qualified-cert-93","id-mod-qualified-cert-93",
        +	NID_id_mod_qualified_cert_93,8,&(lvalues[2033]),0},
        +{"id-mod-attribute-cert","id-mod-attribute-cert",
        +	NID_id_mod_attribute_cert,8,&(lvalues[2041]),0},
        +{"id-mod-timestamp-protocol","id-mod-timestamp-protocol",
        +	NID_id_mod_timestamp_protocol,8,&(lvalues[2049]),0},
        +{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2057]),0},
        +{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2065]),0},
        +{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8,
        +	&(lvalues[2073]),0},
        +{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2081]),0},
        +{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2089]),0},
        +{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8,
        +	&(lvalues[2097]),0},
        +{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2105]),0},
        +{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2113]),0},
        +{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8,
        +	&(lvalues[2121]),0},
        +{"sbgp-autonomousSysNum","sbgp-autonomousSysNum",
        +	NID_sbgp_autonomousSysNum,8,&(lvalues[2129]),0},
        +{"sbgp-routerIdentifier","sbgp-routerIdentifier",
        +	NID_sbgp_routerIdentifier,8,&(lvalues[2137]),0},
        +{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2145]),0},
        +{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8,
        +	&(lvalues[2153]),0},
        +{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2161]),0},
        +{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2169]),0},
        +{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2177]),0},
        +{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert,
        +	8,&(lvalues[2185]),0},
        +{"id-it-signKeyPairTypes","id-it-signKeyPairTypes",
        +	NID_id_it_signKeyPairTypes,8,&(lvalues[2193]),0},
        +{"id-it-encKeyPairTypes","id-it-encKeyPairTypes",
        +	NID_id_it_encKeyPairTypes,8,&(lvalues[2201]),0},
        +{"id-it-preferredSymmAlg","id-it-preferredSymmAlg",
        +	NID_id_it_preferredSymmAlg,8,&(lvalues[2209]),0},
        +{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo",
        +	NID_id_it_caKeyUpdateInfo,8,&(lvalues[2217]),0},
        +{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8,
        +	&(lvalues[2225]),0},
        +{"id-it-unsupportedOIDs","id-it-unsupportedOIDs",
        +	NID_id_it_unsupportedOIDs,8,&(lvalues[2233]),0},
        +{"id-it-subscriptionRequest","id-it-subscriptionRequest",
        +	NID_id_it_subscriptionRequest,8,&(lvalues[2241]),0},
        +{"id-it-subscriptionResponse","id-it-subscriptionResponse",
        +	NID_id_it_subscriptionResponse,8,&(lvalues[2249]),0},
        +{"id-it-keyPairParamReq","id-it-keyPairParamReq",
        +	NID_id_it_keyPairParamReq,8,&(lvalues[2257]),0},
        +{"id-it-keyPairParamRep","id-it-keyPairParamRep",
        +	NID_id_it_keyPairParamRep,8,&(lvalues[2265]),0},
        +{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase,
        +	8,&(lvalues[2273]),0},
        +{"id-it-implicitConfirm","id-it-implicitConfirm",
        +	NID_id_it_implicitConfirm,8,&(lvalues[2281]),0},
        +{"id-it-confirmWaitTime","id-it-confirmWaitTime",
        +	NID_id_it_confirmWaitTime,8,&(lvalues[2289]),0},
        +{"id-it-origPKIMessage","id-it-origPKIMessage",
        +	NID_id_it_origPKIMessage,8,&(lvalues[2297]),0},
        +{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2305]),0},
        +{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2313]),0},
        +{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken,
        +	9,&(lvalues[2321]),0},
        +{"id-regCtrl-authenticator","id-regCtrl-authenticator",
        +	NID_id_regCtrl_authenticator,9,&(lvalues[2330]),0},
        +{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo",
        +	NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2339]),0},
        +{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions",
        +	NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2348]),0},
        +{"id-regCtrl-oldCertID","id-regCtrl-oldCertID",
        +	NID_id_regCtrl_oldCertID,9,&(lvalues[2357]),0},
        +{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey",
        +	NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2366]),0},
        +{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs",
        +	NID_id_regInfo_utf8Pairs,9,&(lvalues[2375]),0},
        +{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9,
        +	&(lvalues[2384]),0},
        +{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2393]),0},
        +{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8,
        +	&(lvalues[2401]),0},
        +{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1",
        +	NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2409]),0},
        +{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2417]),0},
        +{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8,
        +	&(lvalues[2425]),0},
        +{"id-cmc-identification","id-cmc-identification",
        +	NID_id_cmc_identification,8,&(lvalues[2433]),0},
        +{"id-cmc-identityProof","id-cmc-identityProof",
        +	NID_id_cmc_identityProof,8,&(lvalues[2441]),0},
        +{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8,
        +	&(lvalues[2449]),0},
        +{"id-cmc-transactionId","id-cmc-transactionId",
        +	NID_id_cmc_transactionId,8,&(lvalues[2457]),0},
        +{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8,
        +	&(lvalues[2465]),0},
        +{"id-cmc-recipientNonce","id-cmc-recipientNonce",
        +	NID_id_cmc_recipientNonce,8,&(lvalues[2473]),0},
        +{"id-cmc-addExtensions","id-cmc-addExtensions",
        +	NID_id_cmc_addExtensions,8,&(lvalues[2481]),0},
        +{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP,
        +	8,&(lvalues[2489]),0},
        +{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP,
        +	8,&(lvalues[2497]),0},
        +{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness",
        +	NID_id_cmc_lraPOPWitness,8,&(lvalues[2505]),0},
        +{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8,
        +	&(lvalues[2513]),0},
        +{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2521]),0},
        +{"id-cmc-revokeRequest","id-cmc-revokeRequest",
        +	NID_id_cmc_revokeRequest,8,&(lvalues[2529]),0},
        +{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8,
        +	&(lvalues[2537]),0},
        +{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo,
        +	8,&(lvalues[2545]),0},
        +{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending,
        +	8,&(lvalues[2553]),0},
        +{"id-cmc-popLinkRandom","id-cmc-popLinkRandom",
        +	NID_id_cmc_popLinkRandom,8,&(lvalues[2561]),0},
        +{"id-cmc-popLinkWitness","id-cmc-popLinkWitness",
        +	NID_id_cmc_popLinkWitness,8,&(lvalues[2569]),0},
        +{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance",
        +	NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2577]),0},
        +{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8,
        +	&(lvalues[2585]),0},
        +{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8,
        +	&(lvalues[2593]),0},
        +{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth,
        +	8,&(lvalues[2601]),0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2609]),0},
        +{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship",
        +	NID_id_pda_countryOfCitizenship,8,&(lvalues[2617]),0},
        +{"id-pda-countryOfResidence","id-pda-countryOfResidence",
        +	NID_id_pda_countryOfResidence,8,&(lvalues[2625]),0},
        +{"id-aca-authenticationInfo","id-aca-authenticationInfo",
        +	NID_id_aca_authenticationInfo,8,&(lvalues[2633]),0},
        +{"id-aca-accessIdentity","id-aca-accessIdentity",
        +	NID_id_aca_accessIdentity,8,&(lvalues[2641]),0},
        +{"id-aca-chargingIdentity","id-aca-chargingIdentity",
        +	NID_id_aca_chargingIdentity,8,&(lvalues[2649]),0},
        +{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2657]),0},
        +{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2665]),0},
        +{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1",
        +	NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2673]),0},
        +{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2681]),0},
        +{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8,
        +	&(lvalues[2689]),0},
        +{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8,
        +	&(lvalues[2697]),0},
        +{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8,
        +	&(lvalues[2705]),0},
        +{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2713]),0},
        +{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9,
        +	&(lvalues[2721]),0},
        +{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2730]),0},
        +{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2739]),0},
        +{"acceptableResponses","Acceptable OCSP Responses",
        +	NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2748]),0},
        +{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2757]),0},
        +{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff,
        +	9,&(lvalues[2766]),0},
        +{"serviceLocator","OCSP Service Locator",
        +	NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2775]),0},
        +{"extendedStatus","Extended OCSP Status",
        +	NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2784]),0},
        +{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2793]),0},
        +{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2802]),0},
        +{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9,
        +	&(lvalues[2811]),0},
        +{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2820]),0},
        +{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2824]),0},
        +{"X500algorithms","directory services - algorithms",
        +	NID_X500algorithms,2,&(lvalues[2829]),0},
        +{"ORG","org",NID_org,1,&(lvalues[2831]),0},
        +{"DOD","dod",NID_dod,2,&(lvalues[2832]),0},
        +{"IANA","iana",NID_iana,3,&(lvalues[2834]),0},
        +{"directory","Directory",NID_Directory,4,&(lvalues[2837]),0},
        +{"mgmt","Management",NID_Management,4,&(lvalues[2841]),0},
        +{"experimental","Experimental",NID_Experimental,4,&(lvalues[2845]),0},
        +{"private","Private",NID_Private,4,&(lvalues[2849]),0},
        +{"security","Security",NID_Security,4,&(lvalues[2853]),0},
        +{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2857]),0},
        +{"Mail","Mail",NID_Mail,4,&(lvalues[2861]),0},
        +{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2865]),0},
        +{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2870]),0},
        +{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2879]),0},
        +{"domain","Domain",NID_Domain,10,&(lvalues[2889]),0},
        +{"NULL","NULL",NID_joint_iso_ccitt,1,&(lvalues[2899]),0},
        +{"selected-attribute-types","Selected Attribute Types",
        +	NID_selected_attribute_types,3,&(lvalues[2900]),0},
        +{"clearance","clearance",NID_clearance,4,&(lvalues[2903]),0},
        +{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9,
        +	&(lvalues[2907]),0},
        +{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2916]),0},
        +{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8,
        +	&(lvalues[2924]),0},
        +{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8,
        +	&(lvalues[2932]),0},
        +{"role","role",NID_role,3,&(lvalues[2940]),0},
        +{"policyConstraints","X509v3 Policy Constraints",
        +	NID_policy_constraints,3,&(lvalues[2943]),0},
        +{"targetInformation","X509v3 AC Targeting",NID_target_information,3,
        +	&(lvalues[2946]),0},
        +{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3,
        +	&(lvalues[2949]),0},
        +{"NULL","NULL",NID_ccitt,1,&(lvalues[2952]),0},
        +{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2953]),0},
        +{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2958]),0},
        +{"characteristic-two-field","characteristic-two-field",
        +	NID_X9_62_characteristic_two_field,7,&(lvalues[2965]),0},
        +{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7,
        +	&(lvalues[2972]),0},
        +{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2979]),0},
        +{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2987]),0},
        +{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2995]),0},
        +{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[3003]),0},
        +{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3011]),0},
        +{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3019]),0},
        +{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3027]),0},
        +{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7,
        +	&(lvalues[3035]),0},
        +{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3042]),0},
        +{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3051]),0},
        +{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3060]),0},
        +{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3069]),0},
        +{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3078]),0},
        +{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3087]),0},
        +{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3096]),0},
        +{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3105]),0},
        +{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3114]),0},
        +{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3123]),0},
        +{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3132]),0},
        +{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3141]),0},
        +{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3150]),0},
        +{"holdInstructionCode","Hold Instruction Code",
        +	NID_hold_instruction_code,3,&(lvalues[3159]),0},
        +{"holdInstructionNone","Hold Instruction None",
        +	NID_hold_instruction_none,7,&(lvalues[3162]),0},
        +{"holdInstructionCallIssuer","Hold Instruction Call Issuer",
        +	NID_hold_instruction_call_issuer,7,&(lvalues[3169]),0},
        +{"holdInstructionReject","Hold Instruction Reject",
        +	NID_hold_instruction_reject,7,&(lvalues[3176]),0},
        +{"data","data",NID_data,1,&(lvalues[3183]),0},
        +{"pss","pss",NID_pss,3,&(lvalues[3184]),0},
        +{"ucl","ucl",NID_ucl,7,&(lvalues[3187]),0},
        +{"pilot","pilot",NID_pilot,8,&(lvalues[3194]),0},
        +{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9,
        +	&(lvalues[3202]),0},
        +{"pilotAttributeSyntax","pilotAttributeSyntax",
        +	NID_pilotAttributeSyntax,9,&(lvalues[3211]),0},
        +{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9,
        +	&(lvalues[3220]),0},
        +{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3229]),0},
        +{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10,
        +	&(lvalues[3238]),0},
        +{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax",
        +	NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3248]),0},
        +{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3258]),0},
        +{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3268]),0},
        +{"account","account",NID_account,10,&(lvalues[3278]),0},
        +{"document","document",NID_document,10,&(lvalues[3288]),0},
        +{"room","room",NID_room,10,&(lvalues[3298]),0},
        +{"documentSeries","documentSeries",NID_documentSeries,10,
        +	&(lvalues[3308]),0},
        +{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10,
        +	&(lvalues[3318]),0},
        +{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3328]),0},
        +{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject,
        +	10,&(lvalues[3338]),0},
        +{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10,
        +	&(lvalues[3348]),0},
        +{"simpleSecurityObject","simpleSecurityObject",
        +	NID_simpleSecurityObject,10,&(lvalues[3358]),0},
        +{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10,
        +	&(lvalues[3368]),0},
        +{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3378]),0},
        +{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData,
        +	10,&(lvalues[3388]),0},
        +{"UID","userId",NID_userId,10,&(lvalues[3398]),0},
        +{"textEncodedORAddress","textEncodedORAddress",
        +	NID_textEncodedORAddress,10,&(lvalues[3408]),0},
        +{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3418]),0},
        +{"info","info",NID_info,10,&(lvalues[3428]),0},
        +{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10,
        +	&(lvalues[3438]),0},
        +{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3448]),0},
        +{"photo","photo",NID_photo,10,&(lvalues[3458]),0},
        +{"userClass","userClass",NID_userClass,10,&(lvalues[3468]),0},
        +{"host","host",NID_host,10,&(lvalues[3478]),0},
        +{"manager","manager",NID_manager,10,&(lvalues[3488]),0},
        +{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10,
        +	&(lvalues[3498]),0},
        +{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3508]),0},
        +{"documentVersion","documentVersion",NID_documentVersion,10,
        +	&(lvalues[3518]),0},
        +{"documentAuthor","documentAuthor",NID_documentAuthor,10,
        +	&(lvalues[3528]),0},
        +{"documentLocation","documentLocation",NID_documentLocation,10,
        +	&(lvalues[3538]),0},
        +{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber,
        +	10,&(lvalues[3548]),0},
        +{"secretary","secretary",NID_secretary,10,&(lvalues[3558]),0},
        +{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3568]),0},
        +{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10,
        +	&(lvalues[3578]),0},
        +{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10,
        +	&(lvalues[3588]),0},
        +{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3598]),0},
        +{"pilotAttributeType27","pilotAttributeType27",
        +	NID_pilotAttributeType27,10,&(lvalues[3608]),0},
        +{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3618]),0},
        +{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3628]),0},
        +{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3638]),0},
        +{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3648]),0},
        +{"associatedDomain","associatedDomain",NID_associatedDomain,10,
        +	&(lvalues[3658]),0},
        +{"associatedName","associatedName",NID_associatedName,10,
        +	&(lvalues[3668]),0},
        +{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10,
        +	&(lvalues[3678]),0},
        +{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3688]),0},
        +{"mobileTelephoneNumber","mobileTelephoneNumber",
        +	NID_mobileTelephoneNumber,10,&(lvalues[3698]),0},
        +{"pagerTelephoneNumber","pagerTelephoneNumber",
        +	NID_pagerTelephoneNumber,10,&(lvalues[3708]),0},
        +{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName,
        +	10,&(lvalues[3718]),0},
        +{"organizationalStatus","organizationalStatus",
        +	NID_organizationalStatus,10,&(lvalues[3728]),0},
        +{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3738]),0},
        +{"mailPreferenceOption","mailPreferenceOption",
        +	NID_mailPreferenceOption,10,&(lvalues[3748]),0},
        +{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3758]),0},
        +{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3768]),0},
        +{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10,
        +	&(lvalues[3778]),0},
        +{"subtreeMinimumQuality","subtreeMinimumQuality",
        +	NID_subtreeMinimumQuality,10,&(lvalues[3788]),0},
        +{"subtreeMaximumQuality","subtreeMaximumQuality",
        +	NID_subtreeMaximumQuality,10,&(lvalues[3798]),0},
        +{"personalSignature","personalSignature",NID_personalSignature,10,
        +	&(lvalues[3808]),0},
        +{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3818]),0},
        +{"audio","audio",NID_audio,10,&(lvalues[3828]),0},
        +{"documentPublisher","documentPublisher",NID_documentPublisher,10,
        +	&(lvalues[3838]),0},
        +{"x500UniqueIdentifier","x500UniqueIdentifier",
        +	NID_x500UniqueIdentifier,3,&(lvalues[3848]),0},
        +{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3851]),0},
        +{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6,
        +	&(lvalues[3856]),0},
        +{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6,
        +	&(lvalues[3862]),0},
        +{"id-hex-partial-message","id-hex-partial-message",
        +	NID_id_hex_partial_message,7,&(lvalues[3868]),0},
        +{"id-hex-multipart-message","id-hex-multipart-message",
        +	NID_id_hex_multipart_message,7,&(lvalues[3875]),0},
        +{"generationQualifier","generationQualifier",NID_generationQualifier,
        +	3,&(lvalues[3882]),0},
        +{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3885]),0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{"id-set","Secure Electronic Transactions",NID_id_set,2,
        +	&(lvalues[3888]),0},
        +{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3890]),0},
        +{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3893]),0},
        +{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3896]),0},
        +{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3899]),0},
        +{"set-certExt","certificate extensions",NID_set_certExt,3,
        +	&(lvalues[3902]),0},
        +{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3905]),0},
        +{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3908]),0},
        +{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4,
        +	&(lvalues[3912]),0},
        +{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3916]),0},
        +{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3920]),0},
        +{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3924]),0},
        +{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3928]),0},
        +{"setct-PIDataUnsigned","setct-PIDataUnsigned",
        +	NID_setct_PIDataUnsigned,4,&(lvalues[3932]),0},
        +{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4,
        +	&(lvalues[3936]),0},
        +{"setct-AuthResBaggage","setct-AuthResBaggage",
        +	NID_setct_AuthResBaggage,4,&(lvalues[3940]),0},
        +{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage",
        +	NID_setct_AuthRevReqBaggage,4,&(lvalues[3944]),0},
        +{"setct-AuthRevResBaggage","setct-AuthRevResBaggage",
        +	NID_setct_AuthRevResBaggage,4,&(lvalues[3948]),0},
        +{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4,
        +	&(lvalues[3952]),0},
        +{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4,
        +	&(lvalues[3956]),0},
        +{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3960]),0},
        +{"setct-PResData","setct-PResData",NID_setct_PResData,4,
        +	&(lvalues[3964]),0},
        +{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4,
        +	&(lvalues[3968]),0},
        +{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4,
        +	&(lvalues[3972]),0},
        +{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4,
        +	&(lvalues[3976]),0},
        +{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4,
        +	&(lvalues[3980]),0},
        +{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4,
        +	&(lvalues[3984]),0},
        +{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4,
        +	&(lvalues[3988]),0},
        +{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg",
        +	NID_setct_AcqCardCodeMsg,4,&(lvalues[3992]),0},
        +{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS,
        +	4,&(lvalues[3996]),0},
        +{"setct-AuthRevResData","setct-AuthRevResData",
        +	NID_setct_AuthRevResData,4,&(lvalues[4000]),0},
        +{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS,
        +	4,&(lvalues[4004]),0},
        +{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4,
        +	&(lvalues[4008]),0},
        +{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4,
        +	&(lvalues[4012]),0},
        +{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4,
        +	&(lvalues[4016]),0},
        +{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4,
        +	&(lvalues[4020]),0},
        +{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX,
        +	4,&(lvalues[4024]),0},
        +{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData,
        +	4,&(lvalues[4028]),0},
        +{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4,
        +	&(lvalues[4032]),0},
        +{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4,
        +	&(lvalues[4036]),0},
        +{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4,
        +	&(lvalues[4040]),0},
        +{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS,
        +	4,&(lvalues[4044]),0},
        +{"setct-CredRevReqTBSX","setct-CredRevReqTBSX",
        +	NID_setct_CredRevReqTBSX,4,&(lvalues[4048]),0},
        +{"setct-CredRevResData","setct-CredRevResData",
        +	NID_setct_CredRevResData,4,&(lvalues[4052]),0},
        +{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4,
        +	&(lvalues[4056]),0},
        +{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4,
        +	&(lvalues[4060]),0},
        +{"setct-BatchAdminReqData","setct-BatchAdminReqData",
        +	NID_setct_BatchAdminReqData,4,&(lvalues[4064]),0},
        +{"setct-BatchAdminResData","setct-BatchAdminResData",
        +	NID_setct_BatchAdminResData,4,&(lvalues[4068]),0},
        +{"setct-CardCInitResTBS","setct-CardCInitResTBS",
        +	NID_setct_CardCInitResTBS,4,&(lvalues[4072]),0},
        +{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS",
        +	NID_setct_MeAqCInitResTBS,4,&(lvalues[4076]),0},
        +{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS,
        +	4,&(lvalues[4080]),0},
        +{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4,
        +	&(lvalues[4084]),0},
        +{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4,
        +	&(lvalues[4088]),0},
        +{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4,
        +	&(lvalues[4092]),0},
        +{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS,
        +	4,&(lvalues[4096]),0},
        +{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4,
        +	&(lvalues[4100]),0},
        +{"setct-PIDualSignedTBE","setct-PIDualSignedTBE",
        +	NID_setct_PIDualSignedTBE,4,&(lvalues[4104]),0},
        +{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE,
        +	4,&(lvalues[4108]),0},
        +{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4,
        +	&(lvalues[4112]),0},
        +{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4,
        +	&(lvalues[4116]),0},
        +{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4,
        +	&(lvalues[4120]),0},
        +{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4,
        +	&(lvalues[4124]),0},
        +{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4,
        +	&(lvalues[4128]),0},
        +{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4,
        +	&(lvalues[4132]),0},
        +{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE",
        +	NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4136]),0},
        +{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE,
        +	4,&(lvalues[4140]),0},
        +{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE,
        +	4,&(lvalues[4144]),0},
        +{"setct-AuthRevResTBEB","setct-AuthRevResTBEB",
        +	NID_setct_AuthRevResTBEB,4,&(lvalues[4148]),0},
        +{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4,
        +	&(lvalues[4152]),0},
        +{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4,
        +	&(lvalues[4156]),0},
        +{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4,
        +	&(lvalues[4160]),0},
        +{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4,
        +	&(lvalues[4164]),0},
        +{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX,
        +	4,&(lvalues[4168]),0},
        +{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4,
        +	&(lvalues[4172]),0},
        +{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4,
        +	&(lvalues[4176]),0},
        +{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4,
        +	&(lvalues[4180]),0},
        +{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4,
        +	&(lvalues[4184]),0},
        +{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE,
        +	4,&(lvalues[4188]),0},
        +{"setct-CredRevReqTBEX","setct-CredRevReqTBEX",
        +	NID_setct_CredRevReqTBEX,4,&(lvalues[4192]),0},
        +{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE,
        +	4,&(lvalues[4196]),0},
        +{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE",
        +	NID_setct_BatchAdminReqTBE,4,&(lvalues[4200]),0},
        +{"setct-BatchAdminResTBE","setct-BatchAdminResTBE",
        +	NID_setct_BatchAdminResTBE,4,&(lvalues[4204]),0},
        +{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE,
        +	4,&(lvalues[4208]),0},
        +{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4,
        +	&(lvalues[4212]),0},
        +{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4,
        +	&(lvalues[4216]),0},
        +{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4,
        +	&(lvalues[4220]),0},
        +{"setct-CRLNotificationTBS","setct-CRLNotificationTBS",
        +	NID_setct_CRLNotificationTBS,4,&(lvalues[4224]),0},
        +{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS",
        +	NID_setct_CRLNotificationResTBS,4,&(lvalues[4228]),0},
        +{"setct-BCIDistributionTBS","setct-BCIDistributionTBS",
        +	NID_setct_BCIDistributionTBS,4,&(lvalues[4232]),0},
        +{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4,
        +	&(lvalues[4236]),0},
        +{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4,
        +	&(lvalues[4240]),0},
        +{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4,
        +	&(lvalues[4244]),0},
        +{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4248]),0},
        +{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4252]),0},
        +{"setext-cv","additional verification",NID_setext_cv,4,
        +	&(lvalues[4256]),0},
        +{"set-policy-root","set-policy-root",NID_set_policy_root,4,
        +	&(lvalues[4260]),0},
        +{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4,
        +	&(lvalues[4264]),0},
        +{"setCext-certType","setCext-certType",NID_setCext_certType,4,
        +	&(lvalues[4268]),0},
        +{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4,
        +	&(lvalues[4272]),0},
        +{"setCext-cCertRequired","setCext-cCertRequired",
        +	NID_setCext_cCertRequired,4,&(lvalues[4276]),0},
        +{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4,
        +	&(lvalues[4280]),0},
        +{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4,
        +	&(lvalues[4284]),0},
        +{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4,
        +	&(lvalues[4288]),0},
        +{"setCext-PGWYcapabilities","setCext-PGWYcapabilities",
        +	NID_setCext_PGWYcapabilities,4,&(lvalues[4292]),0},
        +{"setCext-TokenIdentifier","setCext-TokenIdentifier",
        +	NID_setCext_TokenIdentifier,4,&(lvalues[4296]),0},
        +{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4,
        +	&(lvalues[4300]),0},
        +{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4,
        +	&(lvalues[4304]),0},
        +{"setCext-IssuerCapabilities","setCext-IssuerCapabilities",
        +	NID_setCext_IssuerCapabilities,4,&(lvalues[4308]),0},
        +{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4312]),0},
        +{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap,
        +	4,&(lvalues[4316]),0},
        +{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4,
        +	&(lvalues[4320]),0},
        +{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4,
        +	&(lvalues[4324]),0},
        +{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5,
        +	&(lvalues[4328]),0},
        +{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4333]),0},
        +{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5,
        +	&(lvalues[4338]),0},
        +{"setAttr-Token-B0Prime","setAttr-Token-B0Prime",
        +	NID_setAttr_Token_B0Prime,5,&(lvalues[4343]),0},
        +{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5,
        +	&(lvalues[4348]),0},
        +{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5,
        +	&(lvalues[4353]),0},
        +{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5,
        +	&(lvalues[4358]),0},
        +{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm,
        +	6,&(lvalues[4363]),0},
        +{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6,
        +	&(lvalues[4369]),0},
        +{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6,
        +	&(lvalues[4375]),0},
        +{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6,
        +	&(lvalues[4381]),0},
        +{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig,
        +	6,&(lvalues[4387]),0},
        +{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4,
        +	&(lvalues[4393]),0},
        +{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4,
        +	&(lvalues[4397]),0},
        +{"set-brand-AmericanExpress","set-brand-AmericanExpress",
        +	NID_set_brand_AmericanExpress,4,&(lvalues[4401]),0},
        +{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4405]),0},
        +{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4,
        +	&(lvalues[4409]),0},
        +{"set-brand-MasterCard","set-brand-MasterCard",
        +	NID_set_brand_MasterCard,4,&(lvalues[4413]),0},
        +{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5,
        +	&(lvalues[4417]),0},
        +{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4422]),0},
        +{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET",
        +	NID_rsaOAEPEncryptionSET,9,&(lvalues[4430]),0},
        +{"ITU-T","itu-t",NID_itu_t,1,&(lvalues[4439]),0},
        +{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,1,
        +	&(lvalues[4440]),0},
        +{"international-organizations","International Organizations",
        +	NID_international_organizations,1,&(lvalues[4441]),0},
        +{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login,
        +	10,&(lvalues[4442]),0},
        +{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10,
        +	&(lvalues[4452]),0},
        +{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0},
        +{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0},
        +{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0},
        +{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0},
        +{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0},
        +{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0},
        +{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0},
        +{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0},
        +{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0},
        +{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0},
        +{"street","streetAddress",NID_streetAddress,3,&(lvalues[4462]),0},
        +{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4465]),0},
        +{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4468]),0},
        +{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
        +	&(lvalues[4475]),0},
        +{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8,
        +	&(lvalues[4483]),0},
        +{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8,
        +	&(lvalues[4491]),0},
        +{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3,
        +	&(lvalues[4499]),0},
        +{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4502]),0},
        +{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9,
        +	&(lvalues[4510]),0},
        +{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9,
        +	&(lvalues[4519]),0},
        +{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9,
        +	&(lvalues[4528]),0},
        +{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9,
        +	&(lvalues[4537]),0},
        +{"SHA256","sha256",NID_sha256,9,&(lvalues[4546]),0},
        +{"SHA384","sha384",NID_sha384,9,&(lvalues[4555]),0},
        +{"SHA512","sha512",NID_sha512,9,&(lvalues[4564]),0},
        +{"SHA224","sha224",NID_sha224,9,&(lvalues[4573]),0},
        +{"identified-organization","identified-organization",
        +	NID_identified_organization,1,&(lvalues[4582]),0},
        +{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4583]),0},
        +{"wap","wap",NID_wap,2,&(lvalues[4586]),0},
        +{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4588]),0},
        +{"id-characteristic-two-basis","id-characteristic-two-basis",
        +	NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4591]),0},
        +{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4599]),0},
        +{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4608]),0},
        +{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4617]),0},
        +{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4626]),0},
        +{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4634]),0},
        +{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4642]),0},
        +{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4650]),0},
        +{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4658]),0},
        +{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4666]),0},
        +{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4674]),0},
        +{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4682]),0},
        +{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4690]),0},
        +{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4698]),0},
        +{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4706]),0},
        +{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4714]),0},
        +{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4722]),0},
        +{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4730]),0},
        +{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4738]),0},
        +{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4746]),0},
        +{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4754]),0},
        +{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4762]),0},
        +{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4770]),0},
        +{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4778]),0},
        +{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4786]),0},
        +{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4791]),0},
        +{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4796]),0},
        +{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4801]),0},
        +{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4806]),0},
        +{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4811]),0},
        +{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4816]),0},
        +{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4821]),0},
        +{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4826]),0},
        +{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4831]),0},
        +{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4836]),0},
        +{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4841]),0},
        +{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4846]),0},
        +{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4851]),0},
        +{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4856]),0},
        +{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4861]),0},
        +{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4866]),0},
        +{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4871]),0},
        +{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4876]),0},
        +{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4881]),0},
        +{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4886]),0},
        +{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4891]),0},
        +{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4896]),0},
        +{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4901]),0},
        +{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4906]),0},
        +{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4911]),0},
        +{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4916]),0},
        +{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4921]),0},
        +{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4926]),0},
        +{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4931]),0},
        +{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4936]),0},
        +{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1",
        +	NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4941]),0},
        +{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3",
        +	NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4946]),0},
        +{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4",
        +	NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4951]),0},
        +{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5",
        +	NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4956]),0},
        +{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6",
        +	NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4961]),0},
        +{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7",
        +	NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4966]),0},
        +{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8",
        +	NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4971]),0},
        +{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9",
        +	NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4976]),0},
        +{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10",
        +	NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4981]),0},
        +{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11",
        +	NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4986]),0},
        +{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12",
        +	NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4991]),0},
        +{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4996]),0},
        +{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3,
        +	&(lvalues[5000]),0},
        +{"inhibitAnyPolicy","X509v3 Inhibit Any Policy",
        +	NID_inhibit_any_policy,3,&(lvalues[5003]),0},
        +{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0},
        +{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0},
        +{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11,
        +	&(lvalues[5006]),0},
        +{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11,
        +	&(lvalues[5017]),0},
        +{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11,
        +	&(lvalues[5028]),0},
        +{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8,
        +	&(lvalues[5039]),0},
        +{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8,
        +	&(lvalues[5047]),0},
        +{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8,
        +	&(lvalues[5055]),0},
        +{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8,
        +	&(lvalues[5063]),0},
        +{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8,
        +	&(lvalues[5071]),0},
        +{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8,
        +	&(lvalues[5079]),0},
        +{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0},
        +{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0},
        +{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0},
        +{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0},
        +{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0},
        +{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0},
        +{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8,
        +	&(lvalues[5087]),0},
        +{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8,
        +	&(lvalues[5095]),0},
        +{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8,
        +	&(lvalues[5103]),0},
        +{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes",
        +	NID_subject_directory_attributes,3,&(lvalues[5111]),0},
        +{"issuingDistributionPoint","X509v3 Issuing Distrubution Point",
        +	NID_issuing_distribution_point,3,&(lvalues[5114]),0},
        +{"certificateIssuer","X509v3 Certificate Issuer",
        +	NID_certificate_issuer,3,&(lvalues[5117]),0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{"KISA","kisa",NID_kisa,6,&(lvalues[5120]),0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{NULL,NULL,NID_undef,0,NULL,0},
        +{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5126]),0},
        +{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5134]),0},
        +{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5142]),0},
        +{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5150]),0},
        +{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5158]),0},
        +{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5166]),0},
        +{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9,
        +	&(lvalues[5174]),0},
        +{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9,
        +	&(lvalues[5183]),0},
        +{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8,
        +	&(lvalues[5192]),0},
        +{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5200]),0},
        +{"id-smime-ct-compressedData","id-smime-ct-compressedData",
        +	NID_id_smime_ct_compressedData,11,&(lvalues[5208]),0},
        +{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF",
        +	NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5219]),0},
        +{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9,
        +	&(lvalues[5230]),0},
        +{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9,
        +	&(lvalues[5239]),0},
        +{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9,
        +	&(lvalues[5248]),0},
        +{"ecdsa-with-Recommended","ecdsa-with-Recommended",
        +	NID_ecdsa_with_Recommended,7,&(lvalues[5257]),0},
        +{"ecdsa-with-Specified","ecdsa-with-Specified",
        +	NID_ecdsa_with_Specified,7,&(lvalues[5264]),0},
        +{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8,
        +	&(lvalues[5271]),0},
        +{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8,
        +	&(lvalues[5279]),0},
        +{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8,
        +	&(lvalues[5287]),0},
        +{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8,
        +	&(lvalues[5295]),0},
        +{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5303]),0},
        +{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8,
        +	&(lvalues[5311]),0},
        +{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8,
        +	&(lvalues[5319]),0},
        +{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8,
        +	&(lvalues[5327]),0},
        +{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8,
        +	&(lvalues[5335]),0},
        +{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9,
        +	&(lvalues[5343]),0},
        +{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9,
        +	&(lvalues[5352]),0},
        +{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5361]),0},
        +{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5367]),0},
        +{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5372]),0},
        +{"id-GostR3411-94-with-GostR3410-2001",
        +	"GOST R 34.11-94 with GOST R 34.10-2001",
        +	NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5377]),0},
        +{"id-GostR3411-94-with-GostR3410-94",
        +	"GOST R 34.11-94 with GOST R 34.10-94",
        +	NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5383]),0},
        +{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5389]),0},
        +{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6,
        +	&(lvalues[5395]),0},
        +{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6,
        +	&(lvalues[5401]),0},
        +{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5407]),0},
        +{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5413]),0},
        +{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0},
        +{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6,
        +	&(lvalues[5419]),0},
        +{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6,
        +	&(lvalues[5425]),0},
        +{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH,
        +	6,&(lvalues[5431]),0},
        +{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6,
        +	&(lvalues[5437]),0},
        +{"id-Gost28147-89-CryptoPro-KeyMeshing",
        +	"id-Gost28147-89-CryptoPro-KeyMeshing",
        +	NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5443]),0},
        +{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing",
        +	NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5450]),0},
        +{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet",
        +	NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5457]),0},
        +{"id-GostR3411-94-CryptoProParamSet",
        +	"id-GostR3411-94-CryptoProParamSet",
        +	NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5464]),0},
        +{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet",
        +	NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5471]),0},
        +{"id-Gost28147-89-CryptoPro-A-ParamSet",
        +	"id-Gost28147-89-CryptoPro-A-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5478]),0},
        +{"id-Gost28147-89-CryptoPro-B-ParamSet",
        +	"id-Gost28147-89-CryptoPro-B-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5485]),0},
        +{"id-Gost28147-89-CryptoPro-C-ParamSet",
        +	"id-Gost28147-89-CryptoPro-C-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5492]),0},
        +{"id-Gost28147-89-CryptoPro-D-ParamSet",
        +	"id-Gost28147-89-CryptoPro-D-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5499]),0},
        +{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
        +	"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5506]),
        +	0},
        +{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
        +	"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5513]),
        +	0},
        +{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
        +	"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
        +	NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5520]),0},
        +{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet",
        +	NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5527]),0},
        +{"id-GostR3410-94-CryptoPro-A-ParamSet",
        +	"id-GostR3410-94-CryptoPro-A-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5534]),0},
        +{"id-GostR3410-94-CryptoPro-B-ParamSet",
        +	"id-GostR3410-94-CryptoPro-B-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5541]),0},
        +{"id-GostR3410-94-CryptoPro-C-ParamSet",
        +	"id-GostR3410-94-CryptoPro-C-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5548]),0},
        +{"id-GostR3410-94-CryptoPro-D-ParamSet",
        +	"id-GostR3410-94-CryptoPro-D-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5555]),0},
        +{"id-GostR3410-94-CryptoPro-XchA-ParamSet",
        +	"id-GostR3410-94-CryptoPro-XchA-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5562]),0},
        +{"id-GostR3410-94-CryptoPro-XchB-ParamSet",
        +	"id-GostR3410-94-CryptoPro-XchB-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5569]),0},
        +{"id-GostR3410-94-CryptoPro-XchC-ParamSet",
        +	"id-GostR3410-94-CryptoPro-XchC-ParamSet",
        +	NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5576]),0},
        +{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet",
        +	NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5583]),0},
        +{"id-GostR3410-2001-CryptoPro-A-ParamSet",
        +	"id-GostR3410-2001-CryptoPro-A-ParamSet",
        +	NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5590]),0},
        +{"id-GostR3410-2001-CryptoPro-B-ParamSet",
        +	"id-GostR3410-2001-CryptoPro-B-ParamSet",
        +	NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5597]),0},
        +{"id-GostR3410-2001-CryptoPro-C-ParamSet",
        +	"id-GostR3410-2001-CryptoPro-C-ParamSet",
        +	NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5604]),0},
        +{"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
        +	"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
        +	NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5611]),0},
        +	
        +{"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
        +	"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
        +	NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5618]),0},
        +	
        +{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7,
        +	&(lvalues[5625]),0},
        +{"id-GostR3410-94-aBis","id-GostR3410-94-aBis",
        +	NID_id_GostR3410_94_aBis,7,&(lvalues[5632]),0},
        +{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7,
        +	&(lvalues[5639]),0},
        +{"id-GostR3410-94-bBis","id-GostR3410-94-bBis",
        +	NID_id_GostR3410_94_bBis,7,&(lvalues[5646]),0},
        +{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet",
        +	NID_id_Gost28147_89_cc,8,&(lvalues[5653]),0},
        +{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8,
        +	&(lvalues[5661]),0},
        +{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8,
        +	&(lvalues[5669]),0},
        +{"id-GostR3411-94-with-GostR3410-94-cc",
        +	"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom",
        +	NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5677]),0},
        +{"id-GostR3411-94-with-GostR3410-2001-cc",
        +	"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom",
        +	NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5685]),0},
        +{"id-GostR3410-2001-ParamSet-cc",
        +	"GOST R 3410-2001 Parameter Set Cryptocom",
        +	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5693]),0},
        +{"HMAC","hmac",NID_hmac,0,NULL,0},
        +{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
        +	&(lvalues[5701]),0},
        +{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3,
        +	&(lvalues[5710]),0},
        +{"id-on-permanentIdentifier","Permanent Identifier",
        +	NID_id_on_permanentIdentifier,8,&(lvalues[5713]),0},
        +{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5721]),0},
        +{"businessCategory","businessCategory",NID_businessCategory,3,
        +	&(lvalues[5724]),0},
        +{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5727]),0},
        +{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5730]),0},
        +{"physicalDeliveryOfficeName","physicalDeliveryOfficeName",
        +	NID_physicalDeliveryOfficeName,3,&(lvalues[5733]),0},
        +{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3,
        +	&(lvalues[5736]),0},
        +{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5739]),0},
        +{"teletexTerminalIdentifier","teletexTerminalIdentifier",
        +	NID_teletexTerminalIdentifier,3,&(lvalues[5742]),0},
        +{"facsimileTelephoneNumber","facsimileTelephoneNumber",
        +	NID_facsimileTelephoneNumber,3,&(lvalues[5745]),0},
        +{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5748]),0},
        +{"internationaliSDNNumber","internationaliSDNNumber",
        +	NID_internationaliSDNNumber,3,&(lvalues[5751]),0},
        +{"registeredAddress","registeredAddress",NID_registeredAddress,3,
        +	&(lvalues[5754]),0},
        +{"destinationIndicator","destinationIndicator",
        +	NID_destinationIndicator,3,&(lvalues[5757]),0},
        +{"preferredDeliveryMethod","preferredDeliveryMethod",
        +	NID_preferredDeliveryMethod,3,&(lvalues[5760]),0},
        +{"presentationAddress","presentationAddress",NID_presentationAddress,
        +	3,&(lvalues[5763]),0},
        +{"supportedApplicationContext","supportedApplicationContext",
        +	NID_supportedApplicationContext,3,&(lvalues[5766]),0},
        +{"member","member",NID_member,3,&(lvalues[5769]),0},
        +{"owner","owner",NID_owner,3,&(lvalues[5772]),0},
        +{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5775]),0},
        +{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5778]),0},
        +{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5781]),0},
        +{"userCertificate","userCertificate",NID_userCertificate,3,
        +	&(lvalues[5784]),0},
        +{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5787]),0},
        +{"authorityRevocationList","authorityRevocationList",
        +	NID_authorityRevocationList,3,&(lvalues[5790]),0},
        +{"certificateRevocationList","certificateRevocationList",
        +	NID_certificateRevocationList,3,&(lvalues[5793]),0},
        +{"crossCertificatePair","crossCertificatePair",
        +	NID_crossCertificatePair,3,&(lvalues[5796]),0},
        +{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide,
        +	3,&(lvalues[5799]),0},
        +{"protocolInformation","protocolInformation",NID_protocolInformation,
        +	3,&(lvalues[5802]),0},
        +{"distinguishedName","distinguishedName",NID_distinguishedName,3,
        +	&(lvalues[5805]),0},
        +{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5808]),0},
        +{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3,
        +	&(lvalues[5811]),0},
        +{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms,
        +	3,&(lvalues[5814]),0},
        +{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
        +	3,&(lvalues[5817]),0},
        +{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5820]),0},
        +{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11,
        +	&(lvalues[5823]),0},
        +{"CMAC","cmac",NID_cmac,0,NULL,0},
        +{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5834]),0},
        +{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5843]),0},
        +{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9,
        +	&(lvalues[5852]),0},
        +{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5861]),0},
        +{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5870]),0},
        +{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9,
        +	&(lvalues[5879]),0},
        +{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5888]),0},
        +{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5897]),0},
        +{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9,
        +	&(lvalues[5906]),0},
        +{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0},
        +{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0},
        +{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0},
        +{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap,
        +	11,&(lvalues[5915]),0},
        +{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap,
        +	11,&(lvalues[5926]),0},
        +{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap,
        +	11,&(lvalues[5937]),0},
        +{"anyExtendedKeyUsage","Any Extended Key Usage",
        +	NID_anyExtendedKeyUsage,4,&(lvalues[5948]),0},
        +{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5952]),0},
        +{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5961]),0},
        +{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0},
        +{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0},
        +{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0},
        +{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1",
        +	NID_aes_128_cbc_hmac_sha1,0,NULL,0},
        +{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1",
        +	NID_aes_192_cbc_hmac_sha1,0,NULL,0},
        +{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1",
        +	NID_aes_256_cbc_hmac_sha1,0,NULL,0},
        +{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5970]),0},
        +};
        +
        +static const unsigned int sn_objs[NUM_SN]={
        +364,	/* "AD_DVCS" */
        +419,	/* "AES-128-CBC" */
        +916,	/* "AES-128-CBC-HMAC-SHA1" */
        +421,	/* "AES-128-CFB" */
        +650,	/* "AES-128-CFB1" */
        +653,	/* "AES-128-CFB8" */
        +904,	/* "AES-128-CTR" */
        +418,	/* "AES-128-ECB" */
        +420,	/* "AES-128-OFB" */
        +913,	/* "AES-128-XTS" */
        +423,	/* "AES-192-CBC" */
        +917,	/* "AES-192-CBC-HMAC-SHA1" */
        +425,	/* "AES-192-CFB" */
        +651,	/* "AES-192-CFB1" */
        +654,	/* "AES-192-CFB8" */
        +905,	/* "AES-192-CTR" */
        +422,	/* "AES-192-ECB" */
        +424,	/* "AES-192-OFB" */
        +427,	/* "AES-256-CBC" */
        +918,	/* "AES-256-CBC-HMAC-SHA1" */
        +429,	/* "AES-256-CFB" */
        +652,	/* "AES-256-CFB1" */
        +655,	/* "AES-256-CFB8" */
        +906,	/* "AES-256-CTR" */
        +426,	/* "AES-256-ECB" */
        +428,	/* "AES-256-OFB" */
        +914,	/* "AES-256-XTS" */
        +91,	/* "BF-CBC" */
        +93,	/* "BF-CFB" */
        +92,	/* "BF-ECB" */
        +94,	/* "BF-OFB" */
        +14,	/* "C" */
        +751,	/* "CAMELLIA-128-CBC" */
        +757,	/* "CAMELLIA-128-CFB" */
        +760,	/* "CAMELLIA-128-CFB1" */
        +763,	/* "CAMELLIA-128-CFB8" */
        +754,	/* "CAMELLIA-128-ECB" */
        +766,	/* "CAMELLIA-128-OFB" */
        +752,	/* "CAMELLIA-192-CBC" */
        +758,	/* "CAMELLIA-192-CFB" */
        +761,	/* "CAMELLIA-192-CFB1" */
        +764,	/* "CAMELLIA-192-CFB8" */
        +755,	/* "CAMELLIA-192-ECB" */
        +767,	/* "CAMELLIA-192-OFB" */
        +753,	/* "CAMELLIA-256-CBC" */
        +759,	/* "CAMELLIA-256-CFB" */
        +762,	/* "CAMELLIA-256-CFB1" */
        +765,	/* "CAMELLIA-256-CFB8" */
        +756,	/* "CAMELLIA-256-ECB" */
        +768,	/* "CAMELLIA-256-OFB" */
        +108,	/* "CAST5-CBC" */
        +110,	/* "CAST5-CFB" */
        +109,	/* "CAST5-ECB" */
        +111,	/* "CAST5-OFB" */
        +894,	/* "CMAC" */
        +13,	/* "CN" */
        +141,	/* "CRLReason" */
        +417,	/* "CSPName" */
        +367,	/* "CrlID" */
        +391,	/* "DC" */
        +31,	/* "DES-CBC" */
        +643,	/* "DES-CDMF" */
        +30,	/* "DES-CFB" */
        +656,	/* "DES-CFB1" */
        +657,	/* "DES-CFB8" */
        +29,	/* "DES-ECB" */
        +32,	/* "DES-EDE" */
        +43,	/* "DES-EDE-CBC" */
        +60,	/* "DES-EDE-CFB" */
        +62,	/* "DES-EDE-OFB" */
        +33,	/* "DES-EDE3" */
        +44,	/* "DES-EDE3-CBC" */
        +61,	/* "DES-EDE3-CFB" */
        +658,	/* "DES-EDE3-CFB1" */
        +659,	/* "DES-EDE3-CFB8" */
        +63,	/* "DES-EDE3-OFB" */
        +45,	/* "DES-OFB" */
        +80,	/* "DESX-CBC" */
        +380,	/* "DOD" */
        +116,	/* "DSA" */
        +66,	/* "DSA-SHA" */
        +113,	/* "DSA-SHA1" */
        +70,	/* "DSA-SHA1-old" */
        +67,	/* "DSA-old" */
        +297,	/* "DVCS" */
        +99,	/* "GN" */
        +855,	/* "HMAC" */
        +780,	/* "HMAC-MD5" */
        +781,	/* "HMAC-SHA1" */
        +381,	/* "IANA" */
        +34,	/* "IDEA-CBC" */
        +35,	/* "IDEA-CFB" */
        +36,	/* "IDEA-ECB" */
        +46,	/* "IDEA-OFB" */
        +181,	/* "ISO" */
        +183,	/* "ISO-US" */
        +645,	/* "ITU-T" */
        +646,	/* "JOINT-ISO-ITU-T" */
        +773,	/* "KISA" */
        +15,	/* "L" */
        +856,	/* "LocalKeySet" */
        + 3,	/* "MD2" */
        +257,	/* "MD4" */
        + 4,	/* "MD5" */
        +114,	/* "MD5-SHA1" */
        +95,	/* "MDC2" */
        +911,	/* "MGF1" */
        +388,	/* "Mail" */
        +393,	/* "NULL" */
        +404,	/* "NULL" */
        +57,	/* "Netscape" */
        +366,	/* "Nonce" */
        +17,	/* "O" */
        +178,	/* "OCSP" */
        +180,	/* "OCSPSigning" */
        +379,	/* "ORG" */
        +18,	/* "OU" */
        +749,	/* "Oakley-EC2N-3" */
        +750,	/* "Oakley-EC2N-4" */
        + 9,	/* "PBE-MD2-DES" */
        +168,	/* "PBE-MD2-RC2-64" */
        +10,	/* "PBE-MD5-DES" */
        +169,	/* "PBE-MD5-RC2-64" */
        +147,	/* "PBE-SHA1-2DES" */
        +146,	/* "PBE-SHA1-3DES" */
        +170,	/* "PBE-SHA1-DES" */
        +148,	/* "PBE-SHA1-RC2-128" */
        +149,	/* "PBE-SHA1-RC2-40" */
        +68,	/* "PBE-SHA1-RC2-64" */
        +144,	/* "PBE-SHA1-RC4-128" */
        +145,	/* "PBE-SHA1-RC4-40" */
        +161,	/* "PBES2" */
        +69,	/* "PBKDF2" */
        +162,	/* "PBMAC1" */
        +127,	/* "PKIX" */
        +98,	/* "RC2-40-CBC" */
        +166,	/* "RC2-64-CBC" */
        +37,	/* "RC2-CBC" */
        +39,	/* "RC2-CFB" */
        +38,	/* "RC2-ECB" */
        +40,	/* "RC2-OFB" */
        + 5,	/* "RC4" */
        +97,	/* "RC4-40" */
        +915,	/* "RC4-HMAC-MD5" */
        +120,	/* "RC5-CBC" */
        +122,	/* "RC5-CFB" */
        +121,	/* "RC5-ECB" */
        +123,	/* "RC5-OFB" */
        +117,	/* "RIPEMD160" */
        +124,	/* "RLE" */
        +19,	/* "RSA" */
        + 7,	/* "RSA-MD2" */
        +396,	/* "RSA-MD4" */
        + 8,	/* "RSA-MD5" */
        +96,	/* "RSA-MDC2" */
        +104,	/* "RSA-NP-MD5" */
        +119,	/* "RSA-RIPEMD160" */
        +42,	/* "RSA-SHA" */
        +65,	/* "RSA-SHA1" */
        +115,	/* "RSA-SHA1-2" */
        +671,	/* "RSA-SHA224" */
        +668,	/* "RSA-SHA256" */
        +669,	/* "RSA-SHA384" */
        +670,	/* "RSA-SHA512" */
        +919,	/* "RSAES-OAEP" */
        +912,	/* "RSASSA-PSS" */
        +777,	/* "SEED-CBC" */
        +779,	/* "SEED-CFB" */
        +776,	/* "SEED-ECB" */
        +778,	/* "SEED-OFB" */
        +41,	/* "SHA" */
        +64,	/* "SHA1" */
        +675,	/* "SHA224" */
        +672,	/* "SHA256" */
        +673,	/* "SHA384" */
        +674,	/* "SHA512" */
        +188,	/* "SMIME" */
        +167,	/* "SMIME-CAPS" */
        +100,	/* "SN" */
        +16,	/* "ST" */
        +143,	/* "SXNetID" */
        +458,	/* "UID" */
        + 0,	/* "UNDEF" */
        +11,	/* "X500" */
        +378,	/* "X500algorithms" */
        +12,	/* "X509" */
        +184,	/* "X9-57" */
        +185,	/* "X9cm" */
        +125,	/* "ZLIB" */
        +478,	/* "aRecord" */
        +289,	/* "aaControls" */
        +287,	/* "ac-auditEntity" */
        +397,	/* "ac-proxying" */
        +288,	/* "ac-targeting" */
        +368,	/* "acceptableResponses" */
        +446,	/* "account" */
        +363,	/* "ad_timestamping" */
        +376,	/* "algorithm" */
        +405,	/* "ansi-X9-62" */
        +910,	/* "anyExtendedKeyUsage" */
        +746,	/* "anyPolicy" */
        +370,	/* "archiveCutoff" */
        +484,	/* "associatedDomain" */
        +485,	/* "associatedName" */
        +501,	/* "audio" */
        +177,	/* "authorityInfoAccess" */
        +90,	/* "authorityKeyIdentifier" */
        +882,	/* "authorityRevocationList" */
        +87,	/* "basicConstraints" */
        +365,	/* "basicOCSPResponse" */
        +285,	/* "biometricInfo" */
        +494,	/* "buildingName" */
        +860,	/* "businessCategory" */
        +691,	/* "c2onb191v4" */
        +692,	/* "c2onb191v5" */
        +697,	/* "c2onb239v4" */
        +698,	/* "c2onb239v5" */
        +684,	/* "c2pnb163v1" */
        +685,	/* "c2pnb163v2" */
        +686,	/* "c2pnb163v3" */
        +687,	/* "c2pnb176v1" */
        +693,	/* "c2pnb208w1" */
        +699,	/* "c2pnb272w1" */
        +700,	/* "c2pnb304w1" */
        +702,	/* "c2pnb368w1" */
        +688,	/* "c2tnb191v1" */
        +689,	/* "c2tnb191v2" */
        +690,	/* "c2tnb191v3" */
        +694,	/* "c2tnb239v1" */
        +695,	/* "c2tnb239v2" */
        +696,	/* "c2tnb239v3" */
        +701,	/* "c2tnb359v1" */
        +703,	/* "c2tnb431r1" */
        +881,	/* "cACertificate" */
        +483,	/* "cNAMERecord" */
        +179,	/* "caIssuers" */
        +785,	/* "caRepository" */
        +443,	/* "caseIgnoreIA5StringSyntax" */
        +152,	/* "certBag" */
        +677,	/* "certicom-arc" */
        +771,	/* "certificateIssuer" */
        +89,	/* "certificatePolicies" */
        +883,	/* "certificateRevocationList" */
        +54,	/* "challengePassword" */
        +407,	/* "characteristic-two-field" */
        +395,	/* "clearance" */
        +130,	/* "clientAuth" */
        +131,	/* "codeSigning" */
        +50,	/* "contentType" */
        +53,	/* "countersignature" */
        +153,	/* "crlBag" */
        +103,	/* "crlDistributionPoints" */
        +88,	/* "crlNumber" */
        +884,	/* "crossCertificatePair" */
        +806,	/* "cryptocom" */
        +805,	/* "cryptopro" */
        +500,	/* "dITRedirect" */
        +451,	/* "dNSDomain" */
        +495,	/* "dSAQuality" */
        +434,	/* "data" */
        +390,	/* "dcobject" */
        +140,	/* "deltaCRL" */
        +891,	/* "deltaRevocationList" */
        +107,	/* "description" */
        +871,	/* "destinationIndicator" */
        +28,	/* "dhKeyAgreement" */
        +382,	/* "directory" */
        +887,	/* "distinguishedName" */
        +892,	/* "dmdName" */
        +174,	/* "dnQualifier" */
        +447,	/* "document" */
        +471,	/* "documentAuthor" */
        +468,	/* "documentIdentifier" */
        +472,	/* "documentLocation" */
        +502,	/* "documentPublisher" */
        +449,	/* "documentSeries" */
        +469,	/* "documentTitle" */
        +470,	/* "documentVersion" */
        +392,	/* "domain" */
        +452,	/* "domainRelatedObject" */
        +802,	/* "dsa_with_SHA224" */
        +803,	/* "dsa_with_SHA256" */
        +791,	/* "ecdsa-with-Recommended" */
        +416,	/* "ecdsa-with-SHA1" */
        +793,	/* "ecdsa-with-SHA224" */
        +794,	/* "ecdsa-with-SHA256" */
        +795,	/* "ecdsa-with-SHA384" */
        +796,	/* "ecdsa-with-SHA512" */
        +792,	/* "ecdsa-with-Specified" */
        +48,	/* "emailAddress" */
        +132,	/* "emailProtection" */
        +885,	/* "enhancedSearchGuide" */
        +389,	/* "enterprises" */
        +384,	/* "experimental" */
        +172,	/* "extReq" */
        +56,	/* "extendedCertificateAttributes" */
        +126,	/* "extendedKeyUsage" */
        +372,	/* "extendedStatus" */
        +867,	/* "facsimileTelephoneNumber" */
        +462,	/* "favouriteDrink" */
        +857,	/* "freshestCRL" */
        +453,	/* "friendlyCountry" */
        +490,	/* "friendlyCountryName" */
        +156,	/* "friendlyName" */
        +509,	/* "generationQualifier" */
        +815,	/* "gost-mac" */
        +811,	/* "gost2001" */
        +851,	/* "gost2001cc" */
        +813,	/* "gost89" */
        +814,	/* "gost89-cnt" */
        +812,	/* "gost94" */
        +850,	/* "gost94cc" */
        +797,	/* "hmacWithMD5" */
        +163,	/* "hmacWithSHA1" */
        +798,	/* "hmacWithSHA224" */
        +799,	/* "hmacWithSHA256" */
        +800,	/* "hmacWithSHA384" */
        +801,	/* "hmacWithSHA512" */
        +432,	/* "holdInstructionCallIssuer" */
        +430,	/* "holdInstructionCode" */
        +431,	/* "holdInstructionNone" */
        +433,	/* "holdInstructionReject" */
        +486,	/* "homePostalAddress" */
        +473,	/* "homeTelephoneNumber" */
        +466,	/* "host" */
        +889,	/* "houseIdentifier" */
        +442,	/* "iA5StringSyntax" */
        +783,	/* "id-DHBasedMac" */
        +824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
        +825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
        +826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
        +827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
        +819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
        +829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
        +828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
        +830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
        +820,	/* "id-Gost28147-89-None-KeyMeshing" */
        +823,	/* "id-Gost28147-89-TestParamSet" */
        +849,	/* "id-Gost28147-89-cc" */
        +840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
        +841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
        +842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
        +843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
        +844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
        +854,	/* "id-GostR3410-2001-ParamSet-cc" */
        +839,	/* "id-GostR3410-2001-TestParamSet" */
        +817,	/* "id-GostR3410-2001DH" */
        +832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
        +833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
        +834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
        +835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
        +836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
        +837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
        +838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
        +831,	/* "id-GostR3410-94-TestParamSet" */
        +845,	/* "id-GostR3410-94-a" */
        +846,	/* "id-GostR3410-94-aBis" */
        +847,	/* "id-GostR3410-94-b" */
        +848,	/* "id-GostR3410-94-bBis" */
        +818,	/* "id-GostR3410-94DH" */
        +822,	/* "id-GostR3411-94-CryptoProParamSet" */
        +821,	/* "id-GostR3411-94-TestParamSet" */
        +807,	/* "id-GostR3411-94-with-GostR3410-2001" */
        +853,	/* "id-GostR3411-94-with-GostR3410-2001-cc" */
        +808,	/* "id-GostR3411-94-with-GostR3410-94" */
        +852,	/* "id-GostR3411-94-with-GostR3410-94-cc" */
        +810,	/* "id-HMACGostR3411-94" */
        +782,	/* "id-PasswordBasedMAC" */
        +266,	/* "id-aca" */
        +355,	/* "id-aca-accessIdentity" */
        +354,	/* "id-aca-authenticationInfo" */
        +356,	/* "id-aca-chargingIdentity" */
        +399,	/* "id-aca-encAttrs" */
        +357,	/* "id-aca-group" */
        +358,	/* "id-aca-role" */
        +176,	/* "id-ad" */
        +896,	/* "id-aes128-CCM" */
        +895,	/* "id-aes128-GCM" */
        +788,	/* "id-aes128-wrap" */
        +897,	/* "id-aes128-wrap-pad" */
        +899,	/* "id-aes192-CCM" */
        +898,	/* "id-aes192-GCM" */
        +789,	/* "id-aes192-wrap" */
        +900,	/* "id-aes192-wrap-pad" */
        +902,	/* "id-aes256-CCM" */
        +901,	/* "id-aes256-GCM" */
        +790,	/* "id-aes256-wrap" */
        +903,	/* "id-aes256-wrap-pad" */
        +262,	/* "id-alg" */
        +893,	/* "id-alg-PWRI-KEK" */
        +323,	/* "id-alg-des40" */
        +326,	/* "id-alg-dh-pop" */
        +325,	/* "id-alg-dh-sig-hmac-sha1" */
        +324,	/* "id-alg-noSignature" */
        +907,	/* "id-camellia128-wrap" */
        +908,	/* "id-camellia192-wrap" */
        +909,	/* "id-camellia256-wrap" */
        +268,	/* "id-cct" */
        +361,	/* "id-cct-PKIData" */
        +362,	/* "id-cct-PKIResponse" */
        +360,	/* "id-cct-crs" */
        +81,	/* "id-ce" */
        +680,	/* "id-characteristic-two-basis" */
        +263,	/* "id-cmc" */
        +334,	/* "id-cmc-addExtensions" */
        +346,	/* "id-cmc-confirmCertAcceptance" */
        +330,	/* "id-cmc-dataReturn" */
        +336,	/* "id-cmc-decryptedPOP" */
        +335,	/* "id-cmc-encryptedPOP" */
        +339,	/* "id-cmc-getCRL" */
        +338,	/* "id-cmc-getCert" */
        +328,	/* "id-cmc-identification" */
        +329,	/* "id-cmc-identityProof" */
        +337,	/* "id-cmc-lraPOPWitness" */
        +344,	/* "id-cmc-popLinkRandom" */
        +345,	/* "id-cmc-popLinkWitness" */
        +343,	/* "id-cmc-queryPending" */
        +333,	/* "id-cmc-recipientNonce" */
        +341,	/* "id-cmc-regInfo" */
        +342,	/* "id-cmc-responseInfo" */
        +340,	/* "id-cmc-revokeRequest" */
        +332,	/* "id-cmc-senderNonce" */
        +327,	/* "id-cmc-statusInfo" */
        +331,	/* "id-cmc-transactionId" */
        +787,	/* "id-ct-asciiTextWithCRLF" */
        +408,	/* "id-ecPublicKey" */
        +508,	/* "id-hex-multipart-message" */
        +507,	/* "id-hex-partial-message" */
        +260,	/* "id-it" */
        +302,	/* "id-it-caKeyUpdateInfo" */
        +298,	/* "id-it-caProtEncCert" */
        +311,	/* "id-it-confirmWaitTime" */
        +303,	/* "id-it-currentCRL" */
        +300,	/* "id-it-encKeyPairTypes" */
        +310,	/* "id-it-implicitConfirm" */
        +308,	/* "id-it-keyPairParamRep" */
        +307,	/* "id-it-keyPairParamReq" */
        +312,	/* "id-it-origPKIMessage" */
        +301,	/* "id-it-preferredSymmAlg" */
        +309,	/* "id-it-revPassphrase" */
        +299,	/* "id-it-signKeyPairTypes" */
        +305,	/* "id-it-subscriptionRequest" */
        +306,	/* "id-it-subscriptionResponse" */
        +784,	/* "id-it-suppLangTags" */
        +304,	/* "id-it-unsupportedOIDs" */
        +128,	/* "id-kp" */
        +280,	/* "id-mod-attribute-cert" */
        +274,	/* "id-mod-cmc" */
        +277,	/* "id-mod-cmp" */
        +284,	/* "id-mod-cmp2000" */
        +273,	/* "id-mod-crmf" */
        +283,	/* "id-mod-dvcs" */
        +275,	/* "id-mod-kea-profile-88" */
        +276,	/* "id-mod-kea-profile-93" */
        +282,	/* "id-mod-ocsp" */
        +278,	/* "id-mod-qualified-cert-88" */
        +279,	/* "id-mod-qualified-cert-93" */
        +281,	/* "id-mod-timestamp-protocol" */
        +264,	/* "id-on" */
        +858,	/* "id-on-permanentIdentifier" */
        +347,	/* "id-on-personalData" */
        +265,	/* "id-pda" */
        +352,	/* "id-pda-countryOfCitizenship" */
        +353,	/* "id-pda-countryOfResidence" */
        +348,	/* "id-pda-dateOfBirth" */
        +351,	/* "id-pda-gender" */
        +349,	/* "id-pda-placeOfBirth" */
        +175,	/* "id-pe" */
        +261,	/* "id-pkip" */
        +258,	/* "id-pkix-mod" */
        +269,	/* "id-pkix1-explicit-88" */
        +271,	/* "id-pkix1-explicit-93" */
        +270,	/* "id-pkix1-implicit-88" */
        +272,	/* "id-pkix1-implicit-93" */
        +662,	/* "id-ppl" */
        +664,	/* "id-ppl-anyLanguage" */
        +667,	/* "id-ppl-independent" */
        +665,	/* "id-ppl-inheritAll" */
        +267,	/* "id-qcs" */
        +359,	/* "id-qcs-pkixQCSyntax-v1" */
        +259,	/* "id-qt" */
        +164,	/* "id-qt-cps" */
        +165,	/* "id-qt-unotice" */
        +313,	/* "id-regCtrl" */
        +316,	/* "id-regCtrl-authenticator" */
        +319,	/* "id-regCtrl-oldCertID" */
        +318,	/* "id-regCtrl-pkiArchiveOptions" */
        +317,	/* "id-regCtrl-pkiPublicationInfo" */
        +320,	/* "id-regCtrl-protocolEncrKey" */
        +315,	/* "id-regCtrl-regToken" */
        +314,	/* "id-regInfo" */
        +322,	/* "id-regInfo-certReq" */
        +321,	/* "id-regInfo-utf8Pairs" */
        +512,	/* "id-set" */
        +191,	/* "id-smime-aa" */
        +215,	/* "id-smime-aa-contentHint" */
        +218,	/* "id-smime-aa-contentIdentifier" */
        +221,	/* "id-smime-aa-contentReference" */
        +240,	/* "id-smime-aa-dvcs-dvc" */
        +217,	/* "id-smime-aa-encapContentType" */
        +222,	/* "id-smime-aa-encrypKeyPref" */
        +220,	/* "id-smime-aa-equivalentLabels" */
        +232,	/* "id-smime-aa-ets-CertificateRefs" */
        +233,	/* "id-smime-aa-ets-RevocationRefs" */
        +238,	/* "id-smime-aa-ets-archiveTimeStamp" */
        +237,	/* "id-smime-aa-ets-certCRLTimestamp" */
        +234,	/* "id-smime-aa-ets-certValues" */
        +227,	/* "id-smime-aa-ets-commitmentType" */
        +231,	/* "id-smime-aa-ets-contentTimestamp" */
        +236,	/* "id-smime-aa-ets-escTimeStamp" */
        +230,	/* "id-smime-aa-ets-otherSigCert" */
        +235,	/* "id-smime-aa-ets-revocationValues" */
        +226,	/* "id-smime-aa-ets-sigPolicyId" */
        +229,	/* "id-smime-aa-ets-signerAttr" */
        +228,	/* "id-smime-aa-ets-signerLocation" */
        +219,	/* "id-smime-aa-macValue" */
        +214,	/* "id-smime-aa-mlExpandHistory" */
        +216,	/* "id-smime-aa-msgSigDigest" */
        +212,	/* "id-smime-aa-receiptRequest" */
        +213,	/* "id-smime-aa-securityLabel" */
        +239,	/* "id-smime-aa-signatureType" */
        +223,	/* "id-smime-aa-signingCertificate" */
        +224,	/* "id-smime-aa-smimeEncryptCerts" */
        +225,	/* "id-smime-aa-timeStampToken" */
        +192,	/* "id-smime-alg" */
        +243,	/* "id-smime-alg-3DESwrap" */
        +246,	/* "id-smime-alg-CMS3DESwrap" */
        +247,	/* "id-smime-alg-CMSRC2wrap" */
        +245,	/* "id-smime-alg-ESDH" */
        +241,	/* "id-smime-alg-ESDHwith3DES" */
        +242,	/* "id-smime-alg-ESDHwithRC2" */
        +244,	/* "id-smime-alg-RC2wrap" */
        +193,	/* "id-smime-cd" */
        +248,	/* "id-smime-cd-ldap" */
        +190,	/* "id-smime-ct" */
        +210,	/* "id-smime-ct-DVCSRequestData" */
        +211,	/* "id-smime-ct-DVCSResponseData" */
        +208,	/* "id-smime-ct-TDTInfo" */
        +207,	/* "id-smime-ct-TSTInfo" */
        +205,	/* "id-smime-ct-authData" */
        +786,	/* "id-smime-ct-compressedData" */
        +209,	/* "id-smime-ct-contentInfo" */
        +206,	/* "id-smime-ct-publishCert" */
        +204,	/* "id-smime-ct-receipt" */
        +195,	/* "id-smime-cti" */
        +255,	/* "id-smime-cti-ets-proofOfApproval" */
        +256,	/* "id-smime-cti-ets-proofOfCreation" */
        +253,	/* "id-smime-cti-ets-proofOfDelivery" */
        +251,	/* "id-smime-cti-ets-proofOfOrigin" */
        +252,	/* "id-smime-cti-ets-proofOfReceipt" */
        +254,	/* "id-smime-cti-ets-proofOfSender" */
        +189,	/* "id-smime-mod" */
        +196,	/* "id-smime-mod-cms" */
        +197,	/* "id-smime-mod-ess" */
        +202,	/* "id-smime-mod-ets-eSigPolicy-88" */
        +203,	/* "id-smime-mod-ets-eSigPolicy-97" */
        +200,	/* "id-smime-mod-ets-eSignature-88" */
        +201,	/* "id-smime-mod-ets-eSignature-97" */
        +199,	/* "id-smime-mod-msg-v3" */
        +198,	/* "id-smime-mod-oid" */
        +194,	/* "id-smime-spq" */
        +250,	/* "id-smime-spq-ets-sqt-unotice" */
        +249,	/* "id-smime-spq-ets-sqt-uri" */
        +676,	/* "identified-organization" */
        +461,	/* "info" */
        +748,	/* "inhibitAnyPolicy" */
        +101,	/* "initials" */
        +647,	/* "international-organizations" */
        +869,	/* "internationaliSDNNumber" */
        +142,	/* "invalidityDate" */
        +294,	/* "ipsecEndSystem" */
        +295,	/* "ipsecTunnel" */
        +296,	/* "ipsecUser" */
        +86,	/* "issuerAltName" */
        +770,	/* "issuingDistributionPoint" */
        +492,	/* "janetMailbox" */
        +150,	/* "keyBag" */
        +83,	/* "keyUsage" */
        +477,	/* "lastModifiedBy" */
        +476,	/* "lastModifiedTime" */
        +157,	/* "localKeyID" */
        +480,	/* "mXRecord" */
        +460,	/* "mail" */
        +493,	/* "mailPreferenceOption" */
        +467,	/* "manager" */
        +809,	/* "md_gost94" */
        +875,	/* "member" */
        +182,	/* "member-body" */
        +51,	/* "messageDigest" */
        +383,	/* "mgmt" */
        +504,	/* "mime-mhs" */
        +506,	/* "mime-mhs-bodies" */
        +505,	/* "mime-mhs-headings" */
        +488,	/* "mobileTelephoneNumber" */
        +136,	/* "msCTLSign" */
        +135,	/* "msCodeCom" */
        +134,	/* "msCodeInd" */
        +138,	/* "msEFS" */
        +171,	/* "msExtReq" */
        +137,	/* "msSGC" */
        +648,	/* "msSmartcardLogin" */
        +649,	/* "msUPN" */
        +481,	/* "nSRecord" */
        +173,	/* "name" */
        +666,	/* "nameConstraints" */
        +369,	/* "noCheck" */
        +403,	/* "noRevAvail" */
        +72,	/* "nsBaseUrl" */
        +76,	/* "nsCaPolicyUrl" */
        +74,	/* "nsCaRevocationUrl" */
        +58,	/* "nsCertExt" */
        +79,	/* "nsCertSequence" */
        +71,	/* "nsCertType" */
        +78,	/* "nsComment" */
        +59,	/* "nsDataType" */
        +75,	/* "nsRenewalUrl" */
        +73,	/* "nsRevocationUrl" */
        +139,	/* "nsSGC" */
        +77,	/* "nsSslServerName" */
        +681,	/* "onBasis" */
        +491,	/* "organizationalStatus" */
        +475,	/* "otherMailbox" */
        +876,	/* "owner" */
        +489,	/* "pagerTelephoneNumber" */
        +374,	/* "path" */
        +112,	/* "pbeWithMD5AndCast5CBC" */
        +499,	/* "personalSignature" */
        +487,	/* "personalTitle" */
        +464,	/* "photo" */
        +863,	/* "physicalDeliveryOfficeName" */
        +437,	/* "pilot" */
        +439,	/* "pilotAttributeSyntax" */
        +438,	/* "pilotAttributeType" */
        +479,	/* "pilotAttributeType27" */
        +456,	/* "pilotDSA" */
        +441,	/* "pilotGroups" */
        +444,	/* "pilotObject" */
        +440,	/* "pilotObjectClass" */
        +455,	/* "pilotOrganization" */
        +445,	/* "pilotPerson" */
        + 2,	/* "pkcs" */
        +186,	/* "pkcs1" */
        +27,	/* "pkcs3" */
        +187,	/* "pkcs5" */
        +20,	/* "pkcs7" */
        +21,	/* "pkcs7-data" */
        +25,	/* "pkcs7-digestData" */
        +26,	/* "pkcs7-encryptedData" */
        +23,	/* "pkcs7-envelopedData" */
        +24,	/* "pkcs7-signedAndEnvelopedData" */
        +22,	/* "pkcs7-signedData" */
        +151,	/* "pkcs8ShroudedKeyBag" */
        +47,	/* "pkcs9" */
        +401,	/* "policyConstraints" */
        +747,	/* "policyMappings" */
        +862,	/* "postOfficeBox" */
        +861,	/* "postalAddress" */
        +661,	/* "postalCode" */
        +683,	/* "ppBasis" */
        +872,	/* "preferredDeliveryMethod" */
        +873,	/* "presentationAddress" */
        +816,	/* "prf-gostr3411-94" */
        +406,	/* "prime-field" */
        +409,	/* "prime192v1" */
        +410,	/* "prime192v2" */
        +411,	/* "prime192v3" */
        +412,	/* "prime239v1" */
        +413,	/* "prime239v2" */
        +414,	/* "prime239v3" */
        +415,	/* "prime256v1" */
        +385,	/* "private" */
        +84,	/* "privateKeyUsagePeriod" */
        +886,	/* "protocolInformation" */
        +663,	/* "proxyCertInfo" */
        +510,	/* "pseudonym" */
        +435,	/* "pss" */
        +286,	/* "qcStatements" */
        +457,	/* "qualityLabelledData" */
        +450,	/* "rFC822localPart" */
        +870,	/* "registeredAddress" */
        +400,	/* "role" */
        +877,	/* "roleOccupant" */
        +448,	/* "room" */
        +463,	/* "roomNumber" */
        + 6,	/* "rsaEncryption" */
        +644,	/* "rsaOAEPEncryptionSET" */
        +377,	/* "rsaSignature" */
        + 1,	/* "rsadsi" */
        +482,	/* "sOARecord" */
        +155,	/* "safeContentsBag" */
        +291,	/* "sbgp-autonomousSysNum" */
        +290,	/* "sbgp-ipAddrBlock" */
        +292,	/* "sbgp-routerIdentifier" */
        +159,	/* "sdsiCertificate" */
        +859,	/* "searchGuide" */
        +704,	/* "secp112r1" */
        +705,	/* "secp112r2" */
        +706,	/* "secp128r1" */
        +707,	/* "secp128r2" */
        +708,	/* "secp160k1" */
        +709,	/* "secp160r1" */
        +710,	/* "secp160r2" */
        +711,	/* "secp192k1" */
        +712,	/* "secp224k1" */
        +713,	/* "secp224r1" */
        +714,	/* "secp256k1" */
        +715,	/* "secp384r1" */
        +716,	/* "secp521r1" */
        +154,	/* "secretBag" */
        +474,	/* "secretary" */
        +717,	/* "sect113r1" */
        +718,	/* "sect113r2" */
        +719,	/* "sect131r1" */
        +720,	/* "sect131r2" */
        +721,	/* "sect163k1" */
        +722,	/* "sect163r1" */
        +723,	/* "sect163r2" */
        +724,	/* "sect193r1" */
        +725,	/* "sect193r2" */
        +726,	/* "sect233k1" */
        +727,	/* "sect233r1" */
        +728,	/* "sect239k1" */
        +729,	/* "sect283k1" */
        +730,	/* "sect283r1" */
        +731,	/* "sect409k1" */
        +732,	/* "sect409r1" */
        +733,	/* "sect571k1" */
        +734,	/* "sect571r1" */
        +386,	/* "security" */
        +878,	/* "seeAlso" */
        +394,	/* "selected-attribute-types" */
        +105,	/* "serialNumber" */
        +129,	/* "serverAuth" */
        +371,	/* "serviceLocator" */
        +625,	/* "set-addPolicy" */
        +515,	/* "set-attr" */
        +518,	/* "set-brand" */
        +638,	/* "set-brand-AmericanExpress" */
        +637,	/* "set-brand-Diners" */
        +636,	/* "set-brand-IATA-ATA" */
        +639,	/* "set-brand-JCB" */
        +641,	/* "set-brand-MasterCard" */
        +642,	/* "set-brand-Novus" */
        +640,	/* "set-brand-Visa" */
        +517,	/* "set-certExt" */
        +513,	/* "set-ctype" */
        +514,	/* "set-msgExt" */
        +516,	/* "set-policy" */
        +607,	/* "set-policy-root" */
        +624,	/* "set-rootKeyThumb" */
        +620,	/* "setAttr-Cert" */
        +631,	/* "setAttr-GenCryptgrm" */
        +623,	/* "setAttr-IssCap" */
        +628,	/* "setAttr-IssCap-CVM" */
        +630,	/* "setAttr-IssCap-Sig" */
        +629,	/* "setAttr-IssCap-T2" */
        +621,	/* "setAttr-PGWYcap" */
        +635,	/* "setAttr-SecDevSig" */
        +632,	/* "setAttr-T2Enc" */
        +633,	/* "setAttr-T2cleartxt" */
        +634,	/* "setAttr-TokICCsig" */
        +627,	/* "setAttr-Token-B0Prime" */
        +626,	/* "setAttr-Token-EMV" */
        +622,	/* "setAttr-TokenType" */
        +619,	/* "setCext-IssuerCapabilities" */
        +615,	/* "setCext-PGWYcapabilities" */
        +616,	/* "setCext-TokenIdentifier" */
        +618,	/* "setCext-TokenType" */
        +617,	/* "setCext-Track2Data" */
        +611,	/* "setCext-cCertRequired" */
        +609,	/* "setCext-certType" */
        +608,	/* "setCext-hashedRoot" */
        +610,	/* "setCext-merchData" */
        +613,	/* "setCext-setExt" */
        +614,	/* "setCext-setQualf" */
        +612,	/* "setCext-tunneling" */
        +540,	/* "setct-AcqCardCodeMsg" */
        +576,	/* "setct-AcqCardCodeMsgTBE" */
        +570,	/* "setct-AuthReqTBE" */
        +534,	/* "setct-AuthReqTBS" */
        +527,	/* "setct-AuthResBaggage" */
        +571,	/* "setct-AuthResTBE" */
        +572,	/* "setct-AuthResTBEX" */
        +535,	/* "setct-AuthResTBS" */
        +536,	/* "setct-AuthResTBSX" */
        +528,	/* "setct-AuthRevReqBaggage" */
        +577,	/* "setct-AuthRevReqTBE" */
        +541,	/* "setct-AuthRevReqTBS" */
        +529,	/* "setct-AuthRevResBaggage" */
        +542,	/* "setct-AuthRevResData" */
        +578,	/* "setct-AuthRevResTBE" */
        +579,	/* "setct-AuthRevResTBEB" */
        +543,	/* "setct-AuthRevResTBS" */
        +573,	/* "setct-AuthTokenTBE" */
        +537,	/* "setct-AuthTokenTBS" */
        +600,	/* "setct-BCIDistributionTBS" */
        +558,	/* "setct-BatchAdminReqData" */
        +592,	/* "setct-BatchAdminReqTBE" */
        +559,	/* "setct-BatchAdminResData" */
        +593,	/* "setct-BatchAdminResTBE" */
        +599,	/* "setct-CRLNotificationResTBS" */
        +598,	/* "setct-CRLNotificationTBS" */
        +580,	/* "setct-CapReqTBE" */
        +581,	/* "setct-CapReqTBEX" */
        +544,	/* "setct-CapReqTBS" */
        +545,	/* "setct-CapReqTBSX" */
        +546,	/* "setct-CapResData" */
        +582,	/* "setct-CapResTBE" */
        +583,	/* "setct-CapRevReqTBE" */
        +584,	/* "setct-CapRevReqTBEX" */
        +547,	/* "setct-CapRevReqTBS" */
        +548,	/* "setct-CapRevReqTBSX" */
        +549,	/* "setct-CapRevResData" */
        +585,	/* "setct-CapRevResTBE" */
        +538,	/* "setct-CapTokenData" */
        +530,	/* "setct-CapTokenSeq" */
        +574,	/* "setct-CapTokenTBE" */
        +575,	/* "setct-CapTokenTBEX" */
        +539,	/* "setct-CapTokenTBS" */
        +560,	/* "setct-CardCInitResTBS" */
        +566,	/* "setct-CertInqReqTBS" */
        +563,	/* "setct-CertReqData" */
        +595,	/* "setct-CertReqTBE" */
        +596,	/* "setct-CertReqTBEX" */
        +564,	/* "setct-CertReqTBS" */
        +565,	/* "setct-CertResData" */
        +597,	/* "setct-CertResTBE" */
        +586,	/* "setct-CredReqTBE" */
        +587,	/* "setct-CredReqTBEX" */
        +550,	/* "setct-CredReqTBS" */
        +551,	/* "setct-CredReqTBSX" */
        +552,	/* "setct-CredResData" */
        +588,	/* "setct-CredResTBE" */
        +589,	/* "setct-CredRevReqTBE" */
        +590,	/* "setct-CredRevReqTBEX" */
        +553,	/* "setct-CredRevReqTBS" */
        +554,	/* "setct-CredRevReqTBSX" */
        +555,	/* "setct-CredRevResData" */
        +591,	/* "setct-CredRevResTBE" */
        +567,	/* "setct-ErrorTBS" */
        +526,	/* "setct-HODInput" */
        +561,	/* "setct-MeAqCInitResTBS" */
        +522,	/* "setct-OIData" */
        +519,	/* "setct-PANData" */
        +521,	/* "setct-PANOnly" */
        +520,	/* "setct-PANToken" */
        +556,	/* "setct-PCertReqData" */
        +557,	/* "setct-PCertResTBS" */
        +523,	/* "setct-PI" */
        +532,	/* "setct-PI-TBS" */
        +524,	/* "setct-PIData" */
        +525,	/* "setct-PIDataUnsigned" */
        +568,	/* "setct-PIDualSignedTBE" */
        +569,	/* "setct-PIUnsignedTBE" */
        +531,	/* "setct-PInitResData" */
        +533,	/* "setct-PResData" */
        +594,	/* "setct-RegFormReqTBE" */
        +562,	/* "setct-RegFormResTBS" */
        +606,	/* "setext-cv" */
        +601,	/* "setext-genCrypt" */
        +602,	/* "setext-miAuth" */
        +604,	/* "setext-pinAny" */
        +603,	/* "setext-pinSecure" */
        +605,	/* "setext-track2" */
        +52,	/* "signingTime" */
        +454,	/* "simpleSecurityObject" */
        +496,	/* "singleLevelQuality" */
        +387,	/* "snmpv2" */
        +660,	/* "street" */
        +85,	/* "subjectAltName" */
        +769,	/* "subjectDirectoryAttributes" */
        +398,	/* "subjectInfoAccess" */
        +82,	/* "subjectKeyIdentifier" */
        +498,	/* "subtreeMaximumQuality" */
        +497,	/* "subtreeMinimumQuality" */
        +890,	/* "supportedAlgorithms" */
        +874,	/* "supportedApplicationContext" */
        +402,	/* "targetInformation" */
        +864,	/* "telephoneNumber" */
        +866,	/* "teletexTerminalIdentifier" */
        +865,	/* "telexNumber" */
        +459,	/* "textEncodedORAddress" */
        +293,	/* "textNotice" */
        +133,	/* "timeStamping" */
        +106,	/* "title" */
        +682,	/* "tpBasis" */
        +375,	/* "trustRoot" */
        +436,	/* "ucl" */
        +888,	/* "uniqueMember" */
        +55,	/* "unstructuredAddress" */
        +49,	/* "unstructuredName" */
        +880,	/* "userCertificate" */
        +465,	/* "userClass" */
        +879,	/* "userPassword" */
        +373,	/* "valid" */
        +678,	/* "wap" */
        +679,	/* "wap-wsg" */
        +735,	/* "wap-wsg-idm-ecid-wtls1" */
        +743,	/* "wap-wsg-idm-ecid-wtls10" */
        +744,	/* "wap-wsg-idm-ecid-wtls11" */
        +745,	/* "wap-wsg-idm-ecid-wtls12" */
        +736,	/* "wap-wsg-idm-ecid-wtls3" */
        +737,	/* "wap-wsg-idm-ecid-wtls4" */
        +738,	/* "wap-wsg-idm-ecid-wtls5" */
        +739,	/* "wap-wsg-idm-ecid-wtls6" */
        +740,	/* "wap-wsg-idm-ecid-wtls7" */
        +741,	/* "wap-wsg-idm-ecid-wtls8" */
        +742,	/* "wap-wsg-idm-ecid-wtls9" */
        +804,	/* "whirlpool" */
        +868,	/* "x121Address" */
        +503,	/* "x500UniqueIdentifier" */
        +158,	/* "x509Certificate" */
        +160,	/* "x509Crl" */
        +};
        +
        +static const unsigned int ln_objs[NUM_LN]={
        +363,	/* "AD Time Stamping" */
        +405,	/* "ANSI X9.62" */
        +368,	/* "Acceptable OCSP Responses" */
        +910,	/* "Any Extended Key Usage" */
        +664,	/* "Any language" */
        +177,	/* "Authority Information Access" */
        +365,	/* "Basic OCSP Response" */
        +285,	/* "Biometric Info" */
        +179,	/* "CA Issuers" */
        +785,	/* "CA Repository" */
        +131,	/* "Code Signing" */
        +783,	/* "Diffie-Hellman based MAC" */
        +382,	/* "Directory" */
        +392,	/* "Domain" */
        +132,	/* "E-mail Protection" */
        +389,	/* "Enterprises" */
        +384,	/* "Experimental" */
        +372,	/* "Extended OCSP Status" */
        +172,	/* "Extension Request" */
        +813,	/* "GOST 28147-89" */
        +849,	/* "GOST 28147-89 Cryptocom ParamSet" */
        +815,	/* "GOST 28147-89 MAC" */
        +851,	/* "GOST 34.10-2001 Cryptocom" */
        +850,	/* "GOST 34.10-94 Cryptocom" */
        +811,	/* "GOST R 34.10-2001" */
        +817,	/* "GOST R 34.10-2001 DH" */
        +812,	/* "GOST R 34.10-94" */
        +818,	/* "GOST R 34.10-94 DH" */
        +809,	/* "GOST R 34.11-94" */
        +816,	/* "GOST R 34.11-94 PRF" */
        +807,	/* "GOST R 34.11-94 with GOST R 34.10-2001" */
        +853,	/* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
        +808,	/* "GOST R 34.11-94 with GOST R 34.10-94" */
        +852,	/* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
        +854,	/* "GOST R 3410-2001 Parameter Set Cryptocom" */
        +810,	/* "HMAC GOST 34.11-94" */
        +432,	/* "Hold Instruction Call Issuer" */
        +430,	/* "Hold Instruction Code" */
        +431,	/* "Hold Instruction None" */
        +433,	/* "Hold Instruction Reject" */
        +634,	/* "ICC or token signature" */
        +294,	/* "IPSec End System" */
        +295,	/* "IPSec Tunnel" */
        +296,	/* "IPSec User" */
        +182,	/* "ISO Member Body" */
        +183,	/* "ISO US Member Body" */
        +667,	/* "Independent" */
        +665,	/* "Inherit all" */
        +647,	/* "International Organizations" */
        +142,	/* "Invalidity Date" */
        +504,	/* "MIME MHS" */
        +388,	/* "Mail" */
        +383,	/* "Management" */
        +417,	/* "Microsoft CSP Name" */
        +135,	/* "Microsoft Commercial Code Signing" */
        +138,	/* "Microsoft Encrypted File System" */
        +171,	/* "Microsoft Extension Request" */
        +134,	/* "Microsoft Individual Code Signing" */
        +856,	/* "Microsoft Local Key set" */
        +137,	/* "Microsoft Server Gated Crypto" */
        +648,	/* "Microsoft Smartcardlogin" */
        +136,	/* "Microsoft Trust List Signing" */
        +649,	/* "Microsoft Universal Principal Name" */
        +393,	/* "NULL" */
        +404,	/* "NULL" */
        +72,	/* "Netscape Base Url" */
        +76,	/* "Netscape CA Policy Url" */
        +74,	/* "Netscape CA Revocation Url" */
        +71,	/* "Netscape Cert Type" */
        +58,	/* "Netscape Certificate Extension" */
        +79,	/* "Netscape Certificate Sequence" */
        +78,	/* "Netscape Comment" */
        +57,	/* "Netscape Communications Corp." */
        +59,	/* "Netscape Data Type" */
        +75,	/* "Netscape Renewal Url" */
        +73,	/* "Netscape Revocation Url" */
        +77,	/* "Netscape SSL Server Name" */
        +139,	/* "Netscape Server Gated Crypto" */
        +178,	/* "OCSP" */
        +370,	/* "OCSP Archive Cutoff" */
        +367,	/* "OCSP CRL ID" */
        +369,	/* "OCSP No Check" */
        +366,	/* "OCSP Nonce" */
        +371,	/* "OCSP Service Locator" */
        +180,	/* "OCSP Signing" */
        +161,	/* "PBES2" */
        +69,	/* "PBKDF2" */
        +162,	/* "PBMAC1" */
        +127,	/* "PKIX" */
        +858,	/* "Permanent Identifier" */
        +164,	/* "Policy Qualifier CPS" */
        +165,	/* "Policy Qualifier User Notice" */
        +385,	/* "Private" */
        +663,	/* "Proxy Certificate Information" */
        + 1,	/* "RSA Data Security, Inc." */
        + 2,	/* "RSA Data Security, Inc. PKCS" */
        +188,	/* "S/MIME" */
        +167,	/* "S/MIME Capabilities" */
        +387,	/* "SNMPv2" */
        +512,	/* "Secure Electronic Transactions" */
        +386,	/* "Security" */
        +394,	/* "Selected Attribute Types" */
        +143,	/* "Strong Extranet ID" */
        +398,	/* "Subject Information Access" */
        +130,	/* "TLS Web Client Authentication" */
        +129,	/* "TLS Web Server Authentication" */
        +133,	/* "Time Stamping" */
        +375,	/* "Trust Root" */
        +12,	/* "X509" */
        +402,	/* "X509v3 AC Targeting" */
        +746,	/* "X509v3 Any Policy" */
        +90,	/* "X509v3 Authority Key Identifier" */
        +87,	/* "X509v3 Basic Constraints" */
        +103,	/* "X509v3 CRL Distribution Points" */
        +88,	/* "X509v3 CRL Number" */
        +141,	/* "X509v3 CRL Reason Code" */
        +771,	/* "X509v3 Certificate Issuer" */
        +89,	/* "X509v3 Certificate Policies" */
        +140,	/* "X509v3 Delta CRL Indicator" */
        +126,	/* "X509v3 Extended Key Usage" */
        +857,	/* "X509v3 Freshest CRL" */
        +748,	/* "X509v3 Inhibit Any Policy" */
        +86,	/* "X509v3 Issuer Alternative Name" */
        +770,	/* "X509v3 Issuing Distrubution Point" */
        +83,	/* "X509v3 Key Usage" */
        +666,	/* "X509v3 Name Constraints" */
        +403,	/* "X509v3 No Revocation Available" */
        +401,	/* "X509v3 Policy Constraints" */
        +747,	/* "X509v3 Policy Mappings" */
        +84,	/* "X509v3 Private Key Usage Period" */
        +85,	/* "X509v3 Subject Alternative Name" */
        +769,	/* "X509v3 Subject Directory Attributes" */
        +82,	/* "X509v3 Subject Key Identifier" */
        +184,	/* "X9.57" */
        +185,	/* "X9.57 CM ?" */
        +478,	/* "aRecord" */
        +289,	/* "aaControls" */
        +287,	/* "ac-auditEntity" */
        +397,	/* "ac-proxying" */
        +288,	/* "ac-targeting" */
        +446,	/* "account" */
        +364,	/* "ad dvcs" */
        +606,	/* "additional verification" */
        +419,	/* "aes-128-cbc" */
        +916,	/* "aes-128-cbc-hmac-sha1" */
        +896,	/* "aes-128-ccm" */
        +421,	/* "aes-128-cfb" */
        +650,	/* "aes-128-cfb1" */
        +653,	/* "aes-128-cfb8" */
        +904,	/* "aes-128-ctr" */
        +418,	/* "aes-128-ecb" */
        +895,	/* "aes-128-gcm" */
        +420,	/* "aes-128-ofb" */
        +913,	/* "aes-128-xts" */
        +423,	/* "aes-192-cbc" */
        +917,	/* "aes-192-cbc-hmac-sha1" */
        +899,	/* "aes-192-ccm" */
        +425,	/* "aes-192-cfb" */
        +651,	/* "aes-192-cfb1" */
        +654,	/* "aes-192-cfb8" */
        +905,	/* "aes-192-ctr" */
        +422,	/* "aes-192-ecb" */
        +898,	/* "aes-192-gcm" */
        +424,	/* "aes-192-ofb" */
        +427,	/* "aes-256-cbc" */
        +918,	/* "aes-256-cbc-hmac-sha1" */
        +902,	/* "aes-256-ccm" */
        +429,	/* "aes-256-cfb" */
        +652,	/* "aes-256-cfb1" */
        +655,	/* "aes-256-cfb8" */
        +906,	/* "aes-256-ctr" */
        +426,	/* "aes-256-ecb" */
        +901,	/* "aes-256-gcm" */
        +428,	/* "aes-256-ofb" */
        +914,	/* "aes-256-xts" */
        +376,	/* "algorithm" */
        +484,	/* "associatedDomain" */
        +485,	/* "associatedName" */
        +501,	/* "audio" */
        +882,	/* "authorityRevocationList" */
        +91,	/* "bf-cbc" */
        +93,	/* "bf-cfb" */
        +92,	/* "bf-ecb" */
        +94,	/* "bf-ofb" */
        +494,	/* "buildingName" */
        +860,	/* "businessCategory" */
        +691,	/* "c2onb191v4" */
        +692,	/* "c2onb191v5" */
        +697,	/* "c2onb239v4" */
        +698,	/* "c2onb239v5" */
        +684,	/* "c2pnb163v1" */
        +685,	/* "c2pnb163v2" */
        +686,	/* "c2pnb163v3" */
        +687,	/* "c2pnb176v1" */
        +693,	/* "c2pnb208w1" */
        +699,	/* "c2pnb272w1" */
        +700,	/* "c2pnb304w1" */
        +702,	/* "c2pnb368w1" */
        +688,	/* "c2tnb191v1" */
        +689,	/* "c2tnb191v2" */
        +690,	/* "c2tnb191v3" */
        +694,	/* "c2tnb239v1" */
        +695,	/* "c2tnb239v2" */
        +696,	/* "c2tnb239v3" */
        +701,	/* "c2tnb359v1" */
        +703,	/* "c2tnb431r1" */
        +881,	/* "cACertificate" */
        +483,	/* "cNAMERecord" */
        +751,	/* "camellia-128-cbc" */
        +757,	/* "camellia-128-cfb" */
        +760,	/* "camellia-128-cfb1" */
        +763,	/* "camellia-128-cfb8" */
        +754,	/* "camellia-128-ecb" */
        +766,	/* "camellia-128-ofb" */
        +752,	/* "camellia-192-cbc" */
        +758,	/* "camellia-192-cfb" */
        +761,	/* "camellia-192-cfb1" */
        +764,	/* "camellia-192-cfb8" */
        +755,	/* "camellia-192-ecb" */
        +767,	/* "camellia-192-ofb" */
        +753,	/* "camellia-256-cbc" */
        +759,	/* "camellia-256-cfb" */
        +762,	/* "camellia-256-cfb1" */
        +765,	/* "camellia-256-cfb8" */
        +756,	/* "camellia-256-ecb" */
        +768,	/* "camellia-256-ofb" */
        +443,	/* "caseIgnoreIA5StringSyntax" */
        +108,	/* "cast5-cbc" */
        +110,	/* "cast5-cfb" */
        +109,	/* "cast5-ecb" */
        +111,	/* "cast5-ofb" */
        +152,	/* "certBag" */
        +677,	/* "certicom-arc" */
        +517,	/* "certificate extensions" */
        +883,	/* "certificateRevocationList" */
        +54,	/* "challengePassword" */
        +407,	/* "characteristic-two-field" */
        +395,	/* "clearance" */
        +633,	/* "cleartext track 2" */
        +894,	/* "cmac" */
        +13,	/* "commonName" */
        +513,	/* "content types" */
        +50,	/* "contentType" */
        +53,	/* "countersignature" */
        +14,	/* "countryName" */
        +153,	/* "crlBag" */
        +884,	/* "crossCertificatePair" */
        +806,	/* "cryptocom" */
        +805,	/* "cryptopro" */
        +500,	/* "dITRedirect" */
        +451,	/* "dNSDomain" */
        +495,	/* "dSAQuality" */
        +434,	/* "data" */
        +390,	/* "dcObject" */
        +891,	/* "deltaRevocationList" */
        +31,	/* "des-cbc" */
        +643,	/* "des-cdmf" */
        +30,	/* "des-cfb" */
        +656,	/* "des-cfb1" */
        +657,	/* "des-cfb8" */
        +29,	/* "des-ecb" */
        +32,	/* "des-ede" */
        +43,	/* "des-ede-cbc" */
        +60,	/* "des-ede-cfb" */
        +62,	/* "des-ede-ofb" */
        +33,	/* "des-ede3" */
        +44,	/* "des-ede3-cbc" */
        +61,	/* "des-ede3-cfb" */
        +658,	/* "des-ede3-cfb1" */
        +659,	/* "des-ede3-cfb8" */
        +63,	/* "des-ede3-ofb" */
        +45,	/* "des-ofb" */
        +107,	/* "description" */
        +871,	/* "destinationIndicator" */
        +80,	/* "desx-cbc" */
        +28,	/* "dhKeyAgreement" */
        +11,	/* "directory services (X.500)" */
        +378,	/* "directory services - algorithms" */
        +887,	/* "distinguishedName" */
        +892,	/* "dmdName" */
        +174,	/* "dnQualifier" */
        +447,	/* "document" */
        +471,	/* "documentAuthor" */
        +468,	/* "documentIdentifier" */
        +472,	/* "documentLocation" */
        +502,	/* "documentPublisher" */
        +449,	/* "documentSeries" */
        +469,	/* "documentTitle" */
        +470,	/* "documentVersion" */
        +380,	/* "dod" */
        +391,	/* "domainComponent" */
        +452,	/* "domainRelatedObject" */
        +116,	/* "dsaEncryption" */
        +67,	/* "dsaEncryption-old" */
        +66,	/* "dsaWithSHA" */
        +113,	/* "dsaWithSHA1" */
        +70,	/* "dsaWithSHA1-old" */
        +802,	/* "dsa_with_SHA224" */
        +803,	/* "dsa_with_SHA256" */
        +297,	/* "dvcs" */
        +791,	/* "ecdsa-with-Recommended" */
        +416,	/* "ecdsa-with-SHA1" */
        +793,	/* "ecdsa-with-SHA224" */
        +794,	/* "ecdsa-with-SHA256" */
        +795,	/* "ecdsa-with-SHA384" */
        +796,	/* "ecdsa-with-SHA512" */
        +792,	/* "ecdsa-with-Specified" */
        +48,	/* "emailAddress" */
        +632,	/* "encrypted track 2" */
        +885,	/* "enhancedSearchGuide" */
        +56,	/* "extendedCertificateAttributes" */
        +867,	/* "facsimileTelephoneNumber" */
        +462,	/* "favouriteDrink" */
        +453,	/* "friendlyCountry" */
        +490,	/* "friendlyCountryName" */
        +156,	/* "friendlyName" */
        +631,	/* "generate cryptogram" */
        +509,	/* "generationQualifier" */
        +601,	/* "generic cryptogram" */
        +99,	/* "givenName" */
        +814,	/* "gost89-cnt" */
        +855,	/* "hmac" */
        +780,	/* "hmac-md5" */
        +781,	/* "hmac-sha1" */
        +797,	/* "hmacWithMD5" */
        +163,	/* "hmacWithSHA1" */
        +798,	/* "hmacWithSHA224" */
        +799,	/* "hmacWithSHA256" */
        +800,	/* "hmacWithSHA384" */
        +801,	/* "hmacWithSHA512" */
        +486,	/* "homePostalAddress" */
        +473,	/* "homeTelephoneNumber" */
        +466,	/* "host" */
        +889,	/* "houseIdentifier" */
        +442,	/* "iA5StringSyntax" */
        +381,	/* "iana" */
        +824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
        +825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
        +826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
        +827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
        +819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
        +829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
        +828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
        +830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
        +820,	/* "id-Gost28147-89-None-KeyMeshing" */
        +823,	/* "id-Gost28147-89-TestParamSet" */
        +840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
        +841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
        +842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
        +843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
        +844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
        +839,	/* "id-GostR3410-2001-TestParamSet" */
        +832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
        +833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
        +834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
        +835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
        +836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
        +837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
        +838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
        +831,	/* "id-GostR3410-94-TestParamSet" */
        +845,	/* "id-GostR3410-94-a" */
        +846,	/* "id-GostR3410-94-aBis" */
        +847,	/* "id-GostR3410-94-b" */
        +848,	/* "id-GostR3410-94-bBis" */
        +822,	/* "id-GostR3411-94-CryptoProParamSet" */
        +821,	/* "id-GostR3411-94-TestParamSet" */
        +266,	/* "id-aca" */
        +355,	/* "id-aca-accessIdentity" */
        +354,	/* "id-aca-authenticationInfo" */
        +356,	/* "id-aca-chargingIdentity" */
        +399,	/* "id-aca-encAttrs" */
        +357,	/* "id-aca-group" */
        +358,	/* "id-aca-role" */
        +176,	/* "id-ad" */
        +788,	/* "id-aes128-wrap" */
        +897,	/* "id-aes128-wrap-pad" */
        +789,	/* "id-aes192-wrap" */
        +900,	/* "id-aes192-wrap-pad" */
        +790,	/* "id-aes256-wrap" */
        +903,	/* "id-aes256-wrap-pad" */
        +262,	/* "id-alg" */
        +893,	/* "id-alg-PWRI-KEK" */
        +323,	/* "id-alg-des40" */
        +326,	/* "id-alg-dh-pop" */
        +325,	/* "id-alg-dh-sig-hmac-sha1" */
        +324,	/* "id-alg-noSignature" */
        +907,	/* "id-camellia128-wrap" */
        +908,	/* "id-camellia192-wrap" */
        +909,	/* "id-camellia256-wrap" */
        +268,	/* "id-cct" */
        +361,	/* "id-cct-PKIData" */
        +362,	/* "id-cct-PKIResponse" */
        +360,	/* "id-cct-crs" */
        +81,	/* "id-ce" */
        +680,	/* "id-characteristic-two-basis" */
        +263,	/* "id-cmc" */
        +334,	/* "id-cmc-addExtensions" */
        +346,	/* "id-cmc-confirmCertAcceptance" */
        +330,	/* "id-cmc-dataReturn" */
        +336,	/* "id-cmc-decryptedPOP" */
        +335,	/* "id-cmc-encryptedPOP" */
        +339,	/* "id-cmc-getCRL" */
        +338,	/* "id-cmc-getCert" */
        +328,	/* "id-cmc-identification" */
        +329,	/* "id-cmc-identityProof" */
        +337,	/* "id-cmc-lraPOPWitness" */
        +344,	/* "id-cmc-popLinkRandom" */
        +345,	/* "id-cmc-popLinkWitness" */
        +343,	/* "id-cmc-queryPending" */
        +333,	/* "id-cmc-recipientNonce" */
        +341,	/* "id-cmc-regInfo" */
        +342,	/* "id-cmc-responseInfo" */
        +340,	/* "id-cmc-revokeRequest" */
        +332,	/* "id-cmc-senderNonce" */
        +327,	/* "id-cmc-statusInfo" */
        +331,	/* "id-cmc-transactionId" */
        +787,	/* "id-ct-asciiTextWithCRLF" */
        +408,	/* "id-ecPublicKey" */
        +508,	/* "id-hex-multipart-message" */
        +507,	/* "id-hex-partial-message" */
        +260,	/* "id-it" */
        +302,	/* "id-it-caKeyUpdateInfo" */
        +298,	/* "id-it-caProtEncCert" */
        +311,	/* "id-it-confirmWaitTime" */
        +303,	/* "id-it-currentCRL" */
        +300,	/* "id-it-encKeyPairTypes" */
        +310,	/* "id-it-implicitConfirm" */
        +308,	/* "id-it-keyPairParamRep" */
        +307,	/* "id-it-keyPairParamReq" */
        +312,	/* "id-it-origPKIMessage" */
        +301,	/* "id-it-preferredSymmAlg" */
        +309,	/* "id-it-revPassphrase" */
        +299,	/* "id-it-signKeyPairTypes" */
        +305,	/* "id-it-subscriptionRequest" */
        +306,	/* "id-it-subscriptionResponse" */
        +784,	/* "id-it-suppLangTags" */
        +304,	/* "id-it-unsupportedOIDs" */
        +128,	/* "id-kp" */
        +280,	/* "id-mod-attribute-cert" */
        +274,	/* "id-mod-cmc" */
        +277,	/* "id-mod-cmp" */
        +284,	/* "id-mod-cmp2000" */
        +273,	/* "id-mod-crmf" */
        +283,	/* "id-mod-dvcs" */
        +275,	/* "id-mod-kea-profile-88" */
        +276,	/* "id-mod-kea-profile-93" */
        +282,	/* "id-mod-ocsp" */
        +278,	/* "id-mod-qualified-cert-88" */
        +279,	/* "id-mod-qualified-cert-93" */
        +281,	/* "id-mod-timestamp-protocol" */
        +264,	/* "id-on" */
        +347,	/* "id-on-personalData" */
        +265,	/* "id-pda" */
        +352,	/* "id-pda-countryOfCitizenship" */
        +353,	/* "id-pda-countryOfResidence" */
        +348,	/* "id-pda-dateOfBirth" */
        +351,	/* "id-pda-gender" */
        +349,	/* "id-pda-placeOfBirth" */
        +175,	/* "id-pe" */
        +261,	/* "id-pkip" */
        +258,	/* "id-pkix-mod" */
        +269,	/* "id-pkix1-explicit-88" */
        +271,	/* "id-pkix1-explicit-93" */
        +270,	/* "id-pkix1-implicit-88" */
        +272,	/* "id-pkix1-implicit-93" */
        +662,	/* "id-ppl" */
        +267,	/* "id-qcs" */
        +359,	/* "id-qcs-pkixQCSyntax-v1" */
        +259,	/* "id-qt" */
        +313,	/* "id-regCtrl" */
        +316,	/* "id-regCtrl-authenticator" */
        +319,	/* "id-regCtrl-oldCertID" */
        +318,	/* "id-regCtrl-pkiArchiveOptions" */
        +317,	/* "id-regCtrl-pkiPublicationInfo" */
        +320,	/* "id-regCtrl-protocolEncrKey" */
        +315,	/* "id-regCtrl-regToken" */
        +314,	/* "id-regInfo" */
        +322,	/* "id-regInfo-certReq" */
        +321,	/* "id-regInfo-utf8Pairs" */
        +191,	/* "id-smime-aa" */
        +215,	/* "id-smime-aa-contentHint" */
        +218,	/* "id-smime-aa-contentIdentifier" */
        +221,	/* "id-smime-aa-contentReference" */
        +240,	/* "id-smime-aa-dvcs-dvc" */
        +217,	/* "id-smime-aa-encapContentType" */
        +222,	/* "id-smime-aa-encrypKeyPref" */
        +220,	/* "id-smime-aa-equivalentLabels" */
        +232,	/* "id-smime-aa-ets-CertificateRefs" */
        +233,	/* "id-smime-aa-ets-RevocationRefs" */
        +238,	/* "id-smime-aa-ets-archiveTimeStamp" */
        +237,	/* "id-smime-aa-ets-certCRLTimestamp" */
        +234,	/* "id-smime-aa-ets-certValues" */
        +227,	/* "id-smime-aa-ets-commitmentType" */
        +231,	/* "id-smime-aa-ets-contentTimestamp" */
        +236,	/* "id-smime-aa-ets-escTimeStamp" */
        +230,	/* "id-smime-aa-ets-otherSigCert" */
        +235,	/* "id-smime-aa-ets-revocationValues" */
        +226,	/* "id-smime-aa-ets-sigPolicyId" */
        +229,	/* "id-smime-aa-ets-signerAttr" */
        +228,	/* "id-smime-aa-ets-signerLocation" */
        +219,	/* "id-smime-aa-macValue" */
        +214,	/* "id-smime-aa-mlExpandHistory" */
        +216,	/* "id-smime-aa-msgSigDigest" */
        +212,	/* "id-smime-aa-receiptRequest" */
        +213,	/* "id-smime-aa-securityLabel" */
        +239,	/* "id-smime-aa-signatureType" */
        +223,	/* "id-smime-aa-signingCertificate" */
        +224,	/* "id-smime-aa-smimeEncryptCerts" */
        +225,	/* "id-smime-aa-timeStampToken" */
        +192,	/* "id-smime-alg" */
        +243,	/* "id-smime-alg-3DESwrap" */
        +246,	/* "id-smime-alg-CMS3DESwrap" */
        +247,	/* "id-smime-alg-CMSRC2wrap" */
        +245,	/* "id-smime-alg-ESDH" */
        +241,	/* "id-smime-alg-ESDHwith3DES" */
        +242,	/* "id-smime-alg-ESDHwithRC2" */
        +244,	/* "id-smime-alg-RC2wrap" */
        +193,	/* "id-smime-cd" */
        +248,	/* "id-smime-cd-ldap" */
        +190,	/* "id-smime-ct" */
        +210,	/* "id-smime-ct-DVCSRequestData" */
        +211,	/* "id-smime-ct-DVCSResponseData" */
        +208,	/* "id-smime-ct-TDTInfo" */
        +207,	/* "id-smime-ct-TSTInfo" */
        +205,	/* "id-smime-ct-authData" */
        +786,	/* "id-smime-ct-compressedData" */
        +209,	/* "id-smime-ct-contentInfo" */
        +206,	/* "id-smime-ct-publishCert" */
        +204,	/* "id-smime-ct-receipt" */
        +195,	/* "id-smime-cti" */
        +255,	/* "id-smime-cti-ets-proofOfApproval" */
        +256,	/* "id-smime-cti-ets-proofOfCreation" */
        +253,	/* "id-smime-cti-ets-proofOfDelivery" */
        +251,	/* "id-smime-cti-ets-proofOfOrigin" */
        +252,	/* "id-smime-cti-ets-proofOfReceipt" */
        +254,	/* "id-smime-cti-ets-proofOfSender" */
        +189,	/* "id-smime-mod" */
        +196,	/* "id-smime-mod-cms" */
        +197,	/* "id-smime-mod-ess" */
        +202,	/* "id-smime-mod-ets-eSigPolicy-88" */
        +203,	/* "id-smime-mod-ets-eSigPolicy-97" */
        +200,	/* "id-smime-mod-ets-eSignature-88" */
        +201,	/* "id-smime-mod-ets-eSignature-97" */
        +199,	/* "id-smime-mod-msg-v3" */
        +198,	/* "id-smime-mod-oid" */
        +194,	/* "id-smime-spq" */
        +250,	/* "id-smime-spq-ets-sqt-unotice" */
        +249,	/* "id-smime-spq-ets-sqt-uri" */
        +34,	/* "idea-cbc" */
        +35,	/* "idea-cfb" */
        +36,	/* "idea-ecb" */
        +46,	/* "idea-ofb" */
        +676,	/* "identified-organization" */
        +461,	/* "info" */
        +101,	/* "initials" */
        +869,	/* "internationaliSDNNumber" */
        +749,	/* "ipsec3" */
        +750,	/* "ipsec4" */
        +181,	/* "iso" */
        +623,	/* "issuer capabilities" */
        +645,	/* "itu-t" */
        +492,	/* "janetMailbox" */
        +646,	/* "joint-iso-itu-t" */
        +150,	/* "keyBag" */
        +773,	/* "kisa" */
        +477,	/* "lastModifiedBy" */
        +476,	/* "lastModifiedTime" */
        +157,	/* "localKeyID" */
        +15,	/* "localityName" */
        +480,	/* "mXRecord" */
        +493,	/* "mailPreferenceOption" */
        +467,	/* "manager" */
        + 3,	/* "md2" */
        + 7,	/* "md2WithRSAEncryption" */
        +257,	/* "md4" */
        +396,	/* "md4WithRSAEncryption" */
        + 4,	/* "md5" */
        +114,	/* "md5-sha1" */
        +104,	/* "md5WithRSA" */
        + 8,	/* "md5WithRSAEncryption" */
        +95,	/* "mdc2" */
        +96,	/* "mdc2WithRSA" */
        +875,	/* "member" */
        +602,	/* "merchant initiated auth" */
        +514,	/* "message extensions" */
        +51,	/* "messageDigest" */
        +911,	/* "mgf1" */
        +506,	/* "mime-mhs-bodies" */
        +505,	/* "mime-mhs-headings" */
        +488,	/* "mobileTelephoneNumber" */
        +481,	/* "nSRecord" */
        +173,	/* "name" */
        +681,	/* "onBasis" */
        +379,	/* "org" */
        +17,	/* "organizationName" */
        +491,	/* "organizationalStatus" */
        +18,	/* "organizationalUnitName" */
        +475,	/* "otherMailbox" */
        +876,	/* "owner" */
        +489,	/* "pagerTelephoneNumber" */
        +782,	/* "password based MAC" */
        +374,	/* "path" */
        +621,	/* "payment gateway capabilities" */
        + 9,	/* "pbeWithMD2AndDES-CBC" */
        +168,	/* "pbeWithMD2AndRC2-CBC" */
        +112,	/* "pbeWithMD5AndCast5CBC" */
        +10,	/* "pbeWithMD5AndDES-CBC" */
        +169,	/* "pbeWithMD5AndRC2-CBC" */
        +148,	/* "pbeWithSHA1And128BitRC2-CBC" */
        +144,	/* "pbeWithSHA1And128BitRC4" */
        +147,	/* "pbeWithSHA1And2-KeyTripleDES-CBC" */
        +146,	/* "pbeWithSHA1And3-KeyTripleDES-CBC" */
        +149,	/* "pbeWithSHA1And40BitRC2-CBC" */
        +145,	/* "pbeWithSHA1And40BitRC4" */
        +170,	/* "pbeWithSHA1AndDES-CBC" */
        +68,	/* "pbeWithSHA1AndRC2-CBC" */
        +499,	/* "personalSignature" */
        +487,	/* "personalTitle" */
        +464,	/* "photo" */
        +863,	/* "physicalDeliveryOfficeName" */
        +437,	/* "pilot" */
        +439,	/* "pilotAttributeSyntax" */
        +438,	/* "pilotAttributeType" */
        +479,	/* "pilotAttributeType27" */
        +456,	/* "pilotDSA" */
        +441,	/* "pilotGroups" */
        +444,	/* "pilotObject" */
        +440,	/* "pilotObjectClass" */
        +455,	/* "pilotOrganization" */
        +445,	/* "pilotPerson" */
        +186,	/* "pkcs1" */
        +27,	/* "pkcs3" */
        +187,	/* "pkcs5" */
        +20,	/* "pkcs7" */
        +21,	/* "pkcs7-data" */
        +25,	/* "pkcs7-digestData" */
        +26,	/* "pkcs7-encryptedData" */
        +23,	/* "pkcs7-envelopedData" */
        +24,	/* "pkcs7-signedAndEnvelopedData" */
        +22,	/* "pkcs7-signedData" */
        +151,	/* "pkcs8ShroudedKeyBag" */
        +47,	/* "pkcs9" */
        +862,	/* "postOfficeBox" */
        +861,	/* "postalAddress" */
        +661,	/* "postalCode" */
        +683,	/* "ppBasis" */
        +872,	/* "preferredDeliveryMethod" */
        +873,	/* "presentationAddress" */
        +406,	/* "prime-field" */
        +409,	/* "prime192v1" */
        +410,	/* "prime192v2" */
        +411,	/* "prime192v3" */
        +412,	/* "prime239v1" */
        +413,	/* "prime239v2" */
        +414,	/* "prime239v3" */
        +415,	/* "prime256v1" */
        +886,	/* "protocolInformation" */
        +510,	/* "pseudonym" */
        +435,	/* "pss" */
        +286,	/* "qcStatements" */
        +457,	/* "qualityLabelledData" */
        +450,	/* "rFC822localPart" */
        +98,	/* "rc2-40-cbc" */
        +166,	/* "rc2-64-cbc" */
        +37,	/* "rc2-cbc" */
        +39,	/* "rc2-cfb" */
        +38,	/* "rc2-ecb" */
        +40,	/* "rc2-ofb" */
        + 5,	/* "rc4" */
        +97,	/* "rc4-40" */
        +915,	/* "rc4-hmac-md5" */
        +120,	/* "rc5-cbc" */
        +122,	/* "rc5-cfb" */
        +121,	/* "rc5-ecb" */
        +123,	/* "rc5-ofb" */
        +870,	/* "registeredAddress" */
        +460,	/* "rfc822Mailbox" */
        +117,	/* "ripemd160" */
        +119,	/* "ripemd160WithRSA" */
        +400,	/* "role" */
        +877,	/* "roleOccupant" */
        +448,	/* "room" */
        +463,	/* "roomNumber" */
        +19,	/* "rsa" */
        + 6,	/* "rsaEncryption" */
        +644,	/* "rsaOAEPEncryptionSET" */
        +377,	/* "rsaSignature" */
        +919,	/* "rsaesOaep" */
        +912,	/* "rsassaPss" */
        +124,	/* "run length compression" */
        +482,	/* "sOARecord" */
        +155,	/* "safeContentsBag" */
        +291,	/* "sbgp-autonomousSysNum" */
        +290,	/* "sbgp-ipAddrBlock" */
        +292,	/* "sbgp-routerIdentifier" */
        +159,	/* "sdsiCertificate" */
        +859,	/* "searchGuide" */
        +704,	/* "secp112r1" */
        +705,	/* "secp112r2" */
        +706,	/* "secp128r1" */
        +707,	/* "secp128r2" */
        +708,	/* "secp160k1" */
        +709,	/* "secp160r1" */
        +710,	/* "secp160r2" */
        +711,	/* "secp192k1" */
        +712,	/* "secp224k1" */
        +713,	/* "secp224r1" */
        +714,	/* "secp256k1" */
        +715,	/* "secp384r1" */
        +716,	/* "secp521r1" */
        +154,	/* "secretBag" */
        +474,	/* "secretary" */
        +717,	/* "sect113r1" */
        +718,	/* "sect113r2" */
        +719,	/* "sect131r1" */
        +720,	/* "sect131r2" */
        +721,	/* "sect163k1" */
        +722,	/* "sect163r1" */
        +723,	/* "sect163r2" */
        +724,	/* "sect193r1" */
        +725,	/* "sect193r2" */
        +726,	/* "sect233k1" */
        +727,	/* "sect233r1" */
        +728,	/* "sect239k1" */
        +729,	/* "sect283k1" */
        +730,	/* "sect283r1" */
        +731,	/* "sect409k1" */
        +732,	/* "sect409r1" */
        +733,	/* "sect571k1" */
        +734,	/* "sect571r1" */
        +635,	/* "secure device signature" */
        +878,	/* "seeAlso" */
        +777,	/* "seed-cbc" */
        +779,	/* "seed-cfb" */
        +776,	/* "seed-ecb" */
        +778,	/* "seed-ofb" */
        +105,	/* "serialNumber" */
        +625,	/* "set-addPolicy" */
        +515,	/* "set-attr" */
        +518,	/* "set-brand" */
        +638,	/* "set-brand-AmericanExpress" */
        +637,	/* "set-brand-Diners" */
        +636,	/* "set-brand-IATA-ATA" */
        +639,	/* "set-brand-JCB" */
        +641,	/* "set-brand-MasterCard" */
        +642,	/* "set-brand-Novus" */
        +640,	/* "set-brand-Visa" */
        +516,	/* "set-policy" */
        +607,	/* "set-policy-root" */
        +624,	/* "set-rootKeyThumb" */
        +620,	/* "setAttr-Cert" */
        +628,	/* "setAttr-IssCap-CVM" */
        +630,	/* "setAttr-IssCap-Sig" */
        +629,	/* "setAttr-IssCap-T2" */
        +627,	/* "setAttr-Token-B0Prime" */
        +626,	/* "setAttr-Token-EMV" */
        +622,	/* "setAttr-TokenType" */
        +619,	/* "setCext-IssuerCapabilities" */
        +615,	/* "setCext-PGWYcapabilities" */
        +616,	/* "setCext-TokenIdentifier" */
        +618,	/* "setCext-TokenType" */
        +617,	/* "setCext-Track2Data" */
        +611,	/* "setCext-cCertRequired" */
        +609,	/* "setCext-certType" */
        +608,	/* "setCext-hashedRoot" */
        +610,	/* "setCext-merchData" */
        +613,	/* "setCext-setExt" */
        +614,	/* "setCext-setQualf" */
        +612,	/* "setCext-tunneling" */
        +540,	/* "setct-AcqCardCodeMsg" */
        +576,	/* "setct-AcqCardCodeMsgTBE" */
        +570,	/* "setct-AuthReqTBE" */
        +534,	/* "setct-AuthReqTBS" */
        +527,	/* "setct-AuthResBaggage" */
        +571,	/* "setct-AuthResTBE" */
        +572,	/* "setct-AuthResTBEX" */
        +535,	/* "setct-AuthResTBS" */
        +536,	/* "setct-AuthResTBSX" */
        +528,	/* "setct-AuthRevReqBaggage" */
        +577,	/* "setct-AuthRevReqTBE" */
        +541,	/* "setct-AuthRevReqTBS" */
        +529,	/* "setct-AuthRevResBaggage" */
        +542,	/* "setct-AuthRevResData" */
        +578,	/* "setct-AuthRevResTBE" */
        +579,	/* "setct-AuthRevResTBEB" */
        +543,	/* "setct-AuthRevResTBS" */
        +573,	/* "setct-AuthTokenTBE" */
        +537,	/* "setct-AuthTokenTBS" */
        +600,	/* "setct-BCIDistributionTBS" */
        +558,	/* "setct-BatchAdminReqData" */
        +592,	/* "setct-BatchAdminReqTBE" */
        +559,	/* "setct-BatchAdminResData" */
        +593,	/* "setct-BatchAdminResTBE" */
        +599,	/* "setct-CRLNotificationResTBS" */
        +598,	/* "setct-CRLNotificationTBS" */
        +580,	/* "setct-CapReqTBE" */
        +581,	/* "setct-CapReqTBEX" */
        +544,	/* "setct-CapReqTBS" */
        +545,	/* "setct-CapReqTBSX" */
        +546,	/* "setct-CapResData" */
        +582,	/* "setct-CapResTBE" */
        +583,	/* "setct-CapRevReqTBE" */
        +584,	/* "setct-CapRevReqTBEX" */
        +547,	/* "setct-CapRevReqTBS" */
        +548,	/* "setct-CapRevReqTBSX" */
        +549,	/* "setct-CapRevResData" */
        +585,	/* "setct-CapRevResTBE" */
        +538,	/* "setct-CapTokenData" */
        +530,	/* "setct-CapTokenSeq" */
        +574,	/* "setct-CapTokenTBE" */
        +575,	/* "setct-CapTokenTBEX" */
        +539,	/* "setct-CapTokenTBS" */
        +560,	/* "setct-CardCInitResTBS" */
        +566,	/* "setct-CertInqReqTBS" */
        +563,	/* "setct-CertReqData" */
        +595,	/* "setct-CertReqTBE" */
        +596,	/* "setct-CertReqTBEX" */
        +564,	/* "setct-CertReqTBS" */
        +565,	/* "setct-CertResData" */
        +597,	/* "setct-CertResTBE" */
        +586,	/* "setct-CredReqTBE" */
        +587,	/* "setct-CredReqTBEX" */
        +550,	/* "setct-CredReqTBS" */
        +551,	/* "setct-CredReqTBSX" */
        +552,	/* "setct-CredResData" */
        +588,	/* "setct-CredResTBE" */
        +589,	/* "setct-CredRevReqTBE" */
        +590,	/* "setct-CredRevReqTBEX" */
        +553,	/* "setct-CredRevReqTBS" */
        +554,	/* "setct-CredRevReqTBSX" */
        +555,	/* "setct-CredRevResData" */
        +591,	/* "setct-CredRevResTBE" */
        +567,	/* "setct-ErrorTBS" */
        +526,	/* "setct-HODInput" */
        +561,	/* "setct-MeAqCInitResTBS" */
        +522,	/* "setct-OIData" */
        +519,	/* "setct-PANData" */
        +521,	/* "setct-PANOnly" */
        +520,	/* "setct-PANToken" */
        +556,	/* "setct-PCertReqData" */
        +557,	/* "setct-PCertResTBS" */
        +523,	/* "setct-PI" */
        +532,	/* "setct-PI-TBS" */
        +524,	/* "setct-PIData" */
        +525,	/* "setct-PIDataUnsigned" */
        +568,	/* "setct-PIDualSignedTBE" */
        +569,	/* "setct-PIUnsignedTBE" */
        +531,	/* "setct-PInitResData" */
        +533,	/* "setct-PResData" */
        +594,	/* "setct-RegFormReqTBE" */
        +562,	/* "setct-RegFormResTBS" */
        +604,	/* "setext-pinAny" */
        +603,	/* "setext-pinSecure" */
        +605,	/* "setext-track2" */
        +41,	/* "sha" */
        +64,	/* "sha1" */
        +115,	/* "sha1WithRSA" */
        +65,	/* "sha1WithRSAEncryption" */
        +675,	/* "sha224" */
        +671,	/* "sha224WithRSAEncryption" */
        +672,	/* "sha256" */
        +668,	/* "sha256WithRSAEncryption" */
        +673,	/* "sha384" */
        +669,	/* "sha384WithRSAEncryption" */
        +674,	/* "sha512" */
        +670,	/* "sha512WithRSAEncryption" */
        +42,	/* "shaWithRSAEncryption" */
        +52,	/* "signingTime" */
        +454,	/* "simpleSecurityObject" */
        +496,	/* "singleLevelQuality" */
        +16,	/* "stateOrProvinceName" */
        +660,	/* "streetAddress" */
        +498,	/* "subtreeMaximumQuality" */
        +497,	/* "subtreeMinimumQuality" */
        +890,	/* "supportedAlgorithms" */
        +874,	/* "supportedApplicationContext" */
        +100,	/* "surname" */
        +864,	/* "telephoneNumber" */
        +866,	/* "teletexTerminalIdentifier" */
        +865,	/* "telexNumber" */
        +459,	/* "textEncodedORAddress" */
        +293,	/* "textNotice" */
        +106,	/* "title" */
        +682,	/* "tpBasis" */
        +436,	/* "ucl" */
        + 0,	/* "undefined" */
        +888,	/* "uniqueMember" */
        +55,	/* "unstructuredAddress" */
        +49,	/* "unstructuredName" */
        +880,	/* "userCertificate" */
        +465,	/* "userClass" */
        +458,	/* "userId" */
        +879,	/* "userPassword" */
        +373,	/* "valid" */
        +678,	/* "wap" */
        +679,	/* "wap-wsg" */
        +735,	/* "wap-wsg-idm-ecid-wtls1" */
        +743,	/* "wap-wsg-idm-ecid-wtls10" */
        +744,	/* "wap-wsg-idm-ecid-wtls11" */
        +745,	/* "wap-wsg-idm-ecid-wtls12" */
        +736,	/* "wap-wsg-idm-ecid-wtls3" */
        +737,	/* "wap-wsg-idm-ecid-wtls4" */
        +738,	/* "wap-wsg-idm-ecid-wtls5" */
        +739,	/* "wap-wsg-idm-ecid-wtls6" */
        +740,	/* "wap-wsg-idm-ecid-wtls7" */
        +741,	/* "wap-wsg-idm-ecid-wtls8" */
        +742,	/* "wap-wsg-idm-ecid-wtls9" */
        +804,	/* "whirlpool" */
        +868,	/* "x121Address" */
        +503,	/* "x500UniqueIdentifier" */
        +158,	/* "x509Certificate" */
        +160,	/* "x509Crl" */
        +125,	/* "zlib compression" */
        +};
        +
        +static const unsigned int obj_objs[NUM_OBJ]={
        + 0,	/* OBJ_undef                        0 */
        +393,	/* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
        +404,	/* OBJ_ccitt                        OBJ_itu_t */
        +645,	/* OBJ_itu_t                        0 */
        +434,	/* OBJ_data                         0 9 */
        +181,	/* OBJ_iso                          1 */
        +182,	/* OBJ_member_body                  1 2 */
        +379,	/* OBJ_org                          1 3 */
        +676,	/* OBJ_identified_organization      1 3 */
        +646,	/* OBJ_joint_iso_itu_t              2 */
        +11,	/* OBJ_X500                         2 5 */
        +647,	/* OBJ_international_organizations  2 23 */
        +380,	/* OBJ_dod                          1 3 6 */
        +12,	/* OBJ_X509                         2 5 4 */
        +378,	/* OBJ_X500algorithms               2 5 8 */
        +81,	/* OBJ_id_ce                        2 5 29 */
        +512,	/* OBJ_id_set                       2 23 42 */
        +678,	/* OBJ_wap                          2 23 43 */
        +435,	/* OBJ_pss                          0 9 2342 */
        +183,	/* OBJ_ISO_US                       1 2 840 */
        +381,	/* OBJ_iana                         1 3 6 1 */
        +677,	/* OBJ_certicom_arc                 1 3 132 */
        +394,	/* OBJ_selected_attribute_types     2 5 1 5 */
        +13,	/* OBJ_commonName                   2 5 4 3 */
        +100,	/* OBJ_surname                      2 5 4 4 */
        +105,	/* OBJ_serialNumber                 2 5 4 5 */
        +14,	/* OBJ_countryName                  2 5 4 6 */
        +15,	/* OBJ_localityName                 2 5 4 7 */
        +16,	/* OBJ_stateOrProvinceName          2 5 4 8 */
        +660,	/* OBJ_streetAddress                2 5 4 9 */
        +17,	/* OBJ_organizationName             2 5 4 10 */
        +18,	/* OBJ_organizationalUnitName       2 5 4 11 */
        +106,	/* OBJ_title                        2 5 4 12 */
        +107,	/* OBJ_description                  2 5 4 13 */
        +859,	/* OBJ_searchGuide                  2 5 4 14 */
        +860,	/* OBJ_businessCategory             2 5 4 15 */
        +861,	/* OBJ_postalAddress                2 5 4 16 */
        +661,	/* OBJ_postalCode                   2 5 4 17 */
        +862,	/* OBJ_postOfficeBox                2 5 4 18 */
        +863,	/* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
        +864,	/* OBJ_telephoneNumber              2 5 4 20 */
        +865,	/* OBJ_telexNumber                  2 5 4 21 */
        +866,	/* OBJ_teletexTerminalIdentifier    2 5 4 22 */
        +867,	/* OBJ_facsimileTelephoneNumber     2 5 4 23 */
        +868,	/* OBJ_x121Address                  2 5 4 24 */
        +869,	/* OBJ_internationaliSDNNumber      2 5 4 25 */
        +870,	/* OBJ_registeredAddress            2 5 4 26 */
        +871,	/* OBJ_destinationIndicator         2 5 4 27 */
        +872,	/* OBJ_preferredDeliveryMethod      2 5 4 28 */
        +873,	/* OBJ_presentationAddress          2 5 4 29 */
        +874,	/* OBJ_supportedApplicationContext  2 5 4 30 */
        +875,	/* OBJ_member                       2 5 4 31 */
        +876,	/* OBJ_owner                        2 5 4 32 */
        +877,	/* OBJ_roleOccupant                 2 5 4 33 */
        +878,	/* OBJ_seeAlso                      2 5 4 34 */
        +879,	/* OBJ_userPassword                 2 5 4 35 */
        +880,	/* OBJ_userCertificate              2 5 4 36 */
        +881,	/* OBJ_cACertificate                2 5 4 37 */
        +882,	/* OBJ_authorityRevocationList      2 5 4 38 */
        +883,	/* OBJ_certificateRevocationList    2 5 4 39 */
        +884,	/* OBJ_crossCertificatePair         2 5 4 40 */
        +173,	/* OBJ_name                         2 5 4 41 */
        +99,	/* OBJ_givenName                    2 5 4 42 */
        +101,	/* OBJ_initials                     2 5 4 43 */
        +509,	/* OBJ_generationQualifier          2 5 4 44 */
        +503,	/* OBJ_x500UniqueIdentifier         2 5 4 45 */
        +174,	/* OBJ_dnQualifier                  2 5 4 46 */
        +885,	/* OBJ_enhancedSearchGuide          2 5 4 47 */
        +886,	/* OBJ_protocolInformation          2 5 4 48 */
        +887,	/* OBJ_distinguishedName            2 5 4 49 */
        +888,	/* OBJ_uniqueMember                 2 5 4 50 */
        +889,	/* OBJ_houseIdentifier              2 5 4 51 */
        +890,	/* OBJ_supportedAlgorithms          2 5 4 52 */
        +891,	/* OBJ_deltaRevocationList          2 5 4 53 */
        +892,	/* OBJ_dmdName                      2 5 4 54 */
        +510,	/* OBJ_pseudonym                    2 5 4 65 */
        +400,	/* OBJ_role                         2 5 4 72 */
        +769,	/* OBJ_subject_directory_attributes 2 5 29 9 */
        +82,	/* OBJ_subject_key_identifier       2 5 29 14 */
        +83,	/* OBJ_key_usage                    2 5 29 15 */
        +84,	/* OBJ_private_key_usage_period     2 5 29 16 */
        +85,	/* OBJ_subject_alt_name             2 5 29 17 */
        +86,	/* OBJ_issuer_alt_name              2 5 29 18 */
        +87,	/* OBJ_basic_constraints            2 5 29 19 */
        +88,	/* OBJ_crl_number                   2 5 29 20 */
        +141,	/* OBJ_crl_reason                   2 5 29 21 */
        +430,	/* OBJ_hold_instruction_code        2 5 29 23 */
        +142,	/* OBJ_invalidity_date              2 5 29 24 */
        +140,	/* OBJ_delta_crl                    2 5 29 27 */
        +770,	/* OBJ_issuing_distribution_point   2 5 29 28 */
        +771,	/* OBJ_certificate_issuer           2 5 29 29 */
        +666,	/* OBJ_name_constraints             2 5 29 30 */
        +103,	/* OBJ_crl_distribution_points      2 5 29 31 */
        +89,	/* OBJ_certificate_policies         2 5 29 32 */
        +747,	/* OBJ_policy_mappings              2 5 29 33 */
        +90,	/* OBJ_authority_key_identifier     2 5 29 35 */
        +401,	/* OBJ_policy_constraints           2 5 29 36 */
        +126,	/* OBJ_ext_key_usage                2 5 29 37 */
        +857,	/* OBJ_freshest_crl                 2 5 29 46 */
        +748,	/* OBJ_inhibit_any_policy           2 5 29 54 */
        +402,	/* OBJ_target_information           2 5 29 55 */
        +403,	/* OBJ_no_rev_avail                 2 5 29 56 */
        +513,	/* OBJ_set_ctype                    2 23 42 0 */
        +514,	/* OBJ_set_msgExt                   2 23 42 1 */
        +515,	/* OBJ_set_attr                     2 23 42 3 */
        +516,	/* OBJ_set_policy                   2 23 42 5 */
        +517,	/* OBJ_set_certExt                  2 23 42 7 */
        +518,	/* OBJ_set_brand                    2 23 42 8 */
        +679,	/* OBJ_wap_wsg                      2 23 43 1 */
        +382,	/* OBJ_Directory                    1 3 6 1 1 */
        +383,	/* OBJ_Management                   1 3 6 1 2 */
        +384,	/* OBJ_Experimental                 1 3 6 1 3 */
        +385,	/* OBJ_Private                      1 3 6 1 4 */
        +386,	/* OBJ_Security                     1 3 6 1 5 */
        +387,	/* OBJ_SNMPv2                       1 3 6 1 6 */
        +388,	/* OBJ_Mail                         1 3 6 1 7 */
        +376,	/* OBJ_algorithm                    1 3 14 3 2 */
        +395,	/* OBJ_clearance                    2 5 1 5 55 */
        +19,	/* OBJ_rsa                          2 5 8 1 1 */
        +96,	/* OBJ_mdc2WithRSA                  2 5 8 3 100 */
        +95,	/* OBJ_mdc2                         2 5 8 3 101 */
        +746,	/* OBJ_any_policy                   2 5 29 32 0 */
        +910,	/* OBJ_anyExtendedKeyUsage          2 5 29 37 0 */
        +519,	/* OBJ_setct_PANData                2 23 42 0 0 */
        +520,	/* OBJ_setct_PANToken               2 23 42 0 1 */
        +521,	/* OBJ_setct_PANOnly                2 23 42 0 2 */
        +522,	/* OBJ_setct_OIData                 2 23 42 0 3 */
        +523,	/* OBJ_setct_PI                     2 23 42 0 4 */
        +524,	/* OBJ_setct_PIData                 2 23 42 0 5 */
        +525,	/* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
        +526,	/* OBJ_setct_HODInput               2 23 42 0 7 */
        +527,	/* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
        +528,	/* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
        +529,	/* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
        +530,	/* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
        +531,	/* OBJ_setct_PInitResData           2 23 42 0 12 */
        +532,	/* OBJ_setct_PI_TBS                 2 23 42 0 13 */
        +533,	/* OBJ_setct_PResData               2 23 42 0 14 */
        +534,	/* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
        +535,	/* OBJ_setct_AuthResTBS             2 23 42 0 17 */
        +536,	/* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
        +537,	/* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
        +538,	/* OBJ_setct_CapTokenData           2 23 42 0 20 */
        +539,	/* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
        +540,	/* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
        +541,	/* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
        +542,	/* OBJ_setct_AuthRevResData         2 23 42 0 24 */
        +543,	/* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
        +544,	/* OBJ_setct_CapReqTBS              2 23 42 0 26 */
        +545,	/* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
        +546,	/* OBJ_setct_CapResData             2 23 42 0 28 */
        +547,	/* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
        +548,	/* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
        +549,	/* OBJ_setct_CapRevResData          2 23 42 0 31 */
        +550,	/* OBJ_setct_CredReqTBS             2 23 42 0 32 */
        +551,	/* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
        +552,	/* OBJ_setct_CredResData            2 23 42 0 34 */
        +553,	/* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
        +554,	/* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
        +555,	/* OBJ_setct_CredRevResData         2 23 42 0 37 */
        +556,	/* OBJ_setct_PCertReqData           2 23 42 0 38 */
        +557,	/* OBJ_setct_PCertResTBS            2 23 42 0 39 */
        +558,	/* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
        +559,	/* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
        +560,	/* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
        +561,	/* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
        +562,	/* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
        +563,	/* OBJ_setct_CertReqData            2 23 42 0 45 */
        +564,	/* OBJ_setct_CertReqTBS             2 23 42 0 46 */
        +565,	/* OBJ_setct_CertResData            2 23 42 0 47 */
        +566,	/* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
        +567,	/* OBJ_setct_ErrorTBS               2 23 42 0 49 */
        +568,	/* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
        +569,	/* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
        +570,	/* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
        +571,	/* OBJ_setct_AuthResTBE             2 23 42 0 53 */
        +572,	/* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
        +573,	/* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
        +574,	/* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
        +575,	/* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
        +576,	/* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
        +577,	/* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
        +578,	/* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
        +579,	/* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
        +580,	/* OBJ_setct_CapReqTBE              2 23 42 0 62 */
        +581,	/* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
        +582,	/* OBJ_setct_CapResTBE              2 23 42 0 64 */
        +583,	/* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
        +584,	/* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
        +585,	/* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
        +586,	/* OBJ_setct_CredReqTBE             2 23 42 0 68 */
        +587,	/* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
        +588,	/* OBJ_setct_CredResTBE             2 23 42 0 70 */
        +589,	/* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
        +590,	/* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
        +591,	/* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
        +592,	/* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
        +593,	/* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
        +594,	/* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
        +595,	/* OBJ_setct_CertReqTBE             2 23 42 0 77 */
        +596,	/* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
        +597,	/* OBJ_setct_CertResTBE             2 23 42 0 79 */
        +598,	/* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
        +599,	/* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
        +600,	/* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
        +601,	/* OBJ_setext_genCrypt              2 23 42 1 1 */
        +602,	/* OBJ_setext_miAuth                2 23 42 1 3 */
        +603,	/* OBJ_setext_pinSecure             2 23 42 1 4 */
        +604,	/* OBJ_setext_pinAny                2 23 42 1 5 */
        +605,	/* OBJ_setext_track2                2 23 42 1 7 */
        +606,	/* OBJ_setext_cv                    2 23 42 1 8 */
        +620,	/* OBJ_setAttr_Cert                 2 23 42 3 0 */
        +621,	/* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
        +622,	/* OBJ_setAttr_TokenType            2 23 42 3 2 */
        +623,	/* OBJ_setAttr_IssCap               2 23 42 3 3 */
        +607,	/* OBJ_set_policy_root              2 23 42 5 0 */
        +608,	/* OBJ_setCext_hashedRoot           2 23 42 7 0 */
        +609,	/* OBJ_setCext_certType             2 23 42 7 1 */
        +610,	/* OBJ_setCext_merchData            2 23 42 7 2 */
        +611,	/* OBJ_setCext_cCertRequired        2 23 42 7 3 */
        +612,	/* OBJ_setCext_tunneling            2 23 42 7 4 */
        +613,	/* OBJ_setCext_setExt               2 23 42 7 5 */
        +614,	/* OBJ_setCext_setQualf             2 23 42 7 6 */
        +615,	/* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
        +616,	/* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
        +617,	/* OBJ_setCext_Track2Data           2 23 42 7 9 */
        +618,	/* OBJ_setCext_TokenType            2 23 42 7 10 */
        +619,	/* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
        +636,	/* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
        +640,	/* OBJ_set_brand_Visa               2 23 42 8 4 */
        +641,	/* OBJ_set_brand_MasterCard         2 23 42 8 5 */
        +637,	/* OBJ_set_brand_Diners             2 23 42 8 30 */
        +638,	/* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
        +639,	/* OBJ_set_brand_JCB                2 23 42 8 35 */
        +805,	/* OBJ_cryptopro                    1 2 643 2 2 */
        +806,	/* OBJ_cryptocom                    1 2 643 2 9 */
        +184,	/* OBJ_X9_57                        1 2 840 10040 */
        +405,	/* OBJ_ansi_X9_62                   1 2 840 10045 */
        +389,	/* OBJ_Enterprises                  1 3 6 1 4 1 */
        +504,	/* OBJ_mime_mhs                     1 3 6 1 7 1 */
        +104,	/* OBJ_md5WithRSA                   1 3 14 3 2 3 */
        +29,	/* OBJ_des_ecb                      1 3 14 3 2 6 */
        +31,	/* OBJ_des_cbc                      1 3 14 3 2 7 */
        +45,	/* OBJ_des_ofb64                    1 3 14 3 2 8 */
        +30,	/* OBJ_des_cfb64                    1 3 14 3 2 9 */
        +377,	/* OBJ_rsaSignature                 1 3 14 3 2 11 */
        +67,	/* OBJ_dsa_2                        1 3 14 3 2 12 */
        +66,	/* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
        +42,	/* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
        +32,	/* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
        +41,	/* OBJ_sha                          1 3 14 3 2 18 */
        +64,	/* OBJ_sha1                         1 3 14 3 2 26 */
        +70,	/* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
        +115,	/* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
        +117,	/* OBJ_ripemd160                    1 3 36 3 2 1 */
        +143,	/* OBJ_sxnet                        1 3 101 1 4 1 */
        +721,	/* OBJ_sect163k1                    1 3 132 0 1 */
        +722,	/* OBJ_sect163r1                    1 3 132 0 2 */
        +728,	/* OBJ_sect239k1                    1 3 132 0 3 */
        +717,	/* OBJ_sect113r1                    1 3 132 0 4 */
        +718,	/* OBJ_sect113r2                    1 3 132 0 5 */
        +704,	/* OBJ_secp112r1                    1 3 132 0 6 */
        +705,	/* OBJ_secp112r2                    1 3 132 0 7 */
        +709,	/* OBJ_secp160r1                    1 3 132 0 8 */
        +708,	/* OBJ_secp160k1                    1 3 132 0 9 */
        +714,	/* OBJ_secp256k1                    1 3 132 0 10 */
        +723,	/* OBJ_sect163r2                    1 3 132 0 15 */
        +729,	/* OBJ_sect283k1                    1 3 132 0 16 */
        +730,	/* OBJ_sect283r1                    1 3 132 0 17 */
        +719,	/* OBJ_sect131r1                    1 3 132 0 22 */
        +720,	/* OBJ_sect131r2                    1 3 132 0 23 */
        +724,	/* OBJ_sect193r1                    1 3 132 0 24 */
        +725,	/* OBJ_sect193r2                    1 3 132 0 25 */
        +726,	/* OBJ_sect233k1                    1 3 132 0 26 */
        +727,	/* OBJ_sect233r1                    1 3 132 0 27 */
        +706,	/* OBJ_secp128r1                    1 3 132 0 28 */
        +707,	/* OBJ_secp128r2                    1 3 132 0 29 */
        +710,	/* OBJ_secp160r2                    1 3 132 0 30 */
        +711,	/* OBJ_secp192k1                    1 3 132 0 31 */
        +712,	/* OBJ_secp224k1                    1 3 132 0 32 */
        +713,	/* OBJ_secp224r1                    1 3 132 0 33 */
        +715,	/* OBJ_secp384r1                    1 3 132 0 34 */
        +716,	/* OBJ_secp521r1                    1 3 132 0 35 */
        +731,	/* OBJ_sect409k1                    1 3 132 0 36 */
        +732,	/* OBJ_sect409r1                    1 3 132 0 37 */
        +733,	/* OBJ_sect571k1                    1 3 132 0 38 */
        +734,	/* OBJ_sect571r1                    1 3 132 0 39 */
        +624,	/* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
        +625,	/* OBJ_set_addPolicy                2 23 42 3 0 1 */
        +626,	/* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
        +627,	/* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
        +628,	/* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
        +629,	/* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
        +630,	/* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
        +642,	/* OBJ_set_brand_Novus              2 23 42 8 6011 */
        +735,	/* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
        +736,	/* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
        +737,	/* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
        +738,	/* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
        +739,	/* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
        +740,	/* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
        +741,	/* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
        +742,	/* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
        +743,	/* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
        +744,	/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
        +745,	/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
        +804,	/* OBJ_whirlpool                    1 0 10118 3 0 55 */
        +124,	/* OBJ_rle_compression              1 1 1 1 666 1 */
        +773,	/* OBJ_kisa                         1 2 410 200004 */
        +807,	/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
        +808,	/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
        +809,	/* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
        +810,	/* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
        +811,	/* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
        +812,	/* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
        +813,	/* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
        +815,	/* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
        +816,	/* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
        +817,	/* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
        +818,	/* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
        + 1,	/* OBJ_rsadsi                       1 2 840 113549 */
        +185,	/* OBJ_X9cm                         1 2 840 10040 4 */
        +127,	/* OBJ_id_pkix                      1 3 6 1 5 5 7 */
        +505,	/* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
        +506,	/* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
        +119,	/* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
        +631,	/* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
        +632,	/* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
        +633,	/* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
        +634,	/* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
        +635,	/* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
        +436,	/* OBJ_ucl                          0 9 2342 19200300 */
        +820,	/* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
        +819,	/* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
        +845,	/* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
        +846,	/* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
        +847,	/* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
        +848,	/* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
        +821,	/* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
        +822,	/* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
        +823,	/* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
        +824,	/* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
        +825,	/* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
        +826,	/* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
        +827,	/* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
        +828,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
        +829,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
        +830,	/* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
        +831,	/* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
        +832,	/* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
        +833,	/* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
        +834,	/* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
        +835,	/* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
        +836,	/* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
        +837,	/* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
        +838,	/* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
        +839,	/* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
        +840,	/* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
        +841,	/* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
        +842,	/* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
        +843,	/* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
        +844,	/* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
        + 2,	/* OBJ_pkcs                         1 2 840 113549 1 */
        +431,	/* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
        +432,	/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
        +433,	/* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
        +116,	/* OBJ_dsa                          1 2 840 10040 4 1 */
        +113,	/* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
        +406,	/* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
        +407,	/* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
        +408,	/* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
        +416,	/* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
        +791,	/* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
        +792,	/* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
        +258,	/* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
        +175,	/* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
        +259,	/* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
        +128,	/* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
        +260,	/* OBJ_id_it                        1 3 6 1 5 5 7 4 */
        +261,	/* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
        +262,	/* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
        +263,	/* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
        +264,	/* OBJ_id_on                        1 3 6 1 5 5 7 8 */
        +265,	/* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
        +266,	/* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
        +267,	/* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
        +268,	/* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
        +662,	/* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
        +176,	/* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
        +507,	/* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
        +508,	/* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
        +57,	/* OBJ_netscape                     2 16 840 1 113730 */
        +754,	/* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
        +766,	/* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
        +757,	/* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
        +755,	/* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
        +767,	/* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
        +758,	/* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
        +756,	/* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
        +768,	/* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
        +759,	/* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
        +437,	/* OBJ_pilot                        0 9 2342 19200300 100 */
        +776,	/* OBJ_seed_ecb                     1 2 410 200004 1 3 */
        +777,	/* OBJ_seed_cbc                     1 2 410 200004 1 4 */
        +779,	/* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
        +778,	/* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
        +852,	/* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
        +853,	/* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
        +850,	/* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
        +851,	/* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
        +849,	/* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
        +854,	/* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
        +186,	/* OBJ_pkcs1                        1 2 840 113549 1 1 */
        +27,	/* OBJ_pkcs3                        1 2 840 113549 1 3 */
        +187,	/* OBJ_pkcs5                        1 2 840 113549 1 5 */
        +20,	/* OBJ_pkcs7                        1 2 840 113549 1 7 */
        +47,	/* OBJ_pkcs9                        1 2 840 113549 1 9 */
        + 3,	/* OBJ_md2                          1 2 840 113549 2 2 */
        +257,	/* OBJ_md4                          1 2 840 113549 2 4 */
        + 4,	/* OBJ_md5                          1 2 840 113549 2 5 */
        +797,	/* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
        +163,	/* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
        +798,	/* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
        +799,	/* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
        +800,	/* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
        +801,	/* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
        +37,	/* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
        + 5,	/* OBJ_rc4                          1 2 840 113549 3 4 */
        +44,	/* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
        +120,	/* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
        +643,	/* OBJ_des_cdmf                     1 2 840 113549 3 10 */
        +680,	/* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
        +684,	/* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
        +685,	/* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
        +686,	/* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
        +687,	/* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
        +688,	/* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
        +689,	/* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
        +690,	/* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
        +691,	/* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
        +692,	/* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
        +693,	/* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
        +694,	/* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
        +695,	/* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
        +696,	/* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
        +697,	/* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
        +698,	/* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
        +699,	/* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
        +700,	/* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
        +701,	/* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
        +702,	/* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
        +703,	/* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
        +409,	/* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
        +410,	/* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
        +411,	/* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
        +412,	/* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
        +413,	/* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
        +414,	/* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
        +415,	/* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
        +793,	/* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
        +794,	/* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
        +795,	/* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
        +796,	/* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
        +269,	/* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
        +270,	/* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
        +271,	/* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
        +272,	/* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
        +273,	/* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
        +274,	/* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
        +275,	/* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
        +276,	/* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
        +277,	/* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
        +278,	/* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
        +279,	/* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
        +280,	/* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
        +281,	/* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
        +282,	/* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
        +283,	/* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
        +284,	/* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
        +177,	/* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
        +285,	/* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
        +286,	/* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
        +287,	/* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
        +288,	/* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
        +289,	/* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
        +290,	/* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
        +291,	/* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
        +292,	/* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
        +397,	/* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
        +398,	/* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
        +663,	/* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
        +164,	/* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
        +165,	/* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
        +293,	/* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
        +129,	/* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
        +130,	/* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
        +131,	/* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
        +132,	/* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
        +294,	/* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
        +295,	/* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
        +296,	/* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
        +133,	/* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
        +180,	/* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
        +297,	/* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
        +298,	/* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
        +299,	/* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
        +300,	/* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
        +301,	/* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
        +302,	/* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
        +303,	/* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
        +304,	/* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
        +305,	/* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
        +306,	/* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
        +307,	/* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
        +308,	/* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
        +309,	/* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
        +310,	/* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
        +311,	/* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
        +312,	/* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
        +784,	/* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
        +313,	/* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
        +314,	/* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
        +323,	/* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
        +324,	/* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
        +325,	/* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
        +326,	/* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
        +327,	/* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
        +328,	/* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
        +329,	/* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
        +330,	/* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
        +331,	/* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
        +332,	/* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
        +333,	/* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
        +334,	/* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
        +335,	/* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
        +336,	/* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
        +337,	/* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
        +338,	/* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
        +339,	/* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
        +340,	/* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
        +341,	/* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
        +342,	/* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
        +343,	/* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
        +344,	/* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
        +345,	/* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
        +346,	/* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
        +347,	/* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
        +858,	/* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
        +348,	/* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
        +349,	/* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
        +351,	/* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
        +352,	/* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
        +353,	/* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
        +354,	/* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
        +355,	/* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
        +356,	/* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
        +357,	/* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
        +358,	/* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
        +399,	/* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
        +359,	/* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
        +360,	/* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
        +361,	/* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
        +362,	/* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
        +664,	/* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
        +665,	/* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
        +667,	/* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
        +178,	/* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
        +179,	/* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
        +363,	/* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
        +364,	/* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
        +785,	/* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
        +780,	/* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
        +781,	/* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
        +58,	/* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
        +59,	/* OBJ_netscape_data_type           2 16 840 1 113730 2 */
        +438,	/* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
        +439,	/* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
        +440,	/* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
        +441,	/* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
        +108,	/* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
        +112,	/* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
        +782,	/* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
        +783,	/* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
        + 6,	/* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
        + 7,	/* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
        +396,	/* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
        + 8,	/* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
        +65,	/* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
        +644,	/* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
        +919,	/* OBJ_rsaesOaep                    1 2 840 113549 1 1 7 */
        +911,	/* OBJ_mgf1                         1 2 840 113549 1 1 8 */
        +912,	/* OBJ_rsassaPss                    1 2 840 113549 1 1 10 */
        +668,	/* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
        +669,	/* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
        +670,	/* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
        +671,	/* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
        +28,	/* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
        + 9,	/* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
        +10,	/* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
        +168,	/* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
        +169,	/* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
        +170,	/* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
        +68,	/* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
        +69,	/* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
        +161,	/* OBJ_pbes2                        1 2 840 113549 1 5 13 */
        +162,	/* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
        +21,	/* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
        +22,	/* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
        +23,	/* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
        +24,	/* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
        +25,	/* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
        +26,	/* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
        +48,	/* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
        +49,	/* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
        +50,	/* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
        +51,	/* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
        +52,	/* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
        +53,	/* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
        +54,	/* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
        +55,	/* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
        +56,	/* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
        +172,	/* OBJ_ext_req                      1 2 840 113549 1 9 14 */
        +167,	/* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
        +188,	/* OBJ_SMIME                        1 2 840 113549 1 9 16 */
        +156,	/* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
        +157,	/* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
        +681,	/* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
        +682,	/* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
        +683,	/* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
        +417,	/* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
        +856,	/* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
        +390,	/* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
        +91,	/* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
        +315,	/* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
        +316,	/* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
        +317,	/* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
        +318,	/* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
        +319,	/* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
        +320,	/* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
        +321,	/* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
        +322,	/* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
        +365,	/* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
        +366,	/* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
        +367,	/* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
        +368,	/* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
        +369,	/* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
        +370,	/* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
        +371,	/* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
        +372,	/* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
        +373,	/* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
        +374,	/* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
        +375,	/* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
        +418,	/* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
        +419,	/* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
        +420,	/* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
        +421,	/* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
        +788,	/* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
        +895,	/* OBJ_aes_128_gcm                  2 16 840 1 101 3 4 1 6 */
        +896,	/* OBJ_aes_128_ccm                  2 16 840 1 101 3 4 1 7 */
        +897,	/* OBJ_id_aes128_wrap_pad           2 16 840 1 101 3 4 1 8 */
        +422,	/* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
        +423,	/* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
        +424,	/* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
        +425,	/* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
        +789,	/* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
        +898,	/* OBJ_aes_192_gcm                  2 16 840 1 101 3 4 1 26 */
        +899,	/* OBJ_aes_192_ccm                  2 16 840 1 101 3 4 1 27 */
        +900,	/* OBJ_id_aes192_wrap_pad           2 16 840 1 101 3 4 1 28 */
        +426,	/* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
        +427,	/* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
        +428,	/* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
        +429,	/* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
        +790,	/* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
        +901,	/* OBJ_aes_256_gcm                  2 16 840 1 101 3 4 1 46 */
        +902,	/* OBJ_aes_256_ccm                  2 16 840 1 101 3 4 1 47 */
        +903,	/* OBJ_id_aes256_wrap_pad           2 16 840 1 101 3 4 1 48 */
        +672,	/* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
        +673,	/* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
        +674,	/* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
        +675,	/* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
        +802,	/* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
        +803,	/* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
        +71,	/* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
        +72,	/* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
        +73,	/* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
        +74,	/* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
        +75,	/* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
        +76,	/* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
        +77,	/* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
        +78,	/* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
        +79,	/* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
        +139,	/* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
        +458,	/* OBJ_userId                       0 9 2342 19200300 100 1 1 */
        +459,	/* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
        +460,	/* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
        +461,	/* OBJ_info                         0 9 2342 19200300 100 1 4 */
        +462,	/* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
        +463,	/* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
        +464,	/* OBJ_photo                        0 9 2342 19200300 100 1 7 */
        +465,	/* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
        +466,	/* OBJ_host                         0 9 2342 19200300 100 1 9 */
        +467,	/* OBJ_manager                      0 9 2342 19200300 100 1 10 */
        +468,	/* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
        +469,	/* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
        +470,	/* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
        +471,	/* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
        +472,	/* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
        +473,	/* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
        +474,	/* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
        +475,	/* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
        +476,	/* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
        +477,	/* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
        +391,	/* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
        +478,	/* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
        +479,	/* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
        +480,	/* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
        +481,	/* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
        +482,	/* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
        +483,	/* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
        +484,	/* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
        +485,	/* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
        +486,	/* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
        +487,	/* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
        +488,	/* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
        +489,	/* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
        +490,	/* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
        +491,	/* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
        +492,	/* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
        +493,	/* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
        +494,	/* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
        +495,	/* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
        +496,	/* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
        +497,	/* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
        +498,	/* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
        +499,	/* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
        +500,	/* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
        +501,	/* OBJ_audio                        0 9 2342 19200300 100 1 55 */
        +502,	/* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
        +442,	/* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
        +443,	/* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
        +444,	/* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
        +445,	/* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
        +446,	/* OBJ_account                      0 9 2342 19200300 100 4 5 */
        +447,	/* OBJ_document                     0 9 2342 19200300 100 4 6 */
        +448,	/* OBJ_room                         0 9 2342 19200300 100 4 7 */
        +449,	/* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
        +392,	/* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
        +450,	/* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
        +451,	/* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
        +452,	/* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
        +453,	/* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
        +454,	/* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
        +455,	/* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
        +456,	/* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
        +457,	/* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
        +189,	/* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
        +190,	/* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
        +191,	/* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
        +192,	/* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
        +193,	/* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
        +194,	/* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
        +195,	/* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
        +158,	/* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
        +159,	/* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
        +160,	/* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
        +144,	/* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
        +145,	/* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
        +146,	/* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
        +147,	/* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
        +148,	/* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
        +149,	/* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
        +171,	/* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
        +134,	/* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
        +135,	/* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
        +136,	/* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
        +137,	/* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
        +138,	/* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
        +648,	/* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
        +649,	/* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
        +751,	/* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
        +752,	/* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
        +753,	/* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
        +907,	/* OBJ_id_camellia128_wrap          1 2 392 200011 61 1 1 3 2 */
        +908,	/* OBJ_id_camellia192_wrap          1 2 392 200011 61 1 1 3 3 */
        +909,	/* OBJ_id_camellia256_wrap          1 2 392 200011 61 1 1 3 4 */
        +196,	/* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
        +197,	/* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
        +198,	/* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
        +199,	/* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
        +200,	/* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
        +201,	/* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
        +202,	/* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
        +203,	/* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
        +204,	/* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
        +205,	/* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
        +206,	/* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
        +207,	/* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
        +208,	/* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
        +209,	/* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
        +210,	/* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
        +211,	/* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
        +786,	/* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
        +787,	/* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
        +212,	/* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
        +213,	/* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
        +214,	/* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
        +215,	/* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
        +216,	/* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
        +217,	/* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
        +218,	/* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
        +219,	/* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
        +220,	/* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
        +221,	/* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
        +222,	/* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
        +223,	/* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
        +224,	/* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
        +225,	/* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
        +226,	/* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
        +227,	/* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
        +228,	/* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
        +229,	/* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
        +230,	/* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
        +231,	/* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
        +232,	/* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
        +233,	/* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
        +234,	/* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
        +235,	/* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
        +236,	/* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
        +237,	/* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
        +238,	/* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
        +239,	/* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
        +240,	/* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
        +241,	/* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
        +242,	/* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
        +243,	/* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
        +244,	/* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
        +245,	/* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
        +246,	/* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
        +247,	/* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
        +125,	/* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
        +893,	/* OBJ_id_alg_PWRI_KEK              1 2 840 113549 1 9 16 3 9 */
        +248,	/* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
        +249,	/* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
        +250,	/* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
        +251,	/* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
        +252,	/* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
        +253,	/* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
        +254,	/* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
        +255,	/* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
        +256,	/* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
        +150,	/* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
        +151,	/* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
        +152,	/* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
        +153,	/* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
        +154,	/* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
        +155,	/* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
        +34,	/* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
        +};
        +
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_dat.pl b/vendor/openssl/openssl/crypto/objects/obj_dat.pl
        new file mode 100644
        index 000000000..c67f71c32
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_dat.pl
        @@ -0,0 +1,307 @@
        +#!/usr/local/bin/perl
        +
        +# fixes bug in floating point emulation on sparc64 when
        +# this script produces off-by-one output on sparc64
        +use integer;
        +
        +sub obj_cmp
        +	{
        +	local(@a,@b,$_,$r);
        +
        +	$A=$obj_len{$obj{$nid{$a}}};
        +	$B=$obj_len{$obj{$nid{$b}}};
        +
        +	$r=($A-$B);
        +	return($r) if $r != 0;
        +
        +	$A=$obj_der{$obj{$nid{$a}}};
        +	$B=$obj_der{$obj{$nid{$b}}};
        +
        +	return($A cmp $B);
        +	}
        +
        +sub expand_obj
        +	{
        +	local(*v)=@_;
        +	local($k,$d);
        +	local($i);
        +
        +	do	{
        +		$i=0;
        +		foreach $k (keys %v)
        +			{
        +			if (($v{$k} =~ s/(OBJ_[^,]+),/$v{$1},/))
        +				{ $i++; }
        +			}
        +		} while($i);
        +	foreach $k (keys %v)
        +		{
        +		@a=split(/,/,$v{$k});
        +		$objn{$k}=$#a+1;
        +		}
        +	return(%objn);
        +	}
        +
        +open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]";
        +open (OUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]";
        +
        +while (<IN>)
        +	{
        +	next unless /^\#define\s+(\S+)\s+(.*)$/;
        +	$v=$1;
        +	$d=$2;
        +	$d =~ s/^\"//;
        +	$d =~ s/\"$//;
        +	if ($v =~ /^SN_(.*)$/)
        +		{
        +		if(defined $snames{$d})
        +			{
        +			print "WARNING: Duplicate short name \"$d\"\n";
        +			}
        +		else 
        +			{ $snames{$d} = "X"; }
        +		$sn{$1}=$d;
        +		}
        +	elsif ($v =~ /^LN_(.*)$/)
        +		{
        +		if(defined $lnames{$d})
        +			{
        +			print "WARNING: Duplicate long name \"$d\"\n";
        +			}
        +		else 
        +			{ $lnames{$d} = "X"; }
        +		$ln{$1}=$d;
        +		}
        +	elsif ($v =~ /^NID_(.*)$/)
        +		{ $nid{$d}=$1; }
        +	elsif ($v =~ /^OBJ_(.*)$/)
        +		{
        +		$obj{$1}=$v;
        +		$objd{$v}=$d;
        +		}
        +	}
        +close IN;
        +
        +%ob=&expand_obj(*objd);
        +
        +@a=sort { $a <=> $b } keys %nid;
        +$n=$a[$#a]+1;
        +
        +@lvalues=();
        +$lvalues=0;
        +
        +for ($i=0; $i<$n; $i++)
        +	{
        +	if (!defined($nid{$i}))
        +		{
        +		push(@out,"{NULL,NULL,NID_undef,0,NULL,0},\n");
        +		}
        +	else
        +		{
        +		$sn=defined($sn{$nid{$i}})?"$sn{$nid{$i}}":"NULL";
        +		$ln=defined($ln{$nid{$i}})?"$ln{$nid{$i}}":"NULL";
        +
        +		if ($sn eq "NULL") {
        +			$sn=$ln;
        +			$sn{$nid{$i}} = $ln;
        +		}
        +
        +		if ($ln eq "NULL") {
        +			$ln=$sn;
        +			$ln{$nid{$i}} = $sn;
        +		}
        +			
        +		$out ="{";
        +		$out.="\"$sn\"";
        +		$out.=","."\"$ln\"";
        +		$out.=",NID_$nid{$i},";
        +		if (defined($obj{$nid{$i}}))
        +			{
        +			$v=$objd{$obj{$nid{$i}}};
        +			$v =~ s/L//g;
        +			$v =~ s/,/ /g;
        +			$r=&der_it($v);
        +			$z="";
        +			$length=0;
        +			foreach (unpack("C*",$r))
        +				{
        +				$z.=sprintf("0x%02X,",$_);
        +				$length++;
        +				}
        +			$obj_der{$obj{$nid{$i}}}=$z;
        +			$obj_len{$obj{$nid{$i}}}=$length;
        +
        +			push(@lvalues,sprintf("%-45s/* [%3d] %s */\n",
        +				$z,$lvalues,$obj{$nid{$i}}));
        +			$out.="$length,&(lvalues[$lvalues]),0";
        +			$lvalues+=$length;
        +			}
        +		else
        +			{
        +			$out.="0,NULL,0";
        +			}
        +		$out.="},\n";
        +		push(@out,$out);
        +		}
        +	}
        +
        +@a=grep(defined($sn{$nid{$_}}),0 .. $n);
        +foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a)
        +	{
        +	push(@sn,sprintf("%2d,\t/* \"$sn{$nid{$_}}\" */\n",$_));
        +	}
        +
        +@a=grep(defined($ln{$nid{$_}}),0 .. $n);
        +foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a)
        +	{
        +	push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
        +	}
        +
        +@a=grep(defined($obj{$nid{$_}}),0 .. $n);
        +foreach (sort obj_cmp @a)
        +	{
        +	$m=$obj{$nid{$_}};
        +	$v=$objd{$m};
        +	$v =~ s/L//g;
        +	$v =~ s/,/ /g;
        +	push(@ob,sprintf("%2d,\t/* %-32s %s */\n",$_,$m,$v));
        +	}
        +
        +print OUT <<'EOF';
        +/* crypto/objects/obj_dat.h */
        +
        +/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
        + * following command:
        + * perl obj_dat.pl obj_mac.h obj_dat.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.]
        + */
        +
        +EOF
        +
        +printf OUT "#define NUM_NID %d\n",$n;
        +printf OUT "#define NUM_SN %d\n",$#sn+1;
        +printf OUT "#define NUM_LN %d\n",$#ln+1;
        +printf OUT "#define NUM_OBJ %d\n\n",$#ob+1;
        +
        +printf OUT "static const unsigned char lvalues[%d]={\n",$lvalues+1;
        +print OUT @lvalues;
        +print OUT "};\n\n";
        +
        +printf OUT "static const ASN1_OBJECT nid_objs[NUM_NID]={\n";
        +foreach (@out)
        +	{
        +	if (length($_) > 75)
        +		{
        +		$out="";
        +		foreach (split(/,/))
        +			{
        +			$t=$out.$_.",";
        +			if (length($t) > 70)
        +				{
        +				print OUT "$out\n";
        +				$t="\t$_,";
        +				}
        +			$out=$t;
        +			}
        +		chop $out;
        +		print OUT "$out";
        +		}
        +	else
        +		{ print OUT $_; }
        +	}
        +print  OUT "};\n\n";
        +
        +printf OUT "static const unsigned int sn_objs[NUM_SN]={\n";
        +print  OUT @sn;
        +print  OUT "};\n\n";
        +
        +printf OUT "static const unsigned int ln_objs[NUM_LN]={\n";
        +print  OUT @ln;
        +print  OUT "};\n\n";
        +
        +printf OUT "static const unsigned int obj_objs[NUM_OBJ]={\n";
        +print  OUT @ob;
        +print  OUT "};\n\n";
        +
        +close OUT;
        +
        +sub der_it
        +	{
        +	local($v)=@_;
        +	local(@a,$i,$ret,@r);
        +
        +	@a=split(/\s+/,$v);
        +	$ret.=pack("C*",$a[0]*40+$a[1]);
        +	shift @a;
        +	shift @a;
        +	foreach (@a)
        +		{
        +		@r=();
        +		$t=0;
        +		while ($_ >= 128)
        +			{
        +			$x=$_%128;
        +			$_/=128;
        +			push(@r,((($t++)?0x80:0)|$x));
        +			}
        +		push(@r,((($t++)?0x80:0)|$_));
        +		$ret.=pack("C*",reverse(@r));
        +		}
        +	return($ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_err.c b/vendor/openssl/openssl/crypto/objects/obj_err.c
        new file mode 100644
        index 000000000..2e7a034c3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_err.c
        @@ -0,0 +1,102 @@
        +/* crypto/objects/obj_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/objects.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason)
        +
        +static ERR_STRING_DATA OBJ_str_functs[]=
        +	{
        +{ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT),	"OBJ_add_object"},
        +{ERR_FUNC(OBJ_F_OBJ_CREATE),	"OBJ_create"},
        +{ERR_FUNC(OBJ_F_OBJ_DUP),	"OBJ_dup"},
        +{ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX),	"OBJ_NAME_new_index"},
        +{ERR_FUNC(OBJ_F_OBJ_NID2LN),	"OBJ_nid2ln"},
        +{ERR_FUNC(OBJ_F_OBJ_NID2OBJ),	"OBJ_nid2obj"},
        +{ERR_FUNC(OBJ_F_OBJ_NID2SN),	"OBJ_nid2sn"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA OBJ_str_reasons[]=
        +	{
        +{ERR_REASON(OBJ_R_MALLOC_FAILURE)        ,"malloc failure"},
        +{ERR_REASON(OBJ_R_UNKNOWN_NID)           ,"unknown nid"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_OBJ_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,OBJ_str_functs);
        +		ERR_load_strings(0,OBJ_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_lib.c b/vendor/openssl/openssl/crypto/objects/obj_lib.c
        new file mode 100644
        index 000000000..23e9d48cd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_lib.c
        @@ -0,0 +1,129 @@
        +/* crypto/objects/obj_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +
        +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
        +	{
        +	ASN1_OBJECT *r;
        +	int i;
        +	char *ln=NULL,*sn=NULL;
        +	unsigned char *data=NULL;
        +
        +	if (o == NULL) return(NULL);
        +	if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
        +		return((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of
        +					     duplication is this??? */
        +
        +	r=ASN1_OBJECT_new();
        +	if (r == NULL)
        +		{
        +		OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB);
        +		return(NULL);
        +		}
        +	data=OPENSSL_malloc(o->length);
        +	if (data == NULL)
        +		goto err;
        +	if (o->data != NULL)
        +		memcpy(data,o->data,o->length);
        +	/* once data attached to object it remains const */
        +	r->data = data;
        +	r->length=o->length;
        +	r->nid=o->nid;
        +	r->ln=r->sn=NULL;
        +	if (o->ln != NULL)
        +		{
        +		i=strlen(o->ln)+1;
        +		ln=OPENSSL_malloc(i);
        +		if (ln == NULL) goto err;
        +		memcpy(ln,o->ln,i);
        +		r->ln=ln;
        +		}
        +
        +	if (o->sn != NULL)
        +		{
        +		i=strlen(o->sn)+1;
        +		sn=OPENSSL_malloc(i);
        +		if (sn == NULL) goto err;
        +		memcpy(sn,o->sn,i);
        +		r->sn=sn;
        +		}
        +	r->flags=o->flags|(ASN1_OBJECT_FLAG_DYNAMIC|
        +		ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA);
        +	return(r);
        +err:
        +	OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE);
        +	if (ln != NULL)		OPENSSL_free(ln);
        +	if (sn != NULL)		OPENSSL_free(sn);
        +	if (data != NULL)	OPENSSL_free(data);
        +	if (r != NULL)		OPENSSL_free(r);
        +	return(NULL);
        +	}
        +
        +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
        +	{
        +	int ret;
        +
        +	ret=(a->length-b->length);
        +	if (ret) return(ret);
        +	return(memcmp(a->data,b->data,a->length));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_mac.h b/vendor/openssl/openssl/crypto/objects/obj_mac.h
        new file mode 100644
        index 000000000..b5ea7cdab
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_mac.h
        @@ -0,0 +1,4032 @@
        +/* crypto/objects/obj_mac.h */
        +
        +/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
        + * following command:
        + * perl objects.pl objects.txt obj_mac.num obj_mac.h
        + */
        +
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#define SN_undef			"UNDEF"
        +#define LN_undef			"undefined"
        +#define NID_undef			0
        +#define OBJ_undef			0L
        +
        +#define SN_itu_t		"ITU-T"
        +#define LN_itu_t		"itu-t"
        +#define NID_itu_t		645
        +#define OBJ_itu_t		0L
        +
        +#define NID_ccitt		404
        +#define OBJ_ccitt		OBJ_itu_t
        +
        +#define SN_iso		"ISO"
        +#define LN_iso		"iso"
        +#define NID_iso		181
        +#define OBJ_iso		1L
        +
        +#define SN_joint_iso_itu_t		"JOINT-ISO-ITU-T"
        +#define LN_joint_iso_itu_t		"joint-iso-itu-t"
        +#define NID_joint_iso_itu_t		646
        +#define OBJ_joint_iso_itu_t		2L
        +
        +#define NID_joint_iso_ccitt		393
        +#define OBJ_joint_iso_ccitt		OBJ_joint_iso_itu_t
        +
        +#define SN_member_body		"member-body"
        +#define LN_member_body		"ISO Member Body"
        +#define NID_member_body		182
        +#define OBJ_member_body		OBJ_iso,2L
        +
        +#define SN_identified_organization		"identified-organization"
        +#define NID_identified_organization		676
        +#define OBJ_identified_organization		OBJ_iso,3L
        +
        +#define SN_hmac_md5		"HMAC-MD5"
        +#define LN_hmac_md5		"hmac-md5"
        +#define NID_hmac_md5		780
        +#define OBJ_hmac_md5		OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
        +
        +#define SN_hmac_sha1		"HMAC-SHA1"
        +#define LN_hmac_sha1		"hmac-sha1"
        +#define NID_hmac_sha1		781
        +#define OBJ_hmac_sha1		OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
        +
        +#define SN_certicom_arc		"certicom-arc"
        +#define NID_certicom_arc		677
        +#define OBJ_certicom_arc		OBJ_identified_organization,132L
        +
        +#define SN_international_organizations		"international-organizations"
        +#define LN_international_organizations		"International Organizations"
        +#define NID_international_organizations		647
        +#define OBJ_international_organizations		OBJ_joint_iso_itu_t,23L
        +
        +#define SN_wap		"wap"
        +#define NID_wap		678
        +#define OBJ_wap		OBJ_international_organizations,43L
        +
        +#define SN_wap_wsg		"wap-wsg"
        +#define NID_wap_wsg		679
        +#define OBJ_wap_wsg		OBJ_wap,1L
        +
        +#define SN_selected_attribute_types		"selected-attribute-types"
        +#define LN_selected_attribute_types		"Selected Attribute Types"
        +#define NID_selected_attribute_types		394
        +#define OBJ_selected_attribute_types		OBJ_joint_iso_itu_t,5L,1L,5L
        +
        +#define SN_clearance		"clearance"
        +#define NID_clearance		395
        +#define OBJ_clearance		OBJ_selected_attribute_types,55L
        +
        +#define SN_ISO_US		"ISO-US"
        +#define LN_ISO_US		"ISO US Member Body"
        +#define NID_ISO_US		183
        +#define OBJ_ISO_US		OBJ_member_body,840L
        +
        +#define SN_X9_57		"X9-57"
        +#define LN_X9_57		"X9.57"
        +#define NID_X9_57		184
        +#define OBJ_X9_57		OBJ_ISO_US,10040L
        +
        +#define SN_X9cm		"X9cm"
        +#define LN_X9cm		"X9.57 CM ?"
        +#define NID_X9cm		185
        +#define OBJ_X9cm		OBJ_X9_57,4L
        +
        +#define SN_dsa		"DSA"
        +#define LN_dsa		"dsaEncryption"
        +#define NID_dsa		116
        +#define OBJ_dsa		OBJ_X9cm,1L
        +
        +#define SN_dsaWithSHA1		"DSA-SHA1"
        +#define LN_dsaWithSHA1		"dsaWithSHA1"
        +#define NID_dsaWithSHA1		113
        +#define OBJ_dsaWithSHA1		OBJ_X9cm,3L
        +
        +#define SN_ansi_X9_62		"ansi-X9-62"
        +#define LN_ansi_X9_62		"ANSI X9.62"
        +#define NID_ansi_X9_62		405
        +#define OBJ_ansi_X9_62		OBJ_ISO_US,10045L
        +
        +#define OBJ_X9_62_id_fieldType		OBJ_ansi_X9_62,1L
        +
        +#define SN_X9_62_prime_field		"prime-field"
        +#define NID_X9_62_prime_field		406
        +#define OBJ_X9_62_prime_field		OBJ_X9_62_id_fieldType,1L
        +
        +#define SN_X9_62_characteristic_two_field		"characteristic-two-field"
        +#define NID_X9_62_characteristic_two_field		407
        +#define OBJ_X9_62_characteristic_two_field		OBJ_X9_62_id_fieldType,2L
        +
        +#define SN_X9_62_id_characteristic_two_basis		"id-characteristic-two-basis"
        +#define NID_X9_62_id_characteristic_two_basis		680
        +#define OBJ_X9_62_id_characteristic_two_basis		OBJ_X9_62_characteristic_two_field,3L
        +
        +#define SN_X9_62_onBasis		"onBasis"
        +#define NID_X9_62_onBasis		681
        +#define OBJ_X9_62_onBasis		OBJ_X9_62_id_characteristic_two_basis,1L
        +
        +#define SN_X9_62_tpBasis		"tpBasis"
        +#define NID_X9_62_tpBasis		682
        +#define OBJ_X9_62_tpBasis		OBJ_X9_62_id_characteristic_two_basis,2L
        +
        +#define SN_X9_62_ppBasis		"ppBasis"
        +#define NID_X9_62_ppBasis		683
        +#define OBJ_X9_62_ppBasis		OBJ_X9_62_id_characteristic_two_basis,3L
        +
        +#define OBJ_X9_62_id_publicKeyType		OBJ_ansi_X9_62,2L
        +
        +#define SN_X9_62_id_ecPublicKey		"id-ecPublicKey"
        +#define NID_X9_62_id_ecPublicKey		408
        +#define OBJ_X9_62_id_ecPublicKey		OBJ_X9_62_id_publicKeyType,1L
        +
        +#define OBJ_X9_62_ellipticCurve		OBJ_ansi_X9_62,3L
        +
        +#define OBJ_X9_62_c_TwoCurve		OBJ_X9_62_ellipticCurve,0L
        +
        +#define SN_X9_62_c2pnb163v1		"c2pnb163v1"
        +#define NID_X9_62_c2pnb163v1		684
        +#define OBJ_X9_62_c2pnb163v1		OBJ_X9_62_c_TwoCurve,1L
        +
        +#define SN_X9_62_c2pnb163v2		"c2pnb163v2"
        +#define NID_X9_62_c2pnb163v2		685
        +#define OBJ_X9_62_c2pnb163v2		OBJ_X9_62_c_TwoCurve,2L
        +
        +#define SN_X9_62_c2pnb163v3		"c2pnb163v3"
        +#define NID_X9_62_c2pnb163v3		686
        +#define OBJ_X9_62_c2pnb163v3		OBJ_X9_62_c_TwoCurve,3L
        +
        +#define SN_X9_62_c2pnb176v1		"c2pnb176v1"
        +#define NID_X9_62_c2pnb176v1		687
        +#define OBJ_X9_62_c2pnb176v1		OBJ_X9_62_c_TwoCurve,4L
        +
        +#define SN_X9_62_c2tnb191v1		"c2tnb191v1"
        +#define NID_X9_62_c2tnb191v1		688
        +#define OBJ_X9_62_c2tnb191v1		OBJ_X9_62_c_TwoCurve,5L
        +
        +#define SN_X9_62_c2tnb191v2		"c2tnb191v2"
        +#define NID_X9_62_c2tnb191v2		689
        +#define OBJ_X9_62_c2tnb191v2		OBJ_X9_62_c_TwoCurve,6L
        +
        +#define SN_X9_62_c2tnb191v3		"c2tnb191v3"
        +#define NID_X9_62_c2tnb191v3		690
        +#define OBJ_X9_62_c2tnb191v3		OBJ_X9_62_c_TwoCurve,7L
        +
        +#define SN_X9_62_c2onb191v4		"c2onb191v4"
        +#define NID_X9_62_c2onb191v4		691
        +#define OBJ_X9_62_c2onb191v4		OBJ_X9_62_c_TwoCurve,8L
        +
        +#define SN_X9_62_c2onb191v5		"c2onb191v5"
        +#define NID_X9_62_c2onb191v5		692
        +#define OBJ_X9_62_c2onb191v5		OBJ_X9_62_c_TwoCurve,9L
        +
        +#define SN_X9_62_c2pnb208w1		"c2pnb208w1"
        +#define NID_X9_62_c2pnb208w1		693
        +#define OBJ_X9_62_c2pnb208w1		OBJ_X9_62_c_TwoCurve,10L
        +
        +#define SN_X9_62_c2tnb239v1		"c2tnb239v1"
        +#define NID_X9_62_c2tnb239v1		694
        +#define OBJ_X9_62_c2tnb239v1		OBJ_X9_62_c_TwoCurve,11L
        +
        +#define SN_X9_62_c2tnb239v2		"c2tnb239v2"
        +#define NID_X9_62_c2tnb239v2		695
        +#define OBJ_X9_62_c2tnb239v2		OBJ_X9_62_c_TwoCurve,12L
        +
        +#define SN_X9_62_c2tnb239v3		"c2tnb239v3"
        +#define NID_X9_62_c2tnb239v3		696
        +#define OBJ_X9_62_c2tnb239v3		OBJ_X9_62_c_TwoCurve,13L
        +
        +#define SN_X9_62_c2onb239v4		"c2onb239v4"
        +#define NID_X9_62_c2onb239v4		697
        +#define OBJ_X9_62_c2onb239v4		OBJ_X9_62_c_TwoCurve,14L
        +
        +#define SN_X9_62_c2onb239v5		"c2onb239v5"
        +#define NID_X9_62_c2onb239v5		698
        +#define OBJ_X9_62_c2onb239v5		OBJ_X9_62_c_TwoCurve,15L
        +
        +#define SN_X9_62_c2pnb272w1		"c2pnb272w1"
        +#define NID_X9_62_c2pnb272w1		699
        +#define OBJ_X9_62_c2pnb272w1		OBJ_X9_62_c_TwoCurve,16L
        +
        +#define SN_X9_62_c2pnb304w1		"c2pnb304w1"
        +#define NID_X9_62_c2pnb304w1		700
        +#define OBJ_X9_62_c2pnb304w1		OBJ_X9_62_c_TwoCurve,17L
        +
        +#define SN_X9_62_c2tnb359v1		"c2tnb359v1"
        +#define NID_X9_62_c2tnb359v1		701
        +#define OBJ_X9_62_c2tnb359v1		OBJ_X9_62_c_TwoCurve,18L
        +
        +#define SN_X9_62_c2pnb368w1		"c2pnb368w1"
        +#define NID_X9_62_c2pnb368w1		702
        +#define OBJ_X9_62_c2pnb368w1		OBJ_X9_62_c_TwoCurve,19L
        +
        +#define SN_X9_62_c2tnb431r1		"c2tnb431r1"
        +#define NID_X9_62_c2tnb431r1		703
        +#define OBJ_X9_62_c2tnb431r1		OBJ_X9_62_c_TwoCurve,20L
        +
        +#define OBJ_X9_62_primeCurve		OBJ_X9_62_ellipticCurve,1L
        +
        +#define SN_X9_62_prime192v1		"prime192v1"
        +#define NID_X9_62_prime192v1		409
        +#define OBJ_X9_62_prime192v1		OBJ_X9_62_primeCurve,1L
        +
        +#define SN_X9_62_prime192v2		"prime192v2"
        +#define NID_X9_62_prime192v2		410
        +#define OBJ_X9_62_prime192v2		OBJ_X9_62_primeCurve,2L
        +
        +#define SN_X9_62_prime192v3		"prime192v3"
        +#define NID_X9_62_prime192v3		411
        +#define OBJ_X9_62_prime192v3		OBJ_X9_62_primeCurve,3L
        +
        +#define SN_X9_62_prime239v1		"prime239v1"
        +#define NID_X9_62_prime239v1		412
        +#define OBJ_X9_62_prime239v1		OBJ_X9_62_primeCurve,4L
        +
        +#define SN_X9_62_prime239v2		"prime239v2"
        +#define NID_X9_62_prime239v2		413
        +#define OBJ_X9_62_prime239v2		OBJ_X9_62_primeCurve,5L
        +
        +#define SN_X9_62_prime239v3		"prime239v3"
        +#define NID_X9_62_prime239v3		414
        +#define OBJ_X9_62_prime239v3		OBJ_X9_62_primeCurve,6L
        +
        +#define SN_X9_62_prime256v1		"prime256v1"
        +#define NID_X9_62_prime256v1		415
        +#define OBJ_X9_62_prime256v1		OBJ_X9_62_primeCurve,7L
        +
        +#define OBJ_X9_62_id_ecSigType		OBJ_ansi_X9_62,4L
        +
        +#define SN_ecdsa_with_SHA1		"ecdsa-with-SHA1"
        +#define NID_ecdsa_with_SHA1		416
        +#define OBJ_ecdsa_with_SHA1		OBJ_X9_62_id_ecSigType,1L
        +
        +#define SN_ecdsa_with_Recommended		"ecdsa-with-Recommended"
        +#define NID_ecdsa_with_Recommended		791
        +#define OBJ_ecdsa_with_Recommended		OBJ_X9_62_id_ecSigType,2L
        +
        +#define SN_ecdsa_with_Specified		"ecdsa-with-Specified"
        +#define NID_ecdsa_with_Specified		792
        +#define OBJ_ecdsa_with_Specified		OBJ_X9_62_id_ecSigType,3L
        +
        +#define SN_ecdsa_with_SHA224		"ecdsa-with-SHA224"
        +#define NID_ecdsa_with_SHA224		793
        +#define OBJ_ecdsa_with_SHA224		OBJ_ecdsa_with_Specified,1L
        +
        +#define SN_ecdsa_with_SHA256		"ecdsa-with-SHA256"
        +#define NID_ecdsa_with_SHA256		794
        +#define OBJ_ecdsa_with_SHA256		OBJ_ecdsa_with_Specified,2L
        +
        +#define SN_ecdsa_with_SHA384		"ecdsa-with-SHA384"
        +#define NID_ecdsa_with_SHA384		795
        +#define OBJ_ecdsa_with_SHA384		OBJ_ecdsa_with_Specified,3L
        +
        +#define SN_ecdsa_with_SHA512		"ecdsa-with-SHA512"
        +#define NID_ecdsa_with_SHA512		796
        +#define OBJ_ecdsa_with_SHA512		OBJ_ecdsa_with_Specified,4L
        +
        +#define OBJ_secg_ellipticCurve		OBJ_certicom_arc,0L
        +
        +#define SN_secp112r1		"secp112r1"
        +#define NID_secp112r1		704
        +#define OBJ_secp112r1		OBJ_secg_ellipticCurve,6L
        +
        +#define SN_secp112r2		"secp112r2"
        +#define NID_secp112r2		705
        +#define OBJ_secp112r2		OBJ_secg_ellipticCurve,7L
        +
        +#define SN_secp128r1		"secp128r1"
        +#define NID_secp128r1		706
        +#define OBJ_secp128r1		OBJ_secg_ellipticCurve,28L
        +
        +#define SN_secp128r2		"secp128r2"
        +#define NID_secp128r2		707
        +#define OBJ_secp128r2		OBJ_secg_ellipticCurve,29L
        +
        +#define SN_secp160k1		"secp160k1"
        +#define NID_secp160k1		708
        +#define OBJ_secp160k1		OBJ_secg_ellipticCurve,9L
        +
        +#define SN_secp160r1		"secp160r1"
        +#define NID_secp160r1		709
        +#define OBJ_secp160r1		OBJ_secg_ellipticCurve,8L
        +
        +#define SN_secp160r2		"secp160r2"
        +#define NID_secp160r2		710
        +#define OBJ_secp160r2		OBJ_secg_ellipticCurve,30L
        +
        +#define SN_secp192k1		"secp192k1"
        +#define NID_secp192k1		711
        +#define OBJ_secp192k1		OBJ_secg_ellipticCurve,31L
        +
        +#define SN_secp224k1		"secp224k1"
        +#define NID_secp224k1		712
        +#define OBJ_secp224k1		OBJ_secg_ellipticCurve,32L
        +
        +#define SN_secp224r1		"secp224r1"
        +#define NID_secp224r1		713
        +#define OBJ_secp224r1		OBJ_secg_ellipticCurve,33L
        +
        +#define SN_secp256k1		"secp256k1"
        +#define NID_secp256k1		714
        +#define OBJ_secp256k1		OBJ_secg_ellipticCurve,10L
        +
        +#define SN_secp384r1		"secp384r1"
        +#define NID_secp384r1		715
        +#define OBJ_secp384r1		OBJ_secg_ellipticCurve,34L
        +
        +#define SN_secp521r1		"secp521r1"
        +#define NID_secp521r1		716
        +#define OBJ_secp521r1		OBJ_secg_ellipticCurve,35L
        +
        +#define SN_sect113r1		"sect113r1"
        +#define NID_sect113r1		717
        +#define OBJ_sect113r1		OBJ_secg_ellipticCurve,4L
        +
        +#define SN_sect113r2		"sect113r2"
        +#define NID_sect113r2		718
        +#define OBJ_sect113r2		OBJ_secg_ellipticCurve,5L
        +
        +#define SN_sect131r1		"sect131r1"
        +#define NID_sect131r1		719
        +#define OBJ_sect131r1		OBJ_secg_ellipticCurve,22L
        +
        +#define SN_sect131r2		"sect131r2"
        +#define NID_sect131r2		720
        +#define OBJ_sect131r2		OBJ_secg_ellipticCurve,23L
        +
        +#define SN_sect163k1		"sect163k1"
        +#define NID_sect163k1		721
        +#define OBJ_sect163k1		OBJ_secg_ellipticCurve,1L
        +
        +#define SN_sect163r1		"sect163r1"
        +#define NID_sect163r1		722
        +#define OBJ_sect163r1		OBJ_secg_ellipticCurve,2L
        +
        +#define SN_sect163r2		"sect163r2"
        +#define NID_sect163r2		723
        +#define OBJ_sect163r2		OBJ_secg_ellipticCurve,15L
        +
        +#define SN_sect193r1		"sect193r1"
        +#define NID_sect193r1		724
        +#define OBJ_sect193r1		OBJ_secg_ellipticCurve,24L
        +
        +#define SN_sect193r2		"sect193r2"
        +#define NID_sect193r2		725
        +#define OBJ_sect193r2		OBJ_secg_ellipticCurve,25L
        +
        +#define SN_sect233k1		"sect233k1"
        +#define NID_sect233k1		726
        +#define OBJ_sect233k1		OBJ_secg_ellipticCurve,26L
        +
        +#define SN_sect233r1		"sect233r1"
        +#define NID_sect233r1		727
        +#define OBJ_sect233r1		OBJ_secg_ellipticCurve,27L
        +
        +#define SN_sect239k1		"sect239k1"
        +#define NID_sect239k1		728
        +#define OBJ_sect239k1		OBJ_secg_ellipticCurve,3L
        +
        +#define SN_sect283k1		"sect283k1"
        +#define NID_sect283k1		729
        +#define OBJ_sect283k1		OBJ_secg_ellipticCurve,16L
        +
        +#define SN_sect283r1		"sect283r1"
        +#define NID_sect283r1		730
        +#define OBJ_sect283r1		OBJ_secg_ellipticCurve,17L
        +
        +#define SN_sect409k1		"sect409k1"
        +#define NID_sect409k1		731
        +#define OBJ_sect409k1		OBJ_secg_ellipticCurve,36L
        +
        +#define SN_sect409r1		"sect409r1"
        +#define NID_sect409r1		732
        +#define OBJ_sect409r1		OBJ_secg_ellipticCurve,37L
        +
        +#define SN_sect571k1		"sect571k1"
        +#define NID_sect571k1		733
        +#define OBJ_sect571k1		OBJ_secg_ellipticCurve,38L
        +
        +#define SN_sect571r1		"sect571r1"
        +#define NID_sect571r1		734
        +#define OBJ_sect571r1		OBJ_secg_ellipticCurve,39L
        +
        +#define OBJ_wap_wsg_idm_ecid		OBJ_wap_wsg,4L
        +
        +#define SN_wap_wsg_idm_ecid_wtls1		"wap-wsg-idm-ecid-wtls1"
        +#define NID_wap_wsg_idm_ecid_wtls1		735
        +#define OBJ_wap_wsg_idm_ecid_wtls1		OBJ_wap_wsg_idm_ecid,1L
        +
        +#define SN_wap_wsg_idm_ecid_wtls3		"wap-wsg-idm-ecid-wtls3"
        +#define NID_wap_wsg_idm_ecid_wtls3		736
        +#define OBJ_wap_wsg_idm_ecid_wtls3		OBJ_wap_wsg_idm_ecid,3L
        +
        +#define SN_wap_wsg_idm_ecid_wtls4		"wap-wsg-idm-ecid-wtls4"
        +#define NID_wap_wsg_idm_ecid_wtls4		737
        +#define OBJ_wap_wsg_idm_ecid_wtls4		OBJ_wap_wsg_idm_ecid,4L
        +
        +#define SN_wap_wsg_idm_ecid_wtls5		"wap-wsg-idm-ecid-wtls5"
        +#define NID_wap_wsg_idm_ecid_wtls5		738
        +#define OBJ_wap_wsg_idm_ecid_wtls5		OBJ_wap_wsg_idm_ecid,5L
        +
        +#define SN_wap_wsg_idm_ecid_wtls6		"wap-wsg-idm-ecid-wtls6"
        +#define NID_wap_wsg_idm_ecid_wtls6		739
        +#define OBJ_wap_wsg_idm_ecid_wtls6		OBJ_wap_wsg_idm_ecid,6L
        +
        +#define SN_wap_wsg_idm_ecid_wtls7		"wap-wsg-idm-ecid-wtls7"
        +#define NID_wap_wsg_idm_ecid_wtls7		740
        +#define OBJ_wap_wsg_idm_ecid_wtls7		OBJ_wap_wsg_idm_ecid,7L
        +
        +#define SN_wap_wsg_idm_ecid_wtls8		"wap-wsg-idm-ecid-wtls8"
        +#define NID_wap_wsg_idm_ecid_wtls8		741
        +#define OBJ_wap_wsg_idm_ecid_wtls8		OBJ_wap_wsg_idm_ecid,8L
        +
        +#define SN_wap_wsg_idm_ecid_wtls9		"wap-wsg-idm-ecid-wtls9"
        +#define NID_wap_wsg_idm_ecid_wtls9		742
        +#define OBJ_wap_wsg_idm_ecid_wtls9		OBJ_wap_wsg_idm_ecid,9L
        +
        +#define SN_wap_wsg_idm_ecid_wtls10		"wap-wsg-idm-ecid-wtls10"
        +#define NID_wap_wsg_idm_ecid_wtls10		743
        +#define OBJ_wap_wsg_idm_ecid_wtls10		OBJ_wap_wsg_idm_ecid,10L
        +
        +#define SN_wap_wsg_idm_ecid_wtls11		"wap-wsg-idm-ecid-wtls11"
        +#define NID_wap_wsg_idm_ecid_wtls11		744
        +#define OBJ_wap_wsg_idm_ecid_wtls11		OBJ_wap_wsg_idm_ecid,11L
        +
        +#define SN_wap_wsg_idm_ecid_wtls12		"wap-wsg-idm-ecid-wtls12"
        +#define NID_wap_wsg_idm_ecid_wtls12		745
        +#define OBJ_wap_wsg_idm_ecid_wtls12		OBJ_wap_wsg_idm_ecid,12L
        +
        +#define SN_cast5_cbc		"CAST5-CBC"
        +#define LN_cast5_cbc		"cast5-cbc"
        +#define NID_cast5_cbc		108
        +#define OBJ_cast5_cbc		OBJ_ISO_US,113533L,7L,66L,10L
        +
        +#define SN_cast5_ecb		"CAST5-ECB"
        +#define LN_cast5_ecb		"cast5-ecb"
        +#define NID_cast5_ecb		109
        +
        +#define SN_cast5_cfb64		"CAST5-CFB"
        +#define LN_cast5_cfb64		"cast5-cfb"
        +#define NID_cast5_cfb64		110
        +
        +#define SN_cast5_ofb64		"CAST5-OFB"
        +#define LN_cast5_ofb64		"cast5-ofb"
        +#define NID_cast5_ofb64		111
        +
        +#define LN_pbeWithMD5AndCast5_CBC		"pbeWithMD5AndCast5CBC"
        +#define NID_pbeWithMD5AndCast5_CBC		112
        +#define OBJ_pbeWithMD5AndCast5_CBC		OBJ_ISO_US,113533L,7L,66L,12L
        +
        +#define SN_id_PasswordBasedMAC		"id-PasswordBasedMAC"
        +#define LN_id_PasswordBasedMAC		"password based MAC"
        +#define NID_id_PasswordBasedMAC		782
        +#define OBJ_id_PasswordBasedMAC		OBJ_ISO_US,113533L,7L,66L,13L
        +
        +#define SN_id_DHBasedMac		"id-DHBasedMac"
        +#define LN_id_DHBasedMac		"Diffie-Hellman based MAC"
        +#define NID_id_DHBasedMac		783
        +#define OBJ_id_DHBasedMac		OBJ_ISO_US,113533L,7L,66L,30L
        +
        +#define SN_rsadsi		"rsadsi"
        +#define LN_rsadsi		"RSA Data Security, Inc."
        +#define NID_rsadsi		1
        +#define OBJ_rsadsi		OBJ_ISO_US,113549L
        +
        +#define SN_pkcs		"pkcs"
        +#define LN_pkcs		"RSA Data Security, Inc. PKCS"
        +#define NID_pkcs		2
        +#define OBJ_pkcs		OBJ_rsadsi,1L
        +
        +#define SN_pkcs1		"pkcs1"
        +#define NID_pkcs1		186
        +#define OBJ_pkcs1		OBJ_pkcs,1L
        +
        +#define LN_rsaEncryption		"rsaEncryption"
        +#define NID_rsaEncryption		6
        +#define OBJ_rsaEncryption		OBJ_pkcs1,1L
        +
        +#define SN_md2WithRSAEncryption		"RSA-MD2"
        +#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
        +#define NID_md2WithRSAEncryption		7
        +#define OBJ_md2WithRSAEncryption		OBJ_pkcs1,2L
        +
        +#define SN_md4WithRSAEncryption		"RSA-MD4"
        +#define LN_md4WithRSAEncryption		"md4WithRSAEncryption"
        +#define NID_md4WithRSAEncryption		396
        +#define OBJ_md4WithRSAEncryption		OBJ_pkcs1,3L
        +
        +#define SN_md5WithRSAEncryption		"RSA-MD5"
        +#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
        +#define NID_md5WithRSAEncryption		8
        +#define OBJ_md5WithRSAEncryption		OBJ_pkcs1,4L
        +
        +#define SN_sha1WithRSAEncryption		"RSA-SHA1"
        +#define LN_sha1WithRSAEncryption		"sha1WithRSAEncryption"
        +#define NID_sha1WithRSAEncryption		65
        +#define OBJ_sha1WithRSAEncryption		OBJ_pkcs1,5L
        +
        +#define SN_rsaesOaep		"RSAES-OAEP"
        +#define LN_rsaesOaep		"rsaesOaep"
        +#define NID_rsaesOaep		919
        +#define OBJ_rsaesOaep		OBJ_pkcs1,7L
        +
        +#define SN_mgf1		"MGF1"
        +#define LN_mgf1		"mgf1"
        +#define NID_mgf1		911
        +#define OBJ_mgf1		OBJ_pkcs1,8L
        +
        +#define SN_rsassaPss		"RSASSA-PSS"
        +#define LN_rsassaPss		"rsassaPss"
        +#define NID_rsassaPss		912
        +#define OBJ_rsassaPss		OBJ_pkcs1,10L
        +
        +#define SN_sha256WithRSAEncryption		"RSA-SHA256"
        +#define LN_sha256WithRSAEncryption		"sha256WithRSAEncryption"
        +#define NID_sha256WithRSAEncryption		668
        +#define OBJ_sha256WithRSAEncryption		OBJ_pkcs1,11L
        +
        +#define SN_sha384WithRSAEncryption		"RSA-SHA384"
        +#define LN_sha384WithRSAEncryption		"sha384WithRSAEncryption"
        +#define NID_sha384WithRSAEncryption		669
        +#define OBJ_sha384WithRSAEncryption		OBJ_pkcs1,12L
        +
        +#define SN_sha512WithRSAEncryption		"RSA-SHA512"
        +#define LN_sha512WithRSAEncryption		"sha512WithRSAEncryption"
        +#define NID_sha512WithRSAEncryption		670
        +#define OBJ_sha512WithRSAEncryption		OBJ_pkcs1,13L
        +
        +#define SN_sha224WithRSAEncryption		"RSA-SHA224"
        +#define LN_sha224WithRSAEncryption		"sha224WithRSAEncryption"
        +#define NID_sha224WithRSAEncryption		671
        +#define OBJ_sha224WithRSAEncryption		OBJ_pkcs1,14L
        +
        +#define SN_pkcs3		"pkcs3"
        +#define NID_pkcs3		27
        +#define OBJ_pkcs3		OBJ_pkcs,3L
        +
        +#define LN_dhKeyAgreement		"dhKeyAgreement"
        +#define NID_dhKeyAgreement		28
        +#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
        +
        +#define SN_pkcs5		"pkcs5"
        +#define NID_pkcs5		187
        +#define OBJ_pkcs5		OBJ_pkcs,5L
        +
        +#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
        +#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
        +#define NID_pbeWithMD2AndDES_CBC		9
        +#define OBJ_pbeWithMD2AndDES_CBC		OBJ_pkcs5,1L
        +
        +#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
        +#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
        +#define NID_pbeWithMD5AndDES_CBC		10
        +#define OBJ_pbeWithMD5AndDES_CBC		OBJ_pkcs5,3L
        +
        +#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
        +#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
        +#define NID_pbeWithMD2AndRC2_CBC		168
        +#define OBJ_pbeWithMD2AndRC2_CBC		OBJ_pkcs5,4L
        +
        +#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
        +#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
        +#define NID_pbeWithMD5AndRC2_CBC		169
        +#define OBJ_pbeWithMD5AndRC2_CBC		OBJ_pkcs5,6L
        +
        +#define SN_pbeWithSHA1AndDES_CBC		"PBE-SHA1-DES"
        +#define LN_pbeWithSHA1AndDES_CBC		"pbeWithSHA1AndDES-CBC"
        +#define NID_pbeWithSHA1AndDES_CBC		170
        +#define OBJ_pbeWithSHA1AndDES_CBC		OBJ_pkcs5,10L
        +
        +#define SN_pbeWithSHA1AndRC2_CBC		"PBE-SHA1-RC2-64"
        +#define LN_pbeWithSHA1AndRC2_CBC		"pbeWithSHA1AndRC2-CBC"
        +#define NID_pbeWithSHA1AndRC2_CBC		68
        +#define OBJ_pbeWithSHA1AndRC2_CBC		OBJ_pkcs5,11L
        +
        +#define LN_id_pbkdf2		"PBKDF2"
        +#define NID_id_pbkdf2		69
        +#define OBJ_id_pbkdf2		OBJ_pkcs5,12L
        +
        +#define LN_pbes2		"PBES2"
        +#define NID_pbes2		161
        +#define OBJ_pbes2		OBJ_pkcs5,13L
        +
        +#define LN_pbmac1		"PBMAC1"
        +#define NID_pbmac1		162
        +#define OBJ_pbmac1		OBJ_pkcs5,14L
        +
        +#define SN_pkcs7		"pkcs7"
        +#define NID_pkcs7		20
        +#define OBJ_pkcs7		OBJ_pkcs,7L
        +
        +#define LN_pkcs7_data		"pkcs7-data"
        +#define NID_pkcs7_data		21
        +#define OBJ_pkcs7_data		OBJ_pkcs7,1L
        +
        +#define LN_pkcs7_signed		"pkcs7-signedData"
        +#define NID_pkcs7_signed		22
        +#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
        +
        +#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
        +#define NID_pkcs7_enveloped		23
        +#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
        +
        +#define LN_pkcs7_signedAndEnveloped		"pkcs7-signedAndEnvelopedData"
        +#define NID_pkcs7_signedAndEnveloped		24
        +#define OBJ_pkcs7_signedAndEnveloped		OBJ_pkcs7,4L
        +
        +#define LN_pkcs7_digest		"pkcs7-digestData"
        +#define NID_pkcs7_digest		25
        +#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
        +
        +#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
        +#define NID_pkcs7_encrypted		26
        +#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
        +
        +#define SN_pkcs9		"pkcs9"
        +#define NID_pkcs9		47
        +#define OBJ_pkcs9		OBJ_pkcs,9L
        +
        +#define LN_pkcs9_emailAddress		"emailAddress"
        +#define NID_pkcs9_emailAddress		48
        +#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
        +
        +#define LN_pkcs9_unstructuredName		"unstructuredName"
        +#define NID_pkcs9_unstructuredName		49
        +#define OBJ_pkcs9_unstructuredName		OBJ_pkcs9,2L
        +
        +#define LN_pkcs9_contentType		"contentType"
        +#define NID_pkcs9_contentType		50
        +#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
        +
        +#define LN_pkcs9_messageDigest		"messageDigest"
        +#define NID_pkcs9_messageDigest		51
        +#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
        +
        +#define LN_pkcs9_signingTime		"signingTime"
        +#define NID_pkcs9_signingTime		52
        +#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
        +
        +#define LN_pkcs9_countersignature		"countersignature"
        +#define NID_pkcs9_countersignature		53
        +#define OBJ_pkcs9_countersignature		OBJ_pkcs9,6L
        +
        +#define LN_pkcs9_challengePassword		"challengePassword"
        +#define NID_pkcs9_challengePassword		54
        +#define OBJ_pkcs9_challengePassword		OBJ_pkcs9,7L
        +
        +#define LN_pkcs9_unstructuredAddress		"unstructuredAddress"
        +#define NID_pkcs9_unstructuredAddress		55
        +#define OBJ_pkcs9_unstructuredAddress		OBJ_pkcs9,8L
        +
        +#define LN_pkcs9_extCertAttributes		"extendedCertificateAttributes"
        +#define NID_pkcs9_extCertAttributes		56
        +#define OBJ_pkcs9_extCertAttributes		OBJ_pkcs9,9L
        +
        +#define SN_ext_req		"extReq"
        +#define LN_ext_req		"Extension Request"
        +#define NID_ext_req		172
        +#define OBJ_ext_req		OBJ_pkcs9,14L
        +
        +#define SN_SMIMECapabilities		"SMIME-CAPS"
        +#define LN_SMIMECapabilities		"S/MIME Capabilities"
        +#define NID_SMIMECapabilities		167
        +#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
        +
        +#define SN_SMIME		"SMIME"
        +#define LN_SMIME		"S/MIME"
        +#define NID_SMIME		188
        +#define OBJ_SMIME		OBJ_pkcs9,16L
        +
        +#define SN_id_smime_mod		"id-smime-mod"
        +#define NID_id_smime_mod		189
        +#define OBJ_id_smime_mod		OBJ_SMIME,0L
        +
        +#define SN_id_smime_ct		"id-smime-ct"
        +#define NID_id_smime_ct		190
        +#define OBJ_id_smime_ct		OBJ_SMIME,1L
        +
        +#define SN_id_smime_aa		"id-smime-aa"
        +#define NID_id_smime_aa		191
        +#define OBJ_id_smime_aa		OBJ_SMIME,2L
        +
        +#define SN_id_smime_alg		"id-smime-alg"
        +#define NID_id_smime_alg		192
        +#define OBJ_id_smime_alg		OBJ_SMIME,3L
        +
        +#define SN_id_smime_cd		"id-smime-cd"
        +#define NID_id_smime_cd		193
        +#define OBJ_id_smime_cd		OBJ_SMIME,4L
        +
        +#define SN_id_smime_spq		"id-smime-spq"
        +#define NID_id_smime_spq		194
        +#define OBJ_id_smime_spq		OBJ_SMIME,5L
        +
        +#define SN_id_smime_cti		"id-smime-cti"
        +#define NID_id_smime_cti		195
        +#define OBJ_id_smime_cti		OBJ_SMIME,6L
        +
        +#define SN_id_smime_mod_cms		"id-smime-mod-cms"
        +#define NID_id_smime_mod_cms		196
        +#define OBJ_id_smime_mod_cms		OBJ_id_smime_mod,1L
        +
        +#define SN_id_smime_mod_ess		"id-smime-mod-ess"
        +#define NID_id_smime_mod_ess		197
        +#define OBJ_id_smime_mod_ess		OBJ_id_smime_mod,2L
        +
        +#define SN_id_smime_mod_oid		"id-smime-mod-oid"
        +#define NID_id_smime_mod_oid		198
        +#define OBJ_id_smime_mod_oid		OBJ_id_smime_mod,3L
        +
        +#define SN_id_smime_mod_msg_v3		"id-smime-mod-msg-v3"
        +#define NID_id_smime_mod_msg_v3		199
        +#define OBJ_id_smime_mod_msg_v3		OBJ_id_smime_mod,4L
        +
        +#define SN_id_smime_mod_ets_eSignature_88		"id-smime-mod-ets-eSignature-88"
        +#define NID_id_smime_mod_ets_eSignature_88		200
        +#define OBJ_id_smime_mod_ets_eSignature_88		OBJ_id_smime_mod,5L
        +
        +#define SN_id_smime_mod_ets_eSignature_97		"id-smime-mod-ets-eSignature-97"
        +#define NID_id_smime_mod_ets_eSignature_97		201
        +#define OBJ_id_smime_mod_ets_eSignature_97		OBJ_id_smime_mod,6L
        +
        +#define SN_id_smime_mod_ets_eSigPolicy_88		"id-smime-mod-ets-eSigPolicy-88"
        +#define NID_id_smime_mod_ets_eSigPolicy_88		202
        +#define OBJ_id_smime_mod_ets_eSigPolicy_88		OBJ_id_smime_mod,7L
        +
        +#define SN_id_smime_mod_ets_eSigPolicy_97		"id-smime-mod-ets-eSigPolicy-97"
        +#define NID_id_smime_mod_ets_eSigPolicy_97		203
        +#define OBJ_id_smime_mod_ets_eSigPolicy_97		OBJ_id_smime_mod,8L
        +
        +#define SN_id_smime_ct_receipt		"id-smime-ct-receipt"
        +#define NID_id_smime_ct_receipt		204
        +#define OBJ_id_smime_ct_receipt		OBJ_id_smime_ct,1L
        +
        +#define SN_id_smime_ct_authData		"id-smime-ct-authData"
        +#define NID_id_smime_ct_authData		205
        +#define OBJ_id_smime_ct_authData		OBJ_id_smime_ct,2L
        +
        +#define SN_id_smime_ct_publishCert		"id-smime-ct-publishCert"
        +#define NID_id_smime_ct_publishCert		206
        +#define OBJ_id_smime_ct_publishCert		OBJ_id_smime_ct,3L
        +
        +#define SN_id_smime_ct_TSTInfo		"id-smime-ct-TSTInfo"
        +#define NID_id_smime_ct_TSTInfo		207
        +#define OBJ_id_smime_ct_TSTInfo		OBJ_id_smime_ct,4L
        +
        +#define SN_id_smime_ct_TDTInfo		"id-smime-ct-TDTInfo"
        +#define NID_id_smime_ct_TDTInfo		208
        +#define OBJ_id_smime_ct_TDTInfo		OBJ_id_smime_ct,5L
        +
        +#define SN_id_smime_ct_contentInfo		"id-smime-ct-contentInfo"
        +#define NID_id_smime_ct_contentInfo		209
        +#define OBJ_id_smime_ct_contentInfo		OBJ_id_smime_ct,6L
        +
        +#define SN_id_smime_ct_DVCSRequestData		"id-smime-ct-DVCSRequestData"
        +#define NID_id_smime_ct_DVCSRequestData		210
        +#define OBJ_id_smime_ct_DVCSRequestData		OBJ_id_smime_ct,7L
        +
        +#define SN_id_smime_ct_DVCSResponseData		"id-smime-ct-DVCSResponseData"
        +#define NID_id_smime_ct_DVCSResponseData		211
        +#define OBJ_id_smime_ct_DVCSResponseData		OBJ_id_smime_ct,8L
        +
        +#define SN_id_smime_ct_compressedData		"id-smime-ct-compressedData"
        +#define NID_id_smime_ct_compressedData		786
        +#define OBJ_id_smime_ct_compressedData		OBJ_id_smime_ct,9L
        +
        +#define SN_id_ct_asciiTextWithCRLF		"id-ct-asciiTextWithCRLF"
        +#define NID_id_ct_asciiTextWithCRLF		787
        +#define OBJ_id_ct_asciiTextWithCRLF		OBJ_id_smime_ct,27L
        +
        +#define SN_id_smime_aa_receiptRequest		"id-smime-aa-receiptRequest"
        +#define NID_id_smime_aa_receiptRequest		212
        +#define OBJ_id_smime_aa_receiptRequest		OBJ_id_smime_aa,1L
        +
        +#define SN_id_smime_aa_securityLabel		"id-smime-aa-securityLabel"
        +#define NID_id_smime_aa_securityLabel		213
        +#define OBJ_id_smime_aa_securityLabel		OBJ_id_smime_aa,2L
        +
        +#define SN_id_smime_aa_mlExpandHistory		"id-smime-aa-mlExpandHistory"
        +#define NID_id_smime_aa_mlExpandHistory		214
        +#define OBJ_id_smime_aa_mlExpandHistory		OBJ_id_smime_aa,3L
        +
        +#define SN_id_smime_aa_contentHint		"id-smime-aa-contentHint"
        +#define NID_id_smime_aa_contentHint		215
        +#define OBJ_id_smime_aa_contentHint		OBJ_id_smime_aa,4L
        +
        +#define SN_id_smime_aa_msgSigDigest		"id-smime-aa-msgSigDigest"
        +#define NID_id_smime_aa_msgSigDigest		216
        +#define OBJ_id_smime_aa_msgSigDigest		OBJ_id_smime_aa,5L
        +
        +#define SN_id_smime_aa_encapContentType		"id-smime-aa-encapContentType"
        +#define NID_id_smime_aa_encapContentType		217
        +#define OBJ_id_smime_aa_encapContentType		OBJ_id_smime_aa,6L
        +
        +#define SN_id_smime_aa_contentIdentifier		"id-smime-aa-contentIdentifier"
        +#define NID_id_smime_aa_contentIdentifier		218
        +#define OBJ_id_smime_aa_contentIdentifier		OBJ_id_smime_aa,7L
        +
        +#define SN_id_smime_aa_macValue		"id-smime-aa-macValue"
        +#define NID_id_smime_aa_macValue		219
        +#define OBJ_id_smime_aa_macValue		OBJ_id_smime_aa,8L
        +
        +#define SN_id_smime_aa_equivalentLabels		"id-smime-aa-equivalentLabels"
        +#define NID_id_smime_aa_equivalentLabels		220
        +#define OBJ_id_smime_aa_equivalentLabels		OBJ_id_smime_aa,9L
        +
        +#define SN_id_smime_aa_contentReference		"id-smime-aa-contentReference"
        +#define NID_id_smime_aa_contentReference		221
        +#define OBJ_id_smime_aa_contentReference		OBJ_id_smime_aa,10L
        +
        +#define SN_id_smime_aa_encrypKeyPref		"id-smime-aa-encrypKeyPref"
        +#define NID_id_smime_aa_encrypKeyPref		222
        +#define OBJ_id_smime_aa_encrypKeyPref		OBJ_id_smime_aa,11L
        +
        +#define SN_id_smime_aa_signingCertificate		"id-smime-aa-signingCertificate"
        +#define NID_id_smime_aa_signingCertificate		223
        +#define OBJ_id_smime_aa_signingCertificate		OBJ_id_smime_aa,12L
        +
        +#define SN_id_smime_aa_smimeEncryptCerts		"id-smime-aa-smimeEncryptCerts"
        +#define NID_id_smime_aa_smimeEncryptCerts		224
        +#define OBJ_id_smime_aa_smimeEncryptCerts		OBJ_id_smime_aa,13L
        +
        +#define SN_id_smime_aa_timeStampToken		"id-smime-aa-timeStampToken"
        +#define NID_id_smime_aa_timeStampToken		225
        +#define OBJ_id_smime_aa_timeStampToken		OBJ_id_smime_aa,14L
        +
        +#define SN_id_smime_aa_ets_sigPolicyId		"id-smime-aa-ets-sigPolicyId"
        +#define NID_id_smime_aa_ets_sigPolicyId		226
        +#define OBJ_id_smime_aa_ets_sigPolicyId		OBJ_id_smime_aa,15L
        +
        +#define SN_id_smime_aa_ets_commitmentType		"id-smime-aa-ets-commitmentType"
        +#define NID_id_smime_aa_ets_commitmentType		227
        +#define OBJ_id_smime_aa_ets_commitmentType		OBJ_id_smime_aa,16L
        +
        +#define SN_id_smime_aa_ets_signerLocation		"id-smime-aa-ets-signerLocation"
        +#define NID_id_smime_aa_ets_signerLocation		228
        +#define OBJ_id_smime_aa_ets_signerLocation		OBJ_id_smime_aa,17L
        +
        +#define SN_id_smime_aa_ets_signerAttr		"id-smime-aa-ets-signerAttr"
        +#define NID_id_smime_aa_ets_signerAttr		229
        +#define OBJ_id_smime_aa_ets_signerAttr		OBJ_id_smime_aa,18L
        +
        +#define SN_id_smime_aa_ets_otherSigCert		"id-smime-aa-ets-otherSigCert"
        +#define NID_id_smime_aa_ets_otherSigCert		230
        +#define OBJ_id_smime_aa_ets_otherSigCert		OBJ_id_smime_aa,19L
        +
        +#define SN_id_smime_aa_ets_contentTimestamp		"id-smime-aa-ets-contentTimestamp"
        +#define NID_id_smime_aa_ets_contentTimestamp		231
        +#define OBJ_id_smime_aa_ets_contentTimestamp		OBJ_id_smime_aa,20L
        +
        +#define SN_id_smime_aa_ets_CertificateRefs		"id-smime-aa-ets-CertificateRefs"
        +#define NID_id_smime_aa_ets_CertificateRefs		232
        +#define OBJ_id_smime_aa_ets_CertificateRefs		OBJ_id_smime_aa,21L
        +
        +#define SN_id_smime_aa_ets_RevocationRefs		"id-smime-aa-ets-RevocationRefs"
        +#define NID_id_smime_aa_ets_RevocationRefs		233
        +#define OBJ_id_smime_aa_ets_RevocationRefs		OBJ_id_smime_aa,22L
        +
        +#define SN_id_smime_aa_ets_certValues		"id-smime-aa-ets-certValues"
        +#define NID_id_smime_aa_ets_certValues		234
        +#define OBJ_id_smime_aa_ets_certValues		OBJ_id_smime_aa,23L
        +
        +#define SN_id_smime_aa_ets_revocationValues		"id-smime-aa-ets-revocationValues"
        +#define NID_id_smime_aa_ets_revocationValues		235
        +#define OBJ_id_smime_aa_ets_revocationValues		OBJ_id_smime_aa,24L
        +
        +#define SN_id_smime_aa_ets_escTimeStamp		"id-smime-aa-ets-escTimeStamp"
        +#define NID_id_smime_aa_ets_escTimeStamp		236
        +#define OBJ_id_smime_aa_ets_escTimeStamp		OBJ_id_smime_aa,25L
        +
        +#define SN_id_smime_aa_ets_certCRLTimestamp		"id-smime-aa-ets-certCRLTimestamp"
        +#define NID_id_smime_aa_ets_certCRLTimestamp		237
        +#define OBJ_id_smime_aa_ets_certCRLTimestamp		OBJ_id_smime_aa,26L
        +
        +#define SN_id_smime_aa_ets_archiveTimeStamp		"id-smime-aa-ets-archiveTimeStamp"
        +#define NID_id_smime_aa_ets_archiveTimeStamp		238
        +#define OBJ_id_smime_aa_ets_archiveTimeStamp		OBJ_id_smime_aa,27L
        +
        +#define SN_id_smime_aa_signatureType		"id-smime-aa-signatureType"
        +#define NID_id_smime_aa_signatureType		239
        +#define OBJ_id_smime_aa_signatureType		OBJ_id_smime_aa,28L
        +
        +#define SN_id_smime_aa_dvcs_dvc		"id-smime-aa-dvcs-dvc"
        +#define NID_id_smime_aa_dvcs_dvc		240
        +#define OBJ_id_smime_aa_dvcs_dvc		OBJ_id_smime_aa,29L
        +
        +#define SN_id_smime_alg_ESDHwith3DES		"id-smime-alg-ESDHwith3DES"
        +#define NID_id_smime_alg_ESDHwith3DES		241
        +#define OBJ_id_smime_alg_ESDHwith3DES		OBJ_id_smime_alg,1L
        +
        +#define SN_id_smime_alg_ESDHwithRC2		"id-smime-alg-ESDHwithRC2"
        +#define NID_id_smime_alg_ESDHwithRC2		242
        +#define OBJ_id_smime_alg_ESDHwithRC2		OBJ_id_smime_alg,2L
        +
        +#define SN_id_smime_alg_3DESwrap		"id-smime-alg-3DESwrap"
        +#define NID_id_smime_alg_3DESwrap		243
        +#define OBJ_id_smime_alg_3DESwrap		OBJ_id_smime_alg,3L
        +
        +#define SN_id_smime_alg_RC2wrap		"id-smime-alg-RC2wrap"
        +#define NID_id_smime_alg_RC2wrap		244
        +#define OBJ_id_smime_alg_RC2wrap		OBJ_id_smime_alg,4L
        +
        +#define SN_id_smime_alg_ESDH		"id-smime-alg-ESDH"
        +#define NID_id_smime_alg_ESDH		245
        +#define OBJ_id_smime_alg_ESDH		OBJ_id_smime_alg,5L
        +
        +#define SN_id_smime_alg_CMS3DESwrap		"id-smime-alg-CMS3DESwrap"
        +#define NID_id_smime_alg_CMS3DESwrap		246
        +#define OBJ_id_smime_alg_CMS3DESwrap		OBJ_id_smime_alg,6L
        +
        +#define SN_id_smime_alg_CMSRC2wrap		"id-smime-alg-CMSRC2wrap"
        +#define NID_id_smime_alg_CMSRC2wrap		247
        +#define OBJ_id_smime_alg_CMSRC2wrap		OBJ_id_smime_alg,7L
        +
        +#define SN_id_alg_PWRI_KEK		"id-alg-PWRI-KEK"
        +#define NID_id_alg_PWRI_KEK		893
        +#define OBJ_id_alg_PWRI_KEK		OBJ_id_smime_alg,9L
        +
        +#define SN_id_smime_cd_ldap		"id-smime-cd-ldap"
        +#define NID_id_smime_cd_ldap		248
        +#define OBJ_id_smime_cd_ldap		OBJ_id_smime_cd,1L
        +
        +#define SN_id_smime_spq_ets_sqt_uri		"id-smime-spq-ets-sqt-uri"
        +#define NID_id_smime_spq_ets_sqt_uri		249
        +#define OBJ_id_smime_spq_ets_sqt_uri		OBJ_id_smime_spq,1L
        +
        +#define SN_id_smime_spq_ets_sqt_unotice		"id-smime-spq-ets-sqt-unotice"
        +#define NID_id_smime_spq_ets_sqt_unotice		250
        +#define OBJ_id_smime_spq_ets_sqt_unotice		OBJ_id_smime_spq,2L
        +
        +#define SN_id_smime_cti_ets_proofOfOrigin		"id-smime-cti-ets-proofOfOrigin"
        +#define NID_id_smime_cti_ets_proofOfOrigin		251
        +#define OBJ_id_smime_cti_ets_proofOfOrigin		OBJ_id_smime_cti,1L
        +
        +#define SN_id_smime_cti_ets_proofOfReceipt		"id-smime-cti-ets-proofOfReceipt"
        +#define NID_id_smime_cti_ets_proofOfReceipt		252
        +#define OBJ_id_smime_cti_ets_proofOfReceipt		OBJ_id_smime_cti,2L
        +
        +#define SN_id_smime_cti_ets_proofOfDelivery		"id-smime-cti-ets-proofOfDelivery"
        +#define NID_id_smime_cti_ets_proofOfDelivery		253
        +#define OBJ_id_smime_cti_ets_proofOfDelivery		OBJ_id_smime_cti,3L
        +
        +#define SN_id_smime_cti_ets_proofOfSender		"id-smime-cti-ets-proofOfSender"
        +#define NID_id_smime_cti_ets_proofOfSender		254
        +#define OBJ_id_smime_cti_ets_proofOfSender		OBJ_id_smime_cti,4L
        +
        +#define SN_id_smime_cti_ets_proofOfApproval		"id-smime-cti-ets-proofOfApproval"
        +#define NID_id_smime_cti_ets_proofOfApproval		255
        +#define OBJ_id_smime_cti_ets_proofOfApproval		OBJ_id_smime_cti,5L
        +
        +#define SN_id_smime_cti_ets_proofOfCreation		"id-smime-cti-ets-proofOfCreation"
        +#define NID_id_smime_cti_ets_proofOfCreation		256
        +#define OBJ_id_smime_cti_ets_proofOfCreation		OBJ_id_smime_cti,6L
        +
        +#define LN_friendlyName		"friendlyName"
        +#define NID_friendlyName		156
        +#define OBJ_friendlyName		OBJ_pkcs9,20L
        +
        +#define LN_localKeyID		"localKeyID"
        +#define NID_localKeyID		157
        +#define OBJ_localKeyID		OBJ_pkcs9,21L
        +
        +#define SN_ms_csp_name		"CSPName"
        +#define LN_ms_csp_name		"Microsoft CSP Name"
        +#define NID_ms_csp_name		417
        +#define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
        +
        +#define SN_LocalKeySet		"LocalKeySet"
        +#define LN_LocalKeySet		"Microsoft Local Key set"
        +#define NID_LocalKeySet		856
        +#define OBJ_LocalKeySet		1L,3L,6L,1L,4L,1L,311L,17L,2L
        +
        +#define OBJ_certTypes		OBJ_pkcs9,22L
        +
        +#define LN_x509Certificate		"x509Certificate"
        +#define NID_x509Certificate		158
        +#define OBJ_x509Certificate		OBJ_certTypes,1L
        +
        +#define LN_sdsiCertificate		"sdsiCertificate"
        +#define NID_sdsiCertificate		159
        +#define OBJ_sdsiCertificate		OBJ_certTypes,2L
        +
        +#define OBJ_crlTypes		OBJ_pkcs9,23L
        +
        +#define LN_x509Crl		"x509Crl"
        +#define NID_x509Crl		160
        +#define OBJ_x509Crl		OBJ_crlTypes,1L
        +
        +#define OBJ_pkcs12		OBJ_pkcs,12L
        +
        +#define OBJ_pkcs12_pbeids		OBJ_pkcs12,1L
        +
        +#define SN_pbe_WithSHA1And128BitRC4		"PBE-SHA1-RC4-128"
        +#define LN_pbe_WithSHA1And128BitRC4		"pbeWithSHA1And128BitRC4"
        +#define NID_pbe_WithSHA1And128BitRC4		144
        +#define OBJ_pbe_WithSHA1And128BitRC4		OBJ_pkcs12_pbeids,1L
        +
        +#define SN_pbe_WithSHA1And40BitRC4		"PBE-SHA1-RC4-40"
        +#define LN_pbe_WithSHA1And40BitRC4		"pbeWithSHA1And40BitRC4"
        +#define NID_pbe_WithSHA1And40BitRC4		145
        +#define OBJ_pbe_WithSHA1And40BitRC4		OBJ_pkcs12_pbeids,2L
        +
        +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC		"PBE-SHA1-3DES"
        +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC		"pbeWithSHA1And3-KeyTripleDES-CBC"
        +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC		146
        +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,3L
        +
        +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC		"PBE-SHA1-2DES"
        +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC		"pbeWithSHA1And2-KeyTripleDES-CBC"
        +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC		147
        +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,4L
        +
        +#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
        +#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
        +#define NID_pbe_WithSHA1And128BitRC2_CBC		148
        +#define OBJ_pbe_WithSHA1And128BitRC2_CBC		OBJ_pkcs12_pbeids,5L
        +
        +#define SN_pbe_WithSHA1And40BitRC2_CBC		"PBE-SHA1-RC2-40"
        +#define LN_pbe_WithSHA1And40BitRC2_CBC		"pbeWithSHA1And40BitRC2-CBC"
        +#define NID_pbe_WithSHA1And40BitRC2_CBC		149
        +#define OBJ_pbe_WithSHA1And40BitRC2_CBC		OBJ_pkcs12_pbeids,6L
        +
        +#define OBJ_pkcs12_Version1		OBJ_pkcs12,10L
        +
        +#define OBJ_pkcs12_BagIds		OBJ_pkcs12_Version1,1L
        +
        +#define LN_keyBag		"keyBag"
        +#define NID_keyBag		150
        +#define OBJ_keyBag		OBJ_pkcs12_BagIds,1L
        +
        +#define LN_pkcs8ShroudedKeyBag		"pkcs8ShroudedKeyBag"
        +#define NID_pkcs8ShroudedKeyBag		151
        +#define OBJ_pkcs8ShroudedKeyBag		OBJ_pkcs12_BagIds,2L
        +
        +#define LN_certBag		"certBag"
        +#define NID_certBag		152
        +#define OBJ_certBag		OBJ_pkcs12_BagIds,3L
        +
        +#define LN_crlBag		"crlBag"
        +#define NID_crlBag		153
        +#define OBJ_crlBag		OBJ_pkcs12_BagIds,4L
        +
        +#define LN_secretBag		"secretBag"
        +#define NID_secretBag		154
        +#define OBJ_secretBag		OBJ_pkcs12_BagIds,5L
        +
        +#define LN_safeContentsBag		"safeContentsBag"
        +#define NID_safeContentsBag		155
        +#define OBJ_safeContentsBag		OBJ_pkcs12_BagIds,6L
        +
        +#define SN_md2		"MD2"
        +#define LN_md2		"md2"
        +#define NID_md2		3
        +#define OBJ_md2		OBJ_rsadsi,2L,2L
        +
        +#define SN_md4		"MD4"
        +#define LN_md4		"md4"
        +#define NID_md4		257
        +#define OBJ_md4		OBJ_rsadsi,2L,4L
        +
        +#define SN_md5		"MD5"
        +#define LN_md5		"md5"
        +#define NID_md5		4
        +#define OBJ_md5		OBJ_rsadsi,2L,5L
        +
        +#define SN_md5_sha1		"MD5-SHA1"
        +#define LN_md5_sha1		"md5-sha1"
        +#define NID_md5_sha1		114
        +
        +#define LN_hmacWithMD5		"hmacWithMD5"
        +#define NID_hmacWithMD5		797
        +#define OBJ_hmacWithMD5		OBJ_rsadsi,2L,6L
        +
        +#define LN_hmacWithSHA1		"hmacWithSHA1"
        +#define NID_hmacWithSHA1		163
        +#define OBJ_hmacWithSHA1		OBJ_rsadsi,2L,7L
        +
        +#define LN_hmacWithSHA224		"hmacWithSHA224"
        +#define NID_hmacWithSHA224		798
        +#define OBJ_hmacWithSHA224		OBJ_rsadsi,2L,8L
        +
        +#define LN_hmacWithSHA256		"hmacWithSHA256"
        +#define NID_hmacWithSHA256		799
        +#define OBJ_hmacWithSHA256		OBJ_rsadsi,2L,9L
        +
        +#define LN_hmacWithSHA384		"hmacWithSHA384"
        +#define NID_hmacWithSHA384		800
        +#define OBJ_hmacWithSHA384		OBJ_rsadsi,2L,10L
        +
        +#define LN_hmacWithSHA512		"hmacWithSHA512"
        +#define NID_hmacWithSHA512		801
        +#define OBJ_hmacWithSHA512		OBJ_rsadsi,2L,11L
        +
        +#define SN_rc2_cbc		"RC2-CBC"
        +#define LN_rc2_cbc		"rc2-cbc"
        +#define NID_rc2_cbc		37
        +#define OBJ_rc2_cbc		OBJ_rsadsi,3L,2L
        +
        +#define SN_rc2_ecb		"RC2-ECB"
        +#define LN_rc2_ecb		"rc2-ecb"
        +#define NID_rc2_ecb		38
        +
        +#define SN_rc2_cfb64		"RC2-CFB"
        +#define LN_rc2_cfb64		"rc2-cfb"
        +#define NID_rc2_cfb64		39
        +
        +#define SN_rc2_ofb64		"RC2-OFB"
        +#define LN_rc2_ofb64		"rc2-ofb"
        +#define NID_rc2_ofb64		40
        +
        +#define SN_rc2_40_cbc		"RC2-40-CBC"
        +#define LN_rc2_40_cbc		"rc2-40-cbc"
        +#define NID_rc2_40_cbc		98
        +
        +#define SN_rc2_64_cbc		"RC2-64-CBC"
        +#define LN_rc2_64_cbc		"rc2-64-cbc"
        +#define NID_rc2_64_cbc		166
        +
        +#define SN_rc4		"RC4"
        +#define LN_rc4		"rc4"
        +#define NID_rc4		5
        +#define OBJ_rc4		OBJ_rsadsi,3L,4L
        +
        +#define SN_rc4_40		"RC4-40"
        +#define LN_rc4_40		"rc4-40"
        +#define NID_rc4_40		97
        +
        +#define SN_des_ede3_cbc		"DES-EDE3-CBC"
        +#define LN_des_ede3_cbc		"des-ede3-cbc"
        +#define NID_des_ede3_cbc		44
        +#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
        +
        +#define SN_rc5_cbc		"RC5-CBC"
        +#define LN_rc5_cbc		"rc5-cbc"
        +#define NID_rc5_cbc		120
        +#define OBJ_rc5_cbc		OBJ_rsadsi,3L,8L
        +
        +#define SN_rc5_ecb		"RC5-ECB"
        +#define LN_rc5_ecb		"rc5-ecb"
        +#define NID_rc5_ecb		121
        +
        +#define SN_rc5_cfb64		"RC5-CFB"
        +#define LN_rc5_cfb64		"rc5-cfb"
        +#define NID_rc5_cfb64		122
        +
        +#define SN_rc5_ofb64		"RC5-OFB"
        +#define LN_rc5_ofb64		"rc5-ofb"
        +#define NID_rc5_ofb64		123
        +
        +#define SN_ms_ext_req		"msExtReq"
        +#define LN_ms_ext_req		"Microsoft Extension Request"
        +#define NID_ms_ext_req		171
        +#define OBJ_ms_ext_req		1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
        +
        +#define SN_ms_code_ind		"msCodeInd"
        +#define LN_ms_code_ind		"Microsoft Individual Code Signing"
        +#define NID_ms_code_ind		134
        +#define OBJ_ms_code_ind		1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
        +
        +#define SN_ms_code_com		"msCodeCom"
        +#define LN_ms_code_com		"Microsoft Commercial Code Signing"
        +#define NID_ms_code_com		135
        +#define OBJ_ms_code_com		1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
        +
        +#define SN_ms_ctl_sign		"msCTLSign"
        +#define LN_ms_ctl_sign		"Microsoft Trust List Signing"
        +#define NID_ms_ctl_sign		136
        +#define OBJ_ms_ctl_sign		1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
        +
        +#define SN_ms_sgc		"msSGC"
        +#define LN_ms_sgc		"Microsoft Server Gated Crypto"
        +#define NID_ms_sgc		137
        +#define OBJ_ms_sgc		1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
        +
        +#define SN_ms_efs		"msEFS"
        +#define LN_ms_efs		"Microsoft Encrypted File System"
        +#define NID_ms_efs		138
        +#define OBJ_ms_efs		1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
        +
        +#define SN_ms_smartcard_login		"msSmartcardLogin"
        +#define LN_ms_smartcard_login		"Microsoft Smartcardlogin"
        +#define NID_ms_smartcard_login		648
        +#define OBJ_ms_smartcard_login		1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
        +
        +#define SN_ms_upn		"msUPN"
        +#define LN_ms_upn		"Microsoft Universal Principal Name"
        +#define NID_ms_upn		649
        +#define OBJ_ms_upn		1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
        +
        +#define SN_idea_cbc		"IDEA-CBC"
        +#define LN_idea_cbc		"idea-cbc"
        +#define NID_idea_cbc		34
        +#define OBJ_idea_cbc		1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
        +
        +#define SN_idea_ecb		"IDEA-ECB"
        +#define LN_idea_ecb		"idea-ecb"
        +#define NID_idea_ecb		36
        +
        +#define SN_idea_cfb64		"IDEA-CFB"
        +#define LN_idea_cfb64		"idea-cfb"
        +#define NID_idea_cfb64		35
        +
        +#define SN_idea_ofb64		"IDEA-OFB"
        +#define LN_idea_ofb64		"idea-ofb"
        +#define NID_idea_ofb64		46
        +
        +#define SN_bf_cbc		"BF-CBC"
        +#define LN_bf_cbc		"bf-cbc"
        +#define NID_bf_cbc		91
        +#define OBJ_bf_cbc		1L,3L,6L,1L,4L,1L,3029L,1L,2L
        +
        +#define SN_bf_ecb		"BF-ECB"
        +#define LN_bf_ecb		"bf-ecb"
        +#define NID_bf_ecb		92
        +
        +#define SN_bf_cfb64		"BF-CFB"
        +#define LN_bf_cfb64		"bf-cfb"
        +#define NID_bf_cfb64		93
        +
        +#define SN_bf_ofb64		"BF-OFB"
        +#define LN_bf_ofb64		"bf-ofb"
        +#define NID_bf_ofb64		94
        +
        +#define SN_id_pkix		"PKIX"
        +#define NID_id_pkix		127
        +#define OBJ_id_pkix		1L,3L,6L,1L,5L,5L,7L
        +
        +#define SN_id_pkix_mod		"id-pkix-mod"
        +#define NID_id_pkix_mod		258
        +#define OBJ_id_pkix_mod		OBJ_id_pkix,0L
        +
        +#define SN_id_pe		"id-pe"
        +#define NID_id_pe		175
        +#define OBJ_id_pe		OBJ_id_pkix,1L
        +
        +#define SN_id_qt		"id-qt"
        +#define NID_id_qt		259
        +#define OBJ_id_qt		OBJ_id_pkix,2L
        +
        +#define SN_id_kp		"id-kp"
        +#define NID_id_kp		128
        +#define OBJ_id_kp		OBJ_id_pkix,3L
        +
        +#define SN_id_it		"id-it"
        +#define NID_id_it		260
        +#define OBJ_id_it		OBJ_id_pkix,4L
        +
        +#define SN_id_pkip		"id-pkip"
        +#define NID_id_pkip		261
        +#define OBJ_id_pkip		OBJ_id_pkix,5L
        +
        +#define SN_id_alg		"id-alg"
        +#define NID_id_alg		262
        +#define OBJ_id_alg		OBJ_id_pkix,6L
        +
        +#define SN_id_cmc		"id-cmc"
        +#define NID_id_cmc		263
        +#define OBJ_id_cmc		OBJ_id_pkix,7L
        +
        +#define SN_id_on		"id-on"
        +#define NID_id_on		264
        +#define OBJ_id_on		OBJ_id_pkix,8L
        +
        +#define SN_id_pda		"id-pda"
        +#define NID_id_pda		265
        +#define OBJ_id_pda		OBJ_id_pkix,9L
        +
        +#define SN_id_aca		"id-aca"
        +#define NID_id_aca		266
        +#define OBJ_id_aca		OBJ_id_pkix,10L
        +
        +#define SN_id_qcs		"id-qcs"
        +#define NID_id_qcs		267
        +#define OBJ_id_qcs		OBJ_id_pkix,11L
        +
        +#define SN_id_cct		"id-cct"
        +#define NID_id_cct		268
        +#define OBJ_id_cct		OBJ_id_pkix,12L
        +
        +#define SN_id_ppl		"id-ppl"
        +#define NID_id_ppl		662
        +#define OBJ_id_ppl		OBJ_id_pkix,21L
        +
        +#define SN_id_ad		"id-ad"
        +#define NID_id_ad		176
        +#define OBJ_id_ad		OBJ_id_pkix,48L
        +
        +#define SN_id_pkix1_explicit_88		"id-pkix1-explicit-88"
        +#define NID_id_pkix1_explicit_88		269
        +#define OBJ_id_pkix1_explicit_88		OBJ_id_pkix_mod,1L
        +
        +#define SN_id_pkix1_implicit_88		"id-pkix1-implicit-88"
        +#define NID_id_pkix1_implicit_88		270
        +#define OBJ_id_pkix1_implicit_88		OBJ_id_pkix_mod,2L
        +
        +#define SN_id_pkix1_explicit_93		"id-pkix1-explicit-93"
        +#define NID_id_pkix1_explicit_93		271
        +#define OBJ_id_pkix1_explicit_93		OBJ_id_pkix_mod,3L
        +
        +#define SN_id_pkix1_implicit_93		"id-pkix1-implicit-93"
        +#define NID_id_pkix1_implicit_93		272
        +#define OBJ_id_pkix1_implicit_93		OBJ_id_pkix_mod,4L
        +
        +#define SN_id_mod_crmf		"id-mod-crmf"
        +#define NID_id_mod_crmf		273
        +#define OBJ_id_mod_crmf		OBJ_id_pkix_mod,5L
        +
        +#define SN_id_mod_cmc		"id-mod-cmc"
        +#define NID_id_mod_cmc		274
        +#define OBJ_id_mod_cmc		OBJ_id_pkix_mod,6L
        +
        +#define SN_id_mod_kea_profile_88		"id-mod-kea-profile-88"
        +#define NID_id_mod_kea_profile_88		275
        +#define OBJ_id_mod_kea_profile_88		OBJ_id_pkix_mod,7L
        +
        +#define SN_id_mod_kea_profile_93		"id-mod-kea-profile-93"
        +#define NID_id_mod_kea_profile_93		276
        +#define OBJ_id_mod_kea_profile_93		OBJ_id_pkix_mod,8L
        +
        +#define SN_id_mod_cmp		"id-mod-cmp"
        +#define NID_id_mod_cmp		277
        +#define OBJ_id_mod_cmp		OBJ_id_pkix_mod,9L
        +
        +#define SN_id_mod_qualified_cert_88		"id-mod-qualified-cert-88"
        +#define NID_id_mod_qualified_cert_88		278
        +#define OBJ_id_mod_qualified_cert_88		OBJ_id_pkix_mod,10L
        +
        +#define SN_id_mod_qualified_cert_93		"id-mod-qualified-cert-93"
        +#define NID_id_mod_qualified_cert_93		279
        +#define OBJ_id_mod_qualified_cert_93		OBJ_id_pkix_mod,11L
        +
        +#define SN_id_mod_attribute_cert		"id-mod-attribute-cert"
        +#define NID_id_mod_attribute_cert		280
        +#define OBJ_id_mod_attribute_cert		OBJ_id_pkix_mod,12L
        +
        +#define SN_id_mod_timestamp_protocol		"id-mod-timestamp-protocol"
        +#define NID_id_mod_timestamp_protocol		281
        +#define OBJ_id_mod_timestamp_protocol		OBJ_id_pkix_mod,13L
        +
        +#define SN_id_mod_ocsp		"id-mod-ocsp"
        +#define NID_id_mod_ocsp		282
        +#define OBJ_id_mod_ocsp		OBJ_id_pkix_mod,14L
        +
        +#define SN_id_mod_dvcs		"id-mod-dvcs"
        +#define NID_id_mod_dvcs		283
        +#define OBJ_id_mod_dvcs		OBJ_id_pkix_mod,15L
        +
        +#define SN_id_mod_cmp2000		"id-mod-cmp2000"
        +#define NID_id_mod_cmp2000		284
        +#define OBJ_id_mod_cmp2000		OBJ_id_pkix_mod,16L
        +
        +#define SN_info_access		"authorityInfoAccess"
        +#define LN_info_access		"Authority Information Access"
        +#define NID_info_access		177
        +#define OBJ_info_access		OBJ_id_pe,1L
        +
        +#define SN_biometricInfo		"biometricInfo"
        +#define LN_biometricInfo		"Biometric Info"
        +#define NID_biometricInfo		285
        +#define OBJ_biometricInfo		OBJ_id_pe,2L
        +
        +#define SN_qcStatements		"qcStatements"
        +#define NID_qcStatements		286
        +#define OBJ_qcStatements		OBJ_id_pe,3L
        +
        +#define SN_ac_auditEntity		"ac-auditEntity"
        +#define NID_ac_auditEntity		287
        +#define OBJ_ac_auditEntity		OBJ_id_pe,4L
        +
        +#define SN_ac_targeting		"ac-targeting"
        +#define NID_ac_targeting		288
        +#define OBJ_ac_targeting		OBJ_id_pe,5L
        +
        +#define SN_aaControls		"aaControls"
        +#define NID_aaControls		289
        +#define OBJ_aaControls		OBJ_id_pe,6L
        +
        +#define SN_sbgp_ipAddrBlock		"sbgp-ipAddrBlock"
        +#define NID_sbgp_ipAddrBlock		290
        +#define OBJ_sbgp_ipAddrBlock		OBJ_id_pe,7L
        +
        +#define SN_sbgp_autonomousSysNum		"sbgp-autonomousSysNum"
        +#define NID_sbgp_autonomousSysNum		291
        +#define OBJ_sbgp_autonomousSysNum		OBJ_id_pe,8L
        +
        +#define SN_sbgp_routerIdentifier		"sbgp-routerIdentifier"
        +#define NID_sbgp_routerIdentifier		292
        +#define OBJ_sbgp_routerIdentifier		OBJ_id_pe,9L
        +
        +#define SN_ac_proxying		"ac-proxying"
        +#define NID_ac_proxying		397
        +#define OBJ_ac_proxying		OBJ_id_pe,10L
        +
        +#define SN_sinfo_access		"subjectInfoAccess"
        +#define LN_sinfo_access		"Subject Information Access"
        +#define NID_sinfo_access		398
        +#define OBJ_sinfo_access		OBJ_id_pe,11L
        +
        +#define SN_proxyCertInfo		"proxyCertInfo"
        +#define LN_proxyCertInfo		"Proxy Certificate Information"
        +#define NID_proxyCertInfo		663
        +#define OBJ_proxyCertInfo		OBJ_id_pe,14L
        +
        +#define SN_id_qt_cps		"id-qt-cps"
        +#define LN_id_qt_cps		"Policy Qualifier CPS"
        +#define NID_id_qt_cps		164
        +#define OBJ_id_qt_cps		OBJ_id_qt,1L
        +
        +#define SN_id_qt_unotice		"id-qt-unotice"
        +#define LN_id_qt_unotice		"Policy Qualifier User Notice"
        +#define NID_id_qt_unotice		165
        +#define OBJ_id_qt_unotice		OBJ_id_qt,2L
        +
        +#define SN_textNotice		"textNotice"
        +#define NID_textNotice		293
        +#define OBJ_textNotice		OBJ_id_qt,3L
        +
        +#define SN_server_auth		"serverAuth"
        +#define LN_server_auth		"TLS Web Server Authentication"
        +#define NID_server_auth		129
        +#define OBJ_server_auth		OBJ_id_kp,1L
        +
        +#define SN_client_auth		"clientAuth"
        +#define LN_client_auth		"TLS Web Client Authentication"
        +#define NID_client_auth		130
        +#define OBJ_client_auth		OBJ_id_kp,2L
        +
        +#define SN_code_sign		"codeSigning"
        +#define LN_code_sign		"Code Signing"
        +#define NID_code_sign		131
        +#define OBJ_code_sign		OBJ_id_kp,3L
        +
        +#define SN_email_protect		"emailProtection"
        +#define LN_email_protect		"E-mail Protection"
        +#define NID_email_protect		132
        +#define OBJ_email_protect		OBJ_id_kp,4L
        +
        +#define SN_ipsecEndSystem		"ipsecEndSystem"
        +#define LN_ipsecEndSystem		"IPSec End System"
        +#define NID_ipsecEndSystem		294
        +#define OBJ_ipsecEndSystem		OBJ_id_kp,5L
        +
        +#define SN_ipsecTunnel		"ipsecTunnel"
        +#define LN_ipsecTunnel		"IPSec Tunnel"
        +#define NID_ipsecTunnel		295
        +#define OBJ_ipsecTunnel		OBJ_id_kp,6L
        +
        +#define SN_ipsecUser		"ipsecUser"
        +#define LN_ipsecUser		"IPSec User"
        +#define NID_ipsecUser		296
        +#define OBJ_ipsecUser		OBJ_id_kp,7L
        +
        +#define SN_time_stamp		"timeStamping"
        +#define LN_time_stamp		"Time Stamping"
        +#define NID_time_stamp		133
        +#define OBJ_time_stamp		OBJ_id_kp,8L
        +
        +#define SN_OCSP_sign		"OCSPSigning"
        +#define LN_OCSP_sign		"OCSP Signing"
        +#define NID_OCSP_sign		180
        +#define OBJ_OCSP_sign		OBJ_id_kp,9L
        +
        +#define SN_dvcs		"DVCS"
        +#define LN_dvcs		"dvcs"
        +#define NID_dvcs		297
        +#define OBJ_dvcs		OBJ_id_kp,10L
        +
        +#define SN_id_it_caProtEncCert		"id-it-caProtEncCert"
        +#define NID_id_it_caProtEncCert		298
        +#define OBJ_id_it_caProtEncCert		OBJ_id_it,1L
        +
        +#define SN_id_it_signKeyPairTypes		"id-it-signKeyPairTypes"
        +#define NID_id_it_signKeyPairTypes		299
        +#define OBJ_id_it_signKeyPairTypes		OBJ_id_it,2L
        +
        +#define SN_id_it_encKeyPairTypes		"id-it-encKeyPairTypes"
        +#define NID_id_it_encKeyPairTypes		300
        +#define OBJ_id_it_encKeyPairTypes		OBJ_id_it,3L
        +
        +#define SN_id_it_preferredSymmAlg		"id-it-preferredSymmAlg"
        +#define NID_id_it_preferredSymmAlg		301
        +#define OBJ_id_it_preferredSymmAlg		OBJ_id_it,4L
        +
        +#define SN_id_it_caKeyUpdateInfo		"id-it-caKeyUpdateInfo"
        +#define NID_id_it_caKeyUpdateInfo		302
        +#define OBJ_id_it_caKeyUpdateInfo		OBJ_id_it,5L
        +
        +#define SN_id_it_currentCRL		"id-it-currentCRL"
        +#define NID_id_it_currentCRL		303
        +#define OBJ_id_it_currentCRL		OBJ_id_it,6L
        +
        +#define SN_id_it_unsupportedOIDs		"id-it-unsupportedOIDs"
        +#define NID_id_it_unsupportedOIDs		304
        +#define OBJ_id_it_unsupportedOIDs		OBJ_id_it,7L
        +
        +#define SN_id_it_subscriptionRequest		"id-it-subscriptionRequest"
        +#define NID_id_it_subscriptionRequest		305
        +#define OBJ_id_it_subscriptionRequest		OBJ_id_it,8L
        +
        +#define SN_id_it_subscriptionResponse		"id-it-subscriptionResponse"
        +#define NID_id_it_subscriptionResponse		306
        +#define OBJ_id_it_subscriptionResponse		OBJ_id_it,9L
        +
        +#define SN_id_it_keyPairParamReq		"id-it-keyPairParamReq"
        +#define NID_id_it_keyPairParamReq		307
        +#define OBJ_id_it_keyPairParamReq		OBJ_id_it,10L
        +
        +#define SN_id_it_keyPairParamRep		"id-it-keyPairParamRep"
        +#define NID_id_it_keyPairParamRep		308
        +#define OBJ_id_it_keyPairParamRep		OBJ_id_it,11L
        +
        +#define SN_id_it_revPassphrase		"id-it-revPassphrase"
        +#define NID_id_it_revPassphrase		309
        +#define OBJ_id_it_revPassphrase		OBJ_id_it,12L
        +
        +#define SN_id_it_implicitConfirm		"id-it-implicitConfirm"
        +#define NID_id_it_implicitConfirm		310
        +#define OBJ_id_it_implicitConfirm		OBJ_id_it,13L
        +
        +#define SN_id_it_confirmWaitTime		"id-it-confirmWaitTime"
        +#define NID_id_it_confirmWaitTime		311
        +#define OBJ_id_it_confirmWaitTime		OBJ_id_it,14L
        +
        +#define SN_id_it_origPKIMessage		"id-it-origPKIMessage"
        +#define NID_id_it_origPKIMessage		312
        +#define OBJ_id_it_origPKIMessage		OBJ_id_it,15L
        +
        +#define SN_id_it_suppLangTags		"id-it-suppLangTags"
        +#define NID_id_it_suppLangTags		784
        +#define OBJ_id_it_suppLangTags		OBJ_id_it,16L
        +
        +#define SN_id_regCtrl		"id-regCtrl"
        +#define NID_id_regCtrl		313
        +#define OBJ_id_regCtrl		OBJ_id_pkip,1L
        +
        +#define SN_id_regInfo		"id-regInfo"
        +#define NID_id_regInfo		314
        +#define OBJ_id_regInfo		OBJ_id_pkip,2L
        +
        +#define SN_id_regCtrl_regToken		"id-regCtrl-regToken"
        +#define NID_id_regCtrl_regToken		315
        +#define OBJ_id_regCtrl_regToken		OBJ_id_regCtrl,1L
        +
        +#define SN_id_regCtrl_authenticator		"id-regCtrl-authenticator"
        +#define NID_id_regCtrl_authenticator		316
        +#define OBJ_id_regCtrl_authenticator		OBJ_id_regCtrl,2L
        +
        +#define SN_id_regCtrl_pkiPublicationInfo		"id-regCtrl-pkiPublicationInfo"
        +#define NID_id_regCtrl_pkiPublicationInfo		317
        +#define OBJ_id_regCtrl_pkiPublicationInfo		OBJ_id_regCtrl,3L
        +
        +#define SN_id_regCtrl_pkiArchiveOptions		"id-regCtrl-pkiArchiveOptions"
        +#define NID_id_regCtrl_pkiArchiveOptions		318
        +#define OBJ_id_regCtrl_pkiArchiveOptions		OBJ_id_regCtrl,4L
        +
        +#define SN_id_regCtrl_oldCertID		"id-regCtrl-oldCertID"
        +#define NID_id_regCtrl_oldCertID		319
        +#define OBJ_id_regCtrl_oldCertID		OBJ_id_regCtrl,5L
        +
        +#define SN_id_regCtrl_protocolEncrKey		"id-regCtrl-protocolEncrKey"
        +#define NID_id_regCtrl_protocolEncrKey		320
        +#define OBJ_id_regCtrl_protocolEncrKey		OBJ_id_regCtrl,6L
        +
        +#define SN_id_regInfo_utf8Pairs		"id-regInfo-utf8Pairs"
        +#define NID_id_regInfo_utf8Pairs		321
        +#define OBJ_id_regInfo_utf8Pairs		OBJ_id_regInfo,1L
        +
        +#define SN_id_regInfo_certReq		"id-regInfo-certReq"
        +#define NID_id_regInfo_certReq		322
        +#define OBJ_id_regInfo_certReq		OBJ_id_regInfo,2L
        +
        +#define SN_id_alg_des40		"id-alg-des40"
        +#define NID_id_alg_des40		323
        +#define OBJ_id_alg_des40		OBJ_id_alg,1L
        +
        +#define SN_id_alg_noSignature		"id-alg-noSignature"
        +#define NID_id_alg_noSignature		324
        +#define OBJ_id_alg_noSignature		OBJ_id_alg,2L
        +
        +#define SN_id_alg_dh_sig_hmac_sha1		"id-alg-dh-sig-hmac-sha1"
        +#define NID_id_alg_dh_sig_hmac_sha1		325
        +#define OBJ_id_alg_dh_sig_hmac_sha1		OBJ_id_alg,3L
        +
        +#define SN_id_alg_dh_pop		"id-alg-dh-pop"
        +#define NID_id_alg_dh_pop		326
        +#define OBJ_id_alg_dh_pop		OBJ_id_alg,4L
        +
        +#define SN_id_cmc_statusInfo		"id-cmc-statusInfo"
        +#define NID_id_cmc_statusInfo		327
        +#define OBJ_id_cmc_statusInfo		OBJ_id_cmc,1L
        +
        +#define SN_id_cmc_identification		"id-cmc-identification"
        +#define NID_id_cmc_identification		328
        +#define OBJ_id_cmc_identification		OBJ_id_cmc,2L
        +
        +#define SN_id_cmc_identityProof		"id-cmc-identityProof"
        +#define NID_id_cmc_identityProof		329
        +#define OBJ_id_cmc_identityProof		OBJ_id_cmc,3L
        +
        +#define SN_id_cmc_dataReturn		"id-cmc-dataReturn"
        +#define NID_id_cmc_dataReturn		330
        +#define OBJ_id_cmc_dataReturn		OBJ_id_cmc,4L
        +
        +#define SN_id_cmc_transactionId		"id-cmc-transactionId"
        +#define NID_id_cmc_transactionId		331
        +#define OBJ_id_cmc_transactionId		OBJ_id_cmc,5L
        +
        +#define SN_id_cmc_senderNonce		"id-cmc-senderNonce"
        +#define NID_id_cmc_senderNonce		332
        +#define OBJ_id_cmc_senderNonce		OBJ_id_cmc,6L
        +
        +#define SN_id_cmc_recipientNonce		"id-cmc-recipientNonce"
        +#define NID_id_cmc_recipientNonce		333
        +#define OBJ_id_cmc_recipientNonce		OBJ_id_cmc,7L
        +
        +#define SN_id_cmc_addExtensions		"id-cmc-addExtensions"
        +#define NID_id_cmc_addExtensions		334
        +#define OBJ_id_cmc_addExtensions		OBJ_id_cmc,8L
        +
        +#define SN_id_cmc_encryptedPOP		"id-cmc-encryptedPOP"
        +#define NID_id_cmc_encryptedPOP		335
        +#define OBJ_id_cmc_encryptedPOP		OBJ_id_cmc,9L
        +
        +#define SN_id_cmc_decryptedPOP		"id-cmc-decryptedPOP"
        +#define NID_id_cmc_decryptedPOP		336
        +#define OBJ_id_cmc_decryptedPOP		OBJ_id_cmc,10L
        +
        +#define SN_id_cmc_lraPOPWitness		"id-cmc-lraPOPWitness"
        +#define NID_id_cmc_lraPOPWitness		337
        +#define OBJ_id_cmc_lraPOPWitness		OBJ_id_cmc,11L
        +
        +#define SN_id_cmc_getCert		"id-cmc-getCert"
        +#define NID_id_cmc_getCert		338
        +#define OBJ_id_cmc_getCert		OBJ_id_cmc,15L
        +
        +#define SN_id_cmc_getCRL		"id-cmc-getCRL"
        +#define NID_id_cmc_getCRL		339
        +#define OBJ_id_cmc_getCRL		OBJ_id_cmc,16L
        +
        +#define SN_id_cmc_revokeRequest		"id-cmc-revokeRequest"
        +#define NID_id_cmc_revokeRequest		340
        +#define OBJ_id_cmc_revokeRequest		OBJ_id_cmc,17L
        +
        +#define SN_id_cmc_regInfo		"id-cmc-regInfo"
        +#define NID_id_cmc_regInfo		341
        +#define OBJ_id_cmc_regInfo		OBJ_id_cmc,18L
        +
        +#define SN_id_cmc_responseInfo		"id-cmc-responseInfo"
        +#define NID_id_cmc_responseInfo		342
        +#define OBJ_id_cmc_responseInfo		OBJ_id_cmc,19L
        +
        +#define SN_id_cmc_queryPending		"id-cmc-queryPending"
        +#define NID_id_cmc_queryPending		343
        +#define OBJ_id_cmc_queryPending		OBJ_id_cmc,21L
        +
        +#define SN_id_cmc_popLinkRandom		"id-cmc-popLinkRandom"
        +#define NID_id_cmc_popLinkRandom		344
        +#define OBJ_id_cmc_popLinkRandom		OBJ_id_cmc,22L
        +
        +#define SN_id_cmc_popLinkWitness		"id-cmc-popLinkWitness"
        +#define NID_id_cmc_popLinkWitness		345
        +#define OBJ_id_cmc_popLinkWitness		OBJ_id_cmc,23L
        +
        +#define SN_id_cmc_confirmCertAcceptance		"id-cmc-confirmCertAcceptance"
        +#define NID_id_cmc_confirmCertAcceptance		346
        +#define OBJ_id_cmc_confirmCertAcceptance		OBJ_id_cmc,24L
        +
        +#define SN_id_on_personalData		"id-on-personalData"
        +#define NID_id_on_personalData		347
        +#define OBJ_id_on_personalData		OBJ_id_on,1L
        +
        +#define SN_id_on_permanentIdentifier		"id-on-permanentIdentifier"
        +#define LN_id_on_permanentIdentifier		"Permanent Identifier"
        +#define NID_id_on_permanentIdentifier		858
        +#define OBJ_id_on_permanentIdentifier		OBJ_id_on,3L
        +
        +#define SN_id_pda_dateOfBirth		"id-pda-dateOfBirth"
        +#define NID_id_pda_dateOfBirth		348
        +#define OBJ_id_pda_dateOfBirth		OBJ_id_pda,1L
        +
        +#define SN_id_pda_placeOfBirth		"id-pda-placeOfBirth"
        +#define NID_id_pda_placeOfBirth		349
        +#define OBJ_id_pda_placeOfBirth		OBJ_id_pda,2L
        +
        +#define SN_id_pda_gender		"id-pda-gender"
        +#define NID_id_pda_gender		351
        +#define OBJ_id_pda_gender		OBJ_id_pda,3L
        +
        +#define SN_id_pda_countryOfCitizenship		"id-pda-countryOfCitizenship"
        +#define NID_id_pda_countryOfCitizenship		352
        +#define OBJ_id_pda_countryOfCitizenship		OBJ_id_pda,4L
        +
        +#define SN_id_pda_countryOfResidence		"id-pda-countryOfResidence"
        +#define NID_id_pda_countryOfResidence		353
        +#define OBJ_id_pda_countryOfResidence		OBJ_id_pda,5L
        +
        +#define SN_id_aca_authenticationInfo		"id-aca-authenticationInfo"
        +#define NID_id_aca_authenticationInfo		354
        +#define OBJ_id_aca_authenticationInfo		OBJ_id_aca,1L
        +
        +#define SN_id_aca_accessIdentity		"id-aca-accessIdentity"
        +#define NID_id_aca_accessIdentity		355
        +#define OBJ_id_aca_accessIdentity		OBJ_id_aca,2L
        +
        +#define SN_id_aca_chargingIdentity		"id-aca-chargingIdentity"
        +#define NID_id_aca_chargingIdentity		356
        +#define OBJ_id_aca_chargingIdentity		OBJ_id_aca,3L
        +
        +#define SN_id_aca_group		"id-aca-group"
        +#define NID_id_aca_group		357
        +#define OBJ_id_aca_group		OBJ_id_aca,4L
        +
        +#define SN_id_aca_role		"id-aca-role"
        +#define NID_id_aca_role		358
        +#define OBJ_id_aca_role		OBJ_id_aca,5L
        +
        +#define SN_id_aca_encAttrs		"id-aca-encAttrs"
        +#define NID_id_aca_encAttrs		399
        +#define OBJ_id_aca_encAttrs		OBJ_id_aca,6L
        +
        +#define SN_id_qcs_pkixQCSyntax_v1		"id-qcs-pkixQCSyntax-v1"
        +#define NID_id_qcs_pkixQCSyntax_v1		359
        +#define OBJ_id_qcs_pkixQCSyntax_v1		OBJ_id_qcs,1L
        +
        +#define SN_id_cct_crs		"id-cct-crs"
        +#define NID_id_cct_crs		360
        +#define OBJ_id_cct_crs		OBJ_id_cct,1L
        +
        +#define SN_id_cct_PKIData		"id-cct-PKIData"
        +#define NID_id_cct_PKIData		361
        +#define OBJ_id_cct_PKIData		OBJ_id_cct,2L
        +
        +#define SN_id_cct_PKIResponse		"id-cct-PKIResponse"
        +#define NID_id_cct_PKIResponse		362
        +#define OBJ_id_cct_PKIResponse		OBJ_id_cct,3L
        +
        +#define SN_id_ppl_anyLanguage		"id-ppl-anyLanguage"
        +#define LN_id_ppl_anyLanguage		"Any language"
        +#define NID_id_ppl_anyLanguage		664
        +#define OBJ_id_ppl_anyLanguage		OBJ_id_ppl,0L
        +
        +#define SN_id_ppl_inheritAll		"id-ppl-inheritAll"
        +#define LN_id_ppl_inheritAll		"Inherit all"
        +#define NID_id_ppl_inheritAll		665
        +#define OBJ_id_ppl_inheritAll		OBJ_id_ppl,1L
        +
        +#define SN_Independent		"id-ppl-independent"
        +#define LN_Independent		"Independent"
        +#define NID_Independent		667
        +#define OBJ_Independent		OBJ_id_ppl,2L
        +
        +#define SN_ad_OCSP		"OCSP"
        +#define LN_ad_OCSP		"OCSP"
        +#define NID_ad_OCSP		178
        +#define OBJ_ad_OCSP		OBJ_id_ad,1L
        +
        +#define SN_ad_ca_issuers		"caIssuers"
        +#define LN_ad_ca_issuers		"CA Issuers"
        +#define NID_ad_ca_issuers		179
        +#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
        +
        +#define SN_ad_timeStamping		"ad_timestamping"
        +#define LN_ad_timeStamping		"AD Time Stamping"
        +#define NID_ad_timeStamping		363
        +#define OBJ_ad_timeStamping		OBJ_id_ad,3L
        +
        +#define SN_ad_dvcs		"AD_DVCS"
        +#define LN_ad_dvcs		"ad dvcs"
        +#define NID_ad_dvcs		364
        +#define OBJ_ad_dvcs		OBJ_id_ad,4L
        +
        +#define SN_caRepository		"caRepository"
        +#define LN_caRepository		"CA Repository"
        +#define NID_caRepository		785
        +#define OBJ_caRepository		OBJ_id_ad,5L
        +
        +#define OBJ_id_pkix_OCSP		OBJ_ad_OCSP
        +
        +#define SN_id_pkix_OCSP_basic		"basicOCSPResponse"
        +#define LN_id_pkix_OCSP_basic		"Basic OCSP Response"
        +#define NID_id_pkix_OCSP_basic		365
        +#define OBJ_id_pkix_OCSP_basic		OBJ_id_pkix_OCSP,1L
        +
        +#define SN_id_pkix_OCSP_Nonce		"Nonce"
        +#define LN_id_pkix_OCSP_Nonce		"OCSP Nonce"
        +#define NID_id_pkix_OCSP_Nonce		366
        +#define OBJ_id_pkix_OCSP_Nonce		OBJ_id_pkix_OCSP,2L
        +
        +#define SN_id_pkix_OCSP_CrlID		"CrlID"
        +#define LN_id_pkix_OCSP_CrlID		"OCSP CRL ID"
        +#define NID_id_pkix_OCSP_CrlID		367
        +#define OBJ_id_pkix_OCSP_CrlID		OBJ_id_pkix_OCSP,3L
        +
        +#define SN_id_pkix_OCSP_acceptableResponses		"acceptableResponses"
        +#define LN_id_pkix_OCSP_acceptableResponses		"Acceptable OCSP Responses"
        +#define NID_id_pkix_OCSP_acceptableResponses		368
        +#define OBJ_id_pkix_OCSP_acceptableResponses		OBJ_id_pkix_OCSP,4L
        +
        +#define SN_id_pkix_OCSP_noCheck		"noCheck"
        +#define LN_id_pkix_OCSP_noCheck		"OCSP No Check"
        +#define NID_id_pkix_OCSP_noCheck		369
        +#define OBJ_id_pkix_OCSP_noCheck		OBJ_id_pkix_OCSP,5L
        +
        +#define SN_id_pkix_OCSP_archiveCutoff		"archiveCutoff"
        +#define LN_id_pkix_OCSP_archiveCutoff		"OCSP Archive Cutoff"
        +#define NID_id_pkix_OCSP_archiveCutoff		370
        +#define OBJ_id_pkix_OCSP_archiveCutoff		OBJ_id_pkix_OCSP,6L
        +
        +#define SN_id_pkix_OCSP_serviceLocator		"serviceLocator"
        +#define LN_id_pkix_OCSP_serviceLocator		"OCSP Service Locator"
        +#define NID_id_pkix_OCSP_serviceLocator		371
        +#define OBJ_id_pkix_OCSP_serviceLocator		OBJ_id_pkix_OCSP,7L
        +
        +#define SN_id_pkix_OCSP_extendedStatus		"extendedStatus"
        +#define LN_id_pkix_OCSP_extendedStatus		"Extended OCSP Status"
        +#define NID_id_pkix_OCSP_extendedStatus		372
        +#define OBJ_id_pkix_OCSP_extendedStatus		OBJ_id_pkix_OCSP,8L
        +
        +#define SN_id_pkix_OCSP_valid		"valid"
        +#define NID_id_pkix_OCSP_valid		373
        +#define OBJ_id_pkix_OCSP_valid		OBJ_id_pkix_OCSP,9L
        +
        +#define SN_id_pkix_OCSP_path		"path"
        +#define NID_id_pkix_OCSP_path		374
        +#define OBJ_id_pkix_OCSP_path		OBJ_id_pkix_OCSP,10L
        +
        +#define SN_id_pkix_OCSP_trustRoot		"trustRoot"
        +#define LN_id_pkix_OCSP_trustRoot		"Trust Root"
        +#define NID_id_pkix_OCSP_trustRoot		375
        +#define OBJ_id_pkix_OCSP_trustRoot		OBJ_id_pkix_OCSP,11L
        +
        +#define SN_algorithm		"algorithm"
        +#define LN_algorithm		"algorithm"
        +#define NID_algorithm		376
        +#define OBJ_algorithm		1L,3L,14L,3L,2L
        +
        +#define SN_md5WithRSA		"RSA-NP-MD5"
        +#define LN_md5WithRSA		"md5WithRSA"
        +#define NID_md5WithRSA		104
        +#define OBJ_md5WithRSA		OBJ_algorithm,3L
        +
        +#define SN_des_ecb		"DES-ECB"
        +#define LN_des_ecb		"des-ecb"
        +#define NID_des_ecb		29
        +#define OBJ_des_ecb		OBJ_algorithm,6L
        +
        +#define SN_des_cbc		"DES-CBC"
        +#define LN_des_cbc		"des-cbc"
        +#define NID_des_cbc		31
        +#define OBJ_des_cbc		OBJ_algorithm,7L
        +
        +#define SN_des_ofb64		"DES-OFB"
        +#define LN_des_ofb64		"des-ofb"
        +#define NID_des_ofb64		45
        +#define OBJ_des_ofb64		OBJ_algorithm,8L
        +
        +#define SN_des_cfb64		"DES-CFB"
        +#define LN_des_cfb64		"des-cfb"
        +#define NID_des_cfb64		30
        +#define OBJ_des_cfb64		OBJ_algorithm,9L
        +
        +#define SN_rsaSignature		"rsaSignature"
        +#define NID_rsaSignature		377
        +#define OBJ_rsaSignature		OBJ_algorithm,11L
        +
        +#define SN_dsa_2		"DSA-old"
        +#define LN_dsa_2		"dsaEncryption-old"
        +#define NID_dsa_2		67
        +#define OBJ_dsa_2		OBJ_algorithm,12L
        +
        +#define SN_dsaWithSHA		"DSA-SHA"
        +#define LN_dsaWithSHA		"dsaWithSHA"
        +#define NID_dsaWithSHA		66
        +#define OBJ_dsaWithSHA		OBJ_algorithm,13L
        +
        +#define SN_shaWithRSAEncryption		"RSA-SHA"
        +#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
        +#define NID_shaWithRSAEncryption		42
        +#define OBJ_shaWithRSAEncryption		OBJ_algorithm,15L
        +
        +#define SN_des_ede_ecb		"DES-EDE"
        +#define LN_des_ede_ecb		"des-ede"
        +#define NID_des_ede_ecb		32
        +#define OBJ_des_ede_ecb		OBJ_algorithm,17L
        +
        +#define SN_des_ede3_ecb		"DES-EDE3"
        +#define LN_des_ede3_ecb		"des-ede3"
        +#define NID_des_ede3_ecb		33
        +
        +#define SN_des_ede_cbc		"DES-EDE-CBC"
        +#define LN_des_ede_cbc		"des-ede-cbc"
        +#define NID_des_ede_cbc		43
        +
        +#define SN_des_ede_cfb64		"DES-EDE-CFB"
        +#define LN_des_ede_cfb64		"des-ede-cfb"
        +#define NID_des_ede_cfb64		60
        +
        +#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
        +#define LN_des_ede3_cfb64		"des-ede3-cfb"
        +#define NID_des_ede3_cfb64		61
        +
        +#define SN_des_ede_ofb64		"DES-EDE-OFB"
        +#define LN_des_ede_ofb64		"des-ede-ofb"
        +#define NID_des_ede_ofb64		62
        +
        +#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
        +#define LN_des_ede3_ofb64		"des-ede3-ofb"
        +#define NID_des_ede3_ofb64		63
        +
        +#define SN_desx_cbc		"DESX-CBC"
        +#define LN_desx_cbc		"desx-cbc"
        +#define NID_desx_cbc		80
        +
        +#define SN_sha		"SHA"
        +#define LN_sha		"sha"
        +#define NID_sha		41
        +#define OBJ_sha		OBJ_algorithm,18L
        +
        +#define SN_sha1		"SHA1"
        +#define LN_sha1		"sha1"
        +#define NID_sha1		64
        +#define OBJ_sha1		OBJ_algorithm,26L
        +
        +#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
        +#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
        +#define NID_dsaWithSHA1_2		70
        +#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
        +
        +#define SN_sha1WithRSA		"RSA-SHA1-2"
        +#define LN_sha1WithRSA		"sha1WithRSA"
        +#define NID_sha1WithRSA		115
        +#define OBJ_sha1WithRSA		OBJ_algorithm,29L
        +
        +#define SN_ripemd160		"RIPEMD160"
        +#define LN_ripemd160		"ripemd160"
        +#define NID_ripemd160		117
        +#define OBJ_ripemd160		1L,3L,36L,3L,2L,1L
        +
        +#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
        +#define LN_ripemd160WithRSA		"ripemd160WithRSA"
        +#define NID_ripemd160WithRSA		119
        +#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
        +
        +#define SN_sxnet		"SXNetID"
        +#define LN_sxnet		"Strong Extranet ID"
        +#define NID_sxnet		143
        +#define OBJ_sxnet		1L,3L,101L,1L,4L,1L
        +
        +#define SN_X500		"X500"
        +#define LN_X500		"directory services (X.500)"
        +#define NID_X500		11
        +#define OBJ_X500		2L,5L
        +
        +#define SN_X509		"X509"
        +#define NID_X509		12
        +#define OBJ_X509		OBJ_X500,4L
        +
        +#define SN_commonName		"CN"
        +#define LN_commonName		"commonName"
        +#define NID_commonName		13
        +#define OBJ_commonName		OBJ_X509,3L
        +
        +#define SN_surname		"SN"
        +#define LN_surname		"surname"
        +#define NID_surname		100
        +#define OBJ_surname		OBJ_X509,4L
        +
        +#define LN_serialNumber		"serialNumber"
        +#define NID_serialNumber		105
        +#define OBJ_serialNumber		OBJ_X509,5L
        +
        +#define SN_countryName		"C"
        +#define LN_countryName		"countryName"
        +#define NID_countryName		14
        +#define OBJ_countryName		OBJ_X509,6L
        +
        +#define SN_localityName		"L"
        +#define LN_localityName		"localityName"
        +#define NID_localityName		15
        +#define OBJ_localityName		OBJ_X509,7L
        +
        +#define SN_stateOrProvinceName		"ST"
        +#define LN_stateOrProvinceName		"stateOrProvinceName"
        +#define NID_stateOrProvinceName		16
        +#define OBJ_stateOrProvinceName		OBJ_X509,8L
        +
        +#define SN_streetAddress		"street"
        +#define LN_streetAddress		"streetAddress"
        +#define NID_streetAddress		660
        +#define OBJ_streetAddress		OBJ_X509,9L
        +
        +#define SN_organizationName		"O"
        +#define LN_organizationName		"organizationName"
        +#define NID_organizationName		17
        +#define OBJ_organizationName		OBJ_X509,10L
        +
        +#define SN_organizationalUnitName		"OU"
        +#define LN_organizationalUnitName		"organizationalUnitName"
        +#define NID_organizationalUnitName		18
        +#define OBJ_organizationalUnitName		OBJ_X509,11L
        +
        +#define SN_title		"title"
        +#define LN_title		"title"
        +#define NID_title		106
        +#define OBJ_title		OBJ_X509,12L
        +
        +#define LN_description		"description"
        +#define NID_description		107
        +#define OBJ_description		OBJ_X509,13L
        +
        +#define LN_searchGuide		"searchGuide"
        +#define NID_searchGuide		859
        +#define OBJ_searchGuide		OBJ_X509,14L
        +
        +#define LN_businessCategory		"businessCategory"
        +#define NID_businessCategory		860
        +#define OBJ_businessCategory		OBJ_X509,15L
        +
        +#define LN_postalAddress		"postalAddress"
        +#define NID_postalAddress		861
        +#define OBJ_postalAddress		OBJ_X509,16L
        +
        +#define LN_postalCode		"postalCode"
        +#define NID_postalCode		661
        +#define OBJ_postalCode		OBJ_X509,17L
        +
        +#define LN_postOfficeBox		"postOfficeBox"
        +#define NID_postOfficeBox		862
        +#define OBJ_postOfficeBox		OBJ_X509,18L
        +
        +#define LN_physicalDeliveryOfficeName		"physicalDeliveryOfficeName"
        +#define NID_physicalDeliveryOfficeName		863
        +#define OBJ_physicalDeliveryOfficeName		OBJ_X509,19L
        +
        +#define LN_telephoneNumber		"telephoneNumber"
        +#define NID_telephoneNumber		864
        +#define OBJ_telephoneNumber		OBJ_X509,20L
        +
        +#define LN_telexNumber		"telexNumber"
        +#define NID_telexNumber		865
        +#define OBJ_telexNumber		OBJ_X509,21L
        +
        +#define LN_teletexTerminalIdentifier		"teletexTerminalIdentifier"
        +#define NID_teletexTerminalIdentifier		866
        +#define OBJ_teletexTerminalIdentifier		OBJ_X509,22L
        +
        +#define LN_facsimileTelephoneNumber		"facsimileTelephoneNumber"
        +#define NID_facsimileTelephoneNumber		867
        +#define OBJ_facsimileTelephoneNumber		OBJ_X509,23L
        +
        +#define LN_x121Address		"x121Address"
        +#define NID_x121Address		868
        +#define OBJ_x121Address		OBJ_X509,24L
        +
        +#define LN_internationaliSDNNumber		"internationaliSDNNumber"
        +#define NID_internationaliSDNNumber		869
        +#define OBJ_internationaliSDNNumber		OBJ_X509,25L
        +
        +#define LN_registeredAddress		"registeredAddress"
        +#define NID_registeredAddress		870
        +#define OBJ_registeredAddress		OBJ_X509,26L
        +
        +#define LN_destinationIndicator		"destinationIndicator"
        +#define NID_destinationIndicator		871
        +#define OBJ_destinationIndicator		OBJ_X509,27L
        +
        +#define LN_preferredDeliveryMethod		"preferredDeliveryMethod"
        +#define NID_preferredDeliveryMethod		872
        +#define OBJ_preferredDeliveryMethod		OBJ_X509,28L
        +
        +#define LN_presentationAddress		"presentationAddress"
        +#define NID_presentationAddress		873
        +#define OBJ_presentationAddress		OBJ_X509,29L
        +
        +#define LN_supportedApplicationContext		"supportedApplicationContext"
        +#define NID_supportedApplicationContext		874
        +#define OBJ_supportedApplicationContext		OBJ_X509,30L
        +
        +#define SN_member		"member"
        +#define NID_member		875
        +#define OBJ_member		OBJ_X509,31L
        +
        +#define SN_owner		"owner"
        +#define NID_owner		876
        +#define OBJ_owner		OBJ_X509,32L
        +
        +#define LN_roleOccupant		"roleOccupant"
        +#define NID_roleOccupant		877
        +#define OBJ_roleOccupant		OBJ_X509,33L
        +
        +#define SN_seeAlso		"seeAlso"
        +#define NID_seeAlso		878
        +#define OBJ_seeAlso		OBJ_X509,34L
        +
        +#define LN_userPassword		"userPassword"
        +#define NID_userPassword		879
        +#define OBJ_userPassword		OBJ_X509,35L
        +
        +#define LN_userCertificate		"userCertificate"
        +#define NID_userCertificate		880
        +#define OBJ_userCertificate		OBJ_X509,36L
        +
        +#define LN_cACertificate		"cACertificate"
        +#define NID_cACertificate		881
        +#define OBJ_cACertificate		OBJ_X509,37L
        +
        +#define LN_authorityRevocationList		"authorityRevocationList"
        +#define NID_authorityRevocationList		882
        +#define OBJ_authorityRevocationList		OBJ_X509,38L
        +
        +#define LN_certificateRevocationList		"certificateRevocationList"
        +#define NID_certificateRevocationList		883
        +#define OBJ_certificateRevocationList		OBJ_X509,39L
        +
        +#define LN_crossCertificatePair		"crossCertificatePair"
        +#define NID_crossCertificatePair		884
        +#define OBJ_crossCertificatePair		OBJ_X509,40L
        +
        +#define SN_name		"name"
        +#define LN_name		"name"
        +#define NID_name		173
        +#define OBJ_name		OBJ_X509,41L
        +
        +#define SN_givenName		"GN"
        +#define LN_givenName		"givenName"
        +#define NID_givenName		99
        +#define OBJ_givenName		OBJ_X509,42L
        +
        +#define SN_initials		"initials"
        +#define LN_initials		"initials"
        +#define NID_initials		101
        +#define OBJ_initials		OBJ_X509,43L
        +
        +#define LN_generationQualifier		"generationQualifier"
        +#define NID_generationQualifier		509
        +#define OBJ_generationQualifier		OBJ_X509,44L
        +
        +#define LN_x500UniqueIdentifier		"x500UniqueIdentifier"
        +#define NID_x500UniqueIdentifier		503
        +#define OBJ_x500UniqueIdentifier		OBJ_X509,45L
        +
        +#define SN_dnQualifier		"dnQualifier"
        +#define LN_dnQualifier		"dnQualifier"
        +#define NID_dnQualifier		174
        +#define OBJ_dnQualifier		OBJ_X509,46L
        +
        +#define LN_enhancedSearchGuide		"enhancedSearchGuide"
        +#define NID_enhancedSearchGuide		885
        +#define OBJ_enhancedSearchGuide		OBJ_X509,47L
        +
        +#define LN_protocolInformation		"protocolInformation"
        +#define NID_protocolInformation		886
        +#define OBJ_protocolInformation		OBJ_X509,48L
        +
        +#define LN_distinguishedName		"distinguishedName"
        +#define NID_distinguishedName		887
        +#define OBJ_distinguishedName		OBJ_X509,49L
        +
        +#define LN_uniqueMember		"uniqueMember"
        +#define NID_uniqueMember		888
        +#define OBJ_uniqueMember		OBJ_X509,50L
        +
        +#define LN_houseIdentifier		"houseIdentifier"
        +#define NID_houseIdentifier		889
        +#define OBJ_houseIdentifier		OBJ_X509,51L
        +
        +#define LN_supportedAlgorithms		"supportedAlgorithms"
        +#define NID_supportedAlgorithms		890
        +#define OBJ_supportedAlgorithms		OBJ_X509,52L
        +
        +#define LN_deltaRevocationList		"deltaRevocationList"
        +#define NID_deltaRevocationList		891
        +#define OBJ_deltaRevocationList		OBJ_X509,53L
        +
        +#define SN_dmdName		"dmdName"
        +#define NID_dmdName		892
        +#define OBJ_dmdName		OBJ_X509,54L
        +
        +#define LN_pseudonym		"pseudonym"
        +#define NID_pseudonym		510
        +#define OBJ_pseudonym		OBJ_X509,65L
        +
        +#define SN_role		"role"
        +#define LN_role		"role"
        +#define NID_role		400
        +#define OBJ_role		OBJ_X509,72L
        +
        +#define SN_X500algorithms		"X500algorithms"
        +#define LN_X500algorithms		"directory services - algorithms"
        +#define NID_X500algorithms		378
        +#define OBJ_X500algorithms		OBJ_X500,8L
        +
        +#define SN_rsa		"RSA"
        +#define LN_rsa		"rsa"
        +#define NID_rsa		19
        +#define OBJ_rsa		OBJ_X500algorithms,1L,1L
        +
        +#define SN_mdc2WithRSA		"RSA-MDC2"
        +#define LN_mdc2WithRSA		"mdc2WithRSA"
        +#define NID_mdc2WithRSA		96
        +#define OBJ_mdc2WithRSA		OBJ_X500algorithms,3L,100L
        +
        +#define SN_mdc2		"MDC2"
        +#define LN_mdc2		"mdc2"
        +#define NID_mdc2		95
        +#define OBJ_mdc2		OBJ_X500algorithms,3L,101L
        +
        +#define SN_id_ce		"id-ce"
        +#define NID_id_ce		81
        +#define OBJ_id_ce		OBJ_X500,29L
        +
        +#define SN_subject_directory_attributes		"subjectDirectoryAttributes"
        +#define LN_subject_directory_attributes		"X509v3 Subject Directory Attributes"
        +#define NID_subject_directory_attributes		769
        +#define OBJ_subject_directory_attributes		OBJ_id_ce,9L
        +
        +#define SN_subject_key_identifier		"subjectKeyIdentifier"
        +#define LN_subject_key_identifier		"X509v3 Subject Key Identifier"
        +#define NID_subject_key_identifier		82
        +#define OBJ_subject_key_identifier		OBJ_id_ce,14L
        +
        +#define SN_key_usage		"keyUsage"
        +#define LN_key_usage		"X509v3 Key Usage"
        +#define NID_key_usage		83
        +#define OBJ_key_usage		OBJ_id_ce,15L
        +
        +#define SN_private_key_usage_period		"privateKeyUsagePeriod"
        +#define LN_private_key_usage_period		"X509v3 Private Key Usage Period"
        +#define NID_private_key_usage_period		84
        +#define OBJ_private_key_usage_period		OBJ_id_ce,16L
        +
        +#define SN_subject_alt_name		"subjectAltName"
        +#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
        +#define NID_subject_alt_name		85
        +#define OBJ_subject_alt_name		OBJ_id_ce,17L
        +
        +#define SN_issuer_alt_name		"issuerAltName"
        +#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
        +#define NID_issuer_alt_name		86
        +#define OBJ_issuer_alt_name		OBJ_id_ce,18L
        +
        +#define SN_basic_constraints		"basicConstraints"
        +#define LN_basic_constraints		"X509v3 Basic Constraints"
        +#define NID_basic_constraints		87
        +#define OBJ_basic_constraints		OBJ_id_ce,19L
        +
        +#define SN_crl_number		"crlNumber"
        +#define LN_crl_number		"X509v3 CRL Number"
        +#define NID_crl_number		88
        +#define OBJ_crl_number		OBJ_id_ce,20L
        +
        +#define SN_crl_reason		"CRLReason"
        +#define LN_crl_reason		"X509v3 CRL Reason Code"
        +#define NID_crl_reason		141
        +#define OBJ_crl_reason		OBJ_id_ce,21L
        +
        +#define SN_invalidity_date		"invalidityDate"
        +#define LN_invalidity_date		"Invalidity Date"
        +#define NID_invalidity_date		142
        +#define OBJ_invalidity_date		OBJ_id_ce,24L
        +
        +#define SN_delta_crl		"deltaCRL"
        +#define LN_delta_crl		"X509v3 Delta CRL Indicator"
        +#define NID_delta_crl		140
        +#define OBJ_delta_crl		OBJ_id_ce,27L
        +
        +#define SN_issuing_distribution_point		"issuingDistributionPoint"
        +#define LN_issuing_distribution_point		"X509v3 Issuing Distrubution Point"
        +#define NID_issuing_distribution_point		770
        +#define OBJ_issuing_distribution_point		OBJ_id_ce,28L
        +
        +#define SN_certificate_issuer		"certificateIssuer"
        +#define LN_certificate_issuer		"X509v3 Certificate Issuer"
        +#define NID_certificate_issuer		771
        +#define OBJ_certificate_issuer		OBJ_id_ce,29L
        +
        +#define SN_name_constraints		"nameConstraints"
        +#define LN_name_constraints		"X509v3 Name Constraints"
        +#define NID_name_constraints		666
        +#define OBJ_name_constraints		OBJ_id_ce,30L
        +
        +#define SN_crl_distribution_points		"crlDistributionPoints"
        +#define LN_crl_distribution_points		"X509v3 CRL Distribution Points"
        +#define NID_crl_distribution_points		103
        +#define OBJ_crl_distribution_points		OBJ_id_ce,31L
        +
        +#define SN_certificate_policies		"certificatePolicies"
        +#define LN_certificate_policies		"X509v3 Certificate Policies"
        +#define NID_certificate_policies		89
        +#define OBJ_certificate_policies		OBJ_id_ce,32L
        +
        +#define SN_any_policy		"anyPolicy"
        +#define LN_any_policy		"X509v3 Any Policy"
        +#define NID_any_policy		746
        +#define OBJ_any_policy		OBJ_certificate_policies,0L
        +
        +#define SN_policy_mappings		"policyMappings"
        +#define LN_policy_mappings		"X509v3 Policy Mappings"
        +#define NID_policy_mappings		747
        +#define OBJ_policy_mappings		OBJ_id_ce,33L
        +
        +#define SN_authority_key_identifier		"authorityKeyIdentifier"
        +#define LN_authority_key_identifier		"X509v3 Authority Key Identifier"
        +#define NID_authority_key_identifier		90
        +#define OBJ_authority_key_identifier		OBJ_id_ce,35L
        +
        +#define SN_policy_constraints		"policyConstraints"
        +#define LN_policy_constraints		"X509v3 Policy Constraints"
        +#define NID_policy_constraints		401
        +#define OBJ_policy_constraints		OBJ_id_ce,36L
        +
        +#define SN_ext_key_usage		"extendedKeyUsage"
        +#define LN_ext_key_usage		"X509v3 Extended Key Usage"
        +#define NID_ext_key_usage		126
        +#define OBJ_ext_key_usage		OBJ_id_ce,37L
        +
        +#define SN_freshest_crl		"freshestCRL"
        +#define LN_freshest_crl		"X509v3 Freshest CRL"
        +#define NID_freshest_crl		857
        +#define OBJ_freshest_crl		OBJ_id_ce,46L
        +
        +#define SN_inhibit_any_policy		"inhibitAnyPolicy"
        +#define LN_inhibit_any_policy		"X509v3 Inhibit Any Policy"
        +#define NID_inhibit_any_policy		748
        +#define OBJ_inhibit_any_policy		OBJ_id_ce,54L
        +
        +#define SN_target_information		"targetInformation"
        +#define LN_target_information		"X509v3 AC Targeting"
        +#define NID_target_information		402
        +#define OBJ_target_information		OBJ_id_ce,55L
        +
        +#define SN_no_rev_avail		"noRevAvail"
        +#define LN_no_rev_avail		"X509v3 No Revocation Available"
        +#define NID_no_rev_avail		403
        +#define OBJ_no_rev_avail		OBJ_id_ce,56L
        +
        +#define SN_anyExtendedKeyUsage		"anyExtendedKeyUsage"
        +#define LN_anyExtendedKeyUsage		"Any Extended Key Usage"
        +#define NID_anyExtendedKeyUsage		910
        +#define OBJ_anyExtendedKeyUsage		OBJ_ext_key_usage,0L
        +
        +#define SN_netscape		"Netscape"
        +#define LN_netscape		"Netscape Communications Corp."
        +#define NID_netscape		57
        +#define OBJ_netscape		2L,16L,840L,1L,113730L
        +
        +#define SN_netscape_cert_extension		"nsCertExt"
        +#define LN_netscape_cert_extension		"Netscape Certificate Extension"
        +#define NID_netscape_cert_extension		58
        +#define OBJ_netscape_cert_extension		OBJ_netscape,1L
        +
        +#define SN_netscape_data_type		"nsDataType"
        +#define LN_netscape_data_type		"Netscape Data Type"
        +#define NID_netscape_data_type		59
        +#define OBJ_netscape_data_type		OBJ_netscape,2L
        +
        +#define SN_netscape_cert_type		"nsCertType"
        +#define LN_netscape_cert_type		"Netscape Cert Type"
        +#define NID_netscape_cert_type		71
        +#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
        +
        +#define SN_netscape_base_url		"nsBaseUrl"
        +#define LN_netscape_base_url		"Netscape Base Url"
        +#define NID_netscape_base_url		72
        +#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
        +
        +#define SN_netscape_revocation_url		"nsRevocationUrl"
        +#define LN_netscape_revocation_url		"Netscape Revocation Url"
        +#define NID_netscape_revocation_url		73
        +#define OBJ_netscape_revocation_url		OBJ_netscape_cert_extension,3L
        +
        +#define SN_netscape_ca_revocation_url		"nsCaRevocationUrl"
        +#define LN_netscape_ca_revocation_url		"Netscape CA Revocation Url"
        +#define NID_netscape_ca_revocation_url		74
        +#define OBJ_netscape_ca_revocation_url		OBJ_netscape_cert_extension,4L
        +
        +#define SN_netscape_renewal_url		"nsRenewalUrl"
        +#define LN_netscape_renewal_url		"Netscape Renewal Url"
        +#define NID_netscape_renewal_url		75
        +#define OBJ_netscape_renewal_url		OBJ_netscape_cert_extension,7L
        +
        +#define SN_netscape_ca_policy_url		"nsCaPolicyUrl"
        +#define LN_netscape_ca_policy_url		"Netscape CA Policy Url"
        +#define NID_netscape_ca_policy_url		76
        +#define OBJ_netscape_ca_policy_url		OBJ_netscape_cert_extension,8L
        +
        +#define SN_netscape_ssl_server_name		"nsSslServerName"
        +#define LN_netscape_ssl_server_name		"Netscape SSL Server Name"
        +#define NID_netscape_ssl_server_name		77
        +#define OBJ_netscape_ssl_server_name		OBJ_netscape_cert_extension,12L
        +
        +#define SN_netscape_comment		"nsComment"
        +#define LN_netscape_comment		"Netscape Comment"
        +#define NID_netscape_comment		78
        +#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
        +
        +#define SN_netscape_cert_sequence		"nsCertSequence"
        +#define LN_netscape_cert_sequence		"Netscape Certificate Sequence"
        +#define NID_netscape_cert_sequence		79
        +#define OBJ_netscape_cert_sequence		OBJ_netscape_data_type,5L
        +
        +#define SN_ns_sgc		"nsSGC"
        +#define LN_ns_sgc		"Netscape Server Gated Crypto"
        +#define NID_ns_sgc		139
        +#define OBJ_ns_sgc		OBJ_netscape,4L,1L
        +
        +#define SN_org		"ORG"
        +#define LN_org		"org"
        +#define NID_org		379
        +#define OBJ_org		OBJ_iso,3L
        +
        +#define SN_dod		"DOD"
        +#define LN_dod		"dod"
        +#define NID_dod		380
        +#define OBJ_dod		OBJ_org,6L
        +
        +#define SN_iana		"IANA"
        +#define LN_iana		"iana"
        +#define NID_iana		381
        +#define OBJ_iana		OBJ_dod,1L
        +
        +#define OBJ_internet		OBJ_iana
        +
        +#define SN_Directory		"directory"
        +#define LN_Directory		"Directory"
        +#define NID_Directory		382
        +#define OBJ_Directory		OBJ_internet,1L
        +
        +#define SN_Management		"mgmt"
        +#define LN_Management		"Management"
        +#define NID_Management		383
        +#define OBJ_Management		OBJ_internet,2L
        +
        +#define SN_Experimental		"experimental"
        +#define LN_Experimental		"Experimental"
        +#define NID_Experimental		384
        +#define OBJ_Experimental		OBJ_internet,3L
        +
        +#define SN_Private		"private"
        +#define LN_Private		"Private"
        +#define NID_Private		385
        +#define OBJ_Private		OBJ_internet,4L
        +
        +#define SN_Security		"security"
        +#define LN_Security		"Security"
        +#define NID_Security		386
        +#define OBJ_Security		OBJ_internet,5L
        +
        +#define SN_SNMPv2		"snmpv2"
        +#define LN_SNMPv2		"SNMPv2"
        +#define NID_SNMPv2		387
        +#define OBJ_SNMPv2		OBJ_internet,6L
        +
        +#define LN_Mail		"Mail"
        +#define NID_Mail		388
        +#define OBJ_Mail		OBJ_internet,7L
        +
        +#define SN_Enterprises		"enterprises"
        +#define LN_Enterprises		"Enterprises"
        +#define NID_Enterprises		389
        +#define OBJ_Enterprises		OBJ_Private,1L
        +
        +#define SN_dcObject		"dcobject"
        +#define LN_dcObject		"dcObject"
        +#define NID_dcObject		390
        +#define OBJ_dcObject		OBJ_Enterprises,1466L,344L
        +
        +#define SN_mime_mhs		"mime-mhs"
        +#define LN_mime_mhs		"MIME MHS"
        +#define NID_mime_mhs		504
        +#define OBJ_mime_mhs		OBJ_Mail,1L
        +
        +#define SN_mime_mhs_headings		"mime-mhs-headings"
        +#define LN_mime_mhs_headings		"mime-mhs-headings"
        +#define NID_mime_mhs_headings		505
        +#define OBJ_mime_mhs_headings		OBJ_mime_mhs,1L
        +
        +#define SN_mime_mhs_bodies		"mime-mhs-bodies"
        +#define LN_mime_mhs_bodies		"mime-mhs-bodies"
        +#define NID_mime_mhs_bodies		506
        +#define OBJ_mime_mhs_bodies		OBJ_mime_mhs,2L
        +
        +#define SN_id_hex_partial_message		"id-hex-partial-message"
        +#define LN_id_hex_partial_message		"id-hex-partial-message"
        +#define NID_id_hex_partial_message		507
        +#define OBJ_id_hex_partial_message		OBJ_mime_mhs_headings,1L
        +
        +#define SN_id_hex_multipart_message		"id-hex-multipart-message"
        +#define LN_id_hex_multipart_message		"id-hex-multipart-message"
        +#define NID_id_hex_multipart_message		508
        +#define OBJ_id_hex_multipart_message		OBJ_mime_mhs_headings,2L
        +
        +#define SN_rle_compression		"RLE"
        +#define LN_rle_compression		"run length compression"
        +#define NID_rle_compression		124
        +#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
        +
        +#define SN_zlib_compression		"ZLIB"
        +#define LN_zlib_compression		"zlib compression"
        +#define NID_zlib_compression		125
        +#define OBJ_zlib_compression		OBJ_id_smime_alg,8L
        +
        +#define OBJ_csor		2L,16L,840L,1L,101L,3L
        +
        +#define OBJ_nistAlgorithms		OBJ_csor,4L
        +
        +#define OBJ_aes		OBJ_nistAlgorithms,1L
        +
        +#define SN_aes_128_ecb		"AES-128-ECB"
        +#define LN_aes_128_ecb		"aes-128-ecb"
        +#define NID_aes_128_ecb		418
        +#define OBJ_aes_128_ecb		OBJ_aes,1L
        +
        +#define SN_aes_128_cbc		"AES-128-CBC"
        +#define LN_aes_128_cbc		"aes-128-cbc"
        +#define NID_aes_128_cbc		419
        +#define OBJ_aes_128_cbc		OBJ_aes,2L
        +
        +#define SN_aes_128_ofb128		"AES-128-OFB"
        +#define LN_aes_128_ofb128		"aes-128-ofb"
        +#define NID_aes_128_ofb128		420
        +#define OBJ_aes_128_ofb128		OBJ_aes,3L
        +
        +#define SN_aes_128_cfb128		"AES-128-CFB"
        +#define LN_aes_128_cfb128		"aes-128-cfb"
        +#define NID_aes_128_cfb128		421
        +#define OBJ_aes_128_cfb128		OBJ_aes,4L
        +
        +#define SN_id_aes128_wrap		"id-aes128-wrap"
        +#define NID_id_aes128_wrap		788
        +#define OBJ_id_aes128_wrap		OBJ_aes,5L
        +
        +#define SN_aes_128_gcm		"id-aes128-GCM"
        +#define LN_aes_128_gcm		"aes-128-gcm"
        +#define NID_aes_128_gcm		895
        +#define OBJ_aes_128_gcm		OBJ_aes,6L
        +
        +#define SN_aes_128_ccm		"id-aes128-CCM"
        +#define LN_aes_128_ccm		"aes-128-ccm"
        +#define NID_aes_128_ccm		896
        +#define OBJ_aes_128_ccm		OBJ_aes,7L
        +
        +#define SN_id_aes128_wrap_pad		"id-aes128-wrap-pad"
        +#define NID_id_aes128_wrap_pad		897
        +#define OBJ_id_aes128_wrap_pad		OBJ_aes,8L
        +
        +#define SN_aes_192_ecb		"AES-192-ECB"
        +#define LN_aes_192_ecb		"aes-192-ecb"
        +#define NID_aes_192_ecb		422
        +#define OBJ_aes_192_ecb		OBJ_aes,21L
        +
        +#define SN_aes_192_cbc		"AES-192-CBC"
        +#define LN_aes_192_cbc		"aes-192-cbc"
        +#define NID_aes_192_cbc		423
        +#define OBJ_aes_192_cbc		OBJ_aes,22L
        +
        +#define SN_aes_192_ofb128		"AES-192-OFB"
        +#define LN_aes_192_ofb128		"aes-192-ofb"
        +#define NID_aes_192_ofb128		424
        +#define OBJ_aes_192_ofb128		OBJ_aes,23L
        +
        +#define SN_aes_192_cfb128		"AES-192-CFB"
        +#define LN_aes_192_cfb128		"aes-192-cfb"
        +#define NID_aes_192_cfb128		425
        +#define OBJ_aes_192_cfb128		OBJ_aes,24L
        +
        +#define SN_id_aes192_wrap		"id-aes192-wrap"
        +#define NID_id_aes192_wrap		789
        +#define OBJ_id_aes192_wrap		OBJ_aes,25L
        +
        +#define SN_aes_192_gcm		"id-aes192-GCM"
        +#define LN_aes_192_gcm		"aes-192-gcm"
        +#define NID_aes_192_gcm		898
        +#define OBJ_aes_192_gcm		OBJ_aes,26L
        +
        +#define SN_aes_192_ccm		"id-aes192-CCM"
        +#define LN_aes_192_ccm		"aes-192-ccm"
        +#define NID_aes_192_ccm		899
        +#define OBJ_aes_192_ccm		OBJ_aes,27L
        +
        +#define SN_id_aes192_wrap_pad		"id-aes192-wrap-pad"
        +#define NID_id_aes192_wrap_pad		900
        +#define OBJ_id_aes192_wrap_pad		OBJ_aes,28L
        +
        +#define SN_aes_256_ecb		"AES-256-ECB"
        +#define LN_aes_256_ecb		"aes-256-ecb"
        +#define NID_aes_256_ecb		426
        +#define OBJ_aes_256_ecb		OBJ_aes,41L
        +
        +#define SN_aes_256_cbc		"AES-256-CBC"
        +#define LN_aes_256_cbc		"aes-256-cbc"
        +#define NID_aes_256_cbc		427
        +#define OBJ_aes_256_cbc		OBJ_aes,42L
        +
        +#define SN_aes_256_ofb128		"AES-256-OFB"
        +#define LN_aes_256_ofb128		"aes-256-ofb"
        +#define NID_aes_256_ofb128		428
        +#define OBJ_aes_256_ofb128		OBJ_aes,43L
        +
        +#define SN_aes_256_cfb128		"AES-256-CFB"
        +#define LN_aes_256_cfb128		"aes-256-cfb"
        +#define NID_aes_256_cfb128		429
        +#define OBJ_aes_256_cfb128		OBJ_aes,44L
        +
        +#define SN_id_aes256_wrap		"id-aes256-wrap"
        +#define NID_id_aes256_wrap		790
        +#define OBJ_id_aes256_wrap		OBJ_aes,45L
        +
        +#define SN_aes_256_gcm		"id-aes256-GCM"
        +#define LN_aes_256_gcm		"aes-256-gcm"
        +#define NID_aes_256_gcm		901
        +#define OBJ_aes_256_gcm		OBJ_aes,46L
        +
        +#define SN_aes_256_ccm		"id-aes256-CCM"
        +#define LN_aes_256_ccm		"aes-256-ccm"
        +#define NID_aes_256_ccm		902
        +#define OBJ_aes_256_ccm		OBJ_aes,47L
        +
        +#define SN_id_aes256_wrap_pad		"id-aes256-wrap-pad"
        +#define NID_id_aes256_wrap_pad		903
        +#define OBJ_id_aes256_wrap_pad		OBJ_aes,48L
        +
        +#define SN_aes_128_cfb1		"AES-128-CFB1"
        +#define LN_aes_128_cfb1		"aes-128-cfb1"
        +#define NID_aes_128_cfb1		650
        +
        +#define SN_aes_192_cfb1		"AES-192-CFB1"
        +#define LN_aes_192_cfb1		"aes-192-cfb1"
        +#define NID_aes_192_cfb1		651
        +
        +#define SN_aes_256_cfb1		"AES-256-CFB1"
        +#define LN_aes_256_cfb1		"aes-256-cfb1"
        +#define NID_aes_256_cfb1		652
        +
        +#define SN_aes_128_cfb8		"AES-128-CFB8"
        +#define LN_aes_128_cfb8		"aes-128-cfb8"
        +#define NID_aes_128_cfb8		653
        +
        +#define SN_aes_192_cfb8		"AES-192-CFB8"
        +#define LN_aes_192_cfb8		"aes-192-cfb8"
        +#define NID_aes_192_cfb8		654
        +
        +#define SN_aes_256_cfb8		"AES-256-CFB8"
        +#define LN_aes_256_cfb8		"aes-256-cfb8"
        +#define NID_aes_256_cfb8		655
        +
        +#define SN_aes_128_ctr		"AES-128-CTR"
        +#define LN_aes_128_ctr		"aes-128-ctr"
        +#define NID_aes_128_ctr		904
        +
        +#define SN_aes_192_ctr		"AES-192-CTR"
        +#define LN_aes_192_ctr		"aes-192-ctr"
        +#define NID_aes_192_ctr		905
        +
        +#define SN_aes_256_ctr		"AES-256-CTR"
        +#define LN_aes_256_ctr		"aes-256-ctr"
        +#define NID_aes_256_ctr		906
        +
        +#define SN_aes_128_xts		"AES-128-XTS"
        +#define LN_aes_128_xts		"aes-128-xts"
        +#define NID_aes_128_xts		913
        +
        +#define SN_aes_256_xts		"AES-256-XTS"
        +#define LN_aes_256_xts		"aes-256-xts"
        +#define NID_aes_256_xts		914
        +
        +#define SN_des_cfb1		"DES-CFB1"
        +#define LN_des_cfb1		"des-cfb1"
        +#define NID_des_cfb1		656
        +
        +#define SN_des_cfb8		"DES-CFB8"
        +#define LN_des_cfb8		"des-cfb8"
        +#define NID_des_cfb8		657
        +
        +#define SN_des_ede3_cfb1		"DES-EDE3-CFB1"
        +#define LN_des_ede3_cfb1		"des-ede3-cfb1"
        +#define NID_des_ede3_cfb1		658
        +
        +#define SN_des_ede3_cfb8		"DES-EDE3-CFB8"
        +#define LN_des_ede3_cfb8		"des-ede3-cfb8"
        +#define NID_des_ede3_cfb8		659
        +
        +#define OBJ_nist_hashalgs		OBJ_nistAlgorithms,2L
        +
        +#define SN_sha256		"SHA256"
        +#define LN_sha256		"sha256"
        +#define NID_sha256		672
        +#define OBJ_sha256		OBJ_nist_hashalgs,1L
        +
        +#define SN_sha384		"SHA384"
        +#define LN_sha384		"sha384"
        +#define NID_sha384		673
        +#define OBJ_sha384		OBJ_nist_hashalgs,2L
        +
        +#define SN_sha512		"SHA512"
        +#define LN_sha512		"sha512"
        +#define NID_sha512		674
        +#define OBJ_sha512		OBJ_nist_hashalgs,3L
        +
        +#define SN_sha224		"SHA224"
        +#define LN_sha224		"sha224"
        +#define NID_sha224		675
        +#define OBJ_sha224		OBJ_nist_hashalgs,4L
        +
        +#define OBJ_dsa_with_sha2		OBJ_nistAlgorithms,3L
        +
        +#define SN_dsa_with_SHA224		"dsa_with_SHA224"
        +#define NID_dsa_with_SHA224		802
        +#define OBJ_dsa_with_SHA224		OBJ_dsa_with_sha2,1L
        +
        +#define SN_dsa_with_SHA256		"dsa_with_SHA256"
        +#define NID_dsa_with_SHA256		803
        +#define OBJ_dsa_with_SHA256		OBJ_dsa_with_sha2,2L
        +
        +#define SN_hold_instruction_code		"holdInstructionCode"
        +#define LN_hold_instruction_code		"Hold Instruction Code"
        +#define NID_hold_instruction_code		430
        +#define OBJ_hold_instruction_code		OBJ_id_ce,23L
        +
        +#define OBJ_holdInstruction		OBJ_X9_57,2L
        +
        +#define SN_hold_instruction_none		"holdInstructionNone"
        +#define LN_hold_instruction_none		"Hold Instruction None"
        +#define NID_hold_instruction_none		431
        +#define OBJ_hold_instruction_none		OBJ_holdInstruction,1L
        +
        +#define SN_hold_instruction_call_issuer		"holdInstructionCallIssuer"
        +#define LN_hold_instruction_call_issuer		"Hold Instruction Call Issuer"
        +#define NID_hold_instruction_call_issuer		432
        +#define OBJ_hold_instruction_call_issuer		OBJ_holdInstruction,2L
        +
        +#define SN_hold_instruction_reject		"holdInstructionReject"
        +#define LN_hold_instruction_reject		"Hold Instruction Reject"
        +#define NID_hold_instruction_reject		433
        +#define OBJ_hold_instruction_reject		OBJ_holdInstruction,3L
        +
        +#define SN_data		"data"
        +#define NID_data		434
        +#define OBJ_data		OBJ_itu_t,9L
        +
        +#define SN_pss		"pss"
        +#define NID_pss		435
        +#define OBJ_pss		OBJ_data,2342L
        +
        +#define SN_ucl		"ucl"
        +#define NID_ucl		436
        +#define OBJ_ucl		OBJ_pss,19200300L
        +
        +#define SN_pilot		"pilot"
        +#define NID_pilot		437
        +#define OBJ_pilot		OBJ_ucl,100L
        +
        +#define LN_pilotAttributeType		"pilotAttributeType"
        +#define NID_pilotAttributeType		438
        +#define OBJ_pilotAttributeType		OBJ_pilot,1L
        +
        +#define LN_pilotAttributeSyntax		"pilotAttributeSyntax"
        +#define NID_pilotAttributeSyntax		439
        +#define OBJ_pilotAttributeSyntax		OBJ_pilot,3L
        +
        +#define LN_pilotObjectClass		"pilotObjectClass"
        +#define NID_pilotObjectClass		440
        +#define OBJ_pilotObjectClass		OBJ_pilot,4L
        +
        +#define LN_pilotGroups		"pilotGroups"
        +#define NID_pilotGroups		441
        +#define OBJ_pilotGroups		OBJ_pilot,10L
        +
        +#define LN_iA5StringSyntax		"iA5StringSyntax"
        +#define NID_iA5StringSyntax		442
        +#define OBJ_iA5StringSyntax		OBJ_pilotAttributeSyntax,4L
        +
        +#define LN_caseIgnoreIA5StringSyntax		"caseIgnoreIA5StringSyntax"
        +#define NID_caseIgnoreIA5StringSyntax		443
        +#define OBJ_caseIgnoreIA5StringSyntax		OBJ_pilotAttributeSyntax,5L
        +
        +#define LN_pilotObject		"pilotObject"
        +#define NID_pilotObject		444
        +#define OBJ_pilotObject		OBJ_pilotObjectClass,3L
        +
        +#define LN_pilotPerson		"pilotPerson"
        +#define NID_pilotPerson		445
        +#define OBJ_pilotPerson		OBJ_pilotObjectClass,4L
        +
        +#define SN_account		"account"
        +#define NID_account		446
        +#define OBJ_account		OBJ_pilotObjectClass,5L
        +
        +#define SN_document		"document"
        +#define NID_document		447
        +#define OBJ_document		OBJ_pilotObjectClass,6L
        +
        +#define SN_room		"room"
        +#define NID_room		448
        +#define OBJ_room		OBJ_pilotObjectClass,7L
        +
        +#define LN_documentSeries		"documentSeries"
        +#define NID_documentSeries		449
        +#define OBJ_documentSeries		OBJ_pilotObjectClass,9L
        +
        +#define SN_Domain		"domain"
        +#define LN_Domain		"Domain"
        +#define NID_Domain		392
        +#define OBJ_Domain		OBJ_pilotObjectClass,13L
        +
        +#define LN_rFC822localPart		"rFC822localPart"
        +#define NID_rFC822localPart		450
        +#define OBJ_rFC822localPart		OBJ_pilotObjectClass,14L
        +
        +#define LN_dNSDomain		"dNSDomain"
        +#define NID_dNSDomain		451
        +#define OBJ_dNSDomain		OBJ_pilotObjectClass,15L
        +
        +#define LN_domainRelatedObject		"domainRelatedObject"
        +#define NID_domainRelatedObject		452
        +#define OBJ_domainRelatedObject		OBJ_pilotObjectClass,17L
        +
        +#define LN_friendlyCountry		"friendlyCountry"
        +#define NID_friendlyCountry		453
        +#define OBJ_friendlyCountry		OBJ_pilotObjectClass,18L
        +
        +#define LN_simpleSecurityObject		"simpleSecurityObject"
        +#define NID_simpleSecurityObject		454
        +#define OBJ_simpleSecurityObject		OBJ_pilotObjectClass,19L
        +
        +#define LN_pilotOrganization		"pilotOrganization"
        +#define NID_pilotOrganization		455
        +#define OBJ_pilotOrganization		OBJ_pilotObjectClass,20L
        +
        +#define LN_pilotDSA		"pilotDSA"
        +#define NID_pilotDSA		456
        +#define OBJ_pilotDSA		OBJ_pilotObjectClass,21L
        +
        +#define LN_qualityLabelledData		"qualityLabelledData"
        +#define NID_qualityLabelledData		457
        +#define OBJ_qualityLabelledData		OBJ_pilotObjectClass,22L
        +
        +#define SN_userId		"UID"
        +#define LN_userId		"userId"
        +#define NID_userId		458
        +#define OBJ_userId		OBJ_pilotAttributeType,1L
        +
        +#define LN_textEncodedORAddress		"textEncodedORAddress"
        +#define NID_textEncodedORAddress		459
        +#define OBJ_textEncodedORAddress		OBJ_pilotAttributeType,2L
        +
        +#define SN_rfc822Mailbox		"mail"
        +#define LN_rfc822Mailbox		"rfc822Mailbox"
        +#define NID_rfc822Mailbox		460
        +#define OBJ_rfc822Mailbox		OBJ_pilotAttributeType,3L
        +
        +#define SN_info		"info"
        +#define NID_info		461
        +#define OBJ_info		OBJ_pilotAttributeType,4L
        +
        +#define LN_favouriteDrink		"favouriteDrink"
        +#define NID_favouriteDrink		462
        +#define OBJ_favouriteDrink		OBJ_pilotAttributeType,5L
        +
        +#define LN_roomNumber		"roomNumber"
        +#define NID_roomNumber		463
        +#define OBJ_roomNumber		OBJ_pilotAttributeType,6L
        +
        +#define SN_photo		"photo"
        +#define NID_photo		464
        +#define OBJ_photo		OBJ_pilotAttributeType,7L
        +
        +#define LN_userClass		"userClass"
        +#define NID_userClass		465
        +#define OBJ_userClass		OBJ_pilotAttributeType,8L
        +
        +#define SN_host		"host"
        +#define NID_host		466
        +#define OBJ_host		OBJ_pilotAttributeType,9L
        +
        +#define SN_manager		"manager"
        +#define NID_manager		467
        +#define OBJ_manager		OBJ_pilotAttributeType,10L
        +
        +#define LN_documentIdentifier		"documentIdentifier"
        +#define NID_documentIdentifier		468
        +#define OBJ_documentIdentifier		OBJ_pilotAttributeType,11L
        +
        +#define LN_documentTitle		"documentTitle"
        +#define NID_documentTitle		469
        +#define OBJ_documentTitle		OBJ_pilotAttributeType,12L
        +
        +#define LN_documentVersion		"documentVersion"
        +#define NID_documentVersion		470
        +#define OBJ_documentVersion		OBJ_pilotAttributeType,13L
        +
        +#define LN_documentAuthor		"documentAuthor"
        +#define NID_documentAuthor		471
        +#define OBJ_documentAuthor		OBJ_pilotAttributeType,14L
        +
        +#define LN_documentLocation		"documentLocation"
        +#define NID_documentLocation		472
        +#define OBJ_documentLocation		OBJ_pilotAttributeType,15L
        +
        +#define LN_homeTelephoneNumber		"homeTelephoneNumber"
        +#define NID_homeTelephoneNumber		473
        +#define OBJ_homeTelephoneNumber		OBJ_pilotAttributeType,20L
        +
        +#define SN_secretary		"secretary"
        +#define NID_secretary		474
        +#define OBJ_secretary		OBJ_pilotAttributeType,21L
        +
        +#define LN_otherMailbox		"otherMailbox"
        +#define NID_otherMailbox		475
        +#define OBJ_otherMailbox		OBJ_pilotAttributeType,22L
        +
        +#define LN_lastModifiedTime		"lastModifiedTime"
        +#define NID_lastModifiedTime		476
        +#define OBJ_lastModifiedTime		OBJ_pilotAttributeType,23L
        +
        +#define LN_lastModifiedBy		"lastModifiedBy"
        +#define NID_lastModifiedBy		477
        +#define OBJ_lastModifiedBy		OBJ_pilotAttributeType,24L
        +
        +#define SN_domainComponent		"DC"
        +#define LN_domainComponent		"domainComponent"
        +#define NID_domainComponent		391
        +#define OBJ_domainComponent		OBJ_pilotAttributeType,25L
        +
        +#define LN_aRecord		"aRecord"
        +#define NID_aRecord		478
        +#define OBJ_aRecord		OBJ_pilotAttributeType,26L
        +
        +#define LN_pilotAttributeType27		"pilotAttributeType27"
        +#define NID_pilotAttributeType27		479
        +#define OBJ_pilotAttributeType27		OBJ_pilotAttributeType,27L
        +
        +#define LN_mXRecord		"mXRecord"
        +#define NID_mXRecord		480
        +#define OBJ_mXRecord		OBJ_pilotAttributeType,28L
        +
        +#define LN_nSRecord		"nSRecord"
        +#define NID_nSRecord		481
        +#define OBJ_nSRecord		OBJ_pilotAttributeType,29L
        +
        +#define LN_sOARecord		"sOARecord"
        +#define NID_sOARecord		482
        +#define OBJ_sOARecord		OBJ_pilotAttributeType,30L
        +
        +#define LN_cNAMERecord		"cNAMERecord"
        +#define NID_cNAMERecord		483
        +#define OBJ_cNAMERecord		OBJ_pilotAttributeType,31L
        +
        +#define LN_associatedDomain		"associatedDomain"
        +#define NID_associatedDomain		484
        +#define OBJ_associatedDomain		OBJ_pilotAttributeType,37L
        +
        +#define LN_associatedName		"associatedName"
        +#define NID_associatedName		485
        +#define OBJ_associatedName		OBJ_pilotAttributeType,38L
        +
        +#define LN_homePostalAddress		"homePostalAddress"
        +#define NID_homePostalAddress		486
        +#define OBJ_homePostalAddress		OBJ_pilotAttributeType,39L
        +
        +#define LN_personalTitle		"personalTitle"
        +#define NID_personalTitle		487
        +#define OBJ_personalTitle		OBJ_pilotAttributeType,40L
        +
        +#define LN_mobileTelephoneNumber		"mobileTelephoneNumber"
        +#define NID_mobileTelephoneNumber		488
        +#define OBJ_mobileTelephoneNumber		OBJ_pilotAttributeType,41L
        +
        +#define LN_pagerTelephoneNumber		"pagerTelephoneNumber"
        +#define NID_pagerTelephoneNumber		489
        +#define OBJ_pagerTelephoneNumber		OBJ_pilotAttributeType,42L
        +
        +#define LN_friendlyCountryName		"friendlyCountryName"
        +#define NID_friendlyCountryName		490
        +#define OBJ_friendlyCountryName		OBJ_pilotAttributeType,43L
        +
        +#define LN_organizationalStatus		"organizationalStatus"
        +#define NID_organizationalStatus		491
        +#define OBJ_organizationalStatus		OBJ_pilotAttributeType,45L
        +
        +#define LN_janetMailbox		"janetMailbox"
        +#define NID_janetMailbox		492
        +#define OBJ_janetMailbox		OBJ_pilotAttributeType,46L
        +
        +#define LN_mailPreferenceOption		"mailPreferenceOption"
        +#define NID_mailPreferenceOption		493
        +#define OBJ_mailPreferenceOption		OBJ_pilotAttributeType,47L
        +
        +#define LN_buildingName		"buildingName"
        +#define NID_buildingName		494
        +#define OBJ_buildingName		OBJ_pilotAttributeType,48L
        +
        +#define LN_dSAQuality		"dSAQuality"
        +#define NID_dSAQuality		495
        +#define OBJ_dSAQuality		OBJ_pilotAttributeType,49L
        +
        +#define LN_singleLevelQuality		"singleLevelQuality"
        +#define NID_singleLevelQuality		496
        +#define OBJ_singleLevelQuality		OBJ_pilotAttributeType,50L
        +
        +#define LN_subtreeMinimumQuality		"subtreeMinimumQuality"
        +#define NID_subtreeMinimumQuality		497
        +#define OBJ_subtreeMinimumQuality		OBJ_pilotAttributeType,51L
        +
        +#define LN_subtreeMaximumQuality		"subtreeMaximumQuality"
        +#define NID_subtreeMaximumQuality		498
        +#define OBJ_subtreeMaximumQuality		OBJ_pilotAttributeType,52L
        +
        +#define LN_personalSignature		"personalSignature"
        +#define NID_personalSignature		499
        +#define OBJ_personalSignature		OBJ_pilotAttributeType,53L
        +
        +#define LN_dITRedirect		"dITRedirect"
        +#define NID_dITRedirect		500
        +#define OBJ_dITRedirect		OBJ_pilotAttributeType,54L
        +
        +#define SN_audio		"audio"
        +#define NID_audio		501
        +#define OBJ_audio		OBJ_pilotAttributeType,55L
        +
        +#define LN_documentPublisher		"documentPublisher"
        +#define NID_documentPublisher		502
        +#define OBJ_documentPublisher		OBJ_pilotAttributeType,56L
        +
        +#define SN_id_set		"id-set"
        +#define LN_id_set		"Secure Electronic Transactions"
        +#define NID_id_set		512
        +#define OBJ_id_set		OBJ_international_organizations,42L
        +
        +#define SN_set_ctype		"set-ctype"
        +#define LN_set_ctype		"content types"
        +#define NID_set_ctype		513
        +#define OBJ_set_ctype		OBJ_id_set,0L
        +
        +#define SN_set_msgExt		"set-msgExt"
        +#define LN_set_msgExt		"message extensions"
        +#define NID_set_msgExt		514
        +#define OBJ_set_msgExt		OBJ_id_set,1L
        +
        +#define SN_set_attr		"set-attr"
        +#define NID_set_attr		515
        +#define OBJ_set_attr		OBJ_id_set,3L
        +
        +#define SN_set_policy		"set-policy"
        +#define NID_set_policy		516
        +#define OBJ_set_policy		OBJ_id_set,5L
        +
        +#define SN_set_certExt		"set-certExt"
        +#define LN_set_certExt		"certificate extensions"
        +#define NID_set_certExt		517
        +#define OBJ_set_certExt		OBJ_id_set,7L
        +
        +#define SN_set_brand		"set-brand"
        +#define NID_set_brand		518
        +#define OBJ_set_brand		OBJ_id_set,8L
        +
        +#define SN_setct_PANData		"setct-PANData"
        +#define NID_setct_PANData		519
        +#define OBJ_setct_PANData		OBJ_set_ctype,0L
        +
        +#define SN_setct_PANToken		"setct-PANToken"
        +#define NID_setct_PANToken		520
        +#define OBJ_setct_PANToken		OBJ_set_ctype,1L
        +
        +#define SN_setct_PANOnly		"setct-PANOnly"
        +#define NID_setct_PANOnly		521
        +#define OBJ_setct_PANOnly		OBJ_set_ctype,2L
        +
        +#define SN_setct_OIData		"setct-OIData"
        +#define NID_setct_OIData		522
        +#define OBJ_setct_OIData		OBJ_set_ctype,3L
        +
        +#define SN_setct_PI		"setct-PI"
        +#define NID_setct_PI		523
        +#define OBJ_setct_PI		OBJ_set_ctype,4L
        +
        +#define SN_setct_PIData		"setct-PIData"
        +#define NID_setct_PIData		524
        +#define OBJ_setct_PIData		OBJ_set_ctype,5L
        +
        +#define SN_setct_PIDataUnsigned		"setct-PIDataUnsigned"
        +#define NID_setct_PIDataUnsigned		525
        +#define OBJ_setct_PIDataUnsigned		OBJ_set_ctype,6L
        +
        +#define SN_setct_HODInput		"setct-HODInput"
        +#define NID_setct_HODInput		526
        +#define OBJ_setct_HODInput		OBJ_set_ctype,7L
        +
        +#define SN_setct_AuthResBaggage		"setct-AuthResBaggage"
        +#define NID_setct_AuthResBaggage		527
        +#define OBJ_setct_AuthResBaggage		OBJ_set_ctype,8L
        +
        +#define SN_setct_AuthRevReqBaggage		"setct-AuthRevReqBaggage"
        +#define NID_setct_AuthRevReqBaggage		528
        +#define OBJ_setct_AuthRevReqBaggage		OBJ_set_ctype,9L
        +
        +#define SN_setct_AuthRevResBaggage		"setct-AuthRevResBaggage"
        +#define NID_setct_AuthRevResBaggage		529
        +#define OBJ_setct_AuthRevResBaggage		OBJ_set_ctype,10L
        +
        +#define SN_setct_CapTokenSeq		"setct-CapTokenSeq"
        +#define NID_setct_CapTokenSeq		530
        +#define OBJ_setct_CapTokenSeq		OBJ_set_ctype,11L
        +
        +#define SN_setct_PInitResData		"setct-PInitResData"
        +#define NID_setct_PInitResData		531
        +#define OBJ_setct_PInitResData		OBJ_set_ctype,12L
        +
        +#define SN_setct_PI_TBS		"setct-PI-TBS"
        +#define NID_setct_PI_TBS		532
        +#define OBJ_setct_PI_TBS		OBJ_set_ctype,13L
        +
        +#define SN_setct_PResData		"setct-PResData"
        +#define NID_setct_PResData		533
        +#define OBJ_setct_PResData		OBJ_set_ctype,14L
        +
        +#define SN_setct_AuthReqTBS		"setct-AuthReqTBS"
        +#define NID_setct_AuthReqTBS		534
        +#define OBJ_setct_AuthReqTBS		OBJ_set_ctype,16L
        +
        +#define SN_setct_AuthResTBS		"setct-AuthResTBS"
        +#define NID_setct_AuthResTBS		535
        +#define OBJ_setct_AuthResTBS		OBJ_set_ctype,17L
        +
        +#define SN_setct_AuthResTBSX		"setct-AuthResTBSX"
        +#define NID_setct_AuthResTBSX		536
        +#define OBJ_setct_AuthResTBSX		OBJ_set_ctype,18L
        +
        +#define SN_setct_AuthTokenTBS		"setct-AuthTokenTBS"
        +#define NID_setct_AuthTokenTBS		537
        +#define OBJ_setct_AuthTokenTBS		OBJ_set_ctype,19L
        +
        +#define SN_setct_CapTokenData		"setct-CapTokenData"
        +#define NID_setct_CapTokenData		538
        +#define OBJ_setct_CapTokenData		OBJ_set_ctype,20L
        +
        +#define SN_setct_CapTokenTBS		"setct-CapTokenTBS"
        +#define NID_setct_CapTokenTBS		539
        +#define OBJ_setct_CapTokenTBS		OBJ_set_ctype,21L
        +
        +#define SN_setct_AcqCardCodeMsg		"setct-AcqCardCodeMsg"
        +#define NID_setct_AcqCardCodeMsg		540
        +#define OBJ_setct_AcqCardCodeMsg		OBJ_set_ctype,22L
        +
        +#define SN_setct_AuthRevReqTBS		"setct-AuthRevReqTBS"
        +#define NID_setct_AuthRevReqTBS		541
        +#define OBJ_setct_AuthRevReqTBS		OBJ_set_ctype,23L
        +
        +#define SN_setct_AuthRevResData		"setct-AuthRevResData"
        +#define NID_setct_AuthRevResData		542
        +#define OBJ_setct_AuthRevResData		OBJ_set_ctype,24L
        +
        +#define SN_setct_AuthRevResTBS		"setct-AuthRevResTBS"
        +#define NID_setct_AuthRevResTBS		543
        +#define OBJ_setct_AuthRevResTBS		OBJ_set_ctype,25L
        +
        +#define SN_setct_CapReqTBS		"setct-CapReqTBS"
        +#define NID_setct_CapReqTBS		544
        +#define OBJ_setct_CapReqTBS		OBJ_set_ctype,26L
        +
        +#define SN_setct_CapReqTBSX		"setct-CapReqTBSX"
        +#define NID_setct_CapReqTBSX		545
        +#define OBJ_setct_CapReqTBSX		OBJ_set_ctype,27L
        +
        +#define SN_setct_CapResData		"setct-CapResData"
        +#define NID_setct_CapResData		546
        +#define OBJ_setct_CapResData		OBJ_set_ctype,28L
        +
        +#define SN_setct_CapRevReqTBS		"setct-CapRevReqTBS"
        +#define NID_setct_CapRevReqTBS		547
        +#define OBJ_setct_CapRevReqTBS		OBJ_set_ctype,29L
        +
        +#define SN_setct_CapRevReqTBSX		"setct-CapRevReqTBSX"
        +#define NID_setct_CapRevReqTBSX		548
        +#define OBJ_setct_CapRevReqTBSX		OBJ_set_ctype,30L
        +
        +#define SN_setct_CapRevResData		"setct-CapRevResData"
        +#define NID_setct_CapRevResData		549
        +#define OBJ_setct_CapRevResData		OBJ_set_ctype,31L
        +
        +#define SN_setct_CredReqTBS		"setct-CredReqTBS"
        +#define NID_setct_CredReqTBS		550
        +#define OBJ_setct_CredReqTBS		OBJ_set_ctype,32L
        +
        +#define SN_setct_CredReqTBSX		"setct-CredReqTBSX"
        +#define NID_setct_CredReqTBSX		551
        +#define OBJ_setct_CredReqTBSX		OBJ_set_ctype,33L
        +
        +#define SN_setct_CredResData		"setct-CredResData"
        +#define NID_setct_CredResData		552
        +#define OBJ_setct_CredResData		OBJ_set_ctype,34L
        +
        +#define SN_setct_CredRevReqTBS		"setct-CredRevReqTBS"
        +#define NID_setct_CredRevReqTBS		553
        +#define OBJ_setct_CredRevReqTBS		OBJ_set_ctype,35L
        +
        +#define SN_setct_CredRevReqTBSX		"setct-CredRevReqTBSX"
        +#define NID_setct_CredRevReqTBSX		554
        +#define OBJ_setct_CredRevReqTBSX		OBJ_set_ctype,36L
        +
        +#define SN_setct_CredRevResData		"setct-CredRevResData"
        +#define NID_setct_CredRevResData		555
        +#define OBJ_setct_CredRevResData		OBJ_set_ctype,37L
        +
        +#define SN_setct_PCertReqData		"setct-PCertReqData"
        +#define NID_setct_PCertReqData		556
        +#define OBJ_setct_PCertReqData		OBJ_set_ctype,38L
        +
        +#define SN_setct_PCertResTBS		"setct-PCertResTBS"
        +#define NID_setct_PCertResTBS		557
        +#define OBJ_setct_PCertResTBS		OBJ_set_ctype,39L
        +
        +#define SN_setct_BatchAdminReqData		"setct-BatchAdminReqData"
        +#define NID_setct_BatchAdminReqData		558
        +#define OBJ_setct_BatchAdminReqData		OBJ_set_ctype,40L
        +
        +#define SN_setct_BatchAdminResData		"setct-BatchAdminResData"
        +#define NID_setct_BatchAdminResData		559
        +#define OBJ_setct_BatchAdminResData		OBJ_set_ctype,41L
        +
        +#define SN_setct_CardCInitResTBS		"setct-CardCInitResTBS"
        +#define NID_setct_CardCInitResTBS		560
        +#define OBJ_setct_CardCInitResTBS		OBJ_set_ctype,42L
        +
        +#define SN_setct_MeAqCInitResTBS		"setct-MeAqCInitResTBS"
        +#define NID_setct_MeAqCInitResTBS		561
        +#define OBJ_setct_MeAqCInitResTBS		OBJ_set_ctype,43L
        +
        +#define SN_setct_RegFormResTBS		"setct-RegFormResTBS"
        +#define NID_setct_RegFormResTBS		562
        +#define OBJ_setct_RegFormResTBS		OBJ_set_ctype,44L
        +
        +#define SN_setct_CertReqData		"setct-CertReqData"
        +#define NID_setct_CertReqData		563
        +#define OBJ_setct_CertReqData		OBJ_set_ctype,45L
        +
        +#define SN_setct_CertReqTBS		"setct-CertReqTBS"
        +#define NID_setct_CertReqTBS		564
        +#define OBJ_setct_CertReqTBS		OBJ_set_ctype,46L
        +
        +#define SN_setct_CertResData		"setct-CertResData"
        +#define NID_setct_CertResData		565
        +#define OBJ_setct_CertResData		OBJ_set_ctype,47L
        +
        +#define SN_setct_CertInqReqTBS		"setct-CertInqReqTBS"
        +#define NID_setct_CertInqReqTBS		566
        +#define OBJ_setct_CertInqReqTBS		OBJ_set_ctype,48L
        +
        +#define SN_setct_ErrorTBS		"setct-ErrorTBS"
        +#define NID_setct_ErrorTBS		567
        +#define OBJ_setct_ErrorTBS		OBJ_set_ctype,49L
        +
        +#define SN_setct_PIDualSignedTBE		"setct-PIDualSignedTBE"
        +#define NID_setct_PIDualSignedTBE		568
        +#define OBJ_setct_PIDualSignedTBE		OBJ_set_ctype,50L
        +
        +#define SN_setct_PIUnsignedTBE		"setct-PIUnsignedTBE"
        +#define NID_setct_PIUnsignedTBE		569
        +#define OBJ_setct_PIUnsignedTBE		OBJ_set_ctype,51L
        +
        +#define SN_setct_AuthReqTBE		"setct-AuthReqTBE"
        +#define NID_setct_AuthReqTBE		570
        +#define OBJ_setct_AuthReqTBE		OBJ_set_ctype,52L
        +
        +#define SN_setct_AuthResTBE		"setct-AuthResTBE"
        +#define NID_setct_AuthResTBE		571
        +#define OBJ_setct_AuthResTBE		OBJ_set_ctype,53L
        +
        +#define SN_setct_AuthResTBEX		"setct-AuthResTBEX"
        +#define NID_setct_AuthResTBEX		572
        +#define OBJ_setct_AuthResTBEX		OBJ_set_ctype,54L
        +
        +#define SN_setct_AuthTokenTBE		"setct-AuthTokenTBE"
        +#define NID_setct_AuthTokenTBE		573
        +#define OBJ_setct_AuthTokenTBE		OBJ_set_ctype,55L
        +
        +#define SN_setct_CapTokenTBE		"setct-CapTokenTBE"
        +#define NID_setct_CapTokenTBE		574
        +#define OBJ_setct_CapTokenTBE		OBJ_set_ctype,56L
        +
        +#define SN_setct_CapTokenTBEX		"setct-CapTokenTBEX"
        +#define NID_setct_CapTokenTBEX		575
        +#define OBJ_setct_CapTokenTBEX		OBJ_set_ctype,57L
        +
        +#define SN_setct_AcqCardCodeMsgTBE		"setct-AcqCardCodeMsgTBE"
        +#define NID_setct_AcqCardCodeMsgTBE		576
        +#define OBJ_setct_AcqCardCodeMsgTBE		OBJ_set_ctype,58L
        +
        +#define SN_setct_AuthRevReqTBE		"setct-AuthRevReqTBE"
        +#define NID_setct_AuthRevReqTBE		577
        +#define OBJ_setct_AuthRevReqTBE		OBJ_set_ctype,59L
        +
        +#define SN_setct_AuthRevResTBE		"setct-AuthRevResTBE"
        +#define NID_setct_AuthRevResTBE		578
        +#define OBJ_setct_AuthRevResTBE		OBJ_set_ctype,60L
        +
        +#define SN_setct_AuthRevResTBEB		"setct-AuthRevResTBEB"
        +#define NID_setct_AuthRevResTBEB		579
        +#define OBJ_setct_AuthRevResTBEB		OBJ_set_ctype,61L
        +
        +#define SN_setct_CapReqTBE		"setct-CapReqTBE"
        +#define NID_setct_CapReqTBE		580
        +#define OBJ_setct_CapReqTBE		OBJ_set_ctype,62L
        +
        +#define SN_setct_CapReqTBEX		"setct-CapReqTBEX"
        +#define NID_setct_CapReqTBEX		581
        +#define OBJ_setct_CapReqTBEX		OBJ_set_ctype,63L
        +
        +#define SN_setct_CapResTBE		"setct-CapResTBE"
        +#define NID_setct_CapResTBE		582
        +#define OBJ_setct_CapResTBE		OBJ_set_ctype,64L
        +
        +#define SN_setct_CapRevReqTBE		"setct-CapRevReqTBE"
        +#define NID_setct_CapRevReqTBE		583
        +#define OBJ_setct_CapRevReqTBE		OBJ_set_ctype,65L
        +
        +#define SN_setct_CapRevReqTBEX		"setct-CapRevReqTBEX"
        +#define NID_setct_CapRevReqTBEX		584
        +#define OBJ_setct_CapRevReqTBEX		OBJ_set_ctype,66L
        +
        +#define SN_setct_CapRevResTBE		"setct-CapRevResTBE"
        +#define NID_setct_CapRevResTBE		585
        +#define OBJ_setct_CapRevResTBE		OBJ_set_ctype,67L
        +
        +#define SN_setct_CredReqTBE		"setct-CredReqTBE"
        +#define NID_setct_CredReqTBE		586
        +#define OBJ_setct_CredReqTBE		OBJ_set_ctype,68L
        +
        +#define SN_setct_CredReqTBEX		"setct-CredReqTBEX"
        +#define NID_setct_CredReqTBEX		587
        +#define OBJ_setct_CredReqTBEX		OBJ_set_ctype,69L
        +
        +#define SN_setct_CredResTBE		"setct-CredResTBE"
        +#define NID_setct_CredResTBE		588
        +#define OBJ_setct_CredResTBE		OBJ_set_ctype,70L
        +
        +#define SN_setct_CredRevReqTBE		"setct-CredRevReqTBE"
        +#define NID_setct_CredRevReqTBE		589
        +#define OBJ_setct_CredRevReqTBE		OBJ_set_ctype,71L
        +
        +#define SN_setct_CredRevReqTBEX		"setct-CredRevReqTBEX"
        +#define NID_setct_CredRevReqTBEX		590
        +#define OBJ_setct_CredRevReqTBEX		OBJ_set_ctype,72L
        +
        +#define SN_setct_CredRevResTBE		"setct-CredRevResTBE"
        +#define NID_setct_CredRevResTBE		591
        +#define OBJ_setct_CredRevResTBE		OBJ_set_ctype,73L
        +
        +#define SN_setct_BatchAdminReqTBE		"setct-BatchAdminReqTBE"
        +#define NID_setct_BatchAdminReqTBE		592
        +#define OBJ_setct_BatchAdminReqTBE		OBJ_set_ctype,74L
        +
        +#define SN_setct_BatchAdminResTBE		"setct-BatchAdminResTBE"
        +#define NID_setct_BatchAdminResTBE		593
        +#define OBJ_setct_BatchAdminResTBE		OBJ_set_ctype,75L
        +
        +#define SN_setct_RegFormReqTBE		"setct-RegFormReqTBE"
        +#define NID_setct_RegFormReqTBE		594
        +#define OBJ_setct_RegFormReqTBE		OBJ_set_ctype,76L
        +
        +#define SN_setct_CertReqTBE		"setct-CertReqTBE"
        +#define NID_setct_CertReqTBE		595
        +#define OBJ_setct_CertReqTBE		OBJ_set_ctype,77L
        +
        +#define SN_setct_CertReqTBEX		"setct-CertReqTBEX"
        +#define NID_setct_CertReqTBEX		596
        +#define OBJ_setct_CertReqTBEX		OBJ_set_ctype,78L
        +
        +#define SN_setct_CertResTBE		"setct-CertResTBE"
        +#define NID_setct_CertResTBE		597
        +#define OBJ_setct_CertResTBE		OBJ_set_ctype,79L
        +
        +#define SN_setct_CRLNotificationTBS		"setct-CRLNotificationTBS"
        +#define NID_setct_CRLNotificationTBS		598
        +#define OBJ_setct_CRLNotificationTBS		OBJ_set_ctype,80L
        +
        +#define SN_setct_CRLNotificationResTBS		"setct-CRLNotificationResTBS"
        +#define NID_setct_CRLNotificationResTBS		599
        +#define OBJ_setct_CRLNotificationResTBS		OBJ_set_ctype,81L
        +
        +#define SN_setct_BCIDistributionTBS		"setct-BCIDistributionTBS"
        +#define NID_setct_BCIDistributionTBS		600
        +#define OBJ_setct_BCIDistributionTBS		OBJ_set_ctype,82L
        +
        +#define SN_setext_genCrypt		"setext-genCrypt"
        +#define LN_setext_genCrypt		"generic cryptogram"
        +#define NID_setext_genCrypt		601
        +#define OBJ_setext_genCrypt		OBJ_set_msgExt,1L
        +
        +#define SN_setext_miAuth		"setext-miAuth"
        +#define LN_setext_miAuth		"merchant initiated auth"
        +#define NID_setext_miAuth		602
        +#define OBJ_setext_miAuth		OBJ_set_msgExt,3L
        +
        +#define SN_setext_pinSecure		"setext-pinSecure"
        +#define NID_setext_pinSecure		603
        +#define OBJ_setext_pinSecure		OBJ_set_msgExt,4L
        +
        +#define SN_setext_pinAny		"setext-pinAny"
        +#define NID_setext_pinAny		604
        +#define OBJ_setext_pinAny		OBJ_set_msgExt,5L
        +
        +#define SN_setext_track2		"setext-track2"
        +#define NID_setext_track2		605
        +#define OBJ_setext_track2		OBJ_set_msgExt,7L
        +
        +#define SN_setext_cv		"setext-cv"
        +#define LN_setext_cv		"additional verification"
        +#define NID_setext_cv		606
        +#define OBJ_setext_cv		OBJ_set_msgExt,8L
        +
        +#define SN_set_policy_root		"set-policy-root"
        +#define NID_set_policy_root		607
        +#define OBJ_set_policy_root		OBJ_set_policy,0L
        +
        +#define SN_setCext_hashedRoot		"setCext-hashedRoot"
        +#define NID_setCext_hashedRoot		608
        +#define OBJ_setCext_hashedRoot		OBJ_set_certExt,0L
        +
        +#define SN_setCext_certType		"setCext-certType"
        +#define NID_setCext_certType		609
        +#define OBJ_setCext_certType		OBJ_set_certExt,1L
        +
        +#define SN_setCext_merchData		"setCext-merchData"
        +#define NID_setCext_merchData		610
        +#define OBJ_setCext_merchData		OBJ_set_certExt,2L
        +
        +#define SN_setCext_cCertRequired		"setCext-cCertRequired"
        +#define NID_setCext_cCertRequired		611
        +#define OBJ_setCext_cCertRequired		OBJ_set_certExt,3L
        +
        +#define SN_setCext_tunneling		"setCext-tunneling"
        +#define NID_setCext_tunneling		612
        +#define OBJ_setCext_tunneling		OBJ_set_certExt,4L
        +
        +#define SN_setCext_setExt		"setCext-setExt"
        +#define NID_setCext_setExt		613
        +#define OBJ_setCext_setExt		OBJ_set_certExt,5L
        +
        +#define SN_setCext_setQualf		"setCext-setQualf"
        +#define NID_setCext_setQualf		614
        +#define OBJ_setCext_setQualf		OBJ_set_certExt,6L
        +
        +#define SN_setCext_PGWYcapabilities		"setCext-PGWYcapabilities"
        +#define NID_setCext_PGWYcapabilities		615
        +#define OBJ_setCext_PGWYcapabilities		OBJ_set_certExt,7L
        +
        +#define SN_setCext_TokenIdentifier		"setCext-TokenIdentifier"
        +#define NID_setCext_TokenIdentifier		616
        +#define OBJ_setCext_TokenIdentifier		OBJ_set_certExt,8L
        +
        +#define SN_setCext_Track2Data		"setCext-Track2Data"
        +#define NID_setCext_Track2Data		617
        +#define OBJ_setCext_Track2Data		OBJ_set_certExt,9L
        +
        +#define SN_setCext_TokenType		"setCext-TokenType"
        +#define NID_setCext_TokenType		618
        +#define OBJ_setCext_TokenType		OBJ_set_certExt,10L
        +
        +#define SN_setCext_IssuerCapabilities		"setCext-IssuerCapabilities"
        +#define NID_setCext_IssuerCapabilities		619
        +#define OBJ_setCext_IssuerCapabilities		OBJ_set_certExt,11L
        +
        +#define SN_setAttr_Cert		"setAttr-Cert"
        +#define NID_setAttr_Cert		620
        +#define OBJ_setAttr_Cert		OBJ_set_attr,0L
        +
        +#define SN_setAttr_PGWYcap		"setAttr-PGWYcap"
        +#define LN_setAttr_PGWYcap		"payment gateway capabilities"
        +#define NID_setAttr_PGWYcap		621
        +#define OBJ_setAttr_PGWYcap		OBJ_set_attr,1L
        +
        +#define SN_setAttr_TokenType		"setAttr-TokenType"
        +#define NID_setAttr_TokenType		622
        +#define OBJ_setAttr_TokenType		OBJ_set_attr,2L
        +
        +#define SN_setAttr_IssCap		"setAttr-IssCap"
        +#define LN_setAttr_IssCap		"issuer capabilities"
        +#define NID_setAttr_IssCap		623
        +#define OBJ_setAttr_IssCap		OBJ_set_attr,3L
        +
        +#define SN_set_rootKeyThumb		"set-rootKeyThumb"
        +#define NID_set_rootKeyThumb		624
        +#define OBJ_set_rootKeyThumb		OBJ_setAttr_Cert,0L
        +
        +#define SN_set_addPolicy		"set-addPolicy"
        +#define NID_set_addPolicy		625
        +#define OBJ_set_addPolicy		OBJ_setAttr_Cert,1L
        +
        +#define SN_setAttr_Token_EMV		"setAttr-Token-EMV"
        +#define NID_setAttr_Token_EMV		626
        +#define OBJ_setAttr_Token_EMV		OBJ_setAttr_TokenType,1L
        +
        +#define SN_setAttr_Token_B0Prime		"setAttr-Token-B0Prime"
        +#define NID_setAttr_Token_B0Prime		627
        +#define OBJ_setAttr_Token_B0Prime		OBJ_setAttr_TokenType,2L
        +
        +#define SN_setAttr_IssCap_CVM		"setAttr-IssCap-CVM"
        +#define NID_setAttr_IssCap_CVM		628
        +#define OBJ_setAttr_IssCap_CVM		OBJ_setAttr_IssCap,3L
        +
        +#define SN_setAttr_IssCap_T2		"setAttr-IssCap-T2"
        +#define NID_setAttr_IssCap_T2		629
        +#define OBJ_setAttr_IssCap_T2		OBJ_setAttr_IssCap,4L
        +
        +#define SN_setAttr_IssCap_Sig		"setAttr-IssCap-Sig"
        +#define NID_setAttr_IssCap_Sig		630
        +#define OBJ_setAttr_IssCap_Sig		OBJ_setAttr_IssCap,5L
        +
        +#define SN_setAttr_GenCryptgrm		"setAttr-GenCryptgrm"
        +#define LN_setAttr_GenCryptgrm		"generate cryptogram"
        +#define NID_setAttr_GenCryptgrm		631
        +#define OBJ_setAttr_GenCryptgrm		OBJ_setAttr_IssCap_CVM,1L
        +
        +#define SN_setAttr_T2Enc		"setAttr-T2Enc"
        +#define LN_setAttr_T2Enc		"encrypted track 2"
        +#define NID_setAttr_T2Enc		632
        +#define OBJ_setAttr_T2Enc		OBJ_setAttr_IssCap_T2,1L
        +
        +#define SN_setAttr_T2cleartxt		"setAttr-T2cleartxt"
        +#define LN_setAttr_T2cleartxt		"cleartext track 2"
        +#define NID_setAttr_T2cleartxt		633
        +#define OBJ_setAttr_T2cleartxt		OBJ_setAttr_IssCap_T2,2L
        +
        +#define SN_setAttr_TokICCsig		"setAttr-TokICCsig"
        +#define LN_setAttr_TokICCsig		"ICC or token signature"
        +#define NID_setAttr_TokICCsig		634
        +#define OBJ_setAttr_TokICCsig		OBJ_setAttr_IssCap_Sig,1L
        +
        +#define SN_setAttr_SecDevSig		"setAttr-SecDevSig"
        +#define LN_setAttr_SecDevSig		"secure device signature"
        +#define NID_setAttr_SecDevSig		635
        +#define OBJ_setAttr_SecDevSig		OBJ_setAttr_IssCap_Sig,2L
        +
        +#define SN_set_brand_IATA_ATA		"set-brand-IATA-ATA"
        +#define NID_set_brand_IATA_ATA		636
        +#define OBJ_set_brand_IATA_ATA		OBJ_set_brand,1L
        +
        +#define SN_set_brand_Diners		"set-brand-Diners"
        +#define NID_set_brand_Diners		637
        +#define OBJ_set_brand_Diners		OBJ_set_brand,30L
        +
        +#define SN_set_brand_AmericanExpress		"set-brand-AmericanExpress"
        +#define NID_set_brand_AmericanExpress		638
        +#define OBJ_set_brand_AmericanExpress		OBJ_set_brand,34L
        +
        +#define SN_set_brand_JCB		"set-brand-JCB"
        +#define NID_set_brand_JCB		639
        +#define OBJ_set_brand_JCB		OBJ_set_brand,35L
        +
        +#define SN_set_brand_Visa		"set-brand-Visa"
        +#define NID_set_brand_Visa		640
        +#define OBJ_set_brand_Visa		OBJ_set_brand,4L
        +
        +#define SN_set_brand_MasterCard		"set-brand-MasterCard"
        +#define NID_set_brand_MasterCard		641
        +#define OBJ_set_brand_MasterCard		OBJ_set_brand,5L
        +
        +#define SN_set_brand_Novus		"set-brand-Novus"
        +#define NID_set_brand_Novus		642
        +#define OBJ_set_brand_Novus		OBJ_set_brand,6011L
        +
        +#define SN_des_cdmf		"DES-CDMF"
        +#define LN_des_cdmf		"des-cdmf"
        +#define NID_des_cdmf		643
        +#define OBJ_des_cdmf		OBJ_rsadsi,3L,10L
        +
        +#define SN_rsaOAEPEncryptionSET		"rsaOAEPEncryptionSET"
        +#define NID_rsaOAEPEncryptionSET		644
        +#define OBJ_rsaOAEPEncryptionSET		OBJ_rsadsi,1L,1L,6L
        +
        +#define SN_ipsec3		"Oakley-EC2N-3"
        +#define LN_ipsec3		"ipsec3"
        +#define NID_ipsec3		749
        +
        +#define SN_ipsec4		"Oakley-EC2N-4"
        +#define LN_ipsec4		"ipsec4"
        +#define NID_ipsec4		750
        +
        +#define SN_whirlpool		"whirlpool"
        +#define NID_whirlpool		804
        +#define OBJ_whirlpool		OBJ_iso,0L,10118L,3L,0L,55L
        +
        +#define SN_cryptopro		"cryptopro"
        +#define NID_cryptopro		805
        +#define OBJ_cryptopro		OBJ_member_body,643L,2L,2L
        +
        +#define SN_cryptocom		"cryptocom"
        +#define NID_cryptocom		806
        +#define OBJ_cryptocom		OBJ_member_body,643L,2L,9L
        +
        +#define SN_id_GostR3411_94_with_GostR3410_2001		"id-GostR3411-94-with-GostR3410-2001"
        +#define LN_id_GostR3411_94_with_GostR3410_2001		"GOST R 34.11-94 with GOST R 34.10-2001"
        +#define NID_id_GostR3411_94_with_GostR3410_2001		807
        +#define OBJ_id_GostR3411_94_with_GostR3410_2001		OBJ_cryptopro,3L
        +
        +#define SN_id_GostR3411_94_with_GostR3410_94		"id-GostR3411-94-with-GostR3410-94"
        +#define LN_id_GostR3411_94_with_GostR3410_94		"GOST R 34.11-94 with GOST R 34.10-94"
        +#define NID_id_GostR3411_94_with_GostR3410_94		808
        +#define OBJ_id_GostR3411_94_with_GostR3410_94		OBJ_cryptopro,4L
        +
        +#define SN_id_GostR3411_94		"md_gost94"
        +#define LN_id_GostR3411_94		"GOST R 34.11-94"
        +#define NID_id_GostR3411_94		809
        +#define OBJ_id_GostR3411_94		OBJ_cryptopro,9L
        +
        +#define SN_id_HMACGostR3411_94		"id-HMACGostR3411-94"
        +#define LN_id_HMACGostR3411_94		"HMAC GOST 34.11-94"
        +#define NID_id_HMACGostR3411_94		810
        +#define OBJ_id_HMACGostR3411_94		OBJ_cryptopro,10L
        +
        +#define SN_id_GostR3410_2001		"gost2001"
        +#define LN_id_GostR3410_2001		"GOST R 34.10-2001"
        +#define NID_id_GostR3410_2001		811
        +#define OBJ_id_GostR3410_2001		OBJ_cryptopro,19L
        +
        +#define SN_id_GostR3410_94		"gost94"
        +#define LN_id_GostR3410_94		"GOST R 34.10-94"
        +#define NID_id_GostR3410_94		812
        +#define OBJ_id_GostR3410_94		OBJ_cryptopro,20L
        +
        +#define SN_id_Gost28147_89		"gost89"
        +#define LN_id_Gost28147_89		"GOST 28147-89"
        +#define NID_id_Gost28147_89		813
        +#define OBJ_id_Gost28147_89		OBJ_cryptopro,21L
        +
        +#define SN_gost89_cnt		"gost89-cnt"
        +#define NID_gost89_cnt		814
        +
        +#define SN_id_Gost28147_89_MAC		"gost-mac"
        +#define LN_id_Gost28147_89_MAC		"GOST 28147-89 MAC"
        +#define NID_id_Gost28147_89_MAC		815
        +#define OBJ_id_Gost28147_89_MAC		OBJ_cryptopro,22L
        +
        +#define SN_id_GostR3411_94_prf		"prf-gostr3411-94"
        +#define LN_id_GostR3411_94_prf		"GOST R 34.11-94 PRF"
        +#define NID_id_GostR3411_94_prf		816
        +#define OBJ_id_GostR3411_94_prf		OBJ_cryptopro,23L
        +
        +#define SN_id_GostR3410_2001DH		"id-GostR3410-2001DH"
        +#define LN_id_GostR3410_2001DH		"GOST R 34.10-2001 DH"
        +#define NID_id_GostR3410_2001DH		817
        +#define OBJ_id_GostR3410_2001DH		OBJ_cryptopro,98L
        +
        +#define SN_id_GostR3410_94DH		"id-GostR3410-94DH"
        +#define LN_id_GostR3410_94DH		"GOST R 34.10-94 DH"
        +#define NID_id_GostR3410_94DH		818
        +#define OBJ_id_GostR3410_94DH		OBJ_cryptopro,99L
        +
        +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing		"id-Gost28147-89-CryptoPro-KeyMeshing"
        +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing		819
        +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing		OBJ_cryptopro,14L,1L
        +
        +#define SN_id_Gost28147_89_None_KeyMeshing		"id-Gost28147-89-None-KeyMeshing"
        +#define NID_id_Gost28147_89_None_KeyMeshing		820
        +#define OBJ_id_Gost28147_89_None_KeyMeshing		OBJ_cryptopro,14L,0L
        +
        +#define SN_id_GostR3411_94_TestParamSet		"id-GostR3411-94-TestParamSet"
        +#define NID_id_GostR3411_94_TestParamSet		821
        +#define OBJ_id_GostR3411_94_TestParamSet		OBJ_cryptopro,30L,0L
        +
        +#define SN_id_GostR3411_94_CryptoProParamSet		"id-GostR3411-94-CryptoProParamSet"
        +#define NID_id_GostR3411_94_CryptoProParamSet		822
        +#define OBJ_id_GostR3411_94_CryptoProParamSet		OBJ_cryptopro,30L,1L
        +
        +#define SN_id_Gost28147_89_TestParamSet		"id-Gost28147-89-TestParamSet"
        +#define NID_id_Gost28147_89_TestParamSet		823
        +#define OBJ_id_Gost28147_89_TestParamSet		OBJ_cryptopro,31L,0L
        +
        +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet		"id-Gost28147-89-CryptoPro-A-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet		824
        +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet		OBJ_cryptopro,31L,1L
        +
        +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet		"id-Gost28147-89-CryptoPro-B-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet		825
        +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet		OBJ_cryptopro,31L,2L
        +
        +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet		"id-Gost28147-89-CryptoPro-C-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet		826
        +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet		OBJ_cryptopro,31L,3L
        +
        +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet		"id-Gost28147-89-CryptoPro-D-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet		827
        +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet		OBJ_cryptopro,31L,4L
        +
        +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
        +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		OBJ_cryptopro,31L,5L
        +
        +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
        +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		OBJ_cryptopro,31L,6L
        +
        +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		"id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
        +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
        +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		OBJ_cryptopro,31L,7L
        +
        +#define SN_id_GostR3410_94_TestParamSet		"id-GostR3410-94-TestParamSet"
        +#define NID_id_GostR3410_94_TestParamSet		831
        +#define OBJ_id_GostR3410_94_TestParamSet		OBJ_cryptopro,32L,0L
        +
        +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet		"id-GostR3410-94-CryptoPro-A-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet		832
        +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet		OBJ_cryptopro,32L,2L
        +
        +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet		"id-GostR3410-94-CryptoPro-B-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet		833
        +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet		OBJ_cryptopro,32L,3L
        +
        +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet		"id-GostR3410-94-CryptoPro-C-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet		834
        +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet		OBJ_cryptopro,32L,4L
        +
        +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet		"id-GostR3410-94-CryptoPro-D-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet		835
        +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet		OBJ_cryptopro,32L,5L
        +
        +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet		"id-GostR3410-94-CryptoPro-XchA-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet		836
        +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet		OBJ_cryptopro,33L,1L
        +
        +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet		"id-GostR3410-94-CryptoPro-XchB-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet		837
        +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet		OBJ_cryptopro,33L,2L
        +
        +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet		"id-GostR3410-94-CryptoPro-XchC-ParamSet"
        +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet		838
        +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet		OBJ_cryptopro,33L,3L
        +
        +#define SN_id_GostR3410_2001_TestParamSet		"id-GostR3410-2001-TestParamSet"
        +#define NID_id_GostR3410_2001_TestParamSet		839
        +#define OBJ_id_GostR3410_2001_TestParamSet		OBJ_cryptopro,35L,0L
        +
        +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet		"id-GostR3410-2001-CryptoPro-A-ParamSet"
        +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet		840
        +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet		OBJ_cryptopro,35L,1L
        +
        +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet		"id-GostR3410-2001-CryptoPro-B-ParamSet"
        +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet		841
        +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet		OBJ_cryptopro,35L,2L
        +
        +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet		"id-GostR3410-2001-CryptoPro-C-ParamSet"
        +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet		842
        +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet		OBJ_cryptopro,35L,3L
        +
        +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet		"id-GostR3410-2001-CryptoPro-XchA-ParamSet"
        +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
        +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet		OBJ_cryptopro,36L,0L
        +
        +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet		"id-GostR3410-2001-CryptoPro-XchB-ParamSet"
        +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
        +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet		OBJ_cryptopro,36L,1L
        +
        +#define SN_id_GostR3410_94_a		"id-GostR3410-94-a"
        +#define NID_id_GostR3410_94_a		845
        +#define OBJ_id_GostR3410_94_a		OBJ_id_GostR3410_94,1L
        +
        +#define SN_id_GostR3410_94_aBis		"id-GostR3410-94-aBis"
        +#define NID_id_GostR3410_94_aBis		846
        +#define OBJ_id_GostR3410_94_aBis		OBJ_id_GostR3410_94,2L
        +
        +#define SN_id_GostR3410_94_b		"id-GostR3410-94-b"
        +#define NID_id_GostR3410_94_b		847
        +#define OBJ_id_GostR3410_94_b		OBJ_id_GostR3410_94,3L
        +
        +#define SN_id_GostR3410_94_bBis		"id-GostR3410-94-bBis"
        +#define NID_id_GostR3410_94_bBis		848
        +#define OBJ_id_GostR3410_94_bBis		OBJ_id_GostR3410_94,4L
        +
        +#define SN_id_Gost28147_89_cc		"id-Gost28147-89-cc"
        +#define LN_id_Gost28147_89_cc		"GOST 28147-89 Cryptocom ParamSet"
        +#define NID_id_Gost28147_89_cc		849
        +#define OBJ_id_Gost28147_89_cc		OBJ_cryptocom,1L,6L,1L
        +
        +#define SN_id_GostR3410_94_cc		"gost94cc"
        +#define LN_id_GostR3410_94_cc		"GOST 34.10-94 Cryptocom"
        +#define NID_id_GostR3410_94_cc		850
        +#define OBJ_id_GostR3410_94_cc		OBJ_cryptocom,1L,5L,3L
        +
        +#define SN_id_GostR3410_2001_cc		"gost2001cc"
        +#define LN_id_GostR3410_2001_cc		"GOST 34.10-2001 Cryptocom"
        +#define NID_id_GostR3410_2001_cc		851
        +#define OBJ_id_GostR3410_2001_cc		OBJ_cryptocom,1L,5L,4L
        +
        +#define SN_id_GostR3411_94_with_GostR3410_94_cc		"id-GostR3411-94-with-GostR3410-94-cc"
        +#define LN_id_GostR3411_94_with_GostR3410_94_cc		"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
        +#define NID_id_GostR3411_94_with_GostR3410_94_cc		852
        +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc		OBJ_cryptocom,1L,3L,3L
        +
        +#define SN_id_GostR3411_94_with_GostR3410_2001_cc		"id-GostR3411-94-with-GostR3410-2001-cc"
        +#define LN_id_GostR3411_94_with_GostR3410_2001_cc		"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
        +#define NID_id_GostR3411_94_with_GostR3410_2001_cc		853
        +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc		OBJ_cryptocom,1L,3L,4L
        +
        +#define SN_id_GostR3410_2001_ParamSet_cc		"id-GostR3410-2001-ParamSet-cc"
        +#define LN_id_GostR3410_2001_ParamSet_cc		"GOST R 3410-2001 Parameter Set Cryptocom"
        +#define NID_id_GostR3410_2001_ParamSet_cc		854
        +#define OBJ_id_GostR3410_2001_ParamSet_cc		OBJ_cryptocom,1L,8L,1L
        +
        +#define SN_camellia_128_cbc		"CAMELLIA-128-CBC"
        +#define LN_camellia_128_cbc		"camellia-128-cbc"
        +#define NID_camellia_128_cbc		751
        +#define OBJ_camellia_128_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,2L
        +
        +#define SN_camellia_192_cbc		"CAMELLIA-192-CBC"
        +#define LN_camellia_192_cbc		"camellia-192-cbc"
        +#define NID_camellia_192_cbc		752
        +#define OBJ_camellia_192_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,3L
        +
        +#define SN_camellia_256_cbc		"CAMELLIA-256-CBC"
        +#define LN_camellia_256_cbc		"camellia-256-cbc"
        +#define NID_camellia_256_cbc		753
        +#define OBJ_camellia_256_cbc		1L,2L,392L,200011L,61L,1L,1L,1L,4L
        +
        +#define SN_id_camellia128_wrap		"id-camellia128-wrap"
        +#define NID_id_camellia128_wrap		907
        +#define OBJ_id_camellia128_wrap		1L,2L,392L,200011L,61L,1L,1L,3L,2L
        +
        +#define SN_id_camellia192_wrap		"id-camellia192-wrap"
        +#define NID_id_camellia192_wrap		908
        +#define OBJ_id_camellia192_wrap		1L,2L,392L,200011L,61L,1L,1L,3L,3L
        +
        +#define SN_id_camellia256_wrap		"id-camellia256-wrap"
        +#define NID_id_camellia256_wrap		909
        +#define OBJ_id_camellia256_wrap		1L,2L,392L,200011L,61L,1L,1L,3L,4L
        +
        +#define OBJ_ntt_ds		0L,3L,4401L,5L
        +
        +#define OBJ_camellia		OBJ_ntt_ds,3L,1L,9L
        +
        +#define SN_camellia_128_ecb		"CAMELLIA-128-ECB"
        +#define LN_camellia_128_ecb		"camellia-128-ecb"
        +#define NID_camellia_128_ecb		754
        +#define OBJ_camellia_128_ecb		OBJ_camellia,1L
        +
        +#define SN_camellia_128_ofb128		"CAMELLIA-128-OFB"
        +#define LN_camellia_128_ofb128		"camellia-128-ofb"
        +#define NID_camellia_128_ofb128		766
        +#define OBJ_camellia_128_ofb128		OBJ_camellia,3L
        +
        +#define SN_camellia_128_cfb128		"CAMELLIA-128-CFB"
        +#define LN_camellia_128_cfb128		"camellia-128-cfb"
        +#define NID_camellia_128_cfb128		757
        +#define OBJ_camellia_128_cfb128		OBJ_camellia,4L
        +
        +#define SN_camellia_192_ecb		"CAMELLIA-192-ECB"
        +#define LN_camellia_192_ecb		"camellia-192-ecb"
        +#define NID_camellia_192_ecb		755
        +#define OBJ_camellia_192_ecb		OBJ_camellia,21L
        +
        +#define SN_camellia_192_ofb128		"CAMELLIA-192-OFB"
        +#define LN_camellia_192_ofb128		"camellia-192-ofb"
        +#define NID_camellia_192_ofb128		767
        +#define OBJ_camellia_192_ofb128		OBJ_camellia,23L
        +
        +#define SN_camellia_192_cfb128		"CAMELLIA-192-CFB"
        +#define LN_camellia_192_cfb128		"camellia-192-cfb"
        +#define NID_camellia_192_cfb128		758
        +#define OBJ_camellia_192_cfb128		OBJ_camellia,24L
        +
        +#define SN_camellia_256_ecb		"CAMELLIA-256-ECB"
        +#define LN_camellia_256_ecb		"camellia-256-ecb"
        +#define NID_camellia_256_ecb		756
        +#define OBJ_camellia_256_ecb		OBJ_camellia,41L
        +
        +#define SN_camellia_256_ofb128		"CAMELLIA-256-OFB"
        +#define LN_camellia_256_ofb128		"camellia-256-ofb"
        +#define NID_camellia_256_ofb128		768
        +#define OBJ_camellia_256_ofb128		OBJ_camellia,43L
        +
        +#define SN_camellia_256_cfb128		"CAMELLIA-256-CFB"
        +#define LN_camellia_256_cfb128		"camellia-256-cfb"
        +#define NID_camellia_256_cfb128		759
        +#define OBJ_camellia_256_cfb128		OBJ_camellia,44L
        +
        +#define SN_camellia_128_cfb1		"CAMELLIA-128-CFB1"
        +#define LN_camellia_128_cfb1		"camellia-128-cfb1"
        +#define NID_camellia_128_cfb1		760
        +
        +#define SN_camellia_192_cfb1		"CAMELLIA-192-CFB1"
        +#define LN_camellia_192_cfb1		"camellia-192-cfb1"
        +#define NID_camellia_192_cfb1		761
        +
        +#define SN_camellia_256_cfb1		"CAMELLIA-256-CFB1"
        +#define LN_camellia_256_cfb1		"camellia-256-cfb1"
        +#define NID_camellia_256_cfb1		762
        +
        +#define SN_camellia_128_cfb8		"CAMELLIA-128-CFB8"
        +#define LN_camellia_128_cfb8		"camellia-128-cfb8"
        +#define NID_camellia_128_cfb8		763
        +
        +#define SN_camellia_192_cfb8		"CAMELLIA-192-CFB8"
        +#define LN_camellia_192_cfb8		"camellia-192-cfb8"
        +#define NID_camellia_192_cfb8		764
        +
        +#define SN_camellia_256_cfb8		"CAMELLIA-256-CFB8"
        +#define LN_camellia_256_cfb8		"camellia-256-cfb8"
        +#define NID_camellia_256_cfb8		765
        +
        +#define SN_kisa		"KISA"
        +#define LN_kisa		"kisa"
        +#define NID_kisa		773
        +#define OBJ_kisa		OBJ_member_body,410L,200004L
        +
        +#define SN_seed_ecb		"SEED-ECB"
        +#define LN_seed_ecb		"seed-ecb"
        +#define NID_seed_ecb		776
        +#define OBJ_seed_ecb		OBJ_kisa,1L,3L
        +
        +#define SN_seed_cbc		"SEED-CBC"
        +#define LN_seed_cbc		"seed-cbc"
        +#define NID_seed_cbc		777
        +#define OBJ_seed_cbc		OBJ_kisa,1L,4L
        +
        +#define SN_seed_cfb128		"SEED-CFB"
        +#define LN_seed_cfb128		"seed-cfb"
        +#define NID_seed_cfb128		779
        +#define OBJ_seed_cfb128		OBJ_kisa,1L,5L
        +
        +#define SN_seed_ofb128		"SEED-OFB"
        +#define LN_seed_ofb128		"seed-ofb"
        +#define NID_seed_ofb128		778
        +#define OBJ_seed_ofb128		OBJ_kisa,1L,6L
        +
        +#define SN_hmac		"HMAC"
        +#define LN_hmac		"hmac"
        +#define NID_hmac		855
        +
        +#define SN_cmac		"CMAC"
        +#define LN_cmac		"cmac"
        +#define NID_cmac		894
        +
        +#define SN_rc4_hmac_md5		"RC4-HMAC-MD5"
        +#define LN_rc4_hmac_md5		"rc4-hmac-md5"
        +#define NID_rc4_hmac_md5		915
        +
        +#define SN_aes_128_cbc_hmac_sha1		"AES-128-CBC-HMAC-SHA1"
        +#define LN_aes_128_cbc_hmac_sha1		"aes-128-cbc-hmac-sha1"
        +#define NID_aes_128_cbc_hmac_sha1		916
        +
        +#define SN_aes_192_cbc_hmac_sha1		"AES-192-CBC-HMAC-SHA1"
        +#define LN_aes_192_cbc_hmac_sha1		"aes-192-cbc-hmac-sha1"
        +#define NID_aes_192_cbc_hmac_sha1		917
        +
        +#define SN_aes_256_cbc_hmac_sha1		"AES-256-CBC-HMAC-SHA1"
        +#define LN_aes_256_cbc_hmac_sha1		"aes-256-cbc-hmac-sha1"
        +#define NID_aes_256_cbc_hmac_sha1		918
        +
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_mac.num b/vendor/openssl/openssl/crypto/objects/obj_mac.num
        new file mode 100644
        index 000000000..1d0a7c802
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_mac.num
        @@ -0,0 +1,919 @@
        +undef		0
        +rsadsi		1
        +pkcs		2
        +md2		3
        +md5		4
        +rc4		5
        +rsaEncryption		6
        +md2WithRSAEncryption		7
        +md5WithRSAEncryption		8
        +pbeWithMD2AndDES_CBC		9
        +pbeWithMD5AndDES_CBC		10
        +X500		11
        +X509		12
        +commonName		13
        +countryName		14
        +localityName		15
        +stateOrProvinceName		16
        +organizationName		17
        +organizationalUnitName		18
        +rsa		19
        +pkcs7		20
        +pkcs7_data		21
        +pkcs7_signed		22
        +pkcs7_enveloped		23
        +pkcs7_signedAndEnveloped		24
        +pkcs7_digest		25
        +pkcs7_encrypted		26
        +pkcs3		27
        +dhKeyAgreement		28
        +des_ecb		29
        +des_cfb64		30
        +des_cbc		31
        +des_ede_ecb		32
        +des_ede3_ecb		33
        +idea_cbc		34
        +idea_cfb64		35
        +idea_ecb		36
        +rc2_cbc		37
        +rc2_ecb		38
        +rc2_cfb64		39
        +rc2_ofb64		40
        +sha		41
        +shaWithRSAEncryption		42
        +des_ede_cbc		43
        +des_ede3_cbc		44
        +des_ofb64		45
        +idea_ofb64		46
        +pkcs9		47
        +pkcs9_emailAddress		48
        +pkcs9_unstructuredName		49
        +pkcs9_contentType		50
        +pkcs9_messageDigest		51
        +pkcs9_signingTime		52
        +pkcs9_countersignature		53
        +pkcs9_challengePassword		54
        +pkcs9_unstructuredAddress		55
        +pkcs9_extCertAttributes		56
        +netscape		57
        +netscape_cert_extension		58
        +netscape_data_type		59
        +des_ede_cfb64		60
        +des_ede3_cfb64		61
        +des_ede_ofb64		62
        +des_ede3_ofb64		63
        +sha1		64
        +sha1WithRSAEncryption		65
        +dsaWithSHA		66
        +dsa_2		67
        +pbeWithSHA1AndRC2_CBC		68
        +id_pbkdf2		69
        +dsaWithSHA1_2		70
        +netscape_cert_type		71
        +netscape_base_url		72
        +netscape_revocation_url		73
        +netscape_ca_revocation_url		74
        +netscape_renewal_url		75
        +netscape_ca_policy_url		76
        +netscape_ssl_server_name		77
        +netscape_comment		78
        +netscape_cert_sequence		79
        +desx_cbc		80
        +id_ce		81
        +subject_key_identifier		82
        +key_usage		83
        +private_key_usage_period		84
        +subject_alt_name		85
        +issuer_alt_name		86
        +basic_constraints		87
        +crl_number		88
        +certificate_policies		89
        +authority_key_identifier		90
        +bf_cbc		91
        +bf_ecb		92
        +bf_cfb64		93
        +bf_ofb64		94
        +mdc2		95
        +mdc2WithRSA		96
        +rc4_40		97
        +rc2_40_cbc		98
        +givenName		99
        +surname		100
        +initials		101
        +uniqueIdentifier		102
        +crl_distribution_points		103
        +md5WithRSA		104
        +serialNumber		105
        +title		106
        +description		107
        +cast5_cbc		108
        +cast5_ecb		109
        +cast5_cfb64		110
        +cast5_ofb64		111
        +pbeWithMD5AndCast5_CBC		112
        +dsaWithSHA1		113
        +md5_sha1		114
        +sha1WithRSA		115
        +dsa		116
        +ripemd160		117
        +ripemd160WithRSA		119
        +rc5_cbc		120
        +rc5_ecb		121
        +rc5_cfb64		122
        +rc5_ofb64		123
        +rle_compression		124
        +zlib_compression		125
        +ext_key_usage		126
        +id_pkix		127
        +id_kp		128
        +server_auth		129
        +client_auth		130
        +code_sign		131
        +email_protect		132
        +time_stamp		133
        +ms_code_ind		134
        +ms_code_com		135
        +ms_ctl_sign		136
        +ms_sgc		137
        +ms_efs		138
        +ns_sgc		139
        +delta_crl		140
        +crl_reason		141
        +invalidity_date		142
        +sxnet		143
        +pbe_WithSHA1And128BitRC4		144
        +pbe_WithSHA1And40BitRC4		145
        +pbe_WithSHA1And3_Key_TripleDES_CBC		146
        +pbe_WithSHA1And2_Key_TripleDES_CBC		147
        +pbe_WithSHA1And128BitRC2_CBC		148
        +pbe_WithSHA1And40BitRC2_CBC		149
        +keyBag		150
        +pkcs8ShroudedKeyBag		151
        +certBag		152
        +crlBag		153
        +secretBag		154
        +safeContentsBag		155
        +friendlyName		156
        +localKeyID		157
        +x509Certificate		158
        +sdsiCertificate		159
        +x509Crl		160
        +pbes2		161
        +pbmac1		162
        +hmacWithSHA1		163
        +id_qt_cps		164
        +id_qt_unotice		165
        +rc2_64_cbc		166
        +SMIMECapabilities		167
        +pbeWithMD2AndRC2_CBC		168
        +pbeWithMD5AndRC2_CBC		169
        +pbeWithSHA1AndDES_CBC		170
        +ms_ext_req		171
        +ext_req		172
        +name		173
        +dnQualifier		174
        +id_pe		175
        +id_ad		176
        +info_access		177
        +ad_OCSP		178
        +ad_ca_issuers		179
        +OCSP_sign		180
        +iso		181
        +member_body		182
        +ISO_US		183
        +X9_57		184
        +X9cm		185
        +pkcs1		186
        +pkcs5		187
        +SMIME		188
        +id_smime_mod		189
        +id_smime_ct		190
        +id_smime_aa		191
        +id_smime_alg		192
        +id_smime_cd		193
        +id_smime_spq		194
        +id_smime_cti		195
        +id_smime_mod_cms		196
        +id_smime_mod_ess		197
        +id_smime_mod_oid		198
        +id_smime_mod_msg_v3		199
        +id_smime_mod_ets_eSignature_88		200
        +id_smime_mod_ets_eSignature_97		201
        +id_smime_mod_ets_eSigPolicy_88		202
        +id_smime_mod_ets_eSigPolicy_97		203
        +id_smime_ct_receipt		204
        +id_smime_ct_authData		205
        +id_smime_ct_publishCert		206
        +id_smime_ct_TSTInfo		207
        +id_smime_ct_TDTInfo		208
        +id_smime_ct_contentInfo		209
        +id_smime_ct_DVCSRequestData		210
        +id_smime_ct_DVCSResponseData		211
        +id_smime_aa_receiptRequest		212
        +id_smime_aa_securityLabel		213
        +id_smime_aa_mlExpandHistory		214
        +id_smime_aa_contentHint		215
        +id_smime_aa_msgSigDigest		216
        +id_smime_aa_encapContentType		217
        +id_smime_aa_contentIdentifier		218
        +id_smime_aa_macValue		219
        +id_smime_aa_equivalentLabels		220
        +id_smime_aa_contentReference		221
        +id_smime_aa_encrypKeyPref		222
        +id_smime_aa_signingCertificate		223
        +id_smime_aa_smimeEncryptCerts		224
        +id_smime_aa_timeStampToken		225
        +id_smime_aa_ets_sigPolicyId		226
        +id_smime_aa_ets_commitmentType		227
        +id_smime_aa_ets_signerLocation		228
        +id_smime_aa_ets_signerAttr		229
        +id_smime_aa_ets_otherSigCert		230
        +id_smime_aa_ets_contentTimestamp		231
        +id_smime_aa_ets_CertificateRefs		232
        +id_smime_aa_ets_RevocationRefs		233
        +id_smime_aa_ets_certValues		234
        +id_smime_aa_ets_revocationValues		235
        +id_smime_aa_ets_escTimeStamp		236
        +id_smime_aa_ets_certCRLTimestamp		237
        +id_smime_aa_ets_archiveTimeStamp		238
        +id_smime_aa_signatureType		239
        +id_smime_aa_dvcs_dvc		240
        +id_smime_alg_ESDHwith3DES		241
        +id_smime_alg_ESDHwithRC2		242
        +id_smime_alg_3DESwrap		243
        +id_smime_alg_RC2wrap		244
        +id_smime_alg_ESDH		245
        +id_smime_alg_CMS3DESwrap		246
        +id_smime_alg_CMSRC2wrap		247
        +id_smime_cd_ldap		248
        +id_smime_spq_ets_sqt_uri		249
        +id_smime_spq_ets_sqt_unotice		250
        +id_smime_cti_ets_proofOfOrigin		251
        +id_smime_cti_ets_proofOfReceipt		252
        +id_smime_cti_ets_proofOfDelivery		253
        +id_smime_cti_ets_proofOfSender		254
        +id_smime_cti_ets_proofOfApproval		255
        +id_smime_cti_ets_proofOfCreation		256
        +md4		257
        +id_pkix_mod		258
        +id_qt		259
        +id_it		260
        +id_pkip		261
        +id_alg		262
        +id_cmc		263
        +id_on		264
        +id_pda		265
        +id_aca		266
        +id_qcs		267
        +id_cct		268
        +id_pkix1_explicit_88		269
        +id_pkix1_implicit_88		270
        +id_pkix1_explicit_93		271
        +id_pkix1_implicit_93		272
        +id_mod_crmf		273
        +id_mod_cmc		274
        +id_mod_kea_profile_88		275
        +id_mod_kea_profile_93		276
        +id_mod_cmp		277
        +id_mod_qualified_cert_88		278
        +id_mod_qualified_cert_93		279
        +id_mod_attribute_cert		280
        +id_mod_timestamp_protocol		281
        +id_mod_ocsp		282
        +id_mod_dvcs		283
        +id_mod_cmp2000		284
        +biometricInfo		285
        +qcStatements		286
        +ac_auditEntity		287
        +ac_targeting		288
        +aaControls		289
        +sbgp_ipAddrBlock		290
        +sbgp_autonomousSysNum		291
        +sbgp_routerIdentifier		292
        +textNotice		293
        +ipsecEndSystem		294
        +ipsecTunnel		295
        +ipsecUser		296
        +dvcs		297
        +id_it_caProtEncCert		298
        +id_it_signKeyPairTypes		299
        +id_it_encKeyPairTypes		300
        +id_it_preferredSymmAlg		301
        +id_it_caKeyUpdateInfo		302
        +id_it_currentCRL		303
        +id_it_unsupportedOIDs		304
        +id_it_subscriptionRequest		305
        +id_it_subscriptionResponse		306
        +id_it_keyPairParamReq		307
        +id_it_keyPairParamRep		308
        +id_it_revPassphrase		309
        +id_it_implicitConfirm		310
        +id_it_confirmWaitTime		311
        +id_it_origPKIMessage		312
        +id_regCtrl		313
        +id_regInfo		314
        +id_regCtrl_regToken		315
        +id_regCtrl_authenticator		316
        +id_regCtrl_pkiPublicationInfo		317
        +id_regCtrl_pkiArchiveOptions		318
        +id_regCtrl_oldCertID		319
        +id_regCtrl_protocolEncrKey		320
        +id_regInfo_utf8Pairs		321
        +id_regInfo_certReq		322
        +id_alg_des40		323
        +id_alg_noSignature		324
        +id_alg_dh_sig_hmac_sha1		325
        +id_alg_dh_pop		326
        +id_cmc_statusInfo		327
        +id_cmc_identification		328
        +id_cmc_identityProof		329
        +id_cmc_dataReturn		330
        +id_cmc_transactionId		331
        +id_cmc_senderNonce		332
        +id_cmc_recipientNonce		333
        +id_cmc_addExtensions		334
        +id_cmc_encryptedPOP		335
        +id_cmc_decryptedPOP		336
        +id_cmc_lraPOPWitness		337
        +id_cmc_getCert		338
        +id_cmc_getCRL		339
        +id_cmc_revokeRequest		340
        +id_cmc_regInfo		341
        +id_cmc_responseInfo		342
        +id_cmc_queryPending		343
        +id_cmc_popLinkRandom		344
        +id_cmc_popLinkWitness		345
        +id_cmc_confirmCertAcceptance		346
        +id_on_personalData		347
        +id_pda_dateOfBirth		348
        +id_pda_placeOfBirth		349
        +id_pda_pseudonym		350
        +id_pda_gender		351
        +id_pda_countryOfCitizenship		352
        +id_pda_countryOfResidence		353
        +id_aca_authenticationInfo		354
        +id_aca_accessIdentity		355
        +id_aca_chargingIdentity		356
        +id_aca_group		357
        +id_aca_role		358
        +id_qcs_pkixQCSyntax_v1		359
        +id_cct_crs		360
        +id_cct_PKIData		361
        +id_cct_PKIResponse		362
        +ad_timeStamping		363
        +ad_dvcs		364
        +id_pkix_OCSP_basic		365
        +id_pkix_OCSP_Nonce		366
        +id_pkix_OCSP_CrlID		367
        +id_pkix_OCSP_acceptableResponses		368
        +id_pkix_OCSP_noCheck		369
        +id_pkix_OCSP_archiveCutoff		370
        +id_pkix_OCSP_serviceLocator		371
        +id_pkix_OCSP_extendedStatus		372
        +id_pkix_OCSP_valid		373
        +id_pkix_OCSP_path		374
        +id_pkix_OCSP_trustRoot		375
        +algorithm		376
        +rsaSignature		377
        +X500algorithms		378
        +org		379
        +dod		380
        +iana		381
        +Directory		382
        +Management		383
        +Experimental		384
        +Private		385
        +Security		386
        +SNMPv2		387
        +Mail		388
        +Enterprises		389
        +dcObject		390
        +domainComponent		391
        +Domain		392
        +joint_iso_ccitt		393
        +selected_attribute_types		394
        +clearance		395
        +md4WithRSAEncryption		396
        +ac_proxying		397
        +sinfo_access		398
        +id_aca_encAttrs		399
        +role		400
        +policy_constraints		401
        +target_information		402
        +no_rev_avail		403
        +ccitt		404
        +ansi_X9_62		405
        +X9_62_prime_field		406
        +X9_62_characteristic_two_field		407
        +X9_62_id_ecPublicKey		408
        +X9_62_prime192v1		409
        +X9_62_prime192v2		410
        +X9_62_prime192v3		411
        +X9_62_prime239v1		412
        +X9_62_prime239v2		413
        +X9_62_prime239v3		414
        +X9_62_prime256v1		415
        +ecdsa_with_SHA1		416
        +ms_csp_name		417
        +aes_128_ecb		418
        +aes_128_cbc		419
        +aes_128_ofb128		420
        +aes_128_cfb128		421
        +aes_192_ecb		422
        +aes_192_cbc		423
        +aes_192_ofb128		424
        +aes_192_cfb128		425
        +aes_256_ecb		426
        +aes_256_cbc		427
        +aes_256_ofb128		428
        +aes_256_cfb128		429
        +hold_instruction_code		430
        +hold_instruction_none		431
        +hold_instruction_call_issuer		432
        +hold_instruction_reject		433
        +data		434
        +pss		435
        +ucl		436
        +pilot		437
        +pilotAttributeType		438
        +pilotAttributeSyntax		439
        +pilotObjectClass		440
        +pilotGroups		441
        +iA5StringSyntax		442
        +caseIgnoreIA5StringSyntax		443
        +pilotObject		444
        +pilotPerson		445
        +account		446
        +document		447
        +room		448
        +documentSeries		449
        +rFC822localPart		450
        +dNSDomain		451
        +domainRelatedObject		452
        +friendlyCountry		453
        +simpleSecurityObject		454
        +pilotOrganization		455
        +pilotDSA		456
        +qualityLabelledData		457
        +userId		458
        +textEncodedORAddress		459
        +rfc822Mailbox		460
        +info		461
        +favouriteDrink		462
        +roomNumber		463
        +photo		464
        +userClass		465
        +host		466
        +manager		467
        +documentIdentifier		468
        +documentTitle		469
        +documentVersion		470
        +documentAuthor		471
        +documentLocation		472
        +homeTelephoneNumber		473
        +secretary		474
        +otherMailbox		475
        +lastModifiedTime		476
        +lastModifiedBy		477
        +aRecord		478
        +pilotAttributeType27		479
        +mXRecord		480
        +nSRecord		481
        +sOARecord		482
        +cNAMERecord		483
        +associatedDomain		484
        +associatedName		485
        +homePostalAddress		486
        +personalTitle		487
        +mobileTelephoneNumber		488
        +pagerTelephoneNumber		489
        +friendlyCountryName		490
        +organizationalStatus		491
        +janetMailbox		492
        +mailPreferenceOption		493
        +buildingName		494
        +dSAQuality		495
        +singleLevelQuality		496
        +subtreeMinimumQuality		497
        +subtreeMaximumQuality		498
        +personalSignature		499
        +dITRedirect		500
        +audio		501
        +documentPublisher		502
        +x500UniqueIdentifier		503
        +mime_mhs		504
        +mime_mhs_headings		505
        +mime_mhs_bodies		506
        +id_hex_partial_message		507
        +id_hex_multipart_message		508
        +generationQualifier		509
        +pseudonym		510
        +InternationalRA		511
        +id_set		512
        +set_ctype		513
        +set_msgExt		514
        +set_attr		515
        +set_policy		516
        +set_certExt		517
        +set_brand		518
        +setct_PANData		519
        +setct_PANToken		520
        +setct_PANOnly		521
        +setct_OIData		522
        +setct_PI		523
        +setct_PIData		524
        +setct_PIDataUnsigned		525
        +setct_HODInput		526
        +setct_AuthResBaggage		527
        +setct_AuthRevReqBaggage		528
        +setct_AuthRevResBaggage		529
        +setct_CapTokenSeq		530
        +setct_PInitResData		531
        +setct_PI_TBS		532
        +setct_PResData		533
        +setct_AuthReqTBS		534
        +setct_AuthResTBS		535
        +setct_AuthResTBSX		536
        +setct_AuthTokenTBS		537
        +setct_CapTokenData		538
        +setct_CapTokenTBS		539
        +setct_AcqCardCodeMsg		540
        +setct_AuthRevReqTBS		541
        +setct_AuthRevResData		542
        +setct_AuthRevResTBS		543
        +setct_CapReqTBS		544
        +setct_CapReqTBSX		545
        +setct_CapResData		546
        +setct_CapRevReqTBS		547
        +setct_CapRevReqTBSX		548
        +setct_CapRevResData		549
        +setct_CredReqTBS		550
        +setct_CredReqTBSX		551
        +setct_CredResData		552
        +setct_CredRevReqTBS		553
        +setct_CredRevReqTBSX		554
        +setct_CredRevResData		555
        +setct_PCertReqData		556
        +setct_PCertResTBS		557
        +setct_BatchAdminReqData		558
        +setct_BatchAdminResData		559
        +setct_CardCInitResTBS		560
        +setct_MeAqCInitResTBS		561
        +setct_RegFormResTBS		562
        +setct_CertReqData		563
        +setct_CertReqTBS		564
        +setct_CertResData		565
        +setct_CertInqReqTBS		566
        +setct_ErrorTBS		567
        +setct_PIDualSignedTBE		568
        +setct_PIUnsignedTBE		569
        +setct_AuthReqTBE		570
        +setct_AuthResTBE		571
        +setct_AuthResTBEX		572
        +setct_AuthTokenTBE		573
        +setct_CapTokenTBE		574
        +setct_CapTokenTBEX		575
        +setct_AcqCardCodeMsgTBE		576
        +setct_AuthRevReqTBE		577
        +setct_AuthRevResTBE		578
        +setct_AuthRevResTBEB		579
        +setct_CapReqTBE		580
        +setct_CapReqTBEX		581
        +setct_CapResTBE		582
        +setct_CapRevReqTBE		583
        +setct_CapRevReqTBEX		584
        +setct_CapRevResTBE		585
        +setct_CredReqTBE		586
        +setct_CredReqTBEX		587
        +setct_CredResTBE		588
        +setct_CredRevReqTBE		589
        +setct_CredRevReqTBEX		590
        +setct_CredRevResTBE		591
        +setct_BatchAdminReqTBE		592
        +setct_BatchAdminResTBE		593
        +setct_RegFormReqTBE		594
        +setct_CertReqTBE		595
        +setct_CertReqTBEX		596
        +setct_CertResTBE		597
        +setct_CRLNotificationTBS		598
        +setct_CRLNotificationResTBS		599
        +setct_BCIDistributionTBS		600
        +setext_genCrypt		601
        +setext_miAuth		602
        +setext_pinSecure		603
        +setext_pinAny		604
        +setext_track2		605
        +setext_cv		606
        +set_policy_root		607
        +setCext_hashedRoot		608
        +setCext_certType		609
        +setCext_merchData		610
        +setCext_cCertRequired		611
        +setCext_tunneling		612
        +setCext_setExt		613
        +setCext_setQualf		614
        +setCext_PGWYcapabilities		615
        +setCext_TokenIdentifier		616
        +setCext_Track2Data		617
        +setCext_TokenType		618
        +setCext_IssuerCapabilities		619
        +setAttr_Cert		620
        +setAttr_PGWYcap		621
        +setAttr_TokenType		622
        +setAttr_IssCap		623
        +set_rootKeyThumb		624
        +set_addPolicy		625
        +setAttr_Token_EMV		626
        +setAttr_Token_B0Prime		627
        +setAttr_IssCap_CVM		628
        +setAttr_IssCap_T2		629
        +setAttr_IssCap_Sig		630
        +setAttr_GenCryptgrm		631
        +setAttr_T2Enc		632
        +setAttr_T2cleartxt		633
        +setAttr_TokICCsig		634
        +setAttr_SecDevSig		635
        +set_brand_IATA_ATA		636
        +set_brand_Diners		637
        +set_brand_AmericanExpress		638
        +set_brand_JCB		639
        +set_brand_Visa		640
        +set_brand_MasterCard		641
        +set_brand_Novus		642
        +des_cdmf		643
        +rsaOAEPEncryptionSET		644
        +itu_t		645
        +joint_iso_itu_t		646
        +international_organizations		647
        +ms_smartcard_login		648
        +ms_upn		649
        +aes_128_cfb1		650
        +aes_192_cfb1		651
        +aes_256_cfb1		652
        +aes_128_cfb8		653
        +aes_192_cfb8		654
        +aes_256_cfb8		655
        +des_cfb1		656
        +des_cfb8		657
        +des_ede3_cfb1		658
        +des_ede3_cfb8		659
        +streetAddress		660
        +postalCode		661
        +id_ppl		662
        +proxyCertInfo		663
        +id_ppl_anyLanguage		664
        +id_ppl_inheritAll		665
        +name_constraints		666
        +Independent		667
        +sha256WithRSAEncryption		668
        +sha384WithRSAEncryption		669
        +sha512WithRSAEncryption		670
        +sha224WithRSAEncryption		671
        +sha256		672
        +sha384		673
        +sha512		674
        +sha224		675
        +identified_organization		676
        +certicom_arc		677
        +wap		678
        +wap_wsg		679
        +X9_62_id_characteristic_two_basis		680
        +X9_62_onBasis		681
        +X9_62_tpBasis		682
        +X9_62_ppBasis		683
        +X9_62_c2pnb163v1		684
        +X9_62_c2pnb163v2		685
        +X9_62_c2pnb163v3		686
        +X9_62_c2pnb176v1		687
        +X9_62_c2tnb191v1		688
        +X9_62_c2tnb191v2		689
        +X9_62_c2tnb191v3		690
        +X9_62_c2onb191v4		691
        +X9_62_c2onb191v5		692
        +X9_62_c2pnb208w1		693
        +X9_62_c2tnb239v1		694
        +X9_62_c2tnb239v2		695
        +X9_62_c2tnb239v3		696
        +X9_62_c2onb239v4		697
        +X9_62_c2onb239v5		698
        +X9_62_c2pnb272w1		699
        +X9_62_c2pnb304w1		700
        +X9_62_c2tnb359v1		701
        +X9_62_c2pnb368w1		702
        +X9_62_c2tnb431r1		703
        +secp112r1		704
        +secp112r2		705
        +secp128r1		706
        +secp128r2		707
        +secp160k1		708
        +secp160r1		709
        +secp160r2		710
        +secp192k1		711
        +secp224k1		712
        +secp224r1		713
        +secp256k1		714
        +secp384r1		715
        +secp521r1		716
        +sect113r1		717
        +sect113r2		718
        +sect131r1		719
        +sect131r2		720
        +sect163k1		721
        +sect163r1		722
        +sect163r2		723
        +sect193r1		724
        +sect193r2		725
        +sect233k1		726
        +sect233r1		727
        +sect239k1		728
        +sect283k1		729
        +sect283r1		730
        +sect409k1		731
        +sect409r1		732
        +sect571k1		733
        +sect571r1		734
        +wap_wsg_idm_ecid_wtls1		735
        +wap_wsg_idm_ecid_wtls3		736
        +wap_wsg_idm_ecid_wtls4		737
        +wap_wsg_idm_ecid_wtls5		738
        +wap_wsg_idm_ecid_wtls6		739
        +wap_wsg_idm_ecid_wtls7		740
        +wap_wsg_idm_ecid_wtls8		741
        +wap_wsg_idm_ecid_wtls9		742
        +wap_wsg_idm_ecid_wtls10		743
        +wap_wsg_idm_ecid_wtls11		744
        +wap_wsg_idm_ecid_wtls12		745
        +any_policy		746
        +policy_mappings		747
        +inhibit_any_policy		748
        +ipsec3		749
        +ipsec4		750
        +camellia_128_cbc		751
        +camellia_192_cbc		752
        +camellia_256_cbc		753
        +camellia_128_ecb		754
        +camellia_192_ecb		755
        +camellia_256_ecb		756
        +camellia_128_cfb128		757
        +camellia_192_cfb128		758
        +camellia_256_cfb128		759
        +camellia_128_cfb1		760
        +camellia_192_cfb1		761
        +camellia_256_cfb1		762
        +camellia_128_cfb8		763
        +camellia_192_cfb8		764
        +camellia_256_cfb8		765
        +camellia_128_ofb128		766
        +camellia_192_ofb128		767
        +camellia_256_ofb128		768
        +subject_directory_attributes		769
        +issuing_distribution_point		770
        +certificate_issuer		771
        +korea		772
        +kisa		773
        +kftc		774
        +npki_alg		775
        +seed_ecb		776
        +seed_cbc		777
        +seed_ofb128		778
        +seed_cfb128		779
        +hmac_md5		780
        +hmac_sha1		781
        +id_PasswordBasedMAC		782
        +id_DHBasedMac		783
        +id_it_suppLangTags		784
        +caRepository		785
        +id_smime_ct_compressedData		786
        +id_ct_asciiTextWithCRLF		787
        +id_aes128_wrap		788
        +id_aes192_wrap		789
        +id_aes256_wrap		790
        +ecdsa_with_Recommended		791
        +ecdsa_with_Specified		792
        +ecdsa_with_SHA224		793
        +ecdsa_with_SHA256		794
        +ecdsa_with_SHA384		795
        +ecdsa_with_SHA512		796
        +hmacWithMD5		797
        +hmacWithSHA224		798
        +hmacWithSHA256		799
        +hmacWithSHA384		800
        +hmacWithSHA512		801
        +dsa_with_SHA224		802
        +dsa_with_SHA256		803
        +whirlpool		804
        +cryptopro		805
        +cryptocom		806
        +id_GostR3411_94_with_GostR3410_2001		807
        +id_GostR3411_94_with_GostR3410_94		808
        +id_GostR3411_94		809
        +id_HMACGostR3411_94		810
        +id_GostR3410_2001		811
        +id_GostR3410_94		812
        +id_Gost28147_89		813
        +gost89_cnt		814
        +id_Gost28147_89_MAC		815
        +id_GostR3411_94_prf		816
        +id_GostR3410_2001DH		817
        +id_GostR3410_94DH		818
        +id_Gost28147_89_CryptoPro_KeyMeshing		819
        +id_Gost28147_89_None_KeyMeshing		820
        +id_GostR3411_94_TestParamSet		821
        +id_GostR3411_94_CryptoProParamSet		822
        +id_Gost28147_89_TestParamSet		823
        +id_Gost28147_89_CryptoPro_A_ParamSet		824
        +id_Gost28147_89_CryptoPro_B_ParamSet		825
        +id_Gost28147_89_CryptoPro_C_ParamSet		826
        +id_Gost28147_89_CryptoPro_D_ParamSet		827
        +id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
        +id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
        +id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
        +id_GostR3410_94_TestParamSet		831
        +id_GostR3410_94_CryptoPro_A_ParamSet		832
        +id_GostR3410_94_CryptoPro_B_ParamSet		833
        +id_GostR3410_94_CryptoPro_C_ParamSet		834
        +id_GostR3410_94_CryptoPro_D_ParamSet		835
        +id_GostR3410_94_CryptoPro_XchA_ParamSet		836
        +id_GostR3410_94_CryptoPro_XchB_ParamSet		837
        +id_GostR3410_94_CryptoPro_XchC_ParamSet		838
        +id_GostR3410_2001_TestParamSet		839
        +id_GostR3410_2001_CryptoPro_A_ParamSet		840
        +id_GostR3410_2001_CryptoPro_B_ParamSet		841
        +id_GostR3410_2001_CryptoPro_C_ParamSet		842
        +id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
        +id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
        +id_GostR3410_94_a		845
        +id_GostR3410_94_aBis		846
        +id_GostR3410_94_b		847
        +id_GostR3410_94_bBis		848
        +id_Gost28147_89_cc		849
        +id_GostR3410_94_cc		850
        +id_GostR3410_2001_cc		851
        +id_GostR3411_94_with_GostR3410_94_cc		852
        +id_GostR3411_94_with_GostR3410_2001_cc		853
        +id_GostR3410_2001_ParamSet_cc		854
        +hmac		855
        +LocalKeySet		856
        +freshest_crl		857
        +id_on_permanentIdentifier		858
        +searchGuide		859
        +businessCategory		860
        +postalAddress		861
        +postOfficeBox		862
        +physicalDeliveryOfficeName		863
        +telephoneNumber		864
        +telexNumber		865
        +teletexTerminalIdentifier		866
        +facsimileTelephoneNumber		867
        +x121Address		868
        +internationaliSDNNumber		869
        +registeredAddress		870
        +destinationIndicator		871
        +preferredDeliveryMethod		872
        +presentationAddress		873
        +supportedApplicationContext		874
        +member		875
        +owner		876
        +roleOccupant		877
        +seeAlso		878
        +userPassword		879
        +userCertificate		880
        +cACertificate		881
        +authorityRevocationList		882
        +certificateRevocationList		883
        +crossCertificatePair		884
        +enhancedSearchGuide		885
        +protocolInformation		886
        +distinguishedName		887
        +uniqueMember		888
        +houseIdentifier		889
        +supportedAlgorithms		890
        +deltaRevocationList		891
        +dmdName		892
        +id_alg_PWRI_KEK		893
        +cmac		894
        +aes_128_gcm		895
        +aes_128_ccm		896
        +id_aes128_wrap_pad		897
        +aes_192_gcm		898
        +aes_192_ccm		899
        +id_aes192_wrap_pad		900
        +aes_256_gcm		901
        +aes_256_ccm		902
        +id_aes256_wrap_pad		903
        +aes_128_ctr		904
        +aes_192_ctr		905
        +aes_256_ctr		906
        +id_camellia128_wrap		907
        +id_camellia192_wrap		908
        +id_camellia256_wrap		909
        +anyExtendedKeyUsage		910
        +mgf1		911
        +rsassaPss		912
        +aes_128_xts		913
        +aes_256_xts		914
        +rc4_hmac_md5		915
        +aes_128_cbc_hmac_sha1		916
        +aes_192_cbc_hmac_sha1		917
        +aes_256_cbc_hmac_sha1		918
        +rsaesOaep		919
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_xref.c b/vendor/openssl/openssl/crypto/objects/obj_xref.c
        new file mode 100644
        index 000000000..9f744bced
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_xref.c
        @@ -0,0 +1,234 @@
        +/* crypto/objects/obj_xref.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <openssl/objects.h>
        +#include "obj_xref.h"
        +
        +DECLARE_STACK_OF(nid_triple)
        +STACK_OF(nid_triple) *sig_app, *sigx_app;
        +
        +static int sig_cmp(const nid_triple *a, const nid_triple *b)
        +	{
        +	return a->sign_id - b->sign_id;
        +	}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
        +
        +static int sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b)
        +	{
        +	return (*a)->sign_id - (*b)->sign_id;
        +	}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
        +
        +static int sigx_cmp(const nid_triple * const *a, const nid_triple * const *b)
        +	{
        +	int ret;
        +	ret = (*a)->hash_id - (*b)->hash_id;
        +	if (ret)
        +		return ret;
        +	return (*a)->pkey_id - (*b)->pkey_id;
        +	}
        +
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
        +
        +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
        +	{
        +	nid_triple tmp;
        +	const nid_triple *rv = NULL;
        +	tmp.sign_id = signid;
        +
        +	if (sig_app)
        +		{
        +		int idx = sk_nid_triple_find(sig_app, &tmp);
        +		if (idx >= 0)
        +			rv = sk_nid_triple_value(sig_app, idx);
        +		}
        +
        +#ifndef OBJ_XREF_TEST2
        +	if (rv == NULL)
        +		{
        +		rv = OBJ_bsearch_sig(&tmp, sigoid_srt,
        +				 sizeof(sigoid_srt) / sizeof(nid_triple));
        +		}
        +#endif
        +	if (rv == NULL)
        +		return 0;
        +	if (pdig_nid)
        +		*pdig_nid = rv->hash_id;
        +	if (ppkey_nid)
        +		*ppkey_nid = rv->pkey_id;
        +	return 1;
        +	}
        +
        +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
        +	{
        +	nid_triple tmp;
        +	const nid_triple *t=&tmp;
        +	const nid_triple **rv = NULL;
        +
        +	tmp.hash_id = dig_nid;
        +	tmp.pkey_id = pkey_nid;
        +
        +	if (sigx_app)
        +		{
        +		int idx = sk_nid_triple_find(sigx_app, &tmp);
        +		if (idx >= 0)
        +			{
        +			t = sk_nid_triple_value(sigx_app, idx);
        +			rv = &t;
        +			}
        +		}
        +
        +#ifndef OBJ_XREF_TEST2
        +	if (rv == NULL)
        +		{
        +		rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref,
        +				 sizeof(sigoid_srt_xref) / sizeof(nid_triple *)
        +				 );
        +		}
        +#endif
        +	if (rv == NULL)
        +		return 0;
        +	if (psignid)
        +		*psignid = (*rv)->sign_id;
        +	return 1;
        +	}
        +
        +int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
        +	{
        +	nid_triple *ntr;
        +	if (!sig_app)
        +		sig_app = sk_nid_triple_new(sig_sk_cmp);
        +	if (!sig_app)
        +		return 0;
        +	if (!sigx_app)
        +		sigx_app = sk_nid_triple_new(sigx_cmp);
        +	if (!sigx_app)
        +		return 0;
        +	ntr = OPENSSL_malloc(sizeof(int) * 3);
        +	if (!ntr)
        +		return 0;
        +	ntr->sign_id = signid;
        +	ntr->hash_id = dig_id;
        +	ntr->pkey_id = pkey_id;
        +
        +	if (!sk_nid_triple_push(sig_app, ntr))
        +		{
        +		OPENSSL_free(ntr);
        +		return 0;
        +		}
        +
        +	if (!sk_nid_triple_push(sigx_app, ntr))
        +		return 0;
        +
        +	sk_nid_triple_sort(sig_app);
        +	sk_nid_triple_sort(sigx_app);
        +
        +	return 1;
        +	}
        +
        +static void sid_free(nid_triple *tt)
        +	{
        +	OPENSSL_free(tt);
        +	}
        +
        +void OBJ_sigid_free(void)
        +	{
        +	if (sig_app)
        +		{
        +		sk_nid_triple_pop_free(sig_app, sid_free);
        +		sig_app = NULL;
        +		}
        +	if (sigx_app)
        +		{
        +		sk_nid_triple_free(sigx_app);
        +		sigx_app = NULL;
        +		}
        +	}
        +		
        +#ifdef OBJ_XREF_TEST
        +
        +main()
        +	{
        +	int n1, n2, n3;
        +
        +	int i, rv;
        +#ifdef OBJ_XREF_TEST2
        +	for (i = 0; i <	sizeof(sigoid_srt) / sizeof(nid_triple); i++)
        +		{
        +		OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1],
        +				sigoid_srt[i][2]);
        +		}
        +#endif
        +
        +	for (i = 0; i <	sizeof(sigoid_srt) / sizeof(nid_triple); i++)
        +		{
        +		n1 = sigoid_srt[i][0];
        +		rv = OBJ_find_sigid_algs(n1, &n2, &n3);
        +		printf("Forward: %d, %s %s %s\n", rv,
        +			OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
        +		n1=0;
        +		rv = OBJ_find_sigid_by_algs(&n1, n2, n3);
        +		printf("Reverse: %d, %s %s %s\n", rv,
        +			OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
        +		}
        +	}
        +	
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_xref.h b/vendor/openssl/openssl/crypto/objects/obj_xref.h
        new file mode 100644
        index 000000000..e23938c29
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_xref.h
        @@ -0,0 +1,77 @@
        +/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
        +
        +typedef struct
        +	{
        +	int sign_id;
        +	int hash_id;
        +	int pkey_id;
        +	} nid_triple;
        +
        +static const nid_triple sigoid_srt[] =
        +	{
        +	{NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
        +	{NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
        +	{NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
        +	{NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
        +	{NID_dsaWithSHA, NID_sha, NID_dsa},
        +	{NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
        +	{NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
        +	{NID_md5WithRSA, NID_md5, NID_rsa},
        +	{NID_dsaWithSHA1, NID_sha1, NID_dsa},
        +	{NID_sha1WithRSA, NID_sha1, NID_rsa},
        +	{NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
        +	{NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
        +	{NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
        +	{NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
        +	{NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
        +	{NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
        +	{NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
        +	{NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
        +	{NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
        +	{NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
        +	{NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
        +	{NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
        +	{NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
        +	{NID_dsa_with_SHA224, NID_sha224, NID_dsa},
        +	{NID_dsa_with_SHA256, NID_sha256, NID_dsa},
        +	{NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001},
        +	{NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
        +	{NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
        +	{NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
        +	{NID_rsassaPss, NID_undef, NID_rsaEncryption},
        +	};
        +
        +static const nid_triple * const sigoid_srt_xref[] =
        +	{
        +	&sigoid_srt[29],
        +	&sigoid_srt[17],
        +	&sigoid_srt[18],
        +	&sigoid_srt[0],
        +	&sigoid_srt[1],
        +	&sigoid_srt[7],
        +	&sigoid_srt[2],
        +	&sigoid_srt[4],
        +	&sigoid_srt[3],
        +	&sigoid_srt[9],
        +	&sigoid_srt[5],
        +	&sigoid_srt[8],
        +	&sigoid_srt[12],
        +	&sigoid_srt[6],
        +	&sigoid_srt[10],
        +	&sigoid_srt[11],
        +	&sigoid_srt[13],
        +	&sigoid_srt[24],
        +	&sigoid_srt[20],
        +	&sigoid_srt[14],
        +	&sigoid_srt[21],
        +	&sigoid_srt[15],
        +	&sigoid_srt[22],
        +	&sigoid_srt[16],
        +	&sigoid_srt[23],
        +	&sigoid_srt[19],
        +	&sigoid_srt[25],
        +	&sigoid_srt[26],
        +	&sigoid_srt[27],
        +	&sigoid_srt[28],
        +	};
        +
        diff --git a/vendor/openssl/openssl/crypto/objects/obj_xref.txt b/vendor/openssl/openssl/crypto/objects/obj_xref.txt
        new file mode 100644
        index 000000000..cb917182e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/obj_xref.txt
        @@ -0,0 +1,46 @@
        +# OID cross reference table.
        +# Links signatures OIDs to their corresponding public key algorithms
        +# and digests.
        +
        +md2WithRSAEncryption	md2	rsaEncryption
        +md5WithRSAEncryption	md5	rsaEncryption
        +shaWithRSAEncryption	sha	rsaEncryption
        +sha1WithRSAEncryption	sha1	rsaEncryption
        +md4WithRSAEncryption	md4	rsaEncryption
        +sha256WithRSAEncryption sha256	rsaEncryption
        +sha384WithRSAEncryption	sha384	rsaEncryption
        +sha512WithRSAEncryption	sha512	rsaEncryption
        +sha224WithRSAEncryption	sha224	rsaEncryption
        +mdc2WithRSA		mdc2	rsaEncryption
        +ripemd160WithRSA	ripemd160 rsaEncryption
        +# For PSS the digest algorithm can vary and depends on the included
        +# AlgorithmIdentifier. The digest "undef" indicates the public key
        +# method should handle this explicitly.
        +rsassaPss		undef	rsaEncryption
        +
        +# Alternative deprecated OIDs. By using the older "rsa" OID this
        +# type will be recognized by not normally used.
        +
        +md5WithRSA		md5	rsa
        +sha1WithRSA		sha1	rsa
        +
        +dsaWithSHA		sha	dsa
        +dsaWithSHA1		sha1	dsa
        +
        +dsaWithSHA1_2		sha1	dsa_2
        +
        +ecdsa_with_SHA1		sha1	X9_62_id_ecPublicKey
        +ecdsa_with_SHA224	sha224	X9_62_id_ecPublicKey
        +ecdsa_with_SHA256	sha256	X9_62_id_ecPublicKey
        +ecdsa_with_SHA384	sha384	X9_62_id_ecPublicKey
        +ecdsa_with_SHA512	sha512	X9_62_id_ecPublicKey
        +ecdsa_with_Recommended	undef	X9_62_id_ecPublicKey
        +ecdsa_with_Specified	undef	X9_62_id_ecPublicKey
        +
        +dsa_with_SHA224		sha224	dsa
        +dsa_with_SHA256		sha256	dsa
        +
        +id_GostR3411_94_with_GostR3410_2001	id_GostR3411_94 id_GostR3410_2001
        +id_GostR3411_94_with_GostR3410_94	id_GostR3411_94 id_GostR3410_94
        +id_GostR3411_94_with_GostR3410_94_cc	id_GostR3411_94 id_GostR3410_94_cc
        +id_GostR3411_94_with_GostR3410_2001_cc	id_GostR3411_94 id_GostR3410_2001_cc
        diff --git a/vendor/openssl/openssl/crypto/objects/objects.README b/vendor/openssl/openssl/crypto/objects/objects.README
        new file mode 100644
        index 000000000..4d745508d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/objects.README
        @@ -0,0 +1,44 @@
        +objects.txt syntax
        +------------------
        +
        +To cover all the naming hacks that were previously in objects.h needed some
        +kind of hacks in objects.txt.
        +
        +The basic syntax for adding an object is as follows:
        +
        +	1 2 3 4		: shortName	: Long Name
        +
        +		If the long name doesn't contain spaces, or no short name
        +		exists, the long name is used as basis for the base name
        +		in C.  Otherwise, the short name is used.
        +
        +		The base name (let's call it 'base') will then be used to
        +		create the C macros SN_base, LN_base, NID_base and OBJ_base.
        +
        +		Note that if the base name contains spaces, dashes or periods,
        +		those will be converte to underscore.
        +
        +Then there are some extra commands:
        +
        +	!Alias foo 1 2 3 4
        +
        +		This juts makes a name foo for an OID.  The C macro
        +		OBJ_foo will be created as a result.
        +
        +	!Cname foo
        +
        +		This makes sure that the name foo will be used as base name
        +		in C.
        +
        +	!module foo
        +	1 2 3 4		: shortName	: Long Name
        +	!global
        +
        +		The !module command was meant to define a kind of modularity.
        +		What it does is to make sure the module name is prepended
        +		to the base name.  !global turns this off.  This construction
        +		is not recursive.
        +
        +Lines starting with # are treated as comments, as well as any line starting
        +with ! and not matching the commands above.
        +
        diff --git a/vendor/openssl/openssl/crypto/objects/objects.h b/vendor/openssl/openssl/crypto/objects/objects.h
        new file mode 100644
        index 000000000..bd0ee52fe
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/objects.h
        @@ -0,0 +1,1138 @@
        +/* crypto/objects/objects.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_OBJECTS_H
        +#define HEADER_OBJECTS_H
        +
        +#define USE_OBJ_MAC
        +
        +#ifdef USE_OBJ_MAC
        +#include <openssl/obj_mac.h>
        +#else
        +#define SN_undef			"UNDEF"
        +#define LN_undef			"undefined"
        +#define NID_undef			0
        +#define OBJ_undef			0L
        +
        +#define SN_Algorithm			"Algorithm"
        +#define LN_algorithm			"algorithm"
        +#define NID_algorithm			38
        +#define OBJ_algorithm			1L,3L,14L,3L,2L
        +
        +#define LN_rsadsi			"rsadsi"
        +#define NID_rsadsi			1
        +#define OBJ_rsadsi			1L,2L,840L,113549L
        +
        +#define LN_pkcs				"pkcs"
        +#define NID_pkcs			2
        +#define OBJ_pkcs			OBJ_rsadsi,1L
        +
        +#define SN_md2				"MD2"
        +#define LN_md2				"md2"
        +#define NID_md2				3
        +#define OBJ_md2				OBJ_rsadsi,2L,2L
        +
        +#define SN_md5				"MD5"
        +#define LN_md5				"md5"
        +#define NID_md5				4
        +#define OBJ_md5				OBJ_rsadsi,2L,5L
        +
        +#define SN_rc4				"RC4"
        +#define LN_rc4				"rc4"
        +#define NID_rc4				5
        +#define OBJ_rc4				OBJ_rsadsi,3L,4L
        +
        +#define LN_rsaEncryption		"rsaEncryption"
        +#define NID_rsaEncryption		6
        +#define OBJ_rsaEncryption		OBJ_pkcs,1L,1L
        +
        +#define SN_md2WithRSAEncryption		"RSA-MD2"
        +#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
        +#define NID_md2WithRSAEncryption	7
        +#define OBJ_md2WithRSAEncryption	OBJ_pkcs,1L,2L
        +
        +#define SN_md5WithRSAEncryption		"RSA-MD5"
        +#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
        +#define NID_md5WithRSAEncryption	8
        +#define OBJ_md5WithRSAEncryption	OBJ_pkcs,1L,4L
        +
        +#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
        +#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
        +#define NID_pbeWithMD2AndDES_CBC	9
        +#define OBJ_pbeWithMD2AndDES_CBC	OBJ_pkcs,5L,1L
        +
        +#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
        +#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
        +#define NID_pbeWithMD5AndDES_CBC	10
        +#define OBJ_pbeWithMD5AndDES_CBC	OBJ_pkcs,5L,3L
        +
        +#define LN_X500				"X500"
        +#define NID_X500			11
        +#define OBJ_X500			2L,5L
        +
        +#define LN_X509				"X509"
        +#define NID_X509			12
        +#define OBJ_X509			OBJ_X500,4L
        +
        +#define SN_commonName			"CN"
        +#define LN_commonName			"commonName"
        +#define NID_commonName			13
        +#define OBJ_commonName			OBJ_X509,3L
        +
        +#define SN_countryName			"C"
        +#define LN_countryName			"countryName"
        +#define NID_countryName			14
        +#define OBJ_countryName			OBJ_X509,6L
        +
        +#define SN_localityName			"L"
        +#define LN_localityName			"localityName"
        +#define NID_localityName		15
        +#define OBJ_localityName		OBJ_X509,7L
        +
        +/* Postal Address? PA */
        +
        +/* should be "ST" (rfc1327) but MS uses 'S' */
        +#define SN_stateOrProvinceName		"ST"
        +#define LN_stateOrProvinceName		"stateOrProvinceName"
        +#define NID_stateOrProvinceName		16
        +#define OBJ_stateOrProvinceName		OBJ_X509,8L
        +
        +#define SN_organizationName		"O"
        +#define LN_organizationName		"organizationName"
        +#define NID_organizationName		17
        +#define OBJ_organizationName		OBJ_X509,10L
        +
        +#define SN_organizationalUnitName	"OU"
        +#define LN_organizationalUnitName	"organizationalUnitName"
        +#define NID_organizationalUnitName	18
        +#define OBJ_organizationalUnitName	OBJ_X509,11L
        +
        +#define SN_rsa				"RSA"
        +#define LN_rsa				"rsa"
        +#define NID_rsa				19
        +#define OBJ_rsa				OBJ_X500,8L,1L,1L
        +
        +#define LN_pkcs7			"pkcs7"
        +#define NID_pkcs7			20
        +#define OBJ_pkcs7			OBJ_pkcs,7L
        +
        +#define LN_pkcs7_data			"pkcs7-data"
        +#define NID_pkcs7_data			21
        +#define OBJ_pkcs7_data			OBJ_pkcs7,1L
        +
        +#define LN_pkcs7_signed			"pkcs7-signedData"
        +#define NID_pkcs7_signed		22
        +#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
        +
        +#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
        +#define NID_pkcs7_enveloped		23
        +#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
        +
        +#define LN_pkcs7_signedAndEnveloped	"pkcs7-signedAndEnvelopedData"
        +#define NID_pkcs7_signedAndEnveloped	24
        +#define OBJ_pkcs7_signedAndEnveloped	OBJ_pkcs7,4L
        +
        +#define LN_pkcs7_digest			"pkcs7-digestData"
        +#define NID_pkcs7_digest		25
        +#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
        +
        +#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
        +#define NID_pkcs7_encrypted		26
        +#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
        +
        +#define LN_pkcs3			"pkcs3"
        +#define NID_pkcs3			27
        +#define OBJ_pkcs3			OBJ_pkcs,3L
        +
        +#define LN_dhKeyAgreement		"dhKeyAgreement"
        +#define NID_dhKeyAgreement		28
        +#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
        +
        +#define SN_des_ecb			"DES-ECB"
        +#define LN_des_ecb			"des-ecb"
        +#define NID_des_ecb			29
        +#define OBJ_des_ecb			OBJ_algorithm,6L
        +
        +#define SN_des_cfb64			"DES-CFB"
        +#define LN_des_cfb64			"des-cfb"
        +#define NID_des_cfb64			30
        +/* IV + num */
        +#define OBJ_des_cfb64			OBJ_algorithm,9L
        +
        +#define SN_des_cbc			"DES-CBC"
        +#define LN_des_cbc			"des-cbc"
        +#define NID_des_cbc			31
        +/* IV */
        +#define OBJ_des_cbc			OBJ_algorithm,7L
        +
        +#define SN_des_ede			"DES-EDE"
        +#define LN_des_ede			"des-ede"
        +#define NID_des_ede			32
        +/* ?? */
        +#define OBJ_des_ede			OBJ_algorithm,17L
        +
        +#define SN_des_ede3			"DES-EDE3"
        +#define LN_des_ede3			"des-ede3"
        +#define NID_des_ede3			33
        +
        +#define SN_idea_cbc			"IDEA-CBC"
        +#define LN_idea_cbc			"idea-cbc"
        +#define NID_idea_cbc			34
        +#define OBJ_idea_cbc			1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
        +
        +#define SN_idea_cfb64			"IDEA-CFB"
        +#define LN_idea_cfb64			"idea-cfb"
        +#define NID_idea_cfb64			35
        +
        +#define SN_idea_ecb			"IDEA-ECB"
        +#define LN_idea_ecb			"idea-ecb"
        +#define NID_idea_ecb			36
        +
        +#define SN_rc2_cbc			"RC2-CBC"
        +#define LN_rc2_cbc			"rc2-cbc"
        +#define NID_rc2_cbc			37
        +#define OBJ_rc2_cbc			OBJ_rsadsi,3L,2L
        +
        +#define SN_rc2_ecb			"RC2-ECB"
        +#define LN_rc2_ecb			"rc2-ecb"
        +#define NID_rc2_ecb			38
        +
        +#define SN_rc2_cfb64			"RC2-CFB"
        +#define LN_rc2_cfb64			"rc2-cfb"
        +#define NID_rc2_cfb64			39
        +
        +#define SN_rc2_ofb64			"RC2-OFB"
        +#define LN_rc2_ofb64			"rc2-ofb"
        +#define NID_rc2_ofb64			40
        +
        +#define SN_sha				"SHA"
        +#define LN_sha				"sha"
        +#define NID_sha				41
        +#define OBJ_sha				OBJ_algorithm,18L
        +
        +#define SN_shaWithRSAEncryption		"RSA-SHA"
        +#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
        +#define NID_shaWithRSAEncryption	42
        +#define OBJ_shaWithRSAEncryption	OBJ_algorithm,15L
        +
        +#define SN_des_ede_cbc			"DES-EDE-CBC"
        +#define LN_des_ede_cbc			"des-ede-cbc"
        +#define NID_des_ede_cbc			43
        +
        +#define SN_des_ede3_cbc			"DES-EDE3-CBC"
        +#define LN_des_ede3_cbc			"des-ede3-cbc"
        +#define NID_des_ede3_cbc		44
        +#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
        +
        +#define SN_des_ofb64			"DES-OFB"
        +#define LN_des_ofb64			"des-ofb"
        +#define NID_des_ofb64			45
        +#define OBJ_des_ofb64			OBJ_algorithm,8L
        +
        +#define SN_idea_ofb64			"IDEA-OFB"
        +#define LN_idea_ofb64			"idea-ofb"
        +#define NID_idea_ofb64			46
        +
        +#define LN_pkcs9			"pkcs9"
        +#define NID_pkcs9			47
        +#define OBJ_pkcs9			OBJ_pkcs,9L
        +
        +#define SN_pkcs9_emailAddress		"Email"
        +#define LN_pkcs9_emailAddress		"emailAddress"
        +#define NID_pkcs9_emailAddress		48
        +#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
        +
        +#define LN_pkcs9_unstructuredName	"unstructuredName"
        +#define NID_pkcs9_unstructuredName	49
        +#define OBJ_pkcs9_unstructuredName	OBJ_pkcs9,2L
        +
        +#define LN_pkcs9_contentType		"contentType"
        +#define NID_pkcs9_contentType		50
        +#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
        +
        +#define LN_pkcs9_messageDigest		"messageDigest"
        +#define NID_pkcs9_messageDigest		51
        +#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
        +
        +#define LN_pkcs9_signingTime		"signingTime"
        +#define NID_pkcs9_signingTime		52
        +#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
        +
        +#define LN_pkcs9_countersignature	"countersignature"
        +#define NID_pkcs9_countersignature	53
        +#define OBJ_pkcs9_countersignature	OBJ_pkcs9,6L
        +
        +#define LN_pkcs9_challengePassword	"challengePassword"
        +#define NID_pkcs9_challengePassword	54
        +#define OBJ_pkcs9_challengePassword	OBJ_pkcs9,7L
        +
        +#define LN_pkcs9_unstructuredAddress	"unstructuredAddress"
        +#define NID_pkcs9_unstructuredAddress	55
        +#define OBJ_pkcs9_unstructuredAddress	OBJ_pkcs9,8L
        +
        +#define LN_pkcs9_extCertAttributes	"extendedCertificateAttributes"
        +#define NID_pkcs9_extCertAttributes	56
        +#define OBJ_pkcs9_extCertAttributes	OBJ_pkcs9,9L
        +
        +#define SN_netscape			"Netscape"
        +#define LN_netscape			"Netscape Communications Corp."
        +#define NID_netscape			57
        +#define OBJ_netscape			2L,16L,840L,1L,113730L
        +
        +#define SN_netscape_cert_extension	"nsCertExt"
        +#define LN_netscape_cert_extension	"Netscape Certificate Extension"
        +#define NID_netscape_cert_extension	58
        +#define OBJ_netscape_cert_extension	OBJ_netscape,1L
        +
        +#define SN_netscape_data_type		"nsDataType"
        +#define LN_netscape_data_type		"Netscape Data Type"
        +#define NID_netscape_data_type		59
        +#define OBJ_netscape_data_type		OBJ_netscape,2L
        +
        +#define SN_des_ede_cfb64		"DES-EDE-CFB"
        +#define LN_des_ede_cfb64		"des-ede-cfb"
        +#define NID_des_ede_cfb64		60
        +
        +#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
        +#define LN_des_ede3_cfb64		"des-ede3-cfb"
        +#define NID_des_ede3_cfb64		61
        +
        +#define SN_des_ede_ofb64		"DES-EDE-OFB"
        +#define LN_des_ede_ofb64		"des-ede-ofb"
        +#define NID_des_ede_ofb64		62
        +
        +#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
        +#define LN_des_ede3_ofb64		"des-ede3-ofb"
        +#define NID_des_ede3_ofb64		63
        +
        +/* I'm not sure about the object ID */
        +#define SN_sha1				"SHA1"
        +#define LN_sha1				"sha1"
        +#define NID_sha1			64
        +#define OBJ_sha1			OBJ_algorithm,26L
        +/* 28 Jun 1996 - eay */
        +/* #define OBJ_sha1			1L,3L,14L,2L,26L,05L <- wrong */
        +
        +#define SN_sha1WithRSAEncryption	"RSA-SHA1"
        +#define LN_sha1WithRSAEncryption	"sha1WithRSAEncryption"
        +#define NID_sha1WithRSAEncryption	65
        +#define OBJ_sha1WithRSAEncryption	OBJ_pkcs,1L,5L
        +
        +#define SN_dsaWithSHA			"DSA-SHA"
        +#define LN_dsaWithSHA			"dsaWithSHA"
        +#define NID_dsaWithSHA			66
        +#define OBJ_dsaWithSHA			OBJ_algorithm,13L
        +
        +#define SN_dsa_2			"DSA-old"
        +#define LN_dsa_2			"dsaEncryption-old"
        +#define NID_dsa_2			67
        +#define OBJ_dsa_2			OBJ_algorithm,12L
        +
        +/* proposed by microsoft to RSA */
        +#define SN_pbeWithSHA1AndRC2_CBC	"PBE-SHA1-RC2-64"
        +#define LN_pbeWithSHA1AndRC2_CBC	"pbeWithSHA1AndRC2-CBC"
        +#define NID_pbeWithSHA1AndRC2_CBC	68
        +#define OBJ_pbeWithSHA1AndRC2_CBC	OBJ_pkcs,5L,11L 
        +
        +/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now
        + * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something
        + * completely different.
        + */
        +#define LN_id_pbkdf2			"PBKDF2"
        +#define NID_id_pbkdf2			69
        +#define OBJ_id_pbkdf2			OBJ_pkcs,5L,12L 
        +
        +#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
        +#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
        +#define NID_dsaWithSHA1_2		70
        +/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
        +#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
        +
        +#define SN_netscape_cert_type		"nsCertType"
        +#define LN_netscape_cert_type		"Netscape Cert Type"
        +#define NID_netscape_cert_type		71
        +#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
        +
        +#define SN_netscape_base_url		"nsBaseUrl"
        +#define LN_netscape_base_url		"Netscape Base Url"
        +#define NID_netscape_base_url		72
        +#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
        +
        +#define SN_netscape_revocation_url	"nsRevocationUrl"
        +#define LN_netscape_revocation_url	"Netscape Revocation Url"
        +#define NID_netscape_revocation_url	73
        +#define OBJ_netscape_revocation_url	OBJ_netscape_cert_extension,3L
        +
        +#define SN_netscape_ca_revocation_url	"nsCaRevocationUrl"
        +#define LN_netscape_ca_revocation_url	"Netscape CA Revocation Url"
        +#define NID_netscape_ca_revocation_url	74
        +#define OBJ_netscape_ca_revocation_url	OBJ_netscape_cert_extension,4L
        +
        +#define SN_netscape_renewal_url		"nsRenewalUrl"
        +#define LN_netscape_renewal_url		"Netscape Renewal Url"
        +#define NID_netscape_renewal_url	75
        +#define OBJ_netscape_renewal_url	OBJ_netscape_cert_extension,7L
        +
        +#define SN_netscape_ca_policy_url	"nsCaPolicyUrl"
        +#define LN_netscape_ca_policy_url	"Netscape CA Policy Url"
        +#define NID_netscape_ca_policy_url	76
        +#define OBJ_netscape_ca_policy_url	OBJ_netscape_cert_extension,8L
        +
        +#define SN_netscape_ssl_server_name	"nsSslServerName"
        +#define LN_netscape_ssl_server_name	"Netscape SSL Server Name"
        +#define NID_netscape_ssl_server_name	77
        +#define OBJ_netscape_ssl_server_name	OBJ_netscape_cert_extension,12L
        +
        +#define SN_netscape_comment		"nsComment"
        +#define LN_netscape_comment		"Netscape Comment"
        +#define NID_netscape_comment		78
        +#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
        +
        +#define SN_netscape_cert_sequence	"nsCertSequence"
        +#define LN_netscape_cert_sequence	"Netscape Certificate Sequence"
        +#define NID_netscape_cert_sequence	79
        +#define OBJ_netscape_cert_sequence	OBJ_netscape_data_type,5L
        +
        +#define SN_desx_cbc			"DESX-CBC"
        +#define LN_desx_cbc			"desx-cbc"
        +#define NID_desx_cbc			80
        +
        +#define SN_id_ce			"id-ce"
        +#define NID_id_ce			81
        +#define OBJ_id_ce			2L,5L,29L
        +
        +#define SN_subject_key_identifier	"subjectKeyIdentifier"
        +#define LN_subject_key_identifier	"X509v3 Subject Key Identifier"
        +#define NID_subject_key_identifier	82
        +#define OBJ_subject_key_identifier	OBJ_id_ce,14L
        +
        +#define SN_key_usage			"keyUsage"
        +#define LN_key_usage			"X509v3 Key Usage"
        +#define NID_key_usage			83
        +#define OBJ_key_usage			OBJ_id_ce,15L
        +
        +#define SN_private_key_usage_period	"privateKeyUsagePeriod"
        +#define LN_private_key_usage_period	"X509v3 Private Key Usage Period"
        +#define NID_private_key_usage_period	84
        +#define OBJ_private_key_usage_period	OBJ_id_ce,16L
        +
        +#define SN_subject_alt_name		"subjectAltName"
        +#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
        +#define NID_subject_alt_name		85
        +#define OBJ_subject_alt_name		OBJ_id_ce,17L
        +
        +#define SN_issuer_alt_name		"issuerAltName"
        +#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
        +#define NID_issuer_alt_name		86
        +#define OBJ_issuer_alt_name		OBJ_id_ce,18L
        +
        +#define SN_basic_constraints		"basicConstraints"
        +#define LN_basic_constraints		"X509v3 Basic Constraints"
        +#define NID_basic_constraints		87
        +#define OBJ_basic_constraints		OBJ_id_ce,19L
        +
        +#define SN_crl_number			"crlNumber"
        +#define LN_crl_number			"X509v3 CRL Number"
        +#define NID_crl_number			88
        +#define OBJ_crl_number			OBJ_id_ce,20L
        +
        +#define SN_certificate_policies		"certificatePolicies"
        +#define LN_certificate_policies		"X509v3 Certificate Policies"
        +#define NID_certificate_policies	89
        +#define OBJ_certificate_policies	OBJ_id_ce,32L
        +
        +#define SN_authority_key_identifier	"authorityKeyIdentifier"
        +#define LN_authority_key_identifier	"X509v3 Authority Key Identifier"
        +#define NID_authority_key_identifier	90
        +#define OBJ_authority_key_identifier	OBJ_id_ce,35L
        +
        +#define SN_bf_cbc			"BF-CBC"
        +#define LN_bf_cbc			"bf-cbc"
        +#define NID_bf_cbc			91
        +#define OBJ_bf_cbc			1L,3L,6L,1L,4L,1L,3029L,1L,2L
        +
        +#define SN_bf_ecb			"BF-ECB"
        +#define LN_bf_ecb			"bf-ecb"
        +#define NID_bf_ecb			92
        +
        +#define SN_bf_cfb64			"BF-CFB"
        +#define LN_bf_cfb64			"bf-cfb"
        +#define NID_bf_cfb64			93
        +
        +#define SN_bf_ofb64			"BF-OFB"
        +#define LN_bf_ofb64			"bf-ofb"
        +#define NID_bf_ofb64			94
        +
        +#define SN_mdc2				"MDC2"
        +#define LN_mdc2				"mdc2"
        +#define NID_mdc2			95
        +#define OBJ_mdc2			2L,5L,8L,3L,101L
        +/* An alternative?			1L,3L,14L,3L,2L,19L */
        +
        +#define SN_mdc2WithRSA			"RSA-MDC2"
        +#define LN_mdc2WithRSA			"mdc2withRSA"
        +#define NID_mdc2WithRSA			96
        +#define OBJ_mdc2WithRSA			2L,5L,8L,3L,100L
        +
        +#define SN_rc4_40			"RC4-40"
        +#define LN_rc4_40			"rc4-40"
        +#define NID_rc4_40			97
        +
        +#define SN_rc2_40_cbc			"RC2-40-CBC"
        +#define LN_rc2_40_cbc			"rc2-40-cbc"
        +#define NID_rc2_40_cbc			98
        +
        +#define SN_givenName			"G"
        +#define LN_givenName			"givenName"
        +#define NID_givenName			99
        +#define OBJ_givenName			OBJ_X509,42L
        +
        +#define SN_surname			"S"
        +#define LN_surname			"surname"
        +#define NID_surname			100
        +#define OBJ_surname			OBJ_X509,4L
        +
        +#define SN_initials			"I"
        +#define LN_initials			"initials"
        +#define NID_initials			101
        +#define OBJ_initials			OBJ_X509,43L
        +
        +#define SN_uniqueIdentifier		"UID"
        +#define LN_uniqueIdentifier		"uniqueIdentifier"
        +#define NID_uniqueIdentifier		102
        +#define OBJ_uniqueIdentifier		OBJ_X509,45L
        +
        +#define SN_crl_distribution_points	"crlDistributionPoints"
        +#define LN_crl_distribution_points	"X509v3 CRL Distribution Points"
        +#define NID_crl_distribution_points	103
        +#define OBJ_crl_distribution_points	OBJ_id_ce,31L
        +
        +#define SN_md5WithRSA			"RSA-NP-MD5"
        +#define LN_md5WithRSA			"md5WithRSA"
        +#define NID_md5WithRSA			104
        +#define OBJ_md5WithRSA			OBJ_algorithm,3L
        +
        +#define SN_serialNumber			"SN"
        +#define LN_serialNumber			"serialNumber"
        +#define NID_serialNumber		105
        +#define OBJ_serialNumber		OBJ_X509,5L
        +
        +#define SN_title			"T"
        +#define LN_title			"title"
        +#define NID_title			106
        +#define OBJ_title			OBJ_X509,12L
        +
        +#define SN_description			"D"
        +#define LN_description			"description"
        +#define NID_description			107
        +#define OBJ_description			OBJ_X509,13L
        +
        +/* CAST5 is CAST-128, I'm just sticking with the documentation */
        +#define SN_cast5_cbc			"CAST5-CBC"
        +#define LN_cast5_cbc			"cast5-cbc"
        +#define NID_cast5_cbc			108
        +#define OBJ_cast5_cbc			1L,2L,840L,113533L,7L,66L,10L
        +
        +#define SN_cast5_ecb			"CAST5-ECB"
        +#define LN_cast5_ecb			"cast5-ecb"
        +#define NID_cast5_ecb			109
        +
        +#define SN_cast5_cfb64			"CAST5-CFB"
        +#define LN_cast5_cfb64			"cast5-cfb"
        +#define NID_cast5_cfb64			110
        +
        +#define SN_cast5_ofb64			"CAST5-OFB"
        +#define LN_cast5_ofb64			"cast5-ofb"
        +#define NID_cast5_ofb64			111
        +
        +#define LN_pbeWithMD5AndCast5_CBC	"pbeWithMD5AndCast5CBC"
        +#define NID_pbeWithMD5AndCast5_CBC	112
        +#define OBJ_pbeWithMD5AndCast5_CBC	1L,2L,840L,113533L,7L,66L,12L
        +
        +/* This is one sun will soon be using :-(
        + * id-dsa-with-sha1 ID  ::= {
        + *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
        + */
        +#define SN_dsaWithSHA1			"DSA-SHA1"
        +#define LN_dsaWithSHA1			"dsaWithSHA1"
        +#define NID_dsaWithSHA1			113
        +#define OBJ_dsaWithSHA1			1L,2L,840L,10040L,4L,3L
        +
        +#define NID_md5_sha1			114
        +#define SN_md5_sha1			"MD5-SHA1"
        +#define LN_md5_sha1			"md5-sha1"
        +
        +#define SN_sha1WithRSA			"RSA-SHA1-2"
        +#define LN_sha1WithRSA			"sha1WithRSA"
        +#define NID_sha1WithRSA			115
        +#define OBJ_sha1WithRSA			OBJ_algorithm,29L
        +
        +#define SN_dsa				"DSA"
        +#define LN_dsa				"dsaEncryption"
        +#define NID_dsa				116
        +#define OBJ_dsa				1L,2L,840L,10040L,4L,1L
        +
        +#define SN_ripemd160			"RIPEMD160"
        +#define LN_ripemd160			"ripemd160"
        +#define NID_ripemd160			117
        +#define OBJ_ripemd160			1L,3L,36L,3L,2L,1L
        +
        +/* The name should actually be rsaSignatureWithripemd160, but I'm going
        + * to continue using the convention I'm using with the other ciphers */
        +#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
        +#define LN_ripemd160WithRSA		"ripemd160WithRSA"
        +#define NID_ripemd160WithRSA		119
        +#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
        +
        +/* Taken from rfc2040
        + *  RC5_CBC_Parameters ::= SEQUENCE {
        + *	version           INTEGER (v1_0(16)),
        + *	rounds            INTEGER (8..127),
        + *	blockSizeInBits   INTEGER (64, 128),
        + *	iv                OCTET STRING OPTIONAL
        + *	}
        + */
        +#define SN_rc5_cbc			"RC5-CBC"
        +#define LN_rc5_cbc			"rc5-cbc"
        +#define NID_rc5_cbc			120
        +#define OBJ_rc5_cbc			OBJ_rsadsi,3L,8L
        +
        +#define SN_rc5_ecb			"RC5-ECB"
        +#define LN_rc5_ecb			"rc5-ecb"
        +#define NID_rc5_ecb			121
        +
        +#define SN_rc5_cfb64			"RC5-CFB"
        +#define LN_rc5_cfb64			"rc5-cfb"
        +#define NID_rc5_cfb64			122
        +
        +#define SN_rc5_ofb64			"RC5-OFB"
        +#define LN_rc5_ofb64			"rc5-ofb"
        +#define NID_rc5_ofb64			123
        +
        +#define SN_rle_compression		"RLE"
        +#define LN_rle_compression		"run length compression"
        +#define NID_rle_compression		124
        +#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
        +
        +#define SN_zlib_compression		"ZLIB"
        +#define LN_zlib_compression		"zlib compression"
        +#define NID_zlib_compression		125
        +#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
        +
        +#define SN_ext_key_usage		"extendedKeyUsage"
        +#define LN_ext_key_usage		"X509v3 Extended Key Usage"
        +#define NID_ext_key_usage		126
        +#define OBJ_ext_key_usage		OBJ_id_ce,37
        +
        +#define SN_id_pkix			"PKIX"
        +#define NID_id_pkix			127
        +#define OBJ_id_pkix			1L,3L,6L,1L,5L,5L,7L
        +
        +#define SN_id_kp			"id-kp"
        +#define NID_id_kp			128
        +#define OBJ_id_kp			OBJ_id_pkix,3L
        +
        +/* PKIX extended key usage OIDs */
        +
        +#define SN_server_auth			"serverAuth"
        +#define LN_server_auth			"TLS Web Server Authentication"
        +#define NID_server_auth			129
        +#define OBJ_server_auth			OBJ_id_kp,1L
        +
        +#define SN_client_auth			"clientAuth"
        +#define LN_client_auth			"TLS Web Client Authentication"
        +#define NID_client_auth			130
        +#define OBJ_client_auth			OBJ_id_kp,2L
        +
        +#define SN_code_sign			"codeSigning"
        +#define LN_code_sign			"Code Signing"
        +#define NID_code_sign			131
        +#define OBJ_code_sign			OBJ_id_kp,3L
        +
        +#define SN_email_protect		"emailProtection"
        +#define LN_email_protect		"E-mail Protection"
        +#define NID_email_protect		132
        +#define OBJ_email_protect		OBJ_id_kp,4L
        +
        +#define SN_time_stamp			"timeStamping"
        +#define LN_time_stamp			"Time Stamping"
        +#define NID_time_stamp			133
        +#define OBJ_time_stamp			OBJ_id_kp,8L
        +
        +/* Additional extended key usage OIDs: Microsoft */
        +
        +#define SN_ms_code_ind			"msCodeInd"
        +#define LN_ms_code_ind			"Microsoft Individual Code Signing"
        +#define NID_ms_code_ind			134
        +#define OBJ_ms_code_ind			1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
        +
        +#define SN_ms_code_com			"msCodeCom"
        +#define LN_ms_code_com			"Microsoft Commercial Code Signing"
        +#define NID_ms_code_com			135
        +#define OBJ_ms_code_com			1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
        +
        +#define SN_ms_ctl_sign			"msCTLSign"
        +#define LN_ms_ctl_sign			"Microsoft Trust List Signing"
        +#define NID_ms_ctl_sign			136
        +#define OBJ_ms_ctl_sign			1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
        +
        +#define SN_ms_sgc			"msSGC"
        +#define LN_ms_sgc			"Microsoft Server Gated Crypto"
        +#define NID_ms_sgc			137
        +#define OBJ_ms_sgc			1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
        +
        +#define SN_ms_efs			"msEFS"
        +#define LN_ms_efs			"Microsoft Encrypted File System"
        +#define NID_ms_efs			138
        +#define OBJ_ms_efs			1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
        +
        +/* Additional usage: Netscape */
        +
        +#define SN_ns_sgc			"nsSGC"
        +#define LN_ns_sgc			"Netscape Server Gated Crypto"
        +#define NID_ns_sgc			139
        +#define OBJ_ns_sgc			OBJ_netscape,4L,1L
        +
        +#define SN_delta_crl			"deltaCRL"
        +#define LN_delta_crl			"X509v3 Delta CRL Indicator"
        +#define NID_delta_crl			140
        +#define OBJ_delta_crl			OBJ_id_ce,27L
        +
        +#define SN_crl_reason			"CRLReason"
        +#define LN_crl_reason			"CRL Reason Code"
        +#define NID_crl_reason			141
        +#define OBJ_crl_reason			OBJ_id_ce,21L
        +
        +#define SN_invalidity_date		"invalidityDate"
        +#define LN_invalidity_date		"Invalidity Date"
        +#define NID_invalidity_date		142
        +#define OBJ_invalidity_date		OBJ_id_ce,24L
        +
        +#define SN_sxnet			"SXNetID"
        +#define LN_sxnet			"Strong Extranet ID"
        +#define NID_sxnet			143
        +#define OBJ_sxnet			1L,3L,101L,1L,4L,1L
        +
        +/* PKCS12 and related OBJECT IDENTIFIERS */
        +
        +#define OBJ_pkcs12			OBJ_pkcs,12L
        +#define OBJ_pkcs12_pbeids		OBJ_pkcs12, 1
        +
        +#define SN_pbe_WithSHA1And128BitRC4	"PBE-SHA1-RC4-128"
        +#define LN_pbe_WithSHA1And128BitRC4	"pbeWithSHA1And128BitRC4"
        +#define NID_pbe_WithSHA1And128BitRC4	144
        +#define OBJ_pbe_WithSHA1And128BitRC4	OBJ_pkcs12_pbeids, 1L
        +
        +#define SN_pbe_WithSHA1And40BitRC4	"PBE-SHA1-RC4-40"
        +#define LN_pbe_WithSHA1And40BitRC4	"pbeWithSHA1And40BitRC4"
        +#define NID_pbe_WithSHA1And40BitRC4	145
        +#define OBJ_pbe_WithSHA1And40BitRC4	OBJ_pkcs12_pbeids, 2L
        +
        +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC	"PBE-SHA1-3DES"
        +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC	"pbeWithSHA1And3-KeyTripleDES-CBC"
        +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC	146
        +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 3L
        +
        +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC	"PBE-SHA1-2DES"
        +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC	"pbeWithSHA1And2-KeyTripleDES-CBC"
        +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC	147
        +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 4L
        +
        +#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
        +#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
        +#define NID_pbe_WithSHA1And128BitRC2_CBC	148
        +#define OBJ_pbe_WithSHA1And128BitRC2_CBC	OBJ_pkcs12_pbeids, 5L
        +
        +#define SN_pbe_WithSHA1And40BitRC2_CBC	"PBE-SHA1-RC2-40"
        +#define LN_pbe_WithSHA1And40BitRC2_CBC	"pbeWithSHA1And40BitRC2-CBC"
        +#define NID_pbe_WithSHA1And40BitRC2_CBC	149
        +#define OBJ_pbe_WithSHA1And40BitRC2_CBC	OBJ_pkcs12_pbeids, 6L
        +
        +#define OBJ_pkcs12_Version1	OBJ_pkcs12, 10L
        +
        +#define OBJ_pkcs12_BagIds	OBJ_pkcs12_Version1, 1L
        +
        +#define LN_keyBag		"keyBag"
        +#define NID_keyBag		150
        +#define OBJ_keyBag		OBJ_pkcs12_BagIds, 1L
        +
        +#define LN_pkcs8ShroudedKeyBag	"pkcs8ShroudedKeyBag"
        +#define NID_pkcs8ShroudedKeyBag	151
        +#define OBJ_pkcs8ShroudedKeyBag	OBJ_pkcs12_BagIds, 2L
        +
        +#define LN_certBag		"certBag"
        +#define NID_certBag		152
        +#define OBJ_certBag		OBJ_pkcs12_BagIds, 3L
        +
        +#define LN_crlBag		"crlBag"
        +#define NID_crlBag		153
        +#define OBJ_crlBag		OBJ_pkcs12_BagIds, 4L
        +
        +#define LN_secretBag		"secretBag"
        +#define NID_secretBag		154
        +#define OBJ_secretBag		OBJ_pkcs12_BagIds, 5L
        +
        +#define LN_safeContentsBag	"safeContentsBag"
        +#define NID_safeContentsBag	155
        +#define OBJ_safeContentsBag	OBJ_pkcs12_BagIds, 6L
        +
        +#define LN_friendlyName		"friendlyName"
        +#define	NID_friendlyName	156
        +#define OBJ_friendlyName	OBJ_pkcs9, 20L
        +
        +#define LN_localKeyID		"localKeyID"
        +#define	NID_localKeyID		157
        +#define OBJ_localKeyID		OBJ_pkcs9, 21L
        +
        +#define OBJ_certTypes		OBJ_pkcs9, 22L
        +
        +#define LN_x509Certificate	"x509Certificate"
        +#define	NID_x509Certificate	158
        +#define OBJ_x509Certificate	OBJ_certTypes, 1L
        +
        +#define LN_sdsiCertificate	"sdsiCertificate"
        +#define	NID_sdsiCertificate	159
        +#define OBJ_sdsiCertificate	OBJ_certTypes, 2L
        +
        +#define OBJ_crlTypes		OBJ_pkcs9, 23L
        +
        +#define LN_x509Crl		"x509Crl"
        +#define	NID_x509Crl		160
        +#define OBJ_x509Crl		OBJ_crlTypes, 1L
        +
        +/* PKCS#5 v2 OIDs */
        +
        +#define LN_pbes2		"PBES2"
        +#define NID_pbes2		161
        +#define OBJ_pbes2		OBJ_pkcs,5L,13L
        +
        +#define LN_pbmac1		"PBMAC1"
        +#define NID_pbmac1		162
        +#define OBJ_pbmac1		OBJ_pkcs,5L,14L
        +
        +#define LN_hmacWithSHA1		"hmacWithSHA1"
        +#define NID_hmacWithSHA1	163
        +#define OBJ_hmacWithSHA1	OBJ_rsadsi,2L,7L
        +
        +/* Policy Qualifier Ids */
        +
        +#define LN_id_qt_cps		"Policy Qualifier CPS"
        +#define SN_id_qt_cps		"id-qt-cps"
        +#define NID_id_qt_cps		164
        +#define OBJ_id_qt_cps		OBJ_id_pkix,2L,1L
        +
        +#define LN_id_qt_unotice	"Policy Qualifier User Notice"
        +#define SN_id_qt_unotice	"id-qt-unotice"
        +#define NID_id_qt_unotice	165
        +#define OBJ_id_qt_unotice	OBJ_id_pkix,2L,2L
        +
        +#define SN_rc2_64_cbc			"RC2-64-CBC"
        +#define LN_rc2_64_cbc			"rc2-64-cbc"
        +#define NID_rc2_64_cbc			166
        +
        +#define SN_SMIMECapabilities		"SMIME-CAPS"
        +#define LN_SMIMECapabilities		"S/MIME Capabilities"
        +#define NID_SMIMECapabilities		167
        +#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
        +
        +#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
        +#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
        +#define NID_pbeWithMD2AndRC2_CBC	168
        +#define OBJ_pbeWithMD2AndRC2_CBC	OBJ_pkcs,5L,4L
        +
        +#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
        +#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
        +#define NID_pbeWithMD5AndRC2_CBC	169
        +#define OBJ_pbeWithMD5AndRC2_CBC	OBJ_pkcs,5L,6L
        +
        +#define SN_pbeWithSHA1AndDES_CBC	"PBE-SHA1-DES"
        +#define LN_pbeWithSHA1AndDES_CBC	"pbeWithSHA1AndDES-CBC"
        +#define NID_pbeWithSHA1AndDES_CBC	170
        +#define OBJ_pbeWithSHA1AndDES_CBC	OBJ_pkcs,5L,10L
        +
        +/* Extension request OIDs */
        +
        +#define LN_ms_ext_req			"Microsoft Extension Request"
        +#define SN_ms_ext_req			"msExtReq"
        +#define NID_ms_ext_req			171
        +#define OBJ_ms_ext_req			1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
        +
        +#define LN_ext_req			"Extension Request"
        +#define SN_ext_req			"extReq"
        +#define NID_ext_req			172
        +#define OBJ_ext_req			OBJ_pkcs9,14L
        +
        +#define SN_name				"name"
        +#define LN_name				"name"
        +#define NID_name			173
        +#define OBJ_name			OBJ_X509,41L
        +
        +#define SN_dnQualifier			"dnQualifier"
        +#define LN_dnQualifier			"dnQualifier"
        +#define NID_dnQualifier			174
        +#define OBJ_dnQualifier			OBJ_X509,46L
        +
        +#define SN_id_pe			"id-pe"
        +#define NID_id_pe			175
        +#define OBJ_id_pe			OBJ_id_pkix,1L
        +
        +#define SN_id_ad			"id-ad"
        +#define NID_id_ad			176
        +#define OBJ_id_ad			OBJ_id_pkix,48L
        +
        +#define SN_info_access			"authorityInfoAccess"
        +#define LN_info_access			"Authority Information Access"
        +#define NID_info_access			177
        +#define OBJ_info_access			OBJ_id_pe,1L
        +
        +#define SN_ad_OCSP			"OCSP"
        +#define LN_ad_OCSP			"OCSP"
        +#define NID_ad_OCSP			178
        +#define OBJ_ad_OCSP			OBJ_id_ad,1L
        +
        +#define SN_ad_ca_issuers		"caIssuers"
        +#define LN_ad_ca_issuers		"CA Issuers"
        +#define NID_ad_ca_issuers		179
        +#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
        +
        +#define SN_OCSP_sign			"OCSPSigning"
        +#define LN_OCSP_sign			"OCSP Signing"
        +#define NID_OCSP_sign			180
        +#define OBJ_OCSP_sign			OBJ_id_kp,9L
        +#endif /* USE_OBJ_MAC */
        +
        +#include <openssl/bio.h>
        +#include <openssl/asn1.h>
        +
        +#define	OBJ_NAME_TYPE_UNDEF		0x00
        +#define	OBJ_NAME_TYPE_MD_METH		0x01
        +#define	OBJ_NAME_TYPE_CIPHER_METH	0x02
        +#define	OBJ_NAME_TYPE_PKEY_METH		0x03
        +#define	OBJ_NAME_TYPE_COMP_METH		0x04
        +#define	OBJ_NAME_TYPE_NUM		0x05
        +
        +#define	OBJ_NAME_ALIAS			0x8000
        +
        +#define OBJ_BSEARCH_VALUE_ON_NOMATCH		0x01
        +#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH	0x02
        +
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct obj_name_st
        +	{
        +	int type;
        +	int alias;
        +	const char *name;
        +	const char *data;
        +	} OBJ_NAME;
        +
        +#define		OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
        +
        +
        +int OBJ_NAME_init(void);
        +int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
        +		       int (*cmp_func)(const char *, const char *),
        +		       void (*free_func)(const char *, int, const char *));
        +const char *OBJ_NAME_get(const char *name,int type);
        +int OBJ_NAME_add(const char *name,int type,const char *data);
        +int OBJ_NAME_remove(const char *name,int type);
        +void OBJ_NAME_cleanup(int type); /* -1 for everything */
        +void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),
        +		     void *arg);
        +void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
        +			    void *arg);
        +
        +ASN1_OBJECT *	OBJ_dup(const ASN1_OBJECT *o);
        +ASN1_OBJECT *	OBJ_nid2obj(int n);
        +const char *	OBJ_nid2ln(int n);
        +const char *	OBJ_nid2sn(int n);
        +int		OBJ_obj2nid(const ASN1_OBJECT *o);
        +ASN1_OBJECT *	OBJ_txt2obj(const char *s, int no_name);
        +int	OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
        +int		OBJ_txt2nid(const char *s);
        +int		OBJ_ln2nid(const char *s);
        +int		OBJ_sn2nid(const char *s);
        +int		OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
        +const void *	OBJ_bsearch_(const void *key,const void *base,int num,int size,
        +			     int (*cmp)(const void *, const void *));
        +const void *	OBJ_bsearch_ex_(const void *key,const void *base,int num,
        +				int size,
        +				int (*cmp)(const void *, const void *),
        +				int flags);
        +
        +#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)	\
        +  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
        +  static int nm##_cmp(type1 const *, type2 const *); \
        +  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
        +
        +#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)	\
        +  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
        +#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
        +  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
        +
        +/*
        + * Unsolved problem: if a type is actually a pointer type, like
        + * nid_triple is, then its impossible to get a const where you need
        + * it. Consider:
        + *
        + * typedef int nid_triple[3];
        + * const void *a_;
        + * const nid_triple const *a = a_;
        + *
        + * The assignement discards a const because what you really want is:
        + *
        + * const int const * const *a = a_;
        + *
        + * But if you do that, you lose the fact that a is an array of 3 ints,
        + * which breaks comparison functions.
        + *
        + * Thus we end up having to cast, sadly, or unpack the
        + * declarations. Or, as I finally did in this case, delcare nid_triple
        + * to be a struct, which it should have been in the first place.
        + *
        + * Ben, August 2008.
        + *
        + * Also, strictly speaking not all types need be const, but handling
        + * the non-constness means a lot of complication, and in practice
        + * comparison routines do always not touch their arguments.
        + */
        +
        +#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)	\
        +  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
        +      { \
        +      type1 const *a = a_; \
        +      type2 const *b = b_; \
        +      return nm##_cmp(a,b); \
        +      } \
        +  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
        +      { \
        +      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
        +					nm##_cmp_BSEARCH_CMP_FN); \
        +      } \
        +      extern void dummy_prototype(void)
        +
        +#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
        +  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
        +      { \
        +      type1 const *a = a_; \
        +      type2 const *b = b_; \
        +      return nm##_cmp(a,b); \
        +      } \
        +  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
        +      { \
        +      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
        +					nm##_cmp_BSEARCH_CMP_FN); \
        +      } \
        +      extern void dummy_prototype(void)
        +
        +#define OBJ_bsearch(type1,key,type2,base,num,cmp)			       \
        +  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
        +			 num,sizeof(type2),				\
        +			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
        +			  (void)CHECKED_PTR_OF(type2,cmp##_type_2),	\
        +			  cmp##_BSEARCH_CMP_FN)))
        +
        +#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)			\
        +  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
        +			 num,sizeof(type2),				\
        +			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
        +			  (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
        +			  cmp##_BSEARCH_CMP_FN)),flags)
        +
        +int		OBJ_new_nid(int num);
        +int		OBJ_add_object(const ASN1_OBJECT *obj);
        +int		OBJ_create(const char *oid,const char *sn,const char *ln);
        +void		OBJ_cleanup(void );
        +int		OBJ_create_objects(BIO *in);
        +
        +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
        +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
        +int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
        +void OBJ_sigid_free(void);
        +
        +extern int obj_cleanup_defer;
        +void check_defer(int nid);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_OBJ_strings(void);
        +
        +/* Error codes for the OBJ functions. */
        +
        +/* Function codes. */
        +#define OBJ_F_OBJ_ADD_OBJECT				 105
        +#define OBJ_F_OBJ_CREATE				 100
        +#define OBJ_F_OBJ_DUP					 101
        +#define OBJ_F_OBJ_NAME_NEW_INDEX			 106
        +#define OBJ_F_OBJ_NID2LN				 102
        +#define OBJ_F_OBJ_NID2OBJ				 103
        +#define OBJ_F_OBJ_NID2SN				 104
        +
        +/* Reason codes. */
        +#define OBJ_R_MALLOC_FAILURE				 100
        +#define OBJ_R_UNKNOWN_NID				 101
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/objects/objects.pl b/vendor/openssl/openssl/crypto/objects/objects.pl
        new file mode 100644
        index 000000000..15c00bbd5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/objects.pl
        @@ -0,0 +1,232 @@
        +#!/usr/local/bin/perl
        +
        +open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]";
        +$max_nid=0;
        +$o=0;
        +while(<NUMIN>)
        +	{
        +	chop;
        +	$o++;
        +	s/#.*$//;
        +	next if /^\s*$/;
        +	$_ = 'X'.$_;
        +	($Cname,$mynum) = split;
        +	$Cname =~ s/^X//;
        +	if (defined($nidn{$mynum}))
        +		{ die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; }
        +	if (defined($nid{$Cname}))
        +		{ die "$ARGV[1]:$o:There's already an object with name ",$Cname," on line ",$order{$nid{$Cname}},"\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 (<IN>)
        +	{
        +	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;
        +print STDERR "Added OID $Cname\n";
        +		}
        +	$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';
        +/* crypto/objects/obj_mac.h */
        +
        +/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
        + * following command:
        + * perl objects.pl objects.txt obj_mac.num obj_mac.h
        + */
        +
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#define SN_undef			"UNDEF"
        +#define LN_undef			"undefined"
        +#define NID_undef			0
        +#define OBJ_undef			0L
        +
        +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;
        +		if (!defined($obj{$a[0]}))
        +			{ die "$ARGV[0]:$o:Undefined identifier ",$a[0],"\n"; }
        +		$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/vendor/openssl/openssl/crypto/objects/objects.txt b/vendor/openssl/openssl/crypto/objects/objects.txt
        new file mode 100644
        index 000000000..d3bfad72a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/objects.txt
        @@ -0,0 +1,1292 @@
        +# CCITT was renamed to ITU-T quite some time ago
        +0			: ITU-T			: itu-t
        +!Alias ccitt itu-t
        +
        +1			: ISO			: iso
        +
        +2			: JOINT-ISO-ITU-T	: joint-iso-itu-t
        +!Alias joint-iso-ccitt joint-iso-itu-t
        +
        +iso 2			: member-body		: ISO Member Body
        +
        +iso 3			: identified-organization
        +
        +# HMAC OIDs
        +identified-organization 6 1 5 5 8 1 1	: HMAC-MD5	: hmac-md5
        +identified-organization 6 1 5 5 8 1 2	: HMAC-SHA1	: hmac-sha1
        +
        +identified-organization 132	: certicom-arc
        +
        +joint-iso-itu-t 23	: international-organizations	: International Organizations
        +
        +international-organizations 43	: wap
        +wap 1			: wap-wsg
        +
        +joint-iso-itu-t 5 1 5	: selected-attribute-types	: Selected Attribute Types
        +
        +selected-attribute-types 55	: clearance
        +
        +member-body 840		: ISO-US		: ISO US Member Body
        +ISO-US 10040		: X9-57			: X9.57
        +X9-57 4			: X9cm			: X9.57 CM ?
        +
        +!Cname dsa
        +X9cm 1			: DSA			: dsaEncryption
        +X9cm 3			: DSA-SHA1		: dsaWithSHA1
        +
        +
        +ISO-US 10045		: ansi-X9-62		: ANSI X9.62
        +!module X9-62
        +!Alias id-fieldType ansi-X9-62 1
        +X9-62_id-fieldType 1		: prime-field
        +X9-62_id-fieldType 2		: characteristic-two-field
        +X9-62_characteristic-two-field 3 : id-characteristic-two-basis
        +X9-62_id-characteristic-two-basis 1 : onBasis
        +X9-62_id-characteristic-two-basis 2 : tpBasis
        +X9-62_id-characteristic-two-basis 3 : ppBasis
        +!Alias id-publicKeyType ansi-X9-62 2
        +X9-62_id-publicKeyType 1	: id-ecPublicKey
        +!Alias ellipticCurve ansi-X9-62 3
        +!Alias c-TwoCurve X9-62_ellipticCurve 0
        +X9-62_c-TwoCurve 1		: c2pnb163v1
        +X9-62_c-TwoCurve 2		: c2pnb163v2
        +X9-62_c-TwoCurve 3		: c2pnb163v3
        +X9-62_c-TwoCurve 4		: c2pnb176v1
        +X9-62_c-TwoCurve 5		: c2tnb191v1
        +X9-62_c-TwoCurve 6		: c2tnb191v2
        +X9-62_c-TwoCurve 7		: c2tnb191v3
        +X9-62_c-TwoCurve 8		: c2onb191v4
        +X9-62_c-TwoCurve 9		: c2onb191v5
        +X9-62_c-TwoCurve 10		: c2pnb208w1
        +X9-62_c-TwoCurve 11		: c2tnb239v1
        +X9-62_c-TwoCurve 12		: c2tnb239v2
        +X9-62_c-TwoCurve 13		: c2tnb239v3
        +X9-62_c-TwoCurve 14		: c2onb239v4
        +X9-62_c-TwoCurve 15		: c2onb239v5
        +X9-62_c-TwoCurve 16		: c2pnb272w1
        +X9-62_c-TwoCurve 17		: c2pnb304w1
        +X9-62_c-TwoCurve 18		: c2tnb359v1
        +X9-62_c-TwoCurve 19		: c2pnb368w1
        +X9-62_c-TwoCurve 20		: c2tnb431r1
        +!Alias primeCurve X9-62_ellipticCurve 1
        +X9-62_primeCurve 1	 	: prime192v1
        +X9-62_primeCurve 2	 	: prime192v2
        +X9-62_primeCurve 3	 	: prime192v3
        +X9-62_primeCurve 4	 	: prime239v1
        +X9-62_primeCurve 5	 	: prime239v2
        +X9-62_primeCurve 6	 	: prime239v3
        +X9-62_primeCurve 7	 	: prime256v1
        +!Alias id-ecSigType ansi-X9-62 4
        +!global
        +X9-62_id-ecSigType 1		: ecdsa-with-SHA1
        +X9-62_id-ecSigType 2		: ecdsa-with-Recommended
        +X9-62_id-ecSigType 3		: ecdsa-with-Specified
        +ecdsa-with-Specified 1		: ecdsa-with-SHA224
        +ecdsa-with-Specified 2		: ecdsa-with-SHA256
        +ecdsa-with-Specified 3		: ecdsa-with-SHA384
        +ecdsa-with-Specified 4		: ecdsa-with-SHA512
        +
        +# SECG curve OIDs from "SEC 2: Recommended Elliptic Curve Domain Parameters"
        +# (http://www.secg.org/)
        +!Alias secg_ellipticCurve certicom-arc 0
        +# SECG prime curves OIDs
        +secg-ellipticCurve 6		: secp112r1
        +secg-ellipticCurve 7		: secp112r2
        +secg-ellipticCurve 28		: secp128r1
        +secg-ellipticCurve 29		: secp128r2
        +secg-ellipticCurve 9		: secp160k1
        +secg-ellipticCurve 8		: secp160r1
        +secg-ellipticCurve 30		: secp160r2
        +secg-ellipticCurve 31		: secp192k1
        +# NOTE: the curve secp192r1 is the same as prime192v1 defined above
        +#       and is therefore omitted
        +secg-ellipticCurve 32		: secp224k1
        +secg-ellipticCurve 33		: secp224r1
        +secg-ellipticCurve 10		: secp256k1
        +# NOTE: the curve secp256r1 is the same as prime256v1 defined above
        +#       and is therefore omitted
        +secg-ellipticCurve 34		: secp384r1
        +secg-ellipticCurve 35		: secp521r1
        +# SECG characteristic two curves OIDs
        +secg-ellipticCurve 4		: sect113r1
        +secg-ellipticCurve 5		: sect113r2
        +secg-ellipticCurve 22		: sect131r1
        +secg-ellipticCurve 23		: sect131r2
        +secg-ellipticCurve 1		: sect163k1
        +secg-ellipticCurve 2		: sect163r1
        +secg-ellipticCurve 15		: sect163r2
        +secg-ellipticCurve 24		: sect193r1
        +secg-ellipticCurve 25		: sect193r2
        +secg-ellipticCurve 26		: sect233k1
        +secg-ellipticCurve 27		: sect233r1
        +secg-ellipticCurve 3		: sect239k1
        +secg-ellipticCurve 16		: sect283k1
        +secg-ellipticCurve 17		: sect283r1
        +secg-ellipticCurve 36		: sect409k1
        +secg-ellipticCurve 37		: sect409r1
        +secg-ellipticCurve 38		: sect571k1
        +secg-ellipticCurve 39		: sect571r1
        +
        +# WAP/TLS curve OIDs (http://www.wapforum.org/)
        +!Alias wap-wsg-idm-ecid wap-wsg 4
        +wap-wsg-idm-ecid 1	: wap-wsg-idm-ecid-wtls1
        +wap-wsg-idm-ecid 3	: wap-wsg-idm-ecid-wtls3
        +wap-wsg-idm-ecid 4	: wap-wsg-idm-ecid-wtls4
        +wap-wsg-idm-ecid 5	: wap-wsg-idm-ecid-wtls5
        +wap-wsg-idm-ecid 6	: wap-wsg-idm-ecid-wtls6
        +wap-wsg-idm-ecid 7	: wap-wsg-idm-ecid-wtls7
        +wap-wsg-idm-ecid 8	: wap-wsg-idm-ecid-wtls8
        +wap-wsg-idm-ecid 9	: wap-wsg-idm-ecid-wtls9
        +wap-wsg-idm-ecid 10	: wap-wsg-idm-ecid-wtls10
        +wap-wsg-idm-ecid 11	: wap-wsg-idm-ecid-wtls11
        +wap-wsg-idm-ecid 12	: wap-wsg-idm-ecid-wtls12
        +
        +
        +ISO-US 113533 7 66 10	: CAST5-CBC		: cast5-cbc
        +			: CAST5-ECB		: cast5-ecb
        +!Cname cast5-cfb64
        +			: CAST5-CFB		: cast5-cfb
        +!Cname cast5-ofb64
        +			: CAST5-OFB		: cast5-ofb
        +!Cname pbeWithMD5AndCast5-CBC
        +ISO-US 113533 7 66 12	:			: pbeWithMD5AndCast5CBC
        +
        +# Macs for CMP and CRMF
        +ISO-US 113533 7 66 13	: id-PasswordBasedMAC	: password based MAC
        +ISO-US 113533 7 66 30	: id-DHBasedMac		: Diffie-Hellman based MAC
        +
        +ISO-US 113549		: rsadsi		: RSA Data Security, Inc.
        +
        +rsadsi 1		: pkcs			: RSA Data Security, Inc. PKCS
        +
        +pkcs 1			: pkcs1
        +pkcs1 1			:			: rsaEncryption
        +pkcs1 2			: RSA-MD2		: md2WithRSAEncryption
        +pkcs1 3			: RSA-MD4		: md4WithRSAEncryption
        +pkcs1 4			: RSA-MD5		: md5WithRSAEncryption
        +pkcs1 5			: RSA-SHA1		: sha1WithRSAEncryption
        +# According to PKCS #1 version 2.1
        +pkcs1 7			: RSAES-OAEP		: rsaesOaep
        +pkcs1 8			: MGF1			: mgf1
        +pkcs1 10		: RSASSA-PSS		: rsassaPss
        +
        +pkcs1 11		: RSA-SHA256		: sha256WithRSAEncryption
        +pkcs1 12		: RSA-SHA384		: sha384WithRSAEncryption
        +pkcs1 13		: RSA-SHA512		: sha512WithRSAEncryption
        +pkcs1 14		: RSA-SHA224		: sha224WithRSAEncryption
        +
        +pkcs 3			: pkcs3
        +pkcs3 1			:			: dhKeyAgreement
        +
        +pkcs 5			: pkcs5
        +pkcs5 1			: PBE-MD2-DES		: pbeWithMD2AndDES-CBC
        +pkcs5 3			: PBE-MD5-DES		: pbeWithMD5AndDES-CBC
        +pkcs5 4			: PBE-MD2-RC2-64	: pbeWithMD2AndRC2-CBC
        +pkcs5 6			: PBE-MD5-RC2-64	: pbeWithMD5AndRC2-CBC
        +pkcs5 10		: PBE-SHA1-DES		: pbeWithSHA1AndDES-CBC
        +pkcs5 11		: PBE-SHA1-RC2-64	: pbeWithSHA1AndRC2-CBC
        +!Cname id_pbkdf2
        +pkcs5 12		:			: PBKDF2
        +!Cname pbes2
        +pkcs5 13		:			: PBES2
        +!Cname pbmac1
        +pkcs5 14		:			: PBMAC1
        +
        +pkcs 7			: pkcs7
        +pkcs7 1			:			: pkcs7-data
        +!Cname pkcs7-signed
        +pkcs7 2			:			: pkcs7-signedData
        +!Cname pkcs7-enveloped
        +pkcs7 3			:			: pkcs7-envelopedData
        +!Cname pkcs7-signedAndEnveloped
        +pkcs7 4			:			: pkcs7-signedAndEnvelopedData
        +!Cname pkcs7-digest
        +pkcs7 5			:			: pkcs7-digestData
        +!Cname pkcs7-encrypted
        +pkcs7 6			:			: pkcs7-encryptedData
        +
        +pkcs 9			: pkcs9
        +!module pkcs9
        +pkcs9 1			: 			: emailAddress
        +pkcs9 2			:			: unstructuredName
        +pkcs9 3			:			: contentType
        +pkcs9 4			:			: messageDigest
        +pkcs9 5			:			: signingTime
        +pkcs9 6			:			: countersignature
        +pkcs9 7			:			: challengePassword
        +pkcs9 8			:			: unstructuredAddress
        +!Cname extCertAttributes
        +pkcs9 9			:			: extendedCertificateAttributes
        +!global
        +
        +!Cname ext-req
        +pkcs9 14		: extReq		: Extension Request
        +
        +!Cname SMIMECapabilities
        +pkcs9 15		: SMIME-CAPS		: S/MIME Capabilities
        +
        +# S/MIME
        +!Cname SMIME
        +pkcs9 16		: SMIME			: S/MIME
        +SMIME 0			: id-smime-mod
        +SMIME 1			: id-smime-ct
        +SMIME 2			: id-smime-aa
        +SMIME 3			: id-smime-alg
        +SMIME 4			: id-smime-cd
        +SMIME 5			: id-smime-spq
        +SMIME 6			: id-smime-cti
        +
        +# S/MIME Modules
        +id-smime-mod 1		: id-smime-mod-cms
        +id-smime-mod 2		: id-smime-mod-ess
        +id-smime-mod 3		: id-smime-mod-oid
        +id-smime-mod 4		: id-smime-mod-msg-v3
        +id-smime-mod 5		: id-smime-mod-ets-eSignature-88
        +id-smime-mod 6		: id-smime-mod-ets-eSignature-97
        +id-smime-mod 7		: id-smime-mod-ets-eSigPolicy-88
        +id-smime-mod 8		: id-smime-mod-ets-eSigPolicy-97
        +
        +# S/MIME Content Types
        +id-smime-ct 1		: id-smime-ct-receipt
        +id-smime-ct 2		: id-smime-ct-authData
        +id-smime-ct 3		: id-smime-ct-publishCert
        +id-smime-ct 4		: id-smime-ct-TSTInfo
        +id-smime-ct 5		: id-smime-ct-TDTInfo
        +id-smime-ct 6		: id-smime-ct-contentInfo
        +id-smime-ct 7		: id-smime-ct-DVCSRequestData
        +id-smime-ct 8		: id-smime-ct-DVCSResponseData
        +id-smime-ct 9		: id-smime-ct-compressedData
        +id-smime-ct 27		: id-ct-asciiTextWithCRLF
        +
        +# S/MIME Attributes
        +id-smime-aa 1		: id-smime-aa-receiptRequest
        +id-smime-aa 2		: id-smime-aa-securityLabel
        +id-smime-aa 3		: id-smime-aa-mlExpandHistory
        +id-smime-aa 4		: id-smime-aa-contentHint
        +id-smime-aa 5		: id-smime-aa-msgSigDigest
        +# obsolete
        +id-smime-aa 6		: id-smime-aa-encapContentType
        +id-smime-aa 7		: id-smime-aa-contentIdentifier
        +# obsolete
        +id-smime-aa 8		: id-smime-aa-macValue
        +id-smime-aa 9		: id-smime-aa-equivalentLabels
        +id-smime-aa 10		: id-smime-aa-contentReference
        +id-smime-aa 11		: id-smime-aa-encrypKeyPref
        +id-smime-aa 12		: id-smime-aa-signingCertificate
        +id-smime-aa 13		: id-smime-aa-smimeEncryptCerts
        +id-smime-aa 14		: id-smime-aa-timeStampToken
        +id-smime-aa 15		: id-smime-aa-ets-sigPolicyId
        +id-smime-aa 16		: id-smime-aa-ets-commitmentType
        +id-smime-aa 17		: id-smime-aa-ets-signerLocation
        +id-smime-aa 18		: id-smime-aa-ets-signerAttr
        +id-smime-aa 19		: id-smime-aa-ets-otherSigCert
        +id-smime-aa 20		: id-smime-aa-ets-contentTimestamp
        +id-smime-aa 21		: id-smime-aa-ets-CertificateRefs
        +id-smime-aa 22		: id-smime-aa-ets-RevocationRefs
        +id-smime-aa 23		: id-smime-aa-ets-certValues
        +id-smime-aa 24		: id-smime-aa-ets-revocationValues
        +id-smime-aa 25		: id-smime-aa-ets-escTimeStamp
        +id-smime-aa 26		: id-smime-aa-ets-certCRLTimestamp
        +id-smime-aa 27		: id-smime-aa-ets-archiveTimeStamp
        +id-smime-aa 28		: id-smime-aa-signatureType
        +id-smime-aa 29		: id-smime-aa-dvcs-dvc
        +
        +# S/MIME Algorithm Identifiers
        +# obsolete
        +id-smime-alg 1		: id-smime-alg-ESDHwith3DES
        +# obsolete
        +id-smime-alg 2		: id-smime-alg-ESDHwithRC2
        +# obsolete
        +id-smime-alg 3		: id-smime-alg-3DESwrap
        +# obsolete
        +id-smime-alg 4		: id-smime-alg-RC2wrap
        +id-smime-alg 5		: id-smime-alg-ESDH
        +id-smime-alg 6		: id-smime-alg-CMS3DESwrap
        +id-smime-alg 7		: id-smime-alg-CMSRC2wrap
        +id-smime-alg 9		: id-alg-PWRI-KEK
        +
        +# S/MIME Certificate Distribution
        +id-smime-cd 1		: id-smime-cd-ldap
        +
        +# S/MIME Signature Policy Qualifier
        +id-smime-spq 1		: id-smime-spq-ets-sqt-uri
        +id-smime-spq 2		: id-smime-spq-ets-sqt-unotice
        +
        +# S/MIME Commitment Type Identifier
        +id-smime-cti 1		: id-smime-cti-ets-proofOfOrigin
        +id-smime-cti 2		: id-smime-cti-ets-proofOfReceipt
        +id-smime-cti 3		: id-smime-cti-ets-proofOfDelivery
        +id-smime-cti 4		: id-smime-cti-ets-proofOfSender
        +id-smime-cti 5		: id-smime-cti-ets-proofOfApproval
        +id-smime-cti 6		: id-smime-cti-ets-proofOfCreation
        +
        +pkcs9 20		:			: friendlyName
        +pkcs9 21		:			: localKeyID
        +!Cname ms-csp-name
        +1 3 6 1 4 1 311 17 1	: CSPName		: Microsoft CSP Name
        +1 3 6 1 4 1 311 17 2	: LocalKeySet		: Microsoft Local Key set
        +!Alias certTypes pkcs9 22
        +certTypes 1		:			: x509Certificate
        +certTypes 2		:			: sdsiCertificate
        +!Alias crlTypes pkcs9 23
        +crlTypes 1		:			: x509Crl
        +
        +!Alias pkcs12 pkcs 12
        +!Alias pkcs12-pbeids pkcs12 1
        +
        +!Cname pbe-WithSHA1And128BitRC4
        +pkcs12-pbeids 1		: PBE-SHA1-RC4-128	: pbeWithSHA1And128BitRC4
        +!Cname pbe-WithSHA1And40BitRC4
        +pkcs12-pbeids 2		: PBE-SHA1-RC4-40	: pbeWithSHA1And40BitRC4
        +!Cname pbe-WithSHA1And3_Key_TripleDES-CBC
        +pkcs12-pbeids 3		: PBE-SHA1-3DES		: pbeWithSHA1And3-KeyTripleDES-CBC
        +!Cname pbe-WithSHA1And2_Key_TripleDES-CBC
        +pkcs12-pbeids 4		: PBE-SHA1-2DES		: pbeWithSHA1And2-KeyTripleDES-CBC
        +!Cname pbe-WithSHA1And128BitRC2-CBC
        +pkcs12-pbeids 5		: PBE-SHA1-RC2-128	: pbeWithSHA1And128BitRC2-CBC
        +!Cname pbe-WithSHA1And40BitRC2-CBC
        +pkcs12-pbeids 6		: PBE-SHA1-RC2-40	: pbeWithSHA1And40BitRC2-CBC
        +
        +!Alias pkcs12-Version1 pkcs12 10
        +!Alias pkcs12-BagIds pkcs12-Version1 1
        +pkcs12-BagIds 1		:			: keyBag
        +pkcs12-BagIds 2		:			: pkcs8ShroudedKeyBag
        +pkcs12-BagIds 3		:			: certBag
        +pkcs12-BagIds 4		:			: crlBag
        +pkcs12-BagIds 5		:			: secretBag
        +pkcs12-BagIds 6		:			: safeContentsBag
        +
        +rsadsi 2 2		: MD2			: md2
        +rsadsi 2 4		: MD4			: md4
        +rsadsi 2 5		: MD5			: md5
        +			: MD5-SHA1		: md5-sha1
        +rsadsi 2 6		:			: hmacWithMD5
        +rsadsi 2 7		:			: hmacWithSHA1
        +
        +# From RFC4231
        +rsadsi 2 8		:			: hmacWithSHA224
        +rsadsi 2 9		:			: hmacWithSHA256
        +rsadsi 2 10		:			: hmacWithSHA384
        +rsadsi 2 11		:			: hmacWithSHA512
        +
        +rsadsi 3 2		: RC2-CBC		: rc2-cbc
        +			: RC2-ECB		: rc2-ecb
        +!Cname rc2-cfb64
        +			: RC2-CFB		: rc2-cfb
        +!Cname rc2-ofb64
        +			: RC2-OFB		: rc2-ofb
        +			: RC2-40-CBC		: rc2-40-cbc
        +			: RC2-64-CBC		: rc2-64-cbc
        +rsadsi 3 4		: RC4			: rc4
        +			: RC4-40		: rc4-40
        +rsadsi 3 7		: DES-EDE3-CBC		: des-ede3-cbc
        +rsadsi 3 8		: RC5-CBC		: rc5-cbc
        +			: RC5-ECB		: rc5-ecb
        +!Cname rc5-cfb64
        +			: RC5-CFB		: rc5-cfb
        +!Cname rc5-ofb64
        +			: RC5-OFB		: rc5-ofb
        +
        +!Cname ms-ext-req
        +1 3 6 1 4 1 311 2 1 14	: msExtReq		: Microsoft Extension Request
        +!Cname ms-code-ind
        +1 3 6 1 4 1 311 2 1 21	: msCodeInd		: Microsoft Individual Code Signing
        +!Cname ms-code-com
        +1 3 6 1 4 1 311 2 1 22	: msCodeCom		: Microsoft Commercial Code Signing
        +!Cname ms-ctl-sign
        +1 3 6 1 4 1 311 10 3 1	: msCTLSign		: Microsoft Trust List Signing
        +!Cname ms-sgc
        +1 3 6 1 4 1 311 10 3 3	: msSGC			: Microsoft Server Gated Crypto
        +!Cname ms-efs
        +1 3 6 1 4 1 311 10 3 4	: msEFS			: Microsoft Encrypted File System
        +!Cname ms-smartcard-login
        +1 3 6 1 4 1 311 20 2 2	: msSmartcardLogin	: Microsoft Smartcardlogin
        +!Cname ms-upn
        +1 3 6 1 4 1 311 20 2 3	: msUPN			: Microsoft Universal Principal Name
        +
        +1 3 6 1 4 1 188 7 1 1 2	: IDEA-CBC		: idea-cbc
        +			: IDEA-ECB		: idea-ecb
        +!Cname idea-cfb64
        +			: IDEA-CFB		: idea-cfb
        +!Cname idea-ofb64
        +			: IDEA-OFB		: idea-ofb
        +
        +1 3 6 1 4 1 3029 1 2	: BF-CBC		: bf-cbc
        +			: BF-ECB		: bf-ecb
        +!Cname bf-cfb64
        +			: BF-CFB		: bf-cfb
        +!Cname bf-ofb64
        +			: BF-OFB		: bf-ofb
        +
        +!Cname id-pkix
        +1 3 6 1 5 5 7		: PKIX
        +
        +# PKIX Arcs
        +id-pkix 0		: id-pkix-mod
        +id-pkix 1		: id-pe
        +id-pkix 2		: id-qt
        +id-pkix 3		: id-kp
        +id-pkix 4		: id-it
        +id-pkix 5		: id-pkip
        +id-pkix 6		: id-alg
        +id-pkix 7		: id-cmc
        +id-pkix 8		: id-on
        +id-pkix 9		: id-pda
        +id-pkix 10		: id-aca
        +id-pkix 11		: id-qcs
        +id-pkix 12		: id-cct
        +id-pkix 21		: id-ppl
        +id-pkix 48		: id-ad
        +
        +# PKIX Modules
        +id-pkix-mod 1		: id-pkix1-explicit-88
        +id-pkix-mod 2		: id-pkix1-implicit-88
        +id-pkix-mod 3		: id-pkix1-explicit-93
        +id-pkix-mod 4		: id-pkix1-implicit-93
        +id-pkix-mod 5		: id-mod-crmf
        +id-pkix-mod 6		: id-mod-cmc
        +id-pkix-mod 7		: id-mod-kea-profile-88
        +id-pkix-mod 8		: id-mod-kea-profile-93
        +id-pkix-mod 9		: id-mod-cmp
        +id-pkix-mod 10		: id-mod-qualified-cert-88
        +id-pkix-mod 11		: id-mod-qualified-cert-93
        +id-pkix-mod 12		: id-mod-attribute-cert
        +id-pkix-mod 13		: id-mod-timestamp-protocol
        +id-pkix-mod 14		: id-mod-ocsp
        +id-pkix-mod 15		: id-mod-dvcs
        +id-pkix-mod 16		: id-mod-cmp2000
        +
        +# PKIX Private Extensions
        +!Cname info-access
        +id-pe 1			: authorityInfoAccess	: Authority Information Access
        +id-pe 2			: biometricInfo		: Biometric Info
        +id-pe 3			: qcStatements
        +id-pe 4			: ac-auditEntity
        +id-pe 5			: ac-targeting
        +id-pe 6			: aaControls
        +id-pe 7			: sbgp-ipAddrBlock
        +id-pe 8			: sbgp-autonomousSysNum
        +id-pe 9			: sbgp-routerIdentifier
        +id-pe 10		: ac-proxying
        +!Cname sinfo-access
        +id-pe 11		: subjectInfoAccess	: Subject Information Access
        +id-pe 14		: proxyCertInfo		: Proxy Certificate Information
        +
        +# PKIX policyQualifiers for Internet policy qualifiers
        +id-qt 1			: id-qt-cps		: Policy Qualifier CPS
        +id-qt 2			: id-qt-unotice		: Policy Qualifier User Notice
        +id-qt 3			: textNotice
        +
        +# PKIX key purpose identifiers
        +!Cname server-auth
        +id-kp 1			: serverAuth		: TLS Web Server Authentication
        +!Cname client-auth
        +id-kp 2			: clientAuth		: TLS Web Client Authentication
        +!Cname code-sign
        +id-kp 3			: codeSigning		: Code Signing
        +!Cname email-protect
        +id-kp 4			: emailProtection	: E-mail Protection
        +id-kp 5			: ipsecEndSystem	: IPSec End System
        +id-kp 6			: ipsecTunnel		: IPSec Tunnel
        +id-kp 7			: ipsecUser		: IPSec User
        +!Cname time-stamp
        +id-kp 8			: timeStamping		: Time Stamping
        +# From OCSP spec RFC2560
        +!Cname OCSP-sign
        +id-kp 9			: OCSPSigning		: OCSP Signing
        +id-kp 10		: DVCS			: dvcs
        +
        +# CMP information types
        +id-it 1			: id-it-caProtEncCert
        +id-it 2			: id-it-signKeyPairTypes
        +id-it 3			: id-it-encKeyPairTypes
        +id-it 4			: id-it-preferredSymmAlg
        +id-it 5			: id-it-caKeyUpdateInfo
        +id-it 6			: id-it-currentCRL
        +id-it 7			: id-it-unsupportedOIDs
        +# obsolete
        +id-it 8			: id-it-subscriptionRequest
        +# obsolete
        +id-it 9			: id-it-subscriptionResponse
        +id-it 10		: id-it-keyPairParamReq
        +id-it 11		: id-it-keyPairParamRep
        +id-it 12		: id-it-revPassphrase
        +id-it 13		: id-it-implicitConfirm
        +id-it 14		: id-it-confirmWaitTime
        +id-it 15		: id-it-origPKIMessage
        +id-it 16		: id-it-suppLangTags
        +
        +# CRMF registration
        +id-pkip 1		: id-regCtrl
        +id-pkip 2		: id-regInfo
        +
        +# CRMF registration controls
        +id-regCtrl 1		: id-regCtrl-regToken
        +id-regCtrl 2		: id-regCtrl-authenticator
        +id-regCtrl 3		: id-regCtrl-pkiPublicationInfo
        +id-regCtrl 4		: id-regCtrl-pkiArchiveOptions
        +id-regCtrl 5		: id-regCtrl-oldCertID
        +id-regCtrl 6		: id-regCtrl-protocolEncrKey
        +
        +# CRMF registration information
        +id-regInfo 1		: id-regInfo-utf8Pairs
        +id-regInfo 2		: id-regInfo-certReq
        +
        +# algorithms
        +id-alg 1		: id-alg-des40
        +id-alg 2		: id-alg-noSignature
        +id-alg 3		: id-alg-dh-sig-hmac-sha1
        +id-alg 4		: id-alg-dh-pop
        +
        +# CMC controls
        +id-cmc 1		: id-cmc-statusInfo
        +id-cmc 2		: id-cmc-identification
        +id-cmc 3		: id-cmc-identityProof
        +id-cmc 4		: id-cmc-dataReturn
        +id-cmc 5		: id-cmc-transactionId
        +id-cmc 6		: id-cmc-senderNonce
        +id-cmc 7		: id-cmc-recipientNonce
        +id-cmc 8		: id-cmc-addExtensions
        +id-cmc 9		: id-cmc-encryptedPOP
        +id-cmc 10		: id-cmc-decryptedPOP
        +id-cmc 11		: id-cmc-lraPOPWitness
        +id-cmc 15		: id-cmc-getCert
        +id-cmc 16		: id-cmc-getCRL
        +id-cmc 17		: id-cmc-revokeRequest
        +id-cmc 18		: id-cmc-regInfo
        +id-cmc 19		: id-cmc-responseInfo
        +id-cmc 21		: id-cmc-queryPending
        +id-cmc 22		: id-cmc-popLinkRandom
        +id-cmc 23		: id-cmc-popLinkWitness
        +id-cmc 24		: id-cmc-confirmCertAcceptance 
        +
        +# other names
        +id-on 1			: id-on-personalData
        +id-on 3			: id-on-permanentIdentifier : Permanent Identifier
        +
        +# personal data attributes
        +id-pda 1		: id-pda-dateOfBirth
        +id-pda 2		: id-pda-placeOfBirth
        +id-pda 3		: id-pda-gender
        +id-pda 4		: id-pda-countryOfCitizenship
        +id-pda 5		: id-pda-countryOfResidence
        +
        +# attribute certificate attributes
        +id-aca 1		: id-aca-authenticationInfo
        +id-aca 2		: id-aca-accessIdentity
        +id-aca 3		: id-aca-chargingIdentity
        +id-aca 4		: id-aca-group
        +# attention : the following seems to be obsolete, replace by 'role'
        +id-aca 5		: id-aca-role
        +id-aca 6		: id-aca-encAttrs
        +
        +# qualified certificate statements
        +id-qcs 1		: id-qcs-pkixQCSyntax-v1
        +
        +# CMC content types
        +id-cct 1		: id-cct-crs
        +id-cct 2		: id-cct-PKIData
        +id-cct 3		: id-cct-PKIResponse
        +
        +# Predefined Proxy Certificate policy languages
        +id-ppl 0		: id-ppl-anyLanguage	: Any language
        +id-ppl 1		: id-ppl-inheritAll	: Inherit all
        +id-ppl 2		: id-ppl-independent	: Independent
        +
        +# access descriptors for authority info access extension
        +!Cname ad-OCSP
        +id-ad 1			: OCSP			: OCSP
        +!Cname ad-ca-issuers
        +id-ad 2			: caIssuers		: CA Issuers
        +!Cname ad-timeStamping
        +id-ad 3			: ad_timestamping	: AD Time Stamping
        +!Cname ad-dvcs
        +id-ad 4			: AD_DVCS		: ad dvcs
        +id-ad 5			: caRepository		: CA Repository
        +
        +
        +!Alias id-pkix-OCSP ad-OCSP
        +!module id-pkix-OCSP
        +!Cname basic
        +id-pkix-OCSP 1		: basicOCSPResponse	: Basic OCSP Response
        +id-pkix-OCSP 2		: Nonce			: OCSP Nonce
        +id-pkix-OCSP 3		: CrlID			: OCSP CRL ID
        +id-pkix-OCSP 4		: acceptableResponses	: Acceptable OCSP Responses
        +id-pkix-OCSP 5		: noCheck		: OCSP No Check
        +id-pkix-OCSP 6		: archiveCutoff		: OCSP Archive Cutoff
        +id-pkix-OCSP 7		: serviceLocator	: OCSP Service Locator
        +id-pkix-OCSP 8		: extendedStatus	: Extended OCSP Status
        +id-pkix-OCSP 9		: valid
        +id-pkix-OCSP 10		: path
        +id-pkix-OCSP 11		: trustRoot		: Trust Root
        +!global
        +
        +1 3 14 3 2		: algorithm		: algorithm
        +algorithm 3		: RSA-NP-MD5		: md5WithRSA
        +algorithm 6		: DES-ECB		: des-ecb
        +algorithm 7		: DES-CBC		: des-cbc
        +!Cname des-ofb64
        +algorithm 8		: DES-OFB		: des-ofb
        +!Cname des-cfb64
        +algorithm 9		: DES-CFB		: des-cfb
        +algorithm 11		: rsaSignature
        +!Cname dsa-2
        +algorithm 12		: DSA-old		: dsaEncryption-old
        +algorithm 13		: DSA-SHA		: dsaWithSHA
        +algorithm 15		: RSA-SHA		: shaWithRSAEncryption
        +!Cname des-ede-ecb
        +algorithm 17		: DES-EDE		: des-ede
        +!Cname des-ede3-ecb
        +			: DES-EDE3		: des-ede3
        +			: DES-EDE-CBC		: des-ede-cbc
        +!Cname des-ede-cfb64
        +			: DES-EDE-CFB		: des-ede-cfb
        +!Cname des-ede3-cfb64
        +			: DES-EDE3-CFB		: des-ede3-cfb
        +!Cname des-ede-ofb64
        +			: DES-EDE-OFB		: des-ede-ofb
        +!Cname des-ede3-ofb64
        +			: DES-EDE3-OFB		: des-ede3-ofb
        +			: DESX-CBC		: desx-cbc
        +algorithm 18		: SHA			: sha
        +algorithm 26		: SHA1			: sha1
        +!Cname dsaWithSHA1-2
        +algorithm 27		: DSA-SHA1-old		: dsaWithSHA1-old
        +algorithm 29		: RSA-SHA1-2		: sha1WithRSA
        +
        +1 3 36 3 2 1		: RIPEMD160		: ripemd160
        +1 3 36 3 3 1 2		: RSA-RIPEMD160		: ripemd160WithRSA
        +
        +!Cname sxnet
        +1 3 101 1 4 1		: SXNetID		: Strong Extranet ID
        +
        +2 5			: X500			: directory services (X.500)
        +
        +X500 4			: X509
        +X509 3			: CN			: commonName
        +X509 4			: SN			: surname
        +X509 5			: 			: serialNumber
        +X509 6			: C			: countryName
        +X509 7			: L			: localityName
        +X509 8			: ST			: stateOrProvinceName
        +X509 9			: street		: streetAddress
        +X509 10			: O			: organizationName
        +X509 11			: OU			: organizationalUnitName
        +X509 12			: title			: title
        +X509 13			: 			: description
        +X509 14			: 			: searchGuide
        +X509 15			: 			: businessCategory
        +X509 16			: 			: postalAddress
        +X509 17			: 			: postalCode
        +X509 18			: 			: postOfficeBox
        +X509 19			: 			: physicalDeliveryOfficeName
        +X509 20			: 			: telephoneNumber
        +X509 21			: 			: telexNumber
        +X509 22			: 			: teletexTerminalIdentifier
        +X509 23			: 			: facsimileTelephoneNumber
        +X509 24			: 			: x121Address
        +X509 25			: 			: internationaliSDNNumber
        +X509 26			: 			: registeredAddress
        +X509 27			: 			: destinationIndicator
        +X509 28			: 			: preferredDeliveryMethod
        +X509 29			: 			: presentationAddress
        +X509 30			: 			: supportedApplicationContext
        +X509 31			: member		:
        +X509 32			: owner			:
        +X509 33			: 			: roleOccupant
        +X509 34			: seeAlso		:
        +X509 35			: 			: userPassword
        +X509 36			: 			: userCertificate
        +X509 37			: 			: cACertificate
        +X509 38			: 			: authorityRevocationList
        +X509 39			: 			: certificateRevocationList
        +X509 40			: 			: crossCertificatePair
        +X509 41			: name			: name
        +X509 42			: GN			: givenName
        +X509 43			: initials		: initials
        +X509 44			: 			: generationQualifier
        +X509 45			: 			: x500UniqueIdentifier
        +X509 46			: dnQualifier		: dnQualifier
        +X509 47			: 			: enhancedSearchGuide
        +X509 48			: 			: protocolInformation
        +X509 49			: 			: distinguishedName
        +X509 50			: 			: uniqueMember
        +X509 51			: 			: houseIdentifier
        +X509 52			: 			: supportedAlgorithms
        +X509 53			: 			: deltaRevocationList
        +X509 54			: dmdName		:
        +X509 65			:			: pseudonym
        +X509 72			: role			: role
        +
        +X500 8			: X500algorithms	: directory services - algorithms
        +X500algorithms 1 1	: RSA			: rsa
        +X500algorithms 3 100	: RSA-MDC2		: mdc2WithRSA
        +X500algorithms 3 101	: MDC2			: mdc2
        +
        +X500 29			: id-ce
        +!Cname subject-directory-attributes
        +id-ce 9			: subjectDirectoryAttributes : X509v3 Subject Directory Attributes
        +!Cname subject-key-identifier
        +id-ce 14		: subjectKeyIdentifier	: X509v3 Subject Key Identifier
        +!Cname key-usage
        +id-ce 15		: keyUsage		: X509v3 Key Usage
        +!Cname private-key-usage-period
        +id-ce 16		: privateKeyUsagePeriod	: X509v3 Private Key Usage Period
        +!Cname subject-alt-name
        +id-ce 17		: subjectAltName	: X509v3 Subject Alternative Name
        +!Cname issuer-alt-name
        +id-ce 18		: issuerAltName		: X509v3 Issuer Alternative Name
        +!Cname basic-constraints
        +id-ce 19		: basicConstraints	: X509v3 Basic Constraints
        +!Cname crl-number
        +id-ce 20		: crlNumber		: X509v3 CRL Number
        +!Cname crl-reason
        +id-ce 21		: CRLReason		: X509v3 CRL Reason Code
        +!Cname invalidity-date
        +id-ce 24		: invalidityDate	: Invalidity Date
        +!Cname delta-crl
        +id-ce 27		: deltaCRL		: X509v3 Delta CRL Indicator
        +!Cname issuing-distribution-point
        +id-ce 28		: issuingDistributionPoint : X509v3 Issuing Distrubution Point
        +!Cname certificate-issuer
        +id-ce 29		: certificateIssuer	: X509v3 Certificate Issuer
        +!Cname name-constraints
        +id-ce 30		: nameConstraints	: X509v3 Name Constraints
        +!Cname crl-distribution-points
        +id-ce 31		: crlDistributionPoints	: X509v3 CRL Distribution Points
        +!Cname certificate-policies
        +id-ce 32		: certificatePolicies	: X509v3 Certificate Policies
        +!Cname any-policy
        +certificate-policies 0	: anyPolicy		: X509v3 Any Policy
        +!Cname policy-mappings
        +id-ce 33		: policyMappings	: X509v3 Policy Mappings
        +!Cname authority-key-identifier
        +id-ce 35		: authorityKeyIdentifier : X509v3 Authority Key Identifier
        +!Cname policy-constraints
        +id-ce 36		: policyConstraints	: X509v3 Policy Constraints
        +!Cname ext-key-usage
        +id-ce 37		: extendedKeyUsage	: X509v3 Extended Key Usage
        +!Cname freshest-crl
        +id-ce 46		: freshestCRL		: X509v3 Freshest CRL
        +!Cname inhibit-any-policy
        +id-ce 54		: inhibitAnyPolicy	: X509v3 Inhibit Any Policy
        +!Cname target-information
        +id-ce 55		: targetInformation	: X509v3 AC Targeting
        +!Cname no-rev-avail
        +id-ce 56		: noRevAvail		: X509v3 No Revocation Available
        +
        +# From RFC5280
        +ext-key-usage 0		: anyExtendedKeyUsage	: Any Extended Key Usage
        +
        +
        +!Cname netscape
        +2 16 840 1 113730	: Netscape		: Netscape Communications Corp.
        +!Cname netscape-cert-extension
        +netscape 1		: nsCertExt		: Netscape Certificate Extension
        +!Cname netscape-data-type
        +netscape 2		: nsDataType		: Netscape Data Type
        +!Cname netscape-cert-type
        +netscape-cert-extension 1 : nsCertType		: Netscape Cert Type
        +!Cname netscape-base-url
        +netscape-cert-extension 2 : nsBaseUrl		: Netscape Base Url
        +!Cname netscape-revocation-url
        +netscape-cert-extension 3 : nsRevocationUrl	: Netscape Revocation Url
        +!Cname netscape-ca-revocation-url
        +netscape-cert-extension 4 : nsCaRevocationUrl	: Netscape CA Revocation Url
        +!Cname netscape-renewal-url
        +netscape-cert-extension 7 : nsRenewalUrl	: Netscape Renewal Url
        +!Cname netscape-ca-policy-url
        +netscape-cert-extension 8 : nsCaPolicyUrl	: Netscape CA Policy Url
        +!Cname netscape-ssl-server-name
        +netscape-cert-extension 12 : nsSslServerName	: Netscape SSL Server Name
        +!Cname netscape-comment
        +netscape-cert-extension 13 : nsComment		: Netscape Comment
        +!Cname netscape-cert-sequence
        +netscape-data-type 5	: nsCertSequence	: Netscape Certificate Sequence
        +!Cname ns-sgc
        +netscape 4 1		: nsSGC			: Netscape Server Gated Crypto
        +
        +# iso(1)
        +iso 3			: ORG			: org
        +org 6			: DOD			: dod
        +dod 1			: IANA			: iana
        +!Alias internet iana
        +
        +internet 1		: directory		: Directory
        +internet 2		: mgmt			: Management
        +internet 3		: experimental		: Experimental
        +internet 4		: private		: Private
        +internet 5		: security		: Security
        +internet 6		: snmpv2		: SNMPv2
        +# Documents refer to "internet 7" as "mail". This however leads to ambiguities
        +# with RFC2798, Section 9.1.3, where "mail" is defined as the short name for
        +# rfc822Mailbox. The short name is therefore here left out for a reason.
        +# Subclasses of "mail", e.g. "MIME MHS" don't consitute a problem, as
        +# references are realized via long name "Mail" (with capital M).
        +internet 7		:			: Mail
        +
        +Private 1		: enterprises		: Enterprises
        +
        +# RFC 2247
        +Enterprises 1466 344	: dcobject		: dcObject
        +
        +# RFC 1495
        +Mail 1			: mime-mhs		: MIME MHS
        +mime-mhs 1		: mime-mhs-headings	: mime-mhs-headings
        +mime-mhs 2		: mime-mhs-bodies	: mime-mhs-bodies
        +mime-mhs-headings 1	: id-hex-partial-message : id-hex-partial-message
        +mime-mhs-headings 2	: id-hex-multipart-message : id-hex-multipart-message
        +
        +# What the hell are these OIDs, really?
        +!Cname rle-compression
        +1 1 1 1 666 1		: RLE			: run length compression
        +!Cname zlib-compression
        +id-smime-alg 8		: ZLIB			: zlib compression
        +
        +# AES aka Rijndael
        +
        +!Alias csor 2 16 840 1 101 3
        +!Alias nistAlgorithms csor 4
        +!Alias aes nistAlgorithms 1
        +
        +aes 1			: AES-128-ECB		: aes-128-ecb
        +aes 2			: AES-128-CBC		: aes-128-cbc
        +!Cname aes-128-ofb128
        +aes 3			: AES-128-OFB		: aes-128-ofb
        +!Cname aes-128-cfb128
        +aes 4			: AES-128-CFB		: aes-128-cfb
        +aes 5			: id-aes128-wrap
        +aes 6			: id-aes128-GCM		: aes-128-gcm
        +aes 7			: id-aes128-CCM		: aes-128-ccm
        +aes 8			: id-aes128-wrap-pad
        +
        +aes 21			: AES-192-ECB		: aes-192-ecb
        +aes 22			: AES-192-CBC		: aes-192-cbc
        +!Cname aes-192-ofb128
        +aes 23			: AES-192-OFB		: aes-192-ofb
        +!Cname aes-192-cfb128
        +aes 24			: AES-192-CFB		: aes-192-cfb
        +aes 25			: id-aes192-wrap
        +aes 26			: id-aes192-GCM		: aes-192-gcm
        +aes 27			: id-aes192-CCM		: aes-192-ccm
        +aes 28			: id-aes192-wrap-pad
        +
        +aes 41			: AES-256-ECB		: aes-256-ecb
        +aes 42			: AES-256-CBC		: aes-256-cbc
        +!Cname aes-256-ofb128
        +aes 43			: AES-256-OFB		: aes-256-ofb
        +!Cname aes-256-cfb128
        +aes 44			: AES-256-CFB		: aes-256-cfb
        +aes 45			: id-aes256-wrap
        +aes 46			: id-aes256-GCM		: aes-256-gcm
        +aes 47			: id-aes256-CCM		: aes-256-ccm
        +aes 48			: id-aes256-wrap-pad
        +
        +# There are no OIDs for these modes...
        +
        +			: AES-128-CFB1		: aes-128-cfb1
        +			: AES-192-CFB1		: aes-192-cfb1
        +			: AES-256-CFB1		: aes-256-cfb1
        +			: AES-128-CFB8		: aes-128-cfb8
        +			: AES-192-CFB8		: aes-192-cfb8
        +			: AES-256-CFB8		: aes-256-cfb8
        +			: AES-128-CTR		: aes-128-ctr
        +			: AES-192-CTR		: aes-192-ctr
        +			: AES-256-CTR		: aes-256-ctr
        +			: AES-128-XTS		: aes-128-xts
        +			: AES-256-XTS		: aes-256-xts
        +			: DES-CFB1		: des-cfb1
        +			: DES-CFB8		: des-cfb8
        +			: DES-EDE3-CFB1		: des-ede3-cfb1
        +			: DES-EDE3-CFB8		: des-ede3-cfb8
        +
        +# OIDs for SHA224, SHA256, SHA385 and SHA512, according to x9.84.
        +!Alias nist_hashalgs nistAlgorithms 2
        +nist_hashalgs 1		: SHA256		: sha256
        +nist_hashalgs 2		: SHA384		: sha384
        +nist_hashalgs 3		: SHA512		: sha512
        +nist_hashalgs 4		: SHA224		: sha224
        +
        +# OIDs for dsa-with-sha224 and dsa-with-sha256
        +!Alias dsa_with_sha2 nistAlgorithms 3
        +dsa_with_sha2 1		: dsa_with_SHA224
        +dsa_with_sha2 2		: dsa_with_SHA256
        +
        +# Hold instruction CRL entry extension
        +!Cname hold-instruction-code
        +id-ce 23		: holdInstructionCode	: Hold Instruction Code
        +!Alias holdInstruction	X9-57 2
        +!Cname hold-instruction-none
        +holdInstruction 1	: holdInstructionNone	: Hold Instruction None
        +!Cname hold-instruction-call-issuer
        +holdInstruction 2	: holdInstructionCallIssuer : Hold Instruction Call Issuer
        +!Cname hold-instruction-reject
        +holdInstruction 3	: holdInstructionReject	: Hold Instruction Reject
        +
        +# OID's from ITU-T.  Most of this is defined in RFC 1274.  A couple of
        +# them are also mentioned in RFC 2247
        +itu-t 9			: data
        +data 2342		: pss
        +pss 19200300		: ucl
        +ucl 100			: pilot
        +pilot 1			:			: pilotAttributeType
        +pilot 3			:			: pilotAttributeSyntax
        +pilot 4			:			: pilotObjectClass
        +pilot 10		:			: pilotGroups
        +pilotAttributeSyntax 4	:			: iA5StringSyntax
        +pilotAttributeSyntax 5	:			: caseIgnoreIA5StringSyntax
        +pilotObjectClass 3	:			: pilotObject
        +pilotObjectClass 4	:			: pilotPerson
        +pilotObjectClass 5	: account
        +pilotObjectClass 6	: document
        +pilotObjectClass 7	: room
        +pilotObjectClass 9	:			: documentSeries
        +pilotObjectClass 13	: domain		: Domain
        +pilotObjectClass 14	:			: rFC822localPart
        +pilotObjectClass 15	:			: dNSDomain
        +pilotObjectClass 17	:			: domainRelatedObject
        +pilotObjectClass 18	:			: friendlyCountry
        +pilotObjectClass 19	:			: simpleSecurityObject
        +pilotObjectClass 20	:			: pilotOrganization
        +pilotObjectClass 21	:			: pilotDSA
        +pilotObjectClass 22	:			: qualityLabelledData
        +pilotAttributeType 1	: UID			: userId
        +pilotAttributeType 2	:			: textEncodedORAddress
        +pilotAttributeType 3	: mail			: rfc822Mailbox
        +pilotAttributeType 4	: info
        +pilotAttributeType 5	:			: favouriteDrink
        +pilotAttributeType 6	:			: roomNumber
        +pilotAttributeType 7	: photo
        +pilotAttributeType 8	:			: userClass
        +pilotAttributeType 9	: host
        +pilotAttributeType 10	: manager
        +pilotAttributeType 11	:			: documentIdentifier
        +pilotAttributeType 12	:			: documentTitle
        +pilotAttributeType 13	:			: documentVersion
        +pilotAttributeType 14	:			: documentAuthor
        +pilotAttributeType 15	:			: documentLocation
        +pilotAttributeType 20	:			: homeTelephoneNumber
        +pilotAttributeType 21	: secretary
        +pilotAttributeType 22	:			: otherMailbox
        +pilotAttributeType 23	:			: lastModifiedTime
        +pilotAttributeType 24	:			: lastModifiedBy
        +pilotAttributeType 25	: DC			: domainComponent
        +pilotAttributeType 26	:			: aRecord
        +pilotAttributeType 27	:			: pilotAttributeType27
        +pilotAttributeType 28	:			: mXRecord
        +pilotAttributeType 29	:			: nSRecord
        +pilotAttributeType 30	:			: sOARecord
        +pilotAttributeType 31	:			: cNAMERecord
        +pilotAttributeType 37	:			: associatedDomain
        +pilotAttributeType 38	:			: associatedName
        +pilotAttributeType 39	:			: homePostalAddress
        +pilotAttributeType 40	:			: personalTitle
        +pilotAttributeType 41	:			: mobileTelephoneNumber
        +pilotAttributeType 42	:			: pagerTelephoneNumber
        +pilotAttributeType 43	:			: friendlyCountryName
        +# The following clashes with 2.5.4.45, so commented away
        +#pilotAttributeType 44	: uid			: uniqueIdentifier
        +pilotAttributeType 45	:			: organizationalStatus
        +pilotAttributeType 46	:			: janetMailbox
        +pilotAttributeType 47	:			: mailPreferenceOption
        +pilotAttributeType 48	:			: buildingName
        +pilotAttributeType 49	:			: dSAQuality
        +pilotAttributeType 50	:			: singleLevelQuality
        +pilotAttributeType 51	:			: subtreeMinimumQuality
        +pilotAttributeType 52	:			: subtreeMaximumQuality
        +pilotAttributeType 53	:			: personalSignature
        +pilotAttributeType 54	:			: dITRedirect
        +pilotAttributeType 55	: audio
        +pilotAttributeType 56	:			: documentPublisher
        +
        +international-organizations 42	: id-set	: Secure Electronic Transactions
        +
        +id-set 0		: set-ctype		: content types
        +id-set 1		: set-msgExt		: message extensions
        +id-set 3		: set-attr
        +id-set 5		: set-policy
        +id-set 7		: set-certExt		: certificate extensions
        +id-set 8		: set-brand
        +
        +set-ctype 0		: setct-PANData
        +set-ctype 1		: setct-PANToken
        +set-ctype 2		: setct-PANOnly
        +set-ctype 3		: setct-OIData
        +set-ctype 4		: setct-PI
        +set-ctype 5		: setct-PIData
        +set-ctype 6		: setct-PIDataUnsigned
        +set-ctype 7		: setct-HODInput
        +set-ctype 8		: setct-AuthResBaggage
        +set-ctype 9		: setct-AuthRevReqBaggage
        +set-ctype 10		: setct-AuthRevResBaggage
        +set-ctype 11		: setct-CapTokenSeq
        +set-ctype 12		: setct-PInitResData
        +set-ctype 13		: setct-PI-TBS
        +set-ctype 14		: setct-PResData
        +set-ctype 16		: setct-AuthReqTBS
        +set-ctype 17		: setct-AuthResTBS
        +set-ctype 18		: setct-AuthResTBSX
        +set-ctype 19		: setct-AuthTokenTBS
        +set-ctype 20		: setct-CapTokenData
        +set-ctype 21		: setct-CapTokenTBS
        +set-ctype 22		: setct-AcqCardCodeMsg
        +set-ctype 23		: setct-AuthRevReqTBS
        +set-ctype 24		: setct-AuthRevResData
        +set-ctype 25		: setct-AuthRevResTBS
        +set-ctype 26		: setct-CapReqTBS
        +set-ctype 27		: setct-CapReqTBSX
        +set-ctype 28		: setct-CapResData
        +set-ctype 29		: setct-CapRevReqTBS
        +set-ctype 30		: setct-CapRevReqTBSX
        +set-ctype 31		: setct-CapRevResData
        +set-ctype 32		: setct-CredReqTBS
        +set-ctype 33		: setct-CredReqTBSX
        +set-ctype 34		: setct-CredResData
        +set-ctype 35		: setct-CredRevReqTBS
        +set-ctype 36		: setct-CredRevReqTBSX
        +set-ctype 37		: setct-CredRevResData
        +set-ctype 38		: setct-PCertReqData
        +set-ctype 39		: setct-PCertResTBS
        +set-ctype 40		: setct-BatchAdminReqData
        +set-ctype 41		: setct-BatchAdminResData
        +set-ctype 42		: setct-CardCInitResTBS
        +set-ctype 43		: setct-MeAqCInitResTBS
        +set-ctype 44		: setct-RegFormResTBS
        +set-ctype 45		: setct-CertReqData
        +set-ctype 46		: setct-CertReqTBS
        +set-ctype 47		: setct-CertResData
        +set-ctype 48		: setct-CertInqReqTBS
        +set-ctype 49		: setct-ErrorTBS
        +set-ctype 50		: setct-PIDualSignedTBE
        +set-ctype 51		: setct-PIUnsignedTBE
        +set-ctype 52		: setct-AuthReqTBE
        +set-ctype 53		: setct-AuthResTBE
        +set-ctype 54		: setct-AuthResTBEX
        +set-ctype 55		: setct-AuthTokenTBE
        +set-ctype 56		: setct-CapTokenTBE
        +set-ctype 57		: setct-CapTokenTBEX
        +set-ctype 58		: setct-AcqCardCodeMsgTBE
        +set-ctype 59		: setct-AuthRevReqTBE
        +set-ctype 60		: setct-AuthRevResTBE
        +set-ctype 61		: setct-AuthRevResTBEB
        +set-ctype 62		: setct-CapReqTBE
        +set-ctype 63		: setct-CapReqTBEX
        +set-ctype 64		: setct-CapResTBE
        +set-ctype 65		: setct-CapRevReqTBE
        +set-ctype 66		: setct-CapRevReqTBEX
        +set-ctype 67		: setct-CapRevResTBE
        +set-ctype 68		: setct-CredReqTBE
        +set-ctype 69		: setct-CredReqTBEX
        +set-ctype 70		: setct-CredResTBE
        +set-ctype 71		: setct-CredRevReqTBE
        +set-ctype 72		: setct-CredRevReqTBEX
        +set-ctype 73		: setct-CredRevResTBE
        +set-ctype 74		: setct-BatchAdminReqTBE
        +set-ctype 75		: setct-BatchAdminResTBE
        +set-ctype 76		: setct-RegFormReqTBE
        +set-ctype 77		: setct-CertReqTBE
        +set-ctype 78		: setct-CertReqTBEX
        +set-ctype 79		: setct-CertResTBE
        +set-ctype 80		: setct-CRLNotificationTBS
        +set-ctype 81		: setct-CRLNotificationResTBS
        +set-ctype 82		: setct-BCIDistributionTBS
        +
        +set-msgExt 1		: setext-genCrypt	: generic cryptogram
        +set-msgExt 3		: setext-miAuth		: merchant initiated auth
        +set-msgExt 4		: setext-pinSecure
        +set-msgExt 5		: setext-pinAny
        +set-msgExt 7		: setext-track2
        +set-msgExt 8		: setext-cv		: additional verification
        +
        +set-policy 0		: set-policy-root
        +
        +set-certExt 0		: setCext-hashedRoot
        +set-certExt 1		: setCext-certType
        +set-certExt 2		: setCext-merchData
        +set-certExt 3		: setCext-cCertRequired
        +set-certExt 4		: setCext-tunneling
        +set-certExt 5		: setCext-setExt
        +set-certExt 6		: setCext-setQualf
        +set-certExt 7		: setCext-PGWYcapabilities
        +set-certExt 8		: setCext-TokenIdentifier
        +set-certExt 9		: setCext-Track2Data
        +set-certExt 10		: setCext-TokenType
        +set-certExt 11		: setCext-IssuerCapabilities
        +
        +set-attr 0		: setAttr-Cert
        +set-attr 1		: setAttr-PGWYcap	: payment gateway capabilities
        +set-attr 2		: setAttr-TokenType
        +set-attr 3		: setAttr-IssCap	: issuer capabilities
        +
        +setAttr-Cert 0		: set-rootKeyThumb
        +setAttr-Cert 1		: set-addPolicy
        +
        +setAttr-TokenType 1	: setAttr-Token-EMV
        +setAttr-TokenType 2	: setAttr-Token-B0Prime
        +
        +setAttr-IssCap 3	: setAttr-IssCap-CVM
        +setAttr-IssCap 4	: setAttr-IssCap-T2
        +setAttr-IssCap 5	: setAttr-IssCap-Sig
        +
        +setAttr-IssCap-CVM 1	: setAttr-GenCryptgrm	: generate cryptogram
        +setAttr-IssCap-T2 1	: setAttr-T2Enc		: encrypted track 2
        +setAttr-IssCap-T2 2	: setAttr-T2cleartxt	: cleartext track 2
        +
        +setAttr-IssCap-Sig 1	: setAttr-TokICCsig	: ICC or token signature
        +setAttr-IssCap-Sig 2	: setAttr-SecDevSig	: secure device signature
        +
        +set-brand 1		: set-brand-IATA-ATA
        +set-brand 30		: set-brand-Diners
        +set-brand 34		: set-brand-AmericanExpress
        +set-brand 35		: set-brand-JCB
        +set-brand 4		: set-brand-Visa
        +set-brand 5		: set-brand-MasterCard
        +set-brand 6011		: set-brand-Novus
        +
        +rsadsi 3 10		: DES-CDMF		: des-cdmf
        +rsadsi 1 1 6		: rsaOAEPEncryptionSET
        +
        +			: Oakley-EC2N-3		: ipsec3
        +			: Oakley-EC2N-4		: ipsec4
        +
        +iso 0 10118 3 0 55	: whirlpool
        +
        +# GOST OIDs
        +
        +member-body 643 2 2	: cryptopro
        +member-body 643 2 9	: cryptocom
        +
        +cryptopro 3		: id-GostR3411-94-with-GostR3410-2001 : GOST R 34.11-94 with GOST R 34.10-2001
        +cryptopro 4		: id-GostR3411-94-with-GostR3410-94 : GOST R 34.11-94 with GOST R 34.10-94
        +!Cname id-GostR3411-94
        +cryptopro 9		: md_gost94		: GOST R 34.11-94
        +cryptopro 10		: id-HMACGostR3411-94	: HMAC GOST 34.11-94
        +!Cname id-GostR3410-2001
        +cryptopro 19		: gost2001	: GOST R 34.10-2001
        +!Cname id-GostR3410-94
        +cryptopro 20		: gost94	: GOST R 34.10-94
        +!Cname id-Gost28147-89
        +cryptopro 21		: gost89 		: GOST 28147-89
        +			: gost89-cnt
        +!Cname id-Gost28147-89-MAC
        +cryptopro 22		: gost-mac	: GOST 28147-89 MAC
        +!Cname id-GostR3411-94-prf
        +cryptopro 23		: prf-gostr3411-94	: GOST R 34.11-94 PRF
        +cryptopro 98		: id-GostR3410-2001DH	: GOST R 34.10-2001 DH
        +cryptopro 99		: id-GostR3410-94DH	: GOST R 34.10-94 DH
        +
        +cryptopro 14 1		: id-Gost28147-89-CryptoPro-KeyMeshing
        +cryptopro 14 0		: id-Gost28147-89-None-KeyMeshing
        +
        +# GOST parameter set OIDs
        +
        +cryptopro 30 0		: id-GostR3411-94-TestParamSet
        +cryptopro 30 1		: id-GostR3411-94-CryptoProParamSet
        +
        +cryptopro 31 0		: id-Gost28147-89-TestParamSet
        +cryptopro 31 1		: id-Gost28147-89-CryptoPro-A-ParamSet
        +cryptopro 31 2		: id-Gost28147-89-CryptoPro-B-ParamSet
        +cryptopro 31 3		: id-Gost28147-89-CryptoPro-C-ParamSet
        +cryptopro 31 4		: id-Gost28147-89-CryptoPro-D-ParamSet
        +cryptopro 31 5		: id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet
        +cryptopro 31 6		: id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet
        +cryptopro 31 7		: id-Gost28147-89-CryptoPro-RIC-1-ParamSet
        +
        +cryptopro 32 0		: id-GostR3410-94-TestParamSet
        +cryptopro 32 2		: id-GostR3410-94-CryptoPro-A-ParamSet
        +cryptopro 32 3		: id-GostR3410-94-CryptoPro-B-ParamSet
        +cryptopro 32 4		: id-GostR3410-94-CryptoPro-C-ParamSet
        +cryptopro 32 5		: id-GostR3410-94-CryptoPro-D-ParamSet
        +
        +cryptopro 33 1		: id-GostR3410-94-CryptoPro-XchA-ParamSet
        +cryptopro 33 2		: id-GostR3410-94-CryptoPro-XchB-ParamSet
        +cryptopro 33 3		: id-GostR3410-94-CryptoPro-XchC-ParamSet
        +
        +cryptopro 35 0		: id-GostR3410-2001-TestParamSet
        +cryptopro 35 1		: id-GostR3410-2001-CryptoPro-A-ParamSet
        +cryptopro 35 2		: id-GostR3410-2001-CryptoPro-B-ParamSet
        +cryptopro 35 3		: id-GostR3410-2001-CryptoPro-C-ParamSet
        +
        +cryptopro 36 0		: id-GostR3410-2001-CryptoPro-XchA-ParamSet
        +cryptopro 36 1		: id-GostR3410-2001-CryptoPro-XchB-ParamSet
        +
        +id-GostR3410-94 1	: id-GostR3410-94-a
        +id-GostR3410-94 2	: id-GostR3410-94-aBis
        +id-GostR3410-94 3	: id-GostR3410-94-b
        +id-GostR3410-94 4	: id-GostR3410-94-bBis
        +
        +# Cryptocom LTD GOST OIDs
        +
        +cryptocom 1 6 1		: id-Gost28147-89-cc	: GOST 28147-89 Cryptocom ParamSet
        +!Cname id-GostR3410-94-cc
        +cryptocom 1 5 3		: gost94cc	: GOST 34.10-94 Cryptocom
        +!Cname id-GostR3410-2001-cc
        +cryptocom 1 5 4		: gost2001cc	: GOST 34.10-2001 Cryptocom
        +
        +cryptocom 1 3 3		: id-GostR3411-94-with-GostR3410-94-cc : GOST R 34.11-94 with GOST R 34.10-94 Cryptocom
        +cryptocom 1 3 4		: id-GostR3411-94-with-GostR3410-2001-cc : GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom
        +
        +cryptocom 1 8 1		: id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Set Cryptocom
        +
        +# Definitions for Camellia cipher - CBC MODE
        +
        +1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC		: camellia-128-cbc
        +1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC		: camellia-192-cbc
        +1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC		: camellia-256-cbc
        +1 2 392 200011 61 1 1 3 2 : id-camellia128-wrap
        +1 2 392 200011 61 1 1 3 3 : id-camellia192-wrap
        +1 2 392 200011 61 1 1 3 4 : id-camellia256-wrap
        +
        +# Definitions for Camellia cipher - ECB, CFB, OFB MODE
        +
        +!Alias ntt-ds 0 3 4401 5
        +!Alias camellia ntt-ds 3 1 9 
        +
        +camellia 1		: CAMELLIA-128-ECB		: camellia-128-ecb
        +!Cname camellia-128-ofb128
        +camellia 3		: CAMELLIA-128-OFB		: camellia-128-ofb
        +!Cname camellia-128-cfb128
        +camellia 4		: CAMELLIA-128-CFB		: camellia-128-cfb
        +
        +camellia 21		: CAMELLIA-192-ECB		: camellia-192-ecb
        +!Cname camellia-192-ofb128
        +camellia 23		: CAMELLIA-192-OFB		: camellia-192-ofb
        +!Cname camellia-192-cfb128
        +camellia 24		: CAMELLIA-192-CFB		: camellia-192-cfb
        +
        +camellia 41		: CAMELLIA-256-ECB		: camellia-256-ecb
        +!Cname camellia-256-ofb128
        +camellia 43		: CAMELLIA-256-OFB		: camellia-256-ofb
        +!Cname camellia-256-cfb128
        +camellia 44		: CAMELLIA-256-CFB		: camellia-256-cfb
        +
        +# There are no OIDs for these modes...
        +
        +			: CAMELLIA-128-CFB1		: camellia-128-cfb1
        +			: CAMELLIA-192-CFB1		: camellia-192-cfb1
        +			: CAMELLIA-256-CFB1		: camellia-256-cfb1
        +			: CAMELLIA-128-CFB8		: camellia-128-cfb8
        +			: CAMELLIA-192-CFB8		: camellia-192-cfb8
        +			: CAMELLIA-256-CFB8		: camellia-256-cfb8
        +
        +# Definitions for SEED cipher - ECB, CBC, OFB mode
        +
        +member-body 410 200004  : KISA          : kisa
        +kisa 1 3                : SEED-ECB      : seed-ecb
        +kisa 1 4                : SEED-CBC      : seed-cbc
        +!Cname seed-cfb128
        +kisa 1 5                : SEED-CFB      : seed-cfb
        +!Cname seed-ofb128
        +kisa 1 6                : SEED-OFB      : seed-ofb
        +
        +# There is no OID that just denotes "HMAC" oddly enough...
        +
        +			: HMAC				: hmac
        +# Nor CMAC either
        +			: CMAC				: cmac
        +
        +# Synthetic composite ciphersuites
        +			: RC4-HMAC-MD5			: rc4-hmac-md5
        +			: AES-128-CBC-HMAC-SHA1		: aes-128-cbc-hmac-sha1
        +			: AES-192-CBC-HMAC-SHA1		: aes-192-cbc-hmac-sha1
        +			: AES-256-CBC-HMAC-SHA1		: aes-256-cbc-hmac-sha1
        diff --git a/vendor/openssl/openssl/crypto/objects/objxref.pl b/vendor/openssl/openssl/crypto/objects/objxref.pl
        new file mode 100644
        index 000000000..731d3ae22
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/objects/objxref.pl
        @@ -0,0 +1,107 @@
        +#!/usr/local/bin/perl
        +
        +use strict;
        +
        +my %xref_tbl;
        +my %oid_tbl;
        +
        +my ($mac_file, $xref_file) = @ARGV;
        +
        +open(IN, $mac_file) || die "Can't open $mac_file";
        +
        +# Read in OID nid values for a lookup table.
        +
        +while (<IN>)
        +	{
        +	chomp;
        +	my ($name, $num) = /^(\S+)\s+(\S+)$/;
        +	$oid_tbl{$name} = $num;
        +	}
        +close IN;
        +
        +open(IN, $xref_file) || die "Can't open $xref_file";
        +
        +my $ln = 1;
        +
        +while (<IN>)
        +	{
        +	chomp;
        +	s/#.*$//;
        +	next if (/^\S*$/);
        +	my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/;
        +	check_oid($xr);
        +	check_oid($p1);
        +	check_oid($p2);
        +	$xref_tbl{$xr} = [$p1, $p2, $ln];
        +	}
        +
        +my @xrkeys = keys %xref_tbl;
        +
        +my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys;
        +
        +for(my $i = 0; $i <= $#srt1; $i++)
        +	{
        +	$xref_tbl{$srt1[$i]}[2] = $i;
        +	}
        +
        +my @srt2 = sort
        +	{
        +	my$ap1 = $oid_tbl{$xref_tbl{$a}[0]};
        +	my$bp1 = $oid_tbl{$xref_tbl{$b}[0]};
        +	return $ap1 - $bp1 if ($ap1 != $bp1);
        +	my$ap2 = $oid_tbl{$xref_tbl{$a}[1]};
        +	my$bp2 = $oid_tbl{$xref_tbl{$b}[1]};
        +
        +	return $ap2 - $bp2;
        +	} @xrkeys;
        +
        +my $pname = $0;
        +
        +$pname =~ s|^.[^/]/||;
        +
        +print <<EOF;
        +/* AUTOGENERATED BY $pname, DO NOT EDIT */
        +
        +typedef struct
        +	{
        +	int sign_id;
        +	int hash_id;
        +	int pkey_id;
        +	} nid_triple;
        +
        +static const nid_triple sigoid_srt[] =
        +	{
        +EOF
        +
        +foreach (@srt1)
        +	{
        +	my $xr = $_;
        +	my ($p1, $p2) = @{$xref_tbl{$_}};
        +	print "\t{NID_$xr, NID_$p1, NID_$p2},\n";
        +	}
        +
        +print "\t};";
        +print <<EOF;
        +
        +
        +static const nid_triple * const sigoid_srt_xref[] =
        +	{
        +EOF
        +
        +foreach (@srt2)
        +	{
        +	my $x = $xref_tbl{$_}[2];
        +	print "\t\&sigoid_srt\[$x\],\n";
        +	}
        +
        +print "\t};\n\n";
        +
        +sub check_oid
        +	{
        +	my ($chk) = @_;
        +	if (!exists $oid_tbl{$chk})
        +		{
        +		die "Not Found \"$chk\"\n";
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ocsp/Makefile b/vendor/openssl/openssl/crypto/ocsp/Makefile
        new file mode 100644
        index 000000000..60c414cf4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/Makefile
        @@ -0,0 +1,213 @@
        +#
        +# OpenSSL/ocsp/Makefile
        +#
        +
        +DIR=	ocsp
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= ocsp_asn.c ocsp_ext.c ocsp_ht.c ocsp_lib.c ocsp_cl.c \
        +	ocsp_srv.c ocsp_prn.c ocsp_vfy.c ocsp_err.c
        +
        +LIBOBJ= ocsp_asn.o ocsp_ext.o ocsp_ht.o ocsp_lib.o ocsp_cl.o \
        +	ocsp_srv.o ocsp_prn.o ocsp_vfy.o ocsp_err.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ocsp.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +ocsp_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +ocsp_asn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ocsp_asn.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ocsp_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ocsp_asn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ocsp_asn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ocsp_asn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ocsp_asn.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
        +ocsp_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_asn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ocsp_asn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ocsp_asn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ocsp_asn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ocsp_asn.o: ocsp_asn.c
        +ocsp_cl.o: ../../e_os.h ../../include/openssl/asn1.h
        +ocsp_cl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ocsp_cl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ocsp_cl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ocsp_cl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ocsp_cl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ocsp_cl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ocsp_cl.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
        +ocsp_cl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ocsp_cl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +ocsp_cl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +ocsp_cl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +ocsp_cl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ocsp_cl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ocsp_cl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ocsp_cl.o: ../cryptlib.h ocsp_cl.c
        +ocsp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ocsp_err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ocsp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ocsp_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ocsp_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ocsp_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ocsp_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ocsp_err.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
        +ocsp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ocsp_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ocsp_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ocsp_err.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ocsp_err.o: ocsp_err.c
        +ocsp_ext.o: ../../e_os.h ../../include/openssl/asn1.h
        +ocsp_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ocsp_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ocsp_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ocsp_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ocsp_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ocsp_ext.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ocsp_ext.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
        +ocsp_ext.o: ../../include/openssl/opensslconf.h
        +ocsp_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +ocsp_ext.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ocsp_ext.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ocsp_ext.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ocsp_ext.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_ext.c
        +ocsp_ht.o: ../../e_os.h ../../include/openssl/asn1.h
        +ocsp_ht.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ocsp_ht.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ocsp_ht.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ocsp_ht.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ocsp_ht.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ocsp_ht.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ocsp_ht.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
        +ocsp_ht.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ocsp_ht.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ocsp_ht.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ocsp_ht.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ocsp_ht.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ocsp_ht.o: ../../include/openssl/x509v3.h ocsp_ht.c
        +ocsp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +ocsp_lib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +ocsp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ocsp_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ocsp_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ocsp_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ocsp_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ocsp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ocsp_lib.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
        +ocsp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_lib.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +ocsp_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +ocsp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ocsp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ocsp_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ocsp_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_lib.c
        +ocsp_prn.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ocsp_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ocsp_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ocsp_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ocsp_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ocsp_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ocsp_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ocsp_prn.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
        +ocsp_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_prn.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +ocsp_prn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ocsp_prn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ocsp_prn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ocsp_prn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ocsp_prn.o: ocsp_prn.c
        +ocsp_srv.o: ../../e_os.h ../../include/openssl/asn1.h
        +ocsp_srv.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ocsp_srv.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ocsp_srv.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ocsp_srv.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ocsp_srv.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ocsp_srv.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ocsp_srv.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
        +ocsp_srv.o: ../../include/openssl/opensslconf.h
        +ocsp_srv.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_srv.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +ocsp_srv.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +ocsp_srv.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ocsp_srv.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ocsp_srv.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ocsp_srv.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_srv.c
        +ocsp_vfy.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ocsp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ocsp_vfy.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ocsp_vfy.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ocsp_vfy.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ocsp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ocsp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ocsp_vfy.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
        +ocsp_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ocsp_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +ocsp_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ocsp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ocsp_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ocsp_vfy.o: ocsp_vfy.c
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp.h b/vendor/openssl/openssl/crypto/ocsp/ocsp.h
        new file mode 100644
        index 000000000..31e45744b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp.h
        @@ -0,0 +1,623 @@
        +/* ocsp.h */
        +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
        + * project. */
        +
        +/* History:
        +   This file was transfered to Richard Levitte from CertCo by Kathy
        +   Weinhold in mid-spring 2000 to be included in OpenSSL or released
        +   as a patch kit. */
        +
        +/* ====================================================================
        + * 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_OCSP_H
        +#define HEADER_OCSP_H
        +
        +#include <openssl/ossl_typ.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/safestack.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Various flags and values */
        +
        +#define OCSP_DEFAULT_NONCE_LENGTH	16
        +
        +#define OCSP_NOCERTS			0x1
        +#define OCSP_NOINTERN			0x2
        +#define OCSP_NOSIGS			0x4
        +#define OCSP_NOCHAIN			0x8
        +#define OCSP_NOVERIFY			0x10
        +#define OCSP_NOEXPLICIT			0x20
        +#define OCSP_NOCASIGN			0x40
        +#define OCSP_NODELEGATED		0x80
        +#define OCSP_NOCHECKS			0x100
        +#define OCSP_TRUSTOTHER			0x200
        +#define OCSP_RESPID_KEY			0x400
        +#define OCSP_NOTIME			0x800
        +
        +/*   CertID ::= SEQUENCE {
        + *       hashAlgorithm            AlgorithmIdentifier,
        + *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
        + *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
        + *       serialNumber       CertificateSerialNumber }
        + */
        +typedef struct ocsp_cert_id_st
        +	{
        +	X509_ALGOR *hashAlgorithm;
        +	ASN1_OCTET_STRING *issuerNameHash;
        +	ASN1_OCTET_STRING *issuerKeyHash;
        +	ASN1_INTEGER *serialNumber;
        +	} OCSP_CERTID;
        +
        +DECLARE_STACK_OF(OCSP_CERTID)
        +
        +/*   Request ::=     SEQUENCE {
        + *       reqCert                    CertID,
        + *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
        + */
        +typedef struct ocsp_one_request_st
        +	{
        +	OCSP_CERTID *reqCert;
        +	STACK_OF(X509_EXTENSION) *singleRequestExtensions;
        +	} OCSP_ONEREQ;
        +
        +DECLARE_STACK_OF(OCSP_ONEREQ)
        +DECLARE_ASN1_SET_OF(OCSP_ONEREQ)
        +
        +
        +/*   TBSRequest      ::=     SEQUENCE {
        + *       version             [0] EXPLICIT Version DEFAULT v1,
        + *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
        + *       requestList             SEQUENCE OF Request,
        + *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
        + */
        +typedef struct ocsp_req_info_st
        +	{
        +	ASN1_INTEGER *version;
        +	GENERAL_NAME *requestorName;
        +	STACK_OF(OCSP_ONEREQ) *requestList;
        +	STACK_OF(X509_EXTENSION) *requestExtensions;
        +	} OCSP_REQINFO;
        +
        +/*   Signature       ::=     SEQUENCE {
        + *       signatureAlgorithm   AlgorithmIdentifier,
        + *       signature            BIT STRING,
        + *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
        + */
        +typedef struct ocsp_signature_st
        +	{
        +	X509_ALGOR *signatureAlgorithm;
        +	ASN1_BIT_STRING *signature;
        +	STACK_OF(X509) *certs;
        +	} OCSP_SIGNATURE;
        +
        +/*   OCSPRequest     ::=     SEQUENCE {
        + *       tbsRequest                  TBSRequest,
        + *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
        + */
        +typedef struct ocsp_request_st
        +	{
        +	OCSP_REQINFO *tbsRequest;
        +	OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
        +	} OCSP_REQUEST;
        +
        +/*   OCSPResponseStatus ::= ENUMERATED {
        + *       successful            (0),      --Response has valid confirmations
        + *       malformedRequest      (1),      --Illegal confirmation request
        + *       internalError         (2),      --Internal error in issuer
        + *       tryLater              (3),      --Try again later
        + *                                       --(4) is not used
        + *       sigRequired           (5),      --Must sign the request
        + *       unauthorized          (6)       --Request unauthorized
        + *   }
        + */
        +#define OCSP_RESPONSE_STATUS_SUCCESSFUL          0
        +#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
        +#define OCSP_RESPONSE_STATUS_INTERNALERROR        2
        +#define OCSP_RESPONSE_STATUS_TRYLATER             3
        +#define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
        +#define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6
        +
        +/*   ResponseBytes ::=       SEQUENCE {
        + *       responseType   OBJECT IDENTIFIER,
        + *       response       OCTET STRING }
        + */
        +typedef struct ocsp_resp_bytes_st
        +	{
        +	ASN1_OBJECT *responseType;
        +	ASN1_OCTET_STRING *response;
        +	} OCSP_RESPBYTES;
        +
        +/*   OCSPResponse ::= SEQUENCE {
        + *      responseStatus         OCSPResponseStatus,
        + *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
        + */
        +struct ocsp_response_st
        +	{
        +	ASN1_ENUMERATED *responseStatus;
        +	OCSP_RESPBYTES  *responseBytes;
        +	};
        +
        +/*   ResponderID ::= CHOICE {
        + *      byName   [1] Name,
        + *      byKey    [2] KeyHash }
        + */
        +#define V_OCSP_RESPID_NAME 0
        +#define V_OCSP_RESPID_KEY  1
        +struct ocsp_responder_id_st
        +	{
        +	int type;
        +	union   {
        +		X509_NAME* byName;
        +        	ASN1_OCTET_STRING *byKey;
        +		} value;
        +	};
        +
        +DECLARE_STACK_OF(OCSP_RESPID)
        +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
        +
        +/*   KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
        + *                            --(excluding the tag and length fields)
        + */
        +
        +/*   RevokedInfo ::= SEQUENCE {
        + *       revocationTime              GeneralizedTime,
        + *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
        + */
        +typedef struct ocsp_revoked_info_st
        +	{
        +	ASN1_GENERALIZEDTIME *revocationTime;
        +	ASN1_ENUMERATED *revocationReason;
        +	} OCSP_REVOKEDINFO;
        +
        +/*   CertStatus ::= CHOICE {
        + *       good                [0]     IMPLICIT NULL,
        + *       revoked             [1]     IMPLICIT RevokedInfo,
        + *       unknown             [2]     IMPLICIT UnknownInfo }
        + */
        +#define V_OCSP_CERTSTATUS_GOOD    0
        +#define V_OCSP_CERTSTATUS_REVOKED 1
        +#define V_OCSP_CERTSTATUS_UNKNOWN 2
        +typedef struct ocsp_cert_status_st
        +	{
        +	int type;
        +	union	{
        +		ASN1_NULL *good;
        +		OCSP_REVOKEDINFO *revoked;
        +		ASN1_NULL *unknown;
        +		} value;
        +	} OCSP_CERTSTATUS;
        +
        +/*   SingleResponse ::= SEQUENCE {
        + *      certID                       CertID,
        + *      certStatus                   CertStatus,
        + *      thisUpdate                   GeneralizedTime,
        + *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
        + *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
        + */
        +typedef struct ocsp_single_response_st
        +	{
        +	OCSP_CERTID *certId;
        +	OCSP_CERTSTATUS *certStatus;
        +	ASN1_GENERALIZEDTIME *thisUpdate;
        +	ASN1_GENERALIZEDTIME *nextUpdate;
        +	STACK_OF(X509_EXTENSION) *singleExtensions;
        +	} OCSP_SINGLERESP;
        +
        +DECLARE_STACK_OF(OCSP_SINGLERESP)
        +DECLARE_ASN1_SET_OF(OCSP_SINGLERESP)
        +
        +/*   ResponseData ::= SEQUENCE {
        + *      version              [0] EXPLICIT Version DEFAULT v1,
        + *      responderID              ResponderID,
        + *      producedAt               GeneralizedTime,
        + *      responses                SEQUENCE OF SingleResponse,
        + *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
        + */
        +typedef struct ocsp_response_data_st
        +	{
        +	ASN1_INTEGER *version;
        +	OCSP_RESPID  *responderId;
        +	ASN1_GENERALIZEDTIME *producedAt;
        +	STACK_OF(OCSP_SINGLERESP) *responses;
        +	STACK_OF(X509_EXTENSION) *responseExtensions;
        +	} OCSP_RESPDATA;
        +
        +/*   BasicOCSPResponse       ::= SEQUENCE {
        + *      tbsResponseData      ResponseData,
        + *      signatureAlgorithm   AlgorithmIdentifier,
        + *      signature            BIT STRING,
        + *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
        + */
        +  /* Note 1:
        +     The value for "signature" is specified in the OCSP rfc2560 as follows:
        +     "The value for the signature SHALL be computed on the hash of the DER
        +     encoding ResponseData."  This means that you must hash the DER-encoded
        +     tbsResponseData, and then run it through a crypto-signing function, which
        +     will (at least w/RSA) do a hash-'n'-private-encrypt operation.  This seems
        +     a bit odd, but that's the spec.  Also note that the data structures do not
        +     leave anywhere to independently specify the algorithm used for the initial
        +     hash. So, we look at the signature-specification algorithm, and try to do
        +     something intelligent.	-- Kathy Weinhold, CertCo */
        +  /* Note 2:
        +     It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open
        +     for interpretation.  I've done tests against another responder, and found
        +     that it doesn't do the double hashing that the RFC seems to say one
        +     should.  Therefore, all relevant functions take a flag saying which
        +     variant should be used.	-- Richard Levitte, OpenSSL team and CeloCom */
        +typedef struct ocsp_basic_response_st
        +	{
        +	OCSP_RESPDATA *tbsResponseData;
        +	X509_ALGOR *signatureAlgorithm;
        +	ASN1_BIT_STRING *signature;
        +	STACK_OF(X509) *certs;
        +	} OCSP_BASICRESP;
        +
        +/*
        + *   CRLReason ::= ENUMERATED {
        + *        unspecified             (0),
        + *        keyCompromise           (1),
        + *        cACompromise            (2),
        + *        affiliationChanged      (3),
        + *        superseded              (4),
        + *        cessationOfOperation    (5),
        + *        certificateHold         (6),
        + *        removeFromCRL           (8) }
        + */
        +#define OCSP_REVOKED_STATUS_NOSTATUS               -1
        +#define OCSP_REVOKED_STATUS_UNSPECIFIED             0
        +#define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
        +#define OCSP_REVOKED_STATUS_CACOMPROMISE            2
        +#define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
        +#define OCSP_REVOKED_STATUS_SUPERSEDED              4
        +#define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
        +#define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
        +#define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8
        +
        +/* CrlID ::= SEQUENCE {
        + *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
        + *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
        + *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
        + */
        +typedef struct ocsp_crl_id_st
        +        {
        +	ASN1_IA5STRING *crlUrl;
        +	ASN1_INTEGER *crlNum;
        +	ASN1_GENERALIZEDTIME *crlTime;
        +        } OCSP_CRLID;
        +
        +/* ServiceLocator ::= SEQUENCE {
        + *      issuer    Name,
        + *      locator   AuthorityInfoAccessSyntax OPTIONAL }
        + */
        +typedef struct ocsp_service_locator_st
        +        {
        +	X509_NAME* issuer;
        +	STACK_OF(ACCESS_DESCRIPTION) *locator;
        +        } OCSP_SERVICELOC;
        + 
        +#define PEM_STRING_OCSP_REQUEST	"OCSP REQUEST"
        +#define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"
        +
        +#define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)
        +
        +#define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)
        +
        +#define	PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
        +     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)
        +
        +#define	PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
        +     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)
        +
        +#define PEM_write_bio_OCSP_REQUEST(bp,o) \
        +    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
        +			bp,(char *)o, NULL,NULL,0,NULL,NULL)
        +
        +#define PEM_write_bio_OCSP_RESPONSE(bp,o) \
        +    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
        +			bp,(char *)o, NULL,NULL,0,NULL,NULL)
        +
        +#define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)
        +
        +#define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)
        +
        +#define OCSP_REQUEST_sign(o,pkey,md) \
        +	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
        +		o->optionalSignature->signatureAlgorithm,NULL,\
        +	        o->optionalSignature->signature,o->tbsRequest,pkey,md)
        +
        +#define OCSP_BASICRESP_sign(o,pkey,md,d) \
        +	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\
        +		o->signature,o->tbsResponseData,pkey,md)
        +
        +#define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
        +        a->optionalSignature->signatureAlgorithm,\
        +	a->optionalSignature->signature,a->tbsRequest,r)
        +
        +#define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
        +	a->signatureAlgorithm,a->signature,a->tbsResponseData,r)
        +
        +#define ASN1_BIT_STRING_digest(data,type,md,len) \
        +	ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
        +
        +#define OCSP_CERTSTATUS_dup(cs)\
        +                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
        +		(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
        +
        +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
        +
        +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
        +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
        +								int maxline);
        +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
        +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
        +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
        +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
        +		const char *name, const char *value);
        +
        +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
        +
        +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 
        +			      X509_NAME *issuerName, 
        +			      ASN1_BIT_STRING* issuerKey, 
        +			      ASN1_INTEGER *serialNumber);
        +
        +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
        +
        +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
        +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
        +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
        +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);
        +
        +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
        +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
        +
        +int OCSP_request_sign(OCSP_REQUEST   *req,
        +		      X509           *signer,
        +		      EVP_PKEY       *key,
        +		      const EVP_MD   *dgst,
        +		      STACK_OF(X509) *certs,
        +		      unsigned long flags);
        +
        +int OCSP_response_status(OCSP_RESPONSE *resp);
        +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
        +
        +int OCSP_resp_count(OCSP_BASICRESP *bs);
        +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
        +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
        +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
        +				ASN1_GENERALIZEDTIME **revtime,
        +				ASN1_GENERALIZEDTIME **thisupd,
        +				ASN1_GENERALIZEDTIME **nextupd);
        +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
        +				int *reason,
        +				ASN1_GENERALIZEDTIME **revtime,
        +				ASN1_GENERALIZEDTIME **thisupd,
        +				ASN1_GENERALIZEDTIME **nextupd);
        +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
        +			ASN1_GENERALIZEDTIME *nextupd,
        +			long sec, long maxsec);
        +
        +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags);
        +
        +int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl);
        +
        +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
        +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
        +
        +int OCSP_request_onereq_count(OCSP_REQUEST *req);
        +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
        +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
        +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
        +			ASN1_OCTET_STRING **pikeyHash,
        +			ASN1_INTEGER **pserial, OCSP_CERTID *cid);
        +int OCSP_request_is_signed(OCSP_REQUEST *req);
        +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
        +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
        +						OCSP_CERTID *cid,
        +						int status, int reason,
        +						ASN1_TIME *revtime,
        +					ASN1_TIME *thisupd, ASN1_TIME *nextupd);
        +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
        +int OCSP_basic_sign(OCSP_BASICRESP *brsp, 
        +			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
        +			STACK_OF(X509) *certs, unsigned long flags);
        +
        +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
        +
        +X509_EXTENSION *OCSP_accept_responses_new(char **oids);
        +
        +X509_EXTENSION *OCSP_archive_cutoff_new(char* tim);
        +
        +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls);
        +
        +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
        +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
        +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos);
        +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
        +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
        +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
        +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx);
        +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);
        +
        +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
        +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
        +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos);
        +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
        +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
        +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
        +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
        +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);
        +
        +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
        +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
        +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos);
        +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos);
        +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
        +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
        +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx);
        +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);
        +
        +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
        +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
        +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos);
        +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos);
        +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
        +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
        +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx);
        +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);
        +
        +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
        +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
        +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
        +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
        +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
        +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
        +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
        +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
        +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
        +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
        +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
        +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
        +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
        +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
        +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
        +
        +const char *OCSP_response_status_str(long s);
        +const char *OCSP_cert_status_str(long s);
        +const char *OCSP_crl_reason_str(long s);
        +
        +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
        +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
        +
        +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
        +				X509_STORE *st, unsigned long flags);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_OCSP_strings(void);
        +
        +/* Error codes for the OCSP functions. */
        +
        +/* Function codes. */
        +#define OCSP_F_ASN1_STRING_ENCODE			 100
        +#define OCSP_F_D2I_OCSP_NONCE				 102
        +#define OCSP_F_OCSP_BASIC_ADD1_STATUS			 103
        +#define OCSP_F_OCSP_BASIC_SIGN				 104
        +#define OCSP_F_OCSP_BASIC_VERIFY			 105
        +#define OCSP_F_OCSP_CERT_ID_NEW				 101
        +#define OCSP_F_OCSP_CHECK_DELEGATED			 106
        +#define OCSP_F_OCSP_CHECK_IDS				 107
        +#define OCSP_F_OCSP_CHECK_ISSUER			 108
        +#define OCSP_F_OCSP_CHECK_VALIDITY			 115
        +#define OCSP_F_OCSP_MATCH_ISSUERID			 109
        +#define OCSP_F_OCSP_PARSE_URL				 114
        +#define OCSP_F_OCSP_REQUEST_SIGN			 110
        +#define OCSP_F_OCSP_REQUEST_VERIFY			 116
        +#define OCSP_F_OCSP_RESPONSE_GET1_BASIC			 111
        +#define OCSP_F_OCSP_SENDREQ_BIO				 112
        +#define OCSP_F_OCSP_SENDREQ_NBIO			 117
        +#define OCSP_F_PARSE_HTTP_LINE1				 118
        +#define OCSP_F_REQUEST_VERIFY				 113
        +
        +/* Reason codes. */
        +#define OCSP_R_BAD_DATA					 100
        +#define OCSP_R_CERTIFICATE_VERIFY_ERROR			 101
        +#define OCSP_R_DIGEST_ERR				 102
        +#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD		 122
        +#define OCSP_R_ERROR_IN_THISUPDATE_FIELD		 123
        +#define OCSP_R_ERROR_PARSING_URL			 121
        +#define OCSP_R_MISSING_OCSPSIGNING_USAGE		 103
        +#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE		 124
        +#define OCSP_R_NOT_BASIC_RESPONSE			 104
        +#define OCSP_R_NO_CERTIFICATES_IN_CHAIN			 105
        +#define OCSP_R_NO_CONTENT				 106
        +#define OCSP_R_NO_PUBLIC_KEY				 107
        +#define OCSP_R_NO_RESPONSE_DATA				 108
        +#define OCSP_R_NO_REVOKED_TIME				 109
        +#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 110
        +#define OCSP_R_REQUEST_NOT_SIGNED			 128
        +#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA	 111
        +#define OCSP_R_ROOT_CA_NOT_TRUSTED			 112
        +#define OCSP_R_SERVER_READ_ERROR			 113
        +#define OCSP_R_SERVER_RESPONSE_ERROR			 114
        +#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR		 115
        +#define OCSP_R_SERVER_WRITE_ERROR			 116
        +#define OCSP_R_SIGNATURE_FAILURE			 117
        +#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND		 118
        +#define OCSP_R_STATUS_EXPIRED				 125
        +#define OCSP_R_STATUS_NOT_YET_VALID			 126
        +#define OCSP_R_STATUS_TOO_OLD				 127
        +#define OCSP_R_UNKNOWN_MESSAGE_DIGEST			 119
        +#define OCSP_R_UNKNOWN_NID				 120
        +#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE		 129
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_asn.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_asn.c
        new file mode 100644
        index 000000000..bfe892ac7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_asn.c
        @@ -0,0 +1,182 @@
        +/* ocsp_asn.c */
        +/* Written by Dr Stephen N Henson (steve@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 <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/ocsp.h>
        +
        +ASN1_SEQUENCE(OCSP_SIGNATURE) = {
        +	ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING),
        +	ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0)
        +} ASN1_SEQUENCE_END(OCSP_SIGNATURE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE)
        +
        +ASN1_SEQUENCE(OCSP_CERTID) = {
        +	ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(OCSP_CERTID)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID)
        +
        +ASN1_SEQUENCE(OCSP_ONEREQ) = {
        +	ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID),
        +	ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0)
        +} ASN1_SEQUENCE_END(OCSP_ONEREQ)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ)
        +
        +ASN1_SEQUENCE(OCSP_REQINFO) = {
        +	ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0),
        +	ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1),
        +	ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ),
        +	ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2)
        +} ASN1_SEQUENCE_END(OCSP_REQINFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO)
        +
        +ASN1_SEQUENCE(OCSP_REQUEST) = {
        +	ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO),
        +	ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0)
        +} ASN1_SEQUENCE_END(OCSP_REQUEST)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST)
        +
        +/* OCSP_RESPONSE templates */
        +
        +ASN1_SEQUENCE(OCSP_RESPBYTES) = {
        +	    ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT),
        +	    ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(OCSP_RESPBYTES)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES)
        +
        +ASN1_SEQUENCE(OCSP_RESPONSE) = {
        +	ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED),
        +	ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0)
        +} ASN1_SEQUENCE_END(OCSP_RESPONSE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE)
        +
        +ASN1_CHOICE(OCSP_RESPID) = {
        +	   ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1),
        +	   ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2)
        +} ASN1_CHOICE_END(OCSP_RESPID)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID)
        +
        +ASN1_SEQUENCE(OCSP_REVOKEDINFO) = {
        +	ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME),
        +  	ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0)
        +} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
        +
        +ASN1_CHOICE(OCSP_CERTSTATUS) = {
        +	ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0),
        +	ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1),
        +	ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2)
        +} ASN1_CHOICE_END(OCSP_CERTSTATUS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
        +
        +ASN1_SEQUENCE(OCSP_SINGLERESP) = {
        +	   ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID),
        +	   ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS),
        +	   ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME),
        +	   ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0),
        +	   ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1)
        +} ASN1_SEQUENCE_END(OCSP_SINGLERESP)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP)
        +
        +ASN1_SEQUENCE(OCSP_RESPDATA) = {
        +	   ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0),
        +	   ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID),
        +	   ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME),
        +	   ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP),
        +	   ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1)
        +} ASN1_SEQUENCE_END(OCSP_RESPDATA)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA)
        +
        +ASN1_SEQUENCE(OCSP_BASICRESP) = {
        +	   ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA),
        +	   ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR),
        +	   ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING),
        +	   ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0)
        +} ASN1_SEQUENCE_END(OCSP_BASICRESP)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP)
        +
        +ASN1_SEQUENCE(OCSP_CRLID) = {
        +	   ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0),
        +	   ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1),
        +	   ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2)
        +} ASN1_SEQUENCE_END(OCSP_CRLID)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID)
        +
        +ASN1_SEQUENCE(OCSP_SERVICELOC) = {
        +	ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME),
        +	ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION)
        +} ASN1_SEQUENCE_END(OCSP_SERVICELOC)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC)
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_cl.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_cl.c
        new file mode 100644
        index 000000000..9c14d9da2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_cl.c
        @@ -0,0 +1,371 @@
        +/* ocsp_cl.c */
        +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
        + * project. */
        +
        +/* History:
        +   This file was transfered to Richard Levitte from CertCo by Kathy
        +   Weinhold in mid-spring 2000 to be included in OpenSSL or released
        +   as a patch kit. */
        +
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <time.h>
        +#include <cryptlib.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ocsp.h>
        +
        +/* Utility functions related to sending OCSP requests and extracting
        + * relevant information from the response.
        + */
        +
        +/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ 
        + * pointer: useful if we want to add extensions.
        + */
        +
        +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
        +        {
        +	OCSP_ONEREQ *one = NULL;
        +
        +	if (!(one = OCSP_ONEREQ_new())) goto err;
        +	if (one->reqCert) OCSP_CERTID_free(one->reqCert);
        +	one->reqCert = cid;
        +	if (req &&
        +		!sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
        +				goto err;
        +	return one;
        +err:
        +	OCSP_ONEREQ_free(one);
        +	return NULL;
        +        }
        +
        +/* Set requestorName from an X509_NAME structure */
        +
        +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
        +	{
        +	GENERAL_NAME *gen;
        +	gen = GENERAL_NAME_new();
        +	if (gen == NULL)
        +		return 0;
        +	if (!X509_NAME_set(&gen->d.directoryName, nm))
        +		{
        +		GENERAL_NAME_free(gen);
        +		return 0;
        +		}
        +	gen->type = GEN_DIRNAME;
        +	if (req->tbsRequest->requestorName)
        +		GENERAL_NAME_free(req->tbsRequest->requestorName);
        +	req->tbsRequest->requestorName = gen;
        +	return 1;
        +	}
        +	
        +
        +/* Add a certificate to an OCSP request */
        +
        +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
        +	{
        +	OCSP_SIGNATURE *sig;
        +	if (!req->optionalSignature)
        +		req->optionalSignature = OCSP_SIGNATURE_new();
        +	sig = req->optionalSignature;
        +	if (!sig) return 0;
        +	if (!cert) return 1;
        +	if (!sig->certs && !(sig->certs = sk_X509_new_null()))
        +		return 0;
        +
        +	if(!sk_X509_push(sig->certs, cert)) return 0;
        +	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
        +	return 1;
        +	}
        +
        +/* Sign an OCSP request set the requestorName to the subjec
        + * name of an optional signers certificate and include one
        + * or more optional certificates in the request. Behaves
        + * like PKCS7_sign().
        + */
        +
        +int OCSP_request_sign(OCSP_REQUEST   *req,
        +		      X509           *signer,
        +		      EVP_PKEY       *key,
        +		      const EVP_MD   *dgst,
        +		      STACK_OF(X509) *certs,
        +		      unsigned long flags)
        +        {
        +	int i;
        +	OCSP_SIGNATURE *sig;
        +	X509 *x;
        +
        +	if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
        +			goto err;
        +
        +	if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
        +	if (key)
        +		{
        +		if (!X509_check_private_key(signer, key))
        +			{
        +			OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        +			goto err;
        +			}
        +		if (!OCSP_REQUEST_sign(req, key, dgst)) goto err;
        +		}
        +
        +	if (!(flags & OCSP_NOCERTS))
        +		{
        +		if(!OCSP_request_add1_cert(req, signer)) goto err;
        +		for (i = 0; i < sk_X509_num(certs); i++)
        +			{
        +			x = sk_X509_value(certs, i);
        +			if (!OCSP_request_add1_cert(req, x)) goto err;
        +			}
        +		}
        +
        +	return 1;
        +err:
        +	OCSP_SIGNATURE_free(req->optionalSignature);
        +	req->optionalSignature = NULL;
        +	return 0;
        +	}
        +
        +/* Get response status */
        +
        +int OCSP_response_status(OCSP_RESPONSE *resp)
        +	{
        +	return ASN1_ENUMERATED_get(resp->responseStatus);
        +	}
        +
        +/* Extract basic response from OCSP_RESPONSE or NULL if
        + * no basic response present.
        + */
        + 
        +
        +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
        +	{
        +	OCSP_RESPBYTES *rb;
        +	rb = resp->responseBytes;
        +	if (!rb)
        +		{
        +		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
        +		return NULL;
        +		}
        +	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic)
        +		{
        +		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
        +		return NULL;
        +		}
        +
        +	return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
        +	}
        +
        +/* Return number of OCSP_SINGLERESP reponses present in
        + * a basic response.
        + */
        +
        +int OCSP_resp_count(OCSP_BASICRESP *bs)
        +	{
        +	if (!bs) return -1;
        +	return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
        +	}
        +
        +/* Extract an OCSP_SINGLERESP response with a given index */
        +
        +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
        +	{
        +	if (!bs) return NULL;
        +	return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
        +	}
        +
        +/* Look single response matching a given certificate ID */
        +
        +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
        +	{
        +	int i;
        +	STACK_OF(OCSP_SINGLERESP) *sresp;
        +	OCSP_SINGLERESP *single;
        +	if (!bs) return -1;
        +	if (last < 0) last = 0;
        +	else last++;
        +	sresp = bs->tbsResponseData->responses;
        +	for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++)
        +		{
        +		single = sk_OCSP_SINGLERESP_value(sresp, i);
        +		if (!OCSP_id_cmp(id, single->certId)) return i;
        +		}
        +	return -1;
        +	}
        +
        +/* Extract status information from an OCSP_SINGLERESP structure.
        + * Note: the revtime and reason values are only set if the 
        + * certificate status is revoked. Returns numerical value of
        + * status.
        + */
        +
        +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
        +				ASN1_GENERALIZEDTIME **revtime,
        +				ASN1_GENERALIZEDTIME **thisupd,
        +				ASN1_GENERALIZEDTIME **nextupd)
        +	{
        +	int ret;
        +	OCSP_CERTSTATUS *cst;
        +	if(!single) return -1;
        +	cst = single->certStatus;
        +	ret = cst->type;
        +	if (ret == V_OCSP_CERTSTATUS_REVOKED)
        +		{
        +		OCSP_REVOKEDINFO *rev = cst->value.revoked;
        +		if (revtime) *revtime = rev->revocationTime;
        +		if (reason) 
        +			{
        +			if(rev->revocationReason)
        +				*reason = ASN1_ENUMERATED_get(rev->revocationReason);
        +			else *reason = -1;
        +			}
        +		}
        +	if(thisupd) *thisupd = single->thisUpdate;
        +	if(nextupd) *nextupd = single->nextUpdate;
        +	return ret;
        +	}
        +
        +/* This function combines the previous ones: look up a certificate ID and
        + * if found extract status information. Return 0 is successful.
        + */
        +
        +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
        +				int *reason,
        +				ASN1_GENERALIZEDTIME **revtime,
        +				ASN1_GENERALIZEDTIME **thisupd,
        +				ASN1_GENERALIZEDTIME **nextupd)
        +	{
        +	int i;
        +	OCSP_SINGLERESP *single;
        +	i = OCSP_resp_find(bs, id, -1);
        +	/* Maybe check for multiple responses and give an error? */
        +	if(i < 0) return 0;
        +	single = OCSP_resp_get0(bs, i);
        +	i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
        +	if(status) *status = i;
        +	return 1;
        +	}
        +
        +/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will
        + * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid
        + * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time.
        + * Also to avoid accepting very old responses without a nextUpdate field an optional maxage
        + * parameter specifies the maximum age the thisUpdate field can be.
        + */
        +
        +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
        +	{
        +	int ret = 1;
        +	time_t t_now, t_tmp;
        +	time(&t_now);
        +	/* Check thisUpdate is valid and not more than nsec in the future */
        +	if (!ASN1_GENERALIZEDTIME_check(thisupd))
        +		{
        +		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
        +		ret = 0;
        +		}
        +	else 
        +		{
        +			t_tmp = t_now + nsec;
        +			if (X509_cmp_time(thisupd, &t_tmp) > 0)
        +			{
        +			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
        +			ret = 0;
        +			}
        +
        +		/* If maxsec specified check thisUpdate is not more than maxsec in the past */
        +		if (maxsec >= 0)
        +			{
        +			t_tmp = t_now - maxsec;
        +			if (X509_cmp_time(thisupd, &t_tmp) < 0)
        +				{
        +				OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
        +				ret = 0;
        +				}
        +			}
        +		}
        +		
        +
        +	if (!nextupd) return ret;
        +
        +	/* Check nextUpdate is valid and not more than nsec in the past */
        +	if (!ASN1_GENERALIZEDTIME_check(nextupd))
        +		{
        +		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
        +		ret = 0;
        +		}
        +	else 
        +		{
        +		t_tmp = t_now - nsec;
        +		if (X509_cmp_time(nextupd, &t_tmp) < 0)
        +			{
        +			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
        +			ret = 0;
        +			}
        +		}
        +
        +	/* Also don't allow nextUpdate to precede thisUpdate */
        +	if (ASN1_STRING_cmp(nextupd, thisupd) < 0)
        +		{
        +		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
        +		ret = 0;
        +		}
        +
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_err.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_err.c
        new file mode 100644
        index 000000000..0cedcea68
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_err.c
        @@ -0,0 +1,142 @@
        +/* crypto/ocsp/ocsp_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ocsp.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason)
        +
        +static ERR_STRING_DATA OCSP_str_functs[]=
        +	{
        +{ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE),	"ASN1_STRING_encode"},
        +{ERR_FUNC(OCSP_F_D2I_OCSP_NONCE),	"D2I_OCSP_NONCE"},
        +{ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS),	"OCSP_basic_add1_status"},
        +{ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN),	"OCSP_basic_sign"},
        +{ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY),	"OCSP_basic_verify"},
        +{ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW),	"OCSP_cert_id_new"},
        +{ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED),	"OCSP_CHECK_DELEGATED"},
        +{ERR_FUNC(OCSP_F_OCSP_CHECK_IDS),	"OCSP_CHECK_IDS"},
        +{ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER),	"OCSP_CHECK_ISSUER"},
        +{ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY),	"OCSP_check_validity"},
        +{ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID),	"OCSP_MATCH_ISSUERID"},
        +{ERR_FUNC(OCSP_F_OCSP_PARSE_URL),	"OCSP_parse_url"},
        +{ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN),	"OCSP_request_sign"},
        +{ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY),	"OCSP_request_verify"},
        +{ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC),	"OCSP_response_get1_basic"},
        +{ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO),	"OCSP_sendreq_bio"},
        +{ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO),	"OCSP_sendreq_nbio"},
        +{ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1),	"PARSE_HTTP_LINE1"},
        +{ERR_FUNC(OCSP_F_REQUEST_VERIFY),	"REQUEST_VERIFY"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA OCSP_str_reasons[]=
        +	{
        +{ERR_REASON(OCSP_R_BAD_DATA)             ,"bad data"},
        +{ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
        +{ERR_REASON(OCSP_R_DIGEST_ERR)           ,"digest err"},
        +{ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD),"error in nextupdate field"},
        +{ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD),"error in thisupdate field"},
        +{ERR_REASON(OCSP_R_ERROR_PARSING_URL)    ,"error parsing url"},
        +{ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE),"missing ocspsigning usage"},
        +{ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE),"nextupdate before thisupdate"},
        +{ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE)   ,"not basic response"},
        +{ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN),"no certificates in chain"},
        +{ERR_REASON(OCSP_R_NO_CONTENT)           ,"no content"},
        +{ERR_REASON(OCSP_R_NO_PUBLIC_KEY)        ,"no public key"},
        +{ERR_REASON(OCSP_R_NO_RESPONSE_DATA)     ,"no response data"},
        +{ERR_REASON(OCSP_R_NO_REVOKED_TIME)      ,"no revoked time"},
        +{ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
        +{ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED)   ,"request not signed"},
        +{ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA),"response contains no revocation data"},
        +{ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED)  ,"root ca not trusted"},
        +{ERR_REASON(OCSP_R_SERVER_READ_ERROR)    ,"server read error"},
        +{ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR),"server response error"},
        +{ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR),"server response parse error"},
        +{ERR_REASON(OCSP_R_SERVER_WRITE_ERROR)   ,"server write error"},
        +{ERR_REASON(OCSP_R_SIGNATURE_FAILURE)    ,"signature failure"},
        +{ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
        +{ERR_REASON(OCSP_R_STATUS_EXPIRED)       ,"status expired"},
        +{ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID) ,"status not yet valid"},
        +{ERR_REASON(OCSP_R_STATUS_TOO_OLD)       ,"status too old"},
        +{ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST),"unknown message digest"},
        +{ERR_REASON(OCSP_R_UNKNOWN_NID)          ,"unknown nid"},
        +{ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE),"unsupported requestorname type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_OCSP_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,OCSP_str_functs);
        +		ERR_load_strings(0,OCSP_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_ext.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_ext.c
        new file mode 100644
        index 000000000..ec884cb08
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_ext.c
        @@ -0,0 +1,518 @@
        +/* ocsp_ext.c */
        +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
        + * project. */
        +
        +/* History:
        +   This file was transfered to Richard Levitte from CertCo by Kathy
        +   Weinhold in mid-spring 2000 to be included in OpenSSL or released
        +   as a patch kit. */
        +
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <cryptlib.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509v3.h>
        +
        +/* Standard wrapper functions for extensions */
        +
        +/* OCSP request extensions */
        +
        +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
        +	{
        +	return(X509v3_get_ext_count(x->tbsRequest->requestExtensions));
        +	}
        +
        +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos));
        +	}
        +
        +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos));
        +	}
        +
        +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc));
        +	}
        +
        +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc));
        +	}
        +
        +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
        +	{
        +	return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
        +	}
        +
        +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +	{
        +	return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags);
        +	}
        +
        +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL);
        +	}
        +
        +/* Single extensions */
        +
        +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
        +	{
        +	return(X509v3_get_ext_count(x->singleRequestExtensions));
        +	}
        +
        +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos));
        +	}
        +
        +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos));
        +	}
        +
        +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->singleRequestExtensions,loc));
        +	}
        +
        +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->singleRequestExtensions,loc));
        +	}
        +
        +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
        +	{
        +	return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
        +	}
        +
        +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +	{
        +	return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags);
        +	}
        +
        +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL);
        +	}
        +
        +/* OCSP Basic response */
        +
        +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
        +	{
        +	return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions));
        +	}
        +
        +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos));
        +	}
        +
        +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos));
        +	}
        +
        +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc));
        +	}
        +
        +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc));
        +	}
        +
        +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx)
        +	{
        +	return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx);
        +	}
        +
        +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +	{
        +	return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags);
        +	}
        +
        +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL);
        +	}
        +
        +/* OCSP single response extensions */
        +
        +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
        +	{
        +	return(X509v3_get_ext_count(x->singleExtensions));
        +	}
        +
        +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos));
        +	}
        +
        +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos));
        +	}
        +
        +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->singleExtensions,loc));
        +	}
        +
        +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->singleExtensions,loc));
        +	}
        +
        +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx)
        +	{
        +	return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
        +	}
        +
        +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +	{
        +	return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
        +	}
        +
        +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL);
        +	}
        +
        +/* also CRL Entry Extensions */
        +#if 0
        +ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
        +				void *data, STACK_OF(ASN1_OBJECT) *sk)
        +        {
        +	int i;
        +	unsigned char *p, *b = NULL;
        +
        +	if (data)
        +	        {
        +		if ((i=i2d(data,NULL)) <= 0) goto err;
        +		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
        +			goto err;
        +	        if (i2d(data, &p) <= 0) goto err;
        +		}
        +	else if (sk)
        +	        {
        +		if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL,
        +						   (I2D_OF(ASN1_OBJECT))i2d,
        +						   V_ASN1_SEQUENCE,
        +						   V_ASN1_UNIVERSAL,
        +						   IS_SEQUENCE))<=0) goto err;
        +		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
        +			goto err;
        +		if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,(I2D_OF(ASN1_OBJECT))i2d,
        +						V_ASN1_SEQUENCE,
        +						V_ASN1_UNIVERSAL,
        +						IS_SEQUENCE)<=0) goto err;
        +		}
        +	else
        +		{
        +		OCSPerr(OCSP_F_ASN1_STRING_ENCODE,OCSP_R_BAD_DATA);
        +		goto err;
        +		}
        +	if (!s && !(s = ASN1_STRING_new())) goto err;
        +	if (!(ASN1_STRING_set(s, b, i))) goto err;
        +	OPENSSL_free(b);
        +	return s;
        +err:
        +	if (b) OPENSSL_free(b);
        +	return NULL;
        +	}
        +#endif
        +
        +/* Nonce handling functions */
        +
        +/* Add a nonce to an extension stack. A nonce can be specificed or if NULL
        + * a random nonce will be generated.
        + * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the 
        + * nonce, previous versions used the raw nonce.
        + */
        +
        +static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len)
        +	{
        +	unsigned char *tmpval;
        +	ASN1_OCTET_STRING os;
        +	int ret = 0;
        +	if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH;
        +	/* Create the OCTET STRING manually by writing out the header and
        +	 * appending the content octets. This avoids an extra memory allocation
        +	 * operation in some cases. Applications should *NOT* do this because
        +         * it relies on library internals.
        +	 */
        +	os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
        +	os.data = OPENSSL_malloc(os.length);
        +	if (os.data == NULL)
        +		goto err;
        +	tmpval = os.data;
        +	ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
        +	if (val)
        +		memcpy(tmpval, val, len);
        +	else
        +		RAND_pseudo_bytes(tmpval, len);
        +	if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
        +			&os, 0, X509V3_ADD_REPLACE))
        +				goto err;
        +	ret = 1;
        +	err:
        +	if (os.data)
        +		OPENSSL_free(os.data);
        +	return ret;
        +	}
        +
        +
        +/* Add nonce to an OCSP request */
        +
        +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
        +	{
        +	return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
        +	}
        +
        +/* Same as above but for a response */
        +
        +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
        +	{
        +	return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len);
        +	}
        +
        +/* Check nonce validity in a request and response.
        + * Return value reflects result:
        + *  1: nonces present and equal.
        + *  2: nonces both absent.
        + *  3: nonce present in response only.
        + *  0: nonces both present and not equal.
        + * -1: nonce in request only.
        + *
        + *  For most responders clients can check return > 0.
        + *  If responder doesn't handle nonces return != 0 may be
        + *  necessary. return == 0 is always an error.
        + */
        +
        +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
        +	{
        +	/*
        +	 * Since we are only interested in the presence or absence of
        +	 * the nonce and comparing its value there is no need to use
        +	 * the X509V3 routines: this way we can avoid them allocating an
        +	 * ASN1_OCTET_STRING structure for the value which would be
        +	 * freed immediately anyway.
        +	 */
        +
        +	int req_idx, resp_idx;
        +	X509_EXTENSION *req_ext, *resp_ext;
        +	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
        +	resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
        +	/* Check both absent */
        +	if((req_idx < 0) && (resp_idx < 0))
        +		return 2;
        +	/* Check in request only */
        +	if((req_idx >= 0) && (resp_idx < 0))
        +		return -1;
        +	/* Check in response but not request */
        +	if((req_idx < 0) && (resp_idx >= 0))
        +		return 3;
        +	/* Otherwise nonce in request and response so retrieve the extensions */
        +	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
        +	resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
        +	if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
        +		return 0;
        +	return 1;
        +	}
        +
        +/* Copy the nonce value (if any) from an OCSP request to 
        + * a response.
        + */
        +
        +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
        +	{
        +	X509_EXTENSION *req_ext;
        +	int req_idx;
        +	/* Check for nonce in request */
        +	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
        +	/* If no nonce that's OK */
        +	if (req_idx < 0) return 2;
        +	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
        +	return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
        +	}
        +
        +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
        +        {
        +	X509_EXTENSION *x = NULL;
        +	OCSP_CRLID *cid = NULL;
        +	
        +	if (!(cid = OCSP_CRLID_new())) goto err;
        +	if (url)
        +	        {
        +		if (!(cid->crlUrl = ASN1_IA5STRING_new())) goto err;
        +		if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) goto err;
        +		}
        +	if (n)
        +	        {
        +		if (!(cid->crlNum = ASN1_INTEGER_new())) goto err;
        +		if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err;
        +		}
        +	if (tim)
        +	        {
        +		if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err;
        +		if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 
        +		        goto err;
        +		}
        +	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
        +err:
        +	if (cid) OCSP_CRLID_free(cid);
        +	return x;
        +	}
        +
        +/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
        +X509_EXTENSION *OCSP_accept_responses_new(char **oids)
        +        {
        +	int nid;
        +	STACK_OF(ASN1_OBJECT) *sk = NULL;
        +	ASN1_OBJECT *o = NULL;
        +        X509_EXTENSION *x = NULL;
        +
        +	if (!(sk = sk_ASN1_OBJECT_new_null())) goto err;
        +	while (oids && *oids)
        +	        {
        +		if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) 
        +		        sk_ASN1_OBJECT_push(sk, o);
        +		oids++;
        +		}
        +	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
        +err:
        +	if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
        +	return x;
        +        }
        +
        +/*  ArchiveCutoff ::= GeneralizedTime */
        +X509_EXTENSION *OCSP_archive_cutoff_new(char* tim)
        +        {
        +	X509_EXTENSION *x=NULL;
        +	ASN1_GENERALIZEDTIME *gt = NULL;
        +
        +	if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err;
        +	if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err;
        +	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
        +err:
        +	if (gt) ASN1_GENERALIZEDTIME_free(gt);
        +	return x;
        +	}
        +
        +/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
        + * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This
        + * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
        + */
        +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls)
        +        {
        +	X509_EXTENSION *x = NULL;
        +	ASN1_IA5STRING *ia5 = NULL;
        +	OCSP_SERVICELOC *sloc = NULL;
        +	ACCESS_DESCRIPTION *ad = NULL;
        +	
        +	if (!(sloc = OCSP_SERVICELOC_new())) goto err;
        +	if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err;
        +	if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err;
        +	while (urls && *urls)
        +	        {
        +		if (!(ad = ACCESS_DESCRIPTION_new())) goto err;
        +		if (!(ad->method=OBJ_nid2obj(NID_ad_OCSP))) goto err;
        +		if (!(ad->location = GENERAL_NAME_new())) goto err;
        +	        if (!(ia5 = ASN1_IA5STRING_new())) goto err;
        +		if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) goto err;
        +		ad->location->type = GEN_URI;
        +		ad->location->d.ia5 = ia5;
        +		if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err;
        +		urls++;
        +		}
        +	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
        +err:
        +	if (sloc) OCSP_SERVICELOC_free(sloc);
        +	return x;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_ht.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_ht.c
        new file mode 100644
        index 000000000..af5fc1669
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_ht.c
        @@ -0,0 +1,504 @@
        +/* ocsp_ht.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include <stdlib.h>
        +#include <ctype.h>
        +#include <string.h>
        +#include "e_os.h"
        +#include <openssl/asn1.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/err.h>
        +#include <openssl/buffer.h>
        +#ifdef OPENSSL_SYS_SUNOS
        +#define strtoul (unsigned long)strtol
        +#endif /* OPENSSL_SYS_SUNOS */
        +
        +/* Stateful OCSP request code, supporting non-blocking I/O */
        +
        +/* Opaque OCSP request status structure */
        +
        +struct ocsp_req_ctx_st {
        +	int state;		/* Current I/O state */
        +	unsigned char *iobuf;	/* Line buffer */
        +	int iobuflen;		/* Line buffer length */
        +	BIO *io;		/* BIO to perform I/O with */
        +	BIO *mem;		/* Memory BIO response is built into */
        +	unsigned long asn1_len;	/* ASN1 length of response */
        +	};
        +
        +#define OCSP_MAX_REQUEST_LENGTH	(100 * 1024)
        +#define OCSP_MAX_LINE_LEN	4096;
        +
        +/* OCSP states */
        +
        +/* If set no reading should be performed */
        +#define OHS_NOREAD		0x1000
        +/* Error condition */
        +#define OHS_ERROR		(0 | OHS_NOREAD)
        +/* First line being read */
        +#define OHS_FIRSTLINE		1
        +/* MIME headers being read */
        +#define OHS_HEADERS		2
        +/* OCSP initial header (tag + length) being read */
        +#define OHS_ASN1_HEADER		3
        +/* OCSP content octets being read */
        +#define OHS_ASN1_CONTENT	4
        +/* Request being sent */
        +#define OHS_ASN1_WRITE		(6 | OHS_NOREAD)
        +/* Request being flushed */
        +#define OHS_ASN1_FLUSH		(7 | OHS_NOREAD)
        +/* Completed */
        +#define OHS_DONE		(8 | OHS_NOREAD)
        +
        +
        +static int parse_http_line1(char *line);
        +
        +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
        +	{
        +	if (rctx->mem)
        +		BIO_free(rctx->mem);
        +	if (rctx->iobuf)
        +		OPENSSL_free(rctx->iobuf);
        +	OPENSSL_free(rctx);
        +	}
        +
        +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
        +	{
        +	static const char req_hdr[] =
        +	"Content-Type: application/ocsp-request\r\n"
        +	"Content-Length: %d\r\n\r\n";
        +        if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0)
        +		return 0;
        +        if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
        +		return 0;
        +	rctx->state = OHS_ASN1_WRITE;
        +	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
        +	return 1;
        +	}
        +
        +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
        +		const char *name, const char *value)
        +	{
        +	if (!name)
        +		return 0;
        +	if (BIO_puts(rctx->mem, name) <= 0)
        +		return 0;
        +	if (value)
        +		{
        +		if (BIO_write(rctx->mem, ": ", 2) != 2)
        +			return 0;
        +		if (BIO_puts(rctx->mem, value) <= 0)
        +			return 0;
        +		}
        +	if (BIO_write(rctx->mem, "\r\n", 2) != 2)
        +		return 0;
        +	return 1;
        +	}
        +
        +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
        +								int maxline)
        +	{
        +	static const char post_hdr[] = "POST %s HTTP/1.0\r\n";
        +
        +	OCSP_REQ_CTX *rctx;
        +	rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
        +	rctx->state = OHS_ERROR;
        +	rctx->mem = BIO_new(BIO_s_mem());
        +	rctx->io = io;
        +	rctx->asn1_len = 0;
        +	if (maxline > 0)
        +		rctx->iobuflen = maxline;
        +	else
        +		rctx->iobuflen = OCSP_MAX_LINE_LEN;
        +	rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
        +	if (!rctx->iobuf)
        +		return 0;
        +	if (!path)
        +		path = "/";
        +
        +        if (BIO_printf(rctx->mem, post_hdr, path) <= 0)
        +		return 0;
        +
        +	if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
        +		return 0;
        +
        +	return rctx;
        +	}
        +
        +/* Parse the HTTP response. This will look like this:
        + * "HTTP/1.0 200 OK". We need to obtain the numeric code and
        + * (optional) informational message.
        + */
        +
        +static int parse_http_line1(char *line)
        +	{
        +	int retcode;
        +	char *p, *q, *r;
        +	/* Skip to first white space (passed protocol info) */
        +
        +	for(p = line; *p && !isspace((unsigned char)*p); p++)
        +		continue;
        +	if(!*p)
        +		{
        +		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
        +					OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
        +		return 0;
        +		}
        +
        +	/* Skip past white space to start of response code */
        +	while(*p && isspace((unsigned char)*p))
        +		p++;
        +
        +	if(!*p)
        +		{
        +		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
        +					OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
        +		return 0;
        +		}
        +
        +	/* Find end of response code: first whitespace after start of code */
        +	for(q = p; *q && !isspace((unsigned char)*q); q++)
        +		continue;
        +
        +	if(!*q)
        +		{
        +		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
        +					OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
        +		return 0;
        +		}
        +
        +	/* Set end of response code and start of message */ 
        +	*q++ = 0;
        +
        +	/* Attempt to parse numeric code */
        +	retcode = strtoul(p, &r, 10);
        +
        +	if(*r)
        +		return 0;
        +
        +	/* Skip over any leading white space in message */
        +	while(*q && isspace((unsigned char)*q))
        +		q++;
        +
        +	if(*q)
        +		{
        +		/* Finally zap any trailing white space in message (include
        +		 * CRLF) */
        +
        +		/* We know q has a non white space character so this is OK */
        +		for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
        +			*r = 0;
        +		}
        +	if(retcode != 200)
        +		{
        +		OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
        +		if(!*q)
        +			ERR_add_error_data(2, "Code=", p);
        +		else
        +			ERR_add_error_data(4, "Code=", p, ",Reason=", q);
        +		return 0;
        +		}
        +
        +
        +	return 1;
        +
        +	}
        +
        +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
        +	{
        +	int i, n;
        +	const unsigned char *p;
        +	next_io:
        +	if (!(rctx->state & OHS_NOREAD))
        +		{
        +		n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
        +
        +		if (n <= 0)
        +			{
        +			if (BIO_should_retry(rctx->io))
        +				return -1;
        +			return 0;
        +			}
        +
        +		/* Write data to memory BIO */
        +
        +		if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
        +			return 0;
        +		}
        +
        +	switch(rctx->state)
        +		{
        +
        +		case OHS_ASN1_WRITE:
        +		n = BIO_get_mem_data(rctx->mem, &p);
        +
        +		i = BIO_write(rctx->io,
        +			p + (n - rctx->asn1_len), rctx->asn1_len);
        +
        +		if (i <= 0)
        +			{
        +			if (BIO_should_retry(rctx->io))
        +				return -1;
        +			rctx->state = OHS_ERROR;
        +			return 0;
        +			}
        +
        +		rctx->asn1_len -= i;
        +
        +		if (rctx->asn1_len > 0)
        +			goto next_io;
        +
        +		rctx->state = OHS_ASN1_FLUSH;
        +
        +		(void)BIO_reset(rctx->mem);
        +
        +		case OHS_ASN1_FLUSH:
        +
        +		i = BIO_flush(rctx->io);
        +
        +		if (i > 0)
        +			{
        +			rctx->state = OHS_FIRSTLINE;
        +			goto next_io;
        +			}
        +
        +		if (BIO_should_retry(rctx->io))
        +			return -1;
        +
        +		rctx->state = OHS_ERROR;
        +		return 0;
        +
        +		case OHS_ERROR:
        +		return 0;
        +
        +		case OHS_FIRSTLINE:
        +		case OHS_HEADERS:
        +
        +		/* Attempt to read a line in */
        +
        +		next_line:
        +		/* Due to &%^*$" memory BIO behaviour with BIO_gets we
        +		 * have to check there's a complete line in there before
        +		 * calling BIO_gets or we'll just get a partial read.
        +		 */
        +		n = BIO_get_mem_data(rctx->mem, &p);
        +		if ((n <= 0) || !memchr(p, '\n', n))
        +			{
        +			if (n >= rctx->iobuflen)
        +				{
        +				rctx->state = OHS_ERROR;
        +				return 0;
        +				}
        +			goto next_io;
        +			}
        +		n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
        +
        +		if (n <= 0)
        +			{
        +			if (BIO_should_retry(rctx->mem))
        +				goto next_io;
        +			rctx->state = OHS_ERROR;
        +			return 0;
        +			}
        +
        +		/* Don't allow excessive lines */
        +		if (n == rctx->iobuflen)
        +			{
        +			rctx->state = OHS_ERROR;
        +			return 0;
        +			}
        +
        +		/* First line */
        +		if (rctx->state == OHS_FIRSTLINE)
        +			{
        +			if (parse_http_line1((char *)rctx->iobuf))
        +				{
        +				rctx->state = OHS_HEADERS;
        +				goto next_line;
        +				}
        +			else
        +				{
        +				rctx->state = OHS_ERROR;
        +				return 0;
        +				}
        +			}
        +		else
        +			{
        +			/* Look for blank line: end of headers */
        +			for (p = rctx->iobuf; *p; p++)
        +				{
        +				if ((*p != '\r') && (*p != '\n'))
        +					break;
        +				}
        +			if (*p)
        +				goto next_line;
        +
        +			rctx->state = OHS_ASN1_HEADER;
        +
        +			}
        + 
        +		/* Fall thru */
        +
        +
        +		case OHS_ASN1_HEADER:
        +		/* Now reading ASN1 header: can read at least 2 bytes which
        +		 * is enough for ASN1 SEQUENCE header and either length field
        +		 * or at least the length of the length field.
        +		 */
        +		n = BIO_get_mem_data(rctx->mem, &p);
        +		if (n < 2)
        +			goto next_io;
        +
        +		/* Check it is an ASN1 SEQUENCE */
        +		if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
        +			{
        +			rctx->state = OHS_ERROR;
        +			return 0;
        +			}
        +
        +		/* Check out length field */
        +		if (*p & 0x80)
        +			{
        +			/* If MSB set on initial length octet we can now
        +			 * always read 6 octets: make sure we have them.
        +			 */
        +			if (n < 6)
        +				goto next_io;
        +			n = *p & 0x7F;
        +			/* Not NDEF or excessive length */
        +			if (!n || (n > 4))
        +				{
        +				rctx->state = OHS_ERROR;
        +				return 0;
        +				}
        +			p++;
        +			rctx->asn1_len = 0;
        +			for (i = 0; i < n; i++)
        +				{
        +				rctx->asn1_len <<= 8;
        +				rctx->asn1_len |= *p++;
        +				}
        +
        +			if (rctx->asn1_len > OCSP_MAX_REQUEST_LENGTH)
        +				{
        +				rctx->state = OHS_ERROR;
        +				return 0;
        +				}
        +
        +			rctx->asn1_len += n + 2;
        +			}
        +		else
        +			rctx->asn1_len = *p + 2;
        +
        +		rctx->state = OHS_ASN1_CONTENT;
        +
        +		/* Fall thru */
        +		
        +		case OHS_ASN1_CONTENT:
        +		n = BIO_get_mem_data(rctx->mem, &p);
        +		if (n < (int)rctx->asn1_len)
        +			goto next_io;
        +
        +
        +		*presp = d2i_OCSP_RESPONSE(NULL, &p, rctx->asn1_len);
        +		if (*presp)
        +			{
        +			rctx->state = OHS_DONE;
        +			return 1;
        +			}
        +
        +		rctx->state = OHS_ERROR;
        +		return 0;
        +
        +		break;
        +
        +		case OHS_DONE:
        +		return 1;
        +
        +		}
        +
        +
        +
        +	return 0;
        +
        +
        +	}
        +
        +/* Blocking OCSP request handler: now a special case of non-blocking I/O */
        +
        +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req)
        +	{
        +	OCSP_RESPONSE *resp = NULL;
        +	OCSP_REQ_CTX *ctx;
        +	int rv;
        +
        +	ctx = OCSP_sendreq_new(b, path, req, -1);
        +
        +	do
        +		{
        +		rv = OCSP_sendreq_nbio(&resp, ctx);
        +		} while ((rv == -1) && BIO_should_retry(b));
        +
        +	OCSP_REQ_CTX_free(ctx);
        +
        +	if (rv)
        +		return resp;
        +
        +	return NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_lib.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_lib.c
        new file mode 100644
        index 000000000..a94dc838e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_lib.c
        @@ -0,0 +1,266 @@
        +/* ocsp_lib.c */
        +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
        + * project. */
        +
        +/* History:
        +   This file was transfered to Richard Levitte from CertCo by Kathy
        +   Weinhold in mid-spring 2000 to be included in OpenSSL or released
        +   as a patch kit. */
        +
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <cryptlib.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/asn1t.h>
        +
        +/* Convert a certificate and its issuer to an OCSP_CERTID */
        +
        +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
        +{
        +	X509_NAME *iname;
        +	ASN1_INTEGER *serial;
        +	ASN1_BIT_STRING *ikey;
        +#ifndef OPENSSL_NO_SHA1
        +	if(!dgst) dgst = EVP_sha1();
        +#endif
        +	if (subject)
        +		{
        +		iname = X509_get_issuer_name(subject);
        +		serial = X509_get_serialNumber(subject);
        +		}
        +	else
        +		{
        +		iname = X509_get_subject_name(issuer);
        +		serial = NULL;
        +		}
        +	ikey = X509_get0_pubkey_bitstr(issuer);
        +	return OCSP_cert_id_new(dgst, iname, ikey, serial);
        +}
        +
        +
        +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 
        +			      X509_NAME *issuerName, 
        +			      ASN1_BIT_STRING* issuerKey, 
        +			      ASN1_INTEGER *serialNumber)
        +        {
        +	int nid;
        +        unsigned int i;
        +	X509_ALGOR *alg;
        +	OCSP_CERTID *cid = NULL;
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +
        +	if (!(cid = OCSP_CERTID_new())) goto err;
        +
        +	alg = cid->hashAlgorithm;
        +	if (alg->algorithm != NULL) ASN1_OBJECT_free(alg->algorithm);
        +	if ((nid = EVP_MD_type(dgst)) == NID_undef)
        +	        {
        +		OCSPerr(OCSP_F_OCSP_CERT_ID_NEW,OCSP_R_UNKNOWN_NID);
        +		goto err;
        +		}
        +	if (!(alg->algorithm=OBJ_nid2obj(nid))) goto err;
        +	if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err;
        +	alg->parameter->type=V_ASN1_NULL;
        +
        +	if (!X509_NAME_digest(issuerName, dgst, md, &i)) goto digerr;
        +	if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err;
        +
        +	/* Calculate the issuerKey hash, excluding tag and length */
        +	if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
        +		goto err;
        +
        +	if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err;
        +
        +	if (serialNumber)
        +		{
        +		ASN1_INTEGER_free(cid->serialNumber);
        +		if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) goto err;
        +		}
        +	return cid;
        +digerr:
        +	OCSPerr(OCSP_F_OCSP_CERT_ID_NEW,OCSP_R_DIGEST_ERR);
        +err:
        +	if (cid) OCSP_CERTID_free(cid);
        +	return NULL;
        +	}
        +
        +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
        +	{
        +	int ret;
        +	ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
        +	if (ret) return ret;
        +	ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
        +	if (ret) return ret;
        +	return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
        +	}
        +
        +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
        +	{
        +	int ret;
        +	ret = OCSP_id_issuer_cmp(a, b);
        +	if (ret) return ret;
        +	return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
        +	}
        +
        +
        +/* Parse a URL and split it up into host, port and path components and whether
        + * it is SSL.
        + */
        +
        +int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl)
        +	{
        +	char *p, *buf;
        +
        +	char *host, *port;
        +
        +	*phost = NULL;
        +	*pport = NULL;
        +	*ppath = NULL;
        +
        +	/* dup the buffer since we are going to mess with it */
        +	buf = BUF_strdup(url);
        +	if (!buf) goto mem_err;
        +
        +	/* Check for initial colon */
        +	p = strchr(buf, ':');
        +
        +	if (!p) goto parse_err;
        +
        +	*(p++) = '\0';
        +
        +	if (!strcmp(buf, "http"))
        +		{
        +		*pssl = 0;
        +		port = "80";
        +		}
        +	else if (!strcmp(buf, "https"))
        +		{
        +		*pssl = 1;
        +		port = "443";
        +		}
        +	else
        +		goto parse_err;
        +
        +	/* Check for double slash */
        +	if ((p[0] != '/') || (p[1] != '/'))
        +		goto parse_err;
        +
        +	p += 2;
        +
        +	host = p;
        +
        +	/* Check for trailing part of path */
        +
        +	p = strchr(p, '/');
        +
        +	if (!p) 
        +		*ppath = BUF_strdup("/");
        +	else
        +		{
        +		*ppath = BUF_strdup(p);
        +		/* Set start of path to 0 so hostname is valid */
        +		*p = '\0';
        +		}
        +
        +	if (!*ppath) goto mem_err;
        +
        +	/* Look for optional ':' for port number */
        +	if ((p = strchr(host, ':')))
        +		{
        +		*p = 0;
        +		port = p + 1;
        +		}
        +	else
        +		{
        +		/* Not found: set default port */
        +		if (*pssl) port = "443";
        +		else port = "80";
        +		}
        +
        +	*pport = BUF_strdup(port);
        +	if (!*pport) goto mem_err;
        +
        +	*phost = BUF_strdup(host);
        +
        +	if (!*phost) goto mem_err;
        +
        +	OPENSSL_free(buf);
        +
        +	return 1;
        +
        +	mem_err:
        +	OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +
        +	parse_err:
        +	OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
        +
        +
        +	err:
        +	if (buf) OPENSSL_free(buf);
        +	if (*ppath) OPENSSL_free(*ppath);
        +	if (*pport) OPENSSL_free(*pport);
        +	if (*phost) OPENSSL_free(*phost);
        +	return 0;
        +
        +	}
        +
        +IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_prn.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_prn.c
        new file mode 100644
        index 000000000..87608ff39
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_prn.c
        @@ -0,0 +1,290 @@
        +/* ocsp_prn.c */
        +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
        + * project. */
        +
        +/* History:
        +   This file was originally part of ocsp.c and was transfered to Richard
        +   Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included
        +   in OpenSSL or released as a patch kit. */
        +
        +/* ====================================================================
        + * 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 <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/pem.h>
        +
        +static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent)
        +        {
        +	BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
        +	indent += 2;
        +	BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
        +	i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm);
        +	BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
        +	i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING);
        +	BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
        +	i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING);
        +	BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
        +	i2a_ASN1_INTEGER(bp, a->serialNumber);
        +	BIO_printf(bp, "\n");
        +	return 1;
        +	}
        +
        +typedef struct
        +	{
        +	long t;
        +	const char *m;
        +	} OCSP_TBLSTR;
        +
        +static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
        +{
        +	const OCSP_TBLSTR *p;
        +	for (p=ts; p < ts + len; p++)
        +	        if (p->t == s)
        +		         return p->m;
        +	return "(UNKNOWN)";
        +}
        +
        +const char *OCSP_response_status_str(long s)
        +        {
        +	static const OCSP_TBLSTR rstat_tbl[] = {
        +	        { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
        +	        { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
        +	        { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
        +	        { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" },
        +	        { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" },
        +	        { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } };
        +	return table2string(s, rstat_tbl, 6);
        +	} 
        +
        +const char *OCSP_cert_status_str(long s)
        +        {
        +	static const OCSP_TBLSTR cstat_tbl[] = {
        +	        { V_OCSP_CERTSTATUS_GOOD, "good" },
        +	        { V_OCSP_CERTSTATUS_REVOKED, "revoked" },
        +	        { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } };
        +	return table2string(s, cstat_tbl, 3);
        +	} 
        +
        +const char *OCSP_crl_reason_str(long s)
        +        {
        +	static const OCSP_TBLSTR reason_tbl[] = {
        +	  { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
        +          { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" },
        +          { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" },
        +          { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" },
        +          { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" },
        +          { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" },
        +          { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" },
        +          { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } };
        +	return table2string(s, reason_tbl, 8);
        +	} 
        +
        +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
        +        {
        +	int i;
        +	long l;
        +	OCSP_CERTID* cid = NULL;
        +	OCSP_ONEREQ *one = NULL;
        +	OCSP_REQINFO *inf = o->tbsRequest;
        +	OCSP_SIGNATURE *sig = o->optionalSignature;
        +
        +	if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err;
        +	l=ASN1_INTEGER_get(inf->version);
        +	if (BIO_printf(bp,"    Version: %lu (0x%lx)",l+1,l) <= 0) goto err;
        +	if (inf->requestorName != NULL)
        +	        {
        +		if (BIO_write(bp,"\n    Requestor Name: ",21) <= 0) 
        +		        goto err;
        +		GENERAL_NAME_print(bp, inf->requestorName);
        +		}
        +	if (BIO_write(bp,"\n    Requestor List:\n",21) <= 0) goto err;
        +	for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++)
        +	        {
        +		one = sk_OCSP_ONEREQ_value(inf->requestList, i);
        +		cid = one->reqCert;
        +		ocsp_certid_print(bp, cid, 8);
        +		if (!X509V3_extensions_print(bp,
        +					"Request Single Extensions",
        +					one->singleRequestExtensions, flags, 8))
        +							goto err;
        +		}
        +	if (!X509V3_extensions_print(bp, "Request Extensions",
        +			inf->requestExtensions, flags, 4))
        +							goto err;
        +	if (sig)
        +	        {
        +		X509_signature_print(bp, sig->signatureAlgorithm, sig->signature);
        +		for (i=0; i<sk_X509_num(sig->certs); i++)
        +			{
        +			X509_print(bp, sk_X509_value(sig->certs,i));
        +			PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i));
        +			}
        +		}
        +	return 1;
        +err:
        +	return 0;
        +	}
        +
        +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
        +        {
        +	int i, ret = 0;
        +	long l;
        +	OCSP_CERTID *cid = NULL;
        +	OCSP_BASICRESP *br = NULL;
        +	OCSP_RESPID *rid = NULL;
        +	OCSP_RESPDATA  *rd = NULL;
        +	OCSP_CERTSTATUS *cst = NULL;
        +	OCSP_REVOKEDINFO *rev = NULL;
        +	OCSP_SINGLERESP *single = NULL;
        +	OCSP_RESPBYTES *rb = o->responseBytes;
        +
        +	if (BIO_puts(bp,"OCSP Response Data:\n") <= 0) goto err;
        +	l=ASN1_ENUMERATED_get(o->responseStatus);
        +	if (BIO_printf(bp,"    OCSP Response Status: %s (0x%lx)\n",
        +		       OCSP_response_status_str(l), l) <= 0) goto err;
        +	if (rb == NULL) return 1;
        +        if (BIO_puts(bp,"    Response Type: ") <= 0)
        +	        goto err;
        +	if(i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
        +	        goto err;
        +	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) 
        +	        {
        +		BIO_puts(bp," (unknown response type)\n");
        +		return 1;
        +		}
        +
        +	i = ASN1_STRING_length(rb->response);
        +	if (!(br = OCSP_response_get1_basic(o))) goto err;
        +	rd = br->tbsResponseData;
        +	l=ASN1_INTEGER_get(rd->version);
        +	if (BIO_printf(bp,"\n    Version: %lu (0x%lx)\n",
        +		       l+1,l) <= 0) goto err;
        +	if (BIO_puts(bp,"    Responder Id: ") <= 0) goto err;
        +
        +	rid =  rd->responderId;
        +	switch (rid->type)
        +		{
        +		case V_OCSP_RESPID_NAME:
        +		        X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
        +		        break;
        +		case V_OCSP_RESPID_KEY:
        +		        i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING);
        +		        break;
        +		}
        +
        +	if (BIO_printf(bp,"\n    Produced At: ")<=0) goto err;
        +	if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) goto err;
        +	if (BIO_printf(bp,"\n    Responses:\n") <= 0) goto err;
        +	for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++)
        +	        {
        +		if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) continue;
        +		single = sk_OCSP_SINGLERESP_value(rd->responses, i);
        +		cid = single->certId;
        +		if(ocsp_certid_print(bp, cid, 4) <= 0) goto err;
        +		cst = single->certStatus;
        +		if (BIO_printf(bp,"    Cert Status: %s",
        +			       OCSP_cert_status_str(cst->type)) <= 0)
        +		        goto err;
        +		if (cst->type == V_OCSP_CERTSTATUS_REVOKED)
        +		        {
        +		        rev = cst->value.revoked;
        +			if (BIO_printf(bp, "\n    Revocation Time: ") <= 0) 
        +			        goto err;
        +			if (!ASN1_GENERALIZEDTIME_print(bp, 
        +							rev->revocationTime)) 
        +				goto err;
        +			if (rev->revocationReason) 
        +			        {
        +				l=ASN1_ENUMERATED_get(rev->revocationReason);
        +				if (BIO_printf(bp, 
        +					 "\n    Revocation Reason: %s (0x%lx)",
        +					       OCSP_crl_reason_str(l), l) <= 0)
        +				        goto err;
        +				}
        +			}
        +		if (BIO_printf(bp,"\n    This Update: ") <= 0) goto err;
        +		if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 
        +			goto err;
        +		if (single->nextUpdate)
        +		        {
        +			if (BIO_printf(bp,"\n    Next Update: ") <= 0)goto err;
        +			if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate))
        +				goto err;
        +			}
        +		if (BIO_write(bp,"\n",1) <= 0) goto err;
        +		if (!X509V3_extensions_print(bp,
        +					"Response Single Extensions",
        +					single->singleExtensions, flags, 8))
        +							goto err;
        +		if (BIO_write(bp,"\n",1) <= 0) goto err;
        +		}
        +	if (!X509V3_extensions_print(bp, "Response Extensions",
        +					rd->responseExtensions, flags, 4))
        +							goto err;
        +	if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0)
        +							goto err;
        +
        +	for (i=0; i<sk_X509_num(br->certs); i++)
        +		{
        +		X509_print(bp, sk_X509_value(br->certs,i));
        +		PEM_write_bio_X509(bp,sk_X509_value(br->certs,i));
        +		}
        +
        +	ret = 1;
        +err:
        +	OCSP_BASICRESP_free(br);
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_srv.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_srv.c
        new file mode 100644
        index 000000000..1c606dd0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_srv.c
        @@ -0,0 +1,264 @@
        +/* ocsp_srv.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include <cryptlib.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ocsp.h>
        +
        +/* Utility functions related to sending OCSP responses and extracting
        + * relevant information from the request.
        + */
        +
        +int OCSP_request_onereq_count(OCSP_REQUEST *req)
        +	{
        +	return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList);
        +	}
        +
        +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
        +	{
        +	return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i);
        +	}
        +
        +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one)
        +	{
        +	return one->reqCert;
        +	}
        +
        +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
        +			ASN1_OCTET_STRING **pikeyHash,
        +			ASN1_INTEGER **pserial, OCSP_CERTID *cid)
        +	{
        +	if (!cid) return 0;
        +	if (pmd) *pmd = cid->hashAlgorithm->algorithm;
        +	if(piNameHash) *piNameHash = cid->issuerNameHash;
        +	if (pikeyHash) *pikeyHash = cid->issuerKeyHash;
        +	if (pserial) *pserial = cid->serialNumber;
        +	return 1;
        +	}
        +
        +int OCSP_request_is_signed(OCSP_REQUEST *req)
        +	{
        +	if(req->optionalSignature) return 1;
        +	return 0;
        +	}
        +
        +/* Create an OCSP response and encode an optional basic response */
        +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
        +        {
        +        OCSP_RESPONSE *rsp = NULL;
        +
        +	if (!(rsp = OCSP_RESPONSE_new())) goto err;
        +	if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) goto err;
        +	if (!bs) return rsp;
        +	if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) goto err;
        +	rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
        +	if (!ASN1_item_pack(bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response))
        +				goto err;
        +	return rsp;
        +err:
        +	if (rsp) OCSP_RESPONSE_free(rsp);
        +	return NULL;
        +	}
        +
        +
        +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
        +						OCSP_CERTID *cid,
        +						int status, int reason,
        +						ASN1_TIME *revtime,
        +					ASN1_TIME *thisupd, ASN1_TIME *nextupd)
        +	{
        +	OCSP_SINGLERESP *single = NULL;
        +	OCSP_CERTSTATUS *cs;
        +	OCSP_REVOKEDINFO *ri;
        +
        +	if(!rsp->tbsResponseData->responses &&
        +	    !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null()))
        +		goto err;
        +
        +	if (!(single = OCSP_SINGLERESP_new()))
        +		goto err;
        +
        +
        +
        +	if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
        +		goto err;
        +	if (nextupd &&
        +		!ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
        +		goto err;
        +
        +	OCSP_CERTID_free(single->certId);
        +
        +	if(!(single->certId = OCSP_CERTID_dup(cid)))
        +		goto err;
        +
        +	cs = single->certStatus;
        +	switch(cs->type = status)
        +		{
        +	case V_OCSP_CERTSTATUS_REVOKED:
        +		if (!revtime)
        +		        {
        +		        OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS,OCSP_R_NO_REVOKED_TIME);
        +			goto err;
        +		        }
        +		if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) goto err;
        +		if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
        +			goto err;	
        +		if (reason != OCSP_REVOKED_STATUS_NOSTATUS)
        +		        {
        +			if (!(ri->revocationReason = ASN1_ENUMERATED_new())) 
        +			        goto err;
        +			if (!(ASN1_ENUMERATED_set(ri->revocationReason, 
        +						  reason)))
        +			        goto err;	
        +			}
        +		break;
        +
        +	case V_OCSP_CERTSTATUS_GOOD:
        +		cs->value.good = ASN1_NULL_new();
        +		break;
        +
        +	case V_OCSP_CERTSTATUS_UNKNOWN:
        +		cs->value.unknown = ASN1_NULL_new();
        +		break;
        +
        +	default:
        +		goto err;
        +
        +		}
        +	if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single)))
        +		goto err;
        +	return single;
        +err:
        +	OCSP_SINGLERESP_free(single);
        +	return NULL;
        +	}
        +
        +/* Add a certificate to an OCSP request */
        +
        +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
        +	{
        +	if (!resp->certs && !(resp->certs = sk_X509_new_null()))
        +		return 0;
        +
        +	if(!sk_X509_push(resp->certs, cert)) return 0;
        +	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
        +	return 1;
        +	}
        +
        +int OCSP_basic_sign(OCSP_BASICRESP *brsp, 
        +			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
        +			STACK_OF(X509) *certs, unsigned long flags)
        +        {
        +	int i;
        +	OCSP_RESPID *rid;
        +
        +	if (!X509_check_private_key(signer, key))
        +		{
        +		OCSPerr(OCSP_F_OCSP_BASIC_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        +		goto err;
        +		}
        +
        +	if(!(flags & OCSP_NOCERTS))
        +		{
        +		if(!OCSP_basic_add1_cert(brsp, signer))
        +			goto err;
        +		for (i = 0; i < sk_X509_num(certs); i++)
        +			{
        +			X509 *tmpcert = sk_X509_value(certs, i);
        +			if(!OCSP_basic_add1_cert(brsp, tmpcert))
        +				goto err;
        +			}
        +		}
        +
        +	rid = brsp->tbsResponseData->responderId;
        +	if (flags & OCSP_RESPID_KEY)
        +		{
        +		unsigned char md[SHA_DIGEST_LENGTH];
        +		X509_pubkey_digest(signer, EVP_sha1(), md, NULL);
        +		if (!(rid->value.byKey = ASN1_OCTET_STRING_new()))
        +			goto err;
        +		if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH)))
        +				goto err;
        +		rid->type = V_OCSP_RESPID_KEY;
        +		}
        +	else
        +		{
        +		if (!X509_NAME_set(&rid->value.byName,
        +					X509_get_subject_name(signer)))
        +				goto err;
        +		rid->type = V_OCSP_RESPID_NAME;
        +		}
        +
        +	if (!(flags & OCSP_NOTIME) &&
        +		!X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0))
        +		goto err;
        +
        +	/* Right now, I think that not doing double hashing is the right
        +	   thing.	-- Richard Levitte */
        +
        +	if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) goto err;
        +
        +	return 1;
        +err:
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ocsp/ocsp_vfy.c b/vendor/openssl/openssl/crypto/ocsp/ocsp_vfy.c
        new file mode 100644
        index 000000000..276718304
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ocsp/ocsp_vfy.c
        @@ -0,0 +1,450 @@
        +/* ocsp_vfy.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2004 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 <openssl/ocsp.h>
        +#include <openssl/err.h>
        +#include <string.h>
        +
        +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
        +				X509_STORE *st, unsigned long flags);
        +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
        +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags);
        +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret);
        +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp);
        +static int ocsp_check_delegated(X509 *x, int flags);
        +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
        +				X509_STORE *st, unsigned long flags);
        +
        +/* Verify a basic response message */
        +
        +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
        +				X509_STORE *st, unsigned long flags)
        +	{
        +	X509 *signer, *x;
        +	STACK_OF(X509) *chain = NULL;
        +	X509_STORE_CTX ctx;
        +	int i, ret = 0;
        +	ret = ocsp_find_signer(&signer, bs, certs, st, flags);
        +	if (!ret)
        +		{
        +		OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
        +		goto end;
        +		}
        +	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
        +		flags |= OCSP_NOVERIFY;
        +	if (!(flags & OCSP_NOSIGS))
        +		{
        +		EVP_PKEY *skey;
        +		skey = X509_get_pubkey(signer);
        +		if (skey)
        +			{
        +			ret = OCSP_BASICRESP_verify(bs, skey, 0);
        +			EVP_PKEY_free(skey);
        +			}
        +		if(!skey || ret <= 0)
        +			{
        +			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
        +			goto end;
        +			}
        +		}
        +	if (!(flags & OCSP_NOVERIFY))
        +		{
        +		int init_res;
        +		if(flags & OCSP_NOCHAIN)
        +			init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL);
        +		else
        +			init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
        +		if(!init_res)
        +			{
        +			ret = -1;
        +			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
        +			goto end;
        +			}
        +
        +		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
        +		ret = X509_verify_cert(&ctx);
        +		chain = X509_STORE_CTX_get1_chain(&ctx);
        +		X509_STORE_CTX_cleanup(&ctx);
        +                if (ret <= 0)
        +			{
        +			i = X509_STORE_CTX_get_error(&ctx);	
        +			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR);
        +			ERR_add_error_data(2, "Verify error:",
        +					X509_verify_cert_error_string(i));
        +                        goto end;
        +                	}
        +		if(flags & OCSP_NOCHECKS)
        +			{
        +			ret = 1;
        +			goto end;
        +			}
        +		/* At this point we have a valid certificate chain
        +		 * need to verify it against the OCSP issuer criteria.
        +		 */
        +		ret = ocsp_check_issuer(bs, chain, flags);
        +
        +		/* If fatal error or valid match then finish */
        +		if (ret != 0) goto end;
        +
        +		/* Easy case: explicitly trusted. Get root CA and
        +		 * check for explicit trust
        +		 */
        +		if(flags & OCSP_NOEXPLICIT) goto end;
        +
        +		x = sk_X509_value(chain, sk_X509_num(chain) - 1);
        +		if(X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED)
        +			{
        +			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_ROOT_CA_NOT_TRUSTED);
        +			goto end;
        +			}
        +		ret = 1;
        +		}
        +
        +
        +
        +	end:
        +	if(chain) sk_X509_pop_free(chain, X509_free);
        +	return ret;
        +	}
        +
        +
        +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
        +				X509_STORE *st, unsigned long flags)
        +	{
        +	X509 *signer;
        +	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
        +	if ((signer = ocsp_find_signer_sk(certs, rid)))
        +		{
        +		*psigner = signer;
        +		return 2;
        +		}
        +	if(!(flags & OCSP_NOINTERN) &&
        +	    (signer = ocsp_find_signer_sk(bs->certs, rid)))
        +		{
        +		*psigner = signer;
        +		return 1;
        +		}
        +	/* Maybe lookup from store if by subject name */
        +
        +	*psigner = NULL;
        +	return 0;
        +	}
        +
        +
        +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
        +	{
        +	int i;
        +	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
        +	X509 *x;
        +
        +	/* Easy if lookup by name */
        +	if (id->type == V_OCSP_RESPID_NAME)
        +		return X509_find_by_subject(certs, id->value.byName);
        +
        +	/* Lookup by key hash */
        +
        +	/* If key hash isn't SHA1 length then forget it */
        +	if (id->value.byKey->length != SHA_DIGEST_LENGTH) return NULL;
        +	keyhash = id->value.byKey->data;
        +	/* Calculate hash of each key and compare */
        +	for (i = 0; i < sk_X509_num(certs); i++)
        +		{
        +		x = sk_X509_value(certs, i);
        +		X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
        +		if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
        +			return x;
        +		}
        +	return NULL;
        +	}
        +
        +
        +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags)
        +	{
        +	STACK_OF(OCSP_SINGLERESP) *sresp;
        +	X509 *signer, *sca;
        +	OCSP_CERTID *caid = NULL;
        +	int i;
        +	sresp = bs->tbsResponseData->responses;
        +
        +	if (sk_X509_num(chain) <= 0)
        +		{
        +		OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
        +		return -1;
        +		}
        +
        +	/* See if the issuer IDs match. */
        +	i = ocsp_check_ids(sresp, &caid);
        +
        +	/* If ID mismatch or other error then return */
        +	if (i <= 0) return i;
        +
        +	signer = sk_X509_value(chain, 0);
        +	/* Check to see if OCSP responder CA matches request CA */
        +	if (sk_X509_num(chain) > 1)
        +		{
        +		sca = sk_X509_value(chain, 1);
        +		i = ocsp_match_issuerid(sca, caid, sresp);
        +		if (i < 0) return i;
        +		if (i)
        +			{
        +			/* We have a match, if extensions OK then success */
        +			if (ocsp_check_delegated(signer, flags)) return 1;
        +			return 0;
        +			}
        +		}
        +
        +	/* Otherwise check if OCSP request signed directly by request CA */
        +	return ocsp_match_issuerid(signer, caid, sresp);
        +	}
        +
        +
        +/* Check the issuer certificate IDs for equality. If there is a mismatch with the same
        + * algorithm then there's no point trying to match any certificates against the issuer.
        + * If the issuer IDs all match then we just need to check equality against one of them.
        + */
        +	
        +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
        +	{
        +	OCSP_CERTID *tmpid, *cid;
        +	int i, idcount;
        +
        +	idcount = sk_OCSP_SINGLERESP_num(sresp);
        +	if (idcount <= 0)
        +		{
        +		OCSPerr(OCSP_F_OCSP_CHECK_IDS, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
        +		return -1;
        +		}
        +
        +	cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
        +
        +	*ret = NULL;
        +
        +	for (i = 1; i < idcount; i++)
        +		{
        +		tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
        +		/* Check to see if IDs match */
        +		if (OCSP_id_issuer_cmp(cid, tmpid))
        +			{
        +			/* If algoritm mismatch let caller deal with it */
        +			if (OBJ_cmp(tmpid->hashAlgorithm->algorithm,
        +					cid->hashAlgorithm->algorithm))
        +					return 2;
        +			/* Else mismatch */
        +			return 0;
        +			}
        +		}
        +
        +	/* All IDs match: only need to check one ID */
        +	*ret = cid;
        +	return 1;
        +	}
        +
        +
        +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
        +			STACK_OF(OCSP_SINGLERESP) *sresp)
        +	{
        +	/* If only one ID to match then do it */
        +	if(cid)
        +		{
        +		const EVP_MD *dgst;
        +		X509_NAME *iname;
        +		int mdlen;
        +		unsigned char md[EVP_MAX_MD_SIZE];
        +		if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm)))
        +			{
        +			OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, OCSP_R_UNKNOWN_MESSAGE_DIGEST);
        +			return -1;
        +			}
        +
        +		mdlen = EVP_MD_size(dgst);
        +		if (mdlen < 0)
        +		    return -1;
        +		if ((cid->issuerNameHash->length != mdlen) ||
        +		   (cid->issuerKeyHash->length != mdlen))
        +			return 0;
        +		iname = X509_get_subject_name(cert);
        +		if (!X509_NAME_digest(iname, dgst, md, NULL))
        +			return -1;
        +		if (memcmp(md, cid->issuerNameHash->data, mdlen))
        +			return 0;
        +		X509_pubkey_digest(cert, dgst, md, NULL);
        +		if (memcmp(md, cid->issuerKeyHash->data, mdlen))
        +			return 0;
        +
        +		return 1;
        +
        +		}
        +	else
        +		{
        +		/* We have to match the whole lot */
        +		int i, ret;
        +		OCSP_CERTID *tmpid;
        +		for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++)
        +			{
        +			tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
        +			ret = ocsp_match_issuerid(cert, tmpid, NULL);
        +			if (ret <= 0) return ret;
        +			}
        +		return 1;
        +		}
        +			
        +	}
        +
        +static int ocsp_check_delegated(X509 *x, int flags)
        +	{
        +	X509_check_purpose(x, -1, 0);
        +	if ((x->ex_flags & EXFLAG_XKUSAGE) &&
        +	    (x->ex_xkusage & XKU_OCSP_SIGN))
        +		return 1;
        +	OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
        +	return 0;
        +	}
        +
        +/* Verify an OCSP request. This is fortunately much easier than OCSP
        + * response verify. Just find the signers certificate and verify it
        + * against a given trust value.
        + */
        +
        +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags)
        +        {
        +	X509 *signer;
        +	X509_NAME *nm;
        +	GENERAL_NAME *gen;
        +	int ret;
        +	X509_STORE_CTX ctx;
        +	if (!req->optionalSignature) 
        +		{
        +		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
        +		return 0;
        +		}
        +	gen = req->tbsRequest->requestorName;
        +	if (!gen || gen->type != GEN_DIRNAME)
        +		{
        +		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
        +		return 0;
        +		}
        +	nm = gen->d.directoryName;
        +	ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags);
        +	if (ret <= 0)
        +		{
        +		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
        +		return 0;
        +		}
        +	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
        +		flags |= OCSP_NOVERIFY;
        +	if (!(flags & OCSP_NOSIGS))
        +		{
        +		EVP_PKEY *skey;
        +		skey = X509_get_pubkey(signer);
        +		ret = OCSP_REQUEST_verify(req, skey);
        +		EVP_PKEY_free(skey);
        +		if(ret <= 0)
        +			{
        +			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
        +			return 0;
        +			}
        +		}
        +	if (!(flags & OCSP_NOVERIFY))
        +		{
        +		int init_res;
        +		if(flags & OCSP_NOCHAIN)
        +			init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL);
        +		else
        +			init_res = X509_STORE_CTX_init(&ctx, store, signer,
        +					req->optionalSignature->certs);
        +		if(!init_res)
        +			{
        +			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,ERR_R_X509_LIB);
        +			return 0;
        +			}
        +
        +		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
        +		X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST);
        +		ret = X509_verify_cert(&ctx);
        +		X509_STORE_CTX_cleanup(&ctx);
        +                if (ret <= 0)
        +			{
        +			ret = X509_STORE_CTX_get_error(&ctx);	
        +			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR);
        +			ERR_add_error_data(2, "Verify error:",
        +					X509_verify_cert_error_string(ret));
        +                        return 0;
        +                	}
        +		}
        +	return 1;
        +        }
        +
        +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
        +				X509_STORE *st, unsigned long flags)
        +	{
        +	X509 *signer;
        +	if(!(flags & OCSP_NOINTERN))
        +		{
        +		signer = X509_find_by_subject(req->optionalSignature->certs, nm);
        +		*psigner = signer;
        +		return 1;
        +		}
        +
        +	signer = X509_find_by_subject(certs, nm);
        +	if (signer)
        +		{
        +		*psigner = signer;
        +		return 2;
        +		}
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/opensslconf.h b/vendor/openssl/openssl/crypto/opensslconf.h
        new file mode 100644
        index 000000000..76c99d433
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/opensslconf.h
        @@ -0,0 +1 @@
        +#include "../../config/opensslconf.h"
        diff --git a/vendor/openssl/openssl/crypto/opensslconf.h.in b/vendor/openssl/openssl/crypto/opensslconf.h.in
        new file mode 100644
        index 000000000..97e374556
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/opensslconf.h.in
        @@ -0,0 +1,154 @@
        +/* crypto/opensslconf.h.in */
        +
        +/* Generate 80386 code? */
        +#undef I386_ONLY
        +
        +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
        +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
        +#define ENGINESDIR "/usr/local/lib/engines"
        +#define OPENSSLDIR "/usr/local/ssl"
        +#endif
        +#endif
        +
        +#undef OPENSSL_UNISTD
        +#define OPENSSL_UNISTD <unistd.h>
        +
        +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +
        +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
        +#define IDEA_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_MD2_H) && !defined(MD2_INT)
        +#define MD2_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_RC2_H) && !defined(RC2_INT)
        +/* I need to put in a mod for the alpha - eay */
        +#define RC2_INT unsigned int
        +#endif
        +
        +#if defined(HEADER_RC4_H)
        +#if !defined(RC4_INT)
        +/* using int types make the structure larger but make the code faster
        + * on most boxes I have tested - up to %20 faster. */
        +/*
        + * I don't know what does "most" mean, but declaring "int" is a must on:
        + * - Intel P6 because partial register stalls are very expensive;
        + * - elder Alpha because it lacks byte load/store instructions;
        + */
        +#define RC4_INT unsigned int
        +#endif
        +#if !defined(RC4_CHUNK)
        +/*
        + * This enables code handling data aligned at natural CPU word
        + * boundary. See crypto/rc4/rc4_enc.c for further details.
        + */
        +#undef RC4_CHUNK
        +#endif
        +#endif
        +
        +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
        +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
        + * %20 speed up (longs are 8 bytes, int's are 4). */
        +#ifndef DES_LONG
        +#define DES_LONG unsigned long
        +#endif
        +#endif
        +
        +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
        +#define CONFIG_HEADER_BN_H
        +#undef BN_LLONG
        +
        +/* Should we define BN_DIV2W here? */
        +
        +/* Only one for the following should be defined */
        +#undef SIXTY_FOUR_BIT_LONG
        +#undef SIXTY_FOUR_BIT
        +#define THIRTY_TWO_BIT
        +#endif
        +
        +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
        +#define CONFIG_HEADER_RC4_LOCL_H
        +/* if this is defined data[i] is used instead of *data, this is a %20
        + * speedup on x86 */
        +#undef RC4_INDEX
        +#endif
        +
        +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
        +#define CONFIG_HEADER_BF_LOCL_H
        +#undef BF_PTR
        +#endif /* HEADER_BF_LOCL_H */
        +
        +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
        +#define CONFIG_HEADER_DES_LOCL_H
        +#ifndef DES_DEFAULT_OPTIONS
        +/* the following is tweaked from a config script, that is why it is a
        + * protected undef/define */
        +#ifndef DES_PTR
        +#undef DES_PTR
        +#endif
        +
        +/* This helps C compiler generate the correct code for multiple functional
        + * units.  It reduces register dependancies at the expense of 2 more
        + * registers */
        +#ifndef DES_RISC1
        +#undef DES_RISC1
        +#endif
        +
        +#ifndef DES_RISC2
        +#undef DES_RISC2
        +#endif
        +
        +#if defined(DES_RISC1) && defined(DES_RISC2)
        +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
        +#endif
        +
        +/* Unroll the inner loop, this sometimes helps, sometimes hinders.
        + * Very mucy CPU dependant */
        +#ifndef DES_UNROLL
        +#undef DES_UNROLL
        +#endif
        +
        +/* These default values were supplied by
        + * Peter Gutman <pgut001@cs.auckland.ac.nz>
        + * They are only used if nothing else has been defined */
        +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
        +/* Special defines which change the way the code is built depending on the
        +   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
        +   even newer MIPS CPU's, but at the moment one size fits all for
        +   optimization options.  Older Sparc's work better with only UNROLL, but
        +   there's no way to tell at compile time what it is you're running on */
        + 
        +#if defined( sun )		/* Newer Sparc's */
        +#  define DES_PTR
        +#  define DES_RISC1
        +#  define DES_UNROLL
        +#elif defined( __ultrix )	/* Older MIPS */
        +#  define DES_PTR
        +#  define DES_RISC2
        +#  define DES_UNROLL
        +#elif defined( __osf1__ )	/* Alpha */
        +#  define DES_PTR
        +#  define DES_RISC2
        +#elif defined ( _AIX )		/* RS6000 */
        +  /* Unknown */
        +#elif defined( __hpux )		/* HP-PA */
        +  /* Unknown */
        +#elif defined( __aux )		/* 68K */
        +  /* Unknown */
        +#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
        +#  define DES_UNROLL
        +#elif defined( __sgi )		/* Newer MIPS */
        +#  define DES_PTR
        +#  define DES_RISC2
        +#  define DES_UNROLL
        +#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
        +#  define DES_PTR
        +#  define DES_RISC1
        +#  define DES_UNROLL
        +#endif /* Systems-specific speed defines */
        +#endif
        +
        +#endif /* DES_DEFAULT_OPTIONS */
        +#endif /* HEADER_DES_LOCL_H */
        diff --git a/vendor/openssl/openssl/crypto/opensslv.h b/vendor/openssl/openssl/crypto/opensslv.h
        new file mode 100644
        index 000000000..5bc8e53e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/opensslv.h
        @@ -0,0 +1,89 @@
        +#ifndef HEADER_OPENSSLV_H
        +#define HEADER_OPENSSLV_H
        +
        +/* Numeric release version identifier:
        + * MNNFFPPS: major minor fix patch status
        + * The status nibble has one of the values 0 for development, 1 to e for betas
        + * 1 to 14, and f for release.  The patch level is exactly that.
        + * For example:
        + * 0.9.3-dev	  0x00903000
        + * 0.9.3-beta1	  0x00903001
        + * 0.9.3-beta2-dev 0x00903002
        + * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
        + * 0.9.3	  0x0090300f
        + * 0.9.3a	  0x0090301f
        + * 0.9.4 	  0x0090400f
        + * 1.2.3z	  0x102031af
        + *
        + * For continuity reasons (because 0.9.5 is already out, and is coded
        + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
        + * part is slightly different, by setting the highest bit.  This means
        + * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
        + * with 0x0090600S...
        + *
        + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
        + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
        + *  major minor fix final patch/beta)
        + */
        +#define OPENSSL_VERSION_NUMBER	0x1000105fL
        +#ifdef OPENSSL_FIPS
        +#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e-fips 11 Feb 2013"
        +#else
        +#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e 11 Feb 2013"
        +#endif
        +#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
        +
        +
        +/* The macros below are to be used for shared library (.so, .dll, ...)
        + * versioning.  That kind of versioning works a bit differently between
        + * operating systems.  The most usual scheme is to set a major and a minor
        + * number, and have the runtime loader check that the major number is equal
        + * to what it was at application link time, while the minor number has to
        + * be greater or equal to what it was at application link time.  With this
        + * scheme, the version number is usually part of the file name, like this:
        + *
        + *	libcrypto.so.0.9
        + *
        + * Some unixen also make a softlink with the major verson number only:
        + *
        + *	libcrypto.so.0
        + *
        + * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
        + * shared library version is stored in the file, and is actually a series
        + * of versions, separated by colons.  The rightmost version present in the
        + * library when linking an application is stored in the application to be
        + * matched at run time.  When the application is run, a check is done to
        + * see if the library version stored in the application matches any of the
        + * versions in the version string of the library itself.
        + * This version string can be constructed in any way, depending on what
        + * kind of matching is desired.  However, to implement the same scheme as
        + * the one used in the other unixen, all compatible versions, from lowest
        + * to highest, should be part of the string.  Consecutive builds would
        + * give the following versions strings:
        + *
        + *	3.0
        + *	3.0:3.1
        + *	3.0:3.1:3.2
        + *	4.0
        + *	4.0:4.1
        + *
        + * Notice how version 4 is completely incompatible with version, and
        + * therefore give the breach you can see.
        + *
        + * There may be other schemes as well that I haven't yet discovered.
        + *
        + * So, here's the way it works here: first of all, the library version
        + * number doesn't need at all to match the overall OpenSSL version.
        + * However, it's nice and more understandable if it actually does.
        + * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
        + * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
        + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
        + * we need to keep a history of version numbers, which is done in the
        + * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
        + * should only keep the versions that are binary compatible with the current.
        + */
        +#define SHLIB_VERSION_HISTORY ""
        +#define SHLIB_VERSION_NUMBER "1.0.0"
        +
        +
        +#endif /* HEADER_OPENSSLV_H */
        diff --git a/vendor/openssl/openssl/crypto/ossl_typ.h b/vendor/openssl/openssl/crypto/ossl_typ.h
        new file mode 100644
        index 000000000..ea9227f6f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ossl_typ.h
        @@ -0,0 +1,202 @@
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_OPENSSL_TYPES_H
        +#define HEADER_OPENSSL_TYPES_H
        +
        +#include <openssl/e_os2.h>
        +
        +#ifdef NO_ASN1_TYPEDEFS
        +#define ASN1_INTEGER		ASN1_STRING
        +#define ASN1_ENUMERATED		ASN1_STRING
        +#define ASN1_BIT_STRING		ASN1_STRING
        +#define ASN1_OCTET_STRING	ASN1_STRING
        +#define ASN1_PRINTABLESTRING	ASN1_STRING
        +#define ASN1_T61STRING		ASN1_STRING
        +#define ASN1_IA5STRING		ASN1_STRING
        +#define ASN1_UTCTIME		ASN1_STRING
        +#define ASN1_GENERALIZEDTIME	ASN1_STRING
        +#define ASN1_TIME		ASN1_STRING
        +#define ASN1_GENERALSTRING	ASN1_STRING
        +#define ASN1_UNIVERSALSTRING	ASN1_STRING
        +#define ASN1_BMPSTRING		ASN1_STRING
        +#define ASN1_VISIBLESTRING	ASN1_STRING
        +#define ASN1_UTF8STRING		ASN1_STRING
        +#define ASN1_BOOLEAN		int
        +#define ASN1_NULL		int
        +#else
        +typedef struct asn1_string_st ASN1_INTEGER;
        +typedef struct asn1_string_st ASN1_ENUMERATED;
        +typedef struct asn1_string_st ASN1_BIT_STRING;
        +typedef struct asn1_string_st ASN1_OCTET_STRING;
        +typedef struct asn1_string_st ASN1_PRINTABLESTRING;
        +typedef struct asn1_string_st ASN1_T61STRING;
        +typedef struct asn1_string_st ASN1_IA5STRING;
        +typedef struct asn1_string_st ASN1_GENERALSTRING;
        +typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
        +typedef struct asn1_string_st ASN1_BMPSTRING;
        +typedef struct asn1_string_st ASN1_UTCTIME;
        +typedef struct asn1_string_st ASN1_TIME;
        +typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
        +typedef struct asn1_string_st ASN1_VISIBLESTRING;
        +typedef struct asn1_string_st ASN1_UTF8STRING;
        +typedef struct asn1_string_st ASN1_STRING;
        +typedef int ASN1_BOOLEAN;
        +typedef int ASN1_NULL;
        +#endif
        +
        +typedef struct ASN1_ITEM_st ASN1_ITEM;
        +typedef struct asn1_pctx_st ASN1_PCTX;
        +
        +#ifdef OPENSSL_SYS_WIN32
        +#undef X509_NAME
        +#undef X509_EXTENSIONS
        +#undef X509_CERT_PAIR
        +#undef PKCS7_ISSUER_AND_SERIAL
        +#undef OCSP_REQUEST
        +#undef OCSP_RESPONSE
        +#endif
        +
        +#ifdef BIGNUM
        +#undef BIGNUM
        +#endif
        +typedef struct bignum_st BIGNUM;
        +typedef struct bignum_ctx BN_CTX;
        +typedef struct bn_blinding_st BN_BLINDING;
        +typedef struct bn_mont_ctx_st BN_MONT_CTX;
        +typedef struct bn_recp_ctx_st BN_RECP_CTX;
        +typedef struct bn_gencb_st BN_GENCB;
        +
        +typedef struct buf_mem_st BUF_MEM;
        +
        +typedef struct evp_cipher_st EVP_CIPHER;
        +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
        +typedef struct env_md_st EVP_MD;
        +typedef struct env_md_ctx_st EVP_MD_CTX;
        +typedef struct evp_pkey_st EVP_PKEY;
        +
        +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
        +
        +typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
        +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
        +
        +typedef struct dh_st DH;
        +typedef struct dh_method DH_METHOD;
        +
        +typedef struct dsa_st DSA;
        +typedef struct dsa_method DSA_METHOD;
        +
        +typedef struct rsa_st RSA;
        +typedef struct rsa_meth_st RSA_METHOD;
        +
        +typedef struct rand_meth_st RAND_METHOD;
        +
        +typedef struct ecdh_method ECDH_METHOD;
        +typedef struct ecdsa_method ECDSA_METHOD;
        +
        +typedef struct x509_st X509;
        +typedef struct X509_algor_st X509_ALGOR;
        +typedef struct X509_crl_st X509_CRL;
        +typedef struct x509_crl_method_st X509_CRL_METHOD;
        +typedef struct x509_revoked_st X509_REVOKED;
        +typedef struct X509_name_st X509_NAME;
        +typedef struct X509_pubkey_st X509_PUBKEY;
        +typedef struct x509_store_st X509_STORE;
        +typedef struct x509_store_ctx_st X509_STORE_CTX;
        +
        +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
        +
        +typedef struct v3_ext_ctx X509V3_CTX;
        +typedef struct conf_st CONF;
        +
        +typedef struct store_st STORE;
        +typedef struct store_method_st STORE_METHOD;
        +
        +typedef struct ui_st UI;
        +typedef struct ui_method_st UI_METHOD;
        +
        +typedef struct st_ERR_FNS ERR_FNS;
        +
        +typedef struct engine_st ENGINE;
        +typedef struct ssl_st SSL;
        +typedef struct ssl_ctx_st SSL_CTX;
        +
        +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
        +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
        +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
        +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
        +
        +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
        +typedef struct DIST_POINT_st DIST_POINT;
        +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
        +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
        +
        +  /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
        +#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
        +#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
        +
        +typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
        +/* Callback types for crypto.h */
        +typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +					int idx, long argl, void *argp);
        +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +					int idx, long argl, void *argp);
        +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
        +					int idx, long argl, void *argp);
        +
        +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
        +typedef struct ocsp_response_st OCSP_RESPONSE;
        +typedef struct ocsp_responder_id_st OCSP_RESPID;
        +
        +#endif /* def HEADER_OPENSSL_TYPES_H */
        diff --git a/vendor/openssl/openssl/crypto/pariscid.pl b/vendor/openssl/openssl/crypto/pariscid.pl
        new file mode 100644
        index 000000000..477ec9b87
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pariscid.pl
        @@ -0,0 +1,224 @@
        +#!/usr/bin/env perl
        +
        +$flavour = shift;
        +$output = shift;
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$ST		="std";
        +} else {
        +	$LEVEL		="1.1";
        +	$SIZE_T		=4;
        +	$ST		="stw";
        +}
        +
        +$rp="%r2";
        +$sp="%r30";
        +$rv="%r28";
        +
        +$code=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.EXPORT	OPENSSL_cpuid_setup,ENTRY
        +	.ALIGN	8
        +OPENSSL_cpuid_setup
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	bv	($rp)
        +	.EXIT
        +	nop
        +	.PROCEND
        +
        +	.EXPORT	OPENSSL_rdtsc,ENTRY
        +	.ALIGN	8
        +OPENSSL_rdtsc
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	mfctl	%cr16,$rv
        +	bv	($rp)
        +	.EXIT
        +	nop
        +	.PROCEND
        +
        +	.EXPORT	OPENSSL_wipe_cpu,ENTRY
        +	.ALIGN	8
        +OPENSSL_wipe_cpu
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	xor		%r0,%r0,%r1
        +	fcpy,dbl	%fr0,%fr4
        +	xor		%r0,%r0,%r19
        +	fcpy,dbl	%fr0,%fr5
        +	xor		%r0,%r0,%r20
        +	fcpy,dbl	%fr0,%fr6
        +	xor		%r0,%r0,%r21
        +	fcpy,dbl	%fr0,%fr7
        +	xor		%r0,%r0,%r22
        +	fcpy,dbl	%fr0,%fr8
        +	xor		%r0,%r0,%r23
        +	fcpy,dbl	%fr0,%fr9
        +	xor		%r0,%r0,%r24
        +	fcpy,dbl	%fr0,%fr10
        +	xor		%r0,%r0,%r25
        +	fcpy,dbl	%fr0,%fr11
        +	xor		%r0,%r0,%r26
        +	fcpy,dbl	%fr0,%fr22
        +	xor		%r0,%r0,%r29
        +	fcpy,dbl	%fr0,%fr23
        +	xor		%r0,%r0,%r31
        +	fcpy,dbl	%fr0,%fr24
        +	fcpy,dbl	%fr0,%fr25
        +	fcpy,dbl	%fr0,%fr26
        +	fcpy,dbl	%fr0,%fr27
        +	fcpy,dbl	%fr0,%fr28
        +	fcpy,dbl	%fr0,%fr29
        +	fcpy,dbl	%fr0,%fr30
        +	fcpy,dbl	%fr0,%fr31
        +	bv		($rp)
        +	.EXIT
        +	ldo		0($sp),$rv
        +	.PROCEND
        +___
        +{
        +my $inp="%r26";
        +my $len="%r25";
        +
        +$code.=<<___;
        +	.EXPORT	OPENSSL_cleanse,ENTRY,ARGW0=GR,ARGW1=GR
        +	.ALIGN	8
        +OPENSSL_cleanse
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	cmpib,*=	0,$len,Ldone
        +	nop
        +	cmpib,*>>=	15,$len,Little
        +	ldi		$SIZE_T-1,%r1
        +
        +Lalign
        +	and,*<>		$inp,%r1,%r28
        +	b,n		Laligned
        +	stb		%r0,0($inp)
        +	ldo		-1($len),$len
        +	b		Lalign
        +	ldo		1($inp),$inp
        +
        +Laligned
        +	andcm		$len,%r1,%r28
        +Lot
        +	$ST		%r0,0($inp)
        +	addib,*<>	-$SIZE_T,%r28,Lot
        +	ldo		$SIZE_T($inp),$inp
        +
        +	and,*<>		$len,%r1,$len
        +	b,n		Ldone
        +Little
        +	stb		%r0,0($inp)
        +	addib,*<>	-1,$len,Little
        +	ldo		1($inp),$inp
        +Ldone
        +	bv		($rp)
        +	.EXIT
        +	nop
        +	.PROCEND
        +___
        +}
        +{
        +my ($out,$cnt,$max)=("%r26","%r25","%r24");
        +my ($tick,$lasttick)=("%r23","%r22");
        +my ($diff,$lastdiff)=("%r21","%r20");
        +
        +$code.=<<___;
        +	.EXPORT	OPENSSL_instrument_bus,ENTRY,ARGW0=GR,ARGW1=GR
        +	.ALIGN	8
        +OPENSSL_instrument_bus
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	copy		$cnt,$rv
        +	mfctl		%cr16,$tick
        +	copy		$tick,$lasttick
        +	ldi		0,$diff
        +
        +	fdc		0($out)
        +	ldw		0($out),$tick
        +	add		$diff,$tick,$tick
        +	stw		$tick,0($out)
        +Loop
        +	mfctl		%cr16,$tick
        +	sub		$tick,$lasttick,$diff
        +	copy		$tick,$lasttick
        +
        +	fdc		0($out)
        +	ldw		0($out),$tick
        +	add		$diff,$tick,$tick
        +	stw		$tick,0($out)
        +
        +	addib,<>	-1,$cnt,Loop
        +	addi		4,$out,$out
        +
        +	bv		($rp)
        +	.EXIT
        +	sub		$rv,$cnt,$rv
        +	.PROCEND
        +
        +	.EXPORT	OPENSSL_instrument_bus2,ENTRY,ARGW0=GR,ARGW1=GR
        +	.ALIGN	8
        +OPENSSL_instrument_bus2
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	copy		$cnt,$rv
        +	sub		%r0,$cnt,$cnt
        +
        +	mfctl		%cr16,$tick
        +	copy		$tick,$lasttick
        +	ldi		0,$diff
        +
        +	fdc		0($out)
        +	ldw		0($out),$tick
        +	add		$diff,$tick,$tick
        +	stw		$tick,0($out)
        +
        +	mfctl		%cr16,$tick
        +	sub		$tick,$lasttick,$diff
        +	copy		$tick,$lasttick
        +Loop2
        +	copy		$diff,$lastdiff
        +	fdc		0($out)
        +	ldw		0($out),$tick
        +	add		$diff,$tick,$tick
        +	stw		$tick,0($out)
        +
        +	addib,=		-1,$max,Ldone2
        +	nop
        +
        +	mfctl		%cr16,$tick
        +	sub		$tick,$lasttick,$diff
        +	copy		$tick,$lasttick
        +	cmpclr,<>	$lastdiff,$diff,$tick
        +	ldi		1,$tick
        +
        +	ldi		1,%r1
        +	xor		%r1,$tick,$tick
        +	addb,<>		$tick,$cnt,Loop2
        +	shladd,l	$tick,2,$out,$out
        +Ldone2
        +	bv		($rp)
        +	.EXIT
        +	add		$rv,$cnt,$rv
        +	.PROCEND
        +___
        +}
        +$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4);
        +$code =~ s/,\*/,/gm if ($SIZE_T==4);
        +print $code;
        +close STDOUT;
        +
        diff --git a/vendor/openssl/openssl/crypto/pem/Makefile b/vendor/openssl/openssl/crypto/pem/Makefile
        new file mode 100644
        index 000000000..2cc780152
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/Makefile
        @@ -0,0 +1,258 @@
        +#
        +# OpenSSL/crypto/pem/Makefile
        +#
        +
        +DIR=	pem
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= pem_sign.c pem_seal.c pem_info.c pem_lib.c pem_all.c pem_err.c \
        +	pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c pvkfmt.c
        +
        +LIBOBJ=	pem_sign.o pem_seal.o pem_info.o pem_lib.o pem_all.o pem_err.o \
        +	pem_x509.o pem_xaux.o pem_oth.o pem_pk8.o pem_pkey.o pvkfmt.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= pem.h pem2.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links: $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +pem_all.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_all.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +pem_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +pem_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +pem_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +pem_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +pem_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +pem_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_all.c
        +pem_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +pem_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +pem_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pem_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pem_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pem_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pem_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pem_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_err.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pem_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_err.o: ../../include/openssl/x509_vfy.h pem_err.c
        +pem_info.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_info.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_info.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +pem_info.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pem_info.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pem_info.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pem_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pem_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pem_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_info.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +pem_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pem_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pem_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pem_info.o: ../cryptlib.h pem_info.c
        +pem_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
        +pem_lib.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
        +pem_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +pem_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pem_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pem_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pem_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_lib.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_lib.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +pem_lib.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +pem_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +pem_lib.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
        +pem_lib.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +pem_lib.o: pem_lib.c
        +pem_oth.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_oth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_oth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_oth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_oth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_oth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_oth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_oth.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +pem_oth.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +pem_oth.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +pem_oth.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +pem_oth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_oth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_oth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_oth.c
        +pem_pk8.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_pk8.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_pk8.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_pk8.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_pk8.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_pk8.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_pk8.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_pk8.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +pem_pk8.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +pem_pk8.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
        +pem_pk8.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +pem_pk8.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pem_pk8.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pem_pk8.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pem_pk8.o: ../cryptlib.h pem_pk8.c
        +pem_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +pem_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pem_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pem_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pem_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_pkey.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_pkey.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +pem_pkey.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +pem_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_pkey.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
        +pem_pkey.o: pem_pkey.c
        +pem_seal.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_seal.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_seal.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_seal.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_seal.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_seal.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_seal.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_seal.o: ../../include/openssl/opensslconf.h
        +pem_seal.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_seal.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_seal.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +pem_seal.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +pem_seal.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_seal.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_seal.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_seal.c
        +pem_sign.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_sign.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_sign.o: ../../include/openssl/opensslconf.h
        +pem_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_sign.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +pem_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pem_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pem_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pem_sign.o: ../cryptlib.h pem_sign.c
        +pem_x509.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_x509.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_x509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_x509.o: ../../include/openssl/opensslconf.h
        +pem_x509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_x509.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_x509.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pem_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_x509.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_x509.c
        +pem_xaux.o: ../../e_os.h ../../include/openssl/asn1.h
        +pem_xaux.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pem_xaux.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pem_xaux.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pem_xaux.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pem_xaux.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pem_xaux.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pem_xaux.o: ../../include/openssl/opensslconf.h
        +pem_xaux.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pem_xaux.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pem_xaux.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pem_xaux.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pem_xaux.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pem_xaux.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_xaux.c
        +pvkfmt.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +pvkfmt.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +pvkfmt.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +pvkfmt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pvkfmt.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pvkfmt.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pvkfmt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pvkfmt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pvkfmt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pvkfmt.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pvkfmt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +pvkfmt.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +pvkfmt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pvkfmt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pvkfmt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pvkfmt.c
        diff --git a/vendor/openssl/openssl/crypto/pem/message b/vendor/openssl/openssl/crypto/pem/message
        new file mode 100644
        index 000000000..e8bf9d759
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/message
        @@ -0,0 +1,16 @@
        +-----BEGIN PRIVACY-ENHANCED MESSAGE-----
        +Proc-Type: 4,ENCRYPTED
        +Proc-Type: 4,MIC-ONLY
        +Proc-Type: 4,MIC-CLEAR
        +Content-Domain: RFC822
        +DEK-Info: DES-CBC,0123456789abcdef
        +Originator-Certificate
        + xxxx
        +Issuer-Certificate
        + xxxx
        +MIC-Info: RSA-MD5,RSA,
        + xxxx
        +
        +
        +-----END PRIVACY-ENHANCED MESSAGE-----
        +
        diff --git a/vendor/openssl/openssl/crypto/pem/pem.h b/vendor/openssl/openssl/crypto/pem/pem.h
        new file mode 100644
        index 000000000..8a6ababe3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem.h
        @@ -0,0 +1,641 @@
        +/* crypto/pem/pem.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_PEM_H
        +#define HEADER_PEM_H
        +
        +#include <openssl/e_os2.h>
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#ifndef OPENSSL_NO_STACK
        +#include <openssl/stack.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem2.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#define PEM_BUFSIZE		1024
        +
        +#define PEM_OBJ_UNDEF		0
        +#define PEM_OBJ_X509		1
        +#define PEM_OBJ_X509_REQ	2
        +#define PEM_OBJ_CRL		3
        +#define PEM_OBJ_SSL_SESSION	4
        +#define PEM_OBJ_PRIV_KEY	10
        +#define PEM_OBJ_PRIV_RSA	11
        +#define PEM_OBJ_PRIV_DSA	12
        +#define PEM_OBJ_PRIV_DH		13
        +#define PEM_OBJ_PUB_RSA		14
        +#define PEM_OBJ_PUB_DSA		15
        +#define PEM_OBJ_PUB_DH		16
        +#define PEM_OBJ_DHPARAMS	17
        +#define PEM_OBJ_DSAPARAMS	18
        +#define PEM_OBJ_PRIV_RSA_PUBLIC	19
        +#define PEM_OBJ_PRIV_ECDSA	20
        +#define PEM_OBJ_PUB_ECDSA	21
        +#define PEM_OBJ_ECPARAMETERS	22
        +
        +#define PEM_ERROR		30
        +#define PEM_DEK_DES_CBC         40
        +#define PEM_DEK_IDEA_CBC        45
        +#define PEM_DEK_DES_EDE         50
        +#define PEM_DEK_DES_ECB         60
        +#define PEM_DEK_RSA             70
        +#define PEM_DEK_RSA_MD2         80
        +#define PEM_DEK_RSA_MD5         90
        +
        +#define PEM_MD_MD2		NID_md2
        +#define PEM_MD_MD5		NID_md5
        +#define PEM_MD_SHA		NID_sha
        +#define PEM_MD_MD2_RSA		NID_md2WithRSAEncryption
        +#define PEM_MD_MD5_RSA		NID_md5WithRSAEncryption
        +#define PEM_MD_SHA_RSA		NID_sha1WithRSAEncryption
        +
        +#define PEM_STRING_X509_OLD	"X509 CERTIFICATE"
        +#define PEM_STRING_X509		"CERTIFICATE"
        +#define PEM_STRING_X509_PAIR	"CERTIFICATE PAIR"
        +#define PEM_STRING_X509_TRUSTED	"TRUSTED CERTIFICATE"
        +#define PEM_STRING_X509_REQ_OLD	"NEW CERTIFICATE REQUEST"
        +#define PEM_STRING_X509_REQ	"CERTIFICATE REQUEST"
        +#define PEM_STRING_X509_CRL	"X509 CRL"
        +#define PEM_STRING_EVP_PKEY	"ANY PRIVATE KEY"
        +#define PEM_STRING_PUBLIC	"PUBLIC KEY"
        +#define PEM_STRING_RSA		"RSA PRIVATE KEY"
        +#define PEM_STRING_RSA_PUBLIC	"RSA PUBLIC KEY"
        +#define PEM_STRING_DSA		"DSA PRIVATE KEY"
        +#define PEM_STRING_DSA_PUBLIC	"DSA PUBLIC KEY"
        +#define PEM_STRING_PKCS7	"PKCS7"
        +#define PEM_STRING_PKCS7_SIGNED	"PKCS #7 SIGNED DATA"
        +#define PEM_STRING_PKCS8	"ENCRYPTED PRIVATE KEY"
        +#define PEM_STRING_PKCS8INF	"PRIVATE KEY"
        +#define PEM_STRING_DHPARAMS	"DH PARAMETERS"
        +#define PEM_STRING_SSL_SESSION	"SSL SESSION PARAMETERS"
        +#define PEM_STRING_DSAPARAMS	"DSA PARAMETERS"
        +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
        +#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
        +#define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
        +#define PEM_STRING_PARAMETERS	"PARAMETERS"
        +#define PEM_STRING_CMS		"CMS"
        +
        +  /* Note that this structure is initialised by PEM_SealInit and cleaned up
        +     by PEM_SealFinal (at least for now) */
        +typedef struct PEM_Encode_Seal_st
        +	{
        +	EVP_ENCODE_CTX encode;
        +	EVP_MD_CTX md;
        +	EVP_CIPHER_CTX cipher;
        +	} PEM_ENCODE_SEAL_CTX;
        +
        +/* enc_type is one off */
        +#define PEM_TYPE_ENCRYPTED      10
        +#define PEM_TYPE_MIC_ONLY       20
        +#define PEM_TYPE_MIC_CLEAR      30
        +#define PEM_TYPE_CLEAR		40
        +
        +typedef struct pem_recip_st
        +	{
        +	char *name;
        +	X509_NAME *dn;
        +
        +	int cipher;
        +	int key_enc;
        +	/*	char iv[8]; unused and wrong size */
        +	} PEM_USER;
        +
        +typedef struct pem_ctx_st
        +	{
        +	int type;		/* what type of object */
        +
        +	struct	{
        +		int version;	
        +		int mode;		
        +		} proc_type;
        +
        +	char *domain;
        +
        +	struct	{
        +		int cipher;
        +	/* unused, and wrong size
        +	   unsigned char iv[8]; */
        +		} DEK_info;
        +		
        +	PEM_USER *originator;
        +
        +	int num_recipient;
        +	PEM_USER **recipient;
        +
        +	/* XXX(ben): don#t think this is used! 
        +		STACK *x509_chain;	/ * certificate chain */
        +	EVP_MD *md;		/* signature type */
        +
        +	int md_enc;		/* is the md encrypted or not? */
        +	int md_len;		/* length of md_data */
        +	char *md_data;		/* message digest, could be pkey encrypted */
        +
        +	EVP_CIPHER *dec;	/* date encryption cipher */
        +	int key_len;		/* key length */
        +	unsigned char *key;	/* key */
        +	/* unused, and wrong size
        +	   unsigned char iv[8]; */
        +
        +	
        +	int  data_enc;		/* is the data encrypted */
        +	int data_len;
        +	unsigned char *data;
        +	} PEM_CTX;
        +
        +/* These macros make the PEM_read/PEM_write functions easier to maintain and
        + * write. Now they are all implemented with either:
        + * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...)
        + */
        +
        +#ifdef OPENSSL_NO_FP_API
        +
        +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
        +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
        +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
        +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
        +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
        +
        +#else
        +
        +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
        +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
        +{ \
        +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
        +} 
        +
        +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
        +int PEM_write_##name(FILE *fp, type *x) \
        +{ \
        +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
        +}
        +
        +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
        +int PEM_write_##name(FILE *fp, const type *x) \
        +{ \
        +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
        +}
        +
        +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
        +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, \
        +		  void *u) \
        +	{ \
        +	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
        +	}
        +
        +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
        +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, \
        +		  void *u) \
        +	{ \
        +	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
        +	}
        +
        +#endif
        +
        +#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
        +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
        +{ \
        +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
        +}
        +
        +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
        +int PEM_write_bio_##name(BIO *bp, type *x) \
        +{ \
        +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
        +}
        +
        +#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
        +int PEM_write_bio_##name(BIO *bp, const type *x) \
        +{ \
        +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
        +}
        +
        +#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
        +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
        +	{ \
        +	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
        +	}
        +
        +#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
        +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
        +	{ \
        +	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
        +	}
        +
        +#define IMPLEMENT_PEM_write(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_fp(name, type, str, asn1) 
        +
        +#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) 
        +
        +#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) 
        +
        +#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) 
        +
        +#define IMPLEMENT_PEM_read(name, type, str, asn1) \
        +	IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
        +	IMPLEMENT_PEM_read_fp(name, type, str, asn1) 
        +
        +#define IMPLEMENT_PEM_rw(name, type, str, asn1) \
        +	IMPLEMENT_PEM_read(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write(name, type, str, asn1)
        +
        +#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
        +	IMPLEMENT_PEM_read(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_const(name, type, str, asn1)
        +
        +#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
        +	IMPLEMENT_PEM_read(name, type, str, asn1) \
        +	IMPLEMENT_PEM_write_cb(name, type, str, asn1)
        +
        +/* These are the same except they are for the declarations */
        +
        +#if defined(OPENSSL_NO_FP_API)
        +
        +#define DECLARE_PEM_read_fp(name, type) /**/
        +#define DECLARE_PEM_write_fp(name, type) /**/
        +#define DECLARE_PEM_write_cb_fp(name, type) /**/
        +
        +#else
        +
        +#define DECLARE_PEM_read_fp(name, type) \
        +	type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
        +
        +#define DECLARE_PEM_write_fp(name, type) \
        +	int PEM_write_##name(FILE *fp, type *x);
        +
        +#define DECLARE_PEM_write_fp_const(name, type) \
        +	int PEM_write_##name(FILE *fp, const type *x);
        +
        +#define DECLARE_PEM_write_cb_fp(name, type) \
        +	int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +#define DECLARE_PEM_read_bio(name, type) \
        +	type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
        +
        +#define DECLARE_PEM_write_bio(name, type) \
        +	int PEM_write_bio_##name(BIO *bp, type *x);
        +
        +#define DECLARE_PEM_write_bio_const(name, type) \
        +	int PEM_write_bio_##name(BIO *bp, const type *x);
        +
        +#define DECLARE_PEM_write_cb_bio(name, type) \
        +	int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
        +
        +#else
        +
        +#define DECLARE_PEM_read_bio(name, type) /**/
        +#define DECLARE_PEM_write_bio(name, type) /**/
        +#define DECLARE_PEM_write_bio_const(name, type) /**/
        +#define DECLARE_PEM_write_cb_bio(name, type) /**/
        +
        +#endif
        +
        +#define DECLARE_PEM_write(name, type) \
        +	DECLARE_PEM_write_bio(name, type) \
        +	DECLARE_PEM_write_fp(name, type) 
        +
        +#define DECLARE_PEM_write_const(name, type) \
        +	DECLARE_PEM_write_bio_const(name, type) \
        +	DECLARE_PEM_write_fp_const(name, type)
        +
        +#define DECLARE_PEM_write_cb(name, type) \
        +	DECLARE_PEM_write_cb_bio(name, type) \
        +	DECLARE_PEM_write_cb_fp(name, type) 
        +
        +#define DECLARE_PEM_read(name, type) \
        +	DECLARE_PEM_read_bio(name, type) \
        +	DECLARE_PEM_read_fp(name, type)
        +
        +#define DECLARE_PEM_rw(name, type) \
        +	DECLARE_PEM_read(name, type) \
        +	DECLARE_PEM_write(name, type)
        +
        +#define DECLARE_PEM_rw_const(name, type) \
        +	DECLARE_PEM_read(name, type) \
        +	DECLARE_PEM_write_const(name, type)
        +
        +#define DECLARE_PEM_rw_cb(name, type) \
        +	DECLARE_PEM_read(name, type) \
        +	DECLARE_PEM_write_cb(name, type)
        +
        +#if 1
        +/* "userdata": new with OpenSSL 0.9.4 */
        +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
        +#else
        +/* OpenSSL 0.9.3, 0.9.3a */
        +typedef int pem_password_cb(char *buf, int size, int rwflag);
        +#endif
        +
        +int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
        +int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
        +	pem_password_cb *callback,void *u);
        +
        +#ifndef OPENSSL_NO_BIO
        +int	PEM_read_bio(BIO *bp, char **name, char **header,
        +		unsigned char **data,long *len);
        +int	PEM_write_bio(BIO *bp,const char *name,char *hdr,unsigned char *data,
        +		long len);
        +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
        +	     pem_password_cb *cb, void *u);
        +void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
        +			  void **x, pem_password_cb *cb, void *u);
        +int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x,
        +			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
        +			   pem_password_cb *cb, void *u);
        +
        +STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
        +int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
        +		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
        +#endif
        +
        +int	PEM_read(FILE *fp, char **name, char **header,
        +		unsigned char **data,long *len);
        +int	PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
        +void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
        +		      pem_password_cb *cb, void *u);
        +int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
        +		       void *x,const EVP_CIPHER *enc,unsigned char *kstr,
        +		       int klen,pem_password_cb *callback, void *u);
        +STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
        +	pem_password_cb *cb, void *u);
        +
        +int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
        +		EVP_MD *md_type, unsigned char **ek, int *ekl,
        +		unsigned char *iv, EVP_PKEY **pubk, int npubk);
        +void	PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
        +		unsigned char *in, int inl);
        +int	PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl,
        +		unsigned char *out, int *outl, EVP_PKEY *priv);
        +
        +void    PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
        +void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
        +int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
        +		unsigned int *siglen, EVP_PKEY *pkey);
        +
        +int	PEM_def_callback(char *buf, int num, int w, void *key);
        +void	PEM_proc_type(char *buf, int type);
        +void	PEM_dek_info(char *buf, const char *type, int len, char *str);
        +
        +
        +#include <openssl/symhacks.h>
        +
        +DECLARE_PEM_rw(X509, X509)
        +
        +DECLARE_PEM_rw(X509_AUX, X509)
        +
        +DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
        +
        +DECLARE_PEM_rw(X509_REQ, X509_REQ)
        +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
        +
        +DECLARE_PEM_rw(X509_CRL, X509_CRL)
        +
        +DECLARE_PEM_rw(PKCS7, PKCS7)
        +
        +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
        +
        +DECLARE_PEM_rw(PKCS8, X509_SIG)
        +
        +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
        +
        +DECLARE_PEM_rw_const(RSAPublicKey, RSA)
        +DECLARE_PEM_rw(RSA_PUBKEY, RSA)
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +
        +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
        +
        +DECLARE_PEM_rw(DSA_PUBKEY, DSA)
        +
        +DECLARE_PEM_rw_const(DSAparams, DSA)
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
        +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
        +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +
        +DECLARE_PEM_rw_const(DHparams, DH)
        +
        +#endif
        +
        +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
        +
        +DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
        +
        +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
        +                                  char *, int, pem_password_cb *, void *);
        +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
        +
        +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +
        +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
        +
        +int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
        +			      char *kstr,int klen, pem_password_cb *cd, void *u);
        +
        +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
        +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
        +
        +
        +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
        +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
        +EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
        +EVP_PKEY *b2i_PublicKey_bio(BIO *in);
        +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
        +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
        +#ifndef OPENSSL_NO_RC4
        +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
        +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
        +		pem_password_cb *cb, void *u);
        +#endif
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_PEM_strings(void);
        +
        +/* Error codes for the PEM functions. */
        +
        +/* Function codes. */
        +#define PEM_F_B2I_DSS					 127
        +#define PEM_F_B2I_PVK_BIO				 128
        +#define PEM_F_B2I_RSA					 129
        +#define PEM_F_CHECK_BITLEN_DSA				 130
        +#define PEM_F_CHECK_BITLEN_RSA				 131
        +#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO			 120
        +#define PEM_F_D2I_PKCS8PRIVATEKEY_FP			 121
        +#define PEM_F_DO_B2I					 132
        +#define PEM_F_DO_B2I_BIO				 133
        +#define PEM_F_DO_BLOB_HEADER				 134
        +#define PEM_F_DO_PK8PKEY				 126
        +#define PEM_F_DO_PK8PKEY_FP				 125
        +#define PEM_F_DO_PVK_BODY				 135
        +#define PEM_F_DO_PVK_HEADER				 136
        +#define PEM_F_I2B_PVK					 137
        +#define PEM_F_I2B_PVK_BIO				 138
        +#define PEM_F_LOAD_IV					 101
        +#define PEM_F_PEM_ASN1_READ				 102
        +#define PEM_F_PEM_ASN1_READ_BIO				 103
        +#define PEM_F_PEM_ASN1_WRITE				 104
        +#define PEM_F_PEM_ASN1_WRITE_BIO			 105
        +#define PEM_F_PEM_DEF_CALLBACK				 100
        +#define PEM_F_PEM_DO_HEADER				 106
        +#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY		 118
        +#define PEM_F_PEM_GET_EVP_CIPHER_INFO			 107
        +#define PEM_F_PEM_PK8PKEY				 119
        +#define PEM_F_PEM_READ					 108
        +#define PEM_F_PEM_READ_BIO				 109
        +#define PEM_F_PEM_READ_BIO_PARAMETERS			 140
        +#define PEM_F_PEM_READ_BIO_PRIVATEKEY			 123
        +#define PEM_F_PEM_READ_PRIVATEKEY			 124
        +#define PEM_F_PEM_SEALFINAL				 110
        +#define PEM_F_PEM_SEALINIT				 111
        +#define PEM_F_PEM_SIGNFINAL				 112
        +#define PEM_F_PEM_WRITE					 113
        +#define PEM_F_PEM_WRITE_BIO				 114
        +#define PEM_F_PEM_WRITE_PRIVATEKEY			 139
        +#define PEM_F_PEM_X509_INFO_READ			 115
        +#define PEM_F_PEM_X509_INFO_READ_BIO			 116
        +#define PEM_F_PEM_X509_INFO_WRITE_BIO			 117
        +
        +/* Reason codes. */
        +#define PEM_R_BAD_BASE64_DECODE				 100
        +#define PEM_R_BAD_DECRYPT				 101
        +#define PEM_R_BAD_END_LINE				 102
        +#define PEM_R_BAD_IV_CHARS				 103
        +#define PEM_R_BAD_MAGIC_NUMBER				 116
        +#define PEM_R_BAD_PASSWORD_READ				 104
        +#define PEM_R_BAD_VERSION_NUMBER			 117
        +#define PEM_R_BIO_WRITE_FAILURE				 118
        +#define PEM_R_CIPHER_IS_NULL				 127
        +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY		 115
        +#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB		 119
        +#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB			 120
        +#define PEM_R_INCONSISTENT_HEADER			 121
        +#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR		 122
        +#define PEM_R_KEYBLOB_TOO_SHORT				 123
        +#define PEM_R_NOT_DEK_INFO				 105
        +#define PEM_R_NOT_ENCRYPTED				 106
        +#define PEM_R_NOT_PROC_TYPE				 107
        +#define PEM_R_NO_START_LINE				 108
        +#define PEM_R_PROBLEMS_GETTING_PASSWORD			 109
        +#define PEM_R_PUBLIC_KEY_NO_RSA				 110
        +#define PEM_R_PVK_DATA_TOO_SHORT			 124
        +#define PEM_R_PVK_TOO_SHORT				 125
        +#define PEM_R_READ_KEY					 111
        +#define PEM_R_SHORT_HEADER				 112
        +#define PEM_R_UNSUPPORTED_CIPHER			 113
        +#define PEM_R_UNSUPPORTED_ENCRYPTION			 114
        +#define PEM_R_UNSUPPORTED_KEY_COMPONENTS		 126
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pem/pem2.h b/vendor/openssl/openssl/crypto/pem/pem2.h
        new file mode 100644
        index 000000000..f31790d69
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem2.h
        @@ -0,0 +1,70 @@
        +/* ====================================================================
        + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +/*
        + * This header only exists to break a circular dependency between pem and err
        + * Ben 30 Jan 1999.
        + */
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifndef HEADER_PEM_H
        +void ERR_load_PEM_strings(void);
        +#endif
        +
        +#ifdef __cplusplus
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_all.c b/vendor/openssl/openssl/crypto/pem/pem_all.c
        new file mode 100644
        index 000000000..eac0460e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_all.c
        @@ -0,0 +1,457 @@
        +/* crypto/pem/pem_all.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-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/pem.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
        +#endif
        +
        +IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
        +
        +IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
        +
        +IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
        +
        +IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
        +
        +IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
        +					PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
        +
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +/* We treat RSA or DSA private keys as a special case.
        + *
        + * For private keys we read in an EVP_PKEY structure with
        + * PEM_read_bio_PrivateKey() and extract the relevant private
        + * key: this means can handle "traditional" and PKCS#8 formats
        + * transparently.
        + */
        +
        +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
        +{
        +	RSA *rtmp;
        +	if(!key) return NULL;
        +	rtmp = EVP_PKEY_get1_RSA(key);
        +	EVP_PKEY_free(key);
        +	if(!rtmp) return NULL;
        +	if(rsa) {
        +		RSA_free(*rsa);
        +		*rsa = rtmp;
        +	}
        +	return rtmp;
        +}
        +
        +RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
        +								void *u)
        +{
        +	EVP_PKEY *pktmp;
        +	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
        +	return pkey_get_rsa(pktmp, rsa);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +
        +RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
        +								void *u)
        +{
        +	EVP_PKEY *pktmp;
        +	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
        +	return pkey_get_rsa(pktmp, rsa);
        +}
        +
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +
        +int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +{
        +	if (FIPS_mode())
        +		{
        +		EVP_PKEY *k;
        +		int ret;
        +		k = EVP_PKEY_new();
        +		if (!k)
        +			return 0;
        +		EVP_PKEY_set1_RSA(k, x);
        +
        +		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
        +		EVP_PKEY_free(k);
        +		return ret;
        +		}
        +	else
        +		return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
        +					PEM_STRING_RSA,bp,x,enc,kstr,klen,cb,u);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +{
        +	if (FIPS_mode())
        +		{
        +		EVP_PKEY *k;
        +		int ret;
        +		k = EVP_PKEY_new();
        +		if (!k)
        +			return 0;
        +
        +		EVP_PKEY_set1_RSA(k, x);
        +
        +		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
        +		EVP_PKEY_free(k);
        +		return ret;
        +		}
        +	else
        +		return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
        +					PEM_STRING_RSA,fp,x,enc,kstr,klen,cb,u);
        +}
        +#endif
        +
        +#else
        +
        +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
        +
        +#endif
        +
        +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
        +IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +
        +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
        +{
        +	DSA *dtmp;
        +	if(!key) return NULL;
        +	dtmp = EVP_PKEY_get1_DSA(key);
        +	EVP_PKEY_free(key);
        +	if(!dtmp) return NULL;
        +	if(dsa) {
        +		DSA_free(*dsa);
        +		*dsa = dtmp;
        +	}
        +	return dtmp;
        +}
        +
        +DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
        +								void *u)
        +{
        +	EVP_PKEY *pktmp;
        +	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
        +	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
        +}
        +
        +#ifdef OPENSSL_FIPS
        +
        +int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +{
        +	if (FIPS_mode())
        +		{
        +		EVP_PKEY *k;
        +		int ret;
        +		k = EVP_PKEY_new();
        +		if (!k)
        +			return 0;
        +		EVP_PKEY_set1_DSA(k, x);
        +
        +		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
        +		EVP_PKEY_free(k);
        +		return ret;
        +		}
        +	else
        +		return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
        +					PEM_STRING_DSA,bp,x,enc,kstr,klen,cb,u);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +{
        +	if (FIPS_mode())
        +		{
        +		EVP_PKEY *k;
        +		int ret;
        +		k = EVP_PKEY_new();
        +		if (!k)
        +			return 0;
        +		EVP_PKEY_set1_DSA(k, x);
        +		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
        +		EVP_PKEY_free(k);
        +		return ret;
        +		}
        +	else
        +		return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
        +					PEM_STRING_DSA,fp,x,enc,kstr,klen,cb,u);
        +}
        +#endif
        +
        +#else
        +
        +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
        +
        +#endif
        +
        +IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
        +
        +#ifndef OPENSSL_NO_FP_API
        +
        +DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
        +								void *u)
        +{
        +	EVP_PKEY *pktmp;
        +	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
        +	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
        +}
        +
        +#endif
        +
        +IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
        +
        +#endif
        +
        +
        +#ifndef OPENSSL_NO_EC
        +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
        +{
        +	EC_KEY *dtmp;
        +	if(!key) return NULL;
        +	dtmp = EVP_PKEY_get1_EC_KEY(key);
        +	EVP_PKEY_free(key);
        +	if(!dtmp) return NULL;
        +	if(eckey) 
        +	{
        + 		EC_KEY_free(*eckey);
        +		*eckey = dtmp;
        +	}
        +	return dtmp;
        +}
        +
        +EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
        +							void *u)
        +{
        +	EVP_PKEY *pktmp;
        +	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
        +	return pkey_get_eckey(pktmp, key);	/* will free pktmp */
        +}
        +
        +IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
        +
        +
        +
        +#ifdef OPENSSL_FIPS
        +
        +int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +{
        +	if (FIPS_mode())
        +		{
        +		EVP_PKEY *k;
        +		int ret;
        +		k = EVP_PKEY_new();
        +		if (!k)
        +			return 0;
        +		EVP_PKEY_set1_EC_KEY(k, x);
        +
        +		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
        +		EVP_PKEY_free(k);
        +		return ret;
        +		}
        +	else
        +		return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
        +						PEM_STRING_ECPRIVATEKEY,
        +						bp,x,enc,kstr,klen,cb,u);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +{
        +	if (FIPS_mode())
        +		{
        +		EVP_PKEY *k;
        +		int ret;
        +		k = EVP_PKEY_new();
        +		if (!k)
        +			return 0;
        +		EVP_PKEY_set1_EC_KEY(k, x);
        +		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
        +		EVP_PKEY_free(k);
        +		return ret;
        +		}
        +	else
        +		return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
        +						PEM_STRING_ECPRIVATEKEY,
        +						fp,x,enc,kstr,klen,cb,u);
        +}
        +#endif
        +
        +#else
        +
        +IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
        +
        +#endif
        +
        +IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
        +
        +#ifndef OPENSSL_NO_FP_API
        + 
        +EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
        + 								void *u)
        +{
        +	EVP_PKEY *pktmp;
        +	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
        +	return pkey_get_eckey(pktmp, eckey);	/* will free pktmp */
        +}
        +
        +#endif
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +
        +IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
        +
        +#endif
        +
        +IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_err.c b/vendor/openssl/openssl/crypto/pem/pem_err.c
        new file mode 100644
        index 000000000..d644aeedd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_err.c
        @@ -0,0 +1,161 @@
        +/* crypto/pem/pem_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
        +
        +static ERR_STRING_DATA PEM_str_functs[]=
        +	{
        +{ERR_FUNC(PEM_F_B2I_DSS),	"B2I_DSS"},
        +{ERR_FUNC(PEM_F_B2I_PVK_BIO),	"b2i_PVK_bio"},
        +{ERR_FUNC(PEM_F_B2I_RSA),	"B2I_RSA"},
        +{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA),	"CHECK_BITLEN_DSA"},
        +{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA),	"CHECK_BITLEN_RSA"},
        +{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO),	"d2i_PKCS8PrivateKey_bio"},
        +{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP),	"d2i_PKCS8PrivateKey_fp"},
        +{ERR_FUNC(PEM_F_DO_B2I),	"DO_B2I"},
        +{ERR_FUNC(PEM_F_DO_B2I_BIO),	"DO_B2I_BIO"},
        +{ERR_FUNC(PEM_F_DO_BLOB_HEADER),	"DO_BLOB_HEADER"},
        +{ERR_FUNC(PEM_F_DO_PK8PKEY),	"DO_PK8PKEY"},
        +{ERR_FUNC(PEM_F_DO_PK8PKEY_FP),	"DO_PK8PKEY_FP"},
        +{ERR_FUNC(PEM_F_DO_PVK_BODY),	"DO_PVK_BODY"},
        +{ERR_FUNC(PEM_F_DO_PVK_HEADER),	"DO_PVK_HEADER"},
        +{ERR_FUNC(PEM_F_I2B_PVK),	"I2B_PVK"},
        +{ERR_FUNC(PEM_F_I2B_PVK_BIO),	"i2b_PVK_bio"},
        +{ERR_FUNC(PEM_F_LOAD_IV),	"LOAD_IV"},
        +{ERR_FUNC(PEM_F_PEM_ASN1_READ),	"PEM_ASN1_read"},
        +{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO),	"PEM_ASN1_read_bio"},
        +{ERR_FUNC(PEM_F_PEM_ASN1_WRITE),	"PEM_ASN1_write"},
        +{ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO),	"PEM_ASN1_write_bio"},
        +{ERR_FUNC(PEM_F_PEM_DEF_CALLBACK),	"PEM_def_callback"},
        +{ERR_FUNC(PEM_F_PEM_DO_HEADER),	"PEM_do_header"},
        +{ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY),	"PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
        +{ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO),	"PEM_get_EVP_CIPHER_INFO"},
        +{ERR_FUNC(PEM_F_PEM_PK8PKEY),	"PEM_PK8PKEY"},
        +{ERR_FUNC(PEM_F_PEM_READ),	"PEM_read"},
        +{ERR_FUNC(PEM_F_PEM_READ_BIO),	"PEM_read_bio"},
        +{ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS),	"PEM_read_bio_Parameters"},
        +{ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY),	"PEM_READ_BIO_PRIVATEKEY"},
        +{ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY),	"PEM_READ_PRIVATEKEY"},
        +{ERR_FUNC(PEM_F_PEM_SEALFINAL),	"PEM_SealFinal"},
        +{ERR_FUNC(PEM_F_PEM_SEALINIT),	"PEM_SealInit"},
        +{ERR_FUNC(PEM_F_PEM_SIGNFINAL),	"PEM_SignFinal"},
        +{ERR_FUNC(PEM_F_PEM_WRITE),	"PEM_write"},
        +{ERR_FUNC(PEM_F_PEM_WRITE_BIO),	"PEM_write_bio"},
        +{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY),	"PEM_WRITE_PRIVATEKEY"},
        +{ERR_FUNC(PEM_F_PEM_X509_INFO_READ),	"PEM_X509_INFO_read"},
        +{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO),	"PEM_X509_INFO_read_bio"},
        +{ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO),	"PEM_X509_INFO_write_bio"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA PEM_str_reasons[]=
        +	{
        +{ERR_REASON(PEM_R_BAD_BASE64_DECODE)     ,"bad base64 decode"},
        +{ERR_REASON(PEM_R_BAD_DECRYPT)           ,"bad decrypt"},
        +{ERR_REASON(PEM_R_BAD_END_LINE)          ,"bad end line"},
        +{ERR_REASON(PEM_R_BAD_IV_CHARS)          ,"bad iv chars"},
        +{ERR_REASON(PEM_R_BAD_MAGIC_NUMBER)      ,"bad magic number"},
        +{ERR_REASON(PEM_R_BAD_PASSWORD_READ)     ,"bad password read"},
        +{ERR_REASON(PEM_R_BAD_VERSION_NUMBER)    ,"bad version number"},
        +{ERR_REASON(PEM_R_BIO_WRITE_FAILURE)     ,"bio write failure"},
        +{ERR_REASON(PEM_R_CIPHER_IS_NULL)        ,"cipher is null"},
        +{ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),"error converting private key"},
        +{ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),"expecting private key blob"},
        +{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),"expecting public key blob"},
        +{ERR_REASON(PEM_R_INCONSISTENT_HEADER)   ,"inconsistent header"},
        +{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),"keyblob header parse error"},
        +{ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT)     ,"keyblob too short"},
        +{ERR_REASON(PEM_R_NOT_DEK_INFO)          ,"not dek info"},
        +{ERR_REASON(PEM_R_NOT_ENCRYPTED)         ,"not encrypted"},
        +{ERR_REASON(PEM_R_NOT_PROC_TYPE)         ,"not proc type"},
        +{ERR_REASON(PEM_R_NO_START_LINE)         ,"no start line"},
        +{ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),"problems getting password"},
        +{ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA)     ,"public key no rsa"},
        +{ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT)    ,"pvk data too short"},
        +{ERR_REASON(PEM_R_PVK_TOO_SHORT)         ,"pvk too short"},
        +{ERR_REASON(PEM_R_READ_KEY)              ,"read key"},
        +{ERR_REASON(PEM_R_SHORT_HEADER)          ,"short header"},
        +{ERR_REASON(PEM_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
        +{ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION),"unsupported encryption"},
        +{ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),"unsupported key components"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_PEM_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(PEM_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,PEM_str_functs);
        +		ERR_load_strings(0,PEM_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_info.c b/vendor/openssl/openssl/crypto/pem/pem_info.c
        new file mode 100644
        index 000000000..1b2be527e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_info.c
        @@ -0,0 +1,405 @@
        +/* crypto/pem/pem_info.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_FP_API
        +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
        +	{
        +        BIO *b;
        +        STACK_OF(X509_INFO) *ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_X509_INFO_READ,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=PEM_X509_INFO_read_bio(b,sk,cb,u);
        +        BIO_free(b);
        +        return(ret);
        +	}
        +#endif
        +
        +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
        +	{
        +	X509_INFO *xi=NULL;
        +	char *name=NULL,*header=NULL;
        +	void *pp;
        +	unsigned char *data=NULL;
        +	const unsigned char *p;
        +	long len,error=0;
        +	int ok=0;
        +	STACK_OF(X509_INFO) *ret=NULL;
        +	unsigned int i,raw,ptype;
        +	d2i_of_void *d2i = 0;
        +
        +	if (sk == NULL)
        +		{
        +		if ((ret=sk_X509_INFO_new_null()) == NULL)
        +			{
        +			PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	else
        +		ret=sk;
        +
        +	if ((xi=X509_INFO_new()) == NULL) goto err;
        +	for (;;)
        +		{
        +		raw=0;
        +		ptype = 0;
        +		i=PEM_read_bio(bp,&name,&header,&data,&len);
        +		if (i == 0)
        +			{
        +			error=ERR_GET_REASON(ERR_peek_last_error());
        +			if (error == PEM_R_NO_START_LINE)
        +				{
        +				ERR_clear_error();
        +				break;
        +				}
        +			goto err;
        +			}
        +start:
        +		if (	(strcmp(name,PEM_STRING_X509) == 0) ||
        +			(strcmp(name,PEM_STRING_X509_OLD) == 0))
        +			{
        +			d2i=(D2I_OF(void))d2i_X509;
        +			if (xi->x509 != NULL)
        +				{
        +				if (!sk_X509_INFO_push(ret,xi)) goto err;
        +				if ((xi=X509_INFO_new()) == NULL) goto err;
        +				goto start;
        +				}
        +			pp=&(xi->x509);
        +			}
        +		else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0))
        +			{
        +			d2i=(D2I_OF(void))d2i_X509_AUX;
        +			if (xi->x509 != NULL)
        +				{
        +				if (!sk_X509_INFO_push(ret,xi)) goto err;
        +				if ((xi=X509_INFO_new()) == NULL) goto err;
        +				goto start;
        +				}
        +			pp=&(xi->x509);
        +			}
        +		else if (strcmp(name,PEM_STRING_X509_CRL) == 0)
        +			{
        +			d2i=(D2I_OF(void))d2i_X509_CRL;
        +			if (xi->crl != NULL)
        +				{
        +				if (!sk_X509_INFO_push(ret,xi)) goto err;
        +				if ((xi=X509_INFO_new()) == NULL) goto err;
        +				goto start;
        +				}
        +			pp=&(xi->crl);
        +			}
        +		else
        +#ifndef OPENSSL_NO_RSA
        +			if (strcmp(name,PEM_STRING_RSA) == 0)
        +			{
        +			if (xi->x_pkey != NULL) 
        +				{
        +				if (!sk_X509_INFO_push(ret,xi)) goto err;
        +				if ((xi=X509_INFO_new()) == NULL) goto err;
        +				goto start;
        +				}
        +
        +			xi->enc_data=NULL;
        +			xi->enc_len=0;
        +
        +			xi->x_pkey=X509_PKEY_new();
        +			ptype=EVP_PKEY_RSA;
        +			pp=&xi->x_pkey->dec_pkey;
        +			if ((int)strlen(header) > 10) /* assume encrypted */
        +				raw=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			if (strcmp(name,PEM_STRING_DSA) == 0)
        +			{
        +			d2i=(D2I_OF(void))d2i_DSAPrivateKey;
        +			if (xi->x_pkey != NULL) 
        +				{
        +				if (!sk_X509_INFO_push(ret,xi)) goto err;
        +				if ((xi=X509_INFO_new()) == NULL) goto err;
        +				goto start;
        +				}
        +
        +			xi->enc_data=NULL;
        +			xi->enc_len=0;
        +
        +			xi->x_pkey=X509_PKEY_new();
        +			ptype = EVP_PKEY_DSA;
        +			pp=&xi->x_pkey->dec_pkey;
        +			if ((int)strlen(header) > 10) /* assume encrypted */
        +				raw=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_EC
        + 			if (strcmp(name,PEM_STRING_ECPRIVATEKEY) == 0)
        + 			{
        + 				d2i=(D2I_OF(void))d2i_ECPrivateKey;
        + 				if (xi->x_pkey != NULL) 
        + 				{
        + 					if (!sk_X509_INFO_push(ret,xi)) goto err;
        + 					if ((xi=X509_INFO_new()) == NULL) goto err;
        + 						goto start;
        + 				}
        + 
        + 			xi->enc_data=NULL;
        + 			xi->enc_len=0;
        + 
        + 			xi->x_pkey=X509_PKEY_new();
        +			ptype = EVP_PKEY_EC;
        + 			pp=&xi->x_pkey->dec_pkey;
        + 			if ((int)strlen(header) > 10) /* assume encrypted */
        + 				raw=1;
        +			}
        +		else
        +#endif
        +			{
        +			d2i=NULL;
        +			pp=NULL;
        +			}
        +
        +		if (d2i != NULL)
        +			{
        +			if (!raw)
        +				{
        +				EVP_CIPHER_INFO cipher;
        +
        +				if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))
        +					goto err;
        +				if (!PEM_do_header(&cipher,data,&len,cb,u))
        +					goto err;
        +				p=data;
        +				if (ptype)
        +					{
        +					if (!d2i_PrivateKey(ptype, pp, &p, len))
        +						{
        +						PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
        +						goto err;
        +						}
        +					}
        +				else if (d2i(pp,&p,len) == NULL)
        +					{
        +					PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
        +					goto err;
        +					}
        +				}
        +			else
        +				{ /* encrypted RSA data */
        +				if (!PEM_get_EVP_CIPHER_INFO(header,
        +					&xi->enc_cipher)) goto err;
        +				xi->enc_data=(char *)data;
        +				xi->enc_len=(int)len;
        +				data=NULL;
        +				}
        +			}
        +		else	{
        +			/* unknown */
        +			}
        +		if (name != NULL) OPENSSL_free(name);
        +		if (header != NULL) OPENSSL_free(header);
        +		if (data != NULL) OPENSSL_free(data);
        +		name=NULL;
        +		header=NULL;
        +		data=NULL;
        +		}
        +
        +	/* if the last one hasn't been pushed yet and there is anything
        +	 * in it then add it to the stack ... 
        +	 */
        +	if ((xi->x509 != NULL) || (xi->crl != NULL) ||
        +		(xi->x_pkey != NULL) || (xi->enc_data != NULL))
        +		{
        +		if (!sk_X509_INFO_push(ret,xi)) goto err;
        +		xi=NULL;
        +		}
        +	ok=1;
        +err:
        +	if (xi != NULL) X509_INFO_free(xi);
        +	if (!ok)
        +		{
        +		for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++)
        +			{
        +			xi=sk_X509_INFO_value(ret,i);
        +			X509_INFO_free(xi);
        +			}
        +		if (ret != sk) sk_X509_INFO_free(ret);
        +		ret=NULL;
        +		}
        +		
        +	if (name != NULL) OPENSSL_free(name);
        +	if (header != NULL) OPENSSL_free(header);
        +	if (data != NULL) OPENSSL_free(data);
        +	return(ret);
        +	}
        +
        +
        +/* A TJH addition */
        +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
        +	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
        +	{
        +	EVP_CIPHER_CTX ctx;
        +	int i,ret=0;
        +	unsigned char *data=NULL;
        +	const char *objstr=NULL;
        +	char buf[PEM_BUFSIZE];
        +	unsigned char *iv=NULL;
        +	
        +	if (enc != NULL)
        +		{
        +		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
        +		if (objstr == NULL)
        +			{
        +			PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
        +			goto err;
        +			}
        +		}
        +
        +	/* now for the fun part ... if we have a private key then 
        +	 * we have to be able to handle a not-yet-decrypted key
        +	 * being written out correctly ... if it is decrypted or
        +	 * it is non-encrypted then we use the base code
        +	 */
        +	if (xi->x_pkey!=NULL)
        +		{
        +		if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
        +			{
        +			if (enc == NULL)
        +				{
        +				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_CIPHER_IS_NULL);
        +				goto err;
        +				}
        +
        +			/* copy from weirdo names into more normal things */
        +			iv=xi->enc_cipher.iv;
        +			data=(unsigned char *)xi->enc_data;
        +			i=xi->enc_len;
        +
        +			/* we take the encryption data from the
        +			 * internal stuff rather than what the
        +			 * user has passed us ... as we have to 
        +			 * match exactly for some strange reason
        +			 */
        +			objstr=OBJ_nid2sn(
        +				EVP_CIPHER_nid(xi->enc_cipher.cipher));
        +			if (objstr == NULL)
        +				{
        +				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
        +				goto err;
        +				}
        +
        +			/* create the right magic header stuff */
        +			OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);
        +			buf[0]='\0';
        +			PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
        +			PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
        +
        +			/* use the normal code to write things out */
        +			i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);
        +			if (i <= 0) goto err;
        +			}
        +		else
        +			{
        +			/* Add DSA/DH */
        +#ifndef OPENSSL_NO_RSA
        +			/* normal optionally encrypted stuff */
        +			if (PEM_write_bio_RSAPrivateKey(bp,
        +				xi->x_pkey->dec_pkey->pkey.rsa,
        +				enc,kstr,klen,cb,u)<=0)
        +				goto err;
        +#endif
        +			}
        +		}
        +
        +	/* if we have a certificate then write it out now */
        +	if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0))
        +		goto err;
        +
        +	/* we are ignoring anything else that is loaded into the X509_INFO
        +	 * structure for the moment ... as I don't need it so I'm not
        +	 * coding it here and Eric can do it when this makes it into the
        +	 * base library --tjh
        +	 */
        +
        +	ret=1;
        +
        +err:
        +	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
        +	OPENSSL_cleanse(buf,PEM_BUFSIZE);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_lib.c b/vendor/openssl/openssl/crypto/pem/pem_lib.c
        new file mode 100644
        index 000000000..5a421fc4b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_lib.c
        @@ -0,0 +1,859 @@
        +/* crypto/pem/pem_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/pkcs12.h>
        +#include "asn1_locl.h"
        +#ifndef OPENSSL_NO_DES
        +#include <openssl/des.h>
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
        +
        +#define MIN_LENGTH	4
        +
        +static int load_iv(char **fromp,unsigned char *to, int num);
        +static int check_pem(const char *nm, const char *name);
        +int pem_check_suffix(const char *pem_str, const char *suffix);
        +
        +int PEM_def_callback(char *buf, int num, int w, void *key)
        +	{
        +#ifdef OPENSSL_NO_FP_API
        +	/* We should not ever call the default callback routine from
        +	 * windows. */
        +	PEMerr(PEM_F_PEM_DEF_CALLBACK,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(-1);
        +#else
        +	int i,j;
        +	const char *prompt;
        +	if(key) {
        +		i=strlen(key);
        +		i=(i > num)?num:i;
        +		memcpy(buf,key,i);
        +		return(i);
        +	}
        +
        +	prompt=EVP_get_pw_prompt();
        +	if (prompt == NULL)
        +		prompt="Enter PEM pass phrase:";
        +
        +	for (;;)
        +		{
        +		i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w);
        +		if (i != 0)
        +			{
        +			PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
        +			memset(buf,0,(unsigned int)num);
        +			return(-1);
        +			}
        +		j=strlen(buf);
        +		if (j < MIN_LENGTH)
        +			{
        +			fprintf(stderr,"phrase is too short, needs to be at least %d chars\n",MIN_LENGTH);
        +			}
        +		else
        +			break;
        +		}
        +	return(j);
        +#endif
        +	}
        +
        +void PEM_proc_type(char *buf, int type)
        +	{
        +	const char *str;
        +
        +	if (type == PEM_TYPE_ENCRYPTED)
        +		str="ENCRYPTED";
        +	else if (type == PEM_TYPE_MIC_CLEAR)
        +		str="MIC-CLEAR";
        +	else if (type == PEM_TYPE_MIC_ONLY)
        +		str="MIC-ONLY";
        +	else
        +		str="BAD-TYPE";
        +		
        +	BUF_strlcat(buf,"Proc-Type: 4,",PEM_BUFSIZE);
        +	BUF_strlcat(buf,str,PEM_BUFSIZE);
        +	BUF_strlcat(buf,"\n",PEM_BUFSIZE);
        +	}
        +
        +void PEM_dek_info(char *buf, const char *type, int len, char *str)
        +	{
        +	static const unsigned char map[17]="0123456789ABCDEF";
        +	long i;
        +	int j;
        +
        +	BUF_strlcat(buf,"DEK-Info: ",PEM_BUFSIZE);
        +	BUF_strlcat(buf,type,PEM_BUFSIZE);
        +	BUF_strlcat(buf,",",PEM_BUFSIZE);
        +	j=strlen(buf);
        +	if (j + (len * 2) + 1 > PEM_BUFSIZE)
        +        	return;
        +	for (i=0; i<len; i++)
        +		{
        +		buf[j+i*2]  =map[(str[i]>>4)&0x0f];
        +		buf[j+i*2+1]=map[(str[i]   )&0x0f];
        +		}
        +	buf[j+i*2]='\n';
        +	buf[j+i*2+1]='\0';
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
        +		    pem_password_cb *cb, void *u)
        +	{
        +        BIO *b;
        +        void *ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=PEM_ASN1_read_bio(d2i,name,b,x,cb,u);
        +        BIO_free(b);
        +        return(ret);
        +	}
        +#endif
        +
        +static int check_pem(const char *nm, const char *name)
        +{
        +	/* Normal matching nm and name */
        +	if (!strcmp(nm,name)) return 1;
        +
        +	/* Make PEM_STRING_EVP_PKEY match any private key */
        +
        +	if(!strcmp(name,PEM_STRING_EVP_PKEY))
        +		{
        +		int slen;
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +		if(!strcmp(nm,PEM_STRING_PKCS8))
        +			return 1;
        +		if(!strcmp(nm,PEM_STRING_PKCS8INF))
        +			return 1;
        +		slen = pem_check_suffix(nm, "PRIVATE KEY"); 
        +		if (slen > 0)
        +			{
        +			/* NB: ENGINE implementations wont contain
        +			 * a deprecated old private key decode function
        +			 * so don't look for them.
        +			 */
        +			ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
        +			if (ameth && ameth->old_priv_decode)
        +				return 1;
        +			}
        +		return 0;
        +		}
        +
        +	if(!strcmp(name,PEM_STRING_PARAMETERS))
        +		{
        +		int slen;
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +		slen = pem_check_suffix(nm, "PARAMETERS"); 
        +		if (slen > 0)
        +			{
        +			ENGINE *e;
        +			ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
        +			if (ameth)
        +				{
        +				int r;
        +				if (ameth->param_decode)
        +					r = 1;
        +				else
        +					r = 0;
        +#ifndef OPENSSL_NO_ENGINE
        +				if (e)
        +					ENGINE_finish(e);
        +#endif
        +				return r;
        +				}
        +			}
        +		return 0;
        +		}
        +
        +	/* Permit older strings */
        +
        +	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
        +		!strcmp(name,PEM_STRING_X509)) return 1;
        +
        +	if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) &&
        +		!strcmp(name,PEM_STRING_X509_REQ)) return 1;
        +
        +	/* Allow normal certs to be read as trusted certs */
        +	if(!strcmp(nm,PEM_STRING_X509) &&
        +		!strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
        +
        +	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
        +		!strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
        +
        +	/* Some CAs use PKCS#7 with CERTIFICATE headers */
        +	if(!strcmp(nm, PEM_STRING_X509) &&
        +		!strcmp(name, PEM_STRING_PKCS7)) return 1;
        +
        +	if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
        +		!strcmp(name, PEM_STRING_PKCS7)) return 1;
        +
        +#ifndef OPENSSL_NO_CMS
        +	if(!strcmp(nm, PEM_STRING_X509) &&
        +		!strcmp(name, PEM_STRING_CMS)) return 1;
        +	/* Allow CMS to be read from PKCS#7 headers */
        +	if(!strcmp(nm, PEM_STRING_PKCS7) &&
        +		!strcmp(name, PEM_STRING_CMS)) return 1;
        +#endif
        +
        +	return 0;
        +}
        +
        +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
        +	     pem_password_cb *cb, void *u)
        +	{
        +	EVP_CIPHER_INFO cipher;
        +	char *nm=NULL,*header=NULL;
        +	unsigned char *data=NULL;
        +	long len;
        +	int ret = 0;
        +
        +	for (;;)
        +		{
        +		if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
        +			if(ERR_GET_REASON(ERR_peek_error()) ==
        +				PEM_R_NO_START_LINE)
        +				ERR_add_error_data(2, "Expecting: ", name);
        +			return 0;
        +		}
        +		if(check_pem(nm, name)) break;
        +		OPENSSL_free(nm);
        +		OPENSSL_free(header);
        +		OPENSSL_free(data);
        +		}
        +	if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) goto err;
        +	if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err;
        +
        +	*pdata = data;
        +	*plen = len;
        +
        +	if (pnm)
        +		*pnm = nm;
        +
        +	ret = 1;
        +
        +err:
        +	if (!ret || !pnm) OPENSSL_free(nm);
        +	OPENSSL_free(header);
        +	if (!ret) OPENSSL_free(data);
        +	return ret;
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
        +		   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
        +		   int klen, pem_password_cb *callback, void *u)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
        +		       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
        +		       int klen, pem_password_cb *callback, void *u)
        +	{
        +	EVP_CIPHER_CTX ctx;
        +	int dsize=0,i,j,ret=0;
        +	unsigned char *p,*data=NULL;
        +	const char *objstr=NULL;
        +	char buf[PEM_BUFSIZE];
        +	unsigned char key[EVP_MAX_KEY_LENGTH];
        +	unsigned char iv[EVP_MAX_IV_LENGTH];
        +	
        +	if (enc != NULL)
        +		{
        +		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
        +		if (objstr == NULL)
        +			{
        +			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
        +			goto err;
        +			}
        +		}
        +
        +	if ((dsize=i2d(x,NULL)) < 0)
        +		{
        +		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB);
        +		dsize=0;
        +		goto err;
        +		}
        +	/* dzise + 8 bytes are needed */
        +	/* actually it needs the cipher block size extra... */
        +	data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
        +	if (data == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	p=data;
        +	i=i2d(x,&p);
        +
        +	if (enc != NULL)
        +		{
        +		if (kstr == NULL)
        +			{
        +			if (callback == NULL)
        +				klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u);
        +			else
        +				klen=(*callback)(buf,PEM_BUFSIZE,1,u);
        +			if (klen <= 0)
        +				{
        +				PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY);
        +				goto err;
        +				}
        +#ifdef CHARSET_EBCDIC
        +			/* Convert the pass phrase from EBCDIC */
        +			ebcdic2ascii(buf, buf, klen);
        +#endif
        +			kstr=(unsigned char *)buf;
        +			}
        +		RAND_add(data,i,0);/* put in the RSA key. */
        +		OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
        +		if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */
        +			goto err;
        +		/* The 'iv' is used as the iv and as a salt.  It is
        +		 * NOT taken from the BytesToKey function */
        +		if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
        +			goto err;
        +
        +		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
        +
        +		OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);
        +
        +		buf[0]='\0';
        +		PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
        +		PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
        +		/* k=strlen(buf); */
        +
        +		EVP_CIPHER_CTX_init(&ctx);
        +		ret = 1;
        +		if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
        +			|| !EVP_EncryptUpdate(&ctx,data,&j,data,i)
        +			|| !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
        +			ret = 0;
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +		if (ret == 0)
        +			goto err;
        +		i+=j;
        +		}
        +	else
        +		{
        +		ret=1;
        +		buf[0]='\0';
        +		}
        +	i=PEM_write_bio(bp,name,buf,data,i);
        +	if (i <= 0) ret=0;
        +err:
        +	OPENSSL_cleanse(key,sizeof(key));
        +	OPENSSL_cleanse(iv,sizeof(iv));
        +	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
        +	OPENSSL_cleanse(buf,PEM_BUFSIZE);
        +	if (data != NULL)
        +		{
        +		OPENSSL_cleanse(data,(unsigned int)dsize);
        +		OPENSSL_free(data);
        +		}
        +	return(ret);
        +	}
        +
        +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
        +	     pem_password_cb *callback,void *u)
        +	{
        +	int i,j,o,klen;
        +	long len;
        +	EVP_CIPHER_CTX ctx;
        +	unsigned char key[EVP_MAX_KEY_LENGTH];
        +	char buf[PEM_BUFSIZE];
        +
        +	len= *plen;
        +
        +	if (cipher->cipher == NULL) return(1);
        +	if (callback == NULL)
        +		klen=PEM_def_callback(buf,PEM_BUFSIZE,0,u);
        +	else
        +		klen=callback(buf,PEM_BUFSIZE,0,u);
        +	if (klen <= 0)
        +		{
        +		PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_PASSWORD_READ);
        +		return(0);
        +		}
        +#ifdef CHARSET_EBCDIC
        +	/* Convert the pass phrase from EBCDIC */
        +	ebcdic2ascii(buf, buf, klen);
        +#endif
        +
        +	if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
        +		(unsigned char *)buf,klen,1,key,NULL))
        +		return 0;
        +
        +	j=(int)len;
        +	EVP_CIPHER_CTX_init(&ctx);
        +	o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
        +	if (o)
        +		o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
        +	if (o)
        +		o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	OPENSSL_cleanse((char *)buf,sizeof(buf));
        +	OPENSSL_cleanse((char *)key,sizeof(key));
        +	j+=i;
        +	if (!o)
        +		{
        +		PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT);
        +		return(0);
        +		}
        +	*plen=j;
        +	return(1);
        +	}
        +
        +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
        +	{
        +	const EVP_CIPHER *enc=NULL;
        +	char *p,c;
        +	char **header_pp = &header;
        +
        +	cipher->cipher=NULL;
        +	if ((header == NULL) || (*header == '\0') || (*header == '\n'))
        +		return(1);
        +	if (strncmp(header,"Proc-Type: ",11) != 0)
        +		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); return(0); }
        +	header+=11;
        +	if (*header != '4') return(0); header++;
        +	if (*header != ',') return(0); header++;
        +	if (strncmp(header,"ENCRYPTED",9) != 0)
        +		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_ENCRYPTED); return(0); }
        +	for (; (*header != '\n') && (*header != '\0'); header++)
        +		;
        +	if (*header == '\0')
        +		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_SHORT_HEADER); return(0); }
        +	header++;
        +	if (strncmp(header,"DEK-Info: ",10) != 0)
        +		{ PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_DEK_INFO); return(0); }
        +	header+=10;
        +
        +	p=header;
        +	for (;;)
        +		{
        +		c= *header;
        +#ifndef CHARSET_EBCDIC
        +		if (!(	((c >= 'A') && (c <= 'Z')) || (c == '-') ||
        +			((c >= '0') && (c <= '9'))))
        +			break;
        +#else
        +		if (!(	isupper(c) || (c == '-') ||
        +			isdigit(c)))
        +			break;
        +#endif
        +		header++;
        +		}
        +	*header='\0';
        +	cipher->cipher=enc=EVP_get_cipherbyname(p);
        +	*header=c;
        +	header++;
        +
        +	if (enc == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTION);
        +		return(0);
        +		}
        +	if (!load_iv(header_pp,&(cipher->iv[0]),enc->iv_len))
        +		return(0);
        +
        +	return(1);
        +	}
        +
        +static int load_iv(char **fromp, unsigned char *to, int num)
        +	{
        +	int v,i;
        +	char *from;
        +
        +	from= *fromp;
        +	for (i=0; i<num; i++) to[i]=0;
        +	num*=2;
        +	for (i=0; i<num; i++)
        +		{
        +		if ((*from >= '0') && (*from <= '9'))
        +			v= *from-'0';
        +		else if ((*from >= 'A') && (*from <= 'F'))
        +			v= *from-'A'+10;
        +		else if ((*from >= 'a') && (*from <= 'f'))
        +			v= *from-'a'+10;
        +		else
        +			{
        +			PEMerr(PEM_F_LOAD_IV,PEM_R_BAD_IV_CHARS);
        +			return(0);
        +			}
        +		from++;
        +		to[i/2]|=v<<(long)((!(i&1))*4);
        +		}
        +
        +	*fromp=from;
        +	return(1);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int PEM_write(FILE *fp, char *name, char *header, unsigned char *data,
        +	     long len)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_WRITE,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=PEM_write_bio(b, name, header, data,len);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data,
        +	     long len)
        +	{
        +	int nlen,n,i,j,outl;
        +	unsigned char *buf = NULL;
        +	EVP_ENCODE_CTX ctx;
        +	int reason=ERR_R_BUF_LIB;
        +	
        +	EVP_EncodeInit(&ctx);
        +	nlen=strlen(name);
        +
        +	if (	(BIO_write(bp,"-----BEGIN ",11) != 11) ||
        +		(BIO_write(bp,name,nlen) != nlen) ||
        +		(BIO_write(bp,"-----\n",6) != 6))
        +		goto err;
        +		
        +	i=strlen(header);
        +	if (i > 0)
        +		{
        +		if (	(BIO_write(bp,header,i) != i) ||
        +			(BIO_write(bp,"\n",1) != 1))
        +			goto err;
        +		}
        +
        +	buf = OPENSSL_malloc(PEM_BUFSIZE*8);
        +	if (buf == NULL)
        +		{
        +		reason=ERR_R_MALLOC_FAILURE;
        +		goto err;
        +		}
        +
        +	i=j=0;
        +	while (len > 0)
        +		{
        +		n=(int)((len>(PEM_BUFSIZE*5))?(PEM_BUFSIZE*5):len);
        +		EVP_EncodeUpdate(&ctx,buf,&outl,&(data[j]),n);
        +		if ((outl) && (BIO_write(bp,(char *)buf,outl) != outl))
        +			goto err;
        +		i+=outl;
        +		len-=n;
        +		j+=n;
        +		}
        +	EVP_EncodeFinal(&ctx,buf,&outl);
        +	if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err;
        +	OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
        +	OPENSSL_free(buf);
        +	buf = NULL;
        +	if (	(BIO_write(bp,"-----END ",9) != 9) ||
        +		(BIO_write(bp,name,nlen) != nlen) ||
        +		(BIO_write(bp,"-----\n",6) != 6))
        +		goto err;
        +	return(i+outl);
        +err:
        +	if (buf) {
        +		OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
        +		OPENSSL_free(buf);
        +	}
        +	PEMerr(PEM_F_PEM_WRITE_BIO,reason);
        +	return(0);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
        +	     long *len)
        +        {
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_READ,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=PEM_read_bio(b, name, header, data,len);
        +        BIO_free(b);
        +        return(ret);
        +        }
        +#endif
        +
        +int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
        +	     long *len)
        +	{
        +	EVP_ENCODE_CTX ctx;
        +	int end=0,i,k,bl=0,hl=0,nohead=0;
        +	char buf[256];
        +	BUF_MEM *nameB;
        +	BUF_MEM *headerB;
        +	BUF_MEM *dataB,*tmpB;
        +	
        +	nameB=BUF_MEM_new();
        +	headerB=BUF_MEM_new();
        +	dataB=BUF_MEM_new();
        +	if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))
        +		{
        +		BUF_MEM_free(nameB);
        +		BUF_MEM_free(headerB);
        +		BUF_MEM_free(dataB);
        +		PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +
        +	buf[254]='\0';
        +	for (;;)
        +		{
        +		i=BIO_gets(bp,buf,254);
        +
        +		if (i <= 0)
        +			{
        +			PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);
        +			goto err;
        +			}
        +
        +		while ((i >= 0) && (buf[i] <= ' ')) i--;
        +		buf[++i]='\n'; buf[++i]='\0';
        +
        +		if (strncmp(buf,"-----BEGIN ",11) == 0)
        +			{
        +			i=strlen(&(buf[11]));
        +
        +			if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)
        +				continue;
        +			if (!BUF_MEM_grow(nameB,i+9))
        +				{
        +				PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			memcpy(nameB->data,&(buf[11]),i-6);
        +			nameB->data[i-6]='\0';
        +			break;
        +			}
        +		}
        +	hl=0;
        +	if (!BUF_MEM_grow(headerB,256))
        +		{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
        +	headerB->data[0]='\0';
        +	for (;;)
        +		{
        +		i=BIO_gets(bp,buf,254);
        +		if (i <= 0) break;
        +
        +		while ((i >= 0) && (buf[i] <= ' ')) i--;
        +		buf[++i]='\n'; buf[++i]='\0';
        +
        +		if (buf[0] == '\n') break;
        +		if (!BUF_MEM_grow(headerB,hl+i+9))
        +			{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
        +		if (strncmp(buf,"-----END ",9) == 0)
        +			{
        +			nohead=1;
        +			break;
        +			}
        +		memcpy(&(headerB->data[hl]),buf,i);
        +		headerB->data[hl+i]='\0';
        +		hl+=i;
        +		}
        +
        +	bl=0;
        +	if (!BUF_MEM_grow(dataB,1024))
        +		{ PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
        +	dataB->data[0]='\0';
        +	if (!nohead)
        +		{
        +		for (;;)
        +			{
        +			i=BIO_gets(bp,buf,254);
        +			if (i <= 0) break;
        +
        +			while ((i >= 0) && (buf[i] <= ' ')) i--;
        +			buf[++i]='\n'; buf[++i]='\0';
        +
        +			if (i != 65) end=1;
        +			if (strncmp(buf,"-----END ",9) == 0)
        +				break;
        +			if (i > 65) break;
        +			if (!BUF_MEM_grow_clean(dataB,i+bl+9))
        +				{
        +				PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			memcpy(&(dataB->data[bl]),buf,i);
        +			dataB->data[bl+i]='\0';
        +			bl+=i;
        +			if (end)
        +				{
        +				buf[0]='\0';
        +				i=BIO_gets(bp,buf,254);
        +				if (i <= 0) break;
        +
        +				while ((i >= 0) && (buf[i] <= ' ')) i--;
        +				buf[++i]='\n'; buf[++i]='\0';
        +
        +				break;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		tmpB=headerB;
        +		headerB=dataB;
        +		dataB=tmpB;
        +		bl=hl;
        +		}
        +	i=strlen(nameB->data);
        +	if (	(strncmp(buf,"-----END ",9) != 0) ||
        +		(strncmp(nameB->data,&(buf[9]),i) != 0) ||
        +		(strncmp(&(buf[9+i]),"-----\n",6) != 0))
        +		{
        +		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE);
        +		goto err;
        +		}
        +
        +	EVP_DecodeInit(&ctx);
        +	i=EVP_DecodeUpdate(&ctx,
        +		(unsigned char *)dataB->data,&bl,
        +		(unsigned char *)dataB->data,bl);
        +	if (i < 0)
        +		{
        +		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
        +		goto err;
        +		}
        +	i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
        +	if (i < 0)
        +		{
        +		PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
        +		goto err;
        +		}
        +	bl+=k;
        +
        +	if (bl == 0) goto err;
        +	*name=nameB->data;
        +	*header=headerB->data;
        +	*data=(unsigned char *)dataB->data;
        +	*len=bl;
        +	OPENSSL_free(nameB);
        +	OPENSSL_free(headerB);
        +	OPENSSL_free(dataB);
        +	return(1);
        +err:
        +	BUF_MEM_free(nameB);
        +	BUF_MEM_free(headerB);
        +	BUF_MEM_free(dataB);
        +	return(0);
        +	}
        +
        +/* Check pem string and return prefix length.
        + * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
        + * the return value is 3 for the string "RSA".
        + */
        +
        +int pem_check_suffix(const char *pem_str, const char *suffix)
        +	{
        +	int pem_len = strlen(pem_str);
        +	int suffix_len = strlen(suffix);
        +	const char *p;
        +	if (suffix_len + 1 >= pem_len)
        +		return 0;
        +	p = pem_str + pem_len - suffix_len;
        +	if (strcmp(p, suffix))
        +		return 0;
        +	p--;
        +	if (*p != ' ')
        +		return 0;
        +	return p - pem_str;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_oth.c b/vendor/openssl/openssl/crypto/pem/pem_oth.c
        new file mode 100644
        index 000000000..b33868d25
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_oth.c
        @@ -0,0 +1,86 @@
        +/* crypto/pem/pem_oth.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +/* Handle 'other' PEMs: not private keys */
        +
        +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
        +			pem_password_cb *cb, void *u)
        +	{
        +	const unsigned char *p=NULL;
        +	unsigned char *data=NULL;
        +	long len;
        +	char *ret=NULL;
        +
        +	if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
        +		return NULL;
        +	p = data;
        +	ret=d2i(x,&p,len);
        +	if (ret == NULL)
        +		PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB);
        +	OPENSSL_free(data);
        +	return(ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_pk8.c b/vendor/openssl/openssl/crypto/pem/pem_pk8.c
        new file mode 100644
        index 000000000..6deab8c33
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_pk8.c
        @@ -0,0 +1,242 @@
        +/* crypto/pem/pem_pkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/pem.h>
        +
        +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
        +				int nid, const EVP_CIPHER *enc,
        +				char *kstr, int klen,
        +				pem_password_cb *cb, void *u);
        +static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
        +				int nid, const EVP_CIPHER *enc,
        +				char *kstr, int klen,
        +				pem_password_cb *cb, void *u);
        +
        +/* These functions write a private key in PKCS#8 format: it is a "drop in"
        + * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
        + * is NULL then it uses the unencrypted private key form. The 'nid' versions
        + * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
        + */
        +
        +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
        +}
        +
        +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
        +}
        +
        +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
        +}
        +
        +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
        +}
        +
        +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	X509_SIG *p8;
        +	PKCS8_PRIV_KEY_INFO *p8inf;
        +	char buf[PEM_BUFSIZE];
        +	int ret;
        +	if(!(p8inf = EVP_PKEY2PKCS8(x))) {
        +		PEMerr(PEM_F_DO_PK8PKEY,
        +					PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
        +		return 0;
        +	}
        +	if(enc || (nid != -1)) {
        +		if(!kstr) {
        +			if(!cb) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
        +			else klen = cb(buf, PEM_BUFSIZE, 1, u);
        +			if(klen <= 0) {
        +				PEMerr(PEM_F_DO_PK8PKEY,PEM_R_READ_KEY);
        +				PKCS8_PRIV_KEY_INFO_free(p8inf);
        +				return 0;
        +			}
        +				
        +			kstr = buf;
        +		}
        +		p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
        +		if(kstr == buf) OPENSSL_cleanse(buf, klen);
        +		PKCS8_PRIV_KEY_INFO_free(p8inf);
        +		if(isder) ret = i2d_PKCS8_bio(bp, p8);
        +		else ret = PEM_write_bio_PKCS8(bp, p8);
        +		X509_SIG_free(p8);
        +		return ret;
        +	} else {
        +		if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
        +		else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
        +		PKCS8_PRIV_KEY_INFO_free(p8inf);
        +		return ret;
        +	}
        +}
        +
        +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
        +{
        +	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
        +	X509_SIG *p8 = NULL;
        +	int klen;
        +	EVP_PKEY *ret;
        +	char psbuf[PEM_BUFSIZE];
        +	p8 = d2i_PKCS8_bio(bp, NULL);
        +	if(!p8) return NULL;
        +	if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
        +	else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
        +	if (klen <= 0) {
        +		PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
        +		X509_SIG_free(p8);
        +		return NULL;	
        +	}
        +	p8inf = PKCS8_decrypt(p8, psbuf, klen);
        +	X509_SIG_free(p8);
        +	if(!p8inf) return NULL;
        +	ret = EVP_PKCS82PKEY(p8inf);
        +	PKCS8_PRIV_KEY_INFO_free(p8inf);
        +	if(!ret) return NULL;
        +	if(x) {
        +		if(*x) EVP_PKEY_free(*x);
        +		*x = ret;
        +	}
        +	return ret;
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +
        +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
        +}
        +
        +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
        +}
        +
        +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
        +}
        +
        +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +			      char *kstr, int klen, pem_password_cb *cb, void *u)
        +{
        +	return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
        +}
        +
        +static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u)
        +{
        +	BIO *bp;
        +	int ret;
        +	if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
        +		PEMerr(PEM_F_DO_PK8PKEY_FP,ERR_R_BUF_LIB);
        +                return(0);
        +	}
        +	ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
        +	BIO_free(bp);
        +	return ret;
        +}
        +
        +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
        +{
        +	BIO *bp;
        +	EVP_PKEY *ret;
        +	if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
        +		PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB);
        +                return NULL;
        +	}
        +	ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
        +	BIO_free(bp);
        +	return ret;
        +}
        +
        +#endif
        +
        +IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
        +IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
        +							 PKCS8_PRIV_KEY_INFO)
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_pkey.c b/vendor/openssl/openssl/crypto/pem/pem_pkey.c
        new file mode 100644
        index 000000000..8ecf24903
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_pkey.c
        @@ -0,0 +1,242 @@
        +/* crypto/pem/pem_pkey.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs12.h>
        +#include <openssl/pem.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include "asn1_locl.h"
        +
        +int pem_check_suffix(const char *pem_str, const char *suffix);
        +
        +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
        +	{
        +	char *nm=NULL;
        +	const unsigned char *p=NULL;
        +	unsigned char *data=NULL;
        +	long len;
        +	int slen;
        +	EVP_PKEY *ret=NULL;
        +
        +	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
        +		return NULL;
        +	p = data;
        +
        +	if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
        +		PKCS8_PRIV_KEY_INFO *p8inf;
        +		p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
        +		if(!p8inf) goto p8err;
        +		ret = EVP_PKCS82PKEY(p8inf);
        +		if(x) {
        +			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
        +			*x = ret;
        +		}
        +		PKCS8_PRIV_KEY_INFO_free(p8inf);
        +	} else if (strcmp(nm,PEM_STRING_PKCS8) == 0) {
        +		PKCS8_PRIV_KEY_INFO *p8inf;
        +		X509_SIG *p8;
        +		int klen;
        +		char psbuf[PEM_BUFSIZE];
        +		p8 = d2i_X509_SIG(NULL, &p, len);
        +		if(!p8) goto p8err;
        +		if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
        +		else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
        +		if (klen <= 0) {
        +			PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,
        +					PEM_R_BAD_PASSWORD_READ);
        +			X509_SIG_free(p8);
        +			goto err;
        +		}
        +		p8inf = PKCS8_decrypt(p8, psbuf, klen);
        +		X509_SIG_free(p8);
        +		if(!p8inf) goto p8err;
        +		ret = EVP_PKCS82PKEY(p8inf);
        +		if(x) {
        +			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
        +			*x = ret;
        +		}
        +		PKCS8_PRIV_KEY_INFO_free(p8inf);
        +	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
        +		{
        +		const EVP_PKEY_ASN1_METHOD *ameth;
        +		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
        +		if (!ameth || !ameth->old_priv_decode)
        +			goto p8err;
        +		ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
        +		}
        +p8err:
        +	if (ret == NULL)
        +		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
        +err:
        +	OPENSSL_free(nm);
        +	OPENSSL_cleanse(data, len);
        +	OPENSSL_free(data);
        +	return(ret);
        +	}
        +
        +int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +	{
        +	char pem_str[80];
        +	if (!x->ameth || x->ameth->priv_encode)
        +		return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
        +							(char *)kstr, klen,
        +							cb, u);
        +
        +	BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
        +	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
        +				pem_str,bp,x,enc,kstr,klen,cb,u);
        +	}
        +
        +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
        +	{
        +	char *nm=NULL;
        +	const unsigned char *p=NULL;
        +	unsigned char *data=NULL;
        +	long len;
        +	int slen;
        +	EVP_PKEY *ret=NULL;
        +
        +	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
        +								bp, 0, NULL))
        +		return NULL;
        +	p = data;
        +
        +	if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
        +		{
        +		ret = EVP_PKEY_new();
        +		if (!ret)
        +			goto err;
        +		if (!EVP_PKEY_set_type_str(ret, nm, slen)
        +			|| !ret->ameth->param_decode
        +			|| !ret->ameth->param_decode(ret, &p, len))
        +			{
        +			EVP_PKEY_free(ret);
        +			ret = NULL;
        +			goto err;
        +			}
        +		if(x)
        +			{
        +			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
        +			*x = ret;
        +			}
        +		}
        +err:
        +	if (ret == NULL)
        +		PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS,ERR_R_ASN1_LIB);
        +	OPENSSL_free(nm);
        +	OPENSSL_free(data);
        +	return(ret);
        +	}
        +
        +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
        +	{
        +	char pem_str[80];
        +	if (!x->ameth || !x->ameth->param_encode)
        +		return 0;
        +
        +	BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
        +	return PEM_ASN1_write_bio(
        +		(i2d_of_void *)x->ameth->param_encode,
        +				pem_str,bp,x,NULL,NULL,0,0,NULL);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
        +	{
        +        BIO *b;
        +        EVP_PKEY *ret;
        +
        +        if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_READ_PRIVATEKEY,ERR_R_BUF_LIB);
        +                return(0);
        +		}
        +        BIO_set_fp(b,fp,BIO_NOCLOSE);
        +        ret=PEM_read_bio_PrivateKey(b,x,cb,u);
        +        BIO_free(b);
        +        return(ret);
        +	}
        +
        +int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +                                               unsigned char *kstr, int klen,
        +                                               pem_password_cb *cb, void *u)
        +	{
        +        BIO *b;
        +        int ret;
        +
        +        if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY,ERR_R_BUF_LIB);
        +                return 0;
        +		}
        +        ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
        +        BIO_free(b);
        +        return ret;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_seal.c b/vendor/openssl/openssl/crypto/pem/pem_seal.c
        new file mode 100644
        index 000000000..b6b4e1349
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_seal.c
        @@ -0,0 +1,191 @@
        +/* crypto/pem/pem_seal.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 <openssl/opensslconf.h>	/* for OPENSSL_NO_RSA */
        +#ifndef OPENSSL_NO_RSA
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/rsa.h>
        +
        +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
        +	     unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk,
        +	     int npubk)
        +	{
        +	unsigned char key[EVP_MAX_KEY_LENGTH];
        +	int ret= -1;
        +	int i,j,max=0;
        +	char *s=NULL;
        +
        +	for (i=0; i<npubk; i++)
        +		{
        +		if (pubk[i]->type != EVP_PKEY_RSA)
        +			{
        +			PEMerr(PEM_F_PEM_SEALINIT,PEM_R_PUBLIC_KEY_NO_RSA);
        +			goto err;
        +			}
        +		j=RSA_size(pubk[i]->pkey.rsa);
        +		if (j > max) max=j;
        +		}
        +	s=(char *)OPENSSL_malloc(max*2);
        +	if (s == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_SEALINIT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	EVP_EncodeInit(&ctx->encode);
        +
        +	EVP_MD_CTX_init(&ctx->md);
        +	if (!EVP_SignInit(&ctx->md,md_type))
        +		goto err;
        +
        +	EVP_CIPHER_CTX_init(&ctx->cipher);
        +	ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
        +	if (ret <= 0) goto err;
        +
        +	/* base64 encode the keys */
        +	for (i=0; i<npubk; i++)
        +		{
        +		j=EVP_EncodeBlock((unsigned char *)s,ek[i],
        +			RSA_size(pubk[i]->pkey.rsa));
        +		ekl[i]=j;
        +		memcpy(ek[i],s,j+1);
        +		}
        +
        +	ret=npubk;
        +err:
        +	if (s != NULL) OPENSSL_free(s);
        +	OPENSSL_cleanse(key,EVP_MAX_KEY_LENGTH);
        +	return(ret);
        +	}
        +
        +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
        +	     unsigned char *in, int inl)
        +	{
        +	unsigned char buffer[1600];
        +	int i,j;
        +
        +	*outl=0;
        +	EVP_SignUpdate(&ctx->md,in,inl);
        +	for (;;)
        +		{
        +		if (inl <= 0) break;
        +		if (inl > 1200)
        +			i=1200;
        +		else
        +			i=inl;
        +		EVP_EncryptUpdate(&ctx->cipher,buffer,&j,in,i);
        +		EVP_EncodeUpdate(&ctx->encode,out,&j,buffer,j);
        +		*outl+=j;
        +		out+=j;
        +		in+=i;
        +		inl-=i;
        +		}
        +	}
        +
        +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
        +	     unsigned char *out, int *outl, EVP_PKEY *priv)
        +	{
        +	unsigned char *s=NULL;
        +	int ret=0,j;
        +	unsigned int i;
        +
        +	if (priv->type != EVP_PKEY_RSA)
        +		{
        +		PEMerr(PEM_F_PEM_SEALFINAL,PEM_R_PUBLIC_KEY_NO_RSA);
        +		goto err;
        +		}
        +	i=RSA_size(priv->pkey.rsa);
        +	if (i < 100) i=100;
        +	s=(unsigned char *)OPENSSL_malloc(i*2);
        +	if (s == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_SEALFINAL,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i))
        +		goto err;
        +	EVP_EncodeUpdate(&ctx->encode,out,&j,s,i);
        +	*outl=j;
        +	out+=j;
        +	EVP_EncodeFinal(&ctx->encode,out,&j);
        +	*outl+=j;
        +
        +	if (!EVP_SignFinal(&ctx->md,s,&i,priv)) goto err;
        +	*sigl=EVP_EncodeBlock(sig,s,i);
        +
        +	ret=1;
        +err:
        +	EVP_MD_CTX_cleanup(&ctx->md);
        +	EVP_CIPHER_CTX_cleanup(&ctx->cipher);
        +	if (s != NULL) OPENSSL_free(s);
        +	return(ret);
        +	}
        +#else /* !OPENSSL_NO_RSA */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_sign.c b/vendor/openssl/openssl/crypto/pem/pem_sign.c
        new file mode 100644
        index 000000000..c3b9808cb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_sign.c
        @@ -0,0 +1,102 @@
        +/* crypto/pem/pem_sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
        +	{
        +	EVP_DigestInit_ex(ctx, type, NULL);
        +	}
        +
        +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
        +	     unsigned int count)
        +	{
        +	EVP_DigestUpdate(ctx,data,count);
        +	}
        +
        +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
        +	     EVP_PKEY *pkey)
        +	{
        +	unsigned char *m;
        +	int i,ret=0;
        +	unsigned int m_len;
        +
        +	m=(unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey)+2);
        +	if (m == NULL)
        +		{
        +		PEMerr(PEM_F_PEM_SIGNFINAL,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (EVP_SignFinal(ctx,m,&m_len,pkey) <= 0) goto err;
        +
        +	i=EVP_EncodeBlock(sigret,m,m_len);
        +	*siglen=i;
        +	ret=1;
        +err:
        +	/* ctx has been zeroed by EVP_SignFinal() */
        +	if (m != NULL) OPENSSL_free(m);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_x509.c b/vendor/openssl/openssl/crypto/pem/pem_x509.c
        new file mode 100644
        index 000000000..b531057dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_x509.c
        @@ -0,0 +1,68 @@
        +/* pem_x509.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/pem.h>
        +
        +IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
        +
        diff --git a/vendor/openssl/openssl/crypto/pem/pem_xaux.c b/vendor/openssl/openssl/crypto/pem/pem_xaux.c
        new file mode 100644
        index 000000000..328f79620
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pem_xaux.c
        @@ -0,0 +1,68 @@
        +/* pem_xaux.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/pem.h>
        +
        +IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
        +IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, X509_CERT_PAIR)
        diff --git a/vendor/openssl/openssl/crypto/pem/pkcs7.lis b/vendor/openssl/openssl/crypto/pem/pkcs7.lis
        new file mode 100644
        index 000000000..be90c5d87
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pkcs7.lis
        @@ -0,0 +1,22 @@
        +21     0:d=0 hl=2 l=  0 cons: univ: SEQUENCE          
        + 00     2:d=0 hl=2 l=  9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-signedData
        + 21    13:d=0 hl=2 l=  0 cons: cont: 00			# explicit tag
        +  21    15:d=0 hl=2 l=  0 cons: univ: SEQUENCE          
        +   00    17:d=0 hl=2 l=  1 prim: univ: INTEGER          # version 
        +   20    20:d=0 hl=2 l=  0 cons: univ: SET               
        +   21    22:d=0 hl=2 l=  0 cons: univ: SEQUENCE          
        +    00    24:d=0 hl=2 l=  9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-data
        +    00    35:d=0 hl=2 l=  0 prim: univ: EOC               
        +   21    37:d=0 hl=2 l=  0 cons: cont: 00               # cert tag
        +    20    39:d=0 hl=4 l=545 cons: univ: SEQUENCE          
        +    20   588:d=0 hl=4 l=524 cons: univ: SEQUENCE          
        +    00  1116:d=0 hl=2 l=  0 prim: univ: EOC               
        +   21  1118:d=0 hl=2 l=  0 cons: cont: 01		# crl tag
        +    20  1120:d=0 hl=4 l=653 cons: univ: SEQUENCE          
        +    20  1777:d=0 hl=4 l=285 cons: univ: SEQUENCE          
        +    00  2066:d=0 hl=2 l=  0 prim: univ: EOC               
        +   21  2068:d=0 hl=2 l=  0 cons: univ: SET              # signers 
        +    00  2070:d=0 hl=2 l=  0 prim: univ: EOC               
        +  00  2072:d=0 hl=2 l=  0 prim: univ: EOC               
        + 00  2074:d=0 hl=2 l=  0 prim: univ: EOC               
        +00  2076:d=0 hl=2 l=  0 prim: univ: EOC               
        diff --git a/vendor/openssl/openssl/crypto/pem/pvkfmt.c b/vendor/openssl/openssl/crypto/pem/pvkfmt.c
        new file mode 100644
        index 000000000..b1bf71a5d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pem/pvkfmt.c
        @@ -0,0 +1,950 @@
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2005.
        + */
        +/* ====================================================================
        + * Copyright (c) 2005 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).
        + *
        + */
        +
        +/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
        + * and PRIVATEKEYBLOB).
        + */
        +
        +#include "cryptlib.h"
        +#include <openssl/pem.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
        +#include <openssl/dsa.h>
        +#include <openssl/rsa.h>
        +
        +/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
        + * format
        + */
        +
        +static unsigned int read_ledword(const unsigned char **in)
        +	{
        +	const unsigned char *p = *in;
        +	unsigned int ret;
        +	ret = *p++;
        +	ret |= (*p++ << 8);
        +	ret |= (*p++ << 16);
        +	ret |= (*p++ << 24);
        +	*in = p;
        +	return ret;
        +	}
        +
        +/* Read a BIGNUM in little endian format. The docs say that this should take up 
        + * bitlen/8 bytes.
        + */
        +
        +static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
        +	{
        +	const unsigned char *p;
        +	unsigned char *tmpbuf, *q;
        +	unsigned int i;
        +	p = *in + nbyte - 1;
        +	tmpbuf = OPENSSL_malloc(nbyte);
        +	if (!tmpbuf)
        +		return 0;
        +	q = tmpbuf;
        +	for (i = 0; i < nbyte; i++)
        +		*q++ = *p--;
        +	*r = BN_bin2bn(tmpbuf, nbyte, NULL);
        +	OPENSSL_free(tmpbuf);
        +	if (*r)
        +		{
        +		*in += nbyte;
        +		return 1;
        +		}
        +	else
        +		return 0;
        +	}
        +
        +
        +/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
        +
        +#define MS_PUBLICKEYBLOB	0x6
        +#define MS_PRIVATEKEYBLOB	0x7
        +#define MS_RSA1MAGIC		0x31415352L
        +#define MS_RSA2MAGIC		0x32415352L
        +#define MS_DSS1MAGIC		0x31535344L
        +#define MS_DSS2MAGIC		0x32535344L
        +
        +#define MS_KEYALG_RSA_KEYX	0xa400
        +#define MS_KEYALG_DSS_SIGN	0x2200
        +
        +#define MS_KEYTYPE_KEYX		0x1
        +#define MS_KEYTYPE_SIGN		0x2
        +
        +/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
        +#define MS_PVKMAGIC		0xb0b5f11eL
        +/* Salt length for PVK files */
        +#define PVK_SALTLEN		0x10
        +
        +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
        +						unsigned int bitlen, int ispub);
        +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
        +						unsigned int bitlen, int ispub);
        +
        +static int do_blob_header(const unsigned char **in, unsigned int length,
        +				unsigned int *pmagic, unsigned int *pbitlen,
        +				int *pisdss, int *pispub)
        +	{
        +	const unsigned char *p = *in;
        +	if (length < 16)
        +		return 0;
        +	/* bType */
        +	if (*p == MS_PUBLICKEYBLOB)
        +		{
        +		if (*pispub == 0)
        +			{
        +			PEMerr(PEM_F_DO_BLOB_HEADER,
        +					PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
        +			return 0;
        +			}
        +		*pispub = 1;
        +		}
        +	else if (*p == MS_PRIVATEKEYBLOB)
        +		{
        +		if (*pispub == 1)
        +			{
        +			PEMerr(PEM_F_DO_BLOB_HEADER,
        +					PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
        +			return 0;
        +			}
        +		*pispub = 0;
        +		}
        +	else
        +		return 0;
        +	p++;
        +	/* Version */
        +	if (*p++ != 0x2)
        +		{
        +		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
        +		return 0;
        +		}
        +	/* Ignore reserved, aiKeyAlg */
        +	p+= 6;
        +	*pmagic = read_ledword(&p);
        +	*pbitlen = read_ledword(&p);
        +	*pisdss = 0;
        +	switch (*pmagic)
        +		{
        +
        +		case MS_DSS1MAGIC:
        +		*pisdss = 1;
        +		case MS_RSA1MAGIC:
        +		if (*pispub == 0)
        +			{
        +			PEMerr(PEM_F_DO_BLOB_HEADER,
        +					PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
        +			return 0;
        +			}
        +		break;
        +
        +		case MS_DSS2MAGIC:
        +		*pisdss = 1;
        +		case MS_RSA2MAGIC:
        +		if (*pispub == 1)
        +			{
        +			PEMerr(PEM_F_DO_BLOB_HEADER,
        +					PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
        +			return 0;
        +			}
        +		break;
        +
        +		default:
        +		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
        +		return -1;
        +		}
        +	*in = p;
        +	return 1;
        +	}
        +
        +static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
        +	{
        +	unsigned int nbyte, hnbyte;
        +	nbyte = (bitlen + 7) >> 3;
        +	hnbyte = (bitlen + 15) >> 4;
        +	if (isdss)
        +		{
        +
        +		/* Expected length: 20 for q + 3 components bitlen each + 24
        +		 * for seed structure.
        +		 */
        +		if (ispub)
        +			return  44 + 3 * nbyte;
        +		/* Expected length: 20 for q, priv, 2 bitlen components + 24
        +		 * for seed structure.
        +		 */
        +		else
        +			return 64 + 2 * nbyte;
        +		}
        +	else
        +		{
        +		/* Expected length: 4 for 'e' + 'n' */
        +		if (ispub)
        +			return 4 + nbyte;
        +		else
        +		/* Expected length: 4 for 'e' and 7 other components.
        +		 * 2 components are bitlen size, 5 are bitlen/2
        +		 */
        +			return 4 + 2*nbyte + 5*hnbyte;
        +		}
        +
        +	}
        +
        +static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
        +								int ispub)
        +	{
        +	const unsigned char *p = *in;
        +	unsigned int bitlen, magic;
        +	int isdss;
        +	if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0)
        +		{
        +		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
        +		return NULL;
        +		}
        +	length -= 16;
        +	if (length < blob_length(bitlen, isdss, ispub))
        +		{
        +		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
        +		return NULL;
        +		}
        +	if (isdss)
        +		return b2i_dss(&p, length, bitlen, ispub);
        +	else
        +		return b2i_rsa(&p, length, bitlen, ispub);
        +	}
        +
        +static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
        +	{
        +	const unsigned char *p;
        +	unsigned char hdr_buf[16], *buf = NULL;
        +	unsigned int bitlen, magic, length;
        +	int isdss;
        +	EVP_PKEY *ret = NULL;
        +	if (BIO_read(in, hdr_buf, 16) != 16)
        +		{
        +		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
        +		return NULL;
        +		}
        +	p = hdr_buf;
        +	if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
        +		return NULL;
        +
        +	length = blob_length(bitlen, isdss, ispub);
        +	buf = OPENSSL_malloc(length);
        +	if (!buf)
        +		{
        +		PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	p = buf;
        +	if (BIO_read(in, buf, length) != (int)length)
        +		{
        +		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
        +		goto err;
        +		}
        +
        +	if (isdss)
        +		ret = b2i_dss(&p, length, bitlen, ispub);
        +	else
        +		ret = b2i_rsa(&p, length, bitlen, ispub);
        +
        +	err:
        +	if (buf)
        +		OPENSSL_free(buf);
        +	return ret;
        +	}
        +
        +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
        +						unsigned int bitlen, int ispub)
        +	{
        +	const unsigned char *p = *in;
        +	EVP_PKEY *ret = NULL;
        +	DSA *dsa = NULL;
        +	BN_CTX *ctx = NULL;
        +	unsigned int nbyte;
        +	nbyte = (bitlen + 7) >> 3;
        +
        +	dsa = DSA_new();
        +	ret = EVP_PKEY_new();
        +	if (!dsa || !ret)
        +		goto memerr;
        +	if (!read_lebn(&p, nbyte, &dsa->p))
        +		goto memerr;
        +	if (!read_lebn(&p, 20, &dsa->q))
        +		goto memerr;
        +	if (!read_lebn(&p, nbyte, &dsa->g))
        +		goto memerr;
        +	if (ispub)
        +		{
        +		if (!read_lebn(&p, nbyte, &dsa->pub_key))
        +			goto memerr;
        +		}
        +	else
        +		{
        +		if (!read_lebn(&p, 20, &dsa->priv_key))
        +			goto memerr;
        +		/* Calculate public key */
        +		if (!(dsa->pub_key = BN_new()))
        +			goto memerr;
        +		if (!(ctx = BN_CTX_new()))
        +			goto memerr;
        +			
        +		if (!BN_mod_exp(dsa->pub_key, dsa->g,
        +						 dsa->priv_key, dsa->p, ctx))
        +			
        +			goto memerr;
        +		BN_CTX_free(ctx);
        +		}
        +
        +	EVP_PKEY_set1_DSA(ret, dsa);
        +	DSA_free(dsa);
        +	*in = p;
        +	return ret;
        +
        +	memerr:
        +	PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
        +	if (dsa)
        +		DSA_free(dsa);
        +	if (ret)
        +		EVP_PKEY_free(ret);
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	return NULL;
        +	}
        +
        +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
        +						unsigned int bitlen, int ispub)
        +		
        +	{
        +	const unsigned char *p = *in;
        +	EVP_PKEY *ret = NULL;
        +	RSA *rsa = NULL;
        +	unsigned int nbyte, hnbyte;
        +	nbyte = (bitlen + 7) >> 3;
        +	hnbyte = (bitlen + 15) >> 4;
        +	rsa = RSA_new();
        +	ret = EVP_PKEY_new();
        +	if (!rsa || !ret)
        +		goto memerr;
        +	rsa->e = BN_new();
        +	if (!rsa->e)
        +		goto memerr;
        +	if (!BN_set_word(rsa->e, read_ledword(&p)))
        +		goto memerr;
        +	if (!read_lebn(&p, nbyte, &rsa->n))
        +		goto memerr;
        +	if (!ispub)
        +		{
        +		if (!read_lebn(&p, hnbyte, &rsa->p))
        +			goto memerr;
        +		if (!read_lebn(&p, hnbyte, &rsa->q))
        +			goto memerr;
        +		if (!read_lebn(&p, hnbyte, &rsa->dmp1))
        +			goto memerr;
        +		if (!read_lebn(&p, hnbyte, &rsa->dmq1))
        +			goto memerr;
        +		if (!read_lebn(&p, hnbyte, &rsa->iqmp))
        +			goto memerr;
        +		if (!read_lebn(&p, nbyte, &rsa->d))
        +			goto memerr;
        +		}
        +
        +	EVP_PKEY_set1_RSA(ret, rsa);
        +	RSA_free(rsa);
        +	*in = p;
        +	return ret;
        +	memerr:
        +	PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
        +	if (rsa)
        +		RSA_free(rsa);
        +	if (ret)
        +		EVP_PKEY_free(ret);
        +	return NULL;
        +	}
        +
        +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
        +	{
        +	return do_b2i(in, length, 0);
        +	}
        +
        +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
        +	{
        +	return do_b2i(in, length, 1);
        +	}
        +
        +
        +EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
        +	{
        +	return do_b2i_bio(in, 0);
        +	}
        +
        +EVP_PKEY *b2i_PublicKey_bio(BIO *in)
        +	{
        +	return do_b2i_bio(in, 1);
        +	}
        +
        +static void write_ledword(unsigned char **out, unsigned int dw)
        +	{
        +	unsigned char *p = *out;
        +	*p++ = dw & 0xff;
        +	*p++ = (dw>>8) & 0xff;
        +	*p++ = (dw>>16) & 0xff;
        +	*p++ = (dw>>24) & 0xff;
        +	*out = p;
        +	}
        +
        +static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
        +	{
        +	int nb, i;
        +	unsigned char *p = *out, *q, c;
        +	nb = BN_num_bytes(bn);
        +	BN_bn2bin(bn, p);
        +	q = p + nb - 1;
        +	/* In place byte order reversal */
        +	for (i = 0; i < nb/2; i++)
        +		{
        +		c = *p;
        +		*p++ = *q;
        +		*q-- = c;
        +		}
        +	*out += nb;
        +	/* Pad with zeroes if we have to */
        +	if (len > 0)
        +		{
        +		len -= nb;
        +		if (len > 0)
        +			{
        +			memset(*out, 0, len);
        +			*out += len;
        +			}
        +		}
        +	}
        +
        +
        +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
        +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
        +
        +static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
        +static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
        +	
        +static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
        +	{
        +	unsigned char *p;
        +	unsigned int bitlen, magic = 0, keyalg;
        +	int outlen, noinc = 0;
        +	if (pk->type == EVP_PKEY_DSA)
        +		{
        +		bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
        +		keyalg = MS_KEYALG_DSS_SIGN;
        +		}
        +	else if (pk->type == EVP_PKEY_RSA)
        +		{
        +		bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
        +		keyalg = MS_KEYALG_RSA_KEYX;
        +		}
        +	else
        +		return -1;
        +	if (bitlen == 0)
        +		return -1;
        +	outlen = 16 + blob_length(bitlen,
        +			keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
        +	if (out == NULL)
        +		return outlen;
        +	if (*out)
        +		p = *out;
        +	else
        +		{
        +		p = OPENSSL_malloc(outlen);
        +		if (!p)
        +			return -1;
        +		*out = p;
        +		noinc = 1;
        +		}
        +	if (ispub)
        +		*p++ = MS_PUBLICKEYBLOB;
        +	else
        +		*p++ = MS_PRIVATEKEYBLOB;
        +	*p++ = 0x2;
        +	*p++ = 0;
        +	*p++ = 0;
        +	write_ledword(&p, keyalg);
        +	write_ledword(&p, magic);
        +	write_ledword(&p, bitlen);
        +	if (keyalg == MS_KEYALG_DSS_SIGN)
        +		write_dsa(&p, pk->pkey.dsa, ispub);
        +	else
        +		write_rsa(&p, pk->pkey.rsa, ispub);
        +	if (!noinc)
        +		*out += outlen;
        +	return outlen;
        +	}
        +
        +static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
        +	{
        +	unsigned char *tmp = NULL;
        +	int outlen, wrlen;
        +	outlen = do_i2b(&tmp, pk, ispub);
        +	if (outlen < 0)
        +		return -1;
        +	wrlen = BIO_write(out, tmp, outlen);
        +	OPENSSL_free(tmp);
        +	if (wrlen == outlen)
        +		return outlen;
        +	return -1;
        +	}
        +
        +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
        +	{
        +	int bitlen;
        +	bitlen = BN_num_bits(dsa->p);
        +	if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160)
        +		|| (BN_num_bits(dsa->g) > bitlen))
        +		goto badkey;
        +	if (ispub)
        +		{
        +		if (BN_num_bits(dsa->pub_key) > bitlen)
        +			goto badkey;
        +		*pmagic = MS_DSS1MAGIC;
        +		}
        +	else
        +		{
        +		if (BN_num_bits(dsa->priv_key) > 160)
        +			goto badkey;
        +		*pmagic = MS_DSS2MAGIC;
        +		}
        +	
        +	return bitlen;
        +	badkey:
        +	PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
        +	return 0;
        +	}
        +
        +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
        +	{
        +	int nbyte, hnbyte, bitlen;
        +	if (BN_num_bits(rsa->e) > 32)
        +		goto badkey;
        +	bitlen = BN_num_bits(rsa->n);
        +	nbyte = BN_num_bytes(rsa->n);
        +	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
        +	if (ispub)
        +		{
        +		*pmagic = MS_RSA1MAGIC;
        +		return bitlen;
        +		}
        +	else
        +	{
        +		*pmagic = MS_RSA2MAGIC;
        +		/* For private key each component must fit within nbyte or
        +		 * hnbyte.
        +		 */
        +		if (BN_num_bytes(rsa->d) > nbyte)
        +			goto badkey;
        +		if ((BN_num_bytes(rsa->iqmp) > hnbyte)
        +			|| (BN_num_bytes(rsa->p) > hnbyte)
        +			|| (BN_num_bytes(rsa->q) > hnbyte)
        +			|| (BN_num_bytes(rsa->dmp1) > hnbyte)
        +			|| (BN_num_bytes(rsa->dmq1) > hnbyte))
        +			goto badkey;
        +	}
        +	return bitlen;
        +	badkey:
        +	PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
        +	return 0;
        +	}
        +
        +
        +static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
        +	{
        +	int nbyte, hnbyte;
        +	nbyte = BN_num_bytes(rsa->n);
        +	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
        +	write_lebn(out, rsa->e, 4);
        +	write_lebn(out, rsa->n, -1);
        +	if (ispub)
        +		return;
        +	write_lebn(out, rsa->p, hnbyte);
        +	write_lebn(out, rsa->q, hnbyte);
        +	write_lebn(out, rsa->dmp1, hnbyte);
        +	write_lebn(out, rsa->dmq1, hnbyte);
        +	write_lebn(out, rsa->iqmp, hnbyte);
        +	write_lebn(out, rsa->d, nbyte);
        +	}
        +
        +	
        +static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
        +	{
        +	int nbyte;
        +	nbyte = BN_num_bytes(dsa->p);
        +	write_lebn(out, dsa->p, nbyte);
        +	write_lebn(out, dsa->q, 20);
        +	write_lebn(out, dsa->g, nbyte);
        +	if (ispub)
        +		write_lebn(out, dsa->pub_key, nbyte);
        +	else
        +		write_lebn(out, dsa->priv_key, 20);
        +	/* Set "invalid" for seed structure values */
        +	memset(*out, 0xff, 24);
        +	*out += 24;
        +	return;
        +	}
        +	
        +
        +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
        +	{
        +	return do_i2b_bio(out, pk, 0);
        +	}
        +
        +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
        +	{
        +	return do_i2b_bio(out, pk, 1);
        +	}
        +
        +#ifndef OPENSSL_NO_RC4
        +
        +static int do_PVK_header(const unsigned char **in, unsigned int length,
        +		int skip_magic,
        +	       	unsigned int *psaltlen, unsigned int *pkeylen)
        +		
        +	{
        +	const unsigned char *p = *in;
        +	unsigned int pvk_magic, is_encrypted;
        +	if (skip_magic)
        +		{
        +		if (length < 20)
        +			{
        +			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
        +			return 0;
        +			}
        +		length -= 20;
        +		}
        +	else
        +		{
        +		if (length < 24)
        +			{
        +			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
        +			return 0;
        +			}
        +		length -= 24;
        +		pvk_magic = read_ledword(&p);
        +		if (pvk_magic != MS_PVKMAGIC)
        +			{
        +			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
        +			return 0;
        +			}
        +		}
        +	/* Skip reserved */
        +	p += 4;
        +	/*keytype = */read_ledword(&p);
        +	is_encrypted = read_ledword(&p);
        +	*psaltlen = read_ledword(&p);
        +	*pkeylen = read_ledword(&p);
        +
        +	if (is_encrypted && !*psaltlen)
        +		{
        +		PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
        +		return 0;
        +		}
        +
        +	*in = p;
        +	return 1;
        +	}
        +
        +static int derive_pvk_key(unsigned char *key, 
        +			const unsigned char *salt, unsigned int saltlen,
        +			const unsigned char *pass, int passlen)
        +	{
        +	EVP_MD_CTX mctx;
        +	int rv = 1;
        +	EVP_MD_CTX_init(&mctx);
        +	if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL)
        +		|| !EVP_DigestUpdate(&mctx, salt, saltlen)
        +		|| !EVP_DigestUpdate(&mctx, pass, passlen)
        +		|| !EVP_DigestFinal_ex(&mctx, key, NULL))
        +			rv = 0;
        +
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return rv;
        +	}
        +	
        +
        +static EVP_PKEY *do_PVK_body(const unsigned char **in,
        +		unsigned int saltlen, unsigned int keylen,
        +		pem_password_cb *cb, void *u)
        +	{
        +	EVP_PKEY *ret = NULL;
        +	const unsigned char *p = *in;
        +	unsigned int magic;
        +	unsigned char *enctmp = NULL, *q;
        +	EVP_CIPHER_CTX cctx;
        +	EVP_CIPHER_CTX_init(&cctx);
        +	if (saltlen)
        +		{
        +		char psbuf[PEM_BUFSIZE];
        +		unsigned char keybuf[20];
        +		int enctmplen, inlen;
        +		if (cb)
        +			inlen=cb(psbuf,PEM_BUFSIZE,0,u);
        +		else
        +			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
        +		if (inlen <= 0)
        +			{
        +			PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ);
        +			return NULL;
        +			}
        +		enctmp = OPENSSL_malloc(keylen + 8);
        +		if (!enctmp)
        +			{
        +			PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +			}
        +		if (!derive_pvk_key(keybuf, p, saltlen,
        +			    (unsigned char *)psbuf, inlen))
        +			return NULL;
        +		p += saltlen;
        +		/* Copy BLOBHEADER across, decrypt rest */
        +		memcpy(enctmp, p, 8);
        +		p += 8;
        +		inlen = keylen - 8;
        +		q = enctmp + 8;
        +		if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
        +			goto err;
        +		if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
        +			goto err;
        +		if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
        +			goto err;
        +		magic = read_ledword((const unsigned char **)&q);
        +		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
        +			{
        +			q = enctmp + 8;
        +			memset(keybuf + 5, 0, 11);
        +			if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
        +								NULL))
        +				goto err;
        +			OPENSSL_cleanse(keybuf, 20);
        +			if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
        +				goto err;
        +			if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen,
        +								&enctmplen))
        +				goto err;
        +			magic = read_ledword((const unsigned char **)&q);
        +			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
        +				{
        +				PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
        +				goto err;
        +				}
        +			}
        +		else
        +			OPENSSL_cleanse(keybuf, 20);
        +		p = enctmp;
        +		}
        +
        +	ret = b2i_PrivateKey(&p, keylen);
        +	err:
        +	EVP_CIPHER_CTX_cleanup(&cctx);
        +	if (enctmp && saltlen)
        +		OPENSSL_free(enctmp);
        +	return ret;
        +	}
        +
        +
        +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
        +	{
        +	unsigned char pvk_hdr[24], *buf = NULL;
        +	const unsigned char *p;
        +	int buflen;
        +	EVP_PKEY *ret = NULL;
        +	unsigned int saltlen, keylen;
        +	if (BIO_read(in, pvk_hdr, 24) != 24)
        +		{
        +		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
        +		return NULL;
        +		}
        +	p = pvk_hdr;
        +
        +	if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
        +		return 0;
        +	buflen = (int) keylen + saltlen;
        +	buf = OPENSSL_malloc(buflen);
        +	if (!buf)
        +		{
        +		PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	p = buf;
        +	if (BIO_read(in, buf, buflen) != buflen)
        +		{
        +		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
        +		goto err;
        +		}
        +	ret = do_PVK_body(&p, saltlen, keylen, cb, u);
        +
        +	err:
        +	if (buf)
        +		{
        +		OPENSSL_cleanse(buf, buflen);
        +		OPENSSL_free(buf);
        +		}
        +	return ret;
        +	}
        +
        +	
        +	
        +static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
        +		pem_password_cb *cb, void *u)
        +	{
        +	int outlen = 24, pklen;
        +	unsigned char *p, *salt = NULL;
        +	EVP_CIPHER_CTX cctx;
        +	EVP_CIPHER_CTX_init(&cctx);
        +	if (enclevel)
        +		outlen += PVK_SALTLEN;
        +	pklen = do_i2b(NULL, pk, 0);
        +	if (pklen < 0)
        +		return -1;
        +	outlen += pklen;
        +	if (!out)
        +		return outlen;
        +	if (*out)
        +		p = *out;
        +	else
        +		{
        +		p = OPENSSL_malloc(outlen);
        +		if (!p)
        +			{
        +			PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		*out = p;
        +		}
        +
        +	write_ledword(&p, MS_PVKMAGIC);
        +	write_ledword(&p, 0);
        +	if (pk->type == EVP_PKEY_DSA)
        +		write_ledword(&p, MS_KEYTYPE_SIGN);
        +	else
        +		write_ledword(&p, MS_KEYTYPE_KEYX);
        +	write_ledword(&p, enclevel ? 1 : 0);
        +	write_ledword(&p, enclevel ? PVK_SALTLEN: 0);
        +	write_ledword(&p, pklen);
        +	if (enclevel)
        +		{
        +		if (RAND_bytes(p, PVK_SALTLEN) <= 0)
        +			goto error;
        +		salt = p;
        +		p += PVK_SALTLEN;
        +		}
        +	do_i2b(&p, pk, 0);
        +	if (enclevel == 0)
        +		return outlen;
        +	else
        +		{
        +		char psbuf[PEM_BUFSIZE];
        +		unsigned char keybuf[20];
        +		int enctmplen, inlen;
        +		if (cb)
        +			inlen=cb(psbuf,PEM_BUFSIZE,1,u);
        +		else
        +			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u);
        +		if (inlen <= 0)
        +			{
        +			PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ);
        +			goto error;
        +			}
        +		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
        +			    (unsigned char *)psbuf, inlen))
        +			goto error;
        +		if (enclevel == 1)
        +			memset(keybuf + 5, 0, 11);
        +		p = salt + PVK_SALTLEN + 8;
        +		if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
        +			goto error;
        +		OPENSSL_cleanse(keybuf, 20);
        +		if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
        +			goto error;
        +		if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
        +			goto error;
        +		}
        +	EVP_CIPHER_CTX_cleanup(&cctx);
        +	return outlen;
        +
        +	error:
        +	EVP_CIPHER_CTX_cleanup(&cctx);
        +	return -1;
        +	}
        +
        +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
        +		pem_password_cb *cb, void *u)
        +	{
        +	unsigned char *tmp = NULL;
        +	int outlen, wrlen;
        +	outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
        +	if (outlen < 0)
        +		return -1;
        +	wrlen = BIO_write(out, tmp, outlen);
        +	OPENSSL_free(tmp);
        +	if (wrlen == outlen)
        +		{
        +		PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
        +		return outlen;
        +		}
        +	return -1;
        +	}
        +
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/perlasm/cbc.pl b/vendor/openssl/openssl/crypto/perlasm/cbc.pl
        new file mode 100644
        index 000000000..24561e759
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/cbc.pl
        @@ -0,0 +1,349 @@
        +#!/usr/local/bin/perl
        +
        +# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
        +# des_cblock (*input);
        +# des_cblock (*output);
        +# long length;
        +# des_key_schedule schedule;
        +# des_cblock (*ivec);
        +# int enc;
        +#
        +# calls 
        +# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
        +#
        +
        +#&cbc("des_ncbc_encrypt","des_encrypt",0);
        +#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
        +#	1,4,5,3,5,-1);
        +#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
        +#	0,4,5,3,5,-1);
        +#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
        +#	0,6,7,3,4,5);
        +#
        +# When doing a cipher that needs bigendian order,
        +# for encrypt, the iv is kept in bigendian form,
        +# while for decrypt, it is kept in little endian.
        +sub cbc
        +	{
        +	local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
        +	# name is the function name
        +	# enc_func and dec_func and the functions to call for encrypt/decrypt
        +	# swap is true if byte order needs to be reversed
        +	# iv_off is parameter number for the iv 
        +	# enc_off is parameter number for the encrypt/decrypt flag
        +	# p1,p2,p3 are the offsets for parameters to be passed to the
        +	# underlying calls.
        +
        +	&function_begin_B($name,"");
        +	&comment("");
        +
        +	$in="esi";
        +	$out="edi";
        +	$count="ebp";
        +
        +	&push("ebp");
        +	&push("ebx");
        +	&push("esi");
        +	&push("edi");
        +
        +	$data_off=4;
        +	$data_off+=4 if ($p1 > 0);
        +	$data_off+=4 if ($p2 > 0);
        +	$data_off+=4 if ($p3 > 0);
        +
        +	&mov($count,	&wparam(2));	# length
        +
        +	&comment("getting iv ptr from parameter $iv_off");
        +	&mov("ebx",	&wparam($iv_off));	# Get iv ptr
        +
        +	&mov($in,	&DWP(0,"ebx","",0));#	iv[0]
        +	&mov($out,	&DWP(4,"ebx","",0));#	iv[1]
        +
        +	&push($out);
        +	&push($in);
        +	&push($out);	# used in decrypt for iv[1]
        +	&push($in);	# used in decrypt for iv[0]
        +
        +	&mov("ebx",	"esp");		# This is the address of tin[2]
        +
        +	&mov($in,	&wparam(0));	# in
        +	&mov($out,	&wparam(1));	# out
        +
        +	# We have loaded them all, how lets push things
        +	&comment("getting encrypt flag from parameter $enc_off");
        +	&mov("ecx",	&wparam($enc_off));	# Get enc flag
        +	if ($p3 > 0)
        +		{
        +		&comment("get and push parameter $p3");
        +		if ($enc_off != $p3)
        +			{ &mov("eax",	&wparam($p3)); &push("eax"); }
        +		else	{ &push("ecx"); }
        +		}
        +	if ($p2 > 0)
        +		{
        +		&comment("get and push parameter $p2");
        +		if ($enc_off != $p2)
        +			{ &mov("eax",	&wparam($p2)); &push("eax"); }
        +		else	{ &push("ecx"); }
        +		}
        +	if ($p1 > 0)
        +		{
        +		&comment("get and push parameter $p1");
        +		if ($enc_off != $p1)
        +			{ &mov("eax",	&wparam($p1)); &push("eax"); }
        +		else	{ &push("ecx"); }
        +		}
        +	&push("ebx");		# push data/iv
        +
        +	&cmp("ecx",0);
        +	&jz(&label("decrypt"));
        +
        +	&and($count,0xfffffff8);
        +	&mov("eax",	&DWP($data_off,"esp","",0));	# load iv[0]
        +	&mov("ebx",	&DWP($data_off+4,"esp","",0));	# load iv[1]
        +
        +	&jz(&label("encrypt_finish"));
        +
        +	#############################################################
        +
        +	&set_label("encrypt_loop");
        +	# encrypt start 
        +	# "eax" and "ebx" hold iv (or the last cipher text)
        +
        +	&mov("ecx",	&DWP(0,$in,"",0));	# load first 4 bytes
        +	&mov("edx",	&DWP(4,$in,"",0));	# second 4 bytes
        +
        +	&xor("eax",	"ecx");
        +	&xor("ebx",	"edx");
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
        +	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
        +
        +	&call($enc_func);
        +
        +	&mov("eax",	&DWP($data_off,"esp","",0));
        +	&mov("ebx",	&DWP($data_off+4,"esp","",0));
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov(&DWP(0,$out,"",0),"eax");
        +	&mov(&DWP(4,$out,"",0),"ebx");
        +
        +	# eax and ebx are the next iv.
        +
        +	&add($in,	8);
        +	&add($out,	8);
        +
        +	&sub($count,	8);
        +	&jnz(&label("encrypt_loop"));
        +
        +###################################################################3
        +	&set_label("encrypt_finish");
        +	&mov($count,	&wparam(2));	# length
        +	&and($count,	7);
        +	&jz(&label("finish"));
        +	&call(&label("PIC_point"));
        +&set_label("PIC_point");
        +	&blindpop("edx");
        +	&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
        +	&mov($count,&DWP(0,"ecx",$count,4));
        +	&add($count,"edx");
        +	&xor("ecx","ecx");
        +	&xor("edx","edx");
        +	#&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
        +	&jmp_ptr($count);
        +
        +&set_label("ej7");
        +	&movb(&HB("edx"),	&BP(6,$in,"",0));
        +	&shl("edx",8);
        +&set_label("ej6");
        +	&movb(&HB("edx"),	&BP(5,$in,"",0));
        +&set_label("ej5");
        +	&movb(&LB("edx"),	&BP(4,$in,"",0));
        +&set_label("ej4");
        +	&mov("ecx",		&DWP(0,$in,"",0));
        +	&jmp(&label("ejend"));
        +&set_label("ej3");
        +	&movb(&HB("ecx"),	&BP(2,$in,"",0));
        +	&shl("ecx",8);
        +&set_label("ej2");
        +	&movb(&HB("ecx"),	&BP(1,$in,"",0));
        +&set_label("ej1");
        +	&movb(&LB("ecx"),	&BP(0,$in,"",0));
        +&set_label("ejend");
        +
        +	&xor("eax",	"ecx");
        +	&xor("ebx",	"edx");
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
        +	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
        +
        +	&call($enc_func);
        +
        +	&mov("eax",	&DWP($data_off,"esp","",0));
        +	&mov("ebx",	&DWP($data_off+4,"esp","",0));
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov(&DWP(0,$out,"",0),"eax");
        +	&mov(&DWP(4,$out,"",0),"ebx");
        +
        +	&jmp(&label("finish"));
        +
        +	#############################################################
        +	#############################################################
        +	&set_label("decrypt",1);
        +	# decrypt start 
        +	&and($count,0xfffffff8);
        +	# The next 2 instructions are only for if the jz is taken
        +	&mov("eax",	&DWP($data_off+8,"esp","",0));	# get iv[0]
        +	&mov("ebx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
        +	&jz(&label("decrypt_finish"));
        +
        +	&set_label("decrypt_loop");
        +	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
        +	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
        +	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
        +
        +	&call($dec_func);
        +
        +	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
        +	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
        +	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
        +
        +	&xor("ecx",	"eax");
        +	&xor("edx",	"ebx");
        +
        +	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
        +	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
        +
        +	&mov(&DWP(0,$out,"",0),"ecx");
        +	&mov(&DWP(4,$out,"",0),"edx");
        +
        +	&mov(&DWP($data_off+8,"esp","",0),	"eax");	# save iv
        +	&mov(&DWP($data_off+12,"esp","",0),	"ebx");	#
        +
        +	&add($in,	8);
        +	&add($out,	8);
        +
        +	&sub($count,	8);
        +	&jnz(&label("decrypt_loop"));
        +############################ ENDIT #######################3
        +	&set_label("decrypt_finish");
        +	&mov($count,	&wparam(2));	# length
        +	&and($count,	7);
        +	&jz(&label("finish"));
        +
        +	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
        +	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
        +	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
        +
        +	&call($dec_func);
        +
        +	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
        +	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
        +
        +	&bswap("eax")	if $swap;
        +	&bswap("ebx")	if $swap;
        +
        +	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
        +	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
        +
        +	&xor("ecx",	"eax");
        +	&xor("edx",	"ebx");
        +
        +	# this is for when we exit
        +	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
        +	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
        +
        +&set_label("dj7");
        +	&rotr("edx",	16);
        +	&movb(&BP(6,$out,"",0),	&LB("edx"));
        +	&shr("edx",16);
        +&set_label("dj6");
        +	&movb(&BP(5,$out,"",0),	&HB("edx"));
        +&set_label("dj5");
        +	&movb(&BP(4,$out,"",0),	&LB("edx"));
        +&set_label("dj4");
        +	&mov(&DWP(0,$out,"",0),	"ecx");
        +	&jmp(&label("djend"));
        +&set_label("dj3");
        +	&rotr("ecx",	16);
        +	&movb(&BP(2,$out,"",0),	&LB("ecx"));
        +	&shl("ecx",16);
        +&set_label("dj2");
        +	&movb(&BP(1,$in,"",0),	&HB("ecx"));
        +&set_label("dj1");
        +	&movb(&BP(0,$in,"",0),	&LB("ecx"));
        +&set_label("djend");
        +
        +	# final iv is still in eax:ebx
        +	&jmp(&label("finish"));
        +
        +
        +############################ FINISH #######################3
        +	&set_label("finish",1);
        +	&mov("ecx",	&wparam($iv_off));	# Get iv ptr
        +
        +	#################################################
        +	$total=16+4;
        +	$total+=4 if ($p1 > 0);
        +	$total+=4 if ($p2 > 0);
        +	$total+=4 if ($p3 > 0);
        +	&add("esp",$total);
        +
        +	&mov(&DWP(0,"ecx","",0),	"eax");	# save iv
        +	&mov(&DWP(4,"ecx","",0),	"ebx");	# save iv
        +
        +	&function_end_A($name);
        +
        +	&align(64);
        +	&set_label("cbc_enc_jmp_table");
        +	&data_word("0");
        +	&data_word(&label("ej1")."-".&label("PIC_point"));
        +	&data_word(&label("ej2")."-".&label("PIC_point"));
        +	&data_word(&label("ej3")."-".&label("PIC_point"));
        +	&data_word(&label("ej4")."-".&label("PIC_point"));
        +	&data_word(&label("ej5")."-".&label("PIC_point"));
        +	&data_word(&label("ej6")."-".&label("PIC_point"));
        +	&data_word(&label("ej7")."-".&label("PIC_point"));
        +	# not used
        +	#&set_label("cbc_dec_jmp_table",1);
        +	#&data_word("0");
        +	#&data_word(&label("dj1")."-".&label("PIC_point"));
        +	#&data_word(&label("dj2")."-".&label("PIC_point"));
        +	#&data_word(&label("dj3")."-".&label("PIC_point"));
        +	#&data_word(&label("dj4")."-".&label("PIC_point"));
        +	#&data_word(&label("dj5")."-".&label("PIC_point"));
        +	#&data_word(&label("dj6")."-".&label("PIC_point"));
        +	#&data_word(&label("dj7")."-".&label("PIC_point"));
        +	&align(64);
        +
        +	&function_end_B($name);
        +	
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/perlasm/ppc-xlate.pl b/vendor/openssl/openssl/crypto/perlasm/ppc-xlate.pl
        new file mode 100644
        index 000000000..a3edd982b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/ppc-xlate.pl
        @@ -0,0 +1,159 @@
        +#!/usr/bin/env perl
        +
        +# PowerPC assembler distiller by <appro>.
        +
        +my $flavour = shift;
        +my $output = shift;
        +open STDOUT,">$output" || die "can't open $output: $!";
        +
        +my %GLOBALS;
        +my $dotinlocallabels=($flavour=~/linux/)?1:0;
        +
        +################################################################
        +# directives which need special treatment on different platforms
        +################################################################
        +my $globl = sub {
        +    my $junk = shift;
        +    my $name = shift;
        +    my $global = \$GLOBALS{$name};
        +    my $ret;
        +
        +    $name =~ s|^[\.\_]||;
        + 
        +    SWITCH: for ($flavour) {
        +	/aix/		&& do { $name = ".$name";
        +				last;
        +			      };
        +	/osx/		&& do { $name = "_$name";
        +				last;
        +			      };
        +	/linux.*32/	&& do {	$ret .= ".globl	$name\n";
        +				$ret .= ".type	$name,\@function";
        +				last;
        +			      };
        +	/linux.*64/	&& do {	$ret .= ".globl	$name\n";
        +				$ret .= ".type	$name,\@function\n";
        +				$ret .= ".section	\".opd\",\"aw\"\n";
        +				$ret .= ".align	3\n";
        +				$ret .= "$name:\n";
        +				$ret .= ".quad	.$name,.TOC.\@tocbase,0\n";
        +				$ret .= ".size	$name,24\n";
        +				$ret .= ".previous\n";
        +
        +				$name = ".$name";
        +				last;
        +			      };
        +    }
        +
        +    $ret = ".globl	$name" if (!$ret);
        +    $$global = $name;
        +    $ret;
        +};
        +my $text = sub {
        +    ($flavour =~ /aix/) ? ".csect" : ".text";
        +};
        +my $machine = sub {
        +    my $junk = shift;
        +    my $arch = shift;
        +    if ($flavour =~ /osx/)
        +    {	$arch =~ s/\"//g;
        +	$arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
        +    }
        +    ".machine	$arch";
        +};
        +my $size = sub {
        +    if ($flavour =~ /linux.*32/)
        +    {	shift;
        +	".size	" . join(",",@_);
        +    }
        +    else
        +    {	"";	}
        +};
        +my $asciz = sub {
        +    shift;
        +    my $line = join(",",@_);
        +    if ($line =~ /^"(.*)"$/)
        +    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
        +    else
        +    {	"";	}
        +};
        +
        +################################################################
        +# simplified mnemonics not handled by at least one assembler
        +################################################################
        +my $cmplw = sub {
        +    my $f = shift;
        +    my $cr = 0; $cr = shift if ($#_>1);
        +    # Some out-of-date 32-bit GNU assembler just can't handle cmplw...
        +    ($flavour =~ /linux.*32/) ?
        +	"	.long	".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
        +	"	cmplw	".join(',',$cr,@_);
        +};
        +my $bdnz = sub {
        +    my $f = shift;
        +    my $bo = $f=~/[\+\-]/ ? 16+9 : 16;	# optional "to be taken" hint
        +    "	bc	$bo,0,".shift;
        +} if ($flavour!~/linux/);
        +my $bltlr = sub {
        +    my $f = shift;
        +    my $bo = $f=~/\-/ ? 12+2 : 12;	# optional "not to be taken" hint
        +    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
        +	"	.long	".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
        +	"	bclr	$bo,0";
        +};
        +my $bnelr = sub {
        +    my $f = shift;
        +    my $bo = $f=~/\-/ ? 4+2 : 4;	# optional "not to be taken" hint
        +    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
        +	"	.long	".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
        +	"	bclr	$bo,2";
        +};
        +my $beqlr = sub {
        +    my $f = shift;
        +    my $bo = $f=~/-/ ? 12+2 : 12;	# optional "not to be taken" hint
        +    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
        +	"	.long	".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
        +	"	bclr	$bo,2";
        +};
        +# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
        +# arguments is 64, with "operand out of range" error.
        +my $extrdi = sub {
        +    my ($f,$ra,$rs,$n,$b) = @_;
        +    $b = ($b+$n)&63; $n = 64-$n;
        +    "	rldicl	$ra,$rs,$b,$n";
        +};
        +
        +while($line=<>) {
        +
        +    $line =~ s|[#!;].*$||;	# get rid of asm-style comments...
        +    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
        +    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
        +    $line =~ s|\s+$||;		# ... and at the end
        +
        +    {
        +	$line =~ s|\b\.L(\w+)|L$1|g;	# common denominator for Locallabel
        +	$line =~ s|\bL(\w+)|\.L$1|g	if ($dotinlocallabels);
        +    }
        +
        +    {
        +	$line =~ s|(^[\.\w]+)\:\s*||;
        +	my $label = $1;
        +	printf "%s:",($GLOBALS{$label} or $label) if ($label);
        +    }
        +
        +    {
        +	$line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
        +	my $c = $1; $c = "\t" if ($c eq "");
        +	my $mnemonic = $2;
        +	my $f = $3;
        +	my $opcode = eval("\$$mnemonic");
        +	$line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/);
        +	if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
        +	elsif ($mnemonic)           { $line = $c.$mnemonic.$f."\t".$line; }
        +    }
        +
        +    print $line if ($line);
        +    print "\n";
        +}
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/perlasm/readme b/vendor/openssl/openssl/crypto/perlasm/readme
        new file mode 100644
        index 000000000..f02bbee75
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/readme
        @@ -0,0 +1,124 @@
        +The perl scripts in this directory are my 'hack' to generate
        +multiple different assembler formats via the one origional script.
        +
        +The way to use this library is to start with adding the path to this directory
        +and then include it.
        +
        +push(@INC,"perlasm","../../perlasm");
        +require "x86asm.pl";
        +
        +The first thing we do is setup the file and type of assember
        +
        +&asm_init($ARGV[0],$0);
        +
        +The first argument is the 'type'.  Currently
        +'cpp', 'sol', 'a.out', 'elf' or 'win32'.
        +Argument 2 is the file name.
        +
        +The reciprocal function is
        +&asm_finish() which should be called at the end.
        +
        +There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
        +and x86unix.pl which is the unix (gas) version.
        +
        +Functions of interest are:
        +&external_label("des_SPtrans");	declare and external variable
        +&LB(reg);			Low byte for a register
        +&HB(reg);			High byte for a register
        +&BP(off,base,index,scale)	Byte pointer addressing
        +&DWP(off,base,index,scale)	Word pointer addressing
        +&stack_push(num)		Basically a 'sub esp, num*4' with extra
        +&stack_pop(num)			inverse of stack_push
        +&function_begin(name,extra)	Start a function with pushing of
        +				edi, esi, ebx and ebp.  extra is extra win32
        +				external info that may be required.
        +&function_begin_B(name,extra)	Same as norma function_begin but no pushing.
        +&function_end(name)		Call at end of function.
        +&function_end_A(name)		Standard pop and ret, for use inside functions
        +&function_end_B(name)		Call at end but with poping or 'ret'.
        +&swtmp(num)			Address on stack temp word.
        +&wparam(num)			Parameter number num, that was push
        +				in C convention.  This all works over pushes
        +				and pops.
        +&comment("hello there")		Put in a comment.
        +&label("loop")			Refer to a label, normally a jmp target.
        +&set_label("loop")		Set a label at this point.
        +&data_word(word)		Put in a word of data.
        +
        +So how does this all hold together?  Given
        +
        +int calc(int len, int *data)
        +	{
        +	int i,j=0;
        +
        +	for (i=0; i<len; i++)
        +		{
        +		j+=other(data[i]);
        +		}
        +	}
        +
        +So a very simple version of this function could be coded as
        +
        +	push(@INC,"perlasm","../../perlasm");
        +	require "x86asm.pl";
        +	
        +	&asm_init($ARGV[0],"cacl.pl");
        +
        +	&external_label("other");
        +
        +	$tmp1=	"eax";
        +	$j=	"edi";
        +	$data=	"esi";
        +	$i=	"ebp";
        +
        +	&comment("a simple function");
        +	&function_begin("calc");
        +	&mov(	$data,		&wparam(1)); # data
        +	&xor(	$j,		$j);
        +	&xor(	$i,		$i);
        +
        +	&set_label("loop");
        +	&cmp(	$i,		&wparam(0));
        +	&jge(	&label("end"));
        +
        +	&mov(	$tmp1,		&DWP(0,$data,$i,4));
        +	&push(	$tmp1);
        +	&call(	"other");
        +	&add(	$j,		"eax");
        +	&pop(	$tmp1);
        +	&inc(	$i);
        +	&jmp(	&label("loop"));
        +
        +	&set_label("end");
        +	&mov(	"eax",		$j);
        +
        +	&function_end("calc");
        +
        +	&asm_finish();
        +
        +The above example is very very unoptimised but gives an idea of how
        +things work.
        +
        +There is also a cbc mode function generator in cbc.pl
        +
        +&cbc(	$name,
        +	$encrypt_function_name,
        +	$decrypt_function_name,
        +	$true_if_byte_swap_needed,
        +	$parameter_number_for_iv,
        +	$parameter_number_for_encrypt_flag,
        +	$first_parameter_to_pass,
        +	$second_parameter_to_pass,
        +	$third_parameter_to_pass);
        +
        +So for example, given
        +void BF_encrypt(BF_LONG *data,BF_KEY *key);
        +void BF_decrypt(BF_LONG *data,BF_KEY *key);
        +void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
        +        BF_KEY *ks, unsigned char *iv, int enc);
        +
        +&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
        +
        +&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
        +&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
        +
        diff --git a/vendor/openssl/openssl/crypto/perlasm/x86_64-xlate.pl b/vendor/openssl/openssl/crypto/perlasm/x86_64-xlate.pl
        new file mode 100644
        index 000000000..56d9b64b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/x86_64-xlate.pl
        @@ -0,0 +1,1080 @@
        +#!/usr/bin/env perl
        +
        +# Ascetic x86_64 AT&T to MASM/NASM assembler translator by <appro>.
        +#
        +# Why AT&T to MASM and not vice versa? Several reasons. Because AT&T
        +# format is way easier to parse. Because it's simpler to "gear" from
        +# Unix ABI to Windows one [see cross-reference "card" at the end of
        +# file]. Because Linux targets were available first...
        +#
        +# In addition the script also "distills" code suitable for GNU
        +# assembler, so that it can be compiled with more rigid assemblers,
        +# such as Solaris /usr/ccs/bin/as.
        +#
        +# This translator is not designed to convert *arbitrary* assembler
        +# code from AT&T format to MASM one. It's designed to convert just
        +# enough to provide for dual-ABI OpenSSL modules development...
        +# There *are* limitations and you might have to modify your assembler
        +# code or this script to achieve the desired result...
        +#
        +# Currently recognized limitations:
        +#
        +# - can't use multiple ops per line;
        +#
        +# Dual-ABI styling rules.
        +#
        +# 1. Adhere to Unix register and stack layout [see cross-reference
        +#    ABI "card" at the end for explanation].
        +# 2. Forget about "red zone," stick to more traditional blended
        +#    stack frame allocation. If volatile storage is actually required
        +#    that is. If not, just leave the stack as is.
        +# 3. Functions tagged with ".type name,@function" get crafted with
        +#    unified Win64 prologue and epilogue automatically. If you want
        +#    to take care of ABI differences yourself, tag functions as
        +#    ".type name,@abi-omnipotent" instead.
        +# 4. To optimize the Win64 prologue you can specify number of input
        +#    arguments as ".type name,@function,N." Keep in mind that if N is
        +#    larger than 6, then you *have to* write "abi-omnipotent" code,
        +#    because >6 cases can't be addressed with unified prologue.
        +# 5. Name local labels as .L*, do *not* use dynamic labels such as 1:
        +#    (sorry about latter).
        +# 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is
        +#    required to identify the spots, where to inject Win64 epilogue!
        +#    But on the pros, it's then prefixed with rep automatically:-)
        +# 7. Stick to explicit ip-relative addressing. If you have to use
        +#    GOTPCREL addressing, stick to mov symbol@GOTPCREL(%rip),%r??.
        +#    Both are recognized and translated to proper Win64 addressing
        +#    modes. To support legacy code a synthetic directive, .picmeup,
        +#    is implemented. It puts address of the *next* instruction into
        +#    target register, e.g.:
        +#
        +#		.picmeup	%rax
        +#		lea		.Label-.(%rax),%rax
        +#
        +# 8. In order to provide for structured exception handling unified
        +#    Win64 prologue copies %rsp value to %rax. For further details
        +#    see SEH paragraph at the end.
        +# 9. .init segment is allowed to contain calls to functions only.
        +# a. If function accepts more than 4 arguments *and* >4th argument
        +#    is declared as non 64-bit value, do clear its upper part.
        +
        +my $flavour = shift;
        +my $output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +open STDOUT,">$output" || die "can't open $output: $!"
        +	if (defined($output));
        +
        +my $gas=1;	$gas=0 if ($output =~ /\.asm$/);
        +my $elf=1;	$elf=0 if (!$gas);
        +my $win64=0;
        +my $prefix="";
        +my $decor=".L";
        +
        +my $masmref=8 + 50727*2**-32;	# 8.00.50727 shipped with VS2005
        +my $masm=0;
        +my $PTR=" PTR";
        +
        +my $nasmref=2.03;
        +my $nasm=0;
        +
        +if    ($flavour eq "mingw64")	{ $gas=1; $elf=0; $win64=1;
        +				  $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
        +				  chomp($prefix);
        +				}
        +elsif ($flavour eq "macosx")	{ $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
        +elsif ($flavour eq "masm")	{ $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
        +elsif ($flavour eq "nasm")	{ $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
        +elsif (!$gas)
        +{   if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
        +    {	$nasm = $1 + $2*0.01; $PTR="";  }
        +    elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
        +    {	$masm = $1 + $2*2**-16 + $4*2**-32;   }
        +    die "no assembler found on %PATH" if (!($nasm || $masm));
        +    $win64=1;
        +    $elf=0;
        +    $decor="\$L\$";
        +}
        +
        +my $current_segment;
        +my $current_function;
        +my %globals;
        +
        +{ package opcode;	# pick up opcodes
        +    sub re {
        +	my	$self = shift;	# single instance in enough...
        +	local	*line = shift;
        +	undef	$ret;
        +
        +	if ($line =~ /^([a-z][a-z0-9]*)/i) {
        +	    $self->{op} = $1;
        +	    $ret = $self;
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +
        +	    undef $self->{sz};
        +	    if ($self->{op} =~ /^(movz)x?([bw]).*/) {	# movz is pain...
        +		$self->{op} = $1;
        +		$self->{sz} = $2;
        +	    } elsif ($self->{op} =~ /call|jmp/) {
        +		$self->{sz} = "";
        +	    } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn
        +		$self->{sz} = "";
        +	    } elsif ($self->{op} =~ /^v/) { # VEX
        +		$self->{sz} = "";
        +	    } elsif ($self->{op} =~ /movq/ && $line =~ /%xmm/) {
        +		$self->{sz} = "";
        +	    } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
        +		$self->{op} = $1;
        +		$self->{sz} = $2;
        +	    }
        +	}
        +	$ret;
        +    }
        +    sub size {
        +	my $self = shift;
        +	my $sz   = shift;
        +	$self->{sz} = $sz if (defined($sz) && !defined($self->{sz}));
        +	$self->{sz};
        +    }
        +    sub out {
        +	my $self = shift;
        +	if ($gas) {
        +	    if ($self->{op} eq "movz") {	# movz is pain...
        +		sprintf "%s%s%s",$self->{op},$self->{sz},shift;
        +	    } elsif ($self->{op} =~ /^set/) { 
        +		"$self->{op}";
        +	    } elsif ($self->{op} eq "ret") {
        +		my $epilogue = "";
        +		if ($win64 && $current_function->{abi} eq "svr4") {
        +		    $epilogue = "movq	8(%rsp),%rdi\n\t" .
        +				"movq	16(%rsp),%rsi\n\t";
        +		}
        +	    	$epilogue . ".byte	0xf3,0xc3";
        +	    } elsif ($self->{op} eq "call" && !$elf && $current_segment eq ".init") {
        +		".p2align\t3\n\t.quad";
        +	    } else {
        +		"$self->{op}$self->{sz}";
        +	    }
        +	} else {
        +	    $self->{op} =~ s/^movz/movzx/;
        +	    if ($self->{op} eq "ret") {
        +		$self->{op} = "";
        +		if ($win64 && $current_function->{abi} eq "svr4") {
        +		    $self->{op} = "mov	rdi,QWORD${PTR}[8+rsp]\t;WIN64 epilogue\n\t".
        +				  "mov	rsi,QWORD${PTR}[16+rsp]\n\t";
        +	    	}
        +		$self->{op} .= "DB\t0F3h,0C3h\t\t;repret";
        +	    } elsif ($self->{op} =~ /^(pop|push)f/) {
        +		$self->{op} .= $self->{sz};
        +	    } elsif ($self->{op} eq "call" && $current_segment eq ".CRT\$XCU") {
        +		$self->{op} = "\tDQ";
        +	    } 
        +	    $self->{op};
        +	}
        +    }
        +    sub mnemonic {
        +	my $self=shift;
        +	my $op=shift;
        +	$self->{op}=$op if (defined($op));
        +	$self->{op};
        +    }
        +}
        +{ package const;	# pick up constants, which start with $
        +    sub re {
        +	my	$self = shift;	# single instance in enough...
        +	local	*line = shift;
        +	undef	$ret;
        +
        +	if ($line =~ /^\$([^,]+)/) {
        +	    $self->{value} = $1;
        +	    $ret = $self;
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +	}
        +	$ret;
        +    }
        +    sub out {
        +    	my $self = shift;
        +
        +	if ($gas) {
        +	    # Solaris /usr/ccs/bin/as can't handle multiplications
        +	    # in $self->{value}
        +	    $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
        +	    $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
        +	    sprintf "\$%s",$self->{value};
        +	} else {
        +	    $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
        +	    $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
        +	    sprintf "%s",$self->{value};
        +	}
        +    }
        +}
        +{ package ea;		# pick up effective addresses: expr(%reg,%reg,scale)
        +    sub re {
        +	my	$self = shift;	# single instance in enough...
        +	local	*line = shift;
        +	undef	$ret;
        +
        +	# optional * ---vvv--- appears in indirect jmp/call
        +	if ($line =~ /^(\*?)([^\(,]*)\(([%\w,]+)\)/) {
        +	    $self->{asterisk} = $1;
        +	    $self->{label} = $2;
        +	    ($self->{base},$self->{index},$self->{scale})=split(/,/,$3);
        +	    $self->{scale} = 1 if (!defined($self->{scale}));
        +	    $ret = $self;
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +
        +	    if ($win64 && $self->{label} =~ s/\@GOTPCREL//) {
        +		die if (opcode->mnemonic() ne "mov");
        +		opcode->mnemonic("lea");
        +	    }
        +	    $self->{base}  =~ s/^%//;
        +	    $self->{index} =~ s/^%// if (defined($self->{index}));
        +	}
        +	$ret;
        +    }
        +    sub size {}
        +    sub out {
        +    	my $self = shift;
        +	my $sz = shift;
        +
        +	$self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
        +	$self->{label} =~ s/\.L/$decor/g;
        +
        +	# Silently convert all EAs to 64-bit. This is required for
        +	# elder GNU assembler and results in more compact code,
        +	# *but* most importantly AES module depends on this feature!
        +	$self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
        +	$self->{base}  =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
        +
        +	# Solaris /usr/ccs/bin/as can't handle multiplications
        +	# in $self->{label}, new gas requires sign extension...
        +	use integer;
        +	$self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
        +	$self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
        +	$self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
        +
        +	if ($gas) {
        +	    $self->{label} =~ s/^___imp_/__imp__/   if ($flavour eq "mingw64");
        +
        +	    if (defined($self->{index})) {
        +		sprintf "%s%s(%s,%%%s,%d)",$self->{asterisk},
        +					$self->{label},
        +					$self->{base}?"%$self->{base}":"",
        +					$self->{index},$self->{scale};
        +	    } else {
        +		sprintf "%s%s(%%%s)",	$self->{asterisk},$self->{label},$self->{base};
        +	    }
        +	} else {
        +	    %szmap = (	b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR",
        +	    		q=>"QWORD$PTR",o=>"OWORD$PTR",x=>"XMMWORD$PTR" );
        +
        +	    $self->{label} =~ s/\./\$/g;
        +	    $self->{label} =~ s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/ig;
        +	    $self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
        +	    $sz="q" if ($self->{asterisk} || opcode->mnemonic() eq "movq");
        +	    $sz="l" if (opcode->mnemonic() eq "movd");
        +
        +	    if (defined($self->{index})) {
        +		sprintf "%s[%s%s*%d%s]",$szmap{$sz},
        +					$self->{label}?"$self->{label}+":"",
        +					$self->{index},$self->{scale},
        +					$self->{base}?"+$self->{base}":"";
        +	    } elsif ($self->{base} eq "rip") {
        +		sprintf "%s[%s]",$szmap{$sz},$self->{label};
        +	    } else {
        +		sprintf "%s[%s%s]",$szmap{$sz},
        +					$self->{label}?"$self->{label}+":"",
        +					$self->{base};
        +	    }
        +	}
        +    }
        +}
        +{ package register;	# pick up registers, which start with %.
        +    sub re {
        +	my	$class = shift;	# muliple instances...
        +	my	$self = {};
        +	local	*line = shift;
        +	undef	$ret;
        +
        +	# optional * ---vvv--- appears in indirect jmp/call
        +	if ($line =~ /^(\*?)%(\w+)/) {
        +	    bless $self,$class;
        +	    $self->{asterisk} = $1;
        +	    $self->{value} = $2;
        +	    $ret = $self;
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +	}
        +	$ret;
        +    }
        +    sub size {
        +	my	$self = shift;
        +	undef	$ret;
        +
        +	if    ($self->{value} =~ /^r[\d]+b$/i)	{ $ret="b"; }
        +	elsif ($self->{value} =~ /^r[\d]+w$/i)	{ $ret="w"; }
        +	elsif ($self->{value} =~ /^r[\d]+d$/i)	{ $ret="l"; }
        +	elsif ($self->{value} =~ /^r[\w]+$/i)	{ $ret="q"; }
        +	elsif ($self->{value} =~ /^[a-d][hl]$/i){ $ret="b"; }
        +	elsif ($self->{value} =~ /^[\w]{2}l$/i)	{ $ret="b"; }
        +	elsif ($self->{value} =~ /^[\w]{2}$/i)	{ $ret="w"; }
        +	elsif ($self->{value} =~ /^e[a-z]{2}$/i){ $ret="l"; }
        +
        +	$ret;
        +    }
        +    sub out {
        +    	my $self = shift;
        +	if ($gas)	{ sprintf "%s%%%s",$self->{asterisk},$self->{value}; }
        +	else		{ $self->{value}; }
        +    }
        +}
        +{ package label;	# pick up labels, which end with :
        +    sub re {
        +	my	$self = shift;	# single instance is enough...
        +	local	*line = shift;
        +	undef	$ret;
        +
        +	if ($line =~ /(^[\.\w]+)\:/) {
        +	    $self->{value} = $1;
        +	    $ret = $self;
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +
        +	    $self->{value} =~ s/^\.L/$decor/;
        +	}
        +	$ret;
        +    }
        +    sub out {
        +	my $self = shift;
        +
        +	if ($gas) {
        +	    my $func = ($globals{$self->{value}} or $self->{value}) . ":";
        +	    if ($win64	&&
        +			$current_function->{name} eq $self->{value} &&
        +			$current_function->{abi} eq "svr4") {
        +		$func .= "\n";
        +		$func .= "	movq	%rdi,8(%rsp)\n";
        +		$func .= "	movq	%rsi,16(%rsp)\n";
        +		$func .= "	movq	%rsp,%rax\n";
        +		$func .= "${decor}SEH_begin_$current_function->{name}:\n";
        +		my $narg = $current_function->{narg};
        +		$narg=6 if (!defined($narg));
        +		$func .= "	movq	%rcx,%rdi\n" if ($narg>0);
        +		$func .= "	movq	%rdx,%rsi\n" if ($narg>1);
        +		$func .= "	movq	%r8,%rdx\n"  if ($narg>2);
        +		$func .= "	movq	%r9,%rcx\n"  if ($narg>3);
        +		$func .= "	movq	40(%rsp),%r8\n" if ($narg>4);
        +		$func .= "	movq	48(%rsp),%r9\n" if ($narg>5);
        +	    }
        +	    $func;
        +	} elsif ($self->{value} ne "$current_function->{name}") {
        +	    $self->{value} .= ":" if ($masm && $ret!~m/^\$/);
        +	    $self->{value} . ":";
        +	} elsif ($win64 && $current_function->{abi} eq "svr4") {
        +	    my $func =	"$current_function->{name}" .
        +			($nasm ? ":" : "\tPROC $current_function->{scope}") .
        +			"\n";
        +	    $func .= "	mov	QWORD${PTR}[8+rsp],rdi\t;WIN64 prologue\n";
        +	    $func .= "	mov	QWORD${PTR}[16+rsp],rsi\n";
        +	    $func .= "	mov	rax,rsp\n";
        +	    $func .= "${decor}SEH_begin_$current_function->{name}:";
        +	    $func .= ":" if ($masm);
        +	    $func .= "\n";
        +	    my $narg = $current_function->{narg};
        +	    $narg=6 if (!defined($narg));
        +	    $func .= "	mov	rdi,rcx\n" if ($narg>0);
        +	    $func .= "	mov	rsi,rdx\n" if ($narg>1);
        +	    $func .= "	mov	rdx,r8\n"  if ($narg>2);
        +	    $func .= "	mov	rcx,r9\n"  if ($narg>3);
        +	    $func .= "	mov	r8,QWORD${PTR}[40+rsp]\n" if ($narg>4);
        +	    $func .= "	mov	r9,QWORD${PTR}[48+rsp]\n" if ($narg>5);
        +	    $func .= "\n";
        +	} else {
        +	   "$current_function->{name}".
        +			($nasm ? ":" : "\tPROC $current_function->{scope}");
        +	}
        +    }
        +}
        +{ package expr;		# pick up expressioins
        +    sub re {
        +	my	$self = shift;	# single instance is enough...
        +	local	*line = shift;
        +	undef	$ret;
        +
        +	if ($line =~ /(^[^,]+)/) {
        +	    $self->{value} = $1;
        +	    $ret = $self;
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +
        +	    $self->{value} =~ s/\@PLT// if (!$elf);
        +	    $self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
        +	    $self->{value} =~ s/\.L/$decor/g;
        +	}
        +	$ret;
        +    }
        +    sub out {
        +	my $self = shift;
        +	if ($nasm && opcode->mnemonic()=~m/^j/) {
        +	    "NEAR ".$self->{value};
        +	} else {
        +	    $self->{value};
        +	}
        +    }
        +}
        +{ package directive;	# pick up directives, which start with .
        +    sub re {
        +	my	$self = shift;	# single instance is enough...
        +	local	*line = shift;
        +	undef	$ret;
        +	my	$dir;
        +	my	%opcode =	# lea 2f-1f(%rip),%dst; 1: nop; 2:
        +		(	"%rax"=>0x01058d48,	"%rcx"=>0x010d8d48,
        +			"%rdx"=>0x01158d48,	"%rbx"=>0x011d8d48,
        +			"%rsp"=>0x01258d48,	"%rbp"=>0x012d8d48,
        +			"%rsi"=>0x01358d48,	"%rdi"=>0x013d8d48,
        +			"%r8" =>0x01058d4c,	"%r9" =>0x010d8d4c,
        +			"%r10"=>0x01158d4c,	"%r11"=>0x011d8d4c,
        +			"%r12"=>0x01258d4c,	"%r13"=>0x012d8d4c,
        +			"%r14"=>0x01358d4c,	"%r15"=>0x013d8d4c	);
        +
        +	if ($line =~ /^\s*(\.\w+)/) {
        +	    $dir = $1;
        +	    $ret = $self;
        +	    undef $self->{value};
        +	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
        +
        +	    SWITCH: for ($dir) {
        +		/\.picmeup/ && do { if ($line =~ /(%r[\w]+)/i) {
        +			    		$dir="\t.long";
        +					$line=sprintf "0x%x,0x90000000",$opcode{$1};
        +				    }
        +				    last;
        +				  };
        +		/\.global|\.globl|\.extern/
        +			    && do { $globals{$line} = $prefix . $line;
        +				    $line = $globals{$line} if ($prefix);
        +				    last;
        +				  };
        +		/\.type/    && do { ($sym,$type,$narg) = split(',',$line);
        +				    if ($type eq "\@function") {
        +					undef $current_function;
        +					$current_function->{name} = $sym;
        +					$current_function->{abi}  = "svr4";
        +					$current_function->{narg} = $narg;
        +					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
        +				    } elsif ($type eq "\@abi-omnipotent") {
        +					undef $current_function;
        +					$current_function->{name} = $sym;
        +					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
        +				    }
        +				    $line =~ s/\@abi\-omnipotent/\@function/;
        +				    $line =~ s/\@function.*/\@function/;
        +				    last;
        +				  };
        +		/\.asciz/   && do { if ($line =~ /^"(.*)"$/) {
        +					$dir  = ".byte";
        +					$line = join(",",unpack("C*",$1),0);
        +				    }
        +				    last;
        +				  };
        +		/\.rva|\.long|\.quad/
        +			    && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
        +				    $line =~ s/\.L/$decor/g;
        +				    last;
        +				  };
        +	    }
        +
        +	    if ($gas) {
        +		$self->{value} = $dir . "\t" . $line;
        +
        +		if ($dir =~ /\.extern/) {
        +		    $self->{value} = ""; # swallow extern
        +		} elsif (!$elf && $dir =~ /\.type/) {
        +		    $self->{value} = "";
        +		    $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
        +				(defined($globals{$1})?".scl 2;":".scl 3;") .
        +				"\t.type 32;\t.endef"
        +				if ($win64 && $line =~ /([^,]+),\@function/);
        +		} elsif (!$elf && $dir =~ /\.size/) {
        +		    $self->{value} = "";
        +		    if (defined($current_function)) {
        +			$self->{value} .= "${decor}SEH_end_$current_function->{name}:"
        +				if ($win64 && $current_function->{abi} eq "svr4");
        +			undef $current_function;
        +		    }
        +		} elsif (!$elf && $dir =~ /\.align/) {
        +		    $self->{value} = ".p2align\t" . (log($line)/log(2));
        +		} elsif ($dir eq ".section") {
        +		    $current_segment=$line;
        +		    if (!$elf && $current_segment eq ".init") {
        +			if	($flavour eq "macosx")	{ $self->{value} = ".mod_init_func"; }
        +			elsif	($flavour eq "mingw64")	{ $self->{value} = ".section\t.ctors"; }
        +		    }
        +		} elsif ($dir =~ /\.(text|data)/) {
        +		    $current_segment=".$1";
        +		} elsif ($dir =~ /\.hidden/) {
        +		    if    ($flavour eq "macosx")  { $self->{value} = ".private_extern\t$prefix$line"; }
        +		    elsif ($flavour eq "mingw64") { $self->{value} = ""; }
        +		} elsif ($dir =~ /\.comm/) {
        +		    $self->{value} = "$dir\t$prefix$line";
        +		    $self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx");
        +		}
        +		$line = "";
        +		return $self;
        +	    }
        +
        +	    # non-gas case or nasm/masm
        +	    SWITCH: for ($dir) {
        +		/\.text/    && do { my $v=undef;
        +				    if ($nasm) {
        +					$v="section	.text code align=64\n";
        +				    } else {
        +					$v="$current_segment\tENDS\n" if ($current_segment);
        +					$current_segment = ".text\$";
        +					$v.="$current_segment\tSEGMENT ";
        +					$v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
        +					$v.=" 'CODE'";
        +				    }
        +				    $self->{value} = $v;
        +				    last;
        +				  };
        +		/\.data/    && do { my $v=undef;
        +				    if ($nasm) {
        +					$v="section	.data data align=8\n";
        +				    } else {
        +					$v="$current_segment\tENDS\n" if ($current_segment);
        +					$current_segment = "_DATA";
        +					$v.="$current_segment\tSEGMENT";
        +				    }
        +				    $self->{value} = $v;
        +				    last;
        +				  };
        +		/\.section/ && do { my $v=undef;
        +				    $line =~ s/([^,]*).*/$1/;
        +				    $line = ".CRT\$XCU" if ($line eq ".init");
        +				    if ($nasm) {
        +					$v="section	$line";
        +					if ($line=~/\.([px])data/) {
        +					    $v.=" rdata align=";
        +					    $v.=$1 eq "p"? 4 : 8;
        +					} elsif ($line=~/\.CRT\$/i) {
        +					    $v.=" rdata align=8";
        +					}
        +				    } else {
        +					$v="$current_segment\tENDS\n" if ($current_segment);
        +					$v.="$line\tSEGMENT";
        +					if ($line=~/\.([px])data/) {
        +					    $v.=" READONLY";
        +					    $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref);
        +					} elsif ($line=~/\.CRT\$/i) {
        +					    $v.=" READONLY ";
        +					    $v.=$masm>=$masmref ? "ALIGN(8)" : "DWORD";
        +					}
        +				    }
        +				    $current_segment = $line;
        +				    $self->{value} = $v;
        +				    last;
        +				  };
        +		/\.extern/  && do { $self->{value}  = "EXTERN\t".$line;
        +				    $self->{value} .= ":NEAR" if ($masm);
        +				    last;
        +				  };
        +		/\.globl|.global/
        +			    && do { $self->{value}  = $masm?"PUBLIC":"global";
        +				    $self->{value} .= "\t".$line;
        +				    last;
        +				  };
        +		/\.size/    && do { if (defined($current_function)) {
        +					undef $self->{value};
        +					if ($current_function->{abi} eq "svr4") {
        +					    $self->{value}="${decor}SEH_end_$current_function->{name}:";
        +					    $self->{value}.=":\n" if($masm);
        +					}
        +					$self->{value}.="$current_function->{name}\tENDP" if($masm && $current_function->{name});
        +					undef $current_function;
        +				    }
        +				    last;
        +				  };
        +		/\.align/   && do { $self->{value} = "ALIGN\t".$line; last; };
        +		/\.(value|long|rva|quad)/
        +			    && do { my $sz  = substr($1,0,1);
        +				    my @arr = split(/,\s*/,$line);
        +				    my $last = pop(@arr);
        +				    my $conv = sub  {	my $var=shift;
        +							$var=~s/^(0b[0-1]+)/oct($1)/eig;
        +							$var=~s/^0x([0-9a-f]+)/0$1h/ig if ($masm);
        +							if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
        +							{ $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
        +							$var;
        +						    };  
        +
        +				    $sz =~ tr/bvlrq/BWDDQ/;
        +				    $self->{value} = "\tD$sz\t";
        +				    for (@arr) { $self->{value} .= &$conv($_).","; }
        +				    $self->{value} .= &$conv($last);
        +				    last;
        +				  };
        +		/\.byte/    && do { my @str=split(/,\s*/,$line);
        +				    map(s/(0b[0-1]+)/oct($1)/eig,@str);
        +				    map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm);	
        +				    while ($#str>15) {
        +					$self->{value}.="DB\t"
        +						.join(",",@str[0..15])."\n";
        +					foreach (0..15) { shift @str; }
        +				    }
        +				    $self->{value}.="DB\t"
        +						.join(",",@str) if (@str);
        +				    last;
        +				  };
        +		/\.comm/    && do { my @str=split(/,\s*/,$line);
        +				    my $v=undef;
        +				    if ($nasm) {
        +					$v.="common	$prefix@str[0] @str[1]";
        +				    } else {
        +					$v="$current_segment\tENDS\n" if ($current_segment);
        +					$current_segment = "_DATA";
        +					$v.="$current_segment\tSEGMENT\n";
        +					$v.="COMM	@str[0]:DWORD:".@str[1]/4;
        +				    }
        +				    $self->{value} = $v;
        +				    last;
        +				  };
        +	    }
        +	    $line = "";
        +	}
        +
        +	$ret;
        +    }
        +    sub out {
        +	my $self = shift;
        +	$self->{value};
        +    }
        +}
        +
        +sub rex {
        + local *opcode=shift;
        + my ($dst,$src,$rex)=@_;
        +
        +   $rex|=0x04 if($dst>=8);
        +   $rex|=0x01 if($src>=8);
        +   push @opcode,($rex|0x40) if ($rex);
        +}
        +
        +# older gas and ml64 don't handle SSE>2 instructions
        +my %regrm = (	"%eax"=>0, "%ecx"=>1, "%edx"=>2, "%ebx"=>3,
        +		"%esp"=>4, "%ebp"=>5, "%esi"=>6, "%edi"=>7	);
        +
        +my $movq = sub {	# elderly gas can't handle inter-register movq
        +  my $arg = shift;
        +  my @opcode=(0x66);
        +    if ($arg =~ /%xmm([0-9]+),\s*%r(\w+)/) {
        +	my ($src,$dst)=($1,$2);
        +	if ($dst !~ /[0-9]+/)	{ $dst = $regrm{"%e$dst"}; }
        +	rex(\@opcode,$src,$dst,0x8);
        +	push @opcode,0x0f,0x7e;
        +	push @opcode,0xc0|(($src&7)<<3)|($dst&7);	# ModR/M
        +	@opcode;
        +    } elsif ($arg =~ /%r(\w+),\s*%xmm([0-9]+)/) {
        +	my ($src,$dst)=($2,$1);
        +	if ($dst !~ /[0-9]+/)	{ $dst = $regrm{"%e$dst"}; }
        +	rex(\@opcode,$src,$dst,0x8);
        +	push @opcode,0x0f,0x6e;
        +	push @opcode,0xc0|(($src&7)<<3)|($dst&7);	# ModR/M
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +my $pextrd = sub {
        +    if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*(%\w+)/) {
        +      my @opcode=(0x66);
        +	$imm=$1;
        +	$src=$2;
        +	$dst=$3;
        +	if ($dst =~ /%r([0-9]+)d/)	{ $dst = $1; }
        +	elsif ($dst =~ /%e/)		{ $dst = $regrm{$dst}; }
        +	rex(\@opcode,$src,$dst);
        +	push @opcode,0x0f,0x3a,0x16;
        +	push @opcode,0xc0|(($src&7)<<3)|($dst&7);	# ModR/M
        +	push @opcode,$imm;
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +my $pinsrd = sub {
        +    if (shift =~ /\$([0-9]+),\s*(%\w+),\s*%xmm([0-9]+)/) {
        +      my @opcode=(0x66);
        +	$imm=$1;
        +	$src=$2;
        +	$dst=$3;
        +	if ($src =~ /%r([0-9]+)/)	{ $src = $1; }
        +	elsif ($src =~ /%e/)		{ $src = $regrm{$src}; }
        +	rex(\@opcode,$dst,$src);
        +	push @opcode,0x0f,0x3a,0x22;
        +	push @opcode,0xc0|(($dst&7)<<3)|($src&7);	# ModR/M
        +	push @opcode,$imm;
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +my $pshufb = sub {
        +    if (shift =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
        +      my @opcode=(0x66);
        +	rex(\@opcode,$2,$1);
        +	push @opcode,0x0f,0x38,0x00;
        +	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +my $palignr = sub {
        +    if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
        +      my @opcode=(0x66);
        +	rex(\@opcode,$3,$2);
        +	push @opcode,0x0f,0x3a,0x0f;
        +	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
        +	push @opcode,$1;
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +my $pclmulqdq = sub {
        +    if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
        +      my @opcode=(0x66);
        +	rex(\@opcode,$3,$2);
        +	push @opcode,0x0f,0x3a,0x44;
        +	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
        +	my $c=$1;
        +	push @opcode,$c=~/^0/?oct($c):$c;
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +my $rdrand = sub {
        +    if (shift =~ /%[er](\w+)/) {
        +      my @opcode=();
        +      my $dst=$1;
        +	if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
        +	rex(\@opcode,0,$1,8);
        +	push @opcode,0x0f,0xc7,0xf0|($dst&7);
        +	@opcode;
        +    } else {
        +	();
        +    }
        +};
        +
        +if ($nasm) {
        +    print <<___;
        +default	rel
        +%define XMMWORD
        +___
        +} elsif ($masm) {
        +    print <<___;
        +OPTION	DOTNAME
        +___
        +}
        +while($line=<>) {
        +
        +    chomp($line);
        +
        +    $line =~ s|[#!].*$||;	# get rid of asm-style comments...
        +    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
        +    $line =~ s|^\s+||;		# ... and skip white spaces in beginning
        +
        +    undef $label;
        +    undef $opcode;
        +    undef @args;
        +
        +    if ($label=label->re(\$line))	{ print $label->out(); }
        +
        +    if (directive->re(\$line)) {
        +	printf "%s",directive->out();
        +    } elsif ($opcode=opcode->re(\$line)) {
        +	my $asm = eval("\$".$opcode->mnemonic());
        +	undef @bytes;
        +	
        +	if ((ref($asm) eq 'CODE') && scalar(@bytes=&$asm($line))) {
        +	    print $gas?".byte\t":"DB\t",join(',',@bytes),"\n";
        +	    next;
        +	}
        +
        +	ARGUMENT: while (1) {
        +	my $arg;
        +
        +	if ($arg=register->re(\$line))	{ opcode->size($arg->size()); }
        +	elsif ($arg=const->re(\$line))	{ }
        +	elsif ($arg=ea->re(\$line))	{ }
        +	elsif ($arg=expr->re(\$line))	{ }
        +	else				{ last ARGUMENT; }
        +
        +	push @args,$arg;
        +
        +	last ARGUMENT if ($line !~ /^,/);
        +
        +	$line =~ s/^,\s*//;
        +	} # ARGUMENT:
        +
        +	if ($#args>=0) {
        +	    my $insn;
        +	    my $sz=opcode->size();
        +
        +	    if ($gas) {
        +		$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
        +		@args = map($_->out($sz),@args);
        +		printf "\t%s\t%s",$insn,join(",",@args);
        +	    } else {
        +		$insn = $opcode->out();
        +		foreach (@args) {
        +		    my $arg = $_->out();
        +		    # $insn.=$sz compensates for movq, pinsrw, ...
        +		    if ($arg =~ /^xmm[0-9]+$/) { $insn.=$sz; $sz="x" if(!$sz); last; }
        +		    if ($arg =~ /^mm[0-9]+$/)  { $insn.=$sz; $sz="q" if(!$sz); last; }
        +		}
        +		@args = reverse(@args);
        +		undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
        +		printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
        +	    }
        +	} else {
        +	    printf "\t%s",$opcode->out();
        +	}
        +    }
        +
        +    print $line,"\n";
        +}
        +
        +print "\n$current_segment\tENDS\n"	if ($current_segment && $masm);
        +print "END\n"				if ($masm);
        +
        +close STDOUT;
        +
        +#################################################
        +# Cross-reference x86_64 ABI "card"
        +#
        +# 		Unix		Win64
        +# %rax		*		*
        +# %rbx		-		-
        +# %rcx		#4		#1
        +# %rdx		#3		#2
        +# %rsi		#2		-
        +# %rdi		#1		-
        +# %rbp		-		-
        +# %rsp		-		-
        +# %r8		#5		#3
        +# %r9		#6		#4
        +# %r10		*		*
        +# %r11		*		*
        +# %r12		-		-
        +# %r13		-		-
        +# %r14		-		-
        +# %r15		-		-
        +# 
        +# (*)	volatile register
        +# (-)	preserved by callee
        +# (#)	Nth argument, volatile
        +#
        +# In Unix terms top of stack is argument transfer area for arguments
        +# which could not be accomodated in registers. Or in other words 7th
        +# [integer] argument resides at 8(%rsp) upon function entry point.
        +# 128 bytes above %rsp constitute a "red zone" which is not touched
        +# by signal handlers and can be used as temporal storage without
        +# allocating a frame.
        +#
        +# In Win64 terms N*8 bytes on top of stack is argument transfer area,
        +# which belongs to/can be overwritten by callee. N is the number of
        +# arguments passed to callee, *but* not less than 4! This means that
        +# upon function entry point 5th argument resides at 40(%rsp), as well
        +# as that 32 bytes from 8(%rsp) can always be used as temporal
        +# storage [without allocating a frame]. One can actually argue that
        +# one can assume a "red zone" above stack pointer under Win64 as well.
        +# Point is that at apparently no occasion Windows kernel would alter
        +# the area above user stack pointer in true asynchronous manner...
        +#
        +# All the above means that if assembler programmer adheres to Unix
        +# register and stack layout, but disregards the "red zone" existense,
        +# it's possible to use following prologue and epilogue to "gear" from
        +# Unix to Win64 ABI in leaf functions with not more than 6 arguments.
        +#
        +# omnipotent_function:
        +# ifdef WIN64
        +#	movq	%rdi,8(%rsp)
        +#	movq	%rsi,16(%rsp)
        +#	movq	%rcx,%rdi	; if 1st argument is actually present
        +#	movq	%rdx,%rsi	; if 2nd argument is actually ...
        +#	movq	%r8,%rdx	; if 3rd argument is ...
        +#	movq	%r9,%rcx	; if 4th argument ...
        +#	movq	40(%rsp),%r8	; if 5th ...
        +#	movq	48(%rsp),%r9	; if 6th ...
        +# endif
        +#	...
        +# ifdef WIN64
        +#	movq	8(%rsp),%rdi
        +#	movq	16(%rsp),%rsi
        +# endif
        +#	ret
        +#
        +#################################################
        +# Win64 SEH, Structured Exception Handling.
        +#
        +# Unlike on Unix systems(*) lack of Win64 stack unwinding information
        +# has undesired side-effect at run-time: if an exception is raised in
        +# assembler subroutine such as those in question (basically we're
        +# referring to segmentation violations caused by malformed input
        +# parameters), the application is briskly terminated without invoking
        +# any exception handlers, most notably without generating memory dump
        +# or any user notification whatsoever. This poses a problem. It's
        +# possible to address it by registering custom language-specific
        +# handler that would restore processor context to the state at
        +# subroutine entry point and return "exception is not handled, keep
        +# unwinding" code. Writing such handler can be a challenge... But it's
        +# doable, though requires certain coding convention. Consider following
        +# snippet:
        +#
        +# .type	function,@function
        +# function:
        +#	movq	%rsp,%rax	# copy rsp to volatile register
        +#	pushq	%r15		# save non-volatile registers
        +#	pushq	%rbx
        +#	pushq	%rbp
        +#	movq	%rsp,%r11
        +#	subq	%rdi,%r11	# prepare [variable] stack frame
        +#	andq	$-64,%r11
        +#	movq	%rax,0(%r11)	# check for exceptions
        +#	movq	%r11,%rsp	# allocate [variable] stack frame
        +#	movq	%rax,0(%rsp)	# save original rsp value
        +# magic_point:
        +#	...
        +#	movq	0(%rsp),%rcx	# pull original rsp value
        +#	movq	-24(%rcx),%rbp	# restore non-volatile registers
        +#	movq	-16(%rcx),%rbx
        +#	movq	-8(%rcx),%r15
        +#	movq	%rcx,%rsp	# restore original rsp
        +#	ret
        +# .size function,.-function
        +#
        +# The key is that up to magic_point copy of original rsp value remains
        +# in chosen volatile register and no non-volatile register, except for
        +# rsp, is modified. While past magic_point rsp remains constant till
        +# the very end of the function. In this case custom language-specific
        +# exception handler would look like this:
        +#
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +# {	ULONG64 *rsp = (ULONG64 *)context->Rax;
        +#	if (context->Rip >= magic_point)
        +#	{   rsp = ((ULONG64 **)context->Rsp)[0];
        +#	    context->Rbp = rsp[-3];
        +#	    context->Rbx = rsp[-2];
        +#	    context->R15 = rsp[-1];
        +#	}
        +#	context->Rsp = (ULONG64)rsp;
        +#	context->Rdi = rsp[1];
        +#	context->Rsi = rsp[2];
        +#
        +#	memcpy (disp->ContextRecord,context,sizeof(CONTEXT));
        +#	RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase,
        +#		dips->ControlPc,disp->FunctionEntry,disp->ContextRecord,
        +#		&disp->HandlerData,&disp->EstablisherFrame,NULL);
        +#	return ExceptionContinueSearch;
        +# }
        +#
        +# It's appropriate to implement this handler in assembler, directly in
        +# function's module. In order to do that one has to know members'
        +# offsets in CONTEXT and DISPATCHER_CONTEXT structures and some constant
        +# values. Here they are:
        +#
        +#	CONTEXT.Rax				120
        +#	CONTEXT.Rcx				128
        +#	CONTEXT.Rdx				136
        +#	CONTEXT.Rbx				144
        +#	CONTEXT.Rsp				152
        +#	CONTEXT.Rbp				160
        +#	CONTEXT.Rsi				168
        +#	CONTEXT.Rdi				176
        +#	CONTEXT.R8				184
        +#	CONTEXT.R9				192
        +#	CONTEXT.R10				200
        +#	CONTEXT.R11				208
        +#	CONTEXT.R12				216
        +#	CONTEXT.R13				224
        +#	CONTEXT.R14				232
        +#	CONTEXT.R15				240
        +#	CONTEXT.Rip				248
        +#	CONTEXT.Xmm6				512
        +#	sizeof(CONTEXT)				1232
        +#	DISPATCHER_CONTEXT.ControlPc		0
        +#	DISPATCHER_CONTEXT.ImageBase		8
        +#	DISPATCHER_CONTEXT.FunctionEntry	16
        +#	DISPATCHER_CONTEXT.EstablisherFrame	24
        +#	DISPATCHER_CONTEXT.TargetIp		32
        +#	DISPATCHER_CONTEXT.ContextRecord	40
        +#	DISPATCHER_CONTEXT.LanguageHandler	48
        +#	DISPATCHER_CONTEXT.HandlerData		56
        +#	UNW_FLAG_NHANDLER			0
        +#	ExceptionContinueSearch			1
        +#
        +# In order to tie the handler to the function one has to compose
        +# couple of structures: one for .xdata segment and one for .pdata.
        +#
        +# UNWIND_INFO structure for .xdata segment would be
        +#
        +# function_unwind_info:
        +#	.byte	9,0,0,0
        +#	.rva	handler
        +#
        +# This structure designates exception handler for a function with
        +# zero-length prologue, no stack frame or frame register.
        +#
        +# To facilitate composing of .pdata structures, auto-generated "gear"
        +# prologue copies rsp value to rax and denotes next instruction with
        +# .LSEH_begin_{function_name} label. This essentially defines the SEH
        +# styling rule mentioned in the beginning. Position of this label is
        +# chosen in such manner that possible exceptions raised in the "gear"
        +# prologue would be accounted to caller and unwound from latter's frame.
        +# End of function is marked with respective .LSEH_end_{function_name}
        +# label. To summarize, .pdata segment would contain
        +#
        +#	.rva	.LSEH_begin_function
        +#	.rva	.LSEH_end_function
        +#	.rva	function_unwind_info
        +#
        +# Reference to functon_unwind_info from .xdata segment is the anchor.
        +# In case you wonder why references are 32-bit .rvas and not 64-bit
        +# .quads. References put into these two segments are required to be
        +# *relative* to the base address of the current binary module, a.k.a.
        +# image base. No Win64 module, be it .exe or .dll, can be larger than
        +# 2GB and thus such relative references can be and are accommodated in
        +# 32 bits.
        +#
        +# Having reviewed the example function code, one can argue that "movq
        +# %rsp,%rax" above is redundant. It is not! Keep in mind that on Unix
        +# rax would contain an undefined value. If this "offends" you, use
        +# another register and refrain from modifying rax till magic_point is
        +# reached, i.e. as if it was a non-volatile register. If more registers
        +# are required prior [variable] frame setup is completed, note that
        +# nobody says that you can have only one "magic point." You can
        +# "liberate" non-volatile registers by denoting last stack off-load
        +# instruction and reflecting it in finer grade unwind logic in handler.
        +# After all, isn't it why it's called *language-specific* handler...
        +#
        +# Attentive reader can notice that exceptions would be mishandled in
        +# auto-generated "gear" epilogue. Well, exception effectively can't
        +# occur there, because if memory area used by it was subject to
        +# segmentation violation, then it would be raised upon call to the
        +# function (and as already mentioned be accounted to caller, which is
        +# not a problem). If you're still not comfortable, then define tail
        +# "magic point" just prior ret instruction and have handler treat it...
        +#
        +# (*)	Note that we're talking about run-time, not debug-time. Lack of
        +#	unwind information makes debugging hard on both Windows and
        +#	Unix. "Unlike" referes to the fact that on Unix signal handler
        +#	will always be invoked, core dumped and appropriate exit code
        +#	returned to parent (for user notification).
        diff --git a/vendor/openssl/openssl/crypto/perlasm/x86asm.pl b/vendor/openssl/openssl/crypto/perlasm/x86asm.pl
        new file mode 100644
        index 000000000..eb543db2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/x86asm.pl
        @@ -0,0 +1,260 @@
        +#!/usr/bin/env perl
        +
        +# require 'x86asm.pl';
        +# &asm_init(<flavor>,"des-586.pl"[,$i386only]);
        +# &function_begin("foo");
        +# ...
        +# &function_end("foo");
        +# &asm_finish
        +
        +$out=();
        +$i386=0;
        +
        +# AUTOLOAD is this context has quite unpleasant side effect, namely
        +# that typos in function calls effectively go to assembler output,
        +# but on the pros side we don't have to implement one subroutine per
        +# each opcode...
        +sub ::AUTOLOAD
        +{ my $opcode = $AUTOLOAD;
        +
        +    die "more than 4 arguments passed to $opcode" if ($#_>3);
        +
        +    $opcode =~ s/.*:://;
        +    if    ($opcode =~ /^push/) { $stack+=4; }
        +    elsif ($opcode =~ /^pop/)  { $stack-=4; }
        +
        +    &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
        +}
        +
        +sub ::emit
        +{ my $opcode=shift;
        +
        +    if ($#_==-1)    { push(@out,"\t$opcode\n");				}
        +    else            { push(@out,"\t$opcode\t".join(',',@_)."\n");	}
        +}
        +
        +sub ::LB
        +{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
        +  $1."l";
        +}
        +sub ::HB
        +{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
        +  $1."h";
        +}
        +sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num);	}
        +sub ::stack_pop	{ my $num=$_[0]*4; $stack-=$num; &add("esp",$num);	}
        +sub ::blindpop	{ &pop($_[0]); $stack+=4;				}
        +sub ::wparam	{ &DWP($stack+4*$_[0],"esp");				}
        +sub ::swtmp	{ &DWP(4*$_[0],"esp");					}
        +
        +sub ::bswap
        +{   if ($i386)	# emulate bswap for i386
        +    {	&comment("bswap @_");
        +	&xchg(&HB(@_),&LB(@_));
        +	&ror (@_,16);
        +	&xchg(&HB(@_),&LB(@_));
        +    }
        +    else
        +    {	&generic("bswap",@_);	}
        +}
        +# These are made-up opcodes introduced over the years essentially
        +# by ignorance, just alias them to real ones...
        +sub ::movb	{ &mov(@_);	}
        +sub ::xorb	{ &xor(@_);	}
        +sub ::rotl	{ &rol(@_);	}
        +sub ::rotr	{ &ror(@_);	}
        +sub ::exch	{ &xchg(@_);	}
        +sub ::halt	{ &hlt;		}
        +sub ::movz	{ &movzx(@_);	}
        +sub ::pushf	{ &pushfd;	}
        +sub ::popf	{ &popfd;	}
        +
        +# 3 argument instructions
        +sub ::movq
        +{ my($p1,$p2,$optimize)=@_;
        +
        +    if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
        +    # movq between mmx registers can sink Intel CPUs
        +    {	&::pshufw($p1,$p2,0xe4);		}
        +    else
        +    {	&::generic("movq",@_);			}
        +}
        +
        +# SSE>2 instructions
        +my %regrm = (	"eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3,
        +		"esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7	);
        +sub ::pextrd
        +{ my($dst,$src,$imm)=@_;
        +    if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/)
        +    {	&::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm);	}
        +    else
        +    {	&::generic("pextrd",@_);		}
        +}
        +
        +sub ::pinsrd
        +{ my($dst,$src,$imm)=@_;
        +    if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/)
        +    {	&::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm);	}
        +    else
        +    {	&::generic("pinsrd",@_);		}
        +}
        +
        +sub ::pshufb
        +{ my($dst,$src)=@_;
        +    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
        +    {	&data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2);	}
        +    else
        +    {	&::generic("pshufb",@_);		}
        +}
        +
        +sub ::palignr
        +{ my($dst,$src,$imm)=@_;
        +    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
        +    {	&::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm);	}
        +    else
        +    {	&::generic("palignr",@_);		}
        +}
        +
        +sub ::pclmulqdq
        +{ my($dst,$src,$imm)=@_;
        +    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
        +    {	&::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm);	}
        +    else
        +    {	&::generic("pclmulqdq",@_);		}
        +}
        +
        +sub ::rdrand
        +{ my ($dst)=@_;
        +    if ($dst =~ /(e[a-dsd][ixp])/)
        +    {	&::data_byte(0x0f,0xc7,0xf0|$regrm{$dst});	}
        +    else
        +    {	&::generic("rdrand",@_);	}
        +}
        +
        +# label management
        +$lbdecor="L";		# local label decoration, set by package
        +$label="000";
        +
        +sub ::islabel		# see is argument is a known label
        +{ my $i;
        +    foreach $i (values %label) { return $i if ($i eq $_[0]); }
        +  $label{$_[0]};	# can be undef
        +}
        +
        +sub ::label		# instantiate a function-scope label
        +{   if (!defined($label{$_[0]}))
        +    {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   }
        +  $label{$_[0]};
        +}
        +
        +sub ::LABEL		# instantiate a file-scope label
        +{   $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
        +  $label{$_[0]};
        +}
        +
        +sub ::static_label	{ &::LABEL($_[0],$lbdecor.$_[0]); }
        +
        +sub ::set_label_B	{ push(@out,"@_:\n"); }
        +sub ::set_label
        +{ my $label=&::label($_[0]);
        +    &::align($_[1]) if ($_[1]>1);
        +    &::set_label_B($label);
        +  $label;
        +}
        +
        +sub ::wipe_labels	# wipes function-scope labels
        +{   foreach $i (keys %label)
        +    {	delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/);	}
        +}
        +
        +# subroutine management
        +sub ::function_begin
        +{   &function_begin_B(@_);
        +    $stack=4;
        +    &push("ebp");
        +    &push("ebx");
        +    &push("esi");
        +    &push("edi");
        +}
        +
        +sub ::function_end
        +{   &pop("edi");
        +    &pop("esi");
        +    &pop("ebx");
        +    &pop("ebp");
        +    &ret();
        +    &function_end_B(@_);
        +    $stack=0;
        +    &wipe_labels();
        +}
        +
        +sub ::function_end_A
        +{   &pop("edi");
        +    &pop("esi");
        +    &pop("ebx");
        +    &pop("ebp");
        +    &ret();
        +    $stack+=16;	# readjust esp as if we didn't pop anything
        +}
        +
        +sub ::asciz
        +{ my @str=unpack("C*",shift);
        +    push @str,0;
        +    while ($#str>15) {
        +	&data_byte(@str[0..15]);
        +	foreach (0..15) { shift @str; }
        +    }
        +    &data_byte(@str) if (@str);
        +}
        +
        +sub ::asm_finish
        +{   &file_end();
        +    print @out;
        +}
        +
        +sub ::asm_init
        +{ my ($type,$fn,$cpu)=@_;
        +
        +    $filename=$fn;
        +    $i386=$cpu;
        +
        +    $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=$android=0;
        +    if    (($type eq "elf"))
        +    {	$elf=1;			require "x86gas.pl";	}
        +    elsif (($type eq "a\.out"))
        +    {	$aout=1;		require "x86gas.pl";	}
        +    elsif (($type eq "coff" or $type eq "gaswin"))
        +    {	$coff=1;		require "x86gas.pl";	}
        +    elsif (($type eq "win32n"))
        +    {	$win32=1;		require "x86nasm.pl";	}
        +    elsif (($type eq "nw-nasm"))
        +    {	$netware=1;		require "x86nasm.pl";	}
        +    #elsif (($type eq "nw-mwasm"))
        +    #{	$netware=1; $mwerks=1;	require "x86nasm.pl";	}
        +    elsif (($type eq "win32"))
        +    {	$win32=1;		require "x86masm.pl";	}
        +    elsif (($type eq "macosx"))
        +    {	$aout=1; $macosx=1;	require "x86gas.pl";	}
        +    elsif (($type eq "android"))
        +    {	$elf=1; $android=1;	require "x86gas.pl";	}
        +    else
        +    {	print STDERR <<"EOF";
        +Pick one target type from
        +	elf	- Linux, FreeBSD, Solaris x86, etc.
        +	a.out	- DJGPP, elder OpenBSD, etc.
        +	coff	- GAS/COFF such as Win32 targets
        +	win32n	- Windows 95/Windows NT NASM format
        +	nw-nasm - NetWare NASM format
        +	macosx	- Mac OS X
        +EOF
        +	exit(1);
        +    }
        +
        +    $pic=0;
        +    for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
        +
        +    $filename =~ s/\.pl$//;
        +    &file($filename);
        +}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/perlasm/x86gas.pl b/vendor/openssl/openssl/crypto/perlasm/x86gas.pl
        new file mode 100644
        index 000000000..682a3a316
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/x86gas.pl
        @@ -0,0 +1,253 @@
        +#!/usr/bin/env perl
        +
        +package x86gas;
        +
        +*out=\@::out;
        +
        +$::lbdecor=$::aout?"L":".L";		# local label decoration
        +$nmdecor=($::aout or $::coff)?"_":"";	# external name decoration
        +
        +$initseg="";
        +
        +$align=16;
        +$align=log($align)/log(2) if ($::aout);
        +$com_start="#" if ($::aout or $::coff);
        +
        +sub opsize()
        +{ my $reg=shift;
        +    if    ($reg =~ m/^%e/o)		{ "l"; }
        +    elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
        +    elsif ($reg =~ m/^%[xm]/o)		{ undef; }
        +    else				{ "w"; }
        +}
        +
        +# swap arguments;
        +# expand opcode with size suffix;
        +# prefix numeric constants with $;
        +sub ::generic
        +{ my($opcode,@arg)=@_;
        +  my($suffix,$dst,$src);
        +
        +    @arg=reverse(@arg);
        +
        +    for (@arg)
        +    {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers
        +	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers
        +	s/^(\-?[0-9]+)$/\$$1/o;			# constants
        +	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants
        +    }
        +
        +    $dst = $arg[$#arg]		if ($#arg>=0);
        +    $src = $arg[$#arg-1]	if ($#arg>=1);
        +    if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); }
        +    elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); }
        +    else			{ $suffix="l";           }
        +    undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
        +
        +    if ($#_==0)				{ &::emit($opcode);		}
        +    elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o)
        +					{ &::emit($opcode,@arg);	}
        +    else				{ &::emit($opcode.$suffix,@arg);}
        +
        +  1;
        +}
        +#
        +# opcodes not covered by ::generic above, mostly inconsistent namings...
        +#
        +sub ::movzx	{ &::movzb(@_);			}
        +sub ::pushfd	{ &::pushfl;			}
        +sub ::popfd	{ &::popfl;			}
        +sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	}
        +sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	}
        +
        +sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
        +sub ::call_ptr	{ &::generic("call","*$_[0]");	}
        +sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	}
        +
        +*::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386);
        +
        +sub ::DWP
        +{ my($addr,$reg1,$reg2,$idx)=@_;
        +  my $ret="";
        +
        +    $addr =~ s/^\s+//;
        +    # prepend global references with optional underscore
        +    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
        +
        +    $reg1 = "%$reg1" if ($reg1);
        +    $reg2 = "%$reg2" if ($reg2);
        +
        +    $ret .= $addr if (($addr ne "") && ($addr ne 0));
        +
        +    if ($reg2)
        +    {	$idx!= 0 or $idx=1;
        +	$ret .= "($reg1,$reg2,$idx)";
        +    }
        +    elsif ($reg1)
        +    {	$ret .= "($reg1)";	}
        +
        +  $ret;
        +}
        +sub ::QWP	{ &::DWP(@_);	}
        +sub ::BP	{ &::DWP(@_);	}
        +sub ::WP	{ &::DWP(@_);	}
        +sub ::BC	{ @_;		}
        +sub ::DWC	{ @_;		}
        +
        +sub ::file
        +{   push(@out,".file\t\"$_[0].s\"\n.text\n");	}
        +
        +sub ::function_begin_B
        +{ my $func=shift;
        +  my $global=($func !~ /^_/);
        +  my $begin="${::lbdecor}_${func}_begin";
        +
        +    &::LABEL($func,$global?"$begin":"$nmdecor$func");
        +    $func=$nmdecor.$func;
        +
        +    push(@out,".globl\t$func\n")	if ($global);
        +    if ($::coff)
        +    {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
        +    elsif (($::aout and !$::pic) or $::macosx)
        +    { }
        +    else
        +    {	push(@out,".type	$func,\@function\n"); }
        +    push(@out,".align\t$align\n");
        +    push(@out,"$func:\n");
        +    push(@out,"$begin:\n")		if ($global);
        +    $::stack=4;
        +}
        +
        +sub ::function_end_B
        +{ my $func=shift;
        +    push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
        +    $::stack=0;
        +    &::wipe_labels();
        +}
        +
        +sub ::comment
        +	{
        +	if (!defined($com_start) or $::elf)
        +		{	# Regarding $::elf above...
        +			# GNU and SVR4 as'es use different comment delimiters,
        +		push(@out,"\n");	# so we just skip ELF comments...
        +		return;
        +		}
        +	foreach (@_)
        +		{
        +		if (/^\s*$/)
        +			{ push(@out,"\n"); }
        +		else
        +			{ push(@out,"\t$com_start $_ $com_end\n"); }
        +		}
        +	}
        +
        +sub ::external_label
        +{   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   }
        +
        +sub ::public_label
        +{   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
        +
        +sub ::file_end
        +{   if ($::macosx)
        +    {	if (%non_lazy_ptr)
        +    	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
        +	    foreach $i (keys %non_lazy_ptr)
        +	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   }
        +	}
        +    }
        +    if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
        +	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,8";
        +	if ($::macosx)	{ push (@out,"$tmp,2\n"); }
        +	elsif ($::elf)	{ push (@out,"$tmp,4\n"); }
        +	else		{ push (@out,"$tmp\n"); }
        +    }
        +    push(@out,$initseg) if ($initseg);
        +}
        +
        +sub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   }
        +sub ::data_short{   push(@out,".value\t".join(',',@_)."\n");  }
        +sub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   }
        +
        +sub ::align
        +{ my $val=$_[0],$p2,$i;
        +    if ($::aout)
        +    {	for ($p2=0;$val!=0;$val>>=1) { $p2++; }
        +	$val=$p2-1;
        +	$val.=",0x90";
        +    }
        +    push(@out,".align\t$val\n");
        +}
        +
        +sub ::picmeup
        +{ my($dst,$sym,$base,$reflabel)=@_;
        +
        +    if (($::pic && ($::elf || $::aout)) || $::macosx)
        +    {	if (!defined($base))
        +	{   &::call(&::label("PIC_me_up"));
        +	    &::set_label("PIC_me_up");
        +	    &::blindpop($dst);
        +	    $base=$dst;
        +	    $reflabel=&::label("PIC_me_up");
        +	}
        +	if ($::macosx)
        +	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
        +	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
        +	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
        +	}
        +	else
        +	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
        +			    $base));
        +	    &::mov($dst,&::DWP("$sym\@GOT",$dst));
        +	}
        +    }
        +    else
        +    {	&::lea($dst,&::DWP($sym));	}
        +}
        +
        +sub ::initseg
        +{ my $f=$nmdecor.shift;
        +
        +    if ($::android)
        +    {	$initseg.=<<___;
        +.section	.init_array
        +.align	4
        +.long	$f
        +___
        +    }
        +    elsif ($::elf)
        +    {	$initseg.=<<___;
        +.section	.init
        +	call	$f
        +___
        +    }
        +    elsif ($::coff)
        +    {   $initseg.=<<___;	# applies to both Cygwin and Mingw
        +.section	.ctors
        +.long	$f
        +___
        +    }
        +    elsif ($::macosx)
        +    {	$initseg.=<<___;
        +.mod_init_func
        +.align 2
        +.long   $f
        +___
        +    }
        +    elsif ($::aout)
        +    {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
        +	$initseg.=".text\n";
        +	$initseg.=".type	$ctor,\@function\n" if ($::pic);
        +	$initseg.=<<___;	# OpenBSD way...
        +.globl	$ctor
        +.align	2
        +$ctor:
        +	jmp	$f
        +___
        +    }
        +}
        +
        +sub ::dataseg
        +{   push(@out,".data\n");   }
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/perlasm/x86masm.pl b/vendor/openssl/openssl/crypto/perlasm/x86masm.pl
        new file mode 100644
        index 000000000..6b33b146f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/x86masm.pl
        @@ -0,0 +1,198 @@
        +#!/usr/bin/env perl
        +
        +package x86masm;
        +
        +*out=\@::out;
        +
        +$::lbdecor="\$L";	# local label decoration
        +$nmdecor="_";		# external name decoration
        +
        +$initseg="";
        +$segment="";
        +
        +sub ::generic
        +{ my ($opcode,@arg)=@_;
        +
        +    # fix hexadecimal constants
        +    for (@arg) { s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/oi; }
        +
        +    if ($opcode =~ /lea/ && @arg[1] =~ s/.*PTR\s+(\(.*\))$/OFFSET $1/)	# no []
        +    {	$opcode="mov";	}
        +    elsif ($opcode !~ /movq/)
        +    {	# fix xmm references
        +	$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
        +	$arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i);
        +    }
        +
        +    &::emit($opcode,@arg);
        +  1;
        +}
        +#
        +# opcodes not covered by ::generic above, mostly inconsistent namings...
        +#
        +sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
        +sub ::call_ptr	{ &::emit("call",@_);	}
        +sub ::jmp_ptr	{ &::emit("jmp",@_);	}
        +sub ::lock	{ &::data_byte(0xf0);	}
        +
        +sub get_mem
        +{ my($size,$addr,$reg1,$reg2,$idx)=@_;
        +  my($post,$ret);
        +
        +    $ret .= "$size PTR " if ($size ne "");
        +
        +    $addr =~ s/^\s+//;
        +    # prepend global references with optional underscore
        +    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
        +    # put address arithmetic expression in parenthesis
        +    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
        +
        +    if (($addr ne "") && ($addr ne 0))
        +    {	if ($addr !~ /^-/)	{ $ret .= "$addr";  }
        +	else			{ $post=$addr;      }
        +    }
        +    $ret .= "[";
        +
        +    if ($reg2 ne "")
        +    {	$idx!=0 or $idx=1;
        +	$ret .= "$reg2*$idx";
        +	$ret .= "+$reg1" if ($reg1 ne "");
        +    }
        +    else
        +    {	$ret .= "$reg1";   }
        +
        +    $ret .= "$post]";
        +    $ret =~ s/\+\]/]/; # in case $addr was the only argument
        +    $ret =~ s/\[\s*\]//;
        +
        +  $ret;
        +}
        +sub ::BP	{ &get_mem("BYTE",@_);  }
        +sub ::WP	{ &get_mem("WORD",@_);	}
        +sub ::DWP	{ &get_mem("DWORD",@_); }
        +sub ::QWP	{ &get_mem("QWORD",@_); }
        +sub ::BC	{ "@_";  }
        +sub ::DWC	{ "@_"; }
        +
        +sub ::file
        +{ my $tmp=<<___;
        +TITLE	$_[0].asm
        +IF \@Version LT 800
        +ECHO MASM version 8.00 or later is strongly recommended.
        +ENDIF
        +.686
        +.MODEL	FLAT
        +OPTION	DOTNAME
        +IF \@Version LT 800
        +.text\$	SEGMENT PAGE 'CODE'
        +ELSE
        +.text\$	SEGMENT ALIGN(64) 'CODE'
        +ENDIF
        +___
        +    push(@out,$tmp);
        +    $segment = ".text\$";
        +}
        +
        +sub ::function_begin_B
        +{ my $func=shift;
        +  my $global=($func !~ /^_/);
        +  my $begin="${::lbdecor}_${func}_begin";
        +
        +    &::LABEL($func,$global?"$begin":"$nmdecor$func");
        +    $func="ALIGN\t16\n".$nmdecor.$func."\tPROC";
        +
        +    if ($global)    { $func.=" PUBLIC\n${begin}::\n"; }
        +    else	    { $func.=" PRIVATE\n";            }
        +    push(@out,$func);
        +    $::stack=4;
        +}
        +sub ::function_end_B
        +{ my $func=shift;
        +
        +    push(@out,"$nmdecor$func ENDP\n");
        +    $::stack=0;
        +    &::wipe_labels();
        +}
        +
        +sub ::file_end
        +{ my $xmmheader=<<___;
        +.686
        +.XMM
        +IF \@Version LT 800
        +XMMWORD STRUCT 16
        +DQ	2 dup (?)
        +XMMWORD	ENDS
        +ENDIF
        +___
        +    if (grep {/\b[x]?mm[0-7]\b/i} @out) {
        +	grep {s/\.[3-7]86/$xmmheader/} @out;
        +    }
        +
        +    push(@out,"$segment	ENDS\n");
        +
        +    if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
        +    {	my $comm=<<___;
        +.bss	SEGMENT 'BSS'
        +COMM	${nmdecor}OPENSSL_ia32cap_P:QWORD
        +.bss	ENDS
        +___
        +	# comment out OPENSSL_ia32cap_P declarations
        +	grep {s/(^EXTERN\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
        +	push (@out,$comm);
        +    }
        +    push (@out,$initseg) if ($initseg);
        +    push (@out,"END\n");
        +}
        +
        +sub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
        +
        +*::set_label_B = sub
        +{ my $l=shift; push(@out,$l.($l=~/^\Q${::lbdecor}\E[0-9]{3}/?":\n":"::\n")); };
        +
        +sub ::external_label
        +{   foreach(@_)
        +    {	push(@out, "EXTERN\t".&::LABEL($_,$nmdecor.$_).":NEAR\n");   }
        +}
        +
        +sub ::public_label
        +{   push(@out,"PUBLIC\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
        +
        +sub ::data_byte
        +{   push(@out,("DB\t").join(',',@_)."\n");	}
        +
        +sub ::data_short
        +{   push(@out,("DW\t").join(',',@_)."\n");	}
        +
        +sub ::data_word
        +{   push(@out,("DD\t").join(',',@_)."\n");	}
        +
        +sub ::align
        +{   push(@out,"ALIGN\t$_[0]\n");	}
        +
        +sub ::picmeup
        +{ my($dst,$sym)=@_;
        +    &::lea($dst,&::DWP($sym));
        +}
        +
        +sub ::initseg
        +{ my $f=$nmdecor.shift;
        +
        +    $initseg.=<<___;
        +.CRT\$XCU	SEGMENT DWORD PUBLIC 'DATA'
        +EXTERN	$f:NEAR
        +DD	$f
        +.CRT\$XCU	ENDS
        +___
        +}
        +
        +sub ::dataseg
        +{   push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA";   }
        +
        +sub ::safeseh
        +{ my $nm=shift;
        +    push(@out,"IF \@Version GE 710\n");
        +    push(@out,".SAFESEH	".&::LABEL($nm,$nmdecor.$nm)."\n");
        +    push(@out,"ENDIF\n");
        +}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/perlasm/x86nasm.pl b/vendor/openssl/openssl/crypto/perlasm/x86nasm.pl
        new file mode 100644
        index 000000000..ca2511c9e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/perlasm/x86nasm.pl
        @@ -0,0 +1,177 @@
        +#!/usr/bin/env perl
        +
        +package x86nasm;
        +
        +*out=\@::out;
        +
        +$::lbdecor="L\$";		# local label decoration
        +$nmdecor=$::netware?"":"_";	# external name decoration
        +$drdecor=$::mwerks?".":"";	# directive decoration
        +
        +$initseg="";
        +
        +sub ::generic
        +{ my $opcode=shift;
        +  my $tmp;
        +
        +    if (!$::mwerks)
        +    {   if    ($opcode =~ m/^j/o && $#_==0) # optimize jumps
        +	{   $_[0] = "NEAR $_[0]";   	}
        +	elsif ($opcode eq "lea" && $#_==1)  # wipe storage qualifier from lea
        +	{   $_[1] =~ s/^[^\[]*\[/\[/o;	}
        +	elsif ($opcode eq "clflush" && $#_==0)
        +	{   $_[0] =~ s/^[^\[]*\[/\[/o;	}
        +    }
        +    &::emit($opcode,@_);
        +  1;
        +}
        +#
        +# opcodes not covered by ::generic above, mostly inconsistent namings...
        +#
        +sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
        +sub ::call_ptr	{ &::emit("call",@_);	}
        +sub ::jmp_ptr	{ &::emit("jmp",@_);	}
        +
        +sub get_mem
        +{ my($size,$addr,$reg1,$reg2,$idx)=@_;
        +  my($post,$ret);
        +
        +    if ($size ne "")
        +    {	$ret .= "$size";
        +	$ret .= " PTR" if ($::mwerks);
        +	$ret .= " ";
        +    }
        +    $ret .= "[";
        +
        +    $addr =~ s/^\s+//;
        +    # prepend global references with optional underscore
        +    $addr =~ s/^([^\+\-0-9][^\+\-]*)/::islabel($1) or "$nmdecor$1"/ige;
        +    # put address arithmetic expression in parenthesis
        +    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
        +
        +    if (($addr ne "") && ($addr ne 0))
        +    {	if ($addr !~ /^-/)	{ $ret .= "$addr+"; }
        +	else			{ $post=$addr;      }
        +    }
        +
        +    if ($reg2 ne "")
        +    {	$idx!=0 or $idx=1;
        +	$ret .= "$reg2*$idx";
        +	$ret .= "+$reg1" if ($reg1 ne "");
        +    }
        +    else
        +    {	$ret .= "$reg1";   }
        +
        +    $ret .= "$post]";
        +    $ret =~ s/\+\]/]/; # in case $addr was the only argument
        +
        +  $ret;
        +}
        +sub ::BP	{ &get_mem("BYTE",@_);  }
        +sub ::DWP	{ &get_mem("DWORD",@_); }
        +sub ::WP	{ &get_mem("WORD",@_);	}
        +sub ::QWP	{ &get_mem("",@_);      }
        +sub ::BC	{ (($::mwerks)?"":"BYTE ")."@_";  }
        +sub ::DWC	{ (($::mwerks)?"":"DWORD ")."@_"; }
        +
        +sub ::file
        +{   if ($::mwerks)	{ push(@out,".section\t.text,64\n"); }
        +    else
        +    { my $tmp=<<___;
        +%ifidn __OUTPUT_FORMAT__,obj
        +section	code	use32 class=code align=64
        +%elifidn __OUTPUT_FORMAT__,win32
        +\$\@feat.00 equ 1
        +section	.text	code align=64
        +%else
        +section	.text	code
        +%endif
        +___
        +	push(@out,$tmp);
        +    }
        +}
        +
        +sub ::function_begin_B
        +{ my $func=shift;
        +  my $global=($func !~ /^_/);
        +  my $begin="${::lbdecor}_${func}_begin";
        +
        +    $begin =~ s/^\@/./ if ($::mwerks);	# the torture never stops
        +
        +    &::LABEL($func,$global?"$begin":"$nmdecor$func");
        +    $func=$nmdecor.$func;
        +
        +    push(@out,"${drdecor}global	$func\n")	if ($global);
        +    push(@out,"${drdecor}align	16\n");
        +    push(@out,"$func:\n");
        +    push(@out,"$begin:\n")			if ($global);
        +    $::stack=4;
        +}
        +
        +sub ::function_end_B
        +{   $::stack=0;
        +    &::wipe_labels();
        +}
        +
        +sub ::file_end
        +{   if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
        +    {	my $comm=<<___;
        +${drdecor}segment	.bss
        +${drdecor}common	${nmdecor}OPENSSL_ia32cap_P 8
        +___
        +	# comment out OPENSSL_ia32cap_P declarations
        +	grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
        +	push (@out,$comm)
        +    }
        +    push (@out,$initseg) if ($initseg);		
        +}
        +
        +sub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
        +
        +sub ::external_label
        +{   foreach(@_)
        +    {	push(@out,"${drdecor}extern\t".&::LABEL($_,$nmdecor.$_)."\n");   }
        +}
        +
        +sub ::public_label
        +{   push(@out,"${drdecor}global\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");  }
        +
        +sub ::data_byte
        +{   push(@out,(($::mwerks)?".byte\t":"db\t").join(',',@_)."\n");	}
        +sub ::data_short
        +{   push(@out,(($::mwerks)?".word\t":"dw\t").join(',',@_)."\n");	}
        +sub ::data_word
        +{   push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n");	}
        +
        +sub ::align
        +{   push(@out,"${drdecor}align\t$_[0]\n");	}
        +
        +sub ::picmeup
        +{ my($dst,$sym)=@_;
        +    &::lea($dst,&::DWP($sym));
        +}
        +
        +sub ::initseg
        +{ my $f=$nmdecor.shift;
        +    if ($::win32)
        +    {	$initseg=<<___;
        +segment	.CRT\$XCU data align=4
        +extern	$f
        +dd	$f
        +___
        +    }
        +}
        +
        +sub ::dataseg
        +{   if ($mwerks)	{ push(@out,".section\t.data,4\n");   }
        +    else		{ push(@out,"section\t.data align=4\n"); }
        +}
        +
        +sub ::safeseh
        +{ my $nm=shift;
        +    push(@out,"%if	__NASM_VERSION_ID__ >= 0x02030000\n");
        +    push(@out,"safeseh	".&::LABEL($nm,$nmdecor.$nm)."\n");
        +    push(@out,"%endif\n");
        +}
        +
        +1;
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/Makefile b/vendor/openssl/openssl/crypto/pkcs12/Makefile
        new file mode 100644
        index 000000000..3a7498fe7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/Makefile
        @@ -0,0 +1,286 @@
        +#
        +# OpenSSL/crypto/pkcs12/Makefile
        +#
        +
        +DIR=	pkcs12
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= p12_add.c p12_asn.c p12_attr.c p12_crpt.c p12_crt.c p12_decr.c \
        +	p12_init.c p12_key.c p12_kiss.c p12_mutl.c\
        +	p12_utl.c p12_npas.c pk12err.c p12_p8d.c p12_p8e.c
        +LIBOBJ= p12_add.o p12_asn.o p12_attr.o p12_crpt.o p12_crt.o p12_decr.o \
        +	p12_init.o p12_key.o p12_kiss.o p12_mutl.o\
        +	p12_utl.o p12_npas.o pk12err.o p12_p8d.o p12_p8e.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER=  pkcs12.h
        +HEADER=	$(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +test:
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +p12_add.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_add.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_add.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_add.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_add.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_add.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_add.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_add.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +p12_add.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
        +p12_add.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p12_add.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p12_add.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p12_add.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_add.c
        +p12_asn.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_asn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +p12_asn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p12_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p12_asn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p12_asn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p12_asn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p12_asn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p12_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_asn.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_asn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_asn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_asn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_asn.o: ../cryptlib.h p12_asn.c
        +p12_attr.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_attr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_attr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_attr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_attr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_attr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_attr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_attr.o: ../../include/openssl/opensslconf.h
        +p12_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_attr.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_attr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_attr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_attr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_attr.o: ../cryptlib.h p12_attr.c
        +p12_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_crpt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_crpt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_crpt.o: ../../include/openssl/opensslconf.h
        +p12_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_crpt.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_crpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_crpt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_crpt.o: ../cryptlib.h p12_crpt.c
        +p12_crt.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_crt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_crt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_crt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_crt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_crt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_crt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_crt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +p12_crt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
        +p12_crt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p12_crt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p12_crt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p12_crt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_crt.c
        +p12_decr.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_decr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_decr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_decr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_decr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_decr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_decr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_decr.o: ../../include/openssl/opensslconf.h
        +p12_decr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_decr.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_decr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_decr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_decr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_decr.o: ../cryptlib.h p12_decr.c
        +p12_init.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_init.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_init.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_init.o: ../../include/openssl/opensslconf.h
        +p12_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_init.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_init.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_init.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_init.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_init.o: ../cryptlib.h p12_init.c
        +p12_key.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +p12_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p12_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p12_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p12_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p12_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p12_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p12_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_key.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_key.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_key.o: ../cryptlib.h p12_key.c
        +p12_kiss.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_kiss.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_kiss.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_kiss.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_kiss.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_kiss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_kiss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_kiss.o: ../../include/openssl/opensslconf.h
        +p12_kiss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_kiss.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_kiss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_kiss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_kiss.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_kiss.o: ../cryptlib.h p12_kiss.c
        +p12_mutl.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_mutl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_mutl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_mutl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_mutl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_mutl.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
        +p12_mutl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p12_mutl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p12_mutl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_mutl.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_mutl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +p12_mutl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p12_mutl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p12_mutl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_mutl.c
        +p12_npas.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +p12_npas.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +p12_npas.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +p12_npas.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +p12_npas.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +p12_npas.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +p12_npas.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +p12_npas.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +p12_npas.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +p12_npas.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +p12_npas.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +p12_npas.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +p12_npas.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +p12_npas.o: p12_npas.c
        +p12_p8d.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_p8d.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_p8d.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_p8d.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_p8d.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_p8d.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_p8d.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_p8d.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +p12_p8d.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
        +p12_p8d.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p12_p8d.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p12_p8d.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p12_p8d.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_p8d.c
        +p12_p8e.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_p8e.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_p8e.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_p8e.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_p8e.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_p8e.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_p8e.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_p8e.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +p12_p8e.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
        +p12_p8e.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p12_p8e.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p12_p8e.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p12_p8e.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_p8e.c
        +p12_utl.o: ../../e_os.h ../../include/openssl/asn1.h
        +p12_utl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +p12_utl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +p12_utl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +p12_utl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +p12_utl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +p12_utl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +p12_utl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +p12_utl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
        +p12_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +p12_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +p12_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +p12_utl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_utl.c
        +pk12err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +pk12err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +pk12err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pk12err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pk12err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pk12err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pk12err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pk12err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pk12err.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
        +pk12err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pk12err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pk12err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pk12err.o: pk12err.c
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_add.c b/vendor/openssl/openssl/crypto/pkcs12/p12_add.c
        new file mode 100644
        index 000000000..27ac5facf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_add.c
        @@ -0,0 +1,240 @@
        +/* p12_add.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* Pack an object into an OCTET STRING and turn into a safebag */
        +
        +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
        +	     int nid2)
        +{
        +	PKCS12_BAGS *bag;
        +	PKCS12_SAFEBAG *safebag;
        +	if (!(bag = PKCS12_BAGS_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	bag->type = OBJ_nid2obj(nid1);
        +	if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	if (!(safebag = PKCS12_SAFEBAG_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	safebag->value.bag = bag;
        +	safebag->type = OBJ_nid2obj(nid2);
        +	return safebag;
        +}
        +
        +/* Turn PKCS8 object into a keybag */
        +
        +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
        +{
        +	PKCS12_SAFEBAG *bag;
        +	if (!(bag = PKCS12_SAFEBAG_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	bag->type = OBJ_nid2obj(NID_keyBag);
        +	bag->value.keybag = p8;
        +	return bag;
        +}
        +
        +/* Turn PKCS8 object into a shrouded keybag */
        +
        +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
        +	     int passlen, unsigned char *salt, int saltlen, int iter,
        +	     PKCS8_PRIV_KEY_INFO *p8)
        +{
        +	PKCS12_SAFEBAG *bag;
        +	const EVP_CIPHER *pbe_ciph;
        +
        +	/* Set up the safe bag */
        +	if (!(bag = PKCS12_SAFEBAG_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
        +
        +	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
        +
        +	if (pbe_ciph)
        +		pbe_nid = -1;
        +
        +	if (!(bag->value.shkeybag = 
        +	  PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
        +									 p8))) {
        +		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	return bag;
        +}
        +
        +/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
        +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
        +{
        +	PKCS7 *p7;
        +	if (!(p7 = PKCS7_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	p7->type = OBJ_nid2obj(NID_pkcs7_data);
        +	if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	
        +	if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
        +		return NULL;
        +	}
        +	return p7;
        +}
        +
        +/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
        +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
        +{
        +	if(!PKCS7_type_is_data(p7))
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,PKCS12_R_CONTENT_TYPE_NOT_DATA);
        +		return NULL;
        +		}
        +	return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
        +}
        +
        +/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
        +
        +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
        +			      unsigned char *salt, int saltlen, int iter,
        +			      STACK_OF(PKCS12_SAFEBAG) *bags)
        +{
        +	PKCS7 *p7;
        +	X509_ALGOR *pbe;
        +	const EVP_CIPHER *pbe_ciph;
        +	if (!(p7 = PKCS7_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	if(!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
        +				PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
        +		return NULL;
        +	}
        +
        +	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
        +
        +	if (pbe_ciph)
        +		pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
        +	else
        +		pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
        +
        +	if (!pbe) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
        +	p7->d.encrypted->enc_data->algorithm = pbe;
        +	M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
        +	if (!(p7->d.encrypted->enc_data->enc_data =
        +	PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen,
        +				 bags, 1))) {
        +		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
        +		return NULL;
        +	}
        +
        +	return p7;
        +}
        +
        +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen)
        +{
        +	if(!PKCS7_type_is_encrypted(p7)) return NULL;
        +	return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
        +			           ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
        +				   pass, passlen,
        +			           p7->d.encrypted->enc_data->enc_data, 1);
        +}
        +
        +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
        +								int passlen)
        +{
        +	return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
        +}
        +
        +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) 
        +{
        +	if(ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
        +		&p12->authsafes->d.data)) 
        +			return 1;
        +	return 0;
        +}
        +
        +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
        +{
        +	if (!PKCS7_type_is_data(p12->authsafes))
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,PKCS12_R_CONTENT_TYPE_NOT_DATA);
        +		return NULL;
        +		}
        +	return ASN1_item_unpack(p12->authsafes->d.data, ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_asn.c b/vendor/openssl/openssl/crypto/pkcs12/p12_asn.c
        new file mode 100644
        index 000000000..6e2763381
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_asn.c
        @@ -0,0 +1,125 @@
        +/* p12_asn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pkcs12.h>
        +
        +/* PKCS#12 ASN1 module */
        +
        +ASN1_SEQUENCE(PKCS12) = {
        +	ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(PKCS12, authsafes, PKCS7),
        +	ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA)
        +} ASN1_SEQUENCE_END(PKCS12)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS12)
        +
        +ASN1_SEQUENCE(PKCS12_MAC_DATA) = {
        +	ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG),
        +	ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING),
        +	ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(PKCS12_MAC_DATA)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
        +
        +ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0);
        +
        +ASN1_ADB(PKCS12_BAGS) = {
        +	ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)),
        +	ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)),
        +	ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)),
        +} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL);
        +
        +ASN1_SEQUENCE(PKCS12_BAGS) = {
        +	ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(PKCS12_BAGS),
        +} ASN1_SEQUENCE_END(PKCS12_BAGS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS)
        +
        +ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0);
        +
        +ASN1_ADB(PKCS12_SAFEBAG) = {
        +	ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)),
        +	ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)),
        +	ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)),
        +	ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
        +	ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
        +	ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0))
        +} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL);
        +
        +ASN1_SEQUENCE(PKCS12_SAFEBAG) = {
        +	ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(PKCS12_SAFEBAG),
        +	ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE)
        +} ASN1_SEQUENCE_END(PKCS12_SAFEBAG)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
        +
        +/* SEQUENCE OF SafeBag */
        +ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG)
        +ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS)
        +
        +/* Authsafes: SEQUENCE OF PKCS7 */
        +ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7)
        +ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES)
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_attr.c b/vendor/openssl/openssl/crypto/pkcs12/p12_attr.c
        new file mode 100644
        index 000000000..e4d9c2564
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_attr.c
        @@ -0,0 +1,145 @@
        +/* p12_attr.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* Add a local keyid to a safebag */
        +
        +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
        +	     int namelen)
        +{
        +	if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
        +				V_ASN1_OCTET_STRING, name, namelen))
        +		return 1;
        +	else 
        +		return 0;
        +}
        +
        +/* Add key usage to PKCS#8 structure */
        +
        +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
        +{
        +	unsigned char us_val;
        +	us_val = (unsigned char) usage;
        +	if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage,
        +				V_ASN1_BIT_STRING, &us_val, 1))
        +		return 1;
        +	else
        +		return 0;
        +}
        +
        +/* Add a friendlyname to a safebag */
        +
        +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
        +				 int namelen)
        +{
        +	if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
        +				MBSTRING_ASC, (unsigned char *)name, namelen))
        +		return 1;
        +	else
        +		return 0;
        +}
        +
        +
        +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
        +				 const unsigned char *name, int namelen)
        +{
        +	if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
        +				MBSTRING_BMP, name, namelen))
        +		return 1;
        +	else
        +		return 0;
        +}
        +
        +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
        +				 int namelen)
        +{
        +	if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
        +				MBSTRING_ASC, (unsigned char *)name, namelen))
        +		return 1;
        +	else
        +		return 0;
        +}
        +
        +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid)
        +{
        +	X509_ATTRIBUTE *attrib;
        +	int i;
        +	if (!attrs) return NULL;
        +	for (i = 0; i < sk_X509_ATTRIBUTE_num (attrs); i++) {
        +		attrib = sk_X509_ATTRIBUTE_value (attrs, i);
        +		if (OBJ_obj2nid (attrib->object) == attr_nid) {
        +			if (sk_ASN1_TYPE_num (attrib->value.set))
        +			    return sk_ASN1_TYPE_value(attrib->value.set, 0);
        +			else return NULL;
        +		}
        +	}
        +	return NULL;
        +}
        +
        +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
        +{
        +	ASN1_TYPE *atype;
        +	if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL;
        +	if (atype->type != V_ASN1_BMPSTRING) return NULL;
        +	return OPENSSL_uni2asc(atype->value.bmpstring->data,
        +				 atype->value.bmpstring->length);
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_crpt.c b/vendor/openssl/openssl/crypto/pkcs12/p12_crpt.c
        new file mode 100644
        index 000000000..b71d07b4d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_crpt.c
        @@ -0,0 +1,112 @@
        +/* p12_crpt.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* PKCS#12 PBE algorithms now in static table */
        +
        +void PKCS12_PBE_add(void)
        +{
        +}
        +
        +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +		ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de)
        +{
        +	PBEPARAM *pbe;
        +	int saltlen, iter, ret;
        +	unsigned char *salt;
        +	const unsigned char *pbuf;
        +	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
        +
        +	/* Extract useful info from parameter */
        +	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
        +	    param->value.sequence == NULL) {
        +		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_DECODE_ERROR);
        +		return 0;
        +	}
        +
        +	pbuf = param->value.sequence->data;
        +	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
        +		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_DECODE_ERROR);
        +		return 0;
        +	}
        +
        +	if (!pbe->iter) iter = 1;
        +	else iter = ASN1_INTEGER_get (pbe->iter);
        +	salt = pbe->salt->data;
        +	saltlen = pbe->salt->length;
        +	if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_KEY_ID,
        +			     iter, EVP_CIPHER_key_length(cipher), key, md)) {
        +		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_KEY_GEN_ERROR);
        +		PBEPARAM_free(pbe);
        +		return 0;
        +	}
        +	if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_IV_ID,
        +				iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
        +		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_IV_GEN_ERROR);
        +		PBEPARAM_free(pbe);
        +		return 0;
        +	}
        +	PBEPARAM_free(pbe);
        +	ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
        +	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
        +	OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
        +	return ret;
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_crt.c b/vendor/openssl/openssl/crypto/pkcs12/p12_crt.c
        new file mode 100644
        index 000000000..96b131def
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_crt.c
        @@ -0,0 +1,359 @@
        +/* p12_crt.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +
        +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);
        +
        +static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
        +	{
        +	int idx;
        +	X509_ATTRIBUTE *attr;
        +	idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
        +	if (idx < 0)
        +		return 1;
        +	attr = EVP_PKEY_get_attr(pkey, idx);
        +	if (!X509at_add1_attr(&bag->attrib, attr))
        +		return 0;
        +	return 1;
        +	}
        +
        +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
        +	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
        +	     int keytype)
        +{
        +	PKCS12 *p12 = NULL;
        +	STACK_OF(PKCS7) *safes = NULL;
        +	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
        +	PKCS12_SAFEBAG *bag = NULL;
        +	int i;
        +	unsigned char keyid[EVP_MAX_MD_SIZE];
        +	unsigned int keyidlen = 0;
        +
        +	/* Set defaults */
        +	if (!nid_cert)
        +		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
        +	if (!nid_key)
        +		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
        +	if (!iter)
        +		iter = PKCS12_DEFAULT_ITER;
        +	if (!mac_iter)
        +		mac_iter = 1;
        +
        +	if(!pkey && !cert && !ca)
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_CREATE,PKCS12_R_INVALID_NULL_ARGUMENT);
        +		return NULL;
        +		}
        +
        +	if (pkey && cert)
        +		{
        +		if(!X509_check_private_key(cert, pkey))
        +			return NULL;
        +		X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
        +		}
        +
        +	if (cert)
        +		{
        +		bag = PKCS12_add_cert(&bags, cert);
        +		if(name && !PKCS12_add_friendlyname(bag, name, -1))
        +			goto err;
        +		if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
        +			goto err;
        +		}
        +
        +	/* Add all other certificates */
        +	for(i = 0; i < sk_X509_num(ca); i++)
        +		{
        +		if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
        +			goto err;
        +		}
        +
        +	if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
        +			goto err;
        +
        +	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +	bags = NULL;
        +
        +	if (pkey)
        +		{
        +		bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
        +
        +		if (!bag)
        +			goto err;
        +
        +		if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
        +			goto err;
        +		if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
        +			goto err;
        +
        +		if(name && !PKCS12_add_friendlyname(bag, name, -1))
        +			goto err;
        +		if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
        +			goto err;
        +		}
        +
        +	if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
        +			goto err;
        +
        +	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +	bags = NULL;
        +
        +	p12 = PKCS12_add_safes(safes, 0);
        +
        +	if (!p12)
        +		goto err;
        +
        +	sk_PKCS7_pop_free(safes, PKCS7_free);
        +
        +	safes = NULL;
        +
        +	if ((mac_iter != -1) &&
        +		!PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
        +	    goto err;
        +
        +	return p12;
        +
        +	err:
        +
        +	if (p12)
        +		PKCS12_free(p12);
        +	if (safes)
        +		sk_PKCS7_pop_free(safes, PKCS7_free);
        +	if (bags)
        +		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +	return NULL;
        +
        +}
        +
        +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
        +	{
        +	PKCS12_SAFEBAG *bag = NULL;
        +	char *name;
        +	int namelen = -1;
        +	unsigned char *keyid;
        +	int keyidlen = -1;
        +
        +	/* Add user certificate */
        +	if(!(bag = PKCS12_x5092certbag(cert)))
        +		goto err;
        +
        +	/* Use friendlyName and localKeyID in certificate.
        +	 * (if present)
        +	 */
        +
        +	name = (char *)X509_alias_get0(cert, &namelen);
        +
        +	if(name && !PKCS12_add_friendlyname(bag, name, namelen))
        +		goto err;
        +
        +	keyid = X509_keyid_get0(cert, &keyidlen);
        +
        +	if(keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
        +		goto err;
        +
        +	if (!pkcs12_add_bag(pbags, bag))
        +		goto err;
        +
        +	return bag;
        +
        +	err:
        +
        +	if (bag)
        +		PKCS12_SAFEBAG_free(bag);
        +
        +	return NULL;
        +
        +	}
        +
        +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
        +						int key_usage, int iter,
        +						int nid_key, char *pass)
        +	{
        +
        +	PKCS12_SAFEBAG *bag = NULL;
        +	PKCS8_PRIV_KEY_INFO *p8 = NULL;
        +
        +	/* Make a PKCS#8 structure */
        +	if(!(p8 = EVP_PKEY2PKCS8(key)))
        +		goto err;
        +	if(key_usage && !PKCS8_add_keyusage(p8, key_usage))
        +		goto err;
        +	if (nid_key != -1)
        +		{
        +		bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8);
        +		PKCS8_PRIV_KEY_INFO_free(p8);
        +		}
        +	else
        +		bag = PKCS12_MAKE_KEYBAG(p8);
        +
        +	if(!bag)
        +		goto err;
        +
        +	if (!pkcs12_add_bag(pbags, bag))
        +		goto err;
        +
        +	return bag;
        +
        +	err:
        +
        +	if (bag)
        +		PKCS12_SAFEBAG_free(bag);
        +
        +	return NULL;
        +
        +	}
        +
        +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
        +						int nid_safe, int iter, char *pass)
        +	{
        +	PKCS7 *p7 = NULL;
        +	int free_safes = 0;
        +
        +	if (!*psafes)
        +		{
        +		*psafes = sk_PKCS7_new_null();
        +		if (!*psafes)
        +			return 0;
        +		free_safes = 1;
        +		}
        +	else
        +		free_safes = 0;
        +
        +	if (nid_safe == 0)
        +		nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
        +
        +	if (nid_safe == -1)
        +		p7 = PKCS12_pack_p7data(bags);
        +	else
        +		p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0,
        +					  iter, bags);
        +	if (!p7)
        +		goto err;
        +
        +	if (!sk_PKCS7_push(*psafes, p7))
        +		goto err;
        +
        +	return 1;
        +
        +	err:
        +	if (free_safes)
        +		{
        +		sk_PKCS7_free(*psafes);
        +		*psafes = NULL;
        +		}
        +
        +	if (p7)
        +		PKCS7_free(p7);
        +
        +	return 0;
        +
        +	}
        +
        +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag)
        +	{
        +	int free_bags;
        +	if (!pbags)
        +		return 1;
        +	if (!*pbags)
        +		{
        +		*pbags = sk_PKCS12_SAFEBAG_new_null();
        +		if (!*pbags)
        +			return 0;
        +		free_bags = 1;
        +		}
        +	else 
        +		free_bags = 0;
        +
        +	if (!sk_PKCS12_SAFEBAG_push(*pbags, bag))
        +		{
        +		if (free_bags)
        +			{
        +			sk_PKCS12_SAFEBAG_free(*pbags);
        +			*pbags = NULL;
        +			}
        +		return 0;
        +		}
        +
        +	return 1;
        +
        +	}
        +		
        +
        +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
        +	{
        +	PKCS12 *p12;
        +	if (nid_p7 <= 0)
        +		nid_p7 = NID_pkcs7_data;
        +	p12 = PKCS12_init(nid_p7);
        +
        +	if (!p12)
        +		return NULL;
        +
        +	if(!PKCS12_pack_authsafes(p12, safes))
        +		{
        +		PKCS12_free(p12);
        +		return NULL;
        +		}
        +
        +	return p12;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_decr.c b/vendor/openssl/openssl/crypto/pkcs12/p12_decr.c
        new file mode 100644
        index 000000000..9d3557e8d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_decr.c
        @@ -0,0 +1,184 @@
        +/* p12_decr.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* Define this to dump decrypted output to files called DERnnn */
        +/*#define DEBUG_DECRYPT*/
        +
        +
        +/* Encrypt/Decrypt a buffer based on password and algor, result in a
        + * OPENSSL_malloc'ed buffer
        + */
        +
        +unsigned char * PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
        +	     int passlen, unsigned char *in, int inlen, unsigned char **data,
        +	     int *datalen, int en_de)
        +{
        +	unsigned char *out;
        +	int outlen, i;
        +	EVP_CIPHER_CTX ctx;
        +
        +	EVP_CIPHER_CTX_init(&ctx);
        +	/* Decrypt data */
        +        if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
        +					 algor->parameter, &ctx, en_de)) {
        +		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
        +		return NULL;
        +	}
        +
        +	if(!(out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) {
        +		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +
        +	if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen))
        +		{
        +		OPENSSL_free(out);
        +		out = NULL;
        +		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +
        +	outlen = i;
        +	if(!EVP_CipherFinal_ex(&ctx, out + i, &i)) {
        +		OPENSSL_free(out);
        +		out = NULL;
        +		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
        +		goto err;
        +	}
        +	outlen += i;
        +	if (datalen) *datalen = outlen;
        +	if (data) *data = out;
        +	err:
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	return out;
        +
        +}
        +
        +/* Decrypt an OCTET STRING and decode ASN1 structure 
        + * if zbuf set zero buffer after use.
        + */
        +
        +void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
        +	     const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf)
        +{
        +	unsigned char *out;
        +	const unsigned char *p;
        +	void *ret;
        +	int outlen;
        +
        +	if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
        +			       &out, &outlen, 0)) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
        +		return NULL;
        +	}
        +	p = out;
        +#ifdef DEBUG_DECRYPT
        +	{
        +		FILE *op;
        +
        +		char fname[30];
        +		static int fnm = 1;
        +		sprintf(fname, "DER%d", fnm++);
        +		op = fopen(fname, "wb");
        +		fwrite (p, 1, outlen, op);
        +		fclose(op);
        +	}
        +#endif
        +	ret = ASN1_item_d2i(NULL, &p, outlen, it);
        +	if (zbuf) OPENSSL_cleanse(out, outlen);
        +	if(!ret) PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,PKCS12_R_DECODE_ERROR);
        +	OPENSSL_free(out);
        +	return ret;
        +}
        +
        +/* Encode ASN1 structure and encrypt, return OCTET STRING 
        + * if zbuf set zero encoding.
        + */
        +
        +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
        +				       const char *pass, int passlen,
        +				       void *obj, int zbuf)
        +{
        +	ASN1_OCTET_STRING *oct;
        +	unsigned char *in = NULL;
        +	int inlen;
        +	if (!(oct = M_ASN1_OCTET_STRING_new ())) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	inlen = ASN1_item_i2d(obj, &in, it);
        +	if (!in) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,PKCS12_R_ENCODE_ERROR);
        +		return NULL;
        +	}
        +	if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
        +				 &oct->length, 1)) {
        +		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,PKCS12_R_ENCRYPT_ERROR);
        +		OPENSSL_free(in);
        +		return NULL;
        +	}
        +	if (zbuf) OPENSSL_cleanse(in, inlen);
        +	OPENSSL_free(in);
        +	return oct;
        +}
        +
        +IMPLEMENT_PKCS12_STACK_OF(PKCS7)
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_init.c b/vendor/openssl/openssl/crypto/pkcs12/p12_init.c
        new file mode 100644
        index 000000000..d4d84b056
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_init.c
        @@ -0,0 +1,92 @@
        +/* p12_init.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* Initialise a PKCS12 structure to take data */
        +
        +PKCS12 *PKCS12_init(int mode)
        +{
        +	PKCS12 *pkcs12;
        +	if (!(pkcs12 = PKCS12_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	ASN1_INTEGER_set(pkcs12->version, 3);
        +	pkcs12->authsafes->type = OBJ_nid2obj(mode);
        +	switch (mode) {
        +		case NID_pkcs7_data:
        +			if (!(pkcs12->authsafes->d.data =
        +				 M_ASN1_OCTET_STRING_new())) {
        +			PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		break;
        +		default:
        +			PKCS12err(PKCS12_F_PKCS12_INIT,
        +				PKCS12_R_UNSUPPORTED_PKCS12_MODE);
        +			goto err;
        +	}
        +		
        +	return pkcs12;
        +err:
        +	if (pkcs12 != NULL) PKCS12_free(pkcs12);
        +	return NULL;
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_key.c b/vendor/openssl/openssl/crypto/pkcs12/p12_key.c
        new file mode 100644
        index 000000000..61d58502f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_key.c
        @@ -0,0 +1,227 @@
        +/* p12_key.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +#include <openssl/bn.h>
        +
        +/* Uncomment out this line to get debugging info about key generation */
        +/*#define DEBUG_KEYGEN*/
        +#ifdef DEBUG_KEYGEN
        +#include <openssl/bio.h>
        +extern BIO *bio_err;
        +void h__dump (unsigned char *p, int len);
        +#endif
        +
        +/* PKCS12 compatible key/IV generation */
        +#ifndef min
        +#define min(a,b) ((a) < (b) ? (a) : (b))
        +#endif
        +
        +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
        +	     int saltlen, int id, int iter, int n, unsigned char *out,
        +	     const EVP_MD *md_type)
        +{
        +	int ret;
        +	unsigned char *unipass;
        +	int uniplen;
        +
        +	if(!pass) {
        +		unipass = NULL;
        +		uniplen = 0;
        +	} else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
        +		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
        +						 id, iter, n, out, md_type);
        +	if (ret <= 0)
        +	    return 0;
        +	if(unipass) {
        +		OPENSSL_cleanse(unipass, uniplen);	/* Clear password from memory */
        +		OPENSSL_free(unipass);
        +	}
        +	return ret;
        +}
        +
        +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
        +	     int saltlen, int id, int iter, int n, unsigned char *out,
        +	     const EVP_MD *md_type)
        +{
        +	unsigned char *B, *D, *I, *p, *Ai;
        +	int Slen, Plen, Ilen, Ijlen;
        +	int i, j, u, v;
        +	int ret = 0;
        +	BIGNUM *Ij, *Bpl1;	/* These hold Ij and B + 1 */
        +	EVP_MD_CTX ctx;
        +#ifdef  DEBUG_KEYGEN
        +	unsigned char *tmpout = out;
        +	int tmpn = n;
        +#endif
        +
        +#if 0
        +	if (!pass) {
        +		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +	}
        +#endif
        +
        +	EVP_MD_CTX_init(&ctx);
        +#ifdef  DEBUG_KEYGEN
        +	fprintf(stderr, "KEYGEN DEBUG\n");
        +	fprintf(stderr, "ID %d, ITER %d\n", id, iter);
        +	fprintf(stderr, "Password (length %d):\n", passlen);
        +	h__dump(pass, passlen);
        +	fprintf(stderr, "Salt (length %d):\n", saltlen);
        +	h__dump(salt, saltlen);
        +#endif
        +	v = EVP_MD_block_size (md_type);
        +	u = EVP_MD_size (md_type);
        +	if (u < 0)
        +	    return 0;
        +	D = OPENSSL_malloc (v);
        +	Ai = OPENSSL_malloc (u);
        +	B = OPENSSL_malloc (v + 1);
        +	Slen = v * ((saltlen+v-1)/v);
        +	if(passlen) Plen = v * ((passlen+v-1)/v);
        +	else Plen = 0;
        +	Ilen = Slen + Plen;
        +	I = OPENSSL_malloc (Ilen);
        +	Ij = BN_new();
        +	Bpl1 = BN_new();
        +	if (!D || !Ai || !B || !I || !Ij || !Bpl1)
        +		goto err;
        +	for (i = 0; i < v; i++) D[i] = id;
        +	p = I;
        +	for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen];
        +	for (i = 0; i < Plen; i++) *p++ = pass[i % passlen];
        +	for (;;) {
        +		if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
        +			|| !EVP_DigestUpdate(&ctx, D, v)
        +			|| !EVP_DigestUpdate(&ctx, I, Ilen)
        +			|| !EVP_DigestFinal_ex(&ctx, Ai, NULL))
        +			goto err;
        +		for (j = 1; j < iter; j++) {
        +			if (!EVP_DigestInit_ex(&ctx, md_type, NULL)
        +				|| !EVP_DigestUpdate(&ctx, Ai, u)
        +				|| !EVP_DigestFinal_ex(&ctx, Ai, NULL))
        +			goto err;
        +		}
        +		memcpy (out, Ai, min (n, u));
        +		if (u >= n) {
        +#ifdef DEBUG_KEYGEN
        +			fprintf(stderr, "Output KEY (length %d)\n", tmpn);
        +			h__dump(tmpout, tmpn);
        +#endif
        +			ret = 1;
        +			goto end;
        +		}
        +		n -= u;
        +		out += u;
        +		for (j = 0; j < v; j++) B[j] = Ai[j % u];
        +		/* Work out B + 1 first then can use B as tmp space */
        +		if (!BN_bin2bn (B, v, Bpl1))
        +			goto err;
        +		if (!BN_add_word (Bpl1, 1))
        +			goto err;
        +		for (j = 0; j < Ilen ; j+=v) {
        +			if (!BN_bin2bn(I + j, v, Ij))
        +				goto err;
        +			if (!BN_add(Ij, Ij, Bpl1))
        +				goto err;
        +			if (!BN_bn2bin(Ij, B))
        +				goto err;
        +			Ijlen = BN_num_bytes (Ij);
        +			/* If more than 2^(v*8) - 1 cut off MSB */
        +			if (Ijlen > v) {
        +				if (!BN_bn2bin (Ij, B))
        +					goto err;
        +				memcpy (I + j, B + 1, v);
        +#ifndef PKCS12_BROKEN_KEYGEN
        +			/* If less than v bytes pad with zeroes */
        +			} else if (Ijlen < v) {
        +				memset(I + j, 0, v - Ijlen);
        +				if (!BN_bn2bin(Ij, I + j + v - Ijlen))
        +					goto err;
        +#endif
        +			} else if (!BN_bn2bin (Ij, I + j))
        +				goto err;
        +		}
        +	}
        +
        +err:
        +	PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_MALLOC_FAILURE);
        +
        +end:
        +	OPENSSL_free (Ai);
        +	OPENSSL_free (B);
        +	OPENSSL_free (D);
        +	OPENSSL_free (I);
        +	BN_free (Ij);
        +	BN_free (Bpl1);
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return ret;
        +}
        +#ifdef DEBUG_KEYGEN
        +void h__dump (unsigned char *p, int len)
        +{
        +	for (; len --; p++) fprintf(stderr, "%02X", *p);
        +	fprintf(stderr, "\n");	
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_kiss.c b/vendor/openssl/openssl/crypto/pkcs12/p12_kiss.c
        new file mode 100644
        index 000000000..206b1b0b1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_kiss.c
        @@ -0,0 +1,302 @@
        +/* p12_kiss.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* Simplified PKCS#12 routines */
        +
        +static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
        +		EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
        +
        +static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
        +		       int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
        +
        +static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
        +			EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
        +
        +/* Parse and decrypt a PKCS#12 structure returning user key, user cert
        + * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
        + * or it should point to a valid STACK structure. pkey and cert can be
        + * passed unitialised.
        + */
        +
        +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
        +	     STACK_OF(X509) **ca)
        +{
        +	STACK_OF(X509) *ocerts = NULL;
        +	X509 *x = NULL;
        +	/* Check for NULL PKCS12 structure */
        +
        +	if(!p12)
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
        +		return 0;
        +		}
        +
        +	if(pkey)
        +		*pkey = NULL;
        +	if(cert)
        +		*cert = NULL;
        +
        +	/* Check the mac */
        +
        +	/* If password is zero length or NULL then try verifying both cases
        +	 * to determine which password is correct. The reason for this is that
        +	 * under PKCS#12 password based encryption no password and a zero length
        +	 * password are two different things...
        +	 */
        +
        +	if(!pass || !*pass) {
        +		if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL;
        +		else if(PKCS12_verify_mac(p12, "", 0)) pass = "";
        +		else {
        +			PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
        +			goto err;
        +		}
        +	} else if (!PKCS12_verify_mac(p12, pass, -1)) {
        +		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
        +		goto err;
        +	}
        +
        +	/* Allocate stack for other certificates */
        +	ocerts = sk_X509_new_null();
        +
        +	if (!ocerts)
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	if (!parse_pk12 (p12, pass, -1, pkey, ocerts))
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR);
        +		goto err;
        +		}
        +
        +	while ((x = sk_X509_pop(ocerts)))
        +		{
        +		if (pkey && *pkey && cert && !*cert)
        +			{
        +			if (X509_check_private_key(x, *pkey))
        +				{
        +				*cert = x;
        +				x = NULL;
        +				}
        +			}
        +
        +		if (ca && x)
        +			{
        +			if (!*ca)
        +				*ca = sk_X509_new_null();
        +			if (!*ca)
        +				goto err;
        +			if (!sk_X509_push(*ca, x))
        +				goto err;
        +			x = NULL;
        +			}
        +		if (x)
        +			X509_free(x);
        +		}
        +
        +	if (ocerts)
        +		sk_X509_pop_free(ocerts, X509_free);
        +
        +	return 1;
        +
        + err:
        +
        +	if (pkey && *pkey)
        +		EVP_PKEY_free(*pkey);
        +	if (cert && *cert)
        +		X509_free(*cert);
        +	if (x)
        +		X509_free(x);
        +	if (ocerts)
        +		sk_X509_pop_free(ocerts, X509_free);
        +	return 0;
        +
        +}
        +
        +/* Parse the outer PKCS#12 structure */
        +
        +static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
        +	     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
        +{
        +	STACK_OF(PKCS7) *asafes;
        +	STACK_OF(PKCS12_SAFEBAG) *bags;
        +	int i, bagnid;
        +	PKCS7 *p7;
        +
        +	if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0;
        +	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
        +		p7 = sk_PKCS7_value (asafes, i);
        +		bagnid = OBJ_obj2nid (p7->type);
        +		if (bagnid == NID_pkcs7_data) {
        +			bags = PKCS12_unpack_p7data(p7);
        +		} else if (bagnid == NID_pkcs7_encrypted) {
        +			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
        +		} else continue;
        +		if (!bags) {
        +			sk_PKCS7_pop_free(asafes, PKCS7_free);
        +			return 0;
        +		}
        +	    	if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
        +			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +			sk_PKCS7_pop_free(asafes, PKCS7_free);
        +			return 0;
        +		}
        +		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +	}
        +	sk_PKCS7_pop_free(asafes, PKCS7_free);
        +	return 1;
        +}
        +
        +
        +static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
        +		      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
        +{
        +	int i;
        +	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
        +		if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i),
        +				 pass, passlen, pkey, ocerts))
        +			return 0;
        +	}
        +	return 1;
        +}
        +
        +static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
        +		     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
        +{
        +	PKCS8_PRIV_KEY_INFO *p8;
        +	X509 *x509;
        +	ASN1_TYPE *attrib;
        +	ASN1_BMPSTRING *fname = NULL;
        +	ASN1_OCTET_STRING *lkid = NULL;
        +
        +	if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
        +		fname = attrib->value.bmpstring;
        +
        +	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
        +		lkid = attrib->value.octet_string;
        +
        +	switch (M_PKCS12_bag_type(bag))
        +	{
        +	case NID_keyBag:
        +		if (!pkey || *pkey)
        +			return 1;	
        +		if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
        +			return 0;
        +	break;
        +
        +	case NID_pkcs8ShroudedKeyBag:
        +		if (!pkey || *pkey)
        +			return 1;	
        +		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
        +				return 0;
        +		*pkey = EVP_PKCS82PKEY(p8);
        +		PKCS8_PRIV_KEY_INFO_free(p8);
        +		if (!(*pkey)) return 0;
        +	break;
        +
        +	case NID_certBag:
        +		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
        +			return 1;
        +		if (!(x509 = PKCS12_certbag2x509(bag)))
        +			return 0;
        +		if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length))
        +			{
        +			X509_free(x509);
        +			return 0;
        +			}
        +		if(fname) {
        +			int len, r;
        +			unsigned char *data;
        +			len = ASN1_STRING_to_UTF8(&data, fname);
        +			if(len > 0) {
        +				r = X509_alias_set1(x509, data, len);
        +				OPENSSL_free(data);
        +				if (!r)
        +					{
        +					X509_free(x509);
        +					return 0;
        +					}
        +			}
        +		}
        +
        +		if(!sk_X509_push(ocerts, x509))
        +			{
        +			X509_free(x509);
        +			return 0;
        +			}
        +
        +	break;
        +
        +	case NID_safeContentsBag:
        +		return parse_bags(bag->value.safes, pass, passlen,
        +			 		pkey, ocerts);
        +	break;
        +
        +	default:
        +		return 1;
        +	break;
        +	}
        +	return 1;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_mutl.c b/vendor/openssl/openssl/crypto/pkcs12/p12_mutl.c
        new file mode 100644
        index 000000000..96de1bd11
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_mutl.c
        @@ -0,0 +1,190 @@
        +/* p12_mutl.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 OPENSSL_NO_HMAC
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/hmac.h>
        +#include <openssl/rand.h>
        +#include <openssl/pkcs12.h>
        +
        +/* Generate a MAC */
        +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
        +		   unsigned char *mac, unsigned int *maclen)
        +{
        +	const EVP_MD *md_type;
        +	HMAC_CTX hmac;
        +	unsigned char key[EVP_MAX_MD_SIZE], *salt;
        +	int saltlen, iter;
        +	int md_size;
        +
        +	if (!PKCS7_type_is_data(p12->authsafes))
        +		{
        +		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_CONTENT_TYPE_NOT_DATA);
        +		return 0;
        +		}
        +
        +	salt = p12->mac->salt->data;
        +	saltlen = p12->mac->salt->length;
        +	if (!p12->mac->iter) iter = 1;
        +	else iter = ASN1_INTEGER_get (p12->mac->iter);
        +    	if(!(md_type =
        +		 EVP_get_digestbyobj (p12->mac->dinfo->algor->algorithm))) {
        +		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
        +		return 0;
        +	}
        +	md_size = EVP_MD_size(md_type);
        +	if (md_size < 0)
        +	    return 0;
        +	if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
        +				 md_size, key, md_type)) {
        +		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR);
        +		return 0;
        +	}
        +	HMAC_CTX_init(&hmac);
        +	if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL)
        +    		|| !HMAC_Update(&hmac, p12->authsafes->d.data->data,
        +					 p12->authsafes->d.data->length)
        +    		|| !HMAC_Final(&hmac, mac, maclen))
        +		{
        +    		HMAC_CTX_cleanup(&hmac);
        +		return 0;
        +		}
        +    	HMAC_CTX_cleanup(&hmac);
        +	return 1;
        +}
        +
        +/* Verify the mac */
        +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
        +{
        +	unsigned char mac[EVP_MAX_MD_SIZE];
        +	unsigned int maclen;
        +	if(p12->mac == NULL) {
        +		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,PKCS12_R_MAC_ABSENT);
        +		return 0;
        +	}
        +	if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
        +		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,PKCS12_R_MAC_GENERATION_ERROR);
        +		return 0;
        +	}
        +	if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
        +	|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
        +	return 1;
        +}
        +
        +/* Set a mac */
        +
        +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
        +	     unsigned char *salt, int saltlen, int iter, const EVP_MD *md_type)
        +{
        +	unsigned char mac[EVP_MAX_MD_SIZE];
        +	unsigned int maclen;
        +
        +	if (!md_type) md_type = EVP_sha1();
        +	if (PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) ==
        +				 	PKCS12_ERROR) {
        +		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_SETUP_ERROR);
        +		return 0;
        +	}
        +	if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) {
        +		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_GENERATION_ERROR);
        +		return 0;
        +	}
        +	if (!(M_ASN1_OCTET_STRING_set (p12->mac->dinfo->digest, mac, maclen))) {
        +		PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_STRING_SET_ERROR);
        +						return 0;
        +	}
        +	return 1;
        +}
        +
        +/* Set up a mac structure */
        +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
        +	     const EVP_MD *md_type)
        +{
        +	if (!(p12->mac = PKCS12_MAC_DATA_new())) return PKCS12_ERROR;
        +	if (iter > 1) {
        +		if(!(p12->mac->iter = M_ASN1_INTEGER_new())) {
        +			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
        +			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +	}
        +	if (!saltlen) saltlen = PKCS12_SALT_LEN;
        +	p12->mac->salt->length = saltlen;
        +	if (!(p12->mac->salt->data = OPENSSL_malloc (saltlen))) {
        +		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	if (!salt) {
        +		if (RAND_pseudo_bytes (p12->mac->salt->data, saltlen) < 0)
        +			return 0;
        +	}
        +	else memcpy (p12->mac->salt->data, salt, saltlen);
        +	p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
        +	if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
        +		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;
        +	
        +	return 1;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_npas.c b/vendor/openssl/openssl/crypto/pkcs12/p12_npas.c
        new file mode 100644
        index 000000000..2f7135515
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_npas.c
        @@ -0,0 +1,225 @@
        +/* p12_npas.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/pkcs12.h>
        +
        +/* PKCS#12 password change routine */
        +
        +static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
        +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
        +			char *newpass);
        +static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
        +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
        +
        +/* 
        + * Change the password on a PKCS#12 structure.
        + */
        +
        +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
        +{
        +	/* Check for NULL PKCS12 structure */
        +
        +	if(!p12) {
        +		PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
        +		return 0;
        +	}
        +
        +	/* Check the mac */
        +	
        +	if (!PKCS12_verify_mac(p12, oldpass, -1)) {
        +		PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE);
        +		return 0;
        +	}
        +
        +	if (!newpass_p12(p12, oldpass, newpass)) {
        +		PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR);
        +		return 0;
        +	}
        +
        +	return 1;
        +}
        +
        +/* Parse the outer PKCS#12 structure */
        +
        +static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
        +{
        +	STACK_OF(PKCS7) *asafes, *newsafes;
        +	STACK_OF(PKCS12_SAFEBAG) *bags;
        +	int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
        +	PKCS7 *p7, *p7new;
        +	ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
        +	unsigned char mac[EVP_MAX_MD_SIZE];
        +	unsigned int maclen;
        +
        +	if (!(asafes = PKCS12_unpack_authsafes(p12))) return 0;
        +	if(!(newsafes = sk_PKCS7_new_null())) return 0;
        +	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
        +		p7 = sk_PKCS7_value(asafes, i);
        +		bagnid = OBJ_obj2nid(p7->type);
        +		if (bagnid == NID_pkcs7_data) {
        +			bags = PKCS12_unpack_p7data(p7);
        +		} else if (bagnid == NID_pkcs7_encrypted) {
        +			bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
        +			if (!alg_get(p7->d.encrypted->enc_data->algorithm,
        +				&pbe_nid, &pbe_iter, &pbe_saltlen))
        +				{
        +				sk_PKCS12_SAFEBAG_pop_free(bags,
        +						PKCS12_SAFEBAG_free);
        +				bags = NULL;
        +				}
        +		} else continue;
        +		if (!bags) {
        +			sk_PKCS7_pop_free(asafes, PKCS7_free);
        +			return 0;
        +		}
        +	    	if (!newpass_bags(bags, oldpass, newpass)) {
        +			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +			sk_PKCS7_pop_free(asafes, PKCS7_free);
        +			return 0;
        +		}
        +		/* Repack bag in same form with new password */
        +		if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags);
        +		else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
        +						 pbe_saltlen, pbe_iter, bags);
        +		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        +		if(!p7new) {
        +			sk_PKCS7_pop_free(asafes, PKCS7_free);
        +			return 0;
        +		}
        +		sk_PKCS7_push(newsafes, p7new);
        +	}
        +	sk_PKCS7_pop_free(asafes, PKCS7_free);
        +
        +	/* Repack safe: save old safe in case of error */
        +
        +	p12_data_tmp = p12->authsafes->d.data;
        +	if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr;
        +	if(!PKCS12_pack_authsafes(p12, newsafes)) goto saferr;
        +
        +	if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr;
        +	if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr;
        +	if(!ASN1_OCTET_STRING_set(macnew, mac, maclen)) goto saferr;
        +	ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
        +	p12->mac->dinfo->digest = macnew;
        +	ASN1_OCTET_STRING_free(p12_data_tmp);
        +
        +	return 1;
        +
        +	saferr:
        +	/* Restore old safe */
        +	ASN1_OCTET_STRING_free(p12->authsafes->d.data);
        +	ASN1_OCTET_STRING_free(macnew);
        +	p12->authsafes->d.data = p12_data_tmp;
        +	return 0;
        +
        +}
        +
        +
        +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
        +			char *newpass)
        +{
        +	int i;
        +	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
        +		if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i),
        +				 oldpass, newpass))
        +		    return 0;
        +	}
        +	return 1;
        +}
        +
        +/* Change password of safebag: only needs handle shrouded keybags */
        +
        +static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
        +{
        +	PKCS8_PRIV_KEY_INFO *p8;
        +	X509_SIG *p8new;
        +	int p8_nid, p8_saltlen, p8_iter;
        +
        +	if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1;
        +
        +	if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0;
        +	if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
        +							&p8_saltlen))
        +		return 0;
        +	if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
        +						     p8_iter, p8))) return 0;
        +	X509_SIG_free(bag->value.shkeybag);
        +	bag->value.shkeybag = p8new;
        +	return 1;
        +}
        +
        +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
        +{
        +        PBEPARAM *pbe;
        +        const unsigned char *p;
        +
        +        p = alg->parameter->value.sequence->data;
        +        pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
        +	if (!pbe)
        +		return 0;
        +        *pnid = OBJ_obj2nid(alg->algorithm);
        +	*piter = ASN1_INTEGER_get(pbe->iter);
        +	*psaltlen = pbe->salt->length;
        +        PBEPARAM_free(pbe);
        +        return 1;
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_p8d.c b/vendor/openssl/openssl/crypto/pkcs12/p12_p8d.c
        new file mode 100644
        index 000000000..deba81e4a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_p8d.c
        @@ -0,0 +1,68 @@
        +/* p12_p8d.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen)
        +{
        +	return PKCS12_item_decrypt_d2i(p8->algor, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
        +					passlen, p8->digest, 1);
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_p8e.c b/vendor/openssl/openssl/crypto/pkcs12/p12_p8e.c
        new file mode 100644
        index 000000000..bf20a77b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_p8e.c
        @@ -0,0 +1,97 @@
        +/* p12_p8e.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
        +			 const char *pass, int passlen,
        +			 unsigned char *salt, int saltlen, int iter,
        +						PKCS8_PRIV_KEY_INFO *p8inf)
        +{
        +	X509_SIG *p8 = NULL;
        +	X509_ALGOR *pbe;
        +
        +	if (!(p8 = X509_SIG_new())) {
        +		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +
        +	if(pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
        +	else pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
        +	if(!pbe) {
        +		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
        +		goto err;
        +	}
        +	X509_ALGOR_free(p8->algor);
        +	p8->algor = pbe;
        +	M_ASN1_OCTET_STRING_free(p8->digest);
        +	p8->digest = PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
        +					pass, passlen, p8inf, 1);
        +	if(!p8->digest) {
        +		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
        +		goto err;
        +	}
        +
        +	return p8;
        +
        +	err:
        +	X509_SIG_free(p8);
        +	return NULL;
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/p12_utl.c b/vendor/openssl/openssl/crypto/pkcs12/p12_utl.c
        new file mode 100644
        index 000000000..59c6f453f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/p12_utl.c
        @@ -0,0 +1,146 @@
        +/* p12_utl.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/pkcs12.h>
        +
        +/* Cheap and nasty Unicode stuff */
        +
        +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
        +{
        +	int ulen, i;
        +	unsigned char *unitmp;
        +	if (asclen == -1) asclen = strlen(asc);
        +	ulen = asclen*2  + 2;
        +	if (!(unitmp = OPENSSL_malloc(ulen))) return NULL;
        +	for (i = 0; i < ulen - 2; i+=2) {
        +		unitmp[i] = 0;
        +		unitmp[i + 1] = asc[i>>1];
        +	}
        +	/* Make result double null terminated */
        +	unitmp[ulen - 2] = 0;
        +	unitmp[ulen - 1] = 0;
        +	if (unilen) *unilen = ulen;
        +	if (uni) *uni = unitmp;
        +	return unitmp;
        +}
        +
        +char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
        +{
        +	int asclen, i;
        +	char *asctmp;
        +	asclen = unilen / 2;
        +	/* If no terminating zero allow for one */
        +	if (!unilen || uni[unilen - 1]) asclen++;
        +	uni++;
        +	if (!(asctmp = OPENSSL_malloc(asclen))) return NULL;
        +	for (i = 0; i < unilen; i+=2) asctmp[i>>1] = uni[i];
        +	asctmp[asclen - 1] = 0;
        +	return asctmp;
        +}
        +
        +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
        +{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
        +}
        +
        +#ifndef OPENSSL_NO_FP_API
        +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
        +{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
        +}
        +#endif
        +
        +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
        +{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
        +}
        +#ifndef OPENSSL_NO_FP_API
        +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
        +{
        +        return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
        +}
        +#endif
        +
        +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509)
        +{
        +	return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
        +			NID_x509Certificate, NID_certBag);
        +}
        +
        +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl)
        +{
        +	return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
        +			NID_x509Crl, NID_crlBag);
        +}
        +
        +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag)
        +{
        +	if(M_PKCS12_bag_type(bag) != NID_certBag) return NULL;
        +	if(M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) return NULL;
        +	return ASN1_item_unpack(bag->value.bag->value.octet, ASN1_ITEM_rptr(X509));
        +}
        +
        +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag)
        +{
        +	if(M_PKCS12_bag_type(bag) != NID_crlBag) return NULL;
        +	if(M_PKCS12_cert_bag_type(bag) != NID_x509Crl) return NULL;
        +	return ASN1_item_unpack(bag->value.bag->value.octet,
        +							ASN1_ITEM_rptr(X509_CRL));
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/pk12err.c b/vendor/openssl/openssl/crypto/pkcs12/pk12err.c
        new file mode 100644
        index 000000000..f6ddf2df1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/pk12err.c
        @@ -0,0 +1,144 @@
        +/* crypto/pkcs12/pk12err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/pkcs12.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason)
        +
        +static ERR_STRING_DATA PKCS12_str_functs[]=
        +	{
        +{ERR_FUNC(PKCS12_F_PARSE_BAG),	"PARSE_BAG"},
        +{ERR_FUNC(PKCS12_F_PARSE_BAGS),	"PARSE_BAGS"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME),	"PKCS12_ADD_FRIENDLYNAME"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC),	"PKCS12_add_friendlyname_asc"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI),	"PKCS12_add_friendlyname_uni"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID),	"PKCS12_add_localkeyid"},
        +{ERR_FUNC(PKCS12_F_PKCS12_CREATE),	"PKCS12_create"},
        +{ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC),	"PKCS12_gen_mac"},
        +{ERR_FUNC(PKCS12_F_PKCS12_INIT),	"PKCS12_init"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I),	"PKCS12_item_decrypt_d2i"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT),	"PKCS12_item_i2d_encrypt"},
        +{ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG),	"PKCS12_item_pack_safebag"},
        +{ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC),	"PKCS12_key_gen_asc"},
        +{ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI),	"PKCS12_key_gen_uni"},
        +{ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG),	"PKCS12_MAKE_KEYBAG"},
        +{ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG),	"PKCS12_MAKE_SHKEYBAG"},
        +{ERR_FUNC(PKCS12_F_PKCS12_NEWPASS),	"PKCS12_newpass"},
        +{ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA),	"PKCS12_pack_p7data"},
        +{ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA),	"PKCS12_pack_p7encdata"},
        +{ERR_FUNC(PKCS12_F_PKCS12_PARSE),	"PKCS12_parse"},
        +{ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT),	"PKCS12_pbe_crypt"},
        +{ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN),	"PKCS12_PBE_keyivgen"},
        +{ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC),	"PKCS12_setup_mac"},
        +{ERR_FUNC(PKCS12_F_PKCS12_SET_MAC),	"PKCS12_set_mac"},
        +{ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES),	"PKCS12_unpack_authsafes"},
        +{ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA),	"PKCS12_unpack_p7data"},
        +{ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC),	"PKCS12_verify_mac"},
        +{ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE),	"PKCS8_add_keyusage"},
        +{ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT),	"PKCS8_encrypt"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA PKCS12_str_reasons[]=
        +	{
        +{ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE),"cant pack structure"},
        +{ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA),"content type not data"},
        +{ERR_REASON(PKCS12_R_DECODE_ERROR)       ,"decode error"},
        +{ERR_REASON(PKCS12_R_ENCODE_ERROR)       ,"encode error"},
        +{ERR_REASON(PKCS12_R_ENCRYPT_ERROR)      ,"encrypt error"},
        +{ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE),"error setting encrypted data type"},
        +{ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT),"invalid null argument"},
        +{ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER),"invalid null pkcs12 pointer"},
        +{ERR_REASON(PKCS12_R_IV_GEN_ERROR)       ,"iv gen error"},
        +{ERR_REASON(PKCS12_R_KEY_GEN_ERROR)      ,"key gen error"},
        +{ERR_REASON(PKCS12_R_MAC_ABSENT)         ,"mac absent"},
        +{ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR),"mac generation error"},
        +{ERR_REASON(PKCS12_R_MAC_SETUP_ERROR)    ,"mac setup error"},
        +{ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR),"mac string set error"},
        +{ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR)   ,"mac verify error"},
        +{ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE) ,"mac verify failure"},
        +{ERR_REASON(PKCS12_R_PARSE_ERROR)        ,"parse error"},
        +{ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR),"pkcs12 algor cipherinit error"},
        +{ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR),"pkcs12 cipherfinal error"},
        +{ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR),"pkcs12 pbe crypt error"},
        +{ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM),"unknown digest algorithm"},
        +{ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE),"unsupported pkcs12 mode"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_PKCS12_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,PKCS12_str_functs);
        +		ERR_load_strings(0,PKCS12_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs12/pkcs12.h b/vendor/openssl/openssl/crypto/pkcs12/pkcs12.h
        new file mode 100644
        index 000000000..b17eb9f42
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs12/pkcs12.h
        @@ -0,0 +1,331 @@
        +/* pkcs12.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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_PKCS12_H
        +#define HEADER_PKCS12_H
        +
        +#include <openssl/bio.h>
        +#include <openssl/x509.h>
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +#define PKCS12_KEY_ID	1
        +#define PKCS12_IV_ID	2
        +#define PKCS12_MAC_ID	3
        +
        +/* Default iteration count */
        +#ifndef PKCS12_DEFAULT_ITER
        +#define PKCS12_DEFAULT_ITER	PKCS5_DEFAULT_ITER
        +#endif
        +
        +#define PKCS12_MAC_KEY_LENGTH 20
        +
        +#define PKCS12_SALT_LEN	8
        +
        +/* Uncomment out next line for unicode password and names, otherwise ASCII */
        +
        +/*#define PBE_UNICODE*/
        +
        +#ifdef PBE_UNICODE
        +#define PKCS12_key_gen PKCS12_key_gen_uni
        +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
        +#else
        +#define PKCS12_key_gen PKCS12_key_gen_asc
        +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
        +#endif
        +
        +/* MS key usage constants */
        +
        +#define KEY_EX	0x10
        +#define KEY_SIG 0x80
        +
        +typedef struct {
        +X509_SIG *dinfo;
        +ASN1_OCTET_STRING *salt;
        +ASN1_INTEGER *iter;	/* defaults to 1 */
        +} PKCS12_MAC_DATA;
        +
        +typedef struct {
        +ASN1_INTEGER *version;
        +PKCS12_MAC_DATA *mac;
        +PKCS7 *authsafes;
        +} PKCS12;
        +
        +typedef struct {
        +ASN1_OBJECT *type;
        +union {
        +	struct pkcs12_bag_st *bag; /* secret, crl and certbag */
        +	struct pkcs8_priv_key_info_st	*keybag; /* keybag */
        +	X509_SIG *shkeybag; /* shrouded key bag */
        +	STACK_OF(PKCS12_SAFEBAG) *safes;
        +	ASN1_TYPE *other;
        +}value;
        +STACK_OF(X509_ATTRIBUTE) *attrib;
        +} PKCS12_SAFEBAG;
        +
        +DECLARE_STACK_OF(PKCS12_SAFEBAG)
        +DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
        +DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)
        +
        +typedef struct pkcs12_bag_st {
        +ASN1_OBJECT *type;
        +union {
        +	ASN1_OCTET_STRING *x509cert;
        +	ASN1_OCTET_STRING *x509crl;
        +	ASN1_OCTET_STRING *octet;
        +	ASN1_IA5STRING *sdsicert;
        +	ASN1_TYPE *other; /* Secret or other bag */
        +}value;
        +} PKCS12_BAGS;
        +
        +#define PKCS12_ERROR	0
        +#define PKCS12_OK	1
        +
        +/* Compatibility macros */
        +
        +#define M_PKCS12_x5092certbag PKCS12_x5092certbag
        +#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag
        +
        +#define M_PKCS12_certbag2x509 PKCS12_certbag2x509
        +#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl 
        +
        +#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
        +#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
        +#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
        +#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata
        +
        +#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
        +#define M_PKCS8_decrypt PKCS8_decrypt
        +
        +#define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
        +#define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
        +#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type
        +
        +#define PKCS12_get_attr(bag, attr_nid) \
        +			 PKCS12_get_attr_gen(bag->attrib, attr_nid)
        +
        +#define PKCS8_get_attr(p8, attr_nid) \
        +		PKCS12_get_attr_gen(p8->attributes, attr_nid)
        +
        +#define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)
        +
        +
        +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
        +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
        +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
        +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);
        +
        +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
        +	     int nid2);
        +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
        +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen);
        +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
        +								int passlen);
        +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, 
        +			const char *pass, int passlen,
        +			unsigned char *salt, int saltlen, int iter,
        +			PKCS8_PRIV_KEY_INFO *p8);
        +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
        +				     int passlen, unsigned char *salt,
        +				     int saltlen, int iter,
        +				     PKCS8_PRIV_KEY_INFO *p8);
        +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
        +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
        +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
        +			     unsigned char *salt, int saltlen, int iter,
        +			     STACK_OF(PKCS12_SAFEBAG) *bags);
        +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen);
        +
        +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
        +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);
        +
        +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen);
        +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
        +				int namelen);
        +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
        +				int namelen);
        +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name,
        +				int namelen);
        +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
        +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
        +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
        +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
        +				int passlen, unsigned char *in, int inlen,
        +				unsigned char **data, int *datalen, int en_de);
        +void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
        +	     const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf);
        +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
        +				       const char *pass, int passlen,
        +				       void *obj, int zbuf);
        +PKCS12 *PKCS12_init(int mode);
        +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
        +		       int saltlen, int id, int iter, int n,
        +		       unsigned char *out, const EVP_MD *md_type);
        +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type);
        +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
        +			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md_type,
        +			 int en_de);
        +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
        +			 unsigned char *mac, unsigned int *maclen);
        +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
        +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
        +		   unsigned char *salt, int saltlen, int iter,
        +		   const EVP_MD *md_type);
        +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
        +					 int saltlen, const EVP_MD *md_type);
        +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
        +char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
        +
        +DECLARE_ASN1_FUNCTIONS(PKCS12)
        +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
        +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
        +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
        +
        +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
        +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
        +
        +void PKCS12_PBE_add(void);
        +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
        +		 STACK_OF(X509) **ca);
        +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
        +			 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
        +						 int mac_iter, int keytype);
        +
        +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
        +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
        +						int key_usage, int iter,
        +						int key_nid, char *pass);
        +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
        +					int safe_nid, int iter, char *pass);
        +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
        +
        +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
        +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
        +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
        +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
        +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_PKCS12_strings(void);
        +
        +/* Error codes for the PKCS12 functions. */
        +
        +/* Function codes. */
        +#define PKCS12_F_PARSE_BAG				 129
        +#define PKCS12_F_PARSE_BAGS				 103
        +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME		 100
        +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC		 127
        +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI		 102
        +#define PKCS12_F_PKCS12_ADD_LOCALKEYID			 104
        +#define PKCS12_F_PKCS12_CREATE				 105
        +#define PKCS12_F_PKCS12_GEN_MAC				 107
        +#define PKCS12_F_PKCS12_INIT				 109
        +#define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I		 106
        +#define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT		 108
        +#define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG		 117
        +#define PKCS12_F_PKCS12_KEY_GEN_ASC			 110
        +#define PKCS12_F_PKCS12_KEY_GEN_UNI			 111
        +#define PKCS12_F_PKCS12_MAKE_KEYBAG			 112
        +#define PKCS12_F_PKCS12_MAKE_SHKEYBAG			 113
        +#define PKCS12_F_PKCS12_NEWPASS				 128
        +#define PKCS12_F_PKCS12_PACK_P7DATA			 114
        +#define PKCS12_F_PKCS12_PACK_P7ENCDATA			 115
        +#define PKCS12_F_PKCS12_PARSE				 118
        +#define PKCS12_F_PKCS12_PBE_CRYPT			 119
        +#define PKCS12_F_PKCS12_PBE_KEYIVGEN			 120
        +#define PKCS12_F_PKCS12_SETUP_MAC			 122
        +#define PKCS12_F_PKCS12_SET_MAC				 123
        +#define PKCS12_F_PKCS12_UNPACK_AUTHSAFES		 130
        +#define PKCS12_F_PKCS12_UNPACK_P7DATA			 131
        +#define PKCS12_F_PKCS12_VERIFY_MAC			 126
        +#define PKCS12_F_PKCS8_ADD_KEYUSAGE			 124
        +#define PKCS12_F_PKCS8_ENCRYPT				 125
        +
        +/* Reason codes. */
        +#define PKCS12_R_CANT_PACK_STRUCTURE			 100
        +#define PKCS12_R_CONTENT_TYPE_NOT_DATA			 121
        +#define PKCS12_R_DECODE_ERROR				 101
        +#define PKCS12_R_ENCODE_ERROR				 102
        +#define PKCS12_R_ENCRYPT_ERROR				 103
        +#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE	 120
        +#define PKCS12_R_INVALID_NULL_ARGUMENT			 104
        +#define PKCS12_R_INVALID_NULL_PKCS12_POINTER		 105
        +#define PKCS12_R_IV_GEN_ERROR				 106
        +#define PKCS12_R_KEY_GEN_ERROR				 107
        +#define PKCS12_R_MAC_ABSENT				 108
        +#define PKCS12_R_MAC_GENERATION_ERROR			 109
        +#define PKCS12_R_MAC_SETUP_ERROR			 110
        +#define PKCS12_R_MAC_STRING_SET_ERROR			 111
        +#define PKCS12_R_MAC_VERIFY_ERROR			 112
        +#define PKCS12_R_MAC_VERIFY_FAILURE			 113
        +#define PKCS12_R_PARSE_ERROR				 114
        +#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR		 115
        +#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR		 116
        +#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR			 117
        +#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM		 118
        +#define PKCS12_R_UNSUPPORTED_PKCS12_MODE		 119
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/Makefile b/vendor/openssl/openssl/crypto/pkcs7/Makefile
        new file mode 100644
        index 000000000..56dc6823d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/Makefile
        @@ -0,0 +1,194 @@
        +#
        +# OpenSSL/crypto/pkcs7/Makefile
        +#
        +
        +DIR=	pkcs7
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +PEX_LIBS=
        +EX_LIBS=
        + 
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	pk7_asn1.c pk7_lib.c pkcs7err.c pk7_doit.c pk7_smime.c pk7_attr.c \
        +	pk7_mime.c bio_pk7.c
        +LIBOBJ= pk7_asn1.o pk7_lib.o pkcs7err.o pk7_doit.o pk7_smime.o pk7_attr.o \
        +	pk7_mime.o bio_pk7.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER=  pkcs7.h
        +HEADER=	$(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +test:
        +
        +all:	lib
        +
        +testapps: enc dec sign verify
        +
        +enc: enc.o lib
        +	$(CC) $(CFLAGS) -o enc enc.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
        +
        +dec: dec.o lib
        +	$(CC) $(CFLAGS) -o dec dec.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
        +
        +sign: sign.o lib
        +	$(CC) $(CFLAGS) -o sign sign.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
        +
        +verify: verify.o example.o lib
        +	$(CC) $(CFLAGS) -o verify verify.o $(PEX_LIBS) example.o $(LIB) $(EX_LIBS)
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +bio_pk7.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +bio_pk7.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +bio_pk7.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +bio_pk7.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +bio_pk7.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +bio_pk7.o: ../../include/openssl/symhacks.h bio_pk7.c
        +pk7_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
        +pk7_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +pk7_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +pk7_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pk7_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pk7_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pk7_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pk7_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pk7_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pk7_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pk7_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pk7_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pk7_asn1.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pk7_asn1.c
        +pk7_attr.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +pk7_attr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pk7_attr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pk7_attr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pk7_attr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pk7_attr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pk7_attr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pk7_attr.o: ../../include/openssl/opensslconf.h
        +pk7_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pk7_attr.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +pk7_attr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pk7_attr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pk7_attr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pk7_attr.o: ../../include/openssl/x509_vfy.h pk7_attr.c
        +pk7_doit.o: ../../e_os.h ../../include/openssl/asn1.h
        +pk7_doit.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pk7_doit.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pk7_doit.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pk7_doit.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pk7_doit.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pk7_doit.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pk7_doit.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pk7_doit.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pk7_doit.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pk7_doit.o: ../../include/openssl/x509v3.h ../cryptlib.h pk7_doit.c
        +pk7_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +pk7_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pk7_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pk7_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pk7_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pk7_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pk7_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pk7_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +pk7_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +pk7_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pk7_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pk7_lib.o: ../asn1/asn1_locl.h ../cryptlib.h pk7_lib.c
        +pk7_mime.o: ../../e_os.h ../../include/openssl/asn1.h
        +pk7_mime.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pk7_mime.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pk7_mime.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pk7_mime.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +pk7_mime.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +pk7_mime.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +pk7_mime.o: ../../include/openssl/opensslconf.h
        +pk7_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pk7_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +pk7_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +pk7_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pk7_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +pk7_mime.o: ../cryptlib.h pk7_mime.c
        +pk7_smime.o: ../../e_os.h ../../include/openssl/asn1.h
        +pk7_smime.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pk7_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pk7_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pk7_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pk7_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pk7_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pk7_smime.o: ../../include/openssl/objects.h
        +pk7_smime.o: ../../include/openssl/opensslconf.h
        +pk7_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pk7_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pk7_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pk7_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pk7_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pk7_smime.o: ../cryptlib.h pk7_smime.c
        +pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +pkcs7err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pkcs7err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +pkcs7err.o: ../../include/openssl/opensslconf.h
        +pkcs7err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pkcs7err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pkcs7err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +pkcs7err.o: pkcs7err.c
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/bio_ber.c b/vendor/openssl/openssl/crypto/pkcs7/bio_ber.c
        new file mode 100644
        index 000000000..31973fcd1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/bio_ber.c
        @@ -0,0 +1,466 @@
        +/* crypto/evp/bio_ber.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +
        +static int ber_write(BIO *h,char *buf,int num);
        +static int ber_read(BIO *h,char *buf,int size);
        +/*static int ber_puts(BIO *h,char *str); */
        +/*static int ber_gets(BIO *h,char *str,int size); */
        +static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2);
        +static int ber_new(BIO *h);
        +static int ber_free(BIO *data);
        +static long ber_callback_ctrl(BIO *h,int cmd,void *(*fp)());
        +#define BER_BUF_SIZE	(32)
        +
        +/* This is used to hold the state of the BER objects being read. */
        +typedef struct ber_struct
        +	{
        +	int tag;
        +	int class;
        +	long length;
        +	int inf;
        +	int num_left;
        +	int depth;
        +	} BER_CTX;
        +
        +typedef struct bio_ber_struct
        +	{
        +	int tag;
        +	int class;
        +	long length;
        +	int inf;
        +
        +	/* most of the following are used when doing non-blocking IO */
        +	/* reading */
        +	long num_left;	/* number of bytes still to read/write in block */
        +	int depth;	/* used with indefinite encoding. */
        +	int finished;	/* No more read data */
        +
        +	/* writting */ 
        +	char *w_addr;
        +	int w_offset;
        +	int w_left;
        +
        +	int buf_len;
        +	int buf_off;
        +	unsigned char buf[BER_BUF_SIZE];
        +	} BIO_BER_CTX;
        +
        +static BIO_METHOD methods_ber=
        +	{
        +	BIO_TYPE_CIPHER,"cipher",
        +	ber_write,
        +	ber_read,
        +	NULL, /* ber_puts, */
        +	NULL, /* ber_gets, */
        +	ber_ctrl,
        +	ber_new,
        +	ber_free,
        +	ber_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_ber(void)
        +	{
        +	return(&methods_ber);
        +	}
        +
        +static int ber_new(BIO *bi)
        +	{
        +	BIO_BER_CTX *ctx;
        +
        +	ctx=(BIO_BER_CTX *)OPENSSL_malloc(sizeof(BIO_BER_CTX));
        +	if (ctx == NULL) return(0);
        +
        +	memset((char *)ctx,0,sizeof(BIO_BER_CTX));
        +
        +	bi->init=0;
        +	bi->ptr=(char *)ctx;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int ber_free(BIO *a)
        +	{
        +	BIO_BER_CTX *b;
        +
        +	if (a == NULL) return(0);
        +	b=(BIO_BER_CTX *)a->ptr;
        +	OPENSSL_cleanse(a->ptr,sizeof(BIO_BER_CTX));
        +	OPENSSL_free(a->ptr);
        +	a->ptr=NULL;
        +	a->init=0;
        +	a->flags=0;
        +	return(1);
        +	}
        +
        +int bio_ber_get_header(BIO *bio, BIO_BER_CTX *ctx)
        +	{
        +	char buf[64];
        +	int i,j,n;
        +	int ret;
        +	unsigned char *p;
        +	unsigned long length
        +	int tag;
        +	int class;
        +	long max;
        +
        +	BIO_clear_retry_flags(b);
        +
        +	/* Pack the buffer down if there is a hole at the front */
        +	if (ctx->buf_off != 0)
        +		{
        +		p=ctx->buf;
        +		j=ctx->buf_off;
        +		n=ctx->buf_len-j;
        +		for (i=0; i<n; i++)
        +			{
        +			p[0]=p[j];
        +			p++;
        +			}
        +		ctx->buf_len-j;
        +		ctx->buf_off=0;
        +		}
        +
        +	/* If there is more room, read some more data */
        +	i=BER_BUF_SIZE-ctx->buf_len;
        +	if (i)
        +		{
        +		i=BIO_read(bio->next_bio,&(ctx->buf[ctx->buf_len]),i);
        +		if (i <= 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			return(i);
        +			}
        +		else
        +			ctx->buf_len+=i;
        +		}
        +
        +	max=ctx->buf_len;
        +	p=ctx->buf;
        +	ret=ASN1_get_object(&p,&length,&tag,&class,max);
        +
        +	if (ret & 0x80)
        +		{
        +		if ((ctx->buf_len < BER_BUF_SIZE) &&
        +			(ERR_GET_REASON(ERR_peek_error()) == ASN1_R_TOO_LONG))
        +			{
        +			ERR_clear_error(); /* clear the error */
        +			BIO_set_retry_read(b);
        +			}
        +		return(-1);
        +		}
        +
        +	/* We have no error, we have a header, so make use of it */
        +
        +	if ((ctx->tag  >= 0) && (ctx->tag != tag))
        +		{
        +		BIOerr(BIO_F_BIO_BER_GET_HEADER,BIO_R_TAG_MISMATCH);
        +		sprintf(buf,"tag=%d, got %d",ctx->tag,tag);
        +		ERR_add_error_data(1,buf);
        +		return(-1);
        +		}
        +	if (ret & 0x01)
        +	if (ret & V_ASN1_CONSTRUCTED)
        +	}
        +	
        +static int ber_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=0,i,n;
        +	BIO_BER_CTX *ctx;
        +
        +	BIO_clear_retry_flags(b);
        +
        +	if (out == NULL) return(0);
        +	ctx=(BIO_BER_CTX *)b->ptr;
        +
        +	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
        +
        +	if (ctx->finished) return(0);
        +
        +again:
        +	/* First see if we are half way through reading a block */
        +	if (ctx->num_left > 0)
        +		{
        +		if (ctx->num_left < outl)
        +			n=ctx->num_left;
        +		else
        +			n=outl;
        +		i=BIO_read(b->next_bio,out,n);
        +		if (i <= 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			return(i);
        +			}
        +		ctx->num_left-=i;
        +		outl-=i;
        +		ret+=i;
        +		if (ctx->num_left <= 0)
        +			{
        +			ctx->depth--;
        +			if (ctx->depth <= 0)
        +				ctx->finished=1;
        +			}
        +		if (outl <= 0)
        +			return(ret);
        +		else
        +			goto again;
        +		}
        +	else	/* we need to read another BER header */
        +		{
        +		}
        +	}
        +
        +static int ber_write(BIO *b, char *in, int inl)
        +	{
        +	int ret=0,n,i;
        +	BIO_ENC_CTX *ctx;
        +
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +	ret=inl;
        +
        +	BIO_clear_retry_flags(b);
        +	n=ctx->buf_len-ctx->buf_off;
        +	while (n > 0)
        +		{
        +		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +		if (i <= 0)
        +			{
        +			BIO_copy_next_retry(b);
        +			return(i);
        +			}
        +		ctx->buf_off+=i;
        +		n-=i;
        +		}
        +	/* at this point all pending data has been written */
        +
        +	if ((in == NULL) || (inl <= 0)) return(0);
        +
        +	ctx->buf_off=0;
        +	while (inl > 0)
        +		{
        +		n=(inl > ENC_BLOCK_SIZE)?ENC_BLOCK_SIZE:inl;
        +		EVP_CipherUpdate(&(ctx->cipher),
        +			(unsigned char *)ctx->buf,&ctx->buf_len,
        +			(unsigned char *)in,n);
        +		inl-=n;
        +		in+=n;
        +
        +		ctx->buf_off=0;
        +		n=ctx->buf_len;
        +		while (n > 0)
        +			{
        +			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
        +			if (i <= 0)
        +				{
        +				BIO_copy_next_retry(b);
        +				return(i);
        +				}
        +			n-=i;
        +			ctx->buf_off+=i;
        +			}
        +		ctx->buf_len=0;
        +		ctx->buf_off=0;
        +		}
        +	BIO_copy_next_retry(b);
        +	return(ret);
        +	}
        +
        +static long ber_ctrl(BIO *b, int cmd, long num, char *ptr)
        +	{
        +	BIO *dbio;
        +	BIO_ENC_CTX *ctx,*dctx;
        +	long ret=1;
        +	int i;
        +
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		ctx->ok=1;
        +		ctx->finished=0;
        +		EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
        +			ctx->cipher.berrypt);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_EOF:	/* More to read */
        +		if (ctx->cont <= 0)
        +			ret=1;
        +		else
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_WPENDING:
        +		ret=ctx->buf_len-ctx->buf_off;
        +		if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_PENDING: /* More to read in buffer */
        +		ret=ctx->buf_len-ctx->buf_off;
        +		if (ret <= 0)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		/* do a final write */
        +again:
        +		while (ctx->buf_len != ctx->buf_off)
        +			{
        +			i=ber_write(b,NULL,0);
        +			if (i < 0)
        +				{
        +				ret=i;
        +				break;
        +				}
        +			}
        +
        +		if (!ctx->finished)
        +			{
        +			ctx->finished=1;
        +			ctx->buf_off=0;
        +			ret=EVP_CipherFinal_ex(&(ctx->cipher),
        +				(unsigned char *)ctx->buf,
        +				&(ctx->buf_len));
        +			ctx->ok=(int)ret;
        +			if (ret <= 0) break;
        +
        +			/* push out the bytes */
        +			goto again;
        +			}
        +		
        +		/* Finally flush the underlying BIO */
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +	case BIO_C_GET_CIPHER_STATUS:
        +		ret=(long)ctx->ok;
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +
        +	case BIO_CTRL_DUP:
        +		dbio=(BIO *)ptr;
        +		dctx=(BIO_ENC_CTX *)dbio->ptr;
        +		memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher));
        +		dbio->init=1;
        +		break;
        +	default:
        +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long ber_callback_ctrl(BIO *b, int cmd, void *(*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);
        +	}
        +
        +/*
        +void BIO_set_cipher_ctx(b,c)
        +BIO *b;
        +EVP_CIPHER_ctx *c;
        +	{
        +	if (b == NULL) return;
        +
        +	if ((b->callback != NULL) &&
        +		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
        +		return;
        +
        +	b->init=1;
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
        +	
        +	if (b->callback != NULL)
        +		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
        +	}
        +*/
        +
        +void BIO_set_cipher(BIO *b, EVP_CIPHER *c, unsigned char *k, unsigned char *i,
        +	     int e)
        +	{
        +	BIO_ENC_CTX *ctx;
        +
        +	if (b == NULL) return;
        +
        +	if ((b->callback != NULL) &&
        +		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
        +		return;
        +
        +	b->init=1;
        +	ctx=(BIO_ENC_CTX *)b->ptr;
        +	EVP_CipherInit_ex(&(ctx->cipher),c,NULL,k,i,e);
        +	
        +	if (b->callback != NULL)
        +		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/bio_pk7.c b/vendor/openssl/openssl/crypto/pkcs7/bio_pk7.c
        new file mode 100644
        index 000000000..0fd31e730
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/bio_pk7.c
        @@ -0,0 +1,69 @@
        +/* bio_pk7.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/asn1.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/bio.h>
        +
        +#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS)
        +#include <memory.h>
        +#endif
        +#include <stdio.h>
        +
        +/* Streaming encode support for PKCS#7 */
        +
        +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) 
        +	{
        +	return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/dec.c b/vendor/openssl/openssl/crypto/pkcs7/dec.c
        new file mode 100644
        index 000000000..6752ec568
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/dec.c
        @@ -0,0 +1,248 @@
        +/* crypto/pkcs7/verify.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/bio.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/asn1.h>
        +
        +int verify_callback(int ok, X509_STORE_CTX *ctx);
        +
        +BIO *bio_err=NULL;
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	char *keyfile=NULL;
        +	BIO *in;
        +	EVP_PKEY *pkey;
        +	X509 *x509;
        +	PKCS7 *p7;
        +	PKCS7_SIGNER_INFO *si;
        +	X509_STORE_CTX cert_ctx;
        +	X509_STORE *cert_store=NULL;
        +	BIO *data,*detached=NULL,*p7bio=NULL;
        +	char buf[1024*4];
        +	unsigned char *pp;
        +	int i,printit=0;
        +	STACK_OF(PKCS7_SIGNER_INFO) *sk;
        +
        +	OpenSSL_add_all_algorithms();
        +	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	data=BIO_new(BIO_s_file());
        +	pp=NULL;
        +	while (argc > 1)
        +		{
        +		argc--;
        +		argv++;
        +		if (strcmp(argv[0],"-p") == 0)
        +			{
        +			printit=1;
        +			}
        +		else if ((strcmp(argv[0],"-k") == 0) && (argc >= 2)) {
        +			keyfile = argv[1];
        +			argc-=1;
        +			argv+=1;
        +		} else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
        +			{
        +			detached=BIO_new(BIO_s_file());
        +			if (!BIO_read_filename(detached,argv[1]))
        +				goto err;
        +			argc-=1;
        +			argv+=1;
        +			}
        +		else break;
        +		}
        +
        +	 if (!BIO_read_filename(data,argv[0])) goto err; 
        +
        +	if(!keyfile) {
        +		fprintf(stderr, "No private key file specified\n");
        +		goto err;
        +	}
        +
        +        if ((in=BIO_new_file(keyfile,"r")) == NULL) goto err;
        +        if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
        +        BIO_reset(in);
        +        if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL)
        +		goto err;
        +        BIO_free(in);
        +
        +	if (pp == NULL)
        +		BIO_set_fp(data,stdin,BIO_NOCLOSE);
        +
        +
        +	/* Load the PKCS7 object from a file */
        +	if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
        +
        +
        +
        +	/* This stuff is being setup for certificate verification.
        +	 * When using SSL, it could be replaced with a 
        +	 * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
        +	cert_store=X509_STORE_new();
        +	X509_STORE_set_default_paths(cert_store);
        +	X509_STORE_load_locations(cert_store,NULL,"../../certs");
        +	X509_STORE_set_verify_cb_func(cert_store,verify_callback);
        +
        +	ERR_clear_error();
        +
        +	/* We need to process the data */
        +	/* We cannot support detached encryption */
        +	p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
        +
        +	if (p7bio == NULL)
        +		{
        +		printf("problems decoding\n");
        +		goto err;
        +		}
        +
        +	/* We now have to 'read' from p7bio to calculate digests etc. */
        +	for (;;)
        +		{
        +		i=BIO_read(p7bio,buf,sizeof(buf));
        +		/* print it? */
        +		if (i <= 0) break;
        +		fwrite(buf,1, i, stdout);
        +		}
        +
        +	/* We can now verify signatures */
        +	sk=PKCS7_get_signer_info(p7);
        +	if (sk == NULL)
        +		{
        +		fprintf(stderr, "there are no signatures on this data\n");
        +		}
        +	else
        +		{
        +		/* Ok, first we need to, for each subject entry,
        +		 * see if we can verify */
        +		ERR_clear_error();
        +		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
        +			{
        +			si=sk_PKCS7_SIGNER_INFO_value(sk,i);
        +			i=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
        +			if (i <= 0)
        +				goto err;
        +			else
        +				fprintf(stderr,"Signature verified\n");
        +			}
        +		}
        +	X509_STORE_free(cert_store);
        +
        +	exit(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	exit(1);
        +	}
        +
        +/* should be X509 * but we can just have them as char *. */
        +int verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	char buf[256];
        +	X509 *err_cert;
        +	int err,depth;
        +
        +	err_cert=X509_STORE_CTX_get_current_cert(ctx);
        +	err=	X509_STORE_CTX_get_error(ctx);
        +	depth=	X509_STORE_CTX_get_error_depth(ctx);
        +
        +	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
        +	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
        +	if (!ok)
        +		{
        +		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
        +			X509_verify_cert_error_string(err));
        +		if (depth < 6)
        +			{
        +			ok=1;
        +			X509_STORE_CTX_set_error(ctx,X509_V_OK);
        +			}
        +		else
        +			{
        +			ok=0;
        +			X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
        +			}
        +		}
        +	switch (ctx->error)
        +		{
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
        +		BIO_printf(bio_err,"issuer= %s\n",buf);
        +		break;
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +		BIO_printf(bio_err,"notBefore=");
        +		ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +		BIO_printf(bio_err,"notAfter=");
        +		ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +		}
        +	BIO_printf(bio_err,"verify return:%d\n",ok);
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/des.pem b/vendor/openssl/openssl/crypto/pkcs7/des.pem
        new file mode 100644
        index 000000000..62d1657e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/des.pem
        @@ -0,0 +1,15 @@
        +
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR+MA0GCSqGSIb3DQEBAQUABEC2vXI1xQDW6lUHM3zQ
        +/9uBEBOO5A3TtkrklAXq7v01gsIC21t52qSk36REXY+slhNZ0OQ349tgkTsoETHFLoEwMIHw
        +AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
        +QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR9MA0G
        +CSqGSIb3DQEBAQUABEB8ujxbabxXUYJhopuDm3oDq4JNqX6Io4p3ro+ShqfIndsXTZ1v5a2N
        +WtLLCWlHn/habjBwZ/DgQgcKASbZ7QxNMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
        +oAQIbsL5v1wX98KggAQoAaJ4WHm68fXY1WE5OIjfVBIDpO1K+i8dmKhjnAjrjoyZ9Bwc8rDL
        +lgQg4CXb805h5xl+GfvSwUaHJayte1m2mcOhs3J2YyqbQ+MEIMIiJQccmhO3oDKm36CFvYR8
        +5PjpclVcZyX2ngbwPFMnBAgy0clOAE6UKAAAAAAAAAAAAAA=
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/doc b/vendor/openssl/openssl/crypto/pkcs7/doc
        new file mode 100644
        index 000000000..d2e8b7b2a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/doc
        @@ -0,0 +1,24 @@
        +int PKCS7_set_content_type(PKCS7 *p7, int type);
        +Call to set the type of PKCS7 object we are working on
        +
        +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
        +	EVP_MD *dgst);
        +Use this to setup a signer info
        +There will also be functions to add signed and unsigned attributes.
        +
        +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
        +Add a signer info to the content.
        +
        +int PKCS7_add_certificae(PKCS7 *p7, X509 *x509);
        +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
        +
        +----
        +
        +p7=PKCS7_new();
        +PKCS7_set_content_type(p7,NID_pkcs7_signed);
        +
        +signer=PKCS7_SINGNER_INFO_new();
        +PKCS7_SIGNER_INFO_set(signer,x509,pkey,EVP_md5());
        +PKCS7_add_signer(py,signer);
        +
        +we are now setup.
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/enc.c b/vendor/openssl/openssl/crypto/pkcs7/enc.c
        new file mode 100644
        index 000000000..7417f8a4e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/enc.c
        @@ -0,0 +1,174 @@
        +/* crypto/pkcs7/enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/bio.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	X509 *x509;
        +	PKCS7 *p7;
        +	BIO *in;
        +	BIO *data,*p7bio;
        +	char buf[1024*4];
        +	int i;
        +	int nodetach=1;
        +	char *keyfile = NULL;
        +	const EVP_CIPHER *cipher=NULL;
        +	STACK_OF(X509) *recips=NULL;
        +
        +	OpenSSL_add_all_algorithms();
        +
        +	data=BIO_new(BIO_s_file());
        +	while(argc > 1)
        +		{
        +		if (strcmp(argv[1],"-nd") == 0)
        +			{
        +			nodetach=1;
        +			argv++; argc--;
        +			}
        +		else if ((strcmp(argv[1],"-c") == 0) && (argc >= 2)) {
        +			if(!(cipher = EVP_get_cipherbyname(argv[2]))) {
        +				fprintf(stderr, "Unknown cipher %s\n", argv[2]);
        +				goto err;
        +			}
        +			argc-=2;
        +			argv+=2;
        +		} else if ((strcmp(argv[1],"-k") == 0) && (argc >= 2)) {
        +			keyfile = argv[2];
        +			argc-=2;
        +			argv+=2;
        +			if (!(in=BIO_new_file(keyfile,"r"))) goto err;
        +			if (!(x509=PEM_read_bio_X509(in,NULL,NULL,NULL)))
        +				goto err;
        +			if(!recips) recips = sk_X509_new_null();
        +			sk_X509_push(recips, x509);
        +			BIO_free(in);
        +		} else break;
        +	}
        +
        +	if(!recips) {
        +		fprintf(stderr, "No recipients\n");
        +		goto err;
        +	}
        +
        +	if (!BIO_read_filename(data,argv[1])) goto err;
        +
        +	p7=PKCS7_new();
        +#if 0
        +	BIO_reset(in);
        +	if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL)) == NULL) goto err;
        +	BIO_free(in);
        +	PKCS7_set_type(p7,NID_pkcs7_signedAndEnveloped);
        +	 
        +	if (PKCS7_add_signature(p7,x509,pkey,EVP_sha1()) == NULL) goto err;
        +	/* we may want to add more */
        +	PKCS7_add_certificate(p7,x509);
        +#else
        +	PKCS7_set_type(p7,NID_pkcs7_enveloped);
        +#endif
        +	if(!cipher)	{
        +#ifndef OPENSSL_NO_DES
        +		cipher = EVP_des_ede3_cbc();
        +#else
        +		fprintf(stderr, "No cipher selected\n");
        +		goto err;
        +#endif
        +	}
        +
        +	if (!PKCS7_set_cipher(p7,cipher)) goto err;
        +	for(i = 0; i < sk_X509_num(recips); i++) {
        +		if (!PKCS7_add_recipient(p7,sk_X509_value(recips, i))) goto err;
        +	}
        +	sk_X509_pop_free(recips, X509_free);
        +
        +	/* Set the content of the signed to 'data' */
        +	/* PKCS7_content_new(p7,NID_pkcs7_data); not used in envelope */
        +
        +	/* could be used, but not in this version :-)
        +	if (!nodetach) PKCS7_set_detached(p7,1);
        +	*/
        +
        +	if ((p7bio=PKCS7_dataInit(p7,NULL)) == NULL) goto err;
        +
        +	for (;;)
        +		{
        +		i=BIO_read(data,buf,sizeof(buf));
        +		if (i <= 0) break;
        +		BIO_write(p7bio,buf,i);
        +		}
        +	BIO_flush(p7bio);
        +
        +	if (!PKCS7_dataFinal(p7,p7bio)) goto err;
        +	BIO_free(p7bio);
        +
        +	PEM_write_PKCS7(stdout,p7);
        +	PKCS7_free(p7);
        +
        +	exit(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	exit(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/es1.pem b/vendor/openssl/openssl/crypto/pkcs7/es1.pem
        new file mode 100644
        index 000000000..47112a238
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/es1.pem
        @@ -0,0 +1,66 @@
        +-----BEGIN PKCS7-----
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqGSIb3DQEBAQUABEDWak0y/5XZJhQJeCLo
        +KECcHXkTEbjzYkYNHIinbiPmRK4QbNfs9z2mA3z/c2ykQ4eAqFR2jyNrUMN/+I5XEiv6MIHw
        +AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
        +QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR9MA0G
        +CSqGSIb3DQEBAQUABEAWg9+KgtCjc77Jdj1Ve4wGgHjVHbbSYEA1ZqKFDoi15vSr9hfpHmC4
        +ycZzcRo16JkTfolefiHZzmyjVz94vSN6MIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
        +oAQI7X4Tk4mcbV6ggASBsHl1mCaJ3RhXWlNPCgCRU53d7M5x6TDZRkvwdtdvW96m1lupT03F
        +XtonkBqk7oMkH7kGfs5/REQOPjx0QE2Ixmgt1W3szum82EZwA7pZNppcraK7W/odw/7bYZO+
        +II3HPmRklE2N9qiu1LPaPUsnYogkO6SennyeL5tZ382vBweL/8pnG0qsbT1OBb65v+llnsjT
        +pa1T/p+fIx/iJJGE6K9fYFokC6gXLQ6ozXRdOu5oBDB8mPCYYvAqKycidM/MrGGUkpEtS4f0
        +lS31PwQi5YTim8Ig3/TOwVpPX32i46FTuEIEIMHkD/OvpfwCCzXUHHJnKnKUAUvIsSY3vGBs
        +8ezpUDfBBBj9LHDy32hZ2tQilkDefP5VM2LLdrWgamYEgfiyITQvn08Ul5lQOQxbFKBheFq5
        +otCCN4MR+w5eq12xQu6y+f9z0159ag2ru87D0lLtUtXXtCELbO1nUkT2sJ0k/iDs9TOXr6Cx
        +go1XKYho83hlkXYiCteVizdAbgVGNsNRD4wtIdajsorET/LuJECgp11YeL9w1dlDB0HLEZfi
        +XCsUphH4jGagba3hDeUSibnjSiJlN0ukfuQurBBbI2UkBAujiEAubKPn7C1FZJRSw6CPPX5t
        +KEpmcqT1JNk6LO8Js6/1sCmmBh1VGCy1+EuTI9J1p7Dagf4nQ8cHitoCRpHuKZlFHnZyv7tw
        +Rn/KOhHaYP2VzAh40gQIvKMAAWh9oFsEEIMwIoOmLwLH5wf+8QdbDhoECH8HwZt9a12dBAjL
        +r4j2zlvtfgQIt7nmEM3wz1EECKlc3EIy1irCBBCAKINcermK3A+jI6ISN2RzBFA3dsh/xwMu
        +l61aWMBBZzEz/SF92k6n35KZhCC0d6fIVC/1WMv0fnCwQ8oEDynSre216VEFiYKBaQLJe5o/
        +mTAxC7Ht3goXnuc+i1FItOkLrgRI/wyvTICEn2WsNZiMADnGaee2bqPnUopo+VMGexJEtCPk
        +l0ZNlDJGquPDkpUwaEtecVZzCNyVPYyyF4J/l8rmGDhDdYUIC8IKBEg/ip/E0BuubBLWVbv+
        +HRl4QrnGpyCyeXRXXK603QP3sT1Zbbm1v5pI/loOhVHi724LmtXHSyp5qv9MDcxE1PoX10LY
        +gBRtlwwESPeCF8bK5jk4xIQMhK5NMHj1Y1KQWTZ9NGITBL4hjRq2qp4Qk5GIpGgOVPopAuCo
        +TIyPikpqBRNtLSPRSsDs6QPUPzWBh6JgxwRQblnDKKUkxUcnJiD4i9QtGa/ZabMn4KxtNOBL
        +5JSh1nJkaLXCZY070131WWPAByLcd5TiXq8x84pmzV5NNk4tiMpoXhJNsx8e4rskQQlKd6ME
        +SCe2eYDHKcKPX3WJbUzhrJSQ92/aWnI2iUY8WQ+kSNyiZ2QUjyuUg9Z66g/0d2STlvPOBHT/
        +y5ODP2CwbcWX4QmCbUc9TT66fQRIrRVuwvtOfnUueyGgYhJ3HpAJfVaB/7kap5bj7Fi/azW4
        +9JDfd1bC/W9h0Kyk7RO2gxvE0hIHc26mZJHTm9MNP5D328MnM2MdBEjKjQBtgrp+lFIii7MP
        +nGHFTKUkG4WAIZJCf/CsT+p6/SW0qG71Me/YcSw5STB24j+a+HgMV8RVIeUlkP4z0IWWrSoB
        +Gh4d/Z0EUMCVHs/HZ/bWgiyhtHpvuVAzidm8D81p1LJ5BQX5/5f/m+q5+fS/npL27dTEbNqs
        +LSB6ij3MZAi7LwHWpTn9zWnDajCMEj9vlaV7mcKtHK5iBEg85agFi1h3MvicqLtoFe5hVv9T
        +tG0j6CRkjkixPzivltlrf44KHv14gLM0XJxCGyq7vd3l8QYr3+9at0zNnX/yqTiBnsnE5dUE
        +SIgrYuz87M2gi/ER9PcDoTtONH3+CkcqVy03q/Sj8cVWD/b1KgEhqnNOfc8Ak9PctyR/ItcR
        +8Me5XVn1GJKkQJk4O29fxvgNoAQIrIESvUWGshAEQByXiFoFTDUByjTlgjcy77H1lrH+y3P/
        +wAInJjJAut9kCNyGJV0PA4kdPB5USWltuO6t8gk4Pd2YBMl09zqUWkAEUCjFrtZ3mapjcGZI
        +uQTASKR5LSjXoWxTT5gae/+64MerF/oCEeO3ehRTpjnPrsiRDo0rWIQTaj9+Nro8Z2xtWstw
        +RnfoAHIxV1lEamPwjsceBEi2SD9hiifFeO5ECiVoaE1FdXUXhU+jwYAMx6jHWO9hMkYzS9pM
        +Y3IyWR5ybtOjiQgkUdvRJPUPGf5DVVMPnymGX25aDh5PYpIESPbsM9akCpOOVuscywcUswmU
        +o7dXvlB48WWCfg/al3BQKAZbn5ZXtWNwpUZkrEdHsrxAVv3rxRcdkT3Z1fzUbIuYkLJN200o
        +WgRIJvn6RO8KEj7/HOg2sYuuM8nz1kR0TSgwX7/0y/7JfjBa0JIlP7o75sNJscE8oyoIMzuy
        +Dvn6/U9g3BCDXn83A/s+ke60qn9gBFC6NAeLOlXal1YVWYhMQNOqCyUfAjiXBTawaysQb1Mk
        +YgeNlF8xuEFcUQWIP+vNG7FJ5JPMaMRL4YEoaQ3sVFhYOERJR1cSb+8xt4QCYtBKQgRIUOmJ
        +CHW5o1hXJWJiTkZK2qWFcEMzTINSj5EpYFySr8aVBjkRnI7vxegRT/+XZZXoYedQ3UNsnGI3
        +DdkWii5VzX0PNF6C60pfBEiVpausYuX7Wjb3Lfm8cBj7GgN69i6Pm2gxtobVcmpo2nS4D714
        +ePyhlX9n8kJ6QAcqWMRj22smDPrHVGNTizfzHBh5zNllK9gESJizILOWI327og3ZWp+qUht5
        +kNDJCzMK7Z09UAy+h+vq0VTQuEo3FgLzVdqkJujjSL4Nx97lXg51AovrEn3nd4evydwcjKLX
        +1wRIo72NaeWuUEQ+rt1SlCsOJ7k1ioJSqhrPOfvwcaFcb4beVet1JWiy4yvowTjLDGbUje2s
        +xjrlVt4BJWI/uA6jbQsrxSe89ADZBAi5YAlR4qszeAQIXD3VSBVKbRUECNTtyvw9vvqXBAhb
        +IZNn4H4cxgQI+XW7GkfL+ekECCCCg2reMyGDBAh1PYqkg3lw3gQQkNlggEPU+BH8eh7Gm7n7
        +7AQIjC5EWbkil5cEEKcpuqwTWww/X89KnQAg8TcECJPomqHvrlZFBBiRSuIiHpmN+PaujXpv
        +qZV2VhjkB2j09GEECOIdv8AVOJgKBAjlHgIqAD9jZQQIXHbs44+wogcEIGGqTACRJxrhMcMG
        +X8drNjksIPt+snxTXUBIkTVpZWoABAh6unXPTyIr8QQgBF8xKoX27MWk7iTNmkSNZggZXa2a
        +DWCGHSYLngbSOHIECD9XmO6VsvTgBAjfqB70CEW4WwQIVIBkbCocznUEEHB/zFXy/sR4OYHe
        +UfbNPnIEEDWBB/NTCLMGE+o8BfyujcAECFik7GQnnF9VBBAhLXExQeWAofZNc6NtN7qZBCC1
        +gVIS3ruTwKltmcrgx3heT3M8ZJhCfWa+6KzchnmKygQQ+1NL5sSzR4m/fdrqxHFyUAQYCT2x
        +PamQr3wK3h0lyZER+4H0zPM86AhFBBC3CkmvL2vjflMfujnzPBVpBBge9rMbI5+0q9DLrTiT
        +5F3AIgXLpD8PQWAECHkHVo6RomV3BAgMbi8E271UeAQIqtS8wnI3XngECG3TWmOMb3/iBEha
        +y+mvCS6I3n3JfL8e1B5P4qX9/czJRaERLuKpGNjLiL4A+zxN0LZ0UHd0qfmJjwOTxAx3iJAC
        +lGXX4nB9ATYPUT5EU+o1Y4sECN01pP6vWNIdBDAsiE0Ts8/9ltJlqX2B3AoOM4qOt9EaCjXf
        +lB+aEmrhtjUwuZ6GqS5Ke7P6XnakTk4ECCLIMatNdootAAAAAAAAAAAAAA==
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/example.c b/vendor/openssl/openssl/crypto/pkcs7/example.c
        new file mode 100644
        index 000000000..2953d04b5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/example.c
        @@ -0,0 +1,329 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/asn1_mac.h>
        +#include <openssl/x509.h>
        +
        +int add_signed_time(PKCS7_SIGNER_INFO *si)
        +	{
        +	ASN1_UTCTIME *sign_time;
        +
        +	/* The last parameter is the amount to add/subtract from the current
        +	 * time (in seconds) */
        +	sign_time=X509_gmtime_adj(NULL,0);
        +	PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime,
        +		V_ASN1_UTCTIME,(char *)sign_time);
        +	return(1);
        +	}
        +
        +ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
        +	{
        +	ASN1_TYPE *so;
        +
        +	so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
        +	if (so->type == V_ASN1_UTCTIME)
        +	    return so->value.utctime;
        +	return NULL;
        +	}
        +	
        +static int signed_string_nid= -1;
        +
        +void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
        +	{
        +	ASN1_OCTET_STRING *os;
        +
        +	/* To a an object of OID 1.2.3.4.5, which is an octet string */
        +	if (signed_string_nid == -1)
        +		signed_string_nid=
        +			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
        +	os=ASN1_OCTET_STRING_new();
        +	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
        +	/* When we add, we do not free */
        +	PKCS7_add_signed_attribute(si,signed_string_nid,
        +		V_ASN1_OCTET_STRING,(char *)os);
        +	}
        +
        +int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
        +	{
        +	ASN1_TYPE *so;
        +	ASN1_OCTET_STRING *os;
        +	int i;
        +
        +	if (signed_string_nid == -1)
        +		signed_string_nid=
        +			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
        +	/* To retrieve */
        +	so=PKCS7_get_signed_attribute(si,signed_string_nid);
        +	if (so != NULL)
        +		{
        +		if (so->type == V_ASN1_OCTET_STRING)
        +			{
        +			os=so->value.octet_string;
        +			i=os->length;
        +			if ((i+1) > len)
        +				i=len-1;
        +			memcpy(buf,os->data,i);
        +			return(i);
        +			}
        +		}
        +	return(0);
        +	}
        +
        +static int signed_seq2string_nid= -1;
        +/* ########################################### */
        +int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
        +	{
        +	/* To add an object of OID 1.9.999, which is a sequence containing
        +	 * 2 octet strings */
        +	unsigned char *p;
        +	ASN1_OCTET_STRING *os1,*os2;
        +	ASN1_STRING *seq;
        +	unsigned char *data;
        +	int i,total;
        +
        +	if (signed_seq2string_nid == -1)
        +		signed_seq2string_nid=
        +			OBJ_create("1.9.9999","OID_example","Our example OID");
        +
        +	os1=ASN1_OCTET_STRING_new();
        +	os2=ASN1_OCTET_STRING_new();
        +	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
        +	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
        +	i =i2d_ASN1_OCTET_STRING(os1,NULL);
        +	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
        +	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
        +
        +	data=malloc(total);
        +	p=data;
        +	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
        +	i2d_ASN1_OCTET_STRING(os1,&p);
        +	i2d_ASN1_OCTET_STRING(os2,&p);
        +
        +	seq=ASN1_STRING_new();
        +	ASN1_STRING_set(seq,data,total);
        +	free(data);
        +	ASN1_OCTET_STRING_free(os1);
        +	ASN1_OCTET_STRING_free(os2);
        +
        +	PKCS7_add_signed_attribute(si,signed_seq2string_nid,
        +		V_ASN1_SEQUENCE,(char *)seq);
        +	return(1);
        +	}
        +
        +/* For this case, I will malloc the return strings */
        +int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
        +	{
        +	ASN1_TYPE *so;
        +
        +	if (signed_seq2string_nid == -1)
        +		signed_seq2string_nid=
        +			OBJ_create("1.9.9999","OID_example","Our example OID");
        +	/* To retrieve */
        +	so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
        +	if (so && (so->type == V_ASN1_SEQUENCE))
        +		{
        +		ASN1_const_CTX c;
        +		ASN1_STRING *s;
        +		long length;
        +		ASN1_OCTET_STRING *os1,*os2;
        +
        +		s=so->value.sequence;
        +		c.p=ASN1_STRING_data(s);
        +		c.max=c.p+ASN1_STRING_length(s);
        +		if (!asn1_GetSequence(&c,&length)) goto err;
        +		/* Length is the length of the seqence */
        +
        +		c.q=c.p;
        +		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
        +			goto err;
        +		c.slen-=(c.p-c.q);
        +
        +		c.q=c.p;
        +		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
        +			goto err;
        +		c.slen-=(c.p-c.q);
        +
        +		if (!asn1_const_Finish(&c)) goto err;
        +		*str1=malloc(os1->length+1);
        +		*str2=malloc(os2->length+1);
        +		memcpy(*str1,os1->data,os1->length);
        +		memcpy(*str2,os2->data,os2->length);
        +		(*str1)[os1->length]='\0';
        +		(*str2)[os2->length]='\0';
        +		ASN1_OCTET_STRING_free(os1);
        +		ASN1_OCTET_STRING_free(os2);
        +		return(1);
        +		}
        +err:
        +	return(0);
        +	}
        +
        +
        +/* #######################################
        + * THE OTHER WAY TO DO THINGS
        + * #######################################
        + */
        +X509_ATTRIBUTE *create_time(void)
        +	{
        +	ASN1_UTCTIME *sign_time;
        +	X509_ATTRIBUTE *ret;
        +
        +	/* The last parameter is the amount to add/subtract from the current
        +	 * time (in seconds) */
        +	sign_time=X509_gmtime_adj(NULL,0);
        +	ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime,
        +		V_ASN1_UTCTIME,(char *)sign_time);
        +	return(ret);
        +	}
        +
        +ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk)
        +	{
        +	ASN1_TYPE *so;
        +	PKCS7_SIGNER_INFO si;
        +
        +	si.auth_attr=sk;
        +	so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
        +	if (so->type == V_ASN1_UTCTIME)
        +	    return so->value.utctime;
        +	return NULL;
        +	}
        +	
        +X509_ATTRIBUTE *create_string(char *str)
        +	{
        +	ASN1_OCTET_STRING *os;
        +	X509_ATTRIBUTE *ret;
        +
        +	/* To a an object of OID 1.2.3.4.5, which is an octet string */
        +	if (signed_string_nid == -1)
        +		signed_string_nid=
        +			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
        +	os=ASN1_OCTET_STRING_new();
        +	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
        +	/* When we add, we do not free */
        +	ret=X509_ATTRIBUTE_create(signed_string_nid,
        +		V_ASN1_OCTET_STRING,(char *)os);
        +	return(ret);
        +	}
        +
        +int sk_get_string(STACK_OF(X509_ATTRIBUTE) *sk, char *buf, int len)
        +	{
        +	ASN1_TYPE *so;
        +	ASN1_OCTET_STRING *os;
        +	int i;
        +	PKCS7_SIGNER_INFO si;
        +
        +	si.auth_attr=sk;
        +
        +	if (signed_string_nid == -1)
        +		signed_string_nid=
        +			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
        +	/* To retrieve */
        +	so=PKCS7_get_signed_attribute(&si,signed_string_nid);
        +	if (so != NULL)
        +		{
        +		if (so->type == V_ASN1_OCTET_STRING)
        +			{
        +			os=so->value.octet_string;
        +			i=os->length;
        +			if ((i+1) > len)
        +				i=len-1;
        +			memcpy(buf,os->data,i);
        +			return(i);
        +			}
        +		}
        +	return(0);
        +	}
        +
        +X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
        +	{
        +	/* To add an object of OID 1.9.999, which is a sequence containing
        +	 * 2 octet strings */
        +	unsigned char *p;
        +	ASN1_OCTET_STRING *os1,*os2;
        +	ASN1_STRING *seq;
        +	X509_ATTRIBUTE *ret;
        +	unsigned char *data;
        +	int i,total;
        +
        +	if (signed_seq2string_nid == -1)
        +		signed_seq2string_nid=
        +			OBJ_create("1.9.9999","OID_example","Our example OID");
        +
        +	os1=ASN1_OCTET_STRING_new();
        +	os2=ASN1_OCTET_STRING_new();
        +	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
        +	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
        +	i =i2d_ASN1_OCTET_STRING(os1,NULL);
        +	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
        +	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
        +
        +	data=malloc(total);
        +	p=data;
        +	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
        +	i2d_ASN1_OCTET_STRING(os1,&p);
        +	i2d_ASN1_OCTET_STRING(os2,&p);
        +
        +	seq=ASN1_STRING_new();
        +	ASN1_STRING_set(seq,data,total);
        +	free(data);
        +	ASN1_OCTET_STRING_free(os1);
        +	ASN1_OCTET_STRING_free(os2);
        +
        +	ret=X509_ATTRIBUTE_create(signed_seq2string_nid,
        +		V_ASN1_SEQUENCE,(char *)seq);
        +	return(ret);
        +	}
        +
        +/* For this case, I will malloc the return strings */
        +int sk_get_seq2string(STACK_OF(X509_ATTRIBUTE) *sk, char **str1, char **str2)
        +	{
        +	ASN1_TYPE *so;
        +	PKCS7_SIGNER_INFO si;
        +
        +	if (signed_seq2string_nid == -1)
        +		signed_seq2string_nid=
        +			OBJ_create("1.9.9999","OID_example","Our example OID");
        +
        +	si.auth_attr=sk;
        +	/* To retrieve */
        +	so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid);
        +	if (so->type == V_ASN1_SEQUENCE)
        +		{
        +		ASN1_const_CTX c;
        +		ASN1_STRING *s;
        +		long length;
        +		ASN1_OCTET_STRING *os1,*os2;
        +
        +		s=so->value.sequence;
        +		c.p=ASN1_STRING_data(s);
        +		c.max=c.p+ASN1_STRING_length(s);
        +		if (!asn1_GetSequence(&c,&length)) goto err;
        +		/* Length is the length of the seqence */
        +
        +		c.q=c.p;
        +		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
        +			goto err;
        +		c.slen-=(c.p-c.q);
        +
        +		c.q=c.p;
        +		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) 
        +			goto err;
        +		c.slen-=(c.p-c.q);
        +
        +		if (!asn1_const_Finish(&c)) goto err;
        +		*str1=malloc(os1->length+1);
        +		*str2=malloc(os2->length+1);
        +		memcpy(*str1,os1->data,os1->length);
        +		memcpy(*str2,os2->data,os2->length);
        +		(*str1)[os1->length]='\0';
        +		(*str2)[os2->length]='\0';
        +		ASN1_OCTET_STRING_free(os1);
        +		ASN1_OCTET_STRING_free(os2);
        +		return(1);
        +		}
        +err:
        +	return(0);
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/example.h b/vendor/openssl/openssl/crypto/pkcs7/example.h
        new file mode 100644
        index 000000000..96167de18
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/example.h
        @@ -0,0 +1,57 @@
        +/* ====================================================================
        + * 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).
        + *
        + */
        +
        +int add_signed_time(PKCS7_SIGNER_INFO *si);
        +ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si);
        +int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2);
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/info.pem b/vendor/openssl/openssl/crypto/pkcs7/info.pem
        new file mode 100644
        index 000000000..989baf870
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/info.pem
        @@ -0,0 +1,57 @@
        +issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
        +subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
        +serial :047D
        +
        +Certificate:
        +    Data:
        +        Version: 3 (0x2)
        +        Serial Number: 1149 (0x47d)
        +        Signature Algorithm: md5withRSAEncryption
        +        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
        +        Validity
        +            Not Before: May 13 05:40:58 1998 GMT
        +            Not After : May 12 05:40:58 2000 GMT
        +        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +                Modulus:
        +                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
        +                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
        +                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
        +                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
        +                    e7:e7:0c:4d:0b
        +                Exponent: 65537 (0x10001)
        +        X509v3 extensions:
        +            Netscape Comment: 
        +                Generated with SSLeay
        +    Signature Algorithm: md5withRSAEncryption
        +        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
        +        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
        +        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
        +        50:74:ad:92:cb:4e:90:e5:fa:7d
        +
        +-----BEGIN CERTIFICATE-----
        +MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
        +MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
        +ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
        +IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
        +NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
        +aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
        +9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
        +lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
        +hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
        +UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
        +4A3ZItobUHStkstOkOX6fQ==
        +-----END CERTIFICATE-----
        +
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
        +mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
        +fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
        +zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
        +p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
        +bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
        +IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/infokey.pem b/vendor/openssl/openssl/crypto/pkcs7/infokey.pem
        new file mode 100644
        index 000000000..1e2acc954
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/infokey.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
        +mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
        +fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
        +zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
        +p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
        +bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
        +IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/p7/a1 b/vendor/openssl/openssl/crypto/pkcs7/p7/a1
        new file mode 100644
        index 000000000..56ca94376
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/p7/a1
        @@ -0,0 +1,2 @@
        +j,H>_æá_­DôzEîLœ	VJ³ß觬¤””E3ûáYäx%_Àk
        +3ê)DLScñ8%ôM
        \ No newline at end of file
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/p7/a2 b/vendor/openssl/openssl/crypto/pkcs7/p7/a2
        new file mode 100644
        index 000000000..23d8fb5e9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/p7/a2
        @@ -0,0 +1 @@
        +k~@a”,NâM͹¼	<O( KP—騠¤K²>­×U¿o_½BqrmÎ?Ù t?t÷ÏéId2‰Š
        \ No newline at end of file
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/p7/cert.p7c b/vendor/openssl/openssl/crypto/pkcs7/p7/cert.p7c
        new file mode 100644
        index 000000000..2b75ec05f
        Binary files /dev/null and b/vendor/openssl/openssl/crypto/pkcs7/p7/cert.p7c differ
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/p7/smime.p7m b/vendor/openssl/openssl/crypto/pkcs7/p7/smime.p7m
        new file mode 100644
        index 000000000..2b6e6f82b
        Binary files /dev/null and b/vendor/openssl/openssl/crypto/pkcs7/p7/smime.p7m differ
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/p7/smime.p7s b/vendor/openssl/openssl/crypto/pkcs7/p7/smime.p7s
        new file mode 100644
        index 000000000..2b5d4fb0e
        Binary files /dev/null and b/vendor/openssl/openssl/crypto/pkcs7/p7/smime.p7s differ
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_asn1.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_asn1.c
        new file mode 100644
        index 000000000..b7ec2883c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_asn1.c
        @@ -0,0 +1,247 @@
        +/* pk7_asn.c */
        +/* Written by Dr Stephen N Henson (steve@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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/x509.h>
        +
        +/* PKCS#7 ASN1 module */
        +
        +/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
        +
        +ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
        +
        +ASN1_ADB(PKCS7) = {
        +	ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)),
        +	ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
        +	ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
        +	ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
        +	ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
        +	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
        +} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
        +
        +/* PKCS#7 streaming support */
        +static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +{
        +	ASN1_STREAM_ARG *sarg = exarg;
        +	PKCS7 **pp7 = (PKCS7 **)pval;
        +
        +	switch(operation)
        +		{
        +
        +		case ASN1_OP_STREAM_PRE:
        +		if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
        +			return 0;
        +		case ASN1_OP_DETACHED_PRE:
        +		sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
        +		if (!sarg->ndef_bio)
        +			return 0;
        +		break;
        +
        +		case ASN1_OP_STREAM_POST:
        +		case ASN1_OP_DETACHED_POST:
        +		if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
        +			return 0;
        +		break;
        +
        +		}
        +	return 1;
        +}
        +
        +ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
        +	ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(PKCS7)
        +}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
        +IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
        +IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
        +
        +ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
        +	ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
        +	ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
        +	ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
        +	ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
        +	ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
        +	ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
        +} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
        +
        +/* Minor tweak to operation: free up EVP_PKEY */
        +static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +							void *exarg)
        +{
        +	if(operation == ASN1_OP_FREE_POST) {
        +		PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
        +		EVP_PKEY_free(si->pkey);
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = {
        +	ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
        +	ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
        +	/* NB this should be a SET OF but we use a SEQUENCE OF so the
        +	 * original order * is retained when the structure is reencoded.
        +	 * Since the attributes are implicitly tagged this will not affect
        +	 * the encoding.
        +	 */
        +	ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
        +	ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
        +	ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
        +	ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)
        +} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
        +
        +ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
        +	ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME),
        +	ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
        +
        +ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
        +	ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
        +	ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
        +	ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
        +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
        +
        +/* Minor tweak to operation: free up X509 */
        +static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +{
        +	if(operation == ASN1_OP_FREE_POST) {
        +		PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
        +		X509_free(ri->cert);
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
        +	ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
        +	ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR),
        +	ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
        +
        +ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
        +	ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
        +	ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
        +	ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
        +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
        +
        +ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
        +	ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
        +	ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
        +	ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
        +	ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT),
        +	ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
        +	ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
        +	ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
        +} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
        +
        +ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = {
        +	ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
        +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
        +
        +ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = {
        +	ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
        +	ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
        +	ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
        +} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
        +
        +/* Specials for authenticated attributes */
        +
        +/* When signing attributes we want to reorder them to match the sorted
        + * encoding.
        + */
        +
        +ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
        +ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN)
        +
        +/* When verifying attributes we need to use the received order. So 
        + * we use SEQUENCE OF and tag it to SET OF
        + */
        +
        +ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
        +				V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
        +ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
        +
        +IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_attr.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_attr.c
        new file mode 100644
        index 000000000..a97db5121
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_attr.c
        @@ -0,0 +1,165 @@
        +/* pk7_attr.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001-2004 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/bio.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/pem.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +
        +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
        +{
        +	ASN1_STRING *seq;
        +	if(!(seq = ASN1_STRING_new())) {
        +		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data,
        +				ASN1_ITEM_rptr(X509_ALGORS));
        +        return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
        +							V_ASN1_SEQUENCE, seq);
        +}
        +
        +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
        +	{
        +	ASN1_TYPE *cap;
        +	const unsigned char *p;
        +
        +	cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
        +	if (!cap || (cap->type != V_ASN1_SEQUENCE))
        +		return NULL;
        +	p = cap->value.sequence->data;
        +	return (STACK_OF(X509_ALGOR) *)
        +		ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
        +				ASN1_ITEM_rptr(X509_ALGORS));
        +	}
        +
        +/* Basic smime-capabilities OID and optional integer arg */
        +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
        +{
        +	X509_ALGOR *alg;
        +
        +	if(!(alg = X509_ALGOR_new())) {
        +		PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	ASN1_OBJECT_free(alg->algorithm);
        +	alg->algorithm = OBJ_nid2obj (nid);
        +	if (arg > 0) {
        +		ASN1_INTEGER *nbit;
        +		if(!(alg->parameter = ASN1_TYPE_new())) {
        +			PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		if(!(nbit = ASN1_INTEGER_new())) {
        +			PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		if(!ASN1_INTEGER_set (nbit, arg)) {
        +			PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		alg->parameter->value.integer = nbit;
        +		alg->parameter->type = V_ASN1_INTEGER;
        +	}
        +	sk_X509_ALGOR_push (sk, alg);
        +	return 1;
        +}
        +
        +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
        +	{
        +	if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
        +		return 0;
        +	if (!coid)
        +		coid = OBJ_nid2obj(NID_pkcs7_data);
        +	return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
        +				V_ASN1_OBJECT, coid);
        +	}
        +
        +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
        +	{
        +	if (!t && !(t=X509_gmtime_adj(NULL,0)))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
        +				ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
        +						V_ASN1_UTCTIME, t);
        +	}
        +
        +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
        +				const unsigned char *md, int mdlen)
        +	{
        +	ASN1_OCTET_STRING *os;
        +	os = ASN1_OCTET_STRING_new();
        +	if (!os)
        +		return 0;
        +	if (!ASN1_STRING_set(os, md, mdlen)
        +		|| !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
        +						V_ASN1_OCTET_STRING, os))
        +		{
        +		ASN1_OCTET_STRING_free(os);
        +		return 0;
        +		}
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_dgst.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_dgst.c
        new file mode 100644
        index 000000000..90edfa500
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_dgst.c
        @@ -0,0 +1,66 @@
        +/* crypto/pkcs7/pk7_dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_doit.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_doit.c
        new file mode 100644
        index 000000000..77fda3b82
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_doit.c
        @@ -0,0 +1,1299 @@
        +/* crypto/pkcs7/pk7_doit.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/err.h>
        +
        +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
        +			 void *value);
        +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
        +
        +static int PKCS7_type_is_other(PKCS7* p7)
        +	{
        +	int isOther=1;
        +	
        +	int nid=OBJ_obj2nid(p7->type);
        +
        +	switch( nid )
        +		{
        +	case NID_pkcs7_data:
        +	case NID_pkcs7_signed:
        +	case NID_pkcs7_enveloped:
        +	case NID_pkcs7_signedAndEnveloped:
        +	case NID_pkcs7_digest:
        +	case NID_pkcs7_encrypted:
        +		isOther=0;
        +		break;
        +	default:
        +		isOther=1;
        +		}
        +
        +	return isOther;
        +
        +	}
        +
        +static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
        +	{
        +	if ( PKCS7_type_is_data(p7))
        +		return p7->d.data;
        +	if ( PKCS7_type_is_other(p7) && p7->d.other
        +		&& (p7->d.other->type == V_ASN1_OCTET_STRING))
        +		return p7->d.other->value.octet_string;
        +	return NULL;
        +	}
        +
        +static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
        +	{
        +	BIO *btmp;
        +	const EVP_MD *md;
        +	if ((btmp=BIO_new(BIO_f_md())) == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
        +		goto err;
        +		}
        +
        +	md=EVP_get_digestbyobj(alg->algorithm);
        +	if (md == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE);
        +		goto err;
        +		}
        +
        +	BIO_set_md(btmp,md);
        +	if (*pbio == NULL)
        +		*pbio=btmp;
        +	else if (!BIO_push(*pbio,btmp))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
        +		goto err;
        +		}
        +	btmp=NULL;
        +
        +	return 1;
        +
        +	err:
        +	if (btmp)
        +		BIO_free(btmp);
        +	return 0;
        +
        +	}
        +
        +static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
        +					unsigned char *key, int keylen)
        +	{
        +	EVP_PKEY_CTX *pctx = NULL;
        +	EVP_PKEY *pkey = NULL;
        +	unsigned char *ek = NULL;
        +	int ret = 0;
        +	size_t eklen;
        +
        +	pkey = X509_get_pubkey(ri->cert);
        +
        +	if (!pkey)
        +		return 0;
        +
        +	pctx = EVP_PKEY_CTX_new(pkey, NULL);
        +	if (!pctx)
        +		return 0;
        +
        +	if (EVP_PKEY_encrypt_init(pctx) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
        +				EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
        +		goto err;
        +
        +	ek = OPENSSL_malloc(eklen);
        +
        +	if (ek == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
        +		goto err;
        +
        +	ASN1_STRING_set0(ri->enc_key, ek, eklen);
        +	ek = NULL;
        +
        +	ret = 1;
        +
        +	err:
        +	if (pkey)
        +		EVP_PKEY_free(pkey);
        +	if (pctx)
        +		EVP_PKEY_CTX_free(pctx);
        +	if (ek)
        +		OPENSSL_free(ek);
        +	return ret;
        +
        +	}
        +
        +
        +static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
        +			       PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
        +	{
        +	EVP_PKEY_CTX *pctx = NULL;
        +	unsigned char *ek = NULL;
        +	size_t eklen;
        +
        +	int ret = -1;
        +
        +	pctx = EVP_PKEY_CTX_new(pkey, NULL);
        +	if (!pctx)
        +		return -1;
        +
        +	if (EVP_PKEY_decrypt_init(pctx) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
        +				EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
        +				ri->enc_key->data, ri->enc_key->length) <= 0)
        +		goto err;
        +
        +	ek = OPENSSL_malloc(eklen);
        +
        +	if (ek == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
        +				ri->enc_key->data, ri->enc_key->length) <= 0)
        +		{
        +		ret = 0;
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +
        +	if (*pek)
        +		{
        +		OPENSSL_cleanse(*pek, *peklen);
        +		OPENSSL_free(*pek);
        +		}
        +
        +	*pek = ek;
        +	*peklen = eklen;
        +
        +	err:
        +	if (pctx)
        +		EVP_PKEY_CTX_free(pctx);
        +	if (!ret && ek)
        +		OPENSSL_free(ek);
        +
        +	return ret;
        +	}
        +
        +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
        +	{
        +	int i;
        +	BIO *out=NULL,*btmp=NULL;
        +	X509_ALGOR *xa = NULL;
        +	const EVP_CIPHER *evp_cipher=NULL;
        +	STACK_OF(X509_ALGOR) *md_sk=NULL;
        +	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
        +	X509_ALGOR *xalg=NULL;
        +	PKCS7_RECIP_INFO *ri=NULL;
        +	ASN1_OCTET_STRING *os=NULL;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	p7->state=PKCS7_S_HEADER;
        +
        +	switch (i)
        +		{
        +	case NID_pkcs7_signed:
        +		md_sk=p7->d.sign->md_algs;
        +		os = PKCS7_get_octet_string(p7->d.sign->contents);
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		rsk=p7->d.signed_and_enveloped->recipientinfo;
        +		md_sk=p7->d.signed_and_enveloped->md_algs;
        +		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
        +		evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
        +		if (evp_cipher == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
        +						PKCS7_R_CIPHER_NOT_INITIALIZED);
        +			goto err;
        +			}
        +		break;
        +	case NID_pkcs7_enveloped:
        +		rsk=p7->d.enveloped->recipientinfo;
        +		xalg=p7->d.enveloped->enc_data->algorithm;
        +		evp_cipher=p7->d.enveloped->enc_data->cipher;
        +		if (evp_cipher == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
        +						PKCS7_R_CIPHER_NOT_INITIALIZED);
        +			goto err;
        +			}
        +		break;
        +	case NID_pkcs7_digest:
        +		xa = p7->d.digest->md;
        +		os = PKCS7_get_octet_string(p7->d.digest->contents);
        +		break;
        +	case NID_pkcs7_data:
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        +	        goto err;
        +		}
        +
        +	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
        +		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
        +			goto err;
        +
        +	if (xa && !PKCS7_bio_add_digest(&out, xa))
        +			goto err;
        +
        +	if (evp_cipher != NULL)
        +		{
        +		unsigned char key[EVP_MAX_KEY_LENGTH];
        +		unsigned char iv[EVP_MAX_IV_LENGTH];
        +		int keylen,ivlen;
        +		EVP_CIPHER_CTX *ctx;
        +
        +		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
        +			goto err;
        +			}
        +		BIO_get_cipher_ctx(btmp, &ctx);
        +		keylen=EVP_CIPHER_key_length(evp_cipher);
        +		ivlen=EVP_CIPHER_iv_length(evp_cipher);
        +		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
        +		if (ivlen > 0)
        +			if (RAND_pseudo_bytes(iv,ivlen) <= 0)
        +				goto err;
        +		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
        +			goto err;
        +		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
        +			goto err;
        +		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
        +			goto err;
        +
        +		if (ivlen > 0) {
        +			if (xalg->parameter == NULL) {
        +				xalg->parameter = ASN1_TYPE_new();
        +				if (xalg->parameter == NULL)
        +					goto err;
        +			}
        +			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
        +				goto err;
        +		}
        +
        +		/* Lets do the pub key stuff :-) */
        +		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
        +			{
        +			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
        +			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
        +				goto err;
        +			}
        +		OPENSSL_cleanse(key, keylen);
        +
        +		if (out == NULL)
        +			out=btmp;
        +		else
        +			BIO_push(out,btmp);
        +		btmp=NULL;
        +		}
        +
        +	if (bio == NULL)
        +		{
        +		if (PKCS7_is_detached(p7))
        +			bio=BIO_new(BIO_s_null());
        +		else if (os && os->length > 0)
        +			bio = BIO_new_mem_buf(os->data, os->length);
        +		if(bio == NULL)
        +			{
        +			bio=BIO_new(BIO_s_mem());
        +			if (bio == NULL)
        +				goto err;
        +			BIO_set_mem_eof_return(bio,0);
        +			}
        +		}
        +	if (out)
        +		BIO_push(out,bio);
        +	else
        +		out = bio;
        +	bio=NULL;
        +	if (0)
        +		{
        +err:
        +		if (out != NULL)
        +			BIO_free_all(out);
        +		if (btmp != NULL)
        +			BIO_free_all(btmp);
        +		out=NULL;
        +		}
        +	return(out);
        +	}
        +
        +static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
        +	{
        +	int ret;
        +	ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
        +				pcert->cert_info->issuer);
        +	if (ret)
        +		return ret;
        +	return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
        +					ri->issuer_and_serial->serial);
        +	}
        +
        +/* int */
        +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
        +	{
        +	int i,j;
        +	BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
        +	X509_ALGOR *xa;
        +	ASN1_OCTET_STRING *data_body=NULL;
        +	const EVP_MD *evp_md;
        +	const EVP_CIPHER *evp_cipher=NULL;
        +	EVP_CIPHER_CTX *evp_ctx=NULL;
        +	X509_ALGOR *enc_alg=NULL;
        +	STACK_OF(X509_ALGOR) *md_sk=NULL;
        +	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
        +	PKCS7_RECIP_INFO *ri=NULL;
        +       unsigned char *ek = NULL, *tkey = NULL;
        +       int eklen = 0, tkeylen = 0;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	p7->state=PKCS7_S_HEADER;
        +
        +	switch (i)
        +		{
        +	case NID_pkcs7_signed:
        +		data_body=PKCS7_get_octet_string(p7->d.sign->contents);
        +		md_sk=p7->d.sign->md_algs;
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		rsk=p7->d.signed_and_enveloped->recipientinfo;
        +		md_sk=p7->d.signed_and_enveloped->md_algs;
        +		data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
        +		enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
        +		evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
        +		if (evp_cipher == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
        +			goto err;
        +			}
        +		break;
        +	case NID_pkcs7_enveloped:
        +		rsk=p7->d.enveloped->recipientinfo;
        +		enc_alg=p7->d.enveloped->enc_data->algorithm;
        +		data_body=p7->d.enveloped->enc_data->enc_data;
        +		evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
        +		if (evp_cipher == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
        +			goto err;
        +			}
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        +	        goto err;
        +		}
        +
        +	/* We will be checking the signature */
        +	if (md_sk != NULL)
        +		{
        +		for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
        +			{
        +			xa=sk_X509_ALGOR_value(md_sk,i);
        +			if ((btmp=BIO_new(BIO_f_md())) == NULL)
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
        +				goto err;
        +				}
        +
        +			j=OBJ_obj2nid(xa->algorithm);
        +			evp_md=EVP_get_digestbynid(j);
        +			if (evp_md == NULL)
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
        +				goto err;
        +				}
        +
        +			BIO_set_md(btmp,evp_md);
        +			if (out == NULL)
        +				out=btmp;
        +			else
        +				BIO_push(out,btmp);
        +			btmp=NULL;
        +			}
        +		}
        +
        +	if (evp_cipher != NULL)
        +		{
        +#if 0
        +		unsigned char key[EVP_MAX_KEY_LENGTH];
        +		unsigned char iv[EVP_MAX_IV_LENGTH];
        +		unsigned char *p;
        +		int keylen,ivlen;
        +		int max;
        +		X509_OBJECT ret;
        +#endif
        +
        +		if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
        +			goto err;
        +			}
        +
        +		/* It was encrypted, we need to decrypt the secret key
        +		 * with the private key */
        +
        +		/* Find the recipientInfo which matches the passed certificate
        +		 * (if any)
        +		 */
        +
        +		if (pcert)
        +			{
        +			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
        +				{
        +				ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
        +				if (!pkcs7_cmp_ri(ri, pcert))
        +					break;
        +				ri=NULL;
        +				}
        +			if (ri == NULL)
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
        +				      PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
        +				goto err;
        +				}
        +			}
        +
        +		/* If we haven't got a certificate try each ri in turn */
        +		if (pcert == NULL)
        +			{
        +			/* Always attempt to decrypt all rinfo even
        +			 * after sucess as a defence against MMA timing
        +			 * attacks.
        +			 */
        +			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
        +				{
        +				ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
        +				
        +				if (pkcs7_decrypt_rinfo(&ek, &eklen,
        +							ri, pkey) < 0)
        +					goto err;
        +				ERR_clear_error();
        +				}
        +			}
        +		else
        +			{
        +			/* Only exit on fatal errors, not decrypt failure */
        +			if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
        +				goto err;
        +			ERR_clear_error();
        +			}
        +
        +		evp_ctx=NULL;
        +		BIO_get_cipher_ctx(etmp,&evp_ctx);
        +		if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
        +			goto err;
        +		if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
        +			goto err;
        +		/* Generate random key as MMA defence */
        +		tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
        +		tkey = OPENSSL_malloc(tkeylen);
        +		if (!tkey)
        +			goto err;
        +		if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
        +			goto err;
        +		if (ek == NULL)
        +			{
        +			ek = tkey;
        +			eklen = tkeylen;
        +			tkey = NULL;
        +			}
        +
        +		if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
        +			/* Some S/MIME clients don't use the same key
        +			 * and effective key length. The key length is
        +			 * determined by the size of the decrypted RSA key.
        +			 */
        +			if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
        +				{
        +				/* Use random key as MMA defence */
        +				OPENSSL_cleanse(ek, eklen);
        +				OPENSSL_free(ek);
        +				ek = tkey;
        +				eklen = tkeylen;
        +				tkey = NULL;
        +				}
        +		} 
        +		/* Clear errors so we don't leak information useful in MMA */
        +		ERR_clear_error();
        +		if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
        +			goto err;
        +
        +		if (ek)
        +			{
        +			OPENSSL_cleanse(ek,eklen);
        +			OPENSSL_free(ek);
        +                       ek = NULL;
        +			}
        +		if (tkey)
        +			{
        +			OPENSSL_cleanse(tkey,tkeylen);
        +			OPENSSL_free(tkey);
        +                       tkey = NULL;
        +			}
        +
        +		if (out == NULL)
        +			out=etmp;
        +		else
        +			BIO_push(out,etmp);
        +		etmp=NULL;
        +		}
        +
        +#if 1
        +	if (PKCS7_is_detached(p7) || (in_bio != NULL))
        +		{
        +		bio=in_bio;
        +		}
        +	else 
        +		{
        +#if 0
        +		bio=BIO_new(BIO_s_mem());
        +		/* We need to set this so that when we have read all
        +		 * the data, the encrypt BIO, if present, will read
        +		 * EOF and encode the last few bytes */
        +		BIO_set_mem_eof_return(bio,0);
        +
        +		if (data_body->length > 0)
        +			BIO_write(bio,(char *)data_body->data,data_body->length);
        +#else
        +		if (data_body->length > 0)
        +		      bio = BIO_new_mem_buf(data_body->data,data_body->length);
        +		else {
        +			bio=BIO_new(BIO_s_mem());
        +			BIO_set_mem_eof_return(bio,0);
        +		}
        +		if (bio == NULL)
        +			goto err;
        +#endif
        +		}
        +	BIO_push(out,bio);
        +	bio=NULL;
        +#endif
        +	if (0)
        +		{
        +err:
        +               if (ek)
        +                       {
        +                       OPENSSL_cleanse(ek,eklen);
        +                       OPENSSL_free(ek);
        +                       }
        +               if (tkey)
        +                       {
        +                       OPENSSL_cleanse(tkey,tkeylen);
        +                       OPENSSL_free(tkey);
        +                       }
        +		if (out != NULL) BIO_free_all(out);
        +		if (btmp != NULL) BIO_free_all(btmp);
        +		if (etmp != NULL) BIO_free_all(etmp);
        +		if (bio != NULL) BIO_free_all(bio);
        +		out=NULL;
        +		}
        +	return(out);
        +	}
        +
        +static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
        +	{
        +	for (;;)
        +		{
        +		bio=BIO_find_type(bio,BIO_TYPE_MD);
        +		if (bio == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
        +			return NULL;	
        +			}
        +		BIO_get_md_ctx(bio,pmd);
        +		if (*pmd == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			}	
        +		if (EVP_MD_CTX_type(*pmd) == nid)
        +			return bio;
        +		bio=BIO_next(bio);
        +		}
        +	return NULL;
        +	}
        +
        +static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
        +	{
        +	unsigned char md_data[EVP_MAX_MD_SIZE];
        +	unsigned int md_len;
        +
        +	/* Add signing time if not already present */
        +	if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime))
        +		{
        +		if (!PKCS7_add0_attrib_signing_time(si, NULL))
        +			{
        +			PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
        +					ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		}
        +
        +	/* Add digest */
        +	if (!EVP_DigestFinal_ex(mctx, md_data,&md_len))
        +		{
        +		PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
        +		return 0;
        +		}
        +	if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
        +		{
        +		PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	/* Now sign the attributes */
        +	if (!PKCS7_SIGNER_INFO_sign(si))
        +			return 0;
        +
        +	return 1;
        +	}
        +	
        +				
        +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
        +	{
        +	int ret=0;
        +	int i,j;
        +	BIO *btmp;
        +	PKCS7_SIGNER_INFO *si;
        +	EVP_MD_CTX *mdc,ctx_tmp;
        +	STACK_OF(X509_ATTRIBUTE) *sk;
        +	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
        +	ASN1_OCTET_STRING *os=NULL;
        +
        +	EVP_MD_CTX_init(&ctx_tmp);
        +	i=OBJ_obj2nid(p7->type);
        +	p7->state=PKCS7_S_HEADER;
        +
        +	switch (i)
        +		{
        +	case NID_pkcs7_data:
        +		os = p7->d.data;
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		/* XXXXXXXXXXXXXXXX */
        +		si_sk=p7->d.signed_and_enveloped->signer_info;
        +		os = p7->d.signed_and_enveloped->enc_data->enc_data;
        +		if (!os)
        +			{
        +			os=M_ASN1_OCTET_STRING_new();
        +			if (!os)
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			p7->d.signed_and_enveloped->enc_data->enc_data=os;
        +			}
        +		break;
        +	case NID_pkcs7_enveloped:
        +		/* XXXXXXXXXXXXXXXX */
        +		os = p7->d.enveloped->enc_data->enc_data;
        +		if (!os)
        +			{
        +			os=M_ASN1_OCTET_STRING_new();
        +			if (!os)
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			p7->d.enveloped->enc_data->enc_data=os;
        +			}
        +		break;
        +	case NID_pkcs7_signed:
        +		si_sk=p7->d.sign->signer_info;
        +		os=PKCS7_get_octet_string(p7->d.sign->contents);
        +		/* If detached data then the content is excluded */
        +		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
        +			M_ASN1_OCTET_STRING_free(os);
        +			p7->d.sign->contents->d.data = NULL;
        +		}
        +		break;
        +
        +	case NID_pkcs7_digest:
        +		os=PKCS7_get_octet_string(p7->d.digest->contents);
        +		/* If detached data then the content is excluded */
        +		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
        +			{
        +			M_ASN1_OCTET_STRING_free(os);
        +			p7->d.digest->contents->d.data = NULL;
        +			}
        +		break;
        +
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        +	        goto err;
        +		}
        +
        +	if (si_sk != NULL)
        +		{
        +		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
        +			{
        +			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
        +			if (si->pkey == NULL)
        +				continue;
        +
        +			j = OBJ_obj2nid(si->digest_alg->algorithm);
        +
        +			btmp=bio;
        +
        +			btmp = PKCS7_find_digest(&mdc, btmp, j);
        +
        +			if (btmp == NULL)
        +				goto err;
        +
        +			/* We now have the EVP_MD_CTX, lets do the
        +			 * signing. */
        +			if (!EVP_MD_CTX_copy_ex(&ctx_tmp,mdc))
        +				goto err;
        +
        +			sk=si->auth_attr;
        +
        +			/* If there are attributes, we add the digest
        +			 * attribute and only sign the attributes */
        +			if (sk_X509_ATTRIBUTE_num(sk) > 0)
        +				{
        +				if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
        +					goto err;
        +				}
        +			else
        +				{
        +				unsigned char *abuf = NULL;
        +				unsigned int abuflen;
        +				abuflen = EVP_PKEY_size(si->pkey);
        +				abuf = OPENSSL_malloc(abuflen);
        +				if (!abuf)
        +					goto err;
        +
        +				if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
        +							si->pkey))
        +					{
        +					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
        +							ERR_R_EVP_LIB);
        +					goto err;
        +					}
        +				ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
        +				}
        +			}
        +		}
        +	else if (i == NID_pkcs7_digest)
        +		{
        +		unsigned char md_data[EVP_MAX_MD_SIZE];
        +		unsigned int md_len;
        +		if (!PKCS7_find_digest(&mdc, bio,
        +				OBJ_obj2nid(p7->d.digest->md->algorithm)))
        +			goto err;
        +		if (!EVP_DigestFinal_ex(mdc,md_data,&md_len))
        +			goto err;
        +		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
        +		}
        +
        +	if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
        +		{
        +		char *cont;
        +		long contlen;
        +		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
        +		if (btmp == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
        +			goto err;
        +			}
        +		contlen = BIO_get_mem_data(btmp, &cont);
        +		/* Mark the BIO read only then we can use its copy of the data
        +		 * instead of making an extra copy.
        +		 */
        +		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
        +		BIO_set_mem_eof_return(btmp, 0);
        +		ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
        +		}
        +	ret=1;
        +err:
        +	EVP_MD_CTX_cleanup(&ctx_tmp);
        +	return(ret);
        +	}
        +
        +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
        +	{
        +	EVP_MD_CTX mctx;
        +	EVP_PKEY_CTX *pctx;
        +	unsigned char *abuf = NULL;
        +	int alen;
        +	size_t siglen;
        +	const EVP_MD *md = NULL;
        +
        +	md = EVP_get_digestbyobj(si->digest_alg->algorithm);
        +	if (md == NULL)
        +		return 0;
        +
        +	EVP_MD_CTX_init(&mctx);
        +	if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
        +				EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
        +				ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
        +	if(!abuf)
        +		goto err;
        +	if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
        +		goto err;
        +	OPENSSL_free(abuf);
        +	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
        +		goto err;
        +	abuf = OPENSSL_malloc(siglen);
        +	if(!abuf)
        +		goto err;
        +	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
        +				EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
        +		goto err;
        +		}
        +
        +	EVP_MD_CTX_cleanup(&mctx);
        +
        +	ASN1_STRING_set0(si->enc_digest, abuf, siglen);
        +
        +	return 1;
        +
        +	err:
        +	if (abuf)
        +		OPENSSL_free(abuf);
        +	EVP_MD_CTX_cleanup(&mctx);
        +	return 0;
        +
        +	}
        +
        +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
        +	     PKCS7 *p7, PKCS7_SIGNER_INFO *si)
        +	{
        +	PKCS7_ISSUER_AND_SERIAL *ias;
        +	int ret=0,i;
        +	STACK_OF(X509) *cert;
        +	X509 *x509;
        +
        +	if (PKCS7_type_is_signed(p7))
        +		{
        +		cert=p7->d.sign->cert;
        +		}
        +	else if (PKCS7_type_is_signedAndEnveloped(p7))
        +		{
        +		cert=p7->d.signed_and_enveloped->cert;
        +		}
        +	else
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
        +		goto err;
        +		}
        +	/* XXXXXXXXXXXXXXXXXXXXXXX */
        +	ias=si->issuer_and_serial;
        +
        +	x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
        +
        +	/* were we able to find the cert in passed to us */
        +	if (x509 == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
        +		goto err;
        +		}
        +
        +	/* Lets verify */
        +	if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
        +		goto err;
        +		}
        +	X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
        +	i=X509_verify_cert(ctx);
        +	if (i <= 0) 
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
        +		X509_STORE_CTX_cleanup(ctx);
        +		goto err;
        +		}
        +	X509_STORE_CTX_cleanup(ctx);
        +
        +	return PKCS7_signatureVerify(bio, p7, si, x509);
        +	err:
        +	return ret;
        +	}
        +
        +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
        +								X509 *x509)
        +	{
        +	ASN1_OCTET_STRING *os;
        +	EVP_MD_CTX mdc_tmp,*mdc;
        +	int ret=0,i;
        +	int md_type;
        +	STACK_OF(X509_ATTRIBUTE) *sk;
        +	BIO *btmp;
        +	EVP_PKEY *pkey;
        +
        +	EVP_MD_CTX_init(&mdc_tmp);
        +
        +	if (!PKCS7_type_is_signed(p7) && 
        +				!PKCS7_type_is_signedAndEnveloped(p7)) {
        +		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
        +						PKCS7_R_WRONG_PKCS7_TYPE);
        +		goto err;
        +	}
        +
        +	md_type=OBJ_obj2nid(si->digest_alg->algorithm);
        +
        +	btmp=bio;
        +	for (;;)
        +		{
        +		if ((btmp == NULL) ||
        +			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
        +					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
        +			goto err;
        +			}
        +		BIO_get_md_ctx(btmp,&mdc);
        +		if (mdc == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
        +							ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		if (EVP_MD_CTX_type(mdc) == md_type)
        +			break;
        +		/* Workaround for some broken clients that put the signature
        +		 * OID instead of the digest OID in digest_alg->algorithm
        +		 */
        +		if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
        +			break;
        +		btmp=BIO_next(btmp);
        +		}
        +
        +	/* mdc is the digest ctx that we want, unless there are attributes,
        +	 * in which case the digest is the signed attributes */
        +	if (!EVP_MD_CTX_copy_ex(&mdc_tmp,mdc))
        +		goto err;
        +
        +	sk=si->auth_attr;
        +	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
        +		{
        +		unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
        +                unsigned int md_len;
        +		int alen;
        +		ASN1_OCTET_STRING *message_digest;
        +
        +		if (!EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len))
        +			goto err;
        +		message_digest=PKCS7_digest_from_attributes(sk);
        +		if (!message_digest)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
        +					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
        +			goto err;
        +			}
        +		if ((message_digest->length != (int)md_len) ||
        +			(memcmp(message_digest->data,md_dat,md_len)))
        +			{
        +#if 0
        +{
        +int ii;
        +for (ii=0; ii<message_digest->length; ii++)
        +	printf("%02X",message_digest->data[ii]); printf(" sent\n");
        +for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
        +}
        +#endif
        +			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
        +							PKCS7_R_DIGEST_FAILURE);
        +			ret= -1;
        +			goto err;
        +			}
        +
        +		if (!EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL))
        +			goto err;
        +
        +		alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
        +						ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
        +		if (alen <= 0) 
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
        +			ret = -1;
        +			goto err;
        +			}
        +		if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
        +			goto err;
        +
        +		OPENSSL_free(abuf);
        +		}
        +
        +	os=si->enc_digest;
        +	pkey = X509_get_pubkey(x509);
        +	if (!pkey)
        +		{
        +		ret = -1;
        +		goto err;
        +		}
        +
        +	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
        +	EVP_PKEY_free(pkey);
        +	if (i <= 0)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
        +						PKCS7_R_SIGNATURE_FAILURE);
        +		ret= -1;
        +		goto err;
        +		}
        +	else
        +		ret=1;
        +err:
        +	EVP_MD_CTX_cleanup(&mdc_tmp);
        +	return(ret);
        +	}
        +
        +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
        +	{
        +	STACK_OF(PKCS7_RECIP_INFO) *rsk;
        +	PKCS7_RECIP_INFO *ri;
        +	int i;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	if (i != NID_pkcs7_signedAndEnveloped)
        +		return NULL;
        +	if (p7->d.signed_and_enveloped == NULL)
        +		return NULL;
        +	rsk=p7->d.signed_and_enveloped->recipientinfo;
        +	if (rsk == NULL)
        +		return NULL;
        +	ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
        +	if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
        +	ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
        +	return(ri->issuer_and_serial);
        +	}
        +
        +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
        +	{
        +	return(get_attribute(si->auth_attr,nid));
        +	}
        +
        +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
        +	{
        +	return(get_attribute(si->unauth_attr,nid));
        +	}
        +
        +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
        +	{
        +	int i;
        +	X509_ATTRIBUTE *xa;
        +	ASN1_OBJECT *o;
        +
        +	o=OBJ_nid2obj(nid);
        +	if (!o || !sk) return(NULL);
        +	for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
        +		{
        +		xa=sk_X509_ATTRIBUTE_value(sk,i);
        +		if (OBJ_cmp(xa->object,o) == 0)
        +			{
        +			if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
        +				return(sk_ASN1_TYPE_value(xa->value.set,0));
        +			else
        +				return(NULL);
        +			}
        +		}
        +	return(NULL);
        +	}
        +
        +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
        +{
        +	ASN1_TYPE *astype;
        +	if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
        +	return astype->value.octet_string;
        +}
        +
        +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
        +				STACK_OF(X509_ATTRIBUTE) *sk)
        +	{
        +	int i;
        +
        +	if (p7si->auth_attr != NULL)
        +		sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
        +	p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
        +	if (p7si->auth_attr == NULL)
        +		return 0;
        +	for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
        +		{
        +		if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
        +			X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
        +		    == NULL)
        +			return(0);
        +		}
        +	return(1);
        +	}
        +
        +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
        +	{
        +	int i;
        +
        +	if (p7si->unauth_attr != NULL)
        +		sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
        +					   X509_ATTRIBUTE_free);
        +	p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
        +	if (p7si->unauth_attr == NULL)
        +		return 0;
        +	for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
        +		{
        +		if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
        +                        X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
        +		    == NULL)
        +			return(0);
        +		}
        +	return(1);
        +	}
        +
        +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
        +	     void *value)
        +	{
        +	return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
        +	}
        +
        +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
        +	     void *value)
        +	{
        +	return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
        +	}
        +
        +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
        +			 void *value)
        +	{
        +	X509_ATTRIBUTE *attr=NULL;
        +
        +	if (*sk == NULL)
        +		{
        +		*sk = sk_X509_ATTRIBUTE_new_null();
        +		if (*sk == NULL)
        +			return 0;	
        +new_attrib:
        +		if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
        +			return 0;
        +		if (!sk_X509_ATTRIBUTE_push(*sk,attr))
        +			{
        +			X509_ATTRIBUTE_free(attr);
        +			return 0;
        +			}
        +		}
        +	else
        +		{
        +		int i;
        +
        +		for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
        +			{
        +			attr=sk_X509_ATTRIBUTE_value(*sk,i);
        +			if (OBJ_obj2nid(attr->object) == nid)
        +				{
        +				X509_ATTRIBUTE_free(attr);
        +				attr=X509_ATTRIBUTE_create(nid,atrtype,value);
        +				if (attr == NULL)
        +					return 0;
        +				if (!sk_X509_ATTRIBUTE_set(*sk,i,attr))
        +					{
        +					X509_ATTRIBUTE_free(attr);
        +					return 0;
        +					}
        +				goto end;
        +				}
        +			}
        +		goto new_attrib;
        +		}
        +end:
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_enc.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_enc.c
        new file mode 100644
        index 000000000..acbb189c5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_enc.c
        @@ -0,0 +1,76 @@
        +/* crypto/pkcs7/pk7_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/pkcs7.h>
        +
        +PKCS7_in_bio(PKCS7 *p7,BIO *in);
        +PKCS7_out_bio(PKCS7 *p7,BIO *out);
        +
        +PKCS7_add_signer(PKCS7 *p7,X509 *cert,EVP_PKEY *key);
        +PKCS7_cipher(PKCS7 *p7,EVP_CIPHER *cipher);
        +
        +PKCS7_Init(PKCS7 *p7);
        +PKCS7_Update(PKCS7 *p7);
        +PKCS7_Finish(PKCS7 *p7);
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_lib.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_lib.c
        new file mode 100644
        index 000000000..d411269b5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_lib.c
        @@ -0,0 +1,665 @@
        +/* crypto/pkcs7/pk7_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include "asn1_locl.h"
        +
        +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
        +	{
        +	int nid;
        +	long ret;
        +
        +	nid=OBJ_obj2nid(p7->type);
        +
        +	switch (cmd)
        +		{
        +	case PKCS7_OP_SET_DETACHED_SIGNATURE:
        +		if (nid == NID_pkcs7_signed)
        +			{
        +			ret=p7->detached=(int)larg;
        +			if (ret && PKCS7_type_is_data(p7->d.sign->contents))
        +					{
        +					ASN1_OCTET_STRING *os;
        +					os=p7->d.sign->contents->d.data;
        +					ASN1_OCTET_STRING_free(os);
        +					p7->d.sign->contents->d.data = NULL;
        +					}
        +			}
        +		else
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
        +			ret=0;
        +			}
        +		break;
        +	case PKCS7_OP_GET_DETACHED_SIGNATURE:
        +		if (nid == NID_pkcs7_signed)
        +			{
        +			if(!p7->d.sign  || !p7->d.sign->contents->d.ptr)
        +				ret = 1;
        +			else ret = 0;
        +				
        +			p7->detached = ret;
        +			}
        +		else
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
        +			ret=0;
        +			}
        +			
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION);
        +		ret=0;
        +		}
        +	return(ret);
        +	}
        +
        +int PKCS7_content_new(PKCS7 *p7, int type)
        +	{
        +	PKCS7 *ret=NULL;
        +
        +	if ((ret=PKCS7_new()) == NULL) goto err;
        +	if (!PKCS7_set_type(ret,type)) goto err;
        +	if (!PKCS7_set_content(p7,ret)) goto err;
        +
        +	return(1);
        +err:
        +	if (ret != NULL) PKCS7_free(ret);
        +	return(0);
        +	}
        +
        +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
        +	{
        +	int i;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	switch (i)
        +		{
        +	case NID_pkcs7_signed:
        +		if (p7->d.sign->contents != NULL)
        +			PKCS7_free(p7->d.sign->contents);
        +		p7->d.sign->contents=p7_data;
        +		break;
        +	case NID_pkcs7_digest:
        +		if (p7->d.digest->contents != NULL)
        +			PKCS7_free(p7->d.digest->contents);
        +		p7->d.digest->contents=p7_data;
        +		break;
        +	case NID_pkcs7_data:
        +	case NID_pkcs7_enveloped:
        +	case NID_pkcs7_signedAndEnveloped:
        +	case NID_pkcs7_encrypted:
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        +		goto err;
        +		}
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +int PKCS7_set_type(PKCS7 *p7, int type)
        +	{
        +	ASN1_OBJECT *obj;
        +
        +	/*PKCS7_content_free(p7);*/
        +	obj=OBJ_nid2obj(type); /* will not fail */
        +
        +	switch (type)
        +		{
        +	case NID_pkcs7_signed:
        +		p7->type=obj;
        +		if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
        +			goto err;
        +		if (!ASN1_INTEGER_set(p7->d.sign->version,1))
        +			{
        +			PKCS7_SIGNED_free(p7->d.sign);
        +			p7->d.sign=NULL;
        +			goto err;
        +			}
        +		break;
        +	case NID_pkcs7_data:
        +		p7->type=obj;
        +		if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
        +			goto err;
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		p7->type=obj;
        +		if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
        +			== NULL) goto err;
        +		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
        +		if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1))
        +			goto err;
        +		p7->d.signed_and_enveloped->enc_data->content_type
        +						= OBJ_nid2obj(NID_pkcs7_data);
        +		break;
        +	case NID_pkcs7_enveloped:
        +		p7->type=obj;
        +		if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
        +			== NULL) goto err;
        +		if (!ASN1_INTEGER_set(p7->d.enveloped->version,0))
        +			goto err;
        +		p7->d.enveloped->enc_data->content_type
        +						= OBJ_nid2obj(NID_pkcs7_data);
        +		break;
        +	case NID_pkcs7_encrypted:
        +		p7->type=obj;
        +		if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
        +			== NULL) goto err;
        +		if (!ASN1_INTEGER_set(p7->d.encrypted->version,0))
        +			goto err;
        +		p7->d.encrypted->enc_data->content_type
        +						= OBJ_nid2obj(NID_pkcs7_data);
        +		break;
        +
        +	case NID_pkcs7_digest:
        +		p7->type=obj;
        +		if ((p7->d.digest=PKCS7_DIGEST_new())
        +			== NULL) goto err;
        +		if (!ASN1_INTEGER_set(p7->d.digest->version,0))
        +			goto err;
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        +		goto err;
        +		}
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
        +	{
        +	p7->type = OBJ_nid2obj(type);
        +	p7->d.other = other;
        +	return 1;
        +	}
        +
        +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
        +	{
        +	int i,j,nid;
        +	X509_ALGOR *alg;
        +	STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
        +	STACK_OF(X509_ALGOR) *md_sk;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	switch (i)
        +		{
        +	case NID_pkcs7_signed:
        +		signer_sk=	p7->d.sign->signer_info;
        +		md_sk=		p7->d.sign->md_algs;
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		signer_sk=	p7->d.signed_and_enveloped->signer_info;
        +		md_sk=		p7->d.signed_and_enveloped->md_algs;
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return(0);
        +		}
        +
        +	nid=OBJ_obj2nid(psi->digest_alg->algorithm);
        +
        +	/* If the digest is not currently listed, add it */
        +	j=0;
        +	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
        +		{
        +		alg=sk_X509_ALGOR_value(md_sk,i);
        +		if (OBJ_obj2nid(alg->algorithm) == nid)
        +			{
        +			j=1;
        +			break;
        +			}
        +		}
        +	if (!j) /* we need to add another algorithm */
        +		{
        +		if(!(alg=X509_ALGOR_new())
        +			|| !(alg->parameter = ASN1_TYPE_new()))
        +			{
        +			X509_ALGOR_free(alg);
        +			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		alg->algorithm=OBJ_nid2obj(nid);
        +		alg->parameter->type = V_ASN1_NULL;
        +		if (!sk_X509_ALGOR_push(md_sk,alg))
        +			{
        +			X509_ALGOR_free(alg);
        +			return 0;
        +			}
        +		}
        +
        +	if (!sk_PKCS7_SIGNER_INFO_push(signer_sk,psi))
        +		return 0;
        +	return(1);
        +	}
        +
        +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
        +	{
        +	int i;
        +	STACK_OF(X509) **sk;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	switch (i)
        +		{
        +	case NID_pkcs7_signed:
        +		sk= &(p7->d.sign->cert);
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		sk= &(p7->d.signed_and_enveloped->cert);
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return(0);
        +		}
        +
        +	if (*sk == NULL)
        +		*sk=sk_X509_new_null();
        +	if (*sk == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
        +	if (!sk_X509_push(*sk,x509))
        +		{
        +		X509_free(x509);
        +		return 0;
        +		}
        +	return(1);
        +	}
        +
        +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
        +	{
        +	int i;
        +	STACK_OF(X509_CRL) **sk;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	switch (i)
        +		{
        +	case NID_pkcs7_signed:
        +		sk= &(p7->d.sign->crl);
        +		break;
        +	case NID_pkcs7_signedAndEnveloped:
        +		sk= &(p7->d.signed_and_enveloped->crl);
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return(0);
        +		}
        +
        +	if (*sk == NULL)
        +		*sk=sk_X509_CRL_new_null();
        +	if (*sk == NULL)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_ADD_CRL,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
        +	if (!sk_X509_CRL_push(*sk,crl))
        +		{
        +		X509_CRL_free(crl);
        +		return 0;
        +		}
        +	return(1);
        +	}
        +
        +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
        +	     const EVP_MD *dgst)
        +	{
        +	int ret;
        +
        +	/* We now need to add another PKCS7_SIGNER_INFO entry */
        +	if (!ASN1_INTEGER_set(p7i->version,1))
        +		goto err;
        +	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
        +			X509_get_issuer_name(x509)))
        +		goto err;
        +
        +	/* because ASN1_INTEGER_set is used to set a 'long' we will do
        +	 * things the ugly way. */
        +	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
        +	if (!(p7i->issuer_and_serial->serial=
        +			M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
        +		goto err;
        +
        +	/* lets keep the pkey around for a while */
        +	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        +	p7i->pkey=pkey;
        +
        +	/* Set the algorithms */
        +
        +	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
        +				V_ASN1_NULL, NULL);
        +
        +	if (pkey->ameth && pkey->ameth->pkey_ctrl)
        +		{
        +		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
        +						0, p7i);
        +		if (ret > 0)
        +			return 1;
        +		if (ret != -2)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
        +					PKCS7_R_SIGNING_CTRL_FAILURE);
        +			return 0;
        +			}
        +		}
        +	PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
        +			PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
        +err:
        +	return 0;
        +	}
        +
        +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
        +	     const EVP_MD *dgst)
        +	{
        +	PKCS7_SIGNER_INFO *si = NULL;
        +
        +	if (dgst == NULL)
        +		{
        +		int def_nid;
        +		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
        +			goto err;
        +		dgst = EVP_get_digestbynid(def_nid);
        +		if (dgst == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
        +						PKCS7_R_NO_DEFAULT_DIGEST);
        +			goto err;
        +			}
        +		}
        +
        +	if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
        +	if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
        +	if (!PKCS7_add_signer(p7,si)) goto err;
        +	return(si);
        +err:
        +	if (si)
        +		PKCS7_SIGNER_INFO_free(si);
        +	return(NULL);
        +	}
        +
        +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
        +	{
        +	if (PKCS7_type_is_digest(p7))
        +		{
        +		if(!(p7->d.digest->md->parameter = ASN1_TYPE_new()))
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		p7->d.digest->md->parameter->type = V_ASN1_NULL;
        +		p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
        +		return 1;
        +		}
        +		
        +	PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE);
        +	return 1;
        +	}
        +
        +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
        +	{
        +	if (PKCS7_type_is_signed(p7))
        +		{
        +		return(p7->d.sign->signer_info);
        +		}
        +	else if (PKCS7_type_is_signedAndEnveloped(p7))
        +		{
        +		return(p7->d.signed_and_enveloped->signer_info);
        +		}
        +	else
        +		return(NULL);
        +	}
        +
        +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
        +					X509_ALGOR **pdig, X509_ALGOR **psig)
        +	{
        +	if (pk)
        +		*pk = si->pkey;
        +	if (pdig)
        +		*pdig = si->digest_alg;
        +	if (psig)
        +		*psig = si->digest_enc_alg;
        +	}
        +
        +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
        +	{
        +	if (penc)
        +		*penc = ri->key_enc_algor;
        +	}
        +
        +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
        +	{
        +	PKCS7_RECIP_INFO *ri;
        +
        +	if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
        +	if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
        +	if (!PKCS7_add_recipient_info(p7,ri)) goto err;
        +	return ri;
        +err:
        +	if (ri)
        +		PKCS7_RECIP_INFO_free(ri);
        +	return NULL;
        +	}
        +
        +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
        +	{
        +	int i;
        +	STACK_OF(PKCS7_RECIP_INFO) *sk;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	switch (i)
        +		{
        +	case NID_pkcs7_signedAndEnveloped:
        +		sk=	p7->d.signed_and_enveloped->recipientinfo;
        +		break;
        +	case NID_pkcs7_enveloped:
        +		sk=	p7->d.enveloped->recipientinfo;
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return(0);
        +		}
        +
        +	if (!sk_PKCS7_RECIP_INFO_push(sk,ri))
        +		return 0;
        +	return(1);
        +	}
        +
        +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
        +	{
        +	int ret;
        +	EVP_PKEY *pkey = NULL;
        +	if (!ASN1_INTEGER_set(p7i->version,0))
        +		return 0;
        +	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
        +		X509_get_issuer_name(x509)))
        +		return 0;
        +
        +	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
        +	if (!(p7i->issuer_and_serial->serial=
        +		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
        +		return 0;
        +
        +	pkey = X509_get_pubkey(x509);
        +
        +	if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
        +			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
        +		goto err;
        +		}
        +
        +	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
        +						0, p7i);
        +	if (ret == -2)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
        +			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
        +		goto err;
        +		}
        +	if (ret <= 0)
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
        +				PKCS7_R_ENCRYPTION_CTRL_FAILURE);
        +		goto err;
        +		}
        +
        +	EVP_PKEY_free(pkey);
        +
        +	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
        +	p7i->cert=x509;
        +
        +	return 1;
        +
        +	err:
        +	if (pkey)
        +		EVP_PKEY_free(pkey);
        +	return 0;
        +	}
        +
        +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
        +	{
        +	if (PKCS7_type_is_signed(p7))
        +		return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
        +			si->issuer_and_serial->issuer,
        +			si->issuer_and_serial->serial));
        +	else
        +		return(NULL);
        +	}
        +
        +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
        +	{
        +	int i;
        +	PKCS7_ENC_CONTENT *ec;
        +
        +	i=OBJ_obj2nid(p7->type);
        +	switch (i)
        +		{
        +	case NID_pkcs7_signedAndEnveloped:
        +		ec=p7->d.signed_and_enveloped->enc_data;
        +		break;
        +	case NID_pkcs7_enveloped:
        +		ec=p7->d.enveloped->enc_data;
        +		break;
        +	default:
        +		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return(0);
        +		}
        +
        +	/* Check cipher OID exists and has data in it*/
        +	i = EVP_CIPHER_type(cipher);
        +	if(i == NID_undef) {
        +		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        +		return(0);
        +	}
        +
        +	ec->cipher = cipher;
        +	return 1;
        +	}
        +
        +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
        +	{
        +	ASN1_OCTET_STRING *os = NULL;
        +
        +	switch (OBJ_obj2nid(p7->type))
        +		{
        +		case NID_pkcs7_data:
        +		os = p7->d.data;
        +		break;
        +
        +		case NID_pkcs7_signedAndEnveloped:
        +		os = p7->d.signed_and_enveloped->enc_data->enc_data;
        +		if (os == NULL)
        +			{
        +			os=M_ASN1_OCTET_STRING_new();
        +			p7->d.signed_and_enveloped->enc_data->enc_data=os;
        +			}
        +		break;
        +
        +		case NID_pkcs7_enveloped:
        +		os = p7->d.enveloped->enc_data->enc_data;
        +		if (os == NULL)
        +			{
        +			os=M_ASN1_OCTET_STRING_new();
        +			p7->d.enveloped->enc_data->enc_data=os;
        +			}
        +		break;
        +
        +		case NID_pkcs7_signed:
        +		os=p7->d.sign->contents->d.data;
        +		break;
        +
        +		default:
        +		os = NULL;
        +		break;
        +		}
        +	
        +	if (os == NULL)
        +		return 0;
        +
        +	os->flags |= ASN1_STRING_FLAG_NDEF;
        +	*boundary = &os->data;
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_mime.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_mime.c
        new file mode 100644
        index 000000000..938f79a64
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_mime.c
        @@ -0,0 +1,97 @@
        +/* pk7_mime.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1.h>
        +
        +/* PKCS#7 wrappers round generalised stream and MIME routines */
        +
        +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
        +	{
        +	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
        +					ASN1_ITEM_rptr(PKCS7));
        +	}
        +
        +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
        +	{
        +	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
        +						"PKCS7",
        +						ASN1_ITEM_rptr(PKCS7));
        +	}
        +
        +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
        +	{
        +	STACK_OF(X509_ALGOR) *mdalgs;
        +	int ctype_nid = OBJ_obj2nid(p7->type);
        +	if (ctype_nid == NID_pkcs7_signed)
        +		mdalgs = p7->d.sign->md_algs;
        +	else
        +		mdalgs = NULL;
        +
        +	flags ^= SMIME_OLDMIME;
        +
        +
        +	return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
        +					ctype_nid, NID_undef, mdalgs,
        +					ASN1_ITEM_rptr(PKCS7));	
        +	}
        +
        +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
        +	{
        +	return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pk7_smime.c b/vendor/openssl/openssl/crypto/pkcs7/pk7_smime.c
        new file mode 100644
        index 000000000..a5104f8d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pk7_smime.c
        @@ -0,0 +1,606 @@
        +/* pk7_smime.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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).
        + *
        + */
        +
        +/* Simple PKCS#7 processing functions */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
        +
        +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
        +		  BIO *data, int flags)
        +{
        +	PKCS7 *p7;
        +	int i;
        +
        +	if(!(p7 = PKCS7_new()))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	if (!PKCS7_set_type(p7, NID_pkcs7_signed))
        +		goto err;
        +
        +	if (!PKCS7_content_new(p7, NID_pkcs7_data))
        +		goto err;
        +
        +    	if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
        +		goto err;
        +		}
        +
        +	if(!(flags & PKCS7_NOCERTS))
        +		{
        +		for(i = 0; i < sk_X509_num(certs); i++)
        +			{
        +			if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
        +				goto err;
        +			}
        +		}
        +
        +	if(flags & PKCS7_DETACHED)
        +		PKCS7_set_detached(p7, 1);
        +
        +	if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
        +		return p7;
        +
        +	if (PKCS7_final(p7, data, flags))
        +		return p7;
        +
        +	err:
        +	PKCS7_free(p7);
        +	return NULL;
        +}
        +
        +int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
        +	{
        +	BIO *p7bio;
        +	int ret = 0;
        +	if (!(p7bio = PKCS7_dataInit(p7, NULL)))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	SMIME_crlf_copy(data, p7bio, flags);
        +
        +	(void)BIO_flush(p7bio);
        +
        +
        +        if (!PKCS7_dataFinal(p7,p7bio))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +
        +	err:
        +	BIO_free_all(p7bio);
        +
        +	return ret;
        +
        +	}
        +
        +/* Check to see if a cipher exists and if so add S/MIME capabilities */
        +
        +static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
        +	{
        +	if (EVP_get_cipherbynid(nid))
        +		return PKCS7_simple_smimecap(sk, nid, arg);
        +	return 1;
        +	}
        +
        +static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
        +	{
        +	if (EVP_get_digestbynid(nid))
        +		return PKCS7_simple_smimecap(sk, nid, arg);
        +	return 1;
        +	}
        +
        +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
        +					EVP_PKEY *pkey, const EVP_MD *md,
        +					int flags)
        +	{
        +	PKCS7_SIGNER_INFO *si = NULL;
        +	STACK_OF(X509_ALGOR) *smcap = NULL;
        +	if(!X509_check_private_key(signcert, pkey))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
        +			PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        +                return NULL;
        +		}
        +
        +    	if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
        +		{
        +		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
        +				PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
        +		return NULL;
        +		}
        +
        +	if(!(flags & PKCS7_NOCERTS))
        +		{
        +		if (!PKCS7_add_certificate(p7, signcert))
        +			goto err;
        +		}
        +
        +	if(!(flags & PKCS7_NOATTR))
        +		{
        +		if (!PKCS7_add_attrib_content_type(si, NULL))
        +			goto err;
        +		/* Add SMIMECapabilities */
        +		if(!(flags & PKCS7_NOSMIMECAP))
        +			{
        +			if(!(smcap = sk_X509_ALGOR_new_null()))
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
        +					ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
        +			|| !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
        +			|| !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
        +				|| !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
        +				|| !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
        +			|| !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
        +				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
        +				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
        +				|| !add_cipher_smcap(smcap, NID_des_cbc, -1)
        +				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
        +				|| !PKCS7_add_attrib_smimecap (si, smcap))
        +				goto err;
        +			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
        +			smcap = NULL;
        +			}
        +		if (flags & PKCS7_REUSE_DIGEST)
        +			{
        +			if (!pkcs7_copy_existing_digest(p7, si))
        +				goto err;
        +			if (!(flags & PKCS7_PARTIAL) &&
        +					!PKCS7_SIGNER_INFO_sign(si))
        +				goto err;
        +			}
        +		}
        +	return si;
        +	err:
        +	if (smcap)
        +		sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
        +	return NULL;
        +	}
        +
        +/* Search for a digest matching SignerInfo digest type and if found
        + * copy across.
        + */
        +
        +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
        +	{
        +	int i;
        +	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
        +	PKCS7_SIGNER_INFO *sitmp;
        +	ASN1_OCTET_STRING *osdig = NULL;
        +	sinfos = PKCS7_get_signer_info(p7);
        +	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
        +		{
        +		sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
        +		if (si == sitmp)
        +			break;
        +		if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
        +			continue;
        +		if (!OBJ_cmp(si->digest_alg->algorithm,
        +				sitmp->digest_alg->algorithm))
        +			{
        +			osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
        +			break;
        +			}
        +
        +		}
        +
        +	if (osdig)
        +		return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
        +
        +	PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
        +			PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
        +	return 0;
        +	}
        +
        +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
        +					BIO *indata, BIO *out, int flags)
        +{
        +	STACK_OF(X509) *signers;
        +	X509 *signer;
        +	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
        +	PKCS7_SIGNER_INFO *si;
        +	X509_STORE_CTX cert_ctx;
        +	char buf[4096];
        +	int i, j=0, k, ret = 0;
        +	BIO *p7bio;
        +	BIO *tmpin, *tmpout;
        +
        +	if(!p7) {
        +		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER);
        +		return 0;
        +	}
        +
        +	if(!PKCS7_type_is_signed(p7)) {
        +		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return 0;
        +	}
        +
        +	/* Check for no data and no content: no data to verify signature */
        +	if(PKCS7_get_detached(p7) && !indata) {
        +		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT);
        +		return 0;
        +	}
        +#if 0
        +	/* NB: this test commented out because some versions of Netscape
        +	 * illegally include zero length content when signing data.
        +	 */
        +
        +	/* Check for data and content: two sets of data */
        +	if(!PKCS7_get_detached(p7) && indata) {
        +				PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT);
        +		return 0;
        +	}
        +#endif
        +
        +	sinfos = PKCS7_get_signer_info(p7);
        +
        +	if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
        +		PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA);
        +		return 0;
        +	}
        +
        +
        +	signers = PKCS7_get0_signers(p7, certs, flags);
        +
        +	if(!signers) return 0;
        +
        +	/* Now verify the certificates */
        +
        +	if (!(flags & PKCS7_NOVERIFY)) for (k = 0; k < sk_X509_num(signers); k++) {
        +		signer = sk_X509_value (signers, k);
        +		if (!(flags & PKCS7_NOCHAIN)) {
        +			if(!X509_STORE_CTX_init(&cert_ctx, store, signer,
        +							p7->d.sign->cert))
        +				{
        +				PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
        +				sk_X509_free(signers);
        +				return 0;
        +				}
        +			X509_STORE_CTX_set_default(&cert_ctx, "smime_sign");
        +		} else if(!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) {
        +			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
        +			sk_X509_free(signers);
        +			return 0;
        +		}
        +		if (!(flags & PKCS7_NOCRL))
        +			X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl);
        +		i = X509_verify_cert(&cert_ctx);
        +		if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx);
        +		X509_STORE_CTX_cleanup(&cert_ctx);
        +		if (i <= 0) {
        +			PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR);
        +			ERR_add_error_data(2, "Verify error:",
        +					 X509_verify_cert_error_string(j));
        +			sk_X509_free(signers);
        +			return 0;
        +		}
        +		/* Check for revocation status here */
        +	}
        +
        +	/* Performance optimization: if the content is a memory BIO then
        +	 * store its contents in a temporary read only memory BIO. This
        +	 * avoids potentially large numbers of slow copies of data which will
        +	 * occur when reading from a read write memory BIO when signatures
        +	 * are calculated.
        +	 */
        +
        +	if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM))
        +		{
        +		char *ptr;
        +		long len;
        +		len = BIO_get_mem_data(indata, &ptr);
        +		tmpin = BIO_new_mem_buf(ptr, len);
        +		if (tmpin == NULL)
        +			{
        +			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		}
        +	else
        +		tmpin = indata;
        +		
        +
        +	if (!(p7bio=PKCS7_dataInit(p7,tmpin)))
        +		goto err;
        +
        +	if(flags & PKCS7_TEXT) {
        +		if(!(tmpout = BIO_new(BIO_s_mem()))) {
        +			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		BIO_set_mem_eof_return(tmpout, 0);
        +	} else tmpout = out;
        +
        +	/* We now have to 'read' from p7bio to calculate digests etc. */
        +	for (;;)
        +	{
        +		i=BIO_read(p7bio,buf,sizeof(buf));
        +		if (i <= 0) break;
        +		if (tmpout) BIO_write(tmpout, buf, i);
        +	}
        +
        +	if(flags & PKCS7_TEXT) {
        +		if(!SMIME_text(tmpout, out)) {
        +			PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR);
        +			BIO_free(tmpout);
        +			goto err;
        +		}
        +		BIO_free(tmpout);
        +	}
        +
        +	/* Now Verify All Signatures */
        +	if (!(flags & PKCS7_NOSIGS))
        +	    for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
        +		{
        +		si=sk_PKCS7_SIGNER_INFO_value(sinfos,i);
        +		signer = sk_X509_value (signers, i);
        +		j=PKCS7_signatureVerify(p7bio,p7,si, signer);
        +		if (j <= 0) {
        +			PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE);
        +			goto err;
        +		}
        +	}
        +
        +	ret = 1;
        +
        +	err:
        +	
        +	if (tmpin == indata)
        +		{
        +		if (indata) BIO_pop(p7bio);
        +		}
        +	BIO_free_all(p7bio);
        +
        +	sk_X509_free(signers);
        +
        +	return ret;
        +}
        +
        +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
        +{
        +	STACK_OF(X509) *signers;
        +	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
        +	PKCS7_SIGNER_INFO *si;
        +	PKCS7_ISSUER_AND_SERIAL *ias;
        +	X509 *signer;
        +	int i;
        +
        +	if(!p7) {
        +		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER);
        +		return NULL;
        +	}
        +
        +	if(!PKCS7_type_is_signed(p7)) {
        +		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return NULL;
        +	}
        +
        +	/* Collect all the signers together */
        +
        +	sinfos = PKCS7_get_signer_info(p7);
        +
        +	if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
        +		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
        +		return 0;
        +	}
        +
        +	if(!(signers = sk_X509_new_null())) {
        +		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
        +	{
        +	    si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
        +	    ias = si->issuer_and_serial;
        +	    signer = NULL;
        +		/* If any certificates passed they take priority */
        +	    if (certs) signer = X509_find_by_issuer_and_serial (certs,
        +					 	ias->issuer, ias->serial);
        +	    if (!signer && !(flags & PKCS7_NOINTERN)
        +			&& p7->d.sign->cert) signer =
        +		              X509_find_by_issuer_and_serial (p7->d.sign->cert,
        +					      	ias->issuer, ias->serial);
        +	    if (!signer) {
        +			PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
        +			sk_X509_free(signers);
        +			return 0;
        +	    }
        +
        +	    if (!sk_X509_push(signers, signer)) {
        +		sk_X509_free(signers);
        +		return NULL;
        +	    }
        +	}
        +	return signers;
        +}
        +
        +
        +/* Build a complete PKCS#7 enveloped data */
        +
        +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
        +								int flags)
        +{
        +	PKCS7 *p7;
        +	BIO *p7bio = NULL;
        +	int i;
        +	X509 *x509;
        +	if(!(p7 = PKCS7_new())) {
        +		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
        +		goto err;
        +	if (!PKCS7_set_cipher(p7, cipher)) {
        +		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
        +		goto err;
        +	}
        +
        +	for(i = 0; i < sk_X509_num(certs); i++) {
        +		x509 = sk_X509_value(certs, i);
        +		if(!PKCS7_add_recipient(p7, x509)) {
        +			PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
        +					PKCS7_R_ERROR_ADDING_RECIPIENT);
        +			goto err;
        +		}
        +	}
        +
        +	if (flags & PKCS7_STREAM)
        +		return p7;
        +
        +	if (PKCS7_final(p7, in, flags))
        +		return p7;
        +
        +	err:
        +
        +	BIO_free_all(p7bio);
        +	PKCS7_free(p7);
        +	return NULL;
        +
        +}
        +
        +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
        +{
        +	BIO *tmpmem;
        +	int ret, i;
        +	char buf[4096];
        +
        +	if(!p7) {
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER);
        +		return 0;
        +	}
        +
        +	if(!PKCS7_type_is_enveloped(p7)) {
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE);
        +		return 0;
        +	}
        +
        +	if(cert && !X509_check_private_key(cert, pkey)) {
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT,
        +				PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        +		return 0;
        +	}
        +
        +	if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
        +		PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
        +		return 0;
        +	}
        +
        +	if (flags & PKCS7_TEXT) {
        +		BIO *tmpbuf, *bread;
        +		/* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
        +		if(!(tmpbuf = BIO_new(BIO_f_buffer()))) {
        +			PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
        +			BIO_free_all(tmpmem);
        +			return 0;
        +		}
        +		if(!(bread = BIO_push(tmpbuf, tmpmem))) {
        +			PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
        +			BIO_free_all(tmpbuf);
        +			BIO_free_all(tmpmem);
        +			return 0;
        +		}
        +		ret = SMIME_text(bread, data);
        +		if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER)
        +			{
        +			if (!BIO_get_cipher_status(tmpmem))
        +				ret = 0;
        +			}
        +		BIO_free_all(bread);
        +		return ret;
        +	} else {
        +		for(;;) {
        +			i = BIO_read(tmpmem, buf, sizeof(buf));
        +			if(i <= 0)
        +				{
        +				ret = 1;
        +				if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER)
        +					{
        +					if (!BIO_get_cipher_status(tmpmem))
        +						ret = 0;
        +					}
        +					
        +				break;
        +				}
        +			if (BIO_write(data, buf, i) != i)
        +				{
        +				ret = 0;
        +				break;
        +				}
        +		}
        +		BIO_free_all(tmpmem);
        +		return ret;
        +	}
        +}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pkcs7.h b/vendor/openssl/openssl/crypto/pkcs7/pkcs7.h
        new file mode 100644
        index 000000000..e4d443193
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pkcs7.h
        @@ -0,0 +1,499 @@
        +/* crypto/pkcs7/pkcs7.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_PKCS7_H
        +#define HEADER_PKCS7_H
        +
        +#include <openssl/asn1.h>
        +#include <openssl/bio.h>
        +#include <openssl/e_os2.h>
        +
        +#include <openssl/symhacks.h>
        +#include <openssl/ossl_typ.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_SYS_WIN32
        +/* Under Win32 thes are defined in wincrypt.h */
        +#undef PKCS7_ISSUER_AND_SERIAL
        +#undef PKCS7_SIGNER_INFO
        +#endif
        +
        +/*
        +Encryption_ID		DES-CBC
        +Digest_ID		MD5
        +Digest_Encryption_ID	rsaEncryption
        +Key_Encryption_ID	rsaEncryption
        +*/
        +
        +typedef struct pkcs7_issuer_and_serial_st
        +	{
        +	X509_NAME *issuer;
        +	ASN1_INTEGER *serial;
        +	} PKCS7_ISSUER_AND_SERIAL;
        +
        +typedef struct pkcs7_signer_info_st
        +	{
        +	ASN1_INTEGER 			*version;	/* version 1 */
        +	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
        +	X509_ALGOR			*digest_alg;
        +	STACK_OF(X509_ATTRIBUTE)	*auth_attr;	/* [ 0 ] */
        +	X509_ALGOR			*digest_enc_alg;
        +	ASN1_OCTET_STRING		*enc_digest;
        +	STACK_OF(X509_ATTRIBUTE)	*unauth_attr;	/* [ 1 ] */
        +
        +	/* The private key to sign with */
        +	EVP_PKEY			*pkey;
        +	} PKCS7_SIGNER_INFO;
        +
        +DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
        +DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
        +
        +typedef struct pkcs7_recip_info_st
        +	{
        +	ASN1_INTEGER			*version;	/* version 0 */
        +	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
        +	X509_ALGOR			*key_enc_algor;
        +	ASN1_OCTET_STRING		*enc_key;
        +	X509				*cert; /* get the pub-key from this */
        +	} PKCS7_RECIP_INFO;
        +
        +DECLARE_STACK_OF(PKCS7_RECIP_INFO)
        +DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
        +
        +typedef struct pkcs7_signed_st
        +	{
        +	ASN1_INTEGER			*version;	/* version 1 */
        +	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
        +	STACK_OF(X509)			*cert;		/* [ 0 ] */
        +	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
        +	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
        +
        +	struct pkcs7_st			*contents;
        +	} PKCS7_SIGNED;
        +/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
        + * How about merging the two */
        +
        +typedef struct pkcs7_enc_content_st
        +	{
        +	ASN1_OBJECT			*content_type;
        +	X509_ALGOR			*algorithm;
        +	ASN1_OCTET_STRING		*enc_data;	/* [ 0 ] */
        +	const EVP_CIPHER		*cipher;
        +	} PKCS7_ENC_CONTENT;
        +
        +typedef struct pkcs7_enveloped_st
        +	{
        +	ASN1_INTEGER			*version;	/* version 0 */
        +	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
        +	PKCS7_ENC_CONTENT		*enc_data;
        +	} PKCS7_ENVELOPE;
        +
        +typedef struct pkcs7_signedandenveloped_st
        +	{
        +	ASN1_INTEGER			*version;	/* version 1 */
        +	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
        +	STACK_OF(X509)			*cert;		/* [ 0 ] */
        +	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
        +	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
        +
        +	PKCS7_ENC_CONTENT		*enc_data;
        +	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
        +	} PKCS7_SIGN_ENVELOPE;
        +
        +typedef struct pkcs7_digest_st
        +	{
        +	ASN1_INTEGER			*version;	/* version 0 */
        +	X509_ALGOR			*md;		/* md used */
        +	struct pkcs7_st 		*contents;
        +	ASN1_OCTET_STRING		*digest;
        +	} PKCS7_DIGEST;
        +
        +typedef struct pkcs7_encrypted_st
        +	{
        +	ASN1_INTEGER			*version;	/* version 0 */
        +	PKCS7_ENC_CONTENT		*enc_data;
        +	} PKCS7_ENCRYPT;
        +
        +typedef struct pkcs7_st
        +	{
        +	/* The following is non NULL if it contains ASN1 encoding of
        +	 * this structure */
        +	unsigned char *asn1;
        +	long length;
        +
        +#define PKCS7_S_HEADER	0
        +#define PKCS7_S_BODY	1
        +#define PKCS7_S_TAIL	2
        +	int state; /* used during processing */
        +
        +	int detached;
        +
        +	ASN1_OBJECT *type;
        +	/* content as defined by the type */
        +	/* all encryption/message digests are applied to the 'contents',
        +	 * leaving out the 'type' field. */
        +	union	{
        +		char *ptr;
        +
        +		/* NID_pkcs7_data */
        +		ASN1_OCTET_STRING *data;
        +
        +		/* NID_pkcs7_signed */
        +		PKCS7_SIGNED *sign;
        +
        +		/* NID_pkcs7_enveloped */
        +		PKCS7_ENVELOPE *enveloped;
        +
        +		/* NID_pkcs7_signedAndEnveloped */
        +		PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
        +
        +		/* NID_pkcs7_digest */
        +		PKCS7_DIGEST *digest;
        +
        +		/* NID_pkcs7_encrypted */
        +		PKCS7_ENCRYPT *encrypted;
        +
        +		/* Anything else */
        +		ASN1_TYPE *other;
        +		} d;
        +	} PKCS7;
        +
        +DECLARE_STACK_OF(PKCS7)
        +DECLARE_ASN1_SET_OF(PKCS7)
        +DECLARE_PKCS12_STACK_OF(PKCS7)
        +
        +#define PKCS7_OP_SET_DETACHED_SIGNATURE	1
        +#define PKCS7_OP_GET_DETACHED_SIGNATURE	2
        +
        +#define PKCS7_get_signed_attributes(si)	((si)->auth_attr)
        +#define PKCS7_get_attributes(si)	((si)->unauth_attr)
        +
        +#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
        +#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
        +#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
        +#define PKCS7_type_is_signedAndEnveloped(a) \
        +		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
        +#define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
        +#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
        +#define PKCS7_type_is_encrypted(a) \
        +		(OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
        +
        +#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
        +
        +#define PKCS7_set_detached(p,v) \
        +		PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
        +#define PKCS7_get_detached(p) \
        +		PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
        +
        +#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
        +
        +/* S/MIME related flags */
        +
        +#define PKCS7_TEXT		0x1
        +#define PKCS7_NOCERTS		0x2
        +#define PKCS7_NOSIGS		0x4
        +#define PKCS7_NOCHAIN		0x8
        +#define PKCS7_NOINTERN		0x10
        +#define PKCS7_NOVERIFY		0x20
        +#define PKCS7_DETACHED		0x40
        +#define PKCS7_BINARY		0x80
        +#define PKCS7_NOATTR		0x100
        +#define	PKCS7_NOSMIMECAP	0x200
        +#define PKCS7_NOOLDMIMETYPE	0x400
        +#define PKCS7_CRLFEOL		0x800
        +#define PKCS7_STREAM		0x1000
        +#define PKCS7_NOCRL		0x2000
        +#define PKCS7_PARTIAL		0x4000
        +#define PKCS7_REUSE_DIGEST	0x8000
        +
        +/* Flags: for compatibility with older code */
        +
        +#define SMIME_TEXT	PKCS7_TEXT
        +#define SMIME_NOCERTS	PKCS7_NOCERTS
        +#define SMIME_NOSIGS	PKCS7_NOSIGS
        +#define SMIME_NOCHAIN	PKCS7_NOCHAIN
        +#define SMIME_NOINTERN	PKCS7_NOINTERN
        +#define SMIME_NOVERIFY	PKCS7_NOVERIFY
        +#define SMIME_DETACHED	PKCS7_DETACHED
        +#define SMIME_BINARY	PKCS7_BINARY
        +#define SMIME_NOATTR	PKCS7_NOATTR
        +
        +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
        +
        +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
        +	unsigned char *md,unsigned int *len);
        +#ifndef OPENSSL_NO_FP_API
        +PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
        +int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
        +#endif
        +PKCS7 *PKCS7_dup(PKCS7 *p7);
        +PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
        +int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
        +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
        +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
        +
        +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
        +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
        +DECLARE_ASN1_FUNCTIONS(PKCS7)
        +
        +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
        +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
        +
        +DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
        +DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
        +
        +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
        +
        +int PKCS7_set_type(PKCS7 *p7, int type);
        +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
        +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
        +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
        +	const EVP_MD *dgst);
        +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
        +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
        +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
        +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
        +int PKCS7_content_new(PKCS7 *p7, int nid);
        +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
        +	BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); 
        +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
        +								X509 *x509);
        +
        +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
        +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
        +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
        +
        +
        +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
        +	EVP_PKEY *pkey, const EVP_MD *dgst);
        +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
        +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
        +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
        +
        +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
        +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
        +					X509_ALGOR **pdig, X509_ALGOR **psig);
        +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
        +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
        +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
        +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
        +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
        +
        +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
        +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
        +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type,
        +	void *data);
        +int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
        +	void *value);
        +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
        +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
        +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
        +				STACK_OF(X509_ATTRIBUTE) *sk);
        +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
        +
        +
        +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
        +							BIO *data, int flags);
        +
        +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
        +			X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
        +			int flags);
        +
        +int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
        +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
        +					BIO *indata, BIO *out, int flags);
        +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
        +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
        +								int flags);
        +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
        +
        +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
        +			      STACK_OF(X509_ALGOR) *cap);
        +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
        +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
        +
        +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
        +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
        +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
        +				const unsigned char *md, int mdlen);
        +
        +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
        +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
        +
        +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_PKCS7_strings(void);
        +
        +/* Error codes for the PKCS7 functions. */
        +
        +/* Function codes. */
        +#define PKCS7_F_B64_READ_PKCS7				 120
        +#define PKCS7_F_B64_WRITE_PKCS7				 121
        +#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB			 136
        +#define PKCS7_F_I2D_PKCS7_BIO_STREAM			 140
        +#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME		 135
        +#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
        +#define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
        +#define PKCS7_F_PKCS7_ADD_CRL				 101
        +#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
        +#define PKCS7_F_PKCS7_ADD_SIGNATURE			 131
        +#define PKCS7_F_PKCS7_ADD_SIGNER			 103
        +#define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
        +#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST		 138
        +#define PKCS7_F_PKCS7_CTRL				 104
        +#define PKCS7_F_PKCS7_DATADECODE			 112
        +#define PKCS7_F_PKCS7_DATAFINAL				 128
        +#define PKCS7_F_PKCS7_DATAINIT				 105
        +#define PKCS7_F_PKCS7_DATASIGN				 106
        +#define PKCS7_F_PKCS7_DATAVERIFY			 107
        +#define PKCS7_F_PKCS7_DECRYPT				 114
        +#define PKCS7_F_PKCS7_DECRYPT_RINFO			 133
        +#define PKCS7_F_PKCS7_ENCODE_RINFO			 132
        +#define PKCS7_F_PKCS7_ENCRYPT				 115
        +#define PKCS7_F_PKCS7_FINAL				 134
        +#define PKCS7_F_PKCS7_FIND_DIGEST			 127
        +#define PKCS7_F_PKCS7_GET0_SIGNERS			 124
        +#define PKCS7_F_PKCS7_RECIP_INFO_SET			 130
        +#define PKCS7_F_PKCS7_SET_CIPHER			 108
        +#define PKCS7_F_PKCS7_SET_CONTENT			 109
        +#define PKCS7_F_PKCS7_SET_DIGEST			 126
        +#define PKCS7_F_PKCS7_SET_TYPE				 110
        +#define PKCS7_F_PKCS7_SIGN				 116
        +#define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
        +#define PKCS7_F_PKCS7_SIGNER_INFO_SET			 129
        +#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN			 139
        +#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER			 137
        +#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
        +#define PKCS7_F_PKCS7_VERIFY				 117
        +#define PKCS7_F_SMIME_READ_PKCS7			 122
        +#define PKCS7_F_SMIME_TEXT				 123
        +
        +/* Reason codes. */
        +#define PKCS7_R_CERTIFICATE_VERIFY_ERROR		 117
        +#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
        +#define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
        +#define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
        +#define PKCS7_R_CTRL_ERROR				 152
        +#define PKCS7_R_DECODE_ERROR				 130
        +#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
        +#define PKCS7_R_DECRYPT_ERROR				 119
        +#define PKCS7_R_DIGEST_FAILURE				 101
        +#define PKCS7_R_ENCRYPTION_CTRL_FAILURE			 149
        +#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
        +#define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
        +#define PKCS7_R_ERROR_SETTING_CIPHER			 121
        +#define PKCS7_R_INVALID_MIME_TYPE			 131
        +#define PKCS7_R_INVALID_NULL_POINTER			 143
        +#define PKCS7_R_MIME_NO_CONTENT_TYPE			 132
        +#define PKCS7_R_MIME_PARSE_ERROR			 133
        +#define PKCS7_R_MIME_SIG_PARSE_ERROR			 134
        +#define PKCS7_R_MISSING_CERIPEND_INFO			 103
        +#define PKCS7_R_NO_CONTENT				 122
        +#define PKCS7_R_NO_CONTENT_TYPE				 135
        +#define PKCS7_R_NO_DEFAULT_DIGEST			 151
        +#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND		 154
        +#define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
        +#define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
        +#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
        +#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY		 146
        +#define PKCS7_R_NO_SIGNATURES_ON_DATA			 123
        +#define PKCS7_R_NO_SIGNERS				 142
        +#define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
        +#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
        +#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
        +#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR			 153
        +#define PKCS7_R_PKCS7_DATAFINAL				 126
        +#define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
        +#define PKCS7_R_PKCS7_DATASIGN				 145
        +#define PKCS7_R_PKCS7_PARSE_ERROR			 139
        +#define PKCS7_R_PKCS7_SIG_PARSE_ERROR			 140
        +#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
        +#define PKCS7_R_SIGNATURE_FAILURE			 105
        +#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
        +#define PKCS7_R_SIGNING_CTRL_FAILURE			 147
        +#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE	 148
        +#define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
        +#define PKCS7_R_SMIME_TEXT_ERROR			 129
        +#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
        +#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO			 107
        +#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST		 108
        +#define PKCS7_R_UNKNOWN_DIGEST_TYPE			 109
        +#define PKCS7_R_UNKNOWN_OPERATION			 110
        +#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE			 111
        +#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE		 112
        +#define PKCS7_R_WRONG_CONTENT_TYPE			 113
        +#define PKCS7_R_WRONG_PKCS7_TYPE			 114
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/pkcs7err.c b/vendor/openssl/openssl/crypto/pkcs7/pkcs7err.c
        new file mode 100644
        index 000000000..d0af32a26
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/pkcs7err.c
        @@ -0,0 +1,187 @@
        +/* crypto/pkcs7/pkcs7err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/pkcs7.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
        +
        +static ERR_STRING_DATA PKCS7_str_functs[]=
        +	{
        +{ERR_FUNC(PKCS7_F_B64_READ_PKCS7),	"B64_READ_PKCS7"},
        +{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7),	"B64_WRITE_PKCS7"},
        +{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB),	"DO_PKCS7_SIGNED_ATTRIB"},
        +{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM),	"i2d_PKCS7_bio_stream"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME),	"PKCS7_add0_attrib_signing_time"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP),	"PKCS7_add_attrib_smimecap"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE),	"PKCS7_add_certificate"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL),	"PKCS7_add_crl"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO),	"PKCS7_add_recipient_info"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE),	"PKCS7_add_signature"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER),	"PKCS7_add_signer"},
        +{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST),	"PKCS7_BIO_ADD_DIGEST"},
        +{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),	"PKCS7_COPY_EXISTING_DIGEST"},
        +{ERR_FUNC(PKCS7_F_PKCS7_CTRL),	"PKCS7_ctrl"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE),	"PKCS7_dataDecode"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL),	"PKCS7_dataFinal"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DATAINIT),	"PKCS7_dataInit"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN),	"PKCS7_DATASIGN"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY),	"PKCS7_dataVerify"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT),	"PKCS7_decrypt"},
        +{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO),	"PKCS7_DECRYPT_RINFO"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO),	"PKCS7_ENCODE_RINFO"},
        +{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT),	"PKCS7_encrypt"},
        +{ERR_FUNC(PKCS7_F_PKCS7_FINAL),	"PKCS7_final"},
        +{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST),	"PKCS7_FIND_DIGEST"},
        +{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS),	"PKCS7_get0_signers"},
        +{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET),	"PKCS7_RECIP_INFO_set"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER),	"PKCS7_set_cipher"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT),	"PKCS7_set_content"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST),	"PKCS7_set_digest"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE),	"PKCS7_set_type"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SIGN),	"PKCS7_sign"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY),	"PKCS7_signatureVerify"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET),	"PKCS7_SIGNER_INFO_set"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN),	"PKCS7_SIGNER_INFO_sign"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER),	"PKCS7_sign_add_signer"},
        +{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP),	"PKCS7_simple_smimecap"},
        +{ERR_FUNC(PKCS7_F_PKCS7_VERIFY),	"PKCS7_verify"},
        +{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7),	"SMIME_read_PKCS7"},
        +{ERR_FUNC(PKCS7_F_SMIME_TEXT),	"SMIME_text"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA PKCS7_str_reasons[]=
        +	{
        +{ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
        +{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
        +{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
        +{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
        +{ERR_REASON(PKCS7_R_CTRL_ERROR)          ,"ctrl error"},
        +{ERR_REASON(PKCS7_R_DECODE_ERROR)        ,"decode error"},
        +{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
        +{ERR_REASON(PKCS7_R_DECRYPT_ERROR)       ,"decrypt error"},
        +{ERR_REASON(PKCS7_R_DIGEST_FAILURE)      ,"digest failure"},
        +{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE),"encryption ctrl failure"},
        +{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"encryption not supported for this key type"},
        +{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"},
        +{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
        +{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE)   ,"invalid mime type"},
        +{ERR_REASON(PKCS7_R_INVALID_NULL_POINTER),"invalid null pointer"},
        +{ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE),"mime no content type"},
        +{ERR_REASON(PKCS7_R_MIME_PARSE_ERROR)    ,"mime parse error"},
        +{ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR),"mime sig parse error"},
        +{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"},
        +{ERR_REASON(PKCS7_R_NO_CONTENT)          ,"no content"},
        +{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE)     ,"no content type"},
        +{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST)   ,"no default digest"},
        +{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"},
        +{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
        +{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
        +{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
        +{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY),"no recipient matches key"},
        +{ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA),"no signatures on data"},
        +{ERR_REASON(PKCS7_R_NO_SIGNERS)          ,"no signers"},
        +{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
        +{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"},
        +{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
        +{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR),"pkcs7 add signer error"},
        +{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL)     ,"pkcs7 datafinal"},
        +{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"},
        +{ERR_REASON(PKCS7_R_PKCS7_DATASIGN)      ,"pkcs7 datasign"},
        +{ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR)   ,"pkcs7 parse error"},
        +{ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR),"pkcs7 sig parse error"},
        +{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
        +{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE)   ,"signature failure"},
        +{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
        +{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"},
        +{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"},
        +{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
        +{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR)    ,"smime text error"},
        +{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},
        +{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO),"unable to find mem bio"},
        +{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST),"unable to find message digest"},
        +{ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE) ,"unknown digest type"},
        +{ERR_REASON(PKCS7_R_UNKNOWN_OPERATION)   ,"unknown operation"},
        +{ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE),"unsupported cipher type"},
        +{ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
        +{ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE)  ,"wrong content type"},
        +{ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE)    ,"wrong pkcs7 type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_PKCS7_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,PKCS7_str_functs);
        +		ERR_load_strings(0,PKCS7_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/server.pem b/vendor/openssl/openssl/crypto/pkcs7/server.pem
        new file mode 100644
        index 000000000..750aac209
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/server.pem
        @@ -0,0 +1,24 @@
        +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
        +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (512 bit)
        +-----BEGIN CERTIFICATE-----
        +MIIB6TCCAVICAQAwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV
        +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD
        +VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzQ2WhcNOTgwNjA5
        +MTM1NzQ2WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
        +A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl
        +cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP
        +Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2//
        +Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB4TMR2CvacKE9wAsu9jyCX8YiW
        +mgCM+YoP6kt4Zkj2z5IRfm7WrycKsnpnOR+tGeqAjkCeZ6/36o9l91RvPnN1VJ/i
        +xQv2df0KFeMr00IkDdTNAdIWqFkSsZTAY2QAdgenb7MB1joejquYzO2DQIO7+wpH
        +irObpESxAZLySCmPPg==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
        +TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
        +OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
        +gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
        +rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
        +PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
        +vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/sign.c b/vendor/openssl/openssl/crypto/pkcs7/sign.c
        new file mode 100644
        index 000000000..8b59885f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/sign.c
        @@ -0,0 +1,154 @@
        +/* crypto/pkcs7/sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/bio.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	X509 *x509;
        +	EVP_PKEY *pkey;
        +	PKCS7 *p7;
        +	PKCS7_SIGNER_INFO *si;
        +	BIO *in;
        +	BIO *data,*p7bio;
        +	char buf[1024*4];
        +	int i;
        +	int nodetach=0;
        +
        +#ifndef OPENSSL_NO_MD2
        +	EVP_add_digest(EVP_md2());
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +	EVP_add_digest(EVP_md5());
        +#endif
        +#ifndef OPENSSL_NO_SHA1
        +	EVP_add_digest(EVP_sha1());
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +	EVP_add_digest(EVP_mdc2());
        +#endif
        +
        +	data=BIO_new(BIO_s_file());
        +again:
        +	if (argc > 1)
        +		{
        +		if (strcmp(argv[1],"-nd") == 0)
        +			{
        +			nodetach=1;
        +			argv++; argc--;
        +			goto again;
        +			}
        +		if (!BIO_read_filename(data,argv[1]))
        +			goto err;
        +		}
        +	else
        +		BIO_set_fp(data,stdin,BIO_NOCLOSE);
        +
        +	if ((in=BIO_new_file("server.pem","r")) == NULL) goto err;
        +	if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
        +	BIO_reset(in);
        +	if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL) goto err;
        +	BIO_free(in);
        +
        +	p7=PKCS7_new();
        +	PKCS7_set_type(p7,NID_pkcs7_signed);
        +	 
        +	si=PKCS7_add_signature(p7,x509,pkey,EVP_sha1());
        +	if (si == NULL) goto err;
        +
        +	/* If you do this then you get signing time automatically added */
        +	PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT,
        +						OBJ_nid2obj(NID_pkcs7_data));
        +
        +	/* we may want to add more */
        +	PKCS7_add_certificate(p7,x509);
        +
        +	/* Set the content of the signed to 'data' */
        +	PKCS7_content_new(p7,NID_pkcs7_data);
        +
        +	if (!nodetach)
        +		PKCS7_set_detached(p7,1);
        +
        +	if ((p7bio=PKCS7_dataInit(p7,NULL)) == NULL) goto err;
        +
        +	for (;;)
        +		{
        +		i=BIO_read(data,buf,sizeof(buf));
        +		if (i <= 0) break;
        +		BIO_write(p7bio,buf,i);
        +		}
        +
        +	if (!PKCS7_dataFinal(p7,p7bio)) goto err;
        +	BIO_free(p7bio);
        +
        +	PEM_write_PKCS7(stdout,p7);
        +	PKCS7_free(p7);
        +
        +	exit(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	exit(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/3des.pem b/vendor/openssl/openssl/crypto/pkcs7/t/3des.pem
        new file mode 100644
        index 000000000..b2b5081a1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/3des.pem
        @@ -0,0 +1,16 @@
        +-----BEGIN PKCS7-----
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR+MA0GCSqGSIb3DQEBAQUABEC2vXI1xQDW6lUHM3zQ
        +/9uBEBOO5A3TtkrklAXq7v01gsIC21t52qSk36REXY+slhNZ0OQ349tgkTsoETHFLoEwMIHw
        +AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
        +QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR9MA0G
        +CSqGSIb3DQEBAQUABEB8ujxbabxXUYJhopuDm3oDq4JNqX6Io4p3ro+ShqfIndsXTZ1v5a2N
        +WtLLCWlHn/habjBwZ/DgQgcKASbZ7QxNMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
        +oAQIbsL5v1wX98KggAQoAaJ4WHm68fXY1WE5OIjfVBIDpO1K+i8dmKhjnAjrjoyZ9Bwc8rDL
        +lgQg4CXb805h5xl+GfvSwUaHJayte1m2mcOhs3J2YyqbQ+MEIMIiJQccmhO3oDKm36CFvYR8
        +5PjpclVcZyX2ngbwPFMnBAgy0clOAE6UKAAAAAAAAAAAAAA=
        +-----END PKCS7-----
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/3dess.pem b/vendor/openssl/openssl/crypto/pkcs7/t/3dess.pem
        new file mode 100644
        index 000000000..23f013516
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/3dess.pem
        @@ -0,0 +1,32 @@
        +-----BEGIN PKCS7-----
        +MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
        +BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
        +BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
        +ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
        +AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
        +gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
        +ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
        +A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
        +dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
        +hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
        +hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
        +igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
        +syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
        +kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
        +MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
        +TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
        +BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
        +mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
        +8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
        +ggF7MIIBdwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
        +BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
        +REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
        +AgIEfjAJBgUrDgMCGgUAoHowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAbBgkqhkiG9w0B
        +CQ8xDjAMMAoGCCqGSIb3DQMHMBwGCSqGSIb3DQEJBTEPFw05ODA1MTQwMzM5MzdaMCMGCSqG
        +SIb3DQEJBDEWBBQstNMnSV26ba8PapQEDhO21yNFrjANBgkqhkiG9w0BAQEFAARAW9Xb9YXv
        +BfcNkutgFX9Gr8iXhBVsNtGEVrjrpkQwpKa7jHI8SjAlLhk/4RFwDHf+ISB9Np3Z1WDWnLcA
        +9CWR6g==
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/c.pem b/vendor/openssl/openssl/crypto/pkcs7/t/c.pem
        new file mode 100644
        index 000000000..a4b55e321
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/c.pem
        @@ -0,0 +1,48 @@
        +issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
        +subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
        +serial :047D
        +
        +Certificate:
        +    Data:
        +        Version: 3 (0x2)
        +        Serial Number: 1149 (0x47d)
        +        Signature Algorithm: md5withRSAEncryption
        +        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
        +        Validity
        +            Not Before: May 13 05:40:58 1998 GMT
        +            Not After : May 12 05:40:58 2000 GMT
        +        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +                Modulus:
        +                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
        +                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
        +                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
        +                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
        +                    e7:e7:0c:4d:0b
        +                Exponent: 65537 (0x10001)
        +        X509v3 extensions:
        +            Netscape Comment: 
        +                Generated with SSLeay
        +    Signature Algorithm: md5withRSAEncryption
        +        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
        +        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
        +        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
        +        50:74:ad:92:cb:4e:90:e5:fa:7d
        +
        +-----BEGIN CERTIFICATE-----
        +MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
        +MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
        +ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
        +IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
        +NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
        +aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
        +9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
        +lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
        +hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
        +UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
        +4A3ZItobUHStkstOkOX6fQ==
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/ff b/vendor/openssl/openssl/crypto/pkcs7/t/ff
        new file mode 100644
        index 000000000..23f013516
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/ff
        @@ -0,0 +1,32 @@
        +-----BEGIN PKCS7-----
        +MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
        +BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
        +BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
        +ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
        +AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
        +gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
        +ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
        +A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
        +dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
        +hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
        +hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
        +igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
        +syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
        +kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
        +MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
        +TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
        +BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
        +mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
        +8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
        +ggF7MIIBdwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
        +BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
        +REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
        +AgIEfjAJBgUrDgMCGgUAoHowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAbBgkqhkiG9w0B
        +CQ8xDjAMMAoGCCqGSIb3DQMHMBwGCSqGSIb3DQEJBTEPFw05ODA1MTQwMzM5MzdaMCMGCSqG
        +SIb3DQEJBDEWBBQstNMnSV26ba8PapQEDhO21yNFrjANBgkqhkiG9w0BAQEFAARAW9Xb9YXv
        +BfcNkutgFX9Gr8iXhBVsNtGEVrjrpkQwpKa7jHI8SjAlLhk/4RFwDHf+ISB9Np3Z1WDWnLcA
        +9CWR6g==
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-e b/vendor/openssl/openssl/crypto/pkcs7/t/msie-e
        new file mode 100644
        index 000000000..aafae69fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-e
        @@ -0,0 +1,20 @@
        +
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHCMIHMAgEAMHYwYjERMA8GA1UEBxMISW50ZXJuZXQxFzAV
        +BgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5k
        +aXZpZHVhbCBTdWJzY3JpYmVyAhBgQJiC3qfbCbjdj5INYLnKMA0GCSqGSIb3DQEBAQUABECMzu8y
        +wQ/qZbO8cAGMRBF+mPruv3+Dvb9aWNZ2k8njUgqF6mcdhVB2MkGcsG3memRXJBixvMYWVkU3qK4Z
        +VuKsMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UE
        +BxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqG
        +SIb3DQEBAQUABEBcWwYFHJbJGhiztt7lzue3Lc9CH5WAbyR+2BZ3uv+JxZfRs1PuaWPOwRa0Vgs3
        +YwSJoRfxQj2Gk0wFqG1qt6d1MIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQI8vRlP/Nx
        +2iSggASCAZhR5srxyspy7DfomRJ9ff8eMCtaNwEoEx7G25PZRonC57hBvGoScLtEPU3Wp9FEbPN7
        +oJESeC+AqMTyTLNy8aQsyC5s53E9UkoIvg62ekYZBbXZqXsrxx4PhiiX3NH8GVh42phB0Chjw0nK
        +HZeRDmxGY3Cmk+J+l0uVKxbNIfJIKOguLBnhqmnKH/PrnzDt591u0ULy2aTLqRm+4/1Yat/QPb6J
        +eoKGwNPBbS9ogBdrCNCp9ZFg3Xar2AtQHzyTQIfYeH3SRQUpKmRm5U5o9p5emgEdT+ZfJm/J4tSH
        +OmbgAFsbHQakA4MBZ4J5qfDJhOA2g5lWk1hIeu5Dn/AaLRZd0yz3oY0Ieo/erPWx/bCqtBzYbMe9
        +qSFTedKlbc9EGe3opOTdBZVzK8KH3w3zsy5luxKdOUG59YYb5F1IZiWGiDyuo/HuacX+griu5LeD
        +bEzOtZnko+TZXvWIko30fD79j3T4MRRhWXbgj2HKza+4vJ0mzcC/1+GPsJjAEAA/JgIEDU4w6/DI
        +/HQHhLAO3G+9xKD7MvmrzkoAAAAAAAAAAAAA
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-e.pem b/vendor/openssl/openssl/crypto/pkcs7/t/msie-e.pem
        new file mode 100644
        index 000000000..a2a5e24e7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-e.pem
        @@ -0,0 +1,22 @@
        +-----BEGIN PKCS7-----
        +MIAGCSqGSIb3DQEHA6CAMIIDkAIBADGCAcIwgcwCAQAwdjBiMREwDwYDVQQHEwhJ
        +bnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1ZlcmlT
        +aWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXICEGBAmILep9sJ
        +uN2Pkg1gucowDQYJKoZIhvcNAQEBBQAEQIzO7zLBD+pls7xwAYxEEX6Y+u6/f4O9
        +v1pY1naTyeNSCoXqZx2FUHYyQZywbeZ6ZFckGLG8xhZWRTeorhlW4qwwgfACAQAw
        +gZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
        +EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsT
        +GURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBW
        +QUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQFxbBgUclskaGLO23uXO57ctz0If
        +lYBvJH7YFne6/4nFl9GzU+5pY87BFrRWCzdjBImhF/FCPYaTTAWobWq3p3UwggHD
        +BgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgICAKAECPL0ZT/zcdokgIIBmFHmyvHK
        +ynLsN+iZEn19/x4wK1o3ASgTHsbbk9lGicLnuEG8ahJwu0Q9Tdan0URs83ugkRJ4
        +L4CoxPJMs3LxpCzILmzncT1SSgi+DrZ6RhkFtdmpeyvHHg+GKJfc0fwZWHjamEHQ
        +KGPDScodl5EObEZjcKaT4n6XS5UrFs0h8kgo6C4sGeGqacof8+ufMO3n3W7RQvLZ
        +pMupGb7j/Vhq39A9vol6gobA08FtL2iAF2sI0Kn1kWDddqvYC1AfPJNAh9h4fdJF
        +BSkqZGblTmj2nl6aAR1P5l8mb8ni1Ic6ZuAAWxsdBqQDgwFngnmp8MmE4DaDmVaT
        +WEh67kOf8BotFl3TLPehjQh6j96s9bH9sKq0HNhsx72pIVN50qVtz0QZ7eik5N0F
        +lXMrwoffDfOzLmW7Ep05Qbn1hhvkXUhmJYaIPK6j8e5pxf6CuK7kt4NsTM61meSj
        +5Nle9YiSjfR8Pv2PdPgxFGFZduCPYcrNr7i8nSbNwL/X4Y+wmMAQAD8mAgQNTjDr
        +8Mj8dAeEsA7cb73EoPsy+avOSgAAAAA=
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-01 b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-01
        new file mode 100644
        index 000000000..2c93ab646
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-01
        @@ -0,0 +1,62 @@
        +
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxgfMwgfACAQAwgZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYD
        +VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0
        +IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMT
        +EkRFTU8gWkVSTyBWQUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQKvMaW8xh6oF/X+CJivz
        +IZV7yHxlp4O3NHQtWG0A8MOZB+CtKlU7/6g5e/a9Du/TOqxRMqtYRp63pa2Q/mM4IYMwgAYJ
        +KoZIhvcNAQcBMBoGCCqGSIb3DQMCMA4CAgCgBAifz6RvzOPYlKCABIGwxtGA/FLBBRs1wbBP
        +gDCbSG0yCwjJNsFg89/k6xuXo8c5YTwsw8+XlIVq03navpew6XxxzY090rD2OJ0t6HA6GqrI
        +pd8WiSh/Atqn0yfLFmkLqgIAPRfzxUxqUocxLpQsLIFp2YNUGE+yps+UZmIjw/WHfdqrcWTm
        +STSvKuy3UkIJZCkGDBpTvqk4BFaHh4oTXEpgpNY+GKxjf9TDN9GQPqQZR7sgQki4t2g4/Saq
        +Kl4EMISgluk6swdND0tiHY7v5d6YR29ePCl2/STJ98eJpWkEEC22GNNvOy7ru/Rv2He4MgQg
        +optd7sk9MMd9xhJppg7CcH/yDx//HrtgpOcWmn6VxpgECFqon4uXkQtIBIH4PaNclFn7/hLx
        +Pw2VmBGaC0SYF3U1jyN96EBxdjqy8Aa6ByMXYDW5BcfqniD5mYXfw+b81lh1kutxaPaV4YJ9
        +ZlRUW752N7VHo/fG0/fukoe5W9a8kIhgLpygllb/GP4oSF4wM6n1/OgRzZj2IWFiobKO4d/t
        +Mnh+C+PoEVAuFZcxQwi9GqvsK5OoIjVwNx0XcVSOl1TTYS9SwC7ugMBCab73JiruC24pL78Y
        +M+NaIpIQ3On4DokJA2ZHtjBjZIxF4tKA144RvFN6pBd6TVE5XM6KD/Vh9bjSmujtEAfdQ3Te
        +dvKJsbZuu0stErbvWcRy11I328l557EECAJT7d44OJ3rBBBj6bnnx6dDU2SRqp2CEoQaBAhK
        +RBuyhNxkygQIOY9/NhwqAJAECOvX0Zd0DqgoBAjobPpMHhVV3gQQWLU2vEoZ51BwzxdzCmxO
        +wwQI4oKfudaNqoAESKzBNAqv5kGumHOlMKsRfrs7jZCcSaOuEj97pYx08FLEgF23cav39MOQ
        +NUEM1dNU+EYslL4o3RoSHRjUgPU+2t9c0prS9A/bPARIEOP94PynaTNxwHi3VTK7SzuQmgzA
        +4n942E9joSiqsQPlsKAb3sPUaLC3SuUxSjNBgfpvD0bmrA/5h+WZoYXvIogFpwjkSmnFBEie
        +0lh5Ov1aRrvCw5/j3Q/W/4ZtN5U+aeVBJMtA8n0Mxd5kPxHbNVh4oGprZ6wEegV8ht3voyZa
        +mZ5Cyxc8ffMYnM/JJI6/oEYEUEMyyiS5FnYyvxKzfMtyn2lZ2st9nZGNNgMc9N62r5HgNbdD
        +FHuRdKKzV+8kQfuMc3mOPpK1t9TFY+QgrxiB5p6S7VooI97YtP3PbfknszCEBEh4PdXYbbaR
        +3AacN3Q5kYYmWsq3WW6xgrg0mmEGosGvwSQxBBuiXZrxScCa4ivEq05UZwyShePvKduOvnUE
        +2zDO6IXFLZxhTZAESEm9/FovLgGAiJ7iMGmYvsISLJScwG4n+wrSaQNQXizs9N3ykys54wBN
        +d/+BQ4F7pncHhDQ2Dyt5MekB8Y8iNOocUTFCu524vQRIaWCXmXP3vU7D21dp0XnAMzRQJ565
        +JV3aHRoY7XDa4LePa7PP9ywyafOE5yCW7ndqx3J+2JhTDvSFsW8/q3H3iyeFhykuJVS6BFDK
        +6CmKbnyyjOfE2iLGJmTFa905V2KrVDCmlEu/xyGMs80yTyZC+ySzM83FMVvLEQmSzcTNUZVp
        +DfA1kNXbXkPouBXXT6g8r8JCRljaKKABmgRIlMheOJQRUUU4cgvhMreXPayhq5Ao4VMSCkA5
        +hYRCBczm4Di/MMohF0SxIsdRY6gY9CPnrBXAsY6h1RbR7Tw0iQZmeXi52DCiBEj0by+SYMAa
        +9z0CReIzl8JLL6EVIFz8kFxlkGWjr4dnOzhhPOq/mCpp0WxbavDfdhE87MdXJZBnLwoT62QG
        +955HlAoEQBOGJbcESCgd5XSirZ9Y3AbCfuKOqoMBvEUGn+w/pMaqnGvnr5FZhuBDKrhRXqtx
        +QsxA//drGUxsrZOuSL/0+fbvo7n2h1Z8Ny86jOvVZAQIAjw2l1Yc5RAESNc9i3I8pKEOVQf/
        +UBczJ0NR9aTEF80dRg2lpXwD0ho4N0AvSiVbgxC7cPZHQwIqvq9LHRUs/4n+Vu3SVYU3cAxo
        +lUTiCGUSlARIF+TD57SI5+RI+MNtnD9rs4E1ml51YoHGWFj3UPriDmY0FKEwIgqtMXMY3fZ9
        +Kq8d83bjDzxwbDX7WwR7KbSeJWT42pCz7kM+BEjjPsOnZHuusXT3x2rrsBnYtYsbt98mSFiS
        +KzTtFmXfkOBbCQdit1P76QnYJ1aXMGs6zP6GypQTadK/zYWvlm38QkVwueaJ0woESKW2pqKA
        +70h2UMDHOrpepU1lj0YMzmotDHSTU3L909VvUMNg9uqfrQ6mSkb9j5Tl8oF2otOw5EzA1Yda
        +KPmgsv62RWLYl80wXQRQwG0e/mgG75jp9lOhJdVXqcYbQpS9viwVaVkwH+69mu/bQI4gjoEs
        +UYX6O71Re2z+cYhcm9UrK+DXuSFBXQOIlAFxKMW4B0apd6fU84FsZLMESOorXE5OE0A2B2ji
        +J8QI0Exk4hUvWrMNJfUZwFyS7E05xV9ORuX1xmsKqkT4tVR5Nqln4vhvAY860VBoloz0CDkd
        +8seSBEjeMgRI9FvpYuflIeHg9urkwp6N+1f0DrJJhJY9ZQ0HTQhziJmIfvbEjNqCl7hEC28+
        +F8I5tuViLgfSwcFFCvnS6WFoN4X6QdFdqMCbBEjdlI1c+IQGA/IuTDMJYCuQ/v+8BG5ZeWVH
        +icPZmXfRat9eFK1dGKAJef6+Tf9HPuDjSpDyffrifsp7Dc34lmm7GN1+ON3ZMtwEUNm6epb8
        +1RKWjoI7jIKUV/M2p/0eeGSqs4b06KF/VR6dBwsJVL5DpnTsp3MV4j/CAOlRdSPZ5++tsKbM
        +aplk+ceqQtpEFz1MYTtVV4+rlrWaBEA1okJyNZ5/tNOwM7B+XfOZ0xw+uyVi9v4byTZM2Qds
        +J+d3YGYLAugTGHISLqQEerD8/gGK+/SL06b2gNedXPHtBAiBKX+Mdy3wFQQIqE9gVgvrFNUE
        +CKKoTFoMGqnPBAjDPgLCklNfrwQI3Ek1vSq68w8ECBodu2FOZJVkBAgzwjfSr2N9WQQQTCoQ
        +KkAbrS9tnjXn1I3+ZwQIrPx3eINo/YUECIeYWCFskxlYBAiDUdvZXwD3vgQIkEyZbbZWbUUE
        +CH4+odl1Isk3BBj68fkqJ0fKJRWVLWuW/O3VE4BOPKwFlaIECFseVTdDUho8BAj+cOKvV2WA
        +hgQgaXr+wwq+ItblG0Qxz8IVUXX6PV2mIdHwz4SCCvnCsaIECJhBYxdfLI/XBCDswamPn9MR
        +yXi2HVQBineV+GtWVkIoZ2dCLFB9mQRMoAQI0nUR5a5AOJoECA+AunKlAlx8BAi5RtFeF4g1
        +FQQIz/ie+16LlQcECOmNuVg5DXjMBAjH2nkfpXZgWwQIVdLuO/+kuHAECO/5rEHmyI9vBBD4
        +16BU4Rd3YerDQnHtrwOQBCCkho1XxK5Maz8KLCNi20wvcGt8wsIXlj2h5q9ITBq7IgQQvKVY
        +4OfJ7bKbItP2dylwQgQYPIGxwkkbRXNraONYvN19G8UdF35rFOuIBAjf0sKz/618ZQQIxObr
        +xJkRe0sECIC+ssnjEb2NBBBI+XM4OntVWGsRV9Td3sFgBAinGwIroo8O0gQQMGAwgc9PaLaG
        +gBCiwSTrYQQIVHjfCQgOtygEUIoraFoANfhZgIShpOd/RRxFU4/7xZR5tMdGoYz/g0thR0lM
        ++Hi88FtFD4mAh/Oat4Ri8B7bv04aokjN2UHz6nPbHHjZ8zIqpbYTCy043GNZBAhOqjyB2JbD
        +NwQoR23XCYD9x6E20ChHJRXmaHwyMdYXKl5CUxypl7ois+sy2D7jDukS3wQIsTyyPgJi0GsA
        +AAAAAAAAAAAA
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-01.pem b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-01.pem
        new file mode 100644
        index 000000000..9abf00b2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-01.pem
        @@ -0,0 +1,66 @@
        +-----BEGIN PKCS7-----
        +MIAGCSqGSIb3DQEHA6CAMIILyAIBADGB8zCB8AIBADCBmTCBkjELMAkGA1UEBhMC
        +QVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYD
        +VQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
        +TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBAgIEbjANBgkq
        +hkiG9w0BAQEFAARAq8xpbzGHqgX9f4ImK/MhlXvIfGWng7c0dC1YbQDww5kH4K0q
        +VTv/qDl79r0O79M6rFEyq1hGnrelrZD+YzghgzCCCssGCSqGSIb3DQEHATAaBggq
        +hkiG9w0DAjAOAgIAoAQIn8+kb8zj2JSAggqgxtGA/FLBBRs1wbBPgDCbSG0yCwjJ
        +NsFg89/k6xuXo8c5YTwsw8+XlIVq03navpew6XxxzY090rD2OJ0t6HA6GqrIpd8W
        +iSh/Atqn0yfLFmkLqgIAPRfzxUxqUocxLpQsLIFp2YNUGE+yps+UZmIjw/WHfdqr
        +cWTmSTSvKuy3UkIJZCkGDBpTvqk4BFaHh4oTXEpgpNY+GKxjf9TDN9GQPqQZR7sg
        +Qki4t2g4/SaqKl6EoJbpOrMHTQ9LYh2O7+XemEdvXjwpdv0kyffHiaVpBBAtthjT
        +bzsu67v0b9h3uDKim13uyT0wx33GEmmmDsJwf/IPH/8eu2Ck5xaafpXGmFqon4uX
        +kQtIPaNclFn7/hLxPw2VmBGaC0SYF3U1jyN96EBxdjqy8Aa6ByMXYDW5BcfqniD5
        +mYXfw+b81lh1kutxaPaV4YJ9ZlRUW752N7VHo/fG0/fukoe5W9a8kIhgLpygllb/
        +GP4oSF4wM6n1/OgRzZj2IWFiobKO4d/tMnh+C+PoEVAuFZcxQwi9GqvsK5OoIjVw
        +Nx0XcVSOl1TTYS9SwC7ugMBCab73JiruC24pL78YM+NaIpIQ3On4DokJA2ZHtjBj
        +ZIxF4tKA144RvFN6pBd6TVE5XM6KD/Vh9bjSmujtEAfdQ3TedvKJsbZuu0stErbv
        +WcRy11I328l557ECU+3eODid62PpuefHp0NTZJGqnYIShBpKRBuyhNxkyjmPfzYc
        +KgCQ69fRl3QOqCjobPpMHhVV3li1NrxKGedQcM8XcwpsTsPigp+51o2qgKzBNAqv
        +5kGumHOlMKsRfrs7jZCcSaOuEj97pYx08FLEgF23cav39MOQNUEM1dNU+EYslL4o
        +3RoSHRjUgPU+2t9c0prS9A/bPBDj/eD8p2kzccB4t1Uyu0s7kJoMwOJ/eNhPY6Eo
        +qrED5bCgG97D1Giwt0rlMUozQYH6bw9G5qwP+YflmaGF7yKIBacI5EppxZ7SWHk6
        +/VpGu8LDn+PdD9b/hm03lT5p5UEky0DyfQzF3mQ/Eds1WHigamtnrAR6BXyG3e+j
        +JlqZnkLLFzx98xicz8kkjr+gRkMyyiS5FnYyvxKzfMtyn2lZ2st9nZGNNgMc9N62
        +r5HgNbdDFHuRdKKzV+8kQfuMc3mOPpK1t9TFY+QgrxiB5p6S7VooI97YtP3Pbfkn
        +szCEeD3V2G22kdwGnDd0OZGGJlrKt1lusYK4NJphBqLBr8EkMQQbol2a8UnAmuIr
        +xKtOVGcMkoXj7ynbjr51BNswzuiFxS2cYU2QSb38Wi8uAYCInuIwaZi+whIslJzA
        +bif7CtJpA1BeLOz03fKTKznjAE13/4FDgXumdweENDYPK3kx6QHxjyI06hxRMUK7
        +nbi9aWCXmXP3vU7D21dp0XnAMzRQJ565JV3aHRoY7XDa4LePa7PP9ywyafOE5yCW
        +7ndqx3J+2JhTDvSFsW8/q3H3iyeFhykuJVS6yugpim58soznxNoixiZkxWvdOVdi
        +q1QwppRLv8chjLPNMk8mQvskszPNxTFbyxEJks3EzVGVaQ3wNZDV215D6LgV10+o
        +PK/CQkZY2iigAZqUyF44lBFRRThyC+Eyt5c9rKGrkCjhUxIKQDmFhEIFzObgOL8w
        +yiEXRLEix1FjqBj0I+esFcCxjqHVFtHtPDSJBmZ5eLnYMKL0by+SYMAa9z0CReIz
        +l8JLL6EVIFz8kFxlkGWjr4dnOzhhPOq/mCpp0WxbavDfdhE87MdXJZBnLwoT62QG
        +955HlAoEQBOGJbcoHeV0oq2fWNwGwn7ijqqDAbxFBp/sP6TGqpxr56+RWYbgQyq4
        +UV6rcULMQP/3axlMbK2Trki/9Pn276O59odWfDcvOozr1WQCPDaXVhzlENc9i3I8
        +pKEOVQf/UBczJ0NR9aTEF80dRg2lpXwD0ho4N0AvSiVbgxC7cPZHQwIqvq9LHRUs
        +/4n+Vu3SVYU3cAxolUTiCGUSlBfkw+e0iOfkSPjDbZw/a7OBNZpedWKBxlhY91D6
        +4g5mNBShMCIKrTFzGN32fSqvHfN24w88cGw1+1sEeym0niVk+NqQs+5DPuM+w6dk
        +e66xdPfHauuwGdi1ixu33yZIWJIrNO0WZd+Q4FsJB2K3U/vpCdgnVpcwazrM/obK
        +lBNp0r/Nha+WbfxCRXC55onTCqW2pqKA70h2UMDHOrpepU1lj0YMzmotDHSTU3L9
        +09VvUMNg9uqfrQ6mSkb9j5Tl8oF2otOw5EzA1YdaKPmgsv62RWLYl80wXcBtHv5o
        +Bu+Y6fZToSXVV6nGG0KUvb4sFWlZMB/uvZrv20COII6BLFGF+ju9UXts/nGIXJvV
        +Kyvg17khQV0DiJQBcSjFuAdGqXen1POBbGSz6itcTk4TQDYHaOInxAjQTGTiFS9a
        +sw0l9RnAXJLsTTnFX05G5fXGawqqRPi1VHk2qWfi+G8BjzrRUGiWjPQIOR3yx5IE
        +SN4y9FvpYuflIeHg9urkwp6N+1f0DrJJhJY9ZQ0HTQhziJmIfvbEjNqCl7hEC28+
        +F8I5tuViLgfSwcFFCvnS6WFoN4X6QdFdqMCb3ZSNXPiEBgPyLkwzCWArkP7/vARu
        +WXllR4nD2Zl30WrfXhStXRigCXn+vk3/Rz7g40qQ8n364n7Kew3N+JZpuxjdfjjd
        +2TLc2bp6lvzVEpaOgjuMgpRX8zan/R54ZKqzhvTooX9VHp0HCwlUvkOmdOyncxXi
        +P8IA6VF1I9nn762wpsxqmWT5x6pC2kQXPUxhO1VXj6uWtZo1okJyNZ5/tNOwM7B+
        +XfOZ0xw+uyVi9v4byTZM2QdsJ+d3YGYLAugTGHISLqQEerD8/gGK+/SL06b2gNed
        +XPHtgSl/jHct8BWoT2BWC+sU1aKoTFoMGqnPwz4CwpJTX6/cSTW9KrrzDxodu2FO
        +ZJVkM8I30q9jfVlMKhAqQButL22eNefUjf5nrPx3eINo/YWHmFghbJMZWINR29lf
        +APe+kEyZbbZWbUV+PqHZdSLJN/rx+SonR8olFZUta5b87dUTgE48rAWVolseVTdD
        +Uho8/nDir1dlgIZpev7DCr4i1uUbRDHPwhVRdfo9XaYh0fDPhIIK+cKxophBYxdf
        +LI/X7MGpj5/TEcl4th1UAYp3lfhrVlZCKGdnQixQfZkETKDSdRHlrkA4mg+AunKl
        +Alx8uUbRXheINRXP+J77XouVB+mNuVg5DXjMx9p5H6V2YFtV0u47/6S4cO/5rEHm
        +yI9v+NegVOEXd2Hqw0Jx7a8DkKSGjVfErkxrPwosI2LbTC9wa3zCwheWPaHmr0hM
        +GrsivKVY4OfJ7bKbItP2dylwQjyBscJJG0Vza2jjWLzdfRvFHRd+axTriN/SwrP/
        +rXxlxObrxJkRe0uAvrLJ4xG9jUj5czg6e1VYaxFX1N3ewWCnGwIroo8O0jBgMIHP
        +T2i2hoAQosEk62FUeN8JCA63KIoraFoANfhZgIShpOd/RRxFU4/7xZR5tMdGoYz/
        +g0thR0lM+Hi88FtFD4mAh/Oat4Ri8B7bv04aokjN2UHz6nPbHHjZ8zIqpbYTCy04
        +3GNZTqo8gdiWwzdHbdcJgP3HoTbQKEclFeZofDIx1hcqXkJTHKmXuiKz6zLYPuMO
        +6RLfsTyyPgJi0GsAAAAA
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-02 b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-02
        new file mode 100644
        index 000000000..701705596
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-02
        @@ -0,0 +1,90 @@
        +
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHCMIHMAgEAMHYwYjERMA8GA1UEBxMISW50ZXJuZXQxFzAV
        +BgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5k
        +aXZpZHVhbCBTdWJzY3JpYmVyAhBgQJiC3qfbCbjdj5INYLnKMA0GCSqGSIb3DQEBAQUABEACr4tn
        +kSzvo3aIlHfJLGbfokNCV6FjdDP1vQhL+kdXONqcFCEf9ReETCvaHslIr/Wepc5j2hjZselzgqLn
        +rM1ZMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UE
        +BxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqG
        +SIb3DQEBAQUABEBanBxKOvUoRn3DiFY55lly2TPu2Cv+dI/GLrzW6qvnUMZPWGPGaUlPyWLMZrXJ
        +xGXZUiRJKTBwDu91fnodUEK9MIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQImxKZEDWP
        +EuOggASCBACBi1bX/qc3geqFyfRpX7JyIo/g4CDr62GlwvassAGlIO8zJ5Z/UDIIooeV6QS4D4OW
        +PymKd0WXhwcJI0yBcJTWEoxND27LM7CWFJpA07AoxVCRHTOPgm794NynLecNUOqVTFyS4CRuLhVG
        +PAk0nFZG/RE2yMtx4rAkSiVgOexES7wq/xWuoDSSmuTMNQOTbKfkEKqdFLkM/d62gD2wnaph7vKk
        +PPK82wdZP8rF3nUUC5c4ahbNoa8g+5B3tIF/Jz3ZZK3vGLU0IWO+i7W451dna13MglDDjXOeikNl
        +XLsQdAVo0nsjfGu+f66besJojPzysNA+IEZl6gNWUetl9lim4SqrxubUExdS2rmXnXXmEuEW/HC7
        +dlTAeYq5Clqx5id6slhC2C2oegMww3XH9yxHw6OqzvXY6pVPEScEtBMQLgaKFQT+m2SRtbTVFG7c
        +QcnUODyVB1IbpQTF1DHeeOX1W/HfpWZym8dzkti6SCyeumHmqO406xDiIMVKtHOqM86nEHuAMZsr
        +cLy+ey6TEJvR6S4N8QRzng8JJDZDTJXQN6q84aEudsnOrw2KyOVwPpI6ey4qBsHUgQ8kAFy5lsQa
        +WV45h6exgUwbBcKLgPZGFj+OdD2RKJsTb83/UqbJS5Q/lGXhzBlnaYucyJxEprRxbntmcnOEPFJe
        ++tRDUwOTd7qlJljdhIJL+uDcooL9Ahgo6Cwep6tduekv2cSEohJeTE8Dvy34YRhMbLvnFNdmnpNy
        +rNZDYVVxxaKoyd2AfB8NPFZh1VdAYfI3R1QAQ2kXEef5NNIfVQfMzD9akJn4RP+Kv32Qaxm4FrnK
        +xmwRyGJShavIBc2ax+F1r1+NZXuSBHn5vfoRTxOk0ST4dXsw74dnlYUMRaSu4qqUdM9jsXSyeX4Z
        +gQgkR2bkaYO6ezFgenFIa7QWVw8rXZAEZ5aibCxbnY1VE41PYIvhlLdbFJhH9gY22s+fFAuwnzyA
        +SRjC40A9aAEItRlaPStWSGiqlLRgNkBBwdpv2l2YPBd2QzHx6ek6XGrvRJuAC+Nh62rtQKwpNH54
        +YAOHW55maBFW2SQ3TF+cZ6NbbqhCmHTyyR7mcSYc9sXSVDWEhYKQ1iyU870zhHWVpvglZizZetJC
        +ZFjYex3b1ngVdcgargOvpPq9urCKKi2mbkqv/EFpzSWGXkKSpfCG/XfMnEOtkNrB8S06vnk2JcJB
        +OBqJot+uuSH5hOg0vTpxX2DuONJSiWSWyfRE/lTfJJFXwhod7SXclUyXPeSyibcSic2hVAzDmwjD
        +31js/j2k02PI/agPhr3UQ8cMgcNAiaoCKbNaWfn6BGbCAbTchxzUlo2cSJiLlrX2IDZmfXbXmZCo
        +m1smWIG+BIIEALiuAxDb6dWLAYyVBoN9hYI4AiPeZAY9MtvQ6AV8o2/EFm6PvYGXy3Hei5830CH0
        +PBeX7Kdd6ff1y33TW/l5qSkIL1ULTGR7okFfJePHDmq1dFt6/JOMptiQ8WSu7CsJQvZ9VTFXeYFc
        +ZqCPPZc1NrPegNK70Zf9QxWIbDAevJ5KLBf1c6j8pU2/6LnvDY6VjaTvYSgr7vTR8eVzH4Rm77W0
        +iOHxg5VcODv6cGSVyuvbX8UAGo8Cmb58ERDtBDJBQXVpWKLNAuDJ9GX8n2zNkpjZLbPSkcmuhqGa
        +BJBE/BaCTkUQWlY9dIbRtEnxIU1mfbPPdx1Ppa8DqGDjSOsQdKcKYNNZtayEw++EIpmpdBNsKphC
        +fB8UEK2Wkk4ZVW+qyGoi/r0MFsvO1NmSOOZ0o/jy/YHmoeURHhPy97AO3eVTkEAa5CfJEJybmo56
        +7CDw/FwoGAUCgsoz7rlxzMudr/IhHIH+APinncxXlHO2ecvHD9i8DaHGA8tVifgsUhqQoZieULut
        +eF94O5UAxOkv41UZssYTwN4nYrN1QkesZl3BX4ORS4EE30/PQ23ARf3WZptZrCJevGm2ZYzGeh8x
        +g17mCDfiLO+bff4qP/4mC96Pu4ia6j4to5BwKIJS/+DCuoD8WeSKF4pugXQkMUiHdQnNnVP9Sp2O
        +/4ly5mO8JzrQC59V2bnTNBqPhpno8kfJvK5TypPSVC+bTzern3rJ6UceB3srcn9zxKx9GdNydJQj
        +yWjv8ec3n3d1nuQwhz5Q053NBhIjwoGg3Go7LO6i78ZOlpF7dcoAO13NfHLyNjnyHCaiWtVRTct9
        +rLf5vN00urSn8YJngHk1eTKK8nHGIcOg6YdYDOD2nE5XwRijKmieG8Xa3eKRzfbL06GrBQENle6J
        +mC131bp3cRVxpjq+o6RAbGoMm4yICsL4eTarCQrsyHmoPHqr91UHo91avyxU7knWmEhX27ybmsrs
        +8aeZwPHixL14TeyhruCqRVvkf1Ks7P+z8MPUboGNqQe2WLN8ktCGEr15O8MJR/em86G03Jfo4oaw
        +/DVUH5RwLT6acedOGuzMh/2r8BcmemhVQ8/cWvV4YJ0tOW4hzyVHC5hQf8sZ3LzxXLH6Ohnrbprh
        +xvrdbaSdChWZDDP0bCCbxEhkwuBkBeKZrMbwRTP+TPTPYLVTH/CmKLzKh/114tkGkyO3hHS4qExU
        +V39F2Sj4mylx+hD0+20D9pntpNi7htccGlOm6yNM69at/3+kLgJJyoIlaxLcCUYHNMifDt+T3p/t
        +5U4XmD53uUQ6M8dvj/udqPekNSUfse15yrd9pjOt5PcJuqW28q0sFHf9pHIgz3XZFMe5PD7ppw6r
        +S+C6Ir4PrYIEggQA7ZDVtiCm+BbtNNB/UJm79/OQ5mp5bTI0kPmDeycaWTa0Ojpum+c/dpG/iJOB
        +DICj7jHOXSHT7JlGyX6aSFJUltucAnZvwzhPDmdDaIDiKSk85GqgdDWVfGosSCX9Ph/T3WpIxnwf
        +WSDRtIHkWTjly+pe4yy5K6/XISy/L5Zh/fhiI5fjHjgzmlibs2ru4nVw6hBhUvlSSe2BEs5d9h/y
        +NH8Wy3qvb2D3jh7hkepFtZJGNTHp8ZUC7Ns2JIpQYObsaxdI65i3mMOu7fRwI+0/4ejsWhP6KCEi
        +LgwvLg0qM82ma6YB7qHAHboaczRVEffDcJUG4a5uycB0DoZFn+uEaEFyili20hCn4hVfsqUQk2PT
        +8Mo1tSl5e30xI1YJZrRgiJm9nHRX6fLizngP+ILJLPHZsPvlSVIfY+/v/FR8feKOjaGhyGF51BAx
        +aM2NIQ4jMP5/X+U5gQybi0E6u7rroDhaHsKmCMgXqszwXWCpedA/sEbeHpiTC59YlPPSlIOMc9vP
        +Ko/mQCfWy/9icUaIfKQldvkllUxxNkqu6AbIpHVscbAEzSPs5xbQXU8EZNNCDisFnnpY3nQ3eLnl
        +m89saTJxRb7NWHRMlmPv7qgD7uMIq3vdOGA7i5wT9MeoNIgK1/DsgH30s6RWjJy4YyyLmRTXPzbj
        +hbQVpEmiMRbEidIvUx2OjKVxVQIcgtLsa2lvHQ4XL1cpLr5GVtOgy0fMg5OCDUUDsvjgjgLQ3P2U
        +p2nVY5FM6/QpPc5DTLuuR9ekI2/c9Biz09RtcYDUQK2ajdo8h1IyKqHFoB7h48OXxXKKY94DY0TG
        +x6PonB/epj8orAw4QKmm5M0vXYwBOqRymCTHTqOJGObdLx1euFFyqguzHJOU2gAGZI0z9Lg1yRuF
        +yhdPZyuniIcmtLNxRZ1duYHErcAyX56qndmLXt7UVkATai/rIMuoJLfAsUnVuTUS5p7tJM754UZT
        +7lTcXvDJgOUNnBRaIcxC3pxvbrYDJ2iFJ72xkxUP2p74gucqg25XnCVmQuLg6zDDxF6CLuw9isxy
        +Xg4pkneMN//7fpp8GYl9nyZm2yqYYM+jcw0fcVc64L+X4w/gL3H2UMGgxIHSJp7HIG7VKHtXrNyj
        +dPXXPVUsMsAAimqOr0Lr2sZWirfuivLaPTqhbkvG5PF7K3gT80AOIcd/6EIHBy2hZ7ukfjHmdP4L
        +yQOhTQklaKzGHI0mypq0uFLWJOUlZnVrMiLP1xrWkpC8Ro9eo6mfjjQ45z8adC43a47klwTEzvod
        +3rNEFIGJJUEjAN3mbqie7IxoSJknBBJK0D9lZEQ8lZWlq7vuN8JdqPM6xh155jMVsPwjLK6Tzkj5
        +BpRD9Tgm3u6HPQSCBADgkWEN75Mu9TGosXY0xm1k6K6sPv8L949CrLWo4r1I2LA072bTGvQP28Vs
        +hUA76jgcT1ocC++9PoktIK10YCq5w+FfMAQ04KeCXuAdmiY2iAT4Slea61PMCMta3mVGyLUZCLEm
        +P+I0UKR5mlO0fGEcjU9j8TmbjZqxNFqloLsU7oSi7Os0EtYHkdAVrExUyOc/ZDie6fBjdLTmLdCm
        +bE9JNwjlbXypdTZupGgLNhKGDIskUAAMwZYayI6YfSIMkNCeAYTnjOuGZZ1msCXGXsfMBR1sfUIj
        +9UeGjwD8gq+UVVHX/oeoH/m0eJ5ppqi3+nUlgc9DvpYsC/Fg0G2KuYb9B+VJ+a4GMzQSPREoFtQp
        +B9dtLkBb7Ha/hpGWTIdqzW0eAo5llyN8FNvl2Fu2IcLaNmWFO69gLjRKQopp0dvFOuwAVI6fvGDj
        +p1WigoNbFZl8N+iiWmzKOjoG2ZLbez1clZCms/JPJrXhEMMOxWpVzkQyN336VWHmGgMcjaKCGSeA
        +2nnESIGuiCXMrkHlGfabYIsKcHFCo2t13uXyZPf0zSPTkuD0Eh92wqC9pvA3gvrrCUfo9Mn3bs+e
        +KWKmDlpcs8mDn032oIg+zrQhIduMqXVn3evzeVM3B5MBOGMvg51/SXg7R+MC/463juQQEb9IVe/I
        +YGnO//oWm9lw/377Af/qH+FnN02obJw1FvesQIs9e5RHNQykKbO+vmVJQl1nd9DZWrHDNO7/80Yz
        +2hCm7Tws5nSRN2iFlyRaYJHr7ypxkU2rCak2r6ua7XDwu1qU2RT3+qPjT1RuxQ2oTlHyGkKPMZGC
        +Rc+CSWz5aeeCmHZVwdb3nC8YpfsujMiYqygLeuQ82pjKuR7DIKGmnfcOLdv5F+Ek2Wyy0D98iSgk
        ++aoQGYLhL9llU13pn21uRsDY5uGcXiIw1IETFlTdgENEv8futZuJsegrp7fmFXyNoNyFNyypeDrM
        +6ZqR4vKxFjg3tKKeVpkw/W4EAklzMxmNiazGNDBHsnYV3rwPlKa+HeeE2YxnsKwGLCNgRYUXTaJk
        +461vS160z3dvh/mLfdZ7MYCkmO3bNE3ELUDAw7YQkSuo9ujzdFKte9LC34sjg9fOex3ThAg5Y50n
        +wYm4zBmGM7yEqL8O6QgnM6tIDFS9XryDaLNzcGhMWqMvhzO6sC/AA2WfLgwS517Cp03IkJQWqG9q
        +w52+E+GAtpioJfczEhlv9BrhjttdugRSjJrG8SYVYE4zG3Aur5eNBoGaALIOHOtPw8+JovQmIWcF
        +oaJ/WQuglFrWtew51IK6F8RiHAOBVavZOuZcO7tV+5enVfreOd0rX8ZOy4hYmHhmF1hOrrWOn+Ee
        +E0SYKonXN01BM9xMBIIBSLCvNAppnGPTUGjwbMJRg1VJ2KMiBWH5oJp8tyfIAxMuWFdtaLYbRSOD
        +XbOAshPVK8JAY8DQDkzqaCTAkLTfSRAt9yY6SbUpMsRv7xa8nMZNJBJzJT9b/wNjgiOJgaGuJMkV
        +2g/DX2jfP3PrMM/Sbnz7edORXHj1Pa5XTT8nG5MS0FuZgvevdq3o/gVVAz+ZCKOH3ShMzZvfp01l
        +SX5gaJTflmU6cdNwtn2yZ6IScF7OrjUeA9iEoSVR9dQcA+4lB3RAG3LMwcnxXY35D7+PMJzHIZdF
        +cSnq+n03ACY2/E/T31iijRH29rvYHGI+mP/ieYs45iq4fTWo6i1HofeWLdP0fX7xW3XO0/hWYFiw
        +BxKu66whAbRhaib3XJNvetVs25ToYXyiDpjG+cd5rCMei8sGQwTBj9Zeh0URoeMW1inTP0JvCmMU
        +rZgAAAAAAAAAAAAA
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-02.pem b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-02.pem
        new file mode 100644
        index 000000000..279c5d830
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-enc-02.pem
        @@ -0,0 +1,106 @@
        +-----BEGIN PKCS7-----
        +MIAGCSqGSIb3DQEHA6CAMIITQAIBADGCAcIwgcwCAQAwdjBiMREwDwYDVQQHEwhJ
        +bnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1ZlcmlT
        +aWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXICEGBAmILep9sJ
        +uN2Pkg1gucowDQYJKoZIhvcNAQEBBQAEQAKvi2eRLO+jdoiUd8ksZt+iQ0JXoWN0
        +M/W9CEv6R1c42pwUIR/1F4RMK9oeyUiv9Z6lzmPaGNmx6XOCoueszVkwgfACAQAw
        +gZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
        +EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsT
        +GURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBW
        +QUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQFqcHEo69ShGfcOIVjnmWXLZM+7Y
        +K/50j8YuvNbqq+dQxk9YY8ZpSU/JYsxmtcnEZdlSJEkpMHAO73V+eh1QQr0wghFz
        +BgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgICAKAECJsSmRA1jxLjgIIRSIGLVtf+
        +pzeB6oXJ9GlfsnIij+DgIOvrYaXC9qywAaUg7zMnln9QMgiih5XpBLgPg5Y/KYp3
        +RZeHBwkjTIFwlNYSjE0PbsszsJYUmkDTsCjFUJEdM4+Cbv3g3Kct5w1Q6pVMXJLg
        +JG4uFUY8CTScVkb9ETbIy3HisCRKJWA57ERLvCr/Fa6gNJKa5Mw1A5Nsp+QQqp0U
        +uQz93raAPbCdqmHu8qQ88rzbB1k/ysXedRQLlzhqFs2hryD7kHe0gX8nPdlkre8Y
        +tTQhY76LtbjnV2drXcyCUMONc56KQ2VcuxB0BWjSeyN8a75/rpt6wmiM/PKw0D4g
        +RmXqA1ZR62X2WKbhKqvG5tQTF1LauZeddeYS4Rb8cLt2VMB5irkKWrHmJ3qyWELY
        +Lah6AzDDdcf3LEfDo6rO9djqlU8RJwS0ExAuBooVBP6bZJG1tNUUbtxBydQ4PJUH
        +UhulBMXUMd545fVb8d+lZnKbx3OS2LpILJ66Yeao7jTrEOIgxUq0c6ozzqcQe4Ax
        +mytwvL57LpMQm9HpLg3xBHOeDwkkNkNMldA3qrzhoS52yc6vDYrI5XA+kjp7LioG
        +wdSBDyQAXLmWxBpZXjmHp7GBTBsFwouA9kYWP450PZEomxNvzf9SpslLlD+UZeHM
        +GWdpi5zInESmtHFue2Zyc4Q8Ul761ENTA5N3uqUmWN2Egkv64Nyigv0CGCjoLB6n
        +q1256S/ZxISiEl5MTwO/LfhhGExsu+cU12aek3Ks1kNhVXHFoqjJ3YB8Hw08VmHV
        +V0Bh8jdHVABDaRcR5/k00h9VB8zMP1qQmfhE/4q/fZBrGbgWucrGbBHIYlKFq8gF
        +zZrH4XWvX41le5IEefm9+hFPE6TRJPh1ezDvh2eVhQxFpK7iqpR0z2OxdLJ5fhmB
        +CCRHZuRpg7p7MWB6cUhrtBZXDytdkARnlqJsLFudjVUTjU9gi+GUt1sUmEf2Bjba
        +z58UC7CfPIBJGMLjQD1oAQi1GVo9K1ZIaKqUtGA2QEHB2m/aXZg8F3ZDMfHp6Tpc
        +au9Em4AL42Hrau1ArCk0fnhgA4dbnmZoEVbZJDdMX5xno1tuqEKYdPLJHuZxJhz2
        +xdJUNYSFgpDWLJTzvTOEdZWm+CVmLNl60kJkWNh7HdvWeBV1yBquA6+k+r26sIoq
        +LaZuSq/8QWnNJYZeQpKl8Ib9d8ycQ62Q2sHxLTq+eTYlwkE4Gomi3665IfmE6DS9
        +OnFfYO440lKJZJbJ9ET+VN8kkVfCGh3tJdyVTJc95LKJtxKJzaFUDMObCMPfWOz+
        +PaTTY8j9qA+GvdRDxwyBw0CJqgIps1pZ+foEZsIBtNyHHNSWjZxImIuWtfYgNmZ9
        +dteZkKibWyZYgb64rgMQ2+nViwGMlQaDfYWCOAIj3mQGPTLb0OgFfKNvxBZuj72B
        +l8tx3oufN9Ah9DwXl+ynXen39ct901v5eakpCC9VC0xke6JBXyXjxw5qtXRbevyT
        +jKbYkPFkruwrCUL2fVUxV3mBXGagjz2XNTaz3oDSu9GX/UMViGwwHryeSiwX9XOo
        +/KVNv+i57w2OlY2k72EoK+700fHlcx+EZu+1tIjh8YOVXDg7+nBklcrr21/FABqP
        +Apm+fBEQ7QQyQUF1aViizQLgyfRl/J9szZKY2S2z0pHJroahmgSQRPwWgk5FEFpW
        +PXSG0bRJ8SFNZn2zz3cdT6WvA6hg40jrEHSnCmDTWbWshMPvhCKZqXQTbCqYQnwf
        +FBCtlpJOGVVvqshqIv69DBbLztTZkjjmdKP48v2B5qHlER4T8vewDt3lU5BAGuQn
        +yRCcm5qOeuwg8PxcKBgFAoLKM+65cczLna/yIRyB/gD4p53MV5RztnnLxw/YvA2h
        +xgPLVYn4LFIakKGYnlC7rXhfeDuVAMTpL+NVGbLGE8DeJ2KzdUJHrGZdwV+DkUuB
        +BN9Pz0NtwEX91mabWawiXrxptmWMxnofMYNe5gg34izvm33+Kj/+Jgvej7uImuo+
        +LaOQcCiCUv/gwrqA/FnkiheKboF0JDFIh3UJzZ1T/Uqdjv+JcuZjvCc60AufVdm5
        +0zQaj4aZ6PJHybyuU8qT0lQvm083q596yelHHgd7K3J/c8SsfRnTcnSUI8lo7/Hn
        +N593dZ7kMIc+UNOdzQYSI8KBoNxqOyzuou/GTpaRe3XKADtdzXxy8jY58hwmolrV
        +UU3Lfay3+bzdNLq0p/GCZ4B5NXkyivJxxiHDoOmHWAzg9pxOV8EYoyponhvF2t3i
        +kc32y9OhqwUBDZXuiZgtd9W6d3EVcaY6vqOkQGxqDJuMiArC+Hk2qwkK7Mh5qDx6
        +q/dVB6PdWr8sVO5J1phIV9u8m5rK7PGnmcDx4sS9eE3soa7gqkVb5H9SrOz/s/DD
        +1G6BjakHtlizfJLQhhK9eTvDCUf3pvOhtNyX6OKGsPw1VB+UcC0+mnHnThrszIf9
        +q/AXJnpoVUPP3Fr1eGCdLTluIc8lRwuYUH/LGdy88Vyx+joZ626a4cb63W2knQoV
        +mQwz9Gwgm8RIZMLgZAXimazG8EUz/kz0z2C1Ux/wpii8yof9deLZBpMjt4R0uKhM
        +VFd/Rdko+JspcfoQ9PttA/aZ7aTYu4bXHBpTpusjTOvWrf9/pC4CScqCJWsS3AlG
        +BzTInw7fk96f7eVOF5g+d7lEOjPHb4/7naj3pDUlH7Htecq3faYzreT3CbqltvKt
        +LBR3/aRyIM912RTHuTw+6acOq0vguiK+D62C7ZDVtiCm+BbtNNB/UJm79/OQ5mp5
        +bTI0kPmDeycaWTa0Ojpum+c/dpG/iJOBDICj7jHOXSHT7JlGyX6aSFJUltucAnZv
        +wzhPDmdDaIDiKSk85GqgdDWVfGosSCX9Ph/T3WpIxnwfWSDRtIHkWTjly+pe4yy5
        +K6/XISy/L5Zh/fhiI5fjHjgzmlibs2ru4nVw6hBhUvlSSe2BEs5d9h/yNH8Wy3qv
        +b2D3jh7hkepFtZJGNTHp8ZUC7Ns2JIpQYObsaxdI65i3mMOu7fRwI+0/4ejsWhP6
        +KCEiLgwvLg0qM82ma6YB7qHAHboaczRVEffDcJUG4a5uycB0DoZFn+uEaEFyili2
        +0hCn4hVfsqUQk2PT8Mo1tSl5e30xI1YJZrRgiJm9nHRX6fLizngP+ILJLPHZsPvl
        +SVIfY+/v/FR8feKOjaGhyGF51BAxaM2NIQ4jMP5/X+U5gQybi0E6u7rroDhaHsKm
        +CMgXqszwXWCpedA/sEbeHpiTC59YlPPSlIOMc9vPKo/mQCfWy/9icUaIfKQldvkl
        +lUxxNkqu6AbIpHVscbAEzSPs5xbQXU8EZNNCDisFnnpY3nQ3eLnlm89saTJxRb7N
        +WHRMlmPv7qgD7uMIq3vdOGA7i5wT9MeoNIgK1/DsgH30s6RWjJy4YyyLmRTXPzbj
        +hbQVpEmiMRbEidIvUx2OjKVxVQIcgtLsa2lvHQ4XL1cpLr5GVtOgy0fMg5OCDUUD
        +svjgjgLQ3P2Up2nVY5FM6/QpPc5DTLuuR9ekI2/c9Biz09RtcYDUQK2ajdo8h1Iy
        +KqHFoB7h48OXxXKKY94DY0TGx6PonB/epj8orAw4QKmm5M0vXYwBOqRymCTHTqOJ
        +GObdLx1euFFyqguzHJOU2gAGZI0z9Lg1yRuFyhdPZyuniIcmtLNxRZ1duYHErcAy
        +X56qndmLXt7UVkATai/rIMuoJLfAsUnVuTUS5p7tJM754UZT7lTcXvDJgOUNnBRa
        +IcxC3pxvbrYDJ2iFJ72xkxUP2p74gucqg25XnCVmQuLg6zDDxF6CLuw9isxyXg4p
        +kneMN//7fpp8GYl9nyZm2yqYYM+jcw0fcVc64L+X4w/gL3H2UMGgxIHSJp7HIG7V
        +KHtXrNyjdPXXPVUsMsAAimqOr0Lr2sZWirfuivLaPTqhbkvG5PF7K3gT80AOIcd/
        +6EIHBy2hZ7ukfjHmdP4LyQOhTQklaKzGHI0mypq0uFLWJOUlZnVrMiLP1xrWkpC8
        +Ro9eo6mfjjQ45z8adC43a47klwTEzvod3rNEFIGJJUEjAN3mbqie7IxoSJknBBJK
        +0D9lZEQ8lZWlq7vuN8JdqPM6xh155jMVsPwjLK6Tzkj5BpRD9Tgm3u6HPeCRYQ3v
        +ky71MaixdjTGbWTorqw+/wv3j0KstajivUjYsDTvZtMa9A/bxWyFQDvqOBxPWhwL
        +770+iS0grXRgKrnD4V8wBDTgp4Je4B2aJjaIBPhKV5rrU8wIy1reZUbItRkIsSY/
        +4jRQpHmaU7R8YRyNT2PxOZuNmrE0WqWguxTuhKLs6zQS1geR0BWsTFTI5z9kOJ7p
        +8GN0tOYt0KZsT0k3COVtfKl1Nm6kaAs2EoYMiyRQAAzBlhrIjph9IgyQ0J4BhOeM
        +64ZlnWawJcZex8wFHWx9QiP1R4aPAPyCr5RVUdf+h6gf+bR4nmmmqLf6dSWBz0O+
        +liwL8WDQbYq5hv0H5Un5rgYzNBI9ESgW1CkH120uQFvsdr+GkZZMh2rNbR4CjmWX
        +I3wU2+XYW7Yhwto2ZYU7r2AuNEpCimnR28U67ABUjp+8YOOnVaKCg1sVmXw36KJa
        +bMo6OgbZktt7PVyVkKaz8k8mteEQww7FalXORDI3ffpVYeYaAxyNooIZJ4DaecRI
        +ga6IJcyuQeUZ9ptgiwpwcUKja3Xe5fJk9/TNI9OS4PQSH3bCoL2m8DeC+usJR+j0
        +yfduz54pYqYOWlyzyYOfTfagiD7OtCEh24ypdWfd6/N5UzcHkwE4Yy+DnX9JeDtH
        +4wL/jreO5BARv0hV78hgac7/+hab2XD/fvsB/+of4Wc3TahsnDUW96xAiz17lEc1
        +DKQps76+ZUlCXWd30NlascM07v/zRjPaEKbtPCzmdJE3aIWXJFpgkevvKnGRTasJ
        +qTavq5rtcPC7WpTZFPf6o+NPVG7FDahOUfIaQo8xkYJFz4JJbPlp54KYdlXB1vec
        +Lxil+y6MyJirKAt65DzamMq5HsMgoaad9w4t2/kX4STZbLLQP3yJKCT5qhAZguEv
        +2WVTXemfbW5GwNjm4ZxeIjDUgRMWVN2AQ0S/x+61m4mx6Cunt+YVfI2g3IU3LKl4
        +OszpmpHi8rEWODe0op5WmTD9bgQCSXMzGY2JrMY0MEeydhXevA+Upr4d54TZjGew
        +rAYsI2BFhRdNomTjrW9LXrTPd2+H+Yt91nsxgKSY7ds0TcQtQMDDthCRK6j26PN0
        +Uq170sLfiyOD1857HdOECDljnSfBibjMGYYzvISovw7pCCczq0gMVL1evINos3Nw
        +aExaoy+HM7qwL8ADZZ8uDBLnXsKnTciQlBaob2rDnb4T4YC2mKgl9zMSGW/0GuGO
        +2126BFKMmsbxJhVgTjMbcC6vl40GgZoAsg4c60/Dz4mi9CYhZwWhon9ZC6CUWta1
        +7DnUgroXxGIcA4FVq9k65lw7u1X7l6dV+t453Stfxk7LiFiYeGYXWE6utY6f4R4T
        +RJgqidc3TUEz3EywrzQKaZxj01Bo8GzCUYNVSdijIgVh+aCafLcnyAMTLlhXbWi2
        +G0Ujg12zgLIT1SvCQGPA0A5M6mgkwJC030kQLfcmOkm1KTLEb+8WvJzGTSQScyU/
        +W/8DY4IjiYGhriTJFdoPw19o3z9z6zDP0m58+3nTkVx49T2uV00/JxuTEtBbmYL3
        +r3at6P4FVQM/mQijh90oTM2b36dNZUl+YGiU35ZlOnHTcLZ9smeiEnBezq41HgPY
        +hKElUfXUHAPuJQd0QBtyzMHJ8V2N+Q+/jzCcxyGXRXEp6vp9NwAmNvxP099Yoo0R
        +9va72BxiPpj/4nmLOOYquH01qOotR6H3li3T9H1+8Vt1ztP4VmBYsAcSruusIQG0
        +YWom91yTb3rVbNuU6GF8og6YxvnHeawjHovLBkMEwY/WXodFEaHjFtYp0z9Cbwpj
        +FK2YAAAAAA==
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-s-a-e b/vendor/openssl/openssl/crypto/pkcs7/t/msie-s-a-e
        new file mode 100644
        index 000000000..0067794d7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-s-a-e
        @@ -0,0 +1,91 @@
        +
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHCMIHMAgEAMHYwYjERMA8GA1UEBxMISW50ZXJuZXQxFzAV
        +BgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5k
        +aXZpZHVhbCBTdWJzY3JpYmVyAhBgQJiC3qfbCbjdj5INYLnKMA0GCSqGSIb3DQEBAQUABECjscaS
        +G0U299fqiEAgTqTFQBp8Ai6zzjl557cVb3k6z4QZ7CbqBjSXAjLbh5e7S5Hd/FrFcDnxl1Ka06ha
        +VHGPMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UE
        +BxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0GCSqG
        +SIb3DQEBAQUABECsyHXZ1xaiv0UQRvOmVYsaF38AL2XX75wxbCsz5/wOg7g3RP4aicZxaR4sBog0
        +f2G1o9om/hu+A0rIYF/L4/GUMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIAoAQIsozQrnwj
        +cc2ggASCBAAQz/LPoJe/+iYWeTwSebz6Q9UeKZzQ2UWm7GLtEM3s3c9SCvpmkwIRdEhLjWaBJMyI
        +DiL7t1I1vMf9inB8LXgAcIEYkpNScjS8ERA9Ebb7ieNKSBg7w7B8ATHFxLSlDADqRgoZrB1Ctfgf
        +ximp3EgxTgnhtyQhZxXW7kBQyFRwumplrJXOp7albP7IothrOKncw30IJT1fwPxWNMItI9juXF0U
        +CbWVSjPzGBo4+XNXMvUO6MplOQEz/ywEQ9E8OZAQex1Zw9qq5ppsXB2pMsYV5sLJGikukMYKquiz
        +3YK+tN6J8ahLcDUs+VGwqvZi17gpBTlbEP+ZmXJpnO63t1yTEB0V5AZcRKWUOhzlCBM5YUagqNoY
        +cpsmSvOK6bYzkUKOrzWpDCAtGZ/Dvul5dTZZmxs2WpM+iyeHXMxO3huy8K1brPTqt1f1sHhuq1jD
        +1eXedaCjIgUW9qV18vNAQCof/Yb6T/1fxztf/jD7pPLQJ+7LJkKCAEHGcaizpoKqhYcttaEhLq1G
        +O+Ohqf7yFegMdTJ3wwP324w5ZYSU5fLo2Z34/Edf6EGvXyTIqVfAmEBALd6JGVdN5GlYYTxrL+eO
        +P80Z4ao4YKoxwEmRp5bmQsQ8B29QhOFKmC6eiG5B96qLMtp7Zmu1grDNxTd6OXShWVwYARD0/B1P
        +Sy0PAfk9Gb4fAkO9fZJDQYZ7s0mM5iOPEeSR7820TolOb+KfRabLA9d714jsc2jEykKlpP66Bh4j
        +aCsyqJ0uUQcE8SnzrKAqGwgWiCGQpiTa+HBiP6eRlRGOKQj5Y06vcNx6Ija4cGe6+yCN8HV8tCY0
        +okZK98NQCl5t79R/ZB2c3NvBJH+/g3ulU48ikT3tVmDxE3mOZofZyGFEM99P+YCMScLDxTl3hzGy
        +0YkI8U855P7qOAbcFfh2T5n+LSELwLhbkymEfZT917GWTfmypBWMvJx0WHeDhKwQYPdzbKgWETnc
        +yeKasaCW+oLdhBwrd6Ws2r4MA8cwiYXDLbwYmCxJA8VF++8kubF2HJOjSyMBS+QT2PSV/0D9UWoi
        +Vfk7R4OvWBJVvq7nV+lXS0O5igjExxlmx1OaBfg7+Cr/MbK4zVNrKSJn82NnKKt6LC6RaTmvFYay
        +0sDFxQ7Xo+Th6tDNKmKWJt6Kegfjc+qTWJTKb3kL+UI8vS0zTLy1+M/rZ4ekos/JiS5rYIcAswvg
        +58kBgp/0rc6upBeWjBaK5O0aLAeBQfLulo1axWX04OSVKmYeoAltyR6UO9ME3acurQyg7Ta24yqO
        +whi/PrIaEiO7dsWvFtzsshVzBLic02NlAkPkMUzliPYnZHWQglDAVxL5K2qhvK1OFCkQpIgBsBDM
        +6KYRL/mkBIIEALIl927rIkaN37/BQIcxLcSa05YfC0Hl3mxWESt1A0D4lA37A9S8EbYmDfAYlMc0
        +3HhZGdZEtawfpJFyDHzNZceNWBch6nxeNZCY4YFdsbzuGS0RKpwNA9S/czOJ4p9ymBCxuhGepI3U
        +PKbC8C749Www1/wMdAot1n+K7M/PBGR8hWmaH5SS7U3yMwAB1fq2NDjx4ur+Um+MclSdN01MDXzG
        +EO+eAo1pdAY8479234l8dB2YVAhZ1ZlJ4KmbqMKJrGJXnQUEYS6/cTDRjsUocsoW7uGg1ci2GiHa
        +qjlkfpBfie3SdhFW/K8hwAH0HALs56oFN66wUkP/AaJAPfIUNhR6RpHKzZ9zCC42oB2mNawQRMnF
        +ETBl1s/SwMxLKRp7jAfKs4NZxSY6I9z/2dTpzS3tsHMjxVDuxkolvRNWBILEMeL1CBvip2HhmoUw
        +/Sz5NDgyzk1aQLV6DQNJ2RZLMZDRCtSwZSBu6lhhSgTJGazP0+NbqXXC5aQTrqrFIcWyDXz+ADle
        +kszzYM/gSaQTCALTwfDDaU9Ek3xVgW+XBtExtJ3U+0AN3l0j86rUIdIvp6eWdxWQqv9LtpoorKMD
        +KfUc5PYV09Z1JgsT4X51Zzq+74l5dz7udIM7UNbdTpmRm9PDj3TUbGCvNR9hqOEGTLbkvb1ZR24a
        +h6uGRl2znB25IpDAGRhNRb9is/pO2tvHwHTDMOjrgvZG/pNvXgSUxz0pRjUjXIcqBe2X2gcQfeal
        +r8gY76o83WEGL6ODryV9vTQVHt52+izgpYoBZaVlpgqbZl54c+OE0Zxf9RwXwDbcYu5Ku5E0MPL0
        +qUjc0y2+Y6E4P5bAWaZGMGT+ORkyVUzcaWmM/+XlO7PER5wrWlCIMZCX1L/nvioY0q0CKqALn7DJ
        +QU+qenbwrb6uwS7uNZY6V86s0aDYpU7yRyqxC5SbuyNJb02gdxUCgpIscFaMUjMVRml4M4BIjX/b
        +U+HgHoVMUm8SnN9gRcT2izPrgOGVcMTJjfenzoCKoCPo9RjgGMctgB4DvKamErNU7OrilIfuoqzE
        +PNSeP9SPw/zkDmNvMebM499We9CVnsHUWqF00/ZJWoua77+0f1bLS/tmci1JBvIcMo/4SJvgH+KF
        +o0gijP9gqAPd5iCOnpnJlHUqRIym42SmyKEDuzdSwXKjAR6j7uXda39JyMJr8gGzEsu0jYRkAmj1
        +YdiqwKXUcLMkcj1AKeU/PxTUVw0YKsv/rowrPYww3xQUWqNivrXB7GCHE3BzsYNdHsmziaGIXQbA
        ++EBHdkuKrM8BcC+fxhF/l/KUxngsD1E75IcUv8zFDF+sk4CBYHqks9S4JYlcubuizqsILbdGzIMN
        +Z7w34k0XT+sEggQAyzr8MHeIJGsT+AYnZr08PeTbyr01JEoT7lPYT6PzX4F63QKKDl+mB+PwLMzY
        +CXrxZcUmuay6/MV8w/f5T6vQXdoSw5puWodBYwVReYh1IaEN+jiTapm9YBVmcIsJPO6abHowknSV
        +OWSvST0AtAX57fFOTckm+facfBK9s9T1lUUgF44Bh5e8f9qKqfOV44nqdCOEyUm0Dao497ieN4Eg
        +XBLNvOZY9+irMiXjp0lcyFvhrJOczfyCr9EiiaiH1TfSzKGKsf2W84iKn/JH6x2eOo7xjwJ40BQD
        +c6S1cUNEuqBhP6by0FioOXYOKVyifpxk84Eb+F/4CNdTJTvCPwsiegdfsX/Q53DvKVtXp9Ycam5J
        +TmKRHXK/bMHF4ONv3p/O/kn/BqRx+fbbP2eMX8Z1F/ltHKfp6B+06HljUwQLBJs9XtCfqH5Zgdz9
        +gad5WZF5ykFArmHDgeFlgggvbZ7z9vqnjN/TH68TxJzauYQ5vLHQ6wGXik4/4uq7/TqNmhxlQEM4
        +zVkwsn203bUmKLyz+yl1zItDpn5zy1uXfGo99rBdUzdbdE9LmEFPMaFsaHd4a8oDaUroD7FgCbeD
        +JJVld3ac6F8+3QbExPs48OrgA1kI3/UwXr52ldjiYzTLfAGR9BjqNFTw45FUHuMf8TEM5hcHx56w
        +95eKAqraDk28o9k+M2UKpcmrdlWoWzdqVVFeWGpM8x9Y9Nt0lf/4VUQgrXjqTkUCQkJyqTeTeGgH
        +rn3QBk2XAgpxZhaJs3InW0BkAlBmK99cMinUiJeFt5a4p5wPeXrVuh6V9m7Mpl9hzpogg++EZqah
        +fzzNnDgxOZfW342DX052PdgXo0NnkhCk005LvFt6M2mRn0fLgNVfyUZZoOp8cO5ZWbhXXlrhrgUt
        +j2zKPK6Q94Zj4kdXHBGpAkrB8ZQ4EGGODE0Dqusm8WPXzB+9236IMHPU7lFbyjBrFNI7O4jg+qRI
        +Ipi+7tX0FsilqEbmjG+OPwhZXrdqUqyF+rjKQuSRq7lOeDB4c6S2dq4OOny01i5HCbbyc9UvSHRm
        +hOhGqUlzHyHLo3W7j+26V/MhkDXJ+Tx+qfylv4pbliwTteJJj+CZwzjv29qb6lxYi+38Bw10ERap
        +m8UCRFBecVN7xXlcIfyeAl666Vi7EBJZv3EdFNrx1nlLwM65nYya7uj6L7IwJWotIUx8E0XH0/cU
        +xS/dG8bxf9L/8652h5gq3LI+wTNGuEX0DMuz7BGQG+NtgabrZ6SsKGthGa7eULTpz0McWTLRU0y/
        +/tkckpm5pDnXSFbIMskwwjECz82UZBSPpigdN/Pjg5d+0yWu7s3VJxw4ENWPPpzZ+j7sOXmdvn9P
        +O1tQd60EO+3awASCBAAZQvWV3/yJ6FxPttbP+qeURpJoPEZfpN2UYZmd8HqtR0YbaOZ6Rln9nvpd
        +K9fylXdw9z2xeCbjDWUttJB4VqZxGJM8eCTC1VDVyAOsQ5n7SY55dMkQbU+o4Z/4J5m8+wz50BBI
        +LfruL1eZ6/CF6CdvxVRiJ10sXc0Tn2sVMXqkw7Adp1GYoCI9c6VFSFK74+n+y7LVFQ5HBnbQyKJc
        +dvdLOXwZOPaFHC5UNXRmOpcwdPqyXUe+xIsOMYbzdlAnI9eGDNeRDktUa/Rh0CbZCxjmJzoZEYOE
        +ZjsYZlEfp1Kb61t8z4m28hGLEg88T1Ihmxa2HeUWes1RpmgIOP+/2Lb3smj/l/fpSu4gabFgyCAV
        +H5HdCYMScUv8SVu55+tpeO8ELoHHQUXV4rr084O4budzhgNSOPyLGDl5sfDUXiyusPCxS4JVO/KY
        +6V2Qrtg/q2wtmXpEkZnGT+Qi3WDzwt4W81alztnYMP17oGLmxX71KV9OEiMZjI4WaaGt+OOINLtR
        +qefioZ1NI2L1s5M0tybwTsyU9WERM+3pUwXIfJVsbMZRlNaO2OogcHbaR4UWvhOj+3CTG1sThiYQ
        +MxMnp1Rpqx3nhyzqLO3TRrkYvxnA3cdPBn9EeqpgBMg7X3hCiMV3Fl5cj/WOMhtHYgY7BgeCXo46
        +EFVZ4+WroGZ46xGiRDiIblo8bzLd7QCxvukzxy3mUDgsZQ8pds4N28weSUhBk5MAPbfBpRvXUVJx
        +MhKqXucQU1Md1qSGLbuuIQuz9pAGp1JFUx/vEkCgm74daSoVWCZuB+1ZE4f48clvrBj51xMNf8CP
        +EFE7vySzVb6X2H1i5X3Z+Y3DdIcWw4Y2FClfcJk4Mwq8Cq2GALGFEge9YSEE9YmyuU6OFeU0ICon
        +iXAgZ72SM8fBwJPruLFbdsNYKW+oAfmPisXSWMcZmdSbfk0GYv+vKtu3eegSbWw1UsCVtZOh9E5Z
        +uQ83l59CBqO9sV/SFU3WrrJ0qNWxrmXu9nJn5Qf5iCRoFGYNHYHkIG5FS6N00GEDZxGkxmro2d++
        +Adj5LVHc/b1cYWmrux+jEqI8ZK8cyTB0XMbBA/HYbx9NXazr7znP4/Mlv3pZToEcYt+lgLHAArtU
        +AdhybhbLIwNMq0gr6EwtDklBa3ns4Wx/rJU8H7LGs6gV8uqeaSketv+nz+sQhfctxZ1rx+5qzXfy
        +FOQVpO23KDQunBi1Bl9k61Di4q9JWcyADBXPHXJzp7mL8Fk7zdvMAEfuED1phdRm6GgDYoYUs4yQ
        +IrhSjFlWyk7hT8475xk3BIv++obvWSAv/3+pF6A6U2RXDChVmnG0JnPa9wYYtdzBmLfZKBjX+DjD
        +yEMsuhPsCzuN4R6tBIIBWCVRKmKwdkatmpsQBgDw48u0/Arffl5/DRlS9ee+QffFecUitDdCK+kt
        +X5L2fGYrL5g6SltncMIeV1ptx4nuSjC/O944q1KYtqvQiPFWJqEXIRMNbbYOC47sjLza0tEFrimN
        +wxcrWGSzsy5R9beFQ1aHPcMrDWfCoviNRk2qPtxuKIC5Qk2ZuOmJLjCiLwUGEb0/1Mpzv3MqQa7d
        +mRayXg3DZWJPajxNZv6eS357ElMvwGQmqafb2mlQJwWLsg9m9PG7uqEoyrqSc6MiuY+icLEFib9j
        +OfRQrx70rTSKUfTr4MtP0aZZAefjCrpVIyTekhFDOk0Nmx057eonlyGgmGpl5/Uo+t1J1Z11Ya/l
        +bNbfmebRISJeTVW0I8FhseAZMI1GSwp/ludJxSLYOgyRkh+GX134MexNo7O9F1SxLCfWaSG9Fc3s
        +5ify04ua9/t8SGrYZPm/l3MkAAAAAAAAAAAAAA==
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/msie-s-a-e.pem b/vendor/openssl/openssl/crypto/pkcs7/t/msie-s-a-e.pem
        new file mode 100644
        index 000000000..55dbd8f80
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/msie-s-a-e.pem
        @@ -0,0 +1,106 @@
        +-----BEGIN PKCS7-----
        +MIAGCSqGSIb3DQEHA6CAMIITUAIBADGCAcIwgcwCAQAwdjBiMREwDwYDVQQHEwhJ
        +bnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1ZlcmlT
        +aWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXICEGBAmILep9sJ
        +uN2Pkg1gucowDQYJKoZIhvcNAQEBBQAEQKOxxpIbRTb31+qIQCBOpMVAGnwCLrPO
        +OXnntxVveTrPhBnsJuoGNJcCMtuHl7tLkd38WsVwOfGXUprTqFpUcY8wgfACAQAw
        +gZkwgZIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
        +EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsT
        +GURFTU9OU1RSQVRJT04gQU5EIFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBW
        +QUxVRSBDQQICBG4wDQYJKoZIhvcNAQEBBQAEQKzIddnXFqK/RRBG86ZVixoXfwAv
        +ZdfvnDFsKzPn/A6DuDdE/hqJxnFpHiwGiDR/YbWj2ib+G74DSshgX8vj8ZQwghGD
        +BgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgICAKAECLKM0K58I3HNgIIRWBDP8s+g
        +l7/6JhZ5PBJ5vPpD1R4pnNDZRabsYu0Qzezdz1IK+maTAhF0SEuNZoEkzIgOIvu3
        +UjW8x/2KcHwteABwgRiSk1JyNLwRED0RtvuJ40pIGDvDsHwBMcXEtKUMAOpGChms
        +HUK1+B/GKancSDFOCeG3JCFnFdbuQFDIVHC6amWslc6ntqVs/sii2Gs4qdzDfQgl
        +PV/A/FY0wi0j2O5cXRQJtZVKM/MYGjj5c1cy9Q7oymU5ATP/LARD0Tw5kBB7HVnD
        +2qrmmmxcHakyxhXmwskaKS6Qxgqq6LPdgr603onxqEtwNSz5UbCq9mLXuCkFOVsQ
        +/5mZcmmc7re3XJMQHRXkBlxEpZQ6HOUIEzlhRqCo2hhymyZK84rptjORQo6vNakM
        +IC0Zn8O+6Xl1NlmbGzZakz6LJ4dczE7eG7LwrVus9Oq3V/WweG6rWMPV5d51oKMi
        +BRb2pXXy80BAKh/9hvpP/V/HO1/+MPuk8tAn7ssmQoIAQcZxqLOmgqqFhy21oSEu
        +rUY746Gp/vIV6Ax1MnfDA/fbjDllhJTl8ujZnfj8R1/oQa9fJMipV8CYQEAt3okZ
        +V03kaVhhPGsv544/zRnhqjhgqjHASZGnluZCxDwHb1CE4UqYLp6IbkH3qosy2ntm
        +a7WCsM3FN3o5dKFZXBgBEPT8HU9LLQ8B+T0Zvh8CQ719kkNBhnuzSYzmI48R5JHv
        +zbROiU5v4p9FpssD13vXiOxzaMTKQqWk/roGHiNoKzKonS5RBwTxKfOsoCobCBaI
        +IZCmJNr4cGI/p5GVEY4pCPljTq9w3HoiNrhwZ7r7II3wdXy0JjSiRkr3w1AKXm3v
        +1H9kHZzc28Ekf7+De6VTjyKRPe1WYPETeY5mh9nIYUQz30/5gIxJwsPFOXeHMbLR
        +iQjxTznk/uo4BtwV+HZPmf4tIQvAuFuTKYR9lP3XsZZN+bKkFYy8nHRYd4OErBBg
        +93NsqBYROdzJ4pqxoJb6gt2EHCt3pazavgwDxzCJhcMtvBiYLEkDxUX77yS5sXYc
        +k6NLIwFL5BPY9JX/QP1RaiJV+TtHg69YElW+rudX6VdLQ7mKCMTHGWbHU5oF+Dv4
        +Kv8xsrjNU2spImfzY2coq3osLpFpOa8VhrLSwMXFDtej5OHq0M0qYpYm3op6B+Nz
        +6pNYlMpveQv5Qjy9LTNMvLX4z+tnh6Siz8mJLmtghwCzC+DnyQGCn/Stzq6kF5aM
        +Fork7RosB4FB8u6WjVrFZfTg5JUqZh6gCW3JHpQ70wTdpy6tDKDtNrbjKo7CGL8+
        +shoSI7t2xa8W3OyyFXMEuJzTY2UCQ+QxTOWI9idkdZCCUMBXEvkraqG8rU4UKRCk
        +iAGwEMzophEv+aSyJfdu6yJGjd+/wUCHMS3EmtOWHwtB5d5sVhErdQNA+JQN+wPU
        +vBG2Jg3wGJTHNNx4WRnWRLWsH6SRcgx8zWXHjVgXIep8XjWQmOGBXbG87hktESqc
        +DQPUv3MzieKfcpgQsboRnqSN1DymwvAu+PVsMNf8DHQKLdZ/iuzPzwRkfIVpmh+U
        +ku1N8jMAAdX6tjQ48eLq/lJvjHJUnTdNTA18xhDvngKNaXQGPOO/dt+JfHQdmFQI
        +WdWZSeCpm6jCiaxiV50FBGEuv3Ew0Y7FKHLKFu7hoNXIthoh2qo5ZH6QX4nt0nYR
        +VvyvIcAB9BwC7OeqBTeusFJD/wGiQD3yFDYUekaRys2fcwguNqAdpjWsEETJxREw
        +ZdbP0sDMSykae4wHyrODWcUmOiPc/9nU6c0t7bBzI8VQ7sZKJb0TVgSCxDHi9Qgb
        +4qdh4ZqFMP0s+TQ4Ms5NWkC1eg0DSdkWSzGQ0QrUsGUgbupYYUoEyRmsz9PjW6l1
        +wuWkE66qxSHFsg18/gA5XpLM82DP4EmkEwgC08Hww2lPRJN8VYFvlwbRMbSd1PtA
        +Dd5dI/Oq1CHSL6enlncVkKr/S7aaKKyjAyn1HOT2FdPWdSYLE+F+dWc6vu+JeXc+
        +7nSDO1DW3U6ZkZvTw4901GxgrzUfYajhBky25L29WUduGoerhkZds5wduSKQwBkY
        +TUW/YrP6Ttrbx8B0wzDo64L2Rv6Tb14ElMc9KUY1I1yHKgXtl9oHEH3mpa/IGO+q
        +PN1hBi+jg68lfb00FR7edvos4KWKAWWlZaYKm2ZeeHPjhNGcX/UcF8A23GLuSruR
        +NDDy9KlI3NMtvmOhOD+WwFmmRjBk/jkZMlVM3GlpjP/l5TuzxEecK1pQiDGQl9S/
        +574qGNKtAiqgC5+wyUFPqnp28K2+rsEu7jWWOlfOrNGg2KVO8kcqsQuUm7sjSW9N
        +oHcVAoKSLHBWjFIzFUZpeDOASI1/21Ph4B6FTFJvEpzfYEXE9osz64DhlXDEyY33
        +p86AiqAj6PUY4BjHLYAeA7ymphKzVOzq4pSH7qKsxDzUnj/Uj8P85A5jbzHmzOPf
        +VnvQlZ7B1FqhdNP2SVqLmu+/tH9Wy0v7ZnItSQbyHDKP+Eib4B/ihaNIIoz/YKgD
        +3eYgjp6ZyZR1KkSMpuNkpsihA7s3UsFyowEeo+7l3Wt/ScjCa/IBsxLLtI2EZAJo
        +9WHYqsCl1HCzJHI9QCnlPz8U1FcNGCrL/66MKz2MMN8UFFqjYr61wexghxNwc7GD
        +XR7Js4mhiF0GwPhAR3ZLiqzPAXAvn8YRf5fylMZ4LA9RO+SHFL/MxQxfrJOAgWB6
        +pLPUuCWJXLm7os6rCC23RsyDDWe8N+JNF0/ryzr8MHeIJGsT+AYnZr08PeTbyr01
        +JEoT7lPYT6PzX4F63QKKDl+mB+PwLMzYCXrxZcUmuay6/MV8w/f5T6vQXdoSw5pu
        +WodBYwVReYh1IaEN+jiTapm9YBVmcIsJPO6abHowknSVOWSvST0AtAX57fFOTckm
        ++facfBK9s9T1lUUgF44Bh5e8f9qKqfOV44nqdCOEyUm0Dao497ieN4EgXBLNvOZY
        +9+irMiXjp0lcyFvhrJOczfyCr9EiiaiH1TfSzKGKsf2W84iKn/JH6x2eOo7xjwJ4
        +0BQDc6S1cUNEuqBhP6by0FioOXYOKVyifpxk84Eb+F/4CNdTJTvCPwsiegdfsX/Q
        +53DvKVtXp9Ycam5JTmKRHXK/bMHF4ONv3p/O/kn/BqRx+fbbP2eMX8Z1F/ltHKfp
        +6B+06HljUwQLBJs9XtCfqH5Zgdz9gad5WZF5ykFArmHDgeFlgggvbZ7z9vqnjN/T
        +H68TxJzauYQ5vLHQ6wGXik4/4uq7/TqNmhxlQEM4zVkwsn203bUmKLyz+yl1zItD
        +pn5zy1uXfGo99rBdUzdbdE9LmEFPMaFsaHd4a8oDaUroD7FgCbeDJJVld3ac6F8+
        +3QbExPs48OrgA1kI3/UwXr52ldjiYzTLfAGR9BjqNFTw45FUHuMf8TEM5hcHx56w
        +95eKAqraDk28o9k+M2UKpcmrdlWoWzdqVVFeWGpM8x9Y9Nt0lf/4VUQgrXjqTkUC
        +QkJyqTeTeGgHrn3QBk2XAgpxZhaJs3InW0BkAlBmK99cMinUiJeFt5a4p5wPeXrV
        +uh6V9m7Mpl9hzpogg++EZqahfzzNnDgxOZfW342DX052PdgXo0NnkhCk005LvFt6
        +M2mRn0fLgNVfyUZZoOp8cO5ZWbhXXlrhrgUtj2zKPK6Q94Zj4kdXHBGpAkrB8ZQ4
        +EGGODE0Dqusm8WPXzB+9236IMHPU7lFbyjBrFNI7O4jg+qRIIpi+7tX0FsilqEbm
        +jG+OPwhZXrdqUqyF+rjKQuSRq7lOeDB4c6S2dq4OOny01i5HCbbyc9UvSHRmhOhG
        +qUlzHyHLo3W7j+26V/MhkDXJ+Tx+qfylv4pbliwTteJJj+CZwzjv29qb6lxYi+38
        +Bw10ERapm8UCRFBecVN7xXlcIfyeAl666Vi7EBJZv3EdFNrx1nlLwM65nYya7uj6
        +L7IwJWotIUx8E0XH0/cUxS/dG8bxf9L/8652h5gq3LI+wTNGuEX0DMuz7BGQG+Nt
        +gabrZ6SsKGthGa7eULTpz0McWTLRU0y//tkckpm5pDnXSFbIMskwwjECz82UZBSP
        +pigdN/Pjg5d+0yWu7s3VJxw4ENWPPpzZ+j7sOXmdvn9PO1tQd60EO+3awBlC9ZXf
        +/InoXE+21s/6p5RGkmg8Rl+k3ZRhmZ3weq1HRhto5npGWf2e+l0r1/KVd3D3PbF4
        +JuMNZS20kHhWpnEYkzx4JMLVUNXIA6xDmftJjnl0yRBtT6jhn/gnmbz7DPnQEEgt
        ++u4vV5nr8IXoJ2/FVGInXSxdzROfaxUxeqTDsB2nUZigIj1zpUVIUrvj6f7LstUV
        +DkcGdtDIolx290s5fBk49oUcLlQ1dGY6lzB0+rJdR77Eiw4xhvN2UCcj14YM15EO
        +S1Rr9GHQJtkLGOYnOhkRg4RmOxhmUR+nUpvrW3zPibbyEYsSDzxPUiGbFrYd5RZ6
        +zVGmaAg4/7/YtveyaP+X9+lK7iBpsWDIIBUfkd0JgxJxS/xJW7nn62l47wQugcdB
        +RdXiuvTzg7hu53OGA1I4/IsYOXmx8NReLK6w8LFLglU78pjpXZCu2D+rbC2ZekSR
        +mcZP5CLdYPPC3hbzVqXO2dgw/XugYubFfvUpX04SIxmMjhZpoa3444g0u1Gp5+Kh
        +nU0jYvWzkzS3JvBOzJT1YREz7elTBch8lWxsxlGU1o7Y6iBwdtpHhRa+E6P7cJMb
        +WxOGJhAzEyenVGmrHeeHLOos7dNGuRi/GcDdx08Gf0R6qmAEyDtfeEKIxXcWXlyP
        +9Y4yG0diBjsGB4JejjoQVVnj5augZnjrEaJEOIhuWjxvMt3tALG+6TPHLeZQOCxl
        +Dyl2zg3bzB5JSEGTkwA9t8GlG9dRUnEyEqpe5xBTUx3WpIYtu64hC7P2kAanUkVT
        +H+8SQKCbvh1pKhVYJm4H7VkTh/jxyW+sGPnXEw1/wI8QUTu/JLNVvpfYfWLlfdn5
        +jcN0hxbDhjYUKV9wmTgzCrwKrYYAsYUSB71hIQT1ibK5To4V5TQgKieJcCBnvZIz
        +x8HAk+u4sVt2w1gpb6gB+Y+KxdJYxxmZ1Jt+TQZi/68q27d56BJtbDVSwJW1k6H0
        +Tlm5DzeXn0IGo72xX9IVTdausnSo1bGuZe72cmflB/mIJGgUZg0dgeQgbkVLo3TQ
        +YQNnEaTGaujZ374B2PktUdz9vVxhaau7H6MSojxkrxzJMHRcxsED8dhvH01drOvv
        +Oc/j8yW/ellOgRxi36WAscACu1QB2HJuFssjA0yrSCvoTC0OSUFreezhbH+slTwf
        +ssazqBXy6p5pKR62/6fP6xCF9y3FnWvH7mrNd/IU5BWk7bcoNC6cGLUGX2TrUOLi
        +r0lZzIAMFc8dcnOnuYvwWTvN28wAR+4QPWmF1GboaANihhSzjJAiuFKMWVbKTuFP
        +zjvnGTcEi/76hu9ZIC//f6kXoDpTZFcMKFWacbQmc9r3Bhi13MGYt9koGNf4OMPI
        +Qyy6E+wLO43hHq0lUSpisHZGrZqbEAYA8OPLtPwK335efw0ZUvXnvkH3xXnFIrQ3
        +QivpLV+S9nxmKy+YOkpbZ3DCHldabceJ7kowvzveOKtSmLar0IjxViahFyETDW22
        +DguO7Iy82tLRBa4pjcMXK1hks7MuUfW3hUNWhz3DKw1nwqL4jUZNqj7cbiiAuUJN
        +mbjpiS4woi8FBhG9P9TKc79zKkGu3ZkWsl4Nw2ViT2o8TWb+nkt+exJTL8BkJqmn
        +29ppUCcFi7IPZvTxu7qhKMq6knOjIrmPonCxBYm/Yzn0UK8e9K00ilH06+DLT9Gm
        +WQHn4wq6VSMk3pIRQzpNDZsdOe3qJ5choJhqZef1KPrdSdWddWGv5WzW35nm0SEi
        +Xk1VtCPBYbHgGTCNRksKf5bnScUi2DoMkZIfhl9d+DHsTaOzvRdUsSwn1mkhvRXN
        +7OYn8tOLmvf7fEhq2GT5v5dzJAAAAAA=
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/nav-smime b/vendor/openssl/openssl/crypto/pkcs7/t/nav-smime
        new file mode 100644
        index 000000000..6ee4b597a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/nav-smime
        @@ -0,0 +1,157 @@
        +From angela@c2.net.au Thu May 14 13:32:27 1998
        +X-UIDL: 83c94dd550e54329bf9571b72038b8c8
        +Return-Path: angela@c2.net.au
        +Received: from cryptsoft.com (play.cryptsoft.com [203.56.44.3]) by pandora.cryptsoft.com (8.8.3/8.7.3) with ESMTP id NAA27838 for <tjh@cryptsoft.com>; Thu, 14 May 1998 13:32:26 +1000 (EST)
        +Message-ID: <355A6779.4B63E64C@cryptsoft.com>
        +Date: Thu, 14 May 1998 13:39:37 +1000
        +From: Angela van Lent <angela@c2.net.au>
        +X-Mailer: Mozilla 4.03 [en] (Win95; U)
        +MIME-Version: 1.0
        +To: tjh@cryptsoft.com
        +Subject: signed
        +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------ms9A58844C95949ECC78A1C54C"
        +Content-Length: 2604
        +Status: OR
        +
        +This is a cryptographically signed message in MIME format.
        +
        +--------------ms9A58844C95949ECC78A1C54C
        +Content-Type: text/plain; charset=us-ascii
        +Content-Transfer-Encoding: 7bit
        +
        +signed body
        +
        +--------------ms9A58844C95949ECC78A1C54C
        +Content-Type: application/x-pkcs7-signature; name="smime.p7s"
        +Content-Transfer-Encoding: base64
        +Content-Disposition: attachment; filename="smime.p7s"
        +Content-Description: S/MIME Cryptographic Signature
        +
        +MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
        +BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
        +BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
        +ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
        +AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
        +gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
        +ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
        +A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
        +dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
        +hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
        +hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
        +igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
        +syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
        +kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
        +MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
        +TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
        +BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
        +mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
        +8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
        +ggF7MIIBdwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
        +BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
        +REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
        +AgIEfjAJBgUrDgMCGgUAoHowGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAbBgkqhkiG9w0B
        +CQ8xDjAMMAoGCCqGSIb3DQMHMBwGCSqGSIb3DQEJBTEPFw05ODA1MTQwMzM5MzdaMCMGCSqG
        +SIb3DQEJBDEWBBQstNMnSV26ba8PapQEDhO21yNFrjANBgkqhkiG9w0BAQEFAARAW9Xb9YXv
        +BfcNkutgFX9Gr8iXhBVsNtGEVrjrpkQwpKa7jHI8SjAlLhk/4RFwDHf+ISB9Np3Z1WDWnLcA
        +9CWR6g==
        +--------------ms9A58844C95949ECC78A1C54C--
        +
        +
        +From angela@c2.net.au Thu May 14 13:33:16 1998
        +X-UIDL: 8f076c44ff7c5967fd5b00c4588a8731
        +Return-Path: angela@c2.net.au
        +Received: from cryptsoft.com (play.cryptsoft.com [203.56.44.3]) by pandora.cryptsoft.com (8.8.3/8.7.3) with ESMTP id NAA27847 for <tjh@cryptsoft.com>; Thu, 14 May 1998 13:33:15 +1000 (EST)
        +Message-ID: <355A67AB.2AF38806@cryptsoft.com>
        +Date: Thu, 14 May 1998 13:40:27 +1000
        +From: Angela van Lent <angela@c2.net.au>
        +X-Mailer: Mozilla 4.03 [en] (Win95; U)
        +MIME-Version: 1.0
        +To: tjh@cryptsoft.com
        +Subject: signed
        +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------msD7863B84BD61E02C407F2F5E"
        +Content-Length: 2679
        +Status: OR
        +
        +This is a cryptographically signed message in MIME format.
        +
        +--------------msD7863B84BD61E02C407F2F5E
        +Content-Type: text/plain; charset=us-ascii
        +Content-Transfer-Encoding: 7bit
        +
        +signed body 2
        +
        +--------------msD7863B84BD61E02C407F2F5E
        +Content-Type: application/x-pkcs7-signature; name="smime.p7s"
        +Content-Transfer-Encoding: base64
        +Content-Disposition: attachment; filename="smime.p7s"
        +Content-Description: S/MIME Cryptographic Signature
        +
        +MIIGVgYJKoZIhvcNAQcCoIIGRzCCBkMCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
        +BGswggJTMIIB/aADAgECAgIEfjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCQVUxEzAR
        +BgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNv
        +ZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UE
        +AxMSREVNTyBaRVJPIFZBTFVFIENBMB4XDTk4MDUxMzA2MjY1NloXDTAwMDUxMjA2MjY1Nlow
        +gaUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFu
        +ZTEaMBgGA1UEChMRQ3J5cHRzb2Z0IFB0eSBMdGQxEjAQBgNVBAsTCVNNSU1FIDAwMzEZMBcG
        +A1UEAxMQQW5nZWxhIHZhbiBMZWVudDEjMCEGCSqGSIb3DQEJARYUYW5nZWxhQGNyeXB0c29m
        +dC5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAuC3+7dAb2LhuO7gt2cTM8vsNjhG5JfDh
        +hX1Vl/wVGbKEEj0MA6vWEolvefQlxB+EzwCtR0YZ7eEC/T/4JoCyeQIDAQABoygwJjAkBglg
        +hkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EAUnSP
        +igs6TMFISTjw8cBtJYb98czgAVkVFjKyJQwYMH8FbDnCyx6NocM555nsyDstaw8fKR11Khds
        +syd3ikkrhDCCAhAwggG6AgEDMA0GCSqGSIb3DQEBBAUAMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0EwHhcNOTgwMzAzMDc0MTMyWhcNMDgwMjI5MDc0MTMyWjCB
        +kjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5l
        +MRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZREVNT05TVFJBVElPTiBB
        +TkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENBMFwwDQYJKoZIhvcNAQEB
        +BQADSwAwSAJBAL+0E2fLej3FSCwe2A2iRnMuC3z12qHIp6Ky1wo2zZcxft7AI+RfkrWrSGtf
        +mfzBEuPrLdfulncC5Y1pNcM8RTUCAwEAATANBgkqhkiG9w0BAQQFAANBAGSbLMphL6F5pp3s
        +8o0Xyh86FHFdpVOwYx09ELLkuG17V/P9pgIc0Eo/gDMbN+KT3IdgECf8S//pCRA6RrNjcXIx
        +ggGzMIIBrwIBATCBmTCBkjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAP
        +BgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdHNvZnQgUHR5IEx0ZDEiMCAGA1UECxMZ
        +REVNT05TVFJBVElPTiBBTkQgVEVTVElORzEbMBkGA1UEAxMSREVNTyBaRVJPIFZBTFVFIENB
        +AgIEfjAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN
        +AQkFMQ8XDTk4MDUxNDAzNDAyN1owIwYJKoZIhvcNAQkEMRYEFOKcV8mNYJnM8rHQajcSEqJN
        +rwdDMFIGCSqGSIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMAcGBSsO
        +AwIHMA0GCCqGSIb3DQMCAgFAMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABEADPE/N
        +coH+zTFuX5YpolupTKxKK8eEjc48TuADuO8bIHHDE/fEYaWunlwDuTlcFJl1ig0idffPB1qC
        +Zp8SSVVY
        +--------------msD7863B84BD61E02C407F2F5E--
        +
        +
        +From angela@c2.net.au Thu May 14 14:05:32 1998
        +X-UIDL: a7d629b4b9acacaee8b39371b860a32a
        +Return-Path: angela@c2.net.au
        +Received: from cryptsoft.com (play.cryptsoft.com [203.56.44.3]) by pandora.cryptsoft.com (8.8.3/8.7.3) with ESMTP id OAA28033 for <tjh@cryptsoft.com>; Thu, 14 May 1998 14:05:32 +1000 (EST)
        +Message-ID: <355A6F3B.AC385981@cryptsoft.com>
        +Date: Thu, 14 May 1998 14:12:43 +1000
        +From: Angela van Lent <angela@c2.net.au>
        +X-Mailer: Mozilla 4.03 [en] (Win95; U)
        +MIME-Version: 1.0
        +To: tjh@cryptsoft.com
        +Subject: encrypted
        +Content-Type: application/x-pkcs7-mime; name="smime.p7m"
        +Content-Transfer-Encoding: base64
        +Content-Disposition: attachment; filename="smime.p7m"
        +Content-Description: S/MIME Encrypted Message
        +Content-Length: 905
        +Status: OR
        +
        +MIAGCSqGSIb3DQEHA6CAMIACAQAxggHmMIHwAgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEG
        +A1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNUUkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQD
        +ExJERU1PIFpFUk8gVkFMVUUgQ0ECAgR+MA0GCSqGSIb3DQEBAQUABEA92N29Yk39RUY2tIVd
        +exGT2MFX3J6H8LB8aDRJjw7843ALgJ5zXpM5+f80QkAWwEN2A6Pl3VxiCeKLi435zXVyMIHw
        +AgEAMIGZMIGSMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMI
        +QnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29mdCBQdHkgTHRkMSIwIAYDVQQLExlERU1PTlNU
        +UkFUSU9OIEFORCBURVNUSU5HMRswGQYDVQQDExJERU1PIFpFUk8gVkFMVUUgQ0ECAgRuMA0G
        +CSqGSIb3DQEBAQUABECR9IfyHtvnjFmZ8B2oUCEs1vxMsG0u1kxKE4RMPFyDqDCEARq7zXMg
        +nzSUI7Wgv5USSKDqcLRJeW+jvYURv/nJMIAGCSqGSIb3DQEHATAaBggqhkiG9w0DAjAOAgIA
        +oAQIrLqrij2ZMpeggAQoibtn6reRZWuWk5Iv5IAhgitr8EYE4w4ySQ7EMB6mTlBoFpccUMWX
        +BwQgQn1UoWCvYAlhDzURdbui64Dc0rS2wtj+kE/InS6y25EEEPe4NUKaF8/UlE+lo3LtILQE
        +CL3uV8k7m0iqAAAAAAAAAAAAAA==
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/s.pem b/vendor/openssl/openssl/crypto/pkcs7/t/s.pem
        new file mode 100644
        index 000000000..4fa925b18
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/s.pem
        @@ -0,0 +1,57 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
        +mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
        +fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
        +zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
        +p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
        +bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
        +IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
        +-----END RSA PRIVATE KEY-----
        +issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
        +subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
        +serial :047D
        +
        +Certificate:
        +    Data:
        +        Version: 3 (0x2)
        +        Serial Number: 1149 (0x47d)
        +        Signature Algorithm: md5withRSAEncryption
        +        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
        +        Validity
        +            Not Before: May 13 05:40:58 1998 GMT
        +            Not After : May 12 05:40:58 2000 GMT
        +        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +                Modulus:
        +                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
        +                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
        +                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
        +                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
        +                    e7:e7:0c:4d:0b
        +                Exponent: 65537 (0x10001)
        +        X509v3 extensions:
        +            Netscape Comment: 
        +                Generated with SSLeay
        +    Signature Algorithm: md5withRSAEncryption
        +        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
        +        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
        +        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
        +        50:74:ad:92:cb:4e:90:e5:fa:7d
        +
        +-----BEGIN CERTIFICATE-----
        +MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
        +MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
        +ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
        +IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
        +NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
        +aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
        +9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
        +lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
        +hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
        +UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
        +4A3ZItobUHStkstOkOX6fQ==
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/t/server.pem b/vendor/openssl/openssl/crypto/pkcs7/t/server.pem
        new file mode 100644
        index 000000000..989baf870
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/t/server.pem
        @@ -0,0 +1,57 @@
        +issuer :/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=DEMONSTRATION AND TESTING/CN=DEMO ZERO VALUE CA
        +subject:/C=AU/SP=Queensland/L=Brisbane/O=Cryptsoft Pty Ltd/OU=SMIME 003/CN=Information/Email=info@cryptsoft.com
        +serial :047D
        +
        +Certificate:
        +    Data:
        +        Version: 3 (0x2)
        +        Serial Number: 1149 (0x47d)
        +        Signature Algorithm: md5withRSAEncryption
        +        Issuer: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=DEMONSTRATION AND TESTING, CN=DEMO ZERO VALUE CA
        +        Validity
        +            Not Before: May 13 05:40:58 1998 GMT
        +            Not After : May 12 05:40:58 2000 GMT
        +        Subject: C=AU, SP=Queensland, L=Brisbane, O=Cryptsoft Pty Ltd, OU=SMIME 003, CN=Information/Email=info@cryptsoft.com
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +                Modulus:
        +                    00:ad:e7:23:89:ee:0d:87:b7:9c:32:44:4b:95:81:
        +                    73:dd:22:80:4b:2d:c5:60:b8:fe:1e:18:63:ef:dc:
        +                    89:89:22:df:95:3c:7a:db:3d:9a:06:a8:08:d6:29:
        +                    fd:ef:41:09:91:ed:bc:ad:98:f9:f6:28:90:62:6f:
        +                    e7:e7:0c:4d:0b
        +                Exponent: 65537 (0x10001)
        +        X509v3 extensions:
        +            Netscape Comment: 
        +                Generated with SSLeay
        +    Signature Algorithm: md5withRSAEncryption
        +        52:15:ea:88:f4:f0:f9:0b:ef:ce:d5:f8:83:40:61:16:5e:55:
        +        f9:ce:2d:d1:8b:31:5c:03:c6:2d:10:7c:61:d5:5c:0a:42:97:
        +        d1:fd:65:b6:b6:84:a5:39:ec:46:ec:fc:e0:0d:d9:22:da:1b:
        +        50:74:ad:92:cb:4e:90:e5:fa:7d
        +
        +-----BEGIN CERTIFICATE-----
        +MIICTDCCAfagAwIBAgICBH0wDQYJKoZIhvcNAQEEBQAwgZIxCzAJBgNVBAYTAkFV
        +MRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UE
        +ChMRQ3J5cHRzb2Z0IFB0eSBMdGQxIjAgBgNVBAsTGURFTU9OU1RSQVRJT04gQU5E
        +IFRFU1RJTkcxGzAZBgNVBAMTEkRFTU8gWkVSTyBWQUxVRSBDQTAeFw05ODA1MTMw
        +NTQwNThaFw0wMDA1MTIwNTQwNThaMIGeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
        +UXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0c29m
        +dCBQdHkgTHRkMRIwEAYDVQQLEwlTTUlNRSAwMDMxFDASBgNVBAMTC0luZm9ybWF0
        +aW9uMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGNyeXB0c29mdC5jb20wXDANBgkqhkiG
        +9w0BAQEFAANLADBIAkEArecjie4Nh7ecMkRLlYFz3SKASy3FYLj+Hhhj79yJiSLf
        +lTx62z2aBqgI1in970EJke28rZj59iiQYm/n5wxNCwIDAQABoygwJjAkBglghkgB
        +hvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0GCSqGSIb3DQEBBAUAA0EA
        +UhXqiPTw+QvvztX4g0BhFl5V+c4t0YsxXAPGLRB8YdVcCkKX0f1ltraEpTnsRuz8
        +4A3ZItobUHStkstOkOX6fQ==
        +-----END CERTIFICATE-----
        +
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBOgIBAAJBAK3nI4nuDYe3nDJES5WBc90igEstxWC4/h4YY+/ciYki35U8ets9
        +mgaoCNYp/e9BCZHtvK2Y+fYokGJv5+cMTQsCAwEAAQJBAIHpvXvqEcOEoDRRHuIG
        +fkcB4jPHcr9KE9TpxabH6xs9beN6OJnkePXAHwaz5MnUgSnbpOKq+cw8miKjXwe/
        +zVECIQDVLwncT2lRmXarEYHzb+q/0uaSvKhWKKt3kJasLNTrAwIhANDUc/ghut29
        +p3jJYjurzUKuG774/5eLjPLsxPPIZzNZAiA/10hSq41UnGqHLEUIS9m2/EeEZe7b
        +bm567dfRU9OnVQIgDo8ROrZXSchEGbaog5J5r/Fle83uO8l93R3GqVxKXZkCIFfk
        +IPD5PIYQAyyod3hyKKza7ZP4CGY4oOfZetbkSGGG
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/crypto/pkcs7/verify.c b/vendor/openssl/openssl/crypto/pkcs7/verify.c
        new file mode 100644
        index 000000000..b40f26032
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pkcs7/verify.c
        @@ -0,0 +1,263 @@
        +/* crypto/pkcs7/verify.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/bio.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include "example.h"
        +
        +int verify_callback(int ok, X509_STORE_CTX *ctx);
        +
        +BIO *bio_err=NULL;
        +BIO *bio_out=NULL;
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	PKCS7 *p7;
        +	PKCS7_SIGNER_INFO *si;
        +	X509_STORE_CTX cert_ctx;
        +	X509_STORE *cert_store=NULL;
        +	BIO *data,*detached=NULL,*p7bio=NULL;
        +	char buf[1024*4];
        +	char *pp;
        +	int i,printit=0;
        +	STACK_OF(PKCS7_SIGNER_INFO) *sk;
        +
        +	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +	bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
        +#ifndef OPENSSL_NO_MD2
        +	EVP_add_digest(EVP_md2());
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +	EVP_add_digest(EVP_md5());
        +#endif
        +#ifndef OPENSSL_NO_SHA1
        +	EVP_add_digest(EVP_sha1());
        +#endif
        +#ifndef OPENSSL_NO_MDC2
        +	EVP_add_digest(EVP_mdc2());
        +#endif
        +
        +	data=BIO_new(BIO_s_file());
        +
        +	pp=NULL;
        +	while (argc > 1)
        +		{
        +		argc--;
        +		argv++;
        +		if (strcmp(argv[0],"-p") == 0)
        +			{
        +			printit=1;
        +			}
        +		else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
        +			{
        +			detached=BIO_new(BIO_s_file());
        +			if (!BIO_read_filename(detached,argv[1]))
        +				goto err;
        +			argc--;
        +			argv++;
        +			}
        +		else
        +			{
        +			pp=argv[0];
        +			if (!BIO_read_filename(data,argv[0]))
        +				goto err;
        +			}
        +		}
        +
        +	if (pp == NULL)
        +		BIO_set_fp(data,stdin,BIO_NOCLOSE);
        +
        +
        +	/* Load the PKCS7 object from a file */
        +	if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
        +
        +	/* This stuff is being setup for certificate verification.
        +	 * When using SSL, it could be replaced with a 
        +	 * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
        +	cert_store=X509_STORE_new();
        +	X509_STORE_set_default_paths(cert_store);
        +	X509_STORE_load_locations(cert_store,NULL,"../../certs");
        +	X509_STORE_set_verify_cb_func(cert_store,verify_callback);
        +
        +	ERR_clear_error();
        +
        +	/* We need to process the data */
        +	if ((PKCS7_get_detached(p7) || detached))
        +		{
        +		if (detached == NULL)
        +			{
        +			printf("no data to verify the signature on\n");
        +			exit(1);
        +			}
        +		else
        +			p7bio=PKCS7_dataInit(p7,detached);
        +		}
        +	else
        +		{
        +		p7bio=PKCS7_dataInit(p7,NULL);
        +		}
        +
        +	/* We now have to 'read' from p7bio to calculate digests etc. */
        +	for (;;)
        +		{
        +		i=BIO_read(p7bio,buf,sizeof(buf));
        +		/* print it? */
        +		if (i <= 0) break;
        +		}
        +
        +	/* We can now verify signatures */
        +	sk=PKCS7_get_signer_info(p7);
        +	if (sk == NULL)
        +		{
        +		printf("there are no signatures on this data\n");
        +		exit(1);
        +		}
        +
        +	/* Ok, first we need to, for each subject entry, see if we can verify */
        +	for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
        +		{
        +		ASN1_UTCTIME *tm;
        +		char *str1,*str2;
        +		int rc;
        +
        +		si=sk_PKCS7_SIGNER_INFO_value(sk,i);
        +		rc=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
        +		if (rc <= 0)
        +			goto err;
        +		printf("signer info\n");
        +		if ((tm=get_signed_time(si)) != NULL)
        +			{
        +			BIO_printf(bio_out,"Signed time:");
        +			ASN1_UTCTIME_print(bio_out,tm);
        +			ASN1_UTCTIME_free(tm);
        +			BIO_printf(bio_out,"\n");
        +			}
        +		if (get_signed_seq2string(si,&str1,&str2))
        +			{
        +			BIO_printf(bio_out,"String 1 is %s\n",str1);
        +			BIO_printf(bio_out,"String 2 is %s\n",str2);
        +			}
        +
        +		}
        +
        +	X509_STORE_free(cert_store);
        +
        +	printf("done\n");
        +	exit(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	exit(1);
        +	}
        +
        +/* should be X509 * but we can just have them as char *. */
        +int verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	char buf[256];
        +	X509 *err_cert;
        +	int err,depth;
        +
        +	err_cert=X509_STORE_CTX_get_current_cert(ctx);
        +	err=	X509_STORE_CTX_get_error(ctx);
        +	depth=	X509_STORE_CTX_get_error_depth(ctx);
        +
        +	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
        +	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
        +	if (!ok)
        +		{
        +		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
        +			X509_verify_cert_error_string(err));
        +		if (depth < 6)
        +			{
        +			ok=1;
        +			X509_STORE_CTX_set_error(ctx,X509_V_OK);
        +			}
        +		else
        +			{
        +			ok=0;
        +			X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
        +			}
        +		}
        +	switch (ctx->error)
        +		{
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
        +		BIO_printf(bio_err,"issuer= %s\n",buf);
        +		break;
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +		BIO_printf(bio_err,"notBefore=");
        +		ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +		BIO_printf(bio_err,"notAfter=");
        +		ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +		}
        +	BIO_printf(bio_err,"verify return:%d\n",ok);
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ppccap.c b/vendor/openssl/openssl/crypto/ppccap.c
        new file mode 100644
        index 000000000..f71ba66aa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ppccap.c
        @@ -0,0 +1,126 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <setjmp.h>
        +#include <signal.h>
        +#include <unistd.h>
        +#include <crypto.h>
        +#include <openssl/bn.h>
        +
        +#define PPC_FPU64	(1<<0)
        +#define PPC_ALTIVEC	(1<<1)
        +
        +static int OPENSSL_ppccap_P = 0;
        +
        +static sigset_t all_masked;
        +
        +#ifdef OPENSSL_BN_ASM_MONT
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num)
        +	{
        +	int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
        +	int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
        +
        +	if (sizeof(size_t)==4)
        +		{
        +#if (defined(__APPLE__) && defined(__MACH__))
        +		if (num>=8 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64))
        +			return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num);
        +#else
        +		/* boundary of 32 was experimentally determined on
        +		   Linux 2.6.22, might have to be adjusted on AIX... */
        +		if (num>=32 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64))
        +			{
        +			sigset_t oset;
        +			int ret;
        +
        +			sigprocmask(SIG_SETMASK,&all_masked,&oset);
        +			ret=bn_mul_mont_fpu64(rp,ap,bp,np,n0,num);
        +			sigprocmask(SIG_SETMASK,&oset,NULL);
        +
        +			return ret;
        +			}
        +#endif
        +		}
        +	else if ((OPENSSL_ppccap_P&PPC_FPU64))
        +		/* this is a "must" on POWER6, but run-time detection
        +		 * is not implemented yet... */
        +		return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num);
        +
        +	return bn_mul_mont_int(rp,ap,bp,np,n0,num);
        +	}
        +#endif
        +
        +static sigjmp_buf ill_jmp;
        +static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
        +
        +void OPENSSL_ppc64_probe(void);
        +void OPENSSL_altivec_probe(void);
        +
        +void OPENSSL_cpuid_setup(void)
        +	{
        +	char *e;
        +	struct sigaction	ill_oact,ill_act;
        +	sigset_t		oset;
        +	static int trigger=0;
        +
        +	if (trigger) return;
        +	trigger=1;
        + 
        +	sigfillset(&all_masked);
        +	sigdelset(&all_masked,SIGILL);
        +	sigdelset(&all_masked,SIGTRAP);
        +#ifdef SIGEMT
        +	sigdelset(&all_masked,SIGEMT);
        +#endif
        +	sigdelset(&all_masked,SIGFPE);
        +	sigdelset(&all_masked,SIGBUS);
        +	sigdelset(&all_masked,SIGSEGV);
        +
        +	if ((e=getenv("OPENSSL_ppccap")))
        +		{
        +		OPENSSL_ppccap_P=strtoul(e,NULL,0);
        +		return;
        +		}
        +
        +	OPENSSL_ppccap_P = 0;
        +
        +#if defined(_AIX)
        +	if (sizeof(size_t)==4
        +# if defined(_SC_AIX_KERNEL_BITMODE)
        +	    && sysconf(_SC_AIX_KERNEL_BITMODE)!=64
        +# endif
        +	   )
        +		return;
        +#endif
        +
        +	memset(&ill_act,0,sizeof(ill_act));
        +	ill_act.sa_handler = ill_handler;
        +	ill_act.sa_mask    = all_masked;
        +
        +	sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
        +	sigaction(SIGILL,&ill_act,&ill_oact);
        +
        +	if (sizeof(size_t)==4)
        +		{
        +		if (sigsetjmp(ill_jmp,1) == 0)
        +			{
        +			OPENSSL_ppc64_probe();
        +			OPENSSL_ppccap_P |= PPC_FPU64;
        +			}
        +		}
        +	else
        +		{
        +		/*
        +		 * Wanted code detecting POWER6 CPU and setting PPC_FPU64
        +		 */
        +		}
        +
        +	if (sigsetjmp(ill_jmp,1) == 0)
        +		{
        +		OPENSSL_altivec_probe();
        +		OPENSSL_ppccap_P |= PPC_ALTIVEC;
        +		}
        +
        +	sigaction (SIGILL,&ill_oact,NULL);
        +	sigprocmask(SIG_SETMASK,&oset,NULL);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ppccpuid.pl b/vendor/openssl/openssl/crypto/ppccpuid.pl
        new file mode 100644
        index 000000000..4ba736a1d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ppccpuid.pl
        @@ -0,0 +1,132 @@
        +#!/usr/bin/env perl
        +
        +$flavour = shift;
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
        +
        +if ($flavour=~/64/) {
        +    $CMPLI="cmpldi";
        +    $SHRLI="srdi";
        +    $SIGNX="extsw";
        +} else {
        +    $CMPLI="cmplwi";
        +    $SHRLI="srwi";
        +    $SIGNX="mr";
        +}
        +
        +$code=<<___;
        +.machine	"any"
        +.text
        +
        +.globl	.OPENSSL_ppc64_probe
        +.align	4
        +.OPENSSL_ppc64_probe:
        +	fcfid	f1,f1
        +	extrdi	r0,r0,32,0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.globl	.OPENSSL_altivec_probe
        +.align	4
        +.OPENSSL_altivec_probe:
        +	.long	0x10000484	# vor	v0,v0,v0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.globl	.OPENSSL_wipe_cpu
        +.align	4
        +.OPENSSL_wipe_cpu:
        +	xor	r0,r0,r0
        +	fmr	f0,f31
        +	fmr	f1,f31
        +	fmr	f2,f31
        +	mr	r3,r1
        +	fmr	f3,f31
        +	xor	r4,r4,r4
        +	fmr	f4,f31
        +	xor	r5,r5,r5
        +	fmr	f5,f31
        +	xor	r6,r6,r6
        +	fmr	f6,f31
        +	xor	r7,r7,r7
        +	fmr	f7,f31
        +	xor	r8,r8,r8
        +	fmr	f8,f31
        +	xor	r9,r9,r9
        +	fmr	f9,f31
        +	xor	r10,r10,r10
        +	fmr	f10,f31
        +	xor	r11,r11,r11
        +	fmr	f11,f31
        +	xor	r12,r12,r12
        +	fmr	f12,f31
        +	fmr	f13,f31
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.globl	.OPENSSL_atomic_add
        +.align	4
        +.OPENSSL_atomic_add:
        +Ladd:	lwarx	r5,0,r3
        +	add	r0,r4,r5
        +	stwcx.	r0,0,r3
        +	bne-	Ladd
        +	$SIGNX	r3,r0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,2,0
        +	.long	0
        +
        +.globl	.OPENSSL_rdtsc
        +.align	4
        +.OPENSSL_rdtsc:
        +	mftb	r3
        +	mftbu	r4
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +
        +.globl	.OPENSSL_cleanse
        +.align	4
        +.OPENSSL_cleanse:
        +	$CMPLI	r4,7
        +	li	r0,0
        +	bge	Lot
        +	$CMPLI	r4,0
        +	beqlr-
        +Little:	mtctr	r4
        +	stb	r0,0(r3)
        +	addi	r3,r3,1
        +	bdnz	\$-8
        +	blr
        +Lot:	andi.	r5,r3,3
        +	beq	Laligned
        +	stb	r0,0(r3)
        +	subi	r4,r4,1
        +	addi	r3,r3,1
        +	b	Lot
        +Laligned:
        +	$SHRLI	r5,r4,2
        +	mtctr	r5
        +	stw	r0,0(r3)
        +	addi	r3,r3,4
        +	bdnz	\$-8
        +	andi.	r4,r4,3
        +	bne	Little
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,2,0
        +	.long	0
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/pqueue/Makefile b/vendor/openssl/openssl/crypto/pqueue/Makefile
        new file mode 100644
        index 000000000..fb36a0c87
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pqueue/Makefile
        @@ -0,0 +1,83 @@
        +#
        +# OpenSSL/crypto/pqueue/Makefile
        +#
        +
        +DIR=	pqueue
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=pqueue.c
        +LIBOBJ=pqueue.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= pqueue.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +pqueue.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
        +pqueue.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +pqueue.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +pqueue.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +pqueue.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pqueue.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +pqueue.o: ../../include/openssl/symhacks.h ../cryptlib.h pqueue.c pqueue.h
        diff --git a/vendor/openssl/openssl/crypto/pqueue/pq_test.c b/vendor/openssl/openssl/crypto/pqueue/pq_test.c
        new file mode 100644
        index 000000000..8d496dfc6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pqueue/pq_test.c
        @@ -0,0 +1,95 @@
        +/* crypto/pqueue/pq_test.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 "pqueue.h"
        +
        +int
        +main(void)
        +	{
        +	pitem *item;
        +	pqueue pq;
        +
        +	pq = pqueue_new();
        +
        +	item = pitem_new(3, NULL);
        +	pqueue_insert(pq, item);
        +
        +	item = pitem_new(1, NULL);
        +	pqueue_insert(pq, item);
        +
        +	item = pitem_new(2, NULL);
        +	pqueue_insert(pq, item);
        +
        +	item = pqueue_find(pq, 1);
        +	fprintf(stderr, "found %ld\n", item->priority);
        +
        +	item = pqueue_find(pq, 2);
        +	fprintf(stderr, "found %ld\n", item->priority);
        +
        +	item = pqueue_find(pq, 3);
        +	fprintf(stderr, "found %ld\n", item ? item->priority: 0);
        +
        +	pqueue_print(pq);
        +
        +	for(item = pqueue_pop(pq); item != NULL; item = pqueue_pop(pq))
        +		pitem_free(item);
        +
        +	pqueue_free(pq);
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/pqueue/pqueue.c b/vendor/openssl/openssl/crypto/pqueue/pqueue.c
        new file mode 100644
        index 000000000..eab13a125
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pqueue/pqueue.c
        @@ -0,0 +1,252 @@
        +/* crypto/pqueue/pqueue.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <openssl/bn.h>
        +#include "pqueue.h"
        +
        +typedef struct _pqueue
        +	{
        +	pitem *items;
        +	int count;
        +	} pqueue_s;
        +
        +pitem *
        +pitem_new(unsigned char *prio64be, void *data)
        +	{
        +	pitem *item = (pitem *) OPENSSL_malloc(sizeof(pitem));
        +	if (item == NULL) return NULL;
        +
        +	memcpy(item->priority,prio64be,sizeof(item->priority));
        +
        +	item->data = data;
        +	item->next = NULL;
        +
        +	return item;
        +	}
        +
        +void
        +pitem_free(pitem *item)
        +	{
        +	if (item == NULL) return;
        +
        +	OPENSSL_free(item);
        +	}
        +
        +pqueue_s *
        +pqueue_new()
        +	{
        +	pqueue_s *pq = (pqueue_s *) OPENSSL_malloc(sizeof(pqueue_s));
        +	if (pq == NULL) return NULL;
        +
        +	memset(pq, 0x00, sizeof(pqueue_s));
        +	return pq;
        +	}
        +
        +void
        +pqueue_free(pqueue_s *pq)
        +	{
        +	if (pq == NULL) return;
        +
        +	OPENSSL_free(pq);
        +	}
        +
        +pitem *
        +pqueue_insert(pqueue_s *pq, pitem *item)
        +	{
        +	pitem *curr, *next;
        +
        +	if (pq->items == NULL)
        +		{
        +		pq->items = item;
        +		return item;
        +		}
        +
        +	for(curr = NULL, next = pq->items; 
        +		next != NULL;
        +		curr = next, next = next->next)
        +		{
        +		/* we can compare 64-bit value in big-endian encoding
        +		 * with memcmp:-) */
        +		int cmp = memcmp(next->priority, item->priority,8);
        +		if (cmp > 0)		/* next > item */
        +			{
        +			item->next = next;
        +
        +			if (curr == NULL) 
        +				pq->items = item;
        +			else  
        +				curr->next = item;
        +
        +			return item;
        +			}
        +		
        +		else if (cmp == 0)	/* duplicates not allowed */
        +			return NULL;
        +		}
        +
        +	item->next = NULL;
        +	curr->next = item;
        +
        +	return item;
        +	}
        +
        +pitem *
        +pqueue_peek(pqueue_s *pq)
        +	{
        +	return pq->items;
        +	}
        +
        +pitem *
        +pqueue_pop(pqueue_s *pq)
        +	{
        +	pitem *item = pq->items;
        +
        +	if (pq->items != NULL)
        +		pq->items = pq->items->next;
        +
        +	return item;
        +	}
        +
        +pitem *
        +pqueue_find(pqueue_s *pq, unsigned char *prio64be)
        +	{
        +	pitem *next;
        +	pitem *found = NULL;
        +
        +	if ( pq->items == NULL)
        +		return NULL;
        +
        +	for ( next = pq->items; next->next != NULL; next = next->next)
        +		{
        +		if ( memcmp(next->priority, prio64be,8) == 0)
        +			{
        +			found = next;
        +			break;
        +			}
        +		}
        +	
        +	/* check the one last node */
        +	if ( memcmp(next->priority, prio64be,8) ==0)
        +		found = next;
        +
        +	if ( ! found)
        +		return NULL;
        +
        +#if 0 /* find works in peek mode */
        +	if ( prev == NULL)
        +		pq->items = next->next;
        +	else
        +		prev->next = next->next;
        +#endif
        +
        +	return found;
        +	}
        +
        +void
        +pqueue_print(pqueue_s *pq)
        +	{
        +	pitem *item = pq->items;
        +
        +	while(item != NULL)
        +		{
        +		printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n",
        +			item->priority[0],item->priority[1],
        +			item->priority[2],item->priority[3],
        +			item->priority[4],item->priority[5],
        +			item->priority[6],item->priority[7]);
        +		item = item->next;
        +		}
        +	}
        +
        +pitem *
        +pqueue_iterator(pqueue_s *pq)
        +	{
        +	return pqueue_peek(pq);
        +	}
        +
        +pitem *
        +pqueue_next(pitem **item)
        +	{
        +	pitem *ret;
        +
        +	if ( item == NULL || *item == NULL)
        +		return NULL;
        +
        +
        +	/* *item != NULL */
        +	ret = *item;
        +	*item = (*item)->next;
        +
        +	return ret;
        +	}
        +
        +int
        +pqueue_size(pqueue_s *pq)
        +{
        +	pitem *item = pq->items;
        +	int count = 0;
        +	
        +	while(item != NULL)
        +	{
        +		count++;
        +		item = item->next;
        +	}
        +	return count;
        +}
        diff --git a/vendor/openssl/openssl/crypto/pqueue/pqueue.h b/vendor/openssl/openssl/crypto/pqueue/pqueue.h
        new file mode 100644
        index 000000000..87fc9037c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/pqueue/pqueue.h
        @@ -0,0 +1,94 @@
        +/* crypto/pqueue/pqueue.h */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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_PQUEUE_H
        +#define HEADER_PQUEUE_H
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +typedef struct _pqueue *pqueue;
        +
        +typedef struct _pitem
        +	{
        +	unsigned char priority[8]; /* 64-bit value in big-endian encoding */
        +	void *data;
        +	struct _pitem *next;
        +	} pitem;
        +
        +typedef struct _pitem *piterator;
        +
        +pitem *pitem_new(unsigned char *prio64be, void *data);
        +void   pitem_free(pitem *item);
        +
        +pqueue pqueue_new(void);
        +void   pqueue_free(pqueue pq);
        +
        +pitem *pqueue_insert(pqueue pq, pitem *item);
        +pitem *pqueue_peek(pqueue pq);
        +pitem *pqueue_pop(pqueue pq);
        +pitem *pqueue_find(pqueue pq, unsigned char *prio64be);
        +pitem *pqueue_iterator(pqueue pq);
        +pitem *pqueue_next(piterator *iter);
        +
        +void   pqueue_print(pqueue pq);
        +int    pqueue_size(pqueue pq);
        +
        +#endif /* ! HEADER_PQUEUE_H */
        diff --git a/vendor/openssl/openssl/crypto/rand/Makefile b/vendor/openssl/openssl/crypto/rand/Makefile
        new file mode 100644
        index 000000000..27694aa66
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/Makefile
        @@ -0,0 +1,164 @@
        +#
        +# OpenSSL/crypto/rand/Makefile
        +#
        +
        +DIR=	rand
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST= randtest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \
        +	rand_win.c rand_unix.c rand_os2.c rand_nw.c
        +LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \
        +	rand_win.o rand_unix.o rand_os2.o rand_nw.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= rand.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +md_rand.o: ../../e_os.h ../../include/openssl/asn1.h
        +md_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +md_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +md_rand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +md_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +md_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +md_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +md_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +md_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +md_rand.o: md_rand.c rand_lcl.h
        +rand_egd.o: ../../include/openssl/buffer.h ../../include/openssl/e_os2.h
        +rand_egd.o: ../../include/openssl/opensslconf.h
        +rand_egd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +rand_egd.o: rand_egd.c
        +rand_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +rand_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rand_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rand_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rand_err.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rand_err.o: rand_err.c
        +rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rand_lib.o: ../cryptlib.h rand_lib.c
        +rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
        +rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +rand_nw.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rand_nw.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rand_nw.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rand_nw.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rand_nw.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rand_nw.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +rand_nw.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +rand_nw.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h rand_nw.c
        +rand_os2.o: ../../e_os.h ../../include/openssl/asn1.h
        +rand_os2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +rand_os2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rand_os2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rand_os2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rand_os2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rand_os2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rand_os2.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +rand_os2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +rand_os2.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
        +rand_os2.o: rand_os2.c
        +rand_unix.o: ../../e_os.h ../../include/openssl/asn1.h
        +rand_unix.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +rand_unix.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rand_unix.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rand_unix.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rand_unix.o: ../../include/openssl/objects.h
        +rand_unix.o: ../../include/openssl/opensslconf.h
        +rand_unix.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rand_unix.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +rand_unix.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +rand_unix.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
        +rand_unix.o: rand_unix.c
        +rand_win.o: ../../e_os.h ../../include/openssl/asn1.h
        +rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rand_win.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rand_win.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
        +rand_win.o: rand_win.c
        +randfile.o: ../../e_os.h ../../include/openssl/buffer.h
        +randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +randfile.o: ../../include/openssl/opensslconf.h
        +randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +randfile.o: randfile.c
        diff --git a/vendor/openssl/openssl/crypto/rand/md_rand.c b/vendor/openssl/openssl/crypto/rand/md_rand.c
        new file mode 100644
        index 000000000..1e3bcb9bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/md_rand.c
        @@ -0,0 +1,592 @@
        +/* 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-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#define OPENSSL_FIPSEVP
        +
        +#ifdef MD_RAND_DEBUG
        +# ifndef NDEBUG
        +#   define NDEBUG
        +# endif
        +#endif
        +
        +#include <assert.h>
        +#include <stdio.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/rand.h>
        +#include "rand_lcl.h"
        +
        +#include <openssl/err.h>
        +
        +#ifdef BN_DEBUG
        +# define PREDICT
        +#endif
        +
        +/* #define PREDICT	1 */
        +
        +#define STATE_SIZE	1023
        +static int state_num=0,state_index=0;
        +static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
        +static unsigned char md[MD_DIGEST_LENGTH];
        +static long md_count[2]={0,0};
        +static double entropy=0;
        +static int initialized=0;
        +
        +static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
        +                                           * holds CRYPTO_LOCK_RAND
        +                                           * (to prevent double locking) */
        +/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
        +static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
        +
        +
        +#ifdef PREDICT
        +int rand_predictable=0;
        +#endif
        +
        +const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
        +
        +static void ssleay_rand_cleanup(void);
        +static void ssleay_rand_seed(const void *buf, int num);
        +static void ssleay_rand_add(const void *buf, int num, double add_entropy);
        +static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
        +static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
        +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
        +static int ssleay_rand_status(void);
        +
        +RAND_METHOD rand_ssleay_meth={
        +	ssleay_rand_seed,
        +	ssleay_rand_nopseudo_bytes,
        +	ssleay_rand_cleanup,
        +	ssleay_rand_add,
        +	ssleay_rand_pseudo_bytes,
        +	ssleay_rand_status
        +	}; 
        +
        +RAND_METHOD *RAND_SSLeay(void)
        +	{
        +	return(&rand_ssleay_meth);
        +	}
        +
        +static void ssleay_rand_cleanup(void)
        +	{
        +	OPENSSL_cleanse(state,sizeof(state));
        +	state_num=0;
        +	state_index=0;
        +	OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
        +	md_count[0]=0;
        +	md_count[1]=0;
        +	entropy=0;
        +	initialized=0;
        +	}
        +
        +static void ssleay_rand_add(const void *buf, int num, double add)
        +	{
        +	int i,j,k,st_idx;
        +	long md_c[2];
        +	unsigned char local_md[MD_DIGEST_LENGTH];
        +	EVP_MD_CTX m;
        +	int do_not_lock;
        +
        +	/*
        +	 * (Based on the rand(3) manpage)
        +	 *
        +	 * The input is chopped up into units of 20 bytes (or less for
        +	 * the last block).  Each of these blocks is run through the hash
        +	 * function as follows:  The data passed to the hash function
        +	 * is the current 'md', the same number of bytes from the 'state'
        +	 * (the location determined by in incremented looping index) as
        +	 * the current 'block', the new key data 'block', and 'count'
        +	 * (which is incremented after each use).
        +	 * The result of this is kept in 'md' and also xored into the
        +	 * 'state' at the same locations that were used as input into the
        +         * hash function.
        +	 */
        +
        +	/* check if we already have the lock */
        +	if (crypto_lock_rand)
        +		{
        +		CRYPTO_THREADID cur;
        +		CRYPTO_THREADID_current(&cur);
        +		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
        +		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
        +		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
        +		}
        +	else
        +		do_not_lock = 0;
        +
        +	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +	st_idx=state_index;
        +
        +	/* use our own copies of the counters so that even
        +	 * if a concurrent thread seeds with exactly the
        +	 * same data and uses the same subarray there's _some_
        +	 * difference */
        +	md_c[0] = md_count[0];
        +	md_c[1] = md_count[1];
        +
        +	memcpy(local_md, md, sizeof md);
        +
        +	/* state_index <= state_num <= STATE_SIZE */
        +	state_index += num;
        +	if (state_index >= STATE_SIZE)
        +		{
        +		state_index%=STATE_SIZE;
        +		state_num=STATE_SIZE;
        +		}
        +	else if (state_num < STATE_SIZE)	
        +		{
        +		if (state_index > state_num)
        +			state_num=state_index;
        +		}
        +	/* state_index <= state_num <= STATE_SIZE */
        +
        +	/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
        +	 * are what we will use now, but other threads may use them
        +	 * as well */
        +
        +	md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
        +
        +	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +
        +	EVP_MD_CTX_init(&m);
        +	for (i=0; i<num; i+=MD_DIGEST_LENGTH)
        +		{
        +		j=(num-i);
        +		j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
        +
        +		MD_Init(&m);
        +		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
        +		k=(st_idx+j)-STATE_SIZE;
        +		if (k > 0)
        +			{
        +			MD_Update(&m,&(state[st_idx]),j-k);
        +			MD_Update(&m,&(state[0]),k);
        +			}
        +		else
        +			MD_Update(&m,&(state[st_idx]),j);
        +
        +		/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
        +		MD_Update(&m,buf,j);
        +		/* We know that line may cause programs such as
        +		   purify and valgrind to complain about use of
        +		   uninitialized data.  The problem is not, it's
        +		   with the caller.  Removing that line will make
        +		   sure you get really bad randomness and thereby
        +		   other problems such as very insecure keys. */
        +
        +		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
        +		MD_Final(&m,local_md);
        +		md_c[1]++;
        +
        +		buf=(const char *)buf + j;
        +
        +		for (k=0; k<j; k++)
        +			{
        +			/* Parallel threads may interfere with this,
        +			 * but always each byte of the new state is
        +			 * the XOR of some previous value of its
        +			 * and local_md (itermediate values may be lost).
        +			 * Alway using locking could hurt performance more
        +			 * than necessary given that conflicts occur only
        +			 * when the total seeding is longer than the random
        +			 * state. */
        +			state[st_idx++]^=local_md[k];
        +			if (st_idx >= STATE_SIZE)
        +				st_idx=0;
        +			}
        +		}
        +	EVP_MD_CTX_cleanup(&m);
        +
        +	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +	/* Don't just copy back local_md into md -- this could mean that
        +	 * other thread's seeding remains without effect (except for
        +	 * the incremented counter).  By XORing it we keep at least as
        +	 * much entropy as fits into md. */
        +	for (k = 0; k < (int)sizeof(md); k++)
        +		{
        +		md[k] ^= local_md[k];
        +		}
        +	if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
        +	    entropy += add;
        +	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +	
        +#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
        +	assert(md_c[1] == md_count[1]);
        +#endif
        +	}
        +
        +static void ssleay_rand_seed(const void *buf, int num)
        +	{
        +	ssleay_rand_add(buf, num, (double)num);
        +	}
        +
        +static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
        +	{
        +	static volatile int stirred_pool = 0;
        +	int i,j,k,st_num,st_idx;
        +	int num_ceil;
        +	int ok;
        +	long md_c[2];
        +	unsigned char local_md[MD_DIGEST_LENGTH];
        +	EVP_MD_CTX m;
        +#ifndef GETPID_IS_MEANINGLESS
        +	pid_t curr_pid = getpid();
        +#endif
        +	int do_stir_pool = 0;
        +
        +#ifdef PREDICT
        +	if (rand_predictable)
        +		{
        +		static unsigned char val=0;
        +
        +		for (i=0; i<num; i++)
        +			buf[i]=val++;
        +		return(1);
        +		}
        +#endif
        +
        +	if (num <= 0)
        +		return 1;
        +
        +	EVP_MD_CTX_init(&m);
        +	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
        +	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
        +
        +	/*
        +	 * (Based on the rand(3) manpage:)
        +	 *
        +	 * For each group of 10 bytes (or less), we do the following:
        +	 *
        +	 * Input into the hash function the local 'md' (which is initialized from
        +	 * the global 'md' before any bytes are generated), the bytes that are to
        +	 * be overwritten by the random bytes, and bytes from the 'state'
        +	 * (incrementing looping index). From this digest output (which is kept
        +	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
        +	 * bottom 10 bytes are xored into the 'state'.
        +	 * 
        +	 * Finally, after we have finished 'num' random bytes for the
        +	 * caller, 'count' (which is incremented) and the local and global 'md'
        +	 * are fed into the hash function and the results are kept in the
        +	 * global 'md'.
        +	 */
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +
        +	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
        +	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
        +	CRYPTO_THREADID_current(&locking_threadid);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
        +	crypto_lock_rand = 1;
        +
        +	if (!initialized)
        +		{
        +		RAND_poll();
        +		initialized = 1;
        +		}
        +	
        +	if (!stirred_pool)
        +		do_stir_pool = 1;
        +	
        +	ok = (entropy >= ENTROPY_NEEDED);
        +	if (!ok)
        +		{
        +		/* If the PRNG state is not yet unpredictable, then seeing
        +		 * the PRNG output may help attackers to determine the new
        +		 * state; thus we have to decrease the entropy estimate.
        +		 * Once we've had enough initial seeding we don't bother to
        +		 * adjust the entropy count, though, because we're not ambitious
        +		 * to provide *information-theoretic* randomness.
        +		 *
        +		 * NOTE: This approach fails if the program forks before
        +		 * we have enough entropy. Entropy should be collected
        +		 * in a separate input pool and be transferred to the
        +		 * output pool only when the entropy limit has been reached.
        +		 */
        +		entropy -= num;
        +		if (entropy < 0)
        +			entropy = 0;
        +		}
        +
        +	if (do_stir_pool)
        +		{
        +		/* In the output function only half of 'md' remains secret,
        +		 * so we better make sure that the required entropy gets
        +		 * 'evenly distributed' through 'state', our randomness pool.
        +		 * The input function (ssleay_rand_add) chains all of 'md',
        +		 * which makes it more suitable for this purpose.
        +		 */
        +
        +		int n = STATE_SIZE; /* so that the complete pool gets accessed */
        +		while (n > 0)
        +			{
        +#if MD_DIGEST_LENGTH > 20
        +# error "Please adjust DUMMY_SEED."
        +#endif
        +#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
        +			/* Note that the seed does not matter, it's just that
        +			 * ssleay_rand_add expects to have something to hash. */
        +			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
        +			n -= MD_DIGEST_LENGTH;
        +			}
        +		if (ok)
        +			stirred_pool = 1;
        +		}
        +
        +	st_idx=state_index;
        +	st_num=state_num;
        +	md_c[0] = md_count[0];
        +	md_c[1] = md_count[1];
        +	memcpy(local_md, md, sizeof md);
        +
        +	state_index+=num_ceil;
        +	if (state_index > state_num)
        +		state_index %= state_num;
        +
        +	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
        +	 * are now ours (but other threads may use them too) */
        +
        +	md_count[0] += 1;
        +
        +	/* before unlocking, we must clear 'crypto_lock_rand' */
        +	crypto_lock_rand = 0;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +
        +	while (num > 0)
        +		{
        +		/* num_ceil -= MD_DIGEST_LENGTH/2 */
        +		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
        +		num-=j;
        +		MD_Init(&m);
        +#ifndef GETPID_IS_MEANINGLESS
        +		if (curr_pid) /* just in the first iteration to save time */
        +			{
        +			MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
        +			curr_pid = 0;
        +			}
        +#endif
        +		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
        +		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
        +
        +#ifndef PURIFY /* purify complains */
        +		/* The following line uses the supplied buffer as a small
        +		 * source of entropy: since this buffer is often uninitialised
        +		 * it may cause programs such as purify or valgrind to
        +		 * complain. So for those builds it is not used: the removal
        +		 * of such a small source of entropy has negligible impact on
        +		 * security.
        +		 */
        +		MD_Update(&m,buf,j);
        +#endif
        +
        +		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
        +		if (k > 0)
        +			{
        +			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
        +			MD_Update(&m,&(state[0]),k);
        +			}
        +		else
        +			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
        +		MD_Final(&m,local_md);
        +
        +		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
        +			{
        +			state[st_idx++]^=local_md[i]; /* may compete with other threads */
        +			if (st_idx >= st_num)
        +				st_idx=0;
        +			if (i < j)
        +				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
        +			}
        +		}
        +
        +	MD_Init(&m);
        +	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
        +	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
        +	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +	MD_Update(&m,md,MD_DIGEST_LENGTH);
        +	MD_Final(&m,md);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +
        +	EVP_MD_CTX_cleanup(&m);
        +	if (ok)
        +		return(1);
        +	else if (pseudo)
        +		return 0;
        +	else 
        +		{
        +		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
        +		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
        +			"http://www.openssl.org/support/faq.html");
        +		return(0);
        +		}
        +	}
        +
        +static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
        +	{
        +	return ssleay_rand_bytes(buf, num, 0);
        +	}
        +
        +/* pseudo-random bytes that are guaranteed to be unique but not
        +   unpredictable */
        +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 
        +	{
        +	return ssleay_rand_bytes(buf, num, 1);
        +	}
        +
        +static int ssleay_rand_status(void)
        +	{
        +	CRYPTO_THREADID cur;
        +	int ret;
        +	int do_not_lock;
        +
        +	CRYPTO_THREADID_current(&cur);
        +	/* check if we already have the lock
        +	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
        +	if (crypto_lock_rand)
        +		{
        +		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
        +		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
        +		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
        +		}
        +	else
        +		do_not_lock = 0;
        +	
        +	if (!do_not_lock)
        +		{
        +		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +		
        +		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
        +		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
        +		CRYPTO_THREADID_cpy(&locking_threadid, &cur);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
        +		crypto_lock_rand = 1;
        +		}
        +	
        +	if (!initialized)
        +		{
        +		RAND_poll();
        +		initialized = 1;
        +		}
        +
        +	ret = entropy >= ENTROPY_NEEDED;
        +
        +	if (!do_not_lock)
        +		{
        +		/* before unlocking, we must clear 'crypto_lock_rand' */
        +		crypto_lock_rand = 0;
        +		
        +		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +		}
        +	
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rand/rand.h b/vendor/openssl/openssl/crypto/rand/rand.h
        new file mode 100644
        index 000000000..dc8fcf94c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand.h
        @@ -0,0 +1,149 @@
        +/* crypto/rand/rand.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_RAND_H
        +#define HEADER_RAND_H
        +
        +#include <stdlib.h>
        +#include <openssl/ossl_typ.h>
        +#include <openssl/e_os2.h>
        +
        +#if defined(OPENSSL_SYS_WINDOWS)
        +#include <windows.h>
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#if defined(OPENSSL_FIPS)
        +#define FIPS_RAND_SIZE_T size_t
        +#endif
        +
        +/* Already defined in ossl_typ.h */
        +/* typedef struct rand_meth_st RAND_METHOD; */
        +
        +struct rand_meth_st
        +	{
        +	void (*seed)(const void *buf, int num);
        +	int (*bytes)(unsigned char *buf, int num);
        +	void (*cleanup)(void);
        +	void (*add)(const void *buf, int num, double entropy);
        +	int (*pseudorand)(unsigned char *buf, int num);
        +	int (*status)(void);
        +	};
        +
        +#ifdef BN_DEBUG
        +extern int rand_predictable;
        +#endif
        +
        +int RAND_set_rand_method(const RAND_METHOD *meth);
        +const RAND_METHOD *RAND_get_rand_method(void);
        +#ifndef OPENSSL_NO_ENGINE
        +int RAND_set_rand_engine(ENGINE *engine);
        +#endif
        +RAND_METHOD *RAND_SSLeay(void);
        +void RAND_cleanup(void );
        +int  RAND_bytes(unsigned char *buf,int num);
        +int  RAND_pseudo_bytes(unsigned char *buf,int num);
        +void RAND_seed(const void *buf,int num);
        +void RAND_add(const void *buf,int num,double entropy);
        +int  RAND_load_file(const char *file,long max_bytes);
        +int  RAND_write_file(const char *file);
        +const char *RAND_file_name(char *file,size_t num);
        +int RAND_status(void);
        +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
        +int RAND_egd(const char *path);
        +int RAND_egd_bytes(const char *path,int bytes);
        +int RAND_poll(void);
        +
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
        +
        +void RAND_screen(void);
        +int RAND_event(UINT, WPARAM, LPARAM);
        +
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +void RAND_set_fips_drbg_type(int type, int flags);
        +int RAND_init_fips(void);
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_RAND_strings(void);
        +
        +/* Error codes for the RAND functions. */
        +
        +/* Function codes. */
        +#define RAND_F_RAND_GET_RAND_METHOD			 101
        +#define RAND_F_RAND_INIT_FIPS				 102
        +#define RAND_F_SSLEAY_RAND_BYTES			 100
        +
        +/* Reason codes. */
        +#define RAND_R_ERROR_INITIALISING_DRBG			 102
        +#define RAND_R_ERROR_INSTANTIATING_DRBG			 103
        +#define RAND_R_NO_FIPS_RANDOM_METHOD_SET		 101
        +#define RAND_R_PRNG_NOT_SEEDED				 100
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_egd.c b/vendor/openssl/openssl/crypto/rand/rand_egd.c
        new file mode 100644
        index 000000000..d53b916eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_egd.c
        @@ -0,0 +1,303 @@
        +/* crypto/rand/rand_egd.c */
        +/* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */
        +/* ====================================================================
        + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <openssl/e_os2.h>
        +#include <openssl/rand.h>
        +#include <openssl/buffer.h>
        +
        +/*
        + * Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
        + *
        + * This module supplies three routines:
        + *
        + * RAND_query_egd_bytes(path, buf, bytes)
        + *   will actually query "bytes" bytes of entropy form the egd-socket located
        + *   at path and will write them to buf (if supplied) or will directly feed
        + *   it to RAND_seed() if buf==NULL.
        + *   The number of bytes is not limited by the maximum chunk size of EGD,
        + *   which is 255 bytes. If more than 255 bytes are wanted, several chunks
        + *   of entropy bytes are requested. The connection is left open until the
        + *   query is competed.
        + *   RAND_query_egd_bytes() returns with
        + *     -1  if an error occured during connection or communication.
        + *     num the number of bytes read from the EGD socket. This number is either
        + *         the number of bytes requested or smaller, if the EGD pool is
        + *         drained and the daemon signals that the pool is empty.
        + *   This routine does not touch any RAND_status(). This is necessary, since
        + *   PRNG functions may call it during initialization.
        + *
        + * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
        + *   used to seed the PRNG.
        + *   RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
        + *   Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
        + *   seed status so that the return value can reflect the seed state:
        + *     -1  if an error occured during connection or communication _or_
        + *         if the PRNG has still not received the required seeding.
        + *     num the number of bytes read from the EGD socket. This number is either
        + *         the number of bytes requested or smaller, if the EGD pool is
        + *         drained and the daemon signals that the pool is empty.
        + *
        + * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed
        + *   the PRNG.
        + *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
        + */
        +
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
        +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
        +	{
        +	return(-1);
        +	}
        +int RAND_egd(const char *path)
        +	{
        +	return(-1);
        +	}
        +
        +int RAND_egd_bytes(const char *path,int bytes)
        +	{
        +	return(-1);
        +	}
        +#else
        +#include <openssl/opensslconf.h>
        +#include OPENSSL_UNISTD
        +#include <sys/types.h>
        +#include <sys/socket.h>
        +#ifndef NO_SYS_UN_H
        +# ifdef OPENSSL_SYS_VXWORKS
        +#   include <streams/un.h>
        +# else
        +#   include <sys/un.h>
        +# endif
        +#else
        +struct	sockaddr_un {
        +	short	sun_family;		/* AF_UNIX */
        +	char	sun_path[108];		/* path name (gag) */
        +};
        +#endif /* NO_SYS_UN_H */
        +#include <string.h>
        +#include <errno.h>
        +
        +#ifndef offsetof
        +#  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
        +#endif
        +
        +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
        +	{
        +	int ret = 0;
        +	struct sockaddr_un addr;
        +	int len, num, numbytes;
        +	int fd = -1;
        +	int success;
        +	unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
        +
        +	memset(&addr, 0, sizeof(addr));
        +	addr.sun_family = AF_UNIX;
        +	if (strlen(path) >= sizeof(addr.sun_path))
        +		return (-1);
        +	BUF_strlcpy(addr.sun_path,path,sizeof addr.sun_path);
        +	len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
        +	fd = socket(AF_UNIX, SOCK_STREAM, 0);
        +	if (fd == -1) return (-1);
        +	success = 0;
        +	while (!success)
        +	    {
        +	    if (connect(fd, (struct sockaddr *)&addr, len) == 0)
        +	       success = 1;
        +	    else
        +		{
        +		switch (errno)
        +		    {
        +#ifdef EINTR
        +		    case EINTR:
        +#endif
        +#ifdef EAGAIN
        +		    case EAGAIN:
        +#endif
        +#ifdef EINPROGRESS
        +		    case EINPROGRESS:
        +#endif
        +#ifdef EALREADY
        +		    case EALREADY:
        +#endif
        +			/* No error, try again */
        +			break;
        +#ifdef EISCONN
        +		    case EISCONN:
        +			success = 1;
        +			break;
        +#endif
        +		    default:
        +			goto err;	/* failure */
        +		    }
        +		}
        +	    }
        +
        +	while(bytes > 0)
        +	    {
        +	    egdbuf[0] = 1;
        +	    egdbuf[1] = bytes < 255 ? bytes : 255;
        +	    numbytes = 0;
        +	    while (numbytes != 2)
        +		{
        +	        num = write(fd, egdbuf + numbytes, 2 - numbytes);
        +	        if (num >= 0)
        +		    numbytes += num;
        +	    	else
        +		    {
        +		    switch (errno)
        +		    	{
        +#ifdef EINTR
        +		    	case EINTR:
        +#endif
        +#ifdef EAGAIN
        +		    	case EAGAIN:
        +#endif
        +			    /* No error, try again */
        +			    break;
        +		    	default:
        +			    ret = -1;
        +			    goto err;	/* failure */
        +			}
        +		    }
        +		}
        +	    numbytes = 0;
        +	    while (numbytes != 1)
        +		{
        +	        num = read(fd, egdbuf, 1);
        +	        if (num == 0)
        +			goto err;	/* descriptor closed */
        +		else if (num > 0)
        +		    numbytes += num;
        +	    	else
        +		    {
        +		    switch (errno)
        +		    	{
        +#ifdef EINTR
        +		    	case EINTR:
        +#endif
        +#ifdef EAGAIN
        +		    	case EAGAIN:
        +#endif
        +			    /* No error, try again */
        +			    break;
        +		    	default:
        +			    ret = -1;
        +			    goto err;	/* failure */
        +			}
        +		    }
        +		}
        +	    if(egdbuf[0] == 0)
        +		goto err;
        +	    if (buf)
        +		retrievebuf = buf + ret;
        +	    else
        +		retrievebuf = tempbuf;
        +	    numbytes = 0;
        +	    while (numbytes != egdbuf[0])
        +		{
        +	        num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
        +		if (num == 0)
        +			goto err;	/* descriptor closed */
        +	        else if (num > 0)
        +		    numbytes += num;
        +	    	else
        +		    {
        +		    switch (errno)
        +		    	{
        +#ifdef EINTR
        +		    	case EINTR:
        +#endif
        +#ifdef EAGAIN
        +		    	case EAGAIN:
        +#endif
        +			    /* No error, try again */
        +			    break;
        +		    	default:
        +			    ret = -1;
        +			    goto err;	/* failure */
        +			}
        +		    }
        +		}
        +	    ret += egdbuf[0];
        +	    bytes -= egdbuf[0];
        +	    if (!buf)
        +		RAND_seed(tempbuf, egdbuf[0]);
        +	    }
        + err:
        +	if (fd != -1) close(fd);
        +	return(ret);
        +	}
        +
        +
        +int RAND_egd_bytes(const char *path, int bytes)
        +	{
        +	int num, ret = 0;
        +
        +	num = RAND_query_egd_bytes(path, NULL, bytes);
        +	if (num < 1) goto err;
        +	if (RAND_status() == 1)
        +	    ret = num;
        + err:
        +	return(ret);
        +	}
        +
        +
        +int RAND_egd(const char *path)
        +	{
        +	return (RAND_egd_bytes(path, 255));
        +	}
        +
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_err.c b/vendor/openssl/openssl/crypto/rand/rand_err.c
        new file mode 100644
        index 000000000..b8586c8f4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_err.c
        @@ -0,0 +1,100 @@
        +/* crypto/rand/rand_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
        +
        +static ERR_STRING_DATA RAND_str_functs[]=
        +	{
        +{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD),	"RAND_get_rand_method"},
        +{ERR_FUNC(RAND_F_RAND_INIT_FIPS),	"RAND_init_fips"},
        +{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES),	"SSLEAY_RAND_BYTES"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA RAND_str_reasons[]=
        +	{
        +{ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
        +{ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
        +{ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),"no fips random method set"},
        +{ERR_REASON(RAND_R_PRNG_NOT_SEEDED)      ,"PRNG not seeded"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_RAND_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(RAND_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,RAND_str_functs);
        +		ERR_load_strings(0,RAND_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_lcl.h b/vendor/openssl/openssl/crypto/rand/rand_lcl.h
        new file mode 100644
        index 000000000..618a8ec89
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_lcl.h
        @@ -0,0 +1,158 @@
        +/* crypto/rand/rand_lcl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_RAND_LCL_H
        +#define HEADER_RAND_LCL_H
        +
        +#define ENTROPY_NEEDED 32  /* require 256 bits = 32 bytes of randomness */
        +
        +
        +#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
        +#define USE_SHA1_RAND
        +#elif !defined(OPENSSL_NO_MD5)
        +#define USE_MD5_RAND
        +#elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
        +#define USE_MDC2_RAND
        +#elif !defined(OPENSSL_NO_MD2)
        +#define USE_MD2_RAND
        +#else
        +#error No message digest algorithm available
        +#endif
        +#endif
        +
        +#include <openssl/evp.h>
        +#define MD_Update(a,b,c)	EVP_DigestUpdate(a,b,c)
        +#define	MD_Final(a,b)		EVP_DigestFinal_ex(a,b,NULL)
        +#if defined(USE_MD5_RAND)
        +#include <openssl/md5.h>
        +#define MD_DIGEST_LENGTH	MD5_DIGEST_LENGTH
        +#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_md5(), NULL)
        +#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
        +#elif defined(USE_SHA1_RAND)
        +#include <openssl/sha.h>
        +#define MD_DIGEST_LENGTH	SHA_DIGEST_LENGTH
        +#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_sha1(), NULL)
        +#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
        +#elif defined(USE_MDC2_RAND)
        +#include <openssl/mdc2.h>
        +#define MD_DIGEST_LENGTH	MDC2_DIGEST_LENGTH
        +#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
        +#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
        +#elif defined(USE_MD2_RAND)
        +#include <openssl/md2.h>
        +#define MD_DIGEST_LENGTH	MD2_DIGEST_LENGTH
        +#define MD_Init(a)		EVP_DigestInit_ex(a,EVP_md2(), NULL)
        +#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
        +#endif
        +
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_lib.c b/vendor/openssl/openssl/crypto/rand/rand_lib.c
        new file mode 100644
        index 000000000..476a0cd18
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_lib.c
        @@ -0,0 +1,298 @@
        +/* crypto/rand/rand_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#include <openssl/fips_rand.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_ENGINE
        +/* non-NULL if default_RAND_meth is ENGINE-provided */
        +static ENGINE *funct_ref =NULL;
        +#endif
        +static const RAND_METHOD *default_RAND_meth = NULL;
        +
        +int RAND_set_rand_method(const RAND_METHOD *meth)
        +	{
        +#ifndef OPENSSL_NO_ENGINE
        +	if(funct_ref)
        +		{
        +		ENGINE_finish(funct_ref);
        +		funct_ref = NULL;
        +		}
        +#endif
        +	default_RAND_meth = meth;
        +	return 1;
        +	}
        +
        +const RAND_METHOD *RAND_get_rand_method(void)
        +	{
        +	if (!default_RAND_meth)
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		ENGINE *e = ENGINE_get_default_RAND();
        +		if(e)
        +			{
        +			default_RAND_meth = ENGINE_get_RAND(e);
        +			if(!default_RAND_meth)
        +				{
        +				ENGINE_finish(e);
        +				e = NULL;
        +				}
        +			}
        +		if(e)
        +			funct_ref = e;
        +		else
        +#endif
        +			default_RAND_meth = RAND_SSLeay();
        +		}
        +	return default_RAND_meth;
        +	}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +int RAND_set_rand_engine(ENGINE *engine)
        +	{
        +	const RAND_METHOD *tmp_meth = NULL;
        +	if(engine)
        +		{
        +		if(!ENGINE_init(engine))
        +			return 0;
        +		tmp_meth = ENGINE_get_RAND(engine);
        +		if(!tmp_meth)
        +			{
        +			ENGINE_finish(engine);
        +			return 0;
        +			}
        +		}
        +	/* This function releases any prior ENGINE so call it first */
        +	RAND_set_rand_method(tmp_meth);
        +	funct_ref = engine;
        +	return 1;
        +	}
        +#endif
        +
        +void RAND_cleanup(void)
        +	{
        +	const RAND_METHOD *meth = RAND_get_rand_method();
        +	if (meth && meth->cleanup)
        +		meth->cleanup();
        +	RAND_set_rand_method(NULL);
        +	}
        +
        +void RAND_seed(const void *buf, int num)
        +	{
        +	const RAND_METHOD *meth = RAND_get_rand_method();
        +	if (meth && meth->seed)
        +		meth->seed(buf,num);
        +	}
        +
        +void RAND_add(const void *buf, int num, double entropy)
        +	{
        +	const RAND_METHOD *meth = RAND_get_rand_method();
        +	if (meth && meth->add)
        +		meth->add(buf,num,entropy);
        +	}
        +
        +int RAND_bytes(unsigned char *buf, int num)
        +	{
        +	const RAND_METHOD *meth = RAND_get_rand_method();
        +	if (meth && meth->bytes)
        +		return meth->bytes(buf,num);
        +	return(-1);
        +	}
        +
        +int RAND_pseudo_bytes(unsigned char *buf, int num)
        +	{
        +	const RAND_METHOD *meth = RAND_get_rand_method();
        +	if (meth && meth->pseudorand)
        +		return meth->pseudorand(buf,num);
        +	return(-1);
        +	}
        +
        +int RAND_status(void)
        +	{
        +	const RAND_METHOD *meth = RAND_get_rand_method();
        +	if (meth && meth->status)
        +		return meth->status();
        +	return 0;
        +	}
        +
        +#ifdef OPENSSL_FIPS
        +
        +/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
        + * rest of OpenSSL. 
        + */
        +
        +/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
        + * entropy internally through RAND_poll().
        + */
        +
        +static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
        +                                int entropy, size_t min_len, size_t max_len)
        +        {
        +	/* Round up request to multiple of block size */
        +	min_len = ((min_len + 19) / 20) * 20;
        +	*pout = OPENSSL_malloc(min_len);
        +	if (!*pout)
        +		return 0;
        +	if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
        +		{
        +		OPENSSL_free(*pout);
        +		*pout = NULL;
        +		return 0;
        +		}
        +        return min_len;
        +        }
        +
        +static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
        +	{
        +	if (out)
        +		{
        +		OPENSSL_cleanse(out, olen);
        +		OPENSSL_free(out);
        +		}
        +	}
        +
        +/* Set "additional input" when generating random data. This uses the
        + * current PID, a time value and a counter.
        + */
        +
        +static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
        +    	{
        +	/* Use of static variables is OK as this happens under a lock */
        +	static unsigned char buf[16];
        +	static unsigned long counter;
        +	FIPS_get_timevec(buf, &counter);
        +	*pout = buf;
        +	return sizeof(buf);
        +	}
        +
        +/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is 
        + * correctly seeded by RAND_poll().
        + */
        +
        +static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
        +				double entropy)
        +	{
        +	RAND_SSLeay()->add(in, inlen, entropy);
        +	return 1;
        +	}
        +
        +static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
        +	{
        +	RAND_SSLeay()->seed(in, inlen);
        +	return 1;
        +	}
        +
        +#ifndef OPENSSL_DRBG_DEFAULT_TYPE
        +#define OPENSSL_DRBG_DEFAULT_TYPE	NID_aes_256_ctr
        +#endif
        +#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
        +#define OPENSSL_DRBG_DEFAULT_FLAGS	DRBG_FLAG_CTR_USE_DF
        +#endif 
        +
        +static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
        +static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
        +
        +void RAND_set_fips_drbg_type(int type, int flags)
        +	{
        +	fips_drbg_type = type;
        +	fips_drbg_flags = flags;
        +	}
        +
        +int RAND_init_fips(void)
        +	{
        +	DRBG_CTX *dctx;
        +	size_t plen;
        +	unsigned char pers[32], *p;
        +	dctx = FIPS_get_default_drbg();
        +        if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
        +		{
        +		RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
        +		return 0;
        +		}
        +		
        +        FIPS_drbg_set_callbacks(dctx,
        +				drbg_get_entropy, drbg_free_entropy, 20,
        +				drbg_get_entropy, drbg_free_entropy);
        +	FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
        +					drbg_rand_seed, drbg_rand_add);
        +	/* Personalisation string: a string followed by date time vector */
        +	strcpy((char *)pers, "OpenSSL DRBG2.0");
        +	plen = drbg_get_adin(dctx, &p);
        +	memcpy(pers + 16, p, plen);
        +
        +        if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
        +		{
        +		RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
        +		return 0;
        +		}
        +        FIPS_rand_set_method(FIPS_drbg_method());
        +	return 1;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_nw.c b/vendor/openssl/openssl/crypto/rand/rand_nw.c
        new file mode 100644
        index 000000000..8d5b8d2e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_nw.c
        @@ -0,0 +1,183 @@
        +/* crypto/rand/rand_nw.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 <openssl/rand.h>
        +#include "rand_lcl.h"
        +
        +#if defined (OPENSSL_SYS_NETWARE)
        +
        +#if defined(NETWARE_LIBC)
        +#include <nks/thread.h>
        +#else
        +#include <nwthread.h>
        +#endif
        +
        +extern int GetProcessSwitchCount(void);
        +#if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000)
        +extern void *RunningProcess; /* declare here same as found in newer NDKs */
        +extern unsigned long GetSuperHighResolutionTimer(void);
        +#endif
        +
        +   /* the FAQ indicates we need to provide at least 20 bytes (160 bits) of seed
        +   */
        +int RAND_poll(void)
        +{
        +   unsigned long l;
        +   unsigned long tsc;
        +   int i; 
        +
        +      /* There are several options to gather miscellaneous data
        +       * but for now we will loop checking the time stamp counter (rdtsc) and
        +       * the SuperHighResolutionTimer.  Each iteration will collect 8 bytes
        +       * of data but it is treated as only 1 byte of entropy.  The call to
        +       * ThreadSwitchWithDelay() will introduce additional variability into
        +       * the data returned by rdtsc.
        +       *
        +       * Applications can agument the seed material by adding additional
        +       * stuff with RAND_add() and should probably do so.
        +      */
        +   l = GetProcessSwitchCount();
        +   RAND_add(&l,sizeof(l),1);
        +   
        +   /* need to cast the void* to unsigned long here */
        +   l = (unsigned long)RunningProcess;
        +   RAND_add(&l,sizeof(l),1);
        +
        +   for( i=2; i<ENTROPY_NEEDED; i++)
        +   {
        +#ifdef __MWERKS__
        +      asm 
        +      {
        +         rdtsc
        +         mov tsc, eax        
        +      }
        +#elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +      asm volatile("rdtsc":"=a"(tsc)::"edx");
        +#endif
        +
        +      RAND_add(&tsc, sizeof(tsc), 1);
        +
        +      l = GetSuperHighResolutionTimer();
        +      RAND_add(&l, sizeof(l), 0);
        +
        +# if defined(NETWARE_LIBC)
        +      NXThreadYield();
        +# else /* NETWARE_CLIB */
        +      ThreadSwitchWithDelay();
        +# endif
        +   }
        +
        +   return 1;
        +}
        +
        +#endif 
        +
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_os2.c b/vendor/openssl/openssl/crypto/rand/rand_os2.c
        new file mode 100644
        index 000000000..fc1e78b17
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_os2.c
        @@ -0,0 +1,153 @@
        +/* crypto/rand/rand_os2.c */
        +/* ====================================================================
        + * 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 <openssl/rand.h>
        +#include "rand_lcl.h"
        +
        +#ifdef OPENSSL_SYS_OS2
        +
        +#define INCL_DOSPROCESS
        +#define INCL_DOSPROFILE
        +#define INCL_DOSMISC
        +#define INCL_DOSMODULEMGR
        +#include <os2.h>
        +
        +#define   CMD_KI_RDCNT    (0x63)
        +
        +typedef struct _CPUUTIL {
        +    ULONG ulTimeLow;            /* Low 32 bits of time stamp      */
        +    ULONG ulTimeHigh;           /* High 32 bits of time stamp     */
        +    ULONG ulIdleLow;            /* Low 32 bits of idle time       */
        +    ULONG ulIdleHigh;           /* High 32 bits of idle time      */
        +    ULONG ulBusyLow;            /* Low 32 bits of busy time       */
        +    ULONG ulBusyHigh;           /* High 32 bits of busy time      */
        +    ULONG ulIntrLow;            /* Low 32 bits of interrupt time  */
        +    ULONG ulIntrHigh;           /* High 32 bits of interrupt time */
        +} CPUUTIL;
        +
        +#ifndef __KLIBC__
        +APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
        +APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
        +#endif
        +HMODULE hDoscalls = 0;
        +
        +int RAND_poll(void)
        +{
        +    char failed_module[20];
        +    QWORD qwTime;
        +    ULONG SysVars[QSV_FOREGROUND_PROCESS];
        +
        +    if (hDoscalls == 0) {
        +        ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
        +
        +#ifndef __KLIBC__
        +        if (rc == 0) {
        +            rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
        +
        +            if (rc)
        +                DosPerfSysCall = NULL;
        +
        +            rc = DosQueryProcAddr(hDoscalls, 368, NULL, (PFN *)&DosQuerySysState);
        +
        +            if (rc)
        +                DosQuerySysState = NULL;
        +        }
        +#endif
        +    }
        +
        +    /* Sample the hi-res timer, runs at around 1.1 MHz */
        +    DosTmrQueryTime(&qwTime);
        +    RAND_add(&qwTime, sizeof(qwTime), 2);
        +
        +    /* Sample a bunch of system variables, includes various process & memory statistics */
        +    DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
        +    RAND_add(SysVars, sizeof(SysVars), 4);
        +
        +    /* If available, sample CPU registers that count at CPU MHz
        +     * Only fairly new CPUs (PPro & K6 onwards) & OS/2 versions support this
        +     */
        +    if (DosPerfSysCall) {
        +        CPUUTIL util;
        +
        +        if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
        +            RAND_add(&util, sizeof(util), 10);
        +        }
        +        else {
        +#ifndef __KLIBC__
        +            DosPerfSysCall = NULL;
        +#endif
        +        }
        +    }
        +
        +    /* DosQuerySysState() gives us a huge quantity of process, thread, memory & handle stats */
        +    if (DosQuerySysState) {
        +        char *buffer = OPENSSL_malloc(256 * 1024);
        +
        +        if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) {
        +            /* First 4 bytes in buffer is a pointer to the thread count
        +             * there should be at least 1 byte of entropy per thread
        +             */
        +            RAND_add(buffer, 256 * 1024, **(ULONG **)buffer);
        +        }
        +
        +        OPENSSL_free(buffer);
        +        return 1;
        +    }
        +
        +    return 0;
        +}
        +
        +#endif /* OPENSSL_SYS_OS2 */
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_unix.c b/vendor/openssl/openssl/crypto/rand/rand_unix.c
        new file mode 100644
        index 000000000..e3a65571c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_unix.c
        @@ -0,0 +1,431 @@
        +/* crypto/rand/rand_unix.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-2006 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 <stdio.h>
        +
        +#define USE_SOCKETS
        +#include "e_os.h"
        +#include "cryptlib.h"
        +#include <openssl/rand.h>
        +#include "rand_lcl.h"
        +
        +#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE))
        +
        +#include <sys/types.h>
        +#include <sys/time.h>
        +#include <sys/times.h>
        +#include <sys/stat.h>
        +#include <fcntl.h>
        +#include <unistd.h>
        +#include <time.h>
        +#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */
        +# include <poll.h>
        +#endif
        +#include <limits.h>
        +#ifndef FD_SETSIZE
        +# define FD_SETSIZE (8*sizeof(fd_set))
        +#endif
        +
        +#if defined(OPENSSL_SYS_VOS)
        +
        +/* The following algorithm repeatedly samples the real-time clock
        +   (RTC) to generate a sequence of unpredictable data.  The algorithm
        +   relies upon the uneven execution speed of the code (due to factors
        +   such as cache misses, interrupts, bus activity, and scheduling) and
        +   upon the rather large relative difference between the speed of the
        +   clock and the rate at which it can be read.
        +
        +   If this code is ported to an environment where execution speed is
        +   more constant or where the RTC ticks at a much slower rate, or the
        +   clock can be read with fewer instructions, it is likely that the
        +   results would be far more predictable.
        +
        +   As a precaution, we generate 4 times the minimum required amount of
        +   seed data.  */
        +
        +int RAND_poll(void)
        +{
        +	short int code;
        +	gid_t curr_gid;
        +	pid_t curr_pid;
        +	uid_t curr_uid;
        +	int i, k;
        +	struct timespec ts;
        +	unsigned char v;
        +
        +#ifdef OPENSSL_SYS_VOS_HPPA
        +	long duration;
        +	extern void s$sleep (long *_duration, short int *_code);
        +#else
        +#ifdef OPENSSL_SYS_VOS_IA32
        +	long long duration;
        +	extern void s$sleep2 (long long *_duration, short int *_code);
        +#else
        +#error "Unsupported Platform."
        +#endif /* OPENSSL_SYS_VOS_IA32 */
        +#endif /* OPENSSL_SYS_VOS_HPPA */
        +
        +	/* Seed with the gid, pid, and uid, to ensure *some*
        +	   variation between different processes.  */
        +
        +	curr_gid = getgid();
        +	RAND_add (&curr_gid, sizeof curr_gid, 1);
        +	curr_gid = 0;
        +
        +	curr_pid = getpid();
        +	RAND_add (&curr_pid, sizeof curr_pid, 1);
        +	curr_pid = 0;
        +
        +	curr_uid = getuid();
        +	RAND_add (&curr_uid, sizeof curr_uid, 1);
        +	curr_uid = 0;
        +
        +	for (i=0; i<(ENTROPY_NEEDED*4); i++)
        +	{
        +		/* burn some cpu; hope for interrupts, cache
        +		   collisions, bus interference, etc.  */
        +		for (k=0; k<99; k++)
        +			ts.tv_nsec = random ();
        +
        +#ifdef OPENSSL_SYS_VOS_HPPA
        +		/* sleep for 1/1024 of a second (976 us).  */
        +		duration = 1;
        +		s$sleep (&duration, &code);
        +#else
        +#ifdef OPENSSL_SYS_VOS_IA32
        +		/* sleep for 1/65536 of a second (15 us).  */
        +		duration = 1;
        +		s$sleep2 (&duration, &code);
        +#endif /* OPENSSL_SYS_VOS_IA32 */
        +#endif /* OPENSSL_SYS_VOS_HPPA */
        +
        +		/* get wall clock time.  */
        +		clock_gettime (CLOCK_REALTIME, &ts);
        +
        +		/* take 8 bits */
        +		v = (unsigned char) (ts.tv_nsec % 256);
        +		RAND_add (&v, sizeof v, 1);
        +		v = 0;
        +	}
        +	return 1;
        +}
        +#elif defined __OpenBSD__
        +int RAND_poll(void)
        +{
        +	u_int32_t rnd = 0, i;
        +	unsigned char buf[ENTROPY_NEEDED];
        +
        +	for (i = 0; i < sizeof(buf); i++) {
        +		if (i % 4 == 0)
        +			rnd = arc4random();
        +		buf[i] = rnd;
        +		rnd >>= 8;
        +	}
        +	RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
        +	memset(buf, 0, sizeof(buf));
        +
        +	return 1;
        +}
        +#else /* !defined(__OpenBSD__) */
        +int RAND_poll(void)
        +{
        +	unsigned long l;
        +	pid_t curr_pid = getpid();
        +#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        +	unsigned char tmpbuf[ENTROPY_NEEDED];
        +	int n = 0;
        +#endif
        +#ifdef DEVRANDOM
        +	static const char *randomfiles[] = { DEVRANDOM };
        +	struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
        +	int fd;
        +	unsigned int i;
        +#endif
        +#ifdef DEVRANDOM_EGD
        +	static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
        +	const char **egdsocket = NULL;
        +#endif
        +
        +#ifdef DEVRANDOM
        +	memset(randomstats,0,sizeof(randomstats));
        +	/* 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.  */
        +
        +	for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
        +			(n < ENTROPY_NEEDED); i++)
        +		{
        +		if ((fd = open(randomfiles[i], O_RDONLY
        +#ifdef O_NONBLOCK
        +			|O_NONBLOCK
        +#endif
        +#ifdef O_BINARY
        +			|O_BINARY
        +#endif
        +#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
        +		   our controlling tty */
        +			|O_NOCTTY
        +#endif
        +			)) >= 0)
        +			{
        +			int usec = 10*1000; /* spend 10ms on each file */
        +			int r;
        +			unsigned int j;
        +			struct stat *st=&randomstats[i];
        +
        +			/* Avoid using same input... Used to be O_NOFOLLOW
        +			 * above, but it's not universally appropriate... */
        +			if (fstat(fd,st) != 0)	{ close(fd); continue; }
        +			for (j=0;j<i;j++)
        +				{
        +				if (randomstats[j].st_ino==st->st_ino &&
        +				    randomstats[j].st_dev==st->st_dev)
        +					break;
        +				}
        +			if (j<i)		{ close(fd); continue; }
        +
        +			do
        +				{
        +				int try_read = 0;
        +
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +				/* select() is broken in BeOS R5, so we simply
        +				 *  try to read something and snooze if we couldn't */
        +				try_read = 1;
        +
        +#elif defined(OPENSSL_SYS_LINUX)
        +				/* use poll() */
        +				struct pollfd pset;
        +				
        +				pset.fd = fd;
        +				pset.events = POLLIN;
        +				pset.revents = 0;
        +
        +				if (poll(&pset, 1, usec / 1000) < 0)
        +					usec = 0;
        +				else
        +					try_read = (pset.revents & POLLIN) != 0;
        +
        +#else
        +				/* use select() */
        +				fd_set fset;
        +				struct timeval t;
        +				
        +				t.tv_sec = 0;
        +				t.tv_usec = usec;
        +
        +				if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE)
        +					{
        +					/* can't use select, so just try to read once anyway */
        +					try_read = 1;
        +					}
        +				else
        +					{
        +					FD_ZERO(&fset);
        +					FD_SET(fd, &fset);
        +					
        +					if (select(fd+1,&fset,NULL,NULL,&t) >= 0)
        +						{
        +						usec = t.tv_usec;
        +						if (FD_ISSET(fd, &fset))
        +							try_read = 1;
        +						}
        +					else
        +						usec = 0;
        +					}
        +#endif
        +				
        +				if (try_read)
        +					{
        +					r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
        +					if (r > 0)
        +						n += r;
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +					if (r == 0)
        +						snooze(t.tv_usec);
        +#endif
        +					}
        +				else
        +					r = -1;
        +				
        +				/* Some Unixen will update t in select(), some
        +				   won't.  For those who won't, or if we
        +				   didn't use select() in the first place,
        +				   give up here, otherwise, we will do
        +				   this once again for the remaining
        +				   time. */
        +				if (usec == 10*1000)
        +					usec = 0;
        +				}
        +			while ((r > 0 ||
        +			       (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED);
        +
        +			close(fd);
        +			}
        +		}
        +#endif /* defined(DEVRANDOM) */
        +
        +#ifdef DEVRANDOM_EGD
        +	/* Use an EGD socket to read entropy from an EGD or PRNGD entropy
        +	 * collecting daemon. */
        +
        +	for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
        +		{
        +		int r;
        +
        +		r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
        +					 ENTROPY_NEEDED-n);
        +		if (r > 0)
        +			n += r;
        +		}
        +#endif /* defined(DEVRANDOM_EGD) */
        +
        +#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        +	if (n > 0)
        +		{
        +		RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
        +		OPENSSL_cleanse(tmpbuf,n);
        +		}
        +#endif
        +
        +	/* put in some default random data, we need more than just this */
        +	l=curr_pid;
        +	RAND_add(&l,sizeof(l),0.0);
        +	l=getuid();
        +	RAND_add(&l,sizeof(l),0.0);
        +
        +	l=time(NULL);
        +	RAND_add(&l,sizeof(l),0.0);
        +
        +#if defined(OPENSSL_SYS_BEOS)
        +	{
        +	system_info sysInfo;
        +	get_system_info(&sysInfo);
        +	RAND_add(&sysInfo,sizeof(sysInfo),0);
        +	}
        +#endif
        +
        +#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        +	return 1;
        +#else
        +	return 0;
        +#endif
        +}
        +
        +#endif /* defined(__OpenBSD__) */
        +#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */
        +
        +
        +#if defined(OPENSSL_SYS_VXWORKS)
        +int RAND_poll(void)
        +	{
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_vms.c b/vendor/openssl/openssl/crypto/rand/rand_vms.c
        new file mode 100644
        index 000000000..0bfd8ff7e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_vms.c
        @@ -0,0 +1,148 @@
        +/* crypto/rand/rand_vms.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * 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 <openssl/rand.h>
        +#include "rand_lcl.h"
        +
        +#if defined(OPENSSL_SYS_VMS)
        +
        +#include <descrip.h>
        +#include <jpidef.h>
        +#include <ssdef.h>
        +#include <starlet.h>
        +#ifdef __DECC
        +# pragma message disable DOLLARID
        +#endif
        +
        +/* Use 32-bit pointers almost everywhere.  Define the type to which to
        + * cast a pointer passed to an external function.
        + */
        +#if __INITIAL_POINTER_SIZE == 64
        +# define PTR_T __void_ptr64
        +# pragma pointer_size save
        +# pragma pointer_size 32
        +#else /* __INITIAL_POINTER_SIZE == 64 */
        +# define PTR_T void *
        +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +static struct items_data_st
        +	{
        +	short length, code;	/* length is amount of bytes */
        +	} items_data[] =
        +		{ { 4, JPI$_BUFIO },
        +		  { 4, JPI$_CPUTIM },
        +		  { 4, JPI$_DIRIO },
        +		  { 8, JPI$_LOGINTIM },
        +		  { 4, JPI$_PAGEFLTS },
        +		  { 4, JPI$_PID },
        +		  { 4, JPI$_WSSIZE },
        +		  { 0, 0 }
        +		};
        +		  
        +int RAND_poll(void)
        +	{
        +	long pid, iosb[2];
        +	int status = 0;
        +	struct
        +		{
        +		short length, code;
        +		long *buffer;
        +		int *retlen;
        +		} item[32], *pitem;
        +	unsigned char data_buffer[256];
        +	short total_length = 0;
        +	struct items_data_st *pitems_data;
        +
        +	pitems_data = items_data;
        +	pitem = item;
        +
        +	/* Setup */
        +	while (pitems_data->length
        +		&& (total_length + pitems_data->length <= 256))
        +		{
        +		pitem->length = pitems_data->length;
        +		pitem->code = pitems_data->code;
        +		pitem->buffer = (long *)&data_buffer[total_length];
        +		pitem->retlen = 0;
        +		total_length += pitems_data->length;
        +		pitems_data++;
        +		pitem++;
        +		}
        +	pitem->length = pitem->code = 0;
        +
        +	/*
        +	 * Scan through all the processes in the system and add entropy with
        +	 * results from the processes that were possible to look at.
        +	 * However, view the information as only half trustable.
        +	 */
        +	pid = -1;			/* search context */
        +	while ((status = sys$getjpiw(0, &pid,  0, item, iosb, 0, 0))
        +		!= SS$_NOMOREPROC)
        +		{
        +		if (status == SS$_NORMAL)
        +			{
        +			RAND_add( (PTR_T)data_buffer, total_length,
        +			 total_length/2);
        +			}
        +		}
        +	sys$gettim(iosb);
        +	RAND_add( (PTR_T)iosb, sizeof(iosb), sizeof(iosb)/2);
        +	return 1;
        +}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/rand_win.c b/vendor/openssl/openssl/crypto/rand/rand_win.c
        new file mode 100644
        index 000000000..5d134e186
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/rand_win.c
        @@ -0,0 +1,807 @@
        +/* 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 <openssl/rand.h>
        +#include "rand_lcl.h"
        +
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
        +#include <windows.h>
        +#ifndef _WIN32_WINNT
        +# define _WIN32_WINNT 0x0400
        +#endif
        +#include <wincrypt.h>
        +#include <tlhelp32.h>
        +
        +/* Limit the time spent walking through the heap, processes, threads and modules to
        +   a maximum of 1000 miliseconds each, unless CryptoGenRandom failed */
        +#define MAXDELAY 1000
        +
        +/* 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 L"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 */
        +
        +#if !defined(OPENSSL_SYS_WINCE)
        +typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTW)(HCRYPTPROV *, LPCWSTR, LPCWSTR,
        +				    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 *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
        +typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, size_t);
        +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 <lmcons.h>
        +#include <lmstats.h>
        +#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 */
        +#endif /* !OPENSSL_SYS_WINCE */
        +
        +int RAND_poll(void)
        +{
        +	MEMORYSTATUS m;
        +	HCRYPTPROV hProvider = 0;
        +	DWORD w;
        +	int good = 0;
        +
        +	/* 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 ) ;
        +
        +#if defined(OPENSSL_SYS_WINCE)
        +# if defined(_WIN32_WCE) && _WIN32_WCE>=300
        +/* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
        + * in commonly available implementations prior 300... */
        +	{
        +	BYTE buf[64];
        +	/* poll the CryptoAPI PRNG */
        +	/* The CryptoAPI returns sizeof(buf) bytes of randomness */
        +	if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
        +				CRYPT_VERIFYCONTEXT))
        +		{
        +		if (CryptGenRandom(hProvider, sizeof(buf), buf))
        +			RAND_add(buf, sizeof(buf), sizeof(buf));
        +		CryptReleaseContext(hProvider, 0); 
        +		}
        +	}
        +# endif
        +#else	/* OPENSSL_SYS_WINCE */
        +	/*
        +	 * None of below libraries are present on Windows CE, which is
        +	 * why we #ifndef the whole section. This also excuses us from
        +	 * handling the GetProcAddress issue. The trouble is that in
        +	 * real Win32 API GetProcAddress is available in ANSI flavor
        +	 * only. In WinCE on the other hand GetProcAddress is a macro
        +	 * most commonly defined as GetProcAddressW, which accepts
        +	 * Unicode argument. If we were to call GetProcAddress under
        +	 * WinCE, I'd recommend to either redefine GetProcAddress as
        +	 * GetProcAddressA (there seem to be one in common CE spec) or
        +	 * implement own shim routine, which would accept ANSI argument
        +	 * and expand it to Unicode.
        +	 */
        +	{
        +	/* load functions dynamically - not available on all systems */
        +	HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
        +	HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
        +	HMODULE user = NULL;
        +	HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
        +	CRYPTACQUIRECONTEXTW acquire = NULL;
        +	CRYPTGENRANDOM gen = NULL;
        +	CRYPTRELEASECONTEXT release = NULL;
        +	NETSTATGET netstatget = NULL;
        +	NETFREE netfree = NULL;
        +	BYTE buf[64];
        +
        +	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);
        +
        +        /* 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.
        +	 */
        +	/* Wolfgang Marczy <WMarczy@topcall.co.at> reports that
        +	 * the RegQueryValueEx call below can hang on NT4.0 (SP6).
        +	 * So we don't use this at all for now. */
        +#if 0
        +        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, TEXT("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);
        +
        +			/* Close the Registry Key to allow Windows to cleanup/close
        +			 * the open handle
        +			 * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened
        +			 *       when the RegQueryValueEx above is done.  However, if
        +			 *       it is not explicitly closed, it can cause disk
        +			 *       partition manipulation problems.
        +			 */
        +			RegCloseKey(HKEY_PERFORMANCE_DATA);
        +			}
        +		if (buf)
        +			free(buf);
        +		}
        +#endif
        +
        +	if (advapi)
        +		{
        +		/*
        +		 * If it's available, then it's available in both ANSI
        +		 * and UNICODE flavors even in Win9x, documentation says.
        +		 * We favor Unicode...
        +		 */
        +		acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
        +			"CryptAcquireContextW");
        +		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, NULL, NULL, PROV_RSA_FULL,
        +			CRYPT_VERIFYCONTEXT))
        +			{
        +			if (gen(hProvider, sizeof(buf), buf) != 0)
        +				{
        +				RAND_add(buf, sizeof(buf), 0);
        +				good = 1;
        +#if 0
        +				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));
        +				good = 1;
        +#if 0
        +				printf("randomness from PROV_INTEL_SEC\n");
        +#endif
        +				}
        +			release(hProvider, 0);
        +			}
        +		}
        +
        +        if (advapi)
        +		FreeLibrary(advapi);
        +
        +	if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
        +	     !OPENSSL_isservice()) &&
        +	    (user = LoadLibrary(TEXT("USER32.DLL"))))
        +		{
        +		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 */
        +			HWND 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;
        +		CLOSETOOLHELP32SNAPSHOT close_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;
        +		DWORD starttime = 0;
        +
        +		snap = (CREATETOOLHELP32SNAPSHOT)
        +			GetProcAddress(kernel, "CreateToolhelp32Snapshot");
        +		close_snap = (CLOSETOOLHELP32SNAPSHOT)
        +			GetProcAddress(kernel, "CloseToolhelp32Snapshot");
        +		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))
        +			!= INVALID_HANDLE_VALUE)
        +			{
        +			/* 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.
        +                         */
        +			ZeroMemory(&hlist, sizeof(HEAPLIST32));
        +			hlist.dwSize = sizeof(HEAPLIST32);		
        +			if (good) starttime = GetTickCount();
        +#ifdef _MSC_VER
        +			if (heaplist_first(handle, &hlist))
        +				{
        +				/*
        +				   following discussion on dev ML, exception on WinCE (or other Win
        +				   platform) is theoretically of unknown origin; prevent infinite
        +				   loop here when this theoretical case occurs; otherwise cope with
        +				   the expected (MSDN documented) exception-throwing behaviour of
        +				   Heap32Next() on WinCE.
        +
        +				   based on patch in original message by Tanguy Fautré (2009/03/02)
        +			           Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
        +			     */
        +				int ex_cnt_limit = 42; 
        +				do
        +					{
        +					RAND_add(&hlist, hlist.dwSize, 3);
        +					__try
        +						{
        +						ZeroMemory(&hentry, sizeof(HEAPENTRY32));
        +					hentry.dwSize = sizeof(HEAPENTRY32);
        +					if (heap_first(&hentry,
        +						hlist.th32ProcessID,
        +						hlist.th32HeapID))
        +						{
        +						int entrycnt = 80;
        +						do
        +							RAND_add(&hentry,
        +								hentry.dwSize, 5);
        +						while (heap_next(&hentry)
        +						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
        +							&& --entrycnt > 0);
        +						}
        +						}
        +					__except (EXCEPTION_EXECUTE_HANDLER)
        +						{
        +							/* ignore access violations when walking the heap list */
        +							ex_cnt_limit--;
        +						}
        +					} while (heaplist_next(handle, &hlist) 
        +						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
        +						&& ex_cnt_limit > 0);
        +				}
        +
        +#else
        +			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 = 80;
        +						do
        +							RAND_add(&hentry,
        +								hentry.dwSize, 5);
        +						while (heap_next(&hentry)
        +							&& --entrycnt > 0);
        +						}
        +					} while (heaplist_next(handle, &hlist) 
        +						&& (!good || (GetTickCount()-starttime)<MAXDELAY));
        +				}
        +#endif
        +
        +			/* 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 (good) starttime = GetTickCount();
        +			if (process_first(handle, &p))
        +				do
        +					RAND_add(&p, p.dwSize, 9);
        +				while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
        +
        +			/* 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 (good) starttime = GetTickCount();
        +			if (thread_first(handle, &t))
        +				do
        +					RAND_add(&t, t.dwSize, 6);
        +				while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
        +
        +			/* 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 (good) starttime = GetTickCount();
        +			if (module_first(handle, &m))
        +				do
        +					RAND_add(&m, m.dwSize, 9);
        +				while (module_next(handle, &m)
        +					       	&& (!good || (GetTickCount()-starttime)<MAXDELAY));
        +			if (close_snap)
        +				close_snap(handle);
        +			else
        +				CloseHandle(handle);
        +
        +			}
        +
        +		FreeLibrary(kernel);
        +		}
        +	}
        +#endif /* !OPENSSL_SYS_WINCE */
        +
        +	/* 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 0
        +	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;
        +#if defined(_MSC_VER) && defined(_M_X86)
        +	static int have_tsc = 1;
        +	DWORD cyclecount;
        +
        +	if (have_tsc) {
        +	  __try {
        +	    __asm {
        +	      _emit 0x0f
        +	      _emit 0x31
        +	      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
        + * <URL:http://support.microsoft.com/default.aspx?scid=kb;[LN];97193>;
        + * 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)
        +{
        +#if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
        +  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 */
        +
        +  if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
        +    return;
        +
        +  /* Create a screen DC and a memory DC compatible to screen DC */
        +  hScrDC = CreateDC(TEXT("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);
        +#endif /* !OPENSSL_SYS_WINCE */
        +}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rand/randfile.c b/vendor/openssl/openssl/crypto/rand/randfile.c
        new file mode 100644
        index 000000000..7f1428072
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/randfile.c
        @@ -0,0 +1,328 @@
        +/* crypto/rand/randfile.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.]
        + */
        +
        +/* We need to define this to get macros like S_IFBLK and S_IFCHR */
        +#if !defined(OPENSSL_SYS_VXWORKS)
        +#define _XOPEN_SOURCE 500
        +#endif
        +
        +#include <errno.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +#include <openssl/crypto.h>
        +#include <openssl/rand.h>
        +#include <openssl/buffer.h>
        +
        +#ifdef OPENSSL_SYS_VMS
        +#include <unixio.h>
        +#endif
        +#ifndef NO_SYS_TYPES_H
        +# include <sys/types.h>
        +#endif
        +#ifndef OPENSSL_NO_POSIX_IO
        +# include <sys/stat.h>
        +#endif
        +
        +#ifdef _WIN32
        +#define stat	_stat
        +#define chmod	_chmod
        +#define open	_open
        +#define fdopen	_fdopen
        +#endif
        +
        +#undef BUFSIZE
        +#define BUFSIZE	1024
        +#define RAND_DATA 1024
        +
        +#ifdef OPENSSL_SYS_VMS
        +/* This declaration is a nasty hack to get around vms' extension to fopen
        + * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
        +static FILE *(*const vms_fopen)(const char *, const char *, ...) =
        +    (FILE *(*)(const char *, const char *, ...))fopen;
        +#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
        +#endif
        +
        +/* #define RFILE ".rnd" - defined in ../../e_os.h */
        +
        +/* Note that these functions are intended for seed files only.
        + * Entropy devices and EGD sockets are handled in rand_unix.c */
        +
        +int RAND_load_file(const char *file, long bytes)
        +	{
        +	/* If bytes >= 0, read up to 'bytes' bytes.
        +	 * if bytes == -1, read complete file. */
        +
        +	MS_STATIC unsigned char buf[BUFSIZE];
        +#ifndef OPENSSL_NO_POSIX_IO
        +	struct stat sb;
        +#endif
        +	int i,ret=0,n;
        +	FILE *in;
        +
        +	if (file == NULL) return(0);
        +
        +#ifndef OPENSSL_NO_POSIX_IO
        +#ifdef PURIFY
        +	/* struct stat can have padding and unused fields that may not be
        +	 * initialized in the call to stat(). We need to clear the entire
        +	 * structure before calling RAND_add() to avoid complaints from
        +	 * applications such as Valgrind.
        +	 */
        +	memset(&sb, 0, sizeof(sb));
        +#endif
        +	if (stat(file,&sb) < 0) return(0);
        +	RAND_add(&sb,sizeof(sb),0.0);
        +#endif
        +	if (bytes == 0) return(ret);
        +
        +#ifdef OPENSSL_SYS_VMS
        +	in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
        +#else
        +	in=fopen(file,"rb");
        +#endif
        +	if (in == NULL) goto err;
        +#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
        +	if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
        +	  /* this file is a device. we don't want read an infinite number
        +	   * of bytes from a random device, nor do we want to use buffered
        +	   * I/O because we will waste system entropy. 
        +	   */
        +	  bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
        +#ifndef OPENSSL_NO_SETVBUF_IONBF
        +	  setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
        +#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
        +	}
        +#endif
        +	for (;;)
        +		{
        +		if (bytes > 0)
        +			n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
        +		else
        +			n = BUFSIZE;
        +		i=fread(buf,1,n,in);
        +		if (i <= 0) break;
        +#ifdef PURIFY
        +		RAND_add(buf,i,(double)i);
        +#else
        +		/* even if n != i, use the full array */
        +		RAND_add(buf,n,(double)i);
        +#endif
        +		ret+=i;
        +		if (bytes > 0)
        +			{
        +			bytes-=n;
        +			if (bytes <= 0) break;
        +			}
        +		}
        +	fclose(in);
        +	OPENSSL_cleanse(buf,BUFSIZE);
        +err:
        +	return(ret);
        +	}
        +
        +int RAND_write_file(const char *file)
        +	{
        +	unsigned char buf[BUFSIZE];
        +	int i,ret=0,rand_err=0;
        +	FILE *out = NULL;
        +	int n;
        +#ifndef OPENSSL_NO_POSIX_IO
        +	struct stat sb;
        +	
        +	i=stat(file,&sb);
        +	if (i != -1) { 
        +#if defined(S_ISBLK) && defined(S_ISCHR)
        +	  if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
        +	    /* this file is a device. we don't write back to it. 
        +	     * we "succeed" on the assumption this is some sort 
        +	     * of random device. Otherwise attempting to write to 
        +	     * and chmod the device causes problems.
        +	     */
        +	    return(1); 
        +	  }
        +#endif
        +	}
        +#endif
        +
        +#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
        +	{
        +#ifndef O_BINARY
        +#define O_BINARY 0
        +#endif
        +	/* chmod(..., 0600) is too late to protect the file,
        +	 * permissions should be restrictive from the start */
        +	int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600);
        +	if (fd != -1)
        +		out = fdopen(fd, "wb");
        +	}
        +#endif
        +
        +#ifdef OPENSSL_SYS_VMS
        +	/* VMS NOTE: Prior versions of this routine created a _new_
        +	 * version of the rand file for each call into this routine, then
        +	 * deleted all existing versions named ;-1, and finally renamed
        +	 * the current version as ';1'. Under concurrent usage, this
        +	 * resulted in an RMS race condition in rename() which could
        +	 * orphan files (see vms message help for RMS$_REENT). With the
        +	 * fopen() calls below, openssl/VMS now shares the top-level
        +	 * version of the rand file. Note that there may still be
        +	 * conditions where the top-level rand file is locked. If so, this
        +	 * code will then create a new version of the rand file. Without
        +	 * the delete and rename code, this can result in ascending file
        +	 * versions that stop at version 32767, and this routine will then
        +	 * return an error. The remedy for this is to recode the calling
        +	 * application to avoid concurrent use of the rand file, or
        +	 * synchronize usage at the application level. Also consider
        +	 * whether or not you NEED a persistent rand file in a concurrent
        +	 * use situation. 
        +	 */
        +
        +	out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
        +	if (out == NULL)
        +		out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
        +#else
        +	if (out == NULL)
        +		out = fopen(file,"wb");
        +#endif
        +	if (out == NULL) goto err;
        +
        +#ifndef NO_CHMOD
        +	chmod(file,0600);
        +#endif
        +	n=RAND_DATA;
        +	for (;;)
        +		{
        +		i=(n > BUFSIZE)?BUFSIZE:n;
        +		n-=BUFSIZE;
        +		if (RAND_bytes(buf,i) <= 0)
        +			rand_err=1;
        +		i=fwrite(buf,1,i,out);
        +		if (i <= 0)
        +			{
        +			ret=0;
        +			break;
        +			}
        +		ret+=i;
        +		if (n <= 0) break;
        +                }
        +
        +	fclose(out);
        +	OPENSSL_cleanse(buf,BUFSIZE);
        +err:
        +	return (rand_err ? -1 : ret);
        +	}
        +
        +const char *RAND_file_name(char *buf, size_t size)
        +	{
        +	char *s=NULL;
        +#ifdef __OpenBSD__
        +	struct stat sb;
        +#endif
        +
        +	if (OPENSSL_issetugid() == 0)
        +		s=getenv("RANDFILE");
        +	if (s != NULL && *s && strlen(s) + 1 < size)
        +		{
        +		if (BUF_strlcpy(buf,s,size) >= size)
        +			return NULL;
        +		}
        +	else
        +		{
        +		if (OPENSSL_issetugid() == 0)
        +			s=getenv("HOME");
        +#ifdef DEFAULT_HOME
        +		if (s == NULL)
        +			{
        +			s = DEFAULT_HOME;
        +			}
        +#endif
        +		if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
        +			{
        +			BUF_strlcpy(buf,s,size);
        +#ifndef OPENSSL_SYS_VMS
        +			BUF_strlcat(buf,"/",size);
        +#endif
        +			BUF_strlcat(buf,RFILE,size);
        +			}
        +		else
        +		  	buf[0] = '\0'; /* no file name */
        +		}
        +
        +#ifdef __OpenBSD__
        +	/* given that all random loads just fail if the file can't be 
        +	 * seen on a stat, we stat the file we're returning, if it
        +	 * fails, use /dev/arandom instead. this allows the user to 
        +	 * use their own source for good random data, but defaults
        +	 * to something hopefully decent if that isn't available. 
        +	 */
        +
        +	if (!buf[0])
        +		if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
        +			return(NULL);
        +		}	
        +	if (stat(buf,&sb) == -1)
        +		if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
        +			return(NULL);
        +		}	
        +
        +#endif
        +	return(buf);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rand/randtest.c b/vendor/openssl/openssl/crypto/rand/randtest.c
        new file mode 100644
        index 000000000..9e92a70b0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rand/randtest.c
        @@ -0,0 +1,219 @@
        +/* crypto/rand/randtest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/rand.h>
        +
        +#include "../e_os.h"
        +
        +/* some FIPS 140-1 random number test */
        +/* some simple tests */
        +
        +int main(int argc,char **argv)
        +	{
        +	unsigned char buf[2500];
        +	int i,j,k,s,sign,nsign,err=0;
        +	unsigned long n1;
        +	unsigned long n2[16];
        +	unsigned long runs[2][34];
        +	/*double d; */
        +	long d;
        +
        +	i = RAND_pseudo_bytes(buf,2500);
        +	if (i < 0)
        +		{
        +		printf ("init failed, the rand method is not properly installed\n");
        +		err++;
        +		goto err;
        +		}
        +
        +	n1=0;
        +	for (i=0; i<16; i++) n2[i]=0;
        +	for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
        +
        +	/* test 1 and 2 */
        +	sign=0;
        +	nsign=0;
        +	for (i=0; i<2500; i++)
        +		{
        +		j=buf[i];
        +
        +		n2[j&0x0f]++;
        +		n2[(j>>4)&0x0f]++;
        +
        +		for (k=0; k<8; k++)
        +			{
        +			s=(j&0x01);
        +			if (s == sign)
        +				nsign++;
        +			else
        +				{
        +				if (nsign > 34) nsign=34;
        +				if (nsign != 0)
        +					{
        +					runs[sign][nsign-1]++;
        +					if (nsign > 6)
        +						runs[sign][5]++;
        +					}
        +				sign=s;
        +				nsign=1;
        +				}
        +
        +			if (s) n1++;
        +			j>>=1;
        +			}
        +		}
        +		if (nsign > 34) nsign=34;
        +		if (nsign != 0) runs[sign][nsign-1]++;
        +
        +	/* test 1 */
        +	if (!((9654 < n1) && (n1 < 10346)))
        +		{
        +		printf("test 1 failed, X=%lu\n",n1);
        +		err++;
        +		}
        +	printf("test 1 done\n");
        +
        +	/* test 2 */
        +#ifdef undef
        +	d=0;
        +	for (i=0; i<16; i++)
        +		d+=n2[i]*n2[i];
        +	d=d*16.0/5000.0-5000.0;
        +	if (!((1.03 < d) && (d < 57.4)))
        +		{
        +		printf("test 2 failed, X=%.2f\n",d);
        +		err++;
        +		}
        +#endif
        +	d=0;
        +	for (i=0; i<16; i++)
        +		d+=n2[i]*n2[i];
        +	d=(d*8)/25-500000;
        +	if (!((103 < d) && (d < 5740)))
        +		{
        +		printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
        +		err++;
        +		}
        +	printf("test 2 done\n");
        +
        +	/* test 3 */
        +	for (i=0; i<2; i++)
        +		{
        +		if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,1,runs[i][0]);
        +			err++;
        +			}
        +		if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,2,runs[i][1]);
        +			err++;
        +			}
        +		if (!(( 502 < runs[i][2]) && (runs[i][2] <  748)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,3,runs[i][2]);
        +			err++;
        +			}
        +		if (!(( 223 < runs[i][3]) && (runs[i][3] <  402)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,4,runs[i][3]);
        +			err++;
        +			}
        +		if (!((  90 < runs[i][4]) && (runs[i][4] <  223)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,5,runs[i][4]);
        +			err++;
        +			}
        +		if (!((  90 < runs[i][5]) && (runs[i][5] <  223)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,6,runs[i][5]);
        +			err++;
        +			}
        +		}
        +	printf("test 3 done\n");
        +	
        +	/* test 4 */
        +	if (runs[0][33] != 0)
        +		{
        +		printf("test 4 failed, bit=%d run=%d num=%lu\n",
        +			0,34,runs[0][33]);
        +		err++;
        +		}
        +	if (runs[1][33] != 0)
        +		{
        +		printf("test 4 failed, bit=%d run=%d num=%lu\n",
        +			1,34,runs[1][33]);
        +		err++;
        +		}
        +	printf("test 4 done\n");
        + err:
        +	err=((err)?1:0);
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(err);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rc2/Makefile b/vendor/openssl/openssl/crypto/rc2/Makefile
        new file mode 100644
        index 000000000..8a9d49ab5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/Makefile
        @@ -0,0 +1,90 @@
        +#
        +# OpenSSL/crypto/rc2/Makefile
        +#
        +
        +DIR=	rc2
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=rc2test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c
        +LIBOBJ=rc2_ecb.o rc2_skey.o rc2_cbc.o rc2cfb64.o rc2ofb64.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= rc2.h
        +HEADER=	rc2_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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rc2_cbc.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
        +rc2_cbc.o: rc2_cbc.c rc2_locl.h
        +rc2_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rc2_ecb.o: ../../include/openssl/rc2.h rc2_ecb.c rc2_locl.h
        +rc2_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rc2_skey.o: ../../include/openssl/opensslconf.h
        +rc2_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rc2_skey.o: ../../include/openssl/rc2.h ../../include/openssl/safestack.h
        +rc2_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rc2_skey.o: rc2_locl.h rc2_skey.c
        +rc2cfb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
        +rc2cfb64.o: rc2_locl.h rc2cfb64.c
        +rc2ofb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
        +rc2ofb64.o: rc2_locl.h rc2ofb64.c
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2.h b/vendor/openssl/openssl/crypto/rc2/rc2.h
        new file mode 100644
        index 000000000..e542ec94f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2.h
        @@ -0,0 +1,103 @@
        +/* crypto/rc2/rc2.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_RC2_H
        +#define HEADER_RC2_H
        +
        +#include <openssl/opensslconf.h> /* OPENSSL_NO_RC2, RC2_INT */
        +#ifdef OPENSSL_NO_RC2
        +#error RC2 is disabled.
        +#endif
        +
        +#define RC2_ENCRYPT	1
        +#define RC2_DECRYPT	0
        +
        +#define RC2_BLOCK	8
        +#define RC2_KEY_LENGTH	16
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct rc2_key_st
        +	{
        +	RC2_INT data[64];
        +	} RC2_KEY;
        +
        +#ifdef OPENSSL_FIPS 
        +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
        +#endif
        +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
        +void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
        +		     int enc);
        +void RC2_encrypt(unsigned long *data,RC2_KEY *key);
        +void RC2_decrypt(unsigned long *data,RC2_KEY *key);
        +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	RC2_KEY *ks, unsigned char *iv, int enc);
        +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +		       long length, RC2_KEY *schedule, unsigned char *ivec,
        +		       int *num, int enc);
        +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +		       long length, RC2_KEY *schedule, unsigned char *ivec,
        +		       int *num);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2_cbc.c b/vendor/openssl/openssl/crypto/rc2/rc2_cbc.c
        new file mode 100644
        index 000000000..74f48d3d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2_cbc.c
        @@ -0,0 +1,226 @@
        +/* crypto/rc2/rc2_cbc.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 <openssl/rc2.h>
        +#include "rc2_locl.h"
        +
        +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
        +	     RC2_KEY *ks, unsigned char *iv, int encrypt)
        +	{
        +	register unsigned long tin0,tin1;
        +	register unsigned long tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	unsigned long tin[2];
        +
        +	if (encrypt)
        +		{
        +		c2l(iv,tout0);
        +		c2l(iv,tout1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			RC2_encrypt(tin,ks);
        +			tout0=tin[0]; l2c(tout0,out);
        +			tout1=tin[1]; l2c(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			c2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			RC2_encrypt(tin,ks);
        +			tout0=tin[0]; l2c(tout0,out);
        +			tout1=tin[1]; l2c(tout1,out);
        +			}
        +		l2c(tout0,iv);
        +		l2c(tout1,iv);
        +		}
        +	else
        +		{
        +		c2l(iv,xor0);
        +		c2l(iv,xor1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0;
        +			c2l(in,tin1); tin[1]=tin1;
        +			RC2_decrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0;
        +			c2l(in,tin1); tin[1]=tin1;
        +			RC2_decrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2cn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		l2c(xor0,iv);
        +		l2c(xor1,iv);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        +void RC2_encrypt(unsigned long *d, RC2_KEY *key)
        +	{
        +	int i,n;
        +	register RC2_INT *p0,*p1;
        +	register RC2_INT x0,x1,x2,x3,t;
        +	unsigned long l;
        +
        +	l=d[0];
        +	x0=(RC2_INT)l&0xffff;
        +	x1=(RC2_INT)(l>>16L);
        +	l=d[1];
        +	x2=(RC2_INT)l&0xffff;
        +	x3=(RC2_INT)(l>>16L);
        +
        +	n=3;
        +	i=5;
        +
        +	p0=p1= &(key->data[0]);
        +	for (;;)
        +		{
        +		t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff;
        +		x0=(t<<1)|(t>>15);
        +		t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff;
        +		x1=(t<<2)|(t>>14);
        +		t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff;
        +		x2=(t<<3)|(t>>13);
        +		t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff;
        +		x3=(t<<5)|(t>>11);
        +
        +		if (--i == 0)
        +			{
        +			if (--n == 0) break;
        +			i=(n == 2)?6:5;
        +
        +			x0+=p1[x3&0x3f];
        +			x1+=p1[x0&0x3f];
        +			x2+=p1[x1&0x3f];
        +			x3+=p1[x2&0x3f];
        +			}
        +		}
        +
        +	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
        +	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
        +	}
        +
        +void RC2_decrypt(unsigned long *d, RC2_KEY *key)
        +	{
        +	int i,n;
        +	register RC2_INT *p0,*p1;
        +	register RC2_INT x0,x1,x2,x3,t;
        +	unsigned long l;
        +
        +	l=d[0];
        +	x0=(RC2_INT)l&0xffff;
        +	x1=(RC2_INT)(l>>16L);
        +	l=d[1];
        +	x2=(RC2_INT)l&0xffff;
        +	x3=(RC2_INT)(l>>16L);
        +
        +	n=3;
        +	i=5;
        +
        +	p0= &(key->data[63]);
        +	p1= &(key->data[0]);
        +	for (;;)
        +		{
        +		t=((x3<<11)|(x3>>5))&0xffff;
        +		x3=(t-(x0& ~x2)-(x1&x2)- *(p0--))&0xffff;
        +		t=((x2<<13)|(x2>>3))&0xffff;
        +		x2=(t-(x3& ~x1)-(x0&x1)- *(p0--))&0xffff;
        +		t=((x1<<14)|(x1>>2))&0xffff;
        +		x1=(t-(x2& ~x0)-(x3&x0)- *(p0--))&0xffff;
        +		t=((x0<<15)|(x0>>1))&0xffff;
        +		x0=(t-(x1& ~x3)-(x2&x3)- *(p0--))&0xffff;
        +
        +		if (--i == 0)
        +			{
        +			if (--n == 0) break;
        +			i=(n == 2)?6:5;
        +
        +			x3=(x3-p1[x2&0x3f])&0xffff;
        +			x2=(x2-p1[x1&0x3f])&0xffff;
        +			x1=(x1-p1[x0&0x3f])&0xffff;
        +			x0=(x0-p1[x3&0x3f])&0xffff;
        +			}
        +		}
        +
        +	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
        +	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2_ecb.c b/vendor/openssl/openssl/crypto/rc2/rc2_ecb.c
        new file mode 100644
        index 000000000..fff86c7af
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2_ecb.c
        @@ -0,0 +1,88 @@
        +/* crypto/rc2/rc2_ecb.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 <openssl/rc2.h>
        +#include "rc2_locl.h"
        +#include <openssl/opensslv.h>
        +
        +const char RC2_version[]="RC2" OPENSSL_VERSION_PTEXT;
        +
        +/* RC2 as implemented frm a posting from
        + * Newsgroups: sci.crypt
        + * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
        + * Subject: Specification for Ron Rivests Cipher No.2
        + * Message-ID: <4fk39f$f70@net.auckland.ac.nz>
        + * Date: 11 Feb 1996 06:45:03 GMT
        + */
        +
        +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks,
        +		     int encrypt)
        +	{
        +	unsigned long l,d[2];
        +
        +	c2l(in,l); d[0]=l;
        +	c2l(in,l); d[1]=l;
        +	if (encrypt)
        +		RC2_encrypt(d,ks);
        +	else
        +		RC2_decrypt(d,ks);
        +	l=d[0]; l2c(l,out);
        +	l=d[1]; l2c(l,out);
        +	l=d[0]=d[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2_locl.h b/vendor/openssl/openssl/crypto/rc2/rc2_locl.h
        new file mode 100644
        index 000000000..565cd1761
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2_locl.h
        @@ -0,0 +1,156 @@
        +/* crypto/rc2/rc2_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.]
        + */
        +
        +#undef c2l
        +#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
        +			 l|=((unsigned long)(*((c)++)))<< 8L, \
        +			 l|=((unsigned long)(*((c)++)))<<16L, \
        +			 l|=((unsigned long)(*((c)++)))<<24L)
        +
        +/* NOTE - c is not incremented as per c2l */
        +#undef c2ln
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 5: l2|=((unsigned long)(*(--(c))));     \
        +			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 1: l1|=((unsigned long)(*(--(c))));     \
        +				} \
        +			}
        +
        +#undef l2c
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +
        +/* NOTE - c is not incremented as per l2c */
        +#undef l2cn
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per n2l */
        +#define n2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))    ; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
        +			case 4: l1 =((unsigned long)(*(--(c))))    ; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per l2n */
        +#define l2nn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +				} \
        +			}
        +
        +#undef n2l
        +#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
        +                         l|=((unsigned long)(*((c)++)))<<16L, \
        +                         l|=((unsigned long)(*((c)++)))<< 8L, \
        +                         l|=((unsigned long)(*((c)++))))
        +
        +#undef l2n
        +#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)     )&0xff))
        +
        +#define C_RC2(n) \
        +	t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \
        +	x0=(t<<1)|(t>>15); \
        +	t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \
        +	x1=(t<<2)|(t>>14); \
        +	t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \
        +	x2=(t<<3)|(t>>13); \
        +	t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \
        +	x3=(t<<5)|(t>>11);
        +
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2_skey.c b/vendor/openssl/openssl/crypto/rc2/rc2_skey.c
        new file mode 100644
        index 000000000..6668ac011
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2_skey.c
        @@ -0,0 +1,153 @@
        +/* crypto/rc2/rc2_skey.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 <openssl/crypto.h>
        +#include <openssl/rc2.h>
        +#include "rc2_locl.h"
        +
        +static const unsigned char key_table[256]={
        +	0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79,
        +	0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e,
        +	0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5,
        +	0x87,0xb3,0x4f,0x13,0x61,0x45,0x6d,0x8d,0x09,0x81,0x7d,0x32,
        +	0xbd,0x8f,0x40,0xeb,0x86,0xb7,0x7b,0x0b,0xf0,0x95,0x21,0x22,
        +	0x5c,0x6b,0x4e,0x82,0x54,0xd6,0x65,0x93,0xce,0x60,0xb2,0x1c,
        +	0x73,0x56,0xc0,0x14,0xa7,0x8c,0xf1,0xdc,0x12,0x75,0xca,0x1f,
        +	0x3b,0xbe,0xe4,0xd1,0x42,0x3d,0xd4,0x30,0xa3,0x3c,0xb6,0x26,
        +	0x6f,0xbf,0x0e,0xda,0x46,0x69,0x07,0x57,0x27,0xf2,0x1d,0x9b,
        +	0xbc,0x94,0x43,0x03,0xf8,0x11,0xc7,0xf6,0x90,0xef,0x3e,0xe7,
        +	0x06,0xc3,0xd5,0x2f,0xc8,0x66,0x1e,0xd7,0x08,0xe8,0xea,0xde,
        +	0x80,0x52,0xee,0xf7,0x84,0xaa,0x72,0xac,0x35,0x4d,0x6a,0x2a,
        +	0x96,0x1a,0xd2,0x71,0x5a,0x15,0x49,0x74,0x4b,0x9f,0xd0,0x5e,
        +	0x04,0x18,0xa4,0xec,0xc2,0xe0,0x41,0x6e,0x0f,0x51,0xcb,0xcc,
        +	0x24,0x91,0xaf,0x50,0xa1,0xf4,0x70,0x39,0x99,0x7c,0x3a,0x85,
        +	0x23,0xb8,0xb4,0x7a,0xfc,0x02,0x36,0x5b,0x25,0x55,0x97,0x31,
        +	0x2d,0x5d,0xfa,0x98,0xe3,0x8a,0x92,0xae,0x05,0xdf,0x29,0x10,
        +	0x67,0x6c,0xba,0xc9,0xd3,0x00,0xe6,0xcf,0xe1,0x9e,0xa8,0x2c,
        +	0x63,0x16,0x01,0x3f,0x58,0xe2,0x89,0xa9,0x0d,0x38,0x34,0x1b,
        +	0xab,0x33,0xff,0xb0,0xbb,0x48,0x0c,0x5f,0xb9,0xb1,0xcd,0x2e,
        +	0xc5,0xf3,0xdb,0x47,0xe5,0xa5,0x9c,0x77,0x0a,0xa6,0x20,0x68,
        +	0xfe,0x7f,0xc1,0xad,
        +	};
        +
        +#if defined(_MSC_VER) && defined(_ARM_)
        +#pragma optimize("g",off)
        +#endif
        +
        +/* It has come to my attention that there are 2 versions of the RC2
        + * key schedule.  One which is normal, and anther which has a hook to
        + * use a reduced key length.
        + * BSAFE uses the 'retarded' version.  What I previously shipped is
        + * the same as specifying 1024 for the 'bits' parameter.  Bsafe uses
        + * a version where the bits parameter is the same as len*8 */
        +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
        +#ifdef OPENSSL_FIPS
        +	{
        +	fips_cipher_abort(RC2);
        +	private_RC2_set_key(key, len, data, bits);
        +	}
        +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
        +#endif
        +	{
        +	int i,j;
        +	unsigned char *k;
        +	RC2_INT *ki;
        +	unsigned int c,d;
        +
        +	k= (unsigned char *)&(key->data[0]);
        +	*k=0; /* for if there is a zero length key */
        +
        +	if (len > 128) len=128;
        +	if (bits <= 0) bits=1024;
        +	if (bits > 1024) bits=1024;
        +
        +	for (i=0; i<len; i++)
        +		k[i]=data[i];
        +
        +	/* expand table */
        +	d=k[len-1];
        +	j=0;
        +	for (i=len; i < 128; i++,j++)
        +		{
        +		d=key_table[(k[j]+d)&0xff];
        +		k[i]=d;
        +		}
        +
        +	/* hmm.... key reduction to 'bits' bits */
        +
        +	j=(bits+7)>>3;
        +	i=128-j;
        +	c= (0xff>>(-bits & 0x07));
        +
        +	d=key_table[k[i]&c];
        +	k[i]=d;
        +	while (i--)
        +		{
        +		d=key_table[k[i+j]^d];
        +		k[i]=d;
        +		}
        +
        +	/* copy from bytes into RC2_INT's */
        +	ki= &(key->data[63]);
        +	for (i=127; i>=0; i-=2)
        +		*(ki--)=((k[i]<<8)|k[i-1])&0xffff;
        +	}
        +
        +#if defined(_MSC_VER)
        +#pragma optimize("",on)
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2cfb64.c b/vendor/openssl/openssl/crypto/rc2/rc2cfb64.c
        new file mode 100644
        index 000000000..b3a0158a6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2cfb64.c
        @@ -0,0 +1,122 @@
        +/* crypto/rc2/rc2cfb64.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 <openssl/rc2.h>
        +#include "rc2_locl.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +		       long length, RC2_KEY *schedule, unsigned char *ivec,
        +		       int *num, int encrypt)
        +	{
        +	register unsigned long v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned long ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv=(unsigned char *)ivec;
        +	if (encrypt)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0); ti[0]=v0;
        +				c2l(iv,v1); ti[1]=v1;
        +				RC2_encrypt((unsigned long *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2c(t,iv);
        +				t=ti[1]; l2c(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0); ti[0]=v0;
        +				c2l(iv,v1); ti[1]=v1;
        +				RC2_encrypt((unsigned long *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2c(t,iv);
        +				t=ti[1]; l2c(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=t=c=cc=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2ofb64.c b/vendor/openssl/openssl/crypto/rc2/rc2ofb64.c
        new file mode 100644
        index 000000000..9e297867e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2ofb64.c
        @@ -0,0 +1,111 @@
        +/* crypto/rc2/rc2ofb64.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 <openssl/rc2.h>
        +#include "rc2_locl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +		       long length, RC2_KEY *schedule, unsigned char *ivec,
        +		       int *num)
        +	{
        +	register unsigned long v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned char d[8];
        +	register char *dp;
        +	unsigned long ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv=(unsigned char *)ivec;
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=(char *)d;
        +	l2c(v0,dp);
        +	l2c(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			RC2_encrypt((unsigned long *)ti,schedule);
        +			dp=(char *)d;
        +			t=ti[0]; l2c(t,dp);
        +			t=ti[1]; l2c(t,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +		v0=ti[0];
        +		v1=ti[1];
        +		iv=(unsigned char *)ivec;
        +		l2c(v0,iv);
        +		l2c(v1,iv);
        +		}
        +	t=v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2speed.c b/vendor/openssl/openssl/crypto/rc2/rc2speed.c
        new file mode 100644
        index 000000000..85cf6f65b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2speed.c
        @@ -0,0 +1,277 @@
        +/* crypto/rc2/rc2speed.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/rc2.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +#ifndef CLK_TCK
        +#define HZ	100.0
        +#else	/* CLK_TCK */
        +#define HZ ((double)CLK_TCK)
        +#endif	/* CLK_TCK */
        +#endif	/* HZ */
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static unsigned char key[] ={
        +			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
        +			};
        +	RC2_KEY sch;
        +	double a,b,c,d;
        +#ifndef SIGALRM
        +	long ca,cb,cc;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	RC2_set_key(&sch,16,key,128);
        +	count=10;
        +	do	{
        +		long i;
        +		unsigned long data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			RC2_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count/512;
        +	cb=count;
        +	cc=count*8/BUFSIZE+1;
        +	printf("Doing RC2_set_key %ld times\n",ca);
        +#define COND(d)	(count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing RC2_set_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count+=4)
        +		{
        +		RC2_set_key(&sch,16,key,128);
        +		RC2_set_key(&sch,16,key,128);
        +		RC2_set_key(&sch,16,key,128);
        +		RC2_set_key(&sch,16,key,128);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld RC2_set_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing RC2_encrypt's for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing RC2_encrypt %ld times\n",cb);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cb); count+=4)
        +		{
        +		unsigned long data[2];
        +
        +		RC2_encrypt(data,&sch);
        +		RC2_encrypt(data,&sch);
        +		RC2_encrypt(data,&sch);
        +		RC2_encrypt(data,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld RC2_encrypt's in %.2f second\n",count,d);
        +	b=((double)COUNT(cb)*8)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing RC2_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing RC2_cbc_encrypt %ld times on %ld byte blocks\n",cc,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		RC2_cbc_encrypt(buf,buf,BUFSIZE,&sch,
        +			&(key[0]),RC2_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld RC2_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +	printf("RC2 set_key       per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("RC2 raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
        +	printf("RC2 cbc     bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rc2/rc2test.c b/vendor/openssl/openssl/crypto/rc2/rc2test.c
        new file mode 100644
        index 000000000..0e117436b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rc2test.c
        @@ -0,0 +1,274 @@
        +/* crypto/rc2/rc2test.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.]
        + */
        +
        +/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
        + * RC2 modes, more of the code will be uncommented. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RC2
        +int main(int argc, char *argv[])
        +{
        +    printf("No RC2 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rc2.h>
        +
        +static unsigned char RC2key[4][16]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
        +	 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
        +	};
        +
        +static unsigned char RC2plain[4][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	};
        +
        +static unsigned char RC2cipher[4][8]={
        +	{0x1C,0x19,0x8A,0x83,0x8D,0xF0,0x28,0xB7},
        +	{0x21,0x82,0x9C,0x78,0xA9,0xF9,0xC0,0x74},
        +	{0x13,0xDB,0x35,0x17,0xD3,0x21,0x86,0x9E},
        +	{0x50,0xDC,0x01,0x62,0xBD,0x75,0x7F,0x31},
        +	};
        +/************/
        +#ifdef undef
        +unsigned char k[16]={
        +	0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
        +	0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
        +
        +unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
        +unsigned char  c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
        +unsigned char out[80];
        +
        +char *text="Hello to all people out there";
        +
        +static unsigned char cfb_key[16]={
        +	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
        +	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
        +	};
        +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +#define CFB_TEST_SIZE 24
        +static unsigned char plain[CFB_TEST_SIZE]=
        +        {
        +        0x4e,0x6f,0x77,0x20,0x69,0x73,
        +        0x20,0x74,0x68,0x65,0x20,0x74,
        +        0x69,0x6d,0x65,0x20,0x66,0x6f,
        +        0x72,0x20,0x61,0x6c,0x6c,0x20
        +        };
        +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
        +	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
        +	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
        +	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
        +
        +/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
        +	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
        +	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
        +	}; 
        +
        +
        +/*static int cfb64_test(unsigned char *cfb_cipher);*/
        +static char *pt(unsigned char *p);
        +#endif
        +
        +int main(int argc, char *argv[])
        +	{
        +	int i,n,err=0;
        +	RC2_KEY key; 
        +	unsigned char buf[8],buf2[8];
        +
        +	for (n=0; n<4; n++)
        +		{
        +		RC2_set_key(&key,16,&(RC2key[n][0]),0 /* or 1024 */);
        +
        +		RC2_ecb_encrypt(&(RC2plain[n][0]),buf,&key,RC2_ENCRYPT);
        +		if (memcmp(&(RC2cipher[n][0]),buf,8) != 0)
        +			{
        +			printf("ecb rc2 error encrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",RC2cipher[n][i]);
        +			err=20;
        +			printf("\n");
        +			}
        +
        +		RC2_ecb_encrypt(buf,buf2,&key,RC2_DECRYPT);
        +		if (memcmp(&(RC2plain[n][0]),buf2,8) != 0)
        +			{
        +			printf("ecb RC2 error decrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",RC2plain[n][i]);
        +			printf("\n");
        +			err=3;
        +			}
        +		}
        +
        +	if (err == 0) printf("ecb RC2 ok\n");
        +#ifdef undef
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt(out,out,8,&dkey,iv,0);
        +	idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
        +	if (memcmp(text,out,strlen(text)+1) != 0)
        +		{
        +		printf("cbc idea bad\n");
        +		err=4;
        +		}
        +	else
        +		printf("cbc idea ok\n");
        +
        +	printf("cfb64 idea ");
        +	if (cfb64_test(cfb_cipher64))
        +		{
        +		printf("bad\n");
        +		err=5;
        +		}
        +	else
        +		printf("ok\n");
        +#endif
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(err);
        +	}
        +
        +#ifdef undef
        +static int cfb64_test(unsigned char *cfb_cipher)
        +        {
        +        IDEA_KEY_SCHEDULE eks,dks;
        +        int err=0,i,n;
        +
        +        idea_set_encrypt_key(cfb_key,&eks);
        +        idea_set_decrypt_key(&eks,&dks);
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +                (long)CFB_TEST_SIZE-12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb64_encrypt encrypt error\n");
        +                for (i=0; i<CFB_TEST_SIZE; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf1[i])));
        +                }
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +                (long)CFB_TEST_SIZE-17,&dks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb_encrypt decrypt error\n");
        +                for (i=0; i<24; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf2[i])));
        +                }
        +        return(err);
        +        }
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +	
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc2/rrc2.doc b/vendor/openssl/openssl/crypto/rc2/rrc2.doc
        new file mode 100644
        index 000000000..f93ee003d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/rrc2.doc
        @@ -0,0 +1,219 @@
        +>From cygnus.mincom.oz.au!minbne.mincom.oz.au!bunyip.cc.uq.oz.au!munnari.OZ.AU!comp.vuw.ac.nz!waikato!auckland.ac.nz!news Mon Feb 12 18:48:17 EST 1996
        +Article 23601 of sci.crypt:
        +Path: cygnus.mincom.oz.au!minbne.mincom.oz.au!bunyip.cc.uq.oz.au!munnari.OZ.AU!comp.vuw.ac.nz!waikato!auckland.ac.nz!news
        +>From: pgut01@cs.auckland.ac.nz (Peter Gutmann)
        +Newsgroups: sci.crypt
        +Subject: Specification for Ron Rivests Cipher No.2
        +Date: 11 Feb 1996 06:45:03 GMT
        +Organization: University of Auckland
        +Lines: 203
        +Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
        +Message-ID: <4fk39f$f70@net.auckland.ac.nz>
        +NNTP-Posting-Host: cs26.cs.auckland.ac.nz
        +X-Newsreader: NN version 6.5.0 #3 (NOV)
        +
        +
        +
        +
        +                           Ron Rivest's Cipher No.2
        +                           ------------------------
        + 
        +Ron Rivest's Cipher No.2 (hereafter referred to as RRC.2, other people may
        +refer to it by other names) is word oriented, operating on a block of 64 bits
        +divided into four 16-bit words, with a key table of 64 words.  All data units
        +are little-endian.  This functional description of the algorithm is based in
        +the paper "The RC5 Encryption Algorithm" (RC5 is a trademark of RSADSI), using
        +the same general layout, terminology, and pseudocode style.
        + 
        + 
        +Notation and RRC.2 Primitive Operations
        + 
        +RRC.2 uses the following primitive operations:
        + 
        +1. Two's-complement addition of words, denoted by "+".  The inverse operation,
        +   subtraction, is denoted by "-".
        +2. Bitwise exclusive OR, denoted by "^".
        +3. Bitwise AND, denoted by "&".
        +4. Bitwise NOT, denoted by "~".
        +5. A left-rotation of words; the rotation of word x left by y is denoted
        +   x <<< y.  The inverse operation, right-rotation, is denoted x >>> y.
        + 
        +These operations are directly and efficiently supported by most processors.
        + 
        + 
        +The RRC.2 Algorithm
        + 
        +RRC.2 consists of three components, a *key expansion* algorithm, an
        +*encryption* algorithm, and a *decryption* algorithm.
        + 
        + 
        +Key Expansion
        + 
        +The purpose of the key-expansion routine is to expand the user's key K to fill
        +the expanded key array S, so S resembles an array of random binary words
        +determined by the user's secret key K.
        + 
        +Initialising the S-box
        + 
        +RRC.2 uses a single 256-byte S-box derived from the ciphertext contents of
        +Beale Cipher No.1 XOR'd with a one-time pad.  The Beale Ciphers predate modern
        +cryptography by enough time that there should be no concerns about trapdoors
        +hidden in the data.  They have been published widely, and the S-box can be
        +easily recreated from the one-time pad values and the Beale Cipher data taken
        +from a standard source.  To initialise the S-box:
        + 
        +  for i = 0 to 255 do
        +    sBox[ i ] = ( beale[ i ] mod 256 ) ^ pad[ i ]
        + 
        +The contents of Beale Cipher No.1 and the necessary one-time pad are given as
        +an appendix at the end of this document.  For efficiency, implementors may wish
        +to skip the Beale Cipher expansion and store the sBox table directly.
        + 
        +Expanding the Secret Key to 128 Bytes
        + 
        +The secret key is first expanded to fill 128 bytes (64 words).  The expansion
        +consists of taking the sum of the first and last bytes in the user key, looking
        +up the sum (modulo 256) in the S-box, and appending the result to the key.  The
        +operation is repeated with the second byte and new last byte of the key until
        +all 128 bytes have been generated.  Note that the following pseudocode treats
        +the S array as an array of 128 bytes rather than 64 words.
        + 
        +  for j = 0 to length-1 do
        +    S[ j ] = K[ j ]
        +  for j = length to 127 do
        +    s[ j ] = sBox[ ( S[ j-length ] + S[ j-1 ] ) mod 256 ];
        + 
        +At this point it is possible to perform a truncation of the effective key
        +length to ease the creation of espionage-enabled software products.  However
        +since the author cannot conceive why anyone would want to do this, it will not
        +be considered further.
        + 
        +The final phase of the key expansion involves replacing the first byte of S
        +with the entry selected from the S-box:
        + 
        +  S[ 0 ] = sBox[ S[ 0 ] ]
        + 
        + 
        +Encryption
        + 
        +The cipher has 16 full rounds, each divided into 4 subrounds.  Two of the full
        +rounds perform an additional transformation on the data.  Note that the
        +following pseudocode treats the S array as an array of 64 words rather than 128
        +bytes.
        + 
        +  for i = 0 to 15 do
        +    j = i * 4;
        +    word0 = ( word0 + ( word1 & ~word3 ) + ( word2 & word3 ) + S[ j+0 ] ) <<< 1
        +    word1 = ( word1 + ( word2 & ~word0 ) + ( word3 & word0 ) + S[ j+1 ] ) <<< 2
        +    word2 = ( word2 + ( word3 & ~word1 ) + ( word0 & word1 ) + S[ j+2 ] ) <<< 3
        +    word3 = ( word3 + ( word0 & ~word2 ) + ( word1 & word2 ) + S[ j+3 ] ) <<< 5
        + 
        +In addition the fifth and eleventh rounds add the contents of the S-box indexed
        +by one of the data words to another of the data words following the four
        +subrounds as follows:
        + 
        +    word0 = word0 + S[ word3 & 63 ];
        +    word1 = word1 + S[ word0 & 63 ];
        +    word2 = word2 + S[ word1 & 63 ];
        +    word3 = word3 + S[ word2 & 63 ];
        + 
        + 
        +Decryption
        + 
        +The decryption operation is simply the inverse of the encryption operation.
        +Note that the following pseudocode treats the S array as an array of 64 words
        +rather than 128 bytes.
        + 
        +  for i = 15 downto 0 do
        +    j = i * 4;
        +    word3 = ( word3 >>> 5 ) - ( word0 & ~word2 ) - ( word1 & word2 ) - S[ j+3 ]
        +    word2 = ( word2 >>> 3 ) - ( word3 & ~word1 ) - ( word0 & word1 ) - S[ j+2 ]
        +    word1 = ( word1 >>> 2 ) - ( word2 & ~word0 ) - ( word3 & word0 ) - S[ j+1 ]
        +    word0 = ( word0 >>> 1 ) - ( word1 & ~word3 ) - ( word2 & word3 ) - S[ j+0 ]
        + 
        +In addition the fifth and eleventh rounds subtract the contents of the S-box
        +indexed by one of the data words from another one of the data words following
        +the four subrounds as follows:
        + 
        +    word3 = word3 - S[ word2 & 63 ]
        +    word2 = word2 - S[ word1 & 63 ]
        +    word1 = word1 - S[ word0 & 63 ]
        +    word0 = word0 - S[ word3 & 63 ]
        + 
        + 
        +Test Vectors
        + 
        +The following test vectors may be used to test the correctness of an RRC.2
        +implementation:
        + 
        +  Key:      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        +  Plain:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        +  Cipher:   0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7
        + 
        +  Key:      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
        +  Plain:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        +  Cipher:   0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74
        + 
        +  Key:      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        +  Plain:    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
        +  Cipher:   0x13, 0xDB, 0x35, 0x17, 0xD3, 0x21, 0x86, 0x9E
        + 
        +  Key:      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
        +  Plain:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        +  Cipher:   0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31
        + 
        + 
        +Appendix: Beale Cipher No.1, "The Locality of the Vault", and One-time Pad for
        +          Creating the S-Box
        + 
        +Beale Cipher No.1.
        + 
        +  71, 194,  38,1701,  89,  76,  11,  83,1629,  48,  94,  63, 132,  16, 111,  95,
        +  84, 341, 975,  14,  40,  64,  27,  81, 139, 213,  63,  90,1120,   8,  15,   3,
        + 126,2018,  40,  74, 758, 485, 604, 230, 436, 664, 582, 150, 251, 284, 308, 231,
        + 124, 211, 486, 225, 401, 370,  11, 101, 305, 139, 189,  17,  33,  88, 208, 193,
        + 145,   1,  94,  73, 416, 918, 263,  28, 500, 538, 356, 117, 136, 219,  27, 176,
        + 130,  10, 460,  25, 485,  18, 436,  65,  84, 200, 283, 118, 320, 138,  36, 416,
        + 280,  15,  71, 224, 961,  44,  16, 401,  39,  88,  61, 304,  12,  21,  24, 283,
        + 134,  92,  63, 246, 486, 682,   7, 219, 184, 360, 780,  18,  64, 463, 474, 131,
        + 160,  79,  73, 440,  95,  18,  64, 581,  34,  69, 128, 367, 460,  17,  81,  12,
        + 103, 820,  62, 110,  97, 103, 862,  70,  60,1317, 471, 540, 208, 121, 890, 346,
        +  36, 150,  59, 568, 614,  13, 120,  63, 219, 812,2160,1780,  99,  35,  18,  21,
        + 136, 872,  15,  28, 170,  88,   4,  30,  44, 112,  18, 147, 436, 195, 320,  37,
        + 122, 113,   6, 140,   8, 120, 305,  42,  58, 461,  44, 106, 301,  13, 408, 680,
        +  93,  86, 116, 530,  82, 568,   9, 102,  38, 416,  89,  71, 216, 728, 965, 818,
        +   2,  38, 121, 195,  14, 326, 148, 234,  18,  55, 131, 234, 361, 824,   5,  81,
        + 623,  48, 961,  19,  26,  33,  10,1101, 365,  92,  88, 181, 275, 346, 201, 206
        + 
        +One-time Pad.
        + 
        + 158, 186, 223,  97,  64, 145, 190, 190, 117, 217, 163,  70, 206, 176, 183, 194,
        + 146,  43, 248, 141,   3,  54,  72, 223, 233, 153,  91, 210,  36, 131, 244, 161,
        + 105, 120, 113, 191, 113,  86,  19, 245, 213, 221,  43,  27, 242, 157,  73, 213,
        + 193,  92, 166,  10,  23, 197, 112, 110, 193,  30, 156,  51, 125,  51, 158,  67,
        + 197, 215,  59, 218, 110, 246, 181,   0, 135,  76, 164,  97,  47,  87, 234, 108,
        + 144, 127,   6,   6, 222, 172,  80, 144,  22, 245, 207,  70, 227, 182, 146, 134,
        + 119, 176,  73,  58, 135,  69,  23, 198,   0, 170,  32, 171, 176, 129,  91,  24,
        + 126,  77, 248,   0, 118,  69,  57,  60, 190, 171, 217,  61, 136, 169, 196,  84,
        + 168, 167, 163, 102, 223,  64, 174, 178, 166, 239, 242, 195, 249,  92,  59,  38,
        + 241,  46, 236,  31,  59, 114,  23,  50, 119, 186,   7,  66, 212,  97, 222, 182,
        + 230, 118, 122,  86, 105,  92, 179, 243, 255, 189, 223, 164, 194, 215,  98,  44,
        +  17,  20,  53, 153, 137, 224, 176, 100, 208, 114,  36, 200, 145, 150, 215,  20,
        +  87,  44, 252,  20, 235, 242, 163, 132,  63,  18,   5, 122,  74,  97,  34,  97,
        + 142,  86, 146, 221, 179, 166, 161,  74,  69, 182,  88, 120, 128,  58,  76, 155,
        +  15,  30,  77, 216, 165, 117, 107,  90, 169, 127, 143, 181, 208, 137, 200, 127,
        + 170, 195,  26,  84, 255, 132, 150,  58, 103, 250, 120, 221, 237,  37,   8,  99
        + 
        + 
        +Implementation
        + 
        +A non-US based programmer who has never seen any encryption code before will
        +shortly be implementing RRC.2 based solely on this specification and not on
        +knowledge of any other encryption algorithms.  Stand by.
        +
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/rc2/tab.c b/vendor/openssl/openssl/crypto/rc2/tab.c
        new file mode 100644
        index 000000000..25dc14eeb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/tab.c
        @@ -0,0 +1,86 @@
        +#include <stdio.h>
        +
        +unsigned char ebits_to_num[256]={
        +	0xbd,0x56,0xea,0xf2,0xa2,0xf1,0xac,0x2a,
        +	0xb0,0x93,0xd1,0x9c,0x1b,0x33,0xfd,0xd0,
        +	0x30,0x04,0xb6,0xdc,0x7d,0xdf,0x32,0x4b,
        +	0xf7,0xcb,0x45,0x9b,0x31,0xbb,0x21,0x5a,
        +	0x41,0x9f,0xe1,0xd9,0x4a,0x4d,0x9e,0xda,
        +	0xa0,0x68,0x2c,0xc3,0x27,0x5f,0x80,0x36,
        +	0x3e,0xee,0xfb,0x95,0x1a,0xfe,0xce,0xa8,
        +	0x34,0xa9,0x13,0xf0,0xa6,0x3f,0xd8,0x0c,
        +	0x78,0x24,0xaf,0x23,0x52,0xc1,0x67,0x17,
        +	0xf5,0x66,0x90,0xe7,0xe8,0x07,0xb8,0x60,
        +	0x48,0xe6,0x1e,0x53,0xf3,0x92,0xa4,0x72,
        +	0x8c,0x08,0x15,0x6e,0x86,0x00,0x84,0xfa,
        +	0xf4,0x7f,0x8a,0x42,0x19,0xf6,0xdb,0xcd,
        +	0x14,0x8d,0x50,0x12,0xba,0x3c,0x06,0x4e,
        +	0xec,0xb3,0x35,0x11,0xa1,0x88,0x8e,0x2b,
        +	0x94,0x99,0xb7,0x71,0x74,0xd3,0xe4,0xbf,
        +	0x3a,0xde,0x96,0x0e,0xbc,0x0a,0xed,0x77,
        +	0xfc,0x37,0x6b,0x03,0x79,0x89,0x62,0xc6,
        +	0xd7,0xc0,0xd2,0x7c,0x6a,0x8b,0x22,0xa3,
        +	0x5b,0x05,0x5d,0x02,0x75,0xd5,0x61,0xe3,
        +	0x18,0x8f,0x55,0x51,0xad,0x1f,0x0b,0x5e,
        +	0x85,0xe5,0xc2,0x57,0x63,0xca,0x3d,0x6c,
        +	0xb4,0xc5,0xcc,0x70,0xb2,0x91,0x59,0x0d,
        +	0x47,0x20,0xc8,0x4f,0x58,0xe0,0x01,0xe2,
        +	0x16,0x38,0xc4,0x6f,0x3b,0x0f,0x65,0x46,
        +	0xbe,0x7e,0x2d,0x7b,0x82,0xf9,0x40,0xb5,
        +	0x1d,0x73,0xf8,0xeb,0x26,0xc7,0x87,0x97,
        +	0x25,0x54,0xb1,0x28,0xaa,0x98,0x9d,0xa5,
        +	0x64,0x6d,0x7a,0xd4,0x10,0x81,0x44,0xef,
        +	0x49,0xd6,0xae,0x2e,0xdd,0x76,0x5c,0x2f,
        +	0xa7,0x1c,0xc9,0x09,0x69,0x9a,0x83,0xcf,
        +	0x29,0x39,0xb9,0xe9,0x4c,0xff,0x43,0xab,
        +	};
        +
        +unsigned char num_to_ebits[256]={
        +	0x5d,0xbe,0x9b,0x8b,0x11,0x99,0x6e,0x4d,
        +	0x59,0xf3,0x85,0xa6,0x3f,0xb7,0x83,0xc5,
        +	0xe4,0x73,0x6b,0x3a,0x68,0x5a,0xc0,0x47,
        +	0xa0,0x64,0x34,0x0c,0xf1,0xd0,0x52,0xa5,
        +	0xb9,0x1e,0x96,0x43,0x41,0xd8,0xd4,0x2c,
        +	0xdb,0xf8,0x07,0x77,0x2a,0xca,0xeb,0xef,
        +	0x10,0x1c,0x16,0x0d,0x38,0x72,0x2f,0x89,
        +	0xc1,0xf9,0x80,0xc4,0x6d,0xae,0x30,0x3d,
        +	0xce,0x20,0x63,0xfe,0xe6,0x1a,0xc7,0xb8,
        +	0x50,0xe8,0x24,0x17,0xfc,0x25,0x6f,0xbb,
        +	0x6a,0xa3,0x44,0x53,0xd9,0xa2,0x01,0xab,
        +	0xbc,0xb6,0x1f,0x98,0xee,0x9a,0xa7,0x2d,
        +	0x4f,0x9e,0x8e,0xac,0xe0,0xc6,0x49,0x46,
        +	0x29,0xf4,0x94,0x8a,0xaf,0xe1,0x5b,0xc3,
        +	0xb3,0x7b,0x57,0xd1,0x7c,0x9c,0xed,0x87,
        +	0x40,0x8c,0xe2,0xcb,0x93,0x14,0xc9,0x61,
        +	0x2e,0xe5,0xcc,0xf6,0x5e,0xa8,0x5c,0xd6,
        +	0x75,0x8d,0x62,0x95,0x58,0x69,0x76,0xa1,
        +	0x4a,0xb5,0x55,0x09,0x78,0x33,0x82,0xd7,
        +	0xdd,0x79,0xf5,0x1b,0x0b,0xde,0x26,0x21,
        +	0x28,0x74,0x04,0x97,0x56,0xdf,0x3c,0xf0,
        +	0x37,0x39,0xdc,0xff,0x06,0xa4,0xea,0x42,
        +	0x08,0xda,0xb4,0x71,0xb0,0xcf,0x12,0x7a,
        +	0x4e,0xfa,0x6c,0x1d,0x84,0x00,0xc8,0x7f,
        +	0x91,0x45,0xaa,0x2b,0xc2,0xb1,0x8f,0xd5,
        +	0xba,0xf2,0xad,0x19,0xb2,0x67,0x36,0xf7,
        +	0x0f,0x0a,0x92,0x7d,0xe3,0x9d,0xe9,0x90,
        +	0x3e,0x23,0x27,0x66,0x13,0xec,0x81,0x15,
        +	0xbd,0x22,0xbf,0x9f,0x7e,0xa9,0x51,0x4b,
        +	0x4c,0xfb,0x02,0xd3,0x70,0x86,0x31,0xe7,
        +	0x3b,0x05,0x03,0x54,0x60,0x48,0x65,0x18,
        +	0xd2,0xcd,0x5f,0x32,0x88,0x0e,0x35,0xfd,
        +	};
        +	
        +main()
        +	{
        +	int i,j;
        +
        +	for (i=0; i<256; i++)
        +		{
        +		for (j=0; j<256; j++)
        +			if (ebits_to_num[j] == i)
        +				{
        +				printf("0x%02x,",j);
        +				break;
        +				}
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rc2/version b/vendor/openssl/openssl/crypto/rc2/version
        new file mode 100644
        index 000000000..6f89d595f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc2/version
        @@ -0,0 +1,22 @@
        +1.1 23/08/96 - eay
        +	Changed RC2_set_key() so it now takes another argument.  Many
        +	thanks to Peter Gutmann <pgut01@cs.auckland.ac.nz> for the
        +	clarification and origional specification of RC2.  BSAFE uses
        +	this last parameter, 'bits'.  It the key is 128 bits, BSAFE
        +	also sets this parameter to 128.  The old behaviour can be
        +	duplicated by setting this parameter to 1024.
        +
        +1.0 08/04/96 - eay
        +	First version of SSLeay with rc2.  This has been written from the spec
        +	posted sci.crypt.  It is in this directory under rrc2.doc
        +	I have no test values for any mode other than ecb, my wrappers for the
        +	other modes should be ok since they are basically the same as
        +	the ones taken from idea and des :-).  I have implemented them as
        +	little-endian operators.
        +	While rc2 is included because it is used with SSL, I don't know how
        +	far I trust it.  It is about the same speed as IDEA and DES.
        +	So if you are paranoid, used Tripple DES, else IDEA.  If RC2
        +	does get used more, perhaps more people will look for weaknesses in
        +	it.
        +	
        +
        diff --git a/vendor/openssl/openssl/crypto/rc4/Makefile b/vendor/openssl/openssl/crypto/rc4/Makefile
        new file mode 100644
        index 000000000..1614d4796
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/Makefile
        @@ -0,0 +1,125 @@
        +#
        +# OpenSSL/crypto/rc4/Makefile
        +#
        +
        +DIR=	rc4
        +TOP=	../..
        +CC=	cc
        +CPP=    $(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +AR=		ar r
        +
        +RC4_ENC=rc4_enc.o rc4_skey.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=rc4test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=rc4_skey.c rc4_enc.c rc4_utl.c
        +LIBOBJ=$(RC4_ENC) rc4_utl.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= rc4.h
        +HEADER=	$(EXHEADER) rc4_locl.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +rc4-586.s:	asm/rc4-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/rc4-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
        +
        +rc4-x86_64.s: asm/rc4-x86_64.pl
        +	$(PERL) asm/rc4-x86_64.pl $(PERLASM_SCHEME) > $@
        +rc4-md5-x86_64.s:	asm/rc4-md5-x86_64.pl
        +	$(PERL) asm/rc4-md5-x86_64.pl $(PERLASM_SCHEME) > $@
        +
        +rc4-ia64.S: asm/rc4-ia64.pl
        +	$(PERL) asm/rc4-ia64.pl $(CFLAGS) > $@
        +
        +rc4-parisc.s:	asm/rc4-parisc.pl
        +	$(PERL) asm/rc4-parisc.pl $(PERLASM_SCHEME) $@
        +
        +rc4-ia64.s: rc4-ia64.S
        +	@case `awk '/^#define RC4_INT/{print$$NF}' $(TOP)/include/openssl/opensslconf.h` in \
        +	int)	set -x; $(CC) $(CFLAGS) -DSZ=4 -E rc4-ia64.S > $@ ;; \
        +	char)	set -x; $(CC) $(CFLAGS) -DSZ=1 -E rc4-ia64.S > $@ ;; \
        +	*)	exit 1 ;; \
        +	esac
        +
        +# GNU make "catch all"
        +rc4-%.s:	asm/rc4-%.pl;	$(PERL) $< $(PERLASM_SCHEME) $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rc4_enc.o: ../../e_os.h ../../include/openssl/bio.h
        +rc4_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rc4_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rc4_enc.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rc4_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rc4_enc.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
        +rc4_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rc4_enc.o: ../cryptlib.h rc4_enc.c rc4_locl.h
        +rc4_skey.o: ../../e_os.h ../../include/openssl/bio.h
        +rc4_skey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rc4_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rc4_skey.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rc4_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rc4_skey.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
        +rc4_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rc4_skey.o: ../cryptlib.h rc4_locl.h rc4_skey.c
        +rc4_utl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rc4_utl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rc4_utl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
        +rc4_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rc4_utl.o: ../../include/openssl/symhacks.h rc4_utl.c
        diff --git a/vendor/openssl/openssl/crypto/rc4/asm/rc4-586.pl b/vendor/openssl/openssl/crypto/rc4/asm/rc4-586.pl
        new file mode 100644
        index 000000000..5c9ac6ad2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/asm/rc4-586.pl
        @@ -0,0 +1,410 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# At some point it became apparent that the original SSLeay RC4
        +# assembler implementation performs suboptimally on latest IA-32
        +# microarchitectures. After re-tuning performance has changed as
        +# following:
        +#
        +# Pentium	-10%
        +# Pentium III	+12%
        +# AMD		+50%(*)
        +# P4		+250%(**)
        +#
        +# (*)	This number is actually a trade-off:-) It's possible to
        +#	achieve	+72%, but at the cost of -48% off PIII performance.
        +#	In other words code performing further 13% faster on AMD
        +#	would perform almost 2 times slower on Intel PIII...
        +#	For reference! This code delivers ~80% of rc4-amd64.pl
        +#	performance on the same Opteron machine.
        +# (**)	This number requires compressed key schedule set up by
        +#	RC4_set_key [see commentary below for further details].
        +#
        +#					<appro@fy.chalmers.se>
        +
        +# May 2011
        +#
        +# Optimize for Core2 and Westmere [and incidentally Opteron]. Current
        +# performance in cycles per processed byte (less is better) and
        +# improvement relative to previous version of this module is:
        +#
        +# Pentium	10.2			# original numbers
        +# Pentium III	7.8(*)
        +# Intel P4	7.5
        +#
        +# Opteron	6.1/+20%		# new MMX numbers
        +# Core2		5.3/+67%(**)
        +# Westmere	5.1/+94%(**)
        +# Sandy Bridge	5.0/+8%
        +# Atom		12.6/+6%
        +#
        +# (*)	PIII can actually deliver 6.6 cycles per byte with MMX code,
        +#	but this specific code performs poorly on Core2. And vice
        +#	versa, below MMX/SSE code delivering 5.8/7.1 on Core2 performs
        +#	poorly on PIII, at 8.0/14.5:-( As PIII is not a "hot" CPU
        +#	[anymore], I chose to discard PIII-specific code path and opt
        +#	for original IALU-only code, which is why MMX/SSE code path
        +#	is guarded by SSE2 bit (see below), not MMX/SSE.
        +# (**)	Performance vs. block size on Core2 and Westmere had a maximum
        +#	at ... 64 bytes block size. And it was quite a maximum, 40-60%
        +#	in comparison to largest 8KB block size. Above improvement
        +#	coefficients are for the largest block size.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"rc4-586.pl");
        +
        +$xx="eax";
        +$yy="ebx";
        +$tx="ecx";
        +$ty="edx";
        +$inp="esi";
        +$out="ebp";
        +$dat="edi";
        +
        +sub RC4_loop {
        +  my $i=shift;
        +  my $func = ($i==0)?*mov:*or;
        +
        +	&add	(&LB($yy),&LB($tx));
        +	&mov	($ty,&DWP(0,$dat,$yy,4));
        +	&mov	(&DWP(0,$dat,$yy,4),$tx);
        +	&mov	(&DWP(0,$dat,$xx,4),$ty);
        +	&add	($ty,$tx);
        +	&inc	(&LB($xx));
        +	&and	($ty,0xff);
        +	&ror	($out,8)	if ($i!=0);
        +	if ($i<3) {
        +	  &mov	($tx,&DWP(0,$dat,$xx,4));
        +	} else {
        +	  &mov	($tx,&wparam(3));	# reload [re-biased] out
        +	}
        +	&$func	($out,&DWP(0,$dat,$ty,4));
        +}
        +
        +if ($alt=0) {
        +  # >20% faster on Atom and Sandy Bridge[!], 8% faster on Opteron,
        +  # but ~40% slower on Core2 and Westmere... Attempt to add movz
        +  # brings down Opteron by 25%, Atom and Sandy Bridge by 15%, yet
        +  # on Core2 with movz it's almost 20% slower than below alternative
        +  # code... Yes, it's a total mess...
        +  my @XX=($xx,$out);
        +  $RC4_loop_mmx = sub {		# SSE actually...
        +    my $i=shift;
        +    my $j=$i<=0?0:$i>>1;
        +    my $mm=$i<=0?"mm0":"mm".($i&1);
        +
        +	&add	(&LB($yy),&LB($tx));
        +	&lea	(@XX[1],&DWP(1,@XX[0]));
        +	&pxor	("mm2","mm0")				if ($i==0);
        +	&psllq	("mm1",8)				if ($i==0);
        +	&and	(@XX[1],0xff);
        +	&pxor	("mm0","mm0")				if ($i<=0);
        +	&mov	($ty,&DWP(0,$dat,$yy,4));
        +	&mov	(&DWP(0,$dat,$yy,4),$tx);
        +	&pxor	("mm1","mm2")				if ($i==0);
        +	&mov	(&DWP(0,$dat,$XX[0],4),$ty);
        +	&add	(&LB($ty),&LB($tx));
        +	&movd	(@XX[0],"mm7")				if ($i==0);
        +	&mov	($tx,&DWP(0,$dat,@XX[1],4));
        +	&pxor	("mm1","mm1")				if ($i==1);
        +	&movq	("mm2",&QWP(0,$inp))			if ($i==1);
        +	&movq	(&QWP(-8,(@XX[0],$inp)),"mm1")		if ($i==0);
        +	&pinsrw	($mm,&DWP(0,$dat,$ty,4),$j);
        +
        +	push	(@XX,shift(@XX))			if ($i>=0);
        +  }
        +} else {
        +  # Using pinsrw here improves performane on Intel CPUs by 2-3%, but
        +  # brings down AMD by 7%...
        +  $RC4_loop_mmx = sub {
        +    my $i=shift;
        +
        +	&add	(&LB($yy),&LB($tx));
        +	&psllq	("mm1",8*(($i-1)&7))			if (abs($i)!=1);
        +	&mov	($ty,&DWP(0,$dat,$yy,4));
        +	&mov	(&DWP(0,$dat,$yy,4),$tx);
        +	&mov	(&DWP(0,$dat,$xx,4),$ty);
        +	&inc	($xx);
        +	&add	($ty,$tx);
        +	&movz	($xx,&LB($xx));				# (*)
        +	&movz	($ty,&LB($ty));				# (*)
        +	&pxor	("mm2",$i==1?"mm0":"mm1")		if ($i>=0);
        +	&movq	("mm0",&QWP(0,$inp))			if ($i<=0);
        +	&movq	(&QWP(-8,($out,$inp)),"mm2")		if ($i==0);
        +	&mov	($tx,&DWP(0,$dat,$xx,4));
        +	&movd	($i>0?"mm1":"mm2",&DWP(0,$dat,$ty,4));
        +
        +	# (*)	This is the key to Core2 and Westmere performance.
        +	#	Whithout movz out-of-order execution logic confuses
        +	#	itself and fails to reorder loads and stores. Problem
        +	#	appears to be fixed in Sandy Bridge...
        +  }
        +}
        +
        +&external_label("OPENSSL_ia32cap_P");
        +
        +# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
        +&function_begin("RC4");
        +	&mov	($dat,&wparam(0));	# load key schedule pointer
        +	&mov	($ty, &wparam(1));	# load len
        +	&mov	($inp,&wparam(2));	# load inp
        +	&mov	($out,&wparam(3));	# load out
        +
        +	&xor	($xx,$xx);		# avoid partial register stalls
        +	&xor	($yy,$yy);
        +
        +	&cmp	($ty,0);		# safety net
        +	&je	(&label("abort"));
        +
        +	&mov	(&LB($xx),&BP(0,$dat));	# load key->x
        +	&mov	(&LB($yy),&BP(4,$dat));	# load key->y
        +	&add	($dat,8);
        +
        +	&lea	($tx,&DWP(0,$inp,$ty));
        +	&sub	($out,$inp);		# re-bias out
        +	&mov	(&wparam(1),$tx);	# save input+len
        +
        +	&inc	(&LB($xx));
        +
        +	# detect compressed key schedule...
        +	&cmp	(&DWP(256,$dat),-1);
        +	&je	(&label("RC4_CHAR"));
        +
        +	&mov	($tx,&DWP(0,$dat,$xx,4));
        +
        +	&and	($ty,-4);		# how many 4-byte chunks?
        +	&jz	(&label("loop1"));
        +
        +	&test	($ty,-8);
        +	&mov	(&wparam(3),$out);	# $out as accumulator in these loops
        +	&jz	(&label("go4loop4"));
        +
        +	&picmeup($out,"OPENSSL_ia32cap_P");
        +	&bt	(&DWP(0,$out),26);	# check SSE2 bit [could have been MMX]
        +	&jnc	(&label("go4loop4"));
        +
        +	&mov	($out,&wparam(3))	if (!$alt);
        +	&movd	("mm7",&wparam(3))	if ($alt);
        +	&and	($ty,-8);
        +	&lea	($ty,&DWP(-8,$inp,$ty));
        +	&mov	(&DWP(-4,$dat),$ty);	# save input+(len/8)*8-8
        +
        +	&$RC4_loop_mmx(-1);
        +	&jmp(&label("loop_mmx_enter"));
        +
        +	&set_label("loop_mmx",16);
        +		&$RC4_loop_mmx(0);
        +	&set_label("loop_mmx_enter");
        +		for 	($i=1;$i<8;$i++) { &$RC4_loop_mmx($i); }
        +		&mov	($ty,$yy);
        +		&xor	($yy,$yy);		# this is second key to Core2
        +		&mov	(&LB($yy),&LB($ty));	# and Westmere performance...
        +		&cmp	($inp,&DWP(-4,$dat));
        +		&lea	($inp,&DWP(8,$inp));
        +	&jb	(&label("loop_mmx"));
        +
        +    if ($alt) {
        +	&movd	($out,"mm7");
        +	&pxor	("mm2","mm0");
        +	&psllq	("mm1",8);
        +	&pxor	("mm1","mm2");
        +	&movq	(&QWP(-8,$out,$inp),"mm1");
        +    } else {
        +	&psllq	("mm1",56);
        +	&pxor	("mm2","mm1");
        +	&movq	(&QWP(-8,$out,$inp),"mm2");
        +    }
        +	&emms	();
        +
        +	&cmp	($inp,&wparam(1));	# compare to input+len
        +	&je	(&label("done"));
        +	&jmp	(&label("loop1"));
        +
        +&set_label("go4loop4",16);
        +	&lea	($ty,&DWP(-4,$inp,$ty));
        +	&mov	(&wparam(2),$ty);	# save input+(len/4)*4-4
        +
        +	&set_label("loop4");
        +		for ($i=0;$i<4;$i++) { RC4_loop($i); }
        +		&ror	($out,8);
        +		&xor	($out,&DWP(0,$inp));
        +		&cmp	($inp,&wparam(2));	# compare to input+(len/4)*4-4
        +		&mov	(&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here
        +		&lea	($inp,&DWP(4,$inp));
        +		&mov	($tx,&DWP(0,$dat,$xx,4));
        +	&jb	(&label("loop4"));
        +
        +	&cmp	($inp,&wparam(1));	# compare to input+len
        +	&je	(&label("done"));
        +	&mov	($out,&wparam(3));	# restore $out
        +
        +	&set_label("loop1",16);
        +		&add	(&LB($yy),&LB($tx));
        +		&mov	($ty,&DWP(0,$dat,$yy,4));
        +		&mov	(&DWP(0,$dat,$yy,4),$tx);
        +		&mov	(&DWP(0,$dat,$xx,4),$ty);
        +		&add	($ty,$tx);
        +		&inc	(&LB($xx));
        +		&and	($ty,0xff);
        +		&mov	($ty,&DWP(0,$dat,$ty,4));
        +		&xor	(&LB($ty),&BP(0,$inp));
        +		&lea	($inp,&DWP(1,$inp));
        +		&mov	($tx,&DWP(0,$dat,$xx,4));
        +		&cmp	($inp,&wparam(1));	# compare to input+len
        +		&mov	(&BP(-1,$out,$inp),&LB($ty));
        +	&jb	(&label("loop1"));
        +
        +	&jmp	(&label("done"));
        +
        +# this is essentially Intel P4 specific codepath...
        +&set_label("RC4_CHAR",16);
        +	&movz	($tx,&BP(0,$dat,$xx));
        +	# strangely enough unrolled loop performs over 20% slower...
        +	&set_label("cloop1");
        +		&add	(&LB($yy),&LB($tx));
        +		&movz	($ty,&BP(0,$dat,$yy));
        +		&mov	(&BP(0,$dat,$yy),&LB($tx));
        +		&mov	(&BP(0,$dat,$xx),&LB($ty));
        +		&add	(&LB($ty),&LB($tx));
        +		&movz	($ty,&BP(0,$dat,$ty));
        +		&add	(&LB($xx),1);
        +		&xor	(&LB($ty),&BP(0,$inp));
        +		&lea	($inp,&DWP(1,$inp));
        +		&movz	($tx,&BP(0,$dat,$xx));
        +		&cmp	($inp,&wparam(1));
        +		&mov	(&BP(-1,$out,$inp),&LB($ty));
        +	&jb	(&label("cloop1"));
        +
        +&set_label("done");
        +	&dec	(&LB($xx));
        +	&mov	(&DWP(-4,$dat),$yy);		# save key->y
        +	&mov	(&BP(-8,$dat),&LB($xx));	# save key->x
        +&set_label("abort");
        +&function_end("RC4");
        +
        +########################################################################
        +
        +$inp="esi";
        +$out="edi";
        +$idi="ebp";
        +$ido="ecx";
        +$idx="edx";
        +
        +# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
        +&function_begin("private_RC4_set_key");
        +	&mov	($out,&wparam(0));		# load key
        +	&mov	($idi,&wparam(1));		# load len
        +	&mov	($inp,&wparam(2));		# load data
        +	&picmeup($idx,"OPENSSL_ia32cap_P");
        +
        +	&lea	($out,&DWP(2*4,$out));		# &key->data
        +	&lea	($inp,&DWP(0,$inp,$idi));	# $inp to point at the end
        +	&neg	($idi);
        +	&xor	("eax","eax");
        +	&mov	(&DWP(-4,$out),$idi);		# borrow key->y
        +
        +	&bt	(&DWP(0,$idx),20);		# check for bit#20
        +	&jc	(&label("c1stloop"));
        +
        +&set_label("w1stloop",16);
        +	&mov	(&DWP(0,$out,"eax",4),"eax");	# key->data[i]=i;
        +	&add	(&LB("eax"),1);			# i++;
        +	&jnc	(&label("w1stloop"));
        +
        +	&xor	($ido,$ido);
        +	&xor	($idx,$idx);
        +
        +&set_label("w2ndloop",16);
        +	&mov	("eax",&DWP(0,$out,$ido,4));
        +	&add	(&LB($idx),&BP(0,$inp,$idi));
        +	&add	(&LB($idx),&LB("eax"));
        +	&add	($idi,1);
        +	&mov	("ebx",&DWP(0,$out,$idx,4));
        +	&jnz	(&label("wnowrap"));
        +	  &mov	($idi,&DWP(-4,$out));
        +	&set_label("wnowrap");
        +	&mov	(&DWP(0,$out,$idx,4),"eax");
        +	&mov	(&DWP(0,$out,$ido,4),"ebx");
        +	&add	(&LB($ido),1);
        +	&jnc	(&label("w2ndloop"));
        +&jmp	(&label("exit"));
        +
        +# Unlike all other x86 [and x86_64] implementations, Intel P4 core
        +# [including EM64T] was found to perform poorly with above "32-bit" key
        +# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded
        +# assembler turned out to be 3.5x if re-coded for compressed 8-bit one,
        +# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit
        +# schedule for x86[_64], because non-P4 implementations suffer from
        +# significant performance losses then, e.g. PIII exhibits >2x
        +# deterioration, and so does Opteron. In order to assure optimal
        +# all-round performance, we detect P4 at run-time and set up compressed
        +# key schedule, which is recognized by RC4 procedure.
        +
        +&set_label("c1stloop",16);
        +	&mov	(&BP(0,$out,"eax"),&LB("eax"));	# key->data[i]=i;
        +	&add	(&LB("eax"),1);			# i++;
        +	&jnc	(&label("c1stloop"));
        +
        +	&xor	($ido,$ido);
        +	&xor	($idx,$idx);
        +	&xor	("ebx","ebx");
        +
        +&set_label("c2ndloop",16);
        +	&mov	(&LB("eax"),&BP(0,$out,$ido));
        +	&add	(&LB($idx),&BP(0,$inp,$idi));
        +	&add	(&LB($idx),&LB("eax"));
        +	&add	($idi,1);
        +	&mov	(&LB("ebx"),&BP(0,$out,$idx));
        +	&jnz	(&label("cnowrap"));
        +	  &mov	($idi,&DWP(-4,$out));
        +	&set_label("cnowrap");
        +	&mov	(&BP(0,$out,$idx),&LB("eax"));
        +	&mov	(&BP(0,$out,$ido),&LB("ebx"));
        +	&add	(&LB($ido),1);
        +	&jnc	(&label("c2ndloop"));
        +
        +	&mov	(&DWP(256,$out),-1);		# mark schedule as compressed
        +
        +&set_label("exit");
        +	&xor	("eax","eax");
        +	&mov	(&DWP(-8,$out),"eax");		# key->x=0;
        +	&mov	(&DWP(-4,$out),"eax");		# key->y=0;
        +&function_end("private_RC4_set_key");
        +
        +# const char *RC4_options(void);
        +&function_begin_B("RC4_options");
        +	&call	(&label("pic_point"));
        +&set_label("pic_point");
        +	&blindpop("eax");
        +	&lea	("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
        +	&picmeup("edx","OPENSSL_ia32cap_P");
        +	&mov	("edx",&DWP(0,"edx"));
        +	&bt	("edx",20);
        +	&jc	(&label("1xchar"));
        +	&bt	("edx",26);
        +	&jnc	(&label("ret"));
        +	&add	("eax",25);
        +	&ret	();
        +&set_label("1xchar");
        +	&add	("eax",12);
        +&set_label("ret");
        +	&ret	();
        +&set_label("opts",64);
        +&asciz	("rc4(4x,int)");
        +&asciz	("rc4(1x,char)");
        +&asciz	("rc4(8x,mmx)");
        +&asciz	("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +&align	(64);
        +&function_end_B("RC4_options");
        +
        +&asm_finish();
        +
        diff --git a/vendor/openssl/openssl/crypto/rc4/asm/rc4-ia64.pl b/vendor/openssl/openssl/crypto/rc4/asm/rc4-ia64.pl
        new file mode 100644
        index 000000000..49cd5b5e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/asm/rc4-ia64.pl
        @@ -0,0 +1,755 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by David Mosberger <David.Mosberger@acm.org> based on the
        +# Itanium optimized Crypto code which was released by HP Labs at
        +# http://www.hpl.hp.com/research/linux/crypto/.
        +#
        +# Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
        +#
        +# Permission is hereby granted, free of charge, to any person obtaining
        +# a copy of this software and associated documentation files (the
        +# "Software"), to deal in the Software without restriction, including
        +# without limitation the rights to use, copy, modify, merge, publish,
        +# distribute, sublicense, and/or sell copies of the Software, and to
        +# permit persons to whom the Software is furnished to do so, subject to
        +# the following conditions:
        +#
        +# The above copyright notice and this permission notice shall be
        +# included in all copies or substantial portions of the Software.
        +
        +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
        +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
        +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
        +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
        +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
        +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
        +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
        +
        +
        +
        +# This is a little helper program which generates a software-pipelined
        +# for RC4 encryption.  The basic algorithm looks like this:
        +#
        +#   for (counter = 0; counter < len; ++counter)
        +#     {
        +#       in = inp[counter];
        +#       SI = S[I];
        +#       J = (SI + J) & 0xff;
        +#       SJ = S[J];
        +#       T = (SI + SJ) & 0xff;
        +#       S[I] = SJ, S[J] = SI;
        +#       ST = S[T];
        +#       outp[counter] = in ^ ST;
        +#       I = (I + 1) & 0xff;
        +#     }
        +#
        +# Pipelining this loop isn't easy, because the stores to the S[] array
        +# need to be observed in the right order.  The loop generated by the
        +# code below has the following pipeline diagram:
        +#
        +#      cycle
        +#     | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |
        +# iter
        +#   1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
        +#   2:             xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
        +#   3:                         xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
        +#
        +#   where:
        +# 	LDI = load of S[I]
        +# 	LDJ = load of S[J]
        +# 	SWP = swap of S[I] and S[J]
        +# 	LDT = load of S[T]
        +#
        +# Note that in the above diagram, the major trouble-spot is that LDI
        +# of the 2nd iteration is performed BEFORE the SWP of the first
        +# iteration.  Fortunately, this is easy to detect (I of the 1st
        +# iteration will be equal to J of the 2nd iteration) and when this
        +# happens, we simply forward the proper value from the 1st iteration
        +# to the 2nd one.  The proper value in this case is simply the value
        +# of S[I] from the first iteration (thanks to the fact that SWP
        +# simply swaps the contents of S[I] and S[J]).
        +#
        +# Another potential trouble-spot is in cycle 7, where SWP of the 1st
        +# iteration issues at the same time as the LDI of the 3rd iteration.
        +# However, thanks to IA-64 execution semantics, this can be taken
        +# care of simply by placing LDI later in the instruction-group than
        +# SWP.  IA-64 CPUs will automatically forward the value if they
        +# detect that the SWP and LDI are accessing the same memory-location.
        +
        +# The core-loop that can be pipelined then looks like this (annotated
        +# with McKinley/Madison issue port & latency numbers, assuming L1
        +# cache hits for the most part):
        +
        +# operation:	    instruction:		    issue-ports:  latency
        +# ------------------  -----------------------------   ------------- -------
        +
        +# Data = *inp++       ld1 data = [inp], 1             M0-M1         1 cyc     c0
        +#                     shladd Iptr = I, KeyTable, 3    M0-M3, I0, I1 1 cyc
        +# I = (I + 1) & 0xff  padd1 nextI = I, one            M0-M3, I0, I1 3 cyc
        +#                     ;;
        +# SI = S[I]           ld8 SI = [Iptr]                 M0-M1         1 cyc     c1 * after SWAP!
        +#                     ;;
        +#                     cmp.eq.unc pBypass = I, J                                  * after J is valid!
        +# J = SI + J          add J = J, SI                   M0-M3, I0, I1 1 cyc     c2
        +#                     (pBypass) br.cond.spnt Bypass
        +#                     ;;
        +# ---------------------------------------------------------------------------------------
        +# J = J & 0xff        zxt1 J = J                      I0, I1, 1 cyc           c3
        +#                     ;;
        +#                     shladd Jptr = J, KeyTable, 3    M0-M3, I0, I1 1 cyc     c4
        +#                     ;;
        +# SJ = S[J]           ld8 SJ = [Jptr]                 M0-M1         1 cyc     c5
        +#                     ;;
        +# ---------------------------------------------------------------------------------------
        +# T = (SI + SJ)       add T = SI, SJ                  M0-M3, I0, I1 1 cyc     c6
        +#                     ;;
        +# T = T & 0xff        zxt1 T = T                      I0, I1        1 cyc
        +# S[I] = SJ           st8 [Iptr] = SJ                 M2-M3                   c7
        +# S[J] = SI           st8 [Jptr] = SI                 M2-M3
        +#                     ;;
        +#                     shladd Tptr = T, KeyTable, 3    M0-M3, I0, I1 1 cyc     c8
        +#                     ;;
        +# ---------------------------------------------------------------------------------------
        +# T = S[T]            ld8 T = [Tptr]                  M0-M1         1 cyc     c9
        +#                     ;;
        +# data ^= T           xor data = data, T              M0-M3, I0, I1 1 cyc     c10
        +#                     ;;
        +# *out++ = Data ^ T   dep word = word, data, 8, POS   I0, I1        1 cyc     c11
        +#                     ;;
        +# ---------------------------------------------------------------------------------------
        +
        +# There are several points worth making here:
        +
        +#   - Note that due to the bypass/forwarding-path, the first two
        +#     phases of the loop are strangly mingled together.  In
        +#     particular, note that the first stage of the pipeline is
        +#     using the value of "J", as calculated by the second stage.
        +#   - Each bundle-pair will have exactly 6 instructions.
        +#   - Pipelined, the loop can execute in 3 cycles/iteration and
        +#     4 stages.  However, McKinley/Madison can issue "st1" to
        +#     the same bank at a rate of at most one per 4 cycles.  Thus,
        +#     instead of storing each byte, we accumulate them in a word
        +#     and then write them back at once with a single "st8" (this
        +#     implies that the setup code needs to ensure that the output
        +#     buffer is properly aligned, if need be, by encoding the
        +#     first few bytes separately).
        +#   - There is no space for a "br.ctop" instruction.  For this
        +#     reason we can't use module-loop support in IA-64 and have
        +#     to do a traditional, purely software-pipelined loop.
        +#   - We can't replace any of the remaining "add/zxt1" pairs with
        +#     "padd1" because the latency for that instruction is too high
        +#     and would push the loop to the point where more bypasses
        +#     would be needed, which we don't have space for.
        +#   - The above loop runs at around 3.26 cycles/byte, or roughly
        +#     440 MByte/sec on a 1.5GHz Madison.  This is well below the
        +#     system bus bandwidth and hence with judicious use of
        +#     "lfetch" this loop can run at (almost) peak speed even when
        +#     the input and output data reside in memory.  The
        +#     max. latency that can be tolerated is (PREFETCH_DISTANCE *
        +#     L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at
        +#     least) 1-ahead prefetching of 128 byte cache-lines.  Note
        +#     that we do NOT prefetch into L1, since that would only
        +#     interfere with the S[] table values stored there.  This is
        +#     acceptable because there is a 10 cycle latency between
        +#     load and first use of the input data.
        +#   - We use a branch to out-of-line bypass-code of cycle-pressure:
        +#     we calculate the next J, check for the need to activate the
        +#     bypass path, and activate the bypass path ALL IN THE SAME
        +#     CYCLE.  If we didn't have these constraints, we could do
        +#     the bypass with a simple conditional move instruction.
        +#     Fortunately, the bypass paths get activated relatively
        +#     infrequently, so the extra branches don't cost all that much
        +#     (about 0.04 cycles/byte, measured on a 16396 byte file with
        +#     random input data).
        +#
        +
        +$phases = 4;		# number of stages/phases in the pipelined-loop
        +$unroll_count = 6;	# number of times we unrolled it
        +$pComI = (1 << 0);
        +$pComJ = (1 << 1);
        +$pComT = (1 << 2);
        +$pOut  = (1 << 3);
        +
        +$NData = 4;
        +$NIP = 3;
        +$NJP = 2;
        +$NI = 2;
        +$NSI = 3;
        +$NSJ = 2;
        +$NT = 2;
        +$NOutWord = 2;
        +
        +#
        +# $threshold is the minimum length before we attempt to use the
        +# big software-pipelined loop.  It MUST be greater-or-equal
        +# to:
        +#  		PHASES * (UNROLL_COUNT + 1) + 7
        +#
        +# The "+ 7" comes from the fact we may have to encode up to
        +#   7 bytes separately before the output pointer is aligned.
        +#
        +$threshold = (3 * ($phases * ($unroll_count + 1)) + 7);
        +
        +sub I {
        +    local *code = shift;
        +    local $format = shift;
        +    $code .= sprintf ("\t\t".$format."\n", @_);
        +}
        +
        +sub P {
        +    local *code = shift;
        +    local $format = shift;
        +    $code .= sprintf ($format."\n", @_);
        +}
        +
        +sub STOP {
        +    local *code = shift;
        +    $code .=<<___;
        +		;;
        +___
        +}
        +
        +sub emit_body {
        +    local *c = shift;
        +    local *bypass = shift;
        +    local ($iteration, $p) = @_;
        +
        +    local $i0 = $iteration;
        +    local $i1 = $iteration - 1;
        +    local $i2 = $iteration - 2;
        +    local $i3 = $iteration - 3;
        +    local $iw0 = ($iteration - 3) / 8;
        +    local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1;
        +    local $byte_num = ($iteration - 3) % 8;
        +    local $label = $iteration + 1;
        +    local $pAny = ($p & 0xf) == 0xf;
        +    local $pByp = (($p & $pComI) && ($iteration > 0));
        +
        +    $c.=<<___;
        +//////////////////////////////////////////////////
        +___
        +
        +    if (($p & 0xf) == 0) {
        +	$c.="#ifdef HOST_IS_BIG_ENDIAN\n";
        +	&I(\$c,"shr.u	OutWord[%u] = OutWord[%u], 32;;",
        +				$iw1 % $NOutWord, $iw1 % $NOutWord);
        +	$c.="#endif\n";
        +	&I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord);
        +	return;
        +    }
        +
        +    # Cycle 0
        +    &I(\$c, "{ .mmi")					      if ($pAny);
        +    &I(\$c, "ld1    Data[%u] = [InPtr], 1", $i0 % $NData)     if ($p & $pComI);
        +    &I(\$c, "padd1  I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI);
        +    &I(\$c, "zxt1   J = J")				      if ($p & $pComJ);
        +    &I(\$c, "}")					      if ($pAny);
        +    &I(\$c, "{ .mmi")					      if ($pAny);
        +    &I(\$c, "LKEY   T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT)   if ($p & $pOut);
        +    &I(\$c, "add    T[%u] = SI[%u], SJ[%u]",
        +       $i0 % $NT, $i2 % $NSI, $i1 % $NSJ)		      if ($p & $pComT);
        +    &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI);
        +    &I(\$c, "}")					      if ($pAny);
        +    &STOP(\$c);
        +
        +    # Cycle 1
        +    &I(\$c, "{ .mmi")					      if ($pAny);
        +    &I(\$c, "SKEY   [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT);
        +    &I(\$c, "SKEY   [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT);
        +    &I(\$c, "zxt1   T[%u] = T[%u]", $i0 % $NT, $i0 % $NT)     if ($p & $pComT);
        +    &I(\$c, "}")					      if ($pAny);
        +    &I(\$c, "{ .mmi")					      if ($pAny);
        +    &I(\$c, "LKEY   SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI);
        +    &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP)		      if ($p & $pComJ);
        +    &I(\$c, "xor    Data[%u] = Data[%u], T[%u]",
        +       $i3 % $NData, $i3 % $NData, $i1 % $NT)		      if ($p & $pOut);
        +    &I(\$c, "}")					      if ($pAny);
        +    &STOP(\$c);
        +
        +    # Cycle 2
        +    &I(\$c, "{ .mmi")					      if ($pAny);
        +    &I(\$c, "LKEY   SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ);
        +    &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI)	      if ($pByp);
        +    &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8",
        +       $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut);
        +    &I(\$c, "}")					      if ($pAny);
        +    &I(\$c, "{ .mmb")					      if ($pAny);
        +    &I(\$c, "add    J = J, SI[%u]", $i0 % $NSI)		      if ($p & $pComI);
        +    &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT)    if ($p & $pComT);
        +    &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp);
        +    &I(\$c, "}") if ($pAny);
        +    &STOP(\$c);
        +
        +    &P(\$c, ".rc4Resume%u:", $label)			      if ($pByp);
        +    if ($byte_num == 0 && $iteration >= $phases) {
        +	&I(\$c, "st8 [OutPtr] = OutWord[%u], 8",
        +	   $iw1 % $NOutWord)				      if ($p & $pOut);
        +	if ($iteration == (1 + $unroll_count) * $phases - 1) {
        +	    if ($unroll_count == 6) {
        +		&I(\$c, "mov OutWord[%u] = OutWord[%u]",
        +		   $iw1 % $NOutWord, $iw0 % $NOutWord);
        +	    }
        +	    &I(\$c, "lfetch.nt1 [InPrefetch], %u",
        +	       $unroll_count * $phases);
        +	    &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u",
        +	       $unroll_count * $phases);
        +	    &I(\$c, "br.cloop.sptk.few .rc4Loop");
        +	}
        +    }
        +
        +    if ($pByp) {
        +	&P(\$bypass, ".rc4Bypass%u:", $label);
        +	&I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI);
        +	&I(\$bypass, "nop 0");
        +	&I(\$bypass, "nop 0");
        +	&I(\$bypass, ";;");
        +	&I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI);
        +	&I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI);
        +	&I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label);
        +	&I(\$bypass, ";;");
        +    }
        +}
        +
        +$code=<<___;
        +.ident \"rc4-ia64.s, version 3.0\"
        +.ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\"
        +
        +#define LCSave		r8
        +#define PRSave		r9
        +
        +/* Inputs become invalid once rotation begins!  */
        +
        +#define StateTable	in0
        +#define DataLen		in1
        +#define InputBuffer	in2
        +#define OutputBuffer	in3
        +
        +#define KTable		r14
        +#define J		r15
        +#define InPtr		r16
        +#define OutPtr		r17
        +#define InPrefetch	r18
        +#define OutPrefetch	r19
        +#define One		r20
        +#define LoopCount	r21
        +#define Remainder	r22
        +#define IFinal		r23
        +#define EndPtr		r24
        +
        +#define tmp0		r25
        +#define tmp1		r26
        +
        +#define pBypass		p6
        +#define pDone		p7
        +#define pSmall		p8
        +#define pAligned	p9
        +#define pUnaligned	p10
        +
        +#define pComputeI	pPhase[0]
        +#define pComputeJ	pPhase[1]
        +#define pComputeT	pPhase[2]
        +#define pOutput		pPhase[3]
        +
        +#define RetVal		r8
        +#define L_OK		p7
        +#define L_NOK		p8
        +
        +#define	_NINPUTS	4
        +#define	_NOUTPUT	0
        +
        +#define	_NROTATE	24
        +#define	_NLOCALS	(_NROTATE - _NINPUTS - _NOUTPUT)
        +
        +#ifndef SZ
        +# define SZ	4	// this must be set to sizeof(RC4_INT)
        +#endif
        +
        +#if SZ == 1
        +# define LKEY			ld1
        +# define SKEY			st1
        +# define KEYADDR(dst, i)	add dst = i, KTable
        +#elif SZ == 2
        +# define LKEY			ld2
        +# define SKEY			st2
        +# define KEYADDR(dst, i)	shladd dst = i, 1, KTable
        +#elif SZ == 4
        +# define LKEY			ld4
        +# define SKEY			st4
        +# define KEYADDR(dst, i)	shladd dst = i, 2, KTable
        +#else
        +# define LKEY			ld8
        +# define SKEY			st8
        +# define KEYADDR(dst, i)	shladd dst = i, 3, KTable
        +#endif
        +
        +#if defined(_HPUX_SOURCE) && !defined(_LP64)
        +# define ADDP	addp4
        +#else
        +# define ADDP	add
        +#endif
        +
        +/* Define a macro for the bit number of the n-th byte: */
        +
        +#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
        +# define HOST_IS_BIG_ENDIAN
        +# define BYTE_POS(n)	(56 - (8 * (n)))
        +#else
        +# define BYTE_POS(n)	(8 * (n))
        +#endif
        +
        +/*
        +   We must perform the first phase of the pipeline explicitly since
        +   we will always load from the stable the first time. The br.cexit
        +   will never be taken since regardless of the number of bytes because
        +   the epilogue count is 4.
        +*/
        +/* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX
        +   assembler failed on original macro with syntax error. <appro> */
        +#define MODSCHED_RC4_PROLOGUE						   \\
        +	{								   \\
        +				ld1		Data[0] = [InPtr], 1;	   \\
        +				add		IFinal = 1, I[1];	   \\
        +				KEYADDR(IPr[0], I[1]);			   \\
        +	} ;;								   \\
        +	{								   \\
        +				LKEY		SI[0] = [IPr[0]];	   \\
        +				mov		pr.rot = 0x10000;	   \\
        +				mov		ar.ec = 4;		   \\
        +	} ;;								   \\
        +	{								   \\
        +				add		J = J, SI[0];		   \\
        +				zxt1		I[0] = IFinal;		   \\
        +				br.cexit.spnt.few .+16; /* never taken */  \\
        +	} ;;
        +#define MODSCHED_RC4_LOOP(label)					   \\
        +label:									   \\
        +	{	.mmi;							   \\
        +		(pComputeI)	ld1		Data[0] = [InPtr], 1;	   \\
        +		(pComputeI)	add		IFinal = 1, I[1];	   \\
        +		(pComputeJ)	zxt1		J = J;			   \\
        +	}{	.mmi;							   \\
        +		(pOutput)	LKEY		T[1] = [T[1]];		   \\
        +		(pComputeT)	add		T[0] = SI[2], SJ[1];	   \\
        +		(pComputeI)	KEYADDR(IPr[0], I[1]);			   \\
        +	} ;;								   \\
        +	{	.mmi;							   \\
        +		(pComputeT)	SKEY		[IPr[2]] = SJ[1];	   \\
        +		(pComputeT)	SKEY		[JP[1]] = SI[2];	   \\
        +		(pComputeT)	zxt1		T[0] = T[0];		   \\
        +	}{	.mmi;							   \\
        +		(pComputeI)	LKEY		SI[0] = [IPr[0]];	   \\
        +		(pComputeJ)	KEYADDR(JP[0], J);			   \\
        +		(pComputeI)	cmp.eq.unc	pBypass, p0 = I[1], J;	   \\
        +	} ;;								   \\
        +	{	.mmi;							   \\
        +		(pComputeJ)	LKEY		SJ[0] = [JP[0]];	   \\
        +		(pOutput)	xor		Data[3] = Data[3], T[1];   \\
        +				nop		0x0;			   \\
        +	}{	.mmi;							   \\
        +		(pComputeT)	KEYADDR(T[0], T[0]);			   \\
        +		(pBypass)	mov		SI[0] = SI[1];		   \\
        +		(pComputeI)	zxt1		I[0] = IFinal;		   \\
        +	} ;;								   \\
        +	{	.mmb;							   \\
        +		(pOutput)	st1		[OutPtr] = Data[3], 1;	   \\
        +		(pComputeI)	add		J = J, SI[0];		   \\
        +				br.ctop.sptk.few label;			   \\
        +	} ;;
        +
        +	.text
        +
        +	.align	32
        +
        +	.type	RC4, \@function
        +	.global	RC4
        +
        +	.proc	RC4
        +	.prologue
        +
        +RC4:
        +	{
        +	  	.mmi
        +		alloc	r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
        +
        +		.rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\
        +		      OutWord[2]
        +		.rotp pPhase[4]
        +
        +		ADDP		InPrefetch = 0, InputBuffer
        +		ADDP		KTable = 0, StateTable
        +	}
        +	{
        +		.mmi
        +		ADDP		InPtr = 0, InputBuffer
        +		ADDP		OutPtr = 0, OutputBuffer
        +		mov		RetVal = r0
        +	}
        +	;;
        +	{
        +		.mmi
        +		lfetch.nt1	[InPrefetch], 0x80
        +		ADDP		OutPrefetch = 0, OutputBuffer
        +	}
        +	{               // Return 0 if the input length is nonsensical
        +        	.mib
        +		ADDP		StateTable = 0, StateTable
        +        	cmp.ge.unc  	L_NOK, L_OK = r0, DataLen
        +	(L_NOK) br.ret.sptk.few rp
        +	}
        +	;;
        +	{
        +        	.mib
        +        	cmp.eq.or  	L_NOK, L_OK = r0, InPtr
        +        	cmp.eq.or  	L_NOK, L_OK = r0, OutPtr
        +		nop		0x0
        +	}
        +	{
        +		.mib
        +        	cmp.eq.or  	L_NOK, L_OK = r0, StateTable
        +		nop		0x0
        +	(L_NOK) br.ret.sptk.few rp
        +	}
        +	;;
        +		LKEY		I[1] = [KTable], SZ
        +/* Prefetch the state-table. It contains 256 elements of size SZ */
        +
        +#if SZ == 1
        +		ADDP		tmp0 = 1*128, StateTable
        +#elif SZ == 2
        +		ADDP		tmp0 = 3*128, StateTable
        +		ADDP		tmp1 = 2*128, StateTable
        +#elif SZ == 4
        +		ADDP		tmp0 = 7*128, StateTable
        +		ADDP		tmp1 = 6*128, StateTable
        +#elif SZ == 8
        +		ADDP		tmp0 = 15*128, StateTable
        +		ADDP		tmp1 = 14*128, StateTable
        +#endif
        +		;;
        +#if SZ >= 8
        +		lfetch.fault.nt1		[tmp0], -256	// 15
        +		lfetch.fault.nt1		[tmp1], -256;;
        +		lfetch.fault.nt1		[tmp0], -256	// 13
        +		lfetch.fault.nt1		[tmp1], -256;;
        +		lfetch.fault.nt1		[tmp0], -256	// 11
        +		lfetch.fault.nt1		[tmp1], -256;;
        +		lfetch.fault.nt1		[tmp0], -256	//  9
        +		lfetch.fault.nt1		[tmp1], -256;;
        +#endif
        +#if SZ >= 4
        +		lfetch.fault.nt1		[tmp0], -256	//  7
        +		lfetch.fault.nt1		[tmp1], -256;;
        +		lfetch.fault.nt1		[tmp0], -256	//  5
        +		lfetch.fault.nt1		[tmp1], -256;;
        +#endif
        +#if SZ >= 2
        +		lfetch.fault.nt1		[tmp0], -256	//  3
        +		lfetch.fault.nt1		[tmp1], -256;;
        +#endif
        +	{
        +		.mii
        +		lfetch.fault.nt1		[tmp0]		//  1
        +		add		I[1]=1,I[1];;
        +		zxt1		I[1]=I[1]
        +	}
        +	{
        +		.mmi
        +		lfetch.nt1	[InPrefetch], 0x80
        +		lfetch.excl.nt1	[OutPrefetch], 0x80
        +		.save		pr, PRSave
        +		mov		PRSave = pr
        +	} ;;
        +	{
        +		.mmi
        +		lfetch.excl.nt1	[OutPrefetch], 0x80
        +		LKEY		J = [KTable], SZ
        +		ADDP		EndPtr = DataLen, InPtr
        +	}  ;;
        +	{
        +		.mmi
        +		ADDP		EndPtr = -1, EndPtr	// Make it point to
        +							// last data byte.
        +		mov		One = 1
        +		.save		ar.lc, LCSave
        +		mov		LCSave = ar.lc
        +		.body
        +	} ;;
        +	{
        +		.mmb
        +		sub		Remainder = 0, OutPtr
        +		cmp.gtu		pSmall, p0 = $threshold, DataLen
        +(pSmall)	br.cond.dpnt	.rc4Remainder		// Data too small for
        +							// big loop.
        +	} ;;
        +	{
        +		.mmi
        +		and		Remainder = 0x7, Remainder
        +		;;
        +		cmp.eq		pAligned, pUnaligned = Remainder, r0
        +		nop		0x0
        +	} ;;
        +	{
        +		.mmb
        +.pred.rel	"mutex",pUnaligned,pAligned
        +(pUnaligned)	add		Remainder = -1, Remainder
        +(pAligned)	sub		Remainder = EndPtr, InPtr
        +(pAligned)	br.cond.dptk.many .rc4Aligned
        +	} ;;
        +	{
        +		.mmi
        +		nop		0x0
        +		nop		0x0
        +		mov.i		ar.lc = Remainder
        +	}
        +
        +/* Do the initial few bytes via the compact, modulo-scheduled loop
        +   until the output pointer is 8-byte-aligned.  */
        +
        +		MODSCHED_RC4_PROLOGUE
        +		MODSCHED_RC4_LOOP(.RC4AlignLoop)
        +
        +	{
        +		.mib
        +		sub		Remainder = EndPtr, InPtr
        +		zxt1		IFinal = IFinal
        +		clrrrb				// Clear CFM.rrb.pr so
        +		;;				// next "mov pr.rot = N"
        +						// does the right thing.
        +	}
        +	{
        +		.mmi
        +		mov		I[1] = IFinal
        +		nop		0x0
        +		nop		0x0
        +	} ;;
        +
        +
        +.rc4Aligned:
        +
        +/*
        +   Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases)
        + */
        +
        +	{
        +		.mlx
        +		add	LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder
        +		movl		Remainder = 0xaaaaaaaaaaaaaaab
        +	} ;;
        +	{
        +		.mmi
        +		setf.sig	f6 = LoopCount		// M2, M3	6 cyc
        +		setf.sig	f7 = Remainder		// M2, M3	6 cyc
        +		nop		0x0
        +	} ;;
        +	{
        +		.mfb
        +		nop		0x0
        +		xmpy.hu		f6 = f6, f7
        +		nop		0x0
        +	} ;;
        +	{
        +		.mmi
        +		getf.sig	LoopCount = f6;;	// M2		5 cyc
        +		nop		0x0
        +		shr.u		LoopCount = LoopCount, 4
        +	} ;;
        +	{
        +		.mmi
        +		nop		0x0
        +		nop		0x0
        +		mov.i		ar.lc = LoopCount
        +	} ;;
        +
        +/* Now comes the unrolled loop: */
        +
        +.rc4Prologue:
        +___
        +
        +$iteration = 0;
        +
        +# Generate the prologue:
        +$predicates = 1;
        +for ($i = 0; $i < $phases; ++$i) {
        +    &emit_body (\$code, \$bypass, $iteration++, $predicates);
        +    $predicates = ($predicates << 1) | 1;
        +}
        +
        +$code.=<<___;
        +.rc4Loop:
        +___
        +
        +# Generate the body:
        +for ($i = 0; $i < $unroll_count*$phases; ++$i) {
        +    &emit_body (\$code, \$bypass, $iteration++, $predicates);
        +}
        +
        +$code.=<<___;
        +.rc4Epilogue:
        +___
        +
        +# Generate the epilogue:
        +for ($i = 0; $i < $phases; ++$i) {
        +    $predicates <<= 1;
        +    &emit_body (\$code, \$bypass, $iteration++, $predicates);
        +}
        +
        +$code.=<<___;
        +	{
        +		.mmi
        +		lfetch.nt1	[EndPtr]	// fetch line with last byte
        +		mov		IFinal = I[1]
        +		nop		0x0
        +	}
        +
        +.rc4Remainder:
        +	{
        +		.mmi
        +		sub		Remainder = EndPtr, InPtr	// Calculate
        +								// # of bytes
        +								// left - 1
        +		nop		0x0
        +		nop		0x0
        +	} ;;
        +	{
        +		.mib
        +		cmp.eq		pDone, p0 = -1, Remainder // done already?
        +		mov.i		ar.lc = Remainder
        +(pDone)		br.cond.dptk.few .rc4Complete
        +	}
        +
        +/* Do the remaining bytes via the compact, modulo-scheduled loop */
        +
        +		MODSCHED_RC4_PROLOGUE
        +		MODSCHED_RC4_LOOP(.RC4RestLoop)
        +
        +.rc4Complete:
        +	{
        +		.mmi
        +		add		KTable = -SZ, KTable
        +		add		IFinal = -1, IFinal
        +		mov		ar.lc = LCSave
        +	} ;;
        +	{
        +		.mii
        +		SKEY		[KTable] = J,-SZ
        +		zxt1		IFinal = IFinal
        +		mov		pr = PRSave, 0x1FFFF
        +	} ;;
        +	{
        +		.mib
        +		SKEY		[KTable] = IFinal
        +		add		RetVal = 1, r0
        +		br.ret.sptk.few	rp
        +	} ;;
        +___
        +
        +# Last but not least, emit the code for the bypass-code of the unrolled loop:
        +
        +$code.=$bypass;
        +
        +$code.=<<___;
        +	.endp RC4
        +___
        +
        +print $code;
        diff --git a/vendor/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl b/vendor/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
        new file mode 100644
        index 000000000..272fa91e1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
        @@ -0,0 +1,632 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# June 2011
        +#
        +# This is RC4+MD5 "stitch" implementation. The idea, as spelled in
        +# http://download.intel.com/design/intarch/papers/323686.pdf, is that
        +# since both algorithms exhibit instruction-level parallelism, ILP,
        +# below theoretical maximum, interleaving them would allow to utilize
        +# processor resources better and achieve better performance. RC4
        +# instruction sequence is virtually identical to rc4-x86_64.pl, which
        +# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin
        +# and Jim Guilford of Intel. MD5 is fresh implementation aiming to
        +# minimize register usage, which was used as "main thread" with RC4
        +# weaved into it, one RC4 round per one MD5 round. In addition to the
        +# stiched subroutine the script can generate standalone replacement
        +# md5_block_asm_data_order and RC4. Below are performance numbers in
        +# cycles per processed byte, less is better, for these the standalone
        +# subroutines, sum of them, and stitched one:
        +#
        +#		RC4	MD5	RC4+MD5	stitch	gain
        +# Opteron	6.5(*)	5.4	11.9	7.0	+70%(*)
        +# Core2		6.5	5.8	12.3	7.7	+60%
        +# Westmere	4.3	5.2	9.5	7.0	+36%
        +# Sandy Bridge	4.2	5.5	9.7	6.8	+43%
        +# Atom		9.3	6.5	15.8	11.1	+42%
        +#
        +# (*)	rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement
        +#	is +53%...
        +
        +my ($rc4,$md5)=(1,1);	# what to generate?
        +my $D="#" if (!$md5);	# if set to "#", MD5 is stitched into RC4(),
        +			# but its result is discarded. Idea here is
        +			# to be able to use 'openssl speed rc4' for
        +			# benchmarking the stitched subroutine... 
        +
        +my $flavour = shift;
        +my $output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
        +
        +if ($rc4 && !$md5) {
        +  ($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx");
        +  $func="RC4";				$nargs=4;
        +} elsif ($md5 && !$rc4) {
        +  ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx");
        +  $func="md5_block_asm_data_order";	$nargs=3;
        +} else {
        +  ($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
        +  $func="rc4_md5_enc";			$nargs=6;
        +  # void rc4_md5_enc(
        +  #		RC4_KEY *key,		#
        +  #		const void *in0,	# RC4 input
        +  #		void *out,		# RC4 output
        +  #		MD5_CTX *ctx,		#
        +  #		const void *inp,	# MD5 input
        +  #		size_t len);		# number of 64-byte blocks
        +}
        +
        +my @K=(	0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
        +	0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
        +	0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
        +	0x6b901122,0xfd987193,0xa679438e,0x49b40821,
        +
        +	0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
        +	0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
        +	0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
        +	0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
        +
        +	0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
        +	0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
        +	0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
        +	0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
        +
        +	0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
        +	0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
        +	0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
        +	0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391	);
        +
        +my @V=("%r8d","%r9d","%r10d","%r11d");	# MD5 registers
        +my $tmp="%r12d";
        +
        +my @XX=("%rbp","%rsi");			# RC4 registers
        +my @TX=("%rax","%rbx");
        +my $YY="%rcx";
        +my $TY="%rdx";
        +
        +my $MOD=32;				# 16, 32 or 64
        +
        +$code.=<<___;
        +.text
        +.align 16
        +
        +.globl	$func
        +.type	$func,\@function,$nargs
        +$func:
        +	cmp	\$0,$len
        +	je	.Labort
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	sub	\$40,%rsp
        +.Lbody:
        +___
        +if ($rc4) {
        +$code.=<<___;
        +$D#md5#	mov	$ctx,%r11		# reassign arguments
        +	mov	$len,%r12
        +	mov	$in0,%r13
        +	mov	$out,%r14
        +$D#md5#	mov	$inp,%r15
        +___
        +    $ctx="%r11"	if ($md5);		# reassign arguments
        +    $len="%r12";
        +    $in0="%r13";
        +    $out="%r14";
        +    $inp="%r15"	if ($md5);
        +    $inp=$in0	if (!$md5);
        +$code.=<<___;
        +	xor	$XX[0],$XX[0]
        +	xor	$YY,$YY
        +
        +	lea	8($dat),$dat
        +	mov	-8($dat),$XX[0]#b
        +	mov	-4($dat),$YY#b
        +
        +	inc	$XX[0]#b
        +	sub	$in0,$out
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +___
        +$code.=<<___ if (!$md5);
        +	xor	$TX[1],$TX[1]
        +	test	\$-128,$len
        +	jz	.Loop1
        +	sub	$XX[0],$TX[1]
        +	and	\$`$MOD-1`,$TX[1]
        +	jz	.Loop${MOD}_is_hot
        +	sub	$TX[1],$len
        +.Loop${MOD}_warmup:
        +	add	$TX[0]#b,$YY#b
        +	movl	($dat,$YY,4),$TY#d
        +	movl	$TX[0]#d,($dat,$YY,4)
        +	movl	$TY#d,($dat,$XX[0],4)
        +	add	$TY#b,$TX[0]#b
        +	inc	$XX[0]#b
        +	movl	($dat,$TX[0],4),$TY#d
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +	xorb	($in0),$TY#b
        +	movb	$TY#b,($out,$in0)
        +	lea	1($in0),$in0
        +	dec	$TX[1]
        +	jnz	.Loop${MOD}_warmup
        +
        +	mov	$YY,$TX[1]
        +	xor	$YY,$YY
        +	mov	$TX[1]#b,$YY#b
        +
        +.Loop${MOD}_is_hot:
        +	mov	$len,32(%rsp)		# save original $len
        +	shr	\$6,$len		# number of 64-byte blocks
        +___
        +  if ($D && !$md5) {			# stitch in dummy MD5
        +    $md5=1;
        +    $ctx="%r11";
        +    $inp="%r15";
        +    $code.=<<___;
        +	mov	%rsp,$ctx
        +	mov	$in0,$inp
        +___
        +  }
        +}
        +$code.=<<___;
        +#rc4#	add	$TX[0]#b,$YY#b
        +#rc4#	lea	($dat,$XX[0],4),$XX[1]
        +	shl	\$6,$len
        +	add	$inp,$len		# pointer to the end of input
        +	mov	$len,16(%rsp)
        +
        +#md5#	mov	$ctx,24(%rsp)		# save pointer to MD5_CTX
        +#md5#	mov	0*4($ctx),$V[0]		# load current hash value from MD5_CTX
        +#md5#	mov	1*4($ctx),$V[1]
        +#md5#	mov	2*4($ctx),$V[2]
        +#md5#	mov	3*4($ctx),$V[3]
        +	jmp	.Loop
        +
        +.align	16
        +.Loop:
        +#md5#	mov	$V[0],0*4(%rsp)		# put aside current hash value
        +#md5#	mov	$V[1],1*4(%rsp)
        +#md5#	mov	$V[2],2*4(%rsp)
        +#md5#	mov	$V[3],$tmp		# forward reference
        +#md5#	mov	$V[3],3*4(%rsp)
        +___
        +
        +sub R0 {
        +  my ($i,$a,$b,$c,$d)=@_;
        +  my @rot0=(7,12,17,22);
        +  my $j=$i%16;
        +  my $k=$i%$MOD;
        +  my $xmm="%xmm".($j&1);
        +    $code.="	movdqu	($in0),%xmm2\n"		if ($rc4 && $j==15);
        +    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
        +    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
        +    $code.=<<___;
        +#rc4#	movl	($dat,$YY,4),$TY#d
        +#md5#	xor	$c,$tmp
        +#rc4#	movl	$TX[0]#d,($dat,$YY,4)
        +#md5#	and	$b,$tmp
        +#md5#	add	4*`$j`($inp),$a
        +#rc4#	add	$TY#b,$TX[0]#b
        +#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
        +#md5#	add	\$$K[$i],$a
        +#md5#	xor	$d,$tmp
        +#rc4#	movz	$TX[0]#b,$TX[0]#d
        +#rc4#	movl	$TY#d,4*$k($XX[1])
        +#md5#	add	$tmp,$a
        +#rc4#	add	$TX[1]#b,$YY#b
        +#md5#	rol	\$$rot0[$j%4],$a
        +#md5#	mov	`$j==15?"$b":"$c"`,$tmp		# forward reference
        +#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
        +#md5#	add	$b,$a
        +___
        +    $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
        +	mov	$YY,$XX[1]
        +	xor	$YY,$YY				# keyword to partial register
        +	mov	$XX[1]#b,$YY#b
        +	lea	($dat,$XX[0],4),$XX[1]
        +___
        +    $code.=<<___ if ($rc4 && $j==15);
        +	psllq	\$8,%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm1,%xmm2
        +___
        +}
        +sub R1 {
        +  my ($i,$a,$b,$c,$d)=@_;
        +  my @rot1=(5,9,14,20);
        +  my $j=$i%16;
        +  my $k=$i%$MOD;
        +  my $xmm="%xmm".($j&1);
        +    $code.="	movdqu	16($in0),%xmm3\n"	if ($rc4 && $j==15);
        +    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
        +    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
        +    $code.=<<___;
        +#rc4#	movl	($dat,$YY,4),$TY#d
        +#md5#	xor	$b,$tmp
        +#rc4#	movl	$TX[0]#d,($dat,$YY,4)
        +#md5#	and	$d,$tmp
        +#md5#	add	4*`((1+5*$j)%16)`($inp),$a
        +#rc4#	add	$TY#b,$TX[0]#b
        +#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
        +#md5#	add	\$$K[$i],$a
        +#md5#	xor	$c,$tmp
        +#rc4#	movz	$TX[0]#b,$TX[0]#d
        +#rc4#	movl	$TY#d,4*$k($XX[1])
        +#md5#	add	$tmp,$a
        +#rc4#	add	$TX[1]#b,$YY#b
        +#md5#	rol	\$$rot1[$j%4],$a
        +#md5#	mov	`$j==15?"$c":"$b"`,$tmp		# forward reference
        +#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
        +#md5#	add	$b,$a
        +___
        +    $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
        +	mov	$YY,$XX[1]
        +	xor	$YY,$YY				# keyword to partial register
        +	mov	$XX[1]#b,$YY#b
        +	lea	($dat,$XX[0],4),$XX[1]
        +___
        +    $code.=<<___ if ($rc4 && $j==15);
        +	psllq	\$8,%xmm1
        +	pxor	%xmm0,%xmm3
        +	pxor	%xmm1,%xmm3
        +___
        +}
        +sub R2 {
        +  my ($i,$a,$b,$c,$d)=@_;
        +  my @rot2=(4,11,16,23);
        +  my $j=$i%16;
        +  my $k=$i%$MOD;
        +  my $xmm="%xmm".($j&1);
        +    $code.="	movdqu	32($in0),%xmm4\n"	if ($rc4 && $j==15);
        +    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
        +    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
        +    $code.=<<___;
        +#rc4#	movl	($dat,$YY,4),$TY#d
        +#md5#	xor	$c,$tmp
        +#rc4#	movl	$TX[0]#d,($dat,$YY,4)
        +#md5#	xor	$b,$tmp
        +#md5#	add	4*`((5+3*$j)%16)`($inp),$a
        +#rc4#	add	$TY#b,$TX[0]#b
        +#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
        +#md5#	add	\$$K[$i],$a
        +#rc4#	movz	$TX[0]#b,$TX[0]#d
        +#md5#	add	$tmp,$a
        +#rc4#	movl	$TY#d,4*$k($XX[1])
        +#rc4#	add	$TX[1]#b,$YY#b
        +#md5#	rol	\$$rot2[$j%4],$a
        +#md5#	mov	`$j==15?"\\\$-1":"$c"`,$tmp	# forward reference
        +#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
        +#md5#	add	$b,$a
        +___
        +    $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
        +	mov	$YY,$XX[1]
        +	xor	$YY,$YY				# keyword to partial register
        +	mov	$XX[1]#b,$YY#b
        +	lea	($dat,$XX[0],4),$XX[1]
        +___
        +    $code.=<<___ if ($rc4 && $j==15);
        +	psllq	\$8,%xmm1
        +	pxor	%xmm0,%xmm4
        +	pxor	%xmm1,%xmm4
        +___
        +}
        +sub R3 {
        +  my ($i,$a,$b,$c,$d)=@_;
        +  my @rot3=(6,10,15,21);
        +  my $j=$i%16;
        +  my $k=$i%$MOD;
        +  my $xmm="%xmm".($j&1);
        +    $code.="	movdqu	48($in0),%xmm5\n"	if ($rc4 && $j==15);
        +    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
        +    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
        +    $code.=<<___;
        +#rc4#	movl	($dat,$YY,4),$TY#d
        +#md5#	xor	$d,$tmp
        +#rc4#	movl	$TX[0]#d,($dat,$YY,4)
        +#md5#	or	$b,$tmp
        +#md5#	add	4*`((7*$j)%16)`($inp),$a
        +#rc4#	add	$TY#b,$TX[0]#b
        +#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
        +#md5#	add	\$$K[$i],$a
        +#rc4#	movz	$TX[0]#b,$TX[0]#d
        +#md5#	xor	$c,$tmp
        +#rc4#	movl	$TY#d,4*$k($XX[1])
        +#md5#	add	$tmp,$a
        +#rc4#	add	$TX[1]#b,$YY#b
        +#md5#	rol	\$$rot3[$j%4],$a
        +#md5#	mov	\$-1,$tmp			# forward reference
        +#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
        +#md5#	add	$b,$a
        +___
        +    $code.=<<___ if ($rc4 && $j==15);
        +	mov	$XX[0],$XX[1]
        +	xor	$XX[0],$XX[0]			# keyword to partial register
        +	mov	$XX[1]#b,$XX[0]#b
        +	mov	$YY,$XX[1]
        +	xor	$YY,$YY				# keyword to partial register
        +	mov	$XX[1]#b,$YY#b
        +	lea	($dat,$XX[0],4),$XX[1]
        +	psllq	\$8,%xmm1
        +	pxor	%xmm0,%xmm5
        +	pxor	%xmm1,%xmm5
        +___
        +}
        +
        +my $i=0;
        +for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
        +for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
        +for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
        +for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
        +
        +$code.=<<___;
        +#md5#	add	0*4(%rsp),$V[0]		# accumulate hash value
        +#md5#	add	1*4(%rsp),$V[1]
        +#md5#	add	2*4(%rsp),$V[2]
        +#md5#	add	3*4(%rsp),$V[3]
        +
        +#rc4#	movdqu	%xmm2,($out,$in0)	# write RC4 output
        +#rc4#	movdqu	%xmm3,16($out,$in0)
        +#rc4#	movdqu	%xmm4,32($out,$in0)
        +#rc4#	movdqu	%xmm5,48($out,$in0)
        +#md5#	lea	64($inp),$inp
        +#rc4#	lea	64($in0),$in0
        +	cmp	16(%rsp),$inp		# are we done?
        +	jb	.Loop
        +
        +#md5#	mov	24(%rsp),$len		# restore pointer to MD5_CTX
        +#rc4#	sub	$TX[0]#b,$YY#b		# correct $YY
        +#md5#	mov	$V[0],0*4($len)		# write MD5_CTX
        +#md5#	mov	$V[1],1*4($len)
        +#md5#	mov	$V[2],2*4($len)
        +#md5#	mov	$V[3],3*4($len)
        +___
        +$code.=<<___ if ($rc4 && (!$md5 || $D));
        +	mov	32(%rsp),$len		# restore original $len
        +	and	\$63,$len		# remaining bytes
        +	jnz	.Loop1
        +	jmp	.Ldone
        +	
        +.align	16
        +.Loop1:
        +	add	$TX[0]#b,$YY#b
        +	movl	($dat,$YY,4),$TY#d
        +	movl	$TX[0]#d,($dat,$YY,4)
        +	movl	$TY#d,($dat,$XX[0],4)
        +	add	$TY#b,$TX[0]#b
        +	inc	$XX[0]#b
        +	movl	($dat,$TX[0],4),$TY#d
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +	xorb	($in0),$TY#b
        +	movb	$TY#b,($out,$in0)
        +	lea	1($in0),$in0
        +	dec	$len
        +	jnz	.Loop1
        +
        +.Ldone:
        +___
        +$code.=<<___;
        +#rc4#	sub	\$1,$XX[0]#b
        +#rc4#	movl	$XX[0]#d,-8($dat)
        +#rc4#	movl	$YY#d,-4($dat)
        +
        +	mov	40(%rsp),%r15
        +	mov	48(%rsp),%r14
        +	mov	56(%rsp),%r13
        +	mov	64(%rsp),%r12
        +	mov	72(%rsp),%rbp
        +	mov	80(%rsp),%rbx
        +	lea	88(%rsp),%rsp
        +.Lepilogue:
        +.Labort:
        +	ret
        +.size $func,.-$func
        +___
        +
        +if ($rc4 && $D) {	# sole purpose of this section is to provide
        +			# option to use the generated module as drop-in
        +			# replacement for rc4-x86_64.pl for debugging
        +			# and testing purposes...
        +my ($idx,$ido)=("%r8","%r9");
        +my ($dat,$len,$inp)=("%rdi","%rsi","%rdx");
        +
        +$code.=<<___;
        +.globl	RC4_set_key
        +.type	RC4_set_key,\@function,3
        +.align	16
        +RC4_set_key:
        +	lea	8($dat),$dat
        +	lea	($inp,$len),$inp
        +	neg	$len
        +	mov	$len,%rcx
        +	xor	%eax,%eax
        +	xor	$ido,$ido
        +	xor	%r10,%r10
        +	xor	%r11,%r11
        +	jmp	.Lw1stloop
        +
        +.align	16
        +.Lw1stloop:
        +	mov	%eax,($dat,%rax,4)
        +	add	\$1,%al
        +	jnc	.Lw1stloop
        +
        +	xor	$ido,$ido
        +	xor	$idx,$idx
        +.align	16
        +.Lw2ndloop:
        +	mov	($dat,$ido,4),%r10d
        +	add	($inp,$len,1),$idx#b
        +	add	%r10b,$idx#b
        +	add	\$1,$len
        +	mov	($dat,$idx,4),%r11d
        +	cmovz	%rcx,$len
        +	mov	%r10d,($dat,$idx,4)
        +	mov	%r11d,($dat,$ido,4)
        +	add	\$1,$ido#b
        +	jnc	.Lw2ndloop
        +
        +	xor	%eax,%eax
        +	mov	%eax,-8($dat)
        +	mov	%eax,-4($dat)
        +	ret
        +.size	RC4_set_key,.-RC4_set_key
        +
        +.globl	RC4_options
        +.type	RC4_options,\@abi-omnipotent
        +.align	16
        +RC4_options:
        +	lea	.Lopts(%rip),%rax
        +	ret
        +.align	64
        +.Lopts:
        +.asciz	"rc4(64x,int)"
        +.align	64
        +.size	RC4_options,.-RC4_options
        +___
        +}
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +my $rec="%rcx";
        +my $frame="%rdx";
        +my $context="%r8";
        +my $disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lbody(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lbody
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
        +	jae	.Lin_prologue
        +
        +	mov	40(%rax),%r15
        +	mov	48(%rax),%r14
        +	mov	56(%rax),%r13
        +	mov	64(%rax),%r12
        +	mov	72(%rax),%rbp
        +	mov	80(%rax),%rbx
        +	lea	88(%rax),%rax
        +
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R12
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_$func
        +	.rva	.LSEH_end_$func
        +	.rva	.LSEH_info_$func
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_$func:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +___
        +}
        +
        +sub reg_part {
        +my ($reg,$conv)=@_;
        +    if ($reg =~ /%r[0-9]+/)     { $reg .= $conv; }
        +    elsif ($conv eq "b")        { $reg =~ s/%[er]([^x]+)x?/%$1l/;       }
        +    elsif ($conv eq "w")        { $reg =~ s/%[er](.+)/%$1/;             }
        +    elsif ($conv eq "d")        { $reg =~ s/%[er](.+)/%e$1/;            }
        +    return $reg;
        +}
        +
        +$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/pinsrw\s+\$0,/movd	/gm;
        +
        +$code =~ s/#md5#//gm	if ($md5);
        +$code =~ s/#rc4#//gm	if ($rc4);
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl b/vendor/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl
        new file mode 100644
        index 000000000..916506708
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/asm/rc4-parisc.pl
        @@ -0,0 +1,313 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# RC4 for PA-RISC.
        +
        +# June 2009.
        +#
        +# Performance is 33% better than gcc 3.2 generated code on PA-7100LC.
        +# For reference, [4x] unrolled loop is >40% faster than folded one.
        +# It's possible to unroll loop 8 times on PA-RISC 2.0, but improvement
        +# is believed to be not sufficient to justify the effort...
        +#
        +# Special thanks to polarhome.com for providing HP-UX account.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +
        +$flavour = shift;
        +$output = shift;
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$FRAME_MARKER	=80;
        +	$SAVED_RP	=16;
        +	$PUSH		="std";
        +	$PUSHMA		="std,ma";
        +	$POP		="ldd";
        +	$POPMB		="ldd,mb";
        +} else {
        +	$LEVEL		="1.0";
        +	$SIZE_T		=4;
        +	$FRAME_MARKER	=48;
        +	$SAVED_RP	=20;
        +	$PUSH		="stw";
        +	$PUSHMA		="stwm";
        +	$POP		="ldw";
        +	$POPMB		="ldwm";
        +}
        +
        +$FRAME=4*$SIZE_T+$FRAME_MARKER;	# 4 saved regs + frame marker
        +				#                [+ argument transfer]
        +$SZ=1;				# defaults to RC4_CHAR
        +if (open CONF,"<${dir}../../opensslconf.h") {
        +    while(<CONF>) {
        +	if (m/#\s*define\s+RC4_INT\s+(.*)/) {
        +	    $SZ = ($1=~/char$/) ? 1 : 4;
        +	    last;
        +	}
        +    }
        +    close CONF;
        +}
        +
        +if ($SZ==1) {	# RC4_CHAR
        +    $LD="ldb";
        +    $LDX="ldbx";
        +    $MKX="addl";
        +    $ST="stb";
        +} else {	# RC4_INT (~5% faster than RC4_CHAR on PA-7100LC)
        +    $LD="ldw";
        +    $LDX="ldwx,s";
        +    $MKX="sh2addl";
        +    $ST="stw";
        +}
        +
        +$key="%r26";
        +$len="%r25";
        +$inp="%r24";
        +$out="%r23";
        +
        +@XX=("%r19","%r20");
        +@TX=("%r21","%r22");
        +$YY="%r28";
        +$TY="%r29";
        +
        +$acc="%r1";
        +$ix="%r2";
        +$iy="%r3";
        +$dat0="%r4";
        +$dat1="%r5";
        +$rem="%r6";
        +$mask="%r31";
        +
        +sub unrolledloopbody {
        +for ($i=0;$i<4;$i++) {
        +$code.=<<___;
        +	ldo	1($XX[0]),$XX[1]
        +	`sprintf("$LDX	%$TY(%$key),%$dat1") if ($i>0)`	
        +	and	$mask,$XX[1],$XX[1]
        +	$LDX	$YY($key),$TY
        +	$MKX	$YY,$key,$ix
        +	$LDX	$XX[1]($key),$TX[1]
        +	$MKX	$XX[0],$key,$iy
        +	$ST	$TX[0],0($ix)
        +	comclr,<> $XX[1],$YY,%r0	; conditional
        +	copy	$TX[0],$TX[1]		; move
        +	`sprintf("%sdep	%$dat1,%d,8,%$acc",$i==1?"z":"",8*($i-1)+7) if ($i>0)`
        +	$ST	$TY,0($iy)
        +	addl	$TX[0],$TY,$TY
        +	addl	$TX[1],$YY,$YY
        +	and	$mask,$TY,$TY
        +	and	$mask,$YY,$YY
        +___
        +push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
        +} }
        +
        +sub foldedloop {
        +my ($label,$count)=@_;
        +$code.=<<___;
        +$label
        +	$MKX	$YY,$key,$iy
        +	$LDX	$YY($key),$TY
        +	$MKX	$XX[0],$key,$ix
        +	$ST	$TX[0],0($iy)
        +	ldo	1($XX[0]),$XX[0]
        +	$ST	$TY,0($ix)
        +	addl	$TX[0],$TY,$TY
        +	ldbx	$inp($out),$dat1
        +	and	$mask,$TY,$TY
        +	and	$mask,$XX[0],$XX[0]
        +	$LDX	$TY($key),$acc
        +	$LDX	$XX[0]($key),$TX[0]
        +	ldo	1($out),$out
        +	xor	$dat1,$acc,$acc
        +	addl	$TX[0],$YY,$YY
        +	stb	$acc,-1($out)
        +	addib,<> -1,$count,$label	; $count is always small
        +	and	$mask,$YY,$YY
        +___
        +}
        +
        +$code=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.EXPORT	RC4,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
        +RC4
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-4*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=6
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +
        +	cmpib,*= 0,$len,L\$abort
        +	sub	$inp,$out,$inp		; distance between $inp and $out
        +
        +	$LD	`0*$SZ`($key),$XX[0]
        +	$LD	`1*$SZ`($key),$YY
        +	ldo	`2*$SZ`($key),$key
        +
        +	ldi	0xff,$mask
        +	ldi	3,$dat0		
        +
        +	ldo	1($XX[0]),$XX[0]	; warm up loop
        +	and	$mask,$XX[0],$XX[0]
        +	$LDX	$XX[0]($key),$TX[0]
        +	addl	$TX[0],$YY,$YY
        +	cmpib,*>>= 6,$len,L\$oop1	; is $len large enough to bother?
        +	and	$mask,$YY,$YY
        +
        +	and,<>	$out,$dat0,$rem		; is $out aligned?
        +	b	L\$alignedout
        +	subi	4,$rem,$rem
        +	sub	$len,$rem,$len
        +___
        +&foldedloop("L\$alignout",$rem);	# process till $out is aligned
        +
        +$code.=<<___;
        +L\$alignedout				; $len is at least 4 here
        +	and,<>	$inp,$dat0,$acc		; is $inp aligned?
        +	b	L\$oop4
        +	sub	$inp,$acc,$rem		; align $inp
        +
        +	sh3addl	$acc,%r0,$acc
        +	subi	32,$acc,$acc
        +	mtctl	$acc,%cr11		; load %sar with vshd align factor
        +	ldwx	$rem($out),$dat0
        +	ldo	4($rem),$rem
        +L\$oop4misalignedinp
        +___
        +&unrolledloopbody();
        +$code.=<<___;
        +	$LDX	$TY($key),$ix
        +	ldwx	$rem($out),$dat1
        +	ldo	-4($len),$len
        +	or	$ix,$acc,$acc		; last piece, no need to dep
        +	vshd	$dat0,$dat1,$iy		; align data
        +	copy	$dat1,$dat0
        +	xor	$iy,$acc,$acc
        +	stw	$acc,0($out)
        +	cmpib,*<< 3,$len,L\$oop4misalignedinp
        +	ldo	4($out),$out
        +	cmpib,*= 0,$len,L\$done
        +	nop
        +	b	L\$oop1
        +	nop
        +
        +	.ALIGN	8
        +L\$oop4
        +___
        +&unrolledloopbody();
        +$code.=<<___;
        +	$LDX	$TY($key),$ix
        +	ldwx	$inp($out),$dat0
        +	ldo	-4($len),$len
        +	or	$ix,$acc,$acc		; last piece, no need to dep
        +	xor	$dat0,$acc,$acc
        +	stw	$acc,0($out)
        +	cmpib,*<< 3,$len,L\$oop4
        +	ldo	4($out),$out
        +	cmpib,*= 0,$len,L\$done
        +	nop
        +___
        +&foldedloop("L\$oop1",$len);
        +$code.=<<___;
        +L\$done
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2
        +	ldo	-1($XX[0]),$XX[0]	; chill out loop
        +	sub	$YY,$TX[0],$YY
        +	and	$mask,$XX[0],$XX[0]
        +	and	$mask,$YY,$YY
        +	$ST	$XX[0],`-2*$SZ`($key)
        +	$ST	$YY,`-1*$SZ`($key)
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +L\$abort
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +___
        +
        +$code.=<<___;
        +
        +	.EXPORT	private_RC4_set_key,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
        +	.ALIGN	8
        +private_RC4_set_key
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	$ST	%r0,`0*$SZ`($key)
        +	$ST	%r0,`1*$SZ`($key)
        +	ldo	`2*$SZ`($key),$key
        +	copy	%r0,@XX[0]
        +L\$1st
        +	$ST	@XX[0],0($key)
        +	ldo	1(@XX[0]),@XX[0]
        +	bb,>=	@XX[0],`31-8`,L\$1st	; @XX[0]<256
        +	ldo	$SZ($key),$key
        +
        +	ldo	`-256*$SZ`($key),$key	; rewind $key
        +	addl	$len,$inp,$inp		; $inp to point at the end
        +	sub	%r0,$len,%r23		; inverse index
        +	copy	%r0,@XX[0]
        +	copy	%r0,@XX[1]
        +	ldi	0xff,$mask
        +
        +L\$2nd
        +	$LDX	@XX[0]($key),@TX[0]
        +	ldbx	%r23($inp),@TX[1]
        +	addi,nuv 1,%r23,%r23		; increment and conditional
        +	sub	%r0,$len,%r23		; inverse index
        +	addl	@TX[0],@XX[1],@XX[1]
        +	addl	@TX[1],@XX[1],@XX[1]
        +	and	$mask,@XX[1],@XX[1]
        +	$MKX	@XX[0],$key,$TY
        +	$LDX	@XX[1]($key),@TX[1]
        +	$MKX	@XX[1],$key,$YY
        +	ldo	1(@XX[0]),@XX[0]
        +	$ST	@TX[0],0($YY)
        +	bb,>=	@XX[0],`31-8`,L\$2nd	; @XX[0]<256
        +	$ST	@TX[1],0($TY)
        +
        +	bv,n	(%r2)
        +	.EXIT
        +	nop
        +	.PROCEND
        +
        +	.EXPORT	RC4_options,ENTRY
        +	.ALIGN	8
        +RC4_options
        +	.PROC
        +	.CALLINFO	NO_CALLS
        +	.ENTRY
        +	blr	%r0,%r28
        +	ldi	3,%r1
        +L\$pic
        +	andcm	%r28,%r1,%r28
        +	bv	(%r2)
        +	.EXIT
        +	ldo	L\$opts-L\$pic(%r28),%r28
        +	.PROCEND
        +	.ALIGN	8
        +L\$opts
        +	.STRINGZ "rc4(4x,`$SZ==1?"char":"int"`)"
        +	.STRINGZ "RC4 for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4);
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl b/vendor/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl
        new file mode 100644
        index 000000000..7528ece13
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/asm/rc4-s390x.pl
        @@ -0,0 +1,234 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# February 2009
        +#
        +# Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to
        +# "cluster" Address Generation Interlocks, so that one pipeline stall
        +# resolves several dependencies.
        +
        +# November 2010.
        +#
        +# Adapt for -m31 build. If kernel supports what's called "highgprs"
        +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
        +# instructions and achieve "64-bit" performance even in 31-bit legacy
        +# application context. The feature is not specific to any particular
        +# processor, as long as it's "z-CPU". Latter implies that the code
        +# remains z/Architecture specific. On z990 it was measured to perform
        +# 50% better than code generated by gcc 4.3.
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +	$SIZE_T=4;
        +	$g="";
        +} else {
        +	$SIZE_T=8;
        +	$g="g";
        +}
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$rp="%r14";
        +$sp="%r15";
        +$code=<<___;
        +.text
        +
        +___
        +
        +# void RC4(RC4_KEY *key,size_t len,const void *inp,void *out)
        +{
        +$acc="%r0";
        +$cnt="%r1";
        +$key="%r2";
        +$len="%r3";
        +$inp="%r4";
        +$out="%r5";
        +
        +@XX=("%r6","%r7");
        +@TX=("%r8","%r9");
        +$YY="%r10";
        +$TY="%r11";
        +
        +$code.=<<___;
        +.globl	RC4
        +.type	RC4,\@function
        +.align	64
        +RC4:
        +	stm${g}	%r6,%r11,6*$SIZE_T($sp)
        +___
        +$code.=<<___ if ($flavour =~ /3[12]/);
        +	llgfr	$len,$len
        +___
        +$code.=<<___;
        +	llgc	$XX[0],0($key)
        +	llgc	$YY,1($key)
        +	la	$XX[0],1($XX[0])
        +	nill	$XX[0],0xff
        +	srlg	$cnt,$len,3
        +	ltgr	$cnt,$cnt
        +	llgc	$TX[0],2($XX[0],$key)
        +	jz	.Lshort
        +	j	.Loop8
        +
        +.align	64
        +.Loop8:
        +___
        +for ($i=0;$i<8;$i++) {
        +$code.=<<___;
        +	la	$YY,0($YY,$TX[0])	# $i
        +	nill	$YY,255
        +	la	$XX[1],1($XX[0])
        +	nill	$XX[1],255
        +___
        +$code.=<<___ if ($i==1);
        +	llgc	$acc,2($TY,$key)
        +___
        +$code.=<<___ if ($i>1);
        +	sllg	$acc,$acc,8
        +	ic	$acc,2($TY,$key)
        +___
        +$code.=<<___;
        +	llgc	$TY,2($YY,$key)
        +	stc	$TX[0],2($YY,$key)
        +	llgc	$TX[1],2($XX[1],$key)
        +	stc	$TY,2($XX[0],$key)
        +	cr	$XX[1],$YY
        +	jne	.Lcmov$i
        +	la	$TX[1],0($TX[0])
        +.Lcmov$i:
        +	la	$TY,0($TY,$TX[0])
        +	nill	$TY,255
        +___
        +push(@TX,shift(@TX)); push(@XX,shift(@XX));     # "rotate" registers
        +}
        +
        +$code.=<<___;
        +	lg	$TX[1],0($inp)
        +	sllg	$acc,$acc,8
        +	la	$inp,8($inp)
        +	ic	$acc,2($TY,$key)
        +	xgr	$acc,$TX[1]
        +	stg	$acc,0($out)
        +	la	$out,8($out)
        +	brctg	$cnt,.Loop8
        +
        +.Lshort:
        +	lghi	$acc,7
        +	ngr	$len,$acc
        +	jz	.Lexit
        +	j	.Loop1
        +
        +.align	16
        +.Loop1:
        +	la	$YY,0($YY,$TX[0])
        +	nill	$YY,255
        +	llgc	$TY,2($YY,$key)
        +	stc	$TX[0],2($YY,$key)
        +	stc	$TY,2($XX[0],$key)
        +	ar	$TY,$TX[0]
        +	ahi	$XX[0],1
        +	nill	$TY,255
        +	nill	$XX[0],255
        +	llgc	$acc,0($inp)
        +	la	$inp,1($inp)
        +	llgc	$TY,2($TY,$key)
        +	llgc	$TX[0],2($XX[0],$key)
        +	xr	$acc,$TY
        +	stc	$acc,0($out)
        +	la	$out,1($out)
        +	brct	$len,.Loop1
        +
        +.Lexit:
        +	ahi	$XX[0],-1
        +	stc	$XX[0],0($key)
        +	stc	$YY,1($key)
        +	lm${g}	%r6,%r11,6*$SIZE_T($sp)
        +	br	$rp
        +.size	RC4,.-RC4
        +.string	"RC4 for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +
        +___
        +}
        +
        +# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
        +{
        +$cnt="%r0";
        +$idx="%r1";
        +$key="%r2";
        +$len="%r3";
        +$inp="%r4";
        +$acc="%r5";
        +$dat="%r6";
        +$ikey="%r7";
        +$iinp="%r8";
        +
        +$code.=<<___;
        +.globl	private_RC4_set_key
        +.type	private_RC4_set_key,\@function
        +.align	64
        +private_RC4_set_key:
        +	stm${g}	%r6,%r8,6*$SIZE_T($sp)
        +	lhi	$cnt,256
        +	la	$idx,0(%r0)
        +	sth	$idx,0($key)
        +.align	4
        +.L1stloop:
        +	stc	$idx,2($idx,$key)
        +	la	$idx,1($idx)
        +	brct	$cnt,.L1stloop
        +
        +	lghi	$ikey,-256
        +	lr	$cnt,$len
        +	la	$iinp,0(%r0)
        +	la	$idx,0(%r0)
        +.align	16
        +.L2ndloop:
        +	llgc	$acc,2+256($ikey,$key)
        +	llgc	$dat,0($iinp,$inp)
        +	la	$idx,0($idx,$acc)
        +	la	$ikey,1($ikey)
        +	la	$idx,0($idx,$dat)
        +	nill	$idx,255
        +	la	$iinp,1($iinp)
        +	tml	$ikey,255
        +	llgc	$dat,2($idx,$key)
        +	stc	$dat,2+256-1($ikey,$key)
        +	stc	$acc,2($idx,$key)
        +	jz	.Ldone
        +	brct	$cnt,.L2ndloop
        +	lr	$cnt,$len
        +	la	$iinp,0(%r0)
        +	j	.L2ndloop
        +.Ldone:
        +	lm${g}	%r6,%r8,6*$SIZE_T($sp)
        +	br	$rp
        +.size	private_RC4_set_key,.-private_RC4_set_key
        +
        +___
        +}
        +
        +# const char *RC4_options()
        +$code.=<<___;
        +.globl	RC4_options
        +.type	RC4_options,\@function
        +.align	16
        +RC4_options:
        +	larl	%r2,.Loptions
        +	br	%r14
        +.size	RC4_options,.-RC4_options
        +.section	.rodata
        +.Loptions:
        +.align	8
        +.string	"rc4(8x,char)"
        +___
        +
        +print $code;
        +close STDOUT;	# force flush
        diff --git a/vendor/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl b/vendor/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl
        new file mode 100644
        index 000000000..75750dbf3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/asm/rc4-x86_64.pl
        @@ -0,0 +1,677 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# July 2004
        +#
        +# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in
        +# "hand-coded assembler"] doesn't stand for the whole improvement
        +# coefficient. It turned out that eliminating RC4_CHAR from config
        +# line results in ~40% improvement (yes, even for C implementation).
        +# Presumably it has everything to do with AMD cache architecture and
        +# RAW or whatever penalties. Once again! The module *requires* config
        +# line *without* RC4_CHAR! As for coding "secret," I bet on partial
        +# register arithmetics. For example instead of 'inc %r8; and $255,%r8'
        +# I simply 'inc %r8b'. Even though optimization manual discourages
        +# to operate on partial registers, it turned out to be the best bet.
        +# At least for AMD... How IA32E would perform remains to be seen...
        +
        +# November 2004
        +#
        +# As was shown by Marc Bevand reordering of couple of load operations
        +# results in even higher performance gain of 3.3x:-) At least on
        +# Opteron... For reference, 1x in this case is RC4_CHAR C-code
        +# compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock.
        +# Latter means that if you want to *estimate* what to expect from
        +# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz.
        +
        +# November 2004
        +#
        +# Intel P4 EM64T core was found to run the AMD64 code really slow...
        +# The only way to achieve comparable performance on P4 was to keep
        +# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to
        +# compose blended code, which would perform even within 30% marginal
        +# on either AMD and Intel platforms, I implement both cases. See
        +# rc4_skey.c for further details...
        +
        +# April 2005
        +#
        +# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing 
        +# those with add/sub results in 50% performance improvement of folded
        +# loop...
        +
        +# May 2005
        +#
        +# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T
        +# performance by >30% [unlike P4 32-bit case that is]. But this is
        +# provided that loads are reordered even more aggressively! Both code
        +# pathes, AMD64 and EM64T, reorder loads in essentially same manner
        +# as my IA-64 implementation. On Opteron this resulted in modest 5%
        +# improvement [I had to test it], while final Intel P4 performance
        +# achieves respectful 432MBps on 2.8GHz processor now. For reference.
        +# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than
        +# RC4_INT code-path. While if executed on Opteron, it's only 25%
        +# slower than the RC4_INT one [meaning that if CPU µ-arch detection
        +# is not implemented, then this final RC4_CHAR code-path should be
        +# preferred, as it provides better *all-round* performance].
        +
        +# March 2007
        +#
        +# Intel Core2 was observed to perform poorly on both code paths:-( It
        +# apparently suffers from some kind of partial register stall, which
        +# occurs in 64-bit mode only [as virtually identical 32-bit loop was
        +# observed to outperform 64-bit one by almost 50%]. Adding two movzb to
        +# cloop1 boosts its performance by 80%! This loop appears to be optimal
        +# fit for Core2 and therefore the code was modified to skip cloop8 on
        +# this CPU.
        +
        +# May 2010
        +#
        +# Intel Westmere was observed to perform suboptimally. Adding yet
        +# another movzb to cloop1 improved performance by almost 50%! Core2
        +# performance is improved too, but nominally...
        +
        +# May 2011
        +#
        +# The only code path that was not modified is P4-specific one. Non-P4
        +# Intel code path optimization is heavily based on submission by Maxim
        +# Perminov, Maxim Locktyukhin and Jim Guilford of Intel. I've used
        +# some of the ideas even in attempt to optmize the original RC4_INT
        +# code path... Current performance in cycles per processed byte (less
        +# is better) and improvement coefficients relative to previous
        +# version of this module are:
        +#
        +# Opteron	5.3/+0%(*)
        +# P4		6.5
        +# Core2		6.2/+15%(**)
        +# Westmere	4.2/+60%
        +# Sandy Bridge	4.2/+120%
        +# Atom		9.3/+80%
        +#
        +# (*)	But corresponding loop has less instructions, which should have
        +#	positive effect on upcoming Bulldozer, which has one less ALU.
        +#	For reference, Intel code runs at 6.8 cpb rate on Opteron.
        +# (**)	Note that Core2 result is ~15% lower than corresponding result
        +#	for 32-bit code, meaning that it's possible to improve it,
        +#	but more than likely at the cost of the others (see rc4-586.pl
        +#	to get the idea)...
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +$dat="%rdi";	    # arg1
        +$len="%rsi";	    # arg2
        +$inp="%rdx";	    # arg3
        +$out="%rcx";	    # arg4
        +
        +{
        +$code=<<___;
        +.text
        +.extern	OPENSSL_ia32cap_P
        +
        +.globl	RC4
        +.type	RC4,\@function,4
        +.align	16
        +RC4:	or	$len,$len
        +	jne	.Lentry
        +	ret
        +.Lentry:
        +	push	%rbx
        +	push	%r12
        +	push	%r13
        +.Lprologue:
        +	mov	$len,%r11
        +	mov	$inp,%r12
        +	mov	$out,%r13
        +___
        +my $len="%r11";		# reassign input arguments
        +my $inp="%r12";
        +my $out="%r13";
        +
        +my @XX=("%r10","%rsi");
        +my @TX=("%rax","%rbx");
        +my $YY="%rcx";
        +my $TY="%rdx";
        +
        +$code.=<<___;
        +	xor	$XX[0],$XX[0]
        +	xor	$YY,$YY
        +
        +	lea	8($dat),$dat
        +	mov	-8($dat),$XX[0]#b
        +	mov	-4($dat),$YY#b
        +	cmpl	\$-1,256($dat)
        +	je	.LRC4_CHAR
        +	mov	OPENSSL_ia32cap_P(%rip),%r8d
        +	xor	$TX[1],$TX[1]
        +	inc	$XX[0]#b
        +	sub	$XX[0],$TX[1]
        +	sub	$inp,$out
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +	test	\$-16,$len
        +	jz	.Lloop1
        +	bt	\$30,%r8d	# Intel CPU?
        +	jc	.Lintel
        +	and	\$7,$TX[1]
        +	lea	1($XX[0]),$XX[1]
        +	jz	.Loop8
        +	sub	$TX[1],$len
        +.Loop8_warmup:
        +	add	$TX[0]#b,$YY#b
        +	movl	($dat,$YY,4),$TY#d
        +	movl	$TX[0]#d,($dat,$YY,4)
        +	movl	$TY#d,($dat,$XX[0],4)
        +	add	$TY#b,$TX[0]#b
        +	inc	$XX[0]#b
        +	movl	($dat,$TX[0],4),$TY#d
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +	xorb	($inp),$TY#b
        +	movb	$TY#b,($out,$inp)
        +	lea	1($inp),$inp
        +	dec	$TX[1]
        +	jnz	.Loop8_warmup
        +
        +	lea	1($XX[0]),$XX[1]
        +	jmp	.Loop8
        +.align	16
        +.Loop8:
        +___
        +for ($i=0;$i<8;$i++) {
        +$code.=<<___ if ($i==7);
        +	add	\$8,$XX[1]#b
        +___
        +$code.=<<___;
        +	add	$TX[0]#b,$YY#b
        +	movl	($dat,$YY,4),$TY#d
        +	movl	$TX[0]#d,($dat,$YY,4)
        +	movl	`4*($i==7?-1:$i)`($dat,$XX[1],4),$TX[1]#d
        +	ror	\$8,%r8				# ror is redundant when $i=0
        +	movl	$TY#d,4*$i($dat,$XX[0],4)
        +	add	$TX[0]#b,$TY#b
        +	movb	($dat,$TY,4),%r8b
        +___
        +push(@TX,shift(@TX)); #push(@XX,shift(@XX));	# "rotate" registers
        +}
        +$code.=<<___;
        +	add	\$8,$XX[0]#b
        +	ror	\$8,%r8
        +	sub	\$8,$len
        +
        +	xor	($inp),%r8
        +	mov	%r8,($out,$inp)
        +	lea	8($inp),$inp
        +
        +	test	\$-8,$len
        +	jnz	.Loop8
        +	cmp	\$0,$len
        +	jne	.Lloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.Lintel:
        +	test	\$-32,$len
        +	jz	.Lloop1
        +	and	\$15,$TX[1]
        +	jz	.Loop16_is_hot
        +	sub	$TX[1],$len
        +.Loop16_warmup:
        +	add	$TX[0]#b,$YY#b
        +	movl	($dat,$YY,4),$TY#d
        +	movl	$TX[0]#d,($dat,$YY,4)
        +	movl	$TY#d,($dat,$XX[0],4)
        +	add	$TY#b,$TX[0]#b
        +	inc	$XX[0]#b
        +	movl	($dat,$TX[0],4),$TY#d
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +	xorb	($inp),$TY#b
        +	movb	$TY#b,($out,$inp)
        +	lea	1($inp),$inp
        +	dec	$TX[1]
        +	jnz	.Loop16_warmup
        +
        +	mov	$YY,$TX[1]
        +	xor	$YY,$YY
        +	mov	$TX[1]#b,$YY#b
        +
        +.Loop16_is_hot:
        +	lea	($dat,$XX[0],4),$XX[1]
        +___
        +sub RC4_loop {
        +  my $i=shift;
        +  my $j=$i<0?0:$i;
        +  my $xmm="%xmm".($j&1);
        +
        +    $code.="	add	\$16,$XX[0]#b\n"		if ($i==15);
        +    $code.="	movdqu	($inp),%xmm2\n"			if ($i==15);
        +    $code.="	add	$TX[0]#b,$YY#b\n"		if ($i<=0);
        +    $code.="	movl	($dat,$YY,4),$TY#d\n";
        +    $code.="	pxor	%xmm0,%xmm2\n"			if ($i==0);
        +    $code.="	psllq	\$8,%xmm1\n"			if ($i==0);
        +    $code.="	pxor	$xmm,$xmm\n"			if ($i<=1);
        +    $code.="	movl	$TX[0]#d,($dat,$YY,4)\n";
        +    $code.="	add	$TY#b,$TX[0]#b\n";
        +    $code.="	movl	`4*($j+1)`($XX[1]),$TX[1]#d\n"	if ($i<15);
        +    $code.="	movz	$TX[0]#b,$TX[0]#d\n";
        +    $code.="	movl	$TY#d,4*$j($XX[1])\n";
        +    $code.="	pxor	%xmm1,%xmm2\n"			if ($i==0);
        +    $code.="	lea	($dat,$XX[0],4),$XX[1]\n"	if ($i==15);
        +    $code.="	add	$TX[1]#b,$YY#b\n"		if ($i<15);
        +    $code.="	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n";
        +    $code.="	movdqu	%xmm2,($out,$inp)\n"		if ($i==0);
        +    $code.="	lea	16($inp),$inp\n"		if ($i==0);
        +    $code.="	movl	($XX[1]),$TX[1]#d\n"		if ($i==15);
        +}
        +	RC4_loop(-1);
        +$code.=<<___;
        +	jmp	.Loop16_enter
        +.align	16
        +.Loop16:
        +___
        +
        +for ($i=0;$i<16;$i++) {
        +    $code.=".Loop16_enter:\n"		if ($i==1);
        +	RC4_loop($i);
        +	push(@TX,shift(@TX)); 		# "rotate" registers
        +}
        +$code.=<<___;
        +	mov	$YY,$TX[1]
        +	xor	$YY,$YY			# keyword to partial register
        +	sub	\$16,$len
        +	mov	$TX[1]#b,$YY#b
        +	test	\$-16,$len
        +	jnz	.Loop16
        +
        +	psllq	\$8,%xmm1
        +	pxor	%xmm0,%xmm2
        +	pxor	%xmm1,%xmm2
        +	movdqu	%xmm2,($out,$inp)
        +	lea	16($inp),$inp
        +
        +	cmp	\$0,$len
        +	jne	.Lloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.Lloop1:
        +	add	$TX[0]#b,$YY#b
        +	movl	($dat,$YY,4),$TY#d
        +	movl	$TX[0]#d,($dat,$YY,4)
        +	movl	$TY#d,($dat,$XX[0],4)
        +	add	$TY#b,$TX[0]#b
        +	inc	$XX[0]#b
        +	movl	($dat,$TX[0],4),$TY#d
        +	movl	($dat,$XX[0],4),$TX[0]#d
        +	xorb	($inp),$TY#b
        +	movb	$TY#b,($out,$inp)
        +	lea	1($inp),$inp
        +	dec	$len
        +	jnz	.Lloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.LRC4_CHAR:
        +	add	\$1,$XX[0]#b
        +	movzb	($dat,$XX[0]),$TX[0]#d
        +	test	\$-8,$len
        +	jz	.Lcloop1
        +	jmp	.Lcloop8
        +.align	16
        +.Lcloop8:
        +	mov	($inp),%r8d
        +	mov	4($inp),%r9d
        +___
        +# unroll 2x4-wise, because 64-bit rotates kill Intel P4...
        +for ($i=0;$i<4;$i++) {
        +$code.=<<___;
        +	add	$TX[0]#b,$YY#b
        +	lea	1($XX[0]),$XX[1]
        +	movzb	($dat,$YY),$TY#d
        +	movzb	$XX[1]#b,$XX[1]#d
        +	movzb	($dat,$XX[1]),$TX[1]#d
        +	movb	$TX[0]#b,($dat,$YY)
        +	cmp	$XX[1],$YY
        +	movb	$TY#b,($dat,$XX[0])
        +	jne	.Lcmov$i			# Intel cmov is sloooow...
        +	mov	$TX[0],$TX[1]
        +.Lcmov$i:
        +	add	$TX[0]#b,$TY#b
        +	xor	($dat,$TY),%r8b
        +	ror	\$8,%r8d
        +___
        +push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
        +}
        +for ($i=4;$i<8;$i++) {
        +$code.=<<___;
        +	add	$TX[0]#b,$YY#b
        +	lea	1($XX[0]),$XX[1]
        +	movzb	($dat,$YY),$TY#d
        +	movzb	$XX[1]#b,$XX[1]#d
        +	movzb	($dat,$XX[1]),$TX[1]#d
        +	movb	$TX[0]#b,($dat,$YY)
        +	cmp	$XX[1],$YY
        +	movb	$TY#b,($dat,$XX[0])
        +	jne	.Lcmov$i			# Intel cmov is sloooow...
        +	mov	$TX[0],$TX[1]
        +.Lcmov$i:
        +	add	$TX[0]#b,$TY#b
        +	xor	($dat,$TY),%r9b
        +	ror	\$8,%r9d
        +___
        +push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
        +}
        +$code.=<<___;
        +	lea	-8($len),$len
        +	mov	%r8d,($out)
        +	lea	8($inp),$inp
        +	mov	%r9d,4($out)
        +	lea	8($out),$out
        +
        +	test	\$-8,$len
        +	jnz	.Lcloop8
        +	cmp	\$0,$len
        +	jne	.Lcloop1
        +	jmp	.Lexit
        +___
        +$code.=<<___;
        +.align	16
        +.Lcloop1:
        +	add	$TX[0]#b,$YY#b
        +	movzb	$YY#b,$YY#d
        +	movzb	($dat,$YY),$TY#d
        +	movb	$TX[0]#b,($dat,$YY)
        +	movb	$TY#b,($dat,$XX[0])
        +	add	$TX[0]#b,$TY#b
        +	add	\$1,$XX[0]#b
        +	movzb	$TY#b,$TY#d
        +	movzb	$XX[0]#b,$XX[0]#d
        +	movzb	($dat,$TY),$TY#d
        +	movzb	($dat,$XX[0]),$TX[0]#d
        +	xorb	($inp),$TY#b
        +	lea	1($inp),$inp
        +	movb	$TY#b,($out)
        +	lea	1($out),$out
        +	sub	\$1,$len
        +	jnz	.Lcloop1
        +	jmp	.Lexit
        +
        +.align	16
        +.Lexit:
        +	sub	\$1,$XX[0]#b
        +	movl	$XX[0]#d,-8($dat)
        +	movl	$YY#d,-4($dat)
        +
        +	mov	(%rsp),%r13
        +	mov	8(%rsp),%r12
        +	mov	16(%rsp),%rbx
        +	add	\$24,%rsp
        +.Lepilogue:
        +	ret
        +.size	RC4,.-RC4
        +___
        +}
        +
        +$idx="%r8";
        +$ido="%r9";
        +
        +$code.=<<___;
        +.globl	private_RC4_set_key
        +.type	private_RC4_set_key,\@function,3
        +.align	16
        +private_RC4_set_key:
        +	lea	8($dat),$dat
        +	lea	($inp,$len),$inp
        +	neg	$len
        +	mov	$len,%rcx
        +	xor	%eax,%eax
        +	xor	$ido,$ido
        +	xor	%r10,%r10
        +	xor	%r11,%r11
        +
        +	mov	OPENSSL_ia32cap_P(%rip),$idx#d
        +	bt	\$20,$idx#d	# RC4_CHAR?
        +	jc	.Lc1stloop
        +	jmp	.Lw1stloop
        +
        +.align	16
        +.Lw1stloop:
        +	mov	%eax,($dat,%rax,4)
        +	add	\$1,%al
        +	jnc	.Lw1stloop
        +
        +	xor	$ido,$ido
        +	xor	$idx,$idx
        +.align	16
        +.Lw2ndloop:
        +	mov	($dat,$ido,4),%r10d
        +	add	($inp,$len,1),$idx#b
        +	add	%r10b,$idx#b
        +	add	\$1,$len
        +	mov	($dat,$idx,4),%r11d
        +	cmovz	%rcx,$len
        +	mov	%r10d,($dat,$idx,4)
        +	mov	%r11d,($dat,$ido,4)
        +	add	\$1,$ido#b
        +	jnc	.Lw2ndloop
        +	jmp	.Lexit_key
        +
        +.align	16
        +.Lc1stloop:
        +	mov	%al,($dat,%rax)
        +	add	\$1,%al
        +	jnc	.Lc1stloop
        +
        +	xor	$ido,$ido
        +	xor	$idx,$idx
        +.align	16
        +.Lc2ndloop:
        +	mov	($dat,$ido),%r10b
        +	add	($inp,$len),$idx#b
        +	add	%r10b,$idx#b
        +	add	\$1,$len
        +	mov	($dat,$idx),%r11b
        +	jnz	.Lcnowrap
        +	mov	%rcx,$len
        +.Lcnowrap:
        +	mov	%r10b,($dat,$idx)
        +	mov	%r11b,($dat,$ido)
        +	add	\$1,$ido#b
        +	jnc	.Lc2ndloop
        +	movl	\$-1,256($dat)
        +
        +.align	16
        +.Lexit_key:
        +	xor	%eax,%eax
        +	mov	%eax,-8($dat)
        +	mov	%eax,-4($dat)
        +	ret
        +.size	private_RC4_set_key,.-private_RC4_set_key
        +
        +.globl	RC4_options
        +.type	RC4_options,\@abi-omnipotent
        +.align	16
        +RC4_options:
        +	lea	.Lopts(%rip),%rax
        +	mov	OPENSSL_ia32cap_P(%rip),%edx
        +	bt	\$20,%edx
        +	jc	.L8xchar
        +	bt	\$30,%edx
        +	jnc	.Ldone
        +	add	\$25,%rax
        +	ret
        +.L8xchar:
        +	add	\$12,%rax
        +.Ldone:
        +	ret
        +.align	64
        +.Lopts:
        +.asciz	"rc4(8x,int)"
        +.asciz	"rc4(8x,char)"
        +.asciz	"rc4(16x,int)"
        +.asciz	"RC4 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	64
        +.size	RC4_options,.-RC4_options
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	stream_se_handler,\@abi-omnipotent
        +.align	16
        +stream_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lprologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lin_prologue
        +
        +	lea	24(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%r12
        +	mov	-24(%rax),%r13
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	jmp	.Lcommon_seh_exit
        +.size	stream_se_handler,.-stream_se_handler
        +
        +.type	key_se_handler,\@abi-omnipotent
        +.align	16
        +key_se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +.Lcommon_seh_exit:
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	key_se_handler,.-key_se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_RC4
        +	.rva	.LSEH_end_RC4
        +	.rva	.LSEH_info_RC4
        +
        +	.rva	.LSEH_begin_private_RC4_set_key
        +	.rva	.LSEH_end_private_RC4_set_key
        +	.rva	.LSEH_info_private_RC4_set_key
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_RC4:
        +	.byte	9,0,0,0
        +	.rva	stream_se_handler
        +.LSEH_info_private_RC4_set_key:
        +	.byte	9,0,0,0
        +	.rva	key_se_handler
        +___
        +}
        +
        +sub reg_part {
        +my ($reg,$conv)=@_;
        +    if ($reg =~ /%r[0-9]+/)	{ $reg .= $conv; }
        +    elsif ($conv eq "b")	{ $reg =~ s/%[er]([^x]+)x?/%$1l/;	}
        +    elsif ($conv eq "w")	{ $reg =~ s/%[er](.+)/%$1/;		}
        +    elsif ($conv eq "d")	{ $reg =~ s/%[er](.+)/%e$1/;		}
        +    return $reg;
        +}
        +
        +$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +
        +print $code;
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4.c b/vendor/openssl/openssl/crypto/rc4/rc4.c
        new file mode 100644
        index 000000000..c900b2605
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4.c
        @@ -0,0 +1,193 @@
        +/* crypto/rc4/rc4.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/rc4.h>
        +#include <openssl/evp.h>
        +
        +char *usage[]={
        +"usage: rc4 args\n",
        +"\n",
        +" -in arg         - input file - default stdin\n",
        +" -out arg        - output file - default stdout\n",
        +" -key key        - password\n",
        +NULL
        +};
        +
        +int main(int argc, char *argv[])
        +	{
        +	FILE *in=NULL,*out=NULL;
        +	char *infile=NULL,*outfile=NULL,*keystr=NULL;
        +	RC4_KEY key;
        +	char buf[BUFSIZ];
        +	int badops=0,i;
        +	char **pp;
        +	unsigned char md[MD5_DIGEST_LENGTH];
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if 	(strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			infile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outfile= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			keystr= *(++argv);
        +			}
        +		else
        +			{
        +			fprintf(stderr,"unknown option %s\n",*argv);
        +			badops=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (badops)
        +		{
        +bad:
        +		for (pp=usage; (*pp != NULL); pp++)
        +			fprintf(stderr,"%s",*pp);
        +		exit(1);
        +		}
        +
        +	if (infile == NULL)
        +		in=stdin;
        +	else
        +		{
        +		in=fopen(infile,"r");
        +		if (in == NULL)
        +			{
        +			perror("open");
        +			exit(1);
        +			}
        +
        +		}
        +	if (outfile == NULL)
        +		out=stdout;
        +	else
        +		{
        +		out=fopen(outfile,"w");
        +		if (out == NULL)
        +			{
        +			perror("open");
        +			exit(1);
        +			}
        +		}
        +		
        +#ifdef OPENSSL_SYS_MSDOS
        +	/* This should set the file to binary mode. */
        +	{
        +#include <fcntl.h>
        +	setmode(fileno(in),O_BINARY);
        +	setmode(fileno(out),O_BINARY);
        +	}
        +#endif
        +
        +	if (keystr == NULL)
        +		{ /* get key */
        +		i=EVP_read_pw_string(buf,BUFSIZ,"Enter RC4 password:",0);
        +		if (i != 0)
        +			{
        +			OPENSSL_cleanse(buf,BUFSIZ);
        +			fprintf(stderr,"bad password read\n");
        +			exit(1);
        +			}
        +		keystr=buf;
        +		}
        +
        +	EVP_Digest((unsigned char *)keystr,strlen(keystr),md,NULL,EVP_md5(),NULL);
        +	OPENSSL_cleanse(keystr,strlen(keystr));
        +	RC4_set_key(&key,MD5_DIGEST_LENGTH,md);
        +	
        +	for(;;)
        +		{
        +		i=fread(buf,1,BUFSIZ,in);
        +		if (i == 0) break;
        +		if (i < 0)
        +			{
        +			perror("read");
        +			exit(1);
        +			}
        +		RC4(&key,(unsigned int)i,(unsigned char *)buf,
        +			(unsigned char *)buf);
        +		i=fwrite(buf,(unsigned int)i,1,out);
        +		if (i != 1)
        +			{
        +			perror("write");
        +			exit(1);
        +			}
        +		}
        +	fclose(out);
        +	fclose(in);
        +	exit(0);
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4.h b/vendor/openssl/openssl/crypto/rc4/rc4.h
        new file mode 100644
        index 000000000..88ceb46bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4.h
        @@ -0,0 +1,90 @@
        +/* crypto/rc4/rc4.h */
        +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_RC4_H
        +#define HEADER_RC4_H
        +
        +#include <openssl/opensslconf.h> /* OPENSSL_NO_RC4, RC4_INT */
        +#ifdef OPENSSL_NO_RC4
        +#error RC4 is disabled.
        +#endif
        +
        +#include <stddef.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct rc4_key_st
        +	{
        +	RC4_INT x,y;
        +	RC4_INT data[256];
        +	} RC4_KEY;
        +
        + 
        +const char *RC4_options(void);
        +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
        +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
        +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
        +		unsigned char *outdata);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4_enc.c b/vendor/openssl/openssl/crypto/rc4/rc4_enc.c
        new file mode 100644
        index 000000000..8c4fc6c7a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4_enc.c
        @@ -0,0 +1,315 @@
        +/* crypto/rc4/rc4_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <openssl/rc4.h>
        +#include "rc4_locl.h"
        +
        +/* RC4 as implemented from a posting from
        + * Newsgroups: sci.crypt
        + * From: sterndark@netcom.com (David Sterndark)
        + * Subject: RC4 Algorithm revealed.
        + * Message-ID: <sternCvKL4B.Hyy@netcom.com>
        + * Date: Wed, 14 Sep 1994 06:35:31 GMT
        + */
        +
        +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
        +	     unsigned char *outdata)
        +	{
        +        register RC4_INT *d;
        +        register RC4_INT x,y,tx,ty;
        +	size_t i;
        +        
        +        x=key->x;     
        +        y=key->y;     
        +        d=key->data; 
        +
        +#if defined(RC4_CHUNK)
        +	/*
        +	 * The original reason for implementing this(*) was the fact that
        +	 * pre-21164a Alpha CPUs don't have byte load/store instructions
        +	 * and e.g. a byte store has to be done with 64-bit load, shift,
        +	 * and, or and finally 64-bit store. Peaking data and operating
        +	 * at natural word size made it possible to reduce amount of
        +	 * instructions as well as to perform early read-ahead without
        +	 * suffering from RAW (read-after-write) hazard. This resulted
        +	 * in ~40%(**) performance improvement on 21064 box with gcc.
        +	 * But it's not only Alpha users who win here:-) Thanks to the
        +	 * early-n-wide read-ahead this implementation also exhibits
        +	 * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
        +	 * on sizeof(RC4_INT)).
        +	 *
        +	 * (*)	"this" means code which recognizes the case when input
        +	 *	and output pointers appear to be aligned at natural CPU
        +	 *	word boundary
        +	 * (**)	i.e. according to 'apps/openssl speed rc4' benchmark,
        +	 *	crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
        +	 *
        +	 * Cavets.
        +	 *
        +	 * - RC4_CHUNK="unsigned long long" should be a #1 choice for
        +	 *   UltraSPARC. Unfortunately gcc generates very slow code
        +	 *   (2.5-3 times slower than one generated by Sun's WorkShop
        +	 *   C) and therefore gcc (at least 2.95 and earlier) should
        +	 *   always be told that RC4_CHUNK="unsigned long".
        +	 *
        +	 *					<appro@fy.chalmers.se>
        +	 */
        +
        +# define RC4_STEP	( \
        +			x=(x+1) &0xff,	\
        +			tx=d[x],	\
        +			y=(tx+y)&0xff,	\
        +			ty=d[y],	\
        +			d[y]=tx,	\
        +			d[x]=ty,	\
        +			(RC4_CHUNK)d[(tx+ty)&0xff]\
        +			)
        +
        +	if ( ( ((size_t)indata  & (sizeof(RC4_CHUNK)-1)) | 
        +	       ((size_t)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
        +		{
        +		RC4_CHUNK ichunk,otp;
        +		const union { long one; char little; } is_endian = {1};
        +
        +		/*
        +		 * I reckon we can afford to implement both endian
        +		 * cases and to decide which way to take at run-time
        +		 * because the machine code appears to be very compact
        +		 * and redundant 1-2KB is perfectly tolerable (i.e.
        +		 * in case the compiler fails to eliminate it:-). By
        +		 * suggestion from Terrel Larson <terr@terralogic.net>
        +		 * who also stands for the is_endian union:-)
        +		 *
        +		 * Special notes.
        +		 *
        +		 * - is_endian is declared automatic as doing otherwise
        +		 *   (declaring static) prevents gcc from eliminating
        +		 *   the redundant code;
        +		 * - compilers (those I've tried) don't seem to have
        +		 *   problems eliminating either the operators guarded
        +		 *   by "if (sizeof(RC4_CHUNK)==8)" or the condition
        +		 *   expressions themselves so I've got 'em to replace
        +		 *   corresponding #ifdefs from the previous version;
        +		 * - I chose to let the redundant switch cases when
        +		 *   sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
        +		 *   before);
        +		 * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
        +		 *   [LB]ESHFT guards against "shift is out of range"
        +		 *   warnings when sizeof(RC4_CHUNK)!=8 
        +		 *
        +		 *			<appro@fy.chalmers.se>
        +		 */
        +		if (!is_endian.little)
        +			{	/* BIG-ENDIAN CASE */
        +# define BESHFT(c)	(((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
        +			for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
        +				{
        +				ichunk  = *(RC4_CHUNK *)indata;
        +				otp  = RC4_STEP<<BESHFT(0);
        +				otp |= RC4_STEP<<BESHFT(1);
        +				otp |= RC4_STEP<<BESHFT(2);
        +				otp |= RC4_STEP<<BESHFT(3);
        +				if (sizeof(RC4_CHUNK)==8)
        +					{
        +					otp |= RC4_STEP<<BESHFT(4);
        +					otp |= RC4_STEP<<BESHFT(5);
        +					otp |= RC4_STEP<<BESHFT(6);
        +					otp |= RC4_STEP<<BESHFT(7);
        +					}
        +				*(RC4_CHUNK *)outdata = otp^ichunk;
        +				indata  += sizeof(RC4_CHUNK);
        +				outdata += sizeof(RC4_CHUNK);
        +				}
        +			if (len)
        +				{
        +				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
        +
        +				ichunk = *(RC4_CHUNK *)indata;
        +				ochunk = *(RC4_CHUNK *)outdata;
        +				otp = 0;
        +				i = BESHFT(0);
        +				mask <<= (sizeof(RC4_CHUNK)-len)<<3;
        +				switch (len&(sizeof(RC4_CHUNK)-1))
        +					{
        +					case 7:	otp  = RC4_STEP<<i, i-=8;
        +					case 6:	otp |= RC4_STEP<<i, i-=8;
        +					case 5:	otp |= RC4_STEP<<i, i-=8;
        +					case 4:	otp |= RC4_STEP<<i, i-=8;
        +					case 3:	otp |= RC4_STEP<<i, i-=8;
        +					case 2:	otp |= RC4_STEP<<i, i-=8;
        +					case 1:	otp |= RC4_STEP<<i, i-=8;
        +					case 0: ; /*
        +						   * it's never the case,
        +						   * but it has to be here
        +						   * for ultrix?
        +						   */
        +					}
        +				ochunk &= ~mask;
        +				ochunk |= (otp^ichunk) & mask;
        +				*(RC4_CHUNK *)outdata = ochunk;
        +				}
        +			key->x=x;     
        +			key->y=y;
        +			return;
        +			}
        +		else
        +			{	/* LITTLE-ENDIAN CASE */
        +# define LESHFT(c)	(((c)*8)&(sizeof(RC4_CHUNK)*8-1))
        +			for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
        +				{
        +				ichunk  = *(RC4_CHUNK *)indata;
        +				otp  = RC4_STEP;
        +				otp |= RC4_STEP<<8;
        +				otp |= RC4_STEP<<16;
        +				otp |= RC4_STEP<<24;
        +				if (sizeof(RC4_CHUNK)==8)
        +					{
        +					otp |= RC4_STEP<<LESHFT(4);
        +					otp |= RC4_STEP<<LESHFT(5);
        +					otp |= RC4_STEP<<LESHFT(6);
        +					otp |= RC4_STEP<<LESHFT(7);
        +					}
        +				*(RC4_CHUNK *)outdata = otp^ichunk;
        +				indata  += sizeof(RC4_CHUNK);
        +				outdata += sizeof(RC4_CHUNK);
        +				}
        +			if (len)
        +				{
        +				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
        +
        +				ichunk = *(RC4_CHUNK *)indata;
        +				ochunk = *(RC4_CHUNK *)outdata;
        +				otp = 0;
        +				i   = 0;
        +				mask >>= (sizeof(RC4_CHUNK)-len)<<3;
        +				switch (len&(sizeof(RC4_CHUNK)-1))
        +					{
        +					case 7:	otp  = RC4_STEP,    i+=8;
        +					case 6:	otp |= RC4_STEP<<i, i+=8;
        +					case 5:	otp |= RC4_STEP<<i, i+=8;
        +					case 4:	otp |= RC4_STEP<<i, i+=8;
        +					case 3:	otp |= RC4_STEP<<i, i+=8;
        +					case 2:	otp |= RC4_STEP<<i, i+=8;
        +					case 1:	otp |= RC4_STEP<<i, i+=8;
        +					case 0: ; /*
        +						   * it's never the case,
        +						   * but it has to be here
        +						   * for ultrix?
        +						   */
        +					}
        +				ochunk &= ~mask;
        +				ochunk |= (otp^ichunk) & mask;
        +				*(RC4_CHUNK *)outdata = ochunk;
        +				}
        +			key->x=x;     
        +			key->y=y;
        +			return;
        +			}
        +		}
        +#endif
        +#define LOOP(in,out) \
        +		x=((x+1)&0xff); \
        +		tx=d[x]; \
        +		y=(tx+y)&0xff; \
        +		d[x]=ty=d[y]; \
        +		d[y]=tx; \
        +		(out) = d[(tx+ty)&0xff]^ (in);
        +
        +#ifndef RC4_INDEX
        +#define RC4_LOOP(a,b,i)	LOOP(*((a)++),*((b)++))
        +#else
        +#define RC4_LOOP(a,b,i)	LOOP(a[i],b[i])
        +#endif
        +
        +	i=len>>3;
        +	if (i)
        +		{
        +		for (;;)
        +			{
        +			RC4_LOOP(indata,outdata,0);
        +			RC4_LOOP(indata,outdata,1);
        +			RC4_LOOP(indata,outdata,2);
        +			RC4_LOOP(indata,outdata,3);
        +			RC4_LOOP(indata,outdata,4);
        +			RC4_LOOP(indata,outdata,5);
        +			RC4_LOOP(indata,outdata,6);
        +			RC4_LOOP(indata,outdata,7);
        +#ifdef RC4_INDEX
        +			indata+=8;
        +			outdata+=8;
        +#endif
        +			if (--i == 0) break;
        +			}
        +		}
        +	i=len&0x07;
        +	if (i)
        +		{
        +		for (;;)
        +			{
        +			RC4_LOOP(indata,outdata,0); if (--i == 0) break;
        +			RC4_LOOP(indata,outdata,1); if (--i == 0) break;
        +			RC4_LOOP(indata,outdata,2); if (--i == 0) break;
        +			RC4_LOOP(indata,outdata,3); if (--i == 0) break;
        +			RC4_LOOP(indata,outdata,4); if (--i == 0) break;
        +			RC4_LOOP(indata,outdata,5); if (--i == 0) break;
        +			RC4_LOOP(indata,outdata,6); if (--i == 0) break;
        +			}
        +		}               
        +	key->x=x;     
        +	key->y=y;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4_locl.h b/vendor/openssl/openssl/crypto/rc4/rc4_locl.h
        new file mode 100644
        index 000000000..c712e1632
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4_locl.h
        @@ -0,0 +1,5 @@
        +#ifndef HEADER_RC4_LOCL_H
        +#define HEADER_RC4_LOCL_H
        +#include <openssl/opensslconf.h>
        +#include <cryptlib.h>
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4_skey.c b/vendor/openssl/openssl/crypto/rc4/rc4_skey.c
        new file mode 100644
        index 000000000..fda27636e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4_skey.c
        @@ -0,0 +1,116 @@
        +/* crypto/rc4/rc4_skey.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 <openssl/rc4.h>
        +#include "rc4_locl.h"
        +#include <openssl/opensslv.h>
        +
        +const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT;
        +
        +const char *RC4_options(void)
        +	{
        +#ifdef RC4_INDEX
        +	if (sizeof(RC4_INT) == 1)
        +		return("rc4(idx,char)");
        +	else
        +		return("rc4(idx,int)");
        +#else
        +	if (sizeof(RC4_INT) == 1)
        +		return("rc4(ptr,char)");
        +	else
        +		return("rc4(ptr,int)");
        +#endif
        +	}
        +
        +/* RC4 as implemented from a posting from
        + * Newsgroups: sci.crypt
        + * From: sterndark@netcom.com (David Sterndark)
        + * Subject: RC4 Algorithm revealed.
        + * Message-ID: <sternCvKL4B.Hyy@netcom.com>
        + * Date: Wed, 14 Sep 1994 06:35:31 GMT
        + */
        +
        +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
        +	{
        +        register RC4_INT tmp;
        +        register int id1,id2;
        +        register RC4_INT *d;
        +        unsigned int i;
        +        
        +        d= &(key->data[0]);
        +        key->x = 0;     
        +        key->y = 0;     
        +        id1=id2=0;     
        +
        +#define SK_LOOP(d,n) { \
        +		tmp=d[(n)]; \
        +		id2 = (data[id1] + tmp + id2) & 0xff; \
        +		if (++id1 == len) id1=0; \
        +		d[(n)]=d[id2]; \
        +		d[id2]=tmp; }
        +
        +	for (i=0; i < 256; i++) d[i]=i;
        +	for (i=0; i < 256; i+=4)
        +		{
        +		SK_LOOP(d,i+0);
        +		SK_LOOP(d,i+1);
        +		SK_LOOP(d,i+2);
        +		SK_LOOP(d,i+3);
        +		}
        +	}
        +    
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4_utl.c b/vendor/openssl/openssl/crypto/rc4/rc4_utl.c
        new file mode 100644
        index 000000000..ab3f02fe6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4_utl.c
        @@ -0,0 +1,62 @@
        +/* crypto/rc4/rc4_utl.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2011 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +#include <openssl/rc4.h>
        +
        +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
        +	{
        +#ifdef OPENSSL_FIPS
        +	fips_cipher_abort(RC4);
        +#endif
        +	private_RC4_set_key(key, len, data);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4s.cpp b/vendor/openssl/openssl/crypto/rc4/rc4s.cpp
        new file mode 100644
        index 000000000..3814fde99
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4s.cpp
        @@ -0,0 +1,73 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/rc4.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	unsigned char buffer[1024];
        +	RC4_KEY ctx;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned char k[16];
        +	unsigned long data[2];
        +	unsigned char iv[8];
        +	int i,num=64,numm;
        +	int j=0;
        +
        +	if (argc >= 2)
        +		num=atoi(argv[1]);
        +
        +	if (num == 0) num=256;
        +	if (num > 1024-16) num=1024-16;
        +	numm=num+8;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<10; i++) /**/
        +			{
        +			RC4(&ctx,numm,buffer,buffer);
        +			GetTSC(s1);
        +			RC4(&ctx,numm,buffer,buffer);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			RC4(&ctx,num,buffer,buffer);
        +			GetTSC(e2);
        +			RC4(&ctx,num,buffer,buffer);
        +			}
        +
        +		printf("RC4 (%d bytes) %d %d (%d) - 8 bytes\n",num,
        +			e1-s1,e2-s2,(e1-s1)-(e2-s2));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4speed.c b/vendor/openssl/openssl/crypto/rc4/rc4speed.c
        new file mode 100644
        index 000000000..0ebd38123
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4speed.c
        @@ -0,0 +1,253 @@
        +/* crypto/rc4/rc4speed.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/rc4.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +#ifndef CLK_TCK
        +#define HZ	100.0
        +#else /* CLK_TCK */
        +#define HZ ((double)CLK_TCK)
        +#endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static unsigned char key[] ={
        +			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
        +			};
        +	RC4_KEY sch;
        +	double a,b,c,d;
        +#ifndef SIGALRM
        +	long ca,cb,cc;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	RC4_set_key(&sch,16,key);
        +	count=10;
        +	do	{
        +		long i;
        +		unsigned long data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			RC4(&sch,8,buf,buf);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count/512;
        +	cc=count*8/BUFSIZE+1;
        +	printf("Doing RC4_set_key %ld times\n",ca);
        +#define COND(d)	(count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing RC4_set_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count+=4)
        +		{
        +		RC4_set_key(&sch,16,key);
        +		RC4_set_key(&sch,16,key);
        +		RC4_set_key(&sch,16,key);
        +		RC4_set_key(&sch,16,key);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld RC4_set_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing RC4 on %ld byte blocks for 10 seconds\n",BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing RC4 %ld times on %ld byte blocks\n",cc,BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		RC4(&sch,BUFSIZE,buf,buf);
        +	d=Time_F(STOP);
        +	printf("%ld RC4's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +	printf("RC4 set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("RC4   bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc4/rc4test.c b/vendor/openssl/openssl/crypto/rc4/rc4test.c
        new file mode 100644
        index 000000000..4312605cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rc4test.c
        @@ -0,0 +1,242 @@
        +/* crypto/rc4/rc4test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RC4
        +int main(int argc, char *argv[])
        +{
        +    printf("No RC4 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rc4.h>
        +#include <openssl/sha.h>
        +
        +static unsigned char keys[7][30]={
        +	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
        +	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
        +	{8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{4,0xef,0x01,0x23,0x45},
        +	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
        +	{4,0xef,0x01,0x23,0x45},
        +	};
        +
        +static unsigned char data_len[7]={8,8,8,20,28,10};
        +static unsigned char data[7][30]={
        +	{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	   0x00,0x00,0x00,0x00,0xff},
        +	{0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
        +	   0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
        +	   0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
        +	   0x12,0x34,0x56,0x78,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
        +	{0},
        +	};
        +
        +static unsigned char output[7][30]={
        +	{0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
        +	{0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
        +	{0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
        +	{0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,
        +	 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba,
        +	 0x36,0xb6,0x78,0x58,0x00},
        +	{0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89,
        +	 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c,
        +	 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87,
        +	 0x40,0x01,0x1e,0xcf,0x00},
        +	{0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00},
        +	{0},
        +	};
        +
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	int j;
        +	unsigned char *p;
        +	RC4_KEY key;
        +	unsigned char obuf[512];
        +
        +#if !defined(OPENSSL_PIC)
        +	void OPENSSL_cpuid_setup(void);
        +
        +	OPENSSL_cpuid_setup();
        +#endif
        +
        +	for (i=0; i<6; i++)
        +		{
        +		RC4_set_key(&key,keys[i][0],&(keys[i][1]));
        +		memset(obuf,0x00,sizeof(obuf));
        +		RC4(&key,data_len[i],&(data[i][0]),obuf);
        +		if (memcmp(obuf,output[i],data_len[i]+1) != 0)
        +			{
        +			printf("error calculating RC4\n");
        +			printf("output:");
        +			for (j=0; j<data_len[i]+1; j++)
        +				printf(" %02x",obuf[j]);
        +			printf("\n");
        +			printf("expect:");
        +			p= &(output[i][0]);
        +			for (j=0; j<data_len[i]+1; j++)
        +				printf(" %02x",*(p++));
        +			printf("\n");
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		}
        +	printf("test end processing ");
        +	for (i=0; i<data_len[3]; i++)
        +		{
        +		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
        +		memset(obuf,0x00,sizeof(obuf));
        +		RC4(&key,i,&(data[3][0]),obuf);
        +		if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0))
        +			{
        +			printf("error in RC4 length processing\n");
        +			printf("output:");
        +			for (j=0; j<i+1; j++)
        +				printf(" %02x",obuf[j]);
        +			printf("\n");
        +			printf("expect:");
        +			p= &(output[3][0]);
        +			for (j=0; j<i; j++)
        +				printf(" %02x",*(p++));
        +			printf(" 00\n");
        +			err++;
        +			}
        +		else
        +			{
        +			printf(".");
        +			fflush(stdout);
        +			}
        +		}
        +	printf("done\n");
        +	printf("test multi-call ");
        +	for (i=0; i<data_len[3]; i++)
        +		{
        +		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
        +		memset(obuf,0x00,sizeof(obuf));
        +		RC4(&key,i,&(data[3][0]),obuf);
        +		RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i]));
        +		if (memcmp(obuf,output[3],data_len[3]+1) != 0)
        +			{
        +			printf("error in RC4 multi-call processing\n");
        +			printf("output:");
        +			for (j=0; j<data_len[3]+1; j++)
        +				printf(" %02x",obuf[j]);
        +			printf("\n");
        +			printf("expect:");
        +			p= &(output[3][0]);
        +			for (j=0; j<data_len[3]+1; j++)
        +				printf(" %02x",*(p++));
        +			err++;
        +			}
        +		else
        +			{
        +			printf(".");
        +			fflush(stdout);
        +			}
        +		}
        +	printf("done\n");
        +	printf("bulk test ");
        +	{   unsigned char buf[513];
        +	    SHA_CTX c;
        +	    unsigned char md[SHA_DIGEST_LENGTH];
        +	    static unsigned char expected[]={
        +		0xa4,0x7b,0xcc,0x00,0x3d,0xd0,0xbd,0xe1,0xac,0x5f,
        +		0x12,0x1e,0x45,0xbc,0xfb,0x1a,0xa1,0xf2,0x7f,0xc5 };
        +
        +		RC4_set_key(&key,keys[0][0],&(keys[3][1]));
        +		memset(buf,'\0',sizeof(buf));
        +		SHA1_Init(&c);
        +		for (i=0;i<2571;i++) {
        +			RC4(&key,sizeof(buf),buf,buf);
        +			SHA1_Update(&c,buf,sizeof(buf));
        +		}
        +		SHA1_Final(md,&c);
        +
        +		if (memcmp(md,expected,sizeof(md))) {
        +			printf("error in RC4 bulk test\n");
        +			printf("output:");
        +			for (j=0; j<(int)sizeof(md); j++)
        +				printf(" %02x",md[j]);
        +			printf("\n");
        +			printf("expect:");
        +			for (j=0; j<(int)sizeof(md); j++)
        +				printf(" %02x",expected[j]);
        +			printf("\n");
        +			err++;
        +		}
        +		else	printf("ok\n");
        +	}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(0);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc4/rrc4.doc b/vendor/openssl/openssl/crypto/rc4/rrc4.doc
        new file mode 100644
        index 000000000..2f9a953c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc4/rrc4.doc
        @@ -0,0 +1,278 @@
        +Newsgroups: sci.crypt,alt.security,comp.security.misc,alt.privacy
        +Path: ghost.dsi.unimi.it!univ-lyon1.fr!jussieu.fr!zaphod.crihan.fr!warwick!clyde.open.ac.uk!strath-cs!bnr.co.uk!bt!pipex!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!yeshua.marcam.com!charnel.ecst.csuchico.edu!csusac!csus.edu!netcom.com!sterndark
        +From: sterndark@netcom.com (David Sterndark)
        +Subject: RC4 Algorithm revealed.
        +Message-ID: <sternCvKL4B.Hyy@netcom.com>
        +Sender: sterndark@netcom.com 
        +Organization: NETCOM On-line Communication Services (408 261-4700 guest)
        +X-Newsreader: TIN [version 1.2 PL1]
        +Date: Wed, 14 Sep 1994 06:35:31 GMT
        +Lines: 263
        +Xref: ghost.dsi.unimi.it sci.crypt:27332 alt.security:14732 comp.security.misc:11701 alt.privacy:16026
        +
        +I am shocked,  shocked, I tell you,  shocked, to discover
        +that the cypherpunks have illegaly and criminally revealed
        +a crucial RSA trade secret and harmed the security of
        +America by reverse engineering the RC4 algorithm and
        +publishing it to the world.
        + 
        +On Saturday morning an anonymous cypherpunk wrote:
        + 
        + 
        +   SUBJECT:  RC4 Source Code
        + 
        + 
        +   I've tested this.  It is compatible with the RC4 object module
        +   that comes in the various RSA toolkits.  
        + 
        +   /* rc4.h */
        +   typedef struct rc4_key
        +   {      
        +        unsigned char state[256];       
        +        unsigned char x;        
        +        unsigned char y;
        +   } rc4_key;
        +   void prepare_key(unsigned char *key_data_ptr,int key_data_len,
        +   rc4_key *key);
        +   void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key);
        +   
        +   
        +   /*rc4.c */
        +   #include "rc4.h"
        +   static void swap_byte(unsigned char *a, unsigned char *b);
        +   void prepare_key(unsigned char *key_data_ptr, int key_data_len,
        +   rc4_key *key)
        +   {
        +        unsigned char swapByte;
        +        unsigned char index1;
        +        unsigned char index2;
        +        unsigned char* state;
        +        short counter;     
        +        
        +        state = &key->state[0];         
        +        for(counter = 0; counter < 256; counter++)              
        +        state[counter] = counter;               
        +        key->x = 0;     
        +        key->y = 0;     
        +        index1 = 0;     
        +        index2 = 0;             
        +        for(counter = 0; counter < 256; counter++)      
        +        {               
        +             index2 = (key_data_ptr[index1] + state[counter] +
        +                index2) % 256;                
        +             swap_byte(&state[counter], &state[index2]);            
        +   
        +             index1 = (index1 + 1) % key_data_len;  
        +        }       
        +    }
        +    
        +    void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
        +    { 
        +        unsigned char x;
        +        unsigned char y;
        +        unsigned char* state;
        +        unsigned char xorIndex;
        +        short counter;              
        +        
        +        x = key->x;     
        +        y = key->y;     
        +        
        +        state = &key->state[0];         
        +        for(counter = 0; counter < buffer_len; counter ++)      
        +        {               
        +             x = (x + 1) % 256;                      
        +             y = (state[x] + y) % 256;               
        +             swap_byte(&state[x], &state[y]);                        
        +                  
        +             xorIndex = (state[x] + state[y]) % 256;                 
        +                  
        +             buffer_ptr[counter] ^= state[xorIndex];         
        +         }               
        +         key->x = x;     
        +         key->y = y;
        +    }
        +    
        +    static void swap_byte(unsigned char *a, unsigned char *b)
        +    {
        +        unsigned char swapByte; 
        +        
        +        swapByte = *a; 
        +        *a = *b;      
        +        *b = swapByte;
        +    }
        + 
        + 
        + 
        +Another cypherpunk, this one not anonymous, tested the
        +output from this algorithm against the output from
        +official RC4 object code
        + 
        + 
        +   Date: Tue, 13 Sep 94 18:37:56 PDT
        +   From: ekr@eit.COM (Eric Rescorla)
        +   Message-Id: <9409140137.AA17743@eitech.eit.com>
        +   Subject: RC4 compatibility testing
        +   Cc: cypherpunks@toad.com
        +   
        +   One data point:
        +   
        +   I can't say anything about the internals of RC4 versus the
        +   algorithm that Bill Sommerfeld is rightly calling 'Alleged RC4',
        +   since I don't know anything about RC4's internals. 
        +   
        +   However, I do have a (legitimately acquired) copy of BSAFE2 and
        +   so I'm able to compare the output of this algorithm to the output
        +   of genuine RC4 as found in BSAFE. I chose a set of test vectors
        +   and ran them through both algorithms. The algorithms appear to
        +   give identical results, at least with these key/plaintext pairs.
        +   
        +   I note that this is the algorithm _without_ Hal Finney's
        +   proposed modification
        +   
        +   (see <199409130605.XAA24133@jobe.shell.portal.com>).
        +   
        +   The vectors I used (together with the ciphertext they produce)
        +   follow at the end of this message.
        +   
        +   -Ekr
        +   
        +   Disclaimer: This posting does not reflect the opinions of EIT.
        +   
        +   --------------------results follow--------------
        +   Test vector 0
        +   Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
        +   Input: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
        +   0 Output: 0x75 0xb7 0x87 0x80 0x99 0xe0 0xc5 0x96 
        +   
        +   Test vector 1
        +   Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
        +   Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
        +   0 Output: 0x74 0x94 0xc2 0xe7 0x10 0x4b 0x08 0x79 
        +   
        +   Test vector 2
        +   Key: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
        +   Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
        +   0 Output: 0xde 0x18 0x89 0x41 0xa3 0x37 0x5d 0x3a 
        +   
        +   Test vector 3
        +   Key: 0xef 0x01 0x23 0x45 
        +   Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
        +   0 Output: 0xd6 0xa1 0x41 0xa7 0xec 0x3c 0x38 0xdf 0xbd 0x61 
        +   
        +   Test vector 4
        +   Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef 
        +   Input: 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 
        +   0x01 
        +   0 Output: 0x75 0x95 0xc3 0xe6 0x11 0x4a 0x09 0x78 0x0c 0x4a 0xd4 
        +   0x52 0x33 0x8e 0x1f 0xfd 0x9a 0x1b 0xe9 0x49 0x8f 
        +   0x81 0x3d 0x76 0x53 0x34 0x49 0xb6 0x77 0x8d 0xca 
        +   0xd8 0xc7 0x8a 0x8d 0x2b 0xa9 0xac 0x66 0x08 0x5d 
        +   0x0e 0x53 0xd5 0x9c 0x26 0xc2 0xd1 0xc4 0x90 0xc1 
        +   0xeb 0xbe 0x0c 0xe6 0x6d 0x1b 0x6b 0x1b 0x13 0xb6 
        +   0xb9 0x19 0xb8 0x47 0xc2 0x5a 0x91 0x44 0x7a 0x95 
        +   0xe7 0x5e 0x4e 0xf1 0x67 0x79 0xcd 0xe8 0xbf 0x0a 
        +   0x95 0x85 0x0e 0x32 0xaf 0x96 0x89 0x44 0x4f 0xd3 
        +   0x77 0x10 0x8f 0x98 0xfd 0xcb 0xd4 0xe7 0x26 0x56 
        +   0x75 0x00 0x99 0x0b 0xcc 0x7e 0x0c 0xa3 0xc4 0xaa 
        +   0xa3 0x04 0xa3 0x87 0xd2 0x0f 0x3b 0x8f 0xbb 0xcd 
        +   0x42 0xa1 0xbd 0x31 0x1d 0x7a 0x43 0x03 0xdd 0xa5 
        +   0xab 0x07 0x88 0x96 0xae 0x80 0xc1 0x8b 0x0a 0xf6 
        +   0x6d 0xff 0x31 0x96 0x16 0xeb 0x78 0x4e 0x49 0x5a 
        +   0xd2 0xce 0x90 0xd7 0xf7 0x72 0xa8 0x17 0x47 0xb6 
        +   0x5f 0x62 0x09 0x3b 0x1e 0x0d 0xb9 0xe5 0xba 0x53 
        +   0x2f 0xaf 0xec 0x47 0x50 0x83 0x23 0xe6 0x71 0x32 
        +   0x7d 0xf9 0x44 0x44 0x32 0xcb 0x73 0x67 0xce 0xc8 
        +   0x2f 0x5d 0x44 0xc0 0xd0 0x0b 0x67 0xd6 0x50 0xa0 
        +   0x75 0xcd 0x4b 0x70 0xde 0xdd 0x77 0xeb 0x9b 0x10 
        +   0x23 0x1b 0x6b 0x5b 0x74 0x13 0x47 0x39 0x6d 0x62 
        +   0x89 0x74 0x21 0xd4 0x3d 0xf9 0xb4 0x2e 0x44 0x6e 
        +   0x35 0x8e 0x9c 0x11 0xa9 0xb2 0x18 0x4e 0xcb 0xef 
        +   0x0c 0xd8 0xe7 0xa8 0x77 0xef 0x96 0x8f 0x13 0x90 
        +   0xec 0x9b 0x3d 0x35 0xa5 0x58 0x5c 0xb0 0x09 0x29 
        +   0x0e 0x2f 0xcd 0xe7 0xb5 0xec 0x66 0xd9 0x08 0x4b 
        +   0xe4 0x40 0x55 0xa6 0x19 0xd9 0xdd 0x7f 0xc3 0x16 
        +   0x6f 0x94 0x87 0xf7 0xcb 0x27 0x29 0x12 0x42 0x64 
        +   0x45 0x99 0x85 0x14 0xc1 0x5d 0x53 0xa1 0x8c 0x86 
        +   0x4c 0xe3 0xa2 0xb7 0x55 0x57 0x93 0x98 0x81 0x26 
        +   0x52 0x0e 0xac 0xf2 0xe3 0x06 0x6e 0x23 0x0c 0x91 
        +   0xbe 0xe4 0xdd 0x53 0x04 0xf5 0xfd 0x04 0x05 0xb3 
        +   0x5b 0xd9 0x9c 0x73 0x13 0x5d 0x3d 0x9b 0xc3 0x35 
        +   0xee 0x04 0x9e 0xf6 0x9b 0x38 0x67 0xbf 0x2d 0x7b 
        +   0xd1 0xea 0xa5 0x95 0xd8 0xbf 0xc0 0x06 0x6f 0xf8 
        +   0xd3 0x15 0x09 0xeb 0x0c 0x6c 0xaa 0x00 0x6c 0x80 
        +   0x7a 0x62 0x3e 0xf8 0x4c 0x3d 0x33 0xc1 0x95 0xd2 
        +   0x3e 0xe3 0x20 0xc4 0x0d 0xe0 0x55 0x81 0x57 0xc8 
        +   0x22 0xd4 0xb8 0xc5 0x69 0xd8 0x49 0xae 0xd5 0x9d 
        +   0x4e 0x0f 0xd7 0xf3 0x79 0x58 0x6b 0x4b 0x7f 0xf6 
        +   0x84 0xed 0x6a 0x18 0x9f 0x74 0x86 0xd4 0x9b 0x9c 
        +   0x4b 0xad 0x9b 0xa2 0x4b 0x96 0xab 0xf9 0x24 0x37 
        +   0x2c 0x8a 0x8f 0xff 0xb1 0x0d 0x55 0x35 0x49 0x00 
        +   0xa7 0x7a 0x3d 0xb5 0xf2 0x05 0xe1 0xb9 0x9f 0xcd 
        +   0x86 0x60 0x86 0x3a 0x15 0x9a 0xd4 0xab 0xe4 0x0f 
        +   0xa4 0x89 0x34 0x16 0x3d 0xdd 0xe5 0x42 0xa6 0x58 
        +   0x55 0x40 0xfd 0x68 0x3c 0xbf 0xd8 0xc0 0x0f 0x12 
        +   0x12 0x9a 0x28 0x4d 0xea 0xcc 0x4c 0xde 0xfe 0x58 
        +   0xbe 0x71 0x37 0x54 0x1c 0x04 0x71 0x26 0xc8 0xd4 
        +   0x9e 0x27 0x55 0xab 0x18 0x1a 0xb7 0xe9 0x40 0xb0 
        +   0xc0 
        +   
        +
        +
        +-- 
        + ---------------------------------------------------------------------
        +We have the right to defend ourselves and our
        +property, because of the kind of animals that we              James A. Donald
        +are.  True law derives from this right, not from
        +the arbitrary power of the omnipotent state.                jamesd@netcom.com
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/Makefile b/vendor/openssl/openssl/crypto/rc5/Makefile
        new file mode 100644
        index 000000000..8a8b00eb8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/Makefile
        @@ -0,0 +1,94 @@
        +#
        +# OpenSSL/crypto/rc5/Makefile
        +#
        +
        +DIR=	rc5
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +RC5_ENC=		rc5_enc.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=rc5test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=rc5_skey.c rc5_ecb.c rc5_enc.c rc5cfb64.c rc5ofb64.c 
        +LIBOBJ=rc5_skey.o rc5_ecb.o $(RC5_ENC) rc5cfb64.o rc5ofb64.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= rc5.h
        +HEADER=	rc5_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) || echo Never mind.
        +	@touch lib
        +
        +rc5-586.s: asm/rc5-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
        +	$(PERL) asm/rc5-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rc5_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rc5_ecb.o: ../../include/openssl/rc5.h rc5_ecb.c rc5_locl.h
        +rc5_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
        +rc5_enc.o: rc5_enc.c rc5_locl.h
        +rc5_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
        +rc5_skey.o: rc5_locl.h rc5_skey.c
        +rc5cfb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
        +rc5cfb64.o: rc5_locl.h rc5cfb64.c
        +rc5ofb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc5.h
        +rc5ofb64.o: rc5_locl.h rc5ofb64.c
        diff --git a/vendor/openssl/openssl/crypto/rc5/asm/rc5-586.pl b/vendor/openssl/openssl/crypto/rc5/asm/rc5-586.pl
        new file mode 100644
        index 000000000..61ac6effc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/asm/rc5-586.pl
        @@ -0,0 +1,110 @@
        +#!/usr/local/bin/perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +require "cbc.pl";
        +
        +&asm_init($ARGV[0],"rc5-586.pl");
        +
        +$RC5_MAX_ROUNDS=16;
        +$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4;
        +$A="edi";
        +$B="esi";
        +$S="ebp";
        +$tmp1="eax";
        +$r="ebx";
        +$tmpc="ecx";
        +$tmp4="edx";
        +
        +&RC5_32_encrypt("RC5_32_encrypt",1);
        +&RC5_32_encrypt("RC5_32_decrypt",0);
        +&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1);
        +&asm_finish();
        +
        +sub RC5_32_encrypt
        +	{
        +	local($name,$enc)=@_;
        +
        +	&function_begin_B($name,"");
        +
        +	&comment("");
        +
        +	&push("ebp");
        +	 &push("esi");
        +	&push("edi");
        +	 &mov($tmp4,&wparam(0));
        +	&mov($S,&wparam(1));
        +
        +	&comment("Load the 2 words");
        +	 &mov($A,&DWP(0,$tmp4,"",0));
        +	&mov($B,&DWP(4,$tmp4,"",0));
        +
        +	&push($r);
        +	 &mov($r,	&DWP(0,$S,"",0));
        +
        +	# encrypting part
        +
        +	if ($enc)
        +		{
        +		 &add($A,	&DWP(4+0,$S,"",0));
        +		&add($B,	&DWP(4+4,$S,"",0));
        +
        +		for ($i=0; $i<$RC5_MAX_ROUNDS; $i++)
        +			{
        +			 &xor($A,	$B);
        +			&mov($tmp1,	&DWP(12+$i*8,$S,"",0));
        +			 &mov($tmpc,	$B);
        +			&rotl($A,	&LB("ecx"));
        +			&add($A,	$tmp1);
        +
        +			 &xor($B,	$A);
        +			&mov($tmp1,	&DWP(16+$i*8,$S,"",0));
        +			 &mov($tmpc,	$A);
        +			&rotl($B,	&LB("ecx"));
        +			&add($B,	$tmp1);
        +			if (($i == 7) || ($i == 11))
        +				{
        +			 &cmp($r,	$i+1);
        +			&je(&label("rc5_exit"));
        +				}
        +			}
        +		}
        +	else
        +		{
        +		 &cmp($r,	12);
        +		&je(&label("rc5_dec_12"));
        +		 &cmp($r,	8);
        +		&je(&label("rc5_dec_8"));
        +		for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--)
        +			{
        +			&set_label("rc5_dec_$i") if ($i == 12) || ($i == 8);
        +			 &mov($tmp1,	&DWP($i*8+8,$S,"",0));
        +			&sub($B,	$tmp1);
        +			 &mov($tmpc,	$A);
        +			&rotr($B,	&LB("ecx"));
        +			&xor($B,	$A);
        +
        +			 &mov($tmp1,	&DWP($i*8+4,$S,"",0));
        +			&sub($A,	$tmp1);
        +			 &mov($tmpc,	$B);
        +			&rotr($A,	&LB("ecx"));
        +			&xor($A,	$B);
        +			}
        +		 &sub($B,	&DWP(4+4,$S,"",0));
        +		&sub($A,	&DWP(4+0,$S,"",0));
        +		}
        +
        +	&set_label("rc5_exit");
        +	 &mov(&DWP(0,$tmp4,"",0),$A);
        +	&mov(&DWP(4,$tmp4,"",0),$B);
        +
        +	 &pop("ebx");
        +	&pop("edi");
        +	 &pop("esi");
        +	&pop("ebp");
        +	 &ret();
        +	&function_end_B($name);
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5.h b/vendor/openssl/openssl/crypto/rc5/rc5.h
        new file mode 100644
        index 000000000..4b3c153b5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5.h
        @@ -0,0 +1,118 @@
        +/* crypto/rc5/rc5.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_RC5_H
        +#define HEADER_RC5_H
        +
        +#include <openssl/opensslconf.h> /* OPENSSL_NO_RC5 */
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_NO_RC5
        +#error RC5 is disabled.
        +#endif
        +
        +#define RC5_ENCRYPT	1
        +#define RC5_DECRYPT	0
        +
        +/* 32 bit.  For Alpha, things may get weird */
        +#define RC5_32_INT unsigned long
        +
        +#define RC5_32_BLOCK		8
        +#define RC5_32_KEY_LENGTH	16 /* This is a default, max is 255 */
        +
        +/* This are the only values supported.  Tweak the code if you want more
        + * The most supported modes will be
        + * RC5-32/12/16
        + * RC5-32/16/8
        + */
        +#define RC5_8_ROUNDS	8
        +#define RC5_12_ROUNDS	12
        +#define RC5_16_ROUNDS	16
        +
        +typedef struct rc5_key_st
        +	{
        +	/* Number of rounds */
        +	int rounds;
        +	RC5_32_INT data[2*(RC5_16_ROUNDS+1)];
        +	} RC5_32_KEY;
        +
        + 
        +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
        +	int rounds);
        +void RC5_32_ecb_encrypt(const unsigned char *in,unsigned char *out,RC5_32_KEY *key,
        +	int enc);
        +void RC5_32_encrypt(unsigned long *data,RC5_32_KEY *key);
        +void RC5_32_decrypt(unsigned long *data,RC5_32_KEY *key);
        +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, RC5_32_KEY *ks, unsigned char *iv,
        +			int enc);
        +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +			  long length, RC5_32_KEY *schedule,
        +			  unsigned char *ivec, int *num, int enc);
        +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +			  long length, RC5_32_KEY *schedule,
        +			  unsigned char *ivec, int *num);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5_ecb.c b/vendor/openssl/openssl/crypto/rc5/rc5_ecb.c
        new file mode 100644
        index 000000000..e72b53550
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5_ecb.c
        @@ -0,0 +1,80 @@
        +/* crypto/rc5/rc5_ecb.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 <openssl/rc5.h>
        +#include "rc5_locl.h"
        +#include <openssl/opensslv.h>
        +
        +const char RC5_version[]="RC5" OPENSSL_VERSION_PTEXT;
        +
        +void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +			RC5_32_KEY *ks, int encrypt)
        +	{
        +	unsigned long l,d[2];
        +
        +	c2l(in,l); d[0]=l;
        +	c2l(in,l); d[1]=l;
        +	if (encrypt)
        +		RC5_32_encrypt(d,ks);
        +	else
        +		RC5_32_decrypt(d,ks);
        +	l=d[0]; l2c(l,out);
        +	l=d[1]; l2c(l,out);
        +	l=d[0]=d[1]=0;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5_enc.c b/vendor/openssl/openssl/crypto/rc5/rc5_enc.c
        new file mode 100644
        index 000000000..f327d32a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5_enc.c
        @@ -0,0 +1,215 @@
        +/* crypto/rc5/rc5_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/rc5.h>
        +#include "rc5_locl.h"
        +
        +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +			long length, RC5_32_KEY *ks, unsigned char *iv,
        +			int encrypt)
        +	{
        +	register unsigned long tin0,tin1;
        +	register unsigned long tout0,tout1,xor0,xor1;
        +	register long l=length;
        +	unsigned long tin[2];
        +
        +	if (encrypt)
        +		{
        +		c2l(iv,tout0);
        +		c2l(iv,tout1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0);
        +			c2l(in,tin1);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			RC5_32_encrypt(tin,ks);
        +			tout0=tin[0]; l2c(tout0,out);
        +			tout1=tin[1]; l2c(tout1,out);
        +			}
        +		if (l != -8)
        +			{
        +			c2ln(in,tin0,tin1,l+8);
        +			tin0^=tout0;
        +			tin1^=tout1;
        +			tin[0]=tin0;
        +			tin[1]=tin1;
        +			RC5_32_encrypt(tin,ks);
        +			tout0=tin[0]; l2c(tout0,out);
        +			tout1=tin[1]; l2c(tout1,out);
        +			}
        +		l2c(tout0,iv);
        +		l2c(tout1,iv);
        +		}
        +	else
        +		{
        +		c2l(iv,xor0);
        +		c2l(iv,xor1);
        +		iv-=8;
        +		for (l-=8; l>=0; l-=8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0;
        +			c2l(in,tin1); tin[1]=tin1;
        +			RC5_32_decrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2c(tout0,out);
        +			l2c(tout1,out);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		if (l != -8)
        +			{
        +			c2l(in,tin0); tin[0]=tin0;
        +			c2l(in,tin1); tin[1]=tin1;
        +			RC5_32_decrypt(tin,ks);
        +			tout0=tin[0]^xor0;
        +			tout1=tin[1]^xor1;
        +			l2cn(tout0,tout1,out,l+8);
        +			xor0=tin0;
        +			xor1=tin1;
        +			}
        +		l2c(xor0,iv);
        +		l2c(xor1,iv);
        +		}
        +	tin0=tin1=tout0=tout1=xor0=xor1=0;
        +	tin[0]=tin[1]=0;
        +	}
        +
        +void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key)
        +	{
        +	RC5_32_INT a,b,*s;
        +
        +	s=key->data;
        +
        +	a=d[0]+s[0];
        +	b=d[1]+s[1];
        +	E_RC5_32(a,b,s, 2);
        +	E_RC5_32(a,b,s, 4);
        +	E_RC5_32(a,b,s, 6);
        +	E_RC5_32(a,b,s, 8);
        +	E_RC5_32(a,b,s,10);
        +	E_RC5_32(a,b,s,12);
        +	E_RC5_32(a,b,s,14);
        +	E_RC5_32(a,b,s,16);
        +	if (key->rounds == 12)
        +		{
        +		E_RC5_32(a,b,s,18);
        +		E_RC5_32(a,b,s,20);
        +		E_RC5_32(a,b,s,22);
        +		E_RC5_32(a,b,s,24);
        +		}
        +	else if (key->rounds == 16)
        +		{
        +		/* Do a full expansion to avoid a jump */
        +		E_RC5_32(a,b,s,18);
        +		E_RC5_32(a,b,s,20);
        +		E_RC5_32(a,b,s,22);
        +		E_RC5_32(a,b,s,24);
        +		E_RC5_32(a,b,s,26);
        +		E_RC5_32(a,b,s,28);
        +		E_RC5_32(a,b,s,30);
        +		E_RC5_32(a,b,s,32);
        +		}
        +	d[0]=a;
        +	d[1]=b;
        +	}
        +
        +void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key)
        +	{
        +	RC5_32_INT a,b,*s;
        +
        +	s=key->data;
        +
        +	a=d[0];
        +	b=d[1];
        +	if (key->rounds == 16) 
        +		{
        +		D_RC5_32(a,b,s,32);
        +		D_RC5_32(a,b,s,30);
        +		D_RC5_32(a,b,s,28);
        +		D_RC5_32(a,b,s,26);
        +		/* Do a full expansion to avoid a jump */
        +		D_RC5_32(a,b,s,24);
        +		D_RC5_32(a,b,s,22);
        +		D_RC5_32(a,b,s,20);
        +		D_RC5_32(a,b,s,18);
        +		}
        +	else if (key->rounds == 12)
        +		{
        +		D_RC5_32(a,b,s,24);
        +		D_RC5_32(a,b,s,22);
        +		D_RC5_32(a,b,s,20);
        +		D_RC5_32(a,b,s,18);
        +		}
        +	D_RC5_32(a,b,s,16);
        +	D_RC5_32(a,b,s,14);
        +	D_RC5_32(a,b,s,12);
        +	D_RC5_32(a,b,s,10);
        +	D_RC5_32(a,b,s, 8);
        +	D_RC5_32(a,b,s, 6);
        +	D_RC5_32(a,b,s, 4);
        +	D_RC5_32(a,b,s, 2);
        +	d[0]=a-s[0];
        +	d[1]=b-s[1];
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5_locl.h b/vendor/openssl/openssl/crypto/rc5/rc5_locl.h
        new file mode 100644
        index 000000000..d337f73fa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5_locl.h
        @@ -0,0 +1,207 @@
        +/* crypto/rc5/rc5_locl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdlib.h>
        +
        +#undef c2l
        +#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
        +			 l|=((unsigned long)(*((c)++)))<< 8L, \
        +			 l|=((unsigned long)(*((c)++)))<<16L, \
        +			 l|=((unsigned long)(*((c)++)))<<24L)
        +
        +/* NOTE - c is not incremented as per c2l */
        +#undef c2ln
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 5: l2|=((unsigned long)(*(--(c))));     \
        +			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
        +			case 1: l1|=((unsigned long)(*(--(c))));     \
        +				} \
        +			}
        +
        +#undef l2c
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        +
        +/* NOTE - c is not incremented as per l2c */
        +#undef l2cn
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per n2l */
        +#define n2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))    ; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
        +			case 4: l1 =((unsigned long)(*(--(c))))    ; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
        +				} \
        +			}
        +
        +/* NOTE - c is not incremented as per l2n */
        +#define l2nn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +				} \
        +			}
        +
        +#undef n2l
        +#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
        +                         l|=((unsigned long)(*((c)++)))<<16L, \
        +                         l|=((unsigned long)(*((c)++)))<< 8L, \
        +                         l|=((unsigned long)(*((c)++))))
        +
        +#undef l2n
        +#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        +                         *((c)++)=(unsigned char)(((l)     )&0xff))
        +
        +#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
        +#define ROTATE_l32(a,n)     _lrotl(a,n)
        +#define ROTATE_r32(a,n)     _lrotr(a,n)
        +#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
        +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
        +#  define ROTATE_l32(a,n)	({ register unsigned int ret;	\
        +					asm ("roll %%cl,%0"	\
        +						: "=r"(ret)	\
        +						: "c"(n),"0"((unsigned int)(a))	\
        +						: "cc");	\
        +					ret;			\
        +				})
        +#  define ROTATE_r32(a,n)	({ register unsigned int ret;	\
        +					asm ("rorl %%cl,%0"	\
        +						: "=r"(ret)	\
        +						: "c"(n),"0"((unsigned int)(a))	\
        +						: "cc");	\
        +					ret;			\
        +				})
        +# endif
        +#endif
        +#ifndef ROTATE_l32
        +#define ROTATE_l32(a,n)     (((a)<<(n&0x1f))|(((a)&0xffffffff)>>(32-(n&0x1f))))
        +#endif
        +#ifndef ROTATE_r32
        +#define ROTATE_r32(a,n)     (((a)<<(32-(n&0x1f)))|(((a)&0xffffffff)>>(n&0x1f)))
        +#endif
        +
        +#define RC5_32_MASK	0xffffffffL
        +
        +#define RC5_16_P	0xB7E1
        +#define RC5_16_Q	0x9E37
        +#define RC5_32_P	0xB7E15163L
        +#define RC5_32_Q	0x9E3779B9L
        +#define RC5_64_P	0xB7E151628AED2A6BLL
        +#define RC5_64_Q	0x9E3779B97F4A7C15LL
        +
        +#define E_RC5_32(a,b,s,n) \
        +	a^=b; \
        +	a=ROTATE_l32(a,b); \
        +	a+=s[n]; \
        +	a&=RC5_32_MASK; \
        +	b^=a; \
        +	b=ROTATE_l32(b,a); \
        +	b+=s[n+1]; \
        +	b&=RC5_32_MASK;
        +
        +#define D_RC5_32(a,b,s,n) \
        +	b-=s[n+1]; \
        +	b&=RC5_32_MASK; \
        +	b=ROTATE_r32(b,a); \
        +	b^=a; \
        +	a-=s[n]; \
        +	a&=RC5_32_MASK; \
        +	a=ROTATE_r32(a,b); \
        +	a^=b;
        +
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5_skey.c b/vendor/openssl/openssl/crypto/rc5/rc5_skey.c
        new file mode 100644
        index 000000000..a2e00a41c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5_skey.c
        @@ -0,0 +1,113 @@
        +/* crypto/rc5/rc5_skey.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 <openssl/rc5.h>
        +#include "rc5_locl.h"
        +
        +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
        +		    int rounds)
        +	{
        +	RC5_32_INT L[64],l,ll,A,B,*S,k;
        +	int i,j,m,c,t,ii,jj;
        +
        +	if (	(rounds != RC5_16_ROUNDS) &&
        +		(rounds != RC5_12_ROUNDS) &&
        +		(rounds != RC5_8_ROUNDS))
        +		rounds=RC5_16_ROUNDS;
        +
        +	key->rounds=rounds;
        +	S= &(key->data[0]);
        +	j=0;
        +	for (i=0; i<=(len-8); i+=8)
        +		{
        +		c2l(data,l);
        +		L[j++]=l;
        +		c2l(data,l);
        +		L[j++]=l;
        +		}
        +	ii=len-i;
        +	if (ii)
        +		{
        +		k=len&0x07;
        +		c2ln(data,l,ll,k);
        +		L[j+0]=l;
        +		L[j+1]=ll;
        +		}
        +
        +	c=(len+3)/4;
        +	t=(rounds+1)*2;
        +	S[0]=RC5_32_P;
        +	for (i=1; i<t; i++)
        +		S[i]=(S[i-1]+RC5_32_Q)&RC5_32_MASK;
        +
        +	j=(t>c)?t:c;
        +	j*=3;
        +	ii=jj=0;
        +	A=B=0;
        +	for (i=0; i<j; i++)
        +		{
        +		k=(S[ii]+A+B)&RC5_32_MASK;
        +		A=S[ii]=ROTATE_l32(k,3);
        +		m=(int)(A+B);
        +		k=(L[jj]+A+B)&RC5_32_MASK;
        +		B=L[jj]=ROTATE_l32(k,m);
        +		if (++ii >= t) ii=0;
        +		if (++jj >= c) jj=0;
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5cfb64.c b/vendor/openssl/openssl/crypto/rc5/rc5cfb64.c
        new file mode 100644
        index 000000000..3a8b60bc7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5cfb64.c
        @@ -0,0 +1,122 @@
        +/* crypto/rc5/rc5cfb64.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 <openssl/rc5.h>
        +#include "rc5_locl.h"
        +
        +/* The input and output encrypted as though 64bit cfb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +
        +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +			  long length, RC5_32_KEY *schedule,
        +			  unsigned char *ivec, int *num, int encrypt)
        +	{
        +	register unsigned long v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned long ti[2];
        +	unsigned char *iv,c,cc;
        +
        +	iv=(unsigned char *)ivec;
        +	if (encrypt)
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0); ti[0]=v0;
        +				c2l(iv,v1); ti[1]=v1;
        +				RC5_32_encrypt((unsigned long *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2c(t,iv);
        +				t=ti[1]; l2c(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			c= *(in++)^iv[n];
        +			*(out++)=c;
        +			iv[n]=c;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	else
        +		{
        +		while (l--)
        +			{
        +			if (n == 0)
        +				{
        +				c2l(iv,v0); ti[0]=v0;
        +				c2l(iv,v1); ti[1]=v1;
        +				RC5_32_encrypt((unsigned long *)ti,schedule);
        +				iv=(unsigned char *)ivec;
        +				t=ti[0]; l2c(t,iv);
        +				t=ti[1]; l2c(t,iv);
        +				iv=(unsigned char *)ivec;
        +				}
        +			cc= *(in++);
        +			c=iv[n];
        +			iv[n]=cc;
        +			*(out++)=c^cc;
        +			n=(n+1)&0x07;
        +			}
        +		}
        +	v0=v1=ti[0]=ti[1]=t=c=cc=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5ofb64.c b/vendor/openssl/openssl/crypto/rc5/rc5ofb64.c
        new file mode 100644
        index 000000000..d412215f3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5ofb64.c
        @@ -0,0 +1,111 @@
        +/* crypto/rc5/rc5ofb64.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 <openssl/rc5.h>
        +#include "rc5_locl.h"
        +
        +/* The input and output encrypted as though 64bit ofb mode is being
        + * used.  The extra state information to record how much of the
        + * 64bit block we have used is contained in *num;
        + */
        +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +			  long length, RC5_32_KEY *schedule,
        +			  unsigned char *ivec, int *num)
        +	{
        +	register unsigned long v0,v1,t;
        +	register int n= *num;
        +	register long l=length;
        +	unsigned char d[8];
        +	register char *dp;
        +	unsigned long ti[2];
        +	unsigned char *iv;
        +	int save=0;
        +
        +	iv=(unsigned char *)ivec;
        +	c2l(iv,v0);
        +	c2l(iv,v1);
        +	ti[0]=v0;
        +	ti[1]=v1;
        +	dp=(char *)d;
        +	l2c(v0,dp);
        +	l2c(v1,dp);
        +	while (l--)
        +		{
        +		if (n == 0)
        +			{
        +			RC5_32_encrypt((unsigned long *)ti,schedule);
        +			dp=(char *)d;
        +			t=ti[0]; l2c(t,dp);
        +			t=ti[1]; l2c(t,dp);
        +			save++;
        +			}
        +		*(out++)= *(in++)^d[n];
        +		n=(n+1)&0x07;
        +		}
        +	if (save)
        +		{
        +		v0=ti[0];
        +		v1=ti[1];
        +		iv=(unsigned char *)ivec;
        +		l2c(v0,iv);
        +		l2c(v1,iv);
        +		}
        +	t=v0=v1=ti[0]=ti[1]=0;
        +	*num=n;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5s.cpp b/vendor/openssl/openssl/crypto/rc5/rc5s.cpp
        new file mode 100644
        index 000000000..1c5518bc8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5s.cpp
        @@ -0,0 +1,70 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/rc5.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	RC5_32_KEY key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +	static unsigned char d[16]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
        +
        +	RC5_32_set_key(&key, 16,d,12);
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			RC5_32_encrypt(&data[0],&key);
        +			GetTSC(s1);
        +			RC5_32_encrypt(&data[0],&key);
        +			RC5_32_encrypt(&data[0],&key);
        +			RC5_32_encrypt(&data[0],&key);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			RC5_32_encrypt(&data[0],&key);
        +			RC5_32_encrypt(&data[0],&key);
        +			RC5_32_encrypt(&data[0],&key);
        +			RC5_32_encrypt(&data[0],&key);
        +			GetTSC(e2);
        +			RC5_32_encrypt(&data[0],&key);
        +			}
        +
        +		printf("cast %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5speed.c b/vendor/openssl/openssl/crypto/rc5/rc5speed.c
        new file mode 100644
        index 000000000..8e363be53
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5speed.c
        @@ -0,0 +1,277 @@
        +/* crypto/rc5/rc5speed.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.]
        + */
        +
        +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
        +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
        +#define TIMES
        +#endif
        +
        +#include <stdio.h>
        +
        +#include <openssl/e_os2.h>
        +#include OPENSSL_UNISTD_IO
        +OPENSSL_DECLARE_EXIT
        +
        +#ifndef OPENSSL_SYS_NETWARE
        +#include <signal.h>
        +#endif
        +
        +#ifndef _IRIX
        +#include <time.h>
        +#endif
        +#ifdef TIMES
        +#include <sys/types.h>
        +#include <sys/times.h>
        +#endif
        +
        +/* Depending on the VMS version, the tms structure is perhaps defined.
        +   The __TMS macro will show if it was.  If it wasn't defined, we should
        +   undefine TIMES, since that tells the rest of the program how things
        +   should be handled.				-- Richard Levitte */
        +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
        +#undef TIMES
        +#endif
        +
        +#ifndef TIMES
        +#include <sys/timeb.h>
        +#endif
        +
        +#if defined(sun) || defined(__ultrix)
        +#define _POSIX_SOURCE
        +#include <limits.h>
        +#include <sys/param.h>
        +#endif
        +
        +#include <openssl/rc5.h>
        +
        +/* The following if from times(3) man page.  It may need to be changed */
        +#ifndef HZ
        +#ifndef CLK_TCK
        +#define HZ	100.0
        +#else /* CLK_TCK */
        +#define HZ ((double)CLK_TCK)
        +#endif
        +#endif
        +
        +#define BUFSIZE	((long)1024)
        +long run=0;
        +
        +double Time_F(int s);
        +#ifdef SIGALRM
        +#if defined(__STDC__) || defined(sgi) || defined(_AIX)
        +#define SIGRETTYPE void
        +#else
        +#define SIGRETTYPE int
        +#endif
        +
        +SIGRETTYPE sig_done(int sig);
        +SIGRETTYPE sig_done(int sig)
        +	{
        +	signal(SIGALRM,sig_done);
        +	run=0;
        +#ifdef LINT
        +	sig=sig;
        +#endif
        +	}
        +#endif
        +
        +#define START	0
        +#define STOP	1
        +
        +double Time_F(int s)
        +	{
        +	double ret;
        +#ifdef TIMES
        +	static struct tms tstart,tend;
        +
        +	if (s == START)
        +		{
        +		times(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		times(&tend);
        +		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#else /* !times() */
        +	static struct timeb tstart,tend;
        +	long i;
        +
        +	if (s == START)
        +		{
        +		ftime(&tstart);
        +		return(0);
        +		}
        +	else
        +		{
        +		ftime(&tend);
        +		i=(long)tend.millitm-(long)tstart.millitm;
        +		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
        +		return((ret == 0.0)?1e-6:ret);
        +		}
        +#endif
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	long count;
        +	static unsigned char buf[BUFSIZE];
        +	static unsigned char key[] ={
        +			0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
        +			0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
        +			};
        +	RC5_32_KEY sch;
        +	double a,b,c,d;
        +#ifndef SIGALRM
        +	long ca,cb,cc;
        +#endif
        +
        +#ifndef TIMES
        +	printf("To get the most accurate results, try to run this\n");
        +	printf("program when this computer is idle.\n");
        +#endif
        +
        +#ifndef SIGALRM
        +	printf("First we calculate the approximate speed ...\n");
        +	RC5_32_set_key(&sch,16,key,12);
        +	count=10;
        +	do	{
        +		long i;
        +		unsigned long data[2];
        +
        +		count*=2;
        +		Time_F(START);
        +		for (i=count; i; i--)
        +			RC5_32_encrypt(data,&sch);
        +		d=Time_F(STOP);
        +		} while (d < 3.0);
        +	ca=count/512;
        +	cb=count;
        +	cc=count*8/BUFSIZE+1;
        +	printf("Doing RC5_32_set_key %ld times\n",ca);
        +#define COND(d)	(count != (d))
        +#define COUNT(d) (d)
        +#else
        +#define COND(c)	(run)
        +#define COUNT(d) (count)
        +	signal(SIGALRM,sig_done);
        +	printf("Doing RC5_32_set_key for 10 seconds\n");
        +	alarm(10);
        +#endif
        +
        +	Time_F(START);
        +	for (count=0,run=1; COND(ca); count+=4)
        +		{
        +		RC5_32_set_key(&sch,16,key,12);
        +		RC5_32_set_key(&sch,16,key,12);
        +		RC5_32_set_key(&sch,16,key,12);
        +		RC5_32_set_key(&sch,16,key,12);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld RC5_32_set_key's in %.2f seconds\n",count,d);
        +	a=((double)COUNT(ca))/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing RC5_32_encrypt's for 10 seconds\n");
        +	alarm(10);
        +#else
        +	printf("Doing RC5_32_encrypt %ld times\n",cb);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cb); count+=4)
        +		{
        +		unsigned long data[2];
        +
        +		RC5_32_encrypt(data,&sch);
        +		RC5_32_encrypt(data,&sch);
        +		RC5_32_encrypt(data,&sch);
        +		RC5_32_encrypt(data,&sch);
        +		}
        +	d=Time_F(STOP);
        +	printf("%ld RC5_32_encrypt's in %.2f second\n",count,d);
        +	b=((double)COUNT(cb)*8)/d;
        +
        +#ifdef SIGALRM
        +	printf("Doing RC5_32_cbc_encrypt on %ld byte blocks for 10 seconds\n",
        +		BUFSIZE);
        +	alarm(10);
        +#else
        +	printf("Doing RC5_32_cbc_encrypt %ld times on %ld byte blocks\n",cc,
        +		BUFSIZE);
        +#endif
        +	Time_F(START);
        +	for (count=0,run=1; COND(cc); count++)
        +		RC5_32_cbc_encrypt(buf,buf,BUFSIZE,&sch,
        +			&(key[0]),RC5_ENCRYPT);
        +	d=Time_F(STOP);
        +	printf("%ld RC5_32_cbc_encrypt's of %ld byte blocks in %.2f second\n",
        +		count,BUFSIZE,d);
        +	c=((double)COUNT(cc)*BUFSIZE)/d;
        +
        +	printf("RC5_32/12/16 set_key       per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
        +	printf("RC5_32/12/16 raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
        +	printf("RC5_32/12/16 cbc     bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
        +	exit(0);
        +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
        +	return(0);
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rc5/rc5test.c b/vendor/openssl/openssl/crypto/rc5/rc5test.c
        new file mode 100644
        index 000000000..ce3d0cc16
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rc5/rc5test.c
        @@ -0,0 +1,386 @@
        +/* crypto/rc5/rc5test.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.]
        + */
        +
        +/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
        + * RC5 modes, more of the code will be uncommented. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RC5
        +int main(int argc, char *argv[])
        +{
        +    printf("No RC5 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rc5.h>
        +
        +static unsigned char RC5key[5][16]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x91,0x5f,0x46,0x19,0xbe,0x41,0xb2,0x51,
        +	 0x63,0x55,0xa5,0x01,0x10,0xa9,0xce,0x91},
        +	{0x78,0x33,0x48,0xe7,0x5a,0xeb,0x0f,0x2f,
        +	 0xd7,0xb1,0x69,0xbb,0x8d,0xc1,0x67,0x87},
        +	{0xdc,0x49,0xdb,0x13,0x75,0xa5,0x58,0x4f,
        +	 0x64,0x85,0xb4,0x13,0xb5,0xf1,0x2b,0xaf},
        +	{0x52,0x69,0xf1,0x49,0xd4,0x1b,0xa0,0x15,
        +	 0x24,0x97,0x57,0x4d,0x7f,0x15,0x31,0x25},
        +	};
        +
        +static unsigned char RC5plain[5][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D},
        +	{0xF7,0xC0,0x13,0xAC,0x5B,0x2B,0x89,0x52},
        +	{0x2F,0x42,0xB3,0xB7,0x03,0x69,0xFC,0x92},
        +	{0x65,0xC1,0x78,0xB2,0x84,0xD1,0x97,0xCC},
        +	};
        +
        +static unsigned char RC5cipher[5][8]={
        +	{0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D},
        +	{0xF7,0xC0,0x13,0xAC,0x5B,0x2B,0x89,0x52},
        +	{0x2F,0x42,0xB3,0xB7,0x03,0x69,0xFC,0x92},
        +	{0x65,0xC1,0x78,0xB2,0x84,0xD1,0x97,0xCC},
        +	{0xEB,0x44,0xE4,0x15,0xDA,0x31,0x98,0x24},
        +	};
        +
        +#define RC5_CBC_NUM 27
        +static unsigned char rc5_cbc_cipher[RC5_CBC_NUM][8]={
        +	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1e},
        +	{0x79,0x7b,0xba,0x4d,0x78,0x11,0x1d,0x1e},
        +	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1f},
        +	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1f},
        +	{0x8b,0x9d,0xed,0x91,0xce,0x77,0x94,0xa6},
        +	{0x2f,0x75,0x9f,0xe7,0xad,0x86,0xa3,0x78},
        +	{0xdc,0xa2,0x69,0x4b,0xf4,0x0e,0x07,0x88},
        +	{0xdc,0xa2,0x69,0x4b,0xf4,0x0e,0x07,0x88},
        +	{0xdc,0xfe,0x09,0x85,0x77,0xec,0xa5,0xff},
        +	{0x96,0x46,0xfb,0x77,0x63,0x8f,0x9c,0xa8},
        +	{0xb2,0xb3,0x20,0x9d,0xb6,0x59,0x4d,0xa4},
        +	{0x54,0x5f,0x7f,0x32,0xa5,0xfc,0x38,0x36},
        +	{0x82,0x85,0xe7,0xc1,0xb5,0xbc,0x74,0x02},
        +	{0xfc,0x58,0x6f,0x92,0xf7,0x08,0x09,0x34},
        +	{0xcf,0x27,0x0e,0xf9,0x71,0x7f,0xf7,0xc4},
        +	{0xe4,0x93,0xf1,0xc1,0xbb,0x4d,0x6e,0x8c},
        +	{0x5c,0x4c,0x04,0x1e,0x0f,0x21,0x7a,0xc3},
        +	{0x92,0x1f,0x12,0x48,0x53,0x73,0xb4,0xf7},
        +	{0x5b,0xa0,0xca,0x6b,0xbe,0x7f,0x5f,0xad},
        +	{0xc5,0x33,0x77,0x1c,0xd0,0x11,0x0e,0x63},
        +	{0x29,0x4d,0xdb,0x46,0xb3,0x27,0x8d,0x60},
        +	{0xda,0xd6,0xbd,0xa9,0xdf,0xe8,0xf7,0xe8},
        +	{0x97,0xe0,0x78,0x78,0x37,0xed,0x31,0x7f},
        +	{0x78,0x75,0xdb,0xf6,0x73,0x8c,0x64,0x78},
        +	{0x8f,0x34,0xc3,0xc6,0x81,0xc9,0x96,0x95},
        +	{0x7c,0xb3,0xf1,0xdf,0x34,0xf9,0x48,0x11},
        +	{0x7f,0xd1,0xa0,0x23,0xa5,0xbb,0xa2,0x17},
        +	};
        +
        +static unsigned char rc5_cbc_key[RC5_CBC_NUM][17]={
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 1,0x11},
        +	{ 1,0x00},
        +	{ 4,0x00,0x00,0x00,0x00},
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 1,0x00},
        +	{ 4,0x01,0x02,0x03,0x04},
        +	{ 4,0x01,0x02,0x03,0x04},
        +	{ 4,0x01,0x02,0x03,0x04},
        +	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{ 8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{16,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
        +	    0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{16,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
        +	    0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{16,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
        +	    0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{ 5,0x01,0x02,0x03,0x04,0x05},
        +	{ 5,0x01,0x02,0x03,0x04,0x05},
        +	{ 5,0x01,0x02,0x03,0x04,0x05},
        +	{ 5,0x01,0x02,0x03,0x04,0x05},
        +	{ 5,0x01,0x02,0x03,0x04,0x05},
        +	};
        +
        +static unsigned char rc5_cbc_plain[RC5_CBC_NUM][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
        +	{0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x01},
        +	};
        +
        +static int rc5_cbc_rounds[RC5_CBC_NUM]={
        +	 0, 0, 0, 0, 0, 1, 2, 2,
        +	 8, 8,12,16, 8,12,16,12,
        +	 8,12,16, 8,12,16,12, 8,
        +	 8, 8, 8,
        +	};
        +
        +static unsigned char rc5_cbc_iv[RC5_CBC_NUM][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x78,0x75,0xdb,0xf6,0x73,0x8c,0x64,0x78},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x7c,0xb3,0xf1,0xdf,0x34,0xf9,0x48,0x11},
        +	};
        +
        +int main(int argc, char *argv[])
        +	{
        +	int i,n,err=0;
        +	RC5_32_KEY key; 
        +	unsigned char buf[8],buf2[8],ivb[8];
        +
        +	for (n=0; n<5; n++)
        +		{
        +		RC5_32_set_key(&key,16,&(RC5key[n][0]),12);
        +
        +		RC5_32_ecb_encrypt(&(RC5plain[n][0]),buf,&key,RC5_ENCRYPT);
        +		if (memcmp(&(RC5cipher[n][0]),buf,8) != 0)
        +			{
        +			printf("ecb RC5 error encrypting (%d)\n",n+1);
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",RC5cipher[n][i]);
        +			err=20;
        +			printf("\n");
        +			}
        +
        +		RC5_32_ecb_encrypt(buf,buf2,&key,RC5_DECRYPT);
        +		if (memcmp(&(RC5plain[n][0]),buf2,8) != 0)
        +			{
        +			printf("ecb RC5 error decrypting (%d)\n",n+1);
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf2[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",RC5plain[n][i]);
        +			printf("\n");
        +			err=3;
        +			}
        +		}
        +	if (err == 0) printf("ecb RC5 ok\n");
        +
        +	for (n=0; n<RC5_CBC_NUM; n++)
        +		{
        +		i=rc5_cbc_rounds[n];
        +		if (i < 8) continue;
        +
        +		RC5_32_set_key(&key,rc5_cbc_key[n][0],&(rc5_cbc_key[n][1]),i);
        +
        +		memcpy(ivb,&(rc5_cbc_iv[n][0]),8);
        +		RC5_32_cbc_encrypt(&(rc5_cbc_plain[n][0]),buf,8,
        +			&key,&(ivb[0]),RC5_ENCRYPT);
        +
        +		if (memcmp(&(rc5_cbc_cipher[n][0]),buf,8) != 0)
        +			{
        +			printf("cbc RC5 error encrypting (%d)\n",n+1);
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",rc5_cbc_cipher[n][i]);
        +			err=30;
        +			printf("\n");
        +			}
        +
        +		memcpy(ivb,&(rc5_cbc_iv[n][0]),8);
        +		RC5_32_cbc_encrypt(buf,buf2,8,
        +			&key,&(ivb[0]),RC5_DECRYPT);
        +		if (memcmp(&(rc5_cbc_plain[n][0]),buf2,8) != 0)
        +			{
        +			printf("cbc RC5 error decrypting (%d)\n",n+1);
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf2[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",rc5_cbc_plain[n][i]);
        +			printf("\n");
        +			err=3;
        +			}
        +		}
        +	if (err == 0) printf("cbc RC5 ok\n");
        +
        +	EXIT(err);
        +	return(err);
        +	}
        +
        +#ifdef undef
        +static int cfb64_test(unsigned char *cfb_cipher)
        +        {
        +        IDEA_KEY_SCHEDULE eks,dks;
        +        int err=0,i,n;
        +
        +        idea_set_encrypt_key(cfb_key,&eks);
        +        idea_set_decrypt_key(&eks,&dks);
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +                (long)CFB_TEST_SIZE-12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb64_encrypt encrypt error\n");
        +                for (i=0; i<CFB_TEST_SIZE; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf1[i])));
        +                }
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +                (long)CFB_TEST_SIZE-17,&dks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb_encrypt decrypt error\n");
        +                for (i=0; i<24; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf2[i])));
        +                }
        +        return(err);
        +        }
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +	
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ripemd/Makefile b/vendor/openssl/openssl/crypto/ripemd/Makefile
        new file mode 100644
        index 000000000..25140b2a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/Makefile
        @@ -0,0 +1,95 @@
        +#
        +# OpenSSL/crypto/ripemd/Makefile
        +#
        +
        +DIR=    ripemd
        +TOP=    ../..
        +CC=     cc
        +CPP=    $(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=       Makefile
        +AR=             ar r
        +
        +RIP_ASM_OBJ=
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=rmdtest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=rmd_dgst.c rmd_one.c
        +LIBOBJ=rmd_dgst.o rmd_one.o $(RMD160_ASM_OBJ)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ripemd.h
        +HEADER= rmd_locl.h rmdconst.h $(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:    lib
        +
        +lib:    $(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +rmd-586.s:	asm/rmd-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/rmd-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rmd_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rmd_dgst.o: ../../include/openssl/opensslconf.h
        +rmd_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rmd_dgst.o: ../../include/openssl/ripemd.h ../../include/openssl/safestack.h
        +rmd_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rmd_dgst.o: ../md32_common.h rmd_dgst.c rmd_locl.h rmdconst.h
        +rmd_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rmd_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rmd_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/ripemd.h
        +rmd_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rmd_one.o: ../../include/openssl/symhacks.h rmd_one.c
        diff --git a/vendor/openssl/openssl/crypto/ripemd/README b/vendor/openssl/openssl/crypto/ripemd/README
        new file mode 100644
        index 000000000..f1ffc8b13
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/README
        @@ -0,0 +1,15 @@
        +RIPEMD-160
        +http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
        +
        +This is my implementation of RIPEMD-160.  The pentium assember is a little
        +off the pace since I only get 1050 cycles, while the best is 1013.
        +I have a few ideas for how to get another 20 or so cycles, but at
        +this point I will not bother right now.  I believe the trick will be
        +to remove my 'copy X array onto stack' until inside the RIP1() finctions the
        +first time round.  To do this I need another register and will only have one
        +temporary one.  A bit tricky....  I can also cleanup the saving of the 5 words
        +after the first half of the calculation.  I should read the origional
        +value, add then write.  Currently I just save the new and read the origioal.
        +I then read both at the end.  Bad.
        +
        +eric (20-Jan-1998)
        diff --git a/vendor/openssl/openssl/crypto/ripemd/asm/rips.cpp b/vendor/openssl/openssl/crypto/ripemd/asm/rips.cpp
        new file mode 100644
        index 000000000..f7a13677a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/asm/rips.cpp
        @@ -0,0 +1,82 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/ripemd.h>
        +
        +#define ripemd160_block_x86 ripemd160_block_asm_host_order
        +
        +extern "C" {
        +void ripemd160_block_x86(RIPEMD160_CTX *ctx, unsigned char *buffer,int num);
        +}
        +
        +void main(int argc,char *argv[])
        +	{
        +	unsigned char buffer[64*256];
        +	RIPEMD160_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;
        +#if 0
        +	num*=64;
        +	numm*=64;
        +#endif
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<10; i++) /**/
        +			{
        +			ripemd160_block_x86(&ctx,buffer,numm);
        +			GetTSC(s1);
        +			ripemd160_block_x86(&ctx,buffer,numm);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			ripemd160_block_x86(&ctx,buffer,num);
        +			GetTSC(e2);
        +			ripemd160_block_x86(&ctx,buffer,num);
        +			}
        +		printf("ripemd160 (%d bytes) %d %d (%.2f)\n",num*64,
        +			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ripemd/asm/rmd-586.pl b/vendor/openssl/openssl/crypto/ripemd/asm/rmd-586.pl
        new file mode 100644
        index 000000000..e8b2bc2db
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/asm/rmd-586.pl
        @@ -0,0 +1,591 @@
        +#!/usr/local/bin/perl
        +
        +# Normal is the
        +# ripemd160_block_asm_data_order(RIPEMD160_CTX *c, ULONG *X,int blocks);
        +
        +$normal=0;
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],$0);
        +
        +$A="ecx";
        +$B="esi";
        +$C="edi";
        +$D="ebx";
        +$E="ebp";
        +$tmp1="eax";
        +$tmp2="edx";
        +
        +$KL1=0x5A827999;
        +$KL2=0x6ED9EBA1;
        +$KL3=0x8F1BBCDC;
        +$KL4=0xA953FD4E;
        +$KR0=0x50A28BE6;
        +$KR1=0x5C4DD124; 
        +$KR2=0x6D703EF3;
        +$KR3=0x7A6D76E9;
        +
        +
        +@wl=(	 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
        +	 7, 4,13, 1,10, 6,15, 3,12, 0, 9, 5, 2,14,11, 8,
        +	 3,10,14, 4, 9,15, 8, 1, 2, 7, 0, 6,13,11, 5,12,
        +	 1, 9,11,10, 0, 8,12, 4,13, 3, 7,15,14, 5, 6, 2,
        +	 4, 0, 5, 9, 7,12, 2,10,14, 1, 3, 8,11, 6,15,13,
        +	 );
        +
        +@wr=(	 5,14, 7, 0, 9, 2,11, 4,13, 6,15, 8, 1,10, 3,12,
        +	 6,11, 3, 7, 0,13, 5,10,14,15, 8,12, 4, 9, 1, 2,
        +	15, 5, 1, 3, 7,14, 6, 9,11, 8,12, 2,10, 0, 4,13,
        +	 8, 6, 4, 1, 3,11,15, 0, 5,12, 2,13, 9, 7,10,14,
        +	12,15,10, 4, 1, 5, 8, 7, 6, 2,13,14, 0, 3, 9,11,
        +	);
        +
        +@sl=(	11,14,15,12, 5, 8, 7, 9,11,13,14,15, 6, 7, 9, 8,
        +	 7, 6, 8,13,11, 9, 7,15, 7,12,15, 9,11, 7,13,12,
        +	11,13, 6, 7,14, 9,13,15,14, 8,13, 6, 5,12, 7, 5,
        +	11,12,14,15,14,15, 9, 8, 9,14, 5, 6, 8, 6, 5,12,
        +	 9,15, 5,11, 6, 8,13,12, 5,12,13,14,11, 8, 5, 6,
        +	 );
        +
        +@sr=(	 8, 9, 9,11,13,15,15, 5, 7, 7, 8,11,14,14,12, 6,
        +	 9,13,15, 7,12, 8, 9,11, 7, 7,12, 7, 6,15,13,11,
        +	 9, 7,15,11, 8, 6, 6,14,12,13, 5,14,13,13, 7, 5,
        +	15, 5, 8,11,14,14, 6,14, 6, 9,12, 9,12, 5,15, 8,
        +	 8, 5,12, 9,12, 5,14, 6, 8,13, 6, 5,15,13,11,11,
        + 	);
        +
        +&ripemd160_block("ripemd160_block_asm_data_order");
        +&asm_finish();
        +
        +sub Xv
        +	{
        +	local($n)=@_;
        +	return(&swtmp($n));
        +	# tmp on stack
        +	}
        +
        +sub Np
        +	{
        +	local($p)=@_;
        +	local(%n)=($A,$E,$B,$A,$C,$B,$D,$C,$E,$D);
        +	return($n{$p});
        +	}
        +
        +sub RIP1
        +	{
        +	local($a,$b,$c,$d,$e,$pos,$s,$o,$pos2)=@_;
        +
        +	&comment($p++);
        +	if ($p & 1)
        +		{
        +	 #&mov($tmp1,	$c) if $o == -1;
        +	&xor($tmp1,	$d) if $o == -1;
        +	 &mov($tmp2,	&Xv($pos));
        +	&xor($tmp1,	$b);
        +	 &add($a,	$tmp2);
        +	&rotl($c,	10);
        +	&add($a,	$tmp1);
        +	 &mov($tmp1,	&Np($c));	# NEXT
        +	 # XXX
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	else
        +		{
        +	 &xor($tmp1,	$d);
        +	&mov($tmp2,	&Xv($pos));
        +	 &xor($tmp1,	$b);
        +	&add($a,	$tmp1);
        +	 &mov($tmp1,	&Np($c)) if $o <= 0;
        +	 &mov($tmp1,	-1) if $o == 1;
        +	 # XXX if $o == 2;
        +	&rotl($c,	10);
        +	&add($a,	$tmp2);
        +	 &xor($tmp1,	&Np($d)) if $o <= 0;
        +	 &mov($tmp2,	&Xv($pos2)) if $o == 1;
        +	 &mov($tmp2,	&wparam(0)) if $o == 2;
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	}
        +
        +sub RIP2
        +	{
        +	local($a,$b,$c,$d,$e,$pos,$pos2,$s,$K,$o)=@_;
        +
        +# XXXXXX
        +	&comment($p++);
        +	if ($p & 1)
        +		{
        +#	 &mov($tmp2,	&Xv($pos)) if $o < -1;
        +#	&mov($tmp1,	-1) if $o < -1;
        +
        +	 &add($a,	$tmp2);
        +	&mov($tmp2,	$c);
        +	 &sub($tmp1,	$b);
        +	&and($tmp2,	$b);
        +	 &and($tmp1,	$d);
        +	&or($tmp2,	$tmp1);
        +	 &mov($tmp1,	&Xv($pos2)) if $o <= 0; # XXXXXXXXXXXXXX
        +	 # XXX
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp2,1));
        +	 &mov($tmp2,	-1) if $o <= 0;
        +	 # XXX
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	else
        +		{
        +	 # XXX
        +	 &add($a,	$tmp1);
        +	&mov($tmp1,	$c);
        +	 &sub($tmp2,	$b);
        +	&and($tmp1,	$b);
        +	 &and($tmp2,	$d);
        +	if ($o != 2)
        +		{
        +	&or($tmp1,	$tmp2);
        +	 &mov($tmp2,	&Xv($pos2)) if $o <= 0;
        +	 &mov($tmp2,	-1) if $o == 1;
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp1,1));
        +	 &mov($tmp1,	-1) if $o <= 0;
        +	 &sub($tmp2,	&Np($c)) if $o == 1;
        +		} else {
        +	&or($tmp2,	$tmp1);
        +	 &mov($tmp1,	&Np($c));
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp2,1));
        +	 &xor($tmp1,	&Np($d));
        +		}
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	}
        +
        +sub RIP3
        +	{
        +	local($a,$b,$c,$d,$e,$pos,$s,$K,$o,$pos2)=@_;
        +
        +	&comment($p++);
        +	if ($p & 1)
        +		{
        +#	 &mov($tmp2,	-1) if $o < -1;
        +#	&sub($tmp2,	$c) if $o < -1;
        +	 &mov($tmp1,	&Xv($pos));
        +	&or($tmp2,	$b);
        +	 &add($a,	$tmp1);
        +	&xor($tmp2,	$d);
        +	 &mov($tmp1,	-1) if $o <= 0;		# NEXT
        +	 # XXX
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp2,1));
        +	 &sub($tmp1,	&Np($c)) if $o <= 0;	# NEXT
        +	 # XXX
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	else
        +		{
        +	 &mov($tmp2,	&Xv($pos));
        +	&or($tmp1,	$b);
        +	 &add($a,	$tmp2);
        +	&xor($tmp1,	$d);
        +	 &mov($tmp2,	-1) if $o <= 0;		# NEXT
        +	 &mov($tmp2,	-1) if $o == 1;
        +	 &mov($tmp2,	&Xv($pos2)) if $o == 2;
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp1,1));
        +	 &sub($tmp2,	&Np($c)) if $o <= 0;	# NEXT
        +	 &mov($tmp1,	&Np($d)) if $o == 1;
        +	 &mov($tmp1,	-1) if $o == 2;
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	}
        +
        +sub RIP4
        +	{
        +	local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_;
        +
        +	&comment($p++);
        +	if ($p & 1)
        +		{
        +#	 &mov($tmp2,	-1) if $o == -2;
        +#	&mov($tmp1,	$d) if $o == -2;
        +	 &sub($tmp2,	$d);
        +	&and($tmp1,	$b);
        +	 &and($tmp2,	$c);
        +	&or($tmp2,	$tmp1);
        +	 &mov($tmp1,	&Xv($pos));
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp2));
        +	 &mov($tmp2,	-1) unless $o > 0;	# NEXT
        +	 # XXX
        +	&add($a,	$tmp1);
        +	 &mov($tmp1,	&Np($d)) unless $o > 0; # NEXT
        +	 # XXX
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	else
        +		{
        +	 &sub($tmp2,	$d);
        +	&and($tmp1,	$b);
        +	 &and($tmp2,	$c);
        +	&or($tmp2,	$tmp1);
        +	 &mov($tmp1,	&Xv($pos));
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp2));
        +	 &mov($tmp2,	-1) if $o == 0;	# NEXT
        +	 &mov($tmp2,	-1) if $o == 1;
        +	 &mov($tmp2,	-1) if $o == 2;
        +	 # XXX
        +	&add($a,	$tmp1);
        +	 &mov($tmp1,	&Np($d)) if $o == 0;	# NEXT
        +	 &sub($tmp2,	&Np($d)) if $o == 1;
        +	 &sub($tmp2,	&Np($c)) if $o == 2;
        +	 # XXX
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	}
        +
        +sub RIP5
        +	{
        +	local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_;
        +
        +	&comment($p++);
        +	if ($p & 1)
        +		{
        +	 &mov($tmp2,	-1) if $o == -2;
        +	&sub($tmp2,	$d) if $o == -2;
        +	 &mov($tmp1,	&Xv($pos));
        +	&or($tmp2,	$c);
        +	 &add($a,	$tmp1);
        +	&xor($tmp2,	$b);
        +	 &mov($tmp1,	-1) if $o <= 0;
        +	 # XXX
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp2,1));
        +	 &sub($tmp1,	&Np($d)) if $o <= 0;
        +	 # XXX
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	else
        +		{
        +	 &mov($tmp2,	&Xv($pos));
        +	&or($tmp1,	$c);
        +	 &add($a,	$tmp2);
        +	&xor($tmp1,	$b);
        +	 &mov($tmp2,	-1) if $o <= 0;
        +	 &mov($tmp2,	&wparam(0)) if $o == 1;	# Middle code
        +	 &mov($tmp2,	-1) if $o == 2;
        +	&rotl($c,	10);
        +	&lea($a,	&DWP($K,$a,$tmp1,1));
        +	 &sub($tmp2,	&Np($d)) if $o <= 0;
        +	 &mov(&swtmp(16),	$A) if $o == 1;
        +	 &mov($tmp1,	&Np($d)) if $o == 2;
        +	&rotl($a,	$s);
        +	&add($a,	$e);
        +		}
        +	}
        +
        +sub ripemd160_block
        +	{
        +	local($name)=@_;
        +
        +	&function_begin_B($name,"",3);
        +
        +	# parameter 1 is the RIPEMD160_CTX structure.
        +	# A	0
        +	# B	4
        +	# C	8
        +	# D 	12
        +	# E 	16
        +
        +	&mov($tmp2,	&wparam(0));
        +	 &mov($tmp1,	&wparam(1));
        +	&push("esi");
        +	 &mov($A,	&DWP( 0,$tmp2,"",0));
        +	&push("edi");
        +	 &mov($B,	&DWP( 4,$tmp2,"",0));
        +	&push("ebp");
        +	 &mov($C,	&DWP( 8,$tmp2,"",0));
        +	&push("ebx");
        +	 &stack_push(16+5+6);
        +			  # Special comment about the figure of 6.
        +			  # Idea is to pad the current frame so
        +			  # that the top of the stack gets fairly
        +			  # aligned. Well, as you realize it would
        +			  # always depend on how the frame below is
        +			  # aligned. The good news are that gcc-2.95
        +			  # and later does keep first argument at
        +			  # least double-wise aligned.
        +			  #			<appro@fy.chalmers.se>
        +
        +	&set_label("start") unless $normal;
        +	&comment("");
        +
        +	# &mov($tmp1,	&wparam(1)); # Done at end of loop
        +	# &mov($tmp2,	&wparam(0)); # Done at end of loop
        +
        +	for ($z=0; $z<16; $z+=2)
        +		{
        +		&mov($D,		&DWP( $z*4,$tmp1,"",0));
        +		 &mov($E,		&DWP( ($z+1)*4,$tmp1,"",0));
        +		&mov(&swtmp($z),	$D);
        +		 &mov(&swtmp($z+1),	$E);
        +		}
        +	&mov($tmp1,	$C);
        +	 &mov($D,	&DWP(12,$tmp2,"",0));
        +	&mov($E,	&DWP(16,$tmp2,"",0));
        +
        +	&RIP1($A,$B,$C,$D,$E,$wl[ 0],$sl[ 0],-1);
        +	&RIP1($E,$A,$B,$C,$D,$wl[ 1],$sl[ 1],0);
        +	&RIP1($D,$E,$A,$B,$C,$wl[ 2],$sl[ 2],0);
        +	&RIP1($C,$D,$E,$A,$B,$wl[ 3],$sl[ 3],0);
        +	&RIP1($B,$C,$D,$E,$A,$wl[ 4],$sl[ 4],0);
        +	&RIP1($A,$B,$C,$D,$E,$wl[ 5],$sl[ 5],0);
        +	&RIP1($E,$A,$B,$C,$D,$wl[ 6],$sl[ 6],0);
        +	&RIP1($D,$E,$A,$B,$C,$wl[ 7],$sl[ 7],0);
        +	&RIP1($C,$D,$E,$A,$B,$wl[ 8],$sl[ 8],0);
        +	&RIP1($B,$C,$D,$E,$A,$wl[ 9],$sl[ 9],0);
        +	&RIP1($A,$B,$C,$D,$E,$wl[10],$sl[10],0);
        +	&RIP1($E,$A,$B,$C,$D,$wl[11],$sl[11],0);
        +	&RIP1($D,$E,$A,$B,$C,$wl[12],$sl[12],0);
        +	&RIP1($C,$D,$E,$A,$B,$wl[13],$sl[13],0);
        +	&RIP1($B,$C,$D,$E,$A,$wl[14],$sl[14],0);
        +	&RIP1($A,$B,$C,$D,$E,$wl[15],$sl[15],1,$wl[16]);
        +
        +	&RIP2($E,$A,$B,$C,$D,$wl[16],$wl[17],$sl[16],$KL1,-1);
        +	&RIP2($D,$E,$A,$B,$C,$wl[17],$wl[18],$sl[17],$KL1,0);
        +	&RIP2($C,$D,$E,$A,$B,$wl[18],$wl[19],$sl[18],$KL1,0);
        +	&RIP2($B,$C,$D,$E,$A,$wl[19],$wl[20],$sl[19],$KL1,0);
        +	&RIP2($A,$B,$C,$D,$E,$wl[20],$wl[21],$sl[20],$KL1,0);
        +	&RIP2($E,$A,$B,$C,$D,$wl[21],$wl[22],$sl[21],$KL1,0);
        +	&RIP2($D,$E,$A,$B,$C,$wl[22],$wl[23],$sl[22],$KL1,0);
        +	&RIP2($C,$D,$E,$A,$B,$wl[23],$wl[24],$sl[23],$KL1,0);
        +	&RIP2($B,$C,$D,$E,$A,$wl[24],$wl[25],$sl[24],$KL1,0);
        +	&RIP2($A,$B,$C,$D,$E,$wl[25],$wl[26],$sl[25],$KL1,0);
        +	&RIP2($E,$A,$B,$C,$D,$wl[26],$wl[27],$sl[26],$KL1,0);
        +	&RIP2($D,$E,$A,$B,$C,$wl[27],$wl[28],$sl[27],$KL1,0);
        +	&RIP2($C,$D,$E,$A,$B,$wl[28],$wl[29],$sl[28],$KL1,0);
        +	&RIP2($B,$C,$D,$E,$A,$wl[29],$wl[30],$sl[29],$KL1,0);
        +	&RIP2($A,$B,$C,$D,$E,$wl[30],$wl[31],$sl[30],$KL1,0);
        +	&RIP2($E,$A,$B,$C,$D,$wl[31],$wl[32],$sl[31],$KL1,1);
        +
        +	&RIP3($D,$E,$A,$B,$C,$wl[32],$sl[32],$KL2,-1);
        +	&RIP3($C,$D,$E,$A,$B,$wl[33],$sl[33],$KL2,0);
        +	&RIP3($B,$C,$D,$E,$A,$wl[34],$sl[34],$KL2,0);
        +	&RIP3($A,$B,$C,$D,$E,$wl[35],$sl[35],$KL2,0);
        +	&RIP3($E,$A,$B,$C,$D,$wl[36],$sl[36],$KL2,0);
        +	&RIP3($D,$E,$A,$B,$C,$wl[37],$sl[37],$KL2,0);
        +	&RIP3($C,$D,$E,$A,$B,$wl[38],$sl[38],$KL2,0);
        +	&RIP3($B,$C,$D,$E,$A,$wl[39],$sl[39],$KL2,0);
        +	&RIP3($A,$B,$C,$D,$E,$wl[40],$sl[40],$KL2,0);
        +	&RIP3($E,$A,$B,$C,$D,$wl[41],$sl[41],$KL2,0);
        +	&RIP3($D,$E,$A,$B,$C,$wl[42],$sl[42],$KL2,0);
        +	&RIP3($C,$D,$E,$A,$B,$wl[43],$sl[43],$KL2,0);
        +	&RIP3($B,$C,$D,$E,$A,$wl[44],$sl[44],$KL2,0);
        +	&RIP3($A,$B,$C,$D,$E,$wl[45],$sl[45],$KL2,0);
        +	&RIP3($E,$A,$B,$C,$D,$wl[46],$sl[46],$KL2,0);
        +	&RIP3($D,$E,$A,$B,$C,$wl[47],$sl[47],$KL2,1);
        +
        +	&RIP4($C,$D,$E,$A,$B,$wl[48],$sl[48],$KL3,-1);
        +	&RIP4($B,$C,$D,$E,$A,$wl[49],$sl[49],$KL3,0);
        +	&RIP4($A,$B,$C,$D,$E,$wl[50],$sl[50],$KL3,0);
        +	&RIP4($E,$A,$B,$C,$D,$wl[51],$sl[51],$KL3,0);
        +	&RIP4($D,$E,$A,$B,$C,$wl[52],$sl[52],$KL3,0);
        +	&RIP4($C,$D,$E,$A,$B,$wl[53],$sl[53],$KL3,0);
        +	&RIP4($B,$C,$D,$E,$A,$wl[54],$sl[54],$KL3,0);
        +	&RIP4($A,$B,$C,$D,$E,$wl[55],$sl[55],$KL3,0);
        +	&RIP4($E,$A,$B,$C,$D,$wl[56],$sl[56],$KL3,0);
        +	&RIP4($D,$E,$A,$B,$C,$wl[57],$sl[57],$KL3,0);
        +	&RIP4($C,$D,$E,$A,$B,$wl[58],$sl[58],$KL3,0);
        +	&RIP4($B,$C,$D,$E,$A,$wl[59],$sl[59],$KL3,0);
        +	&RIP4($A,$B,$C,$D,$E,$wl[60],$sl[60],$KL3,0);
        +	&RIP4($E,$A,$B,$C,$D,$wl[61],$sl[61],$KL3,0);
        +	&RIP4($D,$E,$A,$B,$C,$wl[62],$sl[62],$KL3,0);
        +	&RIP4($C,$D,$E,$A,$B,$wl[63],$sl[63],$KL3,1);
        +
        +	&RIP5($B,$C,$D,$E,$A,$wl[64],$sl[64],$KL4,-1);
        +	&RIP5($A,$B,$C,$D,$E,$wl[65],$sl[65],$KL4,0);
        +	&RIP5($E,$A,$B,$C,$D,$wl[66],$sl[66],$KL4,0);
        +	&RIP5($D,$E,$A,$B,$C,$wl[67],$sl[67],$KL4,0);
        +	&RIP5($C,$D,$E,$A,$B,$wl[68],$sl[68],$KL4,0);
        +	&RIP5($B,$C,$D,$E,$A,$wl[69],$sl[69],$KL4,0);
        +	&RIP5($A,$B,$C,$D,$E,$wl[70],$sl[70],$KL4,0);
        +	&RIP5($E,$A,$B,$C,$D,$wl[71],$sl[71],$KL4,0);
        +	&RIP5($D,$E,$A,$B,$C,$wl[72],$sl[72],$KL4,0);
        +	&RIP5($C,$D,$E,$A,$B,$wl[73],$sl[73],$KL4,0);
        +	&RIP5($B,$C,$D,$E,$A,$wl[74],$sl[74],$KL4,0);
        +	&RIP5($A,$B,$C,$D,$E,$wl[75],$sl[75],$KL4,0);
        +	&RIP5($E,$A,$B,$C,$D,$wl[76],$sl[76],$KL4,0);
        +	&RIP5($D,$E,$A,$B,$C,$wl[77],$sl[77],$KL4,0);
        +	&RIP5($C,$D,$E,$A,$B,$wl[78],$sl[78],$KL4,0);
        +	&RIP5($B,$C,$D,$E,$A,$wl[79],$sl[79],$KL4,1);
        +
        +	# &mov($tmp2,	&wparam(0)); # moved into last RIP5
        +	# &mov(&swtmp(16),	$A);
        +	 &mov($A,	&DWP( 0,$tmp2,"",0));
        +	&mov(&swtmp(16+1),	$B);
        +	 &mov(&swtmp(16+2),	$C);
        +	&mov($B,	&DWP( 4,$tmp2,"",0));
        +	 &mov(&swtmp(16+3),	$D);
        +	&mov($C,	&DWP( 8,$tmp2,"",0));
        +	 &mov(&swtmp(16+4),	$E);
        +	&mov($D,	&DWP(12,$tmp2,"",0));
        +	 &mov($E,	&DWP(16,$tmp2,"",0));
        +
        +	&RIP5($A,$B,$C,$D,$E,$wr[ 0],$sr[ 0],$KR0,-2);
        +	&RIP5($E,$A,$B,$C,$D,$wr[ 1],$sr[ 1],$KR0,0);
        +	&RIP5($D,$E,$A,$B,$C,$wr[ 2],$sr[ 2],$KR0,0);
        +	&RIP5($C,$D,$E,$A,$B,$wr[ 3],$sr[ 3],$KR0,0);
        +	&RIP5($B,$C,$D,$E,$A,$wr[ 4],$sr[ 4],$KR0,0);
        +	&RIP5($A,$B,$C,$D,$E,$wr[ 5],$sr[ 5],$KR0,0);
        +	&RIP5($E,$A,$B,$C,$D,$wr[ 6],$sr[ 6],$KR0,0);
        +	&RIP5($D,$E,$A,$B,$C,$wr[ 7],$sr[ 7],$KR0,0);
        +	&RIP5($C,$D,$E,$A,$B,$wr[ 8],$sr[ 8],$KR0,0);
        +	&RIP5($B,$C,$D,$E,$A,$wr[ 9],$sr[ 9],$KR0,0);
        +	&RIP5($A,$B,$C,$D,$E,$wr[10],$sr[10],$KR0,0);
        +	&RIP5($E,$A,$B,$C,$D,$wr[11],$sr[11],$KR0,0);
        +	&RIP5($D,$E,$A,$B,$C,$wr[12],$sr[12],$KR0,0);
        +	&RIP5($C,$D,$E,$A,$B,$wr[13],$sr[13],$KR0,0);
        +	&RIP5($B,$C,$D,$E,$A,$wr[14],$sr[14],$KR0,0);
        +	&RIP5($A,$B,$C,$D,$E,$wr[15],$sr[15],$KR0,2);
        +
        +	&RIP4($E,$A,$B,$C,$D,$wr[16],$sr[16],$KR1,-2);
        +	&RIP4($D,$E,$A,$B,$C,$wr[17],$sr[17],$KR1,0);
        +	&RIP4($C,$D,$E,$A,$B,$wr[18],$sr[18],$KR1,0);
        +	&RIP4($B,$C,$D,$E,$A,$wr[19],$sr[19],$KR1,0);
        +	&RIP4($A,$B,$C,$D,$E,$wr[20],$sr[20],$KR1,0);
        +	&RIP4($E,$A,$B,$C,$D,$wr[21],$sr[21],$KR1,0);
        +	&RIP4($D,$E,$A,$B,$C,$wr[22],$sr[22],$KR1,0);
        +	&RIP4($C,$D,$E,$A,$B,$wr[23],$sr[23],$KR1,0);
        +	&RIP4($B,$C,$D,$E,$A,$wr[24],$sr[24],$KR1,0);
        +	&RIP4($A,$B,$C,$D,$E,$wr[25],$sr[25],$KR1,0);
        +	&RIP4($E,$A,$B,$C,$D,$wr[26],$sr[26],$KR1,0);
        +	&RIP4($D,$E,$A,$B,$C,$wr[27],$sr[27],$KR1,0);
        +	&RIP4($C,$D,$E,$A,$B,$wr[28],$sr[28],$KR1,0);
        +	&RIP4($B,$C,$D,$E,$A,$wr[29],$sr[29],$KR1,0);
        +	&RIP4($A,$B,$C,$D,$E,$wr[30],$sr[30],$KR1,0);
        +	&RIP4($E,$A,$B,$C,$D,$wr[31],$sr[31],$KR1,2);
        +
        +	&RIP3($D,$E,$A,$B,$C,$wr[32],$sr[32],$KR2,-2);
        +	&RIP3($C,$D,$E,$A,$B,$wr[33],$sr[33],$KR2,0);
        +	&RIP3($B,$C,$D,$E,$A,$wr[34],$sr[34],$KR2,0);
        +	&RIP3($A,$B,$C,$D,$E,$wr[35],$sr[35],$KR2,0);
        +	&RIP3($E,$A,$B,$C,$D,$wr[36],$sr[36],$KR2,0);
        +	&RIP3($D,$E,$A,$B,$C,$wr[37],$sr[37],$KR2,0);
        +	&RIP3($C,$D,$E,$A,$B,$wr[38],$sr[38],$KR2,0);
        +	&RIP3($B,$C,$D,$E,$A,$wr[39],$sr[39],$KR2,0);
        +	&RIP3($A,$B,$C,$D,$E,$wr[40],$sr[40],$KR2,0);
        +	&RIP3($E,$A,$B,$C,$D,$wr[41],$sr[41],$KR2,0);
        +	&RIP3($D,$E,$A,$B,$C,$wr[42],$sr[42],$KR2,0);
        +	&RIP3($C,$D,$E,$A,$B,$wr[43],$sr[43],$KR2,0);
        +	&RIP3($B,$C,$D,$E,$A,$wr[44],$sr[44],$KR2,0);
        +	&RIP3($A,$B,$C,$D,$E,$wr[45],$sr[45],$KR2,0);
        +	&RIP3($E,$A,$B,$C,$D,$wr[46],$sr[46],$KR2,0);
        +	&RIP3($D,$E,$A,$B,$C,$wr[47],$sr[47],$KR2,2,$wr[48]);
        +
        +	&RIP2($C,$D,$E,$A,$B,$wr[48],$wr[49],$sr[48],$KR3,-2);
        +	&RIP2($B,$C,$D,$E,$A,$wr[49],$wr[50],$sr[49],$KR3,0);
        +	&RIP2($A,$B,$C,$D,$E,$wr[50],$wr[51],$sr[50],$KR3,0);
        +	&RIP2($E,$A,$B,$C,$D,$wr[51],$wr[52],$sr[51],$KR3,0);
        +	&RIP2($D,$E,$A,$B,$C,$wr[52],$wr[53],$sr[52],$KR3,0);
        +	&RIP2($C,$D,$E,$A,$B,$wr[53],$wr[54],$sr[53],$KR3,0);
        +	&RIP2($B,$C,$D,$E,$A,$wr[54],$wr[55],$sr[54],$KR3,0);
        +	&RIP2($A,$B,$C,$D,$E,$wr[55],$wr[56],$sr[55],$KR3,0);
        +	&RIP2($E,$A,$B,$C,$D,$wr[56],$wr[57],$sr[56],$KR3,0);
        +	&RIP2($D,$E,$A,$B,$C,$wr[57],$wr[58],$sr[57],$KR3,0);
        +	&RIP2($C,$D,$E,$A,$B,$wr[58],$wr[59],$sr[58],$KR3,0);
        +	&RIP2($B,$C,$D,$E,$A,$wr[59],$wr[60],$sr[59],$KR3,0);
        +	&RIP2($A,$B,$C,$D,$E,$wr[60],$wr[61],$sr[60],$KR3,0);
        +	&RIP2($E,$A,$B,$C,$D,$wr[61],$wr[62],$sr[61],$KR3,0);
        +	&RIP2($D,$E,$A,$B,$C,$wr[62],$wr[63],$sr[62],$KR3,0);
        +	&RIP2($C,$D,$E,$A,$B,$wr[63],$wr[64],$sr[63],$KR3,2);
        +
        +	&RIP1($B,$C,$D,$E,$A,$wr[64],$sr[64],-2);
        +	&RIP1($A,$B,$C,$D,$E,$wr[65],$sr[65],0);
        +	&RIP1($E,$A,$B,$C,$D,$wr[66],$sr[66],0);
        +	&RIP1($D,$E,$A,$B,$C,$wr[67],$sr[67],0);
        +	&RIP1($C,$D,$E,$A,$B,$wr[68],$sr[68],0);
        +	&RIP1($B,$C,$D,$E,$A,$wr[69],$sr[69],0);
        +	&RIP1($A,$B,$C,$D,$E,$wr[70],$sr[70],0);
        +	&RIP1($E,$A,$B,$C,$D,$wr[71],$sr[71],0);
        +	&RIP1($D,$E,$A,$B,$C,$wr[72],$sr[72],0);
        +	&RIP1($C,$D,$E,$A,$B,$wr[73],$sr[73],0);
        +	&RIP1($B,$C,$D,$E,$A,$wr[74],$sr[74],0);
        +	&RIP1($A,$B,$C,$D,$E,$wr[75],$sr[75],0);
        +	&RIP1($E,$A,$B,$C,$D,$wr[76],$sr[76],0);
        +	&RIP1($D,$E,$A,$B,$C,$wr[77],$sr[77],0);
        +	&RIP1($C,$D,$E,$A,$B,$wr[78],$sr[78],0);
        +	&RIP1($B,$C,$D,$E,$A,$wr[79],$sr[79],2);
        +
        +	# &mov($tmp2,	&wparam(0)); # Moved into last round
        +
        +	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));	# ctx->B
        + 	&add($D,	$tmp1);	
        +	 &mov($tmp1,	&swtmp(16+2));		# $c
        +	&add($D,	$tmp1);
        +
        +	 &mov($tmp1,	&DWP( 8,$tmp2,"",0));	# ctx->C
        +	&add($E,	$tmp1);	
        +	 &mov($tmp1,	&swtmp(16+3));		# $d
        +	&add($E,	$tmp1);
        +
        +	 &mov($tmp1,	&DWP(12,$tmp2,"",0));	# ctx->D
        +	&add($A,	$tmp1);	
        +	 &mov($tmp1,	&swtmp(16+4));		# $e
        +	&add($A,	$tmp1);
        +
        +
        +	 &mov($tmp1,	&DWP(16,$tmp2,"",0));	# ctx->E
        +	&add($B,	$tmp1);	
        +	 &mov($tmp1,	&swtmp(16+0));		# $a
        +	&add($B,	$tmp1);
        +
        +	 &mov($tmp1,	&DWP( 0,$tmp2,"",0));	# ctx->A
        +	&add($C,	$tmp1);	
        +	 &mov($tmp1,	&swtmp(16+1));		# $b
        +	&add($C,	$tmp1);
        +
        +	 &mov($tmp1,	&wparam(2));
        +
        +	&mov(&DWP( 0,$tmp2,"",0),	$D);
        +	 &mov(&DWP( 4,$tmp2,"",0),	$E);
        +	&mov(&DWP( 8,$tmp2,"",0),	$A);
        +	 &sub($tmp1,1);
        +	&mov(&DWP(12,$tmp2,"",0),	$B);
        +	 &mov(&DWP(16,$tmp2,"",0),	$C);
        +
        +	&jle(&label("get_out"));
        +
        +	&mov(&wparam(2),$tmp1);
        +	 &mov($C,	$A);
        +	&mov($tmp1,	&wparam(1));
        +	 &mov($A,	$D);
        +	&add($tmp1,	64);
        +	 &mov($B,	$E);
        +	&mov(&wparam(1),$tmp1);
        +
        +	&jmp(&label("start"));
        +
        +	&set_label("get_out");
        +
        +	&stack_pop(16+5+6);
        +
        +	&pop("ebx");
        +	&pop("ebp");
        +	&pop("edi");
        +	&pop("esi");
        +	&ret();
        +	&function_end_B($name);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ripemd/ripemd.h b/vendor/openssl/openssl/crypto/ripemd/ripemd.h
        new file mode 100644
        index 000000000..189bd8c90
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/ripemd.h
        @@ -0,0 +1,107 @@
        +/* crypto/ripemd/ripemd.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_RIPEMD_H
        +#define HEADER_RIPEMD_H
        +
        +#include <openssl/e_os2.h>
        +#include <stddef.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_NO_RIPEMD
        +#error RIPEMD is disabled.
        +#endif
        +
        +#if defined(__LP32__)
        +#define RIPEMD160_LONG unsigned long
        +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
        +#define RIPEMD160_LONG unsigned long
        +#define RIPEMD160_LONG_LOG2 3
        +#else
        +#define RIPEMD160_LONG unsigned int
        +#endif
        +
        +#define RIPEMD160_CBLOCK	64
        +#define RIPEMD160_LBLOCK	(RIPEMD160_CBLOCK/4)
        +#define RIPEMD160_DIGEST_LENGTH	20
        +
        +typedef struct RIPEMD160state_st
        +	{
        +	RIPEMD160_LONG A,B,C,D,E;
        +	RIPEMD160_LONG Nl,Nh;
        +	RIPEMD160_LONG data[RIPEMD160_LBLOCK];
        +	unsigned int   num;
        +	} RIPEMD160_CTX;
        +
        +#ifdef OPENSSL_FIPS
        +int private_RIPEMD160_Init(RIPEMD160_CTX *c);
        +#endif
        +int RIPEMD160_Init(RIPEMD160_CTX *c);
        +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
        +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
        +unsigned char *RIPEMD160(const unsigned char *d, size_t n,
        +	unsigned char *md);
        +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ripemd/rmd160.c b/vendor/openssl/openssl/crypto/ripemd/rmd160.c
        new file mode 100644
        index 000000000..b0ec57449
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/rmd160.c
        @@ -0,0 +1,127 @@
        +/* crypto/ripemd/rmd160.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/ripemd.h>
        +
        +#define BUFSIZE	1024*16
        +
        +void do_fp(FILE *f);
        +void pt(unsigned char *md);
        +#if !defined(_OSD_POSIX) && !defined(__DJGPP__)
        +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<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("RIPEMD160(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	RIPEMD160_CTX c;
        +	unsigned char md[RIPEMD160_DIGEST_LENGTH];
        +	int fd;
        +	int i;
        +	static unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	RIPEMD160_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,BUFSIZE);
        +		if (i <= 0) break;
        +		RIPEMD160_Update(&c,buf,(unsigned long)i);
        +		}
        +	RIPEMD160_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<RIPEMD160_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ripemd/rmd_dgst.c b/vendor/openssl/openssl/crypto/ripemd/rmd_dgst.c
        new file mode 100644
        index 000000000..d8e72da51
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/rmd_dgst.c
        @@ -0,0 +1,292 @@
        +/* crypto/ripemd/rmd_dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "rmd_locl.h"
        +#include <openssl/opensslv.h>
        +#include <openssl/crypto.h>
        +
        +const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
        +
        +#  ifdef RMD160_ASM
        +     void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p,size_t num);
        +#    define ripemd160_block ripemd160_block_x86
        +#  else
        +     void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
        +#  endif
        +
        +fips_md_init(RIPEMD160)
        +	{
        +	memset (c,0,sizeof(*c));
        +	c->A=RIPEMD160_A;
        +	c->B=RIPEMD160_B;
        +	c->C=RIPEMD160_C;
        +	c->D=RIPEMD160_D;
        +	c->E=RIPEMD160_E;
        +	return 1;
        +	}
        +
        +#ifndef ripemd160_block_data_order
        +#ifdef X
        +#undef X
        +#endif
        +void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
        +	{
        +	const unsigned char *data=p;
        +	register unsigned MD32_REG_T A,B,C,D,E;
        +	unsigned MD32_REG_T a,b,c,d,e,l;
        +#ifndef MD32_XARRAY
        +	/* See comment in crypto/sha/sha_locl.h for details. */
        +	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
        +				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
        +# define X(i)	XX##i
        +#else
        +	RIPEMD160_LONG	XX[16];
        +# define X(i)	XX[i]
        +#endif
        +
        +	for (;num--;)
        +		{
        +
        +	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
        +
        +	(void)HOST_c2l(data,l); X( 0)=l;(void)HOST_c2l(data,l); X( 1)=l;
        +	RIP1(A,B,C,D,E,WL00,SL00);	(void)HOST_c2l(data,l); X( 2)=l;
        +	RIP1(E,A,B,C,D,WL01,SL01);	(void)HOST_c2l(data,l); X( 3)=l;
        +	RIP1(D,E,A,B,C,WL02,SL02);	(void)HOST_c2l(data,l); X( 4)=l;
        +	RIP1(C,D,E,A,B,WL03,SL03);	(void)HOST_c2l(data,l); X( 5)=l;
        +	RIP1(B,C,D,E,A,WL04,SL04);	(void)HOST_c2l(data,l); X( 6)=l;
        +	RIP1(A,B,C,D,E,WL05,SL05);	(void)HOST_c2l(data,l); X( 7)=l;
        +	RIP1(E,A,B,C,D,WL06,SL06);	(void)HOST_c2l(data,l); X( 8)=l;
        +	RIP1(D,E,A,B,C,WL07,SL07);	(void)HOST_c2l(data,l); X( 9)=l;
        +	RIP1(C,D,E,A,B,WL08,SL08);	(void)HOST_c2l(data,l); X(10)=l;
        +	RIP1(B,C,D,E,A,WL09,SL09);	(void)HOST_c2l(data,l); X(11)=l;
        +	RIP1(A,B,C,D,E,WL10,SL10);	(void)HOST_c2l(data,l); X(12)=l;
        +	RIP1(E,A,B,C,D,WL11,SL11);	(void)HOST_c2l(data,l); X(13)=l;
        +	RIP1(D,E,A,B,C,WL12,SL12);	(void)HOST_c2l(data,l); X(14)=l;
        +	RIP1(C,D,E,A,B,WL13,SL13);	(void)HOST_c2l(data,l); X(15)=l;
        +	RIP1(B,C,D,E,A,WL14,SL14);
        +	RIP1(A,B,C,D,E,WL15,SL15);
        +
        +	RIP2(E,A,B,C,D,WL16,SL16,KL1);
        +	RIP2(D,E,A,B,C,WL17,SL17,KL1);
        +	RIP2(C,D,E,A,B,WL18,SL18,KL1);
        +	RIP2(B,C,D,E,A,WL19,SL19,KL1);
        +	RIP2(A,B,C,D,E,WL20,SL20,KL1);
        +	RIP2(E,A,B,C,D,WL21,SL21,KL1);
        +	RIP2(D,E,A,B,C,WL22,SL22,KL1);
        +	RIP2(C,D,E,A,B,WL23,SL23,KL1);
        +	RIP2(B,C,D,E,A,WL24,SL24,KL1);
        +	RIP2(A,B,C,D,E,WL25,SL25,KL1);
        +	RIP2(E,A,B,C,D,WL26,SL26,KL1);
        +	RIP2(D,E,A,B,C,WL27,SL27,KL1);
        +	RIP2(C,D,E,A,B,WL28,SL28,KL1);
        +	RIP2(B,C,D,E,A,WL29,SL29,KL1);
        +	RIP2(A,B,C,D,E,WL30,SL30,KL1);
        +	RIP2(E,A,B,C,D,WL31,SL31,KL1);
        +
        +	RIP3(D,E,A,B,C,WL32,SL32,KL2);
        +	RIP3(C,D,E,A,B,WL33,SL33,KL2);
        +	RIP3(B,C,D,E,A,WL34,SL34,KL2);
        +	RIP3(A,B,C,D,E,WL35,SL35,KL2);
        +	RIP3(E,A,B,C,D,WL36,SL36,KL2);
        +	RIP3(D,E,A,B,C,WL37,SL37,KL2);
        +	RIP3(C,D,E,A,B,WL38,SL38,KL2);
        +	RIP3(B,C,D,E,A,WL39,SL39,KL2);
        +	RIP3(A,B,C,D,E,WL40,SL40,KL2);
        +	RIP3(E,A,B,C,D,WL41,SL41,KL2);
        +	RIP3(D,E,A,B,C,WL42,SL42,KL2);
        +	RIP3(C,D,E,A,B,WL43,SL43,KL2);
        +	RIP3(B,C,D,E,A,WL44,SL44,KL2);
        +	RIP3(A,B,C,D,E,WL45,SL45,KL2);
        +	RIP3(E,A,B,C,D,WL46,SL46,KL2);
        +	RIP3(D,E,A,B,C,WL47,SL47,KL2);
        +
        +	RIP4(C,D,E,A,B,WL48,SL48,KL3);
        +	RIP4(B,C,D,E,A,WL49,SL49,KL3);
        +	RIP4(A,B,C,D,E,WL50,SL50,KL3);
        +	RIP4(E,A,B,C,D,WL51,SL51,KL3);
        +	RIP4(D,E,A,B,C,WL52,SL52,KL3);
        +	RIP4(C,D,E,A,B,WL53,SL53,KL3);
        +	RIP4(B,C,D,E,A,WL54,SL54,KL3);
        +	RIP4(A,B,C,D,E,WL55,SL55,KL3);
        +	RIP4(E,A,B,C,D,WL56,SL56,KL3);
        +	RIP4(D,E,A,B,C,WL57,SL57,KL3);
        +	RIP4(C,D,E,A,B,WL58,SL58,KL3);
        +	RIP4(B,C,D,E,A,WL59,SL59,KL3);
        +	RIP4(A,B,C,D,E,WL60,SL60,KL3);
        +	RIP4(E,A,B,C,D,WL61,SL61,KL3);
        +	RIP4(D,E,A,B,C,WL62,SL62,KL3);
        +	RIP4(C,D,E,A,B,WL63,SL63,KL3);
        +
        +	RIP5(B,C,D,E,A,WL64,SL64,KL4);
        +	RIP5(A,B,C,D,E,WL65,SL65,KL4);
        +	RIP5(E,A,B,C,D,WL66,SL66,KL4);
        +	RIP5(D,E,A,B,C,WL67,SL67,KL4);
        +	RIP5(C,D,E,A,B,WL68,SL68,KL4);
        +	RIP5(B,C,D,E,A,WL69,SL69,KL4);
        +	RIP5(A,B,C,D,E,WL70,SL70,KL4);
        +	RIP5(E,A,B,C,D,WL71,SL71,KL4);
        +	RIP5(D,E,A,B,C,WL72,SL72,KL4);
        +	RIP5(C,D,E,A,B,WL73,SL73,KL4);
        +	RIP5(B,C,D,E,A,WL74,SL74,KL4);
        +	RIP5(A,B,C,D,E,WL75,SL75,KL4);
        +	RIP5(E,A,B,C,D,WL76,SL76,KL4);
        +	RIP5(D,E,A,B,C,WL77,SL77,KL4);
        +	RIP5(C,D,E,A,B,WL78,SL78,KL4);
        +	RIP5(B,C,D,E,A,WL79,SL79,KL4);
        +
        +	a=A; b=B; c=C; d=D; e=E;
        +	/* Do other half */
        +	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
        +
        +	RIP5(A,B,C,D,E,WR00,SR00,KR0);
        +	RIP5(E,A,B,C,D,WR01,SR01,KR0);
        +	RIP5(D,E,A,B,C,WR02,SR02,KR0);
        +	RIP5(C,D,E,A,B,WR03,SR03,KR0);
        +	RIP5(B,C,D,E,A,WR04,SR04,KR0);
        +	RIP5(A,B,C,D,E,WR05,SR05,KR0);
        +	RIP5(E,A,B,C,D,WR06,SR06,KR0);
        +	RIP5(D,E,A,B,C,WR07,SR07,KR0);
        +	RIP5(C,D,E,A,B,WR08,SR08,KR0);
        +	RIP5(B,C,D,E,A,WR09,SR09,KR0);
        +	RIP5(A,B,C,D,E,WR10,SR10,KR0);
        +	RIP5(E,A,B,C,D,WR11,SR11,KR0);
        +	RIP5(D,E,A,B,C,WR12,SR12,KR0);
        +	RIP5(C,D,E,A,B,WR13,SR13,KR0);
        +	RIP5(B,C,D,E,A,WR14,SR14,KR0);
        +	RIP5(A,B,C,D,E,WR15,SR15,KR0);
        +
        +	RIP4(E,A,B,C,D,WR16,SR16,KR1);
        +	RIP4(D,E,A,B,C,WR17,SR17,KR1);
        +	RIP4(C,D,E,A,B,WR18,SR18,KR1);
        +	RIP4(B,C,D,E,A,WR19,SR19,KR1);
        +	RIP4(A,B,C,D,E,WR20,SR20,KR1);
        +	RIP4(E,A,B,C,D,WR21,SR21,KR1);
        +	RIP4(D,E,A,B,C,WR22,SR22,KR1);
        +	RIP4(C,D,E,A,B,WR23,SR23,KR1);
        +	RIP4(B,C,D,E,A,WR24,SR24,KR1);
        +	RIP4(A,B,C,D,E,WR25,SR25,KR1);
        +	RIP4(E,A,B,C,D,WR26,SR26,KR1);
        +	RIP4(D,E,A,B,C,WR27,SR27,KR1);
        +	RIP4(C,D,E,A,B,WR28,SR28,KR1);
        +	RIP4(B,C,D,E,A,WR29,SR29,KR1);
        +	RIP4(A,B,C,D,E,WR30,SR30,KR1);
        +	RIP4(E,A,B,C,D,WR31,SR31,KR1);
        +
        +	RIP3(D,E,A,B,C,WR32,SR32,KR2);
        +	RIP3(C,D,E,A,B,WR33,SR33,KR2);
        +	RIP3(B,C,D,E,A,WR34,SR34,KR2);
        +	RIP3(A,B,C,D,E,WR35,SR35,KR2);
        +	RIP3(E,A,B,C,D,WR36,SR36,KR2);
        +	RIP3(D,E,A,B,C,WR37,SR37,KR2);
        +	RIP3(C,D,E,A,B,WR38,SR38,KR2);
        +	RIP3(B,C,D,E,A,WR39,SR39,KR2);
        +	RIP3(A,B,C,D,E,WR40,SR40,KR2);
        +	RIP3(E,A,B,C,D,WR41,SR41,KR2);
        +	RIP3(D,E,A,B,C,WR42,SR42,KR2);
        +	RIP3(C,D,E,A,B,WR43,SR43,KR2);
        +	RIP3(B,C,D,E,A,WR44,SR44,KR2);
        +	RIP3(A,B,C,D,E,WR45,SR45,KR2);
        +	RIP3(E,A,B,C,D,WR46,SR46,KR2);
        +	RIP3(D,E,A,B,C,WR47,SR47,KR2);
        +
        +	RIP2(C,D,E,A,B,WR48,SR48,KR3);
        +	RIP2(B,C,D,E,A,WR49,SR49,KR3);
        +	RIP2(A,B,C,D,E,WR50,SR50,KR3);
        +	RIP2(E,A,B,C,D,WR51,SR51,KR3);
        +	RIP2(D,E,A,B,C,WR52,SR52,KR3);
        +	RIP2(C,D,E,A,B,WR53,SR53,KR3);
        +	RIP2(B,C,D,E,A,WR54,SR54,KR3);
        +	RIP2(A,B,C,D,E,WR55,SR55,KR3);
        +	RIP2(E,A,B,C,D,WR56,SR56,KR3);
        +	RIP2(D,E,A,B,C,WR57,SR57,KR3);
        +	RIP2(C,D,E,A,B,WR58,SR58,KR3);
        +	RIP2(B,C,D,E,A,WR59,SR59,KR3);
        +	RIP2(A,B,C,D,E,WR60,SR60,KR3);
        +	RIP2(E,A,B,C,D,WR61,SR61,KR3);
        +	RIP2(D,E,A,B,C,WR62,SR62,KR3);
        +	RIP2(C,D,E,A,B,WR63,SR63,KR3);
        +
        +	RIP1(B,C,D,E,A,WR64,SR64);
        +	RIP1(A,B,C,D,E,WR65,SR65);
        +	RIP1(E,A,B,C,D,WR66,SR66);
        +	RIP1(D,E,A,B,C,WR67,SR67);
        +	RIP1(C,D,E,A,B,WR68,SR68);
        +	RIP1(B,C,D,E,A,WR69,SR69);
        +	RIP1(A,B,C,D,E,WR70,SR70);
        +	RIP1(E,A,B,C,D,WR71,SR71);
        +	RIP1(D,E,A,B,C,WR72,SR72);
        +	RIP1(C,D,E,A,B,WR73,SR73);
        +	RIP1(B,C,D,E,A,WR74,SR74);
        +	RIP1(A,B,C,D,E,WR75,SR75);
        +	RIP1(E,A,B,C,D,WR76,SR76);
        +	RIP1(D,E,A,B,C,WR77,SR77);
        +	RIP1(C,D,E,A,B,WR78,SR78);
        +	RIP1(B,C,D,E,A,WR79,SR79);
        +
        +	D     =ctx->B+c+D;
        +	ctx->B=ctx->C+d+E;
        +	ctx->C=ctx->D+e+A;
        +	ctx->D=ctx->E+a+B;
        +	ctx->E=ctx->A+b+C;
        +	ctx->A=D;
        +
        +		}
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ripemd/rmd_locl.h b/vendor/openssl/openssl/crypto/ripemd/rmd_locl.h
        new file mode 100644
        index 000000000..2bd8957d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/rmd_locl.h
        @@ -0,0 +1,150 @@
        +/* crypto/ripemd/rmd_locl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/opensslconf.h>
        +#include <openssl/ripemd.h>
        +
        +#ifndef RIPEMD160_LONG_LOG2
        +#define RIPEMD160_LONG_LOG2 2 /* default to 32 bits */
        +#endif
        +
        +/*
        + * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c
        + * FOR EXPLANATIONS ON FOLLOWING "CODE."
        + *					<appro@fy.chalmers.se>
        + */
        +#ifdef RMD160_ASM
        +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
        +#  define ripemd160_block_data_order ripemd160_block_asm_data_order
        +# endif
        +#endif
        +
        +void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
        +
        +#define DATA_ORDER_IS_LITTLE_ENDIAN
        +
        +#define HASH_LONG               RIPEMD160_LONG
        +#define HASH_CTX                RIPEMD160_CTX
        +#define HASH_CBLOCK             RIPEMD160_CBLOCK
        +#define HASH_UPDATE             RIPEMD160_Update
        +#define HASH_TRANSFORM          RIPEMD160_Transform
        +#define HASH_FINAL              RIPEMD160_Final
        +#define	HASH_MAKE_STRING(c,s)	do {	\
        +	unsigned long ll;		\
        +	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->E; (void)HOST_l2c(ll,(s));	\
        +	} while (0)
        +#define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
        +
        +#include "md32_common.h"
        +
        +#if 0
        +#define F1(x,y,z)	 ((x)^(y)^(z))
        +#define F2(x,y,z)	(((x)&(y))|((~x)&z))
        +#define F3(x,y,z)	(((x)|(~y))^(z))
        +#define F4(x,y,z)	(((x)&(z))|((y)&(~(z))))
        +#define F5(x,y,z)	 ((x)^((y)|(~(z))))
        +#else
        +/*
        + * Transformed F2 and F4 are courtesy of Wei Dai <weidai@eskimo.com>
        + */
        +#define F1(x,y,z)	((x) ^ (y) ^ (z))
        +#define F2(x,y,z)	((((y) ^ (z)) & (x)) ^ (z))
        +#define F3(x,y,z)	(((~(y)) | (x)) ^ (z))
        +#define F4(x,y,z)	((((x) ^ (y)) & (z)) ^ (y))
        +#define F5(x,y,z)	(((~(z)) | (y)) ^ (x))
        +#endif
        +
        +#define RIPEMD160_A	0x67452301L
        +#define RIPEMD160_B	0xEFCDAB89L
        +#define RIPEMD160_C	0x98BADCFEL
        +#define RIPEMD160_D	0x10325476L
        +#define RIPEMD160_E	0xC3D2E1F0L
        +
        +#include "rmdconst.h"
        +
        +#define RIP1(a,b,c,d,e,w,s) { \
        +	a+=F1(b,c,d)+X(w); \
        +        a=ROTATE(a,s)+e; \
        +        c=ROTATE(c,10); }
        +
        +#define RIP2(a,b,c,d,e,w,s,K) { \
        +	a+=F2(b,c,d)+X(w)+K; \
        +        a=ROTATE(a,s)+e; \
        +        c=ROTATE(c,10); }
        +
        +#define RIP3(a,b,c,d,e,w,s,K) { \
        +	a+=F3(b,c,d)+X(w)+K; \
        +        a=ROTATE(a,s)+e; \
        +        c=ROTATE(c,10); }
        +
        +#define RIP4(a,b,c,d,e,w,s,K) { \
        +	a+=F4(b,c,d)+X(w)+K; \
        +        a=ROTATE(a,s)+e; \
        +        c=ROTATE(c,10); }
        +
        +#define RIP5(a,b,c,d,e,w,s,K) { \
        +	a+=F5(b,c,d)+X(w)+K; \
        +        a=ROTATE(a,s)+e; \
        +        c=ROTATE(c,10); }
        +
        diff --git a/vendor/openssl/openssl/crypto/ripemd/rmd_one.c b/vendor/openssl/openssl/crypto/ripemd/rmd_one.c
        new file mode 100644
        index 000000000..3efb13758
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/rmd_one.c
        @@ -0,0 +1,78 @@
        +/* crypto/ripemd/rmd_one.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/ripemd.h>
        +#include <openssl/crypto.h>
        +
        +unsigned char *RIPEMD160(const unsigned char *d, size_t n,
        +	     unsigned char *md)
        +	{
        +	RIPEMD160_CTX c;
        +	static unsigned char m[RIPEMD160_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!RIPEMD160_Init(&c))
        +		return NULL;
        +	RIPEMD160_Update(&c,d,n);
        +	RIPEMD160_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
        +	return(md);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/ripemd/rmdconst.h b/vendor/openssl/openssl/crypto/ripemd/rmdconst.h
        new file mode 100644
        index 000000000..59c48dead
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/rmdconst.h
        @@ -0,0 +1,399 @@
        +/* crypto/ripemd/rmdconst.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.]
        + */
        +#define KL0 0x00000000L
        +#define KL1 0x5A827999L
        +#define KL2 0x6ED9EBA1L
        +#define KL3 0x8F1BBCDCL
        +#define KL4 0xA953FD4EL
        +
        +#define KR0 0x50A28BE6L
        +#define KR1 0x5C4DD124L
        +#define KR2 0x6D703EF3L
        +#define KR3 0x7A6D76E9L
        +#define KR4 0x00000000L
        +
        +#define WL00  0
        +#define SL00 11
        +#define WL01  1
        +#define SL01 14
        +#define WL02  2
        +#define SL02 15
        +#define WL03  3
        +#define SL03 12
        +#define WL04  4
        +#define SL04  5
        +#define WL05  5
        +#define SL05  8
        +#define WL06  6
        +#define SL06  7
        +#define WL07  7
        +#define SL07  9
        +#define WL08  8
        +#define SL08 11
        +#define WL09  9
        +#define SL09 13
        +#define WL10 10
        +#define SL10 14
        +#define WL11 11
        +#define SL11 15
        +#define WL12 12
        +#define SL12  6
        +#define WL13 13
        +#define SL13  7
        +#define WL14 14
        +#define SL14  9
        +#define WL15 15
        +#define SL15  8
        +
        +#define WL16  7
        +#define SL16  7
        +#define WL17  4
        +#define SL17  6
        +#define WL18 13
        +#define SL18  8
        +#define WL19  1
        +#define SL19 13
        +#define WL20 10
        +#define SL20 11
        +#define WL21  6
        +#define SL21  9
        +#define WL22 15
        +#define SL22  7
        +#define WL23  3
        +#define SL23 15
        +#define WL24 12
        +#define SL24  7
        +#define WL25  0
        +#define SL25 12
        +#define WL26  9
        +#define SL26 15
        +#define WL27  5
        +#define SL27  9
        +#define WL28  2
        +#define SL28 11
        +#define WL29 14
        +#define SL29  7
        +#define WL30 11
        +#define SL30 13
        +#define WL31  8
        +#define SL31 12
        +
        +#define WL32  3
        +#define SL32 11
        +#define WL33 10
        +#define SL33 13
        +#define WL34 14
        +#define SL34  6
        +#define WL35  4
        +#define SL35  7
        +#define WL36  9
        +#define SL36 14
        +#define WL37 15
        +#define SL37  9
        +#define WL38  8
        +#define SL38 13
        +#define WL39  1
        +#define SL39 15
        +#define WL40  2
        +#define SL40 14
        +#define WL41  7
        +#define SL41  8
        +#define WL42  0
        +#define SL42 13
        +#define WL43  6
        +#define SL43  6
        +#define WL44 13
        +#define SL44  5
        +#define WL45 11
        +#define SL45 12
        +#define WL46  5
        +#define SL46  7
        +#define WL47 12
        +#define SL47  5
        +
        +#define WL48  1
        +#define SL48 11
        +#define WL49  9
        +#define SL49 12
        +#define WL50 11
        +#define SL50 14
        +#define WL51 10
        +#define SL51 15
        +#define WL52  0
        +#define SL52 14
        +#define WL53  8
        +#define SL53 15
        +#define WL54 12
        +#define SL54  9
        +#define WL55  4
        +#define SL55  8
        +#define WL56 13
        +#define SL56  9
        +#define WL57  3
        +#define SL57 14
        +#define WL58  7
        +#define SL58  5
        +#define WL59 15
        +#define SL59  6
        +#define WL60 14
        +#define SL60  8
        +#define WL61  5
        +#define SL61  6
        +#define WL62  6
        +#define SL62  5
        +#define WL63  2
        +#define SL63 12
        +
        +#define WL64  4
        +#define SL64  9
        +#define WL65  0
        +#define SL65 15
        +#define WL66  5
        +#define SL66  5
        +#define WL67  9
        +#define SL67 11
        +#define WL68  7
        +#define SL68  6
        +#define WL69 12
        +#define SL69  8
        +#define WL70  2
        +#define SL70 13
        +#define WL71 10
        +#define SL71 12
        +#define WL72 14
        +#define SL72  5
        +#define WL73  1
        +#define SL73 12
        +#define WL74  3
        +#define SL74 13
        +#define WL75  8
        +#define SL75 14
        +#define WL76 11
        +#define SL76 11
        +#define WL77  6
        +#define SL77  8
        +#define WL78 15
        +#define SL78  5
        +#define WL79 13
        +#define SL79  6
        +
        +#define WR00  5
        +#define SR00  8
        +#define WR01 14
        +#define SR01  9
        +#define WR02  7
        +#define SR02  9
        +#define WR03  0
        +#define SR03 11
        +#define WR04  9
        +#define SR04 13
        +#define WR05  2
        +#define SR05 15
        +#define WR06 11
        +#define SR06 15
        +#define WR07  4
        +#define SR07  5
        +#define WR08 13
        +#define SR08  7
        +#define WR09  6
        +#define SR09  7
        +#define WR10 15
        +#define SR10  8
        +#define WR11  8
        +#define SR11 11
        +#define WR12  1
        +#define SR12 14
        +#define WR13 10
        +#define SR13 14
        +#define WR14  3
        +#define SR14 12
        +#define WR15 12
        +#define SR15  6
        +
        +#define WR16  6
        +#define SR16  9
        +#define WR17 11
        +#define SR17 13
        +#define WR18  3
        +#define SR18 15
        +#define WR19  7
        +#define SR19  7
        +#define WR20  0
        +#define SR20 12
        +#define WR21 13
        +#define SR21  8
        +#define WR22  5
        +#define SR22  9
        +#define WR23 10
        +#define SR23 11
        +#define WR24 14
        +#define SR24  7
        +#define WR25 15
        +#define SR25  7
        +#define WR26  8
        +#define SR26 12
        +#define WR27 12
        +#define SR27  7
        +#define WR28  4
        +#define SR28  6
        +#define WR29  9
        +#define SR29 15
        +#define WR30  1
        +#define SR30 13
        +#define WR31  2
        +#define SR31 11
        +
        +#define WR32 15
        +#define SR32  9
        +#define WR33  5
        +#define SR33  7
        +#define WR34  1
        +#define SR34 15
        +#define WR35  3
        +#define SR35 11
        +#define WR36  7
        +#define SR36  8
        +#define WR37 14
        +#define SR37  6
        +#define WR38  6
        +#define SR38  6
        +#define WR39  9
        +#define SR39 14
        +#define WR40 11
        +#define SR40 12
        +#define WR41  8
        +#define SR41 13
        +#define WR42 12
        +#define SR42  5
        +#define WR43  2
        +#define SR43 14
        +#define WR44 10
        +#define SR44 13
        +#define WR45  0
        +#define SR45 13
        +#define WR46  4
        +#define SR46  7
        +#define WR47 13
        +#define SR47  5
        +
        +#define WR48  8
        +#define SR48 15
        +#define WR49  6
        +#define SR49  5
        +#define WR50  4
        +#define SR50  8
        +#define WR51  1
        +#define SR51 11
        +#define WR52  3
        +#define SR52 14
        +#define WR53 11
        +#define SR53 14
        +#define WR54 15
        +#define SR54  6
        +#define WR55  0
        +#define SR55 14
        +#define WR56  5
        +#define SR56  6
        +#define WR57 12
        +#define SR57  9
        +#define WR58  2
        +#define SR58 12
        +#define WR59 13
        +#define SR59  9
        +#define WR60  9
        +#define SR60 12
        +#define WR61  7
        +#define SR61  5
        +#define WR62 10
        +#define SR62 15
        +#define WR63 14
        +#define SR63  8
        +
        +#define WR64 12
        +#define SR64  8
        +#define WR65 15
        +#define SR65  5
        +#define WR66 10
        +#define SR66 12
        +#define WR67  4
        +#define SR67  9
        +#define WR68  1
        +#define SR68 12
        +#define WR69  5
        +#define SR69  5
        +#define WR70  8
        +#define SR70 14
        +#define WR71  7
        +#define SR71  6
        +#define WR72  6
        +#define SR72  8
        +#define WR73  2
        +#define SR73 13
        +#define WR74 13
        +#define SR74  6
        +#define WR75 14
        +#define SR75  5
        +#define WR76  0
        +#define SR76 15
        +#define WR77  3
        +#define SR77 13
        +#define WR78  9
        +#define SR78 11
        +#define WR79 11
        +#define SR79 11
        +
        diff --git a/vendor/openssl/openssl/crypto/ripemd/rmdtest.c b/vendor/openssl/openssl/crypto/ripemd/rmdtest.c
        new file mode 100644
        index 000000000..fb34e0e83
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ripemd/rmdtest.c
        @@ -0,0 +1,145 @@
        +/* crypto/ripemd/rmdtest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RIPEMD
        +int main(int argc, char *argv[])
        +{
        +    printf("No ripemd support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/ripemd.h>
        +#include <openssl/evp.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static char *test[]={
        +	"",
        +	"a",
        +	"abc",
        +	"message digest",
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
        +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        +	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
        +	NULL,
        +	};
        +
        +static char *ret[]={
        +	"9c1185a5c5e9fc54612808977ee8f548b2258d31",
        +	"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe",
        +	"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
        +	"5d0689ef49d2fae572b881b123a85ffa21595f36",
        +	"f71c27109c692c1b56bbdceb5b9d2865b3708dbc",
        +	"12a053384a9c0c88e405a06c27dcf49ada62eb2b",
        +	"b0e20b6e3116640286ed3a87a5713079b21f5189",
        +	"9b752e45573d4b39f4dbd3323cab82bf63326bfb",
        +	};
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[RIPEMD160_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +#ifdef CHARSET_EBCDIC
        +		ebcdic2ascii((char *)*P, (char *)*P, strlen((char *)*P));
        +#endif
        +		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_ripemd160(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,(char *)*R) != 0)
        +			{
        +			printf("error calculating RIPEMD160 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<RIPEMD160_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/Makefile b/vendor/openssl/openssl/crypto/rsa/Makefile
        new file mode 100644
        index 000000000..f798d2f74
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/Makefile
        @@ -0,0 +1,308 @@
        +#
        +# OpenSSL/crypto/rsa/Makefile
        +#
        +
        +DIR=	rsa
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=rsa_test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
        +	rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
        +	rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
        +	rsa_pmeth.c rsa_crpt.c
        +LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
        +	rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
        +	rsa_pss.o rsa_x931.o rsa_asn1.o rsa_depr.o rsa_ameth.o rsa_prn.o \
        +	rsa_pmeth.o rsa_crpt.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= rsa.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +rsa_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_ameth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +rsa_ameth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +rsa_ameth.o: ../../include/openssl/cms.h ../../include/openssl/crypto.h
        +rsa_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +rsa_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +rsa_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rsa_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rsa_ameth.o: ../../include/openssl/objects.h
        +rsa_ameth.o: ../../include/openssl/opensslconf.h
        +rsa_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +rsa_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_ameth.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_ameth.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rsa_ameth.o: ../asn1/asn1_locl.h ../cryptlib.h rsa_ameth.c
        +rsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +rsa_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +rsa_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rsa_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +rsa_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +rsa_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +rsa_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +rsa_asn1.o: ../../include/openssl/opensslconf.h
        +rsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +rsa_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_asn1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rsa_asn1.o: ../cryptlib.h rsa_asn1.c
        +rsa_chk.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +rsa_chk.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
        +rsa_chk.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_chk.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_chk.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +rsa_chk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_chk.o: rsa_chk.c
        +rsa_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_crpt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_crpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_crpt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +rsa_crpt.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +rsa_crpt.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +rsa_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +rsa_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +rsa_crpt.o: ../../include/openssl/opensslconf.h
        +rsa_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_crpt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +rsa_crpt.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +rsa_crpt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +rsa_crpt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +rsa_crpt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h rsa_crpt.c
        +rsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_depr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +rsa_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_depr.o: ../cryptlib.h rsa_depr.c
        +rsa_eay.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_eay.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_eay.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_eay.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_eay.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_eay.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_eay.c
        +rsa_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +rsa_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
        +rsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
        +rsa_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_err.o: ../../include/openssl/symhacks.h rsa_err.c
        +rsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +rsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_gen.o: ../cryptlib.h rsa_gen.c
        +rsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +rsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +rsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +rsa_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +rsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +rsa_lib.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rsa_lib.o: ../cryptlib.h rsa_lib.c
        +rsa_none.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_none.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_none.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_none.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_none.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_none.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_none.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_none.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_none.c
        +rsa_null.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_null.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_null.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_null.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_null.c
        +rsa_oaep.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_oaep.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_oaep.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_oaep.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +rsa_oaep.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +rsa_oaep.o: ../../include/openssl/opensslconf.h
        +rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_oaep.o: ../cryptlib.h rsa_oaep.c
        +rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_pk1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
        +rsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +rsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +rsa_pmeth.o: ../../include/openssl/cms.h ../../include/openssl/crypto.h
        +rsa_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +rsa_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +rsa_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rsa_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rsa_pmeth.o: ../../include/openssl/objects.h
        +rsa_pmeth.o: ../../include/openssl/opensslconf.h
        +rsa_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +rsa_pmeth.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_pmeth.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_pmeth.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rsa_pmeth.o: ../cryptlib.h ../evp/evp_locl.h rsa_locl.h rsa_pmeth.c
        +rsa_prn.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_prn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +rsa_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +rsa_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rsa_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rsa_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rsa_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_prn.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +rsa_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_prn.o: ../cryptlib.h rsa_prn.c
        +rsa_pss.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_pss.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_pss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_pss.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_pss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +rsa_pss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +rsa_pss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +rsa_pss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +rsa_pss.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +rsa_pss.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +rsa_pss.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pss.c
        +rsa_saos.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_saos.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_saos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_saos.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +rsa_saos.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +rsa_saos.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rsa_saos.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rsa_saos.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rsa_saos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_saos.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +rsa_saos.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_saos.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_saos.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rsa_saos.o: ../cryptlib.h rsa_saos.c
        +rsa_sign.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +rsa_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +rsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rsa_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +rsa_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +rsa_sign.o: ../cryptlib.h rsa_locl.h rsa_sign.c
        +rsa_ssl.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_ssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_ssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_ssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_ssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +rsa_ssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_ssl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_ssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_ssl.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_ssl.c
        +rsa_x931.o: ../../e_os.h ../../include/openssl/asn1.h
        +rsa_x931.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +rsa_x931.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +rsa_x931.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +rsa_x931.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +rsa_x931.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +rsa_x931.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +rsa_x931.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
        +rsa_x931.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +rsa_x931.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_x931.c
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa.h b/vendor/openssl/openssl/crypto/rsa/rsa.h
        new file mode 100644
        index 000000000..5f269e577
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa.h
        @@ -0,0 +1,582 @@
        +/* crypto/rsa/rsa.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_RSA_H
        +#define HEADER_RSA_H
        +
        +#include <openssl/asn1.h>
        +
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/crypto.h>
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/bn.h>
        +#endif
        +
        +#ifdef OPENSSL_NO_RSA
        +#error RSA is disabled.
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Declared already in ossl_typ.h */
        +/* typedef struct rsa_st RSA; */
        +/* typedef struct rsa_meth_st RSA_METHOD; */
        +
        +struct rsa_meth_st
        +	{
        +	const char *name;
        +	int (*rsa_pub_enc)(int flen,const unsigned char *from,
        +			   unsigned char *to,
        +			   RSA *rsa,int padding);
        +	int (*rsa_pub_dec)(int flen,const unsigned char *from,
        +			   unsigned char *to,
        +			   RSA *rsa,int padding);
        +	int (*rsa_priv_enc)(int flen,const unsigned char *from,
        +			    unsigned char *to,
        +			    RSA *rsa,int padding);
        +	int (*rsa_priv_dec)(int flen,const unsigned char *from,
        +			    unsigned char *to,
        +			    RSA *rsa,int padding);
        +	int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa,BN_CTX *ctx); /* Can be null */
        +	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx,
        +			  BN_MONT_CTX *m_ctx); /* Can be null */
        +	int (*init)(RSA *rsa);		/* called at new */
        +	int (*finish)(RSA *rsa);	/* called at free */
        +	int flags;			/* RSA_METHOD_FLAG_* things */
        +	char *app_data;			/* may be needed! */
        +/* New sign and verify functions: some libraries don't allow arbitrary data
        + * to be signed/verified: this allows them to be used. Note: for this to work
        + * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used
        + * RSA_sign(), RSA_verify() should be used instead. Note: for backwards
        + * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER
        + * option is set in 'flags'.
        + */
        +	int (*rsa_sign)(int type,
        +		const unsigned char *m, unsigned int m_length,
        +		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
        +	int (*rsa_verify)(int dtype,
        +		const unsigned char *m, unsigned int m_length,
        +		const unsigned char *sigbuf, unsigned int siglen,
        +								const RSA *rsa);
        +/* If this callback is NULL, the builtin software RSA key-gen will be used. This
        + * is for behavioural compatibility whilst the code gets rewired, but one day
        + * it would be nice to assume there are no such things as "builtin software"
        + * implementations. */
        +	int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
        +	};
        +
        +struct rsa_st
        +	{
        +	/* The first parameter is used to pickup errors where
        +	 * this is passed instead of aEVP_PKEY, it is set to 0 */
        +	int pad;
        +	long version;
        +	const RSA_METHOD *meth;
        +	/* functional reference if 'meth' is ENGINE-provided */
        +	ENGINE *engine;
        +	BIGNUM *n;
        +	BIGNUM *e;
        +	BIGNUM *d;
        +	BIGNUM *p;
        +	BIGNUM *q;
        +	BIGNUM *dmp1;
        +	BIGNUM *dmq1;
        +	BIGNUM *iqmp;
        +	/* be careful using this if the RSA structure is shared */
        +	CRYPTO_EX_DATA ex_data;
        +	int references;
        +	int flags;
        +
        +	/* Used to cache montgomery values */
        +	BN_MONT_CTX *_method_mod_n;
        +	BN_MONT_CTX *_method_mod_p;
        +	BN_MONT_CTX *_method_mod_q;
        +
        +	/* all BIGNUM values are actually in the following data, if it is not
        +	 * NULL */
        +	char *bignum_data;
        +	BN_BLINDING *blinding;
        +	BN_BLINDING *mt_blinding;
        +	};
        +
        +#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
        +# define OPENSSL_RSA_MAX_MODULUS_BITS	16384
        +#endif
        +
        +#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
        +# define OPENSSL_RSA_SMALL_MODULUS_BITS	3072
        +#endif
        +#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
        +# define OPENSSL_RSA_MAX_PUBEXP_BITS	64 /* exponent limit enforced for "large" modulus only */
        +#endif
        +
        +#define RSA_3	0x3L
        +#define RSA_F4	0x10001L
        +
        +#define RSA_METHOD_FLAG_NO_CHECK	0x0001 /* don't check pub/private match */
        +
        +#define RSA_FLAG_CACHE_PUBLIC		0x0002
        +#define RSA_FLAG_CACHE_PRIVATE		0x0004
        +#define RSA_FLAG_BLINDING		0x0008
        +#define RSA_FLAG_THREAD_SAFE		0x0010
        +/* This flag means the private key operations will be handled by rsa_mod_exp
        + * and that they do not depend on the private key components being present:
        + * for example a key stored in external hardware. Without this flag bn_mod_exp
        + * gets called when private key components are absent.
        + */
        +#define RSA_FLAG_EXT_PKEY		0x0020
        +
        +/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
        + */
        +#define RSA_FLAG_SIGN_VER		0x0040
        +
        +#define RSA_FLAG_NO_BLINDING		0x0080 /* new with 0.9.6j and 0.9.7b; the built-in
        +                                                * RSA implementation now uses blinding by
        +                                                * default (ignoring RSA_FLAG_BLINDING),
        +                                                * but other engines might not need it
        +                                                */
        +#define RSA_FLAG_NO_CONSTTIME		0x0100 /* new with 0.9.8f; the built-in RSA
        +						* implementation now uses constant time
        +						* operations by default in private key operations,
        +						* e.g., constant time modular exponentiation, 
        +                                                * modular inverse without leaking branches, 
        +                                                * division without leaking branches. This 
        +                                                * flag disables these constant time 
        +                                                * operations and results in faster RSA 
        +                                                * private key operations.
        +                                                */ 
        +#ifndef OPENSSL_NO_DEPRECATED
        +#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
        +                                                /* new with 0.9.7h; the built-in RSA
        +                                                * implementation now uses constant time
        +                                                * modular exponentiation for secret exponents
        +                                                * by default. This flag causes the
        +                                                * faster variable sliding window method to
        +                                                * be used for all exponents.
        +                                                */
        +#endif
        +
        +
        +#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
        +				pad, NULL)
        +
        +#define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \
        +				EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad)
        +
        +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
        +				(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
        +				EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
        +				len, NULL)
        +
        +#define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
        +				(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
        +				EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \
        +				0, plen)
        +
        +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
        +				EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
        +
        +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
        +	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
        +				EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
        +
        +#define	 EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md)	\
        +		EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG,  \
        +				EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md)
        +
        +#define	 EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd)	\
        +		EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG,  \
        +				EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd)
        +
        +#define EVP_PKEY_CTRL_RSA_PADDING	(EVP_PKEY_ALG_CTRL + 1)
        +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN	(EVP_PKEY_ALG_CTRL + 2)
        +
        +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS	(EVP_PKEY_ALG_CTRL + 3)
        +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP	(EVP_PKEY_ALG_CTRL + 4)
        +#define EVP_PKEY_CTRL_RSA_MGF1_MD	(EVP_PKEY_ALG_CTRL + 5)
        +
        +#define EVP_PKEY_CTRL_GET_RSA_PADDING		(EVP_PKEY_ALG_CTRL + 6)
        +#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN	(EVP_PKEY_ALG_CTRL + 7)
        +#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD		(EVP_PKEY_ALG_CTRL + 8)
        +
        +#define RSA_PKCS1_PADDING	1
        +#define RSA_SSLV23_PADDING	2
        +#define RSA_NO_PADDING		3
        +#define RSA_PKCS1_OAEP_PADDING	4
        +#define RSA_X931_PADDING	5
        +/* EVP_PKEY_ only */
        +#define RSA_PKCS1_PSS_PADDING	6
        +
        +#define RSA_PKCS1_PADDING_SIZE	11
        +
        +#define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
        +#define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
        +
        +RSA *	RSA_new(void);
        +RSA *	RSA_new_method(ENGINE *engine);
        +int	RSA_size(const RSA *rsa);
        +
        +/* Deprecated version */
        +#ifndef OPENSSL_NO_DEPRECATED
        +RSA *	RSA_generate_key(int bits, unsigned long e,void
        +		(*callback)(int,int,void *),void *cb_arg);
        +#endif /* !defined(OPENSSL_NO_DEPRECATED) */
        +
        +/* New version */
        +int	RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
        +
        +int	RSA_check_key(const RSA *);
        +	/* next 4 return -1 on error */
        +int	RSA_public_encrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +int	RSA_private_encrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +int	RSA_public_decrypt(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa,int padding);
        +int	RSA_private_decrypt(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa,int padding);
        +void	RSA_free (RSA *r);
        +/* "up" the RSA object's reference count */
        +int	RSA_up_ref(RSA *r);
        +
        +int	RSA_flags(const RSA *r);
        +
        +void RSA_set_default_method(const RSA_METHOD *meth);
        +const RSA_METHOD *RSA_get_default_method(void);
        +const RSA_METHOD *RSA_get_method(const RSA *rsa);
        +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
        +
        +/* This function needs the memory locking malloc callbacks to be installed */
        +int RSA_memory_lock(RSA *r);
        +
        +/* these are the actual SSLeay RSA functions */
        +const RSA_METHOD *RSA_PKCS1_SSLeay(void);
        +
        +const RSA_METHOD *RSA_null_method(void);
        +
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
        +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
        +
        +typedef struct rsa_pss_params_st
        +	{
        +	X509_ALGOR *hashAlgorithm;
        +	X509_ALGOR *maskGenAlgorithm;
        +	ASN1_INTEGER *saltLength;
        +	ASN1_INTEGER *trailerField;
        +	} RSA_PSS_PARAMS;
        +
        +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
        +
        +#ifndef OPENSSL_NO_FP_API
        +int	RSA_print_fp(FILE *fp, const RSA *r,int offset);
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +int	RSA_print(BIO *bp, const RSA *r,int offset);
        +#endif
        +
        +#ifndef OPENSSL_NO_RC4
        +int i2d_RSA_NET(const RSA *a, unsigned char **pp,
        +		int (*cb)(char *buf, int len, const char *prompt, int verify),
        +		int sgckey);
        +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
        +		 int (*cb)(char *buf, int len, const char *prompt, int verify),
        +		 int sgckey);
        +
        +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
        +		     int (*cb)(char *buf, int len, const char *prompt,
        +			       int verify));
        +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
        +		      int (*cb)(char *buf, int len, const char *prompt,
        +				int verify));
        +#endif
        +
        +/* The following 2 functions sign and verify a X509_SIG ASN1 object
        + * inside PKCS#1 padded RSA encryption */
        +int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
        +	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
        +int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
        +	const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
        +
        +/* The following 2 function sign and verify a ASN1_OCTET_STRING
        + * object inside PKCS#1 padded RSA encryption */
        +int RSA_sign_ASN1_OCTET_STRING(int type,
        +	const unsigned char *m, unsigned int m_length,
        +	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
        +int RSA_verify_ASN1_OCTET_STRING(int type,
        +	const unsigned char *m, unsigned int m_length,
        +	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
        +
        +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
        +void RSA_blinding_off(RSA *rsa);
        +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
        +
        +int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl);
        +int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,int rsa_len);
        +int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl);
        +int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,int rsa_len);
        +int PKCS1_MGF1(unsigned char *mask, long len,
        +	const unsigned char *seed, long seedlen, const EVP_MD *dgst);
        +int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,
        +	const unsigned char *p,int pl);
        +int RSA_padding_check_PKCS1_OAEP(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,int rsa_len,
        +	const unsigned char *p,int pl);
        +int RSA_padding_add_SSLv23(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl);
        +int RSA_padding_check_SSLv23(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,int rsa_len);
        +int RSA_padding_add_none(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl);
        +int RSA_padding_check_none(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,int rsa_len);
        +int RSA_padding_add_X931(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl);
        +int RSA_padding_check_X931(unsigned char *to,int tlen,
        +	const unsigned char *f,int fl,int rsa_len);
        +int RSA_X931_hash_id(int nid);
        +
        +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
        +			const EVP_MD *Hash, const unsigned char *EM, int sLen);
        +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
        +			const unsigned char *mHash,
        +			const EVP_MD *Hash, int sLen);
        +
        +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
        +			const EVP_MD *Hash, const EVP_MD *mgf1Hash, 
        +			const unsigned char *EM, int sLen);
        +
        +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
        +			const unsigned char *mHash,
        +			const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen);
        +
        +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int RSA_set_ex_data(RSA *r,int idx,void *arg);
        +void *RSA_get_ex_data(const RSA *r, int idx);
        +
        +RSA *RSAPublicKey_dup(RSA *rsa);
        +RSA *RSAPrivateKey_dup(RSA *rsa);
        +
        +/* If this flag is set the RSA method is FIPS compliant and can be used
        + * in FIPS mode. This is set in the validated module method. If an
        + * application sets this flag in its own methods it is its responsibility
        + * to ensure the result is compliant.
        + */
        +
        +#define RSA_FLAG_FIPS_METHOD			0x0400
        +
        +/* If this flag is set the operations normally disabled in FIPS mode are
        + * permitted it is then the applications responsibility to ensure that the
        + * usage is compliant.
        + */
        +
        +#define RSA_FLAG_NON_FIPS_ALLOW			0x0400
        +/* Application has decided PRNG is good enough to generate a key: don't
        + * check.
        + */
        +#define RSA_FLAG_CHECKED			0x0800
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_RSA_strings(void);
        +
        +/* Error codes for the RSA functions. */
        +
        +/* Function codes. */
        +#define RSA_F_CHECK_PADDING_MD				 140
        +#define RSA_F_DO_RSA_PRINT				 146
        +#define RSA_F_INT_RSA_VERIFY				 145
        +#define RSA_F_MEMORY_LOCK				 100
        +#define RSA_F_OLD_RSA_PRIV_DECODE			 147
        +#define RSA_F_PKEY_RSA_CTRL				 143
        +#define RSA_F_PKEY_RSA_CTRL_STR				 144
        +#define RSA_F_PKEY_RSA_SIGN				 142
        +#define RSA_F_PKEY_RSA_VERIFY				 154
        +#define RSA_F_PKEY_RSA_VERIFYRECOVER			 141
        +#define RSA_F_RSA_BUILTIN_KEYGEN			 129
        +#define RSA_F_RSA_CHECK_KEY				 123
        +#define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
        +#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT			 102
        +#define RSA_F_RSA_EAY_PUBLIC_DECRYPT			 103
        +#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT			 104
        +#define RSA_F_RSA_GENERATE_KEY				 105
        +#define RSA_F_RSA_GENERATE_KEY_EX			 155
        +#define RSA_F_RSA_ITEM_VERIFY				 156
        +#define RSA_F_RSA_MEMORY_LOCK				 130
        +#define RSA_F_RSA_NEW_METHOD				 106
        +#define RSA_F_RSA_NULL					 124
        +#define RSA_F_RSA_NULL_MOD_EXP				 131
        +#define RSA_F_RSA_NULL_PRIVATE_DECRYPT			 132
        +#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT			 133
        +#define RSA_F_RSA_NULL_PUBLIC_DECRYPT			 134
        +#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT			 135
        +#define RSA_F_RSA_PADDING_ADD_NONE			 107
        +#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP		 121
        +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS			 125
        +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1		 148
        +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1		 108
        +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2		 109
        +#define RSA_F_RSA_PADDING_ADD_SSLV23			 110
        +#define RSA_F_RSA_PADDING_ADD_X931			 127
        +#define RSA_F_RSA_PADDING_CHECK_NONE			 111
        +#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP		 122
        +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1		 112
        +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2		 113
        +#define RSA_F_RSA_PADDING_CHECK_SSLV23			 114
        +#define RSA_F_RSA_PADDING_CHECK_X931			 128
        +#define RSA_F_RSA_PRINT					 115
        +#define RSA_F_RSA_PRINT_FP				 116
        +#define RSA_F_RSA_PRIVATE_DECRYPT			 150
        +#define RSA_F_RSA_PRIVATE_ENCRYPT			 151
        +#define RSA_F_RSA_PRIV_DECODE				 137
        +#define RSA_F_RSA_PRIV_ENCODE				 138
        +#define RSA_F_RSA_PUBLIC_DECRYPT			 152
        +#define RSA_F_RSA_PUBLIC_ENCRYPT			 153
        +#define RSA_F_RSA_PUB_DECODE				 139
        +#define RSA_F_RSA_SETUP_BLINDING			 136
        +#define RSA_F_RSA_SIGN					 117
        +#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
        +#define RSA_F_RSA_VERIFY				 119
        +#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING		 120
        +#define RSA_F_RSA_VERIFY_PKCS1_PSS			 126
        +#define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1			 149
        +
        +/* Reason codes. */
        +#define RSA_R_ALGORITHM_MISMATCH			 100
        +#define RSA_R_BAD_E_VALUE				 101
        +#define RSA_R_BAD_FIXED_HEADER_DECRYPT			 102
        +#define RSA_R_BAD_PAD_BYTE_COUNT			 103
        +#define RSA_R_BAD_SIGNATURE				 104
        +#define RSA_R_BLOCK_TYPE_IS_NOT_01			 106
        +#define RSA_R_BLOCK_TYPE_IS_NOT_02			 107
        +#define RSA_R_DATA_GREATER_THAN_MOD_LEN			 108
        +#define RSA_R_DATA_TOO_LARGE				 109
        +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 110
        +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS		 132
        +#define RSA_R_DATA_TOO_SMALL				 111
        +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE		 122
        +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY		 112
        +#define RSA_R_DMP1_NOT_CONGRUENT_TO_D			 124
        +#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
        +#define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
        +#define RSA_R_FIRST_OCTET_INVALID			 133
        +#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE	 144
        +#define RSA_R_INVALID_DIGEST_LENGTH			 143
        +#define RSA_R_INVALID_HEADER				 137
        +#define RSA_R_INVALID_KEYBITS				 145
        +#define RSA_R_INVALID_MESSAGE_LENGTH			 131
        +#define RSA_R_INVALID_MGF1_MD				 156
        +#define RSA_R_INVALID_PADDING				 138
        +#define RSA_R_INVALID_PADDING_MODE			 141
        +#define RSA_R_INVALID_PSS_PARAMETERS			 149
        +#define RSA_R_INVALID_PSS_SALTLEN			 146
        +#define RSA_R_INVALID_SALT_LENGTH			 150
        +#define RSA_R_INVALID_TRAILER				 139
        +#define RSA_R_INVALID_X931_DIGEST			 142
        +#define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
        +#define RSA_R_KEY_SIZE_TOO_SMALL			 120
        +#define RSA_R_LAST_OCTET_INVALID			 134
        +#define RSA_R_MODULUS_TOO_LARGE				 105
        +#define RSA_R_NON_FIPS_RSA_METHOD			 157
        +#define RSA_R_NO_PUBLIC_EXPONENT			 140
        +#define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
        +#define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
        +#define RSA_R_OAEP_DECODING_ERROR			 121
        +#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE	 158
        +#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 148
        +#define RSA_R_PADDING_CHECK_FAILED			 114
        +#define RSA_R_P_NOT_PRIME				 128
        +#define RSA_R_Q_NOT_PRIME				 129
        +#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED		 130
        +#define RSA_R_SLEN_CHECK_FAILED				 136
        +#define RSA_R_SLEN_RECOVERY_FAILED			 135
        +#define RSA_R_SSLV3_ROLLBACK_ATTACK			 115
        +#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
        +#define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
        +#define RSA_R_UNKNOWN_MASK_DIGEST			 151
        +#define RSA_R_UNKNOWN_PADDING_TYPE			 118
        +#define RSA_R_UNKNOWN_PSS_DIGEST			 152
        +#define RSA_R_UNSUPPORTED_MASK_ALGORITHM		 153
        +#define RSA_R_UNSUPPORTED_MASK_PARAMETER		 154
        +#define RSA_R_UNSUPPORTED_SIGNATURE_TYPE		 155
        +#define RSA_R_VALUE_MISSING				 147
        +#define RSA_R_WRONG_SIGNATURE_LENGTH			 119
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_ameth.c b/vendor/openssl/openssl/crypto/rsa/rsa_ameth.c
        new file mode 100644
        index 000000000..2460910ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_ameth.c
        @@ -0,0 +1,698 @@
        +/* crypto/rsa/rsa_ameth.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/rsa.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_CMS
        +#include <openssl/cms.h>
        +#endif
        +#include "asn1_locl.h"
        +
        +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
        +	{
        +	unsigned char *penc = NULL;
        +	int penclen;
        +	penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
        +	if (penclen <= 0)
        +		return 0;
        +	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
        +				V_ASN1_NULL, NULL, penc, penclen))
        +		return 1;
        +
        +	OPENSSL_free(penc);
        +	return 0;
        +	}
        +
        +static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
        +	{
        +	const unsigned char *p;
        +	int pklen;
        +	RSA *rsa = NULL;
        +	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
        +		return 0;
        +	if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
        +		{
        +		RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_RSA (pkey, rsa);
        +	return 1;
        +	}
        +
        +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
        +		|| BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
        +			return 0;
        +	return 1;
        +	}
        +
        +static int old_rsa_priv_decode(EVP_PKEY *pkey,
        +					const unsigned char **pder, int derlen)
        +	{
        +	RSA *rsa;
        +	if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
        +		{
        +		RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
        +		return 0;
        +		}
        +	EVP_PKEY_assign_RSA(pkey, rsa);
        +	return 1;
        +	}
        +
        +static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
        +	{
        +	return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
        +	}
        +
        +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
        +	{
        +	unsigned char *rk = NULL;
        +	int rklen;
        +	rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
        +
        +	if (rklen <= 0)
        +		{
        +		RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
        +				V_ASN1_NULL, NULL, rk, rklen))
        +		{
        +		RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
        +	{
        +	const unsigned char *p;
        +	int pklen;
        +	if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
        +		return 0;
        +	return old_rsa_priv_decode(pkey, &p, pklen);
        +	}
        +
        +static int int_rsa_size(const EVP_PKEY *pkey)
        +	{
        +	return RSA_size(pkey->pkey.rsa);
        +	}
        +
        +static int rsa_bits(const EVP_PKEY *pkey)
        +	{
        +	return BN_num_bits(pkey->pkey.rsa->n);
        +	}
        +
        +static void int_rsa_free(EVP_PKEY *pkey)
        +	{
        +	RSA_free(pkey->pkey.rsa);
        +	}
        +
        +
        +static void update_buflen(const BIGNUM *b, size_t *pbuflen)
        +	{
        +	size_t i;
        +	if (!b)
        +		return;
        +	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
        +			*pbuflen = i;
        +	}
        +
        +static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
        +	{
        +	char *str;
        +	const char *s;
        +	unsigned char *m=NULL;
        +	int ret=0, mod_len = 0;
        +	size_t buf_len=0;
        +
        +	update_buflen(x->n, &buf_len);
        +	update_buflen(x->e, &buf_len);
        +
        +	if (priv)
        +		{
        +		update_buflen(x->d, &buf_len);
        +		update_buflen(x->p, &buf_len);
        +		update_buflen(x->q, &buf_len);
        +		update_buflen(x->dmp1, &buf_len);
        +		update_buflen(x->dmq1, &buf_len);
        +		update_buflen(x->iqmp, &buf_len);
        +		}
        +
        +	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
        +	if (m == NULL)
        +		{
        +		RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (x->n != NULL)
        +		mod_len = BN_num_bits(x->n);
        +
        +	if(!BIO_indent(bp,off,128))
        +		goto err;
        +
        +	if (priv && x->d)
        +		{
        +		if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
        +			<= 0) goto err;
        +		str = "modulus:";
        +		s = "publicExponent:";
        +		}
        +	else
        +		{
        +		if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len)
        +			<= 0) goto err;
        +		str = "Modulus:";
        +		s= "Exponent:";
        +		}
        +	if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
        +	if (!ASN1_bn_print(bp,s,x->e,m,off))
        +		goto err;
        +	if (priv)
        +		{
        +		if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
        +			goto err;
        +		if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
        +			goto err;
        +		if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
        +			goto err;
        +		if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
        +			goto err;
        +		if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
        +			goto err;
        +		if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
        +			goto err;
        +		}
        +	ret=1;
        +err:
        +	if (m != NULL) OPENSSL_free(m);
        +	return(ret);
        +	}
        +
        +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
        +	}
        +
        +
        +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
        +							ASN1_PCTX *ctx)
        +	{
        +	return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
        +	}
        +
        +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
        +					X509_ALGOR **pmaskHash)
        +	{
        +	const unsigned char *p;
        +	int plen;
        +	RSA_PSS_PARAMS *pss;
        +
        +	*pmaskHash = NULL;
        +
        +	if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
        +		return NULL;
        +	p = alg->parameter->value.sequence->data;
        +	plen = alg->parameter->value.sequence->length;
        +	pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
        +
        +	if (!pss)
        +		return NULL;
        +	
        +	if (pss->maskGenAlgorithm)
        +		{
        +		ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
        +		if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
        +			&& param->type == V_ASN1_SEQUENCE)
        +			{
        +			p = param->value.sequence->data;
        +			plen = param->value.sequence->length;
        +			*pmaskHash = d2i_X509_ALGOR(NULL, &p, plen);
        +			}
        +		}
        +
        +	return pss;
        +	}
        +
        +static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, 
        +				X509_ALGOR *maskHash, int indent)
        +	{
        +	int rv = 0;
        +	if (!pss)
        +		{
        +		if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
        +			return 0;
        +		return 1;
        +		}
        +	if (BIO_puts(bp, "\n") <= 0)
        +		goto err;
        +	if (!BIO_indent(bp, indent, 128))
        +		goto err;
        +	if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
        +		goto err;
        +
        +	if (pss->hashAlgorithm)
        +		{
        +		if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
        +			goto err;
        +		}
        +	else if (BIO_puts(bp, "sha1 (default)") <= 0)
        +		goto err;
        +
        +	if (BIO_puts(bp, "\n") <= 0)
        +		goto err;
        +
        +	if (!BIO_indent(bp, indent, 128))
        +		goto err;
        +
        +	if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
        +			goto err;
        +	if (pss->maskGenAlgorithm)
        +		{
        +		if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
        +			goto err;
        +		if (BIO_puts(bp, " with ") <= 0)
        +			goto err;
        +		if (maskHash)
        +			{
        +			if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
        +			goto err;
        +			}
        +		else if (BIO_puts(bp, "INVALID") <= 0)
        +			goto err;
        +		}
        +	else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
        +		goto err;
        +	BIO_puts(bp, "\n");
        +
        +	if (!BIO_indent(bp, indent, 128))
        +		goto err;
        +	if (BIO_puts(bp, "Salt Length: ") <= 0)
        +			goto err;
        +	if (pss->saltLength)
        +		{
        +		if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
        +			goto err;
        +		}
        +	else if (BIO_puts(bp, "20 (default)") <= 0)
        +		goto err;
        +	BIO_puts(bp, "\n");
        +
        +	if (!BIO_indent(bp, indent, 128))
        +		goto err;
        +	if (BIO_puts(bp, "Trailer Field: ") <= 0)
        +			goto err;
        +	if (pss->trailerField)
        +		{
        +		if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
        +			goto err;
        +		}
        +	else if (BIO_puts(bp, "0xbc (default)") <= 0)
        +		goto err;
        +	BIO_puts(bp, "\n");
        +	
        +	rv = 1;
        +
        +	err:
        +	return rv;
        +
        +	}
        +
        +static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
        +					const ASN1_STRING *sig,
        +					int indent, ASN1_PCTX *pctx)
        +	{
        +	if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss)
        +		{
        +		int rv;
        +		RSA_PSS_PARAMS *pss;
        +		X509_ALGOR *maskHash;
        +		pss = rsa_pss_decode(sigalg, &maskHash);
        +		rv = rsa_pss_param_print(bp, pss, maskHash, indent);
        +		if (pss)
        +			RSA_PSS_PARAMS_free(pss);
        +		if (maskHash)
        +			X509_ALGOR_free(maskHash);
        +		if (!rv)
        +			return 0;
        +		}
        +	else if (!sig && BIO_puts(bp, "\n") <= 0)
        +		return 0;
        +	if (sig)
        +		return X509_signature_dump(bp, sig, indent);
        +	return 1;
        +	}
        +
        +static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        +	{
        +	X509_ALGOR *alg = NULL;
        +	switch (op)
        +		{
        +
        +		case ASN1_PKEY_CTRL_PKCS7_SIGN:
        +		if (arg1 == 0)
        +			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
        +		break;
        +
        +		case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
        +		if (arg1 == 0)
        +			PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
        +		break;
        +#ifndef OPENSSL_NO_CMS
        +		case ASN1_PKEY_CTRL_CMS_SIGN:
        +		if (arg1 == 0)
        +			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
        +		break;
        +
        +		case ASN1_PKEY_CTRL_CMS_ENVELOPE:
        +		if (arg1 == 0)
        +			CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
        +		break;
        +#endif
        +
        +		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        +		*(int *)arg2 = NID_sha1;
        +		return 1;
        +
        +		default:
        +		return -2;
        +
        +		}
        +
        +	if (alg)
        +		X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
        +							V_ASN1_NULL, 0);
        +
        +	return 1;
        +
        +	}
        +
        +/* Customised RSA item verification routine. This is called 
        + * when a signature is encountered requiring special handling. We 
        + * currently only handle PSS.
        + */
        +
        +
        +static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
        +			X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
        +			EVP_PKEY *pkey)
        +	{
        +	int rv = -1;
        +	int saltlen;
        +	const EVP_MD *mgf1md = NULL, *md = NULL;
        +	RSA_PSS_PARAMS *pss;
        +	X509_ALGOR *maskHash;
        +	EVP_PKEY_CTX *pkctx;
        +	/* Sanity check: make sure it is PSS */
        +	if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss)
        +		{
        +		RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
        +		return -1;
        +		}
        +	/* Decode PSS parameters */
        +	pss = rsa_pss_decode(sigalg, &maskHash);
        +
        +	if (pss == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS);
        +		goto err;
        +		}
        +	/* Check mask and lookup mask hash algorithm */
        +	if (pss->maskGenAlgorithm)
        +		{
        +		if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1)
        +			{
        +			RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
        +			goto err;
        +			}
        +		if (!maskHash)
        +			{
        +			RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER);
        +			goto err;
        +			}
        +		mgf1md = EVP_get_digestbyobj(maskHash->algorithm);
        +		if (mgf1md == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST);
        +			goto err;
        +			}
        +		}
        +	else
        +		mgf1md = EVP_sha1();
        +
        +	if (pss->hashAlgorithm)
        +		{
        +		md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm);
        +		if (md == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST);
        +			goto err;
        +			}
        +		}
        +	else
        +		md = EVP_sha1();
        +
        +	if (pss->saltLength)
        +		{
        +		saltlen = ASN1_INTEGER_get(pss->saltLength);
        +
        +		/* Could perform more salt length sanity checks but the main
        +		 * RSA routines will trap other invalid values anyway.
        +		 */
        +		if (saltlen < 0)
        +			{
        +			RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH);
        +			goto err;
        +			}
        +		}
        +	else
        +		saltlen = 20;
        +
        +	/* low-level routines support only trailer field 0xbc (value 1)
        +	 * and PKCS#1 says we should reject any other value anyway.
        +	 */
        +	if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1)
        +		{
        +		RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER);
        +		goto err;
        +		}
        +
        +	/* We have all parameters now set up context */
        +
        +	if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
        +		goto err;
        +
        +	if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
        +		goto err;
        +	/* Carry on */
        +	rv = 2;
        +
        +	err:
        +	RSA_PSS_PARAMS_free(pss);
        +	if (maskHash)
        +		X509_ALGOR_free(maskHash);
        +	return rv;
        +	}
        +
        +static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
        +				X509_ALGOR *alg1, X509_ALGOR *alg2, 
        +				ASN1_BIT_STRING *sig)
        +	{
        +	int pad_mode;
        +	EVP_PKEY_CTX *pkctx = ctx->pctx;
        +	if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
        +		return 0;
        +	if (pad_mode == RSA_PKCS1_PADDING)
        +		return 2;
        +	if (pad_mode == RSA_PKCS1_PSS_PADDING)
        +		{
        +		const EVP_MD *sigmd, *mgf1md;
        +		RSA_PSS_PARAMS *pss = NULL;
        +		X509_ALGOR *mgf1alg = NULL;
        +		ASN1_STRING *os1 = NULL, *os2 = NULL;
        +		EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
        +		int saltlen, rv = 0;
        +		sigmd = EVP_MD_CTX_md(ctx);
        +		if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
        +			goto err;
        +		if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
        +			goto err;
        +		if (saltlen == -1)
        +			saltlen = EVP_MD_size(sigmd);
        +		else if (saltlen == -2)
        +			{
        +			saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
        +			if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
        +				saltlen--;
        +			}
        +		pss = RSA_PSS_PARAMS_new();
        +		if (!pss)
        +			goto err;
        +		if (saltlen != 20)
        +			{
        +			pss->saltLength = ASN1_INTEGER_new();
        +			if (!pss->saltLength)
        +				goto err;
        +			if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
        +				goto err;
        +			}
        +		if (EVP_MD_type(sigmd) != NID_sha1)
        +			{
        +			pss->hashAlgorithm = X509_ALGOR_new();
        +			if (!pss->hashAlgorithm)
        +				goto err;
        +			X509_ALGOR_set_md(pss->hashAlgorithm, sigmd);
        +			}
        +		if (EVP_MD_type(mgf1md) != NID_sha1)
        +			{
        +			ASN1_STRING *stmp = NULL;
        +			/* need to embed algorithm ID inside another */
        +			mgf1alg = X509_ALGOR_new();
        +			X509_ALGOR_set_md(mgf1alg, mgf1md);
        +			if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR),
        +									&stmp))
        +					goto err;
        +			pss->maskGenAlgorithm = X509_ALGOR_new();
        +			if (!pss->maskGenAlgorithm)
        +				goto err;
        +			X509_ALGOR_set0(pss->maskGenAlgorithm,
        +					OBJ_nid2obj(NID_mgf1),
        +					V_ASN1_SEQUENCE, stmp);
        +			}
        +		/* Finally create string with pss parameter encoding. */
        +		if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1))
        +			goto err;
        +		if (alg2)
        +			{
        +			os2 = ASN1_STRING_dup(os1);
        +			if (!os2)
        +				goto err;
        +			X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
        +						V_ASN1_SEQUENCE, os2);
        +			}
        +		X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
        +					V_ASN1_SEQUENCE, os1);
        +		os1 = os2 = NULL;
        +		rv = 3;
        +		err:
        +		if (mgf1alg)
        +			X509_ALGOR_free(mgf1alg);
        +		if (pss)
        +			RSA_PSS_PARAMS_free(pss);
        +		if (os1)
        +			ASN1_STRING_free(os1);
        +		return rv;
        +		
        +		}
        +	return 2;
        +	}
        +
        +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = 
        +	{
        +		{
        +		EVP_PKEY_RSA,
        +		EVP_PKEY_RSA,
        +		ASN1_PKEY_SIGPARAM_NULL,
        +
        +		"RSA",
        +		"OpenSSL RSA method",
        +
        +		rsa_pub_decode,
        +		rsa_pub_encode,
        +		rsa_pub_cmp,
        +		rsa_pub_print,
        +
        +		rsa_priv_decode,
        +		rsa_priv_encode,
        +		rsa_priv_print,
        +
        +		int_rsa_size,
        +		rsa_bits,
        +
        +		0,0,0,0,0,0,
        +
        +		rsa_sig_print,
        +		int_rsa_free,
        +		rsa_pkey_ctrl,
        +		old_rsa_priv_decode,
        +		old_rsa_priv_encode,
        +		rsa_item_verify,
        +		rsa_item_sign
        +		},
        +
        +		{
        +		EVP_PKEY_RSA2,
        +		EVP_PKEY_RSA,
        +		ASN1_PKEY_ALIAS
        +		}
        +	};
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_asn1.c b/vendor/openssl/openssl/crypto/rsa/rsa_asn1.c
        new file mode 100644
        index 000000000..6ed5de3db
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_asn1.c
        @@ -0,0 +1,121 @@
        +/* rsa_asn1.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/x509.h>
        +#include <openssl/asn1t.h>
        +
        +/* Override the default free and new methods */
        +static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +{
        +	if(operation == ASN1_OP_NEW_PRE) {
        +		*pval = (ASN1_VALUE *)RSA_new();
        +		if(*pval) return 2;
        +		return 0;
        +	} else if(operation == ASN1_OP_FREE_PRE) {
        +		RSA_free((RSA *)*pval);
        +		*pval = NULL;
        +		return 2;
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
        +	ASN1_SIMPLE(RSA, version, LONG),
        +	ASN1_SIMPLE(RSA, n, BIGNUM),
        +	ASN1_SIMPLE(RSA, e, BIGNUM),
        +	ASN1_SIMPLE(RSA, d, BIGNUM),
        +	ASN1_SIMPLE(RSA, p, BIGNUM),
        +	ASN1_SIMPLE(RSA, q, BIGNUM),
        +	ASN1_SIMPLE(RSA, dmp1, BIGNUM),
        +	ASN1_SIMPLE(RSA, dmq1, BIGNUM),
        +	ASN1_SIMPLE(RSA, iqmp, BIGNUM)
        +} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
        +
        +
        +ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
        +	ASN1_SIMPLE(RSA, n, BIGNUM),
        +	ASN1_SIMPLE(RSA, e, BIGNUM),
        +} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
        +
        +ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
        +	ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
        +	ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
        +	ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
        +	ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3)
        +} ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
        +
        +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
        +
        +RSA *RSAPublicKey_dup(RSA *rsa)
        +	{
        +	return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
        +	}
        +
        +RSA *RSAPrivateKey_dup(RSA *rsa)
        +	{
        +	return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_chk.c b/vendor/openssl/openssl/crypto/rsa/rsa_chk.c
        new file mode 100644
        index 000000000..9d848db8c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_chk.c
        @@ -0,0 +1,184 @@
        +/* crypto/rsa/rsa_chk.c  -*- Mode: C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * 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.
        + * ====================================================================
        + */
        +
        +#include <openssl/bn.h>
        +#include <openssl/err.h>
        +#include <openssl/rsa.h>
        +
        +
        +int RSA_check_key(const RSA *key)
        +	{
        +	BIGNUM *i, *j, *k, *l, *m;
        +	BN_CTX *ctx;
        +	int r;
        +	int ret=1;
        +	
        +	i = BN_new();
        +	j = BN_new();
        +	k = BN_new();
        +	l = BN_new();
        +	m = BN_new();
        +	ctx = BN_CTX_new();
        +	if (i == NULL || j == NULL || k == NULL || l == NULL ||
        +		m == NULL || ctx == NULL)
        +		{
        +		ret = -1;
        +		RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	
        +	/* p prime? */
        +	r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
        +	if (r != 1)
        +		{
        +		ret = r;
        +		if (r != 0)
        +			goto err;
        +		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
        +		}
        +	
        +	/* q prime? */
        +	r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
        +	if (r != 1)
        +		{
        +		ret = r;
        +		if (r != 0)
        +			goto err;
        +		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
        +		}
        +	
        +	/* n = p*q? */
        +	r = BN_mul(i, key->p, key->q, ctx);
        +	if (!r) { ret = -1; goto err; }
        +	
        +	if (BN_cmp(i, key->n) != 0)
        +		{
        +		ret = 0;
        +		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
        +		}
        +	
        +	/* d*e = 1  mod lcm(p-1,q-1)? */
        +
        +	r = BN_sub(i, key->p, BN_value_one());
        +	if (!r) { ret = -1; goto err; }
        +	r = BN_sub(j, key->q, BN_value_one());
        +	if (!r) { ret = -1; goto err; }
        +
        +	/* now compute k = lcm(i,j) */
        +	r = BN_mul(l, i, j, ctx);
        +	if (!r) { ret = -1; goto err; }
        +	r = BN_gcd(m, i, j, ctx);
        +	if (!r) { ret = -1; goto err; }
        +	r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
        +	if (!r) { ret = -1; goto err; }
        +
        +	r = BN_mod_mul(i, key->d, key->e, k, ctx);
        +	if (!r) { ret = -1; goto err; }
        +
        +	if (!BN_is_one(i))
        +		{
        +		ret = 0;
        +		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
        +		}
        +	
        +	if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL)
        +		{
        +		/* dmp1 = d mod (p-1)? */
        +		r = BN_sub(i, key->p, BN_value_one());
        +		if (!r) { ret = -1; goto err; }
        +
        +		r = BN_mod(j, key->d, i, ctx);
        +		if (!r) { ret = -1; goto err; }
        +
        +		if (BN_cmp(j, key->dmp1) != 0)
        +			{
        +			ret = 0;
        +			RSAerr(RSA_F_RSA_CHECK_KEY,
        +				RSA_R_DMP1_NOT_CONGRUENT_TO_D);
        +			}
        +	
        +		/* dmq1 = d mod (q-1)? */    
        +		r = BN_sub(i, key->q, BN_value_one());
        +		if (!r) { ret = -1; goto err; }
        +	
        +		r = BN_mod(j, key->d, i, ctx);
        +		if (!r) { ret = -1; goto err; }
        +
        +		if (BN_cmp(j, key->dmq1) != 0)
        +			{
        +			ret = 0;
        +			RSAerr(RSA_F_RSA_CHECK_KEY,
        +				RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
        +			}
        +	
        +		/* iqmp = q^-1 mod p? */
        +		if(!BN_mod_inverse(i, key->q, key->p, ctx))
        +			{
        +			ret = -1;
        +			goto err;
        +			}
        +
        +		if (BN_cmp(i, key->iqmp) != 0)
        +			{
        +			ret = 0;
        +			RSAerr(RSA_F_RSA_CHECK_KEY,
        +				RSA_R_IQMP_NOT_INVERSE_OF_Q);
        +			}
        +		}
        +
        + err:
        +	if (i != NULL) BN_free(i);
        +	if (j != NULL) BN_free(j);
        +	if (k != NULL) BN_free(k);
        +	if (l != NULL) BN_free(l);
        +	if (m != NULL) BN_free(m);
        +	if (ctx != NULL) BN_CTX_free(ctx);
        +	return (ret);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_crpt.c b/vendor/openssl/openssl/crypto/rsa/rsa_crpt.c
        new file mode 100644
        index 000000000..d3e44785d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_crpt.c
        @@ -0,0 +1,257 @@
        +/* crypto/rsa/rsa_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +int RSA_size(const RSA *r)
        +	{
        +	return(BN_num_bytes(r->n));
        +	}
        +
        +int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
        +		return -1;
        +		}
        +#endif
        +	return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
        +	}
        +
        +int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
        +		return -1;
        +		}
        +#endif
        +	return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
        +	}
        +
        +int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
        +		return -1;
        +		}
        +#endif
        +	return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
        +	}
        +
        +int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
        +		return -1;
        +		}
        +#endif
        +	return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
        +	}
        +
        +int RSA_flags(const RSA *r)
        +	{
        +	return((r == NULL)?0:r->meth->flags);
        +	}
        +
        +void RSA_blinding_off(RSA *rsa)
        +	{
        +	if (rsa->blinding != NULL)
        +		{
        +		BN_BLINDING_free(rsa->blinding);
        +		rsa->blinding=NULL;
        +		}
        +	rsa->flags &= ~RSA_FLAG_BLINDING;
        +	rsa->flags |= RSA_FLAG_NO_BLINDING;
        +	}
        +
        +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
        +	{
        +	int ret=0;
        +
        +	if (rsa->blinding != NULL)
        +		RSA_blinding_off(rsa);
        +
        +	rsa->blinding = RSA_setup_blinding(rsa, ctx);
        +	if (rsa->blinding == NULL)
        +		goto err;
        +
        +	rsa->flags |= RSA_FLAG_BLINDING;
        +	rsa->flags &= ~RSA_FLAG_NO_BLINDING;
        +	ret=1;
        +err:
        +	return(ret);
        +	}
        +
        +static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
        +	const BIGNUM *q, BN_CTX *ctx)
        +{
        +	BIGNUM *ret = NULL, *r0, *r1, *r2;
        +
        +	if (d == NULL || p == NULL || q == NULL)
        +		return NULL;
        +
        +	BN_CTX_start(ctx);
        +	r0 = BN_CTX_get(ctx);
        +	r1 = BN_CTX_get(ctx);
        +	r2 = BN_CTX_get(ctx);
        +	if (r2 == NULL)
        +		goto err;
        +
        +	if (!BN_sub(r1, p, BN_value_one())) goto err;
        +	if (!BN_sub(r2, q, BN_value_one())) goto err;
        +	if (!BN_mul(r0, r1, r2, ctx)) goto err;
        +
        +	ret = BN_mod_inverse(NULL, d, r0, ctx);
        +err:
        +	BN_CTX_end(ctx);
        +	return ret;
        +}
        +
        +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
        +{
        +	BIGNUM local_n;
        +	BIGNUM *e,*n;
        +	BN_CTX *ctx;
        +	BN_BLINDING *ret = NULL;
        +
        +	if (in_ctx == NULL)
        +		{
        +		if ((ctx = BN_CTX_new()) == NULL) return 0;
        +		}
        +	else
        +		ctx = in_ctx;
        +
        +	BN_CTX_start(ctx);
        +	e  = BN_CTX_get(ctx);
        +	if (e == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (rsa->e == NULL)
        +		{
        +		e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
        +		if (e == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
        +			goto err;
        +			}
        +		}
        +	else
        +		e = rsa->e;
        +
        +	
        +	if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
        +		{
        +		/* if PRNG is not properly seeded, resort to secret
        +		 * exponent as unpredictable seed */
        +		RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
        +		}
        +
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		/* Set BN_FLG_CONSTTIME flag */
        +		n = &local_n;
        +		BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		n = rsa->n;
        +
        +	ret = BN_BLINDING_create_param(NULL, e, n, ctx,
        +			rsa->meth->bn_mod_exp, rsa->_method_mod_n);
        +	if (ret == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
        +err:
        +	BN_CTX_end(ctx);
        +	if (in_ctx == NULL)
        +		BN_CTX_free(ctx);
        +	if(rsa->e == NULL)
        +		BN_free(e);
        +
        +	return ret;
        +}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_depr.c b/vendor/openssl/openssl/crypto/rsa/rsa_depr.c
        new file mode 100644
        index 000000000..a859ded98
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_depr.c
        @@ -0,0 +1,101 @@
        +/* crypto/rsa/rsa_depr.c */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +/* NB: This file contains deprecated functions (compatibility wrappers to the
        + * "new" versions). */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +
        +#ifdef OPENSSL_NO_DEPRECATED
        +
        +static void *dummy=&dummy;
        +
        +#else
        +
        +RSA *RSA_generate_key(int bits, unsigned long e_value,
        +	     void (*callback)(int,int,void *), void *cb_arg)
        +	{
        +	BN_GENCB cb;
        +	int i;
        +	RSA *rsa = RSA_new();
        +	BIGNUM *e = BN_new();
        +
        +	if(!rsa || !e) goto err;
        +
        +	/* The problem is when building with 8, 16, or 32 BN_ULONG,
        +	 * unsigned long can be larger */
        +	for (i=0; i<(int)sizeof(unsigned long)*8; i++)
        +		{
        +		if (e_value & (1UL<<i))
        +			if (BN_set_bit(e,i) == 0)
        +				goto err;
        +		}
        +
        +	BN_GENCB_set_old(&cb, callback, cb_arg);
        +
        +	if(RSA_generate_key_ex(rsa, bits, e, &cb)) {
        +		BN_free(e);
        +		return rsa;
        +	}
        +err:
        +	if(e) BN_free(e);
        +	if(rsa) RSA_free(rsa);
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_eay.c b/vendor/openssl/openssl/crypto/rsa/rsa_eay.c
        new file mode 100644
        index 000000000..88ee2cb55
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_eay.c
        @@ -0,0 +1,915 @@
        +/* crypto/rsa/rsa_eay.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +
        +#ifndef RSA_NULL
        +
        +static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
        +static int RSA_eay_init(RSA *rsa);
        +static int RSA_eay_finish(RSA *rsa);
        +static RSA_METHOD rsa_pkcs1_eay_meth={
        +	"Eric Young's PKCS#1 RSA",
        +	RSA_eay_public_encrypt,
        +	RSA_eay_public_decrypt, /* signature verification */
        +	RSA_eay_private_encrypt, /* signing */
        +	RSA_eay_private_decrypt,
        +	RSA_eay_mod_exp,
        +	BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
        +	RSA_eay_init,
        +	RSA_eay_finish,
        +	0, /* flags */
        +	NULL,
        +	0, /* rsa_sign */
        +	0, /* rsa_verify */
        +	NULL /* rsa_keygen */
        +	};
        +
        +const RSA_METHOD *RSA_PKCS1_SSLeay(void)
        +	{
        +	return(&rsa_pkcs1_eay_meth);
        +	}
        +
        +static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	BIGNUM *f,*ret;
        +	int i,j,k,num=0,r= -1;
        +	unsigned char *buf=NULL;
        +	BN_CTX *ctx=NULL;
        +
        +	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
        +		return -1;
        +		}
        +
        +	if (BN_ucmp(rsa->n, rsa->e) <= 0)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
        +		return -1;
        +		}
        +
        +	/* for large moduli, enforce exponent limit */
        +	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
        +		{
        +		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
        +			{
        +			RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
        +			return -1;
        +			}
        +		}
        +	
        +	if ((ctx=BN_CTX_new()) == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	f = BN_CTX_get(ctx);
        +	ret = BN_CTX_get(ctx);
        +	num=BN_num_bytes(rsa->n);
        +	buf = OPENSSL_malloc(num);
        +	if (!f || !ret || !buf)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	switch (padding)
        +		{
        +	case RSA_PKCS1_PADDING:
        +		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
        +		break;
        +#ifndef OPENSSL_NO_SHA
        +	case RSA_PKCS1_OAEP_PADDING:
        +	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
        +		break;
        +#endif
        +	case RSA_SSLV23_PADDING:
        +		i=RSA_padding_add_SSLv23(buf,num,from,flen);
        +		break;
        +	case RSA_NO_PADDING:
        +		i=RSA_padding_add_none(buf,num,from,flen);
        +		break;
        +	default:
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
        +		goto err;
        +		}
        +	if (i <= 0) goto err;
        +
        +	if (BN_bin2bn(buf,num,f) == NULL) goto err;
        +	
        +	if (BN_ucmp(f, rsa->n) >= 0)
        +		{
        +		/* usually the padding functions would catch this */
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
        +		goto err;
        +		}
        +
        +	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
        +		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
        +			goto err;
        +
        +	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
        +		rsa->_method_mod_n)) goto err;
        +
        +	/* put in leading 0 bytes if the number is less than the
        +	 * length of the modulus */
        +	j=BN_num_bytes(ret);
        +	i=BN_bn2bin(ret,&(to[num-j]));
        +	for (k=0; k<(num-i); k++)
        +		to[k]=0;
        +
        +	r=num;
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	if (buf != NULL) 
        +		{
        +		OPENSSL_cleanse(buf,num);
        +		OPENSSL_free(buf);
        +		}
        +	return(r);
        +	}
        +
        +static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
        +{
        +	BN_BLINDING *ret;
        +	int got_write_lock = 0;
        +	CRYPTO_THREADID cur;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_RSA);
        +
        +	if (rsa->blinding == NULL)
        +		{
        +		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
        +		CRYPTO_w_lock(CRYPTO_LOCK_RSA);
        +		got_write_lock = 1;
        +
        +		if (rsa->blinding == NULL)
        +			rsa->blinding = RSA_setup_blinding(rsa, ctx);
        +		}
        +
        +	ret = rsa->blinding;
        +	if (ret == NULL)
        +		goto err;
        +
        +	CRYPTO_THREADID_current(&cur);
        +	if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
        +		{
        +		/* rsa->blinding is ours! */
        +
        +		*local = 1;
        +		}
        +	else
        +		{
        +		/* resort to rsa->mt_blinding instead */
        +
        +		*local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
        +		             * that the BN_BLINDING is shared, meaning that accesses
        +		             * require locks, and that the blinding factor must be
        +		             * stored outside the BN_BLINDING
        +		             */
        +
        +		if (rsa->mt_blinding == NULL)
        +			{
        +			if (!got_write_lock)
        +				{
        +				CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
        +				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
        +				got_write_lock = 1;
        +				}
        +			
        +			if (rsa->mt_blinding == NULL)
        +				rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
        +			}
        +		ret = rsa->mt_blinding;
        +		}
        +
        + err:
        +	if (got_write_lock)
        +		CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
        +	else
        +		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
        +	return ret;
        +}
        +
        +static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
        +	BN_CTX *ctx)
        +	{
        +	if (unblind == NULL)
        +		/* Local blinding: store the unblinding factor
        +		 * in BN_BLINDING. */
        +		return BN_BLINDING_convert_ex(f, NULL, b, ctx);
        +	else
        +		{
        +		/* Shared blinding: store the unblinding factor
        +		 * outside BN_BLINDING. */
        +		int ret;
        +		CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
        +		ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
        +		return ret;
        +		}
        +	}
        +
        +static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
        +	BN_CTX *ctx)
        +	{
        +	/* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
        +	 * will use the unblinding factor stored in BN_BLINDING.
        +	 * If BN_BLINDING is shared between threads, unblind must be non-null:
        +	 * BN_BLINDING_invert_ex will then use the local unblinding factor,
        +	 * and will only read the modulus from BN_BLINDING.
        +	 * In both cases it's safe to access the blinding without a lock.
        +	 */
        +	return BN_BLINDING_invert_ex(f, unblind, b, ctx);
        +	}
        +
        +/* signing */
        +static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	BIGNUM *f, *ret, *res;
        +	int i,j,k,num=0,r= -1;
        +	unsigned char *buf=NULL;
        +	BN_CTX *ctx=NULL;
        +	int local_blinding = 0;
        +	/* Used only if the blinding structure is shared. A non-NULL unblind
        +	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
        +	 * the unblinding factor outside the blinding structure. */
        +	BIGNUM *unblind = NULL;
        +	BN_BLINDING *blinding = NULL;
        +
        +	if ((ctx=BN_CTX_new()) == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	f   = BN_CTX_get(ctx);
        +	ret = BN_CTX_get(ctx);
        +	num = BN_num_bytes(rsa->n);
        +	buf = OPENSSL_malloc(num);
        +	if(!f || !ret || !buf)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	switch (padding)
        +		{
        +	case RSA_PKCS1_PADDING:
        +		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
        +		break;
        +	case RSA_X931_PADDING:
        +		i=RSA_padding_add_X931(buf,num,from,flen);
        +		break;
        +	case RSA_NO_PADDING:
        +		i=RSA_padding_add_none(buf,num,from,flen);
        +		break;
        +	case RSA_SSLV23_PADDING:
        +	default:
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
        +		goto err;
        +		}
        +	if (i <= 0) goto err;
        +
        +	if (BN_bin2bn(buf,num,f) == NULL) goto err;
        +	
        +	if (BN_ucmp(f, rsa->n) >= 0)
        +		{	
        +		/* usually the padding functions would catch this */
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
        +		goto err;
        +		}
        +
        +	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
        +		{
        +		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
        +		if (blinding == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		}
        +	
        +	if (blinding != NULL)
        +		{
        +		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
        +			{
        +			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
        +			goto err;
        +		}
        +
        +	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
        +		((rsa->p != NULL) &&
        +		(rsa->q != NULL) &&
        +		(rsa->dmp1 != NULL) &&
        +		(rsa->dmq1 != NULL) &&
        +		(rsa->iqmp != NULL)) )
        +		{ 
        +		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
        +		}
        +	else
        +		{
        +		BIGNUM local_d;
        +		BIGNUM *d = NULL;
        +		
        +		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +			{
        +			BN_init(&local_d);
        +			d = &local_d;
        +			BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
        +			}
        +		else
        +			d= rsa->d;
        +
        +		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
        +			if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
        +				goto err;
        +
        +		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
        +				rsa->_method_mod_n)) goto err;
        +		}
        +
        +	if (blinding)
        +		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
        +			goto err;
        +
        +	if (padding == RSA_X931_PADDING)
        +		{
        +		BN_sub(f, rsa->n, ret);
        +		if (BN_cmp(ret, f))
        +			res = f;
        +		else
        +			res = ret;
        +		}
        +	else
        +		res = ret;
        +
        +	/* put in leading 0 bytes if the number is less than the
        +	 * length of the modulus */
        +	j=BN_num_bytes(res);
        +	i=BN_bn2bin(res,&(to[num-j]));
        +	for (k=0; k<(num-i); k++)
        +		to[k]=0;
        +
        +	r=num;
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	if (buf != NULL)
        +		{
        +		OPENSSL_cleanse(buf,num);
        +		OPENSSL_free(buf);
        +		}
        +	return(r);
        +	}
        +
        +static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	BIGNUM *f, *ret;
        +	int j,num=0,r= -1;
        +	unsigned char *p;
        +	unsigned char *buf=NULL;
        +	BN_CTX *ctx=NULL;
        +	int local_blinding = 0;
        +	/* Used only if the blinding structure is shared. A non-NULL unblind
        +	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
        +	 * the unblinding factor outside the blinding structure. */
        +	BIGNUM *unblind = NULL;
        +	BN_BLINDING *blinding = NULL;
        +
        +	if((ctx = BN_CTX_new()) == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	f   = BN_CTX_get(ctx);
        +	ret = BN_CTX_get(ctx);
        +	num = BN_num_bytes(rsa->n);
        +	buf = OPENSSL_malloc(num);
        +	if(!f || !ret || !buf)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	/* This check was for equality but PGP does evil things
        +	 * and chops off the top '0' bytes */
        +	if (flen > num)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
        +		goto err;
        +		}
        +
        +	/* make data into a big number */
        +	if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
        +
        +	if (BN_ucmp(f, rsa->n) >= 0)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
        +		goto err;
        +		}
        +
        +	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
        +		{
        +		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
        +		if (blinding == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		}
        +	
        +	if (blinding != NULL)
        +		{
        +		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
        +			{
        +			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
        +			goto err;
        +		}
        +
        +	/* do the decrypt */
        +	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
        +		((rsa->p != NULL) &&
        +		(rsa->q != NULL) &&
        +		(rsa->dmp1 != NULL) &&
        +		(rsa->dmq1 != NULL) &&
        +		(rsa->iqmp != NULL)) )
        +		{
        +		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
        +		}
        +	else
        +		{
        +		BIGNUM local_d;
        +		BIGNUM *d = NULL;
        +		
        +		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +			{
        +			d = &local_d;
        +			BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
        +			}
        +		else
        +			d = rsa->d;
        +
        +		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
        +			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
        +				goto err;
        +		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
        +				rsa->_method_mod_n))
        +		  goto err;
        +		}
        +
        +	if (blinding)
        +		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
        +			goto err;
        +
        +	p=buf;
        +	j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
        +
        +	switch (padding)
        +		{
        +	case RSA_PKCS1_PADDING:
        +		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
        +		break;
        +#ifndef OPENSSL_NO_SHA
        +        case RSA_PKCS1_OAEP_PADDING:
        +	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
        +                break;
        +#endif
        + 	case RSA_SSLV23_PADDING:
        +		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
        +		break;
        +	case RSA_NO_PADDING:
        +		r=RSA_padding_check_none(to,num,buf,j,num);
        +		break;
        +	default:
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
        +		goto err;
        +		}
        +	if (r < 0)
        +		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
        +
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	if (buf != NULL)
        +		{
        +		OPENSSL_cleanse(buf,num);
        +		OPENSSL_free(buf);
        +		}
        +	return(r);
        +	}
        +
        +/* signature verification */
        +static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	BIGNUM *f,*ret;
        +	int i,num=0,r= -1;
        +	unsigned char *p;
        +	unsigned char *buf=NULL;
        +	BN_CTX *ctx=NULL;
        +
        +	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
        +		return -1;
        +		}
        +
        +	if (BN_ucmp(rsa->n, rsa->e) <= 0)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
        +		return -1;
        +		}
        +
        +	/* for large moduli, enforce exponent limit */
        +	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
        +		{
        +		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
        +			{
        +			RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
        +			return -1;
        +			}
        +		}
        +	
        +	if((ctx = BN_CTX_new()) == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	f = BN_CTX_get(ctx);
        +	ret = BN_CTX_get(ctx);
        +	num=BN_num_bytes(rsa->n);
        +	buf = OPENSSL_malloc(num);
        +	if(!f || !ret || !buf)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	/* This check was for equality but PGP does evil things
        +	 * and chops off the top '0' bytes */
        +	if (flen > num)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
        +		goto err;
        +		}
        +
        +	if (BN_bin2bn(from,flen,f) == NULL) goto err;
        +
        +	if (BN_ucmp(f, rsa->n) >= 0)
        +		{
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
        +		goto err;
        +		}
        +
        +	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
        +		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
        +			goto err;
        +
        +	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
        +		rsa->_method_mod_n)) goto err;
        +
        +	if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
        +		if (!BN_sub(ret, rsa->n, ret)) goto err;
        +
        +	p=buf;
        +	i=BN_bn2bin(ret,p);
        +
        +	switch (padding)
        +		{
        +	case RSA_PKCS1_PADDING:
        +		r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
        +		break;
        +	case RSA_X931_PADDING:
        +		r=RSA_padding_check_X931(to,num,buf,i,num);
        +		break;
        +	case RSA_NO_PADDING:
        +		r=RSA_padding_check_none(to,num,buf,i,num);
        +		break;
        +	default:
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
        +		goto err;
        +		}
        +	if (r < 0)
        +		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
        +
        +err:
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	if (buf != NULL)
        +		{
        +		OPENSSL_cleanse(buf,num);
        +		OPENSSL_free(buf);
        +		}
        +	return(r);
        +	}
        +
        +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	BIGNUM *r1,*m1,*vrfy;
        +	BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
        +	BIGNUM *dmp1,*dmq1,*c,*pr1;
        +	int ret=0;
        +
        +	BN_CTX_start(ctx);
        +	r1 = BN_CTX_get(ctx);
        +	m1 = BN_CTX_get(ctx);
        +	vrfy = BN_CTX_get(ctx);
        +
        +	{
        +		BIGNUM local_p, local_q;
        +		BIGNUM *p = NULL, *q = NULL;
        +
        +		/* Make sure BN_mod_inverse in Montgomery intialization uses the
        +		 * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set)
        +		 */
        +		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +			{
        +			BN_init(&local_p);
        +			p = &local_p;
        +			BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
        +
        +			BN_init(&local_q);
        +			q = &local_q;
        +			BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
        +			}
        +		else
        +			{
        +			p = rsa->p;
        +			q = rsa->q;
        +			}
        +
        +		if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
        +			{
        +			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
        +				goto err;
        +			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
        +				goto err;
        +			}
        +	}
        +
        +	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
        +		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
        +			goto err;
        +
        +	/* compute I mod q */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		c = &local_c;
        +		BN_with_flags(c, I, BN_FLG_CONSTTIME);
        +		if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
        +		}
        +
        +	/* compute r1^dmq1 mod q */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		dmq1 = &local_dmq1;
        +		BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		dmq1 = rsa->dmq1;
        +	if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
        +		rsa->_method_mod_q)) goto err;
        +
        +	/* compute I mod p */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		c = &local_c;
        +		BN_with_flags(c, I, BN_FLG_CONSTTIME);
        +		if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
        +		}
        +	else
        +		{
        +		if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
        +		}
        +
        +	/* compute r1^dmp1 mod p */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		dmp1 = &local_dmp1;
        +		BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		dmp1 = rsa->dmp1;
        +	if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
        +		rsa->_method_mod_p)) goto err;
        +
        +	if (!BN_sub(r0,r0,m1)) goto err;
        +	/* This will help stop the size of r0 increasing, which does
        +	 * affect the multiply if it optimised for a power of 2 size */
        +	if (BN_is_negative(r0))
        +		if (!BN_add(r0,r0,rsa->p)) goto err;
        +
        +	if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
        +
        +	/* Turn BN_FLG_CONSTTIME flag on before division operation */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		pr1 = &local_r1;
        +		BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		pr1 = r1;
        +	if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
        +
        +	/* If p < q it is occasionally possible for the correction of
        +	 * adding 'p' if r0 is negative above to leave the result still
        +	 * negative. This can break the private key operations: the following
        +	 * second correction should *always* correct this rare occurrence.
        +	 * This will *never* happen with OpenSSL generated keys because
        +	 * they ensure p > q [steve]
        +	 */
        +	if (BN_is_negative(r0))
        +		if (!BN_add(r0,r0,rsa->p)) goto err;
        +	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
        +	if (!BN_add(r0,r1,m1)) goto err;
        +
        +	if (rsa->e && rsa->n)
        +		{
        +		if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
        +		/* If 'I' was greater than (or equal to) rsa->n, the operation
        +		 * will be equivalent to using 'I mod n'. However, the result of
        +		 * the verify will *always* be less than 'n' so we don't check
        +		 * for absolute equality, just congruency. */
        +		if (!BN_sub(vrfy, vrfy, I)) goto err;
        +		if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
        +		if (BN_is_negative(vrfy))
        +			if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
        +		if (!BN_is_zero(vrfy))
        +			{
        +			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
        +			 * miscalculated CRT output, just do a raw (slower)
        +			 * mod_exp and return that instead. */
        +
        +			BIGNUM local_d;
        +			BIGNUM *d = NULL;
        +		
        +			if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +				{
        +				d = &local_d;
        +				BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
        +				}
        +			else
        +				d = rsa->d;
        +			if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
        +						   rsa->_method_mod_n)) goto err;
        +			}
        +		}
        +	ret=1;
        +err:
        +	BN_CTX_end(ctx);
        +	return(ret);
        +	}
        +
        +static int RSA_eay_init(RSA *rsa)
        +	{
        +	rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
        +	return(1);
        +	}
        +
        +static int RSA_eay_finish(RSA *rsa)
        +	{
        +	if (rsa->_method_mod_n != NULL)
        +		BN_MONT_CTX_free(rsa->_method_mod_n);
        +	if (rsa->_method_mod_p != NULL)
        +		BN_MONT_CTX_free(rsa->_method_mod_p);
        +	if (rsa->_method_mod_q != NULL)
        +		BN_MONT_CTX_free(rsa->_method_mod_q);
        +	return(1);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_err.c b/vendor/openssl/openssl/crypto/rsa/rsa_err.c
        new file mode 100644
        index 000000000..46e0bf998
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_err.c
        @@ -0,0 +1,209 @@
        +/* crypto/rsa/rsa_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/rsa.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
        +
        +static ERR_STRING_DATA RSA_str_functs[]=
        +	{
        +{ERR_FUNC(RSA_F_CHECK_PADDING_MD),	"CHECK_PADDING_MD"},
        +{ERR_FUNC(RSA_F_DO_RSA_PRINT),	"DO_RSA_PRINT"},
        +{ERR_FUNC(RSA_F_INT_RSA_VERIFY),	"INT_RSA_VERIFY"},
        +{ERR_FUNC(RSA_F_MEMORY_LOCK),	"MEMORY_LOCK"},
        +{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE),	"OLD_RSA_PRIV_DECODE"},
        +{ERR_FUNC(RSA_F_PKEY_RSA_CTRL),	"PKEY_RSA_CTRL"},
        +{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR),	"PKEY_RSA_CTRL_STR"},
        +{ERR_FUNC(RSA_F_PKEY_RSA_SIGN),	"PKEY_RSA_SIGN"},
        +{ERR_FUNC(RSA_F_PKEY_RSA_VERIFY),	"PKEY_RSA_VERIFY"},
        +{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER),	"PKEY_RSA_VERIFYRECOVER"},
        +{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
        +{ERR_FUNC(RSA_F_RSA_CHECK_KEY),	"RSA_check_key"},
        +{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT),	"RSA_EAY_PRIVATE_DECRYPT"},
        +{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT),	"RSA_EAY_PRIVATE_ENCRYPT"},
        +{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT),	"RSA_EAY_PUBLIC_DECRYPT"},
        +{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT),	"RSA_EAY_PUBLIC_ENCRYPT"},
        +{ERR_FUNC(RSA_F_RSA_GENERATE_KEY),	"RSA_generate_key"},
        +{ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX),	"RSA_generate_key_ex"},
        +{ERR_FUNC(RSA_F_RSA_ITEM_VERIFY),	"RSA_ITEM_VERIFY"},
        +{ERR_FUNC(RSA_F_RSA_MEMORY_LOCK),	"RSA_memory_lock"},
        +{ERR_FUNC(RSA_F_RSA_NEW_METHOD),	"RSA_new_method"},
        +{ERR_FUNC(RSA_F_RSA_NULL),	"RSA_NULL"},
        +{ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP),	"RSA_NULL_MOD_EXP"},
        +{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT),	"RSA_NULL_PRIVATE_DECRYPT"},
        +{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT),	"RSA_NULL_PRIVATE_ENCRYPT"},
        +{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT),	"RSA_NULL_PUBLIC_DECRYPT"},
        +{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT),	"RSA_NULL_PUBLIC_ENCRYPT"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE),	"RSA_padding_add_none"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP),	"RSA_padding_add_PKCS1_OAEP"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS),	"RSA_padding_add_PKCS1_PSS"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1),	"RSA_padding_add_PKCS1_PSS_mgf1"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1),	"RSA_padding_add_PKCS1_type_1"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2),	"RSA_padding_add_PKCS1_type_2"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23),	"RSA_padding_add_SSLv23"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931),	"RSA_padding_add_X931"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE),	"RSA_padding_check_none"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP),	"RSA_padding_check_PKCS1_OAEP"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1),	"RSA_padding_check_PKCS1_type_1"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2),	"RSA_padding_check_PKCS1_type_2"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23),	"RSA_padding_check_SSLv23"},
        +{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931),	"RSA_padding_check_X931"},
        +{ERR_FUNC(RSA_F_RSA_PRINT),	"RSA_print"},
        +{ERR_FUNC(RSA_F_RSA_PRINT_FP),	"RSA_print_fp"},
        +{ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT),	"RSA_private_decrypt"},
        +{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT),	"RSA_private_encrypt"},
        +{ERR_FUNC(RSA_F_RSA_PRIV_DECODE),	"RSA_PRIV_DECODE"},
        +{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE),	"RSA_PRIV_ENCODE"},
        +{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT),	"RSA_public_decrypt"},
        +{ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT),	"RSA_public_encrypt"},
        +{ERR_FUNC(RSA_F_RSA_PUB_DECODE),	"RSA_PUB_DECODE"},
        +{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING),	"RSA_setup_blinding"},
        +{ERR_FUNC(RSA_F_RSA_SIGN),	"RSA_sign"},
        +{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),	"RSA_sign_ASN1_OCTET_STRING"},
        +{ERR_FUNC(RSA_F_RSA_VERIFY),	"RSA_verify"},
        +{ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING),	"RSA_verify_ASN1_OCTET_STRING"},
        +{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS),	"RSA_verify_PKCS1_PSS"},
        +{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1),	"RSA_verify_PKCS1_PSS_mgf1"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA RSA_str_reasons[]=
        +	{
        +{ERR_REASON(RSA_R_ALGORITHM_MISMATCH)    ,"algorithm mismatch"},
        +{ERR_REASON(RSA_R_BAD_E_VALUE)           ,"bad e value"},
        +{ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT),"bad fixed header decrypt"},
        +{ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT)    ,"bad pad byte count"},
        +{ERR_REASON(RSA_R_BAD_SIGNATURE)         ,"bad signature"},
        +{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01)  ,"block type is not 01"},
        +{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02)  ,"block type is not 02"},
        +{ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN),"data greater than mod len"},
        +{ERR_REASON(RSA_R_DATA_TOO_LARGE)        ,"data too large"},
        +{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
        +{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS),"data too large for modulus"},
        +{ERR_REASON(RSA_R_DATA_TOO_SMALL)        ,"data too small"},
        +{ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE),"data too small for key size"},
        +{ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY),"digest too big for rsa key"},
        +{ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D),"dmp1 not congruent to d"},
        +{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
        +{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
        +{ERR_REASON(RSA_R_FIRST_OCTET_INVALID)   ,"first octet invalid"},
        +{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"},
        +{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"},
        +{ERR_REASON(RSA_R_INVALID_HEADER)        ,"invalid header"},
        +{ERR_REASON(RSA_R_INVALID_KEYBITS)       ,"invalid keybits"},
        +{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
        +{ERR_REASON(RSA_R_INVALID_MGF1_MD)       ,"invalid mgf1 md"},
        +{ERR_REASON(RSA_R_INVALID_PADDING)       ,"invalid padding"},
        +{ERR_REASON(RSA_R_INVALID_PADDING_MODE)  ,"invalid padding mode"},
        +{ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS),"invalid pss parameters"},
        +{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN)   ,"invalid pss saltlen"},
        +{ERR_REASON(RSA_R_INVALID_SALT_LENGTH)   ,"invalid salt length"},
        +{ERR_REASON(RSA_R_INVALID_TRAILER)       ,"invalid trailer"},
        +{ERR_REASON(RSA_R_INVALID_X931_DIGEST)   ,"invalid x931 digest"},
        +{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
        +{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
        +{ERR_REASON(RSA_R_LAST_OCTET_INVALID)    ,"last octet invalid"},
        +{ERR_REASON(RSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
        +{ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD)   ,"non fips rsa method"},
        +{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT)    ,"no public exponent"},
        +{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
        +{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q)  ,"n does not equal p q"},
        +{ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   ,"oaep decoding error"},
        +{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
        +{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
        +{ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  ,"padding check failed"},
        +{ERR_REASON(RSA_R_P_NOT_PRIME)           ,"p not prime"},
        +{ERR_REASON(RSA_R_Q_NOT_PRIME)           ,"q not prime"},
        +{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
        +{ERR_REASON(RSA_R_SLEN_CHECK_FAILED)     ,"salt length check failed"},
        +{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED)  ,"salt length recovery failed"},
        +{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
        +{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
        +{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
        +{ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST)   ,"unknown mask digest"},
        +{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE)  ,"unknown padding type"},
        +{ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST)    ,"unknown pss digest"},
        +{ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM),"unsupported mask algorithm"},
        +{ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER),"unsupported mask parameter"},
        +{ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE),"unsupported signature type"},
        +{ERR_REASON(RSA_R_VALUE_MISSING)         ,"value missing"},
        +{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_RSA_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(RSA_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,RSA_str_functs);
        +		ERR_load_strings(0,RSA_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_gen.c b/vendor/openssl/openssl/crypto/rsa/rsa_gen.c
        new file mode 100644
        index 000000000..42290cce6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_gen.c
        @@ -0,0 +1,234 @@
        +/* crypto/rsa/rsa_gen.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +
        +/* NB: these functions have been "upgraded", the deprecated versions (which are
        + * compatibility wrappers using these functions) are in rsa_depr.c.
        + * - Geoff
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
        +
        +/* NB: this wrapper would normally be placed in rsa_lib.c and the static
        + * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
        + * that we don't introduce a new linker dependency. Eg. any application that
        + * wasn't previously linking object code related to key-generation won't have to
        + * now just because key-generation is part of RSA_METHOD. */
        +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD);
        +		return 0;
        +		}
        +#endif
        +	if(rsa->meth->rsa_keygen)
        +		return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		return FIPS_rsa_generate_key_ex(rsa, bits, e_value, cb);
        +#endif
        +	return rsa_builtin_keygen(rsa, bits, e_value, cb);
        +	}
        +
        +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
        +	{
        +	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
        +	BIGNUM local_r0,local_d,local_p;
        +	BIGNUM *pr0,*d,*p;
        +	int bitsp,bitsq,ok= -1,n=0;
        +	BN_CTX *ctx=NULL;
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) goto err;
        +	BN_CTX_start(ctx);
        +	r0 = BN_CTX_get(ctx);
        +	r1 = BN_CTX_get(ctx);
        +	r2 = BN_CTX_get(ctx);
        +	r3 = BN_CTX_get(ctx);
        +	if (r3 == NULL) goto err;
        +
        +	bitsp=(bits+1)/2;
        +	bitsq=bits-bitsp;
        +
        +	/* We need the RSA components non-NULL */
        +	if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
        +	if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
        +	if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
        +	if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
        +	if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
        +	if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
        +	if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
        +	if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
        +
        +	BN_copy(rsa->e, e_value);
        +
        +	/* generate p and q */
        +	for (;;)
        +		{
        +		if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
        +			goto err;
        +		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
        +		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
        +		if (BN_is_one(r1)) break;
        +		if(!BN_GENCB_call(cb, 2, n++))
        +			goto err;
        +		}
        +	if(!BN_GENCB_call(cb, 3, 0))
        +		goto err;
        +	for (;;)
        +		{
        +		/* When generating ridiculously small keys, we can get stuck
        +		 * continually regenerating the same prime values. Check for
        +		 * this and bail if it happens 3 times. */
        +		unsigned int degenerate = 0;
        +		do
        +			{
        +			if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
        +				goto err;
        +			} while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
        +		if(degenerate == 3)
        +			{
        +			ok = 0; /* we set our own err */
        +			RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
        +			goto err;
        +			}
        +		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
        +		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
        +		if (BN_is_one(r1))
        +			break;
        +		if(!BN_GENCB_call(cb, 2, n++))
        +			goto err;
        +		}
        +	if(!BN_GENCB_call(cb, 3, 1))
        +		goto err;
        +	if (BN_cmp(rsa->p,rsa->q) < 0)
        +		{
        +		tmp=rsa->p;
        +		rsa->p=rsa->q;
        +		rsa->q=tmp;
        +		}
        +
        +	/* calculate n */
        +	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
        +
        +	/* calculate d */
        +	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
        +	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
        +	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		  pr0 = &local_r0;
        +		  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
        +		}
        +	else
        +	  pr0 = r0;
        +	if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;	/* d */
        +
        +	/* set up d for correct BN_FLG_CONSTTIME flag */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		d = &local_d;
        +		BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		d = rsa->d;
        +
        +	/* calculate d mod (p-1) */
        +	if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
        +
        +	/* calculate d mod (q-1) */
        +	if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
        +
        +	/* calculate inverse of q mod p */
        +	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
        +		{
        +		p = &local_p;
        +		BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
        +		}
        +	else
        +		p = rsa->p;
        +	if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
        +
        +	ok=1;
        +err:
        +	if (ok == -1)
        +		{
        +		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
        +		ok=0;
        +		}
        +	if (ctx != NULL)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +
        +	return ok;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_lib.c b/vendor/openssl/openssl/crypto/rsa/rsa_lib.c
        new file mode 100644
        index 000000000..c95ceafc8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_lib.c
        @@ -0,0 +1,333 @@
        +/* crypto/rsa/rsa_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
        +
        +static const RSA_METHOD *default_RSA_meth=NULL;
        +
        +RSA *RSA_new(void)
        +	{
        +	RSA *r=RSA_new_method(NULL);
        +
        +	return r;
        +	}
        +
        +void RSA_set_default_method(const RSA_METHOD *meth)
        +	{
        +	default_RSA_meth = meth;
        +	}
        +
        +const RSA_METHOD *RSA_get_default_method(void)
        +	{
        +	if (default_RSA_meth == NULL)
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return FIPS_rsa_pkcs1_ssleay();
        +		else
        +			return RSA_PKCS1_SSLeay();
        +#else
        +#ifdef RSA_NULL
        +		default_RSA_meth=RSA_null_method();
        +#else
        +		default_RSA_meth=RSA_PKCS1_SSLeay();
        +#endif
        +#endif
        +		}
        +
        +	return default_RSA_meth;
        +	}
        +
        +const RSA_METHOD *RSA_get_method(const RSA *rsa)
        +	{
        +	return rsa->meth;
        +	}
        +
        +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
        +	{
        +	/* NB: The caller is specifically setting a method, so it's not up to us
        +	 * to deal with which ENGINE it comes from. */
        +	const RSA_METHOD *mtmp;
        +	mtmp = rsa->meth;
        +	if (mtmp->finish) mtmp->finish(rsa);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (rsa->engine)
        +		{
        +		ENGINE_finish(rsa->engine);
        +		rsa->engine = NULL;
        +		}
        +#endif
        +	rsa->meth = meth;
        +	if (meth->init) meth->init(rsa);
        +	return 1;
        +	}
        +
        +RSA *RSA_new_method(ENGINE *engine)
        +	{
        +	RSA *ret;
        +
        +	ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
        +	if (ret == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	ret->meth = RSA_get_default_method();
        +#ifndef OPENSSL_NO_ENGINE
        +	if (engine)
        +		{
        +		if (!ENGINE_init(engine))
        +			{
        +			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		ret->engine = engine;
        +		}
        +	else
        +		ret->engine = ENGINE_get_default_RSA();
        +	if(ret->engine)
        +		{
        +		ret->meth = ENGINE_get_RSA(ret->engine);
        +		if(!ret->meth)
        +			{
        +			RSAerr(RSA_F_RSA_NEW_METHOD,
        +				ERR_R_ENGINE_LIB);
        +			ENGINE_finish(ret->engine);
        +			OPENSSL_free(ret);
        +			return NULL;
        +			}
        +		}
        +#endif
        +
        +	ret->pad=0;
        +	ret->version=0;
        +	ret->n=NULL;
        +	ret->e=NULL;
        +	ret->d=NULL;
        +	ret->p=NULL;
        +	ret->q=NULL;
        +	ret->dmp1=NULL;
        +	ret->dmq1=NULL;
        +	ret->iqmp=NULL;
        +	ret->references=1;
        +	ret->_method_mod_n=NULL;
        +	ret->_method_mod_p=NULL;
        +	ret->_method_mod_q=NULL;
        +	ret->blinding=NULL;
        +	ret->mt_blinding=NULL;
        +	ret->bignum_data=NULL;
        +	ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
        +	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +	if (ret->engine)
        +		ENGINE_finish(ret->engine);
        +#endif
        +		OPENSSL_free(ret);
        +		return(NULL);
        +		}
        +
        +	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
        +		{
        +#ifndef OPENSSL_NO_ENGINE
        +		if (ret->engine)
        +			ENGINE_finish(ret->engine);
        +#endif
        +		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
        +		OPENSSL_free(ret);
        +		ret=NULL;
        +		}
        +	return(ret);
        +	}
        +
        +void RSA_free(RSA *r)
        +	{
        +	int i;
        +
        +	if (r == NULL) return;
        +
        +	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
        +#ifdef REF_PRINT
        +	REF_PRINT("RSA",r);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"RSA_free, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +
        +	if (r->meth->finish)
        +		r->meth->finish(r);
        +#ifndef OPENSSL_NO_ENGINE
        +	if (r->engine)
        +		ENGINE_finish(r->engine);
        +#endif
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
        +
        +	if (r->n != NULL) BN_clear_free(r->n);
        +	if (r->e != NULL) BN_clear_free(r->e);
        +	if (r->d != NULL) BN_clear_free(r->d);
        +	if (r->p != NULL) BN_clear_free(r->p);
        +	if (r->q != NULL) BN_clear_free(r->q);
        +	if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
        +	if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
        +	if (r->iqmp != NULL) BN_clear_free(r->iqmp);
        +	if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
        +	if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
        +	if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
        +	OPENSSL_free(r);
        +	}
        +
        +int RSA_up_ref(RSA *r)
        +	{
        +	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
        +#ifdef REF_PRINT
        +	REF_PRINT("RSA",r);
        +#endif
        +#ifdef REF_CHECK
        +	if (i < 2)
        +		{
        +		fprintf(stderr, "RSA_up_ref, bad reference count\n");
        +		abort();
        +		}
        +#endif
        +	return ((i > 1) ? 1 : 0);
        +	}
        +
        +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +        {
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
        +				new_func, dup_func, free_func);
        +        }
        +
        +int RSA_set_ex_data(RSA *r, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
        +	}
        +
        +void *RSA_get_ex_data(const RSA *r, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&r->ex_data,idx));
        +	}
        +
        +int RSA_memory_lock(RSA *r)
        +	{
        +	int i,j,k,off;
        +	char *p;
        +	BIGNUM *bn,**t[6],*b;
        +	BN_ULONG *ul;
        +
        +	if (r->d == NULL) return(1);
        +	t[0]= &r->d;
        +	t[1]= &r->p;
        +	t[2]= &r->q;
        +	t[3]= &r->dmp1;
        +	t[4]= &r->dmq1;
        +	t[5]= &r->iqmp;
        +	k=sizeof(BIGNUM)*6;
        +	off=k/sizeof(BN_ULONG)+1;
        +	j=1;
        +	for (i=0; i<6; i++)
        +		j+= (*t[i])->top;
        +	if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	bn=(BIGNUM *)p;
        +	ul=(BN_ULONG *)&(p[off]);
        +	for (i=0; i<6; i++)
        +		{
        +		b= *(t[i]);
        +		*(t[i])= &(bn[i]);
        +		memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
        +		bn[i].flags=BN_FLG_STATIC_DATA;
        +		bn[i].d=ul;
        +		memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
        +		ul+=b->top;
        +		BN_clear_free(b);
        +		}
        +	
        +	/* I should fix this so it can still be done */
        +	r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
        +
        +	r->bignum_data=p;
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_locl.h b/vendor/openssl/openssl/crypto/rsa/rsa_locl.h
        new file mode 100644
        index 000000000..f5d2d5662
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_locl.h
        @@ -0,0 +1,4 @@
        +extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
        +		unsigned char *rm, size_t *prm_len,
        +		const unsigned char *sigbuf, size_t siglen,
        +		RSA *rsa);
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_none.c b/vendor/openssl/openssl/crypto/rsa/rsa_none.c
        new file mode 100644
        index 000000000..e6f3e627c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_none.c
        @@ -0,0 +1,98 @@
        +/* crypto/rsa/rsa_none.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +
        +int RSA_padding_add_none(unsigned char *to, int tlen,
        +	const unsigned char *from, int flen)
        +	{
        +	if (flen > tlen)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		return(0);
        +		}
        +
        +	if (flen < tlen)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
        +		return(0);
        +		}
        +	
        +	memcpy(to,from,(unsigned int)flen);
        +	return(1);
        +	}
        +
        +int RSA_padding_check_none(unsigned char *to, int tlen,
        +	const unsigned char *from, int flen, int num)
        +	{
        +
        +	if (flen > tlen)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_NONE,RSA_R_DATA_TOO_LARGE);
        +		return(-1);
        +		}
        +
        +	memset(to,0,tlen-flen);
        +	memcpy(to+tlen-flen,from,flen);
        +	return(tlen);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_null.c b/vendor/openssl/openssl/crypto/rsa/rsa_null.c
        new file mode 100644
        index 000000000..2f2202f14
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_null.c
        @@ -0,0 +1,151 @@
        +/* rsa_null.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +
        +/* This is a dummy RSA implementation that just returns errors when called.
        + * It is designed to allow some RSA functions to work while stopping those
        + * covered by the RSA patent. That is RSA, encryption, decryption, signing
        + * and verify is not allowed but RSA key generation, key checking and other
        + * operations (like storing RSA keys) are permitted.
        + */
        +
        +static int RSA_null_public_encrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_null_private_encrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_null_public_decrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int RSA_null_private_decrypt(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +#if 0 /* not currently used */
        +static int RSA_null_mod_exp(const BIGNUM *r0, const BIGNUM *i, RSA *rsa);
        +#endif
        +static int RSA_null_init(RSA *rsa);
        +static int RSA_null_finish(RSA *rsa);
        +static RSA_METHOD rsa_null_meth={
        +	"Null RSA",
        +	RSA_null_public_encrypt,
        +	RSA_null_public_decrypt,
        +	RSA_null_private_encrypt,
        +	RSA_null_private_decrypt,
        +	NULL,
        +	NULL,
        +	RSA_null_init,
        +	RSA_null_finish,
        +	0,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +const RSA_METHOD *RSA_null_method(void)
        +	{
        +	return(&rsa_null_meth);
        +	}
        +
        +static int RSA_null_public_encrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
        +	return -1;
        +	}
        +
        +static int RSA_null_private_encrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
        +	return -1;
        +	}
        +
        +static int RSA_null_private_decrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
        +	return -1;
        +	}
        +
        +static int RSA_null_public_decrypt(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +	RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
        +	return -1;
        +	}
        +
        +#if 0 /* not currently used */
        +static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
        +	{
        +	...err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
        +	return -1;
        +	}
        +#endif
        +
        +static int RSA_null_init(RSA *rsa)
        +	{
        +	return(1);
        +	}
        +
        +static int RSA_null_finish(RSA *rsa)
        +	{
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_oaep.c b/vendor/openssl/openssl/crypto/rsa/rsa_oaep.c
        new file mode 100644
        index 000000000..af4d24a56
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_oaep.c
        @@ -0,0 +1,235 @@
        +/* crypto/rsa/rsa_oaep.c */
        +/* Written by Ulf Moeller. This software is distributed on an "AS IS"
        +   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
        +
        +/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
        +
        +/* See Victor Shoup, "OAEP reconsidered," Nov. 2000,
        + * <URL: http://www.shoup.net/papers/oaep.ps.Z>
        + * for problems with the security proof for the
        + * original OAEP scheme, which EME-OAEP is based on.
        + * 
        + * A new proof can be found in E. Fujisaki, T. Okamoto,
        + * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!",
        + * Dec. 2000, <URL: http://eprint.iacr.org/2000/061/>.
        + * The new proof has stronger requirements for the
        + * underlying permutation: "partial-one-wayness" instead
        + * of one-wayness.  For the RSA function, this is
        + * an equivalent notion.
        + */
        +
        +
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/sha.h>
        +
        +static int MGF1(unsigned char *mask, long len,
        +	const unsigned char *seed, long seedlen);
        +
        +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
        +	const unsigned char *from, int flen,
        +	const unsigned char *param, int plen)
        +	{
        +	int i, emlen = tlen - 1;
        +	unsigned char *db, *seed;
        +	unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
        +
        +	if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
        +		   RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		return 0;
        +		}
        +
        +	if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
        +		return 0;
        +		}
        +
        +	to[0] = 0;
        +	seed = to + 1;
        +	db = to + SHA_DIGEST_LENGTH + 1;
        +
        +	if (!EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL))
        +		return 0;
        +	memset(db + SHA_DIGEST_LENGTH, 0,
        +		emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
        +	db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
        +	memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
        +	if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
        +		return 0;
        +#ifdef PKCS_TESTVECT
        +	memcpy(seed,
        +	   "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
        +	   20);
        +#endif
        +
        +	dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
        +	if (dbmask == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0)
        +		return 0;
        +	for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
        +		db[i] ^= dbmask[i];
        +
        +	if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0)
        +		return 0;
        +	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
        +		seed[i] ^= seedmask[i];
        +
        +	OPENSSL_free(dbmask);
        +	return 1;
        +	}
        +
        +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
        +	const unsigned char *from, int flen, int num,
        +	const unsigned char *param, int plen)
        +	{
        +	int i, dblen, mlen = -1;
        +	const unsigned char *maskeddb;
        +	int lzero;
        +	unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
        +	unsigned char *padded_from;
        +	int bad = 0;
        +
        +	if (--num < 2 * SHA_DIGEST_LENGTH + 1)
        +		/* 'num' is the length of the modulus, i.e. does not depend on the
        +		 * particular ciphertext. */
        +		goto decoding_err;
        +
        +	lzero = num - flen;
        +	if (lzero < 0)
        +		{
        +		/* signalling this error immediately after detection might allow
        +		 * for side-channel attacks (e.g. timing if 'plen' is huge
        +		 * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
        +		 * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
        +		 * so we use a 'bad' flag */
        +		bad = 1;
        +		lzero = 0;
        +		flen = num; /* don't overflow the memcpy to padded_from */
        +		}
        +
        +	dblen = num - SHA_DIGEST_LENGTH;
        +	db = OPENSSL_malloc(dblen + num);
        +	if (db == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
        +		return -1;
        +		}
        +
        +	/* Always do this zero-padding copy (even when lzero == 0)
        +	 * to avoid leaking timing info about the value of lzero. */
        +	padded_from = db + dblen;
        +	memset(padded_from, 0, lzero);
        +	memcpy(padded_from + lzero, from, flen);
        +
        +	maskeddb = padded_from + SHA_DIGEST_LENGTH;
        +
        +	if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
        +		return -1;
        +	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
        +		seed[i] ^= padded_from[i];
        +  
        +	if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
        +		return -1;
        +	for (i = 0; i < dblen; i++)
        +		db[i] ^= maskeddb[i];
        +
        +	if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
        +		return -1;
        +
        +	if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
        +		goto decoding_err;
        +	else
        +		{
        +		for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
        +			if (db[i] != 0x00)
        +				break;
        +		if (i == dblen || db[i] != 0x01)
        +			goto decoding_err;
        +		else
        +			{
        +			/* everything looks OK */
        +
        +			mlen = dblen - ++i;
        +			if (tlen < mlen)
        +				{
        +				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
        +				mlen = -1;
        +				}
        +			else
        +				memcpy(to, db + i, mlen);
        +			}
        +		}
        +	OPENSSL_free(db);
        +	return mlen;
        +
        +decoding_err:
        +	/* to avoid chosen ciphertext attacks, the error message should not reveal
        +	 * which kind of decoding error happened */
        +	RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
        +	if (db != NULL) OPENSSL_free(db);
        +	return -1;
        +	}
        +
        +int PKCS1_MGF1(unsigned char *mask, long len,
        +	const unsigned char *seed, long seedlen, const EVP_MD *dgst)
        +	{
        +	long i, outlen = 0;
        +	unsigned char cnt[4];
        +	EVP_MD_CTX c;
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +	int mdlen;
        +	int rv = -1;
        +
        +	EVP_MD_CTX_init(&c);
        +	mdlen = EVP_MD_size(dgst);
        +	if (mdlen < 0)
        +		goto err;
        +	for (i = 0; outlen < len; i++)
        +		{
        +		cnt[0] = (unsigned char)((i >> 24) & 255);
        +		cnt[1] = (unsigned char)((i >> 16) & 255);
        +		cnt[2] = (unsigned char)((i >> 8)) & 255;
        +		cnt[3] = (unsigned char)(i & 255);
        +		if (!EVP_DigestInit_ex(&c,dgst, NULL)
        +			|| !EVP_DigestUpdate(&c, seed, seedlen)
        +			|| !EVP_DigestUpdate(&c, cnt, 4))
        +			goto err;
        +		if (outlen + mdlen <= len)
        +			{
        +			if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
        +				goto err;
        +			outlen += mdlen;
        +			}
        +		else
        +			{
        +			if (!EVP_DigestFinal_ex(&c, md, NULL))
        +				goto err;
        +			memcpy(mask + outlen, md, len - outlen);
        +			outlen = len;
        +			}
        +		}
        +	rv = 0;
        +	err:
        +	EVP_MD_CTX_cleanup(&c);
        +	return rv;
        +	}
        +
        +static int MGF1(unsigned char *mask, long len, const unsigned char *seed,
        +		 long seedlen)
        +	{
        +	return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_pk1.c b/vendor/openssl/openssl/crypto/rsa/rsa_pk1.c
        new file mode 100644
        index 000000000..8560755f1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_pk1.c
        @@ -0,0 +1,224 @@
        +/* crypto/rsa/rsa_pk1.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +
        +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
        +	     const unsigned char *from, int flen)
        +	{
        +	int j;
        +	unsigned char *p;
        +
        +	if (flen > (tlen-RSA_PKCS1_PADDING_SIZE))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		return(0);
        +		}
        +	
        +	p=(unsigned char *)to;
        +
        +	*(p++)=0;
        +	*(p++)=1; /* Private Key BT (Block Type) */
        +
        +	/* pad out with 0xff data */
        +	j=tlen-3-flen;
        +	memset(p,0xff,j);
        +	p+=j;
        +	*(p++)='\0';
        +	memcpy(p,from,(unsigned int)flen);
        +	return(1);
        +	}
        +
        +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
        +	     const unsigned char *from, int flen, int num)
        +	{
        +	int i,j;
        +	const unsigned char *p;
        +
        +	p=from;
        +	if ((num != (flen+1)) || (*(p++) != 01))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01);
        +		return(-1);
        +		}
        +
        +	/* scan over padding data */
        +	j=flen-1; /* one for type. */
        +	for (i=0; i<j; i++)
        +		{
        +		if (*p != 0xff) /* should decrypt to 0xff */
        +			{
        +			if (*p == 0)
        +				{ p++; break; }
        +			else	{
        +				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_FIXED_HEADER_DECRYPT);
        +				return(-1);
        +				}
        +			}
        +		p++;
        +		}
        +
        +	if (i == j)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_NULL_BEFORE_BLOCK_MISSING);
        +		return(-1);
        +		}
        +
        +	if (i < 8)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_PAD_BYTE_COUNT);
        +		return(-1);
        +		}
        +	i++; /* Skip over the '\0' */
        +	j-=i;
        +	if (j > tlen)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE);
        +		return(-1);
        +		}
        +	memcpy(to,p,(unsigned int)j);
        +
        +	return(j);
        +	}
        +
        +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
        +	     const unsigned char *from, int flen)
        +	{
        +	int i,j;
        +	unsigned char *p;
        +	
        +	if (flen > (tlen-11))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		return(0);
        +		}
        +	
        +	p=(unsigned char *)to;
        +
        +	*(p++)=0;
        +	*(p++)=2; /* Public Key BT (Block Type) */
        +
        +	/* pad out with non-zero random data */
        +	j=tlen-3-flen;
        +
        +	if (RAND_bytes(p,j) <= 0)
        +		return(0);
        +	for (i=0; i<j; i++)
        +		{
        +		if (*p == '\0')
        +			do	{
        +				if (RAND_bytes(p,1) <= 0)
        +					return(0);
        +				} while (*p == '\0');
        +		p++;
        +		}
        +
        +	*(p++)='\0';
        +
        +	memcpy(p,from,(unsigned int)flen);
        +	return(1);
        +	}
        +
        +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
        +	     const unsigned char *from, int flen, int num)
        +	{
        +	int i,j;
        +	const unsigned char *p;
        +
        +	p=from;
        +	if ((num != (flen+1)) || (*(p++) != 02))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02);
        +		return(-1);
        +		}
        +#ifdef PKCS1_CHECK
        +	return(num-11);
        +#endif
        +
        +	/* scan over padding data */
        +	j=flen-1; /* one for type. */
        +	for (i=0; i<j; i++)
        +		if (*(p++) == 0) break;
        +
        +	if (i == j)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
        +		return(-1);
        +		}
        +
        +	if (i < 8)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT);
        +		return(-1);
        +		}
        +	i++; /* Skip over the '\0' */
        +	j-=i;
        +	if (j > tlen)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE);
        +		return(-1);
        +		}
        +	memcpy(to,p,(unsigned int)j);
        +
        +	return(j);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_pmeth.c b/vendor/openssl/openssl/crypto/rsa/rsa_pmeth.c
        new file mode 100644
        index 000000000..5b2ecf56a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_pmeth.c
        @@ -0,0 +1,723 @@
        +/* crypto/rsa/rsa_pmeth.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/rsa.h>
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_CMS
        +#include <openssl/cms.h>
        +#endif
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +#include "evp_locl.h"
        +#include "rsa_locl.h"
        +
        +/* RSA pkey context structure */
        +
        +typedef struct
        +	{
        +	/* Key gen parameters */
        +	int nbits;
        +	BIGNUM *pub_exp;
        +	/* Keygen callback info */
        +	int gentmp[2];
        +	/* RSA padding mode */
        +	int pad_mode;
        +	/* message digest */
        +	const EVP_MD *md;
        +	/* message digest for MGF1 */
        +	const EVP_MD *mgf1md;
        +	/* PSS/OAEP salt length */
        +	int saltlen;
        +	/* Temp buffer */
        +	unsigned char *tbuf;
        +	} RSA_PKEY_CTX;
        +
        +static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
        +	{
        +	RSA_PKEY_CTX *rctx;
        +	rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
        +	if (!rctx)
        +		return 0;
        +	rctx->nbits = 1024;
        +	rctx->pub_exp = NULL;
        +	rctx->pad_mode = RSA_PKCS1_PADDING;
        +	rctx->md = NULL;
        +	rctx->mgf1md = NULL;
        +	rctx->tbuf = NULL;
        +
        +	rctx->saltlen = -2;
        +
        +	ctx->data = rctx;
        +	ctx->keygen_info = rctx->gentmp;
        +	ctx->keygen_info_count = 2;
        +	
        +	return 1;
        +	}
        +
        +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	RSA_PKEY_CTX *dctx, *sctx;
        +	if (!pkey_rsa_init(dst))
        +		return 0;
        +       	sctx = src->data;
        +	dctx = dst->data;
        +	dctx->nbits = sctx->nbits;
        +	if (sctx->pub_exp)
        +		{
        +		dctx->pub_exp = BN_dup(sctx->pub_exp);
        +		if (!dctx->pub_exp)
        +			return 0;
        +		}
        +	dctx->pad_mode = sctx->pad_mode;
        +	dctx->md = sctx->md;
        +	return 1;
        +	}
        +
        +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
        +	{
        +	if (ctx->tbuf)
        +		return 1;
        +	ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
        +	if (!ctx->tbuf)
        +		return 0;
        +	return 1;
        +	}
        +
        +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
        +	{
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	if (rctx)
        +		{
        +		if (rctx->pub_exp)
        +			BN_free(rctx->pub_exp);
        +		if (rctx->tbuf)
        +			OPENSSL_free(rctx->tbuf);
        +		OPENSSL_free(rctx);
        +		}
        +	}
        +#ifdef OPENSSL_FIPS
        +/* FIP checker. Return value indicates status of context parameters:
        + * 1  : redirect to FIPS.
        + * 0  : don't redirect to FIPS.
        + * -1 : illegal operation in FIPS mode.
        + */
        +
        +static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx)
        +	{
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	RSA *rsa = ctx->pkey->pkey.rsa;
        +	int rv = -1;
        +	if (!FIPS_mode())
        +		return 0;
        +	if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
        +		rv = 0;
        +	if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv)
        +		return -1;
        +	if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS))
        +		return rv;
        +	if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS))
        +		return rv;
        +	return 1;
        +	}
        +#endif
        +
        +static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +					const unsigned char *tbs, size_t tbslen)
        +	{
        +	int ret;
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	RSA *rsa = ctx->pkey->pkey.rsa;
        +
        +#ifdef OPENSSL_FIPS
        +	ret = pkey_fips_check_ctx(ctx);
        +	if (ret < 0)
        +		{
        +		RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
        +		return -1;
        +		}
        +#endif
        +
        +	if (rctx->md)
        +		{
        +		if (tbslen != (size_t)EVP_MD_size(rctx->md))
        +			{
        +			RSAerr(RSA_F_PKEY_RSA_SIGN,
        +					RSA_R_INVALID_DIGEST_LENGTH);
        +			return -1;
        +			}
        +#ifdef OPENSSL_FIPS
        +		if (ret > 0)
        +			{
        +			unsigned int slen;
        +			ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md,
        +							rctx->pad_mode,
        +							rctx->saltlen,
        +							rctx->mgf1md,
        +							sig, &slen);
        +			if (ret > 0)
        +				*siglen = slen;
        +			else
        +				*siglen = 0;
        +			return ret;
        +			}
        +#endif
        +
        +		if (EVP_MD_type(rctx->md) == NID_mdc2)
        +			{
        +			unsigned int sltmp;
        +			if (rctx->pad_mode != RSA_PKCS1_PADDING)
        +				return -1;
        +			ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2,
        +						tbs, tbslen, sig, &sltmp, rsa);
        +
        +			if (ret <= 0)
        +				return ret;
        +			ret = sltmp;
        +			}
        +		else if (rctx->pad_mode == RSA_X931_PADDING)
        +			{
        +			if (!setup_tbuf(rctx, ctx))
        +				return -1;
        +			memcpy(rctx->tbuf, tbs, tbslen);
        +			rctx->tbuf[tbslen] =
        +				RSA_X931_hash_id(EVP_MD_type(rctx->md));
        +			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
        +						sig, rsa, RSA_X931_PADDING);
        +			}
        +		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
        +			{
        +			unsigned int sltmp;
        +			ret = RSA_sign(EVP_MD_type(rctx->md),
        +						tbs, tbslen, sig, &sltmp, rsa);
        +			if (ret <= 0)
        +				return ret;
        +			ret = sltmp;
        +			}
        +		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
        +			{
        +			if (!setup_tbuf(rctx, ctx))
        +				return -1;
        +			if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa,
        +						rctx->tbuf, tbs,
        +						rctx->md, rctx->mgf1md,
        +						rctx->saltlen))
        +				return -1;
        +			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
        +						sig, rsa, RSA_NO_PADDING);
        +			}
        +		else
        +			return -1;
        +		}
        +	else
        +		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
        +							rctx->pad_mode);
        +	if (ret < 0)
        +		return ret;
        +	*siglen = ret;
        +	return 1;
        +	}
        +
        +
        +static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
        +					unsigned char *rout, size_t *routlen,
        +					const unsigned char *sig, size_t siglen)
        +	{
        +	int ret;
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +
        +	if (rctx->md)
        +		{
        +		if (rctx->pad_mode == RSA_X931_PADDING)
        +			{
        +			if (!setup_tbuf(rctx, ctx))
        +				return -1;
        +			ret = RSA_public_decrypt(siglen, sig,
        +						rctx->tbuf, ctx->pkey->pkey.rsa,
        +						RSA_X931_PADDING);
        +			if (ret < 1)
        +				return 0;
        +			ret--;
        +			if (rctx->tbuf[ret] !=
        +				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
        +				{
        +				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
        +						RSA_R_ALGORITHM_MISMATCH);
        +				return 0;
        +				}
        +			if (ret != EVP_MD_size(rctx->md))
        +				{
        +				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
        +					RSA_R_INVALID_DIGEST_LENGTH);
        +				return 0;
        +				}
        +			if (rout)
        +				memcpy(rout, rctx->tbuf, ret);
        +			}
        +		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
        +			{
        +			size_t sltmp;
        +			ret = int_rsa_verify(EVP_MD_type(rctx->md),
        +						NULL, 0, rout, &sltmp,
        +					sig, siglen, ctx->pkey->pkey.rsa);
        +			if (ret <= 0)
        +				return 0;
        +			ret = sltmp;
        +			}
        +		else
        +			return -1;
        +		}
        +	else
        +		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
        +							rctx->pad_mode);
        +	if (ret < 0)
        +		return ret;
        +	*routlen = ret;
        +	return 1;
        +	}
        +
        +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
        +					const unsigned char *sig, size_t siglen,
        +					const unsigned char *tbs, size_t tbslen)
        +	{
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	RSA *rsa = ctx->pkey->pkey.rsa;
        +	size_t rslen;
        +#ifdef OPENSSL_FIPS
        +	int rv;
        +	rv = pkey_fips_check_ctx(ctx);
        +	if (rv < 0)
        +		{
        +		RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
        +		return -1;
        +		}
        +#endif
        +	if (rctx->md)
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (rv > 0)
        +			{
        +			return FIPS_rsa_verify_digest(rsa,
        +							tbs, tbslen,
        +							rctx->md,
        +							rctx->pad_mode,
        +							rctx->saltlen,
        +							rctx->mgf1md,
        +							sig, siglen);
        +							
        +			}
        +#endif
        +		if (rctx->pad_mode == RSA_PKCS1_PADDING)
        +			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
        +					sig, siglen, rsa);
        +		if (rctx->pad_mode == RSA_X931_PADDING)
        +			{
        +			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
        +					sig, siglen) <= 0)
        +				return 0;
        +			}
        +		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
        +			{
        +			int ret;
        +			if (!setup_tbuf(rctx, ctx))
        +				return -1;
        +			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
        +							rsa, RSA_NO_PADDING);
        +			if (ret <= 0)
        +				return 0;
        +			ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
        +						rctx->md, rctx->mgf1md,
        +						rctx->tbuf, rctx->saltlen);
        +			if (ret <= 0)
        +				return 0;
        +			return 1;
        +			}
        +		else
        +			return -1;
        +		}
        +	else
        +		{
        +		if (!setup_tbuf(rctx, ctx))
        +			return -1;
        +		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
        +						rsa, rctx->pad_mode);
        +		if (rslen == 0)
        +			return 0;
        +		}
        +
        +	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
        +		return 0;
        +
        +	return 1;
        +			
        +	}
        +	
        +
        +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
        +					unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen)
        +	{
        +	int ret;
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
        +							rctx->pad_mode);
        +	if (ret < 0)
        +		return ret;
        +	*outlen = ret;
        +	return 1;
        +	}
        +
        +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
        +					unsigned char *out, size_t *outlen,
        +					const unsigned char *in, size_t inlen)
        +	{
        +	int ret;
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
        +							rctx->pad_mode);
        +	if (ret < 0)
        +		return ret;
        +	*outlen = ret;
        +	return 1;
        +	}
        +
        +static int check_padding_md(const EVP_MD *md, int padding)
        +	{
        +	if (!md)
        +		return 1;
        +
        +	if (padding == RSA_NO_PADDING)
        +		{
        +		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
        +		return 0;
        +		}
        +
        +	if (padding == RSA_X931_PADDING)
        +		{
        +		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
        +			{
        +			RSAerr(RSA_F_CHECK_PADDING_MD,
        +						RSA_R_INVALID_X931_DIGEST);
        +			return 0;
        +			}
        +		return 1;
        +		}
        +
        +	return 1;
        +	}
        +			
        +
        +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	switch (type)
        +		{
        +		case EVP_PKEY_CTRL_RSA_PADDING:
        +		if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
        +			{
        +			if (!check_padding_md(rctx->md, p1))
        +				return 0;
        +			if (p1 == RSA_PKCS1_PSS_PADDING) 
        +				{
        +				if (!(ctx->operation &
        +				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
        +					goto bad_pad;
        +				if (!rctx->md)
        +					rctx->md = EVP_sha1();
        +				}
        +			if (p1 == RSA_PKCS1_OAEP_PADDING) 
        +				{
        +				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
        +					goto bad_pad;
        +				if (!rctx->md)
        +					rctx->md = EVP_sha1();
        +				}
        +			rctx->pad_mode = p1;
        +			return 1;
        +			}
        +		bad_pad:
        +		RSAerr(RSA_F_PKEY_RSA_CTRL,
        +				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
        +		return -2;
        +
        +		case EVP_PKEY_CTRL_GET_RSA_PADDING:
        +		*(int *)p2 = rctx->pad_mode;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
        +		case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
        +		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
        +			{
        +			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
        +			return -2;
        +			}
        +		if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
        +			*(int *)p2 = rctx->saltlen;
        +		else
        +			{
        +			if (p1 < -2)
        +				return -2;
        +			rctx->saltlen = p1;
        +			}
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
        +		if (p1 < 256)
        +			{
        +			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
        +			return -2;
        +			}
        +		rctx->nbits = p1;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
        +		if (!p2)
        +			return -2;
        +		rctx->pub_exp = p2;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_MD:
        +		if (!check_padding_md(p2, rctx->pad_mode))
        +			return 0;
        +		rctx->md = p2;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_RSA_MGF1_MD:
        +		case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
        +		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
        +			{
        +			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
        +			return -2;
        +			}
        +		if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD)
        +			{
        +			if (rctx->mgf1md)
        +				*(const EVP_MD **)p2 = rctx->mgf1md;
        +			else
        +				*(const EVP_MD **)p2 = rctx->md;
        +			}
        +		else
        +			rctx->mgf1md = p2;
        +		return 1;
        +
        +		case EVP_PKEY_CTRL_DIGESTINIT:
        +		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
        +		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
        +		case EVP_PKEY_CTRL_PKCS7_SIGN:
        +		return 1;
        +#ifndef OPENSSL_NO_CMS
        +		case EVP_PKEY_CTRL_CMS_DECRYPT:
        +		{
        +		X509_ALGOR *alg = NULL;
        +		ASN1_OBJECT *encalg = NULL;
        +		if (p2)
        +			CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg);
        +		if (alg)
        +			X509_ALGOR_get0(&encalg, NULL, NULL, alg);
        +		if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep)
        +			rctx->pad_mode = RSA_PKCS1_OAEP_PADDING;
        +		}
        +		case EVP_PKEY_CTRL_CMS_ENCRYPT:
        +		case EVP_PKEY_CTRL_CMS_SIGN:
        +		return 1;
        +#endif
        +		case EVP_PKEY_CTRL_PEER_KEY:
        +			RSAerr(RSA_F_PKEY_RSA_CTRL,
        +			RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        +			return -2;	
        +
        +		default:
        +		return -2;
        +
        +		}
        +	}
        +			
        +static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
        +			const char *type, const char *value)
        +	{
        +	if (!value)
        +		{
        +		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
        +		return 0;
        +		}
        +	if (!strcmp(type, "rsa_padding_mode"))
        +		{
        +		int pm;
        +		if (!strcmp(value, "pkcs1"))
        +			pm = RSA_PKCS1_PADDING;
        +		else if (!strcmp(value, "sslv23"))
        +			pm = RSA_SSLV23_PADDING;
        +		else if (!strcmp(value, "none"))
        +			pm = RSA_NO_PADDING;
        +		else if (!strcmp(value, "oeap"))
        +			pm = RSA_PKCS1_OAEP_PADDING;
        +		else if (!strcmp(value, "x931"))
        +			pm = RSA_X931_PADDING;
        +		else if (!strcmp(value, "pss"))
        +			pm = RSA_PKCS1_PSS_PADDING;
        +		else
        +			{
        +			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
        +						RSA_R_UNKNOWN_PADDING_TYPE);
        +			return -2;
        +			}
        +		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
        +		}
        +
        +	if (!strcmp(type, "rsa_pss_saltlen"))
        +		{
        +		int saltlen;
        +		saltlen = atoi(value);
        +		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
        +		}
        +
        +	if (!strcmp(type, "rsa_keygen_bits"))
        +		{
        +		int nbits;
        +		nbits = atoi(value);
        +		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
        +		}
        +
        +	if (!strcmp(type, "rsa_keygen_pubexp"))
        +		{
        +		int ret;
        +		BIGNUM *pubexp = NULL;
        +		if (!BN_asc2bn(&pubexp, value))
        +			return 0;
        +		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
        +		if (ret <= 0)
        +			BN_free(pubexp);
        +		return ret;
        +		}
        +
        +	return -2;
        +	}
        +
        +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	RSA *rsa = NULL;
        +	RSA_PKEY_CTX *rctx = ctx->data;
        +	BN_GENCB *pcb, cb;
        +	int ret;
        +	if (!rctx->pub_exp)
        +		{
        +		rctx->pub_exp = BN_new();
        +		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
        +			return 0;
        +		}
        +	rsa = RSA_new();
        +	if (!rsa)
        +		return 0;
        +	if (ctx->pkey_gencb)
        +		{
        +		pcb = &cb;
        +		evp_pkey_set_cb_translate(pcb, ctx);
        +		}
        +	else
        +		pcb = NULL;
        +	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
        +	if (ret > 0)
        +		EVP_PKEY_assign_RSA(pkey, rsa);
        +	else
        +		RSA_free(rsa);
        +	return ret;
        +	}
        +
        +const EVP_PKEY_METHOD rsa_pkey_meth = 
        +	{
        +	EVP_PKEY_RSA,
        +	EVP_PKEY_FLAG_AUTOARGLEN,
        +	pkey_rsa_init,
        +	pkey_rsa_copy,
        +	pkey_rsa_cleanup,
        +
        +	0,0,
        +
        +	0,
        +	pkey_rsa_keygen,
        +
        +	0,
        +	pkey_rsa_sign,
        +
        +	0,
        +	pkey_rsa_verify,
        +
        +	0,
        +	pkey_rsa_verifyrecover,
        +
        +
        +	0,0,0,0,
        +
        +	0,
        +	pkey_rsa_encrypt,
        +
        +	0,
        +	pkey_rsa_decrypt,
        +
        +	0,0,
        +
        +	pkey_rsa_ctrl,
        +	pkey_rsa_ctrl_str
        +
        +
        +	};
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_prn.c b/vendor/openssl/openssl/crypto/rsa/rsa_prn.c
        new file mode 100644
        index 000000000..224db0fae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_prn.c
        @@ -0,0 +1,93 @@
        +/* crypto/rsa/rsa_prn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2006.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +
        +#ifndef OPENSSL_NO_FP_API
        +int RSA_print_fp(FILE *fp, const RSA *x, int off)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file())) == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	ret=RSA_print(b,x,off);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +#endif
        +
        +int RSA_print(BIO *bp, const RSA *x, int off)
        +	{
        +	EVP_PKEY *pk;
        +	int ret;
        +	pk = EVP_PKEY_new();
        +	if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
        +		return 0;
        +	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
        +	EVP_PKEY_free(pk);
        +	return ret;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_pss.c b/vendor/openssl/openssl/crypto/rsa/rsa_pss.c
        new file mode 100644
        index 000000000..5f9f533d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_pss.c
        @@ -0,0 +1,300 @@
        +/* rsa_pss.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2005.
        + */
        +/* ====================================================================
        + * Copyright (c) 2005 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <openssl/sha.h>
        +
        +static const unsigned char zeroes[] = {0,0,0,0,0,0,0,0};
        +
        +#if defined(_MSC_VER) && defined(_ARM_)
        +#pragma optimize("g", off)
        +#endif
        +
        +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
        +			const EVP_MD *Hash, const unsigned char *EM, int sLen)
        +	{
        +	return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
        +	}
        +
        +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
        +			const EVP_MD *Hash, const EVP_MD *mgf1Hash,
        +			const unsigned char *EM, int sLen)
        +	{
        +	int i;
        +	int ret = 0;
        +	int hLen, maskedDBLen, MSBits, emLen;
        +	const unsigned char *H;
        +	unsigned char *DB = NULL;
        +	EVP_MD_CTX ctx;
        +	unsigned char H_[EVP_MAX_MD_SIZE];
        +	EVP_MD_CTX_init(&ctx);
        +
        +	if (mgf1Hash == NULL)
        +		mgf1Hash = Hash;
        +
        +	hLen = EVP_MD_size(Hash);
        +	if (hLen < 0)
        +		goto err;
        +	/*
        +	 * Negative sLen has special meanings:
        +	 *	-1	sLen == hLen
        +	 *	-2	salt length is autorecovered from signature
        +	 *	-N	reserved
        +	 */
        +	if      (sLen == -1)	sLen = hLen;
        +	else if (sLen == -2)	sLen = -2;
        +	else if (sLen < -2)
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
        +		goto err;
        +		}
        +
        +	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
        +	emLen = RSA_size(rsa);
        +	if (EM[0] & (0xFF << MSBits))
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
        +		goto err;
        +		}
        +	if (MSBits == 0)
        +		{
        +		EM++;
        +		emLen--;
        +		}
        +	if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
        +		goto err;
        +		}
        +	if (EM[emLen - 1] != 0xbc)
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
        +		goto err;
        +		}
        +	maskedDBLen = emLen - hLen - 1;
        +	H = EM + maskedDBLen;
        +	DB = OPENSSL_malloc(maskedDBLen);
        +	if (!DB)
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
        +		goto err;
        +	for (i = 0; i < maskedDBLen; i++)
        +		DB[i] ^= EM[i];
        +	if (MSBits)
        +		DB[0] &= 0xFF >> (8 - MSBits);
        +	for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
        +	if (DB[i++] != 0x1)
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
        +		goto err;
        +		}
        +	if (sLen >= 0 && (maskedDBLen - i) != sLen)
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
        +		goto err;
        +		}
        +	if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
        +		|| !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
        +		|| !EVP_DigestUpdate(&ctx, mHash, hLen))
        +		goto err;
        +	if (maskedDBLen - i)
        +		{
        +		if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
        +			goto err;
        +		}
        +	if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
        +		goto err;
        +	if (memcmp(H_, H, hLen))
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
        +		ret = 0;
        +		}
        +	else 
        +		ret = 1;
        +
        +	err:
        +	if (DB)
        +		OPENSSL_free(DB);
        +	EVP_MD_CTX_cleanup(&ctx);
        +
        +	return ret;
        +
        +	}
        +
        +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
        +			const unsigned char *mHash,
        +			const EVP_MD *Hash, int sLen)
        +	{
        +	return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
        +	}
        +
        +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
        +			const unsigned char *mHash,
        +			const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen)
        +	{
        +	int i;
        +	int ret = 0;
        +	int hLen, maskedDBLen, MSBits, emLen;
        +	unsigned char *H, *salt = NULL, *p;
        +	EVP_MD_CTX ctx;
        +
        +	if (mgf1Hash == NULL)
        +		mgf1Hash = Hash;
        +
        +	hLen = EVP_MD_size(Hash);
        +	if (hLen < 0)
        +		goto err;
        +	/*
        +	 * Negative sLen has special meanings:
        +	 *	-1	sLen == hLen
        +	 *	-2	salt length is maximized
        +	 *	-N	reserved
        +	 */
        +	if      (sLen == -1)	sLen = hLen;
        +	else if (sLen == -2)	sLen = -2;
        +	else if (sLen < -2)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
        +		goto err;
        +		}
        +
        +	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
        +	emLen = RSA_size(rsa);
        +	if (MSBits == 0)
        +		{
        +		*EM++ = 0;
        +		emLen--;
        +		}
        +	if (sLen == -2)
        +		{
        +		sLen = emLen - hLen - 2;
        +		}
        +	else if (emLen < (hLen + sLen + 2))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		goto err;
        +		}
        +	if (sLen > 0)
        +		{
        +		salt = OPENSSL_malloc(sLen);
        +		if (!salt)
        +			{
        +			RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		if (RAND_bytes(salt, sLen) <= 0)
        +			goto err;
        +		}
        +	maskedDBLen = emLen - hLen - 1;
        +	H = EM + maskedDBLen;
        +	EVP_MD_CTX_init(&ctx);
        +	if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
        +		|| !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
        +		|| !EVP_DigestUpdate(&ctx, mHash, hLen))
        +		goto err;
        +	if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
        +		goto err;
        +	if (!EVP_DigestFinal_ex(&ctx, H, NULL))
        +		goto err;
        +	EVP_MD_CTX_cleanup(&ctx);
        +
        +	/* Generate dbMask in place then perform XOR on it */
        +	if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
        +		goto err;
        +
        +	p = EM;
        +
        +	/* Initial PS XORs with all zeroes which is a NOP so just update
        +	 * pointer. Note from a test above this value is guaranteed to
        +	 * be non-negative.
        +	 */
        +	p += emLen - sLen - hLen - 2;
        +	*p++ ^= 0x1;
        +	if (sLen > 0)
        +		{
        +		for (i = 0; i < sLen; i++)
        +			*p++ ^= salt[i];
        +		}
        +	if (MSBits)
        +		EM[0] &= 0xFF >> (8 - MSBits);
        +
        +	/* H is already in place so just set final 0xbc */
        +
        +	EM[emLen - 1] = 0xbc;
        +
        +	ret = 1;
        +
        +	err:
        +	if (salt)
        +		OPENSSL_free(salt);
        +
        +	return ret;
        +
        +	}
        +
        +#if defined(_MSC_VER)
        +#pragma optimize("",on)
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_saos.c b/vendor/openssl/openssl/crypto/rsa/rsa_saos.c
        new file mode 100644
        index 000000000..f98e0a80a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_saos.c
        @@ -0,0 +1,150 @@
        +/* crypto/rsa/rsa_saos.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int RSA_sign_ASN1_OCTET_STRING(int type,
        +	const unsigned char *m, unsigned int m_len,
        +	unsigned char *sigret, unsigned int *siglen, RSA *rsa)
        +	{
        +	ASN1_OCTET_STRING sig;
        +	int i,j,ret=1;
        +	unsigned char *p,*s;
        +
        +	sig.type=V_ASN1_OCTET_STRING;
        +	sig.length=m_len;
        +	sig.data=(unsigned char *)m;
        +
        +	i=i2d_ASN1_OCTET_STRING(&sig,NULL);
        +	j=RSA_size(rsa);
        +	if (i > (j-RSA_PKCS1_PADDING_SIZE))
        +		{
        +		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
        +		return(0);
        +		}
        +	s=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
        +	if (s == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	p=s;
        +	i2d_ASN1_OCTET_STRING(&sig,&p);
        +	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
        +	if (i <= 0)
        +		ret=0;
        +	else
        +		*siglen=i;
        +
        +	OPENSSL_cleanse(s,(unsigned int)j+1);
        +	OPENSSL_free(s);
        +	return(ret);
        +	}
        +
        +int RSA_verify_ASN1_OCTET_STRING(int dtype,
        +	const unsigned char *m,
        +	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
        +	RSA *rsa)
        +	{
        +	int i,ret=0;
        +	unsigned char *s;
        +	const unsigned char *p;
        +	ASN1_OCTET_STRING *sig=NULL;
        +
        +	if (siglen != (unsigned int)RSA_size(rsa))
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,RSA_R_WRONG_SIGNATURE_LENGTH);
        +		return(0);
        +		}
        +
        +	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
        +	if (s == NULL)
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
        +
        +	if (i <= 0) goto err;
        +
        +	p=s;
        +	sig=d2i_ASN1_OCTET_STRING(NULL,&p,(long)i);
        +	if (sig == NULL) goto err;
        +
        +	if (	((unsigned int)sig->length != m_len) ||
        +		(memcmp(m,sig->data,m_len) != 0))
        +		{
        +		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,RSA_R_BAD_SIGNATURE);
        +		}
        +	else
        +		ret=1;
        +err:
        +	if (sig != NULL) M_ASN1_OCTET_STRING_free(sig);
        +	if (s != NULL)
        +		{
        +		OPENSSL_cleanse(s,(unsigned int)siglen);
        +		OPENSSL_free(s);
        +		}
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_sign.c b/vendor/openssl/openssl/crypto/rsa/rsa_sign.c
        new file mode 100644
        index 000000000..b6f6037ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_sign.c
        @@ -0,0 +1,318 @@
        +/* crypto/rsa/rsa_sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include "rsa_locl.h"
        +
        +/* Size of an SSL signature: MD5+SHA1 */
        +#define SSL_SIG_LENGTH	36
        +
        +int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
        +	     unsigned char *sigret, unsigned int *siglen, RSA *rsa)
        +	{
        +	X509_SIG sig;
        +	ASN1_TYPE parameter;
        +	int i,j,ret=1;
        +	unsigned char *p, *tmps = NULL;
        +	const unsigned char *s = NULL;
        +	X509_ALGOR algor;
        +	ASN1_OCTET_STRING digest;
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD);
        +		return 0;
        +		}
        +#endif
        +	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
        +		{
        +		return rsa->meth->rsa_sign(type, m, m_len,
        +			sigret, siglen, rsa);
        +		}
        +	/* Special case: SSL signature, just check the length */
        +	if(type == NID_md5_sha1) {
        +		if(m_len != SSL_SIG_LENGTH) {
        +			RSAerr(RSA_F_RSA_SIGN,RSA_R_INVALID_MESSAGE_LENGTH);
        +			return(0);
        +		}
        +		i = SSL_SIG_LENGTH;
        +		s = m;
        +	} else {
        +		sig.algor= &algor;
        +		sig.algor->algorithm=OBJ_nid2obj(type);
        +		if (sig.algor->algorithm == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
        +			return(0);
        +			}
        +		if (sig.algor->algorithm->length == 0)
        +			{
        +			RSAerr(RSA_F_RSA_SIGN,RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
        +			return(0);
        +			}
        +		parameter.type=V_ASN1_NULL;
        +		parameter.value.ptr=NULL;
        +		sig.algor->parameter= &parameter;
        +
        +		sig.digest= &digest;
        +		sig.digest->data=(unsigned char *)m; /* TMP UGLY CAST */
        +		sig.digest->length=m_len;
        +
        +		i=i2d_X509_SIG(&sig,NULL);
        +	}
        +	j=RSA_size(rsa);
        +	if (i > (j-RSA_PKCS1_PADDING_SIZE))
        +		{
        +		RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
        +		return(0);
        +		}
        +	if(type != NID_md5_sha1) {
        +		tmps=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
        +		if (tmps == NULL)
        +			{
        +			RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		p=tmps;
        +		i2d_X509_SIG(&sig,&p);
        +		s=tmps;
        +	}
        +	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
        +	if (i <= 0)
        +		ret=0;
        +	else
        +		*siglen=i;
        +
        +	if(type != NID_md5_sha1) {
        +		OPENSSL_cleanse(tmps,(unsigned int)j+1);
        +		OPENSSL_free(tmps);
        +	}
        +	return(ret);
        +	}
        +
        +int int_rsa_verify(int dtype, const unsigned char *m,
        +			  unsigned int m_len,
        +			  unsigned char *rm, size_t *prm_len,
        +			  const unsigned char *sigbuf, size_t siglen,
        +			  RSA *rsa)
        +	{
        +	int i,ret=0,sigtype;
        +	unsigned char *s;
        +	X509_SIG *sig=NULL;
        +
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
        +			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
        +		{
        +		RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD);
        +		return 0;
        +		}
        +#endif
        +
        +	if (siglen != (unsigned int)RSA_size(rsa))
        +		{
        +		RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
        +		return(0);
        +		}
        +
        +	if((dtype == NID_md5_sha1) && rm)
        +		{
        +		i = RSA_public_decrypt((int)siglen,
        +					sigbuf,rm,rsa,RSA_PKCS1_PADDING);
        +		if (i <= 0)
        +			return 0;
        +		*prm_len = i;
        +		return 1;
        +		}
        +
        +	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
        +	if (s == NULL)
        +		{
        +		RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
        +			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
        +			goto err;
        +	}
        +	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
        +
        +	if (i <= 0) goto err;
        +	/* Oddball MDC2 case: signature can be OCTET STRING.
        +	 * check for correct tag and length octets.
        +	 */
        +	if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10)
        +		{
        +		if (rm)
        +			{
        +			memcpy(rm, s + 2, 16);
        +			*prm_len = 16;
        +			ret = 1;
        +			}
        +		else if(memcmp(m, s + 2, 16))
        +			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
        +		else
        +			ret = 1;
        +		}
        +
        +	/* Special case: SSL signature */
        +	if(dtype == NID_md5_sha1) {
        +		if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
        +				RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
        +		else ret = 1;
        +	} else {
        +		const unsigned char *p=s;
        +		sig=d2i_X509_SIG(NULL,&p,(long)i);
        +
        +		if (sig == NULL) goto err;
        +
        +		/* Excess data can be used to create forgeries */
        +		if(p != s+i)
        +			{
        +			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
        +			goto err;
        +			}
        +
        +		/* Parameters to the signature algorithm can also be used to
        +		   create forgeries */
        +		if(sig->algor->parameter
        +		   && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
        +			{
        +			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
        +			goto err;
        +			}
        +
        +		sigtype=OBJ_obj2nid(sig->algor->algorithm);
        +
        +
        +	#ifdef RSA_DEBUG
        +		/* put a backward compatibility flag in EAY */
        +		fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype),
        +			OBJ_nid2ln(dtype));
        +	#endif
        +		if (sigtype != dtype)
        +			{
        +			if (((dtype == NID_md5) &&
        +				(sigtype == NID_md5WithRSAEncryption)) ||
        +				((dtype == NID_md2) &&
        +				(sigtype == NID_md2WithRSAEncryption)))
        +				{
        +				/* ok, we will let it through */
        +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
        +				fprintf(stderr,"signature has problems, re-make with post SSLeay045\n");
        +#endif
        +				}
        +			else
        +				{
        +				RSAerr(RSA_F_INT_RSA_VERIFY,
        +						RSA_R_ALGORITHM_MISMATCH);
        +				goto err;
        +				}
        +			}
        +		if (rm)
        +			{
        +			const EVP_MD *md;
        +			md = EVP_get_digestbynid(dtype);
        +			if (md && (EVP_MD_size(md) != sig->digest->length))
        +				RSAerr(RSA_F_INT_RSA_VERIFY,
        +						RSA_R_INVALID_DIGEST_LENGTH);
        +			else
        +				{
        +				memcpy(rm, sig->digest->data,
        +							sig->digest->length);
        +				*prm_len = sig->digest->length;
        +				ret = 1;
        +				}
        +			}
        +		else if (((unsigned int)sig->digest->length != m_len) ||
        +			(memcmp(m,sig->digest->data,m_len) != 0))
        +			{
        +			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
        +			}
        +		else
        +			ret=1;
        +	}
        +err:
        +	if (sig != NULL) X509_SIG_free(sig);
        +	if (s != NULL)
        +		{
        +		OPENSSL_cleanse(s,(unsigned int)siglen);
        +		OPENSSL_free(s);
        +		}
        +	return(ret);
        +	}
        +
        +int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
        +		const unsigned char *sigbuf, unsigned int siglen,
        +		RSA *rsa)
        +	{
        +
        +	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
        +		{
        +		return rsa->meth->rsa_verify(dtype, m, m_len,
        +			sigbuf, siglen, rsa);
        +		}
        +
        +	return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_ssl.c b/vendor/openssl/openssl/crypto/rsa/rsa_ssl.c
        new file mode 100644
        index 000000000..cfeff15bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_ssl.c
        @@ -0,0 +1,154 @@
        +/* crypto/rsa/rsa_ssl.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +
        +int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
        +	const unsigned char *from, int flen)
        +	{
        +	int i,j;
        +	unsigned char *p;
        +	
        +	if (flen > (tlen-11))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		return(0);
        +		}
        +	
        +	p=(unsigned char *)to;
        +
        +	*(p++)=0;
        +	*(p++)=2; /* Public Key BT (Block Type) */
        +
        +	/* pad out with non-zero random data */
        +	j=tlen-3-8-flen;
        +
        +	if (RAND_bytes(p,j) <= 0)
        +		return(0);
        +	for (i=0; i<j; i++)
        +		{
        +		if (*p == '\0')
        +			do	{
        +				if (RAND_bytes(p,1) <= 0)
        +					return(0);
        +				} while (*p == '\0');
        +		p++;
        +		}
        +
        +	memset(p,3,8);
        +	p+=8;
        +	*(p++)='\0';
        +
        +	memcpy(p,from,(unsigned int)flen);
        +	return(1);
        +	}
        +
        +int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
        +	const unsigned char *from, int flen, int num)
        +	{
        +	int i,j,k;
        +	const unsigned char *p;
        +
        +	p=from;
        +	if (flen < 10)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_SMALL);
        +		return(-1);
        +		}
        +	if ((num != (flen+1)) || (*(p++) != 02))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_BLOCK_TYPE_IS_NOT_02);
        +		return(-1);
        +		}
        +
        +	/* scan over padding data */
        +	j=flen-1; /* one for type */
        +	for (i=0; i<j; i++)
        +		if (*(p++) == 0) break;
        +
        +	if ((i == j) || (i < 8))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_NULL_BEFORE_BLOCK_MISSING);
        +		return(-1);
        +		}
        +	for (k = -9; k<-1; k++)
        +		{
        +		if (p[k] !=  0x03) break;
        +		}
        +	if (k == -1)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_SSLV3_ROLLBACK_ATTACK);
        +		return(-1);
        +		}
        +
        +	i++; /* Skip over the '\0' */
        +	j-=i;
        +	if (j > tlen)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_LARGE);
        +		return(-1);
        +		}
        +	memcpy(to,p,(unsigned int)j);
        +
        +	return(j);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_test.c b/vendor/openssl/openssl/crypto/rsa/rsa_test.c
        new file mode 100644
        index 000000000..c8705a0f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_test.c
        @@ -0,0 +1,340 @@
        +/* test vectors from p1ovect1.txt */
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +#ifdef OPENSSL_NO_RSA
        +int main(int argc, char *argv[])
        +{
        +    printf("No RSA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rsa.h>
        +
        +#define SetKey \
        +  key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
        +  key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
        +  key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
        +  key->p = BN_bin2bn(p, sizeof(p)-1, key->p); \
        +  key->q = BN_bin2bn(q, sizeof(q)-1, key->q); \
        +  key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); \
        +  key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); \
        +  key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); \
        +  memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \
        +  return (sizeof(ctext_ex) - 1);
        +
        +static int key1(RSA *key, unsigned char *c)
        +    {
        +    static unsigned char n[] =
        +"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
        +"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
        +"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
        +"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
        +"\xF5";
        +
        +    static unsigned char e[] = "\x11";
        +
        +    static unsigned char d[] =
        +"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
        +"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
        +"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
        +"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
        +
        +    static unsigned char p[] =
        +"\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
        +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
        +"\x0D";
        +    
        +    static unsigned char q[] =
        +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
        +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
        +"\x89";
        +
        +    static unsigned char dmp1[] =
        +"\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
        +"\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
        +
        +    static unsigned char dmq1[] =
        +"\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
        +"\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
        +"\x51";
        +
        +    static unsigned char iqmp[] =
        +"\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
        +"\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
        +
        +    static unsigned char ctext_ex[] =
        +"\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89"
        +"\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52"
        +"\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44"
        +"\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
        +
        +    SetKey;
        +    }
        +
        +static int key2(RSA *key, unsigned char *c)
        +    {
        +    static unsigned char n[] =
        +"\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8"
        +"\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26"
        +"\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8"
        +"\x34\x77\xCF";
        +
        +    static unsigned char e[] = "\x3";
        +
        +    static unsigned char d[] =
        +"\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2"
        +"\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41"
        +"\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21"
        +"\xE5\xEB";
        +
        +    static unsigned char p[] =
        +"\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92"
        +"\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91";
        +
        +    static unsigned char q[] =
        +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
        +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F";
        +    
        +    static unsigned char dmp1[] =
        +"\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61"
        +"\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B";
        +
        +    static unsigned char dmq1[] =
        +"\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90"
        +"\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F";
        +
        +    static unsigned char iqmp[] =
        +"\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13"
        +"\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D";
        +
        +    static unsigned char ctext_ex[] =
        +"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
        +"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
        +"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
        +"\x62\x51";
        +
        +    SetKey;
        +    }
        +
        +static int key3(RSA *key, unsigned char *c)
        +    {
        +    static unsigned char n[] =
        +"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
        +"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
        +"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
        +"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
        +"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
        +"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
        +"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
        +"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
        +"\xCB";
        +
        +    static unsigned char e[] = "\x11";
        +
        +    static unsigned char d[] =
        +"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
        +"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
        +"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
        +"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
        +"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
        +"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
        +"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
        +"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
        +"\xC1";
        +
        +    static unsigned char p[] =
        +"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
        +"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
        +"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
        +"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
        +"\x99";
        +
        +    static unsigned char q[] =
        +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
        +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
        +"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
        +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
        +"\x03";
        +
        +    static unsigned char dmp1[] =
        +"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
        +"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
        +"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
        +"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
        +
        +    static unsigned char dmq1[] =
        +"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
        +"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
        +"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
        +"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
        +    
        +    static unsigned char iqmp[] =
        +"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
        +"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
        +"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
        +"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
        +"\xF7";
        +
        +    static unsigned char ctext_ex[] =
        +"\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7"
        +"\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce"
        +"\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3"
        +"\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06"
        +"\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86"
        +"\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4"
        +"\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a"
        +"\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1";
        +
        +    SetKey;
        +    }
        +
        +static int pad_unknown(void)
        +{
        +    unsigned long l;
        +    while ((l = ERR_get_error()) != 0)
        +      if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE)
        +	return(1);
        +    return(0);
        +}
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +    {
        +    int err=0;
        +    int v;
        +    RSA *key;
        +    unsigned char ptext[256];
        +    unsigned char ctext[256];
        +    static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
        +    unsigned char ctext_ex[256];
        +    int plen;
        +    int clen = 0;
        +    int num;
        +    int n;
        +
        +    CRYPTO_malloc_debug_init();
        +    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +    RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */
        +
        +    plen = sizeof(ptext_ex) - 1;
        +
        +    for (v = 0; v < 6; v++)
        +	{
        +	key = RSA_new();
        +	switch (v%3) {
        +    case 0:
        +	clen = key1(key, ctext_ex);
        +	break;
        +    case 1:
        +	clen = key2(key, ctext_ex);
        +	break;
        +    case 2:
        +	clen = key3(key, ctext_ex);
        +	break;
        +	}
        +	if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
        +
        +	num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
        +				 RSA_PKCS1_PADDING);
        +	if (num != clen)
        +	    {
        +	    printf("PKCS#1 v1.5 encryption failed!\n");
        +	    err=1;
        +	    goto oaep;
        +	    }
        +  
        +	num = RSA_private_decrypt(num, ctext, ptext, key,
        +				  RSA_PKCS1_PADDING);
        +	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
        +	    {
        +	    printf("PKCS#1 v1.5 decryption failed!\n");
        +	    err=1;
        +	    }
        +	else
        +	    printf("PKCS #1 v1.5 encryption/decryption ok\n");
        +
        +    oaep:
        +	ERR_clear_error();
        +	num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
        +				 RSA_PKCS1_OAEP_PADDING);
        +	if (num == -1 && pad_unknown())
        +	    {
        +	    printf("No OAEP support\n");
        +	    goto next;
        +	    }
        +	if (num != clen)
        +	    {
        +	    printf("OAEP encryption failed!\n");
        +	    err=1;
        +	    goto next;
        +	    }
        +
        +	num = RSA_private_decrypt(num, ctext, ptext, key,
        +				  RSA_PKCS1_OAEP_PADDING);
        +	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
        +	    {
        +	    printf("OAEP decryption (encrypted data) failed!\n");
        +	    err=1;
        +	    }
        +	else if (memcmp(ctext, ctext_ex, num) == 0)
        +	    printf("OAEP test vector %d passed!\n", v);
        +    
        +	/* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
        +	   Try decrypting ctext_ex */
        +
        +	num = RSA_private_decrypt(clen, ctext_ex, ptext, key,
        +				  RSA_PKCS1_OAEP_PADDING);
        +
        +	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
        +	    {
        +	    printf("OAEP decryption (test vector data) failed!\n");
        +	    err=1;
        +	    }
        +	else
        +	    printf("OAEP encryption/decryption ok\n");
        +
        +	/* Try decrypting corrupted ciphertexts */
        +	for(n = 0 ; n < clen ; ++n)
        +	    {
        +	    int b;
        +	    unsigned char saved = ctext[n];
        +	    for(b = 0 ; b < 256 ; ++b)
        +		{
        +		if(b == saved)
        +		    continue;
        +		ctext[n] = b;
        +		num = RSA_private_decrypt(num, ctext, ptext, key,
        +					  RSA_PKCS1_OAEP_PADDING);
        +		if(num > 0)
        +		    {
        +		    printf("Corrupt data decrypted!\n");
        +		    err = 1;
        +		    }
        +		}
        +	    }
        +    next:
        +	RSA_free(key);
        +	}
        +
        +    CRYPTO_cleanup_all_ex_data();
        +    ERR_remove_thread_state(NULL);
        +
        +    CRYPTO_mem_leaks_fp(stderr);
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +    return err;
        +    }
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/rsa/rsa_x931.c b/vendor/openssl/openssl/crypto/rsa/rsa_x931.c
        new file mode 100644
        index 000000000..21548e37e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/rsa/rsa_x931.c
        @@ -0,0 +1,177 @@
        +/* rsa_x931.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2005.
        + */
        +/* ====================================================================
        + * Copyright (c) 2005 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/rsa.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +
        +int RSA_padding_add_X931(unsigned char *to, int tlen,
        +	     const unsigned char *from, int flen)
        +	{
        +	int j;
        +	unsigned char *p;
        +
        +	/* Absolute minimum amount of padding is 1 header nibble, 1 padding
        +	 * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
        +	 */
        +
        +	j = tlen - flen - 2;
        +
        +	if (j < 0)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_ADD_X931,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        +		return -1;
        +		}
        +	
        +	p=(unsigned char *)to;
        +
        +	/* If no padding start and end nibbles are in one byte */
        +	if (j == 0)
        +		*p++ = 0x6A;
        +	else
        +		{
        +		*p++ = 0x6B;
        +		if (j > 1)
        +			{
        +			memset(p, 0xBB, j - 1);
        +			p += j - 1;
        +			}
        +		*p++ = 0xBA;
        +		}
        +	memcpy(p,from,(unsigned int)flen);
        +	p += flen;
        +	*p = 0xCC;
        +	return(1);
        +	}
        +
        +int RSA_padding_check_X931(unsigned char *to, int tlen,
        +	     const unsigned char *from, int flen, int num)
        +	{
        +	int i = 0,j;
        +	const unsigned char *p;
        +
        +	p=from;
        +	if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B)))
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_X931,RSA_R_INVALID_HEADER);
        +		return -1;
        +		}
        +
        +	if (*p++ == 0x6B)
        +		{
        +		j=flen-3;
        +		for (i = 0; i < j; i++)
        +			{
        +			unsigned char c = *p++;
        +			if (c == 0xBA)
        +				break;
        +			if (c != 0xBB)
        +				{
        +				RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
        +					RSA_R_INVALID_PADDING);
        +				return -1;
        +				}
        +			}
        +
        +		j -= i;
        +
        +		if (i == 0)
        +			{
        +			RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
        +			return -1;
        +			}
        +
        +		}
        +	else j = flen - 2;
        +
        +	if (p[j] != 0xCC)
        +		{
        +		RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
        +		return -1;
        +		}
        +
        +	memcpy(to,p,(unsigned int)j);
        +
        +	return(j);
        +	}
        +
        +/* Translate between X931 hash ids and NIDs */
        +
        +int RSA_X931_hash_id(int nid)
        +	{
        +	switch (nid)
        +		{
        +		case NID_sha1:
        +		return 0x33;
        +
        +		case NID_sha256:
        +		return 0x34;
        +
        +		case NID_sha384:
        +		return 0x36;
        +
        +		case NID_sha512:
        +		return 0x35;
        +
        +		}
        +	return -1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/s390xcap.c b/vendor/openssl/openssl/crypto/s390xcap.c
        new file mode 100644
        index 000000000..f2e94ef47
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/s390xcap.c
        @@ -0,0 +1,37 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <setjmp.h>
        +#include <signal.h>
        +
        +extern unsigned long OPENSSL_s390xcap_P[];
        +
        +static sigjmp_buf ill_jmp;
        +static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
        +
        +unsigned long OPENSSL_s390x_facilities(void);
        +
        +void OPENSSL_cpuid_setup(void)
        +	{
        +	sigset_t oset;
        +	struct sigaction ill_act,oact;
        +
        +	if (OPENSSL_s390xcap_P[0]) return;
        +
        +	OPENSSL_s390xcap_P[0] = 1UL<<(8*sizeof(unsigned long)-1);
        +
        +	memset(&ill_act,0,sizeof(ill_act));
        +	ill_act.sa_handler = ill_handler;
        +	sigfillset(&ill_act.sa_mask);
        +	sigdelset(&ill_act.sa_mask,SIGILL);
        +	sigdelset(&ill_act.sa_mask,SIGTRAP);
        +	sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
        +	sigaction (SIGILL,&ill_act,&oact);
        +
        +	/* protection against missing store-facility-list-extended */
        +	if (sigsetjmp(ill_jmp,1) == 0)
        +		OPENSSL_s390x_facilities();
        +
        +	sigaction (SIGILL,&oact,NULL);
        +	sigprocmask(SIG_SETMASK,&oset,NULL);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/s390xcpuid.S b/vendor/openssl/openssl/crypto/s390xcpuid.S
        new file mode 100644
        index 000000000..06815347e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/s390xcpuid.S
        @@ -0,0 +1,99 @@
        +.text
        +
        +.globl	OPENSSL_s390x_facilities
        +.type	OPENSSL_s390x_facilities,@function
        +.align	16
        +OPENSSL_s390x_facilities:
        +	lghi	%r0,0
        +	larl	%r2,OPENSSL_s390xcap_P
        +	stg	%r0,8(%r2)
        +	.long	0xb2b02000	# stfle	0(%r2)
        +	brc	8,.Ldone
        +	lghi	%r0,1
        +	.long	0xb2b02000	# stfle 0(%r2)
        +.Ldone:
        +	lg	%r2,0(%r2)
        +	br	%r14
        +.size	OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
        +
        +.globl	OPENSSL_rdtsc
        +.type	OPENSSL_rdtsc,@function
        +.align	16
        +OPENSSL_rdtsc:
        +	stck	16(%r15)
        +	lg	%r2,16(%r15)
        +	br	%r14
        +.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
        +
        +.globl	OPENSSL_atomic_add
        +.type	OPENSSL_atomic_add,@function
        +.align	16
        +OPENSSL_atomic_add:
        +	l	%r1,0(%r2)
        +.Lspin:	lr	%r0,%r1
        +	ar	%r0,%r3
        +	cs	%r1,%r0,0(%r2)
        +	brc	4,.Lspin
        +	lgfr	%r2,%r0		# OpenSSL expects the new value
        +	br	%r14
        +.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
        +
        +.globl	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,@function
        +.align	16
        +OPENSSL_wipe_cpu:
        +	xgr	%r0,%r0
        +	xgr	%r1,%r1
        +	lgr	%r2,%r15
        +	xgr	%r3,%r3
        +	xgr	%r4,%r4
        +	lzdr	%f0
        +	lzdr	%f1
        +	lzdr	%f2
        +	lzdr	%f3
        +	lzdr	%f4
        +	lzdr	%f5
        +	lzdr	%f6
        +	lzdr	%f7
        +	br	%r14
        +.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
        +
        +.globl	OPENSSL_cleanse
        +.type	OPENSSL_cleanse,@function
        +.align	16
        +OPENSSL_cleanse:
        +#if !defined(__s390x__) && !defined(__s390x)
        +	llgfr	%r3,%r3
        +#endif
        +	lghi	%r4,15
        +	lghi	%r0,0
        +	clgr	%r3,%r4
        +	jh	.Lot
        +	clgr	%r3,%r0
        +	bcr	8,%r14
        +.Little:
        +	stc	%r0,0(%r2)
        +	la	%r2,1(%r2)
        +	brctg	%r3,.Little
        +	br	%r14
        +.align	4
        +.Lot:	tmll	%r2,7
        +	jz	.Laligned
        +	stc	%r0,0(%r2)
        +	la	%r2,1(%r2)
        +	brctg	%r3,.Lot
        +.Laligned:
        +	srlg	%r4,%r3,3
        +.Loop:	stg	%r0,0(%r2)
        +	la	%r2,8(%r2)
        +	brctg	%r4,.Loop
        +	lghi	%r4,7
        +	ngr	%r3,%r4
        +	jnz	.Little
        +	br	%r14
        +.size	OPENSSL_cleanse,.-OPENSSL_cleanse
        +
        +.section	.init
        +	brasl	%r14,OPENSSL_cpuid_setup
        +
        +.comm	OPENSSL_s390xcap_P,16,8
        diff --git a/vendor/openssl/openssl/crypto/seed/Makefile b/vendor/openssl/openssl/crypto/seed/Makefile
        new file mode 100644
        index 000000000..4bc55e491
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/Makefile
        @@ -0,0 +1,106 @@
        +#
        +# crypto/seed/Makefile
        +#
        +
        +DIR=	seed
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c
        +LIBOBJ=seed.o seed_ecb.o seed_cbc.o seed_cfb.o seed_ofb.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= seed.h
        +HEADER= seed_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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +seed.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +seed.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +seed.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +seed.o: ../../include/openssl/seed.h ../../include/openssl/stack.h
        +seed.o: ../../include/openssl/symhacks.h seed.c seed_locl.h
        +seed_cbc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +seed_cbc.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +seed_cbc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +seed_cbc.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
        +seed_cbc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +seed_cbc.o: seed_cbc.c
        +seed_cfb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +seed_cfb.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +seed_cfb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +seed_cfb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
        +seed_cfb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +seed_cfb.o: seed_cfb.c
        +seed_ecb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +seed_ecb.o: ../../include/openssl/opensslconf.h
        +seed_ecb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +seed_ecb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
        +seed_ecb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +seed_ecb.o: seed_ecb.c
        +seed_ofb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +seed_ofb.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
        +seed_ofb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +seed_ofb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
        +seed_ofb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +seed_ofb.o: seed_ofb.c
        diff --git a/vendor/openssl/openssl/crypto/seed/seed.c b/vendor/openssl/openssl/crypto/seed/seed.c
        new file mode 100644
        index 000000000..3e675a8d7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed.c
        @@ -0,0 +1,336 @@
        +/*
        + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Neither the name of author nor the names of its contributors may
        + *    be used to endorse or promote products derived from this software
        + *    without specific prior written permission.
        + *
        + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL 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.
        + *
        + */
        +#ifndef OPENSSL_NO_SEED
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#ifdef WIN32
        +#include <memory.h>
        +#endif
        +
        +#include <openssl/crypto.h>
        +#include <openssl/seed.h>
        +#include "seed_locl.h"
        +
        +#ifdef SS	/* can get defined on Solaris by inclusion of <stdlib.h> */
        +#undef SS
        +#endif
        +
        +static const seed_word SS[4][256] = {	{
        +	0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
        +	0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
        +	0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
        +	0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
        +	0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
        +	0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
        +	0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
        +	0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
        +	0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
        +	0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
        +	0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
        +	0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
        +	0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
        +	0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
        +	0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
        +	0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
        +	0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
        +	0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
        +	0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038,
        +	0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
        +	0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
        +	0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
        +	0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
        +	0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
        +	0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
        +	0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
        +	0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
        +	0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
        +	0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
        +	0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
        +	0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330,
        +	0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
        +},	{
        +	0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
        +	0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
        +	0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
        +	0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
        +	0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
        +	0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
        +	0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
        +	0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
        +	0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
        +	0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
        +	0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
        +	0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
        +	0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
        +	0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171,
        +	0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
        +	0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
        +	0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
        +	0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
        +	0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
        +	0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
        +	0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
        +	0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
        +	0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
        +	0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
        +	0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
        +	0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
        +	0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
        +	0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
        +	0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
        +	0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
        +	0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
        +	0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
        +},	{
        +	0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
        +	0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
        +	0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
        +	0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
        +	0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
        +	0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
        +	0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
        +	0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
        +	0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
        +	0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
        +	0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
        +	0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
        +	0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
        +	0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
        +	0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
        +	0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
        +	0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
        +	0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
        +	0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808,
        +	0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
        +	0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
        +	0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
        +	0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
        +	0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
        +	0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
        +	0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
        +	0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
        +	0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
        +	0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
        +	0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
        +	0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303,
        +	0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
        +},	{
        +	0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
        +	0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
        +	0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
        +	0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
        +	0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
        +	0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
        +	0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
        +	0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
        +	0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
        +	0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
        +	0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
        +	0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
        +	0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
        +	0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031,
        +	0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
        +	0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
        +	0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
        +	0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
        +	0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
        +	0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
        +	0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
        +	0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
        +	0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
        +	0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
        +	0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
        +	0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
        +	0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
        +	0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
        +	0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
        +	0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
        +	0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
        +	0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
        +}	};
        +
        +/* key schedule constants - golden ratio */
        +#define KC0     0x9e3779b9
        +#define KC1     0x3c6ef373
        +#define KC2     0x78dde6e6
        +#define KC3     0xf1bbcdcc
        +#define KC4     0xe3779b99
        +#define KC5     0xc6ef3733
        +#define KC6     0x8dde6e67
        +#define KC7     0x1bbcdccf
        +#define KC8     0x3779b99e
        +#define KC9     0x6ef3733c
        +#define KC10    0xdde6e678
        +#define KC11    0xbbcdccf1
        +#define KC12    0x779b99e3
        +#define KC13    0xef3733c6
        +#define KC14    0xde6e678d
        +#define KC15    0xbcdccf1b
        +
        +#if defined(OPENSSL_SMALL_FOOTPRINT)
        +static const seed_word KC[] = {
        +	KC0,	KC1,	KC2,	KC3,	KC4,	KC5,	KC6,	KC7,
        +	KC8,	KC9,	KC10,	KC11,	KC12,	KC13,	KC14,	KC15	};
        +#endif
        +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks)
        +#ifdef OPENSSL_FIPS
        +	{
        +	fips_cipher_abort(SEED);
        +	private_SEED_set_key(rawkey, ks);
        +	}
        +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks)
        +#endif
        +{
        +	seed_word x1, x2, x3, x4;
        +	seed_word t0, t1;
        +
        +	char2word(rawkey   , x1);
        +	char2word(rawkey+4 , x2);
        +	char2word(rawkey+8 , x3);
        +	char2word(rawkey+12, x4);
        +
        +	t0 = (x1 + x3 - KC0) & 0xffffffff;
        +	t1 = (x2 - x4 + KC0) & 0xffffffff;                     KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);      KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);      KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);      KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);      KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);      KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);      KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);      KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);      KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);      KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);     KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);     KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);     KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);     KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
        +	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);     KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
        +	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);     KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
        +#else
        +	{
        +	    int i;
        +	    for (i=2; i<16; i+=2) {
        +		KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]);
        +		KEYUPDATE_TEMP(t0, t1, &ks->data[i*2]);
        +		KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i+1]);
        +		KEYUPDATE_TEMP(t0, t1, &ks->data[i*2+2]);
        +	    }
        +	}
        +#endif
        +}
        +
        +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks)
        +{
        +	seed_word x1, x2, x3, x4;
        +	seed_word t0, t1;
        +
        +	char2word(s,    x1);
        +	char2word(s+4,  x2);
        +	char2word(s+8,  x3);
        +	char2word(s+12, x4);
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)	
        +	E_SEED(t0, t1, x1, x2, x3, x4, 0);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 2);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 4);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 6);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 8);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 10);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 12);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 14);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 16);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 18);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 20);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 22);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 24);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 26);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 28);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 30);
        +#else
        +	{
        +	    int i;
        +	    for (i=0;i<30;i+=4) {
        +		E_SEED(t0,t1,x1,x2,x3,x4,i);
        +		E_SEED(t0,t1,x3,x4,x1,x2,i+2);
        +	    }
        +	}
        +#endif
        +
        +	word2char(x3, d);
        +	word2char(x4, d+4);
        +	word2char(x1, d+8);
        +	word2char(x2, d+12);
        +}
        +
        +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks)
        +{
        +	seed_word x1, x2, x3, x4;
        +	seed_word t0, t1;
        +
        +	char2word(s,    x1);
        +	char2word(s+4,  x2);
        +	char2word(s+8,  x3);
        +	char2word(s+12, x4);
        +
        +#if !defined(OPENSSL_SMALL_FOOTPRINT)
        +	E_SEED(t0, t1, x1, x2, x3, x4, 30);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 28);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 26);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 24);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 22);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 20);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 18);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 16);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 14);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 12);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 10);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 8);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 6);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 4);
        +	E_SEED(t0, t1, x1, x2, x3, x4, 2);
        +	E_SEED(t0, t1, x3, x4, x1, x2, 0);
        +#else
        +	{
        +	    int i;
        +	    for (i=30; i>0; i-=4) {
        +		E_SEED(t0, t1, x1, x2, x3, x4, i);
        +		E_SEED(t0, t1, x3, x4, x1, x2, i-2);
        +
        +	    }
        +	}
        +#endif
        +
        +	word2char(x3, d);
        +	word2char(x4, d+4);
        +	word2char(x1, d+8);
        +	word2char(x2, d+12);
        +}
        +
        +#endif /* OPENSSL_NO_SEED */
        diff --git a/vendor/openssl/openssl/crypto/seed/seed.h b/vendor/openssl/openssl/crypto/seed/seed.h
        new file mode 100644
        index 000000000..c50fdd360
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed.h
        @@ -0,0 +1,139 @@
        +/*
        + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Neither the name of author nor the names of its contributors may
        + *    be used to endorse or promote products derived from this software
        + *    without specific prior written permission.
        + *
        + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL 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.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 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_SEED_H
        +#define HEADER_SEED_H
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/crypto.h>
        +
        +#ifdef OPENSSL_NO_SEED
        +#error SEED is disabled.
        +#endif
        +
        +#ifdef AES_LONG /* look whether we need 'long' to get 32 bits */
        +# ifndef SEED_LONG
        +#  define SEED_LONG 1
        +# endif
        +#endif
        +
        +#if !defined(NO_SYS_TYPES_H)
        +# include <sys/types.h>
        +#endif
        +
        +#define SEED_BLOCK_SIZE 16
        +#define SEED_KEY_LENGTH	16
        +
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +typedef struct seed_key_st {
        +#ifdef SEED_LONG
        +    unsigned long data[32];
        +#else
        +    unsigned int data[32];
        +#endif
        +} SEED_KEY_SCHEDULE;
        +
        +#ifdef OPENSSL_FIPS
        +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks);
        +#endif
        +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks);
        +
        +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks);
        +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks);
        +
        +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc);
        +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +        size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int enc);
        +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +        size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc);
        +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +        size_t len, const SEED_KEY_SCHEDULE *ks, unsigned char ivec[SEED_BLOCK_SIZE], int *num);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* HEADER_SEED_H */
        diff --git a/vendor/openssl/openssl/crypto/seed/seed_cbc.c b/vendor/openssl/openssl/crypto/seed/seed_cbc.c
        new file mode 100644
        index 000000000..6c3f9b527
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed_cbc.c
        @@ -0,0 +1,63 @@
        +/* crypto/seed/seed_cbc.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/seed.h>
        +#include <openssl/modes.h>
        +
        +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
        +                      size_t len, const SEED_KEY_SCHEDULE *ks,
        +                      unsigned char ivec[SEED_BLOCK_SIZE], int enc)
        +	{
        +	if (enc)
        +		CRYPTO_cbc128_encrypt(in,out,len,ks,ivec,(block128_f)SEED_encrypt);
        +	else
        +		CRYPTO_cbc128_decrypt(in,out,len,ks,ivec,(block128_f)SEED_decrypt);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/seed/seed_cfb.c b/vendor/openssl/openssl/crypto/seed/seed_cfb.c
        new file mode 100644
        index 000000000..694597dd0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed_cfb.c
        @@ -0,0 +1,116 @@
        +/* crypto/seed/seed_cfb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 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.
        + * ====================================================================
        + *
        + */
        +/* 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 <openssl/seed.h>
        +#include <openssl/modes.h>
        +
        +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
        +                         size_t len, const SEED_KEY_SCHEDULE *ks,
        +                         unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc)
        +	{
        +	CRYPTO_cfb128_encrypt(in,out,len,ks,ivec,num,enc,(block128_f)SEED_encrypt);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/seed/seed_ecb.c b/vendor/openssl/openssl/crypto/seed/seed_ecb.c
        new file mode 100644
        index 000000000..e63f5ae14
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed_ecb.c
        @@ -0,0 +1,60 @@
        +/* crypto/seed/seed_ecb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2007 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/seed.h>
        +
        +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc) 
        +	{
        +	if (enc)
        +		SEED_encrypt(in, out, ks);
        +	else
        +		SEED_decrypt(in, out, ks);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/seed/seed_locl.h b/vendor/openssl/openssl/crypto/seed/seed_locl.h
        new file mode 100644
        index 000000000..fd456b642
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed_locl.h
        @@ -0,0 +1,116 @@
        +/*
        + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Neither the name of author nor the names of its contributors may
        + *    be used to endorse or promote products derived from this software
        + *    without specific prior written permission.
        + *
        + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL 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.
        + *
        + */
        +#ifndef HEADER_SEED_LOCL_H
        +#define HEADER_SEED_LOCL_H
        +
        +#include "openssl/e_os2.h"
        +#include <openssl/seed.h>
        +
        +
        +#ifdef SEED_LONG /* need 32-bit type */
        +typedef unsigned long seed_word;
        +#else
        +typedef unsigned int seed_word;
        +#endif
        +
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#define G_FUNC(v)       \
        +        SS[0][(unsigned char)      (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \
        +        SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff]
        +
        +#define char2word(c, i)  \
        +        (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3]))
        +
        +#define word2char(l, c)  \
        +        *((c)+0) = (unsigned char)((l)>>24) & 0xff; \
        +        *((c)+1) = (unsigned char)((l)>>16) & 0xff; \
        +        *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \
        +        *((c)+3) = (unsigned char)((l))     & 0xff
        +
        +#define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC)  \
        +        (T0) = (X3);                                     \
        +        (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff;    \
        +        (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff;    \
        +        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;    \
        +        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
        +
        +#define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC)  \
        +        (T0) = (X1);                                     \
        +        (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff;    \
        +        (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff;    \
        +        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;     \
        +        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
        +
        +#define KEYUPDATE_TEMP(T0, T1, K)   \
        +        (K)[0] = G_FUNC((T0));      \
        +        (K)[1] = G_FUNC((T1))
        +
        +#define XOR_SEEDBLOCK(DST, SRC)      \
        +        ((DST))[0] ^= ((SRC))[0];    \
        +        ((DST))[1] ^= ((SRC))[1];    \
        +        ((DST))[2] ^= ((SRC))[2];    \
        +        ((DST))[3] ^= ((SRC))[3]
        +
        +#define MOV_SEEDBLOCK(DST, SRC)      \
        +        ((DST))[0] = ((SRC))[0];     \
        +        ((DST))[1] = ((SRC))[1];     \
        +        ((DST))[2] = ((SRC))[2];     \
        +        ((DST))[3] = ((SRC))[3]
        +
        +# define CHAR2WORD(C, I)              \
        +        char2word((C),    (I)[0]);    \
        +        char2word((C+4),  (I)[1]);    \
        +        char2word((C+8),  (I)[2]);    \
        +        char2word((C+12), (I)[3])
        +
        +# define WORD2CHAR(I, C)              \
        +        word2char((I)[0], (C));       \
        +        word2char((I)[1], (C+4));     \
        +        word2char((I)[2], (C+8));     \
        +        word2char((I)[3], (C+12))
        +
        +# define E_SEED(T0, T1, X1, X2, X3, X4, rbase)   \
        +        (T0) = (X3) ^ (ks->data)[(rbase)];       \
        +        (T1) = (X4) ^ (ks->data)[(rbase)+1];     \
        +        (T1) ^= (T0);                            \
        +        (T1) = G_FUNC((T1));                     \
        +        (T0) = ((T0) + (T1)) & 0xffffffff;       \
        +        (T0) = G_FUNC((T0));                     \
        +        (T1) = ((T1) + (T0)) & 0xffffffff;       \
        +        (T1) = G_FUNC((T1));                     \
        +        (T0) = ((T0) + (T1)) & 0xffffffff;       \
        +        (X1) ^= (T0);                            \
        +        (X2) ^= (T1)
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif /* HEADER_SEED_LOCL_H */
        diff --git a/vendor/openssl/openssl/crypto/seed/seed_ofb.c b/vendor/openssl/openssl/crypto/seed/seed_ofb.c
        new file mode 100644
        index 000000000..3c8ba33bb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/seed/seed_ofb.c
        @@ -0,0 +1,116 @@
        +/* crypto/seed/seed_ofb.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 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.
        + * ====================================================================
        + *
        + */
        +/* 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 <openssl/seed.h>
        +#include <openssl/modes.h>
        +
        +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
        +                         size_t len, const SEED_KEY_SCHEDULE *ks,
        +                         unsigned char ivec[SEED_BLOCK_SIZE], int *num)
        +	{
        +	CRYPTO_ofb128_encrypt(in,out,len,ks,ivec,num,(block128_f)SEED_encrypt);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/sha/Makefile b/vendor/openssl/openssl/crypto/sha/Makefile
        new file mode 100644
        index 000000000..6d191d393
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/Makefile
        @@ -0,0 +1,166 @@
        +#
        +# OpenSSL/crypto/sha/Makefile
        +#
        +
        +DIR=    sha
        +TOP=    ../..
        +CC=     cc
        +CPP=    $(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=       Makefile
        +AR=             ar r
        +
        +SHA1_ASM_OBJ=
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=shatest.c sha1test.c sha256t.c sha512t.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=sha_dgst.c sha1dgst.c sha_one.c sha1_one.c sha256.c sha512.c
        +LIBOBJ=sha_dgst.o sha1dgst.o sha_one.o sha1_one.o sha256.o sha512.o $(SHA1_ASM_OBJ)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= sha.h
        +HEADER= sha_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) || echo Never mind.
        +	@touch lib
        +
        +sha1-586.s:	asm/sha1-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/sha1-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +sha256-586.s:	asm/sha256-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/sha256-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +sha512-586.s:	asm/sha512-586.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/sha512-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +
        +sha1-ia64.s:   asm/sha1-ia64.pl
        +	(cd asm; $(PERL) sha1-ia64.pl ../$@ $(CFLAGS))
        +sha256-ia64.s: asm/sha512-ia64.pl
        +	(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
        +sha512-ia64.s: asm/sha512-ia64.pl
        +	(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
        +
        +sha256-armv4.S: asm/sha256-armv4.pl
        +	$(PERL) $< $(PERLASM_SCHEME) $@
        +
        +sha1-alpha.s:	asm/sha1-alpha.pl
        +	$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
        +
        +# Solaris make has to be explicitly told
        +sha1-x86_64.s:	asm/sha1-x86_64.pl;	$(PERL) asm/sha1-x86_64.pl $(PERLASM_SCHEME) > $@
        +sha256-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
        +sha512-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
        +sha1-sparcv9.s:	asm/sha1-sparcv9.pl;	$(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
        +sha256-sparcv9.s:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
        +sha512-sparcv9.s:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
        +
        +sha1-ppc.s:	asm/sha1-ppc.pl;	$(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
        +sha256-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
        +sha512-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
        +
        +sha1-parisc.s:	asm/sha1-parisc.pl;	$(PERL) asm/sha1-parisc.pl $(PERLASM_SCHEME) $@
        +sha256-parisc.s:asm/sha512-parisc.pl;	$(PERL) asm/sha512-parisc.pl $(PERLASM_SCHEME) $@
        +sha512-parisc.s:asm/sha512-parisc.pl;	$(PERL) asm/sha512-parisc.pl $(PERLASM_SCHEME) $@
        +
        +sha1-mips.S:	asm/sha1-mips.pl;	$(PERL) asm/sha1-mips.pl $(PERLASM_SCHEME) $@
        +sha256-mips.S:	asm/sha512-mips.pl;	$(PERL) asm/sha512-mips.pl $(PERLASM_SCHEME) $@
        +sha512-mips.S:	asm/sha512-mips.pl;	$(PERL) asm/sha512-mips.pl $(PERLASM_SCHEME) $@
        +
        +# GNU make "catch all"
        +sha1-%.S:	asm/sha1-%.pl;		$(PERL) $< $(PERLASM_SCHEME) $@
        +sha256-%.S:	asm/sha512-%.pl;	$(PERL) $< $(PERLASM_SCHEME) $@
        +sha512-%.S:	asm/sha512-%.pl;	$(PERL) $< $(PERLASM_SCHEME) $@
        +
        +sha1-armv4-large.o:	sha1-armv4-large.S
        +sha256-armv4.o:		sha256-armv4.S
        +sha512-armv4.o:		sha512-armv4.S
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +sha1_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +sha1_one.o: ../../include/openssl/opensslconf.h
        +sha1_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +sha1_one.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +sha1_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +sha1_one.o: sha1_one.c
        +sha1dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +sha1dgst.o: ../../include/openssl/opensslconf.h
        +sha1dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +sha1dgst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +sha1dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +sha1dgst.o: ../md32_common.h sha1dgst.c sha_locl.h
        +sha256.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +sha256.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +sha256.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +sha256.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +sha256.o: ../../include/openssl/symhacks.h ../md32_common.h sha256.c
        +sha512.o: ../../e_os.h ../../include/openssl/bio.h
        +sha512.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +sha512.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +sha512.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +sha512.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +sha512.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +sha512.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +sha512.o: ../cryptlib.h sha512.c
        +sha_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +sha_dgst.o: ../../include/openssl/opensslconf.h
        +sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +sha_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +sha_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +sha_dgst.o: ../md32_common.h sha_dgst.c sha_locl.h
        +sha_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +sha_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +sha_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +sha_one.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +sha_one.o: ../../include/openssl/symhacks.h sha_one.c
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/README b/vendor/openssl/openssl/crypto/sha/asm/README
        new file mode 100644
        index 000000000..b7e755765
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/README
        @@ -0,0 +1 @@
        +C2.pl works
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-586.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-586.pl
        new file mode 100644
        index 000000000..1084d227f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-586.pl
        @@ -0,0 +1,1229 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# "[Re]written" was achieved in two major overhauls. In 2004 BODY_*
        +# functions were re-implemented to address P4 performance issue [see
        +# commentary below], and in 2006 the rest was rewritten in order to
        +# gain freedom to liberate licensing terms.
        +
        +# January, September 2004.
        +#
        +# It was noted that Intel IA-32 C compiler generates code which
        +# performs ~30% *faster* on P4 CPU than original *hand-coded*
        +# SHA1 assembler implementation. To address this problem (and
        +# prove that humans are still better than machines:-), the
        +# original code was overhauled, which resulted in following
        +# performance changes:
        +#
        +#		compared with original	compared with Intel cc
        +#		assembler impl.		generated code
        +# Pentium	-16%			+48%
        +# PIII/AMD	+8%			+16%
        +# P4		+85%(!)			+45%
        +#
        +# As you can see Pentium came out as looser:-( Yet I reckoned that
        +# improvement on P4 outweights the loss and incorporate this
        +# re-tuned code to 0.9.7 and later.
        +# ----------------------------------------------------------------
        +#					<appro@fy.chalmers.se>
        +
        +# August 2009.
        +#
        +# George Spelvin has tipped that F_40_59(b,c,d) can be rewritten as
        +# '(c&d) + (b&(c^d))', which allows to accumulate partial results
        +# and lighten "pressure" on scratch registers. This resulted in
        +# >12% performance improvement on contemporary AMD cores (with no
        +# degradation on other CPUs:-). Also, the code was revised to maximize
        +# "distance" between instructions producing input to 'lea' instruction
        +# and the 'lea' instruction itself, which is essential for Intel Atom
        +# core and resulted in ~15% improvement.
        +
        +# October 2010.
        +#
        +# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it
        +# is to offload message schedule denoted by Wt in NIST specification,
        +# or Xupdate in OpenSSL source, to SIMD unit. The idea is not novel,
        +# and in SSE2 context was first explored by Dean Gaudet in 2004, see
        +# http://arctic.org/~dean/crypto/sha1.html. Since then several things
        +# have changed that made it interesting again:
        +#
        +# a) XMM units became faster and wider;
        +# b) instruction set became more versatile;
        +# c) an important observation was made by Max Locktykhin, which made
        +#    it possible to reduce amount of instructions required to perform
        +#    the operation in question, for further details see
        +#    http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/.
        +
        +# April 2011.
        +#
        +# Add AVX code path, probably most controversial... The thing is that
        +# switch to AVX alone improves performance by as little as 4% in
        +# comparison to SSSE3 code path. But below result doesn't look like
        +# 4% improvement... Trouble is that Sandy Bridge decodes 'ro[rl]' as
        +# pair of µ-ops, and it's the additional µ-ops, two per round, that
        +# make it run slower than Core2 and Westmere. But 'sh[rl]d' is decoded
        +# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
        +# equivalent 'sh[rl]d' that is responsible for the impressive 5.1
        +# cycles per processed byte. But 'sh[rl]d' is not something that used
        +# to be fast, nor does it appear to be fast in upcoming Bulldozer
        +# [according to its optimization manual]. Which is why AVX code path
        +# is guarded by *both* AVX and synthetic bit denoting Intel CPUs.
        +# One can argue that it's unfair to AMD, but without 'sh[rl]d' it
        +# makes no sense to keep the AVX code path. If somebody feels that
        +# strongly, it's probably more appropriate to discuss possibility of
        +# using vector rotate XOP on AMD...
        +
        +######################################################################
        +# Current performance is summarized in following table. Numbers are
        +# CPU clock cycles spent to process single byte (less is better).
        +#
        +#		x86		SSSE3		AVX
        +# Pentium	15.7		-
        +# PIII		11.5		-
        +# P4		10.6		-
        +# AMD K8	7.1		-
        +# Core2		7.3		6.1/+20%	-
        +# Atom		12.5		9.5(*)/+32%	-
        +# Westmere	7.3		5.6/+30%	-
        +# Sandy Bridge	8.8		6.2/+40%	5.1(**)/+70%
        +#
        +# (*)	Loop is 1056 instructions long and expected result is ~8.25.
        +#	It remains mystery [to me] why ILP is limited to 1.7.
        +#
        +# (**)	As per above comment, the result is for AVX *plus* sh[rl]d.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386");
        +
        +$xmm=$ymm=0;
        +for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +$ymm=1 if ($xmm &&
        +		`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
        +			=~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
        +		$1>=2.19);	# first version supporting AVX
        +
        +$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" && 
        +		`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
        +		$1>=2.03);	# first version supporting AVX
        +
        +&external_label("OPENSSL_ia32cap_P") if ($xmm);
        +
        +
        +$A="eax";
        +$B="ebx";
        +$C="ecx";
        +$D="edx";
        +$E="edi";
        +$T="esi";
        +$tmp1="ebp";
        +
        +@V=($A,$B,$C,$D,$E,$T);
        +
        +$alt=0;	# 1 denotes alternative IALU implementation, which performs
        +	# 8% *worse* on P4, same on Westmere and Atom, 2% better on
        +	# Sandy Bridge...
        +
        +sub BODY_00_15
        +	{
        +	local($n,$a,$b,$c,$d,$e,$f)=@_;
        +
        +	&comment("00_15 $n");
        +
        +	&mov($f,$c);			# f to hold F_00_19(b,c,d)
        +	 if ($n==0)  { &mov($tmp1,$a); }
        +	 else        { &mov($a,$tmp1); }
        +	&rotl($tmp1,5);			# tmp1=ROTATE(a,5)
        +	 &xor($f,$d);
        +	&add($tmp1,$e);			# tmp1+=e;
        +	 &mov($e,&swtmp($n%16));	# e becomes volatile and is loaded
        +	 				# with xi, also note that e becomes
        +					# f in next round...
        +	&and($f,$b);
        +	&rotr($b,2);			# b=ROTATE(b,30)
        +	 &xor($f,$d);			# f holds F_00_19(b,c,d)
        +	&lea($tmp1,&DWP(0x5a827999,$tmp1,$e));	# tmp1+=K_00_19+xi
        +
        +	if ($n==15) { &mov($e,&swtmp(($n+1)%16));# pre-fetch f for next round
        +		      &add($f,$tmp1); }	# f+=tmp1
        +	else        { &add($tmp1,$f); }	# f becomes a in next round
        +	&mov($tmp1,$a)			if ($alt && $n==15);
        +	}
        +
        +sub BODY_16_19
        +	{
        +	local($n,$a,$b,$c,$d,$e,$f)=@_;
        +
        +	&comment("16_19 $n");
        +
        +if ($alt) {
        +	&xor($c,$d);
        +	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
        +	&and($tmp1,$c);			# tmp1 to hold F_00_19(b,c,d), b&=c^d
        +	 &xor($f,&swtmp(($n+8)%16));
        +	&xor($tmp1,$d);			# tmp1=F_00_19(b,c,d)
        +	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
        +	&rotl($f,1);			# f=ROTATE(f,1)
        +	 &add($e,$tmp1);		# e+=F_00_19(b,c,d)
        +	&xor($c,$d);			# restore $c
        +	 &mov($tmp1,$a);		# b in next round
        +	&rotr($b,$n==16?2:7);		# b=ROTATE(b,30)
        +	 &mov(&swtmp($n%16),$f);	# xi=f
        +	&rotl($a,5);			# ROTATE(a,5)
        +	 &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e
        +	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
        +	 &add($f,$a);			# f+=ROTATE(a,5)
        +} else {
        +	&mov($tmp1,$c);			# tmp1 to hold F_00_19(b,c,d)
        +	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
        +	&xor($tmp1,$d);
        +	 &xor($f,&swtmp(($n+8)%16));
        +	&and($tmp1,$b);
        +	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
        +	&rotl($f,1);			# f=ROTATE(f,1)
        +	 &xor($tmp1,$d);		# tmp1=F_00_19(b,c,d)
        +	&add($e,$tmp1);			# e+=F_00_19(b,c,d)
        +	 &mov($tmp1,$a);
        +	&rotr($b,2);			# b=ROTATE(b,30)
        +	 &mov(&swtmp($n%16),$f);	# xi=f
        +	&rotl($tmp1,5);			# ROTATE(a,5)
        +	 &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e
        +	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
        +	 &add($f,$tmp1);		# f+=ROTATE(a,5)
        +}
        +	}
        +
        +sub BODY_20_39
        +	{
        +	local($n,$a,$b,$c,$d,$e,$f)=@_;
        +	local $K=($n<40)?0x6ed9eba1:0xca62c1d6;
        +
        +	&comment("20_39 $n");
        +
        +if ($alt) {
        +	&xor($tmp1,$c);			# tmp1 to hold F_20_39(b,c,d), b^=c
        +	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
        +	&xor($tmp1,$d);			# tmp1 holds F_20_39(b,c,d)
        +	 &xor($f,&swtmp(($n+8)%16));
        +	&add($e,$tmp1);			# e+=F_20_39(b,c,d)
        +	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
        +	&rotl($f,1);			# f=ROTATE(f,1)
        +	 &mov($tmp1,$a);		# b in next round
        +	&rotr($b,7);			# b=ROTATE(b,30)
        +	 &mov(&swtmp($n%16),$f)		if($n<77);# xi=f
        +	&rotl($a,5);			# ROTATE(a,5)
        +	 &xor($b,$c)			if($n==39);# warm up for BODY_40_59
        +	&and($tmp1,$b)			if($n==39);
        +	 &lea($f,&DWP($K,$f,$e));	# f+=e+K_XX_YY
        +	&mov($e,&swtmp(($n+1)%16))	if($n<79);# pre-fetch f for next round
        +	 &add($f,$a);			# f+=ROTATE(a,5)
        +	&rotr($a,5)			if ($n==79);
        +} else {
        +	&mov($tmp1,$b);			# tmp1 to hold F_20_39(b,c,d)
        +	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
        +	&xor($tmp1,$c);
        +	 &xor($f,&swtmp(($n+8)%16));
        +	&xor($tmp1,$d);			# tmp1 holds F_20_39(b,c,d)
        +	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
        +	&rotl($f,1);			# f=ROTATE(f,1)
        +	 &add($e,$tmp1);		# e+=F_20_39(b,c,d)
        +	&rotr($b,2);			# b=ROTATE(b,30)
        +	 &mov($tmp1,$a);
        +	&rotl($tmp1,5);			# ROTATE(a,5)
        +	 &mov(&swtmp($n%16),$f) if($n<77);# xi=f
        +	&lea($f,&DWP($K,$f,$e));	# f+=e+K_XX_YY
        +	 &mov($e,&swtmp(($n+1)%16)) if($n<79);# pre-fetch f for next round
        +	&add($f,$tmp1);			# f+=ROTATE(a,5)
        +}
        +	}
        +
        +sub BODY_40_59
        +	{
        +	local($n,$a,$b,$c,$d,$e,$f)=@_;
        +
        +	&comment("40_59 $n");
        +
        +if ($alt) {
        +	&add($e,$tmp1);			# e+=b&(c^d)
        +	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
        +	&mov($tmp1,$d);
        +	 &xor($f,&swtmp(($n+8)%16));
        +	&xor($c,$d);			# restore $c
        +	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
        +	&rotl($f,1);			# f=ROTATE(f,1)
        +	 &and($tmp1,$c);
        +	&rotr($b,7);			# b=ROTATE(b,30)
        +	 &add($e,$tmp1);		# e+=c&d
        +	&mov($tmp1,$a);			# b in next round
        +	 &mov(&swtmp($n%16),$f);	# xi=f
        +	&rotl($a,5);			# ROTATE(a,5)
        +	 &xor($b,$c)			if ($n<59);
        +	&and($tmp1,$b)			if ($n<59);# tmp1 to hold F_40_59(b,c,d)
        +	 &lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e+(b&(c^d))
        +	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
        +	 &add($f,$a);			# f+=ROTATE(a,5)
        +} else {
        +	&mov($tmp1,$c);			# tmp1 to hold F_40_59(b,c,d)
        +	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
        +	&xor($tmp1,$d);
        +	 &xor($f,&swtmp(($n+8)%16));
        +	&and($tmp1,$b);
        +	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
        +	&rotl($f,1);			# f=ROTATE(f,1)
        +	 &add($tmp1,$e);		# b&(c^d)+=e
        +	&rotr($b,2);			# b=ROTATE(b,30)
        +	 &mov($e,$a);			# e becomes volatile
        +	&rotl($e,5);			# ROTATE(a,5)
        +	 &mov(&swtmp($n%16),$f);	# xi=f
        +	&lea($f,&DWP(0x8f1bbcdc,$f,$tmp1));# f+=K_40_59+e+(b&(c^d))
        +	 &mov($tmp1,$c);
        +	&add($f,$e);			# f+=ROTATE(a,5)
        +	 &and($tmp1,$d);
        +	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
        +	 &add($f,$tmp1);		# f+=c&d
        +}
        +	}
        +
        +&function_begin("sha1_block_data_order");
        +if ($xmm) {
        +  &static_label("ssse3_shortcut");
        +  &static_label("avx_shortcut")		if ($ymm);
        +  &static_label("K_XX_XX");
        +
        +	&call	(&label("pic_point"));	# make it PIC!
        +  &set_label("pic_point");
        +	&blindpop($tmp1);
        +	&picmeup($T,"OPENSSL_ia32cap_P",$tmp1,&label("pic_point"));
        +	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
        +
        +	&mov	($A,&DWP(0,$T));
        +	&mov	($D,&DWP(4,$T));
        +	&test	($D,1<<9);		# check SSSE3 bit
        +	&jz	(&label("x86"));
        +	&test	($A,1<<24);		# check FXSR bit
        +	&jz	(&label("x86"));
        +	if ($ymm) {
        +		&and	($D,1<<28);		# mask AVX bit
        +		&and	($A,1<<30);		# mask "Intel CPU" bit
        +		&or	($A,$D);
        +		&cmp	($A,1<<28|1<<30);
        +		&je	(&label("avx_shortcut"));
        +	}
        +	&jmp	(&label("ssse3_shortcut"));
        +  &set_label("x86",16);
        +}
        +	&mov($tmp1,&wparam(0));	# SHA_CTX *c
        +	&mov($T,&wparam(1));	# const void *input
        +	&mov($A,&wparam(2));	# size_t num
        +	&stack_push(16+3);	# allocate X[16]
        +	&shl($A,6);
        +	&add($A,$T);
        +	&mov(&wparam(2),$A);	# pointer beyond the end of input
        +	&mov($E,&DWP(16,$tmp1));# pre-load E
        +	&jmp(&label("loop"));
        +
        +&set_label("loop",16);
        +
        +	# copy input chunk to X, but reversing byte order!
        +	for ($i=0; $i<16; $i+=4)
        +		{
        +		&mov($A,&DWP(4*($i+0),$T));
        +		&mov($B,&DWP(4*($i+1),$T));
        +		&mov($C,&DWP(4*($i+2),$T));
        +		&mov($D,&DWP(4*($i+3),$T));
        +		&bswap($A);
        +		&bswap($B);
        +		&bswap($C);
        +		&bswap($D);
        +		&mov(&swtmp($i+0),$A);
        +		&mov(&swtmp($i+1),$B);
        +		&mov(&swtmp($i+2),$C);
        +		&mov(&swtmp($i+3),$D);
        +		}
        +	&mov(&wparam(1),$T);	# redundant in 1st spin
        +
        +	&mov($A,&DWP(0,$tmp1));	# load SHA_CTX
        +	&mov($B,&DWP(4,$tmp1));
        +	&mov($C,&DWP(8,$tmp1));
        +	&mov($D,&DWP(12,$tmp1));
        +	# E is pre-loaded
        +
        +	for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +
        +	(($V[5] eq $D) and ($V[0] eq $E)) or die;	# double-check
        +
        +	&mov($tmp1,&wparam(0));	# re-load SHA_CTX*
        +	&mov($D,&wparam(1));	# D is last "T" and is discarded
        +
        +	&add($E,&DWP(0,$tmp1));	# E is last "A"...
        +	&add($T,&DWP(4,$tmp1));
        +	&add($A,&DWP(8,$tmp1));
        +	&add($B,&DWP(12,$tmp1));
        +	&add($C,&DWP(16,$tmp1));
        +
        +	&mov(&DWP(0,$tmp1),$E);	# update SHA_CTX
        +	 &add($D,64);		# advance input pointer
        +	&mov(&DWP(4,$tmp1),$T);
        +	 &cmp($D,&wparam(2));	# have we reached the end yet?
        +	&mov(&DWP(8,$tmp1),$A);
        +	 &mov($E,$C);		# C is last "E" which needs to be "pre-loaded"
        +	&mov(&DWP(12,$tmp1),$B);
        +	 &mov($T,$D);		# input pointer
        +	&mov(&DWP(16,$tmp1),$C);
        +	&jb(&label("loop"));
        +
        +	&stack_pop(16+3);
        +&function_end("sha1_block_data_order");
        +
        +if ($xmm) {
        +######################################################################
        +# The SSSE3 implementation.
        +#
        +# %xmm[0-7] are used as ring @X[] buffer containing quadruples of last
        +# 32 elements of the message schedule or Xupdate outputs. First 4
        +# quadruples are simply byte-swapped input, next 4 are calculated
        +# according to method originally suggested by Dean Gaudet (modulo
        +# being implemented in SSSE3). Once 8 quadruples or 32 elements are
        +# collected, it switches to routine proposed by Max Locktyukhin.
        +#
        +# Calculations inevitably require temporary reqisters, and there are
        +# no %xmm registers left to spare. For this reason part of the ring
        +# buffer, X[2..4] to be specific, is offloaded to 3 quadriples ring
        +# buffer on the stack. Keep in mind that X[2] is alias X[-6], X[3] -
        +# X[-5], and X[4] - X[-4]...
        +#
        +# Another notable optimization is aggressive stack frame compression
        +# aiming to minimize amount of 9-byte instructions...
        +#
        +# Yet another notable optimization is "jumping" $B variable. It means
        +# that there is no register permanently allocated for $B value. This
        +# allowed to eliminate one instruction from body_20_39...
        +#
        +my $Xi=4;			# 4xSIMD Xupdate round, start pre-seeded
        +my @X=map("xmm$_",(4..7,0..3));	# pre-seeded for $Xi=4
        +my @V=($A,$B,$C,$D,$E);
        +my $j=0;			# hash round
        +my @T=($T,$tmp1);
        +my $inp;
        +
        +my $_rol=sub { &rol(@_) };
        +my $_ror=sub { &ror(@_) };
        +
        +&function_begin("_sha1_block_data_order_ssse3");
        +	&call	(&label("pic_point"));	# make it PIC!
        +	&set_label("pic_point");
        +	&blindpop($tmp1);
        +	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
        +&set_label("ssse3_shortcut");
        +
        +	&movdqa	(@X[3],&QWP(0,$tmp1));		# K_00_19
        +	&movdqa	(@X[4],&QWP(16,$tmp1));		# K_20_39
        +	&movdqa	(@X[5],&QWP(32,$tmp1));		# K_40_59
        +	&movdqa	(@X[6],&QWP(48,$tmp1));		# K_60_79
        +	&movdqa	(@X[2],&QWP(64,$tmp1));		# pbswap mask
        +
        +	&mov	($E,&wparam(0));		# load argument block
        +	&mov	($inp=@T[1],&wparam(1));
        +	&mov	($D,&wparam(2));
        +	&mov	(@T[0],"esp");
        +
        +	# stack frame layout
        +	#
        +	# +0	X[0]+K	X[1]+K	X[2]+K	X[3]+K	# XMM->IALU xfer area
        +	#	X[4]+K	X[5]+K	X[6]+K	X[7]+K
        +	#	X[8]+K	X[9]+K	X[10]+K	X[11]+K
        +	#	X[12]+K	X[13]+K	X[14]+K	X[15]+K
        +	#
        +	# +64	X[0]	X[1]	X[2]	X[3]	# XMM->XMM backtrace area
        +	#	X[4]	X[5]	X[6]	X[7]
        +	#	X[8]	X[9]	X[10]	X[11]	# even borrowed for K_00_19
        +	#
        +	# +112	K_20_39	K_20_39	K_20_39	K_20_39	# constants
        +	#	K_40_59	K_40_59	K_40_59	K_40_59
        +	#	K_60_79	K_60_79	K_60_79	K_60_79
        +	#	K_00_19	K_00_19	K_00_19	K_00_19
        +	#	pbswap mask
        +	#
        +	# +192	ctx				# argument block
        +	# +196	inp
        +	# +200	end
        +	# +204	esp
        +	&sub	("esp",208);
        +	&and	("esp",-64);
        +
        +	&movdqa	(&QWP(112+0,"esp"),@X[4]);	# copy constants
        +	&movdqa	(&QWP(112+16,"esp"),@X[5]);
        +	&movdqa	(&QWP(112+32,"esp"),@X[6]);
        +	&shl	($D,6);				# len*64
        +	&movdqa	(&QWP(112+48,"esp"),@X[3]);
        +	&add	($D,$inp);			# end of input
        +	&movdqa	(&QWP(112+64,"esp"),@X[2]);
        +	&add	($inp,64);
        +	&mov	(&DWP(192+0,"esp"),$E);		# save argument block
        +	&mov	(&DWP(192+4,"esp"),$inp);
        +	&mov	(&DWP(192+8,"esp"),$D);
        +	&mov	(&DWP(192+12,"esp"),@T[0]);	# save original %esp
        +
        +	&mov	($A,&DWP(0,$E));		# load context
        +	&mov	($B,&DWP(4,$E));
        +	&mov	($C,&DWP(8,$E));
        +	&mov	($D,&DWP(12,$E));
        +	&mov	($E,&DWP(16,$E));
        +	&mov	(@T[0],$B);			# magic seed
        +
        +	&movdqu	(@X[-4&7],&QWP(-64,$inp));	# load input to %xmm[0-3]
        +	&movdqu	(@X[-3&7],&QWP(-48,$inp));
        +	&movdqu	(@X[-2&7],&QWP(-32,$inp));
        +	&movdqu	(@X[-1&7],&QWP(-16,$inp));
        +	&pshufb	(@X[-4&7],@X[2]);		# byte swap
        +	&pshufb	(@X[-3&7],@X[2]);
        +	&pshufb	(@X[-2&7],@X[2]);
        +	&movdqa	(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
        +	&pshufb	(@X[-1&7],@X[2]);
        +	&paddd	(@X[-4&7],@X[3]);		# add K_00_19
        +	&paddd	(@X[-3&7],@X[3]);
        +	&paddd	(@X[-2&7],@X[3]);
        +	&movdqa	(&QWP(0,"esp"),@X[-4&7]);	# X[]+K xfer to IALU
        +	&psubd	(@X[-4&7],@X[3]);		# restore X[]
        +	&movdqa	(&QWP(0+16,"esp"),@X[-3&7]);
        +	&psubd	(@X[-3&7],@X[3]);
        +	&movdqa	(&QWP(0+32,"esp"),@X[-2&7]);
        +	&psubd	(@X[-2&7],@X[3]);
        +	&movdqa	(@X[0],@X[-3&7]);
        +	&jmp	(&label("loop"));
        +
        +######################################################################
        +# SSE instruction sequence is first broken to groups of indepentent
        +# instructions, independent in respect to their inputs and shifter
        +# (not all architectures have more than one). Then IALU instructions
        +# are "knitted in" between the SSE groups. Distance is maintained for
        +# SSE latency of 2 in hope that it fits better upcoming AMD Bulldozer
        +# [which allegedly also implements SSSE3]...
        +#
        +# Temporary registers usage. X[2] is volatile at the entry and at the
        +# end is restored from backtrace ring buffer. X[3] is expected to
        +# contain current K_XX_XX constant and is used to caclulate X[-1]+K
        +# from previous round, it becomes volatile the moment the value is
        +# saved to stack for transfer to IALU. X[4] becomes volatile whenever
        +# X[-4] is accumulated and offloaded to backtrace ring buffer, at the
        +# end it is loaded with next K_XX_XX [which becomes X[3] in next
        +# round]...
        +#
        +sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&palignr(@X[0],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
        +	&movdqa	(@X[2],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &paddd	(@X[3],@X[-1&7]);
        +	  &movdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&psrldq	(@X[2],4);		# "X[-3]", 3 dwords
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&pxor	(@X[0],@X[-4&7]);	# "X[0]"^="X[-16]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[2],@X[-2&7]);	# "X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@X[2]);		# "X[0]"^="X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&movdqa	(@X[4],@X[0]);
        +	&movdqa	(@X[2],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pslldq	(@X[4],12);		# "X[0]"<<96, extract one dword
        +	&paddd	(@X[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&psrld	(@X[2],31);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(@X[3],@X[4]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&psrld	(@X[4],30);
        +	&por	(@X[0],@X[2]);		# "X[0]"<<<=1
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5);	# restore X[] from backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pslld	(@X[3],2);
        +	&pxor	(@X[0],@X[4]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(@X[4],&QWP(112-16+16*(($Xi)/5),"esp"));	# K_XX_XX
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@X[3]);		# "X[0]"^=("X[0]"<<96)<<<2
        +	  &movdqa	(@X[1],@X[-2&7])	if ($Xi<7);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions [if any]
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +}
        +
        +sub Xupdate_ssse3_32_79()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&movdqa	(@X[2],@X[-1&7])	if ($Xi==8);
        +	 eval(shift(@insns));		# body_20_39
        +	&pxor	(@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
        +	&palignr(@X[2],@X[-2&7],8);	# compose "X[-6]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&pxor	(@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
        +	  &movdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);	# save X[] to backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 if ($Xi%5) {
        +	  &movdqa	(@X[4],@X[3]);	# "perpetuate" K_XX_XX...
        +	 } else {			# ... or load next one
        +	  &movdqa	(@X[4],&QWP(112-16+16*($Xi/5),"esp"));
        +	 }
        +	  &paddd	(@X[3],@X[-1&7]);
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@X[2]);		# "X[0]"^="X[-6]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&movdqa	(@X[2],@X[0]);
        +	  &movdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&pslld	(@X[0],2);
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	&psrld	(@X[2],30);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&por	(@X[0],@X[2]);		# "X[0]"<<<=2
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	  &movdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19);	# restore X[] from backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	  &movdqa	(@X[3],@X[0])	if ($Xi<19);
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +}
        +
        +sub Xuplast_ssse3_80()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	  &paddd	(@X[3],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &movdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer IALU
        +
        +	 foreach (@insns) { eval; }		# remaining instructions
        +
        +	&mov	($inp=@T[1],&DWP(192+4,"esp"));
        +	&cmp	($inp,&DWP(192+8,"esp"));
        +	&je	(&label("done"));
        +
        +	&movdqa	(@X[3],&QWP(112+48,"esp"));	# K_00_19
        +	&movdqa	(@X[2],&QWP(112+64,"esp"));	# pbswap mask
        +	&movdqu	(@X[-4&7],&QWP(0,$inp));	# load input
        +	&movdqu	(@X[-3&7],&QWP(16,$inp));
        +	&movdqu	(@X[-2&7],&QWP(32,$inp));
        +	&movdqu	(@X[-1&7],&QWP(48,$inp));
        +	&add	($inp,64);
        +	&pshufb	(@X[-4&7],@X[2]);		# byte swap
        +	&mov	(&DWP(192+4,"esp"),$inp);
        +	&movdqa	(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
        +
        +  $Xi=0;
        +}
        +
        +sub Xloop_ssse3()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&pshufb	(@X[($Xi-3)&7],@X[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&paddd	(@X[($Xi-4)&7],@X[3]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(&QWP(0+16*$Xi,"esp"),@X[($Xi-4)&7]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&psubd	(@X[($Xi-4)&7],@X[3]);
        +
        +	foreach (@insns) { eval; }
        +  $Xi++;
        +}
        +
        +sub Xtail_ssse3()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	foreach (@insns) { eval; }
        +}
        +
        +sub body_00_19 () {
        +	(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&add	($e,&DWP(4*($j&15),"esp"));',	# X[]+K xfer
        +	'&xor	($c,$d);',
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&and	(@T[0],$c);',	# ($b&($c^$d))
        +	'&xor	($c,$d);',	# restore $c
        +	'&xor	(@T[0],$d);',
        +	'&add	($e,$a);',
        +	'&$_ror	($b,$j?7:2);',	# $b>>>2
        +	'&add	($e,@T[0]);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +}
        +
        +sub body_20_39 () {
        +	(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&add	($e,&DWP(4*($j++&15),"esp"));',	# X[]+K xfer
        +	'&xor	(@T[0],$d);',	# ($b^$d)
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&xor	(@T[0],$c);',	# ($b^$d^$c)
        +	'&add	($e,$a);',
        +	'&$_ror	($b,7);',	# $b>>>2
        +	'&add	($e,@T[0]);'	.'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +}
        +
        +sub body_40_59 () {
        +	(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&mov	(@T[1],$c);',
        +	'&xor	($c,$d);',
        +	'&add	($e,&DWP(4*($j++&15),"esp"));',	# X[]+K xfer
        +	'&and	(@T[1],$d);',
        +	'&and	(@T[0],$c);',	# ($b&($c^$d))
        +	'&$_ror	($b,7);',	# $b>>>2
        +	'&add	($e,@T[1]);',
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&add	($e,@T[0]);',
        +	'&xor	($c,$d);',	# restore $c
        +	'&add	($e,$a);'	.'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +}
        +
        +&set_label("loop",16);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_32_79(\&body_00_19);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xuplast_ssse3_80(\&body_20_39);	# can jump to "done"
        +
        +				$saved_j=$j; @saved_V=@V;
        +
        +	&Xloop_ssse3(\&body_20_39);
        +	&Xloop_ssse3(\&body_20_39);
        +	&Xloop_ssse3(\&body_20_39);
        +
        +	&mov	(@T[1],&DWP(192,"esp"));	# update context
        +	&add	($A,&DWP(0,@T[1]));
        +	&add	(@T[0],&DWP(4,@T[1]));		# $b
        +	&add	($C,&DWP(8,@T[1]));
        +	&mov	(&DWP(0,@T[1]),$A);
        +	&add	($D,&DWP(12,@T[1]));
        +	&mov	(&DWP(4,@T[1]),@T[0]);
        +	&add	($E,&DWP(16,@T[1]));
        +	&mov	(&DWP(8,@T[1]),$C);
        +	&mov	($B,@T[0]);
        +	&mov	(&DWP(12,@T[1]),$D);
        +	&mov	(&DWP(16,@T[1]),$E);
        +	&movdqa	(@X[0],@X[-3&7]);
        +
        +	&jmp	(&label("loop"));
        +
        +&set_label("done",16);		$j=$saved_j; @V=@saved_V;
        +
        +	&Xtail_ssse3(\&body_20_39);
        +	&Xtail_ssse3(\&body_20_39);
        +	&Xtail_ssse3(\&body_20_39);
        +
        +	&mov	(@T[1],&DWP(192,"esp"));	# update context
        +	&add	($A,&DWP(0,@T[1]));
        +	&mov	("esp",&DWP(192+12,"esp"));	# restore %esp
        +	&add	(@T[0],&DWP(4,@T[1]));		# $b
        +	&add	($C,&DWP(8,@T[1]));
        +	&mov	(&DWP(0,@T[1]),$A);
        +	&add	($D,&DWP(12,@T[1]));
        +	&mov	(&DWP(4,@T[1]),@T[0]);
        +	&add	($E,&DWP(16,@T[1]));
        +	&mov	(&DWP(8,@T[1]),$C);
        +	&mov	(&DWP(12,@T[1]),$D);
        +	&mov	(&DWP(16,@T[1]),$E);
        +
        +&function_end("_sha1_block_data_order_ssse3");
        +
        +if ($ymm) {
        +my $Xi=4;			# 4xSIMD Xupdate round, start pre-seeded
        +my @X=map("xmm$_",(4..7,0..3));	# pre-seeded for $Xi=4
        +my @V=($A,$B,$C,$D,$E);
        +my $j=0;			# hash round
        +my @T=($T,$tmp1);
        +my $inp;
        +
        +my $_rol=sub { &shld(@_[0],@_) };
        +my $_ror=sub { &shrd(@_[0],@_) };
        +
        +&function_begin("_sha1_block_data_order_avx");
        +	&call	(&label("pic_point"));	# make it PIC!
        +	&set_label("pic_point");
        +	&blindpop($tmp1);
        +	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
        +&set_label("avx_shortcut");
        +	&vzeroall();
        +
        +	&vmovdqa(@X[3],&QWP(0,$tmp1));		# K_00_19
        +	&vmovdqa(@X[4],&QWP(16,$tmp1));		# K_20_39
        +	&vmovdqa(@X[5],&QWP(32,$tmp1));		# K_40_59
        +	&vmovdqa(@X[6],&QWP(48,$tmp1));		# K_60_79
        +	&vmovdqa(@X[2],&QWP(64,$tmp1));		# pbswap mask
        +
        +	&mov	($E,&wparam(0));		# load argument block
        +	&mov	($inp=@T[1],&wparam(1));
        +	&mov	($D,&wparam(2));
        +	&mov	(@T[0],"esp");
        +
        +	# stack frame layout
        +	#
        +	# +0	X[0]+K	X[1]+K	X[2]+K	X[3]+K	# XMM->IALU xfer area
        +	#	X[4]+K	X[5]+K	X[6]+K	X[7]+K
        +	#	X[8]+K	X[9]+K	X[10]+K	X[11]+K
        +	#	X[12]+K	X[13]+K	X[14]+K	X[15]+K
        +	#
        +	# +64	X[0]	X[1]	X[2]	X[3]	# XMM->XMM backtrace area
        +	#	X[4]	X[5]	X[6]	X[7]
        +	#	X[8]	X[9]	X[10]	X[11]	# even borrowed for K_00_19
        +	#
        +	# +112	K_20_39	K_20_39	K_20_39	K_20_39	# constants
        +	#	K_40_59	K_40_59	K_40_59	K_40_59
        +	#	K_60_79	K_60_79	K_60_79	K_60_79
        +	#	K_00_19	K_00_19	K_00_19	K_00_19
        +	#	pbswap mask
        +	#
        +	# +192	ctx				# argument block
        +	# +196	inp
        +	# +200	end
        +	# +204	esp
        +	&sub	("esp",208);
        +	&and	("esp",-64);
        +
        +	&vmovdqa(&QWP(112+0,"esp"),@X[4]);	# copy constants
        +	&vmovdqa(&QWP(112+16,"esp"),@X[5]);
        +	&vmovdqa(&QWP(112+32,"esp"),@X[6]);
        +	&shl	($D,6);				# len*64
        +	&vmovdqa(&QWP(112+48,"esp"),@X[3]);
        +	&add	($D,$inp);			# end of input
        +	&vmovdqa(&QWP(112+64,"esp"),@X[2]);
        +	&add	($inp,64);
        +	&mov	(&DWP(192+0,"esp"),$E);		# save argument block
        +	&mov	(&DWP(192+4,"esp"),$inp);
        +	&mov	(&DWP(192+8,"esp"),$D);
        +	&mov	(&DWP(192+12,"esp"),@T[0]);	# save original %esp
        +
        +	&mov	($A,&DWP(0,$E));		# load context
        +	&mov	($B,&DWP(4,$E));
        +	&mov	($C,&DWP(8,$E));
        +	&mov	($D,&DWP(12,$E));
        +	&mov	($E,&DWP(16,$E));
        +	&mov	(@T[0],$B);			# magic seed
        +
        +	&vmovdqu(@X[-4&7],&QWP(-64,$inp));	# load input to %xmm[0-3]
        +	&vmovdqu(@X[-3&7],&QWP(-48,$inp));
        +	&vmovdqu(@X[-2&7],&QWP(-32,$inp));
        +	&vmovdqu(@X[-1&7],&QWP(-16,$inp));
        +	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);	# byte swap
        +	&vpshufb(@X[-3&7],@X[-3&7],@X[2]);
        +	&vpshufb(@X[-2&7],@X[-2&7],@X[2]);
        +	&vmovdqa(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
        +	&vpshufb(@X[-1&7],@X[-1&7],@X[2]);
        +	&vpaddd	(@X[0],@X[-4&7],@X[3]);		# add K_00_19
        +	&vpaddd	(@X[1],@X[-3&7],@X[3]);
        +	&vpaddd	(@X[2],@X[-2&7],@X[3]);
        +	&vmovdqa(&QWP(0,"esp"),@X[0]);		# X[]+K xfer to IALU
        +	&vmovdqa(&QWP(0+16,"esp"),@X[1]);
        +	&vmovdqa(&QWP(0+32,"esp"),@X[2]);
        +	&jmp	(&label("loop"));
        +
        +sub Xupdate_avx_16_31()		# recall that $Xi starts wtih 4
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &vpaddd	(@X[3],@X[3],@X[-1&7]);
        +	  &vmovdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpsrldq(@X[2],@X[-1&7],4);		# "X[-3]", 3 dwords
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[2],@X[2],@X[-2&7]);		# "X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &vmovdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@X[2]);		# "X[0]"^="X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpsrld	(@X[2],@X[0],31);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpslldq(@X[4],@X[0],12);		# "X[0]"<<96, extract one dword
        +	&vpaddd	(@X[0],@X[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpsrld	(@X[3],@X[4],30);
        +	&vpor	(@X[0],@X[0],@X[2]);		# "X[0]"<<<=1
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpslld	(@X[4],@X[4],2);
        +	  &vmovdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5);	# restore X[] from backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpxor	(@X[0],@X[0],@X[3]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@X[4]);		# "X[0]"^=("X[0]"<<96)<<<2
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &vmovdqa	(@X[4],&QWP(112-16+16*(($Xi)/5),"esp"));	# K_XX_XX
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions [if any]
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +}
        +
        +sub Xupdate_avx_32_79()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&vpalignr(@X[2],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
        +	&vpxor	(@X[0],@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&vpxor	(@X[0],@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
        +	  &vmovdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);	# save X[] to backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 if ($Xi%5) {
        +	  &vmovdqa	(@X[4],@X[3]);	# "perpetuate" K_XX_XX...
        +	 } else {			# ... or load next one
        +	  &vmovdqa	(@X[4],&QWP(112-16+16*($Xi/5),"esp"));
        +	 }
        +	  &vpaddd	(@X[3],@X[3],@X[-1&7]);
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@X[2]);		# "X[0]"^="X[-6]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&vpsrld	(@X[2],@X[0],30);
        +	  &vmovdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpslld	(@X[0],@X[0],2);
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpor	(@X[0],@X[0],@X[2]);	# "X[0]"<<<=2
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	  &vmovdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19);	# restore X[] from backtrace buffer
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +}
        +
        +sub Xuplast_avx_80()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	  &vpaddd	(@X[3],@X[3],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &vmovdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer IALU
        +
        +	 foreach (@insns) { eval; }		# remaining instructions
        +
        +	&mov	($inp=@T[1],&DWP(192+4,"esp"));
        +	&cmp	($inp,&DWP(192+8,"esp"));
        +	&je	(&label("done"));
        +
        +	&vmovdqa(@X[3],&QWP(112+48,"esp"));	# K_00_19
        +	&vmovdqa(@X[2],&QWP(112+64,"esp"));	# pbswap mask
        +	&vmovdqu(@X[-4&7],&QWP(0,$inp));	# load input
        +	&vmovdqu(@X[-3&7],&QWP(16,$inp));
        +	&vmovdqu(@X[-2&7],&QWP(32,$inp));
        +	&vmovdqu(@X[-1&7],&QWP(48,$inp));
        +	&add	($inp,64);
        +	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);		# byte swap
        +	&mov	(&DWP(192+4,"esp"),$inp);
        +	&vmovdqa(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
        +
        +  $Xi=0;
        +}
        +
        +sub Xloop_avx()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpshufb	(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpaddd	(@X[$Xi&7],@X[($Xi-4)&7],@X[3]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vmovdqa	(&QWP(0+16*$Xi,"esp"),@X[$Xi&7]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	foreach (@insns) { eval; }
        +  $Xi++;
        +}
        +
        +sub Xtail_avx()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	foreach (@insns) { eval; }
        +}
        +
        +&set_label("loop",16);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_32_79(\&body_00_19);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xuplast_avx_80(\&body_20_39);	# can jump to "done"
        +
        +				$saved_j=$j; @saved_V=@V;
        +
        +	&Xloop_avx(\&body_20_39);
        +	&Xloop_avx(\&body_20_39);
        +	&Xloop_avx(\&body_20_39);
        +
        +	&mov	(@T[1],&DWP(192,"esp"));	# update context
        +	&add	($A,&DWP(0,@T[1]));
        +	&add	(@T[0],&DWP(4,@T[1]));		# $b
        +	&add	($C,&DWP(8,@T[1]));
        +	&mov	(&DWP(0,@T[1]),$A);
        +	&add	($D,&DWP(12,@T[1]));
        +	&mov	(&DWP(4,@T[1]),@T[0]);
        +	&add	($E,&DWP(16,@T[1]));
        +	&mov	(&DWP(8,@T[1]),$C);
        +	&mov	($B,@T[0]);
        +	&mov	(&DWP(12,@T[1]),$D);
        +	&mov	(&DWP(16,@T[1]),$E);
        +
        +	&jmp	(&label("loop"));
        +
        +&set_label("done",16);		$j=$saved_j; @V=@saved_V;
        +
        +	&Xtail_avx(\&body_20_39);
        +	&Xtail_avx(\&body_20_39);
        +	&Xtail_avx(\&body_20_39);
        +
        +	&vzeroall();
        +
        +	&mov	(@T[1],&DWP(192,"esp"));	# update context
        +	&add	($A,&DWP(0,@T[1]));
        +	&mov	("esp",&DWP(192+12,"esp"));	# restore %esp
        +	&add	(@T[0],&DWP(4,@T[1]));		# $b
        +	&add	($C,&DWP(8,@T[1]));
        +	&mov	(&DWP(0,@T[1]),$A);
        +	&add	($D,&DWP(12,@T[1]));
        +	&mov	(&DWP(4,@T[1]),@T[0]);
        +	&add	($E,&DWP(16,@T[1]));
        +	&mov	(&DWP(8,@T[1]),$C);
        +	&mov	(&DWP(12,@T[1]),$D);
        +	&mov	(&DWP(16,@T[1]),$E);
        +&function_end("_sha1_block_data_order_avx");
        +}
        +&set_label("K_XX_XX",64);
        +&data_word(0x5a827999,0x5a827999,0x5a827999,0x5a827999);	# K_00_19
        +&data_word(0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1);	# K_20_39
        +&data_word(0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc);	# K_40_59
        +&data_word(0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6);	# K_60_79
        +&data_word(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f);	# pbswap mask
        +}
        +&asciz("SHA1 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-alpha.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-alpha.pl
        new file mode 100644
        index 000000000..6c4b9251f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-alpha.pl
        @@ -0,0 +1,322 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA1 block procedure for Alpha.
        +
        +# On 21264 performance is 33% better than code generated by vendor
        +# compiler, and 75% better than GCC [3.4], and in absolute terms is
        +# 8.7 cycles per processed byte. Implementation features vectorized
        +# byte swap, but not Xupdate.
        +
        +@X=(	"\$0",	"\$1",	"\$2",	"\$3",	"\$4",	"\$5",	"\$6",	"\$7",
        +	"\$8",	"\$9",	"\$10",	"\$11",	"\$12",	"\$13",	"\$14",	"\$15");
        +$ctx="a0";	# $16
        +$inp="a1";
        +$num="a2";
        +$A="a3";
        +$B="a4";	# 20
        +$C="a5";
        +$D="t8";
        +$E="t9";	@V=($A,$B,$C,$D,$E);
        +$t0="t10";	# 24
        +$t1="t11";
        +$t2="ra";
        +$t3="t12";
        +$K="AT";	# 28
        +
        +sub BODY_00_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i==0);
        +	ldq_u	@X[0],0+0($inp)
        +	ldq_u	@X[1],0+7($inp)
        +___
        +$code.=<<___ if (!($i&1) && $i<14);
        +	ldq_u	@X[$i+2],($i+2)*4+0($inp)
        +	ldq_u	@X[$i+3],($i+2)*4+7($inp)
        +___
        +$code.=<<___ if (!($i&1) && $i<15);
        +	extql	@X[$i],$inp,@X[$i]
        +	extqh	@X[$i+1],$inp,@X[$i+1]
        +
        +	or	@X[$i+1],@X[$i],@X[$i]	# pair of 32-bit values are fetched
        +
        +	srl	@X[$i],24,$t0		# vectorized byte swap
        +	srl	@X[$i],8,$t2
        +
        +	sll	@X[$i],8,$t3
        +	sll	@X[$i],24,@X[$i]
        +	zapnot	$t0,0x11,$t0
        +	zapnot	$t2,0x22,$t2
        +
        +	zapnot	@X[$i],0x88,@X[$i]
        +	or	$t0,$t2,$t0
        +	zapnot	$t3,0x44,$t3
        +	sll	$a,5,$t1
        +
        +	or	@X[$i],$t0,@X[$i]
        +	addl	$K,$e,$e
        +	and	$b,$c,$t2
        +	zapnot	$a,0xf,$a
        +
        +	or	@X[$i],$t3,@X[$i]
        +	srl	$a,27,$t0
        +	bic	$d,$b,$t3
        +	sll	$b,30,$b
        +
        +	extll	@X[$i],4,@X[$i+1]	# extract upper half
        +	or	$t2,$t3,$t2
        +	addl	@X[$i],$e,$e
        +
        +	addl	$t1,$e,$e
        +	srl	$b,32,$t3
        +	zapnot	@X[$i],0xf,@X[$i]
        +
        +	addl	$t0,$e,$e
        +	addl	$t2,$e,$e
        +	or	$t3,$b,$b
        +___
        +$code.=<<___ if (($i&1) && $i<15);
        +	sll	$a,5,$t1
        +	addl	$K,$e,$e
        +	and	$b,$c,$t2
        +	zapnot	$a,0xf,$a
        +
        +	srl	$a,27,$t0
        +	addl	@X[$i%16],$e,$e
        +	bic	$d,$b,$t3
        +	sll	$b,30,$b
        +
        +	or	$t2,$t3,$t2
        +	addl	$t1,$e,$e
        +	srl	$b,32,$t3
        +	zapnot	@X[$i],0xf,@X[$i]
        +
        +	addl	$t0,$e,$e
        +	addl	$t2,$e,$e
        +	or	$t3,$b,$b
        +___
        +$code.=<<___ if ($i>=15);	# with forward Xupdate
        +	sll	$a,5,$t1
        +	addl	$K,$e,$e
        +	and	$b,$c,$t2
        +	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
        +
        +	zapnot	$a,0xf,$a
        +	addl	@X[$i%16],$e,$e
        +	bic	$d,$b,$t3
        +	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
        +
        +	srl	$a,27,$t0
        +	addl	$t1,$e,$e
        +	or	$t2,$t3,$t2
        +	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
        +
        +	sll	$b,30,$b
        +	addl	$t0,$e,$e
        +	srl	@X[$j%16],31,$t1
        +
        +	addl	$t2,$e,$e
        +	srl	$b,32,$t3
        +	addl	@X[$j%16],@X[$j%16],@X[$j%16]
        +
        +	or	$t3,$b,$b
        +	zapnot	@X[$i%16],0xf,@X[$i%16]
        +	or	$t1,@X[$j%16],@X[$j%16]
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i<79);	# with forward Xupdate
        +	sll	$a,5,$t1
        +	addl	$K,$e,$e
        +	zapnot	$a,0xf,$a
        +	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
        +
        +	sll	$b,30,$t3
        +	addl	$t1,$e,$e
        +	xor	$b,$c,$t2
        +	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
        +
        +	srl	$b,2,$b
        +	addl	@X[$i%16],$e,$e
        +	xor	$d,$t2,$t2
        +	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
        +
        +	srl	@X[$j%16],31,$t1
        +	addl	$t2,$e,$e
        +	srl	$a,27,$t0
        +	addl	@X[$j%16],@X[$j%16],@X[$j%16]
        +
        +	or	$t3,$b,$b
        +	addl	$t0,$e,$e
        +	or	$t1,@X[$j%16],@X[$j%16]
        +___
        +$code.=<<___ if ($i<77);
        +	zapnot	@X[$i%16],0xf,@X[$i%16]
        +___
        +$code.=<<___ if ($i==79);	# with context fetch
        +	sll	$a,5,$t1
        +	addl	$K,$e,$e
        +	zapnot	$a,0xf,$a
        +	ldl	@X[0],0($ctx)
        +
        +	sll	$b,30,$t3
        +	addl	$t1,$e,$e
        +	xor	$b,$c,$t2
        +	ldl	@X[1],4($ctx)
        +
        +	srl	$b,2,$b
        +	addl	@X[$i%16],$e,$e
        +	xor	$d,$t2,$t2
        +	ldl	@X[2],8($ctx)
        +
        +	srl	$a,27,$t0
        +	addl	$t2,$e,$e
        +	ldl	@X[3],12($ctx)
        +
        +	or	$t3,$b,$b
        +	addl	$t0,$e,$e
        +	ldl	@X[4],16($ctx)
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___;	# with forward Xupdate
        +	sll	$a,5,$t1
        +	addl	$K,$e,$e
        +	zapnot	$a,0xf,$a
        +	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
        +
        +	srl	$a,27,$t0
        +	and	$b,$c,$t2
        +	and	$b,$d,$t3
        +	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
        +
        +	sll	$b,30,$b
        +	addl	$t1,$e,$e
        +	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
        +
        +	srl	@X[$j%16],31,$t1
        +	addl	$t0,$e,$e
        +	or	$t2,$t3,$t2
        +	and	$c,$d,$t3
        +
        +	or	$t2,$t3,$t2
        +	srl	$b,32,$t3
        +	addl	@X[$i%16],$e,$e
        +	addl	@X[$j%16],@X[$j%16],@X[$j%16]
        +
        +	or	$t3,$b,$b
        +	addl	$t2,$e,$e
        +	or	$t1,@X[$j%16],@X[$j%16]
        +	zapnot	@X[$i%16],0xf,@X[$i%16]
        +___
        +}
        +
        +$code=<<___;
        +#ifdef __linux__
        +#include <asm/regdef.h>
        +#else
        +#include <asm.h>
        +#include <regdef.h>
        +#endif
        +
        +.text
        +
        +.set	noat
        +.set	noreorder
        +.globl	sha1_block_data_order
        +.align	5
        +.ent	sha1_block_data_order
        +sha1_block_data_order:
        +	lda	sp,-64(sp)
        +	stq	ra,0(sp)
        +	stq	s0,8(sp)
        +	stq	s1,16(sp)
        +	stq	s2,24(sp)
        +	stq	s3,32(sp)
        +	stq	s4,40(sp)
        +	stq	s5,48(sp)
        +	stq	fp,56(sp)
        +	.mask	0x0400fe00,-64
        +	.frame	sp,64,ra
        +	.prologue 0
        +
        +	ldl	$A,0($ctx)
        +	ldl	$B,4($ctx)
        +	sll	$num,6,$num
        +	ldl	$C,8($ctx)
        +	ldl	$D,12($ctx)
        +	ldl	$E,16($ctx)
        +	addq	$inp,$num,$num
        +
        +.Lloop:
        +	.set	noreorder
        +	ldah	$K,23170(zero)
        +	zapnot	$B,0xf,$B
        +	lda	$K,31129($K)	# K_00_19
        +___
        +for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
        +
        +$code.=<<___;
        +	ldah	$K,28378(zero)
        +	lda	$K,-5215($K)	# K_20_39
        +___
        +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +
        +$code.=<<___;
        +	ldah	$K,-28900(zero)
        +	lda	$K,-17188($K)	# K_40_59
        +___
        +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +
        +$code.=<<___;
        +	ldah	$K,-13725(zero)
        +	lda	$K,-15914($K)	# K_60_79
        +___
        +for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +
        +$code.=<<___;
        +	addl	@X[0],$A,$A
        +	addl	@X[1],$B,$B
        +	addl	@X[2],$C,$C
        +	addl	@X[3],$D,$D
        +	addl	@X[4],$E,$E
        +	stl	$A,0($ctx)
        +	stl	$B,4($ctx)
        +	addq	$inp,64,$inp
        +	stl	$C,8($ctx)
        +	stl	$D,12($ctx)
        +	stl	$E,16($ctx)
        +	cmpult	$inp,$num,$t1
        +	bne	$t1,.Lloop
        +
        +	.set	noreorder
        +	ldq	ra,0(sp)
        +	ldq	s0,8(sp)
        +	ldq	s1,16(sp)
        +	ldq	s2,24(sp)
        +	ldq	s3,32(sp)
        +	ldq	s4,40(sp)
        +	ldq	s5,48(sp)
        +	ldq	fp,56(sp)
        +	lda	sp,64(sp)
        +	ret	(ra)
        +.end	sha1_block_data_order
        +.ascii	"SHA1 block transform for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +___
        +$output=shift and open STDOUT,">$output";
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl
        new file mode 100644
        index 000000000..33da3e0e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-armv4-large.pl
        @@ -0,0 +1,248 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# sha1_block procedure for ARMv4.
        +#
        +# January 2007.
        +
        +# Size/performance trade-off
        +# ====================================================================
        +# impl		size in bytes	comp cycles[*]	measured performance
        +# ====================================================================
        +# thumb		304		3212		4420
        +# armv4-small	392/+29%	1958/+64%	2250/+96%
        +# armv4-compact	740/+89%	1552/+26%	1840/+22%
        +# armv4-large	1420/+92%	1307/+19%	1370/+34%[***]
        +# full unroll	~5100/+260%	~1260/+4%	~1300/+5%
        +# ====================================================================
        +# thumb		= same as 'small' but in Thumb instructions[**] and
        +#		  with recurring code in two private functions;
        +# small		= detached Xload/update, loops are folded;
        +# compact	= detached Xload/update, 5x unroll;
        +# large		= interleaved Xload/update, 5x unroll;
        +# full unroll	= interleaved Xload/update, full unroll, estimated[!];
        +#
        +# [*]	Manually counted instructions in "grand" loop body. Measured
        +#	performance is affected by prologue and epilogue overhead,
        +#	i-cache availability, branch penalties, etc.
        +# [**]	While each Thumb instruction is twice smaller, they are not as
        +#	diverse as ARM ones: e.g., there are only two arithmetic
        +#	instructions with 3 arguments, no [fixed] rotate, addressing
        +#	modes are limited. As result it takes more instructions to do
        +#	the same job in Thumb, therefore the code is never twice as
        +#	small and always slower.
        +# [***]	which is also ~35% better than compiler generated code. Dual-
        +#	issue Cortex A8 core was measured to process input block in
        +#	~990 cycles.
        +
        +# August 2010.
        +#
        +# Rescheduling for dual-issue pipeline resulted in 13% improvement on
        +# Cortex A8 core and in absolute terms ~870 cycles per input block
        +# [or 13.6 cycles per byte].
        +
        +# February 2011.
        +#
        +# Profiler-assisted and platform-specific optimization resulted in 10%
        +# improvement on Cortex A8 core and 12.2 cycles per byte.
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$ctx="r0";
        +$inp="r1";
        +$len="r2";
        +$a="r3";
        +$b="r4";
        +$c="r5";
        +$d="r6";
        +$e="r7";
        +$K="r8";
        +$t0="r9";
        +$t1="r10";
        +$t2="r11";
        +$t3="r12";
        +$Xi="r14";
        +@V=($a,$b,$c,$d,$e);
        +
        +sub Xupdate {
        +my ($a,$b,$c,$d,$e,$opt1,$opt2)=@_;
        +$code.=<<___;
        +	ldr	$t0,[$Xi,#15*4]
        +	ldr	$t1,[$Xi,#13*4]
        +	ldr	$t2,[$Xi,#7*4]
        +	add	$e,$K,$e,ror#2			@ E+=K_xx_xx
        +	ldr	$t3,[$Xi,#2*4]
        +	eor	$t0,$t0,$t1
        +	eor	$t2,$t2,$t3			@ 1 cycle stall
        +	eor	$t1,$c,$d			@ F_xx_xx
        +	mov	$t0,$t0,ror#31
        +	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
        +	eor	$t0,$t0,$t2,ror#31
        +	str	$t0,[$Xi,#-4]!
        +	$opt1					@ F_xx_xx
        +	$opt2					@ F_xx_xx
        +	add	$e,$e,$t0			@ E+=X[i]
        +___
        +}
        +
        +sub BODY_00_15 {
        +my ($a,$b,$c,$d,$e)=@_;
        +$code.=<<___;
        +#if __ARM_ARCH__<7
        +	ldrb	$t1,[$inp,#2]
        +	ldrb	$t0,[$inp,#3]
        +	ldrb	$t2,[$inp,#1]
        +	add	$e,$K,$e,ror#2			@ E+=K_00_19
        +	ldrb	$t3,[$inp],#4
        +	orr	$t0,$t0,$t1,lsl#8
        +	eor	$t1,$c,$d			@ F_xx_xx
        +	orr	$t0,$t0,$t2,lsl#16
        +	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
        +	orr	$t0,$t0,$t3,lsl#24
        +#else
        +	ldr	$t0,[$inp],#4			@ handles unaligned
        +	add	$e,$K,$e,ror#2			@ E+=K_00_19
        +	eor	$t1,$c,$d			@ F_xx_xx
        +	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
        +#ifdef __ARMEL__
        +	rev	$t0,$t0				@ byte swap
        +#endif
        +#endif
        +	and	$t1,$b,$t1,ror#2
        +	add	$e,$e,$t0			@ E+=X[i]
        +	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
        +	str	$t0,[$Xi,#-4]!
        +	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
        +___
        +}
        +
        +sub BODY_16_19 {
        +my ($a,$b,$c,$d,$e)=@_;
        +	&Xupdate(@_,"and $t1,$b,$t1,ror#2");
        +$code.=<<___;
        +	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
        +	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($a,$b,$c,$d,$e)=@_;
        +	&Xupdate(@_,"eor $t1,$b,$t1,ror#2");
        +$code.=<<___;
        +	add	$e,$e,$t1			@ E+=F_20_39(B,C,D)
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($a,$b,$c,$d,$e)=@_;
        +	&Xupdate(@_,"and $t1,$b,$t1,ror#2","and $t2,$c,$d");
        +$code.=<<___;
        +	add	$e,$e,$t1			@ E+=F_40_59(B,C,D)
        +	add	$e,$e,$t2,ror#2
        +___
        +}
        +
        +$code=<<___;
        +#include "arm_arch.h"
        +
        +.text
        +
        +.global	sha1_block_data_order
        +.type	sha1_block_data_order,%function
        +
        +.align	2
        +sha1_block_data_order:
        +	stmdb	sp!,{r4-r12,lr}
        +	add	$len,$inp,$len,lsl#6	@ $len to point at the end of $inp
        +	ldmia	$ctx,{$a,$b,$c,$d,$e}
        +.Lloop:
        +	ldr	$K,.LK_00_19
        +	mov	$Xi,sp
        +	sub	sp,sp,#15*4
        +	mov	$c,$c,ror#30
        +	mov	$d,$d,ror#30
        +	mov	$e,$e,ror#30		@ [6]
        +.L_00_15:
        +___
        +for($i=0;$i<5;$i++) {
        +	&BODY_00_15(@V);	unshift(@V,pop(@V));
        +}
        +$code.=<<___;
        +	teq	$Xi,sp
        +	bne	.L_00_15		@ [((11+4)*5+2)*3]
        +	sub	sp,sp,#25*4
        +___
        +	&BODY_00_15(@V);	unshift(@V,pop(@V));
        +	&BODY_16_19(@V);	unshift(@V,pop(@V));
        +	&BODY_16_19(@V);	unshift(@V,pop(@V));
        +	&BODY_16_19(@V);	unshift(@V,pop(@V));
        +	&BODY_16_19(@V);	unshift(@V,pop(@V));
        +$code.=<<___;
        +
        +	ldr	$K,.LK_20_39		@ [+15+16*4]
        +	cmn	sp,#0			@ [+3], clear carry to denote 20_39
        +.L_20_39_or_60_79:
        +___
        +for($i=0;$i<5;$i++) {
        +	&BODY_20_39(@V);	unshift(@V,pop(@V));
        +}
        +$code.=<<___;
        +	teq	$Xi,sp			@ preserve carry
        +	bne	.L_20_39_or_60_79	@ [+((12+3)*5+2)*4]
        +	bcs	.L_done			@ [+((12+3)*5+2)*4], spare 300 bytes
        +
        +	ldr	$K,.LK_40_59
        +	sub	sp,sp,#20*4		@ [+2]
        +.L_40_59:
        +___
        +for($i=0;$i<5;$i++) {
        +	&BODY_40_59(@V);	unshift(@V,pop(@V));
        +}
        +$code.=<<___;
        +	teq	$Xi,sp
        +	bne	.L_40_59		@ [+((12+5)*5+2)*4]
        +
        +	ldr	$K,.LK_60_79
        +	sub	sp,sp,#20*4
        +	cmp	sp,#0			@ set carry to denote 60_79
        +	b	.L_20_39_or_60_79	@ [+4], spare 300 bytes
        +.L_done:
        +	add	sp,sp,#80*4		@ "deallocate" stack frame
        +	ldmia	$ctx,{$K,$t0,$t1,$t2,$t3}
        +	add	$a,$K,$a
        +	add	$b,$t0,$b
        +	add	$c,$t1,$c,ror#2
        +	add	$d,$t2,$d,ror#2
        +	add	$e,$t3,$e,ror#2
        +	stmia	$ctx,{$a,$b,$c,$d,$e}
        +	teq	$inp,$len
        +	bne	.Lloop			@ [+18], total 1307
        +
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r12,pc}
        +#else
        +	ldmia	sp!,{r4-r12,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.align	2
        +.LK_00_19:	.word	0x5a827999
        +.LK_20_39:	.word	0x6ed9eba1
        +.LK_40_59:	.word	0x8f1bbcdc
        +.LK_60_79:	.word	0xca62c1d6
        +.size	sha1_block_data_order,.-sha1_block_data_order
        +.asciz	"SHA1 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +___
        +
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT; # enforce flush
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-ia64.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-ia64.pl
        new file mode 100644
        index 000000000..02d35d161
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-ia64.pl
        @@ -0,0 +1,305 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# Eternal question is what's wrong with compiler generated code? The
        +# trick is that it's possible to reduce the number of shifts required
        +# to perform rotations by maintaining copy of 32-bit value in upper
        +# bits of 64-bit register. Just follow mux2 and shrp instructions...
        +# Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which
        +# is >50% better than HP C and >2x better than gcc.
        +
        +$code=<<___;
        +.ident  \"sha1-ia64.s, version 1.3\"
        +.ident  \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\"
        +.explicit
        +
        +___
        +
        +
        +if ($^O eq "hpux") {
        +    $ADDP="addp4";
        +    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
        +} else { $ADDP="add"; }
        +
        +#$human=1;
        +if ($human) {	# useful for visual code auditing...
        +	($A,$B,$C,$D,$E)   = ("A","B","C","D","E");
        +	($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4");
        +	($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
        +	    (	"K_00_19","K_20_39","K_40_59","K_60_79"	);
        +	@X= (	"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7",
        +		"X8", "X9","X10","X11","X12","X13","X14","X15"	);
        +}
        +else {
        +	($A,$B,$C,$D,$E)   =    ("loc0","loc1","loc2","loc3","loc4");
        +	($h0,$h1,$h2,$h3,$h4) = ("loc5","loc6","loc7","loc8","loc9");
        +	($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
        +	    (	"r14", "r15", "loc10", "loc11"	);
        +	@X= (	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
        +		"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"	);
        +}
        +
        +sub BODY_00_15 {
        +local	*code=shift;
        +my	($i,$a,$b,$c,$d,$e)=@_;
        +my	$j=$i+1;
        +my	$Xn=@X[$j%16];
        +
        +$code.=<<___ if ($i==0);
        +{ .mmi;	ld1	$X[$i]=[inp],2		    // MSB
        +	ld1	tmp2=[tmp3],2		};;
        +{ .mmi;	ld1	tmp0=[inp],2
        +	ld1	tmp4=[tmp3],2		    // LSB
        +	dep	$X[$i]=$X[$i],tmp2,8,8	};;
        +___
        +if ($i<15) {
        +	$code.=<<___;
        +{ .mmi;	ld1	$Xn=[inp],2		    // forward Xload
        +	nop.m	0x0
        +	dep	tmp1=tmp0,tmp4,8,8	};;
        +{ .mmi;	ld1	tmp2=[tmp3],2		    // forward Xload
        +	and	tmp4=$c,$b
        +	dep	$X[$i]=$X[$i],tmp1,16,16} //;;
        +{ .mmi;	add	$e=$e,$K_00_19		    // e+=K_00_19
        +	andcm	tmp1=$d,$b
        +	dep.z	tmp5=$a,5,27		};; // a<<5
        +{ .mmi;	add	$e=$e,$X[$i]		    // e+=Xload
        +	or	tmp4=tmp4,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
        +	extr.u	tmp1=$a,27,5		};; // a>>27
        +{ .mmi;	ld1	tmp0=[inp],2		    // forward Xload
        +	add	$e=$e,tmp4		    // e+=F_00_19(b,c,d)
        +	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
        +{ .mmi;	ld1	tmp4=[tmp3],2		    // forward Xload
        +	or	tmp5=tmp1,tmp5		    // ROTATE(a,5)
        +	mux2	tmp6=$a,0x44		};; // see b in next iteration
        +{ .mii;	add	$e=$e,tmp5		    // e+=ROTATE(a,5)
        +	dep	$Xn=$Xn,tmp2,8,8	    // forward Xload
        +	mux2	$X[$i]=$X[$i],0x44	} //;;
        +
        +___
        +	}
        +else	{
        +	$code.=<<___;
        +{ .mii;	and	tmp3=$c,$b
        +	dep	tmp1=tmp0,tmp4,8,8;;
        +	dep	$X[$i]=$X[$i],tmp1,16,16} //;;
        +{ .mmi;	add	$e=$e,$K_00_19		    // e+=K_00_19
        +	andcm	tmp1=$d,$b
        +	dep.z	tmp5=$a,5,27		};; // a<<5
        +{ .mmi;	add	$e=$e,$X[$i]		    // e+=Xupdate
        +	or	tmp4=tmp3,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
        +	extr.u	tmp1=$a,27,5		}   // a>>27
        +{ .mmi;	xor	$Xn=$Xn,$X[($j+2)%16]	    // forward Xupdate
        +	xor	tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate
        +	nop.i	0			};;
        +{ .mmi;	add	$e=$e,tmp4		    // e+=F_00_19(b,c,d)
        +	xor	$Xn=$Xn,tmp3		    // forward Xupdate
        +	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
        +{ .mmi; or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
        +	mux2	tmp6=$a,0x44		};; // see b in next iteration
        +{ .mii;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
        +	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
        +	mux2	$X[$i]=$X[$i],0x44	};;
        +
        +___
        +	}
        +}
        +
        +sub BODY_16_19 {
        +local	*code=shift;
        +my	($i,$a,$b,$c,$d,$e)=@_;
        +my	$j=$i+1;
        +my	$Xn=@X[$j%16];
        +
        +$code.=<<___;
        +{ .mib;	add	$e=$e,$K_00_19		    // e+=K_00_19
        +	dep.z	tmp5=$a,5,27		}   // a<<5
        +{ .mib;	andcm	tmp1=$d,$b
        +	and	tmp0=$c,$b		};;
        +{ .mmi;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
        +	or	tmp0=tmp0,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
        +	extr.u	tmp1=$a,27,5		}   // a>>27
        +{ .mmi;	xor	$Xn=$Xn,$X[($j+2)%16]	    // forward Xupdate
        +	xor	tmp3=$X[($j+8)%16],$X[($j+13)%16]	// forward Xupdate
        +	nop.i	0			};;
        +{ .mmi;	add	$e=$e,tmp0		    // f+=F_00_19(b,c,d)
        +	xor	$Xn=$Xn,tmp3		    // forward Xupdate
        +	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
        +{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
        +	mux2	tmp6=$a,0x44		};; // see b in next iteration
        +{ .mii;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
        +	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
        +	nop.i	0			};;
        +
        +___
        +}
        +
        +sub BODY_20_39 {
        +local	*code=shift;
        +my	($i,$a,$b,$c,$d,$e,$Konst)=@_;
        +	$Konst = $K_20_39 if (!defined($Konst));
        +my	$j=$i+1;
        +my	$Xn=@X[$j%16];
        +
        +if ($i<79) {
        +$code.=<<___;
        +{ .mib;	add	$e=$e,$Konst		    // e+=K_XX_XX
        +	dep.z	tmp5=$a,5,27		}   // a<<5
        +{ .mib;	xor	tmp0=$c,$b
        +	xor	$Xn=$Xn,$X[($j+2)%16]	};; // forward Xupdate
        +{ .mib;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
        +	extr.u	tmp1=$a,27,5		}   // a>>27
        +{ .mib;	xor	tmp0=tmp0,$d		    // F_20_39(b,c,d)=b^c^d
        +	xor	$Xn=$Xn,$X[($j+8)%16]	};; // forward Xupdate
        +{ .mmi;	add	$e=$e,tmp0		    // e+=F_20_39(b,c,d)
        +	xor	$Xn=$Xn,$X[($j+13)%16]	    // forward Xupdate
        +	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
        +{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
        +	mux2	tmp6=$a,0x44		};; // see b in next iteration
        +{ .mii;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
        +	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
        +	nop.i	0			};;
        +
        +___
        +}
        +else {
        +$code.=<<___;
        +{ .mib;	add	$e=$e,$Konst		    // e+=K_60_79
        +	dep.z	tmp5=$a,5,27		}   // a<<5
        +{ .mib;	xor	tmp0=$c,$b
        +	add	$h1=$h1,$a		};; // wrap up
        +{ .mib;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
        +	extr.u	tmp1=$a,27,5		}   // a>>27
        +{ .mib;	xor	tmp0=tmp0,$d		    // F_20_39(b,c,d)=b^c^d
        +	add	$h3=$h3,$c		};; // wrap up
        +{ .mmi;	add	$e=$e,tmp0		    // e+=F_20_39(b,c,d)
        +	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
        +	shrp	$b=tmp6,tmp6,2		};; // b=ROTATE(b,30) ;;?
        +{ .mmi;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
        +	add	tmp3=1,inp		    // used in unaligned codepath
        +	add	$h4=$h4,$d		};; // wrap up
        +
        +___
        +}
        +}
        +
        +sub BODY_40_59 {
        +local	*code=shift;
        +my	($i,$a,$b,$c,$d,$e)=@_;
        +my	$j=$i+1;
        +my	$Xn=@X[$j%16];
        +
        +$code.=<<___;
        +{ .mib;	add	$e=$e,$K_40_59		    // e+=K_40_59
        +	dep.z	tmp5=$a,5,27		}   // a<<5
        +{ .mib;	and	tmp1=$c,$d
        +	xor	tmp0=$c,$d		};;
        +{ .mmi;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
        +	add	tmp5=tmp5,tmp1		    // a<<5+(c&d)
        +	extr.u	tmp1=$a,27,5		}   // a>>27
        +{ .mmi;	and	tmp0=tmp0,$b
        +	xor	$Xn=$Xn,$X[($j+2)%16]	    // forward Xupdate
        +	xor	tmp3=$X[($j+8)%16],$X[($j+13)%16] };;	// forward Xupdate
        +{ .mmi;	add	$e=$e,tmp0		    // e+=b&(c^d)
        +	add	tmp5=tmp5,tmp1		    // ROTATE(a,5)+(c&d)
        +	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
        +{ .mmi;	xor	$Xn=$Xn,tmp3
        +	mux2	tmp6=$a,0x44		};; // see b in next iteration
        +{ .mii;	add	$e=$e,tmp5		    // e+=ROTATE(a,5)+(c&d)
        +	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
        +	nop.i	0x0			};;
        +
        +___
        +}
        +sub BODY_60_79	{ &BODY_20_39(@_,$K_60_79); }
        +
        +$code.=<<___;
        +.text
        +
        +tmp0=r8;
        +tmp1=r9;
        +tmp2=r10;
        +tmp3=r11;
        +ctx=r32;	// in0
        +inp=r33;	// in1
        +
        +// void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num);
        +.global	sha1_block_data_order#
        +.proc	sha1_block_data_order#
        +.align	32
        +sha1_block_data_order:
        +	.prologue
        +{ .mmi;	alloc	tmp1=ar.pfs,3,14,0,0
        +	$ADDP	tmp0=4,ctx
        +	.save	ar.lc,r3
        +	mov	r3=ar.lc		}
        +{ .mmi;	$ADDP	ctx=0,ctx
        +	$ADDP	inp=0,inp
        +	mov	r2=pr			};;
        +tmp4=in2;
        +tmp5=loc12;
        +tmp6=loc13;
        +	.body
        +{ .mlx;	ld4	$h0=[ctx],8
        +	movl	$K_00_19=0x5a827999	}
        +{ .mlx;	ld4	$h1=[tmp0],8
        +	movl	$K_20_39=0x6ed9eba1	};;
        +{ .mlx;	ld4	$h2=[ctx],8
        +	movl	$K_40_59=0x8f1bbcdc	}
        +{ .mlx;	ld4	$h3=[tmp0]
        +	movl	$K_60_79=0xca62c1d6	};;
        +{ .mmi;	ld4	$h4=[ctx],-16
        +	add	in2=-1,in2		    // adjust num for ar.lc
        +	mov	ar.ec=1			};;
        +{ .mmi;	nop.m	0
        +	add	tmp3=1,inp
        +	mov	ar.lc=in2		};; // brp.loop.imp: too far
        +
        +.Ldtop:
        +{ .mmi;	mov	$A=$h0
        +	mov	$B=$h1
        +	mux2	tmp6=$h1,0x44		}
        +{ .mmi;	mov	$C=$h2
        +	mov	$D=$h3
        +	mov	$E=$h4			};;
        +
        +___
        +
        +{ my $i;
        +  my @V=($A,$B,$C,$D,$E);
        +
        +	for($i=0;$i<16;$i++)	{ &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<20;$i++)	{ &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<40;$i++)	{ &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<60;$i++)	{ &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); }
        +	for(;$i<80;$i++)	{ &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); }
        +
        +	(($V[0] eq $A) and ($V[4] eq $E)) or die;	# double-check
        +}
        +
        +$code.=<<___;
        +{ .mmb;	add	$h0=$h0,$A
        +	add	$h2=$h2,$C
        +	br.ctop.dptk.many	.Ldtop	};;
        +.Ldend:
        +{ .mmi;	add	tmp0=4,ctx
        +	mov	ar.lc=r3		};;
        +{ .mmi;	st4	[ctx]=$h0,8
        +	st4	[tmp0]=$h1,8		};;
        +{ .mmi;	st4	[ctx]=$h2,8
        +	st4	[tmp0]=$h3		};;
        +{ .mib;	st4	[ctx]=$h4,-16
        +	mov	pr=r2,0x1ffff
        +	br.ret.sptk.many	b0	};;
        +.endp	sha1_block_data_order#
        +stringz	"SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$output=shift and open STDOUT,">$output";
        +print $code;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-mips.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-mips.pl
        new file mode 100644
        index 000000000..f1a702f38
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-mips.pl
        @@ -0,0 +1,354 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA1 block procedure for MIPS.
        +
        +# Performance improvement is 30% on unaligned input. The "secret" is
        +# to deploy lwl/lwr pair to load unaligned input. One could have
        +# vectorized Xupdate on MIPSIII/IV, but the goal was to code MIPS32-
        +# compatible subroutine. There is room for minor optimization on
        +# little-endian platforms...
        +
        +######################################################################
        +# There is a number of MIPS ABI in use, O32 and N32/64 are most
        +# widely used. Then there is a new contender: NUBI. It appears that if
        +# one picks the latter, it's possible to arrange code in ABI neutral
        +# manner. Therefore let's stick to NUBI register layout:
        +#
        +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
        +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
        +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
        +#
        +# The return value is placed in $a0. Following coding rules facilitate
        +# interoperability:
        +#
        +# - never ever touch $tp, "thread pointer", former $gp;
        +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
        +#   old code];
        +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
        +#
        +# For reference here is register layout for N32/64 MIPS ABIs:
        +#
        +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
        +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
        +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
        +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
        +#
        +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
        +
        +if ($flavour =~ /64|n32/i) {
        +	$PTR_ADD="dadd";	# incidentally works even on n32
        +	$PTR_SUB="dsub";	# incidentally works even on n32
        +	$REG_S="sd";
        +	$REG_L="ld";
        +	$PTR_SLL="dsll";	# incidentally works even on n32
        +	$SZREG=8;
        +} else {
        +	$PTR_ADD="add";
        +	$PTR_SUB="sub";
        +	$REG_S="sw";
        +	$REG_L="lw";
        +	$PTR_SLL="sll";
        +	$SZREG=4;
        +}
        +#
        +# <appro@openssl.org>
        +#
        +######################################################################
        +
        +$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
        +
        +for (@ARGV) {	$output=$_ if (/^\w[\w\-]*\.\w+$/);   }
        +open STDOUT,">$output";
        +
        +if (!defined($big_endian))
        +            {   $big_endian=(unpack('L',pack('N',1))==1);   }
        +
        +# offsets of the Most and Least Significant Bytes
        +$MSB=$big_endian?0:3;
        +$LSB=3&~$MSB;
        +
        +@X=map("\$$_",(8..23));	# a4-a7,s0-s11
        +
        +$ctx=$a0;
        +$inp=$a1;
        +$num=$a2;
        +$A="\$1";
        +$B="\$2";
        +$C="\$3";
        +$D="\$7";
        +$E="\$24";	@V=($A,$B,$C,$D,$E);
        +$t0="\$25";
        +$t1=$num;	# $num is offloaded to stack
        +$t2="\$30";	# fp
        +$K="\$31";	# ra
        +
        +sub BODY_00_14 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___	if (!$big_endian);
        +	srl	$t0,@X[$i],24	# byte swap($i)
        +	srl	$t1,@X[$i],8
        +	andi	$t2,@X[$i],0xFF00
        +	sll	@X[$i],@X[$i],24
        +	andi	$t1,0xFF00
        +	sll	$t2,$t2,8
        +	or	@X[$i],$t0
        +	or	$t1,$t2
        +	or	@X[$i],$t1
        +___
        +$code.=<<___;
        +	 lwl	@X[$j],$j*4+$MSB($inp)
        +	sll	$t0,$a,5	# $i
        +	addu	$e,$K
        +	 lwr	@X[$j],$j*4+$LSB($inp)
        +	srl	$t1,$a,27
        +	addu	$e,$t0
        +	xor	$t0,$c,$d
        +	addu	$e,$t1
        +	sll	$t2,$b,30
        +	and	$t0,$b
        +	srl	$b,$b,2
        +	xor	$t0,$d
        +	addu	$e,@X[$i]
        +	or	$b,$t2
        +	addu	$e,$t0
        +___
        +}
        +
        +sub BODY_15_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +
        +$code.=<<___	if (!$big_endian && $i==15);
        +	srl	$t0,@X[$i],24	# byte swap($i)
        +	srl	$t1,@X[$i],8
        +	andi	$t2,@X[$i],0xFF00
        +	sll	@X[$i],@X[$i],24
        +	andi	$t1,0xFF00
        +	sll	$t2,$t2,8
        +	or	@X[$i],$t0
        +	or	@X[$i],$t1
        +	or	@X[$i],$t2
        +___
        +$code.=<<___;
        +	 xor	@X[$j%16],@X[($j+2)%16]
        +	sll	$t0,$a,5	# $i
        +	addu	$e,$K
        +	srl	$t1,$a,27
        +	addu	$e,$t0
        +	 xor	@X[$j%16],@X[($j+8)%16]
        +	xor	$t0,$c,$d
        +	addu	$e,$t1
        +	 xor	@X[$j%16],@X[($j+13)%16]
        +	sll	$t2,$b,30
        +	and	$t0,$b
        +	 srl	$t1,@X[$j%16],31
        +	 addu	@X[$j%16],@X[$j%16]
        +	srl	$b,$b,2
        +	xor	$t0,$d
        +	 or	@X[$j%16],$t1
        +	addu	$e,@X[$i%16]
        +	or	$b,$t2
        +	addu	$e,$t0
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i<79);
        +	 xor	@X[$j%16],@X[($j+2)%16]
        +	sll	$t0,$a,5	# $i
        +	addu	$e,$K
        +	srl	$t1,$a,27
        +	addu	$e,$t0
        +	 xor	@X[$j%16],@X[($j+8)%16]
        +	xor	$t0,$c,$d
        +	addu	$e,$t1
        +	 xor	@X[$j%16],@X[($j+13)%16]
        +	sll	$t2,$b,30
        +	xor	$t0,$b
        +	 srl	$t1,@X[$j%16],31
        +	 addu	@X[$j%16],@X[$j%16]
        +	srl	$b,$b,2
        +	addu	$e,@X[$i%16]
        +	 or	@X[$j%16],$t1
        +	or	$b,$t2
        +	addu	$e,$t0
        +___
        +$code.=<<___ if ($i==79);
        +	 lw	@X[0],0($ctx)
        +	sll	$t0,$a,5	# $i
        +	addu	$e,$K
        +	 lw	@X[1],4($ctx)
        +	srl	$t1,$a,27
        +	addu	$e,$t0
        +	 lw	@X[2],8($ctx)
        +	xor	$t0,$c,$d
        +	addu	$e,$t1
        +	 lw	@X[3],12($ctx)
        +	sll	$t2,$b,30
        +	xor	$t0,$b
        +	 lw	@X[4],16($ctx)
        +	srl	$b,$b,2
        +	addu	$e,@X[$i%16]
        +	or	$b,$t2
        +	addu	$e,$t0
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i<79);
        +	 xor	@X[$j%16],@X[($j+2)%16]
        +	sll	$t0,$a,5	# $i
        +	addu	$e,$K
        +	srl	$t1,$a,27
        +	addu	$e,$t0
        +	 xor	@X[$j%16],@X[($j+8)%16]
        +	and	$t0,$c,$d
        +	addu	$e,$t1
        +	 xor	@X[$j%16],@X[($j+13)%16]
        +	sll	$t2,$b,30
        +	addu	$e,$t0
        +	 srl	$t1,@X[$j%16],31
        +	xor	$t0,$c,$d
        +	 addu	@X[$j%16],@X[$j%16]
        +	and	$t0,$b
        +	srl	$b,$b,2
        +	 or	@X[$j%16],$t1
        +	addu	$e,@X[$i%16]
        +	or	$b,$t2
        +	addu	$e,$t0
        +___
        +}
        +
        +$FRAMESIZE=16;	# large enough to accomodate NUBI saved registers
        +$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
        +
        +$code=<<___;
        +#ifdef OPENSSL_FIPSCANISTER
        +# include <openssl/fipssyms.h>
        +#endif
        +
        +.text
        +
        +.set	noat
        +.set	noreorder
        +.align	5
        +.globl	sha1_block_data_order
        +.ent	sha1_block_data_order
        +sha1_block_data_order:
        +	.frame	$sp,$FRAMESIZE*$SZREG,$ra
        +	.mask	$SAVED_REGS_MASK,-$SZREG
        +	.set	noreorder
        +	$PTR_SUB $sp,$FRAMESIZE*$SZREG
        +	$REG_S	$ra,($FRAMESIZE-1)*$SZREG($sp)
        +	$REG_S	$fp,($FRAMESIZE-2)*$SZREG($sp)
        +	$REG_S	$s11,($FRAMESIZE-3)*$SZREG($sp)
        +	$REG_S	$s10,($FRAMESIZE-4)*$SZREG($sp)
        +	$REG_S	$s9,($FRAMESIZE-5)*$SZREG($sp)
        +	$REG_S	$s8,($FRAMESIZE-6)*$SZREG($sp)
        +	$REG_S	$s7,($FRAMESIZE-7)*$SZREG($sp)
        +	$REG_S	$s6,($FRAMESIZE-8)*$SZREG($sp)
        +	$REG_S	$s5,($FRAMESIZE-9)*$SZREG($sp)
        +	$REG_S	$s4,($FRAMESIZE-10)*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
        +	$REG_S	$s3,($FRAMESIZE-11)*$SZREG($sp)
        +	$REG_S	$s2,($FRAMESIZE-12)*$SZREG($sp)
        +	$REG_S	$s1,($FRAMESIZE-13)*$SZREG($sp)
        +	$REG_S	$s0,($FRAMESIZE-14)*$SZREG($sp)
        +	$REG_S	$gp,($FRAMESIZE-15)*$SZREG($sp)
        +___
        +$code.=<<___;
        +	$PTR_SLL $num,6
        +	$PTR_ADD $num,$inp
        +	$REG_S	$num,0($sp)
        +	lw	$A,0($ctx)
        +	lw	$B,4($ctx)
        +	lw	$C,8($ctx)
        +	lw	$D,12($ctx)
        +	b	.Loop
        +	lw	$E,16($ctx)
        +.align	4
        +.Loop:
        +	.set	reorder
        +	lwl	@X[0],$MSB($inp)
        +	lui	$K,0x5a82
        +	lwr	@X[0],$LSB($inp)
        +	ori	$K,0x7999	# K_00_19
        +___
        +for ($i=0;$i<15;$i++)	{ &BODY_00_14($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<20;$i++)	{ &BODY_15_19($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	lui	$K,0x6ed9
        +	ori	$K,0xeba1	# K_20_39
        +___
        +for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	lui	$K,0x8f1b
        +	ori	$K,0xbcdc	# K_40_59
        +___
        +for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	lui	$K,0xca62
        +	ori	$K,0xc1d6	# K_60_79
        +___
        +for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	$PTR_ADD $inp,64
        +	$REG_L	$num,0($sp)
        +
        +	addu	$A,$X[0]
        +	addu	$B,$X[1]
        +	sw	$A,0($ctx)
        +	addu	$C,$X[2]
        +	addu	$D,$X[3]
        +	sw	$B,4($ctx)
        +	addu	$E,$X[4]
        +	sw	$C,8($ctx)
        +	sw	$D,12($ctx)
        +	sw	$E,16($ctx)
        +	.set	noreorder
        +	bne	$inp,$num,.Loop
        +	nop
        +
        +	.set	noreorder
        +	$REG_L	$ra,($FRAMESIZE-1)*$SZREG($sp)
        +	$REG_L	$fp,($FRAMESIZE-2)*$SZREG($sp)
        +	$REG_L	$s11,($FRAMESIZE-3)*$SZREG($sp)
        +	$REG_L	$s10,($FRAMESIZE-4)*$SZREG($sp)
        +	$REG_L	$s9,($FRAMESIZE-5)*$SZREG($sp)
        +	$REG_L	$s8,($FRAMESIZE-6)*$SZREG($sp)
        +	$REG_L	$s7,($FRAMESIZE-7)*$SZREG($sp)
        +	$REG_L	$s6,($FRAMESIZE-8)*$SZREG($sp)
        +	$REG_L	$s5,($FRAMESIZE-9)*$SZREG($sp)
        +	$REG_L	$s4,($FRAMESIZE-10)*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$s3,($FRAMESIZE-11)*$SZREG($sp)
        +	$REG_L	$s2,($FRAMESIZE-12)*$SZREG($sp)
        +	$REG_L	$s1,($FRAMESIZE-13)*$SZREG($sp)
        +	$REG_L	$s0,($FRAMESIZE-14)*$SZREG($sp)
        +	$REG_L	$gp,($FRAMESIZE-15)*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE*$SZREG
        +.end	sha1_block_data_order
        +.rdata
        +.asciiz	"SHA1 for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-parisc.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-parisc.pl
        new file mode 100644
        index 000000000..6d7bf495b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-parisc.pl
        @@ -0,0 +1,259 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA1 block procedure for PA-RISC.
        +
        +# June 2009.
        +#
        +# On PA-7100LC performance is >30% better than gcc 3.2 generated code
        +# for aligned input and >50% better for unaligned. Compared to vendor
        +# compiler on PA-8600 it's almost 60% faster in 64-bit build and just
        +# few percent faster in 32-bit one (this for aligned input, data for
        +# unaligned input is not available).
        +#
        +# Special thanks to polarhome.com for providing HP-UX account.
        +
        +$flavour = shift;
        +$output = shift;
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$FRAME_MARKER	=80;
        +	$SAVED_RP	=16;
        +	$PUSH		="std";
        +	$PUSHMA		="std,ma";
        +	$POP		="ldd";
        +	$POPMB		="ldd,mb";
        +} else {
        +	$LEVEL		="1.0";
        +	$SIZE_T		=4;
        +	$FRAME_MARKER	=48;
        +	$SAVED_RP	=20;
        +	$PUSH		="stw";
        +	$PUSHMA		="stwm";
        +	$POP		="ldw";
        +	$POPMB		="ldwm";
        +}
        +
        +$FRAME=14*$SIZE_T+$FRAME_MARKER;# 14 saved regs + frame marker
        +				#                 [+ argument transfer]
        +$ctx="%r26";		# arg0
        +$inp="%r25";		# arg1
        +$num="%r24";		# arg2
        +
        +$t0="%r28";
        +$t1="%r29";
        +$K="%r31";
        +
        +@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
        +    "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$t0);
        +
        +@V=($A,$B,$C,$D,$E)=("%r19","%r20","%r21","%r22","%r23");
        +
        +sub BODY_00_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i<15);
        +	addl	$K,$e,$e	; $i
        +	shd	$a,$a,27,$t1
        +	addl	@X[$i],$e,$e
        +	and	$c,$b,$t0
        +	addl	$t1,$e,$e
        +	andcm	$d,$b,$t1
        +	shd	$b,$b,2,$b
        +	or	$t1,$t0,$t0
        +	addl	$t0,$e,$e
        +___
        +$code.=<<___ if ($i>=15);	# with forward Xupdate
        +	addl	$K,$e,$e	; $i
        +	shd	$a,$a,27,$t1
        +	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
        +	addl	@X[$i%16],$e,$e
        +	and	$c,$b,$t0
        +	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
        +	addl	$t1,$e,$e
        +	andcm	$d,$b,$t1
        +	shd	$b,$b,2,$b
        +	or	$t1,$t0,$t0
        +	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
        +	add	$t0,$e,$e
        +	shd	@X[$j%16],@X[$j%16],31,@X[$j%16]
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i<79);
        +	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]	; $i
        +	addl	$K,$e,$e
        +	shd	$a,$a,27,$t1
        +	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
        +	addl	@X[$i%16],$e,$e
        +	xor	$b,$c,$t0
        +	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
        +	addl	$t1,$e,$e
        +	shd	$b,$b,2,$b
        +	xor	$d,$t0,$t0
        +	shd	@X[$j%16],@X[$j%16],31,@X[$j%16]
        +	addl	$t0,$e,$e
        +___
        +$code.=<<___ if ($i==79);	# with context load
        +	ldw	0($ctx),@X[0]	; $i
        +	addl	$K,$e,$e
        +	shd	$a,$a,27,$t1
        +	ldw	4($ctx),@X[1]
        +	addl	@X[$i%16],$e,$e
        +	xor	$b,$c,$t0
        +	ldw	8($ctx),@X[2]
        +	addl	$t1,$e,$e
        +	shd	$b,$b,2,$b
        +	xor	$d,$t0,$t0
        +	ldw	12($ctx),@X[3]
        +	addl	$t0,$e,$e
        +	ldw	16($ctx),@X[4]
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___;
        +	shd	$a,$a,27,$t1	; $i
        +	addl	$K,$e,$e
        +	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
        +	xor	$d,$c,$t0
        +	addl	@X[$i%16],$e,$e
        +	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
        +	and	$b,$t0,$t0
        +	addl	$t1,$e,$e
        +	shd	$b,$b,2,$b
        +	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
        +	addl	$t0,$e,$e
        +	and	$d,$c,$t1
        +	shd	@X[$j%16],@X[$j%16],31,@X[$j%16]
        +	addl	$t1,$e,$e
        +___
        +}
        +
        +$code=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.EXPORT	sha1_block_data_order,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
        +sha1_block_data_order
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-14*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=16
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
        +	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
        +	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
        +	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
        +	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
        +	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
        +
        +	ldw	0($ctx),$A
        +	ldw	4($ctx),$B
        +	ldw	8($ctx),$C
        +	ldw	12($ctx),$D
        +	ldw	16($ctx),$E
        +
        +	extru	$inp,31,2,$t0		; t0=inp&3;
        +	sh3addl	$t0,%r0,$t0		; t0*=8;
        +	subi	32,$t0,$t0		; t0=32-t0;
        +	mtctl	$t0,%cr11		; %sar=t0;
        +
        +L\$oop
        +	ldi	3,$t0
        +	andcm	$inp,$t0,$t0		; 64-bit neutral
        +___
        +	for ($i=0;$i<15;$i++) {		# load input block
        +	$code.="\tldw	`4*$i`($t0),@X[$i]\n";		}
        +$code.=<<___;
        +	cmpb,*=	$inp,$t0,L\$aligned
        +	ldw	60($t0),@X[15]
        +	ldw	64($t0),@X[16]
        +___
        +	for ($i=0;$i<16;$i++) {		# align input
        +	$code.="\tvshd	@X[$i],@X[$i+1],@X[$i]\n";	}
        +$code.=<<___;
        +L\$aligned
        +	ldil	L'0x5a827000,$K		; K_00_19
        +	ldo	0x999($K),$K
        +___
        +for ($i=0;$i<20;$i++)   { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	ldil	L'0x6ed9e000,$K		; K_20_39
        +	ldo	0xba1($K),$K
        +___
        +
        +for (;$i<40;$i++)       { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	ldil	L'0x8f1bb000,$K		; K_40_59
        +	ldo	0xcdc($K),$K
        +___
        +
        +for (;$i<60;$i++)       { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	ldil	L'0xca62c000,$K		; K_60_79
        +	ldo	0x1d6($K),$K
        +___
        +for (;$i<80;$i++)       { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +
        +$code.=<<___;
        +	addl	@X[0],$A,$A
        +	addl	@X[1],$B,$B
        +	addl	@X[2],$C,$C
        +	addl	@X[3],$D,$D
        +	addl	@X[4],$E,$E
        +	stw	$A,0($ctx)
        +	stw	$B,4($ctx)
        +	stw	$C,8($ctx)
        +	stw	$D,12($ctx)
        +	stw	$E,16($ctx)
        +	addib,*<> -1,$num,L\$oop
        +	ldo	64($inp),$inp
        +
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
        +	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
        +	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
        +	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
        +	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
        +	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +	.STRINGZ "SHA1 block transform for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/,\*/,/gm if ($SIZE_T==4);
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-ppc.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-ppc.pl
        new file mode 100644
        index 000000000..2140dd2f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-ppc.pl
        @@ -0,0 +1,326 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# I let hardware handle unaligned input(*), except on page boundaries
        +# (see below for details). Otherwise straightforward implementation
        +# with X vector in register bank. The module is big-endian [which is
        +# not big deal as there're no little-endian targets left around].
        +#
        +# (*) this means that this module is inappropriate for PPC403? Does
        +#     anybody know if pre-POWER3 can sustain unaligned load?
        +
        +# 			-m64	-m32
        +# ----------------------------------
        +# PPC970,gcc-4.0.0	+76%	+59%
        +# Power6,xlc-7		+68%	+33%
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /64/) {
        +	$SIZE_T	=8;
        +	$LRSAVE	=2*$SIZE_T;
        +	$UCMP	="cmpld";
        +	$STU	="stdu";
        +	$POP	="ld";
        +	$PUSH	="std";
        +} elsif ($flavour =~ /32/) {
        +	$SIZE_T	=4;
        +	$LRSAVE	=$SIZE_T;
        +	$UCMP	="cmplw";
        +	$STU	="stwu";
        +	$POP	="lwz";
        +	$PUSH	="stw";
        +} else { die "nonsense $flavour"; }
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
        +
        +$FRAME=24*$SIZE_T+64;
        +$LOCALS=6*$SIZE_T;
        +
        +$K  ="r0";
        +$sp ="r1";
        +$toc="r2";
        +$ctx="r3";
        +$inp="r4";
        +$num="r5";
        +$t0 ="r15";
        +$t1 ="r6";
        +
        +$A  ="r7";
        +$B  ="r8";
        +$C  ="r9";
        +$D  ="r10";
        +$E  ="r11";
        +$T  ="r12";
        +
        +@V=($A,$B,$C,$D,$E,$T);
        +@X=("r16","r17","r18","r19","r20","r21","r22","r23",
        +    "r24","r25","r26","r27","r28","r29","r30","r31");
        +
        +sub BODY_00_19 {
        +my ($i,$a,$b,$c,$d,$e,$f)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i==0);
        +	lwz	@X[$i],`$i*4`($inp)
        +___
        +$code.=<<___ if ($i<15);
        +	lwz	@X[$j],`$j*4`($inp)
        +	add	$f,$K,$e
        +	rotlwi	$e,$a,5
        +	add	$f,$f,@X[$i]
        +	and	$t0,$c,$b
        +	add	$f,$f,$e
        +	andc	$t1,$d,$b
        +	rotlwi	$b,$b,30
        +	or	$t0,$t0,$t1
        +	add	$f,$f,$t0
        +___
        +$code.=<<___ if ($i>=15);
        +	add	$f,$K,$e
        +	rotlwi	$e,$a,5
        +	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
        +	add	$f,$f,@X[$i%16]
        +	and	$t0,$c,$b
        +	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
        +	add	$f,$f,$e
        +	andc	$t1,$d,$b
        +	rotlwi	$b,$b,30
        +	or	$t0,$t0,$t1
        +	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
        +	add	$f,$f,$t0
        +	rotlwi	@X[$j%16],@X[$j%16],1
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e,$f)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i<79);
        +	add	$f,$K,$e
        +	rotlwi	$e,$a,5
        +	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
        +	add	$f,$f,@X[$i%16]
        +	xor	$t0,$b,$c
        +	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
        +	add	$f,$f,$e
        +	rotlwi	$b,$b,30
        +	xor	$t0,$t0,$d
        +	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
        +	add	$f,$f,$t0
        +	rotlwi	@X[$j%16],@X[$j%16],1
        +___
        +$code.=<<___ if ($i==79);
        +	add	$f,$K,$e
        +	rotlwi	$e,$a,5
        +	lwz	r16,0($ctx)
        +	add	$f,$f,@X[$i%16]
        +	xor	$t0,$b,$c
        +	lwz	r17,4($ctx)
        +	add	$f,$f,$e
        +	rotlwi	$b,$b,30
        +	lwz	r18,8($ctx)
        +	xor	$t0,$t0,$d
        +	lwz	r19,12($ctx)
        +	add	$f,$f,$t0
        +	lwz	r20,16($ctx)
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e,$f)=@_;
        +my $j=$i+1;
        +$code.=<<___;
        +	add	$f,$K,$e
        +	rotlwi	$e,$a,5
        +	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
        +	add	$f,$f,@X[$i%16]
        +	and	$t0,$b,$c
        +	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
        +	add	$f,$f,$e
        +	or	$t1,$b,$c
        +	rotlwi	$b,$b,30
        +	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
        +	and	$t1,$t1,$d
        +	or	$t0,$t0,$t1
        +	rotlwi	@X[$j%16],@X[$j%16],1
        +	add	$f,$f,$t0
        +___
        +}
        +
        +$code=<<___;
        +.machine	"any"
        +.text
        +
        +.globl	.sha1_block_data_order
        +.align	4
        +.sha1_block_data_order:
        +	$STU	$sp,-$FRAME($sp)
        +	mflr	r0
        +	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
        +	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
        +	lwz	$A,0($ctx)
        +	lwz	$B,4($ctx)
        +	lwz	$C,8($ctx)
        +	lwz	$D,12($ctx)
        +	lwz	$E,16($ctx)
        +	andi.	r0,$inp,3
        +	bne	Lunaligned
        +Laligned:
        +	mtctr	$num
        +	bl	Lsha1_block_private
        +	b	Ldone
        +
        +; PowerPC specification allows an implementation to be ill-behaved
        +; upon unaligned access which crosses page boundary. "Better safe
        +; than sorry" principle makes me treat it specially. But I don't
        +; look for particular offending word, but rather for 64-byte input
        +; block which crosses the boundary. Once found that block is aligned
        +; and hashed separately...
        +.align	4
        +Lunaligned:
        +	subfic	$t1,$inp,4096
        +	andi.	$t1,$t1,4095	; distance to closest page boundary
        +	srwi.	$t1,$t1,6	; t1/=64
        +	beq	Lcross_page
        +	$UCMP	$num,$t1
        +	ble-	Laligned	; didn't cross the page boundary
        +	mtctr	$t1
        +	subfc	$num,$t1,$num
        +	bl	Lsha1_block_private
        +Lcross_page:
        +	li	$t1,16
        +	mtctr	$t1
        +	addi	r20,$sp,$LOCALS	; spot within the frame
        +Lmemcpy:
        +	lbz	r16,0($inp)
        +	lbz	r17,1($inp)
        +	lbz	r18,2($inp)
        +	lbz	r19,3($inp)
        +	addi	$inp,$inp,4
        +	stb	r16,0(r20)
        +	stb	r17,1(r20)
        +	stb	r18,2(r20)
        +	stb	r19,3(r20)
        +	addi	r20,r20,4
        +	bdnz	Lmemcpy
        +
        +	$PUSH	$inp,`$FRAME-$SIZE_T*18`($sp)
        +	li	$t1,1
        +	addi	$inp,$sp,$LOCALS
        +	mtctr	$t1
        +	bl	Lsha1_block_private
        +	$POP	$inp,`$FRAME-$SIZE_T*18`($sp)
        +	addic.	$num,$num,-1
        +	bne-	Lunaligned
        +
        +Ldone:
        +	$POP	r0,`$FRAME+$LRSAVE`($sp)
        +	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
        +	mtlr	r0
        +	addi	$sp,$sp,$FRAME
        +	blr
        +	.long	0
        +	.byte	0,12,4,1,0x80,18,3,0
        +	.long	0
        +___
        +
        +# This is private block function, which uses tailored calling
        +# interface, namely upon entry SHA_CTX is pre-loaded to given
        +# registers and counter register contains amount of chunks to
        +# digest...
        +$code.=<<___;
        +.align	4
        +Lsha1_block_private:
        +___
        +$code.=<<___;	# load K_00_19
        +	lis	$K,0x5a82
        +	ori	$K,$K,0x7999
        +___
        +for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;	# load K_20_39
        +	lis	$K,0x6ed9
        +	ori	$K,$K,0xeba1
        +___
        +for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;	# load K_40_59
        +	lis	$K,0x8f1b
        +	ori	$K,$K,0xbcdc
        +___
        +for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;	# load K_60_79
        +	lis	$K,0xca62
        +	ori	$K,$K,0xc1d6
        +___
        +for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	add	r16,r16,$E
        +	add	r17,r17,$T
        +	add	r18,r18,$A
        +	add	r19,r19,$B
        +	add	r20,r20,$C
        +	stw	r16,0($ctx)
        +	mr	$A,r16
        +	stw	r17,4($ctx)
        +	mr	$B,r17
        +	stw	r18,8($ctx)
        +	mr	$C,r18
        +	stw	r19,12($ctx)
        +	mr	$D,r19
        +	stw	r20,16($ctx)
        +	mr	$E,r20
        +	addi	$inp,$inp,`16*4`
        +	bdnz-	Lsha1_block_private
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +___
        +$code.=<<___;
        +.asciz	"SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-s390x.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-s390x.pl
        new file mode 100644
        index 000000000..9193dda45
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-s390x.pl
        @@ -0,0 +1,246 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA1 block procedure for s390x.
        +
        +# April 2007.
        +#
        +# Performance is >30% better than gcc 3.3 generated code. But the real
        +# twist is that SHA1 hardware support is detected and utilized. In
        +# which case performance can reach further >4.5x for larger chunks.
        +
        +# January 2009.
        +#
        +# Optimize Xupdate for amount of memory references and reschedule
        +# instructions to favour dual-issue z10 pipeline. On z10 hardware is
        +# "only" ~2.3x faster than software.
        +
        +# November 2010.
        +#
        +# Adapt for -m31 build. If kernel supports what's called "highgprs"
        +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
        +# instructions and achieve "64-bit" performance even in 31-bit legacy
        +# application context. The feature is not specific to any particular
        +# processor, as long as it's "z-CPU". Latter implies that the code
        +# remains z/Architecture specific.
        +
        +$kimdfunc=1;	# magic function code for kimd instruction
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +	$SIZE_T=4;
        +	$g="";
        +} else {
        +	$SIZE_T=8;
        +	$g="g";
        +}
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$K_00_39="%r0"; $K=$K_00_39;
        +$K_40_79="%r1";
        +$ctx="%r2";	$prefetch="%r2";
        +$inp="%r3";
        +$len="%r4";
        +
        +$A="%r5";
        +$B="%r6";
        +$C="%r7";
        +$D="%r8";
        +$E="%r9";	@V=($A,$B,$C,$D,$E);
        +$t0="%r10";
        +$t1="%r11";
        +@X=("%r12","%r13","%r14");
        +$sp="%r15";
        +
        +$stdframe=16*$SIZE_T+4*8;
        +$frame=$stdframe+16*4;
        +
        +sub Xupdate {
        +my $i=shift;
        +
        +$code.=<<___ if ($i==15);
        +	lg	$prefetch,$stdframe($sp)	### Xupdate(16) warm-up
        +	lr	$X[0],$X[2]
        +___
        +return if ($i&1);	# Xupdate is vectorized and executed every 2nd cycle
        +$code.=<<___ if ($i<16);
        +	lg	$X[0],`$i*4`($inp)	### Xload($i)
        +	rllg	$X[1],$X[0],32
        +___
        +$code.=<<___ if ($i>=16);
        +	xgr	$X[0],$prefetch		### Xupdate($i)
        +	lg	$prefetch,`$stdframe+4*(($i+2)%16)`($sp)
        +	xg	$X[0],`$stdframe+4*(($i+8)%16)`($sp)
        +	xgr	$X[0],$prefetch
        +	rll	$X[0],$X[0],1
        +	rllg	$X[1],$X[0],32
        +	rll	$X[1],$X[1],1
        +	rllg	$X[0],$X[1],32
        +	lr	$X[2],$X[1]		# feedback
        +___
        +$code.=<<___ if ($i<=70);
        +	stg	$X[0],`$stdframe+4*($i%16)`($sp)
        +___
        +unshift(@X,pop(@X));
        +}
        +
        +sub BODY_00_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $xi=$X[1];
        +
        +	&Xupdate($i);
        +$code.=<<___;
        +	alr	$e,$K		### $i
        +	rll	$t1,$a,5
        +	lr	$t0,$d
        +	xr	$t0,$c
        +	alr	$e,$t1
        +	nr	$t0,$b
        +	alr	$e,$xi
        +	xr	$t0,$d
        +	rll	$b,$b,30
        +	alr	$e,$t0
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $xi=$X[1];
        +
        +	&Xupdate($i);
        +$code.=<<___;
        +	alr	$e,$K		### $i
        +	rll	$t1,$a,5
        +	lr	$t0,$b
        +	alr	$e,$t1
        +	xr	$t0,$c
        +	alr	$e,$xi
        +	xr	$t0,$d
        +	rll	$b,$b,30
        +	alr	$e,$t0
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $xi=$X[1];
        +
        +	&Xupdate($i);
        +$code.=<<___;
        +	alr	$e,$K		### $i
        +	rll	$t1,$a,5
        +	lr	$t0,$b
        +	alr	$e,$t1
        +	or	$t0,$c
        +	lr	$t1,$b
        +	nr	$t0,$d
        +	nr	$t1,$c
        +	alr	$e,$xi
        +	or	$t0,$t1
        +	rll	$b,$b,30
        +	alr	$e,$t0
        +___
        +}
        +
        +$code.=<<___;
        +.text
        +.align	64
        +.type	Ktable,\@object
        +Ktable: .long	0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
        +	.skip	48	#.long	0,0,0,0,0,0,0,0,0,0,0,0
        +.size	Ktable,.-Ktable
        +.globl	sha1_block_data_order
        +.type	sha1_block_data_order,\@function
        +sha1_block_data_order:
        +___
        +$code.=<<___ if ($kimdfunc);
        +	larl	%r1,OPENSSL_s390xcap_P
        +	lg	%r0,0(%r1)
        +	tmhl	%r0,0x4000	# check for message-security assist
        +	jz	.Lsoftware
        +	lghi	%r0,0
        +	la	%r1,`2*$SIZE_T`($sp)
        +	.long	0xb93e0002	# kimd %r0,%r2
        +	lg	%r0,`2*$SIZE_T`($sp)
        +	tmhh	%r0,`0x8000>>$kimdfunc`
        +	jz	.Lsoftware
        +	lghi	%r0,$kimdfunc
        +	lgr	%r1,$ctx
        +	lgr	%r2,$inp
        +	sllg	%r3,$len,6
        +	.long	0xb93e0002	# kimd %r0,%r2
        +	brc	1,.-4		# pay attention to "partial completion"
        +	br	%r14
        +.align	16
        +.Lsoftware:
        +___
        +$code.=<<___;
        +	lghi	%r1,-$frame
        +	st${g}	$ctx,`2*$SIZE_T`($sp)
        +	stm${g}	%r6,%r15,`6*$SIZE_T`($sp)
        +	lgr	%r0,$sp
        +	la	$sp,0(%r1,$sp)
        +	st${g}	%r0,0($sp)
        +
        +	larl	$t0,Ktable
        +	llgf	$A,0($ctx)
        +	llgf	$B,4($ctx)
        +	llgf	$C,8($ctx)
        +	llgf	$D,12($ctx)
        +	llgf	$E,16($ctx)
        +
        +	lg	$K_00_39,0($t0)
        +	lg	$K_40_79,8($t0)
        +
        +.Lloop:
        +	rllg	$K_00_39,$K_00_39,32
        +___
        +for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	rllg	$K_00_39,$K_00_39,32
        +___
        +for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;	$K=$K_40_79;
        +	rllg	$K_40_79,$K_40_79,32
        +___
        +for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	rllg	$K_40_79,$K_40_79,32
        +___
        +for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +
        +	l${g}	$ctx,`$frame+2*$SIZE_T`($sp)
        +	la	$inp,64($inp)
        +	al	$A,0($ctx)
        +	al	$B,4($ctx)
        +	al	$C,8($ctx)
        +	al	$D,12($ctx)
        +	al	$E,16($ctx)
        +	st	$A,0($ctx)
        +	st	$B,4($ctx)
        +	st	$C,8($ctx)
        +	st	$D,12($ctx)
        +	st	$E,16($ctx)
        +	brct${g} $len,.Lloop
        +
        +	lm${g}	%r6,%r15,`$frame+6*$SIZE_T`($sp)
        +	br	%r14
        +.size	sha1_block_data_order,.-sha1_block_data_order
        +.string	"SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +.comm	OPENSSL_s390xcap_P,16,8
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-sparcv9.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-sparcv9.pl
        new file mode 100644
        index 000000000..5c161cecd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-sparcv9.pl
        @@ -0,0 +1,284 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# Performance improvement is not really impressive on pre-T1 CPU: +8%
        +# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it
        +# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and
        +# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick.
        +# X[16] vector is packed to 8 64-bit registers and as result nothing
        +# is spilled on stack. In addition input data is loaded in compact
        +# instruction sequence, thus minimizing the window when the code is
        +# subject to [inter-thread] cache-thrashing hazard. The goal is to
        +# ensure scalability on UltraSPARC T1, or rather to avoid decay when
        +# amount of active threads exceeds the number of physical cores.
        +
        +$bits=32;
        +for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +if ($bits==64)	{ $bias=2047; $frame=192; }
        +else		{ $bias=0;    $frame=112; }
        +
        +$output=shift;
        +open STDOUT,">$output";
        +
        +@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
        +$rot1m="%g2";
        +$tmp64="%g3";
        +$Xi="%g4";
        +$A="%l0";
        +$B="%l1";
        +$C="%l2";
        +$D="%l3";
        +$E="%l4";
        +@V=($A,$B,$C,$D,$E);
        +$K_00_19="%l5";
        +$K_20_39="%l6";
        +$K_40_59="%l7";
        +$K_60_79="%g5";
        +@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79);
        +
        +$ctx="%i0";
        +$inp="%i1";
        +$len="%i2";
        +$tmp0="%i3";
        +$tmp1="%i4";
        +$tmp2="%i5";
        +
        +sub BODY_00_15 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $xi=($i&1)?@X[($i/2)%8]:$Xi;
        +
        +$code.=<<___;
        +	sll	$a,5,$tmp0		!! $i
        +	add	@K[$i/20],$e,$e
        +	srl	$a,27,$tmp1
        +	add	$tmp0,$e,$e
        +	and	$c,$b,$tmp0
        +	add	$tmp1,$e,$e
        +	sll	$b,30,$tmp2
        +	andn	$d,$b,$tmp1
        +	srl	$b,2,$b
        +	or	$tmp1,$tmp0,$tmp1
        +	or	$tmp2,$b,$b
        +	add	$xi,$e,$e
        +___
        +if ($i&1 && $i<15) {
        +	$code.=
        +	"	srlx	@X[(($i+1)/2)%8],32,$Xi\n";
        +}
        +$code.=<<___;
        +	add	$tmp1,$e,$e
        +___
        +}
        +
        +sub Xupdate {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i/2;
        +
        +if ($i&1) {
        +$code.=<<___;
        +	sll	$a,5,$tmp0		!! $i
        +	add	@K[$i/20],$e,$e
        +	srl	$a,27,$tmp1
        +___
        +} else {
        +$code.=<<___;
        +	sllx	@X[($j+6)%8],32,$Xi	! Xupdate($i)
        +	xor	@X[($j+1)%8],@X[$j%8],@X[$j%8]
        +	srlx	@X[($j+7)%8],32,$tmp1
        +	xor	@X[($j+4)%8],@X[$j%8],@X[$j%8]
        +	sll	$a,5,$tmp0		!! $i
        +	or	$tmp1,$Xi,$Xi
        +	add	@K[$i/20],$e,$e		!!
        +	xor	$Xi,@X[$j%8],@X[$j%8]
        +	srlx	@X[$j%8],31,$Xi
        +	add	@X[$j%8],@X[$j%8],@X[$j%8]
        +	and	$Xi,$rot1m,$Xi
        +	andn	@X[$j%8],$rot1m,@X[$j%8]
        +	srl	$a,27,$tmp1		!!
        +	or	$Xi,@X[$j%8],@X[$j%8]
        +___
        +}
        +}
        +
        +sub BODY_16_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +
        +	&Xupdate(@_);
        +    if ($i&1) {
        +	$xi=@X[($i/2)%8];
        +    } else {
        +	$xi=$Xi;
        +	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
        +    }
        +$code.=<<___;
        +	add	$tmp0,$e,$e		!!
        +	and	$c,$b,$tmp0
        +	add	$tmp1,$e,$e
        +	sll	$b,30,$tmp2
        +	add	$xi,$e,$e
        +	andn	$d,$b,$tmp1
        +	srl	$b,2,$b
        +	or	$tmp1,$tmp0,$tmp1
        +	or	$tmp2,$b,$b
        +	add	$tmp1,$e,$e
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $xi;
        +	&Xupdate(@_);
        +    if ($i&1) {
        +	$xi=@X[($i/2)%8];
        +    } else {
        +	$xi=$Xi;
        +	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
        +    }
        +$code.=<<___;
        +	add	$tmp0,$e,$e		!!
        +	xor	$c,$b,$tmp0
        +	add	$tmp1,$e,$e
        +	sll	$b,30,$tmp2
        +	xor	$d,$tmp0,$tmp1
        +	srl	$b,2,$b
        +	add	$tmp1,$e,$e
        +	or	$tmp2,$b,$b
        +	add	$xi,$e,$e
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $xi;
        +	&Xupdate(@_);
        +    if ($i&1) {
        +	$xi=@X[($i/2)%8];
        +    } else {
        +	$xi=$Xi;
        +	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
        +    }
        +$code.=<<___;
        +	add	$tmp0,$e,$e		!!
        +	and	$c,$b,$tmp0
        +	add	$tmp1,$e,$e
        +	sll	$b,30,$tmp2
        +	or	$c,$b,$tmp1
        +	srl	$b,2,$b
        +	and	$d,$tmp1,$tmp1
        +	add	$xi,$e,$e
        +	or	$tmp1,$tmp0,$tmp1
        +	or	$tmp2,$b,$b
        +	add	$tmp1,$e,$e
        +___
        +}
        +
        +$code.=<<___ if ($bits==64);
        +.register	%g2,#scratch
        +.register	%g3,#scratch
        +___
        +$code.=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.align	32
        +.globl	sha1_block_data_order
        +sha1_block_data_order:
        +	save	%sp,-$frame,%sp
        +	sllx	$len,6,$len
        +	add	$inp,$len,$len
        +
        +	or	%g0,1,$rot1m
        +	sllx	$rot1m,32,$rot1m
        +	or	$rot1m,1,$rot1m
        +
        +	ld	[$ctx+0],$A
        +	ld	[$ctx+4],$B
        +	ld	[$ctx+8],$C
        +	ld	[$ctx+12],$D
        +	ld	[$ctx+16],$E
        +	andn	$inp,7,$tmp0
        +
        +	sethi	%hi(0x5a827999),$K_00_19
        +	or	$K_00_19,%lo(0x5a827999),$K_00_19
        +	sethi	%hi(0x6ed9eba1),$K_20_39
        +	or	$K_20_39,%lo(0x6ed9eba1),$K_20_39
        +	sethi	%hi(0x8f1bbcdc),$K_40_59
        +	or	$K_40_59,%lo(0x8f1bbcdc),$K_40_59
        +	sethi	%hi(0xca62c1d6),$K_60_79
        +	or	$K_60_79,%lo(0xca62c1d6),$K_60_79
        +
        +.Lloop:
        +	ldx	[$tmp0+0],@X[0]
        +	ldx	[$tmp0+16],@X[2]
        +	ldx	[$tmp0+32],@X[4]
        +	ldx	[$tmp0+48],@X[6]
        +	and	$inp,7,$tmp1
        +	ldx	[$tmp0+8],@X[1]
        +	sll	$tmp1,3,$tmp1
        +	ldx	[$tmp0+24],@X[3]
        +	subcc	%g0,$tmp1,$tmp2	! should be 64-$tmp1, but -$tmp1 works too
        +	ldx	[$tmp0+40],@X[5]
        +	bz,pt	%icc,.Laligned
        +	ldx	[$tmp0+56],@X[7]
        +
        +	sllx	@X[0],$tmp1,@X[0]
        +	ldx	[$tmp0+64],$tmp64
        +___
        +for($i=0;$i<7;$i++)
        +{   $code.=<<___;
        +	srlx	@X[$i+1],$tmp2,$Xi
        +	sllx	@X[$i+1],$tmp1,@X[$i+1]
        +	or	$Xi,@X[$i],@X[$i]
        +___
        +}
        +$code.=<<___;
        +	srlx	$tmp64,$tmp2,$tmp64
        +	or	$tmp64,@X[7],@X[7]
        +.Laligned:
        +	srlx	@X[0],32,$Xi
        +___
        +for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +
        +	ld	[$ctx+0],@X[0]
        +	ld	[$ctx+4],@X[1]
        +	ld	[$ctx+8],@X[2]
        +	ld	[$ctx+12],@X[3]
        +	add	$inp,64,$inp
        +	ld	[$ctx+16],@X[4]
        +	cmp	$inp,$len
        +
        +	add	$A,@X[0],$A
        +	st	$A,[$ctx+0]
        +	add	$B,@X[1],$B
        +	st	$B,[$ctx+4]
        +	add	$C,@X[2],$C
        +	st	$C,[$ctx+8]
        +	add	$D,@X[3],$D
        +	st	$D,[$ctx+12]
        +	add	$E,@X[4],$E
        +	st	$E,[$ctx+16]
        +
        +	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
        +	andn	$inp,7,$tmp0
        +
        +	ret
        +	restore
        +.type	sha1_block_data_order,#function
        +.size	sha1_block_data_order,(.-sha1_block_data_order)
        +.asciz	"SHA1 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	4
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl
        new file mode 100644
        index 000000000..e65291bbd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-sparcv9a.pl
        @@ -0,0 +1,601 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# January 2009
        +#
        +# Provided that UltraSPARC VIS instructions are pipe-lined(*) and
        +# pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC
        +# Graphic Unit would make it possible to achieve higher instruction-
        +# level parallelism, ILP, and thus higher performance. It should be
        +# explicitly noted that ILP is the keyword, and it means that this
        +# code would be unsuitable for cores like UltraSPARC-Tx. The idea is
        +# not really novel, Sun had VIS-powered implementation for a while.
        +# Unlike Sun's implementation this one can process multiple unaligned
        +# input blocks, and as such works as drop-in replacement for OpenSSL
        +# sha1_block_data_order. Performance improvement was measured to be
        +# 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on
        +# UltraSPARC-III. See below for discussion...
        +#
        +# The module does not present direct interest for OpenSSL, because
        +# it doesn't provide better performance on contemporary SPARCv9 CPUs,
        +# UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they
        +# absolutely must score on UltraSPARC-I-IV can simply replace
        +# crypto/sha/asm/sha1-sparcv9.pl with this module.
        +#
        +# (*)	"Pipe-lined" means that even if it takes several cycles to
        +#	complete, next instruction using same functional unit [but not
        +#	depending on the result of the current instruction] can start
        +#	execution without having to wait for the unit. "Pairable"
        +#	means that two [or more] independent instructions can be
        +#	issued at the very same time.
        +
        +$bits=32;
        +for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +if ($bits==64)	{ $bias=2047; $frame=192; }
        +else		{ $bias=0;    $frame=112; }
        +
        +$output=shift;
        +open STDOUT,">$output";
        +
        +$ctx="%i0";
        +$inp="%i1";
        +$len="%i2";
        +$tmp0="%i3";
        +$tmp1="%i4";
        +$tmp2="%i5";
        +$tmp3="%g5";
        +
        +$base="%g1";
        +$align="%g4";
        +$Xfer="%o5";
        +$nXfer=$tmp3;
        +$Xi="%o7";
        +
        +$A="%l0";
        +$B="%l1";
        +$C="%l2";
        +$D="%l3";
        +$E="%l4";
        +@V=($A,$B,$C,$D,$E);
        +
        +$Actx="%o0";
        +$Bctx="%o1";
        +$Cctx="%o2";
        +$Dctx="%o3";
        +$Ectx="%o4";
        +
        +$fmul="%f32";
        +$VK_00_19="%f34";
        +$VK_20_39="%f36";
        +$VK_40_59="%f38";
        +$VK_60_79="%f40";
        +@VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79);
        +@X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
        +    "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16");
        +
        +# This is reference 2x-parallelized VIS-powered Xupdate procedure. It
        +# covers even K_NN_MM addition...
        +sub Xupdate {
        +my ($i)=@_;
        +my $K=@VK[($i+16)/20];
        +my $j=($i+16)%16;
        +
        +#	[ provided that GSR.alignaddr_offset is 5, $mul contains
        +#	  0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to
        +#	  chosen registers... ]
        +$code.=<<___;
        +	fxors		@X[($j+13)%16],@X[$j],@X[$j]	!-1/-1/-1:X[0]^=X[13]
        +	fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
        +	fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
        +	fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
        +	faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
        +	fpadd32		@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
        +	fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
        +	![fxors		%f15,%f2,%f2]
        +	for		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
        +	![fxors		%f0,%f3,%f3]			!10/17/12:X[0] dependency
        +	fpadd32		$K,@X[$j],%f20
        +	std		%f20,[$Xfer+`4*$j`]
        +___
        +# The numbers delimited with slash are the earliest possible dispatch
        +# cycles for given instruction assuming 1 cycle latency for simple VIS
        +# instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as
        +# on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being
        +# 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1
        +# round. As [long as] FPU/VIS instructions are perfectly pairable with
        +# IALU ones, the round timing is defined by the maximum between VIS
        +# and IALU timings. The latter varies from round to round and averages
        +# out at 6.25 ticks. This means that USI&II should operate at IALU
        +# rate, while USIII&IV - at VIS rate. This explains why performance
        +# improvement varies among processors. Well, given that pure IALU
        +# sha1-sparcv9.pl module exhibits virtually uniform performance of
        +# ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical
        +# lower limits. Real-life performance was measured to be 6.6 cycles
        +# per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than
        +# half-round VIS timing, because there are 16 Xupdate-free rounds,
        +# which "push down" average theoretical timing to 8 cycles...
        +
        +# (*)	SPARC64-V[II] was originally believed to have 2 cycles VIS
        +#	latency. Well, it might have, but it doesn't have dedicated
        +#	VIS-unit. Instead, VIS instructions are executed by other
        +#	functional units, ones used here - by IALU. This doesn't
        +#	improve effective ILP...
        +}
        +
        +# The reference Xupdate procedure is then "strained" over *pairs* of
        +# BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13]
        +# and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves
        +# plenty of room to amortize for read-after-write hazard, as well as
        +# to fetch and align input for the next spin. The VIS instructions are
        +# scheduled for latency of 2 cycles, because there are not enough IALU
        +# instructions to schedule for latency of 3, while scheduling for 1
        +# would give no gain on USI&II anyway.
        +
        +sub BODY_00_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i&~1;
        +my $k=($j+16+2)%16;	# ahead reference
        +my $l=($j+16-2)%16;	# behind reference
        +my $K=@VK[($j+16-2)/20];
        +
        +$j=($j+16)%16;
        +
        +$code.=<<___ if (!($i&1));
        +	sll		$a,5,$tmp0			!! $i
        +	and		$c,$b,$tmp3
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
        +	sll		$b,30,$tmp2
        +	add		$tmp1,$e,$e
        +	andn		$d,$b,$tmp1
        +	add		$Xi,$e,$e
        +	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
        +	srl		$b,2,$b
        +	or		$tmp1,$tmp3,$tmp1
        +	or		$tmp2,$b,$b
        +	add		$tmp1,$e,$e
        +	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
        +___
        +$code.=<<___ if ($i&1);
        +	sll		$a,5,$tmp0			!! $i
        +	and		$c,$b,$tmp3
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
        +	sll		$b,30,$tmp2
        +	add		$tmp1,$e,$e
        +	 fpadd32	$K,@X[$l],%f20			!
        +	andn		$d,$b,$tmp1
        +	add		$Xi,$e,$e
        +	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
        +	srl		$b,2,$b
        +	or		$tmp1,$tmp3,$tmp1
        +	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
        +	or		$tmp2,$b,$b
        +	add		$tmp1,$e,$e
        +___
        +$code.=<<___ if ($i&1 && $i>=2);
        +	 std		%f20,[$Xfer+`4*$l`]		!
        +___
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i&~1;
        +my $k=($j+16+2)%16;	# ahead reference
        +my $l=($j+16-2)%16;	# behind reference
        +my $K=@VK[($j+16-2)/20];
        +
        +$j=($j+16)%16;
        +
        +$code.=<<___ if (!($i&1) && $i<64);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
        +___
        +$code.=<<___ if ($i&1 && $i<64);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	 fpadd32	$K,@X[$l],%f20			!
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +	 std		%f20,[$Xfer+`4*$l`]		!
        +___
        +$code.=<<___ if ($i==64);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	 fpadd32	$K,@X[$l],%f20
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	 std		%f20,[$Xfer+`4*$l`]
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +___
        +$code.=<<___ if ($i>64);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +___
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i&~1;
        +my $k=($j+16+2)%16;	# ahead reference
        +my $l=($j+16-2)%16;	# behind reference
        +my $K=@VK[($j+16-2)/20];
        +
        +$j=($j+16)%16;
        +
        +$code.=<<___ if (!($i&1));
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
        +	and		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	sll		$b,30,$tmp2
        +	or		$c,$b,$tmp1
        +	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
        +	srl		$b,2,$b
        +	and		$d,$tmp1,$tmp1
        +	add		$Xi,$e,$e
        +	or		$tmp1,$tmp0,$tmp1
        +	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
        +	or		$tmp2,$b,$b
        +	add		$tmp1,$e,$e
        +	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
        +___
        +$code.=<<___ if ($i&1);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
        +	and		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	 fpadd32	$K,@X[$l],%f20			!
        +	sll		$b,30,$tmp2
        +	or		$c,$b,$tmp1
        +	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
        +	srl		$b,2,$b
        +	and		$d,$tmp1,$tmp1
        +	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
        +	add		$Xi,$e,$e
        +	or		$tmp1,$tmp0,$tmp1
        +	or		$tmp2,$b,$b
        +	add		$tmp1,$e,$e
        +	 std		%f20,[$Xfer+`4*$l`]		!
        +___
        +}
        +
        +# If there is more data to process, then we pre-fetch the data for
        +# next iteration in last ten rounds...
        +sub BODY_70_79 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i&~1;
        +my $m=($i%8)*2;
        +
        +$j=($j+16)%16;
        +
        +$code.=<<___ if ($i==70);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	 ldd		[$inp+64],@X[0]
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +
        +	and		$inp,-64,$nXfer
        +	inc		64,$inp
        +	and		$nXfer,255,$nXfer
        +	alignaddr	%g0,$align,%g0
        +	add		$base,$nXfer,$nXfer
        +___
        +$code.=<<___ if ($i==71);
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +___
        +$code.=<<___ if ($i>=72);
        +	 faligndata	@X[$m],@X[$m+2],@X[$m]
        +	sll		$a,5,$tmp0			!! $i
        +	ld		[$Xfer+`4*($i%16)`],$Xi
        +	srl		$a,27,$tmp1
        +	add		$tmp0,$e,$e
        +	xor		$c,$b,$tmp0
        +	add		$tmp1,$e,$e
        +	 fpadd32	$VK_00_19,@X[$m],%f20
        +	sll		$b,30,$tmp2
        +	xor		$d,$tmp0,$tmp1
        +	srl		$b,2,$b
        +	add		$tmp1,$e,$e
        +	or		$tmp2,$b,$b
        +	add		$Xi,$e,$e
        +___
        +$code.=<<___ if ($i<77);
        +	 ldd		[$inp+`8*($i+1-70)`],@X[2*($i+1-70)]
        +___
        +$code.=<<___ if ($i==77);	# redundant if $inp was aligned
        +	 add		$align,63,$tmp0
        +	 and		$tmp0,-8,$tmp0
        +	 ldd		[$inp+$tmp0],@X[16]
        +___
        +$code.=<<___ if ($i>=72);
        +	 std		%f20,[$nXfer+`4*$m`]
        +___
        +}
        +
        +$code.=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.align	64
        +vis_const:
        +.long	0x5a827999,0x5a827999	! K_00_19
        +.long	0x6ed9eba1,0x6ed9eba1	! K_20_39
        +.long	0x8f1bbcdc,0x8f1bbcdc	! K_40_59
        +.long	0xca62c1d6,0xca62c1d6	! K_60_79
        +.long	0x00000100,0x00000100
        +.align	64
        +.type	vis_const,#object
        +.size	vis_const,(.-vis_const)
        +
        +.globl	sha1_block_data_order
        +sha1_block_data_order:
        +	save	%sp,-$frame,%sp
        +	add	%fp,$bias-256,$base
        +
        +1:	call	.+8
        +	add	%o7,vis_const-1b,$tmp0
        +
        +	ldd	[$tmp0+0],$VK_00_19
        +	ldd	[$tmp0+8],$VK_20_39
        +	ldd	[$tmp0+16],$VK_40_59
        +	ldd	[$tmp0+24],$VK_60_79
        +	ldd	[$tmp0+32],$fmul
        +
        +	ld	[$ctx+0],$Actx
        +	and	$base,-256,$base
        +	ld	[$ctx+4],$Bctx
        +	sub	$base,$bias+$frame,%sp
        +	ld	[$ctx+8],$Cctx
        +	and	$inp,7,$align
        +	ld	[$ctx+12],$Dctx
        +	and	$inp,-8,$inp
        +	ld	[$ctx+16],$Ectx
        +
        +	! X[16] is maintained in FP register bank
        +	alignaddr	%g0,$align,%g0
        +	ldd		[$inp+0],@X[0]
        +	sub		$inp,-64,$Xfer
        +	ldd		[$inp+8],@X[2]
        +	and		$Xfer,-64,$Xfer
        +	ldd		[$inp+16],@X[4]
        +	and		$Xfer,255,$Xfer
        +	ldd		[$inp+24],@X[6]
        +	add		$base,$Xfer,$Xfer
        +	ldd		[$inp+32],@X[8]
        +	ldd		[$inp+40],@X[10]
        +	ldd		[$inp+48],@X[12]
        +	brz,pt		$align,.Laligned
        +	ldd		[$inp+56],@X[14]
        +
        +	ldd		[$inp+64],@X[16]
        +	faligndata	@X[0],@X[2],@X[0]
        +	faligndata	@X[2],@X[4],@X[2]
        +	faligndata	@X[4],@X[6],@X[4]
        +	faligndata	@X[6],@X[8],@X[6]
        +	faligndata	@X[8],@X[10],@X[8]
        +	faligndata	@X[10],@X[12],@X[10]
        +	faligndata	@X[12],@X[14],@X[12]
        +	faligndata	@X[14],@X[16],@X[14]
        +
        +.Laligned:
        +	mov		5,$tmp0
        +	dec		1,$len
        +	alignaddr	%g0,$tmp0,%g0
        +	fpadd32		$VK_00_19,@X[0],%f16
        +	fpadd32		$VK_00_19,@X[2],%f18
        +	fpadd32		$VK_00_19,@X[4],%f20
        +	fpadd32		$VK_00_19,@X[6],%f22
        +	fpadd32		$VK_00_19,@X[8],%f24
        +	fpadd32		$VK_00_19,@X[10],%f26
        +	fpadd32		$VK_00_19,@X[12],%f28
        +	fpadd32		$VK_00_19,@X[14],%f30
        +	std		%f16,[$Xfer+0]
        +	mov		$Actx,$A
        +	std		%f18,[$Xfer+8]
        +	mov		$Bctx,$B
        +	std		%f20,[$Xfer+16]
        +	mov		$Cctx,$C
        +	std		%f22,[$Xfer+24]
        +	mov		$Dctx,$D
        +	std		%f24,[$Xfer+32]
        +	mov		$Ectx,$E
        +	std		%f26,[$Xfer+40]
        +	fxors		@X[13],@X[0],@X[0]
        +	std		%f28,[$Xfer+48]
        +	ba		.Loop
        +	std		%f30,[$Xfer+56]
        +.align	32
        +.Loop:
        +___
        +for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +for (;$i<70;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	tst		$len
        +	bz,pn		`$bits==32?"%icc":"%xcc"`,.Ltail
        +	nop
        +___
        +for (;$i<80;$i++)	{ &BODY_70_79($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	add		$A,$Actx,$Actx
        +	add		$B,$Bctx,$Bctx
        +	add		$C,$Cctx,$Cctx
        +	add		$D,$Dctx,$Dctx
        +	add		$E,$Ectx,$Ectx
        +	mov		5,$tmp0
        +	fxors		@X[13],@X[0],@X[0]
        +	mov		$Actx,$A
        +	mov		$Bctx,$B
        +	mov		$Cctx,$C
        +	mov		$Dctx,$D
        +	mov		$Ectx,$E
        +	alignaddr	%g0,$tmp0,%g0	
        +	dec		1,$len
        +	ba		.Loop
        +	mov		$nXfer,$Xfer
        +
        +.align	32
        +.Ltail:
        +___
        +for($i=70;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	add	$A,$Actx,$Actx
        +	add	$B,$Bctx,$Bctx
        +	add	$C,$Cctx,$Cctx
        +	add	$D,$Dctx,$Dctx
        +	add	$E,$Ectx,$Ectx
        +
        +	st	$Actx,[$ctx+0]
        +	st	$Bctx,[$ctx+4]
        +	st	$Cctx,[$ctx+8]
        +	st	$Dctx,[$ctx+12]
        +	st	$Ectx,[$ctx+16]
        +
        +	ret
        +	restore
        +.type	sha1_block_data_order,#function
        +.size	sha1_block_data_order,(.-sha1_block_data_order)
        +.asciz	"SHA1 block transform for SPARCv9a, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	4
        +___
        +
        +# Purpose of these subroutines is to explicitly encode VIS instructions,
        +# so that one can compile the module without having to specify VIS
        +# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
        +# Idea is to reserve for option to produce "universal" binary and let
        +# programmer detect if current CPU is VIS capable at run-time.
        +sub unvis {
        +my ($mnemonic,$rs1,$rs2,$rd)=@_;
        +my ($ref,$opf);
        +my %visopf = (	"fmul8ulx16"	=> 0x037,
        +		"faligndata"	=> 0x048,
        +		"fpadd32"	=> 0x052,
        +		"fxor"		=> 0x06c,
        +		"fxors"		=> 0x06d	);
        +
        +    $ref = "$mnemonic\t$rs1,$rs2,$rd";
        +
        +    if ($opf=$visopf{$mnemonic}) {
        +	foreach ($rs1,$rs2,$rd) {
        +	    return $ref if (!/%f([0-9]{1,2})/);
        +	    $_=$1;
        +	    if ($1>=32) {
        +		return $ref if ($1&1);
        +		# re-encode for upper double register addressing
        +		$_=($1|$1>>5)&31;
        +	    }
        +	}
        +
        +	return	sprintf ".word\t0x%08x !%s",
        +			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
        +			$ref;
        +    } else {
        +	return $ref;
        +    }
        +}
        +sub unalignaddr {
        +my ($mnemonic,$rs1,$rs2,$rd)=@_;
        +my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
        +my $ref="$mnemonic\t$rs1,$rs2,$rd";
        +
        +    foreach ($rs1,$rs2,$rd) {
        +	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
        +	else			{ return $ref; }
        +    }
        +    return  sprintf ".word\t0x%08x !%s",
        +		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
        +		    $ref;
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/
        +		&unvis($1,$2,$3,$4)
        +	  /gem;
        +$code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/
        +		&unalignaddr($1,$2,$3,$4)
        +	  /gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-thumb.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-thumb.pl
        new file mode 100644
        index 000000000..7c9ea9b02
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-thumb.pl
        @@ -0,0 +1,259 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# sha1_block for Thumb.
        +#
        +# January 2007.
        +#
        +# The code does not present direct interest to OpenSSL, because of low
        +# performance. Its purpose is to establish _size_ benchmark. Pretty
        +# useless one I must say, because 30% or 88 bytes larger ARMv4 code
        +# [avialable on demand] is almost _twice_ as fast. It should also be
        +# noted that in-lining of .Lcommon and .Lrotate improves performance
        +# by over 40%, while code increases by only 10% or 32 bytes. But once
        +# again, the goal was to establish _size_ benchmark, not performance.
        +
        +$output=shift;
        +open STDOUT,">$output";
        +
        +$inline=0;
        +#$cheat_on_binutils=1;
        +
        +$t0="r0";
        +$t1="r1";
        +$t2="r2";
        +$a="r3";
        +$b="r4";
        +$c="r5";
        +$d="r6";
        +$e="r7";
        +$K="r8";	# "upper" registers can be used in add/sub and mov insns
        +$ctx="r9";
        +$inp="r10";
        +$len="r11";
        +$Xi="r12";
        +
        +sub common {
        +<<___;
        +	sub	$t0,#4
        +	ldr	$t1,[$t0]
        +	add	$e,$K			@ E+=K_xx_xx
        +	lsl	$t2,$a,#5
        +	add	$t2,$e
        +	lsr	$e,$a,#27
        +	add	$t2,$e			@ E+=ROR(A,27)
        +	add	$t2,$t1			@ E+=X[i]
        +___
        +}
        +sub rotate {
        +<<___;
        +	mov	$e,$d			@ E=D
        +	mov	$d,$c			@ D=C
        +	lsl	$c,$b,#30
        +	lsr	$b,$b,#2
        +	orr	$c,$b			@ C=ROR(B,2)
        +	mov	$b,$a			@ B=A
        +	add	$a,$t2,$t1		@ A=E+F_xx_xx(B,C,D)
        +___
        +}
        +
        +sub BODY_00_19 {
        +$code.=$inline?&common():"\tbl	.Lcommon\n";
        +$code.=<<___;
        +	mov	$t1,$c
        +	eor	$t1,$d
        +	and	$t1,$b
        +	eor	$t1,$d			@ F_00_19(B,C,D)
        +___
        +$code.=$inline?&rotate():"\tbl	.Lrotate\n";
        +}
        +
        +sub BODY_20_39 {
        +$code.=$inline?&common():"\tbl	.Lcommon\n";
        +$code.=<<___;
        +	mov	$t1,$b
        +	eor	$t1,$c
        +	eor	$t1,$d			@ F_20_39(B,C,D)
        +___
        +$code.=$inline?&rotate():"\tbl	.Lrotate\n";
        +}
        +
        +sub BODY_40_59 {
        +$code.=$inline?&common():"\tbl	.Lcommon\n";
        +$code.=<<___;
        +	mov	$t1,$b
        +	and	$t1,$c
        +	mov	$e,$b
        +	orr	$e,$c
        +	and	$e,$d
        +	orr	$t1,$e			@ F_40_59(B,C,D)
        +___
        +$code.=$inline?&rotate():"\tbl	.Lrotate\n";
        +}
        +
        +$code=<<___;
        +.text
        +.code	16
        +
        +.global	sha1_block_data_order
        +.type	sha1_block_data_order,%function
        +
        +.align	2
        +sha1_block_data_order:
        +___
        +if ($cheat_on_binutils) {
        +$code.=<<___;
        +.code	32
        +	add	r3,pc,#1
        +	bx	r3			@ switch to Thumb ISA
        +.code	16
        +___
        +}
        +$code.=<<___;
        +	push	{r4-r7}
        +	mov	r3,r8
        +	mov	r4,r9
        +	mov	r5,r10
        +	mov	r6,r11
        +	mov	r7,r12
        +	push	{r3-r7,lr}
        +	lsl	r2,#6
        +	mov	$ctx,r0			@ save context
        +	mov	$inp,r1			@ save inp
        +	mov	$len,r2			@ save len
        +	add	$len,$inp		@ $len to point at inp end
        +
        +.Lloop:
        +	mov	$Xi,sp
        +	mov	$t2,sp
        +	sub	$t2,#16*4		@ [3]
        +.LXload:
        +	ldrb	$a,[$t1,#0]		@ $t1 is r1 and holds inp
        +	ldrb	$b,[$t1,#1]
        +	ldrb	$c,[$t1,#2]
        +	ldrb	$d,[$t1,#3]
        +	lsl	$a,#24
        +	lsl	$b,#16
        +	lsl	$c,#8
        +	orr	$a,$b
        +	orr	$a,$c
        +	orr	$a,$d
        +	add	$t1,#4
        +	push	{$a}
        +	cmp	sp,$t2
        +	bne	.LXload			@ [+14*16]
        +
        +	mov	$inp,$t1		@ update $inp
        +	sub	$t2,#32*4
        +	sub	$t2,#32*4
        +	mov	$e,#31			@ [+4]
        +.LXupdate:
        +	ldr	$a,[sp,#15*4]
        +	ldr	$b,[sp,#13*4]
        +	ldr	$c,[sp,#7*4]
        +	ldr	$d,[sp,#2*4]
        +	eor	$a,$b
        +	eor	$a,$c
        +	eor	$a,$d
        +	ror	$a,$e
        +	push	{$a}
        +	cmp	sp,$t2
        +	bne	.LXupdate		@ [+(11+1)*64]
        +
        +	ldmia	$t0!,{$a,$b,$c,$d,$e}	@ $t0 is r0 and holds ctx
        +	mov	$t0,$Xi
        +
        +	ldr	$t2,.LK_00_19
        +	mov	$t1,$t0
        +	sub	$t1,#20*4
        +	mov	$Xi,$t1
        +	mov	$K,$t2			@ [+7+4]
        +.L_00_19:
        +___
        +	&BODY_00_19();
        +$code.=<<___;
        +	cmp	$Xi,$t0
        +	bne	.L_00_19		@ [+(2+9+4+2+8+2)*20]
        +
        +	ldr	$t2,.LK_20_39
        +	mov	$t1,$t0
        +	sub	$t1,#20*4
        +	mov	$Xi,$t1
        +	mov	$K,$t2			@ [+5]
        +.L_20_39_or_60_79:
        +___
        +	&BODY_20_39();
        +$code.=<<___;
        +	cmp	$Xi,$t0
        +	bne	.L_20_39_or_60_79	@ [+(2+9+3+2+8+2)*20*2]
        +	cmp	sp,$t0
        +	beq	.Ldone			@ [+2]
        +
        +	ldr	$t2,.LK_40_59
        +	mov	$t1,$t0
        +	sub	$t1,#20*4
        +	mov	$Xi,$t1
        +	mov	$K,$t2			@ [+5]
        +.L_40_59:
        +___
        +	&BODY_40_59();
        +$code.=<<___;
        +	cmp	$Xi,$t0
        +	bne	.L_40_59		@ [+(2+9+6+2+8+2)*20]
        +
        +	ldr	$t2,.LK_60_79
        +	mov	$Xi,sp
        +	mov	$K,$t2
        +	b	.L_20_39_or_60_79	@ [+4]
        +.Ldone:
        +	mov	$t0,$ctx
        +	ldr	$t1,[$t0,#0]
        +	ldr	$t2,[$t0,#4]
        +	add	$a,$t1
        +	ldr	$t1,[$t0,#8]
        +	add	$b,$t2
        +	ldr	$t2,[$t0,#12]
        +	add	$c,$t1
        +	ldr	$t1,[$t0,#16]
        +	add	$d,$t2
        +	add	$e,$t1
        +	stmia	$t0!,{$a,$b,$c,$d,$e}	@ [+20]
        +
        +	add	sp,#80*4		@ deallocate stack frame
        +	mov	$t0,$ctx		@ restore ctx
        +	mov	$t1,$inp		@ restore inp
        +	cmp	$t1,$len
        +	beq	.Lexit
        +	b	.Lloop			@ [+6] total 3212 cycles
        +.Lexit:
        +	pop	{r2-r7}
        +	mov	r8,r2
        +	mov	r9,r3
        +	mov	r10,r4
        +	mov	r11,r5
        +	mov	r12,r6
        +	mov	lr,r7
        +	pop	{r4-r7}
        +	bx	lr
        +.align	2
        +___
        +$code.=".Lcommon:\n".&common()."\tmov	pc,lr\n" if (!$inline);
        +$code.=".Lrotate:\n".&rotate()."\tmov	pc,lr\n" if (!$inline);
        +$code.=<<___;
        +.align	2
        +.LK_00_19:	.word	0x5a827999
        +.LK_20_39:	.word	0x6ed9eba1
        +.LK_40_59:	.word	0x8f1bbcdc
        +.LK_60_79:	.word	0xca62c1d6
        +.size	sha1_block_data_order,.-sha1_block_data_order
        +.asciz	"SHA1 block transform for Thumb, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +print $code;
        +close STDOUT; # enforce flush
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl b/vendor/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl
        new file mode 100644
        index 000000000..cfdc45cce
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha1-x86_64.pl
        @@ -0,0 +1,1261 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# sha1_block procedure for x86_64.
        +#
        +# It was brought to my attention that on EM64T compiler-generated code
        +# was far behind 32-bit assembler implementation. This is unlike on
        +# Opteron where compiler-generated code was only 15% behind 32-bit
        +# assembler, which originally made it hard to motivate the effort.
        +# There was suggestion to mechanically translate 32-bit code, but I
        +# dismissed it, reasoning that x86_64 offers enough register bank
        +# capacity to fully utilize SHA-1 parallelism. Therefore this fresh
        +# implementation:-) However! While 64-bit code does perform better
        +# on Opteron, I failed to beat 32-bit assembler on EM64T core. Well,
        +# x86_64 does offer larger *addressable* bank, but out-of-order core
        +# reaches for even more registers through dynamic aliasing, and EM64T
        +# core must have managed to run-time optimize even 32-bit code just as
        +# good as 64-bit one. Performance improvement is summarized in the
        +# following table:
        +#
        +#		gcc 3.4		32-bit asm	cycles/byte
        +# Opteron	+45%		+20%		6.8
        +# Xeon P4	+65%		+0%		9.9
        +# Core2		+60%		+10%		7.0
        +
        +# August 2009.
        +#
        +# The code was revised to minimize code size and to maximize
        +# "distance" between instructions producing input to 'lea'
        +# instruction and the 'lea' instruction itself, which is essential
        +# for Intel Atom core.
        +
        +# October 2010.
        +#
        +# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it
        +# is to offload message schedule denoted by Wt in NIST specification,
        +# or Xupdate in OpenSSL source, to SIMD unit. See sha1-586.pl module
        +# for background and implementation details. The only difference from
        +# 32-bit code is that 64-bit code doesn't have to spill @X[] elements
        +# to free temporary registers.
        +
        +# April 2011.
        +#
        +# Add AVX code path. See sha1-586.pl for further information.
        +
        +######################################################################
        +# Current performance is summarized in following table. Numbers are
        +# CPU clock cycles spent to process single byte (less is better).
        +#
        +#		x86_64		SSSE3		AVX
        +# P4		9.8		-
        +# Opteron	6.6		-
        +# Core2		6.7		6.1/+10%	-
        +# Atom		11.0		9.7/+13%	-
        +# Westmere	7.1		5.6/+27%	-
        +# Sandy Bridge	7.9		6.3/+25%	5.2/+51%
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
        +		=~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
        +	   $1>=2.19);
        +$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
        +	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
        +	   $1>=2.09);
        +$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
        +	   `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
        +	   $1>=10);
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +$ctx="%rdi";	# 1st arg
        +$inp="%rsi";	# 2nd arg
        +$num="%rdx";	# 3rd arg
        +
        +# reassign arguments in order to produce more compact code
        +$ctx="%r8";
        +$inp="%r9";
        +$num="%r10";
        +
        +$t0="%eax";
        +$t1="%ebx";
        +$t2="%ecx";
        +@xi=("%edx","%ebp");
        +$A="%esi";
        +$B="%edi";
        +$C="%r11d";
        +$D="%r12d";
        +$E="%r13d";
        +
        +@V=($A,$B,$C,$D,$E);
        +
        +sub BODY_00_19 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___ if ($i==0);
        +	mov	`4*$i`($inp),$xi[0]
        +	bswap	$xi[0]
        +	mov	$xi[0],`4*$i`(%rsp)
        +___
        +$code.=<<___ if ($i<15);
        +	mov	$c,$t0
        +	mov	`4*$j`($inp),$xi[1]
        +	mov	$a,$t2
        +	xor	$d,$t0
        +	bswap	$xi[1]
        +	rol	\$5,$t2
        +	lea	0x5a827999($xi[0],$e),$e
        +	and	$b,$t0
        +	mov	$xi[1],`4*$j`(%rsp)
        +	add	$t2,$e
        +	xor	$d,$t0
        +	rol	\$30,$b
        +	add	$t0,$e
        +___
        +$code.=<<___ if ($i>=15);
        +	mov	`4*($j%16)`(%rsp),$xi[1]
        +	mov	$c,$t0
        +	mov	$a,$t2
        +	xor	`4*(($j+2)%16)`(%rsp),$xi[1]
        +	xor	$d,$t0
        +	rol	\$5,$t2
        +	xor	`4*(($j+8)%16)`(%rsp),$xi[1]
        +	and	$b,$t0
        +	lea	0x5a827999($xi[0],$e),$e
        +	xor	`4*(($j+13)%16)`(%rsp),$xi[1]
        +	xor	$d,$t0
        +	rol	\$1,$xi[1]
        +	add	$t2,$e
        +	rol	\$30,$b
        +	mov	$xi[1],`4*($j%16)`(%rsp)
        +	add	$t0,$e
        +___
        +unshift(@xi,pop(@xi));
        +}
        +
        +sub BODY_20_39 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +my $K=($i<40)?0x6ed9eba1:0xca62c1d6;
        +$code.=<<___ if ($i<79);
        +	mov	`4*($j%16)`(%rsp),$xi[1]
        +	mov	$c,$t0
        +	mov	$a,$t2
        +	xor	`4*(($j+2)%16)`(%rsp),$xi[1]
        +	xor	$b,$t0
        +	rol	\$5,$t2
        +	lea	$K($xi[0],$e),$e
        +	xor	`4*(($j+8)%16)`(%rsp),$xi[1]
        +	xor	$d,$t0
        +	add	$t2,$e
        +	xor	`4*(($j+13)%16)`(%rsp),$xi[1]
        +	rol	\$30,$b
        +	add	$t0,$e
        +	rol	\$1,$xi[1]
        +___
        +$code.=<<___ if ($i<76);
        +	mov	$xi[1],`4*($j%16)`(%rsp)
        +___
        +$code.=<<___ if ($i==79);
        +	mov	$c,$t0
        +	mov	$a,$t2
        +	xor	$b,$t0
        +	lea	$K($xi[0],$e),$e
        +	rol	\$5,$t2
        +	xor	$d,$t0
        +	add	$t2,$e
        +	rol	\$30,$b
        +	add	$t0,$e
        +___
        +unshift(@xi,pop(@xi));
        +}
        +
        +sub BODY_40_59 {
        +my ($i,$a,$b,$c,$d,$e)=@_;
        +my $j=$i+1;
        +$code.=<<___;
        +	mov	`4*($j%16)`(%rsp),$xi[1]
        +	mov	$c,$t0
        +	mov	$c,$t1
        +	xor	`4*(($j+2)%16)`(%rsp),$xi[1]
        +	and	$d,$t0
        +	mov	$a,$t2
        +	xor	`4*(($j+8)%16)`(%rsp),$xi[1]
        +	xor	$d,$t1
        +	lea	0x8f1bbcdc($xi[0],$e),$e
        +	rol	\$5,$t2
        +	xor	`4*(($j+13)%16)`(%rsp),$xi[1]
        +	add	$t0,$e
        +	and	$b,$t1
        +	rol	\$1,$xi[1]
        +	add	$t1,$e
        +	rol	\$30,$b
        +	mov	$xi[1],`4*($j%16)`(%rsp)
        +	add	$t2,$e
        +___
        +unshift(@xi,pop(@xi));
        +}
        +
        +$code.=<<___;
        +.text
        +.extern	OPENSSL_ia32cap_P
        +
        +.globl	sha1_block_data_order
        +.type	sha1_block_data_order,\@function,3
        +.align	16
        +sha1_block_data_order:
        +	mov	OPENSSL_ia32cap_P+0(%rip),%r9d
        +	mov	OPENSSL_ia32cap_P+4(%rip),%r8d
        +	test	\$`1<<9`,%r8d		# check SSSE3 bit
        +	jz	.Lialu
        +___
        +$code.=<<___ if ($avx);
        +	and	\$`1<<28`,%r8d		# mask AVX bit
        +	and	\$`1<<30`,%r9d		# mask "Intel CPU" bit
        +	or	%r9d,%r8d
        +	cmp	\$`1<<28|1<<30`,%r8d
        +	je	_avx_shortcut
        +___
        +$code.=<<___;
        +	jmp	_ssse3_shortcut
        +
        +.align	16
        +.Lialu:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	mov	%rsp,%r11
        +	mov	%rdi,$ctx	# reassigned argument
        +	sub	\$`8+16*4`,%rsp
        +	mov	%rsi,$inp	# reassigned argument
        +	and	\$-64,%rsp
        +	mov	%rdx,$num	# reassigned argument
        +	mov	%r11,`16*4`(%rsp)
        +.Lprologue:
        +
        +	mov	0($ctx),$A
        +	mov	4($ctx),$B
        +	mov	8($ctx),$C
        +	mov	12($ctx),$D
        +	mov	16($ctx),$E
        +	jmp	.Lloop
        +
        +.align	16
        +.Lloop:
        +___
        +for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
        +for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
        +for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	add	0($ctx),$A
        +	add	4($ctx),$B
        +	add	8($ctx),$C
        +	add	12($ctx),$D
        +	add	16($ctx),$E
        +	mov	$A,0($ctx)
        +	mov	$B,4($ctx)
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +
        +	sub	\$1,$num
        +	lea	`16*4`($inp),$inp
        +	jnz	.Lloop
        +
        +	mov	`16*4`(%rsp),%rsi
        +	mov	(%rsi),%r13
        +	mov	8(%rsi),%r12
        +	mov	16(%rsi),%rbp
        +	mov	24(%rsi),%rbx
        +	lea	32(%rsi),%rsp
        +.Lepilogue:
        +	ret
        +.size	sha1_block_data_order,.-sha1_block_data_order
        +___
        +{{{
        +my $Xi=4;
        +my @X=map("%xmm$_",(4..7,0..3));
        +my @Tx=map("%xmm$_",(8..10));
        +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
        +my @T=("%esi","%edi");
        +my $j=0;
        +my $K_XX_XX="%r11";
        +
        +my $_rol=sub { &rol(@_) };
        +my $_ror=sub { &ror(@_) };
        +
        +$code.=<<___;
        +.type	sha1_block_data_order_ssse3,\@function,3
        +.align	16
        +sha1_block_data_order_ssse3:
        +_ssse3_shortcut:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	lea	`-64-($win64?5*16:0)`(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,64+0(%rsp)
        +	movaps	%xmm7,64+16(%rsp)
        +	movaps	%xmm8,64+32(%rsp)
        +	movaps	%xmm9,64+48(%rsp)
        +	movaps	%xmm10,64+64(%rsp)
        +.Lprologue_ssse3:
        +___
        +$code.=<<___;
        +	mov	%rdi,$ctx	# reassigned argument
        +	mov	%rsi,$inp	# reassigned argument
        +	mov	%rdx,$num	# reassigned argument
        +
        +	shl	\$6,$num
        +	add	$inp,$num
        +	lea	K_XX_XX(%rip),$K_XX_XX
        +
        +	mov	0($ctx),$A		# load context
        +	mov	4($ctx),$B
        +	mov	8($ctx),$C
        +	mov	12($ctx),$D
        +	mov	$B,@T[0]		# magic seed
        +	mov	16($ctx),$E
        +
        +	movdqa	64($K_XX_XX),@X[2]	# pbswap mask
        +	movdqa	0($K_XX_XX),@Tx[1]	# K_00_19
        +	movdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
        +	movdqu	16($inp),@X[-3&7]
        +	movdqu	32($inp),@X[-2&7]
        +	movdqu	48($inp),@X[-1&7]
        +	pshufb	@X[2],@X[-4&7]		# byte swap
        +	add	\$64,$inp
        +	pshufb	@X[2],@X[-3&7]
        +	pshufb	@X[2],@X[-2&7]
        +	pshufb	@X[2],@X[-1&7]
        +	paddd	@Tx[1],@X[-4&7]		# add K_00_19
        +	paddd	@Tx[1],@X[-3&7]
        +	paddd	@Tx[1],@X[-2&7]
        +	movdqa	@X[-4&7],0(%rsp)	# X[]+K xfer to IALU
        +	psubd	@Tx[1],@X[-4&7]		# restore X[]
        +	movdqa	@X[-3&7],16(%rsp)
        +	psubd	@Tx[1],@X[-3&7]
        +	movdqa	@X[-2&7],32(%rsp)
        +	psubd	@Tx[1],@X[-2&7]
        +	jmp	.Loop_ssse3
        +___
        +
        +sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
        +{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
        +  my $arg = pop;
        +    $arg = "\$$arg" if ($arg*1 eq $arg);
        +    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
        +}
        +
        +sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&movdqa	(@X[0],@X[-3&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(@Tx[0],@X[-1&7]);
        +	&palignr(@X[0],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &paddd	(@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&psrldq	(@Tx[0],4);		# "X[-3]", 3 dwords
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&pxor	(@X[0],@X[-4&7]);	# "X[0]"^="X[-16]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&movdqa	(@Tx[2],@X[0]);
        +	&movdqa	(@Tx[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pslldq	(@Tx[2],12);		# "X[0]"<<96, extract one dword
        +	&paddd	(@X[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&psrld	(@Tx[0],31);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(@Tx[1],@Tx[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&psrld	(@Tx[2],30);
        +	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=1
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pslld	(@Tx[1],2);
        +	&pxor	(@X[0],@Tx[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &movdqa	(@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)");	# K_XX_XX
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@Tx[1]);		# "X[0]"^=("X[0]">>96)<<<2
        +
        +	 foreach (@insns) { eval; }	# remaining instructions [if any]
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xupdate_ssse3_32_79()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&movdqa	(@Tx[0],@X[-1&7])	if ($Xi==8);
        +	 eval(shift(@insns));		# body_20_39
        +	&pxor	(@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
        +	&palignr(@Tx[0],@X[-2&7],8);	# compose "X[-6]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&pxor	(@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns))	if (@insns[0] !~ /&ro[rl]/);
        +	if ($Xi%5) {
        +	  &movdqa	(@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
        +	} else {			# ... or load next one
        +	  &movdqa	(@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
        +	}
        +	  &paddd	(@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&movdqa	(@Tx[0],@X[0]);
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&pslld	(@X[0],2);
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	&psrld	(@Tx[0],30);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=2
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	  &movdqa	(@Tx[1],@X[0])	if ($Xi<19);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xuplast_ssse3_80()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	  &paddd	(@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
        +
        +	 foreach (@insns) { eval; }		# remaining instructions
        +
        +	&cmp	($inp,$num);
        +	&je	(".Ldone_ssse3");
        +
        +	unshift(@Tx,pop(@Tx));
        +
        +	&movdqa	(@X[2],"64($K_XX_XX)");		# pbswap mask
        +	&movdqa	(@Tx[1],"0($K_XX_XX)");		# K_00_19
        +	&movdqu	(@X[-4&7],"0($inp)");		# load input
        +	&movdqu	(@X[-3&7],"16($inp)");
        +	&movdqu	(@X[-2&7],"32($inp)");
        +	&movdqu	(@X[-1&7],"48($inp)");
        +	&pshufb	(@X[-4&7],@X[2]);		# byte swap
        +	&add	($inp,64);
        +
        +  $Xi=0;
        +}
        +
        +sub Xloop_ssse3()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&pshufb	(@X[($Xi-3)&7],@X[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&paddd	(@X[($Xi-4)&7],@Tx[1]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&movdqa	(eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&psubd	(@X[($Xi-4)&7],@Tx[1]);
        +
        +	foreach (@insns) { eval; }
        +  $Xi++;
        +}
        +
        +sub Xtail_ssse3()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	foreach (@insns) { eval; }
        +}
        +
        +sub body_00_19 () {
        +	(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&add	($e,eval(4*($j&15))."(%rsp)");',	# X[]+K xfer
        +	'&xor	($c,$d);',
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&and	(@T[0],$c);',	# ($b&($c^$d))
        +	'&xor	($c,$d);',	# restore $c
        +	'&xor	(@T[0],$d);',
        +	'&add	($e,$a);',
        +	'&$_ror	($b,$j?7:2);',	# $b>>>2
        +	'&add	($e,@T[0]);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +}
        +
        +sub body_20_39 () {
        +	(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&add	($e,eval(4*($j++&15))."(%rsp)");',	# X[]+K xfer
        +	'&xor	(@T[0],$d);',	# ($b^$d)
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&xor	(@T[0],$c);',	# ($b^$d^$c)
        +	'&add	($e,$a);',
        +	'&$_ror	($b,7);',	# $b>>>2
        +	'&add	($e,@T[0]);'	.'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +}
        +
        +sub body_40_59 () {
        +	(
        +	'($a,$b,$c,$d,$e)=@V;'.
        +	'&mov	(@T[1],$c);',
        +	'&xor	($c,$d);',
        +	'&add	($e,eval(4*($j++&15))."(%rsp)");',	# X[]+K xfer
        +	'&and	(@T[1],$d);',
        +	'&and	(@T[0],$c);',	# ($b&($c^$d))
        +	'&$_ror	($b,7);',	# $b>>>2
        +	'&add	($e,@T[1]);',
        +	'&mov	(@T[1],$a);',	# $b in next round
        +	'&$_rol	($a,5);',
        +	'&add	($e,@T[0]);',
        +	'&xor	($c,$d);',	# restore $c
        +	'&add	($e,$a);'	.'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        +	);
        +}
        +$code.=<<___;
        +.align	16
        +.Loop_ssse3:
        +___
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_16_31(\&body_00_19);
        +	&Xupdate_ssse3_32_79(\&body_00_19);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_40_59);
        +	&Xupdate_ssse3_32_79(\&body_20_39);
        +	&Xuplast_ssse3_80(\&body_20_39);	# can jump to "done"
        +
        +				$saved_j=$j; @saved_V=@V;
        +
        +	&Xloop_ssse3(\&body_20_39);
        +	&Xloop_ssse3(\&body_20_39);
        +	&Xloop_ssse3(\&body_20_39);
        +
        +$code.=<<___;
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	add	12($ctx),$D
        +	mov	$A,0($ctx)
        +	add	16($ctx),$E
        +	mov	@T[0],4($ctx)
        +	mov	@T[0],$B			# magic seed
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +	jmp	.Loop_ssse3
        +
        +.align	16
        +.Ldone_ssse3:
        +___
        +				$j=$saved_j; @V=@saved_V;
        +
        +	&Xtail_ssse3(\&body_20_39);
        +	&Xtail_ssse3(\&body_20_39);
        +	&Xtail_ssse3(\&body_20_39);
        +
        +$code.=<<___;
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	mov	$A,0($ctx)
        +	add	12($ctx),$D
        +	mov	@T[0],4($ctx)
        +	add	16($ctx),$E
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	64+0(%rsp),%xmm6
        +	movaps	64+16(%rsp),%xmm7
        +	movaps	64+32(%rsp),%xmm8
        +	movaps	64+48(%rsp),%xmm9
        +	movaps	64+64(%rsp),%xmm10
        +___
        +$code.=<<___;
        +	lea	`64+($win64?5*16:0)`(%rsp),%rsi
        +	mov	0(%rsi),%r12
        +	mov	8(%rsi),%rbp
        +	mov	16(%rsi),%rbx
        +	lea	24(%rsi),%rsp
        +.Lepilogue_ssse3:
        +	ret
        +.size	sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
        +___
        +
        +if ($avx) {
        +my $Xi=4;
        +my @X=map("%xmm$_",(4..7,0..3));
        +my @Tx=map("%xmm$_",(8..10));
        +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
        +my @T=("%esi","%edi");
        +my $j=0;
        +my $K_XX_XX="%r11";
        +
        +my $_rol=sub { &shld(@_[0],@_) };
        +my $_ror=sub { &shrd(@_[0],@_) };
        +
        +$code.=<<___;
        +.type	sha1_block_data_order_avx,\@function,3
        +.align	16
        +sha1_block_data_order_avx:
        +_avx_shortcut:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	lea	`-64-($win64?5*16:0)`(%rsp),%rsp
        +___
        +$code.=<<___ if ($win64);
        +	movaps	%xmm6,64+0(%rsp)
        +	movaps	%xmm7,64+16(%rsp)
        +	movaps	%xmm8,64+32(%rsp)
        +	movaps	%xmm9,64+48(%rsp)
        +	movaps	%xmm10,64+64(%rsp)
        +.Lprologue_avx:
        +___
        +$code.=<<___;
        +	mov	%rdi,$ctx	# reassigned argument
        +	mov	%rsi,$inp	# reassigned argument
        +	mov	%rdx,$num	# reassigned argument
        +	vzeroall
        +
        +	shl	\$6,$num
        +	add	$inp,$num
        +	lea	K_XX_XX(%rip),$K_XX_XX
        +
        +	mov	0($ctx),$A		# load context
        +	mov	4($ctx),$B
        +	mov	8($ctx),$C
        +	mov	12($ctx),$D
        +	mov	$B,@T[0]		# magic seed
        +	mov	16($ctx),$E
        +
        +	vmovdqa	64($K_XX_XX),@X[2]	# pbswap mask
        +	vmovdqa	0($K_XX_XX),@Tx[1]	# K_00_19
        +	vmovdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
        +	vmovdqu	16($inp),@X[-3&7]
        +	vmovdqu	32($inp),@X[-2&7]
        +	vmovdqu	48($inp),@X[-1&7]
        +	vpshufb	@X[2],@X[-4&7],@X[-4&7]	# byte swap
        +	add	\$64,$inp
        +	vpshufb	@X[2],@X[-3&7],@X[-3&7]
        +	vpshufb	@X[2],@X[-2&7],@X[-2&7]
        +	vpshufb	@X[2],@X[-1&7],@X[-1&7]
        +	vpaddd	@Tx[1],@X[-4&7],@X[0]	# add K_00_19
        +	vpaddd	@Tx[1],@X[-3&7],@X[1]
        +	vpaddd	@Tx[1],@X[-2&7],@X[2]
        +	vmovdqa	@X[0],0(%rsp)		# X[]+K xfer to IALU
        +	vmovdqa	@X[1],16(%rsp)
        +	vmovdqa	@X[2],32(%rsp)
        +	jmp	.Loop_avx
        +___
        +
        +sub Xupdate_avx_16_31()		# recall that $Xi starts wtih 4
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &vpaddd	(@Tx[1],@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpsrldq(@Tx[0],@X[-1&7],4);	# "X[-3]", 3 dwords
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpsrld	(@Tx[0],@X[0],31);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpslldq(@Tx[2],@X[0],12);		# "X[0]"<<96, extract one dword
        +	&vpaddd	(@X[0],@X[0],@X[0]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpsrld	(@Tx[1],@Tx[2],30);
        +	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=1
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpslld	(@Tx[2],@Tx[2],2);
        +	&vpxor	(@X[0],@X[0],@Tx[1]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@Tx[2]);		# "X[0]"^=("X[0]">>96)<<<2
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	  &vmovdqa	(@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)");	# K_XX_XX
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +
        +	 foreach (@insns) { eval; }	# remaining instructions [if any]
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xupdate_avx_32_79()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	&vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
        +	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"="X[-32]"^"X[-16]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&vpxor	(@X[0],@X[0],@X[-7&7]);		# "X[0]"^="X[-28]"
        +	 eval(shift(@insns));
        +	 eval(shift(@insns))	if (@insns[0] !~ /&ro[rl]/);
        +	if ($Xi%5) {
        +	  &vmovdqa	(@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
        +	} else {			# ... or load next one
        +	  &vmovdqa	(@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
        +	}
        +	  &vpaddd	(@Tx[1],@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +
        +	&vpsrld	(@Tx[0],@X[0],30);
        +	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpslld	(@X[0],@X[0],2);
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# ror
        +	 eval(shift(@insns));
        +
        +	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=2
        +	 eval(shift(@insns));		# body_20_39
        +	 eval(shift(@insns));
        +	  &vmovdqa	(@Tx[1],@X[0])	if ($Xi<19);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));		# rol
        +	 eval(shift(@insns));
        +
        +	 foreach (@insns) { eval; }	# remaining instructions
        +
        +  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
        +		push(@Tx,shift(@Tx));
        +}
        +
        +sub Xuplast_avx_80()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	  &vpaddd	(@Tx[1],@Tx[1],@X[-1&7]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
        +
        +	 foreach (@insns) { eval; }		# remaining instructions
        +
        +	&cmp	($inp,$num);
        +	&je	(".Ldone_avx");
        +
        +	unshift(@Tx,pop(@Tx));
        +
        +	&vmovdqa(@X[2],"64($K_XX_XX)");		# pbswap mask
        +	&vmovdqa(@Tx[1],"0($K_XX_XX)");		# K_00_19
        +	&vmovdqu(@X[-4&7],"0($inp)");		# load input
        +	&vmovdqu(@X[-3&7],"16($inp)");
        +	&vmovdqu(@X[-2&7],"32($inp)");
        +	&vmovdqu(@X[-1&7],"48($inp)");
        +	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);	# byte swap
        +	&add	($inp,64);
        +
        +  $Xi=0;
        +}
        +
        +sub Xloop_avx()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vpaddd	(@X[$Xi&7],@X[($Xi-4)&7],@Tx[1]);
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +	&vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]);	# X[]+K xfer to IALU
        +	 eval(shift(@insns));
        +	 eval(shift(@insns));
        +
        +	foreach (@insns) { eval; }
        +  $Xi++;
        +}
        +
        +sub Xtail_avx()
        +{ use integer;
        +  my $body = shift;
        +  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
        +  my ($a,$b,$c,$d,$e);
        +
        +	foreach (@insns) { eval; }
        +}
        +
        +$code.=<<___;
        +.align	16
        +.Loop_avx:
        +___
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_16_31(\&body_00_19);
        +	&Xupdate_avx_32_79(\&body_00_19);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_40_59);
        +	&Xupdate_avx_32_79(\&body_20_39);
        +	&Xuplast_avx_80(\&body_20_39);	# can jump to "done"
        +
        +				$saved_j=$j; @saved_V=@V;
        +
        +	&Xloop_avx(\&body_20_39);
        +	&Xloop_avx(\&body_20_39);
        +	&Xloop_avx(\&body_20_39);
        +
        +$code.=<<___;
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	add	12($ctx),$D
        +	mov	$A,0($ctx)
        +	add	16($ctx),$E
        +	mov	@T[0],4($ctx)
        +	mov	@T[0],$B			# magic seed
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +	jmp	.Loop_avx
        +
        +.align	16
        +.Ldone_avx:
        +___
        +				$j=$saved_j; @V=@saved_V;
        +
        +	&Xtail_avx(\&body_20_39);
        +	&Xtail_avx(\&body_20_39);
        +	&Xtail_avx(\&body_20_39);
        +
        +$code.=<<___;
        +	vzeroall
        +
        +	add	0($ctx),$A			# update context
        +	add	4($ctx),@T[0]
        +	add	8($ctx),$C
        +	mov	$A,0($ctx)
        +	add	12($ctx),$D
        +	mov	@T[0],4($ctx)
        +	add	16($ctx),$E
        +	mov	$C,8($ctx)
        +	mov	$D,12($ctx)
        +	mov	$E,16($ctx)
        +___
        +$code.=<<___ if ($win64);
        +	movaps	64+0(%rsp),%xmm6
        +	movaps	64+16(%rsp),%xmm7
        +	movaps	64+32(%rsp),%xmm8
        +	movaps	64+48(%rsp),%xmm9
        +	movaps	64+64(%rsp),%xmm10
        +___
        +$code.=<<___;
        +	lea	`64+($win64?5*16:0)`(%rsp),%rsi
        +	mov	0(%rsi),%r12
        +	mov	8(%rsi),%rbp
        +	mov	16(%rsi),%rbx
        +	lea	24(%rsi),%rsp
        +.Lepilogue_avx:
        +	ret
        +.size	sha1_block_data_order_avx,.-sha1_block_data_order_avx
        +___
        +}
        +$code.=<<___;
        +.align	64
        +K_XX_XX:
        +.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
        +.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
        +.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
        +.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
        +.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap mask
        +___
        +}}}
        +$code.=<<___;
        +.asciz	"SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	64
        +___
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lprologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lprologue
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
        +	jae	.Lcommon_seh_tail
        +
        +	mov	`16*4`(%rax),%rax	# pull saved stack pointer
        +	lea	32(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +
        +	jmp	.Lcommon_seh_tail
        +.size	se_handler,.-se_handler
        +
        +.type	ssse3_handler,\@abi-omnipotent
        +.align	16
        +ssse3_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	mov	8($disp),%rsi		# disp->ImageBase
        +	mov	56($disp),%r11		# disp->HandlerData
        +
        +	mov	0(%r11),%r10d		# HandlerData[0]
        +	lea	(%rsi,%r10),%r10	# prologue label
        +	cmp	%r10,%rbx		# context->Rip<prologue label
        +	jb	.Lcommon_seh_tail
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	mov	4(%r11),%r10d		# HandlerData[1]
        +	lea	(%rsi,%r10),%r10	# epilogue label
        +	cmp	%r10,%rbx		# context->Rip>=epilogue label
        +	jae	.Lcommon_seh_tail
        +
        +	lea	64(%rax),%rsi
        +	lea	512($context),%rdi	# &context.Xmm6
        +	mov	\$10,%ecx
        +	.long	0xa548f3fc		# cld; rep movsq
        +	lea	`24+64+5*16`(%rax),%rax	# adjust stack pointer
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore cotnext->R12
        +
        +.Lcommon_seh_tail:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	ssse3_handler,.-ssse3_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_sha1_block_data_order
        +	.rva	.LSEH_end_sha1_block_data_order
        +	.rva	.LSEH_info_sha1_block_data_order
        +	.rva	.LSEH_begin_sha1_block_data_order_ssse3
        +	.rva	.LSEH_end_sha1_block_data_order_ssse3
        +	.rva	.LSEH_info_sha1_block_data_order_ssse3
        +___
        +$code.=<<___ if ($avx);
        +	.rva	.LSEH_begin_sha1_block_data_order_avx
        +	.rva	.LSEH_end_sha1_block_data_order_avx
        +	.rva	.LSEH_info_sha1_block_data_order_avx
        +___
        +$code.=<<___;
        +.section	.xdata
        +.align	8
        +.LSEH_info_sha1_block_data_order:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +.LSEH_info_sha1_block_data_order_ssse3:
        +	.byte	9,0,0,0
        +	.rva	ssse3_handler
        +	.rva	.Lprologue_ssse3,.Lepilogue_ssse3	# HandlerData[]
        +___
        +$code.=<<___ if ($avx);
        +.LSEH_info_sha1_block_data_order_avx:
        +	.byte	9,0,0,0
        +	.rva	ssse3_handler
        +	.rva	.Lprologue_avx,.Lepilogue_avx		# HandlerData[]
        +___
        +}
        +
        +####################################################################
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha256-586.pl b/vendor/openssl/openssl/crypto/sha/asm/sha256-586.pl
        new file mode 100644
        index 000000000..928ec5312
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha256-586.pl
        @@ -0,0 +1,249 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# SHA256 block transform for x86. September 2007.
        +#
        +# Performance in clock cycles per processed byte (less is better):
        +#
        +#		Pentium	PIII	P4	AMD K8	Core2
        +# gcc		46	36	41	27	26
        +# icc		57	33	38	25	23	
        +# x86 asm	40	30	33	20	18
        +# x86_64 asm(*)	-	-	21	16	16
        +#
        +# (*) x86_64 assembler performance is presented for reference
        +#     purposes.
        +#
        +# Performance improvement over compiler generated code varies from
        +# 10% to 40% [see above]. Not very impressive on some µ-archs, but
        +# it's 5 times smaller and optimizies amount of writes.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
        +
        +$A="eax";
        +$E="edx";
        +$T="ebx";
        +$Aoff=&DWP(0,"esp");
        +$Boff=&DWP(4,"esp");
        +$Coff=&DWP(8,"esp");
        +$Doff=&DWP(12,"esp");
        +$Eoff=&DWP(16,"esp");
        +$Foff=&DWP(20,"esp");
        +$Goff=&DWP(24,"esp");
        +$Hoff=&DWP(28,"esp");
        +$Xoff=&DWP(32,"esp");
        +$K256="ebp";
        +
        +sub BODY_00_15() {
        +    my $in_16_63=shift;
        +
        +	&mov	("ecx",$E);
        +	 &add	($T,"edi")			if ($in_16_63);	# T += sigma1(X[-2])
        +	&ror	("ecx",25-11);
        +	 &mov	("esi",$Foff);
        +	&xor	("ecx",$E);
        +	&ror	("ecx",11-6);
        +	 &mov	(&DWP(4*(8+15),"esp"),$T)	if ($in_16_63);	# save X[0]
        +	&xor	("ecx",$E);
        +	&ror	("ecx",6);	# Sigma1(e)
        +	 &mov	("edi",$Goff);
        +	&add	($T,"ecx");	# T += Sigma1(e)
        +
        +	&xor	("esi","edi");
        +	 &mov	($Eoff,$E);	# modulo-scheduled
        +	 &mov	("ecx",$A);
        +	&and	("esi",$E);
        +	 &mov	($E,$Doff);	# e becomes d, which is e in next iteration
        +	&xor	("esi","edi");	# Ch(e,f,g)
        +	 &mov	("edi",$A);
        +	&add	($T,"esi");	# T += Ch(e,f,g)
        +
        +	&ror	("ecx",22-13);
        +	 &add	($T,$Hoff);	# T += h
        +	&xor	("ecx",$A);
        +	&ror	("ecx",13-2);
        +	 &mov	("esi",$Boff);
        +	&xor	("ecx",$A);
        +	&ror	("ecx",2);	# Sigma0(a)
        +	 &add	($E,$T);	# d += T
        +	 &mov	("edi",$Coff);
        +
        +	&add	($T,"ecx");	# T += Sigma0(a)
        +	 &mov	($Aoff,$A);	# modulo-scheduled
        +
        +	&mov	("ecx",$A);
        +	 &sub	("esp",4);
        +	&or	($A,"esi");	# a becomes h, which is a in next iteration
        +	&and	("ecx","esi");
        +	&and	($A,"edi");
        +	 &mov	("esi",&DWP(0,$K256));
        +	&or	($A,"ecx");	# h=Maj(a,b,c)
        +
        +	&add	($K256,4);
        +	&add	($A,$T);	# h += T
        +	 &mov	($T,&DWP(4*(8+15+16-1),"esp"))	if ($in_16_63);	# preload T
        +	&add	($E,"esi");	# d += K256[i]
        +	&add	($A,"esi");	# h += K256[i]
        +}
        +
        +&function_begin("sha256_block_data_order");
        +	&mov	("esi",wparam(0));	# ctx
        +	&mov	("edi",wparam(1));	# inp
        +	&mov	("eax",wparam(2));	# num
        +	&mov	("ebx","esp");		# saved sp
        +
        +	&call	(&label("pic_point"));	# make it PIC!
        +&set_label("pic_point");
        +	&blindpop($K256);
        +	&lea	($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256));
        +
        +	&sub	("esp",16);
        +	&and	("esp",-64);
        +
        +	&shl	("eax",6);
        +	&add	("eax","edi");
        +	&mov	(&DWP(0,"esp"),"esi");	# ctx
        +	&mov	(&DWP(4,"esp"),"edi");	# inp
        +	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
        +	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
        +
        +&set_label("loop",16);
        +    # copy input block to stack reversing byte and dword order
        +    for($i=0;$i<4;$i++) {
        +	&mov	("eax",&DWP($i*16+0,"edi"));
        +	&mov	("ebx",&DWP($i*16+4,"edi"));
        +	&mov	("ecx",&DWP($i*16+8,"edi"));
        +	&mov	("edx",&DWP($i*16+12,"edi"));
        +	&bswap	("eax");
        +	&bswap	("ebx");
        +	&bswap	("ecx");
        +	&bswap	("edx");
        +	&push	("eax");
        +	&push	("ebx");
        +	&push	("ecx");
        +	&push	("edx");
        +    }
        +	&add	("edi",64);
        +	&sub	("esp",4*8);		# place for A,B,C,D,E,F,G,H
        +	&mov	(&DWP(4*(8+16)+4,"esp"),"edi");
        +
        +	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
        +	&mov	($A,&DWP(0,"esi"));
        +	&mov	("ebx",&DWP(4,"esi"));
        +	&mov	("ecx",&DWP(8,"esi"));
        +	&mov	("edi",&DWP(12,"esi"));
        +	# &mov	($Aoff,$A);
        +	&mov	($Boff,"ebx");
        +	&mov	($Coff,"ecx");
        +	&mov	($Doff,"edi");
        +	&mov	($E,&DWP(16,"esi"));	
        +	&mov	("ebx",&DWP(20,"esi"));
        +	&mov	("ecx",&DWP(24,"esi"));
        +	&mov	("edi",&DWP(28,"esi"));
        +	# &mov	($Eoff,$E);
        +	&mov	($Foff,"ebx");
        +	&mov	($Goff,"ecx");
        +	&mov	($Hoff,"edi");
        +
        +&set_label("00_15",16);
        +	&mov	($T,&DWP(4*(8+15),"esp"));
        +
        +	&BODY_00_15();
        +
        +	&cmp	("esi",0xc19bf174);
        +	&jne	(&label("00_15"));
        +
        +	&mov	($T,&DWP(4*(8+15+16-1),"esp"));	# preloaded in BODY_00_15(1)
        +&set_label("16_63",16);
        +	&mov	("esi",$T);
        +	 &mov	("ecx",&DWP(4*(8+15+16-14),"esp"));
        +	&ror	("esi",18-7);
        +	 &mov	("edi","ecx");
        +	&xor	("esi",$T);
        +	&ror	("esi",7);
        +	&shr	($T,3);
        +
        +	&ror	("edi",19-17);
        +	 &xor	($T,"esi");			# T = sigma0(X[-15])
        +	&xor	("edi","ecx");
        +	&ror	("edi",17);
        +	&shr	("ecx",10);
        +	 &add	($T,&DWP(4*(8+15+16),"esp"));	# T += X[-16]
        +	&xor	("edi","ecx");			# sigma1(X[-2])
        +
        +	 &add	($T,&DWP(4*(8+15+16-9),"esp"));	# T += X[-7]
        +	# &add	($T,"edi");			# T += sigma1(X[-2])
        +	# &mov	(&DWP(4*(8+15),"esp"),$T);	# save X[0]
        +
        +	&BODY_00_15(1);
        +
        +	&cmp	("esi",0xc67178f2);
        +	&jne	(&label("16_63"));
        +
        +	&mov	("esi",&DWP(4*(8+16+64)+0,"esp"));#ctx
        +	# &mov	($A,$Aoff);
        +	&mov	("ebx",$Boff);
        +	&mov	("ecx",$Coff);
        +	&mov	("edi",$Doff);
        +	&add	($A,&DWP(0,"esi"));
        +	&add	("ebx",&DWP(4,"esi"));
        +	&add	("ecx",&DWP(8,"esi"));
        +	&add	("edi",&DWP(12,"esi"));
        +	&mov	(&DWP(0,"esi"),$A);
        +	&mov	(&DWP(4,"esi"),"ebx");
        +	&mov	(&DWP(8,"esi"),"ecx");
        +	&mov	(&DWP(12,"esi"),"edi");
        +	# &mov	($E,$Eoff);
        +	&mov	("eax",$Foff);
        +	&mov	("ebx",$Goff);
        +	&mov	("ecx",$Hoff);
        +	&mov	("edi",&DWP(4*(8+16+64)+4,"esp"));#inp
        +	&add	($E,&DWP(16,"esi"));
        +	&add	("eax",&DWP(20,"esi"));
        +	&add	("ebx",&DWP(24,"esi"));
        +	&add	("ecx",&DWP(28,"esi"));
        +	&mov	(&DWP(16,"esi"),$E);
        +	&mov	(&DWP(20,"esi"),"eax");
        +	&mov	(&DWP(24,"esi"),"ebx");
        +	&mov	(&DWP(28,"esi"),"ecx");
        +
        +	&add	("esp",4*(8+16+64));		# destroy frame
        +	&sub	($K256,4*64);			# rewind K
        +
        +	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
        +	&jb	(&label("loop"));
        +
        +	&mov	("esp",&DWP(12,"esp"));		# restore sp
        +&function_end_A();
        +
        +&set_label("K256",64);	# Yes! I keep it in the code segment!
        +	&data_word(0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5);
        +	&data_word(0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5);
        +	&data_word(0xd807aa98,0x12835b01,0x243185be,0x550c7dc3);
        +	&data_word(0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174);
        +	&data_word(0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc);
        +	&data_word(0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da);
        +	&data_word(0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7);
        +	&data_word(0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967);
        +	&data_word(0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13);
        +	&data_word(0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85);
        +	&data_word(0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3);
        +	&data_word(0xd192e819,0xd6990624,0xf40e3585,0x106aa070);
        +	&data_word(0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5);
        +	&data_word(0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3);
        +	&data_word(0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208);
        +	&data_word(0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2);
        +&function_end_B("sha256_block_data_order");
        +&asciz("SHA256 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha256-armv4.pl b/vendor/openssl/openssl/crypto/sha/asm/sha256-armv4.pl
        new file mode 100644
        index 000000000..9c84e8d93
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha256-armv4.pl
        @@ -0,0 +1,211 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA256 block procedure for ARMv4. May 2007.
        +
        +# Performance is ~2x better than gcc 3.4 generated code and in "abso-
        +# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
        +# byte [on single-issue Xscale PXA250 core].
        +
        +# July 2010.
        +#
        +# Rescheduling for dual-issue pipeline resulted in 22% improvement on
        +# Cortex A8 core and ~20 cycles per processed byte.
        +
        +# February 2011.
        +#
        +# Profiler-assisted and platform-specific optimization resulted in 16%
        +# improvement on Cortex A8 core and ~17 cycles per processed byte.
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$ctx="r0";	$t0="r0";
        +$inp="r1";	$t3="r1";
        +$len="r2";	$t1="r2";
        +$T1="r3";
        +$A="r4";
        +$B="r5";
        +$C="r6";
        +$D="r7";
        +$E="r8";
        +$F="r9";
        +$G="r10";
        +$H="r11";
        +@V=($A,$B,$C,$D,$E,$F,$G,$H);
        +$t2="r12";
        +$Ktbl="r14";
        +
        +@Sigma0=( 2,13,22);
        +@Sigma1=( 6,11,25);
        +@sigma0=( 7,18, 3);
        +@sigma1=(17,19,10);
        +
        +sub BODY_00_15 {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
        +
        +$code.=<<___ if ($i<16);
        +#if __ARM_ARCH__>=7
        +	ldr	$T1,[$inp],#4
        +#else
        +	ldrb	$T1,[$inp,#3]			@ $i
        +	ldrb	$t2,[$inp,#2]
        +	ldrb	$t1,[$inp,#1]
        +	ldrb	$t0,[$inp],#4
        +	orr	$T1,$T1,$t2,lsl#8
        +	orr	$T1,$T1,$t1,lsl#16
        +	orr	$T1,$T1,$t0,lsl#24
        +#endif
        +___
        +$code.=<<___;
        +	mov	$t0,$e,ror#$Sigma1[0]
        +	ldr	$t2,[$Ktbl],#4			@ *K256++
        +	eor	$t0,$t0,$e,ror#$Sigma1[1]
        +	eor	$t1,$f,$g
        +#if $i>=16
        +	add	$T1,$T1,$t3			@ from BODY_16_xx
        +#elif __ARM_ARCH__>=7 && defined(__ARMEL__)
        +	rev	$T1,$T1
        +#endif
        +#if $i==15
        +	str	$inp,[sp,#17*4]			@ leave room for $t3
        +#endif
        +	eor	$t0,$t0,$e,ror#$Sigma1[2]	@ Sigma1(e)
        +	and	$t1,$t1,$e
        +	str	$T1,[sp,#`$i%16`*4]
        +	add	$T1,$T1,$t0
        +	eor	$t1,$t1,$g			@ Ch(e,f,g)
        +	add	$T1,$T1,$h
        +	mov	$h,$a,ror#$Sigma0[0]
        +	add	$T1,$T1,$t1
        +	eor	$h,$h,$a,ror#$Sigma0[1]
        +	add	$T1,$T1,$t2
        +	eor	$h,$h,$a,ror#$Sigma0[2]		@ Sigma0(a)
        +#if $i>=15
        +	ldr	$t3,[sp,#`($i+2)%16`*4]		@ from BODY_16_xx
        +#endif
        +	orr	$t0,$a,$b
        +	and	$t1,$a,$b
        +	and	$t0,$t0,$c
        +	add	$h,$h,$T1
        +	orr	$t0,$t0,$t1			@ Maj(a,b,c)
        +	add	$d,$d,$T1
        +	add	$h,$h,$t0
        +___
        +}
        +
        +sub BODY_16_XX {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
        +
        +$code.=<<___;
        +	@ ldr	$t3,[sp,#`($i+1)%16`*4]		@ $i
        +	ldr	$t2,[sp,#`($i+14)%16`*4]
        +	mov	$t0,$t3,ror#$sigma0[0]
        +	ldr	$T1,[sp,#`($i+0)%16`*4]
        +	eor	$t0,$t0,$t3,ror#$sigma0[1]
        +	ldr	$t1,[sp,#`($i+9)%16`*4]
        +	eor	$t0,$t0,$t3,lsr#$sigma0[2]	@ sigma0(X[i+1])
        +	mov	$t3,$t2,ror#$sigma1[0]
        +	add	$T1,$T1,$t0
        +	eor	$t3,$t3,$t2,ror#$sigma1[1]
        +	add	$T1,$T1,$t1
        +	eor	$t3,$t3,$t2,lsr#$sigma1[2]	@ sigma1(X[i+14])
        +	@ add	$T1,$T1,$t3
        +___
        +	&BODY_00_15(@_);
        +}
        +
        +$code=<<___;
        +#include "arm_arch.h"
        +
        +.text
        +.code	32
        +
        +.type	K256,%object
        +.align	5
        +K256:
        +.word	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +.word	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +.word	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +.word	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +.word	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +.word	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +.word	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +.word	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +.word	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +.word	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +.word	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +.word	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +.word	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +.word	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +.word	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +.word	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        +.size	K256,.-K256
        +
        +.global	sha256_block_data_order
        +.type	sha256_block_data_order,%function
        +sha256_block_data_order:
        +	sub	r3,pc,#8		@ sha256_block_data_order
        +	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
        +	stmdb	sp!,{$ctx,$inp,$len,r4-r11,lr}
        +	ldmia	$ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
        +	sub	$Ktbl,r3,#256		@ K256
        +	sub	sp,sp,#16*4		@ alloca(X[16])
        +.Loop:
        +___
        +for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
        +$code.=".Lrounds_16_xx:\n";
        +for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	and	$t2,$t2,#0xff
        +	cmp	$t2,#0xf2
        +	bne	.Lrounds_16_xx
        +
        +	ldr	$T1,[sp,#16*4]		@ pull ctx
        +	ldr	$t0,[$T1,#0]
        +	ldr	$t1,[$T1,#4]
        +	ldr	$t2,[$T1,#8]
        +	add	$A,$A,$t0
        +	ldr	$t0,[$T1,#12]
        +	add	$B,$B,$t1
        +	ldr	$t1,[$T1,#16]
        +	add	$C,$C,$t2
        +	ldr	$t2,[$T1,#20]
        +	add	$D,$D,$t0
        +	ldr	$t0,[$T1,#24]
        +	add	$E,$E,$t1
        +	ldr	$t1,[$T1,#28]
        +	add	$F,$F,$t2
        +	ldr	$inp,[sp,#17*4]		@ pull inp
        +	ldr	$t2,[sp,#18*4]		@ pull inp+len
        +	add	$G,$G,$t0
        +	add	$H,$H,$t1
        +	stmia	$T1,{$A,$B,$C,$D,$E,$F,$G,$H}
        +	cmp	$inp,$t2
        +	sub	$Ktbl,$Ktbl,#256	@ rewind Ktbl
        +	bne	.Loop
        +
        +	add	sp,sp,#`16+3`*4	@ destroy frame
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r11,pc}
        +#else
        +	ldmia	sp!,{r4-r11,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +.size   sha256_block_data_order,.-sha256_block_data_order
        +.asciz  "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT; # enforce flush
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-586.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-586.pl
        new file mode 100644
        index 000000000..7eab6a5b8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-586.pl
        @@ -0,0 +1,644 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# SHA512 block transform for x86. September 2007.
        +#
        +# Performance in clock cycles per processed byte (less is better):
        +#
        +#		Pentium	PIII	P4	AMD K8	Core2
        +# gcc		100	75	116	54	66
        +# icc		97	77	95	55	57
        +# x86 asm	61	56	82	36	40
        +# SSE2 asm	-	-	38	24	20
        +# x86_64 asm(*)	-	-	30	10.0	10.5
        +#
        +# (*) x86_64 assembler performance is presented for reference
        +#     purposes.
        +#
        +# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
        +# performance improvement over compiler generated code reaches ~60%,
        +# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
        +# to 50%, but it's less important as they are expected to execute SSE2
        +# code-path, which is commonly ~2-3x faster [than compiler generated
        +# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
        +# though it does not use 128-bit operations. The latter means that
        +# SSE2-aware kernel is no longer required to execute the code. Another
        +# difference is that new code optimizes amount of writes, but at the
        +# cost of increased data cache "footprint" by 1/2KB.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
        +
        +$sse2=0;
        +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +&external_label("OPENSSL_ia32cap_P") if ($sse2);
        +
        +$Tlo=&DWP(0,"esp");	$Thi=&DWP(4,"esp");
        +$Alo=&DWP(8,"esp");	$Ahi=&DWP(8+4,"esp");
        +$Blo=&DWP(16,"esp");	$Bhi=&DWP(16+4,"esp");
        +$Clo=&DWP(24,"esp");	$Chi=&DWP(24+4,"esp");
        +$Dlo=&DWP(32,"esp");	$Dhi=&DWP(32+4,"esp");
        +$Elo=&DWP(40,"esp");	$Ehi=&DWP(40+4,"esp");
        +$Flo=&DWP(48,"esp");	$Fhi=&DWP(48+4,"esp");
        +$Glo=&DWP(56,"esp");	$Ghi=&DWP(56+4,"esp");
        +$Hlo=&DWP(64,"esp");	$Hhi=&DWP(64+4,"esp");
        +$K512="ebp";
        +
        +$Asse2=&QWP(0,"esp");
        +$Bsse2=&QWP(8,"esp");
        +$Csse2=&QWP(16,"esp");
        +$Dsse2=&QWP(24,"esp");
        +$Esse2=&QWP(32,"esp");
        +$Fsse2=&QWP(40,"esp");
        +$Gsse2=&QWP(48,"esp");
        +$Hsse2=&QWP(56,"esp");
        +
        +$A="mm0";	# B-D and
        +$E="mm4";	# F-H are commonly loaded to respectively mm1-mm3 and
        +		# mm5-mm7, but it's done on on-demand basis...
        +
        +sub BODY_00_15_sse2 {
        +    my $prefetch=shift;
        +
        +	&movq	("mm5",$Fsse2);			# load f
        +	&movq	("mm6",$Gsse2);			# load g
        +	&movq	("mm7",$Hsse2);			# load h
        +
        +	&movq	("mm1",$E);			# %mm1 is sliding right
        +	&movq	("mm2",$E);			# %mm2 is sliding left
        +	&psrlq	("mm1",14);
        +	&movq	($Esse2,$E);			# modulo-scheduled save e
        +	&psllq	("mm2",23);
        +	&movq	("mm3","mm1");			# %mm3 is T1
        +	&psrlq	("mm1",4);
        +	&pxor	("mm3","mm2");
        +	&psllq	("mm2",23);
        +	&pxor	("mm3","mm1");
        +	&psrlq	("mm1",23);
        +	&pxor	("mm3","mm2");
        +	&psllq	("mm2",4);
        +	&pxor	("mm3","mm1");
        +	&paddq	("mm7",QWP(0,$K512));		# h+=K512[i]
        +	&pxor	("mm3","mm2");			# T1=Sigma1_512(e)
        +
        +	&pxor	("mm5","mm6");			# f^=g
        +	&movq	("mm1",$Bsse2);			# load b
        +	&pand	("mm5",$E);			# f&=e
        +	&movq	("mm2",$Csse2);			# load c
        +	&pxor	("mm5","mm6");			# f^=g
        +	&movq	($E,$Dsse2);			# e = load d
        +	&paddq	("mm3","mm5");			# T1+=Ch(e,f,g)
        +	&movq	(&QWP(0,"esp"),$A);		# modulo-scheduled save a
        +	&paddq	("mm3","mm7");			# T1+=h
        +
        +	&movq	("mm5",$A);			# %mm5 is sliding right
        +	&movq	("mm6",$A);			# %mm6 is sliding left
        +	&paddq	("mm3",&QWP(8*9,"esp"));	# T1+=X[0]
        +	&psrlq	("mm5",28);
        +	&paddq	($E,"mm3");			# e += T1
        +	&psllq	("mm6",25);
        +	&movq	("mm7","mm5");			# %mm7 is T2
        +	&psrlq	("mm5",6);
        +	&pxor	("mm7","mm6");
        +	&psllq	("mm6",5);
        +	&pxor	("mm7","mm5");
        +	&psrlq	("mm5",5);
        +	&pxor	("mm7","mm6");
        +	&psllq	("mm6",6);
        +	&pxor	("mm7","mm5");
        +	&sub	("esp",8);
        +	&pxor	("mm7","mm6");			# T2=Sigma0_512(a)
        +
        +	&movq	("mm5",$A);			# %mm5=a
        +	&por	($A,"mm2");			# a=a|c
        +	&movq	("mm6",&QWP(8*(9+16-14),"esp"))	if ($prefetch);
        +	&pand	("mm5","mm2");			# %mm5=a&c
        +	&pand	($A,"mm1");			# a=(a|c)&b
        +	&movq	("mm2",&QWP(8*(9+16-1),"esp"))	if ($prefetch);
        +	&por	("mm5",$A);			# %mm5=(a&c)|((a|c)&b)
        +	&paddq	("mm7","mm5");			# T2+=Maj(a,b,c)
        +	&movq	($A,"mm3");			# a=T1
        +
        +	&mov	(&LB("edx"),&BP(0,$K512));
        +	&paddq	($A,"mm7");			# a+=T2
        +	&add	($K512,8);
        +}
        +
        +sub BODY_00_15_x86 {
        +	#define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
        +	#	LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
        +	#	HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
        +	&mov	("ecx",$Elo);
        +	&mov	("edx",$Ehi);
        +	&mov	("esi","ecx");
        +
        +	&shr	("ecx",9);	# lo>>9
        +	&mov	("edi","edx");
        +	&shr	("edx",9);	# hi>>9
        +	&mov	("ebx","ecx");
        +	&shl	("esi",14);	# lo<<14
        +	&mov	("eax","edx");
        +	&shl	("edi",14);	# hi<<14
        +	&xor	("ebx","esi");
        +
        +	&shr	("ecx",14-9);	# lo>>14
        +	&xor	("eax","edi");
        +	&shr	("edx",14-9);	# hi>>14
        +	&xor	("eax","ecx");
        +	&shl	("esi",18-14);	# lo<<18
        +	&xor	("ebx","edx");
        +	&shl	("edi",18-14);	# hi<<18
        +	&xor	("ebx","esi");
        +
        +	&shr	("ecx",18-14);	# lo>>18
        +	&xor	("eax","edi");
        +	&shr	("edx",18-14);	# hi>>18
        +	&xor	("eax","ecx");
        +	&shl	("esi",23-18);	# lo<<23
        +	&xor	("ebx","edx");
        +	&shl	("edi",23-18);	# hi<<23
        +	&xor	("eax","esi");
        +	&xor	("ebx","edi");			# T1 = Sigma1(e)
        +
        +	&mov	("ecx",$Flo);
        +	&mov	("edx",$Fhi);
        +	&mov	("esi",$Glo);
        +	&mov	("edi",$Ghi);
        +	 &add	("eax",$Hlo);
        +	 &adc	("ebx",$Hhi);			# T1 += h
        +	&xor	("ecx","esi");
        +	&xor	("edx","edi");
        +	&and	("ecx",$Elo);
        +	&and	("edx",$Ehi);
        +	 &add	("eax",&DWP(8*(9+15)+0,"esp"));
        +	 &adc	("ebx",&DWP(8*(9+15)+4,"esp"));	# T1 += X[0]
        +	&xor	("ecx","esi");
        +	&xor	("edx","edi");			# Ch(e,f,g) = (f^g)&e)^g
        +
        +	&mov	("esi",&DWP(0,$K512));
        +	&mov	("edi",&DWP(4,$K512));		# K[i]
        +	&add	("eax","ecx");
        +	&adc	("ebx","edx");			# T1 += Ch(e,f,g)
        +	&mov	("ecx",$Dlo);
        +	&mov	("edx",$Dhi);
        +	&add	("eax","esi");
        +	&adc	("ebx","edi");			# T1 += K[i]
        +	&mov	($Tlo,"eax");
        +	&mov	($Thi,"ebx");			# put T1 away
        +	&add	("eax","ecx");
        +	&adc	("ebx","edx");			# d += T1
        +
        +	#define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
        +	#	LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
        +	#	HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
        +	&mov	("ecx",$Alo);
        +	&mov	("edx",$Ahi);
        +	&mov	($Dlo,"eax");
        +	&mov	($Dhi,"ebx");
        +	&mov	("esi","ecx");
        +
        +	&shr	("ecx",2);	# lo>>2
        +	&mov	("edi","edx");
        +	&shr	("edx",2);	# hi>>2
        +	&mov	("ebx","ecx");
        +	&shl	("esi",4);	# lo<<4
        +	&mov	("eax","edx");
        +	&shl	("edi",4);	# hi<<4
        +	&xor	("ebx","esi");
        +
        +	&shr	("ecx",7-2);	# lo>>7
        +	&xor	("eax","edi");
        +	&shr	("edx",7-2);	# hi>>7
        +	&xor	("ebx","ecx");
        +	&shl	("esi",25-4);	# lo<<25
        +	&xor	("eax","edx");
        +	&shl	("edi",25-4);	# hi<<25
        +	&xor	("eax","esi");
        +
        +	&shr	("ecx",28-7);	# lo>>28
        +	&xor	("ebx","edi");
        +	&shr	("edx",28-7);	# hi>>28
        +	&xor	("eax","ecx");
        +	&shl	("esi",30-25);	# lo<<30
        +	&xor	("ebx","edx");
        +	&shl	("edi",30-25);	# hi<<30
        +	&xor	("eax","esi");
        +	&xor	("ebx","edi");			# Sigma0(a)
        +
        +	&mov	("ecx",$Alo);
        +	&mov	("edx",$Ahi);
        +	&mov	("esi",$Blo);
        +	&mov	("edi",$Bhi);
        +	&add	("eax",$Tlo);
        +	&adc	("ebx",$Thi);			# T1 = Sigma0(a)+T1
        +	&or	("ecx","esi");
        +	&or	("edx","edi");
        +	&and	("ecx",$Clo);
        +	&and	("edx",$Chi);
        +	&and	("esi",$Alo);
        +	&and	("edi",$Ahi);
        +	&or	("ecx","esi");
        +	&or	("edx","edi");			# Maj(a,b,c) = ((a|b)&c)|(a&b)
        +
        +	&add	("eax","ecx");
        +	&adc	("ebx","edx");			# T1 += Maj(a,b,c)
        +	&mov	($Tlo,"eax");
        +	&mov	($Thi,"ebx");
        +
        +	&mov	(&LB("edx"),&BP(0,$K512));	# pre-fetch LSB of *K
        +	&sub	("esp",8);
        +	&lea	($K512,&DWP(8,$K512));		# K++
        +}
        +
        +
        +&function_begin("sha512_block_data_order");
        +	&mov	("esi",wparam(0));	# ctx
        +	&mov	("edi",wparam(1));	# inp
        +	&mov	("eax",wparam(2));	# num
        +	&mov	("ebx","esp");		# saved sp
        +
        +	&call	(&label("pic_point"));	# make it PIC!
        +&set_label("pic_point");
        +	&blindpop($K512);
        +	&lea	($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
        +
        +	&sub	("esp",16);
        +	&and	("esp",-64);
        +
        +	&shl	("eax",7);
        +	&add	("eax","edi");
        +	&mov	(&DWP(0,"esp"),"esi");	# ctx
        +	&mov	(&DWP(4,"esp"),"edi");	# inp
        +	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
        +	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
        +
        +if ($sse2) {
        +	&picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512"));
        +	&bt	(&DWP(0,"edx"),26);
        +	&jnc	(&label("loop_x86"));
        +
        +	# load ctx->h[0-7]
        +	&movq	($A,&QWP(0,"esi"));
        +	&movq	("mm1",&QWP(8,"esi"));
        +	&movq	("mm2",&QWP(16,"esi"));
        +	&movq	("mm3",&QWP(24,"esi"));
        +	&movq	($E,&QWP(32,"esi"));
        +	&movq	("mm5",&QWP(40,"esi"));
        +	&movq	("mm6",&QWP(48,"esi"));
        +	&movq	("mm7",&QWP(56,"esi"));
        +	&sub	("esp",8*10);
        +
        +&set_label("loop_sse2",16);
        +	# &movq	($Asse2,$A);
        +	&movq	($Bsse2,"mm1");
        +	&movq	($Csse2,"mm2");
        +	&movq	($Dsse2,"mm3");
        +	# &movq	($Esse2,$E);
        +	&movq	($Fsse2,"mm5");
        +	&movq	($Gsse2,"mm6");
        +	&movq	($Hsse2,"mm7");
        +
        +	&mov	("ecx",&DWP(0,"edi"));
        +	&mov	("edx",&DWP(4,"edi"));
        +	&add	("edi",8);
        +	&bswap	("ecx");
        +	&bswap	("edx");
        +	&mov	(&DWP(8*9+4,"esp"),"ecx");
        +	&mov	(&DWP(8*9+0,"esp"),"edx");
        +
        +&set_label("00_14_sse2",16);
        +	&mov	("eax",&DWP(0,"edi"));
        +	&mov	("ebx",&DWP(4,"edi"));
        +	&add	("edi",8);
        +	&bswap	("eax");
        +	&bswap	("ebx");
        +	&mov	(&DWP(8*8+4,"esp"),"eax");
        +	&mov	(&DWP(8*8+0,"esp"),"ebx");
        +
        +	&BODY_00_15_sse2();
        +
        +	&cmp	(&LB("edx"),0x35);
        +	&jne	(&label("00_14_sse2"));
        +
        +	&BODY_00_15_sse2(1);
        +
        +&set_label("16_79_sse2",16);
        +	#&movq	("mm2",&QWP(8*(9+16-1),"esp"));	#prefetched in BODY_00_15 
        +	#&movq	("mm6",&QWP(8*(9+16-14),"esp"));
        +	&movq	("mm1","mm2");
        +
        +	&psrlq	("mm2",1);
        +	&movq	("mm7","mm6");
        +	&psrlq	("mm6",6);
        +	&movq	("mm3","mm2");
        +
        +	&psrlq	("mm2",7-1);
        +	&movq	("mm5","mm6");
        +	&psrlq	("mm6",19-6);
        +	&pxor	("mm3","mm2");
        +
        +	&psrlq	("mm2",8-7);
        +	&pxor	("mm5","mm6");
        +	&psrlq	("mm6",61-19);
        +	&pxor	("mm3","mm2");
        +
        +	&movq	("mm2",&QWP(8*(9+16),"esp"));
        +
        +	&psllq	("mm1",56);
        +	&pxor	("mm5","mm6");
        +	&psllq	("mm7",3);
        +	&pxor	("mm3","mm1");
        +
        +	&paddq	("mm2",&QWP(8*(9+16-9),"esp"));
        +
        +	&psllq	("mm1",63-56);
        +	&pxor	("mm5","mm7");
        +	&psllq	("mm7",45-3);
        +	&pxor	("mm3","mm1");
        +	&pxor	("mm5","mm7");
        +
        +	&paddq	("mm3","mm5");
        +	&paddq	("mm3","mm2");
        +	&movq	(&QWP(8*9,"esp"),"mm3");
        +
        +	&BODY_00_15_sse2(1);
        +
        +	&cmp	(&LB("edx"),0x17);
        +	&jne	(&label("16_79_sse2"));
        +
        +	# &movq	($A,$Asse2);
        +	&movq	("mm1",$Bsse2);
        +	&movq	("mm2",$Csse2);
        +	&movq	("mm3",$Dsse2);
        +	# &movq	($E,$Esse2);
        +	&movq	("mm5",$Fsse2);
        +	&movq	("mm6",$Gsse2);
        +	&movq	("mm7",$Hsse2);
        +
        +	&paddq	($A,&QWP(0,"esi"));
        +	&paddq	("mm1",&QWP(8,"esi"));
        +	&paddq	("mm2",&QWP(16,"esi"));
        +	&paddq	("mm3",&QWP(24,"esi"));
        +	&paddq	($E,&QWP(32,"esi"));
        +	&paddq	("mm5",&QWP(40,"esi"));
        +	&paddq	("mm6",&QWP(48,"esi"));
        +	&paddq	("mm7",&QWP(56,"esi"));
        +
        +	&movq	(&QWP(0,"esi"),$A);
        +	&movq	(&QWP(8,"esi"),"mm1");
        +	&movq	(&QWP(16,"esi"),"mm2");
        +	&movq	(&QWP(24,"esi"),"mm3");
        +	&movq	(&QWP(32,"esi"),$E);
        +	&movq	(&QWP(40,"esi"),"mm5");
        +	&movq	(&QWP(48,"esi"),"mm6");
        +	&movq	(&QWP(56,"esi"),"mm7");
        +
        +	&add	("esp",8*80);			# destroy frame
        +	&sub	($K512,8*80);			# rewind K
        +
        +	&cmp	("edi",&DWP(8*10+8,"esp"));	# are we done yet?
        +	&jb	(&label("loop_sse2"));
        +
        +	&emms	();
        +	&mov	("esp",&DWP(8*10+12,"esp"));	# restore sp
        +&function_end_A();
        +}
        +&set_label("loop_x86",16);
        +    # copy input block to stack reversing byte and qword order
        +    for ($i=0;$i<8;$i++) {
        +	&mov	("eax",&DWP($i*16+0,"edi"));
        +	&mov	("ebx",&DWP($i*16+4,"edi"));
        +	&mov	("ecx",&DWP($i*16+8,"edi"));
        +	&mov	("edx",&DWP($i*16+12,"edi"));
        +	&bswap	("eax");
        +	&bswap	("ebx");
        +	&bswap	("ecx");
        +	&bswap	("edx");
        +	&push	("eax");
        +	&push	("ebx");
        +	&push	("ecx");
        +	&push	("edx");
        +    }
        +	&add	("edi",128);
        +	&sub	("esp",9*8);		# place for T,A,B,C,D,E,F,G,H
        +	&mov	(&DWP(8*(9+16)+4,"esp"),"edi");
        +
        +	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
        +	&lea	("edi",&DWP(8,"esp"));
        +	&mov	("ecx",16);
        +	&data_word(0xA5F3F689);		# rep movsd
        +
        +&set_label("00_15_x86",16);
        +	&BODY_00_15_x86();
        +
        +	&cmp	(&LB("edx"),0x94);
        +	&jne	(&label("00_15_x86"));
        +
        +&set_label("16_79_x86",16);
        +	#define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
        +	#	LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
        +	#	HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
        +	&mov	("ecx",&DWP(8*(9+15+16-1)+0,"esp"));
        +	&mov	("edx",&DWP(8*(9+15+16-1)+4,"esp"));
        +	&mov	("esi","ecx");
        +
        +	&shr	("ecx",1);	# lo>>1
        +	&mov	("edi","edx");
        +	&shr	("edx",1);	# hi>>1
        +	&mov	("eax","ecx");
        +	&shl	("esi",24);	# lo<<24
        +	&mov	("ebx","edx");
        +	&shl	("edi",24);	# hi<<24
        +	&xor	("ebx","esi");
        +
        +	&shr	("ecx",7-1);	# lo>>7
        +	&xor	("eax","edi");
        +	&shr	("edx",7-1);	# hi>>7
        +	&xor	("eax","ecx");
        +	&shl	("esi",31-24);	# lo<<31
        +	&xor	("ebx","edx");
        +	&shl	("edi",25-24);	# hi<<25
        +	&xor	("ebx","esi");
        +
        +	&shr	("ecx",8-7);	# lo>>8
        +	&xor	("eax","edi");
        +	&shr	("edx",8-7);	# hi>>8
        +	&xor	("eax","ecx");
        +	&shl	("edi",31-25);	# hi<<31
        +	&xor	("ebx","edx");
        +	&xor	("eax","edi");			# T1 = sigma0(X[-15])
        +
        +	&mov	(&DWP(0,"esp"),"eax");
        +	&mov	(&DWP(4,"esp"),"ebx");		# put T1 away
        +
        +	#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
        +	#	LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
        +	#	HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
        +	&mov	("ecx",&DWP(8*(9+15+16-14)+0,"esp"));
        +	&mov	("edx",&DWP(8*(9+15+16-14)+4,"esp"));
        +	&mov	("esi","ecx");
        +
        +	&shr	("ecx",6);	# lo>>6
        +	&mov	("edi","edx");
        +	&shr	("edx",6);	# hi>>6
        +	&mov	("eax","ecx");
        +	&shl	("esi",3);	# lo<<3
        +	&mov	("ebx","edx");
        +	&shl	("edi",3);	# hi<<3
        +	&xor	("eax","esi");
        +
        +	&shr	("ecx",19-6);	# lo>>19
        +	&xor	("ebx","edi");
        +	&shr	("edx",19-6);	# hi>>19
        +	&xor	("eax","ecx");
        +	&shl	("esi",13-3);	# lo<<13
        +	&xor	("ebx","edx");
        +	&shl	("edi",13-3);	# hi<<13
        +	&xor	("ebx","esi");
        +
        +	&shr	("ecx",29-19);	# lo>>29
        +	&xor	("eax","edi");
        +	&shr	("edx",29-19);	# hi>>29
        +	&xor	("ebx","ecx");
        +	&shl	("edi",26-13);	# hi<<26
        +	&xor	("eax","edx");
        +	&xor	("eax","edi");			# sigma1(X[-2])
        +
        +	&mov	("ecx",&DWP(8*(9+15+16)+0,"esp"));
        +	&mov	("edx",&DWP(8*(9+15+16)+4,"esp"));
        +	&add	("eax",&DWP(0,"esp"));
        +	&adc	("ebx",&DWP(4,"esp"));		# T1 = sigma1(X[-2])+T1
        +	&mov	("esi",&DWP(8*(9+15+16-9)+0,"esp"));
        +	&mov	("edi",&DWP(8*(9+15+16-9)+4,"esp"));
        +	&add	("eax","ecx");
        +	&adc	("ebx","edx");			# T1 += X[-16]
        +	&add	("eax","esi");
        +	&adc	("ebx","edi");			# T1 += X[-7]
        +	&mov	(&DWP(8*(9+15)+0,"esp"),"eax");
        +	&mov	(&DWP(8*(9+15)+4,"esp"),"ebx");	# save X[0]
        +
        +	&BODY_00_15_x86();
        +
        +	&cmp	(&LB("edx"),0x17);
        +	&jne	(&label("16_79_x86"));
        +
        +	&mov	("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx
        +	&mov	("edi",&DWP(8*(9+16+80)+4,"esp"));# inp
        +    for($i=0;$i<4;$i++) {
        +	&mov	("eax",&DWP($i*16+0,"esi"));
        +	&mov	("ebx",&DWP($i*16+4,"esi"));
        +	&mov	("ecx",&DWP($i*16+8,"esi"));
        +	&mov	("edx",&DWP($i*16+12,"esi"));
        +	&add	("eax",&DWP(8+($i*16)+0,"esp"));
        +	&adc	("ebx",&DWP(8+($i*16)+4,"esp"));
        +	&mov	(&DWP($i*16+0,"esi"),"eax");
        +	&mov	(&DWP($i*16+4,"esi"),"ebx");
        +	&add	("ecx",&DWP(8+($i*16)+8,"esp"));
        +	&adc	("edx",&DWP(8+($i*16)+12,"esp"));
        +	&mov	(&DWP($i*16+8,"esi"),"ecx");
        +	&mov	(&DWP($i*16+12,"esi"),"edx");
        +    }
        +	&add	("esp",8*(9+16+80));		# destroy frame
        +	&sub	($K512,8*80);			# rewind K
        +
        +	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
        +	&jb	(&label("loop_x86"));
        +
        +	&mov	("esp",&DWP(12,"esp"));		# restore sp
        +&function_end_A();
        +
        +&set_label("K512",64);	# Yes! I keep it in the code segment!
        +	&data_word(0xd728ae22,0x428a2f98);	# u64
        +	&data_word(0x23ef65cd,0x71374491);	# u64
        +	&data_word(0xec4d3b2f,0xb5c0fbcf);	# u64
        +	&data_word(0x8189dbbc,0xe9b5dba5);	# u64
        +	&data_word(0xf348b538,0x3956c25b);	# u64
        +	&data_word(0xb605d019,0x59f111f1);	# u64
        +	&data_word(0xaf194f9b,0x923f82a4);	# u64
        +	&data_word(0xda6d8118,0xab1c5ed5);	# u64
        +	&data_word(0xa3030242,0xd807aa98);	# u64
        +	&data_word(0x45706fbe,0x12835b01);	# u64
        +	&data_word(0x4ee4b28c,0x243185be);	# u64
        +	&data_word(0xd5ffb4e2,0x550c7dc3);	# u64
        +	&data_word(0xf27b896f,0x72be5d74);	# u64
        +	&data_word(0x3b1696b1,0x80deb1fe);	# u64
        +	&data_word(0x25c71235,0x9bdc06a7);	# u64
        +	&data_word(0xcf692694,0xc19bf174);	# u64
        +	&data_word(0x9ef14ad2,0xe49b69c1);	# u64
        +	&data_word(0x384f25e3,0xefbe4786);	# u64
        +	&data_word(0x8b8cd5b5,0x0fc19dc6);	# u64
        +	&data_word(0x77ac9c65,0x240ca1cc);	# u64
        +	&data_word(0x592b0275,0x2de92c6f);	# u64
        +	&data_word(0x6ea6e483,0x4a7484aa);	# u64
        +	&data_word(0xbd41fbd4,0x5cb0a9dc);	# u64
        +	&data_word(0x831153b5,0x76f988da);	# u64
        +	&data_word(0xee66dfab,0x983e5152);	# u64
        +	&data_word(0x2db43210,0xa831c66d);	# u64
        +	&data_word(0x98fb213f,0xb00327c8);	# u64
        +	&data_word(0xbeef0ee4,0xbf597fc7);	# u64
        +	&data_word(0x3da88fc2,0xc6e00bf3);	# u64
        +	&data_word(0x930aa725,0xd5a79147);	# u64
        +	&data_word(0xe003826f,0x06ca6351);	# u64
        +	&data_word(0x0a0e6e70,0x14292967);	# u64
        +	&data_word(0x46d22ffc,0x27b70a85);	# u64
        +	&data_word(0x5c26c926,0x2e1b2138);	# u64
        +	&data_word(0x5ac42aed,0x4d2c6dfc);	# u64
        +	&data_word(0x9d95b3df,0x53380d13);	# u64
        +	&data_word(0x8baf63de,0x650a7354);	# u64
        +	&data_word(0x3c77b2a8,0x766a0abb);	# u64
        +	&data_word(0x47edaee6,0x81c2c92e);	# u64
        +	&data_word(0x1482353b,0x92722c85);	# u64
        +	&data_word(0x4cf10364,0xa2bfe8a1);	# u64
        +	&data_word(0xbc423001,0xa81a664b);	# u64
        +	&data_word(0xd0f89791,0xc24b8b70);	# u64
        +	&data_word(0x0654be30,0xc76c51a3);	# u64
        +	&data_word(0xd6ef5218,0xd192e819);	# u64
        +	&data_word(0x5565a910,0xd6990624);	# u64
        +	&data_word(0x5771202a,0xf40e3585);	# u64
        +	&data_word(0x32bbd1b8,0x106aa070);	# u64
        +	&data_word(0xb8d2d0c8,0x19a4c116);	# u64
        +	&data_word(0x5141ab53,0x1e376c08);	# u64
        +	&data_word(0xdf8eeb99,0x2748774c);	# u64
        +	&data_word(0xe19b48a8,0x34b0bcb5);	# u64
        +	&data_word(0xc5c95a63,0x391c0cb3);	# u64
        +	&data_word(0xe3418acb,0x4ed8aa4a);	# u64
        +	&data_word(0x7763e373,0x5b9cca4f);	# u64
        +	&data_word(0xd6b2b8a3,0x682e6ff3);	# u64
        +	&data_word(0x5defb2fc,0x748f82ee);	# u64
        +	&data_word(0x43172f60,0x78a5636f);	# u64
        +	&data_word(0xa1f0ab72,0x84c87814);	# u64
        +	&data_word(0x1a6439ec,0x8cc70208);	# u64
        +	&data_word(0x23631e28,0x90befffa);	# u64
        +	&data_word(0xde82bde9,0xa4506ceb);	# u64
        +	&data_word(0xb2c67915,0xbef9a3f7);	# u64
        +	&data_word(0xe372532b,0xc67178f2);	# u64
        +	&data_word(0xea26619c,0xca273ece);	# u64
        +	&data_word(0x21c0c207,0xd186b8c7);	# u64
        +	&data_word(0xcde0eb1e,0xeada7dd6);	# u64
        +	&data_word(0xee6ed178,0xf57d4f7f);	# u64
        +	&data_word(0x72176fba,0x06f067aa);	# u64
        +	&data_word(0xa2c898a6,0x0a637dc5);	# u64
        +	&data_word(0xbef90dae,0x113f9804);	# u64
        +	&data_word(0x131c471b,0x1b710b35);	# u64
        +	&data_word(0x23047d84,0x28db77f5);	# u64
        +	&data_word(0x40c72493,0x32caab7b);	# u64
        +	&data_word(0x15c9bebc,0x3c9ebe0a);	# u64
        +	&data_word(0x9c100d4c,0x431d67c4);	# u64
        +	&data_word(0xcb3e42b6,0x4cc5d4be);	# u64
        +	&data_word(0xfc657e2a,0x597f299c);	# u64
        +	&data_word(0x3ad6faec,0x5fcb6fab);	# u64
        +	&data_word(0x4a475817,0x6c44198c);	# u64
        +&function_end_B("sha512_block_data_order");
        +&asciz("SHA512 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-armv4.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-armv4.pl
        new file mode 100644
        index 000000000..7faf37b14
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-armv4.pl
        @@ -0,0 +1,582 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA512 block procedure for ARMv4. September 2007.
        +
        +# This code is ~4.5 (four and a half) times faster than code generated
        +# by gcc 3.4 and it spends ~72 clock cycles per byte [on single-issue
        +# Xscale PXA250 core].
        +#
        +# July 2010.
        +#
        +# Rescheduling for dual-issue pipeline resulted in 6% improvement on
        +# Cortex A8 core and ~40 cycles per processed byte.
        +
        +# February 2011.
        +#
        +# Profiler-assisted and platform-specific optimization resulted in 7%
        +# improvement on Coxtex A8 core and ~38 cycles per byte.
        +
        +# March 2011.
        +#
        +# Add NEON implementation. On Cortex A8 it was measured to process
        +# one byte in 25.5 cycles or 47% faster than integer-only code.
        +
        +# Byte order [in]dependence. =========================================
        +#
        +# Originally caller was expected to maintain specific *dword* order in
        +# h[0-7], namely with most significant dword at *lower* address, which
        +# was reflected in below two parameters as 0 and 4. Now caller is
        +# expected to maintain native byte order for whole 64-bit values.
        +$hi="HI";
        +$lo="LO";
        +# ====================================================================
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +$ctx="r0";	# parameter block
        +$inp="r1";
        +$len="r2";
        +
        +$Tlo="r3";
        +$Thi="r4";
        +$Alo="r5";
        +$Ahi="r6";
        +$Elo="r7";
        +$Ehi="r8";
        +$t0="r9";
        +$t1="r10";
        +$t2="r11";
        +$t3="r12";
        +############	r13 is stack pointer
        +$Ktbl="r14";
        +############	r15 is program counter
        +
        +$Aoff=8*0;
        +$Boff=8*1;
        +$Coff=8*2;
        +$Doff=8*3;
        +$Eoff=8*4;
        +$Foff=8*5;
        +$Goff=8*6;
        +$Hoff=8*7;
        +$Xoff=8*8;
        +
        +sub BODY_00_15() {
        +my $magic = shift;
        +$code.=<<___;
        +	@ Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
        +	@ LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
        +	@ HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
        +	mov	$t0,$Elo,lsr#14
        +	str	$Tlo,[sp,#$Xoff+0]
        +	mov	$t1,$Ehi,lsr#14
        +	str	$Thi,[sp,#$Xoff+4]
        +	eor	$t0,$t0,$Ehi,lsl#18
        +	ldr	$t2,[sp,#$Hoff+0]	@ h.lo
        +	eor	$t1,$t1,$Elo,lsl#18
        +	ldr	$t3,[sp,#$Hoff+4]	@ h.hi
        +	eor	$t0,$t0,$Elo,lsr#18
        +	eor	$t1,$t1,$Ehi,lsr#18
        +	eor	$t0,$t0,$Ehi,lsl#14
        +	eor	$t1,$t1,$Elo,lsl#14
        +	eor	$t0,$t0,$Ehi,lsr#9
        +	eor	$t1,$t1,$Elo,lsr#9
        +	eor	$t0,$t0,$Elo,lsl#23
        +	eor	$t1,$t1,$Ehi,lsl#23	@ Sigma1(e)
        +	adds	$Tlo,$Tlo,$t0
        +	ldr	$t0,[sp,#$Foff+0]	@ f.lo
        +	adc	$Thi,$Thi,$t1		@ T += Sigma1(e)
        +	ldr	$t1,[sp,#$Foff+4]	@ f.hi
        +	adds	$Tlo,$Tlo,$t2
        +	ldr	$t2,[sp,#$Goff+0]	@ g.lo
        +	adc	$Thi,$Thi,$t3		@ T += h
        +	ldr	$t3,[sp,#$Goff+4]	@ g.hi
        +
        +	eor	$t0,$t0,$t2
        +	str	$Elo,[sp,#$Eoff+0]
        +	eor	$t1,$t1,$t3
        +	str	$Ehi,[sp,#$Eoff+4]
        +	and	$t0,$t0,$Elo
        +	str	$Alo,[sp,#$Aoff+0]
        +	and	$t1,$t1,$Ehi
        +	str	$Ahi,[sp,#$Aoff+4]
        +	eor	$t0,$t0,$t2
        +	ldr	$t2,[$Ktbl,#$lo]	@ K[i].lo
        +	eor	$t1,$t1,$t3		@ Ch(e,f,g)
        +	ldr	$t3,[$Ktbl,#$hi]	@ K[i].hi
        +
        +	adds	$Tlo,$Tlo,$t0
        +	ldr	$Elo,[sp,#$Doff+0]	@ d.lo
        +	adc	$Thi,$Thi,$t1		@ T += Ch(e,f,g)
        +	ldr	$Ehi,[sp,#$Doff+4]	@ d.hi
        +	adds	$Tlo,$Tlo,$t2
        +	and	$t0,$t2,#0xff
        +	adc	$Thi,$Thi,$t3		@ T += K[i]
        +	adds	$Elo,$Elo,$Tlo
        +	ldr	$t2,[sp,#$Boff+0]	@ b.lo
        +	adc	$Ehi,$Ehi,$Thi		@ d += T
        +	teq	$t0,#$magic
        +
        +	ldr	$t3,[sp,#$Coff+0]	@ c.lo
        +	orreq	$Ktbl,$Ktbl,#1
        +	@ Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
        +	@ LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
        +	@ HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
        +	mov	$t0,$Alo,lsr#28
        +	mov	$t1,$Ahi,lsr#28
        +	eor	$t0,$t0,$Ahi,lsl#4
        +	eor	$t1,$t1,$Alo,lsl#4
        +	eor	$t0,$t0,$Ahi,lsr#2
        +	eor	$t1,$t1,$Alo,lsr#2
        +	eor	$t0,$t0,$Alo,lsl#30
        +	eor	$t1,$t1,$Ahi,lsl#30
        +	eor	$t0,$t0,$Ahi,lsr#7
        +	eor	$t1,$t1,$Alo,lsr#7
        +	eor	$t0,$t0,$Alo,lsl#25
        +	eor	$t1,$t1,$Ahi,lsl#25	@ Sigma0(a)
        +	adds	$Tlo,$Tlo,$t0
        +	and	$t0,$Alo,$t2
        +	adc	$Thi,$Thi,$t1		@ T += Sigma0(a)
        +
        +	ldr	$t1,[sp,#$Boff+4]	@ b.hi
        +	orr	$Alo,$Alo,$t2
        +	ldr	$t2,[sp,#$Coff+4]	@ c.hi
        +	and	$Alo,$Alo,$t3
        +	and	$t3,$Ahi,$t1
        +	orr	$Ahi,$Ahi,$t1
        +	orr	$Alo,$Alo,$t0		@ Maj(a,b,c).lo
        +	and	$Ahi,$Ahi,$t2
        +	adds	$Alo,$Alo,$Tlo
        +	orr	$Ahi,$Ahi,$t3		@ Maj(a,b,c).hi
        +	sub	sp,sp,#8
        +	adc	$Ahi,$Ahi,$Thi		@ h += T
        +	tst	$Ktbl,#1
        +	add	$Ktbl,$Ktbl,#8
        +___
        +}
        +$code=<<___;
        +#include "arm_arch.h"
        +#ifdef __ARMEL__
        +# define LO 0
        +# define HI 4
        +# define WORD64(hi0,lo0,hi1,lo1)	.word	lo0,hi0, lo1,hi1
        +#else
        +# define HI 0
        +# define LO 4
        +# define WORD64(hi0,lo0,hi1,lo1)	.word	hi0,lo0, hi1,lo1
        +#endif
        +
        +.text
        +.code	32
        +.type	K512,%object
        +.align	5
        +K512:
        +WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd)
        +WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc)
        +WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019)
        +WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118)
        +WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe)
        +WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2)
        +WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1)
        +WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694)
        +WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3)
        +WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65)
        +WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483)
        +WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5)
        +WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210)
        +WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4)
        +WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725)
        +WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70)
        +WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926)
        +WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df)
        +WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8)
        +WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b)
        +WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001)
        +WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30)
        +WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910)
        +WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8)
        +WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53)
        +WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8)
        +WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb)
        +WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3)
        +WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60)
        +WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec)
        +WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9)
        +WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b)
        +WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207)
        +WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178)
        +WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6)
        +WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b)
        +WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493)
        +WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c)
        +WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
        +WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
        +.size	K512,.-K512
        +.LOPENSSL_armcap:
        +.word	OPENSSL_armcap_P-sha512_block_data_order
        +.skip	32-4
        +
        +.global	sha512_block_data_order
        +.type	sha512_block_data_order,%function
        +sha512_block_data_order:
        +	sub	r3,pc,#8		@ sha512_block_data_order
        +	add	$len,$inp,$len,lsl#7	@ len to point at the end of inp
        +#if __ARM_ARCH__>=7
        +	ldr	r12,.LOPENSSL_armcap
        +	ldr	r12,[r3,r12]		@ OPENSSL_armcap_P
        +	tst	r12,#1
        +	bne	.LNEON
        +#endif
        +	stmdb	sp!,{r4-r12,lr}
        +	sub	$Ktbl,r3,#672		@ K512
        +	sub	sp,sp,#9*8
        +
        +	ldr	$Elo,[$ctx,#$Eoff+$lo]
        +	ldr	$Ehi,[$ctx,#$Eoff+$hi]
        +	ldr	$t0, [$ctx,#$Goff+$lo]
        +	ldr	$t1, [$ctx,#$Goff+$hi]
        +	ldr	$t2, [$ctx,#$Hoff+$lo]
        +	ldr	$t3, [$ctx,#$Hoff+$hi]
        +.Loop:
        +	str	$t0, [sp,#$Goff+0]
        +	str	$t1, [sp,#$Goff+4]
        +	str	$t2, [sp,#$Hoff+0]
        +	str	$t3, [sp,#$Hoff+4]
        +	ldr	$Alo,[$ctx,#$Aoff+$lo]
        +	ldr	$Ahi,[$ctx,#$Aoff+$hi]
        +	ldr	$Tlo,[$ctx,#$Boff+$lo]
        +	ldr	$Thi,[$ctx,#$Boff+$hi]
        +	ldr	$t0, [$ctx,#$Coff+$lo]
        +	ldr	$t1, [$ctx,#$Coff+$hi]
        +	ldr	$t2, [$ctx,#$Doff+$lo]
        +	ldr	$t3, [$ctx,#$Doff+$hi]
        +	str	$Tlo,[sp,#$Boff+0]
        +	str	$Thi,[sp,#$Boff+4]
        +	str	$t0, [sp,#$Coff+0]
        +	str	$t1, [sp,#$Coff+4]
        +	str	$t2, [sp,#$Doff+0]
        +	str	$t3, [sp,#$Doff+4]
        +	ldr	$Tlo,[$ctx,#$Foff+$lo]
        +	ldr	$Thi,[$ctx,#$Foff+$hi]
        +	str	$Tlo,[sp,#$Foff+0]
        +	str	$Thi,[sp,#$Foff+4]
        +
        +.L00_15:
        +#if __ARM_ARCH__<7
        +	ldrb	$Tlo,[$inp,#7]
        +	ldrb	$t0, [$inp,#6]
        +	ldrb	$t1, [$inp,#5]
        +	ldrb	$t2, [$inp,#4]
        +	ldrb	$Thi,[$inp,#3]
        +	ldrb	$t3, [$inp,#2]
        +	orr	$Tlo,$Tlo,$t0,lsl#8
        +	ldrb	$t0, [$inp,#1]
        +	orr	$Tlo,$Tlo,$t1,lsl#16
        +	ldrb	$t1, [$inp],#8
        +	orr	$Tlo,$Tlo,$t2,lsl#24
        +	orr	$Thi,$Thi,$t3,lsl#8
        +	orr	$Thi,$Thi,$t0,lsl#16
        +	orr	$Thi,$Thi,$t1,lsl#24
        +#else
        +	ldr	$Tlo,[$inp,#4]
        +	ldr	$Thi,[$inp],#8
        +#ifdef __ARMEL__
        +	rev	$Tlo,$Tlo
        +	rev	$Thi,$Thi
        +#endif
        +#endif
        +___
        +	&BODY_00_15(0x94);
        +$code.=<<___;
        +	tst	$Ktbl,#1
        +	beq	.L00_15
        +	ldr	$t0,[sp,#`$Xoff+8*(16-1)`+0]
        +	ldr	$t1,[sp,#`$Xoff+8*(16-1)`+4]
        +	bic	$Ktbl,$Ktbl,#1
        +.L16_79:
        +	@ sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
        +	@ LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
        +	@ HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
        +	mov	$Tlo,$t0,lsr#1
        +	ldr	$t2,[sp,#`$Xoff+8*(16-14)`+0]
        +	mov	$Thi,$t1,lsr#1
        +	ldr	$t3,[sp,#`$Xoff+8*(16-14)`+4]
        +	eor	$Tlo,$Tlo,$t1,lsl#31
        +	eor	$Thi,$Thi,$t0,lsl#31
        +	eor	$Tlo,$Tlo,$t0,lsr#8
        +	eor	$Thi,$Thi,$t1,lsr#8
        +	eor	$Tlo,$Tlo,$t1,lsl#24
        +	eor	$Thi,$Thi,$t0,lsl#24
        +	eor	$Tlo,$Tlo,$t0,lsr#7
        +	eor	$Thi,$Thi,$t1,lsr#7
        +	eor	$Tlo,$Tlo,$t1,lsl#25
        +
        +	@ sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
        +	@ LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
        +	@ HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
        +	mov	$t0,$t2,lsr#19
        +	mov	$t1,$t3,lsr#19
        +	eor	$t0,$t0,$t3,lsl#13
        +	eor	$t1,$t1,$t2,lsl#13
        +	eor	$t0,$t0,$t3,lsr#29
        +	eor	$t1,$t1,$t2,lsr#29
        +	eor	$t0,$t0,$t2,lsl#3
        +	eor	$t1,$t1,$t3,lsl#3
        +	eor	$t0,$t0,$t2,lsr#6
        +	eor	$t1,$t1,$t3,lsr#6
        +	ldr	$t2,[sp,#`$Xoff+8*(16-9)`+0]
        +	eor	$t0,$t0,$t3,lsl#26
        +
        +	ldr	$t3,[sp,#`$Xoff+8*(16-9)`+4]
        +	adds	$Tlo,$Tlo,$t0
        +	ldr	$t0,[sp,#`$Xoff+8*16`+0]
        +	adc	$Thi,$Thi,$t1
        +
        +	ldr	$t1,[sp,#`$Xoff+8*16`+4]
        +	adds	$Tlo,$Tlo,$t2
        +	adc	$Thi,$Thi,$t3
        +	adds	$Tlo,$Tlo,$t0
        +	adc	$Thi,$Thi,$t1
        +___
        +	&BODY_00_15(0x17);
        +$code.=<<___;
        +	ldreq	$t0,[sp,#`$Xoff+8*(16-1)`+0]
        +	ldreq	$t1,[sp,#`$Xoff+8*(16-1)`+4]
        +	beq	.L16_79
        +	bic	$Ktbl,$Ktbl,#1
        +
        +	ldr	$Tlo,[sp,#$Boff+0]
        +	ldr	$Thi,[sp,#$Boff+4]
        +	ldr	$t0, [$ctx,#$Aoff+$lo]
        +	ldr	$t1, [$ctx,#$Aoff+$hi]
        +	ldr	$t2, [$ctx,#$Boff+$lo]
        +	ldr	$t3, [$ctx,#$Boff+$hi]
        +	adds	$t0,$Alo,$t0
        +	str	$t0, [$ctx,#$Aoff+$lo]
        +	adc	$t1,$Ahi,$t1
        +	str	$t1, [$ctx,#$Aoff+$hi]
        +	adds	$t2,$Tlo,$t2
        +	str	$t2, [$ctx,#$Boff+$lo]
        +	adc	$t3,$Thi,$t3
        +	str	$t3, [$ctx,#$Boff+$hi]
        +
        +	ldr	$Alo,[sp,#$Coff+0]
        +	ldr	$Ahi,[sp,#$Coff+4]
        +	ldr	$Tlo,[sp,#$Doff+0]
        +	ldr	$Thi,[sp,#$Doff+4]
        +	ldr	$t0, [$ctx,#$Coff+$lo]
        +	ldr	$t1, [$ctx,#$Coff+$hi]
        +	ldr	$t2, [$ctx,#$Doff+$lo]
        +	ldr	$t3, [$ctx,#$Doff+$hi]
        +	adds	$t0,$Alo,$t0
        +	str	$t0, [$ctx,#$Coff+$lo]
        +	adc	$t1,$Ahi,$t1
        +	str	$t1, [$ctx,#$Coff+$hi]
        +	adds	$t2,$Tlo,$t2
        +	str	$t2, [$ctx,#$Doff+$lo]
        +	adc	$t3,$Thi,$t3
        +	str	$t3, [$ctx,#$Doff+$hi]
        +
        +	ldr	$Tlo,[sp,#$Foff+0]
        +	ldr	$Thi,[sp,#$Foff+4]
        +	ldr	$t0, [$ctx,#$Eoff+$lo]
        +	ldr	$t1, [$ctx,#$Eoff+$hi]
        +	ldr	$t2, [$ctx,#$Foff+$lo]
        +	ldr	$t3, [$ctx,#$Foff+$hi]
        +	adds	$Elo,$Elo,$t0
        +	str	$Elo,[$ctx,#$Eoff+$lo]
        +	adc	$Ehi,$Ehi,$t1
        +	str	$Ehi,[$ctx,#$Eoff+$hi]
        +	adds	$t2,$Tlo,$t2
        +	str	$t2, [$ctx,#$Foff+$lo]
        +	adc	$t3,$Thi,$t3
        +	str	$t3, [$ctx,#$Foff+$hi]
        +
        +	ldr	$Alo,[sp,#$Goff+0]
        +	ldr	$Ahi,[sp,#$Goff+4]
        +	ldr	$Tlo,[sp,#$Hoff+0]
        +	ldr	$Thi,[sp,#$Hoff+4]
        +	ldr	$t0, [$ctx,#$Goff+$lo]
        +	ldr	$t1, [$ctx,#$Goff+$hi]
        +	ldr	$t2, [$ctx,#$Hoff+$lo]
        +	ldr	$t3, [$ctx,#$Hoff+$hi]
        +	adds	$t0,$Alo,$t0
        +	str	$t0, [$ctx,#$Goff+$lo]
        +	adc	$t1,$Ahi,$t1
        +	str	$t1, [$ctx,#$Goff+$hi]
        +	adds	$t2,$Tlo,$t2
        +	str	$t2, [$ctx,#$Hoff+$lo]
        +	adc	$t3,$Thi,$t3
        +	str	$t3, [$ctx,#$Hoff+$hi]
        +
        +	add	sp,sp,#640
        +	sub	$Ktbl,$Ktbl,#640
        +
        +	teq	$inp,$len
        +	bne	.Loop
        +
        +	add	sp,sp,#8*9		@ destroy frame
        +#if __ARM_ARCH__>=5
        +	ldmia	sp!,{r4-r12,pc}
        +#else
        +	ldmia	sp!,{r4-r12,lr}
        +	tst	lr,#1
        +	moveq	pc,lr			@ be binary compatible with V4, yet
        +	bx	lr			@ interoperable with Thumb ISA:-)
        +#endif
        +___
        +
        +{
        +my @Sigma0=(28,34,39);
        +my @Sigma1=(14,18,41);
        +my @sigma0=(1, 8, 7);
        +my @sigma1=(19,61,6);
        +
        +my $Ktbl="r3";
        +my $cnt="r12";	# volatile register known as ip, intra-procedure-call scratch
        +
        +my @X=map("d$_",(0..15));
        +my @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("d$_",(16..23));
        +
        +sub NEON_00_15() {
        +my $i=shift;
        +my ($a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +my ($t0,$t1,$t2,$T1,$K,$Ch,$Maj)=map("d$_",(24..31));	# temps
        +
        +$code.=<<___ if ($i<16 || $i&1);
        +	vshr.u64	$t0,$e,#@Sigma1[0]	@ $i
        +#if $i<16
        +	vld1.64		{@X[$i%16]},[$inp]!	@ handles unaligned
        +#endif
        +	vshr.u64	$t1,$e,#@Sigma1[1]
        +	vshr.u64	$t2,$e,#@Sigma1[2]
        +___
        +$code.=<<___;
        +	vld1.64		{$K},[$Ktbl,:64]!	@ K[i++]
        +	vsli.64		$t0,$e,#`64-@Sigma1[0]`
        +	vsli.64		$t1,$e,#`64-@Sigma1[1]`
        +	vsli.64		$t2,$e,#`64-@Sigma1[2]`
        +#if $i<16 && defined(__ARMEL__)
        +	vrev64.8	@X[$i],@X[$i]
        +#endif
        +	vadd.i64	$T1,$K,$h
        +	veor		$Ch,$f,$g
        +	veor		$t0,$t1
        +	vand		$Ch,$e
        +	veor		$t0,$t2			@ Sigma1(e)
        +	veor		$Ch,$g			@ Ch(e,f,g)
        +	vadd.i64	$T1,$t0
        +	vshr.u64	$t0,$a,#@Sigma0[0]
        +	vadd.i64	$T1,$Ch
        +	vshr.u64	$t1,$a,#@Sigma0[1]
        +	vshr.u64	$t2,$a,#@Sigma0[2]
        +	vsli.64		$t0,$a,#`64-@Sigma0[0]`
        +	vsli.64		$t1,$a,#`64-@Sigma0[1]`
        +	vsli.64		$t2,$a,#`64-@Sigma0[2]`
        +	vadd.i64	$T1,@X[$i%16]
        +	vorr		$Maj,$a,$c
        +	vand		$Ch,$a,$c
        +	veor		$h,$t0,$t1
        +	vand		$Maj,$b
        +	veor		$h,$t2			@ Sigma0(a)
        +	vorr		$Maj,$Ch		@ Maj(a,b,c)
        +	vadd.i64	$h,$T1
        +	vadd.i64	$d,$T1
        +	vadd.i64	$h,$Maj
        +___
        +}
        +
        +sub NEON_16_79() {
        +my $i=shift;
        +
        +if ($i&1)	{ &NEON_00_15($i,@_); return; }
        +
        +# 2x-vectorized, therefore runs every 2nd round
        +my @X=map("q$_",(0..7));			# view @X as 128-bit vector
        +my ($t0,$t1,$s0,$s1) = map("q$_",(12..15));	# temps
        +my ($d0,$d1,$d2) = map("d$_",(24..26));		# temps from NEON_00_15
        +my $e=@_[4];					# $e from NEON_00_15
        +$i /= 2;
        +$code.=<<___;
        +	vshr.u64	$t0,@X[($i+7)%8],#@sigma1[0]
        +	vshr.u64	$t1,@X[($i+7)%8],#@sigma1[1]
        +	vshr.u64	$s1,@X[($i+7)%8],#@sigma1[2]
        +	vsli.64		$t0,@X[($i+7)%8],#`64-@sigma1[0]`
        +	vext.8		$s0,@X[$i%8],@X[($i+1)%8],#8	@ X[i+1]
        +	vsli.64		$t1,@X[($i+7)%8],#`64-@sigma1[1]`
        +	veor		$s1,$t0
        +	vshr.u64	$t0,$s0,#@sigma0[0]
        +	veor		$s1,$t1				@ sigma1(X[i+14])
        +	vshr.u64	$t1,$s0,#@sigma0[1]
        +	vadd.i64	@X[$i%8],$s1
        +	vshr.u64	$s1,$s0,#@sigma0[2]
        +	vsli.64		$t0,$s0,#`64-@sigma0[0]`
        +	vsli.64		$t1,$s0,#`64-@sigma0[1]`
        +	vext.8		$s0,@X[($i+4)%8],@X[($i+5)%8],#8	@ X[i+9]
        +	veor		$s1,$t0
        +	vshr.u64	$d0,$e,#@Sigma1[0]		@ from NEON_00_15
        +	vadd.i64	@X[$i%8],$s0
        +	vshr.u64	$d1,$e,#@Sigma1[1]		@ from NEON_00_15
        +	veor		$s1,$t1				@ sigma0(X[i+1])
        +	vshr.u64	$d2,$e,#@Sigma1[2]		@ from NEON_00_15
        +	vadd.i64	@X[$i%8],$s1
        +___
        +	&NEON_00_15(2*$i,@_);
        +}
        +
        +$code.=<<___;
        +#if __ARM_ARCH__>=7
        +.fpu	neon
        +
        +.align	4
        +.LNEON:
        +	dmb				@ errata #451034 on early Cortex A8
        +	vstmdb	sp!,{d8-d15}		@ ABI specification says so
        +	sub	$Ktbl,r3,#672		@ K512
        +	vldmia	$ctx,{$A-$H}		@ load context
        +.Loop_neon:
        +___
        +for($i=0;$i<16;$i++)	{ &NEON_00_15($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	mov		$cnt,#4
        +.L16_79_neon:
        +	subs		$cnt,#1
        +___
        +for(;$i<32;$i++)	{ &NEON_16_79($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	bne		.L16_79_neon
        +
        +	vldmia		$ctx,{d24-d31}	@ load context to temp
        +	vadd.i64	q8,q12		@ vectorized accumulate
        +	vadd.i64	q9,q13
        +	vadd.i64	q10,q14
        +	vadd.i64	q11,q15
        +	vstmia		$ctx,{$A-$H}	@ save context
        +	teq		$inp,$len
        +	sub		$Ktbl,#640	@ rewind K512
        +	bne		.Loop_neon
        +
        +	vldmia	sp!,{d8-d15}		@ epilogue
        +	bx	lr
        +#endif
        +___
        +}
        +$code.=<<___;
        +.size	sha512_block_data_order,.-sha512_block_data_order
        +.asciz	"SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	2
        +.comm	OPENSSL_armcap_P,4,4
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
        +print $code;
        +close STDOUT; # enforce flush
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-ia64.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-ia64.pl
        new file mode 100644
        index 000000000..1c6ce5652
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-ia64.pl
        @@ -0,0 +1,672 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +#
        +# SHA256/512_Transform for Itanium.
        +#
        +# sha512_block runs in 1003 cycles on Itanium 2, which is almost 50%
        +# faster than gcc and >60%(!) faster than code generated by HP-UX
        +# compiler (yes, HP-UX is generating slower code, because unlike gcc,
        +# it failed to deploy "shift right pair," 'shrp' instruction, which
        +# substitutes for 64-bit rotate).
        +#
        +# 924 cycles long sha256_block outperforms gcc by over factor of 2(!)
        +# and HP-UX compiler - by >40% (yes, gcc won sha512_block, but lost
        +# this one big time). Note that "formally" 924 is about 100 cycles
        +# too much. I mean it's 64 32-bit rounds vs. 80 virtually identical
        +# 64-bit ones and 1003*64/80 gives 802. Extra cycles, 2 per round,
        +# are spent on extra work to provide for 32-bit rotations. 32-bit
        +# rotations are still handled by 'shrp' instruction and for this
        +# reason lower 32 bits are deposited to upper half of 64-bit register
        +# prior 'shrp' issue. And in order to minimize the amount of such
        +# operations, X[16] values are *maintained* with copies of lower
        +# halves in upper halves, which is why you'll spot such instructions
        +# as custom 'mux2', "parallel 32-bit add," 'padd4' and "parallel
        +# 32-bit unsigned right shift," 'pshr4.u' instructions here.
        +#
        +# Rules of engagement.
        +#
        +# There is only one integer shifter meaning that if I have two rotate,
        +# deposit or extract instructions in adjacent bundles, they shall
        +# split [at run-time if they have to]. But note that variable and
        +# parallel shifts are performed by multi-media ALU and *are* pairable
        +# with rotates [and alike]. On the backside MMALU is rather slow: it
        +# takes 2 extra cycles before the result of integer operation is
        +# available *to* MMALU and 2(*) extra cycles before the result of MM
        +# operation is available "back" *to* integer ALU, not to mention that
        +# MMALU itself has 2 cycles latency. However! I explicitly scheduled
        +# these MM instructions to avoid MM stalls, so that all these extra
        +# latencies get "hidden" in instruction-level parallelism.
        +#
        +# (*) 2 cycles on Itanium 1 and 1 cycle on Itanium 2. But I schedule
        +#     for 2 in order to provide for best *overall* performance,
        +#     because on Itanium 1 stall on MM result is accompanied by
        +#     pipeline flush, which takes 6 cycles:-(
        +#
        +# Resulting performance numbers for 900MHz Itanium 2 system:
        +#
        +# The 'numbers' are in 1000s of bytes per second processed.
        +# type     16 bytes    64 bytes   256 bytes  1024 bytes  8192 bytes
        +# sha1(*)   6210.14k   20376.30k   52447.83k   85870.05k  105478.12k
        +# sha256    7476.45k   20572.05k   41538.34k   56062.29k   62093.18k
        +# sha512    4996.56k   20026.28k   47597.20k   85278.79k  111501.31k
        +#
        +# (*) SHA1 numbers are for HP-UX compiler and are presented purely
        +#     for reference purposes. I bet it can improved too...
        +#
        +# To generate code, pass the file name with either 256 or 512 in its
        +# name and compiler flags.
        +
        +$output=shift;
        +
        +if ($output =~ /512.*\.[s|asm]/) {
        +	$SZ=8;
        +	$BITS=8*$SZ;
        +	$LDW="ld8";
        +	$STW="st8";
        +	$ADD="add";
        +	$SHRU="shr.u";
        +	$TABLE="K512";
        +	$func="sha512_block_data_order";
        +	@Sigma0=(28,34,39);
        +	@Sigma1=(14,18,41);
        +	@sigma0=(1,  8, 7);
        +	@sigma1=(19,61, 6);
        +	$rounds=80;
        +} elsif ($output =~ /256.*\.[s|asm]/) {
        +	$SZ=4;
        +	$BITS=8*$SZ;
        +	$LDW="ld4";
        +	$STW="st4";
        +	$ADD="padd4";
        +	$SHRU="pshr4.u";
        +	$TABLE="K256";
        +	$func="sha256_block_data_order";
        +	@Sigma0=( 2,13,22);
        +	@Sigma1=( 6,11,25);
        +	@sigma0=( 7,18, 3);
        +	@sigma1=(17,19,10);
        +	$rounds=64;
        +} else { die "nonsense $output"; }
        +
        +open STDOUT,">$output" || die "can't open $output: $!";
        +
        +if ($^O eq "hpux") {
        +    $ADDP="addp4";
        +    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
        +} else { $ADDP="add"; }
        +for (@ARGV)  {	$big_endian=1 if (/\-DB_ENDIAN/);
        +		$big_endian=0 if (/\-DL_ENDIAN/);  }
        +if (!defined($big_endian))
        +             {	$big_endian=(unpack('L',pack('N',1))==1);  }
        +
        +$code=<<___;
        +.ident  \"$output, version 1.1\"
        +.ident  \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\"
        +.explicit
        +.text
        +
        +pfssave=r2;
        +lcsave=r3;
        +prsave=r14;
        +K=r15;
        +A=r16;	B=r17;	C=r18;	D=r19;
        +E=r20;	F=r21;	G=r22;	H=r23;
        +T1=r24;	T2=r25;
        +s0=r26;	s1=r27;	t0=r28;	t1=r29;
        +Ktbl=r30;
        +ctx=r31;	// 1st arg
        +input=r48;	// 2nd arg
        +num=r49;	// 3rd arg
        +sgm0=r50;	sgm1=r51;	// small constants
        +A_=r54;	B_=r55;	C_=r56;	D_=r57;
        +E_=r58;	F_=r59;	G_=r60;	H_=r61;
        +
        +// void $func (SHA_CTX *ctx, const void *in,size_t num[,int host])
        +.global	$func#
        +.proc	$func#
        +.align	32
        +$func:
        +	.prologue
        +	.save	ar.pfs,pfssave
        +{ .mmi;	alloc	pfssave=ar.pfs,3,27,0,16
        +	$ADDP	ctx=0,r32		// 1st arg
        +	.save	ar.lc,lcsave
        +	mov	lcsave=ar.lc	}
        +{ .mmi;	$ADDP	input=0,r33		// 2nd arg
        +	mov	num=r34			// 3rd arg
        +	.save	pr,prsave
        +	mov	prsave=pr	};;
        +
        +	.body
        +{ .mib;	add	r8=0*$SZ,ctx
        +	add	r9=1*$SZ,ctx
        +	brp.loop.imp	.L_first16,.L_first16_end-16	}
        +{ .mib;	add	r10=2*$SZ,ctx
        +	add	r11=3*$SZ,ctx
        +	brp.loop.imp	.L_rest,.L_rest_end-16		};;
        +
        +// load A-H
        +.Lpic_point:
        +{ .mmi;	$LDW	A_=[r8],4*$SZ
        +	$LDW	B_=[r9],4*$SZ
        +	mov	Ktbl=ip		}
        +{ .mmi;	$LDW	C_=[r10],4*$SZ
        +	$LDW	D_=[r11],4*$SZ
        +	mov	sgm0=$sigma0[2]	};;
        +{ .mmi;	$LDW	E_=[r8]
        +	$LDW	F_=[r9]
        +	add	Ktbl=($TABLE#-.Lpic_point),Ktbl		}
        +{ .mmi;	$LDW	G_=[r10]
        +	$LDW	H_=[r11]
        +	cmp.ne	p0,p16=0,r0	};;	// used in sha256_block
        +___
        +$code.=<<___ if ($BITS==64);
        +{ .mii;	and	r8=7,input
        +	and	input=~7,input;;
        +	cmp.eq	p9,p0=1,r8	}
        +{ .mmi;	cmp.eq	p10,p0=2,r8
        +	cmp.eq	p11,p0=3,r8
        +	cmp.eq	p12,p0=4,r8	}
        +{ .mmi;	cmp.eq	p13,p0=5,r8
        +	cmp.eq	p14,p0=6,r8
        +	cmp.eq	p15,p0=7,r8	};;
        +___
        +$code.=<<___;
        +.L_outer:
        +.rotr	X[16]
        +{ .mmi;	mov	A=A_
        +	mov	B=B_
        +	mov	ar.lc=14	}
        +{ .mmi;	mov	C=C_
        +	mov	D=D_
        +	mov	E=E_		}
        +{ .mmi;	mov	F=F_
        +	mov	G=G_
        +	mov	ar.ec=2		}
        +{ .mmi;	ld1	X[15]=[input],$SZ		// eliminated in 64-bit
        +	mov	H=H_
        +	mov	sgm1=$sigma1[2]	};;
        +
        +___
        +$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32);
        +.align	32
        +.L_first16:
        +{ .mmi;		add	r9=1-$SZ,input
        +		add	r10=2-$SZ,input
        +		add	r11=3-$SZ,input	};;
        +{ .mmi;		ld1	r9=[r9]
        +		ld1	r10=[r10]
        +		dep.z	$t1=E,32,32	}
        +{ .mmi;		$LDW	K=[Ktbl],$SZ
        +		ld1	r11=[r11]
        +		zxt4	E=E		};;
        +{ .mii;		or	$t1=$t1,E
        +		dep	X[15]=X[15],r9,8,8
        +		dep	r11=r10,r11,8,8	};;
        +{ .mmi;		and	T1=F,E
        +		and	T2=A,B
        +		dep	X[15]=X[15],r11,16,16	}
        +{ .mmi;		andcm	r8=G,E
        +		and	r9=A,C
        +		mux2	$t0=A,0x44	};;	// copy lower half to upper
        +{ .mmi;	(p16)	ld1	X[15-1]=[input],$SZ	// prefetch
        +		xor	T1=T1,r8		// T1=((e & f) ^ (~e & g))
        +		_rotr	r11=$t1,$Sigma1[0] }	// ROTR(e,14)
        +{ .mib;		and	r10=B,C
        +		xor	T2=T2,r9	};;
        +___
        +$t0="A", $t1="E", $code.=<<___ if ($BITS==64);
        +// in 64-bit mode I load whole X[16] at once and take care of alignment...
        +{ .mmi;	add	r8=1*$SZ,input
        +	add	r9=2*$SZ,input
        +	add	r10=3*$SZ,input		};;
        +{ .mmb;	$LDW	X[15]=[input],4*$SZ
        +	$LDW	X[14]=[r8],4*$SZ
        +(p9)	br.cond.dpnt.many	.L1byte	};;
        +{ .mmb;	$LDW	X[13]=[r9],4*$SZ
        +	$LDW	X[12]=[r10],4*$SZ
        +(p10)	br.cond.dpnt.many	.L2byte	};;
        +{ .mmb;	$LDW	X[11]=[input],4*$SZ
        +	$LDW	X[10]=[r8],4*$SZ
        +(p11)	br.cond.dpnt.many	.L3byte	};;
        +{ .mmb;	$LDW	X[ 9]=[r9],4*$SZ
        +	$LDW	X[ 8]=[r10],4*$SZ
        +(p12)	br.cond.dpnt.many	.L4byte	};;
        +{ .mmb;	$LDW	X[ 7]=[input],4*$SZ
        +	$LDW	X[ 6]=[r8],4*$SZ
        +(p13)	br.cond.dpnt.many	.L5byte	};;
        +{ .mmb;	$LDW	X[ 5]=[r9],4*$SZ
        +	$LDW	X[ 4]=[r10],4*$SZ
        +(p14)	br.cond.dpnt.many	.L6byte	};;
        +{ .mmb;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +(p15)	br.cond.dpnt.many	.L7byte	};;
        +{ .mmb;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	br.many	.L_first16		};;
        +.L1byte:
        +{ .mmi;	$LDW	X[13]=[r9],4*$SZ
        +	$LDW	X[12]=[r10],4*$SZ
        +	shrp	X[15]=X[15],X[14],56	};;
        +{ .mmi;	$LDW	X[11]=[input],4*$SZ
        +	$LDW	X[10]=[r8],4*$SZ
        +	shrp	X[14]=X[14],X[13],56	}
        +{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
        +	$LDW	X[ 8]=[r10],4*$SZ
        +	shrp	X[13]=X[13],X[12],56	};;
        +{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
        +	$LDW	X[ 6]=[r8],4*$SZ
        +	shrp	X[12]=X[12],X[11],56	}
        +{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
        +	$LDW	X[ 4]=[r10],4*$SZ
        +	shrp	X[11]=X[11],X[10],56	};;
        +{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +	shrp	X[10]=X[10],X[ 9],56	}
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[ 9]=X[ 9],X[ 8],56	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[ 8]=X[ 8],X[ 7],56
        +	shrp	X[ 7]=X[ 7],X[ 6],56	}
        +{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],56
        +	shrp	X[ 5]=X[ 5],X[ 4],56	};;
        +{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],56
        +	shrp	X[ 3]=X[ 3],X[ 2],56	}
        +{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],56
        +	shrp	X[ 1]=X[ 1],X[ 0],56	}
        +{ .mib;	shrp	X[ 0]=X[ 0],T1,56
        +	br.many	.L_first16		};;
        +.L2byte:
        +{ .mmi;	$LDW	X[11]=[input],4*$SZ
        +	$LDW	X[10]=[r8],4*$SZ
        +	shrp	X[15]=X[15],X[14],48	}
        +{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
        +	$LDW	X[ 8]=[r10],4*$SZ
        +	shrp	X[14]=X[14],X[13],48	};;
        +{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
        +	$LDW	X[ 6]=[r8],4*$SZ
        +	shrp	X[13]=X[13],X[12],48	}
        +{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
        +	$LDW	X[ 4]=[r10],4*$SZ
        +	shrp	X[12]=X[12],X[11],48	};;
        +{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +	shrp	X[11]=X[11],X[10],48	}
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[10]=X[10],X[ 9],48	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[ 9]=X[ 9],X[ 8],48
        +	shrp	X[ 8]=X[ 8],X[ 7],48	}
        +{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],48
        +	shrp	X[ 6]=X[ 6],X[ 5],48	};;
        +{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],48
        +	shrp	X[ 4]=X[ 4],X[ 3],48	}
        +{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],48
        +	shrp	X[ 2]=X[ 2],X[ 1],48	}
        +{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],48
        +	shrp	X[ 0]=X[ 0],T1,48	}
        +{ .mfb;	br.many	.L_first16		};;
        +.L3byte:
        +{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
        +	$LDW	X[ 8]=[r10],4*$SZ
        +	shrp	X[15]=X[15],X[14],40	};;
        +{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
        +	$LDW	X[ 6]=[r8],4*$SZ
        +	shrp	X[14]=X[14],X[13],40	}
        +{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
        +	$LDW	X[ 4]=[r10],4*$SZ
        +	shrp	X[13]=X[13],X[12],40	};;
        +{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +	shrp	X[12]=X[12],X[11],40	}
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[11]=X[11],X[10],40	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[10]=X[10],X[ 9],40
        +	shrp	X[ 9]=X[ 9],X[ 8],40	}
        +{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],40
        +	shrp	X[ 7]=X[ 7],X[ 6],40	};;
        +{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],40
        +	shrp	X[ 5]=X[ 5],X[ 4],40	}
        +{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],40
        +	shrp	X[ 3]=X[ 3],X[ 2],40	}
        +{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],40
        +	shrp	X[ 1]=X[ 1],X[ 0],40	}
        +{ .mib;	shrp	X[ 0]=X[ 0],T1,40
        +	br.many	.L_first16		};;
        +.L4byte:
        +{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
        +	$LDW	X[ 6]=[r8],4*$SZ
        +	shrp	X[15]=X[15],X[14],32	}
        +{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
        +	$LDW	X[ 4]=[r10],4*$SZ
        +	shrp	X[14]=X[14],X[13],32	};;
        +{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +	shrp	X[13]=X[13],X[12],32	}
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[12]=X[12],X[11],32	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[11]=X[11],X[10],32
        +	shrp	X[10]=X[10],X[ 9],32	}
        +{ .mii;	shrp	X[ 9]=X[ 9],X[ 8],32
        +	shrp	X[ 8]=X[ 8],X[ 7],32	};;
        +{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],32
        +	shrp	X[ 6]=X[ 6],X[ 5],32	}
        +{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],32
        +	shrp	X[ 4]=X[ 4],X[ 3],32	}
        +{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],32
        +	shrp	X[ 2]=X[ 2],X[ 1],32	}
        +{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],32
        +	shrp	X[ 0]=X[ 0],T1,32	}
        +{ .mfb;	br.many	.L_first16		};;
        +.L5byte:
        +{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
        +	$LDW	X[ 4]=[r10],4*$SZ
        +	shrp	X[15]=X[15],X[14],24	};;
        +{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +	shrp	X[14]=X[14],X[13],24	}
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[13]=X[13],X[12],24	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[12]=X[12],X[11],24
        +	shrp	X[11]=X[11],X[10],24	}
        +{ .mii;	shrp	X[10]=X[10],X[ 9],24
        +	shrp	X[ 9]=X[ 9],X[ 8],24	};;
        +{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],24
        +	shrp	X[ 7]=X[ 7],X[ 6],24	}
        +{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],24
        +	shrp	X[ 5]=X[ 5],X[ 4],24	}
        +{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],24
        +	shrp	X[ 3]=X[ 3],X[ 2],24	}
        +{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],24
        +	shrp	X[ 1]=X[ 1],X[ 0],24	}
        +{ .mib;	shrp	X[ 0]=X[ 0],T1,24
        +	br.many	.L_first16		};;
        +.L6byte:
        +{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
        +	$LDW	X[ 2]=[r8],4*$SZ
        +	shrp	X[15]=X[15],X[14],16	}
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[14]=X[14],X[13],16	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[13]=X[13],X[12],16
        +	shrp	X[12]=X[12],X[11],16	}
        +{ .mii;	shrp	X[11]=X[11],X[10],16
        +	shrp	X[10]=X[10],X[ 9],16	};;
        +{ .mii;	shrp	X[ 9]=X[ 9],X[ 8],16
        +	shrp	X[ 8]=X[ 8],X[ 7],16	}
        +{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],16
        +	shrp	X[ 6]=X[ 6],X[ 5],16	}
        +{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],16
        +	shrp	X[ 4]=X[ 4],X[ 3],16	}
        +{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],16
        +	shrp	X[ 2]=X[ 2],X[ 1],16	}
        +{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],16
        +	shrp	X[ 0]=X[ 0],T1,16	}
        +{ .mfb;	br.many	.L_first16		};;
        +.L7byte:
        +{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
        +	$LDW	X[ 0]=[r10],4*$SZ
        +	shrp	X[15]=X[15],X[14],8	};;
        +{ .mii;	$LDW	T1=[input]
        +	shrp	X[14]=X[14],X[13],8
        +	shrp	X[13]=X[13],X[12],8	}
        +{ .mii;	shrp	X[12]=X[12],X[11],8
        +	shrp	X[11]=X[11],X[10],8	};;
        +{ .mii;	shrp	X[10]=X[10],X[ 9],8
        +	shrp	X[ 9]=X[ 9],X[ 8],8	}
        +{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],8
        +	shrp	X[ 7]=X[ 7],X[ 6],8	}
        +{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],8
        +	shrp	X[ 5]=X[ 5],X[ 4],8	}
        +{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],8
        +	shrp	X[ 3]=X[ 3],X[ 2],8	}
        +{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],8
        +	shrp	X[ 1]=X[ 1],X[ 0],8	}
        +{ .mib;	shrp	X[ 0]=X[ 0],T1,8
        +	br.many	.L_first16		};;
        +
        +.align	32
        +.L_first16:
        +{ .mmi;		$LDW	K=[Ktbl],$SZ
        +		and	T1=F,E
        +		and	T2=A,B		}
        +{ .mmi;		//$LDW	X[15]=[input],$SZ	// X[i]=*input++
        +		andcm	r8=G,E
        +		and	r9=A,C		};;
        +{ .mmi;		xor	T1=T1,r8		//T1=((e & f) ^ (~e & g))
        +		and	r10=B,C
        +		_rotr	r11=$t1,$Sigma1[0] }	// ROTR(e,14)
        +{ .mmi;		xor	T2=T2,r9
        +		mux1	X[15]=X[15],\@rev };;	// eliminated in big-endian
        +___
        +$code.=<<___;
        +{ .mib;		add	T1=T1,H			// T1=Ch(e,f,g)+h
        +		_rotr	r8=$t1,$Sigma1[1] }	// ROTR(e,18)
        +{ .mib;		xor	T2=T2,r10		// T2=((a & b) ^ (a & c) ^ (b & c))
        +		mov	H=G		};;
        +{ .mib;		xor	r11=r8,r11
        +		_rotr	r9=$t1,$Sigma1[2] }	// ROTR(e,41)
        +{ .mib;		mov	G=F
        +		mov	F=E		};;
        +{ .mib;		xor	r9=r9,r11		// r9=Sigma1(e)
        +		_rotr	r10=$t0,$Sigma0[0] }	// ROTR(a,28)
        +{ .mib;		add	T1=T1,K			// T1=Ch(e,f,g)+h+K512[i]
        +		mov	E=D		};;
        +{ .mib;		add	T1=T1,r9		// T1+=Sigma1(e)
        +		_rotr	r11=$t0,$Sigma0[1] }	// ROTR(a,34)
        +{ .mib;		mov	D=C
        +		mov	C=B		};;
        +{ .mib;		add	T1=T1,X[15]		// T1+=X[i]
        +		_rotr	r8=$t0,$Sigma0[2] }	// ROTR(a,39)
        +{ .mib;		xor	r10=r10,r11
        +		mux2	X[15]=X[15],0x44 };;	// eliminated in 64-bit
        +{ .mmi;		xor	r10=r8,r10		// r10=Sigma0(a)
        +		mov	B=A
        +		add	A=T1,T2		};;
        +{ .mib;		add	E=E,T1
        +		add	A=A,r10			// T2=Maj(a,b,c)+Sigma0(a)
        +	br.ctop.sptk	.L_first16	};;
        +.L_first16_end:
        +
        +{ .mii;	mov	ar.lc=$rounds-17
        +	mov	ar.ec=1			};;
        +
        +.align	32
        +.L_rest:
        +.rotr	X[16]
        +{ .mib;		$LDW	K=[Ktbl],$SZ
        +		_rotr	r8=X[15-1],$sigma0[0] }	// ROTR(s0,1)
        +{ .mib; 	$ADD	X[15]=X[15],X[15-9]	// X[i&0xF]+=X[(i+9)&0xF]
        +		$SHRU	s0=X[15-1],sgm0	};;	// s0=X[(i+1)&0xF]>>7
        +{ .mib;		and	T1=F,E
        +		_rotr	r9=X[15-1],$sigma0[1] }	// ROTR(s0,8)
        +{ .mib;		andcm	r10=G,E
        +		$SHRU	s1=X[15-14],sgm1 };;	// s1=X[(i+14)&0xF]>>6
        +{ .mmi;		xor	T1=T1,r10		// T1=((e & f) ^ (~e & g))
        +		xor	r9=r8,r9
        +		_rotr	r10=X[15-14],$sigma1[0] };;// ROTR(s1,19)
        +{ .mib;		and	T2=A,B		
        +		_rotr	r11=X[15-14],$sigma1[1] }// ROTR(s1,61)
        +{ .mib;		and	r8=A,C		};;
        +___
        +$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32);
        +// I adhere to mmi; in order to hold Itanium 1 back and avoid 6 cycle
        +// pipeline flush in last bundle. Note that even on Itanium2 the
        +// latter stalls for one clock cycle...
        +{ .mmi;		xor	s0=s0,r9		// s0=sigma0(X[(i+1)&0xF])
        +		dep.z	$t1=E,32,32	}
        +{ .mmi;		xor	r10=r11,r10
        +		zxt4	E=E		};;
        +{ .mmi;		or	$t1=$t1,E
        +		xor	s1=s1,r10		// s1=sigma1(X[(i+14)&0xF])
        +		mux2	$t0=A,0x44	};;	// copy lower half to upper
        +{ .mmi;		xor	T2=T2,r8
        +		_rotr	r9=$t1,$Sigma1[0] }	// ROTR(e,14)
        +{ .mmi;		and	r10=B,C
        +		add	T1=T1,H			// T1=Ch(e,f,g)+h
        +		$ADD	X[15]=X[15],s0	};;	// X[i&0xF]+=sigma0(X[(i+1)&0xF])
        +___
        +$t0="A", $t1="E", $code.=<<___ if ($BITS==64);
        +{ .mib;		xor	s0=s0,r9		// s0=sigma0(X[(i+1)&0xF])
        +		_rotr	r9=$t1,$Sigma1[0] }	// ROTR(e,14)
        +{ .mib;		xor	r10=r11,r10
        +		xor	T2=T2,r8	};;
        +{ .mib;		xor	s1=s1,r10		// s1=sigma1(X[(i+14)&0xF])
        +		add	T1=T1,H		}
        +{ .mib;		and	r10=B,C
        +		$ADD	X[15]=X[15],s0	};;	// X[i&0xF]+=sigma0(X[(i+1)&0xF])
        +___
        +$code.=<<___;
        +{ .mmi;		xor	T2=T2,r10		// T2=((a & b) ^ (a & c) ^ (b & c))
        +		mov	H=G
        +		_rotr	r8=$t1,$Sigma1[1] };;	// ROTR(e,18)
        +{ .mmi;		xor	r11=r8,r9
        +		$ADD	X[15]=X[15],s1		// X[i&0xF]+=sigma1(X[(i+14)&0xF])
        +		_rotr	r9=$t1,$Sigma1[2] }	// ROTR(e,41)
        +{ .mmi;		mov	G=F
        +		mov	F=E		};;
        +{ .mib;		xor	r9=r9,r11		// r9=Sigma1(e)
        +		_rotr	r10=$t0,$Sigma0[0] }	// ROTR(a,28)
        +{ .mib;		add	T1=T1,K			// T1=Ch(e,f,g)+h+K512[i]
        +		mov	E=D		};;
        +{ .mib;		add	T1=T1,r9		// T1+=Sigma1(e)
        +		_rotr	r11=$t0,$Sigma0[1] }	// ROTR(a,34)
        +{ .mib;		mov	D=C
        +		mov	C=B		};;
        +{ .mmi;		add	T1=T1,X[15]		// T1+=X[i]
        +		xor	r10=r10,r11
        +		_rotr	r8=$t0,$Sigma0[2] };;	// ROTR(a,39)
        +{ .mmi;		xor	r10=r8,r10		// r10=Sigma0(a)
        +		mov	B=A
        +		add	A=T1,T2		};;
        +{ .mib;		add	E=E,T1
        +		add	A=A,r10			// T2=Maj(a,b,c)+Sigma0(a)
        +	br.ctop.sptk	.L_rest	};;
        +.L_rest_end:
        +
        +{ .mmi;	add	A_=A_,A
        +	add	B_=B_,B
        +	add	C_=C_,C			}
        +{ .mmi;	add	D_=D_,D
        +	add	E_=E_,E
        +	cmp.ltu	p16,p0=1,num		};;
        +{ .mmi;	add	F_=F_,F
        +	add	G_=G_,G
        +	add	H_=H_,H			}
        +{ .mmb;	add	Ktbl=-$SZ*$rounds,Ktbl
        +(p16)	add	num=-1,num
        +(p16)	br.dptk.many	.L_outer	};;
        +
        +{ .mib;	add	r8=0*$SZ,ctx
        +	add	r9=1*$SZ,ctx		}
        +{ .mib;	add	r10=2*$SZ,ctx
        +	add	r11=3*$SZ,ctx		};;
        +{ .mmi;	$STW	[r8]=A_,4*$SZ
        +	$STW	[r9]=B_,4*$SZ
        +	mov	ar.lc=lcsave		}
        +{ .mmi;	$STW	[r10]=C_,4*$SZ
        +	$STW	[r11]=D_,4*$SZ
        +	mov	pr=prsave,0x1ffff	};;
        +{ .mmb;	$STW	[r8]=E_
        +	$STW	[r9]=F_			}
        +{ .mmb;	$STW	[r10]=G_
        +	$STW	[r11]=H_
        +	br.ret.sptk.many	b0	};;
        +.endp	$func#
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +$code =~ s/_rotr(\s+)([^=]+)=([^,]+),([0-9]+)/shrp$1$2=$3,$3,$4/gm;
        +if ($BITS==64) {
        +    $code =~ s/mux2(\s+)\S+/nop.i$1 0x0/gm;
        +    $code =~ s/mux1(\s+)\S+/nop.i$1 0x0/gm	if ($big_endian);
        +    $code =~ s/(shrp\s+X\[[^=]+)=([^,]+),([^,]+),([1-9]+)/$1=$3,$2,64-$4/gm
        +    						if (!$big_endian);
        +    $code =~ s/ld1(\s+)X\[\S+/nop.m$1 0x0/gm;
        +}
        +
        +print $code;
        +
        +print<<___ if ($BITS==32);
        +.align	64
        +.type	K256#,\@object
        +K256:	data4	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +	data4	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +	data4	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +	data4	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +	data4	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +	data4	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +	data4	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +	data4	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +	data4	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +	data4	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +	data4	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +	data4	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +	data4	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +	data4	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +	data4	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +	data4	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        +.size	K256#,$SZ*$rounds
        +stringz	"SHA256 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +print<<___ if ($BITS==64);
        +.align	64
        +.type	K512#,\@object
        +K512:	data8	0x428a2f98d728ae22,0x7137449123ef65cd
        +	data8	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
        +	data8	0x3956c25bf348b538,0x59f111f1b605d019
        +	data8	0x923f82a4af194f9b,0xab1c5ed5da6d8118
        +	data8	0xd807aa98a3030242,0x12835b0145706fbe
        +	data8	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
        +	data8	0x72be5d74f27b896f,0x80deb1fe3b1696b1
        +	data8	0x9bdc06a725c71235,0xc19bf174cf692694
        +	data8	0xe49b69c19ef14ad2,0xefbe4786384f25e3
        +	data8	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
        +	data8	0x2de92c6f592b0275,0x4a7484aa6ea6e483
        +	data8	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
        +	data8	0x983e5152ee66dfab,0xa831c66d2db43210
        +	data8	0xb00327c898fb213f,0xbf597fc7beef0ee4
        +	data8	0xc6e00bf33da88fc2,0xd5a79147930aa725
        +	data8	0x06ca6351e003826f,0x142929670a0e6e70
        +	data8	0x27b70a8546d22ffc,0x2e1b21385c26c926
        +	data8	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
        +	data8	0x650a73548baf63de,0x766a0abb3c77b2a8
        +	data8	0x81c2c92e47edaee6,0x92722c851482353b
        +	data8	0xa2bfe8a14cf10364,0xa81a664bbc423001
        +	data8	0xc24b8b70d0f89791,0xc76c51a30654be30
        +	data8	0xd192e819d6ef5218,0xd69906245565a910
        +	data8	0xf40e35855771202a,0x106aa07032bbd1b8
        +	data8	0x19a4c116b8d2d0c8,0x1e376c085141ab53
        +	data8	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
        +	data8	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
        +	data8	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
        +	data8	0x748f82ee5defb2fc,0x78a5636f43172f60
        +	data8	0x84c87814a1f0ab72,0x8cc702081a6439ec
        +	data8	0x90befffa23631e28,0xa4506cebde82bde9
        +	data8	0xbef9a3f7b2c67915,0xc67178f2e372532b
        +	data8	0xca273eceea26619c,0xd186b8c721c0c207
        +	data8	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
        +	data8	0x06f067aa72176fba,0x0a637dc5a2c898a6
        +	data8	0x113f9804bef90dae,0x1b710b35131c471b
        +	data8	0x28db77f523047d84,0x32caab7b40c72493
        +	data8	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
        +	data8	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
        +	data8	0x5fcb6fab3ad6faec,0x6c44198c4a475817
        +.size	K512#,$SZ*$rounds
        +stringz	"SHA512 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-mips.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-mips.pl
        new file mode 100644
        index 000000000..ba5b25089
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-mips.pl
        @@ -0,0 +1,455 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA2 block procedures for MIPS.
        +
        +# October 2010.
        +#
        +# SHA256 performance improvement on MIPS R5000 CPU is ~27% over gcc-
        +# generated code in o32 build and ~55% in n32/64 build. SHA512 [which
        +# for now can only be compiled for MIPS64 ISA] improvement is modest
        +# ~17%, but it comes for free, because it's same instruction sequence.
        +# Improvement coefficients are for aligned input.
        +
        +######################################################################
        +# There is a number of MIPS ABI in use, O32 and N32/64 are most
        +# widely used. Then there is a new contender: NUBI. It appears that if
        +# one picks the latter, it's possible to arrange code in ABI neutral
        +# manner. Therefore let's stick to NUBI register layout:
        +#
        +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
        +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
        +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
        +#
        +# The return value is placed in $a0. Following coding rules facilitate
        +# interoperability:
        +#
        +# - never ever touch $tp, "thread pointer", former $gp [o32 can be
        +#   excluded from the rule, because it's specified volatile];
        +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
        +#   old code];
        +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
        +#
        +# For reference here is register layout for N32/64 MIPS ABIs:
        +#
        +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
        +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
        +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
        +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
        +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
        +#
        +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
        +
        +if ($flavour =~ /64|n32/i) {
        +	$PTR_ADD="dadd";	# incidentally works even on n32
        +	$PTR_SUB="dsub";	# incidentally works even on n32
        +	$REG_S="sd";
        +	$REG_L="ld";
        +	$PTR_SLL="dsll";	# incidentally works even on n32
        +	$SZREG=8;
        +} else {
        +	$PTR_ADD="add";
        +	$PTR_SUB="sub";
        +	$REG_S="sw";
        +	$REG_L="lw";
        +	$PTR_SLL="sll";
        +	$SZREG=4;
        +}
        +$pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
        +#
        +# <appro@openssl.org>
        +#
        +######################################################################
        +
        +$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
        +
        +for (@ARGV) {	$output=$_ if (/^\w[\w\-]*\.\w+$/);	}
        +open STDOUT,">$output";
        +
        +if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); }
        +
        +if ($output =~ /512/) {
        +	$label="512";
        +	$SZ=8;
        +	$LD="ld";		# load from memory
        +	$ST="sd";		# store to memory
        +	$SLL="dsll";		# shift left logical
        +	$SRL="dsrl";		# shift right logical
        +	$ADDU="daddu";
        +	@Sigma0=(28,34,39);
        +	@Sigma1=(14,18,41);
        +	@sigma0=( 7, 1, 8);	# right shift first
        +	@sigma1=( 6,19,61);	# right shift first
        +	$lastK=0x817;
        +	$rounds=80;
        +} else {
        +	$label="256";
        +	$SZ=4;
        +	$LD="lw";		# load from memory
        +	$ST="sw";		# store to memory
        +	$SLL="sll";		# shift left logical
        +	$SRL="srl";		# shift right logical
        +	$ADDU="addu";
        +	@Sigma0=( 2,13,22);
        +	@Sigma1=( 6,11,25);
        +	@sigma0=( 3, 7,18);	# right shift first
        +	@sigma1=(10,17,19);	# right shift first
        +	$lastK=0x8f2;
        +	$rounds=64;
        +}
        +
        +$MSB = $big_endian ? 0 : ($SZ-1);
        +$LSB = ($SZ-1)&~$MSB;
        +
        +@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("\$$_",(1,2,3,7,24,25,30,31));
        +@X=map("\$$_",(8..23));
        +
        +$ctx=$a0;
        +$inp=$a1;
        +$len=$a2;	$Ktbl=$len;
        +
        +sub BODY_00_15 {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +my ($T1,$tmp0,$tmp1,$tmp2)=(@X[4],@X[5],@X[6],@X[7]);
        +
        +$code.=<<___ if ($i<15);
        +	${LD}l	@X[1],`($i+1)*$SZ+$MSB`($inp)
        +	${LD}r	@X[1],`($i+1)*$SZ+$LSB`($inp)
        +___
        +$code.=<<___	if (!$big_endian && $i<16 && $SZ==4);
        +	srl	$tmp0,@X[0],24		# byte swap($i)
        +	srl	$tmp1,@X[0],8
        +	andi	$tmp2,@X[0],0xFF00
        +	sll	@X[0],@X[0],24
        +	andi	$tmp1,0xFF00
        +	sll	$tmp2,$tmp2,8
        +	or	@X[0],$tmp0
        +	or	$tmp1,$tmp2
        +	or	@X[0],$tmp1
        +___
        +$code.=<<___	if (!$big_endian && $i<16 && $SZ==8);
        +	ori	$tmp0,$zero,0xFF
        +	dsll	$tmp2,$tmp0,32
        +	or	$tmp0,$tmp2		# 0x000000FF000000FF
        +	and	$tmp1,@X[0],$tmp0	# byte swap($i)
        +	dsrl	$tmp2,@X[0],24
        +	dsll	$tmp1,24
        +	and	$tmp2,$tmp0
        +	dsll	$tmp0,8			# 0x0000FF000000FF00
        +	or	$tmp1,$tmp2
        +	and	$tmp2,@X[0],$tmp0
        +	dsrl	@X[0],8
        +	dsll	$tmp2,8
        +	and	@X[0],$tmp0
        +	or	$tmp1,$tmp2
        +	or	@X[0],$tmp1
        +	dsrl	$tmp1,@X[0],32
        +	dsll	@X[0],32
        +	or	@X[0],$tmp1
        +___
        +$code.=<<___;
        +	$ADDU	$T1,$X[0],$h			# $i
        +	$SRL	$h,$e,@Sigma1[0]
        +	xor	$tmp2,$f,$g
        +	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[2]`
        +	and	$tmp2,$e
        +	$SRL	$tmp0,$e,@Sigma1[1]
        +	xor	$h,$tmp1
        +	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[1]`
        +	xor	$h,$tmp0
        +	$SRL	$tmp0,$e,@Sigma1[2]
        +	xor	$h,$tmp1
        +	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[0]`
        +	xor	$h,$tmp0
        +	xor	$tmp2,$g			# Ch(e,f,g)
        +	xor	$tmp0,$tmp1,$h			# Sigma1(e)
        +
        +	$SRL	$h,$a,@Sigma0[0]
        +	$ADDU	$T1,$tmp2
        +	$LD	$tmp2,`$i*$SZ`($Ktbl)		# K[$i]
        +	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[2]`
        +	$ADDU	$T1,$tmp0
        +	$SRL	$tmp0,$a,@Sigma0[1]
        +	xor	$h,$tmp1
        +	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[1]`
        +	xor	$h,$tmp0
        +	$SRL	$tmp0,$a,@Sigma0[2]
        +	xor	$h,$tmp1
        +	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[0]`
        +	xor	$h,$tmp0
        +	$ST	@X[0],`($i%16)*$SZ`($sp)	# offload to ring buffer
        +	xor	$h,$tmp1			# Sigma0(a)
        +
        +	or	$tmp0,$a,$b
        +	and	$tmp1,$a,$b
        +	and	$tmp0,$c
        +	or	$tmp1,$tmp0			# Maj(a,b,c)
        +	$ADDU	$T1,$tmp2			# +=K[$i]
        +	$ADDU	$h,$tmp1
        +
        +	$ADDU	$d,$T1
        +	$ADDU	$h,$T1
        +___
        +$code.=<<___ if ($i>=13);
        +	$LD	@X[3],`(($i+3)%16)*$SZ`($sp)	# prefetch from ring buffer
        +___
        +}
        +
        +sub BODY_16_XX {
        +my $i=@_[0];
        +my ($tmp0,$tmp1,$tmp2,$tmp3)=(@X[4],@X[5],@X[6],@X[7]);
        +
        +$code.=<<___;
        +	$SRL	$tmp2,@X[1],@sigma0[0]		# Xupdate($i)
        +	$ADDU	@X[0],@X[9]			# +=X[i+9]
        +	$SLL	$tmp1,@X[1],`$SZ*8-@sigma0[2]`
        +	$SRL	$tmp0,@X[1],@sigma0[1]
        +	xor	$tmp2,$tmp1
        +	$SLL	$tmp1,`@sigma0[2]-@sigma0[1]`
        +	xor	$tmp2,$tmp0
        +	$SRL	$tmp0,@X[1],@sigma0[2]
        +	xor	$tmp2,$tmp1
        +
        +	$SRL	$tmp3,@X[14],@sigma1[0]
        +	xor	$tmp2,$tmp0			# sigma0(X[i+1])
        +	$SLL	$tmp1,@X[14],`$SZ*8-@sigma1[2]`
        +	$ADDU	@X[0],$tmp2
        +	$SRL	$tmp0,@X[14],@sigma1[1]
        +	xor	$tmp3,$tmp1
        +	$SLL	$tmp1,`@sigma1[2]-@sigma1[1]`
        +	xor	$tmp3,$tmp0
        +	$SRL	$tmp0,@X[14],@sigma1[2]
        +	xor	$tmp3,$tmp1
        +
        +	xor	$tmp3,$tmp0			# sigma1(X[i+14])
        +	$ADDU	@X[0],$tmp3
        +___
        +	&BODY_00_15(@_);
        +}
        +
        +$FRAMESIZE=16*$SZ+16*$SZREG;
        +$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
        +
        +$code.=<<___;
        +#ifdef OPENSSL_FIPSCANISTER
        +# include <openssl/fipssyms.h>
        +#endif
        +
        +.text
        +.set	noat
        +#if !defined(__vxworks) || defined(__pic__)
        +.option	pic2
        +#endif
        +
        +.align	5
        +.globl	sha${label}_block_data_order
        +.ent	sha${label}_block_data_order
        +sha${label}_block_data_order:
        +	.frame	$sp,$FRAMESIZE,$ra
        +	.mask	$SAVED_REGS_MASK,-$SZREG
        +	.set	noreorder
        +___
        +$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
        +	.cpload	$pf
        +___
        +$code.=<<___;
        +	$PTR_SUB $sp,$FRAMESIZE
        +	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
        +	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
        +	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
        +	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
        +	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
        +	$REG_S	$s3,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_S	$s2,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_S	$s1,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_S	$s0,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___;
        +	$PTR_SLL @X[15],$len,`log(16*$SZ)/log(2)`
        +___
        +$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
        +	.cplocal	$Ktbl
        +	.cpsetup	$pf,$zero,sha${label}_block_data_order
        +___
        +$code.=<<___;
        +	.set	reorder
        +	la	$Ktbl,K${label}		# PIC-ified 'load address'
        +
        +	$LD	$A,0*$SZ($ctx)		# load context
        +	$LD	$B,1*$SZ($ctx)
        +	$LD	$C,2*$SZ($ctx)
        +	$LD	$D,3*$SZ($ctx)
        +	$LD	$E,4*$SZ($ctx)
        +	$LD	$F,5*$SZ($ctx)
        +	$LD	$G,6*$SZ($ctx)
        +	$LD	$H,7*$SZ($ctx)
        +
        +	$PTR_ADD @X[15],$inp		# pointer to the end of input
        +	$REG_S	@X[15],16*$SZ($sp)
        +	b	.Loop
        +
        +.align	5
        +.Loop:
        +	${LD}l	@X[0],$MSB($inp)
        +	${LD}r	@X[0],$LSB($inp)
        +___
        +for ($i=0;$i<16;$i++)
        +{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
        +$code.=<<___;
        +	b	.L16_xx
        +.align	4
        +.L16_xx:
        +___
        +for (;$i<32;$i++)
        +{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
        +$code.=<<___;
        +	and	@X[6],0xfff
        +	li	@X[7],$lastK
        +	.set	noreorder
        +	bne	@X[6],@X[7],.L16_xx
        +	$PTR_ADD $Ktbl,16*$SZ		# Ktbl+=16
        +
        +	$REG_L	@X[15],16*$SZ($sp)	# restore pointer to the end of input
        +	$LD	@X[0],0*$SZ($ctx)
        +	$LD	@X[1],1*$SZ($ctx)
        +	$LD	@X[2],2*$SZ($ctx)
        +	$PTR_ADD $inp,16*$SZ
        +	$LD	@X[3],3*$SZ($ctx)
        +	$ADDU	$A,@X[0]
        +	$LD	@X[4],4*$SZ($ctx)
        +	$ADDU	$B,@X[1]
        +	$LD	@X[5],5*$SZ($ctx)
        +	$ADDU	$C,@X[2]
        +	$LD	@X[6],6*$SZ($ctx)
        +	$ADDU	$D,@X[3]
        +	$LD	@X[7],7*$SZ($ctx)
        +	$ADDU	$E,@X[4]
        +	$ST	$A,0*$SZ($ctx)
        +	$ADDU	$F,@X[5]
        +	$ST	$B,1*$SZ($ctx)
        +	$ADDU	$G,@X[6]
        +	$ST	$C,2*$SZ($ctx)
        +	$ADDU	$H,@X[7]
        +	$ST	$D,3*$SZ($ctx)
        +	$ST	$E,4*$SZ($ctx)
        +	$ST	$F,5*$SZ($ctx)
        +	$ST	$G,6*$SZ($ctx)
        +	$ST	$H,7*$SZ($ctx)
        +
        +	bnel	$inp,@X[15],.Loop
        +	$PTR_SUB $Ktbl,`($rounds-16)*$SZ`	# rewind $Ktbl
        +
        +	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
        +	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
        +	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
        +	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
        +	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
        +	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
        +	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
        +	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
        +	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
        +	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
        +___
        +$code.=<<___ if ($flavour =~ /nubi/i);
        +	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
        +	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
        +	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
        +	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
        +	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
        +___
        +$code.=<<___;
        +	jr	$ra
        +	$PTR_ADD $sp,$FRAMESIZE
        +.end	sha${label}_block_data_order
        +
        +.rdata
        +.align	5
        +K${label}:
        +___
        +if ($SZ==4) {
        +$code.=<<___;
        +	.word	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
        +	.word	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
        +	.word	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
        +	.word	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
        +	.word	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
        +	.word	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
        +	.word	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
        +	.word	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
        +	.word	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
        +	.word	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
        +	.word	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
        +	.word	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
        +	.word	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
        +	.word	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
        +	.word	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
        +	.word	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
        +___
        +} else {
        +$code.=<<___;
        +	.dword	0x428a2f98d728ae22, 0x7137449123ef65cd
        +	.dword	0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc
        +	.dword	0x3956c25bf348b538, 0x59f111f1b605d019
        +	.dword	0x923f82a4af194f9b, 0xab1c5ed5da6d8118
        +	.dword	0xd807aa98a3030242, 0x12835b0145706fbe
        +	.dword	0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2
        +	.dword	0x72be5d74f27b896f, 0x80deb1fe3b1696b1
        +	.dword	0x9bdc06a725c71235, 0xc19bf174cf692694
        +	.dword	0xe49b69c19ef14ad2, 0xefbe4786384f25e3
        +	.dword	0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65
        +	.dword	0x2de92c6f592b0275, 0x4a7484aa6ea6e483
        +	.dword	0x5cb0a9dcbd41fbd4, 0x76f988da831153b5
        +	.dword	0x983e5152ee66dfab, 0xa831c66d2db43210
        +	.dword	0xb00327c898fb213f, 0xbf597fc7beef0ee4
        +	.dword	0xc6e00bf33da88fc2, 0xd5a79147930aa725
        +	.dword	0x06ca6351e003826f, 0x142929670a0e6e70
        +	.dword	0x27b70a8546d22ffc, 0x2e1b21385c26c926
        +	.dword	0x4d2c6dfc5ac42aed, 0x53380d139d95b3df
        +	.dword	0x650a73548baf63de, 0x766a0abb3c77b2a8
        +	.dword	0x81c2c92e47edaee6, 0x92722c851482353b
        +	.dword	0xa2bfe8a14cf10364, 0xa81a664bbc423001
        +	.dword	0xc24b8b70d0f89791, 0xc76c51a30654be30
        +	.dword	0xd192e819d6ef5218, 0xd69906245565a910
        +	.dword	0xf40e35855771202a, 0x106aa07032bbd1b8
        +	.dword	0x19a4c116b8d2d0c8, 0x1e376c085141ab53
        +	.dword	0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8
        +	.dword	0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb
        +	.dword	0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3
        +	.dword	0x748f82ee5defb2fc, 0x78a5636f43172f60
        +	.dword	0x84c87814a1f0ab72, 0x8cc702081a6439ec
        +	.dword	0x90befffa23631e28, 0xa4506cebde82bde9
        +	.dword	0xbef9a3f7b2c67915, 0xc67178f2e372532b
        +	.dword	0xca273eceea26619c, 0xd186b8c721c0c207
        +	.dword	0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178
        +	.dword	0x06f067aa72176fba, 0x0a637dc5a2c898a6
        +	.dword	0x113f9804bef90dae, 0x1b710b35131c471b
        +	.dword	0x28db77f523047d84, 0x32caab7b40c72493
        +	.dword	0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c
        +	.dword	0x4cc5d4becb3e42b6, 0x597f299cfc657e2a
        +	.dword	0x5fcb6fab3ad6faec, 0x6c44198c4a475817
        +___
        +}
        +$code.=<<___;
        +.asciiz	"SHA${label} for MIPS, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	5
        +
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-parisc.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-parisc.pl
        new file mode 100644
        index 000000000..e24ee58ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-parisc.pl
        @@ -0,0 +1,791 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA256/512 block procedure for PA-RISC.
        +
        +# June 2009.
        +#
        +# SHA256 performance is >75% better than gcc 3.2 generated code on
        +# PA-7100LC. Compared to code generated by vendor compiler this
        +# implementation is almost 70% faster in 64-bit build, but delivers
        +# virtually same performance in 32-bit build on PA-8600.
        +#
        +# SHA512 performance is >2.9x better than gcc 3.2 generated code on
        +# PA-7100LC, PA-RISC 1.1 processor. Then implementation detects if the
        +# code is executed on PA-RISC 2.0 processor and switches to 64-bit
        +# code path delivering adequate peformance even in "blended" 32-bit
        +# build. Though 64-bit code is not any faster than code generated by
        +# vendor compiler on PA-8600...
        +#
        +# Special thanks to polarhome.com for providing HP-UX account.
        +
        +$flavour = shift;
        +$output = shift;
        +open STDOUT,">$output";
        +
        +if ($flavour =~ /64/) {
        +	$LEVEL		="2.0W";
        +	$SIZE_T		=8;
        +	$FRAME_MARKER	=80;
        +	$SAVED_RP	=16;
        +	$PUSH		="std";
        +	$PUSHMA		="std,ma";
        +	$POP		="ldd";
        +	$POPMB		="ldd,mb";
        +} else {
        +	$LEVEL		="1.0";
        +	$SIZE_T		=4;
        +	$FRAME_MARKER	=48;
        +	$SAVED_RP	=20;
        +	$PUSH		="stw";
        +	$PUSHMA		="stwm";
        +	$POP		="ldw";
        +	$POPMB		="ldwm";
        +}
        +
        +if ($output =~ /512/) {
        +	$func="sha512_block_data_order";
        +	$SZ=8;
        +	@Sigma0=(28,34,39);
        +	@Sigma1=(14,18,41);
        +	@sigma0=(1,  8, 7);
        +	@sigma1=(19,61, 6);
        +	$rounds=80;
        +	$LAST10BITS=0x017;
        +	$LD="ldd";
        +	$LDM="ldd,ma";
        +	$ST="std";
        +} else {
        +	$func="sha256_block_data_order";
        +	$SZ=4;
        +	@Sigma0=( 2,13,22);
        +	@Sigma1=( 6,11,25);
        +	@sigma0=( 7,18, 3);
        +	@sigma1=(17,19,10);
        +	$rounds=64;
        +	$LAST10BITS=0x0f2;
        +	$LD="ldw";
        +	$LDM="ldwm";
        +	$ST="stw";
        +}
        +
        +$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker
        +				#                 [+ argument transfer]
        +$XOFF=16*$SZ+32;		# local variables
        +$FRAME+=$XOFF;
        +$XOFF+=$FRAME_MARKER;		# distance between %sp and local variables
        +
        +$ctx="%r26";	# zapped by $a0
        +$inp="%r25";	# zapped by $a1
        +$num="%r24";	# zapped by $t0
        +
        +$a0 ="%r26";
        +$a1 ="%r25";
        +$t0 ="%r24";
        +$t1 ="%r29";
        +$Tbl="%r31";
        +
        +@V=($A,$B,$C,$D,$E,$F,$G,$H)=("%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r28");
        +
        +@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
        +    "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$inp);
        +
        +sub ROUND_00_15 {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +$code.=<<___;
        +	_ror	$e,$Sigma1[0],$a0
        +	and	$f,$e,$t0
        +	_ror	$e,$Sigma1[1],$a1
        +	addl	$t1,$h,$h
        +	andcm	$g,$e,$t1
        +	xor	$a1,$a0,$a0
        +	_ror	$a1,`$Sigma1[2]-$Sigma1[1]`,$a1
        +	or	$t0,$t1,$t1		; Ch(e,f,g)
        +	addl	@X[$i%16],$h,$h
        +	xor	$a0,$a1,$a1		; Sigma1(e)
        +	addl	$t1,$h,$h
        +	_ror	$a,$Sigma0[0],$a0
        +	addl	$a1,$h,$h
        +
        +	_ror	$a,$Sigma0[1],$a1
        +	and	$a,$b,$t0
        +	and	$a,$c,$t1
        +	xor	$a1,$a0,$a0
        +	_ror	$a1,`$Sigma0[2]-$Sigma0[1]`,$a1
        +	xor	$t1,$t0,$t0
        +	and	$b,$c,$t1
        +	xor	$a0,$a1,$a1		; Sigma0(a)
        +	addl	$h,$d,$d
        +	xor	$t1,$t0,$t0		; Maj(a,b,c)
        +	`"$LDM	$SZ($Tbl),$t1" if ($i<15)`
        +	addl	$a1,$h,$h
        +	addl	$t0,$h,$h
        +
        +___
        +}
        +
        +sub ROUND_16_xx {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +$i-=16;
        +$code.=<<___;
        +	_ror	@X[($i+1)%16],$sigma0[0],$a0
        +	_ror	@X[($i+1)%16],$sigma0[1],$a1
        +	addl	@X[($i+9)%16],@X[$i],@X[$i]
        +	_ror	@X[($i+14)%16],$sigma1[0],$t0
        +	_ror	@X[($i+14)%16],$sigma1[1],$t1
        +	xor	$a1,$a0,$a0
        +	_shr	@X[($i+1)%16],$sigma0[2],$a1
        +	xor	$t1,$t0,$t0
        +	_shr	@X[($i+14)%16],$sigma1[2],$t1
        +	xor	$a1,$a0,$a0		; sigma0(X[(i+1)&0x0f])
        +	xor	$t1,$t0,$t0		; sigma1(X[(i+14)&0x0f])
        +	$LDM	$SZ($Tbl),$t1
        +	addl	$a0,@X[$i],@X[$i]
        +	addl	$t0,@X[$i],@X[$i]
        +___
        +$code.=<<___ if ($i==15);
        +	extru	$t1,31,10,$a1
        +	comiclr,<> $LAST10BITS,$a1,%r0
        +	ldo	1($Tbl),$Tbl		; signal end of $Tbl
        +___
        +&ROUND_00_15($i+16,$a,$b,$c,$d,$e,$f,$g,$h);
        +}
        +
        +$code=<<___;
        +	.LEVEL	$LEVEL
        +	.SPACE	\$TEXT\$
        +	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
        +
        +	.ALIGN	64
        +L\$table
        +___
        +$code.=<<___ if ($SZ==8);
        +	.WORD	0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
        +	.WORD	0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
        +	.WORD	0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
        +	.WORD	0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
        +	.WORD	0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
        +	.WORD	0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
        +	.WORD	0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
        +	.WORD	0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
        +	.WORD	0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
        +	.WORD	0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
        +	.WORD	0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
        +	.WORD	0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
        +	.WORD	0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
        +	.WORD	0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
        +	.WORD	0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
        +	.WORD	0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
        +	.WORD	0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
        +	.WORD	0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
        +	.WORD	0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
        +	.WORD	0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
        +	.WORD	0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
        +	.WORD	0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
        +	.WORD	0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
        +	.WORD	0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
        +	.WORD	0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
        +	.WORD	0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
        +	.WORD	0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
        +	.WORD	0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
        +	.WORD	0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
        +	.WORD	0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
        +	.WORD	0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
        +	.WORD	0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
        +	.WORD	0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
        +	.WORD	0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
        +	.WORD	0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
        +	.WORD	0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
        +	.WORD	0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
        +	.WORD	0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
        +	.WORD	0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
        +	.WORD	0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
        +___
        +$code.=<<___ if ($SZ==4);
        +	.WORD	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +	.WORD	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +	.WORD	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +	.WORD	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +	.WORD	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +	.WORD	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +	.WORD	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +	.WORD	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +	.WORD	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +	.WORD	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +	.WORD	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +	.WORD	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +	.WORD	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +	.WORD	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +	.WORD	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +	.WORD	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        +___
        +$code.=<<___;
        +
        +	.EXPORT	$func,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
        +	.ALIGN	64
        +$func
        +	.PROC
        +	.CALLINFO	FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
        +	.ENTRY
        +	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
        +	$PUSHMA	%r3,$FRAME(%sp)
        +	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
        +	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
        +	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
        +	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
        +	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
        +	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
        +	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
        +	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
        +	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
        +	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
        +	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
        +	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
        +	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
        +	$PUSH	%r17,`-$FRAME+14*$SIZE_T`(%sp)
        +	$PUSH	%r18,`-$FRAME+15*$SIZE_T`(%sp)
        +
        +	_shl	$num,`log(16*$SZ)/log(2)`,$num
        +	addl	$inp,$num,$num		; $num to point at the end of $inp
        +
        +	$PUSH	$num,`-$FRAME_MARKER-4*$SIZE_T`(%sp)	; save arguments
        +	$PUSH	$inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)
        +	$PUSH	$ctx,`-$FRAME_MARKER-2*$SIZE_T`(%sp)
        +
        +	blr	%r0,$Tbl
        +	ldi	3,$t1
        +L\$pic
        +	andcm	$Tbl,$t1,$Tbl		; wipe privilege level
        +	ldo	L\$table-L\$pic($Tbl),$Tbl
        +___
        +$code.=<<___ if ($SZ==8 && $SIZE_T==4);
        +	ldi	31,$t1
        +	mtctl	$t1,%cr11
        +	extrd,u,*= $t1,%sar,1,$t1	; executes on PA-RISC 1.0
        +	b	L\$parisc1
        +	nop
        +___
        +$code.=<<___;
        +	$LD	`0*$SZ`($ctx),$A	; load context
        +	$LD	`1*$SZ`($ctx),$B
        +	$LD	`2*$SZ`($ctx),$C
        +	$LD	`3*$SZ`($ctx),$D
        +	$LD	`4*$SZ`($ctx),$E
        +	$LD	`5*$SZ`($ctx),$F
        +	$LD	`6*$SZ`($ctx),$G
        +	$LD	`7*$SZ`($ctx),$H
        +
        +	extru	$inp,31,`log($SZ)/log(2)`,$t0
        +	sh3addl	$t0,%r0,$t0
        +	subi	`8*$SZ`,$t0,$t0
        +	mtctl	$t0,%cr11		; load %sar with align factor
        +
        +L\$oop
        +	ldi	`$SZ-1`,$t0
        +	$LDM	$SZ($Tbl),$t1
        +	andcm	$inp,$t0,$t0		; align $inp
        +___
        +	for ($i=0;$i<15;$i++) {		# load input block
        +	$code.="\t$LD	`$SZ*$i`($t0),@X[$i]\n";		}
        +$code.=<<___;
        +	cmpb,*=	$inp,$t0,L\$aligned
        +	$LD	`$SZ*15`($t0),@X[15]
        +	$LD	`$SZ*16`($t0),@X[16]
        +___
        +	for ($i=0;$i<16;$i++) {		# align data
        +	$code.="\t_align	@X[$i],@X[$i+1],@X[$i]\n";	}
        +$code.=<<___;
        +L\$aligned
        +	nop	; otherwise /usr/ccs/bin/as is confused by below .WORD
        +___
        +
        +for($i=0;$i<16;$i++)	{ &ROUND_00_15($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +L\$rounds
        +	nop	; otherwise /usr/ccs/bin/as is confused by below .WORD
        +___
        +for(;$i<32;$i++)	{ &ROUND_16_xx($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	bb,>=	$Tbl,31,L\$rounds	; end of $Tbl signalled?
        +	nop
        +
        +	$POP	`-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx	; restore arguments
        +	$POP	`-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp
        +	$POP	`-$FRAME_MARKER-4*$SIZE_T`(%sp),$num
        +	ldo	`-$rounds*$SZ-1`($Tbl),$Tbl		; rewind $Tbl
        +
        +	$LD	`0*$SZ`($ctx),@X[0]	; load context
        +	$LD	`1*$SZ`($ctx),@X[1]
        +	$LD	`2*$SZ`($ctx),@X[2]
        +	$LD	`3*$SZ`($ctx),@X[3]
        +	$LD	`4*$SZ`($ctx),@X[4]
        +	$LD	`5*$SZ`($ctx),@X[5]
        +	addl	@X[0],$A,$A
        +	$LD	`6*$SZ`($ctx),@X[6]
        +	addl	@X[1],$B,$B
        +	$LD	`7*$SZ`($ctx),@X[7]
        +	ldo	`16*$SZ`($inp),$inp	; advance $inp
        +
        +	$ST	$A,`0*$SZ`($ctx)	; save context
        +	addl	@X[2],$C,$C
        +	$ST	$B,`1*$SZ`($ctx)
        +	addl	@X[3],$D,$D
        +	$ST	$C,`2*$SZ`($ctx)
        +	addl	@X[4],$E,$E
        +	$ST	$D,`3*$SZ`($ctx)
        +	addl	@X[5],$F,$F
        +	$ST	$E,`4*$SZ`($ctx)
        +	addl	@X[6],$G,$G
        +	$ST	$F,`5*$SZ`($ctx)
        +	addl	@X[7],$H,$H
        +	$ST	$G,`6*$SZ`($ctx)
        +	$ST	$H,`7*$SZ`($ctx)
        +
        +	cmpb,*<>,n $inp,$num,L\$oop
        +	$PUSH	$inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)	; save $inp
        +___
        +if ($SZ==8 && $SIZE_T==4)	# SHA512 for 32-bit PA-RISC 1.0
        +{{
        +$code.=<<___;
        +	b	L\$done
        +	nop
        +
        +	.ALIGN	64
        +L\$parisc1
        +___
        +
        +@V=(  $Ahi,  $Alo,  $Bhi,  $Blo,  $Chi,  $Clo,  $Dhi,  $Dlo,
        +      $Ehi,  $Elo,  $Fhi,  $Flo,  $Ghi,  $Glo,  $Hhi,  $Hlo) = 
        +   ( "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
        +     "%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16");
        +$a0 ="%r17";
        +$a1 ="%r18";
        +$a2 ="%r19";
        +$a3 ="%r20";
        +$t0 ="%r21";
        +$t1 ="%r22";
        +$t2 ="%r28";
        +$t3 ="%r29";
        +$Tbl="%r31";
        +
        +@X=("%r23","%r24","%r25","%r26");	# zaps $num,$inp,$ctx
        +
        +sub ROUND_00_15_pa1 {
        +my ($i,$ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo,
        +       $ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo,$flag)=@_;
        +my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X;
        +
        +$code.=<<___ if (!$flag);
        +	ldw	`-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi
        +	ldw	`-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo	; load X[i+1]
        +___
        +$code.=<<___;
        +	shd	$ehi,$elo,$Sigma1[0],$t0
        +	 add	$Xlo,$hlo,$hlo
        +	shd	$elo,$ehi,$Sigma1[0],$t1
        +	 addc	$Xhi,$hhi,$hhi		; h += X[i]
        +	shd	$ehi,$elo,$Sigma1[1],$t2
        +	 ldwm	8($Tbl),$Xhi
        +	shd	$elo,$ehi,$Sigma1[1],$t3
        +	 ldw	-4($Tbl),$Xlo		; load K[i]
        +	xor	$t2,$t0,$t0
        +	xor	$t3,$t1,$t1
        +	 and	$flo,$elo,$a0
        +	 and	$fhi,$ehi,$a1
        +	shd	$ehi,$elo,$Sigma1[2],$t2
        +	 andcm	$glo,$elo,$a2
        +	shd	$elo,$ehi,$Sigma1[2],$t3
        +	 andcm	$ghi,$ehi,$a3
        +	xor	$t2,$t0,$t0
        +	xor	$t3,$t1,$t1		; Sigma1(e)
        +	add	$Xlo,$hlo,$hlo
        +	 xor	$a2,$a0,$a0
        +	addc	$Xhi,$hhi,$hhi		; h += K[i]
        +	 xor	$a3,$a1,$a1		; Ch(e,f,g)
        +
        +	 add	$t0,$hlo,$hlo
        +	shd	$ahi,$alo,$Sigma0[0],$t0
        +	 addc	$t1,$hhi,$hhi		; h += Sigma1(e)
        +	shd	$alo,$ahi,$Sigma0[0],$t1	
        +	 add	$a0,$hlo,$hlo
        +	shd	$ahi,$alo,$Sigma0[1],$t2
        +	 addc	$a1,$hhi,$hhi		; h += Ch(e,f,g)
        +	shd	$alo,$ahi,$Sigma0[1],$t3
        +
        +	xor	$t2,$t0,$t0
        +	xor	$t3,$t1,$t1
        +	shd	$ahi,$alo,$Sigma0[2],$t2
        +	and	$alo,$blo,$a0
        +	shd	$alo,$ahi,$Sigma0[2],$t3
        +	and	$ahi,$bhi,$a1
        +	xor	$t2,$t0,$t0
        +	xor	$t3,$t1,$t1		; Sigma0(a)
        +
        +	and	$alo,$clo,$a2
        +	and	$ahi,$chi,$a3
        +	xor	$a2,$a0,$a0
        +	 add	$hlo,$dlo,$dlo
        +	xor	$a3,$a1,$a1
        +	 addc	$hhi,$dhi,$dhi		; d += h
        +	and	$blo,$clo,$a2
        +	 add	$t0,$hlo,$hlo
        +	and	$bhi,$chi,$a3
        +	 addc	$t1,$hhi,$hhi		; h += Sigma0(a)
        +	xor	$a2,$a0,$a0
        +	 add	$a0,$hlo,$hlo
        +	xor	$a3,$a1,$a1		; Maj(a,b,c)
        +	 addc	$a1,$hhi,$hhi		; h += Maj(a,b,c)
        +
        +___
        +$code.=<<___ if ($i==15 && $flag);
        +	extru	$Xlo,31,10,$Xlo
        +	comiclr,= $LAST10BITS,$Xlo,%r0
        +	b	L\$rounds_pa1
        +	nop
        +___
        +push(@X,shift(@X)); push(@X,shift(@X));
        +}
        +
        +sub ROUND_16_xx_pa1 {
        +my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X;
        +my ($i)=shift;
        +$i-=16;
        +$code.=<<___;
        +	ldw	`-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi
        +	ldw	`-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo	; load X[i+1]
        +	ldw	`-$XOFF+8*(($i+9)%16)`(%sp),$a1
        +	ldw	`-$XOFF+8*(($i+9)%16)+4`(%sp),$a0	; load X[i+9]
        +	ldw	`-$XOFF+8*(($i+14)%16)`(%sp),$a3
        +	ldw	`-$XOFF+8*(($i+14)%16)+4`(%sp),$a2	; load X[i+14]
        +	shd	$Xnhi,$Xnlo,$sigma0[0],$t0
        +	shd	$Xnlo,$Xnhi,$sigma0[0],$t1
        +	 add	$a0,$Xlo,$Xlo
        +	shd	$Xnhi,$Xnlo,$sigma0[1],$t2
        +	 addc	$a1,$Xhi,$Xhi
        +	shd	$Xnlo,$Xnhi,$sigma0[1],$t3
        +	xor	$t2,$t0,$t0
        +	shd	$Xnhi,$Xnlo,$sigma0[2],$t2
        +	xor	$t3,$t1,$t1
        +	extru	$Xnhi,`31-$sigma0[2]`,`32-$sigma0[2]`,$t3
        +	xor	$t2,$t0,$t0
        +	 shd	$a3,$a2,$sigma1[0],$a0
        +	xor	$t3,$t1,$t1		; sigma0(X[i+1)&0x0f])
        +	 shd	$a2,$a3,$sigma1[0],$a1
        +	add	$t0,$Xlo,$Xlo
        +	 shd	$a3,$a2,$sigma1[1],$t2
        +	addc	$t1,$Xhi,$Xhi
        +	 shd	$a2,$a3,$sigma1[1],$t3
        +	xor	$t2,$a0,$a0
        +	shd	$a3,$a2,$sigma1[2],$t2
        +	xor	$t3,$a1,$a1
        +	extru	$a3,`31-$sigma1[2]`,`32-$sigma1[2]`,$t3
        +	xor	$t2,$a0,$a0
        +	xor	$t3,$a1,$a1		; sigma0(X[i+14)&0x0f])
        +	add	$a0,$Xlo,$Xlo
        +	addc	$a1,$Xhi,$Xhi
        +
        +	stw	$Xhi,`-$XOFF+8*($i%16)`(%sp)
        +	stw	$Xlo,`-$XOFF+8*($i%16)+4`(%sp)
        +___
        +&ROUND_00_15_pa1($i,@_,1);
        +}
        +$code.=<<___;
        +	ldw	`0*4`($ctx),$Ahi		; load context
        +	ldw	`1*4`($ctx),$Alo
        +	ldw	`2*4`($ctx),$Bhi
        +	ldw	`3*4`($ctx),$Blo
        +	ldw	`4*4`($ctx),$Chi
        +	ldw	`5*4`($ctx),$Clo
        +	ldw	`6*4`($ctx),$Dhi
        +	ldw	`7*4`($ctx),$Dlo
        +	ldw	`8*4`($ctx),$Ehi
        +	ldw	`9*4`($ctx),$Elo
        +	ldw	`10*4`($ctx),$Fhi
        +	ldw	`11*4`($ctx),$Flo
        +	ldw	`12*4`($ctx),$Ghi
        +	ldw	`13*4`($ctx),$Glo
        +	ldw	`14*4`($ctx),$Hhi
        +	ldw	`15*4`($ctx),$Hlo
        +
        +	extru	$inp,31,2,$t0
        +	sh3addl	$t0,%r0,$t0
        +	subi	32,$t0,$t0
        +	mtctl	$t0,%cr11		; load %sar with align factor
        +
        +L\$oop_pa1
        +	extru	$inp,31,2,$a3
        +	comib,=	0,$a3,L\$aligned_pa1
        +	sub	$inp,$a3,$inp
        +
        +	ldw	`0*4`($inp),$X[0]
        +	ldw	`1*4`($inp),$X[1]
        +	ldw	`2*4`($inp),$t2
        +	ldw	`3*4`($inp),$t3
        +	ldw	`4*4`($inp),$a0
        +	ldw	`5*4`($inp),$a1
        +	ldw	`6*4`($inp),$a2
        +	ldw	`7*4`($inp),$a3
        +	vshd	$X[0],$X[1],$X[0]
        +	vshd	$X[1],$t2,$X[1]
        +	stw	$X[0],`-$XOFF+0*4`(%sp)
        +	ldw	`8*4`($inp),$t0
        +	vshd	$t2,$t3,$t2
        +	stw	$X[1],`-$XOFF+1*4`(%sp)
        +	ldw	`9*4`($inp),$t1
        +	vshd	$t3,$a0,$t3
        +___
        +{
        +my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1);
        +for ($i=2;$i<=(128/4-8);$i++) {
        +$code.=<<___;
        +	stw	$t[0],`-$XOFF+$i*4`(%sp)
        +	ldw	`(8+$i)*4`($inp),$t[0]
        +	vshd	$t[1],$t[2],$t[1]
        +___
        +push(@t,shift(@t));
        +}
        +for (;$i<(128/4-1);$i++) {
        +$code.=<<___;
        +	stw	$t[0],`-$XOFF+$i*4`(%sp)
        +	vshd	$t[1],$t[2],$t[1]
        +___
        +push(@t,shift(@t));
        +}
        +$code.=<<___;
        +	b	L\$collected_pa1
        +	stw	$t[0],`-$XOFF+$i*4`(%sp)
        +
        +___
        +}
        +$code.=<<___;
        +L\$aligned_pa1
        +	ldw	`0*4`($inp),$X[0]
        +	ldw	`1*4`($inp),$X[1]
        +	ldw	`2*4`($inp),$t2
        +	ldw	`3*4`($inp),$t3
        +	ldw	`4*4`($inp),$a0
        +	ldw	`5*4`($inp),$a1
        +	ldw	`6*4`($inp),$a2
        +	ldw	`7*4`($inp),$a3
        +	stw	$X[0],`-$XOFF+0*4`(%sp)
        +	ldw	`8*4`($inp),$t0
        +	stw	$X[1],`-$XOFF+1*4`(%sp)
        +	ldw	`9*4`($inp),$t1
        +___
        +{
        +my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1);
        +for ($i=2;$i<(128/4-8);$i++) {
        +$code.=<<___;
        +	stw	$t[0],`-$XOFF+$i*4`(%sp)
        +	ldw	`(8+$i)*4`($inp),$t[0]
        +___
        +push(@t,shift(@t));
        +}
        +for (;$i<128/4;$i++) {
        +$code.=<<___;
        +	stw	$t[0],`-$XOFF+$i*4`(%sp)
        +___
        +push(@t,shift(@t));
        +}
        +$code.="L\$collected_pa1\n";
        +}
        +
        +for($i=0;$i<16;$i++)	{ &ROUND_00_15_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); }
        +$code.="L\$rounds_pa1\n";
        +for(;$i<32;$i++)	{ &ROUND_16_xx_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); }
        +
        +$code.=<<___;
        +	$POP	`-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx	; restore arguments
        +	$POP	`-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp
        +	$POP	`-$FRAME_MARKER-4*$SIZE_T`(%sp),$num
        +	ldo	`-$rounds*$SZ`($Tbl),$Tbl		; rewind $Tbl
        +
        +	ldw	`0*4`($ctx),$t1		; update context
        +	ldw	`1*4`($ctx),$t0
        +	ldw	`2*4`($ctx),$t3
        +	ldw	`3*4`($ctx),$t2
        +	ldw	`4*4`($ctx),$a1
        +	ldw	`5*4`($ctx),$a0
        +	ldw	`6*4`($ctx),$a3
        +	add	$t0,$Alo,$Alo
        +	ldw	`7*4`($ctx),$a2
        +	addc	$t1,$Ahi,$Ahi
        +	ldw	`8*4`($ctx),$t1
        +	add	$t2,$Blo,$Blo
        +	ldw	`9*4`($ctx),$t0
        +	addc	$t3,$Bhi,$Bhi
        +	ldw	`10*4`($ctx),$t3
        +	add	$a0,$Clo,$Clo
        +	ldw	`11*4`($ctx),$t2
        +	addc	$a1,$Chi,$Chi
        +	ldw	`12*4`($ctx),$a1
        +	add	$a2,$Dlo,$Dlo
        +	ldw	`13*4`($ctx),$a0
        +	addc	$a3,$Dhi,$Dhi
        +	ldw	`14*4`($ctx),$a3
        +	add	$t0,$Elo,$Elo
        +	ldw	`15*4`($ctx),$a2
        +	addc	$t1,$Ehi,$Ehi
        +	stw	$Ahi,`0*4`($ctx)
        +	add	$t2,$Flo,$Flo
        +	stw	$Alo,`1*4`($ctx)
        +	addc	$t3,$Fhi,$Fhi
        +	stw	$Bhi,`2*4`($ctx)
        +	add	$a0,$Glo,$Glo
        +	stw	$Blo,`3*4`($ctx)
        +	addc	$a1,$Ghi,$Ghi
        +	stw	$Chi,`4*4`($ctx)
        +	add	$a2,$Hlo,$Hlo
        +	stw	$Clo,`5*4`($ctx)
        +	addc	$a3,$Hhi,$Hhi
        +	stw	$Dhi,`6*4`($ctx)
        +	ldo	`16*$SZ`($inp),$inp	; advance $inp
        +	stw	$Dlo,`7*4`($ctx)
        +	stw	$Ehi,`8*4`($ctx)
        +	stw	$Elo,`9*4`($ctx)
        +	stw	$Fhi,`10*4`($ctx)
        +	stw	$Flo,`11*4`($ctx)
        +	stw	$Ghi,`12*4`($ctx)
        +	stw	$Glo,`13*4`($ctx)
        +	stw	$Hhi,`14*4`($ctx)
        +	comb,=	$inp,$num,L\$done
        +	stw	$Hlo,`15*4`($ctx)
        +	b	L\$oop_pa1
        +	$PUSH	$inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)	; save $inp
        +L\$done
        +___
        +}}
        +$code.=<<___;
        +	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2		; standard epilogue
        +	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
        +	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
        +	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
        +	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
        +	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
        +	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
        +	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
        +	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
        +	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
        +	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
        +	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
        +	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
        +	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
        +	$POP	`-$FRAME+14*$SIZE_T`(%sp),%r17
        +	$POP	`-$FRAME+15*$SIZE_T`(%sp),%r18
        +	bv	(%r2)
        +	.EXIT
        +	$POPMB	-$FRAME(%sp),%r3
        +	.PROCEND
        +	.STRINGZ "SHA`64*$SZ` block transform for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
        +___
        +
        +# Explicitly encode PA-RISC 2.0 instructions used in this module, so
        +# that it can be compiled with .LEVEL 1.0. It should be noted that I
        +# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
        +# directive...
        +
        +my $ldd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "ldd$mod\t$args";
        +
        +    if ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 3 suffices
        +    {	my $opcode=(0x14<<26)|($2<<21)|($3<<16)|(($1&0x1FF8)<<1)|(($1>>13)&1);
        +	$opcode|=(1<<3) if ($mod =~ /^,m/);
        +	$opcode|=(1<<2) if ($mod =~ /^,mb/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $std = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "std$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices
        +    {	my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $extrd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "extrd$mod\t$args";
        +
        +    # I only have ",u" completer, it's implicitly encoded...
        +    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 15
        +    {	my $opcode=(0x36<<26)|($1<<21)|($4<<16);
        +	my $len=32-$3;
        +	$opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5);		# encode pos
        +	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/)	# format 12
        +    {	my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
        +	my $len=32-$2;
        +	$opcode |= (($len&0x20)<<3)|($len&0x1f);		# encode len
        +	$opcode |= (1<<13) if ($mod =~ /,\**=/);
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +my $shrpd = sub {
        +  my ($mod,$args) = @_;
        +  my $orig = "shrpd$mod\t$args";
        +
        +    if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/)	# format 14
        +    {	my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
        +	my $cpos=63-$3;
        +	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode sa
        +	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
        +    }
        +    elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/)	# format 11
        +    {	sprintf "\t.WORD\t0x%08x\t; %s",
        +		(0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig;
        +    }
        +    else { "\t".$orig; }
        +};
        +
        +sub assemble {
        +  my ($mnemonic,$mod,$args)=@_;
        +  my $opcode = eval("\$$mnemonic");
        +
        +    ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
        +}
        +
        +foreach (split("\n",$code)) {
        +	s/\`([^\`]*)\`/eval $1/ge;
        +
        +	s/shd\s+(%r[0-9]+),(%r[0-9]+),([0-9]+)/
        +		$3>31 ? sprintf("shd\t%$2,%$1,%d",$3-32)	# rotation for >=32
        +		:       sprintf("shd\t%$1,%$2,%d",$3)/e			or
        +	# translate made up instructons: _ror, _shr, _align, _shl
        +	s/_ror(\s+)(%r[0-9]+),/
        +		($SZ==4 ? "shd" : "shrpd")."$1$2,$2,"/e			or
        +
        +	s/_shr(\s+%r[0-9]+),([0-9]+),/
        +		$SZ==4 ? sprintf("extru%s,%d,%d,",$1,31-$2,32-$2)
        +		:        sprintf("extrd,u%s,%d,%d,",$1,63-$2,64-$2)/e	or
        +
        +	s/_align(\s+%r[0-9]+,%r[0-9]+),/
        +		($SZ==4 ? "vshd$1," : "shrpd$1,%sar,")/e		or
        +
        +	s/_shl(\s+%r[0-9]+),([0-9]+),/
        +		$SIZE_T==4 ? sprintf("zdep%s,%d,%d,",$1,31-$2,32-$2)
        +		:            sprintf("depd,z%s,%d,%d,",$1,63-$2,64-$2)/e;
        +
        +	s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($SIZE_T==4);
        +
        +	s/cmpb,\*/comb,/ if ($SIZE_T==4);
        +
        +	print $_,"\n";
        +}
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-ppc.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-ppc.pl
        new file mode 100644
        index 000000000..6b44a68e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-ppc.pl
        @@ -0,0 +1,460 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# I let hardware handle unaligned input, except on page boundaries
        +# (see below for details). Otherwise straightforward implementation
        +# with X vector in register bank. The module is big-endian [which is
        +# not big deal as there're no little-endian targets left around].
        +
        +#			sha256		|	sha512
        +# 			-m64	-m32	|	-m64	-m32
        +# --------------------------------------+-----------------------
        +# PPC970,gcc-4.0.0	+50%	+38%	|	+40%	+410%(*)
        +# Power6,xlc-7		+150%	+90%	|	+100%	+430%(*)
        +#
        +# (*)	64-bit code in 32-bit application context, which actually is
        +#	on TODO list. It should be noted that for safe deployment in
        +#	32-bit *mutli-threaded* context asyncronous signals should be
        +#	blocked upon entry to SHA512 block routine. This is because
        +#	32-bit signaling procedure invalidates upper halves of GPRs.
        +#	Context switch procedure preserves them, but not signaling:-(
        +
        +# Second version is true multi-thread safe. Trouble with the original
        +# version was that it was using thread local storage pointer register.
        +# Well, it scrupulously preserved it, but the problem would arise the
        +# moment asynchronous signal was delivered and signal handler would
        +# dereference the TLS pointer. While it's never the case in openssl
        +# application or test suite, we have to respect this scenario and not
        +# use TLS pointer register. Alternative would be to require caller to
        +# block signals prior calling this routine. For the record, in 32-bit
        +# context R2 serves as TLS pointer, while in 64-bit context - R13.
        +
        +$flavour=shift;
        +$output =shift;
        +
        +if ($flavour =~ /64/) {
        +	$SIZE_T=8;
        +	$LRSAVE=2*$SIZE_T;
        +	$STU="stdu";
        +	$UCMP="cmpld";
        +	$SHL="sldi";
        +	$POP="ld";
        +	$PUSH="std";
        +} elsif ($flavour =~ /32/) {
        +	$SIZE_T=4;
        +	$LRSAVE=$SIZE_T;
        +	$STU="stwu";
        +	$UCMP="cmplw";
        +	$SHL="slwi";
        +	$POP="lwz";
        +	$PUSH="stw";
        +} else { die "nonsense $flavour"; }
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
        +die "can't locate ppc-xlate.pl";
        +
        +open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
        +
        +if ($output =~ /512/) {
        +	$func="sha512_block_data_order";
        +	$SZ=8;
        +	@Sigma0=(28,34,39);
        +	@Sigma1=(14,18,41);
        +	@sigma0=(1,  8, 7);
        +	@sigma1=(19,61, 6);
        +	$rounds=80;
        +	$LD="ld";
        +	$ST="std";
        +	$ROR="rotrdi";
        +	$SHR="srdi";
        +} else {
        +	$func="sha256_block_data_order";
        +	$SZ=4;
        +	@Sigma0=( 2,13,22);
        +	@Sigma1=( 6,11,25);
        +	@sigma0=( 7,18, 3);
        +	@sigma1=(17,19,10);
        +	$rounds=64;
        +	$LD="lwz";
        +	$ST="stw";
        +	$ROR="rotrwi";
        +	$SHR="srwi";
        +}
        +
        +$FRAME=32*$SIZE_T+16*$SZ;
        +$LOCALS=6*$SIZE_T;
        +
        +$sp ="r1";
        +$toc="r2";
        +$ctx="r3";	# zapped by $a0
        +$inp="r4";	# zapped by $a1
        +$num="r5";	# zapped by $t0
        +
        +$T  ="r0";
        +$a0 ="r3";
        +$a1 ="r4";
        +$t0 ="r5";
        +$t1 ="r6";
        +$Tbl="r7";
        +
        +$A  ="r8";
        +$B  ="r9";
        +$C  ="r10";
        +$D  ="r11";
        +$E  ="r12";
        +$F  ="r13";	$F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer
        +$G  ="r14";
        +$H  ="r15";
        +
        +@V=($A,$B,$C,$D,$E,$F,$G,$H);
        +@X=("r16","r17","r18","r19","r20","r21","r22","r23",
        +    "r24","r25","r26","r27","r28","r29","r30","r31");
        +
        +$inp="r31";	# reassigned $inp! aliases with @X[15]
        +
        +sub ROUND_00_15 {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +$code.=<<___;
        +	$LD	$T,`$i*$SZ`($Tbl)
        +	$ROR	$a0,$e,$Sigma1[0]
        +	$ROR	$a1,$e,$Sigma1[1]
        +	and	$t0,$f,$e
        +	andc	$t1,$g,$e
        +	add	$T,$T,$h
        +	xor	$a0,$a0,$a1
        +	$ROR	$a1,$a1,`$Sigma1[2]-$Sigma1[1]`
        +	or	$t0,$t0,$t1		; Ch(e,f,g)
        +	add	$T,$T,@X[$i]
        +	xor	$a0,$a0,$a1		; Sigma1(e)
        +	add	$T,$T,$t0
        +	add	$T,$T,$a0
        +
        +	$ROR	$a0,$a,$Sigma0[0]
        +	$ROR	$a1,$a,$Sigma0[1]
        +	and	$t0,$a,$b
        +	and	$t1,$a,$c
        +	xor	$a0,$a0,$a1
        +	$ROR	$a1,$a1,`$Sigma0[2]-$Sigma0[1]`
        +	xor	$t0,$t0,$t1
        +	and	$t1,$b,$c
        +	xor	$a0,$a0,$a1		; Sigma0(a)
        +	add	$d,$d,$T
        +	xor	$t0,$t0,$t1		; Maj(a,b,c)
        +	add	$h,$T,$a0
        +	add	$h,$h,$t0
        +
        +___
        +}
        +
        +sub ROUND_16_xx {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +$i-=16;
        +$code.=<<___;
        +	$ROR	$a0,@X[($i+1)%16],$sigma0[0]
        +	$ROR	$a1,@X[($i+1)%16],$sigma0[1]
        +	$ROR	$t0,@X[($i+14)%16],$sigma1[0]
        +	$ROR	$t1,@X[($i+14)%16],$sigma1[1]
        +	xor	$a0,$a0,$a1
        +	$SHR	$a1,@X[($i+1)%16],$sigma0[2]
        +	xor	$t0,$t0,$t1
        +	$SHR	$t1,@X[($i+14)%16],$sigma1[2]
        +	add	@X[$i],@X[$i],@X[($i+9)%16]
        +	xor	$a0,$a0,$a1		; sigma0(X[(i+1)&0x0f])
        +	xor	$t0,$t0,$t1		; sigma1(X[(i+14)&0x0f])
        +	add	@X[$i],@X[$i],$a0
        +	add	@X[$i],@X[$i],$t0
        +___
        +&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h);
        +}
        +
        +$code=<<___;
        +.machine	"any"
        +.text
        +
        +.globl	$func
        +.align	6
        +$func:
        +	$STU	$sp,-$FRAME($sp)
        +	mflr	r0
        +	$SHL	$num,$num,`log(16*$SZ)/log(2)`
        +
        +	$PUSH	$ctx,`$FRAME-$SIZE_T*22`($sp)
        +
        +	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
        +	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
        +	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
        +	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
        +	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
        +
        +	$LD	$A,`0*$SZ`($ctx)
        +	mr	$inp,r4				; incarnate $inp
        +	$LD	$B,`1*$SZ`($ctx)
        +	$LD	$C,`2*$SZ`($ctx)
        +	$LD	$D,`3*$SZ`($ctx)
        +	$LD	$E,`4*$SZ`($ctx)
        +	$LD	$F,`5*$SZ`($ctx)
        +	$LD	$G,`6*$SZ`($ctx)
        +	$LD	$H,`7*$SZ`($ctx)
        +
        +	bl	LPICmeup
        +LPICedup:
        +	andi.	r0,$inp,3
        +	bne	Lunaligned
        +Laligned:
        +	add	$num,$inp,$num
        +	$PUSH	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
        +	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
        +	bl	Lsha2_block_private
        +	b	Ldone
        +
        +; PowerPC specification allows an implementation to be ill-behaved
        +; upon unaligned access which crosses page boundary. "Better safe
        +; than sorry" principle makes me treat it specially. But I don't
        +; look for particular offending word, but rather for the input
        +; block which crosses the boundary. Once found that block is aligned
        +; and hashed separately...
        +.align	4
        +Lunaligned:
        +	subfic	$t1,$inp,4096
        +	andi.	$t1,$t1,`4096-16*$SZ`	; distance to closest page boundary
        +	beq	Lcross_page
        +	$UCMP	$num,$t1
        +	ble-	Laligned		; didn't cross the page boundary
        +	subfc	$num,$t1,$num
        +	add	$t1,$inp,$t1
        +	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real remaining num
        +	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; intermediate end pointer
        +	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
        +	bl	Lsha2_block_private
        +	; $inp equals to the intermediate end pointer here
        +	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real remaining num
        +Lcross_page:
        +	li	$t1,`16*$SZ/4`
        +	mtctr	$t1
        +	addi	r20,$sp,$LOCALS			; aligned spot below the frame
        +Lmemcpy:
        +	lbz	r16,0($inp)
        +	lbz	r17,1($inp)
        +	lbz	r18,2($inp)
        +	lbz	r19,3($inp)
        +	addi	$inp,$inp,4
        +	stb	r16,0(r20)
        +	stb	r17,1(r20)
        +	stb	r18,2(r20)
        +	stb	r19,3(r20)
        +	addi	r20,r20,4
        +	bdnz	Lmemcpy
        +
        +	$PUSH	$inp,`$FRAME-$SIZE_T*26`($sp)	; save real inp
        +	addi	$t1,$sp,`$LOCALS+16*$SZ`	; fictitious end pointer
        +	addi	$inp,$sp,$LOCALS		; fictitious inp pointer
        +	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real num
        +	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; end pointer
        +	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
        +	bl	Lsha2_block_private
        +	$POP	$inp,`$FRAME-$SIZE_T*26`($sp)	; restore real inp
        +	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real num
        +	addic.	$num,$num,`-16*$SZ`		; num--
        +	bne-	Lunaligned
        +
        +Ldone:
        +	$POP	r0,`$FRAME+$LRSAVE`($sp)
        +	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
        +	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
        +	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
        +	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
        +	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
        +	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
        +	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
        +	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
        +	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
        +	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
        +	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
        +	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
        +	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
        +	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
        +	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
        +	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
        +	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
        +	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
        +	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
        +	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
        +	mtlr	r0
        +	addi	$sp,$sp,$FRAME
        +	blr
        +	.long	0
        +	.byte	0,12,4,1,0x80,18,3,0
        +	.long	0
        +
        +.align	4
        +Lsha2_block_private:
        +___
        +for($i=0;$i<16;$i++) {
        +$code.=<<___ if ($SZ==4);
        +	lwz	@X[$i],`$i*$SZ`($inp)
        +___
        +# 64-bit loads are split to 2x32-bit ones, as CPU can't handle
        +# unaligned 64-bit loads, only 32-bit ones...
        +$code.=<<___ if ($SZ==8);
        +	lwz	$t0,`$i*$SZ`($inp)
        +	lwz	@X[$i],`$i*$SZ+4`($inp)
        +	insrdi	@X[$i],$t0,32,0
        +___
        +	&ROUND_00_15($i,@V);
        +	unshift(@V,pop(@V));
        +}
        +$code.=<<___;
        +	li	$T,`$rounds/16-1`
        +	mtctr	$T
        +.align	4
        +Lrounds:
        +	addi	$Tbl,$Tbl,`16*$SZ`
        +___
        +for(;$i<32;$i++) {
        +	&ROUND_16_xx($i,@V);
        +	unshift(@V,pop(@V));
        +}
        +$code.=<<___;
        +	bdnz-	Lrounds
        +
        +	$POP	$ctx,`$FRAME-$SIZE_T*22`($sp)
        +	$POP	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
        +	$POP	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
        +	subi	$Tbl,$Tbl,`($rounds-16)*$SZ`	; rewind Tbl
        +
        +	$LD	r16,`0*$SZ`($ctx)
        +	$LD	r17,`1*$SZ`($ctx)
        +	$LD	r18,`2*$SZ`($ctx)
        +	$LD	r19,`3*$SZ`($ctx)
        +	$LD	r20,`4*$SZ`($ctx)
        +	$LD	r21,`5*$SZ`($ctx)
        +	$LD	r22,`6*$SZ`($ctx)
        +	addi	$inp,$inp,`16*$SZ`		; advance inp
        +	$LD	r23,`7*$SZ`($ctx)
        +	add	$A,$A,r16
        +	add	$B,$B,r17
        +	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)
        +	add	$C,$C,r18
        +	$ST	$A,`0*$SZ`($ctx)
        +	add	$D,$D,r19
        +	$ST	$B,`1*$SZ`($ctx)
        +	add	$E,$E,r20
        +	$ST	$C,`2*$SZ`($ctx)
        +	add	$F,$F,r21
        +	$ST	$D,`3*$SZ`($ctx)
        +	add	$G,$G,r22
        +	$ST	$E,`4*$SZ`($ctx)
        +	add	$H,$H,r23
        +	$ST	$F,`5*$SZ`($ctx)
        +	$ST	$G,`6*$SZ`($ctx)
        +	$UCMP	$inp,$num
        +	$ST	$H,`7*$SZ`($ctx)
        +	bne	Lsha2_block_private
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +___
        +
        +# Ugly hack here, because PPC assembler syntax seem to vary too
        +# much from platforms to platform...
        +$code.=<<___;
        +.align	6
        +LPICmeup:
        +	mflr	r0
        +	bcl	20,31,\$+4
        +	mflr	$Tbl	; vvvvvv "distance" between . and 1st data entry
        +	addi	$Tbl,$Tbl,`64-8`
        +	mtlr	r0
        +	blr
        +	.long	0
        +	.byte	0,12,0x14,0,0,0,0,0
        +	.space	`64-9*4`
        +___
        +$code.=<<___ if ($SZ==8);
        +	.long	0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
        +	.long	0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
        +	.long	0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
        +	.long	0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
        +	.long	0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
        +	.long	0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
        +	.long	0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
        +	.long	0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
        +	.long	0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
        +	.long	0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
        +	.long	0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
        +	.long	0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
        +	.long	0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
        +	.long	0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
        +	.long	0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
        +	.long	0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
        +	.long	0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
        +	.long	0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
        +	.long	0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
        +	.long	0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
        +	.long	0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
        +	.long	0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
        +	.long	0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
        +	.long	0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
        +	.long	0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
        +	.long	0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
        +	.long	0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
        +	.long	0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
        +	.long	0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
        +	.long	0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
        +	.long	0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
        +	.long	0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
        +	.long	0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
        +	.long	0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
        +	.long	0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
        +	.long	0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
        +	.long	0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
        +	.long	0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
        +	.long	0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
        +	.long	0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
        +___
        +$code.=<<___ if ($SZ==4);
        +	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-s390x.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-s390x.pl
        new file mode 100644
        index 000000000..079a3fc78
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-s390x.pl
        @@ -0,0 +1,322 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA256/512 block procedures for s390x.
        +
        +# April 2007.
        +#
        +# sha256_block_data_order is reportedly >3 times faster than gcc 3.3
        +# generated code (must be a bug in compiler, as improvement is
        +# "pathologically" high, in particular in comparison to other SHA
        +# modules). But the real twist is that it detects if hardware support
        +# for SHA256 is available and in such case utilizes it. Then the
        +# performance can reach >6.5x of assembler one for larger chunks.
        +#
        +# sha512_block_data_order is ~70% faster than gcc 3.3 generated code.
        +
        +# January 2009.
        +#
        +# Add support for hardware SHA512 and reschedule instructions to
        +# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster
        +# than software.
        +
        +# November 2010.
        +#
        +# Adapt for -m31 build. If kernel supports what's called "highgprs"
        +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
        +# instructions and achieve "64-bit" performance even in 31-bit legacy
        +# application context. The feature is not specific to any particular
        +# processor, as long as it's "z-CPU". Latter implies that the code
        +# remains z/Architecture specific. On z900 SHA256 was measured to
        +# perform 2.4x and SHA512 - 13x better than code generated by gcc 4.3.
        +
        +$flavour = shift;
        +
        +if ($flavour =~ /3[12]/) {
        +	$SIZE_T=4;
        +	$g="";
        +} else {
        +	$SIZE_T=8;
        +	$g="g";
        +}
        +
        +$t0="%r0";
        +$t1="%r1";
        +$ctx="%r2";	$t2="%r2";
        +$inp="%r3";
        +$len="%r4";	# used as index in inner loop
        +
        +$A="%r5";
        +$B="%r6";
        +$C="%r7";
        +$D="%r8";
        +$E="%r9";
        +$F="%r10";
        +$G="%r11";
        +$H="%r12";	@V=($A,$B,$C,$D,$E,$F,$G,$H);
        +$tbl="%r13";
        +$T1="%r14";
        +$sp="%r15";
        +
        +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
        +open STDOUT,">$output";
        +
        +if ($output =~ /512/) {
        +	$label="512";
        +	$SZ=8;
        +	$LD="lg";	# load from memory
        +	$ST="stg";	# store to memory
        +	$ADD="alg";	# add with memory operand
        +	$ROT="rllg";	# rotate left
        +	$SHR="srlg";	# logical right shift [see even at the end]
        +	@Sigma0=(25,30,36);
        +	@Sigma1=(23,46,50);
        +	@sigma0=(56,63, 7);
        +	@sigma1=( 3,45, 6);
        +	$rounds=80;
        +	$kimdfunc=3;	# 0 means unknown/unsupported/unimplemented/disabled
        +} else {
        +	$label="256";
        +	$SZ=4;
        +	$LD="llgf";	# load from memory
        +	$ST="st";	# store to memory
        +	$ADD="al";	# add with memory operand
        +	$ROT="rll";	# rotate left
        +	$SHR="srl";	# logical right shift
        +	@Sigma0=(10,19,30);
        +	@Sigma1=( 7,21,26);
        +	@sigma0=(14,25, 3);
        +	@sigma1=(13,15,10);
        +	$rounds=64;
        +	$kimdfunc=2;	# magic function code for kimd instruction
        +}
        +$Func="sha${label}_block_data_order";
        +$Table="K${label}";
        +$stdframe=16*$SIZE_T+4*8;
        +$frame=$stdframe+16*$SZ;
        +
        +sub BODY_00_15 {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
        +
        +$code.=<<___ if ($i<16);
        +	$LD	$T1,`$i*$SZ`($inp)	### $i
        +___
        +$code.=<<___;
        +	$ROT	$t0,$e,$Sigma1[0]
        +	$ROT	$t1,$e,$Sigma1[1]
        +	 lgr	$t2,$f
        +	xgr	$t0,$t1
        +	$ROT	$t1,$t1,`$Sigma1[2]-$Sigma1[1]`
        +	 xgr	$t2,$g
        +	$ST	$T1,`$stdframe+$SZ*($i%16)`($sp)
        +	xgr	$t0,$t1			# Sigma1(e)
        +	algr	$T1,$h			# T1+=h
        +	 ngr	$t2,$e
        +	 lgr	$t1,$a
        +	algr	$T1,$t0			# T1+=Sigma1(e)
        +	$ROT	$h,$a,$Sigma0[0]
        +	 xgr	$t2,$g			# Ch(e,f,g)
        +	$ADD	$T1,`$i*$SZ`($len,$tbl)	# T1+=K[i]
        +	$ROT	$t0,$a,$Sigma0[1]
        +	algr	$T1,$t2			# T1+=Ch(e,f,g)
        +	 ogr	$t1,$b
        +	xgr	$h,$t0
        +	 lgr	$t2,$a
        +	 ngr	$t1,$c
        +	$ROT	$t0,$t0,`$Sigma0[2]-$Sigma0[1]`
        +	xgr	$h,$t0			# h=Sigma0(a)
        +	 ngr	$t2,$b
        +	algr	$h,$T1			# h+=T1
        +	 ogr	$t2,$t1			# Maj(a,b,c)
        +	algr	$d,$T1			# d+=T1
        +	algr	$h,$t2			# h+=Maj(a,b,c)
        +___
        +}
        +
        +sub BODY_16_XX {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
        +
        +$code.=<<___;
        +	$LD	$T1,`$stdframe+$SZ*(($i+1)%16)`($sp)	### $i
        +	$LD	$t1,`$stdframe+$SZ*(($i+14)%16)`($sp)
        +	$ROT	$t0,$T1,$sigma0[0]
        +	$SHR	$T1,$sigma0[2]
        +	$ROT	$t2,$t0,`$sigma0[1]-$sigma0[0]`
        +	xgr	$T1,$t0
        +	$ROT	$t0,$t1,$sigma1[0]
        +	xgr	$T1,$t2					# sigma0(X[i+1])
        +	$SHR	$t1,$sigma1[2]
        +	$ADD	$T1,`$stdframe+$SZ*($i%16)`($sp)	# +=X[i]
        +	xgr	$t1,$t0
        +	$ROT	$t0,$t0,`$sigma1[1]-$sigma1[0]`
        +	$ADD	$T1,`$stdframe+$SZ*(($i+9)%16)`($sp)	# +=X[i+9]
        +	xgr	$t1,$t0				# sigma1(X[i+14])
        +	algr	$T1,$t1				# +=sigma1(X[i+14])
        +___
        +	&BODY_00_15(@_);
        +}
        +
        +$code.=<<___;
        +.text
        +.align	64
        +.type	$Table,\@object
        +$Table:
        +___
        +$code.=<<___ if ($SZ==4);
        +	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        +___
        +$code.=<<___ if ($SZ==8);
        +	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
        +	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
        +	.quad	0x3956c25bf348b538,0x59f111f1b605d019
        +	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
        +	.quad	0xd807aa98a3030242,0x12835b0145706fbe
        +	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
        +	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
        +	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
        +	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
        +	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
        +	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
        +	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
        +	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
        +	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
        +	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
        +	.quad	0x06ca6351e003826f,0x142929670a0e6e70
        +	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
        +	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
        +	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
        +	.quad	0x81c2c92e47edaee6,0x92722c851482353b
        +	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
        +	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
        +	.quad	0xd192e819d6ef5218,0xd69906245565a910
        +	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
        +	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
        +	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
        +	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
        +	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
        +	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
        +	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
        +	.quad	0x90befffa23631e28,0xa4506cebde82bde9
        +	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
        +	.quad	0xca273eceea26619c,0xd186b8c721c0c207
        +	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
        +	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
        +	.quad	0x113f9804bef90dae,0x1b710b35131c471b
        +	.quad	0x28db77f523047d84,0x32caab7b40c72493
        +	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
        +	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
        +	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
        +___
        +$code.=<<___;
        +.size	$Table,.-$Table
        +.globl	$Func
        +.type	$Func,\@function
        +$Func:
        +	sllg	$len,$len,`log(16*$SZ)/log(2)`
        +___
        +$code.=<<___ if ($kimdfunc);
        +	larl	%r1,OPENSSL_s390xcap_P
        +	lg	%r0,0(%r1)
        +	tmhl	%r0,0x4000	# check for message-security assist
        +	jz	.Lsoftware
        +	lghi	%r0,0
        +	la	%r1,`2*$SIZE_T`($sp)
        +	.long	0xb93e0002	# kimd %r0,%r2
        +	lg	%r0,`2*$SIZE_T`($sp)
        +	tmhh	%r0,`0x8000>>$kimdfunc`
        +	jz	.Lsoftware
        +	lghi	%r0,$kimdfunc
        +	lgr	%r1,$ctx
        +	lgr	%r2,$inp
        +	lgr	%r3,$len
        +	.long	0xb93e0002	# kimd %r0,%r2
        +	brc	1,.-4		# pay attention to "partial completion"
        +	br	%r14
        +.align	16
        +.Lsoftware:
        +___
        +$code.=<<___;
        +	lghi	%r1,-$frame
        +	la	$len,0($len,$inp)
        +	stm${g}	$ctx,%r15,`2*$SIZE_T`($sp)
        +	lgr	%r0,$sp
        +	la	$sp,0(%r1,$sp)
        +	st${g}	%r0,0($sp)
        +
        +	larl	$tbl,$Table
        +	$LD	$A,`0*$SZ`($ctx)
        +	$LD	$B,`1*$SZ`($ctx)
        +	$LD	$C,`2*$SZ`($ctx)
        +	$LD	$D,`3*$SZ`($ctx)
        +	$LD	$E,`4*$SZ`($ctx)
        +	$LD	$F,`5*$SZ`($ctx)
        +	$LD	$G,`6*$SZ`($ctx)
        +	$LD	$H,`7*$SZ`($ctx)
        +
        +.Lloop:
        +	lghi	$len,0
        +___
        +for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
        +$code.=".Lrounds_16_xx:\n";
        +for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	aghi	$len,`16*$SZ`
        +	lghi	$t0,`($rounds-16)*$SZ`
        +	clgr	$len,$t0
        +	jne	.Lrounds_16_xx
        +
        +	l${g}	$ctx,`$frame+2*$SIZE_T`($sp)
        +	la	$inp,`16*$SZ`($inp)
        +	$ADD	$A,`0*$SZ`($ctx)
        +	$ADD	$B,`1*$SZ`($ctx)
        +	$ADD	$C,`2*$SZ`($ctx)
        +	$ADD	$D,`3*$SZ`($ctx)
        +	$ADD	$E,`4*$SZ`($ctx)
        +	$ADD	$F,`5*$SZ`($ctx)
        +	$ADD	$G,`6*$SZ`($ctx)
        +	$ADD	$H,`7*$SZ`($ctx)
        +	$ST	$A,`0*$SZ`($ctx)
        +	$ST	$B,`1*$SZ`($ctx)
        +	$ST	$C,`2*$SZ`($ctx)
        +	$ST	$D,`3*$SZ`($ctx)
        +	$ST	$E,`4*$SZ`($ctx)
        +	$ST	$F,`5*$SZ`($ctx)
        +	$ST	$G,`6*$SZ`($ctx)
        +	$ST	$H,`7*$SZ`($ctx)
        +	cl${g}	$inp,`$frame+4*$SIZE_T`($sp)
        +	jne	.Lloop
        +
        +	lm${g}	%r6,%r15,`$frame+6*$SIZE_T`($sp)	
        +	br	%r14
        +.size	$Func,.-$Func
        +.string	"SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
        +.comm	OPENSSL_s390xcap_P,16,8
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +# unlike 32-bit shift 64-bit one takes three arguments
        +$code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm;
        +
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl
        new file mode 100644
        index 000000000..585740789
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-sparcv9.pl
        @@ -0,0 +1,594 @@
        +#!/usr/bin/env perl
        +
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. The module is, however, dual licensed under OpenSSL and
        +# CRYPTOGAMS licenses depending on where you obtain it. For further
        +# details see http://www.openssl.org/~appro/cryptogams/.
        +# ====================================================================
        +
        +# SHA256 performance improvement over compiler generated code varies
        +# from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit
        +# build]. Just like in SHA1 module I aim to ensure scalability on
        +# UltraSPARC T1 by packing X[16] to 8 64-bit registers.
        +
        +# SHA512 on pre-T1 UltraSPARC.
        +#
        +# Performance is >75% better than 64-bit code generated by Sun C and
        +# over 2x than 32-bit code. X[16] resides on stack, but access to it
        +# is scheduled for L2 latency and staged through 32 least significant
        +# bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI
        +# duality. Nevetheless it's ~40% faster than SHA256, which is pretty
        +# good [optimal coefficient is 50%].
        +#
        +# SHA512 on UltraSPARC T1.
        +#
        +# It's not any faster than 64-bit code generated by Sun C 5.8. This is
        +# because 64-bit code generator has the advantage of using 64-bit
        +# loads(*) to access X[16], which I consciously traded for 32-/64-bit
        +# ABI duality [as per above]. But it surpasses 32-bit Sun C generated
        +# code by 60%, not to mention that it doesn't suffer from severe decay
        +# when running 4 times physical cores threads and that it leaves gcc
        +# [3.4] behind by over 4x factor! If compared to SHA256, single thread
        +# performance is only 10% better, but overall throughput for maximum
        +# amount of threads for given CPU exceeds corresponding one of SHA256
        +# by 30% [again, optimal coefficient is 50%].
        +#
        +# (*)	Unlike pre-T1 UltraSPARC loads on T1 are executed strictly
        +#	in-order, i.e. load instruction has to complete prior next
        +#	instruction in given thread is executed, even if the latter is
        +#	not dependent on load result! This means that on T1 two 32-bit
        +#	loads are always slower than one 64-bit load. Once again this
        +#	is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
        +#	2x32-bit loads can be as fast as 1x64-bit ones.
        +
        +$bits=32;
        +for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
        +if ($bits==64)	{ $bias=2047; $frame=192; }
        +else		{ $bias=0;    $frame=112; }
        +
        +$output=shift;
        +open STDOUT,">$output";
        +
        +if ($output =~ /512/) {
        +	$label="512";
        +	$SZ=8;
        +	$LD="ldx";		# load from memory
        +	$ST="stx";		# store to memory
        +	$SLL="sllx";		# shift left logical
        +	$SRL="srlx";		# shift right logical
        +	@Sigma0=(28,34,39);
        +	@Sigma1=(14,18,41);
        +	@sigma0=( 7, 1, 8);	# right shift first
        +	@sigma1=( 6,19,61);	# right shift first
        +	$lastK=0x817;
        +	$rounds=80;
        +	$align=4;
        +
        +	$locals=16*$SZ;		# X[16]
        +
        +	$A="%o0";
        +	$B="%o1";
        +	$C="%o2";
        +	$D="%o3";
        +	$E="%o4";
        +	$F="%o5";
        +	$G="%g1";
        +	$H="%o7";
        +	@V=($A,$B,$C,$D,$E,$F,$G,$H);
        +} else {
        +	$label="256";
        +	$SZ=4;
        +	$LD="ld";		# load from memory
        +	$ST="st";		# store to memory
        +	$SLL="sll";		# shift left logical
        +	$SRL="srl";		# shift right logical
        +	@Sigma0=( 2,13,22);
        +	@Sigma1=( 6,11,25);
        +	@sigma0=( 3, 7,18);	# right shift first
        +	@sigma1=(10,17,19);	# right shift first
        +	$lastK=0x8f2;
        +	$rounds=64;
        +	$align=8;
        +
        +	$locals=0;		# X[16] is register resident
        +	@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
        +	
        +	$A="%l0";
        +	$B="%l1";
        +	$C="%l2";
        +	$D="%l3";
        +	$E="%l4";
        +	$F="%l5";
        +	$G="%l6";
        +	$H="%l7";
        +	@V=($A,$B,$C,$D,$E,$F,$G,$H);
        +}
        +$T1="%g2";
        +$tmp0="%g3";
        +$tmp1="%g4";
        +$tmp2="%g5";
        +
        +$ctx="%i0";
        +$inp="%i1";
        +$len="%i2";
        +$Ktbl="%i3";
        +$tmp31="%i4";
        +$tmp32="%i5";
        +
        +########### SHA256
        +$Xload = sub {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +
        +    if ($i==0) {
        +$code.=<<___;
        +	ldx	[$inp+0],@X[0]
        +	ldx	[$inp+16],@X[2]
        +	ldx	[$inp+32],@X[4]
        +	ldx	[$inp+48],@X[6]
        +	ldx	[$inp+8],@X[1]
        +	ldx	[$inp+24],@X[3]
        +	subcc	%g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too
        +	ldx	[$inp+40],@X[5]
        +	bz,pt	%icc,.Laligned
        +	ldx	[$inp+56],@X[7]
        +
        +	sllx	@X[0],$tmp31,@X[0]
        +	ldx	[$inp+64],$T1
        +___
        +for($j=0;$j<7;$j++)
        +{   $code.=<<___;
        +	srlx	@X[$j+1],$tmp32,$tmp1
        +	sllx	@X[$j+1],$tmp31,@X[$j+1]
        +	or	$tmp1,@X[$j],@X[$j]
        +___
        +}
        +$code.=<<___;
        +	srlx	$T1,$tmp32,$T1
        +	or	$T1,@X[7],@X[7]
        +.Laligned:
        +___
        +    }
        +
        +    if ($i&1) {
        +	$code.="\tadd	@X[$i/2],$h,$T1\n";
        +    } else {
        +	$code.="\tsrlx	@X[$i/2],32,$T1\n\tadd	$h,$T1,$T1\n";
        +    }
        +} if ($SZ==4);
        +
        +########### SHA512
        +$Xload = sub {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8));
        +
        +$code.=<<___ if ($i==0);
        +	ld	[$inp+0],%l0
        +	ld	[$inp+4],%l1
        +	ld	[$inp+8],%l2
        +	ld	[$inp+12],%l3
        +	ld	[$inp+16],%l4
        +	ld	[$inp+20],%l5
        +	ld	[$inp+24],%l6
        +	ld	[$inp+28],%l7
        +___
        +$code.=<<___ if ($i<15);
        +	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
        +	add	$tmp31,32,$tmp0
        +	sllx	@pair[0],$tmp0,$tmp1
        +	`"ld	[$inp+".eval(32+0+$i*8)."],@pair[0]"	if ($i<12)`
        +	srlx	@pair[2],$tmp32,@pair[1]
        +	or	$tmp1,$tmp2,$tmp2
        +	or	@pair[1],$tmp2,$tmp2
        +	`"ld	[$inp+".eval(32+4+$i*8)."],@pair[1]"	if ($i<12)`
        +	add	$h,$tmp2,$T1
        +	$ST	$tmp2,[%sp+`$bias+$frame+$i*$SZ`]
        +___
        +$code.=<<___ if ($i==12);
        +	brnz,a	$tmp31,.+8
        +	ld	[$inp+128],%l0
        +___
        +$code.=<<___ if ($i==15);
        +	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
        +	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
        +	add	$tmp31,32,$tmp0
        +	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
        +	sllx	@pair[0],$tmp0,$tmp1
        +	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
        +	srlx	@pair[2],$tmp32,@pair[1]
        +	or	$tmp1,$tmp2,$tmp2
        +	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
        +	or	@pair[1],$tmp2,$tmp2
        +	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
        +	add	$h,$tmp2,$T1
        +	$ST	$tmp2,[%sp+`$bias+$frame+$i*$SZ`]
        +	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
        +	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
        +	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
        +___
        +} if ($SZ==8);
        +
        +########### common
        +sub BODY_00_15 {
        +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
        +
        +    if ($i<16) {
        +	&$Xload(@_);
        +    } else {
        +	$code.="\tadd	$h,$T1,$T1\n";
        +    }
        +
        +$code.=<<___;
        +	$SRL	$e,@Sigma1[0],$h	!! $i
        +	xor	$f,$g,$tmp2
        +	$SLL	$e,`$SZ*8-@Sigma1[2]`,$tmp1
        +	and	$e,$tmp2,$tmp2
        +	$SRL	$e,@Sigma1[1],$tmp0
        +	xor	$tmp1,$h,$h
        +	$SLL	$e,`$SZ*8-@Sigma1[1]`,$tmp1
        +	xor	$tmp0,$h,$h
        +	$SRL	$e,@Sigma1[2],$tmp0
        +	xor	$tmp1,$h,$h
        +	$SLL	$e,`$SZ*8-@Sigma1[0]`,$tmp1
        +	xor	$tmp0,$h,$h
        +	xor	$g,$tmp2,$tmp2		! Ch(e,f,g)
        +	xor	$tmp1,$h,$tmp0		! Sigma1(e)
        +
        +	$SRL	$a,@Sigma0[0],$h
        +	add	$tmp2,$T1,$T1
        +	$LD	[$Ktbl+`$i*$SZ`],$tmp2	! K[$i]
        +	$SLL	$a,`$SZ*8-@Sigma0[2]`,$tmp1
        +	add	$tmp0,$T1,$T1
        +	$SRL	$a,@Sigma0[1],$tmp0
        +	xor	$tmp1,$h,$h
        +	$SLL	$a,`$SZ*8-@Sigma0[1]`,$tmp1
        +	xor	$tmp0,$h,$h
        +	$SRL	$a,@Sigma0[2],$tmp0
        +	xor	$tmp1,$h,$h	
        +	$SLL	$a,`$SZ*8-@Sigma0[0]`,$tmp1
        +	xor	$tmp0,$h,$h
        +	xor	$tmp1,$h,$h		! Sigma0(a)
        +
        +	or	$a,$b,$tmp0
        +	and	$a,$b,$tmp1
        +	and	$c,$tmp0,$tmp0
        +	or	$tmp0,$tmp1,$tmp1	! Maj(a,b,c)
        +	add	$tmp2,$T1,$T1		! +=K[$i]
        +	add	$tmp1,$h,$h
        +
        +	add	$T1,$d,$d
        +	add	$T1,$h,$h
        +___
        +}
        +
        +########### SHA256
        +$BODY_16_XX = sub {
        +my $i=@_[0];
        +my $xi;
        +
        +    if ($i&1) {
        +	$xi=$tmp32;
        +	$code.="\tsrlx	@X[(($i+1)/2)%8],32,$xi\n";
        +    } else {
        +	$xi=@X[(($i+1)/2)%8];
        +    }
        +$code.=<<___;
        +	srl	$xi,@sigma0[0],$T1		!! Xupdate($i)
        +	sll	$xi,`32-@sigma0[2]`,$tmp1
        +	srl	$xi,@sigma0[1],$tmp0
        +	xor	$tmp1,$T1,$T1
        +	sll	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
        +	xor	$tmp0,$T1,$T1
        +	srl	$xi,@sigma0[2],$tmp0
        +	xor	$tmp1,$T1,$T1
        +___
        +    if ($i&1) {
        +	$xi=@X[(($i+14)/2)%8];
        +    } else {
        +	$xi=$tmp32;
        +	$code.="\tsrlx	@X[(($i+14)/2)%8],32,$xi\n";
        +    }
        +$code.=<<___;
        +	srl	$xi,@sigma1[0],$tmp2
        +	xor	$tmp0,$T1,$T1			! T1=sigma0(X[i+1])
        +	sll	$xi,`32-@sigma1[2]`,$tmp1
        +	srl	$xi,@sigma1[1],$tmp0
        +	xor	$tmp1,$tmp2,$tmp2
        +	sll	$tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1
        +	xor	$tmp0,$tmp2,$tmp2
        +	srl	$xi,@sigma1[2],$tmp0
        +	xor	$tmp1,$tmp2,$tmp2
        +___
        +    if ($i&1) {
        +	$xi=@X[($i/2)%8];
        +$code.=<<___;
        +	srlx	@X[(($i+9)/2)%8],32,$tmp1	! X[i+9]
        +	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
        +	srl	@X[($i/2)%8],0,$tmp0
        +	add	$tmp2,$tmp1,$tmp1
        +	add	$xi,$T1,$T1			! +=X[i]
        +	xor	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
        +	add	$tmp1,$T1,$T1
        +
        +	srl	$T1,0,$T1
        +	or	$T1,@X[($i/2)%8],@X[($i/2)%8]
        +___
        +    } else {
        +	$xi=@X[(($i+9)/2)%8];
        +$code.=<<___;
        +	srlx	@X[($i/2)%8],32,$tmp1		! X[i]
        +	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
        +	add	$xi,$T1,$T1			! +=X[i+9]
        +	add	$tmp2,$tmp1,$tmp1
        +	srl	@X[($i/2)%8],0,@X[($i/2)%8]
        +	add	$tmp1,$T1,$T1
        +
        +	sllx	$T1,32,$tmp0
        +	or	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
        +___
        +    }
        +    &BODY_00_15(@_);
        +} if ($SZ==4);
        +
        +########### SHA512
        +$BODY_16_XX = sub {
        +my $i=@_[0];
        +my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1));
        +
        +$code.=<<___;
        +	sllx	%l2,32,$tmp0		!! Xupdate($i)
        +	or	%l3,$tmp0,$tmp0
        +
        +	srlx	$tmp0,@sigma0[0],$T1
        +	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
        +	sllx	$tmp0,`64-@sigma0[2]`,$tmp1
        +	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
        +	srlx	$tmp0,@sigma0[1],$tmp0
        +	xor	$tmp1,$T1,$T1
        +	sllx	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
        +	xor	$tmp0,$T1,$T1
        +	srlx	$tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0
        +	xor	$tmp1,$T1,$T1
        +	sllx	%l6,32,$tmp2
        +	xor	$tmp0,$T1,$T1		! sigma0(X[$i+1])
        +	or	%l7,$tmp2,$tmp2
        +
        +	srlx	$tmp2,@sigma1[0],$tmp1
        +	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
        +	sllx	$tmp2,`64-@sigma1[2]`,$tmp0
        +	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
        +	srlx	$tmp2,@sigma1[1],$tmp2
        +	xor	$tmp0,$tmp1,$tmp1
        +	sllx	$tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0
        +	xor	$tmp2,$tmp1,$tmp1
        +	srlx	$tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2
        +	xor	$tmp0,$tmp1,$tmp1
        +	sllx	%l4,32,$tmp0
        +	xor	$tmp2,$tmp1,$tmp1	! sigma1(X[$i+14])
        +	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
        +	or	%l5,$tmp0,$tmp0
        +	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
        +
        +	sllx	%l0,32,$tmp2
        +	add	$tmp1,$T1,$T1
        +	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
        +	or	%l1,$tmp2,$tmp2
        +	add	$tmp0,$T1,$T1		! +=X[$i+9]
        +	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
        +	add	$tmp2,$T1,$T1		! +=X[$i]
        +	$ST	$T1,[%sp+`$bias+$frame+($i%16)*$SZ`]
        +___
        +    &BODY_00_15(@_);
        +} if ($SZ==8);
        +
        +$code.=<<___ if ($bits==64);
        +.register	%g2,#scratch
        +.register	%g3,#scratch
        +___
        +$code.=<<___;
        +.section	".text",#alloc,#execinstr
        +
        +.align	64
        +K${label}:
        +.type	K${label},#object
        +___
        +if ($SZ==4) {
        +$code.=<<___;
        +	.long	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
        +	.long	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
        +	.long	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
        +	.long	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
        +	.long	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
        +	.long	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
        +	.long	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
        +	.long	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
        +	.long	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
        +	.long	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
        +	.long	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
        +	.long	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
        +	.long	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
        +	.long	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
        +	.long	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
        +	.long	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
        +___
        +} else {
        +$code.=<<___;
        +	.long	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
        +	.long	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
        +	.long	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
        +	.long	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
        +	.long	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
        +	.long	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
        +	.long	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
        +	.long	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
        +	.long	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
        +	.long	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
        +	.long	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
        +	.long	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
        +	.long	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
        +	.long	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
        +	.long	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
        +	.long	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
        +	.long	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
        +	.long	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
        +	.long	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
        +	.long	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
        +	.long	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
        +	.long	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
        +	.long	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
        +	.long	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
        +	.long	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
        +	.long	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
        +	.long	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
        +	.long	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
        +	.long	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
        +	.long	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
        +	.long	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
        +	.long	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
        +	.long	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
        +	.long	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
        +	.long	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
        +	.long	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
        +	.long	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
        +	.long	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
        +	.long	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
        +	.long	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
        +___
        +}
        +$code.=<<___;
        +.size	K${label},.-K${label}
        +.globl	sha${label}_block_data_order
        +sha${label}_block_data_order:
        +	save	%sp,`-$frame-$locals`,%sp
        +	and	$inp,`$align-1`,$tmp31
        +	sllx	$len,`log(16*$SZ)/log(2)`,$len
        +	andn	$inp,`$align-1`,$inp
        +	sll	$tmp31,3,$tmp31
        +	add	$inp,$len,$len
        +___
        +$code.=<<___ if ($SZ==8); # SHA512
        +	mov	32,$tmp32
        +	sub	$tmp32,$tmp31,$tmp32
        +___
        +$code.=<<___;
        +.Lpic:	call	.+8
        +	add	%o7,K${label}-.Lpic,$Ktbl
        +
        +	$LD	[$ctx+`0*$SZ`],$A
        +	$LD	[$ctx+`1*$SZ`],$B
        +	$LD	[$ctx+`2*$SZ`],$C
        +	$LD	[$ctx+`3*$SZ`],$D
        +	$LD	[$ctx+`4*$SZ`],$E
        +	$LD	[$ctx+`5*$SZ`],$F
        +	$LD	[$ctx+`6*$SZ`],$G
        +	$LD	[$ctx+`7*$SZ`],$H
        +
        +.Lloop:
        +___
        +for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
        +$code.=".L16_xx:\n";
        +for (;$i<32;$i++)	{ &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
        +$code.=<<___;
        +	and	$tmp2,0xfff,$tmp2
        +	cmp	$tmp2,$lastK
        +	bne	.L16_xx
        +	add	$Ktbl,`16*$SZ`,$Ktbl	! Ktbl+=16
        +
        +___
        +$code.=<<___ if ($SZ==4); # SHA256
        +	$LD	[$ctx+`0*$SZ`],@X[0]
        +	$LD	[$ctx+`1*$SZ`],@X[1]
        +	$LD	[$ctx+`2*$SZ`],@X[2]
        +	$LD	[$ctx+`3*$SZ`],@X[3]
        +	$LD	[$ctx+`4*$SZ`],@X[4]
        +	$LD	[$ctx+`5*$SZ`],@X[5]
        +	$LD	[$ctx+`6*$SZ`],@X[6]
        +	$LD	[$ctx+`7*$SZ`],@X[7]
        +
        +	add	$A,@X[0],$A
        +	$ST	$A,[$ctx+`0*$SZ`]
        +	add	$B,@X[1],$B
        +	$ST	$B,[$ctx+`1*$SZ`]
        +	add	$C,@X[2],$C
        +	$ST	$C,[$ctx+`2*$SZ`]
        +	add	$D,@X[3],$D
        +	$ST	$D,[$ctx+`3*$SZ`]
        +	add	$E,@X[4],$E
        +	$ST	$E,[$ctx+`4*$SZ`]
        +	add	$F,@X[5],$F
        +	$ST	$F,[$ctx+`5*$SZ`]
        +	add	$G,@X[6],$G
        +	$ST	$G,[$ctx+`6*$SZ`]
        +	add	$H,@X[7],$H
        +	$ST	$H,[$ctx+`7*$SZ`]
        +___
        +$code.=<<___ if ($SZ==8); # SHA512
        +	ld	[$ctx+`0*$SZ+0`],%l0
        +	ld	[$ctx+`0*$SZ+4`],%l1
        +	ld	[$ctx+`1*$SZ+0`],%l2
        +	ld	[$ctx+`1*$SZ+4`],%l3
        +	ld	[$ctx+`2*$SZ+0`],%l4
        +	ld	[$ctx+`2*$SZ+4`],%l5
        +	ld	[$ctx+`3*$SZ+0`],%l6
        +
        +	sllx	%l0,32,$tmp0
        +	ld	[$ctx+`3*$SZ+4`],%l7
        +	sllx	%l2,32,$tmp1
        +	or	%l1,$tmp0,$tmp0
        +	or	%l3,$tmp1,$tmp1
        +	add	$tmp0,$A,$A
        +	add	$tmp1,$B,$B
        +	$ST	$A,[$ctx+`0*$SZ`]
        +	sllx	%l4,32,$tmp2
        +	$ST	$B,[$ctx+`1*$SZ`]
        +	sllx	%l6,32,$T1
        +	or	%l5,$tmp2,$tmp2
        +	or	%l7,$T1,$T1
        +	add	$tmp2,$C,$C
        +	$ST	$C,[$ctx+`2*$SZ`]
        +	add	$T1,$D,$D
        +	$ST	$D,[$ctx+`3*$SZ`]
        +
        +	ld	[$ctx+`4*$SZ+0`],%l0
        +	ld	[$ctx+`4*$SZ+4`],%l1
        +	ld	[$ctx+`5*$SZ+0`],%l2
        +	ld	[$ctx+`5*$SZ+4`],%l3
        +	ld	[$ctx+`6*$SZ+0`],%l4
        +	ld	[$ctx+`6*$SZ+4`],%l5
        +	ld	[$ctx+`7*$SZ+0`],%l6
        +
        +	sllx	%l0,32,$tmp0
        +	ld	[$ctx+`7*$SZ+4`],%l7
        +	sllx	%l2,32,$tmp1
        +	or	%l1,$tmp0,$tmp0
        +	or	%l3,$tmp1,$tmp1
        +	add	$tmp0,$E,$E
        +	add	$tmp1,$F,$F
        +	$ST	$E,[$ctx+`4*$SZ`]
        +	sllx	%l4,32,$tmp2
        +	$ST	$F,[$ctx+`5*$SZ`]
        +	sllx	%l6,32,$T1
        +	or	%l5,$tmp2,$tmp2
        +	or	%l7,$T1,$T1
        +	add	$tmp2,$G,$G
        +	$ST	$G,[$ctx+`6*$SZ`]
        +	add	$T1,$H,$H
        +	$ST	$H,[$ctx+`7*$SZ`]
        +___
        +$code.=<<___;
        +	add	$inp,`16*$SZ`,$inp		! advance inp
        +	cmp	$inp,$len
        +	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
        +	sub	$Ktbl,`($rounds-16)*$SZ`,$Ktbl	! rewind Ktbl
        +
        +	ret
        +	restore
        +.type	sha${label}_block_data_order,#function
        +.size	sha${label}_block_data_order,(.-sha${label}_block_data_order)
        +.asciz	"SHA${label} block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
        +.align	4
        +___
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl b/vendor/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl
        new file mode 100644
        index 000000000..8d5167855
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl
        @@ -0,0 +1,451 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. Rights for redistribution and usage in source and binary
        +# forms are granted according to the OpenSSL license.
        +# ====================================================================
        +#
        +# sha256/512_block procedure for x86_64.
        +#
        +# 40% improvement over compiler-generated code on Opteron. On EM64T
        +# sha256 was observed to run >80% faster and sha512 - >40%. No magical
        +# tricks, just straight implementation... I really wonder why gcc
        +# [being armed with inline assembler] fails to generate as fast code.
        +# The only thing which is cool about this module is that it's very
        +# same instruction sequence used for both SHA-256 and SHA-512. In
        +# former case the instructions operate on 32-bit operands, while in
        +# latter - on 64-bit ones. All I had to do is to get one flavor right,
        +# the other one passed the test right away:-)
        +#
        +# sha256_block runs in ~1005 cycles on Opteron, which gives you
        +# asymptotic performance of 64*1000/1005=63.7MBps times CPU clock
        +# frequency in GHz. sha512_block runs in ~1275 cycles, which results
        +# in 128*1000/1275=100MBps per GHz. Is there room for improvement?
        +# Well, if you compare it to IA-64 implementation, which maintains
        +# X[16] in register bank[!], tends to 4 instructions per CPU clock
        +# cycle and runs in 1003 cycles, 1275 is very good result for 3-way
        +# issue Opteron pipeline and X[16] maintained in memory. So that *if*
        +# there is a way to improve it, *then* the only way would be to try to
        +# offload X[16] updates to SSE unit, but that would require "deeper"
        +# loop unroll, which in turn would naturally cause size blow-up, not
        +# to mention increased complexity! And once again, only *if* it's
        +# actually possible to noticeably improve overall ILP, instruction
        +# level parallelism, on a given CPU implementation in this case.
        +#
        +# Special note on Intel EM64T. While Opteron CPU exhibits perfect
        +# perfromance ratio of 1.5 between 64- and 32-bit flavors [see above],
        +# [currently available] EM64T CPUs apparently are far from it. On the
        +# contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit
        +# sha256_block:-( This is presumably because 64-bit shifts/rotates
        +# apparently are not atomic instructions, but implemented in microcode.
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +if ($output =~ /512/) {
        +	$func="sha512_block_data_order";
        +	$TABLE="K512";
        +	$SZ=8;
        +	@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx",
        +					"%r8", "%r9", "%r10","%r11");
        +	($T1,$a0,$a1,$a2)=("%r12","%r13","%r14","%r15");
        +	@Sigma0=(28,34,39);
        +	@Sigma1=(14,18,41);
        +	@sigma0=(1,  8, 7);
        +	@sigma1=(19,61, 6);
        +	$rounds=80;
        +} else {
        +	$func="sha256_block_data_order";
        +	$TABLE="K256";
        +	$SZ=4;
        +	@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx",
        +					"%r8d","%r9d","%r10d","%r11d");
        +	($T1,$a0,$a1,$a2)=("%r12d","%r13d","%r14d","%r15d");
        +	@Sigma0=( 2,13,22);
        +	@Sigma1=( 6,11,25);
        +	@sigma0=( 7,18, 3);
        +	@sigma1=(17,19,10);
        +	$rounds=64;
        +}
        +
        +$ctx="%rdi";	# 1st arg
        +$round="%rdi";	# zaps $ctx
        +$inp="%rsi";	# 2nd arg
        +$Tbl="%rbp";
        +
        +$_ctx="16*$SZ+0*8(%rsp)";
        +$_inp="16*$SZ+1*8(%rsp)";
        +$_end="16*$SZ+2*8(%rsp)";
        +$_rsp="16*$SZ+3*8(%rsp)";
        +$framesz="16*$SZ+4*8";
        +
        +
        +sub ROUND_00_15()
        +{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
        +
        +$code.=<<___;
        +	ror	\$`$Sigma1[2]-$Sigma1[1]`,$a0
        +	mov	$f,$a2
        +	mov	$T1,`$SZ*($i&0xf)`(%rsp)
        +
        +	ror	\$`$Sigma0[2]-$Sigma0[1]`,$a1
        +	xor	$e,$a0
        +	xor	$g,$a2			# f^g
        +
        +	ror	\$`$Sigma1[1]-$Sigma1[0]`,$a0
        +	add	$h,$T1			# T1+=h
        +	xor	$a,$a1
        +
        +	add	($Tbl,$round,$SZ),$T1	# T1+=K[round]
        +	and	$e,$a2			# (f^g)&e
        +	mov	$b,$h
        +
        +	ror	\$`$Sigma0[1]-$Sigma0[0]`,$a1
        +	xor	$e,$a0
        +	xor	$g,$a2			# Ch(e,f,g)=((f^g)&e)^g
        +
        +	xor	$c,$h			# b^c
        +	xor	$a,$a1
        +	add	$a2,$T1			# T1+=Ch(e,f,g)
        +	mov	$b,$a2
        +
        +	ror	\$$Sigma1[0],$a0	# Sigma1(e)
        +	and	$a,$h			# h=(b^c)&a
        +	and	$c,$a2			# b&c
        +
        +	ror	\$$Sigma0[0],$a1	# Sigma0(a)
        +	add	$a0,$T1			# T1+=Sigma1(e)
        +	add	$a2,$h			# h+=b&c (completes +=Maj(a,b,c)
        +
        +	add	$T1,$d			# d+=T1
        +	add	$T1,$h			# h+=T1
        +	lea	1($round),$round	# round++
        +	add	$a1,$h			# h+=Sigma0(a)
        +
        +___
        +}
        +
        +sub ROUND_16_XX()
        +{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
        +
        +$code.=<<___;
        +	mov	`$SZ*(($i+1)&0xf)`(%rsp),$a0
        +	mov	`$SZ*(($i+14)&0xf)`(%rsp),$a1
        +	mov	$a0,$T1
        +	mov	$a1,$a2
        +
        +	ror	\$`$sigma0[1]-$sigma0[0]`,$T1
        +	xor	$a0,$T1
        +	shr	\$$sigma0[2],$a0
        +
        +	ror	\$$sigma0[0],$T1
        +	xor	$T1,$a0			# sigma0(X[(i+1)&0xf])
        +	mov	`$SZ*(($i+9)&0xf)`(%rsp),$T1
        +
        +	ror	\$`$sigma1[1]-$sigma1[0]`,$a2
        +	xor	$a1,$a2
        +	shr	\$$sigma1[2],$a1
        +
        +	ror	\$$sigma1[0],$a2
        +	add	$a0,$T1
        +	xor	$a2,$a1			# sigma1(X[(i+14)&0xf])
        +
        +	add	`$SZ*($i&0xf)`(%rsp),$T1
        +	mov	$e,$a0
        +	add	$a1,$T1
        +	mov	$a,$a1
        +___
        +	&ROUND_00_15(@_);
        +}
        +
        +$code=<<___;
        +.text
        +
        +.globl	$func
        +.type	$func,\@function,4
        +.align	16
        +$func:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	mov	%rsp,%r11		# copy %rsp
        +	shl	\$4,%rdx		# num*16
        +	sub	\$$framesz,%rsp
        +	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
        +	and	\$-64,%rsp		# align stack frame
        +	mov	$ctx,$_ctx		# save ctx, 1st arg
        +	mov	$inp,$_inp		# save inp, 2nd arh
        +	mov	%rdx,$_end		# save end pointer, "3rd" arg
        +	mov	%r11,$_rsp		# save copy of %rsp
        +.Lprologue:
        +
        +	lea	$TABLE(%rip),$Tbl
        +
        +	mov	$SZ*0($ctx),$A
        +	mov	$SZ*1($ctx),$B
        +	mov	$SZ*2($ctx),$C
        +	mov	$SZ*3($ctx),$D
        +	mov	$SZ*4($ctx),$E
        +	mov	$SZ*5($ctx),$F
        +	mov	$SZ*6($ctx),$G
        +	mov	$SZ*7($ctx),$H
        +	jmp	.Lloop
        +
        +.align	16
        +.Lloop:
        +	xor	$round,$round
        +___
        +	for($i=0;$i<16;$i++) {
        +		$code.="	mov	$SZ*$i($inp),$T1\n";
        +		$code.="	mov	@ROT[4],$a0\n";
        +		$code.="	mov	@ROT[0],$a1\n";
        +		$code.="	bswap	$T1\n";
        +		&ROUND_00_15($i,@ROT);
        +		unshift(@ROT,pop(@ROT));
        +	}
        +$code.=<<___;
        +	jmp	.Lrounds_16_xx
        +.align	16
        +.Lrounds_16_xx:
        +___
        +	for(;$i<32;$i++) {
        +		&ROUND_16_XX($i,@ROT);
        +		unshift(@ROT,pop(@ROT));
        +	}
        +
        +$code.=<<___;
        +	cmp	\$$rounds,$round
        +	jb	.Lrounds_16_xx
        +
        +	mov	$_ctx,$ctx
        +	lea	16*$SZ($inp),$inp
        +
        +	add	$SZ*0($ctx),$A
        +	add	$SZ*1($ctx),$B
        +	add	$SZ*2($ctx),$C
        +	add	$SZ*3($ctx),$D
        +	add	$SZ*4($ctx),$E
        +	add	$SZ*5($ctx),$F
        +	add	$SZ*6($ctx),$G
        +	add	$SZ*7($ctx),$H
        +
        +	cmp	$_end,$inp
        +
        +	mov	$A,$SZ*0($ctx)
        +	mov	$B,$SZ*1($ctx)
        +	mov	$C,$SZ*2($ctx)
        +	mov	$D,$SZ*3($ctx)
        +	mov	$E,$SZ*4($ctx)
        +	mov	$F,$SZ*5($ctx)
        +	mov	$G,$SZ*6($ctx)
        +	mov	$H,$SZ*7($ctx)
        +	jb	.Lloop
        +
        +	mov	$_rsp,%rsi
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lepilogue:
        +	ret
        +.size	$func,.-$func
        +___
        +
        +if ($SZ==4) {
        +$code.=<<___;
        +.align	64
        +.type	$TABLE,\@object
        +$TABLE:
        +	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
        +	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
        +	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
        +	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
        +	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
        +	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
        +	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
        +	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
        +	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
        +	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
        +	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
        +	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
        +	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
        +	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
        +	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
        +	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
        +___
        +} else {
        +$code.=<<___;
        +.align	64
        +.type	$TABLE,\@object
        +$TABLE:
        +	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
        +	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
        +	.quad	0x3956c25bf348b538,0x59f111f1b605d019
        +	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
        +	.quad	0xd807aa98a3030242,0x12835b0145706fbe
        +	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
        +	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
        +	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
        +	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
        +	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
        +	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
        +	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
        +	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
        +	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
        +	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
        +	.quad	0x06ca6351e003826f,0x142929670a0e6e70
        +	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
        +	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
        +	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
        +	.quad	0x81c2c92e47edaee6,0x92722c851482353b
        +	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
        +	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
        +	.quad	0xd192e819d6ef5218,0xd69906245565a910
        +	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
        +	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
        +	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
        +	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
        +	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
        +	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
        +	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
        +	.quad	0x90befffa23631e28,0xa4506cebde82bde9
        +	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
        +	.quad	0xca273eceea26619c,0xd186b8c721c0c207
        +	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
        +	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
        +	.quad	0x113f9804bef90dae,0x1b710b35131c471b
        +	.quad	0x28db77f523047d84,0x32caab7b40c72493
        +	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
        +	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
        +	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
        +___
        +}
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lprologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lprologue
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
        +	jae	.Lin_prologue
        +
        +	mov	16*$SZ+3*8(%rax),%rax	# pull $_rsp
        +	lea	48(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_$func
        +	.rva	.LSEH_end_$func
        +	.rva	.LSEH_info_$func
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_$func:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/sha/sha.c b/vendor/openssl/openssl/crypto/sha/sha.c
        new file mode 100644
        index 000000000..42126551d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha.c
        @@ -0,0 +1,124 @@
        +/* crypto/sha/sha.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/sha.h>
        +
        +#define BUFSIZE	1024*16
        +
        +void do_fp(FILE *f);
        +void pt(unsigned char *md);
        +int read(int, void *, unsigned int);
        +int main(int argc, char **argv)
        +	{
        +	int i,err=0;
        +	FILE *IN;
        +
        +	if (argc == 1)
        +		{
        +		do_fp(stdin);
        +		}
        +	else
        +		{
        +		for (i=1; i<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("SHA(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	SHA_CTX c;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +	int fd;
        +	int i;
        +	unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	SHA_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,BUFSIZE);
        +		if (i <= 0) break;
        +		SHA_Update(&c,buf,(unsigned long)i);
        +		}
        +	SHA_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<SHA_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/sha/sha.h b/vendor/openssl/openssl/crypto/sha/sha.h
        new file mode 100644
        index 000000000..8a6bf4bbb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha.h
        @@ -0,0 +1,214 @@
        +/* crypto/sha/sha.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_SHA_H
        +#define HEADER_SHA_H
        +
        +#include <openssl/e_os2.h>
        +#include <stddef.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
        +#error SHA is disabled.
        +#endif
        +
        +#if defined(OPENSSL_FIPS)
        +#define FIPS_SHA_SIZE_T size_t
        +#endif
        +
        +/*
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
        + * ! SHA_LONG_LOG2 has to be defined along.                        !
        + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        + */
        +
        +#if defined(__LP32__)
        +#define SHA_LONG unsigned long
        +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
        +#define SHA_LONG unsigned long
        +#define SHA_LONG_LOG2 3
        +#else
        +#define SHA_LONG unsigned int
        +#endif
        +
        +#define SHA_LBLOCK	16
        +#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
        +					 * contiguous array of 32 bit
        +					 * wide big-endian values. */
        +#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
        +#define SHA_DIGEST_LENGTH 20
        +
        +typedef struct SHAstate_st
        +	{
        +	SHA_LONG h0,h1,h2,h3,h4;
        +	SHA_LONG Nl,Nh;
        +	SHA_LONG data[SHA_LBLOCK];
        +	unsigned int num;
        +	} SHA_CTX;
        +
        +#ifndef OPENSSL_NO_SHA0
        +#ifdef OPENSSL_FIPS
        +int private_SHA_Init(SHA_CTX *c);
        +#endif
        +int SHA_Init(SHA_CTX *c);
        +int SHA_Update(SHA_CTX *c, const void *data, size_t len);
        +int SHA_Final(unsigned char *md, SHA_CTX *c);
        +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
        +void SHA_Transform(SHA_CTX *c, const unsigned char *data);
        +#endif
        +#ifndef OPENSSL_NO_SHA1
        +#ifdef OPENSSL_FIPS
        +int private_SHA1_Init(SHA_CTX *c);
        +#endif
        +int SHA1_Init(SHA_CTX *c);
        +int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
        +int SHA1_Final(unsigned char *md, SHA_CTX *c);
        +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
        +void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
        +#endif
        +
        +#define SHA256_CBLOCK	(SHA_LBLOCK*4)	/* SHA-256 treats input data as a
        +					 * contiguous array of 32 bit
        +					 * wide big-endian values. */
        +#define SHA224_DIGEST_LENGTH	28
        +#define SHA256_DIGEST_LENGTH	32
        +
        +typedef struct SHA256state_st
        +	{
        +	SHA_LONG h[8];
        +	SHA_LONG Nl,Nh;
        +	SHA_LONG data[SHA_LBLOCK];
        +	unsigned int num,md_len;
        +	} SHA256_CTX;
        +
        +#ifndef OPENSSL_NO_SHA256
        +#ifdef OPENSSL_FIPS
        +int private_SHA224_Init(SHA256_CTX *c);
        +int private_SHA256_Init(SHA256_CTX *c);
        +#endif
        +int SHA224_Init(SHA256_CTX *c);
        +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
        +int SHA224_Final(unsigned char *md, SHA256_CTX *c);
        +unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md);
        +int SHA256_Init(SHA256_CTX *c);
        +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
        +int SHA256_Final(unsigned char *md, SHA256_CTX *c);
        +unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md);
        +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
        +#endif
        +
        +#define SHA384_DIGEST_LENGTH	48
        +#define SHA512_DIGEST_LENGTH	64
        +
        +#ifndef OPENSSL_NO_SHA512
        +/*
        + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
        + * being exactly 64-bit wide. See Implementation Notes in sha512.c
        + * for further details.
        + */
        +#define SHA512_CBLOCK	(SHA_LBLOCK*8)	/* SHA-512 treats input data as a
        +					 * contiguous array of 64 bit
        +					 * wide big-endian values. */
        +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
        +#define SHA_LONG64 unsigned __int64
        +#define U64(C)     C##UI64
        +#elif defined(__arch64__)
        +#define SHA_LONG64 unsigned long
        +#define U64(C)     C##UL
        +#else
        +#define SHA_LONG64 unsigned long long
        +#define U64(C)     C##ULL
        +#endif
        +
        +typedef struct SHA512state_st
        +	{
        +	SHA_LONG64 h[8];
        +	SHA_LONG64 Nl,Nh;
        +	union {
        +		SHA_LONG64	d[SHA_LBLOCK];
        +		unsigned char	p[SHA512_CBLOCK];
        +	} u;
        +	unsigned int num,md_len;
        +	} SHA512_CTX;
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA512
        +#ifdef OPENSSL_FIPS
        +int private_SHA384_Init(SHA512_CTX *c);
        +int private_SHA512_Init(SHA512_CTX *c);
        +#endif
        +int SHA384_Init(SHA512_CTX *c);
        +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
        +int SHA384_Final(unsigned char *md, SHA512_CTX *c);
        +unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md);
        +int SHA512_Init(SHA512_CTX *c);
        +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
        +int SHA512_Final(unsigned char *md, SHA512_CTX *c);
        +unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md);
        +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
        +#endif
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/sha1.c b/vendor/openssl/openssl/crypto/sha/sha1.c
        new file mode 100644
        index 000000000..d350c88ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha1.c
        @@ -0,0 +1,127 @@
        +/* crypto/sha/sha1.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/sha.h>
        +
        +#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<argc; i++)
        +			{
        +			IN=fopen(argv[i],"r");
        +			if (IN == NULL)
        +				{
        +				perror(argv[i]);
        +				err++;
        +				continue;
        +				}
        +			printf("SHA1(%s)= ",argv[i]);
        +			do_fp(IN);
        +			fclose(IN);
        +			}
        +		}
        +	exit(err);
        +	}
        +
        +void do_fp(FILE *f)
        +	{
        +	SHA_CTX c;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +	int fd;
        +	int i;
        +	unsigned char buf[BUFSIZE];
        +
        +	fd=fileno(f);
        +	SHA1_Init(&c);
        +	for (;;)
        +		{
        +		i=read(fd,buf,BUFSIZE);
        +		if (i <= 0) break;
        +		SHA1_Update(&c,buf,(unsigned long)i);
        +		}
        +	SHA1_Final(&(md[0]),&c);
        +	pt(md);
        +	}
        +
        +void pt(unsigned char *md)
        +	{
        +	int i;
        +
        +	for (i=0; i<SHA_DIGEST_LENGTH; i++)
        +		printf("%02x",md[i]);
        +	printf("\n");
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/sha/sha1_one.c b/vendor/openssl/openssl/crypto/sha/sha1_one.c
        new file mode 100644
        index 000000000..c56ec9402
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha1_one.c
        @@ -0,0 +1,78 @@
        +/* crypto/sha/sha1_one.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/sha.h>
        +
        +#ifndef OPENSSL_NO_SHA1
        +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	SHA_CTX c;
        +	static unsigned char m[SHA_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!SHA1_Init(&c))
        +		return NULL;
        +	SHA1_Update(&c,d,n);
        +	SHA1_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));
        +	return(md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/sha1dgst.c b/vendor/openssl/openssl/crypto/sha/sha1dgst.c
        new file mode 100644
        index 000000000..a98690225
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha1dgst.c
        @@ -0,0 +1,75 @@
        +/* crypto/sha/sha1dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <openssl/crypto.h>
        +#include <openssl/opensslconf.h>
        +#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
        +
        +#undef  SHA_0
        +#define SHA_1
        +
        +#include <openssl/opensslv.h>
        +
        +const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT;
        +
        +/* The implementation is in ../md32_common.h */
        +
        +#include "sha_locl.h"
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/sha/sha1test.c b/vendor/openssl/openssl/crypto/sha/sha1test.c
        new file mode 100644
        index 000000000..6feb3964c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha1test.c
        @@ -0,0 +1,178 @@
        +/* crypto/sha/sha1test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_SHA
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/sha.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +#undef SHA_0 /* FIPS 180 */
        +#define  SHA_1 /* FIPS 180-1 */
        +
        +static char *test[]={
        +	"abc",
        +	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
        +	NULL,
        +	};
        +
        +#ifdef SHA_0
        +static char *ret[]={
        +	"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
        +	"d2516ee1acfa5baf33dfc1c471e438449ef134c8",
        +	};
        +static char *bigret=
        +	"3232affa48628a26653b5aaa44541fd90d690603";
        +#endif
        +#ifdef SHA_1
        +static char *ret[]={
        +	"a9993e364706816aba3e25717850c26c9cd0d89d",
        +	"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
        +	};
        +static char *bigret=
        +	"34aa973cd4c4daa4f61eeb2bdbad27316534016f";
        +#endif
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	static unsigned char buf[1000];
        +	char *p,*r;
        +	EVP_MD_CTX c;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(test[0], test[0], strlen(test[0]));
        +	ebcdic2ascii(test[1], test[1], strlen(test[1]));
        +#endif
        +
        +	EVP_MD_CTX_init(&c);
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha1(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,(char *)*R) != 0)
        +			{
        +			printf("error calculating SHA1 on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +
        +	memset(buf,'a',1000);
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(buf, buf, 1000);
        +#endif /*CHARSET_EBCDIC*/
        +	EVP_DigestInit_ex(&c,EVP_sha1(), NULL);
        +	for (i=0; i<1000; i++)
        +		EVP_DigestUpdate(&c,buf,1000);
        +	EVP_DigestFinal_ex(&c,md,NULL);
        +	p=pt(md);
        +
        +	r=bigret;
        +	if (strcmp(p,r) != 0)
        +		{
        +		printf("error calculating SHA1 on 'a' * 1000\n");
        +		printf("got %s instead of %s\n",p,r);
        +		err++;
        +		}
        +	else
        +		printf("test 3 ok\n");
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	EVP_MD_CTX_cleanup(&c);
        +	return(0);
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<SHA_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/sha256.c b/vendor/openssl/openssl/crypto/sha/sha256.c
        new file mode 100644
        index 000000000..4eae07484
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha256.c
        @@ -0,0 +1,282 @@
        +/* crypto/sha/sha256.c */
        +/* ====================================================================
        + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved
        + * according to the OpenSSL license [found in ../../LICENSE].
        + * ====================================================================
        + */
        +#include <openssl/opensslconf.h>
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
        +
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/crypto.h>
        +#include <openssl/sha.h>
        +#include <openssl/opensslv.h>
        +
        +const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
        +
        +fips_md_init_ctx(SHA224, SHA256)
        +	{
        +	memset (c,0,sizeof(*c));
        +	c->h[0]=0xc1059ed8UL;	c->h[1]=0x367cd507UL;
        +	c->h[2]=0x3070dd17UL;	c->h[3]=0xf70e5939UL;
        +	c->h[4]=0xffc00b31UL;	c->h[5]=0x68581511UL;
        +	c->h[6]=0x64f98fa7UL;	c->h[7]=0xbefa4fa4UL;
        +	c->md_len=SHA224_DIGEST_LENGTH;
        +	return 1;
        +	}
        +
        +fips_md_init(SHA256)
        +	{
        +	memset (c,0,sizeof(*c));
        +	c->h[0]=0x6a09e667UL;	c->h[1]=0xbb67ae85UL;
        +	c->h[2]=0x3c6ef372UL;	c->h[3]=0xa54ff53aUL;
        +	c->h[4]=0x510e527fUL;	c->h[5]=0x9b05688cUL;
        +	c->h[6]=0x1f83d9abUL;	c->h[7]=0x5be0cd19UL;
        +	c->md_len=SHA256_DIGEST_LENGTH;
        +	return 1;
        +	}
        +
        +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	SHA256_CTX c;
        +	static unsigned char m[SHA224_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	SHA224_Init(&c);
        +	SHA256_Update(&c,d,n);
        +	SHA256_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));
        +	return(md);
        +	}
        +
        +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	SHA256_CTX c;
        +	static unsigned char m[SHA256_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	SHA256_Init(&c);
        +	SHA256_Update(&c,d,n);
        +	SHA256_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));
        +	return(md);
        +	}
        +
        +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
        +{   return SHA256_Update (c,data,len);   }
        +int SHA224_Final (unsigned char *md, SHA256_CTX *c)
        +{   return SHA256_Final (md,c);   }
        +
        +#define	DATA_ORDER_IS_BIG_ENDIAN
        +
        +#define	HASH_LONG		SHA_LONG
        +#define	HASH_CTX		SHA256_CTX
        +#define	HASH_CBLOCK		SHA_CBLOCK
        +/*
        + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
        + * default: case below covers for it. It's not clear however if it's
        + * permitted to truncate to amount of bytes not divisible by 4. I bet not,
        + * but if it is, then default: case shall be extended. For reference.
        + * Idea behind separate cases for pre-defined lenghts is to let the
        + * compiler decide if it's appropriate to unroll small loops.
        + */
        +#define	HASH_MAKE_STRING(c,s)	do {	\
        +	unsigned long ll;		\
        +	unsigned int  nn;		\
        +	switch ((c)->md_len)		\
        +	{   case SHA224_DIGEST_LENGTH:	\
        +		for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)	\
        +		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
        +		break;			\
        +	    case SHA256_DIGEST_LENGTH:	\
        +		for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)	\
        +		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
        +		break;			\
        +	    default:			\
        +		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\
        +		    return 0;				\
        +		for (nn=0;nn<(c)->md_len/4;nn++)		\
        +		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
        +		break;			\
        +	}				\
        +	} while (0)
        +
        +#define	HASH_UPDATE		SHA256_Update
        +#define	HASH_TRANSFORM		SHA256_Transform
        +#define	HASH_FINAL		SHA256_Final
        +#define	HASH_BLOCK_DATA_ORDER	sha256_block_data_order
        +#ifndef SHA256_ASM
        +static
        +#endif
        +void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num);
        +
        +#include "md32_common.h"
        +
        +#ifndef SHA256_ASM
        +static const SHA_LONG K256[64] = {
        +	0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL,
        +	0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL,
        +	0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL,
        +	0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL,
        +	0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL,
        +	0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL,
        +	0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL,
        +	0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL,
        +	0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL,
        +	0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL,
        +	0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL,
        +	0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL,
        +	0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL,
        +	0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL,
        +	0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL,
        +	0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL };
        +
        +/*
        + * FIPS specification refers to right rotations, while our ROTATE macro
        + * is left one. This is why you might notice that rotation coefficients
        + * differ from those observed in FIPS document by 32-N...
        + */
        +#define Sigma0(x)	(ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
        +#define Sigma1(x)	(ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
        +#define sigma0(x)	(ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
        +#define sigma1(x)	(ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
        +
        +#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
        +#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
        +
        +#ifdef OPENSSL_SMALL_FOOTPRINT
        +
        +static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
        +	{
        +	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1,T2;
        +	SHA_LONG	X[16],l;
        +	int i;
        +	const unsigned char *data=in;
        +
        +			while (num--) {
        +
        +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
        +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
        +
        +	for (i=0;i<16;i++)
        +		{
        +		HOST_c2l(data,l); T1 = X[i] = l;
        +		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];
        +		T2 = Sigma0(a) + Maj(a,b,c);
        +		h = g;	g = f;	f = e;	e = d + T1;
        +		d = c;	c = b;	b = a;	a = T1 + T2;
        +		}
        +
        +	for (;i<64;i++)
        +		{
        +		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);
        +		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);
        +
        +		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
        +		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];
        +		T2 = Sigma0(a) + Maj(a,b,c);
        +		h = g;	g = f;	f = e;	e = d + T1;
        +		d = c;	c = b;	b = a;	a = T1 + T2;
        +		}
        +
        +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
        +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
        +
        +			}
        +}
        +
        +#else
        +
        +#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\
        +	T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];	\
        +	h = Sigma0(a) + Maj(a,b,c);			\
        +	d += T1;	h += T1;		} while (0)
        +
        +#define	ROUND_16_63(i,a,b,c,d,e,f,g,h,X)	do {	\
        +	s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);	\
        +	s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);	\
        +	T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];	\
        +	ROUND_00_15(i,a,b,c,d,e,f,g,h);		} while (0)
        +
        +static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
        +	{
        +	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1;
        +	SHA_LONG	X[16];
        +	int i;
        +	const unsigned char *data=in;
        +	const union { long one; char little; } is_endian = {1};
        +
        +			while (num--) {
        +
        +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
        +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
        +
        +	if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)in%4)==0)
        +		{
        +		const SHA_LONG *W=(const SHA_LONG *)data;
        +
        +		T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h);
        +		T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g);
        +		T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f);
        +		T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e);
        +		T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d);
        +		T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c);
        +		T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b);
        +		T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a);
        +		T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h);
        +		T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g);
        +		T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f);
        +		T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e);
        +		T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d);
        +		T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c);
        +		T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b);
        +		T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a);
        +
        +		data += SHA256_CBLOCK;
        +		}
        +	else
        +		{
        +		SHA_LONG l;
        +
        +		HOST_c2l(data,l); T1 = X[0] = l;  ROUND_00_15(0,a,b,c,d,e,f,g,h);
        +		HOST_c2l(data,l); T1 = X[1] = l;  ROUND_00_15(1,h,a,b,c,d,e,f,g);
        +		HOST_c2l(data,l); T1 = X[2] = l;  ROUND_00_15(2,g,h,a,b,c,d,e,f);
        +		HOST_c2l(data,l); T1 = X[3] = l;  ROUND_00_15(3,f,g,h,a,b,c,d,e);
        +		HOST_c2l(data,l); T1 = X[4] = l;  ROUND_00_15(4,e,f,g,h,a,b,c,d);
        +		HOST_c2l(data,l); T1 = X[5] = l;  ROUND_00_15(5,d,e,f,g,h,a,b,c);
        +		HOST_c2l(data,l); T1 = X[6] = l;  ROUND_00_15(6,c,d,e,f,g,h,a,b);
        +		HOST_c2l(data,l); T1 = X[7] = l;  ROUND_00_15(7,b,c,d,e,f,g,h,a);
        +		HOST_c2l(data,l); T1 = X[8] = l;  ROUND_00_15(8,a,b,c,d,e,f,g,h);
        +		HOST_c2l(data,l); T1 = X[9] = l;  ROUND_00_15(9,h,a,b,c,d,e,f,g);
        +		HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f);
        +		HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e);
        +		HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d);
        +		HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c);
        +		HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b);
        +		HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a);
        +		}
        +
        +	for (i=16;i<64;i+=8)
        +		{
        +		ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X);
        +		ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X);
        +		ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X);
        +		ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X);
        +		ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X);
        +		ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X);
        +		ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X);
        +		ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X);
        +		}
        +
        +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
        +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
        +
        +			}
        +	}
        +
        +#endif
        +#endif /* SHA256_ASM */
        +
        +#endif /* OPENSSL_NO_SHA256 */
        diff --git a/vendor/openssl/openssl/crypto/sha/sha256t.c b/vendor/openssl/openssl/crypto/sha/sha256t.c
        new file mode 100644
        index 000000000..6b4a3bd00
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha256t.c
        @@ -0,0 +1,147 @@
        +/* crypto/sha/sha256t.c */
        +/* ====================================================================
        + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
        + * ====================================================================
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include <openssl/sha.h>
        +#include <openssl/evp.h>
        +
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256)
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA256 support\n");
        +    return(0);
        +}
        +#else
        +
        +unsigned char app_b1[SHA256_DIGEST_LENGTH] = {
        +	0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,
        +	0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,
        +	0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,
        +	0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad	};
        +
        +unsigned char app_b2[SHA256_DIGEST_LENGTH] = {
        +	0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,
        +	0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,
        +	0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,
        +	0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1	};
        +
        +unsigned char app_b3[SHA256_DIGEST_LENGTH] = {
        +	0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,
        +	0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67,
        +	0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,
        +	0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0	};
        +
        +unsigned char addenum_1[SHA224_DIGEST_LENGTH] = {
        +	0x23,0x09,0x7d,0x22,0x34,0x05,0xd8,0x22,
        +	0x86,0x42,0xa4,0x77,0xbd,0xa2,0x55,0xb3,
        +	0x2a,0xad,0xbc,0xe4,0xbd,0xa0,0xb3,0xf7,
        +	0xe3,0x6c,0x9d,0xa7 };
        +
        +unsigned char addenum_2[SHA224_DIGEST_LENGTH] = {
        +	0x75,0x38,0x8b,0x16,0x51,0x27,0x76,0xcc,
        +	0x5d,0xba,0x5d,0xa1,0xfd,0x89,0x01,0x50,
        +	0xb0,0xc6,0x45,0x5c,0xb4,0xf5,0x8b,0x19,
        +	0x52,0x52,0x25,0x25 };
        +
        +unsigned char addenum_3[SHA224_DIGEST_LENGTH] = {
        +	0x20,0x79,0x46,0x55,0x98,0x0c,0x91,0xd8,
        +	0xbb,0xb4,0xc1,0xea,0x97,0x61,0x8a,0x4b,
        +	0xf0,0x3f,0x42,0x58,0x19,0x48,0xb2,0xee,
        +	0x4e,0xe7,0xad,0x67 };
        +
        +int main (int argc,char **argv)
        +{ unsigned char md[SHA256_DIGEST_LENGTH];
        +  int		i;
        +  EVP_MD_CTX	evp;
        +
        +    fprintf(stdout,"Testing SHA-256 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha256(),NULL);
        +    if (memcmp(md,app_b1,sizeof(app_b1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
        +		"ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha256(),NULL);
        +    if (memcmp(md,app_b2,sizeof(app_b2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha256(),NULL);
        +    for (i=0;i<1000000;i+=160)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<160?1000000-i:160);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,app_b3,sizeof(app_b3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +    fprintf(stdout,"Testing SHA-224 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha224(),NULL);
        +    if (memcmp(md,addenum_1,sizeof(addenum_1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
        +		"ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha224(),NULL);
        +    if (memcmp(md,addenum_2,sizeof(addenum_2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha224(),NULL);
        +    for (i=0;i<1000000;i+=64)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<64?1000000-i:64);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,addenum_3,sizeof(addenum_3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +  return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/sha512.c b/vendor/openssl/openssl/crypto/sha/sha512.c
        new file mode 100644
        index 000000000..50dd7dc74
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha512.c
        @@ -0,0 +1,597 @@
        +/* crypto/sha/sha512.c */
        +/* ====================================================================
        + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved
        + * according to the OpenSSL license [found in ../../LICENSE].
        + * ====================================================================
        + */
        +#include <openssl/opensslconf.h>
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
        +/*
        + * IMPLEMENTATION NOTES.
        + *
        + * As you might have noticed 32-bit hash algorithms:
        + *
        + * - permit SHA_LONG to be wider than 32-bit (case on CRAY);
        + * - optimized versions implement two transform functions: one operating
        + *   on [aligned] data in host byte order and one - on data in input
        + *   stream byte order;
        + * - share common byte-order neutral collector and padding function
        + *   implementations, ../md32_common.h;
        + *
        + * Neither of the above applies to this SHA-512 implementations. Reasons
        + * [in reverse order] are:
        + *
        + * - it's the only 64-bit hash algorithm for the moment of this writing,
        + *   there is no need for common collector/padding implementation [yet];
        + * - by supporting only one transform function [which operates on
        + *   *aligned* data in input stream byte order, big-endian in this case]
        + *   we minimize burden of maintenance in two ways: a) collector/padding
        + *   function is simpler; b) only one transform function to stare at;
        + * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
        + *   apply a number of optimizations to mitigate potential performance
        + *   penalties caused by previous design decision;
        + *
        + * Caveat lector.
        + *
        + * Implementation relies on the fact that "long long" is 64-bit on
        + * both 32- and 64-bit platforms. If some compiler vendor comes up
        + * with 128-bit long long, adjustment to sha.h would be required.
        + * As this implementation relies on 64-bit integer type, it's totally
        + * inappropriate for platforms which don't support it, most notably
        + * 16-bit platforms.
        + *					<appro@fy.chalmers.se>
        + */
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/crypto.h>
        +#include <openssl/sha.h>
        +#include <openssl/opensslv.h>
        +
        +#include "cryptlib.h"
        +
        +const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT;
        +
        +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
        +    defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
        +    defined(__s390__) || defined(__s390x__) || \
        +    defined(SHA512_ASM)
        +#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
        +#endif
        +
        +fips_md_init_ctx(SHA384, SHA512)
        +	{
        +	c->h[0]=U64(0xcbbb9d5dc1059ed8);
        +	c->h[1]=U64(0x629a292a367cd507);
        +	c->h[2]=U64(0x9159015a3070dd17);
        +	c->h[3]=U64(0x152fecd8f70e5939);
        +	c->h[4]=U64(0x67332667ffc00b31);
        +	c->h[5]=U64(0x8eb44a8768581511);
        +	c->h[6]=U64(0xdb0c2e0d64f98fa7);
        +	c->h[7]=U64(0x47b5481dbefa4fa4);
        +
        +        c->Nl=0;        c->Nh=0;
        +        c->num=0;       c->md_len=SHA384_DIGEST_LENGTH;
        +        return 1;
        +	}
        +
        +fips_md_init(SHA512)
        +	{
        +	c->h[0]=U64(0x6a09e667f3bcc908);
        +	c->h[1]=U64(0xbb67ae8584caa73b);
        +	c->h[2]=U64(0x3c6ef372fe94f82b);
        +	c->h[3]=U64(0xa54ff53a5f1d36f1);
        +	c->h[4]=U64(0x510e527fade682d1);
        +	c->h[5]=U64(0x9b05688c2b3e6c1f);
        +	c->h[6]=U64(0x1f83d9abfb41bd6b);
        +	c->h[7]=U64(0x5be0cd19137e2179);
        +
        +        c->Nl=0;        c->Nh=0;
        +        c->num=0;       c->md_len=SHA512_DIGEST_LENGTH;
        +        return 1;
        +	}
        +
        +#ifndef SHA512_ASM
        +static
        +#endif
        +void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num);
        +
        +int SHA512_Final (unsigned char *md, SHA512_CTX *c)
        +	{
        +	unsigned char *p=(unsigned char *)c->u.p;
        +	size_t n=c->num;
        +
        +	p[n]=0x80;	/* There always is a room for one */
        +	n++;
        +	if (n > (sizeof(c->u)-16))
        +		memset (p+n,0,sizeof(c->u)-n), n=0,
        +		sha512_block_data_order (c,p,1);
        +
        +	memset (p+n,0,sizeof(c->u)-16-n);
        +#ifdef	B_ENDIAN
        +	c->u.d[SHA_LBLOCK-2] = c->Nh;
        +	c->u.d[SHA_LBLOCK-1] = c->Nl;
        +#else
        +	p[sizeof(c->u)-1]  = (unsigned char)(c->Nl);
        +	p[sizeof(c->u)-2]  = (unsigned char)(c->Nl>>8);
        +	p[sizeof(c->u)-3]  = (unsigned char)(c->Nl>>16);
        +	p[sizeof(c->u)-4]  = (unsigned char)(c->Nl>>24);
        +	p[sizeof(c->u)-5]  = (unsigned char)(c->Nl>>32);
        +	p[sizeof(c->u)-6]  = (unsigned char)(c->Nl>>40);
        +	p[sizeof(c->u)-7]  = (unsigned char)(c->Nl>>48);
        +	p[sizeof(c->u)-8]  = (unsigned char)(c->Nl>>56);
        +	p[sizeof(c->u)-9]  = (unsigned char)(c->Nh);
        +	p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8);
        +	p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16);
        +	p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24);
        +	p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32);
        +	p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40);
        +	p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48);
        +	p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56);
        +#endif
        +
        +	sha512_block_data_order (c,p,1);
        +
        +	if (md==0) return 0;
        +
        +	switch (c->md_len)
        +		{
        +		/* Let compiler decide if it's appropriate to unroll... */
        +		case SHA384_DIGEST_LENGTH:
        +			for (n=0;n<SHA384_DIGEST_LENGTH/8;n++)
        +				{
        +				SHA_LONG64 t = c->h[n];
        +
        +				*(md++)	= (unsigned char)(t>>56);
        +				*(md++)	= (unsigned char)(t>>48);
        +				*(md++)	= (unsigned char)(t>>40);
        +				*(md++)	= (unsigned char)(t>>32);
        +				*(md++)	= (unsigned char)(t>>24);
        +				*(md++)	= (unsigned char)(t>>16);
        +				*(md++)	= (unsigned char)(t>>8);
        +				*(md++)	= (unsigned char)(t);
        +				}
        +			break;
        +		case SHA512_DIGEST_LENGTH:
        +			for (n=0;n<SHA512_DIGEST_LENGTH/8;n++)
        +				{
        +				SHA_LONG64 t = c->h[n];
        +
        +				*(md++)	= (unsigned char)(t>>56);
        +				*(md++)	= (unsigned char)(t>>48);
        +				*(md++)	= (unsigned char)(t>>40);
        +				*(md++)	= (unsigned char)(t>>32);
        +				*(md++)	= (unsigned char)(t>>24);
        +				*(md++)	= (unsigned char)(t>>16);
        +				*(md++)	= (unsigned char)(t>>8);
        +				*(md++)	= (unsigned char)(t);
        +				}
        +			break;
        +		/* ... as well as make sure md_len is not abused. */
        +		default:	return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +int SHA384_Final (unsigned char *md,SHA512_CTX *c)
        +{   return SHA512_Final (md,c);   }
        +
        +int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
        +	{
        +	SHA_LONG64	l;
        +	unsigned char  *p=c->u.p;
        +	const unsigned char *data=(const unsigned char *)_data;
        +
        +	if (len==0) return  1;
        +
        +	l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff);
        +	if (l < c->Nl)		c->Nh++;
        +	if (sizeof(len)>=8)	c->Nh+=(((SHA_LONG64)len)>>61);
        +	c->Nl=l;
        +
        +	if (c->num != 0)
        +		{
        +		size_t n = sizeof(c->u) - c->num;
        +
        +		if (len < n)
        +			{
        +			memcpy (p+c->num,data,len), c->num += (unsigned int)len;
        +			return 1;
        +			}
        +		else	{
        +			memcpy (p+c->num,data,n), c->num = 0;
        +			len-=n, data+=n;
        +			sha512_block_data_order (c,p,1);
        +			}
        +		}
        +
        +	if (len >= sizeof(c->u))
        +		{
        +#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
        +		if ((size_t)data%sizeof(c->u.d[0]) != 0)
        +			while (len >= sizeof(c->u))
        +				memcpy (p,data,sizeof(c->u)),
        +				sha512_block_data_order (c,p,1),
        +				len  -= sizeof(c->u),
        +				data += sizeof(c->u);
        +		else
        +#endif
        +			sha512_block_data_order (c,data,len/sizeof(c->u)),
        +			data += len,
        +			len  %= sizeof(c->u),
        +			data -= len;
        +		}
        +
        +	if (len != 0)	memcpy (p,data,len), c->num = (int)len;
        +
        +	return 1;
        +	}
        +
        +int SHA384_Update (SHA512_CTX *c, const void *data, size_t len)
        +{   return SHA512_Update (c,data,len);   }
        +
        +void SHA512_Transform (SHA512_CTX *c, const unsigned char *data)
        +{   sha512_block_data_order (c,data,1);  }
        +
        +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	SHA512_CTX c;
        +	static unsigned char m[SHA384_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	SHA384_Init(&c);
        +	SHA512_Update(&c,d,n);
        +	SHA512_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));
        +	return(md);
        +	}
        +
        +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	SHA512_CTX c;
        +	static unsigned char m[SHA512_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	SHA512_Init(&c);
        +	SHA512_Update(&c,d,n);
        +	SHA512_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));
        +	return(md);
        +	}
        +
        +#ifndef SHA512_ASM
        +static const SHA_LONG64 K512[80] = {
        +        U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd),
        +        U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc),
        +        U64(0x3956c25bf348b538),U64(0x59f111f1b605d019),
        +        U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118),
        +        U64(0xd807aa98a3030242),U64(0x12835b0145706fbe),
        +        U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2),
        +        U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1),
        +        U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694),
        +        U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3),
        +        U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65),
        +        U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483),
        +        U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5),
        +        U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210),
        +        U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4),
        +        U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725),
        +        U64(0x06ca6351e003826f),U64(0x142929670a0e6e70),
        +        U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926),
        +        U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df),
        +        U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8),
        +        U64(0x81c2c92e47edaee6),U64(0x92722c851482353b),
        +        U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001),
        +        U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30),
        +        U64(0xd192e819d6ef5218),U64(0xd69906245565a910),
        +        U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8),
        +        U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53),
        +        U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8),
        +        U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb),
        +        U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3),
        +        U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60),
        +        U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec),
        +        U64(0x90befffa23631e28),U64(0xa4506cebde82bde9),
        +        U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b),
        +        U64(0xca273eceea26619c),U64(0xd186b8c721c0c207),
        +        U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178),
        +        U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6),
        +        U64(0x113f9804bef90dae),U64(0x1b710b35131c471b),
        +        U64(0x28db77f523047d84),U64(0x32caab7b40c72493),
        +        U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c),
        +        U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a),
        +        U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) };
        +
        +#ifndef PEDANTIC
        +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +#  if defined(__x86_64) || defined(__x86_64__)
        +#   define ROTR(a,n)	({ SHA_LONG64 ret;		\
        +				asm ("rorq %1,%0"	\
        +				: "=r"(ret)		\
        +				: "J"(n),"0"(a)		\
        +				: "cc"); ret;		})
        +#   if !defined(B_ENDIAN)
        +#    define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));	\
        +				asm ("bswapq	%0"		\
        +				: "=r"(ret)			\
        +				: "0"(ret)); ret;		})
        +#   endif
        +#  elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
        +#   if defined(I386_ONLY)
        +#    define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
        +			 unsigned int hi=p[0],lo=p[1];		\
        +				asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
        +				    "roll $16,%%eax; roll $16,%%edx; "\
        +				    "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \
        +				: "=a"(lo),"=d"(hi)		\
        +				: "0"(lo),"1"(hi) : "cc");	\
        +				((SHA_LONG64)hi)<<32|lo;	})
        +#   else
        +#    define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
        +			 unsigned int hi=p[0],lo=p[1];		\
        +				asm ("bswapl %0; bswapl %1;"	\
        +				: "=r"(lo),"=r"(hi)		\
        +				: "0"(lo),"1"(hi));		\
        +				((SHA_LONG64)hi)<<32|lo;	})
        +#   endif
        +#  elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
        +#   define ROTR(a,n)	({ SHA_LONG64 ret;		\
        +				asm ("rotrdi %0,%1,%2"	\
        +				: "=r"(ret)		\
        +				: "r"(a),"K"(n)); ret;	})
        +#  endif
        +# elif defined(_MSC_VER)
        +#  if defined(_WIN64)	/* applies to both IA-64 and AMD64 */
        +#   pragma intrinsic(_rotr64)
        +#   define ROTR(a,n)	_rotr64((a),n)
        +#  endif
        +#  if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
        +#   if defined(I386_ONLY)
        +    static SHA_LONG64 __fastcall __pull64be(const void *x)
        +    {	_asm	mov	edx, [ecx + 0]
        +	_asm	mov	eax, [ecx + 4]
        +	_asm	xchg	dh,dl
        +	_asm	xchg	ah,al
        +	_asm	rol	edx,16
        +	_asm	rol	eax,16
        +	_asm	xchg	dh,dl
        +	_asm	xchg	ah,al
        +    }
        +#   else
        +    static SHA_LONG64 __fastcall __pull64be(const void *x)
        +    {	_asm	mov	edx, [ecx + 0]
        +	_asm	mov	eax, [ecx + 4]
        +	_asm	bswap	edx
        +	_asm	bswap	eax
        +    }
        +#   endif
        +#   define PULL64(x) __pull64be(&(x))
        +#   if _MSC_VER<=1200
        +#    pragma inline_depth(0)
        +#   endif
        +#  endif
        +# endif
        +#endif
        +
        +#ifndef PULL64
        +#define B(x,j)    (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
        +#define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
        +#endif
        +
        +#ifndef ROTR
        +#define ROTR(x,s)	(((x)>>s) | (x)<<(64-s))
        +#endif
        +
        +#define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
        +#define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
        +#define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
        +#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
        +
        +#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
        +#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
        +
        +
        +#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
        +/*
        + * This code should give better results on 32-bit CPU with less than
        + * ~24 registers, both size and performance wise...
        + */
        +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
        +	{
        +	const SHA_LONG64 *W=in;
        +	SHA_LONG64	A,E,T;
        +	SHA_LONG64	X[9+80],*F;
        +	int i;
        +
        +			while (num--) {
        +
        +	F    = X+80;
        +	A    = ctx->h[0];	F[1] = ctx->h[1];
        +	F[2] = ctx->h[2];	F[3] = ctx->h[3];
        +	E    = ctx->h[4];	F[5] = ctx->h[5];
        +	F[6] = ctx->h[6];	F[7] = ctx->h[7];
        +
        +	for (i=0;i<16;i++,F--)
        +		{
        +#ifdef B_ENDIAN
        +		T = W[i];
        +#else
        +		T = PULL64(W[i]);
        +#endif
        +		F[0] = A;
        +		F[4] = E;
        +		F[8] = T;
        +		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
        +		E    = F[3] + T;
        +		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
        +		}
        +
        +	for (;i<80;i++,F--)
        +		{
        +		T    = sigma0(F[8+16-1]);
        +		T   += sigma1(F[8+16-14]);
        +		T   += F[8+16] + F[8+16-9];
        +
        +		F[0] = A;
        +		F[4] = E;
        +		F[8] = T;
        +		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
        +		E    = F[3] + T;
        +		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
        +		}
        +
        +	ctx->h[0] += A;		ctx->h[1] += F[1];
        +	ctx->h[2] += F[2];	ctx->h[3] += F[3];
        +	ctx->h[4] += E;		ctx->h[5] += F[5];
        +	ctx->h[6] += F[6];	ctx->h[7] += F[7];
        +
        +			W+=SHA_LBLOCK;
        +			}
        +	}
        +
        +#elif defined(OPENSSL_SMALL_FOOTPRINT)
        +
        +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
        +	{
        +	const SHA_LONG64 *W=in;
        +	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1,T2;
        +	SHA_LONG64	X[16];
        +	int i;
        +
        +			while (num--) {
        +
        +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
        +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
        +
        +	for (i=0;i<16;i++)
        +		{
        +#ifdef B_ENDIAN
        +		T1 = X[i] = W[i];
        +#else
        +		T1 = X[i] = PULL64(W[i]);
        +#endif
        +		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
        +		T2 = Sigma0(a) + Maj(a,b,c);
        +		h = g;	g = f;	f = e;	e = d + T1;
        +		d = c;	c = b;	b = a;	a = T1 + T2;
        +		}
        +
        +	for (;i<80;i++)
        +		{
        +		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);
        +		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);
        +
        +		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
        +		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
        +		T2 = Sigma0(a) + Maj(a,b,c);
        +		h = g;	g = f;	f = e;	e = d + T1;
        +		d = c;	c = b;	b = a;	a = T1 + T2;
        +		}
        +
        +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
        +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
        +
        +			W+=SHA_LBLOCK;
        +			}
        +	}
        +
        +#else
        +
        +#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\
        +	T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];	\
        +	h = Sigma0(a) + Maj(a,b,c);			\
        +	d += T1;	h += T1;		} while (0)
        +
        +#define	ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)	do {	\
        +	s0 = X[(j+1)&0x0f];	s0 = sigma0(s0);	\
        +	s1 = X[(j+14)&0x0f];	s1 = sigma1(s1);	\
        +	T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];	\
        +	ROUND_00_15(i+j,a,b,c,d,e,f,g,h);		} while (0)
        +
        +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
        +	{
        +	const SHA_LONG64 *W=in;
        +	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1;
        +	SHA_LONG64	X[16];
        +	int i;
        +
        +			while (num--) {
        +
        +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
        +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
        +
        +#ifdef B_ENDIAN
        +	T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h);
        +	T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g);
        +	T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f);
        +	T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e);
        +	T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d);
        +	T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c);
        +	T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b);
        +	T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a);
        +	T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h);
        +	T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g);
        +	T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f);
        +	T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e);
        +	T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d);
        +	T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c);
        +	T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b);
        +	T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a);
        +#else
        +	T1 = X[0]  = PULL64(W[0]);	ROUND_00_15(0,a,b,c,d,e,f,g,h);
        +	T1 = X[1]  = PULL64(W[1]);	ROUND_00_15(1,h,a,b,c,d,e,f,g);
        +	T1 = X[2]  = PULL64(W[2]);	ROUND_00_15(2,g,h,a,b,c,d,e,f);
        +	T1 = X[3]  = PULL64(W[3]);	ROUND_00_15(3,f,g,h,a,b,c,d,e);
        +	T1 = X[4]  = PULL64(W[4]);	ROUND_00_15(4,e,f,g,h,a,b,c,d);
        +	T1 = X[5]  = PULL64(W[5]);	ROUND_00_15(5,d,e,f,g,h,a,b,c);
        +	T1 = X[6]  = PULL64(W[6]);	ROUND_00_15(6,c,d,e,f,g,h,a,b);
        +	T1 = X[7]  = PULL64(W[7]);	ROUND_00_15(7,b,c,d,e,f,g,h,a);
        +	T1 = X[8]  = PULL64(W[8]);	ROUND_00_15(8,a,b,c,d,e,f,g,h);
        +	T1 = X[9]  = PULL64(W[9]);	ROUND_00_15(9,h,a,b,c,d,e,f,g);
        +	T1 = X[10] = PULL64(W[10]);	ROUND_00_15(10,g,h,a,b,c,d,e,f);
        +	T1 = X[11] = PULL64(W[11]);	ROUND_00_15(11,f,g,h,a,b,c,d,e);
        +	T1 = X[12] = PULL64(W[12]);	ROUND_00_15(12,e,f,g,h,a,b,c,d);
        +	T1 = X[13] = PULL64(W[13]);	ROUND_00_15(13,d,e,f,g,h,a,b,c);
        +	T1 = X[14] = PULL64(W[14]);	ROUND_00_15(14,c,d,e,f,g,h,a,b);
        +	T1 = X[15] = PULL64(W[15]);	ROUND_00_15(15,b,c,d,e,f,g,h,a);
        +#endif
        +
        +	for (i=16;i<80;i+=16)
        +		{
        +		ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
        +		ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
        +		ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
        +		ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
        +		ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
        +		ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
        +		ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
        +		ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
        +		ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
        +		ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
        +		ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
        +		ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
        +		ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
        +		ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
        +		ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
        +		ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
        +		}
        +
        +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
        +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
        +
        +			W+=SHA_LBLOCK;
        +			}
        +	}
        +
        +#endif
        +
        +#endif /* SHA512_ASM */
        +
        +#else /* !OPENSSL_NO_SHA512 */
        +
        +#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
        +static void *dummy=&dummy;
        +#endif
        +
        +#endif /* !OPENSSL_NO_SHA512 */
        diff --git a/vendor/openssl/openssl/crypto/sha/sha512t.c b/vendor/openssl/openssl/crypto/sha/sha512t.c
        new file mode 100644
        index 000000000..210041d43
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha512t.c
        @@ -0,0 +1,184 @@
        +/* crypto/sha/sha512t.c */
        +/* ====================================================================
        + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
        + * ====================================================================
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include <openssl/sha.h>
        +#include <openssl/evp.h>
        +#include <openssl/crypto.h>
        +
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512)
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA512 support\n");
        +    return(0);
        +}
        +#else
        +
        +unsigned char app_c1[SHA512_DIGEST_LENGTH] = {
        +	0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,
        +	0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,
        +	0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,
        +	0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,
        +	0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,
        +	0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,
        +	0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,
        +	0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f };
        +
        +unsigned char app_c2[SHA512_DIGEST_LENGTH] = {
        +	0x8e,0x95,0x9b,0x75,0xda,0xe3,0x13,0xda,
        +	0x8c,0xf4,0xf7,0x28,0x14,0xfc,0x14,0x3f,
        +	0x8f,0x77,0x79,0xc6,0xeb,0x9f,0x7f,0xa1,
        +	0x72,0x99,0xae,0xad,0xb6,0x88,0x90,0x18,
        +	0x50,0x1d,0x28,0x9e,0x49,0x00,0xf7,0xe4,
        +	0x33,0x1b,0x99,0xde,0xc4,0xb5,0x43,0x3a,
        +	0xc7,0xd3,0x29,0xee,0xb6,0xdd,0x26,0x54,
        +	0x5e,0x96,0xe5,0x5b,0x87,0x4b,0xe9,0x09 };
        +
        +unsigned char app_c3[SHA512_DIGEST_LENGTH] = {
        +	0xe7,0x18,0x48,0x3d,0x0c,0xe7,0x69,0x64,
        +	0x4e,0x2e,0x42,0xc7,0xbc,0x15,0xb4,0x63,
        +	0x8e,0x1f,0x98,0xb1,0x3b,0x20,0x44,0x28,
        +	0x56,0x32,0xa8,0x03,0xaf,0xa9,0x73,0xeb,
        +	0xde,0x0f,0xf2,0x44,0x87,0x7e,0xa6,0x0a,
        +	0x4c,0xb0,0x43,0x2c,0xe5,0x77,0xc3,0x1b,
        +	0xeb,0x00,0x9c,0x5c,0x2c,0x49,0xaa,0x2e,
        +	0x4e,0xad,0xb2,0x17,0xad,0x8c,0xc0,0x9b };
        +
        +unsigned char app_d1[SHA384_DIGEST_LENGTH] = {
        +	0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b,
        +	0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07,
        +	0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63,
        +	0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed,
        +	0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23,
        +	0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7 };
        +
        +unsigned char app_d2[SHA384_DIGEST_LENGTH] = {
        +	0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8,
        +	0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47,
        +	0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2,
        +	0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12,
        +	0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9,
        +	0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39 };
        +
        +unsigned char app_d3[SHA384_DIGEST_LENGTH] = {
        +	0x9d,0x0e,0x18,0x09,0x71,0x64,0x74,0xcb,
        +	0x08,0x6e,0x83,0x4e,0x31,0x0a,0x4a,0x1c,
        +	0xed,0x14,0x9e,0x9c,0x00,0xf2,0x48,0x52,
        +	0x79,0x72,0xce,0xc5,0x70,0x4c,0x2a,0x5b,
        +	0x07,0xb8,0xb3,0xdc,0x38,0xec,0xc4,0xeb,
        +	0xae,0x97,0xdd,0xd8,0x7f,0x3d,0x89,0x85 };
        +
        +int main (int argc,char **argv)
        +{ unsigned char md[SHA512_DIGEST_LENGTH];
        +  int		i;
        +  EVP_MD_CTX	evp;
        +
        +#ifdef OPENSSL_IA32_SSE2
        +    /* Alternative to this is to call OpenSSL_add_all_algorithms...
        +     * The below code is retained exclusively for debugging purposes. */
        +    { char      *env;
        +
        +	if ((env=getenv("OPENSSL_ia32cap")))
        +	    OPENSSL_ia32cap = strtoul (env,NULL,0);
        +    }
        +#endif
        +
        +    fprintf(stdout,"Testing SHA-512 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha512(),NULL);
        +    if (memcmp(md,app_c1,sizeof(app_c1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
        +		"efghijkl""fghijklm""ghijklmn""hijklmno"
        +		"ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
        +		"mnopqrst""nopqrstu",112,md,NULL,EVP_sha512(),NULL);
        +    if (memcmp(md,app_c2,sizeof(app_c2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha512(),NULL);
        +    for (i=0;i<1000000;i+=288)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<288?1000000-i:288);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,app_c3,sizeof(app_c3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +    fprintf(stdout,"Testing SHA-384 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha384(),NULL);
        +    if (memcmp(md,app_d1,sizeof(app_d1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
        +		"efghijkl""fghijklm""ghijklmn""hijklmno"
        +		"ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
        +		"mnopqrst""nopqrstu",112,md,NULL,EVP_sha384(),NULL);
        +    if (memcmp(md,app_d2,sizeof(app_d2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha384(),NULL);
        +    for (i=0;i<1000000;i+=64)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<64?1000000-i:64);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,app_d3,sizeof(app_d3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +  return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/sha_dgst.c b/vendor/openssl/openssl/crypto/sha/sha_dgst.c
        new file mode 100644
        index 000000000..fb63b17ff
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha_dgst.c
        @@ -0,0 +1,75 @@
        +/* crypto/sha/sha1dgst.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <openssl/crypto.h>
        +#include <openssl/opensslconf.h>
        +#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
        +
        +#undef  SHA_1
        +#define SHA_0
        +
        +#include <openssl/opensslv.h>
        +
        +const char SHA_version[]="SHA" OPENSSL_VERSION_PTEXT;
        +
        +/* The implementation is in ../md32_common.h */
        +
        +#include "sha_locl.h"
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/sha/sha_locl.h b/vendor/openssl/openssl/crypto/sha/sha_locl.h
        new file mode 100644
        index 000000000..d673255f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha_locl.h
        @@ -0,0 +1,441 @@
        +/* crypto/sha/sha_locl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/sha.h>
        +
        +#define DATA_ORDER_IS_BIG_ENDIAN
        +
        +#define HASH_LONG               SHA_LONG
        +#define HASH_CTX                SHA_CTX
        +#define HASH_CBLOCK             SHA_CBLOCK
        +#define HASH_MAKE_STRING(c,s)   do {	\
        +	unsigned long ll;		\
        +	ll=(c)->h0; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->h1; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->h2; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->h3; (void)HOST_l2c(ll,(s));	\
        +	ll=(c)->h4; (void)HOST_l2c(ll,(s));	\
        +	} while (0)
        +
        +#if defined(SHA_0)
        +
        +# define HASH_UPDATE             	SHA_Update
        +# define HASH_TRANSFORM          	SHA_Transform
        +# define HASH_FINAL              	SHA_Final
        +# define HASH_INIT			SHA_Init
        +# define HASH_BLOCK_DATA_ORDER   	sha_block_data_order
        +# define Xupdate(a,ix,ia,ib,ic,id)	(ix=(a)=(ia^ib^ic^id))
        +
        +static void sha_block_data_order (SHA_CTX *c, const void *p,size_t num);
        +
        +#elif defined(SHA_1)
        +
        +# define HASH_UPDATE             	SHA1_Update
        +# define HASH_TRANSFORM          	SHA1_Transform
        +# define HASH_FINAL              	SHA1_Final
        +# define HASH_INIT			SHA1_Init
        +# define HASH_BLOCK_DATA_ORDER   	sha1_block_data_order
        +# if defined(__MWERKS__) && defined(__MC68K__)
        +   /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
        +#  define Xupdate(a,ix,ia,ib,ic,id)	do { (a)=(ia^ib^ic^id);		\
        +					     ix=(a)=ROTATE((a),1);	\
        +					} while (0)
        +# else
        +#  define Xupdate(a,ix,ia,ib,ic,id)	( (a)=(ia^ib^ic^id),	\
        +					  ix=(a)=ROTATE((a),1)	\
        +					)
        +# endif
        +
        +#ifndef SHA1_ASM
        +static
        +#endif
        +void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num);
        +
        +#else
        +# error "Either SHA_0 or SHA_1 must be defined."
        +#endif
        +
        +#include "md32_common.h"
        +
        +#define INIT_DATA_h0 0x67452301UL
        +#define INIT_DATA_h1 0xefcdab89UL
        +#define INIT_DATA_h2 0x98badcfeUL
        +#define INIT_DATA_h3 0x10325476UL
        +#define INIT_DATA_h4 0xc3d2e1f0UL
        +
        +#ifdef SHA_0
        +fips_md_init(SHA)
        +#else
        +fips_md_init_ctx(SHA1, SHA)
        +#endif
        +	{
        +	memset (c,0,sizeof(*c));
        +	c->h0=INIT_DATA_h0;
        +	c->h1=INIT_DATA_h1;
        +	c->h2=INIT_DATA_h2;
        +	c->h3=INIT_DATA_h3;
        +	c->h4=INIT_DATA_h4;
        +	return 1;
        +	}
        +
        +#define K_00_19	0x5a827999UL
        +#define K_20_39 0x6ed9eba1UL
        +#define K_40_59 0x8f1bbcdcUL
        +#define K_60_79 0xca62c1d6UL
        +
        +/* As  pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
        + * simplified to the code in F_00_19.  Wei attributes these optimisations
        + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
        + * #define F(x,y,z) (((x) & (y))  |  ((~(x)) & (z)))
        + * I've just become aware of another tweak to be made, again from Wei Dai,
        + * in F_40_59, (x&a)|(y&a) -> (x|y)&a
        + */
        +#define	F_00_19(b,c,d)	((((c) ^ (d)) & (b)) ^ (d)) 
        +#define	F_20_39(b,c,d)	((b) ^ (c) ^ (d))
        +#define F_40_59(b,c,d)	(((b) & (c)) | (((b)|(c)) & (d))) 
        +#define	F_60_79(b,c,d)	F_20_39(b,c,d)
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +
        +#define BODY_00_15(i,a,b,c,d,e,f,xi) \
        +	(f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
        +	(b)=ROTATE((b),30);
        +
        +#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
        +	Xupdate(f,xi,xa,xb,xc,xd); \
        +	(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
        +	(b)=ROTATE((b),30);
        +
        +#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
        +	Xupdate(f,xi,xa,xb,xc,xd); \
        +	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
        +	(b)=ROTATE((b),30);
        +
        +#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
        +	Xupdate(f,xa,xa,xb,xc,xd); \
        +	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
        +	(b)=ROTATE((b),30);
        +
        +#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
        +	Xupdate(f,xa,xa,xb,xc,xd); \
        +	(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
        +	(b)=ROTATE((b),30);
        +
        +#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
        +	Xupdate(f,xa,xa,xb,xc,xd); \
        +	(f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
        +	(b)=ROTATE((b),30);
        +
        +#ifdef X
        +#undef X
        +#endif
        +#ifndef MD32_XARRAY
        +  /*
        +   * Originally X was an array. As it's automatic it's natural
        +   * to expect RISC compiler to accomodate at least part of it in
        +   * the register bank, isn't it? Unfortunately not all compilers
        +   * "find" this expectation reasonable:-( On order to make such
        +   * compilers generate better code I replace X[] with a bunch of
        +   * X0, X1, etc. See the function body below...
        +   *					<appro@fy.chalmers.se>
        +   */
        +# define X(i)	XX##i
        +#else
        +  /*
        +   * However! Some compilers (most notably HP C) get overwhelmed by
        +   * that many local variables so that we have to have the way to
        +   * fall down to the original behavior.
        +   */
        +# define X(i)	XX[i]
        +#endif
        +
        +#if !defined(SHA_1) || !defined(SHA1_ASM)
        +static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
        +	{
        +	const unsigned char *data=p;
        +	register unsigned MD32_REG_T A,B,C,D,E,T,l;
        +#ifndef MD32_XARRAY
        +	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
        +				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
        +#else
        +	SHA_LONG	XX[16];
        +#endif
        +
        +	A=c->h0;
        +	B=c->h1;
        +	C=c->h2;
        +	D=c->h3;
        +	E=c->h4;
        +
        +	for (;;)
        +			{
        +	const union { long one; char little; } is_endian = {1};
        +
        +	if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)p%4)==0)
        +		{
        +		const SHA_LONG *W=(const SHA_LONG *)data;
        +
        +		X( 0) = W[0];				X( 1) = W[ 1];
        +		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	X( 2) = W[ 2];
        +		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	X( 3) = W[ 3];
        +		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	X( 4) = W[ 4];
        +		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	X( 5) = W[ 5];
        +		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	X( 6) = W[ 6];
        +		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	X( 7) = W[ 7];
        +		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	X( 8) = W[ 8];
        +		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	X( 9) = W[ 9];
        +		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	X(10) = W[10];
        +		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	X(11) = W[11];
        +		BODY_00_15(10,C,D,E,T,A,B,X(10));	X(12) = W[12];
        +		BODY_00_15(11,B,C,D,E,T,A,X(11));	X(13) = W[13];
        +		BODY_00_15(12,A,B,C,D,E,T,X(12));	X(14) = W[14];
        +		BODY_00_15(13,T,A,B,C,D,E,X(13));	X(15) = W[15];
        +		BODY_00_15(14,E,T,A,B,C,D,X(14));
        +		BODY_00_15(15,D,E,T,A,B,C,X(15));
        +
        +		data += SHA_CBLOCK;
        +		}
        +	else
        +		{
        +		(void)HOST_c2l(data,l); X( 0)=l;	(void)HOST_c2l(data,l); X( 1)=l;
        +		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	(void)HOST_c2l(data,l); X( 2)=l;
        +		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	(void)HOST_c2l(data,l); X( 3)=l;
        +		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	(void)HOST_c2l(data,l); X( 4)=l;
        +		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	(void)HOST_c2l(data,l); X( 5)=l;
        +		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	(void)HOST_c2l(data,l); X( 6)=l;
        +		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	(void)HOST_c2l(data,l); X( 7)=l;
        +		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	(void)HOST_c2l(data,l); X( 8)=l;
        +		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	(void)HOST_c2l(data,l); X( 9)=l;
        +		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	(void)HOST_c2l(data,l); X(10)=l;
        +		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	(void)HOST_c2l(data,l); X(11)=l;
        +		BODY_00_15(10,C,D,E,T,A,B,X(10));	(void)HOST_c2l(data,l); X(12)=l;
        +		BODY_00_15(11,B,C,D,E,T,A,X(11));	(void)HOST_c2l(data,l); X(13)=l;
        +		BODY_00_15(12,A,B,C,D,E,T,X(12));	(void)HOST_c2l(data,l); X(14)=l;
        +		BODY_00_15(13,T,A,B,C,D,E,X(13));	(void)HOST_c2l(data,l); X(15)=l;
        +		BODY_00_15(14,E,T,A,B,C,D,X(14));
        +		BODY_00_15(15,D,E,T,A,B,C,X(15));
        +		}
        +
        +	BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
        +	BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
        +	BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
        +	BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
        +
        +	BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
        +	BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
        +	BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
        +	BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
        +	BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
        +	BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
        +	BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
        +	BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
        +	BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
        +	BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
        +	BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
        +	BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
        +
        +	BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
        +	BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
        +	BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
        +	BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
        +	BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
        +	BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
        +	BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
        +	BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
        +
        +	BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
        +	BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
        +	BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
        +	BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
        +	BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
        +	BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
        +	BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
        +	BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
        +	BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
        +	BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
        +	BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
        +	BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
        +	BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
        +	BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
        +	BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
        +	BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
        +	BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
        +	BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
        +	BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
        +	BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
        +
        +	BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
        +	BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
        +	BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
        +	BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
        +	BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
        +	BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
        +	BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
        +	BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
        +	BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
        +	BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
        +	BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
        +	BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
        +	BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
        +	BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
        +	BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
        +	BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
        +	BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
        +	BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
        +	BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
        +	BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
        +	
        +	c->h0=(c->h0+E)&0xffffffffL; 
        +	c->h1=(c->h1+T)&0xffffffffL;
        +	c->h2=(c->h2+A)&0xffffffffL;
        +	c->h3=(c->h3+B)&0xffffffffL;
        +	c->h4=(c->h4+C)&0xffffffffL;
        +
        +	if (--num == 0) break;
        +
        +	A=c->h0;
        +	B=c->h1;
        +	C=c->h2;
        +	D=c->h3;
        +	E=c->h4;
        +
        +			}
        +	}
        +#endif
        +
        +#else	/* OPENSSL_SMALL_FOOTPRINT */
        +
        +#define BODY_00_15(xi)		 do {	\
        +	T=E+K_00_19+F_00_19(B,C,D);	\
        +	E=D, D=C, C=ROTATE(B,30), B=A;	\
        +	A=ROTATE(A,5)+T+xi;	    } while(0)
        +
        +#define BODY_16_19(xa,xb,xc,xd)	 do {	\
        +	Xupdate(T,xa,xa,xb,xc,xd);	\
        +	T+=E+K_00_19+F_00_19(B,C,D);	\
        +	E=D, D=C, C=ROTATE(B,30), B=A;	\
        +	A=ROTATE(A,5)+T;	    } while(0)
        +
        +#define BODY_20_39(xa,xb,xc,xd)	 do {	\
        +	Xupdate(T,xa,xa,xb,xc,xd);	\
        +	T+=E+K_20_39+F_20_39(B,C,D);	\
        +	E=D, D=C, C=ROTATE(B,30), B=A;	\
        +	A=ROTATE(A,5)+T;	    } while(0)
        +
        +#define BODY_40_59(xa,xb,xc,xd)	 do {	\
        +	Xupdate(T,xa,xa,xb,xc,xd);	\
        +	T+=E+K_40_59+F_40_59(B,C,D);	\
        +	E=D, D=C, C=ROTATE(B,30), B=A;	\
        +	A=ROTATE(A,5)+T;	    } while(0)
        +
        +#define BODY_60_79(xa,xb,xc,xd)	 do {	\
        +	Xupdate(T,xa,xa,xb,xc,xd);	\
        +	T=E+K_60_79+F_60_79(B,C,D);	\
        +	E=D, D=C, C=ROTATE(B,30), B=A;	\
        +	A=ROTATE(A,5)+T+xa;	    } while(0)
        +
        +#if !defined(SHA_1) || !defined(SHA1_ASM)
        +static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
        +	{
        +	const unsigned char *data=p;
        +	register unsigned MD32_REG_T A,B,C,D,E,T,l;
        +	int i;
        +	SHA_LONG	X[16];
        +
        +	A=c->h0;
        +	B=c->h1;
        +	C=c->h2;
        +	D=c->h3;
        +	E=c->h4;
        +
        +	for (;;)
        +		{
        +	for (i=0;i<16;i++)
        +	{ HOST_c2l(data,l); X[i]=l; BODY_00_15(X[i]); }
        +	for (i=0;i<4;i++)
        +	{ BODY_16_19(X[i],       X[i+2],      X[i+8],     X[(i+13)&15]); }
        +	for (;i<24;i++)
        +	{ BODY_20_39(X[i&15],    X[(i+2)&15], X[(i+8)&15],X[(i+13)&15]); }
        +	for (i=0;i<20;i++)
        +	{ BODY_40_59(X[(i+8)&15],X[(i+10)&15],X[i&15],    X[(i+5)&15]);  }
        +	for (i=4;i<24;i++)
        +	{ BODY_60_79(X[(i+8)&15],X[(i+10)&15],X[i&15],    X[(i+5)&15]);  }
        +
        +	c->h0=(c->h0+A)&0xffffffffL; 
        +	c->h1=(c->h1+B)&0xffffffffL;
        +	c->h2=(c->h2+C)&0xffffffffL;
        +	c->h3=(c->h3+D)&0xffffffffL;
        +	c->h4=(c->h4+E)&0xffffffffL;
        +
        +	if (--num == 0) break;
        +
        +	A=c->h0;
        +	B=c->h1;
        +	C=c->h2;
        +	D=c->h3;
        +	E=c->h4;
        +
        +		}
        +	}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/sha_one.c b/vendor/openssl/openssl/crypto/sha/sha_one.c
        new file mode 100644
        index 000000000..3bae623ce
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/sha_one.c
        @@ -0,0 +1,78 @@
        +/* crypto/sha/sha_one.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/sha.h>
        +#include <openssl/crypto.h>
        +
        +#ifndef OPENSSL_NO_SHA0
        +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md)
        +	{
        +	SHA_CTX c;
        +	static unsigned char m[SHA_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	if (!SHA_Init(&c))
        +		return NULL;
        +	SHA_Update(&c,d,n);
        +	SHA_Final(md,&c);
        +	OPENSSL_cleanse(&c,sizeof(c));
        +	return(md);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sha/shatest.c b/vendor/openssl/openssl/crypto/sha/shatest.c
        new file mode 100644
        index 000000000..27614646d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sha/shatest.c
        @@ -0,0 +1,178 @@
        +/* crypto/sha/shatest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0)
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA0 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/sha.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +#define SHA_0 /* FIPS 180 */
        +#undef  SHA_1 /* FIPS 180-1 */
        +
        +static char *test[]={
        +	"abc",
        +	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
        +	NULL,
        +	};
        +
        +#ifdef SHA_0
        +static char *ret[]={
        +	"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
        +	"d2516ee1acfa5baf33dfc1c471e438449ef134c8",
        +	};
        +static char *bigret=
        +	"3232affa48628a26653b5aaa44541fd90d690603";
        +#endif
        +#ifdef SHA_1
        +static char *ret[]={
        +	"a9993e364706816aba3e25717850c26c9cd0d89d",
        +	"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
        +	};
        +static char *bigret=
        +	"34aa973cd4c4daa4f61eeb2bdbad27316534016f";
        +#endif
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	static unsigned char buf[1000];
        +	char *p,*r;
        +	EVP_MD_CTX c;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(test[0], test[0], strlen(test[0]));
        +	ebcdic2ascii(test[1], test[1], strlen(test[1]));
        +#endif
        +
        +	EVP_MD_CTX_init(&c);
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(*P,strlen(*P),md,NULL,EVP_sha(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,*R) != 0)
        +			{
        +			printf("error calculating SHA on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +
        +	memset(buf,'a',1000);
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(buf, buf, 1000);
        +#endif /*CHARSET_EBCDIC*/
        +	EVP_DigestInit_ex(&c,EVP_sha(), NULL);
        +	for (i=0; i<1000; i++)
        +		EVP_DigestUpdate(&c,buf,1000);
        +	EVP_DigestFinal_ex(&c,md,NULL);
        +	p=pt(md);
        +
        +	r=bigret;
        +	if (strcmp(p,r) != 0)
        +		{
        +		printf("error calculating SHA on '%s'\n",p);
        +		printf("got %s instead of %s\n",p,r);
        +		err++;
        +		}
        +	else
        +		printf("test 3 ok\n");
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EVP_MD_CTX_cleanup(&c);
        +	EXIT(err);
        +	return(0);
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<SHA_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/sparccpuid.S b/vendor/openssl/openssl/crypto/sparccpuid.S
        new file mode 100644
        index 000000000..0cc247e48
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sparccpuid.S
        @@ -0,0 +1,402 @@
        +#if defined(__SUNPRO_C) && defined(__sparcv9)
        +# define ABI64  /* They've said -xarch=v9 at command line */
        +#elif defined(__GNUC__) && defined(__arch64__)
        +# define ABI64  /* They've said -m64 at command line */
        +#endif
        +
        +#ifdef ABI64
        +  .register	%g2,#scratch
        +  .register	%g3,#scratch
        +# define	FRAME	-192
        +# define	BIAS	2047
        +#else
        +# define	FRAME	-96
        +# define	BIAS	0
        +#endif
        +
        +.text
        +.align	32
        +.global	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,#function
        +! Keep in mind that this does not excuse us from wiping the stack!
        +! This routine wipes registers, but not the backing store [which
        +! resides on the stack, toward lower addresses]. To facilitate for
        +! stack wiping I return pointer to the top of stack of the *caller*.
        +OPENSSL_wipe_cpu:
        +	save	%sp,FRAME,%sp
        +	nop
        +#ifdef __sun
        +#include <sys/trap.h>
        +	ta	ST_CLEAN_WINDOWS
        +#else
        +	call	.walk.reg.wins
        +#endif
        +	nop
        +	call	.PIC.zero.up
        +	mov	.zero-(.-4),%o0
        +	ld	[%o0],%f0
        +	ld	[%o0],%f1
        +
        +	subcc	%g0,1,%o0
        +	! Following is V9 "rd %ccr,%o0" instruction. However! V8
        +	! specification says that it ("rd %asr2,%o0" in V8 terms) does
        +	! not cause illegal_instruction trap. It therefore can be used
        +	! to determine if the CPU the code is executing on is V8- or
        +	! V9-compliant, as V9 returns a distinct value of 0x99,
        +	! "negative" and "borrow" bits set in both %icc and %xcc.
        +	.word	0x91408000	!rd	%ccr,%o0
        +	cmp	%o0,0x99
        +	bne	.v8
        +	nop
        +			! Even though we do not use %fp register bank,
        +			! we wipe it as memcpy might have used it...
        +			.word	0xbfa00040	!fmovd	%f0,%f62
        +			.word	0xbba00040	!...
        +			.word	0xb7a00040
        +			.word	0xb3a00040
        +			.word	0xafa00040
        +			.word	0xaba00040
        +			.word	0xa7a00040
        +			.word	0xa3a00040
        +			.word	0x9fa00040
        +			.word	0x9ba00040
        +			.word	0x97a00040
        +			.word	0x93a00040
        +			.word	0x8fa00040
        +			.word	0x8ba00040
        +			.word	0x87a00040
        +			.word	0x83a00040	!fmovd	%f0,%f32
        +.v8:			fmovs	%f1,%f31
        +	clr	%o0
        +			fmovs	%f0,%f30
        +	clr	%o1
        +			fmovs	%f1,%f29
        +	clr	%o2
        +			fmovs	%f0,%f28
        +	clr	%o3
        +			fmovs	%f1,%f27
        +	clr	%o4
        +			fmovs	%f0,%f26
        +	clr	%o5
        +			fmovs	%f1,%f25
        +	clr	%o7
        +			fmovs	%f0,%f24
        +	clr	%l0
        +			fmovs	%f1,%f23
        +	clr	%l1
        +			fmovs	%f0,%f22
        +	clr	%l2
        +			fmovs	%f1,%f21
        +	clr	%l3
        +			fmovs	%f0,%f20
        +	clr	%l4
        +			fmovs	%f1,%f19
        +	clr	%l5
        +			fmovs	%f0,%f18
        +	clr	%l6
        +			fmovs	%f1,%f17
        +	clr	%l7
        +			fmovs	%f0,%f16
        +	clr	%i0
        +			fmovs	%f1,%f15
        +	clr	%i1
        +			fmovs	%f0,%f14
        +	clr	%i2
        +			fmovs	%f1,%f13
        +	clr	%i3
        +			fmovs	%f0,%f12
        +	clr	%i4
        +			fmovs	%f1,%f11
        +	clr	%i5
        +			fmovs	%f0,%f10
        +	clr	%g1
        +			fmovs	%f1,%f9
        +	clr	%g2
        +			fmovs	%f0,%f8
        +	clr	%g3
        +			fmovs	%f1,%f7
        +	clr	%g4
        +			fmovs	%f0,%f6
        +	clr	%g5
        +			fmovs	%f1,%f5
        +			fmovs	%f0,%f4
        +			fmovs	%f1,%f3
        +			fmovs	%f0,%f2
        +
        +	add	%fp,BIAS,%i0	! return pointer to caller´s top of stack
        +
        +	ret
        +	restore
        +
        +.zero:	.long	0x0,0x0
        +.PIC.zero.up:
        +	retl
        +	add	%o0,%o7,%o0
        +#ifdef DEBUG
        +.global	walk_reg_wins
        +.type	walk_reg_wins,#function
        +walk_reg_wins:
        +#endif
        +.walk.reg.wins:
        +	save	%sp,FRAME,%sp
        +	cmp	%i7,%o7
        +	be	2f
        +	clr	%o0
        +	cmp	%o7,0	! compiler never cleans %o7...
        +	be	1f	! could have been a leaf function...
        +	clr	%o1
        +	call	.walk.reg.wins
        +	nop
        +1:	clr	%o2
        +	clr	%o3
        +	clr	%o4
        +	clr	%o5
        +	clr	%o7
        +	clr	%l0
        +	clr	%l1
        +	clr	%l2
        +	clr	%l3
        +	clr	%l4
        +	clr	%l5
        +	clr	%l6
        +	clr	%l7
        +	add	%o0,1,%i0	! used for debugging
        +2:	ret
        +	restore
        +.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
        +
        +.global	OPENSSL_atomic_add
        +.type	OPENSSL_atomic_add,#function
        +.align	32
        +OPENSSL_atomic_add:
        +#ifndef ABI64
        +	subcc	%g0,1,%o2
        +	.word	0x95408000	!rd	%ccr,%o2, see comment above
        +	cmp	%o2,0x99
        +	be	.v9
        +	nop
        +	save	%sp,FRAME,%sp
        +	ba	.enter
        +	nop
        +#ifdef __sun
        +! Note that you do not have to link with libthread to call thr_yield,
        +! as libc provides a stub, which is overloaded the moment you link
        +! with *either* libpthread or libthread...
        +#define	YIELD_CPU	thr_yield
        +#else
        +! applies at least to Linux and FreeBSD... Feedback expected...
        +#define	YIELD_CPU	sched_yield
        +#endif
        +.spin:	call	YIELD_CPU
        +	nop
        +.enter:	ld	[%i0],%i2
        +	cmp	%i2,-4096
        +	be	.spin
        +	mov	-1,%i2
        +	swap	[%i0],%i2
        +	cmp	%i2,-1
        +	be	.spin
        +	add	%i2,%i1,%i2
        +	stbar
        +	st	%i2,[%i0]
        +	sra	%i2,%g0,%i0
        +	ret
        +	restore
        +.v9:
        +#endif
        +	ld	[%o0],%o2
        +1:	add	%o1,%o2,%o3
        +	.word	0xd7e2100a	!cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
        +	cmp	%o2,%o3
        +	bne	1b
        +	mov	%o3,%o2		! cas is always fetching to dest. register
        +	add	%o1,%o2,%o0	! OpenSSL expects the new value
        +	retl
        +	sra	%o0,%g0,%o0	! we return signed int, remember?
        +.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
        +
        +.global	_sparcv9_rdtick
        +.align	32
        +_sparcv9_rdtick:
        +	subcc	%g0,1,%o0
        +	.word	0x91408000	!rd	%ccr,%o0
        +	cmp	%o0,0x99
        +	bne	.notick
        +	xor	%o0,%o0,%o0
        +	.word	0x91410000	!rd	%tick,%o0
        +	retl
        +	.word	0x93323020	!srlx	%o0,32,%o1
        +.notick:
        +	retl
        +	xor	%o1,%o1,%o1
        +.type	_sparcv9_rdtick,#function
        +.size	_sparcv9_rdtick,.-_sparcv9_rdtick
        +
        +.global	_sparcv9_vis1_probe
        +.align	8
        +_sparcv9_vis1_probe:
        +	add	%sp,BIAS+2,%o1
        +	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
        +	retl
        +	.word	0x81b00d80	!fxor	%f0,%f0,%f0
        +.type	_sparcv9_vis1_probe,#function
        +.size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
        +
        +! Probe and instrument VIS1 instruction. Output is number of cycles it
        +! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
        +! is slow (documented to be 6 cycles on T2) and the core is in-order
        +! single-issue, it should be possible to distinguish Tx reliably...
        +! Observed return values are:
        +!
        +!	UltraSPARC IIe		7
        +!	UltraSPARC III		7
        +!	UltraSPARC T1		24
        +!
        +! Numbers for T2 and SPARC64 V-VII are more than welcomed.
        +!
        +! It would be possible to detect specifically US-T1 by instrumenting
        +! fmul8ulx16, which is emulated on T1 and as such accounts for quite
        +! a lot of %tick-s, couple of thousand on Linux...
        +.global	_sparcv9_vis1_instrument
        +.align	8
        +_sparcv9_vis1_instrument:
        +	.word	0x91410000	!rd	%tick,%o0
        +	.word	0x81b00d80	!fxor	%f0,%f0,%f0
        +	.word	0x85b08d82	!fxor	%f2,%f2,%f2
        +	.word	0x93410000	!rd	%tick,%o1
        +	.word	0x81b00d80	!fxor	%f0,%f0,%f0
        +	.word	0x85b08d82	!fxor	%f2,%f2,%f2
        +	.word	0x95410000	!rd	%tick,%o2
        +	.word	0x81b00d80	!fxor	%f0,%f0,%f0
        +	.word	0x85b08d82	!fxor	%f2,%f2,%f2
        +	.word	0x97410000	!rd	%tick,%o3
        +	.word	0x81b00d80	!fxor	%f0,%f0,%f0
        +	.word	0x85b08d82	!fxor	%f2,%f2,%f2
        +	.word	0x99410000	!rd	%tick,%o4
        +
        +	! calculate intervals
        +	sub	%o1,%o0,%o0
        +	sub	%o2,%o1,%o1
        +	sub	%o3,%o2,%o2
        +	sub	%o4,%o3,%o3
        +
        +	! find minumum value
        +	cmp	%o0,%o1
        +	.word	0x38680002	!bgu,a	%xcc,.+8
        +	mov	%o1,%o0
        +	cmp	%o0,%o2
        +	.word	0x38680002	!bgu,a	%xcc,.+8
        +	mov	%o2,%o0
        +	cmp	%o0,%o3
        +	.word	0x38680002	!bgu,a	%xcc,.+8
        +	mov	%o3,%o0
        +
        +	retl
        +	nop
        +.type	_sparcv9_vis1_instrument,#function
        +.size	_sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
        +
        +.global	_sparcv9_vis2_probe
        +.align	8
        +_sparcv9_vis2_probe:
        +	retl
        +	.word	0x81b00980	!bshuffle	%f0,%f0,%f0
        +.type	_sparcv9_vis2_probe,#function
        +.size	_sparcv9_vis2_probe,.-_sparcv9_vis2_probe
        +
        +.global	_sparcv9_fmadd_probe
        +.align	8
        +_sparcv9_fmadd_probe:
        +	.word	0x81b00d80	!fxor	%f0,%f0,%f0
        +	.word	0x85b08d82	!fxor	%f2,%f2,%f2
        +	retl
        +	.word	0x81b80440	!fmaddd	%f0,%f0,%f2,%f0
        +.type	_sparcv9_fmadd_probe,#function
        +.size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
        +
        +.global	OPENSSL_cleanse
        +.align	32
        +OPENSSL_cleanse:
        +	cmp	%o1,14
        +	nop
        +#ifdef ABI64
        +	bgu	%xcc,.Lot
        +#else
        +	bgu	.Lot
        +#endif
        +	cmp	%o1,0
        +	bne	.Little
        +	nop
        +	retl
        +	nop
        +
        +.Little:
        +	stb	%g0,[%o0]
        +	subcc	%o1,1,%o1
        +	bnz	.Little
        +	add	%o0,1,%o0
        +	retl
        +	nop
        +.align	32
        +.Lot:
        +#ifndef ABI64
        +	subcc	%g0,1,%g1
        +	! see above for explanation
        +	.word	0x83408000	!rd	%ccr,%g1
        +	cmp	%g1,0x99
        +	bne	.v8lot
        +	nop
        +#endif
        +
        +.v9lot:	andcc	%o0,7,%g0
        +	bz	.v9aligned
        +	nop
        +	stb	%g0,[%o0]
        +	sub	%o1,1,%o1
        +	ba	.v9lot
        +	add	%o0,1,%o0
        +.align	16,0x01000000
        +.v9aligned:
        +	.word	0xc0720000	!stx	%g0,[%o0]
        +	sub	%o1,8,%o1
        +	andcc	%o1,-8,%g0
        +#ifdef ABI64
        +	.word	0x126ffffd	!bnz	%xcc,.v9aligned
        +#else
        +	.word	0x124ffffd	!bnz	%icc,.v9aligned
        +#endif
        +	add	%o0,8,%o0
        +
        +	cmp	%o1,0
        +	bne	.Little
        +	nop
        +	retl
        +	nop
        +#ifndef ABI64
        +.v8lot:	andcc	%o0,3,%g0
        +	bz	.v8aligned
        +	nop
        +	stb	%g0,[%o0]
        +	sub	%o1,1,%o1
        +	ba	.v8lot
        +	add	%o0,1,%o0
        +	nop
        +.v8aligned:
        +	st	%g0,[%o0]
        +	sub	%o1,4,%o1
        +	andcc	%o1,-4,%g0
        +	bnz	.v8aligned
        +	add	%o0,4,%o0
        +
        +	cmp	%o1,0
        +	bne	.Little
        +	nop
        +	retl
        +	nop
        +#endif
        +.type	OPENSSL_cleanse,#function
        +.size	OPENSSL_cleanse,.-OPENSSL_cleanse
        +
        +.section	".init",#alloc,#execinstr
        +	call	OPENSSL_cpuid_setup
        +	nop
        diff --git a/vendor/openssl/openssl/crypto/sparcv9cap.c b/vendor/openssl/openssl/crypto/sparcv9cap.c
        new file mode 100644
        index 000000000..43b3ac6f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/sparcv9cap.c
        @@ -0,0 +1,237 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <setjmp.h>
        +#include <signal.h>
        +#include <sys/time.h>
        +#include <openssl/bn.h>
        +
        +#define SPARCV9_TICK_PRIVILEGED	(1<<0)
        +#define SPARCV9_PREFER_FPU	(1<<1)
        +#define SPARCV9_VIS1		(1<<2)
        +#define SPARCV9_VIS2		(1<<3)	/* reserved */
        +#define SPARCV9_FMADD		(1<<4)	/* reserved for SPARC64 V */
        +
        +static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
        +
        +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
        +	{
        +	int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
        +	int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
        +
        +	if (num>=8 && !(num&1) &&
        +	    (OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
        +		(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
        +		return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
        +	else
        +		return bn_mul_mont_int(rp,ap,bp,np,n0,num);
        +	}
        +
        +unsigned long	_sparcv9_rdtick(void);
        +void		_sparcv9_vis1_probe(void);
        +unsigned long	_sparcv9_vis1_instrument(void);
        +void		_sparcv9_vis2_probe(void);
        +void		_sparcv9_fmadd_probe(void);
        +
        +unsigned long OPENSSL_rdtsc(void)
        +	{
        +	if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
        +#if defined(__sun) && defined(__SVR4)
        +		return gethrtime();
        +#else
        +		return 0;
        +#endif
        +	else
        +		return _sparcv9_rdtick();
        +	}
        +
        +#if 0 && defined(__sun) && defined(__SVR4)
        +/* This code path is disabled, because of incompatibility of
        + * libdevinfo.so.1 and libmalloc.so.1 (see below for details)
        + */
        +#include <malloc.h>
        +#include <dlfcn.h>
        +#include <libdevinfo.h>
        +#include <sys/systeminfo.h>
        +
        +typedef di_node_t (*di_init_t)(const char *,uint_t);
        +typedef void      (*di_fini_t)(di_node_t);
        +typedef char *    (*di_node_name_t)(di_node_t);
        +typedef int       (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t));
        +
        +#define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))
        +
        +static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
        +	{
        +	char *name = (*di_node_name)(node);
        +
        +	/* This is expected to catch all UltraSPARC flavors prior T1 */
        +	if (!strcmp (name,"SUNW,UltraSPARC") ||
        +	    !strncmp(name,"SUNW,UltraSPARC-I",17))  /* covers II,III,IV */
        +		{
        +		OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
        +
        +		/* %tick is privileged only on UltraSPARC-I/II, but not IIe */
        +		if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
        +			OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
        +
        +		return DI_WALK_TERMINATE;
        +		}
        +	/* This is expected to catch remaining UltraSPARCs, such as T1 */
        +	else if (!strncmp(name,"SUNW,UltraSPARC",15))
        +		{
        +		OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
        +
        +		return DI_WALK_TERMINATE;
        +		}
        +
        +	return DI_WALK_CONTINUE;
        +	}
        +
        +void OPENSSL_cpuid_setup(void)
        +	{
        +	void *h;
        +	char *e,si[256];
        +	static int trigger=0;
        +
        +	if (trigger) return;
        +	trigger=1;
        +
        +	if ((e=getenv("OPENSSL_sparcv9cap")))
        +		{
        +		OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
        +		return;
        +		}
        +
        +	if (sysinfo(SI_MACHINE,si,sizeof(si))>0)
        +		{
        +		if (strcmp(si,"sun4v"))
        +			/* FPU is preferred for all CPUs, but US-T1/2 */
        +			OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
        +		}
        +
        +	if (sysinfo(SI_ISALIST,si,sizeof(si))>0)
        +		{
        +		if (strstr(si,"+vis"))
        +			OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
        +		if (strstr(si,"+vis2"))
        +			{
        +			OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
        +			OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
        +			return;
        +			}
        +		}
        +#ifdef M_KEEP
        +	/*
        +	 * Solaris libdevinfo.so.1 is effectively incomatible with
        +	 * libmalloc.so.1. Specifically, if application is linked with
        +	 * -lmalloc, it crashes upon startup with SIGSEGV in
        +	 * free(3LIBMALLOC) called by di_fini. Prior call to
        +	 * mallopt(M_KEEP,0) somehow helps... But not always...
        +	 */
        +	if ((h = dlopen(NULL,RTLD_LAZY)))
        +		{
        +		union { void *p; int (*f)(int,int); } sym;
        +		if ((sym.p = dlsym(h,"mallopt"))) (*sym.f)(M_KEEP,0);
        +		dlclose(h);
        +		}
        +#endif
        +	if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do
        +		{
        +		di_init_t	di_init;
        +		di_fini_t	di_fini;
        +		di_walk_node_t	di_walk_node;
        +		di_node_name_t	di_node_name;
        +		di_node_t	root_node;
        +
        +		if (!DLLINK(h,di_init))		break;
        +		if (!DLLINK(h,di_fini))		break;
        +		if (!DLLINK(h,di_walk_node))	break;
        +		if (!DLLINK(h,di_node_name))	break;
        +
        +		if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL)
        +			{
        +			(*di_walk_node)(root_node,DI_WALK_SIBFIRST,
        +					di_node_name,walk_nodename);
        +			(*di_fini)(root_node);
        +			}
        +		} while(0);
        +
        +	if (h) dlclose(h);
        +	}
        +
        +#else
        +
        +static sigjmp_buf common_jmp;
        +static void common_handler(int sig) { siglongjmp(common_jmp,sig); }
        +
        +void OPENSSL_cpuid_setup(void)
        +	{
        +	char *e;
        +	struct sigaction	common_act,ill_oact,bus_oact;
        +	sigset_t		all_masked,oset;
        +	static int trigger=0;
        +
        +	if (trigger) return;
        +	trigger=1;
        + 
        +	if ((e=getenv("OPENSSL_sparcv9cap")))
        +		{
        +		OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
        +		return;
        +		}
        +
        +	/* Initial value, fits UltraSPARC-I&II... */
        +	OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU|SPARCV9_TICK_PRIVILEGED;
        +
        +	sigfillset(&all_masked);
        +	sigdelset(&all_masked,SIGILL);
        +	sigdelset(&all_masked,SIGTRAP);
        +#ifdef SIGEMT
        +	sigdelset(&all_masked,SIGEMT);
        +#endif
        +	sigdelset(&all_masked,SIGFPE);
        +	sigdelset(&all_masked,SIGBUS);
        +	sigdelset(&all_masked,SIGSEGV);
        +	sigprocmask(SIG_SETMASK,&all_masked,&oset);
        +
        +	memset(&common_act,0,sizeof(common_act));
        +	common_act.sa_handler = common_handler;
        +	common_act.sa_mask    = all_masked;
        +
        +	sigaction(SIGILL,&common_act,&ill_oact);
        +	sigaction(SIGBUS,&common_act,&bus_oact);/* T1 fails 16-bit ldda [on Linux] */
        +
        +	if (sigsetjmp(common_jmp,1) == 0)
        +		{
        +		_sparcv9_rdtick();
        +		OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
        +		}
        +
        +	if (sigsetjmp(common_jmp,1) == 0)
        +		{
        +		_sparcv9_vis1_probe();
        +		OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
        +		/* detect UltraSPARC-Tx, see sparccpud.S for details... */
        +		if (_sparcv9_vis1_instrument() >= 12)
        +			OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1|SPARCV9_PREFER_FPU);
        +		else
        +			{
        +			_sparcv9_vis2_probe();
        +			OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
        +			}
        +		}
        +
        +	if (sigsetjmp(common_jmp,1) == 0)
        +		{
        +		_sparcv9_fmadd_probe();
        +		OPENSSL_sparcv9cap_P |= SPARCV9_FMADD;
        +		}
        +
        +	sigaction(SIGBUS,&bus_oact,NULL);
        +	sigaction(SIGILL,&ill_oact,NULL);
        +
        +	sigprocmask(SIG_SETMASK,&oset,NULL);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/srp/Makefile b/vendor/openssl/openssl/crypto/srp/Makefile
        new file mode 100644
        index 000000000..41859d46f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/Makefile
        @@ -0,0 +1,98 @@
        +DIR=	srp
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +INSTALL_PREFIX=
        +OPENSSLDIR=     /usr/local/ssl
        +INSTALLTOP=/usr/local/ssl
        +MAKE=		make -f Makefile.ssl
        +MAKEDEPPROG=	makedepend
        +MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
        +MAKEFILE=	Makefile.ssl
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=srptest.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=srp_lib.c srp_vfy.c
        +LIBOBJ=srp_lib.o srp_vfy.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= srp.h
        +HEADER=	$(EXHEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	do  \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +
        +tags:
        +	ctags $(SRC)
        +
        +tests:
        +
        +srptest: top srptest.c $(LIB)
        +	$(CC) $(CFLAGS) -Wall -Werror -g -o srptest srptest.c $(LIB)
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +
        +depend:
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +srp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +srp_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +srp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +srp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +srp_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +srp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +srp_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +srp_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +srp_lib.o: ../../include/openssl/sha.h ../../include/openssl/srp.h
        +srp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +srp_lib.o: ../cryptlib.h srp_grps.h srp_lcl.h srp_lib.c
        +srp_vfy.o: ../../e_os.h ../../include/openssl/asn1.h
        +srp_vfy.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +srp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +srp_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +srp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +srp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +srp_vfy.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +srp_vfy.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
        +srp_vfy.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +srp_vfy.o: ../../include/openssl/srp.h ../../include/openssl/stack.h
        +srp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h
        +srp_vfy.o: ../cryptlib.h srp_lcl.h srp_vfy.c
        diff --git a/vendor/openssl/openssl/crypto/srp/srp.h b/vendor/openssl/openssl/crypto/srp/srp.h
        new file mode 100644
        index 000000000..7ec7825ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/srp.h
        @@ -0,0 +1,172 @@
        +/* crypto/srp/srp.h */
        +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
        + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
        + * for the EdelKey project and contributed to the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 __SRP_H__
        +#define __SRP_H__
        +
        +#ifndef OPENSSL_NO_SRP
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#include <openssl/safestack.h>
        +#include <openssl/bn.h>
        +#include <openssl/crypto.h>
        +
        +typedef struct SRP_gN_cache_st
        +	{
        +	char *b64_bn;
        +	BIGNUM *bn;
        +	} SRP_gN_cache;
        +
        +
        +DECLARE_STACK_OF(SRP_gN_cache)
        +
        +typedef struct SRP_user_pwd_st
        +	{
        +	char *id;
        +	BIGNUM *s;
        +	BIGNUM *v;
        +	const BIGNUM *g;
        +	const BIGNUM *N;
        +	char *info;
        +	} SRP_user_pwd;
        +
        +DECLARE_STACK_OF(SRP_user_pwd)
        +
        +typedef struct SRP_VBASE_st
        +	{
        +	STACK_OF(SRP_user_pwd) *users_pwd;
        +	STACK_OF(SRP_gN_cache) *gN_cache;
        +/* to simulate a user */
        +	char *seed_key;
        +	BIGNUM *default_g;
        +	BIGNUM *default_N;
        +	} SRP_VBASE;
        +
        +
        +/*Structure interne pour retenir les couples N et g*/
        +typedef struct SRP_gN_st
        +	{
        +	char *id;
        +	BIGNUM *g;
        +	BIGNUM *N;
        +	} SRP_gN;
        +
        +DECLARE_STACK_OF(SRP_gN)
        +
        +SRP_VBASE *SRP_VBASE_new(char *seed_key);
        +int SRP_VBASE_free(SRP_VBASE *vb);
        +int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file);
        +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
        +char *SRP_create_verifier(const char *user, const char *pass, char **salt,
        +			  char **verifier, const char *N, const char *g);
        +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
        +
        +
        +#define SRP_NO_ERROR 0
        +#define SRP_ERR_VBASE_INCOMPLETE_FILE 1
        +#define SRP_ERR_VBASE_BN_LIB 2
        +#define SRP_ERR_OPEN_FILE 3
        +#define SRP_ERR_MEMORY 4
        +
        +#define DB_srptype	0
        +#define DB_srpverifier	1
        +#define DB_srpsalt 	2
        +#define DB_srpid	3              
        +#define DB_srpgN	4       
        +#define DB_srpinfo	5 
        +#undef  DB_NUMBER      
        +#define DB_NUMBER       6
        +
        +#define DB_SRP_INDEX	'I'
        +#define DB_SRP_VALID	'V'
        +#define DB_SRP_REVOKED	'R'
        +#define DB_SRP_MODIF	'v'
        +
        +
        +/* see srp.c */
        +char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N); 
        +SRP_gN *SRP_get_default_gN(const char * id) ;
        +
        +/* server side .... */
        +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N);
        +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v);
        +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N);
        +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) ;
        +
        +
        +
        +/* client side .... */
        +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass);
        +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g);
        +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u);
        +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N);
        +
        +#define SRP_MINIMAL_N 1024
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/srp/srp_grps.h b/vendor/openssl/openssl/crypto/srp/srp_grps.h
        new file mode 100644
        index 000000000..d77c9fff4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/srp_grps.h
        @@ -0,0 +1,517 @@
        +/* start of generated data */
        +
        +static BN_ULONG bn_group_1024_value[] = {
        +	bn_pack4(9FC6,1D2F,C0EB,06E3),
        +	bn_pack4(FD51,38FE,8376,435B),
        +	bn_pack4(2FD4,CBF4,976E,AA9A),
        +	bn_pack4(68ED,BC3C,0572,6CC0),
        +	bn_pack4(C529,F566,660E,57EC),
        +	bn_pack4(8255,9B29,7BCF,1885),
        +	bn_pack4(CE8E,F4AD,69B1,5D49),
        +	bn_pack4(5DC7,D7B4,6154,D6B6),
        +	bn_pack4(8E49,5C1D,6089,DAD1),
        +	bn_pack4(E0D5,D8E2,50B9,8BE4),
        +	bn_pack4(383B,4813,D692,C6E0),
        +	bn_pack4(D674,DF74,96EA,81D3),
        +	bn_pack4(9EA2,314C,9C25,6576),
        +	bn_pack4(6072,6187,75FF,3C0B),
        +	bn_pack4(9C33,F80A,FA8F,C5E8),
        +	bn_pack4(EEAF,0AB9,ADB3,8DD6)
        +};
        +static BIGNUM bn_group_1024 = {
        +	bn_group_1024_value,
        +	(sizeof bn_group_1024_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_1024_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_group_1536_value[] = {
        +	bn_pack4(CF76,E3FE,D135,F9BB),
        +	bn_pack4(1518,0F93,499A,234D),
        +	bn_pack4(8CE7,A28C,2442,C6F3),
        +	bn_pack4(5A02,1FFF,5E91,479E),
        +	bn_pack4(7F8A,2FE9,B8B5,292E),
        +	bn_pack4(837C,264A,E3A9,BEB8),
        +	bn_pack4(E442,734A,F7CC,B7AE),
        +	bn_pack4(6577,2E43,7D6C,7F8C),
        +	bn_pack4(DB2F,D53D,24B7,C486),
        +	bn_pack4(6EDF,0195,3934,9627),
        +	bn_pack4(158B,FD3E,2B9C,8CF5),
        +	bn_pack4(764E,3F4B,53DD,9DA1),
        +	bn_pack4(4754,8381,DBC5,B1FC),
        +	bn_pack4(9B60,9E0B,E3BA,B63D),
        +	bn_pack4(8134,B1C8,B979,8914),
        +	bn_pack4(DF02,8A7C,EC67,F0D0),
        +	bn_pack4(80B6,55BB,9A22,E8DC),
        +	bn_pack4(1558,903B,A0D0,F843),
        +	bn_pack4(51C6,A94B,E460,7A29),
        +	bn_pack4(5F4F,5F55,6E27,CBDE),
        +	bn_pack4(BEEE,A961,4B19,CC4D),
        +	bn_pack4(DBA5,1DF4,99AC,4C80),
        +	bn_pack4(B1F1,2A86,17A4,7BBB),
        +	bn_pack4(9DEF,3CAF,B939,277A)
        +};
        +static BIGNUM bn_group_1536 = {
        +	bn_group_1536_value,
        +	(sizeof bn_group_1536_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_1536_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_group_2048_value[] = {
        +	bn_pack4(0FA7,111F,9E4A,FF73),
        +	bn_pack4(9B65,E372,FCD6,8EF2),
        +	bn_pack4(35DE,236D,525F,5475),
        +	bn_pack4(94B5,C803,D89F,7AE4),
        +	bn_pack4(71AE,35F8,E9DB,FBB6),
        +	bn_pack4(2A56,98F3,A8D0,C382),
        +	bn_pack4(9CCC,041C,7BC3,08D8),
        +	bn_pack4(AF87,4E73,03CE,5329),
        +	bn_pack4(6160,2790,04E5,7AE6),
        +	bn_pack4(032C,FBDB,F52F,B378),
        +	bn_pack4(5EA7,7A27,75D2,ECFA),
        +	bn_pack4(5445,23B5,24B0,D57D),
        +	bn_pack4(5B9D,32E6,88F8,7748),
        +	bn_pack4(F1D2,B907,8717,461A),
        +	bn_pack4(76BD,207A,436C,6481),
        +	bn_pack4(CA97,B43A,23FB,8016),
        +	bn_pack4(1D28,1E44,6B14,773B),
        +	bn_pack4(7359,D041,D5C3,3EA7),
        +	bn_pack4(A80D,740A,DBF4,FF74),
        +	bn_pack4(55F9,7993,EC97,5EEA),
        +	bn_pack4(2918,A996,2F0B,93B8),
        +	bn_pack4(661A,05FB,D5FA,AAE8),
        +	bn_pack4(CF60,9517,9A16,3AB3),
        +	bn_pack4(E808,3969,EDB7,67B0),
        +	bn_pack4(CD7F,48A9,DA04,FD50),
        +	bn_pack4(D523,12AB,4B03,310D),
        +	bn_pack4(8193,E075,7767,A13D),
        +	bn_pack4(A373,29CB,B4A0,99ED),
        +	bn_pack4(FC31,9294,3DB5,6050),
        +	bn_pack4(AF72,B665,1987,EE07),
        +	bn_pack4(F166,DE5E,1389,582F),
        +	bn_pack4(AC6B,DB41,324A,9A9B)
        +};
        +static BIGNUM bn_group_2048 = {
        +	bn_group_2048_value,
        +	(sizeof bn_group_2048_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_2048_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_group_3072_value[] = {
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF),
        +	bn_pack4(4B82,D120,A93A,D2CA),
        +	bn_pack4(43DB,5BFC,E0FD,108E),
        +	bn_pack4(08E2,4FA0,74E5,AB31),
        +	bn_pack4(7709,88C0,BAD9,46E2),
        +	bn_pack4(BBE1,1757,7A61,5D6C),
        +	bn_pack4(521F,2B18,177B,200C),
        +	bn_pack4(D876,0273,3EC8,6A64),
        +	bn_pack4(F12F,FA06,D98A,0864),
        +	bn_pack4(CEE3,D226,1AD2,EE6B),
        +	bn_pack4(1E8C,94E0,4A25,619D),
        +	bn_pack4(ABF5,AE8C,DB09,33D7),
        +	bn_pack4(B397,0F85,A6E1,E4C7),
        +	bn_pack4(8AEA,7157,5D06,0C7D),
        +	bn_pack4(ECFB,8504,58DB,EF0A),
        +	bn_pack4(A855,21AB,DF1C,BA64),
        +	bn_pack4(AD33,170D,0450,7A33),
        +	bn_pack4(1572,8E5A,8AAA,C42D),
        +	bn_pack4(15D2,2618,98FA,0510),
        +	bn_pack4(3995,497C,EA95,6AE5),
        +	bn_pack4(DE2B,CBF6,9558,1718),
        +	bn_pack4(B5C5,5DF0,6F4C,52C9),
        +	bn_pack4(9B27,83A2,EC07,A28F),
        +	bn_pack4(E39E,772C,180E,8603),
        +	bn_pack4(3290,5E46,2E36,CE3B),
        +	bn_pack4(F174,6C08,CA18,217C),
        +	bn_pack4(670C,354E,4ABC,9804),
        +	bn_pack4(9ED5,2907,7096,966D),
        +	bn_pack4(1C62,F356,2085,52BB),
        +	bn_pack4(8365,5D23,DCA3,AD96),
        +	bn_pack4(6916,3FA8,FD24,CF5F),
        +	bn_pack4(98DA,4836,1C55,D39A),
        +	bn_pack4(C200,7CB8,A163,BF05),
        +	bn_pack4(4928,6651,ECE4,5B3D),
        +	bn_pack4(AE9F,2411,7C4B,1FE6),
        +	bn_pack4(EE38,6BFB,5A89,9FA5),
        +	bn_pack4(0BFF,5CB6,F406,B7ED),
        +	bn_pack4(F44C,42E9,A637,ED6B),
        +	bn_pack4(E485,B576,625E,7EC6),
        +	bn_pack4(4FE1,356D,6D51,C245),
        +	bn_pack4(302B,0A6D,F25F,1437),
        +	bn_pack4(EF95,19B3,CD3A,431B),
        +	bn_pack4(514A,0879,8E34,04DD),
        +	bn_pack4(020B,BEA6,3B13,9B22),
        +	bn_pack4(2902,4E08,8A67,CC74),
        +	bn_pack4(C4C6,628B,80DC,1CD1),
        +	bn_pack4(C90F,DAA2,2168,C234),
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF)
        +};
        +static BIGNUM bn_group_3072 = {
        +	bn_group_3072_value,
        +	(sizeof bn_group_3072_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_3072_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_group_4096_value[] = {
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF),
        +	bn_pack4(4DF4,35C9,3406,3199),
        +	bn_pack4(86FF,B7DC,90A6,C08F),
        +	bn_pack4(93B4,EA98,8D8F,DDC1),
        +	bn_pack4(D006,9127,D5B0,5AA9),
        +	bn_pack4(B81B,DD76,2170,481C),
        +	bn_pack4(1F61,2970,CEE2,D7AF),
        +	bn_pack4(233B,A186,515B,E7ED),
        +	bn_pack4(99B2,964F,A090,C3A2),
        +	bn_pack4(287C,5947,4E6B,C05D),
        +	bn_pack4(2E8E,FC14,1FBE,CAA6),
        +	bn_pack4(DBBB,C2DB,04DE,8EF9),
        +	bn_pack4(2583,E9CA,2AD4,4CE8),
        +	bn_pack4(1A94,6834,B615,0BDA),
        +	bn_pack4(99C3,2718,6AF4,E23C),
        +	bn_pack4(8871,9A10,BDBA,5B26),
        +	bn_pack4(1A72,3C12,A787,E6D7),
        +	bn_pack4(4B82,D120,A921,0801),
        +	bn_pack4(43DB,5BFC,E0FD,108E),
        +	bn_pack4(08E2,4FA0,74E5,AB31),
        +	bn_pack4(7709,88C0,BAD9,46E2),
        +	bn_pack4(BBE1,1757,7A61,5D6C),
        +	bn_pack4(521F,2B18,177B,200C),
        +	bn_pack4(D876,0273,3EC8,6A64),
        +	bn_pack4(F12F,FA06,D98A,0864),
        +	bn_pack4(CEE3,D226,1AD2,EE6B),
        +	bn_pack4(1E8C,94E0,4A25,619D),
        +	bn_pack4(ABF5,AE8C,DB09,33D7),
        +	bn_pack4(B397,0F85,A6E1,E4C7),
        +	bn_pack4(8AEA,7157,5D06,0C7D),
        +	bn_pack4(ECFB,8504,58DB,EF0A),
        +	bn_pack4(A855,21AB,DF1C,BA64),
        +	bn_pack4(AD33,170D,0450,7A33),
        +	bn_pack4(1572,8E5A,8AAA,C42D),
        +	bn_pack4(15D2,2618,98FA,0510),
        +	bn_pack4(3995,497C,EA95,6AE5),
        +	bn_pack4(DE2B,CBF6,9558,1718),
        +	bn_pack4(B5C5,5DF0,6F4C,52C9),
        +	bn_pack4(9B27,83A2,EC07,A28F),
        +	bn_pack4(E39E,772C,180E,8603),
        +	bn_pack4(3290,5E46,2E36,CE3B),
        +	bn_pack4(F174,6C08,CA18,217C),
        +	bn_pack4(670C,354E,4ABC,9804),
        +	bn_pack4(9ED5,2907,7096,966D),
        +	bn_pack4(1C62,F356,2085,52BB),
        +	bn_pack4(8365,5D23,DCA3,AD96),
        +	bn_pack4(6916,3FA8,FD24,CF5F),
        +	bn_pack4(98DA,4836,1C55,D39A),
        +	bn_pack4(C200,7CB8,A163,BF05),
        +	bn_pack4(4928,6651,ECE4,5B3D),
        +	bn_pack4(AE9F,2411,7C4B,1FE6),
        +	bn_pack4(EE38,6BFB,5A89,9FA5),
        +	bn_pack4(0BFF,5CB6,F406,B7ED),
        +	bn_pack4(F44C,42E9,A637,ED6B),
        +	bn_pack4(E485,B576,625E,7EC6),
        +	bn_pack4(4FE1,356D,6D51,C245),
        +	bn_pack4(302B,0A6D,F25F,1437),
        +	bn_pack4(EF95,19B3,CD3A,431B),
        +	bn_pack4(514A,0879,8E34,04DD),
        +	bn_pack4(020B,BEA6,3B13,9B22),
        +	bn_pack4(2902,4E08,8A67,CC74),
        +	bn_pack4(C4C6,628B,80DC,1CD1),
        +	bn_pack4(C90F,DAA2,2168,C234),
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF)
        +};
        +static BIGNUM bn_group_4096 = {
        +	bn_group_4096_value,
        +	(sizeof bn_group_4096_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_4096_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_group_6144_value[] = {
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF),
        +	bn_pack4(E694,F91E,6DCC,4024),
        +	bn_pack4(12BF,2D5B,0B74,74D6),
        +	bn_pack4(043E,8F66,3F48,60EE),
        +	bn_pack4(387F,E8D7,6E3C,0468),
        +	bn_pack4(DA56,C9EC,2EF2,9632),
        +	bn_pack4(EB19,CCB1,A313,D55C),
        +	bn_pack4(F550,AA3D,8A1F,BFF0),
        +	bn_pack4(06A1,D58B,B7C5,DA76),
        +	bn_pack4(A797,15EE,F29B,E328),
        +	bn_pack4(14CC,5ED2,0F80,37E0),
        +	bn_pack4(CC8F,6D7E,BF48,E1D8),
        +	bn_pack4(4BD4,07B2,2B41,54AA),
        +	bn_pack4(0F1D,45B7,FF58,5AC5),
        +	bn_pack4(23A9,7A7E,36CC,88BE),
        +	bn_pack4(59E7,C97F,BEC7,E8F3),
        +	bn_pack4(B5A8,4031,900B,1C9E),
        +	bn_pack4(D55E,702F,4698,0C82),
        +	bn_pack4(F482,D7CE,6E74,FEF6),
        +	bn_pack4(F032,EA15,D172,1D03),
        +	bn_pack4(5983,CA01,C64B,92EC),
        +	bn_pack4(6FB8,F401,378C,D2BF),
        +	bn_pack4(3320,5151,2BD7,AF42),
        +	bn_pack4(DB7F,1447,E6CC,254B),
        +	bn_pack4(44CE,6CBA,CED4,BB1B),
        +	bn_pack4(DA3E,DBEB,CF9B,14ED),
        +	bn_pack4(1797,27B0,865A,8918),
        +	bn_pack4(B06A,53ED,9027,D831),
        +	bn_pack4(E5DB,382F,4130,01AE),
        +	bn_pack4(F8FF,9406,AD9E,530E),
        +	bn_pack4(C975,1E76,3DBA,37BD),
        +	bn_pack4(C1D4,DCB2,6026,46DE),
        +	bn_pack4(36C3,FAB4,D27C,7026),
        +	bn_pack4(4DF4,35C9,3402,8492),
        +	bn_pack4(86FF,B7DC,90A6,C08F),
        +	bn_pack4(93B4,EA98,8D8F,DDC1),
        +	bn_pack4(D006,9127,D5B0,5AA9),
        +	bn_pack4(B81B,DD76,2170,481C),
        +	bn_pack4(1F61,2970,CEE2,D7AF),
        +	bn_pack4(233B,A186,515B,E7ED),
        +	bn_pack4(99B2,964F,A090,C3A2),
        +	bn_pack4(287C,5947,4E6B,C05D),
        +	bn_pack4(2E8E,FC14,1FBE,CAA6),
        +	bn_pack4(DBBB,C2DB,04DE,8EF9),
        +	bn_pack4(2583,E9CA,2AD4,4CE8),
        +	bn_pack4(1A94,6834,B615,0BDA),
        +	bn_pack4(99C3,2718,6AF4,E23C),
        +	bn_pack4(8871,9A10,BDBA,5B26),
        +	bn_pack4(1A72,3C12,A787,E6D7),
        +	bn_pack4(4B82,D120,A921,0801),
        +	bn_pack4(43DB,5BFC,E0FD,108E),
        +	bn_pack4(08E2,4FA0,74E5,AB31),
        +	bn_pack4(7709,88C0,BAD9,46E2),
        +	bn_pack4(BBE1,1757,7A61,5D6C),
        +	bn_pack4(521F,2B18,177B,200C),
        +	bn_pack4(D876,0273,3EC8,6A64),
        +	bn_pack4(F12F,FA06,D98A,0864),
        +	bn_pack4(CEE3,D226,1AD2,EE6B),
        +	bn_pack4(1E8C,94E0,4A25,619D),
        +	bn_pack4(ABF5,AE8C,DB09,33D7),
        +	bn_pack4(B397,0F85,A6E1,E4C7),
        +	bn_pack4(8AEA,7157,5D06,0C7D),
        +	bn_pack4(ECFB,8504,58DB,EF0A),
        +	bn_pack4(A855,21AB,DF1C,BA64),
        +	bn_pack4(AD33,170D,0450,7A33),
        +	bn_pack4(1572,8E5A,8AAA,C42D),
        +	bn_pack4(15D2,2618,98FA,0510),
        +	bn_pack4(3995,497C,EA95,6AE5),
        +	bn_pack4(DE2B,CBF6,9558,1718),
        +	bn_pack4(B5C5,5DF0,6F4C,52C9),
        +	bn_pack4(9B27,83A2,EC07,A28F),
        +	bn_pack4(E39E,772C,180E,8603),
        +	bn_pack4(3290,5E46,2E36,CE3B),
        +	bn_pack4(F174,6C08,CA18,217C),
        +	bn_pack4(670C,354E,4ABC,9804),
        +	bn_pack4(9ED5,2907,7096,966D),
        +	bn_pack4(1C62,F356,2085,52BB),
        +	bn_pack4(8365,5D23,DCA3,AD96),
        +	bn_pack4(6916,3FA8,FD24,CF5F),
        +	bn_pack4(98DA,4836,1C55,D39A),
        +	bn_pack4(C200,7CB8,A163,BF05),
        +	bn_pack4(4928,6651,ECE4,5B3D),
        +	bn_pack4(AE9F,2411,7C4B,1FE6),
        +	bn_pack4(EE38,6BFB,5A89,9FA5),
        +	bn_pack4(0BFF,5CB6,F406,B7ED),
        +	bn_pack4(F44C,42E9,A637,ED6B),
        +	bn_pack4(E485,B576,625E,7EC6),
        +	bn_pack4(4FE1,356D,6D51,C245),
        +	bn_pack4(302B,0A6D,F25F,1437),
        +	bn_pack4(EF95,19B3,CD3A,431B),
        +	bn_pack4(514A,0879,8E34,04DD),
        +	bn_pack4(020B,BEA6,3B13,9B22),
        +	bn_pack4(2902,4E08,8A67,CC74),
        +	bn_pack4(C4C6,628B,80DC,1CD1),
        +	bn_pack4(C90F,DAA2,2168,C234),
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF)
        +};
        +static BIGNUM bn_group_6144 = {
        +	bn_group_6144_value,
        +	(sizeof bn_group_6144_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_6144_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_group_8192_value[] = {
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF),
        +	bn_pack4(60C9,80DD,98ED,D3DF),
        +	bn_pack4(C81F,56E8,80B9,6E71),
        +	bn_pack4(9E30,50E2,7656,94DF),
        +	bn_pack4(9558,E447,5677,E9AA),
        +	bn_pack4(C919,0DA6,FC02,6E47),
        +	bn_pack4(889A,002E,D5EE,382B),
        +	bn_pack4(4009,438B,481C,6CD7),
        +	bn_pack4(3590,46F4,EB87,9F92),
        +	bn_pack4(FAF3,6BC3,1ECF,A268),
        +	bn_pack4(B1D5,10BD,7EE7,4D73),
        +	bn_pack4(F9AB,4819,5DED,7EA1),
        +	bn_pack4(64F3,1CC5,0846,851D),
        +	bn_pack4(4597,E899,A025,5DC1),
        +	bn_pack4(DF31,0EE0,74AB,6A36),
        +	bn_pack4(6D2A,13F8,3F44,F82D),
        +	bn_pack4(062B,3CF5,B3A2,78A6),
        +	bn_pack4(7968,3303,ED5B,DD3A),
        +	bn_pack4(FA9D,4B7F,A2C0,87E8),
        +	bn_pack4(4BCB,C886,2F83,85DD),
        +	bn_pack4(3473,FC64,6CEA,306B),
        +	bn_pack4(13EB,57A8,1A23,F0C7),
        +	bn_pack4(2222,2E04,A403,7C07),
        +	bn_pack4(E3FD,B8BE,FC84,8AD9),
        +	bn_pack4(238F,16CB,E39D,652D),
        +	bn_pack4(3423,B474,2BF1,C978),
        +	bn_pack4(3AAB,639C,5AE4,F568),
        +	bn_pack4(2576,F693,6BA4,2466),
        +	bn_pack4(741F,A7BF,8AFC,47ED),
        +	bn_pack4(3BC8,32B6,8D9D,D300),
        +	bn_pack4(D8BE,C4D0,73B9,31BA),
        +	bn_pack4(3877,7CB6,A932,DF8C),
        +	bn_pack4(74A3,926F,12FE,E5E4),
        +	bn_pack4(E694,F91E,6DBE,1159),
        +	bn_pack4(12BF,2D5B,0B74,74D6),
        +	bn_pack4(043E,8F66,3F48,60EE),
        +	bn_pack4(387F,E8D7,6E3C,0468),
        +	bn_pack4(DA56,C9EC,2EF2,9632),
        +	bn_pack4(EB19,CCB1,A313,D55C),
        +	bn_pack4(F550,AA3D,8A1F,BFF0),
        +	bn_pack4(06A1,D58B,B7C5,DA76),
        +	bn_pack4(A797,15EE,F29B,E328),
        +	bn_pack4(14CC,5ED2,0F80,37E0),
        +	bn_pack4(CC8F,6D7E,BF48,E1D8),
        +	bn_pack4(4BD4,07B2,2B41,54AA),
        +	bn_pack4(0F1D,45B7,FF58,5AC5),
        +	bn_pack4(23A9,7A7E,36CC,88BE),
        +	bn_pack4(59E7,C97F,BEC7,E8F3),
        +	bn_pack4(B5A8,4031,900B,1C9E),
        +	bn_pack4(D55E,702F,4698,0C82),
        +	bn_pack4(F482,D7CE,6E74,FEF6),
        +	bn_pack4(F032,EA15,D172,1D03),
        +	bn_pack4(5983,CA01,C64B,92EC),
        +	bn_pack4(6FB8,F401,378C,D2BF),
        +	bn_pack4(3320,5151,2BD7,AF42),
        +	bn_pack4(DB7F,1447,E6CC,254B),
        +	bn_pack4(44CE,6CBA,CED4,BB1B),
        +	bn_pack4(DA3E,DBEB,CF9B,14ED),
        +	bn_pack4(1797,27B0,865A,8918),
        +	bn_pack4(B06A,53ED,9027,D831),
        +	bn_pack4(E5DB,382F,4130,01AE),
        +	bn_pack4(F8FF,9406,AD9E,530E),
        +	bn_pack4(C975,1E76,3DBA,37BD),
        +	bn_pack4(C1D4,DCB2,6026,46DE),
        +	bn_pack4(36C3,FAB4,D27C,7026),
        +	bn_pack4(4DF4,35C9,3402,8492),
        +	bn_pack4(86FF,B7DC,90A6,C08F),
        +	bn_pack4(93B4,EA98,8D8F,DDC1),
        +	bn_pack4(D006,9127,D5B0,5AA9),
        +	bn_pack4(B81B,DD76,2170,481C),
        +	bn_pack4(1F61,2970,CEE2,D7AF),
        +	bn_pack4(233B,A186,515B,E7ED),
        +	bn_pack4(99B2,964F,A090,C3A2),
        +	bn_pack4(287C,5947,4E6B,C05D),
        +	bn_pack4(2E8E,FC14,1FBE,CAA6),
        +	bn_pack4(DBBB,C2DB,04DE,8EF9),
        +	bn_pack4(2583,E9CA,2AD4,4CE8),
        +	bn_pack4(1A94,6834,B615,0BDA),
        +	bn_pack4(99C3,2718,6AF4,E23C),
        +	bn_pack4(8871,9A10,BDBA,5B26),
        +	bn_pack4(1A72,3C12,A787,E6D7),
        +	bn_pack4(4B82,D120,A921,0801),
        +	bn_pack4(43DB,5BFC,E0FD,108E),
        +	bn_pack4(08E2,4FA0,74E5,AB31),
        +	bn_pack4(7709,88C0,BAD9,46E2),
        +	bn_pack4(BBE1,1757,7A61,5D6C),
        +	bn_pack4(521F,2B18,177B,200C),
        +	bn_pack4(D876,0273,3EC8,6A64),
        +	bn_pack4(F12F,FA06,D98A,0864),
        +	bn_pack4(CEE3,D226,1AD2,EE6B),
        +	bn_pack4(1E8C,94E0,4A25,619D),
        +	bn_pack4(ABF5,AE8C,DB09,33D7),
        +	bn_pack4(B397,0F85,A6E1,E4C7),
        +	bn_pack4(8AEA,7157,5D06,0C7D),
        +	bn_pack4(ECFB,8504,58DB,EF0A),
        +	bn_pack4(A855,21AB,DF1C,BA64),
        +	bn_pack4(AD33,170D,0450,7A33),
        +	bn_pack4(1572,8E5A,8AAA,C42D),
        +	bn_pack4(15D2,2618,98FA,0510),
        +	bn_pack4(3995,497C,EA95,6AE5),
        +	bn_pack4(DE2B,CBF6,9558,1718),
        +	bn_pack4(B5C5,5DF0,6F4C,52C9),
        +	bn_pack4(9B27,83A2,EC07,A28F),
        +	bn_pack4(E39E,772C,180E,8603),
        +	bn_pack4(3290,5E46,2E36,CE3B),
        +	bn_pack4(F174,6C08,CA18,217C),
        +	bn_pack4(670C,354E,4ABC,9804),
        +	bn_pack4(9ED5,2907,7096,966D),
        +	bn_pack4(1C62,F356,2085,52BB),
        +	bn_pack4(8365,5D23,DCA3,AD96),
        +	bn_pack4(6916,3FA8,FD24,CF5F),
        +	bn_pack4(98DA,4836,1C55,D39A),
        +	bn_pack4(C200,7CB8,A163,BF05),
        +	bn_pack4(4928,6651,ECE4,5B3D),
        +	bn_pack4(AE9F,2411,7C4B,1FE6),
        +	bn_pack4(EE38,6BFB,5A89,9FA5),
        +	bn_pack4(0BFF,5CB6,F406,B7ED),
        +	bn_pack4(F44C,42E9,A637,ED6B),
        +	bn_pack4(E485,B576,625E,7EC6),
        +	bn_pack4(4FE1,356D,6D51,C245),
        +	bn_pack4(302B,0A6D,F25F,1437),
        +	bn_pack4(EF95,19B3,CD3A,431B),
        +	bn_pack4(514A,0879,8E34,04DD),
        +	bn_pack4(020B,BEA6,3B13,9B22),
        +	bn_pack4(2902,4E08,8A67,CC74),
        +	bn_pack4(C4C6,628B,80DC,1CD1),
        +	bn_pack4(C90F,DAA2,2168,C234),
        +	bn_pack4(FFFF,FFFF,FFFF,FFFF)
        +};
        +static BIGNUM bn_group_8192 = {
        +	bn_group_8192_value,
        +	(sizeof bn_group_8192_value)/sizeof(BN_ULONG),
        +	(sizeof bn_group_8192_value)/sizeof(BN_ULONG),
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static BN_ULONG bn_generator_19_value[] = {19} ;
        +static BIGNUM bn_generator_19 = {
        +	bn_generator_19_value,
        +	1,
        +	1,
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +static BN_ULONG bn_generator_5_value[] = {5} ;
        +static BIGNUM bn_generator_5 = {
        +	bn_generator_5_value,
        +	1,
        +	1,
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +static BN_ULONG bn_generator_2_value[] = {2} ;
        +static BIGNUM bn_generator_2 = {
        +	bn_generator_2_value,
        +	1,
        +	1,
        +	0,
        +	BN_FLG_STATIC_DATA
        +};
        +
        +static SRP_gN knowngN[] = {
        +	{"8192",&bn_generator_19 , &bn_group_8192},
        +	{"6144",&bn_generator_5 , &bn_group_6144},
        +	{"4096",&bn_generator_5 , &bn_group_4096},
        +	{"3072",&bn_generator_5 , &bn_group_3072},
        +	{"2048",&bn_generator_2 , &bn_group_2048},
        +	{"1536",&bn_generator_2 , &bn_group_1536},
        +	{"1024",&bn_generator_2 , &bn_group_1024},
        +};
        +#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
        +
        +/* end of generated data */
        diff --git a/vendor/openssl/openssl/crypto/srp/srp_lcl.h b/vendor/openssl/openssl/crypto/srp/srp_lcl.h
        new file mode 100644
        index 000000000..42bda3f14
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/srp_lcl.h
        @@ -0,0 +1,83 @@
        +/* crypto/srp/srp_lcl.h */
        +/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)  
        + * for the EdelKey project and contributed to the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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_SRP_LCL_H
        +#define HEADER_SRP_LCL_H
        +
        +#include <openssl/srp.h>
        +#include <openssl/sha.h>
        +
        +#if 0
        +#define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
        +   fprintf(stderr,"\n");}
        +#else
        +#define   srp_bn_print(a)
        +#endif
        +
        +
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/srp/srp_lib.c b/vendor/openssl/openssl/crypto/srp/srp_lib.c
        new file mode 100644
        index 000000000..92cea98dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/srp_lib.c
        @@ -0,0 +1,357 @@
        +/* crypto/srp/srp_lib.c */
        +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
        + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
        + * for the EdelKey project and contributed to the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 OPENSSL_NO_SRP
        +#include "cryptlib.h"
        +#include "srp_lcl.h"
        +#include <openssl/srp.h>
        +#include <openssl/evp.h>
        +
        +#if (BN_BYTES == 8)
        +#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul
        +#endif
        +#if (BN_BYTES == 4)
        +#define bn_pack4(a1,a2,a3,a4)  0x##a3##a4##ul, 0x##a1##a2##ul
        +#endif
        +#if (BN_BYTES == 2)
        +#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u
        +#endif
        +
        +
        +#include "srp_grps.h"
        +
        +static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
        +	{
        +	/* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
        +
        +	unsigned char digest[SHA_DIGEST_LENGTH];
        +	unsigned char *tmp;
        +	EVP_MD_CTX ctxt;
        +	int longg ;
        +	int longN = BN_num_bytes(N);
        +
        +	if ((tmp = OPENSSL_malloc(longN)) == NULL)
        +		return NULL;
        +	BN_bn2bin(N,tmp) ;
        +
        +	EVP_MD_CTX_init(&ctxt);
        +	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
        +	EVP_DigestUpdate(&ctxt, tmp, longN);
        +
        +	memset(tmp, 0, longN);
        +	longg = BN_bn2bin(g,tmp) ;
        +        /* use the zeros behind to pad on left */
        +	EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg);
        +	EVP_DigestUpdate(&ctxt, tmp, longg);
        +	OPENSSL_free(tmp);
        +
        +	EVP_DigestFinal_ex(&ctxt, digest, NULL);
        +	EVP_MD_CTX_cleanup(&ctxt);
        +	return BN_bin2bn(digest, sizeof(digest), NULL);	
        +	}
        +
        +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
        +	{
        +	/* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
        +
        +	BIGNUM *u;	
        +	unsigned char cu[SHA_DIGEST_LENGTH];
        +	unsigned char *cAB;
        +	EVP_MD_CTX ctxt;
        +	int longN;  
        +	if ((A == NULL) ||(B == NULL) || (N == NULL))
        +		return NULL;
        +
        +	longN= BN_num_bytes(N);
        +
        +	if ((cAB = OPENSSL_malloc(2*longN)) == NULL) 
        +		return NULL;
        +
        +	memset(cAB, 0, longN);
        +
        +	EVP_MD_CTX_init(&ctxt);
        +	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
        +	EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN);
        +	EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN);
        +	OPENSSL_free(cAB);
        +	EVP_DigestFinal_ex(&ctxt, cu, NULL);
        +	EVP_MD_CTX_cleanup(&ctxt);
        +
        +	if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
        +		return NULL;
        +	if (!BN_is_zero(u))
        +		return u;
        +	BN_free(u);
        +	return NULL;
        +}
        +
        +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N)
        +	{
        +	BIGNUM *tmp = NULL, *S = NULL;
        +	BN_CTX *bn_ctx; 
        +	
        +	if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
        +		return NULL; 
        +
        +	if ((bn_ctx = BN_CTX_new()) == NULL ||
        +		(tmp = BN_new()) == NULL ||
        +		(S = BN_new()) == NULL )
        +		goto err;
        +
        +	/* S = (A*v**u) ** b */ 
        +
        +	if (!BN_mod_exp(tmp,v,u,N,bn_ctx))
        +		goto err;
        +	if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx))
        +		goto err;
        +	if (!BN_mod_exp(S,tmp,b,N,bn_ctx))
        +		goto err;
        +err:
        +	BN_CTX_free(bn_ctx);
        +	BN_clear_free(tmp);
        +	return S;
        +	}
        +
        +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
        +	{
        +	BIGNUM  *kv = NULL, *gb = NULL;
        +	BIGNUM *B = NULL, *k = NULL;
        +	BN_CTX *bn_ctx;
        +
        +	if (b == NULL || N == NULL || g == NULL || v == NULL ||
        +		(bn_ctx = BN_CTX_new()) == NULL)
        +		return NULL; 
        +
        +	if ( (kv = BN_new()) == NULL ||
        +		(gb = BN_new()) == NULL ||
        +		(B = BN_new())== NULL)
        +		goto err;
        +
        +	/* B = g**b + k*v */
        +
        +	if (!BN_mod_exp(gb,g,b,N,bn_ctx) ||
        +	   !(k = srp_Calc_k(N,g)) ||
        +	   !BN_mod_mul(kv,v,k,N,bn_ctx) || 
        +	   !BN_mod_add(B,gb,kv,N,bn_ctx))
        +		{
        +		BN_free(B);
        +		B = NULL;
        +		}
        +err:
        +	BN_CTX_free(bn_ctx);
        +	BN_clear_free(kv);
        +	BN_clear_free(gb);
        +	BN_free(k); 
        +	return B;
        +	}
        +
        +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
        +	{
        +	unsigned char dig[SHA_DIGEST_LENGTH];
        +	EVP_MD_CTX ctxt;
        +	unsigned char *cs;
        +
        +	if ((s == NULL) ||
        +		(user == NULL) ||
        +		(pass == NULL))
        +		return NULL;
        +
        +	if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
        +		return NULL;
        +
        +	EVP_MD_CTX_init(&ctxt);
        +	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
        +	EVP_DigestUpdate(&ctxt, user, strlen(user));
        +	EVP_DigestUpdate(&ctxt, ":", 1);
        +	EVP_DigestUpdate(&ctxt, pass, strlen(pass));
        +	EVP_DigestFinal_ex(&ctxt, dig, NULL);
        +
        +	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
        +	BN_bn2bin(s,cs);
        +	EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
        +	OPENSSL_free(cs);
        +	EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
        +	EVP_DigestFinal_ex(&ctxt, dig, NULL);
        +	EVP_MD_CTX_cleanup(&ctxt);
        +
        +	return BN_bin2bn(dig, sizeof(dig), NULL);
        +	}
        +
        +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
        +	{
        +	BN_CTX *bn_ctx; 
        +	BIGNUM * A = NULL;
        +
        +	if (a == NULL || N == NULL || g == NULL ||
        +		(bn_ctx = BN_CTX_new()) == NULL) 
        +		return NULL;
        +
        +	if ((A = BN_new()) != NULL &&
        +	   !BN_mod_exp(A,g,a,N,bn_ctx))
        +		{
        +		BN_free(A);
        +		A = NULL;
        +		}
        +	BN_CTX_free(bn_ctx);
        +	return A;
        +	}
        +
        +
        +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u)
        +	{
        +	BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL;
        +	BN_CTX *bn_ctx;
        +
        +	if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL ||
        +		(bn_ctx = BN_CTX_new()) == NULL)
        +		return NULL; 
        +
        +	if ((tmp = BN_new()) == NULL ||
        +		(tmp2 = BN_new())== NULL ||
        +		(tmp3 = BN_new())== NULL ||
        +		(K = BN_new()) == NULL)
        +		goto err;
        +	
        +	if (!BN_mod_exp(tmp,g,x,N,bn_ctx))
        +		goto err;
        +	if (!(k = srp_Calc_k(N,g)))
        +		goto err;
        +	if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx))
        +		goto err;
        +	if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx))
        +		goto err;
        +
        +	if (!BN_mod_mul(tmp3,u,x,N,bn_ctx))
        +		goto err;
        +	if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx))
        +		goto err;
        +	if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx))
        +		goto err;
        +
        +err :
        +	BN_CTX_free(bn_ctx);
        +	BN_clear_free(tmp);
        +	BN_clear_free(tmp2);
        +	BN_clear_free(tmp3);
        +	BN_free(k);
        +	return K;	
        +	}
        +
        +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
        +	{
        +	BIGNUM *r;
        +	BN_CTX *bn_ctx; 
        +	int ret = 0;
        +
        +	if (B == NULL || N == NULL ||
        +		(bn_ctx = BN_CTX_new()) == NULL)
        +		return 0;
        +
        +	if ((r = BN_new()) == NULL)
        +		goto err;
        +	/* Checks if B % N == 0 */
        +	if (!BN_nnmod(r,B,N,bn_ctx))
        +		goto err;
        +	ret = !BN_is_zero(r);
        +err:
        +	BN_CTX_free(bn_ctx);
        +	BN_free(r);
        +	return ret;
        +	}
        +
        +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
        +	{
        +	/* Checks if A % N == 0 */
        +	return SRP_Verify_B_mod_N(A,N) ;
        +	}
        +
        +
        +/* Check if G and N are kwown parameters. 
        +   The values have been generated from the ietf-tls-srp draft version 8
        +*/
        +char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)
        +	{
        +	size_t i;
        +	if ((g == NULL) || (N == NULL))
        +		return 0;
        +
        +	srp_bn_print(g);
        +	srp_bn_print(N);
        +
        +	for(i = 0; i < KNOWN_GN_NUMBER; i++)
        +		{
        +		if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) 
        +			return knowngN[i].id;
        +		}
        +	return NULL;
        +	}
        +
        +SRP_gN *SRP_get_default_gN(const char *id)
        +	{
        +	size_t i;
        +
        +	if (id == NULL) 
        +		return knowngN;
        +	for(i = 0; i < KNOWN_GN_NUMBER; i++)
        +		{
        +		if (strcmp(knowngN[i].id, id)==0)
        +			return knowngN + i;
        +		}
        +	return NULL;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/srp/srp_vfy.c b/vendor/openssl/openssl/crypto/srp/srp_vfy.c
        new file mode 100644
        index 000000000..4a3d13edf
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/srp_vfy.c
        @@ -0,0 +1,658 @@
        +/* crypto/srp/srp_vfy.c */
        +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
        + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
        + * for the EdelKey project and contributed to the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 OPENSSL_NO_SRP
        +#include "cryptlib.h"
        +#include "srp_lcl.h"
        +#include <openssl/srp.h>
        +#include <openssl/evp.h>
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/txt_db.h>
        +
        +#define SRP_RANDOM_SALT_LEN 20
        +#define MAX_LEN 2500
        +
        +static char b64table[] =
        +  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
        +
        +/* the following two conversion routines have been inspired by code from Stanford */ 
        +
        +/*
        + * Convert a base64 string into raw byte array representation.
        + */
        +static int t_fromb64(unsigned char *a, const char *src)
        +	{
        +	char *loc;
        +	int i, j;
        +	int size;
        +
        +	while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
        +		++src;
        +	size = strlen(src);
        +	i = 0;
        +	while(i < size)
        +		{
        +		loc = strchr(b64table, src[i]);
        +		if(loc == (char *) 0) break;
        +		else a[i] = loc - b64table;
        +		++i;
        +		}
        +	size = i;
        +	i = size - 1;
        +	j = size;
        +	while(1)
        +		{
        +		a[j] = a[i];
        +		if(--i < 0) break;
        +		a[j] |= (a[i] & 3) << 6;
        +		--j;
        +		a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
        +		if(--i < 0) break;
        +		a[j] |= (a[i] & 0xf) << 4;
        +		--j;
        +		a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
        +		if(--i < 0) break;
        +		a[j] |= (a[i] << 2);
        +
        +		a[--j] = 0;
        +		if(--i < 0) break;
        +		}
        +	while(a[j] == 0 && j <= size) ++j;
        +	i = 0;
        +	while (j <= size) a[i++] = a[j++];
        +	return i;
        +	}
        +
        +
        +/*
        + * Convert a raw byte string into a null-terminated base64 ASCII string.
        + */
        +static char *t_tob64(char *dst, const unsigned char *src, int size)
        +	{
        +	int c, pos = size % 3;
        +	unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
        +	char *olddst = dst;
        +
        +	switch(pos)
        +		{
        +	case 1:
        +		b2 = src[0];
        +		break;
        +	case 2:
        +		b1 = src[0];
        +		b2 = src[1];
        +		break;
        +		}
        +
        +	while(1)
        +		{
        +		c = (b0 & 0xfc) >> 2;
        +		if(notleading || c != 0)
        +			{
        +			*dst++ = b64table[c];
        +			notleading = 1;
        +			}
        +		c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
        +		if(notleading || c != 0)
        +			{
        +			*dst++ = b64table[c];
        +			notleading = 1;
        +			}
        +		c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
        +		if(notleading || c != 0)
        +			{
        +			*dst++ = b64table[c];
        +			notleading = 1;
        +			}
        +		c = b2 & 0x3f;
        +		if(notleading || c != 0)
        +			{
        +			*dst++ = b64table[c];
        +			notleading = 1;
        +			}
        +		if(pos >= size) break;
        +		else
        +			{
        +			b0 = src[pos++];
        +			b1 = src[pos++];
        +			b2 = src[pos++];
        +			}
        +		}
        +
        +	*dst++ = '\0';
        +	return olddst;
        +	}
        +
        +static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
        +	{
        +	if (user_pwd == NULL) 
        +		return;
        +	BN_free(user_pwd->s);
        +	BN_clear_free(user_pwd->v);
        +	OPENSSL_free(user_pwd->id);
        +	OPENSSL_free(user_pwd->info);
        +	OPENSSL_free(user_pwd);
        +	}
        +
        +static SRP_user_pwd *SRP_user_pwd_new()
        +	{
        +	SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd));
        +	if (ret == NULL)
        +		return NULL;								
        +	ret->N = NULL;
        +	ret->g = NULL;	
        +	ret->s = NULL;
        +	ret->v = NULL;
        +	ret->id = NULL ;
        +	ret->info = NULL;
        +	return ret;
        +	}
        +
        +static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
        +				const BIGNUM *N)
        +	{
        +	vinfo->N = N;
        +	vinfo->g = g;	
        +	}
        +
        +static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
        +				const char *info)
        +	{
        +	if (id != NULL && NULL == (vinfo->id = BUF_strdup(id)))
        +		return 0;
        +	return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))) ;
        +	}
        +
        +static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
        +			       const char *v)
        +	{
        +	unsigned char tmp[MAX_LEN];
        +	int len;
        +
        +	if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN) 
        +		return 0; 
        +	len = t_fromb64(tmp, v);
        +	if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)) )
        +		return 0;
        +	len = t_fromb64(tmp, s);
        +	return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL) ;
        +	}
        +
        +static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
        +	{
        +	vinfo->v = v;
        +	vinfo->s = s;
        +	return (vinfo->s != NULL && vinfo->v != NULL) ;
        +	}
        +
        +SRP_VBASE *SRP_VBASE_new(char *seed_key)
        +	{
        +	SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE));
        +
        +	if (vb == NULL)
        +		return NULL;
        +	if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) ||
        +		!(vb->gN_cache = sk_SRP_gN_cache_new_null()))
        +		{
        +		OPENSSL_free(vb);
        +		return NULL;
        +		}
        +	vb->default_g = NULL;
        +	vb->default_N = NULL;
        +	vb->seed_key = NULL;
        +	if ((seed_key != NULL) && 
        +		(vb->seed_key = BUF_strdup(seed_key)) == NULL)
        +		{
        +		sk_SRP_user_pwd_free(vb->users_pwd);
        +		sk_SRP_gN_cache_free(vb->gN_cache);
        +		OPENSSL_free(vb);
        +		return NULL;
        +		}
        +	return vb;
        +	}
        +
        +
        +int SRP_VBASE_free(SRP_VBASE *vb)
        +	{
        +	sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free);
        +	sk_SRP_gN_cache_free(vb->gN_cache);
        +	OPENSSL_free(vb->seed_key);
        +	OPENSSL_free(vb);
        +	return 0;
        +	}
        +
        +
        +static SRP_gN_cache *SRP_gN_new_init(const char *ch)
        +	{
        +	unsigned char tmp[MAX_LEN];
        +	int len;
        +
        +	SRP_gN_cache *newgN = (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache));
        +	if (newgN == NULL)
        +		return NULL;
        +
        +	if ((newgN->b64_bn = BUF_strdup(ch)) == NULL)
        +		goto err;
        +
        +	len = t_fromb64(tmp, ch);
        +	if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
        +		return newgN;
        +
        +	OPENSSL_free(newgN->b64_bn);
        +err:
        +	OPENSSL_free(newgN);
        +	return NULL;
        +	}
        +
        +
        +static void SRP_gN_free(SRP_gN_cache *gN_cache)
        +	{
        +	if (gN_cache == NULL)
        +		return;
        +	OPENSSL_free(gN_cache->b64_bn);
        +	BN_free(gN_cache->bn);
        +	OPENSSL_free(gN_cache);
        +	}
        +
        +static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
        +	{
        +	int i;
        +
        +	SRP_gN *gN;
        +	if (gN_tab != NULL) 
        +	for(i = 0; i < sk_SRP_gN_num(gN_tab); i++)
        +		{
        +		gN = sk_SRP_gN_value(gN_tab, i);
        +		if (gN && (id == NULL || strcmp(gN->id,id)==0))
        +			return gN;
        +		}
        +	
        +	return SRP_get_default_gN(id);
        +	}
        +
        +static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
        +	{
        +	int i;
        +	if (gN_cache == NULL)
        +		return NULL;
        +
        +	/* search if we have already one... */
        +	for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++)
        +		{
        +		SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
        +		if (strcmp(cache->b64_bn,ch)==0)
        +			return cache->bn;
        +		}
        +		{		/* it is the first time that we find it */
        +		SRP_gN_cache *newgN = SRP_gN_new_init(ch);
        +		if (newgN)
        +			{
        +			if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0)
        +				return newgN->bn;
        +			SRP_gN_free(newgN);
        +			}
        +		}
        +	return NULL;
        +	}
        +
        +/* this function parses verifier file. Format is:
        + * string(index):base64(N):base64(g):0
        + * string(username):base64(v):base64(salt):int(index)
        + */
        +
        +
        +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
        +	{
        +	int error_code ;
        +	STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
        +	char *last_index = NULL;
        +	int i;
        +	char **pp;
        +
        +	SRP_gN *gN = NULL;
        +	SRP_user_pwd *user_pwd = NULL ;
        +
        +	TXT_DB *tmpdb = NULL;
        +	BIO *in = BIO_new(BIO_s_file());
        +
        +	error_code = SRP_ERR_OPEN_FILE;
        +
        +	if (in == NULL || BIO_read_filename(in,verifier_file) <= 0)
        +		goto err;
        +
        +	error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
        +
        +	if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL)
        +		goto err;
        +
        +	error_code = SRP_ERR_MEMORY;
        +
        +
        +	if (vb->seed_key)
        +		{
        +		last_index = SRP_get_default_gN(NULL)->id;
        +		}
        +	for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
        +		{
        +		pp = sk_OPENSSL_PSTRING_value(tmpdb->data,i);
        +		if (pp[DB_srptype][0] == DB_SRP_INDEX)
        +			{
        +			/*we add this couple in the internal Stack */
        +
        +			if ((gN = (SRP_gN *)OPENSSL_malloc(sizeof(SRP_gN))) == NULL) 
        + 				goto err;
        +
        +			if  (!(gN->id = BUF_strdup(pp[DB_srpid]))
        +	                ||  !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier]))
        +			||  !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt]))
        +			||  sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0)
        +				goto err;
        +
        +			gN = NULL;
        +
        +			if (vb->seed_key != NULL)
        +				{
        +				last_index = pp[DB_srpid];
        +				}
        +			}
        +		else if (pp[DB_srptype][0] == DB_SRP_VALID)
        +			{
        +			/* it is a user .... */
        +			SRP_gN *lgN;
        +			if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL)
        +				{
        +				error_code = SRP_ERR_MEMORY;
        +				if ((user_pwd = SRP_user_pwd_new()) == NULL) 
        +					goto err;
        +				
        +				SRP_user_pwd_set_gN(user_pwd,lgN->g,lgN->N);
        +				if (!SRP_user_pwd_set_ids(user_pwd, pp[DB_srpid],pp[DB_srpinfo]))
        +					goto err;
        +				
        +				error_code = SRP_ERR_VBASE_BN_LIB;
        +				if (!SRP_user_pwd_set_sv(user_pwd, pp[DB_srpsalt],pp[DB_srpverifier]))
        +					goto err;
        +
        +				if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
        +					goto err;
        +				user_pwd = NULL; /* abandon responsability */
        +				}
        +			}
        +		}
        +	
        +	if (last_index != NULL)
        +		{
        +		/* this means that we want to simulate a default user */
        +
        +		if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL))
        +			{
        +			error_code = SRP_ERR_VBASE_BN_LIB;
        +			goto err;
        +			}
        +		vb->default_g = gN->g ;
        +		vb->default_N = gN->N ;
        +		gN = NULL ;
        +		}
        +	error_code = SRP_NO_ERROR;
        +
        + err:
        +	/* there may be still some leaks to fix, if this fails, the application terminates most likely */
        +
        +	if (gN != NULL)
        +		{
        +		OPENSSL_free(gN->id);
        +		OPENSSL_free(gN);
        +		}
        +
        +	SRP_user_pwd_free(user_pwd);
        +
        +	if (tmpdb) TXT_DB_free(tmpdb);
        +	if (in) BIO_free_all(in);
        +
        +	sk_SRP_gN_free(SRP_gN_tab);
        +
        +	return error_code;
        +
        +	}
        +
        +
        +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
        +	{
        +	int i;
        +	SRP_user_pwd *user;
        +	unsigned char digv[SHA_DIGEST_LENGTH];
        +	unsigned char digs[SHA_DIGEST_LENGTH];
        +	EVP_MD_CTX ctxt;
        +
        +	if (vb == NULL)
        +		return NULL;
        +	for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
        +		{
        +		user = sk_SRP_user_pwd_value(vb->users_pwd, i);
        +		if (strcmp(user->id,username)==0)
        +			return user;
        +		}
        +	if ((vb->seed_key == NULL) ||
        +		(vb->default_g == NULL) ||
        +		(vb->default_N == NULL))
        +		return NULL;
        +
        +/* if the user is unknown we set parameters as well if we have a seed_key */
        +
        +	if ((user = SRP_user_pwd_new()) == NULL) 
        +		return NULL;
        +
        +	SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N);
        +				
        +	if (!SRP_user_pwd_set_ids(user,username,NULL))
        +		goto err;
        +		
        +	RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH);
        +	EVP_MD_CTX_init(&ctxt);
        +	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
        +	EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
        +	EVP_DigestUpdate(&ctxt, username, strlen(username));
        +	EVP_DigestFinal_ex(&ctxt, digs, NULL);
        +	EVP_MD_CTX_cleanup(&ctxt);
        +	if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL))) 
        +		return user;
        +
        +err:    SRP_user_pwd_free(user);
        +	return NULL;
        +	}
        +
        +
        +/*
        +   create a verifier (*salt,*verifier,g and N are in base64)
        +*/
        +char *SRP_create_verifier(const char *user, const char *pass, char **salt,
        +			  char **verifier, const char *N, const char *g)
        +	{
        +	int len;
        +	char * result=NULL;
        +	char *vf;
        +	BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
        +	unsigned char tmp[MAX_LEN];
        +	unsigned char tmp2[MAX_LEN];
        +	char * defgNid = NULL;
        +
        +	if ((user == NULL)||
        +		(pass == NULL)||
        +		(salt == NULL)||
        +		(verifier == NULL))
        +		goto err;
        +
        +	if (N)
        +		{
        +		if (!(len = t_fromb64(tmp, N))) goto err;
        +		N_bn = BN_bin2bn(tmp, len, NULL);
        +		if (!(len = t_fromb64(tmp, g))) goto err;
        +		g_bn = BN_bin2bn(tmp, len, NULL);
        +		defgNid = "*";
        +		}
        +	else
        +		{ 
        +		SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ;
        +		if (gN == NULL)
        +			goto err;
        +		N_bn = gN->N;
        +		g_bn = gN->g;
        +		defgNid = gN->id;
        +		}
        +
        +	if (*salt == NULL)
        +		{
        +		RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
        +
        +		s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
        +		}
        +	else
        +		{
        +		if (!(len = t_fromb64(tmp2, *salt)))
        +			goto err;
        +		s = BN_bin2bn(tmp2, len, NULL);
        +		}
        +
        +
        +	if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err;
        +
        +	BN_bn2bin(v,tmp);
        +	if (((vf = OPENSSL_malloc(BN_num_bytes(v)*2)) == NULL))
        +		goto err;
        +	t_tob64(vf, tmp, BN_num_bytes(v));
        +
        +	*verifier = vf;
        +	if (*salt == NULL)
        +		{
        +		char *tmp_salt;
        +
        +		if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
        +			{
        +			OPENSSL_free(vf);
        +			goto err;
        +			}
        +		t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
        +		*salt = tmp_salt;
        +		}
        +
        +	result=defgNid;
        +
        +err:
        +	if(N)
        +		{
        +		BN_free(N_bn);
        +		BN_free(g_bn);
        +		}
        +	return result;
        +	}
        +
        +/*
        +   create a verifier (*salt,*verifier,g and N are BIGNUMs)
        +*/
        +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g)
        +	{
        +	int result=0;
        +	BIGNUM *x = NULL;
        +	BN_CTX *bn_ctx = BN_CTX_new();
        +	unsigned char tmp2[MAX_LEN];
        +
        +	if ((user == NULL)||
        +		(pass == NULL)||
        +		(salt == NULL)||
        +		(verifier == NULL)||
        +		(N == NULL)||
        +		(g == NULL)||
        +		(bn_ctx == NULL))
        +		goto err;
        +
        +	srp_bn_print(N);
        +	srp_bn_print(g);
        +
        +	if (*salt == NULL)
        +		{
        +		RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
        +
        +		*salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL);
        +		}
        +
        +	x = SRP_Calc_x(*salt,user,pass);
        +
        +	*verifier = BN_new();
        +	if(*verifier == NULL) goto err;
        +
        +	if (!BN_mod_exp(*verifier,g,x,N,bn_ctx))
        +		{
        +		BN_clear_free(*verifier);
        +		goto err;
        +		}
        +
        +	srp_bn_print(*verifier);
        +
        +	result=1;
        +
        +err:
        +
        +	BN_clear_free(x);
        +	BN_CTX_free(bn_ctx);
        +	return result;
        +	}
        +
        +
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/srp/srptest.c b/vendor/openssl/openssl/crypto/srp/srptest.c
        new file mode 100644
        index 000000000..04b66b454
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/srp/srptest.c
        @@ -0,0 +1,162 @@
        +#include <openssl/opensslconf.h>
        +#ifdef OPENSSL_NO_SRP
        +
        +#include <stdio.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	printf("No SRP support\n");
        +	return(0);
        +	}
        +
        +#else
        +
        +#include <openssl/srp.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +static void showbn(const char *name, const BIGNUM *bn)
        +	{
        +	fputs(name, stdout);
        +	fputs(" = ", stdout);
        +	BN_print_fp(stdout, bn);
        +	putc('\n', stdout);
        +	}
        +
        +#define RANDOM_SIZE 32	/* use 256 bits on each side */
        +
        +static int run_srp(const char *username, const char *client_pass, const char *server_pass)
        +	{
        +	int ret=-1;
        +	BIGNUM *s = NULL;
        +	BIGNUM *v = NULL;
        +	BIGNUM *a = NULL;
        +	BIGNUM *b = NULL;
        +	BIGNUM *u = NULL;
        +	BIGNUM *x = NULL;
        +	BIGNUM *Apub = NULL;
        +	BIGNUM *Bpub = NULL;
        +	BIGNUM *Kclient = NULL;
        +	BIGNUM *Kserver = NULL;
        +	unsigned char rand_tmp[RANDOM_SIZE];
        +	/* use builtin 1024-bit params */
        +	SRP_gN *GN = SRP_get_default_gN("1024");
        +
        +	if(GN == NULL)
        +		{
        +		fprintf(stderr, "Failed to get SRP parameters\n");
        +		return -1;
        +		}
        +	/* Set up server's password entry */
        +	if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
        +		{
        +		fprintf(stderr, "Failed to create SRP verifier\n");
        +		return -1;
        +		}
        +
        +	showbn("N", GN->N);
        +	showbn("g", GN->g);
        +	showbn("Salt", s);
        +	showbn("Verifier", v);
        +
        +	/* Server random */
        +	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
        +	b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
        +	/* TODO - check b != 0 */
        +	showbn("b", b);
        +
        +	/* Server's first message */
        +	Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
        +	showbn("B", Bpub);
        +
        +	if(!SRP_Verify_B_mod_N(Bpub, GN->N))
        +		{
        +		fprintf(stderr, "Invalid B\n");
        +		return -1;
        +		}
        +
        +	/* Client random */
        +	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
        +	a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
        +	/* TODO - check a != 0 */
        +	showbn("a", a);
        +
        +	/* Client's response */
        +	Apub = SRP_Calc_A(a, GN->N, GN->g);
        +	showbn("A", Apub);
        +
        +	if(!SRP_Verify_A_mod_N(Apub, GN->N))
        +		{
        +		fprintf(stderr, "Invalid A\n");
        +		return -1;
        +		}
        +
        +	/* Both sides calculate u */
        +	u = SRP_Calc_u(Apub, Bpub, GN->N);
        +
        +	/* Client's key */
        +	x = SRP_Calc_x(s, username, client_pass);
        +	Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
        +	showbn("Client's key", Kclient);
        +
        +	/* Server's key */
        +	Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
        +	showbn("Server's key", Kserver);
        +
        +	if(BN_cmp(Kclient, Kserver) == 0)
        +		{
        +		ret = 0;
        +		}
        +	else
        +		{
        +		fprintf(stderr, "Keys mismatch\n");
        +		ret = 1;
        +		}
        +
        +	BN_clear_free(Kclient);
        +	BN_clear_free(Kserver);
        +	BN_clear_free(x);
        +	BN_free(u);
        +	BN_free(Apub);
        +	BN_clear_free(a);
        +	BN_free(Bpub);
        +	BN_clear_free(b);
        +	BN_free(s);
        +	BN_clear_free(v);
        +
        +	return ret;
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *bio_err;
        +	bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	ERR_load_crypto_strings();
        +
        +	/* "Negative" test, expect a mismatch */
        +	if(run_srp("alice", "password1", "password2") == 0)
        +		{
        +		fprintf(stderr, "Mismatched SRP run failed\n");
        +		return 1;
        +		}
        +
        +	/* "Positive" test, should pass */
        +	if(run_srp("alice", "password", "password") != 0)
        +		{
        +		fprintf(stderr, "Plain SRP run failed\n");
        +		return 1;
        +		}
        +
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	ERR_free_strings();
        +	CRYPTO_mem_leaks(bio_err);
        +
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/stack/Makefile b/vendor/openssl/openssl/crypto/stack/Makefile
        new file mode 100644
        index 000000000..5327692ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/stack/Makefile
        @@ -0,0 +1,84 @@
        +#
        +# OpenSSL/crypto/stack/Makefile
        +#
        +
        +DIR=	stack
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=stack.c
        +LIBOBJ=stack.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= stack.h safestack.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +stack.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +stack.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +stack.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +stack.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +stack.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +stack.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +stack.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +stack.o: ../../include/openssl/symhacks.h ../cryptlib.h stack.c
        diff --git a/vendor/openssl/openssl/crypto/stack/safestack.h b/vendor/openssl/openssl/crypto/stack/safestack.h
        new file mode 100644
        index 000000000..ea3aa0d80
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/stack/safestack.h
        @@ -0,0 +1,2663 @@
        +/* ====================================================================
        + * 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_SAFESTACK_H
        +#define HEADER_SAFESTACK_H
        +
        +#include <openssl/stack.h>
        +
        +#ifndef CHECKED_PTR_OF
        +#define CHECKED_PTR_OF(type, p) \
        +    ((void*) (1 ? p : (type*)0))
        +#endif
        +
        +/* In C++ we get problems because an explicit cast is needed from (void *)
        + * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
        + * below. 
        + */
        +
        +#define CHECKED_STACK_OF(type, p) \
        +    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
        +
        +#define CHECKED_SK_FREE_FUNC(type, p) \
        +    ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
        +
        +#define CHECKED_SK_FREE_FUNC2(type, p) \
        +    ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
        +
        +#define CHECKED_SK_CMP_FUNC(type, p) \
        +    ((int (*)(const void *, const void *)) \
        +	((1 ? p : (int (*)(const type * const *, const type * const *))0)))
        +
        +#define STACK_OF(type) struct stack_st_##type
        +#define PREDECLARE_STACK_OF(type) STACK_OF(type);
        +
        +#define DECLARE_STACK_OF(type) \
        +STACK_OF(type) \
        +    { \
        +    _STACK stack; \
        +    };
        +#define DECLARE_SPECIAL_STACK_OF(type, type2) \
        +STACK_OF(type) \
        +    { \
        +    _STACK stack; \
        +    };
        +
        +#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
        +
        +
        +/* Strings are special: normally an lhash entry will point to a single
        + * (somewhat) mutable object. In the case of strings:
        + *
        + * a) Instead of a single char, there is an array of chars, NUL-terminated.
        + * b) The string may have be immutable.
        + *
        + * So, they need their own declarations. Especially important for
        + * type-checking tools, such as Deputy.
        + *
        +o * In practice, however, it appears to be hard to have a const
        + * string. For now, I'm settling for dealing with the fact it is a
        + * string at all.
        + */
        +typedef char *OPENSSL_STRING;
        +
        +typedef const char *OPENSSL_CSTRING;
        +
        +/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
        + * STACK_OF(STRING) is really more like STACK_OF(char), only, as
        + * mentioned above, instead of a single char each entry is a
        + * NUL-terminated array of chars. So, we have to implement STRING
        + * specially for STACK_OF. This is dealt with in the autogenerated
        + * macros below.
        + */
        +
        +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
        +
        +/* Similarly, we sometimes use a block of characters, NOT
        + * nul-terminated. These should also be distinguished from "normal"
        + * stacks. */
        +
        +typedef void *OPENSSL_BLOCK;
        +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
        +
        +/* SKM_sk_... stack macros are internal to safestack.h:
        + * never use them directly, use sk_<type>_... instead */
        +#define SKM_sk_new(type, cmp) \
        +	((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
        +#define SKM_sk_new_null(type) \
        +	((STACK_OF(type) *)sk_new_null())
        +#define SKM_sk_free(type, st) \
        +	sk_free(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_num(type, st) \
        +	sk_num(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_value(type, st,i) \
        +	((type *)sk_value(CHECKED_STACK_OF(type, st), i))
        +#define SKM_sk_set(type, st,i,val) \
        +	sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
        +#define SKM_sk_zero(type, st) \
        +	sk_zero(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_push(type, st, val) \
        +	sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
        +#define SKM_sk_unshift(type, st, val) \
        +	sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
        +#define SKM_sk_find(type, st, val) \
        +	sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
        +#define SKM_sk_find_ex(type, st, val) \
        +	sk_find_ex(CHECKED_STACK_OF(type, st), \
        +		   CHECKED_PTR_OF(type, val))
        +#define SKM_sk_delete(type, st, i) \
        +	(type *)sk_delete(CHECKED_STACK_OF(type, st), i)
        +#define SKM_sk_delete_ptr(type, st, ptr) \
        +	(type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
        +#define SKM_sk_insert(type, st,val, i) \
        +	sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
        +#define SKM_sk_set_cmp_func(type, st, cmp) \
        +	((int (*)(const type * const *,const type * const *)) \
        +	sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
        +#define SKM_sk_dup(type, st) \
        +	(STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_pop_free(type, st, free_func) \
        +	sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
        +#define SKM_sk_shift(type, st) \
        +	(type *)sk_shift(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_pop(type, st) \
        +	(type *)sk_pop(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_sort(type, st) \
        +	sk_sort(CHECKED_STACK_OF(type, st))
        +#define SKM_sk_is_sorted(type, st) \
        +	sk_is_sorted(CHECKED_STACK_OF(type, st))
        +
        +#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +  (STACK_OF(type) *)d2i_ASN1_SET( \
        +				(STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
        +				pp, length, \
        +				CHECKED_D2I_OF(type, d2i_func), \
        +				CHECKED_SK_FREE_FUNC(type, free_func), \
        +				ex_tag, ex_class)
        +
        +#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +  i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
        +				CHECKED_I2D_OF(type, i2d_func), \
        +				ex_tag, ex_class, is_set)
        +
        +#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
        +	ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
        +			CHECKED_I2D_OF(type, i2d_func), buf, len)
        +
        +#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
        +	(STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
        +
        +#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
        +	(STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
        +				CHECKED_D2I_OF(type, d2i_func), \
        +				CHECKED_SK_FREE_FUNC(type, free_func), \
        +				pass, passlen, oct, seq)
        +
        +/* This block of defines is updated by util/mkstack.pl, please do not touch! */
        +#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
        +#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
        +#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
        +#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
        +#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
        +#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
        +#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
        +#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
        +#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
        +#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
        +#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
        +#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
        +#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
        +#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
        +#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
        +#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
        +#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
        +#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
        +#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
        +#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
        +#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
        +
        +#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
        +#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
        +#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
        +#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
        +#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
        +#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
        +#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
        +#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
        +#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
        +#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
        +#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
        +#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
        +#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
        +#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
        +#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
        +#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
        +#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
        +#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
        +#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
        +#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
        +#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
        +
        +#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
        +#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
        +#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
        +#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
        +#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
        +#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
        +#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
        +#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
        +#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
        +#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
        +#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
        +#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
        +#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
        +#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
        +#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
        +#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
        +#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
        +#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
        +#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
        +#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
        +#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
        +
        +#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
        +#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
        +#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
        +#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
        +#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
        +#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
        +#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
        +#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
        +#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
        +#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
        +#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
        +#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
        +#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
        +#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
        +#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
        +#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
        +#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
        +#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
        +#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
        +#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
        +#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
        +
        +#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
        +#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
        +#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
        +#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
        +#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
        +#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
        +#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
        +#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
        +#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
        +#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
        +#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
        +#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
        +#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
        +#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
        +#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
        +#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
        +#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
        +#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
        +#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
        +#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
        +#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
        +
        +#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
        +#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
        +#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
        +#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
        +#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
        +#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
        +#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
        +#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
        +#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
        +#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
        +#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
        +#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
        +#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
        +#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
        +#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
        +#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
        +#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
        +#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
        +#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
        +#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
        +#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
        +
        +#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
        +#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
        +#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
        +#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
        +#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
        +#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
        +#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
        +#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
        +#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
        +#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
        +#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
        +#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
        +#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
        +#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
        +#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
        +#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
        +#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
        +#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
        +#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
        +#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
        +#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
        +
        +#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
        +#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
        +#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
        +#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
        +#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
        +#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
        +#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
        +#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
        +#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
        +#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
        +#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
        +#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
        +#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
        +#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
        +#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
        +#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
        +#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
        +#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
        +#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
        +#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
        +#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
        +
        +#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
        +#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
        +#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
        +#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
        +#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
        +#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
        +#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
        +#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
        +#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
        +#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
        +#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
        +#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
        +#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
        +#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
        +#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
        +#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
        +#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
        +#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
        +#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
        +#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
        +#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
        +
        +#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
        +#define sk_BIO_new_null() SKM_sk_new_null(BIO)
        +#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
        +#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
        +#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
        +#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
        +#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
        +#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
        +#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
        +#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
        +#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
        +#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
        +#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
        +#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
        +#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
        +#define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
        +#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
        +#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
        +#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
        +#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
        +#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
        +
        +#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
        +#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
        +#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
        +#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
        +#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
        +#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
        +#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
        +#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
        +#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
        +#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
        +#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
        +#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
        +#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
        +#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
        +#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
        +#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
        +#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
        +#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
        +#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
        +#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
        +#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
        +
        +#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
        +#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
        +#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
        +#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
        +#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
        +#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
        +#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
        +#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
        +#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
        +#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
        +#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
        +#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
        +#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
        +#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
        +#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
        +#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
        +#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
        +#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
        +#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
        +#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
        +#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
        +
        +#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
        +#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
        +#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
        +#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
        +#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
        +#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
        +#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
        +#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
        +#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
        +#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
        +#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
        +#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
        +#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
        +#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
        +#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
        +#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
        +#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
        +#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
        +#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
        +#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
        +#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
        +
        +#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
        +#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
        +#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
        +#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
        +#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
        +#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
        +#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
        +#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
        +#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
        +#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
        +#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
        +#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
        +#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
        +#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
        +#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
        +#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
        +#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
        +#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
        +#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
        +#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
        +#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
        +
        +#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
        +#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
        +#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
        +#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
        +#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
        +#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
        +#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
        +#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
        +#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
        +#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
        +#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
        +#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
        +#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
        +#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
        +#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
        +#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
        +#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
        +#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
        +#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
        +#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
        +#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
        +
        +#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
        +#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
        +#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
        +#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
        +#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
        +#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
        +#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
        +#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
        +#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
        +#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
        +#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
        +#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
        +#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
        +#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
        +#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
        +#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
        +#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
        +#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
        +#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
        +#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
        +#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
        +
        +#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
        +#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
        +#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
        +#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
        +#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
        +#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
        +#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
        +#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
        +#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
        +#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
        +#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
        +#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
        +#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
        +#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
        +#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
        +#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
        +#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
        +#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
        +#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
        +#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
        +#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
        +
        +#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
        +#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
        +#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
        +#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
        +#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
        +#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
        +#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
        +#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
        +#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
        +#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
        +#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
        +#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
        +#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
        +#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
        +#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
        +#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
        +#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
        +#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
        +#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
        +#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
        +#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
        +
        +#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
        +#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
        +#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
        +#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
        +#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
        +#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
        +#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
        +#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
        +#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
        +#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
        +#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
        +#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
        +#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
        +#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
        +#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
        +#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
        +#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
        +#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
        +#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
        +#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
        +#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
        +
        +#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
        +#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
        +#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
        +#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
        +#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
        +#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
        +#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
        +#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
        +#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
        +#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
        +#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
        +#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
        +#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
        +#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
        +#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
        +#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
        +#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
        +#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
        +#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
        +#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
        +#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
        +
        +#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
        +#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
        +#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
        +#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
        +#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
        +#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
        +#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
        +#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
        +#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
        +#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
        +#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
        +#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
        +#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
        +#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
        +#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
        +#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
        +#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
        +#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
        +#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
        +#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
        +#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
        +
        +#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
        +#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
        +#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
        +#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
        +#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
        +#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
        +#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
        +#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
        +#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
        +#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
        +#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
        +#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
        +#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
        +#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
        +#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
        +#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
        +#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
        +#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
        +#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
        +#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
        +#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
        +
        +#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
        +#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
        +#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
        +#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
        +#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
        +#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
        +#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
        +#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
        +#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
        +#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
        +#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
        +#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
        +#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
        +#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
        +#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
        +#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
        +#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
        +#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
        +#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
        +#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
        +#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
        +
        +#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
        +#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
        +#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
        +#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
        +#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
        +#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
        +#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
        +#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
        +#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
        +#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
        +#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
        +#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
        +#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
        +#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
        +#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
        +#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
        +#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
        +#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
        +#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
        +#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
        +#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
        +
        +#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
        +#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
        +#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
        +#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
        +#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
        +#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
        +#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
        +#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
        +#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
        +#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
        +#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
        +#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
        +#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
        +#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
        +#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
        +#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
        +#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
        +#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
        +#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
        +#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
        +#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
        +
        +#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
        +#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
        +#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
        +#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
        +#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
        +#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
        +#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
        +#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
        +#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
        +#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
        +#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
        +#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
        +#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
        +#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
        +#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
        +#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
        +#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
        +#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
        +#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
        +#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
        +#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
        +
        +#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
        +#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
        +#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
        +#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
        +#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
        +#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
        +#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
        +#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
        +#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
        +#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
        +#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
        +#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
        +#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
        +#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
        +#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
        +#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
        +#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
        +#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
        +#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
        +#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
        +#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
        +
        +#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
        +#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
        +#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
        +#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
        +#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
        +#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
        +#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
        +#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
        +#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
        +#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
        +#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
        +#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
        +#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
        +#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
        +#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
        +#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
        +#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
        +#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
        +#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
        +#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
        +#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
        +
        +#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
        +#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
        +#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
        +#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
        +#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
        +#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
        +#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
        +#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
        +#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
        +#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
        +#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
        +#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
        +#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
        +#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
        +#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
        +#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
        +#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
        +#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
        +#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
        +#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
        +#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
        +
        +#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
        +#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
        +#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
        +#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
        +#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
        +#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
        +#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
        +#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
        +#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
        +#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
        +#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
        +#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
        +#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
        +#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
        +#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
        +#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
        +#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
        +#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
        +#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
        +#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
        +#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
        +
        +#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
        +#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
        +#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
        +#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
        +#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
        +#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
        +#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
        +#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
        +#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
        +#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
        +#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
        +#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
        +#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
        +#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
        +#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
        +#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
        +#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
        +#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
        +#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
        +#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
        +#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
        +
        +#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
        +#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
        +#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
        +#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
        +#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
        +#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
        +#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
        +#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
        +#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
        +#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
        +#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
        +#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
        +#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
        +#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
        +#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
        +#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
        +#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
        +#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
        +#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
        +#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
        +#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
        +
        +#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
        +#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
        +#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
        +#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
        +#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
        +#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
        +#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
        +#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
        +#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
        +#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
        +#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
        +#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
        +#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
        +#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
        +#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
        +#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
        +#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
        +#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
        +#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
        +#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
        +#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
        +
        +#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
        +#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
        +#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
        +#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
        +#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
        +#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
        +#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
        +#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
        +#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
        +#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
        +#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
        +#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
        +#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
        +#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
        +#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
        +#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
        +#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
        +#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
        +#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
        +#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
        +#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
        +
        +#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
        +#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
        +#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
        +#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
        +#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
        +#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
        +#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
        +#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
        +#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
        +#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
        +#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
        +#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
        +#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
        +#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
        +#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
        +#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
        +#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
        +#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
        +#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
        +#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
        +#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
        +
        +#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
        +#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
        +#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
        +#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
        +#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
        +#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
        +#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
        +#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
        +#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
        +#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
        +#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
        +#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
        +#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
        +#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
        +#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
        +#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
        +#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
        +#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
        +#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
        +#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
        +#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
        +
        +#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
        +#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
        +#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
        +#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
        +#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
        +#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
        +#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
        +#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
        +#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
        +#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
        +#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
        +#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
        +#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
        +#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
        +#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
        +#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
        +#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
        +#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
        +#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
        +#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
        +#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
        +
        +#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
        +#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
        +#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
        +#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
        +#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
        +#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
        +#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
        +#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
        +#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
        +#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
        +#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
        +#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
        +#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
        +#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
        +#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
        +#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
        +#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
        +#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
        +#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
        +#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
        +#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
        +
        +#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
        +#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
        +#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
        +#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
        +#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
        +#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
        +#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
        +#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
        +#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
        +#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
        +#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
        +#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
        +#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
        +#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
        +#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
        +#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
        +#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
        +#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
        +#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
        +#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
        +#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
        +
        +#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
        +#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
        +#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
        +#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
        +#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
        +#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
        +#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
        +#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
        +#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
        +#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
        +#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
        +#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
        +#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
        +#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
        +#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
        +#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
        +#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
        +#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
        +#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
        +#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
        +#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
        +
        +#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
        +#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
        +#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
        +#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
        +#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
        +#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
        +#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
        +#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
        +#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
        +#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
        +#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
        +#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
        +#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
        +#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
        +#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
        +#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
        +#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
        +#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
        +#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
        +#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
        +#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
        +
        +#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
        +#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
        +#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
        +#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
        +#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
        +#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
        +#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
        +#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
        +#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
        +#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
        +#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
        +#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
        +#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
        +#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
        +#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
        +#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
        +#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
        +#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
        +#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
        +#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
        +#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
        +
        +#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
        +#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
        +#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
        +#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
        +#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
        +#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
        +#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
        +#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
        +#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
        +#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
        +#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
        +#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
        +#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
        +#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
        +#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
        +#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
        +#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
        +#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
        +#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
        +#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
        +#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
        +
        +#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
        +#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
        +#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
        +#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
        +#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
        +#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
        +#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
        +#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
        +#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
        +#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
        +#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
        +#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
        +#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
        +#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
        +#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
        +#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
        +#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
        +#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
        +#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
        +#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
        +#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
        +
        +#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
        +#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
        +#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
        +#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
        +#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
        +#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
        +#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
        +#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
        +#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
        +#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
        +#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
        +#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
        +#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
        +#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
        +#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
        +#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
        +#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
        +#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
        +#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
        +#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
        +#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
        +
        +#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
        +#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
        +#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
        +#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
        +#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
        +#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
        +#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
        +#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
        +#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
        +#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
        +#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
        +#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
        +#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
        +#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
        +#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
        +#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
        +#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
        +#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
        +#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
        +#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
        +#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
        +
        +#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
        +#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
        +#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
        +#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
        +#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
        +#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
        +#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
        +#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
        +#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
        +#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
        +#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
        +#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
        +#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
        +#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
        +#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
        +#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
        +#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
        +#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
        +#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
        +#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
        +#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
        +
        +#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
        +#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
        +#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
        +#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
        +#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
        +#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
        +#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
        +#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
        +#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
        +#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
        +#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
        +#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
        +#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
        +#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
        +#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
        +#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
        +#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
        +#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
        +#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
        +#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
        +#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
        +
        +#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
        +#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
        +#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
        +#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
        +#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
        +#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
        +#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
        +#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
        +#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
        +#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
        +#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
        +#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
        +#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
        +#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
        +#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
        +#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
        +#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
        +#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
        +#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
        +#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
        +#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
        +
        +#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
        +#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
        +#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
        +#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
        +#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
        +#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
        +#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
        +#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
        +#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
        +#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
        +#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
        +#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
        +#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
        +#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
        +#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
        +#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
        +#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
        +#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
        +#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
        +#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
        +#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
        +
        +#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
        +#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
        +#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
        +#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
        +#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
        +#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
        +#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
        +#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
        +#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
        +#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
        +#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
        +#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
        +#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
        +#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
        +#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
        +#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
        +#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
        +#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
        +#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
        +#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
        +#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
        +
        +#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
        +#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
        +#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
        +#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
        +#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
        +#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
        +#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
        +#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
        +#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
        +#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
        +#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
        +#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
        +#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
        +#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
        +#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
        +#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
        +#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
        +#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
        +#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
        +#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
        +#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
        +
        +#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
        +#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
        +#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
        +#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
        +#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
        +#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
        +#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
        +#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
        +#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
        +#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
        +#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
        +#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
        +#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
        +#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
        +#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
        +#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
        +#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
        +#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
        +#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
        +#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
        +#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
        +
        +#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
        +#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
        +#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
        +#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
        +#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
        +#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
        +#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
        +#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
        +#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
        +#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
        +#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
        +#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
        +#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
        +#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
        +#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
        +#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
        +#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
        +#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
        +#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
        +#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
        +#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
        +
        +#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
        +#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
        +#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
        +#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
        +#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
        +#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
        +#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
        +#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
        +#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
        +#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
        +#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
        +#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
        +#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
        +#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
        +#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
        +#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
        +#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
        +#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
        +#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
        +#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
        +#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
        +
        +#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
        +#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
        +#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
        +#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
        +#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
        +#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
        +#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
        +#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
        +#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
        +#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
        +#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
        +#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
        +#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
        +#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
        +#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
        +#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
        +#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
        +#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
        +#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
        +#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
        +#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
        +
        +#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
        +#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
        +#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
        +#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
        +#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
        +#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
        +#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
        +#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
        +#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
        +#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
        +#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
        +#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
        +#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
        +#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
        +#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
        +#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
        +#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
        +#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
        +#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
        +#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
        +#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
        +
        +#define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp))
        +#define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
        +#define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
        +#define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
        +#define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
        +#define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
        +#define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
        +#define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
        +#define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
        +#define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
        +#define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val))
        +#define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
        +#define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
        +#define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
        +#define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
        +#define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
        +#define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
        +#define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
        +#define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
        +#define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
        +#define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st))
        +
        +#define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp))
        +#define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
        +#define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
        +#define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
        +#define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
        +#define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
        +#define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
        +#define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
        +#define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
        +#define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
        +#define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val))
        +#define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
        +#define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
        +#define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
        +#define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
        +#define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
        +#define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
        +#define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
        +#define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
        +#define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
        +#define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st))
        +
        +#define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp))
        +#define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
        +#define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
        +#define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
        +#define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
        +#define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
        +#define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
        +#define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
        +#define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
        +#define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
        +#define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val))
        +#define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
        +#define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
        +#define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
        +#define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
        +#define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
        +#define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
        +#define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
        +#define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
        +#define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
        +#define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st))
        +
        +#define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp))
        +#define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE)
        +#define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st))
        +#define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st))
        +#define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i))
        +#define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val))
        +#define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st))
        +#define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val))
        +#define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val))
        +#define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val))
        +#define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val))
        +#define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i))
        +#define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr))
        +#define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i))
        +#define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp))
        +#define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st)
        +#define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func))
        +#define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st))
        +#define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st))
        +#define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st))
        +#define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st))
        +
        +#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
        +#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
        +#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
        +#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
        +#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
        +#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
        +#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
        +#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
        +#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
        +#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
        +#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
        +#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
        +#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
        +#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
        +#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
        +#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
        +#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
        +#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
        +#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
        +#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
        +#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
        +
        +#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
        +#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
        +#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
        +#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
        +#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
        +#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
        +#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
        +#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
        +#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
        +#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
        +#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
        +#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
        +#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
        +#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
        +#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
        +#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
        +#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
        +#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
        +#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
        +#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
        +#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
        +
        +#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
        +#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
        +#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
        +#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
        +#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
        +#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
        +#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
        +#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
        +#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
        +#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
        +#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
        +#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
        +#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
        +#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
        +#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
        +#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
        +#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
        +#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
        +#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
        +#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
        +#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
        +
        +#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
        +#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
        +#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
        +#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
        +#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
        +#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
        +#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
        +#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
        +#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
        +#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
        +#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
        +#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
        +#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
        +#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
        +#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
        +#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
        +#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
        +#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
        +#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
        +#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
        +#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
        +
        +#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
        +#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
        +#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
        +#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
        +#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
        +#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
        +#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
        +#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
        +#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
        +#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
        +#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
        +#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
        +#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
        +#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
        +#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
        +#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
        +#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
        +#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
        +#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
        +#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
        +#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
        +
        +#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
        +#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
        +#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
        +#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
        +#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
        +#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
        +#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
        +#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
        +#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
        +#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
        +#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
        +#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
        +#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
        +#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
        +#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
        +#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
        +#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
        +#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
        +#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
        +#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
        +#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
        +
        +#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
        +#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
        +#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
        +#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
        +#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
        +#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
        +#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
        +#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
        +#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
        +#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
        +#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
        +#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
        +#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
        +#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
        +#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
        +#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
        +#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
        +#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
        +#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
        +#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
        +#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
        +
        +#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
        +#define sk_X509_new_null() SKM_sk_new_null(X509)
        +#define sk_X509_free(st) SKM_sk_free(X509, (st))
        +#define sk_X509_num(st) SKM_sk_num(X509, (st))
        +#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
        +#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
        +#define sk_X509_zero(st) SKM_sk_zero(X509, (st))
        +#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
        +#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
        +#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
        +#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
        +#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
        +#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
        +#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
        +#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
        +#define sk_X509_dup(st) SKM_sk_dup(X509, st)
        +#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
        +#define sk_X509_shift(st) SKM_sk_shift(X509, (st))
        +#define sk_X509_pop(st) SKM_sk_pop(X509, (st))
        +#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
        +#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
        +
        +#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
        +#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
        +#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
        +#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
        +#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
        +#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
        +#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
        +#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
        +#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
        +#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
        +#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
        +#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
        +#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
        +#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
        +#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
        +#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
        +#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
        +#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
        +#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
        +#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
        +#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
        +
        +#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
        +#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
        +#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
        +#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
        +#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
        +#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
        +#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
        +#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
        +#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
        +#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
        +#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
        +#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
        +#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
        +#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
        +#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
        +#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
        +#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
        +#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
        +#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
        +#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
        +#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
        +
        +#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
        +#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
        +#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
        +#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
        +#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
        +#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
        +#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
        +#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
        +#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
        +#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
        +#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
        +#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
        +#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
        +#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
        +#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
        +#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
        +#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
        +#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
        +#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
        +#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
        +#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
        +
        +#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
        +#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
        +#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
        +#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
        +#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
        +#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
        +#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
        +#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
        +#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
        +#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
        +#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
        +#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
        +#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
        +#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
        +#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
        +#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
        +#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
        +#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
        +#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
        +#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
        +#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
        +
        +#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
        +#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
        +#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
        +#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
        +#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
        +#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
        +#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
        +#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
        +#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
        +#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
        +#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
        +#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
        +#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
        +#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
        +#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
        +#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
        +#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
        +#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
        +#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
        +#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
        +#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
        +
        +#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
        +#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
        +#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
        +#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
        +#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
        +#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
        +#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
        +#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
        +#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
        +#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
        +#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
        +#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
        +#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
        +#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
        +#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
        +#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
        +#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
        +#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
        +#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
        +#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
        +#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
        +
        +#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
        +#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
        +#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
        +#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
        +#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
        +#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
        +#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
        +#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
        +#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
        +#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
        +#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
        +#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
        +#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
        +#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
        +#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
        +#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
        +#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
        +#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
        +#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
        +#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
        +#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
        +
        +#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
        +#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
        +#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
        +#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
        +#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
        +#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
        +#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
        +#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
        +#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
        +#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
        +#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
        +#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
        +#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
        +#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
        +#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
        +#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
        +#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
        +#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
        +#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
        +#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
        +#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
        +
        +#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
        +#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
        +#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
        +#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
        +#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
        +#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
        +#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
        +#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
        +#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
        +#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
        +#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
        +#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
        +#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
        +#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
        +#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
        +#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
        +#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
        +#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
        +#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
        +#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
        +#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
        +
        +#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
        +#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
        +#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
        +#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
        +#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
        +#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
        +#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
        +#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
        +#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
        +#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
        +#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
        +#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
        +#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
        +#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
        +#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
        +#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
        +#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
        +#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
        +#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
        +#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
        +#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
        +
        +#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
        +#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
        +#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
        +#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
        +#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
        +#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
        +#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
        +#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
        +#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
        +#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
        +#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
        +#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
        +#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
        +#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
        +#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
        +#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
        +#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
        +#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
        +#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
        +#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
        +#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
        +
        +#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
        +#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
        +#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
        +#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
        +#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
        +#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
        +#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
        +#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
        +#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
        +#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
        +#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
        +#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
        +#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
        +#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
        +#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
        +#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
        +#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
        +#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
        +#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
        +#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
        +#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
        +
        +#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
        +#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
        +#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
        +#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
        +#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
        +#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
        +#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
        +#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
        +#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
        +#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
        +#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
        +#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
        +#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
        +#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
        +#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
        +#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
        +#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
        +#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
        +#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
        +#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
        +#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
        +
        +#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
        +#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
        +#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
        +#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
        +#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
        +#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
        +#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
        +#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
        +#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
        +#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
        +#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
        +#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
        +#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
        +#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
        +#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
        +#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
        +#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
        +#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
        +#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
        +#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
        +#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
        +
        +#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
        +#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
        +#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
        +#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
        +#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
        +#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
        +#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
        +#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
        +#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
        +#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
        +#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
        +#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
        +#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
        +#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
        +#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
        +#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
        +#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
        +#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
        +#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
        +#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
        +#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
        +
        +#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
        +#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
        +#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
        +#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
        +#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
        +#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
        +#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
        +#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
        +#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
        +#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
        +#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
        +#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
        +#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
        +#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
        +#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
        +#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
        +#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
        +#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
        +#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
        +#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
        +#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
        +
        +#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
        +#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
        +#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
        +#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
        +#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
        +#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
        +#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
        +#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
        +#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
        +#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
        +#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
        +#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
        +#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
        +#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
        +#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
        +#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
        +#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
        +#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
        +#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
        +#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
        +#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
        +
        +#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
        +#define sk_void_new_null() SKM_sk_new_null(void)
        +#define sk_void_free(st) SKM_sk_free(void, (st))
        +#define sk_void_num(st) SKM_sk_num(void, (st))
        +#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
        +#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
        +#define sk_void_zero(st) SKM_sk_zero(void, (st))
        +#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
        +#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
        +#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
        +#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
        +#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
        +#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
        +#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
        +#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
        +#define sk_void_dup(st) SKM_sk_dup(void, st)
        +#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
        +#define sk_void_shift(st) SKM_sk_shift(void, (st))
        +#define sk_void_pop(st) SKM_sk_pop(void, (st))
        +#define sk_void_sort(st) SKM_sk_sort(void, (st))
        +#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
        +
        +#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
        +#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
        +#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
        +#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
        +#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
        +#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
        +#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
        +#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
        +#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
        +#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
        +#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
        +#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
        +#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
        +#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
        +#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
        +#define sk_OPENSSL_STRING_set_cmp_func(st, cmp)  \
        +	((int (*)(const char * const *,const char * const *)) \
        +	sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
        +#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
        +#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
        +#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
        +#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
        +#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
        +
        +
        +#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
        +#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
        +#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
        +#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
        +#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
        +#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
        +#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
        +#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
        +#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
        +#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
        +#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
        +#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
        +#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
        +#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
        +#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
        +#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp)  \
        +	((int (*)(const void * const *,const void * const *)) \
        +	sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
        +#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
        +#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
        +#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
        +#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
        +#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
        +
        +
        +#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
        +#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
        +#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
        +#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
        +#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
        +#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
        +#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
        +#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
        +#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
        +#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
        +#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
        +#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
        +#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
        +#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
        +#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
        +#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp)  \
        +	((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
        +	sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
        +#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
        +#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
        +#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
        +#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
        +#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
        +
        +
        +#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
        +
        +#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        +	SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        +	SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
        +	SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
        +	SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
        +
        +#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
        +	SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
        +
        +#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
        +	SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
        +
        +#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
        +#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
        +#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
        +#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
        +#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
        +#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
        +#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
        +#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
        +#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
        +#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
        +#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
        +#define lh_ADDED_OBJ_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(ADDED_OBJ,lh,out)
        +#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
        +
        +#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
        +#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
        +#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
        +#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
        +#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
        +#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
        +#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
        +#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
        +#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
        +#define lh_APP_INFO_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(APP_INFO,lh,out)
        +#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
        +#define lh_APP_INFO_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(APP_INFO,lh,out)
        +#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
        +
        +#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
        +#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
        +#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
        +#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
        +#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
        +#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
        +#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
        +#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
        +#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
        +#define lh_CONF_VALUE_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
        +#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
        +#define lh_CONF_VALUE_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(CONF_VALUE,lh,out)
        +#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
        +
        +#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
        +#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
        +#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
        +#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
        +#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
        +#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
        +#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
        +#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
        +#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
        +#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
        +#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
        +#define lh_ENGINE_PILE_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(ENGINE_PILE,lh,out)
        +#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
        +
        +#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
        +#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
        +#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
        +#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
        +#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
        +#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
        +#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
        +#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
        +#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
        +#define lh_ERR_STATE_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(ERR_STATE,lh,out)
        +#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
        +#define lh_ERR_STATE_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(ERR_STATE,lh,out)
        +#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
        +
        +#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
        +#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
        +#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
        +#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
        +#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
        +#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
        +#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
        +#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
        +#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
        +#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
        +#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
        +#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
        +#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
        +
        +#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
        +#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
        +#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
        +#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
        +#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
        +#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
        +#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
        +#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
        +#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
        +#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
        +#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
        +#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
        +#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
        +
        +#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
        +#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
        +#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
        +#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
        +#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
        +#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
        +#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
        +#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
        +#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
        +#define lh_FUNCTION_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(FUNCTION,lh,out)
        +#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
        +#define lh_FUNCTION_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(FUNCTION,lh,out)
        +#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
        +
        +#define lh_MEM_new() LHM_lh_new(MEM,mem)
        +#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
        +#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
        +#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
        +#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
        +#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
        +#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
        +#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
        +#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
        +#define lh_MEM_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(MEM,lh,out)
        +#define lh_MEM_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(MEM,lh,out)
        +#define lh_MEM_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(MEM,lh,out)
        +#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
        +
        +#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
        +#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
        +#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
        +#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
        +#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
        +#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
        +#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
        +#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
        +#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
        +#define lh_OBJ_NAME_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
        +#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
        +#define lh_OBJ_NAME_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(OBJ_NAME,lh,out)
        +#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
        +
        +#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
        +#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
        +#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
        +#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
        +#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
        +#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
        +#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
        +#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
        +#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
        +#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
        +#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
        +#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
        +#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
        +
        +#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
        +#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
        +#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
        +#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
        +#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
        +#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
        +#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
        +#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
        +#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
        +#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
        +#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
        +#define lh_OPENSSL_STRING_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
        +#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
        +
        +#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
        +#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
        +#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
        +#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
        +#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
        +#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
        +  LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
        +#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
        +#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
        +#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
        +#define lh_SSL_SESSION_node_stats_bio(lh,out) \
        +  LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
        +#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
        +  LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
        +#define lh_SSL_SESSION_stats_bio(lh,out) \
        +  LHM_lh_stats_bio(SSL_SESSION,lh,out)
        +#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
        +/* End of util/mkstack.pl block, you may now edit :-) */
        +
        +#endif /* !defined HEADER_SAFESTACK_H */
        diff --git a/vendor/openssl/openssl/crypto/stack/stack.c b/vendor/openssl/openssl/crypto/stack/stack.c
        new file mode 100644
        index 000000000..76cf1a116
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/stack/stack.c
        @@ -0,0 +1,334 @@
        +/* crypto/stack/stack.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* Code for stacks
        + * Author - Eric Young v 1.0
        + * 1.2 eay 12-Mar-97 -	Modified sk_find so that it _DOES_ return the
        + *			lowest index for the searched item.
        + *
        + * 1.1 eay - Take from netdb and added to SSLeay
        + *
        + * 1.0 eay - First version 29/07/92
        + */
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/stack.h>
        +#include <openssl/objects.h>
        +
        +#undef MIN_NODES
        +#define MIN_NODES	4
        +
        +const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT;
        +
        +#include <errno.h>
        +
        +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
        +		(const void *, const void *)
        +	{
        +	int (*old)(const void *,const void *)=sk->comp;
        +
        +	if (sk->comp != c)
        +		sk->sorted=0;
        +	sk->comp=c;
        +
        +	return old;
        +	}
        +
        +_STACK *sk_dup(_STACK *sk)
        +	{
        +	_STACK *ret;
        +	char **s;
        +
        +	if ((ret=sk_new(sk->comp)) == NULL) goto err;
        +	s=(char **)OPENSSL_realloc((char *)ret->data,
        +		(unsigned int)sizeof(char *)*sk->num_alloc);
        +	if (s == NULL) goto err;
        +	ret->data=s;
        +
        +	ret->num=sk->num;
        +	memcpy(ret->data,sk->data,sizeof(char *)*sk->num);
        +	ret->sorted=sk->sorted;
        +	ret->num_alloc=sk->num_alloc;
        +	ret->comp=sk->comp;
        +	return(ret);
        +err:
        +	if(ret)
        +		sk_free(ret);
        +	return(NULL);
        +	}
        +
        +_STACK *sk_new_null(void)
        +	{
        +	return sk_new((int (*)(const void *, const void *))0);
        +	}
        +
        +_STACK *sk_new(int (*c)(const void *, const void *))
        +	{
        +	_STACK *ret;
        +	int i;
        +
        +	if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL)
        +		goto err;
        +	if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL)
        +		goto err;
        +	for (i=0; i<MIN_NODES; i++)
        +		ret->data[i]=NULL;
        +	ret->comp=c;
        +	ret->num_alloc=MIN_NODES;
        +	ret->num=0;
        +	ret->sorted=0;
        +	return(ret);
        +err:
        +	if(ret)
        +		OPENSSL_free(ret);
        +	return(NULL);
        +	}
        +
        +int sk_insert(_STACK *st, void *data, int loc)
        +	{
        +	char **s;
        +
        +	if(st == NULL) return 0;
        +	if (st->num_alloc <= st->num+1)
        +		{
        +		s=OPENSSL_realloc((char *)st->data,
        +			(unsigned int)sizeof(char *)*st->num_alloc*2);
        +		if (s == NULL)
        +			return(0);
        +		st->data=s;
        +		st->num_alloc*=2;
        +		}
        +	if ((loc >= (int)st->num) || (loc < 0))
        +		st->data[st->num]=data;
        +	else
        +		{
        +		int i;
        +		char **f,**t;
        +
        +		f=st->data;
        +		t=&(st->data[1]);
        +		for (i=st->num; i>=loc; i--)
        +			t[i]=f[i];
        +			
        +#ifdef undef /* no memmove on sunos :-( */
        +		memmove(&(st->data[loc+1]),
        +			&(st->data[loc]),
        +			sizeof(char *)*(st->num-loc));
        +#endif
        +		st->data[loc]=data;
        +		}
        +	st->num++;
        +	st->sorted=0;
        +	return(st->num);
        +	}
        +
        +void *sk_delete_ptr(_STACK *st, void *p)
        +	{
        +	int i;
        +
        +	for (i=0; i<st->num; i++)
        +		if (st->data[i] == p)
        +			return(sk_delete(st,i));
        +	return(NULL);
        +	}
        +
        +void *sk_delete(_STACK *st, int loc)
        +	{
        +	char *ret;
        +	int i,j;
        +
        +	if(!st || (loc < 0) || (loc >= st->num)) return NULL;
        +
        +	ret=st->data[loc];
        +	if (loc != st->num-1)
        +		{
        +		j=st->num-1;
        +		for (i=loc; i<j; i++)
        +			st->data[i]=st->data[i+1];
        +		/* In theory memcpy is not safe for this
        +		 * memcpy( &(st->data[loc]),
        +		 *	&(st->data[loc+1]),
        +		 *	sizeof(char *)*(st->num-loc-1));
        +		 */
        +		}
        +	st->num--;
        +	return(ret);
        +	}
        +
        +static int internal_find(_STACK *st, void *data, int ret_val_options)
        +	{
        +	const void * const *r;
        +	int i;
        +
        +	if(st == NULL) return -1;
        +
        +	if (st->comp == NULL)
        +		{
        +		for (i=0; i<st->num; i++)
        +			if (st->data[i] == data)
        +				return(i);
        +		return(-1);
        +		}
        +	sk_sort(st);
        +	if (data == NULL) return(-1);
        +	r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp,
        +			  ret_val_options);
        +	if (r == NULL) return(-1);
        +	return (int)((char **)r-st->data);
        +	}
        +
        +int sk_find(_STACK *st, void *data)
        +	{
        +	return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
        +	}
        +int sk_find_ex(_STACK *st, void *data)
        +	{
        +	return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
        +	}
        +
        +int sk_push(_STACK *st, void *data)
        +	{
        +	return(sk_insert(st,data,st->num));
        +	}
        +
        +int sk_unshift(_STACK *st, void *data)
        +	{
        +	return(sk_insert(st,data,0));
        +	}
        +
        +void *sk_shift(_STACK *st)
        +	{
        +	if (st == NULL) return(NULL);
        +	if (st->num <= 0) return(NULL);
        +	return(sk_delete(st,0));
        +	}
        +
        +void *sk_pop(_STACK *st)
        +	{
        +	if (st == NULL) return(NULL);
        +	if (st->num <= 0) return(NULL);
        +	return(sk_delete(st,st->num-1));
        +	}
        +
        +void sk_zero(_STACK *st)
        +	{
        +	if (st == NULL) return;
        +	if (st->num <= 0) return;
        +	memset((char *)st->data,0,sizeof(st->data)*st->num);
        +	st->num=0;
        +	}
        +
        +void sk_pop_free(_STACK *st, void (*func)(void *))
        +	{
        +	int i;
        +
        +	if (st == NULL) return;
        +	for (i=0; i<st->num; i++)
        +		if (st->data[i] != NULL)
        +			func(st->data[i]);
        +	sk_free(st);
        +	}
        +
        +void sk_free(_STACK *st)
        +	{
        +	if (st == NULL) return;
        +	if (st->data != NULL) OPENSSL_free(st->data);
        +	OPENSSL_free(st);
        +	}
        +
        +int sk_num(const _STACK *st)
        +{
        +	if(st == NULL) return -1;
        +	return st->num;
        +}
        +
        +void *sk_value(const _STACK *st, int i)
        +{
        +	if(!st || (i < 0) || (i >= st->num)) return NULL;
        +	return st->data[i];
        +}
        +
        +void *sk_set(_STACK *st, int i, void *value)
        +{
        +	if(!st || (i < 0) || (i >= st->num)) return NULL;
        +	return (st->data[i] = value);
        +}
        +
        +void sk_sort(_STACK *st)
        +	{
        +	if (st && !st->sorted)
        +		{
        +		int (*comp_func)(const void *,const void *);
        +
        +		/* same comment as in sk_find ... previously st->comp was declared
        +		 * as a (void*,void*) callback type, but this made the population
        +		 * of the callback pointer illogical - our callbacks compare
        +		 * type** with type**, so we leave the casting until absolutely
        +		 * necessary (ie. "now"). */
        +		comp_func=(int (*)(const void *,const void *))(st->comp);
        +		qsort(st->data,st->num,sizeof(char *), comp_func);
        +		st->sorted=1;
        +		}
        +	}
        +
        +int sk_is_sorted(const _STACK *st)
        +	{
        +	if (!st)
        +		return 1;
        +	return st->sorted;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/stack/stack.h b/vendor/openssl/openssl/crypto/stack/stack.h
        new file mode 100644
        index 000000000..ce35e554e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/stack/stack.h
        @@ -0,0 +1,108 @@
        +/* crypto/stack/stack.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_STACK_H
        +#define HEADER_STACK_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef struct stack_st
        +	{
        +	int num;
        +	char **data;
        +	int sorted;
        +
        +	int num_alloc;
        +	int (*comp)(const void *, const void *);
        +	} _STACK;  /* Use STACK_OF(...) instead */
        +
        +#define M_sk_num(sk)		((sk) ? (sk)->num:-1)
        +#define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
        +
        +int sk_num(const _STACK *);
        +void *sk_value(const _STACK *, int);
        +
        +void *sk_set(_STACK *, int, void *);
        +
        +_STACK *sk_new(int (*cmp)(const void *, const void *));
        +_STACK *sk_new_null(void);
        +void sk_free(_STACK *);
        +void sk_pop_free(_STACK *st, void (*func)(void *));
        +int sk_insert(_STACK *sk, void *data, int where);
        +void *sk_delete(_STACK *st, int loc);
        +void *sk_delete_ptr(_STACK *st, void *p);
        +int sk_find(_STACK *st, void *data);
        +int sk_find_ex(_STACK *st, void *data);
        +int sk_push(_STACK *st, void *data);
        +int sk_unshift(_STACK *st, void *data);
        +void *sk_shift(_STACK *st);
        +void *sk_pop(_STACK *st);
        +void sk_zero(_STACK *st);
        +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
        +	(const void *, const void *);
        +_STACK *sk_dup(_STACK *st);
        +void sk_sort(_STACK *st);
        +int sk_is_sorted(const _STACK *st);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/store/Makefile b/vendor/openssl/openssl/crypto/store/Makefile
        new file mode 100644
        index 000000000..0dcfd7857
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/Makefile
        @@ -0,0 +1,112 @@
        +#
        +# OpenSSL/crypto/store/Makefile
        +#
        +
        +DIR=	store
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +#TEST= storetest.c
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= str_err.c str_lib.c str_meth.c str_mem.c
        +LIBOBJ= str_err.o str_lib.o str_meth.o str_mem.o
        +
        +SRC= $(LIBSRC)
        +
        +#EXHEADER= store.h str_compat.h
        +EXHEADER= store.h
        +HEADER=	$(EXHEADER) str_locl.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +str_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +str_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +str_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +str_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +str_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +str_err.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
        +str_err.o: str_err.c
        +str_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +str_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +str_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +str_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +str_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +str_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +str_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +str_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +str_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +str_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +str_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +str_lib.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
        +str_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +str_lib.o: str_lib.c str_locl.h
        +str_mem.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +str_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +str_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +str_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +str_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +str_mem.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
        +str_mem.o: str_locl.h str_mem.c
        +str_meth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +str_meth.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +str_meth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +str_meth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +str_meth.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
        +str_meth.o: str_locl.h str_meth.c
        diff --git a/vendor/openssl/openssl/crypto/store/README b/vendor/openssl/openssl/crypto/store/README
        new file mode 100644
        index 000000000..966168f6a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/README
        @@ -0,0 +1,95 @@
        +The STORE type
        +==============
        +
        +A STORE, as defined in this code section, is really a rather simple
        +thing which stores objects and per-object associations to a number
        +of attributes.  What attributes are supported entirely depends on
        +the particular implementation of a STORE.  It has some support for
        +generation of certain objects (for example, keys and CRLs).
        +
        +
        +Supported object types
        +----------------------
        +
        +For now, the objects that are supported are the following:
        +
        +X.509 certificate
        +X.509 CRL
        +private key
        +public key
        +number
        +arbitrary (application) data
        +
        +The intention is that a STORE should be able to store everything
        +needed by an application that wants a cert/key store, as well as
        +the data a CA might need to store (this includes the serial number
        +counter, which explains the support for numbers).
        +
        +
        +Supported attribute types
        +-------------------------
        +
        +For now, the following attributes are supported:
        +
        +Friendly Name		- the value is a normal C string
        +Key ID			- the value is a 160 bit SHA1 hash
        +Issuer Key ID		- the value is a 160 bit SHA1 hash
        +Subject Key ID		- the value is a 160 bit SHA1 hash
        +Issuer/Serial Hash	- the value is a 160 bit SHA1 hash
        +Issuer			- the value is a X509_NAME
        +Serial			- the value is a BIGNUM
        +Subject			- the value is a X509_NAME
        +Certificate Hash	- the value is a 160 bit SHA1 hash
        +Email			- the value is a normal C string
        +Filename		- the value is a normal C string
        +
        +It is expected that these attributes should be enough to support
        +the need from most, if not all, current applications.  Applications
        +that need to do certificate verification would typically use Subject
        +Key ID, Issuer/Serial Hash or Subject to look up issuer certificates.
        +S/MIME applications would typically use Email to look up recipient
        +and signer certificates.
        +
        +There's added support for combined sets of attributes to search for,
        +with the special OR attribute.
        +
        +
        +Supported basic functionality
        +-----------------------------
        +
        +The functions that are supported through the STORE type are these:
        +
        +generate_object		- for example to generate keys and CRLs
        +get_object		- to look up one object
        +			  NOTE: this function is really rather
        +			  redundant and probably of lesser usage
        +			  than the list functions
        +store_object		- store an object and the attributes
        +			  associated with it
        +modify_object		- modify the attributes associated with
        +			  a specific object
        +revoke_object		- revoke an object
        +			  NOTE: this only marks an object as
        +			  invalid, it doesn't remove the object
        +			  from the database
        +delete_object		- remove an object from the database
        +list_object		- list objects associated with a given
        +			  set of attributes
        +			  NOTE: this is really four functions:
        +			  list_start, list_next, list_end and
        +			  list_endp
        +update_store		- update the internal data of the store
        +lock_store		- lock the store
        +unlock_store		- unlock the store
        +
        +The list functions need some extra explanation: list_start is
        +used to set up a lookup.  That's where the attributes to use in
        +the search are set up.  It returns a search context.  list_next
        +returns the next object searched for.  list_end closes the search.
        +list_endp is used to check if we have reached the end.
        +
        +A few words on the store functions as well: update_store is
        +typically used by a CA application to update the internal
        +structure of a database.  This may for example involve automatic
        +removal of expired certificates.  lock_store and unlock_store
        +are used for locking a store to allow exclusive writes.
        diff --git a/vendor/openssl/openssl/crypto/store/store.h b/vendor/openssl/openssl/crypto/store/store.h
        new file mode 100644
        index 000000000..0a28c7d5a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/store.h
        @@ -0,0 +1,561 @@
        +/* crypto/store/store.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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_STORE_H
        +#define HEADER_STORE_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifdef OPENSSL_NO_STORE
        +#error STORE is disabled.
        +#endif
        +
        +#include <openssl/ossl_typ.h>
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/x509.h>
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Already defined in ossl_typ.h */
        +/* typedef struct store_st STORE; */
        +/* typedef struct store_method_st STORE_METHOD; */
        +
        +
        +/* All the following functions return 0, a negative number or NULL on error.
        +   When everything is fine, they return a positive value or a non-NULL
        +   pointer, all depending on their purpose. */
        +
        +/* Creators and destructor.   */
        +STORE *STORE_new_method(const STORE_METHOD *method);
        +STORE *STORE_new_engine(ENGINE *engine);
        +void STORE_free(STORE *ui);
        +
        +
        +/* Give a user interface parametrised control commands.  This can be used to
        +   send down an integer, a data pointer or a function pointer, as well as
        +   be used to get information from a STORE. */
        +int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void));
        +
        +/* A control to set the directory with keys and certificates.  Used by the
        +   built-in directory level method. */
        +#define STORE_CTRL_SET_DIRECTORY	0x0001
        +/* A control to set a file to load.  Used by the built-in file level method. */
        +#define STORE_CTRL_SET_FILE		0x0002
        +/* A control to set a configuration file to load.  Can be used by any method
        +   that wishes to load a configuration file. */
        +#define STORE_CTRL_SET_CONF_FILE	0x0003
        +/* A control to set a the section of the loaded configuration file.  Can be
        +   used by any method that wishes to load a configuration file. */
        +#define STORE_CTRL_SET_CONF_SECTION	0x0004
        +
        +
        +/* Some methods may use extra data */
        +#define STORE_set_app_data(s,arg)	STORE_set_ex_data(s,0,arg)
        +#define STORE_get_app_data(s)		STORE_get_ex_data(s,0)
        +int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int STORE_set_ex_data(STORE *r,int idx,void *arg);
        +void *STORE_get_ex_data(STORE *r, int idx);
        +
        +/* Use specific methods instead of the built-in one */
        +const STORE_METHOD *STORE_get_method(STORE *store);
        +const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth);
        +
        +/* The standard OpenSSL methods. */
        +/* This is the in-memory method.  It does everything except revoking and updating,
        +   and is of course volatile.  It's used by other methods that have an in-memory
        +   cache. */
        +const STORE_METHOD *STORE_Memory(void);
        +#if 0 /* Not yet implemented */
        +/* This is the directory store.  It does everything except revoking and updating,
        +   and uses STORE_Memory() to cache things in memory. */
        +const STORE_METHOD *STORE_Directory(void);
        +/* This is the file store.  It does everything except revoking and updating,
        +   and uses STORE_Memory() to cache things in memory.  Certificates are added
        +   to it with the store operation, and it will only get cached certificates. */
        +const STORE_METHOD *STORE_File(void);
        +#endif
        +
        +/* Store functions take a type code for the type of data they should store
        +   or fetch */
        +typedef enum STORE_object_types
        +	{
        +	STORE_OBJECT_TYPE_X509_CERTIFICATE=	0x01, /* X509 * */
        +	STORE_OBJECT_TYPE_X509_CRL=		0x02, /* X509_CRL * */
        +	STORE_OBJECT_TYPE_PRIVATE_KEY=		0x03, /* EVP_PKEY * */
        +	STORE_OBJECT_TYPE_PUBLIC_KEY=		0x04, /* EVP_PKEY * */
        +	STORE_OBJECT_TYPE_NUMBER=		0x05, /* BIGNUM * */
        +	STORE_OBJECT_TYPE_ARBITRARY=		0x06, /* BUF_MEM * */
        +	STORE_OBJECT_TYPE_NUM=			0x06  /* The amount of known
        +							 object types */
        +	} STORE_OBJECT_TYPES;
        +/* List of text strings corresponding to the object types. */
        +extern const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1];
        +
        +/* Some store functions take a parameter list.  Those parameters come with
        +   one of the following codes. The comments following the codes below indicate
        +   what type the value should be a pointer to. */
        +typedef enum STORE_params
        +	{
        +	STORE_PARAM_EVP_TYPE=			0x01, /* int */
        +	STORE_PARAM_BITS=			0x02, /* size_t */
        +	STORE_PARAM_KEY_PARAMETERS=		0x03, /* ??? */
        +	STORE_PARAM_KEY_NO_PARAMETERS=		0x04, /* N/A */
        +	STORE_PARAM_AUTH_PASSPHRASE=		0x05, /* char * */
        +	STORE_PARAM_AUTH_KRB5_TICKET=		0x06, /* void * */
        +	STORE_PARAM_TYPE_NUM=			0x06  /* The amount of known
        +							 parameter types */
        +	} STORE_PARAM_TYPES;
        +/* Parameter value sizes.  -1 means unknown, anything else is the required size. */
        +extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1];
        +
        +/* Store functions take attribute lists.  Those attributes come with codes.
        +   The comments following the codes below indicate what type the value should
        +   be a pointer to. */
        +typedef enum STORE_attribs
        +	{
        +	STORE_ATTR_END=				0x00,
        +	STORE_ATTR_FRIENDLYNAME=		0x01, /* C string */
        +	STORE_ATTR_KEYID=			0x02, /* 160 bit string (SHA1) */
        +	STORE_ATTR_ISSUERKEYID=			0x03, /* 160 bit string (SHA1) */
        +	STORE_ATTR_SUBJECTKEYID=		0x04, /* 160 bit string (SHA1) */
        +	STORE_ATTR_ISSUERSERIALHASH=		0x05, /* 160 bit string (SHA1) */
        +	STORE_ATTR_ISSUER=			0x06, /* X509_NAME * */
        +	STORE_ATTR_SERIAL=			0x07, /* BIGNUM * */
        +	STORE_ATTR_SUBJECT=			0x08, /* X509_NAME * */
        +	STORE_ATTR_CERTHASH=			0x09, /* 160 bit string (SHA1) */
        +	STORE_ATTR_EMAIL=			0x0a, /* C string */
        +	STORE_ATTR_FILENAME=			0x0b, /* C string */
        +	STORE_ATTR_TYPE_NUM=			0x0b, /* The amount of known
        +							 attribute types */
        +	STORE_ATTR_OR=				0xff  /* This is a special
        +							 separator, which
        +							 expresses the OR
        +							 operation.  */
        +	} STORE_ATTR_TYPES;
        +/* Attribute value sizes.  -1 means unknown, anything else is the required size. */
        +extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1];
        +
        +typedef enum STORE_certificate_status
        +	{
        +	STORE_X509_VALID=			0x00,
        +	STORE_X509_EXPIRED=			0x01,
        +	STORE_X509_SUSPENDED=			0x02,
        +	STORE_X509_REVOKED=			0x03
        +	} STORE_CERTIFICATE_STATUS;
        +
        +/* Engine store functions will return a structure that contains all the necessary
        + * information, including revokation status for certificates.  This is really not
        + * needed for application authors, as the ENGINE framework functions will extract
        + * the OpenSSL-specific information when at all possible.  However, for engine
        + * authors, it's crucial to know this structure.  */
        +typedef struct STORE_OBJECT_st
        +	{
        +	STORE_OBJECT_TYPES type;
        +	union
        +		{
        +		struct
        +			{
        +			STORE_CERTIFICATE_STATUS status;
        +			X509 *certificate;
        +			} x509;
        +		X509_CRL *crl;
        +		EVP_PKEY *key;
        +		BIGNUM *number;
        +		BUF_MEM *arbitrary;
        +		} data;
        +	} STORE_OBJECT;
        +DECLARE_STACK_OF(STORE_OBJECT)
        +STORE_OBJECT *STORE_OBJECT_new(void);
        +void STORE_OBJECT_free(STORE_OBJECT *data);
        +
        +
        +
        +/* The following functions handle the storage. They return 0, a negative number
        +   or NULL on error, anything else on success. */
        +X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +X509 *STORE_list_certificate_next(STORE *e, void *handle);
        +int STORE_list_certificate_end(STORE *e, void *handle);
        +int STORE_list_certificate_endp(STORE *e, void *handle);
        +EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_store_private_key(STORE *e, EVP_PKEY *data,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle);
        +int STORE_list_private_key_end(STORE *e, void *handle);
        +int STORE_list_private_key_endp(STORE *e, void *handle);
        +EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_store_public_key(STORE *e, EVP_PKEY *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle);
        +int STORE_list_public_key_end(STORE *e, void *handle);
        +int STORE_list_public_key_endp(STORE *e, void *handle);
        +X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +X509_CRL *STORE_list_crl_next(STORE *e, void *handle);
        +int STORE_list_crl_end(STORE *e, void *handle);
        +int STORE_list_crl_endp(STORE *e, void *handle);
        +int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +
        +
        +/* Create and manipulate methods */
        +STORE_METHOD *STORE_create_method(char *name);
        +void STORE_destroy_method(STORE_METHOD *store_method);
        +
        +/* These callback types are use for store handlers */
        +typedef int (*STORE_INITIALISE_FUNC_PTR)(STORE *);
        +typedef void (*STORE_CLEANUP_FUNC_PTR)(STORE *);
        +typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle);
        +typedef int (*STORE_END_OBJECT_FUNC_PTR)(STORE *, void *handle);
        +typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +typedef int (*STORE_STORE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, STORE_OBJECT *data, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
        +typedef int (*STORE_GENERIC_FUNC_PTR)(STORE *, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +typedef int (*STORE_CTRL_FUNC_PTR)(STORE *, int cmd, long l, void *p, void (*f)(void));
        +
        +int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f);
        +int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f);
        +int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f);
        +int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f);
        +int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f);
        +int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR store_f);
        +int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f);
        +int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f);
        +int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f);
        +int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f);
        +int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f);
        +int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
        +int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
        +int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
        +int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f);
        +
        +STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm);
        +STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm);
        +STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm);
        +STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm);
        +STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm);
        +STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm);
        +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm);
        +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm);
        +STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm);
        +STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm);
        +STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm);
        +STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm);
        +STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm);
        +STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm);
        +STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm);
        +
        +/* Method helper structures and functions. */
        +
        +/* This structure is the result of parsing through the information in a list
        +   of OPENSSL_ITEMs.  It stores all the necessary information in a structured
        +   way.*/
        +typedef struct STORE_attr_info_st STORE_ATTR_INFO;
        +
        +/* Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO.
        +   Note that we do this in the list form, since the list of OPENSSL_ITEMs can
        +   come in blocks separated with STORE_ATTR_OR.  Note that the value returned
        +   by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). */
        +void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes);
        +STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle);
        +int STORE_parse_attrs_end(void *handle);
        +int STORE_parse_attrs_endp(void *handle);
        +
        +/* Creator and destructor */
        +STORE_ATTR_INFO *STORE_ATTR_INFO_new(void);
        +int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs);
        +
        +/* Manipulators */
        +char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
        +unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
        +	STORE_ATTR_TYPES code);
        +X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
        +BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
        +int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	char *cstr, size_t cstr_size);
        +int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	unsigned char *sha1str, size_t sha1str_size);
        +int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	X509_NAME *dn);
        +int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	BIGNUM *number);
        +int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	char *cstr, size_t cstr_size);
        +int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	unsigned char *sha1str, size_t sha1str_size);
        +int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	X509_NAME *dn);
        +int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	BIGNUM *number);
        +
        +/* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
        +   in each contained attribute. */
        +int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
        +			    const STORE_ATTR_INFO * const *b);
        +/* Check if the set of attributes in a is within the range of attributes
        +   set in b. */
        +int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
        +/* Check if the set of attributes in a are also set in b. */
        +int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
        +/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */
        +int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_STORE_strings(void);
        +
        +/* Error codes for the STORE functions. */
        +
        +/* Function codes. */
        +#define STORE_F_MEM_DELETE				 134
        +#define STORE_F_MEM_GENERATE				 135
        +#define STORE_F_MEM_LIST_END				 168
        +#define STORE_F_MEM_LIST_NEXT				 136
        +#define STORE_F_MEM_LIST_START				 137
        +#define STORE_F_MEM_MODIFY				 169
        +#define STORE_F_MEM_STORE				 138
        +#define STORE_F_STORE_ATTR_INFO_GET0_CSTR		 139
        +#define STORE_F_STORE_ATTR_INFO_GET0_DN			 140
        +#define STORE_F_STORE_ATTR_INFO_GET0_NUMBER		 141
        +#define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR		 142
        +#define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR		 143
        +#define STORE_F_STORE_ATTR_INFO_MODIFY_DN		 144
        +#define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER		 145
        +#define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR		 146
        +#define STORE_F_STORE_ATTR_INFO_SET_CSTR		 147
        +#define STORE_F_STORE_ATTR_INFO_SET_DN			 148
        +#define STORE_F_STORE_ATTR_INFO_SET_NUMBER		 149
        +#define STORE_F_STORE_ATTR_INFO_SET_SHA1STR		 150
        +#define STORE_F_STORE_CERTIFICATE			 170
        +#define STORE_F_STORE_CTRL				 161
        +#define STORE_F_STORE_DELETE_ARBITRARY			 158
        +#define STORE_F_STORE_DELETE_CERTIFICATE		 102
        +#define STORE_F_STORE_DELETE_CRL			 103
        +#define STORE_F_STORE_DELETE_NUMBER			 104
        +#define STORE_F_STORE_DELETE_PRIVATE_KEY		 105
        +#define STORE_F_STORE_DELETE_PUBLIC_KEY			 106
        +#define STORE_F_STORE_GENERATE_CRL			 107
        +#define STORE_F_STORE_GENERATE_KEY			 108
        +#define STORE_F_STORE_GET_ARBITRARY			 159
        +#define STORE_F_STORE_GET_CERTIFICATE			 109
        +#define STORE_F_STORE_GET_CRL				 110
        +#define STORE_F_STORE_GET_NUMBER			 111
        +#define STORE_F_STORE_GET_PRIVATE_KEY			 112
        +#define STORE_F_STORE_GET_PUBLIC_KEY			 113
        +#define STORE_F_STORE_LIST_CERTIFICATE_END		 114
        +#define STORE_F_STORE_LIST_CERTIFICATE_ENDP		 153
        +#define STORE_F_STORE_LIST_CERTIFICATE_NEXT		 115
        +#define STORE_F_STORE_LIST_CERTIFICATE_START		 116
        +#define STORE_F_STORE_LIST_CRL_END			 117
        +#define STORE_F_STORE_LIST_CRL_ENDP			 154
        +#define STORE_F_STORE_LIST_CRL_NEXT			 118
        +#define STORE_F_STORE_LIST_CRL_START			 119
        +#define STORE_F_STORE_LIST_PRIVATE_KEY_END		 120
        +#define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP		 155
        +#define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT		 121
        +#define STORE_F_STORE_LIST_PRIVATE_KEY_START		 122
        +#define STORE_F_STORE_LIST_PUBLIC_KEY_END		 123
        +#define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP		 156
        +#define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT		 124
        +#define STORE_F_STORE_LIST_PUBLIC_KEY_START		 125
        +#define STORE_F_STORE_MODIFY_ARBITRARY			 162
        +#define STORE_F_STORE_MODIFY_CERTIFICATE		 163
        +#define STORE_F_STORE_MODIFY_CRL			 164
        +#define STORE_F_STORE_MODIFY_NUMBER			 165
        +#define STORE_F_STORE_MODIFY_PRIVATE_KEY		 166
        +#define STORE_F_STORE_MODIFY_PUBLIC_KEY			 167
        +#define STORE_F_STORE_NEW_ENGINE			 133
        +#define STORE_F_STORE_NEW_METHOD			 132
        +#define STORE_F_STORE_PARSE_ATTRS_END			 151
        +#define STORE_F_STORE_PARSE_ATTRS_ENDP			 172
        +#define STORE_F_STORE_PARSE_ATTRS_NEXT			 152
        +#define STORE_F_STORE_PARSE_ATTRS_START			 171
        +#define STORE_F_STORE_REVOKE_CERTIFICATE		 129
        +#define STORE_F_STORE_REVOKE_PRIVATE_KEY		 130
        +#define STORE_F_STORE_REVOKE_PUBLIC_KEY			 131
        +#define STORE_F_STORE_STORE_ARBITRARY			 157
        +#define STORE_F_STORE_STORE_CERTIFICATE			 100
        +#define STORE_F_STORE_STORE_CRL				 101
        +#define STORE_F_STORE_STORE_NUMBER			 126
        +#define STORE_F_STORE_STORE_PRIVATE_KEY			 127
        +#define STORE_F_STORE_STORE_PUBLIC_KEY			 128
        +
        +/* Reason codes. */
        +#define STORE_R_ALREADY_HAS_A_VALUE			 127
        +#define STORE_R_FAILED_DELETING_ARBITRARY		 132
        +#define STORE_R_FAILED_DELETING_CERTIFICATE		 100
        +#define STORE_R_FAILED_DELETING_KEY			 101
        +#define STORE_R_FAILED_DELETING_NUMBER			 102
        +#define STORE_R_FAILED_GENERATING_CRL			 103
        +#define STORE_R_FAILED_GENERATING_KEY			 104
        +#define STORE_R_FAILED_GETTING_ARBITRARY		 133
        +#define STORE_R_FAILED_GETTING_CERTIFICATE		 105
        +#define STORE_R_FAILED_GETTING_KEY			 106
        +#define STORE_R_FAILED_GETTING_NUMBER			 107
        +#define STORE_R_FAILED_LISTING_CERTIFICATES		 108
        +#define STORE_R_FAILED_LISTING_KEYS			 109
        +#define STORE_R_FAILED_MODIFYING_ARBITRARY		 138
        +#define STORE_R_FAILED_MODIFYING_CERTIFICATE		 139
        +#define STORE_R_FAILED_MODIFYING_CRL			 140
        +#define STORE_R_FAILED_MODIFYING_NUMBER			 141
        +#define STORE_R_FAILED_MODIFYING_PRIVATE_KEY		 142
        +#define STORE_R_FAILED_MODIFYING_PUBLIC_KEY		 143
        +#define STORE_R_FAILED_REVOKING_CERTIFICATE		 110
        +#define STORE_R_FAILED_REVOKING_KEY			 111
        +#define STORE_R_FAILED_STORING_ARBITRARY		 134
        +#define STORE_R_FAILED_STORING_CERTIFICATE		 112
        +#define STORE_R_FAILED_STORING_KEY			 113
        +#define STORE_R_FAILED_STORING_NUMBER			 114
        +#define STORE_R_NOT_IMPLEMENTED				 128
        +#define STORE_R_NO_CONTROL_FUNCTION			 144
        +#define STORE_R_NO_DELETE_ARBITRARY_FUNCTION		 135
        +#define STORE_R_NO_DELETE_NUMBER_FUNCTION		 115
        +#define STORE_R_NO_DELETE_OBJECT_FUNCTION		 116
        +#define STORE_R_NO_GENERATE_CRL_FUNCTION		 117
        +#define STORE_R_NO_GENERATE_OBJECT_FUNCTION		 118
        +#define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION	 136
        +#define STORE_R_NO_GET_OBJECT_FUNCTION			 119
        +#define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION		 120
        +#define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION		 131
        +#define STORE_R_NO_LIST_OBJECT_END_FUNCTION		 121
        +#define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION		 122
        +#define STORE_R_NO_LIST_OBJECT_START_FUNCTION		 123
        +#define STORE_R_NO_MODIFY_OBJECT_FUNCTION		 145
        +#define STORE_R_NO_REVOKE_OBJECT_FUNCTION		 124
        +#define STORE_R_NO_STORE				 129
        +#define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION	 137
        +#define STORE_R_NO_STORE_OBJECT_FUNCTION		 125
        +#define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION		 126
        +#define STORE_R_NO_VALUE				 130
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/store/str_err.c b/vendor/openssl/openssl/crypto/store/str_err.c
        new file mode 100644
        index 000000000..924edf050
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/str_err.c
        @@ -0,0 +1,211 @@
        +/* crypto/store/str_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/store.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_STORE,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_STORE,0,reason)
        +
        +static ERR_STRING_DATA STORE_str_functs[]=
        +	{
        +{ERR_FUNC(STORE_F_MEM_DELETE),	"MEM_DELETE"},
        +{ERR_FUNC(STORE_F_MEM_GENERATE),	"MEM_GENERATE"},
        +{ERR_FUNC(STORE_F_MEM_LIST_END),	"MEM_LIST_END"},
        +{ERR_FUNC(STORE_F_MEM_LIST_NEXT),	"MEM_LIST_NEXT"},
        +{ERR_FUNC(STORE_F_MEM_LIST_START),	"MEM_LIST_START"},
        +{ERR_FUNC(STORE_F_MEM_MODIFY),	"MEM_MODIFY"},
        +{ERR_FUNC(STORE_F_MEM_STORE),	"MEM_STORE"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_CSTR),	"STORE_ATTR_INFO_get0_cstr"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_DN),	"STORE_ATTR_INFO_get0_dn"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_NUMBER),	"STORE_ATTR_INFO_get0_number"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR),	"STORE_ATTR_INFO_get0_sha1str"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR),	"STORE_ATTR_INFO_modify_cstr"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_DN),	"STORE_ATTR_INFO_modify_dn"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER),	"STORE_ATTR_INFO_modify_number"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR),	"STORE_ATTR_INFO_modify_sha1str"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_CSTR),	"STORE_ATTR_INFO_set_cstr"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_DN),	"STORE_ATTR_INFO_set_dn"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_NUMBER),	"STORE_ATTR_INFO_set_number"},
        +{ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_SHA1STR),	"STORE_ATTR_INFO_set_sha1str"},
        +{ERR_FUNC(STORE_F_STORE_CERTIFICATE),	"STORE_CERTIFICATE"},
        +{ERR_FUNC(STORE_F_STORE_CTRL),	"STORE_ctrl"},
        +{ERR_FUNC(STORE_F_STORE_DELETE_ARBITRARY),	"STORE_delete_arbitrary"},
        +{ERR_FUNC(STORE_F_STORE_DELETE_CERTIFICATE),	"STORE_delete_certificate"},
        +{ERR_FUNC(STORE_F_STORE_DELETE_CRL),	"STORE_delete_crl"},
        +{ERR_FUNC(STORE_F_STORE_DELETE_NUMBER),	"STORE_delete_number"},
        +{ERR_FUNC(STORE_F_STORE_DELETE_PRIVATE_KEY),	"STORE_delete_private_key"},
        +{ERR_FUNC(STORE_F_STORE_DELETE_PUBLIC_KEY),	"STORE_delete_public_key"},
        +{ERR_FUNC(STORE_F_STORE_GENERATE_CRL),	"STORE_generate_crl"},
        +{ERR_FUNC(STORE_F_STORE_GENERATE_KEY),	"STORE_generate_key"},
        +{ERR_FUNC(STORE_F_STORE_GET_ARBITRARY),	"STORE_get_arbitrary"},
        +{ERR_FUNC(STORE_F_STORE_GET_CERTIFICATE),	"STORE_get_certificate"},
        +{ERR_FUNC(STORE_F_STORE_GET_CRL),	"STORE_get_crl"},
        +{ERR_FUNC(STORE_F_STORE_GET_NUMBER),	"STORE_get_number"},
        +{ERR_FUNC(STORE_F_STORE_GET_PRIVATE_KEY),	"STORE_get_private_key"},
        +{ERR_FUNC(STORE_F_STORE_GET_PUBLIC_KEY),	"STORE_get_public_key"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_END),	"STORE_list_certificate_end"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_ENDP),	"STORE_list_certificate_endp"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_NEXT),	"STORE_list_certificate_next"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_START),	"STORE_list_certificate_start"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CRL_END),	"STORE_list_crl_end"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CRL_ENDP),	"STORE_list_crl_endp"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CRL_NEXT),	"STORE_list_crl_next"},
        +{ERR_FUNC(STORE_F_STORE_LIST_CRL_START),	"STORE_list_crl_start"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_END),	"STORE_list_private_key_end"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP),	"STORE_list_private_key_endp"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT),	"STORE_list_private_key_next"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_START),	"STORE_list_private_key_start"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_END),	"STORE_list_public_key_end"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP),	"STORE_list_public_key_endp"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT),	"STORE_list_public_key_next"},
        +{ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_START),	"STORE_list_public_key_start"},
        +{ERR_FUNC(STORE_F_STORE_MODIFY_ARBITRARY),	"STORE_modify_arbitrary"},
        +{ERR_FUNC(STORE_F_STORE_MODIFY_CERTIFICATE),	"STORE_modify_certificate"},
        +{ERR_FUNC(STORE_F_STORE_MODIFY_CRL),	"STORE_modify_crl"},
        +{ERR_FUNC(STORE_F_STORE_MODIFY_NUMBER),	"STORE_modify_number"},
        +{ERR_FUNC(STORE_F_STORE_MODIFY_PRIVATE_KEY),	"STORE_modify_private_key"},
        +{ERR_FUNC(STORE_F_STORE_MODIFY_PUBLIC_KEY),	"STORE_modify_public_key"},
        +{ERR_FUNC(STORE_F_STORE_NEW_ENGINE),	"STORE_new_engine"},
        +{ERR_FUNC(STORE_F_STORE_NEW_METHOD),	"STORE_new_method"},
        +{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_END),	"STORE_parse_attrs_end"},
        +{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_ENDP),	"STORE_parse_attrs_endp"},
        +{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_NEXT),	"STORE_parse_attrs_next"},
        +{ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_START),	"STORE_parse_attrs_start"},
        +{ERR_FUNC(STORE_F_STORE_REVOKE_CERTIFICATE),	"STORE_revoke_certificate"},
        +{ERR_FUNC(STORE_F_STORE_REVOKE_PRIVATE_KEY),	"STORE_revoke_private_key"},
        +{ERR_FUNC(STORE_F_STORE_REVOKE_PUBLIC_KEY),	"STORE_revoke_public_key"},
        +{ERR_FUNC(STORE_F_STORE_STORE_ARBITRARY),	"STORE_store_arbitrary"},
        +{ERR_FUNC(STORE_F_STORE_STORE_CERTIFICATE),	"STORE_store_certificate"},
        +{ERR_FUNC(STORE_F_STORE_STORE_CRL),	"STORE_store_crl"},
        +{ERR_FUNC(STORE_F_STORE_STORE_NUMBER),	"STORE_store_number"},
        +{ERR_FUNC(STORE_F_STORE_STORE_PRIVATE_KEY),	"STORE_store_private_key"},
        +{ERR_FUNC(STORE_F_STORE_STORE_PUBLIC_KEY),	"STORE_store_public_key"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA STORE_str_reasons[]=
        +	{
        +{ERR_REASON(STORE_R_ALREADY_HAS_A_VALUE) ,"already has a value"},
        +{ERR_REASON(STORE_R_FAILED_DELETING_ARBITRARY),"failed deleting arbitrary"},
        +{ERR_REASON(STORE_R_FAILED_DELETING_CERTIFICATE),"failed deleting certificate"},
        +{ERR_REASON(STORE_R_FAILED_DELETING_KEY) ,"failed deleting key"},
        +{ERR_REASON(STORE_R_FAILED_DELETING_NUMBER),"failed deleting number"},
        +{ERR_REASON(STORE_R_FAILED_GENERATING_CRL),"failed generating crl"},
        +{ERR_REASON(STORE_R_FAILED_GENERATING_KEY),"failed generating key"},
        +{ERR_REASON(STORE_R_FAILED_GETTING_ARBITRARY),"failed getting arbitrary"},
        +{ERR_REASON(STORE_R_FAILED_GETTING_CERTIFICATE),"failed getting certificate"},
        +{ERR_REASON(STORE_R_FAILED_GETTING_KEY)  ,"failed getting key"},
        +{ERR_REASON(STORE_R_FAILED_GETTING_NUMBER),"failed getting number"},
        +{ERR_REASON(STORE_R_FAILED_LISTING_CERTIFICATES),"failed listing certificates"},
        +{ERR_REASON(STORE_R_FAILED_LISTING_KEYS) ,"failed listing keys"},
        +{ERR_REASON(STORE_R_FAILED_MODIFYING_ARBITRARY),"failed modifying arbitrary"},
        +{ERR_REASON(STORE_R_FAILED_MODIFYING_CERTIFICATE),"failed modifying certificate"},
        +{ERR_REASON(STORE_R_FAILED_MODIFYING_CRL),"failed modifying crl"},
        +{ERR_REASON(STORE_R_FAILED_MODIFYING_NUMBER),"failed modifying number"},
        +{ERR_REASON(STORE_R_FAILED_MODIFYING_PRIVATE_KEY),"failed modifying private key"},
        +{ERR_REASON(STORE_R_FAILED_MODIFYING_PUBLIC_KEY),"failed modifying public key"},
        +{ERR_REASON(STORE_R_FAILED_REVOKING_CERTIFICATE),"failed revoking certificate"},
        +{ERR_REASON(STORE_R_FAILED_REVOKING_KEY) ,"failed revoking key"},
        +{ERR_REASON(STORE_R_FAILED_STORING_ARBITRARY),"failed storing arbitrary"},
        +{ERR_REASON(STORE_R_FAILED_STORING_CERTIFICATE),"failed storing certificate"},
        +{ERR_REASON(STORE_R_FAILED_STORING_KEY)  ,"failed storing key"},
        +{ERR_REASON(STORE_R_FAILED_STORING_NUMBER),"failed storing number"},
        +{ERR_REASON(STORE_R_NOT_IMPLEMENTED)     ,"not implemented"},
        +{ERR_REASON(STORE_R_NO_CONTROL_FUNCTION) ,"no control function"},
        +{ERR_REASON(STORE_R_NO_DELETE_ARBITRARY_FUNCTION),"no delete arbitrary function"},
        +{ERR_REASON(STORE_R_NO_DELETE_NUMBER_FUNCTION),"no delete number function"},
        +{ERR_REASON(STORE_R_NO_DELETE_OBJECT_FUNCTION),"no delete object function"},
        +{ERR_REASON(STORE_R_NO_GENERATE_CRL_FUNCTION),"no generate crl function"},
        +{ERR_REASON(STORE_R_NO_GENERATE_OBJECT_FUNCTION),"no generate object function"},
        +{ERR_REASON(STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION),"no get object arbitrary function"},
        +{ERR_REASON(STORE_R_NO_GET_OBJECT_FUNCTION),"no get object function"},
        +{ERR_REASON(STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION),"no get object number function"},
        +{ERR_REASON(STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION),"no list object endp function"},
        +{ERR_REASON(STORE_R_NO_LIST_OBJECT_END_FUNCTION),"no list object end function"},
        +{ERR_REASON(STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION),"no list object next function"},
        +{ERR_REASON(STORE_R_NO_LIST_OBJECT_START_FUNCTION),"no list object start function"},
        +{ERR_REASON(STORE_R_NO_MODIFY_OBJECT_FUNCTION),"no modify object function"},
        +{ERR_REASON(STORE_R_NO_REVOKE_OBJECT_FUNCTION),"no revoke object function"},
        +{ERR_REASON(STORE_R_NO_STORE)            ,"no store"},
        +{ERR_REASON(STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION),"no store object arbitrary function"},
        +{ERR_REASON(STORE_R_NO_STORE_OBJECT_FUNCTION),"no store object function"},
        +{ERR_REASON(STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION),"no store object number function"},
        +{ERR_REASON(STORE_R_NO_VALUE)            ,"no value"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_STORE_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(STORE_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,STORE_str_functs);
        +		ERR_load_strings(0,STORE_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/store/str_lib.c b/vendor/openssl/openssl/crypto/store/str_lib.c
        new file mode 100644
        index 000000000..f1dbcbd0e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/str_lib.c
        @@ -0,0 +1,1828 @@
        +/* crypto/store/str_lib.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <string.h>
        +#include <openssl/bn.h>
        +#include <openssl/err.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/sha.h>
        +#include <openssl/x509.h>
        +#include "str_locl.h"
        +
        +const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1] =
        +	{
        +	0,
        +	"X.509 Certificate",
        +	"X.509 CRL",
        +	"Private Key",
        +	"Public Key",
        +	"Number",
        +	"Arbitrary Data"
        +	};
        +
        +const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1] =
        +	{
        +	0,
        +	sizeof(int),		/* EVP_TYPE */
        +	sizeof(size_t),		/* BITS */
        +	-1,			/* KEY_PARAMETERS */
        +	0			/* KEY_NO_PARAMETERS */
        +	};	
        +
        +const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1] =
        +	{
        +	0,
        +	-1,			/* FRIENDLYNAME:	C string */
        +	SHA_DIGEST_LENGTH,	/* KEYID:		SHA1 digest, 160 bits */
        +	SHA_DIGEST_LENGTH,	/* ISSUERKEYID:		SHA1 digest, 160 bits */
        +	SHA_DIGEST_LENGTH,	/* SUBJECTKEYID:	SHA1 digest, 160 bits */
        +	SHA_DIGEST_LENGTH,	/* ISSUERSERIALHASH:	SHA1 digest, 160 bits */
        +	sizeof(X509_NAME *),	/* ISSUER:		X509_NAME * */
        +	sizeof(BIGNUM *),	/* SERIAL:		BIGNUM * */
        +	sizeof(X509_NAME *),	/* SUBJECT:		X509_NAME * */
        +	SHA_DIGEST_LENGTH,	/* CERTHASH:		SHA1 digest, 160 bits */
        +	-1,			/* EMAIL:		C string */
        +	-1,			/* FILENAME:		C string */
        +	};	
        +
        +STORE *STORE_new_method(const STORE_METHOD *method)
        +	{
        +	STORE *ret;
        +
        +	if (method == NULL)
        +		{
        +		STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +
        +	ret=(STORE *)OPENSSL_malloc(sizeof(STORE));
        +	if (ret == NULL)
        +		{
        +		STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	ret->meth=method;
        +
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data);
        +	if (ret->meth->init && !ret->meth->init(ret))
        +		{
        +		STORE_free(ret);
        +		ret = NULL;
        +		}
        +	return ret;
        +	}
        +
        +STORE *STORE_new_engine(ENGINE *engine)
        +	{
        +	STORE *ret = NULL;
        +	ENGINE *e = engine;
        +	const STORE_METHOD *meth = 0;
        +
        +#ifdef OPENSSL_NO_ENGINE
        +	e = NULL;
        +#else
        +	if (engine)
        +		{
        +		if (!ENGINE_init(engine))
        +			{
        +			STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB);
        +			return NULL;
        +			}
        +		e = engine;
        +		}
        +	else
        +		{
        +		STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if(e)
        +		{
        +		meth = ENGINE_get_STORE(e);
        +		if(!meth)
        +			{
        +			STOREerr(STORE_F_STORE_NEW_ENGINE,
        +				ERR_R_ENGINE_LIB);
        +			ENGINE_finish(e);
        +			return NULL;
        +			}
        +		}
        +#endif
        +
        +	ret = STORE_new_method(meth);
        +	if (ret == NULL)
        +		{
        +		STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_STORE_LIB);
        +		return NULL;
        +		}
        +
        +	ret->engine = e;
        +
        +	return(ret);
        +	}
        +
        +void STORE_free(STORE *store)
        +	{
        +	if (store == NULL)
        +		return;
        +	if (store->meth->clean)
        +		store->meth->clean(store);
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data);
        +	OPENSSL_free(store);
        +	}
        +
        +int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	if (store == NULL)
        +		{
        +		STOREerr(STORE_F_STORE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (store->meth->ctrl)
        +		return store->meth->ctrl(store, cmd, i, p, f);
        +	STOREerr(STORE_F_STORE_CTRL,STORE_R_NO_CONTROL_FUNCTION);
        +	return 0;
        +	}
        +
        +
        +int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +        {
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp,
        +				new_func, dup_func, free_func);
        +        }
        +
        +int STORE_set_ex_data(STORE *r, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
        +	}
        +
        +void *STORE_get_ex_data(STORE *r, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&r->ex_data,idx));
        +	}
        +
        +const STORE_METHOD *STORE_get_method(STORE *store)
        +	{
        +	return store->meth;
        +	}
        +
        +const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth)
        +	{
        +	store->meth=meth;
        +	return store->meth;
        +	}
        +
        +
        +/* API helpers */
        +
        +#define check_store(s,fncode,fnname,fnerrcode) \
        +	do \
        +		{ \
        +		if ((s) == NULL || (s)->meth == NULL) \
        +			{ \
        +			STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \
        +			return 0; \
        +			} \
        +		if ((s)->meth->fnname == NULL) \
        +			{ \
        +			STOREerr((fncode), (fnerrcode)); \
        +			return 0; \
        +			} \
        +		} \
        +	while(0)
        +
        +/* API functions */
        +
        +X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	X509 *x;
        +
        +	check_store(s,STORE_F_STORE_GET_CERTIFICATE,
        +		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
        +
        +	object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
        +		attributes, parameters);
        +	if (!object || !object->data.x509.certificate)
        +		{
        +		STOREerr(STORE_F_STORE_GET_CERTIFICATE,
        +			STORE_R_FAILED_GETTING_CERTIFICATE);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509",data);
        +#endif
        +	x = object->data.x509.certificate;
        +	STORE_OBJECT_free(object);
        +	return x;
        +	}
        +
        +int STORE_store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_CERTIFICATE,
        +		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
        +
        +	object = STORE_OBJECT_new();
        +	if (!object)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_CERTIFICATE,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	
        +	CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509",data);
        +#endif
        +	object->data.x509.certificate = data;
        +
        +	i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
        +		object, attributes, parameters);
        +
        +	STORE_OBJECT_free(object);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_CERTIFICATE,
        +			STORE_R_FAILED_STORING_CERTIFICATE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_modify_certificate(STORE *s, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_MODIFY_CERTIFICATE,
        +		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
        +
        +	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
        +		    search_attributes, add_attributes, modify_attributes,
        +		    delete_attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_MODIFY_CERTIFICATE,
        +			STORE_R_FAILED_MODIFYING_CERTIFICATE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_REVOKE_CERTIFICATE,
        +		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
        +
        +	if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
        +		    attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE,
        +			STORE_R_FAILED_REVOKING_CERTIFICATE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_DELETE_CERTIFICATE,
        +		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
        +
        +	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
        +		    attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_DELETE_CERTIFICATE,
        +			STORE_R_FAILED_DELETING_CERTIFICATE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	void *handle;
        +
        +	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_START,
        +		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
        +
        +	handle = s->meth->list_object_start(s,
        +		STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes, parameters);
        +	if (!handle)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START,
        +			STORE_R_FAILED_LISTING_CERTIFICATES);
        +		return 0;
        +		}
        +	return handle;
        +	}
        +
        +X509 *STORE_list_certificate_next(STORE *s, void *handle)
        +	{
        +	STORE_OBJECT *object;
        +	X509 *x;
        +
        +	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_NEXT,
        +		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
        +
        +	object = s->meth->list_object_next(s, handle);
        +	if (!object || !object->data.x509.certificate)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT,
        +			STORE_R_FAILED_LISTING_CERTIFICATES);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509",data);
        +#endif
        +	x = object->data.x509.certificate;
        +	STORE_OBJECT_free(object);
        +	return x;
        +	}
        +
        +int STORE_list_certificate_end(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_END,
        +		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
        +
        +	if (!s->meth->list_object_end(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END,
        +			STORE_R_FAILED_LISTING_CERTIFICATES);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_list_certificate_endp(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_ENDP,
        +		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
        +
        +	if (!s->meth->list_object_endp(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP,
        +			STORE_R_FAILED_LISTING_CERTIFICATES);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +EVP_PKEY *STORE_generate_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	EVP_PKEY *pkey;
        +
        +	check_store(s,STORE_F_STORE_GENERATE_KEY,
        +		generate_object,STORE_R_NO_GENERATE_OBJECT_FUNCTION);
        +
        +	object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
        +		attributes, parameters);
        +	if (!object || !object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_GENERATE_KEY,
        +			STORE_R_FAILED_GENERATING_KEY);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	pkey = object->data.key;
        +	STORE_OBJECT_free(object);
        +	return pkey;
        +	}
        +
        +EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	EVP_PKEY *pkey;
        +
        +	check_store(s,STORE_F_STORE_GET_PRIVATE_KEY,
        +		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
        +
        +	object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
        +		attributes, parameters);
        +	if (!object || !object->data.key || !object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_GET_PRIVATE_KEY,
        +			STORE_R_FAILED_GETTING_KEY);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	pkey = object->data.key;
        +	STORE_OBJECT_free(object);
        +	return pkey;
        +	}
        +
        +int STORE_store_private_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_STORE_PRIVATE_KEY,
        +		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
        +
        +	object = STORE_OBJECT_new();
        +	if (!object)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	object->data.key = EVP_PKEY_new();
        +	if (!object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	
        +	CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	object->data.key = data;
        +
        +	i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object,
        +		attributes, parameters);
        +
        +	STORE_OBJECT_free(object);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
        +			STORE_R_FAILED_STORING_KEY);
        +		return 0;
        +		}
        +	return i;
        +	}
        +
        +int STORE_modify_private_key(STORE *s, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_MODIFY_PRIVATE_KEY,
        +		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
        +
        +	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
        +		    search_attributes, add_attributes, modify_attributes,
        +		    delete_attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_MODIFY_PRIVATE_KEY,
        +			STORE_R_FAILED_MODIFYING_PRIVATE_KEY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_REVOKE_PRIVATE_KEY,
        +		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
        +
        +	i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
        +		attributes, parameters);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY,
        +			STORE_R_FAILED_REVOKING_KEY);
        +		return 0;
        +		}
        +	return i;
        +	}
        +
        +int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_DELETE_PRIVATE_KEY,
        +		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
        +	
        +	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
        +		    attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY,
        +			STORE_R_FAILED_DELETING_KEY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	void *handle;
        +
        +	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_START,
        +		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
        +
        +	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
        +		attributes, parameters);
        +	if (!handle)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return handle;
        +	}
        +
        +EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle)
        +	{
        +	STORE_OBJECT *object;
        +	EVP_PKEY *pkey;
        +
        +	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
        +		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
        +
        +	object = s->meth->list_object_next(s, handle);
        +	if (!object || !object->data.key || !object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	pkey = object->data.key;
        +	STORE_OBJECT_free(object);
        +	return pkey;
        +	}
        +
        +int STORE_list_private_key_end(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_END,
        +		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
        +
        +	if (!s->meth->list_object_end(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_list_private_key_endp(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
        +		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
        +
        +	if (!s->meth->list_object_endp(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	EVP_PKEY *pkey;
        +
        +	check_store(s,STORE_F_STORE_GET_PUBLIC_KEY,
        +		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
        +
        +	object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
        +		attributes, parameters);
        +	if (!object || !object->data.key || !object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_GET_PUBLIC_KEY,
        +			STORE_R_FAILED_GETTING_KEY);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	pkey = object->data.key;
        +	STORE_OBJECT_free(object);
        +	return pkey;
        +	}
        +
        +int STORE_store_public_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_STORE_PUBLIC_KEY,
        +		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
        +
        +	object = STORE_OBJECT_new();
        +	if (!object)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	object->data.key = EVP_PKEY_new();
        +	if (!object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	
        +	CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	object->data.key = data;
        +
        +	i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object,
        +		attributes, parameters);
        +
        +	STORE_OBJECT_free(object);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
        +			STORE_R_FAILED_STORING_KEY);
        +		return 0;
        +		}
        +	return i;
        +	}
        +
        +int STORE_modify_public_key(STORE *s, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_MODIFY_PUBLIC_KEY,
        +		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
        +
        +	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
        +		    search_attributes, add_attributes, modify_attributes,
        +		    delete_attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_MODIFY_PUBLIC_KEY,
        +			STORE_R_FAILED_MODIFYING_PUBLIC_KEY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_REVOKE_PUBLIC_KEY,
        +		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
        +
        +	i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
        +		attributes, parameters);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY,
        +			STORE_R_FAILED_REVOKING_KEY);
        +		return 0;
        +		}
        +	return i;
        +	}
        +
        +int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_DELETE_PUBLIC_KEY,
        +		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
        +	
        +	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
        +		    attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY,
        +			STORE_R_FAILED_DELETING_KEY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	void *handle;
        +
        +	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_START,
        +		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
        +
        +	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
        +		attributes, parameters);
        +	if (!handle)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return handle;
        +	}
        +
        +EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle)
        +	{
        +	STORE_OBJECT *object;
        +	EVP_PKEY *pkey;
        +
        +	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
        +		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
        +
        +	object = s->meth->list_object_next(s, handle);
        +	if (!object || !object->data.key || !object->data.key)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
        +#ifdef REF_PRINT
        +	REF_PRINT("EVP_PKEY",data);
        +#endif
        +	pkey = object->data.key;
        +	STORE_OBJECT_free(object);
        +	return pkey;
        +	}
        +
        +int STORE_list_public_key_end(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_END,
        +		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
        +
        +	if (!s->meth->list_object_end(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_list_public_key_endp(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
        +		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
        +
        +	if (!s->meth->list_object_endp(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	X509_CRL *crl;
        +
        +	check_store(s,STORE_F_STORE_GENERATE_CRL,
        +		generate_object,STORE_R_NO_GENERATE_CRL_FUNCTION);
        +
        +	object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL,
        +		attributes, parameters);
        +	if (!object || !object->data.crl)
        +		{
        +		STOREerr(STORE_F_STORE_GENERATE_CRL,
        +			STORE_R_FAILED_GENERATING_CRL);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509_CRL",data);
        +#endif
        +	crl = object->data.crl;
        +	STORE_OBJECT_free(object);
        +	return crl;
        +	}
        +
        +X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	X509_CRL *crl;
        +
        +	check_store(s,STORE_F_STORE_GET_CRL,
        +		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
        +
        +	object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL,
        +		attributes, parameters);
        +	if (!object || !object->data.crl)
        +		{
        +		STOREerr(STORE_F_STORE_GET_CRL,
        +			STORE_R_FAILED_GETTING_KEY);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509_CRL",data);
        +#endif
        +	crl = object->data.crl;
        +	STORE_OBJECT_free(object);
        +	return crl;
        +	}
        +
        +int STORE_store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_STORE_CRL,
        +		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
        +
        +	object = STORE_OBJECT_new();
        +	if (!object)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_CRL,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	
        +	CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509_CRL);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509_CRL",data);
        +#endif
        +	object->data.crl = data;
        +
        +	i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object,
        +		attributes, parameters);
        +
        +	STORE_OBJECT_free(object);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_CRL,
        +			STORE_R_FAILED_STORING_KEY);
        +		return 0;
        +		}
        +	return i;
        +	}
        +
        +int STORE_modify_crl(STORE *s, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_MODIFY_CRL,
        +		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
        +
        +	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CRL,
        +		    search_attributes, add_attributes, modify_attributes,
        +		    delete_attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_MODIFY_CRL,
        +			STORE_R_FAILED_MODIFYING_CRL);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_DELETE_CRL,
        +		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
        +	
        +	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL,
        +		    attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_DELETE_CRL,
        +			STORE_R_FAILED_DELETING_KEY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	void *handle;
        +
        +	check_store(s,STORE_F_STORE_LIST_CRL_START,
        +		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
        +
        +	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL,
        +		attributes, parameters);
        +	if (!handle)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CRL_START,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return handle;
        +	}
        +
        +X509_CRL *STORE_list_crl_next(STORE *s, void *handle)
        +	{
        +	STORE_OBJECT *object;
        +	X509_CRL *crl;
        +
        +	check_store(s,STORE_F_STORE_LIST_CRL_NEXT,
        +		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
        +
        +	object = s->meth->list_object_next(s, handle);
        +	if (!object || !object->data.crl)
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CRL_NEXT,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
        +#ifdef REF_PRINT
        +	REF_PRINT("X509_CRL",data);
        +#endif
        +	crl = object->data.crl;
        +	STORE_OBJECT_free(object);
        +	return crl;
        +	}
        +
        +int STORE_list_crl_end(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_CRL_END,
        +		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
        +
        +	if (!s->meth->list_object_end(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CRL_END,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_list_crl_endp(STORE *s, void *handle)
        +	{
        +	check_store(s,STORE_F_STORE_LIST_CRL_ENDP,
        +		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
        +
        +	if (!s->meth->list_object_endp(s, handle))
        +		{
        +		STOREerr(STORE_F_STORE_LIST_CRL_ENDP,
        +			STORE_R_FAILED_LISTING_KEYS);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_STORE_NUMBER,
        +		store_object,STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION);
        +
        +	object = STORE_OBJECT_new();
        +	if (!object)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_NUMBER,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	
        +	object->data.number = data;
        +
        +	i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object,
        +		attributes, parameters);
        +
        +	STORE_OBJECT_free(object);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_NUMBER,
        +			STORE_R_FAILED_STORING_NUMBER);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_modify_number(STORE *s, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_MODIFY_NUMBER,
        +		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
        +
        +	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_NUMBER,
        +		    search_attributes, add_attributes, modify_attributes,
        +		    delete_attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_MODIFY_NUMBER,
        +			STORE_R_FAILED_MODIFYING_NUMBER);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	BIGNUM *n;
        +
        +	check_store(s,STORE_F_STORE_GET_NUMBER,
        +		get_object,STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION);
        +
        +	object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes,
        +		parameters);
        +	if (!object || !object->data.number)
        +		{
        +		STOREerr(STORE_F_STORE_GET_NUMBER,
        +			STORE_R_FAILED_GETTING_NUMBER);
        +		return 0;
        +		}
        +	n = object->data.number;
        +	object->data.number = NULL;
        +	STORE_OBJECT_free(object);
        +	return n;
        +	}
        +
        +int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_DELETE_NUMBER,
        +		delete_object,STORE_R_NO_DELETE_NUMBER_FUNCTION);
        +
        +	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes,
        +		    parameters))
        +		{
        +		STOREerr(STORE_F_STORE_DELETE_NUMBER,
        +			STORE_R_FAILED_DELETING_NUMBER);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	int i;
        +
        +	check_store(s,STORE_F_STORE_STORE_ARBITRARY,
        +		store_object,STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION);
        +
        +	object = STORE_OBJECT_new();
        +	if (!object)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_ARBITRARY,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	
        +	object->data.arbitrary = data;
        +
        +	i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object,
        +		attributes, parameters);
        +
        +	STORE_OBJECT_free(object);
        +
        +	if (!i)
        +		{
        +		STOREerr(STORE_F_STORE_STORE_ARBITRARY,
        +			STORE_R_FAILED_STORING_ARBITRARY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_modify_arbitrary(STORE *s, OPENSSL_ITEM search_attributes[],
        +	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
        +	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_MODIFY_ARBITRARY,
        +		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
        +
        +	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_ARBITRARY,
        +		    search_attributes, add_attributes, modify_attributes,
        +		    delete_attributes, parameters))
        +		{
        +		STOREerr(STORE_F_STORE_MODIFY_ARBITRARY,
        +			STORE_R_FAILED_MODIFYING_ARBITRARY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STORE_OBJECT *object;
        +	BUF_MEM *b;
        +
        +	check_store(s,STORE_F_STORE_GET_ARBITRARY,
        +		get_object,STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION);
        +
        +	object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY,
        +		attributes, parameters);
        +	if (!object || !object->data.arbitrary)
        +		{
        +		STOREerr(STORE_F_STORE_GET_ARBITRARY,
        +			STORE_R_FAILED_GETTING_ARBITRARY);
        +		return 0;
        +		}
        +	b = object->data.arbitrary;
        +	object->data.arbitrary = NULL;
        +	STORE_OBJECT_free(object);
        +	return b;
        +	}
        +
        +int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	check_store(s,STORE_F_STORE_DELETE_ARBITRARY,
        +		delete_object,STORE_R_NO_DELETE_ARBITRARY_FUNCTION);
        +
        +	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes,
        +		    parameters))
        +		{
        +		STOREerr(STORE_F_STORE_DELETE_ARBITRARY,
        +			STORE_R_FAILED_DELETING_ARBITRARY);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +STORE_OBJECT *STORE_OBJECT_new(void)
        +	{
        +	STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT));
        +	if (object) memset(object, 0, sizeof(STORE_OBJECT));
        +	return object;
        +	}
        +void STORE_OBJECT_free(STORE_OBJECT *data)
        +	{
        +	if (!data) return;
        +	switch (data->type)
        +		{
        +	case STORE_OBJECT_TYPE_X509_CERTIFICATE:
        +		X509_free(data->data.x509.certificate);
        +		break;
        +	case STORE_OBJECT_TYPE_X509_CRL:
        +		X509_CRL_free(data->data.crl);
        +		break;
        +	case STORE_OBJECT_TYPE_PRIVATE_KEY:
        +	case STORE_OBJECT_TYPE_PUBLIC_KEY:
        +		EVP_PKEY_free(data->data.key);
        +		break;
        +	case STORE_OBJECT_TYPE_NUMBER:
        +		BN_free(data->data.number);
        +		break;
        +	case STORE_OBJECT_TYPE_ARBITRARY:
        +		BUF_MEM_free(data->data.arbitrary);
        +		break;
        +		}
        +	OPENSSL_free(data);
        +	}
        +
        +IMPLEMENT_STACK_OF(STORE_OBJECT*)
        +
        +
        +struct STORE_attr_info_st
        +	{
        +	unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8];
        +	union
        +		{
        +		char *cstring;
        +		unsigned char *sha1string;
        +		X509_NAME *dn;
        +		BIGNUM *number;
        +		void *any;
        +		} values[STORE_ATTR_TYPE_NUM+1];
        +	size_t value_sizes[STORE_ATTR_TYPE_NUM+1];
        +	};
        +
        +#define ATTR_IS_SET(a,i)	((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \
        +				&& ((a)->set[(i) / 8] & (1 << ((i) % 8))))
        +#define SET_ATTRBIT(a,i)	((a)->set[(i) / 8] |= (1 << ((i) % 8)))
        +#define CLEAR_ATTRBIT(a,i)	((a)->set[(i) / 8] &= ~(1 << ((i) % 8)))
        +
        +STORE_ATTR_INFO *STORE_ATTR_INFO_new(void)
        +	{
        +	return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO));
        +	}
        +static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs,
        +	STORE_ATTR_TYPES code)
        +	{
        +	if (ATTR_IS_SET(attrs,code))
        +		{
        +		switch(code)
        +			{
        +		case STORE_ATTR_FRIENDLYNAME:
        +		case STORE_ATTR_EMAIL:
        +		case STORE_ATTR_FILENAME:
        +			STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0);
        +			break;
        +		case STORE_ATTR_KEYID:
        +		case STORE_ATTR_ISSUERKEYID:
        +		case STORE_ATTR_SUBJECTKEYID:
        +		case STORE_ATTR_ISSUERSERIALHASH:
        +		case STORE_ATTR_CERTHASH:
        +			STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0);
        +			break;
        +		case STORE_ATTR_ISSUER:
        +		case STORE_ATTR_SUBJECT:
        +			STORE_ATTR_INFO_modify_dn(attrs, code, NULL);
        +			break;
        +		case STORE_ATTR_SERIAL:
        +			STORE_ATTR_INFO_modify_number(attrs, code, NULL);
        +			break;
        +		default:
        +			break;
        +			}
        +		}
        +	}
        +int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs)
        +	{
        +	if (attrs)
        +		{
        +		STORE_ATTR_TYPES i;
        +		for(i = 0; i++ < STORE_ATTR_TYPE_NUM;)
        +			STORE_ATTR_INFO_attr_free(attrs, i);
        +		OPENSSL_free(attrs);
        +		}
        +	return 1;
        +	}
        +char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		return attrs->values[code].cstring;
        +	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
        +		STORE_R_NO_VALUE);
        +	return NULL;
        +	}
        +unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
        +	STORE_ATTR_TYPES code)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		return attrs->values[code].sha1string;
        +	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
        +		STORE_R_NO_VALUE);
        +	return NULL;
        +	}
        +X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		return attrs->values[code].dn;
        +	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
        +		STORE_R_NO_VALUE);
        +	return NULL;
        +	}
        +BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		return attrs->values[code].number;
        +	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
        +		STORE_R_NO_VALUE);
        +	return NULL;
        +	}
        +int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	char *cstr, size_t cstr_size)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (!ATTR_IS_SET(attrs,code))
        +		{
        +		if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size)))
        +			return 1;
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE);
        +	return 0;
        +	}
        +int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	unsigned char *sha1str, size_t sha1str_size)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (!ATTR_IS_SET(attrs,code))
        +		{
        +		if ((attrs->values[code].sha1string =
        +			    (unsigned char *)BUF_memdup(sha1str,
        +				    sha1str_size)))
        +			return 1;
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE);
        +	return 0;
        +	}
        +int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	X509_NAME *dn)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (!ATTR_IS_SET(attrs,code))
        +		{
        +		if ((attrs->values[code].dn = X509_NAME_dup(dn)))
        +			return 1;
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE);
        +	return 0;
        +	}
        +int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	BIGNUM *number)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (!ATTR_IS_SET(attrs,code))
        +		{
        +		if ((attrs->values[code].number = BN_dup(number)))
        +			return 1;
        +		STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
        +			ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE);
        +	return 0;
        +	}
        +int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	char *cstr, size_t cstr_size)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		{
        +		OPENSSL_free(attrs->values[code].cstring);
        +		attrs->values[code].cstring = NULL;
        +		CLEAR_ATTRBIT(attrs, code);
        +		}
        +	return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size);
        +	}
        +int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	unsigned char *sha1str, size_t sha1str_size)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		{
        +		OPENSSL_free(attrs->values[code].sha1string);
        +		attrs->values[code].sha1string = NULL;
        +		CLEAR_ATTRBIT(attrs, code);
        +		}
        +	return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size);
        +	}
        +int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	X509_NAME *dn)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		{
        +		OPENSSL_free(attrs->values[code].dn);
        +		attrs->values[code].dn = NULL;
        +		CLEAR_ATTRBIT(attrs, code);
        +		}
        +	return STORE_ATTR_INFO_set_dn(attrs, code, dn);
        +	}
        +int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
        +	BIGNUM *number)
        +	{
        +	if (!attrs)
        +		{
        +		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER,
        +			ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (ATTR_IS_SET(attrs,code))
        +		{
        +		OPENSSL_free(attrs->values[code].number);
        +		attrs->values[code].number = NULL;
        +		CLEAR_ATTRBIT(attrs, code);
        +		}
        +	return STORE_ATTR_INFO_set_number(attrs, code, number);
        +	}
        +
        +struct attr_list_ctx_st
        +	{
        +	OPENSSL_ITEM *attributes;
        +	};
        +void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes)
        +	{
        +	if (attributes)
        +		{
        +		struct attr_list_ctx_st *context =
        +			(struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st));
        +		if (context)
        +			context->attributes = attributes;
        +		else
        +			STOREerr(STORE_F_STORE_PARSE_ATTRS_START,
        +				ERR_R_MALLOC_FAILURE);
        +		return context;
        +		}
        +	STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_PASSED_NULL_PARAMETER);
        +	return 0;
        +	}
        +STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle)
        +	{
        +	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
        +
        +	if (context && context->attributes)
        +		{
        +		STORE_ATTR_INFO *attrs = NULL;
        +
        +		while(context->attributes
        +			&& context->attributes->code != STORE_ATTR_OR
        +			&& context->attributes->code != STORE_ATTR_END)
        +			{
        +			switch(context->attributes->code)
        +				{
        +			case STORE_ATTR_FRIENDLYNAME:
        +			case STORE_ATTR_EMAIL:
        +			case STORE_ATTR_FILENAME:
        +				if (!attrs) attrs = STORE_ATTR_INFO_new();
        +				if (attrs == NULL)
        +					{
        +					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
        +						ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				STORE_ATTR_INFO_set_cstr(attrs,
        +					context->attributes->code,
        +					context->attributes->value,
        +					context->attributes->value_size);
        +				break;
        +			case STORE_ATTR_KEYID:
        +			case STORE_ATTR_ISSUERKEYID:
        +			case STORE_ATTR_SUBJECTKEYID:
        +			case STORE_ATTR_ISSUERSERIALHASH:
        +			case STORE_ATTR_CERTHASH:
        +				if (!attrs) attrs = STORE_ATTR_INFO_new();
        +				if (attrs == NULL)
        +					{
        +					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
        +						ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				STORE_ATTR_INFO_set_sha1str(attrs,
        +					context->attributes->code,
        +					context->attributes->value,
        +					context->attributes->value_size);
        +				break;
        +			case STORE_ATTR_ISSUER:
        +			case STORE_ATTR_SUBJECT:
        +				if (!attrs) attrs = STORE_ATTR_INFO_new();
        +				if (attrs == NULL)
        +					{
        +					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
        +						ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				STORE_ATTR_INFO_modify_dn(attrs,
        +					context->attributes->code,
        +					context->attributes->value);
        +				break;
        +			case STORE_ATTR_SERIAL:
        +				if (!attrs) attrs = STORE_ATTR_INFO_new();
        +				if (attrs == NULL)
        +					{
        +					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
        +						ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				STORE_ATTR_INFO_modify_number(attrs,
        +					context->attributes->code,
        +					context->attributes->value);
        +				break;
        +				}
        +			context->attributes++;
        +			}
        +		if (context->attributes->code == STORE_ATTR_OR)
        +			context->attributes++;
        +		return attrs;
        +	err:
        +		while(context->attributes
        +			&& context->attributes->code != STORE_ATTR_OR
        +			&& context->attributes->code != STORE_ATTR_END)
        +			context->attributes++;
        +		if (context->attributes->code == STORE_ATTR_OR)
        +			context->attributes++;
        +		return NULL;
        +		}
        +	STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER);
        +	return NULL;
        +	}
        +int STORE_parse_attrs_end(void *handle)
        +	{
        +	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
        +
        +	if (context && context->attributes)
        +		{
        +#if 0
        +		OPENSSL_ITEM *attributes = context->attributes;
        +#endif
        +		OPENSSL_free(context);
        +		return 1;
        +		}
        +	STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
        +	return 0;
        +	}
        +
        +int STORE_parse_attrs_endp(void *handle)
        +	{
        +	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
        +
        +	if (context && context->attributes)
        +		{
        +		return context->attributes->code == STORE_ATTR_END;
        +		}
        +	STOREerr(STORE_F_STORE_PARSE_ATTRS_ENDP, ERR_R_PASSED_NULL_PARAMETER);
        +	return 0;
        +	}
        +
        +static int attr_info_compare_compute_range(
        +	const unsigned char *abits, const unsigned char *bbits,
        +	unsigned int *alowp, unsigned int *ahighp,
        +	unsigned int *blowp, unsigned int *bhighp)
        +	{
        +	unsigned int alow = (unsigned int)-1, ahigh = 0;
        +	unsigned int blow = (unsigned int)-1, bhigh = 0;
        +	int i, res = 0;
        +
        +	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
        +		{
        +		if (res == 0)
        +			{
        +			if (*abits < *bbits) res = -1;
        +			if (*abits > *bbits) res = 1;
        +			}
        +		if (*abits)
        +			{
        +			if (alow == (unsigned int)-1)
        +				{
        +				alow = i * 8;
        +				if (!(*abits & 0x01)) alow++;
        +				if (!(*abits & 0x02)) alow++;
        +				if (!(*abits & 0x04)) alow++;
        +				if (!(*abits & 0x08)) alow++;
        +				if (!(*abits & 0x10)) alow++;
        +				if (!(*abits & 0x20)) alow++;
        +				if (!(*abits & 0x40)) alow++;
        +				}
        +			ahigh = i * 8 + 7;
        +			if (!(*abits & 0x80)) ahigh++;
        +			if (!(*abits & 0x40)) ahigh++;
        +			if (!(*abits & 0x20)) ahigh++;
        +			if (!(*abits & 0x10)) ahigh++;
        +			if (!(*abits & 0x08)) ahigh++;
        +			if (!(*abits & 0x04)) ahigh++;
        +			if (!(*abits & 0x02)) ahigh++;
        +			}
        +		if (*bbits)
        +			{
        +			if (blow == (unsigned int)-1)
        +				{
        +				blow = i * 8;
        +				if (!(*bbits & 0x01)) blow++;
        +				if (!(*bbits & 0x02)) blow++;
        +				if (!(*bbits & 0x04)) blow++;
        +				if (!(*bbits & 0x08)) blow++;
        +				if (!(*bbits & 0x10)) blow++;
        +				if (!(*bbits & 0x20)) blow++;
        +				if (!(*bbits & 0x40)) blow++;
        +				}
        +			bhigh = i * 8 + 7;
        +			if (!(*bbits & 0x80)) bhigh++;
        +			if (!(*bbits & 0x40)) bhigh++;
        +			if (!(*bbits & 0x20)) bhigh++;
        +			if (!(*bbits & 0x10)) bhigh++;
        +			if (!(*bbits & 0x08)) bhigh++;
        +			if (!(*bbits & 0x04)) bhigh++;
        +			if (!(*bbits & 0x02)) bhigh++;
        +			}
        +		}
        +	if (ahigh + alow < bhigh + blow) res = -1;
        +	if (ahigh + alow > bhigh + blow) res = 1;
        +	if (alowp) *alowp = alow;
        +	if (ahighp) *ahighp = ahigh;
        +	if (blowp) *blowp = blow;
        +	if (bhighp) *bhighp = bhigh;
        +	return res;
        +	}
        +
        +int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
        +			    const STORE_ATTR_INFO * const *b)
        +	{
        +	if (a == b) return 0;
        +	if (!a) return -1;
        +	if (!b) return 1;
        +	return attr_info_compare_compute_range((*a)->set, (*b)->set, 0, 0, 0, 0);
        +	}
        +
        +int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
        +	{
        +	unsigned int alow, ahigh, blow, bhigh;
        +
        +	if (a == b) return 1;
        +	if (!a) return 0;
        +	if (!b) return 0;
        +	attr_info_compare_compute_range(a->set, b->set,
        +		&alow, &ahigh, &blow, &bhigh);
        +	if (alow >= blow && ahigh <= bhigh)
        +		return 1;
        +	return 0;
        +	}
        +
        +int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
        +	{
        +	unsigned char *abits, *bbits;
        +	int i;
        +
        +	if (a == b) return 1;
        +	if (!a) return 0;
        +	if (!b) return 0;
        +	abits = a->set;
        +	bbits = b->set;
        +	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
        +		{
        +		if (*abits && (*bbits & *abits) != *abits)
        +			return 0;
        +		}
        +	return 1;
        +	}
        +
        +int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
        +	{
        +	STORE_ATTR_TYPES i;
        +
        +	if (a == b) return 1;
        +	if (!STORE_ATTR_INFO_in(a, b)) return 0;
        +	for (i = 1; i < STORE_ATTR_TYPE_NUM; i++)
        +		if (ATTR_IS_SET(a, i))
        +			{
        +			switch(i)
        +				{
        +			case STORE_ATTR_FRIENDLYNAME:
        +			case STORE_ATTR_EMAIL:
        +			case STORE_ATTR_FILENAME:
        +				if (strcmp(a->values[i].cstring,
        +					    b->values[i].cstring))
        +					return 0;
        +				break;
        +			case STORE_ATTR_KEYID:
        +			case STORE_ATTR_ISSUERKEYID:
        +			case STORE_ATTR_SUBJECTKEYID:
        +			case STORE_ATTR_ISSUERSERIALHASH:
        +			case STORE_ATTR_CERTHASH:
        +				if (memcmp(a->values[i].sha1string,
        +					    b->values[i].sha1string,
        +					    a->value_sizes[i]))
        +					return 0;
        +				break;
        +			case STORE_ATTR_ISSUER:
        +			case STORE_ATTR_SUBJECT:
        +				if (X509_NAME_cmp(a->values[i].dn,
        +					    b->values[i].dn))
        +					return 0;
        +				break;
        +			case STORE_ATTR_SERIAL:
        +				if (BN_cmp(a->values[i].number,
        +					    b->values[i].number))
        +					return 0;
        +				break;
        +			default:
        +				break;
        +				}
        +			}
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/store/str_locl.h b/vendor/openssl/openssl/crypto/store/str_locl.h
        new file mode 100644
        index 000000000..3f8cb7561
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/str_locl.h
        @@ -0,0 +1,124 @@
        +/* crypto/store/str_locl.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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_STORE_LOCL_H
        +#define HEADER_STORE_LOCL_H
        +
        +#include <openssl/crypto.h>
        +#include <openssl/store.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +struct store_method_st
        +	{
        +	char *name;
        +
        +	/* All the functions return a positive integer or non-NULL for success
        +	   and 0, a negative integer or NULL for failure */
        +
        +	/* Initialise the STORE with private data */
        +	STORE_INITIALISE_FUNC_PTR init;
        +	/* Initialise the STORE with private data */
        +	STORE_CLEANUP_FUNC_PTR clean;
        +	/* Generate an object of a given type */
        +	STORE_GENERATE_OBJECT_FUNC_PTR generate_object;
        +	/* Get an object of a given type.  This function isn't really very
        +	   useful since the listing functions (below) can be used for the
        +	   same purpose and are much more general. */
        +	STORE_GET_OBJECT_FUNC_PTR get_object;
        +	/* Store an object of a given type. */
        +	STORE_STORE_OBJECT_FUNC_PTR store_object;
        +	/* Modify the attributes bound to an object of a given type. */
        +	STORE_MODIFY_OBJECT_FUNC_PTR modify_object;
        +	/* Revoke an object of a given type. */
        +	STORE_HANDLE_OBJECT_FUNC_PTR revoke_object;
        +	/* Delete an object of a given type. */
        +	STORE_HANDLE_OBJECT_FUNC_PTR delete_object;
        +	/* List a bunch of objects of a given type and with the associated
        +	   attributes. */
        +	STORE_START_OBJECT_FUNC_PTR list_object_start;
        +	STORE_NEXT_OBJECT_FUNC_PTR list_object_next;
        +	STORE_END_OBJECT_FUNC_PTR list_object_end;
        +	STORE_END_OBJECT_FUNC_PTR list_object_endp;
        +	/* Store-level function to make any necessary update operations. */
        +	STORE_GENERIC_FUNC_PTR update_store;
        +	/* Store-level function to get exclusive access to the store. */
        +	STORE_GENERIC_FUNC_PTR lock_store;
        +	/* Store-level function to release exclusive access to the store. */
        +	STORE_GENERIC_FUNC_PTR unlock_store;
        +
        +	/* Generic control function */
        +	STORE_CTRL_FUNC_PTR ctrl;
        +	};
        +
        +struct store_st
        +	{
        +	const STORE_METHOD *meth;
        +	/* functional reference if 'meth' is ENGINE-provided */
        +	ENGINE *engine;
        +
        +	CRYPTO_EX_DATA ex_data;
        +	int references;
        +	};
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/store/str_mem.c b/vendor/openssl/openssl/crypto/store/str_mem.c
        new file mode 100644
        index 000000000..8ac4f7e55
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/str_mem.c
        @@ -0,0 +1,365 @@
        +/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <string.h>
        +#include <openssl/err.h>
        +#include "str_locl.h"
        +
        +/* The memory store is currently highly experimental.  It's meant to become
        +   a base store used by other stores for internal caching (for full caching
        +   support, aging needs to be added).
        +
        +   The database use is meant to support as much attribute association as
        +   possible, while providing for as small search ranges as possible.
        +   This is currently provided for by sorting the entries by numbers that
        +   are composed of bits set at the positions indicated by attribute type
        +   codes.  This provides for ranges determined by the highest attribute
        +   type code value.  A better idea might be to sort by values computed
        +   from the range of attributes associated with the object (basically,
        +   the difference between the highest and lowest attribute type code)
        +   and it's distance from a base (basically, the lowest associated
        +   attribute type code).
        +*/
        +
        +typedef struct mem_object_data_st
        +	{
        +	STORE_OBJECT *object;
        +	STORE_ATTR_INFO *attr_info;
        +	int references;
        +	} MEM_OBJECT_DATA;
        +
        +DECLARE_STACK_OF(MEM_OBJECT_DATA)
        +struct mem_data_st
        +	{
        +	STACK_OF(MEM_OBJECT_DATA) *data; /* sorted with
        +					  * STORE_ATTR_INFO_compare(). */
        +	unsigned int compute_components : 1; /* Currently unused, but can
        +						be used to add attributes
        +						from parts of the data. */
        +	};
        +
        +DECLARE_STACK_OF(STORE_ATTR_INFO)
        +struct mem_ctx_st
        +	{
        +	int type;		/* The type we're searching for */
        +	STACK_OF(STORE_ATTR_INFO) *search_attributes; /* Sets of
        +				     attributes to search for.  Each
        +				     element is a STORE_ATTR_INFO. */
        +	int search_index;	/* which of the search attributes we
        +				   found a match for, -1 when we still
        +				   haven't found any */
        +	int index;		/* -1 as long as we're searching for
        +                                    the first */
        +	};
        +
        +static int mem_init(STORE *s);
        +static void mem_clean(STORE *s);
        +static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
        +	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
        +	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
        +	OPENSSL_ITEM parameters[]);
        +static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
        +static STORE_OBJECT *mem_list_next(STORE *s, void *handle);
        +static int mem_list_end(STORE *s, void *handle);
        +static int mem_list_endp(STORE *s, void *handle);
        +static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[]);
        +static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void));
        +
        +static STORE_METHOD store_memory =
        +	{
        +	"OpenSSL memory store interface",
        +	mem_init,
        +	mem_clean,
        +	mem_generate,
        +	mem_get,
        +	mem_store,
        +	mem_modify,
        +	NULL, /* revoke */
        +	mem_delete,
        +	mem_list_start,
        +	mem_list_next,
        +	mem_list_end,
        +	mem_list_endp,
        +	NULL, /* update */
        +	mem_lock,
        +	mem_unlock,
        +	mem_ctrl
        +	};
        +
        +const STORE_METHOD *STORE_Memory(void)
        +	{
        +	return &store_memory;
        +	}
        +
        +static int mem_init(STORE *s)
        +	{
        +	return 1;
        +	}
        +
        +static void mem_clean(STORE *s)
        +	{
        +	return;
        +	}
        +
        +static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	void *context = mem_list_start(s, type, attributes, parameters);
        +	
        +	if (context)
        +		{
        +		STORE_OBJECT *object = mem_list_next(s, context);
        +
        +		if (mem_list_end(s, context))
        +			return object;
        +		}
        +	return NULL;
        +	}
        +static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
        +	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
        +	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +/* The list functions may be the hardest to understand.  Basically,
        +   mem_list_start compiles a stack of attribute info elements, and
        +   puts that stack into the context to be returned.  mem_list_next
        +   will then find the first matching element in the store, and then
        +   walk all the way to the end of the store (since any combination
        +   of attribute bits above the starting point may match the searched
        +   for bit pattern...). */
        +static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
        +	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
        +	{
        +	struct mem_ctx_st *context =
        +		(struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st));
        +	void *attribute_context = NULL;
        +	STORE_ATTR_INFO *attrs = NULL;
        +
        +	if (!context)
        +		{
        +		STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	memset(context, 0, sizeof(struct mem_ctx_st));
        +
        +	attribute_context = STORE_parse_attrs_start(attributes);
        +	if (!attribute_context)
        +		{
        +		STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB);
        +		goto err;
        +		}
        +
        +	while((attrs = STORE_parse_attrs_next(attribute_context)))
        +		{
        +		if (context->search_attributes == NULL)
        +			{
        +			context->search_attributes =
        +				sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare);
        +			if (!context->search_attributes)
        +				{
        +				STOREerr(STORE_F_MEM_LIST_START,
        +					ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			}
        +		sk_STORE_ATTR_INFO_push(context->search_attributes,attrs);
        +		}
        +	if (!STORE_parse_attrs_endp(attribute_context))
        +		goto err;
        +	STORE_parse_attrs_end(attribute_context);
        +	context->search_index = -1;
        +	context->index = -1;
        +	return context;
        + err:
        +	if (attribute_context) STORE_parse_attrs_end(attribute_context);
        +	mem_list_end(s, context);
        +	return NULL;
        +	}
        +static STORE_OBJECT *mem_list_next(STORE *s, void *handle)
        +	{
        +	int i;
        +	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
        +	struct mem_object_data_st key = { 0, 0, 1 };
        +	struct mem_data_st *store =
        +		(struct mem_data_st *)STORE_get_ex_data(s, 1);
        +	int srch;
        +	int cres = 0;
        +
        +	if (!context)
        +		{
        +		STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
        +		return NULL;
        +		}
        +	if (!store)
        +		{
        +		STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE);
        +		return NULL;
        +		}
        +
        +	if (context->search_index == -1)
        +		{
        +		for (i = 0;
        +		     i < sk_STORE_ATTR_INFO_num(context->search_attributes);
        +		     i++)
        +			{
        +			key.attr_info
        +			  = sk_STORE_ATTR_INFO_value(context->search_attributes,
        +						     i);
        +			srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key);
        +
        +			if (srch >= 0)
        +				{
        +				context->search_index = srch;
        +				break;
        +				}
        +			}
        +		}
        +	if (context->search_index < 0)
        +		return NULL;
        +	
        +	key.attr_info =
        +		sk_STORE_ATTR_INFO_value(context->search_attributes,
        +					 context->search_index);
        +	for(srch = context->search_index;
        +	    srch < sk_MEM_OBJECT_DATA_num(store->data)
        +		    && STORE_ATTR_INFO_in_range(key.attr_info,
        +			    sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info)
        +		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
        +				 sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info));
        +	    srch++)
        +		;
        +
        +	context->search_index = srch;
        +	if (cres)
        +		return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object;
        +	return NULL;
        +	}
        +static int mem_list_end(STORE *s, void *handle)
        +	{
        +	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
        +
        +	if (!context)
        +		{
        +		STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER);
        +		return 0;
        +		}
        +	if (context && context->search_attributes)
        +		sk_STORE_ATTR_INFO_free(context->search_attributes);
        +	if (context) OPENSSL_free(context);
        +	return 1;
        +	}
        +static int mem_list_endp(STORE *s, void *handle)
        +	{
        +	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
        +
        +	if (!context
        +	    || context->search_index
        +	       == sk_STORE_ATTR_INFO_num(context->search_attributes))
        +		return 1;
        +	return 0;
        +	}
        +static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	return 1;
        +	}
        +static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
        +	OPENSSL_ITEM parameters[])
        +	{
        +	return 1;
        +	}
        +static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void))
        +	{
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/store/str_meth.c b/vendor/openssl/openssl/crypto/store/str_meth.c
        new file mode 100644
        index 000000000..a46de03a2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/store/str_meth.c
        @@ -0,0 +1,250 @@
        +/* crypto/store/str_meth.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <string.h>
        +#include <openssl/buffer.h>
        +#include "str_locl.h"
        +
        +STORE_METHOD *STORE_create_method(char *name)
        +	{
        +	STORE_METHOD *store_method = (STORE_METHOD *)OPENSSL_malloc(sizeof(STORE_METHOD));
        +
        +	if (store_method)
        +		{
        +		memset(store_method, 0, sizeof(*store_method));
        +		store_method->name = BUF_strdup(name);
        +		}
        +	return store_method;
        +	}
        +
        +/* BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
        +   (that is, it hasn't been allocated using STORE_create_method(), you deserve
        +   anything Murphy can throw at you and more!  You have been warned. */
        +void STORE_destroy_method(STORE_METHOD *store_method)
        +	{
        +	if (!store_method) return;
        +	OPENSSL_free(store_method->name);
        +	store_method->name = NULL;
        +	OPENSSL_free(store_method);
        +	}
        +
        +int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f)
        +	{
        +	sm->init = init_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f)
        +	{
        +	sm->clean = clean_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f)
        +	{
        +	sm->generate_object = generate_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f)
        +	{
        +	sm->get_object = get_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f)
        +	{
        +	sm->store_object = store_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR modify_f)
        +	{
        +	sm->modify_object = modify_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f)
        +	{
        +	sm->revoke_object = revoke_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f)
        +	{
        +	sm->delete_object = delete_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f)
        +	{
        +	sm->list_object_start = list_start_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f)
        +	{
        +	sm->list_object_next = list_next_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f)
        +	{
        +	sm->list_object_end = list_end_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR update_f)
        +	{
        +	sm->update_store = update_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR lock_f)
        +	{
        +	sm->lock_store = lock_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR unlock_f)
        +	{
        +	sm->unlock_store = unlock_f;
        +	return 1;
        +	}
        +
        +int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f)
        +	{
        +	sm->ctrl = ctrl_f;
        +	return 1;
        +	}
        +
        +STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm)
        +	{
        +	return sm->init;
        +	}
        +
        +STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm)
        +	{
        +	return sm->clean;
        +	}
        +
        +STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm)
        +	{
        +	return sm->generate_object;
        +	}
        +
        +STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm)
        +	{
        +	return sm->get_object;
        +	}
        +
        +STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm)
        +	{
        +	return sm->store_object;
        +	}
        +
        +STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm)
        +	{
        +	return sm->modify_object;
        +	}
        +
        +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm)
        +	{
        +	return sm->revoke_object;
        +	}
        +
        +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm)
        +	{
        +	return sm->delete_object;
        +	}
        +
        +STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm)
        +	{
        +	return sm->list_object_start;
        +	}
        +
        +STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm)
        +	{
        +	return sm->list_object_next;
        +	}
        +
        +STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm)
        +	{
        +	return sm->list_object_end;
        +	}
        +
        +STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm)
        +	{
        +	return sm->update_store;
        +	}
        +
        +STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm)
        +	{
        +	return sm->lock_store;
        +	}
        +
        +STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm)
        +	{
        +	return sm->unlock_store;
        +	}
        +
        +STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm)
        +	{
        +	return sm->ctrl;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/symhacks.h b/vendor/openssl/openssl/crypto/symhacks.h
        new file mode 100644
        index 000000000..07a412f84
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/symhacks.h
        @@ -0,0 +1,475 @@
        +/* ====================================================================
        + * 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
        +
        +#include <openssl/e_os2.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. */
        +/* Note that this affects util/libeay.num and util/ssleay.num...  you may
        +   change those manually, but that's not recommended, as those files are
        +   controlled centrally and updated on Unix, and the central definition
        +   may disagree with yours, which in turn may come with shareable library
        +   incompatibilities. */
        +#ifdef OPENSSL_SYS_VMS
        +
        +/* Hack a long name in crypto/ex_data.c */
        +#undef CRYPTO_get_ex_data_implementation
        +#define CRYPTO_get_ex_data_implementation	CRYPTO_get_ex_data_impl
        +#undef CRYPTO_set_ex_data_implementation
        +#define CRYPTO_set_ex_data_implementation	CRYPTO_set_ex_data_impl
        +
        +/* 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
        +#undef X509_policy_tree_get0_user_policies
        +#define X509_policy_tree_get0_user_policies	X509_pcy_tree_get0_usr_policies
        +#undef X509_policy_node_get0_qualifiers
        +#define X509_policy_node_get0_qualifiers	X509_pcy_node_get0_qualifiers
        +#undef X509_STORE_CTX_get_explicit_policy
        +#define X509_STORE_CTX_get_explicit_policy	X509_STORE_CTX_get_expl_policy
        +#undef X509_STORE_CTX_get0_current_issuer
        +#define X509_STORE_CTX_get0_current_issuer	X509_STORE_CTX_get0_cur_issuer
        +
        +/* Hack some long CRYPTO names */
        +#undef CRYPTO_set_dynlock_destroy_callback
        +#define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
        +#undef CRYPTO_set_dynlock_create_callback
        +#define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
        +#undef CRYPTO_set_dynlock_lock_callback
        +#define CRYPTO_set_dynlock_lock_callback	CRYPTO_set_dynlock_lock_cb
        +#undef CRYPTO_get_dynlock_lock_callback
        +#define CRYPTO_get_dynlock_lock_callback	CRYPTO_get_dynlock_lock_cb
        +#undef CRYPTO_get_dynlock_destroy_callback
        +#define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
        +#undef CRYPTO_get_dynlock_create_callback
        +#define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
        +#undef CRYPTO_set_locked_mem_ex_functions
        +#define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
        +#undef CRYPTO_get_locked_mem_ex_functions
        +#define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs
        +
        +/* Hack some long SSL names */
        +#undef SSL_CTX_set_default_verify_paths
        +#define SSL_CTX_set_default_verify_paths	SSL_CTX_set_def_verify_paths
        +#undef SSL_get_ex_data_X509_STORE_CTX_idx
        +#define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
        +#undef SSL_add_file_cert_subjects_to_stack
        +#define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
        +#undef SSL_add_dir_cert_subjects_to_stack
        +#define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
        +#undef SSL_CTX_use_certificate_chain_file
        +#define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
        +#undef SSL_CTX_set_cert_verify_callback
        +#define SSL_CTX_set_cert_verify_callback	SSL_CTX_set_cert_verify_cb
        +#undef SSL_CTX_set_default_passwd_cb_userdata
        +#define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
        +#undef SSL_COMP_get_compression_methods
        +#define SSL_COMP_get_compression_methods	SSL_COMP_get_compress_methods
        +#undef ssl_add_clienthello_renegotiate_ext
        +#define ssl_add_clienthello_renegotiate_ext	ssl_add_clienthello_reneg_ext
        +#undef ssl_add_serverhello_renegotiate_ext
        +#define ssl_add_serverhello_renegotiate_ext	ssl_add_serverhello_reneg_ext
        +#undef ssl_parse_clienthello_renegotiate_ext
        +#define ssl_parse_clienthello_renegotiate_ext	ssl_parse_clienthello_reneg_ext
        +#undef ssl_parse_serverhello_renegotiate_ext
        +#define ssl_parse_serverhello_renegotiate_ext	ssl_parse_serverhello_reneg_ext
        +#undef SSL_srp_server_param_with_username
        +#define SSL_srp_server_param_with_username	SSL_srp_server_param_with_un
        +#undef SSL_CTX_set_srp_client_pwd_callback
        +#define SSL_CTX_set_srp_client_pwd_callback	SSL_CTX_set_srp_client_pwd_cb
        +#undef SSL_CTX_set_srp_verify_param_callback
        +#define SSL_CTX_set_srp_verify_param_callback	SSL_CTX_set_srp_vfy_param_cb
        +#undef SSL_CTX_set_srp_username_callback
        +#define SSL_CTX_set_srp_username_callback	SSL_CTX_set_srp_un_cb
        +#undef ssl_add_clienthello_use_srtp_ext
        +#define ssl_add_clienthello_use_srtp_ext	ssl_add_clihello_use_srtp_ext
        +#undef ssl_add_serverhello_use_srtp_ext
        +#define ssl_add_serverhello_use_srtp_ext	ssl_add_serhello_use_srtp_ext
        +#undef ssl_parse_clienthello_use_srtp_ext
        +#define ssl_parse_clienthello_use_srtp_ext	ssl_parse_clihello_use_srtp_ext
        +#undef ssl_parse_serverhello_use_srtp_ext
        +#define ssl_parse_serverhello_use_srtp_ext	ssl_parse_serhello_use_srtp_ext
        +#undef SSL_CTX_set_next_protos_advertised_cb
        +#define SSL_CTX_set_next_protos_advertised_cb	SSL_CTX_set_next_protos_adv_cb
        +#undef SSL_CTX_set_next_proto_select_cb
        +#define SSL_CTX_set_next_proto_select_cb	SSL_CTX_set_next_proto_sel_cb
        +
        +/* Hack some long ENGINE names */
        +#undef ENGINE_get_default_BN_mod_exp_crt
        +#define ENGINE_get_default_BN_mod_exp_crt	ENGINE_get_def_BN_mod_exp_crt
        +#undef ENGINE_set_default_BN_mod_exp_crt
        +#define ENGINE_set_default_BN_mod_exp_crt	ENGINE_set_def_BN_mod_exp_crt
        +#undef ENGINE_set_load_privkey_function
        +#define ENGINE_set_load_privkey_function	ENGINE_set_load_privkey_fn
        +#undef ENGINE_get_load_privkey_function
        +#define ENGINE_get_load_privkey_function	ENGINE_get_load_privkey_fn
        +#undef ENGINE_unregister_pkey_asn1_meths
        +#define ENGINE_unregister_pkey_asn1_meths	ENGINE_unreg_pkey_asn1_meths
        +#undef ENGINE_register_all_pkey_asn1_meths
        +#define ENGINE_register_all_pkey_asn1_meths	ENGINE_reg_all_pkey_asn1_meths
        +#undef ENGINE_set_default_pkey_asn1_meths
        +#define ENGINE_set_default_pkey_asn1_meths	ENGINE_set_def_pkey_asn1_meths
        +#undef ENGINE_get_pkey_asn1_meth_engine
        +#define ENGINE_get_pkey_asn1_meth_engine	ENGINE_get_pkey_asn1_meth_eng
        +#undef ENGINE_set_load_ssl_client_cert_function
        +#define ENGINE_set_load_ssl_client_cert_function \
        +						ENGINE_set_ld_ssl_clnt_cert_fn
        +#undef ENGINE_get_ssl_client_cert_function
        +#define ENGINE_get_ssl_client_cert_function	ENGINE_get_ssl_client_cert_fn
        +
        +/* Hack some long OCSP names */
        +#undef OCSP_REQUEST_get_ext_by_critical
        +#define OCSP_REQUEST_get_ext_by_critical	OCSP_REQUEST_get_ext_by_crit
        +#undef OCSP_BASICRESP_get_ext_by_critical
        +#define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
        +#undef OCSP_SINGLERESP_get_ext_by_critical
        +#define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit
        +
        +/* Hack some long DES names */
        +#undef _ossl_old_des_ede3_cfb64_encrypt
        +#define _ossl_old_des_ede3_cfb64_encrypt	_ossl_odes_ede3_cfb64_encrypt
        +#undef _ossl_old_des_ede3_ofb64_encrypt
        +#define _ossl_old_des_ede3_ofb64_encrypt	_ossl_odes_ede3_ofb64_encrypt
        +
        +/* Hack some long EVP names */
        +#undef OPENSSL_add_all_algorithms_noconf
        +#define OPENSSL_add_all_algorithms_noconf	OPENSSL_add_all_algo_noconf
        +#undef OPENSSL_add_all_algorithms_conf
        +#define OPENSSL_add_all_algorithms_conf		OPENSSL_add_all_algo_conf
        +#undef EVP_PKEY_meth_set_verify_recover
        +#define EVP_PKEY_meth_set_verify_recover	EVP_PKEY_meth_set_vrfy_recover
        +
        +/* Hack some long EC names */
        +#undef EC_GROUP_set_point_conversion_form
        +#define EC_GROUP_set_point_conversion_form	EC_GROUP_set_point_conv_form
        +#undef EC_GROUP_get_point_conversion_form
        +#define EC_GROUP_get_point_conversion_form	EC_GROUP_get_point_conv_form
        +#undef EC_GROUP_clear_free_all_extra_data
        +#define EC_GROUP_clear_free_all_extra_data	EC_GROUP_clr_free_all_xtra_data
        +#undef EC_KEY_set_public_key_affine_coordinates
        +#define EC_KEY_set_public_key_affine_coordinates \
        +						EC_KEY_set_pub_key_aff_coords
        +#undef EC_POINT_set_Jprojective_coordinates_GFp
        +#define EC_POINT_set_Jprojective_coordinates_GFp \
        +                                                EC_POINT_set_Jproj_coords_GFp
        +#undef EC_POINT_get_Jprojective_coordinates_GFp
        +#define EC_POINT_get_Jprojective_coordinates_GFp \
        +                                                EC_POINT_get_Jproj_coords_GFp
        +#undef EC_POINT_set_affine_coordinates_GFp
        +#define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
        +#undef EC_POINT_get_affine_coordinates_GFp
        +#define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
        +#undef EC_POINT_set_compressed_coordinates_GFp
        +#define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
        +#undef EC_POINT_set_affine_coordinates_GF2m
        +#define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
        +#undef EC_POINT_get_affine_coordinates_GF2m
        +#define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
        +#undef EC_POINT_set_compressed_coordinates_GF2m
        +#define EC_POINT_set_compressed_coordinates_GF2m \
        +                                                EC_POINT_set_compr_coords_GF2m
        +#undef ec_GF2m_simple_group_clear_finish
        +#define ec_GF2m_simple_group_clear_finish	ec_GF2m_simple_grp_clr_finish
        +#undef ec_GF2m_simple_group_check_discriminant
        +#define ec_GF2m_simple_group_check_discriminant	ec_GF2m_simple_grp_chk_discrim
        +#undef ec_GF2m_simple_point_clear_finish
        +#define ec_GF2m_simple_point_clear_finish	ec_GF2m_simple_pt_clr_finish
        +#undef ec_GF2m_simple_point_set_to_infinity
        +#define ec_GF2m_simple_point_set_to_infinity	ec_GF2m_simple_pt_set_to_inf
        +#undef ec_GF2m_simple_points_make_affine
        +#define ec_GF2m_simple_points_make_affine	ec_GF2m_simple_pts_make_affine
        +#undef ec_GF2m_simple_point_set_affine_coordinates
        +#define ec_GF2m_simple_point_set_affine_coordinates \
        +                                                ec_GF2m_smp_pt_set_af_coords
        +#undef ec_GF2m_simple_point_get_affine_coordinates
        +#define ec_GF2m_simple_point_get_affine_coordinates \
        +                                                ec_GF2m_smp_pt_get_af_coords
        +#undef ec_GF2m_simple_set_compressed_coordinates
        +#define ec_GF2m_simple_set_compressed_coordinates \
        +                                                ec_GF2m_smp_set_compr_coords
        +#undef ec_GFp_simple_group_set_curve_GFp
        +#define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
        +#undef ec_GFp_simple_group_get_curve_GFp
        +#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
        +#undef ec_GFp_simple_group_clear_finish
        +#define ec_GFp_simple_group_clear_finish	ec_GFp_simple_grp_clear_finish
        +#undef ec_GFp_simple_group_set_generator
        +#define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
        +#undef ec_GFp_simple_group_get0_generator
        +#define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
        +#undef ec_GFp_simple_group_get_cofactor
        +#define ec_GFp_simple_group_get_cofactor	ec_GFp_simple_grp_get_cofactor
        +#undef ec_GFp_simple_point_clear_finish
        +#define ec_GFp_simple_point_clear_finish	ec_GFp_simple_pt_clear_finish
        +#undef ec_GFp_simple_point_set_to_infinity
        +#define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
        +#undef ec_GFp_simple_points_make_affine
        +#define ec_GFp_simple_points_make_affine	ec_GFp_simple_pts_make_affine
        +#undef ec_GFp_simple_set_Jprojective_coordinates_GFp
        +#define ec_GFp_simple_set_Jprojective_coordinates_GFp \
        +                                                ec_GFp_smp_set_Jproj_coords_GFp
        +#undef ec_GFp_simple_get_Jprojective_coordinates_GFp
        +#define ec_GFp_simple_get_Jprojective_coordinates_GFp \
        +                                                ec_GFp_smp_get_Jproj_coords_GFp
        +#undef ec_GFp_simple_point_set_affine_coordinates_GFp
        +#define ec_GFp_simple_point_set_affine_coordinates_GFp \
        +                                                ec_GFp_smp_pt_set_af_coords_GFp
        +#undef ec_GFp_simple_point_get_affine_coordinates_GFp
        +#define ec_GFp_simple_point_get_affine_coordinates_GFp \
        +                                                ec_GFp_smp_pt_get_af_coords_GFp
        +#undef ec_GFp_simple_set_compressed_coordinates_GFp
        +#define ec_GFp_simple_set_compressed_coordinates_GFp \
        +                                                ec_GFp_smp_set_compr_coords_GFp
        +#undef ec_GFp_simple_point_set_affine_coordinates
        +#define ec_GFp_simple_point_set_affine_coordinates \
        +                                                ec_GFp_smp_pt_set_af_coords
        +#undef ec_GFp_simple_point_get_affine_coordinates
        +#define ec_GFp_simple_point_get_affine_coordinates \
        +                                                ec_GFp_smp_pt_get_af_coords
        +#undef ec_GFp_simple_set_compressed_coordinates
        +#define ec_GFp_simple_set_compressed_coordinates \
        +                                                ec_GFp_smp_set_compr_coords
        +#undef ec_GFp_simple_group_check_discriminant
        +#define ec_GFp_simple_group_check_discriminant	ec_GFp_simple_grp_chk_discrim
        +
        +/* Hack som long STORE names */
        +#undef STORE_method_set_initialise_function
        +#define STORE_method_set_initialise_function	STORE_meth_set_initialise_fn
        +#undef STORE_method_set_cleanup_function
        +#define STORE_method_set_cleanup_function	STORE_meth_set_cleanup_fn
        +#undef STORE_method_set_generate_function
        +#define STORE_method_set_generate_function	STORE_meth_set_generate_fn
        +#undef STORE_method_set_modify_function
        +#define STORE_method_set_modify_function	STORE_meth_set_modify_fn
        +#undef STORE_method_set_revoke_function
        +#define STORE_method_set_revoke_function	STORE_meth_set_revoke_fn
        +#undef STORE_method_set_delete_function
        +#define STORE_method_set_delete_function	STORE_meth_set_delete_fn
        +#undef STORE_method_set_list_start_function
        +#define STORE_method_set_list_start_function	STORE_meth_set_list_start_fn
        +#undef STORE_method_set_list_next_function
        +#define STORE_method_set_list_next_function	STORE_meth_set_list_next_fn
        +#undef STORE_method_set_list_end_function
        +#define STORE_method_set_list_end_function	STORE_meth_set_list_end_fn
        +#undef STORE_method_set_update_store_function
        +#define STORE_method_set_update_store_function	STORE_meth_set_update_store_fn
        +#undef STORE_method_set_lock_store_function
        +#define STORE_method_set_lock_store_function	STORE_meth_set_lock_store_fn
        +#undef STORE_method_set_unlock_store_function
        +#define STORE_method_set_unlock_store_function	STORE_meth_set_unlock_store_fn
        +#undef STORE_method_get_initialise_function
        +#define STORE_method_get_initialise_function	STORE_meth_get_initialise_fn
        +#undef STORE_method_get_cleanup_function
        +#define STORE_method_get_cleanup_function	STORE_meth_get_cleanup_fn
        +#undef STORE_method_get_generate_function
        +#define STORE_method_get_generate_function	STORE_meth_get_generate_fn
        +#undef STORE_method_get_modify_function
        +#define STORE_method_get_modify_function	STORE_meth_get_modify_fn
        +#undef STORE_method_get_revoke_function
        +#define STORE_method_get_revoke_function	STORE_meth_get_revoke_fn
        +#undef STORE_method_get_delete_function
        +#define STORE_method_get_delete_function	STORE_meth_get_delete_fn
        +#undef STORE_method_get_list_start_function
        +#define STORE_method_get_list_start_function	STORE_meth_get_list_start_fn
        +#undef STORE_method_get_list_next_function
        +#define STORE_method_get_list_next_function	STORE_meth_get_list_next_fn
        +#undef STORE_method_get_list_end_function
        +#define STORE_method_get_list_end_function	STORE_meth_get_list_end_fn
        +#undef STORE_method_get_update_store_function
        +#define STORE_method_get_update_store_function	STORE_meth_get_update_store_fn
        +#undef STORE_method_get_lock_store_function
        +#define STORE_method_get_lock_store_function	STORE_meth_get_lock_store_fn
        +#undef STORE_method_get_unlock_store_function
        +#define STORE_method_get_unlock_store_function	STORE_meth_get_unlock_store_fn
        +
        +/* Hack some long TS names */
        +#undef TS_RESP_CTX_set_status_info_cond
        +#define TS_RESP_CTX_set_status_info_cond	TS_RESP_CTX_set_stat_info_cond
        +#undef TS_RESP_CTX_set_clock_precision_digits
        +#define TS_RESP_CTX_set_clock_precision_digits	TS_RESP_CTX_set_clk_prec_digits
        +#undef TS_CONF_set_clock_precision_digits
        +#define TS_CONF_set_clock_precision_digits	TS_CONF_set_clk_prec_digits
        +
        +/* Hack some long CMS names */
        +#undef CMS_RecipientInfo_ktri_get0_algs
        +#define CMS_RecipientInfo_ktri_get0_algs	CMS_RecipInfo_ktri_get0_algs
        +#undef CMS_RecipientInfo_ktri_get0_signer_id
        +#define CMS_RecipientInfo_ktri_get0_signer_id	CMS_RecipInfo_ktri_get0_sigr_id
        +#undef CMS_OtherRevocationInfoFormat_it
        +#define CMS_OtherRevocationInfoFormat_it	CMS_OtherRevocInfoFormat_it
        +#undef CMS_KeyAgreeRecipientIdentifier_it
        +#define CMS_KeyAgreeRecipientIdentifier_it	CMS_KeyAgreeRecipIdentifier_it
        +#undef CMS_OriginatorIdentifierOrKey_it
        +#define CMS_OriginatorIdentifierOrKey_it	CMS_OriginatorIdOrKey_it
        +#undef cms_SignerIdentifier_get0_signer_id
        +#define cms_SignerIdentifier_get0_signer_id	cms_SignerId_get0_signer_id
        +
        +/* Hack some long DTLS1 names */
        +#undef dtls1_retransmit_buffered_messages
        +#define dtls1_retransmit_buffered_messages	dtls1_retransmit_buffered_msgs
        +
        +/* Hack some long SRP names */
        +#undef SRP_generate_server_master_secret
        +#define SRP_generate_server_master_secret	SRP_gen_server_master_secret
        +#undef SRP_generate_client_master_secret
        +#define SRP_generate_client_master_secret	SRP_gen_client_master_secret
        +
        +/* Hack some long UI names */
        +#undef UI_method_get_prompt_constructor
        +#define UI_method_get_prompt_constructor	UI_method_get_prompt_constructr
        +#undef UI_method_set_prompt_constructor
        +#define UI_method_set_prompt_constructor	UI_method_set_prompt_constructr
        +
        +#endif /* defined OPENSSL_SYS_VMS */
        +
        +
        +/* Case insensitive linking causes problems.... */
        +#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
        +#undef ERR_load_CRYPTO_strings
        +#define ERR_load_CRYPTO_strings			ERR_load_CRYPTOlib_strings
        +#undef OCSP_crlID_new
        +#define OCSP_crlID_new				OCSP_crlID2_new
        +
        +#undef d2i_ECPARAMETERS
        +#define d2i_ECPARAMETERS			d2i_UC_ECPARAMETERS
        +#undef i2d_ECPARAMETERS
        +#define i2d_ECPARAMETERS			i2d_UC_ECPARAMETERS
        +#undef d2i_ECPKPARAMETERS
        +#define d2i_ECPKPARAMETERS			d2i_UC_ECPKPARAMETERS
        +#undef i2d_ECPKPARAMETERS
        +#define i2d_ECPKPARAMETERS			i2d_UC_ECPKPARAMETERS
        +
        +/* These functions do not seem to exist!  However, I'm paranoid...
        +   Original command in x509v3.h:
        +   These functions are being redefined in another directory,
        +   and clash when the linker is case-insensitive, so let's
        +   hide them a little, by giving them an extra 'o' at the
        +   beginning of the name... */
        +#undef X509v3_cleanup_extensions
        +#define X509v3_cleanup_extensions		oX509v3_cleanup_extensions
        +#undef X509v3_add_extension
        +#define X509v3_add_extension			oX509v3_add_extension
        +#undef X509v3_add_netscape_extensions
        +#define X509v3_add_netscape_extensions		oX509v3_add_netscape_extensions
        +#undef X509v3_add_standard_extensions
        +#define X509v3_add_standard_extensions		oX509v3_add_standard_extensions
        +
        +/* This one clashes with CMS_data_create */
        +#undef cms_Data_create
        +#define cms_Data_create				priv_cms_Data_create
        +
        +#endif
        +
        +
        +#endif /* ! defined HEADER_VMS_IDHACKS_H */
        diff --git a/vendor/openssl/openssl/crypto/threads/README b/vendor/openssl/openssl/crypto/threads/README
        new file mode 100644
        index 000000000..df6b26e14
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/README
        @@ -0,0 +1,14 @@
        +Mutithreading testing area.
        +
        +Since this stuff is very very platorm specific, this is not part of the
        +normal build.  Have a read of doc/threads.doc.
        +
        +mttest will do some testing and will currently build under Windows NT/95,
        +Solaris and Linux.  The IRIX stuff is not finished.
        +
        +I have tested this program on a 12 CPU ultra sparc box (solaris 2.5.1)
        +and things seem to work ok.
        +
        +The Linux pthreads package can be retrieved from 
        +http://www.mit.edu:8001/people/proven/pthreads.html
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/mttest.c b/vendor/openssl/openssl/crypto/threads/mttest.c
        new file mode 100644
        index 000000000..eba7aa8a6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/mttest.c
        @@ -0,0 +1,1310 @@
        +/* crypto/threads/mttest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <errno.h>
        +#ifdef LINUX
        +#include <typedefs.h>
        +#endif
        +#ifdef OPENSSL_SYS_WIN32
        +#include <windows.h>
        +#endif
        +#ifdef SOLARIS
        +#include <synch.h>
        +#include <thread.h>
        +#endif
        +#ifdef IRIX
        +#include <ulocks.h>
        +#include <sys/prctl.h>
        +#endif
        +#ifdef PTHREADS
        +#include <pthread.h>
        +#endif
        +#ifdef OPENSSL_SYS_NETWARE
        +#if !defined __int64
        +#  define __int64 long long
        +#endif   
        +#include <nwmpk.h>
        +#endif
        +#include <openssl/lhash.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include "../../e_os.h"
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +
        +#ifdef OPENSSL_NO_FP_API
        +#define APPS_WIN16
        +#include "../buffer/bss_file.c"
        +#endif
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +#define TEST_SERVER_CERT "/openssl/apps/server.pem"
        +#define TEST_CLIENT_CERT "/openssl/apps/client.pem"
        +#else
        +#define TEST_SERVER_CERT "../../apps/server.pem"
        +#define TEST_CLIENT_CERT "../../apps/client.pem"
        +#endif
        +
        +#define MAX_THREAD_NUMBER	100
        +
        +int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs);
        +void thread_setup(void);
        +void thread_cleanup(void);
        +void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx);
        +
        +void irix_locking_callback(int mode,int type,char *file,int line);
        +void solaris_locking_callback(int mode,int type,char *file,int line);
        +void win32_locking_callback(int mode,int type,char *file,int line);
        +void pthreads_locking_callback(int mode,int type,char *file,int line);
        +void netware_locking_callback(int mode,int type,char *file,int line);
        +void beos_locking_callback(int mode,int type,const char *file,int line);
        +
        +unsigned long irix_thread_id(void );
        +unsigned long solaris_thread_id(void );
        +unsigned long pthreads_thread_id(void );
        +unsigned long netware_thread_id(void );
        +unsigned long beos_thread_id(void );
        +
        +#if defined(OPENSSL_SYS_NETWARE)
        +static MPKMutex *lock_cs;
        +static MPKSema ThreadSem;
        +static long *lock_count;
        +#endif
        +
        +BIO *bio_err=NULL;
        +BIO *bio_stdout=NULL;
        +
        +static char *cipher=NULL;
        +int verbose=0;
        +#ifdef FIONBIO
        +static int s_nbio=0;
        +#endif
        +
        +int thread_number=10;
        +int number_of_loops=10;
        +int reconnect=0;
        +int cache_stats=0;
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int doit(char *ctx[4]);
        +static void print_stats(FILE *fp, SSL_CTX *ctx)
        +{
        +	fprintf(fp,"%4ld items in the session cache\n",
        +		SSL_CTX_sess_number(ctx));
        +	fprintf(fp,"%4d client connects (SSL_connect())\n",
        +		SSL_CTX_sess_connect(ctx));
        +	fprintf(fp,"%4d client connects that finished\n",
        +		SSL_CTX_sess_connect_good(ctx));
        +	fprintf(fp,"%4d server connects (SSL_accept())\n",
        +		SSL_CTX_sess_accept(ctx));
        +	fprintf(fp,"%4d server connects that finished\n",
        +		SSL_CTX_sess_accept_good(ctx));
        +	fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx));
        +	fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx));
        +	fprintf(fp,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ctx));
        +	}
        +
        +static void sv_usage(void)
        +	{
        +	fprintf(stderr,"usage: ssltest [args ...]\n");
        +	fprintf(stderr,"\n");
        +	fprintf(stderr," -server_auth  - check server certificate\n");
        +	fprintf(stderr," -client_auth  - do client authentication\n");
        +	fprintf(stderr," -v            - more output\n");
        +	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
        +	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
        +	fprintf(stderr," -threads arg  - number of threads\n");
        +	fprintf(stderr," -loops arg    - number of 'connections', per thread\n");
        +	fprintf(stderr," -reconnect    - reuse session-id's\n");
        +	fprintf(stderr," -stats        - server session-id cache stats\n");
        +	fprintf(stderr," -cert arg     - server certificate/key\n");
        +	fprintf(stderr," -ccert arg    - client certificate/key\n");
        +	fprintf(stderr," -ssl3         - just SSLv3n\n");
        +	}
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *CApath=NULL,*CAfile=NULL;
        +	int badop=0;
        +	int ret=1;
        +	int client_auth=0;
        +	int server_auth=0;
        +	SSL_CTX *s_ctx=NULL;
        +	SSL_CTX *c_ctx=NULL;
        +	char *scert=TEST_SERVER_CERT;
        +	char *ccert=TEST_CLIENT_CERT;
        +	SSL_METHOD *ssl_method=SSLv23_method();
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +	if (bio_stdout == NULL)
        +		bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
        +	argc--;
        +	argv++;
        +
        +	while (argc >= 1)
        +		{
        +		if	(strcmp(*argv,"-server_auth") == 0)
        +			server_auth=1;
        +		else if	(strcmp(*argv,"-client_auth") == 0)
        +			client_auth=1;
        +		else if	(strcmp(*argv,"-reconnect") == 0)
        +			reconnect=1;
        +		else if	(strcmp(*argv,"-stats") == 0)
        +			cache_stats=1;
        +		else if	(strcmp(*argv,"-ssl3") == 0)
        +			ssl_method=SSLv3_method();
        +		else if	(strcmp(*argv,"-ssl2") == 0)
        +			ssl_method=SSLv2_method();
        +		else if	(strcmp(*argv,"-CApath") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CApath= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CAfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			scert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-ccert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			ccert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-threads") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			thread_number= atoi(*(++argv));
        +			if (thread_number == 0) thread_number=1;
        +			if (thread_number > MAX_THREAD_NUMBER)
        +				thread_number=MAX_THREAD_NUMBER;
        +			}
        +		else if	(strcmp(*argv,"-loops") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			number_of_loops= atoi(*(++argv));
        +			if (number_of_loops == 0) number_of_loops=1;
        +			}
        +		else
        +			{
        +			fprintf(stderr,"unknown option %s\n",*argv);
        +			badop=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +	if (badop)
        +		{
        +bad:
        +		sv_usage();
        +		goto end;
        +		}
        +
        +	if (cipher == NULL && OPENSSL_issetugid() == 0)
        +		cipher=getenv("SSL_CIPHER");
        +
        +	SSL_load_error_strings();
        +	OpenSSL_add_ssl_algorithms();
        +
        +	c_ctx=SSL_CTX_new(ssl_method);
        +	s_ctx=SSL_CTX_new(ssl_method);
        +	if ((c_ctx == NULL) || (s_ctx == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	SSL_CTX_set_session_cache_mode(s_ctx,
        +		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
        +	SSL_CTX_set_session_cache_mode(c_ctx,
        +		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
        +
        +	if (!SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM))
        +		{
        +		ERR_print_errors(bio_err);
        +		}
        +	else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (client_auth)
        +		{
        +		SSL_CTX_use_certificate_file(c_ctx,ccert,
        +			SSL_FILETYPE_PEM);
        +		SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
        +			SSL_FILETYPE_PEM);
        +		}
        +
        +	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
        +		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(c_ctx)))
        +		{
        +		fprintf(stderr,"SSL_load_verify_locations\n");
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (client_auth)
        +		{
        +		fprintf(stderr,"client authentication\n");
        +		SSL_CTX_set_verify(s_ctx,
        +			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
        +			verify_callback);
        +		}
        +	if (server_auth)
        +		{
        +		fprintf(stderr,"server authentication\n");
        +		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
        +			verify_callback);
        +		}
        +
        +	thread_setup();
        +	do_threads(s_ctx,c_ctx);
        +	thread_cleanup();
        +end:
        +	
        +	if (c_ctx != NULL) 
        +		{
        +		fprintf(stderr,"Client SSL_CTX stats then free it\n");
        +		print_stats(stderr,c_ctx);
        +		SSL_CTX_free(c_ctx);
        +		}
        +	if (s_ctx != NULL)
        +		{
        +		fprintf(stderr,"Server SSL_CTX stats then free it\n");
        +		print_stats(stderr,s_ctx);
        +		if (cache_stats)
        +			{
        +			fprintf(stderr,"-----\n");
        +			lh_stats(SSL_CTX_sessions(s_ctx),stderr);
        +			fprintf(stderr,"-----\n");
        +		/*	lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
        +			fprintf(stderr,"-----\n"); */
        +			lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
        +			fprintf(stderr,"-----\n");
        +			}
        +		SSL_CTX_free(s_ctx);
        +		fprintf(stderr,"done free\n");
        +		}
        +	exit(ret);
        +	return(0);
        +	}
        +
        +#define W_READ	1
        +#define W_WRITE	2
        +#define C_DONE	1
        +#define S_DONE	2
        +
        +int ndoit(SSL_CTX *ssl_ctx[2])
        +	{
        +	int i;
        +	int ret;
        +	char *ctx[4];
        +
        +	ctx[0]=(char *)ssl_ctx[0];
        +	ctx[1]=(char *)ssl_ctx[1];
        +
        +	if (reconnect)
        +		{
        +		ctx[2]=(char *)SSL_new(ssl_ctx[0]);
        +		ctx[3]=(char *)SSL_new(ssl_ctx[1]);
        +		}
        +	else
        +		{
        +		ctx[2]=NULL;
        +		ctx[3]=NULL;
        +		}
        +
        +	fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id());
        +	for (i=0; i<number_of_loops; i++)
        +		{
        +/*		fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
        +			CRYPTO_thread_id(),i,
        +			ssl_ctx[0]->references,
        +			ssl_ctx[1]->references); */
        +	/*	pthread_delay_np(&tm);*/
        +
        +		ret=doit(ctx);
        +		if (ret != 0)
        +			{
        +			fprintf(stdout,"error[%d] %lu - %d\n",
        +				i,CRYPTO_thread_id(),ret);
        +			return(ret);
        +			}
        +		}
        +	fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
        +	if (reconnect)
        +		{
        +		SSL_free((SSL *)ctx[2]);
        +		SSL_free((SSL *)ctx[3]);
        +		}
        +#   ifdef OPENSSL_SYS_NETWARE
        +        MPKSemaphoreSignal(ThreadSem);
        +#   endif
        +	return(0);
        +	}
        +
        +int doit(char *ctx[4])
        +	{
        +	SSL_CTX *s_ctx,*c_ctx;
        +	static char cbuf[200],sbuf[200];
        +	SSL *c_ssl=NULL;
        +	SSL *s_ssl=NULL;
        +	BIO *c_to_s=NULL;
        +	BIO *s_to_c=NULL;
        +	BIO *c_bio=NULL;
        +	BIO *s_bio=NULL;
        +	int c_r,c_w,s_r,s_w;
        +	int c_want,s_want;
        +	int i;
        +	int done=0;
        +	int c_write,s_write;
        +	int do_server=0,do_client=0;
        +
        +	s_ctx=(SSL_CTX *)ctx[0];
        +	c_ctx=(SSL_CTX *)ctx[1];
        +
        +	if (ctx[2] != NULL)
        +		s_ssl=(SSL *)ctx[2];
        +	else
        +		s_ssl=SSL_new(s_ctx);
        +
        +	if (ctx[3] != NULL)
        +		c_ssl=(SSL *)ctx[3];
        +	else
        +		c_ssl=SSL_new(c_ctx);
        +
        +	if ((s_ssl == NULL) || (c_ssl == NULL)) goto err;
        +
        +	c_to_s=BIO_new(BIO_s_mem());
        +	s_to_c=BIO_new(BIO_s_mem());
        +	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
        +
        +	c_bio=BIO_new(BIO_f_ssl());
        +	s_bio=BIO_new(BIO_f_ssl());
        +	if ((c_bio == NULL) || (s_bio == NULL)) goto err;
        +
        +	SSL_set_connect_state(c_ssl);
        +	SSL_set_bio(c_ssl,s_to_c,c_to_s);
        +	BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
        +
        +	SSL_set_accept_state(s_ssl);
        +	SSL_set_bio(s_ssl,c_to_s,s_to_c);
        +	BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
        +
        +	c_r=0; s_r=1;
        +	c_w=1; s_w=0;
        +	c_want=W_WRITE;
        +	s_want=0;
        +	c_write=1,s_write=0;
        +
        +	/* We can always do writes */
        +	for (;;)
        +		{
        +		do_server=0;
        +		do_client=0;
        +
        +		i=(int)BIO_pending(s_bio);
        +		if ((i && s_r) || s_w) do_server=1;
        +
        +		i=(int)BIO_pending(c_bio);
        +		if ((i && c_r) || c_w) do_client=1;
        +
        +		if (do_server && verbose)
        +			{
        +			if (SSL_in_init(s_ssl))
        +				printf("server waiting in SSL_accept - %s\n",
        +					SSL_state_string_long(s_ssl));
        +			else if (s_write)
        +				printf("server:SSL_write()\n");
        +			else 
        +				printf("server:SSL_read()\n");
        +			}
        +
        +		if (do_client && verbose)
        +			{
        +			if (SSL_in_init(c_ssl))
        +				printf("client waiting in SSL_connect - %s\n",
        +					SSL_state_string_long(c_ssl));
        +			else if (c_write)
        +				printf("client:SSL_write()\n");
        +			else
        +				printf("client:SSL_read()\n");
        +			}
        +
        +		if (!do_client && !do_server)
        +			{
        +			fprintf(stdout,"ERROR IN STARTUP\n");
        +			break;
        +			}
        +		if (do_client && !(done & C_DONE))
        +			{
        +			if (c_write)
        +				{
        +				i=BIO_write(c_bio,"hello from client\n",18);
        +				if (i < 0)
        +					{
        +					c_r=0;
        +					c_w=0;
        +					if (BIO_should_retry(c_bio))
        +						{
        +						if (BIO_should_read(c_bio))
        +							c_r=1;
        +						if (BIO_should_write(c_bio))
        +							c_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						ERR_print_errors_fp(stderr);
        +						return(1);
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					return(1);
        +					}
        +				else
        +					{
        +					/* ok */
        +					c_write=0;
        +					}
        +				}
        +			else
        +				{
        +				i=BIO_read(c_bio,cbuf,100);
        +				if (i < 0)
        +					{
        +					c_r=0;
        +					c_w=0;
        +					if (BIO_should_retry(c_bio))
        +						{
        +						if (BIO_should_read(c_bio))
        +							c_r=1;
        +						if (BIO_should_write(c_bio))
        +							c_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						ERR_print_errors_fp(stderr);
        +						return(1);
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					return(1);
        +					}
        +				else
        +					{
        +					done|=C_DONE;
        +#ifdef undef
        +					fprintf(stdout,"CLIENT:from server:");
        +					fwrite(cbuf,1,i,stdout);
        +					fflush(stdout);
        +#endif
        +					}
        +				}
        +			}
        +
        +		if (do_server && !(done & S_DONE))
        +			{
        +			if (!s_write)
        +				{
        +				i=BIO_read(s_bio,sbuf,100);
        +				if (i < 0)
        +					{
        +					s_r=0;
        +					s_w=0;
        +					if (BIO_should_retry(s_bio))
        +						{
        +						if (BIO_should_read(s_bio))
        +							s_r=1;
        +						if (BIO_should_write(s_bio))
        +							s_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						ERR_print_errors_fp(stderr);
        +						return(1);
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
        +					return(1);
        +					}
        +				else
        +					{
        +					s_write=1;
        +					s_w=1;
        +#ifdef undef
        +					fprintf(stdout,"SERVER:from client:");
        +					fwrite(sbuf,1,i,stdout);
        +					fflush(stdout);
        +#endif
        +					}
        +				}
        +			else
        +				{
        +				i=BIO_write(s_bio,"hello from server\n",18);
        +				if (i < 0)
        +					{
        +					s_r=0;
        +					s_w=0;
        +					if (BIO_should_retry(s_bio))
        +						{
        +						if (BIO_should_read(s_bio))
        +							s_r=1;
        +						if (BIO_should_write(s_bio))
        +							s_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						ERR_print_errors_fp(stderr);
        +						return(1);
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
        +					return(1);
        +					}
        +				else
        +					{
        +					s_write=0;
        +					s_r=1;
        +					done|=S_DONE;
        +					}
        +				}
        +			}
        +
        +		if ((done & S_DONE) && (done & C_DONE)) break;
        +#   if defined(OPENSSL_SYS_NETWARE)
        +        ThreadSwitchWithDelay();
        +#   endif
        +		}
        +
        +	SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +	SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +
        +#ifdef undef
        +	fprintf(stdout,"DONE\n");
        +#endif
        +err:
        +	/* We have to set the BIO's to NULL otherwise they will be
        +	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
        +	 * again when c_ssl is SSL_free()ed.
        +	 * This is a hack required because s_ssl and c_ssl are sharing the same
        +	 * BIO structure and SSL_set_bio() and SSL_free() automatically
        +	 * BIO_free non NULL entries.
        +	 * You should not normally do this or be required to do this */
        +
        +	if (s_ssl != NULL)
        +		{
        +		s_ssl->rbio=NULL;
        +		s_ssl->wbio=NULL;
        +		}
        +	if (c_ssl != NULL)
        +		{
        +		c_ssl->rbio=NULL;
        +		c_ssl->wbio=NULL;
        +		}
        +
        +	/* The SSL's are optionally freed in the following calls */
        +	if (c_to_s != NULL) BIO_free(c_to_s);
        +	if (s_to_c != NULL) BIO_free(s_to_c);
        +
        +	if (c_bio != NULL) BIO_free(c_bio);
        +	if (s_bio != NULL) BIO_free(s_bio);
        +	return(0);
        +	}
        +
        +int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	char *s, buf[256];
        +
        +	if (verbose)
        +		{
        +		s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
        +				    buf,256);
        +		if (s != NULL)
        +			{
        +			if (ok)
        +				fprintf(stderr,"depth=%d %s\n",
        +					ctx->error_depth,buf);
        +			else
        +				fprintf(stderr,"depth=%d error=%d %s\n",
        +					ctx->error_depth,ctx->error,buf);
        +			}
        +		}
        +	return(ok);
        +	}
        +
        +#define THREAD_STACK_SIZE (16*1024)
        +
        +#ifdef OPENSSL_SYS_WIN32
        +
        +static HANDLE *lock_cs;
        +
        +void thread_setup(void)
        +	{
        +	int i;
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
        +		}
        +
        +	CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
        +	/* id callback defined */
        +	}
        +
        +void thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		CloseHandle(lock_cs[i]);
        +	OPENSSL_free(lock_cs);
        +	}
        +
        +void win32_locking_callback(int mode, int type, char *file, int line)
        +	{
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		WaitForSingleObject(lock_cs[type],INFINITE);
        +		}
        +	else
        +		{
        +		ReleaseMutex(lock_cs[type]);
        +		}
        +	}
        +
        +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
        +	{
        +	double ret;
        +	SSL_CTX *ssl_ctx[2];
        +	DWORD thread_id[MAX_THREAD_NUMBER];
        +	HANDLE thread_handle[MAX_THREAD_NUMBER];
        +	int i;
        +	SYSTEMTIME start,end;
        +
        +	ssl_ctx[0]=s_ctx;
        +	ssl_ctx[1]=c_ctx;
        +
        +	GetSystemTime(&start);
        +	for (i=0; i<thread_number; i++)
        +		{
        +		thread_handle[i]=CreateThread(NULL,
        +			THREAD_STACK_SIZE,
        +			(LPTHREAD_START_ROUTINE)ndoit,
        +			(void *)ssl_ctx,
        +			0L,
        +			&(thread_id[i]));
        +		}
        +
        +	printf("reaping\n");
        +	for (i=0; i<thread_number; i+=50)
        +		{
        +		int j;
        +
        +		j=(thread_number < (i+50))?(thread_number-i):50;
        +
        +		if (WaitForMultipleObjects(j,
        +			(CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE)
        +			== WAIT_FAILED)
        +			{
        +			fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError());
        +			exit(1);
        +			}
        +		}
        +	GetSystemTime(&end);
        +
        +	if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7;
        +	ret=(end.wDayOfWeek-start.wDayOfWeek)*24;
        +
        +	ret=(ret+end.wHour-start.wHour)*60;
        +	ret=(ret+end.wMinute-start.wMinute)*60;
        +	ret=(ret+end.wSecond-start.wSecond);
        +	ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0;
        +
        +	printf("win32 threads done - %.3f seconds\n",ret);
        +	}
        +
        +#endif /* OPENSSL_SYS_WIN32 */
        +
        +#ifdef SOLARIS
        +
        +static mutex_t *lock_cs;
        +/*static rwlock_t *lock_cs; */
        +static long *lock_count;
        +
        +void thread_setup(void)
        +	{
        +	int i;
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
        +	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_count[i]=0;
        +		/* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */
        +		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
        +	}
        +
        +void thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +
        +	fprintf(stderr,"cleanup\n");
        +
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		/* rwlock_destroy(&(lock_cs[i])); */
        +		mutex_destroy(&(lock_cs[i]));
        +		fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
        +		}
        +	OPENSSL_free(lock_cs);
        +	OPENSSL_free(lock_count);
        +
        +	fprintf(stderr,"done cleanup\n");
        +
        +	}
        +
        +void solaris_locking_callback(int mode, int type, char *file, int line)
        +	{
        +#ifdef undef
        +	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
        +		CRYPTO_thread_id(),
        +		(mode&CRYPTO_LOCK)?"l":"u",
        +		(type&CRYPTO_READ)?"r":"w",file,line);
        +#endif
        +
        +	/*
        +	if (CRYPTO_LOCK_SSL_CERT == type)
        +	fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
        +		CRYPTO_thread_id(),
        +		mode,file,line);
        +	*/
        +	if (mode & CRYPTO_LOCK)
        +		{
        +	/*	if (mode & CRYPTO_READ)
        +			rw_rdlock(&(lock_cs[type]));
        +		else
        +			rw_wrlock(&(lock_cs[type])); */
        +
        +		mutex_lock(&(lock_cs[type]));
        +		lock_count[type]++;
        +		}
        +	else
        +		{
        +/*		rw_unlock(&(lock_cs[type]));  */
        +		mutex_unlock(&(lock_cs[type]));
        +		}
        +	}
        +
        +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
        +	{
        +	SSL_CTX *ssl_ctx[2];
        +	thread_t thread_ctx[MAX_THREAD_NUMBER];
        +	int i;
        +
        +	ssl_ctx[0]=s_ctx;
        +	ssl_ctx[1]=c_ctx;
        +
        +	thr_setconcurrency(thread_number);
        +	for (i=0; i<thread_number; i++)
        +		{
        +		thr_create(NULL, THREAD_STACK_SIZE,
        +			(void *(*)())ndoit,
        +			(void *)ssl_ctx,
        +			0L,
        +			&(thread_ctx[i]));
        +		}
        +
        +	printf("reaping\n");
        +	for (i=0; i<thread_number; i++)
        +		{
        +		thr_join(thread_ctx[i],NULL,NULL);
        +		}
        +
        +	printf("solaris threads done (%d,%d)\n",
        +		s_ctx->references,c_ctx->references);
        +	}
        +
        +unsigned long solaris_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)thr_self();
        +	return(ret);
        +	}
        +#endif /* SOLARIS */
        +
        +#ifdef IRIX
        +
        +
        +static usptr_t *arena;
        +static usema_t **lock_cs;
        +
        +void thread_setup(void)
        +	{
        +	int i;
        +	char filename[20];
        +
        +	strcpy(filename,"/tmp/mttest.XXXXXX");
        +	mktemp(filename);
        +
        +	usconfig(CONF_STHREADIOOFF);
        +	usconfig(CONF_STHREADMALLOCOFF);
        +	usconfig(CONF_INITUSERS,100);
        +	usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
        +	arena=usinit(filename);
        +	unlink(filename);
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_cs[i]=usnewsema(arena,1);
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
        +	}
        +
        +void thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		char buf[10];
        +
        +		sprintf(buf,"%2d:",i);
        +		usdumpsema(lock_cs[i],stdout,buf);
        +		usfreesema(lock_cs[i],arena);
        +		}
        +	OPENSSL_free(lock_cs);
        +	}
        +
        +void irix_locking_callback(int mode, int type, char *file, int line)
        +	{
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		printf("lock %d\n",type);
        +		uspsema(lock_cs[type]);
        +		}
        +	else
        +		{
        +		printf("unlock %d\n",type);
        +		usvsema(lock_cs[type]);
        +		}
        +	}
        +
        +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
        +	{
        +	SSL_CTX *ssl_ctx[2];
        +	int thread_ctx[MAX_THREAD_NUMBER];
        +	int i;
        +
        +	ssl_ctx[0]=s_ctx;
        +	ssl_ctx[1]=c_ctx;
        +
        +	for (i=0; i<thread_number; i++)
        +		{
        +		thread_ctx[i]=sproc((void (*)())ndoit,
        +			PR_SADDR|PR_SFDS,(void *)ssl_ctx);
        +		}
        +
        +	printf("reaping\n");
        +	for (i=0; i<thread_number; i++)
        +		{
        +		wait(NULL);
        +		}
        +
        +	printf("irix threads done (%d,%d)\n",
        +		s_ctx->references,c_ctx->references);
        +	}
        +
        +unsigned long irix_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)getpid();
        +	return(ret);
        +	}
        +#endif /* IRIX */
        +
        +#ifdef PTHREADS
        +
        +static pthread_mutex_t *lock_cs;
        +static long *lock_count;
        +
        +void thread_setup(void)
        +	{
        +	int i;
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
        +	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_count[i]=0;
        +		pthread_mutex_init(&(lock_cs[i]),NULL);
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
        +	}
        +
        +void thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	fprintf(stderr,"cleanup\n");
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		pthread_mutex_destroy(&(lock_cs[i]));
        +		fprintf(stderr,"%8ld:%s\n",lock_count[i],
        +			CRYPTO_get_lock_name(i));
        +		}
        +	OPENSSL_free(lock_cs);
        +	OPENSSL_free(lock_count);
        +
        +	fprintf(stderr,"done cleanup\n");
        +	}
        +
        +void pthreads_locking_callback(int mode, int type, char *file,
        +	     int line)
        +      {
        +#ifdef undef
        +	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
        +		CRYPTO_thread_id(),
        +		(mode&CRYPTO_LOCK)?"l":"u",
        +		(type&CRYPTO_READ)?"r":"w",file,line);
        +#endif
        +/*
        +	if (CRYPTO_LOCK_SSL_CERT == type)
        +		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
        +		CRYPTO_thread_id(),
        +		mode,file,line);
        +*/
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		pthread_mutex_lock(&(lock_cs[type]));
        +		lock_count[type]++;
        +		}
        +	else
        +		{
        +		pthread_mutex_unlock(&(lock_cs[type]));
        +		}
        +	}
        +
        +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
        +	{
        +	SSL_CTX *ssl_ctx[2];
        +	pthread_t thread_ctx[MAX_THREAD_NUMBER];
        +	int i;
        +
        +	ssl_ctx[0]=s_ctx;
        +	ssl_ctx[1]=c_ctx;
        +
        +	/*
        +	thr_setconcurrency(thread_number);
        +	*/
        +	for (i=0; i<thread_number; i++)
        +		{
        +		pthread_create(&(thread_ctx[i]), NULL,
        +			(void *(*)())ndoit, (void *)ssl_ctx);
        +		}
        +
        +	printf("reaping\n");
        +	for (i=0; i<thread_number; i++)
        +		{
        +		pthread_join(thread_ctx[i],NULL);
        +		}
        +
        +	printf("pthreads threads done (%d,%d)\n",
        +		s_ctx->references,c_ctx->references);
        +	}
        +
        +unsigned long pthreads_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)pthread_self();
        +	return(ret);
        +	}
        +
        +#endif /* PTHREADS */
        +
        +
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +
        +void thread_setup(void)
        +{
        +   int i;
        +
        +   lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex));
        +   lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
        +   for (i=0; i<CRYPTO_num_locks(); i++)
        +   {
        +      lock_count[i]=0;
        +      lock_cs[i]=MPKMutexAlloc("OpenSSL mutex");
        +   }
        +
        +   ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 );
        +
        +   CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id);
        +   CRYPTO_set_locking_callback((void (*)())netware_locking_callback);
        +}
        +
        +void thread_cleanup(void)
        +{
        +   int i;
        +
        +   CRYPTO_set_locking_callback(NULL);
        +
        +   fprintf(stdout,"thread_cleanup\n");
        +
        +   for (i=0; i<CRYPTO_num_locks(); i++)
        +   {
        +      MPKMutexFree(lock_cs[i]);
        +      fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
        +   }
        +   OPENSSL_free(lock_cs);
        +   OPENSSL_free(lock_count);
        +
        +   MPKSemaphoreFree(ThreadSem);
        +
        +   fprintf(stdout,"done cleanup\n");
        +}
        +
        +void netware_locking_callback(int mode, int type, char *file, int line)
        +{
        +   if (mode & CRYPTO_LOCK)
        +   {
        +      MPKMutexLock(lock_cs[type]);
        +      lock_count[type]++;
        +   }
        +   else
        +      MPKMutexUnlock(lock_cs[type]);
        +}
        +
        +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
        +{
        +   SSL_CTX *ssl_ctx[2];
        +   int i;
        +   ssl_ctx[0]=s_ctx;
        +   ssl_ctx[1]=c_ctx;
        +
        +   for (i=0; i<thread_number; i++)
        +   {
        +      BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE, 
        +                   (void*)ssl_ctx);
        +      ThreadSwitchWithDelay();
        +   }
        +
        +   printf("reaping\n");
        +
        +      /* loop until all threads have signaled the semaphore */
        +   for (i=0; i<thread_number; i++)
        +   {
        +      MPKSemaphoreWait(ThreadSem);
        +   }
        +   printf("netware threads done (%d,%d)\n",
        +         s_ctx->references,c_ctx->references);
        +}
        +
        +unsigned long netware_thread_id(void)
        +{
        +   unsigned long ret;
        +
        +   ret=(unsigned long)GetThreadID();
        +   return(ret);
        +}
        +#endif /* NETWARE */
        +
        +#ifdef BEOS_THREADS
        +
        +#include <Locker.h>
        +
        +static BLocker** lock_cs;
        +static long* lock_count;
        +
        +void thread_setup(void)
        +	{
        +	int i;
        +
        +	lock_cs=(BLocker**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(BLocker*));
        +	lock_count=(long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_count[i]=0;
        +		lock_cs[i] = new BLocker(CRYPTO_get_lock_name(i));
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())beos_thread_id);
        +	CRYPTO_set_locking_callback(beos_locking_callback);
        +	}
        +
        +void thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	fprintf(stderr,"cleanup\n");
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		delete lock_cs[i];
        +		fprintf(stderr,"%8ld:%s\n",lock_count[i],
        +			CRYPTO_get_lock_name(i));
        +		}
        +	OPENSSL_free(lock_cs);
        +	OPENSSL_free(lock_count);
        +
        +	fprintf(stderr,"done cleanup\n");
        +	}
        +
        +void beos_locking_callback(int mode, int type, const char *file, int line)
        +    {
        +#if 0
        +	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
        +		CRYPTO_thread_id(),
        +		(mode&CRYPTO_LOCK)?"l":"u",
        +		(type&CRYPTO_READ)?"r":"w",file,line);
        +#endif
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		lock_cs[type]->Lock();
        +		lock_count[type]++;
        +		}
        +	else
        +		{
        +		lock_cs[type]->Unlock();
        +		}
        +	}
        +
        +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
        +	{
        +	SSL_CTX *ssl_ctx[2];
        +	thread_id thread_ctx[MAX_THREAD_NUMBER];
        +	int i;
        +
        +	ssl_ctx[0]=s_ctx;
        +	ssl_ctx[1]=c_ctx;
        +
        +	for (i=0; i<thread_number; i++)
        +		{
        +		thread_ctx[i] = spawn_thread((thread_func)ndoit,
        +			NULL, B_NORMAL_PRIORITY, (void *)ssl_ctx);
        +		resume_thread(thread_ctx[i]);
        +		}
        +
        +	printf("waiting...\n");
        +	for (i=0; i<thread_number; i++)
        +		{
        +		status_t result;
        +		wait_for_thread(thread_ctx[i], &result);
        +		}
        +
        +	printf("beos threads done (%d,%d)\n",
        +		s_ctx->references,c_ctx->references);
        +	}
        +
        +unsigned long beos_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)find_thread(NULL);
        +	return(ret);
        +	}
        +
        +#endif /* BEOS_THREADS */
        diff --git a/vendor/openssl/openssl/crypto/threads/netware.bat b/vendor/openssl/openssl/crypto/threads/netware.bat
        new file mode 100644
        index 000000000..0b3eca3ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/netware.bat
        @@ -0,0 +1,79 @@
        +@echo off
        +rem batch file to build multi-thread test ( mttest.nlm )
        +
        +rem command line arguments:
        +rem      debug => build using debug settings
        +
        +rem
        +rem After building, copy mttest.nlm to the server and run it, you'll probably
        +rem want to redirect stdout and stderr.  An example command line would be
        +rem "mttest.nlm -thread 20 -loops 10 -CAfile \openssl\apps\server.pem >mttest.out 2>mttest.err"
        +rem 
        +
        +del mttest.nlm
        +
        +set BLD_DEBUG=
        +set CFLAGS=
        +set LFLAGS=
        +set LIBS=
        +
        +if "%1" == "DEBUG" set BLD_DEBUG=YES
        +if "%1" == "debug" set BLD_DEBUG=YES
        +
        +if "%MWCIncludes%" == "" goto inc_error
        +if "%PRELUDE%" == "" goto prelude_error
        +if "%IMPORTS%" == "" goto imports_error
        +
        +set CFLAGS=-c -I..\..\outinc_nw -nosyspath -DOPENSSL_SYS_NETWARE -opt off -g -sym internal -maxerrors 20
        +
        +if "%BLD_DEBUG%" == "YES" set LIBS=..\..\out_nw.dbg\ssl.lib ..\..\out_nw.dbg\crypto.lib
        +if "%BLD_DEBUG%" == ""  set LIBS=..\..\out_nw\ssl.lib ..\..\out_nw\crypto.lib
        +
        +set LFLAGS=-msgstyle gcc -zerobss -stacksize 32768 -nostdlib -sym internal 
        +  
        +rem generate command file for metrowerks
        +echo.
        +echo Generating Metrowerks command file: mttest.def
        +echo # dynamically generated command file for metrowerks build > mttest.def
        +echo IMPORT @%IMPORTS%\clib.imp              >> mttest.def 
        +echo IMPORT @%IMPORTS%\threads.imp           >> mttest.def 
        +echo IMPORT @%IMPORTS%\ws2nlm.imp            >> mttest.def 
        +echo IMPORT GetProcessSwitchCount            >> mttest.def
        +echo MODULE clib                             >> mttest.def 
        +
        +rem compile
        +echo.
        +echo Compiling mttest.c
        +mwccnlm.exe mttest.c %CFLAGS% 
        +if errorlevel 1 goto end
        +
        +rem link               
        +echo.
        +echo Linking mttest.nlm
        +mwldnlm.exe %LFLAGS% -screenname mttest -commandfile mttest.def mttest.o "%PRELUDE%" %LIBS% -o mttest.nlm
        +if errorlevel 1 goto end
        +
        +goto end
        +
        +:inc_error
        +echo.
        +echo Environment variable MWCIncludes is not set - see install.nw
        +goto end
        +
        +:prelude_error
        +echo.
        +echo Environment variable PRELUDE is not set - see install.nw
        +goto end
        +
        +:imports_error
        +echo.
        +echo Environment variable IMPORTS is not set - see install.nw
        +goto end
        +    
        +    
        +:end
        +set BLD_DEBUG=
        +set CFLAGS=
        +set LFLAGS=
        +set LIBS=
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/profile.sh b/vendor/openssl/openssl/crypto/threads/profile.sh
        new file mode 100644
        index 000000000..6e3e342fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/profile.sh
        @@ -0,0 +1,4 @@
        +#!/bin/sh
        +/bin/rm -f mttest
        +cc -p -DSOLARIS -I../../include -g mttest.c -o mttest -L/usr/lib/libc -ldl -L../.. -lthread  -lssl -lcrypto -lnsl -lsocket
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/ptest.bat b/vendor/openssl/openssl/crypto/threads/ptest.bat
        new file mode 100644
        index 000000000..4071b5ffe
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/ptest.bat
        @@ -0,0 +1,4 @@
        +del mttest.exe
        +
        +purify cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssl32.lib ..\..\out\crypt32.lib
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/pthread.sh b/vendor/openssl/openssl/crypto/threads/pthread.sh
        new file mode 100644
        index 000000000..f1c49821d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/pthread.sh
        @@ -0,0 +1,9 @@
        +#!/bin/sh
        +#
        +# build using pthreads
        +#
        +# http://www.mit.edu:8001/people/proven/pthreads.html
        +#
        +/bin/rm -f mttest
        +pgcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto 
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/pthread2.sh b/vendor/openssl/openssl/crypto/threads/pthread2.sh
        new file mode 100644
        index 000000000..41264c6a5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/pthread2.sh
        @@ -0,0 +1,7 @@
        +#!/bin/sh
        +#
        +# build using pthreads where it's already built into the system
        +#
        +/bin/rm -f mttest
        +gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -lpthread
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/pthreads-vms.com b/vendor/openssl/openssl/crypto/threads/pthreads-vms.com
        new file mode 100644
        index 000000000..1cf92bdf5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/pthreads-vms.com
        @@ -0,0 +1,14 @@
        +$! To compile mttest on VMS.
        +$!
        +$! WARNING: only tested with DEC C so far.
        +$
        +$ if (f$getsyi("cpu").lt.128)
        +$ then
        +$     arch := VAX
        +$ else
        +$     arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$     if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$ define/user openssl [--.include.openssl]
        +$ cc/def=PTHREADS mttest.c
        +$ link mttest,[--.'arch'.exe.ssl]libssl/lib,[--.'arch'.exe.crypto]libcrypto/lib
        diff --git a/vendor/openssl/openssl/crypto/threads/purify.sh b/vendor/openssl/openssl/crypto/threads/purify.sh
        new file mode 100644
        index 000000000..6d44fe26b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/purify.sh
        @@ -0,0 +1,4 @@
        +#!/bin/sh
        +/bin/rm -f mttest
        +purify cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread  -lssl -lcrypto -lnsl -lsocket
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/solaris.sh b/vendor/openssl/openssl/crypto/threads/solaris.sh
        new file mode 100644
        index 000000000..bc93094a2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/solaris.sh
        @@ -0,0 +1,4 @@
        +#!/bin/sh
        +/bin/rm -f mttest
        +cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread  -lssl -lcrypto -lnsl -lsocket
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/th-lock.c b/vendor/openssl/openssl/crypto/threads/th-lock.c
        new file mode 100644
        index 000000000..14aae5f91
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/th-lock.c
        @@ -0,0 +1,387 @@
        +/* crypto/threads/th-lock.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <errno.h>
        +#ifdef LINUX
        +#include <typedefs.h>
        +#endif
        +#ifdef OPENSSL_SYS_WIN32
        +#include <windows.h>
        +#endif
        +#ifdef SOLARIS
        +#include <synch.h>
        +#include <thread.h>
        +#endif
        +#ifdef IRIX
        +#include <ulocks.h>
        +#include <sys/prctl.h>
        +#endif
        +#ifdef PTHREADS
        +#include <pthread.h>
        +#endif
        +#include <openssl/lhash.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include "../../e_os.h"
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +
        +void CRYPTO_thread_setup(void);
        +void CRYPTO_thread_cleanup(void);
        +
        +static void irix_locking_callback(int mode,int type,char *file,int line);
        +static void solaris_locking_callback(int mode,int type,char *file,int line);
        +static void win32_locking_callback(int mode,int type,char *file,int line);
        +static void pthreads_locking_callback(int mode,int type,char *file,int line);
        +
        +static unsigned long irix_thread_id(void );
        +static unsigned long solaris_thread_id(void );
        +static unsigned long pthreads_thread_id(void );
        +
        +/* usage:
        + * CRYPTO_thread_setup();
        + * application code
        + * CRYPTO_thread_cleanup();
        + */
        +
        +#define THREAD_STACK_SIZE (16*1024)
        +
        +#ifdef OPENSSL_SYS_WIN32
        +
        +static HANDLE *lock_cs;
        +
        +void CRYPTO_thread_setup(void)
        +	{
        +	int i;
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
        +		}
        +
        +	CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
        +	/* id callback defined */
        +	return(1);
        +	}
        +
        +static void CRYPTO_thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		CloseHandle(lock_cs[i]);
        +	OPENSSL_free(lock_cs);
        +	}
        +
        +void win32_locking_callback(int mode, int type, char *file, int line)
        +	{
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		WaitForSingleObject(lock_cs[type],INFINITE);
        +		}
        +	else
        +		{
        +		ReleaseMutex(lock_cs[type]);
        +		}
        +	}
        +
        +#endif /* OPENSSL_SYS_WIN32 */
        +
        +#ifdef SOLARIS
        +
        +#define USE_MUTEX
        +
        +#ifdef USE_MUTEX
        +static mutex_t *lock_cs;
        +#else
        +static rwlock_t *lock_cs;
        +#endif
        +static long *lock_count;
        +
        +void CRYPTO_thread_setup(void)
        +	{
        +	int i;
        +
        +#ifdef USE_MUTEX
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
        +#else
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t));
        +#endif
        +	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_count[i]=0;
        +#ifdef USE_MUTEX
        +		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
        +#else
        +		rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL);
        +#endif
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
        +	}
        +
        +void CRYPTO_thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +#ifdef USE_MUTEX
        +		mutex_destroy(&(lock_cs[i]));
        +#else
        +		rwlock_destroy(&(lock_cs[i]));
        +#endif
        +		}
        +	OPENSSL_free(lock_cs);
        +	OPENSSL_free(lock_count);
        +	}
        +
        +void solaris_locking_callback(int mode, int type, char *file, int line)
        +	{
        +#if 0
        +	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
        +		CRYPTO_thread_id(),
        +		(mode&CRYPTO_LOCK)?"l":"u",
        +		(type&CRYPTO_READ)?"r":"w",file,line);
        +#endif
        +
        +#if 0
        +	if (CRYPTO_LOCK_SSL_CERT == type)
        +		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
        +			CRYPTO_thread_id(),
        +			mode,file,line);
        +#endif
        +	if (mode & CRYPTO_LOCK)
        +		{
        +#ifdef USE_MUTEX
        +		mutex_lock(&(lock_cs[type]));
        +#else
        +		if (mode & CRYPTO_READ)
        +			rw_rdlock(&(lock_cs[type]));
        +		else
        +			rw_wrlock(&(lock_cs[type]));
        +#endif
        +		lock_count[type]++;
        +		}
        +	else
        +		{
        +#ifdef USE_MUTEX
        +		mutex_unlock(&(lock_cs[type]));
        +#else
        +		rw_unlock(&(lock_cs[type]));
        +#endif
        +		}
        +	}
        +
        +unsigned long solaris_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)thr_self();
        +	return(ret);
        +	}
        +#endif /* SOLARIS */
        +
        +#ifdef IRIX
        +/* I don't think this works..... */
        +
        +static usptr_t *arena;
        +static usema_t **lock_cs;
        +
        +void CRYPTO_thread_setup(void)
        +	{
        +	int i;
        +	char filename[20];
        +
        +	strcpy(filename,"/tmp/mttest.XXXXXX");
        +	mktemp(filename);
        +
        +	usconfig(CONF_STHREADIOOFF);
        +	usconfig(CONF_STHREADMALLOCOFF);
        +	usconfig(CONF_INITUSERS,100);
        +	usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
        +	arena=usinit(filename);
        +	unlink(filename);
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_cs[i]=usnewsema(arena,1);
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
        +	}
        +
        +void CRYPTO_thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		char buf[10];
        +
        +		sprintf(buf,"%2d:",i);
        +		usdumpsema(lock_cs[i],stdout,buf);
        +		usfreesema(lock_cs[i],arena);
        +		}
        +	OPENSSL_free(lock_cs);
        +	}
        +
        +void irix_locking_callback(int mode, int type, char *file, int line)
        +	{
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		uspsema(lock_cs[type]);
        +		}
        +	else
        +		{
        +		usvsema(lock_cs[type]);
        +		}
        +	}
        +
        +unsigned long irix_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)getpid();
        +	return(ret);
        +	}
        +#endif /* IRIX */
        +
        +/* Linux and a few others */
        +#ifdef PTHREADS
        +
        +static pthread_mutex_t *lock_cs;
        +static long *lock_count;
        +
        +void CRYPTO_thread_setup(void)
        +	{
        +	int i;
        +
        +	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
        +	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		lock_count[i]=0;
        +		pthread_mutex_init(&(lock_cs[i]),NULL);
        +		}
        +
        +	CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
        +	}
        +
        +void thread_cleanup(void)
        +	{
        +	int i;
        +
        +	CRYPTO_set_locking_callback(NULL);
        +	for (i=0; i<CRYPTO_num_locks(); i++)
        +		{
        +		pthread_mutex_destroy(&(lock_cs[i]));
        +		}
        +	OPENSSL_free(lock_cs);
        +	OPENSSL_free(lock_count);
        +	}
        +
        +void pthreads_locking_callback(int mode, int type, char *file,
        +	     int line)
        +      {
        +#if 0
        +	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
        +		CRYPTO_thread_id(),
        +		(mode&CRYPTO_LOCK)?"l":"u",
        +		(type&CRYPTO_READ)?"r":"w",file,line);
        +#endif
        +#if 0
        +	if (CRYPTO_LOCK_SSL_CERT == type)
        +		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
        +		CRYPTO_thread_id(),
        +		mode,file,line);
        +#endif
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		pthread_mutex_lock(&(lock_cs[type]));
        +		lock_count[type]++;
        +		}
        +	else
        +		{
        +		pthread_mutex_unlock(&(lock_cs[type]));
        +		}
        +	}
        +
        +unsigned long pthreads_thread_id(void)
        +	{
        +	unsigned long ret;
        +
        +	ret=(unsigned long)pthread_self();
        +	return(ret);
        +	}
        +
        +#endif /* PTHREADS */
        +
        diff --git a/vendor/openssl/openssl/crypto/threads/win32.bat b/vendor/openssl/openssl/crypto/threads/win32.bat
        new file mode 100644
        index 000000000..ee6da80a0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/threads/win32.bat
        @@ -0,0 +1,4 @@
        +del mttest.exe
        +
        +cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssleay32.lib ..\..\out\libeay32.lib
        +
        diff --git a/vendor/openssl/openssl/crypto/ts/Makefile b/vendor/openssl/openssl/crypto/ts/Makefile
        new file mode 100644
        index 000000000..c18234555
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/Makefile
        @@ -0,0 +1,269 @@
        +#
        +# SSLeay/crypto/ts/Makefile
        +#
        +
        +DIR=	ts
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I../../include
        +CFLAG = -g
        +INSTALL_PREFIX=
        +OPENSSLDIR=     /usr/local/ssl
        +INSTALLTOP=/usr/local/ssl
        +MAKEDEPPROG=	makedepend
        +MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +PEX_LIBS=
        +EX_LIBS=
        + 
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL= Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	ts_err.c ts_req_utils.c ts_req_print.c ts_rsp_utils.c ts_rsp_print.c \
        +	ts_rsp_sign.c ts_rsp_verify.c ts_verify_ctx.c ts_lib.c ts_conf.c \
        +	ts_asn1.c
        +LIBOBJ= ts_err.o ts_req_utils.o ts_req_print.o ts_rsp_utils.o ts_rsp_print.o \
        +	ts_rsp_sign.o ts_rsp_verify.o ts_verify_ctx.o ts_lib.o ts_conf.o \
        +	ts_asn1.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ts.h
        +HEADER=	$(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +test:
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	do  \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
        +	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
        +	done;
        +
        +tags:
        +	ctags $(SRC)
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +
        +depend:
        +	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +ts_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +ts_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_asn1.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ts_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ts_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +ts_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ts_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ts_asn1.o: ../../include/openssl/ts.h ../../include/openssl/x509.h
        +ts_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ts_asn1.o: ts_asn1.c
        +ts_conf.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_conf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_conf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_conf.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_conf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_conf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_conf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +ts_conf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ts_conf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ts_conf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ts_conf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +ts_conf.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +ts_conf.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_conf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_conf.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_conf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_conf.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_conf.c
        +ts_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ts_err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ts_err.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +ts_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +ts_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ts_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ts_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ts_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ts_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ts_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_err.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_err.o: ../../include/openssl/x509v3.h ts_err.c
        +ts_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +ts_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +ts_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +ts_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ts_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
        +ts_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +ts_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ts_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ts.h ts_lib.c
        +ts_req_print.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_req_print.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +ts_req_print.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ts_req_print.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +ts_req_print.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +ts_req_print.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ts_req_print.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ts_req_print.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ts_req_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ts_req_print.o: ../../include/openssl/opensslconf.h
        +ts_req_print.o: ../../include/openssl/opensslv.h
        +ts_req_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_req_print.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_req_print.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_req_print.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_req_print.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_req_print.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_req_print.c
        +ts_req_utils.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_req_utils.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_req_utils.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_req_utils.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_req_utils.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_req_utils.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_req_utils.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_req_utils.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_req_utils.o: ../../include/openssl/objects.h
        +ts_req_utils.o: ../../include/openssl/opensslconf.h
        +ts_req_utils.o: ../../include/openssl/opensslv.h
        +ts_req_utils.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_req_utils.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_req_utils.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_req_utils.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_req_utils.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_req_utils.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_req_utils.c
        +ts_rsp_print.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_rsp_print.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +ts_rsp_print.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +ts_rsp_print.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
        +ts_rsp_print.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +ts_rsp_print.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +ts_rsp_print.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +ts_rsp_print.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +ts_rsp_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +ts_rsp_print.o: ../../include/openssl/opensslconf.h
        +ts_rsp_print.o: ../../include/openssl/opensslv.h
        +ts_rsp_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_rsp_print.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_rsp_print.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_rsp_print.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +ts_rsp_print.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +ts_rsp_print.o: ../cryptlib.h ts.h ts_rsp_print.c
        +ts_rsp_sign.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_rsp_sign.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_rsp_sign.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_rsp_sign.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_rsp_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_rsp_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_rsp_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_rsp_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_rsp_sign.o: ../../include/openssl/objects.h
        +ts_rsp_sign.o: ../../include/openssl/opensslconf.h
        +ts_rsp_sign.o: ../../include/openssl/opensslv.h
        +ts_rsp_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_rsp_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_rsp_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_rsp_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_rsp_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_rsp_sign.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_sign.c
        +ts_rsp_utils.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_rsp_utils.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_rsp_utils.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_rsp_utils.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_rsp_utils.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_rsp_utils.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_rsp_utils.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_rsp_utils.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_rsp_utils.o: ../../include/openssl/objects.h
        +ts_rsp_utils.o: ../../include/openssl/opensslconf.h
        +ts_rsp_utils.o: ../../include/openssl/opensslv.h
        +ts_rsp_utils.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_rsp_utils.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_rsp_utils.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_rsp_utils.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_rsp_utils.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_rsp_utils.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_utils.c
        +ts_rsp_verify.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_rsp_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_rsp_verify.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_rsp_verify.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_rsp_verify.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_rsp_verify.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_rsp_verify.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_rsp_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_rsp_verify.o: ../../include/openssl/objects.h
        +ts_rsp_verify.o: ../../include/openssl/opensslconf.h
        +ts_rsp_verify.o: ../../include/openssl/opensslv.h
        +ts_rsp_verify.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_rsp_verify.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_rsp_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_rsp_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_rsp_verify.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_rsp_verify.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_verify.c
        +ts_verify_ctx.o: ../../e_os.h ../../include/openssl/asn1.h
        +ts_verify_ctx.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +ts_verify_ctx.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +ts_verify_ctx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +ts_verify_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +ts_verify_ctx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +ts_verify_ctx.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +ts_verify_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +ts_verify_ctx.o: ../../include/openssl/objects.h
        +ts_verify_ctx.o: ../../include/openssl/opensslconf.h
        +ts_verify_ctx.o: ../../include/openssl/opensslv.h
        +ts_verify_ctx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +ts_verify_ctx.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +ts_verify_ctx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +ts_verify_ctx.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
        +ts_verify_ctx.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +ts_verify_ctx.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_verify_ctx.c
        diff --git a/vendor/openssl/openssl/crypto/ts/ts.h b/vendor/openssl/openssl/crypto/ts/ts.h
        new file mode 100644
        index 000000000..c2448e3c3
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts.h
        @@ -0,0 +1,858 @@
        +/* crypto/ts/ts.h */
        +/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL
        + * project 2002, 2003, 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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_TS_H
        +#define HEADER_TS_H
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/symhacks.h>
        +#ifndef OPENSSL_NO_BUFFER
        +#include <openssl/buffer.h>
        +#endif
        +#ifndef OPENSSL_NO_EVP
        +#include <openssl/evp.h>
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/stack.h>
        +#include <openssl/asn1.h>
        +#include <openssl/safestack.h>
        +
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef WIN32
        +/* Under Win32 this is defined in wincrypt.h */
        +#undef X509_NAME
        +#endif
        +
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +/*
        +MessageImprint ::= SEQUENCE  {
        +     hashAlgorithm                AlgorithmIdentifier,
        +     hashedMessage                OCTET STRING  }
        +*/
        +
        +typedef struct TS_msg_imprint_st
        +	{
        +	X509_ALGOR *hash_algo;
        +	ASN1_OCTET_STRING *hashed_msg;
        +	} TS_MSG_IMPRINT;
        +
        +/*
        +TimeStampReq ::= SEQUENCE  {
        +   version                  INTEGER  { v1(1) },
        +   messageImprint           MessageImprint,
        +     --a hash algorithm OID and the hash value of the data to be
        +     --time-stamped
        +   reqPolicy                TSAPolicyId                OPTIONAL,
        +   nonce                    INTEGER                    OPTIONAL,
        +   certReq                  BOOLEAN                    DEFAULT FALSE,
        +   extensions               [0] IMPLICIT Extensions    OPTIONAL  }
        +*/
        +
        +typedef struct TS_req_st
        +	{
        +	ASN1_INTEGER *version;
        +	TS_MSG_IMPRINT *msg_imprint;
        +	ASN1_OBJECT *policy_id;		/* OPTIONAL */
        +	ASN1_INTEGER *nonce;		/* OPTIONAL */
        +	ASN1_BOOLEAN cert_req;		/* DEFAULT FALSE */
        +	STACK_OF(X509_EXTENSION) *extensions;	/* [0] OPTIONAL */
        +	} TS_REQ;
        +
        +/*
        +Accuracy ::= SEQUENCE {
        +                seconds        INTEGER           OPTIONAL,
        +                millis     [0] INTEGER  (1..999) OPTIONAL,
        +                micros     [1] INTEGER  (1..999) OPTIONAL  }
        +*/
        +
        +typedef struct TS_accuracy_st
        +	{
        +	ASN1_INTEGER *seconds;
        +	ASN1_INTEGER *millis;
        +	ASN1_INTEGER *micros;
        +	} TS_ACCURACY;
        +
        +/*
        +TSTInfo ::= SEQUENCE  {
        +    version                      INTEGER  { v1(1) },
        +    policy                       TSAPolicyId,
        +    messageImprint               MessageImprint,
        +      -- MUST have the same value as the similar field in
        +      -- TimeStampReq
        +    serialNumber                 INTEGER,
        +     -- Time-Stamping users MUST be ready to accommodate integers
        +     -- up to 160 bits.
        +    genTime                      GeneralizedTime,
        +    accuracy                     Accuracy                 OPTIONAL,
        +    ordering                     BOOLEAN             DEFAULT FALSE,
        +    nonce                        INTEGER                  OPTIONAL,
        +      -- MUST be present if the similar field was present
        +      -- in TimeStampReq.  In that case it MUST have the same value.
        +    tsa                          [0] GeneralName          OPTIONAL,
        +    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
        +*/
        +
        +typedef struct TS_tst_info_st
        +	{
        +	ASN1_INTEGER *version;
        +	ASN1_OBJECT *policy_id;
        +	TS_MSG_IMPRINT *msg_imprint;
        +	ASN1_INTEGER *serial;
        +	ASN1_GENERALIZEDTIME *time;
        +	TS_ACCURACY *accuracy;
        +	ASN1_BOOLEAN ordering;
        +	ASN1_INTEGER *nonce;
        +	GENERAL_NAME *tsa;
        +	STACK_OF(X509_EXTENSION) *extensions;
        +	} TS_TST_INFO;	
        +
        +/*
        +PKIStatusInfo ::= SEQUENCE {
        +    status        PKIStatus,
        +    statusString  PKIFreeText     OPTIONAL,
        +    failInfo      PKIFailureInfo  OPTIONAL  }
        +
        +From RFC 1510 - section 3.1.1:
        +PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
        +	-- text encoded as UTF-8 String (note:  each UTF8String SHOULD
        +	-- include an RFC 1766 language tag to indicate the language
        +	-- of the contained text)
        +*/
        +
        +/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */
        +
        +#define	TS_STATUS_GRANTED			0
        +#define	TS_STATUS_GRANTED_WITH_MODS		1
        +#define	TS_STATUS_REJECTION			2
        +#define	TS_STATUS_WAITING			3
        +#define	TS_STATUS_REVOCATION_WARNING		4
        +#define	TS_STATUS_REVOCATION_NOTIFICATION	5
        +
        +/* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */
        +
        +#define	TS_INFO_BAD_ALG			0
        +#define	TS_INFO_BAD_REQUEST		2
        +#define	TS_INFO_BAD_DATA_FORMAT		5
        +#define	TS_INFO_TIME_NOT_AVAILABLE	14
        +#define	TS_INFO_UNACCEPTED_POLICY	15
        +#define	TS_INFO_UNACCEPTED_EXTENSION	16
        +#define	TS_INFO_ADD_INFO_NOT_AVAILABLE	17
        +#define	TS_INFO_SYSTEM_FAILURE		25
        +
        +typedef struct TS_status_info_st
        +	{
        +	ASN1_INTEGER *status;
        +	STACK_OF(ASN1_UTF8STRING) *text;
        +	ASN1_BIT_STRING *failure_info;
        +	} TS_STATUS_INFO;
        +
        +DECLARE_STACK_OF(ASN1_UTF8STRING)
        +DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)
        +
        +/*
        +TimeStampResp ::= SEQUENCE  {
        +     status                  PKIStatusInfo,
        +     timeStampToken          TimeStampToken     OPTIONAL }
        +*/
        +
        +typedef struct TS_resp_st
        +	{
        +	TS_STATUS_INFO *status_info;
        +	PKCS7 *token;
        +	TS_TST_INFO *tst_info;
        +	} TS_RESP;
        +
        +/* The structure below would belong to the ESS component. */
        +
        +/*
        +IssuerSerial ::= SEQUENCE {
        +	issuer                   GeneralNames,
        +	serialNumber             CertificateSerialNumber
        +	}
        +*/
        +
        +typedef struct ESS_issuer_serial
        +	{
        +	STACK_OF(GENERAL_NAME)	*issuer;
        +	ASN1_INTEGER		*serial;
        +	} ESS_ISSUER_SERIAL;
        +
        +/*
        +ESSCertID ::=  SEQUENCE {
        +        certHash                 Hash,
        +        issuerSerial             IssuerSerial OPTIONAL
        +}
        +*/
        +
        +typedef struct ESS_cert_id
        +	{
        +	ASN1_OCTET_STRING *hash;	/* Always SHA-1 digest. */
        +	ESS_ISSUER_SERIAL *issuer_serial;
        +	} ESS_CERT_ID;
        +
        +DECLARE_STACK_OF(ESS_CERT_ID)
        +DECLARE_ASN1_SET_OF(ESS_CERT_ID)
        +
        +/*
        +SigningCertificate ::=  SEQUENCE {
        +       certs        SEQUENCE OF ESSCertID,
        +       policies     SEQUENCE OF PolicyInformation OPTIONAL
        +}
        +*/
        +
        +typedef struct ESS_signing_cert
        +	{
        +	STACK_OF(ESS_CERT_ID) *cert_ids;
        +	STACK_OF(POLICYINFO) *policy_info;
        +	} ESS_SIGNING_CERT;
        +
        +
        +TS_REQ	*TS_REQ_new(void);
        +void	TS_REQ_free(TS_REQ *a);
        +int	i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
        +TS_REQ	*d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
        +
        +TS_REQ	*TS_REQ_dup(TS_REQ *a);
        +
        +TS_REQ	*d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
        +int	i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
        +TS_REQ	*d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
        +int	i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
        +
        +TS_MSG_IMPRINT	*TS_MSG_IMPRINT_new(void);
        +void		TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
        +int		i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
        +TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
        +				    const unsigned char **pp, long length);
        +
        +TS_MSG_IMPRINT	*TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
        +
        +TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
        +int		i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
        +TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
        +int		i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);
        +
        +TS_RESP	*TS_RESP_new(void);
        +void	TS_RESP_free(TS_RESP *a);
        +int	i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
        +TS_RESP	*d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
        +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
        +TS_RESP	*TS_RESP_dup(TS_RESP *a);
        +
        +TS_RESP	*d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
        +int	i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
        +TS_RESP	*d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
        +int	i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);
        +
        +TS_STATUS_INFO	*TS_STATUS_INFO_new(void);
        +void		TS_STATUS_INFO_free(TS_STATUS_INFO *a);
        +int		i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
        +TS_STATUS_INFO	*d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, 
        +				    const unsigned char **pp, long length);
        +TS_STATUS_INFO	*TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
        +
        +TS_TST_INFO	*TS_TST_INFO_new(void);
        +void		TS_TST_INFO_free(TS_TST_INFO *a);
        +int		i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
        +TS_TST_INFO	*d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
        +				    long length);
        +TS_TST_INFO	*TS_TST_INFO_dup(TS_TST_INFO *a);
        +
        +TS_TST_INFO	*d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
        +int		i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
        +TS_TST_INFO	*d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
        +int		i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);
        +
        +TS_ACCURACY	*TS_ACCURACY_new(void);
        +void		TS_ACCURACY_free(TS_ACCURACY *a);
        +int		i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
        +TS_ACCURACY	*d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
        +				    long length);
        +TS_ACCURACY	*TS_ACCURACY_dup(TS_ACCURACY *a);
        +
        +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
        +void		  ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
        +int		  i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a,
        +					unsigned char **pp);
        +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
        +					 const unsigned char **pp, long length);
        +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
        +
        +ESS_CERT_ID	*ESS_CERT_ID_new(void);
        +void		ESS_CERT_ID_free(ESS_CERT_ID *a);
        +int		i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
        +ESS_CERT_ID	*d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
        +				 long length);
        +ESS_CERT_ID	*ESS_CERT_ID_dup(ESS_CERT_ID *a);
        +
        +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
        +void		 ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
        +int		 i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, 
        +				      unsigned char **pp);
        +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
        +				       const unsigned char **pp, long length);
        +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
        +
        +void ERR_load_TS_strings(void);
        +
        +int TS_REQ_set_version(TS_REQ *a, long version);
        +long TS_REQ_get_version(const TS_REQ *a);
        +
        +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
        +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
        +
        +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
        +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
        +
        +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
        +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
        +
        +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
        +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
        +
        +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
        +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
        +
        +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
        +int TS_REQ_get_cert_req(const TS_REQ *a);
        +
        +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
        +void TS_REQ_ext_free(TS_REQ *a);
        +int TS_REQ_get_ext_count(TS_REQ *a);
        +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
        +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
        +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
        +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
        +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
        +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
        +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
        +
        +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
        +
        +int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
        +
        +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
        +
        +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
        +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
        +
        +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
        +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
        +PKCS7 *TS_RESP_get_token(TS_RESP *a);
        +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
        +
        +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
        +long TS_TST_INFO_get_version(const TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
        +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
        +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
        +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
        +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
        +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
        +
        +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
        +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
        +
        +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
        +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
        +
        +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
        +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
        +
        +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
        +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
        +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
        +
        +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
        +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
        +
        +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
        +void TS_TST_INFO_ext_free(TS_TST_INFO *a);
        +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
        +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
        +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
        +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
        +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
        +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
        +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
        +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
        +
        +/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */
        +
        +/* Optional flags for response generation. */
        +
        +/* Don't include the TSA name in response. */
        +#define	TS_TSA_NAME		0x01
        +
        +/* Set ordering to true in response. */
        +#define	TS_ORDERING		0x02
        +
        +/*
        + * Include the signer certificate and the other specified certificates in
        + * the ESS signing certificate attribute beside the PKCS7 signed data.
        + * Only the signer certificates is included by default.
        + */
        +#define	TS_ESS_CERT_ID_CHAIN	0x04
        +
        +/* Forward declaration. */
        +struct TS_resp_ctx;
        +
        +/* This must return a unique number less than 160 bits long. */
        +typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);
        +
        +/* This must return the seconds and microseconds since Jan 1, 1970 in
        +   the sec and usec variables allocated by the caller. 
        +   Return non-zero for success and zero for failure. */
        +typedef	int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec);
        +
        +/* This must process the given extension.
        + * It can modify the TS_TST_INFO object of the context.
        + * Return values: !0 (processed), 0 (error, it must set the 
        + * status info/failure info of the response).
        + */
        +typedef	int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *);
        +
        +typedef struct TS_resp_ctx
        +	{
        +	X509		*signer_cert;
        +	EVP_PKEY	*signer_key;
        +	STACK_OF(X509)	*certs;	/* Certs to include in signed data. */
        +	STACK_OF(ASN1_OBJECT)	*policies;	/* Acceptable policies. */
        +	ASN1_OBJECT	*default_policy; /* It may appear in policies, too. */
        +	STACK_OF(EVP_MD)	*mds;	/* Acceptable message digests. */
        +	ASN1_INTEGER	*seconds;	/* accuracy, 0 means not specified. */
        +	ASN1_INTEGER	*millis;	/* accuracy, 0 means not specified. */
        +	ASN1_INTEGER	*micros;	/* accuracy, 0 means not specified. */
        +	unsigned	clock_precision_digits; /* fraction of seconds in
        +						   time stamp token. */
        +	unsigned	flags;		/* Optional info, see values above. */
        +
        +	/* Callback functions. */
        +	TS_serial_cb serial_cb;
        +	void *serial_cb_data;	/* User data for serial_cb. */
        +	
        +	TS_time_cb time_cb;
        +	void *time_cb_data;	/* User data for time_cb. */
        +	
        +	TS_extension_cb extension_cb;
        +	void *extension_cb_data;	/* User data for extension_cb. */
        +
        +	/* These members are used only while creating the response. */
        +	TS_REQ		*request;
        +	TS_RESP		*response;
        +	TS_TST_INFO	*tst_info;
        +	} TS_RESP_CTX;
        +
        +DECLARE_STACK_OF(EVP_MD)
        +DECLARE_ASN1_SET_OF(EVP_MD)
        +
        +/* Creates a response context that can be used for generating responses. */
        +TS_RESP_CTX *TS_RESP_CTX_new(void);
        +void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
        +
        +/* This parameter must be set. */
        +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
        +
        +/* This parameter must be set. */
        +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
        +
        +/* This parameter must be set. */
        +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
        +
        +/* No additional certs are included in the response by default. */
        +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
        +
        +/* Adds a new acceptable policy, only the default policy 
        +   is accepted by default. */
        +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
        +
        +/* Adds a new acceptable message digest. Note that no message digests 
        +   are accepted by default. The md argument is shared with the caller. */
        +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
        +
        +/* Accuracy is not included by default. */
        +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
        +			     int secs, int millis, int micros);
        +
        +/* Clock precision digits, i.e. the number of decimal digits: 
        +   '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ 
        +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
        +					   unsigned clock_precision_digits);
        +/* At most we accept usec precision. */	
        +#define TS_MAX_CLOCK_PRECISION_DIGITS	6
        +
        +/* No flags are set by default. */
        +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
        +
        +/* Default callback always returns a constant. */
        +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
        +
        +/* Default callback uses the gettimeofday() and gmtime() system calls. */
        +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
        +
        +/* Default callback rejects all extensions. The extension callback is called 
        + * when the TS_TST_INFO object is already set up and not signed yet. */
        +/* FIXME: extension handling is not tested yet. */
        +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
        +				  TS_extension_cb cb, void *data);
        +
        +/* The following methods can be used in the callbacks. */
        +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
        +				int status, const char *text);
        +
        +/* Sets the status info only if it is still TS_STATUS_GRANTED. */
        +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
        +				     int status, const char *text);
        +
        +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
        +
        +/* The get methods below can be used in the extension callback. */
        +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
        +
        +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
        +
        +/* 
        + * Creates the signed TS_TST_INFO and puts it in TS_RESP.
        + * In case of errors it sets the status info properly.
        + * Returns NULL only in case of memory allocation/fatal error.
        + */
        +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
        +
        +/*
        + * Declarations related to response verification,
        + * they are defined in ts/ts_resp_verify.c.
        + */
        +
        +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
        +			     X509_STORE *store, X509 **signer_out);
        +
        +/* Context structure for the generic verify method. */
        +
        +/* Verify the signer's certificate and the signature of the response. */
        +#define	TS_VFY_SIGNATURE	(1u << 0)
        +/* Verify the version number of the response. */
        +#define	TS_VFY_VERSION		(1u << 1)
        +/* Verify if the policy supplied by the user matches the policy of the TSA. */
        +#define	TS_VFY_POLICY		(1u << 2)
        +/* Verify the message imprint provided by the user. This flag should not be
        +   specified with TS_VFY_DATA. */
        +#define	TS_VFY_IMPRINT		(1u << 3)
        +/* Verify the message imprint computed by the verify method from the user
        +   provided data and the MD algorithm of the response. This flag should not be
        +   specified with TS_VFY_IMPRINT. */
        +#define	TS_VFY_DATA		(1u << 4)
        +/* Verify the nonce value. */
        +#define	TS_VFY_NONCE		(1u << 5)
        +/* Verify if the TSA name field matches the signer certificate. */
        +#define	TS_VFY_SIGNER		(1u << 6)
        +/* Verify if the TSA name field equals to the user provided name. */
        +#define	TS_VFY_TSA_NAME		(1u << 7)
        +
        +/* You can use the following convenience constants. */
        +#define	TS_VFY_ALL_IMPRINT	(TS_VFY_SIGNATURE	\
        +				 | TS_VFY_VERSION	\
        +				 | TS_VFY_POLICY	\
        +				 | TS_VFY_IMPRINT	\
        +				 | TS_VFY_NONCE		\
        +				 | TS_VFY_SIGNER	\
        +				 | TS_VFY_TSA_NAME)
        +#define	TS_VFY_ALL_DATA		(TS_VFY_SIGNATURE	\
        +				 | TS_VFY_VERSION	\
        +				 | TS_VFY_POLICY	\
        +				 | TS_VFY_DATA		\
        +				 | TS_VFY_NONCE		\
        +				 | TS_VFY_SIGNER	\
        +				 | TS_VFY_TSA_NAME)
        +
        +typedef struct TS_verify_ctx
        +	{
        +	/* Set this to the union of TS_VFY_... flags you want to carry out. */
        +	unsigned	flags;
        +
        +	/* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
        +	X509_STORE	*store;
        +	STACK_OF(X509)	*certs;
        +
        +	/* Must be set only with TS_VFY_POLICY. */
        +	ASN1_OBJECT	*policy;
        +
        +	/* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, 
        +	   the algorithm from the response is used. */
        +	X509_ALGOR	*md_alg;
        +	unsigned char	*imprint;
        +	unsigned	imprint_len;
        +
        +	/* Must be set only with TS_VFY_DATA. */
        +	BIO		*data;
        +
        +	/* Must be set only with TS_VFY_TSA_NAME. */
        +	ASN1_INTEGER	*nonce;
        +
        +	/* Must be set only with TS_VFY_TSA_NAME. */
        +	GENERAL_NAME	*tsa_name;
        +	} TS_VERIFY_CTX;
        +
        +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
        +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
        +
        +/*
        + * Declarations related to response verification context,
        + * they are defined in ts/ts_verify_ctx.c.
        + */
        +
        +/* Set all fields to zero. */
        +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
        +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
        +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
        +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
        +
        +/* 
        + * If ctx is NULL, it allocates and returns a new object, otherwise
        + * it returns ctx. It initialises all the members as follows:
        + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
        + * certs = NULL
        + * store = NULL
        + * policy = policy from the request or NULL if absent (in this case
        + *	TS_VFY_POLICY is cleared from flags as well)
        + * md_alg = MD algorithm from request
        + * imprint, imprint_len = imprint from request
        + * data = NULL
        + * nonce, nonce_len = nonce from the request or NULL if absent (in this case
        + * 	TS_VFY_NONCE is cleared from flags as well)
        + * tsa_name = NULL
        + * Important: after calling this method TS_VFY_SIGNATURE should be added!
        + */
        +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
        +
        +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
        +
        +int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
        +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
        +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
        +
        +/* Common utility functions defined in ts/ts_lib.c */
        +
        +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
        +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
        +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
        +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
        +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
        +
        +/* Function declarations for handling configuration options,
        +   defined in ts/ts_conf.c */
        +
        +X509 *TS_CONF_load_cert(const char *file);
        +STACK_OF(X509) *TS_CONF_load_certs(const char *file);
        +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
        +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
        +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
        +		       TS_RESP_CTX *ctx);
        +int TS_CONF_set_crypto_device(CONF *conf, const char *section,
        +			      const char *device);
        +int TS_CONF_set_default_engine(const char *name);
        +int TS_CONF_set_signer_cert(CONF *conf, const char *section,
        +			    const char *cert, TS_RESP_CTX *ctx);
        +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
        +		      TS_RESP_CTX *ctx);
        +int TS_CONF_set_signer_key(CONF *conf, const char *section,
        +			   const char *key, const char *pass, TS_RESP_CTX *ctx);
        +int TS_CONF_set_def_policy(CONF *conf, const char *section,
        +			   const char *policy, TS_RESP_CTX *ctx);
        +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
        +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
        +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
        +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
        +				       TS_RESP_CTX *ctx);
        +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
        +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
        +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
        +				  TS_RESP_CTX *ctx);
        +
        +/* -------------------------------------------------- */
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_TS_strings(void);
        +
        +/* Error codes for the TS functions. */
        +
        +/* Function codes. */
        +#define TS_F_D2I_TS_RESP				 147
        +#define TS_F_DEF_SERIAL_CB				 110
        +#define TS_F_DEF_TIME_CB				 111
        +#define TS_F_ESS_ADD_SIGNING_CERT			 112
        +#define TS_F_ESS_CERT_ID_NEW_INIT			 113
        +#define TS_F_ESS_SIGNING_CERT_NEW_INIT			 114
        +#define TS_F_INT_TS_RESP_VERIFY_TOKEN			 149
        +#define TS_F_PKCS7_TO_TS_TST_INFO			 148
        +#define TS_F_TS_ACCURACY_SET_MICROS			 115
        +#define TS_F_TS_ACCURACY_SET_MILLIS			 116
        +#define TS_F_TS_ACCURACY_SET_SECONDS			 117
        +#define TS_F_TS_CHECK_IMPRINTS				 100
        +#define TS_F_TS_CHECK_NONCES				 101
        +#define TS_F_TS_CHECK_POLICY				 102
        +#define TS_F_TS_CHECK_SIGNING_CERTS			 103
        +#define TS_F_TS_CHECK_STATUS_INFO			 104
        +#define TS_F_TS_COMPUTE_IMPRINT				 145
        +#define TS_F_TS_CONF_SET_DEFAULT_ENGINE			 146
        +#define TS_F_TS_GET_STATUS_TEXT				 105
        +#define TS_F_TS_MSG_IMPRINT_SET_ALGO			 118
        +#define TS_F_TS_REQ_SET_MSG_IMPRINT			 119
        +#define TS_F_TS_REQ_SET_NONCE				 120
        +#define TS_F_TS_REQ_SET_POLICY_ID			 121
        +#define TS_F_TS_RESP_CREATE_RESPONSE			 122
        +#define TS_F_TS_RESP_CREATE_TST_INFO			 123
        +#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO		 124
        +#define TS_F_TS_RESP_CTX_ADD_MD				 125
        +#define TS_F_TS_RESP_CTX_ADD_POLICY			 126
        +#define TS_F_TS_RESP_CTX_NEW				 127
        +#define TS_F_TS_RESP_CTX_SET_ACCURACY			 128
        +#define TS_F_TS_RESP_CTX_SET_CERTS			 129
        +#define TS_F_TS_RESP_CTX_SET_DEF_POLICY			 130
        +#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT		 131
        +#define TS_F_TS_RESP_CTX_SET_STATUS_INFO		 132
        +#define TS_F_TS_RESP_GET_POLICY				 133
        +#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION		 134
        +#define TS_F_TS_RESP_SET_STATUS_INFO			 135
        +#define TS_F_TS_RESP_SET_TST_INFO			 150
        +#define TS_F_TS_RESP_SIGN				 136
        +#define TS_F_TS_RESP_VERIFY_SIGNATURE			 106
        +#define TS_F_TS_RESP_VERIFY_TOKEN			 107
        +#define TS_F_TS_TST_INFO_SET_ACCURACY			 137
        +#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT		 138
        +#define TS_F_TS_TST_INFO_SET_NONCE			 139
        +#define TS_F_TS_TST_INFO_SET_POLICY_ID			 140
        +#define TS_F_TS_TST_INFO_SET_SERIAL			 141
        +#define TS_F_TS_TST_INFO_SET_TIME			 142
        +#define TS_F_TS_TST_INFO_SET_TSA			 143
        +#define TS_F_TS_VERIFY					 108
        +#define TS_F_TS_VERIFY_CERT				 109
        +#define TS_F_TS_VERIFY_CTX_NEW				 144
        +
        +/* Reason codes. */
        +#define TS_R_BAD_PKCS7_TYPE				 132
        +#define TS_R_BAD_TYPE					 133
        +#define TS_R_CERTIFICATE_VERIFY_ERROR			 100
        +#define TS_R_COULD_NOT_SET_ENGINE			 127
        +#define TS_R_COULD_NOT_SET_TIME				 115
        +#define TS_R_D2I_TS_RESP_INT_FAILED			 128
        +#define TS_R_DETACHED_CONTENT				 134
        +#define TS_R_ESS_ADD_SIGNING_CERT_ERROR			 116
        +#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR		 101
        +#define TS_R_INVALID_NULL_POINTER			 102
        +#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE		 117
        +#define TS_R_MESSAGE_IMPRINT_MISMATCH			 103
        +#define TS_R_NONCE_MISMATCH				 104
        +#define TS_R_NONCE_NOT_RETURNED				 105
        +#define TS_R_NO_CONTENT					 106
        +#define TS_R_NO_TIME_STAMP_TOKEN			 107
        +#define TS_R_PKCS7_ADD_SIGNATURE_ERROR			 118
        +#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR		 119
        +#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED		 129
        +#define TS_R_POLICY_MISMATCH				 108
        +#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 120
        +#define TS_R_RESPONSE_SETUP_ERROR			 121
        +#define TS_R_SIGNATURE_FAILURE				 109
        +#define TS_R_THERE_MUST_BE_ONE_SIGNER			 110
        +#define TS_R_TIME_SYSCALL_ERROR				 122
        +#define TS_R_TOKEN_NOT_PRESENT				 130
        +#define TS_R_TOKEN_PRESENT				 131
        +#define TS_R_TSA_NAME_MISMATCH				 111
        +#define TS_R_TSA_UNTRUSTED				 112
        +#define TS_R_TST_INFO_SETUP_ERROR			 123
        +#define TS_R_TS_DATASIGN				 124
        +#define TS_R_UNACCEPTABLE_POLICY			 125
        +#define TS_R_UNSUPPORTED_MD_ALGORITHM			 126
        +#define TS_R_UNSUPPORTED_VERSION			 113
        +#define TS_R_WRONG_CONTENT_TYPE				 114
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_asn1.c b/vendor/openssl/openssl/crypto/ts/ts_asn1.c
        new file mode 100644
        index 000000000..40b730c5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_asn1.c
        @@ -0,0 +1,322 @@
        +/* crypto/ts/ts_asn1.c */
        +/* Written by Nils Larsch for the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <openssl/ts.h>
        +#include <openssl/err.h>
        +#include <openssl/asn1t.h>
        +
        +ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
        +	ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR),
        +	ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(TS_MSG_IMPRINT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
        +IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
        +#ifndef OPENSSL_NO_BIO
        +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
        +	{
        +	return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, bp, a);
        +	}
        +
        +int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
        +{
        +	return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
        +}
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
        +	{
        +	return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, fp, a);
        +	}
        +
        +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
        +	{
        +	return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
        +	}
        +#endif
        +
        +ASN1_SEQUENCE(TS_REQ) = {
        +	ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT),
        +	ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT),
        +	ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER),
        +	ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN),
        +	ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
        +} ASN1_SEQUENCE_END(TS_REQ)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
        +IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
        +#ifndef OPENSSL_NO_BIO
        +TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
        +	{
        +	return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
        +	}
        +
        +int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
        +	{
        +	return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
        +	}
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
        +	{
        +	return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
        +	}
        +
        +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
        +	{
        +	return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
        +	}
        +#endif
        +
        +ASN1_SEQUENCE(TS_ACCURACY) = {
        +	ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER),
        +	ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0),
        +	ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
        +} ASN1_SEQUENCE_END(TS_ACCURACY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
        +IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)
        +
        +ASN1_SEQUENCE(TS_TST_INFO) = {
        +	ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER),
        +	ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT),
        +	ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT),
        +	ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER),
        +	ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME),
        +	ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY),
        +	ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN),
        +	ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER),
        +	ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0),
        +	ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
        +} ASN1_SEQUENCE_END(TS_TST_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
        +IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
        +#ifndef OPENSSL_NO_BIO
        +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
        +	{
        +	return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, a);
        +	}
        +
        +int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
        +	{
        +	return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
        +	}
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
        +	{
        +	return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, a);
        +	}
        +
        +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
        +	{
        +	return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
        +	}
        +#endif
        +
        +ASN1_SEQUENCE(TS_STATUS_INFO) = {
        +	ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER),
        +	ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING),
        +	ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END(TS_STATUS_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
        +IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
        +
        +static int ts_resp_set_tst_info(TS_RESP *a)
        +{
        +	long    status;
        +
        +	status = ASN1_INTEGER_get(a->status_info->status);
        +
        +	if (a->token) {
        +		if (status != 0 && status != 1) {
        +			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
        +			return 0;
        +		}
        +		if (a->tst_info != NULL)
        +			TS_TST_INFO_free(a->tst_info);
        +		a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
        +		if (!a->tst_info) {
        +			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
        +			return 0;
        +		}
        +	} else if (status == 0 || status == 1) {
        +		TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
        +		return 0;
        +	}
        +
        +	return 1;
        +}
        +
        +static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +	void *exarg)
        +{
        +	TS_RESP *ts_resp = (TS_RESP *)*pval;
        +	if (op == ASN1_OP_NEW_POST) {
        +		ts_resp->tst_info = NULL;
        +	} else if (op == ASN1_OP_FREE_POST) {
        +		if (ts_resp->tst_info != NULL)
        +			TS_TST_INFO_free(ts_resp->tst_info);
        +	} else if (op == ASN1_OP_D2I_POST) {
        +		if (ts_resp_set_tst_info(ts_resp) == 0)
        +			return 0;
        +	}
        +	return 1;
        +}
        +
        +ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
        +	ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO),
        +	ASN1_OPT(TS_RESP, token, PKCS7),
        +} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
        +IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
        +#ifndef OPENSSL_NO_BIO
        +TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
        +	{
        +	return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
        +	}
        +
        +int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
        +	{
        +	return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
        +	}
        +#endif
        +#ifndef OPENSSL_NO_FP_API
        +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
        +	{
        +	return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
        +	}
        +
        +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
        +	{
        +	return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
        +	}
        +#endif
        +
        +ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
        +	ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
        +	ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
        +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
        +
        +ASN1_SEQUENCE(ESS_CERT_ID) = {
        +	ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING),
        +	ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
        +} ASN1_SEQUENCE_END(ESS_CERT_ID)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
        +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)
        +
        +ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
        +	ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID),
        +	ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
        +} ASN1_SEQUENCE_END(ESS_SIGNING_CERT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
        +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
        +
        +/* Getting encapsulated TS_TST_INFO object from PKCS7. */
        +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
        +{
        +	PKCS7_SIGNED *pkcs7_signed;
        +	PKCS7 *enveloped;
        +	ASN1_TYPE *tst_info_wrapper;
        +	ASN1_OCTET_STRING *tst_info_der;
        +	const unsigned char *p;
        +
        +	if (!PKCS7_type_is_signed(token))
        +		{
        +		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
        +		return NULL;
        +		}
        +
        +	/* Content must be present. */
        +	if (PKCS7_get_detached(token))
        +		{
        +		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
        +		return NULL;
        +		}
        +
        +	/* We have a signed data with content. */
        +	pkcs7_signed = token->d.sign;
        +	enveloped = pkcs7_signed->contents;
        +	if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo)
        +		{
        +		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
        +		return NULL;
        +		}
        +
        +	/* We have a DER encoded TST_INFO as the signed data. */
        +	tst_info_wrapper = enveloped->d.other;
        +	if (tst_info_wrapper->type != V_ASN1_OCTET_STRING)
        +		{
        +		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
        +		return NULL;
        +		}
        +
        +	/* We have the correct ASN1_OCTET_STRING type. */
        +	tst_info_der = tst_info_wrapper->value.octet_string;
        +	/* At last, decode the TST_INFO. */
        +	p = tst_info_der->data;
        +	return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
        +}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_conf.c b/vendor/openssl/openssl/crypto/ts/ts_conf.c
        new file mode 100644
        index 000000000..c39be76f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_conf.c
        @@ -0,0 +1,507 @@
        +/* crypto/ts/ts_conf.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <string.h>
        +
        +#include <openssl/crypto.h>
        +#include "cryptlib.h"
        +#include <openssl/pem.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/ts.h>
        +
        +/* Macro definitions for the configuration file. */
        +
        +#define	BASE_SECTION			"tsa"
        +#define	ENV_DEFAULT_TSA			"default_tsa"
        +#define	ENV_SERIAL			"serial"
        +#define ENV_CRYPTO_DEVICE		"crypto_device"
        +#define	ENV_SIGNER_CERT			"signer_cert"
        +#define	ENV_CERTS			"certs"
        +#define	ENV_SIGNER_KEY			"signer_key"
        +#define	ENV_DEFAULT_POLICY		"default_policy"
        +#define	ENV_OTHER_POLICIES		"other_policies"
        +#define	ENV_DIGESTS			"digests"
        +#define	ENV_ACCURACY			"accuracy"
        +#define	ENV_ORDERING			"ordering"
        +#define	ENV_TSA_NAME			"tsa_name"
        +#define	ENV_ESS_CERT_ID_CHAIN		"ess_cert_id_chain"
        +#define	ENV_VALUE_SECS			"secs"
        +#define	ENV_VALUE_MILLISECS		"millisecs"
        +#define	ENV_VALUE_MICROSECS		"microsecs"
        +#define	ENV_CLOCK_PRECISION_DIGITS	"clock_precision_digits" 
        +#define	ENV_VALUE_YES			"yes"
        +#define	ENV_VALUE_NO			"no"
        +
        +/* Function definitions for certificate and key loading. */
        +
        +X509 *TS_CONF_load_cert(const char *file)
        +	{
        +	BIO *cert = NULL;
        +	X509 *x = NULL;
        +
        +	if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
        +	x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
        +end:
        +	if (x == NULL)
        +		fprintf(stderr, "unable to load certificate: %s\n", file);
        +	BIO_free(cert);
        +	return x;
        +	}
        +
        +STACK_OF(X509) *TS_CONF_load_certs(const char *file)
        +	{
        +	BIO *certs = NULL;
        +	STACK_OF(X509) *othercerts = NULL;
        +	STACK_OF(X509_INFO) *allcerts = NULL;
        +	int i;
        +
        +	if (!(certs = BIO_new_file(file, "r"))) goto end;
        +
        +	if (!(othercerts = sk_X509_new_null())) goto end;
        +	allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
        +	for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
        +		{
        +		X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
        +		if (xi->x509)
        +			{
        +			sk_X509_push(othercerts, xi->x509);
        +			xi->x509 = NULL;
        +			}
        +		}
        +end:
        +	if (othercerts == NULL)
        +		fprintf(stderr, "unable to load certificates: %s\n", file);
        +	sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
        +	BIO_free(certs);
        +	return othercerts;
        +	}
        +
        +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
        +	{
        +	BIO *key = NULL;
        +	EVP_PKEY *pkey = NULL;
        +
        +	if (!(key = BIO_new_file(file, "r"))) goto end;
        +	pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass);
        + end:
        +	if (pkey == NULL)
        +		fprintf(stderr, "unable to load private key: %s\n", file);
        +	BIO_free(key);
        +	return pkey;
        +	}
        +
        +/* Function definitions for handling configuration options. */
        +
        +static void TS_CONF_lookup_fail(const char *name, const char *tag)
        +	{
        +	fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag);
        +	}
        +
        +static void TS_CONF_invalid(const char *name, const char *tag)
        +	{
        +	fprintf(stderr, "invalid variable value for %s::%s\n", name, tag);
        +	}
        +
        +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
        +	{
        +	if (!section)
        +		{
        +		section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
        +		if (!section)
        +			TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
        +		}
        +	return section;
        +	}
        +
        +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
        +		       TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
        +	if (!serial)
        +		{
        +		TS_CONF_lookup_fail(section, ENV_SERIAL);
        +		goto err;
        +		}
        +	TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
        +
        +	ret = 1;
        + err:
        +	return ret;
        +	}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +
        +int TS_CONF_set_crypto_device(CONF *conf, const char *section,
        +			      const char *device)
        +	{
        +	int ret = 0;
        +	
        +	if (!device)
        +		device = NCONF_get_string(conf, section,
        +					  ENV_CRYPTO_DEVICE);
        +
        +	if (device && !TS_CONF_set_default_engine(device))
        +		{
        +		TS_CONF_invalid(section, ENV_CRYPTO_DEVICE);
        +		goto err;
        +		}
        +	ret = 1;
        + err:
        +	return ret;
        +	}
        +
        +int TS_CONF_set_default_engine(const char *name)
        +	{
        +	ENGINE *e = NULL;
        +	int ret = 0;
        +
        +	/* Leave the default if builtin specified. */
        +	if (strcmp(name, "builtin") == 0) return 1;
        +
        +	if (!(e = ENGINE_by_id(name))) goto err;
        +	/* Enable the use of the NCipher HSM for forked children. */
        +	if (strcmp(name, "chil") == 0) 
        +		ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
        +	/* All the operations are going to be carried out by the engine. */
        +	if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err;
        +	ret = 1;
        + err:
        +	if (!ret)
        +		{
        +		TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, 
        +		      TS_R_COULD_NOT_SET_ENGINE);
        +		ERR_add_error_data(2, "engine:", name);
        +		}
        +	if (e) ENGINE_free(e);
        +	return ret;
        +	}
        +
        +#endif
        +
        +int TS_CONF_set_signer_cert(CONF *conf, const char *section,
        +			    const char *cert, TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	X509 *cert_obj = NULL;
        +	if (!cert) 
        +		cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
        +	if (!cert)
        +		{
        +		TS_CONF_lookup_fail(section, ENV_SIGNER_CERT);
        +		goto err;
        +		}
        +	if (!(cert_obj = TS_CONF_load_cert(cert)))
        +		goto err;
        +	if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
        +		goto err;
        +
        +	ret = 1;
        + err:
        +	X509_free(cert_obj);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
        +		      TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	STACK_OF(X509) *certs_obj = NULL;
        +	if (!certs) 
        +		certs = NCONF_get_string(conf, section, ENV_CERTS);
        +	/* Certificate chain is optional. */
        +	if (!certs) goto end;
        +	if (!(certs_obj = TS_CONF_load_certs(certs))) goto err;
        +	if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err;
        + end:
        +	ret = 1;
        + err:
        +	sk_X509_pop_free(certs_obj, X509_free);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_signer_key(CONF *conf, const char *section,
        +			   const char *key, const char *pass,
        +			   TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	EVP_PKEY *key_obj = NULL;
        +	if (!key) 
        +		key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
        +	if (!key)
        +		{
        +		TS_CONF_lookup_fail(section, ENV_SIGNER_KEY);
        +		goto err;
        +		}
        +	if (!(key_obj = TS_CONF_load_key(key, pass))) goto err;
        +	if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err;
        +
        +	ret = 1;
        + err:
        +	EVP_PKEY_free(key_obj);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_def_policy(CONF *conf, const char *section,
        +			   const char *policy, TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	ASN1_OBJECT *policy_obj = NULL;
        +	if (!policy) 
        +		policy = NCONF_get_string(conf, section, 
        +					  ENV_DEFAULT_POLICY);
        +	if (!policy)
        +		{
        +		TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
        +		goto err;
        +		}
        +	if (!(policy_obj = OBJ_txt2obj(policy, 0)))
        +		{
        +		TS_CONF_invalid(section, ENV_DEFAULT_POLICY);
        +		goto err;
        +		}
        +	if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
        +		goto err;
        +
        +	ret = 1;
        + err:
        +	ASN1_OBJECT_free(policy_obj);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_policies(CONF *conf, const char *section,
        +			 TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	int i;
        +	STACK_OF(CONF_VALUE) *list = NULL;
        +	char *policies = NCONF_get_string(conf, section, 
        +					  ENV_OTHER_POLICIES);
        +	/* If no other policy is specified, that's fine. */
        +	if (policies && !(list = X509V3_parse_list(policies)))
        +		{
        +		TS_CONF_invalid(section, ENV_OTHER_POLICIES);
        +		goto err;
        +		}
        +	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
        +		{
        +		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
        +		const char *extval = val->value ? val->value : val->name;
        +		ASN1_OBJECT *objtmp;
        +		if (!(objtmp = OBJ_txt2obj(extval, 0)))
        +			{
        +			TS_CONF_invalid(section, ENV_OTHER_POLICIES);
        +			goto err;
        +			}
        +		if (!TS_RESP_CTX_add_policy(ctx, objtmp))
        +			goto err;
        +		ASN1_OBJECT_free(objtmp);
        +		}
        +
        +	ret = 1;
        + err:
        +	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_digests(CONF *conf, const char *section,
        +			TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	int i;
        +	STACK_OF(CONF_VALUE) *list = NULL;
        +	char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
        +	if (!digests)
        +		{
        +		TS_CONF_lookup_fail(section, ENV_DIGESTS);
        +		goto err;
        +		}
        +	if (!(list = X509V3_parse_list(digests)))
        +		{
        +		TS_CONF_invalid(section, ENV_DIGESTS);
        +		goto err;
        +		}
        +	if (sk_CONF_VALUE_num(list) == 0)
        +		{
        +		TS_CONF_invalid(section, ENV_DIGESTS);
        +		goto err;
        +		}
        +	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
        +		{
        +		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
        +		const char *extval = val->value ? val->value : val->name;
        +		const EVP_MD *md;
        +		if (!(md = EVP_get_digestbyname(extval)))
        +			{
        +			TS_CONF_invalid(section, ENV_DIGESTS);
        +			goto err;
        +			}
        +		if (!TS_RESP_CTX_add_md(ctx, md))
        +			goto err;
        +		}
        +
        +	ret = 1;
        + err:
        +	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	int i;
        +	int secs = 0, millis = 0, micros = 0;
        +	STACK_OF(CONF_VALUE) *list = NULL;
        +	char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
        +
        +	if (accuracy && !(list = X509V3_parse_list(accuracy)))
        +		{
        +		TS_CONF_invalid(section, ENV_ACCURACY);
        +		goto err;
        +		}
        +	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
        +		{
        +		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
        +		if (strcmp(val->name, ENV_VALUE_SECS) == 0) 
        +			{
        +			if (val->value) secs = atoi(val->value);
        +			}
        +		else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0)
        +			{
        +			if (val->value) millis = atoi(val->value);
        +			}
        +		else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0)
        +			{
        +			if (val->value) micros = atoi(val->value);
        +			}
        +		else
        +			{
        +			TS_CONF_invalid(section, ENV_ACCURACY);
        +			goto err;
        +			}
        +		}
        +	if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
        +		goto err;
        +
        +	ret = 1;
        + err:
        +	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
        +	return ret;
        +	}
        +
        +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
        +				       TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	long digits = 0;
        +	
        +	/* If not specified, set the default value to 0, i.e. sec  precision */
        +	if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
        +				&digits))
        +		digits = 0;
        +	if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS)
        +		{
        +		TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
        +		goto err;
        +		}
        +
        +	if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
        +		goto err;
        +
        +	return 1;
        + err:
        +	return ret;
        +	}
        +
        +static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field,
        +			    int flag, TS_RESP_CTX *ctx)
        +	{
        +	/* Default is false. */
        +	const char *value = NCONF_get_string(conf, section, field);
        +	if (value)
        +		{
        +		if (strcmp(value, ENV_VALUE_YES) == 0)
        +			TS_RESP_CTX_add_flags(ctx, flag);
        +		else if (strcmp(value, ENV_VALUE_NO) != 0)
        +			{
        +			TS_CONF_invalid(section, field);
        +			return 0;
        +			}
        +		}
        +
        +	return 1;
        +	}
        +
        +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
        +	{
        +	return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
        +	}
        +
        +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
        +	{
        +	return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
        +	}
        +
        +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
        +				  TS_RESP_CTX *ctx)
        +	{
        +	return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, 
        +				TS_ESS_CERT_ID_CHAIN, ctx);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_err.c b/vendor/openssl/openssl/crypto/ts/ts_err.c
        new file mode 100644
        index 000000000..a08b0ffa2
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_err.c
        @@ -0,0 +1,179 @@
        +/* crypto/ts/ts_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ts.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
        +
        +static ERR_STRING_DATA TS_str_functs[]=
        +	{
        +{ERR_FUNC(TS_F_D2I_TS_RESP),	"d2i_TS_RESP"},
        +{ERR_FUNC(TS_F_DEF_SERIAL_CB),	"DEF_SERIAL_CB"},
        +{ERR_FUNC(TS_F_DEF_TIME_CB),	"DEF_TIME_CB"},
        +{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT),	"ESS_ADD_SIGNING_CERT"},
        +{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT),	"ESS_CERT_ID_NEW_INIT"},
        +{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT),	"ESS_SIGNING_CERT_NEW_INIT"},
        +{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN),	"INT_TS_RESP_VERIFY_TOKEN"},
        +{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO),	"PKCS7_to_TS_TST_INFO"},
        +{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS),	"TS_ACCURACY_set_micros"},
        +{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS),	"TS_ACCURACY_set_millis"},
        +{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS),	"TS_ACCURACY_set_seconds"},
        +{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS),	"TS_CHECK_IMPRINTS"},
        +{ERR_FUNC(TS_F_TS_CHECK_NONCES),	"TS_CHECK_NONCES"},
        +{ERR_FUNC(TS_F_TS_CHECK_POLICY),	"TS_CHECK_POLICY"},
        +{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS),	"TS_CHECK_SIGNING_CERTS"},
        +{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO),	"TS_CHECK_STATUS_INFO"},
        +{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT),	"TS_COMPUTE_IMPRINT"},
        +{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE),	"TS_CONF_set_default_engine"},
        +{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT),	"TS_GET_STATUS_TEXT"},
        +{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO),	"TS_MSG_IMPRINT_set_algo"},
        +{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT),	"TS_REQ_set_msg_imprint"},
        +{ERR_FUNC(TS_F_TS_REQ_SET_NONCE),	"TS_REQ_set_nonce"},
        +{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID),	"TS_REQ_set_policy_id"},
        +{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE),	"TS_RESP_create_response"},
        +{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO),	"TS_RESP_CREATE_TST_INFO"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),	"TS_RESP_CTX_add_failure_info"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD),	"TS_RESP_CTX_add_md"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY),	"TS_RESP_CTX_add_policy"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_NEW),	"TS_RESP_CTX_new"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY),	"TS_RESP_CTX_set_accuracy"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS),	"TS_RESP_CTX_set_certs"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY),	"TS_RESP_CTX_set_def_policy"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),	"TS_RESP_CTX_set_signer_cert"},
        +{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),	"TS_RESP_CTX_set_status_info"},
        +{ERR_FUNC(TS_F_TS_RESP_GET_POLICY),	"TS_RESP_GET_POLICY"},
        +{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),	"TS_RESP_SET_GENTIME_WITH_PRECISION"},
        +{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO),	"TS_RESP_set_status_info"},
        +{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO),	"TS_RESP_set_tst_info"},
        +{ERR_FUNC(TS_F_TS_RESP_SIGN),	"TS_RESP_SIGN"},
        +{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE),	"TS_RESP_verify_signature"},
        +{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN),	"TS_RESP_verify_token"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY),	"TS_TST_INFO_set_accuracy"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),	"TS_TST_INFO_set_msg_imprint"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE),	"TS_TST_INFO_set_nonce"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID),	"TS_TST_INFO_set_policy_id"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL),	"TS_TST_INFO_set_serial"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME),	"TS_TST_INFO_set_time"},
        +{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA),	"TS_TST_INFO_set_tsa"},
        +{ERR_FUNC(TS_F_TS_VERIFY),	"TS_VERIFY"},
        +{ERR_FUNC(TS_F_TS_VERIFY_CERT),	"TS_VERIFY_CERT"},
        +{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW),	"TS_VERIFY_CTX_new"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA TS_str_reasons[]=
        +	{
        +{ERR_REASON(TS_R_BAD_PKCS7_TYPE)         ,"bad pkcs7 type"},
        +{ERR_REASON(TS_R_BAD_TYPE)               ,"bad type"},
        +{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
        +{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE)   ,"could not set engine"},
        +{ERR_REASON(TS_R_COULD_NOT_SET_TIME)     ,"could not set time"},
        +{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"},
        +{ERR_REASON(TS_R_DETACHED_CONTENT)       ,"detached content"},
        +{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"},
        +{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"},
        +{ERR_REASON(TS_R_INVALID_NULL_POINTER)   ,"invalid null pointer"},
        +{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"},
        +{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"},
        +{ERR_REASON(TS_R_NONCE_MISMATCH)         ,"nonce mismatch"},
        +{ERR_REASON(TS_R_NONCE_NOT_RETURNED)     ,"nonce not returned"},
        +{ERR_REASON(TS_R_NO_CONTENT)             ,"no content"},
        +{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN)    ,"no time stamp token"},
        +{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
        +{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"},
        +{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"},
        +{ERR_REASON(TS_R_POLICY_MISMATCH)        ,"policy mismatch"},
        +{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
        +{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR)   ,"response setup error"},
        +{ERR_REASON(TS_R_SIGNATURE_FAILURE)      ,"signature failure"},
        +{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"},
        +{ERR_REASON(TS_R_TIME_SYSCALL_ERROR)     ,"time syscall error"},
        +{ERR_REASON(TS_R_TOKEN_NOT_PRESENT)      ,"token not present"},
        +{ERR_REASON(TS_R_TOKEN_PRESENT)          ,"token present"},
        +{ERR_REASON(TS_R_TSA_NAME_MISMATCH)      ,"tsa name mismatch"},
        +{ERR_REASON(TS_R_TSA_UNTRUSTED)          ,"tsa untrusted"},
        +{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR)   ,"tst info setup error"},
        +{ERR_REASON(TS_R_TS_DATASIGN)            ,"ts datasign"},
        +{ERR_REASON(TS_R_UNACCEPTABLE_POLICY)    ,"unacceptable policy"},
        +{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"},
        +{ERR_REASON(TS_R_UNSUPPORTED_VERSION)    ,"unsupported version"},
        +{ERR_REASON(TS_R_WRONG_CONTENT_TYPE)     ,"wrong content type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_TS_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(TS_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,TS_str_functs);
        +		ERR_load_strings(0,TS_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_lib.c b/vendor/openssl/openssl/crypto/ts/ts_lib.c
        new file mode 100644
        index 000000000..e8608dbf7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_lib.c
        @@ -0,0 +1,145 @@
        +/* crypto/ts/ts_lib.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/bn.h>
        +#include <openssl/x509v3.h>
        +#include "ts.h"
        +
        +/* Local function declarations. */
        +
        +/* Function definitions. */
        +
        +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
        +	{
        +	BIGNUM num_bn;
        +	int result = 0;
        +	char *hex;
        +
        +	BN_init(&num_bn);
        +	ASN1_INTEGER_to_BN(num, &num_bn);
        +	if ((hex = BN_bn2hex(&num_bn))) 
        +		{
        +		result = BIO_write(bio, "0x", 2) > 0;
        +		result = result && BIO_write(bio, hex, strlen(hex)) > 0;
        +		OPENSSL_free(hex);
        +		}
        +	BN_free(&num_bn);
        +
        +	return result;
        +	}
        +
        +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
        +	{
        +	char obj_txt[128];
        +
        +	int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
        +	BIO_write(bio, obj_txt, len);
        +	BIO_write(bio, "\n", 1);
        +
        +	return 1;
        +	}
        +
        +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
        +	{
        +	int i, critical, n;
        +	X509_EXTENSION *ex;
        +	ASN1_OBJECT *obj;
        +
        +	BIO_printf(bio, "Extensions:\n");
        +	n = X509v3_get_ext_count(extensions);
        +	for (i = 0; i < n; i++)
        +		{
        +		ex = X509v3_get_ext(extensions, i);
        +		obj = X509_EXTENSION_get_object(ex);
        +		i2a_ASN1_OBJECT(bio, obj);
        +		critical = X509_EXTENSION_get_critical(ex);
        +		BIO_printf(bio, ": %s\n", critical ? "critical" : "");
        +		if (!X509V3_EXT_print(bio, ex, 0, 4))
        +			{
        +			BIO_printf(bio, "%4s", "");
        +			M_ASN1_OCTET_STRING_print(bio, ex->value);
        +			}
        +		BIO_write(bio, "\n", 1);
        +		}
        +
        +	return 1;
        +	}
        +
        +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
        +	{
        +	int i = OBJ_obj2nid(alg->algorithm);
        +	return BIO_printf(bio, "Hash Algorithm: %s\n",
        +		(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
        +	}
        +
        +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
        +	{
        +	const ASN1_OCTET_STRING *msg;
        +
        +	TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a));
        +
        +	BIO_printf(bio, "Message data:\n");
        +	msg = TS_MSG_IMPRINT_get_msg(a);
        +	BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), 
        +			M_ASN1_STRING_length(msg), 4);
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_req_print.c b/vendor/openssl/openssl/crypto/ts/ts_req_print.c
        new file mode 100644
        index 000000000..eba12c382
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_req_print.c
        @@ -0,0 +1,102 @@
        +/* crypto/ts/ts_req_print.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/bn.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ts.h>
        +
        +/* Function definitions. */
        +
        +int TS_REQ_print_bio(BIO *bio, TS_REQ *a)
        +	{
        +	int v;
        +	ASN1_OBJECT *policy_id;
        +	const ASN1_INTEGER *nonce;
        +
        +	if (a == NULL) return 0;
        +
        +	v = TS_REQ_get_version(a);
        +	BIO_printf(bio, "Version: %d\n", v);
        +
        +	TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a));
        +
        +	BIO_printf(bio, "Policy OID: ");
        +	policy_id = TS_REQ_get_policy_id(a);
        +	if (policy_id == NULL)
        +		BIO_printf(bio, "unspecified\n");
        +	else	
        +		TS_OBJ_print_bio(bio, policy_id);
        +
        +	BIO_printf(bio, "Nonce: ");
        +	nonce = TS_REQ_get_nonce(a);
        +	if (nonce == NULL)
        +		BIO_printf(bio, "unspecified");
        +	else
        +		TS_ASN1_INTEGER_print_bio(bio, nonce);
        +	BIO_write(bio, "\n", 1);
        +
        +	BIO_printf(bio, "Certificate required: %s\n", 
        +		   TS_REQ_get_cert_req(a) ? "yes" : "no");
        +
        +	TS_ext_print_bio(bio, TS_REQ_get_exts(a));
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_req_utils.c b/vendor/openssl/openssl/crypto/ts/ts_req_utils.c
        new file mode 100644
        index 000000000..43280c158
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_req_utils.c
        @@ -0,0 +1,234 @@
        +/* crypto/ts/ts_req_utils.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ts.h>
        +
        +int TS_REQ_set_version(TS_REQ *a, long version)
        +	{
        +	return ASN1_INTEGER_set(a->version, version);
        +	}
        +
        +long TS_REQ_get_version(const TS_REQ *a)
        +	{
        +	return ASN1_INTEGER_get(a->version);
        +	}
        +
        +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
        +	{
        +	TS_MSG_IMPRINT *new_msg_imprint;
        +
        +	if (a->msg_imprint == msg_imprint)
        +		return 1;
        +	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
        +	if (new_msg_imprint == NULL)
        +		{
        +		TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	TS_MSG_IMPRINT_free(a->msg_imprint);
        +	a->msg_imprint = new_msg_imprint;
        +	return 1;
        +	}
        +
        +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a)
        +	{
        +	return a->msg_imprint;
        +	}
        +
        +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
        +	{
        +	X509_ALGOR *new_alg;
        +
        +	if (a->hash_algo == alg)
        +		return 1;
        +	new_alg = X509_ALGOR_dup(alg);
        +	if (new_alg == NULL)
        +		{
        +		TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	X509_ALGOR_free(a->hash_algo);
        +	a->hash_algo = new_alg;
        +	return 1;
        +	}
        +
        +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
        +	{
        +	return a->hash_algo;
        +	}
        +
        +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
        +	{
        +	return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
        +	}
        +
        +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
        +	{
        +	return a->hashed_msg;
        +	}
        +
        +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy)
        +	{
        +	ASN1_OBJECT *new_policy;
        +
        +	if (a->policy_id == policy)
        +		return 1;
        +	new_policy = OBJ_dup(policy);
        +	if (new_policy == NULL)
        +		{
        +		TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_OBJECT_free(a->policy_id);
        +	a->policy_id = new_policy;
        +	return 1;
        +	}
        +
        +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a)
        +	{
        +	return a->policy_id;
        +	}
        +
        +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
        +	{
        +	ASN1_INTEGER *new_nonce;
        +
        +	if (a->nonce == nonce)
        +		return 1;
        +	new_nonce = ASN1_INTEGER_dup(nonce);
        +	if (new_nonce == NULL)
        +		{
        +		TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_INTEGER_free(a->nonce);
        +	a->nonce = new_nonce;
        +	return 1;
        +	}
        +
        +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a)
        +	{
        +	return a->nonce;
        +	}
        +
        +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
        +	{
        +	a->cert_req = cert_req ? 0xFF : 0x00;
        +	return 1;
        +	}
        +
        +int TS_REQ_get_cert_req(const TS_REQ *a)
        +	{
        +	return a->cert_req ? 1 : 0;
        +	}
        +
        +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
        +	{
        +	return a->extensions;
        +	}
        +
        +void TS_REQ_ext_free(TS_REQ *a)
        +	{
        +	if (!a) return;
        +	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
        +	a->extensions = NULL;
        +	}
        +
        +int TS_REQ_get_ext_count(TS_REQ *a)
        +	{
        +	return X509v3_get_ext_count(a->extensions);
        +	}
        +
        +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
        +	{
        +	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
        +	}
        +
        +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
        +	}
        +
        +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
        +	{
        +	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
        +	}
        +
        +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc)
        +	{
        +	return X509v3_get_ext(a->extensions,loc);
        +	}
        +
        +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc)
        +	{
        +	return X509v3_delete_ext(a->extensions,loc);
        +	}
        +
        +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
        +	{
        +	return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
        +	}
        +
        +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
        +	{
        +	return X509V3_get_d2i(a->extensions, nid, crit, idx);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_rsp_print.c b/vendor/openssl/openssl/crypto/ts/ts_rsp_print.c
        new file mode 100644
        index 000000000..21062517b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_rsp_print.c
        @@ -0,0 +1,287 @@
        +/* crypto/ts/ts_resp_print.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/bn.h>
        +#include <openssl/x509v3.h>
        +#include "ts.h"
        +
        +struct status_map_st
        +	{
        +	int bit;
        +	const char *text;
        +	};
        +
        +/* Local function declarations. */
        +
        +static int TS_status_map_print(BIO *bio, struct status_map_st *a,
        +			       ASN1_BIT_STRING *v);
        +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);
        +
        +/* Function definitions. */
        +
        +int TS_RESP_print_bio(BIO *bio, TS_RESP *a)
        +	{
        +	TS_TST_INFO *tst_info;
        +
        +	BIO_printf(bio, "Status info:\n");
        +	TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a));
        +
        +	BIO_printf(bio, "\nTST info:\n");
        +	tst_info = TS_RESP_get_tst_info(a);
        +	if (tst_info != NULL)
        +		TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a));
        +	else
        +		BIO_printf(bio, "Not included.\n");
        +		
        +	return 1;
        +	}
        +
        +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
        +	{
        +	static const char *status_map[] =
        +		{
        +		"Granted.",
        +		"Granted with modifications.",
        +		"Rejected.",
        +		"Waiting.",
        +		"Revocation warning.",
        +		"Revoked."
        +		};
        +	static struct status_map_st failure_map[] =
        +		{
        +		{ TS_INFO_BAD_ALG,
        +		"unrecognized or unsupported algorithm identifier" },
        +		{ TS_INFO_BAD_REQUEST,
        +		"transaction not permitted or supported" },
        +		{ TS_INFO_BAD_DATA_FORMAT,
        +		"the data submitted has the wrong format" },
        +		{ TS_INFO_TIME_NOT_AVAILABLE,
        +		"the TSA's time source is not available" },
        +		{ TS_INFO_UNACCEPTED_POLICY,
        +		"the requested TSA policy is not supported by the TSA" },
        +		{ TS_INFO_UNACCEPTED_EXTENSION,
        +		"the requested extension is not supported by the TSA" },
        +		{ TS_INFO_ADD_INFO_NOT_AVAILABLE,
        +		"the additional information requested could not be understood "
        +		"or is not available" },
        +		{ TS_INFO_SYSTEM_FAILURE,
        +		"the request cannot be handled due to system failure" },
        +		{ -1, NULL }
        +		};
        +	long status;
        +	int i, lines = 0;
        +
        +	/* Printing status code. */
        +	BIO_printf(bio, "Status: ");
        +	status = ASN1_INTEGER_get(a->status);
        +	if (0 <= status && status < (long)(sizeof(status_map)/sizeof(status_map[0])))
        +		BIO_printf(bio, "%s\n", status_map[status]);
        +	else
        +		BIO_printf(bio, "out of bounds\n");
        +	
        +	/* Printing status description. */
        +	BIO_printf(bio, "Status description: ");
        +	for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i)
        +		{
        +		if (i > 0)
        +			BIO_puts(bio, "\t");
        +		ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i),
        +				     0);
        +		BIO_puts(bio, "\n");
        +		}
        +	if (i == 0)
        +		BIO_printf(bio, "unspecified\n");
        +
        +	/* Printing failure information. */
        +	BIO_printf(bio, "Failure info: ");
        +	if (a->failure_info != NULL)
        +		lines = TS_status_map_print(bio, failure_map,
        +					    a->failure_info);
        +	if (lines == 0)
        +		BIO_printf(bio, "unspecified");
        +	BIO_printf(bio, "\n");
        +
        +	return 1;
        +	}
        +
        +static int TS_status_map_print(BIO *bio, struct status_map_st *a,
        +			       ASN1_BIT_STRING *v)
        +	{
        +	int lines = 0;
        +
        +	for (; a->bit >= 0; ++a)
        +		{
        +		if (ASN1_BIT_STRING_get_bit(v, a->bit))
        +			{
        +			if (++lines > 1)
        +				BIO_printf(bio, ", ");
        +			BIO_printf(bio, "%s", a->text);
        +			}
        +		}
        +
        +	return lines;
        +	}
        +
        +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
        +	{
        +	int v;
        +	ASN1_OBJECT *policy_id;
        +	const ASN1_INTEGER *serial;
        +	const ASN1_GENERALIZEDTIME *gtime;
        +	TS_ACCURACY *accuracy;
        +	const ASN1_INTEGER *nonce;
        +	GENERAL_NAME *tsa_name;
        +
        +	if (a == NULL) return 0;
        +
        +	/* Print version. */
        +	v = TS_TST_INFO_get_version(a);
        +	BIO_printf(bio, "Version: %d\n", v);
        +
        +	/* Print policy id. */
        +	BIO_printf(bio, "Policy OID: ");
        +	policy_id = TS_TST_INFO_get_policy_id(a);
        +	TS_OBJ_print_bio(bio, policy_id);
        +
        +	/* Print message imprint. */
        +	TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a));
        +
        +	/* Print serial number. */
        +	BIO_printf(bio, "Serial number: ");
        +	serial = TS_TST_INFO_get_serial(a);
        +	if (serial == NULL)
        +		BIO_printf(bio, "unspecified");
        +	else
        +		TS_ASN1_INTEGER_print_bio(bio, serial);
        +	BIO_write(bio, "\n", 1);
        +
        +	/* Print time stamp. */
        +	BIO_printf(bio, "Time stamp: ");
        +	gtime = TS_TST_INFO_get_time(a);
        +	ASN1_GENERALIZEDTIME_print(bio, gtime);
        +	BIO_write(bio, "\n", 1);
        +
        +	/* Print accuracy. */
        +	BIO_printf(bio, "Accuracy: ");
        +	accuracy = TS_TST_INFO_get_accuracy(a);
        +	if (accuracy == NULL)
        +		BIO_printf(bio, "unspecified");
        +	else
        +		TS_ACCURACY_print_bio(bio, accuracy);
        +	BIO_write(bio, "\n", 1);
        +
        +	/* Print ordering. */
        +	BIO_printf(bio, "Ordering: %s\n", 
        +		   TS_TST_INFO_get_ordering(a) ? "yes" : "no");
        +
        +	/* Print nonce. */
        +	BIO_printf(bio, "Nonce: ");
        +	nonce = TS_TST_INFO_get_nonce(a);
        +	if (nonce == NULL)
        +		BIO_printf(bio, "unspecified");
        +	else
        +		TS_ASN1_INTEGER_print_bio(bio, nonce);
        +	BIO_write(bio, "\n", 1);
        +
        +	/* Print TSA name. */
        +	BIO_printf(bio, "TSA: ");
        +	tsa_name = TS_TST_INFO_get_tsa(a);
        +	if (tsa_name == NULL)
        +		BIO_printf(bio, "unspecified");
        +	else
        +		{
        +		STACK_OF(CONF_VALUE) *nval;
        +		if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL)))
        +			X509V3_EXT_val_prn(bio, nval, 0, 0);
        +		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
        +		}
        +	BIO_write(bio, "\n", 1);
        +
        +	/* Print extensions. */
        +	TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a));
        +
        +	return 1;
        +	}
        +
        +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy)
        +	{
        +	const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy);
        +	const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy);
        +	const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy);
        +
        +	if (seconds != NULL)
        +		TS_ASN1_INTEGER_print_bio(bio, seconds);
        +	else
        +		BIO_printf(bio, "unspecified");
        +	BIO_printf(bio, " seconds, ");
        +	if (millis != NULL)
        +		TS_ASN1_INTEGER_print_bio(bio, millis);
        +	else
        +		BIO_printf(bio, "unspecified");
        +	BIO_printf(bio, " millis, ");
        +	if (micros != NULL)
        +		TS_ASN1_INTEGER_print_bio(bio, micros);
        +	else
        +		BIO_printf(bio, "unspecified");
        +	BIO_printf(bio, " micros");
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_rsp_sign.c b/vendor/openssl/openssl/crypto/ts/ts_rsp_sign.c
        new file mode 100644
        index 000000000..b0f023c9d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_rsp_sign.c
        @@ -0,0 +1,1020 @@
        +/* crypto/ts/ts_resp_sign.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 "cryptlib.h"
        +
        +#if defined(OPENSSL_SYS_UNIX)
        +#include <sys/time.h>
        +#endif
        +
        +#include <openssl/objects.h>
        +#include <openssl/ts.h>
        +#include <openssl/pkcs7.h>
        +
        +/* Private function declarations. */
        +
        +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
        +static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
        +static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
        +
        +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
        +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
        +static int TS_RESP_check_request(TS_RESP_CTX *ctx);
        +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
        +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, 
        +					    ASN1_OBJECT *policy);
        +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
        +static int TS_RESP_sign(TS_RESP_CTX *ctx);
        +
        +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
        +						   STACK_OF(X509) *certs);
        +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
        +static int TS_TST_INFO_content_new(PKCS7 *p7);
        +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
        +
        +static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
        +	ASN1_GENERALIZEDTIME *, long, long, unsigned);
        +
        +/* Default callbacks for response generation. */
        +
        +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
        +	{
        +	ASN1_INTEGER *serial = ASN1_INTEGER_new();
        +	if (!serial) goto err;
        +	if (!ASN1_INTEGER_set(serial, 1)) goto err;
        +	return serial;
        + err:
        +	TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
        +	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +				    "Error during serial number generation.");
        +	return NULL;
        +	}
        +
        +#if defined(OPENSSL_SYS_UNIX)
        +
        +/* Use the gettimeofday function call. */
        +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
        +		       long *sec, long *usec)
        +	{
        +	struct timeval tv;
        +	if (gettimeofday(&tv, NULL) != 0) 
        +		{
        +		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Time is not available.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
        +		return 0;
        +		}
        +	/* Return time to caller. */
        +	*sec = tv.tv_sec;
        +	*usec = tv.tv_usec;
        +
        +	return 1;
        +	}
        +
        +#else
        +
        +/* Use the time function call that provides only seconds precision. */
        +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
        +		       long *sec, long *usec)
        +	{
        +	time_t t;
        +	if (time(&t) == (time_t) -1)
        +		{
        +		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Time is not available.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
        +		return 0;
        +		}
        +	/* Return time to caller, only second precision. */
        +	*sec = (long) t;
        +	*usec = 0;
        +
        +	return 1;
        +	}
        +
        +#endif
        +
        +static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
        +			    void *data)
        +	{
        +	/* No extensions are processed here. */
        +	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +				    "Unsupported extension.");
        +	TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
        +	return 0;
        +	}
        +
        +/* TS_RESP_CTX management functions. */
        +
        +TS_RESP_CTX *TS_RESP_CTX_new()
        +	{
        +	TS_RESP_CTX *ctx;
        +
        +	if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX))))
        +		{
        +		TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	memset(ctx, 0, sizeof(TS_RESP_CTX));
        +
        +	/* Setting default callbacks. */
        +	ctx->serial_cb = def_serial_cb;
        +	ctx->time_cb = def_time_cb;
        +	ctx->extension_cb = def_extension_cb;
        +
        +	return ctx;
        +	}
        +
        +void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
        +	{
        +	if (!ctx) return;
        +
        +	X509_free(ctx->signer_cert);
        +	EVP_PKEY_free(ctx->signer_key);
        +	sk_X509_pop_free(ctx->certs, X509_free);
        +	sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
        +	ASN1_OBJECT_free(ctx->default_policy);
        +	sk_EVP_MD_free(ctx->mds);	/* No EVP_MD_free method exists. */
        +	ASN1_INTEGER_free(ctx->seconds);
        +	ASN1_INTEGER_free(ctx->millis);
        +	ASN1_INTEGER_free(ctx->micros);
        +	OPENSSL_free(ctx);
        +	}
        +
        +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
        +	{
        +	if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1)
        +		{
        +		TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, 
        +		      TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
        +		return 0;
        +		}
        +	if (ctx->signer_cert) X509_free(ctx->signer_cert);
        +	ctx->signer_cert = signer;
        +	CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
        +	return 1;
        +	}
        +
        +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
        +	{
        +	if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key);
        +	ctx->signer_key = key;
        +	CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);
        +
        +	return 1;
        +	}
        +
        +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
        +	{
        +	if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy);
        +	if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err;
        +	return 1;
        + err:
        +	TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
        +	{
        +	int i;
        +
        +	if (ctx->certs)
        +		{
        +		sk_X509_pop_free(ctx->certs, X509_free);
        +		ctx->certs = NULL;
        +		}
        +	if (!certs) return 1;
        +	if (!(ctx->certs = sk_X509_dup(certs))) 
        +		{
        +		TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	for (i = 0; i < sk_X509_num(ctx->certs); ++i)
        +		{
        +		X509 *cert = sk_X509_value(ctx->certs, i);
        +		CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);
        +		}
        +
        +	return 1;
        +	}
        +
        +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
        +	{
        +	ASN1_OBJECT *copy = NULL;
        +
        +	/* Create new policy stack if necessary. */
        +	if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) 
        +		goto err;
        +	if (!(copy = OBJ_dup(policy))) goto err;
        +	if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err;
        +
        +	return 1;
        + err:
        +	TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
        +	ASN1_OBJECT_free(copy);
        +	return 0;
        +	}
        +
        +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
        +	{
        +	/* Create new md stack if necessary. */
        +	if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) 
        +		goto err;
        +	/* Add the shared md, no copy needed. */
        +	if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err;
        +
        +	return 1;
        + err:
        +	TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +#define TS_RESP_CTX_accuracy_free(ctx)		\
        +	ASN1_INTEGER_free(ctx->seconds);	\
        +	ctx->seconds = NULL;			\
        +	ASN1_INTEGER_free(ctx->millis);		\
        +	ctx->millis = NULL;			\
        +	ASN1_INTEGER_free(ctx->micros);		\
        +	ctx->micros = NULL;
        +
        +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, 
        +			     int secs, int millis, int micros)
        +	{
        +
        +	TS_RESP_CTX_accuracy_free(ctx);
        +	if (secs && (!(ctx->seconds = ASN1_INTEGER_new())
        +		     || !ASN1_INTEGER_set(ctx->seconds, secs)))
        +		goto err;
        +	if (millis && (!(ctx->millis = ASN1_INTEGER_new())
        +		       || !ASN1_INTEGER_set(ctx->millis, millis)))
        +		goto err;
        +	if (micros && (!(ctx->micros = ASN1_INTEGER_new())
        +		       || !ASN1_INTEGER_set(ctx->micros, micros)))
        +		goto err;
        +
        +	return 1;
        + err:
        +	TS_RESP_CTX_accuracy_free(ctx);
        +	TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
        +	{
        +	ctx->flags |= flags;
        +	}
        +
        +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
        +	{
        +	ctx->serial_cb = cb;
        +	ctx->serial_cb_data = data;
        +	}
        +
        +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
        +	{
        +	ctx->time_cb = cb;
        +	ctx->time_cb_data = data;
        +	}
        +
        +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
        +				  TS_extension_cb cb, void *data)
        +	{
        +	ctx->extension_cb = cb;
        +	ctx->extension_cb_data = data;
        +	}
        +
        +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
        +				int status, const char *text)
        +	{
        +	TS_STATUS_INFO *si = NULL;
        +	ASN1_UTF8STRING *utf8_text = NULL;
        +	int ret = 0;
        +
        +	if (!(si = TS_STATUS_INFO_new())) goto err;
        +	if (!ASN1_INTEGER_set(si->status, status)) goto err;
        +	if (text)
        +		{
        +		if (!(utf8_text = ASN1_UTF8STRING_new())
        +		    || !ASN1_STRING_set(utf8_text, text, strlen(text)))
        +			goto err;
        +		if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
        +			goto err;
        +		if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err;
        +		utf8_text = NULL;	/* Ownership is lost. */
        +		}
        +	if (!TS_RESP_set_status_info(ctx->response, si)) goto err;
        +	ret = 1;
        + err:
        +	if (!ret)
        +		TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
        +	TS_STATUS_INFO_free(si);
        +	ASN1_UTF8STRING_free(utf8_text);
        +	return ret;
        +	}
        +
        +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
        +				     int status, const char *text)
        +	{
        +	int ret = 1;
        +	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
        +
        +	if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED)
        +		{
        +		/* Status has not been set, set it now. */
        +		ret = TS_RESP_CTX_set_status_info(ctx, status, text);
        +		}
        +	return ret;
        +	}
        +
        +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
        +	{
        +	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
        +	if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
        +		goto err;
        +	if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
        +		goto err;
        +	return 1;
        + err:
        +	TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
        +	{
        +	return ctx->request;
        +	}
        +
        +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
        +	{
        +	return ctx->tst_info;
        +	}
        +
        +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
        +       {
        +       if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
        +	       return 0;
        +       ctx->clock_precision_digits = precision;
        +       return 1;
        +       }
        +
        +/* Main entry method of the response generation. */
        +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
        +	{
        +	ASN1_OBJECT *policy;
        +	TS_RESP *response;
        +	int result = 0;
        +
        +	TS_RESP_CTX_init(ctx);
        +
        +	/* Creating the response object. */
        +	if (!(ctx->response = TS_RESP_new())) 
        +		{
        +		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
        +		goto end;
        +		}
        +
        +	/* Parsing DER request. */
        +	if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL)))
        +		{
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Bad request format or "
        +					    "system error.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
        +		goto end;
        +		}
        +
        +	/* Setting default status info. */
        +	if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
        +		goto end;
        +
        +	/* Checking the request format. */
        +	if (!TS_RESP_check_request(ctx)) goto end;
        +
        +	/* Checking acceptable policies. */
        +	if (!(policy = TS_RESP_get_policy(ctx))) goto end;
        +
        +	/* Creating the TS_TST_INFO object. */
        +	if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
        +		goto end;
        +
        +	/* Processing extensions. */
        +	if (!TS_RESP_process_extensions(ctx)) goto end;
        +
        +	/* Generating the signature. */
        +	if (!TS_RESP_sign(ctx)) goto end;
        +
        +	/* Everything was successful. */
        +	result = 1;
        + end:
        +	if (!result)
        +		{
        +		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
        +		if (ctx->response != NULL)
        +			{
        +			if (TS_RESP_CTX_set_status_info_cond(ctx,
        +				TS_STATUS_REJECTION, "Error during response "
        +				"generation.") == 0)
        +				{
        +				TS_RESP_free(ctx->response);
        +				ctx->response = NULL;
        +				}
        +			}
        +		}
        +	response = ctx->response;
        +	ctx->response = NULL;	/* Ownership will be returned to caller. */
        +	TS_RESP_CTX_cleanup(ctx);
        +	return response;
        +	}
        +
        +/* Initializes the variable part of the context. */
        +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx)
        +	{
        +	ctx->request = NULL;
        +	ctx->response = NULL;
        +	ctx->tst_info = NULL;
        +	}
        +
        +/* Cleans up the variable part of the context. */
        +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
        +	{
        +	TS_REQ_free(ctx->request);
        +	ctx->request = NULL;
        +	TS_RESP_free(ctx->response);
        +	ctx->response = NULL;
        +	TS_TST_INFO_free(ctx->tst_info);
        +	ctx->tst_info = NULL;
        +	}
        +
        +/* Checks the format and content of the request. */
        +static int TS_RESP_check_request(TS_RESP_CTX *ctx)
        +	{
        +	TS_REQ *request = ctx->request;
        +	TS_MSG_IMPRINT *msg_imprint;
        +	X509_ALGOR *md_alg;
        +	int md_alg_id;
        +	const ASN1_OCTET_STRING *digest;
        +	EVP_MD *md = NULL;
        +	int i;
        +
        +	/* Checking request version. */
        +	if (TS_REQ_get_version(request) != 1)
        +		{
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Bad request version.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
        +		return 0;
        +		}
        +
        +	/* Checking message digest algorithm. */
        +	msg_imprint = TS_REQ_get_msg_imprint(request);
        +	md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
        +	md_alg_id = OBJ_obj2nid(md_alg->algorithm);
        +	for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i)
        +		{
        +		EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
        +		if (md_alg_id == EVP_MD_type(current_md))
        +			md = current_md;
        +		}
        +	if (!md)
        +		{
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Message digest algorithm is "
        +					    "not supported.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
        +		return 0;
        +		}
        +
        +	/* No message digest takes parameter. */
        +	if (md_alg->parameter 
        +	    && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL)
        +		{
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Superfluous message digest "
        +					    "parameter.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
        +		return 0;
        +		}
        +	/* Checking message digest size. */
        +	digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
        +	if (digest->length != EVP_MD_size(md))
        +		{
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Bad message digest.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +/* Returns the TSA policy based on the requested and acceptable policies. */
        +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx)
        +	{
        +	ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
        +	ASN1_OBJECT *policy = NULL;
        +	int i;
        +
        +	if (ctx->default_policy == NULL)
        +		{
        +		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
        +		return NULL;
        +		}
        +	/* Return the default policy if none is requested or the default is
        +	   requested. */
        +	if (!requested || !OBJ_cmp(requested, ctx->default_policy))
        +		policy = ctx->default_policy;
        +
        +	/* Check if the policy is acceptable. */
        +	for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i)
        +		{
        +		ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
        +		if (!OBJ_cmp(requested, current))
        +			policy = current;
        +		}
        +	if (!policy)
        +		{
        +		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
        +		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
        +					    "Requested policy is not "
        +					    "supported.");
        +		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
        +		}
        +	return policy;
        +	}
        +
        +/* Creates the TS_TST_INFO object based on the settings of the context. */
        +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
        +					    ASN1_OBJECT *policy)
        +	{
        +	int result = 0;
        +	TS_TST_INFO *tst_info = NULL;
        +	ASN1_INTEGER *serial = NULL;
        +	ASN1_GENERALIZEDTIME *asn1_time = NULL;
        +	long sec, usec;
        +	TS_ACCURACY *accuracy = NULL;
        +	const ASN1_INTEGER *nonce;
        +	GENERAL_NAME *tsa_name = NULL;
        +
        +	if (!(tst_info = TS_TST_INFO_new())) goto end;
        +	if (!TS_TST_INFO_set_version(tst_info, 1)) goto end;
        +	if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end;
        +	if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
        +		goto end;
        +	if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data))
        +	    || !TS_TST_INFO_set_serial(tst_info, serial))
        +		goto end;
        +	if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec)
        +            || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, 
        +					sec, usec, 
        +					ctx->clock_precision_digits))
        +	    || !TS_TST_INFO_set_time(tst_info, asn1_time))
        +		goto end;
        +
        +	/* Setting accuracy if needed. */
        +	if ((ctx->seconds || ctx->millis || ctx->micros) 
        +	    && !(accuracy = TS_ACCURACY_new()))
        +		goto end;
        +
        +	if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
        +		goto end;
        +	if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
        +		goto end;
        +	if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
        +		goto end;
        +	if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) 
        +		goto end;
        +
        +	/* Setting ordering. */
        +	if ((ctx->flags & TS_ORDERING) 
        +	    && !TS_TST_INFO_set_ordering(tst_info, 1))
        +		goto end;
        +	
        +	/* Setting nonce if needed. */
        +	if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL
        +	    && !TS_TST_INFO_set_nonce(tst_info, nonce))
        +		goto end;
        +
        +	/* Setting TSA name to subject of signer certificate. */
        +	if (ctx->flags & TS_TSA_NAME)
        +		{
        +		if (!(tsa_name = GENERAL_NAME_new())) goto end;
        +		tsa_name->type = GEN_DIRNAME;
        +		tsa_name->d.dirn = 
        +			X509_NAME_dup(ctx->signer_cert->cert_info->subject);
        +		if (!tsa_name->d.dirn) goto end;
        +		if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end;
        +		}
        +
        +	result = 1;
        + end:
        +	if (!result)
        +		{
        +		TS_TST_INFO_free(tst_info);
        +		tst_info = NULL;
        +		TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
        +		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
        +						 "Error during TSTInfo "
        +						 "generation.");
        +		}
        +	GENERAL_NAME_free(tsa_name);
        +	TS_ACCURACY_free(accuracy);
        +	ASN1_GENERALIZEDTIME_free(asn1_time);
        +	ASN1_INTEGER_free(serial);
        +	
        +	return tst_info;
        +	}
        +
        +/* Processing the extensions of the request. */
        +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx)
        +	{
        +	STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
        +	int i;
        +	int ok = 1;
        +
        +	for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i)
        +		{
        +		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
        +		/* XXXXX The last argument was previously
        +		   (void *)ctx->extension_cb, but ISO C doesn't permit
        +		   converting a function pointer to void *.  For lack of
        +		   better information, I'm placing a NULL there instead.
        +		   The callback can pick its own address out from the ctx
        +		   anyway...
        +		*/
        +		ok = (*ctx->extension_cb)(ctx, ext, NULL);
        +		}
        +
        +	return ok;
        +	}
        +
        +/* Functions for signing the TS_TST_INFO structure of the context. */
        +static int TS_RESP_sign(TS_RESP_CTX *ctx)
        +	{
        +	int ret = 0;
        +	PKCS7 *p7 = NULL;
        +	PKCS7_SIGNER_INFO *si;
        +	STACK_OF(X509) *certs;	/* Certificates to include in sc. */
        +	ESS_SIGNING_CERT *sc = NULL;
        +	ASN1_OBJECT *oid;
        +	BIO *p7bio = NULL;
        +	int i;
        +
        +	/* Check if signcert and pkey match. */
        +	if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
        +		TSerr(TS_F_TS_RESP_SIGN, 
        +		      TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        +                goto err;
        +	}
        +
        +	/* Create a new PKCS7 signed object. */
        +	if (!(p7 = PKCS7_new())) {
        +		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +	if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err;
        +
        +	/* Force SignedData version to be 3 instead of the default 1. */
        +	if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err;
        +
        +	/* Add signer certificate and optional certificate chain. */
        +	if (TS_REQ_get_cert_req(ctx->request))
        +		{
        +		PKCS7_add_certificate(p7, ctx->signer_cert);
        +		if (ctx->certs)
        +			{
        +			for(i = 0; i < sk_X509_num(ctx->certs); ++i) 
        +				{
        +				X509 *cert = sk_X509_value(ctx->certs, i);
        +				PKCS7_add_certificate(p7, cert);
        +				}
        +			}
        +		}
        +
        +	/* Add a new signer info. */
        +    	if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, 
        +				       ctx->signer_key, EVP_sha1())))
        +		{
        +		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
        +		goto err;
        +		}
        +
        +	/* Add content type signed attribute to the signer info. */
        +	oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
        +	if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
        +					V_ASN1_OBJECT, oid))
        +		{
        +		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
        +		goto err;
        +		}
        +
        +	/* Create the ESS SigningCertificate attribute which contains 
        +	   the signer certificate id and optionally the certificate chain. */
        +	certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
        +	if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
        +		goto err;
        +
        +	/* Add SigningCertificate signed attribute to the signer info. */
        +	if (!ESS_add_signing_cert(si, sc))
        +		{
        +		TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
        +		goto err;
        +		}	
        +
        +	/* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
        +	if (!TS_TST_INFO_content_new(p7)) goto err;
        +
        +	/* Add the DER encoded tst_info to the PKCS7 structure. */
        +	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
        +		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +
        +	/* Convert tst_info to DER. */
        +	if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info))
        +		{
        +		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
        +		goto err;
        +		}
        +
        +	/* Create the signature and add it to the signer info. */
        +        if (!PKCS7_dataFinal(p7, p7bio))
        +		{
        +		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
        +		goto err;
        +		}
        +
        +	/* Set new PKCS7 and TST_INFO objects. */
        +	TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
        +	p7 = NULL;		/* Ownership is lost. */
        +	ctx->tst_info = NULL;	/* Ownership is lost. */
        +
        +	ret = 1;
        + err:
        +	if (!ret)
        +		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
        +						 "Error during signature "
        +						 "generation.");
        +	BIO_free_all(p7bio);
        +	ESS_SIGNING_CERT_free(sc);
        +	PKCS7_free(p7);
        +	return ret;
        +	}
        +
        +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
        +						   STACK_OF(X509) *certs)
        +	{
        +	ESS_CERT_ID *cid;
        +	ESS_SIGNING_CERT *sc = NULL;
        +	int i;
        +
        +	/* Creating the ESS_CERT_ID stack. */
        +	if (!(sc = ESS_SIGNING_CERT_new())) goto err;
        +	if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
        +		goto err;
        +
        +	/* Adding the signing certificate id. */
        +	if (!(cid = ESS_CERT_ID_new_init(signcert, 0))
        +	    || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
        +		goto err;
        +	/* Adding the certificate chain ids. */
        +	for (i = 0; i < sk_X509_num(certs); ++i)
        +		{
        +		X509 *cert = sk_X509_value(certs, i);
        +		if (!(cid = ESS_CERT_ID_new_init(cert, 1))
        +		    || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
        +			goto err;
        +		}
        +
        +	return sc;
        +err:
        +	ESS_SIGNING_CERT_free(sc);
        +	TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +	}
        +
        +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
        +	{
        +	ESS_CERT_ID *cid = NULL;
        +	GENERAL_NAME *name = NULL;
        +	
        +	/* Recompute SHA1 hash of certificate if necessary (side effect). */
        +	X509_check_purpose(cert, -1, 0);
        +
        +	if (!(cid = ESS_CERT_ID_new())) goto err;
        +	if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
        +				   sizeof(cert->sha1_hash)))
        +		goto err;
        +
        +	/* Setting the issuer/serial if requested. */
        +	if (issuer_needed)
        +		{
        +		/* Creating issuer/serial structure. */
        +		if (!cid->issuer_serial
        +		    && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
        +			goto err;
        +		/* Creating general name from the certificate issuer. */
        +		if (!(name = GENERAL_NAME_new())) goto err;
        +		name->type = GEN_DIRNAME;
        +		if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) 
        +			goto err;
        +		if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) 
        +			goto err;
        +		name = NULL;	/* Ownership is lost. */
        +		/* Setting the serial number. */
        +		ASN1_INTEGER_free(cid->issuer_serial->serial);
        +		if (!(cid->issuer_serial->serial = 
        +		      ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
        +			goto err;
        +		}
        +
        +	return cid;
        +err:
        +	GENERAL_NAME_free(name);
        +	ESS_CERT_ID_free(cid);
        +	TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +	}
        +
        +static int TS_TST_INFO_content_new(PKCS7 *p7)
        +	{
        +	PKCS7 *ret = NULL;
        +	ASN1_OCTET_STRING *octet_string = NULL;
        +
        +	/* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
        +	if (!(ret = PKCS7_new())) goto err;
        +	if (!(ret->d.other = ASN1_TYPE_new())) goto err;
        +	ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
        +	if (!(octet_string = ASN1_OCTET_STRING_new())) goto err;
        +	ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
        +	octet_string = NULL;
        +
        +	/* Add encapsulated content to signed PKCS7 structure. */
        +	if (!PKCS7_set_content(p7, ret)) goto err;
        +
        +	return 1;
        + err:
        +	ASN1_OCTET_STRING_free(octet_string);
        +	PKCS7_free(ret);
        +	return 0;
        +	}
        +
        +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
        +	{
        +	ASN1_STRING *seq = NULL;
        +	unsigned char *p, *pp = NULL;
        +	int len;
        +
        +	len = i2d_ESS_SIGNING_CERT(sc, NULL);
        +	if (!(pp = (unsigned char *) OPENSSL_malloc(len)))
        +		{
        +		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	p = pp;
        +	i2d_ESS_SIGNING_CERT(sc, &p);
        +	if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
        +		{
        +		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	OPENSSL_free(pp); pp = NULL;
        +	return PKCS7_add_signed_attribute(si, 
        +					  NID_id_smime_aa_signingCertificate,
        +					  V_ASN1_SEQUENCE, seq);
        + err:
        +	ASN1_STRING_free(seq);
        +	OPENSSL_free(pp);
        +
        +	return 0;
        +	}
        +
        +
        +static ASN1_GENERALIZEDTIME *
        +TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, 
        +				   long sec, long usec, unsigned precision)
        +	{
        +	time_t time_sec = (time_t) sec;
        +	struct tm *tm = NULL;	
        +	char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
        +	char *p = genTime_str;
        +	char *p_end = genTime_str + sizeof(genTime_str);
        +
        +	if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
        +		goto err;
        +
        +	
        +	if (!(tm = gmtime(&time_sec)))
        +		goto err;
        +
        +	/* 
        +	 * Put "genTime_str" in GeneralizedTime format.  We work around the 
        +	 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST 
        +	 * NOT include fractional seconds") and OpenSSL related functions to 
        +	 * meet the rfc3161 requirement: "GeneralizedTime syntax can include 
        +	 * fraction-of-second details". 
        +	 */                   
        +	p += BIO_snprintf(p, p_end - p,
        +			  "%04d%02d%02d%02d%02d%02d",
        +			  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
        +			  tm->tm_hour, tm->tm_min, tm->tm_sec);
        +	if (precision > 0)
        +	{
        +		/* Add fraction of seconds (leave space for dot and null). */
        +		BIO_snprintf(p, 2 + precision, ".%ld", usec);
        +		/* We cannot use the snprintf return value, 
        +		   because it might have been truncated. */
        +		p += strlen(p);
        +
        +		/* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
        +		   the following restrictions for a DER-encoding, which OpenSSL
        +		   (specifically ASN1_GENERALIZEDTIME_check() function) doesn't 
        +		   support:
        +		   "The encoding MUST terminate with a "Z" (which means "Zulu" 
        +		   time). The decimal point element, if present, MUST be the 
        +		   point option ".". The fractional-seconds elements, 
        +		   if present, MUST omit all trailing 0's; 
        +		   if the elements correspond to 0, they MUST be wholly
        +		   omitted, and the decimal point element also MUST be
        +		   omitted." */
        +		/* Remove trailing zeros. The dot guarantees the exit
        +		   condition of this loop even if all the digits are zero. */
        +		while (*--p == '0')
        +			/* empty */;
        +		/* p points to either the dot or the last non-zero digit. */
        +		if (*p != '.') ++p;
        +		}
        +	/* Add the trailing Z and the terminating null. */
        +	*p++ = 'Z';
        +	*p++ = '\0';
        +
        +	/* Now call OpenSSL to check and set our genTime value */
        +	if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new()))
        +		goto err;
        +	if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str))
        +		{
        +		ASN1_GENERALIZEDTIME_free(asn1_time);
        +		goto err;
        +		}
        +
        +	return asn1_time;
        + err:
        +	TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
        +	return NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_rsp_utils.c b/vendor/openssl/openssl/crypto/ts/ts_rsp_utils.c
        new file mode 100644
        index 000000000..401c1fdc5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_rsp_utils.c
        @@ -0,0 +1,409 @@
        +/* crypto/ts/ts_resp_utils.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/ts.h>
        +#include <openssl/pkcs7.h>
        +
        +/* Function definitions. */
        +
        +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
        +	{
        +	TS_STATUS_INFO *new_status_info;
        +
        +	if (a->status_info == status_info)
        +		return 1;
        +	new_status_info = TS_STATUS_INFO_dup(status_info);
        +	if (new_status_info == NULL)
        +		{
        +		TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	TS_STATUS_INFO_free(a->status_info);
        +	a->status_info = new_status_info;
        +
        +	return 1;
        +	}
        +
        +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a)
        +	{
        +	return a->status_info;
        +	}
        +
        +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
        +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
        +	{
        +	/* Set new PKCS7 and TST_INFO objects. */
        +	PKCS7_free(a->token);
        +	a->token = p7;
        +	TS_TST_INFO_free(a->tst_info);
        +	a->tst_info = tst_info;
        +	}
        +
        +PKCS7 *TS_RESP_get_token(TS_RESP *a)
        +	{
        +	return a->token;
        +	}
        +
        +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a)
        +	{
        +	return a->tst_info;
        +	}
        +
        +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
        +	{
        +	return ASN1_INTEGER_set(a->version, version);
        +	}
        +
        +long TS_TST_INFO_get_version(const TS_TST_INFO *a)
        +	{
        +	return ASN1_INTEGER_get(a->version);
        +	}
        +
        +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
        +	{
        +	ASN1_OBJECT *new_policy;
        +
        +	if (a->policy_id == policy)
        +		return 1;
        +	new_policy = OBJ_dup(policy);
        +	if (new_policy == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_OBJECT_free(a->policy_id);
        +	a->policy_id = new_policy;
        +	return 1;
        +	}
        +
        +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
        +	{
        +	return a->policy_id;
        +	}
        +
        +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
        +	{
        +	TS_MSG_IMPRINT *new_msg_imprint;
        +
        +	if (a->msg_imprint == msg_imprint)
        +		return 1;
        +	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
        +	if (new_msg_imprint == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	TS_MSG_IMPRINT_free(a->msg_imprint);
        +	a->msg_imprint = new_msg_imprint;
        +	return 1;
        +	}
        +
        +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
        +	{
        +	return a->msg_imprint;
        +	}
        +
        +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
        +	{
        +	ASN1_INTEGER *new_serial;
        +
        +	if (a->serial == serial)
        +		return 1;
        +	new_serial = ASN1_INTEGER_dup(serial);
        +	if (new_serial == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_INTEGER_free(a->serial);
        +	a->serial = new_serial;
        +	return 1;
        +	}
        +
        +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a)
        +	{
        +	return a->serial;
        +	}
        +
        +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
        +	{
        +	ASN1_GENERALIZEDTIME *new_time;
        +
        +	if (a->time == gtime)
        +		return 1;
        +	new_time = M_ASN1_GENERALIZEDTIME_dup(gtime);
        +	if (new_time == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_GENERALIZEDTIME_free(a->time);
        +	a->time = new_time;
        +	return 1;
        +	}
        +
        +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a)
        +	{
        +	return a->time;
        +	}
        +
        +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
        +	{
        +	TS_ACCURACY *new_accuracy;
        +
        +	if (a->accuracy == accuracy)
        +		return 1;
        +	new_accuracy = TS_ACCURACY_dup(accuracy);
        +	if (new_accuracy == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	TS_ACCURACY_free(a->accuracy);
        +	a->accuracy = new_accuracy;
        +	return 1;
        +	}
        +
        +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
        +	{
        +	return a->accuracy;
        +	}
        +
        +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
        +	{
        +	ASN1_INTEGER *new_seconds;
        +
        +	if (a->seconds == seconds)
        +		return 1;
        +	new_seconds = ASN1_INTEGER_dup(seconds);
        +	if (new_seconds == NULL)
        +		{
        +		TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_INTEGER_free(a->seconds);
        +	a->seconds = new_seconds;
        +	return 1;
        +	}
        +
        +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
        +	{
        +	return a->seconds;
        +	}
        +
        +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
        +	{
        +	ASN1_INTEGER *new_millis = NULL;
        +
        +	if (a->millis == millis)
        +		return 1;
        +	if (millis != NULL)
        +		{
        +		new_millis = ASN1_INTEGER_dup(millis);
        +		if (new_millis == NULL)
        +			{
        +			TSerr(TS_F_TS_ACCURACY_SET_MILLIS, 
        +			      ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		}
        +	ASN1_INTEGER_free(a->millis);
        +	a->millis = new_millis;
        +	return 1;
        +	}
        +
        +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a)
        +	{
        +	return a->millis;
        +	}
        +
        +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
        +	{
        +	ASN1_INTEGER *new_micros = NULL;
        +
        +	if (a->micros == micros)
        +		return 1;
        +	if (micros != NULL)
        +		{
        +		new_micros = ASN1_INTEGER_dup(micros);
        +		if (new_micros == NULL)
        +			{
        +			TSerr(TS_F_TS_ACCURACY_SET_MICROS, 
        +			      ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		}
        +	ASN1_INTEGER_free(a->micros);
        +	a->micros = new_micros;
        +	return 1;
        +	}
        +
        +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a)
        +	{
        +	return a->micros;
        +	}
        +
        +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
        +	{
        +	a->ordering = ordering ? 0xFF : 0x00;
        +	return 1;
        +	}
        +
        +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
        +	{
        +	return a->ordering ? 1 : 0;
        +	}
        +
        +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
        +	{
        +	ASN1_INTEGER *new_nonce;
        +
        +	if (a->nonce == nonce)
        +		return 1;
        +	new_nonce = ASN1_INTEGER_dup(nonce);
        +	if (new_nonce == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	ASN1_INTEGER_free(a->nonce);
        +	a->nonce = new_nonce;
        +	return 1;
        +	}
        +
        +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
        +	{
        +	return a->nonce;
        +	}
        +
        +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
        +	{
        +	GENERAL_NAME *new_tsa;
        +
        +	if (a->tsa == tsa)
        +		return 1;
        +	new_tsa = GENERAL_NAME_dup(tsa);
        +	if (new_tsa == NULL)
        +		{
        +		TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	GENERAL_NAME_free(a->tsa);
        +	a->tsa = new_tsa;
        +	return 1;
        +	}
        +
        +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a)
        +	{
        +	return a->tsa;
        +	}
        +
        +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
        +	{
        +	return a->extensions;
        +	}
        +
        +void TS_TST_INFO_ext_free(TS_TST_INFO *a)
        +	{
        +	if (!a) return;
        +	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
        +	a->extensions = NULL;
        +	}
        +
        +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
        +	{
        +	return X509v3_get_ext_count(a->extensions);
        +	}
        +
        +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
        +	{
        +	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
        +	}
        +
        +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
        +	}
        +
        +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
        +	{
        +	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
        +	}
        +
        +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
        +	{
        +	return X509v3_get_ext(a->extensions,loc);
        +	}
        +
        +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
        +	{
        +	return X509v3_delete_ext(a->extensions,loc);
        +	}
        +
        +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
        +	{
        +	return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
        +	}
        +
        +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
        +	{
        +	return X509V3_get_d2i(a->extensions, nid, crit, idx);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_rsp_verify.c b/vendor/openssl/openssl/crypto/ts/ts_rsp_verify.c
        new file mode 100644
        index 000000000..afe16afbe
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_rsp_verify.c
        @@ -0,0 +1,728 @@
        +/* crypto/ts/ts_resp_verify.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2002.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/ts.h>
        +#include <openssl/pkcs7.h>
        +
        +/* Private function declarations. */
        +
        +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
        +			  X509 *signer, STACK_OF(X509) **chain);
        +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
        +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
        +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
        +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
        +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 
        +				 PKCS7 *token, TS_TST_INFO *tst_info);
        +static int TS_check_status_info(TS_RESP *response);
        +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
        +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
        +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
        +			      X509_ALGOR **md_alg, 
        +			      unsigned char **imprint, unsigned *imprint_len);
        +static int TS_check_imprints(X509_ALGOR *algor_a, 
        +			     unsigned char *imprint_a, unsigned len_a,
        +			     TS_TST_INFO *tst_info);
        +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
        +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
        +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);
        +
        +/*
        + * Local mapping between response codes and descriptions.
        + * Don't forget to change TS_STATUS_BUF_SIZE when modifying 
        + * the elements of this array.
        + */
        +static const char *TS_status_text[] =
        +	{ "granted",
        +	  "grantedWithMods",
        +	  "rejection",
        +	  "waiting",
        +	  "revocationWarning",
        +	  "revocationNotification" };
        +
        +#define TS_STATUS_TEXT_SIZE	(sizeof(TS_status_text)/sizeof(*TS_status_text))
        +
        +/*
        + * This must be greater or equal to the sum of the strings in TS_status_text
        + * plus the number of its elements.
        + */
        +#define TS_STATUS_BUF_SIZE	256
        +
        +static struct
        +	{
        +	int code;
        +	const char *text;
        +	} TS_failure_info[] =
        +		{ { TS_INFO_BAD_ALG, "badAlg" },
        +		  { TS_INFO_BAD_REQUEST, "badRequest" },
        +		  { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
        +		  { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
        +		  { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
        +		  { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
        +		  { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
        +		  { TS_INFO_SYSTEM_FAILURE, "systemFailure" } };
        +
        +#define TS_FAILURE_INFO_SIZE	(sizeof(TS_failure_info) / \
        +				sizeof(*TS_failure_info))
        +
        +/* Functions for verifying a signed TS_TST_INFO structure. */
        +
        +/*
        + * This function carries out the following tasks:
        + *	- Checks if there is one and only one signer.
        + *	- Search for the signing certificate in 'certs' and in the response.
        + *	- Check the extended key usage and key usage fields of the signer
        + *	certificate (done by the path validation).
        + *	- Build and validate the certificate path.
        + *	- Check if the certificate path meets the requirements of the
        + *	SigningCertificate ESS signed attribute.
        + *	- Verify the signature value.
        + *	- Returns the signer certificate in 'signer', if 'signer' is not NULL.
        + */
        +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
        +			     X509_STORE *store, X509 **signer_out)
        +	{
        +	STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
        +	PKCS7_SIGNER_INFO *si;
        +	STACK_OF(X509) *signers = NULL;
        +	X509	*signer;
        +	STACK_OF(X509) *chain = NULL;
        +	char	buf[4096];
        +	int	i, j = 0, ret = 0;
        +	BIO	*p7bio = NULL;
        +
        +	/* Some sanity checks first. */
        +	if (!token)
        +		{
        +		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
        +		goto err;
        +		}
        +
        +	/* Check for the correct content type */
        +	if(!PKCS7_type_is_signed(token))
        +		{
        +		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
        +		goto err;
        +		}
        +
        +	/* Check if there is one and only one signer. */
        +	sinfos = PKCS7_get_signer_info(token);
        +	if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1)
        +		{
        +		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
        +		      TS_R_THERE_MUST_BE_ONE_SIGNER);
        +		goto err;
        +		}
        +	si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
        +
        +	/* Check for no content: no data to verify signature. */
        +	if (PKCS7_get_detached(token))
        +		{
        +		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
        +		goto err;
        +		}
        +	
        +	/* Get hold of the signer certificate, search only internal
        +	   certificates if it was requested. */
        +	signers = PKCS7_get0_signers(token, certs, 0);
        +	if (!signers || sk_X509_num(signers) != 1) goto err;
        +	signer = sk_X509_value(signers, 0);
        +
        +	/* Now verify the certificate. */
        +	if (!TS_verify_cert(store, certs, signer, &chain)) goto err;
        +
        +	/* Check if the signer certificate is consistent with the
        +	   ESS extension. */
        +	if (!TS_check_signing_certs(si, chain)) goto err;
        +
        +	/* Creating the message digest. */
        +	p7bio = PKCS7_dataInit(token, NULL);
        +
        +	/* We now have to 'read' from p7bio to calculate digests etc. */
        +	while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0);
        +
        +	/* Verifying the signature. */
        +	j = PKCS7_signatureVerify(p7bio, token, si, signer);
        +	if (j <= 0)
        +		{
        +		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
        +		goto err;
        +		}
        +
        +	/* Return the signer certificate if needed. */
        +	if (signer_out)
        +		{
        +		*signer_out = signer;
        +		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
        +		}
        +
        +	ret = 1;
        +
        + err:
        +	BIO_free_all(p7bio);
        +	sk_X509_pop_free(chain, X509_free);
        +	sk_X509_free(signers);
        +
        +	return ret;
        +	}
        +
        +/*
        + * The certificate chain is returned in chain. Caller is responsible for
        + * freeing the vector.
        + */
        +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
        +			  X509 *signer, STACK_OF(X509) **chain)
        +	{
        +	X509_STORE_CTX	cert_ctx;
        +	int i;
        +	int ret = 1;
        +
        +	/* chain is an out argument. */
        +	*chain = NULL;
        +	X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted);
        +	X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
        +	i = X509_verify_cert(&cert_ctx);
        +	if (i <= 0)
        +		{
        +		int j = X509_STORE_CTX_get_error(&cert_ctx);
        +		TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
        +		ERR_add_error_data(2, "Verify error:",
        +				   X509_verify_cert_error_string(j));
        +		ret = 0;
        +		}
        +	else
        +		{
        +		/* Get a copy of the certificate chain. */
        +		*chain = X509_STORE_CTX_get1_chain(&cert_ctx);
        +		}
        +
        +	X509_STORE_CTX_cleanup(&cert_ctx);
        +
        +	return ret;
        +	}
        +
        +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
        +	{
        +	ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
        +	STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
        +	X509 *cert;
        +	int i = 0;
        +	int ret = 0;
        +
        +	if (!ss) goto err;
        +	cert_ids = ss->cert_ids;
        +	/* The signer certificate must be the first in cert_ids. */
        +	cert = sk_X509_value(chain, 0);
        +	if (TS_find_cert(cert_ids, cert) != 0) goto err;
        +	
        +	/* Check the other certificates of the chain if there are more
        +	   than one certificate ids in cert_ids. */
        +	if (sk_ESS_CERT_ID_num(cert_ids) > 1)
        +		{
        +		/* All the certificates of the chain must be in cert_ids. */
        +		for (i = 1; i < sk_X509_num(chain); ++i)
        +			{
        +			cert = sk_X509_value(chain, i);
        +			if (TS_find_cert(cert_ids, cert) < 0) goto err;
        +			}
        +		}
        +	ret = 1;
        + err:
        +	if (!ret)
        +		TSerr(TS_F_TS_CHECK_SIGNING_CERTS, 
        +		      TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
        +	ESS_SIGNING_CERT_free(ss);
        +	return ret;
        +	}
        +
        +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
        +	{
        +	ASN1_TYPE *attr;
        +	const unsigned char *p;
        +	attr = PKCS7_get_signed_attribute(si, 
        +					  NID_id_smime_aa_signingCertificate);
        +	if (!attr) return NULL;
        +	p = attr->value.sequence->data;
        +	return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
        +	}
        +
        +/* Returns < 0 if certificate is not found, certificate index otherwise. */
        +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
        +	{
        +	int i;
        +
        +	if (!cert_ids || !cert) return -1;
        +
        +	/* Recompute SHA1 hash of certificate if necessary (side effect). */
        +	X509_check_purpose(cert, -1, 0);
        +
        +	/* Look for cert in the cert_ids vector. */
        +	for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i)
        +		{
        +		ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
        +
        +		/* Check the SHA-1 hash first. */
        +		if (cid->hash->length == sizeof(cert->sha1_hash)
        +		    && !memcmp(cid->hash->data, cert->sha1_hash,
        +			       sizeof(cert->sha1_hash)))
        +			{
        +			/* Check the issuer/serial as well if specified. */
        +			ESS_ISSUER_SERIAL *is = cid->issuer_serial;
        +			if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
        +				return i;
        +			}
        +		}
        +	
        +	return -1;
        +	}
        +
        +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
        +	{
        +	GENERAL_NAME *issuer;
        +
        +	if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1;
        +
        +	/* Check the issuer first. It must be a directory name. */
        +	issuer = sk_GENERAL_NAME_value(is->issuer, 0);
        +	if (issuer->type != GEN_DIRNAME 
        +	    || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
        +		return -1;
        +
        +	/* Check the serial number, too. */
        +	if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))
        +		return -1;
        +
        +	return 0;
        +	}
        +
        +/*
        + * Verifies whether 'response' contains a valid response with regards 
        + * to the settings of the context:
        + *	- Gives an error message if the TS_TST_INFO is not present.
        + *	- Calls _TS_RESP_verify_token to verify the token content.
        + */
        +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
        +	{
        +	PKCS7 *token = TS_RESP_get_token(response);
        +	TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
        +	int ret = 0;
        +
        +	/* Check if we have a successful TS_TST_INFO object in place. */
        +	if (!TS_check_status_info(response)) goto err;
        +
        +	/* Check the contents of the time stamp token. */
        +	if (!int_TS_RESP_verify_token(ctx, token, tst_info))
        +		goto err;
        +
        +	ret = 1;
        + err:
        +	return ret;
        +	}
        +
        +/*
        + * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
        + * calls the internal int_TS_RESP_verify_token function for verifying it.
        + */
        +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
        +	{
        +	TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
        +	int ret = 0;
        +	if (tst_info)
        +		{
        +		ret = int_TS_RESP_verify_token(ctx, token, tst_info);
        +		TS_TST_INFO_free(tst_info);
        +		}
        +	return ret;
        +	}
        +
        +/*
        + * Verifies whether the 'token' contains a valid time stamp token 
        + * with regards to the settings of the context. Only those checks are
        + * carried out that are specified in the context:
        + *	- Verifies the signature of the TS_TST_INFO.
        + *	- Checks the version number of the response.
        + *	- Check if the requested and returned policies math.
        + *	- Check if the message imprints are the same.
        + *	- Check if the nonces are the same.
        + *	- Check if the TSA name matches the signer.
        + *	- Check if the TSA name is the expected TSA.
        + */
        +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 
        +				 PKCS7 *token, TS_TST_INFO *tst_info)
        +	{
        +	X509 *signer = NULL;
        +	GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
        +	X509_ALGOR *md_alg = NULL;
        +	unsigned char *imprint = NULL;
        +	unsigned imprint_len = 0;
        +	int ret = 0;
        +
        +	/* Verify the signature. */
        +	if ((ctx->flags & TS_VFY_SIGNATURE)
        +	    && !TS_RESP_verify_signature(token, ctx->certs, ctx->store,
        +					 &signer))
        +		goto err;
        +	
        +	/* Check version number of response. */
        +	if ((ctx->flags & TS_VFY_VERSION)
        +	    && TS_TST_INFO_get_version(tst_info) != 1)
        +		{
        +		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
        +		goto err;
        +		}
        +
        +	/* Check policies. */
        +	if ((ctx->flags & TS_VFY_POLICY)
        +	    && !TS_check_policy(ctx->policy, tst_info))
        +		goto err;
        +	
        +	/* Check message imprints. */
        +	if ((ctx->flags & TS_VFY_IMPRINT)
        +	    && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
        +				  tst_info)) 
        +		goto err;
        +
        +	/* Compute and check message imprints. */
        +	if ((ctx->flags & TS_VFY_DATA)
        +	    && (!TS_compute_imprint(ctx->data, tst_info,
        +				    &md_alg, &imprint, &imprint_len)
        +	    || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
        +		goto err;
        +
        +	/* Check nonces. */
        +	if ((ctx->flags & TS_VFY_NONCE)
        +	    && !TS_check_nonces(ctx->nonce, tst_info))
        +		goto err;
        +
        +	/* Check whether TSA name and signer certificate match. */
        +	if ((ctx->flags & TS_VFY_SIGNER)
        +	    && tsa_name && !TS_check_signer_name(tsa_name, signer))
        +		{
        +		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
        +		goto err;
        +		}
        +
        +	/* Check whether the TSA is the expected one. */
        +	if ((ctx->flags & TS_VFY_TSA_NAME)
        +	    && !TS_check_signer_name(ctx->tsa_name, signer))
        +		{
        +		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
        +		goto err;
        +		}
        +
        +	ret = 1;
        + err:
        +	X509_free(signer);
        +	X509_ALGOR_free(md_alg);
        +	OPENSSL_free(imprint);
        +	return ret;
        +	}
        +
        +static int TS_check_status_info(TS_RESP *response)
        +	{
        +	TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
        +	long status = ASN1_INTEGER_get(info->status);
        +	const char *status_text = NULL;
        +	char *embedded_status_text = NULL;
        +	char failure_text[TS_STATUS_BUF_SIZE] = "";
        +
        +	/* Check if everything went fine. */
        +	if (status == 0 || status == 1) return 1;
        +
        +	/* There was an error, get the description in status_text. */
        +	if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
        +		status_text = TS_status_text[status];
        +	else
        +		status_text = "unknown code";
        +
        +	/* Set the embedded_status_text to the returned description. */
        +	if (sk_ASN1_UTF8STRING_num(info->text) > 0
        +	    && !(embedded_status_text = TS_get_status_text(info->text)))
        +		return 0;
        +	
        +	/* Filling in failure_text with the failure information. */
        +	if (info->failure_info)
        +		{
        +		int i;
        +		int first = 1;
        +		for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i)
        +			{
        +			if (ASN1_BIT_STRING_get_bit(info->failure_info,
        +						    TS_failure_info[i].code))
        +				{
        +				if (!first)
        +					strcpy(failure_text, ",");
        +				else
        +					first = 0;
        +				strcat(failure_text, TS_failure_info[i].text);
        +				}
        +			}
        +		}
        +	if (failure_text[0] == '\0')
        +		strcpy(failure_text, "unspecified");
        +
        +	/* Making up the error string. */
        +	TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
        +	ERR_add_error_data(6,
        +			   "status code: ", status_text,
        +			   ", status text: ", embedded_status_text ? 
        +			   embedded_status_text : "unspecified",
        +			   ", failure codes: ", failure_text);
        +	OPENSSL_free(embedded_status_text);
        +
        +	return 0;
        +	}
        +
        +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
        +	{
        +	int i;
        +	unsigned int length = 0;
        +	char *result = NULL;
        +	char *p;
        +
        +	/* Determine length first. */
        +	for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i)
        +		{
        +		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
        +		length += ASN1_STRING_length(current);
        +		length += 1;	/* separator character */
        +		}
        +	/* Allocate memory (closing '\0' included). */
        +	if (!(result = OPENSSL_malloc(length)))
        +		{
        +		TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	/* Concatenate the descriptions. */
        +	for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i)
        +		{
        +		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
        +		length = ASN1_STRING_length(current);
        +		if (i > 0) *p++ = '/';
        +		strncpy(p, (const char *)ASN1_STRING_data(current), length);
        +		p += length;
        +		}
        +	/* We do have space for this, too. */
        +	*p = '\0';
        +	
        +	return result;
        +	}
        +
        +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
        +	{
        +	ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);
        +
        +	if (OBJ_cmp(req_oid, resp_oid) != 0)
        +		{
        +		TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
        +			      X509_ALGOR **md_alg, 
        +			      unsigned char **imprint, unsigned *imprint_len)
        +	{
        +	TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
        +	X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
        +	const EVP_MD *md;
        +	EVP_MD_CTX md_ctx;
        +	unsigned char buffer[4096];
        +	int length;
        +
        +	*md_alg = NULL;
        +	*imprint = NULL;
        +
        +	/* Return the MD algorithm of the response. */
        +	if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err;
        +
        +	/* Getting the MD object. */
        +	if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm)))
        +		{
        +		TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
        +		goto err;
        +		}
        +
        +	/* Compute message digest. */
        +	length = EVP_MD_size(md);
        +	if (length < 0)
        +	    goto err;
        +	*imprint_len = length;
        +	if (!(*imprint = OPENSSL_malloc(*imprint_len))) 
        +		{
        +		TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!EVP_DigestInit(&md_ctx, md))
        +		goto err;
        +	while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0)
        +		{
        +		if (!EVP_DigestUpdate(&md_ctx, buffer, length))
        +			goto err;
        +		}
        +	if (!EVP_DigestFinal(&md_ctx, *imprint, NULL))
        +		goto err;
        +
        +	return 1;
        + err:
        +	X509_ALGOR_free(*md_alg);
        +	OPENSSL_free(*imprint);
        +	*imprint_len = 0;
        +	return 0;
        +	}
        +
        +static int TS_check_imprints(X509_ALGOR *algor_a, 
        +			     unsigned char *imprint_a, unsigned len_a,
        +			     TS_TST_INFO *tst_info)
        +	{
        +	TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
        +	X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
        +	int ret = 0;
        +
        +	/* algor_a is optional. */
        +	if (algor_a)
        +		{
        +		/* Compare algorithm OIDs. */
        +		if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err;
        +
        +		/* The parameter must be NULL in both. */
        +		if ((algor_a->parameter 
        +		     && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
        +		    || (algor_b->parameter
        +			&& ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
        +			goto err;
        +		}
        +
        +	/* Compare octet strings. */
        +	ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
        +		memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
        + err:
        +	if (!ret)
        +		TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
        +	return ret;
        +	}
        +
        +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
        +	{
        +	const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);
        +
        +	/* Error if nonce is missing. */
        +	if (!b)
        +		{
        +		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
        +		return 0;
        +		}
        +
        +	/* No error if a nonce is returned without being requested. */
        +	if (ASN1_INTEGER_cmp(a, b) != 0)
        +		{
        +		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +/* Check if the specified TSA name matches either the subject
        +   or one of the subject alternative names of the TSA certificate. */
        +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
        +	{
        +	STACK_OF(GENERAL_NAME) *gen_names = NULL;
        +	int idx = -1;
        +	int found = 0;
        +
        +	/* Check the subject name first. */
        +	if (tsa_name->type == GEN_DIRNAME 
        +	    && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
        +		return 1;
        +
        +	/* Check all the alternative names. */
        +	gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
        +				     NULL, &idx);
        +	while (gen_names != NULL
        +	       && !(found = TS_find_name(gen_names, tsa_name) >= 0))
        +		{
        +		/* Get the next subject alternative name,
        +		   although there should be no more than one. */
        +		GENERAL_NAMES_free(gen_names);
        +		gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
        +					     NULL, &idx);
        +		}
        +	if (gen_names) GENERAL_NAMES_free(gen_names);
        +	
        +	return found;
        +	}
        +
        +/* Returns 1 if name is in gen_names, 0 otherwise. */
        +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
        +	{
        +	int i, found;
        +	for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
        +	     ++i)
        +		{
        +		GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
        +		found = GENERAL_NAME_cmp(current, name) == 0;
        +		}
        +	return found ? i - 1 : -1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ts/ts_verify_ctx.c b/vendor/openssl/openssl/crypto/ts/ts_verify_ctx.c
        new file mode 100644
        index 000000000..609b7735d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ts/ts_verify_ctx.c
        @@ -0,0 +1,159 @@
        +/* crypto/ts/ts_verify_ctx.c */
        +/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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 "cryptlib.h"
        +#include <openssl/objects.h>
        +#include <openssl/ts.h>
        +
        +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
        +	{
        +	TS_VERIFY_CTX *ctx = 
        +		(TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX));
        +	if (ctx)
        +		memset(ctx, 0, sizeof(TS_VERIFY_CTX));
        +	else
        +		TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
        +	return ctx;
        +	}
        +
        +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
        +	{
        +	OPENSSL_assert(ctx != NULL);
        +	memset(ctx, 0, sizeof(TS_VERIFY_CTX));
        +	}
        +
        +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
        +	{
        +	if (!ctx) return;
        +
        +	TS_VERIFY_CTX_cleanup(ctx);
        +	OPENSSL_free(ctx);
        +	}
        +
        +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
        +	{
        +	if (!ctx) return;
        +
        +	X509_STORE_free(ctx->store);
        +	sk_X509_pop_free(ctx->certs, X509_free);
        +
        +	ASN1_OBJECT_free(ctx->policy);
        +
        +	X509_ALGOR_free(ctx->md_alg);
        +	OPENSSL_free(ctx->imprint);
        +	
        +	BIO_free_all(ctx->data);
        +
        +	ASN1_INTEGER_free(ctx->nonce);
        +
        +	GENERAL_NAME_free(ctx->tsa_name);
        +
        +	TS_VERIFY_CTX_init(ctx);
        +	}
        +
        +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
        +	{
        +	TS_VERIFY_CTX *ret = ctx;
        +	ASN1_OBJECT *policy;
        +	TS_MSG_IMPRINT *imprint;
        +	X509_ALGOR *md_alg;
        +	ASN1_OCTET_STRING *msg;
        +	const ASN1_INTEGER *nonce;
        +
        +	OPENSSL_assert(req != NULL);
        +	if (ret)
        +		TS_VERIFY_CTX_cleanup(ret);
        +	else
        +		if (!(ret = TS_VERIFY_CTX_new())) return NULL;
        +
        +	/* Setting flags. */
        +	ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
        +
        +	/* Setting policy. */
        +	if ((policy = TS_REQ_get_policy_id(req)) != NULL)
        +		{
        +		if (!(ret->policy = OBJ_dup(policy))) goto err;
        +		}
        +	else
        +		ret->flags &= ~TS_VFY_POLICY;
        +
        +	/* Setting md_alg, imprint and imprint_len. */
        +	imprint = TS_REQ_get_msg_imprint(req);
        +	md_alg = TS_MSG_IMPRINT_get_algo(imprint);
        +	if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err;
        +	msg = TS_MSG_IMPRINT_get_msg(imprint);
        +	ret->imprint_len = ASN1_STRING_length(msg);
        +	if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err;
        +	memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
        +
        +	/* Setting nonce. */
        +	if ((nonce = TS_REQ_get_nonce(req)) != NULL)
        +		{
        +		if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err;
        +		}
        +	else
        +		ret->flags &= ~TS_VFY_NONCE;
        +
        +	return ret;
        + err:
        +	if (ctx)
        +		TS_VERIFY_CTX_cleanup(ctx);
        +	else
        +		TS_VERIFY_CTX_free(ret);
        +	return NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/txt_db/Makefile b/vendor/openssl/openssl/crypto/txt_db/Makefile
        new file mode 100644
        index 000000000..e6f30331d
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/txt_db/Makefile
        @@ -0,0 +1,84 @@
        +#
        +# OpenSSL/crypto/txt_db/Makefile
        +#
        +
        +DIR=	txt_db
        +TOP=	../..
        +CC=	cc
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=txt_db.c
        +LIBOBJ=txt_db.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= txt_db.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by top Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +txt_db.o: ../../e_os.h ../../include/openssl/bio.h
        +txt_db.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +txt_db.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +txt_db.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +txt_db.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +txt_db.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +txt_db.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h
        +txt_db.o: ../cryptlib.h txt_db.c
        diff --git a/vendor/openssl/openssl/crypto/txt_db/txt_db.c b/vendor/openssl/openssl/crypto/txt_db/txt_db.c
        new file mode 100644
        index 000000000..6f2ce3b5a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/txt_db/txt_db.c
        @@ -0,0 +1,388 @@
        +/* crypto/txt_db/txt_db.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/txt_db.h>
        +
        +#undef BUFSIZE
        +#define BUFSIZE	512
        +
        +const char TXT_DB_version[]="TXT_DB" OPENSSL_VERSION_PTEXT;
        +
        +TXT_DB *TXT_DB_read(BIO *in, int num)
        +	{
        +	TXT_DB *ret=NULL;
        +	int er=1;
        +	int esc=0;
        +	long ln=0;
        +	int i,add,n;
        +	int size=BUFSIZE;
        +	int offset=0;
        +	char *p,*f;
        +	OPENSSL_STRING *pp;
        +	BUF_MEM *buf=NULL;
        +
        +	if ((buf=BUF_MEM_new()) == NULL) goto err;
        +	if (!BUF_MEM_grow(buf,size)) goto err;
        +
        +	if ((ret=OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
        +		goto err;
        +	ret->num_fields=num;
        +	ret->index=NULL;
        +	ret->qual=NULL;
        +	if ((ret->data=sk_OPENSSL_PSTRING_new_null()) == NULL)
        +		goto err;
        +	if ((ret->index=OPENSSL_malloc(sizeof(*ret->index)*num)) == NULL)
        +		goto err;
        +	if ((ret->qual=OPENSSL_malloc(sizeof(*(ret->qual))*num)) == NULL)
        +		goto err;
        +	for (i=0; i<num; i++)
        +		{
        +		ret->index[i]=NULL;
        +		ret->qual[i]=NULL;
        +		}
        +
        +	add=(num+1)*sizeof(char *);
        +	buf->data[size-1]='\0';
        +	offset=0;
        +	for (;;)
        +		{
        +		if (offset != 0)
        +			{
        +			size+=BUFSIZE;
        +			if (!BUF_MEM_grow_clean(buf,size)) goto err;
        +			}
        +		buf->data[offset]='\0';
        +		BIO_gets(in,&(buf->data[offset]),size-offset);
        +		ln++;
        +		if (buf->data[offset] == '\0') break;
        +		if ((offset == 0) && (buf->data[0] == '#')) continue;
        +		i=strlen(&(buf->data[offset]));
        +		offset+=i;
        +		if (buf->data[offset-1] != '\n')
        +			continue;
        +		else
        +			{
        +			buf->data[offset-1]='\0'; /* blat the '\n' */
        +			if (!(p=OPENSSL_malloc(add+offset))) goto err;
        +			offset=0;
        +			}
        +		pp=(char **)p;
        +		p+=add;
        +		n=0;
        +		pp[n++]=p;
        +		i=0;
        +		f=buf->data;
        +
        +		esc=0;
        +		for (;;)
        +			{
        +			if (*f == '\0') break;
        +			if (*f == '\t')
        +				{
        +				if (esc)
        +					p--;
        +				else
        +					{	
        +					*(p++)='\0';
        +					f++;
        +					if (n >=  num) break;
        +					pp[n++]=p;
        +					continue;
        +					}
        +				}
        +			esc=(*f == '\\');
        +			*(p++)= *(f++);
        +			}
        +		*(p++)='\0';
        +		if ((n != num) || (*f != '\0'))
        +			{
        +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporary fix :-( */
        +			fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
        +#endif
        +			er=2;
        +			goto err;
        +			}
        +		pp[n]=p;
        +		if (!sk_OPENSSL_PSTRING_push(ret->data,pp))
        +			{
        +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporary fix :-( */
        +			fprintf(stderr,"failure in sk_push\n");
        +#endif
        +			er=2;
        +			goto err;
        +			}
        +		}
        +	er=0;
        +err:
        +	BUF_MEM_free(buf);
        +	if (er)
        +		{
        +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
        +		if (er == 1) fprintf(stderr,"OPENSSL_malloc failure\n");
        +#endif
        +		if (ret != NULL)
        +			{
        +			if (ret->data != NULL) sk_OPENSSL_PSTRING_free(ret->data);
        +			if (ret->index != NULL) OPENSSL_free(ret->index);
        +			if (ret->qual != NULL) OPENSSL_free(ret->qual);
        +			if (ret != NULL) OPENSSL_free(ret);
        +			}
        +		return(NULL);
        +		}
        +	else
        +		return(ret);
        +	}
        +
        +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value)
        +	{
        +	OPENSSL_STRING *ret;
        +	LHASH_OF(OPENSSL_STRING) *lh;
        +
        +	if (idx >= db->num_fields)
        +		{
        +		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
        +		return(NULL);
        +		}
        +	lh=db->index[idx];
        +	if (lh == NULL)
        +		{
        +		db->error=DB_ERROR_NO_INDEX;
        +		return(NULL);
        +		}
        +	ret=lh_OPENSSL_STRING_retrieve(lh,value);
        +	db->error=DB_ERROR_OK;
        +	return(ret);
        +	}
        +
        +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *),
        +			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
        +	{
        +	LHASH_OF(OPENSSL_STRING) *idx;
        +	OPENSSL_STRING *r;
        +	int i,n;
        +
        +	if (field >= db->num_fields)
        +		{
        +		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
        +		return(0);
        +		}
        +	/* FIXME: we lose type checking at this point */
        +	if ((idx=(LHASH_OF(OPENSSL_STRING) *)lh_new(hash,cmp)) == NULL)
        +		{
        +		db->error=DB_ERROR_MALLOC;
        +		return(0);
        +		}
        +	n=sk_OPENSSL_PSTRING_num(db->data);
        +	for (i=0; i<n; i++)
        +		{
        +		r=sk_OPENSSL_PSTRING_value(db->data,i);
        +		if ((qual != NULL) && (qual(r) == 0)) continue;
        +		if ((r=lh_OPENSSL_STRING_insert(idx,r)) != NULL)
        +			{
        +			db->error=DB_ERROR_INDEX_CLASH;
        +			db->arg1=sk_OPENSSL_PSTRING_find(db->data,r);
        +			db->arg2=i;
        +			lh_OPENSSL_STRING_free(idx);
        +			return(0);
        +			}
        +		}
        +	if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]);
        +	db->index[field]=idx;
        +	db->qual[field]=qual;
        +	return(1);
        +	}
        +
        +long TXT_DB_write(BIO *out, TXT_DB *db)
        +	{
        +	long i,j,n,nn,l,tot=0;
        +	char *p,**pp,*f;
        +	BUF_MEM *buf=NULL;
        +	long ret= -1;
        +
        +	if ((buf=BUF_MEM_new()) == NULL)
        +		goto err;
        +	n=sk_OPENSSL_PSTRING_num(db->data);
        +	nn=db->num_fields;
        +	for (i=0; i<n; i++)
        +		{
        +		pp=sk_OPENSSL_PSTRING_value(db->data,i);
        +
        +		l=0;
        +		for (j=0; j<nn; j++)
        +			{
        +			if (pp[j] != NULL)
        +				l+=strlen(pp[j]);
        +			}
        +		if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err;
        +
        +		p=buf->data;
        +		for (j=0; j<nn; j++)
        +			{
        +			f=pp[j];
        +			if (f != NULL)
        +				for (;;) 
        +					{
        +					if (*f == '\0') break;
        +					if (*f == '\t') *(p++)='\\';
        +					*(p++)= *(f++);
        +					}
        +			*(p++)='\t';
        +			}
        +		p[-1]='\n';
        +		j=p-buf->data;
        +		if (BIO_write(out,buf->data,(int)j) != j)
        +			goto err;
        +		tot+=j;
        +		}
        +	ret=tot;
        +err:
        +	if (buf != NULL) BUF_MEM_free(buf);
        +	return(ret);
        +	}
        +
        +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
        +	{
        +	int i;
        +	OPENSSL_STRING *r;
        +
        +	for (i=0; i<db->num_fields; i++)
        +		{
        +		if (db->index[i] != NULL)
        +			{
        +			if ((db->qual[i] != NULL) &&
        +				(db->qual[i](row) == 0)) continue;
        +			r=lh_OPENSSL_STRING_retrieve(db->index[i],row);
        +			if (r != NULL)
        +				{
        +				db->error=DB_ERROR_INDEX_CLASH;
        +				db->arg1=i;
        +				db->arg_row=r;
        +				goto err;
        +				}
        +			}
        +		}
        +	/* We have passed the index checks, now just append and insert */
        +	if (!sk_OPENSSL_PSTRING_push(db->data,row))
        +		{
        +		db->error=DB_ERROR_MALLOC;
        +		goto err;
        +		}
        +
        +	for (i=0; i<db->num_fields; i++)
        +		{
        +		if (db->index[i] != NULL)
        +			{
        +			if ((db->qual[i] != NULL) &&
        +				(db->qual[i](row) == 0)) continue;
        +			(void)lh_OPENSSL_STRING_insert(db->index[i],row);
        +			}
        +		}
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +void TXT_DB_free(TXT_DB *db)
        +	{
        +	int i,n;
        +	char **p,*max;
        +
        +	if(db == NULL)
        +	    return;
        +
        +	if (db->index != NULL)
        +		{
        +		for (i=db->num_fields-1; i>=0; i--)
        +			if (db->index[i] != NULL) lh_OPENSSL_STRING_free(db->index[i]);
        +		OPENSSL_free(db->index);
        +		}
        +	if (db->qual != NULL)
        +		OPENSSL_free(db->qual);
        +	if (db->data != NULL)
        +		{
        +		for (i=sk_OPENSSL_PSTRING_num(db->data)-1; i>=0; i--)
        +			{
        +			/* check if any 'fields' have been allocated
        +			 * from outside of the initial block */
        +			p=sk_OPENSSL_PSTRING_value(db->data,i);
        +			max=p[db->num_fields]; /* last address */
        +			if (max == NULL) /* new row */
        +				{
        +				for (n=0; n<db->num_fields; n++)
        +					if (p[n] != NULL) OPENSSL_free(p[n]);
        +				}
        +			else
        +				{
        +				for (n=0; n<db->num_fields; n++)
        +					{
        +					if (((p[n] < (char *)p) || (p[n] > max))
        +						&& (p[n] != NULL))
        +						OPENSSL_free(p[n]);
        +					}
        +				}
        +			OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data,i));
        +			}
        +		sk_OPENSSL_PSTRING_free(db->data);
        +		}
        +	OPENSSL_free(db);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/txt_db/txt_db.h b/vendor/openssl/openssl/crypto/txt_db/txt_db.h
        new file mode 100644
        index 000000000..6abe435bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/txt_db/txt_db.h
        @@ -0,0 +1,112 @@
        +/* crypto/txt_db/txt_db.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_TXT_DB_H
        +#define HEADER_TXT_DB_H
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/stack.h>
        +#include <openssl/lhash.h>
        +
        +#define DB_ERROR_OK			0
        +#define DB_ERROR_MALLOC			1
        +#define DB_ERROR_INDEX_CLASH    	2
        +#define DB_ERROR_INDEX_OUT_OF_RANGE	3
        +#define DB_ERROR_NO_INDEX		4
        +#define DB_ERROR_INSERT_INDEX_CLASH    	5
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +typedef OPENSSL_STRING *OPENSSL_PSTRING;
        +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
        +
        +typedef struct txt_db_st
        +	{
        +	int num_fields;
        +	STACK_OF(OPENSSL_PSTRING) *data;
        +	LHASH_OF(OPENSSL_STRING) **index;
        +	int (**qual)(OPENSSL_STRING *);
        +	long error;
        +	long arg1;
        +	long arg2;
        +	OPENSSL_STRING *arg_row;
        +	} TXT_DB;
        +
        +#ifndef OPENSSL_NO_BIO
        +TXT_DB *TXT_DB_read(BIO *in, int num);
        +long TXT_DB_write(BIO *out, TXT_DB *db);
        +#else
        +TXT_DB *TXT_DB_read(char *in, int num);
        +long TXT_DB_write(char *out, TXT_DB *db);
        +#endif
        +int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(OPENSSL_STRING *),
        +			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
        +void TXT_DB_free(TXT_DB *db);
        +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value);
        +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ui/Makefile b/vendor/openssl/openssl/crypto/ui/Makefile
        new file mode 100644
        index 000000000..a685659fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/Makefile
        @@ -0,0 +1,111 @@
        +#
        +# OpenSSL/crypto/ui/Makefile
        +#
        +
        +DIR=	ui
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +#TEST= uitest.c
        +TEST=
        +APPS=
        +
        +COMPATSRC= ui_compat.c
        +COMPATOBJ= ui_compat.o
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC= ui_err.c ui_lib.c ui_openssl.c ui_util.c $(COMPATSRC)
        +LIBOBJ= ui_err.o ui_lib.o ui_openssl.o ui_util.o $(COMPATOBJ)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ui.h ui_compat.h
        +HEADER=	$(EXHEADER) ui_locl.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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.
        +
        +ui_compat.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +ui_compat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ui_compat.o: ../../include/openssl/stack.h ../../include/openssl/ui.h
        +ui_compat.o: ../../include/openssl/ui_compat.h ui_compat.c
        +ui_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
        +ui_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +ui_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +ui_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ui_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ui_err.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h ui_err.c
        +ui_lib.o: ../../e_os.h ../../include/openssl/bio.h
        +ui_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ui_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +ui_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +ui_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ui_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ui_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +ui_lib.o: ../cryptlib.h ui_lib.c ui_locl.h
        +ui_openssl.o: ../../e_os.h ../../include/openssl/bio.h
        +ui_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +ui_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
        +ui_openssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
        +ui_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +ui_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +ui_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
        +ui_openssl.o: ../cryptlib.h ui_locl.h ui_openssl.c
        +ui_util.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +ui_util.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +ui_util.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +ui_util.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +ui_util.o: ../../include/openssl/ui.h ui_locl.h ui_util.c
        diff --git a/vendor/openssl/openssl/crypto/ui/ui.h b/vendor/openssl/openssl/crypto/ui/ui.h
        new file mode 100644
        index 000000000..bd78aa413
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui.h
        @@ -0,0 +1,383 @@
        +/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_UI_H
        +#define HEADER_UI_H
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +#include <openssl/crypto.h>
        +#endif
        +#include <openssl/safestack.h>
        +#include <openssl/ossl_typ.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Declared already in ossl_typ.h */
        +/* typedef struct ui_st UI; */
        +/* typedef struct ui_method_st UI_METHOD; */
        +
        +
        +/* All the following functions return -1 or NULL on error and in some cases
        +   (UI_process()) -2 if interrupted or in some other way cancelled.
        +   When everything is fine, they return 0, a positive value or a non-NULL
        +   pointer, all depending on their purpose. */
        +
        +/* Creators and destructor.   */
        +UI *UI_new(void);
        +UI *UI_new_method(const UI_METHOD *method);
        +void UI_free(UI *ui);
        +
        +/* The following functions are used to add strings to be printed and prompt
        +   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
        +   and UI_{add,dup}_input_boolean.
        +
        +   UI_{add,dup}_<function>_string have the following meanings:
        +	add	add a text or prompt string.  The pointers given to these
        +		functions are used verbatim, no copying is done.
        +	dup	make a copy of the text or prompt string, then add the copy
        +		to the collection of strings in the user interface.
        +	<function>
        +		The function is a name for the functionality that the given
        +		string shall be used for.  It can be one of:
        +			input	use the string as data prompt.
        +			verify	use the string as verification prompt.  This
        +				is used to verify a previous input.
        +			info	use the string for informational output.
        +			error	use the string for error output.
        +   Honestly, there's currently no difference between info and error for the
        +   moment.
        +
        +   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
        +   and are typically used when one wants to prompt for a yes/no response.
        +
        +
        +   All of the functions in this group take a UI and a prompt string.
        +   The string input and verify addition functions also take a flag argument,
        +   a buffer for the result to end up with, a minimum input size and a maximum
        +   input size (the result buffer MUST be large enough to be able to contain
        +   the maximum number of characters).  Additionally, the verify addition
        +   functions takes another buffer to compare the result against.
        +   The boolean input functions take an action description string (which should
        +   be safe to ignore if the expected user action is obvious, for example with
        +   a dialog box with an OK button and a Cancel button), a string of acceptable
        +   characters to mean OK and to mean Cancel.  The two last strings are checked
        +   to make sure they don't have common characters.  Additionally, the same
        +   flag argument as for the string input is taken, as well as a result buffer.
        +   The result buffer is required to be at least one byte long.  Depending on
        +   the answer, the first character from the OK or the Cancel character strings
        +   will be stored in the first byte of the result buffer.  No NUL will be
        +   added, so the result is *not* a string.
        +
        +   On success, the all return an index of the added information.  That index
        +   is usefull when retrieving results with UI_get0_result(). */
        +int UI_add_input_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize);
        +int UI_dup_input_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize);
        +int UI_add_verify_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf);
        +int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf);
        +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int flags, char *result_buf);
        +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int flags, char *result_buf);
        +int UI_add_info_string(UI *ui, const char *text);
        +int UI_dup_info_string(UI *ui, const char *text);
        +int UI_add_error_string(UI *ui, const char *text);
        +int UI_dup_error_string(UI *ui, const char *text);
        +
        +/* These are the possible flags.  They can be or'ed together. */
        +/* Use to have echoing of input */
        +#define UI_INPUT_FLAG_ECHO		0x01
        +/* Use a default password.  Where that password is found is completely
        +   up to the application, it might for example be in the user data set
        +   with UI_add_user_data().  It is not recommended to have more than
        +   one input in each UI being marked with this flag, or the application
        +   might get confused. */
        +#define UI_INPUT_FLAG_DEFAULT_PWD	0x02
        +
        +/* The user of these routines may want to define flags of their own.  The core
        +   UI won't look at those, but will pass them on to the method routines.  They
        +   must use higher bits so they don't get confused with the UI bits above.
        +   UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
        +   example of use is this:
        +
        +	#define MY_UI_FLAG1	(0x01 << UI_INPUT_FLAG_USER_BASE)
        +
        +*/
        +#define UI_INPUT_FLAG_USER_BASE	16
        +
        +
        +/* The following function helps construct a prompt.  object_desc is a
        +   textual short description of the object, for example "pass phrase",
        +   and object_name is the name of the object (might be a card name or
        +   a file name.
        +   The returned string shall always be allocated on the heap with
        +   OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
        +
        +   If the ui_method doesn't contain a pointer to a user-defined prompt
        +   constructor, a default string is built, looking like this:
        +
        +	"Enter {object_desc} for {object_name}:"
        +
        +   So, if object_desc has the value "pass phrase" and object_name has
        +   the value "foo.key", the resulting string is:
        +
        +	"Enter pass phrase for foo.key:"
        +*/
        +char *UI_construct_prompt(UI *ui_method,
        +	const char *object_desc, const char *object_name);
        +
        +
        +/* The following function is used to store a pointer to user-specific data.
        +   Any previous such pointer will be returned and replaced.
        +
        +   For callback purposes, this function makes a lot more sense than using
        +   ex_data, since the latter requires that different parts of OpenSSL or
        +   applications share the same ex_data index.
        +
        +   Note that the UI_OpenSSL() method completely ignores the user data.
        +   Other methods may not, however.  */
        +void *UI_add_user_data(UI *ui, void *user_data);
        +/* We need a user data retrieving function as well.  */
        +void *UI_get0_user_data(UI *ui);
        +
        +/* Return the result associated with a prompt given with the index i. */
        +const char *UI_get0_result(UI *ui, int i);
        +
        +/* When all strings have been added, process the whole thing. */
        +int UI_process(UI *ui);
        +
        +/* Give a user interface parametrised control commands.  This can be used to
        +   send down an integer, a data pointer or a function pointer, as well as
        +   be used to get information from a UI. */
        +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void));
        +
        +/* The commands */
        +/* Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
        +   OpenSSL error stack before printing any info or added error messages and
        +   before any prompting. */
        +#define UI_CTRL_PRINT_ERRORS		1
        +/* Check if a UI_process() is possible to do again with the same instance of
        +   a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
        +   if not. */
        +#define UI_CTRL_IS_REDOABLE		2
        +
        +
        +/* Some methods may use extra data */
        +#define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
        +#define UI_get_app_data(s)             UI_get_ex_data(s,0)
        +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int UI_set_ex_data(UI *r,int idx,void *arg);
        +void *UI_get_ex_data(UI *r, int idx);
        +
        +/* Use specific methods instead of the built-in one */
        +void UI_set_default_method(const UI_METHOD *meth);
        +const UI_METHOD *UI_get_default_method(void);
        +const UI_METHOD *UI_get_method(UI *ui);
        +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
        +
        +/* The method with all the built-in thingies */
        +UI_METHOD *UI_OpenSSL(void);
        +
        +
        +/* ---------- For method writers ---------- */
        +/* A method contains a number of functions that implement the low level
        +   of the User Interface.  The functions are:
        +
        +	an opener	This function starts a session, maybe by opening
        +			a channel to a tty, or by opening a window.
        +	a writer	This function is called to write a given string,
        +			maybe to the tty, maybe as a field label in a
        +			window.
        +	a flusher	This function is called to flush everything that
        +			has been output so far.  It can be used to actually
        +			display a dialog box after it has been built.
        +	a reader	This function is called to read a given prompt,
        +			maybe from the tty, maybe from a field in a
        +			window.  Note that it's called wth all string
        +			structures, not only the prompt ones, so it must
        +			check such things itself.
        +	a closer	This function closes the session, maybe by closing
        +			the channel to the tty, or closing the window.
        +
        +   All these functions are expected to return:
        +
        +	0	on error.
        +	1	on success.
        +	-1	on out-of-band events, for example if some prompting has
        +		been canceled (by pressing Ctrl-C, for example).  This is
        +		only checked when returned by the flusher or the reader.
        +
        +   The way this is used, the opener is first called, then the writer for all
        +   strings, then the flusher, then the reader for all strings and finally the
        +   closer.  Note that if you want to prompt from a terminal or other command
        +   line interface, the best is to have the reader also write the prompts
        +   instead of having the writer do it.  If you want to prompt from a dialog
        +   box, the writer can be used to build up the contents of the box, and the
        +   flusher to actually display the box and run the event loop until all data
        +   has been given, after which the reader only grabs the given data and puts
        +   them back into the UI strings.
        +
        +   All method functions take a UI as argument.  Additionally, the writer and
        +   the reader take a UI_STRING.
        +*/
        +
        +/* The UI_STRING type is the data structure that contains all the needed info
        +   about a string or a prompt, including test data for a verification prompt.
        +*/
        +typedef struct ui_string_st UI_STRING;
        +DECLARE_STACK_OF(UI_STRING)
        +
        +/* The different types of strings that are currently supported.
        +   This is only needed by method authors. */
        +enum UI_string_types
        +	{
        +	UIT_NONE=0,
        +	UIT_PROMPT,		/* Prompt for a string */
        +	UIT_VERIFY,		/* Prompt for a string and verify */
        +	UIT_BOOLEAN,		/* Prompt for a yes/no response */
        +	UIT_INFO,		/* Send info to the user */
        +	UIT_ERROR		/* Send an error message to the user */
        +	};
        +
        +/* Create and manipulate methods */
        +UI_METHOD *UI_create_method(char *name);
        +void UI_destroy_method(UI_METHOD *ui_method);
        +int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui));
        +int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis));
        +int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
        +int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
        +int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
        +int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name));
        +int (*UI_method_get_opener(UI_METHOD *method))(UI*);
        +int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
        +int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
        +int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
        +int (*UI_method_get_closer(UI_METHOD *method))(UI*);
        +char * (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
        +
        +/* The following functions are helpers for method writers to access relevant
        +   data from a UI_STRING. */
        +
        +/* Return type of the UI_STRING */
        +enum UI_string_types UI_get_string_type(UI_STRING *uis);
        +/* Return input flags of the UI_STRING */
        +int UI_get_input_flags(UI_STRING *uis);
        +/* Return the actual string to output (the prompt, info or error) */
        +const char *UI_get0_output_string(UI_STRING *uis);
        +/* Return the optional action string to output (the boolean promtp instruction) */
        +const char *UI_get0_action_string(UI_STRING *uis);
        +/* Return the result of a prompt */
        +const char *UI_get0_result_string(UI_STRING *uis);
        +/* Return the string to test the result against.  Only useful with verifies. */
        +const char *UI_get0_test_string(UI_STRING *uis);
        +/* Return the required minimum size of the result */
        +int UI_get_result_minsize(UI_STRING *uis);
        +/* Return the required maximum size of the result */
        +int UI_get_result_maxsize(UI_STRING *uis);
        +/* Set the result of a UI_STRING. */
        +int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
        +
        +
        +/* A couple of popular utility functions */
        +int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify);
        +int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
        +
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_UI_strings(void);
        +
        +/* Error codes for the UI functions. */
        +
        +/* Function codes. */
        +#define UI_F_GENERAL_ALLOCATE_BOOLEAN			 108
        +#define UI_F_GENERAL_ALLOCATE_PROMPT			 109
        +#define UI_F_GENERAL_ALLOCATE_STRING			 100
        +#define UI_F_UI_CTRL					 111
        +#define UI_F_UI_DUP_ERROR_STRING			 101
        +#define UI_F_UI_DUP_INFO_STRING				 102
        +#define UI_F_UI_DUP_INPUT_BOOLEAN			 110
        +#define UI_F_UI_DUP_INPUT_STRING			 103
        +#define UI_F_UI_DUP_VERIFY_STRING			 106
        +#define UI_F_UI_GET0_RESULT				 107
        +#define UI_F_UI_NEW_METHOD				 104
        +#define UI_F_UI_SET_RESULT				 105
        +
        +/* Reason codes. */
        +#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS		 104
        +#define UI_R_INDEX_TOO_LARGE				 102
        +#define UI_R_INDEX_TOO_SMALL				 103
        +#define UI_R_NO_RESULT_BUFFER				 105
        +#define UI_R_RESULT_TOO_LARGE				 100
        +#define UI_R_RESULT_TOO_SMALL				 101
        +#define UI_R_UNKNOWN_CONTROL_COMMAND			 106
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_compat.c b/vendor/openssl/openssl/crypto/ui/ui_compat.c
        new file mode 100644
        index 000000000..13e0f70d9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_compat.c
        @@ -0,0 +1,67 @@
        +/* crypto/ui/ui_compat.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <string.h>
        +#include <openssl/ui_compat.h>
        +
        +int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify)
        +	{
        +	return UI_UTIL_read_pw_string(buf, length, prompt, verify);
        +	}
        +
        +int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify)
        +	{
        +	return UI_UTIL_read_pw(buf, buff, size, prompt, verify);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_compat.h b/vendor/openssl/openssl/crypto/ui/ui_compat.h
        new file mode 100644
        index 000000000..b35c9bb7f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_compat.h
        @@ -0,0 +1,83 @@
        +/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_UI_COMPAT_H
        +#define HEADER_UI_COMPAT_H
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/ui.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* The following functions were previously part of the DES section,
        +   and are provided here for backward compatibility reasons. */
        +
        +#define des_read_pw_string(b,l,p,v) \
        +	_ossl_old_des_read_pw_string((b),(l),(p),(v))
        +#define des_read_pw(b,bf,s,p,v) \
        +	_ossl_old_des_read_pw((b),(bf),(s),(p),(v))
        +
        +int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify);
        +int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_err.c b/vendor/openssl/openssl/crypto/ui/ui_err.c
        new file mode 100644
        index 000000000..a6b96299a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_err.c
        @@ -0,0 +1,112 @@
        +/* crypto/ui/ui_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ui.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason)
        +
        +static ERR_STRING_DATA UI_str_functs[]=
        +	{
        +{ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN),	"GENERAL_ALLOCATE_BOOLEAN"},
        +{ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT),	"GENERAL_ALLOCATE_PROMPT"},
        +{ERR_FUNC(UI_F_GENERAL_ALLOCATE_STRING),	"GENERAL_ALLOCATE_STRING"},
        +{ERR_FUNC(UI_F_UI_CTRL),	"UI_ctrl"},
        +{ERR_FUNC(UI_F_UI_DUP_ERROR_STRING),	"UI_dup_error_string"},
        +{ERR_FUNC(UI_F_UI_DUP_INFO_STRING),	"UI_dup_info_string"},
        +{ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN),	"UI_dup_input_boolean"},
        +{ERR_FUNC(UI_F_UI_DUP_INPUT_STRING),	"UI_dup_input_string"},
        +{ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING),	"UI_dup_verify_string"},
        +{ERR_FUNC(UI_F_UI_GET0_RESULT),	"UI_get0_result"},
        +{ERR_FUNC(UI_F_UI_NEW_METHOD),	"UI_new_method"},
        +{ERR_FUNC(UI_F_UI_SET_RESULT),	"UI_set_result"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA UI_str_reasons[]=
        +	{
        +{ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS),"common ok and cancel characters"},
        +{ERR_REASON(UI_R_INDEX_TOO_LARGE)        ,"index too large"},
        +{ERR_REASON(UI_R_INDEX_TOO_SMALL)        ,"index too small"},
        +{ERR_REASON(UI_R_NO_RESULT_BUFFER)       ,"no result buffer"},
        +{ERR_REASON(UI_R_RESULT_TOO_LARGE)       ,"result too large"},
        +{ERR_REASON(UI_R_RESULT_TOO_SMALL)       ,"result too small"},
        +{ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND),"unknown control command"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_UI_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(UI_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,UI_str_functs);
        +		ERR_load_strings(0,UI_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_lib.c b/vendor/openssl/openssl/crypto/ui/ui_lib.c
        new file mode 100644
        index 000000000..a8abc2706
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_lib.c
        @@ -0,0 +1,924 @@
        +/* crypto/ui/ui_lib.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/e_os2.h>
        +#include <openssl/buffer.h>
        +#include <openssl/ui.h>
        +#include <openssl/err.h>
        +#include "ui_locl.h"
        +
        +IMPLEMENT_STACK_OF(UI_STRING_ST)
        +
        +static const UI_METHOD *default_UI_meth=NULL;
        +
        +UI *UI_new(void)
        +	{
        +	return(UI_new_method(NULL));
        +	}
        +
        +UI *UI_new_method(const UI_METHOD *method)
        +	{
        +	UI *ret;
        +
        +	ret=(UI *)OPENSSL_malloc(sizeof(UI));
        +	if (ret == NULL)
        +		{
        +		UIerr(UI_F_UI_NEW_METHOD,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	if (method == NULL)
        +		ret->meth=UI_get_default_method();
        +	else
        +		ret->meth=method;
        +
        +	ret->strings=NULL;
        +	ret->user_data=NULL;
        +	ret->flags=0;
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
        +	return ret;
        +	}
        +
        +static void free_string(UI_STRING *uis)
        +	{
        +	if (uis->flags & OUT_STRING_FREEABLE)
        +		{
        +		OPENSSL_free((char *)uis->out_string);
        +		switch(uis->type)
        +			{
        +		case UIT_BOOLEAN:
        +			OPENSSL_free((char *)uis->_.boolean_data.action_desc);
        +			OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
        +			OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
        +			break;
        +		default:
        +			break;
        +			}
        +		}
        +	OPENSSL_free(uis);
        +	}
        +
        +void UI_free(UI *ui)
        +	{
        +	if (ui == NULL)
        +		return;
        +	sk_UI_STRING_pop_free(ui->strings,free_string);
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
        +	OPENSSL_free(ui);
        +	}
        +
        +static int allocate_string_stack(UI *ui)
        +	{
        +	if (ui->strings == NULL)
        +		{
        +		ui->strings=sk_UI_STRING_new_null();
        +		if (ui->strings == NULL)
        +			{
        +			return -1;
        +			}
        +		}
        +	return 0;
        +	}
        +
        +static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
        +	int prompt_freeable, enum UI_string_types type, int input_flags,
        +	char *result_buf)
        +	{
        +	UI_STRING *ret = NULL;
        +
        +	if (prompt == NULL)
        +		{
        +		UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER);
        +		}
        +	else if ((type == UIT_PROMPT || type == UIT_VERIFY
        +			 || type == UIT_BOOLEAN) && result_buf == NULL)
        +		{
        +		UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER);
        +		}
        +	else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING))))
        +		{
        +		ret->out_string=prompt;
        +		ret->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0;
        +		ret->input_flags=input_flags;
        +		ret->type=type;
        +		ret->result_buf=result_buf;
        +		}
        +	return ret;
        +	}
        +
        +static int general_allocate_string(UI *ui, const char *prompt,
        +	int prompt_freeable, enum UI_string_types type, int input_flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf)
        +	{
        +	int ret = -1;
        +	UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
        +		type, input_flags, result_buf);
        +
        +	if (s)
        +		{
        +		if (allocate_string_stack(ui) >= 0)
        +			{
        +			s->_.string_data.result_minsize=minsize;
        +			s->_.string_data.result_maxsize=maxsize;
        +			s->_.string_data.test_buf=test_buf;
        +			ret=sk_UI_STRING_push(ui->strings, s);
        +			/* sk_push() returns 0 on error.  Let's addapt that */
        +			if (ret <= 0) ret--;
        +			}
        +		else
        +			free_string(s);
        +		}
        +	return ret;
        +	}
        +
        +static int general_allocate_boolean(UI *ui,
        +	const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int prompt_freeable, enum UI_string_types type, int input_flags,
        +	char *result_buf)
        +	{
        +	int ret = -1;
        +	UI_STRING *s;
        +	const char *p;
        +
        +	if (ok_chars == NULL)
        +		{
        +		UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
        +		}
        +	else if (cancel_chars == NULL)
        +		{
        +		UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
        +		}
        +	else
        +		{
        +		for(p = ok_chars; *p; p++)
        +			{
        +			if (strchr(cancel_chars, *p))
        +				{
        +				UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
        +					UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
        +				}
        +			}
        +
        +		s = general_allocate_prompt(ui, prompt, prompt_freeable,
        +			type, input_flags, result_buf);
        +
        +		if (s)
        +			{
        +			if (allocate_string_stack(ui) >= 0)
        +				{
        +				s->_.boolean_data.action_desc = action_desc;
        +				s->_.boolean_data.ok_chars = ok_chars;
        +				s->_.boolean_data.cancel_chars = cancel_chars;
        +				ret=sk_UI_STRING_push(ui->strings, s);
        +				/* sk_push() returns 0 on error.
        +				   Let's addapt that */
        +				if (ret <= 0) ret--;
        +				}
        +			else
        +				free_string(s);
        +			}
        +		}
        +	return ret;
        +	}
        +
        +/* Returns the index to the place in the stack or -1 for error.  Uses a
        +   direct reference to the prompt.  */
        +int UI_add_input_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize)
        +	{
        +	return general_allocate_string(ui, prompt, 0,
        +		UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
        +	}
        +
        +/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
        +int UI_dup_input_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize)
        +	{
        +	char *prompt_copy=NULL;
        +
        +	if (prompt)
        +		{
        +		prompt_copy=BUF_strdup(prompt);
        +		if (prompt_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_INPUT_STRING,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		}
        +	
        +	return general_allocate_string(ui, prompt_copy, 1,
        +		UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
        +	}
        +
        +int UI_add_verify_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf)
        +	{
        +	return general_allocate_string(ui, prompt, 0,
        +		UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
        +	}
        +
        +int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf)
        +	{
        +	char *prompt_copy=NULL;
        +
        +	if (prompt)
        +		{
        +		prompt_copy=BUF_strdup(prompt);
        +		if (prompt_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_VERIFY_STRING,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		}
        +	
        +	return general_allocate_string(ui, prompt_copy, 1,
        +		UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
        +	}
        +
        +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int flags, char *result_buf)
        +	{
        +	return general_allocate_boolean(ui, prompt, action_desc,
        +		ok_chars, cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
        +	}
        +
        +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int flags, char *result_buf)
        +	{
        +	char *prompt_copy = NULL;
        +	char *action_desc_copy = NULL;
        +	char *ok_chars_copy = NULL;
        +	char *cancel_chars_copy = NULL;
        +
        +	if (prompt)
        +		{
        +		prompt_copy=BUF_strdup(prompt);
        +		if (prompt_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	
        +	if (action_desc)
        +		{
        +		action_desc_copy=BUF_strdup(action_desc);
        +		if (action_desc_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	
        +	if (ok_chars)
        +		{
        +		ok_chars_copy=BUF_strdup(ok_chars);
        +		if (ok_chars_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	
        +	if (cancel_chars)
        +		{
        +		cancel_chars_copy=BUF_strdup(cancel_chars);
        +		if (cancel_chars_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	
        +	return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
        +		ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags,
        +		result_buf);
        + err:
        +	if (prompt_copy) OPENSSL_free(prompt_copy);
        +	if (action_desc_copy) OPENSSL_free(action_desc_copy);
        +	if (ok_chars_copy) OPENSSL_free(ok_chars_copy);
        +	if (cancel_chars_copy) OPENSSL_free(cancel_chars_copy);
        +	return -1;
        +	}
        +
        +int UI_add_info_string(UI *ui, const char *text)
        +	{
        +	return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
        +		NULL);
        +	}
        +
        +int UI_dup_info_string(UI *ui, const char *text)
        +	{
        +	char *text_copy=NULL;
        +
        +	if (text)
        +		{
        +		text_copy=BUF_strdup(text);
        +		if (text_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_INFO_STRING,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		}
        +
        +	return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
        +		0, 0, NULL);
        +	}
        +
        +int UI_add_error_string(UI *ui, const char *text)
        +	{
        +	return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
        +		NULL);
        +	}
        +
        +int UI_dup_error_string(UI *ui, const char *text)
        +	{
        +	char *text_copy=NULL;
        +
        +	if (text)
        +		{
        +		text_copy=BUF_strdup(text);
        +		if (text_copy == NULL)
        +			{
        +			UIerr(UI_F_UI_DUP_ERROR_STRING,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		}
        +	return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
        +		0, 0, NULL);
        +	}
        +
        +char *UI_construct_prompt(UI *ui, const char *object_desc,
        +	const char *object_name)
        +	{
        +	char *prompt = NULL;
        +
        +	if (ui->meth->ui_construct_prompt)
        +		prompt = ui->meth->ui_construct_prompt(ui,
        +			object_desc, object_name);
        +	else
        +		{
        +		char prompt1[] = "Enter ";
        +		char prompt2[] = " for ";
        +		char prompt3[] = ":";
        +		int len = 0;
        +
        +		if (object_desc == NULL)
        +			return NULL;
        +		len = sizeof(prompt1) - 1 + strlen(object_desc);
        +		if (object_name)
        +			len += sizeof(prompt2) - 1 + strlen(object_name);
        +		len += sizeof(prompt3) - 1;
        +
        +		prompt = (char *)OPENSSL_malloc(len + 1);
        +		BUF_strlcpy(prompt, prompt1, len + 1);
        +		BUF_strlcat(prompt, object_desc, len + 1);
        +		if (object_name)
        +			{
        +			BUF_strlcat(prompt, prompt2, len + 1);
        +			BUF_strlcat(prompt, object_name, len + 1);
        +			}
        +		BUF_strlcat(prompt, prompt3, len + 1);
        +		}
        +	return prompt;
        +	}
        +
        +void *UI_add_user_data(UI *ui, void *user_data)
        +	{
        +	void *old_data = ui->user_data;
        +	ui->user_data = user_data;
        +	return old_data;
        +	}
        +
        +void *UI_get0_user_data(UI *ui)
        +	{
        +	return ui->user_data;
        +	}
        +
        +const char *UI_get0_result(UI *ui, int i)
        +	{
        +	if (i < 0)
        +		{
        +		UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_SMALL);
        +		return NULL;
        +		}
        +	if (i >= sk_UI_STRING_num(ui->strings))
        +		{
        +		UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_LARGE);
        +		return NULL;
        +		}
        +	return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
        +	}
        +
        +static int print_error(const char *str, size_t len, UI *ui)
        +	{
        +	UI_STRING uis;
        +
        +	memset(&uis, 0, sizeof(uis));
        +	uis.type = UIT_ERROR;
        +	uis.out_string = str;
        +
        +	if (ui->meth->ui_write_string
        +		&& !ui->meth->ui_write_string(ui, &uis))
        +		return -1;
        +	return 0;
        +	}
        +
        +int UI_process(UI *ui)
        +	{
        +	int i, ok=0;
        +
        +	if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
        +		return -1;
        +
        +	if (ui->flags & UI_FLAG_PRINT_ERRORS)
        +		ERR_print_errors_cb(
        +			(int (*)(const char *, size_t, void *))print_error,
        +			(void *)ui);
        +
        +	for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
        +		{
        +		if (ui->meth->ui_write_string
        +			&& !ui->meth->ui_write_string(ui,
        +				sk_UI_STRING_value(ui->strings, i)))
        +			{
        +			ok=-1;
        +			goto err;
        +			}
        +		}
        +
        +	if (ui->meth->ui_flush)
        +		switch(ui->meth->ui_flush(ui))
        +			{
        +		case -1: /* Interrupt/Cancel/something... */
        +			ok = -2;
        +			goto err;
        +		case 0: /* Errors */
        +			ok = -1;
        +			goto err;
        +		default: /* Success */
        +			ok = 0;
        +			break;
        +			}
        +
        +	for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
        +		{
        +		if (ui->meth->ui_read_string)
        +			{
        +			switch(ui->meth->ui_read_string(ui,
        +				sk_UI_STRING_value(ui->strings, i)))
        +				{
        +			case -1: /* Interrupt/Cancel/something... */
        +				ok = -2;
        +				goto err;
        +			case 0: /* Errors */
        +				ok = -1;
        +				goto err;
        +			default: /* Success */
        +				ok = 0;
        +				break;
        +				}
        +			}
        +		}
        + err:
        +	if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
        +		return -1;
        +	return ok;
        +	}
        +
        +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	if (ui == NULL)
        +		{
        +		UIerr(UI_F_UI_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +		return -1;
        +		}
        +	switch(cmd)
        +		{
        +	case UI_CTRL_PRINT_ERRORS:
        +		{
        +		int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
        +		if (i)
        +			ui->flags |= UI_FLAG_PRINT_ERRORS;
        +		else
        +			ui->flags &= ~UI_FLAG_PRINT_ERRORS;
        +		return save_flag;
        +		}
        +	case UI_CTRL_IS_REDOABLE:
        +		return !!(ui->flags & UI_FLAG_REDOABLE);
        +	default:
        +		break;
        +		}
        +	UIerr(UI_F_UI_CTRL,UI_R_UNKNOWN_CONTROL_COMMAND);
        +	return -1;
        +	}
        +
        +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +        {
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
        +				new_func, dup_func, free_func);
        +        }
        +
        +int UI_set_ex_data(UI *r, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
        +	}
        +
        +void *UI_get_ex_data(UI *r, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&r->ex_data,idx));
        +	}
        +
        +void UI_set_default_method(const UI_METHOD *meth)
        +	{
        +	default_UI_meth=meth;
        +	}
        +
        +const UI_METHOD *UI_get_default_method(void)
        +	{
        +	if (default_UI_meth == NULL)
        +		{
        +		default_UI_meth=UI_OpenSSL();
        +		}
        +	return default_UI_meth;
        +	}
        +
        +const UI_METHOD *UI_get_method(UI *ui)
        +	{
        +	return ui->meth;
        +	}
        +
        +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
        +	{
        +	ui->meth=meth;
        +	return ui->meth;
        +	}
        +
        +
        +UI_METHOD *UI_create_method(char *name)
        +	{
        +	UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD));
        +
        +	if (ui_method)
        +		{
        +		memset(ui_method, 0, sizeof(*ui_method));
        +		ui_method->name = BUF_strdup(name);
        +		}
        +	return ui_method;
        +	}
        +
        +/* BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
        +   (that is, it hasn't been allocated using UI_create_method(), you deserve
        +   anything Murphy can throw at you and more!  You have been warned. */
        +void UI_destroy_method(UI_METHOD *ui_method)
        +	{
        +	OPENSSL_free(ui_method->name);
        +	ui_method->name = NULL;
        +	OPENSSL_free(ui_method);
        +	}
        +
        +int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
        +	{
        +	if (method)
        +		{
        +		method->ui_open_session = opener;
        +		return 0;
        +		}
        +	else
        +		return -1;
        +	}
        +
        +int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
        +	{
        +	if (method)
        +		{
        +		method->ui_write_string = writer;
        +		return 0;
        +		}
        +	else
        +		return -1;
        +	}
        +
        +int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
        +	{
        +	if (method)
        +		{
        +		method->ui_flush = flusher;
        +		return 0;
        +		}
        +	else
        +		return -1;
        +	}
        +
        +int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
        +	{
        +	if (method)
        +		{
        +		method->ui_read_string = reader;
        +		return 0;
        +		}
        +	else
        +		return -1;
        +	}
        +
        +int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
        +	{
        +	if (method)
        +		{
        +		method->ui_close_session = closer;
        +		return 0;
        +		}
        +	else
        +		return -1;
        +	}
        +
        +int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name))
        +	{
        +	if (method)
        +		{
        +		method->ui_construct_prompt = prompt_constructor;
        +		return 0;
        +		}
        +	else
        +		return -1;
        +	}
        +
        +int (*UI_method_get_opener(UI_METHOD *method))(UI*)
        +	{
        +	if (method)
        +		return method->ui_open_session;
        +	else
        +		return NULL;
        +	}
        +
        +int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*)
        +	{
        +	if (method)
        +		return method->ui_write_string;
        +	else
        +		return NULL;
        +	}
        +
        +int (*UI_method_get_flusher(UI_METHOD *method))(UI*)
        +	{
        +	if (method)
        +		return method->ui_flush;
        +	else
        +		return NULL;
        +	}
        +
        +int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*)
        +	{
        +	if (method)
        +		return method->ui_read_string;
        +	else
        +		return NULL;
        +	}
        +
        +int (*UI_method_get_closer(UI_METHOD *method))(UI*)
        +	{
        +	if (method)
        +		return method->ui_close_session;
        +	else
        +		return NULL;
        +	}
        +
        +char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*)
        +	{
        +	if (method)
        +		return method->ui_construct_prompt;
        +	else
        +		return NULL;
        +	}
        +
        +enum UI_string_types UI_get_string_type(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return UIT_NONE;
        +	return uis->type;
        +	}
        +
        +int UI_get_input_flags(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return 0;
        +	return uis->input_flags;
        +	}
        +
        +const char *UI_get0_output_string(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return NULL;
        +	return uis->out_string;
        +	}
        +
        +const char *UI_get0_action_string(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return NULL;
        +	switch(uis->type)
        +		{
        +	case UIT_PROMPT:
        +	case UIT_BOOLEAN:
        +		return uis->_.boolean_data.action_desc;
        +	default:
        +		return NULL;
        +		}
        +	}
        +
        +const char *UI_get0_result_string(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return NULL;
        +	switch(uis->type)
        +		{
        +	case UIT_PROMPT:
        +	case UIT_VERIFY:
        +		return uis->result_buf;
        +	default:
        +		return NULL;
        +		}
        +	}
        +
        +const char *UI_get0_test_string(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return NULL;
        +	switch(uis->type)
        +		{
        +	case UIT_VERIFY:
        +		return uis->_.string_data.test_buf;
        +	default:
        +		return NULL;
        +		}
        +	}
        +
        +int UI_get_result_minsize(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return -1;
        +	switch(uis->type)
        +		{
        +	case UIT_PROMPT:
        +	case UIT_VERIFY:
        +		return uis->_.string_data.result_minsize;
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +int UI_get_result_maxsize(UI_STRING *uis)
        +	{
        +	if (!uis)
        +		return -1;
        +	switch(uis->type)
        +		{
        +	case UIT_PROMPT:
        +	case UIT_VERIFY:
        +		return uis->_.string_data.result_maxsize;
        +	default:
        +		return -1;
        +		}
        +	}
        +
        +int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
        +	{
        +	int l = strlen(result);
        +
        +	ui->flags &= ~UI_FLAG_REDOABLE;
        +
        +	if (!uis)
        +		return -1;
        +	switch (uis->type)
        +		{
        +	case UIT_PROMPT:
        +	case UIT_VERIFY:
        +		{
        +		char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize)+1];
        +		char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize)+1];
        +
        +		BIO_snprintf(number1, sizeof(number1), "%d",
        +			uis->_.string_data.result_minsize);
        +		BIO_snprintf(number2, sizeof(number2), "%d",
        +			uis->_.string_data.result_maxsize);
        +
        +		if (l < uis->_.string_data.result_minsize)
        +			{
        +			ui->flags |= UI_FLAG_REDOABLE;
        +			UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL);
        +			ERR_add_error_data(5,"You must type in ",
        +				number1," to ",number2," characters");
        +			return -1;
        +			}
        +		if (l > uis->_.string_data.result_maxsize)
        +			{
        +			ui->flags |= UI_FLAG_REDOABLE;
        +			UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE);
        +			ERR_add_error_data(5,"You must type in ",
        +				number1," to ",number2," characters");
        +			return -1;
        +			}
        +		}
        +
        +		if (!uis->result_buf)
        +			{
        +			UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
        +			return -1;
        +			}
        +
        +		BUF_strlcpy(uis->result_buf, result,
        +			    uis->_.string_data.result_maxsize + 1);
        +		break;
        +	case UIT_BOOLEAN:
        +		{
        +		const char *p;
        +
        +		if (!uis->result_buf)
        +			{
        +			UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
        +			return -1;
        +			}
        +
        +		uis->result_buf[0] = '\0';
        +		for(p = result; *p; p++)
        +			{
        +			if (strchr(uis->_.boolean_data.ok_chars, *p))
        +				{
        +				uis->result_buf[0] =
        +					uis->_.boolean_data.ok_chars[0];
        +				break;
        +				}
        +			if (strchr(uis->_.boolean_data.cancel_chars, *p))
        +				{
        +				uis->result_buf[0] =
        +					uis->_.boolean_data.cancel_chars[0];
        +				break;
        +				}
        +			}
        +	default:
        +		break;
        +		}
        +		}
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_locl.h b/vendor/openssl/openssl/crypto/ui/ui_locl.h
        new file mode 100644
        index 000000000..aa4a55637
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_locl.h
        @@ -0,0 +1,153 @@
        +/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_UI_LOCL_H
        +#define HEADER_UI_LOCL_H
        +
        +#include <openssl/ui.h>
        +#include <openssl/crypto.h>
        +
        +#ifdef _
        +#undef _
        +#endif
        +
        +struct ui_method_st
        +	{
        +	char *name;
        +
        +	/* All the functions return 1 or non-NULL for success and 0 or NULL
        +	   for failure */
        +
        +	/* Open whatever channel for this, be it the console, an X window
        +	   or whatever.
        +	   This function should use the ex_data structure to save
        +	   intermediate data. */
        +	int (*ui_open_session)(UI *ui);
        +
        +	int (*ui_write_string)(UI *ui, UI_STRING *uis);
        +
        +	/* Flush the output.  If a GUI dialog box is used, this function can
        +	   be used to actually display it. */
        +	int (*ui_flush)(UI *ui);
        +
        +	int (*ui_read_string)(UI *ui, UI_STRING *uis);
        +
        +	int (*ui_close_session)(UI *ui);
        +
        +	/* Construct a prompt in a user-defined manner.  object_desc is a
        +	   textual short description of the object, for example "pass phrase",
        +	   and object_name is the name of the object (might be a card name or
        +	   a file name.
        +	   The returned string shall always be allocated on the heap with
        +	   OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). */
        +	char *(*ui_construct_prompt)(UI *ui, const char *object_desc,
        +		const char *object_name);
        +	};
        +
        +struct ui_string_st
        +	{
        +	enum UI_string_types type; /* Input */
        +	const char *out_string;	/* Input */
        +	int input_flags;	/* Flags from the user */
        +
        +	/* The following parameters are completely irrelevant for UIT_INFO,
        +	   and can therefore be set to 0 or NULL */
        +	char *result_buf;	/* Input and Output: If not NULL, user-defined
        +				   with size in result_maxsize.  Otherwise, it
        +				   may be allocated by the UI routine, meaning
        +				   result_minsize is going to be overwritten.*/
        +	union
        +		{
        +		struct
        +			{
        +			int result_minsize;	/* Input: minimum required
        +						   size of the result.
        +						*/
        +			int result_maxsize;	/* Input: maximum permitted
        +						   size of the result */
        +
        +			const char *test_buf;	/* Input: test string to verify
        +						   against */
        +			} string_data;
        +		struct
        +			{
        +			const char *action_desc; /* Input */
        +			const char *ok_chars; /* Input */
        +			const char *cancel_chars; /* Input */
        +			} boolean_data;
        +		} _;
        +
        +#define OUT_STRING_FREEABLE 0x01
        +	int flags;		/* flags for internal use */
        +	};
        +
        +struct ui_st
        +	{
        +	const UI_METHOD *meth;
        +	STACK_OF(UI_STRING) *strings; /* We might want to prompt for more
        +					 than one thing at a time, and
        +					 with different echoing status.  */
        +	void *user_data;
        +	CRYPTO_EX_DATA ex_data;
        +
        +#define UI_FLAG_REDOABLE	0x0001
        +#define UI_FLAG_PRINT_ERRORS	0x0100
        +	int flags;
        +	};
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_openssl.c b/vendor/openssl/openssl/crypto/ui/ui_openssl.c
        new file mode 100644
        index 000000000..a38c7581e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_openssl.c
        @@ -0,0 +1,718 @@
        +/* crypto/ui/ui_openssl.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org) and others
        + * for the OpenSSL project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +/* The lowest level part of this file was previously in crypto/des/read_pwd.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 <openssl/e_os2.h>
        +
        +/* need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc
        + * [maybe others?], because it masks interfaces not discussed in standard,
        + * sigaction and fileno included. -pedantic would be more appropriate for
        + * the intended purposes, but we can't prevent users from adding -ansi.
        + */
        +#if defined(OPENSSL_SYSNAME_VXWORKS)
        +#include <sys/types.h>
        +#endif
        +
        +#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
        +#ifndef _POSIX_C_SOURCE
        +#define _POSIX_C_SOURCE 2
        +#endif
        +#endif
        +#include <signal.h>
        +#include <stdio.h>
        +#include <string.h>
        +#include <errno.h>
        +
        +#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS)
        +# ifdef OPENSSL_UNISTD
        +#  include OPENSSL_UNISTD
        +# else
        +#  include <unistd.h>
        +# endif
        +/* If unistd.h defines _POSIX_VERSION, we conclude that we
        + * are on a POSIX system and have sigaction and termios. */
        +# if defined(_POSIX_VERSION)
        +
        +#  define SIGACTION
        +#  if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
        +#   define TERMIOS
        +#  endif
        +
        +# endif
        +#endif
        +
        +#ifdef WIN16TTY
        +# undef OPENSSL_SYS_WIN16
        +# undef WIN16
        +# undef _WINDOWS
        +# include <graph.h>
        +#endif
        +
        +/* 06-Apr-92 Luke Brennan    Support for VMS */
        +#include "ui_locl.h"
        +#include "cryptlib.h"
        +
        +#ifdef OPENSSL_SYS_VMS		/* prototypes for sys$whatever */
        +# include <starlet.h>
        +# ifdef __DECC
        +#  pragma message disable DOLLARID
        +# endif
        +#endif
        +
        +#ifdef WIN_CONSOLE_BUG
        +# include <windows.h>
        +#ifndef OPENSSL_SYS_WINCE
        +# include <wincon.h>
        +#endif
        +#endif
        +
        +
        +/* There are 5 types of terminal interface supported,
        + * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
        + */
        +
        +#if defined(__sgi) && !defined(TERMIOS)
        +# define TERMIOS
        +# undef  TERMIO
        +# undef  SGTTY
        +#endif
        +
        +#if defined(linux) && !defined(TERMIO)
        +# undef  TERMIOS
        +# define TERMIO
        +# undef  SGTTY
        +#endif
        +
        +#ifdef _LIBC
        +# undef  TERMIOS
        +# define TERMIO
        +# undef  SGTTY
        +#endif
        +
        +#if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(MAC_OS_GUSI_SOURCE)
        +# undef  TERMIOS
        +# undef  TERMIO
        +# define SGTTY
        +#endif
        +
        +#if defined(OPENSSL_SYS_VXWORKS)
        +#undef TERMIOS
        +#undef TERMIO
        +#undef SGTTY
        +#endif
        +
        +#if defined(OPENSSL_SYS_NETWARE)
        +#undef TERMIOS
        +#undef TERMIO
        +#undef SGTTY
        +#endif
        +
        +#ifdef TERMIOS
        +# include <termios.h>
        +# define TTY_STRUCT		struct termios
        +# define TTY_FLAGS		c_lflag
        +# define TTY_get(tty,data)	tcgetattr(tty,data)
        +# define TTY_set(tty,data)	tcsetattr(tty,TCSANOW,data)
        +#endif
        +
        +#ifdef TERMIO
        +# include <termio.h>
        +# define TTY_STRUCT		struct termio
        +# define TTY_FLAGS		c_lflag
        +# define TTY_get(tty,data)	ioctl(tty,TCGETA,data)
        +# define TTY_set(tty,data)	ioctl(tty,TCSETA,data)
        +#endif
        +
        +#ifdef SGTTY
        +# include <sgtty.h>
        +# define TTY_STRUCT		struct sgttyb
        +# define TTY_FLAGS		sg_flags
        +# define TTY_get(tty,data)	ioctl(tty,TIOCGETP,data)
        +# define TTY_set(tty,data)	ioctl(tty,TIOCSETP,data)
        +#endif
        +
        +#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS)
        +# include <sys/ioctl.h>
        +#endif
        +
        +#ifdef OPENSSL_SYS_MSDOS
        +# include <conio.h>
        +#endif
        +
        +#ifdef OPENSSL_SYS_VMS
        +# include <ssdef.h>
        +# include <iodef.h>
        +# include <ttdef.h>
        +# include <descrip.h>
        +struct IOSB {
        +	short iosb$w_value;
        +	short iosb$w_count;
        +	long  iosb$l_info;
        +	};
        +#endif
        +
        +#ifdef OPENSSL_SYS_SUNOS
        +	typedef int sig_atomic_t;
        +#endif
        +
        +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE)
        +/*
        + * This one needs work. As a matter of fact the code is unoperational
        + * and this is only a trick to get it compiled.
        + *					<appro@fy.chalmers.se>
        + */
        +# define TTY_STRUCT int
        +#endif
        +
        +#ifndef NX509_SIG
        +# define NX509_SIG 32
        +#endif
        +
        +
        +/* Define globals.  They are protected by a lock */
        +#ifdef SIGACTION
        +static struct sigaction savsig[NX509_SIG];
        +#else
        +static void (*savsig[NX509_SIG])(int );
        +#endif
        +
        +#ifdef OPENSSL_SYS_VMS
        +static struct IOSB iosb;
        +static $DESCRIPTOR(terminal,"TT");
        +static long tty_orig[3], tty_new[3]; /* XXX   Is there any guarantee that this will always suffice for the actual structures? */
        +static long status;
        +static unsigned short channel = 0;
        +#else
        +#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
        +static TTY_STRUCT tty_orig,tty_new;
        +#endif
        +#endif
        +static FILE *tty_in, *tty_out;
        +static int is_a_tty;
        +
        +/* Declare static functions */
        +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
        +static int read_till_nl(FILE *);
        +static void recsig(int);
        +static void pushsig(void);
        +static void popsig(void);
        +#endif
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16)
        +static int noecho_fgets(char *buf, int size, FILE *tty);
        +#endif
        +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl);
        +
        +static int read_string(UI *ui, UI_STRING *uis);
        +static int write_string(UI *ui, UI_STRING *uis);
        +
        +static int open_console(UI *ui);
        +static int echo_console(UI *ui);
        +static int noecho_console(UI *ui);
        +static int close_console(UI *ui);
        +
        +static UI_METHOD ui_openssl =
        +	{
        +	"OpenSSL default user interface",
        +	open_console,
        +	write_string,
        +	NULL,			/* No flusher is needed for command lines */
        +	read_string,
        +	close_console,
        +	NULL
        +	};
        +
        +/* The method with all the built-in thingies */
        +UI_METHOD *UI_OpenSSL(void)
        +	{
        +	return &ui_openssl;
        +	}
        +
        +/* The following function makes sure that info and error strings are printed
        +   before any prompt. */
        +static int write_string(UI *ui, UI_STRING *uis)
        +	{
        +	switch (UI_get_string_type(uis))
        +		{
        +	case UIT_ERROR:
        +	case UIT_INFO:
        +		fputs(UI_get0_output_string(uis), tty_out);
        +		fflush(tty_out);
        +		break;
        +	default:
        +		break;
        +		}
        +	return 1;
        +	}
        +
        +static int read_string(UI *ui, UI_STRING *uis)
        +	{
        +	int ok = 0;
        +
        +	switch (UI_get_string_type(uis))
        +		{
        +	case UIT_BOOLEAN:
        +		fputs(UI_get0_output_string(uis), tty_out);
        +		fputs(UI_get0_action_string(uis), tty_out);
        +		fflush(tty_out);
        +		return read_string_inner(ui, uis,
        +			UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0);
        +	case UIT_PROMPT:
        +		fputs(UI_get0_output_string(uis), tty_out);
        +		fflush(tty_out);
        +		return read_string_inner(ui, uis,
        +			UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1);
        +	case UIT_VERIFY:
        +		fprintf(tty_out,"Verifying - %s",
        +			UI_get0_output_string(uis));
        +		fflush(tty_out);
        +		if ((ok = read_string_inner(ui, uis,
        +			UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1)) <= 0)
        +			return ok;
        +		if (strcmp(UI_get0_result_string(uis),
        +			UI_get0_test_string(uis)) != 0)
        +			{
        +			fprintf(tty_out,"Verify failure\n");
        +			fflush(tty_out);
        +			return 0;
        +			}
        +		break;
        +	default:
        +		break;
        +		}
        +	return 1;
        +	}
        +
        +
        +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
        +/* Internal functions to read a string without echoing */
        +static int read_till_nl(FILE *in)
        +	{
        +#define SIZE 4
        +	char buf[SIZE+1];
        +
        +	do	{
        +		if (!fgets(buf,SIZE,in))
        +			return 0;
        +		} while (strchr(buf,'\n') == NULL);
        +	return 1;
        +	}
        +
        +static volatile sig_atomic_t intr_signal;
        +#endif
        +
        +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
        +	{
        +	static int ps;
        +	int ok;
        +	char result[BUFSIZ];
        +	int maxsize = BUFSIZ-1;
        +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
        +	char *p;
        +
        +	intr_signal=0;
        +	ok=0;
        +	ps=0;
        +
        +	pushsig();
        +	ps=1;
        +
        +	if (!echo && !noecho_console(ui))
        +		goto error;
        +	ps=2;
        +
        +	result[0]='\0';
        +#ifdef OPENSSL_SYS_MSDOS
        +	if (!echo)
        +		{
        +		noecho_fgets(result,maxsize,tty_in);
        +		p=result; /* FIXME: noecho_fgets doesn't return errors */
        +		}
        +	else
        +		p=fgets(result,maxsize,tty_in);
        +#else
        +	p=fgets(result,maxsize,tty_in);
        +#endif
        +	if(!p)
        +		goto error;
        +	if (feof(tty_in)) goto error;
        +	if (ferror(tty_in)) goto error;
        +	if ((p=(char *)strchr(result,'\n')) != NULL)
        +		{
        +		if (strip_nl)
        +			*p='\0';
        +		}
        +	else
        +		if (!read_till_nl(tty_in))
        +			goto error;
        +	if (UI_set_result(ui, uis, result) >= 0)
        +		ok=1;
        +
        +error:
        +	if (intr_signal == SIGINT)
        +		ok=-1;
        +	if (!echo) fprintf(tty_out,"\n");
        +	if (ps >= 2 && !echo && !echo_console(ui))
        +		ok=0;
        +
        +	if (ps >= 1)
        +		popsig();
        +#else
        +	ok=1;
        +#endif
        +
        +	OPENSSL_cleanse(result,BUFSIZ);
        +	return ok;
        +	}
        +
        +
        +/* Internal functions to open, handle and close a channel to the console.  */
        +static int open_console(UI *ui)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_UI);
        +	is_a_tty = 1;
        +
        +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS)
        +	tty_in=stdin;
        +	tty_out=stderr;
        +#else
        +#  ifdef OPENSSL_SYS_MSDOS
        +#    define DEV_TTY "con"
        +#  else
        +#    define DEV_TTY "/dev/tty"
        +#  endif
        +	if ((tty_in=fopen(DEV_TTY,"r")) == NULL)
        +		tty_in=stdin;
        +	if ((tty_out=fopen(DEV_TTY,"w")) == NULL)
        +		tty_out=stderr;
        +#endif
        +
        +#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
        + 	if (TTY_get(fileno(tty_in),&tty_orig) == -1)
        +		{
        +#ifdef ENOTTY
        +		if (errno == ENOTTY)
        +			is_a_tty=0;
        +		else
        +#endif
        +#ifdef EINVAL
        +		/* Ariel Glenn ariel@columbia.edu reports that solaris
        +		 * can return EINVAL instead.  This should be ok */
        +		if (errno == EINVAL)
        +			is_a_tty=0;
        +		else
        +#endif
        +			return 0;
        +		}
        +#endif
        +#ifdef OPENSSL_SYS_VMS
        +	status = sys$assign(&terminal,&channel,0,0);
        +	if (status != SS$_NORMAL)
        +		return 0;
        +	status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
        +	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
        +		return 0;
        +#endif
        +	return 1;
        +	}
        +
        +static int noecho_console(UI *ui)
        +	{
        +#ifdef TTY_FLAGS
        +	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
        +	tty_new.TTY_FLAGS &= ~ECHO;
        +#endif
        +
        +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
        +	if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1))
        +		return 0;
        +#endif
        +#ifdef OPENSSL_SYS_VMS
        +	tty_new[0] = tty_orig[0];
        +	tty_new[1] = tty_orig[1] | TT$M_NOECHO;
        +	tty_new[2] = tty_orig[2];
        +	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
        +	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
        +		return 0;
        +#endif
        +	return 1;
        +	}
        +
        +static int echo_console(UI *ui)
        +	{
        +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
        +	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
        +	tty_new.TTY_FLAGS |= ECHO;
        +#endif
        +
        +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
        +	if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1))
        +		return 0;
        +#endif
        +#ifdef OPENSSL_SYS_VMS
        +	tty_new[0] = tty_orig[0];
        +	tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
        +	tty_new[2] = tty_orig[2];
        +	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
        +	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
        +		return 0;
        +#endif
        +	return 1;
        +	}
        +
        +static int close_console(UI *ui)
        +	{
        +	if (tty_in != stdin) fclose(tty_in);
        +	if (tty_out != stderr) fclose(tty_out);
        +#ifdef OPENSSL_SYS_VMS
        +	status = sys$dassgn(channel);
        +#endif
        +	CRYPTO_w_unlock(CRYPTO_LOCK_UI);
        +
        +	return 1;
        +	}
        +
        +
        +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
        +/* Internal functions to handle signals and act on them */
        +static void pushsig(void)
        +	{
        +#ifndef OPENSSL_SYS_WIN32
        +	int i;
        +#endif
        +#ifdef SIGACTION
        +	struct sigaction sa;
        +
        +	memset(&sa,0,sizeof sa);
        +	sa.sa_handler=recsig;
        +#endif
        +
        +#ifdef OPENSSL_SYS_WIN32
        +	savsig[SIGABRT]=signal(SIGABRT,recsig);
        +	savsig[SIGFPE]=signal(SIGFPE,recsig);
        +	savsig[SIGILL]=signal(SIGILL,recsig);
        +	savsig[SIGINT]=signal(SIGINT,recsig);
        +	savsig[SIGSEGV]=signal(SIGSEGV,recsig);
        +	savsig[SIGTERM]=signal(SIGTERM,recsig);
        +#else
        +	for (i=1; i<NX509_SIG; i++)
        +		{
        +#ifdef SIGUSR1
        +		if (i == SIGUSR1)
        +			continue;
        +#endif
        +#ifdef SIGUSR2
        +		if (i == SIGUSR2)
        +			continue;
        +#endif
        +#ifdef SIGKILL
        +		if (i == SIGKILL) /* We can't make any action on that. */
        +			continue;
        +#endif
        +#ifdef SIGACTION
        +		sigaction(i,&sa,&savsig[i]);
        +#else
        +		savsig[i]=signal(i,recsig);
        +#endif
        +		}
        +#endif
        +
        +#ifdef SIGWINCH
        +	signal(SIGWINCH,SIG_DFL);
        +#endif
        +	}
        +
        +static void popsig(void)
        +	{
        +#ifdef OPENSSL_SYS_WIN32
        +	signal(SIGABRT,savsig[SIGABRT]);
        +	signal(SIGFPE,savsig[SIGFPE]);
        +	signal(SIGILL,savsig[SIGILL]);
        +	signal(SIGINT,savsig[SIGINT]);
        +	signal(SIGSEGV,savsig[SIGSEGV]);
        +	signal(SIGTERM,savsig[SIGTERM]);
        +#else
        +	int i;
        +	for (i=1; i<NX509_SIG; i++)
        +		{
        +#ifdef SIGUSR1
        +		if (i == SIGUSR1)
        +			continue;
        +#endif
        +#ifdef SIGUSR2
        +		if (i == SIGUSR2)
        +			continue;
        +#endif
        +#ifdef SIGACTION
        +		sigaction(i,&savsig[i],NULL);
        +#else
        +		signal(i,savsig[i]);
        +#endif
        +		}
        +#endif
        +	}
        +
        +static void recsig(int i)
        +	{
        +	intr_signal=i;
        +	}
        +#endif
        +
        +/* Internal functions specific for Windows */
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
        +static int noecho_fgets(char *buf, int size, FILE *tty)
        +	{
        +	int i;
        +	char *p;
        +
        +	p=buf;
        +	for (;;)
        +		{
        +		if (size == 0)
        +			{
        +			*p='\0';
        +			break;
        +			}
        +		size--;
        +#ifdef WIN16TTY
        +		i=_inchar();
        +#elif defined(_WIN32)
        +		i=_getch();
        +#else
        +		i=getch();
        +#endif
        +		if (i == '\r') i='\n';
        +		*(p++)=i;
        +		if (i == '\n')
        +			{
        +			*p='\0';
        +			break;
        +			}
        +		}
        +#ifdef WIN_CONSOLE_BUG
        +/* Win95 has several evil console bugs: one of these is that the
        + * last character read using getch() is passed to the next read: this is
        + * usually a CR so this can be trouble. No STDIO fix seems to work but
        + * flushing the console appears to do the trick.
        + */
        +		{
        +			HANDLE inh;
        +			inh = GetStdHandle(STD_INPUT_HANDLE);
        +			FlushConsoleInputBuffer(inh);
        +		}
        +#endif
        +	return(strlen(buf));
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/ui/ui_util.c b/vendor/openssl/openssl/crypto/ui/ui_util.c
        new file mode 100644
        index 000000000..5d9760bb7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/ui/ui_util.c
        @@ -0,0 +1,91 @@
        +/* crypto/ui/ui_util.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <string.h>
        +#include "ui_locl.h"
        +
        +int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify)
        +	{
        +	char buff[BUFSIZ];
        +	int ret;
        +
        +	ret=UI_UTIL_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
        +	OPENSSL_cleanse(buff,BUFSIZ);
        +	return(ret);
        +	}
        +
        +int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify)
        +	{
        +	int ok = 0;
        +	UI *ui;
        +
        +	if (size < 1)
        +		return -1;
        +
        +	ui = UI_new();
        +	if (ui)
        +		{
        +		ok = UI_add_input_string(ui,prompt,0,buf,0,size-1);
        +		if (ok >= 0 && verify)
        +			ok = UI_add_verify_string(ui,prompt,0,buff,0,size-1,
        +				buf);
        +		if (ok >= 0)
        +			ok=UI_process(ui);
        +		UI_free(ui);
        +		}
        +	if (ok > 0)
        +		ok = 0;
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/uid.c b/vendor/openssl/openssl/crypto/uid.c
        new file mode 100644
        index 000000000..b1fd52bad
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/uid.c
        @@ -0,0 +1,89 @@
        +/* crypto/uid.c */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <openssl/crypto.h>
        +#include <openssl/opensslconf.h>
        +
        +#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2)
        +
        +#include OPENSSL_UNISTD
        +
        +int OPENSSL_issetugid(void)
        +	{
        +	return issetugid();
        +	}
        +
        +#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
        +
        +int OPENSSL_issetugid(void)
        +	{
        +	return 0;
        +	}
        +
        +#else
        +
        +#include OPENSSL_UNISTD
        +#include <sys/types.h>
        +
        +int OPENSSL_issetugid(void)
        +	{
        +	if (getuid() != geteuid()) return 1;
        +	if (getgid() != getegid()) return 1;
        +	return 0;
        +	}
        +#endif
        +
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/vms_rms.h b/vendor/openssl/openssl/crypto/vms_rms.h
        new file mode 100644
        index 000000000..00a00d993
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/vms_rms.h
        @@ -0,0 +1,51 @@
        +
        +#ifdef NAML$C_MAXRSS
        +
        +# define CC_RMS_NAMX cc$rms_naml
        +# define FAB_NAMX fab$l_naml
        +# define FAB_OR_NAML( fab, naml) naml
        +# define FAB_OR_NAML_DNA naml$l_long_defname
        +# define FAB_OR_NAML_DNS naml$l_long_defname_size
        +# define FAB_OR_NAML_FNA naml$l_long_filename
        +# define FAB_OR_NAML_FNS naml$l_long_filename_size
        +# define NAMX_ESA naml$l_long_expand
        +# define NAMX_ESL naml$l_long_expand_size
        +# define NAMX_ESS naml$l_long_expand_alloc
        +# define NAMX_NOP naml$b_nop
        +# define SET_NAMX_NO_SHORT_UPCASE( nam) nam.naml$v_no_short_upcase = 1
        +
        +# if __INITIAL_POINTER_SIZE == 64
        +#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (__char_ptr32) -1; \
        +   fab.fab$l_fna = (__char_ptr32) -1;
        +# else /* __INITIAL_POINTER_SIZE == 64 */
        +#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (char *) -1; \
        +   fab.fab$l_fna = (char *) -1;
        +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
        +
        +# define NAMX_MAXRSS NAML$C_MAXRSS
        +# define NAMX_STRUCT NAML
        +
        +#else /* def NAML$C_MAXRSS */
        +
        +# define CC_RMS_NAMX cc$rms_nam
        +# define FAB_NAMX fab$l_nam
        +# define FAB_OR_NAML( fab, naml) fab
        +# define FAB_OR_NAML_DNA fab$l_dna
        +# define FAB_OR_NAML_DNS fab$b_dns
        +# define FAB_OR_NAML_FNA fab$l_fna
        +# define FAB_OR_NAML_FNS fab$b_fns
        +# define NAMX_ESA nam$l_esa
        +# define NAMX_ESL nam$b_esl
        +# define NAMX_ESS nam$b_ess
        +# define NAMX_NOP nam$b_nop
        +# define NAMX_DNA_FNA_SET(fab)
        +# define NAMX_MAXRSS NAM$C_MAXRSS
        +# define NAMX_STRUCT NAM
        +# ifdef NAM$M_NO_SHORT_UPCASE
        +#  define SET_NAMX_NO_SHORT_UPCASE( nam) naml.naml$v_no_short_upcase = 1
        +# else /* def NAM$M_NO_SHORT_UPCASE */
        +#  define SET_NAMX_NO_SHORT_UPCASE( nam)
        +# endif /* def NAM$M_NO_SHORT_UPCASE [else] */
        +
        +#endif /* def NAML$C_MAXRSS [else] */
        +
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/Makefile b/vendor/openssl/openssl/crypto/whrlpool/Makefile
        new file mode 100644
        index 000000000..f4d46e4d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/Makefile
        @@ -0,0 +1,96 @@
        +#
        +# crypto/whrlpool/Makefile
        +#
        +
        +DIR=	whrlpool
        +TOP=	../..
        +CC=	cc
        +CPP=	$(CC) -E
        +INCLUDES=
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +WP_ASM_OBJ=wp_block.o
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +ASFLAGS= $(INCLUDES) $(ASFLAG)
        +AFLAGS= $(ASFLAGS)
        +
        +GENERAL=Makefile
        +TEST=wp_test.c
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=wp_dgst.c wp_block.c
        +LIBOBJ=wp_dgst.o $(WP_ASM_OBJ)
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= whrlpool.h
        +HEADER= wp_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) || echo Never mind.
        +	@touch lib
        +
        +wp-mmx.s:	asm/wp-mmx.pl ../perlasm/x86asm.pl
        +	$(PERL) asm/wp-mmx.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@
        +
        +wp-x86_64.s: asm/wp-x86_64.pl
        +	$(PERL) asm/wp-x86_64.pl $(PERLASM_SCHEME) > $@
        +
        +$(LIBOBJ): $(LIBSRC)
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +wp_block.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
        +wp_block.o: ../../include/openssl/whrlpool.h wp_block.c wp_locl.h
        +wp_dgst.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +wp_dgst.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +wp_dgst.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
        +wp_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +wp_dgst.o: ../../include/openssl/whrlpool.h wp_dgst.c wp_locl.h
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl b/vendor/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl
        new file mode 100644
        index 000000000..cb2381c22
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/asm/wp-mmx.pl
        @@ -0,0 +1,493 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. Rights for redistribution and usage in source and binary
        +# forms are granted according to the OpenSSL license.
        +# ====================================================================
        +#
        +# whirlpool_block_mmx implementation.
        +#
        +*SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results
        +# in 16KB large table, which is tough on L1 cache, but eliminates
        +# unaligned references to it. Value of 2 results in 4KB table, but
        +# 7/8 of references to it are unaligned. AMD cores seem to be
        +# allergic to the latter, while Intel ones - to former [see the
        +# table]. I stick to value of 2 for two reasons: 1. smaller table
        +# minimizes cache trashing and thus mitigates the hazard of side-
        +# channel leakage similar to AES cache-timing one; 2. performance
        +# gap among different µ-archs is smaller.
        +#
        +# Performance table lists rounded amounts of CPU cycles spent by
        +# whirlpool_block_mmx routine on single 64 byte input block, i.e.
        +# smaller is better and asymptotic throughput can be estimated by
        +# multiplying 64 by CPU clock frequency and dividing by relevant
        +# value from the given table:
        +#
        +#		$SCALE=2/8	icc8	gcc3	
        +# Intel P4	3200/4600	4600(*)	6400
        +# Intel PIII	2900/3000	4900	5400
        +# AMD K[78]	2500/1800	9900	8200(**)
        +#
        +# (*)	I've sketched even non-MMX assembler, but for the record
        +#	I've failed to beat the Intel compiler on P4, without using
        +#	MMX that is...
        +# (**)	... on AMD on the other hand non-MMX assembler was observed
        +#	to perform significantly better, but I figured this MMX
        +#	implementation is even faster anyway, so why bother? As for
        +#	pre-MMX AMD core[s], the improvement coefficient is more
        +#	than likely to vary anyway and I don't know how. But the
        +#	least I know is that gcc-generated code compiled with
        +#	-DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for
        +#	details] and optimized for Pentium was observed to perform
        +#	*better* on Pentium 100 than unrolled non-MMX assembler
        +#	loop... So we just say that I don't know if maintaining
        +#	non-MMX implementation would actually pay off, but till
        +#	opposite is proved "unlikely" is assumed.
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}","${dir}../../perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"wp-mmx.pl");
        +
        +sub L()  { &data_byte(@_); }
        +sub LL()
        +{	if	($SCALE==2)	{ &data_byte(@_); &data_byte(@_); }
        +	elsif	($SCALE==8)	{ for ($i=0;$i<8;$i++) {
        +					&data_byte(@_);
        +					unshift(@_,pop(@_));
        +				  }
        +				}
        +	else			{ die "unvalid SCALE value"; }
        +}
        +
        +sub scale()
        +{	if	($SCALE==2)	{ &lea(@_[0],&DWP(0,@_[1],@_[1])); }
        +	elsif	($SCALE==8)	{ &lea(@_[0],&DWP(0,"",@_[1],8));  }
        +	else			{ die "unvalid SCALE value";       }
        +}
        +
        +sub row()
        +{	if	($SCALE==2)	{ ((8-shift)&7); }
        +	elsif	($SCALE==8)	{ (8*shift);     }
        +	else			{ die "unvalid SCALE value"; }
        +}
        +
        +$tbl="ebp";
        +@mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7");
        +
        +&function_begin_B("whirlpool_block_mmx");
        +	&push	("ebp");
        +	&push	("ebx");
        +	&push	("esi");
        +	&push	("edi");
        +
        +	&mov	("esi",&wparam(0));		# hash value
        +	&mov	("edi",&wparam(1));		# input data stream
        +	&mov	("ebp",&wparam(2));		# number of chunks in input
        +
        +	&mov	("eax","esp");			# copy stack pointer
        +	&sub	("esp",128+20);			# allocate frame
        +	&and	("esp",-64);			# align for cache-line
        +
        +	&lea	("ebx",&DWP(128,"esp"));
        +	&mov	(&DWP(0,"ebx"),"esi");		# save parameter block
        +	&mov	(&DWP(4,"ebx"),"edi");
        +	&mov	(&DWP(8,"ebx"),"ebp");
        +	&mov	(&DWP(16,"ebx"),"eax");		# saved stack pointer
        +
        +	&call	(&label("pic_point"));
        +&set_label("pic_point");
        +	&blindpop($tbl);
        +	&lea	($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl));
        +
        +	&xor	("ecx","ecx");
        +	&xor	("edx","edx");
        +
        +	for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); }    # L=H
        +&set_label("outerloop");
        +	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
        +	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
        +	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
        +
        +	&xor	("esi","esi");
        +	&mov	(&DWP(12,"ebx"),"esi");		# zero round counter
        +
        +&set_label("round",16);
        +	&movq	(@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8));	# rc[r]
        +	&mov	("eax",&DWP(0,"esp"));
        +	&mov	("ebx",&DWP(4,"esp"));
        +for($i=0;$i<8;$i++) {
        +    my $func = ($i==0)? \&movq : \&pxor;
        +	&movb	(&LB("ecx"),&LB("eax"));
        +	&movb	(&LB("edx"),&HB("eax"));
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&shr	("eax",16);
        +	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
        +	&$func	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
        +	&movb	(&LB("ecx"),&LB("eax"));
        +	&movb	(&LB("edx"),&HB("eax"));
        +	&mov	("eax",&DWP(($i+1)*8,"esp"));
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&$func	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
        +	&$func	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
        +	&movb	(&LB("ecx"),&LB("ebx"));
        +	&movb	(&LB("edx"),&HB("ebx"));
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&shr	("ebx",16);
        +	&$func	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
        +	&$func	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
        +	&movb	(&LB("ecx"),&LB("ebx"));
        +	&movb	(&LB("edx"),&HB("ebx"));
        +	&mov	("ebx",&DWP(($i+1)*8+4,"esp"));
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&$func	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
        +	&$func	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
        +    push(@mm,shift(@mm));
        +}
        +
        +	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
        +
        +for($i=0;$i<8;$i++) {
        +	&movb	(&LB("ecx"),&LB("eax"));
        +	&movb	(&LB("edx"),&HB("eax"));
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&shr	("eax",16);
        +	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
        +	&pxor	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
        +	&movb	(&LB("ecx"),&LB("eax"));
        +	&movb	(&LB("edx"),&HB("eax"));
        +	&mov	("eax",&DWP(64+($i+1)*8,"esp"))		if ($i<7);
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&pxor	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
        +	&pxor	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
        +	&movb	(&LB("ecx"),&LB("ebx"));
        +	&movb	(&LB("edx"),&HB("ebx"));
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&shr	("ebx",16);
        +	&pxor	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
        +	&pxor	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
        +	&movb	(&LB("ecx"),&LB("ebx"));
        +	&movb	(&LB("edx"),&HB("ebx"));
        +	&mov	("ebx",&DWP(64+($i+1)*8+4,"esp"))	if ($i<7);
        +	&scale	("esi","ecx");
        +	&scale	("edi","edx");
        +	&pxor	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
        +	&pxor	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
        +    push(@mm,shift(@mm));
        +}
        +	&lea	("ebx",&DWP(128,"esp"));
        +	&mov	("esi",&DWP(12,"ebx"));		# pull round counter
        +	&add	("esi",1);
        +	&cmp	("esi",10);
        +	&je	(&label("roundsdone"));
        +
        +	&mov	(&DWP(12,"ebx"),"esi");		# update round counter
        +	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
        +	&jmp	(&label("round"));
        +
        +&set_label("roundsdone",16);
        +	&mov	("esi",&DWP(0,"ebx"));		# reload argument block
        +	&mov	("edi",&DWP(4,"ebx"));
        +	&mov	("eax",&DWP(8,"ebx"));
        +
        +	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
        +	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); }    # L^=H
        +	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); }    # H=L
        +
        +	&lea	("edi",&DWP(64,"edi"));		# inp+=64
        +	&sub	("eax",1);			# num--
        +	&jz	(&label("alldone"));
        +	&mov	(&DWP(4,"ebx"),"edi");		# update argument block
        +	&mov	(&DWP(8,"ebx"),"eax");
        +	&jmp	(&label("outerloop"));
        +
        +&set_label("alldone");
        +	&emms	();
        +	&mov	("esp",&DWP(16,"ebx"));		# restore saved stack pointer
        +	&pop	("edi");
        +	&pop	("esi");
        +	&pop	("ebx");
        +	&pop	("ebp");
        +	&ret	();
        +
        +&align(64);
        +&set_label("table");
        +	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
        +	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
        +	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
        +	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
        +	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
        +	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
        +	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
        +	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
        +	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
        +	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
        +	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
        +	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
        +	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
        +	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
        +	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
        +	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
        +	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
        +	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
        +	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
        +	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
        +	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
        +	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
        +	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
        +	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
        +	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
        +	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
        +	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
        +	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
        +	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
        +	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
        +	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
        +	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
        +	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
        +	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
        +	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
        +	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
        +	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
        +	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
        +	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
        +	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
        +	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
        +	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
        +	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
        +	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
        +	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
        +	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
        +	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
        +	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
        +	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
        +	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
        +	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
        +	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
        +	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
        +	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
        +	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
        +	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
        +	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
        +	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
        +	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
        +	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
        +	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
        +	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
        +	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
        +	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
        +	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
        +	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
        +	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
        +	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
        +	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
        +	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
        +	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
        +	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
        +	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
        +	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
        +	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
        +	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
        +	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
        +	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
        +	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
        +	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
        +	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
        +	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
        +	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
        +	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
        +	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
        +	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
        +	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
        +	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
        +	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
        +	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
        +	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
        +	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
        +	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
        +	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
        +	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
        +	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
        +	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
        +	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
        +	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
        +	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
        +	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
        +	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
        +	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
        +	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
        +	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
        +	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
        +	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
        +	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
        +	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
        +	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
        +	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
        +	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
        +	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
        +	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
        +	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
        +	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
        +	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
        +	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
        +	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
        +	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
        +	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
        +	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
        +	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
        +	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
        +	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
        +	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
        +	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
        +	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
        +	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
        +	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
        +	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
        +	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
        +	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
        +	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
        +	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
        +	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
        +	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
        +	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
        +	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
        +	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
        +	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
        +	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
        +	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
        +	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
        +	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
        +	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
        +	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
        +	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
        +	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
        +	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
        +	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
        +	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
        +	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
        +	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
        +	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
        +	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
        +	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
        +	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
        +	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
        +	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
        +	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
        +	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
        +	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
        +	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
        +	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
        +	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
        +	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
        +	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
        +	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
        +	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
        +	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
        +	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
        +	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
        +	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
        +	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
        +	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
        +	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
        +	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
        +	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
        +	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
        +	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
        +	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
        +	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
        +	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
        +	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
        +	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
        +	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
        +	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
        +	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
        +	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
        +	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
        +	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
        +	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
        +	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
        +	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
        +	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
        +	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
        +	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
        +	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
        +	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
        +	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
        +	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
        +	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
        +	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
        +	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
        +	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
        +	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
        +	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
        +	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
        +	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
        +	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
        +	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
        +	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
        +	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
        +	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
        +	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
        +	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
        +	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
        +	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
        +	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
        +	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
        +	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
        +	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
        +	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
        +	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
        +	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
        +	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
        +	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
        +	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
        +	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
        +	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
        +	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
        +	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
        +	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
        +	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
        +	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
        +	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
        +	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
        +	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
        +	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
        +	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
        +	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
        +	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
        +	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
        +	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
        +	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
        +	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
        +	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
        +	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
        +	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
        +	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
        +	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
        +	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
        +	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
        +	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
        +	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
        +
        +	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
        +	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
        +	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
        +	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
        +	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
        +	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
        +	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
        +	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
        +	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
        +	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
        +
        +&function_end_B("whirlpool_block_mmx");
        +&asm_finish(); 
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl b/vendor/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl
        new file mode 100644
        index 000000000..24b2ff60c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/asm/wp-x86_64.pl
        @@ -0,0 +1,590 @@
        +#!/usr/bin/env perl
        +#
        +# ====================================================================
        +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
        +# project. Rights for redistribution and usage in source and binary
        +# forms are granted according to the OpenSSL license.
        +# ====================================================================
        +#
        +# whirlpool_block for x86_64.
        +#
        +# 2500 cycles per 64-byte input block on AMD64, which is *identical*
        +# to 32-bit MMX version executed on same CPU. So why did I bother?
        +# Well, it's faster than gcc 3.3.2 generated code by over 50%, and
        +# over 80% faster than PathScale 1.4, an "ambitious" commercial
        +# compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio
        +# 10 - by 360%[!]... What is it with x86_64 compilers? It's not the
        +# first example when they fail to generate more optimal code, when
        +# I believe they had *all* chances to...
        +#
        +# Note that register and stack frame layout are virtually identical
        +# to 32-bit MMX version, except that %r8-15 are used instead of
        +# %mm0-8. You can even notice that K[i] and S[i] are loaded to
        +# %eax:%ebx as pair of 32-bit values and not as single 64-bit one.
        +# This is done in order to avoid 64-bit shift penalties on Intel
        +# EM64T core. Speaking of which! I bet it's possible to improve
        +# Opteron performance by compressing the table to 2KB and replacing
        +# unaligned references with complementary rotations [which would
        +# incidentally replace lea instructions], but it would definitely
        +# just "kill" EM64T, because it has only 1 shifter/rotator [against
        +# 3 on Opteron] and which is *unacceptably* slow with 64-bit
        +# operand.
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +sub L() { $code.=".byte	".join(',',@_)."\n"; }
        +sub LL(){ $code.=".byte	".join(',',@_).",".join(',',@_)."\n"; }
        +
        +@mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15");
        +
        +$func="whirlpool_block";
        +$table=".Ltable";
        +
        +$code=<<___;
        +.text
        +
        +.globl	$func
        +.type	$func,\@function,3
        +.align	16
        +$func:
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +
        +	mov	%rsp,%r11
        +	sub	\$128+40,%rsp
        +	and	\$-64,%rsp
        +
        +	lea	128(%rsp),%r10
        +	mov	%rdi,0(%r10)		# save parameter block
        +	mov	%rsi,8(%r10)
        +	mov	%rdx,16(%r10)
        +	mov	%r11,32(%r10)		# saved stack pointer
        +.Lprologue:
        +
        +	mov	%r10,%rbx
        +	lea	$table(%rip),%rbp
        +
        +	xor	%rcx,%rcx
        +	xor	%rdx,%rdx
        +___
        +for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; }	# L=H
        +$code.=".Louterloop:\n";
        +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
        +for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
        +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
        +$code.=<<___;
        +	xor	%rsi,%rsi
        +	mov	%rsi,24(%rbx)		# zero round counter
        +.align	16
        +.Lround:
        +	mov	4096(%rbp,%rsi,8),@mm[0]	# rc[r]
        +	mov	0(%rsp),%eax
        +	mov	4(%rsp),%ebx
        +___
        +for($i=0;$i<8;$i++) {
        +    my $func = ($i==0)? "mov" : "xor";
        +    $code.=<<___;
        +	mov	%al,%cl
        +	mov	%ah,%dl
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	shr	\$16,%eax
        +	xor	0(%rbp,%rsi,8),@mm[0]
        +	$func	7(%rbp,%rdi,8),@mm[1]
        +	mov	%al,%cl
        +	mov	%ah,%dl
        +	mov	$i*8+8(%rsp),%eax		# ($i+1)*8
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	$func	6(%rbp,%rsi,8),@mm[2]
        +	$func	5(%rbp,%rdi,8),@mm[3]
        +	mov	%bl,%cl
        +	mov	%bh,%dl
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	shr	\$16,%ebx
        +	$func	4(%rbp,%rsi,8),@mm[4]
        +	$func	3(%rbp,%rdi,8),@mm[5]
        +	mov	%bl,%cl
        +	mov	%bh,%dl
        +	mov	$i*8+8+4(%rsp),%ebx		# ($i+1)*8+4
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	$func	2(%rbp,%rsi,8),@mm[6]
        +	$func	1(%rbp,%rdi,8),@mm[7]
        +___
        +    push(@mm,shift(@mm));
        +}
        +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
        +for($i=0;$i<8;$i++) {
        +    $code.=<<___;
        +	mov	%al,%cl
        +	mov	%ah,%dl
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	shr	\$16,%eax
        +	xor	0(%rbp,%rsi,8),@mm[0]
        +	xor	7(%rbp,%rdi,8),@mm[1]
        +	mov	%al,%cl
        +	mov	%ah,%dl
        +	`"mov	64+$i*8+8(%rsp),%eax"	if($i<7);`	# 64+($i+1)*8
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	xor	6(%rbp,%rsi,8),@mm[2]
        +	xor	5(%rbp,%rdi,8),@mm[3]
        +	mov	%bl,%cl
        +	mov	%bh,%dl
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	shr	\$16,%ebx
        +	xor	4(%rbp,%rsi,8),@mm[4]
        +	xor	3(%rbp,%rdi,8),@mm[5]
        +	mov	%bl,%cl
        +	mov	%bh,%dl
        +	`"mov	64+$i*8+8+4(%rsp),%ebx"	if($i<7);`	# 64+($i+1)*8+4
        +	lea	(%rcx,%rcx),%rsi
        +	lea	(%rdx,%rdx),%rdi
        +	xor	2(%rbp,%rsi,8),@mm[6]
        +	xor	1(%rbp,%rdi,8),@mm[7]
        +___
        +    push(@mm,shift(@mm));
        +}
        +$code.=<<___;
        +	lea	128(%rsp),%rbx
        +	mov	24(%rbx),%rsi		# pull round counter
        +	add	\$1,%rsi
        +	cmp	\$10,%rsi
        +	je	.Lroundsdone
        +
        +	mov	%rsi,24(%rbx)		# update round counter
        +___
        +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
        +$code.=<<___;
        +	jmp	.Lround
        +.align	16
        +.Lroundsdone:
        +	mov	0(%rbx),%rdi		# reload argument block
        +	mov	8(%rbx),%rsi
        +	mov	16(%rbx),%rax
        +___
        +for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
        +for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; }	# L^=H
        +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; }	# H=L
        +$code.=<<___;
        +	lea	64(%rsi),%rsi		# inp+=64
        +	sub	\$1,%rax		# num--
        +	jz	.Lalldone
        +	mov	%rsi,8(%rbx)		# update parameter block
        +	mov	%rax,16(%rbx)
        +	jmp	.Louterloop
        +.Lalldone:
        +	mov	32(%rbx),%rsi		# restore saved pointer
        +	mov	(%rsi),%r15
        +	mov	8(%rsi),%r14
        +	mov	16(%rsi),%r13
        +	mov	24(%rsi),%r12
        +	mov	32(%rsi),%rbp
        +	mov	40(%rsi),%rbx
        +	lea	48(%rsi),%rsp
        +.Lepilogue:
        +	ret
        +.size	$func,.-$func
        +
        +.align	64
        +.type	$table,\@object
        +$table:
        +___
        +	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
        +	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
        +	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
        +	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
        +	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
        +	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
        +	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
        +	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
        +	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
        +	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
        +	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
        +	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
        +	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
        +	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
        +	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
        +	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
        +	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
        +	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
        +	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
        +	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
        +	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
        +	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
        +	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
        +	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
        +	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
        +	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
        +	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
        +	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
        +	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
        +	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
        +	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
        +	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
        +	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
        +	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
        +	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
        +	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
        +	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
        +	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
        +	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
        +	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
        +	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
        +	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
        +	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
        +	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
        +	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
        +	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
        +	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
        +	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
        +	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
        +	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
        +	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
        +	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
        +	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
        +	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
        +	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
        +	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
        +	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
        +	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
        +	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
        +	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
        +	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
        +	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
        +	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
        +	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
        +	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
        +	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
        +	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
        +	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
        +	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
        +	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
        +	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
        +	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
        +	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
        +	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
        +	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
        +	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
        +	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
        +	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
        +	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
        +	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
        +	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
        +	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
        +	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
        +	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
        +	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
        +	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
        +	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
        +	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
        +	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
        +	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
        +	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
        +	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
        +	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
        +	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
        +	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
        +	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
        +	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
        +	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
        +	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
        +	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
        +	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
        +	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
        +	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
        +	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
        +	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
        +	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
        +	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
        +	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
        +	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
        +	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
        +	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
        +	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
        +	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
        +	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
        +	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
        +	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
        +	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
        +	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
        +	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
        +	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
        +	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
        +	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
        +	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
        +	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
        +	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
        +	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
        +	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
        +	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
        +	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
        +	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
        +	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
        +	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
        +	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
        +	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
        +	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
        +	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
        +	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
        +	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
        +	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
        +	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
        +	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
        +	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
        +	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
        +	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
        +	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
        +	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
        +	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
        +	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
        +	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
        +	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
        +	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
        +	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
        +	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
        +	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
        +	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
        +	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
        +	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
        +	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
        +	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
        +	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
        +	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
        +	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
        +	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
        +	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
        +	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
        +	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
        +	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
        +	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
        +	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
        +	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
        +	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
        +	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
        +	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
        +	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
        +	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
        +	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
        +	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
        +	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
        +	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
        +	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
        +	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
        +	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
        +	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
        +	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
        +	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
        +	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
        +	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
        +	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
        +	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
        +	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
        +	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
        +	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
        +	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
        +	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
        +	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
        +	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
        +	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
        +	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
        +	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
        +	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
        +	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
        +	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
        +	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
        +	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
        +	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
        +	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
        +	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
        +	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
        +	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
        +	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
        +	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
        +	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
        +	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
        +	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
        +	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
        +	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
        +	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
        +	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
        +	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
        +	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
        +	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
        +	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
        +	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
        +	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
        +	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
        +	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
        +	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
        +	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
        +	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
        +	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
        +	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
        +	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
        +	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
        +	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
        +	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
        +	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
        +	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
        +	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
        +	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
        +	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
        +	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
        +	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
        +	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
        +	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
        +	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
        +	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
        +	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
        +	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
        +	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
        +	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
        +	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
        +	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
        +	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
        +	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
        +	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
        +	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
        +
        +	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
        +	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
        +	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
        +	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
        +	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
        +	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
        +	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
        +	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
        +	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
        +	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
        +
        +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
        +#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
        +if ($win64) {
        +$rec="%rcx";
        +$frame="%rdx";
        +$context="%r8";
        +$disp="%r9";
        +
        +$code.=<<___;
        +.extern	__imp_RtlVirtualUnwind
        +.type	se_handler,\@abi-omnipotent
        +.align	16
        +se_handler:
        +	push	%rsi
        +	push	%rdi
        +	push	%rbx
        +	push	%rbp
        +	push	%r12
        +	push	%r13
        +	push	%r14
        +	push	%r15
        +	pushfq
        +	sub	\$64,%rsp
        +
        +	mov	120($context),%rax	# pull context->Rax
        +	mov	248($context),%rbx	# pull context->Rip
        +
        +	lea	.Lprologue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip<.Lprologue
        +	jb	.Lin_prologue
        +
        +	mov	152($context),%rax	# pull context->Rsp
        +
        +	lea	.Lepilogue(%rip),%r10
        +	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
        +	jae	.Lin_prologue
        +
        +	mov	128+32(%rax),%rax	# pull saved stack pointer
        +	lea	48(%rax),%rax
        +
        +	mov	-8(%rax),%rbx
        +	mov	-16(%rax),%rbp
        +	mov	-24(%rax),%r12
        +	mov	-32(%rax),%r13
        +	mov	-40(%rax),%r14
        +	mov	-48(%rax),%r15
        +	mov	%rbx,144($context)	# restore context->Rbx
        +	mov	%rbp,160($context)	# restore context->Rbp
        +	mov	%r12,216($context)	# restore context->R12
        +	mov	%r13,224($context)	# restore context->R13
        +	mov	%r14,232($context)	# restore context->R14
        +	mov	%r15,240($context)	# restore context->R15
        +
        +.Lin_prologue:
        +	mov	8(%rax),%rdi
        +	mov	16(%rax),%rsi
        +	mov	%rax,152($context)	# restore context->Rsp
        +	mov	%rsi,168($context)	# restore context->Rsi
        +	mov	%rdi,176($context)	# restore context->Rdi
        +
        +	mov	40($disp),%rdi		# disp->ContextRecord
        +	mov	$context,%rsi		# context
        +	mov	\$154,%ecx		# sizeof(CONTEXT)
        +	.long	0xa548f3fc		# cld; rep movsq
        +
        +	mov	$disp,%rsi
        +	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
        +	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
        +	mov	0(%rsi),%r8		# arg3, disp->ControlPc
        +	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
        +	mov	40(%rsi),%r10		# disp->ContextRecord
        +	lea	56(%rsi),%r11		# &disp->HandlerData
        +	lea	24(%rsi),%r12		# &disp->EstablisherFrame
        +	mov	%r10,32(%rsp)		# arg5
        +	mov	%r11,40(%rsp)		# arg6
        +	mov	%r12,48(%rsp)		# arg7
        +	mov	%rcx,56(%rsp)		# arg8, (NULL)
        +	call	*__imp_RtlVirtualUnwind(%rip)
        +
        +	mov	\$1,%eax		# ExceptionContinueSearch
        +	add	\$64,%rsp
        +	popfq
        +	pop	%r15
        +	pop	%r14
        +	pop	%r13
        +	pop	%r12
        +	pop	%rbp
        +	pop	%rbx
        +	pop	%rdi
        +	pop	%rsi
        +	ret
        +.size	se_handler,.-se_handler
        +
        +.section	.pdata
        +.align	4
        +	.rva	.LSEH_begin_$func
        +	.rva	.LSEH_end_$func
        +	.rva	.LSEH_info_$func
        +
        +.section	.xdata
        +.align	8
        +.LSEH_info_$func:
        +	.byte	9,0,0,0
        +	.rva	se_handler
        +___
        +}
        +
        +$code =~ s/\`([^\`]*)\`/eval $1/gem;
        +print $code;
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/whrlpool.h b/vendor/openssl/openssl/crypto/whrlpool/whrlpool.h
        new file mode 100644
        index 000000000..9e01f5b07
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/whrlpool.h
        @@ -0,0 +1,41 @@
        +#ifndef HEADER_WHRLPOOL_H
        +#define HEADER_WHRLPOOL_H
        +
        +#include <openssl/e_os2.h>
        +#include <stddef.h>
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +#define WHIRLPOOL_DIGEST_LENGTH	(512/8)
        +#define WHIRLPOOL_BBLOCK	512
        +#define WHIRLPOOL_COUNTER	(256/8)
        +
        +typedef struct	{
        +	union	{
        +		unsigned char	c[WHIRLPOOL_DIGEST_LENGTH];
        +		/* double q is here to ensure 64-bit alignment */
        +		double		q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)];
        +		}	H;
        +	unsigned char	data[WHIRLPOOL_BBLOCK/8];
        +	unsigned int	bitoff;
        +	size_t		bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)];
        +	} WHIRLPOOL_CTX;
        +
        +#ifndef OPENSSL_NO_WHIRLPOOL
        +#ifdef OPENSSL_FIPS
        +int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
        +#endif
        +int WHIRLPOOL_Init	(WHIRLPOOL_CTX *c);
        +int WHIRLPOOL_Update	(WHIRLPOOL_CTX *c,const void *inp,size_t bytes);
        +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits);
        +int WHIRLPOOL_Final	(unsigned char *md,WHIRLPOOL_CTX *c);
        +unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md);
        +#endif
        +
        +#ifdef __cplusplus
        +}
        +#endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/wp_block.c b/vendor/openssl/openssl/crypto/whrlpool/wp_block.c
        new file mode 100644
        index 000000000..824ed1827
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/wp_block.c
        @@ -0,0 +1,655 @@
        +/**
        + * The Whirlpool hashing function.
        + *
        + * <P>
        + * <b>References</b>
        + *
        + * <P>
        + * The Whirlpool algorithm was developed by
        + * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
        + * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
        + *
        + * See
        + *      P.S.L.M. Barreto, V. Rijmen,
        + *      ``The Whirlpool hashing function,''
        + *      NESSIE submission, 2000 (tweaked version, 2001),
        + *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
        + *
        + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
        + * Vincent Rijmen. Lookup "reference implementations" on
        + * <http://planeta.terra.com.br/informatica/paulobarreto/>
        + *
        + * =============================================================================
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
        + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
        + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
        + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + *
        + */
        +
        +#include "wp_locl.h"
        +#include <string.h>
        +
        +typedef unsigned char		u8;
        +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32)
        +typedef unsigned __int64	u64;
        +#elif defined(__arch64__)
        +typedef unsigned long		u64;
        +#else
        +typedef unsigned long long	u64;
        +#endif
        +
        +#define ROUNDS	10
        +
        +#define STRICT_ALIGNMENT
        +#if defined(__i386) || defined(__i386__) || \
        +    defined(__x86_64) || defined(__x86_64__) || \
        +    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)
        +/* Well, formally there're couple of other architectures, which permit
        + * unaligned loads, specifically those not crossing cache lines, IA-64
        + * and PowerPC... */
        +#  undef STRICT_ALIGNMENT
        +#endif
        +
        +#undef SMALL_REGISTER_BANK
        +#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
        +#  define SMALL_REGISTER_BANK
        +#  if defined(WHIRLPOOL_ASM)
        +#    ifndef OPENSSL_SMALL_FOOTPRINT
        +#      define OPENSSL_SMALL_FOOTPRINT	/* it appears that for elder non-MMX
        +					   CPUs this is actually faster! */
        +#    endif
        +#    define GO_FOR_MMX(ctx,inp,num)	do {			\
        +	extern unsigned int OPENSSL_ia32cap_P[];		\
        +	void whirlpool_block_mmx(void *,const void *,size_t);	\
        +	if (!(OPENSSL_ia32cap_P[0] & (1<<23)))	break;		\
        +        whirlpool_block_mmx(ctx->H.c,inp,num);	return;		\
        +					} while (0)
        +#  endif
        +#endif
        +
        +#undef ROTATE
        +#if defined(_MSC_VER)
        +#  if defined(_WIN64)	/* applies to both IA-64 and AMD64 */
        +#    pragma intrinsic(_rotl64)
        +#    define ROTATE(a,n)	_rotl64((a),n)
        +#  endif
        +#elif defined(__GNUC__) && __GNUC__>=2
        +#  if defined(__x86_64) || defined(__x86_64__)
        +#    if defined(L_ENDIAN)
        +#      define ROTATE(a,n)	({ u64 ret; asm ("rolq %1,%0"	\
        +				   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
        +#    elif defined(B_ENDIAN)
        +       /* Most will argue that x86_64 is always little-endian. Well,
        +        * yes, but then we have stratus.com who has modified gcc to
        +	* "emulate" big-endian on x86. Is there evidence that they
        +	* [or somebody else] won't do same for x86_64? Naturally no.
        +	* And this line is waiting ready for that brave soul:-) */
        +#      define ROTATE(a,n)	({ u64 ret; asm ("rorq %1,%0"	\
        +				   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
        +#    endif
        +#  elif defined(__ia64) || defined(__ia64__)
        +#    if defined(L_ENDIAN)
        +#      define ROTATE(a,n)	({ u64 ret; asm ("shrp %0=%1,%1,%2"	\
        +				   : "=r"(ret) : "r"(a),"M"(64-(n))); ret; })
        +#    elif defined(B_ENDIAN)
        +#      define ROTATE(a,n)	({ u64 ret; asm ("shrp %0=%1,%1,%2"	\
        +				   : "=r"(ret) : "r"(a),"M"(n)); ret; })
        +#    endif
        +#  endif
        +#endif
        +
        +#if defined(OPENSSL_SMALL_FOOTPRINT)
        +#  if !defined(ROTATE)
        +#    if defined(L_ENDIAN)	/* little-endians have to rotate left */
        +#      define ROTATE(i,n)	((i)<<(n) ^ (i)>>(64-n))
        +#    elif defined(B_ENDIAN)	/* big-endians have to rotate right */
        +#      define ROTATE(i,n)	((i)>>(n) ^ (i)<<(64-n))
        +#    endif
        +#  endif
        +#  if defined(ROTATE) && !defined(STRICT_ALIGNMENT)
        +#    define STRICT_ALIGNMENT	/* ensure smallest table size */
        +#  endif
        +#endif
        +
        +/*
        + * Table size depends on STRICT_ALIGNMENT and whether or not endian-
        + * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not
        + * defined, which is normally the case on x86[_64] CPUs, the table is
        + * 4KB large unconditionally. Otherwise if ROTATE is defined, the
        + * table is 2KB large, and otherwise - 16KB. 2KB table requires a
        + * whole bunch of additional rotations, but I'm willing to "trade,"
        + * because 16KB table certainly trashes L1 cache. I wish all CPUs
        + * could handle unaligned load as 4KB table doesn't trash the cache,
        + * nor does it require additional rotations.
        + */
        +/*
        + * Note that every Cn macro expands as two loads: one byte load and
        + * one quadword load. One can argue that that many single-byte loads
        + * is too excessive, as one could load a quadword and "milk" it for
        + * eight 8-bit values instead. Well, yes, but in order to do so *and*
        + * avoid excessive loads you have to accomodate a handful of 64-bit
        + * values in the register bank and issue a bunch of shifts and mask.
        + * It's a tradeoff: loads vs. shift and mask in big register bank[!].
        + * On most CPUs eight single-byte loads are faster and I let other
        + * ones to depend on smart compiler to fold byte loads if beneficial.
        + * Hand-coded assembler would be another alternative:-)
        + */
        +#ifdef STRICT_ALIGNMENT
        +#  if defined(ROTATE)
        +#    define N	1
        +#    define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7
        +#    define C0(K,i)	(Cx.q[K.c[(i)*8+0]])
        +#    define C1(K,i)	ROTATE(Cx.q[K.c[(i)*8+1]],8)
        +#    define C2(K,i)	ROTATE(Cx.q[K.c[(i)*8+2]],16)
        +#    define C3(K,i)	ROTATE(Cx.q[K.c[(i)*8+3]],24)
        +#    define C4(K,i)	ROTATE(Cx.q[K.c[(i)*8+4]],32)
        +#    define C5(K,i)	ROTATE(Cx.q[K.c[(i)*8+5]],40)
        +#    define C6(K,i)	ROTATE(Cx.q[K.c[(i)*8+6]],48)
        +#    define C7(K,i)	ROTATE(Cx.q[K.c[(i)*8+7]],56)
        +#  else
        +#    define N	8
        +#    define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7, \
        +					c7,c0,c1,c2,c3,c4,c5,c6, \
        +					c6,c7,c0,c1,c2,c3,c4,c5, \
        +					c5,c6,c7,c0,c1,c2,c3,c4, \
        +					c4,c5,c6,c7,c0,c1,c2,c3, \
        +					c3,c4,c5,c6,c7,c0,c1,c2, \
        +					c2,c3,c4,c5,c6,c7,c0,c1, \
        +					c1,c2,c3,c4,c5,c6,c7,c0
        +#    define C0(K,i)	(Cx.q[0+8*K.c[(i)*8+0]])
        +#    define C1(K,i)	(Cx.q[1+8*K.c[(i)*8+1]])
        +#    define C2(K,i)	(Cx.q[2+8*K.c[(i)*8+2]])
        +#    define C3(K,i)	(Cx.q[3+8*K.c[(i)*8+3]])
        +#    define C4(K,i)	(Cx.q[4+8*K.c[(i)*8+4]])
        +#    define C5(K,i)	(Cx.q[5+8*K.c[(i)*8+5]])
        +#    define C6(K,i)	(Cx.q[6+8*K.c[(i)*8+6]])
        +#    define C7(K,i)	(Cx.q[7+8*K.c[(i)*8+7]])
        +#  endif
        +#else
        +#  define N	2
        +#  define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7, \
        +					c0,c1,c2,c3,c4,c5,c6,c7
        +#  define C0(K,i)	(((u64*)(Cx.c+0))[2*K.c[(i)*8+0]])
        +#  define C1(K,i)	(((u64*)(Cx.c+7))[2*K.c[(i)*8+1]])
        +#  define C2(K,i)	(((u64*)(Cx.c+6))[2*K.c[(i)*8+2]])
        +#  define C3(K,i)	(((u64*)(Cx.c+5))[2*K.c[(i)*8+3]])
        +#  define C4(K,i)	(((u64*)(Cx.c+4))[2*K.c[(i)*8+4]])
        +#  define C5(K,i)	(((u64*)(Cx.c+3))[2*K.c[(i)*8+5]])
        +#  define C6(K,i)	(((u64*)(Cx.c+2))[2*K.c[(i)*8+6]])
        +#  define C7(K,i)	(((u64*)(Cx.c+1))[2*K.c[(i)*8+7]])
        +#endif
        +
        +static const
        +union	{
        +	u8	c[(256*N+ROUNDS)*sizeof(u64)];
        +	u64	q[(256*N+ROUNDS)];
        +	} Cx = { {
        +	/* Note endian-neutral representation:-) */
        +	LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8),
        +	LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26),
        +	LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8),
        +	LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb),
        +	LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb),
        +	LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11),
        +	LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09),
        +	LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d),
        +	LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b),
        +	LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff),
        +	LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c),
        +	LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e),
        +	LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96),
        +	LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30),
        +	LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d),
        +	LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8),
        +	LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47),
        +	LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35),
        +	LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37),
        +	LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a),
        +	LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2),
        +	LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c),
        +	LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84),
        +	LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80),
        +	LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5),
        +	LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3),
        +	LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21),
        +	LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c),
        +	LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43),
        +	LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29),
        +	LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d),
        +	LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5),
        +	LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd),
        +	LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8),
        +	LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92),
        +	LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e),
        +	LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13),
        +	LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23),
        +	LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20),
        +	LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44),
        +	LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2),
        +	LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf),
        +	LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c),
        +	LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a),
        +	LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50),
        +	LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9),
        +	LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14),
        +	LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9),
        +	LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c),
        +	LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f),
        +	LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90),
        +	LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07),
        +	LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd),
        +	LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3),
        +	LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d),
        +	LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78),
        +	LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97),
        +	LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02),
        +	LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73),
        +	LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7),
        +	LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6),
        +	LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2),
        +	LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49),
        +	LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56),
        +	LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70),
        +	LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd),
        +	LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb),
        +	LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71),
        +	LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b),
        +	LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf),
        +	LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45),
        +	LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a),
        +	LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4),
        +	LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58),
        +	LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e),
        +	LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f),
        +	LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac),
        +	LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0),
        +	LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef),
        +	LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6),
        +	LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c),
        +	LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12),
        +	LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93),
        +	LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde),
        +	LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6),
        +	LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1),
        +	LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b),
        +	LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f),
        +	LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31),
        +	LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8),
        +	LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9),
        +	LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc),
        +	LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e),
        +	LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b),
        +	LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf),
        +	LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59),
        +	LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2),
        +	LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77),
        +	LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33),
        +	LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4),
        +	LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27),
        +	LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb),
        +	LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89),
        +	LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32),
        +	LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54),
        +	LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d),
        +	LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64),
        +	LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d),
        +	LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d),
        +	LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f),
        +	LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca),
        +	LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7),
        +	LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d),
        +	LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce),
        +	LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f),
        +	LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f),
        +	LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63),
        +	LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a),
        +	LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc),
        +	LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82),
        +	LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a),
        +	LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48),
        +	LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95),
        +	LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf),
        +	LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d),
        +	LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0),
        +	LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91),
        +	LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8),
        +	LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b),
        +	LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
        +	LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9),
        +	LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e),
        +	LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1),
        +	LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6),
        +	LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28),
        +	LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3),
        +	LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74),
        +	LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe),
        +	LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d),
        +	LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea),
        +	LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57),
        +	LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38),
        +	LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad),
        +	LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4),
        +	LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda),
        +	LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7),
        +	LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb),
        +	LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9),
        +	LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a),
        +	LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03),
        +	LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a),
        +	LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e),
        +	LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60),
        +	LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc),
        +	LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46),
        +	LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f),
        +	LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76),
        +	LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa),
        +	LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36),
        +	LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae),
        +	LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b),
        +	LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85),
        +	LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e),
        +	LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7),
        +	LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55),
        +	LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a),
        +	LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81),
        +	LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52),
        +	LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62),
        +	LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3),
        +	LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10),
        +	LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab),
        +	LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0),
        +	LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5),
        +	LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec),
        +	LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16),
        +	LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94),
        +	LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f),
        +	LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5),
        +	LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98),
        +	LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17),
        +	LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4),
        +	LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1),
        +	LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e),
        +	LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42),
        +	LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34),
        +	LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08),
        +	LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee),
        +	LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61),
        +	LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1),
        +	LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f),
        +	LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24),
        +	LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3),
        +	LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25),
        +	LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22),
        +	LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65),
        +	LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79),
        +	LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69),
        +	LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9),
        +	LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19),
        +	LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe),
        +	LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a),
        +	LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0),
        +	LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99),
        +	LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83),
        +	LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04),
        +	LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66),
        +	LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0),
        +	LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1),
        +	LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd),
        +	LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40),
        +	LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c),
        +	LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18),
        +	LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b),
        +	LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51),
        +	LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05),
        +	LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c),
        +	LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39),
        +	LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa),
        +	LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b),
        +	LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc),
        +	LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e),
        +	LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0),
        +	LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88),
        +	LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67),
        +	LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a),
        +	LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87),
        +	LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1),
        +	LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72),
        +	LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53),
        +	LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01),
        +	LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b),
        +	LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4),
        +	LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3),
        +	LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15),
        +	LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c),
        +	LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5),
        +	LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5),
        +	LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4),
        +	LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba),
        +	LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6),
        +	LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7),
        +	LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06),
        +	LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41),
        +	LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7),
        +	LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f),
        +	LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e),
        +	LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6),
        +	LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2),
        +	LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68),
        +	LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c),
        +	LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed),
        +	LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75),
        +	LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86),
        +	LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b),
        +	LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2),
        +#define RC	(&(Cx.q[256*N]))
        +	0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f,	/* rc[ROUNDS] */
        +	0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52,
        +	0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35,
        +	0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57,
        +	0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda,
        +	0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85,
        +	0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67,
        +	0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8,
        +	0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e,
        +	0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33
        +	}
        +};
        +
        +void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n)
        +	{
        +	int	r;
        +	const u8 *p=inp;
        +	union	{ u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q;
        +
        +#ifdef GO_FOR_MMX
        +	GO_FOR_MMX(ctx,inp,n);
        +#endif
        +							do {
        +#ifdef OPENSSL_SMALL_FOOTPRINT
        +	u64	L[8];
        +	int	i;
        +
        +	for (i=0;i<64;i++)	S.c[i] = (K.c[i] = H->c[i]) ^ p[i];
        +	for (r=0;r<ROUNDS;r++)
        +		{
        +		for (i=0;i<8;i++)
        +			{
        +			L[i]  = i ? 0 : RC[r];
        +			L[i] ^=	C0(K,i)       ^ C1(K,(i-1)&7) ^
        +				C2(K,(i-2)&7) ^ C3(K,(i-3)&7) ^
        +				C4(K,(i-4)&7) ^ C5(K,(i-5)&7) ^
        +				C6(K,(i-6)&7) ^ C7(K,(i-7)&7);
        +			}
        +		memcpy (K.q,L,64);
        +		for (i=0;i<8;i++)
        +			{
        +			L[i] ^= C0(S,i)       ^ C1(S,(i-1)&7) ^
        +				C2(S,(i-2)&7) ^ C3(S,(i-3)&7) ^
        +				C4(S,(i-4)&7) ^ C5(S,(i-5)&7) ^
        +				C6(S,(i-6)&7) ^ C7(S,(i-7)&7);
        +			}
        +		memcpy (S.q,L,64);
        +		}
        +	for (i=0;i<64;i++)	H->c[i] ^= S.c[i] ^ p[i];
        +#else
        +	u64	L0,L1,L2,L3,L4,L5,L6,L7;
        +
        +#ifdef STRICT_ALIGNMENT
        +	if ((size_t)p & 7)
        +		{
        +		memcpy (S.c,p,64);
        +		S.q[0] ^= (K.q[0] = H->q[0]);
        +		S.q[1] ^= (K.q[1] = H->q[1]);
        +		S.q[2] ^= (K.q[2] = H->q[2]);
        +		S.q[3] ^= (K.q[3] = H->q[3]);
        +		S.q[4] ^= (K.q[4] = H->q[4]);
        +		S.q[5] ^= (K.q[5] = H->q[5]);
        +		S.q[6] ^= (K.q[6] = H->q[6]);
        +		S.q[7] ^= (K.q[7] = H->q[7]);
        +		}
        +	else
        +#endif
        +		{
        +		const u64 *pa = (const u64*)p;
        +		S.q[0] = (K.q[0] = H->q[0]) ^ pa[0];
        +		S.q[1] = (K.q[1] = H->q[1]) ^ pa[1];
        +		S.q[2] = (K.q[2] = H->q[2]) ^ pa[2];
        +		S.q[3] = (K.q[3] = H->q[3]) ^ pa[3];
        +		S.q[4] = (K.q[4] = H->q[4]) ^ pa[4];
        +		S.q[5] = (K.q[5] = H->q[5]) ^ pa[5];
        +		S.q[6] = (K.q[6] = H->q[6]) ^ pa[6];
        +		S.q[7] = (K.q[7] = H->q[7]) ^ pa[7];
        +		}
        +
        +	for(r=0;r<ROUNDS;r++)
        +		{
        +#ifdef SMALL_REGISTER_BANK
        +		L0 =	C0(K,0) ^ C1(K,7) ^ C2(K,6) ^ C3(K,5) ^
        +			C4(K,4) ^ C5(K,3) ^ C6(K,2) ^ C7(K,1) ^ RC[r];
        +		L1 =	C0(K,1) ^ C1(K,0) ^ C2(K,7) ^ C3(K,6) ^
        +			C4(K,5) ^ C5(K,4) ^ C6(K,3) ^ C7(K,2);
        +		L2 =	C0(K,2) ^ C1(K,1) ^ C2(K,0) ^ C3(K,7) ^
        +			C4(K,6) ^ C5(K,5) ^ C6(K,4) ^ C7(K,3);
        +		L3 =	C0(K,3) ^ C1(K,2) ^ C2(K,1) ^ C3(K,0) ^
        +			C4(K,7) ^ C5(K,6) ^ C6(K,5) ^ C7(K,4);
        +		L4 =	C0(K,4) ^ C1(K,3) ^ C2(K,2) ^ C3(K,1) ^
        +			C4(K,0) ^ C5(K,7) ^ C6(K,6) ^ C7(K,5);
        +		L5 =	C0(K,5) ^ C1(K,4) ^ C2(K,3) ^ C3(K,2) ^
        +			C4(K,1) ^ C5(K,0) ^ C6(K,7) ^ C7(K,6);
        +		L6 =	C0(K,6) ^ C1(K,5) ^ C2(K,4) ^ C3(K,3) ^
        +			C4(K,2) ^ C5(K,1) ^ C6(K,0) ^ C7(K,7);
        +		L7 =	C0(K,7) ^ C1(K,6) ^ C2(K,5) ^ C3(K,4) ^
        +			C4(K,3) ^ C5(K,2) ^ C6(K,1) ^ C7(K,0);
        +
        +		K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
        +		K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;
        +
        +		L0 ^=	C0(S,0) ^ C1(S,7) ^ C2(S,6) ^ C3(S,5) ^
        +			C4(S,4) ^ C5(S,3) ^ C6(S,2) ^ C7(S,1);
        +		L1 ^=	C0(S,1) ^ C1(S,0) ^ C2(S,7) ^ C3(S,6) ^
        +			C4(S,5) ^ C5(S,4) ^ C6(S,3) ^ C7(S,2);
        +		L2 ^=	C0(S,2) ^ C1(S,1) ^ C2(S,0) ^ C3(S,7) ^
        +			C4(S,6) ^ C5(S,5) ^ C6(S,4) ^ C7(S,3);
        +		L3 ^=	C0(S,3) ^ C1(S,2) ^ C2(S,1) ^ C3(S,0) ^
        +			C4(S,7) ^ C5(S,6) ^ C6(S,5) ^ C7(S,4);
        +		L4 ^=	C0(S,4) ^ C1(S,3) ^ C2(S,2) ^ C3(S,1) ^
        +			C4(S,0) ^ C5(S,7) ^ C6(S,6) ^ C7(S,5);
        +		L5 ^=	C0(S,5) ^ C1(S,4) ^ C2(S,3) ^ C3(S,2) ^
        +			C4(S,1) ^ C5(S,0) ^ C6(S,7) ^ C7(S,6);
        +		L6 ^=	C0(S,6) ^ C1(S,5) ^ C2(S,4) ^ C3(S,3) ^
        +			C4(S,2) ^ C5(S,1) ^ C6(S,0) ^ C7(S,7);
        +		L7 ^=	C0(S,7) ^ C1(S,6) ^ C2(S,5) ^ C3(S,4) ^
        +			C4(S,3) ^ C5(S,2) ^ C6(S,1) ^ C7(S,0);
        +
        +		S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
        +		S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
        +#else
        +		L0  = C0(K,0); L1  = C1(K,0); L2  = C2(K,0); L3  = C3(K,0);
        +		L4  = C4(K,0); L5  = C5(K,0); L6  = C6(K,0); L7  = C7(K,0);
        +		L0 ^= RC[r];
        +
        +		L1 ^= C0(K,1); L2 ^= C1(K,1); L3 ^= C2(K,1); L4 ^= C3(K,1);
        +		L5 ^= C4(K,1); L6 ^= C5(K,1); L7 ^= C6(K,1); L0 ^= C7(K,1);
        +
        +		L2 ^= C0(K,2); L3 ^= C1(K,2); L4 ^= C2(K,2); L5 ^= C3(K,2);
        +		L6 ^= C4(K,2); L7 ^= C5(K,2); L0 ^= C6(K,2); L1 ^= C7(K,2);
        +
        +		L3 ^= C0(K,3); L4 ^= C1(K,3); L5 ^= C2(K,3); L6 ^= C3(K,3);
        +		L7 ^= C4(K,3); L0 ^= C5(K,3); L1 ^= C6(K,3); L2 ^= C7(K,3);
        +
        +		L4 ^= C0(K,4); L5 ^= C1(K,4); L6 ^= C2(K,4); L7 ^= C3(K,4);
        +		L0 ^= C4(K,4); L1 ^= C5(K,4); L2 ^= C6(K,4); L3 ^= C7(K,4);
        +
        +		L5 ^= C0(K,5); L6 ^= C1(K,5); L7 ^= C2(K,5); L0 ^= C3(K,5);
        +		L1 ^= C4(K,5); L2 ^= C5(K,5); L3 ^= C6(K,5); L4 ^= C7(K,5);
        +
        +		L6 ^= C0(K,6); L7 ^= C1(K,6); L0 ^= C2(K,6); L1 ^= C3(K,6);
        +		L2 ^= C4(K,6); L3 ^= C5(K,6); L4 ^= C6(K,6); L5 ^= C7(K,6);
        +
        +		L7 ^= C0(K,7); L0 ^= C1(K,7); L1 ^= C2(K,7); L2 ^= C3(K,7);
        +		L3 ^= C4(K,7); L4 ^= C5(K,7); L5 ^= C6(K,7); L6 ^= C7(K,7);
        +
        +		K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
        +		K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;
        +
        +		L0 ^= C0(S,0); L1 ^= C1(S,0); L2 ^= C2(S,0); L3 ^= C3(S,0);
        +		L4 ^= C4(S,0); L5 ^= C5(S,0); L6 ^= C6(S,0); L7 ^= C7(S,0);
        +
        +		L1 ^= C0(S,1); L2 ^= C1(S,1); L3 ^= C2(S,1); L4 ^= C3(S,1);
        +		L5 ^= C4(S,1); L6 ^= C5(S,1); L7 ^= C6(S,1); L0 ^= C7(S,1);
        +
        +		L2 ^= C0(S,2); L3 ^= C1(S,2); L4 ^= C2(S,2); L5 ^= C3(S,2);
        +		L6 ^= C4(S,2); L7 ^= C5(S,2); L0 ^= C6(S,2); L1 ^= C7(S,2);
        +
        +		L3 ^= C0(S,3); L4 ^= C1(S,3); L5 ^= C2(S,3); L6 ^= C3(S,3);
        +		L7 ^= C4(S,3); L0 ^= C5(S,3); L1 ^= C6(S,3); L2 ^= C7(S,3);
        +
        +		L4 ^= C0(S,4); L5 ^= C1(S,4); L6 ^= C2(S,4); L7 ^= C3(S,4);
        +		L0 ^= C4(S,4); L1 ^= C5(S,4); L2 ^= C6(S,4); L3 ^= C7(S,4);
        +
        +		L5 ^= C0(S,5); L6 ^= C1(S,5); L7 ^= C2(S,5); L0 ^= C3(S,5);
        +		L1 ^= C4(S,5); L2 ^= C5(S,5); L3 ^= C6(S,5); L4 ^= C7(S,5);
        +
        +		L6 ^= C0(S,6); L7 ^= C1(S,6); L0 ^= C2(S,6); L1 ^= C3(S,6);
        +		L2 ^= C4(S,6); L3 ^= C5(S,6); L4 ^= C6(S,6); L5 ^= C7(S,6);
        +
        +		L7 ^= C0(S,7); L0 ^= C1(S,7); L1 ^= C2(S,7); L2 ^= C3(S,7);
        +		L3 ^= C4(S,7); L4 ^= C5(S,7); L5 ^= C6(S,7); L6 ^= C7(S,7);
        +
        +		S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
        +		S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
        +#endif
        +		}
        +
        +#ifdef STRICT_ALIGNMENT
        +	if ((size_t)p & 7)
        +		{
        +		int i;
        +		for(i=0;i<64;i++)	H->c[i] ^= S.c[i] ^ p[i];
        +		}
        +	else
        +#endif
        +		{
        +		const u64 *pa=(const u64 *)p;
        +		H->q[0] ^= S.q[0] ^ pa[0];
        +		H->q[1] ^= S.q[1] ^ pa[1];
        +		H->q[2] ^= S.q[2] ^ pa[2];
        +		H->q[3] ^= S.q[3] ^ pa[3];
        +		H->q[4] ^= S.q[4] ^ pa[4];
        +		H->q[5] ^= S.q[5] ^ pa[5];
        +		H->q[6] ^= S.q[6] ^ pa[6];
        +		H->q[7] ^= S.q[7] ^ pa[7];
        +		}
        +#endif
        +							p += 64;
        +							} while(--n);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/wp_dgst.c b/vendor/openssl/openssl/crypto/whrlpool/wp_dgst.c
        new file mode 100644
        index 000000000..7e28bef51
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/wp_dgst.c
        @@ -0,0 +1,265 @@
        +/**
        + * The Whirlpool hashing function.
        + *
        + * <P>
        + * <b>References</b>
        + *
        + * <P>
        + * The Whirlpool algorithm was developed by
        + * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
        + * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
        + *
        + * See
        + *      P.S.L.M. Barreto, V. Rijmen,
        + *      ``The Whirlpool hashing function,''
        + *      NESSIE submission, 2000 (tweaked version, 2001),
        + *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
        + *
        + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
        + * Vincent Rijmen. Lookup "reference implementations" on
        + * <http://planeta.terra.com.br/informatica/paulobarreto/>
        + *
        + * =============================================================================
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
        + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
        + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
        + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        + *
        + */
        +
        +/*
        + * OpenSSL-specific implementation notes.
        + *
        + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
        + * number of *bytes* as input length argument. Bit-oriented routine
        + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
        + * does not have one-stroke counterpart.
        + *
        + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
        + * to serve WHIRLPOOL_Update. This is done for performance.
        + *
        + * Unlike authors' reference implementation, block processing
        + * routine whirlpool_block is designed to operate on multi-block
        + * input. This is done for perfomance.
        + */
        +
        +#include "wp_locl.h"
        +#include <openssl/crypto.h>
        +#include <string.h>
        +
        +fips_md_init(WHIRLPOOL)
        +	{
        +	memset (c,0,sizeof(*c));
        +	return(1);
        +	}
        +
        +int WHIRLPOOL_Update	(WHIRLPOOL_CTX *c,const void *_inp,size_t bytes)
        +	{
        +	/* Well, largest suitable chunk size actually is
        +	 * (1<<(sizeof(size_t)*8-3))-64, but below number
        +	 * is large enough for not to care about excessive
        +	 * calls to WHIRLPOOL_BitUpdate... */
        +	size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4);
        +	const unsigned char *inp = _inp;
        +
        +	while (bytes>=chunk)
        +		{
        +		WHIRLPOOL_BitUpdate(c,inp,chunk*8);
        +		bytes -= chunk;
        +		inp   += chunk;
        +		}
        +	if (bytes)
        +		WHIRLPOOL_BitUpdate(c,inp,bytes*8);
        +
        +	return(1);
        +	}
        +
        +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits)
        +	{
        +	size_t		n;
        +	unsigned int	bitoff = c->bitoff,
        +			bitrem = bitoff%8,
        +			inpgap = (8-(unsigned int)bits%8)&7;
        +	const unsigned char *inp=_inp;
        +
        +	/* This 256-bit increment procedure relies on the size_t
        +	 * being natural size of CPU register, so that we don't
        +	 * have to mask the value in order to detect overflows. */
        +	c->bitlen[0] += bits;
        +	if (c->bitlen[0] < bits)	/* overflow */
        +		{
        +		n = 1;
        +		do  { 	c->bitlen[n]++;
        +		    } while(c->bitlen[n]==0
        +		   	    && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t)));
        +		}
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +	reconsider:
        +	if (inpgap==0 && bitrem==0)	/* byte-oriented loop */
        +		{
        +		while (bits)
        +			{
        +			if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK))
        +				{
        +				whirlpool_block(c,inp,n);
        +				inp  += n*WHIRLPOOL_BBLOCK/8;
        +				bits %= WHIRLPOOL_BBLOCK;
        +				}
        +			else
        +				{
        +				unsigned int byteoff = bitoff/8;
        +
        +				bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */
        +				if (bits >= bitrem)
        +					{
        +					bits -= bitrem;
        +					bitrem /= 8;
        +					memcpy(c->data+byteoff,inp,bitrem);
        +					inp  += bitrem;
        +					whirlpool_block(c,c->data,1);
        +					bitoff = 0;
        +					}
        +				else
        +					{
        +					memcpy(c->data+byteoff,inp,bits/8);
        +					bitoff += (unsigned int)bits;
        +					bits = 0;
        +					}
        +				c->bitoff = bitoff;
        +				}
        +			}
        +		}
        +	else				/* bit-oriented loop */
        +#endif
        +		{
        +		/*
        +			   inp
        +			   |
        +			   +-------+-------+-------
        +			      |||||||||||||||||||||
        +			   +-------+-------+-------
        +		+-------+-------+-------+-------+-------
        +		||||||||||||||				c->data
        +		+-------+-------+-------+-------+-------
        +			|
        +			c->bitoff/8
        +		*/
        +		while (bits)
        +			{
        +			unsigned int	byteoff	= bitoff/8;
        +			unsigned char	b;
        +
        +#ifndef OPENSSL_SMALL_FOOTPRINT
        +			if (bitrem==inpgap)
        +				{
        +				c->data[byteoff++] |= inp[0] & (0xff>>inpgap);
        +				inpgap = 8-inpgap;
        +				bitoff += inpgap;  bitrem = 0;	/* bitoff%8 */
        +				bits   -= inpgap;  inpgap = 0;	/* bits%8   */
        +				inp++;
        +				if (bitoff==WHIRLPOOL_BBLOCK)
        +					{
        +					whirlpool_block(c,c->data,1);
        +					bitoff = 0;
        +					}
        +				c->bitoff = bitoff;
        +				goto reconsider;
        +				}
        +			else
        +#endif
        +			if (bits>=8)
        +				{
        +				b  = ((inp[0]<<inpgap) | (inp[1]>>(8-inpgap)));
        +				b &= 0xff;
        +				if (bitrem)	c->data[byteoff++] |= b>>bitrem;
        +				else		c->data[byteoff++]  = b;
        +				bitoff += 8;
        +				bits   -= 8;
        +				inp++;
        +				if (bitoff>=WHIRLPOOL_BBLOCK)
        +					{
        +					whirlpool_block(c,c->data,1);
        +					byteoff  = 0;
        +					bitoff  %= WHIRLPOOL_BBLOCK;
        +					}
        +				if (bitrem)	c->data[byteoff] = b<<(8-bitrem);
        +				}
        +			else	/* remaining less than 8 bits */
        +				{
        +				b = (inp[0]<<inpgap)&0xff;
        +				if (bitrem)	c->data[byteoff++] |= b>>bitrem;
        +				else		c->data[byteoff++]  = b;
        +				bitoff += (unsigned int)bits;
        +				if (bitoff==WHIRLPOOL_BBLOCK)
        +					{
        +					whirlpool_block(c,c->data,1);
        +					byteoff  = 0;
        +			        	bitoff  %= WHIRLPOOL_BBLOCK;
        +					}
        +				if (bitrem)	c->data[byteoff] = b<<(8-bitrem);
        +				bits = 0;
        +				}
        +			c->bitoff = bitoff;
        +			}
        +		}
        +	}
        +
        +int WHIRLPOOL_Final	(unsigned char *md,WHIRLPOOL_CTX *c)
        +	{
        +	unsigned int	bitoff  = c->bitoff,
        +			byteoff = bitoff/8;
        +	size_t		i,j,v;
        +	unsigned char  *p;
        +
        +	bitoff %= 8;
        +	if (bitoff)	c->data[byteoff] |= 0x80>>bitoff;
        +	else		c->data[byteoff]  = 0x80;
        +	byteoff++;
        +
        +	/* pad with zeros */
        +	if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
        +		{
        +		if (byteoff<WHIRLPOOL_BBLOCK/8)
        +			memset(&c->data[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff);
        +		whirlpool_block(c,c->data,1);
        +		byteoff = 0;
        +		}
        +	if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
        +		memset(&c->data[byteoff],0,
        +			(WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff);
        +	/* smash 256-bit c->bitlen in big-endian order */
        +	p = &c->data[WHIRLPOOL_BBLOCK/8-1];	/* last byte in c->data */
        +	for(i=0;i<WHIRLPOOL_COUNTER/sizeof(size_t);i++)
        +		for(v=c->bitlen[i],j=0;j<sizeof(size_t);j++,v>>=8)
        +			*p-- = (unsigned char)(v&0xff);
        +
        +	whirlpool_block(c,c->data,1);
        +
        +	if (md)	{
        +		memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH);
        +		memset(c,0,sizeof(*c));
        +		return(1);
        +		}
        +	return(0);
        +	}
        +
        +unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md)
        +	{
        +	WHIRLPOOL_CTX ctx;
        +	static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
        +
        +	if (md == NULL) md=m;
        +	WHIRLPOOL_Init(&ctx);
        +	WHIRLPOOL_Update(&ctx,inp,bytes);
        +	WHIRLPOOL_Final(md,&ctx);
        +	return(md);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/wp_locl.h b/vendor/openssl/openssl/crypto/whrlpool/wp_locl.h
        new file mode 100644
        index 000000000..94e56a39f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/wp_locl.h
        @@ -0,0 +1,3 @@
        +#include <openssl/whrlpool.h>
        +
        +void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t);
        diff --git a/vendor/openssl/openssl/crypto/whrlpool/wp_test.c b/vendor/openssl/openssl/crypto/whrlpool/wp_test.c
        new file mode 100644
        index 000000000..c68c2c62c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/whrlpool/wp_test.c
        @@ -0,0 +1,228 @@
        +/* ====================================================================
        + * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
        + * ====================================================================
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include <openssl/whrlpool.h>
        +#include <openssl/crypto.h>
        +
        +#if defined(OPENSSL_NO_WHIRLPOOL)
        +int main(int argc, char *argv[])
        +{
        +    printf("No Whirlpool support\n");
        +    return(0);
        +}
        +#else
        +
        +/* ISO/IEC 10118-3 test vector set */
        +unsigned char iso_test_1[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x19,0xFA,0x61,0xD7,0x55,0x22,0xA4,0x66,
        +	0x9B,0x44,0xE3,0x9C,0x1D,0x2E,0x17,0x26,
        +	0xC5,0x30,0x23,0x21,0x30,0xD4,0x07,0xF8,
        +	0x9A,0xFE,0xE0,0x96,0x49,0x97,0xF7,0xA7,
        +	0x3E,0x83,0xBE,0x69,0x8B,0x28,0x8F,0xEB,
        +	0xCF,0x88,0xE3,0xE0,0x3C,0x4F,0x07,0x57,
        +	0xEA,0x89,0x64,0xE5,0x9B,0x63,0xD9,0x37,
        +	0x08,0xB1,0x38,0xCC,0x42,0xA6,0x6E,0xB3 };
        +
        +unsigned char iso_test_2[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x8A,0xCA,0x26,0x02,0x79,0x2A,0xEC,0x6F,
        +	0x11,0xA6,0x72,0x06,0x53,0x1F,0xB7,0xD7,
        +	0xF0,0xDF,0xF5,0x94,0x13,0x14,0x5E,0x69,
        +	0x73,0xC4,0x50,0x01,0xD0,0x08,0x7B,0x42,
        +	0xD1,0x1B,0xC6,0x45,0x41,0x3A,0xEF,0xF6,
        +	0x3A,0x42,0x39,0x1A,0x39,0x14,0x5A,0x59,
        +	0x1A,0x92,0x20,0x0D,0x56,0x01,0x95,0xE5,
        +	0x3B,0x47,0x85,0x84,0xFD,0xAE,0x23,0x1A };
        +
        +unsigned char iso_test_3[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x4E,0x24,0x48,0xA4,0xC6,0xF4,0x86,0xBB,
        +	0x16,0xB6,0x56,0x2C,0x73,0xB4,0x02,0x0B,
        +	0xF3,0x04,0x3E,0x3A,0x73,0x1B,0xCE,0x72,
        +	0x1A,0xE1,0xB3,0x03,0xD9,0x7E,0x6D,0x4C,
        +	0x71,0x81,0xEE,0xBD,0xB6,0xC5,0x7E,0x27,
        +	0x7D,0x0E,0x34,0x95,0x71,0x14,0xCB,0xD6,
        +	0xC7,0x97,0xFC,0x9D,0x95,0xD8,0xB5,0x82,
        +	0xD2,0x25,0x29,0x20,0x76,0xD4,0xEE,0xF5 };
        +
        +unsigned char iso_test_4[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x37,0x8C,0x84,0xA4,0x12,0x6E,0x2D,0xC6,
        +	0xE5,0x6D,0xCC,0x74,0x58,0x37,0x7A,0xAC,
        +	0x83,0x8D,0x00,0x03,0x22,0x30,0xF5,0x3C,
        +	0xE1,0xF5,0x70,0x0C,0x0F,0xFB,0x4D,0x3B,
        +	0x84,0x21,0x55,0x76,0x59,0xEF,0x55,0xC1,
        +	0x06,0xB4,0xB5,0x2A,0xC5,0xA4,0xAA,0xA6,
        +	0x92,0xED,0x92,0x00,0x52,0x83,0x8F,0x33,
        +	0x62,0xE8,0x6D,0xBD,0x37,0xA8,0x90,0x3E };
        +
        +unsigned char iso_test_5[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0xF1,0xD7,0x54,0x66,0x26,0x36,0xFF,0xE9,
        +	0x2C,0x82,0xEB,0xB9,0x21,0x2A,0x48,0x4A,
        +	0x8D,0x38,0x63,0x1E,0xAD,0x42,0x38,0xF5,
        +	0x44,0x2E,0xE1,0x3B,0x80,0x54,0xE4,0x1B,
        +	0x08,0xBF,0x2A,0x92,0x51,0xC3,0x0B,0x6A,
        +	0x0B,0x8A,0xAE,0x86,0x17,0x7A,0xB4,0xA6,
        +	0xF6,0x8F,0x67,0x3E,0x72,0x07,0x86,0x5D,
        +	0x5D,0x98,0x19,0xA3,0xDB,0xA4,0xEB,0x3B };
        +
        +unsigned char iso_test_6[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0xDC,0x37,0xE0,0x08,0xCF,0x9E,0xE6,0x9B,
        +	0xF1,0x1F,0x00,0xED,0x9A,0xBA,0x26,0x90,
        +	0x1D,0xD7,0xC2,0x8C,0xDE,0xC0,0x66,0xCC,
        +	0x6A,0xF4,0x2E,0x40,0xF8,0x2F,0x3A,0x1E,
        +	0x08,0xEB,0xA2,0x66,0x29,0x12,0x9D,0x8F,
        +	0xB7,0xCB,0x57,0x21,0x1B,0x92,0x81,0xA6,
        +	0x55,0x17,0xCC,0x87,0x9D,0x7B,0x96,0x21,
        +	0x42,0xC6,0x5F,0x5A,0x7A,0xF0,0x14,0x67 };
        +
        +unsigned char iso_test_7[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x46,0x6E,0xF1,0x8B,0xAB,0xB0,0x15,0x4D,
        +	0x25,0xB9,0xD3,0x8A,0x64,0x14,0xF5,0xC0,
        +	0x87,0x84,0x37,0x2B,0xCC,0xB2,0x04,0xD6,
        +	0x54,0x9C,0x4A,0xFA,0xDB,0x60,0x14,0x29,
        +	0x4D,0x5B,0xD8,0xDF,0x2A,0x6C,0x44,0xE5,
        +	0x38,0xCD,0x04,0x7B,0x26,0x81,0xA5,0x1A,
        +	0x2C,0x60,0x48,0x1E,0x88,0xC5,0xA2,0x0B,
        +	0x2C,0x2A,0x80,0xCF,0x3A,0x9A,0x08,0x3B };
        +
        +unsigned char iso_test_8[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x2A,0x98,0x7E,0xA4,0x0F,0x91,0x70,0x61,
        +	0xF5,0xD6,0xF0,0xA0,0xE4,0x64,0x4F,0x48,
        +	0x8A,0x7A,0x5A,0x52,0xDE,0xEE,0x65,0x62,
        +	0x07,0xC5,0x62,0xF9,0x88,0xE9,0x5C,0x69,
        +	0x16,0xBD,0xC8,0x03,0x1B,0xC5,0xBE,0x1B,
        +	0x7B,0x94,0x76,0x39,0xFE,0x05,0x0B,0x56,
        +	0x93,0x9B,0xAA,0xA0,0xAD,0xFF,0x9A,0xE6,
        +	0x74,0x5B,0x7B,0x18,0x1C,0x3B,0xE3,0xFD };
        +
        +unsigned char iso_test_9[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x0C,0x99,0x00,0x5B,0xEB,0x57,0xEF,0xF5,
        +	0x0A,0x7C,0xF0,0x05,0x56,0x0D,0xDF,0x5D,
        +	0x29,0x05,0x7F,0xD8,0x6B,0x20,0xBF,0xD6,
        +	0x2D,0xEC,0xA0,0xF1,0xCC,0xEA,0x4A,0xF5,
        +	0x1F,0xC1,0x54,0x90,0xED,0xDC,0x47,0xAF,
        +	0x32,0xBB,0x2B,0x66,0xC3,0x4F,0xF9,0xAD,
        +	0x8C,0x60,0x08,0xAD,0x67,0x7F,0x77,0x12,
        +	0x69,0x53,0xB2,0x26,0xE4,0xED,0x8B,0x01 };
        +
        +int main (int argc,char *argv[])
        +{ unsigned char md[WHIRLPOOL_DIGEST_LENGTH];
        +  int		i;
        +  WHIRLPOOL_CTX	ctx;
        +
        +#ifdef OPENSSL_IA32_SSE2
        +    /* Alternative to this is to call OpenSSL_add_all_algorithms...
        +     * The below code is retained exclusively for debugging purposes. */
        +    { char      *env;
        +
        +	if ((env=getenv("OPENSSL_ia32cap")))
        +	    OPENSSL_ia32cap = strtoul (env,NULL,0);
        +    }
        +#endif
        +
        +    fprintf(stdout,"Testing Whirlpool ");
        +
        +    WHIRLPOOL("",0,md);
        +    if (memcmp(md,iso_test_1,sizeof(iso_test_1)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("a",1,md);
        +    if (memcmp(md,iso_test_2,sizeof(iso_test_2)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("abc",3,md);
        +    if (memcmp(md,iso_test_3,sizeof(iso_test_3)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("message digest",14,md);
        +    if (memcmp(md,iso_test_4,sizeof(iso_test_4)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 4 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("abcdefghijklmnopqrstuvwxyz",26,md);
        +    if (memcmp(md,iso_test_5,sizeof(iso_test_5)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 5 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL(	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        +		"abcdefghijklmnopqrstuvwxyz"
        +		"0123456789",62,md);
        +    if (memcmp(md,iso_test_6,sizeof(iso_test_6)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 6 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL(	"1234567890""1234567890""1234567890""1234567890"
        +		"1234567890""1234567890""1234567890""1234567890",80,md);
        +    if (memcmp(md,iso_test_7,sizeof(iso_test_7)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 7 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("abcdbcdecdefdefgefghfghighijhijk",32,md);
        +    if (memcmp(md,iso_test_8,sizeof(iso_test_8)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 8 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        + 
        +    WHIRLPOOL_Init (&ctx);
        +    for (i=0;i<1000000;i+=288)
        +	WHIRLPOOL_Update (&ctx,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<288?1000000-i:288);
        +    WHIRLPOOL_Final (md,&ctx);
        +    if (memcmp(md,iso_test_9,sizeof(iso_test_9)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 9 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +  return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/x509/Makefile b/vendor/openssl/openssl/crypto/x509/Makefile
        new file mode 100644
        index 000000000..72c82278f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/Makefile
        @@ -0,0 +1,407 @@
        +#
        +# OpenSSL/crypto/x509/Makefile
        +#
        +
        +DIR=	x509
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
        +	x509_obj.c x509_req.c x509spki.c x509_vfy.c \
        +	x509_set.c x509cset.c x509rset.c x509_err.c \
        +	x509name.c x509_v3.c x509_ext.c x509_att.c \
        +	x509type.c x509_lu.c x_all.c x509_txt.c \
        +	x509_trs.c by_file.c by_dir.c x509_vpm.c
        +LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
        +	x509_obj.o x509_req.o x509spki.o x509_vfy.o \
        +	x509_set.o x509cset.o x509rset.o x509_err.o \
        +	x509name.o x509_v3.o x509_ext.o x509_att.o \
        +	x509type.o x509_lu.o x_all.o x509_txt.o \
        +	x509_trs.o by_file.o by_dir.o x509_vpm.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= x509.h x509_vfy.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) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +by_dir.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +by_dir.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +by_dir.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +by_dir.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +by_dir.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +by_dir.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +by_dir.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +by_dir.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +by_dir.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +by_dir.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +by_dir.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +by_dir.o: ../../include/openssl/x509_vfy.h ../cryptlib.h by_dir.c
        +by_file.o: ../../e_os.h ../../include/openssl/asn1.h
        +by_file.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +by_file.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +by_file.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +by_file.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +by_file.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +by_file.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +by_file.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +by_file.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
        +by_file.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
        +by_file.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +by_file.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +by_file.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +by_file.o: ../cryptlib.h by_file.c
        +x509_att.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_att.o: ../cryptlib.h x509_att.c
        +x509_cmp.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_cmp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_cmp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_cmp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_cmp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_cmp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_cmp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_cmp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_cmp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_cmp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_cmp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_cmp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_cmp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_cmp.o: ../cryptlib.h x509_cmp.c
        +x509_d2.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_d2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_d2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509_d2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509_d2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509_d2.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509_d2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509_d2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +x509_d2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +x509_d2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +x509_d2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +x509_d2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +x509_d2.o: ../cryptlib.h x509_d2.c
        +x509_def.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_def.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_def.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509_def.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509_def.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509_def.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509_def.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509_def.o: ../../include/openssl/opensslconf.h
        +x509_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_def.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_def.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_def.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_def.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_def.c
        +x509_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +x509_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x509_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_err.o: ../../include/openssl/x509_vfy.h x509_err.c
        +x509_ext.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_ext.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_ext.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_ext.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_ext.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_ext.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_ext.o: ../cryptlib.h x509_ext.c
        +x509_lu.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_lu.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_lu.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_lu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_lu.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_lu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_lu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_lu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_lu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_lu.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_lu.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_lu.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_lu.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_lu.o: ../cryptlib.h x509_lu.c
        +x509_obj.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_obj.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_obj.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509_obj.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509_obj.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509_obj.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509_obj.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509_obj.o: ../../include/openssl/opensslconf.h
        +x509_obj.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_obj.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_obj.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_obj.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_obj.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_obj.c
        +x509_r2x.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_r2x.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +x509_r2x.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x509_r2x.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_r2x.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_r2x.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_r2x.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_r2x.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_r2x.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_r2x.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_r2x.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_r2x.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_r2x.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_r2x.c
        +x509_req.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_req.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +x509_req.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +x509_req.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509_req.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509_req.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509_req.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509_req.o: ../../include/openssl/opensslconf.h
        +x509_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_req.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
        +x509_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_req.c
        +x509_set.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_set.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_set.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509_set.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509_set.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509_set.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509_set.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509_set.o: ../../include/openssl/opensslconf.h
        +x509_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_set.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_set.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_set.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_set.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_set.c
        +x509_trs.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_trs.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_trs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_trs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_trs.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_trs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_trs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_trs.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_trs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_trs.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_trs.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_trs.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_trs.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_trs.o: ../cryptlib.h x509_trs.c
        +x509_txt.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_txt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_txt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509_txt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509_txt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509_txt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509_txt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509_txt.o: ../../include/openssl/opensslconf.h
        +x509_txt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_txt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_txt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_txt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_txt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_txt.c
        +x509_v3.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_v3.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_v3.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_v3.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_v3.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_v3.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_v3.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_v3.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_v3.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_v3.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_v3.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_v3.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_v3.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_v3.o: ../cryptlib.h x509_v3.c
        +x509_vfy.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_vfy.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_vfy.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_vfy.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_vfy.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_vfy.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_vfy.o: ../cryptlib.h x509_vfy.c
        +x509_vpm.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509_vpm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509_vpm.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +x509_vpm.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +x509_vpm.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +x509_vpm.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +x509_vpm.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +x509_vpm.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +x509_vpm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509_vpm.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509_vpm.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509_vpm.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509_vpm.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +x509_vpm.o: ../cryptlib.h x509_vpm.c
        +x509cset.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509cset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509cset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509cset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509cset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509cset.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509cset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509cset.o: ../../include/openssl/opensslconf.h
        +x509cset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509cset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509cset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509cset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509cset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509cset.c
        +x509name.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509name.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509name.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509name.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509name.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509name.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509name.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509name.o: ../../include/openssl/opensslconf.h
        +x509name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509name.c
        +x509rset.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509rset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509rset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509rset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509rset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509rset.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509rset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509rset.o: ../../include/openssl/opensslconf.h
        +x509rset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509rset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509rset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509rset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509rset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509rset.c
        +x509spki.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509spki.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509spki.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509spki.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509spki.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509spki.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509spki.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509spki.o: ../../include/openssl/opensslconf.h
        +x509spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509spki.c
        +x509type.o: ../../e_os.h ../../include/openssl/asn1.h
        +x509type.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +x509type.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +x509type.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x509type.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x509type.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x509type.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x509type.o: ../../include/openssl/opensslconf.h
        +x509type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +x509type.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +x509type.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x509type.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x509type.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509type.c
        +x_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +x_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +x_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +x_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +x_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +x_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +x_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +x_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +x_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +x_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
        +x_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +x_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +x_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_all.c
        diff --git a/vendor/openssl/openssl/crypto/x509/by_dir.c b/vendor/openssl/openssl/crypto/x509/by_dir.c
        new file mode 100644
        index 000000000..27ca5150c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/by_dir.c
        @@ -0,0 +1,482 @@
        +/* crypto/x509/by_dir.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include <errno.h>
        +
        +#include "cryptlib.h"
        +
        +#ifndef NO_SYS_TYPES_H
        +# include <sys/types.h>
        +#endif
        +#ifndef OPENSSL_NO_POSIX_IO
        +# include <sys/stat.h>
        +#endif
        +
        +#include <openssl/lhash.h>
        +#include <openssl/x509.h>
        +
        +
        +typedef struct lookup_dir_hashes_st
        +	{
        +	unsigned long hash;
        +	int suffix;
        +	} BY_DIR_HASH;
        +
        +typedef struct lookup_dir_entry_st
        +	{
        +	char *dir;
        +	int dir_type;
        +	STACK_OF(BY_DIR_HASH) *hashes;
        +	} BY_DIR_ENTRY;
        +
        +typedef struct lookup_dir_st
        +	{
        +	BUF_MEM *buffer;
        +	STACK_OF(BY_DIR_ENTRY) *dirs;
        +	} BY_DIR;
        +
        +DECLARE_STACK_OF(BY_DIR_HASH)
        +DECLARE_STACK_OF(BY_DIR_ENTRY)
        +
        +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
        +	char **ret);
        +static int new_dir(X509_LOOKUP *lu);
        +static void free_dir(X509_LOOKUP *lu);
        +static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
        +static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
        +	X509_OBJECT *ret);
        +X509_LOOKUP_METHOD x509_dir_lookup=
        +	{
        +	"Load certs from files in a directory",
        +	new_dir,		/* new */
        +	free_dir,		/* free */
        +	NULL, 			/* init */
        +	NULL,			/* shutdown */
        +	dir_ctrl,		/* ctrl */
        +	get_cert_by_subject,	/* get_by_subject */
        +	NULL,			/* get_by_issuer_serial */
        +	NULL,			/* get_by_fingerprint */
        +	NULL,			/* get_by_alias */
        +	};
        +
        +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
        +	{
        +	return(&x509_dir_lookup);
        +	}
        +
        +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
        +	     char **retp)
        +	{
        +	int ret=0;
        +	BY_DIR *ld;
        +	char *dir = NULL;
        +
        +	ld=(BY_DIR *)ctx->method_data;
        +
        +	switch (cmd)
        +		{
        +	case X509_L_ADD_DIR:
        +		if (argl == X509_FILETYPE_DEFAULT)
        +			{
        +			dir=(char *)getenv(X509_get_default_cert_dir_env());
        +			if (dir)
        +				ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
        +			else
        +				ret=add_cert_dir(ld,X509_get_default_cert_dir(),
        +					X509_FILETYPE_PEM);
        +			if (!ret)
        +				{
        +				X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR);
        +				}
        +			}
        +		else
        +			ret=add_cert_dir(ld,argp,(int)argl);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int new_dir(X509_LOOKUP *lu)
        +	{
        +	BY_DIR *a;
        +
        +	if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
        +		return(0);
        +	if ((a->buffer=BUF_MEM_new()) == NULL)
        +		{
        +		OPENSSL_free(a);
        +		return(0);
        +		}
        +	a->dirs=NULL;
        +	lu->method_data=(char *)a;
        +	return(1);
        +	}
        +
        +static void by_dir_hash_free(BY_DIR_HASH *hash)
        +	{
        +	OPENSSL_free(hash);
        +	}
        +
        +static int by_dir_hash_cmp(const BY_DIR_HASH * const *a,
        +			const BY_DIR_HASH * const *b)
        +	{
        +	if ((*a)->hash > (*b)->hash)
        +		return 1;
        +	if ((*a)->hash < (*b)->hash)
        +		return -1;
        +	return 0;
        +	}
        +
        +static void by_dir_entry_free(BY_DIR_ENTRY *ent)
        +	{
        +	if (ent->dir)
        +		OPENSSL_free(ent->dir);
        +	if (ent->hashes)
        +		sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
        +	OPENSSL_free(ent);
        +	}
        +
        +static void free_dir(X509_LOOKUP *lu)
        +	{
        +	BY_DIR *a;
        +
        +	a=(BY_DIR *)lu->method_data;
        +	if (a->dirs != NULL)
        +		sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
        +	if (a->buffer != NULL)
        +		BUF_MEM_free(a->buffer);
        +	OPENSSL_free(a);
        +	}
        +
        +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
        +	{
        +	int j,len;
        +	const char *s,*ss,*p;
        +
        +	if (dir == NULL || !*dir)
        +	    {
        +	    X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY);
        +	    return 0;
        +	    }
        +
        +	s=dir;
        +	p=s;
        +	for (;;p++)
        +		{
        +		if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
        +			{
        +			BY_DIR_ENTRY *ent;
        +			ss=s;
        +			s=p+1;
        +			len=(int)(p-ss);
        +			if (len == 0) continue;
        +			for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
        +				{
        +				ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
        +				if (strlen(ent->dir) == (size_t)len &&
        +				    strncmp(ent->dir,ss,(unsigned int)len) == 0)
        +					break;
        +				}
        +			if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
        +				continue;
        +			if (ctx->dirs == NULL)
        +				{
        +				ctx->dirs = sk_BY_DIR_ENTRY_new_null();
        +				if (!ctx->dirs)
        +					{
        +					X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE);
        +					return 0;
        +					}
        +				}
        +			ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
        +			if (!ent)
        +				return 0;
        +			ent->dir_type = type;
        +			ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
        +			ent->dir = OPENSSL_malloc((unsigned int)len+1);
        +			if (!ent->dir || !ent->hashes)
        +				{
        +				by_dir_entry_free(ent);
        +				return 0;
        +				}
        +			strncpy(ent->dir,ss,(unsigned int)len);
        +			ent->dir[len] = '\0';
        +			if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
        +				{
        +				by_dir_entry_free(ent);
        +				return 0;
        +				}
        +			}
        +		if (*p == '\0')
        +			break;
        +		}
        +	return 1;
        +	}
        +
        +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
        +	     X509_OBJECT *ret)
        +	{
        +	BY_DIR *ctx;
        +	union	{
        +		struct	{
        +			X509 st_x509;
        +			X509_CINF st_x509_cinf;
        +			} x509;
        +		struct	{
        +			X509_CRL st_crl;
        +			X509_CRL_INFO st_crl_info;
        +			} crl;
        +		} data;
        +	int ok=0;
        +	int i,j,k;
        +	unsigned long h;
        +	BUF_MEM *b=NULL;
        +	X509_OBJECT stmp,*tmp;
        +	const char *postfix="";
        +
        +	if (name == NULL) return(0);
        +
        +	stmp.type=type;
        +	if (type == X509_LU_X509)
        +		{
        +		data.x509.st_x509.cert_info= &data.x509.st_x509_cinf;
        +		data.x509.st_x509_cinf.subject=name;
        +		stmp.data.x509= &data.x509.st_x509;
        +		postfix="";
        +		}
        +	else if (type == X509_LU_CRL)
        +		{
        +		data.crl.st_crl.crl= &data.crl.st_crl_info;
        +		data.crl.st_crl_info.issuer=name;
        +		stmp.data.crl= &data.crl.st_crl;
        +		postfix="r";
        +		}
        +	else
        +		{
        +		X509err(X509_F_GET_CERT_BY_SUBJECT,X509_R_WRONG_LOOKUP_TYPE);
        +		goto finish;
        +		}
        +
        +	if ((b=BUF_MEM_new()) == NULL)
        +		{
        +		X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB);
        +		goto finish;
        +		}
        +	
        +	ctx=(BY_DIR *)xl->method_data;
        +
        +	h=X509_NAME_hash(name);
        +	for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
        +		{
        +		BY_DIR_ENTRY *ent;
        +		int idx;
        +		BY_DIR_HASH htmp, *hent;
        +		ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
        +		j=strlen(ent->dir)+1+8+6+1+1;
        +		if (!BUF_MEM_grow(b,j))
        +			{
        +			X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
        +			goto finish;
        +			}
        +		if (type == X509_LU_CRL && ent->hashes)
        +			{
        +			htmp.hash = h;
        +			CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
        +			idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
        +			if (idx >= 0)
        +				{
        +				hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
        +				k = hent->suffix;
        +				}
        +			else
        +				{
        +				hent = NULL;
        +				k=0;
        +				}
        +			CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
        +			}
        +		else
        +			{
        +			k = 0;
        +			hent = NULL;
        +			}
        +		for (;;)
        +			{
        +			char c = '/';
        +#ifdef OPENSSL_SYS_VMS
        +			c = ent->dir[strlen(ent->dir)-1];
        +			if (c != ':' && c != '>' && c != ']')
        +				{
        +				/* If no separator is present, we assume the
        +				   directory specifier is a logical name, and
        +				   add a colon.  We really should use better
        +				   VMS routines for merging things like this,
        +				   but this will do for now...
        +				   -- Richard Levitte */
        +				c = ':';
        +				}
        +			else
        +				{
        +				c = '\0';
        +				}
        +#endif
        +			if (c == '\0')
        +				{
        +				/* This is special.  When c == '\0', no
        +				   directory separator should be added. */
        +				BIO_snprintf(b->data,b->max,
        +					"%s%08lx.%s%d",ent->dir,h,
        +					postfix,k);
        +				}
        +			else
        +				{
        +				BIO_snprintf(b->data,b->max,
        +					"%s%c%08lx.%s%d",ent->dir,c,h,
        +					postfix,k);
        +				}
        +#ifndef OPENSSL_NO_POSIX_IO
        +#ifdef _WIN32
        +#define stat _stat
        +#endif
        +			{
        +			struct stat st;
        +			if (stat(b->data,&st) < 0)
        +				break;
        +			}
        +#endif
        +			/* found one. */
        +			if (type == X509_LU_X509)
        +				{
        +				if ((X509_load_cert_file(xl,b->data,
        +					ent->dir_type)) == 0)
        +					break;
        +				}
        +			else if (type == X509_LU_CRL)
        +				{
        +				if ((X509_load_crl_file(xl,b->data,
        +					ent->dir_type)) == 0)
        +					break;
        +				}
        +			/* else case will caught higher up */
        +			k++;
        +			}
        +
        +		/* we have added it to the cache so now pull
        +		 * it out again */
        +		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +		j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp);
        +		if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j);
        +		else tmp = NULL;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +
        +
        +		/* If a CRL, update the last file suffix added for this */
        +
        +		if (type == X509_LU_CRL)
        +			{
        +			CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +			/* Look for entry again in case another thread added
        +			 * an entry first.
        +			 */
        +			if (!hent)
        +				{
        +				htmp.hash = h;
        +				idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
        +				if (idx >= 0)
        +					hent =
        +					 sk_BY_DIR_HASH_value(ent->hashes, idx);
        +				}
        +			if (!hent)
        +				{
        +				hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
        +				hent->hash = h;
        +				hent->suffix = k;
        +				if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
        +					{
        +					CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +					OPENSSL_free(hent);
        +					ok = 0;
        +					goto finish;
        +					}
        +				}
        +			else if (hent->suffix < k)
        +				hent->suffix = k;
        +
        +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +
        +			}
        +
        +		if (tmp != NULL)
        +			{
        +			ok=1;
        +			ret->type=tmp->type;
        +			memcpy(&ret->data,&tmp->data,sizeof(ret->data));
        +			/* If we were going to up the reference count,
        +			 * we would need to do it on a perl 'type'
        +			 * basis */
        +	/*		CRYPTO_add(&tmp->data.x509->references,1,
        +				CRYPTO_LOCK_X509);*/
        +			goto finish;
        +			}
        +		}
        +finish:
        +	if (b != NULL) BUF_MEM_free(b);
        +	return(ok);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509/by_file.c b/vendor/openssl/openssl/crypto/x509/by_file.c
        new file mode 100644
        index 000000000..57b08ee09
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/by_file.c
        @@ -0,0 +1,300 @@
        +/* crypto/x509/by_file.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include <errno.h>
        +
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/buffer.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#ifndef OPENSSL_NO_STDIO
        +
        +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
        +	long argl, char **ret);
        +X509_LOOKUP_METHOD x509_file_lookup=
        +	{
        +	"Load file into cache",
        +	NULL,		/* new */
        +	NULL,		/* free */
        +	NULL, 		/* init */
        +	NULL,		/* shutdown */
        +	by_file_ctrl,	/* ctrl */
        +	NULL,		/* get_by_subject */
        +	NULL,		/* get_by_issuer_serial */
        +	NULL,		/* get_by_fingerprint */
        +	NULL,		/* get_by_alias */
        +	};
        +
        +X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
        +	{
        +	return(&x509_file_lookup);
        +	}
        +
        +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
        +	     char **ret)
        +	{
        +	int ok=0;
        +	char *file;
        +
        +	switch (cmd)
        +		{
        +	case X509_L_FILE_LOAD:
        +		if (argl == X509_FILETYPE_DEFAULT)
        +			{
        +			file = (char *)getenv(X509_get_default_cert_file_env());
        +			if (file)
        +				ok = (X509_load_cert_crl_file(ctx,file,
        +					      X509_FILETYPE_PEM) != 0);
        +
        +			else
        +				ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(),
        +					      X509_FILETYPE_PEM) != 0);
        +
        +			if (!ok)
        +				{
        +				X509err(X509_F_BY_FILE_CTRL,X509_R_LOADING_DEFAULTS);
        +				}
        +			}
        +		else
        +			{
        +			if(argl == X509_FILETYPE_PEM)
        +				ok = (X509_load_cert_crl_file(ctx,argp,
        +					X509_FILETYPE_PEM) != 0);
        +			else
        +				ok = (X509_load_cert_file(ctx,argp,(int)argl) != 0);
        +			}
        +		break;
        +		}
        +	return(ok);
        +	}
        +
        +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
        +	{
        +	int ret=0;
        +	BIO *in=NULL;
        +	int i,count=0;
        +	X509 *x=NULL;
        +
        +	if (file == NULL) return(1);
        +	in=BIO_new(BIO_s_file_internal());
        +
        +	if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
        +		{
        +		X509err(X509_F_X509_LOAD_CERT_FILE,ERR_R_SYS_LIB);
        +		goto err;
        +		}
        +
        +	if (type == X509_FILETYPE_PEM)
        +		{
        +		for (;;)
        +			{
        +			x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL);
        +			if (x == NULL)
        +				{
        +				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
        +					PEM_R_NO_START_LINE) && (count > 0))
        +					{
        +					ERR_clear_error();
        +					break;
        +					}
        +				else
        +					{
        +					X509err(X509_F_X509_LOAD_CERT_FILE,
        +						ERR_R_PEM_LIB);
        +					goto err;
        +					}
        +				}
        +			i=X509_STORE_add_cert(ctx->store_ctx,x);
        +			if (!i) goto err;
        +			count++;
        +			X509_free(x);
        +			x=NULL;
        +			}
        +		ret=count;
        +		}
        +	else if (type == X509_FILETYPE_ASN1)
        +		{
        +		x=d2i_X509_bio(in,NULL);
        +		if (x == NULL)
        +			{
        +			X509err(X509_F_X509_LOAD_CERT_FILE,ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		i=X509_STORE_add_cert(ctx->store_ctx,x);
        +		if (!i) goto err;
        +		ret=i;
        +		}
        +	else
        +		{
        +		X509err(X509_F_X509_LOAD_CERT_FILE,X509_R_BAD_X509_FILETYPE);
        +		goto err;
        +		}
        +err:
        +	if (x != NULL) X509_free(x);
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +
        +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
        +	{
        +	int ret=0;
        +	BIO *in=NULL;
        +	int i,count=0;
        +	X509_CRL *x=NULL;
        +
        +	if (file == NULL) return(1);
        +	in=BIO_new(BIO_s_file_internal());
        +
        +	if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
        +		{
        +		X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_SYS_LIB);
        +		goto err;
        +		}
        +
        +	if (type == X509_FILETYPE_PEM)
        +		{
        +		for (;;)
        +			{
        +			x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
        +			if (x == NULL)
        +				{
        +				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
        +					PEM_R_NO_START_LINE) && (count > 0))
        +					{
        +					ERR_clear_error();
        +					break;
        +					}
        +				else
        +					{
        +					X509err(X509_F_X509_LOAD_CRL_FILE,
        +						ERR_R_PEM_LIB);
        +					goto err;
        +					}
        +				}
        +			i=X509_STORE_add_crl(ctx->store_ctx,x);
        +			if (!i) goto err;
        +			count++;
        +			X509_CRL_free(x);
        +			x=NULL;
        +			}
        +		ret=count;
        +		}
        +	else if (type == X509_FILETYPE_ASN1)
        +		{
        +		x=d2i_X509_CRL_bio(in,NULL);
        +		if (x == NULL)
        +			{
        +			X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		i=X509_STORE_add_crl(ctx->store_ctx,x);
        +		if (!i) goto err;
        +		ret=i;
        +		}
        +	else
        +		{
        +		X509err(X509_F_X509_LOAD_CRL_FILE,X509_R_BAD_X509_FILETYPE);
        +		goto err;
        +		}
        +err:
        +	if (x != NULL) X509_CRL_free(x);
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +
        +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
        +{
        +	STACK_OF(X509_INFO) *inf;
        +	X509_INFO *itmp;
        +	BIO *in;
        +	int i, count = 0;
        +	if(type != X509_FILETYPE_PEM)
        +		return X509_load_cert_file(ctx, file, type);
        +	in = BIO_new_file(file, "r");
        +	if(!in) {
        +		X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_SYS_LIB);
        +		return 0;
        +	}
        +	inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
        +	BIO_free(in);
        +	if(!inf) {
        +		X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB);
        +		return 0;
        +	}
        +	for(i = 0; i < sk_X509_INFO_num(inf); i++) {
        +		itmp = sk_X509_INFO_value(inf, i);
        +		if(itmp->x509) {
        +			X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
        +			count++;
        +		}
        +		if(itmp->crl) {
        +			X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
        +			count++;
        +		}
        +	}
        +	sk_X509_INFO_pop_free(inf, X509_INFO_free);
        +	return count;
        +}
        +
        +
        +#endif /* OPENSSL_NO_STDIO */
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509.h b/vendor/openssl/openssl/crypto/x509/x509.h
        new file mode 100644
        index 000000000..092dd7450
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509.h
        @@ -0,0 +1,1297 @@
        +/* crypto/x509/x509.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECDH support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#ifndef HEADER_X509_H
        +#define HEADER_X509_H
        +
        +#include <openssl/e_os2.h>
        +#include <openssl/symhacks.h>
        +#ifndef OPENSSL_NO_BUFFER
        +#include <openssl/buffer.h>
        +#endif
        +#ifndef OPENSSL_NO_EVP
        +#include <openssl/evp.h>
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#include <openssl/stack.h>
        +#include <openssl/asn1.h>
        +#include <openssl/safestack.h>
        +
        +#ifndef OPENSSL_NO_EC
        +#include <openssl/ec.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +#include <openssl/ecdsa.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +#include <openssl/ecdh.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_DEPRECATED
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA
        +#include <openssl/sha.h>
        +#endif
        +#include <openssl/ossl_typ.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#ifdef OPENSSL_SYS_WIN32
        +/* Under Win32 these are defined in wincrypt.h */
        +#undef X509_NAME
        +#undef X509_CERT_PAIR
        +#undef X509_EXTENSIONS
        +#endif
        +
        +#define X509_FILETYPE_PEM	1
        +#define X509_FILETYPE_ASN1	2
        +#define X509_FILETYPE_DEFAULT	3
        +
        +#define X509v3_KU_DIGITAL_SIGNATURE	0x0080
        +#define X509v3_KU_NON_REPUDIATION	0x0040
        +#define X509v3_KU_KEY_ENCIPHERMENT	0x0020
        +#define X509v3_KU_DATA_ENCIPHERMENT	0x0010
        +#define X509v3_KU_KEY_AGREEMENT		0x0008
        +#define X509v3_KU_KEY_CERT_SIGN		0x0004
        +#define X509v3_KU_CRL_SIGN		0x0002
        +#define X509v3_KU_ENCIPHER_ONLY		0x0001
        +#define X509v3_KU_DECIPHER_ONLY		0x8000
        +#define X509v3_KU_UNDEF			0xffff
        +
        +typedef struct X509_objects_st
        +	{
        +	int nid;
        +	int (*a2i)(void);
        +	int (*i2a)(void);
        +	} X509_OBJECTS;
        +
        +struct X509_algor_st
        +	{
        +	ASN1_OBJECT *algorithm;
        +	ASN1_TYPE *parameter;
        +	} /* X509_ALGOR */;
        +
        +DECLARE_ASN1_SET_OF(X509_ALGOR)
        +
        +typedef STACK_OF(X509_ALGOR) X509_ALGORS;
        +
        +typedef struct X509_val_st
        +	{
        +	ASN1_TIME *notBefore;
        +	ASN1_TIME *notAfter;
        +	} X509_VAL;
        +
        +struct X509_pubkey_st
        +	{
        +	X509_ALGOR *algor;
        +	ASN1_BIT_STRING *public_key;
        +	EVP_PKEY *pkey;
        +	};
        +
        +typedef struct X509_sig_st
        +	{
        +	X509_ALGOR *algor;
        +	ASN1_OCTET_STRING *digest;
        +	} X509_SIG;
        +
        +typedef struct X509_name_entry_st
        +	{
        +	ASN1_OBJECT *object;
        +	ASN1_STRING *value;
        +	int set;
        +	int size; 	/* temp variable */
        +	} X509_NAME_ENTRY;
        +
        +DECLARE_STACK_OF(X509_NAME_ENTRY)
        +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
        +
        +/* we always keep X509_NAMEs in 2 forms. */
        +struct X509_name_st
        +	{
        +	STACK_OF(X509_NAME_ENTRY) *entries;
        +	int modified;	/* true if 'bytes' needs to be built */
        +#ifndef OPENSSL_NO_BUFFER
        +	BUF_MEM *bytes;
        +#else
        +	char *bytes;
        +#endif
        +/*	unsigned long hash; Keep the hash around for lookups */
        +	unsigned char *canon_enc;
        +	int canon_enclen;
        +	} /* X509_NAME */;
        +
        +DECLARE_STACK_OF(X509_NAME)
        +
        +#define X509_EX_V_NETSCAPE_HACK		0x8000
        +#define X509_EX_V_INIT			0x0001
        +typedef struct X509_extension_st
        +	{
        +	ASN1_OBJECT *object;
        +	ASN1_BOOLEAN critical;
        +	ASN1_OCTET_STRING *value;
        +	} X509_EXTENSION;
        +
        +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
        +
        +DECLARE_STACK_OF(X509_EXTENSION)
        +DECLARE_ASN1_SET_OF(X509_EXTENSION)
        +
        +/* a sequence of these are used */
        +typedef struct x509_attributes_st
        +	{
        +	ASN1_OBJECT *object;
        +	int single; /* 0 for a set, 1 for a single item (which is wrong) */
        +	union	{
        +		char		*ptr;
        +/* 0 */		STACK_OF(ASN1_TYPE) *set;
        +/* 1 */		ASN1_TYPE	*single;
        +		} value;
        +	} X509_ATTRIBUTE;
        +
        +DECLARE_STACK_OF(X509_ATTRIBUTE)
        +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
        +
        +
        +typedef struct X509_req_info_st
        +	{
        +	ASN1_ENCODING enc;
        +	ASN1_INTEGER *version;
        +	X509_NAME *subject;
        +	X509_PUBKEY *pubkey;
        +	/*  d=2 hl=2 l=  0 cons: cont: 00 */
        +	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
        +	} X509_REQ_INFO;
        +
        +typedef struct X509_req_st
        +	{
        +	X509_REQ_INFO *req_info;
        +	X509_ALGOR *sig_alg;
        +	ASN1_BIT_STRING *signature;
        +	int references;
        +	} X509_REQ;
        +
        +typedef struct x509_cinf_st
        +	{
        +	ASN1_INTEGER *version;		/* [ 0 ] default of v1 */
        +	ASN1_INTEGER *serialNumber;
        +	X509_ALGOR *signature;
        +	X509_NAME *issuer;
        +	X509_VAL *validity;
        +	X509_NAME *subject;
        +	X509_PUBKEY *key;
        +	ASN1_BIT_STRING *issuerUID;		/* [ 1 ] optional in v2 */
        +	ASN1_BIT_STRING *subjectUID;		/* [ 2 ] optional in v2 */
        +	STACK_OF(X509_EXTENSION) *extensions;	/* [ 3 ] optional in v3 */
        +	ASN1_ENCODING enc;
        +	} X509_CINF;
        +
        +/* This stuff is certificate "auxiliary info"
        + * it contains details which are useful in certificate
        + * stores and databases. When used this is tagged onto
        + * the end of the certificate itself
        + */
        +
        +typedef struct x509_cert_aux_st
        +	{
        +	STACK_OF(ASN1_OBJECT) *trust;		/* trusted uses */
        +	STACK_OF(ASN1_OBJECT) *reject;		/* rejected uses */
        +	ASN1_UTF8STRING *alias;			/* "friendly name" */
        +	ASN1_OCTET_STRING *keyid;		/* key id of private key */
        +	STACK_OF(X509_ALGOR) *other;		/* other unspecified info */
        +	} X509_CERT_AUX;
        +
        +struct x509_st
        +	{
        +	X509_CINF *cert_info;
        +	X509_ALGOR *sig_alg;
        +	ASN1_BIT_STRING *signature;
        +	int valid;
        +	int references;
        +	char *name;
        +	CRYPTO_EX_DATA ex_data;
        +	/* These contain copies of various extension values */
        +	long ex_pathlen;
        +	long ex_pcpathlen;
        +	unsigned long ex_flags;
        +	unsigned long ex_kusage;
        +	unsigned long ex_xkusage;
        +	unsigned long ex_nscert;
        +	ASN1_OCTET_STRING *skid;
        +	AUTHORITY_KEYID *akid;
        +	X509_POLICY_CACHE *policy_cache;
        +	STACK_OF(DIST_POINT) *crldp;
        +	STACK_OF(GENERAL_NAME) *altname;
        +	NAME_CONSTRAINTS *nc;
        +#ifndef OPENSSL_NO_RFC3779
        +	STACK_OF(IPAddressFamily) *rfc3779_addr;
        +	struct ASIdentifiers_st *rfc3779_asid;
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
        +#endif
        +	X509_CERT_AUX *aux;
        +	} /* X509 */;
        +
        +DECLARE_STACK_OF(X509)
        +DECLARE_ASN1_SET_OF(X509)
        +
        +/* This is used for a table of trust checking functions */
        +
        +typedef struct x509_trust_st {
        +	int trust;
        +	int flags;
        +	int (*check_trust)(struct x509_trust_st *, X509 *, int);
        +	char *name;
        +	int arg1;
        +	void *arg2;
        +} X509_TRUST;
        +
        +DECLARE_STACK_OF(X509_TRUST)
        +
        +typedef struct x509_cert_pair_st {
        +	X509 *forward;
        +	X509 *reverse;
        +} X509_CERT_PAIR;
        +
        +/* standard trust ids */
        +
        +#define X509_TRUST_DEFAULT	-1	/* Only valid in purpose settings */
        +
        +#define X509_TRUST_COMPAT	1
        +#define X509_TRUST_SSL_CLIENT	2
        +#define X509_TRUST_SSL_SERVER	3
        +#define X509_TRUST_EMAIL	4
        +#define X509_TRUST_OBJECT_SIGN	5
        +#define X509_TRUST_OCSP_SIGN	6
        +#define X509_TRUST_OCSP_REQUEST	7
        +#define X509_TRUST_TSA		8
        +
        +/* Keep these up to date! */
        +#define X509_TRUST_MIN		1
        +#define X509_TRUST_MAX		8
        +
        +
        +/* trust_flags values */
        +#define	X509_TRUST_DYNAMIC 	1
        +#define	X509_TRUST_DYNAMIC_NAME	2
        +
        +/* check_trust return codes */
        +
        +#define X509_TRUST_TRUSTED	1
        +#define X509_TRUST_REJECTED	2
        +#define X509_TRUST_UNTRUSTED	3
        +
        +/* Flags for X509_print_ex() */
        +
        +#define	X509_FLAG_COMPAT		0
        +#define	X509_FLAG_NO_HEADER		1L
        +#define	X509_FLAG_NO_VERSION		(1L << 1)
        +#define	X509_FLAG_NO_SERIAL		(1L << 2)
        +#define	X509_FLAG_NO_SIGNAME		(1L << 3)
        +#define	X509_FLAG_NO_ISSUER		(1L << 4)
        +#define	X509_FLAG_NO_VALIDITY		(1L << 5)
        +#define	X509_FLAG_NO_SUBJECT		(1L << 6)
        +#define	X509_FLAG_NO_PUBKEY		(1L << 7)
        +#define	X509_FLAG_NO_EXTENSIONS		(1L << 8)
        +#define	X509_FLAG_NO_SIGDUMP		(1L << 9)
        +#define	X509_FLAG_NO_AUX		(1L << 10)
        +#define	X509_FLAG_NO_ATTRIBUTES		(1L << 11)
        +
        +/* Flags specific to X509_NAME_print_ex() */	
        +
        +/* The field separator information */
        +
        +#define XN_FLAG_SEP_MASK	(0xf << 16)
        +
        +#define XN_FLAG_COMPAT		0		/* Traditional SSLeay: use old X509_NAME_print */
        +#define XN_FLAG_SEP_COMMA_PLUS	(1 << 16)	/* RFC2253 ,+ */
        +#define XN_FLAG_SEP_CPLUS_SPC	(2 << 16)	/* ,+ spaced: more readable */
        +#define XN_FLAG_SEP_SPLUS_SPC	(3 << 16)	/* ;+ spaced */
        +#define XN_FLAG_SEP_MULTILINE	(4 << 16)	/* One line per field */
        +
        +#define XN_FLAG_DN_REV		(1 << 20)	/* Reverse DN order */
        +
        +/* How the field name is shown */
        +
        +#define XN_FLAG_FN_MASK		(0x3 << 21)
        +
        +#define XN_FLAG_FN_SN		0		/* Object short name */
        +#define XN_FLAG_FN_LN		(1 << 21)	/* Object long name */
        +#define XN_FLAG_FN_OID		(2 << 21)	/* Always use OIDs */
        +#define XN_FLAG_FN_NONE		(3 << 21)	/* No field names */
        +
        +#define XN_FLAG_SPC_EQ		(1 << 23)	/* Put spaces round '=' */
        +
        +/* This determines if we dump fields we don't recognise:
        + * RFC2253 requires this.
        + */
        +
        +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
        +
        +#define XN_FLAG_FN_ALIGN	(1 << 25)	/* Align field names to 20 characters */
        +
        +/* Complete set of RFC2253 flags */
        +
        +#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
        +			XN_FLAG_SEP_COMMA_PLUS | \
        +			XN_FLAG_DN_REV | \
        +			XN_FLAG_FN_SN | \
        +			XN_FLAG_DUMP_UNKNOWN_FIELDS)
        +
        +/* readable oneline form */
        +
        +#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
        +			ASN1_STRFLGS_ESC_QUOTE | \
        +			XN_FLAG_SEP_CPLUS_SPC | \
        +			XN_FLAG_SPC_EQ | \
        +			XN_FLAG_FN_SN)
        +
        +/* readable multiline form */
        +
        +#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
        +			ASN1_STRFLGS_ESC_MSB | \
        +			XN_FLAG_SEP_MULTILINE | \
        +			XN_FLAG_SPC_EQ | \
        +			XN_FLAG_FN_LN | \
        +			XN_FLAG_FN_ALIGN)
        +
        +struct x509_revoked_st
        +	{
        +	ASN1_INTEGER *serialNumber;
        +	ASN1_TIME *revocationDate;
        +	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
        +	/* Set up if indirect CRL */
        +	STACK_OF(GENERAL_NAME) *issuer;
        +	/* Revocation reason */
        +	int reason;
        +	int sequence; /* load sequence */
        +	};
        +
        +DECLARE_STACK_OF(X509_REVOKED)
        +DECLARE_ASN1_SET_OF(X509_REVOKED)
        +
        +typedef struct X509_crl_info_st
        +	{
        +	ASN1_INTEGER *version;
        +	X509_ALGOR *sig_alg;
        +	X509_NAME *issuer;
        +	ASN1_TIME *lastUpdate;
        +	ASN1_TIME *nextUpdate;
        +	STACK_OF(X509_REVOKED) *revoked;
        +	STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
        +	ASN1_ENCODING enc;
        +	} X509_CRL_INFO;
        +
        +struct X509_crl_st
        +	{
        +	/* actual signature */
        +	X509_CRL_INFO *crl;
        +	X509_ALGOR *sig_alg;
        +	ASN1_BIT_STRING *signature;
        +	int references;
        +	int flags;
        +	/* Copies of various extensions */
        +	AUTHORITY_KEYID *akid;
        +	ISSUING_DIST_POINT *idp;
        +	/* Convenient breakdown of IDP */
        +	int idp_flags;
        +	int idp_reasons;
        +	/* CRL and base CRL numbers for delta processing */
        +	ASN1_INTEGER *crl_number;
        +	ASN1_INTEGER *base_crl_number;
        +#ifndef OPENSSL_NO_SHA
        +	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
        +#endif
        +	STACK_OF(GENERAL_NAMES) *issuers;
        +	const X509_CRL_METHOD *meth;
        +	void *meth_data;
        +	} /* X509_CRL */;
        +
        +DECLARE_STACK_OF(X509_CRL)
        +DECLARE_ASN1_SET_OF(X509_CRL)
        +
        +typedef struct private_key_st
        +	{
        +	int version;
        +	/* The PKCS#8 data types */
        +	X509_ALGOR *enc_algor;
        +	ASN1_OCTET_STRING *enc_pkey;	/* encrypted pub key */
        +
        +	/* When decrypted, the following will not be NULL */
        +	EVP_PKEY *dec_pkey;
        +
        +	/* used to encrypt and decrypt */
        +	int key_length;
        +	char *key_data;
        +	int key_free;	/* true if we should auto free key_data */
        +
        +	/* expanded version of 'enc_algor' */
        +	EVP_CIPHER_INFO cipher;
        +
        +	int references;
        +	} X509_PKEY;
        +
        +#ifndef OPENSSL_NO_EVP
        +typedef struct X509_info_st
        +	{
        +	X509 *x509;
        +	X509_CRL *crl;
        +	X509_PKEY *x_pkey;
        +
        +	EVP_CIPHER_INFO enc_cipher;
        +	int enc_len;
        +	char *enc_data;
        +
        +	int references;
        +	} X509_INFO;
        +
        +DECLARE_STACK_OF(X509_INFO)
        +#endif
        +
        +/* The next 2 structures and their 8 routines were sent to me by
        + * Pat Richard <patr@x509.com> and are used to manipulate
        + * Netscapes spki structures - useful if you are writing a CA web page
        + */
        +typedef struct Netscape_spkac_st
        +	{
        +	X509_PUBKEY *pubkey;
        +	ASN1_IA5STRING *challenge;	/* challenge sent in atlas >= PR2 */
        +	} NETSCAPE_SPKAC;
        +
        +typedef struct Netscape_spki_st
        +	{
        +	NETSCAPE_SPKAC *spkac;	/* signed public key and challenge */
        +	X509_ALGOR *sig_algor;
        +	ASN1_BIT_STRING *signature;
        +	} NETSCAPE_SPKI;
        +
        +/* Netscape certificate sequence structure */
        +typedef struct Netscape_certificate_sequence
        +	{
        +	ASN1_OBJECT *type;
        +	STACK_OF(X509) *certs;
        +	} NETSCAPE_CERT_SEQUENCE;
        +
        +/* Unused (and iv length is wrong)
        +typedef struct CBCParameter_st
        +	{
        +	unsigned char iv[8];
        +	} CBC_PARAM;
        +*/
        +
        +/* Password based encryption structure */
        +
        +typedef struct PBEPARAM_st {
        +ASN1_OCTET_STRING *salt;
        +ASN1_INTEGER *iter;
        +} PBEPARAM;
        +
        +/* Password based encryption V2 structures */
        +
        +typedef struct PBE2PARAM_st {
        +X509_ALGOR *keyfunc;
        +X509_ALGOR *encryption;
        +} PBE2PARAM;
        +
        +typedef struct PBKDF2PARAM_st {
        +ASN1_TYPE *salt;	/* Usually OCTET STRING but could be anything */
        +ASN1_INTEGER *iter;
        +ASN1_INTEGER *keylength;
        +X509_ALGOR *prf;
        +} PBKDF2PARAM;
        +
        +
        +/* PKCS#8 private key info structure */
        +
        +struct pkcs8_priv_key_info_st
        +        {
        +        int broken;     /* Flag for various broken formats */
        +#define PKCS8_OK		0
        +#define PKCS8_NO_OCTET		1
        +#define PKCS8_EMBEDDED_PARAM	2
        +#define PKCS8_NS_DB		3
        +#define PKCS8_NEG_PRIVKEY	4
        +        ASN1_INTEGER *version;
        +        X509_ALGOR *pkeyalg;
        +        ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
        +        STACK_OF(X509_ATTRIBUTE) *attributes;
        +        };
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#include <openssl/x509_vfy.h>
        +#include <openssl/pkcs7.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#define X509_EXT_PACK_UNKNOWN	1
        +#define X509_EXT_PACK_STRING	2
        +
        +#define		X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
        +/* #define	X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
        +#define		X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
        +#define		X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
        +#define		X509_extract_key(x)	X509_get_pubkey(x) /*****/
        +#define		X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
        +#define		X509_REQ_get_subject_name(x) ((x)->req_info->subject)
        +#define		X509_REQ_extract_key(a)	X509_REQ_get_pubkey(a)
        +#define		X509_name_cmp(a,b)	X509_NAME_cmp((a),(b))
        +#define		X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
        +
        +#define		X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
        +#define 	X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
        +#define 	X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
        +#define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
        +#define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
        +
        +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
        +X509_CRL_METHOD *X509_CRL_METHOD_new(
        +	int (*crl_init)(X509_CRL *crl),
        +	int (*crl_free)(X509_CRL *crl),
        +	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
        +				ASN1_INTEGER *ser, X509_NAME *issuer),
        +	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk));
        +void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
        +
        +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
        +void *X509_CRL_get_meth_data(X509_CRL *crl);
        +
        +/* This one is only used so that a binary form can output, as in
        + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
        +#define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
        +
        +
        +const char *X509_verify_cert_error_string(long n);
        +
        +#ifndef OPENSSL_NO_EVP
        +int X509_verify(X509 *a, EVP_PKEY *r);
        +
        +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
        +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
        +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
        +
        +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
        +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
        +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
        +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
        +
        +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
        +
        +int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent);
        +int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
        +
        +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
        +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
        +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
        +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
        +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
        +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
        +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
        +
        +int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
        +		unsigned char *md, unsigned int *len);
        +int X509_digest(const X509 *data,const EVP_MD *type,
        +		unsigned char *md, unsigned int *len);
        +int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
        +		unsigned char *md, unsigned int *len);
        +int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
        +		unsigned char *md, unsigned int *len);
        +int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
        +		unsigned char *md, unsigned int *len);
        +#endif
        +
        +#ifndef OPENSSL_NO_FP_API
        +X509 *d2i_X509_fp(FILE *fp, X509 **x509);
        +int i2d_X509_fp(FILE *fp,X509 *x509);
        +X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
        +int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
        +X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
        +int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
        +#ifndef OPENSSL_NO_RSA
        +RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
        +int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
        +RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
        +int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
        +RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
        +int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
        +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
        +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
        +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
        +#endif
        +#ifndef OPENSSL_NO_EC
        +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
        +int   i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
        +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
        +int   i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
        +#endif
        +X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
        +int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
        +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
        +						PKCS8_PRIV_KEY_INFO **p8inf);
        +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
        +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
        +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
        +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
        +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
        +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +X509 *d2i_X509_bio(BIO *bp,X509 **x509);
        +int i2d_X509_bio(BIO *bp,X509 *x509);
        +X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
        +int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
        +X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
        +int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
        +#ifndef OPENSSL_NO_RSA
        +RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
        +int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
        +RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
        +int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
        +RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
        +int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
        +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
        +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
        +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
        +#endif
        +#ifndef OPENSSL_NO_EC
        +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
        +int   i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
        +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
        +int   i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
        +#endif
        +X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
        +int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
        +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
        +						PKCS8_PRIV_KEY_INFO **p8inf);
        +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
        +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
        +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
        +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
        +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
        +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
        +#endif
        +
        +X509 *X509_dup(X509 *x509);
        +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
        +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
        +X509_CRL *X509_CRL_dup(X509_CRL *crl);
        +X509_REQ *X509_REQ_dup(X509_REQ *req);
        +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
        +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
        +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
        +						X509_ALGOR *algor);
        +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
        +
        +X509_NAME *X509_NAME_dup(X509_NAME *xn);
        +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
        +
        +int		X509_cmp_time(const ASN1_TIME *s, time_t *t);
        +int		X509_cmp_current_time(const ASN1_TIME *s);
        +ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
        +ASN1_TIME *	X509_time_adj_ex(ASN1_TIME *s,
        +				int offset_day, long offset_sec, time_t *t);
        +ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
        +
        +const char *	X509_get_default_cert_area(void );
        +const char *	X509_get_default_cert_dir(void );
        +const char *	X509_get_default_cert_file(void );
        +const char *	X509_get_default_cert_dir_env(void );
        +const char *	X509_get_default_cert_file_env(void );
        +const char *	X509_get_default_private_dir(void );
        +
        +X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
        +X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
        +
        +DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
        +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
        +DECLARE_ASN1_FUNCTIONS(X509_VAL)
        +
        +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
        +
        +int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
        +EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
        +int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
        +					   STACK_OF(X509) *chain);
        +int		i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp);
        +EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
        +			long length);
        +#ifndef OPENSSL_NO_RSA
        +int		i2d_RSA_PUBKEY(RSA *a,unsigned char **pp);
        +RSA *		d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
        +			long length);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +int		i2d_DSA_PUBKEY(DSA *a,unsigned char **pp);
        +DSA *		d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
        +			long length);
        +#endif
        +#ifndef OPENSSL_NO_EC
        +int		i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
        +EC_KEY 		*d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
        +			long length);
        +#endif
        +
        +DECLARE_ASN1_FUNCTIONS(X509_SIG)
        +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
        +DECLARE_ASN1_FUNCTIONS(X509_REQ)
        +
        +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
        +
        +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
        +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
        +
        +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
        +
        +DECLARE_ASN1_FUNCTIONS(X509_NAME)
        +
        +int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
        +
        +DECLARE_ASN1_FUNCTIONS(X509_CINF)
        +
        +DECLARE_ASN1_FUNCTIONS(X509)
        +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
        +
        +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
        +
        +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int X509_set_ex_data(X509 *r, int idx, void *arg);
        +void *X509_get_ex_data(X509 *r, int idx);
        +int		i2d_X509_AUX(X509 *a,unsigned char **pp);
        +X509 *		d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
        +
        +int X509_alias_set1(X509 *x, unsigned char *name, int len);
        +int X509_keyid_set1(X509 *x, unsigned char *id, int len);
        +unsigned char * X509_alias_get0(X509 *x, int *len);
        +unsigned char * X509_keyid_get0(X509 *x, int *len);
        +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
        +int X509_TRUST_set(int *t, int trust);
        +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
        +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
        +void X509_trust_clear(X509 *x);
        +void X509_reject_clear(X509 *x);
        +
        +DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
        +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
        +DECLARE_ASN1_FUNCTIONS(X509_CRL)
        +
        +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
        +int X509_CRL_get0_by_serial(X509_CRL *crl,
        +		X509_REVOKED **ret, ASN1_INTEGER *serial);
        +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
        +
        +X509_PKEY *	X509_PKEY_new(void );
        +void		X509_PKEY_free(X509_PKEY *a);
        +int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
        +X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length);
        +
        +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
        +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
        +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
        +
        +#ifndef OPENSSL_NO_EVP
        +X509_INFO *	X509_INFO_new(void);
        +void		X509_INFO_free(X509_INFO *a);
        +char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
        +
        +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
        +		ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey);
        +
        +int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data,
        +		unsigned char *md,unsigned int *len);
        +
        +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
        +	      X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
        +	      char *data,EVP_PKEY *pkey, const EVP_MD *type);
        +
        +int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
        +	unsigned char *md,unsigned int *len);
        +
        +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
        +	ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
        +
        +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        +	ASN1_BIT_STRING *signature,
        +	void *data, EVP_PKEY *pkey, const EVP_MD *type);
        +int ASN1_item_sign_ctx(const ASN1_ITEM *it,
        +		X509_ALGOR *algor1, X509_ALGOR *algor2,
        +	     	ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx);
        +#endif
        +
        +int 		X509_set_version(X509 *x,long version);
        +int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
        +ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
        +int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
        +X509_NAME *	X509_get_issuer_name(X509 *a);
        +int 		X509_set_subject_name(X509 *x, X509_NAME *name);
        +X509_NAME *	X509_get_subject_name(X509 *a);
        +int 		X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
        +int 		X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
        +int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
        +EVP_PKEY *	X509_get_pubkey(X509 *x);
        +ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
        +int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
        +
        +int		X509_REQ_set_version(X509_REQ *x,long version);
        +int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
        +int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
        +EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
        +int		X509_REQ_extension_nid(int nid);
        +int *		X509_REQ_get_extension_nids(void);
        +void		X509_REQ_set_extension_nids(int *nids);
        +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
        +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
        +				int nid);
        +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
        +int X509_REQ_get_attr_count(const X509_REQ *req);
        +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
        +			  int lastpos);
        +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
        +			  int lastpos);
        +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
        +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
        +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
        +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
        +			const ASN1_OBJECT *obj, int type,
        +			const unsigned char *bytes, int len);
        +int X509_REQ_add1_attr_by_NID(X509_REQ *req,
        +			int nid, int type,
        +			const unsigned char *bytes, int len);
        +int X509_REQ_add1_attr_by_txt(X509_REQ *req,
        +			const char *attrname, int type,
        +			const unsigned char *bytes, int len);
        +
        +int X509_CRL_set_version(X509_CRL *x, long version);
        +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
        +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
        +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
        +int X509_CRL_sort(X509_CRL *crl);
        +
        +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
        +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
        +
        +int		X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
        +
        +int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
        +
        +int		X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
        +unsigned long	X509_issuer_and_serial_hash(X509 *a);
        +
        +int		X509_issuer_name_cmp(const X509 *a, const X509 *b);
        +unsigned long	X509_issuer_name_hash(X509 *a);
        +
        +int		X509_subject_name_cmp(const X509 *a, const X509 *b);
        +unsigned long	X509_subject_name_hash(X509 *x);
        +
        +#ifndef OPENSSL_NO_MD5
        +unsigned long	X509_issuer_name_hash_old(X509 *a);
        +unsigned long	X509_subject_name_hash_old(X509 *x);
        +#endif
        +
        +int		X509_cmp(const X509 *a, const X509 *b);
        +int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
        +unsigned long	X509_NAME_hash(X509_NAME *x);
        +unsigned long	X509_NAME_hash_old(X509_NAME *x);
        +
        +int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
        +int		X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
        +#ifndef OPENSSL_NO_FP_API
        +int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
        +int		X509_print_fp(FILE *bp,X509 *x);
        +int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
        +int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
        +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
        +#endif
        +
        +#ifndef OPENSSL_NO_BIO
        +int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
        +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
        +int		X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
        +int		X509_print(BIO *bp,X509 *x);
        +int		X509_ocspid_print(BIO *bp,X509 *x);
        +int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
        +int		X509_CRL_print(BIO *bp,X509_CRL *x);
        +int		X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
        +int		X509_REQ_print(BIO *bp,X509_REQ *req);
        +#endif
        +
        +int 		X509_NAME_entry_count(X509_NAME *name);
        +int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
        +			char *buf,int len);
        +int		X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
        +			char *buf,int len);
        +
        +/* NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
        + * lastpos, search after that position on. */
        +int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
        +int 		X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj,
        +			int lastpos);
        +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
        +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
        +int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
        +			int loc, int set);
        +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
        +			unsigned char *bytes, int len, int loc, int set);
        +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
        +			unsigned char *bytes, int len, int loc, int set);
        +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
        +		const char *field, int type, const unsigned char *bytes, int len);
        +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
        +			int type,unsigned char *bytes, int len);
        +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
        +			const unsigned char *bytes, int len, int loc, int set);
        +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
        +			ASN1_OBJECT *obj, int type,const unsigned char *bytes,
        +			int len);
        +int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
        +			ASN1_OBJECT *obj);
        +int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
        +			const unsigned char *bytes, int len);
        +ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
        +ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
        +
        +int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
        +int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
        +				      int nid, int lastpos);
        +int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
        +				      ASN1_OBJECT *obj,int lastpos);
        +int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
        +					   int crit, int lastpos);
        +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
        +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
        +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
        +					 X509_EXTENSION *ex, int loc);
        +
        +int		X509_get_ext_count(X509 *x);
        +int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
        +int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
        +int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
        +X509_EXTENSION *X509_get_ext(X509 *x, int loc);
        +X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
        +int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
        +void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
        +int		X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +
        +int		X509_CRL_get_ext_count(X509_CRL *x);
        +int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
        +int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
        +int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
        +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
        +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
        +int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
        +void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
        +int		X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +
        +int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
        +int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
        +int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
        +int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
        +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
        +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
        +int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
        +void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
        +int		X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
        +							unsigned long flags);
        +
        +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
        +			int nid, int crit, ASN1_OCTET_STRING *data);
        +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
        +			ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data);
        +int		X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj);
        +int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
        +int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
        +			ASN1_OCTET_STRING *data);
        +ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
        +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
        +int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
        +
        +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
        +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
        +			  int lastpos);
        +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
        +			  int lastpos);
        +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
        +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
        +					 X509_ATTRIBUTE *attr);
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
        +			const ASN1_OBJECT *obj, int type,
        +			const unsigned char *bytes, int len);
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
        +			int nid, int type,
        +			const unsigned char *bytes, int len);
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
        +			const char *attrname, int type,
        +			const unsigned char *bytes, int len);
        +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
        +				ASN1_OBJECT *obj, int lastpos, int type);
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
        +	     int atrtype, const void *data, int len);
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
        +	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len);
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
        +		const char *atrname, int type, const unsigned char *bytes, int len);
        +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
        +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
        +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
        +					int atrtype, void *data);
        +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
        +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
        +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
        +
        +int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
        +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
        +			  int lastpos);
        +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
        +			  int lastpos);
        +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
        +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
        +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
        +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
        +			const ASN1_OBJECT *obj, int type,
        +			const unsigned char *bytes, int len);
        +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
        +			int nid, int type,
        +			const unsigned char *bytes, int len);
        +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
        +			const char *attrname, int type,
        +			const unsigned char *bytes, int len);
        +
        +int		X509_verify_cert(X509_STORE_CTX *ctx);
        +
        +/* lookup a cert from a X509 STACK */
        +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
        +				     ASN1_INTEGER *serial);
        +X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
        +
        +DECLARE_ASN1_FUNCTIONS(PBEPARAM)
        +DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
        +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
        +
        +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
        +				const unsigned char *salt, int saltlen);
        +
        +X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
        +				const unsigned char *salt, int saltlen);
        +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
        +					 unsigned char *salt, int saltlen);
        +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
        +				 unsigned char *salt, int saltlen,
        +				 unsigned char *aiv, int prf_nid);
        +
        +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
        +				int prf_nid, int keylen);
        +
        +/* PKCS#8 utilities */
        +
        +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
        +
        +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
        +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
        +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
        +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
        +
        +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
        +			int version, int ptype, void *pval,
        +				unsigned char *penc, int penclen);
        +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
        +		const unsigned char **pk, int *ppklen,
        +		X509_ALGOR **pa,
        +		PKCS8_PRIV_KEY_INFO *p8);
        +
        +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
        +					int ptype, void *pval,
        +					unsigned char *penc, int penclen);
        +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
        +		const unsigned char **pk, int *ppklen,
        +		X509_ALGOR **pa,
        +		X509_PUBKEY *pub);
        +
        +int X509_check_trust(X509 *x, int id, int flags);
        +int X509_TRUST_get_count(void);
        +X509_TRUST * X509_TRUST_get0(int idx);
        +int X509_TRUST_get_by_id(int id);
        +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
        +					char *name, int arg1, void *arg2);
        +void X509_TRUST_cleanup(void);
        +int X509_TRUST_get_flags(X509_TRUST *xp);
        +char *X509_TRUST_get0_name(X509_TRUST *xp);
        +int X509_TRUST_get_trust(X509_TRUST *xp);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_X509_strings(void);
        +
        +/* Error codes for the X509 functions. */
        +
        +/* Function codes. */
        +#define X509_F_ADD_CERT_DIR				 100
        +#define X509_F_BY_FILE_CTRL				 101
        +#define X509_F_CHECK_POLICY				 145
        +#define X509_F_DIR_CTRL					 102
        +#define X509_F_GET_CERT_BY_SUBJECT			 103
        +#define X509_F_NETSCAPE_SPKI_B64_DECODE			 129
        +#define X509_F_NETSCAPE_SPKI_B64_ENCODE			 130
        +#define X509_F_X509AT_ADD1_ATTR				 135
        +#define X509_F_X509V3_ADD_EXT				 104
        +#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID		 136
        +#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ		 137
        +#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT		 140
        +#define X509_F_X509_ATTRIBUTE_GET0_DATA			 139
        +#define X509_F_X509_ATTRIBUTE_SET1_DATA			 138
        +#define X509_F_X509_CHECK_PRIVATE_KEY			 128
        +#define X509_F_X509_CRL_PRINT_FP			 147
        +#define X509_F_X509_EXTENSION_CREATE_BY_NID		 108
        +#define X509_F_X509_EXTENSION_CREATE_BY_OBJ		 109
        +#define X509_F_X509_GET_PUBKEY_PARAMETERS		 110
        +#define X509_F_X509_LOAD_CERT_CRL_FILE			 132
        +#define X509_F_X509_LOAD_CERT_FILE			 111
        +#define X509_F_X509_LOAD_CRL_FILE			 112
        +#define X509_F_X509_NAME_ADD_ENTRY			 113
        +#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID		 114
        +#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT		 131
        +#define X509_F_X509_NAME_ENTRY_SET_OBJECT		 115
        +#define X509_F_X509_NAME_ONELINE			 116
        +#define X509_F_X509_NAME_PRINT				 117
        +#define X509_F_X509_PRINT_EX_FP				 118
        +#define X509_F_X509_PUBKEY_GET				 119
        +#define X509_F_X509_PUBKEY_SET				 120
        +#define X509_F_X509_REQ_CHECK_PRIVATE_KEY		 144
        +#define X509_F_X509_REQ_PRINT_EX			 121
        +#define X509_F_X509_REQ_PRINT_FP			 122
        +#define X509_F_X509_REQ_TO_X509				 123
        +#define X509_F_X509_STORE_ADD_CERT			 124
        +#define X509_F_X509_STORE_ADD_CRL			 125
        +#define X509_F_X509_STORE_CTX_GET1_ISSUER		 146
        +#define X509_F_X509_STORE_CTX_INIT			 143
        +#define X509_F_X509_STORE_CTX_NEW			 142
        +#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT		 134
        +#define X509_F_X509_TO_X509_REQ				 126
        +#define X509_F_X509_TRUST_ADD				 133
        +#define X509_F_X509_TRUST_SET				 141
        +#define X509_F_X509_VERIFY_CERT				 127
        +
        +/* Reason codes. */
        +#define X509_R_BAD_X509_FILETYPE			 100
        +#define X509_R_BASE64_DECODE_ERROR			 118
        +#define X509_R_CANT_CHECK_DH_KEY			 114
        +#define X509_R_CERT_ALREADY_IN_HASH_TABLE		 101
        +#define X509_R_ERR_ASN1_LIB				 102
        +#define X509_R_INVALID_DIRECTORY			 113
        +#define X509_R_INVALID_FIELD_NAME			 119
        +#define X509_R_INVALID_TRUST				 123
        +#define X509_R_KEY_TYPE_MISMATCH			 115
        +#define X509_R_KEY_VALUES_MISMATCH			 116
        +#define X509_R_LOADING_CERT_DIR				 103
        +#define X509_R_LOADING_DEFAULTS				 104
        +#define X509_R_METHOD_NOT_SUPPORTED			 124
        +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
        +#define X509_R_PUBLIC_KEY_DECODE_ERROR			 125
        +#define X509_R_PUBLIC_KEY_ENCODE_ERROR			 126
        +#define X509_R_SHOULD_RETRY				 106
        +#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
        +#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
        +#define X509_R_UNKNOWN_KEY_TYPE				 117
        +#define X509_R_UNKNOWN_NID				 109
        +#define X509_R_UNKNOWN_PURPOSE_ID			 121
        +#define X509_R_UNKNOWN_TRUST_ID				 120
        +#define X509_R_UNSUPPORTED_ALGORITHM			 111
        +#define X509_R_WRONG_LOOKUP_TYPE			 112
        +#define X509_R_WRONG_TYPE				 122
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_att.c b/vendor/openssl/openssl/crypto/x509/x509_att.c
        new file mode 100644
        index 000000000..98460e892
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_att.c
        @@ -0,0 +1,359 @@
        +/* crypto/x509/x509_att.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/stack.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
        +{
        +	return sk_X509_ATTRIBUTE_num(x);
        +}
        +
        +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
        +			  int lastpos)
        +{
        +	ASN1_OBJECT *obj;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL) return(-2);
        +	return(X509at_get_attr_by_OBJ(x,obj,lastpos));
        +}
        +
        +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
        +			  int lastpos)
        +{
        +	int n;
        +	X509_ATTRIBUTE *ex;
        +
        +	if (sk == NULL) return(-1);
        +	lastpos++;
        +	if (lastpos < 0)
        +		lastpos=0;
        +	n=sk_X509_ATTRIBUTE_num(sk);
        +	for ( ; lastpos < n; lastpos++)
        +		{
        +		ex=sk_X509_ATTRIBUTE_value(sk,lastpos);
        +		if (OBJ_cmp(ex->object,obj) == 0)
        +			return(lastpos);
        +		}
        +	return(-1);
        +}
        +
        +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
        +{
        +	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
        +		return NULL;
        +	else
        +		return sk_X509_ATTRIBUTE_value(x,loc);
        +}
        +
        +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
        +{
        +	X509_ATTRIBUTE *ret;
        +
        +	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
        +		return(NULL);
        +	ret=sk_X509_ATTRIBUTE_delete(x,loc);
        +	return(ret);
        +}
        +
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
        +					 X509_ATTRIBUTE *attr)
        +{
        +	X509_ATTRIBUTE *new_attr=NULL;
        +	STACK_OF(X509_ATTRIBUTE) *sk=NULL;
        +
        +	if (x == NULL)
        +		{
        +		X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER);
        +		goto err2;
        +		} 
        +
        +	if (*x == NULL)
        +		{
        +		if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL)
        +			goto err;
        +		}
        +	else
        +		sk= *x;
        +
        +	if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
        +		goto err2;
        +	if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
        +		goto err;
        +	if (*x == NULL)
        +		*x=sk;
        +	return(sk);
        +err:
        +	X509err(X509_F_X509AT_ADD1_ATTR,ERR_R_MALLOC_FAILURE);
        +err2:
        +	if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
        +	if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
        +	return(NULL);
        +}
        +
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
        +			const ASN1_OBJECT *obj, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	X509_ATTRIBUTE *attr;
        +	STACK_OF(X509_ATTRIBUTE) *ret;
        +	attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
        +	if(!attr) return 0;
        +	ret = X509at_add1_attr(x, attr);
        +	X509_ATTRIBUTE_free(attr);
        +	return ret;
        +}
        +
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
        +			int nid, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	X509_ATTRIBUTE *attr;
        +	STACK_OF(X509_ATTRIBUTE) *ret;
        +	attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
        +	if(!attr) return 0;
        +	ret = X509at_add1_attr(x, attr);
        +	X509_ATTRIBUTE_free(attr);
        +	return ret;
        +}
        +
        +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
        +			const char *attrname, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	X509_ATTRIBUTE *attr;
        +	STACK_OF(X509_ATTRIBUTE) *ret;
        +	attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
        +	if(!attr) return 0;
        +	ret = X509at_add1_attr(x, attr);
        +	X509_ATTRIBUTE_free(attr);
        +	return ret;
        +}
        +
        +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
        +				ASN1_OBJECT *obj, int lastpos, int type)
        +{
        +	int i;
        +	X509_ATTRIBUTE *at;
        +	i = X509at_get_attr_by_OBJ(x, obj, lastpos);
        +	if (i == -1)
        +		return NULL;
        +	if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
        +		return NULL;
        +	at = X509at_get_attr(x, i);
        +	if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
        +		return NULL;
        +	return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
        +}
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
        +	     int atrtype, const void *data, int len)
        +{
        +	ASN1_OBJECT *obj;
        +	X509_ATTRIBUTE *ret;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID,X509_R_UNKNOWN_NID);
        +		return(NULL);
        +		}
        +	ret=X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
        +	if (ret == NULL) ASN1_OBJECT_free(obj);
        +	return(ret);
        +}
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
        +	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len)
        +{
        +	X509_ATTRIBUTE *ret;
        +
        +	if ((attr == NULL) || (*attr == NULL))
        +		{
        +		if ((ret=X509_ATTRIBUTE_new()) == NULL)
        +			{
        +			X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		}
        +	else
        +		ret= *attr;
        +
        +	if (!X509_ATTRIBUTE_set1_object(ret,obj))
        +		goto err;
        +	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
        +		goto err;
        +
        +	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
        +	return(ret);
        +err:
        +	if ((attr == NULL) || (ret != *attr))
        +		X509_ATTRIBUTE_free(ret);
        +	return(NULL);
        +}
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
        +		const char *atrname, int type, const unsigned char *bytes, int len)
        +	{
        +	ASN1_OBJECT *obj;
        +	X509_ATTRIBUTE *nattr;
        +
        +	obj=OBJ_txt2obj(atrname, 0);
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
        +						X509_R_INVALID_FIELD_NAME);
        +		ERR_add_error_data(2, "name=", atrname);
        +		return(NULL);
        +		}
        +	nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
        +	ASN1_OBJECT_free(obj);
        +	return nattr;
        +	}
        +
        +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
        +{
        +	if ((attr == NULL) || (obj == NULL))
        +		return(0);
        +	ASN1_OBJECT_free(attr->object);
        +	attr->object=OBJ_dup(obj);
        +	return(1);
        +}
        +
        +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len)
        +{
        +	ASN1_TYPE *ttmp;
        +	ASN1_STRING *stmp = NULL;
        +	int atype = 0;
        +	if (!attr) return 0;
        +	if(attrtype & MBSTRING_FLAG) {
        +		stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
        +						OBJ_obj2nid(attr->object));
        +		if(!stmp) {
        +			X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
        +			return 0;
        +		}
        +		atype = stmp->type;
        +	} else if (len != -1){
        +		if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err;
        +		if(!ASN1_STRING_set(stmp, data, len)) goto err;
        +		atype = attrtype;
        +	}
        +	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
        +	attr->single = 0;
        +	/* This is a bit naughty because the attribute should really have
        +	 * at least one value but some types use and zero length SET and
        +	 * require this.
        +	 */
        +	if (attrtype == 0)
        +		return 1;
        +	if(!(ttmp = ASN1_TYPE_new())) goto err;
        +	if ((len == -1) && !(attrtype & MBSTRING_FLAG))
        +		{
        +		if (!ASN1_TYPE_set1(ttmp, attrtype, data))
        +			goto err;
        +		}
        +	else
        +		ASN1_TYPE_set(ttmp, atype, stmp);
        +	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
        +	return 1;
        +	err:
        +	X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +}
        +
        +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
        +{
        +	if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set);
        +	if(attr->value.single) return 1;
        +	return 0;
        +}
        +
        +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
        +{
        +	if (attr == NULL) return(NULL);
        +	return(attr->object);
        +}
        +
        +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
        +					int atrtype, void *data)
        +{
        +	ASN1_TYPE *ttmp;
        +	ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
        +	if(!ttmp) return NULL;
        +	if(atrtype != ASN1_TYPE_get(ttmp)){
        +		X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
        +		return NULL;
        +	}
        +	return ttmp->value.ptr;
        +}
        +
        +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
        +{
        +	if (attr == NULL) return(NULL);
        +	if(idx >= X509_ATTRIBUTE_count(attr)) return NULL;
        +	if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx);
        +	else return attr->value.single;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_cmp.c b/vendor/openssl/openssl/crypto/x509/x509_cmp.c
        new file mode 100644
        index 000000000..352aa3743
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_cmp.c
        @@ -0,0 +1,343 @@
        +/* crypto/x509/x509_cmp.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
        +	{
        +	int i;
        +	X509_CINF *ai,*bi;
        +
        +	ai=a->cert_info;
        +	bi=b->cert_info;
        +	i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
        +	if (i) return(i);
        +	return(X509_NAME_cmp(ai->issuer,bi->issuer));
        +	}
        +
        +#ifndef OPENSSL_NO_MD5
        +unsigned long X509_issuer_and_serial_hash(X509 *a)
        +	{
        +	unsigned long ret=0;
        +	EVP_MD_CTX ctx;
        +	unsigned char md[16];
        +	char *f;
        +
        +	EVP_MD_CTX_init(&ctx);
        +	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
        +	if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
        +		goto err;
        +	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
        +		goto err;
        +	OPENSSL_free(f);
        +	if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
        +		(unsigned long)a->cert_info->serialNumber->length))
        +		goto err;
        +	if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
        +		goto err;
        +	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
        +		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
        +		)&0xffffffffL;
        +	err:
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return(ret);
        +	}
        +#endif
        +	
        +int X509_issuer_name_cmp(const X509 *a, const X509 *b)
        +	{
        +	return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
        +	}
        +
        +int X509_subject_name_cmp(const X509 *a, const X509 *b)
        +	{
        +	return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
        +	}
        +
        +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
        +	{
        +	return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
        +	}
        +
        +#ifndef OPENSSL_NO_SHA
        +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
        +	{
        +	return memcmp(a->sha1_hash, b->sha1_hash, 20);
        +	}
        +#endif
        +
        +X509_NAME *X509_get_issuer_name(X509 *a)
        +	{
        +	return(a->cert_info->issuer);
        +	}
        +
        +unsigned long X509_issuer_name_hash(X509 *x)
        +	{
        +	return(X509_NAME_hash(x->cert_info->issuer));
        +	}
        +
        +#ifndef OPENSSL_NO_MD5
        +unsigned long X509_issuer_name_hash_old(X509 *x)
        +	{
        +	return(X509_NAME_hash_old(x->cert_info->issuer));
        +	}
        +#endif
        +
        +X509_NAME *X509_get_subject_name(X509 *a)
        +	{
        +	return(a->cert_info->subject);
        +	}
        +
        +ASN1_INTEGER *X509_get_serialNumber(X509 *a)
        +	{
        +	return(a->cert_info->serialNumber);
        +	}
        +
        +unsigned long X509_subject_name_hash(X509 *x)
        +	{
        +	return(X509_NAME_hash(x->cert_info->subject));
        +	}
        +
        +#ifndef OPENSSL_NO_MD5
        +unsigned long X509_subject_name_hash_old(X509 *x)
        +	{
        +	return(X509_NAME_hash_old(x->cert_info->subject));
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA
        +/* Compare two certificates: they must be identical for
        + * this to work. NB: Although "cmp" operations are generally
        + * prototyped to take "const" arguments (eg. for use in
        + * STACKs), the way X509 handling is - these operations may
        + * involve ensuring the hashes are up-to-date and ensuring
        + * certain cert information is cached. So this is the point
        + * where the "depth-first" constification tree has to halt
        + * with an evil cast.
        + */
        +int X509_cmp(const X509 *a, const X509 *b)
        +{
        +	/* ensure hash is valid */
        +	X509_check_purpose((X509 *)a, -1, 0);
        +	X509_check_purpose((X509 *)b, -1, 0);
        +
        +	return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
        +}
        +#endif
        +
        +
        +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
        +	{
        +	int ret;
        +
        +	/* Ensure canonical encoding is present and up to date */
        +
        +	if (!a->canon_enc || a->modified)
        +		{
        +		ret = i2d_X509_NAME((X509_NAME *)a, NULL);
        +		if (ret < 0)
        +			return -2;
        +		}
        +
        +	if (!b->canon_enc || b->modified)
        +		{
        +		ret = i2d_X509_NAME((X509_NAME *)b, NULL);
        +		if (ret < 0)
        +			return -2;
        +		}
        +
        +	ret = a->canon_enclen - b->canon_enclen;
        +
        +	if (ret)
        +		return ret;
        +
        +	return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
        +
        +	}
        +
        +unsigned long X509_NAME_hash(X509_NAME *x)
        +	{
        +	unsigned long ret=0;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +
        +	/* Make sure X509_NAME structure contains valid cached encoding */
        +	i2d_X509_NAME(x,NULL);
        +	if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
        +		NULL))
        +		return 0;
        +
        +	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
        +		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
        +		)&0xffffffffL;
        +	return(ret);
        +	}
        +
        +
        +#ifndef OPENSSL_NO_MD5
        +/* I now DER encode the name and hash it.  Since I cache the DER encoding,
        + * this is reasonably efficient. */
        +
        +unsigned long X509_NAME_hash_old(X509_NAME *x)
        +	{
        +	EVP_MD_CTX md_ctx;
        +	unsigned long ret=0;
        +	unsigned char md[16];
        +
        +	/* Make sure X509_NAME structure contains valid cached encoding */
        +	i2d_X509_NAME(x,NULL);
        +	EVP_MD_CTX_init(&md_ctx);
        +	EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +	if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
        +	    && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
        +	    && EVP_DigestFinal_ex(&md_ctx,md,NULL))
        +		ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
        +		     ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
        +		     )&0xffffffffL;
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +
        +	return(ret);
        +	}
        +#endif
        +
        +/* Search a stack of X509 for a match */
        +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
        +		ASN1_INTEGER *serial)
        +	{
        +	int i;
        +	X509_CINF cinf;
        +	X509 x,*x509=NULL;
        +
        +	if(!sk) return NULL;
        +
        +	x.cert_info= &cinf;
        +	cinf.serialNumber=serial;
        +	cinf.issuer=name;
        +
        +	for (i=0; i<sk_X509_num(sk); i++)
        +		{
        +		x509=sk_X509_value(sk,i);
        +		if (X509_issuer_and_serial_cmp(x509,&x) == 0)
        +			return(x509);
        +		}
        +	return(NULL);
        +	}
        +
        +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
        +	{
        +	X509 *x509;
        +	int i;
        +
        +	for (i=0; i<sk_X509_num(sk); i++)
        +		{
        +		x509=sk_X509_value(sk,i);
        +		if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
        +			return(x509);
        +		}
        +	return(NULL);
        +	}
        +
        +EVP_PKEY *X509_get_pubkey(X509 *x)
        +	{
        +	if ((x == NULL) || (x->cert_info == NULL))
        +		return(NULL);
        +	return(X509_PUBKEY_get(x->cert_info->key));
        +	}
        +
        +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
        +	{
        +	if(!x) return NULL;
        +	return x->cert_info->key->public_key;
        +	}
        +
        +int X509_check_private_key(X509 *x, EVP_PKEY *k)
        +	{
        +	EVP_PKEY *xk;
        +	int ret;
        +
        +	xk=X509_get_pubkey(x);
        +
        +	if (xk)
        +		ret = EVP_PKEY_cmp(xk, k);
        +	else
        +		ret = -2;
        +
        +	switch (ret)
        +		{
        +	case 1:
        +		break;
        +	case 0:
        +		X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
        +		break;
        +	case -1:
        +		X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
        +		break;
        +	case -2:
        +	        X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
        +		}
        +	if (xk)
        +		EVP_PKEY_free(xk);
        +	if (ret > 0)
        +		return 1;
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_d2.c b/vendor/openssl/openssl/crypto/x509/x509_d2.c
        new file mode 100644
        index 000000000..51410cfd1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_d2.c
        @@ -0,0 +1,107 @@
        +/* crypto/x509/x509_d2.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/crypto.h>
        +#include <openssl/x509.h>
        +
        +#ifndef OPENSSL_NO_STDIO
        +int X509_STORE_set_default_paths(X509_STORE *ctx)
        +	{
        +	X509_LOOKUP *lookup;
        +
        +	lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
        +	if (lookup == NULL) return(0);
        +	X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
        +
        +	lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
        +	if (lookup == NULL) return(0);
        +	X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
        +	
        +	/* clear any errors */
        +	ERR_clear_error();
        +
        +	return(1);
        +	}
        +
        +int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
        +		const char *path)
        +	{
        +	X509_LOOKUP *lookup;
        +
        +	if (file != NULL)
        +		{
        +		lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file());
        +		if (lookup == NULL) return(0);
        +		if (X509_LOOKUP_load_file(lookup,file,X509_FILETYPE_PEM) != 1)
        +		    return(0);
        +		}
        +	if (path != NULL)
        +		{
        +		lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir());
        +		if (lookup == NULL) return(0);
        +		if (X509_LOOKUP_add_dir(lookup,path,X509_FILETYPE_PEM) != 1)
        +		    return(0);
        +		}
        +	if ((path == NULL) && (file == NULL))
        +		return(0);
        +	return(1);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_def.c b/vendor/openssl/openssl/crypto/x509/x509_def.c
        new file mode 100644
        index 000000000..e0ac151a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_def.c
        @@ -0,0 +1,81 @@
        +/* crypto/x509/x509_def.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/crypto.h>
        +#include <openssl/x509.h>
        +
        +const char *X509_get_default_private_dir(void)
        +	{ return(X509_PRIVATE_DIR); }
        +	
        +const char *X509_get_default_cert_area(void)
        +	{ return(X509_CERT_AREA); }
        +
        +const char *X509_get_default_cert_dir(void)
        +	{ return(X509_CERT_DIR); }
        +
        +const char *X509_get_default_cert_file(void)
        +	{ return(X509_CERT_FILE); }
        +
        +const char *X509_get_default_cert_dir_env(void)
        +	{ return(X509_CERT_DIR_EVP); }
        +
        +const char *X509_get_default_cert_file_env(void)
        +	{ return(X509_CERT_FILE_EVP); }
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_err.c b/vendor/openssl/openssl/crypto/x509/x509_err.c
        new file mode 100644
        index 000000000..a01402f41
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_err.c
        @@ -0,0 +1,164 @@
        +/* crypto/x509/x509_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2006 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/x509.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
        +
        +static ERR_STRING_DATA X509_str_functs[]=
        +	{
        +{ERR_FUNC(X509_F_ADD_CERT_DIR),	"ADD_CERT_DIR"},
        +{ERR_FUNC(X509_F_BY_FILE_CTRL),	"BY_FILE_CTRL"},
        +{ERR_FUNC(X509_F_CHECK_POLICY),	"CHECK_POLICY"},
        +{ERR_FUNC(X509_F_DIR_CTRL),	"DIR_CTRL"},
        +{ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT),	"GET_CERT_BY_SUBJECT"},
        +{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE),	"NETSCAPE_SPKI_b64_decode"},
        +{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE),	"NETSCAPE_SPKI_b64_encode"},
        +{ERR_FUNC(X509_F_X509AT_ADD1_ATTR),	"X509at_add1_attr"},
        +{ERR_FUNC(X509_F_X509V3_ADD_EXT),	"X509v3_add_ext"},
        +{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID),	"X509_ATTRIBUTE_create_by_NID"},
        +{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),	"X509_ATTRIBUTE_create_by_OBJ"},
        +{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),	"X509_ATTRIBUTE_create_by_txt"},
        +{ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA),	"X509_ATTRIBUTE_get0_data"},
        +{ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA),	"X509_ATTRIBUTE_set1_data"},
        +{ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY),	"X509_check_private_key"},
        +{ERR_FUNC(X509_F_X509_CRL_PRINT_FP),	"X509_CRL_print_fp"},
        +{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),	"X509_EXTENSION_create_by_NID"},
        +{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),	"X509_EXTENSION_create_by_OBJ"},
        +{ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),	"X509_get_pubkey_parameters"},
        +{ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE),	"X509_load_cert_crl_file"},
        +{ERR_FUNC(X509_F_X509_LOAD_CERT_FILE),	"X509_load_cert_file"},
        +{ERR_FUNC(X509_F_X509_LOAD_CRL_FILE),	"X509_load_crl_file"},
        +{ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY),	"X509_NAME_add_entry"},
        +{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID),	"X509_NAME_ENTRY_create_by_NID"},
        +{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),	"X509_NAME_ENTRY_create_by_txt"},
        +{ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),	"X509_NAME_ENTRY_set_object"},
        +{ERR_FUNC(X509_F_X509_NAME_ONELINE),	"X509_NAME_oneline"},
        +{ERR_FUNC(X509_F_X509_NAME_PRINT),	"X509_NAME_print"},
        +{ERR_FUNC(X509_F_X509_PRINT_EX_FP),	"X509_print_ex_fp"},
        +{ERR_FUNC(X509_F_X509_PUBKEY_GET),	"X509_PUBKEY_get"},
        +{ERR_FUNC(X509_F_X509_PUBKEY_SET),	"X509_PUBKEY_set"},
        +{ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY),	"X509_REQ_check_private_key"},
        +{ERR_FUNC(X509_F_X509_REQ_PRINT_EX),	"X509_REQ_print_ex"},
        +{ERR_FUNC(X509_F_X509_REQ_PRINT_FP),	"X509_REQ_print_fp"},
        +{ERR_FUNC(X509_F_X509_REQ_TO_X509),	"X509_REQ_to_X509"},
        +{ERR_FUNC(X509_F_X509_STORE_ADD_CERT),	"X509_STORE_add_cert"},
        +{ERR_FUNC(X509_F_X509_STORE_ADD_CRL),	"X509_STORE_add_crl"},
        +{ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER),	"X509_STORE_CTX_get1_issuer"},
        +{ERR_FUNC(X509_F_X509_STORE_CTX_INIT),	"X509_STORE_CTX_init"},
        +{ERR_FUNC(X509_F_X509_STORE_CTX_NEW),	"X509_STORE_CTX_new"},
        +{ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT),	"X509_STORE_CTX_purpose_inherit"},
        +{ERR_FUNC(X509_F_X509_TO_X509_REQ),	"X509_to_X509_REQ"},
        +{ERR_FUNC(X509_F_X509_TRUST_ADD),	"X509_TRUST_add"},
        +{ERR_FUNC(X509_F_X509_TRUST_SET),	"X509_TRUST_set"},
        +{ERR_FUNC(X509_F_X509_VERIFY_CERT),	"X509_verify_cert"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA X509_str_reasons[]=
        +	{
        +{ERR_REASON(X509_R_BAD_X509_FILETYPE)    ,"bad x509 filetype"},
        +{ERR_REASON(X509_R_BASE64_DECODE_ERROR)  ,"base64 decode error"},
        +{ERR_REASON(X509_R_CANT_CHECK_DH_KEY)    ,"cant check dh key"},
        +{ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),"cert already in hash table"},
        +{ERR_REASON(X509_R_ERR_ASN1_LIB)         ,"err asn1 lib"},
        +{ERR_REASON(X509_R_INVALID_DIRECTORY)    ,"invalid directory"},
        +{ERR_REASON(X509_R_INVALID_FIELD_NAME)   ,"invalid field name"},
        +{ERR_REASON(X509_R_INVALID_TRUST)        ,"invalid trust"},
        +{ERR_REASON(X509_R_KEY_TYPE_MISMATCH)    ,"key type mismatch"},
        +{ERR_REASON(X509_R_KEY_VALUES_MISMATCH)  ,"key values mismatch"},
        +{ERR_REASON(X509_R_LOADING_CERT_DIR)     ,"loading cert dir"},
        +{ERR_REASON(X509_R_LOADING_DEFAULTS)     ,"loading defaults"},
        +{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
        +{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"},
        +{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR),"public key decode error"},
        +{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR),"public key encode error"},
        +{ERR_REASON(X509_R_SHOULD_RETRY)         ,"should retry"},
        +{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"},
        +{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"},
        +{ERR_REASON(X509_R_UNKNOWN_KEY_TYPE)     ,"unknown key type"},
        +{ERR_REASON(X509_R_UNKNOWN_NID)          ,"unknown nid"},
        +{ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID)   ,"unknown purpose id"},
        +{ERR_REASON(X509_R_UNKNOWN_TRUST_ID)     ,"unknown trust id"},
        +{ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM),"unsupported algorithm"},
        +{ERR_REASON(X509_R_WRONG_LOOKUP_TYPE)    ,"wrong lookup type"},
        +{ERR_REASON(X509_R_WRONG_TYPE)           ,"wrong type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_X509_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(X509_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,X509_str_functs);
        +		ERR_load_strings(0,X509_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_ext.c b/vendor/openssl/openssl/crypto/x509/x509_ext.c
        new file mode 100644
        index 000000000..e7fdacb5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_ext.c
        @@ -0,0 +1,210 @@
        +/* crypto/x509/x509_ext.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/stack.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +
        +int X509_CRL_get_ext_count(X509_CRL *x)
        +	{
        +	return(X509v3_get_ext_count(x->crl->extensions));
        +	}
        +
        +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->crl->extensions,nid,lastpos));
        +	}
        +
        +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->crl->extensions,obj,lastpos));
        +	}
        +
        +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->crl->extensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->crl->extensions,loc));
        +	}
        +
        +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->crl->extensions,loc));
        +	}
        +
        +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
        +{
        +	return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
        +}
        +
        +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +{
        +	return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
        +}
        +
        +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->crl->extensions),ex,loc) != NULL);
        +	}
        +
        +int X509_get_ext_count(X509 *x)
        +	{
        +	return(X509v3_get_ext_count(x->cert_info->extensions));
        +	}
        +
        +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->cert_info->extensions,nid,lastpos));
        +	}
        +
        +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->cert_info->extensions,obj,lastpos));
        +	}
        +
        +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->cert_info->extensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *X509_get_ext(X509 *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->cert_info->extensions,loc));
        +	}
        +
        +X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->cert_info->extensions,loc));
        +	}
        +
        +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->cert_info->extensions),ex,loc) != NULL);
        +	}
        +
        +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
        +{
        +	return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
        +}
        +
        +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +{
        +	return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
        +							flags);
        +}
        +
        +int X509_REVOKED_get_ext_count(X509_REVOKED *x)
        +	{
        +	return(X509v3_get_ext_count(x->extensions));
        +	}
        +
        +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_NID(x->extensions,nid,lastpos));
        +	}
        +
        +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
        +	     int lastpos)
        +	{
        +	return(X509v3_get_ext_by_OBJ(x->extensions,obj,lastpos));
        +	}
        +
        +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos)
        +	{
        +	return(X509v3_get_ext_by_critical(x->extensions,crit,lastpos));
        +	}
        +
        +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
        +	{
        +	return(X509v3_get_ext(x->extensions,loc));
        +	}
        +
        +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
        +	{
        +	return(X509v3_delete_ext(x->extensions,loc));
        +	}
        +
        +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
        +	{
        +	return(X509v3_add_ext(&(x->extensions),ex,loc) != NULL);
        +	}
        +
        +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
        +{
        +	return X509V3_get_d2i(x->extensions, nid, crit, idx);
        +}
        +
        +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
        +							unsigned long flags)
        +{
        +	return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
        +}
        +
        +IMPLEMENT_STACK_OF(X509_EXTENSION)
        +IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_lu.c b/vendor/openssl/openssl/crypto/x509/x509_lu.c
        new file mode 100644
        index 000000000..38525a8cd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_lu.c
        @@ -0,0 +1,716 @@
        +/* crypto/x509/x509_lu.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
        +	{
        +	X509_LOOKUP *ret;
        +
        +	ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
        +	if (ret == NULL) return NULL;
        +
        +	ret->init=0;
        +	ret->skip=0;
        +	ret->method=method;
        +	ret->method_data=NULL;
        +	ret->store_ctx=NULL;
        +	if ((method->new_item != NULL) && !method->new_item(ret))
        +		{
        +		OPENSSL_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void X509_LOOKUP_free(X509_LOOKUP *ctx)
        +	{
        +	if (ctx == NULL) return;
        +	if (	(ctx->method != NULL) &&
        +		(ctx->method->free != NULL))
        +		(*ctx->method->free)(ctx);
        +	OPENSSL_free(ctx);
        +	}
        +
        +int X509_LOOKUP_init(X509_LOOKUP *ctx)
        +	{
        +	if (ctx->method == NULL) return 0;
        +	if (ctx->method->init != NULL)
        +		return ctx->method->init(ctx);
        +	else
        +		return 1;
        +	}
        +
        +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
        +	{
        +	if (ctx->method == NULL) return 0;
        +	if (ctx->method->shutdown != NULL)
        +		return ctx->method->shutdown(ctx);
        +	else
        +		return 1;
        +	}
        +
        +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
        +	     char **ret)
        +	{
        +	if (ctx->method == NULL) return -1;
        +	if (ctx->method->ctrl != NULL)
        +		return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
        +	else
        +		return 1;
        +	}
        +
        +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
        +	     X509_OBJECT *ret)
        +	{
        +	if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
        +		return X509_LU_FAIL;
        +	if (ctx->skip) return 0;
        +	return ctx->method->get_by_subject(ctx,type,name,ret);
        +	}
        +
        +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
        +	     ASN1_INTEGER *serial, X509_OBJECT *ret)
        +	{
        +	if ((ctx->method == NULL) ||
        +		(ctx->method->get_by_issuer_serial == NULL))
        +		return X509_LU_FAIL;
        +	return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
        +	}
        +
        +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
        +	     unsigned char *bytes, int len, X509_OBJECT *ret)
        +	{
        +	if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
        +		return X509_LU_FAIL;
        +	return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
        +	}
        +
        +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
        +	     X509_OBJECT *ret)
        +	{
        +	if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
        +		return X509_LU_FAIL;
        +	return ctx->method->get_by_alias(ctx,type,str,len,ret);
        +	}
        +
        +  
        +static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
        +  	{
        + 	int ret;
        +
        + 	ret=((*a)->type - (*b)->type);
        + 	if (ret) return ret;
        + 	switch ((*a)->type)
        + 		{
        + 	case X509_LU_X509:
        + 		ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
        + 		break;
        + 	case X509_LU_CRL:
        + 		ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
        + 		break;
        +	default:
        +		/* abort(); */
        +		return 0;
        +		}
        +	return ret;
        +	}
        +
        +X509_STORE *X509_STORE_new(void)
        +	{
        +	X509_STORE *ret;
        +
        +	if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
        +		return NULL;
        +	ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
        +	ret->cache=1;
        +	ret->get_cert_methods=sk_X509_LOOKUP_new_null();
        +	ret->verify=0;
        +	ret->verify_cb=0;
        +
        +	if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
        +		return NULL;
        +
        +	ret->get_issuer = 0;
        +	ret->check_issued = 0;
        +	ret->check_revocation = 0;
        +	ret->get_crl = 0;
        +	ret->check_crl = 0;
        +	ret->cert_crl = 0;
        +	ret->lookup_certs = 0;
        +	ret->lookup_crls = 0;
        +	ret->cleanup = 0;
        +
        +	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
        +		{
        +		sk_X509_OBJECT_free(ret->objs);
        +		OPENSSL_free(ret);
        +		return NULL;
        +		}
        +
        +	ret->references=1;
        +	return ret;
        +	}
        +
        +static void cleanup(X509_OBJECT *a)
        +	{
        +	if (a->type == X509_LU_X509)
        +		{
        +		X509_free(a->data.x509);
        +		}
        +	else if (a->type == X509_LU_CRL)
        +		{
        +		X509_CRL_free(a->data.crl);
        +		}
        +	else
        +		{
        +		/* abort(); */
        +		}
        +
        +	OPENSSL_free(a);
        +	}
        +
        +void X509_STORE_free(X509_STORE *vfy)
        +	{
        +	int i;
        +	STACK_OF(X509_LOOKUP) *sk;
        +	X509_LOOKUP *lu;
        +
        +	if (vfy == NULL)
        +	    return;
        +
        +	sk=vfy->get_cert_methods;
        +	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
        +		{
        +		lu=sk_X509_LOOKUP_value(sk,i);
        +		X509_LOOKUP_shutdown(lu);
        +		X509_LOOKUP_free(lu);
        +		}
        +	sk_X509_LOOKUP_free(sk);
        +	sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
        +	if (vfy->param)
        +		X509_VERIFY_PARAM_free(vfy->param);
        +	OPENSSL_free(vfy);
        +	}
        +
        +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
        +	{
        +	int i;
        +	STACK_OF(X509_LOOKUP) *sk;
        +	X509_LOOKUP *lu;
        +
        +	sk=v->get_cert_methods;
        +	for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
        +		{
        +		lu=sk_X509_LOOKUP_value(sk,i);
        +		if (m == lu->method)
        +			{
        +			return lu;
        +			}
        +		}
        +	/* a new one */
        +	lu=X509_LOOKUP_new(m);
        +	if (lu == NULL)
        +		return NULL;
        +	else
        +		{
        +		lu->store_ctx=v;
        +		if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
        +			return lu;
        +		else
        +			{
        +			X509_LOOKUP_free(lu);
        +			return NULL;
        +			}
        +		}
        +	}
        +
        +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
        +	     X509_OBJECT *ret)
        +	{
        +	X509_STORE *ctx=vs->ctx;
        +	X509_LOOKUP *lu;
        +	X509_OBJECT stmp,*tmp;
        +	int i,j;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +
        +	if (tmp == NULL || type == X509_LU_CRL)
        +		{
        +		for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
        +			{
        +			lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
        +			j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
        +			if (j < 0)
        +				{
        +				vs->current_method=j;
        +				return j;
        +				}
        +			else if (j)
        +				{
        +				tmp= &stmp;
        +				break;
        +				}
        +			}
        +		vs->current_method=0;
        +		if (tmp == NULL)
        +			return 0;
        +		}
        +
        +/*	if (ret->data.ptr != NULL)
        +		X509_OBJECT_free_contents(ret); */
        +
        +	ret->type=tmp->type;
        +	ret->data.ptr=tmp->data.ptr;
        +
        +	X509_OBJECT_up_ref_count(ret);
        +
        +	return 1;
        +	}
        +
        +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
        +	{
        +	X509_OBJECT *obj;
        +	int ret=1;
        +
        +	if (x == NULL) return 0;
        +	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	obj->type=X509_LU_X509;
        +	obj->data.x509=x;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +
        +	X509_OBJECT_up_ref_count(obj);
        +
        +	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
        +		{
        +		X509_OBJECT_free_contents(obj);
        +		OPENSSL_free(obj);
        +		X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE);
        +		ret=0;
        +		} 
        +	else sk_X509_OBJECT_push(ctx->objs, obj);
        +
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +
        +	return ret;
        +	}
        +
        +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
        +	{
        +	X509_OBJECT *obj;
        +	int ret=1;
        +
        +	if (x == NULL) return 0;
        +	obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	obj->type=X509_LU_CRL;
        +	obj->data.crl=x;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +
        +	X509_OBJECT_up_ref_count(obj);
        +
        +	if (X509_OBJECT_retrieve_match(ctx->objs, obj))
        +		{
        +		X509_OBJECT_free_contents(obj);
        +		OPENSSL_free(obj);
        +		X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE);
        +		ret=0;
        +		}
        +	else sk_X509_OBJECT_push(ctx->objs, obj);
        +
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +
        +	return ret;
        +	}
        +
        +void X509_OBJECT_up_ref_count(X509_OBJECT *a)
        +	{
        +	switch (a->type)
        +		{
        +	case X509_LU_X509:
        +		CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
        +		break;
        +	case X509_LU_CRL:
        +		CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
        +		break;
        +		}
        +	}
        +
        +void X509_OBJECT_free_contents(X509_OBJECT *a)
        +	{
        +	switch (a->type)
        +		{
        +	case X509_LU_X509:
        +		X509_free(a->data.x509);
        +		break;
        +	case X509_LU_CRL:
        +		X509_CRL_free(a->data.crl);
        +		break;
        +		}
        +	}
        +
        +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
        +	     X509_NAME *name, int *pnmatch)
        +	{
        +	X509_OBJECT stmp;
        +	X509 x509_s;
        +	X509_CINF cinf_s;
        +	X509_CRL crl_s;
        +	X509_CRL_INFO crl_info_s;
        +	int idx;
        +
        +	stmp.type=type;
        +	switch (type)
        +		{
        +	case X509_LU_X509:
        +		stmp.data.x509= &x509_s;
        +		x509_s.cert_info= &cinf_s;
        +		cinf_s.subject=name;
        +		break;
        +	case X509_LU_CRL:
        +		stmp.data.crl= &crl_s;
        +		crl_s.crl= &crl_info_s;
        +		crl_info_s.issuer=name;
        +		break;
        +	default:
        +		/* abort(); */
        +		return -1;
        +		}
        +
        +	idx = sk_X509_OBJECT_find(h,&stmp);
        +	if (idx >= 0 && pnmatch)
        +		{
        +		int tidx;
        +		const X509_OBJECT *tobj, *pstmp;
        +		*pnmatch = 1;
        +		pstmp = &stmp;
        +		for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++)
        +			{
        +			tobj = sk_X509_OBJECT_value(h, tidx);
        +			if (x509_object_cmp(&tobj, &pstmp))
        +				break;
        +			(*pnmatch)++;
        +			}
        +		}
        +	return idx;
        +	}
        +
        +
        +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
        +	     X509_NAME *name)
        +	{
        +	return x509_object_idx_cnt(h, type, name, NULL);
        +	}
        +
        +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
        +	     X509_NAME *name)
        +	{
        +	int idx;
        +	idx = X509_OBJECT_idx_by_subject(h, type, name);
        +	if (idx==-1) return NULL;
        +	return sk_X509_OBJECT_value(h, idx);
        +	}
        +
        +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
        +	{
        +	int i, idx, cnt;
        +	STACK_OF(X509) *sk;
        +	X509 *x;
        +	X509_OBJECT *obj;
        +	sk = sk_X509_new_null();
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
        +	if (idx < 0)
        +		{
        +		/* Nothing found in cache: do lookup to possibly add new
        +		 * objects to cache
        +		 */
        +		X509_OBJECT xobj;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +		if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
        +			{
        +			sk_X509_free(sk);
        +			return NULL;
        +			}
        +		X509_OBJECT_free_contents(&xobj);
        +		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
        +		if (idx < 0)
        +			{
        +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +			sk_X509_free(sk);
        +			return NULL;
        +			}
        +		}
        +	for (i = 0; i < cnt; i++, idx++)
        +		{
        +		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
        +		x = obj->data.x509;
        +		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
        +		if (!sk_X509_push(sk, x))
        +			{
        +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +			X509_free(x);
        +			sk_X509_pop_free(sk, X509_free);
        +			return NULL;
        +			}
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +	return sk;
        +
        +	}
        +
        +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
        +	{
        +	int i, idx, cnt;
        +	STACK_OF(X509_CRL) *sk;
        +	X509_CRL *x;
        +	X509_OBJECT *obj, xobj;
        +	sk = sk_X509_CRL_new_null();
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +	/* Check cache first */
        +	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
        +
        +	/* Always do lookup to possibly add new CRLs to cache
        +	 */
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +	if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
        +		{
        +		sk_X509_CRL_free(sk);
        +		return NULL;
        +		}
        +	X509_OBJECT_free_contents(&xobj);
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
        +	if (idx < 0)
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +		sk_X509_CRL_free(sk);
        +		return NULL;
        +		}
        +
        +	for (i = 0; i < cnt; i++, idx++)
        +		{
        +		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
        +		x = obj->data.crl;
        +		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
        +		if (!sk_X509_CRL_push(sk, x))
        +			{
        +			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +			X509_CRL_free(x);
        +			sk_X509_CRL_pop_free(sk, X509_CRL_free);
        +			return NULL;
        +			}
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +	return sk;
        +	}
        +
        +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
        +	{
        +	int idx, i;
        +	X509_OBJECT *obj;
        +	idx = sk_X509_OBJECT_find(h, x);
        +	if (idx == -1) return NULL;
        +	if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
        +		return sk_X509_OBJECT_value(h, idx);
        +	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
        +		{
        +		obj = sk_X509_OBJECT_value(h, i);
        +		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
        +			return NULL;
        +		if (x->type == X509_LU_X509)
        +			{
        +			if (!X509_cmp(obj->data.x509, x->data.x509))
        +				return obj;
        +			}
        +		else if (x->type == X509_LU_CRL)
        +			{
        +			if (!X509_CRL_match(obj->data.crl, x->data.crl))
        +				return obj;
        +			}
        +		else
        +			return obj;
        +		}
        +	return NULL;
        +	}
        +
        +
        +/* Try to get issuer certificate from store. Due to limitations
        + * of the API this can only retrieve a single certificate matching
        + * a given subject name. However it will fill the cache with all
        + * matching certificates, so we can examine the cache for all
        + * matches.
        + *
        + * Return values are:
        + *  1 lookup successful.
        + *  0 certificate not found.
        + * -1 some other error.
        + */
        +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
        +	{
        +	X509_NAME *xn;
        +	X509_OBJECT obj, *pobj;
        +	int i, ok, idx, ret;
        +	xn=X509_get_issuer_name(x);
        +	ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
        +	if (ok != X509_LU_X509)
        +		{
        +		if (ok == X509_LU_RETRY)
        +			{
        +			X509_OBJECT_free_contents(&obj);
        +			X509err(X509_F_X509_STORE_CTX_GET1_ISSUER,X509_R_SHOULD_RETRY);
        +			return -1;
        +			}
        +		else if (ok != X509_LU_FAIL)
        +			{
        +			X509_OBJECT_free_contents(&obj);
        +			/* not good :-(, break anyway */
        +			return -1;
        +			}
        +		return 0;
        +		}
        +	/* If certificate matches all OK */
        +	if (ctx->check_issued(ctx, x, obj.data.x509))
        +		{
        +		*issuer = obj.data.x509;
        +		return 1;
        +		}
        +	X509_OBJECT_free_contents(&obj);
        +
        +	/* Else find index of first cert accepted by 'check_issued' */
        +	ret = 0;
        +	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +	idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
        +	if (idx != -1) /* should be true as we've had at least one match */
        +		{
        +		/* Look through all matching certs for suitable issuer */
        +		for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
        +			{
        +			pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
        +			/* See if we've run past the matches */
        +			if (pobj->type != X509_LU_X509)
        +				break;
        +			if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
        +				break;
        +			if (ctx->check_issued(ctx, x, pobj->data.x509))
        +				{
        +				*issuer = pobj->data.x509;
        +				X509_OBJECT_up_ref_count(pobj);
        +				ret = 1;
        +				break;
        +				}
        +			}
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +	return ret;
        +	}
        +
        +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
        +	{
        +	return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
        +	}
        +
        +int X509_STORE_set_depth(X509_STORE *ctx, int depth)
        +	{
        +	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
        +	return 1;
        +	}
        +
        +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
        +	{
        +	return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
        +	}
        +
        +int X509_STORE_set_trust(X509_STORE *ctx, int trust)
        +	{
        +	return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
        +	}
        +
        +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
        +	{
        +	return X509_VERIFY_PARAM_set1(ctx->param, param);
        +	}
        +
        +void X509_STORE_set_verify_cb(X509_STORE *ctx,
        +				  int (*verify_cb)(int, X509_STORE_CTX *))
        +	{
        +	ctx->verify_cb = verify_cb;
        +	}
        +
        +IMPLEMENT_STACK_OF(X509_LOOKUP)
        +IMPLEMENT_STACK_OF(X509_OBJECT)
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_obj.c b/vendor/openssl/openssl/crypto/x509/x509_obj.c
        new file mode 100644
        index 000000000..21fed9f83
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_obj.c
        @@ -0,0 +1,226 @@
        +/* crypto/x509/x509_obj.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/buffer.h>
        +
        +char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
        +	{
        +	X509_NAME_ENTRY *ne;
        +int i;
        +	int n,lold,l,l1,l2,num,j,type;
        +	const char *s;
        +	char *p;
        +	unsigned char *q;
        +	BUF_MEM *b=NULL;
        +	static const char hex[17]="0123456789ABCDEF";
        +	int gs_doit[4];
        +	char tmp_buf[80];
        +#ifdef CHARSET_EBCDIC
        +	char ebcdic_buf[1024];
        +#endif
        +
        +	if (buf == NULL)
        +		{
        +		if ((b=BUF_MEM_new()) == NULL) goto err;
        +		if (!BUF_MEM_grow(b,200)) goto err;
        +		b->data[0]='\0';
        +		len=200;
        +		}
        +	if (a == NULL)
        +	    {
        +	    if(b)
        +		{
        +		buf=b->data;
        +		OPENSSL_free(b);
        +		}
        +	    strncpy(buf,"NO X509_NAME",len);
        +	    buf[len-1]='\0';
        +	    return buf;
        +	    }
        +
        +	len--; /* space for '\0' */
        +	l=0;
        +	for (i=0; i<sk_X509_NAME_ENTRY_num(a->entries); i++)
        +		{
        +		ne=sk_X509_NAME_ENTRY_value(a->entries,i);
        +		n=OBJ_obj2nid(ne->object);
        +		if ((n == NID_undef) || ((s=OBJ_nid2sn(n)) == NULL))
        +			{
        +			i2t_ASN1_OBJECT(tmp_buf,sizeof(tmp_buf),ne->object);
        +			s=tmp_buf;
        +			}
        +		l1=strlen(s);
        +
        +		type=ne->value->type;
        +		num=ne->value->length;
        +		q=ne->value->data;
        +#ifdef CHARSET_EBCDIC
        +                if (type == V_ASN1_GENERALSTRING ||
        +		    type == V_ASN1_VISIBLESTRING ||
        +		    type == V_ASN1_PRINTABLESTRING ||
        +		    type == V_ASN1_TELETEXSTRING ||
        +		    type == V_ASN1_VISIBLESTRING ||
        +		    type == V_ASN1_IA5STRING) {
        +                        ascii2ebcdic(ebcdic_buf, q,
        +				     (num > sizeof ebcdic_buf)
        +				     ? sizeof ebcdic_buf : num);
        +                        q=ebcdic_buf;
        +		}
        +#endif
        +
        +		if ((type == V_ASN1_GENERALSTRING) && ((num%4) == 0))
        +			{
        +			gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=0;
        +			for (j=0; j<num; j++)
        +				if (q[j] != 0) gs_doit[j&3]=1;
        +
        +			if (gs_doit[0]|gs_doit[1]|gs_doit[2])
        +				gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
        +			else
        +				{
        +				gs_doit[0]=gs_doit[1]=gs_doit[2]=0;
        +				gs_doit[3]=1;
        +				}
        +			}
        +		else
        +			gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1;
        +
        +		for (l2=j=0; j<num; j++)
        +			{
        +			if (!gs_doit[j&3]) continue;
        +			l2++;
        +#ifndef CHARSET_EBCDIC
        +			if ((q[j] < ' ') || (q[j] > '~')) l2+=3;
        +#else
        +			if ((os_toascii[q[j]] < os_toascii[' ']) ||
        +			    (os_toascii[q[j]] > os_toascii['~'])) l2+=3;
        +#endif
        +			}
        +
        +		lold=l;
        +		l+=1+l1+1+l2;
        +		if (b != NULL)
        +			{
        +			if (!BUF_MEM_grow(b,l+1)) goto err;
        +			p= &(b->data[lold]);
        +			}
        +		else if (l > len)
        +			{
        +			break;
        +			}
        +		else
        +			p= &(buf[lold]);
        +		*(p++)='/';
        +		memcpy(p,s,(unsigned int)l1); p+=l1;
        +		*(p++)='=';
        +
        +#ifndef CHARSET_EBCDIC /* q was assigned above already. */
        +		q=ne->value->data;
        +#endif
        +
        +		for (j=0; j<num; j++)
        +			{
        +			if (!gs_doit[j&3]) continue;
        +#ifndef CHARSET_EBCDIC
        +			n=q[j];
        +			if ((n < ' ') || (n > '~'))
        +				{
        +				*(p++)='\\';
        +				*(p++)='x';
        +				*(p++)=hex[(n>>4)&0x0f];
        +				*(p++)=hex[n&0x0f];
        +				}
        +			else
        +				*(p++)=n;
        +#else
        +			n=os_toascii[q[j]];
        +			if ((n < os_toascii[' ']) ||
        +			    (n > os_toascii['~']))
        +				{
        +				*(p++)='\\';
        +				*(p++)='x';
        +				*(p++)=hex[(n>>4)&0x0f];
        +				*(p++)=hex[n&0x0f];
        +				}
        +			else
        +				*(p++)=q[j];
        +#endif
        +			}
        +		*p='\0';
        +		}
        +	if (b != NULL)
        +		{
        +		p=b->data;
        +		OPENSSL_free(b);
        +		}
        +	else
        +		p=buf;
        +	if (i == 0)
        +		*p = '\0';
        +	return(p);
        +err:
        +	X509err(X509_F_X509_NAME_ONELINE,ERR_R_MALLOC_FAILURE);
        +	if (b != NULL) BUF_MEM_free(b);
        +	return(NULL);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_r2x.c b/vendor/openssl/openssl/crypto/x509/x509_r2x.c
        new file mode 100644
        index 000000000..254a14693
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_r2x.c
        @@ -0,0 +1,114 @@
        +/* crypto/x509/x509_r2x.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +
        +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
        +	{
        +	X509 *ret=NULL;
        +	X509_CINF *xi=NULL;
        +	X509_NAME *xn;
        +
        +	if ((ret=X509_new()) == NULL)
        +		{
        +		X509err(X509_F_X509_REQ_TO_X509,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	/* duplicate the request */
        +	xi=ret->cert_info;
        +
        +	if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0)
        +		{
        +		if ((xi->version=M_ASN1_INTEGER_new()) == NULL) goto err;
        +		if (!ASN1_INTEGER_set(xi->version,2)) goto err;
        +/*		xi->extensions=ri->attributes; <- bad, should not ever be done
        +		ri->attributes=NULL; */
        +		}
        +
        +	xn=X509_REQ_get_subject_name(r);
        +	if (X509_set_subject_name(ret,X509_NAME_dup(xn)) == 0)
        +		goto err;
        +	if (X509_set_issuer_name(ret,X509_NAME_dup(xn)) == 0)
        +		goto err;
        +
        +	if (X509_gmtime_adj(xi->validity->notBefore,0) == NULL)
        +		goto err;
        +	if (X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days) == NULL)
        +		goto err;
        +
        +	X509_set_pubkey(ret,X509_REQ_get_pubkey(r));
        +
        +	if (!X509_sign(ret,pkey,EVP_md5()))
        +		goto err;
        +	if (0)
        +		{
        +err:
        +		X509_free(ret);
        +		ret=NULL;
        +		}
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_req.c b/vendor/openssl/openssl/crypto/x509/x509_req.c
        new file mode 100644
        index 000000000..48183dc00
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_req.c
        @@ -0,0 +1,316 @@
        +/* crypto/x509/x509_req.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +#include <openssl/buffer.h>
        +#include <openssl/pem.h>
        +
        +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
        +	{
        +	X509_REQ *ret;
        +	X509_REQ_INFO *ri;
        +	int i;
        +	EVP_PKEY *pktmp;
        +
        +	ret=X509_REQ_new();
        +	if (ret == NULL)
        +		{
        +		X509err(X509_F_X509_TO_X509_REQ,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	ri=ret->req_info;
        +
        +	ri->version->length=1;
        +	ri->version->data=(unsigned char *)OPENSSL_malloc(1);
        +	if (ri->version->data == NULL) goto err;
        +	ri->version->data[0]=0; /* version == 0 */
        +
        +	if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x)))
        +		goto err;
        +
        +	pktmp = X509_get_pubkey(x);
        +	i=X509_REQ_set_pubkey(ret,pktmp);
        +	EVP_PKEY_free(pktmp);
        +	if (!i) goto err;
        +
        +	if (pkey != NULL)
        +		{
        +		if (!X509_REQ_sign(ret,pkey,md))
        +			goto err;
        +		}
        +	return(ret);
        +err:
        +	X509_REQ_free(ret);
        +	return(NULL);
        +	}
        +
        +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
        +	{
        +	if ((req == NULL) || (req->req_info == NULL))
        +		return(NULL);
        +	return(X509_PUBKEY_get(req->req_info->pubkey));
        +	}
        +
        +int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
        +	{
        +	EVP_PKEY *xk=NULL;
        +	int ok=0;
        +
        +	xk=X509_REQ_get_pubkey(x);
        +	switch (EVP_PKEY_cmp(xk, k))
        +		{
        +	case 1:
        +		ok=1;
        +		break;
        +	case 0:
        +		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
        +		break;
        +	case -1:
        +		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
        +		break;
        +	case -2:
        +#ifndef OPENSSL_NO_EC
        +		if (k->type == EVP_PKEY_EC)
        +			{
        +			X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
        +			break;
        +			}
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		if (k->type == EVP_PKEY_DH)
        +			{
        +			/* No idea */
        +			X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
        +			break;
        +			}
        +#endif
        +	        X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
        +		}
        +
        +	EVP_PKEY_free(xk);
        +	return(ok);
        +	}
        +
        +/* It seems several organisations had the same idea of including a list of
        + * extensions in a certificate request. There are at least two OIDs that are
        + * used and there may be more: so the list is configurable.
        + */
        +
        +static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef};
        +
        +static int *ext_nids = ext_nid_list;
        +
        +int X509_REQ_extension_nid(int req_nid)
        +{
        +	int i, nid;
        +	for(i = 0; ; i++) {
        +		nid = ext_nids[i];
        +		if(nid == NID_undef) return 0;
        +		else if (req_nid == nid) return 1;
        +	}
        +}
        +
        +int *X509_REQ_get_extension_nids(void)
        +{
        +	return ext_nids;
        +}
        +	
        +void X509_REQ_set_extension_nids(int *nids)
        +{
        +	ext_nids = nids;
        +}
        +
        +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
        +	{
        +	X509_ATTRIBUTE *attr;
        +	ASN1_TYPE *ext = NULL;
        +	int idx, *pnid;
        +	const unsigned char *p;
        +
        +	if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
        +		return(NULL);
        +	for (pnid = ext_nids; *pnid != NID_undef; pnid++)
        +		{
        +		idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
        +		if (idx == -1)
        +			continue;
        +		attr = X509_REQ_get_attr(req, idx);
        +		if(attr->single) ext = attr->value.single;
        +		else if(sk_ASN1_TYPE_num(attr->value.set))
        +			ext = sk_ASN1_TYPE_value(attr->value.set, 0);
        +		break;
        +		}
        +	if(!ext || (ext->type != V_ASN1_SEQUENCE))
        +		return NULL;
        +	p = ext->value.sequence->data;
        +	return (STACK_OF(X509_EXTENSION) *)
        +		ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
        +				ASN1_ITEM_rptr(X509_EXTENSIONS));
        +}
        +
        +/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
        + * in case we want to create a non standard one.
        + */
        +
        +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
        +				int nid)
        +{
        +	ASN1_TYPE *at = NULL;
        +	X509_ATTRIBUTE *attr = NULL;
        +	if(!(at = ASN1_TYPE_new()) ||
        +		!(at->value.sequence = ASN1_STRING_new())) goto err;
        +
        +	at->type = V_ASN1_SEQUENCE;
        +	/* Generate encoding of extensions */
        +	at->value.sequence->length = 
        +			ASN1_item_i2d((ASN1_VALUE *)exts,
        +				&at->value.sequence->data,
        +				ASN1_ITEM_rptr(X509_EXTENSIONS));
        +	if(!(attr = X509_ATTRIBUTE_new())) goto err;
        +	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
        +	if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
        +	at = NULL;
        +	attr->single = 0;
        +	attr->object = OBJ_nid2obj(nid);
        +	if (!req->req_info->attributes)
        +		{
        +		if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
        +			goto err;
        +		}
        +	if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
        +	return 1;
        +	err:
        +	X509_ATTRIBUTE_free(attr);
        +	ASN1_TYPE_free(at);
        +	return 0;
        +}
        +/* This is the normal usage: use the "official" OID */
        +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
        +{
        +	return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
        +}
        +
        +/* Request attribute functions */
        +
        +int X509_REQ_get_attr_count(const X509_REQ *req)
        +{
        +	return X509at_get_attr_count(req->req_info->attributes);
        +}
        +
        +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
        +}
        +
        +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
        +			  int lastpos)
        +{
        +	return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
        +}
        +
        +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
        +{
        +	return X509at_get_attr(req->req_info->attributes, loc);
        +}
        +
        +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
        +{
        +	return X509at_delete_attr(req->req_info->attributes, loc);
        +}
        +
        +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
        +{
        +	if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1;
        +	return 0;
        +}
        +
        +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
        +			const ASN1_OBJECT *obj, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int X509_REQ_add1_attr_by_NID(X509_REQ *req,
        +			int nid, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        +
        +int X509_REQ_add1_attr_by_txt(X509_REQ *req,
        +			const char *attrname, int type,
        +			const unsigned char *bytes, int len)
        +{
        +	if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
        +				type, bytes, len)) return 1;
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_set.c b/vendor/openssl/openssl/crypto/x509/x509_set.c
        new file mode 100644
        index 000000000..4b94fc584
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_set.c
        @@ -0,0 +1,150 @@
        +/* crypto/x509/x509_set.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +int X509_set_version(X509 *x, long version)
        +	{
        +	if (x == NULL) return(0);
        +	if (x->cert_info->version == NULL)
        +		{
        +		if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL)
        +			return(0);
        +		}
        +	return(ASN1_INTEGER_set(x->cert_info->version,version));
        +	}
        +
        +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
        +	{
        +	ASN1_INTEGER *in;
        +
        +	if (x == NULL) return(0);
        +	in=x->cert_info->serialNumber;
        +	if (in != serial)
        +		{
        +		in=M_ASN1_INTEGER_dup(serial);
        +		if (in != NULL)
        +			{
        +			M_ASN1_INTEGER_free(x->cert_info->serialNumber);
        +			x->cert_info->serialNumber=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        +
        +int X509_set_issuer_name(X509 *x, X509_NAME *name)
        +	{
        +	if ((x == NULL) || (x->cert_info == NULL)) return(0);
        +	return(X509_NAME_set(&x->cert_info->issuer,name));
        +	}
        +
        +int X509_set_subject_name(X509 *x, X509_NAME *name)
        +	{
        +	if ((x == NULL) || (x->cert_info == NULL)) return(0);
        +	return(X509_NAME_set(&x->cert_info->subject,name));
        +	}
        +
        +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
        +	{
        +	ASN1_TIME *in;
        +
        +	if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
        +	in=x->cert_info->validity->notBefore;
        +	if (in != tm)
        +		{
        +		in=M_ASN1_TIME_dup(tm);
        +		if (in != NULL)
        +			{
        +			M_ASN1_TIME_free(x->cert_info->validity->notBefore);
        +			x->cert_info->validity->notBefore=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        +
        +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
        +	{
        +	ASN1_TIME *in;
        +
        +	if ((x == NULL) || (x->cert_info->validity == NULL)) return(0);
        +	in=x->cert_info->validity->notAfter;
        +	if (in != tm)
        +		{
        +		in=M_ASN1_TIME_dup(tm);
        +		if (in != NULL)
        +			{
        +			M_ASN1_TIME_free(x->cert_info->validity->notAfter);
        +			x->cert_info->validity->notAfter=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        +
        +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
        +	{
        +	if ((x == NULL) || (x->cert_info == NULL)) return(0);
        +	return(X509_PUBKEY_set(&(x->cert_info->key),pkey));
        +	}
        +
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_trs.c b/vendor/openssl/openssl/crypto/x509/x509_trs.c
        new file mode 100644
        index 000000000..a6cb9c8b1
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_trs.c
        @@ -0,0 +1,288 @@
        +/* x509_trs.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509v3.h>
        +
        +
        +static int tr_cmp(const X509_TRUST * const *a,
        +		const X509_TRUST * const *b);
        +static void trtable_free(X509_TRUST *p);
        +
        +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
        +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
        +static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
        +
        +static int obj_trust(int id, X509 *x, int flags);
        +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
        +
        +/* WARNING: the following table should be kept in order of trust
        + * and without any gaps so we can just subtract the minimum trust
        + * value to get an index into the table
        + */
        +
        +static X509_TRUST trstandard[] = {
        +{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
        +{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL},
        +{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL},
        +{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
        +{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
        +{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
        +{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL},
        +{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
        +};
        +
        +#define X509_TRUST_COUNT	(sizeof(trstandard)/sizeof(X509_TRUST))
        +
        +IMPLEMENT_STACK_OF(X509_TRUST)
        +
        +static STACK_OF(X509_TRUST) *trtable = NULL;
        +
        +static int tr_cmp(const X509_TRUST * const *a,
        +		const X509_TRUST * const *b)
        +{
        +	return (*a)->trust - (*b)->trust;
        +}
        +
        +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
        +{
        +	int (*oldtrust)(int , X509 *, int);
        +	oldtrust = default_trust;
        +	default_trust = trust;
        +	return oldtrust;
        +}
        +
        +
        +int X509_check_trust(X509 *x, int id, int flags)
        +{
        +	X509_TRUST *pt;
        +	int idx;
        +	if(id == -1) return 1;
        +	idx = X509_TRUST_get_by_id(id);
        +	if(idx == -1) return default_trust(id, x, flags);
        +	pt = X509_TRUST_get0(idx);
        +	return pt->check_trust(pt, x, flags);
        +}
        +
        +int X509_TRUST_get_count(void)
        +{
        +	if(!trtable) return X509_TRUST_COUNT;
        +	return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
        +}
        +
        +X509_TRUST * X509_TRUST_get0(int idx)
        +{
        +	if(idx < 0) return NULL;
        +	if(idx < (int)X509_TRUST_COUNT) return trstandard + idx;
        +	return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
        +}
        +
        +int X509_TRUST_get_by_id(int id)
        +{
        +	X509_TRUST tmp;
        +	int idx;
        +	if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
        +				 return id - X509_TRUST_MIN;
        +	tmp.trust = id;
        +	if(!trtable) return -1;
        +	idx = sk_X509_TRUST_find(trtable, &tmp);
        +	if(idx == -1) return -1;
        +	return idx + X509_TRUST_COUNT;
        +}
        +
        +int X509_TRUST_set(int *t, int trust)
        +{
        +	if(X509_TRUST_get_by_id(trust) == -1) {
        +		X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
        +		return 0;
        +	}
        +	*t = trust;
        +	return 1;
        +}
        +
        +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
        +					char *name, int arg1, void *arg2)
        +{
        +	int idx;
        +	X509_TRUST *trtmp;
        +	/* This is set according to what we change: application can't set it */
        +	flags &= ~X509_TRUST_DYNAMIC;
        +	/* This will always be set for application modified trust entries */
        +	flags |= X509_TRUST_DYNAMIC_NAME;
        +	/* Get existing entry if any */
        +	idx = X509_TRUST_get_by_id(id);
        +	/* Need a new entry */
        +	if(idx == -1) {
        +		if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
        +			X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		trtmp->flags = X509_TRUST_DYNAMIC;
        +	} else trtmp = X509_TRUST_get0(idx);
        +
        +	/* OPENSSL_free existing name if dynamic */
        +	if(trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
        +	/* dup supplied name */
        +	if(!(trtmp->name = BUF_strdup(name))) {
        +		X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	/* Keep the dynamic flag of existing entry */
        +	trtmp->flags &= X509_TRUST_DYNAMIC;
        +	/* Set all other flags */
        +	trtmp->flags |= flags;
        +
        +	trtmp->trust = id;
        +	trtmp->check_trust = ck;
        +	trtmp->arg1 = arg1;
        +	trtmp->arg2 = arg2;
        +
        +	/* If its a new entry manage the dynamic table */
        +	if(idx == -1) {
        +		if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
        +			X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		if (!sk_X509_TRUST_push(trtable, trtmp)) {
        +			X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +	}
        +	return 1;
        +}
        +
        +static void trtable_free(X509_TRUST *p)
        +	{
        +	if(!p) return;
        +	if (p->flags & X509_TRUST_DYNAMIC) 
        +		{
        +		if (p->flags & X509_TRUST_DYNAMIC_NAME)
        +			OPENSSL_free(p->name);
        +		OPENSSL_free(p);
        +		}
        +	}
        +
        +void X509_TRUST_cleanup(void)
        +{
        +	unsigned int i;
        +	for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i);
        +	sk_X509_TRUST_pop_free(trtable, trtable_free);
        +	trtable = NULL;
        +}
        +
        +int X509_TRUST_get_flags(X509_TRUST *xp)
        +{
        +	return xp->flags;
        +}
        +
        +char *X509_TRUST_get0_name(X509_TRUST *xp)
        +{
        +	return xp->name;
        +}
        +
        +int X509_TRUST_get_trust(X509_TRUST *xp)
        +{
        +	return xp->trust;
        +}
        +
        +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
        +{
        +	if(x->aux && (x->aux->trust || x->aux->reject))
        +		return obj_trust(trust->arg1, x, flags);
        +	/* we don't have any trust settings: for compatibility
        +	 * we return trusted if it is self signed
        +	 */
        +	return trust_compat(trust, x, flags);
        +}
        +
        +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
        +{
        +	if(x->aux) return obj_trust(trust->arg1, x, flags);
        +	return X509_TRUST_UNTRUSTED;
        +}
        +
        +static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
        +{
        +	X509_check_purpose(x, -1, 0);
        +	if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED;
        +	else return X509_TRUST_UNTRUSTED;
        +}
        +
        +static int obj_trust(int id, X509 *x, int flags)
        +{
        +	ASN1_OBJECT *obj;
        +	int i;
        +	X509_CERT_AUX *ax;
        +	ax = x->aux;
        +	if(!ax) return X509_TRUST_UNTRUSTED;
        +	if(ax->reject) {
        +		for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
        +			obj = sk_ASN1_OBJECT_value(ax->reject, i);
        +			if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED;
        +		}
        +	}	
        +	if(ax->trust) {
        +		for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
        +			obj = sk_ASN1_OBJECT_value(ax->trust, i);
        +			if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED;
        +		}
        +	}
        +	return X509_TRUST_UNTRUSTED;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_txt.c b/vendor/openssl/openssl/crypto/x509/x509_txt.c
        new file mode 100644
        index 000000000..c44f753c4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_txt.c
        @@ -0,0 +1,193 @@
        +/* crypto/x509/x509_txt.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include <errno.h>
        +
        +#include "cryptlib.h"
        +#include <openssl/lhash.h>
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +
        +const char *X509_verify_cert_error_string(long n)
        +	{
        +	static char buf[100];
        +
        +	switch ((int)n)
        +		{
        +	case X509_V_OK:
        +		return("ok");
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +		return("unable to get issuer certificate");
        +	case X509_V_ERR_UNABLE_TO_GET_CRL:
        +		return("unable to get certificate CRL");
        +	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
        +		return("unable to decrypt certificate's signature");
        +	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
        +		return("unable to decrypt CRL's signature");
        +	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
        +		return("unable to decode issuer public key");
        +	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
        +		return("certificate signature failure");
        +	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
        +		return("CRL signature failure");
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +		return("certificate is not yet valid");
        +	case X509_V_ERR_CRL_NOT_YET_VALID:
        +		return("CRL is not yet valid");
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +		return("certificate has expired");
        +	case X509_V_ERR_CRL_HAS_EXPIRED:
        +		return("CRL has expired");
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +		return("format error in certificate's notBefore field");
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +		return("format error in certificate's notAfter field");
        +	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
        +		return("format error in CRL's lastUpdate field");
        +	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
        +		return("format error in CRL's nextUpdate field");
        +	case X509_V_ERR_OUT_OF_MEM:
        +		return("out of memory");
        +	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        +		return("self signed certificate");
        +	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
        +		return("self signed certificate in certificate chain");
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
        +		return("unable to get local issuer certificate");
        +	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
        +		return("unable to verify the first certificate");
        +	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
        +		return("certificate chain too long");
        +	case X509_V_ERR_CERT_REVOKED:
        +		return("certificate revoked");
        +	case X509_V_ERR_INVALID_CA:
        +		return ("invalid CA certificate");
        +	case X509_V_ERR_INVALID_NON_CA:
        +		return ("invalid non-CA certificate (has CA markings)");
        +	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
        +		return ("path length constraint exceeded");
        +	case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
        +		return("proxy path length constraint exceeded");
        +	case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
        +		return("proxy certificates not allowed, please set the appropriate flag");
        +	case X509_V_ERR_INVALID_PURPOSE:
        +		return ("unsupported certificate purpose");
        +	case X509_V_ERR_CERT_UNTRUSTED:
        +		return ("certificate not trusted");
        +	case X509_V_ERR_CERT_REJECTED:
        +		return ("certificate rejected");
        +	case X509_V_ERR_APPLICATION_VERIFICATION:
        +		return("application verification failure");
        +	case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
        +		return("subject issuer mismatch");
        +	case X509_V_ERR_AKID_SKID_MISMATCH:
        +		return("authority and subject key identifier mismatch");
        +	case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
        +		return("authority and issuer serial number mismatch");
        +	case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
        +		return("key usage does not include certificate signing");
        +	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
        +		return("unable to get CRL issuer certificate");
        +	case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
        +		return("unhandled critical extension");
        +	case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
        +		return("key usage does not include CRL signing");
        +	case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
        +		return("key usage does not include digital signature");
        +	case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
        +		return("unhandled critical CRL extension");
        +	case X509_V_ERR_INVALID_EXTENSION:
        +		return("invalid or inconsistent certificate extension");
        +	case X509_V_ERR_INVALID_POLICY_EXTENSION:
        +		return("invalid or inconsistent certificate policy extension");
        +	case X509_V_ERR_NO_EXPLICIT_POLICY:
        +		return("no explicit policy");
        +	case X509_V_ERR_DIFFERENT_CRL_SCOPE:
        +	return("Different CRL scope");
        +	case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
        +	return("Unsupported extension feature");
        + 	case X509_V_ERR_UNNESTED_RESOURCE:
        + 		return("RFC 3779 resource not subset of parent's resources");
        +
        +	case X509_V_ERR_PERMITTED_VIOLATION:
        +		return("permitted subtree violation");
        +	case X509_V_ERR_EXCLUDED_VIOLATION:
        +		return("excluded subtree violation");
        +	case X509_V_ERR_SUBTREE_MINMAX:
        +		return("name constraints minimum and maximum not supported");
        +	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
        +		return("unsupported name constraint type");
        +	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
        +		return("unsupported or invalid name constraint syntax");
        +	case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
        +		return("unsupported or invalid name syntax");
        +	case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
        +		return("CRL path validation error");
        +
        +	default:
        +		BIO_snprintf(buf,sizeof buf,"error number %ld",n);
        +		return(buf);
        +		}
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_v3.c b/vendor/openssl/openssl/crypto/x509/x509_v3.c
        new file mode 100644
        index 000000000..42e6f0ab0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_v3.c
        @@ -0,0 +1,274 @@
        +/* crypto/x509/x509_v3.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/stack.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
        +	{
        +	if (x == NULL) return(0);
        +	return(sk_X509_EXTENSION_num(x));
        +	}
        +
        +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
        +			  int lastpos)
        +	{
        +	ASN1_OBJECT *obj;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL) return(-2);
        +	return(X509v3_get_ext_by_OBJ(x,obj,lastpos));
        +	}
        +
        +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, ASN1_OBJECT *obj,
        +			  int lastpos)
        +	{
        +	int n;
        +	X509_EXTENSION *ex;
        +
        +	if (sk == NULL) return(-1);
        +	lastpos++;
        +	if (lastpos < 0)
        +		lastpos=0;
        +	n=sk_X509_EXTENSION_num(sk);
        +	for ( ; lastpos < n; lastpos++)
        +		{
        +		ex=sk_X509_EXTENSION_value(sk,lastpos);
        +		if (OBJ_cmp(ex->object,obj) == 0)
        +			return(lastpos);
        +		}
        +	return(-1);
        +	}
        +
        +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
        +			       int lastpos)
        +	{
        +	int n;
        +	X509_EXTENSION *ex;
        +
        +	if (sk == NULL) return(-1);
        +	lastpos++;
        +	if (lastpos < 0)
        +		lastpos=0;
        +	n=sk_X509_EXTENSION_num(sk);
        +	for ( ; lastpos < n; lastpos++)
        +		{
        +		ex=sk_X509_EXTENSION_value(sk,lastpos);
        +		if (	((ex->critical > 0) && crit) ||
        +			((ex->critical <= 0) && !crit))
        +			return(lastpos);
        +		}
        +	return(-1);
        +	}
        +
        +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
        +	{
        +	if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
        +		return NULL;
        +	else
        +		return sk_X509_EXTENSION_value(x,loc);
        +	}
        +
        +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
        +	{
        +	X509_EXTENSION *ret;
        +
        +	if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
        +		return(NULL);
        +	ret=sk_X509_EXTENSION_delete(x,loc);
        +	return(ret);
        +	}
        +
        +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
        +					 X509_EXTENSION *ex, int loc)
        +	{
        +	X509_EXTENSION *new_ex=NULL;
        +	int n;
        +	STACK_OF(X509_EXTENSION) *sk=NULL;
        +
        +	if (x == NULL)
        +		{
        +		X509err(X509_F_X509V3_ADD_EXT,ERR_R_PASSED_NULL_PARAMETER);
        +		goto err2;
        +		}
        +
        +	if (*x == NULL)
        +		{
        +		if ((sk=sk_X509_EXTENSION_new_null()) == NULL)
        +			goto err;
        +		}
        +	else
        +		sk= *x;
        +
        +	n=sk_X509_EXTENSION_num(sk);
        +	if (loc > n) loc=n;
        +	else if (loc < 0) loc=n;
        +
        +	if ((new_ex=X509_EXTENSION_dup(ex)) == NULL)
        +		goto err2;
        +	if (!sk_X509_EXTENSION_insert(sk,new_ex,loc))
        +		goto err;
        +	if (*x == NULL)
        +		*x=sk;
        +	return(sk);
        +err:
        +	X509err(X509_F_X509V3_ADD_EXT,ERR_R_MALLOC_FAILURE);
        +err2:
        +	if (new_ex != NULL) X509_EXTENSION_free(new_ex);
        +	if (sk != NULL) sk_X509_EXTENSION_free(sk);
        +	return(NULL);
        +	}
        +
        +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
        +	     int crit, ASN1_OCTET_STRING *data)
        +	{
        +	ASN1_OBJECT *obj;
        +	X509_EXTENSION *ret;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_EXTENSION_CREATE_BY_NID,X509_R_UNKNOWN_NID);
        +		return(NULL);
        +		}
        +	ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
        +	if (ret == NULL) ASN1_OBJECT_free(obj);
        +	return(ret);
        +	}
        +
        +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
        +	     ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data)
        +	{
        +	X509_EXTENSION *ret;
        +
        +	if ((ex == NULL) || (*ex == NULL))
        +		{
        +		if ((ret=X509_EXTENSION_new()) == NULL)
        +			{
        +			X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE);
        +			return(NULL);
        +			}
        +		}
        +	else
        +		ret= *ex;
        +
        +	if (!X509_EXTENSION_set_object(ret,obj))
        +		goto err;
        +	if (!X509_EXTENSION_set_critical(ret,crit))
        +		goto err;
        +	if (!X509_EXTENSION_set_data(ret,data))
        +		goto err;
        +	
        +	if ((ex != NULL) && (*ex == NULL)) *ex=ret;
        +	return(ret);
        +err:
        +	if ((ex == NULL) || (ret != *ex))
        +		X509_EXTENSION_free(ret);
        +	return(NULL);
        +	}
        +
        +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj)
        +	{
        +	if ((ex == NULL) || (obj == NULL))
        +		return(0);
        +	ASN1_OBJECT_free(ex->object);
        +	ex->object=OBJ_dup(obj);
        +	return(1);
        +	}
        +
        +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
        +	{
        +	if (ex == NULL) return(0);
        +	ex->critical=(crit)?0xFF:-1;
        +	return(1);
        +	}
        +
        +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
        +	{
        +	int i;
        +
        +	if (ex == NULL) return(0);
        +	i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length);
        +	if (!i) return(0);
        +	return(1);
        +	}
        +
        +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
        +	{
        +	if (ex == NULL) return(NULL);
        +	return(ex->object);
        +	}
        +
        +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
        +	{
        +	if (ex == NULL) return(NULL);
        +	return(ex->value);
        +	}
        +
        +int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
        +	{
        +	if (ex == NULL) return(0);
        +	if(ex->critical > 0) return 1;
        +	return 0;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_vfy.c b/vendor/openssl/openssl/crypto/x509/x509_vfy.c
        new file mode 100644
        index 000000000..12d71f54e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_vfy.c
        @@ -0,0 +1,2214 @@
        +/* crypto/x509/x509_vfy.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <time.h>
        +#include <errno.h>
        +
        +#include "cryptlib.h"
        +#include <openssl/crypto.h>
        +#include <openssl/lhash.h>
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/objects.h>
        +
        +/* CRL score values */
        +
        +/* No unhandled critical extensions */
        +
        +#define CRL_SCORE_NOCRITICAL	0x100
        +
        +/* certificate is within CRL scope */
        +
        +#define CRL_SCORE_SCOPE		0x080
        +
        +/* CRL times valid */
        +
        +#define CRL_SCORE_TIME		0x040
        +
        +/* Issuer name matches certificate */
        +
        +#define CRL_SCORE_ISSUER_NAME	0x020
        +
        +/* If this score or above CRL is probably valid */
        +
        +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
        +
        +/* CRL issuer is certificate issuer */
        +
        +#define CRL_SCORE_ISSUER_CERT	0x018
        +
        +/* CRL issuer is on certificate path */
        +
        +#define CRL_SCORE_SAME_PATH	0x008
        +
        +/* CRL issuer matches CRL AKID */
        +
        +#define CRL_SCORE_AKID		0x004
        +
        +/* Have a delta CRL with valid times */
        +
        +#define CRL_SCORE_TIME_DELTA	0x002
        +
        +static int null_callback(int ok,X509_STORE_CTX *e);
        +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
        +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
        +static int check_chain_extensions(X509_STORE_CTX *ctx);
        +static int check_name_constraints(X509_STORE_CTX *ctx);
        +static int check_trust(X509_STORE_CTX *ctx);
        +static int check_revocation(X509_STORE_CTX *ctx);
        +static int check_cert(X509_STORE_CTX *ctx);
        +static int check_policy(X509_STORE_CTX *ctx);
        +
        +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
        +			unsigned int *preasons,
        +			X509_CRL *crl, X509 *x);
        +static int get_crl_delta(X509_STORE_CTX *ctx,
        +				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
        +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
        +			X509_CRL *base, STACK_OF(X509_CRL) *crls);
        +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
        +				X509 **pissuer, int *pcrl_score);
        +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
        +				unsigned int *preasons);
        +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
        +static int check_crl_chain(X509_STORE_CTX *ctx,
        +			STACK_OF(X509) *cert_path,
        +			STACK_OF(X509) *crl_path);
        +
        +static int internal_verify(X509_STORE_CTX *ctx);
        +const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT;
        +
        +
        +static int null_callback(int ok, X509_STORE_CTX *e)
        +	{
        +	return ok;
        +	}
        +
        +#if 0
        +static int x509_subject_cmp(X509 **a, X509 **b)
        +	{
        +	return X509_subject_name_cmp(*a,*b);
        +	}
        +#endif
        +
        +int X509_verify_cert(X509_STORE_CTX *ctx)
        +	{
        +	X509 *x,*xtmp,*chain_ss=NULL;
        +	int bad_chain = 0;
        +	X509_VERIFY_PARAM *param = ctx->param;
        +	int depth,i,ok=0;
        +	int num;
        +	int (*cb)(int xok,X509_STORE_CTX *xctx);
        +	STACK_OF(X509) *sktmp=NULL;
        +	if (ctx->cert == NULL)
        +		{
        +		X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
        +		return -1;
        +		}
        +
        +	cb=ctx->verify_cb;
        +
        +	/* first we make sure the chain we are going to build is
        +	 * present and that the first entry is in place */
        +	if (ctx->chain == NULL)
        +		{
        +		if (	((ctx->chain=sk_X509_new_null()) == NULL) ||
        +			(!sk_X509_push(ctx->chain,ctx->cert)))
        +			{
        +			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
        +			goto end;
        +			}
        +		CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
        +		ctx->last_untrusted=1;
        +		}
        +
        +	/* We use a temporary STACK so we can chop and hack at it */
        +	if (ctx->untrusted != NULL
        +	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
        +		{
        +		X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
        +		goto end;
        +		}
        +
        +	num=sk_X509_num(ctx->chain);
        +	x=sk_X509_value(ctx->chain,num-1);
        +	depth=param->depth;
        +
        +
        +	for (;;)
        +		{
        +		/* If we have enough, we break */
        +		if (depth < num) break; /* FIXME: If this happens, we should take
        +		                         * note of it and, if appropriate, use the
        +		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error
        +		                         * code later.
        +		                         */
        +
        +		/* If we are self signed, we break */
        +		if (ctx->check_issued(ctx, x,x)) break;
        +
        +		/* If we were passed a cert chain, use it first */
        +		if (ctx->untrusted != NULL)
        +			{
        +			xtmp=find_issuer(ctx, sktmp,x);
        +			if (xtmp != NULL)
        +				{
        +				if (!sk_X509_push(ctx->chain,xtmp))
        +					{
        +					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
        +					goto end;
        +					}
        +				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
        +				(void)sk_X509_delete_ptr(sktmp,xtmp);
        +				ctx->last_untrusted++;
        +				x=xtmp;
        +				num++;
        +				/* reparse the full chain for
        +				 * the next one */
        +				continue;
        +				}
        +			}
        +		break;
        +		}
        +
        +	/* at this point, chain should contain a list of untrusted
        +	 * certificates.  We now need to add at least one trusted one,
        +	 * if possible, otherwise we complain. */
        +
        +	/* Examine last certificate in chain and see if it
        + 	 * is self signed.
        + 	 */
        +
        +	i=sk_X509_num(ctx->chain);
        +	x=sk_X509_value(ctx->chain,i-1);
        +	if (ctx->check_issued(ctx, x, x))
        +		{
        +		/* we have a self signed certificate */
        +		if (sk_X509_num(ctx->chain) == 1)
        +			{
        +			/* We have a single self signed certificate: see if
        +			 * we can find it in the store. We must have an exact
        +			 * match to avoid possible impersonation.
        +			 */
        +			ok = ctx->get_issuer(&xtmp, ctx, x);
        +			if ((ok <= 0) || X509_cmp(x, xtmp)) 
        +				{
        +				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
        +				ctx->current_cert=x;
        +				ctx->error_depth=i-1;
        +				if (ok == 1) X509_free(xtmp);
        +				bad_chain = 1;
        +				ok=cb(0,ctx);
        +				if (!ok) goto end;
        +				}
        +			else 
        +				{
        +				/* We have a match: replace certificate with store version
        +				 * so we get any trust settings.
        +				 */
        +				X509_free(x);
        +				x = xtmp;
        +				(void)sk_X509_set(ctx->chain, i - 1, x);
        +				ctx->last_untrusted=0;
        +				}
        +			}
        +		else
        +			{
        +			/* extract and save self signed certificate for later use */
        +			chain_ss=sk_X509_pop(ctx->chain);
        +			ctx->last_untrusted--;
        +			num--;
        +			x=sk_X509_value(ctx->chain,num-1);
        +			}
        +		}
        +
        +	/* We now lookup certs from the certificate store */
        +	for (;;)
        +		{
        +		/* If we have enough, we break */
        +		if (depth < num) break;
        +
        +		/* If we are self signed, we break */
        +		if (ctx->check_issued(ctx,x,x)) break;
        +
        +		ok = ctx->get_issuer(&xtmp, ctx, x);
        +
        +		if (ok < 0) return ok;
        +		if (ok == 0) break;
        +
        +		x = xtmp;
        +		if (!sk_X509_push(ctx->chain,x))
        +			{
        +			X509_free(xtmp);
        +			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		num++;
        +		}
        +
        +	/* we now have our chain, lets check it... */
        +
        +	/* Is last certificate looked up self signed? */
        +	if (!ctx->check_issued(ctx,x,x))
        +		{
        +		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
        +			{
        +			if (ctx->last_untrusted >= num)
        +				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
        +			else
        +				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
        +			ctx->current_cert=x;
        +			}
        +		else
        +			{
        +
        +			sk_X509_push(ctx->chain,chain_ss);
        +			num++;
        +			ctx->last_untrusted=num;
        +			ctx->current_cert=chain_ss;
        +			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
        +			chain_ss=NULL;
        +			}
        +
        +		ctx->error_depth=num-1;
        +		bad_chain = 1;
        +		ok=cb(0,ctx);
        +		if (!ok) goto end;
        +		}
        +
        +	/* We have the chain complete: now we need to check its purpose */
        +	ok = check_chain_extensions(ctx);
        +
        +	if (!ok) goto end;
        +
        +	/* Check name constraints */
        +
        +	ok = check_name_constraints(ctx);
        +	
        +	if (!ok) goto end;
        +
        +	/* The chain extensions are OK: check trust */
        +
        +	if (param->trust > 0) ok = check_trust(ctx);
        +
        +	if (!ok) goto end;
        +
        +	/* We may as well copy down any DSA parameters that are required */
        +	X509_get_pubkey_parameters(NULL,ctx->chain);
        +
        +	/* Check revocation status: we do this after copying parameters
        +	 * because they may be needed for CRL signature verification.
        +	 */
        +
        +	ok = ctx->check_revocation(ctx);
        +	if(!ok) goto end;
        +
        +	/* At this point, we have a chain and need to verify it */
        +	if (ctx->verify != NULL)
        +		ok=ctx->verify(ctx);
        +	else
        +		ok=internal_verify(ctx);
        +	if(!ok) goto end;
        +
        +#ifndef OPENSSL_NO_RFC3779
        +	/* RFC 3779 path validation, now that CRL check has been done */
        +	ok = v3_asid_validate_path(ctx);
        +	if (!ok) goto end;
        +	ok = v3_addr_validate_path(ctx);
        +	if (!ok) goto end;
        +#endif
        +
        +	/* If we get this far evaluate policies */
        +	if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
        +		ok = ctx->check_policy(ctx);
        +	if(!ok) goto end;
        +	if (0)
        +		{
        +end:
        +		X509_get_pubkey_parameters(NULL,ctx->chain);
        +		}
        +	if (sktmp != NULL) sk_X509_free(sktmp);
        +	if (chain_ss != NULL) X509_free(chain_ss);
        +	return ok;
        +	}
        +
        +
        +/* Given a STACK_OF(X509) find the issuer of cert (if any)
        + */
        +
        +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
        +{
        +	int i;
        +	X509 *issuer;
        +	for (i = 0; i < sk_X509_num(sk); i++)
        +		{
        +		issuer = sk_X509_value(sk, i);
        +		if (ctx->check_issued(ctx, x, issuer))
        +			return issuer;
        +		}
        +	return NULL;
        +}
        +
        +/* Given a possible certificate and issuer check them */
        +
        +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
        +{
        +	int ret;
        +	ret = X509_check_issued(issuer, x);
        +	if (ret == X509_V_OK)
        +		return 1;
        +	/* If we haven't asked for issuer errors don't set ctx */
        +	if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
        +		return 0;
        +
        +	ctx->error = ret;
        +	ctx->current_cert = x;
        +	ctx->current_issuer = issuer;
        +	return ctx->verify_cb(0, ctx);
        +	return 0;
        +}
        +
        +/* Alternative lookup method: look from a STACK stored in other_ctx */
        +
        +static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
        +{
        +	*issuer = find_issuer(ctx, ctx->other_ctx, x);
        +	if (*issuer)
        +		{
        +		CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509);
        +		return 1;
        +		}
        +	else
        +		return 0;
        +}
        +	
        +
        +/* Check a certificate chains extensions for consistency
        + * with the supplied purpose
        + */
        +
        +static int check_chain_extensions(X509_STORE_CTX *ctx)
        +{
        +#ifdef OPENSSL_NO_CHAIN_VERIFY
        +	return 1;
        +#else
        +	int i, ok=0, must_be_ca, plen = 0;
        +	X509 *x;
        +	int (*cb)(int xok,X509_STORE_CTX *xctx);
        +	int proxy_path_length = 0;
        +	int purpose;
        +	int allow_proxy_certs;
        +	cb=ctx->verify_cb;
        +
        +	/* must_be_ca can have 1 of 3 values:
        +	   -1: we accept both CA and non-CA certificates, to allow direct
        +	       use of self-signed certificates (which are marked as CA).
        +	   0:  we only accept non-CA certificates.  This is currently not
        +	       used, but the possibility is present for future extensions.
        +	   1:  we only accept CA certificates.  This is currently used for
        +	       all certificates in the chain except the leaf certificate.
        +	*/
        +	must_be_ca = -1;
        +
        +	/* CRL path validation */
        +	if (ctx->parent)
        +		{
        +		allow_proxy_certs = 0;
        +		purpose = X509_PURPOSE_CRL_SIGN;
        +		}
        +	else
        +		{
        +		allow_proxy_certs =
        +			!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
        +		/* A hack to keep people who don't want to modify their
        +		   software happy */
        +		if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
        +			allow_proxy_certs = 1;
        +		purpose = ctx->param->purpose;
        +		}
        +
        +	/* Check all untrusted certificates */
        +	for (i = 0; i < ctx->last_untrusted; i++)
        +		{
        +		int ret;
        +		x = sk_X509_value(ctx->chain, i);
        +		if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
        +			&& (x->ex_flags & EXFLAG_CRITICAL))
        +			{
        +			ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
        +			ctx->error_depth = i;
        +			ctx->current_cert = x;
        +			ok=cb(0,ctx);
        +			if (!ok) goto end;
        +			}
        +		if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
        +			{
        +			ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
        +			ctx->error_depth = i;
        +			ctx->current_cert = x;
        +			ok=cb(0,ctx);
        +			if (!ok) goto end;
        +			}
        +		ret = X509_check_ca(x);
        +		switch(must_be_ca)
        +			{
        +		case -1:
        +			if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
        +				&& (ret != 1) && (ret != 0))
        +				{
        +				ret = 0;
        +				ctx->error = X509_V_ERR_INVALID_CA;
        +				}
        +			else
        +				ret = 1;
        +			break;
        +		case 0:
        +			if (ret != 0)
        +				{
        +				ret = 0;
        +				ctx->error = X509_V_ERR_INVALID_NON_CA;
        +				}
        +			else
        +				ret = 1;
        +			break;
        +		default:
        +			if ((ret == 0)
        +				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
        +					&& (ret != 1)))
        +				{
        +				ret = 0;
        +				ctx->error = X509_V_ERR_INVALID_CA;
        +				}
        +			else
        +				ret = 1;
        +			break;
        +			}
        +		if (ret == 0)
        +			{
        +			ctx->error_depth = i;
        +			ctx->current_cert = x;
        +			ok=cb(0,ctx);
        +			if (!ok) goto end;
        +			}
        +		if (ctx->param->purpose > 0)
        +			{
        +			ret = X509_check_purpose(x, purpose, must_be_ca > 0);
        +			if ((ret == 0)
        +				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
        +					&& (ret != 1)))
        +				{
        +				ctx->error = X509_V_ERR_INVALID_PURPOSE;
        +				ctx->error_depth = i;
        +				ctx->current_cert = x;
        +				ok=cb(0,ctx);
        +				if (!ok) goto end;
        +				}
        +			}
        +		/* Check pathlen if not self issued */
        +		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
        +			   && (x->ex_pathlen != -1)
        +			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
        +			{
        +			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
        +			ctx->error_depth = i;
        +			ctx->current_cert = x;
        +			ok=cb(0,ctx);
        +			if (!ok) goto end;
        +			}
        +		/* Increment path length if not self issued */
        +		if (!(x->ex_flags & EXFLAG_SI))
        +			plen++;
        +		/* If this certificate is a proxy certificate, the next
        +		   certificate must be another proxy certificate or a EE
        +		   certificate.  If not, the next certificate must be a
        +		   CA certificate.  */
        +		if (x->ex_flags & EXFLAG_PROXY)
        +			{
        +			if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
        +				{
        +				ctx->error =
        +					X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
        +				ctx->error_depth = i;
        +				ctx->current_cert = x;
        +				ok=cb(0,ctx);
        +				if (!ok) goto end;
        +				}
        +			proxy_path_length++;
        +			must_be_ca = 0;
        +			}
        +		else
        +			must_be_ca = 1;
        +		}
        +	ok = 1;
        + end:
        +	return ok;
        +#endif
        +}
        +
        +static int check_name_constraints(X509_STORE_CTX *ctx)
        +	{
        +	X509 *x;
        +	int i, j, rv;
        +	/* Check name constraints for all certificates */
        +	for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
        +		{
        +		x = sk_X509_value(ctx->chain, i);
        +		/* Ignore self issued certs unless last in chain */
        +		if (i && (x->ex_flags & EXFLAG_SI))
        +			continue;
        +		/* Check against constraints for all certificates higher in
        +		 * chain including trust anchor. Trust anchor not strictly
        +		 * speaking needed but if it includes constraints it is to be
        +		 * assumed it expects them to be obeyed.
        +		 */
        +		for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
        +			{
        +			NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
        +			if (nc)
        +				{
        +				rv = NAME_CONSTRAINTS_check(x, nc);
        +				if (rv != X509_V_OK)
        +					{
        +					ctx->error = rv;
        +					ctx->error_depth = i;
        +					ctx->current_cert = x;
        +					if (!ctx->verify_cb(0,ctx))
        +						return 0;
        +					}
        +				}
        +			}
        +		}
        +	return 1;
        +	}
        +
        +static int check_trust(X509_STORE_CTX *ctx)
        +{
        +#ifdef OPENSSL_NO_CHAIN_VERIFY
        +	return 1;
        +#else
        +	int i, ok;
        +	X509 *x;
        +	int (*cb)(int xok,X509_STORE_CTX *xctx);
        +	cb=ctx->verify_cb;
        +/* For now just check the last certificate in the chain */
        +	i = sk_X509_num(ctx->chain) - 1;
        +	x = sk_X509_value(ctx->chain, i);
        +	ok = X509_check_trust(x, ctx->param->trust, 0);
        +	if (ok == X509_TRUST_TRUSTED)
        +		return 1;
        +	ctx->error_depth = i;
        +	ctx->current_cert = x;
        +	if (ok == X509_TRUST_REJECTED)
        +		ctx->error = X509_V_ERR_CERT_REJECTED;
        +	else
        +		ctx->error = X509_V_ERR_CERT_UNTRUSTED;
        +	ok = cb(0, ctx);
        +	return ok;
        +#endif
        +}
        +
        +static int check_revocation(X509_STORE_CTX *ctx)
        +	{
        +	int i, last, ok;
        +	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
        +		return 1;
        +	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
        +		last = sk_X509_num(ctx->chain) - 1;
        +	else
        +		{
        +		/* If checking CRL paths this isn't the EE certificate */
        +		if (ctx->parent)
        +			return 1;
        +		last = 0;
        +		}
        +	for(i = 0; i <= last; i++)
        +		{
        +		ctx->error_depth = i;
        +		ok = check_cert(ctx);
        +		if (!ok) return ok;
        +		}
        +	return 1;
        +	}
        +
        +static int check_cert(X509_STORE_CTX *ctx)
        +	{
        +	X509_CRL *crl = NULL, *dcrl = NULL;
        +	X509 *x;
        +	int ok, cnum;
        +	cnum = ctx->error_depth;
        +	x = sk_X509_value(ctx->chain, cnum);
        +	ctx->current_cert = x;
        +	ctx->current_issuer = NULL;
        +	ctx->current_crl_score = 0;
        +	ctx->current_reasons = 0;
        +	while (ctx->current_reasons != CRLDP_ALL_REASONS)
        +		{
        +		/* Try to retrieve relevant CRL */
        +		if (ctx->get_crl)
        +			ok = ctx->get_crl(ctx, &crl, x);
        +		else
        +			ok = get_crl_delta(ctx, &crl, &dcrl, x);
        +		/* If error looking up CRL, nothing we can do except
        +		 * notify callback
        +		 */
        +		if(!ok)
        +			{
        +			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
        +			ok = ctx->verify_cb(0, ctx);
        +			goto err;
        +			}
        +		ctx->current_crl = crl;
        +		ok = ctx->check_crl(ctx, crl);
        +		if (!ok)
        +			goto err;
        +
        +		if (dcrl)
        +			{
        +			ok = ctx->check_crl(ctx, dcrl);
        +			if (!ok)
        +				goto err;
        +			ok = ctx->cert_crl(ctx, dcrl, x);
        +			if (!ok)
        +				goto err;
        +			}
        +		else
        +			ok = 1;
        +
        +		/* Don't look in full CRL if delta reason is removefromCRL */
        +		if (ok != 2)
        +			{
        +			ok = ctx->cert_crl(ctx, crl, x);
        +			if (!ok)
        +				goto err;
        +			}
        +
        +		X509_CRL_free(crl);
        +		X509_CRL_free(dcrl);
        +		crl = NULL;
        +		dcrl = NULL;
        +		}
        +	err:
        +	X509_CRL_free(crl);
        +	X509_CRL_free(dcrl);
        +
        +	ctx->current_crl = NULL;
        +	return ok;
        +
        +	}
        +
        +/* Check CRL times against values in X509_STORE_CTX */
        +
        +static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
        +	{
        +	time_t *ptime;
        +	int i;
        +	if (notify)
        +		ctx->current_crl = crl;
        +	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
        +		ptime = &ctx->param->check_time;
        +	else
        +		ptime = NULL;
        +
        +	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
        +	if (i == 0)
        +		{
        +		if (!notify)
        +			return 0;
        +		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
        +		if (!ctx->verify_cb(0, ctx))
        +			return 0;
        +		}
        +
        +	if (i > 0)
        +		{
        +		if (!notify)
        +			return 0;
        +		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
        +		if (!ctx->verify_cb(0, ctx))
        +			return 0;
        +		}
        +
        +	if(X509_CRL_get_nextUpdate(crl))
        +		{
        +		i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
        +
        +		if (i == 0)
        +			{
        +			if (!notify)
        +				return 0;
        +			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
        +			if (!ctx->verify_cb(0, ctx))
        +				return 0;
        +			}
        +		/* Ignore expiry of base CRL is delta is valid */
        +		if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
        +			{
        +			if (!notify)
        +				return 0;
        +			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
        +			if (!ctx->verify_cb(0, ctx))
        +				return 0;
        +			}
        +		}
        +
        +	if (notify)
        +		ctx->current_crl = NULL;
        +
        +	return 1;
        +	}
        +
        +static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
        +			X509 **pissuer, int *pscore, unsigned int *preasons,
        +			STACK_OF(X509_CRL) *crls)
        +	{
        +	int i, crl_score, best_score = *pscore;
        +	unsigned int reasons, best_reasons = 0;
        +	X509 *x = ctx->current_cert;
        +	X509_CRL *crl, *best_crl = NULL;
        +	X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
        +
        +	for (i = 0; i < sk_X509_CRL_num(crls); i++)
        +		{
        +		crl = sk_X509_CRL_value(crls, i);
        +		reasons = *preasons;
        +		crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
        +
        +		if (crl_score > best_score)
        +			{
        +			best_crl = crl;
        +			best_crl_issuer = crl_issuer;
        +			best_score = crl_score;
        +			best_reasons = reasons;
        +			}
        +		}
        +
        +	if (best_crl)
        +		{
        +		if (*pcrl)
        +			X509_CRL_free(*pcrl);
        +		*pcrl = best_crl;
        +		*pissuer = best_crl_issuer;
        +		*pscore = best_score;
        +		*preasons = best_reasons;
        +		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
        +		if (*pdcrl)
        +			{
        +			X509_CRL_free(*pdcrl);
        +			*pdcrl = NULL;
        +			}
        +		get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
        +		}
        +
        +	if (best_score >= CRL_SCORE_VALID)
        +		return 1;
        +
        +	return 0;
        +	}
        +
        +/* Compare two CRL extensions for delta checking purposes. They should be
        + * both present or both absent. If both present all fields must be identical.
        + */
        +
        +static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
        +	{
        +	ASN1_OCTET_STRING *exta, *extb;
        +	int i;
        +	i = X509_CRL_get_ext_by_NID(a, nid, -1);
        +	if (i >= 0)
        +		{
        +		/* Can't have multiple occurrences */
        +		if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
        +			return 0;
        +		exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
        +		}
        +	else
        +		exta = NULL;
        +
        +	i = X509_CRL_get_ext_by_NID(b, nid, -1);
        +
        +	if (i >= 0)
        +		{
        +
        +		if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
        +			return 0;
        +		extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
        +		}
        +	else
        +		extb = NULL;
        +
        +	if (!exta && !extb)
        +		return 1;
        +
        +	if (!exta || !extb)
        +		return 0;
        +
        +
        +	if (ASN1_OCTET_STRING_cmp(exta, extb))
        +		return 0;
        +
        +	return 1;
        +	}
        +
        +/* See if a base and delta are compatible */
        +
        +static int check_delta_base(X509_CRL *delta, X509_CRL *base)
        +	{
        +	/* Delta CRL must be a delta */
        +	if (!delta->base_crl_number)
        +			return 0;
        +	/* Base must have a CRL number */
        +	if (!base->crl_number)
        +			return 0;
        +	/* Issuer names must match */
        +	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
        +				X509_CRL_get_issuer(delta)))
        +		return 0;
        +	/* AKID and IDP must match */
        +	if (!crl_extension_match(delta, base, NID_authority_key_identifier))
        +			return 0;
        +	if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
        +			return 0;
        +	/* Delta CRL base number must not exceed Full CRL number. */
        +	if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
        +			return 0;
        +	/* Delta CRL number must exceed full CRL number */
        +	if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
        +			return 1;
        +	return 0;
        +	}
        +
        +/* For a given base CRL find a delta... maybe extend to delta scoring
        + * or retrieve a chain of deltas...
        + */
        +
        +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
        +			X509_CRL *base, STACK_OF(X509_CRL) *crls)
        +	{
        +	X509_CRL *delta;
        +	int i;
        +	if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
        +		return;
        +	if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
        +		return;
        +	for (i = 0; i < sk_X509_CRL_num(crls); i++)
        +		{
        +		delta = sk_X509_CRL_value(crls, i);
        +		if (check_delta_base(delta, base))
        +			{
        +			if (check_crl_time(ctx, delta, 0))
        +				*pscore |= CRL_SCORE_TIME_DELTA;
        +			CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
        +			*dcrl = delta;
        +			return;
        +			}
        +		}
        +	*dcrl = NULL;
        +	}
        +
        +/* For a given CRL return how suitable it is for the supplied certificate 'x'.
        + * The return value is a mask of several criteria.
        + * If the issuer is not the certificate issuer this is returned in *pissuer.
        + * The reasons mask is also used to determine if the CRL is suitable: if
        + * no new reasons the CRL is rejected, otherwise reasons is updated.
        + */
        +
        +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
        +			unsigned int *preasons,
        +			X509_CRL *crl, X509 *x)
        +	{
        +
        +	int crl_score = 0;
        +	unsigned int tmp_reasons = *preasons, crl_reasons;
        +
        +	/* First see if we can reject CRL straight away */
        +
        +	/* Invalid IDP cannot be processed */
        +	if (crl->idp_flags & IDP_INVALID)
        +		return 0;
        +	/* Reason codes or indirect CRLs need extended CRL support */
        +	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
        +		{
        +		if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
        +			return 0;
        +		}
        +	else if (crl->idp_flags & IDP_REASONS)
        +		{
        +		/* If no new reasons reject */
        +		if (!(crl->idp_reasons & ~tmp_reasons))
        +			return 0;
        +		}
        +	/* Don't process deltas at this stage */
        +	else if (crl->base_crl_number)
        +		return 0;
        +	/* If issuer name doesn't match certificate need indirect CRL */
        +	if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
        +		{
        +		if (!(crl->idp_flags & IDP_INDIRECT))
        +			return 0;
        +		}
        +	else
        +		crl_score |= CRL_SCORE_ISSUER_NAME;
        +
        +	if (!(crl->flags & EXFLAG_CRITICAL))
        +		crl_score |= CRL_SCORE_NOCRITICAL;
        +
        +	/* Check expiry */
        +	if (check_crl_time(ctx, crl, 0))
        +		crl_score |= CRL_SCORE_TIME;
        +
        +	/* Check authority key ID and locate certificate issuer */
        +	crl_akid_check(ctx, crl, pissuer, &crl_score);
        +
        +	/* If we can't locate certificate issuer at this point forget it */
        +
        +	if (!(crl_score & CRL_SCORE_AKID))
        +		return 0;
        +
        +	/* Check cert for matching CRL distribution points */
        +
        +	if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
        +		{
        +		/* If no new reasons reject */
        +		if (!(crl_reasons & ~tmp_reasons))
        +			return 0;
        +		tmp_reasons |= crl_reasons;
        +		crl_score |= CRL_SCORE_SCOPE;
        +		}
        +
        +	*preasons = tmp_reasons;
        +
        +	return crl_score;
        +
        +	}
        +
        +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
        +				X509 **pissuer, int *pcrl_score)
        +	{
        +	X509 *crl_issuer = NULL;
        +	X509_NAME *cnm = X509_CRL_get_issuer(crl);
        +	int cidx = ctx->error_depth;
        +	int i;
        +
        +	if (cidx != sk_X509_num(ctx->chain) - 1)
        +		cidx++;
        +
        +	crl_issuer = sk_X509_value(ctx->chain, cidx);
        +
        +	if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
        +		{
        +		if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
        +			{
        +			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
        +			*pissuer = crl_issuer;
        +			return;
        +			}
        +		}
        +
        +	for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++)
        +		{
        +		crl_issuer = sk_X509_value(ctx->chain, cidx);
        +		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
        +			continue;
        +		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
        +			{
        +			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
        +			*pissuer = crl_issuer;
        +			return;
        +			}
        +		}
        +
        +	/* Anything else needs extended CRL support */
        +
        +	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
        +		return;
        +
        +	/* Otherwise the CRL issuer is not on the path. Look for it in the
        +	 * set of untrusted certificates.
        +	 */
        +	for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
        +		{
        +		crl_issuer = sk_X509_value(ctx->untrusted, i);
        +		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
        +			continue;
        +		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
        +			{
        +			*pissuer = crl_issuer;
        +			*pcrl_score |= CRL_SCORE_AKID;
        +			return;
        +			}
        +		}
        +	}
        +
        +/* Check the path of a CRL issuer certificate. This creates a new
        + * X509_STORE_CTX and populates it with most of the parameters from the
        + * parent. This could be optimised somewhat since a lot of path checking
        + * will be duplicated by the parent, but this will rarely be used in 
        + * practice.
        + */
        +
        +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
        +	{
        +	X509_STORE_CTX crl_ctx;
        +	int ret;
        +	/* Don't allow recursive CRL path validation */
        +	if (ctx->parent)
        +		return 0;
        +	if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
        +		return -1;
        +
        +	crl_ctx.crls = ctx->crls;
        +	/* Copy verify params across */
        +	X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
        +
        +	crl_ctx.parent = ctx;
        +	crl_ctx.verify_cb = ctx->verify_cb;
        +
        +	/* Verify CRL issuer */
        +	ret = X509_verify_cert(&crl_ctx);
        +
        +	if (ret <= 0)
        +		goto err;
        +
        +	/* Check chain is acceptable */
        +
        +	ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
        +	err:
        +	X509_STORE_CTX_cleanup(&crl_ctx);
        +	return ret;
        +	}
        +
        +/* RFC3280 says nothing about the relationship between CRL path
        + * and certificate path, which could lead to situations where a
        + * certificate could be revoked or validated by a CA not authorised
        + * to do so. RFC5280 is more strict and states that the two paths must
        + * end in the same trust anchor, though some discussions remain...
        + * until this is resolved we use the RFC5280 version
        + */
        +
        +static int check_crl_chain(X509_STORE_CTX *ctx,
        +			STACK_OF(X509) *cert_path,
        +			STACK_OF(X509) *crl_path)
        +	{
        +	X509 *cert_ta, *crl_ta;
        +	cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
        +	crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
        +	if (!X509_cmp(cert_ta, crl_ta))
        +		return 1;
        +	return 0;
        +	}
        +
        +/* Check for match between two dist point names: three separate cases.
        + * 1. Both are relative names and compare X509_NAME types.
        + * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
        + * 3. Both are full names and compare two GENERAL_NAMES.
        + * 4. One is NULL: automatic match.
        + */
        +
        +
        +static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
        +	{
        +	X509_NAME *nm = NULL;
        +	GENERAL_NAMES *gens = NULL;
        +	GENERAL_NAME *gena, *genb;
        +	int i, j;
        +	if (!a || !b)
        +		return 1;
        +	if (a->type == 1)
        +		{
        +		if (!a->dpname)
        +			return 0;
        +		/* Case 1: two X509_NAME */
        +		if (b->type == 1)
        +			{
        +			if (!b->dpname)
        +				return 0;
        +			if (!X509_NAME_cmp(a->dpname, b->dpname))
        +				return 1;
        +			else
        +				return 0;
        +			}
        +		/* Case 2: set name and GENERAL_NAMES appropriately */
        +		nm = a->dpname;
        +		gens = b->name.fullname;
        +		}
        +	else if (b->type == 1)
        +		{
        +		if (!b->dpname)
        +			return 0;
        +		/* Case 2: set name and GENERAL_NAMES appropriately */
        +		gens = a->name.fullname;
        +		nm = b->dpname;
        +		}
        +
        +	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
        +	if (nm)
        +		{
        +		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
        +			{
        +			gena = sk_GENERAL_NAME_value(gens, i);	
        +			if (gena->type != GEN_DIRNAME)
        +				continue;
        +			if (!X509_NAME_cmp(nm, gena->d.directoryName))
        +				return 1;
        +			}
        +		return 0;
        +		}
        +
        +	/* Else case 3: two GENERAL_NAMES */
        +
        +	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
        +		{
        +		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
        +		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
        +			{
        +			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
        +			if (!GENERAL_NAME_cmp(gena, genb))
        +				return 1;
        +			}
        +		}
        +
        +	return 0;
        +
        +	}
        +
        +static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
        +	{
        +	int i;
        +	X509_NAME *nm = X509_CRL_get_issuer(crl);
        +	/* If no CRLissuer return is successful iff don't need a match */
        +	if (!dp->CRLissuer)
        +		return !!(crl_score & CRL_SCORE_ISSUER_NAME);
        +	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
        +		{
        +		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
        +		if (gen->type != GEN_DIRNAME)
        +			continue;
        +		if (!X509_NAME_cmp(gen->d.directoryName, nm))
        +			return 1;
        +		}
        +	return 0;
        +	}
        +
        +/* Check CRLDP and IDP */
        +
        +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
        +				unsigned int *preasons)
        +	{
        +	int i;
        +	if (crl->idp_flags & IDP_ONLYATTR)
        +		return 0;
        +	if (x->ex_flags & EXFLAG_CA)
        +		{
        +		if (crl->idp_flags & IDP_ONLYUSER)
        +			return 0;
        +		}
        +	else
        +		{
        +		if (crl->idp_flags & IDP_ONLYCA)
        +			return 0;
        +		}
        +	*preasons = crl->idp_reasons;
        +	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
        +		{
        +		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
        +		if (crldp_check_crlissuer(dp, crl, crl_score))
        +			{
        +			if (!crl->idp ||
        +			     idp_check_dp(dp->distpoint, crl->idp->distpoint))
        +				{
        +				*preasons &= dp->dp_reasons;
        +				return 1;
        +				}
        +			}
        +		}
        +	if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
        +		return 1;
        +	return 0;
        +	}
        +
        +/* Retrieve CRL corresponding to current certificate.
        + * If deltas enabled try to find a delta CRL too
        + */
        +	
        +static int get_crl_delta(X509_STORE_CTX *ctx,
        +				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
        +	{
        +	int ok;
        +	X509 *issuer = NULL;
        +	int crl_score = 0;
        +	unsigned int reasons;
        +	X509_CRL *crl = NULL, *dcrl = NULL;
        +	STACK_OF(X509_CRL) *skcrl;
        +	X509_NAME *nm = X509_get_issuer_name(x);
        +	reasons = ctx->current_reasons;
        +	ok = get_crl_sk(ctx, &crl, &dcrl, 
        +				&issuer, &crl_score, &reasons, ctx->crls);
        +
        +	if (ok)
        +		goto done;
        +
        +	/* Lookup CRLs from store */
        +
        +	skcrl = ctx->lookup_crls(ctx, nm);
        +
        +	/* If no CRLs found and a near match from get_crl_sk use that */
        +	if (!skcrl && crl)
        +		goto done;
        +
        +	get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
        +
        +	sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
        +
        +	done:
        +
        +	/* If we got any kind of CRL use it and return success */
        +	if (crl)
        +		{
        +		ctx->current_issuer = issuer;
        +		ctx->current_crl_score = crl_score;
        +		ctx->current_reasons = reasons;
        +		*pcrl = crl;
        +		*pdcrl = dcrl;
        +		return 1;
        +		}
        +
        +	return 0;
        +	}
        +
        +/* Check CRL validity */
        +static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
        +	{
        +	X509 *issuer = NULL;
        +	EVP_PKEY *ikey = NULL;
        +	int ok = 0, chnum, cnum;
        +	cnum = ctx->error_depth;
        +	chnum = sk_X509_num(ctx->chain) - 1;
        +	/* if we have an alternative CRL issuer cert use that */
        +	if (ctx->current_issuer)
        +		issuer = ctx->current_issuer;
        +
        +	/* Else find CRL issuer: if not last certificate then issuer
        +	 * is next certificate in chain.
        +	 */
        +	else if (cnum < chnum)
        +		issuer = sk_X509_value(ctx->chain, cnum + 1);
        +	else
        +		{
        +		issuer = sk_X509_value(ctx->chain, chnum);
        +		/* If not self signed, can't check signature */
        +		if(!ctx->check_issued(ctx, issuer, issuer))
        +			{
        +			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
        +			ok = ctx->verify_cb(0, ctx);
        +			if(!ok) goto err;
        +			}
        +		}
        +
        +	if(issuer)
        +		{
        +		/* Skip most tests for deltas because they have already
        +		 * been done
        +		 */
        +		if (!crl->base_crl_number)
        +			{
        +			/* Check for cRLSign bit if keyUsage present */
        +			if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
        +				!(issuer->ex_kusage & KU_CRL_SIGN))
        +				{
        +				ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
        +				ok = ctx->verify_cb(0, ctx);
        +				if(!ok) goto err;
        +				}
        +
        +			if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
        +				{
        +				ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
        +				ok = ctx->verify_cb(0, ctx);
        +				if(!ok) goto err;
        +				}
        +
        +			if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
        +				{
        +				if (check_crl_path(ctx, ctx->current_issuer) <= 0)
        +					{
        +					ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
        +					ok = ctx->verify_cb(0, ctx);
        +					if(!ok) goto err;
        +					}
        +				}
        +
        +			if (crl->idp_flags & IDP_INVALID)
        +				{
        +				ctx->error = X509_V_ERR_INVALID_EXTENSION;
        +				ok = ctx->verify_cb(0, ctx);
        +				if(!ok) goto err;
        +				}
        +
        +
        +			}
        +
        +		if (!(ctx->current_crl_score & CRL_SCORE_TIME))
        +			{
        +			ok = check_crl_time(ctx, crl, 1);
        +			if (!ok)
        +				goto err;
        +			}
        +
        +		/* Attempt to get issuer certificate public key */
        +		ikey = X509_get_pubkey(issuer);
        +
        +		if(!ikey)
        +			{
        +			ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
        +			ok = ctx->verify_cb(0, ctx);
        +			if (!ok) goto err;
        +			}
        +		else
        +			{
        +			/* Verify CRL signature */
        +			if(X509_CRL_verify(crl, ikey) <= 0)
        +				{
        +				ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
        +				ok = ctx->verify_cb(0, ctx);
        +				if (!ok) goto err;
        +				}
        +			}
        +		}
        +
        +	ok = 1;
        +
        +	err:
        +	EVP_PKEY_free(ikey);
        +	return ok;
        +	}
        +
        +/* Check certificate against CRL */
        +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
        +	{
        +	int ok;
        +	X509_REVOKED *rev;
        +	/* The rules changed for this... previously if a CRL contained
        +	 * unhandled critical extensions it could still be used to indicate
        +	 * a certificate was revoked. This has since been changed since 
        +	 * critical extension can change the meaning of CRL entries.
        +	 */
        +	if (crl->flags & EXFLAG_CRITICAL)
        +		{
        +		if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
        +			return 1;
        +		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
        +		ok = ctx->verify_cb(0, ctx);
        +		if(!ok)
        +			return 0;
        +		}
        +	/* Look for serial number of certificate in CRL
        +	 * If found make sure reason is not removeFromCRL.
        +	 */
        +	if (X509_CRL_get0_by_cert(crl, &rev, x))
        +		{
        +		if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
        +			return 2;
        +		ctx->error = X509_V_ERR_CERT_REVOKED;
        +		ok = ctx->verify_cb(0, ctx);
        +		if (!ok)
        +			return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int check_policy(X509_STORE_CTX *ctx)
        +	{
        +	int ret;
        +	if (ctx->parent)
        +		return 1;
        +	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
        +				ctx->param->policies, ctx->param->flags);
        +	if (ret == 0)
        +		{
        +		X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	/* Invalid or inconsistent extensions */
        +	if (ret == -1)
        +		{
        +		/* Locate certificates with bad extensions and notify
        +		 * callback.
        +		 */
        +		X509 *x;
        +		int i;
        +		for (i = 1; i < sk_X509_num(ctx->chain); i++)
        +			{
        +			x = sk_X509_value(ctx->chain, i);
        +			if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
        +				continue;
        +			ctx->current_cert = x;
        +			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
        +			if(!ctx->verify_cb(0, ctx))
        +				return 0;
        +			}
        +		return 1;
        +		}
        +	if (ret == -2)
        +		{
        +		ctx->current_cert = NULL;
        +		ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
        +		return ctx->verify_cb(0, ctx);
        +		}
        +
        +	if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
        +		{
        +		ctx->current_cert = NULL;
        +		ctx->error = X509_V_OK;
        +		if (!ctx->verify_cb(2, ctx))
        +			return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
        +	{
        +	time_t *ptime;
        +	int i;
        +
        +	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
        +		ptime = &ctx->param->check_time;
        +	else
        +		ptime = NULL;
        +
        +	i=X509_cmp_time(X509_get_notBefore(x), ptime);
        +	if (i == 0)
        +		{
        +		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
        +		ctx->current_cert=x;
        +		if (!ctx->verify_cb(0, ctx))
        +			return 0;
        +		}
        +
        +	if (i > 0)
        +		{
        +		ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
        +		ctx->current_cert=x;
        +		if (!ctx->verify_cb(0, ctx))
        +			return 0;
        +		}
        +
        +	i=X509_cmp_time(X509_get_notAfter(x), ptime);
        +	if (i == 0)
        +		{
        +		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
        +		ctx->current_cert=x;
        +		if (!ctx->verify_cb(0, ctx))
        +			return 0;
        +		}
        +
        +	if (i < 0)
        +		{
        +		ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
        +		ctx->current_cert=x;
        +		if (!ctx->verify_cb(0, ctx))
        +			return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int internal_verify(X509_STORE_CTX *ctx)
        +	{
        +	int ok=0,n;
        +	X509 *xs,*xi;
        +	EVP_PKEY *pkey=NULL;
        +	int (*cb)(int xok,X509_STORE_CTX *xctx);
        +
        +	cb=ctx->verify_cb;
        +
        +	n=sk_X509_num(ctx->chain);
        +	ctx->error_depth=n-1;
        +	n--;
        +	xi=sk_X509_value(ctx->chain,n);
        +
        +	if (ctx->check_issued(ctx, xi, xi))
        +		xs=xi;
        +	else
        +		{
        +		if (n <= 0)
        +			{
        +			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
        +			ctx->current_cert=xi;
        +			ok=cb(0,ctx);
        +			goto end;
        +			}
        +		else
        +			{
        +			n--;
        +			ctx->error_depth=n;
        +			xs=sk_X509_value(ctx->chain,n);
        +			}
        +		}
        +
        +/*	ctx->error=0;  not needed */
        +	while (n >= 0)
        +		{
        +		ctx->error_depth=n;
        +
        +		/* Skip signature check for self signed certificates unless
        +		 * explicitly asked for. It doesn't add any security and
        +		 * just wastes time.
        +		 */
        +		if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
        +			{
        +			if ((pkey=X509_get_pubkey(xi)) == NULL)
        +				{
        +				ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
        +				ctx->current_cert=xi;
        +				ok=(*cb)(0,ctx);
        +				if (!ok) goto end;
        +				}
        +			else if (X509_verify(xs,pkey) <= 0)
        +				{
        +				ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
        +				ctx->current_cert=xs;
        +				ok=(*cb)(0,ctx);
        +				if (!ok)
        +					{
        +					EVP_PKEY_free(pkey);
        +					goto end;
        +					}
        +				}
        +			EVP_PKEY_free(pkey);
        +			pkey=NULL;
        +			}
        +
        +		xs->valid = 1;
        +
        +		ok = check_cert_time(ctx, xs);
        +		if (!ok)
        +			goto end;
        +
        +		/* The last error (if any) is still in the error value */
        +		ctx->current_issuer=xi;
        +		ctx->current_cert=xs;
        +		ok=(*cb)(1,ctx);
        +		if (!ok) goto end;
        +
        +		n--;
        +		if (n >= 0)
        +			{
        +			xi=xs;
        +			xs=sk_X509_value(ctx->chain,n);
        +			}
        +		}
        +	ok=1;
        +end:
        +	return ok;
        +	}
        +
        +int X509_cmp_current_time(const ASN1_TIME *ctm)
        +{
        +	return X509_cmp_time(ctm, NULL);
        +}
        +
        +int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
        +	{
        +	char *str;
        +	ASN1_TIME atm;
        +	long offset;
        +	char buff1[24],buff2[24],*p;
        +	int i,j;
        +
        +	p=buff1;
        +	i=ctm->length;
        +	str=(char *)ctm->data;
        +	if (ctm->type == V_ASN1_UTCTIME)
        +		{
        +		if ((i < 11) || (i > 17)) return 0;
        +		memcpy(p,str,10);
        +		p+=10;
        +		str+=10;
        +		}
        +	else
        +		{
        +		if (i < 13) return 0;
        +		memcpy(p,str,12);
        +		p+=12;
        +		str+=12;
        +		}
        +
        +	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
        +		{ *(p++)='0'; *(p++)='0'; }
        +	else
        +		{ 
        +		*(p++)= *(str++);
        +		*(p++)= *(str++);
        +		/* Skip any fractional seconds... */
        +		if (*str == '.')
        +			{
        +			str++;
        +			while ((*str >= '0') && (*str <= '9')) str++;
        +			}
        +		
        +		}
        +	*(p++)='Z';
        +	*(p++)='\0';
        +
        +	if (*str == 'Z')
        +		offset=0;
        +	else
        +		{
        +		if ((*str != '+') && (*str != '-'))
        +			return 0;
        +		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
        +		offset+=(str[3]-'0')*10+(str[4]-'0');
        +		if (*str == '-')
        +			offset= -offset;
        +		}
        +	atm.type=ctm->type;
        +	atm.flags = 0;
        +	atm.length=sizeof(buff2);
        +	atm.data=(unsigned char *)buff2;
        +
        +	if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
        +		return 0;
        +
        +	if (ctm->type == V_ASN1_UTCTIME)
        +		{
        +		i=(buff1[0]-'0')*10+(buff1[1]-'0');
        +		if (i < 50) i+=100; /* cf. RFC 2459 */
        +		j=(buff2[0]-'0')*10+(buff2[1]-'0');
        +		if (j < 50) j+=100;
        +
        +		if (i < j) return -1;
        +		if (i > j) return 1;
        +		}
        +	i=strcmp(buff1,buff2);
        +	if (i == 0) /* wait a second then return younger :-) */
        +		return -1;
        +	else
        +		return i;
        +	}
        +
        +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
        +{
        +	return X509_time_adj(s, adj, NULL);
        +}
        +
        +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
        +	{
        +	return X509_time_adj_ex(s, 0, offset_sec, in_tm);
        +	}
        +
        +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
        +				int offset_day, long offset_sec, time_t *in_tm)
        +	{
        +	time_t t;
        +
        +	if (in_tm) t = *in_tm;
        +	else time(&t);
        +
        +	if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
        +		{
        +		if (s->type == V_ASN1_UTCTIME)
        +			return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
        +		if (s->type == V_ASN1_GENERALIZEDTIME)
        +			return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
        +								offset_sec);
        +		}
        +	return ASN1_TIME_adj(s, t, offset_day, offset_sec);
        +	}
        +
        +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
        +	{
        +	EVP_PKEY *ktmp=NULL,*ktmp2;
        +	int i,j;
        +
        +	if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1;
        +
        +	for (i=0; i<sk_X509_num(chain); i++)
        +		{
        +		ktmp=X509_get_pubkey(sk_X509_value(chain,i));
        +		if (ktmp == NULL)
        +			{
        +			X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
        +			return 0;
        +			}
        +		if (!EVP_PKEY_missing_parameters(ktmp))
        +			break;
        +		else
        +			{
        +			EVP_PKEY_free(ktmp);
        +			ktmp=NULL;
        +			}
        +		}
        +	if (ktmp == NULL)
        +		{
        +		X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
        +		return 0;
        +		}
        +
        +	/* first, populate the other certs */
        +	for (j=i-1; j >= 0; j--)
        +		{
        +		ktmp2=X509_get_pubkey(sk_X509_value(chain,j));
        +		EVP_PKEY_copy_parameters(ktmp2,ktmp);
        +		EVP_PKEY_free(ktmp2);
        +		}
        +	
        +	if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp);
        +	EVP_PKEY_free(ktmp);
        +	return 1;
        +	}
        +
        +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +	{
        +	/* This function is (usually) called only once, by
        +	 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
        +			new_func, dup_func, free_func);
        +	}
        +
        +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
        +	{
        +	return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
        +	}
        +
        +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
        +	{
        +	return CRYPTO_get_ex_data(&ctx->ex_data,idx);
        +	}
        +
        +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->error;
        +	}
        +
        +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
        +	{
        +	ctx->error=err;
        +	}
        +
        +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->error_depth;
        +	}
        +
        +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->current_cert;
        +	}
        +
        +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->chain;
        +	}
        +
        +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
        +	{
        +	int i;
        +	X509 *x;
        +	STACK_OF(X509) *chain;
        +	if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL;
        +	for (i = 0; i < sk_X509_num(chain); i++)
        +		{
        +		x = sk_X509_value(chain, i);
        +		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
        +		}
        +	return chain;
        +	}
        +
        +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->current_issuer;
        +	}
        +
        +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->current_crl;
        +	}
        +
        +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->parent;
        +	}
        +
        +void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
        +	{
        +	ctx->cert=x;
        +	}
        +
        +void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
        +	{
        +	ctx->untrusted=sk;
        +	}
        +
        +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
        +	{
        +	ctx->crls=sk;
        +	}
        +
        +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
        +	{
        +	return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
        +	}
        +
        +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
        +	{
        +	return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
        +	}
        +
        +/* This function is used to set the X509_STORE_CTX purpose and trust
        + * values. This is intended to be used when another structure has its
        + * own trust and purpose values which (if set) will be inherited by
        + * the ctx. If they aren't set then we will usually have a default
        + * purpose in mind which should then be used to set the trust value.
        + * An example of this is SSL use: an SSL structure will have its own
        + * purpose and trust settings which the application can set: if they
        + * aren't set then we use the default of SSL client/server.
        + */
        +
        +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
        +				int purpose, int trust)
        +{
        +	int idx;
        +	/* If purpose not set use default */
        +	if (!purpose) purpose = def_purpose;
        +	/* If we have a purpose then check it is valid */
        +	if (purpose)
        +		{
        +		X509_PURPOSE *ptmp;
        +		idx = X509_PURPOSE_get_by_id(purpose);
        +		if (idx == -1)
        +			{
        +			X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
        +						X509_R_UNKNOWN_PURPOSE_ID);
        +			return 0;
        +			}
        +		ptmp = X509_PURPOSE_get0(idx);
        +		if (ptmp->trust == X509_TRUST_DEFAULT)
        +			{
        +			idx = X509_PURPOSE_get_by_id(def_purpose);
        +			if (idx == -1)
        +				{
        +				X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
        +						X509_R_UNKNOWN_PURPOSE_ID);
        +				return 0;
        +				}
        +			ptmp = X509_PURPOSE_get0(idx);
        +			}
        +		/* If trust not set then get from purpose default */
        +		if (!trust) trust = ptmp->trust;
        +		}
        +	if (trust)
        +		{
        +		idx = X509_TRUST_get_by_id(trust);
        +		if (idx == -1)
        +			{
        +			X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
        +						X509_R_UNKNOWN_TRUST_ID);
        +			return 0;
        +			}
        +		}
        +
        +	if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
        +	if (trust && !ctx->param->trust) ctx->param->trust = trust;
        +	return 1;
        +}
        +
        +X509_STORE_CTX *X509_STORE_CTX_new(void)
        +{
        +	X509_STORE_CTX *ctx;
        +	ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
        +	if (!ctx)
        +		{
        +		X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	memset(ctx, 0, sizeof(X509_STORE_CTX));
        +	return ctx;
        +}
        +
        +void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
        +{
        +	X509_STORE_CTX_cleanup(ctx);
        +	OPENSSL_free(ctx);
        +}
        +
        +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
        +	     STACK_OF(X509) *chain)
        +	{
        +	int ret = 1;
        +	ctx->ctx=store;
        +	ctx->current_method=0;
        +	ctx->cert=x509;
        +	ctx->untrusted=chain;
        +	ctx->crls = NULL;
        +	ctx->last_untrusted=0;
        +	ctx->other_ctx=NULL;
        +	ctx->valid=0;
        +	ctx->chain=NULL;
        +	ctx->error=0;
        +	ctx->explicit_policy=0;
        +	ctx->error_depth=0;
        +	ctx->current_cert=NULL;
        +	ctx->current_issuer=NULL;
        +	ctx->current_crl=NULL;
        +	ctx->current_crl_score=0;
        +	ctx->current_reasons=0;
        +	ctx->tree = NULL;
        +	ctx->parent = NULL;
        +
        +	ctx->param = X509_VERIFY_PARAM_new();
        +
        +	if (!ctx->param)
        +		{
        +		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	/* Inherit callbacks and flags from X509_STORE if not set
        +	 * use defaults.
        +	 */
        +
        +
        +	if (store)
        +		ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
        +	else
        +		ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
        +
        +	if (store)
        +		{
        +		ctx->verify_cb = store->verify_cb;
        +		ctx->cleanup = store->cleanup;
        +		}
        +	else
        +		ctx->cleanup = 0;
        +
        +	if (ret)
        +		ret = X509_VERIFY_PARAM_inherit(ctx->param,
        +					X509_VERIFY_PARAM_lookup("default"));
        +
        +	if (ret == 0)
        +		{
        +		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +
        +	if (store && store->check_issued)
        +		ctx->check_issued = store->check_issued;
        +	else
        +		ctx->check_issued = check_issued;
        +
        +	if (store && store->get_issuer)
        +		ctx->get_issuer = store->get_issuer;
        +	else
        +		ctx->get_issuer = X509_STORE_CTX_get1_issuer;
        +
        +	if (store && store->verify_cb)
        +		ctx->verify_cb = store->verify_cb;
        +	else
        +		ctx->verify_cb = null_callback;
        +
        +	if (store && store->verify)
        +		ctx->verify = store->verify;
        +	else
        +		ctx->verify = internal_verify;
        +
        +	if (store && store->check_revocation)
        +		ctx->check_revocation = store->check_revocation;
        +	else
        +		ctx->check_revocation = check_revocation;
        +
        +	if (store && store->get_crl)
        +		ctx->get_crl = store->get_crl;
        +	else
        +		ctx->get_crl = NULL;
        +
        +	if (store && store->check_crl)
        +		ctx->check_crl = store->check_crl;
        +	else
        +		ctx->check_crl = check_crl;
        +
        +	if (store && store->cert_crl)
        +		ctx->cert_crl = store->cert_crl;
        +	else
        +		ctx->cert_crl = cert_crl;
        +
        +	if (store && store->lookup_certs)
        +		ctx->lookup_certs = store->lookup_certs;
        +	else
        +		ctx->lookup_certs = X509_STORE_get1_certs;
        +
        +	if (store && store->lookup_crls)
        +		ctx->lookup_crls = store->lookup_crls;
        +	else
        +		ctx->lookup_crls = X509_STORE_get1_crls;
        +
        +	ctx->check_policy = check_policy;
        +
        +
        +	/* This memset() can't make any sense anyway, so it's removed. As
        +	 * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
        +	 * corresponding "new" here and remove this bogus initialisation. */
        +	/* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
        +	if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
        +				&(ctx->ex_data)))
        +		{
        +		OPENSSL_free(ctx);
        +		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* Set alternative lookup method: just a STACK of trusted certificates.
        + * This avoids X509_STORE nastiness where it isn't needed.
        + */
        +
        +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
        +{
        +	ctx->other_ctx = sk;
        +	ctx->get_issuer = get_issuer_sk;
        +}
        +
        +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
        +	{
        +	if (ctx->cleanup) ctx->cleanup(ctx);
        +	if (ctx->param != NULL)
        +		{
        +		if (ctx->parent == NULL)
        +			X509_VERIFY_PARAM_free(ctx->param);
        +		ctx->param=NULL;
        +		}
        +	if (ctx->tree != NULL)
        +		{
        +		X509_policy_tree_free(ctx->tree);
        +		ctx->tree=NULL;
        +		}
        +	if (ctx->chain != NULL)
        +		{
        +		sk_X509_pop_free(ctx->chain,X509_free);
        +		ctx->chain=NULL;
        +		}
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
        +	memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
        +	}
        +
        +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
        +	{
        +	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
        +	}
        +
        +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
        +	{
        +	X509_VERIFY_PARAM_set_flags(ctx->param, flags);
        +	}
        +
        +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
        +	{
        +	X509_VERIFY_PARAM_set_time(ctx->param, t);
        +	}
        +
        +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
        +				  int (*verify_cb)(int, X509_STORE_CTX *))
        +	{
        +	ctx->verify_cb=verify_cb;
        +	}
        +
        +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->tree;
        +	}
        +
        +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->explicit_policy;
        +	}
        +
        +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
        +	{
        +	const X509_VERIFY_PARAM *param;
        +	param = X509_VERIFY_PARAM_lookup(name);
        +	if (!param)
        +		return 0;
        +	return X509_VERIFY_PARAM_inherit(ctx->param, param);
        +	}
        +
        +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
        +	{
        +	return ctx->param;
        +	}
        +
        +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
        +	{
        +	if (ctx->param)
        +		X509_VERIFY_PARAM_free(ctx->param);
        +	ctx->param = param;
        +	}
        +
        +IMPLEMENT_STACK_OF(X509)
        +IMPLEMENT_ASN1_SET_OF(X509)
        +
        +IMPLEMENT_STACK_OF(X509_NAME)
        +
        +IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
        +IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_vfy.h b/vendor/openssl/openssl/crypto/x509/x509_vfy.h
        new file mode 100644
        index 000000000..fe09b30aa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_vfy.h
        @@ -0,0 +1,567 @@
        +/* crypto/x509/x509_vfy.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_X509_H
        +#include <openssl/x509.h>
        +/* openssl/x509.h ends up #include-ing this file at about the only
        + * appropriate moment. */
        +#endif
        +
        +#ifndef HEADER_X509_VFY_H
        +#define HEADER_X509_VFY_H
        +
        +#include <openssl/opensslconf.h>
        +#ifndef OPENSSL_NO_LHASH
        +#include <openssl/lhash.h>
        +#endif
        +#include <openssl/bio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/symhacks.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#if 0
        +/* Outer object */
        +typedef struct x509_hash_dir_st
        +	{
        +	int num_dirs;
        +	char **dirs;
        +	int *dirs_type;
        +	int num_dirs_alloced;
        +	} X509_HASH_DIR_CTX;
        +#endif
        +
        +typedef struct x509_file_st
        +	{
        +	int num_paths;	/* number of paths to files or directories */
        +	int num_alloced;
        +	char **paths;	/* the list of paths or directories */
        +	int *path_type;
        +	} X509_CERT_FILE_CTX;
        +
        +/*******************************/
        +/*
        +SSL_CTX -> X509_STORE    
        +		-> X509_LOOKUP
        +			->X509_LOOKUP_METHOD
        +		-> X509_LOOKUP
        +			->X509_LOOKUP_METHOD
        + 
        +SSL	-> X509_STORE_CTX
        +		->X509_STORE    
        +
        +The X509_STORE holds the tables etc for verification stuff.
        +A X509_STORE_CTX is used while validating a single certificate.
        +The X509_STORE has X509_LOOKUPs for looking up certs.
        +The X509_STORE then calls a function to actually verify the
        +certificate chain.
        +*/
        +
        +#define X509_LU_RETRY		-1
        +#define X509_LU_FAIL		0
        +#define X509_LU_X509		1
        +#define X509_LU_CRL		2
        +#define X509_LU_PKEY		3
        +
        +typedef struct x509_object_st
        +	{
        +	/* one of the above types */
        +	int type;
        +	union	{
        +		char *ptr;
        +		X509 *x509;
        +		X509_CRL *crl;
        +		EVP_PKEY *pkey;
        +		} data;
        +	} X509_OBJECT;
        +
        +typedef struct x509_lookup_st X509_LOOKUP;
        +
        +DECLARE_STACK_OF(X509_LOOKUP)
        +DECLARE_STACK_OF(X509_OBJECT)
        +
        +/* This is a static that defines the function interface */
        +typedef struct x509_lookup_method_st
        +	{
        +	const char *name;
        +	int (*new_item)(X509_LOOKUP *ctx);
        +	void (*free)(X509_LOOKUP *ctx);
        +	int (*init)(X509_LOOKUP *ctx);
        +	int (*shutdown)(X509_LOOKUP *ctx);
        +	int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl,
        +			char **ret);
        +	int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name,
        +			      X509_OBJECT *ret);
        +	int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name,
        +				    ASN1_INTEGER *serial,X509_OBJECT *ret);
        +	int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type,
        +				  unsigned char *bytes,int len,
        +				  X509_OBJECT *ret);
        +	int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len,
        +			    X509_OBJECT *ret);
        +	} X509_LOOKUP_METHOD;
        +
        +/* This structure hold all parameters associated with a verify operation
        + * by including an X509_VERIFY_PARAM structure in related structures the
        + * parameters used can be customized
        + */
        +
        +typedef struct X509_VERIFY_PARAM_st
        +	{
        +	char *name;
        +	time_t check_time;	/* Time to use */
        +	unsigned long inh_flags; /* Inheritance flags */
        +	unsigned long flags;	/* Various verify flags */
        +	int purpose;		/* purpose to check untrusted certificates */
        +	int trust;		/* trust setting to check */
        +	int depth;		/* Verify depth */
        +	STACK_OF(ASN1_OBJECT) *policies;	/* Permissible policies */
        +	} X509_VERIFY_PARAM;
        +
        +DECLARE_STACK_OF(X509_VERIFY_PARAM)
        +
        +/* This is used to hold everything.  It is used for all certificate
        + * validation.  Once we have a certificate chain, the 'verify'
        + * function is then called to actually check the cert chain. */
        +struct x509_store_st
        +	{
        +	/* The following is a cache of trusted certs */
        +	int cache; 	/* if true, stash any hits */
        +	STACK_OF(X509_OBJECT) *objs;	/* Cache of all objects */
        +
        +	/* These are external lookup methods */
        +	STACK_OF(X509_LOOKUP) *get_cert_methods;
        +
        +	X509_VERIFY_PARAM *param;
        +
        +	/* Callbacks for various operations */
        +	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
        +	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);	/* error callback */
        +	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
        +	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
        +	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
        +	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
        +	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
        +	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
        +	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
        +	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
        +	int (*cleanup)(X509_STORE_CTX *ctx);
        +
        +	CRYPTO_EX_DATA ex_data;
        +	int references;
        +	} /* X509_STORE */;
        +
        +int X509_STORE_set_depth(X509_STORE *store, int depth);
        +
        +#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
        +#define X509_STORE_set_verify_func(ctx,func)	((ctx)->verify=(func))
        +
        +/* This is the functions plus an instance of the local variables. */
        +struct x509_lookup_st
        +	{
        +	int init;			/* have we been started */
        +	int skip;			/* don't use us. */
        +	X509_LOOKUP_METHOD *method;	/* the functions */
        +	char *method_data;		/* method data */
        +
        +	X509_STORE *store_ctx;	/* who owns us */
        +	} /* X509_LOOKUP */;
        +
        +/* This is a used when verifying cert chains.  Since the
        + * gathering of the cert chain can take some time (and have to be
        + * 'retried', this needs to be kept and passed around. */
        +struct x509_store_ctx_st      /* X509_STORE_CTX */
        +	{
        +	X509_STORE *ctx;
        +	int current_method;	/* used when looking up certs */
        +
        +	/* The following are set by the caller */
        +	X509 *cert;		/* The cert to check */
        +	STACK_OF(X509) *untrusted;	/* chain of X509s - untrusted - passed in */
        +	STACK_OF(X509_CRL) *crls;	/* set of CRLs passed in */
        +
        +	X509_VERIFY_PARAM *param;
        +	void *other_ctx;	/* Other info for use with get_issuer() */
        +
        +	/* Callbacks for various operations */
        +	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
        +	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);		/* error callback */
        +	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
        +	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
        +	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
        +	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
        +	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
        +	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
        +	int (*check_policy)(X509_STORE_CTX *ctx);
        +	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
        +	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
        +	int (*cleanup)(X509_STORE_CTX *ctx);
        +
        +	/* The following is built up */
        +	int valid;		/* if 0, rebuild chain */
        +	int last_untrusted;	/* index of last untrusted cert */
        +	STACK_OF(X509) *chain; 		/* chain of X509s - built up and trusted */
        +	X509_POLICY_TREE *tree;	/* Valid policy tree */
        +
        +	int explicit_policy;	/* Require explicit policy value */
        +
        +	/* When something goes wrong, this is why */
        +	int error_depth;
        +	int error;
        +	X509 *current_cert;
        +	X509 *current_issuer;	/* cert currently being tested as valid issuer */
        +	X509_CRL *current_crl;	/* current CRL */
        +
        +	int current_crl_score;  /* score of current CRL */
        +	unsigned int current_reasons;  /* Reason mask */
        +
        +	X509_STORE_CTX *parent; /* For CRL path validation: parent context */
        +
        +	CRYPTO_EX_DATA ex_data;
        +	} /* X509_STORE_CTX */;
        +
        +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
        +
        +#define X509_STORE_CTX_set_app_data(ctx,data) \
        +	X509_STORE_CTX_set_ex_data(ctx,0,data)
        +#define X509_STORE_CTX_get_app_data(ctx) \
        +	X509_STORE_CTX_get_ex_data(ctx,0)
        +
        +#define X509_L_FILE_LOAD	1
        +#define X509_L_ADD_DIR		2
        +
        +#define X509_LOOKUP_load_file(x,name,type) \
        +		X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
        +
        +#define X509_LOOKUP_add_dir(x,name,type) \
        +		X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
        +
        +#define		X509_V_OK					0
        +/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */
        +
        +#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT		2
        +#define		X509_V_ERR_UNABLE_TO_GET_CRL			3
        +#define		X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE	4
        +#define		X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE	5
        +#define		X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY	6
        +#define		X509_V_ERR_CERT_SIGNATURE_FAILURE		7
        +#define		X509_V_ERR_CRL_SIGNATURE_FAILURE		8
        +#define		X509_V_ERR_CERT_NOT_YET_VALID			9
        +#define		X509_V_ERR_CERT_HAS_EXPIRED			10
        +#define		X509_V_ERR_CRL_NOT_YET_VALID			11
        +#define		X509_V_ERR_CRL_HAS_EXPIRED			12
        +#define		X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD	13
        +#define		X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD	14
        +#define		X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD	15
        +#define		X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD	16
        +#define		X509_V_ERR_OUT_OF_MEM				17
        +#define		X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT		18
        +#define		X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN		19
        +#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY	20
        +#define		X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE	21
        +#define		X509_V_ERR_CERT_CHAIN_TOO_LONG			22
        +#define		X509_V_ERR_CERT_REVOKED				23
        +#define		X509_V_ERR_INVALID_CA				24
        +#define		X509_V_ERR_PATH_LENGTH_EXCEEDED			25
        +#define		X509_V_ERR_INVALID_PURPOSE			26
        +#define		X509_V_ERR_CERT_UNTRUSTED			27
        +#define		X509_V_ERR_CERT_REJECTED			28
        +/* These are 'informational' when looking for issuer cert */
        +#define		X509_V_ERR_SUBJECT_ISSUER_MISMATCH		29
        +#define		X509_V_ERR_AKID_SKID_MISMATCH			30
        +#define		X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH		31
        +#define		X509_V_ERR_KEYUSAGE_NO_CERTSIGN			32
        +
        +#define		X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER		33
        +#define		X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION		34
        +#define		X509_V_ERR_KEYUSAGE_NO_CRL_SIGN			35
        +#define		X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION	36
        +#define		X509_V_ERR_INVALID_NON_CA			37
        +#define		X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED		38
        +#define		X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE	39
        +#define		X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED	40
        +
        +#define		X509_V_ERR_INVALID_EXTENSION			41
        +#define		X509_V_ERR_INVALID_POLICY_EXTENSION		42
        +#define		X509_V_ERR_NO_EXPLICIT_POLICY			43
        +#define		X509_V_ERR_DIFFERENT_CRL_SCOPE			44
        +#define		X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE	45
        +
        +#define		X509_V_ERR_UNNESTED_RESOURCE			46
        +
        +#define		X509_V_ERR_PERMITTED_VIOLATION			47
        +#define		X509_V_ERR_EXCLUDED_VIOLATION			48
        +#define		X509_V_ERR_SUBTREE_MINMAX			49
        +#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE		51
        +#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX	52
        +#define		X509_V_ERR_UNSUPPORTED_NAME_SYNTAX		53
        +#define		X509_V_ERR_CRL_PATH_VALIDATION_ERROR		54
        +
        +/* The application is not happy */
        +#define		X509_V_ERR_APPLICATION_VERIFICATION		50
        +
        +/* Certificate verify flags */
        +
        +/* Send issuer+subject checks to verify_cb */
        +#define	X509_V_FLAG_CB_ISSUER_CHECK		0x1
        +/* Use check time instead of current time */
        +#define	X509_V_FLAG_USE_CHECK_TIME		0x2
        +/* Lookup CRLs */
        +#define	X509_V_FLAG_CRL_CHECK			0x4
        +/* Lookup CRLs for whole chain */
        +#define	X509_V_FLAG_CRL_CHECK_ALL		0x8
        +/* Ignore unhandled critical extensions */
        +#define	X509_V_FLAG_IGNORE_CRITICAL		0x10
        +/* Disable workarounds for broken certificates */
        +#define	X509_V_FLAG_X509_STRICT			0x20
        +/* Enable proxy certificate validation */
        +#define	X509_V_FLAG_ALLOW_PROXY_CERTS		0x40
        +/* Enable policy checking */
        +#define X509_V_FLAG_POLICY_CHECK		0x80
        +/* Policy variable require-explicit-policy */
        +#define X509_V_FLAG_EXPLICIT_POLICY		0x100
        +/* Policy variable inhibit-any-policy */
        +#define	X509_V_FLAG_INHIBIT_ANY			0x200
        +/* Policy variable inhibit-policy-mapping */
        +#define X509_V_FLAG_INHIBIT_MAP			0x400
        +/* Notify callback that policy is OK */
        +#define X509_V_FLAG_NOTIFY_POLICY		0x800
        +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
        +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT	0x1000
        +/* Delta CRL support */
        +#define X509_V_FLAG_USE_DELTAS			0x2000
        +/* Check selfsigned CA signature */
        +#define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
        +
        +
        +#define X509_VP_FLAG_DEFAULT			0x1
        +#define X509_VP_FLAG_OVERWRITE			0x2
        +#define X509_VP_FLAG_RESET_FLAGS		0x4
        +#define X509_VP_FLAG_LOCKED			0x8
        +#define X509_VP_FLAG_ONCE			0x10
        +
        +/* Internal use: mask of policy related options */
        +#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
        +				| X509_V_FLAG_EXPLICIT_POLICY \
        +				| X509_V_FLAG_INHIBIT_ANY \
        +				| X509_V_FLAG_INHIBIT_MAP)
        +
        +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
        +	     X509_NAME *name);
        +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name);
        +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
        +void X509_OBJECT_up_ref_count(X509_OBJECT *a);
        +void X509_OBJECT_free_contents(X509_OBJECT *a);
        +X509_STORE *X509_STORE_new(void );
        +void X509_STORE_free(X509_STORE *v);
        +
        +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
        +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
        +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
        +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
        +int X509_STORE_set_trust(X509_STORE *ctx, int trust);
        +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
        +
        +void X509_STORE_set_verify_cb(X509_STORE *ctx,
        +				  int (*verify_cb)(int, X509_STORE_CTX *));
        +
        +X509_STORE_CTX *X509_STORE_CTX_new(void);
        +
        +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
        +
        +void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
        +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
        +			 X509 *x509, STACK_OF(X509) *chain);
        +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
        +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
        +
        +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
        +
        +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
        +X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
        +
        +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
        +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
        +
        +int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
        +	X509_OBJECT *ret);
        +
        +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
        +	long argl, char **ret);
        +
        +#ifndef OPENSSL_NO_STDIO
        +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
        +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
        +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
        +#endif
        +
        +
        +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
        +void X509_LOOKUP_free(X509_LOOKUP *ctx);
        +int X509_LOOKUP_init(X509_LOOKUP *ctx);
        +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
        +	X509_OBJECT *ret);
        +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
        +	ASN1_INTEGER *serial, X509_OBJECT *ret);
        +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
        +	unsigned char *bytes, int len, X509_OBJECT *ret);
        +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
        +	int len, X509_OBJECT *ret);
        +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
        +
        +#ifndef OPENSSL_NO_STDIO
        +int	X509_STORE_load_locations (X509_STORE *ctx,
        +		const char *file, const char *dir);
        +int	X509_STORE_set_default_paths(X509_STORE *ctx);
        +#endif
        +
        +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
        +void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
        +int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
        +void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
        +int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
        +X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
        +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
        +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
        +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
        +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
        +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
        +void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
        +void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
        +void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
        +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
        +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
        +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
        +				int purpose, int trust);
        +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
        +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
        +								time_t t);
        +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
        +				  int (*verify_cb)(int, X509_STORE_CTX *));
        +  
        +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
        +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
        +
        +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
        +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
        +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
        +
        +/* X509_VERIFY_PARAM functions */
        +
        +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
        +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
        +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
        +						const X509_VERIFY_PARAM *from);
        +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 
        +						const X509_VERIFY_PARAM *from);
        +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
        +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
        +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
        +							unsigned long flags);
        +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
        +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
        +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
        +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
        +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
        +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
        +						ASN1_OBJECT *policy);
        +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
        +					STACK_OF(ASN1_OBJECT) *policies);
        +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
        +
        +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
        +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
        +void X509_VERIFY_PARAM_table_cleanup(void);
        +
        +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
        +			STACK_OF(X509) *certs,
        +			STACK_OF(ASN1_OBJECT) *policy_oids,
        +			unsigned int flags);
        +
        +void X509_policy_tree_free(X509_POLICY_TREE *tree);
        +
        +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
        +X509_POLICY_LEVEL *
        +	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i);
        +
        +STACK_OF(X509_POLICY_NODE) *
        +	X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree);
        +
        +STACK_OF(X509_POLICY_NODE) *
        +	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree);
        +
        +int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
        +
        +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i);
        +
        +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
        +
        +STACK_OF(POLICYQUALINFO) *
        +	X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node);
        +const X509_POLICY_NODE *
        +	X509_policy_node_get0_parent(const X509_POLICY_NODE *node);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509_vpm.c b/vendor/openssl/openssl/crypto/x509/x509_vpm.c
        new file mode 100644
        index 000000000..dfd89d89f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509_vpm.c
        @@ -0,0 +1,438 @@
        +/* x509_vpm.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 <stdio.h>
        +
        +#include "cryptlib.h"
        +#include <openssl/crypto.h>
        +#include <openssl/lhash.h>
        +#include <openssl/buffer.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +/* X509_VERIFY_PARAM functions */
        +
        +static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
        +	{
        +	if (!param)
        +		return;
        +	param->name = NULL;
        +	param->purpose = 0;
        +	param->trust = 0;
        +	/*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
        +	param->inh_flags = 0;
        +	param->flags = 0;
        +	param->depth = -1;
        +	if (param->policies)
        +		{
        +		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
        +		param->policies = NULL;
        +		}
        +	}
        +
        +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
        +	{
        +	X509_VERIFY_PARAM *param;
        +	param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
        +	memset(param, 0, sizeof(X509_VERIFY_PARAM));
        +	x509_verify_param_zero(param);
        +	return param;
        +	}
        +
        +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
        +	{
        +	x509_verify_param_zero(param);
        +	OPENSSL_free(param);
        +	}
        +
        +/* This function determines how parameters are "inherited" from one structure
        + * to another. There are several different ways this can happen.
        + *
        + * 1. If a child structure needs to have its values initialized from a parent
        + *    they are simply copied across. For example SSL_CTX copied to SSL.
        + * 2. If the structure should take on values only if they are currently unset.
        + *    For example the values in an SSL structure will take appropriate value
        + *    for SSL servers or clients but only if the application has not set new
        + *    ones.
        + *
        + * The "inh_flags" field determines how this function behaves. 
        + *
        + * Normally any values which are set in the default are not copied from the
        + * destination and verify flags are ORed together.
        + *
        + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
        + * to the destination. Effectively the values in "to" become default values
        + * which will be used only if nothing new is set in "from".
        + *
        + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
        + * they are set or not. Flags is still Ored though.
        + *
        + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
        + * of ORed.
        + *
        + * If X509_VP_FLAG_LOCKED is set then no values are copied.
        + *
        + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
        + * after the next call.
        + */
        +
        +/* Macro to test if a field should be copied from src to dest */
        +
        +#define test_x509_verify_param_copy(field, def) \
        +	(to_overwrite || \
        +		((src->field != def) && (to_default || (dest->field == def))))
        +
        +/* Macro to test and copy a field if necessary */
        +
        +#define x509_verify_param_copy(field, def) \
        +	if (test_x509_verify_param_copy(field, def)) \
        +		dest->field = src->field
        +		
        +
        +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
        +						const X509_VERIFY_PARAM *src)
        +	{
        +	unsigned long inh_flags;
        +	int to_default, to_overwrite;
        +	if (!src)
        +		return 1;
        +	inh_flags = dest->inh_flags | src->inh_flags;
        +
        +	if (inh_flags & X509_VP_FLAG_ONCE)
        +		dest->inh_flags = 0;
        +
        +	if (inh_flags & X509_VP_FLAG_LOCKED)
        +		return 1;
        +
        +	if (inh_flags & X509_VP_FLAG_DEFAULT)
        +		to_default = 1;
        +	else
        +		to_default = 0;
        +
        +	if (inh_flags & X509_VP_FLAG_OVERWRITE)
        +		to_overwrite = 1;
        +	else
        +		to_overwrite = 0;
        +
        +	x509_verify_param_copy(purpose, 0);
        +	x509_verify_param_copy(trust, 0);
        +	x509_verify_param_copy(depth, -1);
        +
        +	/* If overwrite or check time not set, copy across */
        +
        +	if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME))
        +		{
        +		dest->check_time = src->check_time;
        +		dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
        +		/* Don't need to copy flag: that is done below */
        +		}
        +
        +	if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
        +		dest->flags = 0;
        +
        +	dest->flags |= src->flags;
        +
        +	if (test_x509_verify_param_copy(policies, NULL))
        +		{
        +		if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
        +			return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
        +						const X509_VERIFY_PARAM *from)
        +	{
        +	unsigned long save_flags = to->inh_flags;
        +	int ret;
        +	to->inh_flags |= X509_VP_FLAG_DEFAULT;
        +	ret = X509_VERIFY_PARAM_inherit(to, from);
        +	to->inh_flags = save_flags;
        +	return ret;
        +	}
        +
        +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
        +	{
        +	if (param->name)
        +		OPENSSL_free(param->name);
        +	param->name = BUF_strdup(name);
        +	if (param->name)
        +		return 1;
        +	return 0;
        +	}
        +
        +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
        +	{
        +	param->flags |= flags;
        +	if (flags & X509_V_FLAG_POLICY_MASK)
        +		param->flags |= X509_V_FLAG_POLICY_CHECK;
        +	return 1;
        +	}
        +
        +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
        +	{
        +	param->flags &= ~flags;
        +	return 1;
        +	}
        +
        +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
        +	{
        +	return param->flags;
        +	}
        +
        +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
        +	{
        +	return X509_PURPOSE_set(&param->purpose, purpose);
        +	}
        +
        +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
        +	{
        +	return X509_TRUST_set(&param->trust, trust);
        +	}
        +
        +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
        +	{
        +	param->depth = depth;
        +	}
        +
        +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
        +	{
        +	param->check_time = t;
        +	param->flags |= X509_V_FLAG_USE_CHECK_TIME;
        +	}
        +
        +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
        +	{
        +	if (!param->policies)
        +		{
        +		param->policies = sk_ASN1_OBJECT_new_null();
        +		if (!param->policies)
        +			return 0;
        +		}
        +	if (!sk_ASN1_OBJECT_push(param->policies, policy))
        +		return 0;
        +	return 1;
        +	}
        +
        +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
        +					STACK_OF(ASN1_OBJECT) *policies)
        +	{
        +	int i;
        +	ASN1_OBJECT *oid, *doid;
        +	if (!param)
        +		return 0;
        +	if (param->policies)
        +		sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
        +
        +	if (!policies)
        +		{
        +		param->policies = NULL;
        +		return 1;
        +		}
        +
        +	param->policies = sk_ASN1_OBJECT_new_null();
        +	if (!param->policies)
        +		return 0;
        +
        +	for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++)
        +		{
        +		oid = sk_ASN1_OBJECT_value(policies, i);
        +		doid = OBJ_dup(oid);
        +		if (!doid)
        +			return 0;
        +		if (!sk_ASN1_OBJECT_push(param->policies, doid))
        +			{
        +			ASN1_OBJECT_free(doid);
        +			return 0;
        +			}
        +		}
        +	param->flags |= X509_V_FLAG_POLICY_CHECK;
        +	return 1;
        +	}
        +
        +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
        +	{
        +	return param->depth;
        +	}
        +
        +/* Default verify parameters: these are used for various
        + * applications and can be overridden by the user specified table.
        + * NB: the 'name' field *must* be in alphabetical order because it
        + * will be searched using OBJ_search.
        + */
        +
        +static const X509_VERIFY_PARAM default_table[] = {
        +	{
        +	"default",	/* X509 default parameters */
        +	0,		/* Check time */
        +	0,		/* internal flags */
        +	0,		/* flags */
        +	0,		/* purpose */
        +	0,		/* trust */
        +	100,		/* depth */
        +	NULL		/* policies */
        +	},
        +	{
        +	"pkcs7",			/* S/MIME sign parameters */
        +	0,				/* Check time */
        +	0,				/* internal flags */
        +	0,				/* flags */
        +	X509_PURPOSE_SMIME_SIGN,	/* purpose */
        +	X509_TRUST_EMAIL,		/* trust */
        +	-1,				/* depth */
        +	NULL				/* policies */
        +	},
        +	{
        +	"smime_sign",			/* S/MIME sign parameters */
        +	0,				/* Check time */
        +	0,				/* internal flags */
        +	0,				/* flags */
        +	X509_PURPOSE_SMIME_SIGN,	/* purpose */
        +	X509_TRUST_EMAIL,		/* trust */
        +	-1,				/* depth */
        +	NULL				/* policies */
        +	},
        +	{
        +	"ssl_client",			/* SSL/TLS client parameters */
        +	0,				/* Check time */
        +	0,				/* internal flags */
        +	0,				/* flags */
        +	X509_PURPOSE_SSL_CLIENT,	/* purpose */
        +	X509_TRUST_SSL_CLIENT,		/* trust */
        +	-1,				/* depth */
        +	NULL				/* policies */
        +	},
        +	{
        +	"ssl_server",			/* SSL/TLS server parameters */
        +	0,				/* Check time */
        +	0,				/* internal flags */
        +	0,				/* flags */
        +	X509_PURPOSE_SSL_SERVER,	/* purpose */
        +	X509_TRUST_SSL_SERVER,		/* trust */
        +	-1,				/* depth */
        +	NULL				/* policies */
        +	}};
        +
        +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
        +
        +static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
        +
        +	{
        +	return strcmp(a->name, b->name);
        +	}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
        +			   table);
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
        +			     table);
        +
        +static int param_cmp(const X509_VERIFY_PARAM * const *a,
        +			const X509_VERIFY_PARAM * const *b)
        +	{
        +	return strcmp((*a)->name, (*b)->name);
        +	}
        +
        +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
        +	{
        +	int idx;
        +	X509_VERIFY_PARAM *ptmp;
        +	if (!param_table)
        +		{
        +		param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
        +		if (!param_table)
        +			return 0;
        +		}
        +	else
        +		{
        +		idx = sk_X509_VERIFY_PARAM_find(param_table, param);
        +		if (idx != -1)
        +			{
        +			ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
        +			X509_VERIFY_PARAM_free(ptmp);
        +			(void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
        +			}
        +		}
        +	if (!sk_X509_VERIFY_PARAM_push(param_table, param))
        +		return 0;
        +	return 1;
        +	}
        +
        +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
        +	{
        +	int idx;
        +	X509_VERIFY_PARAM pm;
        +
        +	pm.name = (char *)name;
        +	if (param_table)
        +		{
        +		idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
        +		if (idx != -1)
        +			return sk_X509_VERIFY_PARAM_value(param_table, idx);
        +		}
        +	return OBJ_bsearch_table(&pm, default_table,
        +			   sizeof(default_table)/sizeof(X509_VERIFY_PARAM));
        +	}
        +
        +void X509_VERIFY_PARAM_table_cleanup(void)
        +	{
        +	if (param_table)
        +		sk_X509_VERIFY_PARAM_pop_free(param_table,
        +						X509_VERIFY_PARAM_free);
        +	param_table = NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509cset.c b/vendor/openssl/openssl/crypto/x509/x509cset.c
        new file mode 100644
        index 000000000..3109defb0
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509cset.c
        @@ -0,0 +1,170 @@
        +/* crypto/x509/x509cset.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +int X509_CRL_set_version(X509_CRL *x, long version)
        +	{
        +	if (x == NULL) return(0);
        +	if (x->crl->version == NULL)
        +		{
        +		if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL)
        +			return(0);
        +		}
        +	return(ASN1_INTEGER_set(x->crl->version,version));
        +	}
        +
        +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
        +	{
        +	if ((x == NULL) || (x->crl == NULL)) return(0);
        +	return(X509_NAME_set(&x->crl->issuer,name));
        +	}
        +
        +
        +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
        +	{
        +	ASN1_TIME *in;
        +
        +	if (x == NULL) return(0);
        +	in=x->crl->lastUpdate;
        +	if (in != tm)
        +		{
        +		in=M_ASN1_TIME_dup(tm);
        +		if (in != NULL)
        +			{
        +			M_ASN1_TIME_free(x->crl->lastUpdate);
        +			x->crl->lastUpdate=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        +
        +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
        +	{
        +	ASN1_TIME *in;
        +
        +	if (x == NULL) return(0);
        +	in=x->crl->nextUpdate;
        +	if (in != tm)
        +		{
        +		in=M_ASN1_TIME_dup(tm);
        +		if (in != NULL)
        +			{
        +			M_ASN1_TIME_free(x->crl->nextUpdate);
        +			x->crl->nextUpdate=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        +
        +int X509_CRL_sort(X509_CRL *c)
        +	{
        +	int i;
        +	X509_REVOKED *r;
        +	/* sort the data so it will be written in serial
        +	 * number order */
        +	sk_X509_REVOKED_sort(c->crl->revoked);
        +	for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++)
        +		{
        +		r=sk_X509_REVOKED_value(c->crl->revoked,i);
        +		r->sequence=i;
        +		}
        +	c->crl->enc.modified = 1;
        +	return 1;
        +	}
        +
        +int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
        +	{
        +	ASN1_TIME *in;
        +
        +	if (x == NULL) return(0);
        +	in=x->revocationDate;
        +	if (in != tm)
        +		{
        +		in=M_ASN1_TIME_dup(tm);
        +		if (in != NULL)
        +			{
        +			M_ASN1_TIME_free(x->revocationDate);
        +			x->revocationDate=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        +
        +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
        +	{
        +	ASN1_INTEGER *in;
        +
        +	if (x == NULL) return(0);
        +	in=x->serialNumber;
        +	if (in != serial)
        +		{
        +		in=M_ASN1_INTEGER_dup(serial);
        +		if (in != NULL)
        +			{
        +			M_ASN1_INTEGER_free(x->serialNumber);
        +			x->serialNumber=in;
        +			}
        +		}
        +	return(in != NULL);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509name.c b/vendor/openssl/openssl/crypto/x509/x509name.c
        new file mode 100644
        index 000000000..27bc4dc9a
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509name.c
        @@ -0,0 +1,383 @@
        +/* crypto/x509/x509name.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/stack.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
        +	{
        +	ASN1_OBJECT *obj;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL) return(-1);
        +	return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
        +	}
        +
        +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,
        +	     int len)
        +	{
        +	int i;
        +	ASN1_STRING *data;
        +
        +	i=X509_NAME_get_index_by_OBJ(name,obj,-1);
        +	if (i < 0) return(-1);
        +	data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
        +	i=(data->length > (len-1))?(len-1):data->length;
        +	if (buf == NULL) return(data->length);
        +	memcpy(buf,data->data,i);
        +	buf[i]='\0';
        +	return(i);
        +	}
        +
        +int X509_NAME_entry_count(X509_NAME *name)
        +	{
        +	if (name == NULL) return(0);
        +	return(sk_X509_NAME_ENTRY_num(name->entries));
        +	}
        +
        +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
        +	{
        +	ASN1_OBJECT *obj;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL) return(-2);
        +	return(X509_NAME_get_index_by_OBJ(name,obj,lastpos));
        +	}
        +
        +/* NOTE: you should be passsing -1, not 0 as lastpos */
        +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
        +	     int lastpos)
        +	{
        +	int n;
        +	X509_NAME_ENTRY *ne;
        +	STACK_OF(X509_NAME_ENTRY) *sk;
        +
        +	if (name == NULL) return(-1);
        +	if (lastpos < 0)
        +		lastpos= -1;
        +	sk=name->entries;
        +	n=sk_X509_NAME_ENTRY_num(sk);
        +	for (lastpos++; lastpos < n; lastpos++)
        +		{
        +		ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
        +		if (OBJ_cmp(ne->object,obj) == 0)
        +			return(lastpos);
        +		}
        +	return(-1);
        +	}
        +
        +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
        +	{
        +	if(name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
        +	   || loc < 0)
        +		return(NULL);
        +	else
        +		return(sk_X509_NAME_ENTRY_value(name->entries,loc));
        +	}
        +
        +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
        +	{
        +	X509_NAME_ENTRY *ret;
        +	int i,n,set_prev,set_next;
        +	STACK_OF(X509_NAME_ENTRY) *sk;
        +
        +	if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
        +	    || loc < 0)
        +		return(NULL);
        +	sk=name->entries;
        +	ret=sk_X509_NAME_ENTRY_delete(sk,loc);
        +	n=sk_X509_NAME_ENTRY_num(sk);
        +	name->modified=1;
        +	if (loc == n) return(ret);
        +
        +	/* else we need to fixup the set field */
        +	if (loc != 0)
        +		set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set;
        +	else
        +		set_prev=ret->set-1;
        +	set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set;
        +
        +	/* set_prev is the previous set
        +	 * set is the current set
        +	 * set_next is the following
        +	 * prev  1 1	1 1	1 1	1 1
        +	 * set   1	1	2	2
        +	 * next  1 1	2 2	2 2	3 2
        +	 * so basically only if prev and next differ by 2, then
        +	 * re-number down by 1 */
        +	if (set_prev+1 < set_next)
        +		for (i=loc; i<n; i++)
        +			sk_X509_NAME_ENTRY_value(sk,i)->set--;
        +	return(ret);
        +	}
        +
        +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
        +			unsigned char *bytes, int len, int loc, int set)
        +{
        +	X509_NAME_ENTRY *ne;
        +	int ret;
        +	ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
        +	if(!ne) return 0;
        +	ret = X509_NAME_add_entry(name, ne, loc, set);
        +	X509_NAME_ENTRY_free(ne);
        +	return ret;
        +}
        +
        +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
        +			unsigned char *bytes, int len, int loc, int set)
        +{
        +	X509_NAME_ENTRY *ne;
        +	int ret;
        +	ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
        +	if(!ne) return 0;
        +	ret = X509_NAME_add_entry(name, ne, loc, set);
        +	X509_NAME_ENTRY_free(ne);
        +	return ret;
        +}
        +
        +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
        +			const unsigned char *bytes, int len, int loc, int set)
        +{
        +	X509_NAME_ENTRY *ne;
        +	int ret;
        +	ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
        +	if(!ne) return 0;
        +	ret = X509_NAME_add_entry(name, ne, loc, set);
        +	X509_NAME_ENTRY_free(ne);
        +	return ret;
        +}
        +
        +/* if set is -1, append to previous set, 0 'a new one', and 1,
        + * prepend to the guy we are about to stomp on. */
        +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
        +	     int set)
        +	{
        +	X509_NAME_ENTRY *new_name=NULL;
        +	int n,i,inc;
        +	STACK_OF(X509_NAME_ENTRY) *sk;
        +
        +	if (name == NULL) return(0);
        +	sk=name->entries;
        +	n=sk_X509_NAME_ENTRY_num(sk);
        +	if (loc > n) loc=n;
        +	else if (loc < 0) loc=n;
        +
        +	name->modified=1;
        +
        +	if (set == -1)
        +		{
        +		if (loc == 0)
        +			{
        +			set=0;
        +			inc=1;
        +			}
        +		else
        +			{
        +			set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set;
        +			inc=0;
        +			}
        +		}
        +	else /* if (set >= 0) */
        +		{
        +		if (loc >= n)
        +			{
        +			if (loc != 0)
        +				set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1;
        +			else
        +				set=0;
        +			}
        +		else
        +			set=sk_X509_NAME_ENTRY_value(sk,loc)->set;
        +		inc=(set == 0)?1:0;
        +		}
        +
        +	if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
        +		goto err;
        +	new_name->set=set;
        +	if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
        +		{
        +		X509err(X509_F_X509_NAME_ADD_ENTRY,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	if (inc)
        +		{
        +		n=sk_X509_NAME_ENTRY_num(sk);
        +		for (i=loc+1; i<n; i++)
        +			sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1;
        +		}	
        +	return(1);
        +err:
        +	if (new_name != NULL)
        +		X509_NAME_ENTRY_free(new_name);
        +	return(0);
        +	}
        +
        +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
        +		const char *field, int type, const unsigned char *bytes, int len)
        +	{
        +	ASN1_OBJECT *obj;
        +	X509_NAME_ENTRY *nentry;
        +
        +	obj=OBJ_txt2obj(field, 0);
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
        +						X509_R_INVALID_FIELD_NAME);
        +		ERR_add_error_data(2, "name=", field);
        +		return(NULL);
        +		}
        +	nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
        +	ASN1_OBJECT_free(obj);
        +	return nentry;
        +	}
        +
        +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
        +	     int type, unsigned char *bytes, int len)
        +	{
        +	ASN1_OBJECT *obj;
        +	X509_NAME_ENTRY *nentry;
        +
        +	obj=OBJ_nid2obj(nid);
        +	if (obj == NULL)
        +		{
        +		X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID,X509_R_UNKNOWN_NID);
        +		return(NULL);
        +		}
        +	nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
        +	ASN1_OBJECT_free(obj);
        +	return nentry;
        +	}
        +
        +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
        +	     ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len)
        +	{
        +	X509_NAME_ENTRY *ret;
        +
        +	if ((ne == NULL) || (*ne == NULL))
        +		{
        +		if ((ret=X509_NAME_ENTRY_new()) == NULL)
        +			return(NULL);
        +		}
        +	else
        +		ret= *ne;
        +
        +	if (!X509_NAME_ENTRY_set_object(ret,obj))
        +		goto err;
        +	if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
        +		goto err;
        +
        +	if ((ne != NULL) && (*ne == NULL)) *ne=ret;
        +	return(ret);
        +err:
        +	if ((ne == NULL) || (ret != *ne))
        +		X509_NAME_ENTRY_free(ret);
        +	return(NULL);
        +	}
        +
        +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
        +	{
        +	if ((ne == NULL) || (obj == NULL))
        +		{
        +		X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	ASN1_OBJECT_free(ne->object);
        +	ne->object=OBJ_dup(obj);
        +	return((ne->object == NULL)?0:1);
        +	}
        +
        +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
        +	     const unsigned char *bytes, int len)
        +	{
        +	int i;
        +
        +	if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
        +	if((type > 0) && (type & MBSTRING_FLAG)) 
        +		return ASN1_STRING_set_by_NID(&ne->value, bytes,
        +						len, type,
        +					OBJ_obj2nid(ne->object)) ? 1 : 0;
        +	if (len < 0) len=strlen((const char *)bytes);
        +	i=ASN1_STRING_set(ne->value,bytes,len);
        +	if (!i) return(0);
        +	if (type != V_ASN1_UNDEF)
        +		{
        +		if (type == V_ASN1_APP_CHOOSE)
        +			ne->value->type=ASN1_PRINTABLE_type(bytes,len);
        +		else
        +			ne->value->type=type;
        +		}
        +	return(1);
        +	}
        +
        +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
        +	{
        +	if (ne == NULL) return(NULL);
        +	return(ne->object);
        +	}
        +
        +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
        +	{
        +	if (ne == NULL) return(NULL);
        +	return(ne->value);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509rset.c b/vendor/openssl/openssl/crypto/x509/x509rset.c
        new file mode 100644
        index 000000000..d9f6b5737
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509rset.c
        @@ -0,0 +1,83 @@
        +/* crypto/x509/x509rset.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +int X509_REQ_set_version(X509_REQ *x, long version)
        +	{
        +	if (x == NULL) return(0);
        +	return(ASN1_INTEGER_set(x->req_info->version,version));
        +	}
        +
        +int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
        +	{
        +	if ((x == NULL) || (x->req_info == NULL)) return(0);
        +	return(X509_NAME_set(&x->req_info->subject,name));
        +	}
        +
        +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
        +	{
        +	if ((x == NULL) || (x->req_info == NULL)) return(0);
        +	return(X509_PUBKEY_set(&x->req_info->pubkey,pkey));
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x509spki.c b/vendor/openssl/openssl/crypto/x509/x509spki.c
        new file mode 100644
        index 000000000..02a203d72
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509spki.c
        @@ -0,0 +1,121 @@
        +/* x509spki.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509.h>
        +
        +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
        +{
        +	if ((x == NULL) || (x->spkac == NULL)) return(0);
        +	return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey));
        +}
        +
        +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
        +{
        +	if ((x == NULL) || (x->spkac == NULL))
        +		return(NULL);
        +	return(X509_PUBKEY_get(x->spkac->pubkey));
        +}
        +
        +/* Load a Netscape SPKI from a base64 encoded string */
        +
        +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len)
        +{
        +	unsigned char *spki_der;
        +	const unsigned char *p;
        +	int spki_len;
        +	NETSCAPE_SPKI *spki;
        +	if(len <= 0) len = strlen(str);
        +	if (!(spki_der = OPENSSL_malloc(len + 1))) {
        +		X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
        +	if(spki_len < 0) {
        +		X509err(X509_F_NETSCAPE_SPKI_B64_DECODE,
        +						X509_R_BASE64_DECODE_ERROR);
        +		OPENSSL_free(spki_der);
        +		return NULL;
        +	}
        +	p = spki_der;
        +	spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
        +	OPENSSL_free(spki_der);
        +	return spki;
        +}
        +
        +/* Generate a base64 encoded string from an SPKI */
        +
        +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
        +{
        +	unsigned char *der_spki, *p;
        +	char *b64_str;
        +	int der_len;
        +	der_len = i2d_NETSCAPE_SPKI(spki, NULL);
        +	der_spki = OPENSSL_malloc(der_len);
        +	b64_str = OPENSSL_malloc(der_len * 2);
        +	if(!der_spki || !b64_str) {
        +		X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	p = der_spki;
        +	i2d_NETSCAPE_SPKI(spki, &p);
        +	EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
        +	OPENSSL_free(der_spki);
        +	return b64_str;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509/x509type.c b/vendor/openssl/openssl/crypto/x509/x509type.c
        new file mode 100644
        index 000000000..9702ec531
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x509type.c
        @@ -0,0 +1,131 @@
        +/* crypto/x509/x509type.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
        +	{
        +	EVP_PKEY *pk;
        +	int ret=0,i;
        +
        +	if (x == NULL) return(0);
        +
        +	if (pkey == NULL)
        +		pk=X509_get_pubkey(x);
        +	else
        +		pk=pkey;
        +
        +	if (pk == NULL) return(0);
        +
        +	switch (pk->type)
        +		{
        +	case EVP_PKEY_RSA:
        +		ret=EVP_PK_RSA|EVP_PKT_SIGN;
        +/*		if (!sign only extension) */
        +			ret|=EVP_PKT_ENC;
        +	break;
        +	case EVP_PKEY_DSA:
        +		ret=EVP_PK_DSA|EVP_PKT_SIGN;
        +		break;
        +	case EVP_PKEY_EC:
        +		ret=EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH;
        +		break;
        +	case EVP_PKEY_DH:
        +		ret=EVP_PK_DH|EVP_PKT_EXCH;
        +		break;	
        +	case NID_id_GostR3410_94:
        +	case NID_id_GostR3410_2001:
        +		ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
        +		break;
        +	default:
        +		break;
        +		}
        +
        +	i=OBJ_obj2nid(x->sig_alg->algorithm);
        +	if (i && OBJ_find_sigid_algs(i, NULL, &i))
        +		{
        +
        +		switch (i)
        +			{
        +		case NID_rsaEncryption:
        +		case NID_rsa:
        +			ret|=EVP_PKS_RSA;
        +			break;
        +		case NID_dsa:
        +		case NID_dsa_2:
        +			ret|=EVP_PKS_DSA;
        +			break;
        +		case NID_X9_62_id_ecPublicKey:
        +			ret|=EVP_PKS_EC;
        +			break;
        +		default:
        +			break;
        +			}
        +		}
        +
        +	if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look
        +					   for, not bytes */
        +		ret|=EVP_PKT_EXP;
        +	if(pkey==NULL) EVP_PKEY_free(pk);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509/x_all.c b/vendor/openssl/openssl/crypto/x509/x_all.c
        new file mode 100644
        index 000000000..b94aeeb87
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509/x_all.c
        @@ -0,0 +1,535 @@
        +/* crypto/x509/x_all.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/stack.h>
        +#include "cryptlib.h"
        +#include <openssl/buffer.h>
        +#include <openssl/asn1.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +
        +int X509_verify(X509 *a, EVP_PKEY *r)
        +	{
        +	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
        +		a->signature,a->cert_info,r));
        +	}
        +
        +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
        +	{
        +	return( ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
        +		a->sig_alg,a->signature,a->req_info,r));
        +	}
        +
        +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
        +	{
        +	return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
        +		a->sig_algor,a->signature,a->spkac,r));
        +	}
        +
        +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
        +	{
        +	x->cert_info->enc.modified = 1;
        +	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
        +		x->sig_alg, x->signature, x->cert_info,pkey,md));
        +	}
        +
        +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
        +	{
        +	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
        +		x->cert_info->signature,
        +		x->sig_alg, x->signature, x->cert_info, ctx);
        +	}
        +
        +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
        +	{
        +	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL,
        +		x->signature, x->req_info,pkey,md));
        +	}
        +
        +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
        +	{
        +	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
        +		x->sig_alg, NULL, x->signature, x->req_info, ctx);
        +	}
        +
        +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
        +	{
        +	x->crl->enc.modified = 1;
        +	return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg,
        +		x->sig_alg, x->signature, x->crl,pkey,md));
        +	}
        +
        +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
        +	{
        +	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
        +		x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
        +	}
        +
        +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
        +	{
        +	return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL,
        +		x->signature, x->spkac,pkey,md));
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +X509 *d2i_X509_fp(FILE *fp, X509 **x509)
        +	{
        +	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
        +	}
        +
        +int i2d_X509_fp(FILE *fp, X509 *x509)
        +	{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
        +	}
        +#endif
        +
        +X509 *d2i_X509_bio(BIO *bp, X509 **x509)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
        +	}
        +
        +int i2d_X509_bio(BIO *bp, X509 *x509)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
        +	{
        +	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
        +	}
        +
        +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
        +	{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
        +	}
        +#endif
        +
        +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
        +	}
        +
        +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
        +	{
        +	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
        +	}
        +
        +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
        +	{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
        +	}
        +#endif
        +
        +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
        +	}
        +
        +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
        +	{
        +	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
        +	}
        +
        +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
        +	{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
        +	}
        +#endif
        +
        +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
        +	}
        +
        +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +#ifndef OPENSSL_NO_FP_API
        +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
        +	{
        +	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
        +	}
        +
        +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
        +	{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
        +	}
        +
        +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
        +	{
        +	return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
        +	}
        +
        +
        +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
        +	{
        +	return ASN1_d2i_fp((void *(*)(void))
        +			   RSA_new,(D2I_OF(void))d2i_RSA_PUBKEY, fp,
        +			   (void **)rsa);
        +	}
        +
        +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
        +	{
        +	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
        +	}
        +
        +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
        +	{
        +	return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY,fp,rsa);
        +	}
        +#endif
        +
        +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
        +	}
        +
        +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
        +	}
        +
        +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
        +	{
        +	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
        +	}
        +
        +
        +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
        +	{
        +	return ASN1_d2i_bio_of(RSA,RSA_new,d2i_RSA_PUBKEY,bp,rsa);
        +	}
        +
        +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
        +	{
        +	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
        +	}
        +
        +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
        +	{
        +	return ASN1_i2d_bio_of(RSA,i2d_RSA_PUBKEY,bp,rsa);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +#ifndef OPENSSL_NO_FP_API
        +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
        +	{
        +	return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSAPrivateKey,fp,dsa);
        +	}
        +
        +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
        +	{
        +	return ASN1_i2d_fp_of_const(DSA,i2d_DSAPrivateKey,fp,dsa);
        +	}
        +
        +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
        +	{
        +	return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSA_PUBKEY,fp,dsa);
        +	}
        +
        +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
        +	{
        +	return ASN1_i2d_fp_of(DSA,i2d_DSA_PUBKEY,fp,dsa);
        +	}
        +#endif
        +
        +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
        +	{
        +	return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAPrivateKey,bp,dsa
        +);
        +	}
        +
        +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
        +	{
        +	return ASN1_i2d_bio_of_const(DSA,i2d_DSAPrivateKey,bp,dsa);
        +	}
        +
        +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
        +	{
        +	return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSA_PUBKEY,bp,dsa);
        +	}
        +
        +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
        +	{
        +	return ASN1_i2d_bio_of(DSA,i2d_DSA_PUBKEY,bp,dsa);
        +	}
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +#ifndef OPENSSL_NO_FP_API
        +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
        +	{
        +	return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,fp,eckey);
        +	}
        +  
        +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
        +	{
        +	return ASN1_i2d_fp_of(EC_KEY,i2d_EC_PUBKEY,fp,eckey);
        +	}
        +
        +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
        +	{
        +	return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,fp,eckey);
        +	}
        +  
        +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
        +	{
        +	return ASN1_i2d_fp_of(EC_KEY,i2d_ECPrivateKey,fp,eckey);
        +	}
        +#endif
        +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
        +	{
        +	return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,bp,eckey);
        +	}
        +  
        +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
        +	{
        +	return ASN1_i2d_bio_of(EC_KEY,i2d_EC_PUBKEY,bp,ecdsa);
        +	}
        +
        +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
        +	{
        +	return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,bp,eckey);
        +	}
        +  
        +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
        +	{
        +	return ASN1_i2d_bio_of(EC_KEY,i2d_ECPrivateKey,bp,eckey);
        +	}
        +#endif
        +
        +
        +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
        +	     unsigned int *len)
        +	{
        +	ASN1_BIT_STRING *key;
        +	key = X509_get0_pubkey_bitstr(data);
        +	if(!key) return 0;
        +	return EVP_Digest(key->data, key->length, md, len, type, NULL);
        +	}
        +
        +int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
        +	     unsigned int *len)
        +	{
        +	return(ASN1_item_digest(ASN1_ITEM_rptr(X509),type,(char *)data,md,len));
        +	}
        +
        +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
        +	     unsigned int *len)
        +	{
        +	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL),type,(char *)data,md,len));
        +	}
        +
        +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
        +	     unsigned int *len)
        +	{
        +	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ),type,(char *)data,md,len));
        +	}
        +
        +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md,
        +	     unsigned int *len)
        +	{
        +	return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len));
        +	}
        +
        +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, const EVP_MD *type,
        +	     unsigned char *md, unsigned int *len)
        +	{
        +	return(ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL),type,
        +		(char *)data,md,len));
        +	}
        +
        +
        +#ifndef OPENSSL_NO_FP_API
        +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
        +	{
        +	return ASN1_d2i_fp_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,fp,p8);
        +	}
        +
        +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
        +	{
        +	return ASN1_i2d_fp_of(X509_SIG,i2d_X509_SIG,fp,p8);
        +	}
        +#endif
        +
        +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
        +	{
        +	return ASN1_d2i_bio_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,bp,p8);
        +	}
        +
        +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
        +	{
        +	return ASN1_i2d_bio_of(X509_SIG,i2d_X509_SIG,bp,p8);
        +	}
        +
        +#ifndef OPENSSL_NO_FP_API
        +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
        +						 PKCS8_PRIV_KEY_INFO **p8inf)
        +	{
        +	return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
        +			      d2i_PKCS8_PRIV_KEY_INFO,fp,p8inf);
        +	}
        +
        +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
        +	{
        +	return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,fp,
        +			      p8inf);
        +	}
        +
        +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
        +	{
        +	PKCS8_PRIV_KEY_INFO *p8inf;
        +	int ret;
        +	p8inf = EVP_PKEY2PKCS8(key);
        +	if(!p8inf) return 0;
        +	ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
        +	PKCS8_PRIV_KEY_INFO_free(p8inf);
        +	return ret;
        +	}
        +
        +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
        +	{
        +	return ASN1_i2d_fp_of(EVP_PKEY,i2d_PrivateKey,fp,pkey);
        +	}
        +
        +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
        +{
        +	return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,fp,a);
        +}
        +
        +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
        +	{
        +	return ASN1_i2d_fp_of(EVP_PKEY,i2d_PUBKEY,fp,pkey);
        +	}
        +
        +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
        +{
        +	return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,fp,a);
        +}
        +
        +#endif
        +
        +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
        +						 PKCS8_PRIV_KEY_INFO **p8inf)
        +	{
        +	return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new,
        +			    d2i_PKCS8_PRIV_KEY_INFO,bp,p8inf);
        +	}
        +
        +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
        +	{
        +	return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,bp,
        +			       p8inf);
        +	}
        +
        +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
        +	{
        +	PKCS8_PRIV_KEY_INFO *p8inf;
        +	int ret;
        +	p8inf = EVP_PKEY2PKCS8(key);
        +	if(!p8inf) return 0;
        +	ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
        +	PKCS8_PRIV_KEY_INFO_free(p8inf);
        +	return ret;
        +	}
        +
        +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
        +	{
        +	return ASN1_i2d_bio_of(EVP_PKEY,i2d_PrivateKey,bp,pkey);
        +	}
        +
        +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
        +	{
        +	return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,bp,a);
        +	}
        +
        +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
        +	{
        +	return ASN1_i2d_bio_of(EVP_PKEY,i2d_PUBKEY,bp,pkey);
        +	}
        +
        +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
        +	{
        +	return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,bp,a);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/Makefile b/vendor/openssl/openssl/crypto/x509v3/Makefile
        new file mode 100644
        index 000000000..556ef351b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/Makefile
        @@ -0,0 +1,591 @@
        +#
        +# OpenSSL/crypto/x509v3/Makefile
        +#
        +
        +DIR=	x509v3
        +TOP=	../..
        +CC=	cc
        +INCLUDES= -I.. -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBSRC=	v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \
        +v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \
        +v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \
        +v3_ocsp.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \
        +pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \
        +v3_asid.c v3_addr.c
        +LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \
        +v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \
        +v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \
        +v3_ocsp.o v3_akeya.o v3_pmaps.o v3_pcons.o v3_ncons.o v3_pcia.o v3_pci.o \
        +pcy_cache.o pcy_node.o pcy_data.o pcy_map.o pcy_tree.o pcy_lib.o \
        +v3_asid.o v3_addr.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= x509v3.h
        +HEADER=	$(EXHEADER) pcy_int.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
        +
        +all:	lib
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
        +	$(MAKEDEPEND) -- $(CFLAG) $(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 *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +pcy_cache.o: ../../e_os.h ../../include/openssl/asn1.h
        +pcy_cache.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pcy_cache.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pcy_cache.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pcy_cache.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pcy_cache.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pcy_cache.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pcy_cache.o: ../../include/openssl/objects.h
        +pcy_cache.o: ../../include/openssl/opensslconf.h
        +pcy_cache.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pcy_cache.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pcy_cache.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pcy_cache.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pcy_cache.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pcy_cache.o: ../cryptlib.h pcy_cache.c pcy_int.h
        +pcy_data.o: ../../e_os.h ../../include/openssl/asn1.h
        +pcy_data.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pcy_data.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pcy_data.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pcy_data.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pcy_data.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pcy_data.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pcy_data.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pcy_data.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pcy_data.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pcy_data.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pcy_data.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pcy_data.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pcy_data.o: ../cryptlib.h pcy_data.c pcy_int.h
        +pcy_lib.o: ../../e_os.h ../../include/openssl/asn1.h
        +pcy_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pcy_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pcy_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pcy_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pcy_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pcy_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pcy_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pcy_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pcy_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pcy_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pcy_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pcy_lib.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pcy_lib.o: ../cryptlib.h pcy_int.h pcy_lib.c
        +pcy_map.o: ../../e_os.h ../../include/openssl/asn1.h
        +pcy_map.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pcy_map.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pcy_map.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pcy_map.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pcy_map.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pcy_map.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pcy_map.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pcy_map.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pcy_map.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pcy_map.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pcy_map.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pcy_map.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pcy_map.o: ../cryptlib.h pcy_int.h pcy_map.c
        +pcy_node.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +pcy_node.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +pcy_node.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +pcy_node.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +pcy_node.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
        +pcy_node.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pcy_node.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pcy_node.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pcy_node.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pcy_node.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pcy_node.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pcy_node.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pcy_node.o: pcy_int.h pcy_node.c
        +pcy_tree.o: ../../e_os.h ../../include/openssl/asn1.h
        +pcy_tree.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +pcy_tree.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +pcy_tree.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +pcy_tree.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +pcy_tree.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +pcy_tree.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +pcy_tree.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +pcy_tree.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +pcy_tree.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +pcy_tree.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +pcy_tree.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +pcy_tree.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +pcy_tree.o: ../cryptlib.h pcy_int.h pcy_tree.c
        +v3_addr.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_addr.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_addr.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_addr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_addr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_addr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_addr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_addr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_addr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_addr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_addr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_addr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_addr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_addr.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_addr.c
        +v3_akey.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_akey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_akey.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_akey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_akey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_akey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_akey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_akey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_akey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_akey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_akey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_akey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_akey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_akey.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_akey.c
        +v3_akeya.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_akeya.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_akeya.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_akeya.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_akeya.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_akeya.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_akeya.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_akeya.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_akeya.o: ../../include/openssl/opensslconf.h
        +v3_akeya.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_akeya.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_akeya.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_akeya.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_akeya.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_akeya.o: ../cryptlib.h v3_akeya.c
        +v3_alt.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_alt.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_alt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_alt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_alt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_alt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_alt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_alt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_alt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_alt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_alt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_alt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_alt.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_alt.c
        +v3_asid.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_asid.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_asid.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +v3_asid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_asid.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_asid.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_asid.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_asid.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_asid.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_asid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_asid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_asid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_asid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_asid.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_asid.o: ../cryptlib.h v3_asid.c
        +v3_bcons.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_bcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_bcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_bcons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_bcons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_bcons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_bcons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_bcons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_bcons.o: ../../include/openssl/opensslconf.h
        +v3_bcons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_bcons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_bcons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_bcons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_bcons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_bcons.o: ../cryptlib.h v3_bcons.c
        +v3_bitst.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_bitst.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_bitst.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_bitst.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_bitst.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_bitst.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_bitst.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_bitst.o: ../cryptlib.h v3_bitst.c
        +v3_conf.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_conf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_conf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_conf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_conf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_conf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_conf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_conf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_conf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_conf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_conf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_conf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_conf.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_conf.o: ../cryptlib.h v3_conf.c
        +v3_cpols.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_cpols.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_cpols.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_cpols.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_cpols.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_cpols.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_cpols.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_cpols.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_cpols.o: ../../include/openssl/opensslconf.h
        +v3_cpols.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_cpols.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_cpols.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_cpols.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_cpols.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_cpols.o: ../cryptlib.h pcy_int.h v3_cpols.c
        +v3_crld.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_crld.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_crld.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_crld.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_crld.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_crld.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_crld.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_crld.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_crld.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_crld.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_crld.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_crld.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_crld.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_crld.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_crld.c
        +v3_enum.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_enum.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_enum.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_enum.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_enum.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_enum.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_enum.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_enum.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_enum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_enum.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_enum.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_enum.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_enum.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_enum.o: ../cryptlib.h v3_enum.c
        +v3_extku.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_extku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_extku.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_extku.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_extku.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_extku.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_extku.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_extku.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_extku.o: ../../include/openssl/opensslconf.h
        +v3_extku.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_extku.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_extku.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_extku.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_extku.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_extku.o: ../cryptlib.h v3_extku.c
        +v3_genn.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_genn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_genn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_genn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_genn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_genn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_genn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_genn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_genn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_genn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_genn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_genn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_genn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_genn.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_genn.c
        +v3_ia5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_ia5.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_ia5.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_ia5.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_ia5.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_ia5.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_ia5.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_ia5.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_ia5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_ia5.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_ia5.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_ia5.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_ia5.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_ia5.c
        +v3_info.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_info.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_info.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_info.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_info.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_info.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_info.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_info.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_info.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_info.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_info.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_info.c
        +v3_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_int.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_int.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_int.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_int.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_int.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_int.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_int.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_int.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_int.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_int.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_int.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_int.c
        +v3_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_lib.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ext_dat.h v3_lib.c
        +v3_ncons.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_ncons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_ncons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_ncons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_ncons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_ncons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_ncons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_ncons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_ncons.o: ../../include/openssl/opensslconf.h
        +v3_ncons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_ncons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_ncons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_ncons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_ncons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_ncons.o: ../cryptlib.h v3_ncons.c
        +v3_ocsp.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_ocsp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_ocsp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_ocsp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_ocsp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_ocsp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_ocsp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_ocsp.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
        +v3_ocsp.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_ocsp.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_ocsp.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_ocsp.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_ocsp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_ocsp.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_ocsp.c
        +v3_pci.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_pci.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_pci.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_pci.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_pci.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_pci.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_pci.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_pci.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_pci.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_pci.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_pci.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_pci.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_pci.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_pci.c
        +v3_pcia.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +v3_pcia.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_pcia.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_pcia.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_pcia.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_pcia.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_pcia.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_pcia.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_pcia.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_pcia.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_pcia.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_pcia.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_pcia.o: ../../include/openssl/x509v3.h v3_pcia.c
        +v3_pcons.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_pcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_pcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_pcons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_pcons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_pcons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_pcons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_pcons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_pcons.o: ../../include/openssl/opensslconf.h
        +v3_pcons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_pcons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_pcons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_pcons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_pcons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_pcons.o: ../cryptlib.h v3_pcons.c
        +v3_pku.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_pku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_pku.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_pku.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_pku.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_pku.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_pku.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_pku.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_pku.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_pku.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_pku.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_pku.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_pku.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_pku.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_pku.c
        +v3_pmaps.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_pmaps.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_pmaps.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_pmaps.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_pmaps.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_pmaps.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_pmaps.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_pmaps.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_pmaps.o: ../../include/openssl/opensslconf.h
        +v3_pmaps.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_pmaps.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_pmaps.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_pmaps.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_pmaps.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_pmaps.o: ../cryptlib.h v3_pmaps.c
        +v3_prn.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_prn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3_prn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3_prn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3_prn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3_prn.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_prn.c
        +v3_purp.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_purp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_purp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_purp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_purp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_purp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_purp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_purp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_purp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_purp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_purp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_purp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_purp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_purp.o: ../cryptlib.h v3_purp.c
        +v3_skey.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_skey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
        +v3_skey.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_skey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_skey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_skey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_skey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_skey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_skey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_skey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_skey.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_skey.o: ../cryptlib.h v3_skey.c
        +v3_sxnet.o: ../../e_os.h ../../include/openssl/asn1.h
        +v3_sxnet.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
        +v3_sxnet.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3_sxnet.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3_sxnet.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3_sxnet.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3_sxnet.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3_sxnet.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3_sxnet.o: ../../include/openssl/opensslconf.h
        +v3_sxnet.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_sxnet.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_sxnet.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_sxnet.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_sxnet.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_sxnet.o: ../cryptlib.h v3_sxnet.c
        +v3_utl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3_utl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
        +v3_utl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
        +v3_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +v3_utl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +v3_utl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +v3_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +v3_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +v3_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +v3_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +v3_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +v3_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +v3_utl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +v3_utl.o: ../cryptlib.h v3_utl.c
        +v3err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +v3err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +v3err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +v3err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +v3err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
        +v3err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +v3err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +v3err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +v3err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +v3err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +v3err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +v3err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +v3err.o: ../../include/openssl/x509v3.h v3err.c
        diff --git a/vendor/openssl/openssl/crypto/x509v3/ext_dat.h b/vendor/openssl/openssl/crypto/x509v3/ext_dat.h
        new file mode 100644
        index 000000000..76daee6fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/ext_dat.h
        @@ -0,0 +1,132 @@
        +/* ext_dat.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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 file contains a table of "standard" extensions */
        +
        +extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
        +extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
        +extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
        +extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
        +extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
        +extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
        +extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
        +extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
        +extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
        +extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
        +extern X509V3_EXT_METHOD v3_addr, v3_asid;
        +
        +/* This table will be searched using OBJ_bsearch so it *must* kept in
        + * order of the ext_nid values.
        + */
        +
        +static const X509V3_EXT_METHOD *standard_exts[] = {
        +&v3_nscert,
        +&v3_ns_ia5_list[0],
        +&v3_ns_ia5_list[1],
        +&v3_ns_ia5_list[2],
        +&v3_ns_ia5_list[3],
        +&v3_ns_ia5_list[4],
        +&v3_ns_ia5_list[5],
        +&v3_ns_ia5_list[6],
        +&v3_skey_id,
        +&v3_key_usage,
        +&v3_pkey_usage_period,
        +&v3_alt[0],
        +&v3_alt[1],
        +&v3_bcons,
        +&v3_crl_num,
        +&v3_cpols,
        +&v3_akey_id,
        +&v3_crld,
        +&v3_ext_ku,
        +&v3_delta_crl,
        +&v3_crl_reason,
        +#ifndef OPENSSL_NO_OCSP
        +&v3_crl_invdate,
        +#endif
        +&v3_sxnet,
        +&v3_info,
        +#ifndef OPENSSL_NO_RFC3779
        +&v3_addr,
        +&v3_asid,
        +#endif
        +#ifndef OPENSSL_NO_OCSP
        +&v3_ocsp_nonce,
        +&v3_ocsp_crlid,
        +&v3_ocsp_accresp,
        +&v3_ocsp_nocheck,
        +&v3_ocsp_acutoff,
        +&v3_ocsp_serviceloc,
        +#endif
        +&v3_sinfo,
        +&v3_policy_constraints,
        +#ifndef OPENSSL_NO_OCSP
        +&v3_crl_hold,
        +#endif
        +&v3_pci,
        +&v3_name_constraints,
        +&v3_policy_mappings,
        +&v3_inhibit_anyp,
        +&v3_idp,
        +&v3_alt[2],
        +&v3_freshest_crl,
        +};
        +
        +/* Number of standard extensions */
        +
        +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_cache.c b/vendor/openssl/openssl/crypto/x509v3/pcy_cache.c
        new file mode 100644
        index 000000000..172b7e7ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_cache.c
        @@ -0,0 +1,286 @@
        +/* pcy_cache.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +static int policy_data_cmp(const X509_POLICY_DATA * const *a,
        +				const X509_POLICY_DATA * const *b);
        +static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
        +
        +/* Set cache entry according to CertificatePolicies extension.
        + * Note: this destroys the passed CERTIFICATEPOLICIES structure.
        + */
        +
        +static int policy_cache_create(X509 *x,
        +			CERTIFICATEPOLICIES *policies, int crit)
        +	{
        +	int i;
        +	int ret = 0;
        +	X509_POLICY_CACHE *cache = x->policy_cache;
        +	X509_POLICY_DATA *data = NULL;
        +	POLICYINFO *policy;
        +	if (sk_POLICYINFO_num(policies) == 0)
        +		goto bad_policy;
        +	cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
        +	if (!cache->data)
        +		goto bad_policy;
        +	for (i = 0; i < sk_POLICYINFO_num(policies); i++)
        +		{
        +		policy = sk_POLICYINFO_value(policies, i);
        +		data = policy_data_new(policy, NULL, crit);
        +		if (!data)
        +			goto bad_policy;
        +		/* Duplicate policy OIDs are illegal: reject if matches
        +		 * found.
        +		 */
        +		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
        +			{
        +			if (cache->anyPolicy)
        +				{
        +				ret = -1;
        +				goto bad_policy;
        +				}
        +			cache->anyPolicy = data;
        +			}
        +		else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1)
        +			{
        +			ret = -1;
        +			goto bad_policy;
        +			}
        +		else if (!sk_X509_POLICY_DATA_push(cache->data, data))
        +			goto bad_policy;
        +		data = NULL;
        +		}
        +	ret = 1;
        +	bad_policy:
        +	if (ret == -1)
        +		x->ex_flags |= EXFLAG_INVALID_POLICY;
        +	if (data)
        +		policy_data_free(data);
        +	sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
        +	if (ret <= 0)
        +		{
        +		sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
        +		cache->data = NULL;
        +		}
        +	return ret;
        +	}
        +
        +	
        +static int policy_cache_new(X509 *x)
        +	{
        +	X509_POLICY_CACHE *cache;
        +	ASN1_INTEGER *ext_any = NULL;
        +	POLICY_CONSTRAINTS *ext_pcons = NULL;
        +	CERTIFICATEPOLICIES *ext_cpols = NULL;
        +	POLICY_MAPPINGS *ext_pmaps = NULL;
        +	int i;
        +	cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
        +	if (!cache)
        +		return 0;
        +	cache->anyPolicy = NULL;
        +	cache->data = NULL;
        +	cache->any_skip = -1;
        +	cache->explicit_skip = -1;
        +	cache->map_skip = -1;
        +
        +	x->policy_cache = cache;
        +
        +	/* Handle requireExplicitPolicy *first*. Need to process this
        +	 * even if we don't have any policies.
        +	 */
        +	ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
        +
        +	if (!ext_pcons)
        +		{
        +		if (i != -1)
        +			goto bad_cache;
        +		}
        +	else
        +		{
        +		if (!ext_pcons->requireExplicitPolicy
        +			&& !ext_pcons->inhibitPolicyMapping)
        +			goto bad_cache;
        +		if (!policy_cache_set_int(&cache->explicit_skip,
        +			ext_pcons->requireExplicitPolicy))
        +			goto bad_cache;
        +		if (!policy_cache_set_int(&cache->map_skip,
        +			ext_pcons->inhibitPolicyMapping))
        +			goto bad_cache;
        +		}
        +
        +	/* Process CertificatePolicies */
        +
        +	ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
        +	/* If no CertificatePolicies extension or problem decoding then
        +	 * there is no point continuing because the valid policies will be
        +	 * NULL.
        +	 */
        +	if (!ext_cpols)
        +		{
        +		/* If not absent some problem with extension */
        +		if (i != -1)
        +			goto bad_cache;
        +		return 1;
        +		}
        +
        +	i = policy_cache_create(x, ext_cpols, i);
        +
        +	/* NB: ext_cpols freed by policy_cache_set_policies */
        +
        +	if (i <= 0)
        +		return i;
        +
        +	ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
        +
        +	if (!ext_pmaps)
        +		{
        +		/* If not absent some problem with extension */
        +		if (i != -1)
        +			goto bad_cache;
        +		}
        +	else
        +		{
        +		i = policy_cache_set_mapping(x, ext_pmaps);
        +		if (i <= 0)
        +			goto bad_cache;
        +		}
        +
        +	ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
        +
        +	if (!ext_any)
        +		{
        +		if (i != -1)
        +			goto bad_cache;
        +		}
        +	else if (!policy_cache_set_int(&cache->any_skip, ext_any))
        +			goto bad_cache;
        +
        +	if (0)
        +		{
        +		bad_cache:
        +		x->ex_flags |= EXFLAG_INVALID_POLICY;
        +		}
        +
        +	if(ext_pcons)
        +		POLICY_CONSTRAINTS_free(ext_pcons);
        +
        +	if (ext_any)
        +		ASN1_INTEGER_free(ext_any);
        +
        +	return 1;
        +
        +	
        +}
        +
        +void policy_cache_free(X509_POLICY_CACHE *cache)
        +	{
        +	if (!cache)
        +		return;
        +	if (cache->anyPolicy)
        +		policy_data_free(cache->anyPolicy);
        +	if (cache->data)
        +		sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
        +	OPENSSL_free(cache);
        +	}
        +
        +const X509_POLICY_CACHE *policy_cache_set(X509 *x)
        +	{
        +
        +	if (x->policy_cache == NULL)
        +		{
        +		CRYPTO_w_lock(CRYPTO_LOCK_X509);
        +			policy_cache_new(x);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
        +		}
        +
        +	return x->policy_cache;
        +
        +	}
        +
        +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
        +						const ASN1_OBJECT *id)
        +	{
        +	int idx;
        +	X509_POLICY_DATA tmp;
        +	tmp.valid_policy = (ASN1_OBJECT *)id;
        +	idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
        +	if (idx == -1)
        +		return NULL;
        +	return sk_X509_POLICY_DATA_value(cache->data, idx);
        +	}
        +
        +static int policy_data_cmp(const X509_POLICY_DATA * const *a,
        +				const X509_POLICY_DATA * const *b)
        +	{
        +	return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
        +	}
        +
        +static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
        +	{
        +	if (value == NULL)
        +		return 1;
        +	if (value->type == V_ASN1_NEG_INTEGER)
        +		return 0;
        +	*out = ASN1_INTEGER_get(value);
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_data.c b/vendor/openssl/openssl/crypto/x509v3/pcy_data.c
        new file mode 100644
        index 000000000..3444b0319
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_data.c
        @@ -0,0 +1,135 @@
        +/* pcy_data.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +/* Policy Node routines */
        +
        +void policy_data_free(X509_POLICY_DATA *data)
        +	{
        +	ASN1_OBJECT_free(data->valid_policy);
        +	/* Don't free qualifiers if shared */
        +	if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
        +		sk_POLICYQUALINFO_pop_free(data->qualifier_set,
        +					POLICYQUALINFO_free);
        +	sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
        +	OPENSSL_free(data);
        +	}
        +
        +/* Create a data based on an existing policy. If 'id' is NULL use the
        + * oid in the policy, otherwise use 'id'. This behaviour covers the two
        + * types of data in RFC3280: data with from a CertificatePolcies extension
        + * and additional data with just the qualifiers of anyPolicy and ID from
        + * another source.
        + */
        +
        +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
        +					const ASN1_OBJECT *cid, int crit)
        +	{
        +	X509_POLICY_DATA *ret;
        +	ASN1_OBJECT *id;
        +	if (!policy && !cid)
        +		return NULL;
        +	if (cid)
        +		{
        +		id = OBJ_dup(cid);
        +		if (!id)
        +			return NULL;
        +		}
        +	else
        +		id = NULL;
        +	ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
        +	if (!ret)
        +		return NULL;
        +	ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
        +	if (!ret->expected_policy_set)
        +		{
        +		OPENSSL_free(ret);
        +		if (id)
        +			ASN1_OBJECT_free(id);
        +		return NULL;
        +		}
        +
        +	if (crit)
        +		ret->flags = POLICY_DATA_FLAG_CRITICAL;
        +	else
        +		ret->flags = 0;
        +
        +	if (id)
        +		ret->valid_policy = id;
        +	else
        +		{
        +		ret->valid_policy = policy->policyid;
        +		policy->policyid = NULL;
        +		}
        +
        +	if (policy)
        +		{
        +		ret->qualifier_set = policy->qualifiers;
        +		policy->qualifiers = NULL;
        +		}
        +	else
        +		ret->qualifier_set = NULL;
        +
        +	return ret;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_int.h b/vendor/openssl/openssl/crypto/x509v3/pcy_int.h
        new file mode 100644
        index 000000000..ccff92846
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_int.h
        @@ -0,0 +1,212 @@
        +/* pcy_int.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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).
        + *
        + */
        +
        +
        +typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
        +
        +DECLARE_STACK_OF(X509_POLICY_DATA)
        +
        +/* Internal structures */
        +
        +/* This structure and the field names correspond to the Policy 'node' of
        + * RFC3280. NB this structure contains no pointers to parent or child
        + * data: X509_POLICY_NODE contains that. This means that the main policy data
        + * can be kept static and cached with the certificate.
        + */
        +
        +struct X509_POLICY_DATA_st
        +	{
        +	unsigned int flags;
        +	/* Policy OID and qualifiers for this data */
        +	ASN1_OBJECT *valid_policy;
        +	STACK_OF(POLICYQUALINFO) *qualifier_set;
        +	STACK_OF(ASN1_OBJECT) *expected_policy_set;
        +	};
        +
        +/* X509_POLICY_DATA flags values */
        +
        +/* This flag indicates the structure has been mapped using a policy mapping
        + * extension. If policy mapping is not active its references get deleted. 
        + */
        +
        +#define POLICY_DATA_FLAG_MAPPED			0x1
        +
        +/* This flag indicates the data doesn't correspond to a policy in Certificate
        + * Policies: it has been mapped to any policy.
        + */
        +
        +#define POLICY_DATA_FLAG_MAPPED_ANY		0x2
        +
        +/* AND with flags to see if any mapping has occurred */
        +
        +#define POLICY_DATA_FLAG_MAP_MASK		0x3
        +
        +/* qualifiers are shared and shouldn't be freed */
        +
        +#define POLICY_DATA_FLAG_SHARED_QUALIFIERS	0x4
        +
        +/* Parent node is an extra node and should be freed */
        +
        +#define POLICY_DATA_FLAG_EXTRA_NODE		0x8
        +
        +/* Corresponding CertificatePolicies is critical */
        +
        +#define POLICY_DATA_FLAG_CRITICAL		0x10
        +
        +/* This structure is cached with a certificate */
        +
        +struct X509_POLICY_CACHE_st {
        +	/* anyPolicy data or NULL if no anyPolicy */
        +	X509_POLICY_DATA *anyPolicy;
        +	/* other policy data */
        +	STACK_OF(X509_POLICY_DATA) *data;
        +	/* If InhibitAnyPolicy present this is its value or -1 if absent. */
        +	long any_skip;
        +	/* If policyConstraints and requireExplicitPolicy present this is its
        +	 * value or -1 if absent.
        +	 */
        +	long explicit_skip;
        +	/* If policyConstraints and policyMapping present this is its
        +	 * value or -1 if absent.
        +         */
        +	long map_skip;
        +	};
        +
        +/*#define POLICY_CACHE_FLAG_CRITICAL		POLICY_DATA_FLAG_CRITICAL*/
        +
        +/* This structure represents the relationship between nodes */
        +
        +struct X509_POLICY_NODE_st
        +	{
        +	/* node data this refers to */
        +	const X509_POLICY_DATA *data;
        +	/* Parent node */
        +	X509_POLICY_NODE *parent;
        +	/* Number of child nodes */
        +	int nchild;
        +	};
        +
        +struct X509_POLICY_LEVEL_st
        +	{
        +	/* Cert for this level */
        +	X509 *cert;
        +	/* nodes at this level */
        +	STACK_OF(X509_POLICY_NODE) *nodes;
        +	/* anyPolicy node */
        +	X509_POLICY_NODE *anyPolicy;
        +	/* Extra data */
        +	/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
        +	unsigned int flags;
        +	};
        +
        +struct X509_POLICY_TREE_st
        +	{
        +	/* This is the tree 'level' data */
        +	X509_POLICY_LEVEL *levels;
        +	int nlevel;
        +	/* Extra policy data when additional nodes (not from the certificate)
        +	 * are required.
        +	 */
        +	STACK_OF(X509_POLICY_DATA) *extra_data;
        +	/* This is the authority constained policy set */
        +	STACK_OF(X509_POLICY_NODE) *auth_policies;
        +	STACK_OF(X509_POLICY_NODE) *user_policies;
        +	unsigned int flags;
        +	};
        +
        +/* Set if anyPolicy present in user policies */
        +#define POLICY_FLAG_ANY_POLICY		0x2
        +
        +/* Useful macros */
        +
        +#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
        +#define node_critical(node) node_data_critical(node->data)
        +
        +/* Internal functions */
        +
        +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
        +								int crit);
        +void policy_data_free(X509_POLICY_DATA *data);
        +
        +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
        +							const ASN1_OBJECT *id);
        +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
        +
        +
        +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
        +
        +void policy_cache_init(void);
        +
        +void policy_cache_free(X509_POLICY_CACHE *cache);
        +
        +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
        +					const X509_POLICY_NODE *parent,	
        +					const ASN1_OBJECT *id);
        +
        +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
        +						const ASN1_OBJECT *id);
        +
        +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
        +			const X509_POLICY_DATA *data,
        +			X509_POLICY_NODE *parent,
        +			X509_POLICY_TREE *tree);
        +void policy_node_free(X509_POLICY_NODE *node);
        +int policy_node_match(const X509_POLICY_LEVEL *lvl,
        +		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
        +
        +const X509_POLICY_CACHE *policy_cache_set(X509 *x);
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_lib.c b/vendor/openssl/openssl/crypto/x509v3/pcy_lib.c
        new file mode 100644
        index 000000000..93bfd9270
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_lib.c
        @@ -0,0 +1,167 @@
        +/* pcy_lib.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +/* accessor functions */
        +
        +/* X509_POLICY_TREE stuff */
        +
        +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
        +	{
        +	if (!tree)
        +		return 0;
        +	return tree->nlevel;
        +	}
        +
        +X509_POLICY_LEVEL *
        +	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
        +	{
        +	if (!tree || (i < 0) || (i >= tree->nlevel))
        +		return NULL;
        +	return tree->levels + i;
        +	}
        +
        +STACK_OF(X509_POLICY_NODE) *
        +		X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
        +	{
        +	if (!tree)
        +		return NULL;
        +	return tree->auth_policies;
        +	}
        +
        +STACK_OF(X509_POLICY_NODE) *
        +	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
        +	{
        +	if (!tree)
        +		return NULL;
        +	if (tree->flags & POLICY_FLAG_ANY_POLICY)
        +		return tree->auth_policies;
        +	else
        +		return tree->user_policies;
        +	}
        +
        +/* X509_POLICY_LEVEL stuff */
        +
        +int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
        +	{
        +	int n;
        +	if (!level)
        +		return 0;
        +	if (level->anyPolicy)
        +		n = 1;
        +	else
        +		n = 0;
        +	if (level->nodes)
        +		n += sk_X509_POLICY_NODE_num(level->nodes);
        +	return n;
        +	}
        +
        +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
        +	{
        +	if (!level)
        +		return NULL;
        +	if (level->anyPolicy)
        +		{
        +		if (i == 0)
        +			return level->anyPolicy;
        +		i--;
        +		}
        +	return sk_X509_POLICY_NODE_value(level->nodes, i);
        +	}
        +
        +/* X509_POLICY_NODE stuff */
        +
        +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
        +	{
        +	if (!node)
        +		return NULL;
        +	return node->data->valid_policy;
        +	}
        +
        +#if 0
        +int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
        +	{
        +	if (node_critical(node))
        +		return 1;
        +	return 0;
        +	}
        +#endif
        +
        +STACK_OF(POLICYQUALINFO) *
        +		X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
        +	{
        +	if (!node)
        +		return NULL;
        +	return node->data->qualifier_set;
        +	}
        +
        +const X509_POLICY_NODE *
        +		X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
        +	{
        +	if (!node)
        +		return NULL;
        +	return node->parent;
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_map.c b/vendor/openssl/openssl/crypto/x509v3/pcy_map.c
        new file mode 100644
        index 000000000..21163b529
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_map.c
        @@ -0,0 +1,132 @@
        +/* pcy_map.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +/* Set policy mapping entries in cache.
        + * Note: this modifies the passed POLICY_MAPPINGS structure
        + */
        +
        +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
        +	{
        +	POLICY_MAPPING *map;
        +	X509_POLICY_DATA *data;
        +	X509_POLICY_CACHE *cache = x->policy_cache;
        +	int i;
        +	int ret = 0;
        +	if (sk_POLICY_MAPPING_num(maps) == 0)
        +		{
        +		ret = -1;
        +		goto bad_mapping;
        +		}
        +	for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
        +		{
        +		map = sk_POLICY_MAPPING_value(maps, i);
        +		/* Reject if map to or from anyPolicy */
        +		if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
        +		   || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
        +			{
        +			ret = -1;
        +			goto bad_mapping;
        +			}
        +
        +		/* Attempt to find matching policy data */
        +		data = policy_cache_find_data(cache, map->issuerDomainPolicy);
        +		/* If we don't have anyPolicy can't map */
        +		if (!data && !cache->anyPolicy)
        +			continue;
        +
        +		/* Create a NODE from anyPolicy */
        +		if (!data)
        +			{
        +			data = policy_data_new(NULL, map->issuerDomainPolicy,
        +					cache->anyPolicy->flags
        +						& POLICY_DATA_FLAG_CRITICAL);
        +			if (!data)
        +				goto bad_mapping;
        +			data->qualifier_set = cache->anyPolicy->qualifier_set;
        +			/*map->issuerDomainPolicy = NULL;*/
        +			data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
        +			data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
        +			if (!sk_X509_POLICY_DATA_push(cache->data, data))
        +				{
        +				policy_data_free(data);
        +				goto bad_mapping;
        +				}
        +			}
        +		else
        +			data->flags |= POLICY_DATA_FLAG_MAPPED;
        +		if (!sk_ASN1_OBJECT_push(data->expected_policy_set, 
        +						map->subjectDomainPolicy))
        +			goto bad_mapping;
        +		map->subjectDomainPolicy = NULL;
        +
        +		}
        +
        +	ret = 1;
        +	bad_mapping:
        +	if (ret == -1)
        +		x->ex_flags |= EXFLAG_INVALID_POLICY;
        +	sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_node.c b/vendor/openssl/openssl/crypto/x509v3/pcy_node.c
        new file mode 100644
        index 000000000..bd1e7f1ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_node.c
        @@ -0,0 +1,197 @@
        +/* pcy_node.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 <openssl/asn1.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +static int node_cmp(const X509_POLICY_NODE * const *a,
        +			const X509_POLICY_NODE * const *b)
        +	{
        +	return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
        +	}
        +
        +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
        +	{
        +	return sk_X509_POLICY_NODE_new(node_cmp);
        +	}
        +
        +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
        +					const ASN1_OBJECT *id)
        +	{
        +	X509_POLICY_DATA n;
        +	X509_POLICY_NODE l;
        +	int idx;
        +
        +	n.valid_policy = (ASN1_OBJECT *)id;
        +	l.data = &n;
        +
        +	idx = sk_X509_POLICY_NODE_find(nodes, &l);
        +	if (idx == -1)
        +		return NULL;
        +
        +	return sk_X509_POLICY_NODE_value(nodes, idx);
        +
        +	}
        +
        +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
        +					const X509_POLICY_NODE *parent,	
        +					const ASN1_OBJECT *id)
        +	{
        +	X509_POLICY_NODE *node;
        +	int i;
        +	for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
        +		{
        +		node = sk_X509_POLICY_NODE_value(level->nodes, i);
        +		if (node->parent == parent)
        +			{
        +			if (!OBJ_cmp(node->data->valid_policy, id))
        +				return node;
        +			}
        +		}
        +	return NULL;
        +	}
        +
        +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
        +			const X509_POLICY_DATA *data,
        +			X509_POLICY_NODE *parent,
        +			X509_POLICY_TREE *tree)
        +	{
        +	X509_POLICY_NODE *node;
        +	node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
        +	if (!node)
        +		return NULL;
        +	node->data = data;
        +	node->parent = parent;
        +	node->nchild = 0;
        +	if (level)
        +		{
        +		if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
        +			{
        +			if (level->anyPolicy)
        +				goto node_error;
        +			level->anyPolicy = node;
        +			}
        +		else
        +			{
        +
        +			if (!level->nodes)
        +				level->nodes = policy_node_cmp_new();
        +			if (!level->nodes)
        +				goto node_error;
        +			if (!sk_X509_POLICY_NODE_push(level->nodes, node))
        +				goto node_error;
        +			}
        +		}
        +
        +	if (tree)
        +		{
        +		if (!tree->extra_data)
        +			 tree->extra_data = sk_X509_POLICY_DATA_new_null();
        +		if (!tree->extra_data)
        +			goto node_error;
        +		if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
        +			goto node_error;
        +		}
        +
        +	if (parent)
        +		parent->nchild++;
        +
        +	return node;
        +
        +	node_error:
        +	policy_node_free(node);
        +	return 0;
        +
        +	}
        +
        +void policy_node_free(X509_POLICY_NODE *node)
        +	{
        +	OPENSSL_free(node);
        +	}
        +
        +/* See if a policy node matches a policy OID. If mapping enabled look through
        + * expected policy set otherwise just valid policy.
        + */
        +
        +int policy_node_match(const X509_POLICY_LEVEL *lvl,
        +		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
        +	{
        +	int i;
        +	ASN1_OBJECT *policy_oid;
        +	const X509_POLICY_DATA *x = node->data;
        +
        +	if (	    (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
        +		|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
        +		{
        +		if (!OBJ_cmp(x->valid_policy, oid))
        +			return 1;
        +		return 0;
        +		}
        +
        +	for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
        +		{
        +		policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
        +		if (!OBJ_cmp(policy_oid, oid))
        +			return 1;
        +		}
        +	return 0;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/pcy_tree.c b/vendor/openssl/openssl/crypto/x509v3/pcy_tree.c
        new file mode 100644
        index 000000000..bb9777348
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/pcy_tree.c
        @@ -0,0 +1,872 @@
        +/* pcy_tree.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004 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 "cryptlib.h"
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +/* Enable this to print out the complete policy tree at various point during
        + * evaluation.
        + */
        +
        +/*#define OPENSSL_POLICY_DEBUG*/
        +
        +#ifdef OPENSSL_POLICY_DEBUG
        +
        +static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
        +				X509_POLICY_NODE *node, int indent)
        +	{
        +	if (	    (lev->flags & X509_V_FLAG_INHIBIT_MAP)
        +		|| !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
        +		BIO_puts(err, "  Not Mapped\n");
        +	else
        +		{
        +		int i;
        +		STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
        +		ASN1_OBJECT *oid;
        +		BIO_puts(err, "  Expected: ");
        +		for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
        +			{
        +			oid = sk_ASN1_OBJECT_value(pset, i);
        +			if (i)
        +				BIO_puts(err, ", ");
        +			i2a_ASN1_OBJECT(err, oid);
        +			}
        +		BIO_puts(err, "\n");
        +		}
        +	}
        +
        +static void tree_print(char *str, X509_POLICY_TREE *tree,
        +			X509_POLICY_LEVEL *curr)
        +	{
        +	X509_POLICY_LEVEL *plev;
        +	X509_POLICY_NODE *node;
        +	int i;
        +	BIO *err;
        +	err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +	if (!curr)
        +		curr = tree->levels + tree->nlevel;
        +	else
        +		curr++;
        +	BIO_printf(err, "Level print after %s\n", str);
        +	BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
        +	for (plev = tree->levels; plev != curr; plev++)
        +		{
        +		BIO_printf(err, "Level %ld, flags = %x\n",
        +				plev - tree->levels, plev->flags);
        +		for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
        +			{
        +			node = sk_X509_POLICY_NODE_value(plev->nodes, i);
        +			X509_POLICY_NODE_print(err, node, 2);
        +			expected_print(err, plev, node, 2);
        +			BIO_printf(err, "  Flags: %x\n", node->data->flags);
        +			}
        +		if (plev->anyPolicy)
        +			X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
        +		}
        +
        +	BIO_free(err);
        +
        +	}
        +#else
        +
        +#define tree_print(a,b,c) /* */
        +
        +#endif
        +
        +/* Initialize policy tree. Return values:
        + *  0 Some internal error occured.
        + * -1 Inconsistent or invalid extensions in certificates.
        + *  1 Tree initialized OK.
        + *  2 Policy tree is empty.
        + *  5 Tree OK and requireExplicitPolicy true.
        + *  6 Tree empty and requireExplicitPolicy true.
        + */
        +
        +static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
        +			unsigned int flags)
        +	{
        +	X509_POLICY_TREE *tree;
        +	X509_POLICY_LEVEL *level;
        +	const X509_POLICY_CACHE *cache;
        +	X509_POLICY_DATA *data = NULL;
        +	X509 *x;
        +	int ret = 1;
        +	int i, n;
        +	int explicit_policy;
        +	int any_skip;
        +	int map_skip;
        +	*ptree = NULL;
        +	n = sk_X509_num(certs);
        +
        +#if 0
        +	/* Disable policy mapping for now... */
        +	flags |= X509_V_FLAG_INHIBIT_MAP;
        +#endif
        +
        +	if (flags & X509_V_FLAG_EXPLICIT_POLICY)
        +		explicit_policy = 0;
        +	else
        +		explicit_policy = n + 1;
        +
        +	if (flags & X509_V_FLAG_INHIBIT_ANY)
        +		any_skip = 0;
        +	else
        +		any_skip = n + 1;
        +
        +	if (flags & X509_V_FLAG_INHIBIT_MAP)
        +		map_skip = 0;
        +	else
        +		map_skip = n + 1;
        +
        +	/* Can't do anything with just a trust anchor */
        +	if (n == 1)
        +		return 1;
        +	/* First setup policy cache in all certificates apart from the
        +	 * trust anchor. Note any bad cache results on the way. Also can
        +	 * calculate explicit_policy value at this point.
        +	 */
        +	for (i = n - 2; i >= 0; i--)
        +		{
        +		x = sk_X509_value(certs, i);
        +		X509_check_purpose(x, -1, -1);
        +		cache = policy_cache_set(x);
        +		/* If cache NULL something bad happened: return immediately */
        +		if (cache == NULL)
        +			return 0;
        +		/* If inconsistent extensions keep a note of it but continue */
        +		if (x->ex_flags & EXFLAG_INVALID_POLICY)
        +			ret = -1;
        +		/* Otherwise if we have no data (hence no CertificatePolicies)
        +		 * and haven't already set an inconsistent code note it.
        +		 */
        +		else if ((ret == 1) && !cache->data)
        +			ret = 2;
        +		if (explicit_policy > 0)
        +			{
        +			if (!(x->ex_flags & EXFLAG_SI))
        +				explicit_policy--;
        +			if ((cache->explicit_skip != -1)
        +				&& (cache->explicit_skip < explicit_policy))
        +				explicit_policy = cache->explicit_skip;
        +			}
        +		}
        +
        +	if (ret != 1)
        +		{
        +		if (ret == 2 && !explicit_policy)
        +			return 6;
        +		return ret;
        +		}
        +
        +
        +	/* If we get this far initialize the tree */
        +
        +	tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
        +
        +	if (!tree)
        +		return 0;
        +
        +	tree->flags = 0;
        +	tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
        +	tree->nlevel = 0;
        +	tree->extra_data = NULL;
        +	tree->auth_policies = NULL;
        +	tree->user_policies = NULL;
        +
        +	if (!tree->levels)
        +		{
        +		OPENSSL_free(tree);
        +		return 0;
        +		}
        +
        +	memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
        +
        +	tree->nlevel = n;
        +
        +	level = tree->levels;
        +
        +	/* Root data: initialize to anyPolicy */
        +
        +	data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
        +
        +	if (!data || !level_add_node(level, data, NULL, tree))
        +		goto bad_tree;
        +
        +	for (i = n - 2; i >= 0; i--)
        +		{
        +		level++;
        +		x = sk_X509_value(certs, i);
        +		cache = policy_cache_set(x);
        +		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
        +		level->cert = x;
        +
        +		if (!cache->anyPolicy)
        +				level->flags |= X509_V_FLAG_INHIBIT_ANY;
        +
        +		/* Determine inhibit any and inhibit map flags */
        +		if (any_skip == 0)
        +			{
        +			/* Any matching allowed if certificate is self
        +			 * issued and not the last in the chain.
        +			 */
        +			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
        +				level->flags |= X509_V_FLAG_INHIBIT_ANY;
        +			}
        +		else
        +			{
        +			if (!(x->ex_flags & EXFLAG_SI))
        +				any_skip--;
        +			if ((cache->any_skip >= 0)
        +				&& (cache->any_skip < any_skip))
        +				any_skip = cache->any_skip;
        +			}
        +
        +		if (map_skip == 0)
        +			level->flags |= X509_V_FLAG_INHIBIT_MAP;
        +		else
        +			{
        +			if (!(x->ex_flags & EXFLAG_SI))
        +				map_skip--;
        +			if ((cache->map_skip >= 0)
        +				&& (cache->map_skip < map_skip))
        +				map_skip = cache->map_skip;
        +			}
        +
        +		}
        +
        +	*ptree = tree;
        +
        +	if (explicit_policy)
        +		return 1;
        +	else
        +		return 5;
        +
        +	bad_tree:
        +
        +	X509_policy_tree_free(tree);
        +
        +	return 0;
        +
        +	}
        +
        +static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
        +				const X509_POLICY_DATA *data)
        +	{
        +	X509_POLICY_LEVEL *last = curr - 1;
        +	X509_POLICY_NODE *node;
        +	int i, matched = 0;
        +	/* Iterate through all in nodes linking matches */
        +	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
        +		{
        +		node = sk_X509_POLICY_NODE_value(last->nodes, i);
        +		if (policy_node_match(last, node, data->valid_policy))
        +			{
        +			if (!level_add_node(curr, data, node, NULL))
        +				return 0;
        +			matched = 1;
        +			}
        +		}
        +	if (!matched && last->anyPolicy)
        +		{
        +		if (!level_add_node(curr, data, last->anyPolicy, NULL))
        +			return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* This corresponds to RFC3280 6.1.3(d)(1):
        + * link any data from CertificatePolicies onto matching parent
        + * or anyPolicy if no match.
        + */
        +
        +static int tree_link_nodes(X509_POLICY_LEVEL *curr,
        +				const X509_POLICY_CACHE *cache)
        +	{
        +	int i;
        +	X509_POLICY_DATA *data;
        +
        +	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
        +		{
        +		data = sk_X509_POLICY_DATA_value(cache->data, i);
        +		/* If a node is mapped any it doesn't have a corresponding
        +		 * CertificatePolicies entry. 
        +		 * However such an identical node would be created
        +		 * if anyPolicy matching is enabled because there would be
        +		 * no match with the parent valid_policy_set. So we create
        +		 * link because then it will have the mapping flags
        +		 * right and we can prune it later.
        +		 */
        +#if 0
        +		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
        +			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
        +			continue;
        +#endif
        +		/* Look for matching nodes in previous level */
        +		if (!tree_link_matching_nodes(curr, data))
        +				return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* This corresponds to RFC3280 6.1.3(d)(2):
        + * Create new data for any unmatched policies in the parent and link
        + * to anyPolicy.
        + */
        +
        +static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
        +			const X509_POLICY_CACHE *cache,
        +			const ASN1_OBJECT *id,
        +			X509_POLICY_NODE *node,
        +			X509_POLICY_TREE *tree)
        +	{
        +	X509_POLICY_DATA *data;
        +	if (id == NULL)
        +		id = node->data->valid_policy;
        +	/* Create a new node with qualifiers from anyPolicy and
        +	 * id from unmatched node.
        +	 */
        +	data = policy_data_new(NULL, id, node_critical(node));
        +
        +	if (data == NULL)
        +		return 0;
        +	/* Curr may not have anyPolicy */
        +	data->qualifier_set = cache->anyPolicy->qualifier_set;
        +	data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
        +	if (!level_add_node(curr, data, node, tree))
        +		{
        +		policy_data_free(data);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
        +			const X509_POLICY_CACHE *cache,
        +			X509_POLICY_NODE *node,
        +			X509_POLICY_TREE *tree)
        +	{
        +	const X509_POLICY_LEVEL *last = curr - 1;
        +	int i;
        +
        +	if (	    (last->flags & X509_V_FLAG_INHIBIT_MAP)
        +		|| !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
        +		{
        +		/* If no policy mapping: matched if one child present */
        +		if (node->nchild)
        +			return 1;
        +		if (!tree_add_unmatched(curr, cache, NULL, node, tree))
        +			return 0;
        +		/* Add it */
        +		}
        +	else
        +		{
        +		/* If mapping: matched if one child per expected policy set */
        +		STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
        +		if (node->nchild == sk_ASN1_OBJECT_num(expset))
        +			return 1;
        +		/* Locate unmatched nodes */
        +		for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
        +			{
        +			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
        +			if (level_find_node(curr, node, oid))
        +				continue;
        +			if (!tree_add_unmatched(curr, cache, oid, node, tree))
        +				return 0;
        +			}
        +
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +static int tree_link_any(X509_POLICY_LEVEL *curr,
        +			const X509_POLICY_CACHE *cache,
        +			X509_POLICY_TREE *tree)
        +	{
        +	int i;
        +	/*X509_POLICY_DATA *data;*/
        +	X509_POLICY_NODE *node;
        +	X509_POLICY_LEVEL *last = curr - 1;
        +
        +	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
        +		{
        +		node = sk_X509_POLICY_NODE_value(last->nodes, i);
        +
        +		if (!tree_link_unmatched(curr, cache, node, tree))
        +			return 0;
        +
        +#if 0
        +
        +		/* Skip any node with any children: we only want unmathced
        +		 * nodes.
        +		 *
        +		 * Note: need something better for policy mapping
        +		 * because each node may have multiple children 
        +		 */
        +		if (node->nchild)
        +			continue;
        +
        +		/* Create a new node with qualifiers from anyPolicy and
        +		 * id from unmatched node.
        +		 */
        +		data = policy_data_new(NULL, node->data->valid_policy, 
        +						node_critical(node));
        +
        +		if (data == NULL)
        +			return 0;
        +		/* Curr may not have anyPolicy */
        +		data->qualifier_set = cache->anyPolicy->qualifier_set;
        +		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
        +		if (!level_add_node(curr, data, node, tree))
        +			{
        +			policy_data_free(data);
        +			return 0;
        +			}
        +
        +#endif
        +
        +		}
        +	/* Finally add link to anyPolicy */
        +	if (last->anyPolicy)
        +		{
        +		if (!level_add_node(curr, cache->anyPolicy,
        +						last->anyPolicy, NULL))
        +			return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* Prune the tree: delete any child mapped child data on the current level
        + * then proceed up the tree deleting any data with no children. If we ever
        + * have no data on a level we can halt because the tree will be empty.
        + */
        +
        +static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
        +	{
        +	STACK_OF(X509_POLICY_NODE) *nodes;
        +	X509_POLICY_NODE *node;
        +	int i;
        +	nodes = curr->nodes;
        +	if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
        +		{
        +		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
        +			{
        +			node = sk_X509_POLICY_NODE_value(nodes, i);
        +			/* Delete any mapped data: see RFC3280 XXXX */
        +			if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
        +				{
        +				node->parent->nchild--;
        +				OPENSSL_free(node);
        +				(void)sk_X509_POLICY_NODE_delete(nodes,i);
        +				}
        +			}
        +		}
        +
        +	for(;;)	{
        +		--curr;
        +		nodes = curr->nodes;
        +		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
        +			{
        +			node = sk_X509_POLICY_NODE_value(nodes, i);
        +			if (node->nchild == 0)
        +				{
        +				node->parent->nchild--;
        +				OPENSSL_free(node);
        +				(void)sk_X509_POLICY_NODE_delete(nodes, i);
        +				}
        +			}
        +		if (curr->anyPolicy && !curr->anyPolicy->nchild)
        +			{
        +			if (curr->anyPolicy->parent)
        +				curr->anyPolicy->parent->nchild--;
        +			OPENSSL_free(curr->anyPolicy);
        +			curr->anyPolicy = NULL;
        +			}
        +		if (curr == tree->levels)
        +			{
        +			/* If we zapped anyPolicy at top then tree is empty */
        +			if (!curr->anyPolicy)
        +					return 2;
        +			return 1;
        +			}
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
        +						 X509_POLICY_NODE *pcy)
        +	{
        +	if (!*pnodes)
        +		{
        +		*pnodes = policy_node_cmp_new();
        +		if (!*pnodes)
        +			return 0;
        +		}
        +	else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
        +		return 1;
        +
        +	if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
        +		return 0;
        +
        +	return 1;
        +
        +	}
        +
        +/* Calculate the authority set based on policy tree.
        + * The 'pnodes' parameter is used as a store for the set of policy nodes
        + * used to calculate the user set. If the authority set is not anyPolicy
        + * then pnodes will just point to the authority set. If however the authority
        + * set is anyPolicy then the set of valid policies (other than anyPolicy)
        + * is store in pnodes. The return value of '2' is used in this case to indicate
        + * that pnodes should be freed.
        + */
        +
        +static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
        +					STACK_OF(X509_POLICY_NODE) **pnodes)
        +	{
        +	X509_POLICY_LEVEL *curr;
        +	X509_POLICY_NODE *node, *anyptr;
        +	STACK_OF(X509_POLICY_NODE) **addnodes;
        +	int i, j;
        +	curr = tree->levels + tree->nlevel - 1;
        +
        +	/* If last level contains anyPolicy set is anyPolicy */
        +	if (curr->anyPolicy)
        +		{
        +		if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
        +			return 0;
        +		addnodes = pnodes;
        +		}
        +	else
        +		/* Add policies to authority set */
        +		addnodes = &tree->auth_policies;
        +
        +	curr = tree->levels;
        +	for (i = 1; i < tree->nlevel; i++)
        +		{
        +		/* If no anyPolicy node on this this level it can't
        +		 * appear on lower levels so end search.
        +		 */
        +		if (!(anyptr = curr->anyPolicy))
        +			break;
        +		curr++;
        +		for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
        +			{
        +			node = sk_X509_POLICY_NODE_value(curr->nodes, j);
        +			if ((node->parent == anyptr)
        +				&& !tree_add_auth_node(addnodes, node))
        +					return 0;
        +			}
        +		}
        +
        +	if (addnodes == pnodes)
        +		return 2;
        +
        +	*pnodes = tree->auth_policies;
        +
        +	return 1;
        +	}
        +
        +static int tree_calculate_user_set(X509_POLICY_TREE *tree,
        +				STACK_OF(ASN1_OBJECT) *policy_oids,
        +				STACK_OF(X509_POLICY_NODE) *auth_nodes)
        +	{
        +	int i;
        +	X509_POLICY_NODE *node;
        +	ASN1_OBJECT *oid;
        +
        +	X509_POLICY_NODE *anyPolicy;
        +	X509_POLICY_DATA *extra;
        +
        +	/* Check if anyPolicy present in authority constrained policy set:
        +	 * this will happen if it is a leaf node.
        +	 */
        +
        +	if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
        +		return 1;
        +
        +	anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
        +
        +	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
        +		{
        +		oid = sk_ASN1_OBJECT_value(policy_oids, i);
        +		if (OBJ_obj2nid(oid) == NID_any_policy)
        +			{
        +			tree->flags |= POLICY_FLAG_ANY_POLICY;
        +			return 1;
        +			}
        +		}
        +
        +	for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
        +		{
        +		oid = sk_ASN1_OBJECT_value(policy_oids, i);
        +		node = tree_find_sk(auth_nodes, oid);
        +		if (!node)
        +			{
        +			if (!anyPolicy)
        +				continue;
        +			/* Create a new node with policy ID from user set
        +			 * and qualifiers from anyPolicy.
        +			 */
        +			extra = policy_data_new(NULL, oid,
        +						node_critical(anyPolicy));
        +			if (!extra)
        +				return 0;
        +			extra->qualifier_set = anyPolicy->data->qualifier_set;
        +			extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
        +						| POLICY_DATA_FLAG_EXTRA_NODE;
        +			node = level_add_node(NULL, extra, anyPolicy->parent,
        +						tree);
        +			}
        +		if (!tree->user_policies)
        +			{
        +			tree->user_policies = sk_X509_POLICY_NODE_new_null();
        +			if (!tree->user_policies)
        +				return 1;
        +			}
        +		if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
        +			return 0;
        +		}
        +	return 1;
        +
        +	}
        +
        +static int tree_evaluate(X509_POLICY_TREE *tree)
        +	{
        +	int ret, i;
        +	X509_POLICY_LEVEL *curr = tree->levels + 1;
        +	const X509_POLICY_CACHE *cache;
        +
        +	for(i = 1; i < tree->nlevel; i++, curr++)
        +		{
        +		cache = policy_cache_set(curr->cert);
        +		if (!tree_link_nodes(curr, cache))
        +			return 0;
        +
        +		if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
        +			&& !tree_link_any(curr, cache, tree))
        +			return 0;
        +	tree_print("before tree_prune()", tree, curr);
        +		ret = tree_prune(tree, curr);
        +		if (ret != 1)
        +			return ret;
        +		}
        +
        +	return 1;
        +
        +	}
        +
        +static void exnode_free(X509_POLICY_NODE *node)
        +	{
        +	if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
        +		OPENSSL_free(node);
        +	}
        +
        +
        +void X509_policy_tree_free(X509_POLICY_TREE *tree)
        +	{
        +	X509_POLICY_LEVEL *curr;
        +	int i;
        +
        +	if (!tree)
        +		return;
        +
        +	sk_X509_POLICY_NODE_free(tree->auth_policies);
        +	sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
        +
        +	for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
        +		{
        +		if (curr->cert)
        +			X509_free(curr->cert);
        +		if (curr->nodes)
        +			sk_X509_POLICY_NODE_pop_free(curr->nodes,
        +						policy_node_free);
        +		if (curr->anyPolicy)
        +			policy_node_free(curr->anyPolicy);
        +		}
        +
        +	if (tree->extra_data)
        +		sk_X509_POLICY_DATA_pop_free(tree->extra_data,
        +						policy_data_free);
        +
        +	OPENSSL_free(tree->levels);
        +	OPENSSL_free(tree);
        +
        +	}
        +
        +/* Application policy checking function.
        + * Return codes:
        + *  0 	Internal Error.
        + *  1   Successful.
        + * -1   One or more certificates contain invalid or inconsistent extensions
        + * -2	User constrained policy set empty and requireExplicit true.
        + */
        +
        +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
        +			STACK_OF(X509) *certs,
        +			STACK_OF(ASN1_OBJECT) *policy_oids,
        +			unsigned int flags)
        +	{
        +	int ret;
        +	X509_POLICY_TREE *tree = NULL;
        +	STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
        +	*ptree = NULL;
        +
        +	*pexplicit_policy = 0;
        +	ret = tree_init(&tree, certs, flags);
        +
        +	switch (ret)
        +		{
        +
        +		/* Tree empty requireExplicit False: OK */
        +		case 2:
        +		return 1;
        +
        +		/* Some internal error */
        +		case -1:
        +		return -1;
        +
        +		/* Some internal error */
        +		case 0:
        +		return 0;
        +
        +		/* Tree empty requireExplicit True: Error */
        +
        +		case 6:
        +		*pexplicit_policy = 1;
        +		return -2;
        +
        +		/* Tree OK requireExplicit True: OK and continue */
        +		case 5:
        +		*pexplicit_policy = 1;
        +		break;
        +
        +		/* Tree OK: continue */
        +
        +		case 1:
        +		if (!tree)
        +			/*
        +			 * tree_init() returns success and a null tree
        +			 * if it's just looking at a trust anchor.
        +			 * I'm not sure that returning success here is
        +			 * correct, but I'm sure that reporting this
        +			 * as an internal error which our caller
        +			 * interprets as a malloc failure is wrong.
        +			 */
        +			return 1;
        +		break;
        +		}
        +
        +	if (!tree) goto error;
        +	ret = tree_evaluate(tree);
        +
        +	tree_print("tree_evaluate()", tree, NULL);
        +
        +	if (ret <= 0)
        +		goto error;
        +
        +	/* Return value 2 means tree empty */
        +	if (ret == 2)
        +		{
        +		X509_policy_tree_free(tree);
        +		if (*pexplicit_policy)
        +			return -2;
        +		else
        +			return 1;
        +		}
        +
        +	/* Tree is not empty: continue */
        +
        +	ret = tree_calculate_authority_set(tree, &auth_nodes);
        +
        +	if (!ret)
        +		goto error;
        +
        +	if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
        +		goto error;
        +	
        +	if (ret == 2)
        +		sk_X509_POLICY_NODE_free(auth_nodes);
        +
        +	if (tree)
        +		*ptree = tree;
        +
        +	if (*pexplicit_policy)
        +		{
        +		nodes = X509_policy_tree_get0_user_policies(tree);
        +		if (sk_X509_POLICY_NODE_num(nodes) <= 0)
        +			return -2;
        +		}
        +
        +	return 1;
        +
        +	error:
        +
        +	X509_policy_tree_free(tree);
        +
        +	return 0;
        +
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/tabtest.c b/vendor/openssl/openssl/crypto/x509v3/tabtest.c
        new file mode 100644
        index 000000000..5ed6eb689
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/tabtest.c
        @@ -0,0 +1,88 @@
        +/* tabtest.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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).
        + *
        + */
        +
        +/* Simple program to check the ext_dat.h is correct and print out
        + * problems if it is not.
        + */
        +
        +#include <stdio.h>
        +
        +#include <openssl/x509v3.h>
        +
        +#include "ext_dat.h"
        +
        +main()
        +{
        +	int i, prev = -1, bad = 0;
        +	X509V3_EXT_METHOD **tmp;
        +	i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
        +	if(i != STANDARD_EXTENSION_COUNT)
        +		fprintf(stderr, "Extension number invalid expecting %d\n", i);
        +	tmp = standard_exts;
        +	for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
        +		if((*tmp)->ext_nid < prev) bad = 1;
        +		prev = (*tmp)->ext_nid;
        +		
        +	}
        +	if(bad) {
        +		tmp = standard_exts;
        +		fprintf(stderr, "Extensions out of order!\n");
        +		for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
        +		printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
        +	} else fprintf(stderr, "Order OK\n");
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_addr.c b/vendor/openssl/openssl/crypto/x509v3/v3_addr.c
        new file mode 100644
        index 000000000..df46a4983
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_addr.c
        @@ -0,0 +1,1338 @@
        +/*
        + * Contributed to the OpenSSL Project by the American Registry for
        + * Internet Numbers ("ARIN").
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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).
        + */
        +
        +/*
        + * Implementation of RFC 3779 section 2.2.
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/buffer.h>
        +#include <openssl/x509v3.h>
        +
        +#ifndef OPENSSL_NO_RFC3779
        +
        +/*
        + * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
        + */
        +
        +ASN1_SEQUENCE(IPAddressRange) = {
        +  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
        +  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
        +} ASN1_SEQUENCE_END(IPAddressRange)
        +
        +ASN1_CHOICE(IPAddressOrRange) = {
        +  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
        +  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
        +} ASN1_CHOICE_END(IPAddressOrRange)
        +
        +ASN1_CHOICE(IPAddressChoice) = {
        +  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
        +  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
        +} ASN1_CHOICE_END(IPAddressChoice)
        +
        +ASN1_SEQUENCE(IPAddressFamily) = {
        +  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
        +  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
        +} ASN1_SEQUENCE_END(IPAddressFamily)
        +
        +ASN1_ITEM_TEMPLATE(IPAddrBlocks) = 
        +  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
        +			IPAddrBlocks, IPAddressFamily)
        +ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
        +IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
        +IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
        +IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
        +
        +/*
        + * How much buffer space do we need for a raw address?
        + */
        +#define ADDR_RAW_BUF_LEN	16
        +
        +/*
        + * What's the address length associated with this AFI?
        + */
        +static int length_from_afi(const unsigned afi)
        +{
        +  switch (afi) {
        +  case IANA_AFI_IPV4:
        +    return 4;
        +  case IANA_AFI_IPV6:
        +    return 16;
        +  default:
        +    return 0;
        +  }
        +}
        +
        +/*
        + * Extract the AFI from an IPAddressFamily.
        + */
        +unsigned int v3_addr_get_afi(const IPAddressFamily *f)
        +{
        +  return ((f != NULL &&
        +	   f->addressFamily != NULL &&
        +	   f->addressFamily->data != NULL)
        +	  ? ((f->addressFamily->data[0] << 8) |
        +	     (f->addressFamily->data[1]))
        +	  : 0);
        +}
        +
        +/*
        + * Expand the bitstring form of an address into a raw byte array.
        + * At the moment this is coded for simplicity, not speed.
        + */
        +static int addr_expand(unsigned char *addr,
        +			const ASN1_BIT_STRING *bs,
        +			const int length,
        +			const unsigned char fill)
        +{
        +  if (bs->length < 0 || bs->length > length)
        +    return 0;
        +  if (bs->length > 0) {
        +    memcpy(addr, bs->data, bs->length);
        +    if ((bs->flags & 7) != 0) {
        +      unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
        +      if (fill == 0)
        +	addr[bs->length - 1] &= ~mask;
        +      else
        +	addr[bs->length - 1] |= mask;
        +    }
        +  }
        +  memset(addr + bs->length, fill, length - bs->length);
        +  return 1;
        +}
        +
        +/*
        + * Extract the prefix length from a bitstring.
        + */
        +#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
        +
        +/*
        + * i2r handler for one address bitstring.
        + */
        +static int i2r_address(BIO *out,
        +		       const unsigned afi,
        +		       const unsigned char fill,
        +		       const ASN1_BIT_STRING *bs)
        +{
        +  unsigned char addr[ADDR_RAW_BUF_LEN];
        +  int i, n;
        +
        +  if (bs->length < 0)
        +    return 0;
        +  switch (afi) {
        +  case IANA_AFI_IPV4:
        +    if (!addr_expand(addr, bs, 4, fill))
        +      return 0;
        +    BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
        +    break;
        +  case IANA_AFI_IPV6:
        +    if (!addr_expand(addr, bs, 16, fill))
        +      return 0;
        +    for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
        +      ;
        +    for (i = 0; i < n; i += 2)
        +      BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
        +    if (i < 16)
        +      BIO_puts(out, ":");
        +    if (i == 0)
        +      BIO_puts(out, ":");
        +    break;
        +  default:
        +    for (i = 0; i < bs->length; i++)
        +      BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
        +    BIO_printf(out, "[%d]", (int) (bs->flags & 7));
        +    break;
        +  }
        +  return 1;
        +}
        +
        +/*
        + * i2r handler for a sequence of addresses and ranges.
        + */
        +static int i2r_IPAddressOrRanges(BIO *out,
        +				 const int indent,
        +				 const IPAddressOrRanges *aors,
        +				 const unsigned afi)
        +{
        +  int i;
        +  for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
        +    const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
        +    BIO_printf(out, "%*s", indent, "");
        +    switch (aor->type) {
        +    case IPAddressOrRange_addressPrefix:
        +      if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
        +	return 0;
        +      BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
        +      continue;
        +    case IPAddressOrRange_addressRange:
        +      if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
        +	return 0;
        +      BIO_puts(out, "-");
        +      if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
        +	return 0;
        +      BIO_puts(out, "\n");
        +      continue;
        +    }
        +  }
        +  return 1;
        +}
        +
        +/*
        + * i2r handler for an IPAddrBlocks extension.
        + */
        +static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
        +			    void *ext,
        +			    BIO *out,
        +			    int indent)
        +{
        +  const IPAddrBlocks *addr = ext;
        +  int i;
        +  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        +    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        +    const unsigned int afi = v3_addr_get_afi(f);
        +    switch (afi) {
        +    case IANA_AFI_IPV4:
        +      BIO_printf(out, "%*sIPv4", indent, "");
        +      break;
        +    case IANA_AFI_IPV6:
        +      BIO_printf(out, "%*sIPv6", indent, "");
        +      break;
        +    default:
        +      BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
        +      break;
        +    }
        +    if (f->addressFamily->length > 2) {
        +      switch (f->addressFamily->data[2]) {
        +      case   1:
        +	BIO_puts(out, " (Unicast)");
        +	break;
        +      case   2:
        +	BIO_puts(out, " (Multicast)");
        +	break;
        +      case   3:
        +	BIO_puts(out, " (Unicast/Multicast)");
        +	break;
        +      case   4:
        +	BIO_puts(out, " (MPLS)");
        +	break;
        +      case  64:
        +	BIO_puts(out, " (Tunnel)");
        +	break;
        +      case  65:
        +	BIO_puts(out, " (VPLS)");
        +	break;
        +      case  66:
        +	BIO_puts(out, " (BGP MDT)");
        +	break;
        +      case 128:
        +	BIO_puts(out, " (MPLS-labeled VPN)");
        +	break;
        +      default:  
        +	BIO_printf(out, " (Unknown SAFI %u)",
        +		   (unsigned) f->addressFamily->data[2]);
        +	break;
        +      }
        +    }
        +    switch (f->ipAddressChoice->type) {
        +    case IPAddressChoice_inherit:
        +      BIO_puts(out, ": inherit\n");
        +      break;
        +    case IPAddressChoice_addressesOrRanges:
        +      BIO_puts(out, ":\n");
        +      if (!i2r_IPAddressOrRanges(out,
        +				 indent + 2,
        +				 f->ipAddressChoice->u.addressesOrRanges,
        +				 afi))
        +	return 0;
        +      break;
        +    }
        +  }
        +  return 1;
        +}
        +
        +/*
        + * Sort comparison function for a sequence of IPAddressOrRange
        + * elements.
        + *
        + * There's no sane answer we can give if addr_expand() fails, and an
        + * assertion failure on externally supplied data is seriously uncool,
        + * so we just arbitrarily declare that if given invalid inputs this
        + * function returns -1.  If this messes up your preferred sort order
        + * for garbage input, tough noogies.
        + */
        +static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
        +				const IPAddressOrRange *b,
        +				const int length)
        +{
        +  unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
        +  int prefixlen_a = 0, prefixlen_b = 0;
        +  int r;
        +
        +  switch (a->type) {
        +  case IPAddressOrRange_addressPrefix:
        +    if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
        +      return -1;
        +    prefixlen_a = addr_prefixlen(a->u.addressPrefix);
        +    break;
        +  case IPAddressOrRange_addressRange:
        +    if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
        +      return -1;
        +    prefixlen_a = length * 8;
        +    break;
        +  }
        +
        +  switch (b->type) {
        +  case IPAddressOrRange_addressPrefix:
        +    if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
        +      return -1;
        +    prefixlen_b = addr_prefixlen(b->u.addressPrefix);
        +    break;
        +  case IPAddressOrRange_addressRange:
        +    if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
        +      return -1;
        +    prefixlen_b = length * 8;
        +    break;
        +  }
        +
        +  if ((r = memcmp(addr_a, addr_b, length)) != 0)
        +    return r;
        +  else
        +    return prefixlen_a - prefixlen_b;
        +}
        +
        +/*
        + * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
        + * comparision routines are only allowed two arguments.
        + */
        +static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
        +				  const IPAddressOrRange * const *b)
        +{
        +  return IPAddressOrRange_cmp(*a, *b, 4);
        +}
        +
        +/*
        + * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
        + * comparision routines are only allowed two arguments.
        + */
        +static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
        +				  const IPAddressOrRange * const *b)
        +{
        +  return IPAddressOrRange_cmp(*a, *b, 16);
        +}
        +
        +/*
        + * Calculate whether a range collapses to a prefix.
        + * See last paragraph of RFC 3779 2.2.3.7.
        + */
        +static int range_should_be_prefix(const unsigned char *min,
        +				  const unsigned char *max,
        +				  const int length)
        +{
        +  unsigned char mask;
        +  int i, j;
        +
        +  OPENSSL_assert(memcmp(min, max, length) <= 0);
        +  for (i = 0; i < length && min[i] == max[i]; i++)
        +    ;
        +  for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
        +    ;
        +  if (i < j)
        +    return -1;
        +  if (i > j)
        +    return i * 8;
        +  mask = min[i] ^ max[i];
        +  switch (mask) {
        +  case 0x01: j = 7; break;
        +  case 0x03: j = 6; break;
        +  case 0x07: j = 5; break;
        +  case 0x0F: j = 4; break;
        +  case 0x1F: j = 3; break;
        +  case 0x3F: j = 2; break;
        +  case 0x7F: j = 1; break;
        +  default:   return -1;
        +  }
        +  if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
        +    return -1;
        +  else
        +    return i * 8 + j;
        +}
        +
        +/*
        + * Construct a prefix.
        + */
        +static int make_addressPrefix(IPAddressOrRange **result,
        +			      unsigned char *addr,
        +			      const int prefixlen)
        +{
        +  int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
        +  IPAddressOrRange *aor = IPAddressOrRange_new();
        +
        +  if (aor == NULL)
        +    return 0;
        +  aor->type = IPAddressOrRange_addressPrefix;
        +  if (aor->u.addressPrefix == NULL &&
        +      (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
        +    goto err;
        +  if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
        +    goto err;
        +  aor->u.addressPrefix->flags &= ~7;
        +  aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        +  if (bitlen > 0) {
        +    aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
        +    aor->u.addressPrefix->flags |= 8 - bitlen;
        +  }
        +  
        +  *result = aor;
        +  return 1;
        +
        + err:
        +  IPAddressOrRange_free(aor);
        +  return 0;
        +}
        +
        +/*
        + * Construct a range.  If it can be expressed as a prefix,
        + * return a prefix instead.  Doing this here simplifies
        + * the rest of the code considerably.
        + */
        +static int make_addressRange(IPAddressOrRange **result,
        +			     unsigned char *min,
        +			     unsigned char *max,
        +			     const int length)
        +{
        +  IPAddressOrRange *aor;
        +  int i, prefixlen;
        +
        +  if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
        +    return make_addressPrefix(result, min, prefixlen);
        +
        +  if ((aor = IPAddressOrRange_new()) == NULL)
        +    return 0;
        +  aor->type = IPAddressOrRange_addressRange;
        +  OPENSSL_assert(aor->u.addressRange == NULL);
        +  if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
        +    goto err;
        +  if (aor->u.addressRange->min == NULL &&
        +      (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
        +    goto err;
        +  if (aor->u.addressRange->max == NULL &&
        +      (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
        +    goto err;
        +
        +  for (i = length; i > 0 && min[i - 1] == 0x00; --i)
        +    ;
        +  if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
        +    goto err;
        +  aor->u.addressRange->min->flags &= ~7;
        +  aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        +  if (i > 0) {
        +    unsigned char b = min[i - 1];
        +    int j = 1;
        +    while ((b & (0xFFU >> j)) != 0) 
        +      ++j;
        +    aor->u.addressRange->min->flags |= 8 - j;
        +  }
        +
        +  for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
        +    ;
        +  if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
        +    goto err;
        +  aor->u.addressRange->max->flags &= ~7;
        +  aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        +  if (i > 0) {
        +    unsigned char b = max[i - 1];
        +    int j = 1;
        +    while ((b & (0xFFU >> j)) != (0xFFU >> j))
        +      ++j;
        +    aor->u.addressRange->max->flags |= 8 - j;
        +  }
        +
        +  *result = aor;
        +  return 1;
        +
        + err:
        +  IPAddressOrRange_free(aor);
        +  return 0;
        +}
        +
        +/*
        + * Construct a new address family or find an existing one.
        + */
        +static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
        +					     const unsigned afi,
        +					     const unsigned *safi)
        +{
        +  IPAddressFamily *f;
        +  unsigned char key[3];
        +  unsigned keylen;
        +  int i;
        +
        +  key[0] = (afi >> 8) & 0xFF;
        +  key[1] = afi & 0xFF;
        +  if (safi != NULL) {
        +    key[2] = *safi & 0xFF;
        +    keylen = 3;
        +  } else {
        +    keylen = 2;
        +  }
        +
        +  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        +    f = sk_IPAddressFamily_value(addr, i);
        +    OPENSSL_assert(f->addressFamily->data != NULL);
        +    if (f->addressFamily->length == keylen &&
        +	!memcmp(f->addressFamily->data, key, keylen))
        +      return f;
        +  }
        +
        +  if ((f = IPAddressFamily_new()) == NULL)
        +    goto err;
        +  if (f->ipAddressChoice == NULL &&
        +      (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
        +    goto err;
        +  if (f->addressFamily == NULL && 
        +      (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
        +    goto err;
        +  if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
        +    goto err;
        +  if (!sk_IPAddressFamily_push(addr, f))
        +    goto err;
        +
        +  return f;
        +
        + err:
        +  IPAddressFamily_free(f);
        +  return NULL;
        +}
        +
        +/*
        + * Add an inheritance element.
        + */
        +int v3_addr_add_inherit(IPAddrBlocks *addr,
        +			const unsigned afi,
        +			const unsigned *safi)
        +{
        +  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
        +  if (f == NULL ||
        +      f->ipAddressChoice == NULL ||
        +      (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
        +       f->ipAddressChoice->u.addressesOrRanges != NULL))
        +    return 0;
        +  if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
        +      f->ipAddressChoice->u.inherit != NULL)
        +    return 1;
        +  if (f->ipAddressChoice->u.inherit == NULL &&
        +      (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
        +    return 0;
        +  f->ipAddressChoice->type = IPAddressChoice_inherit;
        +  return 1;
        +}
        +
        +/*
        + * Construct an IPAddressOrRange sequence, or return an existing one.
        + */
        +static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
        +					       const unsigned afi,
        +					       const unsigned *safi)
        +{
        +  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
        +  IPAddressOrRanges *aors = NULL;
        +
        +  if (f == NULL ||
        +      f->ipAddressChoice == NULL ||
        +      (f->ipAddressChoice->type == IPAddressChoice_inherit &&
        +       f->ipAddressChoice->u.inherit != NULL))
        +    return NULL;
        +  if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
        +    aors = f->ipAddressChoice->u.addressesOrRanges;
        +  if (aors != NULL)
        +    return aors;
        +  if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
        +    return NULL;
        +  switch (afi) {
        +  case IANA_AFI_IPV4:
        +    (void) sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
        +    break;
        +  case IANA_AFI_IPV6:
        +    (void) sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
        +    break;
        +  }
        +  f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
        +  f->ipAddressChoice->u.addressesOrRanges = aors;
        +  return aors;
        +}
        +
        +/*
        + * Add a prefix.
        + */
        +int v3_addr_add_prefix(IPAddrBlocks *addr,
        +		       const unsigned afi,
        +		       const unsigned *safi,
        +		       unsigned char *a,
        +		       const int prefixlen)
        +{
        +  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
        +  IPAddressOrRange *aor;
        +  if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
        +    return 0;
        +  if (sk_IPAddressOrRange_push(aors, aor))
        +    return 1;
        +  IPAddressOrRange_free(aor);
        +  return 0;
        +}
        +
        +/*
        + * Add a range.
        + */
        +int v3_addr_add_range(IPAddrBlocks *addr,
        +		      const unsigned afi,
        +		      const unsigned *safi,
        +		      unsigned char *min,
        +		      unsigned char *max)
        +{
        +  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
        +  IPAddressOrRange *aor;
        +  int length = length_from_afi(afi);
        +  if (aors == NULL)
        +    return 0;
        +  if (!make_addressRange(&aor, min, max, length))
        +    return 0;
        +  if (sk_IPAddressOrRange_push(aors, aor))
        +    return 1;
        +  IPAddressOrRange_free(aor);
        +  return 0;
        +}
        +
        +/*
        + * Extract min and max values from an IPAddressOrRange.
        + */
        +static int extract_min_max(IPAddressOrRange *aor,
        +			    unsigned char *min,
        +			    unsigned char *max,
        +			    int length)
        +{
        +  if (aor == NULL || min == NULL || max == NULL)
        +    return 0;
        +  switch (aor->type) {
        +  case IPAddressOrRange_addressPrefix:
        +    return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
        +	    addr_expand(max, aor->u.addressPrefix, length, 0xFF));
        +  case IPAddressOrRange_addressRange:
        +    return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
        +	    addr_expand(max, aor->u.addressRange->max, length, 0xFF));
        +  }
        +  return 0;
        +}
        +
        +/*
        + * Public wrapper for extract_min_max().
        + */
        +int v3_addr_get_range(IPAddressOrRange *aor,
        +		      const unsigned afi,
        +		      unsigned char *min,
        +		      unsigned char *max,
        +		      const int length)
        +{
        +  int afi_length = length_from_afi(afi);
        +  if (aor == NULL || min == NULL || max == NULL ||
        +      afi_length == 0 || length < afi_length ||
        +      (aor->type != IPAddressOrRange_addressPrefix &&
        +       aor->type != IPAddressOrRange_addressRange) ||
        +      !extract_min_max(aor, min, max, afi_length))
        +    return 0;
        +
        +  return afi_length;
        +}
        +
        +/*
        + * Sort comparision function for a sequence of IPAddressFamily.
        + *
        + * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
        + * the ordering: I can read it as meaning that IPv6 without a SAFI
        + * comes before IPv4 with a SAFI, which seems pretty weird.  The
        + * examples in appendix B suggest that the author intended the
        + * null-SAFI rule to apply only within a single AFI, which is what I
        + * would have expected and is what the following code implements.
        + */
        +static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
        +			       const IPAddressFamily * const *b_)
        +{
        +  const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
        +  const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
        +  int len = ((a->length <= b->length) ? a->length : b->length);
        +  int cmp = memcmp(a->data, b->data, len);
        +  return cmp ? cmp : a->length - b->length;
        +}
        +
        +/*
        + * Check whether an IPAddrBLocks is in canonical form.
        + */
        +int v3_addr_is_canonical(IPAddrBlocks *addr)
        +{
        +  unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
        +  unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
        +  IPAddressOrRanges *aors;
        +  int i, j, k;
        +
        +  /*
        +   * Empty extension is cannonical.
        +   */
        +  if (addr == NULL)
        +    return 1;
        +
        +  /*
        +   * Check whether the top-level list is in order.
        +   */
        +  for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
        +    const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
        +    const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
        +    if (IPAddressFamily_cmp(&a, &b) >= 0)
        +      return 0;
        +  }
        +
        +  /*
        +   * Top level's ok, now check each address family.
        +   */
        +  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        +    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        +    int length = length_from_afi(v3_addr_get_afi(f));
        +
        +    /*
        +     * Inheritance is canonical.  Anything other than inheritance or
        +     * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
        +     */
        +    if (f == NULL || f->ipAddressChoice == NULL)
        +      return 0;
        +    switch (f->ipAddressChoice->type) {
        +    case IPAddressChoice_inherit:
        +      continue;
        +    case IPAddressChoice_addressesOrRanges:
        +      break;
        +    default:
        +      return 0;
        +    }
        +
        +    /*
        +     * It's an IPAddressOrRanges sequence, check it.
        +     */
        +    aors = f->ipAddressChoice->u.addressesOrRanges;
        +    if (sk_IPAddressOrRange_num(aors) == 0)
        +      return 0;
        +    for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
        +      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
        +      IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
        +
        +      if (!extract_min_max(a, a_min, a_max, length) ||
        +	  !extract_min_max(b, b_min, b_max, length))
        +	return 0;
        +
        +      /*
        +       * Punt misordered list, overlapping start, or inverted range.
        +       */
        +      if (memcmp(a_min, b_min, length) >= 0 ||
        +	  memcmp(a_min, a_max, length) > 0 ||
        +	  memcmp(b_min, b_max, length) > 0)
        +	return 0;
        +
        +      /*
        +       * Punt if adjacent or overlapping.  Check for adjacency by
        +       * subtracting one from b_min first.
        +       */
        +      for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
        +	;
        +      if (memcmp(a_max, b_min, length) >= 0)
        +	return 0;
        +
        +      /*
        +       * Check for range that should be expressed as a prefix.
        +       */
        +      if (a->type == IPAddressOrRange_addressRange &&
        +	  range_should_be_prefix(a_min, a_max, length) >= 0)
        +	return 0;
        +    }
        +
        +    /*
        +     * Check range to see if it's inverted or should be a
        +     * prefix.
        +     */
        +    j = sk_IPAddressOrRange_num(aors) - 1;
        +    {
        +      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
        +      if (a != NULL && a->type == IPAddressOrRange_addressRange) {
        +	if (!extract_min_max(a, a_min, a_max, length))
        +	  return 0;
        +	if (memcmp(a_min, a_max, length) > 0 ||
        +	    range_should_be_prefix(a_min, a_max, length) >= 0)
        +	  return 0;
        +      }
        +    }
        +  }
        +
        +  /*
        +   * If we made it through all that, we're happy.
        +   */
        +  return 1;
        +}
        +
        +/*
        + * Whack an IPAddressOrRanges into canonical form.
        + */
        +static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
        +				      const unsigned afi)
        +{
        +  int i, j, length = length_from_afi(afi);
        +
        +  /*
        +   * Sort the IPAddressOrRanges sequence.
        +   */
        +  sk_IPAddressOrRange_sort(aors);
        +
        +  /*
        +   * Clean up representation issues, punt on duplicates or overlaps.
        +   */
        +  for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
        +    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
        +    IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
        +    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
        +    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
        +
        +    if (!extract_min_max(a, a_min, a_max, length) ||
        +	!extract_min_max(b, b_min, b_max, length))
        +      return 0;
        +
        +    /*
        +     * Punt inverted ranges.
        +     */
        +    if (memcmp(a_min, a_max, length) > 0 ||
        +	memcmp(b_min, b_max, length) > 0)
        +      return 0;
        +
        +    /*
        +     * Punt overlaps.
        +     */
        +    if (memcmp(a_max, b_min, length) >= 0)
        +      return 0;
        +
        +    /*
        +     * Merge if a and b are adjacent.  We check for
        +     * adjacency by subtracting one from b_min first.
        +     */
        +    for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
        +      ;
        +    if (memcmp(a_max, b_min, length) == 0) {
        +      IPAddressOrRange *merged;
        +      if (!make_addressRange(&merged, a_min, b_max, length))
        +	return 0;
        +      (void) sk_IPAddressOrRange_set(aors, i, merged);
        +      (void) sk_IPAddressOrRange_delete(aors, i + 1);
        +      IPAddressOrRange_free(a);
        +      IPAddressOrRange_free(b);
        +      --i;
        +      continue;
        +    }
        +  }
        +
        +  /*
        +   * Check for inverted final range.
        +   */
        +  j = sk_IPAddressOrRange_num(aors) - 1;
        +  {
        +    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
        +    if (a != NULL && a->type == IPAddressOrRange_addressRange) {
        +      unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
        +      extract_min_max(a, a_min, a_max, length);
        +      if (memcmp(a_min, a_max, length) > 0)
        +	return 0;
        +    }
        +  }
        +
        +  return 1;
        +}
        +
        +/*
        + * Whack an IPAddrBlocks extension into canonical form.
        + */
        +int v3_addr_canonize(IPAddrBlocks *addr)
        +{
        +  int i;
        +  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        +    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        +    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
        +	!IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
        +				    v3_addr_get_afi(f)))
        +      return 0;
        +  }
        +  (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
        +  sk_IPAddressFamily_sort(addr);
        +  OPENSSL_assert(v3_addr_is_canonical(addr));
        +  return 1;
        +}
        +
        +/*
        + * v2i handler for the IPAddrBlocks extension.
        + */
        +static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
        +			      struct v3_ext_ctx *ctx,
        +			      STACK_OF(CONF_VALUE) *values)
        +{
        +  static const char v4addr_chars[] = "0123456789.";
        +  static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
        +  IPAddrBlocks *addr = NULL;
        +  char *s = NULL, *t;
        +  int i;
        +  
        +  if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
        +    X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        +    return NULL;
        +  }
        +
        +  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
        +    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
        +    unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
        +    unsigned afi, *safi = NULL, safi_;
        +    const char *addr_chars;
        +    int prefixlen, i1, i2, delim, length;
        +
        +    if (       !name_cmp(val->name, "IPv4")) {
        +      afi = IANA_AFI_IPV4;
        +    } else if (!name_cmp(val->name, "IPv6")) {
        +      afi = IANA_AFI_IPV6;
        +    } else if (!name_cmp(val->name, "IPv4-SAFI")) {
        +      afi = IANA_AFI_IPV4;
        +      safi = &safi_;
        +    } else if (!name_cmp(val->name, "IPv6-SAFI")) {
        +      afi = IANA_AFI_IPV6;
        +      safi = &safi_;
        +    } else {
        +      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
        +      X509V3_conf_err(val);
        +      goto err;
        +    }
        +
        +    switch (afi) {
        +    case IANA_AFI_IPV4:
        +      addr_chars = v4addr_chars;
        +      break;
        +    case IANA_AFI_IPV6:
        +      addr_chars = v6addr_chars;
        +      break;
        +    }
        +
        +    length = length_from_afi(afi);
        +
        +    /*
        +     * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
        +     * the other input values.
        +     */
        +    if (safi != NULL) {
        +      *safi = strtoul(val->value, &t, 0);
        +      t += strspn(t, " \t");
        +      if (*safi > 0xFF || *t++ != ':') {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      t += strspn(t, " \t");
        +      s = BUF_strdup(t);
        +    } else {
        +      s = BUF_strdup(val->value);
        +    }
        +    if (s == NULL) {
        +      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        +      goto err;
        +    }
        +
        +    /*
        +     * Check for inheritance.  Not worth additional complexity to
        +     * optimize this (seldom-used) case.
        +     */
        +    if (!strcmp(s, "inherit")) {
        +      if (!v3_addr_add_inherit(addr, afi, safi)) {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      OPENSSL_free(s);
        +      s = NULL;
        +      continue;
        +    }
        +
        +    i1 = strspn(s, addr_chars);
        +    i2 = i1 + strspn(s + i1, " \t");
        +    delim = s[i2++];
        +    s[i1] = '\0';
        +
        +    if (a2i_ipadd(min, s) != length) {
        +      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
        +      X509V3_conf_err(val);
        +      goto err;
        +    }
        +
        +    switch (delim) {
        +    case '/':
        +      prefixlen = (int) strtoul(s + i2, &t, 10);
        +      if (t == s + i2 || *t != '\0') {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +      }
        +      break;
        +    case '-':
        +      i1 = i2 + strspn(s + i2, " \t");
        +      i2 = i1 + strspn(s + i1, addr_chars);
        +      if (i1 == i2 || s[i2] != '\0') {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      if (a2i_ipadd(max, s + i1) != length) {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      if (memcmp(min, max, length_from_afi(afi)) > 0) {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      if (!v3_addr_add_range(addr, afi, safi, min, max)) {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +      }
        +      break;
        +    case '\0':
        +      if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
        +	X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +      }
        +      break;
        +    default:
        +      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
        +      X509V3_conf_err(val);
        +      goto err;
        +    }
        +
        +    OPENSSL_free(s);
        +    s = NULL;
        +  }
        +
        +  /*
        +   * Canonize the result, then we're done.
        +   */
        +  if (!v3_addr_canonize(addr))
        +    goto err;    
        +  return addr;
        +
        + err:
        +  OPENSSL_free(s);
        +  sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
        +  return NULL;
        +}
        +
        +/*
        + * OpenSSL dispatch
        + */
        +const X509V3_EXT_METHOD v3_addr = {
        +  NID_sbgp_ipAddrBlock,		/* nid */
        +  0,				/* flags */
        +  ASN1_ITEM_ref(IPAddrBlocks),	/* template */
        +  0, 0, 0, 0,			/* old functions, ignored */
        +  0,				/* i2s */
        +  0,				/* s2i */
        +  0,				/* i2v */
        +  v2i_IPAddrBlocks,		/* v2i */
        +  i2r_IPAddrBlocks,		/* i2r */
        +  0,				/* r2i */
        +  NULL				/* extension-specific data */
        +};
        +
        +/*
        + * Figure out whether extension sues inheritance.
        + */
        +int v3_addr_inherits(IPAddrBlocks *addr)
        +{
        +  int i;
        +  if (addr == NULL)
        +    return 0;
        +  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        +    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        +    if (f->ipAddressChoice->type == IPAddressChoice_inherit)
        +      return 1;
        +  }
        +  return 0;
        +}
        +
        +/*
        + * Figure out whether parent contains child.
        + */
        +static int addr_contains(IPAddressOrRanges *parent,
        +			 IPAddressOrRanges *child,
        +			 int length)
        +{
        +  unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
        +  unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
        +  int p, c;
        +
        +  if (child == NULL || parent == child)
        +    return 1;
        +  if (parent == NULL)
        +    return 0;
        +
        +  p = 0;
        +  for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
        +    if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
        +			 c_min, c_max, length))
        +      return -1;
        +    for (;; p++) {
        +      if (p >= sk_IPAddressOrRange_num(parent))
        +	return 0;
        +      if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
        +			   p_min, p_max, length))
        +	return 0;
        +      if (memcmp(p_max, c_max, length) < 0)
        +	continue;
        +      if (memcmp(p_min, c_min, length) > 0)
        +	return 0;
        +      break;
        +    }
        +  }
        +
        +  return 1;
        +}
        +
        +/*
        + * Test whether a is a subset of b.
        + */
        +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
        +{
        +  int i;
        +  if (a == NULL || a == b)
        +    return 1;
        +  if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
        +    return 0;
        +  (void) sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
        +  for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
        +    IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
        +    int j = sk_IPAddressFamily_find(b, fa);
        +    IPAddressFamily *fb;
        +    fb = sk_IPAddressFamily_value(b, j);
        +    if (fb == NULL)
        +       return 0;
        +    if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 
        +		       fa->ipAddressChoice->u.addressesOrRanges,
        +		       length_from_afi(v3_addr_get_afi(fb))))
        +      return 0;
        +  }
        +  return 1;
        +}
        +
        +/*
        + * Validation error handling via callback.
        + */
        +#define validation_err(_err_)		\
        +  do {					\
        +    if (ctx != NULL) {			\
        +      ctx->error = _err_;		\
        +      ctx->error_depth = i;		\
        +      ctx->current_cert = x;		\
        +      ret = ctx->verify_cb(0, ctx);	\
        +    } else {				\
        +      ret = 0;				\
        +    }					\
        +    if (!ret)				\
        +      goto done;			\
        +  } while (0)
        +
        +/*
        + * Core code for RFC 3779 2.3 path validation.
        + */
        +static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
        +					  STACK_OF(X509) *chain,
        +					  IPAddrBlocks *ext)
        +{
        +  IPAddrBlocks *child = NULL;
        +  int i, j, ret = 1;
        +  X509 *x;
        +
        +  OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
        +  OPENSSL_assert(ctx != NULL || ext != NULL);
        +  OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
        +
        +  /*
        +   * Figure out where to start.  If we don't have an extension to
        +   * check, we're done.  Otherwise, check canonical form and
        +   * set up for walking up the chain.
        +   */
        +  if (ext != NULL) {
        +    i = -1;
        +    x = NULL;
        +  } else {
        +    i = 0;
        +    x = sk_X509_value(chain, i);
        +    OPENSSL_assert(x != NULL);
        +    if ((ext = x->rfc3779_addr) == NULL)
        +      goto done;
        +  }
        +  if (!v3_addr_is_canonical(ext))
        +    validation_err(X509_V_ERR_INVALID_EXTENSION);
        +  (void) sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
        +  if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
        +    X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
        +    ret = 0;
        +    goto done;
        +  }
        +
        +  /*
        +   * Now walk up the chain.  No cert may list resources that its
        +   * parent doesn't list.
        +   */
        +  for (i++; i < sk_X509_num(chain); i++) {
        +    x = sk_X509_value(chain, i);
        +    OPENSSL_assert(x != NULL);
        +    if (!v3_addr_is_canonical(x->rfc3779_addr))
        +      validation_err(X509_V_ERR_INVALID_EXTENSION);
        +    if (x->rfc3779_addr == NULL) {
        +      for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
        +	IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
        +	if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
        +	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +	  break;
        +	}
        +      }
        +      continue;
        +    }
        +    (void) sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
        +    for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
        +      IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
        +      int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
        +      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
        +      if (fp == NULL) {
        +	if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
        +	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +	  break;
        +	}
        +	continue;
        +      }
        +      if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
        +	if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
        +	    addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 
        +			  fc->ipAddressChoice->u.addressesOrRanges,
        +			  length_from_afi(v3_addr_get_afi(fc))))
        +	  sk_IPAddressFamily_set(child, j, fp);
        +	else
        +	  validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +      }
        +    }
        +  }
        +
        +  /*
        +   * Trust anchor can't inherit.
        +   */
        +  OPENSSL_assert(x != NULL);
        +  if (x->rfc3779_addr != NULL) {
        +    for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
        +      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
        +      if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
        +	  sk_IPAddressFamily_find(child, fp) >= 0)
        +	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +    }
        +  }
        +
        + done:
        +  sk_IPAddressFamily_free(child);
        +  return ret;
        +}
        +
        +#undef validation_err
        +
        +/*
        + * RFC 3779 2.3 path validation -- called from X509_verify_cert().
        + */
        +int v3_addr_validate_path(X509_STORE_CTX *ctx)
        +{
        +  return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
        +}
        +
        +/*
        + * RFC 3779 2.3 path validation of an extension.
        + * Test whether chain covers extension.
        + */
        +int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
        +				  IPAddrBlocks *ext,
        +				  int allow_inheritance)
        +{
        +  if (ext == NULL)
        +    return 1;
        +  if (chain == NULL || sk_X509_num(chain) == 0)
        +    return 0;
        +  if (!allow_inheritance && v3_addr_inherits(ext))
        +    return 0;
        +  return v3_addr_validate_path_internal(NULL, chain, ext);
        +}
        +
        +#endif /* OPENSSL_NO_RFC3779 */
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_akey.c b/vendor/openssl/openssl/crypto/x509v3/v3_akey.c
        new file mode 100644
        index 000000000..c6b68ee22
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_akey.c
        @@ -0,0 +1,208 @@
        +/* v3_akey.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
        +			AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist);
        +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
        +			X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
        +
        +const X509V3_EXT_METHOD v3_akey_id =
        +	{
        +	NID_authority_key_identifier,
        +	X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
        +	0,0,0,0,
        +	0,0,
        +	(X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
        +	(X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
        +	0,0,
        +	NULL
        +	};
        +
        +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
        +	     AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist)
        +{
        +	char *tmp;
        +	if(akeyid->keyid) {
        +		tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length);
        +		X509V3_add_value("keyid", tmp, &extlist);
        +		OPENSSL_free(tmp);
        +	}
        +	if(akeyid->issuer) 
        +		extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
        +	if(akeyid->serial) {
        +		tmp = hex_to_string(akeyid->serial->data,
        +						 akeyid->serial->length);
        +		X509V3_add_value("serial", tmp, &extlist);
        +		OPENSSL_free(tmp);
        +	}
        +	return extlist;
        +}
        +
        +/* Currently two options:
        + * keyid: use the issuers subject keyid, the value 'always' means its is
        + * an error if the issuer certificate doesn't have a key id.
        + * issuer: use the issuers cert issuer and serial number. The default is
        + * to only use this if keyid is not present. With the option 'always'
        + * this is always included.
        + */
        +
        +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
        +	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
        +	{
        +	char keyid=0, issuer=0;
        +	int i;
        +	CONF_VALUE *cnf;
        +	ASN1_OCTET_STRING *ikeyid = NULL;
        +	X509_NAME *isname = NULL;
        +	GENERAL_NAMES * gens = NULL;
        +	GENERAL_NAME *gen = NULL;
        +	ASN1_INTEGER *serial = NULL;
        +	X509_EXTENSION *ext;
        +	X509 *cert;
        +	AUTHORITY_KEYID *akeyid;
        +
        +	for(i = 0; i < sk_CONF_VALUE_num(values); i++)
        +		{
        +		cnf = sk_CONF_VALUE_value(values, i);
        +		if(!strcmp(cnf->name, "keyid"))
        +			{
        +			keyid = 1;
        +			if(cnf->value && !strcmp(cnf->value, "always"))
        +				keyid = 2;
        +			}
        +		else if(!strcmp(cnf->name, "issuer"))
        +			{
        +			issuer = 1;
        +			if(cnf->value && !strcmp(cnf->value, "always"))
        +				issuer = 2;
        +			}
        +		else
        +			{
        +			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNKNOWN_OPTION);
        +			ERR_add_error_data(2, "name=", cnf->name);
        +			return NULL;
        +			}
        +		}
        +
        +	if(!ctx || !ctx->issuer_cert)
        +		{
        +		if(ctx && (ctx->flags==CTX_TEST))
        +			return AUTHORITY_KEYID_new();
        +		X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_NO_ISSUER_CERTIFICATE);
        +		return NULL;
        +		}
        +
        +	cert = ctx->issuer_cert;
        +
        +	if(keyid)
        +		{
        +		i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
        +		if((i >= 0)  && (ext = X509_get_ext(cert, i)))
        +			ikeyid = X509V3_EXT_d2i(ext);
        +		if(keyid==2 && !ikeyid)
        +			{
        +			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
        +			return NULL;
        +			}
        +		}
        +
        +	if((issuer && !ikeyid) || (issuer == 2))
        +		{
        +		isname = X509_NAME_dup(X509_get_issuer_name(cert));
        +		serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
        +		if(!isname || !serial)
        +			{
        +			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
        +			goto err;
        +			}
        +		}
        +
        +	if(!(akeyid = AUTHORITY_KEYID_new())) goto err;
        +
        +	if(isname)
        +		{
        +		if(!(gens = sk_GENERAL_NAME_new_null())
        +			|| !(gen = GENERAL_NAME_new())
        +			|| !sk_GENERAL_NAME_push(gens, gen))
        +			{
        +			X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		gen->type = GEN_DIRNAME;
        +		gen->d.dirn = isname;
        +		}
        +
        +	akeyid->issuer = gens;
        +	akeyid->serial = serial;
        +	akeyid->keyid = ikeyid;
        +
        +	return akeyid;
        +
        + err:
        +	X509_NAME_free(isname);
        +	M_ASN1_INTEGER_free(serial);
        +	M_ASN1_OCTET_STRING_free(ikeyid);
        +	return NULL;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_akeya.c b/vendor/openssl/openssl/crypto/x509v3/v3_akeya.c
        new file mode 100644
        index 000000000..2c50f7360
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_akeya.c
        @@ -0,0 +1,72 @@
        +/* v3_akey_asn1.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +ASN1_SEQUENCE(AUTHORITY_KEYID) = {
        +	ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
        +	ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
        +	ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
        +} ASN1_SEQUENCE_END(AUTHORITY_KEYID)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_alt.c b/vendor/openssl/openssl/crypto/x509v3/v3_alt.c
        new file mode 100644
        index 000000000..d29d94338
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_alt.c
        @@ -0,0 +1,614 @@
        +/* v3_alt.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
        +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
        +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
        +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
        +
        +const X509V3_EXT_METHOD v3_alt[] = {
        +{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
        +0,0,0,0,
        +0,0,
        +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
        +(X509V3_EXT_V2I)v2i_subject_alt,
        +NULL, NULL, NULL},
        +
        +{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
        +0,0,0,0,
        +0,0,
        +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
        +(X509V3_EXT_V2I)v2i_issuer_alt,
        +NULL, NULL, NULL},
        +
        +{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
        +0,0,0,0,
        +0,0,
        +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
        +NULL, NULL, NULL, NULL},
        +};
        +
        +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
        +		GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret)
        +{
        +	int i;
        +	GENERAL_NAME *gen;
        +	for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
        +		gen = sk_GENERAL_NAME_value(gens, i);
        +		ret = i2v_GENERAL_NAME(method, gen, ret);
        +	}
        +	if(!ret) return sk_CONF_VALUE_new_null();
        +	return ret;
        +}
        +
        +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
        +				GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
        +{
        +	unsigned char *p;
        +	char oline[256], htmp[5];
        +	int i;
        +	switch (gen->type)
        +	{
        +		case GEN_OTHERNAME:
        +		X509V3_add_value("othername","<unsupported>", &ret);
        +		break;
        +
        +		case GEN_X400:
        +		X509V3_add_value("X400Name","<unsupported>", &ret);
        +		break;
        +
        +		case GEN_EDIPARTY:
        +		X509V3_add_value("EdiPartyName","<unsupported>", &ret);
        +		break;
        +
        +		case GEN_EMAIL:
        +		X509V3_add_value_uchar("email",gen->d.ia5->data, &ret);
        +		break;
        +
        +		case GEN_DNS:
        +		X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret);
        +		break;
        +
        +		case GEN_URI:
        +		X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret);
        +		break;
        +
        +		case GEN_DIRNAME:
        +		X509_NAME_oneline(gen->d.dirn, oline, 256);
        +		X509V3_add_value("DirName",oline, &ret);
        +		break;
        +
        +		case GEN_IPADD:
        +		p = gen->d.ip->data;
        +		if(gen->d.ip->length == 4)
        +			BIO_snprintf(oline, sizeof oline,
        +				     "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
        +		else if(gen->d.ip->length == 16)
        +			{
        +			oline[0] = 0;
        +			for (i = 0; i < 8; i++)
        +				{
        +				BIO_snprintf(htmp, sizeof htmp,
        +					     "%X", p[0] << 8 | p[1]);
        +				p += 2;
        +				strcat(oline, htmp);
        +				if (i != 7)
        +					strcat(oline, ":");
        +				}
        +			}
        +		else
        +			{
        +			X509V3_add_value("IP Address","<invalid>", &ret);
        +			break;
        +			}
        +		X509V3_add_value("IP Address",oline, &ret);
        +		break;
        +
        +		case GEN_RID:
        +		i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
        +		X509V3_add_value("Registered ID",oline, &ret);
        +		break;
        +	}
        +	return ret;
        +}
        +
        +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
        +{
        +	unsigned char *p;
        +	int i;
        +	switch (gen->type)
        +	{
        +		case GEN_OTHERNAME:
        +		BIO_printf(out, "othername:<unsupported>");
        +		break;
        +
        +		case GEN_X400:
        +		BIO_printf(out, "X400Name:<unsupported>");
        +		break;
        +
        +		case GEN_EDIPARTY:
        +		/* Maybe fix this: it is supported now */
        +		BIO_printf(out, "EdiPartyName:<unsupported>");
        +		break;
        +
        +		case GEN_EMAIL:
        +		BIO_printf(out, "email:%s",gen->d.ia5->data);
        +		break;
        +
        +		case GEN_DNS:
        +		BIO_printf(out, "DNS:%s",gen->d.ia5->data);
        +		break;
        +
        +		case GEN_URI:
        +		BIO_printf(out, "URI:%s",gen->d.ia5->data);
        +		break;
        +
        +		case GEN_DIRNAME:
        +		BIO_printf(out, "DirName: ");
        +		X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
        +		break;
        +
        +		case GEN_IPADD:
        +		p = gen->d.ip->data;
        +		if(gen->d.ip->length == 4)
        +			BIO_printf(out, "IP Address:%d.%d.%d.%d",
        +						p[0], p[1], p[2], p[3]);
        +		else if(gen->d.ip->length == 16)
        +			{
        +			BIO_printf(out, "IP Address");
        +			for (i = 0; i < 8; i++)
        +				{
        +				BIO_printf(out, ":%X", p[0] << 8 | p[1]);
        +				p += 2;
        +				}
        +			BIO_puts(out, "\n");
        +			}
        +		else
        +			{
        +			BIO_printf(out,"IP Address:<invalid>");
        +			break;
        +			}
        +		break;
        +
        +		case GEN_RID:
        +		BIO_printf(out, "Registered ID");
        +		i2a_ASN1_OBJECT(out, gen->d.rid);
        +		break;
        +	}
        +	return 1;
        +}
        +
        +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	GENERAL_NAMES *gens = NULL;
        +	CONF_VALUE *cnf;
        +	int i;
        +	if(!(gens = sk_GENERAL_NAME_new_null())) {
        +		X509V3err(X509V3_F_V2I_ISSUER_ALT,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		if(!name_cmp(cnf->name, "issuer") && cnf->value &&
        +						!strcmp(cnf->value, "copy")) {
        +			if(!copy_issuer(ctx, gens)) goto err;
        +		} else {
        +			GENERAL_NAME *gen;
        +			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
        +								 goto err; 
        +			sk_GENERAL_NAME_push(gens, gen);
        +		}
        +	}
        +	return gens;
        +	err:
        +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
        +	return NULL;
        +}
        +
        +/* Append subject altname of issuer to issuer alt name of subject */
        +
        +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
        +{
        +	GENERAL_NAMES *ialt;
        +	GENERAL_NAME *gen;
        +	X509_EXTENSION *ext;
        +	int i;
        +	if(ctx && (ctx->flags == CTX_TEST)) return 1;
        +	if(!ctx || !ctx->issuer_cert) {
        +		X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS);
        +		goto err;
        +	}
        +        i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
        +	if(i < 0) return 1;
        +        if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
        +                        !(ialt = X509V3_EXT_d2i(ext)) ) {
        +		X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR);
        +		goto err;
        +	}
        +
        +	for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
        +		gen = sk_GENERAL_NAME_value(ialt, i);
        +		if(!sk_GENERAL_NAME_push(gens, gen)) {
        +			X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +	}
        +	sk_GENERAL_NAME_free(ialt);
        +
        +	return 1;
        +		
        +	err:
        +	return 0;
        +	
        +}
        +
        +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	GENERAL_NAMES *gens = NULL;
        +	CONF_VALUE *cnf;
        +	int i;
        +	if(!(gens = sk_GENERAL_NAME_new_null())) {
        +		X509V3err(X509V3_F_V2I_SUBJECT_ALT,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		if(!name_cmp(cnf->name, "email") && cnf->value &&
        +						!strcmp(cnf->value, "copy")) {
        +			if(!copy_email(ctx, gens, 0)) goto err;
        +		} else if(!name_cmp(cnf->name, "email") && cnf->value &&
        +						!strcmp(cnf->value, "move")) {
        +			if(!copy_email(ctx, gens, 1)) goto err;
        +		} else {
        +			GENERAL_NAME *gen;
        +			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
        +								 goto err; 
        +			sk_GENERAL_NAME_push(gens, gen);
        +		}
        +	}
        +	return gens;
        +	err:
        +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
        +	return NULL;
        +}
        +
        +/* Copy any email addresses in a certificate or request to 
        + * GENERAL_NAMES
        + */
        +
        +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
        +{
        +	X509_NAME *nm;
        +	ASN1_IA5STRING *email = NULL;
        +	X509_NAME_ENTRY *ne;
        +	GENERAL_NAME *gen = NULL;
        +	int i;
        +	if(ctx != NULL && ctx->flags == CTX_TEST)
        +		return 1;
        +	if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
        +		X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS);
        +		goto err;
        +	}
        +	/* Find the subject name */
        +	if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert);
        +	else nm = X509_REQ_get_subject_name(ctx->subject_req);
        +
        +	/* Now add any email address(es) to STACK */
        +	i = -1;
        +	while((i = X509_NAME_get_index_by_NID(nm,
        +					 NID_pkcs9_emailAddress, i)) >= 0) {
        +		ne = X509_NAME_get_entry(nm, i);
        +		email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
        +                if (move_p)
        +                        {
        +                        X509_NAME_delete_entry(nm, i);
        +			X509_NAME_ENTRY_free(ne);
        +                        i--;
        +                        }
        +		if(!email || !(gen = GENERAL_NAME_new())) {
        +			X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		gen->d.ia5 = email;
        +		email = NULL;
        +		gen->type = GEN_EMAIL;
        +		if(!sk_GENERAL_NAME_push(gens, gen)) {
        +			X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		gen = NULL;
        +	}
        +
        +	
        +	return 1;
        +		
        +	err:
        +	GENERAL_NAME_free(gen);
        +	M_ASN1_IA5STRING_free(email);
        +	return 0;
        +	
        +}
        +
        +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	GENERAL_NAME *gen;
        +	GENERAL_NAMES *gens = NULL;
        +	CONF_VALUE *cnf;
        +	int i;
        +	if(!(gens = sk_GENERAL_NAME_new_null())) {
        +		X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 
        +		sk_GENERAL_NAME_push(gens, gen);
        +	}
        +	return gens;
        +	err:
        +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
        +	return NULL;
        +}
        +
        +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +			       CONF_VALUE *cnf)
        +	{
        +	return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
        +	}
        +
        +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
        +			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +			       int gen_type, char *value, int is_nc)
        +	{
        +	char is_string = 0;
        +	GENERAL_NAME *gen = NULL;
        +
        +	if(!value)
        +		{
        +		X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
        +		return NULL;
        +		}
        +
        +	if (out)
        +		gen = out;
        +	else
        +		{
        +		gen = GENERAL_NAME_new();
        +		if(gen == NULL)
        +			{
        +			X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +			}
        +		}
        +
        +	switch (gen_type)
        +		{
        +		case GEN_URI:
        +		case GEN_EMAIL:
        +		case GEN_DNS:
        +		is_string = 1;
        +		break;
        +		
        +		case GEN_RID:
        +		{
        +		ASN1_OBJECT *obj;
        +		if(!(obj = OBJ_txt2obj(value,0)))
        +			{
        +			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT);
        +			ERR_add_error_data(2, "value=", value);
        +			goto err;
        +			}
        +		gen->d.rid = obj;
        +		}
        +		break;
        +
        +		case GEN_IPADD:
        +		if (is_nc)
        +			gen->d.ip = a2i_IPADDRESS_NC(value);
        +		else
        +			gen->d.ip = a2i_IPADDRESS(value);
        +		if(gen->d.ip == NULL)
        +			{
        +			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS);
        +			ERR_add_error_data(2, "value=", value);
        +			goto err;
        +			}
        +		break;
        +
        +		case GEN_DIRNAME:
        +		if (!do_dirname(gen, value, ctx))
        +			{
        +			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR);
        +			goto err;
        +			}
        +		break;
        +
        +		case GEN_OTHERNAME:
        +		if (!do_othername(gen, value, ctx))
        +			{
        +			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR);
        +			goto err;
        +			}
        +		break;
        +		default:
        +		X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE);
        +		goto err;
        +		}
        +
        +	if(is_string)
        +		{
        +		if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
        +			      !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
        +					       strlen(value)))
        +			{
        +			X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +
        +	gen->type = gen_type;
        +
        +	return gen;
        +
        +	err:
        +	if (!out)
        +		GENERAL_NAME_free(gen);
        +	return NULL;
        +	}
        +
        +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
        +				  const X509V3_EXT_METHOD *method,
        +				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
        +	{
        +	int type;
        +
        +	char *name, *value;
        +
        +	name = cnf->name;
        +	value = cnf->value;
        +
        +	if(!value)
        +		{
        +		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE);
        +		return NULL;
        +		}
        +
        +	if(!name_cmp(name, "email"))
        +		type = GEN_EMAIL;
        +	else if(!name_cmp(name, "URI"))
        +		type = GEN_URI;
        +	else if(!name_cmp(name, "DNS"))
        +		type = GEN_DNS;
        +	else if(!name_cmp(name, "RID"))
        +		type = GEN_RID;
        +	else if(!name_cmp(name, "IP"))
        +		type = GEN_IPADD;
        +	else if(!name_cmp(name, "dirName"))
        +		type = GEN_DIRNAME;
        +	else if(!name_cmp(name, "otherName"))
        +		type = GEN_OTHERNAME;
        +	else
        +		{
        +		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
        +		ERR_add_error_data(2, "name=", name);
        +		return NULL;
        +		}
        +
        +	return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
        +
        +	}
        +
        +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
        +	{
        +	char *objtmp = NULL, *p;
        +	int objlen;
        +	if (!(p = strchr(value, ';')))
        +		return 0;
        +	if (!(gen->d.otherName = OTHERNAME_new()))
        +		return 0;
        +	/* Free this up because we will overwrite it.
        +	 * no need to free type_id because it is static
        +	 */
        +	ASN1_TYPE_free(gen->d.otherName->value);
        +	if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
        +		return 0;
        +	objlen = p - value;
        +	objtmp = OPENSSL_malloc(objlen + 1);
        +	strncpy(objtmp, value, objlen);
        +	objtmp[objlen] = 0;
        +	gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
        +	OPENSSL_free(objtmp);	
        +	if (!gen->d.otherName->type_id)
        +		return 0;
        +	return 1;
        +	}
        +
        +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
        +	{
        +	int ret;
        +	STACK_OF(CONF_VALUE) *sk;
        +	X509_NAME *nm;
        +	if (!(nm = X509_NAME_new()))
        +		return 0;
        +	sk = X509V3_get_section(ctx, value);
        +	if (!sk)
        +		{
        +		X509V3err(X509V3_F_DO_DIRNAME,X509V3_R_SECTION_NOT_FOUND);
        +		ERR_add_error_data(2, "section=", value);
        +		X509_NAME_free(nm);
        +		return 0;
        +		}
        +	/* FIXME: should allow other character types... */
        +	ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
        +	if (!ret)
        +		X509_NAME_free(nm);
        +	gen->d.dirn = nm;
        +	X509V3_section_free(ctx, sk);
        +		
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_asid.c b/vendor/openssl/openssl/crypto/x509v3/v3_asid.c
        new file mode 100644
        index 000000000..1587e8ed7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_asid.c
        @@ -0,0 +1,890 @@
        +/*
        + * Contributed to the OpenSSL Project by the American Registry for
        + * Internet Numbers ("ARIN").
        + */
        +/* ====================================================================
        + * Copyright (c) 2006 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).
        + */
        +
        +/*
        + * Implementation of RFC 3779 section 3.2.
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/x509.h>
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_RFC3779
        +
        +/*
        + * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
        + */
        +
        +ASN1_SEQUENCE(ASRange) = {
        +  ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
        +  ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(ASRange)
        +
        +ASN1_CHOICE(ASIdOrRange) = {
        +  ASN1_SIMPLE(ASIdOrRange, u.id,    ASN1_INTEGER),
        +  ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
        +} ASN1_CHOICE_END(ASIdOrRange)
        +
        +ASN1_CHOICE(ASIdentifierChoice) = {
        +  ASN1_SIMPLE(ASIdentifierChoice,      u.inherit,       ASN1_NULL),
        +  ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
        +} ASN1_CHOICE_END(ASIdentifierChoice)
        +
        +ASN1_SEQUENCE(ASIdentifiers) = {
        +  ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
        +  ASN1_EXP_OPT(ASIdentifiers, rdi,   ASIdentifierChoice, 1)
        +} ASN1_SEQUENCE_END(ASIdentifiers)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(ASRange)
        +IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
        +IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
        +IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
        +
        +/*
        + * i2r method for an ASIdentifierChoice.
        + */
        +static int i2r_ASIdentifierChoice(BIO *out,
        +				  ASIdentifierChoice *choice,
        +				  int indent,
        +				  const char *msg)
        +{
        +  int i;
        +  char *s;
        +  if (choice == NULL)
        +    return 1;
        +  BIO_printf(out, "%*s%s:\n", indent, "", msg);
        +  switch (choice->type) {
        +  case ASIdentifierChoice_inherit:
        +    BIO_printf(out, "%*sinherit\n", indent + 2, "");
        +    break;
        +  case ASIdentifierChoice_asIdsOrRanges:
        +    for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
        +      ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
        +      switch (aor->type) {
        +      case ASIdOrRange_id:
        +	if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
        +	  return 0;
        +	BIO_printf(out, "%*s%s\n", indent + 2, "", s);
        +	OPENSSL_free(s);
        +	break;
        +      case ASIdOrRange_range:
        +	if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
        +	  return 0;
        +	BIO_printf(out, "%*s%s-", indent + 2, "", s);
        +	OPENSSL_free(s);
        +	if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
        +	  return 0;
        +	BIO_printf(out, "%s\n", s);
        +	OPENSSL_free(s);
        +	break;
        +      default:
        +	return 0;
        +      }
        +    }
        +    break;
        +  default:
        +    return 0;
        +  }
        +  return 1;
        +}
        +
        +/*
        + * i2r method for an ASIdentifier extension.
        + */
        +static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
        +			     void *ext,
        +			     BIO *out,
        +			     int indent)
        +{
        +  ASIdentifiers *asid = ext;
        +  return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
        +				 "Autonomous System Numbers") &&
        +	  i2r_ASIdentifierChoice(out, asid->rdi, indent,
        +				 "Routing Domain Identifiers"));
        +}
        +
        +/*
        + * Sort comparision function for a sequence of ASIdOrRange elements.
        + */
        +static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
        +			   const ASIdOrRange * const *b_)
        +{
        +  const ASIdOrRange *a = *a_, *b = *b_;
        +
        +  OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
        +	 (a->type == ASIdOrRange_range && a->u.range != NULL &&
        +	  a->u.range->min != NULL && a->u.range->max != NULL));
        +
        +  OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
        +	 (b->type == ASIdOrRange_range && b->u.range != NULL &&
        +	  b->u.range->min != NULL && b->u.range->max != NULL));
        +
        +  if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
        +    return ASN1_INTEGER_cmp(a->u.id, b->u.id);
        +
        +  if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
        +    int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
        +    return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max);
        +  }
        +
        +  if (a->type == ASIdOrRange_id)
        +    return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
        +  else
        +    return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
        +}
        +
        +/*
        + * Add an inherit element.
        + */
        +int v3_asid_add_inherit(ASIdentifiers *asid, int which)
        +{
        +  ASIdentifierChoice **choice;
        +  if (asid == NULL)
        +    return 0;
        +  switch (which) {
        +  case V3_ASID_ASNUM:
        +    choice = &asid->asnum;
        +    break;
        +  case V3_ASID_RDI:
        +    choice = &asid->rdi;
        +    break;
        +  default:
        +    return 0;
        +  }
        +  if (*choice == NULL) {
        +    if ((*choice = ASIdentifierChoice_new()) == NULL)
        +      return 0;
        +    OPENSSL_assert((*choice)->u.inherit == NULL);
        +    if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
        +      return 0;
        +    (*choice)->type = ASIdentifierChoice_inherit;
        +  }
        +  return (*choice)->type == ASIdentifierChoice_inherit;
        +}
        +
        +/*
        + * Add an ID or range to an ASIdentifierChoice.
        + */
        +int v3_asid_add_id_or_range(ASIdentifiers *asid,
        +			    int which,
        +			    ASN1_INTEGER *min,
        +			    ASN1_INTEGER *max)
        +{
        +  ASIdentifierChoice **choice;
        +  ASIdOrRange *aor;
        +  if (asid == NULL)
        +    return 0;
        +  switch (which) {
        +  case V3_ASID_ASNUM:
        +    choice = &asid->asnum;
        +    break;
        +  case V3_ASID_RDI:
        +    choice = &asid->rdi;
        +    break;
        +  default:
        +    return 0;
        +  }
        +  if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
        +    return 0;
        +  if (*choice == NULL) {
        +    if ((*choice = ASIdentifierChoice_new()) == NULL)
        +      return 0;
        +    OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
        +    (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
        +    if ((*choice)->u.asIdsOrRanges == NULL)
        +      return 0;
        +    (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
        +  }
        +  if ((aor = ASIdOrRange_new()) == NULL)
        +    return 0;
        +  if (max == NULL) {
        +    aor->type = ASIdOrRange_id;
        +    aor->u.id = min;
        +  } else {
        +    aor->type = ASIdOrRange_range;
        +    if ((aor->u.range = ASRange_new()) == NULL)
        +      goto err;
        +    ASN1_INTEGER_free(aor->u.range->min);
        +    aor->u.range->min = min;
        +    ASN1_INTEGER_free(aor->u.range->max);
        +    aor->u.range->max = max;
        +  }
        +  if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
        +    goto err;
        +  return 1;
        +
        + err:
        +  ASIdOrRange_free(aor);
        +  return 0;
        +}
        +
        +/*
        + * Extract min and max values from an ASIdOrRange.
        + */
        +static void extract_min_max(ASIdOrRange *aor,
        +			    ASN1_INTEGER **min,
        +			    ASN1_INTEGER **max)
        +{
        +  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
        +  switch (aor->type) {
        +  case ASIdOrRange_id:
        +    *min = aor->u.id;
        +    *max = aor->u.id;
        +    return;
        +  case ASIdOrRange_range:
        +    *min = aor->u.range->min;
        +    *max = aor->u.range->max;
        +    return;
        +  }
        +}
        +
        +/*
        + * Check whether an ASIdentifierChoice is in canonical form.
        + */
        +static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
        +{
        +  ASN1_INTEGER *a_max_plus_one = NULL;
        +  BIGNUM *bn = NULL;
        +  int i, ret = 0;
        +
        +  /*
        +   * Empty element or inheritance is canonical.
        +   */
        +  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
        +    return 1;
        +
        +  /*
        +   * If not a list, or if empty list, it's broken.
        +   */
        +  if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
        +      sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
        +    return 0;
        +
        +  /*
        +   * It's a list, check it.
        +   */
        +  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
        +    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
        +    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
        +    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
        +
        +    extract_min_max(a, &a_min, &a_max);
        +    extract_min_max(b, &b_min, &b_max);
        +
        +    /*
        +     * Punt misordered list, overlapping start, or inverted range.
        +     */
        +    if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
        +	ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
        +	ASN1_INTEGER_cmp(b_min, b_max) > 0)
        +      goto done;
        +
        +    /*
        +     * Calculate a_max + 1 to check for adjacency.
        +     */
        +    if ((bn == NULL && (bn = BN_new()) == NULL) ||
        +	ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
        +	!BN_add_word(bn, 1) ||
        +	(a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
        +      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
        +		ERR_R_MALLOC_FAILURE);
        +      goto done;
        +    }
        +    
        +    /*
        +     * Punt if adjacent or overlapping.
        +     */
        +    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
        +      goto done;
        +  }
        +
        +  /*
        +   * Check for inverted range.
        +   */
        +  i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
        +  {
        +    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
        +    ASN1_INTEGER *a_min, *a_max;
        +    if (a != NULL && a->type == ASIdOrRange_range) {
        +      extract_min_max(a, &a_min, &a_max);
        +      if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
        +	goto done;
        +    }
        +  }
        +
        +  ret = 1;
        +
        + done:
        +  ASN1_INTEGER_free(a_max_plus_one);
        +  BN_free(bn);
        +  return ret;
        +}
        +
        +/*
        + * Check whether an ASIdentifier extension is in canonical form.
        + */
        +int v3_asid_is_canonical(ASIdentifiers *asid)
        +{
        +  return (asid == NULL ||
        +	  (ASIdentifierChoice_is_canonical(asid->asnum) &&
        +	   ASIdentifierChoice_is_canonical(asid->rdi)));
        +}
        +
        +/*
        + * Whack an ASIdentifierChoice into canonical form.
        + */
        +static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
        +{
        +  ASN1_INTEGER *a_max_plus_one = NULL;
        +  BIGNUM *bn = NULL;
        +  int i, ret = 0;
        +
        +  /*
        +   * Nothing to do for empty element or inheritance.
        +   */
        +  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
        +    return 1;
        +
        +  /*
        +   * If not a list, or if empty list, it's broken.
        +   */
        +  if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
        +      sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
        +    X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
        +	      X509V3_R_EXTENSION_VALUE_ERROR);
        +    return 0;
        +  }
        +
        +  /*
        +   * We have a non-empty list.  Sort it.
        +   */
        +  sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
        +
        +  /*
        +   * Now check for errors and suboptimal encoding, rejecting the
        +   * former and fixing the latter.
        +   */
        +  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
        +    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
        +    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
        +    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
        +
        +    extract_min_max(a, &a_min, &a_max);
        +    extract_min_max(b, &b_min, &b_max);
        +
        +    /*
        +     * Make sure we're properly sorted (paranoia).
        +     */
        +    OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
        +
        +    /*
        +     * Punt inverted ranges.
        +     */
        +    if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
        +	ASN1_INTEGER_cmp(b_min, b_max) > 0)
        +      goto done;
        +
        +    /*
        +     * Check for overlaps.
        +     */
        +    if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
        +      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
        +		X509V3_R_EXTENSION_VALUE_ERROR);
        +      goto done;
        +    }
        +
        +    /*
        +     * Calculate a_max + 1 to check for adjacency.
        +     */
        +    if ((bn == NULL && (bn = BN_new()) == NULL) ||
        +	ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
        +	!BN_add_word(bn, 1) ||
        +	(a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
        +      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
        +      goto done;
        +    }
        +    
        +    /*
        +     * If a and b are adjacent, merge them.
        +     */
        +    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
        +      ASRange *r;
        +      switch (a->type) {
        +      case ASIdOrRange_id:
        +	if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
        +	  X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
        +		    ERR_R_MALLOC_FAILURE);
        +	  goto done;
        +	}
        +	r->min = a_min;
        +	r->max = b_max;
        +	a->type = ASIdOrRange_range;
        +	a->u.range = r;
        +	break;
        +      case ASIdOrRange_range:
        +	ASN1_INTEGER_free(a->u.range->max);
        +	a->u.range->max = b_max;
        +	break;
        +      }
        +      switch (b->type) {
        +      case ASIdOrRange_id:
        +	b->u.id = NULL;
        +	break;
        +      case ASIdOrRange_range:
        +	b->u.range->max = NULL;
        +	break;
        +      }
        +      ASIdOrRange_free(b);
        +      (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
        +      i--;
        +      continue;
        +    }
        +  }
        +
        +  /*
        +   * Check for final inverted range.
        +   */
        +  i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
        +  {
        +    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
        +    ASN1_INTEGER *a_min, *a_max;
        +    if (a != NULL && a->type == ASIdOrRange_range) {
        +      extract_min_max(a, &a_min, &a_max);
        +      if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
        +	goto done;
        +    }
        +  }
        +
        +  OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
        +
        +  ret = 1;
        +
        + done:
        +  ASN1_INTEGER_free(a_max_plus_one);
        +  BN_free(bn);
        +  return ret;
        +}
        +
        +/*
        + * Whack an ASIdentifier extension into canonical form.
        + */
        +int v3_asid_canonize(ASIdentifiers *asid)
        +{
        +  return (asid == NULL ||
        +	  (ASIdentifierChoice_canonize(asid->asnum) &&
        +	   ASIdentifierChoice_canonize(asid->rdi)));
        +}
        +
        +/*
        + * v2i method for an ASIdentifier extension.
        + */
        +static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
        +			       struct v3_ext_ctx *ctx,
        +			       STACK_OF(CONF_VALUE) *values)
        +{
        +  ASN1_INTEGER *min = NULL, *max = NULL;
        +  ASIdentifiers *asid = NULL;
        +  int i;
        +
        +  if ((asid = ASIdentifiers_new()) == NULL) {
        +    X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
        +    return NULL;
        +  }
        +
        +  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
        +    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
        +    int i1, i2, i3, is_range, which;
        +
        +    /*
        +     * Figure out whether this is an AS or an RDI.
        +     */
        +    if (       !name_cmp(val->name, "AS")) {
        +      which = V3_ASID_ASNUM;
        +    } else if (!name_cmp(val->name, "RDI")) {
        +      which = V3_ASID_RDI;
        +    } else {
        +      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR);
        +      X509V3_conf_err(val);
        +      goto err;
        +    }
        +
        +    /*
        +     * Handle inheritance.
        +     */
        +    if (!strcmp(val->value, "inherit")) {
        +      if (v3_asid_add_inherit(asid, which))
        +	continue;
        +      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE);
        +      X509V3_conf_err(val);
        +      goto err;
        +    }
        +
        +    /*
        +     * Number, range, or mistake, pick it apart and figure out which.
        +     */
        +    i1 = strspn(val->value, "0123456789");
        +    if (val->value[i1] == '\0') {
        +      is_range = 0;
        +    } else {
        +      is_range = 1;
        +      i2 = i1 + strspn(val->value + i1, " \t");
        +      if (val->value[i2] != '-') {
        +	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +      i2++;
        +      i2 = i2 + strspn(val->value + i2, " \t");
        +      i3 = i2 + strspn(val->value + i2, "0123456789");
        +      if (val->value[i3] != '\0') {
        +	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE);
        +	X509V3_conf_err(val);
        +	goto err;
        +      }
        +    }
        +
        +    /*
        +     * Syntax is ok, read and add it.
        +     */
        +    if (!is_range) {
        +      if (!X509V3_get_value_int(val, &min)) {
        +	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +      }
        +    } else {
        +      char *s = BUF_strdup(val->value);
        +      if (s == NULL) {
        +	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +      }
        +      s[i1] = '\0';
        +      min = s2i_ASN1_INTEGER(NULL, s);
        +      max = s2i_ASN1_INTEGER(NULL, s + i2);
        +      OPENSSL_free(s);
        +      if (min == NULL || max == NULL) {
        +	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +      }
        +      if (ASN1_INTEGER_cmp(min, max) > 0) {
        +	X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR);
        +	goto err;
        +      }
        +    }
        +    if (!v3_asid_add_id_or_range(asid, which, min, max)) {
        +      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
        +      goto err;
        +    }
        +    min = max = NULL;
        +  }
        +
        +  /*
        +   * Canonize the result, then we're done.
        +   */
        +  if (!v3_asid_canonize(asid))
        +    goto err;
        +  return asid;
        +
        + err:
        +  ASIdentifiers_free(asid);
        +  ASN1_INTEGER_free(min);
        +  ASN1_INTEGER_free(max);
        +  return NULL;
        +}
        +
        +/*
        + * OpenSSL dispatch.
        + */
        +const X509V3_EXT_METHOD v3_asid = {
        +  NID_sbgp_autonomousSysNum,	/* nid */
        +  0,				/* flags */
        +  ASN1_ITEM_ref(ASIdentifiers),	/* template */
        +  0, 0, 0, 0,			/* old functions, ignored */
        +  0,				/* i2s */
        +  0,				/* s2i */
        +  0,				/* i2v */
        +  v2i_ASIdentifiers,		/* v2i */
        +  i2r_ASIdentifiers,		/* i2r */
        +  0,				/* r2i */
        +  NULL				/* extension-specific data */
        +};
        +
        +/*
        + * Figure out whether extension uses inheritance.
        + */
        +int v3_asid_inherits(ASIdentifiers *asid)
        +{
        +  return (asid != NULL &&
        +	  ((asid->asnum != NULL &&
        +	    asid->asnum->type == ASIdentifierChoice_inherit) ||
        +	   (asid->rdi != NULL &&
        +	    asid->rdi->type == ASIdentifierChoice_inherit)));
        +}
        +
        +/*
        + * Figure out whether parent contains child.
        + */
        +static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
        +{
        +  ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
        +  int p, c;
        +
        +  if (child == NULL || parent == child)
        +    return 1;
        +  if (parent == NULL)
        +    return 0;
        +
        +  p = 0;
        +  for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
        +    extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
        +    for (;; p++) {
        +      if (p >= sk_ASIdOrRange_num(parent))
        +	return 0;
        +      extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
        +      if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
        +	continue;
        +      if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
        +	return 0;
        +      break;
        +    }
        +  }
        +
        +  return 1;
        +}
        +
        +/*
        + * Test whether a is a subet of b.
        + */
        +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
        +{
        +  return (a == NULL ||
        +	  a == b ||
        +	  (b != NULL &&
        +	   !v3_asid_inherits(a) &&
        +	   !v3_asid_inherits(b) &&
        +	   asid_contains(b->asnum->u.asIdsOrRanges,
        +			 a->asnum->u.asIdsOrRanges) &&
        +	   asid_contains(b->rdi->u.asIdsOrRanges,
        +			 a->rdi->u.asIdsOrRanges)));
        +}
        +
        +/*
        + * Validation error handling via callback.
        + */
        +#define validation_err(_err_)		\
        +  do {					\
        +    if (ctx != NULL) {			\
        +      ctx->error = _err_;		\
        +      ctx->error_depth = i;		\
        +      ctx->current_cert = x;		\
        +      ret = ctx->verify_cb(0, ctx);	\
        +    } else {				\
        +      ret = 0;				\
        +    }					\
        +    if (!ret)				\
        +      goto done;			\
        +  } while (0)
        +
        +/*
        + * Core code for RFC 3779 3.3 path validation.
        + */
        +static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
        +					  STACK_OF(X509) *chain,
        +					  ASIdentifiers *ext)
        +{
        +  ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
        +  int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
        +  X509 *x;
        +
        +  OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
        +  OPENSSL_assert(ctx != NULL || ext != NULL);
        +  OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
        +
        +  /*
        +   * Figure out where to start.  If we don't have an extension to
        +   * check, we're done.  Otherwise, check canonical form and
        +   * set up for walking up the chain.
        +   */
        +  if (ext != NULL) {
        +    i = -1;
        +    x = NULL;
        +  } else {
        +    i = 0;
        +    x = sk_X509_value(chain, i);
        +    OPENSSL_assert(x != NULL);
        +    if ((ext = x->rfc3779_asid) == NULL)
        +      goto done;
        +  }
        +  if (!v3_asid_is_canonical(ext))
        +    validation_err(X509_V_ERR_INVALID_EXTENSION);
        +  if (ext->asnum != NULL)  {
        +    switch (ext->asnum->type) {
        +    case ASIdentifierChoice_inherit:
        +      inherit_as = 1;
        +      break;
        +    case ASIdentifierChoice_asIdsOrRanges:
        +      child_as = ext->asnum->u.asIdsOrRanges;
        +      break;
        +    }
        +  }
        +  if (ext->rdi != NULL) {
        +    switch (ext->rdi->type) {
        +    case ASIdentifierChoice_inherit:
        +      inherit_rdi = 1;
        +      break;
        +    case ASIdentifierChoice_asIdsOrRanges:
        +      child_rdi = ext->rdi->u.asIdsOrRanges;
        +      break;
        +    }
        +  }
        +
        +  /*
        +   * Now walk up the chain.  Extensions must be in canonical form, no
        +   * cert may list resources that its parent doesn't list.
        +   */
        +  for (i++; i < sk_X509_num(chain); i++) {
        +    x = sk_X509_value(chain, i);
        +    OPENSSL_assert(x != NULL);
        +    if (x->rfc3779_asid == NULL) {
        +      if (child_as != NULL || child_rdi != NULL)
        +	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +      continue;
        +    }
        +    if (!v3_asid_is_canonical(x->rfc3779_asid))
        +      validation_err(X509_V_ERR_INVALID_EXTENSION);
        +    if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
        +      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +      child_as = NULL;
        +      inherit_as = 0;
        +    }
        +    if (x->rfc3779_asid->asnum != NULL &&
        +	x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
        +      if (inherit_as ||
        +	  asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) {
        +	child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
        +	inherit_as = 0;
        +      } else {
        +	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +      }
        +    }
        +    if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
        +      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +      child_rdi = NULL;
        +      inherit_rdi = 0;
        +    }
        +    if (x->rfc3779_asid->rdi != NULL &&
        +	x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
        +      if (inherit_rdi ||
        +	  asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) {
        +	child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
        +	inherit_rdi = 0;
        +      } else {
        +	validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +      }
        +    }
        +  }
        +
        +  /*
        +   * Trust anchor can't inherit.
        +   */
        +  OPENSSL_assert(x != NULL);
        +  if (x->rfc3779_asid != NULL) {
        +    if (x->rfc3779_asid->asnum != NULL &&
        +	x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
        +      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +    if (x->rfc3779_asid->rdi != NULL &&
        +	x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
        +      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        +  }
        +
        + done:
        +  return ret;
        +}
        +
        +#undef validation_err
        +
        +/*
        + * RFC 3779 3.3 path validation -- called from X509_verify_cert().
        + */
        +int v3_asid_validate_path(X509_STORE_CTX *ctx)
        +{
        +  return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
        +}
        +
        +/*
        + * RFC 3779 3.3 path validation of an extension.
        + * Test whether chain covers extension.
        + */
        +int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
        +				  ASIdentifiers *ext,
        +				  int allow_inheritance)
        +{
        +  if (ext == NULL)
        +    return 1;
        +  if (chain == NULL || sk_X509_num(chain) == 0)
        +    return 0;
        +  if (!allow_inheritance && v3_asid_inherits(ext))
        +    return 0;
        +  return v3_asid_validate_path_internal(NULL, chain, ext);
        +}
        +
        +#endif /* OPENSSL_NO_RFC3779 */
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_bcons.c b/vendor/openssl/openssl/crypto/x509v3/v3_bcons.c
        new file mode 100644
        index 000000000..82aa488f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_bcons.c
        @@ -0,0 +1,124 @@
        +/* v3_bcons.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
        +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
        +
        +const X509V3_EXT_METHOD v3_bcons = {
        +NID_basic_constraints, 0,
        +ASN1_ITEM_ref(BASIC_CONSTRAINTS),
        +0,0,0,0,
        +0,0,
        +(X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS,
        +(X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
        +NULL,NULL,
        +NULL
        +};
        +
        +ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
        +	ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
        +	ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
        +
        +
        +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
        +	     BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist)
        +{
        +	X509V3_add_value_bool("CA", bcons->ca, &extlist);
        +	X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
        +	return extlist;
        +}
        +
        +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
        +	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
        +{
        +	BASIC_CONSTRAINTS *bcons=NULL;
        +	CONF_VALUE *val;
        +	int i;
        +	if(!(bcons = BASIC_CONSTRAINTS_new())) {
        +		X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
        +		val = sk_CONF_VALUE_value(values, i);
        +		if(!strcmp(val->name, "CA")) {
        +			if(!X509V3_get_value_bool(val, &bcons->ca)) goto err;
        +		} else if(!strcmp(val->name, "pathlen")) {
        +			if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
        +		} else {
        +			X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
        +			X509V3_conf_err(val);
        +			goto err;
        +		}
        +	}
        +	return bcons;
        +	err:
        +	BASIC_CONSTRAINTS_free(bcons);
        +	return NULL;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_bitst.c b/vendor/openssl/openssl/crypto/x509v3/v3_bitst.c
        new file mode 100644
        index 000000000..058d0d4dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_bitst.c
        @@ -0,0 +1,141 @@
        +/* v3_bitst.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static BIT_STRING_BITNAME ns_cert_type_table[] = {
        +{0, "SSL Client", "client"},
        +{1, "SSL Server", "server"},
        +{2, "S/MIME", "email"},
        +{3, "Object Signing", "objsign"},
        +{4, "Unused", "reserved"},
        +{5, "SSL CA", "sslCA"},
        +{6, "S/MIME CA", "emailCA"},
        +{7, "Object Signing CA", "objCA"},
        +{-1, NULL, NULL}
        +};
        +
        +static BIT_STRING_BITNAME key_usage_type_table[] = {
        +{0, "Digital Signature", "digitalSignature"},
        +{1, "Non Repudiation", "nonRepudiation"},
        +{2, "Key Encipherment", "keyEncipherment"},
        +{3, "Data Encipherment", "dataEncipherment"},
        +{4, "Key Agreement", "keyAgreement"},
        +{5, "Certificate Sign", "keyCertSign"},
        +{6, "CRL Sign", "cRLSign"},
        +{7, "Encipher Only", "encipherOnly"},
        +{8, "Decipher Only", "decipherOnly"},
        +{-1, NULL, NULL}
        +};
        +
        +
        +
        +const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
        +const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
        +
        +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
        +	     ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
        +{
        +	BIT_STRING_BITNAME *bnam;
        +	for(bnam =method->usr_data; bnam->lname; bnam++) {
        +		if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) 
        +			X509V3_add_value(bnam->lname, NULL, &ret);
        +	}
        +	return ret;
        +}
        +	
        +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
        +	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	CONF_VALUE *val;
        +	ASN1_BIT_STRING *bs;
        +	int i;
        +	BIT_STRING_BITNAME *bnam;
        +	if(!(bs = M_ASN1_BIT_STRING_new())) {
        +		X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		val = sk_CONF_VALUE_value(nval, i);
        +		for(bnam = method->usr_data; bnam->lname; bnam++) {
        +			if(!strcmp(bnam->sname, val->name) ||
        +				!strcmp(bnam->lname, val->name) ) {
        +				if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
        +					X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
        +						ERR_R_MALLOC_FAILURE);
        +					M_ASN1_BIT_STRING_free(bs);
        +					return NULL;
        +				}
        +				break;
        +			}
        +		}
        +		if(!bnam->lname) {
        +			X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
        +					X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
        +			X509V3_conf_err(val);
        +			M_ASN1_BIT_STRING_free(bs);
        +			return NULL;
        +		}
        +	}
        +	return bs;
        +}
        +	
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_conf.c b/vendor/openssl/openssl/crypto/x509v3/v3_conf.c
        new file mode 100644
        index 000000000..6730f9a6e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_conf.c
        @@ -0,0 +1,525 @@
        +/* v3_conf.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* extension creation utilities */
        +
        +
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +static int v3_check_critical(char **value);
        +static int v3_check_generic(char **value);
        +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
        +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
        +static char *conf_lhash_get_string(void *db, char *section, char *value);
        +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
        +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
        +				  int crit, void *ext_struc);
        +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
        +/* CONF *conf:  Config file    */
        +/* char *name:  Name    */
        +/* char *value:  Value    */
        +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
        +				 char *value)
        +	{
        +	int crit;
        +	int ext_type;
        +	X509_EXTENSION *ret;
        +	crit = v3_check_critical(&value);
        +	if ((ext_type = v3_check_generic(&value))) 
        +		return v3_generic_extension(name, value, crit, ext_type, ctx);
        +	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
        +	if (!ret)
        +		{
        +		X509V3err(X509V3_F_X509V3_EXT_NCONF,X509V3_R_ERROR_IN_EXTENSION);
        +		ERR_add_error_data(4,"name=", name, ", value=", value);
        +		}
        +	return ret;
        +	}
        +
        +/* CONF *conf:  Config file    */
        +/* char *value:  Value    */
        +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
        +				     char *value)
        +	{
        +	int crit;
        +	int ext_type;
        +	crit = v3_check_critical(&value);
        +	if ((ext_type = v3_check_generic(&value))) 
        +		return v3_generic_extension(OBJ_nid2sn(ext_nid),
        +						 value, crit, ext_type, ctx);
        +	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
        +	}
        +
        +/* CONF *conf:  Config file    */
        +/* char *value:  Value    */
        +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
        +				    int crit, char *value)
        +	{
        +	const X509V3_EXT_METHOD *method;
        +	X509_EXTENSION *ext;
        +	STACK_OF(CONF_VALUE) *nval;
        +	void *ext_struc;
        +	if (ext_nid == NID_undef)
        +		{
        +		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
        +		return NULL;
        +		}
        +	if (!(method = X509V3_EXT_get_nid(ext_nid)))
        +		{
        +		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION);
        +		return NULL;
        +		}
        +	/* Now get internal extension representation based on type */
        +	if (method->v2i)
        +		{
        +		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
        +		else nval = X509V3_parse_list(value);
        +		if(sk_CONF_VALUE_num(nval) <= 0)
        +			{
        +			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_INVALID_EXTENSION_STRING);
        +			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
        +			return NULL;
        +			}
        +		ext_struc = method->v2i(method, ctx, nval);
        +		if(*value != '@') sk_CONF_VALUE_pop_free(nval,
        +							 X509V3_conf_free);
        +		if(!ext_struc) return NULL;
        +		}
        +	else if(method->s2i)
        +		{
        +		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
        +		}
        +	else if(method->r2i)
        +		{
        +		if(!ctx->db || !ctx->db_meth)
        +			{
        +			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_NO_CONFIG_DATABASE);
        +			return NULL;
        +			}
        +		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
        +		}
        +	else
        +		{
        +		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
        +		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
        +		return NULL;
        +		}
        +
        +	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
        +	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
        +	else method->ext_free(ext_struc);
        +	return ext;
        +
        +	}
        +
        +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
        +				  int crit, void *ext_struc)
        +	{
        +	unsigned char *ext_der;
        +	int ext_len;
        +	ASN1_OCTET_STRING *ext_oct;
        +	X509_EXTENSION *ext;
        +	/* Convert internal representation to DER */
        +	if (method->it)
        +		{
        +		ext_der = NULL;
        +		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
        +		if (ext_len < 0) goto merr;
        +		}
        +	 else
        +		{
        +		unsigned char *p;
        +		ext_len = method->i2d(ext_struc, NULL);
        +		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
        +		p = ext_der;
        +		method->i2d(ext_struc, &p);
        +		}
        +	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
        +	ext_oct->data = ext_der;
        +	ext_oct->length = ext_len;
        +
        +	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
        +	if (!ext) goto merr;
        +	M_ASN1_OCTET_STRING_free(ext_oct);
        +
        +	return ext;
        +
        +	merr:
        +	X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +
        +	}
        +
        +/* Given an internal structure, nid and critical flag create an extension */
        +
        +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
        +	{
        +	const X509V3_EXT_METHOD *method;
        +	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
        +		X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
        +		return NULL;
        +	}
        +	return do_ext_i2d(method, ext_nid, crit, ext_struc);
        +}
        +
        +/* Check the extension string for critical flag */
        +static int v3_check_critical(char **value)
        +{
        +	char *p = *value;
        +	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
        +	p+=9;
        +	while(isspace((unsigned char)*p)) p++;
        +	*value = p;
        +	return 1;
        +}
        +
        +/* Check extension string for generic extension and return the type */
        +static int v3_check_generic(char **value)
        +{
        +	int gen_type = 0;
        +	char *p = *value;
        +	if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
        +		{
        +		p+=4;
        +		gen_type = 1;
        +		}
        +	else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
        +		{
        +		p+=5;
        +		gen_type = 2;
        +		}
        +	else
        +		return 0;
        +
        +	while (isspace((unsigned char)*p)) p++;
        +	*value = p;
        +	return gen_type;
        +}
        +
        +/* Create a generic extension: for now just handle DER type */
        +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
        +					    int crit, int gen_type,
        +					    X509V3_CTX *ctx)
        +	{
        +	unsigned char *ext_der=NULL;
        +	long ext_len;
        +	ASN1_OBJECT *obj=NULL;
        +	ASN1_OCTET_STRING *oct=NULL;
        +	X509_EXTENSION *extension=NULL;
        +	if (!(obj = OBJ_txt2obj(ext, 0)))
        +		{
        +		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
        +		ERR_add_error_data(2, "name=", ext);
        +		goto err;
        +		}
        +
        +	if (gen_type == 1)
        +		ext_der = string_to_hex(value, &ext_len);
        +	else if (gen_type == 2)
        +		ext_der = generic_asn1(value, ctx, &ext_len);
        +
        +	if (ext_der == NULL)
        +		{
        +		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
        +		ERR_add_error_data(2, "value=", value);
        +		goto err;
        +		}
        +
        +	if (!(oct = M_ASN1_OCTET_STRING_new()))
        +		{
        +		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	oct->data = ext_der;
        +	oct->length = ext_len;
        +	ext_der = NULL;
        +
        +	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
        +
        +	err:
        +	ASN1_OBJECT_free(obj);
        +	M_ASN1_OCTET_STRING_free(oct);
        +	if(ext_der) OPENSSL_free(ext_der);
        +	return extension;
        +
        +	}
        +
        +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
        +	{
        +	ASN1_TYPE *typ;
        +	unsigned char *ext_der = NULL;
        +	typ = ASN1_generate_v3(value, ctx);
        +	if (typ == NULL)
        +		return NULL;
        +	*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
        +	ASN1_TYPE_free(typ);
        +	return ext_der;
        +	}
        +
        +/* This is the main function: add a bunch of extensions based on a config file
        + * section to an extension STACK.
        + */
        +
        +
        +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
        +			    STACK_OF(X509_EXTENSION) **sk)
        +	{
        +	X509_EXTENSION *ext;
        +	STACK_OF(CONF_VALUE) *nval;
        +	CONF_VALUE *val;	
        +	int i;
        +	if (!(nval = NCONF_get_section(conf, section))) return 0;
        +	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
        +		{
        +		val = sk_CONF_VALUE_value(nval, i);
        +		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
        +								return 0;
        +		if (sk) X509v3_add_ext(sk, ext, -1);
        +		X509_EXTENSION_free(ext);
        +		}
        +	return 1;
        +	}
        +
        +/* Convenience functions to add extensions to a certificate, CRL and request */
        +
        +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
        +			 X509 *cert)
        +	{
        +	STACK_OF(X509_EXTENSION) **sk = NULL;
        +	if (cert)
        +		sk = &cert->cert_info->extensions;
        +	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
        +	}
        +
        +/* Same as above but for a CRL */
        +
        +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
        +			     X509_CRL *crl)
        +	{
        +	STACK_OF(X509_EXTENSION) **sk = NULL;
        +	if (crl)
        +		sk = &crl->crl->extensions;
        +	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
        +	}
        +
        +/* Add extensions to certificate request */
        +
        +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
        +	     X509_REQ *req)
        +	{
        +	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
        +	int i;
        +	if (req)
        +		sk = &extlist;
        +	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
        +	if (!i || !sk)
        +		return i;
        +	i = X509_REQ_add_extensions(req, extlist);
        +	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
        +	return i;
        +	}
        +
        +/* Config database functions */
        +
        +char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
        +	{
        +	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
        +		{
        +		X509V3err(X509V3_F_X509V3_GET_STRING,X509V3_R_OPERATION_NOT_DEFINED);
        +		return NULL;
        +		}
        +	if (ctx->db_meth->get_string)
        +			return ctx->db_meth->get_string(ctx->db, name, section);
        +	return NULL;
        +	}
        +
        +STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
        +	{
        +	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
        +		{
        +		X509V3err(X509V3_F_X509V3_GET_SECTION,X509V3_R_OPERATION_NOT_DEFINED);
        +		return NULL;
        +		}
        +	if (ctx->db_meth->get_section)
        +			return ctx->db_meth->get_section(ctx->db, section);
        +	return NULL;
        +	}
        +
        +void X509V3_string_free(X509V3_CTX *ctx, char *str)
        +	{
        +	if (!str) return;
        +	if (ctx->db_meth->free_string)
        +			ctx->db_meth->free_string(ctx->db, str);
        +	}
        +
        +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
        +	{
        +	if (!section) return;
        +	if (ctx->db_meth->free_section)
        +			ctx->db_meth->free_section(ctx->db, section);
        +	}
        +
        +static char *nconf_get_string(void *db, char *section, char *value)
        +	{
        +	return NCONF_get_string(db, section, value);
        +	}
        +
        +static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
        +	{
        +	return NCONF_get_section(db, section);
        +	}
        +
        +static X509V3_CONF_METHOD nconf_method = {
        +nconf_get_string,
        +nconf_get_section,
        +NULL,
        +NULL
        +};
        +
        +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
        +	{
        +	ctx->db_meth = &nconf_method;
        +	ctx->db = conf;
        +	}
        +
        +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
        +		    X509_CRL *crl, int flags)
        +	{
        +	ctx->issuer_cert = issuer;
        +	ctx->subject_cert = subj;
        +	ctx->crl = crl;
        +	ctx->subject_req = req;
        +	ctx->flags = flags;
        +	}
        +
        +/* Old conf compatibility functions */
        +
        +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +				char *name, char *value)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, conf);
        +	return X509V3_EXT_nconf(&ctmp, ctx, name, value);
        +	}
        +
        +/* LHASH *conf:  Config file    */
        +/* char *value:  Value    */
        +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +				    int ext_nid, char *value)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, conf);
        +	return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
        +	}
        +
        +static char *conf_lhash_get_string(void *db, char *section, char *value)
        +	{
        +	return CONF_get_string(db, section, value);
        +	}
        +
        +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
        +	{
        +	return CONF_get_section(db, section);
        +	}
        +
        +static X509V3_CONF_METHOD conf_lhash_method = {
        +conf_lhash_get_string,
        +conf_lhash_get_section,
        +NULL,
        +NULL
        +};
        +
        +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
        +	{
        +	ctx->db_meth = &conf_lhash_method;
        +	ctx->db = lhash;
        +	}
        +
        +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +			char *section, X509 *cert)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, conf);
        +	return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
        +	}
        +
        +/* Same as above but for a CRL */
        +
        +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +			    char *section, X509_CRL *crl)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, conf);
        +	return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
        +	}
        +
        +/* Add extensions to certificate request */
        +
        +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +			    char *section, X509_REQ *req)
        +	{
        +	CONF ctmp;
        +	CONF_set_nconf(&ctmp, conf);
        +	return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_cpols.c b/vendor/openssl/openssl/crypto/x509v3/v3_cpols.c
        new file mode 100644
        index 000000000..1f0798b94
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_cpols.c
        @@ -0,0 +1,457 @@
        +/* v3_cpols.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +#include "pcy_int.h"
        +
        +/* Certificate policies extension support: this one is a bit complex... */
        +
        +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
        +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
        +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
        +static void print_notice(BIO *out, USERNOTICE *notice, int indent);
        +static POLICYINFO *policy_section(X509V3_CTX *ctx,
        +				 STACK_OF(CONF_VALUE) *polstrs, int ia5org);
        +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
        +					STACK_OF(CONF_VALUE) *unot, int ia5org);
        +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
        +
        +const X509V3_EXT_METHOD v3_cpols = {
        +NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
        +0,0,0,0,
        +0,0,
        +0,0,
        +(X509V3_EXT_I2R)i2r_certpol,
        +(X509V3_EXT_R2I)r2i_certpol,
        +NULL
        +};
        +
        +ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
        +ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
        +
        +ASN1_SEQUENCE(POLICYINFO) = {
        +	ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
        +	ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
        +} ASN1_SEQUENCE_END(POLICYINFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
        +
        +ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
        +
        +ASN1_ADB(POLICYQUALINFO) = {
        +	ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
        +	ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
        +} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
        +
        +ASN1_SEQUENCE(POLICYQUALINFO) = {
        +	ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
        +	ASN1_ADB_OBJECT(POLICYQUALINFO)
        +} ASN1_SEQUENCE_END(POLICYQUALINFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
        +
        +ASN1_SEQUENCE(USERNOTICE) = {
        +	ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
        +	ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
        +} ASN1_SEQUENCE_END(USERNOTICE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
        +
        +ASN1_SEQUENCE(NOTICEREF) = {
        +	ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
        +	ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(NOTICEREF)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
        +
        +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
        +		X509V3_CTX *ctx, char *value)
        +{
        +	STACK_OF(POLICYINFO) *pols = NULL;
        +	char *pstr;
        +	POLICYINFO *pol;
        +	ASN1_OBJECT *pobj;
        +	STACK_OF(CONF_VALUE) *vals;
        +	CONF_VALUE *cnf;
        +	int i, ia5org;
        +	pols = sk_POLICYINFO_new_null();
        +	if (pols == NULL) {
        +		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	vals =  X509V3_parse_list(value);
        +	if (vals == NULL) {
        +		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
        +		goto err;
        +	}
        +	ia5org = 0;
        +	for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
        +		cnf = sk_CONF_VALUE_value(vals, i);
        +		if(cnf->value || !cnf->name ) {
        +			X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER);
        +			X509V3_conf_err(cnf);
        +			goto err;
        +		}
        +		pstr = cnf->name;
        +		if(!strcmp(pstr,"ia5org")) {
        +			ia5org = 1;
        +			continue;
        +		} else if(*pstr == '@') {
        +			STACK_OF(CONF_VALUE) *polsect;
        +			polsect = X509V3_get_section(ctx, pstr + 1);
        +			if(!polsect) {
        +				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION);
        +
        +				X509V3_conf_err(cnf);
        +				goto err;
        +			}
        +			pol = policy_section(ctx, polsect, ia5org);
        +			X509V3_section_free(ctx, polsect);
        +			if(!pol) goto err;
        +		} else {
        +			if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
        +				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER);
        +				X509V3_conf_err(cnf);
        +				goto err;
        +			}
        +			pol = POLICYINFO_new();
        +			pol->policyid = pobj;
        +		}
        +		if (!sk_POLICYINFO_push(pols, pol)){
        +			POLICYINFO_free(pol);
        +			X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +	}
        +	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
        +	return pols;
        +	err:
        +	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
        +	sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
        +	return NULL;
        +}
        +
        +static POLICYINFO *policy_section(X509V3_CTX *ctx,
        +				STACK_OF(CONF_VALUE) *polstrs, int ia5org)
        +{
        +	int i;
        +	CONF_VALUE *cnf;
        +	POLICYINFO *pol;
        +	POLICYQUALINFO *qual;
        +	if(!(pol = POLICYINFO_new())) goto merr;
        +	for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
        +		cnf = sk_CONF_VALUE_value(polstrs, i);
        +		if(!strcmp(cnf->name, "policyIdentifier")) {
        +			ASN1_OBJECT *pobj;
        +			if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
        +				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OBJECT_IDENTIFIER);
        +				X509V3_conf_err(cnf);
        +				goto err;
        +			}
        +			pol->policyid = pobj;
        +
        +		} else if(!name_cmp(cnf->name, "CPS")) {
        +			if(!pol->qualifiers) pol->qualifiers =
        +						 sk_POLICYQUALINFO_new_null();
        +			if(!(qual = POLICYQUALINFO_new())) goto merr;
        +			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
        +								 goto merr;
        +			qual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
        +			qual->d.cpsuri = M_ASN1_IA5STRING_new();
        +			if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
        +						 strlen(cnf->value))) goto merr;
        +		} else if(!name_cmp(cnf->name, "userNotice")) {
        +			STACK_OF(CONF_VALUE) *unot;
        +			if(*cnf->value != '@') {
        +				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME);
        +				X509V3_conf_err(cnf);
        +				goto err;
        +			}
        +			unot = X509V3_get_section(ctx, cnf->value + 1);
        +			if(!unot) {
        +				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_SECTION);
        +
        +				X509V3_conf_err(cnf);
        +				goto err;
        +			}
        +			qual = notice_section(ctx, unot, ia5org);
        +			X509V3_section_free(ctx, unot);
        +			if(!qual) goto err;
        +			if(!pol->qualifiers) pol->qualifiers =
        +						 sk_POLICYQUALINFO_new_null();
        +			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
        +								 goto merr;
        +		} else {
        +			X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION);
        +
        +			X509V3_conf_err(cnf);
        +			goto err;
        +		}
        +	}
        +	if(!pol->policyid) {
        +		X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_NO_POLICY_IDENTIFIER);
        +		goto err;
        +	}
        +
        +	return pol;
        +
        +	merr:
        +	X509V3err(X509V3_F_POLICY_SECTION,ERR_R_MALLOC_FAILURE);
        +
        +	err:
        +	POLICYINFO_free(pol);
        +	return NULL;
        +	
        +	
        +}
        +
        +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
        +					STACK_OF(CONF_VALUE) *unot, int ia5org)
        +{
        +	int i, ret;
        +	CONF_VALUE *cnf;
        +	USERNOTICE *not;
        +	POLICYQUALINFO *qual;
        +	if(!(qual = POLICYQUALINFO_new())) goto merr;
        +	qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
        +	if(!(not = USERNOTICE_new())) goto merr;
        +	qual->d.usernotice = not;
        +	for(i = 0; i < sk_CONF_VALUE_num(unot); i++) {
        +		cnf = sk_CONF_VALUE_value(unot, i);
        +		if(!strcmp(cnf->name, "explicitText")) {
        +			not->exptext = M_ASN1_VISIBLESTRING_new();
        +			if(!ASN1_STRING_set(not->exptext, cnf->value,
        +						 strlen(cnf->value))) goto merr;
        +		} else if(!strcmp(cnf->name, "organization")) {
        +			NOTICEREF *nref;
        +			if(!not->noticeref) {
        +				if(!(nref = NOTICEREF_new())) goto merr;
        +				not->noticeref = nref;
        +			} else nref = not->noticeref;
        +			if(ia5org) nref->organization->type = V_ASN1_IA5STRING;
        +			else nref->organization->type = V_ASN1_VISIBLESTRING;
        +			if(!ASN1_STRING_set(nref->organization, cnf->value,
        +						 strlen(cnf->value))) goto merr;
        +		} else if(!strcmp(cnf->name, "noticeNumbers")) {
        +			NOTICEREF *nref;
        +			STACK_OF(CONF_VALUE) *nos;
        +			if(!not->noticeref) {
        +				if(!(nref = NOTICEREF_new())) goto merr;
        +				not->noticeref = nref;
        +			} else nref = not->noticeref;
        +			nos = X509V3_parse_list(cnf->value);
        +			if(!nos || !sk_CONF_VALUE_num(nos)) {
        +				X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_NUMBERS);
        +				X509V3_conf_err(cnf);
        +				goto err;
        +			}
        +			ret = nref_nos(nref->noticenos, nos);
        +			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
        +			if (!ret)
        +				goto err;
        +		} else {
        +			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION);
        +			X509V3_conf_err(cnf);
        +			goto err;
        +		}
        +	}
        +
        +	if(not->noticeref && 
        +	      (!not->noticeref->noticenos || !not->noticeref->organization)) {
        +			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
        +			goto err;
        +	}
        +
        +	return qual;
        +
        +	merr:
        +	X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE);
        +
        +	err:
        +	POLICYQUALINFO_free(qual);
        +	return NULL;
        +}
        +
        +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
        +{
        +	CONF_VALUE *cnf;
        +	ASN1_INTEGER *aint;
        +
        +	int i;
        +
        +	for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
        +		cnf = sk_CONF_VALUE_value(nos, i);
        +		if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
        +			X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER);
        +			goto err;
        +		}
        +		if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
        +	}
        +	return 1;
        +
        +	merr:
        +	X509V3err(X509V3_F_NREF_NOS,ERR_R_MALLOC_FAILURE);
        +
        +	err:
        +	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
        +	return 0;
        +}
        +
        +
        +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
        +		BIO *out, int indent)
        +{
        +	int i;
        +	POLICYINFO *pinfo;
        +	/* First print out the policy OIDs */
        +	for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
        +		pinfo = sk_POLICYINFO_value(pol, i);
        +		BIO_printf(out, "%*sPolicy: ", indent, "");
        +		i2a_ASN1_OBJECT(out, pinfo->policyid);
        +		BIO_puts(out, "\n");
        +		if(pinfo->qualifiers)
        +			 print_qualifiers(out, pinfo->qualifiers, indent + 2);
        +	}
        +	return 1;
        +}
        +
        +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
        +		int indent)
        +{
        +	POLICYQUALINFO *qualinfo;
        +	int i;
        +	for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
        +		qualinfo = sk_POLICYQUALINFO_value(quals, i);
        +		switch(OBJ_obj2nid(qualinfo->pqualid))
        +		{
        +			case NID_id_qt_cps:
        +			BIO_printf(out, "%*sCPS: %s\n", indent, "",
        +						qualinfo->d.cpsuri->data);
        +			break;
        +		
        +			case NID_id_qt_unotice:
        +			BIO_printf(out, "%*sUser Notice:\n", indent, "");
        +			print_notice(out, qualinfo->d.usernotice, indent + 2);
        +			break;
        +
        +			default:
        +			BIO_printf(out, "%*sUnknown Qualifier: ",
        +							 indent + 2, "");
        +			
        +			i2a_ASN1_OBJECT(out, qualinfo->pqualid);
        +			BIO_puts(out, "\n");
        +			break;
        +		}
        +	}
        +}
        +
        +static void print_notice(BIO *out, USERNOTICE *notice, int indent)
        +{
        +	int i;
        +	if(notice->noticeref) {
        +		NOTICEREF *ref;
        +		ref = notice->noticeref;
        +		BIO_printf(out, "%*sOrganization: %s\n", indent, "",
        +						 ref->organization->data);
        +		BIO_printf(out, "%*sNumber%s: ", indent, "",
        +			   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
        +		for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
        +			ASN1_INTEGER *num;
        +			char *tmp;
        +			num = sk_ASN1_INTEGER_value(ref->noticenos, i);
        +			if(i) BIO_puts(out, ", ");
        +			tmp = i2s_ASN1_INTEGER(NULL, num);
        +			BIO_puts(out, tmp);
        +			OPENSSL_free(tmp);
        +		}
        +		BIO_puts(out, "\n");
        +	}
        +	if(notice->exptext)
        +		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
        +							 notice->exptext->data);
        +}
        +
        +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
        +	{
        +	const X509_POLICY_DATA *dat = node->data;
        +
        +	BIO_printf(out, "%*sPolicy: ", indent, "");
        +			
        +	i2a_ASN1_OBJECT(out, dat->valid_policy);
        +	BIO_puts(out, "\n");
        +	BIO_printf(out, "%*s%s\n", indent + 2, "",
        +		node_data_critical(dat) ? "Critical" : "Non Critical");
        +	if (dat->qualifier_set)
        +		print_qualifiers(out, dat->qualifier_set, indent + 2);
        +	else
        +		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
        +	}
        +
        +
        +IMPLEMENT_STACK_OF(X509_POLICY_NODE)
        +IMPLEMENT_STACK_OF(X509_POLICY_DATA)
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_crld.c b/vendor/openssl/openssl/crypto/x509v3/v3_crld.c
        new file mode 100644
        index 000000000..790a6dd03
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_crld.c
        @@ -0,0 +1,616 @@
        +/* v3_crld.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2008 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +static void *v2i_crld(const X509V3_EXT_METHOD *method,
        +		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
        +		     int indent);
        +
        +const X509V3_EXT_METHOD v3_crld =
        +	{
        +	NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
        +	0,0,0,0,
        +	0,0,
        +	0,
        +	v2i_crld,
        +	i2r_crldp,0,
        +	NULL
        +	};
        +
        +const X509V3_EXT_METHOD v3_freshest_crl =
        +	{
        +	NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
        +	0,0,0,0,
        +	0,0,
        +	0,
        +	v2i_crld,
        +	i2r_crldp,0,
        +	NULL
        +	};
        +
        +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
        +	{
        +	STACK_OF(CONF_VALUE) *gnsect;
        +	STACK_OF(GENERAL_NAME) *gens;
        +	if (*sect == '@')
        +		gnsect = X509V3_get_section(ctx, sect + 1);
        +	else
        +		gnsect = X509V3_parse_list(sect);
        +	if (!gnsect)
        +		{
        +		X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
        +						X509V3_R_SECTION_NOT_FOUND);
        +		return NULL;
        +		}
        +	gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
        +	if (*sect == '@')
        +		X509V3_section_free(ctx, gnsect);
        +	else
        +		sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
        +	return gens;
        +	}
        +
        +static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
        +							CONF_VALUE *cnf)
        +	{
        +	STACK_OF(GENERAL_NAME) *fnm = NULL;
        +	STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
        +	if (!strncmp(cnf->name, "fullname", 9))
        +		{
        +		fnm = gnames_from_sectname(ctx, cnf->value);
        +		if (!fnm)
        +			goto err;
        +		}
        +	else if (!strcmp(cnf->name, "relativename"))
        +		{
        +		int ret;
        +		STACK_OF(CONF_VALUE) *dnsect;
        +		X509_NAME *nm;
        +		nm = X509_NAME_new();
        +		if (!nm)
        +			return -1;
        +		dnsect = X509V3_get_section(ctx, cnf->value);
        +		if (!dnsect)
        +			{
        +			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
        +						X509V3_R_SECTION_NOT_FOUND);
        +			return -1;
        +			}
        +		ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
        +		X509V3_section_free(ctx, dnsect);
        +		rnm = nm->entries;
        +		nm->entries = NULL;
        +		X509_NAME_free(nm);
        +		if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
        +			goto err;
        +		/* Since its a name fragment can't have more than one
        +		 * RDNSequence
        +		 */
        +		if (sk_X509_NAME_ENTRY_value(rnm,
        +				sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
        +			{
        +			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
        +						X509V3_R_INVALID_MULTIPLE_RDNS);
        +			goto err;
        +			}
        +		}
        +	else
        +		return 0;
        +
        +	if (*pdp)
        +		{
        +		X509V3err(X509V3_F_SET_DIST_POINT_NAME,
        +						X509V3_R_DISTPOINT_ALREADY_SET);
        +		goto err;
        +		}
        +
        +	*pdp = DIST_POINT_NAME_new();
        +	if (!*pdp)
        +		goto err;
        +	if (fnm)
        +		{
        +		(*pdp)->type = 0;
        +		(*pdp)->name.fullname = fnm;
        +		}
        +	else
        +		{
        +		(*pdp)->type = 1;
        +		(*pdp)->name.relativename = rnm;
        +		}
        +
        +	return 1;
        +		
        +	err:
        +	if (fnm)
        +		sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
        +	if (rnm)
        +		sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
        +	return -1;
        +	}
        +
        +static const BIT_STRING_BITNAME reason_flags[] = {
        +{0, "Unused", "unused"},
        +{1, "Key Compromise", "keyCompromise"},
        +{2, "CA Compromise", "CACompromise"},
        +{3, "Affiliation Changed", "affiliationChanged"},
        +{4, "Superseded", "superseded"},
        +{5, "Cessation Of Operation", "cessationOfOperation"},
        +{6, "Certificate Hold", "certificateHold"},
        +{7, "Privilege Withdrawn", "privilegeWithdrawn"},
        +{8, "AA Compromise", "AACompromise"},
        +{-1, NULL, NULL}
        +};
        +
        +static int set_reasons(ASN1_BIT_STRING **preas, char *value)
        +	{
        +	STACK_OF(CONF_VALUE) *rsk = NULL;
        +	const BIT_STRING_BITNAME *pbn;
        +	const char *bnam;
        +	int i, ret = 0;
        +	rsk = X509V3_parse_list(value);
        +	if (!rsk)
        +		return 0;
        +	if (*preas)
        +		return 0;
        +	for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
        +		{
        +		bnam = sk_CONF_VALUE_value(rsk, i)->name;
        +		if (!*preas)
        +			{
        +			*preas = ASN1_BIT_STRING_new();
        +			if (!*preas)
        +				goto err;
        +			}
        +		for (pbn = reason_flags; pbn->lname; pbn++)
        +			{
        +			if (!strcmp(pbn->sname, bnam))
        +				{
        +				if (!ASN1_BIT_STRING_set_bit(*preas,
        +							pbn->bitnum, 1))
        +					goto err;
        +				break;
        +				}
        +			}
        +		if (!pbn->lname)
        +			goto err;
        +		}
        +	ret = 1;
        +
        +	err:
        +	sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
        +	return ret;
        +	}
        +
        +static int print_reasons(BIO *out, const char *rname,
        +			ASN1_BIT_STRING *rflags, int indent)
        +	{
        +	int first = 1;
        +	const BIT_STRING_BITNAME *pbn;
        +	BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
        +	for (pbn = reason_flags; pbn->lname; pbn++)
        +		{
        +		if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
        +			{
        +			if (first)
        +				first = 0;
        +			else
        +				BIO_puts(out, ", ");
        +			BIO_puts(out, pbn->lname);
        +			}
        +		}
        +	if (first)
        +		BIO_puts(out, "<EMPTY>\n");
        +	else
        +		BIO_puts(out, "\n");
        +	return 1;
        +	}
        +
        +static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
        +						STACK_OF(CONF_VALUE) *nval)
        +	{
        +	int i;
        +	CONF_VALUE *cnf;
        +	DIST_POINT *point = NULL;
        +	point = DIST_POINT_new();
        +	if (!point)
        +		goto err;
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
        +		{
        +		int ret;
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		ret = set_dist_point_name(&point->distpoint, ctx, cnf);
        +		if (ret > 0)
        +			continue;
        +		if (ret < 0)
        +			goto err;
        +		if (!strcmp(cnf->name, "reasons"))
        +			{
        +			if (!set_reasons(&point->reasons, cnf->value))
        +				goto err;
        +			}
        +		else if (!strcmp(cnf->name, "CRLissuer"))
        +			{
        +			point->CRLissuer =
        +				gnames_from_sectname(ctx, cnf->value);
        +			if (!point->CRLissuer)
        +				goto err;
        +			}
        +		}
        +
        +	return point;
        +			
        +
        +	err:
        +	if (point)
        +		DIST_POINT_free(point);
        +	return NULL;
        +	}
        +
        +static void *v2i_crld(const X509V3_EXT_METHOD *method,
        +		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +	{
        +	STACK_OF(DIST_POINT) *crld = NULL;
        +	GENERAL_NAMES *gens = NULL;
        +	GENERAL_NAME *gen = NULL;
        +	CONF_VALUE *cnf;
        +	int i;
        +	if(!(crld = sk_DIST_POINT_new_null())) goto merr;
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		DIST_POINT *point;
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		if (!cnf->value)
        +			{
        +			STACK_OF(CONF_VALUE) *dpsect;
        +			dpsect = X509V3_get_section(ctx, cnf->name);
        +			if (!dpsect)
        +				goto err;
        +			point = crldp_from_section(ctx, dpsect);
        +			X509V3_section_free(ctx, dpsect);
        +			if (!point)
        +				goto err;
        +			if(!sk_DIST_POINT_push(crld, point))
        +				{
        +				DIST_POINT_free(point);
        +				goto merr;
        +				}
        +			}
        +		else
        +			{
        +			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
        +				goto err; 
        +			if(!(gens = GENERAL_NAMES_new()))
        +				goto merr;
        +			if(!sk_GENERAL_NAME_push(gens, gen))
        +				goto merr;
        +			gen = NULL;
        +			if(!(point = DIST_POINT_new()))
        +				goto merr;
        +			if(!sk_DIST_POINT_push(crld, point))
        +				{
        +				DIST_POINT_free(point);
        +				goto merr;
        +				}
        +			if(!(point->distpoint = DIST_POINT_NAME_new()))
        +				goto merr;
        +			point->distpoint->name.fullname = gens;
        +			point->distpoint->type = 0;
        +			gens = NULL;
        +			}
        +	}
        +	return crld;
        +
        +	merr:
        +	X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE);
        +	err:
        +	GENERAL_NAME_free(gen);
        +	GENERAL_NAMES_free(gens);
        +	sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
        +	return NULL;
        +}
        +
        +IMPLEMENT_STACK_OF(DIST_POINT)
        +IMPLEMENT_ASN1_SET_OF(DIST_POINT)
        +
        +static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
        +								void *exarg)
        +	{
        +	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
        +
        +	switch(operation)
        +		{
        +		case ASN1_OP_NEW_POST:
        +		dpn->dpname = NULL;
        +		break;
        +
        +		case ASN1_OP_FREE_POST:
        +		if (dpn->dpname)
        +			X509_NAME_free(dpn->dpname);
        +		break;
        +		}
        +	return 1;
        +	}
        +
        +
        +ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
        +	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
        +	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
        +} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
        +
        +
        +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
        +
        +ASN1_SEQUENCE(DIST_POINT) = {
        +	ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
        +	ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
        +	ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
        +} ASN1_SEQUENCE_END(DIST_POINT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
        +
        +ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
        +ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
        +
        +ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
        +	ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
        +	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
        +	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
        +	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
        +	ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
        +	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
        +} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
        +
        +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
        +		   int indent);
        +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +		     STACK_OF(CONF_VALUE) *nval);
        +
        +const X509V3_EXT_METHOD v3_idp =
        +	{
        +	NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
        +	ASN1_ITEM_ref(ISSUING_DIST_POINT),
        +	0,0,0,0,
        +	0,0,
        +	0,
        +	v2i_idp,
        +	i2r_idp,0,
        +	NULL
        +	};
        +
        +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +		     STACK_OF(CONF_VALUE) *nval)
        +	{
        +	ISSUING_DIST_POINT *idp = NULL;
        +	CONF_VALUE *cnf;
        +	char *name, *val;
        +	int i, ret;
        +	idp = ISSUING_DIST_POINT_new();
        +	if (!idp)
        +		goto merr;
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
        +		{
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		name = cnf->name;
        +		val = cnf->value;
        +		ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
        +		if (ret > 0)
        +			continue;
        +		if (ret < 0)
        +			goto err;
        +		if (!strcmp(name, "onlyuser"))
        +			{
        +			if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
        +				goto err;
        +			}
        +		else if (!strcmp(name, "onlyCA"))
        +			{
        +			if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
        +				goto err;
        +			}
        +		else if (!strcmp(name, "onlyAA"))
        +			{
        +			if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
        +				goto err;
        +			}
        +		else if (!strcmp(name, "indirectCRL"))
        +			{
        +			if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
        +				goto err;
        +			}
        +		else if (!strcmp(name, "onlysomereasons"))
        +			{
        +			if (!set_reasons(&idp->onlysomereasons, val))
        +				goto err;
        +			}
        +		else
        +			{
        +                        X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
        +                        X509V3_conf_err(cnf);
        +                        goto err;
        +			}
        +		}
        +	return idp;
        +
        +	merr:
        +	X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
        +	err:
        +	ISSUING_DIST_POINT_free(idp);
        +	return NULL;
        +	}
        +
        +static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
        +	{
        +	int i;
        +	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
        +		{
        +		BIO_printf(out, "%*s", indent + 2, "");
        +		GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
        +		BIO_puts(out, "\n");
        +		}
        +	return 1;
        +	}
        +
        +static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
        +	{
        +	if (dpn->type == 0)
        +		{
        +		BIO_printf(out, "%*sFull Name:\n", indent, "");
        +		print_gens(out, dpn->name.fullname, indent);
        +		}
        +	else
        +		{
        +		X509_NAME ntmp;
        +		ntmp.entries = dpn->name.relativename;
        +		BIO_printf(out, "%*sRelative Name:\n%*s",
        +						indent, "", indent + 2, "");
        +		X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
        +		BIO_puts(out, "\n");
        +		}
        +	return 1;
        +	}
        +
        +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
        +		   int indent)
        +	{
        +	ISSUING_DIST_POINT *idp = pidp;
        +	if (idp->distpoint)
        +		print_distpoint(out, idp->distpoint, indent);
        +	if (idp->onlyuser > 0)
        +		BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
        +	if (idp->onlyCA > 0)
        +		BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
        +	if (idp->indirectCRL > 0)
        +		BIO_printf(out, "%*sIndirect CRL\n", indent, "");
        +	if (idp->onlysomereasons)
        +		print_reasons(out, "Only Some Reasons", 
        +				idp->onlysomereasons, indent);
        +	if (idp->onlyattr > 0)
        +		BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
        +	if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
        +		&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
        +		&& (idp->onlyattr <= 0))
        +		BIO_printf(out, "%*s<EMPTY>\n", indent, "");
        +		
        +	return 1;
        +	}
        +
        +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
        +		     int indent)
        +	{
        +	STACK_OF(DIST_POINT) *crld = pcrldp;
        +	DIST_POINT *point;
        +	int i;
        +	for(i = 0; i < sk_DIST_POINT_num(crld); i++)
        +		{
        +		BIO_puts(out, "\n");
        +		point = sk_DIST_POINT_value(crld, i);
        +		if(point->distpoint)
        +			print_distpoint(out, point->distpoint, indent);
        +		if(point->reasons) 
        +			print_reasons(out, "Reasons", point->reasons,
        +								indent);
        +		if(point->CRLissuer)
        +			{
        +			BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
        +			print_gens(out, point->CRLissuer, indent);
        +			}
        +		}
        +	return 1;
        +	}
        +
        +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
        +	{
        +	int i;
        +	STACK_OF(X509_NAME_ENTRY) *frag;
        +	X509_NAME_ENTRY *ne;
        +	if (!dpn || (dpn->type != 1))
        +		return 1;
        +	frag = dpn->name.relativename;
        +	dpn->dpname = X509_NAME_dup(iname);
        +	if (!dpn->dpname)
        +		return 0;
        +	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
        +		{
        +		ne = sk_X509_NAME_ENTRY_value(frag, i);
        +		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
        +			{
        +			X509_NAME_free(dpn->dpname);
        +			dpn->dpname = NULL;
        +			return 0;
        +			}
        +		}
        +	/* generate cached encoding of name */
        +	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
        +		{
        +		X509_NAME_free(dpn->dpname);
        +		dpn->dpname = NULL;
        +		return 0;
        +		}
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_enum.c b/vendor/openssl/openssl/crypto/x509v3/v3_enum.c
        new file mode 100644
        index 000000000..c0575e368
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_enum.c
        @@ -0,0 +1,97 @@
        +/* v3_enum.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509v3.h>
        +
        +static ENUMERATED_NAMES crl_reasons[] = {
        +{CRL_REASON_UNSPECIFIED, 	 "Unspecified", "unspecified"},
        +{CRL_REASON_KEY_COMPROMISE,	 "Key Compromise", "keyCompromise"},
        +{CRL_REASON_CA_COMPROMISE,	 "CA Compromise", "CACompromise"},
        +{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
        +{CRL_REASON_SUPERSEDED, 	 "Superseded", "superseded"},
        +{CRL_REASON_CESSATION_OF_OPERATION,
        +			"Cessation Of Operation", "cessationOfOperation"},
        +{CRL_REASON_CERTIFICATE_HOLD,	 "Certificate Hold", "certificateHold"},
        +{CRL_REASON_REMOVE_FROM_CRL,	 "Remove From CRL", "removeFromCRL"},
        +{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
        +{CRL_REASON_AA_COMPROMISE,	 "AA Compromise", "AACompromise"},
        +{-1, NULL, NULL}
        +};
        +
        +const X509V3_EXT_METHOD v3_crl_reason = { 
        +NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
        +0,0,0,0,
        +(X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
        +0,
        +0,0,0,0,
        +crl_reasons};
        +
        +
        +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method,
        +	     ASN1_ENUMERATED *e)
        +{
        +	ENUMERATED_NAMES *enam;
        +	long strval;
        +	strval = ASN1_ENUMERATED_get(e);
        +	for(enam = method->usr_data; enam->lname; enam++) {
        +		if(strval == enam->bitnum) return BUF_strdup(enam->lname);
        +	}
        +	return i2s_ASN1_ENUMERATED(method, e);
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_extku.c b/vendor/openssl/openssl/crypto/x509v3/v3_extku.c
        new file mode 100644
        index 000000000..1c6653275
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_extku.c
        @@ -0,0 +1,144 @@
        +/* v3_extku.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
        +				    X509V3_CTX *ctx,
        +				    STACK_OF(CONF_VALUE) *nval);
        +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
        +		void *eku, STACK_OF(CONF_VALUE) *extlist);
        +
        +const X509V3_EXT_METHOD v3_ext_ku = {
        +	NID_ext_key_usage, 0,
        +	ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
        +	0,0,0,0,
        +	0,0,
        +	i2v_EXTENDED_KEY_USAGE,
        +	v2i_EXTENDED_KEY_USAGE,
        +	0,0,
        +	NULL
        +};
        +
        +/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
        +const X509V3_EXT_METHOD v3_ocsp_accresp = {
        +	NID_id_pkix_OCSP_acceptableResponses, 0,
        +	ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
        +	0,0,0,0,
        +	0,0,
        +	i2v_EXTENDED_KEY_USAGE,
        +	v2i_EXTENDED_KEY_USAGE,
        +	0,0,
        +	NULL
        +};
        +
        +ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
        +ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
        +
        +static STACK_OF(CONF_VALUE) *
        +  i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
        +			 STACK_OF(CONF_VALUE) *ext_list)
        +{
        +	EXTENDED_KEY_USAGE *eku = a;
        +	int i;
        +	ASN1_OBJECT *obj;
        +	char obj_tmp[80];
        +	for(i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
        +		obj = sk_ASN1_OBJECT_value(eku, i);
        +		i2t_ASN1_OBJECT(obj_tmp, 80, obj);
        +		X509V3_add_value(NULL, obj_tmp, &ext_list);
        +	}
        +	return ext_list;
        +}
        +
        +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
        +				    X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	EXTENDED_KEY_USAGE *extku;
        +	char *extval;
        +	ASN1_OBJECT *objtmp;
        +	CONF_VALUE *val;
        +	int i;
        +
        +	if(!(extku = sk_ASN1_OBJECT_new_null())) {
        +		X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		val = sk_CONF_VALUE_value(nval, i);
        +		if(val->value) extval = val->value;
        +		else extval = val->name;
        +		if(!(objtmp = OBJ_txt2obj(extval, 0))) {
        +			sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
        +			X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
        +			X509V3_conf_err(val);
        +			return NULL;
        +		}
        +		sk_ASN1_OBJECT_push(extku, objtmp);
        +	}
        +	return extku;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_genn.c b/vendor/openssl/openssl/crypto/x509v3/v3_genn.c
        new file mode 100644
        index 000000000..b62835730
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_genn.c
        @@ -0,0 +1,252 @@
        +/* v3_genn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2008 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +ASN1_SEQUENCE(OTHERNAME) = {
        +	ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
        +	/* Maybe have a true ANY DEFINED BY later */
        +	ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
        +} ASN1_SEQUENCE_END(OTHERNAME)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
        +
        +ASN1_SEQUENCE(EDIPARTYNAME) = {
        +	ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
        +	ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
        +} ASN1_SEQUENCE_END(EDIPARTYNAME)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
        +
        +ASN1_CHOICE(GENERAL_NAME) = {
        +	ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
        +	ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
        +	ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
        +	/* Don't decode this */
        +	ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
        +	/* X509_NAME is a CHOICE type so use EXPLICIT */
        +	ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
        +	ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
        +	ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
        +	ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
        +	ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
        +} ASN1_CHOICE_END(GENERAL_NAME)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
        +
        +ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
        +ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
        +
        +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
        +	{
        +	return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
        +					 (d2i_of_void *) d2i_GENERAL_NAME,
        +					 (char *) a);
        +	}
        +
        +/* Returns 0 if they are equal, != 0 otherwise. */
        +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
        +	{
        +	int result = -1;
        +
        +	if (!a || !b || a->type != b->type) return -1;
        +	switch(a->type)
        +		{
        +	case GEN_X400:
        +	case GEN_EDIPARTY:
        +		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
        +		break;
        +
        +	case GEN_OTHERNAME:
        +		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
        +		break;
        +
        +	case GEN_EMAIL:
        +	case GEN_DNS:
        +	case GEN_URI:
        +		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
        +		break;
        +
        +	case GEN_DIRNAME:
        +		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
        +		break;
        +
        +	case GEN_IPADD:
        +		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
        +		break;
        +	
        +	case GEN_RID:
        +		result = OBJ_cmp(a->d.rid, b->d.rid);
        +		break;
        +		}
        +	return result;
        +	}
        +
        +/* Returns 0 if they are equal, != 0 otherwise. */
        +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
        +	{
        +	int result = -1;
        +
        +	if (!a || !b) return -1;
        +	/* Check their type first. */
        +	if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
        +		return result;
        +	/* Check the value. */
        +	result = ASN1_TYPE_cmp(a->value, b->value);
        +	return result;
        +	}
        +
        +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
        +	{
        +	switch(type)
        +		{
        +	case GEN_X400:
        +	case GEN_EDIPARTY:
        +		a->d.other = value;
        +		break;
        +
        +	case GEN_OTHERNAME:
        +		a->d.otherName = value;
        +		break;
        +
        +	case GEN_EMAIL:
        +	case GEN_DNS:
        +	case GEN_URI:
        +		a->d.ia5 = value;
        +		break;
        +
        +	case GEN_DIRNAME:
        +		a->d.dirn = value;
        +		break;
        +
        +	case GEN_IPADD:
        +		a->d.ip = value;
        +		break;
        +	
        +	case GEN_RID:
        +		a->d.rid = value;
        +		break;
        +		}
        +	a->type = type;
        +	}
        +
        +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
        +	{
        +	if (ptype)
        +		*ptype = a->type;
        +	switch(a->type)
        +		{
        +	case GEN_X400:
        +	case GEN_EDIPARTY:
        +		return a->d.other;
        +
        +	case GEN_OTHERNAME:
        +		return a->d.otherName;
        +
        +	case GEN_EMAIL:
        +	case GEN_DNS:
        +	case GEN_URI:
        +		return a->d.ia5;
        +
        +	case GEN_DIRNAME:
        +		return a->d.dirn;
        +
        +	case GEN_IPADD:
        +		return a->d.ip;
        +	
        +	case GEN_RID:
        +		return a->d.rid;
        +
        +	default:
        +		return NULL;
        +		}
        +	}
        +
        +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
        +				ASN1_OBJECT *oid, ASN1_TYPE *value)
        +	{
        +	OTHERNAME *oth;
        +	oth = OTHERNAME_new();
        +	if (!oth)
        +		return 0;
        +	oth->type_id = oid;
        +	oth->value = value;
        +	GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
        +	return 1;
        +	}
        +
        +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
        +				ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
        +	{
        +	if (gen->type != GEN_OTHERNAME)
        +		return 0;
        +	if (poid)
        +		*poid = gen->d.otherName->type_id;
        +	if (pvalue)
        +		*pvalue = gen->d.otherName->value;
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_ia5.c b/vendor/openssl/openssl/crypto/x509v3/v3_ia5.c
        new file mode 100644
        index 000000000..4ff12b52b
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_ia5.c
        @@ -0,0 +1,116 @@
        +/* v3_ia5.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
        +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
        +const X509V3_EXT_METHOD v3_ns_ia5_list[] = { 
        +EXT_IA5STRING(NID_netscape_base_url),
        +EXT_IA5STRING(NID_netscape_revocation_url),
        +EXT_IA5STRING(NID_netscape_ca_revocation_url),
        +EXT_IA5STRING(NID_netscape_renewal_url),
        +EXT_IA5STRING(NID_netscape_ca_policy_url),
        +EXT_IA5STRING(NID_netscape_ssl_server_name),
        +EXT_IA5STRING(NID_netscape_comment),
        +EXT_END
        +};
        +
        +
        +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
        +	     ASN1_IA5STRING *ia5)
        +{
        +	char *tmp;
        +	if(!ia5 || !ia5->length) return NULL;
        +	if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
        +		X509V3err(X509V3_F_I2S_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	memcpy(tmp, ia5->data, ia5->length);
        +	tmp[ia5->length] = 0;
        +	return tmp;
        +}
        +
        +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
        +	     X509V3_CTX *ctx, char *str)
        +{
        +	ASN1_IA5STRING *ia5;
        +	if(!str) {
        +		X509V3err(X509V3_F_S2I_ASN1_IA5STRING,X509V3_R_INVALID_NULL_ARGUMENT);
        +		return NULL;
        +	}
        +	if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
        +	if(!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str,
        +			    strlen(str))) {
        +		M_ASN1_IA5STRING_free(ia5);
        +		goto err;
        +	}
        +#ifdef CHARSET_EBCDIC
        +        ebcdic2ascii(ia5->data, ia5->data, ia5->length);
        +#endif /*CHARSET_EBCDIC*/
        +	return ia5;
        +	err:
        +	X509V3err(X509V3_F_S2I_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_info.c b/vendor/openssl/openssl/crypto/x509v3/v3_info.c
        new file mode 100644
        index 000000000..e1b8699f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_info.c
        @@ -0,0 +1,193 @@
        +/* v3_info.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
        +				AUTHORITY_INFO_ACCESS *ainfo,
        +						STACK_OF(CONF_VALUE) *ret);
        +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +
        +const X509V3_EXT_METHOD v3_info =
        +{ NID_info_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
        +0,0,0,0,
        +0,0,
        +(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
        +(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
        +0,0,
        +NULL};
        +
        +const X509V3_EXT_METHOD v3_sinfo =
        +{ NID_sinfo_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
        +0,0,0,0,
        +0,0,
        +(X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
        +(X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
        +0,0,
        +NULL};
        +
        +ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
        +	ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
        +	ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
        +} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
        +
        +ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
        +ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
        +
        +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
        +				AUTHORITY_INFO_ACCESS *ainfo,
        +						STACK_OF(CONF_VALUE) *ret)
        +{
        +	ACCESS_DESCRIPTION *desc;
        +	int i,nlen;
        +	char objtmp[80], *ntmp;
        +	CONF_VALUE *vtmp;
        +	for(i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
        +		desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
        +		ret = i2v_GENERAL_NAME(method, desc->location, ret);
        +		if(!ret) break;
        +		vtmp = sk_CONF_VALUE_value(ret, i);
        +		i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
        +		nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
        +		ntmp = OPENSSL_malloc(nlen);
        +		if(!ntmp) {
        +			X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
        +					ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +		}
        +		BUF_strlcpy(ntmp, objtmp, nlen);
        +		BUF_strlcat(ntmp, " - ", nlen);
        +		BUF_strlcat(ntmp, vtmp->name, nlen);
        +		OPENSSL_free(vtmp->name);
        +		vtmp->name = ntmp;
        +		
        +	}
        +	if(!ret) return sk_CONF_VALUE_new_null();
        +	return ret;
        +}
        +
        +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	AUTHORITY_INFO_ACCESS *ainfo = NULL;
        +	CONF_VALUE *cnf, ctmp;
        +	ACCESS_DESCRIPTION *acc;
        +	int i, objlen;
        +	char *objtmp, *ptmp;
        +	if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
        +		X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		if(!(acc = ACCESS_DESCRIPTION_new())
        +			|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
        +			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		ptmp = strchr(cnf->name, ';');
        +		if(!ptmp) {
        +			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,X509V3_R_INVALID_SYNTAX);
        +			goto err;
        +		}
        +		objlen = ptmp - cnf->name;
        +		ctmp.name = ptmp + 1;
        +		ctmp.value = cnf->value;
        +		if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
        +								 goto err; 
        +		if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
        +			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		strncpy(objtmp, cnf->name, objlen);
        +		objtmp[objlen] = 0;
        +		acc->method = OBJ_txt2obj(objtmp, 0);
        +		if(!acc->method) {
        +			X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,X509V3_R_BAD_OBJECT);
        +			ERR_add_error_data(2, "value=", objtmp);
        +			OPENSSL_free(objtmp);
        +			goto err;
        +		}
        +		OPENSSL_free(objtmp);
        +
        +	}
        +	return ainfo;
        +	err:
        +	sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
        +	return NULL;
        +}
        +
        +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a)
        +        {
        +	i2a_ASN1_OBJECT(bp, a->method);
        +#ifdef UNDEF
        +	i2a_GENERAL_NAME(bp, a->location);
        +#endif
        +	return 2;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_int.c b/vendor/openssl/openssl/crypto/x509v3/v3_int.c
        new file mode 100644
        index 000000000..4bfd14cf4
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_int.c
        @@ -0,0 +1,89 @@
        +/* v3_int.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509v3.h>
        +
        +const X509V3_EXT_METHOD v3_crl_num = { 
        +	NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
        +	0,0,0,0,
        +	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
        +	0,
        +	0,0,0,0, NULL};
        +
        +const X509V3_EXT_METHOD v3_delta_crl = { 
        +	NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
        +	0,0,0,0,
        +	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
        +	0,
        +	0,0,0,0, NULL};
        +
        +static void * s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
        +	{
        +	return s2i_ASN1_INTEGER(meth, value);
        +	}
        +
        +const X509V3_EXT_METHOD v3_inhibit_anyp = { 
        +	NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
        +	0,0,0,0,
        +	(X509V3_EXT_I2S)i2s_ASN1_INTEGER,
        +	(X509V3_EXT_S2I)s2i_asn1_int,
        +	0,0,0,0, NULL};
        +
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_lib.c b/vendor/openssl/openssl/crypto/x509v3/v3_lib.c
        new file mode 100644
        index 000000000..0f1e1d442
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_lib.c
        @@ -0,0 +1,309 @@
        +/* v3_lib.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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).
        + *
        + */
        +/* X509 v3 extension utilities */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +#include "ext_dat.h"
        +
        +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
        +
        +static int ext_cmp(const X509V3_EXT_METHOD * const *a,
        +		const X509V3_EXT_METHOD * const *b);
        +static void ext_list_free(X509V3_EXT_METHOD *ext);
        +
        +int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
        +{
        +	if(!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
        +		X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
        +		X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	return 1;
        +}
        +
        +static int ext_cmp(const X509V3_EXT_METHOD * const *a,
        +		   const X509V3_EXT_METHOD * const *b)
        +{
        +	return ((*a)->ext_nid - (*b)->ext_nid);
        +}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, const X509V3_EXT_METHOD *,
        +			   ext);
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
        +			     const X509V3_EXT_METHOD *, ext);
        +
        +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
        +{
        +	X509V3_EXT_METHOD tmp;
        +	const X509V3_EXT_METHOD *t = &tmp, * const *ret;
        +	int idx;
        +	if(nid < 0) return NULL;
        +	tmp.ext_nid = nid;
        +	ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
        +	if(ret) return *ret;
        +	if(!ext_list) return NULL;
        +	idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
        +	if(idx == -1) return NULL;
        +	return sk_X509V3_EXT_METHOD_value(ext_list, idx);
        +}
        +
        +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
        +{
        +	int nid;
        +	if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
        +	return X509V3_EXT_get_nid(nid);
        +}
        +
        +
        +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
        +{
        +	for(;extlist->ext_nid!=-1;extlist++) 
        +			if(!X509V3_EXT_add(extlist)) return 0;
        +	return 1;
        +}
        +
        +int X509V3_EXT_add_alias(int nid_to, int nid_from)
        +{
        +	const X509V3_EXT_METHOD *ext;
        +	X509V3_EXT_METHOD *tmpext;
        +
        +	if(!(ext = X509V3_EXT_get_nid(nid_from))) {
        +		X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND);
        +		return 0;
        +	}
        +	if(!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
        +		X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	*tmpext = *ext;
        +	tmpext->ext_nid = nid_to;
        +	tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
        +	return X509V3_EXT_add(tmpext);
        +}
        +
        +void X509V3_EXT_cleanup(void)
        +{
        +	sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
        +	ext_list = NULL;
        +}
        +
        +static void ext_list_free(X509V3_EXT_METHOD *ext)
        +{
        +	if(ext->ext_flags & X509V3_EXT_DYNAMIC) OPENSSL_free(ext);
        +}
        +
        +/* Legacy function: we don't need to add standard extensions
        + * any more because they are now kept in ext_dat.h.
        + */
        +
        +int X509V3_add_standard_extensions(void)
        +{
        +	return 1;
        +}
        +
        +/* Return an extension internal structure */
        +
        +void *X509V3_EXT_d2i(X509_EXTENSION *ext)
        +{
        +	const X509V3_EXT_METHOD *method;
        +	const unsigned char *p;
        +
        +	if(!(method = X509V3_EXT_get(ext))) return NULL;
        +	p = ext->value->data;
        +	if(method->it) return ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
        +	return method->d2i(NULL, &p, ext->value->length);
        +}
        +
        +/* Get critical flag and decoded version of extension from a NID.
        + * The "idx" variable returns the last found extension and can
        + * be used to retrieve multiple extensions of the same NID.
        + * However multiple extensions with the same NID is usually
        + * due to a badly encoded certificate so if idx is NULL we
        + * choke if multiple extensions exist.
        + * The "crit" variable is set to the critical value.
        + * The return value is the decoded extension or NULL on
        + * error. The actual error can have several different causes,
        + * the value of *crit reflects the cause:
        + * >= 0, extension found but not decoded (reflects critical value).
        + * -1 extension not found.
        + * -2 extension occurs more than once.
        + */
        +
        +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
        +{
        +	int lastpos, i;
        +	X509_EXTENSION *ex, *found_ex = NULL;
        +	if(!x) {
        +		if(idx) *idx = -1;
        +		if(crit) *crit = -1;
        +		return NULL;
        +	}
        +	if(idx) lastpos = *idx + 1;
        +	else lastpos = 0;
        +	if(lastpos < 0) lastpos = 0;
        +	for(i = lastpos; i < sk_X509_EXTENSION_num(x); i++)
        +	{
        +		ex = sk_X509_EXTENSION_value(x, i);
        +		if(OBJ_obj2nid(ex->object) == nid) {
        +			if(idx) {
        +				*idx = i;
        +				found_ex = ex;
        +				break;
        +			} else if(found_ex) {
        +				/* Found more than one */
        +				if(crit) *crit = -2;
        +				return NULL;
        +			}
        +			found_ex = ex;
        +		}
        +	}
        +	if(found_ex) {
        +		/* Found it */
        +		if(crit) *crit = X509_EXTENSION_get_critical(found_ex);
        +		return X509V3_EXT_d2i(found_ex);
        +	}
        +
        +	/* Extension not found */
        +	if(idx) *idx = -1;
        +	if(crit) *crit = -1;
        +	return NULL;
        +}
        +
        +/* This function is a general extension append, replace and delete utility.
        + * The precise operation is governed by the 'flags' value. The 'crit' and
        + * 'value' arguments (if relevant) are the extensions internal structure.
        + */
        +
        +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
        +					int crit, unsigned long flags)
        +{
        +	int extidx = -1;
        +	int errcode;
        +	X509_EXTENSION *ext, *extmp;
        +	unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
        +
        +	/* If appending we don't care if it exists, otherwise
        +	 * look for existing extension.
        +	 */
        +	if(ext_op != X509V3_ADD_APPEND)
        +		extidx = X509v3_get_ext_by_NID(*x, nid, -1);
        +
        +	/* See if extension exists */
        +	if(extidx >= 0) {
        +		/* If keep existing, nothing to do */
        +		if(ext_op == X509V3_ADD_KEEP_EXISTING)
        +			return 1;
        +		/* If default then its an error */
        +		if(ext_op == X509V3_ADD_DEFAULT) {
        +			errcode = X509V3_R_EXTENSION_EXISTS;
        +			goto err;
        +		}
        +		/* If delete, just delete it */
        +		if(ext_op == X509V3_ADD_DELETE) {
        +			if(!sk_X509_EXTENSION_delete(*x, extidx)) return -1;
        +			return 1;
        +		}
        +	} else {
        +		/* If replace existing or delete, error since 
        +		 * extension must exist
        +		 */
        +		if((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
        +		   (ext_op == X509V3_ADD_DELETE)) {
        +			errcode = X509V3_R_EXTENSION_NOT_FOUND;
        +			goto err;
        +		}
        +	}
        +
        +	/* If we get this far then we have to create an extension:
        +	 * could have some flags for alternative encoding schemes...
        +	 */
        +
        +	ext = X509V3_EXT_i2d(nid, crit, value);
        +
        +	if(!ext) {
        +		X509V3err(X509V3_F_X509V3_ADD1_I2D, X509V3_R_ERROR_CREATING_EXTENSION);
        +		return 0;
        +	}
        +
        +	/* If extension exists replace it.. */
        +	if(extidx >= 0) {
        +		extmp = sk_X509_EXTENSION_value(*x, extidx);
        +		X509_EXTENSION_free(extmp);
        +		if(!sk_X509_EXTENSION_set(*x, extidx, ext)) return -1;
        +		return 1;
        +	}
        +
        +	if(!*x && !(*x = sk_X509_EXTENSION_new_null())) return -1;
        +	if(!sk_X509_EXTENSION_push(*x, ext)) return -1;
        +
        +	return 1;
        +
        +	err:
        +	if(!(flags & X509V3_ADD_SILENT))
        +		X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
        +	return 0;
        +}
        +
        +IMPLEMENT_STACK_OF(X509V3_EXT_METHOD)
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_ncons.c b/vendor/openssl/openssl/crypto/x509v3/v3_ncons.c
        new file mode 100644
        index 000000000..a01dc64dd
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_ncons.c
        @@ -0,0 +1,505 @@
        +/* v3_ncons.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
        +				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 
        +				void *a, BIO *bp, int ind);
        +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
        +				   STACK_OF(GENERAL_SUBTREE) *trees,
        +				   BIO *bp, int ind, char *name);
        +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
        +
        +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
        +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
        +static int nc_dn(X509_NAME *sub, X509_NAME *nm);
        +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
        +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
        +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
        +
        +const X509V3_EXT_METHOD v3_name_constraints = {
        +	NID_name_constraints, 0,
        +	ASN1_ITEM_ref(NAME_CONSTRAINTS),
        +	0,0,0,0,
        +	0,0,
        +	0, v2i_NAME_CONSTRAINTS,
        +	i2r_NAME_CONSTRAINTS,0,
        +	NULL
        +};
        +
        +ASN1_SEQUENCE(GENERAL_SUBTREE) = {
        +	ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
        +	ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
        +	ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
        +} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
        +
        +ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
        +	ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
        +							GENERAL_SUBTREE, 0),
        +	ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
        +							GENERAL_SUBTREE, 1),
        +} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
        +	
        +
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
        +
        +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
        +				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +	{
        +	int i;
        +	CONF_VALUE tval, *val;
        +	STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
        +	NAME_CONSTRAINTS *ncons = NULL;
        +	GENERAL_SUBTREE *sub = NULL;
        +	ncons = NAME_CONSTRAINTS_new();
        +	if (!ncons)
        +		goto memerr;
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
        +		{
        +		val = sk_CONF_VALUE_value(nval, i);
        +		if (!strncmp(val->name, "permitted", 9) && val->name[9])
        +			{
        +			ptree = &ncons->permittedSubtrees;
        +			tval.name = val->name + 10;
        +			}
        +		else if (!strncmp(val->name, "excluded", 8) && val->name[8])
        +			{
        +			ptree = &ncons->excludedSubtrees;
        +			tval.name = val->name + 9;
        +			}
        +		else
        +			{
        +			X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
        +			goto err;
        +			}
        +		tval.value = val->value;
        +		sub = GENERAL_SUBTREE_new();
        +		if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
        +			goto err;
        +		if (!*ptree)
        +			*ptree = sk_GENERAL_SUBTREE_new_null();
        +		if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
        +			goto memerr;
        +		sub = NULL;
        +		}
        +
        +	return ncons;
        +
        +	memerr:
        +	X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
        +	err:
        +	if (ncons)
        +		NAME_CONSTRAINTS_free(ncons);
        +	if (sub)
        +		GENERAL_SUBTREE_free(sub);
        +
        +	return NULL;
        +	}
        +			
        +
        +	
        +
        +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
        +				BIO *bp, int ind)
        +	{
        +	NAME_CONSTRAINTS *ncons = a;
        +	do_i2r_name_constraints(method, ncons->permittedSubtrees,
        +					bp, ind, "Permitted");
        +	do_i2r_name_constraints(method, ncons->excludedSubtrees,
        +					bp, ind, "Excluded");
        +	return 1;
        +	}
        +
        +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
        +				   STACK_OF(GENERAL_SUBTREE) *trees,
        +				   BIO *bp, int ind, char *name)
        +	{
        +	GENERAL_SUBTREE *tree;
        +	int i;
        +	if (sk_GENERAL_SUBTREE_num(trees) > 0)
        +		BIO_printf(bp, "%*s%s:\n", ind, "", name);
        +	for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
        +		{
        +		tree = sk_GENERAL_SUBTREE_value(trees, i);
        +		BIO_printf(bp, "%*s", ind + 2, "");
        +		if (tree->base->type == GEN_IPADD)
        +			print_nc_ipadd(bp, tree->base->d.ip);
        +		else
        +			GENERAL_NAME_print(bp, tree->base);
        +		BIO_puts(bp, "\n");
        +		}
        +	return 1;
        +	}
        +
        +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
        +	{
        +	int i, len;
        +	unsigned char *p;
        +	p = ip->data;
        +	len = ip->length;
        +	BIO_puts(bp, "IP:");
        +	if(len == 8)
        +		{
        +		BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
        +				p[0], p[1], p[2], p[3],
        +				p[4], p[5], p[6], p[7]);
        +		}
        +	else if(len == 32)
        +		{
        +		for (i = 0; i < 16; i++)
        +			{
        +			BIO_printf(bp, "%X", p[0] << 8 | p[1]);
        +			p += 2;
        +			if (i == 7)
        +				BIO_puts(bp, "/");
        +			else if (i != 15)
        +				BIO_puts(bp, ":");
        +			}
        +		}
        +	else
        +		BIO_printf(bp, "IP Address:<invalid>");
        +	return 1;
        +	}
        +
        +/* Check a certificate conforms to a specified set of constraints.
        + * Return values:
        + *  X509_V_OK: All constraints obeyed.
        + *  X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
        + *  X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
        + *  X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
        + *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:  Unsupported constraint type.
        + *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
        + *  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
        +
        + */
        +
        +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
        +	{
        +	int r, i;
        +	X509_NAME *nm;
        +
        +	nm = X509_get_subject_name(x);
        +
        +	if (X509_NAME_entry_count(nm) > 0)
        +		{
        +		GENERAL_NAME gntmp;
        +		gntmp.type = GEN_DIRNAME;
        +		gntmp.d.directoryName = nm;
        +
        +		r = nc_match(&gntmp, nc);
        +
        +		if (r != X509_V_OK)
        +			return r;
        +
        +		gntmp.type = GEN_EMAIL;
        +
        +
        +		/* Process any email address attributes in subject name */
        +
        +		for (i = -1;;)
        +			{
        +			X509_NAME_ENTRY *ne;
        +			i = X509_NAME_get_index_by_NID(nm,
        +						       NID_pkcs9_emailAddress,
        +						       i);
        +			if (i == -1)
        +				break;
        +			ne = X509_NAME_get_entry(nm, i);
        +			gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
        +			if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
        +				return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
        +
        +			r = nc_match(&gntmp, nc);
        +
        +			if (r != X509_V_OK)
        +				return r;
        +			}
        +		
        +		}
        +
        +	for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
        +		{
        +		GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
        +		r = nc_match(gen, nc);
        +		if (r != X509_V_OK)
        +			return r;
        +		}
        +
        +	return X509_V_OK;
        +
        +	}
        +
        +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
        +	{
        +	GENERAL_SUBTREE *sub;
        +	int i, r, match = 0;
        +
        +	/* Permitted subtrees: if any subtrees exist of matching the type
        +	 * at least one subtree must match.
        +	 */
        +
        +	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
        +		{
        +		sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
        +		if (gen->type != sub->base->type)
        +			continue;
        +		if (sub->minimum || sub->maximum)
        +			return X509_V_ERR_SUBTREE_MINMAX;
        +		/* If we already have a match don't bother trying any more */
        +		if (match == 2)
        +			continue;
        +		if (match == 0)
        +			match = 1;
        +		r = nc_match_single(gen, sub->base);
        +		if (r == X509_V_OK)
        +			match = 2;
        +		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
        +			return r;
        +		}
        +
        +	if (match == 1)
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +
        +	/* Excluded subtrees: must not match any of these */
        +
        +	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
        +		{
        +		sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
        +		if (gen->type != sub->base->type)
        +			continue;
        +		if (sub->minimum || sub->maximum)
        +			return X509_V_ERR_SUBTREE_MINMAX;
        +
        +		r = nc_match_single(gen, sub->base);
        +		if (r == X509_V_OK)
        +			return X509_V_ERR_EXCLUDED_VIOLATION;
        +		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
        +			return r;
        +
        +		}
        +
        +	return X509_V_OK;
        +
        +	}
        +
        +static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
        +	{
        +	switch(base->type)
        +		{
        +		case GEN_DIRNAME:
        +		return nc_dn(gen->d.directoryName, base->d.directoryName);
        +
        +		case GEN_DNS:
        +		return nc_dns(gen->d.dNSName, base->d.dNSName);
        +
        +		case GEN_EMAIL:
        +		return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
        +
        +		case GEN_URI:
        +		return nc_uri(gen->d.uniformResourceIdentifier,
        +					base->d.uniformResourceIdentifier);
        +
        +		default:
        +		return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
        +		}
        +
        +	}
        +
        +/* directoryName name constraint matching.
        + * The canonical encoding of X509_NAME makes this comparison easy. It is
        + * matched if the subtree is a subset of the name.
        + */
        +
        +static int nc_dn(X509_NAME *nm, X509_NAME *base)
        +	{
        +	/* Ensure canonical encodings are up to date.  */
        +	if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
        +		return X509_V_ERR_OUT_OF_MEM;
        +	if (base->modified && i2d_X509_NAME(base, NULL) < 0)
        +		return X509_V_ERR_OUT_OF_MEM;
        +	if (base->canon_enclen > nm->canon_enclen)
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +	if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +	return X509_V_OK;
        +	}
        +
        +static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
        +	{
        +	char *baseptr = (char *)base->data;
        +	char *dnsptr = (char *)dns->data;
        +	/* Empty matches everything */
        +	if (!*baseptr)
        +		return X509_V_OK;
        +	/* Otherwise can add zero or more components on the left so
        +	 * compare RHS and if dns is longer and expect '.' as preceding
        +	 * character.
        +	 */
        +	if (dns->length > base->length)
        +		{
        +		dnsptr += dns->length - base->length;
        +		if (dnsptr[-1] != '.')
        +			return X509_V_ERR_PERMITTED_VIOLATION;
        +		}
        +
        +	if (strcasecmp(baseptr, dnsptr))
        +			return X509_V_ERR_PERMITTED_VIOLATION;
        +
        +	return X509_V_OK;
        +
        +	}
        +
        +static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
        +	{
        +	const char *baseptr = (char *)base->data;
        +	const char *emlptr = (char *)eml->data;
        +
        +	const char *baseat = strchr(baseptr, '@');
        +	const char *emlat = strchr(emlptr, '@');
        +	if (!emlat)
        +		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
        +	/* Special case: inital '.' is RHS match */
        +	if (!baseat && (*baseptr == '.'))
        +		{
        +		if (eml->length > base->length)
        +			{
        +			emlptr += eml->length - base->length;
        +			if (!strcasecmp(baseptr, emlptr))
        +				return X509_V_OK;
        +			}
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +		}
        +
        +	/* If we have anything before '@' match local part */
        +
        +	if (baseat)
        +		{
        +		if (baseat != baseptr)
        +			{
        +			if ((baseat - baseptr) != (emlat - emlptr))
        +				return X509_V_ERR_PERMITTED_VIOLATION;
        +			/* Case sensitive match of local part */
        +			if (strncmp(baseptr, emlptr, emlat - emlptr))
        +				return X509_V_ERR_PERMITTED_VIOLATION;
        +			}
        +		/* Position base after '@' */
        +		baseptr = baseat + 1;
        +		}
        +	emlptr = emlat + 1;
        +	/* Just have hostname left to match: case insensitive */
        +	if (strcasecmp(baseptr, emlptr))
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +
        +	return X509_V_OK;
        +
        +	}
        +
        +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
        +	{
        +	const char *baseptr = (char *)base->data;
        +	const char *hostptr = (char *)uri->data;
        +	const char *p = strchr(hostptr, ':');
        +	int hostlen;
        +	/* Check for foo:// and skip past it */
        +	if (!p || (p[1] != '/') || (p[2] != '/'))
        +		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
        +	hostptr = p + 3;
        +
        +	/* Determine length of hostname part of URI */
        +
        +	/* Look for a port indicator as end of hostname first */
        +
        +	p = strchr(hostptr, ':');
        +	/* Otherwise look for trailing slash */
        +	if (!p)
        +		p = strchr(hostptr, '/');
        +
        +	if (!p)
        +		hostlen = strlen(hostptr);
        +	else
        +		hostlen = p - hostptr;
        +
        +	if (hostlen == 0)
        +		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
        +
        +	/* Special case: inital '.' is RHS match */
        +	if (*baseptr == '.')
        +		{
        +		if (hostlen > base->length)
        +			{
        +			p = hostptr + hostlen - base->length;
        +			if (!strncasecmp(p, baseptr, base->length))
        +				return X509_V_OK;
        +			}
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +		}
        +
        +	if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
        +		return X509_V_ERR_PERMITTED_VIOLATION;
        +
        +	return X509_V_OK;
        +
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_ocsp.c b/vendor/openssl/openssl/crypto/x509v3/v3_ocsp.c
        new file mode 100644
        index 000000000..0c165af31
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_ocsp.c
        @@ -0,0 +1,289 @@
        +/* v3_ocsp.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 OPENSSL_NO_OCSP
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/x509v3.h>
        +
        +/* OCSP extensions and a couple of CRL entry extensions
        + */
        +
        +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
        +			  BIO *out, int indent);
        +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
        +			    BIO *out, int indent);
        +static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
        +		      int indent);
        +
        +static void *ocsp_nonce_new(void);
        +static int i2d_ocsp_nonce(void *a, unsigned char **pp);
        +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
        +static void ocsp_nonce_free(void *a);
        +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
        +			  BIO *out, int indent);
        +
        +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
        +			    void *nocheck, BIO *out, int indent);
        +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +			      const char *str);
        +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
        +			       BIO *bp, int ind);
        +
        +const X509V3_EXT_METHOD v3_ocsp_crlid = {
        +	NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
        +	0,0,0,0,
        +	0,0,
        +	0,0,
        +	i2r_ocsp_crlid,0,
        +	NULL
        +};
        +
        +const X509V3_EXT_METHOD v3_ocsp_acutoff = {
        +	NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
        +	0,0,0,0,
        +	0,0,
        +	0,0,
        +	i2r_ocsp_acutoff,0,
        +	NULL
        +};
        +
        +const X509V3_EXT_METHOD v3_crl_invdate = {
        +	NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
        +	0,0,0,0,
        +	0,0,
        +	0,0,
        +	i2r_ocsp_acutoff,0,
        +	NULL
        +};
        +
        +const X509V3_EXT_METHOD v3_crl_hold = {
        +	NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
        +	0,0,0,0,
        +	0,0,
        +	0,0,
        +	i2r_object,0,
        +	NULL
        +};
        +
        +const X509V3_EXT_METHOD v3_ocsp_nonce = {
        +	NID_id_pkix_OCSP_Nonce, 0, NULL,
        +	ocsp_nonce_new,
        +	ocsp_nonce_free,
        +	d2i_ocsp_nonce,
        +	i2d_ocsp_nonce,
        +	0,0,
        +	0,0,
        +	i2r_ocsp_nonce,0,
        +	NULL
        +};
        +
        +const X509V3_EXT_METHOD v3_ocsp_nocheck = {
        +	NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
        +	0,0,0,0,
        +	0,s2i_ocsp_nocheck,
        +	0,0,
        +	i2r_ocsp_nocheck,0,
        +	NULL
        +};
        +
        +const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
        +	NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
        +	0,0,0,0,
        +	0,0,
        +	0,0,
        +	i2r_ocsp_serviceloc,0,
        +	NULL
        +};
        +
        +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
        +			  int ind)
        +{
        +	OCSP_CRLID *a = in;
        +	if (a->crlUrl)
        +	        {
        +		if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) goto err;
        +		if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
        +		if (BIO_write(bp, "\n", 1) <= 0) goto err;
        +		}
        +	if (a->crlNum)
        +	        {
        +		if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) goto err;
        +		if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) goto err;
        +		if (BIO_write(bp, "\n", 1) <= 0) goto err;
        +		}
        +	if (a->crlTime)
        +	        {
        +		if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) goto err;
        +		if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
        +		if (BIO_write(bp, "\n", 1) <= 0) goto err;
        +		}
        +	return 1;
        +	err:
        +	return 0;
        +}
        +
        +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
        +			    BIO *bp, int ind)
        +{
        +	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
        +	if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
        +	return 1;
        +}
        +
        +
        +static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
        +		      int ind)
        +{
        +	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
        +	if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
        +	return 1;
        +}
        +
        +/* OCSP nonce. This is needs special treatment because it doesn't have
        + * an ASN1 encoding at all: it just contains arbitrary data.
        + */
        +
        +static void *ocsp_nonce_new(void)
        +{
        +	return ASN1_OCTET_STRING_new();
        +}
        +
        +static int i2d_ocsp_nonce(void *a, unsigned char **pp)
        +{
        +	ASN1_OCTET_STRING *os = a;
        +	if(pp) {
        +		memcpy(*pp, os->data, os->length);
        +		*pp += os->length;
        +	}
        +	return os->length;
        +}
        +
        +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
        +{
        +	ASN1_OCTET_STRING *os, **pos;
        +	pos = a;
        +	if(!pos || !*pos) os = ASN1_OCTET_STRING_new();
        +	else os = *pos;
        +	if(!ASN1_OCTET_STRING_set(os, *pp, length)) goto err;
        +
        +	*pp += length;
        +
        +	if(pos) *pos = os;
        +	return os;
        +
        +	err:
        +	if(os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os);
        +	OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +}
        +
        +static void ocsp_nonce_free(void *a)
        +{
        +	M_ASN1_OCTET_STRING_free(a);
        +}
        +
        +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
        +			  BIO *out, int indent)
        +{
        +	if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
        +	if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
        +	return 1;
        +}
        +
        +/* Nocheck is just a single NULL. Don't print anything and always set it */
        +
        +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
        +			    BIO *out, int indent)
        +{
        +	return 1;
        +}
        +
        +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +			      const char *str)
        +{
        +	return ASN1_NULL_new();
        +}
        +
        +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
        +			       BIO *bp, int ind)
        +        {
        +	int i;
        +	OCSP_SERVICELOC *a = in;
        +	ACCESS_DESCRIPTION *ad;
        +
        +        if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) goto err;
        +        if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) goto err;
        +	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++)
        +	        {
        +				ad = sk_ACCESS_DESCRIPTION_value(a->locator,i);
        +				if (BIO_printf(bp, "\n%*s", (2*ind), "") <= 0) 
        +					goto err;
        +				if(i2a_ASN1_OBJECT(bp, ad->method) <= 0) goto err;
        +				if(BIO_puts(bp, " - ") <= 0) goto err;
        +				if(GENERAL_NAME_print(bp, ad->location) <= 0) goto err;
        +		}
        +	return 1;
        +err:
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_pci.c b/vendor/openssl/openssl/crypto/x509v3/v3_pci.c
        new file mode 100644
        index 000000000..0dcfa004f
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_pci.c
        @@ -0,0 +1,328 @@
        +/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Contributed to the OpenSSL Project 2004
        + * by Richard Levitte (richard@levitte.org)
        + */
        +/* Copyright (c) 2004 Kungliga Tekniska Högskolan
        + * (Royal Institute of Technology, Stockholm, Sweden).
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + *
        + * 3. Neither the name of the Institute nor the names of its contributors
        + *    may be used to endorse or promote products derived from this software
        + *    without specific prior written permission.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
        +	BIO *out, int indent);
        +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
        +	X509V3_CTX *ctx, char *str);
        +
        +const X509V3_EXT_METHOD v3_pci =
        +	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
        +	  0,0,0,0,
        +	  0,0,
        +	  NULL, NULL,
        +	  (X509V3_EXT_I2R)i2r_pci,
        +	  (X509V3_EXT_R2I)r2i_pci,
        +	  NULL,
        +	};
        +
        +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
        +	BIO *out, int indent)
        +	{
        +	BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
        +	if (pci->pcPathLengthConstraint)
        +	  i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
        +	else
        +	  BIO_printf(out, "infinite");
        +	BIO_puts(out, "\n");
        +	BIO_printf(out, "%*sPolicy Language: ", indent, "");
        +	i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
        +	BIO_puts(out, "\n");
        +	if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
        +	  BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
        +		     pci->proxyPolicy->policy->data);
        +	return 1;
        +	}
        +
        +static int process_pci_value(CONF_VALUE *val,
        +	ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
        +	ASN1_OCTET_STRING **policy)
        +	{
        +	int free_policy = 0;
        +
        +	if (strcmp(val->name, "language") == 0)
        +		{
        +		if (*language)
        +			{
        +			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
        +			X509V3_conf_err(val);
        +			return 0;
        +			}
        +		if (!(*language = OBJ_txt2obj(val->value, 0)))
        +			{
        +			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
        +			X509V3_conf_err(val);
        +			return 0;
        +			}
        +		}
        +	else if (strcmp(val->name, "pathlen") == 0)
        +		{
        +		if (*pathlen)
        +			{
        +			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
        +			X509V3_conf_err(val);
        +			return 0;
        +			}
        +		if (!X509V3_get_value_int(val, pathlen))
        +			{
        +			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
        +			X509V3_conf_err(val);
        +			return 0;
        +			}
        +		}
        +	else if (strcmp(val->name, "policy") == 0)
        +		{
        +		unsigned char *tmp_data = NULL;
        +		long val_len;
        +		if (!*policy)
        +			{
        +			*policy = ASN1_OCTET_STRING_new();
        +			if (!*policy)
        +				{
        +				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
        +				X509V3_conf_err(val);
        +				return 0;
        +				}
        +			free_policy = 1;
        +			}
        +		if (strncmp(val->value, "hex:", 4) == 0)
        +			{
        +			unsigned char *tmp_data2 =
        +				string_to_hex(val->value + 4, &val_len);
        +
        +			if (!tmp_data2) 
        +				{
        +				X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT);
        +				X509V3_conf_err(val);
        +				goto err;
        +				}
        +
        +			tmp_data = OPENSSL_realloc((*policy)->data,
        +				(*policy)->length + val_len + 1);
        +			if (tmp_data)
        +				{
        +				(*policy)->data = tmp_data;
        +				memcpy(&(*policy)->data[(*policy)->length],
        +					tmp_data2, val_len);
        +				(*policy)->length += val_len;
        +				(*policy)->data[(*policy)->length] = '\0';
        +				}
        +			else
        +				{
        +				OPENSSL_free(tmp_data2);
        +				/* realloc failure implies the original data space is b0rked too! */
        +				(*policy)->data = NULL;
        +				(*policy)->length = 0;
        +				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
        +				X509V3_conf_err(val);
        +				goto err;
        +				}
        +			OPENSSL_free(tmp_data2);
        +			}
        +		else if (strncmp(val->value, "file:", 5) == 0)
        +			{
        +			unsigned char buf[2048];
        +			int n;
        +			BIO *b = BIO_new_file(val->value + 5, "r");
        +			if (!b)
        +				{
        +				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
        +				X509V3_conf_err(val);
        +				goto err;
        +				}
        +			while((n = BIO_read(b, buf, sizeof(buf))) > 0
        +				|| (n == 0 && BIO_should_retry(b)))
        +				{
        +				if (!n) continue;
        +
        +				tmp_data = OPENSSL_realloc((*policy)->data,
        +					(*policy)->length + n + 1);
        +
        +				if (!tmp_data)
        +					break;
        +
        +				(*policy)->data = tmp_data;
        +				memcpy(&(*policy)->data[(*policy)->length],
        +					buf, n);
        +				(*policy)->length += n;
        +				(*policy)->data[(*policy)->length] = '\0';
        +				}
        +			BIO_free_all(b);
        +
        +			if (n < 0)
        +				{
        +				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
        +				X509V3_conf_err(val);
        +				goto err;
        +				}
        +			}
        +		else if (strncmp(val->value, "text:", 5) == 0)
        +			{
        +			val_len = strlen(val->value + 5);
        +			tmp_data = OPENSSL_realloc((*policy)->data,
        +				(*policy)->length + val_len + 1);
        +			if (tmp_data)
        +				{
        +				(*policy)->data = tmp_data;
        +				memcpy(&(*policy)->data[(*policy)->length],
        +					val->value + 5, val_len);
        +				(*policy)->length += val_len;
        +				(*policy)->data[(*policy)->length] = '\0';
        +				}
        +			else
        +				{
        +				/* realloc failure implies the original data space is b0rked too! */
        +				(*policy)->data = NULL;
        +				(*policy)->length = 0;
        +				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
        +				X509V3_conf_err(val);
        +				goto err;
        +				}
        +			}
        +		else
        +			{
        +			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
        +			X509V3_conf_err(val);
        +			goto err;
        +			}
        +		if (!tmp_data)
        +			{
        +			X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
        +			X509V3_conf_err(val);
        +			goto err;
        +			}
        +		}
        +	return 1;
        +err:
        +	if (free_policy)
        +		{
        +		ASN1_OCTET_STRING_free(*policy);
        +		*policy = NULL;
        +		}
        +	return 0;
        +	}
        +
        +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
        +	X509V3_CTX *ctx, char *value)
        +	{
        +	PROXY_CERT_INFO_EXTENSION *pci = NULL;
        +	STACK_OF(CONF_VALUE) *vals;
        +	ASN1_OBJECT *language = NULL;
        +	ASN1_INTEGER *pathlen = NULL;
        +	ASN1_OCTET_STRING *policy = NULL;
        +	int i, j;
        +
        +	vals = X509V3_parse_list(value);
        +	for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
        +		{
        +		CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
        +		if (!cnf->name || (*cnf->name != '@' && !cnf->value))
        +			{
        +			X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING);
        +			X509V3_conf_err(cnf);
        +			goto err;
        +			}
        +		if (*cnf->name == '@')
        +			{
        +			STACK_OF(CONF_VALUE) *sect;
        +			int success_p = 1;
        +
        +			sect = X509V3_get_section(ctx, cnf->name + 1);
        +			if (!sect)
        +				{
        +				X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION);
        +				X509V3_conf_err(cnf);
        +				goto err;
        +				}
        +			for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
        +				{
        +				success_p =
        +					process_pci_value(sk_CONF_VALUE_value(sect, j),
        +						&language, &pathlen, &policy);
        +				}
        +			X509V3_section_free(ctx, sect);
        +			if (!success_p)
        +				goto err;
        +			}
        +		else
        +			{
        +			if (!process_pci_value(cnf,
        +					&language, &pathlen, &policy))
        +				{
        +				X509V3_conf_err(cnf);
        +				goto err;
        +				}
        +			}
        +		}
        +
        +	/* Language is mandatory */
        +	if (!language)
        +		{
        +		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
        +		goto err;
        +		}
        +	i = OBJ_obj2nid(language);
        +	if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
        +		{
        +		X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
        +		goto err;
        +		}
        +
        +	pci = PROXY_CERT_INFO_EXTENSION_new();
        +	if (!pci)
        +		{
        +		X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	pci->proxyPolicy->policyLanguage = language; language = NULL;
        +	pci->proxyPolicy->policy = policy; policy = NULL;
        +	pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
        +	goto end;
        +err:
        +	if (language) { ASN1_OBJECT_free(language); language = NULL; }
        +	if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
        +	if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
        +	if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
        +end:
        +	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
        +	return pci;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_pcia.c b/vendor/openssl/openssl/crypto/x509v3/v3_pcia.c
        new file mode 100644
        index 000000000..bb362e0e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_pcia.c
        @@ -0,0 +1,55 @@
        +/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */
        +/* Contributed to the OpenSSL Project 2004
        + * by Richard Levitte (richard@levitte.org)
        + */
        +/* Copyright (c) 2004 Kungliga Tekniska Högskolan
        + * (Royal Institute of Technology, Stockholm, Sweden).
        + * All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + *
        + * 3. Neither the name of the Institute nor the names of its contributors
        + *    may be used to endorse or promote products derived from this software
        + *    without specific prior written permission.
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + */
        +
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +ASN1_SEQUENCE(PROXY_POLICY) =
        +	{
        +	ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
        +	ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(PROXY_POLICY)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
        +
        +ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
        +	{
        +	ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
        +	ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
        +} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_pcons.c b/vendor/openssl/openssl/crypto/x509v3/v3_pcons.c
        new file mode 100644
        index 000000000..30ca65235
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_pcons.c
        @@ -0,0 +1,140 @@
        +/* v3_pcons.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static STACK_OF(CONF_VALUE) *
        +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
        +		       STACK_OF(CONF_VALUE) *extlist);
        +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
        +				    X509V3_CTX *ctx,
        +				    STACK_OF(CONF_VALUE) *values);
        +
        +const X509V3_EXT_METHOD v3_policy_constraints = {
        +NID_policy_constraints, 0,
        +ASN1_ITEM_ref(POLICY_CONSTRAINTS),
        +0,0,0,0,
        +0,0,
        +i2v_POLICY_CONSTRAINTS,
        +v2i_POLICY_CONSTRAINTS,
        +NULL,NULL,
        +NULL
        +};
        +
        +ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
        +	ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
        +	ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
        +} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
        +
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
        +
        +
        +static STACK_OF(CONF_VALUE) *
        +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
        +		       STACK_OF(CONF_VALUE) *extlist)
        +{
        +	POLICY_CONSTRAINTS *pcons = a;
        +	X509V3_add_value_int("Require Explicit Policy",
        +			pcons->requireExplicitPolicy, &extlist);
        +	X509V3_add_value_int("Inhibit Policy Mapping",
        +			pcons->inhibitPolicyMapping, &extlist);
        +	return extlist;
        +}
        +
        +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
        +				    X509V3_CTX *ctx,
        +				    STACK_OF(CONF_VALUE) *values)
        +{
        +	POLICY_CONSTRAINTS *pcons=NULL;
        +	CONF_VALUE *val;
        +	int i;
        +	if(!(pcons = POLICY_CONSTRAINTS_new())) {
        +		X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
        +		val = sk_CONF_VALUE_value(values, i);
        +		if(!strcmp(val->name, "requireExplicitPolicy")) {
        +			if(!X509V3_get_value_int(val,
        +				&pcons->requireExplicitPolicy)) goto err;
        +		} else if(!strcmp(val->name, "inhibitPolicyMapping")) {
        +			if(!X509V3_get_value_int(val,
        +				&pcons->inhibitPolicyMapping)) goto err;
        +		} else {
        +			X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
        +			X509V3_conf_err(val);
        +			goto err;
        +		}
        +	}
        +	if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
        +		X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
        +		goto err;
        +	}
        +
        +	return pcons;
        +	err:
        +	POLICY_CONSTRAINTS_free(pcons);
        +	return NULL;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_pku.c b/vendor/openssl/openssl/crypto/x509v3/v3_pku.c
        new file mode 100644
        index 000000000..076f3ff48
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_pku.c
        @@ -0,0 +1,108 @@
        +/* v3_pku.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
        +/*
        +static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
        +*/
        +const X509V3_EXT_METHOD v3_pkey_usage_period = {
        +NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
        +0,0,0,0,
        +0,0,0,0,
        +(X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
        +NULL
        +};
        +
        +ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
        +	ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
        +	ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
        +} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
        +
        +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
        +	     PKEY_USAGE_PERIOD *usage, BIO *out, int indent)
        +{
        +	BIO_printf(out, "%*s", indent, "");
        +	if(usage->notBefore) {
        +		BIO_write(out, "Not Before: ", 12);
        +		ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
        +		if(usage->notAfter) BIO_write(out, ", ", 2);
        +	}
        +	if(usage->notAfter) {
        +		BIO_write(out, "Not After: ", 11);
        +		ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
        +	}
        +	return 1;
        +}
        +
        +/*
        +static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
        +X509V3_EXT_METHOD *method;
        +X509V3_CTX *ctx;
        +STACK_OF(CONF_VALUE) *values;
        +{
        +return NULL;
        +}
        +*/
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_pmaps.c b/vendor/openssl/openssl/crypto/x509v3/v3_pmaps.c
        new file mode 100644
        index 000000000..865bcd398
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_pmaps.c
        @@ -0,0 +1,155 @@
        +/* v3_pmaps.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1t.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +static STACK_OF(CONF_VALUE) *
        +i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
        +		    STACK_OF(CONF_VALUE) *extlist);
        +
        +const X509V3_EXT_METHOD v3_policy_mappings = {
        +	NID_policy_mappings, 0,
        +	ASN1_ITEM_ref(POLICY_MAPPINGS),
        +	0,0,0,0,
        +	0,0,
        +	i2v_POLICY_MAPPINGS,
        +	v2i_POLICY_MAPPINGS,
        +	0,0,
        +	NULL
        +};
        +
        +ASN1_SEQUENCE(POLICY_MAPPING) = {
        +	ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
        +	ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
        +} ASN1_SEQUENCE_END(POLICY_MAPPING)
        +
        +ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = 
        +	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
        +								POLICY_MAPPING)
        +ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
        +
        +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
        +
        +
        +static STACK_OF(CONF_VALUE) *
        +i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
        +		    STACK_OF(CONF_VALUE) *ext_list)
        +{
        +	POLICY_MAPPINGS *pmaps = a;
        +	POLICY_MAPPING *pmap;
        +	int i;
        +	char obj_tmp1[80];
        +	char obj_tmp2[80];
        +	for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
        +		pmap = sk_POLICY_MAPPING_value(pmaps, i);
        +		i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
        +		i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
        +		X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
        +	}
        +	return ext_list;
        +}
        +
        +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
        +{
        +	POLICY_MAPPINGS *pmaps;
        +	POLICY_MAPPING *pmap;
        +	ASN1_OBJECT *obj1, *obj2;
        +	CONF_VALUE *val;
        +	int i;
        +
        +	if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
        +		X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		val = sk_CONF_VALUE_value(nval, i);
        +		if(!val->value || !val->name) {
        +			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
        +			X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
        +			X509V3_conf_err(val);
        +			return NULL;
        +		}
        +		obj1 = OBJ_txt2obj(val->name, 0);
        +		obj2 = OBJ_txt2obj(val->value, 0);
        +		if(!obj1 || !obj2) {
        +			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
        +			X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
        +			X509V3_conf_err(val);
        +			return NULL;
        +		}
        +		pmap = POLICY_MAPPING_new();
        +		if (!pmap) {
        +			sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
        +			X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
        +			return NULL;
        +		}
        +		pmap->issuerDomainPolicy = obj1;
        +		pmap->subjectDomainPolicy = obj2;
        +		sk_POLICY_MAPPING_push(pmaps, pmap);
        +	}
        +	return pmaps;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_prn.c b/vendor/openssl/openssl/crypto/x509v3/v3_prn.c
        new file mode 100644
        index 000000000..314621870
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_prn.c
        @@ -0,0 +1,234 @@
        +/* v3_prn.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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).
        + *
        + */
        +/* X509 v3 extension utilities */
        +
        +#include <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +/* Extension printing routines */
        +
        +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported);
        +
        +/* Print out a name+value stack */
        +
        +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
        +{
        +	int i;
        +	CONF_VALUE *nval;
        +	if(!val) return;
        +	if(!ml || !sk_CONF_VALUE_num(val)) {
        +		BIO_printf(out, "%*s", indent, "");
        +		if(!sk_CONF_VALUE_num(val)) BIO_puts(out, "<EMPTY>\n");
        +	}
        +	for(i = 0; i < sk_CONF_VALUE_num(val); i++) {
        +		if(ml) BIO_printf(out, "%*s", indent, "");
        +		else if(i > 0) BIO_printf(out, ", ");
        +		nval = sk_CONF_VALUE_value(val, i);
        +		if(!nval->name) BIO_puts(out, nval->value);
        +		else if(!nval->value) BIO_puts(out, nval->name);
        +#ifndef CHARSET_EBCDIC
        +		else BIO_printf(out, "%s:%s", nval->name, nval->value);
        +#else
        +		else {
        +			int len;
        +			char *tmp;
        +			len = strlen(nval->value)+1;
        +			tmp = OPENSSL_malloc(len);
        +			if (tmp)
        +			{
        +				ascii2ebcdic(tmp, nval->value, len);
        +				BIO_printf(out, "%s:%s", nval->name, tmp);
        +				OPENSSL_free(tmp);
        +			}
        +		}
        +#endif
        +		if(ml) BIO_puts(out, "\n");
        +	}
        +}
        +
        +/* Main routine: print out a general extension */
        +
        +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
        +{
        +	void *ext_str = NULL;
        +	char *value = NULL;
        +	const unsigned char *p;
        +	const X509V3_EXT_METHOD *method;	
        +	STACK_OF(CONF_VALUE) *nval = NULL;
        +	int ok = 1;
        +
        +	if(!(method = X509V3_EXT_get(ext)))
        +		return unknown_ext_print(out, ext, flag, indent, 0);
        +	p = ext->value->data;
        +	if(method->it) ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it));
        +	else ext_str = method->d2i(NULL, &p, ext->value->length);
        +
        +	if(!ext_str) return unknown_ext_print(out, ext, flag, indent, 1);
        +
        +	if(method->i2s) {
        +		if(!(value = method->i2s(method, ext_str))) {
        +			ok = 0;
        +			goto err;
        +		}
        +#ifndef CHARSET_EBCDIC
        +		BIO_printf(out, "%*s%s", indent, "", value);
        +#else
        +		{
        +			int len;
        +			char *tmp;
        +			len = strlen(value)+1;
        +			tmp = OPENSSL_malloc(len);
        +			if (tmp)
        +			{
        +				ascii2ebcdic(tmp, value, len);
        +				BIO_printf(out, "%*s%s", indent, "", tmp);
        +				OPENSSL_free(tmp);
        +			}
        +		}
        +#endif
        +	} else if(method->i2v) {
        +		if(!(nval = method->i2v(method, ext_str, NULL))) {
        +			ok = 0;
        +			goto err;
        +		}
        +		X509V3_EXT_val_prn(out, nval, indent,
        +				 method->ext_flags & X509V3_EXT_MULTILINE);
        +	} else if(method->i2r) {
        +		if(!method->i2r(method, ext_str, out, indent)) ok = 0;
        +	} else ok = 0;
        +
        +	err:
        +		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
        +		if(value) OPENSSL_free(value);
        +		if(method->it) ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
        +		else method->ext_free(ext_str);
        +		return ok;
        +}
        +
        +int X509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
        +{
        +	int i, j;
        +
        +	if(sk_X509_EXTENSION_num(exts) <= 0) return 1;
        +
        +	if(title) 
        +		{
        +		BIO_printf(bp,"%*s%s:\n",indent, "", title);
        +		indent += 4;
        +		}
        +
        +	for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
        +		{
        +		ASN1_OBJECT *obj;
        +		X509_EXTENSION *ex;
        +		ex=sk_X509_EXTENSION_value(exts, i);
        +		if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
        +		obj=X509_EXTENSION_get_object(ex);
        +		i2a_ASN1_OBJECT(bp,obj);
        +		j=X509_EXTENSION_get_critical(ex);
        +		if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
        +			return 0;
        +		if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
        +			{
        +			BIO_printf(bp, "%*s", indent + 4, "");
        +			M_ASN1_OCTET_STRING_print(bp,ex->value);
        +			}
        +		if (BIO_write(bp,"\n",1) <= 0) return 0;
        +		}
        +	return 1;
        +}
        +
        +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported)
        +{
        +	switch(flag & X509V3_EXT_UNKNOWN_MASK) {
        +
        +		case X509V3_EXT_DEFAULT:
        +		return 0;
        +
        +		case X509V3_EXT_ERROR_UNKNOWN:
        +		if(supported)
        +			BIO_printf(out, "%*s<Parse Error>", indent, "");
        +		else
        +			BIO_printf(out, "%*s<Not Supported>", indent, "");
        +		return 1;
        +
        +		case X509V3_EXT_PARSE_UNKNOWN:
        +			return ASN1_parse_dump(out,
        +				ext->value->data, ext->value->length, indent, -1);
        +		case X509V3_EXT_DUMP_UNKNOWN:
        +			return BIO_dump_indent(out, (char *)ext->value->data, ext->value->length, indent);
        +
        +		default:
        +		return 1;
        +	}
        +}
        +	
        +
        +#ifndef OPENSSL_NO_FP_API
        +int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
        +{
        +	BIO *bio_tmp;
        +	int ret;
        +	if(!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) return 0;
        +	ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
        +	BIO_free(bio_tmp);
        +	return ret;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_purp.c b/vendor/openssl/openssl/crypto/x509v3/v3_purp.c
        new file mode 100644
        index 000000000..ad688657e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_purp.c
        @@ -0,0 +1,767 @@
        +/* v3_purp.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 2001.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509v3.h>
        +#include <openssl/x509_vfy.h>
        +
        +static void x509v3_cache_extensions(X509 *x);
        +
        +static int check_ssl_ca(const X509 *x);
        +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int purpose_smime(const X509 *x, int ca);
        +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
        +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
        +
        +static int xp_cmp(const X509_PURPOSE * const *a,
        +		const X509_PURPOSE * const *b);
        +static void xptable_free(X509_PURPOSE *p);
        +
        +static X509_PURPOSE xstandard[] = {
        +	{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL},
        +	{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL},
        +	{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
        +	{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL},
        +	{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
        +	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
        +	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
        +	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
        +	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
        +};
        +
        +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
        +
        +IMPLEMENT_STACK_OF(X509_PURPOSE)
        +
        +static STACK_OF(X509_PURPOSE) *xptable = NULL;
        +
        +static int xp_cmp(const X509_PURPOSE * const *a,
        +		const X509_PURPOSE * const *b)
        +{
        +	return (*a)->purpose - (*b)->purpose;
        +}
        +
        +/* As much as I'd like to make X509_check_purpose use a "const" X509*
        + * I really can't because it does recalculate hashes and do other non-const
        + * things. */
        +int X509_check_purpose(X509 *x, int id, int ca)
        +{
        +	int idx;
        +	const X509_PURPOSE *pt;
        +	if(!(x->ex_flags & EXFLAG_SET)) {
        +		CRYPTO_w_lock(CRYPTO_LOCK_X509);
        +		x509v3_cache_extensions(x);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
        +	}
        +	if(id == -1) return 1;
        +	idx = X509_PURPOSE_get_by_id(id);
        +	if(idx == -1) return -1;
        +	pt = X509_PURPOSE_get0(idx);
        +	return pt->check_purpose(pt, x, ca);
        +}
        +
        +int X509_PURPOSE_set(int *p, int purpose)
        +{
        +	if(X509_PURPOSE_get_by_id(purpose) == -1) {
        +		X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE);
        +		return 0;
        +	}
        +	*p = purpose;
        +	return 1;
        +}
        +
        +int X509_PURPOSE_get_count(void)
        +{
        +	if(!xptable) return X509_PURPOSE_COUNT;
        +	return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
        +}
        +
        +X509_PURPOSE * X509_PURPOSE_get0(int idx)
        +{
        +	if(idx < 0) return NULL;
        +	if(idx < (int)X509_PURPOSE_COUNT) return xstandard + idx;
        +	return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
        +}
        +
        +int X509_PURPOSE_get_by_sname(char *sname)
        +{
        +	int i;
        +	X509_PURPOSE *xptmp;
        +	for(i = 0; i < X509_PURPOSE_get_count(); i++) {
        +		xptmp = X509_PURPOSE_get0(i);
        +		if(!strcmp(xptmp->sname, sname)) return i;
        +	}
        +	return -1;
        +}
        +
        +int X509_PURPOSE_get_by_id(int purpose)
        +{
        +	X509_PURPOSE tmp;
        +	int idx;
        +	if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
        +		return purpose - X509_PURPOSE_MIN;
        +	tmp.purpose = purpose;
        +	if(!xptable) return -1;
        +	idx = sk_X509_PURPOSE_find(xptable, &tmp);
        +	if(idx == -1) return -1;
        +	return idx + X509_PURPOSE_COUNT;
        +}
        +
        +int X509_PURPOSE_add(int id, int trust, int flags,
        +			int (*ck)(const X509_PURPOSE *, const X509 *, int),
        +					char *name, char *sname, void *arg)
        +{
        +	int idx;
        +	X509_PURPOSE *ptmp;
        +	/* This is set according to what we change: application can't set it */
        +	flags &= ~X509_PURPOSE_DYNAMIC;
        +	/* This will always be set for application modified trust entries */
        +	flags |= X509_PURPOSE_DYNAMIC_NAME;
        +	/* Get existing entry if any */
        +	idx = X509_PURPOSE_get_by_id(id);
        +	/* Need a new entry */
        +	if(idx == -1) {
        +		if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
        +			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		ptmp->flags = X509_PURPOSE_DYNAMIC;
        +	} else ptmp = X509_PURPOSE_get0(idx);
        +
        +	/* OPENSSL_free existing name if dynamic */
        +	if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
        +		OPENSSL_free(ptmp->name);
        +		OPENSSL_free(ptmp->sname);
        +	}
        +	/* dup supplied name */
        +	ptmp->name = BUF_strdup(name);
        +	ptmp->sname = BUF_strdup(sname);
        +	if(!ptmp->name || !ptmp->sname) {
        +		X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +	}
        +	/* Keep the dynamic flag of existing entry */
        +	ptmp->flags &= X509_PURPOSE_DYNAMIC;
        +	/* Set all other flags */
        +	ptmp->flags |= flags;
        +
        +	ptmp->purpose = id;
        +	ptmp->trust = trust;
        +	ptmp->check_purpose = ck;
        +	ptmp->usr_data = arg;
        +
        +	/* If its a new entry manage the dynamic table */
        +	if(idx == -1) {
        +		if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
        +			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +		if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
        +			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +		}
        +	}
        +	return 1;
        +}
        +
        +static void xptable_free(X509_PURPOSE *p)
        +	{
        +	if(!p) return;
        +	if (p->flags & X509_PURPOSE_DYNAMIC) 
        +		{
        +		if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
        +			OPENSSL_free(p->name);
        +			OPENSSL_free(p->sname);
        +		}
        +		OPENSSL_free(p);
        +		}
        +	}
        +
        +void X509_PURPOSE_cleanup(void)
        +{
        +	unsigned int i;
        +	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
        +	for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i);
        +	xptable = NULL;
        +}
        +
        +int X509_PURPOSE_get_id(X509_PURPOSE *xp)
        +{
        +	return xp->purpose;
        +}
        +
        +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
        +{
        +	return xp->name;
        +}
        +
        +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
        +{
        +	return xp->sname;
        +}
        +
        +int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
        +{
        +	return xp->trust;
        +}
        +
        +static int nid_cmp(const int *a, const int *b)
        +	{
        +	return *a - *b;
        +	}
        +
        +DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid);
        +IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid);
        +
        +int X509_supported_extension(X509_EXTENSION *ex)
        +	{
        +	/* This table is a list of the NIDs of supported extensions:
        +	 * that is those which are used by the verify process. If
        +	 * an extension is critical and doesn't appear in this list
        +	 * then the verify process will normally reject the certificate.
        +	 * The list must be kept in numerical order because it will be
        +	 * searched using bsearch.
        +	 */
        +
        +	static const int supported_nids[] = {
        +		NID_netscape_cert_type, /* 71 */
        +        	NID_key_usage,		/* 83 */
        +		NID_subject_alt_name,	/* 85 */
        +		NID_basic_constraints,	/* 87 */
        +		NID_certificate_policies, /* 89 */
        +        	NID_ext_key_usage,	/* 126 */
        +#ifndef OPENSSL_NO_RFC3779
        +		NID_sbgp_ipAddrBlock,	/* 290 */
        +		NID_sbgp_autonomousSysNum, /* 291 */
        +#endif
        +		NID_policy_constraints,	/* 401 */
        +		NID_proxyCertInfo,	/* 663 */
        +		NID_name_constraints,	/* 666 */
        +		NID_policy_mappings,	/* 747 */
        +		NID_inhibit_any_policy	/* 748 */
        +	};
        +
        +	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
        +
        +	if (ex_nid == NID_undef) 
        +		return 0;
        +
        +	if (OBJ_bsearch_nid(&ex_nid, supported_nids,
        +			sizeof(supported_nids)/sizeof(int)))
        +		return 1;
        +	return 0;
        +	}
        +
        +static void setup_dp(X509 *x, DIST_POINT *dp)
        +	{
        +	X509_NAME *iname = NULL;
        +	int i;
        +	if (dp->reasons)
        +		{
        +		if (dp->reasons->length > 0)
        +			dp->dp_reasons = dp->reasons->data[0];
        +		if (dp->reasons->length > 1)
        +			dp->dp_reasons |= (dp->reasons->data[1] << 8);
        +		dp->dp_reasons &= CRLDP_ALL_REASONS;
        +		}
        +	else
        +		dp->dp_reasons = CRLDP_ALL_REASONS;
        +	if (!dp->distpoint || (dp->distpoint->type != 1))
        +		return;
        +	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
        +		{
        +		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
        +		if (gen->type == GEN_DIRNAME)
        +			{
        +			iname = gen->d.directoryName;
        +			break;
        +			}
        +		}
        +	if (!iname)
        +		iname = X509_get_issuer_name(x);
        +
        +	DIST_POINT_set_dpname(dp->distpoint, iname);
        +
        +	}
        +
        +static void setup_crldp(X509 *x)
        +	{
        +	int i;
        +	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
        +	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
        +		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
        +	}
        +
        +static void x509v3_cache_extensions(X509 *x)
        +{
        +	BASIC_CONSTRAINTS *bs;
        +	PROXY_CERT_INFO_EXTENSION *pci;
        +	ASN1_BIT_STRING *usage;
        +	ASN1_BIT_STRING *ns;
        +	EXTENDED_KEY_USAGE *extusage;
        +	X509_EXTENSION *ex;
        +	
        +	int i;
        +	if(x->ex_flags & EXFLAG_SET) return;
        +#ifndef OPENSSL_NO_SHA
        +	X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
        +#endif
        +	/* Does subject name match issuer ? */
        +	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
        +			 x->ex_flags |= EXFLAG_SI;
        +	/* V1 should mean no extensions ... */
        +	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
        +	/* Handle basic constraints */
        +	if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
        +		if(bs->ca) x->ex_flags |= EXFLAG_CA;
        +		if(bs->pathlen) {
        +			if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
        +						|| !bs->ca) {
        +				x->ex_flags |= EXFLAG_INVALID;
        +				x->ex_pathlen = 0;
        +			} else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
        +		} else x->ex_pathlen = -1;
        +		BASIC_CONSTRAINTS_free(bs);
        +		x->ex_flags |= EXFLAG_BCONS;
        +	}
        +	/* Handle proxy certificates */
        +	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
        +		if (x->ex_flags & EXFLAG_CA
        +		    || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
        +		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
        +			x->ex_flags |= EXFLAG_INVALID;
        +		}
        +		if (pci->pcPathLengthConstraint) {
        +			x->ex_pcpathlen =
        +				ASN1_INTEGER_get(pci->pcPathLengthConstraint);
        +		} else x->ex_pcpathlen = -1;
        +		PROXY_CERT_INFO_EXTENSION_free(pci);
        +		x->ex_flags |= EXFLAG_PROXY;
        +	}
        +	/* Handle key usage */
        +	if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
        +		if(usage->length > 0) {
        +			x->ex_kusage = usage->data[0];
        +			if(usage->length > 1) 
        +				x->ex_kusage |= usage->data[1] << 8;
        +		} else x->ex_kusage = 0;
        +		x->ex_flags |= EXFLAG_KUSAGE;
        +		ASN1_BIT_STRING_free(usage);
        +	}
        +	x->ex_xkusage = 0;
        +	if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
        +		x->ex_flags |= EXFLAG_XKUSAGE;
        +		for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
        +			switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
        +				case NID_server_auth:
        +				x->ex_xkusage |= XKU_SSL_SERVER;
        +				break;
        +
        +				case NID_client_auth:
        +				x->ex_xkusage |= XKU_SSL_CLIENT;
        +				break;
        +
        +				case NID_email_protect:
        +				x->ex_xkusage |= XKU_SMIME;
        +				break;
        +
        +				case NID_code_sign:
        +				x->ex_xkusage |= XKU_CODE_SIGN;
        +				break;
        +
        +				case NID_ms_sgc:
        +				case NID_ns_sgc:
        +				x->ex_xkusage |= XKU_SGC;
        +				break;
        +
        +				case NID_OCSP_sign:
        +				x->ex_xkusage |= XKU_OCSP_SIGN;
        +				break;
        +
        +				case NID_time_stamp:
        +				x->ex_xkusage |= XKU_TIMESTAMP;
        +				break;
        +
        +				case NID_dvcs:
        +				x->ex_xkusage |= XKU_DVCS;
        +				break;
        +			}
        +		}
        +		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
        +	}
        +
        +	if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
        +		if(ns->length > 0) x->ex_nscert = ns->data[0];
        +		else x->ex_nscert = 0;
        +		x->ex_flags |= EXFLAG_NSCERT;
        +		ASN1_BIT_STRING_free(ns);
        +	}
        +	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
        +	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
        +	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
        +	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
        +	if (!x->nc && (i != -1))
        +		x->ex_flags |= EXFLAG_INVALID;
        +	setup_crldp(x);
        +
        +#ifndef OPENSSL_NO_RFC3779
        + 	x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
        + 	x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
        + 					  NULL, NULL);
        +#endif
        +	for (i = 0; i < X509_get_ext_count(x); i++)
        +		{
        +		ex = X509_get_ext(x, i);
        +		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
        +					== NID_freshest_crl)
        +			x->ex_flags |= EXFLAG_FRESHEST;
        +		if (!X509_EXTENSION_get_critical(ex))
        +			continue;
        +		if (!X509_supported_extension(ex))
        +			{
        +			x->ex_flags |= EXFLAG_CRITICAL;
        +			break;
        +			}
        +		}
        +	x->ex_flags |= EXFLAG_SET;
        +}
        +
        +/* CA checks common to all purposes
        + * return codes:
        + * 0 not a CA
        + * 1 is a CA
        + * 2 basicConstraints absent so "maybe" a CA
        + * 3 basicConstraints absent but self signed V1.
        + * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
        + */
        +
        +#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
        +#define ku_reject(x, usage) \
        +	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
        +#define xku_reject(x, usage) \
        +	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
        +#define ns_reject(x, usage) \
        +	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
        +
        +static int check_ca(const X509 *x)
        +{
        +	/* keyUsage if present should allow cert signing */
        +	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
        +	if(x->ex_flags & EXFLAG_BCONS) {
        +		if(x->ex_flags & EXFLAG_CA) return 1;
        +		/* If basicConstraints says not a CA then say so */
        +		else return 0;
        +	} else {
        +		/* we support V1 roots for...  uh, I don't really know why. */
        +		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
        +		/* If key usage present it must have certSign so tolerate it */
        +		else if (x->ex_flags & EXFLAG_KUSAGE) return 4;
        +		/* Older certificates could have Netscape-specific CA types */
        +		else if (x->ex_flags & EXFLAG_NSCERT
        +			 && x->ex_nscert & NS_ANY_CA) return 5;
        +		/* can this still be regarded a CA certificate?  I doubt it */
        +		return 0;
        +	}
        +}
        +
        +int X509_check_ca(X509 *x)
        +{
        +	if(!(x->ex_flags & EXFLAG_SET)) {
        +		CRYPTO_w_lock(CRYPTO_LOCK_X509);
        +		x509v3_cache_extensions(x);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
        +	}
        +
        +	return check_ca(x);
        +}
        +
        +/* Check SSL CA: common checks for SSL client and server */
        +static int check_ssl_ca(const X509 *x)
        +{
        +	int ca_ret;
        +	ca_ret = check_ca(x);
        +	if(!ca_ret) return 0;
        +	/* check nsCertType if present */
        +	if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
        +	else return 0;
        +}
        +
        +
        +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
        +	if(ca) return check_ssl_ca(x);
        +	/* We need to do digital signatures with it */
        +	if(ku_reject(x,KU_DIGITAL_SIGNATURE)) return 0;
        +	/* nsCertType if present should allow SSL client use */	
        +	if(ns_reject(x, NS_SSL_CLIENT)) return 0;
        +	return 1;
        +}
        +
        +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
        +	if(ca) return check_ssl_ca(x);
        +
        +	if(ns_reject(x, NS_SSL_SERVER)) return 0;
        +	/* Now as for keyUsage: we'll at least need to sign OR encipher */
        +	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) return 0;
        +	
        +	return 1;
        +
        +}
        +
        +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	int ret;
        +	ret = check_purpose_ssl_server(xp, x, ca);
        +	if(!ret || ca) return ret;
        +	/* We need to encipher or Netscape complains */
        +	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
        +	return ret;
        +}
        +
        +/* common S/MIME checks */
        +static int purpose_smime(const X509 *x, int ca)
        +{
        +	if(xku_reject(x,XKU_SMIME)) return 0;
        +	if(ca) {
        +		int ca_ret;
        +		ca_ret = check_ca(x);
        +		if(!ca_ret) return 0;
        +		/* check nsCertType if present */
        +		if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;
        +		else return 0;
        +	}
        +	if(x->ex_flags & EXFLAG_NSCERT) {
        +		if(x->ex_nscert & NS_SMIME) return 1;
        +		/* Workaround for some buggy certificates */
        +		if(x->ex_nscert & NS_SSL_CLIENT) return 2;
        +		return 0;
        +	}
        +	return 1;
        +}
        +
        +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	int ret;
        +	ret = purpose_smime(x, ca);
        +	if(!ret || ca) return ret;
        +	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
        +	return ret;
        +}
        +
        +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	int ret;
        +	ret = purpose_smime(x, ca);
        +	if(!ret || ca) return ret;
        +	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
        +	return ret;
        +}
        +
        +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	if(ca) {
        +		int ca_ret;
        +		if((ca_ret = check_ca(x)) != 2) return ca_ret;
        +		else return 0;
        +	}
        +	if(ku_reject(x, KU_CRL_SIGN)) return 0;
        +	return 1;
        +}
        +
        +/* OCSP helper: this is *not* a full OCSP check. It just checks that
        + * each CA is valid. Additional checks must be made on the chain.
        + */
        +
        +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	/* Must be a valid CA.  Should we really support the "I don't know"
        +	   value (2)? */
        +	if(ca) return check_ca(x);
        +	/* leaf certificate is checked in OCSP_verify() */
        +	return 1;
        +}
        +
        +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
        +					int ca)
        +{
        +	int i_ext;
        +
        +	/* If ca is true we must return if this is a valid CA certificate. */
        +	if (ca) return check_ca(x);
        +
        +	/* 
        +	 * Check the optional key usage field:
        +	 * if Key Usage is present, it must be one of digitalSignature 
        +	 * and/or nonRepudiation (other values are not consistent and shall
        +	 * be rejected).
        +	 */
        +	if ((x->ex_flags & EXFLAG_KUSAGE)
        +	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
        +		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
        +		return 0;
        +
        +	/* Only time stamp key usage is permitted and it's required. */
        +	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
        +		return 0;
        +
        +	/* Extended Key Usage MUST be critical */
        +	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
        +	if (i_ext >= 0)
        +		{
        +		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
        +		if (!X509_EXTENSION_get_critical(ext))
        +			return 0;
        +		}
        +
        +	return 1;
        +}
        +
        +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
        +{
        +	return 1;
        +}
        +
        +/* Various checks to see if one certificate issued the second.
        + * This can be used to prune a set of possible issuer certificates
        + * which have been looked up using some simple method such as by
        + * subject name.
        + * These are:
        + * 1. Check issuer_name(subject) == subject_name(issuer)
        + * 2. If akid(subject) exists check it matches issuer
        + * 3. If key_usage(issuer) exists check it supports certificate signing
        + * returns 0 for OK, positive for reason for mismatch, reasons match
        + * codes for X509_verify_cert()
        + */
        +
        +int X509_check_issued(X509 *issuer, X509 *subject)
        +{
        +	if(X509_NAME_cmp(X509_get_subject_name(issuer),
        +			X509_get_issuer_name(subject)))
        +				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
        +	x509v3_cache_extensions(issuer);
        +	x509v3_cache_extensions(subject);
        +
        +	if(subject->akid)
        +		{
        +		int ret = X509_check_akid(issuer, subject->akid);
        +		if (ret != X509_V_OK)
        +			return ret;
        +		}
        +
        +	if(subject->ex_flags & EXFLAG_PROXY)
        +		{
        +		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
        +			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
        +		}
        +	else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
        +		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
        +	return X509_V_OK;
        +}
        +
        +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
        +	{
        +
        +	if(!akid)
        +		return X509_V_OK;
        +
        +	/* Check key ids (if present) */
        +	if(akid->keyid && issuer->skid &&
        +		 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
        +				return X509_V_ERR_AKID_SKID_MISMATCH;
        +	/* Check serial number */
        +	if(akid->serial &&
        +		ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
        +				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
        +	/* Check issuer name */
        +	if(akid->issuer)
        +		{
        +		/* Ugh, for some peculiar reason AKID includes
        +		 * SEQUENCE OF GeneralName. So look for a DirName.
        +		 * There may be more than one but we only take any
        +		 * notice of the first.
        +		 */
        +		GENERAL_NAMES *gens;
        +		GENERAL_NAME *gen;
        +		X509_NAME *nm = NULL;
        +		int i;
        +		gens = akid->issuer;
        +		for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
        +			{
        +			gen = sk_GENERAL_NAME_value(gens, i);
        +			if(gen->type == GEN_DIRNAME)
        +				{
        +				nm = gen->d.dirn;
        +				break;
        +				}
        +			}
        +		if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
        +			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
        +		}
        +	return X509_V_OK;
        +	}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_skey.c b/vendor/openssl/openssl/crypto/x509v3/v3_skey.c
        new file mode 100644
        index 000000000..0a984fbaa
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_skey.c
        @@ -0,0 +1,145 @@
        +/* v3_skey.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/x509v3.h>
        +
        +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
        +const X509V3_EXT_METHOD v3_skey_id = { 
        +NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
        +0,0,0,0,
        +(X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
        +(X509V3_EXT_S2I)s2i_skey_id,
        +0,0,0,0,
        +NULL};
        +
        +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
        +	     ASN1_OCTET_STRING *oct)
        +{
        +	return hex_to_string(oct->data, oct->length);
        +}
        +
        +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
        +	     X509V3_CTX *ctx, char *str)
        +{
        +	ASN1_OCTET_STRING *oct;
        +	long length;
        +
        +	if(!(oct = M_ASN1_OCTET_STRING_new())) {
        +		X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	if(!(oct->data = string_to_hex(str, &length))) {
        +		M_ASN1_OCTET_STRING_free(oct);
        +		return NULL;
        +	}
        +
        +	oct->length = length;
        +
        +	return oct;
        +
        +}
        +
        +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
        +	     X509V3_CTX *ctx, char *str)
        +{
        +	ASN1_OCTET_STRING *oct;
        +	ASN1_BIT_STRING *pk;
        +	unsigned char pkey_dig[EVP_MAX_MD_SIZE];
        +	unsigned int diglen;
        +
        +	if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
        +
        +	if(!(oct = M_ASN1_OCTET_STRING_new())) {
        +		X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +
        +	if(ctx && (ctx->flags == CTX_TEST)) return oct;
        +
        +	if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
        +		X509V3err(X509V3_F_S2I_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
        +		goto err;
        +	}
        +
        +	if(ctx->subject_req) 
        +		pk = ctx->subject_req->req_info->pubkey->public_key;
        +	else pk = ctx->subject_cert->cert_info->key->public_key;
        +
        +	if(!pk) {
        +		X509V3err(X509V3_F_S2I_SKEY_ID,X509V3_R_NO_PUBLIC_KEY);
        +		goto err;
        +	}
        +
        +	if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
        +		goto err;
        +
        +	if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
        +		X509V3err(X509V3_F_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +	}
        +
        +	return oct;
        +	
        +	err:
        +	M_ASN1_OCTET_STRING_free(oct);
        +	return NULL;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_sxnet.c b/vendor/openssl/openssl/crypto/x509v3/v3_sxnet.c
        new file mode 100644
        index 000000000..2a6bf11b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_sxnet.c
        @@ -0,0 +1,262 @@
        +/* v3_sxnet.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +/* Support for Thawte strong extranet extension */
        +
        +#define SXNET_TEST
        +
        +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
        +#ifdef SXNET_TEST
        +static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +						STACK_OF(CONF_VALUE) *nval);
        +#endif
        +const X509V3_EXT_METHOD v3_sxnet = {
        +NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
        +0,0,0,0,
        +0,0,
        +0, 
        +#ifdef SXNET_TEST
        +(X509V3_EXT_V2I)sxnet_v2i,
        +#else
        +0,
        +#endif
        +(X509V3_EXT_I2R)sxnet_i2r,
        +0,
        +NULL
        +};
        +
        +ASN1_SEQUENCE(SXNETID) = {
        +	ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
        +	ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(SXNETID)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
        +
        +ASN1_SEQUENCE(SXNET) = {
        +	ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
        +	ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
        +} ASN1_SEQUENCE_END(SXNET)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(SXNET)
        +
        +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
        +	     int indent)
        +{
        +	long v;
        +	char *tmp;
        +	SXNETID *id;
        +	int i;
        +	v = ASN1_INTEGER_get(sx->version);
        +	BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
        +	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
        +		id = sk_SXNETID_value(sx->ids, i);
        +		tmp = i2s_ASN1_INTEGER(NULL, id->zone);
        +		BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
        +		OPENSSL_free(tmp);
        +		M_ASN1_OCTET_STRING_print(out, id->user);
        +	}
        +	return 1;
        +}
        +
        +#ifdef SXNET_TEST
        +
        +/* NBB: this is used for testing only. It should *not* be used for anything
        + * else because it will just take static IDs from the configuration file and
        + * they should really be separate values for each user.
        + */
        +
        +
        +static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +	     STACK_OF(CONF_VALUE) *nval)
        +{
        +	CONF_VALUE *cnf;
        +	SXNET *sx = NULL;
        +	int i;
        +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
        +		cnf = sk_CONF_VALUE_value(nval, i);
        +		if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
        +								 return NULL;
        +	}
        +	return sx;
        +}
        +		
        +	
        +#endif
        +
        +/* Strong Extranet utility functions */
        +
        +/* Add an id given the zone as an ASCII number */
        +
        +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
        +	     int userlen)
        +{
        +	ASN1_INTEGER *izone = NULL;
        +	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
        +		X509V3err(X509V3_F_SXNET_ADD_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
        +		return 0;
        +	}
        +	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
        +}
        +
        +/* Add an id given the zone as an unsigned long */
        +
        +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
        +	     int userlen)
        +{
        +	ASN1_INTEGER *izone = NULL;
        +	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
        +		X509V3err(X509V3_F_SXNET_ADD_ID_ULONG,ERR_R_MALLOC_FAILURE);
        +		M_ASN1_INTEGER_free(izone);
        +		return 0;
        +	}
        +	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
        +	
        +}
        +
        +/* Add an id given the zone as an ASN1_INTEGER.
        + * Note this version uses the passed integer and doesn't make a copy so don't
        + * free it up afterwards.
        + */
        +
        +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
        +	     int userlen)
        +{
        +	SXNET *sx = NULL;
        +	SXNETID *id = NULL;
        +	if(!psx || !zone || !user) {
        +		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_INVALID_NULL_ARGUMENT);
        +		return 0;
        +	}
        +	if(userlen == -1) userlen = strlen(user);
        +	if(userlen > 64) {
        +		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_USER_TOO_LONG);
        +		return 0;
        +	}
        +	if(!*psx) {
        +		if(!(sx = SXNET_new())) goto err;
        +		if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
        +		*psx = sx;
        +	} else sx = *psx;
        +	if(SXNET_get_id_INTEGER(sx, zone)) {
        +		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_DUPLICATE_ZONE_ID);
        +		return 0;
        +	}
        +
        +	if(!(id = SXNETID_new())) goto err;
        +	if(userlen == -1) userlen = strlen(user);
        +		
        +	if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
        +	if(!sk_SXNETID_push(sx->ids, id)) goto err;
        +	id->zone = zone;
        +	return 1;
        +	
        +	err:
        +	X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,ERR_R_MALLOC_FAILURE);
        +	SXNETID_free(id);
        +	SXNET_free(sx);
        +	*psx = NULL;
        +	return 0;
        +}
        +
        +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
        +{
        +	ASN1_INTEGER *izone = NULL;
        +	ASN1_OCTET_STRING *oct;
        +	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
        +		X509V3err(X509V3_F_SXNET_GET_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
        +		return NULL;
        +	}
        +	oct = SXNET_get_id_INTEGER(sx, izone);
        +	M_ASN1_INTEGER_free(izone);
        +	return oct;
        +}
        +
        +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
        +{
        +	ASN1_INTEGER *izone = NULL;
        +	ASN1_OCTET_STRING *oct;
        +	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
        +		X509V3err(X509V3_F_SXNET_GET_ID_ULONG,ERR_R_MALLOC_FAILURE);
        +		M_ASN1_INTEGER_free(izone);
        +		return NULL;
        +	}
        +	oct = SXNET_get_id_INTEGER(sx, izone);
        +	M_ASN1_INTEGER_free(izone);
        +	return oct;
        +}
        +
        +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
        +{
        +	SXNETID *id;
        +	int i;
        +	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
        +		id = sk_SXNETID_value(sx->ids, i);
        +		if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
        +	}
        +	return NULL;
        +}
        +
        +IMPLEMENT_STACK_OF(SXNETID)
        +IMPLEMENT_ASN1_SET_OF(SXNETID)
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3_utl.c b/vendor/openssl/openssl/crypto/x509v3/v3_utl.c
        new file mode 100644
        index 000000000..e03023454
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3_utl.c
        @@ -0,0 +1,874 @@
        +/* v3_utl.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    licensing@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* X509 v3 extension utilities */
        +
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include "cryptlib.h"
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/bn.h>
        +
        +static char *strip_spaces(char *name);
        +static int sk_strcmp(const char * const *a, const char * const *b);
        +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens);
        +static void str_free(OPENSSL_STRING str);
        +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
        +
        +static int ipv4_from_asc(unsigned char *v4, const char *in);
        +static int ipv6_from_asc(unsigned char *v6, const char *in);
        +static int ipv6_cb(const char *elem, int len, void *usr);
        +static int ipv6_hex(unsigned char *out, const char *in, int inlen);
        +
        +/* Add a CONF_VALUE name value pair to stack */
        +
        +int X509V3_add_value(const char *name, const char *value,
        +						STACK_OF(CONF_VALUE) **extlist)
        +{
        +	CONF_VALUE *vtmp = NULL;
        +	char *tname = NULL, *tvalue = NULL;
        +	if(name && !(tname = BUF_strdup(name))) goto err;
        +	if(value && !(tvalue = BUF_strdup(value))) goto err;
        +	if(!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) goto err;
        +	if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
        +	vtmp->section = NULL;
        +	vtmp->name = tname;
        +	vtmp->value = tvalue;
        +	if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
        +	return 1;
        +	err:
        +	X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE);
        +	if(vtmp) OPENSSL_free(vtmp);
        +	if(tname) OPENSSL_free(tname);
        +	if(tvalue) OPENSSL_free(tvalue);
        +	return 0;
        +}
        +
        +int X509V3_add_value_uchar(const char *name, const unsigned char *value,
        +			   STACK_OF(CONF_VALUE) **extlist)
        +    {
        +    return X509V3_add_value(name,(const char *)value,extlist);
        +    }
        +
        +/* Free function for STACK_OF(CONF_VALUE) */
        +
        +void X509V3_conf_free(CONF_VALUE *conf)
        +{
        +	if(!conf) return;
        +	if(conf->name) OPENSSL_free(conf->name);
        +	if(conf->value) OPENSSL_free(conf->value);
        +	if(conf->section) OPENSSL_free(conf->section);
        +	OPENSSL_free(conf);
        +}
        +
        +int X509V3_add_value_bool(const char *name, int asn1_bool,
        +						STACK_OF(CONF_VALUE) **extlist)
        +{
        +	if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
        +	return X509V3_add_value(name, "FALSE", extlist);
        +}
        +
        +int X509V3_add_value_bool_nf(char *name, int asn1_bool,
        +						STACK_OF(CONF_VALUE) **extlist)
        +{
        +	if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
        +	return 1;
        +}
        +
        +
        +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
        +{
        +	BIGNUM *bntmp = NULL;
        +	char *strtmp = NULL;
        +	if(!a) return NULL;
        +	if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
        +	    !(strtmp = BN_bn2dec(bntmp)) )
        +		X509V3err(X509V3_F_I2S_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
        +	BN_free(bntmp);
        +	return strtmp;
        +}
        +
        +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
        +{
        +	BIGNUM *bntmp = NULL;
        +	char *strtmp = NULL;
        +	if(!a) return NULL;
        +	if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
        +	    !(strtmp = BN_bn2dec(bntmp)) )
        +		X509V3err(X509V3_F_I2S_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
        +	BN_free(bntmp);
        +	return strtmp;
        +}
        +
        +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
        +{
        +	BIGNUM *bn = NULL;
        +	ASN1_INTEGER *aint;
        +	int isneg, ishex;
        +	int ret;
        +	if (!value) {
        +		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE);
        +		return 0;
        +	}
        +	bn = BN_new();
        +	if (value[0] == '-') {
        +		value++;
        +		isneg = 1;
        +	} else isneg = 0;
        +
        +	if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
        +		value += 2;
        +		ishex = 1;
        +	} else ishex = 0;
        +
        +	if (ishex) ret = BN_hex2bn(&bn, value);
        +	else ret = BN_dec2bn(&bn, value);
        +
        +	if (!ret || value[ret]) {
        +		BN_free(bn);
        +		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR);
        +		return 0;
        +	}
        +
        +	if (isneg && BN_is_zero(bn)) isneg = 0;
        +
        +	aint = BN_to_ASN1_INTEGER(bn, NULL);
        +	BN_free(bn);
        +	if (!aint) {
        +		X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
        +		return 0;
        +	}
        +	if (isneg) aint->type |= V_ASN1_NEG;
        +	return aint;
        +}
        +
        +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
        +	     STACK_OF(CONF_VALUE) **extlist)
        +{
        +	char *strtmp;
        +	int ret;
        +	if(!aint) return 1;
        +	if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
        +	ret = X509V3_add_value(name, strtmp, extlist);
        +	OPENSSL_free(strtmp);
        +	return ret;
        +}
        +
        +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
        +{
        +	char *btmp;
        +	if(!(btmp = value->value)) goto err;
        +	if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
        +		 || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
        +		|| !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
        +		*asn1_bool = 0xff;
        +		return 1;
        +	} else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
        +		 || !strcmp(btmp, "N") || !strcmp(btmp, "n")
        +		|| !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
        +		*asn1_bool = 0;
        +		return 1;
        +	}
        +	err:
        +	X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
        +	X509V3_conf_err(value);
        +	return 0;
        +}
        +
        +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
        +{
        +	ASN1_INTEGER *itmp;
        +	if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
        +		X509V3_conf_err(value);
        +		return 0;
        +	}
        +	*aint = itmp;
        +	return 1;
        +}
        +
        +#define HDR_NAME	1
        +#define HDR_VALUE	2
        +
        +/*#define DEBUG*/
        +
        +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
        +{
        +	char *p, *q, c;
        +	char *ntmp, *vtmp;
        +	STACK_OF(CONF_VALUE) *values = NULL;
        +	char *linebuf;
        +	int state;
        +	/* We are going to modify the line so copy it first */
        +	linebuf = BUF_strdup(line);
        +	state = HDR_NAME;
        +	ntmp = NULL;
        +	/* Go through all characters */
        +	for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
        +
        +		switch(state) {
        +			case HDR_NAME:
        +			if(c == ':') {
        +				state = HDR_VALUE;
        +				*p = 0;
        +				ntmp = strip_spaces(q);
        +				if(!ntmp) {
        +					X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
        +					goto err;
        +				}
        +				q = p + 1;
        +			} else if(c == ',') {
        +				*p = 0;
        +				ntmp = strip_spaces(q);
        +				q = p + 1;
        +#if 0
        +				printf("%s\n", ntmp);
        +#endif
        +				if(!ntmp) {
        +					X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
        +					goto err;
        +				}
        +				X509V3_add_value(ntmp, NULL, &values);
        +			}
        +			break ;
        +
        +			case HDR_VALUE:
        +			if(c == ',') {
        +				state = HDR_NAME;
        +				*p = 0;
        +				vtmp = strip_spaces(q);
        +#if 0
        +				printf("%s\n", ntmp);
        +#endif
        +				if(!vtmp) {
        +					X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
        +					goto err;
        +				}
        +				X509V3_add_value(ntmp, vtmp, &values);
        +				ntmp = NULL;
        +				q = p + 1;
        +			}
        +
        +		}
        +	}
        +
        +	if(state == HDR_VALUE) {
        +		vtmp = strip_spaces(q);
        +#if 0
        +		printf("%s=%s\n", ntmp, vtmp);
        +#endif
        +		if(!vtmp) {
        +			X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
        +			goto err;
        +		}
        +		X509V3_add_value(ntmp, vtmp, &values);
        +	} else {
        +		ntmp = strip_spaces(q);
        +#if 0
        +		printf("%s\n", ntmp);
        +#endif
        +		if(!ntmp) {
        +			X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
        +			goto err;
        +		}
        +		X509V3_add_value(ntmp, NULL, &values);
        +	}
        +OPENSSL_free(linebuf);
        +return values;
        +
        +err:
        +OPENSSL_free(linebuf);
        +sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
        +return NULL;
        +
        +}
        +
        +/* Delete leading and trailing spaces from a string */
        +static char *strip_spaces(char *name)
        +{
        +	char *p, *q;
        +	/* Skip over leading spaces */
        +	p = name;
        +	while(*p && isspace((unsigned char)*p)) p++;
        +	if(!*p) return NULL;
        +	q = p + strlen(p) - 1;
        +	while((q != p) && isspace((unsigned char)*q)) q--;
        +	if(p != q) q[1] = 0;
        +	if(!*p) return NULL;
        +	return p;
        +}
        +
        +/* hex string utilities */
        +
        +/* Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
        + * hex representation
        + * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
        + */
        +
        +char *hex_to_string(const unsigned char *buffer, long len)
        +{
        +	char *tmp, *q;
        +	const unsigned char *p;
        +	int i;
        +	const static char hexdig[] = "0123456789ABCDEF";
        +	if(!buffer || !len) return NULL;
        +	if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
        +		X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +	}
        +	q = tmp;
        +	for(i = 0, p = buffer; i < len; i++,p++) {
        +		*q++ = hexdig[(*p >> 4) & 0xf];
        +		*q++ = hexdig[*p & 0xf];
        +		*q++ = ':';
        +	}
        +	q[-1] = 0;
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(tmp, tmp, q - tmp - 1);
        +#endif
        +
        +	return tmp;
        +}
        +
        +/* Give a string of hex digits convert to
        + * a buffer
        + */
        +
        +unsigned char *string_to_hex(const char *str, long *len)
        +{
        +	unsigned char *hexbuf, *q;
        +	unsigned char ch, cl, *p;
        +	if(!str) {
        +		X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
        +		return NULL;
        +	}
        +	if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
        +	for(p = (unsigned char *)str, q = hexbuf; *p;) {
        +		ch = *p++;
        +#ifdef CHARSET_EBCDIC
        +		ch = os_toebcdic[ch];
        +#endif
        +		if(ch == ':') continue;
        +		cl = *p++;
        +#ifdef CHARSET_EBCDIC
        +		cl = os_toebcdic[cl];
        +#endif
        +		if(!cl) {
        +			X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
        +			OPENSSL_free(hexbuf);
        +			return NULL;
        +		}
        +		if(isupper(ch)) ch = tolower(ch);
        +		if(isupper(cl)) cl = tolower(cl);
        +
        +		if((ch >= '0') && (ch <= '9')) ch -= '0';
        +		else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
        +		else goto badhex;
        +
        +		if((cl >= '0') && (cl <= '9')) cl -= '0';
        +		else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
        +		else goto badhex;
        +
        +		*q++ = (ch << 4) | cl;
        +	}
        +
        +	if(len) *len = q - hexbuf;
        +
        +	return hexbuf;
        +
        +	err:
        +	if(hexbuf) OPENSSL_free(hexbuf);
        +	X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
        +	return NULL;
        +
        +	badhex:
        +	OPENSSL_free(hexbuf);
        +	X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
        +	return NULL;
        +
        +}
        +
        +/* V2I name comparison function: returns zero if 'name' matches
        + * cmp or cmp.*
        + */
        +
        +int name_cmp(const char *name, const char *cmp)
        +{
        +	int len, ret;
        +	char c;
        +	len = strlen(cmp);
        +	if((ret = strncmp(name, cmp, len))) return ret;
        +	c = name[len];
        +	if(!c || (c=='.')) return 0;
        +	return 1;
        +}
        +
        +static int sk_strcmp(const char * const *a, const char * const *b)
        +{
        +	return strcmp(*a, *b);
        +}
        +
        +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
        +{
        +	GENERAL_NAMES *gens;
        +	STACK_OF(OPENSSL_STRING) *ret;
        +
        +	gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
        +	ret = get_email(X509_get_subject_name(x), gens);
        +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
        +	return ret;
        +}
        +
        +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
        +{
        +	AUTHORITY_INFO_ACCESS *info;
        +	STACK_OF(OPENSSL_STRING) *ret = NULL;
        +	int i;
        +
        +	info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
        +	if (!info)
        +		return NULL;
        +	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++)
        +		{
        +		ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
        +		if (OBJ_obj2nid(ad->method) == NID_ad_OCSP)
        +			{
        +			if (ad->location->type == GEN_URI)
        +				{
        +				if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier))
        +					break;
        +				}
        +			}
        +		}
        +	AUTHORITY_INFO_ACCESS_free(info);
        +	return ret;
        +}
        +
        +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
        +{
        +	GENERAL_NAMES *gens;
        +	STACK_OF(X509_EXTENSION) *exts;
        +	STACK_OF(OPENSSL_STRING) *ret;
        +
        +	exts = X509_REQ_get_extensions(x);
        +	gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
        +	ret = get_email(X509_REQ_get_subject_name(x), gens);
        +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
        +	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        +	return ret;
        +}
        +
        +
        +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
        +{
        +	STACK_OF(OPENSSL_STRING) *ret = NULL;
        +	X509_NAME_ENTRY *ne;
        +	ASN1_IA5STRING *email;
        +	GENERAL_NAME *gen;
        +	int i;
        +	/* Now add any email address(es) to STACK */
        +	i = -1;
        +	/* First supplied X509_NAME */
        +	while((i = X509_NAME_get_index_by_NID(name,
        +					 NID_pkcs9_emailAddress, i)) >= 0) {
        +		ne = X509_NAME_get_entry(name, i);
        +		email = X509_NAME_ENTRY_get_data(ne);
        +		if(!append_ia5(&ret, email)) return NULL;
        +	}
        +	for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
        +	{
        +		gen = sk_GENERAL_NAME_value(gens, i);
        +		if(gen->type != GEN_EMAIL) continue;
        +		if(!append_ia5(&ret, gen->d.ia5)) return NULL;
        +	}
        +	return ret;
        +}
        +
        +static void str_free(OPENSSL_STRING str)
        +{
        +	OPENSSL_free(str);
        +}
        +
        +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
        +{
        +	char *emtmp;
        +	/* First some sanity checks */
        +	if(email->type != V_ASN1_IA5STRING) return 1;
        +	if(!email->data || !email->length) return 1;
        +	if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp);
        +	if(!*sk) return 0;
        +	/* Don't add duplicates */
        +	if(sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) return 1;
        +	emtmp = BUF_strdup((char *)email->data);
        +	if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
        +		X509_email_free(*sk);
        +		*sk = NULL;
        +		return 0;
        +	}
        +	return 1;
        +}
        +
        +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
        +{
        +	sk_OPENSSL_STRING_pop_free(sk, str_free);
        +}
        +
        +/* Convert IP addresses both IPv4 and IPv6 into an 
        + * OCTET STRING compatible with RFC3280.
        + */
        +
        +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
        +	{
        +	unsigned char ipout[16];
        +	ASN1_OCTET_STRING *ret;
        +	int iplen;
        +
        +	/* If string contains a ':' assume IPv6 */
        +
        +	iplen = a2i_ipadd(ipout, ipasc);
        +
        +	if (!iplen)
        +		return NULL;
        +
        +	ret = ASN1_OCTET_STRING_new();
        +	if (!ret)
        +		return NULL;
        +	if (!ASN1_OCTET_STRING_set(ret, ipout, iplen))
        +		{
        +		ASN1_OCTET_STRING_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
        +	{
        +	ASN1_OCTET_STRING *ret = NULL;
        +	unsigned char ipout[32];
        +	char *iptmp = NULL, *p;
        +	int iplen1, iplen2;
        +	p = strchr(ipasc,'/');
        +	if (!p)
        +		return NULL;
        +	iptmp = BUF_strdup(ipasc);
        +	if (!iptmp)
        +		return NULL;
        +	p = iptmp + (p - ipasc);
        +	*p++ = 0;
        +
        +	iplen1 = a2i_ipadd(ipout, iptmp);
        +
        +	if (!iplen1)
        +		goto err;
        +
        +	iplen2 = a2i_ipadd(ipout + iplen1, p);
        +
        +	OPENSSL_free(iptmp);
        +	iptmp = NULL;
        +
        +	if (!iplen2 || (iplen1 != iplen2))
        +		goto err;
        +
        +	ret = ASN1_OCTET_STRING_new();
        +	if (!ret)
        +		goto err;
        +	if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
        +		goto err;
        +
        +	return ret;
        +
        +	err:
        +	if (iptmp)
        +		OPENSSL_free(iptmp);
        +	if (ret)
        +		ASN1_OCTET_STRING_free(ret);
        +	return NULL;
        +	}
        +	
        +
        +int a2i_ipadd(unsigned char *ipout, const char *ipasc)
        +	{
        +	/* If string contains a ':' assume IPv6 */
        +
        +	if (strchr(ipasc, ':'))
        +		{
        +		if (!ipv6_from_asc(ipout, ipasc))
        +			return 0;
        +		return 16;
        +		}
        +	else
        +		{
        +		if (!ipv4_from_asc(ipout, ipasc))
        +			return 0;
        +		return 4;
        +		}
        +	}
        +
        +static int ipv4_from_asc(unsigned char *v4, const char *in)
        +	{
        +	int a0, a1, a2, a3;
        +	if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
        +		return 0;
        +	if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
        +		|| (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
        +		return 0;
        +	v4[0] = a0;
        +	v4[1] = a1;
        +	v4[2] = a2;
        +	v4[3] = a3;
        +	return 1;
        +	}
        +
        +typedef struct {
        +		/* Temporary store for IPV6 output */
        +		unsigned char tmp[16];
        +		/* Total number of bytes in tmp */
        +		int total;
        +		/* The position of a zero (corresponding to '::') */
        +		int zero_pos;
        +		/* Number of zeroes */
        +		int zero_cnt;
        +	} IPV6_STAT;
        +
        +
        +static int ipv6_from_asc(unsigned char *v6, const char *in)
        +	{
        +	IPV6_STAT v6stat;
        +	v6stat.total = 0;
        +	v6stat.zero_pos = -1;
        +	v6stat.zero_cnt = 0;
        +	/* Treat the IPv6 representation as a list of values
        +	 * separated by ':'. The presence of a '::' will parse
        + 	 * as one, two or three zero length elements.
        +	 */
        +	if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
        +		return 0;
        +
        +	/* Now for some sanity checks */
        +
        +	if (v6stat.zero_pos == -1)
        +		{
        +		/* If no '::' must have exactly 16 bytes */
        +		if (v6stat.total != 16)
        +			return 0;
        +		}
        +	else 
        +		{
        +		/* If '::' must have less than 16 bytes */
        +		if (v6stat.total == 16)
        +			return 0;
        +		/* More than three zeroes is an error */
        +		if (v6stat.zero_cnt > 3)
        +			return 0;
        +		/* Can only have three zeroes if nothing else present */
        +		else if (v6stat.zero_cnt == 3)
        +			{
        +			if (v6stat.total > 0)
        +				return 0;
        +			}
        +		/* Can only have two zeroes if at start or end */
        +		else if (v6stat.zero_cnt == 2)
        +			{
        +			if ((v6stat.zero_pos != 0)
        +				&& (v6stat.zero_pos != v6stat.total))
        +				return 0;
        +			}
        +		else 
        +		/* Can only have one zero if *not* start or end */
        +			{
        +			if ((v6stat.zero_pos == 0)
        +				|| (v6stat.zero_pos == v6stat.total))
        +				return 0;
        +			}
        +		}
        +
        +	/* Format result */
        +
        +	if (v6stat.zero_pos >= 0)
        +		{
        +		/* Copy initial part */
        +		memcpy(v6, v6stat.tmp, v6stat.zero_pos);
        +		/* Zero middle */
        +		memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
        +		/* Copy final part */
        +		if (v6stat.total != v6stat.zero_pos)
        +			memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
        +				v6stat.tmp + v6stat.zero_pos,
        +				v6stat.total - v6stat.zero_pos);
        +		}
        +	else
        +		memcpy(v6, v6stat.tmp, 16);
        +
        +	return 1;
        +	}
        +
        +static int ipv6_cb(const char *elem, int len, void *usr)
        +	{
        +	IPV6_STAT *s = usr;
        +	/* Error if 16 bytes written */
        +	if (s->total == 16)
        +		return 0;
        +	if (len == 0)
        +		{
        +		/* Zero length element, corresponds to '::' */
        +		if (s->zero_pos == -1)
        +			s->zero_pos = s->total;
        +		/* If we've already got a :: its an error */
        +		else if (s->zero_pos != s->total)
        +			return 0;
        +		s->zero_cnt++;
        +		}
        +	else 
        +		{
        +		/* If more than 4 characters could be final a.b.c.d form */
        +		if (len > 4)
        +			{
        +			/* Need at least 4 bytes left */
        +			if (s->total > 12)
        +				return 0;
        +			/* Must be end of string */
        +			if (elem[len])
        +				return 0;
        +			if (!ipv4_from_asc(s->tmp + s->total, elem))
        +				return 0;
        +			s->total += 4;
        +			}
        +		else
        +			{
        +			if (!ipv6_hex(s->tmp + s->total, elem, len))
        +				return 0;
        +			s->total += 2;
        +			}
        +		}
        +	return 1;
        +	}
        +
        +/* Convert a string of up to 4 hex digits into the corresponding
        + * IPv6 form.
        + */
        +
        +static int ipv6_hex(unsigned char *out, const char *in, int inlen)
        +	{
        +	unsigned char c;
        +	unsigned int num = 0;
        +	if (inlen > 4)
        +		return 0;
        +	while(inlen--)
        +		{
        +		c = *in++;
        +		num <<= 4;
        +		if ((c >= '0') && (c <= '9'))
        +			num |= c - '0';
        +		else if ((c >= 'A') && (c <= 'F'))
        +			num |= c - 'A' + 10;
        +		else if ((c >= 'a') && (c <= 'f'))
        +			num |=  c - 'a' + 10;
        +		else
        +			return 0;
        +		}
        +	out[0] = num >> 8;
        +	out[1] = num & 0xff;
        +	return 1;
        +	}
        +
        +
        +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
        +						unsigned long chtype)
        +	{
        +	CONF_VALUE *v;
        +	int i, mval;
        +	char *p, *type;
        +	if (!nm)
        +		return 0;
        +
        +	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
        +		{
        +		v=sk_CONF_VALUE_value(dn_sk,i);
        +		type=v->name;
        +		/* Skip past any leading X. X: X, etc to allow for
        +		 * multiple instances 
        +		 */
        +		for(p = type; *p ; p++) 
        +#ifndef CHARSET_EBCDIC
        +			if ((*p == ':') || (*p == ',') || (*p == '.'))
        +#else
        +			if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.']))
        +#endif
        +				{
        +				p++;
        +				if(*p) type = p;
        +				break;
        +				}
        +#ifndef CHARSET_EBCDIC
        +		if (*type == '+')
        +#else
        +		if (*type == os_toascii['+'])
        +#endif
        +			{
        +			mval = -1;
        +			type++;
        +			}
        +		else
        +			mval = 0;
        +		if (!X509_NAME_add_entry_by_txt(nm,type, chtype,
        +				(unsigned char *) v->value,-1,-1,mval))
        +					return 0;
        +
        +		}
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3conf.c b/vendor/openssl/openssl/crypto/x509v3/v3conf.c
        new file mode 100644
        index 000000000..a9e6ca354
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3conf.c
        @@ -0,0 +1,127 @@
        +/* v3conf.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include "cryptlib.h"
        +#include <openssl/asn1.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +/* Test application to add extensions from a config file */
        +
        +int main(int argc, char **argv)
        +{
        +	LHASH *conf;
        +	X509 *cert;
        +	FILE *inf;
        +	char *conf_file;
        +	int i;
        +	int count;
        +	X509_EXTENSION *ext;
        +	X509V3_add_standard_extensions();
        +	ERR_load_crypto_strings();
        +	if(!argv[1]) {
        +		fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n");
        +		exit(1);
        +	}
        +	conf_file = argv[2];
        +	if(!conf_file) conf_file = "test.cnf";
        +	conf = CONF_load(NULL, "test.cnf", NULL);
        +	if(!conf) {
        +		fprintf(stderr, "Error opening Config file %s\n", conf_file);
        +		ERR_print_errors_fp(stderr);
        +		exit(1);
        +	}
        +
        +	inf = fopen(argv[1], "r");
        +	if(!inf) {
        +		fprintf(stderr, "Can't open certificate file %s\n", argv[1]);
        +		exit(1);
        +	}
        +	cert = PEM_read_X509(inf, NULL, NULL);
        +	if(!cert) {
        +		fprintf(stderr, "Error reading certificate file %s\n", argv[1]);
        +		exit(1);
        +	}
        +	fclose(inf);
        +
        +	sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free);
        +	cert->cert_info->extensions = NULL;
        +
        +	if(!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) {
        +		fprintf(stderr, "Error adding extensions\n");
        +		ERR_print_errors_fp(stderr);
        +		exit(1);
        +	}
        +
        +	count = X509_get_ext_count(cert);
        +	printf("%d extensions\n", count);
        +	for(i = 0; i < count; i++) {
        +		ext = X509_get_ext(cert, i);
        +		printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
        +		if(ext->critical) printf(",critical:\n");
        +		else printf(":\n");
        +		X509V3_EXT_print_fp(stdout, ext, 0, 0);
        +		printf("\n");
        +		
        +	}
        +	return 0;
        +}
        +
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3err.c b/vendor/openssl/openssl/crypto/x509v3/v3err.c
        new file mode 100644
        index 000000000..f9f6f1f91
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3err.c
        @@ -0,0 +1,226 @@
        +/* crypto/x509v3/v3err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/x509v3.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
        +
        +static ERR_STRING_DATA X509V3_str_functs[]=
        +	{
        +{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME),	"A2I_GENERAL_NAME"},
        +{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE),	"ASIDENTIFIERCHOICE_CANONIZE"},
        +{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL),	"ASIDENTIFIERCHOICE_IS_CANONICAL"},
        +{ERR_FUNC(X509V3_F_COPY_EMAIL),	"COPY_EMAIL"},
        +{ERR_FUNC(X509V3_F_COPY_ISSUER),	"COPY_ISSUER"},
        +{ERR_FUNC(X509V3_F_DO_DIRNAME),	"DO_DIRNAME"},
        +{ERR_FUNC(X509V3_F_DO_EXT_CONF),	"DO_EXT_CONF"},
        +{ERR_FUNC(X509V3_F_DO_EXT_I2D),	"DO_EXT_I2D"},
        +{ERR_FUNC(X509V3_F_DO_EXT_NCONF),	"DO_EXT_NCONF"},
        +{ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS),	"DO_I2V_NAME_CONSTRAINTS"},
        +{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME),	"GNAMES_FROM_SECTNAME"},
        +{ERR_FUNC(X509V3_F_HEX_TO_STRING),	"hex_to_string"},
        +{ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED),	"i2s_ASN1_ENUMERATED"},
        +{ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING),	"I2S_ASN1_IA5STRING"},
        +{ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER),	"i2s_ASN1_INTEGER"},
        +{ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS),	"I2V_AUTHORITY_INFO_ACCESS"},
        +{ERR_FUNC(X509V3_F_NOTICE_SECTION),	"NOTICE_SECTION"},
        +{ERR_FUNC(X509V3_F_NREF_NOS),	"NREF_NOS"},
        +{ERR_FUNC(X509V3_F_POLICY_SECTION),	"POLICY_SECTION"},
        +{ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE),	"PROCESS_PCI_VALUE"},
        +{ERR_FUNC(X509V3_F_R2I_CERTPOL),	"R2I_CERTPOL"},
        +{ERR_FUNC(X509V3_F_R2I_PCI),	"R2I_PCI"},
        +{ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING),	"S2I_ASN1_IA5STRING"},
        +{ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER),	"s2i_ASN1_INTEGER"},
        +{ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING),	"s2i_ASN1_OCTET_STRING"},
        +{ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID),	"S2I_ASN1_SKEY_ID"},
        +{ERR_FUNC(X509V3_F_S2I_SKEY_ID),	"S2I_SKEY_ID"},
        +{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME),	"SET_DIST_POINT_NAME"},
        +{ERR_FUNC(X509V3_F_STRING_TO_HEX),	"string_to_hex"},
        +{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC),	"SXNET_add_id_asc"},
        +{ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER),	"SXNET_add_id_INTEGER"},
        +{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG),	"SXNET_add_id_ulong"},
        +{ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC),	"SXNET_get_id_asc"},
        +{ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG),	"SXNET_get_id_ulong"},
        +{ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS),	"V2I_ASIDENTIFIERS"},
        +{ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING),	"v2i_ASN1_BIT_STRING"},
        +{ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS),	"V2I_AUTHORITY_INFO_ACCESS"},
        +{ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID),	"V2I_AUTHORITY_KEYID"},
        +{ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS),	"V2I_BASIC_CONSTRAINTS"},
        +{ERR_FUNC(X509V3_F_V2I_CRLD),	"V2I_CRLD"},
        +{ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE),	"V2I_EXTENDED_KEY_USAGE"},
        +{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES),	"v2i_GENERAL_NAMES"},
        +{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX),	"v2i_GENERAL_NAME_ex"},
        +{ERR_FUNC(X509V3_F_V2I_IDP),	"V2I_IDP"},
        +{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS),	"V2I_IPADDRBLOCKS"},
        +{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT),	"V2I_ISSUER_ALT"},
        +{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS),	"V2I_NAME_CONSTRAINTS"},
        +{ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS),	"V2I_POLICY_CONSTRAINTS"},
        +{ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS),	"V2I_POLICY_MAPPINGS"},
        +{ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT),	"V2I_SUBJECT_ALT"},
        +{ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL),	"V3_ADDR_VALIDATE_PATH_INTERNAL"},
        +{ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION),	"V3_GENERIC_EXTENSION"},
        +{ERR_FUNC(X509V3_F_X509V3_ADD1_I2D),	"X509V3_add1_i2d"},
        +{ERR_FUNC(X509V3_F_X509V3_ADD_VALUE),	"X509V3_add_value"},
        +{ERR_FUNC(X509V3_F_X509V3_EXT_ADD),	"X509V3_EXT_add"},
        +{ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS),	"X509V3_EXT_add_alias"},
        +{ERR_FUNC(X509V3_F_X509V3_EXT_CONF),	"X509V3_EXT_conf"},
        +{ERR_FUNC(X509V3_F_X509V3_EXT_I2D),	"X509V3_EXT_i2d"},
        +{ERR_FUNC(X509V3_F_X509V3_EXT_NCONF),	"X509V3_EXT_nconf"},
        +{ERR_FUNC(X509V3_F_X509V3_GET_SECTION),	"X509V3_get_section"},
        +{ERR_FUNC(X509V3_F_X509V3_GET_STRING),	"X509V3_get_string"},
        +{ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL),	"X509V3_get_value_bool"},
        +{ERR_FUNC(X509V3_F_X509V3_PARSE_LIST),	"X509V3_parse_list"},
        +{ERR_FUNC(X509V3_F_X509_PURPOSE_ADD),	"X509_PURPOSE_add"},
        +{ERR_FUNC(X509V3_F_X509_PURPOSE_SET),	"X509_PURPOSE_set"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA X509V3_str_reasons[]=
        +	{
        +{ERR_REASON(X509V3_R_BAD_IP_ADDRESS)     ,"bad ip address"},
        +{ERR_REASON(X509V3_R_BAD_OBJECT)         ,"bad object"},
        +{ERR_REASON(X509V3_R_BN_DEC2BN_ERROR)    ,"bn dec2bn error"},
        +{ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"},
        +{ERR_REASON(X509V3_R_DIRNAME_ERROR)      ,"dirname error"},
        +{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"},
        +{ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID)  ,"duplicate zone id"},
        +{ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"},
        +{ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"},
        +{ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) ,"error in extension"},
        +{ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME),"expected a section name"},
        +{ERR_REASON(X509V3_R_EXTENSION_EXISTS)   ,"extension exists"},
        +{ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR),"extension name error"},
        +{ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND),"extension not found"},
        +{ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED),"extension setting not supported"},
        +{ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR),"extension value error"},
        +{ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"},
        +{ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT)  ,"illegal hex digit"},
        +{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"},
        +{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS),"invalid multiple rdns"},
        +{ERR_REASON(X509V3_R_INVALID_ASNUMBER)   ,"invalid asnumber"},
        +{ERR_REASON(X509V3_R_INVALID_ASRANGE)    ,"invalid asrange"},
        +{ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"},
        +{ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),"invalid extension string"},
        +{ERR_REASON(X509V3_R_INVALID_INHERITANCE),"invalid inheritance"},
        +{ERR_REASON(X509V3_R_INVALID_IPADDRESS)  ,"invalid ipaddress"},
        +{ERR_REASON(X509V3_R_INVALID_NAME)       ,"invalid name"},
        +{ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT),"invalid null argument"},
        +{ERR_REASON(X509V3_R_INVALID_NULL_NAME)  ,"invalid null name"},
        +{ERR_REASON(X509V3_R_INVALID_NULL_VALUE) ,"invalid null value"},
        +{ERR_REASON(X509V3_R_INVALID_NUMBER)     ,"invalid number"},
        +{ERR_REASON(X509V3_R_INVALID_NUMBERS)    ,"invalid numbers"},
        +{ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER),"invalid object identifier"},
        +{ERR_REASON(X509V3_R_INVALID_OPTION)     ,"invalid option"},
        +{ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),"invalid policy identifier"},
        +{ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),"invalid proxy policy setting"},
        +{ERR_REASON(X509V3_R_INVALID_PURPOSE)    ,"invalid purpose"},
        +{ERR_REASON(X509V3_R_INVALID_SAFI)       ,"invalid safi"},
        +{ERR_REASON(X509V3_R_INVALID_SECTION)    ,"invalid section"},
        +{ERR_REASON(X509V3_R_INVALID_SYNTAX)     ,"invalid syntax"},
        +{ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR),"issuer decode error"},
        +{ERR_REASON(X509V3_R_MISSING_VALUE)      ,"missing value"},
        +{ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),"need organization and numbers"},
        +{ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) ,"no config database"},
        +{ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE),"no issuer certificate"},
        +{ERR_REASON(X509V3_R_NO_ISSUER_DETAILS)  ,"no issuer details"},
        +{ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER),"no policy identifier"},
        +{ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED),"no proxy cert policy language defined"},
        +{ERR_REASON(X509V3_R_NO_PUBLIC_KEY)      ,"no public key"},
        +{ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) ,"no subject details"},
        +{ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"},
        +{ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"},
        +{ERR_REASON(X509V3_R_OTHERNAME_ERROR)    ,"othername error"},
        +{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),"policy language already defined"},
        +{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"},
        +{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),"policy path length already defined"},
        +{ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"},
        +{ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"},
        +{ERR_REASON(X509V3_R_SECTION_NOT_FOUND)  ,"section not found"},
        +{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS),"unable to get issuer details"},
        +{ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID),"unable to get issuer keyid"},
        +{ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT),"unknown bit string argument"},
        +{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION)  ,"unknown extension"},
        +{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"},
        +{ERR_REASON(X509V3_R_UNKNOWN_OPTION)     ,"unknown option"},
        +{ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"},
        +{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE)   ,"unsupported type"},
        +{ERR_REASON(X509V3_R_USER_TOO_LONG)      ,"user too long"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_X509V3_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,X509V3_str_functs);
        +		ERR_load_strings(0,X509V3_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/v3prin.c b/vendor/openssl/openssl/crypto/x509v3/v3prin.c
        new file mode 100644
        index 000000000..d5ff26829
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/v3prin.c
        @@ -0,0 +1,99 @@
        +/* v3prin.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <openssl/asn1.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +
        +int main(int argc, char **argv)
        +{
        +	X509 *cert;
        +	FILE *inf;
        +	int i, count;
        +	X509_EXTENSION *ext;
        +	X509V3_add_standard_extensions();
        +	ERR_load_crypto_strings();
        +	if(!argv[1]) {
        +		fprintf(stderr, "Usage v3prin cert.pem\n");
        +		exit(1);
        +	}
        +	if(!(inf = fopen(argv[1], "r"))) {
        +		fprintf(stderr, "Can't open %s\n", argv[1]);
        +		exit(1);
        +	}
        +	if(!(cert = PEM_read_X509(inf, NULL, NULL))) {
        +		fprintf(stderr, "Can't read certificate %s\n", argv[1]);
        +		ERR_print_errors_fp(stderr);
        +		exit(1);
        +	}
        +	fclose(inf);
        +	count = X509_get_ext_count(cert);
        +	printf("%d extensions\n", count);
        +	for(i = 0; i < count; i++) {
        +		ext = X509_get_ext(cert, i);
        +		printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
        +		if(!X509V3_EXT_print_fp(stdout, ext, 0, 0)) ERR_print_errors_fp(stderr);
        +		printf("\n");
        +		
        +	}
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/crypto/x509v3/x509v3.h b/vendor/openssl/openssl/crypto/x509v3/x509v3.h
        new file mode 100644
        index 000000000..b308abe7c
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x509v3/x509v3.h
        @@ -0,0 +1,1007 @@
        +/* x509v3.h */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project 1999.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2004 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_X509V3_H
        +#define HEADER_X509V3_H
        +
        +#include <openssl/bio.h>
        +#include <openssl/x509.h>
        +#include <openssl/conf.h>
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Forward reference */
        +struct v3_ext_method;
        +struct v3_ext_ctx;
        +
        +/* Useful typedefs */
        +
        +typedef void * (*X509V3_EXT_NEW)(void);
        +typedef void (*X509V3_EXT_FREE)(void *);
        +typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
        +typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
        +typedef STACK_OF(CONF_VALUE) *
        +  (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext,
        +		    STACK_OF(CONF_VALUE) *extlist);
        +typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method,
        +				 struct v3_ext_ctx *ctx,
        +				 STACK_OF(CONF_VALUE) *values);
        +typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext);
        +typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method,
        +				 struct v3_ext_ctx *ctx, const char *str);
        +typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext,
        +			      BIO *out, int indent);
        +typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method,
        +				 struct v3_ext_ctx *ctx, const char *str);
        +
        +/* V3 extension structure */
        +
        +struct v3_ext_method {
        +int ext_nid;
        +int ext_flags;
        +/* If this is set the following four fields are ignored */
        +ASN1_ITEM_EXP *it;
        +/* Old style ASN1 calls */
        +X509V3_EXT_NEW ext_new;
        +X509V3_EXT_FREE ext_free;
        +X509V3_EXT_D2I d2i;
        +X509V3_EXT_I2D i2d;
        +
        +/* The following pair is used for string extensions */
        +X509V3_EXT_I2S i2s;
        +X509V3_EXT_S2I s2i;
        +
        +/* The following pair is used for multi-valued extensions */
        +X509V3_EXT_I2V i2v;
        +X509V3_EXT_V2I v2i;
        +
        +/* The following are used for raw extensions */
        +X509V3_EXT_I2R i2r;
        +X509V3_EXT_R2I r2i;
        +
        +void *usr_data;	/* Any extension specific data */
        +};
        +
        +typedef struct X509V3_CONF_METHOD_st {
        +char * (*get_string)(void *db, char *section, char *value);
        +STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
        +void (*free_string)(void *db, char * string);
        +void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
        +} X509V3_CONF_METHOD;
        +
        +/* Context specific info */
        +struct v3_ext_ctx {
        +#define CTX_TEST 0x1
        +int flags;
        +X509 *issuer_cert;
        +X509 *subject_cert;
        +X509_REQ *subject_req;
        +X509_CRL *crl;
        +X509V3_CONF_METHOD *db_meth;
        +void *db;
        +/* Maybe more here */
        +};
        +
        +typedef struct v3_ext_method X509V3_EXT_METHOD;
        +
        +DECLARE_STACK_OF(X509V3_EXT_METHOD)
        +
        +/* ext_flags values */
        +#define X509V3_EXT_DYNAMIC	0x1
        +#define X509V3_EXT_CTX_DEP	0x2
        +#define X509V3_EXT_MULTILINE	0x4
        +
        +typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
        +
        +typedef struct BASIC_CONSTRAINTS_st {
        +int ca;
        +ASN1_INTEGER *pathlen;
        +} BASIC_CONSTRAINTS;
        +
        +
        +typedef struct PKEY_USAGE_PERIOD_st {
        +ASN1_GENERALIZEDTIME *notBefore;
        +ASN1_GENERALIZEDTIME *notAfter;
        +} PKEY_USAGE_PERIOD;
        +
        +typedef struct otherName_st {
        +ASN1_OBJECT *type_id;
        +ASN1_TYPE *value;
        +} OTHERNAME;
        +
        +typedef struct EDIPartyName_st {
        +	ASN1_STRING *nameAssigner;
        +	ASN1_STRING *partyName;
        +} EDIPARTYNAME;
        +
        +typedef struct GENERAL_NAME_st {
        +
        +#define GEN_OTHERNAME	0
        +#define GEN_EMAIL	1
        +#define GEN_DNS		2
        +#define GEN_X400	3
        +#define GEN_DIRNAME	4
        +#define GEN_EDIPARTY	5
        +#define GEN_URI		6
        +#define GEN_IPADD	7
        +#define GEN_RID		8
        +
        +int type;
        +union {
        +	char *ptr;
        +	OTHERNAME *otherName; /* otherName */
        +	ASN1_IA5STRING *rfc822Name;
        +	ASN1_IA5STRING *dNSName;
        +	ASN1_TYPE *x400Address;
        +	X509_NAME *directoryName;
        +	EDIPARTYNAME *ediPartyName;
        +	ASN1_IA5STRING *uniformResourceIdentifier;
        +	ASN1_OCTET_STRING *iPAddress;
        +	ASN1_OBJECT *registeredID;
        +
        +	/* Old names */
        +	ASN1_OCTET_STRING *ip; /* iPAddress */
        +	X509_NAME *dirn;		/* dirn */
        +	ASN1_IA5STRING *ia5;/* rfc822Name, dNSName, uniformResourceIdentifier */
        +	ASN1_OBJECT *rid; /* registeredID */
        +	ASN1_TYPE *other; /* x400Address */
        +} d;
        +} GENERAL_NAME;
        +
        +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
        +
        +typedef struct ACCESS_DESCRIPTION_st {
        +	ASN1_OBJECT *method;
        +	GENERAL_NAME *location;
        +} ACCESS_DESCRIPTION;
        +
        +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
        +
        +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
        +
        +DECLARE_STACK_OF(GENERAL_NAME)
        +DECLARE_ASN1_SET_OF(GENERAL_NAME)
        +
        +DECLARE_STACK_OF(ACCESS_DESCRIPTION)
        +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)
        +
        +typedef struct DIST_POINT_NAME_st {
        +int type;
        +union {
        +	GENERAL_NAMES *fullname;
        +	STACK_OF(X509_NAME_ENTRY) *relativename;
        +} name;
        +/* If relativename then this contains the full distribution point name */
        +X509_NAME *dpname;
        +} DIST_POINT_NAME;
        +/* All existing reasons */
        +#define CRLDP_ALL_REASONS	0x807f
        +
        +#define CRL_REASON_NONE				-1
        +#define CRL_REASON_UNSPECIFIED			0
        +#define CRL_REASON_KEY_COMPROMISE		1
        +#define CRL_REASON_CA_COMPROMISE		2
        +#define CRL_REASON_AFFILIATION_CHANGED		3
        +#define CRL_REASON_SUPERSEDED			4
        +#define CRL_REASON_CESSATION_OF_OPERATION	5
        +#define CRL_REASON_CERTIFICATE_HOLD		6
        +#define CRL_REASON_REMOVE_FROM_CRL		8
        +#define CRL_REASON_PRIVILEGE_WITHDRAWN		9
        +#define CRL_REASON_AA_COMPROMISE		10
        +
        +struct DIST_POINT_st {
        +DIST_POINT_NAME	*distpoint;
        +ASN1_BIT_STRING *reasons;
        +GENERAL_NAMES *CRLissuer;
        +int dp_reasons;
        +};
        +
        +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
        +
        +DECLARE_STACK_OF(DIST_POINT)
        +DECLARE_ASN1_SET_OF(DIST_POINT)
        +
        +struct AUTHORITY_KEYID_st {
        +ASN1_OCTET_STRING *keyid;
        +GENERAL_NAMES *issuer;
        +ASN1_INTEGER *serial;
        +};
        +
        +/* Strong extranet structures */
        +
        +typedef struct SXNET_ID_st {
        +	ASN1_INTEGER *zone;
        +	ASN1_OCTET_STRING *user;
        +} SXNETID;
        +
        +DECLARE_STACK_OF(SXNETID)
        +DECLARE_ASN1_SET_OF(SXNETID)
        +
        +typedef struct SXNET_st {
        +	ASN1_INTEGER *version;
        +	STACK_OF(SXNETID) *ids;
        +} SXNET;
        +
        +typedef struct NOTICEREF_st {
        +	ASN1_STRING *organization;
        +	STACK_OF(ASN1_INTEGER) *noticenos;
        +} NOTICEREF;
        +
        +typedef struct USERNOTICE_st {
        +	NOTICEREF *noticeref;
        +	ASN1_STRING *exptext;
        +} USERNOTICE;
        +
        +typedef struct POLICYQUALINFO_st {
        +	ASN1_OBJECT *pqualid;
        +	union {
        +		ASN1_IA5STRING *cpsuri;
        +		USERNOTICE *usernotice;
        +		ASN1_TYPE *other;
        +	} d;
        +} POLICYQUALINFO;
        +
        +DECLARE_STACK_OF(POLICYQUALINFO)
        +DECLARE_ASN1_SET_OF(POLICYQUALINFO)
        +
        +typedef struct POLICYINFO_st {
        +	ASN1_OBJECT *policyid;
        +	STACK_OF(POLICYQUALINFO) *qualifiers;
        +} POLICYINFO;
        +
        +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
        +
        +DECLARE_STACK_OF(POLICYINFO)
        +DECLARE_ASN1_SET_OF(POLICYINFO)
        +
        +typedef struct POLICY_MAPPING_st {
        +	ASN1_OBJECT *issuerDomainPolicy;
        +	ASN1_OBJECT *subjectDomainPolicy;
        +} POLICY_MAPPING;
        +
        +DECLARE_STACK_OF(POLICY_MAPPING)
        +
        +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
        +
        +typedef struct GENERAL_SUBTREE_st {
        +	GENERAL_NAME *base;
        +	ASN1_INTEGER *minimum;
        +	ASN1_INTEGER *maximum;
        +} GENERAL_SUBTREE;
        +
        +DECLARE_STACK_OF(GENERAL_SUBTREE)
        +
        +struct NAME_CONSTRAINTS_st {
        +	STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
        +	STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
        +};
        +
        +typedef struct POLICY_CONSTRAINTS_st {
        +	ASN1_INTEGER *requireExplicitPolicy;
        +	ASN1_INTEGER *inhibitPolicyMapping;
        +} POLICY_CONSTRAINTS;
        +
        +/* Proxy certificate structures, see RFC 3820 */
        +typedef struct PROXY_POLICY_st
        +	{
        +	ASN1_OBJECT *policyLanguage;
        +	ASN1_OCTET_STRING *policy;
        +	} PROXY_POLICY;
        +
        +typedef struct PROXY_CERT_INFO_EXTENSION_st
        +	{
        +	ASN1_INTEGER *pcPathLengthConstraint;
        +	PROXY_POLICY *proxyPolicy;
        +	} PROXY_CERT_INFO_EXTENSION;
        +
        +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
        +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
        +
        +struct ISSUING_DIST_POINT_st
        +	{
        +	DIST_POINT_NAME *distpoint;
        +	int onlyuser;
        +	int onlyCA;
        +	ASN1_BIT_STRING *onlysomereasons;
        +	int indirectCRL;
        +	int onlyattr;
        +	};
        +
        +/* Values in idp_flags field */
        +/* IDP present */
        +#define	IDP_PRESENT	0x1
        +/* IDP values inconsistent */
        +#define IDP_INVALID	0x2
        +/* onlyuser true */
        +#define	IDP_ONLYUSER	0x4
        +/* onlyCA true */
        +#define	IDP_ONLYCA	0x8
        +/* onlyattr true */
        +#define IDP_ONLYATTR	0x10
        +/* indirectCRL true */
        +#define IDP_INDIRECT	0x20
        +/* onlysomereasons present */
        +#define IDP_REASONS	0x40
        +
        +#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
        +",name:", val->name, ",value:", val->value);
        +
        +#define X509V3_set_ctx_test(ctx) \
        +			X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
        +#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
        +
        +#define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
        +			0,0,0,0, \
        +			0,0, \
        +			(X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
        +			(X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
        +			NULL, NULL, \
        +			table}
        +
        +#define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
        +			0,0,0,0, \
        +			(X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
        +			(X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
        +			0,0,0,0, \
        +			NULL}
        +
        +#define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        +
        +
        +/* X509_PURPOSE stuff */
        +
        +#define EXFLAG_BCONS		0x1
        +#define EXFLAG_KUSAGE		0x2
        +#define EXFLAG_XKUSAGE		0x4
        +#define EXFLAG_NSCERT		0x8
        +
        +#define EXFLAG_CA		0x10
        +/* Really self issued not necessarily self signed */
        +#define EXFLAG_SI		0x20
        +#define EXFLAG_SS		0x20
        +#define EXFLAG_V1		0x40
        +#define EXFLAG_INVALID		0x80
        +#define EXFLAG_SET		0x100
        +#define EXFLAG_CRITICAL		0x200
        +#define EXFLAG_PROXY		0x400
        +
        +#define EXFLAG_INVALID_POLICY	0x800
        +#define EXFLAG_FRESHEST		0x1000
        +
        +#define KU_DIGITAL_SIGNATURE	0x0080
        +#define KU_NON_REPUDIATION	0x0040
        +#define KU_KEY_ENCIPHERMENT	0x0020
        +#define KU_DATA_ENCIPHERMENT	0x0010
        +#define KU_KEY_AGREEMENT	0x0008
        +#define KU_KEY_CERT_SIGN	0x0004
        +#define KU_CRL_SIGN		0x0002
        +#define KU_ENCIPHER_ONLY	0x0001
        +#define KU_DECIPHER_ONLY	0x8000
        +
        +#define NS_SSL_CLIENT		0x80
        +#define NS_SSL_SERVER		0x40
        +#define NS_SMIME		0x20
        +#define NS_OBJSIGN		0x10
        +#define NS_SSL_CA		0x04
        +#define NS_SMIME_CA		0x02
        +#define NS_OBJSIGN_CA		0x01
        +#define NS_ANY_CA		(NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
        +
        +#define XKU_SSL_SERVER		0x1	
        +#define XKU_SSL_CLIENT		0x2
        +#define XKU_SMIME		0x4
        +#define XKU_CODE_SIGN		0x8
        +#define XKU_SGC			0x10
        +#define XKU_OCSP_SIGN		0x20
        +#define XKU_TIMESTAMP		0x40
        +#define XKU_DVCS		0x80
        +
        +#define X509_PURPOSE_DYNAMIC	0x1
        +#define X509_PURPOSE_DYNAMIC_NAME	0x2
        +
        +typedef struct x509_purpose_st {
        +	int purpose;
        +	int trust;		/* Default trust ID */
        +	int flags;
        +	int (*check_purpose)(const struct x509_purpose_st *,
        +				const X509 *, int);
        +	char *name;
        +	char *sname;
        +	void *usr_data;
        +} X509_PURPOSE;
        +
        +#define X509_PURPOSE_SSL_CLIENT		1
        +#define X509_PURPOSE_SSL_SERVER		2
        +#define X509_PURPOSE_NS_SSL_SERVER	3
        +#define X509_PURPOSE_SMIME_SIGN		4
        +#define X509_PURPOSE_SMIME_ENCRYPT	5
        +#define X509_PURPOSE_CRL_SIGN		6
        +#define X509_PURPOSE_ANY		7
        +#define X509_PURPOSE_OCSP_HELPER	8
        +#define X509_PURPOSE_TIMESTAMP_SIGN	9
        +
        +#define X509_PURPOSE_MIN		1
        +#define X509_PURPOSE_MAX		9
        +
        +/* Flags for X509V3_EXT_print() */
        +
        +#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
        +/* Return error for unknown extensions */
        +#define X509V3_EXT_DEFAULT		0
        +/* Print error for unknown extensions */
        +#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
        +/* ASN1 parse unknown extensions */
        +#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
        +/* BIO_dump unknown extensions */
        +#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
        +
        +/* Flags for X509V3_add1_i2d */
        +
        +#define X509V3_ADD_OP_MASK		0xfL
        +#define X509V3_ADD_DEFAULT		0L
        +#define X509V3_ADD_APPEND		1L
        +#define X509V3_ADD_REPLACE		2L
        +#define X509V3_ADD_REPLACE_EXISTING	3L
        +#define X509V3_ADD_KEEP_EXISTING	4L
        +#define X509V3_ADD_DELETE		5L
        +#define X509V3_ADD_SILENT		0x10
        +
        +DECLARE_STACK_OF(X509_PURPOSE)
        +
        +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
        +
        +DECLARE_ASN1_FUNCTIONS(SXNET)
        +DECLARE_ASN1_FUNCTIONS(SXNETID)
        +
        +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); 
        +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, int userlen); 
        +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, int userlen); 
        +
        +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
        +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
        +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
        +
        +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
        +
        +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
        +
        +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
        +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
        +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
        +
        +
        +
        +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
        +				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
        +				ASN1_BIT_STRING *bits,
        +				STACK_OF(CONF_VALUE) *extlist);
        +
        +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
        +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
        +
        +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
        +
        +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
        +		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
        +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
        +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
        +
        +DECLARE_ASN1_FUNCTIONS(OTHERNAME)
        +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
        +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
        +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
        +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
        +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
        +				ASN1_OBJECT *oid, ASN1_TYPE *value);
        +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
        +				ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
        +
        +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
        +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
        +
        +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
        +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a);
        +
        +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
        +DECLARE_ASN1_FUNCTIONS(POLICYINFO)
        +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
        +DECLARE_ASN1_FUNCTIONS(USERNOTICE)
        +DECLARE_ASN1_FUNCTIONS(NOTICEREF)
        +
        +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
        +DECLARE_ASN1_FUNCTIONS(DIST_POINT)
        +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
        +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
        +
        +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
        +
        +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
        +
        +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
        +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
        +
        +DECLARE_ASN1_ITEM(POLICY_MAPPING)
        +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
        +DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
        +
        +DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
        +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
        +
        +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
        +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
        +
        +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
        +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
        +
        +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
        +			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +			       int gen_type, char *value, int is_nc);
        +
        +#ifdef HEADER_CONF_H
        +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
        +			       CONF_VALUE *cnf);
        +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
        +				  const X509V3_EXT_METHOD *method,
        +				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
        +void X509V3_conf_free(CONF_VALUE *val);
        +
        +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
        +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
        +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
        +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert);
        +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
        +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
        +
        +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +				    int ext_nid, char *value);
        +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +				char *name, char *value);
        +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +			char *section, X509 *cert);
        +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +			    char *section, X509_REQ *req);
        +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
        +			    char *section, X509_CRL *crl);
        +
        +int X509V3_add_value_bool_nf(char *name, int asn1_bool,
        +			     STACK_OF(CONF_VALUE) **extlist);
        +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
        +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
        +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
        +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
        +#endif
        +
        +char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
        +STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
        +void X509V3_string_free(X509V3_CTX *ctx, char *str);
        +void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
        +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
        +				 X509_REQ *req, X509_CRL *crl, int flags);
        +
        +int X509V3_add_value(const char *name, const char *value,
        +						STACK_OF(CONF_VALUE) **extlist);
        +int X509V3_add_value_uchar(const char *name, const unsigned char *value,
        +						STACK_OF(CONF_VALUE) **extlist);
        +int X509V3_add_value_bool(const char *name, int asn1_bool,
        +						STACK_OF(CONF_VALUE) **extlist);
        +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
        +						STACK_OF(CONF_VALUE) **extlist);
        +char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
        +ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
        +char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
        +char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
        +int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
        +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
        +int X509V3_EXT_add_alias(int nid_to, int nid_from);
        +void X509V3_EXT_cleanup(void);
        +
        +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
        +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
        +int X509V3_add_standard_extensions(void);
        +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
        +void *X509V3_EXT_d2i(X509_EXTENSION *ext);
        +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
        +
        +
        +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
        +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
        +
        +char *hex_to_string(const unsigned char *buffer, long len);
        +unsigned char *string_to_hex(const char *str, long *len);
        +int name_cmp(const char *name, const char *cmp);
        +
        +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
        +								 int ml);
        +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
        +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
        +
        +int X509V3_extensions_print(BIO *out, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
        +
        +int X509_check_ca(X509 *x);
        +int X509_check_purpose(X509 *x, int id, int ca);
        +int X509_supported_extension(X509_EXTENSION *ex);
        +int X509_PURPOSE_set(int *p, int purpose);
        +int X509_check_issued(X509 *issuer, X509 *subject);
        +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
        +int X509_PURPOSE_get_count(void);
        +X509_PURPOSE * X509_PURPOSE_get0(int idx);
        +int X509_PURPOSE_get_by_sname(char *sname);
        +int X509_PURPOSE_get_by_id(int id);
        +int X509_PURPOSE_add(int id, int trust, int flags,
        +			int (*ck)(const X509_PURPOSE *, const X509 *, int),
        +				char *name, char *sname, void *arg);
        +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
        +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
        +int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
        +void X509_PURPOSE_cleanup(void);
        +int X509_PURPOSE_get_id(X509_PURPOSE *);
        +
        +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
        +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
        +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
        +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
        +
        +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
        +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
        +int a2i_ipadd(unsigned char *ipout, const char *ipasc);
        +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
        +						unsigned long chtype);
        +
        +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
        +DECLARE_STACK_OF(X509_POLICY_NODE)
        +
        +#ifndef OPENSSL_NO_RFC3779
        +
        +typedef struct ASRange_st {
        +  ASN1_INTEGER *min, *max;
        +} ASRange;
        +
        +#define	ASIdOrRange_id		0
        +#define	ASIdOrRange_range	1
        +
        +typedef struct ASIdOrRange_st {
        +  int type;
        +  union {
        +    ASN1_INTEGER *id;
        +    ASRange      *range;
        +  } u;
        +} ASIdOrRange;
        +
        +typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
        +DECLARE_STACK_OF(ASIdOrRange)
        +
        +#define	ASIdentifierChoice_inherit		0
        +#define	ASIdentifierChoice_asIdsOrRanges	1
        +
        +typedef struct ASIdentifierChoice_st {
        +  int type;
        +  union {
        +    ASN1_NULL    *inherit;
        +    ASIdOrRanges *asIdsOrRanges;
        +  } u;
        +} ASIdentifierChoice;
        +
        +typedef struct ASIdentifiers_st {
        +  ASIdentifierChoice *asnum, *rdi;
        +} ASIdentifiers;
        +
        +DECLARE_ASN1_FUNCTIONS(ASRange)
        +DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
        +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
        +DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
        +
        +
        +typedef struct IPAddressRange_st {
        +  ASN1_BIT_STRING	*min, *max;
        +} IPAddressRange;
        +
        +#define	IPAddressOrRange_addressPrefix	0
        +#define	IPAddressOrRange_addressRange	1
        +
        +typedef struct IPAddressOrRange_st {
        +  int type;
        +  union {
        +    ASN1_BIT_STRING	*addressPrefix;
        +    IPAddressRange	*addressRange;
        +  } u;
        +} IPAddressOrRange;
        +
        +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
        +DECLARE_STACK_OF(IPAddressOrRange)
        +
        +#define	IPAddressChoice_inherit			0
        +#define	IPAddressChoice_addressesOrRanges	1
        +
        +typedef struct IPAddressChoice_st {
        +  int type;
        +  union {
        +    ASN1_NULL		*inherit;
        +    IPAddressOrRanges	*addressesOrRanges;
        +  } u;
        +} IPAddressChoice;
        +
        +typedef struct IPAddressFamily_st {
        +  ASN1_OCTET_STRING	*addressFamily;
        +  IPAddressChoice	*ipAddressChoice;
        +} IPAddressFamily;
        +
        +typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
        +DECLARE_STACK_OF(IPAddressFamily)
        +
        +DECLARE_ASN1_FUNCTIONS(IPAddressRange)
        +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
        +DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
        +DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
        +
        +/*
        + * API tag for elements of the ASIdentifer SEQUENCE.
        + */
        +#define	V3_ASID_ASNUM	0
        +#define	V3_ASID_RDI	1
        +
        +/*
        + * AFI values, assigned by IANA.  It'd be nice to make the AFI
        + * handling code totally generic, but there are too many little things
        + * that would need to be defined for other address families for it to
        + * be worth the trouble.
        + */
        +#define	IANA_AFI_IPV4	1
        +#define	IANA_AFI_IPV6	2
        +
        +/*
        + * Utilities to construct and extract values from RFC3779 extensions,
        + * since some of the encodings (particularly for IP address prefixes
        + * and ranges) are a bit tedious to work with directly.
        + */
        +int v3_asid_add_inherit(ASIdentifiers *asid, int which);
        +int v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
        +			    ASN1_INTEGER *min, ASN1_INTEGER *max);
        +int v3_addr_add_inherit(IPAddrBlocks *addr,
        +			const unsigned afi, const unsigned *safi);
        +int v3_addr_add_prefix(IPAddrBlocks *addr,
        +		       const unsigned afi, const unsigned *safi,
        +		       unsigned char *a, const int prefixlen);
        +int v3_addr_add_range(IPAddrBlocks *addr,
        +		      const unsigned afi, const unsigned *safi,
        +		      unsigned char *min, unsigned char *max);
        +unsigned v3_addr_get_afi(const IPAddressFamily *f);
        +int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
        +		      unsigned char *min, unsigned char *max,
        +		      const int length);
        +
        +/*
        + * Canonical forms.
        + */
        +int v3_asid_is_canonical(ASIdentifiers *asid);
        +int v3_addr_is_canonical(IPAddrBlocks *addr);
        +int v3_asid_canonize(ASIdentifiers *asid);
        +int v3_addr_canonize(IPAddrBlocks *addr);
        +
        +/*
        + * Tests for inheritance and containment.
        + */
        +int v3_asid_inherits(ASIdentifiers *asid);
        +int v3_addr_inherits(IPAddrBlocks *addr);
        +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
        +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
        +
        +/*
        + * Check whether RFC 3779 extensions nest properly in chains.
        + */
        +int v3_asid_validate_path(X509_STORE_CTX *);
        +int v3_addr_validate_path(X509_STORE_CTX *);
        +int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
        +				  ASIdentifiers *ext,
        +				  int allow_inheritance);
        +int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
        +				  IPAddrBlocks *ext,
        +				  int allow_inheritance);
        +
        +#endif /* OPENSSL_NO_RFC3779 */
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_X509V3_strings(void);
        +
        +/* Error codes for the X509V3 functions. */
        +
        +/* Function codes. */
        +#define X509V3_F_A2I_GENERAL_NAME			 164
        +#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 161
        +#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 162
        +#define X509V3_F_COPY_EMAIL				 122
        +#define X509V3_F_COPY_ISSUER				 123
        +#define X509V3_F_DO_DIRNAME				 144
        +#define X509V3_F_DO_EXT_CONF				 124
        +#define X509V3_F_DO_EXT_I2D				 135
        +#define X509V3_F_DO_EXT_NCONF				 151
        +#define X509V3_F_DO_I2V_NAME_CONSTRAINTS		 148
        +#define X509V3_F_GNAMES_FROM_SECTNAME			 156
        +#define X509V3_F_HEX_TO_STRING				 111
        +#define X509V3_F_I2S_ASN1_ENUMERATED			 121
        +#define X509V3_F_I2S_ASN1_IA5STRING			 149
        +#define X509V3_F_I2S_ASN1_INTEGER			 120
        +#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS		 138
        +#define X509V3_F_NOTICE_SECTION				 132
        +#define X509V3_F_NREF_NOS				 133
        +#define X509V3_F_POLICY_SECTION				 131
        +#define X509V3_F_PROCESS_PCI_VALUE			 150
        +#define X509V3_F_R2I_CERTPOL				 130
        +#define X509V3_F_R2I_PCI				 155
        +#define X509V3_F_S2I_ASN1_IA5STRING			 100
        +#define X509V3_F_S2I_ASN1_INTEGER			 108
        +#define X509V3_F_S2I_ASN1_OCTET_STRING			 112
        +#define X509V3_F_S2I_ASN1_SKEY_ID			 114
        +#define X509V3_F_S2I_SKEY_ID				 115
        +#define X509V3_F_SET_DIST_POINT_NAME			 158
        +#define X509V3_F_STRING_TO_HEX				 113
        +#define X509V3_F_SXNET_ADD_ID_ASC			 125
        +#define X509V3_F_SXNET_ADD_ID_INTEGER			 126
        +#define X509V3_F_SXNET_ADD_ID_ULONG			 127
        +#define X509V3_F_SXNET_GET_ID_ASC			 128
        +#define X509V3_F_SXNET_GET_ID_ULONG			 129
        +#define X509V3_F_V2I_ASIDENTIFIERS			 163
        +#define X509V3_F_V2I_ASN1_BIT_STRING			 101
        +#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
        +#define X509V3_F_V2I_AUTHORITY_KEYID			 119
        +#define X509V3_F_V2I_BASIC_CONSTRAINTS			 102
        +#define X509V3_F_V2I_CRLD				 134
        +#define X509V3_F_V2I_EXTENDED_KEY_USAGE			 103
        +#define X509V3_F_V2I_GENERAL_NAMES			 118
        +#define X509V3_F_V2I_GENERAL_NAME_EX			 117
        +#define X509V3_F_V2I_IDP				 157
        +#define X509V3_F_V2I_IPADDRBLOCKS			 159
        +#define X509V3_F_V2I_ISSUER_ALT				 153
        +#define X509V3_F_V2I_NAME_CONSTRAINTS			 147
        +#define X509V3_F_V2I_POLICY_CONSTRAINTS			 146
        +#define X509V3_F_V2I_POLICY_MAPPINGS			 145
        +#define X509V3_F_V2I_SUBJECT_ALT			 154
        +#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL		 160
        +#define X509V3_F_V3_GENERIC_EXTENSION			 116
        +#define X509V3_F_X509V3_ADD1_I2D			 140
        +#define X509V3_F_X509V3_ADD_VALUE			 105
        +#define X509V3_F_X509V3_EXT_ADD				 104
        +#define X509V3_F_X509V3_EXT_ADD_ALIAS			 106
        +#define X509V3_F_X509V3_EXT_CONF			 107
        +#define X509V3_F_X509V3_EXT_I2D				 136
        +#define X509V3_F_X509V3_EXT_NCONF			 152
        +#define X509V3_F_X509V3_GET_SECTION			 142
        +#define X509V3_F_X509V3_GET_STRING			 143
        +#define X509V3_F_X509V3_GET_VALUE_BOOL			 110
        +#define X509V3_F_X509V3_PARSE_LIST			 109
        +#define X509V3_F_X509_PURPOSE_ADD			 137
        +#define X509V3_F_X509_PURPOSE_SET			 141
        +
        +/* Reason codes. */
        +#define X509V3_R_BAD_IP_ADDRESS				 118
        +#define X509V3_R_BAD_OBJECT				 119
        +#define X509V3_R_BN_DEC2BN_ERROR			 100
        +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
        +#define X509V3_R_DIRNAME_ERROR				 149
        +#define X509V3_R_DISTPOINT_ALREADY_SET			 160
        +#define X509V3_R_DUPLICATE_ZONE_ID			 133
        +#define X509V3_R_ERROR_CONVERTING_ZONE			 131
        +#define X509V3_R_ERROR_CREATING_EXTENSION		 144
        +#define X509V3_R_ERROR_IN_EXTENSION			 128
        +#define X509V3_R_EXPECTED_A_SECTION_NAME		 137
        +#define X509V3_R_EXTENSION_EXISTS			 145
        +#define X509V3_R_EXTENSION_NAME_ERROR			 115
        +#define X509V3_R_EXTENSION_NOT_FOUND			 102
        +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED	 103
        +#define X509V3_R_EXTENSION_VALUE_ERROR			 116
        +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION		 151
        +#define X509V3_R_ILLEGAL_HEX_DIGIT			 113
        +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
        +#define X509V3_R_INVALID_MULTIPLE_RDNS			 161
        +#define X509V3_R_INVALID_ASNUMBER			 162
        +#define X509V3_R_INVALID_ASRANGE			 163
        +#define X509V3_R_INVALID_BOOLEAN_STRING			 104
        +#define X509V3_R_INVALID_EXTENSION_STRING		 105
        +#define X509V3_R_INVALID_INHERITANCE			 165
        +#define X509V3_R_INVALID_IPADDRESS			 166
        +#define X509V3_R_INVALID_NAME				 106
        +#define X509V3_R_INVALID_NULL_ARGUMENT			 107
        +#define X509V3_R_INVALID_NULL_NAME			 108
        +#define X509V3_R_INVALID_NULL_VALUE			 109
        +#define X509V3_R_INVALID_NUMBER				 140
        +#define X509V3_R_INVALID_NUMBERS			 141
        +#define X509V3_R_INVALID_OBJECT_IDENTIFIER		 110
        +#define X509V3_R_INVALID_OPTION				 138
        +#define X509V3_R_INVALID_POLICY_IDENTIFIER		 134
        +#define X509V3_R_INVALID_PROXY_POLICY_SETTING		 153
        +#define X509V3_R_INVALID_PURPOSE			 146
        +#define X509V3_R_INVALID_SAFI				 164
        +#define X509V3_R_INVALID_SECTION			 135
        +#define X509V3_R_INVALID_SYNTAX				 143
        +#define X509V3_R_ISSUER_DECODE_ERROR			 126
        +#define X509V3_R_MISSING_VALUE				 124
        +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS		 142
        +#define X509V3_R_NO_CONFIG_DATABASE			 136
        +#define X509V3_R_NO_ISSUER_CERTIFICATE			 121
        +#define X509V3_R_NO_ISSUER_DETAILS			 127
        +#define X509V3_R_NO_POLICY_IDENTIFIER			 139
        +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED	 154
        +#define X509V3_R_NO_PUBLIC_KEY				 114
        +#define X509V3_R_NO_SUBJECT_DETAILS			 125
        +#define X509V3_R_ODD_NUMBER_OF_DIGITS			 112
        +#define X509V3_R_OPERATION_NOT_DEFINED			 148
        +#define X509V3_R_OTHERNAME_ERROR			 147
        +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED	 155
        +#define X509V3_R_POLICY_PATH_LENGTH			 156
        +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED	 157
        +#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
        +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
        +#define X509V3_R_SECTION_NOT_FOUND			 150
        +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122
        +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123
        +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT		 111
        +#define X509V3_R_UNKNOWN_EXTENSION			 129
        +#define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
        +#define X509V3_R_UNKNOWN_OPTION				 120
        +#define X509V3_R_UNSUPPORTED_OPTION			 117
        +#define X509V3_R_UNSUPPORTED_TYPE			 167
        +#define X509V3_R_USER_TOO_LONG				 132
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/crypto/x86_64cpuid.pl b/vendor/openssl/openssl/crypto/x86_64cpuid.pl
        new file mode 100644
        index 000000000..6ebfd017e
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x86_64cpuid.pl
        @@ -0,0 +1,284 @@
        +#!/usr/bin/env perl
        +
        +$flavour = shift;
        +$output  = shift;
        +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
        +
        +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
        +( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or
        +die "can't locate x86_64-xlate.pl";
        +
        +open OUT,"| \"$^X\" $xlate $flavour $output";
        +*STDOUT=*OUT;
        +
        +($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") :	# Win64 order
        +				 ("%rdi","%rsi","%rdx","%rcx");	# Unix order
        +
        +print<<___;
        +.extern		OPENSSL_cpuid_setup
        +.hidden		OPENSSL_cpuid_setup
        +.section	.init
        +	call	OPENSSL_cpuid_setup
        +
        +.hidden	OPENSSL_ia32cap_P
        +.comm	OPENSSL_ia32cap_P,8,4
        +
        +.text
        +
        +.globl	OPENSSL_atomic_add
        +.type	OPENSSL_atomic_add,\@abi-omnipotent
        +.align	16
        +OPENSSL_atomic_add:
        +	movl	($arg1),%eax
        +.Lspin:	leaq	($arg2,%rax),%r8
        +	.byte	0xf0		# lock
        +	cmpxchgl	%r8d,($arg1)
        +	jne	.Lspin
        +	movl	%r8d,%eax
        +	.byte	0x48,0x98	# cltq/cdqe
        +	ret
        +.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
        +
        +.globl	OPENSSL_rdtsc
        +.type	OPENSSL_rdtsc,\@abi-omnipotent
        +.align	16
        +OPENSSL_rdtsc:
        +	rdtsc
        +	shl	\$32,%rdx
        +	or	%rdx,%rax
        +	ret
        +.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
        +
        +.globl	OPENSSL_ia32_cpuid
        +.type	OPENSSL_ia32_cpuid,\@abi-omnipotent
        +.align	16
        +OPENSSL_ia32_cpuid:
        +	mov	%rbx,%r8		# save %rbx
        +
        +	xor	%eax,%eax
        +	cpuid
        +	mov	%eax,%r11d		# max value for standard query level
        +
        +	xor	%eax,%eax
        +	cmp	\$0x756e6547,%ebx	# "Genu"
        +	setne	%al
        +	mov	%eax,%r9d
        +	cmp	\$0x49656e69,%edx	# "ineI"
        +	setne	%al
        +	or	%eax,%r9d
        +	cmp	\$0x6c65746e,%ecx	# "ntel"
        +	setne	%al
        +	or	%eax,%r9d		# 0 indicates Intel CPU
        +	jz	.Lintel
        +
        +	cmp	\$0x68747541,%ebx	# "Auth"
        +	setne	%al
        +	mov	%eax,%r10d
        +	cmp	\$0x69746E65,%edx	# "enti"
        +	setne	%al
        +	or	%eax,%r10d
        +	cmp	\$0x444D4163,%ecx	# "cAMD"
        +	setne	%al
        +	or	%eax,%r10d		# 0 indicates AMD CPU
        +	jnz	.Lintel
        +
        +	# AMD specific
        +	mov	\$0x80000000,%eax
        +	cpuid
        +	cmp	\$0x80000001,%eax
        +	jb	.Lintel
        +	mov	%eax,%r10d
        +	mov	\$0x80000001,%eax
        +	cpuid
        +	or	%ecx,%r9d
        +	and	\$0x00000801,%r9d	# isolate AMD XOP bit, 1<<11
        +
        +	cmp	\$0x80000008,%r10d
        +	jb	.Lintel
        +
        +	mov	\$0x80000008,%eax
        +	cpuid
        +	movzb	%cl,%r10		# number of cores - 1
        +	inc	%r10			# number of cores
        +
        +	mov	\$1,%eax
        +	cpuid
        +	bt	\$28,%edx		# test hyper-threading bit
        +	jnc	.Lgeneric
        +	shr	\$16,%ebx		# number of logical processors
        +	cmp	%r10b,%bl
        +	ja	.Lgeneric
        +	and	\$0xefffffff,%edx	# ~(1<<28)
        +	jmp	.Lgeneric
        +
        +.Lintel:
        +	cmp	\$4,%r11d
        +	mov	\$-1,%r10d
        +	jb	.Lnocacheinfo
        +
        +	mov	\$4,%eax
        +	mov	\$0,%ecx		# query L1D
        +	cpuid
        +	mov	%eax,%r10d
        +	shr	\$14,%r10d
        +	and	\$0xfff,%r10d		# number of cores -1 per L1D
        +
        +.Lnocacheinfo:
        +	mov	\$1,%eax
        +	cpuid
        +	and	\$0xbfefffff,%edx	# force reserved bits to 0
        +	cmp	\$0,%r9d
        +	jne	.Lnotintel
        +	or	\$0x40000000,%edx	# set reserved bit#30 on Intel CPUs
        +	and	\$15,%ah
        +	cmp	\$15,%ah		# examine Family ID
        +	jne	.Lnotintel
        +	or	\$0x00100000,%edx	# set reserved bit#20 to engage RC4_CHAR
        +.Lnotintel:
        +	bt	\$28,%edx		# test hyper-threading bit
        +	jnc	.Lgeneric
        +	and	\$0xefffffff,%edx	# ~(1<<28)
        +	cmp	\$0,%r10d
        +	je	.Lgeneric
        +
        +	or	\$0x10000000,%edx	# 1<<28
        +	shr	\$16,%ebx
        +	cmp	\$1,%bl			# see if cache is shared
        +	ja	.Lgeneric
        +	and	\$0xefffffff,%edx	# ~(1<<28)
        +.Lgeneric:
        +	and	\$0x00000800,%r9d	# isolate AMD XOP flag
        +	and	\$0xfffff7ff,%ecx
        +	or	%ecx,%r9d		# merge AMD XOP flag
        +
        +	mov	%edx,%r10d		# %r9d:%r10d is copy of %ecx:%edx
        +	bt	\$27,%r9d		# check OSXSAVE bit
        +	jnc	.Lclear_avx
        +	xor	%ecx,%ecx		# XCR0
        +	.byte	0x0f,0x01,0xd0		# xgetbv
        +	and	\$6,%eax		# isolate XMM and YMM state support
        +	cmp	\$6,%eax
        +	je	.Ldone
        +.Lclear_avx:
        +	mov	\$0xefffe7ff,%eax	# ~(1<<28|1<<12|1<<11)
        +	and	%eax,%r9d		# clear AVX, FMA and AMD XOP bits
        +.Ldone:
        +	shl	\$32,%r9
        +	mov	%r10d,%eax
        +	mov	%r8,%rbx		# restore %rbx
        +	or	%r9,%rax
        +	ret
        +.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
        +
        +.globl  OPENSSL_cleanse
        +.type   OPENSSL_cleanse,\@abi-omnipotent
        +.align  16
        +OPENSSL_cleanse:
        +	xor	%rax,%rax
        +	cmp	\$15,$arg2
        +	jae	.Lot
        +	cmp	\$0,$arg2
        +	je	.Lret
        +.Little:
        +	mov	%al,($arg1)
        +	sub	\$1,$arg2
        +	lea	1($arg1),$arg1
        +	jnz	.Little
        +.Lret:
        +	ret
        +.align	16
        +.Lot:
        +	test	\$7,$arg1
        +	jz	.Laligned
        +	mov	%al,($arg1)
        +	lea	-1($arg2),$arg2
        +	lea	1($arg1),$arg1
        +	jmp	.Lot
        +.Laligned:
        +	mov	%rax,($arg1)
        +	lea	-8($arg2),$arg2
        +	test	\$-8,$arg2
        +	lea	8($arg1),$arg1
        +	jnz	.Laligned
        +	cmp	\$0,$arg2
        +	jne	.Little
        +	ret
        +.size	OPENSSL_cleanse,.-OPENSSL_cleanse
        +___
        +
        +print<<___ if (!$win64);
        +.globl	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,\@abi-omnipotent
        +.align	16
        +OPENSSL_wipe_cpu:
        +	pxor	%xmm0,%xmm0
        +	pxor	%xmm1,%xmm1
        +	pxor	%xmm2,%xmm2
        +	pxor	%xmm3,%xmm3
        +	pxor	%xmm4,%xmm4
        +	pxor	%xmm5,%xmm5
        +	pxor	%xmm6,%xmm6
        +	pxor	%xmm7,%xmm7
        +	pxor	%xmm8,%xmm8
        +	pxor	%xmm9,%xmm9
        +	pxor	%xmm10,%xmm10
        +	pxor	%xmm11,%xmm11
        +	pxor	%xmm12,%xmm12
        +	pxor	%xmm13,%xmm13
        +	pxor	%xmm14,%xmm14
        +	pxor	%xmm15,%xmm15
        +	xorq	%rcx,%rcx
        +	xorq	%rdx,%rdx
        +	xorq	%rsi,%rsi
        +	xorq	%rdi,%rdi
        +	xorq	%r8,%r8
        +	xorq	%r9,%r9
        +	xorq	%r10,%r10
        +	xorq	%r11,%r11
        +	leaq	8(%rsp),%rax
        +	ret
        +.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
        +___
        +print<<___ if ($win64);
        +.globl	OPENSSL_wipe_cpu
        +.type	OPENSSL_wipe_cpu,\@abi-omnipotent
        +.align	16
        +OPENSSL_wipe_cpu:
        +	pxor	%xmm0,%xmm0
        +	pxor	%xmm1,%xmm1
        +	pxor	%xmm2,%xmm2
        +	pxor	%xmm3,%xmm3
        +	pxor	%xmm4,%xmm4
        +	pxor	%xmm5,%xmm5
        +	xorq	%rcx,%rcx
        +	xorq	%rdx,%rdx
        +	xorq	%r8,%r8
        +	xorq	%r9,%r9
        +	xorq	%r10,%r10
        +	xorq	%r11,%r11
        +	leaq	8(%rsp),%rax
        +	ret
        +.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
        +___
        +
        +print<<___;
        +.globl	OPENSSL_ia32_rdrand
        +.type	OPENSSL_ia32_rdrand,\@abi-omnipotent
        +.align	16
        +OPENSSL_ia32_rdrand:
        +	mov	\$8,%ecx
        +.Loop_rdrand:
        +	rdrand	%rax
        +	jc	.Lbreak_rdrand
        +	loop	.Loop_rdrand
        +.Lbreak_rdrand:
        +	cmp	\$0,%rax
        +	cmove	%rcx,%rax
        +	ret
        +.size	OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand
        +___
        +
        +close STDOUT;	# flush
        diff --git a/vendor/openssl/openssl/crypto/x86cpuid.pl b/vendor/openssl/openssl/crypto/x86cpuid.pl
        new file mode 100644
        index 000000000..c18b0e248
        --- /dev/null
        +++ b/vendor/openssl/openssl/crypto/x86cpuid.pl
        @@ -0,0 +1,356 @@
        +#!/usr/bin/env perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC, "${dir}perlasm", "perlasm");
        +require "x86asm.pl";
        +
        +&asm_init($ARGV[0],"x86cpuid");
        +
        +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        +
        +&function_begin("OPENSSL_ia32_cpuid");
        +	&xor	("edx","edx");
        +	&pushf	();
        +	&pop	("eax");
        +	&mov	("ecx","eax");
        +	&xor	("eax",1<<21);
        +	&push	("eax");
        +	&popf	();
        +	&pushf	();
        +	&pop	("eax");
        +	&xor	("ecx","eax");
        +	&xor	("eax","eax");
        +	&bt	("ecx",21);
        +	&jnc	(&label("nocpuid"));
        +	&cpuid	();
        +	&mov	("edi","eax");		# max value for standard query level
        +
        +	&xor	("eax","eax");
        +	&cmp	("ebx",0x756e6547);	# "Genu"
        +	&setne	(&LB("eax"));
        +	&mov	("ebp","eax");
        +	&cmp	("edx",0x49656e69);	# "ineI"
        +	&setne	(&LB("eax"));
        +	&or	("ebp","eax");
        +	&cmp	("ecx",0x6c65746e);	# "ntel"
        +	&setne	(&LB("eax"));
        +	&or	("ebp","eax");		# 0 indicates Intel CPU
        +	&jz	(&label("intel"));
        +
        +	&cmp	("ebx",0x68747541);	# "Auth"
        +	&setne	(&LB("eax"));
        +	&mov	("esi","eax");
        +	&cmp	("edx",0x69746E65);	# "enti"
        +	&setne	(&LB("eax"));
        +	&or	("esi","eax");
        +	&cmp	("ecx",0x444D4163);	# "cAMD"
        +	&setne	(&LB("eax"));
        +	&or	("esi","eax");		# 0 indicates AMD CPU
        +	&jnz	(&label("intel"));
        +
        +	# AMD specific
        +	&mov	("eax",0x80000000);
        +	&cpuid	();
        +	&cmp	("eax",0x80000001);
        +	&jb	(&label("intel"));
        +	&mov	("esi","eax");
        +	&mov	("eax",0x80000001);
        +	&cpuid	();
        +	&or	("ebp","ecx");
        +	&and	("ebp",1<<11|1);	# isolate XOP bit
        +	&cmp	("esi",0x80000008);
        +	&jb	(&label("intel"));
        +
        +	&mov	("eax",0x80000008);
        +	&cpuid	();
        +	&movz	("esi",&LB("ecx"));	# number of cores - 1
        +	&inc	("esi");		# number of cores
        +
        +	&mov	("eax",1);
        +	&cpuid	();
        +	&bt	("edx",28);
        +	&jnc	(&label("generic"));
        +	&shr	("ebx",16);
        +	&and	("ebx",0xff);
        +	&cmp	("ebx","esi");
        +	&ja	(&label("generic"));
        +	&and	("edx",0xefffffff);	# clear hyper-threading bit
        +	&jmp	(&label("generic"));
        +	
        +&set_label("intel");
        +	&cmp	("edi",4);
        +	&mov	("edi",-1);
        +	&jb	(&label("nocacheinfo"));
        +
        +	&mov	("eax",4);
        +	&mov	("ecx",0);		# query L1D
        +	&cpuid	();
        +	&mov	("edi","eax");
        +	&shr	("edi",14);
        +	&and	("edi",0xfff);		# number of cores -1 per L1D
        +
        +&set_label("nocacheinfo");
        +	&mov	("eax",1);
        +	&cpuid	();
        +	&and	("edx",0xbfefffff);	# force reserved bits #20, #30 to 0
        +	&cmp	("ebp",0);
        +	&jne	(&label("notintel"));
        +	&or	("edx",1<<30);		# set reserved bit#30 on Intel CPUs
        +	&and	(&HB("eax"),15);	# familiy ID
        +	&cmp	(&HB("eax"),15);	# P4?
        +	&jne	(&label("notintel"));
        +	&or	("edx",1<<20);		# set reserved bit#20 to engage RC4_CHAR
        +&set_label("notintel");
        +	&bt	("edx",28);		# test hyper-threading bit
        +	&jnc	(&label("generic"));
        +	&and	("edx",0xefffffff);
        +	&cmp	("edi",0);
        +	&je	(&label("generic"));
        +
        +	&or	("edx",0x10000000);
        +	&shr	("ebx",16);
        +	&cmp	(&LB("ebx"),1);
        +	&ja	(&label("generic"));
        +	&and	("edx",0xefffffff);	# clear hyper-threading bit if not
        +
        +&set_label("generic");
        +	&and	("ebp",1<<11);		# isolate AMD XOP flag
        +	&and	("ecx",0xfffff7ff);	# force 11th bit to 0
        +	&mov	("esi","edx");
        +	&or	("ebp","ecx");		# merge AMD XOP flag
        +
        +	&bt	("ecx",27);		# check OSXSAVE bit
        +	&jnc	(&label("clear_avx"));
        +	&xor	("ecx","ecx");
        +	&data_byte(0x0f,0x01,0xd0);	# xgetbv
        +	&and	("eax",6);
        +	&cmp	("eax",6);
        +	&je	(&label("done"));
        +	&cmp	("eax",2);
        +	&je	(&label("clear_avx"));
        +&set_label("clear_xmm");
        +	&and	("ebp",0xfdfffffd);	# clear AESNI and PCLMULQDQ bits
        +	&and	("esi",0xfeffffff);	# clear FXSR
        +&set_label("clear_avx");
        +	&and	("ebp",0xefffe7ff);	# clear AVX, FMA and AMD XOP bits
        +&set_label("done");
        +	&mov	("eax","esi");
        +	&mov	("edx","ebp");
        +&set_label("nocpuid");
        +&function_end("OPENSSL_ia32_cpuid");
        +
        +&external_label("OPENSSL_ia32cap_P");
        +
        +&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
        +	&xor	("eax","eax");
        +	&xor	("edx","edx");
        +	&picmeup("ecx","OPENSSL_ia32cap_P");
        +	&bt	(&DWP(0,"ecx"),4);
        +	&jnc	(&label("notsc"));
        +	&rdtsc	();
        +&set_label("notsc");
        +	&ret	();
        +&function_end_B("OPENSSL_rdtsc");
        +
        +# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
        +# but it's safe to call it on any [supported] 32-bit platform...
        +# Just check for [non-]zero return value...
        +&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
        +	&picmeup("ecx","OPENSSL_ia32cap_P");
        +	&bt	(&DWP(0,"ecx"),4);
        +	&jnc	(&label("nohalt"));	# no TSC
        +
        +	&data_word(0x9058900e);		# push %cs; pop %eax
        +	&and	("eax",3);
        +	&jnz	(&label("nohalt"));	# not enough privileges
        +
        +	&pushf	();
        +	&pop	("eax");
        +	&bt	("eax",9);
        +	&jnc	(&label("nohalt"));	# interrupts are disabled
        +
        +	&rdtsc	();
        +	&push	("edx");
        +	&push	("eax");
        +	&halt	();
        +	&rdtsc	();
        +
        +	&sub	("eax",&DWP(0,"esp"));
        +	&sbb	("edx",&DWP(4,"esp"));
        +	&add	("esp",8);
        +	&ret	();
        +
        +&set_label("nohalt");
        +	&xor	("eax","eax");
        +	&xor	("edx","edx");
        +	&ret	();
        +&function_end_B("OPENSSL_instrument_halt");
        +
        +# Essentially there is only one use for this function. Under DJGPP:
        +#
        +#	#include <go32.h>
        +#	...
        +#	i=OPENSSL_far_spin(_dos_ds,0x46c);
        +#	...
        +# to obtain the number of spins till closest timer interrupt.
        +
        +&function_begin_B("OPENSSL_far_spin");
        +	&pushf	();
        +	&pop	("eax")
        +	&bt	("eax",9);
        +	&jnc	(&label("nospin"));	# interrupts are disabled
        +
        +	&mov	("eax",&DWP(4,"esp"));
        +	&mov	("ecx",&DWP(8,"esp"));
        +	&data_word (0x90d88e1e);	# push %ds, mov %eax,%ds
        +	&xor	("eax","eax");
        +	&mov	("edx",&DWP(0,"ecx"));
        +	&jmp	(&label("spin"));
        +
        +	&align	(16);
        +&set_label("spin");
        +	&inc	("eax");
        +	&cmp	("edx",&DWP(0,"ecx"));
        +	&je	(&label("spin"));
        +
        +	&data_word (0x1f909090);	# pop	%ds
        +	&ret	();
        +
        +&set_label("nospin");
        +	&xor	("eax","eax");
        +	&xor	("edx","edx");
        +	&ret	();
        +&function_end_B("OPENSSL_far_spin");
        +
        +&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
        +	&xor	("eax","eax");
        +	&xor	("edx","edx");
        +	&picmeup("ecx","OPENSSL_ia32cap_P");
        +	&mov	("ecx",&DWP(0,"ecx"));
        +	&bt	(&DWP(0,"ecx"),1);
        +	&jnc	(&label("no_x87"));
        +	if ($sse2) {
        +		&and	("ecx",1<<26|1<<24);	# check SSE2 and FXSR bits
        +		&cmp	("ecx",1<<26|1<<24);
        +		&jne	(&label("no_sse2"));
        +		&pxor	("xmm0","xmm0");
        +		&pxor	("xmm1","xmm1");
        +		&pxor	("xmm2","xmm2");
        +		&pxor	("xmm3","xmm3");
        +		&pxor	("xmm4","xmm4");
        +		&pxor	("xmm5","xmm5");
        +		&pxor	("xmm6","xmm6");
        +		&pxor	("xmm7","xmm7");
        +	&set_label("no_sse2");
        +	}
        +	# just a bunch of fldz to zap the fp/mm bank followed by finit...
        +	&data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b);
        +&set_label("no_x87");
        +	&lea	("eax",&DWP(4,"esp"));
        +	&ret	();
        +&function_end_B("OPENSSL_wipe_cpu");
        +
        +&function_begin_B("OPENSSL_atomic_add");
        +	&mov	("edx",&DWP(4,"esp"));	# fetch the pointer, 1st arg
        +	&mov	("ecx",&DWP(8,"esp"));	# fetch the increment, 2nd arg
        +	&push	("ebx");
        +	&nop	();
        +	&mov	("eax",&DWP(0,"edx"));
        +&set_label("spin");
        +	&lea	("ebx",&DWP(0,"eax","ecx"));
        +	&nop	();
        +	&data_word(0x1ab10ff0);	# lock;	cmpxchg	%ebx,(%edx)	# %eax is envolved and is always reloaded
        +	&jne	(&label("spin"));
        +	&mov	("eax","ebx");	# OpenSSL expects the new value
        +	&pop	("ebx");
        +	&ret	();
        +&function_end_B("OPENSSL_atomic_add");
        +
        +# This function can become handy under Win32 in situations when
        +# we don't know which calling convention, __stdcall or __cdecl(*),
        +# indirect callee is using. In C it can be deployed as
        +#
        +#ifdef OPENSSL_CPUID_OBJ
        +#	type OPENSSL_indirect_call(void *f,...);
        +#	...
        +#	OPENSSL_indirect_call(func,[up to $max arguments]);
        +#endif
        +#
        +# (*)	it's designed to work even for __fastcall if number of
        +#	arguments is 1 or 2!
        +&function_begin_B("OPENSSL_indirect_call");
        +	{
        +	my ($max,$i)=(7,);	# $max has to be chosen as 4*n-1
        +				# in order to preserve eventual
        +				# stack alignment
        +	&push	("ebp");
        +	&mov	("ebp","esp");
        +	&sub	("esp",$max*4);
        +	&mov	("ecx",&DWP(12,"ebp"));
        +	&mov	(&DWP(0,"esp"),"ecx");
        +	&mov	("edx",&DWP(16,"ebp"));
        +	&mov	(&DWP(4,"esp"),"edx");
        +	for($i=2;$i<$max;$i++)
        +		{
        +		# Some copies will be redundant/bogus...
        +		&mov	("eax",&DWP(12+$i*4,"ebp"));
        +		&mov	(&DWP(0+$i*4,"esp"),"eax");
        +		}
        +	&call_ptr	(&DWP(8,"ebp"));# make the call...
        +	&mov	("esp","ebp");	# ... and just restore the stack pointer
        +				# without paying attention to what we called,
        +				# (__cdecl *func) or (__stdcall *one).
        +	&pop	("ebp");
        +	&ret	();
        +	}
        +&function_end_B("OPENSSL_indirect_call");
        +
        +&function_begin_B("OPENSSL_cleanse");
        +	&mov	("edx",&wparam(0));
        +	&mov	("ecx",&wparam(1));
        +	&xor	("eax","eax");
        +	&cmp	("ecx",7);
        +	&jae	(&label("lot"));
        +	&cmp	("ecx",0);
        +	&je	(&label("ret"));
        +&set_label("little");
        +	&mov	(&BP(0,"edx"),"al");
        +	&sub	("ecx",1);
        +	&lea	("edx",&DWP(1,"edx"));
        +	&jnz	(&label("little"));
        +&set_label("ret");
        +	&ret	();
        +
        +&set_label("lot",16);
        +	&test	("edx",3);
        +	&jz	(&label("aligned"));
        +	&mov	(&BP(0,"edx"),"al");
        +	&lea	("ecx",&DWP(-1,"ecx"));
        +	&lea	("edx",&DWP(1,"edx"));
        +	&jmp	(&label("lot"));
        +&set_label("aligned");
        +	&mov	(&DWP(0,"edx"),"eax");
        +	&lea	("ecx",&DWP(-4,"ecx"));
        +	&test	("ecx",-4);
        +	&lea	("edx",&DWP(4,"edx"));
        +	&jnz	(&label("aligned"));
        +	&cmp	("ecx",0);
        +	&jne	(&label("little"));
        +	&ret	();
        +&function_end_B("OPENSSL_cleanse");
        +
        +&function_begin_B("OPENSSL_ia32_rdrand");
        +	&mov	("ecx",8);
        +&set_label("loop");
        +	&rdrand	("eax");
        +	&jc	(&label("break"));
        +	&loop	(&label("loop"));
        +&set_label("break");
        +	&cmp	("eax",0);
        +	&cmove	("eax","ecx");
        +	&ret	();
        +&function_end_B("OPENSSL_ia32_rdrand");
        +
        +&initseg("OPENSSL_cpuid_setup");
        +
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/demos/README b/vendor/openssl/openssl/demos/README
        new file mode 100644
        index 000000000..d2155ef97
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/README
        @@ -0,0 +1,9 @@
        +NOTE: Don't expect any of these programs to work with current
        +OpenSSL releases, or even with later SSLeay releases.
        +
        +Original README:
        +=============================================================================
        +
        +Some demo programs sent to me by various people
        +
        +eric
        diff --git a/vendor/openssl/openssl/demos/asn1/README.ASN1 b/vendor/openssl/openssl/demos/asn1/README.ASN1
        new file mode 100644
        index 000000000..ac497be18
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/asn1/README.ASN1
        @@ -0,0 +1,7 @@
        +This is a demo of the new ASN1 code. Its an OCSP ASN1 module. Doesn't
        +do much yet other than demonstrate what the new ASN1 modules might look
        +like.
        +
        +It wont even compile yet: the new code isn't in place.
        +
        +
        diff --git a/vendor/openssl/openssl/demos/asn1/ocsp.c b/vendor/openssl/openssl/demos/asn1/ocsp.c
        new file mode 100644
        index 000000000..e89f1f72a
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/asn1/ocsp.c
        @@ -0,0 +1,366 @@
        +/* ocsp.c */
        +/* Written by Dr Stephen N Henson (steve@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 <openssl/asn1.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509v3.h>
        +
        +
        +
        +
        +/* Example of new ASN1 code, OCSP request
        +
        +	OCSPRequest     ::=     SEQUENCE {
        +	    tbsRequest                  TBSRequest,
        +	    optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
        +
        +	TBSRequest      ::=     SEQUENCE {
        +	    version             [0] EXPLICIT Version DEFAULT v1,
        +	    requestorName       [1] EXPLICIT GeneralName OPTIONAL,
        +	    requestList             SEQUENCE OF Request,
        +	    requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
        +
        +	Signature       ::=     SEQUENCE {
        +	    signatureAlgorithm   AlgorithmIdentifier,
        +	    signature            BIT STRING,
        +	    certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
        +
        +	Version  ::=  INTEGER  {  v1(0) }
        +
        +	Request ::=     SEQUENCE {
        +	    reqCert                    CertID,
        +	    singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
        +
        +	CertID ::= SEQUENCE {
        +	    hashAlgorithm            AlgorithmIdentifier,
        +	    issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
        +	    issuerKeyHash      OCTET STRING, -- Hash of Issuers public key
        +	    serialNumber       CertificateSerialNumber }
        +
        +	OCSPResponse ::= SEQUENCE {
        +	   responseStatus         OCSPResponseStatus,
        +	   responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
        +
        +	OCSPResponseStatus ::= ENUMERATED {
        +	    successful            (0),      --Response has valid confirmations
        +	    malformedRequest      (1),      --Illegal confirmation request
        +	    internalError         (2),      --Internal error in issuer
        +	    tryLater              (3),      --Try again later
        +					    --(4) is not used
        +	    sigRequired           (5),      --Must sign the request
        +	    unauthorized          (6)       --Request unauthorized
        +	}
        +
        +	ResponseBytes ::=       SEQUENCE {
        +	    responseType   OBJECT IDENTIFIER,
        +	    response       OCTET STRING }
        +
        +	BasicOCSPResponse       ::= SEQUENCE {
        +	   tbsResponseData      ResponseData,
        +	   signatureAlgorithm   AlgorithmIdentifier,
        +	   signature            BIT STRING,
        +	   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
        +
        +	ResponseData ::= SEQUENCE {
        +	   version              [0] EXPLICIT Version DEFAULT v1,
        +	   responderID              ResponderID,
        +	   producedAt               GeneralizedTime,
        +	   responses                SEQUENCE OF SingleResponse,
        +	   responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
        +
        +	ResponderID ::= CHOICE {
        +	   byName   [1] Name,    --EXPLICIT
        +	   byKey    [2] KeyHash }
        +
        +	KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
        +				 --(excluding the tag and length fields)
        +
        +	SingleResponse ::= SEQUENCE {
        +	   certID                       CertID,
        +	   certStatus                   CertStatus,
        +	   thisUpdate                   GeneralizedTime,
        +	   nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
        +	   singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
        +
        +	CertStatus ::= CHOICE {
        +	    good                [0]     IMPLICIT NULL,
        +	    revoked             [1]     IMPLICIT RevokedInfo,
        +	    unknown             [2]     IMPLICIT UnknownInfo }
        +
        +	RevokedInfo ::= SEQUENCE {
        +	    revocationTime              GeneralizedTime,
        +	    revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
        +
        +	UnknownInfo ::= NULL -- this can be replaced with an enumeration
        +
        +	ArchiveCutoff ::= GeneralizedTime
        +
        +	AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER
        +
        +	ServiceLocator ::= SEQUENCE {
        +	    issuer    Name,
        +	    locator   AuthorityInfoAccessSyntax }
        +
        +	-- Object Identifiers
        +
        +	id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
        +	id-pkix-ocsp                 OBJECT IDENTIFIER ::= { id-ad-ocsp }
        +	id-pkix-ocsp-basic           OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
        +	id-pkix-ocsp-nonce           OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 }
        +	id-pkix-ocsp-crl             OBJECT IDENTIFIER ::= { id-pkix-ocsp 3 }
        +	id-pkix-ocsp-response        OBJECT IDENTIFIER ::= { id-pkix-ocsp 4 }
        +	id-pkix-ocsp-nocheck         OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
        +	id-pkix-ocsp-archive-cutoff  OBJECT IDENTIFIER ::= { id-pkix-ocsp 6 }
        +	id-pkix-ocsp-service-locator OBJECT IDENTIFIER ::= { id-pkix-ocsp 7 }
        +
        +*/
        +
        +/* Request Structures */
        +
        +DECLARE_STACK_OF(Request)
        +
        +typedef struct {
        +	ASN1_INTEGER *version;
        +	GENERAL_NAME *requestorName;
        +	STACK_OF(Request) *requestList;
        +	STACK_OF(X509_EXTENSION) *requestExtensions;
        +} TBSRequest;
        +
        +typedef struct {
        +	X509_ALGOR *signatureAlgorithm;
        +	ASN1_BIT_STRING *signature;
        +	STACK_OF(X509) *certs;
        +} Signature;
        +
        +typedef struct {
        +	TBSRequest *tbsRequest;
        +	Signature *optionalSignature;
        +} OCSPRequest;
        +
        +typedef struct {
        +	X509_ALGOR *hashAlgorithm;
        +	ASN1_OCTET_STRING *issuerNameHash;
        +	ASN1_OCTET_STRING *issuerKeyHash;
        +	ASN1_INTEGER *certificateSerialNumber;
        +} CertID;
        +
        +typedef struct {
        +	CertID *reqCert;
        +	STACK_OF(X509_EXTENSION) *singleRequestExtensions;
        +} Request;
        +
        +/* Response structures */
        +
        +typedef struct {
        +	ASN1_OBJECT *responseType;
        +	ASN1_OCTET_STRING *response;
        +} ResponseBytes;
        +
        +typedef struct {
        +	ASN1_ENUMERATED *responseStatus;
        +	ResponseBytes *responseBytes;
        +} OCSPResponse;
        +
        +typedef struct {
        +	int type;
        +	union {
        +	   X509_NAME *byName;
        +	   ASN1_OCTET_STRING *byKey;
        +	}d;
        +} ResponderID;
        +
        +typedef struct {
        +	   ASN1_INTEGER *version;
        +	   ResponderID *responderID;
        +	   ASN1_GENERALIZEDTIME *producedAt;
        +	   STACK_OF(SingleResponse) *responses;
        +	   STACK_OF(X509_EXTENSION) *responseExtensions;
        +} ResponseData;
        +
        +typedef struct {
        +	   ResponseData *tbsResponseData;
        +	   X509_ALGOR *signatureAlgorithm;
        +	   ASN1_BIT_STRING *signature;
        +	   STACK_OF(X509) *certs;
        +} BasicOCSPResponse;
        +
        +typedef struct {
        +	ASN1_GENERALIZEDTIME *revocationTime;
        +	ASN1_ENUMERATED * revocationReason;
        +} RevokedInfo;
        +
        +typedef struct {
        +	int type;
        +	union {
        +	    ASN1_NULL *good;
        +	    RevokedInfo *revoked;
        +	    ASN1_NULL *unknown;
        +	} d;
        +} CertStatus;
        +
        +typedef struct {
        +	   CertID *certID;
        +	   CertStatus *certStatus;
        +	   ASN1_GENERALIZEDTIME *thisUpdate;
        +	   ASN1_GENERALIZEDTIME *nextUpdate;
        +	   STACK_OF(X509_EXTENSION) *singleExtensions;
        +} SingleResponse;
        +
        +
        +typedef struct {
        +    X509_NAME *issuer;
        +    STACK_OF(ACCESS_DESCRIPTION) *locator;
        +} ServiceLocator;
        +
        +
        +/* Now the ASN1 templates */
        +
        +IMPLEMENT_COMPAT_ASN1(X509);
        +IMPLEMENT_COMPAT_ASN1(X509_ALGOR);
        +//IMPLEMENT_COMPAT_ASN1(X509_EXTENSION);
        +IMPLEMENT_COMPAT_ASN1(GENERAL_NAME);
        +IMPLEMENT_COMPAT_ASN1(X509_NAME);
        +
        +ASN1_SEQUENCE(X509_EXTENSION) = {
        +	ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
        +	ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
        +	ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(X509_EXTENSION);
        +	
        +
        +ASN1_SEQUENCE(Signature) = {
        +	ASN1_SIMPLE(Signature, signatureAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(Signature, signature, ASN1_BIT_STRING),
        +	ASN1_SEQUENCE_OF(Signature, certs, X509)
        +} ASN1_SEQUENCE_END(Signature);
        +
        +ASN1_SEQUENCE(CertID) = {
        +	ASN1_SIMPLE(CertID, hashAlgorithm, X509_ALGOR),
        +	ASN1_SIMPLE(CertID, issuerNameHash, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(CertID, issuerKeyHash, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(CertID, certificateSerialNumber, ASN1_INTEGER)
        +} ASN1_SEQUENCE_END(CertID);
        +
        +ASN1_SEQUENCE(Request) = {
        +	ASN1_SIMPLE(Request, reqCert, CertID),
        +	ASN1_EXP_SEQUENCE_OF_OPT(Request, singleRequestExtensions, X509_EXTENSION, 0)
        +} ASN1_SEQUENCE_END(Request);
        +
        +ASN1_SEQUENCE(TBSRequest) = {
        +	ASN1_EXP_OPT(TBSRequest, version, ASN1_INTEGER, 0),
        +	ASN1_EXP_OPT(TBSRequest, requestorName, GENERAL_NAME, 1),
        +	ASN1_SEQUENCE_OF(TBSRequest, requestList, Request),
        +	ASN1_EXP_SEQUENCE_OF_OPT(TBSRequest, requestExtensions, X509_EXTENSION, 2)
        +} ASN1_SEQUENCE_END(TBSRequest);
        +
        +ASN1_SEQUENCE(OCSPRequest) = {
        +	ASN1_SIMPLE(OCSPRequest, tbsRequest, TBSRequest),
        +	ASN1_EXP_OPT(OCSPRequest, optionalSignature, Signature, 0)
        +} ASN1_SEQUENCE_END(OCSPRequest);
        +
        +
        +/* Response templates */
        +
        +ASN1_SEQUENCE(ResponseBytes) = {
        +	    ASN1_SIMPLE(ResponseBytes, responseType, ASN1_OBJECT),
        +	    ASN1_SIMPLE(ResponseBytes, response, ASN1_OCTET_STRING)
        +} ASN1_SEQUENCE_END(ResponseBytes);
        +
        +ASN1_SEQUENCE(OCSPResponse) = {
        +	ASN1_SIMPLE(OCSPResponse, responseStatus, ASN1_ENUMERATED),
        +	ASN1_EXP_OPT(OCSPResponse, responseBytes, ResponseBytes, 0)
        +} ASN1_SEQUENCE_END(OCSPResponse);
        +
        +ASN1_CHOICE(ResponderID) = {
        +	   ASN1_EXP(ResponderID, d.byName, X509_NAME, 1),
        +	   ASN1_IMP(ResponderID, d.byKey, ASN1_OCTET_STRING, 2)
        +} ASN1_CHOICE_END(ResponderID);
        +
        +ASN1_SEQUENCE(RevokedInfo) = {
        +	ASN1_SIMPLE(RevokedInfo, revocationTime, ASN1_GENERALIZEDTIME),
        +  	ASN1_EXP_OPT(RevokedInfo, revocationReason, ASN1_ENUMERATED, 0)
        +} ASN1_SEQUENCE_END(RevokedInfo);
        +
        +ASN1_CHOICE(CertStatus) = {
        +	ASN1_IMP(CertStatus, d.good, ASN1_NULL, 0),
        +	ASN1_IMP(CertStatus, d.revoked, RevokedInfo, 1),
        +	ASN1_IMP(CertStatus, d.unknown, ASN1_NULL, 2)
        +} ASN1_CHOICE_END(CertStatus);
        +
        +ASN1_SEQUENCE(SingleResponse) = {
        +	   ASN1_SIMPLE(SingleResponse, certID, CertID),
        +	   ASN1_SIMPLE(SingleResponse, certStatus, CertStatus),
        +	   ASN1_SIMPLE(SingleResponse, thisUpdate, ASN1_GENERALIZEDTIME),
        +	   ASN1_EXP_OPT(SingleResponse, nextUpdate, ASN1_GENERALIZEDTIME, 0),
        +	   ASN1_EXP_SEQUENCE_OF_OPT(SingleResponse, singleExtensions, X509_EXTENSION, 1)
        +} ASN1_SEQUENCE_END(SingleResponse);
        +
        +ASN1_SEQUENCE(ResponseData) = {
        +	   ASN1_EXP_OPT(ResponseData, version, ASN1_INTEGER, 0),
        +	   ASN1_SIMPLE(ResponseData, responderID, ResponderID),
        +	   ASN1_SIMPLE(ResponseData, producedAt, ASN1_GENERALIZEDTIME),
        +	   ASN1_SEQUENCE_OF(ResponseData, responses, SingleResponse),
        +	   ASN1_EXP_SEQUENCE_OF_OPT(ResponseData, responseExtensions, X509_EXTENSION, 1)
        +} ASN1_SEQUENCE_END(ResponseData);
        +
        +ASN1_SEQUENCE(BasicOCSPResponse) = {
        +	   ASN1_SIMPLE(BasicOCSPResponse, tbsResponseData, ResponseData),
        +	   ASN1_SIMPLE(BasicOCSPResponse, signatureAlgorithm, X509_ALGOR),
        +	   ASN1_SIMPLE(BasicOCSPResponse, signature, ASN1_BIT_STRING),
        +	   ASN1_EXP_SEQUENCE_OF_OPT(BasicOCSPResponse, certs, X509, 0)
        +} ASN1_SEQUENCE_END(BasicOCSPResponse);
        +
        diff --git a/vendor/openssl/openssl/demos/b64.c b/vendor/openssl/openssl/demos/b64.c
        new file mode 100644
        index 000000000..efdd44457
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/b64.c
        @@ -0,0 +1,268 @@
        +/* demos/b64.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include "../apps/apps.h"
        +#include <openssl/buffer.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +#undef SIZE
        +#undef BSIZE
        +#undef PROG
        +
        +#define SIZE	(512)
        +#define BSIZE	(8*1024)
        +#define	PROG	enc_main
        +
        +int main(argc,argv)
        +int argc;
        +char **argv;
        +	{
        +	char *strbuf=NULL;
        +	unsigned char *buff=NULL,*bufsize=NULL;
        +	int bsize=BSIZE,verbose=0;
        +	int ret=1,inl;
        +	char *str=NULL;
        +	char *hkey=NULL,*hiv=NULL;
        +	int enc=1,printkey=0,i,base64=0;
        +	int debug=0;
        +	EVP_CIPHER *cipher=NULL,*c;
        +	char *inf=NULL,*outf=NULL;
        +	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
        +#define PROG_NAME_SIZE  39
        +
        +
        +	apps_startup();
        +
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
        +
        +	base64=1;
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if	(strcmp(*argv,"-e") == 0)
        +			enc=1;
        +		if (strcmp(*argv,"-in") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			inf= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			outf= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-d") == 0)
        +			enc=0;
        +		else if	(strcmp(*argv,"-v") == 0)
        +			verbose=1;
        +		else if	(strcmp(*argv,"-debug") == 0)
        +			debug=1;
        +		else if (strcmp(*argv,"-bufsize") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			bufsize=(unsigned char *)*(++argv);
        +			}
        +		else
        +			{
        +			BIO_printf(bio_err,"unknown option '%s'\n",*argv);
        +bad:
        +			BIO_printf(bio_err,"options are\n");
        +			BIO_printf(bio_err,"%-14s input file\n","-in <file>");
        +			BIO_printf(bio_err,"%-14s output file\n","-out <file>");
        +			BIO_printf(bio_err,"%-14s encode\n","-e");
        +			BIO_printf(bio_err,"%-14s decode\n","-d");
        +			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
        +
        +			goto end;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +	if (bufsize != NULL)
        +		{
        +		int i;
        +		unsigned long n;
        +
        +		for (n=0; *bufsize; bufsize++)
        +			{
        +			i= *bufsize;
        +			if ((i <= '9') && (i >= '0'))
        +				n=n*10+i-'0';
        +			else if (i == 'k')
        +				{
        +				n*=1024;
        +				bufsize++;
        +				break;
        +				}
        +			}
        +		if (*bufsize != '\0')
        +			{
        +			BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
        +			goto end;
        +			}
        +
        +		/* It must be large enough for a base64 encoded line */
        +		if (n < 80) n=80;
        +
        +		bsize=(int)n;
        +		if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
        +		}
        +
        +	strbuf=OPENSSL_malloc(SIZE);
        +	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
        +	if ((buff == NULL) || (strbuf == NULL))
        +		{
        +		BIO_printf(bio_err,"OPENSSL_malloc failure\n");
        +		goto end;
        +		}
        +
        +	in=BIO_new(BIO_s_file());
        +	out=BIO_new(BIO_s_file());
        +	if ((in == NULL) || (out == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +	if (debug)
        +		{
        +		BIO_set_callback(in,BIO_debug_callback);
        +		BIO_set_callback(out,BIO_debug_callback);
        +		BIO_set_callback_arg(in,bio_err);
        +		BIO_set_callback_arg(out,bio_err);
        +		}
        +
        +	if (inf == NULL)
        +		BIO_set_fp(in,stdin,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_read_filename(in,inf) <= 0)
        +			{
        +			perror(inf);
        +			goto end;
        +			}
        +		}
        +
        +	if (outf == NULL)
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +	else
        +		{
        +		if (BIO_write_filename(out,outf) <= 0)
        +			{
        +			perror(outf);
        +			goto end;
        +			}
        +		}
        +
        +	rbio=in;
        +	wbio=out;
        +
        +	if (base64)
        +		{
        +		if ((b64=BIO_new(BIO_f_base64())) == NULL)
        +			goto end;
        +		if (debug)
        +			{
        +			BIO_set_callback(b64,BIO_debug_callback);
        +			BIO_set_callback_arg(b64,bio_err);
        +			}
        +		if (enc)
        +			wbio=BIO_push(b64,wbio);
        +		else
        +			rbio=BIO_push(b64,rbio);
        +		}
        +
        +	for (;;)
        +		{
        +		inl=BIO_read(rbio,(char *)buff,bsize);
        +		if (inl <= 0) break;
        +		if (BIO_write(wbio,(char *)buff,inl) != inl)
        +			{
        +			BIO_printf(bio_err,"error writing output file\n");
        +			goto end;
        +			}
        +		}
        +	BIO_flush(wbio);
        +
        +	ret=0;
        +	if (verbose)
        +		{
        +		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in));
        +		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
        +		}
        +end:
        +	if (strbuf != NULL) OPENSSL_free(strbuf);
        +	if (buff != NULL) OPENSSL_free(buff);
        +	if (in != NULL) BIO_free(in);
        +	if (out != NULL) BIO_free(out);
        +	if (benc != NULL) BIO_free(benc);
        +	if (b64 != NULL) BIO_free(b64);
        +	EXIT(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/demos/b64.pl b/vendor/openssl/openssl/demos/b64.pl
        new file mode 100644
        index 000000000..8aa5fb464
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/b64.pl
        @@ -0,0 +1,20 @@
        +#!/usr/local/bin/perl
        +
        +#
        +# Make PEM encoded data have lines of 64 bytes of data
        +#
        +
        +while (<>)
        +	{
        +	if (/^-----BEGIN/ .. /^-----END/)
        +		{
        +		if (/^-----BEGIN/) { $first=$_; next; }
        +		if (/^-----END/) { $last=$_; next; }
        +		$out.=$_;
        +		}
        +	}
        +$out =~ s/\s//g;
        +$out =~ s/(.{64})/$1\n/g;
        +print "$first$out\n$last\n";
        +
        +
        diff --git a/vendor/openssl/openssl/demos/bio/Makefile b/vendor/openssl/openssl/demos/bio/Makefile
        new file mode 100644
        index 000000000..435154053
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/bio/Makefile
        @@ -0,0 +1,16 @@
        +CC=cc
        +CFLAGS= -g -I../../include
        +LIBS= -L../.. ../../libssl.a ../../libcrypto.a
        +EXAMPLES=saccept sconnect
        +
        +all: $(EXAMPLES) 
        +
        +saccept: saccept.o
        +	$(CC) -o saccept saccept.o $(LIBS)
        +
        +sconnect: sconnect.o
        +	$(CC) -o sconnect sconnect.o $(LIBS)
        +
        +clean:	
        +	rm -f $(EXAMPLES) *.o
        +
        diff --git a/vendor/openssl/openssl/demos/bio/README b/vendor/openssl/openssl/demos/bio/README
        new file mode 100644
        index 000000000..0b24e5b80
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/bio/README
        @@ -0,0 +1,3 @@
        +This directory contains some simple examples of the use of BIO's
        +to simplify socket programming.
        +
        diff --git a/vendor/openssl/openssl/demos/bio/saccept.c b/vendor/openssl/openssl/demos/bio/saccept.c
        new file mode 100644
        index 000000000..40cd4daad
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/bio/saccept.c
        @@ -0,0 +1,112 @@
        +/* NOCW */
        +/* demos/bio/saccept.c */
        +
        +/* A minimal program to server an SSL connection.
        + * It uses blocking.
        + * saccept host:port
        + * host is the interface IP to use.  If any interface, use *:port
        + * The default it *:4433
        + *
        + * cc -I../../include saccept.c -L../.. -lssl -lcrypto
        + */
        +
        +#include <stdio.h>
        +#include <signal.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +#define CERT_FILE	"server.pem"
        +
        +BIO *in=NULL;
        +
        +void close_up()
        +	{
        +	if (in != NULL)
        +		BIO_free(in);
        +	}
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	char *port=NULL;
        +	BIO *ssl_bio,*tmp;
        +	SSL_CTX *ctx;
        +	SSL *ssl;
        +	char buf[512];
        +	int ret=1,i;
        +
        +        if (argc <= 1)
        +		port="*:4433";
        +	else
        +		port=argv[1];
        +
        +	signal(SIGINT,close_up);
        +
        +	SSL_load_error_strings();
        +
        +#ifdef WATT32
        +	dbug_init();
        +	sock_init();
        +#endif
        +
        +	/* Add ciphers and message digests */
        +	OpenSSL_add_ssl_algorithms();
        +
        +	ctx=SSL_CTX_new(SSLv23_server_method());
        +	if (!SSL_CTX_use_certificate_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
        +		goto err;
        +	if (!SSL_CTX_use_PrivateKey_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
        +		goto err;
        +	if (!SSL_CTX_check_private_key(ctx))
        +		goto err;
        +
        +	/* Setup server side SSL bio */
        +	ssl=SSL_new(ctx);
        +	ssl_bio=BIO_new_ssl(ctx,0);
        +
        +	if ((in=BIO_new_accept(port)) == NULL) goto err;
        +
        +	/* This means that when a new connection is acceptede on 'in',
        +	 * The ssl_bio will be 'dupilcated' and have the new socket
        +	 * BIO push into it.  Basically it means the SSL BIO will be
        +	 * automatically setup */
        +	BIO_set_accept_bios(in,ssl_bio);
        +
        +again:
        +	/* The first call will setup the accept socket, and the second
        +	 * will get a socket.  In this loop, the first actual accept
        +	 * will occur in the BIO_read() function. */
        +
        +	if (BIO_do_accept(in) <= 0) goto err;
        +
        +	for (;;)
        +		{
        +		i=BIO_read(in,buf,512);
        +		if (i == 0)
        +			{
        +			/* If we have finished, remove the underlying
        +			 * BIO stack so the next time we call any function
        +			 * for this BIO, it will attempt to do an
        +			 * accept */
        +			printf("Done\n");
        +			tmp=BIO_pop(in);
        +			BIO_free_all(tmp);
        +			goto again;
        +			}
        +		if (i < 0) goto err;
        +		fwrite(buf,1,i,stdout);
        +		fflush(stdout);
        +		}
        +
        +	ret=0;
        +err:
        +	if (ret)
        +		{
        +		ERR_print_errors_fp(stderr);
        +		}
        +	if (in != NULL) BIO_free(in);
        +	exit(ret);
        +	return(!ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/demos/bio/sconnect.c b/vendor/openssl/openssl/demos/bio/sconnect.c
        new file mode 100644
        index 000000000..880344eb7
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/bio/sconnect.c
        @@ -0,0 +1,121 @@
        +/* NOCW */
        +/* demos/bio/sconnect.c */
        +
        +/* A minimal program to do SSL to a passed host and port.
        + * It is actually using non-blocking IO but in a very simple manner
        + * sconnect host:port - it does a 'GET / HTTP/1.0'
        + *
        + * cc -I../../include sconnect.c -L../.. -lssl -lcrypto
        + */
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <unistd.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +extern int errno;
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	char *host;
        +	BIO *out;
        +	char buf[1024*10],*p;
        +	SSL_CTX *ssl_ctx=NULL;
        +	SSL *ssl;
        +	BIO *ssl_bio;
        +	int i,len,off,ret=1;
        +
        +	if (argc <= 1)
        +		host="localhost:4433";
        +	else
        +		host=argv[1];
        +
        +#ifdef WATT32
        +	dbug_init();
        +	sock_init();
        +#endif
        +
        +	/* Lets get nice error messages */
        +	SSL_load_error_strings();
        +
        +	/* Setup all the global SSL stuff */
        +	OpenSSL_add_ssl_algorithms();
        +	ssl_ctx=SSL_CTX_new(SSLv23_client_method());
        +
        +	/* Lets make a SSL structure */
        +	ssl=SSL_new(ssl_ctx);
        +	SSL_set_connect_state(ssl);
        +
        +	/* Use it inside an SSL BIO */
        +	ssl_bio=BIO_new(BIO_f_ssl());
        +	BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
        +
        +	/* Lets use a connect BIO under the SSL BIO */
        +	out=BIO_new(BIO_s_connect());
        +	BIO_set_conn_hostname(out,host);
        +	BIO_set_nbio(out,1);
        +	out=BIO_push(ssl_bio,out);
        +
        +	p="GET / HTTP/1.0\r\n\r\n";
        +	len=strlen(p);
        +
        +	off=0;
        +	for (;;)
        +		{
        +		i=BIO_write(out,&(p[off]),len);
        +		if (i <= 0)
        +			{
        +			if (BIO_should_retry(out))
        +				{
        +				fprintf(stderr,"write DELAY\n");
        +				sleep(1);
        +				continue;
        +				}
        +			else
        +				{
        +				goto err;
        +				}
        +			}
        +		off+=i;
        +		len-=i;
        +		if (len <= 0) break;
        +		}
        +
        +	for (;;)
        +		{
        +		i=BIO_read(out,buf,sizeof(buf));
        +		if (i == 0) break;
        +		if (i < 0)
        +			{
        +			if (BIO_should_retry(out))
        +				{
        +				fprintf(stderr,"read DELAY\n");
        +				sleep(1);
        +				continue;
        +				}
        +			goto err;
        +			}
        +		fwrite(buf,1,i,stdout);
        +		}
        +
        +	ret=1;
        +
        +	if (0)
        +		{
        +err:
        +		if (ERR_peek_error() == 0) /* system call error */
        +			{
        +			fprintf(stderr,"errno=%d ",errno);
        +			perror("error");
        +			}
        +		else
        +			ERR_print_errors_fp(stderr);
        +		}
        +	BIO_free_all(out);
        +	if (ssl_ctx != NULL) SSL_CTX_free(ssl_ctx);
        +	exit(!ret);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/demos/bio/server.pem b/vendor/openssl/openssl/demos/bio/server.pem
        new file mode 100644
        index 000000000..5cf1387d6
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/bio/server.pem
        @@ -0,0 +1,30 @@
        +subject=/C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +issuer= /C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +-----BEGIN X509 CERTIFICATE-----
        +
        +MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
        +BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
        +MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
        +RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
        +BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
        +LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
        +/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
        +DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
        +IMs6ZOZB
        +-----END X509 CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +
        +MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
        +Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
        +hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
        +sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
        +tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
        +agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
        +g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
        +-----END RSA PRIVATE KEY-----
        +
        +-----BEGIN DH PARAMETERS-----
        +MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
        +a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
        +-----END DH PARAMETERS-----
        +
        diff --git a/vendor/openssl/openssl/demos/cms/cacert.pem b/vendor/openssl/openssl/demos/cms/cacert.pem
        new file mode 100644
        index 000000000..75cbb347a
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cacert.pem
        @@ -0,0 +1,18 @@
        +-----BEGIN CERTIFICATE-----
        +MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
        +BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
        +dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3
        +WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD
        +aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN
        +RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz
        +i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR
        +ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT
        +jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx
        +CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B
        +SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD
        +VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB
        +ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc
        +G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo
        +u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF
        +1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/demos/cms/cakey.pem b/vendor/openssl/openssl/demos/cms/cakey.pem
        new file mode 100644
        index 000000000..3b53c5e81
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cakey.pem
        @@ -0,0 +1,15 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd
        +c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3
        +dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB
        +AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5
        +HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs
        +tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS
        +rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18
        +9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u
        +jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is
        +uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU
        ++VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP
        +wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW
        +8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/cms/cms_comp.c b/vendor/openssl/openssl/demos/cms/cms_comp.c
        new file mode 100644
        index 000000000..b7943e813
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_comp.c
        @@ -0,0 +1,61 @@
        +/* Simple S/MIME compress example */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	/*
        +	 * On OpenSSL 0.9.9 only:
        +	 * for streaming set CMS_STREAM
        +	 */
        +	int flags = CMS_STREAM;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Open content being compressed */
        +
        +	in = BIO_new_file("comp.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* compress content */
        +	cms = CMS_compress(in, NID_zlib_compression, flags);
        +
        +	if (!cms)
        +		goto err;
        +
        +	out = BIO_new_file("smcomp.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Write out S/MIME message */
        +	if (!SMIME_write_CMS(out, cms, in, flags))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Compressing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_ddec.c b/vendor/openssl/openssl/demos/cms/cms_ddec.c
        new file mode 100644
        index 000000000..ba68cfdf7
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_ddec.c
        @@ -0,0 +1,89 @@
        +/* S/MIME detached data decrypt example: rarely done but
        + * should the need arise this is an example....
        + */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL, *dcont = NULL;
        +	X509 *rcert = NULL;
        +	EVP_PKEY *rkey = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in recipient certificate and private key */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!rcert || !rkey)
        +		goto err;
        +
        +	/* Open PEM file containing enveloped data */
        +
        +	in = BIO_new_file("smencr.pem", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Parse PEM content */
        +	cms = PEM_read_bio_CMS(in, NULL, 0, NULL);
        +
        +	if (!cms)
        +		goto err;
        +
        +	/* Open file containing detached content */
        +	dcont = BIO_new_file("smencr.out", "rb");
        +
        +	if (!in)
        +		goto err;
        +
        +	out = BIO_new_file("encrout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Decrypt S/MIME message */
        +	if (!CMS_decrypt(cms, rkey, rcert, dcont, out, 0))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Decrypting Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	if (rcert)
        +		X509_free(rcert);
        +	if (rkey)
        +		EVP_PKEY_free(rkey);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +	if (dcont)
        +		BIO_free(dcont);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_dec.c b/vendor/openssl/openssl/demos/cms/cms_dec.c
        new file mode 100644
        index 000000000..7ddf65326
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_dec.c
        @@ -0,0 +1,79 @@
        +/* Simple S/MIME decryption example */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *rcert = NULL;
        +	EVP_PKEY *rkey = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in recipient certificate and private key */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!rcert || !rkey)
        +		goto err;
        +
        +	/* Open S/MIME message to decrypt */
        +
        +	in = BIO_new_file("smencr.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Parse message */
        +	cms = SMIME_read_CMS(in, NULL);
        +
        +	if (!cms)
        +		goto err;
        +
        +	out = BIO_new_file("decout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Decrypt S/MIME message */
        +	if (!CMS_decrypt(cms, rkey, rcert, out, NULL, 0))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Decrypting Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	if (rcert)
        +		X509_free(rcert);
        +	if (rkey)
        +		EVP_PKEY_free(rkey);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_denc.c b/vendor/openssl/openssl/demos/cms/cms_denc.c
        new file mode 100644
        index 000000000..9265e47bf
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_denc.c
        @@ -0,0 +1,97 @@
        +/* S/MIME detached data encrypt example: rarely done but
        + * should the need arise this is an example....
        + */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL, *dout = NULL;
        +	X509 *rcert = NULL;
        +	STACK_OF(X509) *recips = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	int flags = CMS_STREAM|CMS_DETACHED;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in recipient certificate */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	if (!rcert)
        +		goto err;
        +
        +	/* Create recipient STACK and add recipient cert to it */
        +	recips = sk_X509_new_null();
        +
        +	if (!recips || !sk_X509_push(recips, rcert))
        +		goto err;
        +
        +	/* sk_X509_pop_free will free up recipient STACK and its contents
        +	 * so set rcert to NULL so it isn't freed up twice.
        +	 */
        +	rcert = NULL;
        +
        +	/* Open content being encrypted */
        +
        +	in = BIO_new_file("encr.txt", "r");
        +
        +	dout = BIO_new_file("smencr.out", "wb");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* encrypt content */
        +	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);
        +
        +	if (!cms)
        +		goto err;
        +
        +	out = BIO_new_file("smencr.pem", "w");
        +	if (!out)
        +		goto err;
        +
        +	if (!CMS_final(cms, in, dout, flags))
        +		goto err;
        +
        +	/* Write out CMS structure without content */
        +	if (!PEM_write_bio_CMS(out, cms))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Encrypting Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	if (rcert)
        +		X509_free(rcert);
        +	if (recips)
        +		sk_X509_pop_free(recips, X509_free);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (dout)
        +		BIO_free(dout);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_enc.c b/vendor/openssl/openssl/demos/cms/cms_enc.c
        new file mode 100644
        index 000000000..916b479d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_enc.c
        @@ -0,0 +1,92 @@
        +/* Simple S/MIME encrypt example */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *rcert = NULL;
        +	STACK_OF(X509) *recips = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	/*
        +	 * On OpenSSL 1.0.0 and later only:
        +	 * for streaming set CMS_STREAM
        +	 */
        +	int flags = CMS_STREAM;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in recipient certificate */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	if (!rcert)
        +		goto err;
        +
        +	/* Create recipient STACK and add recipient cert to it */
        +	recips = sk_X509_new_null();
        +
        +	if (!recips || !sk_X509_push(recips, rcert))
        +		goto err;
        +
        +	/* sk_X509_pop_free will free up recipient STACK and its contents
        +	 * so set rcert to NULL so it isn't freed up twice.
        +	 */
        +	rcert = NULL;
        +
        +	/* Open content being encrypted */
        +
        +	in = BIO_new_file("encr.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* encrypt content */
        +	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);
        +
        +	if (!cms)
        +		goto err;
        +
        +	out = BIO_new_file("smencr.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Write out S/MIME message */
        +	if (!SMIME_write_CMS(out, cms, in, flags))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Encrypting Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	if (rcert)
        +		X509_free(rcert);
        +	if (recips)
        +		sk_X509_pop_free(recips, X509_free);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_sign.c b/vendor/openssl/openssl/demos/cms/cms_sign.c
        new file mode 100644
        index 000000000..42f762034
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_sign.c
        @@ -0,0 +1,89 @@
        +/* Simple S/MIME signing example */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *scert = NULL;
        +	EVP_PKEY *skey = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	/* For simple S/MIME signing use CMS_DETACHED.
        +	 * On OpenSSL 0.9.9 only:
        +	 * for streaming detached set CMS_DETACHED|CMS_STREAM
        +	 * for streaming non-detached set CMS_STREAM
        +	 */
        +	int flags = CMS_DETACHED|CMS_STREAM;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in signer certificate and private key */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!scert || !skey)
        +		goto err;
        +
        +	/* Open content being signed */
        +
        +	in = BIO_new_file("sign.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Sign content */
        +	cms = CMS_sign(scert, skey, NULL, in, flags);
        +
        +	if (!cms)
        +		goto err;
        +
        +	out = BIO_new_file("smout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	if (!(flags & CMS_STREAM))
        +		BIO_reset(in);
        +
        +	/* Write out S/MIME message */
        +	if (!SMIME_write_CMS(out, cms, in, flags))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Signing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +	if (scert)
        +		X509_free(scert);
        +	if (skey)
        +		EVP_PKEY_free(skey);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_sign2.c b/vendor/openssl/openssl/demos/cms/cms_sign2.c
        new file mode 100644
        index 000000000..36adee730
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_sign2.c
        @@ -0,0 +1,103 @@
        +/* S/MIME signing example: 2 signers */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *scert = NULL, *scert2 = NULL;
        +	EVP_PKEY *skey = NULL, *skey2 = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	BIO_free(tbio);
        +
        +	tbio = BIO_new_file("signer2.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!scert2 || !skey2)
        +		goto err;
        +
        +	in = BIO_new_file("sign.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	cms = CMS_sign(NULL, NULL, NULL, in, CMS_STREAM|CMS_PARTIAL);
        +
        +	if (!cms)
        +		goto err;
        +
        +	/* Add each signer in turn */
        +
        +	if (!CMS_add1_signer(cms, scert, skey, NULL, 0))
        +		goto err;
        +
        +	if (!CMS_add1_signer(cms, scert2, skey2, NULL, 0))
        +		goto err;
        +
        +	out = BIO_new_file("smout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* NB: content included and finalized by SMIME_write_CMS */
        +
        +	if (!SMIME_write_CMS(out, cms, in, CMS_STREAM))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Signing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +
        +	if (scert)
        +		X509_free(scert);
        +	if (skey)
        +		EVP_PKEY_free(skey);
        +
        +	if (scert2)
        +		X509_free(scert2);
        +	if (skey)
        +		EVP_PKEY_free(skey2);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_uncomp.c b/vendor/openssl/openssl/demos/cms/cms_uncomp.c
        new file mode 100644
        index 000000000..f15ae2f13
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_uncomp.c
        @@ -0,0 +1,56 @@
        +/* Simple S/MIME uncompression example */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Open compressed content */
        +
        +	in = BIO_new_file("smcomp.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Sign content */
        +	cms = SMIME_read_CMS(in, NULL);
        +
        +	if (!cms)
        +		goto err;
        +
        +	out = BIO_new_file("smuncomp.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Uncompress S/MIME message */
        +	if (!CMS_uncompress(cms, out, NULL, 0))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Uncompressing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/cms_ver.c b/vendor/openssl/openssl/demos/cms/cms_ver.c
        new file mode 100644
        index 000000000..bf1145ed8
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/cms_ver.c
        @@ -0,0 +1,87 @@
        +/* Simple S/MIME verification example */
        +#include <openssl/pem.h>
        +#include <openssl/cms.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
        +	X509_STORE *st = NULL;
        +	X509 *cacert = NULL;
        +	CMS_ContentInfo *cms = NULL;
        +
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Set up trusted CA certificate store */
        +
        +	st = X509_STORE_new();
        +
        +	/* Read in CA certificate */
        +	tbio = BIO_new_file("cacert.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	if (!cacert)
        +		goto err;
        +
        +	if (!X509_STORE_add_cert(st, cacert))
        +		goto err;
        +
        +	/* Open message being verified */
        +
        +	in = BIO_new_file("smout.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* parse message */
        +	cms = SMIME_read_CMS(in, &cont);
        +
        +	if (!cms)
        +		goto err;
        +
        +	/* File to output verified content to */
        +	out = BIO_new_file("smver.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	if (!CMS_verify(cms, NULL, st, cont, out, 0))
        +		{
        +		fprintf(stderr, "Verification Failure\n");
        +		goto err;
        +		}
        +
        +	fprintf(stderr, "Verification Successful\n");
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Verifying Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (cms)
        +		CMS_ContentInfo_free(cms);
        +
        +	if (cacert)
        +		X509_free(cacert);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/cms/comp.txt b/vendor/openssl/openssl/demos/cms/comp.txt
        new file mode 100644
        index 000000000..1672328e7
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/comp.txt
        @@ -0,0 +1,22 @@
        +Content-type: text/plain
        +
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        +Some Text To be Compressed
        diff --git a/vendor/openssl/openssl/demos/cms/encr.txt b/vendor/openssl/openssl/demos/cms/encr.txt
        new file mode 100644
        index 000000000..0eceb407b
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/encr.txt
        @@ -0,0 +1,3 @@
        +Content-type: text/plain
        +
        +Sample OpenSSL Data for CMS encryption
        diff --git a/vendor/openssl/openssl/demos/cms/sign.txt b/vendor/openssl/openssl/demos/cms/sign.txt
        new file mode 100644
        index 000000000..c3f9d73d6
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/sign.txt
        @@ -0,0 +1,3 @@
        +Content-type: text/plain
        +
        +Test OpenSSL CMS Signed Content
        diff --git a/vendor/openssl/openssl/demos/cms/signer.pem b/vendor/openssl/openssl/demos/cms/signer.pem
        new file mode 100644
        index 000000000..bac16ba96
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/signer.pem
        @@ -0,0 +1,32 @@
        +-----BEGIN CERTIFICATE-----
        +MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
        +BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
        +dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3
        +WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
        +TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl
        +bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz
        +jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L
        +ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y
        +gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
        +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
        +BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
        +2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX
        +MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn
        ++Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv
        +lDiQlgX0JtmLgA==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm
        +1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH
        +Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB
        +AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG
        +mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o
        +wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx
        +04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55
        +qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc
        +YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY
        +sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4
        +4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid
        +7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5
        +xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/cms/signer2.pem b/vendor/openssl/openssl/demos/cms/signer2.pem
        new file mode 100644
        index 000000000..25e23d131
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/cms/signer2.pem
        @@ -0,0 +1,32 @@
        +-----BEGIN CERTIFICATE-----
        +MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
        +BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
        +dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0
        +WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
        +TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl
        +bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ
        +jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW
        +ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW
        +GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
        +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
        +BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
        +2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X
        +h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4
        +aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR
        +2aX6rl2JEuJ5Yg==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM
        +nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f
        +nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB
        +AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF
        +6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2
        +CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf
        +m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX
        +2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr
        +upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4
        +ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL
        +SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk
        +gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX
        +pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/easy_tls/Makefile b/vendor/openssl/openssl/demos/easy_tls/Makefile
        new file mode 100644
        index 000000000..208070074
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/Makefile
        @@ -0,0 +1,123 @@
        +# Makefile for easy-tls example application (rudimentary client and server)
        +# $Id: Makefile,v 1.2 2001/09/18 09:15:40 bodo Exp $
        +
        +SOLARIS_CFLAGS=-Wall -pedantic -g -O2
        +SOLARIS_LIBS=-lxnet
        +
        +LINUX_CFLAGS=-Wall -pedantic -g -O2
        +LINUX_LIBS=
        +
        +
        +auto-all:
        +	case `uname -s` in \
        +	SunOS) echo Using SunOS configuration; \
        +	  make SYSCFLAGS="$(SOLARIS_CFLAGS)" SYSLIBS="$(SOLARIS_LIBS)" all;; \
        +	Linux) echo Using Linux configuration; \
        +	  make SYSCFLAGS="$(LINUX_CFLAGS)" SYSLIBS="$(LINUX_LIBS)" all;; \
        +	*) echo "unknown system"; exit 1;; \
        +	esac
        +
        +all: test TAGS
        +
        +# For adapting this Makefile to a different system, only the following
        +# definitions should need customizing:
        +
        +OPENSSLDIR=../..
        +CC=gcc
        +
        +SYSCFLAGS=whatever
        +SYSLIBS=whatever
        +
        +
        +#############################################################################
        +#
        +# SSLeay/OpenSSL imports
        +#
        +# OPENSSLDIR (set above) can be either the directory where OpenSSL is
        +# installed or the directory where it was compiled.
        +
        +# We rely on having a new OpenSSL release where include files
        +# have names like <openssl/ssl.h> (not just <ssl.h>).
        +OPENSSLINCLUDES=-I$(OPENSSLDIR)/include
        +
        +# libcrypto.a and libssl.a are directly in $(OPENSSLDIR) if this is
        +# the compile directory, or in $(OPENSSLDIR)/lib if we use an installed
        +# library.  With the following definition, we can handle either case.
        +OPENSSLLIBS=-L$(OPENSSLDIR) -L$(OPENSSLDIR)/lib -lssl -lcrypto
        +
        +
        +#############################################################################
        +#
        +# Stuff for handling the source files
        +#
        +
        +SOURCES=easy-tls.c test.c
        +HEADERS=easy-tls.h test.h
        +DOCSandEXAMPLESetc=Makefile cert.pem cacerts.pem
        +EVERYTHING=$(SOURCES) $(HEADERS) $(DOCSandEXAMPLESetc)
        +
        +ls: ls-l
        +ls-l:
        +	ls -l $(EVERYTHING)
        +# For RCS:
        +tag:
        +	-rcs -n_`date +%y%m%d`: $(EVERYTHING)
        +	rcs -nMYTAG $(EVERYTHING)
        +	rcs -nMYTAG: $(EVERYTHING)
        +diff:
        +	-rcsdiff -rMYTAG -u $(EVERYTHING)
        +today:
        +	-rcsdiff -r_`date +%y%m%d` -u $(EVERYTHING)
        +ident:
        +	for a in $(EVERYTHING); do ident $$a; done
        +
        +# Distribution .tar:
        +easy-tls.tar.gz: $(EVERYTHING)
        +	tar cvf - $(EVERYTHING) | \
        +	gzip -9 > easy-tls.tar.gz
        +
        +# Working .tar:
        +tls.tgz: $(EVERYTHING)
        +	tar cfv - `find . -type f -a ! -name '*.tgz' -a ! -name '*.tar.gz'` | \
        +	gzip -9 > tls.tgz
        +
        +# For emacs:
        +etags: TAGS
        +TAGS: $(SOURCES) $(HEADERS)
        +	-etags $(SOURCES) $(HEADERS)
        +
        +
        +#############################################################################
        +#
        +# Compilation
        +#
        +# The following definitions are system dependent (and hence defined
        +# at the beginning of this Makefile, where they are more easily found):
        +
        +### CC=gcc
        +### SYSCFLAGS=-Wall -pedantic -g -O2
        +### SYSLIBS=-lxnet
        +
        +EXTRACFLAGS=-DTLS_APP=\"test.h\"
        +# EXTRACFLAGS=-DTLS_APP=\"test.h\" -DDEBUG_TLS
        +
        +#
        +# The rest shouldn't need to be touched.
        +#
        +LDFLAGS=$(SYSLIBS) $(OPENSSLLIBS)
        +INCLUDES=$(OPENSSLINCLUDES)
        +CFLAGS=$(SYSCFLAGS) $(EXTRACFLAGS) $(INCLUDES)
        +
        +OBJS=easy-tls.o test.o
        +
        +clean:
        +	@rm -f test
        +	@rm -f TAGS
        +	@rm -f *.o
        +	@rm -f core
        +
        +test: $(OBJS)
        +	$(CC) $(OBJS) $(LDFLAGS) -o test
        +
        +test.o: $(HEADERS)
        +easy-tls.o: $(HEADERS)
        diff --git a/vendor/openssl/openssl/demos/easy_tls/README b/vendor/openssl/openssl/demos/easy_tls/README
        new file mode 100644
        index 000000000..816a58009
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/README
        @@ -0,0 +1,65 @@
        +easy_tls - generic SSL/TLS proxy
        +========
        +
        +(... and example for non-blocking SSL/TLS I/O multiplexing.)
        +
        +
        +  easy_tls.c, easy_tls.h:
        +
        +     Small generic SSL/TLS proxy library: With a few function calls,
        +     an application socket will be replaced by a pipe handled by a
        +     separate SSL/TLS proxy process.  This allows easily adding
        +     SSL/TLS support to many programs not originally designed for it.
        +
        +     [Actually easy_tls.c is not a proper library: Customization
        +     requires defining preprocessor macros while compiling it.
        +     This is quite confusing, so I'll probably change it.]
        +
        +     These files may be used under the OpenSSL license.
        +
        +
        +
        +  test.c, test.h, Makefile, cert.pem, cacerts.pem:
        +
        +     Rudimentary example program using the easy_tls library, and
        +     example key and certificates for it.  Usage examples:
        +
        +       $ ./test 8443     # create server listening at port 8443
        +       $ ./test 127.0.0.1 8443  # create client, connect to port 8443
        +                                # at IP address 127.0.0.1
        +
        +     'test' will not automatically do SSL/TLS, or even read or write
        +     data -- it must be told to do so on input lines starting
        +     with a command letter.  'W' means write a line, 'R' means
        +     read a line, 'C' means close the connection, 'T' means
        +     start an SSL/TLS proxy.  E.g. (user input tagged with '*'):
        +
        +     * R
        +       <<< 220 mail.example.net
        +     * WSTARTTLS
        +       >>> STARTTLS
        +     * R
        +       <<< 220 Ready to start TLS
        +     * T
        +       test_process_init(fd = 3, client_p = 1, apparg = (nil))
        +       +++ `E:self signed certificate in certificate chain'
        +       +++ `<... certificate info ...>'
        +     * WHELO localhost
        +       >>> HELO localhost
        +       R
        +       <<< 250 mail.example.net
        +
        +     You can even do SSL/TLS over SSL/TLS over SSL/TLS ... by using
        +     'T' multiple times.  I have no idea why you would want to though.
        +
        +
        +This code is rather old.  When I find time I will update anything that
        +should be changed, and improve code comments.  To compile the sample
        +program 'test' on platforms other then Linux or Solaris, you will have
        +to edit the Makefile.
        +
        +As noted above, easy_tls.c will be changed to become a library one
        +day, which means that future revisions will not be fully compatible to
        +the current version.
        +
        +Bodo Möller <bodo@openssl.org>
        diff --git a/vendor/openssl/openssl/demos/easy_tls/cacerts.pem b/vendor/openssl/openssl/demos/easy_tls/cacerts.pem
        new file mode 100644
        index 000000000..acc70baf1
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/cacerts.pem
        @@ -0,0 +1,18 @@
        +$Id: cacerts.pem,v 1.1 2001/09/17 19:06:57 bodo Exp $
        +
        +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
        +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
        +-----BEGIN CERTIFICATE-----
        +MIICJjCCAY8CAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV
        +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD
        +VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0M1oXDTAxMDYw
        +OTEzNTc0M1owWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
        +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgxMDI0
        +IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgybTsZ
        +DCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/dFXSv
        +1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUecQU2
        +mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAM7achv3v
        +hLQJcv/65eGEpBXM40ZDVoFQFFJWaY5p883HTqLB1x4FdzsXHH0QKBTcKpWwqyu4
        +YDm3fb8oDugw72bCzfyZK/zVZPR/hVlqI/fvU109Qoc+7oPvIXWky71HfcK6ZBCA
        +q30KIqGM/uoM60INq97qjDmCJapagcNBGQs=
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/demos/easy_tls/cert.pem b/vendor/openssl/openssl/demos/easy_tls/cert.pem
        new file mode 100644
        index 000000000..364fe10d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/cert.pem
        @@ -0,0 +1,31 @@
        +$Id: cert.pem,v 1.1 2001/09/17 19:06:57 bodo Exp $
        +
        +Example certificate and key.
        +
        +-----BEGIN CERTIFICATE-----
        +MIIB1jCCAT8CAQEwDQYJKoZIhvcNAQEEBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV
        +BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
        +ZDAeFw05OTA1MDEwMTI2MzVaFw05OTA1MzEwMTI2MzVaMCIxCzAJBgNVBAYTAkRF
        +MRMwEQYDVQQDEwpUZXN0c2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
        +gQD6I3oDKiexwwlkzjar69AIFnVUaG85LtCege2R+CtIDlkQYw68/8MbT3ou0pdF
        +AcL9IGiYY3Y0SHM9PqF00RO1MCtNpqTnF3ScLpbmggGjKilmWYn2ai7emdjMjXVL
        +tzWW2xGgIGATWQN32KgfJng4jXi1UjEiyLhkw0Zf1I/ggwIDAQABMA0GCSqGSIb3
        +DQEBBAUAA4GBAMgM+sbAk8DfjSfa+Rf2gcGXmbrvZAzKzC+5RU3kaq/NyxIXAGco
        +9dZjozzWfN/xuGup5boFk+KrP+xdgsaqGHsyzlgEoqz4ekqLjQeVbnoj339hVFU9
        +MhPi6JULPxjXKumjfX2LLNkikW5puz8Df3UiX0EiaJvd7EwP8J75tiUT
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXQIBAAKBgQD6I3oDKiexwwlkzjar69AIFnVUaG85LtCege2R+CtIDlkQYw68
        +/8MbT3ou0pdFAcL9IGiYY3Y0SHM9PqF00RO1MCtNpqTnF3ScLpbmggGjKilmWYn2
        +ai7emdjMjXVLtzWW2xGgIGATWQN32KgfJng4jXi1UjEiyLhkw0Zf1I/ggwIDAQAB
        +AoGANST8c1etf1MU19oIO5aqaE19OCXIG7oakNLCCtVTPMfvnE+vffBJH7BPIUuU
        +4BBzwRv1nQrkvk72TPjVjOAu81B1SStKQueun2flVuYxp9NyupNWCBley4QdohlP
        +I92ml2tzTSPmNIoA6jdGyNzFcGchapRRmejsC39F1RUbHQECQQD9KX81Wt8ZOrri
        +dWiEXja1L3X8Bkb9vvUjVMQDTJJPxBJjehC6eurgE6PP6SJD5p/f3RHPCcLr8tSM
        +D4P/OpKhAkEA/PFNlhIZUDKK6aTvG2mn7qQ5phbadOoyN1Js3ttWG5OMOZ6b/QlC
        +Wvp84h44506BIlv+Tg2YAI0AdBUrf7oEowJAM4joAVd/ROaEtqbJ4PBA2L9RmD06
        +5FqkEk4mHLnQqvYx/BgUIbH18ClvVlqSBBqFfw/EmU3WZSuogt6Bs0ocIQJBAOxB
        +AoPiYcxbeQ5kZIVJOXaX49SzUdaUDNVJYrEBUzsspHQJJo/Avz606kJVkjbSR6Ft
        +JWmIHuqcyMikIV4KxFsCQQCU2evoVjVsqkkbHi7W28f73PGBsyu0KIwlK7nu4h08
        +Daf7TAI+A6jW/WRUsJ6dFhUYi7/Jvkcdrlnbgm2fxziX
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/easy_tls/easy-tls.c b/vendor/openssl/openssl/demos/easy_tls/easy-tls.c
        new file mode 100644
        index 000000000..9cd8314c3
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/easy-tls.c
        @@ -0,0 +1,1240 @@
        +/* -*- Mode: C; c-file-style: "bsd" -*- */
        +/*
        + * easy-tls.c -- generic TLS proxy.
        + * $Id: easy-tls.c,v 1.4 2002/03/05 09:07:16 bodo Exp $
        + */
        +/*
        + (c) Copyright 1999 Bodo Moeller.  All rights reserved.
        +
        + This is free software; you can redistributed and/or modify it
        + unter the terms of either
        +   -  the GNU General Public License as published by the
        +      Free Software Foundation, version 1, or (at your option)
        +      any later version,
        + or
        +   -  the following license:
        +*/
        +/*
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that each of the following
        + * conditions is met:
        + *
        + * 1. Redistributions qualify as "freeware" or "Open Source Software" under
        + *    one of the following terms:
        + * 
        + *    (a) Redistributions are made at no charge beyond the reasonable cost of
        + *        materials and delivery.
        + * 
        + *    (b) Redistributions are accompanied by a copy of the Source Code
        + *        or by an irrevocable offer to provide a copy of the Source Code
        + *        for up to three years at the cost of materials and delivery.
        + *        Such redistributions must allow further use, modification, and
        + *        redistribution of the Source Code under substantially the same
        + *        terms as this license.
        + *
        + * 2. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 3. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 4. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by Bodo Moeller."
        + *    (If available, substitute umlauted o for oe.)
        + *
        + * 5. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by Bodo Moeller."
        + *
        + * THIS SOFTWARE IS PROVIDED BY BODO MOELLER ``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 BODO MOELLER OR
        + * HIS 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.
        + */
        +/*
        + * Attribution for OpenSSL library:
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + * This product includes software developed by the OpenSSL Project
        + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)
        + */
        +
        +static char const rcsid[] =
        +"$Id: easy-tls.c,v 1.4 2002/03/05 09:07:16 bodo Exp $";
        +
        +#include <assert.h>
        +#include <errno.h>
        +#include <fcntl.h>
        +#include <limits.h>
        +#include <stdarg.h>
        +#include <stdio.h>
        +#include <string.h>
        +#include <sys/select.h>
        +#include <sys/socket.h>
        +#include <sys/stat.h>
        +#include <sys/time.h>
        +#include <sys/types.h>
        +#include <sys/utsname.h>
        +#include <unistd.h>
        +
        +#include <openssl/crypto.h>
        +#include <openssl/dh.h>
        +#include <openssl/dsa.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/opensslv.h>
        +#include <openssl/pem.h>
        +#include <openssl/rand.h>
        +#ifndef NO_RSA
        + #include <openssl/rsa.h>
        +#endif
        +#include <openssl/ssl.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509_vfy.h>
        +
        +#if OPENSSL_VERSION_NUMBER < 0x00904000L /* 0.9.4-dev */
        +# error "This program needs OpenSSL 0.9.4 or later."
        +#endif
        +
        +#include "easy-tls.h" /* include after <openssl/ssl.h> if both are needed */
        +
        +#if TLS_INFO_SIZE > PIPE_BUF
        +# if PIPE_BUF < 512
        +#  error "PIPE_BUF < 512" /* non-POSIX */
        +# endif
        +# error "TLS_INFO_SIZE > PIPE_BUF"
        +#endif
        +
        +/*****************************************************************************/
        +
        +#ifdef TLS_APP
        +# include TLS_APP
        +#endif
        +
        +/* Applications can define:
        + *   TLS_APP_PROCESS_INIT -- void ...(int fd, int client_p, void *apparg)
        + *   TLS_CUMULATE_ERRORS 
        + *   TLS_ERROR_BUFSIZ
        + *   TLS_APP_ERRFLUSH -- void ...(int child_p, char *, size_t, void *apparg)
        + */
        +
        +#ifndef TLS_APP_PROCESS_INIT
        +# define TLS_APP_PROCESS_INIT(fd, client_p, apparg) ((void) 0)
        +#endif
        +
        +#ifndef TLS_ERROR_BUFSIZ
        +# define TLS_ERROR_BUFSIZ (10*160)
        +#endif
        +#if TLS_ERROR_BUFSIZ < 2 /* {'\n',0} */
        +# error "TLS_ERROR_BUFSIZE is too small."
        +#endif
        +
        +#ifndef TLS_APP_ERRFLUSH
        +# define TLS_APP_ERRFLUSH tls_app_errflush
        +static void
        +tls_app_errflush(int child_p, char *errbuf, size_t num, void *apparg)
        +{
        +    fputs(errbuf, stderr);
        +}
        +#endif
        +
        +/*****************************************************************************/
        +
        +#ifdef DEBUG_TLS
        +# define DEBUG_MSG(x) fprintf(stderr,"  %s\n",x)
        +# define DEBUG_MSG2(x,y) fprintf(stderr, "  %s: %d\n",x,y)
        +static int tls_loop_count = 0;
        +static int tls_select_count = 0;
        +#else
        +# define DEBUG_MSG(x) (void)0
        +# define DEBUG_MSG2(x,y) (void)0
        +#endif
        +
        +static void tls_rand_seed_uniquely(void);
        +static void tls_proxy(int clear_fd, int tls_fd, int info_fd, SSL_CTX *ctx, int client_p);
        +static int tls_socket_nonblocking(int fd);
        +
        +static int tls_child_p = 0;
        +static void *tls_child_apparg;
        +
        +
        +struct tls_start_proxy_args
        +tls_start_proxy_defaultargs(void)
        +{
        +    struct tls_start_proxy_args ret;
        +
        +    ret.fd = -1;
        +    ret.client_p = -1;
        +    ret.ctx = NULL;
        +    ret.pid = NULL;
        +    ret.infofd = NULL;
        +    
        +    return ret;
        +}
        +
        +/* Slice in TLS proxy process at fd.
        + * Return value:
        + *   0    ok  (*pid is set to child's PID if pid != NULL),
        + *   < 0  look at errno
        + *   > 0  other error
        + *   (return value encodes place of error)
        + *
        + */
        +int
        +tls_start_proxy(struct tls_start_proxy_args a, void *apparg)
        +{
        +    int fds[2] = {-1, -1};
        +    int infofds[2] = {-1, -1};
        +    int r, getfd, getfl;
        +    int ret;
        +
        +    DEBUG_MSG2("tls_start_proxy fd", a.fd);
        +    DEBUG_MSG2("tls_start_proxy client_p", a.client_p);
        +
        +    if (a.fd == -1 || a.client_p == -1 || a.ctx == NULL)
        +	return 1;
        +
        +    if (a.pid != NULL) {
        +	*a.pid = 0;
        +    }
        +    if (a.infofd != NULL) {
        +	*a.infofd = -1;
        +    }
        +
        +    r = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
        +    if (r == -1)
        +	return -1;
        +    if (a.fd >= FD_SETSIZE || fds[0] >= FD_SETSIZE) {
        +	ret = 2;
        +	goto err;
        +    }
        +    if (a.infofd != NULL) {
        +	r = pipe(infofds);
        +	if (r == -1) {
        +	    ret = -3;
        +	    goto err;
        +	}
        +    }
        +
        +    r = fork();
        +    if (r == -1) {
        +	ret = -4;
        +	goto err;
        +    }
        +    if (r == 0) {
        +	DEBUG_MSG("fork");
        +	tls_child_p = 1;
        +	tls_child_apparg = apparg;
        +	close(fds[1]);
        +	if (infofds[0] != -1)
        +	    close(infofds[0]);
        +	TLS_APP_PROCESS_INIT(a.fd, a.client_p, apparg);
        +	DEBUG_MSG("TLS_APP_PROCESS_INIT");
        +	tls_proxy(fds[0], a.fd, infofds[1], a.ctx, a.client_p);
        +	exit(0);
        +    }
        +    if (a.pid != NULL)
        +	*a.pid = r;
        +    if (infofds[1] != -1) {
        +	close(infofds[1]);
        +	infofds[1] = -1;
        +    }
        +    /* install fds[1] in place of fd: */
        +    close(fds[0]);
        +    fds[0] = -1;
        +    getfd = fcntl(a.fd, F_GETFD);
        +    getfl = fcntl(a.fd, F_GETFL);
        +    r = dup2(fds[1], a.fd);
        +    close(fds[1]);
        +    fds[1] = -1;
        +    if (r == -1) {
        +	ret = -5;
        +	goto err;
        +    }
        +    if (getfd != 1)
        +	fcntl(a.fd, F_SETFD, getfd);
        +    if (getfl & O_NONBLOCK)
        +	(void)tls_socket_nonblocking(a.fd);
        +    if (a.infofd != NULL)
        +	*a.infofd = infofds[0];
        +    return 0;
        +    
        +  err:
        +    if (fds[0] != -1)
        +	close(fds[0]);
        +    if (fds[1] != -1)
        +	close(fds[1]);
        +    if (infofds[0] != -1)
        +	close(infofds[0]);
        +    if (infofds[1] != -1)
        +	close(infofds[1]);
        +    return ret;
        +}
        +
        +/*****************************************************************************/
        +
        +static char errbuf[TLS_ERROR_BUFSIZ];
        +static size_t errbuf_i = 0;
        +
        +static void
        +tls_errflush(void *apparg)
        +{
        +    if (errbuf_i == 0)
        +	return;
        +    
        +    assert(errbuf_i < sizeof errbuf);
        +    assert(errbuf[errbuf_i] == 0);
        +    if (errbuf_i == sizeof errbuf - 1) {
        +	/* make sure we have a newline, even if string has been truncated */
        +	errbuf[errbuf_i - 1] = '\n';
        +    }
        +
        +    /* TLS_APP_ERRFLUSH may modify the string as needed,
        +     * e.g. substitute other characters for \n for convenience */
        +    TLS_APP_ERRFLUSH(tls_child_p, errbuf, errbuf_i, apparg);
        +
        +    errbuf_i = 0;
        +}
        +
        +static void
        +tls_errprintf(int flush, void *apparg, const char *fmt, ...)
        +{
        +    va_list args;
        +    int r;
        +    
        +    if (errbuf_i < sizeof errbuf - 1) {
        +	size_t n;
        +
        +	va_start(args, fmt);
        +	n = (sizeof errbuf) - errbuf_i;
        +	r = vsnprintf(errbuf + errbuf_i, n, fmt, args);
        +	if (r >= n)
        +	    r = n - 1;
        +	if (r >= 0) {
        +	    errbuf_i += r;
        +	} else {
        +	    errbuf_i = sizeof errbuf - 1;
        +	    errbuf[errbuf_i] = '\0';
        +	}
        +	assert(errbuf_i < sizeof errbuf);
        +	assert(errbuf[errbuf_i] == 0);
        +    }
        +#ifndef TLS_CUMULATE_ERRORS
        +    tls_errflush(apparg);
        +#else
        +    if (flush)
        +	tls_errflush(apparg);
        +#endif
        +}
        +
        +/* app_prefix.. are for additional information provided by caller.
        + * If OpenSSL error queue is empty, print default_text ("???" if NULL).
        + */
        +static char *
        +tls_openssl_errors(const char *app_prefix_1, const char *app_prefix_2, const char *default_text, void *apparg)
        +{
        +    static char reasons[255];
        +    size_t reasons_i;
        +    unsigned long err;
        +    const char *file;
        +    int line;
        +    const char *data;
        +    int flags;
        +    char *errstring;
        +    int printed_something = 0;
        +    
        +    reasons_i = 0;
        +
        +    assert(app_prefix_1 != NULL);
        +    assert(app_prefix_2 != NULL);
        +
        +    if (default_text == NULL)
        +	default_text = "?""?""?";
        +    
        +    while ((err = ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) {
        +	if (reasons_i < sizeof reasons) {
        +	    size_t n;
        +	    int r;
        +
        +	    n = (sizeof reasons) - reasons_i;
        +	    r = snprintf(reasons + reasons_i, n, "%s%s", (reasons_i > 0 ? ", " : ""), ERR_reason_error_string(err));
        +	    if (r >= n)
        +		r = n - 1;
        +	    if (r >= 0) {
        +		reasons_i += r;
        +	    } else {
        +		reasons_i = sizeof reasons;
        +	    }
        +	    assert(reasons_i <= sizeof reasons);
        +	}
        +	
        +	errstring = ERR_error_string(err, NULL);
        +	assert(errstring != NULL);
        +	tls_errprintf(0, apparg, "OpenSSL error%s%s: %s:%s:%d:%s\n", app_prefix_1, app_prefix_2, errstring, file, line, (flags & ERR_TXT_STRING) ? data : "");
        +	printed_something = 1;
        +    }
        +
        +    if (!printed_something) {
        +	assert(reasons_i == 0);
        +	snprintf(reasons, sizeof reasons, "%s", default_text);
        +	tls_errprintf(0, apparg, "OpenSSL error%s%s: %s\n", app_prefix_1, app_prefix_2, default_text);
        +    }
        +
        +#ifdef TLS_CUMULATE_ERRORS    
        +    tls_errflush(apparg);
        +#endif
        +    assert(errbuf_i == 0);
        +
        +    return reasons;
        +}
        +
        +/*****************************************************************************/
        +
        +static int tls_init_done = 0;
        +
        +static int
        +tls_init(void *apparg)
        +{
        +    if (tls_init_done)
        +	return 0;
        +    
        +    SSL_load_error_strings();
        +    if (!SSL_library_init() /* aka SSLeay_add_ssl_algorithms() */ ) {
        +	tls_errprintf(1, apparg, "SSL_library_init failed.\n");
        +	return -1;
        +    }
        +    tls_init_done = 1;
        +    tls_rand_seed();
        +    return 0;
        +}
        +
        +/*****************************************************************************/
        +
        +static void
        +tls_rand_seed_uniquely(void)
        +{
        +    struct {
        +	pid_t pid;
        +	time_t time;
        +	void *stack;
        +    } data;
        +
        +    data.pid = getpid();
        +    data.time = time(NULL);
        +    data.stack = (void *)&data;
        +
        +    RAND_seed((const void *)&data, sizeof data);
        +}
        +
        +void
        +tls_rand_seed(void)
        +{
        +    struct {
        +	struct utsname uname;
        +	int uname_1;
        +	int uname_2;
        +	uid_t uid;
        +	uid_t euid;
        +	gid_t gid;
        +	gid_t egid;
        +    } data;
        +    
        +    data.uname_1 = uname(&data.uname);
        +    data.uname_2 = errno; /* Let's hope that uname fails randomly :-) */
        +
        +    data.uid = getuid();
        +    data.euid = geteuid();
        +    data.gid = getgid();
        +    data.egid = getegid();
        +    
        +    RAND_seed((const void *)&data, sizeof data);
        +    tls_rand_seed_uniquely();
        +}
        +
        +static int tls_rand_seeded_p = 0;
        +
        +#define my_MIN_SEED_BYTES 256 /* struct stat can be larger than 128 */
        +int
        +tls_rand_seed_from_file(const char *filename, size_t n, void *apparg)
        +{
        +    /* Seed OpenSSL's random number generator from file.
        +       Try to read n bytes if n > 0, whole file if n == 0. */
        +
        +    int r;
        +
        +    if (tls_init(apparg) == -1)
        +	return -1;
        +    tls_rand_seed();
        +
        +    r = RAND_load_file(filename, (n > 0 && n < LONG_MAX) ? (long)n : LONG_MAX);
        +    /* r is the number of bytes filled into the random number generator,
        +     * which are taken from "stat(filename, ...)" in addition to the
        +     * file contents.
        +     */
        +    assert(1 < my_MIN_SEED_BYTES);
        +    /* We need to detect at least those cases when the file does not exist
        +     * at all.  With current versions of OpenSSL, this should do it: */
        +    if (n == 0)
        +	n = my_MIN_SEED_BYTES;
        +    if (r < n) {
        +	tls_errprintf(1, apparg, "rand_seed_from_file: could not read %d bytes from %s.\n", n, filename);
        +	return -1;
        +    } else {
        +	tls_rand_seeded_p = 1;
        +	return 0;
        +    }
        +}
        +
        +void
        +tls_rand_seed_from_memory(const void *buf, size_t n)
        +{
        +    size_t i = 0;
        +    
        +    while (i < n) {
        +	size_t rest = n - i;
        +	int chunk = rest < INT_MAX ? (int)rest : INT_MAX;
        +	RAND_seed((const char *)buf + i, chunk);
        +	i += chunk;
        +    }
        +    tls_rand_seeded_p = 1;
        +}
        +
        +
        +/*****************************************************************************/
        +
        +struct tls_x509_name_string {
        +    char str[100];
        +};
        +
        +static void
        +tls_get_x509_subject_name_oneline(X509 *cert, struct tls_x509_name_string *namestring)
        +{
        +    X509_NAME *name;
        +
        +    if (cert == NULL) {
        +	namestring->str[0] = '\0';
        +	return;
        +    }
        +    
        +    name = X509_get_subject_name(cert); /* does not increment any reference counter */
        +
        +    assert(sizeof namestring->str >= 4); /* "?" or "...", plus 0 */
        +    
        +    if (name == NULL) {
        +	namestring->str[0] = '?';
        +	namestring->str[1] = 0;
        +    } else {
        +	size_t len;
        +
        +	X509_NAME_oneline(name, namestring->str, sizeof namestring->str);
        +	len = strlen(namestring->str);
        +	assert(namestring->str[len] == 0);
        +	assert(len < sizeof namestring->str);
        +
        +	if (len+1 == sizeof namestring->str) {
        +	    /* (Probably something was cut off.)
        +	     * Does not really work -- X509_NAME_oneline truncates after
        +	     * name components, we cannot tell from the result whether
        +	     * anything is missing. */
        +
        +	    assert(namestring->str[len] == 0);
        +	    namestring->str[--len] = '.';
        +	    namestring->str[--len] = '.';
        +	    namestring->str[--len] = '.';
        +	}
        +    }
        +}
        +
        +/*****************************************************************************/
        +
        +/* to hinder OpenSSL from asking for passphrases */
        +static int
        +no_passphrase_callback(char *buf, int num, int w, void *arg)
        +{
        +    return -1;
        +}
        +
        +#if OPENSSL_VERSION_NUMBER >= 0x00907000L
        +static int
        +verify_dont_fail_cb(X509_STORE_CTX *c, void *unused_arg)
        +#else
        +static int
        +verify_dont_fail_cb(X509_STORE_CTX *c)
        +#endif
        +{
        +    int i;
        +    
        +    i = X509_verify_cert(c); /* sets c->error */
        +#if OPENSSL_VERSION_NUMBER >= 0x00905000L /* don't allow unverified
        +					   * certificates -- they could
        +					   * survive session reuse, but
        +					   * OpenSSL < 0.9.5-dev does not
        +					   * preserve their verify_result */
        +    if (i == 0)
        +	return 1;
        +    else
        +#endif
        +	return i;
        +}
        +
        +static DH *tls_dhe1024 = NULL; /* generating these takes a while, so do it just once */
        +
        +void
        +tls_set_dhe1024(int i, void *apparg)
        +{
        +    DSA *dsaparams;
        +    DH *dhparams;
        +    const char *seed[] = { ";-)  :-(  :-)  :-(  ",
        +			   ";-)  :-(  :-)  :-(  ",
        +			   "Random String no. 12",
        +			   ";-)  :-(  :-)  :-(  ",
        +			   "hackers have even mo", /* from jargon file */
        +    };
        +    unsigned char seedbuf[20];
        +    
        +    tls_init(apparg);
        +    if (i >= 0) {
        +	i %= sizeof seed / sizeof seed[0];
        +	assert(strlen(seed[i]) == 20);
        +	memcpy(seedbuf, seed[i], 20);
        +	dsaparams = DSA_generate_parameters(1024, seedbuf, 20, NULL, NULL, 0, NULL);
        +    } else {
        +	/* random parameters (may take a while) */
        +	dsaparams = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, 0, NULL);
        +    }
        +    
        +    if (dsaparams == NULL) {
        +	tls_openssl_errors("", "", NULL, apparg);
        +	return;
        +    }
        +    dhparams = DSA_dup_DH(dsaparams);
        +    DSA_free(dsaparams);
        +    if (dhparams == NULL) {
        +	tls_openssl_errors("", "", NULL, apparg);
        +	return;
        +    }
        +    if (tls_dhe1024 != NULL)
        +	DH_free(tls_dhe1024);
        +    tls_dhe1024 = dhparams;
        +}
        +
        +struct tls_create_ctx_args
        +tls_create_ctx_defaultargs(void)
        +{
        +	struct tls_create_ctx_args ret;
        +
        +	ret.client_p = 0;
        +	ret.certificate_file = NULL;
        +	ret.key_file = NULL;
        +	ret.ca_file = NULL;
        +	ret.verify_depth = -1;
        +	ret.fail_unless_verified = 0;
        +	ret.export_p = 0;
        +
        +	return ret;
        +}
        +
        +SSL_CTX *
        +tls_create_ctx(struct tls_create_ctx_args a, void *apparg)
        +{
        +    int r;
        +    static long context_num = 0;
        +    SSL_CTX *ret;
        +    const char *err_pref_1 = "", *err_pref_2 = "";
        +    
        +    if (tls_init(apparg) == -1)
        +	return NULL;
        +
        +    ret = SSL_CTX_new((a.client_p? SSLv23_client_method:SSLv23_server_method)());
        +
        +    if (ret == NULL)
        +	goto err;
        +
        +    SSL_CTX_set_default_passwd_cb(ret, no_passphrase_callback);
        +    SSL_CTX_set_mode(ret, SSL_MODE_ENABLE_PARTIAL_WRITE);
        +    
        +    if ((a.certificate_file != NULL) || (a.key_file != NULL)) {
        +	if (a.key_file == NULL) {
        +	    tls_errprintf(1, apparg, "Need a key file.\n");
        +	    goto err_return;
        +	}
        +	if (a.certificate_file == NULL) {
        +	    tls_errprintf(1, apparg, "Need a certificate chain file.\n");
        +	    goto err_return;
        +	}
        +	
        +	if (!SSL_CTX_use_PrivateKey_file(ret, a.key_file, SSL_FILETYPE_PEM))
        +	    goto err;
        +	if (!tls_rand_seeded_p) {
        +	    /* particularly paranoid people may not like this --
        +	     * so provide your own random seeding before calling this */
        +	    if (tls_rand_seed_from_file(a.key_file, 0, apparg) == -1)
        +		goto err_return;
        +	}
        +	if (!SSL_CTX_use_certificate_chain_file(ret, a.certificate_file))
        +	    goto err;
        +	if (!SSL_CTX_check_private_key(ret)) {
        +	    tls_errprintf(1, apparg, "Private key \"%s\" does not match certificate \"%s\".\n", a.key_file, a.certificate_file);
        +	    goto err_peek;
        +	}
        +    }
        +    
        +    if ((a.ca_file != NULL) || (a.verify_depth > 0)) {
        +	context_num++;
        +	r = SSL_CTX_set_session_id_context(ret, (const void *)&context_num, (unsigned int)sizeof context_num);
        +	if (!r)
        +	    goto err;
        +	
        +	SSL_CTX_set_verify(ret, SSL_VERIFY_PEER | (a.fail_unless_verified ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0), 0);
        +	if (!a.fail_unless_verified)
        +	    SSL_CTX_set_cert_verify_callback(ret, verify_dont_fail_cb, NULL);
        +	    
        +	if (a.verify_depth > 0)
        +	    SSL_CTX_set_verify_depth(ret, a.verify_depth);
        +	
        +	if (a.ca_file != NULL) {
        +	    r = SSL_CTX_load_verify_locations(ret, a.ca_file, NULL /* no CA-directory */); /* does not report failure if file does not exist ... */
        +	    if (!r) {
        +		err_pref_1 = " while processing certificate file ";
        +		err_pref_2 = a.ca_file;
        +		goto err;
        +	    }
        +	    
        +	    if (!a.client_p) {
        +		/* SSL_load_client_CA_file is a misnomer, it just creates a list of CNs. */
        +		SSL_CTX_set_client_CA_list(ret, SSL_load_client_CA_file(a.ca_file));
        +		/* SSL_CTX_set_client_CA_list does not have a return value;
        +		 * it does not really need one, but make sure
        +		 * (we really test if SSL_load_client_CA_file worked) */
        +		if (SSL_CTX_get_client_CA_list(ret) == NULL) {
        +		    tls_errprintf(1, apparg, "Could not set client CA list from \"%s\".\n", a.ca_file);
        +		    goto err_peek;
        +		}
        +	    }
        +	}
        +    }
        +    
        +    if (!a.client_p) {
        +	if (tls_dhe1024 == NULL) {
        +	    int i;
        +
        +	    RAND_bytes((unsigned char *) &i, sizeof i);
        +	    /* make sure that i is non-negative -- pick one of the provided
        +	     * seeds */
        +	    if (i < 0)
        +		i = -i;
        +	    if (i < 0)
        +		i = 0;
        +	    tls_set_dhe1024(i, apparg);
        +	    if (tls_dhe1024 == NULL)
        +		goto err_return;
        +	}
        +	
        +	if (!SSL_CTX_set_tmp_dh(ret, tls_dhe1024))
        +	    goto err;
        +
        +	/* avoid small subgroup attacks: */
        +	SSL_CTX_set_options(ret, SSL_OP_SINGLE_DH_USE);
        +    }
        +	
        +#ifndef NO_RSA
        +    if (!a.client_p && a.export_p) {
        +	RSA *tmpkey;
        +
        +	tmpkey = RSA_generate_key(512, RSA_F4, 0, NULL);
        +	if (tmpkey == NULL)
        +	    goto err;
        +	if (!SSL_CTX_set_tmp_rsa(ret, tmpkey)) {
        +	    RSA_free(tmpkey);
        +	    goto err;
        +	}
        +	RSA_free(tmpkey); /* SSL_CTX_set_tmp_rsa uses a duplicate. */
        +    }
        +#endif
        +	
        +    return ret;
        +    
        + err_peek:
        +    if (!ERR_peek_error())
        +	goto err_return;
        + err:
        +    tls_openssl_errors(err_pref_1, err_pref_2, NULL, apparg);
        + err_return:
        +    if (ret != NULL)
        +	SSL_CTX_free(ret);
        +    return NULL;
        +}
        +
        +
        +/*****************************************************************************/
        +
        +static int
        +tls_socket_nonblocking(int fd)
        +{
        +    int v, r;
        +
        +    v = fcntl(fd, F_GETFL, 0);
        +    if (v == -1) {
        +	if (errno == EINVAL)
        +	    return 0; /* already shut down -- ignore */
        +	return -1;
        +    }
        +    r = fcntl(fd, F_SETFL, v | O_NONBLOCK);
        +    if (r == -1) {
        +	if (errno == EINVAL)
        +	    return 0; /* already shut down -- ignore */
        +	return -1;
        +    }
        +    return 0;
        +}
        +
        +static int
        +max(int a, int b)
        +{
        +    return a > b ? a : b;
        +}
        +
        +static void
        +tls_sockets_select(int read_select_1, int read_select_2, int write_select_1, int write_select_2, int seconds /* timeout, -1 means no timeout */)
        +{
        +    int maxfd, n;
        +    fd_set reads, writes;
        +    struct timeval timeout;
        +    struct timeval *timeout_p;
        +    
        +    assert(read_select_1 >= -1 && read_select_2 >= -1 && write_select_1 >= -1 && write_select_2 >= -1);
        +    assert(read_select_1 < FD_SETSIZE && read_select_2 < FD_SETSIZE -1 && write_select_1 < FD_SETSIZE -1 && write_select_2 < FD_SETSIZE -1);
        +
        +    maxfd = max(max(read_select_1, read_select_2), max(write_select_1, write_select_2));
        +    assert(maxfd >= 0);
        +
        +    FD_ZERO(&reads);
        +    FD_ZERO(&writes);
        +    
        +    for(n = 0; n < 4; ++n) {
        +	int i = n % 2;
        +	int w = n >= 2;
        +	/* loop over all (i, w) in {0,1}x{0,1} */
        +	int fd;
        +	
        +	if (i == 0 && w == 0)
        +	    fd = read_select_1;
        +	else if (i == 1 && w == 0)
        +	    fd = read_select_2;
        +	else if (i == 0 && w == 1)
        +	    fd = write_select_1;
        +	else {
        +	    assert(i == 1 && w == 1);
        +	    fd = write_select_2;
        +	}
        +	
        +	if (fd >= 0) {
        +	    if (w == 0)
        +		FD_SET(fd, &reads);
        +	    else /* w == 1 */
        +		FD_SET(fd, &writes);
        +	}
        +    }
        +
        +    if (seconds >= 0) {
        +	timeout.tv_sec = seconds;
        +	timeout.tv_usec = 0;
        +	timeout_p = &timeout;
        +    } else 
        +	timeout_p = NULL;
        +
        +    DEBUG_MSG2("select no.", ++tls_select_count);
        +    select(maxfd + 1, &reads, &writes, (fd_set *) NULL, timeout_p);
        +    DEBUG_MSG("cont.");
        +}
        +
        +/*****************************************************************************/
        +
        +#define TUNNELBUFSIZE (16*1024)
        +struct tunnelbuf {
        +    char buf[TUNNELBUFSIZE];
        +    size_t len;
        +    size_t offset;
        +};
        +
        +static int tls_connect_attempt(SSL *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
        +
        +static int tls_accept_attempt(SSL *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
        +
        +static int tls_write_attempt(SSL *, struct tunnelbuf *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
        +
        +static int tls_read_attempt(SSL *, struct tunnelbuf *, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref);
        +
        +static int write_attempt(int fd, struct tunnelbuf *, int *select, int *closed, int *progress);
        +
        +static int read_attempt(int fd, struct tunnelbuf *, int *select, int *closed, int *progress);
        +
        +static void write_info(SSL *ssl, int *info_fd)
        +{
        +    if (*info_fd != -1) {
        +	long v;
        +	int v_ok;
        +	struct tls_x509_name_string peer;
        +	char infobuf[TLS_INFO_SIZE];
        +	int r;
        +
        +	DEBUG_MSG("write_info");
        +	v = SSL_get_verify_result(ssl);
        +	v_ok = (v == X509_V_OK) ? 'A' : 'E'; /* Auth./Error */
        +	{
        +	    X509 *peercert;
        +
        +	    peercert = SSL_get_peer_certificate(ssl);
        +	    tls_get_x509_subject_name_oneline(peercert, &peer);
        +	    if (peercert != NULL)
        +		X509_free(peercert);
        +	}
        +	if (peer.str[0] == '\0')
        +	    v_ok = '0'; /* no cert at all */
        +	else
        +	    if (strchr(peer.str, '\n')) {
        +		/* should not happen, but make sure */
        +		*strchr(peer.str, '\n') = '\0';
        +	    }
        +	r = snprintf(infobuf, sizeof infobuf, "%c:%s\n%s\n", v_ok, X509_verify_cert_error_string(v), peer.str);
        +	DEBUG_MSG2("snprintf", r);
        +	if (r == -1 || r >= sizeof infobuf)
        +	    r = sizeof infobuf - 1;
        +	write(*info_fd, infobuf, r);
        +	close (*info_fd);
        +	*info_fd = -1;
        +    }
        +}
        +
        +
        +/* tls_proxy expects that all fds are closed after return */
        +static void
        +tls_proxy(int clear_fd, int tls_fd, int info_fd, SSL_CTX *ctx, int client_p)
        +{
        +    struct tunnelbuf clear_to_tls, tls_to_clear;
        +    SSL *ssl;
        +    BIO *rbio, *wbio;
        +    int closed, in_handshake;
        +    const char *err_pref_1 = "", *err_pref_2 = "";
        +    const char *err_def = NULL;
        +
        +    assert(clear_fd != -1);
        +    assert(tls_fd != -1);
        +    assert(clear_fd < FD_SETSIZE);
        +    assert(tls_fd < FD_SETSIZE);
        +    /* info_fd may be -1 */
        +    assert(ctx != NULL);
        +
        +    tls_rand_seed_uniquely();
        +
        +    tls_socket_nonblocking(clear_fd);
        +    DEBUG_MSG2("clear_fd", clear_fd);
        +    tls_socket_nonblocking(tls_fd);
        +    DEBUG_MSG2("tls_fd", tls_fd);
        +
        +    ssl = SSL_new(ctx);
        +    if (ssl == NULL)
        +	goto err;
        +    DEBUG_MSG("SSL_new");
        +    if (!SSL_set_fd(ssl, tls_fd))
        +	goto err;
        +    rbio = SSL_get_rbio(ssl);
        +    wbio = SSL_get_wbio(ssl); /* should be the same, but who cares */
        +    assert(rbio != NULL);
        +    assert(wbio != NULL);
        +    if (client_p)
        +	SSL_set_connect_state(ssl);
        +    else
        +	SSL_set_accept_state(ssl);
        +    
        +    closed = 0;
        +    in_handshake = 1;
        +    tls_to_clear.len = 0;
        +    tls_to_clear.offset = 0;
        +    clear_to_tls.len = 0;
        +    clear_to_tls.offset = 0;
        +
        +    err_def = "I/O error";
        +    
        +    /* loop finishes as soon as we detect that one side closed;
        +     * when all (program and OS) buffers have enough space,
        +     * the data from the last succesful read in each direction is transferred
        +     * before close */
        +    do {
        +	int clear_read_select = 0, clear_write_select = 0,
        +	    tls_read_select = 0, tls_write_select = 0,
        +	    progress = 0;
        +	int r;
        +	unsigned long num_read = BIO_number_read(rbio),
        +	    num_written = BIO_number_written(wbio);
        +
        +	DEBUG_MSG2("loop iteration", ++tls_loop_count);
        +
        +	if (in_handshake) {
        +	    DEBUG_MSG("in_handshake");
        +	    if (client_p)
        +		r = tls_connect_attempt(ssl, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
        +	    else
        +		r = tls_accept_attempt(ssl, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
        +	    if (r != 0) {
        +		write_info(ssl, &info_fd);
        +		goto err;
        +	    }
        +	    if (closed)
        +		goto err_return;
        +	    if (!SSL_in_init(ssl)) {
        +		in_handshake = 0;
        +		write_info(ssl, &info_fd);
        +	    }
        +	}
        +	
        +	if (clear_to_tls.len != 0 && !in_handshake) {
        +	    assert(!closed);
        +	    
        +	    r = tls_write_attempt(ssl, &clear_to_tls, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
        +	    if (r != 0)
        +		goto err;
        +	    if (closed) {
        +		assert(progress);
        +		tls_to_clear.offset = 0;
        +		tls_to_clear.len = 0;
        +	    }
        +	}
        +	
        +	if (tls_to_clear.len != 0) {
        +	    assert(!closed);
        +
        +	    r = write_attempt(clear_fd, &tls_to_clear, &clear_write_select, &closed, &progress);
        +	    if (r != 0)
        +		goto err_return;
        +	    if (closed) {
        +		assert(progress);
        +		clear_to_tls.offset = 0;
        +		clear_to_tls.len = 0;
        +	    }
        +	}
        +	
        +	if (!closed) {
        +	    if (clear_to_tls.offset + clear_to_tls.len < sizeof clear_to_tls.buf) {
        +		r = read_attempt(clear_fd, &clear_to_tls, &clear_read_select, &closed, &progress);
        +		if (r != 0)
        +		    goto err_return;
        +		if (closed) {
        +		    r = SSL_shutdown(ssl);
        +		    DEBUG_MSG2("SSL_shutdown", r);
        +		}
        +	    }
        +	}
        +	
        +	if (!closed && !in_handshake) {
        +	    if (tls_to_clear.offset + tls_to_clear.len < sizeof tls_to_clear.buf) {
        +		r = tls_read_attempt(ssl, &tls_to_clear, &tls_write_select, &tls_read_select, &closed, &progress, &err_pref_1);
        +		if (r != 0)
        +		    goto err;
        +		if (closed) {
        +		    r = SSL_shutdown(ssl);
        +		    DEBUG_MSG2("SSL_shutdown", r);
        +		}
        +	    }
        +	}
        +
        +	if (!progress) {
        +	    DEBUG_MSG("!progress?");
        +	    if (num_read != BIO_number_read(rbio) || num_written != BIO_number_written(wbio))
        +		progress = 1;
        +
        +	    if (!progress) {
        +		DEBUG_MSG("!progress");
        +		assert(clear_read_select || tls_read_select || clear_write_select || tls_write_select);
        +		tls_sockets_select(clear_read_select ? clear_fd : -1, tls_read_select ? tls_fd : -1, clear_write_select ? clear_fd : -1, tls_write_select ? tls_fd : -1, -1);
        +	    }
        +	}
        +    } while (!closed);
        +    return;
        +
        + err:
        +    tls_openssl_errors(err_pref_1, err_pref_2, err_def, tls_child_apparg);
        + err_return:
        +    return;
        +}
        +
        +
        +static int
        +tls_get_error(SSL *ssl, int r, int *write_select, int *read_select, int *closed, int *progress)
        +{
        +    int err = SSL_get_error(ssl, r);
        +
        +    if (err == SSL_ERROR_NONE) {
        +	assert(r > 0);
        +	*progress = 1;
        +	return 0;
        +    }
        +
        +    assert(r <= 0);
        +
        +    switch (err) {
        +    case SSL_ERROR_ZERO_RETURN:
        +	assert(r == 0);
        +	*closed = 1;
        +	*progress = 1;
        +	return 0;
        +
        +    case SSL_ERROR_WANT_WRITE:
        +	*write_select = 1;
        +	return 0;
        +	
        +    case SSL_ERROR_WANT_READ:
        +	*read_select = 1;
        +	return 0;
        +    }
        +
        +    return -1;
        +}
        +
        +static int
        +tls_connect_attempt(SSL *ssl, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
        +{
        +    int n, r;
        +
        +    DEBUG_MSG("tls_connect_attempt");
        +    n = SSL_connect(ssl);
        +    DEBUG_MSG2("SSL_connect",n);
        +    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
        +    if (r == -1)
        +	*err_pref = " during SSL_connect";
        +    return r;
        +}
        +
        +static int
        +tls_accept_attempt(SSL *ssl, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
        +{
        +    int n, r;
        +
        +    DEBUG_MSG("tls_accept_attempt");
        +    n = SSL_accept(ssl);
        +    DEBUG_MSG2("SSL_accept",n);
        +    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
        +    if (r == -1)
        +	*err_pref = " during SSL_accept";
        +    return r;
        +}
        +
        +static int
        +tls_write_attempt(SSL *ssl, struct tunnelbuf *buf, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
        +{
        +    int n, r;
        +
        +    DEBUG_MSG("tls_write_attempt");
        +    n = SSL_write(ssl, buf->buf + buf->offset, buf->len);
        +    DEBUG_MSG2("SSL_write",n);
        +    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
        +    if (n > 0) {
        +	buf->len -= n;
        +	assert(buf->len >= 0);
        +	if (buf->len == 0)
        +	    buf->offset = 0;
        +	else
        +	    buf->offset += n;
        +    }
        +    if (r == -1)
        +	*err_pref = " during SSL_write";
        +    return r;
        +}
        +
        +static int
        +tls_read_attempt(SSL *ssl, struct tunnelbuf *buf, int *write_select, int *read_select, int *closed, int *progress, const char **err_pref)
        +{
        +    int n, r;
        +    size_t total;
        +
        +    DEBUG_MSG("tls_read_attempt");
        +    total = buf->offset + buf->len;
        +    assert(total < sizeof buf->buf);
        +    n = SSL_read(ssl, buf->buf + total, (sizeof buf->buf) - total);
        +    DEBUG_MSG2("SSL_read",n);
        +    r = tls_get_error(ssl, n, write_select, read_select, closed, progress);
        +    if (n > 0) {
        +	buf->len += n;
        +	assert(buf->offset + buf->len <= sizeof buf->buf);
        +    }
        +    if (r == -1)
        +	*err_pref = " during SSL_read";
        +    return r;
        +}
        +
        +static int
        +get_error(int r, int *select, int *closed, int *progress)
        +{
        +    if (r >= 0) {
        +	*progress = 1;
        +	if (r == 0)
        +	    *closed = 1;
        +	return 0;
        +    } else {
        +	assert(r == -1);
        +	if (errno == EAGAIN || errno == EWOULDBLOCK) {
        +	    *select = 1;
        +	    return 0;
        +	} else if (errno == EPIPE) {
        +	    *progress = 1;
        +	    *closed = 1;
        +	    return 0;
        +	} else
        +	    return -1;
        +    }
        +}
        +
        +static int write_attempt(int fd, struct tunnelbuf *buf, int *select, int *closed, int *progress)
        +{
        +    int n, r;
        +
        +    DEBUG_MSG("write_attempt");
        +    n = write(fd, buf->buf + buf->offset, buf->len);
        +    DEBUG_MSG2("write",n);
        +    r = get_error(n, select, closed, progress);
        +    if (n > 0) {
        +	buf->len -= n;
        +	assert(buf->len >= 0);
        +	if (buf->len == 0)
        +	    buf->offset = 0;
        +	else
        +	    buf->offset += n;
        +    }
        +    if (r == -1)
        +	tls_errprintf(1, tls_child_apparg, "write error: %s\n", strerror(errno));
        +    return r;
        +}
        +    
        +static int
        +read_attempt(int fd, struct tunnelbuf *buf, int *select, int *closed, int *progress)
        +{
        +    int n, r;
        +    size_t total;
        +
        +    DEBUG_MSG("read_attempt");
        +    total = buf->offset + buf->len;
        +    assert(total < sizeof buf->buf);
        +    n = read(fd, buf->buf + total, (sizeof buf->buf) - total);
        +    DEBUG_MSG2("read",n);
        +    r = get_error(n, select, closed, progress);
        +    if (n > 0) {
        +	buf->len += n;
        +	assert(buf->offset + buf->len <= sizeof buf->buf);
        +    }
        +    if (r == -1)
        +	tls_errprintf(1, tls_child_apparg, "read error: %s\n", strerror(errno));
        +    return r;
        +}
        diff --git a/vendor/openssl/openssl/demos/easy_tls/easy-tls.h b/vendor/openssl/openssl/demos/easy_tls/easy-tls.h
        new file mode 100644
        index 000000000..52b298e65
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/easy-tls.h
        @@ -0,0 +1,57 @@
        +/* -*- Mode: C; c-file-style: "bsd" -*- */
        +/*
        + * easy-tls.h -- generic TLS proxy.
        + * $Id: easy-tls.h,v 1.1 2001/09/17 19:06:59 bodo Exp $
        + */
        +/*
        + * (c) Copyright 1999 Bodo Moeller.  All rights reserved.
        + */
        +
        +#ifndef HEADER_TLS_H
        +#define HEADER_TLS_H
        +
        +#ifndef HEADER_SSL_H
        +typedef struct ssl_ctx_st SSL_CTX;
        +#endif
        +
        +#define TLS_INFO_SIZE 512 /* max. # of bytes written to infofd */
        +
        +void tls_set_dhe1024(int i, void* apparg);
        +/* Generate DHE parameters:
        + * i >= 0 deterministic (i selects seed), i < 0 random (may take a while).
        + * tls_create_ctx calls this with random non-negative i if the application
        + * has never called it.*/
        +
        +void tls_rand_seed(void);
        +int tls_rand_seed_from_file(const char *filename, size_t n, void *apparg);
        +void tls_rand_seed_from_memory(const void *buf, size_t n);
        +
        +struct tls_create_ctx_args 
        +{
        +    int client_p;
        +    const char *certificate_file;
        +    const char *key_file;
        +    const char *ca_file;
        +    int verify_depth;
        +    int fail_unless_verified;
        +    int export_p;
        +};
        +struct tls_create_ctx_args tls_create_ctx_defaultargs(void);
        +/* struct tls_create_ctx_args is similar to a conventional argument list,
        + * but it can provide default values and allows for future extension. */
        +SSL_CTX *tls_create_ctx(struct tls_create_ctx_args, void *apparg);
        +
        +struct tls_start_proxy_args
        +{
        +    int fd;
        +    int client_p;
        +    SSL_CTX *ctx;
        +    pid_t *pid;
        +    int *infofd;
        +};
        +struct tls_start_proxy_args tls_start_proxy_defaultargs(void);
        +/* tls_start_proxy return value *MUST* be checked!
        + * 0 means ok, otherwise we've probably run out of some resources. */
        +int tls_start_proxy(struct tls_start_proxy_args, void *apparg);
        +
        +#endif
        diff --git a/vendor/openssl/openssl/demos/easy_tls/test.c b/vendor/openssl/openssl/demos/easy_tls/test.c
        new file mode 100644
        index 000000000..21f679afd
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/test.c
        @@ -0,0 +1,244 @@
        +/* test.c */
        +/* $Id: test.c,v 1.1 2001/09/17 19:06:59 bodo Exp $ */
        +
        +#define L_PORT 9999
        +#define C_PORT 443
        +
        +#include <arpa/inet.h>
        +#include <assert.h>
        +#include <errno.h>
        +#include <fcntl.h>
        +#include <netinet/in.h>
        +#include <netinet/tcp.h>
        +#include <stdlib.h>
        +#include <stdio.h>
        +#include <string.h>
        +#include <sys/select.h>
        +#include <sys/socket.h>
        +#include <unistd.h>
        +
        +#include "test.h"
        +#include "easy-tls.h"
        +
        +void
        +test_process_init(int fd, int client_p, void *apparg)
        +{
        +    fprintf(stderr, "test_process_init(fd = %d, client_p = %d, apparg = %p)\n", fd, client_p, apparg);
        +}
        +
        +void
        +test_errflush(int child_p, char *errbuf, size_t num, void *apparg)
        +{
        +    fputs(errbuf, stderr);
        +}
        +
        +
        +int
        +main(int argc, char *argv[])
        +{
        +    int s, fd, r;
        +    FILE *conn_in;
        +    FILE *conn_out;
        +    char buf[256];
        +    SSL_CTX *ctx;
        +    int client_p = 0;
        +    int port;
        +    int tls = 0;
        +    char infobuf[TLS_INFO_SIZE + 1];
        +
        +    if (argc > 1 && argv[1][0] == '-') {
        +	fputs("Usage: test [port]                   -- server\n"
        +	      "       test num.num.num.num [port]   -- client\n",
        +	      stderr);
        +	exit(1);
        +    }
        +
        +    if (argc > 1) {
        +	if (strchr(argv[1], '.')) {
        +	    client_p = 1;
        +	}
        +    }
        +    
        +    fputs(client_p ? "Client\n" : "Server\n", stderr);
        +    
        +    {
        +	struct tls_create_ctx_args a = tls_create_ctx_defaultargs();
        +	a.client_p = client_p;
        +	a.certificate_file = "cert.pem";
        +	a.key_file = "cert.pem";
        +	a.ca_file = "cacerts.pem";
        +	
        +	ctx = tls_create_ctx(a, NULL);
        +	if (ctx == NULL)
        +	    exit(1);
        +    }
        +    
        +    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        +    if (s == -1) {
        +	perror("socket");
        +	exit(1);
        +    }
        +    
        +    if (client_p) {
        +	struct sockaddr_in addr;
        +	size_t addr_len = sizeof addr;
        +	    
        +	addr.sin_family = AF_INET;
        +	assert(argc > 1);
        +	if (argc > 2)
        +	    sscanf(argv[2], "%d", &port);
        +	else
        +	    port = C_PORT;
        +	addr.sin_port = htons(port);
        +	addr.sin_addr.s_addr = inet_addr(argv[1]);
        +	    
        +	r = connect(s, &addr, addr_len);
        +	if (r != 0) {
        +	    perror("connect");
        +	    exit(1);
        +	}
        +	fd = s;
        +	fprintf(stderr, "Connect (fd = %d).\n", fd);
        +    } else {
        +	/* server */
        +	{
        +	    int i = 1;
        +
        +	    r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *) &i, sizeof i);
        +	    if (r == -1) {
        +		perror("setsockopt");
        +		exit(1);
        +	    }
        +	}
        +	
        +	{
        +	    struct sockaddr_in addr;
        +	    size_t addr_len = sizeof addr;
        +	    
        +	    if (argc > 1)
        +		sscanf(argv[1], "%d", &port);
        +	    else
        +		port = L_PORT;
        +	    addr.sin_family = AF_INET;
        +	    addr.sin_port = htons(port);
        +	    addr.sin_addr.s_addr = INADDR_ANY;
        +	    
        +	    r = bind(s, &addr, addr_len);
        +	    if (r != 0) {
        +		perror("bind");
        +		exit(1);
        +	    }
        +	}
        +    
        +	r = listen(s, 1);
        +	if (r == -1) {
        +	    perror("listen");
        +	    exit(1);
        +	}
        +
        +	fprintf(stderr, "Listening at port %i.\n", port);
        +	
        +	fd = accept(s, NULL, 0);
        +	if (fd == -1) {
        +	    perror("accept");
        +	    exit(1);
        +	}
        +	
        +	fprintf(stderr, "Accept (fd = %d).\n", fd);
        +    }
        +
        +    conn_in = fdopen(fd, "r");
        +    if (conn_in == NULL) {
        +	perror("fdopen");
        +	exit(1);
        +    }
        +    conn_out = fdopen(fd, "w");
        +    if (conn_out == NULL) {
        +	perror("fdopen");
        +	exit(1);
        +    }
        +
        +    setvbuf(conn_in, NULL, _IOLBF, 256);
        +    setvbuf(conn_out, NULL, _IOLBF, 256);
        +	
        +    while (fgets(buf, sizeof buf, stdin) != NULL) {
        +	if (buf[0] == 'W') {
        +	    fprintf(conn_out, "%.*s\r\n", (int)(strlen(buf + 1) - 1), buf + 1);
        +	    fprintf(stderr, ">>> %.*s\n", (int)(strlen(buf + 1) - 1), buf + 1);
        +	} else if (buf[0] == 'C') {
        +	    fprintf(stderr, "Closing.\n");
        +	    fclose(conn_in);
        +	    fclose(conn_out);
        +	    exit(0);
        +	} else if (buf[0] == 'R') {
        +	    int lines = 0;
        +
        +	    sscanf(buf + 1, "%d", &lines);
        +	    do {
        +		if (fgets(buf, sizeof buf, conn_in) == NULL) {
        +		    if (ferror(conn_in)) {
        +			fprintf(stderr, "ERROR\n");
        +			exit(1);
        +		    }
        +		    fprintf(stderr, "CLOSED\n");
        +		    return 0;
        +		}
        +		fprintf(stderr, "<<< %s", buf);
        +	    } while (--lines > 0);
        +	} else if (buf[0] == 'T') {
        +	    int infofd;
        +
        +	    tls++;
        +	    {
        +		struct tls_start_proxy_args a = tls_start_proxy_defaultargs();
        +		a.fd = fd;
        +		a.client_p = client_p;
        +		a.ctx = ctx;
        +		a.infofd = &infofd;
        +		r = tls_start_proxy(a, NULL);
        +	    }
        +	    assert(r != 1);
        +	    if (r != 0) {
        +		fprintf(stderr, "tls_start_proxy failed: %d\n", r);
        +		switch (r) {
        +		case -1:
        +		    fputs("socketpair", stderr); break;
        +		case 2:
        +		    fputs("FD_SETSIZE exceeded", stderr); break;
        +		case -3:
        +		    fputs("pipe", stderr); break;
        +		case -4:
        +		    fputs("fork", stderr); break;
        +		case -5:
        +		    fputs("dup2", stderr); break;
        +		default:
        +		    fputs("?", stderr);
        +		}
        +		if (r < 0)
        +		    perror("");
        +		else
        +		    fputc('\n', stderr);
        +		exit(1);
        +	    }
        +	    
        +	    r = read(infofd, infobuf, sizeof infobuf - 1);
        +	    if (r > 0) {
        +		const char *info = infobuf;
        +		const char *eol;
        +		
        +		infobuf[r] = '\0';
        +		while ((eol = strchr(info, '\n')) != NULL) {
        +		    fprintf(stderr, "+++ `%.*s'\n", eol - info, info);
        +		    info = eol+1;
        +		}
        +		close (infofd);
        +	    }
        +	} else {
        +	    fprintf(stderr, "W...  write line to network\n"
        +		    "R[n]  read line (n lines) from network\n"
        +		    "C     close\n"
        +		    "T     start %sTLS proxy\n", tls ? "another " : "");
        +	}
        +    }
        +    return 0;
        +}
        diff --git a/vendor/openssl/openssl/demos/easy_tls/test.h b/vendor/openssl/openssl/demos/easy_tls/test.h
        new file mode 100644
        index 000000000..dda667843
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/easy_tls/test.h
        @@ -0,0 +1,11 @@
        +/* test.h */
        +/* $Id: test.h,v 1.1 2001/09/17 19:07:00 bodo Exp $ */
        +
        +
        +void test_process_init(int fd, int client_p, void *apparg);
        +#define TLS_APP_PROCESS_INIT test_process_init
        +
        +#undef TLS_CUMULATE_ERRORS
        +
        +void test_errflush(int child_p, char *errbuf, size_t num, void *apparg);
        +#define TLS_APP_ERRFLUSH test_errflush
        diff --git a/vendor/openssl/openssl/demos/eay/Makefile b/vendor/openssl/openssl/demos/eay/Makefile
        new file mode 100644
        index 000000000..2d22eaca5
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/eay/Makefile
        @@ -0,0 +1,24 @@
        +CC=cc
        +CFLAGS= -g -I../../include
        +#LIBS=  -L../.. -lcrypto -lssl
        +LIBS= -L../.. ../../libssl.a ../../libcrypto.a
        +
        +# the file conn.c requires a file "proxy.h" which I couldn't find...
        +#EXAMPLES=base64 conn loadrsa
        +EXAMPLES=base64 loadrsa
        +
        +all: $(EXAMPLES) 
        +
        +base64: base64.o
        +	$(CC) -o base64 base64.o $(LIBS)
        +#
        +# sorry... can't find "proxy.h"
        +#conn: conn.o
        +#	$(CC) -o conn conn.o $(LIBS)
        +
        +loadrsa: loadrsa.o
        +	$(CC) -o loadrsa loadrsa.o $(LIBS)
        +
        +clean:	
        +	rm -f $(EXAMPLES) *.o
        +
        diff --git a/vendor/openssl/openssl/demos/eay/base64.c b/vendor/openssl/openssl/demos/eay/base64.c
        new file mode 100644
        index 000000000..4b8b0627d
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/eay/base64.c
        @@ -0,0 +1,49 @@
        +/* This is a simple example of using the base64 BIO to a memory BIO and then
        + * getting the data.
        + */
        +#include <stdio.h>
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +
        +main()
        +	{
        +	int i;
        +	BIO *mbio,*b64bio,*bio;
        +	char buf[512];
        +	char *p;
        +
        +	mbio=BIO_new(BIO_s_mem());
        +	b64bio=BIO_new(BIO_f_base64());
        +
        +	bio=BIO_push(b64bio,mbio);
        +	/* We now have bio pointing at b64->mem, the base64 bio encodes on
        +	 * write and decodes on read */
        +
        +	for (;;)
        +		{
        +		i=fread(buf,1,512,stdin);
        +		if (i <= 0) break;
        +		BIO_write(bio,buf,i);
        +		}
        +	/* We need to 'flush' things to push out the encoding of the
        +	 * last few bytes.  There is special encoding if it is not a
        +	 * multiple of 3
        +	 */
        +	BIO_flush(bio);
        +
        +	printf("We have %d bytes available\n",BIO_pending(mbio));
        +
        +	/* We will now get a pointer to the data and the number of elements. */
        +	/* hmm... this one was not defined by a macro in bio.h, it will be for
        +	 * 0.9.1.  The other option is too just read from the memory bio.
        +	 */
        +	i=(int)BIO_ctrl(mbio,BIO_CTRL_INFO,0,(char *)&p);
        +
        +	printf("%d\n",i);
        +	fwrite("---\n",1,4,stdout);
        +	fwrite(p,1,i,stdout);
        +	fwrite("---\n",1,4,stdout);
        +
        +	/* This call will walk the chain freeing all the BIOs */
        +	BIO_free_all(bio);
        +	}
        diff --git a/vendor/openssl/openssl/demos/eay/conn.c b/vendor/openssl/openssl/demos/eay/conn.c
        new file mode 100644
        index 000000000..c4b8f5163
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/eay/conn.c
        @@ -0,0 +1,105 @@
        +/* NOCW */
        +/* demos/eay/conn.c */
        +
        +/* A minimal program to connect to a port using the sock4a protocol.
        + *
        + * cc -I../../include conn.c -L../.. -lcrypto
        + */
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/err.h>
        +#include <openssl/bio.h>
        +/* #include "proxy.h" */
        +
        +extern int errno;
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	PROXY *pxy;
        +	char *host;
        +	char buf[1024*10],*p;
        +	BIO *bio;
        +	int i,len,off,ret=1;
        +
        +	if (argc <= 1)
        +		host="localhost:4433";
        +	else
        +		host=argv[1];
        +
        +	/* Lets get nice error messages */
        +	ERR_load_crypto_strings();
        +
        +	/* First, configure proxy settings */
        +	pxy=PROXY_new();
        +	PROXY_add_server(pxy,PROXY_PROTOCOL_SOCKS,"gromit:1080");
        +
        +	bio=BIO_new(BIO_s_socks4a_connect());
        +
        +	BIO_set_conn_hostname(bio,host);
        +	BIO_set_proxies(bio,pxy);
        +	BIO_set_socks_userid(bio,"eay");
        +	BIO_set_nbio(bio,1);
        +
        +	p="GET / HTTP/1.0\r\n\r\n";
        +	len=strlen(p);
        +
        +	off=0;
        +	for (;;)
        +		{
        +		i=BIO_write(bio,&(p[off]),len);
        +		if (i <= 0)
        +			{
        +			if (BIO_should_retry(bio))
        +				{
        +				fprintf(stderr,"write DELAY\n");
        +				sleep(1);
        +				continue;
        +				}
        +			else
        +				{
        +				goto err;
        +				}
        +			}
        +		off+=i;
        +		len-=i;
        +		if (len <= 0) break;
        +		}
        +
        +	for (;;)
        +		{
        +		i=BIO_read(bio,buf,sizeof(buf));
        +		if (i == 0) break;
        +		if (i < 0)
        +			{
        +			if (BIO_should_retry(bio))
        +				{
        +				fprintf(stderr,"read DELAY\n");
        +				sleep(1);
        +				continue;
        +				}
        +			goto err;
        +			}
        +		fwrite(buf,1,i,stdout);
        +		}
        +
        +	ret=1;
        +
        +	if (0)
        +		{
        +err:
        +		if (ERR_peek_error() == 0) /* system call error */
        +			{
        +			fprintf(stderr,"errno=%d ",errno);
        +			perror("error");
        +			}
        +		else
        +			ERR_print_errors_fp(stderr);
        +		}
        +	BIO_free_all(bio);
        +	if (pxy != NULL) PROXY_free(pxy);
        +	exit(!ret);
        +	return(ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/demos/eay/loadrsa.c b/vendor/openssl/openssl/demos/eay/loadrsa.c
        new file mode 100644
        index 000000000..79f1885ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/eay/loadrsa.c
        @@ -0,0 +1,53 @@
        +#include <stdio.h>
        +#include <openssl/rsa.h>
        +
        +/* This is a simple program to generate an RSA private key.  It then
        + * saves both the public and private key into a char array, then
        + * re-reads them.  It saves them as DER encoded binary data.
        + */
        +
        +void callback(stage,count,arg)
        +int stage,count;
        +char *arg;
        +	{
        +	FILE *out;
        +
        +	out=(FILE *)arg;
        +	fprintf(out,"%d",stage);
        +	if (stage == 3)
        +		fprintf(out,"\n");
        +	fflush(out);
        +	}
        +
        +main()
        +	{
        +	RSA *rsa,*pub_rsa,*priv_rsa;
        +	int len;
        +	unsigned char buf[1024],*p;
        +
        +	rsa=RSA_generate_key(512,RSA_F4,callback,(char *)stdout);
        +
        +	p=buf;
        +
        +	/* Save the public key into buffer, we know it will be big enough
        +	 * but we should really check how much space we need by calling the
        +	 * i2d functions with a NULL second parameter */
        +	len=i2d_RSAPublicKey(rsa,&p);
        +	len+=i2d_RSAPrivateKey(rsa,&p);
        +
        +	printf("The public and private key are now both in a char array\n");
        +	printf("and are taking up %d bytes\n",len);
        +
        +	RSA_free(rsa);
        +
        +	p=buf;
        +	pub_rsa=d2i_RSAPublicKey(NULL,&p,(long)len);
        +	len-=(p-buf);
        +	priv_rsa=d2i_RSAPrivateKey(NULL,&p,(long)len);
        +
        +	if ((pub_rsa == NULL) || (priv_rsa == NULL))
        +		ERR_print_errors_fp(stderr);
        +
        +	RSA_free(pub_rsa);
        +	RSA_free(priv_rsa);
        +	}
        diff --git a/vendor/openssl/openssl/demos/engines/cluster_labs/Makefile b/vendor/openssl/openssl/demos/engines/cluster_labs/Makefile
        new file mode 100644
        index 000000000..956193f09
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/cluster_labs/Makefile
        @@ -0,0 +1,114 @@
        +LIBNAME=	libclabs
        +SRC=		hw_cluster_labs.c
        +OBJ=		hw_cluster_labs.o
        +HEADER=		hw_cluster_labs.h
        +
        +CC=		gcc
        +PIC=		-fPIC
        +CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT -DFLAT_INC
        +AR=		ar r
        +RANLIB=		ranlib
        +
        +LIB=		$(LIBNAME).a
        +SHLIB=		$(LIBNAME).so
        +
        +all:
        +		@echo 'Please choose a system to build on:'
        +		@echo ''
        +		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
        +		@echo 'solaris:  Solaris'
        +		@echo 'irix:     IRIX'
        +		@echo 'hpux32:   32-bit HP/UX'
        +		@echo 'hpux64:   64-bit HP/UX'
        +		@echo 'aix:      AIX'
        +		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
        +		@echo ''
        +
        +FORCE.update:
        +update:		FORCE.update
        +		perl ../../../util/mkerr.pl -conf hw_cluster_labs.ec \
        +			-nostatic -staticloader -write hw_cluster_labs.c
        +
        +gnu:		$(SHLIB).gnu
        +tru64:		$(SHLIB).tru64
        +solaris:	$(SHLIB).solaris
        +irix:		$(SHLIB).irix
        +hpux32:		$(SHLIB).hpux32
        +hpux64:		$(SHLIB).hpux64
        +aix:		$(SHLIB).aix
        +
        +$(LIB):		$(OBJ)
        +		$(AR) $(LIB) $(OBJ)
        +		- $(RANLIB) $(LIB)
        +
        +LINK_SO=	\
        +  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) && \
        +  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
        +   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
        +
        +$(SHLIB).gnu:	$(LIB)
        +		ALLSYMSFLAGS='--whole-archive' \
        +		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).gnu
        +$(SHLIB).tru64:	$(LIB)
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).tru64
        +$(SHLIB).solaris:	$(LIB)
        +		ALLSYMSFLAGS='-z allextract' \
        +		SHAREDFLAGS='-G -h $(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).solaris
        +$(SHLIB).irix:	$(LIB)
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).irix
        +$(SHLIB).hpux32:	$(LIB)
        +		ALLSYMSFLAGS='-Fl' \
        +		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux32
        +$(SHLIB).hpux64:	$(LIB)
        +		ALLSYMSFLAGS='+forceload' \
        +		SHAREDFLAGS='-b -z +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux64
        +$(SHLIB).aix:	$(LIB)
        +		ALLSYMSFLAGS='-bnogc' \
        +		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).aix
        +
        +depend:
        +		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
        +		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
        +		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
        +		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
        +		rm -f Makefile.tmp Makefile
        +		mv Makefile.new Makefile
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
        +rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
        +rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
        +rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
        +rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
        +rsaref.o: ../../../include/openssl/opensslconf.h
        +rsaref.o: ../../../include/openssl/opensslv.h
        +rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
        +rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
        +rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
        +rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
        +rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
        +rsaref.o: source/rsaref.h
        diff --git a/vendor/openssl/openssl/demos/engines/cluster_labs/cluster_labs.h b/vendor/openssl/openssl/demos/engines/cluster_labs/cluster_labs.h
        new file mode 100644
        index 000000000..d0926796f
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/cluster_labs/cluster_labs.h
        @@ -0,0 +1,35 @@
        +typedef int cl_engine_init(void);
        +typedef int cl_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			const BIGNUM *m, BN_CTX *cgx);
        +typedef int cl_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);
        +typedef int cl_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
        +typedef int cl_rsa_pub_enc(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding);
        +typedef int cl_rsa_pub_dec(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding);
        +typedef int cl_rsa_priv_enc(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa, int padding);
        +typedef int cl_rsa_priv_dec(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa, int padding);		
        +typedef int cl_rand_bytes(unsigned char *buf, int num);
        +typedef DSA_SIG *cl_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        +typedef int cl_dsa_verify(const unsigned char *dgst, int dgst_len,
        +				DSA_SIG *sig, DSA *dsa);
        +
        +
        +static const char *CLUSTER_LABS_LIB_NAME = "cluster_labs";
        +static const char *CLUSTER_LABS_F1	 = "hw_engine_init";
        +static const char *CLUSTER_LABS_F2	 = "hw_mod_exp";
        +static const char *CLUSTER_LABS_F3	 = "hw_mod_exp_crt";
        +static const char *CLUSTER_LABS_F4	 = "hw_rsa_mod_exp";
        +static const char *CLUSTER_LABS_F5	 = "hw_rsa_priv_enc";
        +static const char *CLUSTER_LABS_F6	 = "hw_rsa_priv_dec";
        +static const char *CLUSTER_LABS_F7	 = "hw_rsa_pub_enc";
        +static const char *CLUSTER_LABS_F8	 = "hw_rsa_pub_dec";
        +static const char *CLUSTER_LABS_F20	 = "hw_rand_bytes";
        +static const char *CLUSTER_LABS_F30	 = "hw_dsa_sign";
        +static const char *CLUSTER_LABS_F31	 = "hw_dsa_verify";
        +
        +
        diff --git a/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs.c b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs.c
        new file mode 100644
        index 000000000..036f48baf
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs.c
        @@ -0,0 +1,721 @@
        +/* crypto/engine/hw_cluster_labs.c */
        +/* Written by Jan Tschirschwitz (jan.tschirschwitz@cluster-labs.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).
        + *
        + */
        +
        +#define MSC_VER   /* only used cryptic.h */
        +
        +#include <stdio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/dso.h>
        +#include <openssl/des.h>
        +#include <openssl/engine.h>
        +
        +#ifndef NO_HW
        +#ifndef NO_HW_CLUSTER_LABS
        +
        +#ifdef FLAT_INC
        +#include "cluster_labs.h"
        +#else
        +#include "vendor_defns/cluster_labs.h"
        +#endif
        +
        +#define CL_LIB_NAME "cluster_labs engine"
        +#include "hw_cluster_labs_err.c"
        +
        +
        +static int cluster_labs_destroy(ENGINE *e);
        +static int cluster_labs_init(ENGINE *e);
        +static int cluster_labs_finish(ENGINE *e);
        +static int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
        +
        +
        +/* BIGNUM stuff */
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +		
        +/* RSA stuff */
        +#ifndef OPENSSL_NO_RSA
        +static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding);
        +static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding);
        +static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa, int padding);
        +static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa, int padding);
        +static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
        +#endif
        +
        +/* DSA stuff */
        +#ifndef OPENSSL_NO_DSA
        +static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        +static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
        +				DSA_SIG *sig, DSA *dsa);
        +static int cluster_labs_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 cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx);
        +#endif
        +								
        +/* DH stuff */
        +#ifndef OPENSSL_NO_DH
        +/* This function is alised to mod_exp (with the DH and mont dropped). */
        +static int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +		
        +/* RANDOM stuff */						
        +static int cluster_labs_rand_bytes(unsigned char *buf, int num);
        +
        +/* The definitions for control commands specific to this engine */
        +#define CLUSTER_LABS_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN cluster_labs_cmd_defns[] =
        +	{
        +	{ CLUSTER_LABS_CMD_SO_PATH,
        +	  "SO_PATH",
        +	  "Specifies the path to the 'cluster labs' shared library",
        +	  ENGINE_CMD_FLAG_STRING
        +	},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +/* Our internal RSA_METHOD that we provide pointers to */
        +#ifndef OPENSSL_NO_RSA
        +static RSA_METHOD cluster_labs_rsa =
        +	{
        +	"Cluster Labs RSA method",
        +	cluster_labs_rsa_pub_enc,	/* rsa_pub_enc */
        +	cluster_labs_rsa_pub_dec,	/* rsa_pub_dec */
        +	cluster_labs_rsa_priv_enc,	/* rsa_priv_enc */
        +	cluster_labs_rsa_priv_dec,	/* rsa_priv_dec */
        +	cluster_labs_rsa_mod_exp,	/* rsa_mod_exp */
        +	cluster_labs_mod_exp_mont,	/* bn_mod_exp */
        +	NULL,				/* init */
        +	NULL,				/* finish */
        +	0, 				/* flags */
        +	NULL,				/* apps_data */
        +	NULL,				/* rsa_sign */
        +	NULL				/* rsa_verify */
        +	};
        +#endif
        +
        +/* Our internal DSA_METHOD that we provide pointers to */
        +#ifndef OPENSSL_NO_DSA
        +static DSA_METHOD cluster_labs_dsa =
        +	{
        +	"Cluster Labs DSA method",
        +	cluster_labs_dsa_sign,  	/* dsa_do_sign */
        +	NULL, 				/* dsa_sign_setup */
        +	cluster_labs_dsa_verify,	/* dsa_do_verify */
        +	cluster_labs_dsa_mod_exp, 	/* dsa_mod_exp */
        +	cluster_labs_mod_exp_dsa, 	/* bn_mod_exp */
        +	NULL, 				/* init */
        +	NULL, 				/* finish */
        +	0, 				/* flags */
        +	NULL 				/* app_data */
        +	};
        +#endif	
        +
        +/* Our internal DH_METHOD that we provide pointers to */
        +#ifndef OPENSSL_NO_DH
        +static DH_METHOD cluster_labs_dh =
        +	{
        +	"Cluster Labs DH method",
        +	NULL,				/* generate key */
        +	NULL,				/* compute key */
        +	cluster_labs_mod_exp_dh,	/* bn_mod_exp */
        +	NULL,				/* init */
        +	NULL,				/* finish */
        +	0,				/* flags */
        +	NULL				/* app_data */
        +	};
        +#endif	
        +	
        +static RAND_METHOD cluster_labs_rand =
        +	{
        +	/* "Cluster Labs RAND method", */
        +	NULL,				/* seed */
        +	cluster_labs_rand_bytes,	/* bytes */
        +	NULL,				/* cleanup */
        +	NULL,				/* add */
        +	cluster_labs_rand_bytes,	/* pseudorand */
        +	NULL,				/* status */
        +	};	
        +
        +static const char *engine_cluster_labs_id = "cluster_labs";
        +static const char *engine_cluster_labs_name = "Cluster Labs hardware engine support";
        +
        +/* engine implementation */
        +/*-----------------------*/
        +static int bind_helper(ENGINE *e)
        +	{
        +	
        +	if(!ENGINE_set_id(e, engine_cluster_labs_id) ||
        +			!ENGINE_set_name(e, engine_cluster_labs_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &cluster_labs_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			!ENGINE_set_DSA(e, &cluster_labs_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH(e, &cluster_labs_dh) ||
        +#endif
        +			!ENGINE_set_RAND(e, &cluster_labs_rand) ||
        +			!ENGINE_set_destroy_function(e, cluster_labs_destroy) ||
        +			!ENGINE_set_init_function(e, cluster_labs_init) ||
        +			!ENGINE_set_finish_function(e, cluster_labs_finish) ||
        +			!ENGINE_set_ctrl_function(e, cluster_labs_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, cluster_labs_cmd_defns))
        +		return 0;
        +	/* Ensure the error handling is set up */
        +	ERR_load_CL_strings();
        +	return 1;
        +	}
        +	
        +#ifndef ENGINE_DYNAMIC_SUPPORT
        +static ENGINE *engine_cluster_labs(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static
        +#endif
        +void ENGINE_load_cluster_labs(void)
        +	{
        +
        +	ENGINE *cluster_labs = engine_cluster_labs();
        +	
        +	if(!cluster_labs) return;
        +	ENGINE_add(cluster_labs);
        +	ENGINE_free(cluster_labs);
        +	ERR_clear_error();
        +	}
        +#endif /* !ENGINE_DYNAMIC_SUPPORT */
        +
        +static int cluster_labs_destroy(ENGINE *e)
        +	{
        +	
        +	ERR_unload_CL_strings();
        +	return 1;
        +	}
        +
        +
        +
        +/* This is a process-global DSO handle used for loading and unloading
        + * the Cluster Labs 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 *cluster_labs_dso = NULL;
        +
        +/* These are the function pointers that are (un)set when the library has
        + * successfully (un)loaded. */
        +static cl_engine_init	  	*p_cl_engine_init 		 = NULL;
        +static cl_mod_exp	 	*p_cl_mod_exp 			 = NULL;
        +static cl_mod_exp_crt		*p_cl_mod_exp_crt 		 = NULL;
        +static cl_rsa_mod_exp		*p_cl_rsa_mod_exp 		 = NULL;
        +static cl_rsa_priv_enc		*p_cl_rsa_priv_enc 		 = NULL;
        +static cl_rsa_priv_dec		*p_cl_rsa_priv_dec 		 = NULL;
        +static cl_rsa_pub_enc		*p_cl_rsa_pub_enc 		 = NULL;
        +static cl_rsa_pub_dec		*p_cl_rsa_pub_dec 		 = NULL;
        +static cl_rand_bytes		*p_cl_rand_bytes	 	 = NULL;
        +static cl_dsa_sign		*p_cl_dsa_sign		 	 = NULL;
        +static cl_dsa_verify		*p_cl_dsa_verify	 	 = NULL;
        +
        +
        +int cluster_labs_init(ENGINE *e)
        +	{
        +
        +	cl_engine_init			*p1;
        +	cl_mod_exp			*p2;
        +	cl_mod_exp_crt			*p3;
        +	cl_rsa_mod_exp			*p4;
        +	cl_rsa_priv_enc			*p5;
        +	cl_rsa_priv_dec			*p6;	
        +	cl_rsa_pub_enc			*p7;
        +	cl_rsa_pub_dec			*p8;
        +	cl_rand_bytes			*p20;
        +	cl_dsa_sign			*p30;	
        +	cl_dsa_verify			*p31;		
        +	
        +	/* engine already loaded */
        +	if(cluster_labs_dso != NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_ALREADY_LOADED);
        +		goto err;
        +		}
        +	/* try to load engine	 */	
        +	cluster_labs_dso = DSO_load(NULL, CLUSTER_LABS_LIB_NAME, NULL,0);
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_DSO_FAILURE);
        +		goto err;
        +		}
        +	/* bind functions */
        +	if(	!(p1 = (cl_engine_init *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F1)) ||
        +		!(p2 = (cl_mod_exp *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F2)) ||			
        +		!(p3 = (cl_mod_exp_crt *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F3)) ||				
        +		!(p4 = (cl_rsa_mod_exp *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F4)) ||				
        +		!(p5 = (cl_rsa_priv_enc *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F5)) ||
        +		!(p6 = (cl_rsa_priv_dec *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F6)) ||
        +		!(p7 = (cl_rsa_pub_enc *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F7)) ||
        +		!(p8 = (cl_rsa_pub_dec *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F8)) ||
        +		!(p20= (cl_rand_bytes *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F20)) ||
        +		!(p30= (cl_dsa_sign *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F30)) ||
        +		!(p31= (cl_dsa_verify *)DSO_bind_func(
        +				cluster_labs_dso, CLUSTER_LABS_F31)))
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_DSO_FAILURE);
        +		goto err;
        +		}
        +		
        +	/* copy function pointers */
        +	p_cl_engine_init		= p1;
        +	p_cl_mod_exp			= p2;
        +	p_cl_mod_exp_crt		= p3;	
        +	p_cl_rsa_mod_exp 		= p4;
        +	p_cl_rsa_priv_enc	 	= p5;
        +	p_cl_rsa_priv_dec	 	= p6;
        +	p_cl_rsa_pub_enc	 	= p7;
        +	p_cl_rsa_pub_dec	 	= p8;
        +	p_cl_rand_bytes			= p20;	
        +	p_cl_dsa_sign			= p30;
        +	p_cl_dsa_verify			= p31;	
        +	
        +	
        +	
        +	/* cluster labs engine init */
        +	if(p_cl_engine_init()== 0){
        +		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_INIT_FAILED);		
        +		goto err;
        +	}
        +
        +	return(1);
        +
        +err:	
        +	/* reset all pointers */
        +	if(cluster_labs_dso)
        +		DSO_free(cluster_labs_dso);
        +
        +	cluster_labs_dso		= NULL;
        +	p_cl_engine_init		= NULL;	
        +	p_cl_mod_exp			= NULL;
        +	p_cl_mod_exp_crt		= NULL;
        +	p_cl_rsa_mod_exp		= NULL;
        +	p_cl_rsa_priv_enc		= NULL;
        +	p_cl_rsa_priv_dec		= NULL;	
        +	p_cl_rsa_pub_enc		= NULL;
        +	p_cl_rsa_pub_dec		= NULL;	
        +	p_cl_rand_bytes			= NULL;	
        +	p_cl_dsa_sign			= NULL;
        +	p_cl_dsa_verify			= NULL;	
        +	
        +	return(0);
        +	}
        +	
        +
        +static int cluster_labs_finish(ENGINE *e)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_FINISH,CL_R_NOT_LOADED);
        +		return 0;
        +		}
        +	if(!DSO_free(cluster_labs_dso))
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_FINISH,CL_R_DSO_FAILURE);
        +		return 0;
        +		}
        +		
        +	cluster_labs_dso 		= NULL;
        +	p_cl_engine_init		= NULL;		
        +	p_cl_mod_exp			= NULL;
        +	p_cl_rsa_mod_exp		= NULL;	
        +	p_cl_mod_exp_crt		= NULL;	
        +	p_cl_rsa_priv_enc		= NULL;	
        +	p_cl_rsa_priv_dec		= NULL;	
        +	p_cl_rsa_pub_enc		= NULL;
        +	p_cl_rsa_pub_dec		= NULL;	
        +	p_cl_rand_bytes			= NULL;		
        +	p_cl_dsa_sign			= NULL;
        +	p_cl_dsa_verify			= NULL;	
        +	
        +	return(1);	
        +	
        +	}
        +	
        +static int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
        +	{
        +	int initialised = ((cluster_labs_dso == NULL) ? 0 : 1);
        +
        +	switch(cmd)
        +		{
        +	case CLUSTER_LABS_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			CLerr(CL_F_CLUSTER_LABS_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			CLerr(CL_F_CLUSTER_LABS_CTRL,CL_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		CLUSTER_LABS_LIB_NAME = (const char *)p;
        +		return 1;
        +	default:
        +		break;
        +		}
        +	CLerr(CL_F_CLUSTER_LABS_CTRL,CL_R_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +	
        +
        +static int cluster_labs_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_MOD_EXP,CL_R_NOT_LOADED);
        +		return 0;
        +		}	
        +	if(p_cl_mod_exp == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_MOD_EXP,CL_R_FUNCTION_NOT_BINDED);
        +		return 0;
        +		}
        +
        +	return	p_cl_mod_exp(r, a, p, m, ctx);
        +
        +	}
        +	
        +static int cluster_labs_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)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_mod_exp_crt == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT,CL_R_FUNCTION_NOT_BINDED);		
        +		return 0;
        +		}
        +	
        +	return	p_cl_mod_exp_crt(r, a, p, q,dmp1, dmq1, iqmp, ctx);
        +	
        +	}
        +	
        +static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_rsa_mod_exp == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +
        +	return p_cl_rsa_mod_exp(r0, I, rsa);
        +
        +	}
        +	
        +static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_DSA_SIGN,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_dsa_sign == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_DSA_SIGN,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +
        +	return p_cl_dsa_sign(dgst, dlen, dsa);
        +	
        +	}
        +	
        +static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
        +				DSA_SIG *sig, DSA *dsa)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	
        +	if(p_cl_dsa_verify == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +
        +	return p_cl_dsa_verify(dgst, dgst_len, sig, dsa);
        +	
        +	}			
        +
        +static int cluster_labs_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 status = 0;
        +		
        +	BN_init(&t);
        +	/* let rr = a1 ^ p1 mod m */
        +	if (!cluster_labs_mod_exp(rr,a1,p1,m,ctx)) goto end;
        +	/* let t = a2 ^ p2 mod m */
        +	if (!cluster_labs_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;
        +	status = 1;
        +end:
        +	BN_free(&t);
        +	
        +	return(1);
        +
        +	}
        +
        +static int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx)
        +	{
        +	return 	cluster_labs_mod_exp(r, a, p, m, ctx);
        +	}
        +	
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	return	cluster_labs_mod_exp(r, a, p, m, ctx);
        +	}
        +	
        +
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	return 	cluster_labs_mod_exp(r, a, p, m, ctx);
        +	}
        +
        +
        +static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_rsa_priv_enc == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +		
        +	return 	p_cl_rsa_pub_enc(flen, from, to, rsa, padding);
        +	
        +	}  
        +	     
        +static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
        +	     unsigned char *to, RSA *rsa, int padding)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_rsa_priv_enc == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +		
        +	return 	p_cl_rsa_pub_dec(flen, from, to, rsa, padding);
        +	
        +	}  
        +
        +
        +static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa, int padding)
        +	{
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +
        +	if(p_cl_rsa_priv_enc == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +		
        +	return 	p_cl_rsa_priv_enc(flen, from, to, rsa, padding);
        +	
        +	}  
        +
        +static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from, 
        +		unsigned char *to, RSA *rsa, int padding)
        +	{
        +	
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_rsa_priv_dec == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +
        +	return 	p_cl_rsa_priv_dec(flen, from, to, rsa, padding);
        +		
        +	}  
        +
        +/************************************************************************************
        +* Symmetric algorithms
        +************************************************************************************/
        +/* this will be come soon! */
        +
        +/************************************************************************************
        +* Random generator
        +************************************************************************************/
        +
        +static int cluster_labs_rand_bytes(unsigned char *buf, int num){
        +
        +	if(cluster_labs_dso == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RAND_BYTES,CL_R_NOT_LOADED);		
        +		return 0;
        +		}
        +	if(p_cl_mod_exp_crt == NULL)
        +		{
        +		CLerr(CL_F_CLUSTER_LABS_RAND_BYTES,CL_R_FUNCTION_NOT_BINDED);				
        +		return 0;
        +		}
        +
        +	return 	p_cl_rand_bytes(buf, num);
        +
        +}
        +
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	fprintf(stderr, "bind_fn CLUSTER_LABS\n");
        +	if(id && (strcmp(id, engine_cluster_labs_id) != 0)) {
        +		fprintf(stderr, "bind_fn return(0) first\n");
        +		return 0;
        +		}
        +	if(!bind_helper(e)) {
        +		fprintf(stderr, "bind_fn return(1) first\n");
        +		return 0;
        +		}
        +	fprintf(stderr, "bind_fn return(1)\n");		
        +	return 1;
        +	}
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* ENGINE_DYNAMIC_SUPPORT */
        +						
        +#endif /* !NO_HW_CLUSTER_LABS */
        +#endif /* !NO_HW */
        +
        diff --git a/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs.ec b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs.ec
        new file mode 100644
        index 000000000..1f6478654
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs.ec
        @@ -0,0 +1,8 @@
        +# configuration file for util/mkerr.pl
        +#
        +# use like this:
        +#
        +#	perl ../../../util/mkerr.pl -conf hw_cluster_labs.ec \
        +#		-nostatic -staticloader -write *.c
        +
        +L CL		hw_cluster_labs_err.h		hw_cluster_labs_err.c
        diff --git a/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.c b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.c
        new file mode 100644
        index 000000000..a7fa4083b
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.c
        @@ -0,0 +1,151 @@
        +/* hw_cluster_labs_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <openssl/err.h>
        +#include "hw_cluster_labs_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +static ERR_STRING_DATA CL_str_functs[]=
        +	{
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_CTRL,0),	"CLUSTER_LABS_CTRL"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_DSA_SIGN,0),	"CLUSTER_LABS_DSA_SIGN"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_DSA_VERIFY,0),	"CLUSTER_LABS_DSA_VERIFY"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_FINISH,0),	"CLUSTER_LABS_FINISH"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_INIT,0),	"CLUSTER_LABS_INIT"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_MOD_EXP,0),	"CLUSTER_LABS_MOD_EXP"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_MOD_EXP_CRT,0),	"CLUSTER_LABS_MOD_EXP_CRT"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_RAND_BYTES,0),	"CLUSTER_LABS_RAND_BYTES"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_MOD_EXP,0),	"CLUSTER_LABS_RSA_MOD_EXP"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PRIV_DEC,0),	"CLUSTER_LABS_RSA_PRIV_DEC"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PRIV_ENC,0),	"CLUSTER_LABS_RSA_PRIV_ENC"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PUB_DEC,0),	"CLUSTER_LABS_RSA_PUB_DEC"},
        +{ERR_PACK(0,CL_F_CLUSTER_LABS_RSA_PUB_ENC,0),	"CLUSTER_LABS_RSA_PUB_ENC"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CL_str_reasons[]=
        +	{
        +{CL_R_ALREADY_LOADED                     ,"already loaded"},
        +{CL_R_COMMAND_NOT_IMPLEMENTED            ,"command not implemented"},
        +{CL_R_DSO_FAILURE                        ,"dso failure"},
        +{CL_R_FUNCTION_NOT_BINDED                ,"function not binded"},
        +{CL_R_INIT_FAILED                        ,"init failed"},
        +{CL_R_NOT_LOADED                         ,"not loaded"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef CL_LIB_NAME
        +static ERR_STRING_DATA CL_lib_name[]=
        +        {
        +{0	,CL_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int CL_lib_error_code=0;
        +static int CL_error_init=1;
        +
        +static void ERR_load_CL_strings(void)
        +	{
        +	if (CL_lib_error_code == 0)
        +		CL_lib_error_code=ERR_get_next_error_library();
        +
        +	if (CL_error_init)
        +		{
        +		CL_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(CL_lib_error_code,CL_str_functs);
        +		ERR_load_strings(CL_lib_error_code,CL_str_reasons);
        +#endif
        +
        +#ifdef CL_LIB_NAME
        +		CL_lib_name->error = ERR_PACK(CL_lib_error_code,0,0);
        +		ERR_load_strings(0,CL_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_CL_strings(void)
        +	{
        +	if (CL_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(CL_lib_error_code,CL_str_functs);
        +		ERR_unload_strings(CL_lib_error_code,CL_str_reasons);
        +#endif
        +
        +#ifdef CL_LIB_NAME
        +		ERR_unload_strings(0,CL_lib_name);
        +#endif
        +		CL_error_init=1;
        +		}
        +	}
        +
        +static void ERR_CL_error(int function, int reason, char *file, int line)
        +	{
        +	if (CL_lib_error_code == 0)
        +		CL_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(CL_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.h b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.h
        new file mode 100644
        index 000000000..f548a3b66
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/cluster_labs/hw_cluster_labs_err.h
        @@ -0,0 +1,99 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * 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_CL_ERR_H
        +#define HEADER_CL_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_CL_strings(void);
        +static void ERR_unload_CL_strings(void);
        +static void ERR_CL_error(int function, int reason, char *file, int line);
        +#define CLerr(f,r) ERR_CL_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the CL functions. */
        +
        +/* Function codes. */
        +#define CL_F_CLUSTER_LABS_CTRL				 100
        +#define CL_F_CLUSTER_LABS_DSA_SIGN			 101
        +#define CL_F_CLUSTER_LABS_DSA_VERIFY			 102
        +#define CL_F_CLUSTER_LABS_FINISH			 103
        +#define CL_F_CLUSTER_LABS_INIT				 104
        +#define CL_F_CLUSTER_LABS_MOD_EXP			 105
        +#define CL_F_CLUSTER_LABS_MOD_EXP_CRT			 106
        +#define CL_F_CLUSTER_LABS_RAND_BYTES			 107
        +#define CL_F_CLUSTER_LABS_RSA_MOD_EXP			 108
        +#define CL_F_CLUSTER_LABS_RSA_PRIV_DEC			 109
        +#define CL_F_CLUSTER_LABS_RSA_PRIV_ENC			 110
        +#define CL_F_CLUSTER_LABS_RSA_PUB_DEC			 111
        +#define CL_F_CLUSTER_LABS_RSA_PUB_ENC			 112
        +
        +/* Reason codes. */
        +#define CL_R_ALREADY_LOADED				 100
        +#define CL_R_COMMAND_NOT_IMPLEMENTED			 101
        +#define CL_R_DSO_FAILURE				 102
        +#define CL_R_FUNCTION_NOT_BINDED			 103
        +#define CL_R_INIT_FAILED				 104
        +#define CL_R_NOT_LOADED					 105
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/demos/engines/ibmca/Makefile b/vendor/openssl/openssl/demos/engines/ibmca/Makefile
        new file mode 100644
        index 000000000..72f354635
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/ibmca/Makefile
        @@ -0,0 +1,114 @@
        +LIBNAME=	libibmca
        +SRC=		hw_ibmca.c
        +OBJ=		hw_ibmca.o
        +HEADER=		hw_ibmca.h
        +
        +CC=		gcc
        +PIC=		-fPIC
        +CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT -DFLAT_INC
        +AR=		ar r
        +RANLIB=		ranlib
        +
        +LIB=		$(LIBNAME).a
        +SHLIB=		$(LIBNAME).so
        +
        +all:
        +		@echo 'Please choose a system to build on:'
        +		@echo ''
        +		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
        +		@echo 'solaris:  Solaris'
        +		@echo 'irix:     IRIX'
        +		@echo 'hpux32:   32-bit HP/UX'
        +		@echo 'hpux64:   64-bit HP/UX'
        +		@echo 'aix:      AIX'
        +		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
        +		@echo ''
        +
        +FORCE.update:
        +update:		FORCE.update
        +		perl ../../../util/mkerr.pl -conf hw_ibmca.ec \
        +			-nostatic -staticloader -write hw_ibmca.c
        +
        +gnu:		$(SHLIB).gnu
        +tru64:		$(SHLIB).tru64
        +solaris:	$(SHLIB).solaris
        +irix:		$(SHLIB).irix
        +hpux32:		$(SHLIB).hpux32
        +hpux64:		$(SHLIB).hpux64
        +aix:		$(SHLIB).aix
        +
        +$(LIB):		$(OBJ)
        +		$(AR) $(LIB) $(OBJ)
        +		- $(RANLIB) $(LIB)
        +
        +LINK_SO=	\
        +  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) && \
        +  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
        +   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
        +
        +$(SHLIB).gnu:	$(LIB)
        +		ALLSYMSFLAGS='--whole-archive' \
        +		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).gnu
        +$(SHLIB).tru64:	$(LIB)
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).tru64
        +$(SHLIB).solaris:	$(LIB)
        +		ALLSYMSFLAGS='-z allextract' \
        +		SHAREDFLAGS='-G -h $(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).solaris
        +$(SHLIB).irix:	$(LIB)
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).irix
        +$(SHLIB).hpux32:	$(LIB)
        +		ALLSYMSFLAGS='-Fl' \
        +		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux32
        +$(SHLIB).hpux64:	$(LIB)
        +		ALLSYMSFLAGS='+forceload' \
        +		SHAREDFLAGS='-b -z +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux64
        +$(SHLIB).aix:	$(LIB)
        +		ALLSYMSFLAGS='-bnogc' \
        +		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).aix
        +
        +depend:
        +		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
        +		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
        +		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
        +		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
        +		rm -f Makefile.tmp Makefile
        +		mv Makefile.new Makefile
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
        +rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
        +rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
        +rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
        +rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
        +rsaref.o: ../../../include/openssl/opensslconf.h
        +rsaref.o: ../../../include/openssl/opensslv.h
        +rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
        +rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
        +rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
        +rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
        +rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
        +rsaref.o: source/rsaref.h
        diff --git a/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca.c b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca.c
        new file mode 100644
        index 000000000..d42cdba44
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca.c
        @@ -0,0 +1,920 @@
        +/* crypto/engine/hw_ibmca.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).
        + *
        + */
        +
        +/* (C) COPYRIGHT International Business Machines Corp. 2001 */
        +
        +#include <stdio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_IBMCA
        +
        +#ifdef FLAT_INC
        +#include "ica_openssl_api.h"
        +#else
        +#include "vendor_defns/ica_openssl_api.h"
        +#endif
        +
        +#define IBMCA_LIB_NAME "ibmca engine"
        +#include "hw_ibmca_err.c"
        +
        +static int ibmca_destroy(ENGINE *e);
        +static int ibmca_init(ENGINE *e);
        +static int ibmca_finish(ENGINE *e);
        +static int ibmca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
        +
        +static const char *IBMCA_F1 = "icaOpenAdapter";
        +static const char *IBMCA_F2 = "icaCloseAdapter";
        +static const char *IBMCA_F3 = "icaRsaModExpo";
        +static const char *IBMCA_F4 = "icaRandomNumberGenerate";
        +static const char *IBMCA_F5 = "icaRsaCrt";
        +
        +ICA_ADAPTER_HANDLE handle=0;
        +
        +/* BIGNUM stuff */
        +static int ibmca_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +        const BIGNUM *m, BN_CTX *ctx);
        +
        +static int ibmca_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +        const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
        +        const BIGNUM *iqmp, BN_CTX *ctx);
        +
        +#ifndef OPENSSL_NO_RSA  
        +/* RSA stuff */
        +static int ibmca_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
        +#endif
        +
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int ibmca_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +
        +#ifndef OPENSSL_NO_DSA 
        +/* DSA stuff */
        +static int ibmca_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 ibmca_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +        const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +        BN_MONT_CTX *m_ctx);
        +#endif
        +
        +#ifndef OPENSSL_NO_DH 
        +/* DH stuff */
        +/* This function is alised to mod_exp (with the DH and mont dropped). */
        +static int ibmca_mod_exp_dh(const DH *dh, BIGNUM *r, 
        +	const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* RAND stuff */
        +static int ibmca_rand_bytes(unsigned char *buf, int num);
        +static int ibmca_rand_status(void);
        +
        +
        +/* WJH - check for more commands, like in nuron */
        +
        +/* The definitions for control commands specific to this engine */
        +#define IBMCA_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN ibmca_cmd_defns[] = {
        +	{IBMCA_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'atasi' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA  
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD ibmca_rsa =
        +        {
        +        "Ibmca RSA method",
        +        NULL,
        +        NULL,
        +        NULL,
        +        NULL,
        +        ibmca_rsa_mod_exp,
        +        ibmca_mod_exp_mont,
        +        NULL,
        +        NULL,
        +        0,
        +        NULL,
        +        NULL,
        +        NULL
        +        };
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* Our internal DSA_METHOD that we provide pointers to */
        +static DSA_METHOD ibmca_dsa =
        +        {
        +        "Ibmca DSA method",
        +        NULL, /* dsa_do_sign */
        +        NULL, /* dsa_sign_setup */
        +        NULL, /* dsa_do_verify */
        +        ibmca_dsa_mod_exp, /* dsa_mod_exp */
        +        ibmca_mod_exp_dsa, /* bn_mod_exp */
        +        NULL, /* init */
        +        NULL, /* finish */
        +        0, /* flags */
        +        NULL /* app_data */
        +        };
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* Our internal DH_METHOD that we provide pointers to */
        +static DH_METHOD ibmca_dh =
        +        {
        +        "Ibmca DH method",
        +        NULL,
        +        NULL,
        +        ibmca_mod_exp_dh,
        +        NULL,
        +        NULL,
        +        0,
        +        NULL
        +        };
        +#endif
        +
        +static RAND_METHOD ibmca_rand =
        +        {
        +        /* "IBMCA RAND method", */
        +        NULL,
        +        ibmca_rand_bytes,
        +        NULL,
        +        NULL,
        +        ibmca_rand_bytes,
        +        ibmca_rand_status,
        +        };
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_ibmca_id = "ibmca";
        +static const char *engine_ibmca_name = "Ibmca hardware engine support";
        +
        +/* This internal function is used by ENGINE_ibmca() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	const DSA_METHOD *meth2;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth3;
        +#endif
        +	if(!ENGINE_set_id(e, engine_ibmca_id) ||
        +		!ENGINE_set_name(e, engine_ibmca_name) ||
        +#ifndef OPENSSL_NO_RSA
        +		!ENGINE_set_RSA(e, &ibmca_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +		!ENGINE_set_DSA(e, &ibmca_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		!ENGINE_set_DH(e, &ibmca_dh) ||
        +#endif
        +		!ENGINE_set_RAND(e, &ibmca_rand) ||
        +		!ENGINE_set_destroy_function(e, ibmca_destroy) ||
        +		!ENGINE_set_init_function(e, ibmca_init) ||
        +		!ENGINE_set_finish_function(e, ibmca_finish) ||
        +		!ENGINE_set_ctrl_function(e, ibmca_ctrl) ||
        +		!ENGINE_set_cmd_defns(e, ibmca_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* We know that the "PKCS1_SSLeay()" functions hook properly
        +	 * to the ibmca-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();
        +	ibmca_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
        +	ibmca_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
        +	ibmca_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
        +	ibmca_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
        +	 * bits. */
        +	meth2 = DSA_OpenSSL();
        +	ibmca_dsa.dsa_do_sign = meth2->dsa_do_sign;
        +	ibmca_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
        +	ibmca_dsa.dsa_do_verify = meth2->dsa_do_verify;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth3 = DH_OpenSSL();
        +	ibmca_dh.generate_key = meth3->generate_key;
        +	ibmca_dh.compute_key = meth3->compute_key;
        +#endif
        +
        +	/* Ensure the ibmca error handling is set up */
        +	ERR_load_IBMCA_strings(); 
        +	return 1;
        +	}
        +
        +static ENGINE *engine_ibmca(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static
        +#endif
        +void ENGINE_load_ibmca(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_ibmca();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +
        +/* Destructor (complements the "ENGINE_ibmca()" constructor) */
        +static int ibmca_destroy(ENGINE *e)
        +	{
        +	/* Unload the ibmca error strings so any error state including our
        +	 * functs or reasons won't lead to a segfault (they simply get displayed
        +	 * without corresponding string data because none will be found). */
        +        ERR_unload_IBMCA_strings(); 
        +	return 1;
        +	}
        +
        +
        +/* This is a process-global DSO handle used for loading and unloading
        + * the Ibmca 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 *ibmca_dso = NULL;
        +
        +/* These are the function pointers that are (un)set when the library has
        + * successfully (un)loaded. */
        +
        +static unsigned int    (ICA_CALL *p_icaOpenAdapter)();
        +static unsigned int    (ICA_CALL *p_icaCloseAdapter)();
        +static unsigned int    (ICA_CALL *p_icaRsaModExpo)();
        +static unsigned int    (ICA_CALL *p_icaRandomNumberGenerate)();
        +static unsigned int    (ICA_CALL *p_icaRsaCrt)();
        +
        +/* utility function to obtain a context */
        +static int get_context(ICA_ADAPTER_HANDLE *p_handle)
        +        {
        +        unsigned int status=0;
        +
        +        status = p_icaOpenAdapter(0, p_handle);
        +        if(status != 0)
        +                return 0;
        +        return 1;
        +        }
        +
        +/* similarly to release one. */
        +static void release_context(ICA_ADAPTER_HANDLE handle)
        +        {
        +        p_icaCloseAdapter(handle);
        +        }
        +
        +/* (de)initialisation functions. */
        +static int ibmca_init(ENGINE *e)
        +        {
        +
        +        void          (*p1)();
        +        void          (*p2)();
        +        void          (*p3)();
        +        void          (*p4)();
        +        void          (*p5)();
        +
        +        if(ibmca_dso != NULL)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_ALREADY_LOADED);
        +                goto err;
        +                }
        +        /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
        +         * changed unfortunately because the Ibmca drivers don't have
        +         * standard library names that can be platform-translated well. */
        +        /* TODO: Work out how to actually map to the names the Ibmca
        +         * 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. */
        +
        +	/* WJH XXX check name translation */
        +
        +        ibmca_dso = DSO_load(NULL, IBMCA_LIBNAME, NULL,
        +			     /* DSO_FLAG_NAME_TRANSLATION */ 0);
        +        if(ibmca_dso == NULL)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_DSO_FAILURE);
        +                goto err;
        +                }
        +
        +        if(!(p1 = DSO_bind_func(
        +                ibmca_dso, IBMCA_F1)) ||
        +                !(p2 = DSO_bind_func(
        +                        ibmca_dso, IBMCA_F2)) ||
        +                !(p3 = DSO_bind_func(
        +                        ibmca_dso, IBMCA_F3)) ||
        +                !(p4 = DSO_bind_func(
        +                        ibmca_dso, IBMCA_F4)) ||
        +                !(p5 = DSO_bind_func(
        +                        ibmca_dso, IBMCA_F5)))
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_DSO_FAILURE);
        +                goto err;
        +                }
        +
        +        /* Copy the pointers */
        +
        +	p_icaOpenAdapter =           (unsigned int (ICA_CALL *)())p1;
        +	p_icaCloseAdapter =          (unsigned int (ICA_CALL *)())p2;
        +	p_icaRsaModExpo =            (unsigned int (ICA_CALL *)())p3;
        +	p_icaRandomNumberGenerate =  (unsigned int (ICA_CALL *)())p4;
        +	p_icaRsaCrt =                (unsigned int (ICA_CALL *)())p5;
        +
        +        if(!get_context(&handle))
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_UNIT_FAILURE);
        +                goto err;
        +                }
        +
        +        return 1;
        + err:
        +        if(ibmca_dso)
        +                DSO_free(ibmca_dso);
        +
        +        p_icaOpenAdapter = NULL;
        +        p_icaCloseAdapter = NULL;
        +        p_icaRsaModExpo = NULL;
        +        p_icaRandomNumberGenerate = NULL;
        +
        +        return 0;
        +        }
        +
        +static int ibmca_finish(ENGINE *e)
        +        {
        +        if(ibmca_dso == NULL)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_FINISH,IBMCA_R_NOT_LOADED);
        +                return 0;
        +                }
        +        release_context(handle);
        +        if(!DSO_free(ibmca_dso))
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_FINISH,IBMCA_R_DSO_FAILURE);
        +                return 0;
        +                }
        +        ibmca_dso = NULL;
        +
        +        return 1;
        +        }
        +
        +static int ibmca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
        +	{
        +	int initialised = ((ibmca_dso == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case IBMCA_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			IBMCAerr(IBMCA_F_IBMCA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			IBMCAerr(IBMCA_F_IBMCA_CTRL,IBMCA_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		IBMCA_LIBNAME = (const char *)p;
        +		return 1;
        +	default:
        +		break;
        +		}
        +	IBMCAerr(IBMCA_F_IBMCA_CTRL,IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +
        +static int ibmca_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +        const BIGNUM *m, BN_CTX *ctx)
        +        {
        +        /* I need somewhere to store temporary serialised values for
        +         * use with the Ibmca API calls. A neat cheat - I'll use
        +         * BIGNUMs from the BN_CTX but access their arrays directly as
        +         * byte arrays <grin>. This way I don't have to clean anything
        +         * up. */
        +
        +        BIGNUM *argument=NULL;
        +        BIGNUM *result=NULL;
        +        BIGNUM *key=NULL;
        +        int to_return;
        +	int inLen, outLen, tmpLen;
        +
        +
        +        ICA_KEY_RSA_MODEXPO *publKey=NULL;
        +        unsigned int rc;
        +
        +        to_return = 0; /* expect failure */
        +
        +        if(!ibmca_dso)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_NOT_LOADED);
        +                goto err;
        +                }
        +        /* Prepare the params */
        +	BN_CTX_start(ctx);
        +        argument = BN_CTX_get(ctx);
        +        result = BN_CTX_get(ctx);
        +        key = BN_CTX_get(ctx);
        +
        +        if( !argument || !result || !key)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_BN_CTX_FULL);
        +                goto err;
        +                }
        +
        +
        +	if(!bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top) ||
        +                !bn_wexpand(key, sizeof(*publKey)/BN_BYTES))
        +
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_BN_EXPAND_FAIL);
        +                goto err;
        +                }
        +
        +        publKey = (ICA_KEY_RSA_MODEXPO *)key->d;
        +
        +        if (publKey == NULL)
        +                {
        +                goto err;
        +                }
        +        memset(publKey, 0, sizeof(ICA_KEY_RSA_MODEXPO));
        +
        +        publKey->keyType   =  CORRECT_ENDIANNESS(ME_KEY_TYPE);
        +        publKey->keyLength =  CORRECT_ENDIANNESS(sizeof(ICA_KEY_RSA_MODEXPO));
        +        publKey->expOffset =  (char *) publKey->keyRecord - (char *) publKey;
        +
        +        /* A quirk of the card: the exponent length has to be the same
        +     as the modulus (key) length */
        +
        +	outLen = BN_num_bytes(m);
        +
        +/* check for modulus length SAB*/
        +	if (outLen > 256 ) {
        +		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_MEXP_LENGTH_TO_LARGE);
        +		goto err;
        +	}
        +/* check for modulus length SAB*/
        +
        +
        +	publKey->expLength = publKey->nLength = outLen;
        +/* SAB Check for underflow condition
        +    the size of the exponent is less than the size of the parameter
        +    then we have a big problem and will underflow the keyRecord
        +   buffer.  Bad stuff could happen then
        +*/
        +if (outLen < BN_num_bytes(p)){
        +	IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_UNDERFLOW_KEYRECORD);
        +	goto err;
        +}
        +/* SAB End check for underflow */
        +
        +
        +        BN_bn2bin(p, &publKey->keyRecord[publKey->expLength -
        +                BN_num_bytes(p)]);
        +        BN_bn2bin(m, &publKey->keyRecord[publKey->expLength]);
        +
        +
        +
        +        publKey->modulusBitLength = CORRECT_ENDIANNESS(publKey->nLength * 8);
        +        publKey->nOffset   = CORRECT_ENDIANNESS(publKey->expOffset + 
        +						publKey->expLength);
        +
        +        publKey->expOffset = CORRECT_ENDIANNESS((char *) publKey->keyRecord - 
        +						(char *) publKey);
        +
        +	tmpLen = outLen;
        +	publKey->expLength = publKey->nLength = CORRECT_ENDIANNESS(tmpLen);
        +
        +  /* Prepare the argument */
        +
        +	memset(argument->d, 0, outLen);
        +	BN_bn2bin(a, (unsigned char *)argument->d + outLen -
        +                 BN_num_bytes(a));
        +
        +	inLen = outLen;
        +
        +  /* Perform the operation */
        +
        +          if( (rc = p_icaRsaModExpo(handle, inLen,(unsigned char *)argument->d,
        +                publKey, &outLen, (unsigned char *)result->d))
        +                !=0 )
        +
        +                {
        +                printf("rc = %d\n", rc);
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_REQUEST_FAILED);
        +                goto err;
        +                }
        +
        +
        +        /* Convert the response */
        +        BN_bin2bn((unsigned char *)result->d, outLen, r);
        +        to_return = 1;
        + err:
        +	BN_CTX_end(ctx);
        +        return to_return;
        +        }
        +
        +#ifndef OPENSSL_NO_RSA 
        +static int ibmca_rsa_mod_exp(BIGNUM *r0, const 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)
        +                {
        +                if(!rsa->d || !rsa->n)
        +                        {
        +                        IBMCAerr(IBMCA_F_IBMCA_RSA_MOD_EXP,
        +                                IBMCA_R_MISSING_KEY_COMPONENTS);
        +                        goto err;
        +                        }
        +                to_return = ibmca_mod_exp(r0, I, rsa->d, rsa->n, ctx);
        +                }
        +        else
        +                {
        +                to_return = ibmca_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;
        +        }
        +#endif
        +
        +/* Ein kleines chinesisches "Restessen"  */
        +static int ibmca_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +        const BIGNUM *q, const BIGNUM *dmp1,
        +        const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
        +        {
        +
        +        BIGNUM *argument = NULL;
        +        BIGNUM *result = NULL;
        +        BIGNUM *key = NULL;
        +
        +        int to_return = 0; /* expect failure */
        +
        +        char                *pkey=NULL;
        +        ICA_KEY_RSA_CRT     *privKey=NULL;
        +        int inLen, outLen;
        +
        +        int rc;
        +        unsigned int        offset, pSize, qSize;
        +/* SAB New variables */
        +	unsigned int keyRecordSize;
        +	unsigned int pbytes = BN_num_bytes(p);
        +	unsigned int qbytes = BN_num_bytes(q);
        +	unsigned int dmp1bytes = BN_num_bytes(dmp1);
        +	unsigned int dmq1bytes = BN_num_bytes(dmq1);
        +	unsigned int iqmpbytes = BN_num_bytes(iqmp);
        +
        +        /* Prepare the params */
        +
        +	BN_CTX_start(ctx);
        +        argument = BN_CTX_get(ctx);
        +        result = BN_CTX_get(ctx);
        +        key = BN_CTX_get(ctx);
        +
        +        if(!argument || !result || !key)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_BN_CTX_FULL);
        +                goto err;
        +                }
        +
        +	if(!bn_wexpand(argument, p->top + q->top) ||
        +                !bn_wexpand(result, p->top + q->top) ||
        +                !bn_wexpand(key, sizeof(*privKey)/BN_BYTES ))
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_BN_EXPAND_FAIL);
        +                goto err;
        +                }
        +
        +
        +        privKey = (ICA_KEY_RSA_CRT *)key->d;
        +/* SAB Add check for total size in bytes of the parms does not exceed
        +   the buffer space we have
        +   do this first
        +*/
        +      keyRecordSize = pbytes+qbytes+dmp1bytes+dmq1bytes+iqmpbytes;
        +     if (  keyRecordSize > sizeof(privKey->keyRecord )) {
        +	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);
        +         goto err;
        +     }
        +
        +     if ( (qbytes + dmq1bytes)  > 256 ){
        +	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);
        +         goto err;
        +     }
        +
        +     if ( pbytes + dmp1bytes > 256 ) {
        +	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);
        +         goto err;
        +     }
        +
        +/* end SAB additions */
        +  
        +        memset(privKey, 0, sizeof(ICA_KEY_RSA_CRT));
        +        privKey->keyType =  CORRECT_ENDIANNESS(CRT_KEY_TYPE);
        +        privKey->keyLength = CORRECT_ENDIANNESS(sizeof(ICA_KEY_RSA_CRT));
        +        privKey->modulusBitLength = 
        +	  CORRECT_ENDIANNESS(BN_num_bytes(q) * 2 * 8);
        +
        +        /*
        +         * p,dp & qInv are 1 QWORD Larger
        +         */
        +        privKey->pLength = CORRECT_ENDIANNESS(BN_num_bytes(p)+8);
        +        privKey->qLength = CORRECT_ENDIANNESS(BN_num_bytes(q));
        +        privKey->dpLength = CORRECT_ENDIANNESS(BN_num_bytes(dmp1)+8);
        +        privKey->dqLength = CORRECT_ENDIANNESS(BN_num_bytes(dmq1));
        +        privKey->qInvLength = CORRECT_ENDIANNESS(BN_num_bytes(iqmp)+8);
        +
        +        offset = (char *) privKey->keyRecord
        +                  - (char *) privKey;
        +
        +        qSize = BN_num_bytes(q);
        +        pSize = qSize + 8;   /*  1 QWORD larger */
        +
        +
        +/* SAB  probably aittle redundant, but we'll verify that each of the
        +   components which make up a key record sent ot the card does not exceed
        +   the space that is allocated for it.  this handles the case where even if
        +   the total length does not exceed keyrecord zied, if the operands are funny sized
        +they could cause potential side affects on either the card or the result */
        +
        +     if ( (pbytes > pSize) || (dmp1bytes > pSize) ||
        +          (iqmpbytes > pSize) || ( qbytes >qSize) ||
        +          (dmq1bytes > qSize) ) {
        +		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT, IBMCA_R_OPERANDS_TO_LARGE);
        +		goto err;
        +
        +	}
        +     
        +
        +        privKey->dpOffset = CORRECT_ENDIANNESS(offset);
        +
        +	offset += pSize;
        +	privKey->dqOffset = CORRECT_ENDIANNESS(offset);
        +
        +	offset += qSize;
        +	privKey->pOffset = CORRECT_ENDIANNESS(offset);
        +
        +	offset += pSize;
        +	privKey->qOffset = CORRECT_ENDIANNESS(offset);
        +
        +	offset += qSize;
        +	privKey->qInvOffset = CORRECT_ENDIANNESS(offset);
        +
        +        pkey = (char *) privKey->keyRecord;
        +
        +
        +/* SAB first check that we don;t under flow the buffer */
        +	if ( pSize < pbytes ) {
        +		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT, IBMCA_R_UNDERFLOW_CONDITION);
        +		goto err;
        +	}
        +
        +        /* pkey += pSize - BN_num_bytes(p); WROING this should be dmp1) */
        +        pkey += pSize - BN_num_bytes(dmp1);
        +        BN_bn2bin(dmp1, pkey);   
        +        pkey += BN_num_bytes(dmp1);  /* move the pointer */
        +
        +        BN_bn2bin(dmq1, pkey);  /* Copy over dmq1 */
        +
        +        pkey += qSize;     /* move pointer */
        +	pkey += pSize - BN_num_bytes(p);  /* set up for zero padding of next field */
        +
        +        BN_bn2bin(p, pkey);
        +        pkey += BN_num_bytes(p);  /* increment pointer by number of bytes moved  */
        +
        +        BN_bn2bin(q, pkey);
        +        pkey += qSize ;  /* move the pointer */
        +	pkey +=  pSize - BN_num_bytes(iqmp); /* Adjust for padding */
        +        BN_bn2bin(iqmp, pkey);
        +
        +        /* Prepare the argument and response */
        +
        +	outLen = CORRECT_ENDIANNESS(privKey->qLength) * 2;  /* Correct endianess is used 
        +						because the fields were converted above */
        +
        +        if (outLen > 256) {
        +		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OUTLEN_TO_LARGE);
        +		goto err;
        +	}
        +
        +	/* SAB check for underflow here on the argeument */
        +	if ( outLen < BN_num_bytes(a)) {
        +		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_UNDERFLOW_CONDITION);
        +		goto err;
        +	}
        +
        +        BN_bn2bin(a, (unsigned char *)argument->d + outLen -
        +                          BN_num_bytes(a));
        +        inLen = outLen;
        +
        +        memset(result->d, 0, outLen);
        +
        +        /* Perform the operation */
        +
        +        if ( (rc = p_icaRsaCrt(handle, inLen, (unsigned char *)argument->d,
        +                privKey, &outLen, (unsigned char *)result->d)) != 0)
        +                {
        +                printf("rc = %d\n", rc);
        +                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_REQUEST_FAILED);
        +                goto err;
        +                }
        +
        +        /* Convert the response */
        +
        +        BN_bin2bn((unsigned char *)result->d, outLen, r);
        +        to_return = 1;
        +
        + err:
        +	BN_CTX_end(ctx);
        +        return to_return;
        +
        +        }
        +
        +#ifndef OPENSSL_NO_DSA
        +/* This code was liberated and adapted from the commented-out code in
        + * dsa_ossl.c. Because of the unoptimised form of the Ibmca acceleration
        + * (it doesn't have a CRT form for RSA), this function means that an
        + * Ibmca 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 ibmca dsa1024 rsa1024". */
        +static int ibmca_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 (!ibmca_mod_exp(rr,a1,p1,m,ctx)) goto end;
        +        /* let t = a2 ^ p2 mod m */
        +        if (!ibmca_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 ibmca_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +        const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +        BN_MONT_CTX *m_ctx)
        +        {
        +        return ibmca_mod_exp(r, a, p, m, ctx);
        +        }
        +#endif
        +
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int ibmca_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +        {
        +        return ibmca_mod_exp(r, a, p, m, ctx);
        +        }
        +
        +#ifndef OPENSSL_NO_DH 
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int ibmca_mod_exp_dh(DH const *dh, BIGNUM *r, 
        +	const BIGNUM *a, const BIGNUM *p, 
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +        {
        +        return ibmca_mod_exp(r, a, p, m, ctx);
        +        }
        +#endif
        +
        +/* Random bytes are good */
        +static int ibmca_rand_bytes(unsigned char *buf, int num)
        +        {
        +        int to_return = 0; /* assume failure */
        +        unsigned int ret;
        +
        +
        +        if(handle == 0)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_RAND_BYTES,IBMCA_R_NOT_INITIALISED);
        +                goto err;
        +                }
        +
        +        ret = p_icaRandomNumberGenerate(handle, num, buf);
        +        if (ret < 0)
        +                {
        +                IBMCAerr(IBMCA_F_IBMCA_RAND_BYTES,IBMCA_R_REQUEST_FAILED);
        +                goto err;
        +                }
        +        to_return = 1;
        + err:
        +        return to_return;
        +        }
        +
        +static int ibmca_rand_status(void)
        +        {
        +        return 1;
        +        }
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_ibmca_id) != 0))  /* WJH XXX */
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* ENGINE_DYNAMIC_SUPPORT */
        +
        +
        +#endif /* !OPENSSL_NO_HW_IBMCA */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca.ec b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca.ec
        new file mode 100644
        index 000000000..f68646d23
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca.ec
        @@ -0,0 +1,8 @@
        +# configuration file for util/mkerr.pl
        +#
        +# use like this:
        +#
        +#	perl ../../../util/mkerr.pl -conf hw_ibmca.ec \
        +#		-nostatic -staticloader -write *.c
        +
        +L IBMCA		hw_ibmca_err.h			hw_ibmca_err.c
        diff --git a/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca_err.c b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca_err.c
        new file mode 100644
        index 000000000..c4053f6d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca_err.c
        @@ -0,0 +1,154 @@
        +/* hw_ibmca_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <openssl/err.h>
        +#include "hw_ibmca_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +static ERR_STRING_DATA IBMCA_str_functs[]=
        +	{
        +{ERR_PACK(0,IBMCA_F_IBMCA_CTRL,0),	"IBMCA_CTRL"},
        +{ERR_PACK(0,IBMCA_F_IBMCA_FINISH,0),	"IBMCA_FINISH"},
        +{ERR_PACK(0,IBMCA_F_IBMCA_INIT,0),	"IBMCA_INIT"},
        +{ERR_PACK(0,IBMCA_F_IBMCA_MOD_EXP,0),	"IBMCA_MOD_EXP"},
        +{ERR_PACK(0,IBMCA_F_IBMCA_MOD_EXP_CRT,0),	"IBMCA_MOD_EXP_CRT"},
        +{ERR_PACK(0,IBMCA_F_IBMCA_RAND_BYTES,0),	"IBMCA_RAND_BYTES"},
        +{ERR_PACK(0,IBMCA_F_IBMCA_RSA_MOD_EXP,0),	"IBMCA_RSA_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA IBMCA_str_reasons[]=
        +	{
        +{IBMCA_R_ALREADY_LOADED                  ,"already loaded"},
        +{IBMCA_R_BN_CTX_FULL                     ,"bn ctx full"},
        +{IBMCA_R_BN_EXPAND_FAIL                  ,"bn expand fail"},
        +{IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED    ,"ctrl command not implemented"},
        +{IBMCA_R_DSO_FAILURE                     ,"dso failure"},
        +{IBMCA_R_MEXP_LENGTH_TO_LARGE            ,"mexp length to large"},
        +{IBMCA_R_MISSING_KEY_COMPONENTS          ,"missing key components"},
        +{IBMCA_R_NOT_INITIALISED                 ,"not initialised"},
        +{IBMCA_R_NOT_LOADED                      ,"not loaded"},
        +{IBMCA_R_OPERANDS_TO_LARGE               ,"operands to large"},
        +{IBMCA_R_OUTLEN_TO_LARGE                 ,"outlen to large"},
        +{IBMCA_R_REQUEST_FAILED                  ,"request failed"},
        +{IBMCA_R_UNDERFLOW_CONDITION             ,"underflow condition"},
        +{IBMCA_R_UNDERFLOW_KEYRECORD             ,"underflow keyrecord"},
        +{IBMCA_R_UNIT_FAILURE                    ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef IBMCA_LIB_NAME
        +static ERR_STRING_DATA IBMCA_lib_name[]=
        +        {
        +{0	,IBMCA_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int IBMCA_lib_error_code=0;
        +static int IBMCA_error_init=1;
        +
        +static void ERR_load_IBMCA_strings(void)
        +	{
        +	if (IBMCA_lib_error_code == 0)
        +		IBMCA_lib_error_code=ERR_get_next_error_library();
        +
        +	if (IBMCA_error_init)
        +		{
        +		IBMCA_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(IBMCA_lib_error_code,IBMCA_str_functs);
        +		ERR_load_strings(IBMCA_lib_error_code,IBMCA_str_reasons);
        +#endif
        +
        +#ifdef IBMCA_LIB_NAME
        +		IBMCA_lib_name->error = ERR_PACK(IBMCA_lib_error_code,0,0);
        +		ERR_load_strings(0,IBMCA_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_IBMCA_strings(void)
        +	{
        +	if (IBMCA_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(IBMCA_lib_error_code,IBMCA_str_functs);
        +		ERR_unload_strings(IBMCA_lib_error_code,IBMCA_str_reasons);
        +#endif
        +
        +#ifdef IBMCA_LIB_NAME
        +		ERR_unload_strings(0,IBMCA_lib_name);
        +#endif
        +		IBMCA_error_init=1;
        +		}
        +	}
        +
        +static void ERR_IBMCA_error(int function, int reason, char *file, int line)
        +	{
        +	if (IBMCA_lib_error_code == 0)
        +		IBMCA_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(IBMCA_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca_err.h b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca_err.h
        new file mode 100644
        index 000000000..2070f9579
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/ibmca/hw_ibmca_err.h
        @@ -0,0 +1,102 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * 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_IBMCA_ERR_H
        +#define HEADER_IBMCA_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_IBMCA_strings(void);
        +static void ERR_unload_IBMCA_strings(void);
        +static void ERR_IBMCA_error(int function, int reason, char *file, int line);
        +#define IBMCAerr(f,r) ERR_IBMCA_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the IBMCA functions. */
        +
        +/* Function codes. */
        +#define IBMCA_F_IBMCA_CTRL				 100
        +#define IBMCA_F_IBMCA_FINISH				 101
        +#define IBMCA_F_IBMCA_INIT				 102
        +#define IBMCA_F_IBMCA_MOD_EXP				 103
        +#define IBMCA_F_IBMCA_MOD_EXP_CRT			 104
        +#define IBMCA_F_IBMCA_RAND_BYTES			 105
        +#define IBMCA_F_IBMCA_RSA_MOD_EXP			 106
        +
        +/* Reason codes. */
        +#define IBMCA_R_ALREADY_LOADED				 100
        +#define IBMCA_R_BN_CTX_FULL				 101
        +#define IBMCA_R_BN_EXPAND_FAIL				 102
        +#define IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
        +#define IBMCA_R_DSO_FAILURE				 104
        +#define IBMCA_R_MEXP_LENGTH_TO_LARGE			 105
        +#define IBMCA_R_MISSING_KEY_COMPONENTS			 106
        +#define IBMCA_R_NOT_INITIALISED				 107
        +#define IBMCA_R_NOT_LOADED				 108
        +#define IBMCA_R_OPERANDS_TO_LARGE			 109
        +#define IBMCA_R_OUTLEN_TO_LARGE				 110
        +#define IBMCA_R_REQUEST_FAILED				 111
        +#define IBMCA_R_UNDERFLOW_CONDITION			 112
        +#define IBMCA_R_UNDERFLOW_KEYRECORD			 113
        +#define IBMCA_R_UNIT_FAILURE				 114
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/demos/engines/ibmca/ica_openssl_api.h b/vendor/openssl/openssl/demos/engines/ibmca/ica_openssl_api.h
        new file mode 100644
        index 000000000..c77e0fd5c
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/ibmca/ica_openssl_api.h
        @@ -0,0 +1,189 @@
        +
        +#ifndef __ICA_OPENSSL_API_H__
        +#define __ICA_OPENSSL_API_H__
        +
        +/**
        + ** abstract data types for API
        + **/
        +
        +#define ICA_ADAPTER_HANDLE int
        +
        +#if defined(linux) || defined (_AIX)
        +#define ICA_CALL 
        +#endif
        +
        +#if defined(WIN32) || defined(_WIN32)
        +#define ICA_CALL  __stdcall
        +#endif
        +
        +/*------------------------------------------------*
        + | RSA defines and typedefs                       |
        + *------------------------------------------------*/
        + /*
        + * All data elements of the RSA key are in big-endian format
        + * Modulus-Exponent form of key
        + *
        + */
        + #define MAX_EXP_SIZE 256
        + #define MAX_MODULUS_SIZE 256
        + #define MAX_MODEXP_SIZE  (MAX_EXP_SIZE + MAX_MODULUS_SIZE)
        +
        + #define MAX_OPERAND_SIZE  MAX_EXP_SIZE
        +
        + typedef unsigned char ICA_KEY_RSA_MODEXPO_REC[MAX_MODEXP_SIZE];
        + /*
        + * All data elements of the RSA key are in big-endian format
        + * Chinese Remainder Thereom(CRT) form of key
        + * Used only for Decrypt, the encrypt form is typically Modulus-Exponent
        + *
        + */
        + #define MAX_BP_SIZE 136
        + #define MAX_BQ_SIZE 128
        + #define MAX_NP_SIZE 136
        + #define MAX_NQ_SIZE 128
        + #define MAX_QINV_SIZE 136
        + #define MAX_RSACRT_SIZE (MAX_BP_SIZE+MAX_BQ_SIZE+MAX_NP_SIZE+MAX_NQ_SIZE+MAX_QINV_SIZE)
        +
        +#define RSA_GEN_OPERAND_MAX   256 /* bytes */
        +
        +typedef unsigned char ICA_KEY_RSA_CRT_REC[MAX_RSACRT_SIZE];
        +/*------------------------------------------------*
        + | RSA key token types                            |
        + *------------------------------------------------*/
        +
        +#define  RSA_PUBLIC_MODULUS_EXPONENT        3
        +#define  RSA_PKCS_PRIVATE_CHINESE_REMAINDER 6
        +
        +#define KEYTYPE_MODEXPO         1
        +#define KEYTYPE_PKCSCRT         2
        +
        +
        +/*------------------------------------------------*
        + | RSA Key Token format                           |
        + *------------------------------------------------*/
        +
        +/*
        + * NOTE:  All the fields in the ICA_KEY_RSA_MODEXPO structure
        + *        (lengths, offsets, exponents, modulus, etc.) are
        + *        stored in big-endian format
        + */
        +
        +typedef struct _ICA_KEY_RSA_MODEXPO
        +{   unsigned int  keyType;             /* RSA key type.               */
        +    unsigned int  keyLength;           /* Total length of the token.  */
        +    unsigned int  modulusBitLength;    /* Modulus n bit length.       */
        +                                       /* -- Start of the data length.*/
        +    unsigned int  nLength;             /* Modulus n = p * q           */
        +    unsigned int  expLength;           /* exponent (public or private)*/
        +                                       /*   e = 1/d * mod(p-1)(q-1)   */
        +                                       /* -- Start of the data offsets*/
        +    unsigned int  nOffset;             /* Modulus n .                 */
        +    unsigned int  expOffset;           /* exponent (public or private)*/
        +    unsigned char reserved[112];       /* reserved area               */
        +                                       /* -- Start of the variable -- */
        +                                       /* -- length token data.    -- */
        +    ICA_KEY_RSA_MODEXPO_REC keyRecord;
        +} ICA_KEY_RSA_MODEXPO;
        +#define SZ_HEADER_MODEXPO (sizeof(ICA_KEY_RSA_MODEXPO) - sizeof(ICA_KEY_RSA_MODEXPO_REC))
        +
        +/*
        + * NOTE:  All the fields in the ICA_KEY_RSA_CRT structure
        + *        (lengths, offsets, exponents, modulus, etc.) are
        + *        stored in big-endian format
        + */
        +
        +typedef struct _ICA_KEY_RSA_CRT
        +{   unsigned int  keyType;             /* RSA key type.               */
        +    unsigned int  keyLength;           /* Total length of the token.  */
        +    unsigned int  modulusBitLength;    /* Modulus n bit length.       */
        +                                       /* -- Start of the data length.*/
        +#if _AIX
        +    unsigned int  nLength;             /* Modulus n = p * q           */
        +#endif
        +    unsigned int  pLength;             /* Prime number p .            */
        +    unsigned int  qLength;             /* Prime number q .            */
        +    unsigned int  dpLength;            /* dp = d * mod(p-1) .         */
        +    unsigned int  dqLength;            /* dq = d * mod(q-1) .         */
        +    unsigned int  qInvLength;          /* PKCS: qInv = Ap/q           */
        +                                       /* -- Start of the data offsets*/
        +#if _AIX
        +    unsigned int  nOffset;             /* Modulus n .                 */
        +#endif
        +    unsigned int  pOffset;             /* Prime number p .            */
        +    unsigned int  qOffset;             /* Prime number q .            */
        +    unsigned int  dpOffset;            /* dp .                        */
        +    unsigned int  dqOffset;            /* dq .                        */
        +    unsigned int  qInvOffset;          /* qInv for PKCS               */
        +#if _AIX
        +    unsigned char reserved[80];        /* reserved area               */
        +#else
        +    unsigned char reserved[88];        /* reserved area               */
        +#endif
        +                                       /* -- Start of the variable -- */
        +                                       /* -- length token data.    -- */
        +    ICA_KEY_RSA_CRT_REC keyRecord;
        +} ICA_KEY_RSA_CRT;
        +#define SZ_HEADER_CRT (sizeof(ICA_KEY_RSA_CRT) - sizeof(ICA_KEY_RSA_CRT_REC))
        +
        +unsigned int
        +icaOpenAdapter( unsigned int        adapterId,
        +	        ICA_ADAPTER_HANDLE *pAdapterHandle );
        +
        +unsigned int
        +icaCloseAdapter( ICA_ADAPTER_HANDLE adapterHandle );
        +
        +unsigned int
        +icaRsaModExpo( ICA_ADAPTER_HANDLE    hAdapterHandle,
        +	       unsigned int          inputDataLength,
        +	       unsigned char        *pInputData,
        +	       ICA_KEY_RSA_MODEXPO  *pKeyModExpo,
        +	       unsigned int         *pOutputDataLength,
        +	       unsigned char        *pOutputData );
        +
        +unsigned int
        +icaRsaCrt( ICA_ADAPTER_HANDLE     hAdapterHandle,
        +	   unsigned int           inputDataLength,
        +	   unsigned char         *pInputData,
        +	   ICA_KEY_RSA_CRT       *pKeyCrt,
        +	   unsigned int          *pOutputDataLength,
        +	   unsigned char         *pOutputData );
        +
        +unsigned int
        +icaRandomNumberGenerate( ICA_ADAPTER_HANDLE  hAdapterHandle,
        +			 unsigned int        outputDataLength,
        +			 unsigned char      *pOutputData );
        +
        +/* Specific macros and definitions to not have IFDEF;s all over the
        +   main code */
        +
        +#if (_AIX)
        +static const char *IBMCA_LIBNAME = "/lib/libica.a(shr.o)";
        +#elif (WIN32)
        +static const char *IBMCA_LIBNAME = "cryptica";
        +#else
        +static const char *IBMCA_LIBNAME = "ica";
        +#endif
        +
        +#if (WIN32)
        +/*
        + The ICA_KEY_RSA_MODEXPO & ICA_KEY_RSA_CRT lengths and
        + offsets must be in big-endian format.
        +
        +*/
        +#define CORRECT_ENDIANNESS(b) (  \
        +                             (((unsigned long) (b) & 0x000000ff) << 24) |  \
        +                             (((unsigned long) (b) & 0x0000ff00) <<  8) |  \
        +                             (((unsigned long) (b) & 0x00ff0000) >>  8) |  \
        +                             (((unsigned long) (b) & 0xff000000) >> 24)    \
        +                             )
        +#define CRT_KEY_TYPE   RSA_PKCS_PRIVATE_CHINESE_REMAINDER
        +#define ME_KEY_TYPE    RSA_PUBLIC_MODULUS_EXPONENT
        +#else
        +#define CORRECT_ENDIANNESS(b) (b)
        +#define CRT_KEY_TYPE       KEYTYPE_PKCSCRT
        +#define ME_KEY_TYPE        KEYTYPE_MODEXPO
        +#endif
        +
        +
        +
        +#endif   /* __ICA_OPENSSL_API_H__ */
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/Makefile b/vendor/openssl/openssl/demos/engines/rsaref/Makefile
        new file mode 100644
        index 000000000..63b8c79d2
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/Makefile
        @@ -0,0 +1,135 @@
        +LIBNAME=	librsaref
        +SRC=		rsaref.c
        +OBJ=		rsaref.o
        +HEADER=		rsaref.h
        +
        +CC=		gcc
        +PIC=		-fPIC
        +CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT
        +AR=		ar r
        +RANLIB=		ranlib
        +
        +LIB=		$(LIBNAME).a
        +SHLIB=		$(LIBNAME).so
        +
        +all:
        +		@echo 'Please choose a system to build on:'
        +		@echo ''
        +		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
        +		@echo 'solaris:  Solaris'
        +		@echo 'irix:     IRIX'
        +		@echo 'hpux32:   32-bit HP/UX'
        +		@echo 'hpux64:   64-bit HP/UX'
        +		@echo 'aix:      AIX'
        +		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
        +		@echo ''
        +
        +FORCE.install:
        +install:	FORCE.install
        +		cd install; \
        +			make -f unix/makefile CFLAGS='-I. -DPROTOTYPES=1 -O -c' RSAREFLIB=librsaref.a librsaref.a
        +
        +FORCE.update:
        +update:		FORCE.update
        +		perl ../../../util/mkerr.pl -conf rsaref.ec \
        +			-nostatic -staticloader -write rsaref.c
        +
        +darwin:		install $(SHLIB).darwin
        +cygwin:		install $(SHLIB).cygwin
        +gnu:		install $(SHLIB).gnu
        +alpha-osf1:	install $(SHLIB).alpha-osf1
        +tru64:		install $(SHLIB).tru64
        +solaris:	install $(SHLIB).solaris
        +irix:		install $(SHLIB).irix
        +hpux32:		install $(SHLIB).hpux32
        +hpux64:		install $(SHLIB).hpux64
        +aix:		install $(SHLIB).aix
        +reliantunix:	install $(SHLIB).reliantunix
        +
        +$(LIB):		$(OBJ)
        +		$(AR) $(LIB) $(OBJ)
        +		- $(RANLIB) $(LIB)
        +
        +LINK_SO=	\
        +  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) install/librsaref.a && \
        +  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
        +   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
        +
        +$(SHLIB).darwin:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='-all_load' \
        +		SHAREDFLAGS='-dynamiclib -install_name $(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).darwin
        +$(SHLIB).cygwin:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='--whole-archive' \
        +		SHAREDFLAGS='-shared -Wl,-Bsymbolic -Wl,--out-implib,$(LIBNAME).dll.a' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).cygwin
        +$(SHLIB).gnu:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='--whole-archive' \
        +		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).gnu
        +$(SHLIB).tru64:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).tru64
        +$(SHLIB).solaris:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='-z allextract' \
        +		SHAREDFLAGS='-G -h $(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).solaris
        +$(SHLIB).irix:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).irix
        +$(SHLIB).hpux32:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='-Fl' \
        +		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux32
        +$(SHLIB).hpux64:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='+forceload' \
        +		SHAREDFLAGS='-b -z +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux64
        +$(SHLIB).aix:	$(LIB) install/librsaref.a
        +		ALLSYMSFLAGS='-bnogc' \
        +		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).aix
        +
        +depend:
        +		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
        +		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
        +		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
        +		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
        +		rm -f Makefile.tmp Makefile
        +		mv Makefile.new Makefile
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
        +rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
        +rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
        +rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
        +rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
        +rsaref.o: ../../../include/openssl/opensslconf.h
        +rsaref.o: ../../../include/openssl/opensslv.h
        +rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
        +rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
        +rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
        +rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
        +rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
        +rsaref.o: source/rsaref.h
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/README b/vendor/openssl/openssl/demos/engines/rsaref/README
        new file mode 100644
        index 000000000..00b1f7473
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/README
        @@ -0,0 +1,22 @@
        +librsaref.so is a demonstration dynamic engine that does RSA
        +operations using the old RSAref 2.0 implementation.
        +
        +To make proper use of this engine, you must download RSAref 2.0
        +(search the web for rsaref.tar.Z for example) and unpack it in this
        +directory, so you'll end up having the subdirectories "install" and
        +"source" among others.
        +
        +To build, do the following:
        +
        +	make
        +
        +This will list a number of available targets to choose from.  Most of
        +them are architecture-specific.  The exception is "gnu" which is to be
        +used on systems where GNU ld and gcc have been installed in such a way
        +that gcc uses GNU ld to link together programs and shared libraries.
        +
        +The make file assumes you use gcc.  To change that, just reassign CC:
        +
        +	make CC=cc
        +
        +The result is librsaref.so, which you can copy to any place you wish.
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/build.com b/vendor/openssl/openssl/demos/engines/rsaref/build.com
        new file mode 100644
        index 000000000..72b013d45
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/build.com
        @@ -0,0 +1,105 @@
        +$! BUILD.COM -- Building procedure for the RSAref engine
        +$
        +$	if f$search("source.dir") .eqs. "" -
        +	   .or. f$search("install.dir") .eqs. ""
        +$	then
        +$	    write sys$error "RSAref 2.0 hasn't been properly extracted."
        +$	    exit
        +$	endif
        +$
        +$	if (f$getsyi("cpu").lt.128)
        +$	then
        +$	    arch := vax
        +$	else
        +$	    arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	    if (arch .eqs. "") then arch = "UNK"
        +$	endif
        +$
        +$	_save_default = f$environment("default")
        +$	set default [.install]
        +$	files := desc,digit,md2c,md5c,nn,prime,-
        +		rsa,r_encode,r_dh,r_enhanc,r_keygen,r_random,-
        +		r_stdlib
        +$	delete rsaref.olb;*
        +$	library/create/object rsaref.olb
        +$	files_i = 0
        +$ rsaref_loop:
        +$	files_e = f$edit(f$element(files_i,",",files),"trim")
        +$	files_i = files_i + 1
        +$	if files_e .eqs. "," then goto rsaref_loop_end
        +$	cc/include=([-.source],[])/define=PROTOTYPES=1/object=[]'files_e'.obj -
        +		[-.source]'files_e'.c
        +$	library/replace/object rsaref.olb 'files_e'.obj
        +$	goto rsaref_loop
        +$ rsaref_loop_end:
        +$
        +$	set default [-]
        +$	define/user openssl [---.include.openssl]
        +$	cc/define=ENGINE_DYNAMIC_SUPPORT rsaref.c
        +$
        +$	if arch .eqs. "VAX"
        +$	then
        +$	    macro/object=rsaref_vec.obj sys$input:
        +;
        +; Transfer vector for VAX shareable image
        +;
        +	.TITLE librsaref
        +;
        +; Define macro to assist in building transfer vector entries.  Each entry
        +; should take no more than 8 bytes.
        +;
        +	.MACRO FTRANSFER_ENTRY routine
        +	.ALIGN QUAD
        +	.TRANSFER routine
        +	.MASK	routine
        +	JMP	routine+2
        +	.ENDM FTRANSFER_ENTRY
        +;
        +; Place entries in own program section.
        +;
        +	.PSECT $$LIBRSAREF,QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT
        +
        +LIBRSAREF_xfer:
        +	FTRANSFER_ENTRY bind_engine
        +	FTRANSFER_ENTRY v_check
        +
        +;
        +; Allocate extra storage at end of vector to allow for expansion.
        +;
        +	.BLKB 512-<.-LIBRSAREF_xfer>	; 1 page.
        +	.END
        +$	    link/share=librsaref.exe sys$input:/option
        +!
        +! Ensure transfer vector is at beginning of image
        +!
        +CLUSTER=FIRST
        +COLLECT=FIRST,$$LIBRSAREF
        +!
        +! make psects nonshareable so image can be installed.
        +!
        +PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
        +[]rsaref_vec.obj
        +[]rsaref.obj
        +[.install]rsaref.olb/lib
        +[---.vax.exe.crypto]libcrypto.olb/lib
        +$	else
        +$	    if arch_name .eqs. "ALPHA"
        +$	    then
        +$		link/share=librsaref.exe sys$input:/option
        +[]rsaref.obj
        +[.install]rsaref.olb/lib
        +[---.alpha.exe.crypto]libcrypto.olb/lib
        +symbol_vector=(bind_engine=procedure,v_check=procedure)
        +$	    else
        +$		if arch_name .eqs. "IA64"
        +$		then
        +$		    link /shareable=librsaref.exe sys$input: /options
        +[]rsaref.obj
        +[.install]rsaref.olb/lib
        +[---.ia64.exe.crypto]libcrypto.olb/lib
        +symbol_vector=(bind_engine=procedure,v_check=procedure)
        +$		endif
        +$	    endif
        +$	endif
        +$
        +$	set default '_save_default'
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/rsaref.c b/vendor/openssl/openssl/demos/engines/rsaref/rsaref.c
        new file mode 100644
        index 000000000..f97974fc4
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/rsaref.c
        @@ -0,0 +1,685 @@
        +/* Demo of how to construct your own engine and using it.  The basis of this
        +   engine is RSAref, an old reference of the RSA algorithm which can still
        +   be found a little here and there. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include "./source/global.h"
        +#include "./source/rsaref.h"
        +#include "./source/rsa.h"
        +#include "./source/des.h"
        +#include <openssl/err.h>
        +#define OPENSSL_NO_MD2
        +#define OPENSSL_NO_MD5
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/engine.h>
        +
        +#define RSAREF_LIB_NAME "rsaref engine"
        +#include "rsaref_err.c"
        +
        +/*****************************************************************************
        + *** Function declarations and global variable definitions                 ***
        + *****************************************************************************/
        +
        +/*****************************************************************************
        + * Constants used when creating the ENGINE
        + **/
        +static const char *engine_rsaref_id = "rsaref";
        +static const char *engine_rsaref_name = "RSAref engine support";
        +
        +/*****************************************************************************
        + * Functions to handle the engine
        + **/
        +static int rsaref_destroy(ENGINE *e);
        +static int rsaref_init(ENGINE *e);
        +static int rsaref_finish(ENGINE *e);
        +#if 0
        +static int rsaref_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 
        +#endif
        +
        +/*****************************************************************************
        + * Engine commands
        + **/
        +static const ENGINE_CMD_DEFN rsaref_cmd_defns[] = {
        +	{0, NULL, NULL, 0}
        +	};
        +
        +/*****************************************************************************
        + * RSA functions
        + **/
        +static int rsaref_private_decrypt(int len, const unsigned char *from,
        +	unsigned char *to, RSA *rsa, int padding);
        +static int rsaref_private_encrypt(int len, const unsigned char *from,
        +	unsigned char *to, RSA *rsa, int padding);
        +static int rsaref_public_encrypt(int len, const unsigned char *from,
        +	unsigned char *to, RSA *rsa, int padding);
        +static int rsaref_public_decrypt(int len, const unsigned char *from,
        +	unsigned char *to, RSA *rsa, int padding);
        +static int bnref_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m,
        +			  BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
        +
        +/*****************************************************************************
        + * Our RSA method
        + **/
        +static RSA_METHOD rsaref_rsa =
        +{
        +  "RSAref PKCS#1 RSA",
        +  rsaref_public_encrypt,
        +  rsaref_public_decrypt,
        +  rsaref_private_encrypt,
        +  rsaref_private_decrypt,
        +  rsaref_mod_exp,
        +  bnref_mod_exp,
        +  NULL,
        +  NULL,
        +  0,
        +  NULL,
        +  NULL,
        +  NULL
        +};
        +
        +/*****************************************************************************
        + * Symetric cipher and digest function registrars
        + **/
        +static int rsaref_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +	const int **nids, int nid);
        +static int rsaref_digests(ENGINE *e, const EVP_MD **digest,
        +	const int **nids, int nid);
        +
        +static int rsaref_cipher_nids[] =
        +	{ NID_des_cbc, NID_des_ede3_cbc, NID_desx_cbc, 0 };
        +static int rsaref_digest_nids[] =
        +	{ NID_md2, NID_md5, 0 };
        +
        +/*****************************************************************************
        + * DES functions
        + **/
        +static int cipher_des_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc);
        +static int cipher_des_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, unsigned int inl);
        +static int cipher_des_cbc_clean(EVP_CIPHER_CTX *);
        +static int cipher_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc);
        +static int cipher_des_ede3_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, unsigned int inl);
        +static int cipher_des_ede3_cbc_clean(EVP_CIPHER_CTX *);
        +static int cipher_desx_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc);
        +static int cipher_desx_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, unsigned int inl);
        +static int cipher_desx_cbc_clean(EVP_CIPHER_CTX *);
        +
        +/*****************************************************************************
        + * Our DES ciphers
        + **/
        +static const EVP_CIPHER cipher_des_cbc =
        +	{
        +	NID_des_cbc,
        +	8, 8, 8,
        +	0 | EVP_CIPH_CBC_MODE,
        +	cipher_des_cbc_init,
        +	cipher_des_cbc_code,
        +	cipher_des_cbc_clean,
        +	sizeof(DES_CBC_CTX),
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +static const EVP_CIPHER cipher_des_ede3_cbc =
        +	{
        +	NID_des_ede3_cbc,
        +	8, 24, 8,
        +	0 | EVP_CIPH_CBC_MODE,
        +	cipher_des_ede3_cbc_init,
        +	cipher_des_ede3_cbc_code,
        +	cipher_des_ede3_cbc_clean,
        +	sizeof(DES3_CBC_CTX),
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +static const EVP_CIPHER cipher_desx_cbc =
        +	{
        +	NID_desx_cbc,
        +	8, 24, 8,
        +	0 | EVP_CIPH_CBC_MODE,
        +	cipher_desx_cbc_init,
        +	cipher_desx_cbc_code,
        +	cipher_desx_cbc_clean,
        +	sizeof(DESX_CBC_CTX),
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +
        +/*****************************************************************************
        + * MD functions
        + **/
        +static int digest_md2_init(EVP_MD_CTX *ctx);
        +static int digest_md2_update(EVP_MD_CTX *ctx,const void *data,
        +	unsigned long count);
        +static int digest_md2_final(EVP_MD_CTX *ctx,unsigned char *md);
        +static int digest_md5_init(EVP_MD_CTX *ctx);
        +static int digest_md5_update(EVP_MD_CTX *ctx,const void *data,
        +	unsigned long count);
        +static int digest_md5_final(EVP_MD_CTX *ctx,unsigned char *md);
        +
        +/*****************************************************************************
        + * Our MD digests
        + **/
        +static const EVP_MD digest_md2 =
        +	{
        +	NID_md2,
        +	NID_md2WithRSAEncryption,
        +	16,
        +	0,
        +	digest_md2_init,
        +	digest_md2_update,
        +	digest_md2_final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	16,
        +	sizeof(MD2_CTX)
        +	};
        +
        +static const EVP_MD digest_md5 =
        +	{
        +	NID_md5,
        +	NID_md5WithRSAEncryption,
        +	16,
        +	0,
        +	digest_md5_init,
        +	digest_md5_update,
        +	digest_md5_final,
        +	NULL,
        +	NULL,
        +	EVP_PKEY_RSA_method,
        +	64,
        +	sizeof(MD5_CTX)
        +	};
        +
        +/*****************************************************************************
        + *** Function definitions                                                  ***
        + *****************************************************************************/
        +
        +/*****************************************************************************
        + * Functions to handle the engine
        + **/
        +
        +static int bind_rsaref(ENGINE *e)
        +	{
        +	const RSA_METHOD *meth1;
        +	if(!ENGINE_set_id(e, engine_rsaref_id)
        +		|| !ENGINE_set_name(e, engine_rsaref_name)
        +		|| !ENGINE_set_RSA(e, &rsaref_rsa)
        +		|| !ENGINE_set_ciphers(e, rsaref_ciphers)
        +		|| !ENGINE_set_digests(e, rsaref_digests)
        +		|| !ENGINE_set_destroy_function(e, rsaref_destroy)
        +		|| !ENGINE_set_init_function(e, rsaref_init)
        +		|| !ENGINE_set_finish_function(e, rsaref_finish)
        +		/* || !ENGINE_set_ctrl_function(e, rsaref_ctrl) */
        +		/* || !ENGINE_set_cmd_defns(e, rsaref_cmd_defns) */)
        +		return 0;
        +
        +	/* Ensure the rsaref error handling is set up */
        +	ERR_load_RSAREF_strings();
        +	return 1;
        +	}
        +
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static int bind_helper(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_rsaref_id) != 0))
        +		return 0;
        +	if(!bind_rsaref(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
        +#else
        +static ENGINE *engine_rsaref(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_rsaref(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_rsaref(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_rsaref();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* Initiator which is only present to make sure this engine looks available */
        +static int rsaref_init(ENGINE *e)
        +	{
        +	return 1;
        +	}
        +
        +/* Finisher which is only present to make sure this engine looks available */
        +static int rsaref_finish(ENGINE *e)
        +	{
        +	return 1;
        +	}
        +
        +/* Destructor (complements the "ENGINE_ncipher()" constructor) */
        +static int rsaref_destroy(ENGINE *e)
        +	{
        +	ERR_unload_RSAREF_strings();
        +	return 1;
        +	}
        +
        +/*****************************************************************************
        + * RSA functions
        + **/
        +
        +static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
        +	{
        +	RSAREFerr(RSAREF_F_RSAREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(0);
        +	}
        +
        +static int bnref_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	RSAREFerr(RSAREF_F_BNREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(0);
        +	}
        +
        +/* unsigned char *to:  [max]    */
        +static int RSAref_bn2bin(BIGNUM *from, unsigned char *to, int max)
        +	{
        +	int i;
        +
        +	i=BN_num_bytes(from);
        +	if (i > max)
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_BN2BIN,RSAREF_R_LEN);
        +		return(0);
        +		}
        +
        +	memset(to,0,(unsigned int)max);
        +	if (!BN_bn2bin(from,&(to[max-i])))
        +		return(0);
        +	return(1);
        +	}
        +
        +#ifdef undef
        +/* unsigned char *from:  [max]    */
        +static BIGNUM *RSAref_bin2bn(unsigned char *from, BIGNUM *to, int max)
        +	{
        +	int i;
        +	BIGNUM *ret;
        +
        +	for (i=0; i<max; i++)
        +		if (from[i]) break;
        +
        +	ret=BN_bin2bn(&(from[i]),max-i,to);
        +	return(ret);
        +	}
        +
        +static int RSAref_Public_ref2eay(RSArefPublicKey *from, RSA *to)
        +	{
        +	to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN);
        +	to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN);
        +	if ((to->n == NULL) || (to->e == NULL)) return(0);
        +	return(1);
        +	}
        +#endif
        +
        +static int RSAref_Public_eay2ref(RSA *from, R_RSA_PUBLIC_KEY *to)
        +	{
        +	to->bits=BN_num_bits(from->n);
        +	if (!RSAref_bn2bin(from->n,to->modulus,MAX_RSA_MODULUS_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->e,to->exponent,MAX_RSA_MODULUS_LEN)) return(0);
        +	return(1);
        +	}
        +
        +#ifdef undef
        +static int RSAref_Private_ref2eay(RSArefPrivateKey *from, RSA *to)
        +	{
        +	if ((to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN)) == NULL)
        +		return(0);
        +	if ((to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN)) == NULL)
        +		return(0);
        +	if ((to->d=RSAref_bin2bn(from->d,NULL,RSAref_MAX_LEN)) == NULL)
        +		return(0);
        +	if ((to->p=RSAref_bin2bn(from->prime[0],NULL,RSAref_MAX_PLEN)) == NULL)
        +		return(0);
        +	if ((to->q=RSAref_bin2bn(from->prime[1],NULL,RSAref_MAX_PLEN)) == NULL)
        +		return(0);
        +	if ((to->dmp1=RSAref_bin2bn(from->pexp[0],NULL,RSAref_MAX_PLEN))
        +		== NULL)
        +		return(0);
        +	if ((to->dmq1=RSAref_bin2bn(from->pexp[1],NULL,RSAref_MAX_PLEN))
        +		== NULL)
        +		return(0);
        +	if ((to->iqmp=RSAref_bin2bn(from->coef,NULL,RSAref_MAX_PLEN)) == NULL)
        +		return(0);
        +	return(1);
        +	}
        +#endif
        +
        +static int RSAref_Private_eay2ref(RSA *from, R_RSA_PRIVATE_KEY *to)
        +	{
        +	to->bits=BN_num_bits(from->n);
        +	if (!RSAref_bn2bin(from->n,to->modulus,MAX_RSA_MODULUS_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->e,to->publicExponent,MAX_RSA_MODULUS_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->d,to->exponent,MAX_RSA_MODULUS_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->p,to->prime[0],MAX_RSA_PRIME_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->q,to->prime[1],MAX_RSA_PRIME_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->dmp1,to->primeExponent[0],MAX_RSA_PRIME_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->dmq1,to->primeExponent[1],MAX_RSA_PRIME_LEN)) return(0);
        +	if (!RSAref_bn2bin(from->iqmp,to->coefficient,MAX_RSA_PRIME_LEN)) return(0);
        +	return(1);
        +	}
        +
        +static int rsaref_private_decrypt(int len, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +	int i,outlen= -1;
        +	R_RSA_PRIVATE_KEY RSAkey;
        +
        +	if (!RSAref_Private_eay2ref(rsa,&RSAkey))
        +		goto err;
        +	if ((i=RSAPrivateDecrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_PRIVATE_DECRYPT,i);
        +		outlen= -1;
        +		}
        +err:
        +	memset(&RSAkey,0,sizeof(RSAkey));
        +	return(outlen);
        +	}
        +
        +static int rsaref_private_encrypt(int len, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +	int i,outlen= -1;
        +	R_RSA_PRIVATE_KEY RSAkey;
        +
        +	if (padding != RSA_PKCS1_PADDING)
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
        +		goto err;
        +	}
        +	if (!RSAref_Private_eay2ref(rsa,&RSAkey))
        +		goto err;
        +	if ((i=RSAPrivateEncrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_PRIVATE_ENCRYPT,i);
        +		outlen= -1;
        +		}
        +err:
        +	memset(&RSAkey,0,sizeof(RSAkey));
        +	return(outlen);
        +	}
        +
        +static int rsaref_public_decrypt(int len, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +	int i,outlen= -1;
        +	R_RSA_PUBLIC_KEY RSAkey;
        +
        +	if (!RSAref_Public_eay2ref(rsa,&RSAkey))
        +		goto err;
        +	if ((i=RSAPublicDecrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_PUBLIC_DECRYPT,i);
        +		outlen= -1;
        +		}
        +err:
        +	memset(&RSAkey,0,sizeof(RSAkey));
        +	return(outlen);
        +	}
        +
        +static int rsaref_public_encrypt(int len, const unsigned char *from, unsigned char *to,
        +	     RSA *rsa, int padding)
        +	{
        +	int outlen= -1;
        +	int i;
        +	R_RSA_PUBLIC_KEY RSAkey;
        +	R_RANDOM_STRUCT rnd;
        +	unsigned char buf[16];
        +
        +	if (padding != RSA_PKCS1_PADDING && padding != RSA_SSLV23_PADDING) 
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
        +		goto err;
        +		}
        +	
        +	R_RandomInit(&rnd);
        +	R_GetRandomBytesNeeded((unsigned int *)&i,&rnd);
        +	while (i > 0)
        +		{
        +		if (RAND_bytes(buf,16) <= 0)
        +			goto err;
        +		R_RandomUpdate(&rnd,buf,(unsigned int)((i>16)?16:i));
        +		i-=16;
        +		}
        +
        +	if (!RSAref_Public_eay2ref(rsa,&RSAkey))
        +		goto err;
        +	if ((i=RSAPublicEncrypt(to,(unsigned int *)&outlen,(unsigned char *)from,len,&RSAkey,&rnd)) != 0)
        +		{
        +		RSAREFerr(RSAREF_F_RSAREF_PUBLIC_ENCRYPT,i);
        +		outlen= -1;
        +		goto err;
        +		}
        +err:
        +	memset(&RSAkey,0,sizeof(RSAkey));
        +	R_RandomFinal(&rnd);
        +	memset(&rnd,0,sizeof(rnd));
        +	return(outlen);
        +	}
        +
        +/*****************************************************************************
        + * Symetric cipher and digest function registrars
        + **/
        +static int rsaref_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +	const int **nids, int nid)
        +	{
        +	int ok = 1;
        +	if(!cipher)
        +		{
        +		/* We are returning a list of supported nids */
        +		*nids = rsaref_cipher_nids;
        +		return (sizeof(rsaref_cipher_nids)-1)/sizeof(rsaref_cipher_nids[0]);
        +		}
        +	/* We are being asked for a specific cipher */
        +	switch (nid)
        +		{
        +	case NID_des_cbc:
        +		*cipher = &cipher_des_cbc; break;
        +	case NID_des_ede3_cbc:
        +		*cipher = &cipher_des_ede3_cbc; break;
        +	case NID_desx_cbc:
        +		*cipher = &cipher_desx_cbc; break;
        +	default:
        +		ok = 0;
        +		*cipher = NULL;
        +		break;
        +		}
        +	return ok;
        +	}
        +static int rsaref_digests(ENGINE *e, const EVP_MD **digest,
        +	const int **nids, int nid)
        +	{
        +	int ok = 1;
        +	if(!digest)
        +		{
        +		/* We are returning a list of supported nids */
        +		*nids = rsaref_digest_nids;
        +		return (sizeof(rsaref_digest_nids)-1)/sizeof(rsaref_digest_nids[0]);
        +		}
        +	/* We are being asked for a specific digest */
        +	switch (nid)
        +		{
        +	case NID_md2:
        +		*digest = &digest_md2; break;
        +	case NID_md5:
        +		*digest = &digest_md5; break;
        +	default:
        +		ok = 0;
        +		*digest = NULL;
        +		break;
        +		}
        +	return ok;
        +	}
        +
        +/*****************************************************************************
        + * DES functions
        + **/
        +#undef data
        +#define data(ctx) ((DES_CBC_CTX *)(ctx)->cipher_data)
        +static int cipher_des_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc)
        +	{
        +	DES_CBCInit(data(ctx), (unsigned char *)key, (unsigned char *)iv, enc);
        +	return 1;
        +	}
        +static int cipher_des_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, unsigned int inl)
        +	{
        +	int ret = DES_CBCUpdate(data(ctx), out, (unsigned char *)in, inl);
        +	switch (ret)
        +		{
        +	case RE_LEN:
        +		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED);
        +		break;
        +	case 0:
        +		break;
        +	default:
        +		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT);
        +		}
        +	return !ret;
        +	}
        +static int cipher_des_cbc_clean(EVP_CIPHER_CTX *ctx)
        +	{
        +	memset(data(ctx), 0, ctx->cipher->ctx_size);
        +	return 1;
        +	}
        +
        +#undef data
        +#define data(ctx) ((DES3_CBC_CTX *)(ctx)->cipher_data)
        +static int cipher_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc)
        +	{
        +	DES3_CBCInit(data(ctx), (unsigned char *)key, (unsigned char *)iv,
        +		enc);
        +	return 1;
        +	}
        +static int cipher_des_ede3_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, unsigned int inl)
        +	{
        +	int ret = DES3_CBCUpdate(data(ctx), out, (unsigned char *)in, inl);
        +	switch (ret)
        +		{
        +	case RE_LEN:
        +		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED);
        +		break;
        +	case 0:
        +		break;
        +	default:
        +		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT);
        +		}
        +	return !ret;
        +	}
        +static int cipher_des_ede3_cbc_clean(EVP_CIPHER_CTX *ctx)
        +	{
        +	memset(data(ctx), 0, ctx->cipher->ctx_size);
        +	return 1;
        +	}
        +
        +#undef data
        +#define data(ctx) ((DESX_CBC_CTX *)(ctx)->cipher_data)
        +static int cipher_desx_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc)
        +	{
        +	DESX_CBCInit(data(ctx), (unsigned char *)key, (unsigned char *)iv,
        +		enc);
        +	return 1;
        +	}
        +static int cipher_desx_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, unsigned int inl)
        +	{
        +	int ret = DESX_CBCUpdate(data(ctx), out, (unsigned char *)in, inl);
        +	switch (ret)
        +		{
        +	case RE_LEN:
        +		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED);
        +		break;
        +	case 0:
        +		break;
        +	default:
        +		RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT);
        +		}
        +	return !ret;
        +	}
        +static int cipher_desx_cbc_clean(EVP_CIPHER_CTX *ctx)
        +	{
        +	memset(data(ctx), 0, ctx->cipher->ctx_size);
        +	return 1;
        +	}
        +
        +/*****************************************************************************
        + * MD functions
        + **/
        +#undef data
        +#define data(ctx) ((MD2_CTX *)(ctx)->md_data)
        +static int digest_md2_init(EVP_MD_CTX *ctx)
        +	{
        +	MD2Init(data(ctx));
        +	return 1;
        +	}
        +static int digest_md2_update(EVP_MD_CTX *ctx,const void *data,
        +	unsigned long count)
        +	{
        +	MD2Update(data(ctx), (unsigned char *)data, (unsigned int)count);
        +	return 1;
        +	}
        +static int digest_md2_final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{
        +	MD2Final(md, data(ctx));
        +	return 1;
        +	}
        +
        +#undef data
        +#define data(ctx) ((MD5_CTX *)(ctx)->md_data)
        +static int digest_md5_init(EVP_MD_CTX *ctx)
        +	{
        +	MD5Init(data(ctx));
        +	return 1;
        +	}
        +static int digest_md5_update(EVP_MD_CTX *ctx,const void *data,
        +	unsigned long count)
        +	{
        +	MD5Update(data(ctx), (unsigned char *)data, (unsigned int)count);
        +	return 1;
        +	}
        +static int digest_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{
        +	MD5Final(md, data(ctx));
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/rsaref.ec b/vendor/openssl/openssl/demos/engines/rsaref/rsaref.ec
        new file mode 100644
        index 000000000..c690ae388
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/rsaref.ec
        @@ -0,0 +1,8 @@
        +# configuration file for util/mkerr.pl
        +#
        +# use like this:
        +#
        +#	perl ../../../util/mkerr.pl -conf rsaref.ec \
        +#		-nostatic -staticloader -write *.c
        +
        +L RSAREF	rsaref_err.h			rsaref_err.c
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/rsaref_err.c b/vendor/openssl/openssl/demos/engines/rsaref/rsaref_err.c
        new file mode 100644
        index 000000000..ceaf05706
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/rsaref_err.c
        @@ -0,0 +1,161 @@
        +/* rsaref_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 <stdio.h>
        +#include <openssl/err.h>
        +#include "rsaref_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +static ERR_STRING_DATA RSAREF_str_functs[]=
        +	{
        +{ERR_PACK(0,RSAREF_F_BNREF_MOD_EXP,0),	"BNREF_MOD_EXP"},
        +{ERR_PACK(0,RSAREF_F_CIPHER_DES_CBC_CODE,0),	"CIPHER_DES_CBC_CODE"},
        +{ERR_PACK(0,RSAREF_F_RSAREF_BN2BIN,0),	"RSAREF_BN2BIN"},
        +{ERR_PACK(0,RSAREF_F_RSAREF_MOD_EXP,0),	"RSAREF_MOD_EXP"},
        +{ERR_PACK(0,RSAREF_F_RSAREF_PRIVATE_DECRYPT,0),	"RSAREF_PRIVATE_DECRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSAREF_PRIVATE_ENCRYPT,0),	"RSAREF_PRIVATE_ENCRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSAREF_PUBLIC_DECRYPT,0),	"RSAREF_PUBLIC_DECRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSAREF_PUBLIC_ENCRYPT,0),	"RSAREF_PUBLIC_ENCRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSA_BN2BIN,0),	"RSA_BN2BIN"},
        +{ERR_PACK(0,RSAREF_F_RSA_PRIVATE_DECRYPT,0),	"RSA_PRIVATE_DECRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSA_PRIVATE_ENCRYPT,0),	"RSA_PRIVATE_ENCRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSA_PUBLIC_DECRYPT,0),	"RSA_PUBLIC_DECRYPT"},
        +{ERR_PACK(0,RSAREF_F_RSA_PUBLIC_ENCRYPT,0),	"RSA_PUBLIC_ENCRYPT"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA RSAREF_str_reasons[]=
        +	{
        +{RSAREF_R_CONTENT_ENCODING               ,"content encoding"},
        +{RSAREF_R_DATA                           ,"data"},
        +{RSAREF_R_DIGEST_ALGORITHM               ,"digest algorithm"},
        +{RSAREF_R_ENCODING                       ,"encoding"},
        +{RSAREF_R_ENCRYPTION_ALGORITHM           ,"encryption algorithm"},
        +{RSAREF_R_KEY                            ,"key"},
        +{RSAREF_R_KEY_ENCODING                   ,"key encoding"},
        +{RSAREF_R_LEN                            ,"len"},
        +{RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED       ,"length not block aligned"},
        +{RSAREF_R_MODULUS_LEN                    ,"modulus len"},
        +{RSAREF_R_NEED_RANDOM                    ,"need random"},
        +{RSAREF_R_PRIVATE_KEY                    ,"private key"},
        +{RSAREF_R_PUBLIC_KEY                     ,"public key"},
        +{RSAREF_R_SIGNATURE                      ,"signature"},
        +{RSAREF_R_SIGNATURE_ENCODING             ,"signature encoding"},
        +{RSAREF_R_UNKNOWN_FAULT                  ,"unknown fault"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef RSAREF_LIB_NAME
        +static ERR_STRING_DATA RSAREF_lib_name[]=
        +        {
        +{0	,RSAREF_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int RSAREF_lib_error_code=0;
        +static int RSAREF_error_init=1;
        +
        +static void ERR_load_RSAREF_strings(void)
        +	{
        +	if (RSAREF_lib_error_code == 0)
        +		RSAREF_lib_error_code=ERR_get_next_error_library();
        +
        +	if (RSAREF_error_init)
        +		{
        +		RSAREF_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(RSAREF_lib_error_code,RSAREF_str_functs);
        +		ERR_load_strings(RSAREF_lib_error_code,RSAREF_str_reasons);
        +#endif
        +
        +#ifdef RSAREF_LIB_NAME
        +		RSAREF_lib_name->error = ERR_PACK(RSAREF_lib_error_code,0,0);
        +		ERR_load_strings(0,RSAREF_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_RSAREF_strings(void)
        +	{
        +	if (RSAREF_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(RSAREF_lib_error_code,RSAREF_str_functs);
        +		ERR_unload_strings(RSAREF_lib_error_code,RSAREF_str_reasons);
        +#endif
        +
        +#ifdef RSAREF_LIB_NAME
        +		ERR_unload_strings(0,RSAREF_lib_name);
        +#endif
        +		RSAREF_error_init=1;
        +		}
        +	}
        +
        +static void ERR_RSAREF_error(int function, int reason, char *file, int line)
        +	{
        +	if (RSAREF_lib_error_code == 0)
        +		RSAREF_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(RSAREF_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/demos/engines/rsaref/rsaref_err.h b/vendor/openssl/openssl/demos/engines/rsaref/rsaref_err.h
        new file mode 100644
        index 000000000..19759709b
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/rsaref/rsaref_err.h
        @@ -0,0 +1,109 @@
        +/* rsaref_err.h */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_RSAREF_ERR_H
        +#define HEADER_RSAREF_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_RSAREF_strings(void);
        +static void ERR_unload_RSAREF_strings(void);
        +static void ERR_RSAREF_error(int function, int reason, char *file, int line);
        +#define RSAREFerr(f,r) ERR_RSAREF_error((f),(r),__FILE__,__LINE__)
        +/* Error codes for the RSAREF functions. */
        +
        +/* Function codes. */
        +#define RSAREF_F_BNREF_MOD_EXP				 100
        +#define RSAREF_F_CIPHER_DES_CBC_CODE			 112
        +#define RSAREF_F_RSAREF_BN2BIN				 101
        +#define RSAREF_F_RSAREF_MOD_EXP				 102
        +#define RSAREF_F_RSAREF_PRIVATE_DECRYPT			 103
        +#define RSAREF_F_RSAREF_PRIVATE_ENCRYPT			 104
        +#define RSAREF_F_RSAREF_PUBLIC_DECRYPT			 105
        +#define RSAREF_F_RSAREF_PUBLIC_ENCRYPT			 106
        +#define RSAREF_F_RSA_BN2BIN				 107
        +#define RSAREF_F_RSA_PRIVATE_DECRYPT			 108
        +#define RSAREF_F_RSA_PRIVATE_ENCRYPT			 109
        +#define RSAREF_F_RSA_PUBLIC_DECRYPT			 110
        +#define RSAREF_F_RSA_PUBLIC_ENCRYPT			 111
        +
        +/* Reason codes. */
        +#define RSAREF_R_CONTENT_ENCODING			 100
        +#define RSAREF_R_DATA					 101
        +#define RSAREF_R_DIGEST_ALGORITHM			 102
        +#define RSAREF_R_ENCODING				 103
        +#define RSAREF_R_ENCRYPTION_ALGORITHM			 104
        +#define RSAREF_R_KEY					 105
        +#define RSAREF_R_KEY_ENCODING				 106
        +#define RSAREF_R_LEN					 107
        +#define RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED		 114
        +#define RSAREF_R_MODULUS_LEN				 108
        +#define RSAREF_R_NEED_RANDOM				 109
        +#define RSAREF_R_PRIVATE_KEY				 110
        +#define RSAREF_R_PUBLIC_KEY				 111
        +#define RSAREF_R_SIGNATURE				 112
        +#define RSAREF_R_SIGNATURE_ENCODING			 113
        +#define RSAREF_R_UNKNOWN_FAULT				 115
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/demos/engines/zencod/Makefile b/vendor/openssl/openssl/demos/engines/zencod/Makefile
        new file mode 100644
        index 000000000..5b6a339ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/zencod/Makefile
        @@ -0,0 +1,114 @@
        +LIBNAME=	libzencod
        +SRC=		hw_zencod.c
        +OBJ=		hw_zencod.o
        +HEADER=		hw_zencod.h
        +
        +CC=		gcc
        +PIC=		-fPIC
        +CFLAGS=		-g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT -DFLAT_INC
        +AR=		ar r
        +RANLIB=		ranlib
        +
        +LIB=		$(LIBNAME).a
        +SHLIB=		$(LIBNAME).so
        +
        +all:
        +		@echo 'Please choose a system to build on:'
        +		@echo ''
        +		@echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
        +		@echo 'solaris:  Solaris'
        +		@echo 'irix:     IRIX'
        +		@echo 'hpux32:   32-bit HP/UX'
        +		@echo 'hpux64:   64-bit HP/UX'
        +		@echo 'aix:      AIX'
        +		@echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
        +		@echo ''
        +
        +FORCE.update:
        +update:		FORCE.update
        +		perl ../../../util/mkerr.pl -conf hw_zencod.ec \
        +			-nostatic -staticloader -write hw_zencod.c
        +
        +gnu:		$(SHLIB).gnu
        +tru64:		$(SHLIB).tru64
        +solaris:	$(SHLIB).solaris
        +irix:		$(SHLIB).irix
        +hpux32:		$(SHLIB).hpux32
        +hpux64:		$(SHLIB).hpux64
        +aix:		$(SHLIB).aix
        +
        +$(LIB):		$(OBJ)
        +		$(AR) $(LIB) $(OBJ)
        +		- $(RANLIB) $(LIB)
        +
        +LINK_SO=	\
        +  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) && \
        +  (nm -Pg $(LIBNAME).o | grep ' [BDT] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
        +   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto -lc)
        +
        +$(SHLIB).gnu:	$(LIB)
        +		ALLSYMSFLAGS='--whole-archive' \
        +		SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).gnu
        +$(SHLIB).tru64:	$(LIB)
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).tru64
        +$(SHLIB).solaris:	$(LIB)
        +		ALLSYMSFLAGS='-z allextract' \
        +		SHAREDFLAGS='-G -h $(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).solaris
        +$(SHLIB).irix:	$(LIB)
        +		ALLSYMSFLAGS='-all' \
        +		SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).irix
        +$(SHLIB).hpux32:	$(LIB)
        +		ALLSYMSFLAGS='-Fl' \
        +		SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux32
        +$(SHLIB).hpux64:	$(LIB)
        +		ALLSYMSFLAGS='+forceload' \
        +		SHAREDFLAGS='-b -z +h $(SHLIB)' \
        +		SHAREDCMD='/usr/ccs/bin/ld'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).hpux64
        +$(SHLIB).aix:	$(LIB)
        +		ALLSYMSFLAGS='-bnogc' \
        +		SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
        +		SHAREDCMD='$(CC)'; \
        +		$(LINK_SO)
        +		touch $(SHLIB).aix
        +
        +depend:
        +		sed -e '/^# DO NOT DELETE.*/,$$d' < Makefile > Makefile.tmp
        +		echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
        +		gcc -M $(CFLAGS) $(SRC) >> Makefile.tmp
        +		perl ../../../util/clean-depend.pl < Makefile.tmp > Makefile.new
        +		rm -f Makefile.tmp Makefile
        +		mv Makefile.new Makefile
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +rsaref.o: ../../../include/openssl/asn1.h ../../../include/openssl/bio.h
        +rsaref.o: ../../../include/openssl/bn.h ../../../include/openssl/crypto.h
        +rsaref.o: ../../../include/openssl/dh.h ../../../include/openssl/dsa.h
        +rsaref.o: ../../../include/openssl/e_os2.h ../../../include/openssl/engine.h
        +rsaref.o: ../../../include/openssl/err.h ../../../include/openssl/lhash.h
        +rsaref.o: ../../../include/openssl/opensslconf.h
        +rsaref.o: ../../../include/openssl/opensslv.h
        +rsaref.o: ../../../include/openssl/ossl_typ.h ../../../include/openssl/rand.h
        +rsaref.o: ../../../include/openssl/rsa.h ../../../include/openssl/safestack.h
        +rsaref.o: ../../../include/openssl/stack.h ../../../include/openssl/symhacks.h
        +rsaref.o: ../../../include/openssl/ui.h rsaref.c rsaref_err.c rsaref_err.h
        +rsaref.o: source/des.h source/global.h source/md2.h source/md5.h source/rsa.h
        +rsaref.o: source/rsaref.h
        diff --git a/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.c b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.c
        new file mode 100644
        index 000000000..4234b93cb
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.c
        @@ -0,0 +1,1739 @@
        +/* crypto/engine/hw_zencod.c */
        + /* Written by Fred Donnat (frederic.donnat@zencod.com) for "zencod"
        + * engine integration in order to redirect crypto computing on a crypto
        + * hardware accelerator zenssl32  ;-)
        + *
        + * Date : 25 jun 2002
        + * Revision : 17 Ju7 2002
        + * Version : zencod_engine-0.9.7
        + */
        +
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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).
        + *
        + */
        +
        +
        +/* ENGINE general include */
        +#include <stdio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_ZENCOD
        +
        +#ifdef FLAT_INC
        +#  include "hw_zencod.h"
        +#else
        +#  include "vendor_defns/hw_zencod.h"
        +#endif
        +
        +#define ZENCOD_LIB_NAME "zencod engine"
        +#include "hw_zencod_err.c"
        +
        +#define FAIL_TO_SOFTWARE		-15
        +
        +#define	ZEN_LIBRARY	"zenbridge"
        +
        +#if 0
        +#  define PERROR(s)	perror(s)
        +#  define CHEESE()	fputs("## [ZenEngine] ## " __FUNCTION__ "\n", stderr)
        +#else
        +#  define PERROR(s)
        +#  define CHEESE()
        +#endif
        +
        +
        +/* Sorry ;) */
        +#ifndef WIN32
        +static inline void esrever ( unsigned char *d, int l )
        +{
        +	for(;--l>0;--l,d++){*d^=*(d+l);*(d+l)^=*d;*d^=*(d+l);}
        +}
        +
        +static inline void ypcmem ( unsigned char *d, const unsigned char *s, int l )
        +{
        +	for(d+=l;l--;)*--d=*s++;
        +}
        +#else
        +static __inline void esrever ( unsigned char *d, int l )
        +{
        +	for(;--l>0;--l,d++){*d^=*(d+l);*(d+l)^=*d;*d^=*(d+l);}
        +}
        +
        +static __inline void ypcmem ( unsigned char *d, const unsigned char *s, int l )
        +{
        +	for(d+=l;l--;)*--d=*s++;
        +}
        +#endif
        +
        +
        +#define BIGNUM2ZEN(n, bn)	(ptr_zencod_init_number((n), \
        +					(unsigned long) ((bn)->top * BN_BITS2), \
        +					(unsigned char *) ((bn)->d)))
        +
        +#define ZEN_BITS(n, bytes)	(ptr_zencod_bytes2bits((unsigned char *) (n), (unsigned long) (bytes)))
        +#define ZEN_BYTES(bits)	(ptr_zencod_bits2bytes((unsigned long) (bits)))
        +
        +
        +/* Function for ENGINE detection and control */
        +static int zencod_destroy ( ENGINE *e ) ;
        +static int zencod_init ( ENGINE *e ) ;
        +static int zencod_finish ( ENGINE *e ) ;
        +static int zencod_ctrl ( ENGINE *e, int cmd, long i, void *p, void (*f) () ) ;
        +
        +/* BIGNUM stuff */
        +static int zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx ) ;
        +
        +/* RSA stuff */
        +#ifndef OPENSSL_NO_RSA
        +static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *I, RSA *rsa ) ;
        +static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx ) ;
        +#endif
        +
        +/* DSA stuff */
        +#ifndef OPENSSL_NO_DSA
        +static int DSA_zencod_bn_mod_exp ( DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx ) ;
        +
        +static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa ) ;
        +static int DSA_zencod_do_verify ( const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
        +		DSA *dsa ) ;
        +#endif
        +
        +/* DH stuff */
        +#ifndef OPENSSL_NO_DH
        +static int DH_zencod_bn_mod_exp ( const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx ) ;
        +static int DH_zencod_generate_key ( DH *dh ) ;
        +static int DH_zencod_compute_key ( unsigned char *key, const BIGNUM *pub_key, DH *dh ) ;
        +#endif
        +
        +/* Rand stuff */
        +static void RAND_zencod_seed ( const void *buf, int num ) ;
        +static int RAND_zencod_rand_bytes ( unsigned char *buf, int num ) ;
        +static int RAND_zencod_rand_status ( void ) ;
        +
        +/* Digest Stuff */
        +static int engine_digests ( ENGINE *e, const EVP_MD **digest, const int **nids, int nid ) ;
        +
        +/* Cipher Stuff */
        +static int engine_ciphers ( ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid ) ;
        +
        +
        +#define ZENCOD_CMD_SO_PATH			ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN zencod_cmd_defns [ ] =
        +{
        +	{ ZENCOD_CMD_SO_PATH,
        +	  "SO_PATH",
        +	  "Specifies the path to the 'zenbridge' shared library",
        +	  ENGINE_CMD_FLAG_STRING},
        +	{ 0, NULL, NULL, 0 }
        +} ;
        +
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Our internal RSA_METHOD specific to zencod ENGINE providing pointers to our function */
        +static RSA_METHOD zencod_rsa =
        +{
        +	"ZENCOD RSA method",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	RSA_zencod_rsa_mod_exp,
        +	RSA_zencod_bn_mod_exp,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL,
        +	NULL
        +} ;
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* Our internal DSA_METHOD specific to zencod ENGINE providing pointers to our function */
        +static DSA_METHOD zencod_dsa =
        +{
        +	"ZENCOD DSA method",
        +	DSA_zencod_do_sign,
        +	NULL,
        +	DSA_zencod_do_verify,
        +	NULL,
        +	DSA_zencod_bn_mod_exp,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL
        +} ;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* Our internal DH_METHOD specific to zencod ENGINE providing pointers to our function */
        +static DH_METHOD zencod_dh =
        +{
        +	"ZENCOD DH method",
        +	DH_zencod_generate_key,
        +	DH_zencod_compute_key,
        +	DH_zencod_bn_mod_exp,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL
        +} ;
        +#endif
        +
        +/* Our internal RAND_meth specific to zencod ZNGINE providing pointers to  our function */
        +static RAND_METHOD zencod_rand =
        +{
        +	RAND_zencod_seed,
        +	RAND_zencod_rand_bytes,
        +	NULL,
        +	NULL,
        +	RAND_zencod_rand_bytes,
        +	RAND_zencod_rand_status
        +} ;
        +
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_zencod_id = "zencod";
        +static const char *engine_zencod_name = "ZENCOD hardware engine support";
        +
        +
        +/* This internal function is used by ENGINE_zencod () and possibly by the
        + * "dynamic" ENGINE support too   ;-)
        + */
        +static int bind_helper ( ENGINE *e )
        +{
        +
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth_rsa ;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	const DSA_METHOD *meth_dsa ;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth_dh ;
        +#endif
        +
        +	const RAND_METHOD *meth_rand ;
        +
        +
        +	if ( !ENGINE_set_id ( e, engine_zencod_id ) ||
        +			!ENGINE_set_name ( e, engine_zencod_name ) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA ( e, &zencod_rsa ) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			!ENGINE_set_DSA ( e, &zencod_dsa ) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH ( e, &zencod_dh ) ||
        +#endif
        +			!ENGINE_set_RAND ( e, &zencod_rand ) ||
        +
        +			!ENGINE_set_destroy_function ( e, zencod_destroy ) ||
        +			!ENGINE_set_init_function ( e, zencod_init ) ||
        +			!ENGINE_set_finish_function ( e, zencod_finish ) ||
        +			!ENGINE_set_ctrl_function ( e, zencod_ctrl ) ||
        +			!ENGINE_set_cmd_defns ( e, zencod_cmd_defns ) ||
        +			!ENGINE_set_digests ( e, engine_digests ) ||
        +			!ENGINE_set_ciphers ( e, engine_ciphers ) ) {
        +		return 0 ;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* We know that the "PKCS1_SSLeay()" functions hook properly
        +	 * to the Zencod-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!
        +	 */
        +	meth_rsa = RSA_PKCS1_SSLeay () ;
        +
        +	zencod_rsa.rsa_pub_enc = meth_rsa->rsa_pub_enc ;
        +	zencod_rsa.rsa_pub_dec = meth_rsa->rsa_pub_dec ;
        +	zencod_rsa.rsa_priv_enc = meth_rsa->rsa_priv_enc ;
        +	zencod_rsa.rsa_priv_dec = meth_rsa->rsa_priv_dec ;
        +	/* meth_rsa->rsa_mod_exp */
        +	/* meth_rsa->bn_mod_exp */
        +	zencod_rsa.init = meth_rsa->init ;
        +	zencod_rsa.finish = meth_rsa->finish ;
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	/* We use OpenSSL meth to supply what we don't provide ;-*)
        +	 */
        +	meth_dsa = DSA_OpenSSL () ;
        +
        +	/* meth_dsa->dsa_do_sign */
        +	zencod_dsa.dsa_sign_setup = meth_dsa->dsa_sign_setup ;
        +	/* meth_dsa->dsa_do_verify */
        +	zencod_dsa.dsa_mod_exp = meth_dsa->dsa_mod_exp ;
        +	/* zencod_dsa.bn_mod_exp = meth_dsa->bn_mod_exp ; */
        +	zencod_dsa.init = meth_dsa->init ;
        +	zencod_dsa.finish = meth_dsa->finish ;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* We use OpenSSL meth to supply what we don't provide ;-*)
        +	 */
        +	meth_dh = DH_OpenSSL () ;
        +
        +	/* zencod_dh.generate_key = meth_dh->generate_key ; */
        +	/* zencod_dh.compute_key = meth_dh->compute_key ; */
        +	/* zencod_dh.bn_mod_exp = meth_dh->bn_mod_exp ; */
        +	zencod_dh.init = meth_dh->init ;
        +	zencod_dh.finish = meth_dh->finish ;
        +
        +#endif
        +
        +	/* We use OpenSSL (SSLeay) meth to supply what we don't provide ;-*)
        +	 */
        +	meth_rand = RAND_SSLeay () ;
        +
        +	/* meth_rand->seed ; */
        +	/* zencod_rand.seed = meth_rand->seed ; */
        +	/* meth_rand->bytes ; */
        +	/* zencod_rand.bytes = meth_rand->bytes ; */
        +	zencod_rand.cleanup = meth_rand->cleanup ;
        +	zencod_rand.add = meth_rand->add ;
        +	/* meth_rand->pseudorand ; */
        +	/* zencod_rand.pseudorand = meth_rand->pseudorand ; */
        +	/* zencod_rand.status = meth_rand->status ; */
        +	/* meth_rand->status ; */
        +
        +	/* Ensure the zencod error handling is set up */
        +	ERR_load_ZENCOD_strings () ;
        +	return 1 ;
        +}
        +
        +
        +/* As this is only ever called once, there's no need for locking
        + * (indeed - the lock will already be held by our caller!!!)
        + */
        +static ENGINE *ENGINE_zencod ( void )
        +{
        +
        +	ENGINE *eng = ENGINE_new () ;
        +
        +	if ( !eng ) {
        +		return NULL ;
        +	}
        +	if ( !bind_helper ( eng ) ) {
        +		ENGINE_free ( eng ) ;
        +		return NULL ;
        +	}
        +
        +	return eng ;
        +}
        +
        +
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static
        +#endif
        +void ENGINE_load_zencod ( void )
        +{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = ENGINE_zencod ( ) ;
        +	if ( !toadd ) return ;
        +	ENGINE_add ( toadd ) ;
        +	ENGINE_free ( toadd ) ;
        +	ERR_clear_error ( ) ;
        +}
        +
        +
        +/* This is a process-global DSO handle used for loading and unloading
        + * the ZENBRIDGE 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 *zencod_dso = NULL ;
        +
        +static t_zencod_test *ptr_zencod_test = NULL ;
        +static t_zencod_bytes2bits *ptr_zencod_bytes2bits = NULL ;
        +static t_zencod_bits2bytes *ptr_zencod_bits2bytes = NULL ;
        +static t_zencod_new_number *ptr_zencod_new_number = NULL ;
        +static t_zencod_init_number *ptr_zencod_init_number = NULL ;
        +
        +static t_zencod_rsa_mod_exp *ptr_zencod_rsa_mod_exp = NULL ;
        +static t_zencod_rsa_mod_exp_crt *ptr_zencod_rsa_mod_exp_crt = NULL ;
        +static t_zencod_dsa_do_sign *ptr_zencod_dsa_do_sign = NULL ;
        +static t_zencod_dsa_do_verify *ptr_zencod_dsa_do_verify = NULL ;
        +static t_zencod_dh_generate_key *ptr_zencod_dh_generate_key = NULL ;
        +static t_zencod_dh_compute_key *ptr_zencod_dh_compute_key = NULL ;
        +static t_zencod_rand_bytes *ptr_zencod_rand_bytes = NULL ;
        +static t_zencod_math_mod_exp *ptr_zencod_math_mod_exp = NULL ;
        +
        +static t_zencod_md5_init *ptr_zencod_md5_init = NULL ;
        +static t_zencod_md5_update *ptr_zencod_md5_update = NULL ;
        +static t_zencod_md5_do_final *ptr_zencod_md5_do_final = NULL ;
        +static t_zencod_sha1_init *ptr_zencod_sha1_init = NULL ;
        +static t_zencod_sha1_update *ptr_zencod_sha1_update = NULL ;
        +static t_zencod_sha1_do_final *ptr_zencod_sha1_do_final = NULL ;
        +
        +static t_zencod_xdes_cipher *ptr_zencod_xdes_cipher = NULL ;
        +static t_zencod_rc4_cipher *ptr_zencod_rc4_cipher = NULL ;
        +
        +/* These are the static string constants for the DSO file name and the function
        + * symbol names to bind to.
        + */
        +static const char *ZENCOD_LIBNAME = ZEN_LIBRARY ;
        +
        +static const char *ZENCOD_Fct_0 = "test_device" ;
        +static const char *ZENCOD_Fct_1 = "zenbridge_bytes2bits" ;
        +static const char *ZENCOD_Fct_2 = "zenbridge_bits2bytes" ;
        +static const char *ZENCOD_Fct_3 = "zenbridge_new_number" ;
        +static const char *ZENCOD_Fct_4 = "zenbridge_init_number" ;
        +
        +static const char *ZENCOD_Fct_exp_1 = "zenbridge_rsa_mod_exp" ;
        +static const char *ZENCOD_Fct_exp_2 = "zenbridge_rsa_mod_exp_crt" ;
        +static const char *ZENCOD_Fct_dsa_1 = "zenbridge_dsa_do_sign" ;
        +static const char *ZENCOD_Fct_dsa_2 = "zenbridge_dsa_do_verify" ;
        +static const char *ZENCOD_Fct_dh_1 = "zenbridge_dh_generate_key" ;
        +static const char *ZENCOD_Fct_dh_2 = "zenbridge_dh_compute_key" ;
        +static const char *ZENCOD_Fct_rand_1 = "zenbridge_rand_bytes" ;
        +static const char *ZENCOD_Fct_math_1 = "zenbridge_math_mod_exp" ;
        +
        +static const char *ZENCOD_Fct_md5_1 = "zenbridge_md5_init" ;
        +static const char *ZENCOD_Fct_md5_2 = "zenbridge_md5_update" ;
        +static const char *ZENCOD_Fct_md5_3 = "zenbridge_md5_do_final" ;
        +static const char *ZENCOD_Fct_sha1_1 = "zenbridge_sha1_init" ;
        +static const char *ZENCOD_Fct_sha1_2 = "zenbridge_sha1_update" ;
        +static const char *ZENCOD_Fct_sha1_3 = "zenbridge_sha1_do_final" ;
        +
        +static const char *ZENCOD_Fct_xdes_1 = "zenbridge_xdes_cipher" ;
        +static const char *ZENCOD_Fct_rc4_1 = "zenbridge_rc4_cipher" ;
        +
        +/* Destructor (complements the "ENGINE_zencod ()" constructor)
        + */
        +static int zencod_destroy (ENGINE *e )
        +{
        +
        +	ERR_unload_ZENCOD_strings () ;
        +
        +	return 1 ;
        +}
        +
        +
        +/* (de)initialisation functions. Control Function
        + */
        +static int zencod_init ( ENGINE *e )
        +{
        +
        +	t_zencod_test *ptr_0 ;
        +	t_zencod_bytes2bits *ptr_1 ;
        +	t_zencod_bits2bytes *ptr_2 ;
        +	t_zencod_new_number *ptr_3 ;
        +	t_zencod_init_number *ptr_4 ;
        +	t_zencod_rsa_mod_exp *ptr_exp_1 ;
        +	t_zencod_rsa_mod_exp_crt *ptr_exp_2 ;
        +	t_zencod_dsa_do_sign *ptr_dsa_1 ;
        +	t_zencod_dsa_do_verify *ptr_dsa_2 ;
        +	t_zencod_dh_generate_key *ptr_dh_1 ;
        +	t_zencod_dh_compute_key *ptr_dh_2 ;
        +	t_zencod_rand_bytes *ptr_rand_1 ;
        +	t_zencod_math_mod_exp *ptr_math_1 ;
        +	t_zencod_md5_init *ptr_md5_1 ;
        +	t_zencod_md5_update *ptr_md5_2 ;
        +	t_zencod_md5_do_final *ptr_md5_3 ;
        +	t_zencod_sha1_init *ptr_sha1_1 ;
        +	t_zencod_sha1_update *ptr_sha1_2 ;
        +	t_zencod_sha1_do_final *ptr_sha1_3 ;
        +	t_zencod_xdes_cipher *ptr_xdes_1 ;
        +	t_zencod_rc4_cipher *ptr_rc4_1 ;
        +
        +	CHEESE () ;
        +
        +	/*
        +	 * We Should add some tests for non NULL parameters or bad value !!
        +	 * Stuff to be done ...
        +	 */
        +
        +	if ( zencod_dso != NULL ) {
        +		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_ALREADY_LOADED ) ;
        +		goto err ;
        +	}
        +	/* Trying to load the Library "cryptozen"
        +	 */
        +	zencod_dso = DSO_load ( NULL, ZENCOD_LIBNAME, NULL, 0 ) ;
        +	if ( zencod_dso == NULL ) {
        +		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE ) ;
        +		goto err ;
        +	}
        +
        +	/* Trying to load Function from the Library
        +	 */
        +	if ( ! ( ptr_1 = (t_zencod_bytes2bits*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_1 ) ) ||
        +			! ( ptr_2 = (t_zencod_bits2bytes*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_2 ) ) ||
        +			! ( ptr_3 = (t_zencod_new_number*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_3 ) ) ||
        +			! ( ptr_4 = (t_zencod_init_number*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_4 ) ) ||
        +			! ( ptr_exp_1 = (t_zencod_rsa_mod_exp*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_exp_1 ) ) ||
        +			! ( ptr_exp_2 = (t_zencod_rsa_mod_exp_crt*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_exp_2 ) ) ||
        +			! ( ptr_dsa_1 = (t_zencod_dsa_do_sign*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dsa_1 ) ) ||
        +			! ( ptr_dsa_2 = (t_zencod_dsa_do_verify*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dsa_2 ) ) ||
        +			! ( ptr_dh_1 = (t_zencod_dh_generate_key*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dh_1 ) ) ||
        +			! ( ptr_dh_2 = (t_zencod_dh_compute_key*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dh_2 ) ) ||
        +			! ( ptr_rand_1 = (t_zencod_rand_bytes*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_rand_1 ) ) ||
        +			! ( ptr_math_1 = (t_zencod_math_mod_exp*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_math_1 ) ) ||
        +			! ( ptr_0 = (t_zencod_test *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_0 ) ) ||
        +			! ( ptr_md5_1 = (t_zencod_md5_init *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_1 ) ) ||
        +			! ( ptr_md5_2 = (t_zencod_md5_update *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_2 ) ) ||
        +			! ( ptr_md5_3 = (t_zencod_md5_do_final *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_3 ) ) ||
        +			! ( ptr_sha1_1 = (t_zencod_sha1_init *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_1 ) ) ||
        +			! ( ptr_sha1_2 = (t_zencod_sha1_update *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_2 ) ) ||
        +			! ( ptr_sha1_3 = (t_zencod_sha1_do_final *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_3 ) ) ||
        +			! ( ptr_xdes_1 = (t_zencod_xdes_cipher *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_xdes_1 ) ) ||
        +			! ( ptr_rc4_1 = (t_zencod_rc4_cipher *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_rc4_1 ) ) ) {
        +
        +		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE ) ;
        +		goto err ;
        +	}
        +
        +	/* The function from "cryptozen" Library have been correctly loaded so copy them
        +	 */
        +	ptr_zencod_test = ptr_0 ;
        +	ptr_zencod_bytes2bits = ptr_1 ;
        +	ptr_zencod_bits2bytes = ptr_2 ;
        +	ptr_zencod_new_number = ptr_3 ;
        +	ptr_zencod_init_number = ptr_4 ;
        +	ptr_zencod_rsa_mod_exp = ptr_exp_1 ;
        +	ptr_zencod_rsa_mod_exp_crt = ptr_exp_2 ;
        +	ptr_zencod_dsa_do_sign = ptr_dsa_1 ;
        +	ptr_zencod_dsa_do_verify = ptr_dsa_2 ;
        +	ptr_zencod_dh_generate_key = ptr_dh_1 ;
        +	ptr_zencod_dh_compute_key = ptr_dh_2 ;
        +	ptr_zencod_rand_bytes = ptr_rand_1 ;
        +	ptr_zencod_math_mod_exp = ptr_math_1 ;
        +	ptr_zencod_test = ptr_0 ;
        +	ptr_zencod_md5_init = ptr_md5_1 ;
        +	ptr_zencod_md5_update = ptr_md5_2 ;
        +	ptr_zencod_md5_do_final = ptr_md5_3 ;
        +	ptr_zencod_sha1_init = ptr_sha1_1 ;
        +	ptr_zencod_sha1_update = ptr_sha1_2 ;
        +	ptr_zencod_sha1_do_final = ptr_sha1_3 ;
        +	ptr_zencod_xdes_cipher = ptr_xdes_1 ;
        +	ptr_zencod_rc4_cipher = ptr_rc4_1 ;
        +
        +	/* We should peform a test to see if there is actually any unit runnig on the system ...
        +	 * Even if the cryptozen library is loaded the module coul not be loaded on the system ...
        +	 * For now we may just open and close the device !!
        +	 */
        +
        +	if ( ptr_zencod_test () != 0 ) {
        +		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_UNIT_FAILURE ) ;
        +		goto err ;
        +	}
        +
        +	return 1 ;
        +err :
        +	if ( zencod_dso ) {
        +		DSO_free ( zencod_dso ) ;
        +	}
        +	zencod_dso = NULL ;
        +	ptr_zencod_bytes2bits = NULL ;
        +	ptr_zencod_bits2bytes = NULL ;
        +	ptr_zencod_new_number = NULL ;
        +	ptr_zencod_init_number = NULL ;
        +	ptr_zencod_rsa_mod_exp = NULL ;
        +	ptr_zencod_rsa_mod_exp_crt = NULL ;
        +	ptr_zencod_dsa_do_sign = NULL ;
        +	ptr_zencod_dsa_do_verify = NULL ;
        +	ptr_zencod_dh_generate_key = NULL ;
        +	ptr_zencod_dh_compute_key = NULL ;
        +	ptr_zencod_rand_bytes = NULL ;
        +	ptr_zencod_math_mod_exp = NULL ;
        +	ptr_zencod_test = NULL ;
        +	ptr_zencod_md5_init = NULL ;
        +	ptr_zencod_md5_update = NULL ;
        +	ptr_zencod_md5_do_final = NULL ;
        +	ptr_zencod_sha1_init = NULL ;
        +	ptr_zencod_sha1_update = NULL ;
        +	ptr_zencod_sha1_do_final = NULL ;
        +	ptr_zencod_xdes_cipher = NULL ;
        +	ptr_zencod_rc4_cipher = NULL ;
        +
        +	return 0 ;
        +}
        +
        +
        +static int zencod_finish ( ENGINE *e )
        +{
        +
        +	CHEESE () ;
        +
        +	/*
        +	 * We Should add some tests for non NULL parameters or bad value !!
        +	 * Stuff to be done ...
        +	 */
        +	if ( zencod_dso == NULL ) {
        +		ZENCODerr ( ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_NOT_LOADED ) ;
        +		return 0 ;
        +	}
        +	if ( !DSO_free ( zencod_dso ) ) {
        +		ZENCODerr ( ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_DSO_FAILURE ) ;
        +		return 0 ;
        +	}
        +
        +	zencod_dso = NULL ;
        +
        +	ptr_zencod_bytes2bits = NULL ;
        +	ptr_zencod_bits2bytes = NULL ;
        +	ptr_zencod_new_number = NULL ;
        +	ptr_zencod_init_number = NULL ;
        +	ptr_zencod_rsa_mod_exp = NULL ;
        +	ptr_zencod_rsa_mod_exp_crt = NULL ;
        +	ptr_zencod_dsa_do_sign = NULL ;
        +	ptr_zencod_dsa_do_verify = NULL ;
        +	ptr_zencod_dh_generate_key = NULL ;
        +	ptr_zencod_dh_compute_key = NULL ;
        +	ptr_zencod_rand_bytes = NULL ;
        +	ptr_zencod_math_mod_exp = NULL ;
        +	ptr_zencod_test = NULL ;
        +	ptr_zencod_md5_init = NULL ;
        +	ptr_zencod_md5_update = NULL ;
        +	ptr_zencod_md5_do_final = NULL ;
        +	ptr_zencod_sha1_init = NULL ;
        +	ptr_zencod_sha1_update = NULL ;
        +	ptr_zencod_sha1_do_final = NULL ;
        +	ptr_zencod_xdes_cipher = NULL ;
        +	ptr_zencod_rc4_cipher = NULL ;
        +
        +	return 1 ;
        +}
        +
        +
        +static int zencod_ctrl ( ENGINE *e, int cmd, long i, void *p, void (*f) () )
        +{
        +
        +	int initialised = ( ( zencod_dso == NULL ) ? 0 : 1 ) ;
        +
        +	CHEESE () ;
        +
        +	/*
        +	 * We Should add some tests for non NULL parameters or bad value !!
        +	 * Stuff to be done ...
        +	 */
        +	switch ( cmd ) {
        +	case ZENCOD_CMD_SO_PATH :
        +		if ( p == NULL ) {
        +			ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ERR_R_PASSED_NULL_PARAMETER ) ;
        +			return 0 ;
        +		}
        +		if ( initialised ) {
        +			ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_ALREADY_LOADED ) ;
        +			return 0 ;
        +		}
        +		ZENCOD_LIBNAME = (const char *) p ;
        +		return 1 ;
        +	default :
        +		break ;
        +	}
        +
        +	ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED ) ;
        +
        +	return 0 ;
        +}
        +
        +
        +/* BIGNUM stuff Functions
        + */
        +static int zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx )
        +{
        +	zen_nb_t y, x, e, n;
        +	int ret;
        +
        +	CHEESE () ;
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	if ( !bn_wexpand(r, m->top + 1) ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
        +		return 0;
        +	}
        +
        +	memset(r->d, 0, BN_num_bytes(m));
        +
        +	ptr_zencod_init_number ( &y, (r->dmax - 1) * sizeof (BN_ULONG) * 8, (unsigned char *) r->d ) ;
        +	BIGNUM2ZEN ( &x, a ) ;
        +	BIGNUM2ZEN ( &e, p ) ;
        +	BIGNUM2ZEN ( &n, m ) ;
        +
        +	/* Must invert x and e parameter due to BN mod exp prototype ... */
        +	ret = ptr_zencod_math_mod_exp ( &y, &e, &x, &n ) ;
        +
        +	if ( ret )  {
        +		PERROR("zenbridge_math_mod_exp");
        +		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
        +		return 0;
        +	}
        +
        +	r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;
        +
        +	return 1;
        +}
        +
        +
        +/* RSA stuff Functions
        + */
        +#ifndef OPENSSL_NO_RSA
        +static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *i, RSA *rsa )
        +{
        +
        +	CHEESE () ;
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	if ( !rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BAD_KEY_COMPONENTS);
        +		return 0;
        +	}
        +
        +	/* Do in software if argument is too large for hardware */
        +	if ( RSA_size(rsa) * 8 > ZENBRIDGE_MAX_KEYSIZE_RSA_CRT ) {
        +		const RSA_METHOD *meth;
        +
        +		meth = RSA_PKCS1_SSLeay();
        +		return meth->rsa_mod_exp(r0, i, rsa);
        +	} else {
        +		zen_nb_t y, x, p, q, dmp1, dmq1, iqmp;
        +
        +		if ( !bn_expand(r0, RSA_size(rsa) * 8) ) {
        +			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BN_EXPAND_FAIL);
        +			return 0;
        +		}
        +		r0->top = (RSA_size(rsa) * 8 + BN_BITS2 - 1) / BN_BITS2;
        +
        +		BIGNUM2ZEN ( &x, i ) ;
        +		BIGNUM2ZEN ( &y, r0 ) ;
        +		BIGNUM2ZEN ( &p, rsa->p ) ;
        +		BIGNUM2ZEN ( &q, rsa->q ) ;
        +		BIGNUM2ZEN ( &dmp1, rsa->dmp1 ) ;
        +		BIGNUM2ZEN ( &dmq1, rsa->dmq1 ) ;
        +		BIGNUM2ZEN ( &iqmp, rsa->iqmp ) ;
        +
        +		if ( ptr_zencod_rsa_mod_exp_crt ( &y, &x, &p, &q, &dmp1, &dmq1, &iqmp ) < 0 ) {
        +			PERROR("zenbridge_rsa_mod_exp_crt");
        +			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_REQUEST_FAILED);
        +			return 0;
        +		}
        +
        +		return 1;
        +	}
        +}
        +
        +
        +/* This function is aliased to RSA_mod_exp (with the mont stuff dropped).
        + */
        +static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx )
        +{
        +
        +	CHEESE () ;
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	/* Do in software if argument is too large for hardware */
        +	if ( BN_num_bits(m) > ZENBRIDGE_MAX_KEYSIZE_RSA ) {
        +		const RSA_METHOD *meth;
        +
        +		meth = RSA_PKCS1_SSLeay();
        +		return meth->bn_mod_exp(r, a, p, m, ctx, m_ctx);
        +	} else {
        +		zen_nb_t y, x, e, n;
        +
        +		if ( !bn_expand(r, BN_num_bits(m)) ) {
        +			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
        +			return 0;
        +		}
        +		r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;
        +
        +		BIGNUM2ZEN ( &x, a ) ;
        +		BIGNUM2ZEN ( &y, r ) ;
        +		BIGNUM2ZEN ( &e, p ) ;
        +		BIGNUM2ZEN ( &n, m ) ;
        +
        +		if ( ptr_zencod_rsa_mod_exp ( &y, &x, &n, &e ) < 0 ) {
        +			PERROR("zenbridge_rsa_mod_exp");
        +			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
        +			return 0;
        +		}
        +
        +		return 1;
        +	}
        +}
        +#endif /* !OPENSSL_NO_RSA */
        +
        +
        +#ifndef OPENSSL_NO_DSA
        +/* DSA stuff Functions
        + */
        +static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa )
        +{
        +	zen_nb_t p, q, g, x, y, r, s, data;
        +	DSA_SIG *sig;
        +	BIGNUM *bn_r = NULL;
        +	BIGNUM *bn_s = NULL;
        +	char msg[20];
        +
        +	CHEESE();
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_NOT_LOADED);
        +		goto FAILED;
        +	}
        +
        +	if ( dlen > 160 ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        +		goto FAILED;
        +	}
        +
        +	/* Do in software if argument is too large for hardware */
        +	if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
        +		BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) {
        +		const DSA_METHOD *meth;
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
        +		meth = DSA_OpenSSL();
        +		return meth->dsa_do_sign(dgst, dlen, dsa);
        +	}
        +
        +	if ( !(bn_s = BN_new()) || !(bn_r = BN_new()) ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
        +		goto FAILED;
        +	}
        +
        +	if ( !bn_expand(bn_r, 160) || !bn_expand(bn_s, 160) ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BN_EXPAND_FAIL);
        +		goto FAILED;
        +	}
        +
        +	bn_r->top = bn_s->top = (160 + BN_BITS2 - 1) / BN_BITS2;
        +	BIGNUM2ZEN ( &p, dsa->p ) ;
        +	BIGNUM2ZEN ( &q, dsa->q ) ;
        +	BIGNUM2ZEN ( &g, dsa->g ) ;
        +	BIGNUM2ZEN ( &x, dsa->priv_key ) ;
        +	BIGNUM2ZEN ( &y, dsa->pub_key ) ;
        +	BIGNUM2ZEN ( &r, bn_r ) ;
        +	BIGNUM2ZEN ( &s, bn_s ) ;
        +	q.len = x.len = 160;
        +
        +	ypcmem(msg, dgst, 20);
        +	ptr_zencod_init_number ( &data, 160, msg ) ;
        +
        +	if ( ptr_zencod_dsa_do_sign ( 0, &data, &y, &p, &q, &g, &x, &r, &s ) < 0 ) {
        +		PERROR("zenbridge_dsa_do_sign");
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        +		goto FAILED;
        +	}
        +
        +	if ( !( sig = DSA_SIG_new () ) ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        +		goto FAILED;
        +	}
        +	sig->r = bn_r;
        +	sig->s = bn_s;
        +	return sig;
        +
        + FAILED:
        +	if (bn_r)
        +		BN_free(bn_r);
        +	if (bn_s)
        +		BN_free(bn_s);
        +	return NULL;
        +}
        +
        +
        +static int DSA_zencod_do_verify ( const unsigned char *dgst, int dlen, DSA_SIG *sig, DSA *dsa )
        +{
        +	zen_nb_t data, p, q, g, y, r, s, v;
        +	char msg[20];
        +	char v_data[20];
        +	int ret;
        +
        +	CHEESE();
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	if ( dlen > 160 ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        +		return 0;
        +	}
        +
        +	/* Do in software if argument is too large for hardware */
        +	if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
        +		BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) {
        +		const DSA_METHOD *meth;
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
        +		meth = DSA_OpenSSL();
        +		return meth->dsa_do_verify(dgst, dlen, sig, dsa);
        +	}
        +
        +	BIGNUM2ZEN ( &p, dsa->p ) ;
        +	BIGNUM2ZEN ( &q, dsa->q ) ;
        +	BIGNUM2ZEN ( &g, dsa->g ) ;
        +	BIGNUM2ZEN ( &y, dsa->pub_key ) ;
        +	BIGNUM2ZEN ( &r, sig->r ) ;
        +	BIGNUM2ZEN ( &s, sig->s ) ;
        +	ptr_zencod_init_number ( &v, 160, v_data ) ;
        +	ypcmem(msg, dgst, 20);
        +	ptr_zencod_init_number ( &data, 160, msg ) ;
        +
        +	if ( ( ret = ptr_zencod_dsa_do_verify ( 0, &data, &p, &q, &g, &y, &r, &s, &v ) ) < 0 ) {
        +		PERROR("zenbridge_dsa_do_verify");
        +		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_REQUEST_FAILED);
        +		return 0;
        +	}
        +
        +	return ( ( ret == 0 ) ? 1 : ret ) ;
        +}
        +
        +
        +static int DSA_zencod_bn_mod_exp ( DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
        +			     BN_CTX *ctx, BN_MONT_CTX *m_ctx )
        +{
        +	CHEESE () ;
        +
        +	return zencod_bn_mod_exp ( r, a, p, m, ctx ) ;
        +}
        +#endif /* !OPENSSL_NO_DSA */
        +
        +
        +#ifndef OPENSSl_NO_DH
        +/* DH stuff Functions
        + */
        +static int DH_zencod_generate_key ( DH *dh )
        +{
        +	BIGNUM *bn_prv = NULL;
        +	BIGNUM *bn_pub = NULL;
        +	zen_nb_t y, x, g, p;
        +	int generate_x;
        +
        +	CHEESE();
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	/* Private key */
        +	if ( dh->priv_key ) {
        +		bn_prv = dh->priv_key;
        +		generate_x = 0;
        +	} else {
        +		if (!(bn_prv = BN_new())) {
        +			ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
        +			goto FAILED;
        +		}
        +		generate_x = 1;
        +	}
        +
        +	/* Public key */
        +	if ( dh->pub_key )
        +		bn_pub = dh->pub_key;
        +	else
        +		if ( !( bn_pub = BN_new () ) ) {
        +			ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
        +			goto FAILED;
        +		}
        +
        +	/* Expand */
        +	if ( !bn_wexpand ( bn_prv, dh->p->dmax ) ||
        +	    !bn_wexpand ( bn_pub, dh->p->dmax ) ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
        +		goto FAILED;
        +	}
        +	bn_prv->top = dh->p->top;
        +	bn_pub->top = dh->p->top;
        +
        +	/* Convert all keys */
        +	BIGNUM2ZEN ( &p, dh->p ) ;
        +	BIGNUM2ZEN ( &g, dh->g ) ;
        +	BIGNUM2ZEN ( &y, bn_pub ) ;
        +	BIGNUM2ZEN ( &x, bn_prv ) ;
        +	x.len = DH_size(dh) * 8;
        +
        +	/* Adjust the lengths of P and G */
        +	p.len = ptr_zencod_bytes2bits ( p.data, ZEN_BYTES ( p.len ) ) ;
        +	g.len = ptr_zencod_bytes2bits ( g.data, ZEN_BYTES ( g.len ) ) ;
        +
        +	/* Send the request to the driver */
        +	if ( ptr_zencod_dh_generate_key ( &y, &x, &g, &p, generate_x ) < 0 ) {
        +		perror("zenbridge_dh_generate_key");
        +		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_REQUEST_FAILED);
        +		goto FAILED;
        +	}
        +
        +	dh->priv_key = bn_prv;
        +	dh->pub_key  = bn_pub;
        +
        +	return 1;
        +
        + FAILED:
        +	if (!dh->priv_key && bn_prv)
        +		BN_free(bn_prv);
        +	if (!dh->pub_key && bn_pub)
        +		BN_free(bn_pub);
        +
        +	return 0;
        +}
        +
        +
        +static int DH_zencod_compute_key ( unsigned char *key, const BIGNUM *pub_key, DH *dh )
        +{
        +	zen_nb_t y, x, p, k;
        +
        +	CHEESE();
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	if ( !dh->priv_key ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_BAD_KEY_COMPONENTS);
        +		return 0;
        +	}
        +
        +	/* Convert all keys */
        +	BIGNUM2ZEN ( &y, pub_key ) ;
        +	BIGNUM2ZEN ( &x, dh->priv_key ) ;
        +	BIGNUM2ZEN ( &p, dh->p ) ;
        +	ptr_zencod_init_number ( &k, p.len, key ) ;
        +
        +	/* Adjust the lengths */
        +	p.len = ptr_zencod_bytes2bits ( p.data, ZEN_BYTES ( p.len ) ) ;
        +	y.len = ptr_zencod_bytes2bits ( y.data, ZEN_BYTES ( y.len ) ) ;
        +	x.len = ptr_zencod_bytes2bits ( x.data, ZEN_BYTES ( x.len ) ) ;
        +
        +	/* Call the hardware */
        +	if ( ptr_zencod_dh_compute_key ( &k, &y, &x, &p ) < 0 ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_REQUEST_FAILED);
        +		return 0;
        +	}
        +
        +	/* The key must be written MSB -> LSB */
        +	k.len = ptr_zencod_bytes2bits ( k.data, ZEN_BYTES ( k.len ) ) ;
        +	esrever ( key, ZEN_BYTES ( k.len ) ) ;
        +
        +	return ZEN_BYTES ( k.len ) ;
        +}
        +
        +
        +static int DH_zencod_bn_mod_exp ( const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx )
        +{
        +	CHEESE () ;
        +
        +	return zencod_bn_mod_exp ( r, a, p, m, ctx ) ;
        +}
        +#endif	/* !OPENSSL_NO_DH */
        +
        +
        +/* RAND stuff Functions
        + */
        +static void RAND_zencod_seed ( const void *buf, int num )
        +{
        +	/* Nothing to do cause our crypto accelerator provide a true random generator */
        +}
        +
        +
        +static int RAND_zencod_rand_bytes ( unsigned char *buf, int num )
        +{
        +	zen_nb_t r;
        +
        +	CHEESE();
        +
        +	if ( !zencod_dso ) {
        +		ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	ptr_zencod_init_number ( &r, num * 8, buf ) ;
        +
        +	if ( ptr_zencod_rand_bytes ( &r, ZENBRIDGE_RNG_DIRECT ) < 0 ) {
        +		PERROR("zenbridge_rand_bytes");
        +		ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_REQUEST_FAILED);
        +		return 0;
        +	}
        +
        +	return 1;
        +}
        +
        +
        +static int RAND_zencod_rand_status ( void )
        +{
        +	CHEESE () ;
        +
        +	return 1;
        +}
        +
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library.
        + */
        +#ifdef ENGINE_DYNAMIC_SUPPORT
        +static int bind_fn ( ENGINE *e, const char *id )
        +{
        +
        +	if ( id && ( strcmp ( id, engine_zencod_id ) != 0 ) ) {
        +		return 0 ;
        +	}
        +	if ( !bind_helper ( e ) )  {
        +		return 0 ;
        +	}
        +
        +	return 1 ;
        +}
        +
        +IMPLEMENT_DYNAMIC_CHECK_FN ()
        +IMPLEMENT_DYNAMIC_BIND_FN ( bind_fn )
        +#endif /* ENGINE_DYNAMIC_SUPPORT */
        +
        +
        +
        +
        +/*
        + * Adding "Digest" and "Cipher" tools ...
        + * This is in development ... ;-)
        + * In orfer to code this, i refer to hw_openbsd_dev_crypto and openssl engine made by Geoff Thorpe (if i'm rigth),
        + * and evp, sha md5 definitions etc ...
        + */
        +/* First add some include ... */
        +#include <openssl/evp.h>
        +#include <openssl/sha.h>
        +#include <openssl/md5.h>
        +#include <openssl/rc4.h>
        +#include <openssl/des.h>
        +
        +
        +/* Some variables declaration ... */
        +/* DONS:
        + * Disable symetric computation except DES and 3DES, but let part of the code
        + */
        +/* static int engine_digest_nids [ ] = { NID_sha1, NID_md5 } ; */
        +static int engine_digest_nids [ ] = {  } ;
        +static int engine_digest_nids_num = 0 ;
        +/* static int engine_cipher_nids [ ] = { NID_rc4, NID_rc4_40, NID_des_cbc, NID_des_ede3_cbc } ; */
        +static int engine_cipher_nids [ ] = { NID_des_cbc, NID_des_ede3_cbc } ;
        +static int engine_cipher_nids_num = 2 ;
        +
        +
        +/* Function prototype ... */
        +/*  SHA stuff */
        +static int engine_sha1_init ( EVP_MD_CTX *ctx ) ;
        +static int engine_sha1_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count ) ;
        +static int engine_sha1_final ( EVP_MD_CTX *ctx, unsigned char *md ) ;
        +
        +/*  MD5 stuff */
        +static int engine_md5_init ( EVP_MD_CTX *ctx ) ;
        +static int engine_md5_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count ) ;
        +static int engine_md5_final ( EVP_MD_CTX *ctx, unsigned char *md ) ;
        +
        +static int engine_md_cleanup ( EVP_MD_CTX *ctx ) ;
        +static int engine_md_copy ( EVP_MD_CTX *to, const EVP_MD_CTX *from ) ;
        +
        +
        +/* RC4 Stuff */
        +static int engine_rc4_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
        +static int engine_rc4_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl ) ;
        +
        +/* DES Stuff */
        +static int engine_des_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
        +static int engine_des_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl ) ;
        +
        +/*  3DES Stuff */
        +static int engine_des_ede3_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
        +static int engine_des_ede3_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out,const unsigned char *in, unsigned int inl ) ;
        +
        +static int engine_cipher_cleanup ( EVP_CIPHER_CTX *ctx ) ;	/* cleanup ctx */
        +
        +
        +/* The one for SHA ... */
        +static const EVP_MD engine_sha1_md =
        +{
        +	NID_sha1,
        +	NID_sha1WithRSAEncryption,
        +	SHA_DIGEST_LENGTH,
        +	EVP_MD_FLAG_ONESHOT,
        +	/* 0, */			/* EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block
        +				* XXX: set according to device info ... */
        +	engine_sha1_init,
        +	engine_sha1_update,
        +	engine_sha1_final,
        +	engine_md_copy,		/* dev_crypto_sha_copy */
        +	engine_md_cleanup,		/* dev_crypto_sha_cleanup */
        +	EVP_PKEY_RSA_method,
        +	SHA_CBLOCK,
        +	/* sizeof ( EVP_MD * ) + sizeof ( SHA_CTX ) */
        +	sizeof ( ZEN_MD_DATA )
        +	/* sizeof ( MD_CTX_DATA )	The message digest data structure ... */
        +} ;
        +
        +/* The one for MD5 ... */
        +static const EVP_MD engine_md5_md =
        +{
        +	NID_md5,
        +	NID_md5WithRSAEncryption,
        +	MD5_DIGEST_LENGTH,
        +	EVP_MD_FLAG_ONESHOT,
        +	/* 0, */			/* EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block
        +				* XXX: set according to device info ... */
        +	engine_md5_init,
        +	engine_md5_update,
        +	engine_md5_final,
        +	engine_md_copy,		/* dev_crypto_md5_copy */
        +	engine_md_cleanup,		/* dev_crypto_md5_cleanup */
        +	EVP_PKEY_RSA_method,
        +	MD5_CBLOCK,
        +	/* sizeof ( EVP_MD * ) + sizeof ( MD5_CTX ) */
        +	sizeof ( ZEN_MD_DATA )
        +	/* sizeof ( MD_CTX_DATA )	The message digest data structure ... */
        +} ;
        +
        +
        +/* The one for RC4 ... */
        +#define EVP_RC4_KEY_SIZE			16
        +
        +/* Try something static ... */
        +typedef struct
        +{
        +	unsigned int len ;
        +	unsigned int first ;
        +	unsigned char rc4_state [ 260 ] ;
        +} NEW_ZEN_RC4_KEY ;
        +
        +#define rc4_data(ctx)				( (EVP_RC4_KEY *) ( ctx )->cipher_data )
        +
        +static const EVP_CIPHER engine_rc4 =
        +{
        +	NID_rc4,
        +	1,
        +	16,				/* EVP_RC4_KEY_SIZE should be 128 bits */
        +	0,				/* FIXME: key should be up to 256 bytes */
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	engine_rc4_init_key,
        +	engine_rc4_cipher,
        +	engine_cipher_cleanup,
        +	sizeof ( NEW_ZEN_RC4_KEY ),
        +	NULL,
        +	NULL,
        +	NULL
        +} ;
        +
        +/* The one for RC4_40 ... */
        +static const EVP_CIPHER engine_rc4_40 =
        +{
        +	NID_rc4_40,
        +	1,
        +	5,				/* 40 bits */
        +	0,
        +	EVP_CIPH_VARIABLE_LENGTH,
        +	engine_rc4_init_key,
        +	engine_rc4_cipher,
        +	engine_cipher_cleanup,
        +	sizeof ( NEW_ZEN_RC4_KEY ),
        +	NULL,
        +	NULL,
        +	NULL
        +} ;
        +
        +/* The one for DES ... */
        +
        +/* Try something static ... */
        +typedef struct
        +{
        +	unsigned char des_key [ 24 ] ;
        +	unsigned char des_iv [ 8 ] ;
        +} ZEN_DES_KEY ;
        +
        +static const EVP_CIPHER engine_des_cbc =
        +	{
        +	NID_des_cbc,
        +	8, 8, 8,
        +	0 | EVP_CIPH_CBC_MODE,
        +	engine_des_init_key,
        +	engine_des_cbc_cipher,
        +	engine_cipher_cleanup,
        +	sizeof(ZEN_DES_KEY),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL,
        +	NULL
        +	};
        +
        +/* The one for 3DES ... */
        +
        +/* Try something static ... */
        +typedef struct
        +{
        +	unsigned char des3_key [ 24 ] ;
        +	unsigned char des3_iv [ 8 ] ;
        +} ZEN_3DES_KEY ;
        +
        +#define des_data(ctx)				 ( (DES_EDE_KEY *) ( ctx )->cipher_data )
        +
        +static const EVP_CIPHER engine_des_ede3_cbc =
        +	{
        +	NID_des_ede3_cbc,
        +	8, 8, 8,
        +	0 | EVP_CIPH_CBC_MODE,
        +	engine_des_ede3_init_key,
        +	engine_des_ede3_cbc_cipher,
        +	engine_cipher_cleanup,
        +	sizeof(ZEN_3DES_KEY),
        +	EVP_CIPHER_set_asn1_iv,
        +	EVP_CIPHER_get_asn1_iv,
        +	NULL,
        +	NULL
        +	};
        +
        +
        +/* General function cloned on hw_openbsd_dev_crypto one ... */
        +static int engine_digests ( ENGINE *e, const EVP_MD **digest, const int **nids, int nid )
        +{
        +
        +#ifdef DEBUG_ZENCOD_MD
        +	fprintf ( stderr, "\t=>Function : static int engine_digests () called !\n" ) ;
        +#endif
        +
        +	if ( !digest ) {
        +		/* We are returning a list of supported nids */
        +		*nids = engine_digest_nids ;
        +		return engine_digest_nids_num ;
        +	}
        +	/* We are being asked for a specific digest */
        +	if ( nid == NID_md5 ) {
        +		*digest = &engine_md5_md ;
        +	}
        +	else if ( nid == NID_sha1 ) {
        +		*digest = &engine_sha1_md ;
        +	}
        +	else {
        +		*digest = NULL ;
        +		return 0 ;
        +	}
        +	return 1 ;
        +}
        +
        +
        +/* SHA stuff Functions
        + */
        +static int engine_sha1_init ( EVP_MD_CTX *ctx )
        +{
        +
        +	int to_return = 0 ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_sha1_init ( (ZEN_MD_DATA *) ctx->md_data ) ;
        +	to_return = !to_return ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_sha1_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count )
        +{
        +
        +	zen_nb_t input ;
        +	int to_return = 0 ;
        +
        +	/* Convert parameters ... */
        +	input.len = count ;
        +	input.data = (unsigned char *) data ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_sha1_update ( (ZEN_MD_DATA *) ctx->md_data, (const zen_nb_t *) &input ) ;
        +	to_return = !to_return ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_sha1_final ( EVP_MD_CTX *ctx, unsigned char *md )
        +{
        +
        +	zen_nb_t output ;
        +	int to_return = 0 ;
        +
        +	/* Convert parameters ... */
        +	output.len = SHA_DIGEST_LENGTH ;
        +	output.data = md ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_sha1_do_final ( (ZEN_MD_DATA *) ctx->md_data, (zen_nb_t *) &output ) ;
        +	to_return = !to_return ;
        +
        +	return to_return ;
        +}
        +
        +
        +
        +/* MD5 stuff Functions
        + */
        +static int engine_md5_init ( EVP_MD_CTX *ctx )
        +{
        +
        +	int to_return = 0 ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_md5_init ( (ZEN_MD_DATA *) ctx->md_data ) ;
        +	to_return = !to_return ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_md5_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count )
        +{
        +
        +	zen_nb_t input ;
        +	int to_return = 0 ;
        +
        +	/* Convert parameters ... */
        +	input.len = count ;
        +	input.data = (unsigned char *) data ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_md5_update ( (ZEN_MD_DATA *) ctx->md_data, (const zen_nb_t *) &input ) ;
        +	to_return = !to_return ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_md5_final ( EVP_MD_CTX *ctx, unsigned char *md )
        +{
        +
        +	zen_nb_t output ;
        +	int to_return = 0 ;
        +
        +	/* Convert parameters ... */
        +	output.len = MD5_DIGEST_LENGTH ;
        +	output.data = md ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_md5_do_final ( (ZEN_MD_DATA *) ctx->md_data, (zen_nb_t *) &output ) ;
        +	to_return = !to_return ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_md_cleanup ( EVP_MD_CTX *ctx )
        +{
        +
        +	ZEN_MD_DATA *zen_md_data = (ZEN_MD_DATA *) ctx->md_data ;
        +
        +	if ( zen_md_data->HashBuffer != NULL ) {
        +		OPENSSL_free ( zen_md_data->HashBuffer ) ;
        +		zen_md_data->HashBufferSize = 0 ;
        +		ctx->md_data = NULL ;
        +	}
        +
        +	return 1 ;
        +}
        +
        +
        +static int engine_md_copy ( EVP_MD_CTX *to, const EVP_MD_CTX *from )
        +{
        +	const ZEN_MD_DATA *from_md = (ZEN_MD_DATA *) from->md_data ;
        +	ZEN_MD_DATA *to_md = (ZEN_MD_DATA *) to->md_data ;
        +
        +	to_md->HashBuffer = OPENSSL_malloc ( from_md->HashBufferSize ) ;
        +	memcpy ( to_md->HashBuffer, from_md->HashBuffer, from_md->HashBufferSize ) ;
        +
        +	return 1;
        +}
        +
        +
        +/* General function cloned on hw_openbsd_dev_crypto one ... */
        +static int engine_ciphers ( ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid )
        +{
        +
        +	if ( !cipher ) {
        +		/* We are returning a list of supported nids */
        +		*nids = engine_cipher_nids ;
        +		return engine_cipher_nids_num ;
        +	}
        +	/* We are being asked for a specific cipher */
        +	if ( nid == NID_rc4 ) {
        +		*cipher = &engine_rc4 ;
        +	}
        +	else if ( nid == NID_rc4_40 ) {
        +		*cipher = &engine_rc4_40 ;
        +	}
        +	else if ( nid == NID_des_cbc ) {
        +		*cipher = &engine_des_cbc ;
        +	}
        +	else if ( nid == NID_des_ede3_cbc ) {
        +		*cipher = &engine_des_ede3_cbc ;
        +	}
        +	else {
        +		*cipher = NULL ;
        +		return 0 ;
        +	}
        +
        +	return 1 ;
        +}
        +
        +
        +static int engine_rc4_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
        +{
        +	int to_return = 0 ;
        +	int i = 0 ;
        +	int nb = 0 ;
        +	NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL ;
        +
        +	tmp_rc4_key = (NEW_ZEN_RC4_KEY *) ( ctx->cipher_data ) ;
        +	tmp_rc4_key->first = 0 ;
        +	tmp_rc4_key->len = ctx->key_len ;
        +	tmp_rc4_key->rc4_state [ 0 ] = 0x00 ;
        +	tmp_rc4_key->rc4_state [ 2 ] = 0x00 ;
        +	nb = 256 / ctx->key_len ;
        +	for ( i = 0; i < nb ; i++ ) {
        +		memcpy ( &( tmp_rc4_key->rc4_state [ 4 + i*ctx->key_len ] ), key, ctx->key_len ) ;
        +	}
        +
        +	to_return = 1 ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_rc4_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int in_len )
        +{
        +
        +	zen_nb_t output, input ;
        +	zen_nb_t rc4key ;
        +	int to_return = 0 ;
        +	NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL ;
        +
        +	/* Convert parameters ... */
        +	input.len = in_len ;
        +	input.data = (unsigned char *) in ;
        +	output.len = in_len ;
        +	output.data = (unsigned char *) out ;
        +
        +	tmp_rc4_key = ( (NEW_ZEN_RC4_KEY *) ( ctx->cipher_data ) ) ;
        +	rc4key.len = 260 ;
        +	rc4key.data = &( tmp_rc4_key->rc4_state [ 0 ] ) ;
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_rc4_cipher ( &output, &input, (const zen_nb_t *) &rc4key, &( tmp_rc4_key->rc4_state [0] ), &( tmp_rc4_key->rc4_state [3] ), !tmp_rc4_key->first ) ;
        +	to_return = !to_return ;
        +
        +	/* Update encryption state ... */
        +	tmp_rc4_key->first = 1 ;
        +	tmp_rc4_key = NULL ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_des_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
        +{
        +
        +	ZEN_DES_KEY *tmp_des_key = NULL ;
        +	int to_return = 0 ;
        +
        +	tmp_des_key = (ZEN_DES_KEY *) ( ctx->cipher_data ) ;
        +	memcpy ( &( tmp_des_key->des_key [ 0 ] ), key, 8 ) ;
        +	memcpy ( &( tmp_des_key->des_key [ 8 ] ), key, 8 ) ;
        +	memcpy ( &( tmp_des_key->des_key [ 16 ] ), key, 8 ) ;
        +	memcpy ( &( tmp_des_key->des_iv [ 0 ] ), iv, 8 ) ;
        +
        +	to_return = 1 ;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_des_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl )
        +{
        +
        +	zen_nb_t output, input ;
        +	zen_nb_t deskey_1, deskey_2, deskey_3, iv ;
        +	int to_return = 0 ;
        +
        +	/* Convert parameters ... */
        +	input.len = inl ;
        +	input.data = (unsigned char *) in ;
        +	output.len = inl ;
        +	output.data = out ;
        +
        +	/* Set key parameters ... */
        +	deskey_1.len = 8 ;
        +	deskey_2.len = 8 ;
        +	deskey_3.len = 8 ;
        +	deskey_1.data = (unsigned char *) ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key ;
        +	deskey_2.data =  (unsigned char *) &( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key [ 8 ] ;
        +	deskey_3.data =  (unsigned char *) &( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key [ 16 ] ;
        +
        +	/* Key correct iv ... */
        +	memcpy ( ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_iv, ctx->iv, 8 ) ;
        +	iv.len = 8 ;
        +	iv.data = (unsigned char *) ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_iv ;
        +
        +	if ( ctx->encrypt == 0 ) {
        +		memcpy ( ctx->iv, &( input.data [ input.len - 8 ] ), 8 ) ;
        +	}
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_xdes_cipher ( &output, &input,
        +			(zen_nb_t *) &deskey_1, (zen_nb_t *) &deskey_2, (zen_nb_t *) &deskey_3, &iv, ctx->encrypt ) ;
        +	to_return = !to_return ;
        +
        +	/* But we need to set up the rigth iv ...
        +	 * Test ENCRYPT or DECRYPT mode to set iv ... */
        +	if ( ctx->encrypt == 1 ) {
        +		memcpy ( ctx->iv, &( output.data [ output.len - 8 ] ), 8 ) ;
        +	}
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_des_ede3_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
        +{
        +
        +	ZEN_3DES_KEY *tmp_3des_key = NULL ;
        +	int to_return = 0 ;
        +
        +	tmp_3des_key = (ZEN_3DES_KEY *) ( ctx->cipher_data ) ;
        +	memcpy ( &( tmp_3des_key->des3_key [ 0 ] ), key, 24 ) ;
        +	memcpy ( &( tmp_3des_key->des3_iv [ 0 ] ), iv, 8 ) ;
        +
        +	to_return = 1;
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_des_ede3_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
        +	unsigned int in_len )
        +{
        +
        +	zen_nb_t output, input ;
        +	zen_nb_t deskey_1, deskey_2, deskey_3, iv ;
        +	int to_return = 0 ;
        +
        +	/* Convert parameters ... */
        +	input.len = in_len ;
        +	input.data = (unsigned char *) in ;
        +	output.len = in_len ;
        +	output.data = out ;
        +
        +	/* Set key ... */
        +	deskey_1.len = 8 ;
        +	deskey_2.len = 8 ;
        +	deskey_3.len = 8 ;
        +	deskey_1.data =  (unsigned char *) ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key ;
        +	deskey_2.data =  (unsigned char *) &( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key [ 8 ] ;
        +	deskey_3.data =  (unsigned char *) &( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key [ 16 ] ;
        +
        +	/* Key correct iv ... */
        +	memcpy ( ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_iv, ctx->iv, 8 ) ;
        +	iv.len = 8 ;
        +	iv.data = (unsigned char *) ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_iv ;
        +
        +	if ( ctx->encrypt == 0 ) {
        +		memcpy ( ctx->iv, &( input.data [ input.len - 8 ] ), 8 ) ;
        +	}
        +
        +	/* Test with zenbridge library ... */
        +	to_return = ptr_zencod_xdes_cipher ( &output, &input,
        +			(zen_nb_t *) &deskey_1, (zen_nb_t *) &deskey_2, (zen_nb_t *) &deskey_3, &iv, ctx->encrypt ) ;
        +	to_return = !to_return ;
        +
        +	if ( ctx->encrypt == 1 ) {
        +		memcpy ( ctx->iv, &( output.data [ output.len - 8 ] ), 8 ) ;
        +	}
        +
        +	return to_return ;
        +}
        +
        +
        +static int engine_cipher_cleanup ( EVP_CIPHER_CTX *ctx )
        +{
        +
        +	/* Set the key pointer ... */
        +	if ( ctx->cipher->nid == NID_rc4 || ctx->cipher->nid == NID_rc4_40 ) {
        +	}
        +	else if ( ctx->cipher->nid == NID_des_cbc ) {
        +	}
        +	else if ( ctx->cipher->nid == NID_des_ede3_cbc ) {
        +	}
        +
        +	return 1 ;
        +}
        +
        +
        +#endif /* !OPENSSL_NO_HW_ZENCOD */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.ec b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.ec
        new file mode 100644
        index 000000000..1552c79be
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.ec
        @@ -0,0 +1,8 @@
        +# configuration file for util/mkerr.pl
        +#
        +# use like this:
        +#
        +#	perl ../../../util/mkerr.pl -conf hw_zencod.ec \
        +#		-nostatic -staticloader -write *.c
        +
        +L ZENCOD	hw_zencod_err.h			hw_zencod_err.c
        diff --git a/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.h b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.h
        new file mode 100644
        index 000000000..415c9a6be
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod.h
        @@ -0,0 +1,160 @@
        +/* File : /crypto/engine/vendor_defns/hw_zencod.h */
        +/* ====================================================================
        + * Written by Donnat Frederic (frederic.donnat@zencod.com) from ZENCOD
        + * for "zencod" ENGINE integration in OpenSSL project.
        + */
        +
        +
        + #ifndef	_HW_ZENCOD_H_
        +#define	_HW_ZENCOD_H_
        +
        +#include <stdio.h>
        +
        +#ifdef	__cplusplus
        +extern "C" {
        +#endif	/* __cplusplus */
        +
        +#define ZENBRIDGE_MAX_KEYSIZE_RSA	2048
        +#define ZENBRIDGE_MAX_KEYSIZE_RSA_CRT	1024
        +#define ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN	1024
        +#define ZENBRIDGE_MAX_KEYSIZE_DSA_VRFY	1024
        +
        +/* Library version computation */
        +#define	ZENBRIDGE_VERSION_MAJOR(x)	(((x) >> 16) | 0xff)
        +#define	ZENBRIDGE_VERSION_MINOR(x)	(((x) >>  8) | 0xff)
        +#define	ZENBRIDGE_VERSION_PATCH(x)	(((x) >>  0) | 0xff)
        +#define	ZENBRIDGE_VERSION(x, y, z)		((x) << 16 | (y) << 8 | (z))
        +
        +/*
        + * Memory type
        + */
        +typedef struct zencod_number_s {
        +	unsigned long len;
        +	unsigned char *data;
        +} zen_nb_t;
        +
        +#define KEY	zen_nb_t
        +
        +
        +/*
        + * Misc
        + */
        +typedef int t_zencod_lib_version (void);
        +typedef int t_zencod_hw_version (void);
        +typedef int t_zencod_test (void);
        +typedef int t_zencod_dump_key (FILE *stream, char *msg, KEY *key);
        +
        +
        +/*
        + * Key management tools
        + */
        +typedef KEY *t_zencod_new_number (unsigned long len, unsigned char *data);
        +typedef int t_zencod_init_number (KEY *n, unsigned long len, unsigned char *data);
        +typedef unsigned long t_zencod_bytes2bits (unsigned char *n, unsigned long bytes);
        +typedef unsigned long t_zencod_bits2bytes (unsigned long bits);
        +
        +
        +/*
        + * RSA API
        + */
        +/* Compute modular exponential : y = x**e | n */
        +typedef int t_zencod_rsa_mod_exp (KEY *y, KEY *x, KEY *n, KEY *e);
        +/* Compute modular exponential : y1 = (x | p)**edp | p, y2 = (x | p)**edp | p, y = y2 + (qinv * (y1 - y2) | p) * q */
        +typedef int t_zencod_rsa_mod_exp_crt (KEY *y, KEY *x, KEY *p, KEY *q,
        +					KEY *edp, KEY *edq, KEY *qinv);
        +
        +
        +/*
        + * DSA API
        + */
        +typedef int t_zencod_dsa_do_sign (unsigned int hash, KEY *data, KEY *random,
        +				    KEY *p, KEY *q, KEY *g, KEY *x, KEY *r, KEY *s);
        +typedef int t_zencod_dsa_do_verify (unsigned int hash, KEY *data,
        +				      KEY *p, KEY *q, KEY *g, KEY *y,
        +				      KEY *r, KEY *s, KEY *v);
        +
        +
        +/*
        + * DH API
        + */
        + /* Key generation : compute public value y = g**x | n */
        +typedef int t_zencod_dh_generate_key (KEY *y, KEY *x, KEY *g, KEY *n, int gen_x);
        +typedef int t_zencod_dh_compute_key (KEY *k, KEY *y, KEY *x, KEY *n);
        +
        +
        +/*
        + * RNG API
        + */
        +#define ZENBRIDGE_RNG_DIRECT		0
        +#define ZENBRIDGE_RNG_SHA1		1
        +typedef int t_zencod_rand_bytes (KEY *rand, unsigned int flags);
        +
        +
        +/*
        + * Math API
        + */
        +typedef int t_zencod_math_mod_exp (KEY *r, KEY *a, KEY *e, KEY *n);
        +
        +
        +
        +
        +/*
        + * Symetric API
        + */
        +/* Define a data structure for digests operations */
        +typedef struct ZEN_data_st
        +{
        +	unsigned int HashBufferSize ;
        +	unsigned char *HashBuffer ;
        +} ZEN_MD_DATA ;
        +
        +/*
        + * Functions for Digest (MD5, SHA1) stuff
        + */
        +/* output : output data buffer */
        +/* input : input data buffer */
        +/* algo : hash algorithm, MD5 or SHA1 */
        +/* typedef int t_zencod_hash ( KEY *output, const KEY *input, int algo ) ;
        + * typedef int t_zencod_sha_hash ( KEY *output, const KEY *input, int algo ) ;
        + */
        +/* For now separate this stuff that mad it easier to test */
        +typedef int t_zencod_md5_init ( ZEN_MD_DATA *data ) ;
        +typedef int t_zencod_md5_update ( ZEN_MD_DATA *data, const KEY *input ) ;
        +typedef int t_zencod_md5_do_final ( ZEN_MD_DATA *data, KEY *output ) ;
        +
        +typedef int t_zencod_sha1_init ( ZEN_MD_DATA *data ) ;
        +typedef int t_zencod_sha1_update ( ZEN_MD_DATA *data, const KEY *input ) ;
        +typedef int t_zencod_sha1_do_final ( ZEN_MD_DATA *data, KEY *output ) ;
        +
        +
        +/*
        + * Functions for Cipher (RC4, DES, 3DES) stuff
        + */
        +/* output : output data buffer */
        +/* input : input data buffer */
        +/* key : rc4 key data */
        +/* index_1 : value of index x from RC4 key structure */
        +/* index_2 : value of index y from RC4 key structure */
        +/* Be carefull : RC4 key should be expanded before calling this method (Should we provide an expand function ??) */
        +typedef int t_zencod_rc4_cipher ( KEY *output, const KEY *input, const KEY *key,
        +		unsigned char *index_1, unsigned char *index_2, int mode ) ;
        +
        +/* output : output data buffer */
        +/* input : input data buffer */
        +/* key_1 : des first key data */
        +/* key_2 : des second key data */
        +/* key_3 : des third key data */
        +/* iv : initial vector */
        +/* mode : xdes mode (encrypt or decrypt) */
        +/* Be carefull : In DES mode key_1 = key_2 = key_3 (as far as i can see !!) */
        +typedef int t_zencod_xdes_cipher ( KEY *output, const KEY *input, const KEY *key_1,
        +		const KEY *key_2, const KEY *key_3, const KEY *iv, int mode ) ;
        +
        +
        +#undef KEY
        +
        +#ifdef	__cplusplus
        +}
        +#endif	/* __cplusplus */
        +
        +#endif	/* !_HW_ZENCOD_H_ */
        diff --git a/vendor/openssl/openssl/demos/engines/zencod/hw_zencod_err.c b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod_err.c
        new file mode 100644
        index 000000000..8ed0fffc9
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod_err.c
        @@ -0,0 +1,151 @@
        +/* hw_zencod_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <openssl/err.h>
        +#include "hw_zencod_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +static ERR_STRING_DATA ZENCOD_str_functs[]=
        +	{
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_BN_MOD_EXP,0),	"ZENCOD_BN_MOD_EXP"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_CTRL,0),	"ZENCOD_CTRL"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_DH_COMPUTE,0),	"ZENCOD_DH_COMPUTE"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_DH_GENERATE,0),	"ZENCOD_DH_GENERATE"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_DSA_DO_SIGN,0),	"ZENCOD_DSA_DO_SIGN"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_DSA_DO_VERIFY,0),	"ZENCOD_DSA_DO_VERIFY"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_FINISH,0),	"ZENCOD_FINISH"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_INIT,0),	"ZENCOD_INIT"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_RAND,0),	"ZENCOD_RAND"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_RSA_MOD_EXP,0),	"ZENCOD_RSA_MOD_EXP"},
        +{ERR_PACK(0,ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT,0),	"ZENCOD_RSA_MOD_EXP_CRT"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ZENCOD_str_reasons[]=
        +	{
        +{ZENCOD_R_ALREADY_LOADED                 ,"already loaded"},
        +{ZENCOD_R_BAD_KEY_COMPONENTS             ,"bad key components"},
        +{ZENCOD_R_BN_EXPAND_FAIL                 ,"bn expand fail"},
        +{ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED   ,"ctrl command not implemented"},
        +{ZENCOD_R_DSO_FAILURE                    ,"dso failure"},
        +{ZENCOD_R_NOT_LOADED                     ,"not loaded"},
        +{ZENCOD_R_REQUEST_FAILED                 ,"request failed"},
        +{ZENCOD_R_UNIT_FAILURE                   ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef ZENCOD_LIB_NAME
        +static ERR_STRING_DATA ZENCOD_lib_name[]=
        +        {
        +{0	,ZENCOD_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int ZENCOD_lib_error_code=0;
        +static int ZENCOD_error_init=1;
        +
        +static void ERR_load_ZENCOD_strings(void)
        +	{
        +	if (ZENCOD_lib_error_code == 0)
        +		ZENCOD_lib_error_code=ERR_get_next_error_library();
        +
        +	if (ZENCOD_error_init)
        +		{
        +		ZENCOD_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(ZENCOD_lib_error_code,ZENCOD_str_functs);
        +		ERR_load_strings(ZENCOD_lib_error_code,ZENCOD_str_reasons);
        +#endif
        +
        +#ifdef ZENCOD_LIB_NAME
        +		ZENCOD_lib_name->error = ERR_PACK(ZENCOD_lib_error_code,0,0);
        +		ERR_load_strings(0,ZENCOD_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_ZENCOD_strings(void)
        +	{
        +	if (ZENCOD_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(ZENCOD_lib_error_code,ZENCOD_str_functs);
        +		ERR_unload_strings(ZENCOD_lib_error_code,ZENCOD_str_reasons);
        +#endif
        +
        +#ifdef ZENCOD_LIB_NAME
        +		ERR_unload_strings(0,ZENCOD_lib_name);
        +#endif
        +		ZENCOD_error_init=1;
        +		}
        +	}
        +
        +static void ERR_ZENCOD_error(int function, int reason, char *file, int line)
        +	{
        +	if (ZENCOD_lib_error_code == 0)
        +		ZENCOD_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(ZENCOD_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/demos/engines/zencod/hw_zencod_err.h b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod_err.h
        new file mode 100644
        index 000000000..60e923fd8
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/engines/zencod/hw_zencod_err.h
        @@ -0,0 +1,99 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * 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_ZENCOD_ERR_H
        +#define HEADER_ZENCOD_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_ZENCOD_strings(void);
        +static void ERR_unload_ZENCOD_strings(void);
        +static void ERR_ZENCOD_error(int function, int reason, char *file, int line);
        +#define ZENCODerr(f,r) ERR_ZENCOD_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the ZENCOD functions. */
        +
        +/* Function codes. */
        +#define ZENCOD_F_ZENCOD_BN_MOD_EXP			 100
        +#define ZENCOD_F_ZENCOD_CTRL				 101
        +#define ZENCOD_F_ZENCOD_DH_COMPUTE			 102
        +#define ZENCOD_F_ZENCOD_DH_GENERATE			 103
        +#define ZENCOD_F_ZENCOD_DSA_DO_SIGN			 104
        +#define ZENCOD_F_ZENCOD_DSA_DO_VERIFY			 105
        +#define ZENCOD_F_ZENCOD_FINISH				 106
        +#define ZENCOD_F_ZENCOD_INIT				 107
        +#define ZENCOD_F_ZENCOD_RAND				 108
        +#define ZENCOD_F_ZENCOD_RSA_MOD_EXP			 109
        +#define ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT			 110
        +
        +/* Reason codes. */
        +#define ZENCOD_R_ALREADY_LOADED				 100
        +#define ZENCOD_R_BAD_KEY_COMPONENTS			 101
        +#define ZENCOD_R_BN_EXPAND_FAIL				 102
        +#define ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
        +#define ZENCOD_R_DSO_FAILURE				 104
        +#define ZENCOD_R_NOT_LOADED				 105
        +#define ZENCOD_R_REQUEST_FAILED				 106
        +#define ZENCOD_R_UNIT_FAILURE				 107
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/demos/maurice/Makefile b/vendor/openssl/openssl/demos/maurice/Makefile
        new file mode 100644
        index 000000000..f9bf62276
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/Makefile
        @@ -0,0 +1,59 @@
        +CC=cc
        +CFLAGS= -g -I../../include -Wall
        +LIBS=  -L../.. -lcrypto
        +EXAMPLES=example1 example2 example3 example4
        +
        +all: $(EXAMPLES) 
        +
        +example1: example1.o loadkeys.o 
        +	$(CC) -o example1 example1.o loadkeys.o $(LIBS)
        +
        +example2: example2.o loadkeys.o
        +	$(CC) -o example2 example2.o loadkeys.o $(LIBS)
        +
        +example3: example3.o 
        +	$(CC) -o example3 example3.o $(LIBS)
        +
        +example4: example4.o
        +	$(CC) -o example4 example4.o $(LIBS)
        +
        +clean:	
        +	rm -f $(EXAMPLES) *.o
        +
        +test: all
        +	@echo
        +	@echo Example 1 Demonstrates the sealing and opening APIs
        +	@echo Doing the encrypt side...
        +	./example1 <README >t.t
        +	@echo Doing the decrypt side...
        +	./example1 -d <t.t >t.2
        +	diff t.2 README
        +	rm -f t.t t.2
        +	@echo  example1 is OK
        +
        +	@echo
        +	@echo Example2 Demonstrates rsa encryption and decryption
        +	@echo   and it should just print \"This the clear text\"
        +	./example2
        +
        +	@echo
        +	@echo Example3 Demonstrates the use of symmetric block ciphers
        +	@echo in this case it uses EVP_des_ede3_cbc
        +	@echo i.e. triple DES in Cipher Block Chaining mode
        +	@echo Doing the encrypt side...
        +	./example3 ThisIsThePassword <README >t.t
        +	@echo Doing the decrypt side...
        +	./example3 -d ThisIsThePassword <t.t >t.2
        +	diff t.2 README
        +	rm -f t.t t.2
        +	@echo  example3 is OK
        +
        +	@echo
        +	@echo Example4 Demonstrates base64 encoding and decoding
        +	@echo Doing the encrypt side...
        +	./example4 <README >t.t
        +	@echo Doing the decrypt side...
        +	./example4 -d <t.t >t.2
        +	diff t.2 README
        +	rm -f t.t t.2
        +	@echo example4 is OK
        diff --git a/vendor/openssl/openssl/demos/maurice/README b/vendor/openssl/openssl/demos/maurice/README
        new file mode 100644
        index 000000000..29778d55c
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/README
        @@ -0,0 +1,34 @@
        +From Maurice Gittens <mgittens@gits.nl>
        +--
        +	Example programs, demonstrating some basic SSLeay crypto library
        +	operations, to help you not to make the same mistakes I did. 
        +
        +	The following files are present.
        +	- loadkeys.c 	Demonstrates the loading and of public and 
        +			private keys.
        +	- loadkeys.h   	The interface for loadkeys.c
        +	- example1.c    Demonstrates the sealing and opening API's
        +	- example2.c  	Demonstrates rsa encryption and decryption
        +	- example3.c    Demonstrates the use of symmetric block ciphers
        +	- example4.c	Demonstrates base64 and decoding 		
        +	- Makefile	A makefile you probably will have to adjust for
        +			your environment
        +	- README	this file
        +
        +
        +	The programs were written by Maurice Gittens <mgittens@gits.nl>
        +	with the necesary help from Eric Young <eay@cryptsoft.com> 
        +	
        +	You may do as you please with these programs, but please don't
        +	pretend that you wrote them. 
        +
        +	To be complete: If you use these programs you acknowlegde that
        +	you are aware that there is NO warranty of any kind associated
        +	with these programs. I don't even claim that the programs work,
        +	they are provided AS-IS.
        +
        + 	January 1997
        +
        +	Maurice	
        +
        +
        diff --git a/vendor/openssl/openssl/demos/maurice/cert.pem b/vendor/openssl/openssl/demos/maurice/cert.pem
        new file mode 100644
        index 000000000..e31a9ae05
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/cert.pem
        @@ -0,0 +1,77 @@
        +issuer :/C=NL/SP=Brabant/L=Eindhoven/O=Gittens Information Systems B.V./OU=Certification Services/CN=ca.gits.nl/Email=mgittens@gits.nl
        +subject:/C=NL/SP=Brabant/O=Gittens Information Systems B.V./OU=Certification Services/CN=caleb.gits.nl/Email=mgittens@gits.nl
        +serial :01
        +
        +Certificate:
        +    Data:
        +        Version: 0 (0x0)
        +        Serial Number: 1 (0x1)
        +        Signature Algorithm: md5withRSAEncryption
        +        Issuer: C=NL, SP=Brabant, L=Eindhoven, O=Gittens Information Systems B.V., OU=Certification Services, CN=ca.gits.nl/Email=mgittens@gits.nl
        +        Validity
        +            Not Before: Jan  5 13:21:16 1997 GMT
        +            Not After : Jul 24 13:21:16 1997 GMT
        +        Subject: C=NL, SP=Brabant, O=Gittens Information Systems B.V., OU=Certification Services, CN=caleb.gits.nl/Email=mgittens@gits.nl
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +                Modulus:
        +                    00:dd:82:a0:fe:a9:8d:6a:02:7e:78:d6:33:75:9b:
        +                    82:01:4b:12:80:ea:6b:9b:83:9e:e3:ae:dc:f3:d0:
        +                    71:7c:4b:ea:03:57:b4:cc:ba:44:5b:b8:4b:49:d3:
        +                    f6:39:cc:3d:12:1f:da:58:26:27:bc:bc:ab:a4:6d:
        +                    62:d1:91:5a:47:9f:80:40:c1:b9:fa:e3:1e:ef:52:
        +                    78:46:26:43:65:1d:f2:6b:bf:ff:c0:81:66:14:cd:
        +                    81:32:91:f1:f8:51:7d:0e:17:1f:27:fc:c7:51:fd:
        +                    1c:73:41:e5:66:43:3c:67:a3:09:b9:5e:36:50:50:
        +                    b1:e8:42:bd:5c:c6:2b:ec:a9:2c:fe:6a:fe:40:26:
        +                    64:9e:b9:bf:2d:1d:fb:d0:48:5b:82:2a:8e:ab:a4:
        +                    d5:7b:5f:26:84:8a:9a:69:5e:c1:71:e2:a9:59:4c:
        +                    2a:76:f7:fd:f4:cf:3f:d3:ce:30:72:62:65:1c:e9:
        +                    e9:ee:d2:fc:44:00:1e:e0:80:57:e9:41:b3:f0:44:
        +                    e5:0f:77:3b:1a:1f:57:5e:94:1d:c3:a5:fa:af:41:
        +                    8c:4c:30:6b:2b:00:84:52:0c:64:0c:a8:5b:17:16:
        +                    d1:1e:f8:ea:72:01:47:9a:b9:21:95:f9:71:ed:7c:
        +                    d2:93:54:0c:c5:9c:e8:e5:40:28:c5:a0:ca:b1:a9:
        +                    20:f9
        +                Exponent: 65537 (0x10001)
        +    Signature Algorithm: md5withRSAEncryption
        +        93:08:f9:e0:d4:c5:ca:95:de:4e:38:3b:28:87:e9:d3:b6:ce:
        +        4f:69:2e:c9:09:57:2f:fa:e2:50:9f:39:ec:f3:84:e8:3a:8f:
        +        9b:c3:06:62:90:49:93:6d:23:7a:2b:3d:7b:f9:46:32:18:d3:
        +        87:44:49:f7:29:2f:f3:58:97:70:c3:45:5b:90:52:1c:df:fb:
        +        a8:a3:a1:29:53:a3:4c:ed:d2:51:d0:44:98:a4:14:6f:76:9d:
        +        0d:03:76:e5:d3:13:21:ce:a3:4d:2a:77:fe:ad:b3:47:6d:42:
        +        b9:4a:0e:ff:61:f4:ec:62:b2:3b:00:9c:ac:16:a2:ec:19:c8:
        +        c7:3d:d7:7d:97:cd:4d:1a:d2:00:07:4e:40:3d:b9:ba:1e:e2:
        +        fe:81:28:57:b9:ad:2b:74:59:b0:9f:8b:a5:98:d3:75:06:67:
        +        4a:04:11:b2:ea:1a:8c:e0:d4:be:c8:0c:46:76:7f:5f:5a:7b:
        +        72:09:dd:b6:d3:6b:97:70:e8:7e:17:74:1c:f7:3a:5f:e3:fa:
        +        c2:f7:95:bd:74:5e:44:4b:9b:bd:27:de:02:7f:87:1f:68:68:
        +        60:b9:f4:1d:2b:7b:ce:ef:b1:7f:3a:be:b9:66:60:54:6f:0c:
        +        a0:dd:8c:03:a7:f1:9f:f8:0e:8d:bb:c6:ba:77:61:f7:8e:be:
        +        28:ba:d8:4f
        +
        +-----BEGIN CERTIFICATE-----
        +MIIDzzCCArcCAQEwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAk5MMRAwDgYD
        +VQQIEwdCcmFiYW50MRIwEAYDVQQHEwlFaW5kaG92ZW4xKTAnBgNVBAoTIEdpdHRl
        +bnMgSW5mb3JtYXRpb24gU3lzdGVtcyBCLlYuMR8wHQYDVQQLExZDZXJ0aWZpY2F0
        +aW9uIFNlcnZpY2VzMRMwEQYDVQQDEwpjYS5naXRzLm5sMR8wHQYJKoZIhvcNAQkB
        +FhBtZ2l0dGVuc0BnaXRzLm5sMB4XDTk3MDEwNTEzMjExNloXDTk3MDcyNDEzMjEx
        +NlowgaQxCzAJBgNVBAYTAk5MMRAwDgYDVQQIEwdCcmFiYW50MSkwJwYDVQQKEyBH
        +aXR0ZW5zIEluZm9ybWF0aW9uIFN5c3RlbXMgQi5WLjEfMB0GA1UECxMWQ2VydGlm
        +aWNhdGlvbiBTZXJ2aWNlczEWMBQGA1UEAxMNY2FsZWIuZ2l0cy5ubDEfMB0GCSqG
        +SIb3DQEJARYQbWdpdHRlbnNAZ2l0cy5ubDCCASIwDQYJKoZIhvcNAQEBBQADggEP
        +ADCCAQoCggEBAN2CoP6pjWoCfnjWM3WbggFLEoDqa5uDnuOu3PPQcXxL6gNXtMy6
        +RFu4S0nT9jnMPRIf2lgmJ7y8q6RtYtGRWkefgEDBufrjHu9SeEYmQ2Ud8mu//8CB
        +ZhTNgTKR8fhRfQ4XHyf8x1H9HHNB5WZDPGejCbleNlBQsehCvVzGK+ypLP5q/kAm
        +ZJ65vy0d+9BIW4Iqjquk1XtfJoSKmmlewXHiqVlMKnb3/fTPP9POMHJiZRzp6e7S
        +/EQAHuCAV+lBs/BE5Q93OxofV16UHcOl+q9BjEwwaysAhFIMZAyoWxcW0R746nIB
        +R5q5IZX5ce180pNUDMWc6OVAKMWgyrGpIPkCAwEAATANBgkqhkiG9w0BAQQFAAOC
        +AQEAkwj54NTFypXeTjg7KIfp07bOT2kuyQlXL/riUJ857POE6DqPm8MGYpBJk20j
        +eis9e/lGMhjTh0RJ9ykv81iXcMNFW5BSHN/7qKOhKVOjTO3SUdBEmKQUb3adDQN2
        +5dMTIc6jTSp3/q2zR21CuUoO/2H07GKyOwCcrBai7BnIxz3XfZfNTRrSAAdOQD25
        +uh7i/oEoV7mtK3RZsJ+LpZjTdQZnSgQRsuoajODUvsgMRnZ/X1p7cgndttNrl3Do
        +fhd0HPc6X+P6wveVvXReREubvSfeAn+HH2hoYLn0HSt7zu+xfzq+uWZgVG8MoN2M
        +A6fxn/gOjbvGundh946+KLrYTw==
        +-----END CERTIFICATE-----
        +
        diff --git a/vendor/openssl/openssl/demos/maurice/example1.c b/vendor/openssl/openssl/demos/maurice/example1.c
        new file mode 100644
        index 000000000..1ef829990
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/example1.c
        @@ -0,0 +1,198 @@
        +/* NOCW */
        +/*
        +	Please read the README file for condition of use, before
        +	using this software.
        +	
        +	Maurice Gittens  <mgittens@gits.nl>   January 1997
        +*/
        +
        +#include <unistd.h>
        +#include <stdio.h>
        +#include <netinet/in.h>
        +#include <fcntl.h>
        +#include <strings.h>
        +#include <stdlib.h>
        +
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +
        +#include "loadkeys.h"
        +
        +#define PUBFILE   "cert.pem"
        +#define PRIVFILE  "privkey.pem"
        +
        +#define STDIN     0
        +#define STDOUT    1 
        +
        +void main_encrypt(void);
        +void main_decrypt(void);
        +
        +static const char *usage = "Usage: example1 [-d]\n";
        +
        +int main(int argc, char *argv[])
        +{
        +
        +        ERR_load_crypto_strings();
        +
        +	if ((argc == 1))	
        +	{
        +		main_encrypt();
        +	}	
        +	else if ((argc == 2) && !strcmp(argv[1],"-d"))
        +	{
        +		main_decrypt();
        +	}
        +	else
        +	{
        +		printf("%s",usage);
        +		exit(1);
        +	}
        +
        +	return 0;		
        +}
        +
        +void main_encrypt(void)
        +{
        +	unsigned int ebuflen;
        +        EVP_CIPHER_CTX ectx;
        +        unsigned char iv[EVP_MAX_IV_LENGTH];
        +	unsigned char *ekey[1]; 
        +	int readlen;
        +	int ekeylen, net_ekeylen; 
        +	EVP_PKEY *pubKey[1];
        +	char buf[512];
        +	char ebuf[512];
        +	
        + 	memset(iv, '\0', sizeof(iv));
        +
        +        pubKey[0] = ReadPublicKey(PUBFILE);
        +
        +	if(!pubKey[0])
        +	{
        +           fprintf(stderr,"Error: can't load public key");
        +           exit(1);
        +        }      
        +
        +        ekey[0] = malloc(EVP_PKEY_size(pubKey[0]));  
        +        if (!ekey[0])
        +	{
        +	   EVP_PKEY_free(pubKey[0]); 
        +	   perror("malloc");
        +	   exit(1);
        +	}
        +
        +	EVP_SealInit(&ectx,
        +                   EVP_des_ede3_cbc(),
        +		   ekey,
        +		   &ekeylen,
        +		   iv,
        +		   pubKey,
        +		   1); 
        +
        +	net_ekeylen = htonl(ekeylen);	
        +	write(STDOUT, (char*)&net_ekeylen, sizeof(net_ekeylen));
        +        write(STDOUT, ekey[0], ekeylen);
        +        write(STDOUT, iv, sizeof(iv));
        +
        +	while(1)
        +	{
        +		readlen = read(STDIN, buf, sizeof(buf));
        +
        +		if (readlen <= 0)
        +		{
        +		   if (readlen < 0)
        +			perror("read");
        +
        +		   break;
        +		}
        +
        +		EVP_SealUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
        +
        +		write(STDOUT, ebuf, ebuflen);
        +	}
        +
        +        EVP_SealFinal(&ectx, ebuf, &ebuflen);
        +        
        +	write(STDOUT, ebuf, ebuflen);
        +
        +        EVP_PKEY_free(pubKey[0]);
        +	free(ekey[0]);
        +}
        +
        +void main_decrypt(void)
        +{
        +	char buf[520];
        +	char ebuf[512];
        +	unsigned int buflen;
        +        EVP_CIPHER_CTX ectx;
        +        unsigned char iv[EVP_MAX_IV_LENGTH];
        +	unsigned char *encryptKey; 
        +	unsigned int ekeylen; 
        +	EVP_PKEY *privateKey;
        +
        +	memset(iv, '\0', sizeof(iv));
        +
        +	privateKey = ReadPrivateKey(PRIVFILE);
        +	if (!privateKey)
        +	{
        +		fprintf(stderr, "Error: can't load private key");
        +		exit(1);	
        +	}
        +
        +     	read(STDIN, &ekeylen, sizeof(ekeylen));
        +	ekeylen = ntohl(ekeylen);
        +
        +	if (ekeylen != EVP_PKEY_size(privateKey))
        +	{
        +        	EVP_PKEY_free(privateKey);
        +		fprintf(stderr, "keylength mismatch");
        +		exit(1);	
        +	}
        +
        +	encryptKey = malloc(sizeof(char) * ekeylen);
        +	if (!encryptKey)
        +	{
        +        	EVP_PKEY_free(privateKey);
        +		perror("malloc");
        +		exit(1);
        +	}
        +
        +	read(STDIN, encryptKey, ekeylen);
        +	read(STDIN, iv, sizeof(iv));
        +	EVP_OpenInit(&ectx,
        +		   EVP_des_ede3_cbc(), 
        +		   encryptKey,
        +		   ekeylen,
        +		   iv,
        +		   privateKey); 	
        +
        +	while(1)
        +	{
        +		int readlen = read(STDIN, ebuf, sizeof(ebuf));
        +
        +		if (readlen <= 0)
        +		{
        +			if (readlen < 0)
        +				perror("read");
        +
        +			break;
        +		}
        +
        +		EVP_OpenUpdate(&ectx, buf, &buflen, ebuf, readlen);
        +		write(STDOUT, buf, buflen);
        +	}
        +
        +        EVP_OpenFinal(&ectx, buf, &buflen);
        +
        +	write(STDOUT, buf, buflen);
        +
        +        EVP_PKEY_free(privateKey);
        +	free(encryptKey);
        +}
        +
        +
        diff --git a/vendor/openssl/openssl/demos/maurice/example2.c b/vendor/openssl/openssl/demos/maurice/example2.c
        new file mode 100644
        index 000000000..57bce10b5
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/example2.c
        @@ -0,0 +1,75 @@
        +/* NOCW */
        +/*
        +        Please read the README file for condition of use, before
        +        using this software.
        +
        +        Maurice Gittens  <mgittens@gits.nl>   January 1997
        +*/
        +
        +#include <stdlib.h>
        +#include <stdio.h>
        +#include <strings.h>
        +
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +
        +#include "loadkeys.h"
        +
        +#define PUBFILE   "cert.pem"
        +#define PRIVFILE  "privkey.pem"
        +#define STDIN     0
        +#define STDOUT    1 
        +
        +int main()
        +{
        +        char *ct = "This the clear text";
        +	char *buf;   
        +	char *buf2;
        +  	EVP_PKEY *pubKey;
        +  	EVP_PKEY *privKey;
        +	int len;
        +
        +        ERR_load_crypto_strings();
        +
        +        privKey = ReadPrivateKey(PRIVFILE);
        +        if (!privKey) 
        +	{  
        +		ERR_print_errors_fp (stderr);    
        +		exit (1);  
        +	}
        +
        +        pubKey = ReadPublicKey(PUBFILE);  
        +	if(!pubKey)
        +	{
        +	   EVP_PKEY_free(privKey);   
        +           fprintf(stderr,"Error: can't load public key");
        +	   exit(1);
        +	}
        +
        +	/* No error checking */
        +        buf = malloc(EVP_PKEY_size(pubKey));
        +        buf2 = malloc(EVP_PKEY_size(pubKey));
        +
        +	len = RSA_public_encrypt(strlen(ct)+1, ct, buf, pubKey->pkey.rsa,RSA_PKCS1_PADDING);
        +
        +	if (len != EVP_PKEY_size(pubKey))
        +	{
        +	    fprintf(stderr,"Error: ciphertext should match length of key\n");
        +	    exit(1);
        +	}
        +
        +	RSA_private_decrypt(len, buf, buf2, privKey->pkey.rsa,RSA_PKCS1_PADDING);
        +
        +	printf("%s\n", buf2);
        +
        +	EVP_PKEY_free(privKey);
        +	EVP_PKEY_free(pubKey);
        +	free(buf);
        +	free(buf2);
        +        return 0;
        +}
        diff --git a/vendor/openssl/openssl/demos/maurice/example3.c b/vendor/openssl/openssl/demos/maurice/example3.c
        new file mode 100644
        index 000000000..03d8a20f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/example3.c
        @@ -0,0 +1,87 @@
        +/* NOCW */
        +/*
        +        Please read the README file for condition of use, before
        +        using this software.
        +
        +        Maurice Gittens  <mgittens@gits.nl>   January 1997
        +
        +*/
        +
        +#include <stdio.h>
        +#include <unistd.h>
        +#include <fcntl.h>
        +#include <sys/stat.h>
        +#include <openssl/evp.h>
        +
        +#define STDIN     	0
        +#define STDOUT    	1
        +#define BUFLEN	  	512 
        +#define INIT_VECTOR 	"12345678"
        +#define ENCRYPT		1
        +#define DECRYPT         0
        +#define ALG		EVP_des_ede3_cbc()
        +
        +static const char *usage = "Usage: example3 [-d] password\n";
        +
        +void do_cipher(char *,int);
        +
        +int main(int argc, char *argv[])
        +{
        +	if ((argc == 2))	
        +	{
        +		do_cipher(argv[1],ENCRYPT);
        +	}	
        +	else if ((argc == 3) && !strcmp(argv[1],"-d"))
        +	{
        +		do_cipher(argv[2],DECRYPT);
        +	}
        +	else
        +	{
        +		fprintf(stderr,"%s", usage);
        +		exit(1);
        +	}
        +
        +	return 0;		
        +}
        +
        +void do_cipher(char *pw, int operation)
        +{
        +	char buf[BUFLEN];
        +	char ebuf[BUFLEN + 8];
        +	unsigned int ebuflen; /* rc; */
        +        unsigned char iv[EVP_MAX_IV_LENGTH], key[EVP_MAX_KEY_LENGTH];
        +	/* unsigned int ekeylen, net_ekeylen;  */
        +	EVP_CIPHER_CTX ectx;
        +        
        +	memcpy(iv, INIT_VECTOR, sizeof(iv));
        +
        +	EVP_BytesToKey(ALG, EVP_md5(), "salu", pw, strlen(pw), 1, key, iv);
        +
        +	EVP_CIPHER_CTX_init(&ectx);
        +	EVP_CipherInit_ex(&ectx, ALG, NULL, key, iv, operation);
        +
        +	while(1)
        +	{
        +		int readlen = read(STDIN, buf, sizeof(buf));
        +	
        +		if (readlen <= 0)
        +		{
        +			if (!readlen)
        +			   break;
        +			else
        +			{
        +				perror("read");
        +				exit(1);
        +			}
        +		}
        +
        +		EVP_CipherUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
        +
        +		write(STDOUT, ebuf, ebuflen);
        +	}
        +
        +        EVP_CipherFinal_ex(&ectx, ebuf, &ebuflen); 
        +	EVP_CIPHER_CTX_cleanup(&ectx);
        +
        +	write(STDOUT, ebuf, ebuflen); 
        +}
        diff --git a/vendor/openssl/openssl/demos/maurice/example4.c b/vendor/openssl/openssl/demos/maurice/example4.c
        new file mode 100644
        index 000000000..ce629848b
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/example4.c
        @@ -0,0 +1,123 @@
        +/* NOCW */
        +/*
        +        Please read the README file for condition of use, before
        +        using this software.
        +
        +        Maurice Gittens  <mgittens@gits.nl>   January 1997
        +
        +*/
        +
        +#include <stdio.h>
        +#include <unistd.h>
        +#include <fcntl.h>
        +#include <sys/stat.h>
        +#include <openssl/evp.h>
        +
        +#define STDIN     	0
        +#define STDOUT    	1
        +#define BUFLEN	  	512 
        +
        +static const char *usage = "Usage: example4 [-d]\n";
        +
        +void do_encode(void);
        +void do_decode(void);
        +
        +int main(int argc, char *argv[])
        +{
        +	if ((argc == 1))	
        +	{
        +		do_encode();
        +	}	
        +	else if ((argc == 2) && !strcmp(argv[1],"-d"))
        +	{
        +		do_decode();
        +	}
        +	else
        +	{
        +		fprintf(stderr,"%s", usage);
        +		exit(1);
        +	}
        +
        +	return 0;		
        +}
        +
        +void do_encode()
        +{
        +	char buf[BUFLEN];
        +	char ebuf[BUFLEN+24];
        +	unsigned int ebuflen;
        +	EVP_ENCODE_CTX ectx;
        +        
        +	EVP_EncodeInit(&ectx);
        +
        +	while(1)
        +	{
        +		int readlen = read(STDIN, buf, sizeof(buf));
        +	
        +		if (readlen <= 0)
        +		{
        +			if (!readlen)
        +			   break;
        +			else
        +			{
        +				perror("read");
        +				exit(1);
        +			}
        +		}
        +
        +		EVP_EncodeUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
        +
        +		write(STDOUT, ebuf, ebuflen);
        +	}
        +
        +        EVP_EncodeFinal(&ectx, ebuf, &ebuflen); 
        +
        +	write(STDOUT, ebuf, ebuflen);
        +}
        +
        +void do_decode()
        +{
        + 	char buf[BUFLEN];
        + 	char ebuf[BUFLEN+24];
        +	unsigned int ebuflen;
        +	EVP_ENCODE_CTX ectx;
        +        
        +	EVP_DecodeInit(&ectx);
        +
        +	while(1)
        +	{
        +		int readlen = read(STDIN, buf, sizeof(buf));
        +		int rc;	
        +	
        +		if (readlen <= 0)
        +		{
        +			if (!readlen)
        +			   break;
        +			else
        +			{
        +				perror("read");
        +				exit(1);
        +			}
        +		}
        +
        +		rc = EVP_DecodeUpdate(&ectx, ebuf, &ebuflen, buf, readlen);
        +		if (rc <= 0)
        +		{
        +			if (!rc)
        +			{
        +				write(STDOUT, ebuf, ebuflen);
        +				break;
        +			}
        +
        +			fprintf(stderr, "Error: decoding message\n");
        +			return;
        +		}
        +
        +		write(STDOUT, ebuf, ebuflen);
        +	}
        +
        +        EVP_DecodeFinal(&ectx, ebuf, &ebuflen); 
        +
        +	write(STDOUT, ebuf, ebuflen); 
        +}
        +
        diff --git a/vendor/openssl/openssl/demos/maurice/loadkeys.c b/vendor/openssl/openssl/demos/maurice/loadkeys.c
        new file mode 100644
        index 000000000..82fd22a95
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/loadkeys.c
        @@ -0,0 +1,72 @@
        +/* NOCW */
        +/*
        +        Please read the README file for condition of use, before
        +        using this software.
        +
        +        Maurice Gittens  <mgittens@gits.nl>   January 1997
        +
        +*/
        +
        +#include <unistd.h>
        +#include <stdio.h>
        +#include <netinet/in.h>
        +#include <fcntl.h>
        +#include <strings.h>
        +#include <stdlib.h>
        +
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +
        +EVP_PKEY * ReadPublicKey(const char *certfile)
        +{
        +  FILE *fp = fopen (certfile, "r");   
        +  X509 *x509;
        +  EVP_PKEY *pkey;
        +
        +  if (!fp) 
        +     return NULL; 
        +
        +  x509 = PEM_read_X509(fp, NULL, 0, NULL);
        +
        +  if (x509 == NULL) 
        +  {  
        +     ERR_print_errors_fp (stderr);
        +     return NULL;   
        +  }
        +
        +  fclose (fp);
        +  
        +  pkey=X509_extract_key(x509);
        +
        +  X509_free(x509);
        +
        +  if (pkey == NULL) 
        +     ERR_print_errors_fp (stderr);
        +
        +  return pkey; 
        +}
        +
        +EVP_PKEY *ReadPrivateKey(const char *keyfile)
        +{
        +	FILE *fp = fopen(keyfile, "r");
        +	EVP_PKEY *pkey;
        +
        +	if (!fp)
        +		return NULL;
        +
        +	pkey = PEM_read_PrivateKey(fp, NULL, 0, NULL);
        +
        +	fclose (fp);
        +
        +  	if (pkey == NULL) 
        +		ERR_print_errors_fp (stderr);   
        +
        +	return pkey;
        +}
        +
        +
        diff --git a/vendor/openssl/openssl/demos/maurice/loadkeys.h b/vendor/openssl/openssl/demos/maurice/loadkeys.h
        new file mode 100644
        index 000000000..d8fde86eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/loadkeys.h
        @@ -0,0 +1,19 @@
        +/* NOCW */
        +/*
        +        Please read the README file for condition of use, before
        +        using this software.
        +
        +        Maurice Gittens  <mgittens@gits.nl>   January 1997
        +
        +*/
        +
        +#ifndef LOADKEYS_H_SEEN
        +#define LOADKEYS_H_SEEN
        +
        +#include <openssl/evp.h>
        +
        +EVP_PKEY * ReadPublicKey(const char *certfile);
        +EVP_PKEY *ReadPrivateKey(const char *keyfile);
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/demos/maurice/privkey.pem b/vendor/openssl/openssl/demos/maurice/privkey.pem
        new file mode 100644
        index 000000000..fc3554e93
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/maurice/privkey.pem
        @@ -0,0 +1,27 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIEpAIBAAKCAQEA3YKg/qmNagJ+eNYzdZuCAUsSgOprm4Oe467c89BxfEvqA1e0
        +zLpEW7hLSdP2Ocw9Eh/aWCYnvLyrpG1i0ZFaR5+AQMG5+uMe71J4RiZDZR3ya7//
        +wIFmFM2BMpHx+FF9DhcfJ/zHUf0cc0HlZkM8Z6MJuV42UFCx6EK9XMYr7Kks/mr+
        +QCZknrm/LR370EhbgiqOq6TVe18mhIqaaV7BceKpWUwqdvf99M8/084wcmJlHOnp
        +7tL8RAAe4IBX6UGz8ETlD3c7Gh9XXpQdw6X6r0GMTDBrKwCEUgxkDKhbFxbRHvjq
        +cgFHmrkhlflx7XzSk1QMxZzo5UAoxaDKsakg+QIDAQABAoIBAQC0hnh083PnuJ6g
        +Flob+B+stCUhYWtPc6ZzgphaMD+9ABV4oescipWZdooNYiyikBwZgFIvUvFBtTXh
        +rLBDgUVlZ81beUb7/EvC2aBh818rsotWW0Sw/ARY4d7wetcL/EWBzUA8E5vR6wlb
        +uZGelR9OiyYqp2h2bj1/v5yaVnuHxBeBj5clTHtPMXc+/70iUNBDMZ0ruZTdSwll
        +e0DH8pp/5USYewlrKtRIJT7elC8LFMqEz4OpNvfaR2OEY0FatYYmSvQPNwV8/Eor
        +XlNzRi9qD0uXbVexaAgQZ3/KZuAzUbOgwJZZXEAOGkZ/J1n08jljPXdU0o7bHhNl
        +7siHbuEBAoGBAP53IvvJkhnH8Akf6E6sXelZkPKHnwDwfywDAiIhXza9DB1DViRS
        +bZUB5gzcxmLGalex5+LcwZmsqFO5NXZ8SQeE9p0YT8yJsX4J1w9JzSvsWJBS2vyW
        +Kbt21oG6JAGrWSGMIfxKpuahtWLf4JpGjftti0qIVQ60GKEPc1/xE2PZAoGBAN7Y
        +nRPaUaqcIwbnH9kovOKwZ/PWREy1ecr3YXj65VYTnwSJHD0+CJa/DX8eB/G4AoNA
        +Y2LPbq0Xu3+7SaUsO45VkaZuJmNwheUQ4tmyd/YdnVZ0AHXx1tvpR7QeO0WjnlNK
        +mR+x00fetrff2Ypahs0wtU0Xf3F8ORgVB8jnxBIhAoGAcwf0PpI+g30Im3dbEsWE
        +poogpiJ81HXjZ0fs3PTtD9eh9FCOTlkcxHFZR5M980TyqbX4t2tH8WpFpaNh8a/5
        +a3bF7PoiiLnuDKXyHC0mnKZ42rU53VkcgGwWSAqXYFHPNwUcD+rHTBbp4kqGQ/eF
        +E5XPk9/RY5YyVAyiAUr/kvECgYBvW1Ua75SxqbZDI8mhbZ79tGMt0NtubZz/1KCL
        +oOxrGAD1dkJ7Q/1svunSpMIZgvcWeV1wqfFHY72ZNZC2jiTwmkffH9nlBPyTm92Q
        +JYOWo/PUmMEGLyRL3gWrtxOtV/as7nEYCndmyZ8KwTxmy5fi/z0J2f0gS5AIPbIX
        +LeGnoQKBgQDapjz9K4HWR5AMxyga4eiLIrmADySP846uz3eZIvTJQZ+6TAamvnno
        +KbnU21cGq5HBBtxqQvGswLPGW9rZAgykHHJmYBUp0xv4+I4qHfXyD7QNmvq+Vxjj
        +V2tgIafEpaf2ZsfM7BZeZz8MzeGcDwyrHtIO1FQiYN5Qz9Hq68XmVA==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/pkcs12/README b/vendor/openssl/openssl/demos/pkcs12/README
        new file mode 100644
        index 000000000..c87434b04
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/pkcs12/README
        @@ -0,0 +1,3 @@
        +PKCS#12 demo applications
        +
        +Written by Steve Henson.
        diff --git a/vendor/openssl/openssl/demos/pkcs12/pkread.c b/vendor/openssl/openssl/demos/pkcs12/pkread.c
        new file mode 100644
        index 000000000..fa8f50923
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/pkcs12/pkread.c
        @@ -0,0 +1,61 @@
        +/* pkread.c */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/pkcs12.h>
        +
        +/* Simple PKCS#12 file reader */
        +
        +int main(int argc, char **argv)
        +{
        +	FILE *fp;
        +	EVP_PKEY *pkey;
        +	X509 *cert;
        +	STACK_OF(X509) *ca = NULL;
        +	PKCS12 *p12;
        +	int i;
        +	if (argc != 4) {
        +		fprintf(stderr, "Usage: pkread p12file password opfile\n");
        +		exit (1);
        +	}
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +	if (!(fp = fopen(argv[1], "rb"))) {
        +		fprintf(stderr, "Error opening file %s\n", argv[1]);
        +		exit(1);
        +	}
        +	p12 = d2i_PKCS12_fp(fp, NULL);
        +	fclose (fp);
        +	if (!p12) {
        +		fprintf(stderr, "Error reading PKCS#12 file\n");
        +		ERR_print_errors_fp(stderr);
        +		exit (1);
        +	}
        +	if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
        +		fprintf(stderr, "Error parsing PKCS#12 file\n");
        +		ERR_print_errors_fp(stderr);
        +		exit (1);
        +	}
        +	PKCS12_free(p12);
        +	if (!(fp = fopen(argv[3], "w"))) {
        +		fprintf(stderr, "Error opening file %s\n", argv[1]);
        +		exit(1);
        +	}
        +	if (pkey) {
        +		fprintf(fp, "***Private Key***\n");
        +		PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
        +	}
        +	if (cert) {
        +		fprintf(fp, "***User Certificate***\n");
        +		PEM_write_X509_AUX(fp, cert);
        +	}
        +	if (ca && sk_X509_num(ca)) {
        +		fprintf(fp, "***Other Certificates***\n");
        +		for (i = 0; i < sk_X509_num(ca); i++) 
        +		    PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
        +	}
        +	fclose(fp);
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/demos/pkcs12/pkwrite.c b/vendor/openssl/openssl/demos/pkcs12/pkwrite.c
        new file mode 100644
        index 000000000..15f839d1e
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/pkcs12/pkwrite.c
        @@ -0,0 +1,46 @@
        +/* pkwrite.c */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/pem.h>
        +#include <openssl/err.h>
        +#include <openssl/pkcs12.h>
        +
        +/* Simple PKCS#12 file creator */
        +
        +int main(int argc, char **argv)
        +{
        +	FILE *fp;
        +	EVP_PKEY *pkey;
        +	X509 *cert;
        +	PKCS12 *p12;
        +	if (argc != 5) {
        +		fprintf(stderr, "Usage: pkwrite infile password name p12file\n");
        +		exit(1);
        +	}
        +	SSLeay_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +	if (!(fp = fopen(argv[1], "r"))) {
        +		fprintf(stderr, "Error opening file %s\n", argv[1]);
        +		exit(1);
        +	}
        +	cert = PEM_read_X509(fp, NULL, NULL, NULL);
        +	rewind(fp);
        +	pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
        +	fclose(fp);
        +	p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0);
        +	if(!p12) {
        +		fprintf(stderr, "Error creating PKCS#12 structure\n");
        +		ERR_print_errors_fp(stderr);
        +		exit(1);
        +	}
        +	if (!(fp = fopen(argv[4], "wb"))) {
        +		fprintf(stderr, "Error opening file %s\n", argv[1]);
        +		ERR_print_errors_fp(stderr);
        +		exit(1);
        +	}
        +	i2d_PKCS12_fp(fp, p12);
        +	PKCS12_free(p12);
        +	fclose(fp);
        +	return 0;
        +}
        diff --git a/vendor/openssl/openssl/demos/prime/Makefile b/vendor/openssl/openssl/demos/prime/Makefile
        new file mode 100644
        index 000000000..0166cd46f
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/prime/Makefile
        @@ -0,0 +1,20 @@
        +CC=cc
        +CFLAGS= -g -I../../include -Wall
        +LIBS=  -L../.. -lcrypto
        +EXAMPLES=prime
        +
        +all: $(EXAMPLES) 
        +
        +prime: prime.o
        +	$(CC) -o prime prime.o $(LIBS)
        +
        +clean:	
        +	rm -f $(EXAMPLES) *.o
        +
        +test: all
        +	@echo Test creating a 128-bit prime
        +	./prime 128
        +	@echo Test creating a 256-bit prime
        +	./prime 256
        +	@echo Test creating a 512-bit prime
        +	./prime 512
        diff --git a/vendor/openssl/openssl/demos/prime/prime.c b/vendor/openssl/openssl/demos/prime/prime.c
        new file mode 100644
        index 000000000..103e0efc0
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/prime/prime.c
        @@ -0,0 +1,101 @@
        +/* demos/prime/prime.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/bn.h>    
        +
        +void callback(type,num)
        +int type,num;
        +	{
        +	if (type == 0)
        +		fprintf(stderr,".");
        +	else if (type == 1)
        +		fprintf(stderr,"+");
        +	else if (type == 2)
        +		fprintf(stderr,"*");
        +	fflush(stderr);
        +	}
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	BIGNUM *rand;
        +	int num=256;
        +
        +	/* we should really call RAND_seed(char *bytes,int num);
        +	 * to fully initalise the random number generator */
        +	if (argc >= 2)
        +		{
        +		num=atoi(argv[1]);
        +		if (num == 0) num=256;
        +		}
        +
        +	fprintf(stderr,"generate a strong prime\n");
        +        rand=BN_generate_prime(NULL,num,1,NULL,NULL,callback,NULL);
        +	/* change the third parameter to 1 for a strong prime */
        +	fprintf(stderr,"\n");
        +
        +	BN_print_fp(stdout,rand);           
        +	fprintf(stdout,"\n");
        +	BN_free(rand); 
        +	exit(0);
        +	return(0);
        +	}
        +
        diff --git a/vendor/openssl/openssl/demos/privkey.pem b/vendor/openssl/openssl/demos/privkey.pem
        new file mode 100644
        index 000000000..ddae24075
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/privkey.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBAN+FmbxmHVOp/RxtpMGz0DvQEBz1sDktHp19hIoMSu0YZift5MAu
        +4xAEJYvWVCshDiyOTWsUBXwZkrkt87FyctkCAwEAAQJAG/vxBGpQb6IPo1iC0RF/
        +F430BnwoBPCGLbeCOXpSgx5X+19vuTSdEqMgeNB6+aNb+XY/7mvVfCjyD6WZ0oxs
        +JQIhAPO+uL9cP40lFs62pdL3QSWsh3VNDByvOtr9LpeaxBm/AiEA6sKVfXsDQ5hd
        +SHt9U61r2r8Lcxmzi9Kw6JNqjMmzqWcCIQCKoRy+aZ8Tjdas9yDVHh+FZ90bEBkl
        +b1xQFNOdEj8aTQIhAOJWrO6INYNsWTPS6+hLYZtLamyUsQj0H+B8kNQge/mtAiEA
        +nBfvUl243qbqN8gF7Az1u33uc9FsPVvQPiBzLxZ4ixw=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/selfsign.c b/vendor/openssl/openssl/demos/selfsign.c
        new file mode 100644
        index 000000000..68904c611
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/selfsign.c
        @@ -0,0 +1,180 @@
        +/* NOCW */
        +/* cc -o ssdemo -I../include selfsign.c ../libcrypto.a */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include <openssl/pem.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +
        +int mkit(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
        +
        +int main()
        +	{
        +	BIO *bio_err;
        +	X509 *x509=NULL;
        +	EVP_PKEY *pkey=NULL;
        +
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	mkit(&x509,&pkey,512,0,365);
        +
        +	RSA_print_fp(stdout,pkey->pkey.rsa,0);
        +	X509_print_fp(stdout,x509);
        +
        +	PEM_write_PrivateKey(stdout,pkey,NULL,NULL,0,NULL, NULL);
        +	PEM_write_X509(stdout,x509);
        +
        +	X509_free(x509);
        +	EVP_PKEY_free(pkey);
        +
        +#ifdef CUSTOM_EXT
        +	/* Only needed if we add objects or custom extensions */
        +	X509V3_EXT_cleanup();
        +	OBJ_cleanup();
        +#endif
        +
        +	CRYPTO_mem_leaks(bio_err);
        +	BIO_free(bio_err);
        +	return(0);
        +	}
        +
        +#ifdef WIN16
        +#  define MS_CALLBACK   _far _loadds
        +#  define MS_FAR        _far
        +#else
        +#  define MS_CALLBACK
        +#  define MS_FAR
        +#endif
        +
        +static void MS_CALLBACK callback(p, n, arg)
        +int p;
        +int n;
        +void *arg;
        +	{
        +	char c='B';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	fputc(c,stderr);
        +	}
        +
        +int mkit(x509p,pkeyp,bits,serial,days)
        +X509 **x509p;
        +EVP_PKEY **pkeyp;
        +int bits;
        +int serial;
        +int days;
        +	{
        +	X509 *x;
        +	EVP_PKEY *pk;
        +	RSA *rsa;
        +	X509_NAME *name=NULL;
        +	X509_NAME_ENTRY *ne=NULL;
        +	X509_EXTENSION *ex=NULL;
        +
        +	
        +	if ((pkeyp == NULL) || (*pkeyp == NULL))
        +		{
        +		if ((pk=EVP_PKEY_new()) == NULL)
        +			{
        +			abort(); 
        +			return(0);
        +			}
        +		}
        +	else
        +		pk= *pkeyp;
        +
        +	if ((x509p == NULL) || (*x509p == NULL))
        +		{
        +		if ((x=X509_new()) == NULL)
        +			goto err;
        +		}
        +	else
        +		x= *x509p;
        +
        +	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
        +	if (!EVP_PKEY_assign_RSA(pk,rsa))
        +		{
        +		abort();
        +		goto err;
        +		}
        +	rsa=NULL;
        +
        +	X509_set_version(x,3);
        +	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
        +	X509_gmtime_adj(X509_get_notBefore(x),0);
        +	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
        +	X509_set_pubkey(x,pk);
        +
        +	name=X509_get_subject_name(x);
        +
        +	/* This function creates and adds the entry, working out the
        +	 * correct string type and performing checks on its length.
        +	 * Normally we'd check the return value for errors...
        +	 */
        +	X509_NAME_add_entry_by_txt(name,"C",
        +				MBSTRING_ASC, "UK", -1, -1, 0);
        +	X509_NAME_add_entry_by_txt(name,"CN",
        +				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
        +
        +	X509_set_issuer_name(x,name);
        +
        +	/* Add extension using V3 code: we can set the config file as NULL
        +	 * because we wont reference any other sections. We can also set
        +         * the context to NULL because none of these extensions below will need
        +	 * to access it.
        +	 */
        +
        +	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, "server");
        +	X509_add_ext(x,ex,-1);
        +	X509_EXTENSION_free(ex);
        +
        +	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_comment,
        +						"example comment extension");
        +	X509_add_ext(x,ex,-1);
        +	X509_EXTENSION_free(ex);
        +
        +	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_ssl_server_name,
        +							"www.openssl.org");
        +
        +	X509_add_ext(x,ex,-1);
        +	X509_EXTENSION_free(ex);
        +
        +#if 0
        +	/* might want something like this too.... */
        +	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,
        +							"critical,CA:TRUE");
        +
        +
        +	X509_add_ext(x,ex,-1);
        +	X509_EXTENSION_free(ex);
        +#endif
        +
        +#ifdef CUSTOM_EXT
        +	/* Maybe even add our own extension based on existing */
        +	{
        +		int nid;
        +		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
        +		X509V3_EXT_add_alias(nid, NID_netscape_comment);
        +		ex = X509V3_EXT_conf_nid(NULL, NULL, nid,
        +						"example comment alias");
        +		X509_add_ext(x,ex,-1);
        +		X509_EXTENSION_free(ex);
        +	}
        +#endif
        +	
        +	if (!X509_sign(x,pk,EVP_md5()))
        +		goto err;
        +
        +	*x509p=x;
        +	*pkeyp=pk;
        +	return(1);
        +err:
        +	return(0);
        +	}
        diff --git a/vendor/openssl/openssl/demos/sign/Makefile b/vendor/openssl/openssl/demos/sign/Makefile
        new file mode 100644
        index 000000000..e6d391e4a
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/sign/Makefile
        @@ -0,0 +1,15 @@
        +CC=cc
        +CFLAGS= -g -I../../include -Wall
        +LIBS=  -L../.. -lcrypto
        +EXAMPLES=sign
        +
        +all: $(EXAMPLES) 
        +
        +sign: sign.o
        +	$(CC) -o sign sign.o $(LIBS)
        +
        +clean:	
        +	rm -f $(EXAMPLES) *.o
        +
        +test: all
        +	./sign
        diff --git a/vendor/openssl/openssl/demos/sign/cert.pem b/vendor/openssl/openssl/demos/sign/cert.pem
        new file mode 100644
        index 000000000..9d7ac238d
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/sign/cert.pem
        @@ -0,0 +1,14 @@
        +-----BEGIN CERTIFICATE-----
        +MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
        +VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
        +bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
        +dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
        +DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
        +EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
        +dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
        +EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
        +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
        +L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
        +BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
        +9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/demos/sign/key.pem b/vendor/openssl/openssl/demos/sign/key.pem
        new file mode 100644
        index 000000000..239ad66f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/sign/key.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
        +2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
        +oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
        +8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
        +a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
        +WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
        +6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/sign/sig.txt b/vendor/openssl/openssl/demos/sign/sig.txt
        new file mode 100644
        index 000000000..5613c0ee7
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/sign/sig.txt
        @@ -0,0 +1,158 @@
        +From ssl-lists-owner@mincom.com Mon Sep 30 02:37:40 1996
        +Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA11782
        +  (5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 11:46:21 +1000
        +Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id LAA18980 for ssl-users-outgoing; Mon, 30 Sep 1996 11:44:56 +1000 (EST)
        +Received: from minbne.mincom.oz.au (minbne.mincom.oz.au [192.55.196.247]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id LAA18962 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 11:44:51 +1000 (EST)
        +Received: by minbne.mincom.oz.au id AA22230
        +  (5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 11:38:41 +1000
        +Received: from brutus.neuronio.pt (brutus.neuronio.pt [193.126.253.2]) by bunyip.cc.uq.oz.au (8.7.6/8.7.3) with SMTP id LAA15824 for <ssl-users@mincom.com>; Mon, 30 Sep 1996 11:40:07 +1000
        +Received: (from sampo@localhost) by brutus.neuronio.pt (8.6.11/8.6.11) id BAA08729; Mon, 30 Sep 1996 01:37:40 +0100
        +Date: Mon, 30 Sep 1996 01:37:40 +0100
        +Message-Id: <199609300037.BAA08729@brutus.neuronio.pt>
        +From: Sampo Kellomaki <sampo@neuronio.pt>
        +To: ssl-users@mincom.com
        +Cc: sampo@brutus.neuronio.pt
        +Subject: Signing with envelope routines
        +Sender: ssl-lists-owner@mincom.com
        +Precedence: bulk
        +Status: RO
        +X-Status: D
        +
        +
        +I have been trying to figure out how to produce signatures with EVP_
        +routines. I seem to be able to read in private key and sign some
        +data ok, but I can't figure out how I am supposed to read in
        +public key so that I could verify my signature. I use self signed
        +certificate.
        +
        +I figured I should use
        +	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY,
        +	                               fp, NULL, NULL);
        +to read in private key and this seems to work Ok.
        +
        +However when I try analogous
        +	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509,
        +	                               fp, NULL, NULL);
        +the program fails with
        +
        +error:0D09508D:asn1 encoding routines:D2I_PUBLICKEY:unknown public key type:d2i_pu.c:93
        +error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_lib.c:232
        +
        +I figured that the second argument to PEM_ASN1_read should match the
        +name in my PEM encoded object, hence PEM_STRING_X509.
        +PEM_STRING_EVP_PKEY seems to be somehow magical
        +because it matches whatever private key there happens to be. I could
        +not find a similar constant to use with getting the certificate, however.
        +
        +Is my approach of using PEM_ASN1_read correct? What should I pass in
        +as name?  Can I use normal (or even self signed) X509 certificate for
        +verifying the signature?
        +
        +When will SSLeay documentation be written ;-)? If I would contribute
        +comments to the code, would Eric take time to review them and include
        +them in distribution?
        +
        +I'm using SSLeay-0.6.4. My program is included below along with the
        +key and cert that I use.
        +
        +--Sampo
        +
        +-----------------------------------
        +/* sign-it.cpp  -  Simple test app using SSLeay envelopes to sign data
        +   29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
        +
        +#include <stdio.h>
        +#include "rsa.h"
        +#include "evp.h"
        +#include "objects.h"
        +#include "x509.h"
        +#include "err.h"
        +#include "pem.h"
        +#include "ssl.h"
        +
        +void main ()
        +{
        +  int err;
        +  int sig_len;
        +  unsigned char sig_buf [4096];
        +  const char certfile[] = "plain-cert.pem";
        +  const char keyfile[]  = "plain-key.pem";
        +  const char data[]     = "I owe you...";
        +  EVP_MD_CTX     md_ctx;
        +  EVP_PKEY*      pkey;
        +  FILE*          fp;
        +
        +  SSL_load_error_strings();
        +  
        +  /* Read private key */
        +  
        +  fp = fopen (keyfile, "r");   if (fp == NULL) exit (1);
        +  pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
        +				   PEM_STRING_EVP_PKEY,
        +				   fp,
        +				   NULL, NULL);
        +  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  fclose (fp);
        +  
        +  /* Do the signature */
        +  
        +  EVP_SignInit   (&md_ctx, EVP_md5());
        +  EVP_SignUpdate (&md_ctx, data, strlen(data));
        +  sig_len = sizeof(sig_buf);
        +  err = EVP_SignFinal (&md_ctx,
        +		       sig_buf, 
        +		       &sig_len,
        +		       pkey);
        +  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  EVP_PKEY_free (pkey);
        +  
        +  /* Read public key */
        +  
        +  fp = fopen (certfile, "r");   if (fp == NULL) exit (1);
        +  pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PublicKey,
        +				   PEM_STRING_X509,
        +				   fp,
        +				   NULL, NULL);
        +  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  fclose (fp);
        +  
        +  /* Verify the signature */
        +  
        +  EVP_VerifyInit   (&md_ctx, EVP_md5());
        +  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
        +  err = EVP_VerifyFinal (&md_ctx,
        +			 sig_buf,
        +			 sig_len,
        +			 pkey);
        +  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  EVP_PKEY_free (pkey);
        +  printf ("Signature Verified Ok.\n");
        +}
        +/* EOF */
        +--------------- plain-cert.pem -----------------
        +-----BEGIN CERTIFICATE-----
        +MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
        +VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
        +bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
        +dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
        +DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
        +EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
        +dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
        +EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
        +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
        +L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
        +BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
        +9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
        +-----END CERTIFICATE-----
        +---------------- plain-key.pem -----------------
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
        +2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
        +oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
        +8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
        +a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
        +WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
        +6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
        +-----END RSA PRIVATE KEY-----
        +------------------------------------------------
        +
        diff --git a/vendor/openssl/openssl/demos/sign/sign.c b/vendor/openssl/openssl/demos/sign/sign.c
        new file mode 100644
        index 000000000..a6c66e17c
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/sign/sign.c
        @@ -0,0 +1,153 @@
        +/* demos/sign/sign.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +/* sign-it.cpp  -  Simple test app using SSLeay envelopes to sign data
        +   29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
        +
        +/* converted to C - eay :-) */
        +
        +/* reformated a bit and converted to use the more common functions: this was
        + * initially written at the dawn of time :-) - Steve.
        + */
        +
        +#include <stdio.h>
        +#include <openssl/rsa.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +
        +int main ()
        +{
        +  int err;
        +  int sig_len;
        +  unsigned char sig_buf [4096];
        +  static char certfile[] = "cert.pem";
        +  static char keyfile[]  = "key.pem";
        +  static char data[]     = "I owe you...";
        +  EVP_MD_CTX     md_ctx;
        +  EVP_PKEY *      pkey;
        +  FILE *          fp;
        +  X509 *	x509;
        +
        +  /* Just load the crypto library error strings,
        +   * SSL_load_error_strings() loads the crypto AND the SSL ones */
        +  /* SSL_load_error_strings();*/
        +  ERR_load_crypto_strings();
        +  
        +  /* Read private key */
        +  
        +  fp = fopen (keyfile, "r");
        +  if (fp == NULL) exit (1);
        +  pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
        +  fclose (fp);
        +
        +  if (pkey == NULL) { 
        +	ERR_print_errors_fp (stderr);
        +	exit (1);
        +  }
        +  
        +  /* Do the signature */
        +  
        +  EVP_SignInit   (&md_ctx, EVP_sha1());
        +  EVP_SignUpdate (&md_ctx, data, strlen(data));
        +  sig_len = sizeof(sig_buf);
        +  err = EVP_SignFinal (&md_ctx, sig_buf, &sig_len, pkey);
        +
        +  if (err != 1) {
        +	ERR_print_errors_fp(stderr);
        +	exit (1);
        +  }
        +
        +  EVP_PKEY_free (pkey);
        +  
        +  /* Read public key */
        +  
        +  fp = fopen (certfile, "r");
        +  if (fp == NULL) exit (1);
        +  x509 = PEM_read_X509(fp, NULL, NULL, NULL);
        +  fclose (fp);
        +
        +  if (x509 == NULL) {
        +	ERR_print_errors_fp (stderr);
        +	exit (1);
        +  }
        +  
        +  /* Get public key - eay */
        +  pkey=X509_get_pubkey(x509);
        +  if (pkey == NULL) {
        +	ERR_print_errors_fp (stderr);
        +	exit (1);
        +  }
        +
        +  /* Verify the signature */
        +  
        +  EVP_VerifyInit   (&md_ctx, EVP_sha1());
        +  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
        +  err = EVP_VerifyFinal (&md_ctx, sig_buf, sig_len, pkey);
        +  EVP_PKEY_free (pkey);
        +
        +  if (err != 1) {
        +	ERR_print_errors_fp (stderr);
        +	exit (1);
        +  }
        +  printf ("Signature Verified Ok.\n");
        +  return(0);
        +}
        diff --git a/vendor/openssl/openssl/demos/sign/sign.txt b/vendor/openssl/openssl/demos/sign/sign.txt
        new file mode 100644
        index 000000000..2aa2b46cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/sign/sign.txt
        @@ -0,0 +1,170 @@
        +From ssl-lists-owner@mincom.com Mon Sep 30 22:43:15 1996
        +Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA12802
        +  (5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 12:45:43 +1000
        +Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id MAA25922 for ssl-users-outgoing; Mon, 30 Sep 1996 12:43:43 +1000 (EST)
        +Received: from orb.mincom.oz.au (eay@orb.mincom.oz.au [192.55.197.1]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id MAA25900 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 12:43:39 +1000 (EST)
        +Received: by orb.mincom.oz.au id AA12688
        +  (5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 12:43:16 +1000
        +Date: Mon, 30 Sep 1996 12:43:15 +1000 (EST)
        +From: Eric Young <eay@mincom.com>
        +X-Sender: eay@orb
        +To: Sampo Kellomaki <sampo@neuronio.pt>
        +Cc: ssl-users@mincom.com, sampo@brutus.neuronio.pt
        +Subject: Re: Signing with envelope routines
        +In-Reply-To: <199609300037.BAA08729@brutus.neuronio.pt>
        +Message-Id: <Pine.SOL.3.91.960930121504.11800Y-100000@orb>
        +Mime-Version: 1.0
        +Content-Type: TEXT/PLAIN; charset=US-ASCII
        +Sender: ssl-lists-owner@mincom.com
        +Precedence: bulk
        +Status: O
        +X-Status: 
        +
        +
        +On Mon, 30 Sep 1996, Sampo Kellomaki wrote:
        +> I have been trying to figure out how to produce signatures with EVP_
        +> routines. I seem to be able to read in private key and sign some
        +> data ok, but I can't figure out how I am supposed to read in
        +> public key so that I could verify my signature. I use self signed
        +> certificate.
        +
        +hmm... a rather poorly documented are of the library at this point in time.
        +
        +> I figured I should use
        +> 	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY,
        +> 	                               fp, NULL, NULL);
        +> to read in private key and this seems to work Ok.
        +> 
        +> However when I try analogous
        +> 	EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509,
        +> 	                               fp, NULL, NULL);
        +
        +What you should do is 
        +	X509 *x509=PEM_read_X509(fp,NULL,NULL);
        +	/* which is the same as PEM_ASN1_read(d2i_X509,PEM_STRING_X509,fp,
        +	 * NULL,NULL); */
        +Then
        +	EVP_PKEY *pkey=X509_extract_key(x509);
        +
        +There is also a X509_REQ_extract_key(req);
        +which gets the public key from a certificate request.
        +
        +I re-worked quite a bit of this when I cleaned up the dependancy on
        +RSA as the private key.
        +
        +> I figured that the second argument to PEM_ASN1_read should match the
        +> name in my PEM encoded object, hence PEM_STRING_X509.
        +> PEM_STRING_EVP_PKEY seems to be somehow magical
        +> because it matches whatever private key there happens to be. I could
        +> not find a similar constant to use with getting the certificate, however.
        +
        +:-), PEM_STRING_EVP_PKEY is 'magical' :-).  In theory I should be using a
        +standard such as PKCS#8 to store the private key so that the type is 
        +encoded in the asn.1 encoding of the object.
        +
        +> Is my approach of using PEM_ASN1_read correct? What should I pass in
        +> as name?  Can I use normal (or even self signed) X509 certificate for
        +> verifying the signature?
        +
        +The actual public key is kept in the certificate, so basically you have 
        +to load the certificate and then 'unpack' the public key from the 
        +certificate.
        +
        +> When will SSLeay documentation be written ;-)? If I would contribute
        +> comments to the code, would Eric take time to review them and include
        +> them in distribution?
        +
        +:-) After SSLv3 and PKCS#7 :-).  I actually started doing a function list 
        +but what I really need to do is do quite a few 'this is how you do xyz' 
        +type documents.  I suppose the current method is to post to ssl-users and 
        +I'll respond :-).
        +
        +I'll add a 'demo' directory for the next release, I've appended a 
        +modified version of your program that works, you were very close :-).
        +
        +eric
        +
        +/* sign-it.cpp  -  Simple test app using SSLeay envelopes to sign data
        +   29.9.1996, Sampo Kellomaki <sampo@iki.fi> */
        +
        +/* converted to C - eay :-) */
        +
        +#include <stdio.h>
        +#include "rsa.h"
        +#include "evp.h"
        +#include "objects.h"
        +#include "x509.h"
        +#include "err.h"
        +#include "pem.h"
        +#include "ssl.h"
        +
        +void main ()
        +{
        +  int err;
        +  int sig_len;
        +  unsigned char sig_buf [4096];
        +  static char certfile[] = "plain-cert.pem";
        +  static char keyfile[]  = "plain-key.pem";
        +  static char data[]     = "I owe you...";
        +  EVP_MD_CTX     md_ctx;
        +  EVP_PKEY *      pkey;
        +  FILE *          fp;
        +  X509 *	x509;
        +
        +  /* Just load the crypto library error strings,
        +   * SSL_load_error_strings() loads the crypto AND the SSL ones */
        +  /* SSL_load_error_strings();*/
        +  ERR_load_crypto_strings();
        +  
        +  /* Read private key */
        +  
        +  fp = fopen (keyfile, "r");   if (fp == NULL) exit (1);
        +  pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey,
        +				   PEM_STRING_EVP_PKEY,
        +				   fp,
        +				   NULL, NULL);
        +  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  fclose (fp);
        +  
        +  /* Do the signature */
        +  
        +  EVP_SignInit   (&md_ctx, EVP_md5());
        +  EVP_SignUpdate (&md_ctx, data, strlen(data));
        +  sig_len = sizeof(sig_buf);
        +  err = EVP_SignFinal (&md_ctx,
        +		       sig_buf, 
        +		       &sig_len,
        +		       pkey);
        +  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  EVP_PKEY_free (pkey);
        +  
        +  /* Read public key */
        +  
        +  fp = fopen (certfile, "r");   if (fp == NULL) exit (1);
        +  x509 = (X509 *)PEM_ASN1_read ((char *(*)())d2i_X509,
        +				   PEM_STRING_X509,
        +				   fp, NULL, NULL);
        +  if (x509 == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  fclose (fp);
        +  
        +  /* Get public key - eay */
        +  pkey=X509_extract_key(x509);
        +  if (pkey == NULL) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +
        +  /* Verify the signature */
        +  
        +  EVP_VerifyInit   (&md_ctx, EVP_md5());
        +  EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
        +  err = EVP_VerifyFinal (&md_ctx,
        +			 sig_buf,
        +			 sig_len,
        +			 pkey);
        +  if (err != 1) {  ERR_print_errors_fp (stderr);    exit (1);  }
        +  EVP_PKEY_free (pkey);
        +  printf ("Signature Verified Ok.\n");
        +}
        +
        +
        +
        +
        +
        diff --git a/vendor/openssl/openssl/demos/smime/cacert.pem b/vendor/openssl/openssl/demos/smime/cacert.pem
        new file mode 100644
        index 000000000..75cbb347a
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/cacert.pem
        @@ -0,0 +1,18 @@
        +-----BEGIN CERTIFICATE-----
        +MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
        +BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
        +dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3
        +WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD
        +aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN
        +RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz
        +i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR
        +ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT
        +jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx
        +CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B
        +SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD
        +VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB
        +ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc
        +G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo
        +u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF
        +1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/demos/smime/cakey.pem b/vendor/openssl/openssl/demos/smime/cakey.pem
        new file mode 100644
        index 000000000..3b53c5e81
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/cakey.pem
        @@ -0,0 +1,15 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd
        +c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3
        +dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB
        +AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5
        +HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs
        +tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS
        +rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18
        +9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u
        +jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is
        +uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU
        ++VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP
        +wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW
        +8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/smime/encr.txt b/vendor/openssl/openssl/demos/smime/encr.txt
        new file mode 100644
        index 000000000..f163a326e
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/encr.txt
        @@ -0,0 +1,3 @@
        +Content-type: text/plain
        +
        +Sample OpenSSL Data for PKCS#7 encryption
        diff --git a/vendor/openssl/openssl/demos/smime/sign.txt b/vendor/openssl/openssl/demos/smime/sign.txt
        new file mode 100644
        index 000000000..af1341d0a
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/sign.txt
        @@ -0,0 +1,3 @@
        +Content-type: text/plain
        +
        +Test OpenSSL Signed Content
        diff --git a/vendor/openssl/openssl/demos/smime/signer.pem b/vendor/openssl/openssl/demos/smime/signer.pem
        new file mode 100644
        index 000000000..bac16ba96
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/signer.pem
        @@ -0,0 +1,32 @@
        +-----BEGIN CERTIFICATE-----
        +MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
        +BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
        +dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3
        +WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
        +TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl
        +bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz
        +jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L
        +ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y
        +gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
        +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
        +BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
        +2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX
        +MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn
        ++Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv
        +lDiQlgX0JtmLgA==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm
        +1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH
        +Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB
        +AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG
        +mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o
        +wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx
        +04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55
        +qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc
        +YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY
        +sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4
        +4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid
        +7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5
        +xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/smime/signer2.pem b/vendor/openssl/openssl/demos/smime/signer2.pem
        new file mode 100644
        index 000000000..25e23d131
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/signer2.pem
        @@ -0,0 +1,32 @@
        +-----BEGIN CERTIFICATE-----
        +MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
        +BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
        +dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0
        +WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
        +TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl
        +bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ
        +jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW
        +ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW
        +GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
        +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
        +BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
        +2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X
        +h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4
        +aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR
        +2aX6rl2JEuJ5Yg==
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM
        +nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f
        +nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB
        +AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF
        +6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2
        +CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf
        +m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX
        +2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr
        +upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4
        +ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL
        +SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk
        +gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX
        +pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/smime/smdec.c b/vendor/openssl/openssl/demos/smime/smdec.c
        new file mode 100644
        index 000000000..8b1a8545a
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/smdec.c
        @@ -0,0 +1,83 @@
        +/* Simple S/MIME signing example */
        +#include <openssl/pem.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *rcert = NULL;
        +	EVP_PKEY *rkey = NULL;
        +	PKCS7 *p7 = NULL;
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in recipient certificate and private key */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!rcert || !rkey)
        +		goto err;
        +
        +	/* Open content being signed */
        +
        +	in = BIO_new_file("smencr.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Sign content */
        +	p7 = SMIME_read_PKCS7(in, NULL);
        +
        +	if (!p7)
        +		goto err;
        +
        +	out = BIO_new_file("encrout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Decrypt S/MIME message */
        +	if (!PKCS7_decrypt(p7, rkey, rcert, out, 0))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Signing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (p7)
        +		PKCS7_free(p7);
        +	if (rcert)
        +		X509_free(rcert);
        +	if (rkey)
        +		EVP_PKEY_free(rkey);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        +
        +
        +
        +
        diff --git a/vendor/openssl/openssl/demos/smime/smenc.c b/vendor/openssl/openssl/demos/smime/smenc.c
        new file mode 100644
        index 000000000..77dd732fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/smenc.c
        @@ -0,0 +1,92 @@
        +/* Simple S/MIME encrypt example */
        +#include <openssl/pem.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *rcert = NULL;
        +	STACK_OF(X509) *recips = NULL;
        +	PKCS7 *p7 = NULL;
        +	int ret = 1;
        +
        +	/*
        +	 * On OpenSSL 0.9.9 only:
        +	 * for streaming set PKCS7_STREAM
        +	 */
        +	int flags = PKCS7_STREAM;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in recipient certificate */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	if (!rcert)
        +		goto err;
        +
        +	/* Create recipient STACK and add recipient cert to it */
        +	recips = sk_X509_new_null();
        +
        +	if (!recips || !sk_X509_push(recips, rcert))
        +		goto err;
        +
        +	/* sk_X509_pop_free will free up recipient STACK and its contents
        +	 * so set rcert to NULL so it isn't freed up twice.
        +	 */
        +	rcert = NULL;
        +
        +	/* Open content being encrypted */
        +
        +	in = BIO_new_file("encr.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* encrypt content */
        +	p7 = PKCS7_encrypt(recips, in, EVP_des_ede3_cbc(), flags);
        +
        +	if (!p7)
        +		goto err;
        +
        +	out = BIO_new_file("smencr.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* Write out S/MIME message */
        +	if (!SMIME_write_PKCS7(out, p7, in, flags))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Encrypting Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (p7)
        +		PKCS7_free(p7);
        +	if (rcert)
        +		X509_free(rcert);
        +	if (recips)
        +		sk_X509_pop_free(recips, X509_free);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/smime/smsign.c b/vendor/openssl/openssl/demos/smime/smsign.c
        new file mode 100644
        index 000000000..ba78830cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/smsign.c
        @@ -0,0 +1,89 @@
        +/* Simple S/MIME signing example */
        +#include <openssl/pem.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *scert = NULL;
        +	EVP_PKEY *skey = NULL;
        +	PKCS7 *p7 = NULL;
        +	int ret = 1;
        +
        +	/* For simple S/MIME signing use PKCS7_DETACHED.
        +	 * On OpenSSL 0.9.9 only:
        +	 * for streaming detached set PKCS7_DETACHED|PKCS7_STREAM
        +	 * for streaming non-detached set PKCS7_STREAM
        +	 */
        +	int flags = PKCS7_DETACHED|PKCS7_STREAM;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Read in signer certificate and private key */
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!scert || !skey)
        +		goto err;
        +
        +	/* Open content being signed */
        +
        +	in = BIO_new_file("sign.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Sign content */
        +	p7 = PKCS7_sign(scert, skey, NULL, in, flags);
        +
        +	if (!p7)
        +		goto err;
        +
        +	out = BIO_new_file("smout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	if (!(flags & PKCS7_STREAM))
        +		BIO_reset(in);
        +
        +	/* Write out S/MIME message */
        +	if (!SMIME_write_PKCS7(out, p7, in, flags))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Signing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (p7)
        +		PKCS7_free(p7);
        +	if (scert)
        +		X509_free(scert);
        +	if (skey)
        +		EVP_PKEY_free(skey);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/smime/smsign2.c b/vendor/openssl/openssl/demos/smime/smsign2.c
        new file mode 100644
        index 000000000..ff835c568
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/smsign2.c
        @@ -0,0 +1,107 @@
        +/* S/MIME signing example: 2 signers. OpenSSL 0.9.9 only */
        +#include <openssl/pem.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL;
        +	X509 *scert = NULL, *scert2 = NULL;
        +	EVP_PKEY *skey = NULL, *skey2 = NULL;
        +	PKCS7 *p7 = NULL;
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	tbio = BIO_new_file("signer.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	BIO_free(tbio);
        +
        +	tbio = BIO_new_file("signer2.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	BIO_reset(tbio);
        +
        +	skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
        +
        +	if (!scert2 || !skey2)
        +		goto err;
        +
        +	in = BIO_new_file("sign.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	p7 = PKCS7_sign(NULL, NULL, NULL, in, PKCS7_STREAM|PKCS7_PARTIAL);
        +
        +	if (!p7)
        +		goto err;
        +
        +	/* Add each signer in turn */
        +
        +	if (!PKCS7_sign_add_signer(p7, scert, skey, NULL, 0))
        +		goto err;
        +
        +	if (!PKCS7_sign_add_signer(p7, scert2, skey2, NULL, 0))
        +		goto err;
        +
        +	out = BIO_new_file("smout.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	/* NB: content included and finalized by SMIME_write_PKCS7 */
        +
        +	if (!SMIME_write_PKCS7(out, p7, in, PKCS7_STREAM))
        +		goto err;
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Signing Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (p7)
        +		PKCS7_free(p7);
        +
        +	if (scert)
        +		X509_free(scert);
        +	if (skey)
        +		EVP_PKEY_free(skey);
        +
        +	if (scert2)
        +		X509_free(scert2);
        +	if (skey)
        +		EVP_PKEY_free(skey2);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        +
        +
        +
        +
        diff --git a/vendor/openssl/openssl/demos/smime/smver.c b/vendor/openssl/openssl/demos/smime/smver.c
        new file mode 100644
        index 000000000..9d360c273
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/smime/smver.c
        @@ -0,0 +1,87 @@
        +/* Simple S/MIME verification example */
        +#include <openssl/pem.h>
        +#include <openssl/pkcs7.h>
        +#include <openssl/err.h>
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
        +	X509_STORE *st = NULL;
        +	X509 *cacert = NULL;
        +	PKCS7 *p7 = NULL;
        +
        +	int ret = 1;
        +
        +	OpenSSL_add_all_algorithms();
        +	ERR_load_crypto_strings();
        +
        +	/* Set up trusted CA certificate store */
        +
        +	st = X509_STORE_new();
        +
        +	/* Read in signer certificate and private key */
        +	tbio = BIO_new_file("cacert.pem", "r");
        +
        +	if (!tbio)
        +		goto err;
        +
        +	cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
        +
        +	if (!cacert)
        +		goto err;
        +
        +	if (!X509_STORE_add_cert(st, cacert))
        +		goto err;
        +
        +	/* Open content being signed */
        +
        +	in = BIO_new_file("smout.txt", "r");
        +
        +	if (!in)
        +		goto err;
        +
        +	/* Sign content */
        +	p7 = SMIME_read_PKCS7(in, &cont);
        +
        +	if (!p7)
        +		goto err;
        +
        +	/* File to output verified content to */
        +	out = BIO_new_file("smver.txt", "w");
        +	if (!out)
        +		goto err;
        +
        +	if (!PKCS7_verify(p7, NULL, st, cont, out, 0))
        +		{
        +		fprintf(stderr, "Verification Failure\n");
        +		goto err;
        +		}
        +
        +	fprintf(stderr, "Verification Successful\n");
        +
        +	ret = 0;
        +
        +	err:
        +
        +	if (ret)
        +		{
        +		fprintf(stderr, "Error Verifying Data\n");
        +		ERR_print_errors_fp(stderr);
        +		}
        +
        +	if (p7)
        +		PKCS7_free(p7);
        +
        +	if (cacert)
        +		X509_free(cacert);
        +
        +	if (in)
        +		BIO_free(in);
        +	if (out)
        +		BIO_free(out);
        +	if (tbio)
        +		BIO_free(tbio);
        +
        +	return ret;
        +
        +	}
        diff --git a/vendor/openssl/openssl/demos/spkigen.c b/vendor/openssl/openssl/demos/spkigen.c
        new file mode 100644
        index 000000000..2cd5dfea9
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/spkigen.c
        @@ -0,0 +1,161 @@
        +/* NOCW */
        +/* demos/spkigen.c
        + * 18-Mar-1997 - eay - A quick hack :-) 
        + * 		version 1.1, it would probably help to save or load the
        + *		private key :-)
        + */
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/err.h>
        +#include <openssl/asn1.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +/* The following two don't exist in SSLeay but they are in here as
        + * examples */
        +#define PEM_write_SPKI(fp,x) \
        +	PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\
        +			(char *)x,NULL,NULL,0,NULL)
        +int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
        +
        +/* These are defined in the next version of SSLeay */
        +int EVP_PKEY_assign(EVP_PKEY *pkey, int type,char *key);
        +#define RSA_F4	0x10001
        +#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
        +					(char *)(rsa))
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	RSA *rsa=NULL;
        +	NETSCAPE_SPKI *spki=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	char buf[128];
        +	int ok=0,i;
        +	FILE *fp;
        +
        +	pkey=EVP_PKEY_new();
        +	 
        +	if (argc < 2)
        +		{
        +		/* Generate an RSA key, the random state should have been seeded
        +		 * with lots of calls to RAND_seed(....) */
        +		fprintf(stderr,"generating RSA key, could take some time...\n");
        +		if ((rsa=RSA_generate_key(512,RSA_F4,NULL)) == NULL) goto err;
        +		}
        +	else
        +		{
        +		if ((fp=fopen(argv[1],"r")) == NULL)
        +			{ perror(argv[1]); goto err; }
        +		if ((rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL)) == NULL)
        +			goto err;
        +		fclose(fp);
        +		}
        +	
        +	if (!EVP_PKEY_assign_RSA(pkey,rsa)) goto err;
        +	rsa=NULL;
        +
        +	/* lets make the spki and set the public key and challenge */
        +	if ((spki=NETSCAPE_SPKI_new()) == NULL) goto err;
        +
        +	if (!SPKI_set_pubkey(spki,pkey)) goto err;
        +
        +	fprintf(stderr,"please enter challenge string:");
        +	fflush(stderr);
        +	buf[0]='\0';
        +	fgets(buf,sizeof buf,stdin);
        +	i=strlen(buf);
        +	if (i > 0) buf[--i]='\0';
        +	if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge,
        +		buf,i)) goto err;
        +
        +	if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err;
        +	PEM_write_SPKI(stdout,spki);
        +	if (argc < 2)
        +		PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
        +
        +	ok=1;
        +err:
        +	if (!ok)
        +		{
        +		fprintf(stderr,"something bad happened....");
        +		ERR_print_errors_fp(stderr);
        +		}
        +	NETSCAPE_SPKI_free(spki);
        +	EVP_PKEY_free(pkey);
        +	exit(!ok);
        +	}
        +
        +/* This function is in the next version of SSLeay */
        +int EVP_PKEY_assign(pkey,type,key)
        +EVP_PKEY *pkey;
        +int type;
        +char *key;
        +	{
        +	if (pkey == NULL) return(0);
        +	if (pkey->pkey.ptr != NULL)
        +		{
        +		if (pkey->type == EVP_PKEY_RSA)
        +			RSA_free(pkey->pkey.rsa);
        +		/* else memory leak */
        +		}
        +	pkey->type=type;
        +	pkey->pkey.ptr=key;
        +	return(1);
        +	}
        +
        +/* While I have a 
        + * X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does
        + * not currently exist so here is a version of it.
        + * The next SSLeay release will probably have
        + * X509_set_pubkey(),
        + * X509_REQ_set_pubkey() and
        + * NETSCAPE_SPKI_set_pubkey()
        + * as macros calling the same function */
        +int SPKI_set_pubkey(x,pkey)
        +NETSCAPE_SPKI *x;
        +EVP_PKEY *pkey;
        +	{
        +	int ok=0;
        +	X509_PUBKEY *pk;
        +	X509_ALGOR *a;
        +	ASN1_OBJECT *o;
        +	unsigned char *s,*p;
        +	int i;
        +
        +	if (x == NULL) return(0);
        +
        +	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
        +	a=pk->algor;
        +
        +	/* set the algorithm id */
        +	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
        +	ASN1_OBJECT_free(a->algorithm);
        +	a->algorithm=o;
        +
        +	/* Set the parameter list */
        +	if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL))
        +		{
        +		ASN1_TYPE_free(a->parameter);
        +		a->parameter=ASN1_TYPE_new();
        +		a->parameter->type=V_ASN1_NULL;
        +		}
        +	i=i2d_PublicKey(pkey,NULL);
        +	if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err;
        +	p=s;
        +	i2d_PublicKey(pkey,&p);
        +	if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
        +	free(s);
        +
        +	X509_PUBKEY_free(x->spkac->pubkey);
        +	x->spkac->pubkey=pk;
        +	pk=NULL;
        +	ok=1;
        +err:
        +	if (pk != NULL) X509_PUBKEY_free(pk);
        +	return(ok);
        +	}
        +
        diff --git a/vendor/openssl/openssl/demos/ssl/cli.cpp b/vendor/openssl/openssl/demos/ssl/cli.cpp
        new file mode 100644
        index 000000000..49cba5da0
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssl/cli.cpp
        @@ -0,0 +1,110 @@
        +/* cli.cpp  -  Minimal ssleay client for Unix
        +   30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
        +
        +/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b
        +   Simplified to be even more minimal
        +   12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */
        +
        +#include <stdio.h>
        +#include <memory.h>
        +#include <errno.h>
        +#include <sys/types.h>
        +#include <sys/socket.h>
        +#include <netinet/in.h>
        +#include <arpa/inet.h>
        +#include <netdb.h>
        +
        +#include <openssl/crypto.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +
        +
        +#define CHK_NULL(x) if ((x)==NULL) exit (1)
        +#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
        +#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
        +
        +void main ()
        +{
        +  int err;
        +  int sd;
        +  struct sockaddr_in sa;
        +  SSL_CTX* ctx;
        +  SSL*     ssl;
        +  X509*    server_cert;
        +  char*    str;
        +  char     buf [4096];
        +  SSL_METHOD *meth;
        +
        +  SSLeay_add_ssl_algorithms();
        +  meth = SSLv2_client_method();
        +  SSL_load_error_strings();
        +  ctx = SSL_CTX_new (meth);                        CHK_NULL(ctx);
        +
        +  CHK_SSL(err);
        +  
        +  /* ----------------------------------------------- */
        +  /* Create a socket and connect to server using normal socket calls. */
        +  
        +  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");
        + 
        +  memset (&sa, '\0', sizeof(sa));
        +  sa.sin_family      = AF_INET;
        +  sa.sin_addr.s_addr = inet_addr ("127.0.0.1");   /* Server IP */
        +  sa.sin_port        = htons     (1111);          /* Server Port number */
        +  
        +  err = connect(sd, (struct sockaddr*) &sa,
        +		sizeof(sa));                   CHK_ERR(err, "connect");
        +
        +  /* ----------------------------------------------- */
        +  /* Now we have TCP conncetion. Start SSL negotiation. */
        +  
        +  ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
        +  SSL_set_fd (ssl, sd);
        +  err = SSL_connect (ssl);                     CHK_SSL(err);
        +    
        +  /* Following two steps are optional and not required for
        +     data exchange to be successful. */
        +  
        +  /* Get the cipher - opt */
        +
        +  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
        +  
        +  /* Get server's certificate (note: beware of dynamic allocation) - opt */
        +
        +  server_cert = SSL_get_peer_certificate (ssl);       CHK_NULL(server_cert);
        +  printf ("Server certificate:\n");
        +  
        +  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
        +  CHK_NULL(str);
        +  printf ("\t subject: %s\n", str);
        +  OPENSSL_free (str);
        +
        +  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
        +  CHK_NULL(str);
        +  printf ("\t issuer: %s\n", str);
        +  OPENSSL_free (str);
        +
        +  /* We could do all sorts of certificate verification stuff here before
        +     deallocating the certificate. */
        +
        +  X509_free (server_cert);
        +  
        +  /* --------------------------------------------------- */
        +  /* DATA EXCHANGE - Send a message and receive a reply. */
        +
        +  err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));  CHK_SSL(err);
        +  
        +  err = SSL_read (ssl, buf, sizeof(buf) - 1);                     CHK_SSL(err);
        +  buf[err] = '\0';
        +  printf ("Got %d chars:'%s'\n", err, buf);
        +  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
        +
        +  /* Clean up. */
        +
        +  close (sd);
        +  SSL_free (ssl);
        +  SSL_CTX_free (ctx);
        +}
        +/* EOF - cli.cpp */
        diff --git a/vendor/openssl/openssl/demos/ssl/inetdsrv.cpp b/vendor/openssl/openssl/demos/ssl/inetdsrv.cpp
        new file mode 100644
        index 000000000..efd70d277
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssl/inetdsrv.cpp
        @@ -0,0 +1,98 @@
        +/* inetdserv.cpp  -  Minimal ssleay server for Unix inetd.conf
        + * 30.9.1996, Sampo Kellomaki <sampo@iki.fi>
        + * From /etc/inetd.conf:
        + *     1111 stream tcp nowait sampo /usr/users/sampo/demo/inetdserv inetdserv
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +
        +#include "rsa.h"       /* SSLeay stuff */
        +#include <openssl/crypto.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +
        +#define HOME "/usr/users/sampo/demo/"
        +#define CERTF HOME "plain-cert.pem"
        +#define KEYF  HOME "plain-key.pem"
        +
        +#define CHK_NULL(x) if ((x)==NULL) exit (1)
        +#define CHK_ERR(err,s) if ((err)==-1) \
        +                         { fprintf(log, "%s %d\n", (s), errno); exit(1); }
        +#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(log); exit(2); }
        +
        +void main ()
        +{
        +  int err;
        +  SSL_CTX* ctx;
        +  SSL*     ssl;
        +  X509*    client_cert;
        +  char*    str;
        +  char     buf [4096];
        +  FILE* log;
        +  
        +  log = fopen ("/dev/console", "a");                     CHK_NULL(log);
        +  fprintf (log, "inetdserv %ld\n", (long)getpid());
        +  
        +  SSL_load_error_strings();
        +  ctx = SSL_CTX_new (); CHK_NULL(ctx);
        +  
        +  err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF,  SSL_FILETYPE_PEM);
        +  CHK_SSL (err);
        +  
        +  err = SSL_CTX_use_certificate_file   (ctx, CERTF, SSL_FILETYPE_PEM);
        +  CHK_SSL (err);
        +
        +  /* inetd has already opened the TCP connection, so we can get right
        +     down to business. */
        +  
        +  ssl = SSL_new (ctx);  CHK_NULL(ssl);
        +  SSL_set_fd (ssl,  fileno(stdin));
        +  err = SSL_accept (ssl);                                CHK_SSL(err);
        +  
        +  /* Get the cipher - opt */
        +  
        +  fprintf (log, "SSL connection using %s\n", SSL_get_cipher (ssl));
        +  
        +  /* Get client's certificate (note: beware of dynamic allocation) - opt */
        +
        +  client_cert = SSL_get_peer_certificate (ssl);
        +  if (client_cert != NULL) {
        +    fprintf (log, "Client certificate:\n");
        +    
        +    str = X509_NAME_oneline (X509_get_subject_name (client_cert));
        +    CHK_NULL(str);
        +    fprintf (log, "\t subject: %s\n", str);
        +    OPENSSL_free (str);
        +    
        +    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert));
        +    CHK_NULL(str);
        +    fprintf (log, "\t issuer: %s\n", str);
        +    OPENSSL_free (str);
        +    
        +    /* We could do all sorts of certificate verification stuff here before
        +       deallocating the certificate. */
        +    
        +    X509_free (client_cert);
        +  } else
        +    fprintf (log, "Client doe not have certificate.\n");
        +
        +  /* ------------------------------------------------- */
        +  /* DATA EXCHANGE: Receive message and send reply  */
        +  
        +  err = SSL_read (ssl, buf, sizeof(buf) - 1);  CHK_SSL(err);
        +  buf[err] = '\0';
        +  fprintf (log, "Got %d chars:'%s'\n", err, buf);
        +  
        +  err = SSL_write (ssl, "Loud and clear.", strlen("Loud and clear."));
        +  CHK_SSL(err);
        +
        +  /* Clean up. */
        +
        +  fclose (log);
        +  SSL_free (ssl);
        +  SSL_CTX_free (ctx);
        +}
        +/* EOF - inetdserv.cpp */
        diff --git a/vendor/openssl/openssl/demos/ssl/serv.cpp b/vendor/openssl/openssl/demos/ssl/serv.cpp
        new file mode 100644
        index 000000000..b142c758d
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssl/serv.cpp
        @@ -0,0 +1,152 @@
        +/* serv.cpp  -  Minimal ssleay server for Unix
        +   30.9.1996, Sampo Kellomaki <sampo@iki.fi> */
        +
        +
        +/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b
        +   Simplified to be even more minimal
        +   12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */
        +
        +#include <stdio.h>
        +#include <unistd.h>
        +#include <stdlib.h>
        +#include <memory.h>
        +#include <errno.h>
        +#include <sys/types.h>
        +#include <sys/socket.h>
        +#include <netinet/in.h>
        +#include <arpa/inet.h>
        +#include <netdb.h>
        +
        +#include <openssl/rsa.h>       /* SSLeay stuff */
        +#include <openssl/crypto.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +
        +
        +/* define HOME to be dir for key and cert files... */
        +#define HOME "./"
        +/* Make these what you want for cert & key files */
        +#define CERTF  HOME "foo-cert.pem"
        +#define KEYF  HOME  "foo-cert.pem"
        +
        +
        +#define CHK_NULL(x) if ((x)==NULL) exit (1)
        +#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
        +#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
        +
        +void main ()
        +{
        +  int err;
        +  int listen_sd;
        +  int sd;
        +  struct sockaddr_in sa_serv;
        +  struct sockaddr_in sa_cli;
        +  size_t client_len;
        +  SSL_CTX* ctx;
        +  SSL*     ssl;
        +  X509*    client_cert;
        +  char*    str;
        +  char     buf [4096];
        +  SSL_METHOD *meth;
        +  
        +  /* SSL preliminaries. We keep the certificate and key with the context. */
        +
        +  SSL_load_error_strings();
        +  SSLeay_add_ssl_algorithms();
        +  meth = SSLv23_server_method();
        +  ctx = SSL_CTX_new (meth);
        +  if (!ctx) {
        +    ERR_print_errors_fp(stderr);
        +    exit(2);
        +  }
        +  
        +  if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
        +    ERR_print_errors_fp(stderr);
        +    exit(3);
        +  }
        +  if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
        +    ERR_print_errors_fp(stderr);
        +    exit(4);
        +  }
        +
        +  if (!SSL_CTX_check_private_key(ctx)) {
        +    fprintf(stderr,"Private key does not match the certificate public key\n");
        +    exit(5);
        +  }
        +
        +  /* ----------------------------------------------- */
        +  /* Prepare TCP socket for receiving connections */
        +
        +  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd, "socket");
        +  
        +  memset (&sa_serv, '\0', sizeof(sa_serv));
        +  sa_serv.sin_family      = AF_INET;
        +  sa_serv.sin_addr.s_addr = INADDR_ANY;
        +  sa_serv.sin_port        = htons (1111);          /* Server Port number */
        +  
        +  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
        +	     sizeof (sa_serv));                   CHK_ERR(err, "bind");
        +	     
        +  /* Receive a TCP connection. */
        +	     
        +  err = listen (listen_sd, 5);                    CHK_ERR(err, "listen");
        +  
        +  client_len = sizeof(sa_cli);
        +  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
        +  CHK_ERR(sd, "accept");
        +  close (listen_sd);
        +
        +  printf ("Connection from %lx, port %x\n",
        +	  sa_cli.sin_addr.s_addr, sa_cli.sin_port);
        +  
        +  /* ----------------------------------------------- */
        +  /* TCP connection is ready. Do server side SSL. */
        +
        +  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
        +  SSL_set_fd (ssl, sd);
        +  err = SSL_accept (ssl);                        CHK_SSL(err);
        +  
        +  /* Get the cipher - opt */
        +  
        +  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
        +  
        +  /* Get client's certificate (note: beware of dynamic allocation) - opt */
        +
        +  client_cert = SSL_get_peer_certificate (ssl);
        +  if (client_cert != NULL) {
        +    printf ("Client certificate:\n");
        +    
        +    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
        +    CHK_NULL(str);
        +    printf ("\t subject: %s\n", str);
        +    OPENSSL_free (str);
        +    
        +    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
        +    CHK_NULL(str);
        +    printf ("\t issuer: %s\n", str);
        +    OPENSSL_free (str);
        +    
        +    /* We could do all sorts of certificate verification stuff here before
        +       deallocating the certificate. */
        +    
        +    X509_free (client_cert);
        +  } else
        +    printf ("Client does not have certificate.\n");
        +
        +  /* DATA EXCHANGE - Receive message and send reply. */
        +
        +  err = SSL_read (ssl, buf, sizeof(buf) - 1);                   CHK_SSL(err);
        +  buf[err] = '\0';
        +  printf ("Got %d chars:'%s'\n", err, buf);
        +  
        +  err = SSL_write (ssl, "I hear you.", strlen("I hear you."));  CHK_SSL(err);
        +
        +  /* Clean up. */
        +
        +  close (sd);
        +  SSL_free (ssl);
        +  SSL_CTX_free (ctx);
        +}
        +/* EOF - serv.cpp */
        diff --git a/vendor/openssl/openssl/demos/ssltest-ecc/ECC-RSAcertgen.sh b/vendor/openssl/openssl/demos/ssltest-ecc/ECC-RSAcertgen.sh
        new file mode 100644
        index 000000000..b31a4f1ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssltest-ecc/ECC-RSAcertgen.sh
        @@ -0,0 +1,98 @@
        +#!/bin/sh
        +
        +# For a list of supported curves, use "apps/openssl ecparam -list_curves".
        +
        +# Path to the openssl distribution
        +OPENSSL_DIR=../..
        +# Path to the openssl program
        +OPENSSL_CMD=$OPENSSL_DIR/apps/openssl
        +# Option to find configuration file
        +OPENSSL_CNF="-config $OPENSSL_DIR/apps/openssl.cnf"
        +# Directory where certificates are stored
        +CERTS_DIR=./Certs
        +# Directory where private key files are stored
        +KEYS_DIR=$CERTS_DIR
        +# Directory where combo files (containing a certificate and corresponding
        +# private key together) are stored
        +COMBO_DIR=$CERTS_DIR
        +# cat command
        +CAT=/bin/cat
        +# rm command
        +RM=/bin/rm
        +# mkdir command
        +MKDIR=/bin/mkdir
        +# The certificate will expire these many days after the issue date.
        +DAYS=1500
        +TEST_CA_FILE=rsa1024TestCA
        +
        +TEST_SERVER_CURVE=sect163r1
        +TEST_SERVER_FILE=sect163r1-rsaTestServer
        +TEST_SERVER_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (sect163r1 key signed with RSA)"
        +
        +TEST_CLIENT_CURVE=sect163r1
        +TEST_CLIENT_FILE=sect163r1-rsaTestClient
        +TEST_CLIENT_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Client (sect163r1 key signed with RSA)"
        +
        +# Generating an EC certificate involves the following main steps
        +# 1. Generating curve parameters (if needed)
        +# 2. Generating a certificate request
        +# 3. Signing the certificate request 
        +# 4. [Optional] One can combine the cert and private key into a single
        +#    file and also delete the certificate request
        +
        +$MKDIR -p $CERTS_DIR
        +$MKDIR -p $KEYS_DIR
        +$MKDIR -p $COMBO_DIR
        +
        +echo "GENERATING A TEST SERVER CERTIFICATE (ECC key signed with RSA)"
        +echo "=============================================================="
        +$OPENSSL_CMD ecparam -name $TEST_SERVER_CURVE -out $TEST_SERVER_CURVE.pem
        +
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_SERVER_DN" \
        +    -keyout $KEYS_DIR/$TEST_SERVER_FILE.key.pem \
        +    -newkey ec:$TEST_SERVER_CURVE.pem -new \
        +    -out $CERTS_DIR/$TEST_SERVER_FILE.req.pem
        +
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_SERVER_FILE.req.pem \
        +    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
        +    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -CAcreateserial
        +
        +# Display the certificate 
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_SERVER_FILE.pem
        +$CAT $KEYS_DIR/$TEST_SERVER_FILE.key.pem >> $COMBO_DIR/$TEST_SERVER_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_SERVER_FILE.req.pem
        +
        +echo "GENERATING A TEST CLIENT CERTIFICATE (ECC key signed with RSA)"
        +echo "=============================================================="
        +$OPENSSL_CMD ecparam -name $TEST_CLIENT_CURVE -out $TEST_CLIENT_CURVE.pem
        +
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CLIENT_DN" \
        +	     -keyout $KEYS_DIR/$TEST_CLIENT_FILE.key.pem \
        +	     -newkey ec:$TEST_CLIENT_CURVE.pem -new \
        +	     -out $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
        +
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_CLIENT_FILE.req.pem \
        +    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
        +    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -CAcreateserial
        +
        +# Display the certificate 
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_CLIENT_FILE.pem
        +$CAT $KEYS_DIR/$TEST_CLIENT_FILE.key.pem >> $COMBO_DIR/$TEST_CLIENT_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
        +
        diff --git a/vendor/openssl/openssl/demos/ssltest-ecc/ECCcertgen.sh b/vendor/openssl/openssl/demos/ssltest-ecc/ECCcertgen.sh
        new file mode 100644
        index 000000000..a47b8bb0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssltest-ecc/ECCcertgen.sh
        @@ -0,0 +1,164 @@
        +#!/bin/sh
        +
        +# For a list of supported curves, use "apps/openssl ecparam -list_curves".
        +
        +# Path to the openssl distribution
        +OPENSSL_DIR=../..
        +# Path to the openssl program
        +OPENSSL_CMD=$OPENSSL_DIR/apps/openssl
        +# Option to find configuration file
        +OPENSSL_CNF="-config $OPENSSL_DIR/apps/openssl.cnf"
        +# Directory where certificates are stored
        +CERTS_DIR=./Certs
        +# Directory where private key files are stored
        +KEYS_DIR=$CERTS_DIR
        +# Directory where combo files (containing a certificate and corresponding
        +# private key together) are stored
        +COMBO_DIR=$CERTS_DIR
        +# cat command
        +CAT=/bin/cat
        +# rm command
        +RM=/bin/rm
        +# mkdir command
        +MKDIR=/bin/mkdir
        +# The certificate will expire these many days after the issue date.
        +DAYS=1500
        +TEST_CA_CURVE=secp160r1
        +TEST_CA_FILE=secp160r1TestCA
        +TEST_CA_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test CA (Elliptic curve secp160r1)"
        +
        +TEST_SERVER_CURVE=secp160r2
        +TEST_SERVER_FILE=secp160r2TestServer
        +TEST_SERVER_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (Elliptic curve secp160r2)"
        +
        +TEST_CLIENT_CURVE=secp160r2
        +TEST_CLIENT_FILE=secp160r2TestClient
        +TEST_CLIENT_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Client (Elliptic curve secp160r2)"
        +
        +# Generating an EC certificate involves the following main steps
        +# 1. Generating curve parameters (if needed)
        +# 2. Generating a certificate request
        +# 3. Signing the certificate request 
        +# 4. [Optional] One can combine the cert and private key into a single
        +#    file and also delete the certificate request
        +
        +$MKDIR -p $CERTS_DIR
        +$MKDIR -p $KEYS_DIR
        +$MKDIR -p $COMBO_DIR
        +
        +echo "Generating self-signed CA certificate (on curve $TEST_CA_CURVE)"
        +echo "==============================================================="
        +$OPENSSL_CMD ecparam -name $TEST_CA_CURVE -out $TEST_CA_CURVE.pem
        +
        +# Generate a new certificate request in $TEST_CA_FILE.req.pem. A 
        +# new ecdsa (actually ECC) key pair is generated on the parameters in
        +# $TEST_CA_CURVE.pem and the private key is saved in $TEST_CA_FILE.key.pem
        +# WARNING: By using the -nodes option, we force the private key to be 
        +# stored in the clear (rather than encrypted with a password).
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CA_DN" \
        +    -keyout $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -newkey ec:$TEST_CA_CURVE.pem -new \
        +    -out $CERTS_DIR/$TEST_CA_FILE.req.pem
        +
        +# Sign the certificate request in $TEST_CA_FILE.req.pem using the
        +# private key in $TEST_CA_FILE.key.pem and include the CA extension.
        +# Make the certificate valid for 1500 days from the time of signing.
        +# The certificate is written into $TEST_CA_FILE.cert.pem
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_CA_FILE.req.pem \
        +    -extfile $OPENSSL_DIR/apps/openssl.cnf \
        +    -extensions v3_ca \
        +    -signkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_CA_FILE.cert.pem
        +
        +# Display the certificate
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_CA_FILE.pem
        +$CAT $KEYS_DIR/$TEST_CA_FILE.key.pem >> $COMBO_DIR/$TEST_CA_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_CA_FILE.req.pem
        +
        +echo "GENERATING A TEST SERVER CERTIFICATE (on elliptic curve $TEST_SERVER_CURVE)"
        +echo "=========================================================================="
        +# Generate parameters for curve $TEST_SERVER_CURVE, if needed
        +$OPENSSL_CMD ecparam -name $TEST_SERVER_CURVE -out $TEST_SERVER_CURVE.pem
        +
        +# Generate a new certificate request in $TEST_SERVER_FILE.req.pem. A 
        +# new ecdsa (actually ECC) key pair is generated on the parameters in
        +# $TEST_SERVER_CURVE.pem and the private key is saved in 
        +# $TEST_SERVER_FILE.key.pem
        +# WARNING: By using the -nodes option, we force the private key to be 
        +# stored in the clear (rather than encrypted with a password).
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_SERVER_DN" \
        +    -keyout $KEYS_DIR/$TEST_SERVER_FILE.key.pem \
        +    -newkey ec:$TEST_SERVER_CURVE.pem -new \
        +    -out $CERTS_DIR/$TEST_SERVER_FILE.req.pem
        +
        +# Sign the certificate request in $TEST_SERVER_FILE.req.pem using the
        +# CA certificate in $TEST_CA_FILE.cert.pem and the CA private key in
        +# $TEST_CA_FILE.key.pem. Since we do not have an existing serial number
        +# file for this CA, create one. Make the certificate valid for $DAYS days
        +# from the time of signing. The certificate is written into 
        +# $TEST_SERVER_FILE.cert.pem
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_SERVER_FILE.req.pem \
        +    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
        +    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -CAcreateserial
        +
        +# Display the certificate 
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_SERVER_FILE.pem
        +$CAT $KEYS_DIR/$TEST_SERVER_FILE.key.pem >> $COMBO_DIR/$TEST_SERVER_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_SERVER_FILE.req.pem
        +
        +echo "GENERATING A TEST CLIENT CERTIFICATE (on elliptic curve $TEST_CLIENT_CURVE)"
        +echo "=========================================================================="
        +# Generate parameters for curve $TEST_CLIENT_CURVE, if needed
        +$OPENSSL_CMD ecparam -name $TEST_CLIENT_CURVE -out $TEST_CLIENT_CURVE.pem
        +
        +# Generate a new certificate request in $TEST_CLIENT_FILE.req.pem. A 
        +# new ecdsa (actually ECC) key pair is generated on the parameters in
        +# $TEST_CLIENT_CURVE.pem and the private key is saved in 
        +# $TEST_CLIENT_FILE.key.pem
        +# WARNING: By using the -nodes option, we force the private key to be 
        +# stored in the clear (rather than encrypted with a password).
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CLIENT_DN" \
        +	     -keyout $KEYS_DIR/$TEST_CLIENT_FILE.key.pem \
        +	     -newkey ec:$TEST_CLIENT_CURVE.pem -new \
        +	     -out $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
        +
        +# Sign the certificate request in $TEST_CLIENT_FILE.req.pem using the
        +# CA certificate in $TEST_CA_FILE.cert.pem and the CA private key in
        +# $TEST_CA_FILE.key.pem. Since we do not have an existing serial number
        +# file for this CA, create one. Make the certificate valid for $DAYS days
        +# from the time of signing. The certificate is written into 
        +# $TEST_CLIENT_FILE.cert.pem
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_CLIENT_FILE.req.pem \
        +    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
        +    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -CAcreateserial
        +
        +# Display the certificate 
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_CLIENT_FILE.pem
        +$CAT $KEYS_DIR/$TEST_CLIENT_FILE.key.pem >> $COMBO_DIR/$TEST_CLIENT_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
        +
        +
        +
        diff --git a/vendor/openssl/openssl/demos/ssltest-ecc/README b/vendor/openssl/openssl/demos/ssltest-ecc/README
        new file mode 100644
        index 000000000..71c070af1
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssltest-ecc/README
        @@ -0,0 +1,15 @@
        +Scripts for using ECC ciphersuites with test/testssl
        +(these ciphersuites are described in the Internet Draft available at
        +http://www.ietf.org/internet-drafts/draft-ietf-tls-ecc-03.txt).
        +
        +Use ECCcertgen.sh, RSAcertgen.sh, ECC-RSAcertgen.sh to generate
        +root, client and server certs of the following types:
        +
        +     ECC certs signed with ECDSA
        +     RSA certs signed with RSA
        +     ECC certs signed with RSA
        +
        +Afterwards, you can use ssltest.sh to run the various tests;
        +specify one of the following options:
        +
        +     aecdh, ecdh-ecdsa, ecdhe-ecdsa, ecdh-rsa, ecdhe-rsa
        diff --git a/vendor/openssl/openssl/demos/ssltest-ecc/RSAcertgen.sh b/vendor/openssl/openssl/demos/ssltest-ecc/RSAcertgen.sh
        new file mode 100644
        index 000000000..0cb015359
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssltest-ecc/RSAcertgen.sh
        @@ -0,0 +1,121 @@
        +#!/bin/sh
        +
        +# For a list of supported curves, use "apps/openssl ecparam -list_curves".
        +
        +# Path to the openssl distribution
        +OPENSSL_DIR=../..
        +# Path to the openssl program
        +OPENSSL_CMD=$OPENSSL_DIR/apps/openssl
        +# Option to find configuration file
        +OPENSSL_CNF="-config $OPENSSL_DIR/apps/openssl.cnf"
        +# Directory where certificates are stored
        +CERTS_DIR=./Certs
        +# Directory where private key files are stored
        +KEYS_DIR=$CERTS_DIR
        +# Directory where combo files (containing a certificate and corresponding
        +# private key together) are stored
        +COMBO_DIR=$CERTS_DIR
        +# cat command
        +CAT=/bin/cat
        +# rm command
        +RM=/bin/rm
        +# mkdir command
        +MKDIR=/bin/mkdir
        +# The certificate will expire these many days after the issue date.
        +DAYS=1500
        +TEST_CA_FILE=rsa1024TestCA
        +TEST_CA_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test CA (1024 bit RSA)"
        +
        +TEST_SERVER_FILE=rsa1024TestServer
        +TEST_SERVER_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Server (1024 bit RSA)"
        +
        +TEST_CLIENT_FILE=rsa1024TestClient
        +TEST_CLIENT_DN="/C=US/ST=CA/L=Mountain View/O=Sun Microsystems, Inc./OU=Sun Microsystems Laboratories/CN=Test Client (1024 bit RSA)"
        +
        +# Generating an EC certificate involves the following main steps
        +# 1. Generating curve parameters (if needed)
        +# 2. Generating a certificate request
        +# 3. Signing the certificate request 
        +# 4. [Optional] One can combine the cert and private key into a single
        +#    file and also delete the certificate request
        +
        +$MKDIR -p $CERTS_DIR
        +$MKDIR -p $KEYS_DIR
        +$MKDIR -p $COMBO_DIR
        +
        +echo "Generating self-signed CA certificate (RSA)"
        +echo "==========================================="
        +
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CA_DN" \
        +    -keyout $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -newkey rsa:1024 -new \
        +    -out $CERTS_DIR/$TEST_CA_FILE.req.pem
        +
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_CA_FILE.req.pem \
        +    -extfile $OPENSSL_DIR/apps/openssl.cnf \
        +    -extensions v3_ca \
        +    -signkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_CA_FILE.cert.pem
        +
        +# Display the certificate
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CA_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_CA_FILE.pem
        +$CAT $KEYS_DIR/$TEST_CA_FILE.key.pem >> $COMBO_DIR/$TEST_CA_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_CA_FILE.req.pem
        +
        +echo "GENERATING A TEST SERVER CERTIFICATE (RSA)"
        +echo "=========================================="
        +
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_SERVER_DN" \
        +    -keyout $KEYS_DIR/$TEST_SERVER_FILE.key.pem \
        +    -newkey rsa:1024 -new \
        +    -out $CERTS_DIR/$TEST_SERVER_FILE.req.pem
        +
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_SERVER_FILE.req.pem \
        +    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
        +    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -CAcreateserial
        +
        +# Display the certificate 
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_SERVER_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_SERVER_FILE.pem
        +$CAT $KEYS_DIR/$TEST_SERVER_FILE.key.pem >> $COMBO_DIR/$TEST_SERVER_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_SERVER_FILE.req.pem
        +
        +echo "GENERATING A TEST CLIENT CERTIFICATE (RSA)"
        +echo "=========================================="
        +
        +$OPENSSL_CMD req $OPENSSL_CNF -nodes -subj "$TEST_CLIENT_DN" \
        +	     -keyout $KEYS_DIR/$TEST_CLIENT_FILE.key.pem \
        +	     -newkey rsa:1024 -new \
        +	     -out $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
        +
        +$OPENSSL_CMD x509 -req -days $DAYS \
        +    -in $CERTS_DIR/$TEST_CLIENT_FILE.req.pem \
        +    -CA $CERTS_DIR/$TEST_CA_FILE.cert.pem \
        +    -CAkey $KEYS_DIR/$TEST_CA_FILE.key.pem \
        +    -out $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -CAcreateserial
        +
        +# Display the certificate 
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -text
        +
        +# Place the certificate and key in a common file
        +$OPENSSL_CMD x509 -in $CERTS_DIR/$TEST_CLIENT_FILE.cert.pem -issuer -subject \
        +	 > $COMBO_DIR/$TEST_CLIENT_FILE.pem
        +$CAT $KEYS_DIR/$TEST_CLIENT_FILE.key.pem >> $COMBO_DIR/$TEST_CLIENT_FILE.pem
        +
        +# Remove the cert request file (no longer needed)
        +$RM $CERTS_DIR/$TEST_CLIENT_FILE.req.pem
        +
        diff --git a/vendor/openssl/openssl/demos/ssltest-ecc/ssltest.sh b/vendor/openssl/openssl/demos/ssltest-ecc/ssltest.sh
        new file mode 100644
        index 000000000..923ca4382
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/ssltest-ecc/ssltest.sh
        @@ -0,0 +1,188 @@
        +#! /bin/sh
        +# Tests ECC cipher suites using ssltest. Requires one argument which could
        +# be aecdh or ecdh-ecdsa or ecdhe-ecdsa or ecdh-rsa or ecdhe-rsa.
        +# A second optional argument can be one of ssl2 ssl3 or tls1
        +
        +if [ "$1" = "" ]; then
        +  (echo "Usage: $0 test [ protocol ]"
        +   echo "   where test is one of aecdh, ecdh-ecdsa, ecdhe-ecdsa, ecdh-rsa, ecdhe-rsa"
        +   echo "   and protocol (optional) is one of ssl2, ssl3, tls1"
        +   echo "Run RSAcertgen.sh, ECC-RSAcertgen.sh, ECCcertgen.sh first."
        +  ) >&2
        +  exit 1
        +fi
        +
        +
        +OPENSSL_DIR=../..
        +CERTS_DIR=./Certs
        +SSLTEST=$OPENSSL_DIR/test/ssltest
        +# SSL protocol version to test (one of ssl2 ssl3 or tls1)"
        +SSLVERSION=
        +
        +# These don't really require any certificates
        +AECDH_CIPHER_LIST="AECDH-AES256-SHA AECDH-AES128-SHA AECDH-DES-CBC3-SHA AECDH-RC4-SHA AECDH-NULL-SHA"
        +
        +# These require ECC certificates signed with ECDSA
        +# The EC public key must be authorized for key agreement.
        +ECDH_ECDSA_CIPHER_LIST="ECDH-ECDSA-AES256-SHA ECDH-ECDSA-AES128-SHA ECDH-ECDSA-DES-CBC3-SHA ECDH-ECDSA-RC4-SHA ECDH-ECDSA-NULL-SHA"
        +
        +# These require ECC certificates.
        +# The EC public key must be authorized for digital signature.
        +ECDHE_ECDSA_CIPHER_LIST="ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-DES-CBC3-SHA ECDHE-ECDSA-RC4-SHA ECDHE-ECDSA-NULL-SHA"
        +
        +# These require ECC certificates signed with RSA.
        +# The EC public key must be authorized for key agreement.
        +ECDH_RSA_CIPHER_LIST="ECDH-RSA-AES256-SHA ECDH-RSA-AES128-SHA ECDH-RSA-DES-CBC3-SHA ECDH-RSA-RC4-SHA ECDH-RSA-NULL-SHA"
        +
        +# These require RSA certificates.
        +# The RSA public key must be authorized for digital signature.
        +ECDHE_RSA_CIPHER_LIST="ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-RSA-RC4-SHA ECDHE-RSA-NULL-SHA"
        +
        +# List of Elliptic curves over which we wish to test generation of
        +# ephemeral ECDH keys when using AECDH or ECDHE ciphers
        +# NOTE: secp192r1 = prime192v1 and secp256r1 = prime256v1
        +#ELLIPTIC_CURVE_LIST="secp112r1 sect113r2 secp128r1 sect131r1 secp160k1 sect163r2 wap-wsg-idm-ecid-wtls7 c2pnb163v3 c2pnb176v3 c2tnb191v3 secp192r1 prime192v3 sect193r2 secp224r1 wap-wsg-idm-ecid-wtls10 sect239k1 prime239v2 secp256r1 prime256v1 sect283k1 secp384r1 sect409r1 secp521r1 sect571r1"
        +ELLIPTIC_CURVE_LIST="sect163k1 sect163r1 sect163r2 sect193r1 sect193r2 sect233k1 sect233r1 sect239k1 sect283k1 sect283r1 sect409k1 sect409r1 sect571k1 sect571r1 secp160k1 secp160r1 secp160r2 secp192k1 prime192v1 secp224k1 secp224r1 secp256k1 prime256v1 secp384r1 secp521r1"
        +
        +DEFAULT_CURVE="sect163r2"
        +
        +if [ "$2" = "" ]; then
        +    if [ "$SSL_VERSION" = "" ]; then
        +	SSL_VERSION=""
        +    else
        +	SSL_VERSION="-$SSL_VERSION"
        +    fi
        +else
        +    SSL_VERSION="-$2"
        +fi
        +
        +#==============================================================
        +# Anonymous cipher suites do not require key or certificate files
        +# but ssltest expects a cert file and complains if it can't
        +# open the default one.
        +SERVER_PEM=$OPENSSL_DIR/apps/server.pem
        +
        +if [ "$1" = "aecdh" ]; then
        +for cipher in $AECDH_CIPHER_LIST
        +do
        +    echo "Testing $cipher"
        +    $SSLTEST $SSL_VERSION -cert $SERVER_PEM -cipher $cipher 
        +done
        +#--------------------------------------------------------------
        +for curve in $ELLIPTIC_CURVE_LIST
        +do
        +    echo "Testing AECDH-NULL-SHA (with $curve)"
        +    $SSLTEST $SSL_VERSION -cert $SERVER_PEM \
        +	-named_curve $curve -cipher AECDH-NULL-SHA
        +done
        +
        +for curve in $ELLIPTIC_CURVE_LIST
        +do
        +    echo "Testing AECDH-RC4-SHA (with $curve)"
        +    $SSLTEST $SSL_VERSION -cert $SERVER_PEM \
        +	-named_curve $curve -cipher AECDH-RC4-SHA
        +done
        +fi
        +
        +#==============================================================
        +# Both ECDH-ECDSA and ECDHE-ECDSA cipher suites require 
        +# the server to have an ECC certificate signed with ECDSA.
        +CA_PEM=$CERTS_DIR/secp160r1TestCA.pem
        +SERVER_PEM=$CERTS_DIR/secp160r2TestServer.pem
        +CLIENT_PEM=$CERTS_DIR/secp160r2TestClient.pem
        +
        +if [ "$1" = "ecdh-ecdsa" ]; then
        +for cipher in $ECDH_ECDSA_CIPHER_LIST
        +do
        +    echo "Testing $cipher (with server authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-cipher $cipher
        +
        +    echo "Testing $cipher (with server and client authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-c_cert $CLIENT_PEM -client_auth \
        +	-cipher $cipher
        +done
        +fi
        +
        +#==============================================================
        +if [ "$1" = "ecdhe-ecdsa" ]; then
        +for cipher in $ECDHE_ECDSA_CIPHER_LIST
        +do
        +    echo "Testing $cipher (with server authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-cipher $cipher -named_curve $DEFAULT_CURVE
        +
        +    echo "Testing $cipher (with server and client authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-c_cert $CLIENT_PEM -client_auth \
        +	-cipher $cipher -named_curve $DEFAULT_CURVE
        +done
        +
        +#--------------------------------------------------------------
        +for curve in $ELLIPTIC_CURVE_LIST
        +do
        +    echo "Testing ECDHE-ECDSA-AES128-SHA (2-way auth with $curve)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-c_cert $CLIENT_PEM -client_auth \
        +	-cipher ECDHE-ECDSA-AES128-SHA -named_curve $curve 
        +done
        +fi
        +
        +#==============================================================
        +# ECDH-RSA cipher suites require the server to have an ECC
        +# certificate signed with RSA.
        +CA_PEM=$CERTS_DIR/rsa1024TestCA.pem
        +SERVER_PEM=$CERTS_DIR/sect163r1-rsaTestServer.pem
        +CLIENT_PEM=$CERTS_DIR/sect163r1-rsaTestClient.pem
        +
        +if [ "$1" = "ecdh-rsa" ]; then
        +for cipher in $ECDH_RSA_CIPHER_LIST
        +do
        +    echo "Testing $cipher (with server authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-cipher $cipher
        +
        +    echo "Testing $cipher (with server and client authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-c_cert $CLIENT_PEM -client_auth \
        +	-cipher $cipher
        +done
        +fi
        +
        +#==============================================================
        +# ECDHE-RSA cipher suites require the server to have an RSA cert.
        +CA_PEM=$CERTS_DIR/rsa1024TestCA.pem
        +SERVER_PEM=$CERTS_DIR/rsa1024TestServer.pem
        +CLIENT_PEM=$CERTS_DIR/rsa1024TestClient.pem
        +
        +if [ "$1" = "ecdhe-rsa" ]; then
        +for cipher in $ECDHE_RSA_CIPHER_LIST
        +do
        +    echo "Testing $cipher (with server authentication)"
        +    echo $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-cipher $cipher -named_curve $DEFAULT_CURVE
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-cipher $cipher -named_curve $DEFAULT_CURVE
        +
        +    echo "Testing $cipher (with server and client authentication)"
        +    $SSLTEST $SSL_VERSION -CAfile $CA_PEM \
        +	-cert $SERVER_PEM -server_auth \
        +	-c_cert $CLIENT_PEM -client_auth \
        +	-cipher $cipher -named_curve $DEFAULT_CURVE
        +done
        +fi
        +#==============================================================
        +
        +
        +
        +
        diff --git a/vendor/openssl/openssl/demos/state_machine/Makefile b/vendor/openssl/openssl/demos/state_machine/Makefile
        new file mode 100644
        index 000000000..c7a114540
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/state_machine/Makefile
        @@ -0,0 +1,9 @@
        +CFLAGS=-I../../include -Wall -Werror -g
        +
        +all: state_machine
        +
        +state_machine: state_machine.o
        +	$(CC) -o state_machine state_machine.o -L../.. -lssl -lcrypto
        +
        +test: state_machine
        +	./state_machine 10000 ../../apps/server.pem ../../apps/server.pem
        diff --git a/vendor/openssl/openssl/demos/state_machine/state_machine.c b/vendor/openssl/openssl/demos/state_machine/state_machine.c
        new file mode 100644
        index 000000000..fef3f3e3d
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/state_machine/state_machine.c
        @@ -0,0 +1,416 @@
        +/* ====================================================================
        + * 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
        + *    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).
        + *
        + */
        +
        +/*
        + * Nuron, a leader in hardware encryption technology, generously
        + * sponsored the development of this demo by Ben Laurie.
        + *
        + * See http://www.nuron.com/.
        + */
        +
        +/*
        + * the aim of this demo is to provide a fully working state-machine
        + * style SSL implementation, i.e. one where the main loop acquires
        + * some data, then converts it from or to SSL by feeding it into the
        + * SSL state machine. It then does any I/O required by the state machine
        + * and loops.
        + *
        + * In order to keep things as simple as possible, this implementation
        + * listens on a TCP socket, which it expects to get an SSL connection
        + * on (for example, from s_client) and from then on writes decrypted
        + * data to stdout and encrypts anything arriving on stdin. Verbose
        + * commentary is written to stderr.
        + *
        + * This implementation acts as a server, but it can also be done for a client.  */
        +
        +#include <openssl/ssl.h>
        +#include <assert.h>
        +#include <unistd.h>
        +#include <string.h>
        +#include <openssl/err.h>
        +#include <sys/types.h>
        +#include <sys/socket.h>
        +#include <netinet/in.h>
        +
        +/* die_unless is intended to work like assert, except that it happens
        +   always, even if NDEBUG is defined. Use assert as a stopgap. */
        +
        +#define die_unless(x)	assert(x)
        +
        +typedef struct
        +    {
        +    SSL_CTX *pCtx;
        +    BIO *pbioRead;
        +    BIO *pbioWrite;
        +    SSL *pSSL;
        +    } SSLStateMachine;
        +
        +void SSLStateMachine_print_error(SSLStateMachine *pMachine,const char *szErr)
        +    {
        +    unsigned long l;
        +
        +    fprintf(stderr,"%s\n",szErr);
        +    while((l=ERR_get_error()))
        +	{
        +	char buf[1024];
        +
        +	ERR_error_string_n(l,buf,sizeof buf);
        +	fprintf(stderr,"Error %lx: %s\n",l,buf);
        +	}
        +    }
        +
        +SSLStateMachine *SSLStateMachine_new(const char *szCertificateFile,
        +				     const char *szKeyFile)
        +    {
        +    SSLStateMachine *pMachine=malloc(sizeof *pMachine);
        +    int n;
        +
        +    die_unless(pMachine);
        +
        +    pMachine->pCtx=SSL_CTX_new(SSLv23_server_method());
        +    die_unless(pMachine->pCtx);
        +
        +    n=SSL_CTX_use_certificate_file(pMachine->pCtx,szCertificateFile,
        +				   SSL_FILETYPE_PEM);
        +    die_unless(n > 0);
        +
        +    n=SSL_CTX_use_PrivateKey_file(pMachine->pCtx,szKeyFile,SSL_FILETYPE_PEM);
        +    die_unless(n > 0);
        +
        +    pMachine->pSSL=SSL_new(pMachine->pCtx);
        +    die_unless(pMachine->pSSL);
        +
        +    pMachine->pbioRead=BIO_new(BIO_s_mem());
        +
        +    pMachine->pbioWrite=BIO_new(BIO_s_mem());
        +
        +    SSL_set_bio(pMachine->pSSL,pMachine->pbioRead,pMachine->pbioWrite);
        +
        +    SSL_set_accept_state(pMachine->pSSL);
        +
        +    return pMachine;
        +    }
        +
        +void SSLStateMachine_read_inject(SSLStateMachine *pMachine,
        +				 const unsigned char *aucBuf,int nBuf)
        +    {
        +    int n=BIO_write(pMachine->pbioRead,aucBuf,nBuf);
        +    /* If it turns out this assert fails, then buffer the data here
        +     * and just feed it in in churn instead. Seems to me that it
        +     * should be guaranteed to succeed, though.
        +     */
        +    assert(n == nBuf);
        +    fprintf(stderr,"%d bytes of encrypted data fed to state machine\n",n);
        +    }
        +
        +int SSLStateMachine_read_extract(SSLStateMachine *pMachine,
        +				 unsigned char *aucBuf,int nBuf)
        +    {
        +    int n;
        +
        +    if(!SSL_is_init_finished(pMachine->pSSL))
        +	{
        +	fprintf(stderr,"Doing SSL_accept\n");
        +	n=SSL_accept(pMachine->pSSL);
        +	if(n == 0)
        +	    fprintf(stderr,"SSL_accept returned zero\n");
        +	if(n < 0)
        +	    {
        +	    int err;
        +
        +	    if((err=SSL_get_error(pMachine->pSSL,n)) == SSL_ERROR_WANT_READ)
        +		{
        +		fprintf(stderr,"SSL_accept wants more data\n");
        +		return 0;
        +		}
        +
        +	    SSLStateMachine_print_error(pMachine,"SSL_accept error");
        +	    exit(7);
        +	    }
        +	return 0;
        +	}
        +
        +    n=SSL_read(pMachine->pSSL,aucBuf,nBuf);
        +    if(n < 0)
        +	{
        +	int err=SSL_get_error(pMachine->pSSL,n);
        +
        +	if(err == SSL_ERROR_WANT_READ)
        +	    {
        +	    fprintf(stderr,"SSL_read wants more data\n");
        +	    return 0;
        +	    }
        +
        +	SSLStateMachine_print_error(pMachine,"SSL_read error");
        +	exit(8);
        +	}
        +
        +    fprintf(stderr,"%d bytes of decrypted data read from state machine\n",n);
        +    return n;
        +    }
        +
        +int SSLStateMachine_write_can_extract(SSLStateMachine *pMachine)
        +    {
        +    int n=BIO_pending(pMachine->pbioWrite);
        +    if(n)
        +	fprintf(stderr,"There is encrypted data available to write\n");
        +    else
        +	fprintf(stderr,"There is no encrypted data available to write\n");
        +
        +    return n;
        +    }
        +
        +int SSLStateMachine_write_extract(SSLStateMachine *pMachine,
        +				  unsigned char *aucBuf,int nBuf)
        +    {
        +    int n;
        +
        +    n=BIO_read(pMachine->pbioWrite,aucBuf,nBuf);
        +    fprintf(stderr,"%d bytes of encrypted data read from state machine\n",n);
        +    return n;
        +    }
        +
        +void SSLStateMachine_write_inject(SSLStateMachine *pMachine,
        +				  const unsigned char *aucBuf,int nBuf)
        +    {
        +    int n=SSL_write(pMachine->pSSL,aucBuf,nBuf);
        +    /* If it turns out this assert fails, then buffer the data here
        +     * and just feed it in in churn instead. Seems to me that it
        +     * should be guaranteed to succeed, though.
        +     */
        +    assert(n == nBuf);
        +    fprintf(stderr,"%d bytes of unencrypted data fed to state machine\n",n);
        +    }
        +
        +int OpenSocket(int nPort)
        +    {
        +    int nSocket;
        +    struct sockaddr_in saServer;
        +    struct sockaddr_in saClient;
        +    int one=1;
        +    int nSize;
        +    int nFD;
        +    int nLen;
        +
        +    nSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        +    if(nSocket < 0)
        +	{
        +	perror("socket");
        +	exit(1);
        +	}
        +
        +    if(setsockopt(nSocket,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof one) < 0)
        +	{
        +	perror("setsockopt");
        +        exit(2);
        +	}
        +
        +    memset(&saServer,0,sizeof saServer);
        +    saServer.sin_family=AF_INET;
        +    saServer.sin_port=htons(nPort);
        +    nSize=sizeof saServer;
        +    if(bind(nSocket,(struct sockaddr *)&saServer,nSize) < 0)
        +	{
        +	perror("bind");
        +	exit(3);
        +	}
        +
        +    if(listen(nSocket,512) < 0)
        +	{
        +	perror("listen");
        +	exit(4);
        +	}
        +
        +    nLen=sizeof saClient;
        +    nFD=accept(nSocket,(struct sockaddr *)&saClient,&nLen);
        +    if(nFD < 0)
        +	{
        +	perror("accept");
        +	exit(5);
        +	}
        +
        +    fprintf(stderr,"Incoming accepted on port %d\n",nPort);
        +
        +    return nFD;
        +    }
        +
        +int main(int argc,char **argv)
        +    {
        +    SSLStateMachine *pMachine;
        +    int nPort;
        +    int nFD;
        +    const char *szCertificateFile;
        +    const char *szKeyFile;
        +    char rbuf[1];
        +    int nrbuf=0;
        +
        +    if(argc != 4)
        +	{
        +	fprintf(stderr,"%s <port> <certificate file> <key file>\n",argv[0]);
        +	exit(6);
        +	}
        +
        +    nPort=atoi(argv[1]);
        +    szCertificateFile=argv[2];
        +    szKeyFile=argv[3];
        +
        +    SSL_library_init();
        +    OpenSSL_add_ssl_algorithms();
        +    SSL_load_error_strings();
        +    ERR_load_crypto_strings();
        +
        +    nFD=OpenSocket(nPort);
        +
        +    pMachine=SSLStateMachine_new(szCertificateFile,szKeyFile);
        +
        +    for( ; ; )
        +	{
        +	fd_set rfds,wfds;
        +	unsigned char buf[1024];
        +	int n;
        +
        +	FD_ZERO(&rfds);
        +	FD_ZERO(&wfds);
        +
        +	/* Select socket for input */
        +	FD_SET(nFD,&rfds);
        +
        +	/* check whether there's decrypted data */
        +	if(!nrbuf)
        +	    nrbuf=SSLStateMachine_read_extract(pMachine,rbuf,1);
        +
        +	/* if there's decrypted data, check whether we can write it */
        +	if(nrbuf)
        +	    FD_SET(1,&wfds);
        +
        +	/* Select socket for output */
        +	if(SSLStateMachine_write_can_extract(pMachine))
        +	    FD_SET(nFD,&wfds);
        +
        +	/* Select stdin for input */
        +	FD_SET(0,&rfds);
        +
        +	/* Wait for something to do something */
        +	n=select(nFD+1,&rfds,&wfds,NULL,NULL);
        +	assert(n > 0);
        +
        +	/* Socket is ready for input */
        +	if(FD_ISSET(nFD,&rfds))
        +	    {
        +	    n=read(nFD,buf,sizeof buf);
        +	    if(n == 0)
        +		{
        +		fprintf(stderr,"Got EOF on socket\n");
        +		exit(0);
        +		}
        +	    assert(n > 0);
        +
        +	    SSLStateMachine_read_inject(pMachine,buf,n);
        +	    }
        +
        +	/* stdout is ready for output (and hence we have some to send it) */
        +	if(FD_ISSET(1,&wfds))
        +	    {
        +	    assert(nrbuf == 1);
        +	    buf[0]=rbuf[0];
        +	    nrbuf=0;
        +
        +	    n=SSLStateMachine_read_extract(pMachine,buf+1,sizeof buf-1);
        +	    if(n < 0)
        +		{
        +		SSLStateMachine_print_error(pMachine,"read extract failed");
        +		break;
        +		}
        +	    assert(n >= 0);
        +	    ++n;
        +	    if(n > 0) /* FIXME: has to be true now */
        +		{
        +		int w;
        +		
        +		w=write(1,buf,n);
        +		/* FIXME: we should push back any unwritten data */
        +		assert(w == n);
        +		}
        +	    }
        +
        +	/* Socket is ready for output (and therefore we have output to send) */
        +	if(FD_ISSET(nFD,&wfds))
        +	    {
        +	    int w;
        +
        +	    n=SSLStateMachine_write_extract(pMachine,buf,sizeof buf);
        +	    assert(n > 0);
        +
        +	    w=write(nFD,buf,n);
        +	    /* FIXME: we should push back any unwritten data */
        +	    assert(w == n);
        +	    }
        +
        +	/* Stdin is ready for input */
        +	if(FD_ISSET(0,&rfds))
        +	    {
        +	    n=read(0,buf,sizeof buf);
        +	    if(n == 0)
        +		{
        +		fprintf(stderr,"Got EOF on stdin\n");
        +		exit(0);
        +		}
        +	    assert(n > 0);
        +
        +	    SSLStateMachine_write_inject(pMachine,buf,n);
        +	    }
        +	}
        +    /* not reached */
        +    return 0;
        +    }
        diff --git a/vendor/openssl/openssl/demos/tunala/A-client.pem b/vendor/openssl/openssl/demos/tunala/A-client.pem
        new file mode 100644
        index 000000000..a4caf6ef8
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/A-client.pem
        @@ -0,0 +1,84 @@
        +Certificate:
        +    Data:
        +        Version: 3 (0x2)
        +        Serial Number: 2 (0x2)
        +        Signature Algorithm: md5WithRSAEncryption
        +        Issuer: C=NZ, L=Wellington, O=Really Irresponsible Authorisation Authority (RIAA), OU=Cert-stamping, CN=Jackov al-Trades/Email=none@fake.domain
        +        Validity
        +            Not Before: Jan 16 05:19:30 2002 GMT
        +            Not After : Jan 14 05:19:30 2012 GMT
        +        Subject: C=NZ, L=Auckland, O=Mordor, OU=SSL grunt things, CN=tunala-client/Email=client@fake.domain
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +            RSA Public Key: (1024 bit)
        +                Modulus (1024 bit):
        +                    00:b0:d3:56:5c:c8:7f:fb:f4:95:9d:04:84:4f:82:
        +                    b7:a2:75:5c:81:48:8c:56:5d:52:ee:38:e1:5c:c8:
        +                    9a:70:8e:72:f2:00:1c:17:ef:df:b7:06:59:82:04:
        +                    f1:f6:49:11:12:a6:4d:cb:1e:ed:ac:59:1c:4a:d0:
        +                    3d:de:e6:f2:8d:cd:39:c2:0f:e0:46:2f:db:cb:9f:
        +                    47:f7:56:e7:f8:16:5f:68:71:fb:3a:e3:ab:d2:e5:
        +                    05:b7:da:65:61:fe:6d:30:e4:12:a8:b5:c1:71:24:
        +                    6b:aa:80:05:41:17:a0:8b:6e:8b:e6:04:cf:85:7b:
        +                    2a:ac:a1:79:7d:f4:96:6e:77
        +                Exponent: 65537 (0x10001)
        +        X509v3 extensions:
        +            X509v3 Basic Constraints: 
        +                CA:FALSE
        +            Netscape Comment: 
        +                OpenSSL Generated Certificate
        +            X509v3 Subject Key Identifier: 
        +                F8:43:CB:4F:4D:4F:BC:6E:52:1A:FD:F9:7B:E1:12:3F:A7:A3:BA:93
        +            X509v3 Authority Key Identifier: 
        +                keyid:49:FB:45:72:12:C4:CC:E1:45:A1:D3:08:9E:95:C4:2C:6D:55:3F:17
        +                DirName:/C=NZ/L=Wellington/O=Really Irresponsible Authorisation Authority (RIAA)/OU=Cert-stamping/CN=Jackov al-Trades/Email=none@fake.domain
        +                serial:00
        +
        +    Signature Algorithm: md5WithRSAEncryption
        +        8f:5f:0e:43:da:9d:61:43:7e:03:38:9a:e6:50:9d:42:e8:95:
        +        34:49:75:ec:04:8d:5c:85:99:94:70:a0:e7:1f:1e:a0:8b:0f:
        +        d6:e2:cb:f7:35:d9:96:72:bd:a6:e9:8d:4e:b1:e2:ac:97:7f:
        +        2f:70:01:9d:aa:04:bc:d4:01:2b:63:77:a5:de:63:3c:a8:f5:
        +        f2:72:af:ec:11:12:c0:d4:70:cf:71:a6:fb:e9:1d:b3:27:07:
        +        aa:f2:b1:f3:87:d6:ab:8b:ce:c2:08:1b:3c:f9:ba:ff:77:71:
        +        86:09:ef:9e:4e:04:06:63:44:e9:93:20:90:c7:2d:50:c6:50:
        +        f8:66
        +-----BEGIN CERTIFICATE-----
        +MIID9TCCA16gAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox
        +EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp
        +YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy
        +dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3
        +DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTE5MzBaFw0xMjAxMTQw
        +NTE5MzBaMIGHMQswCQYDVQQGEwJOWjERMA8GA1UEBxMIQXVja2xhbmQxDzANBgNV
        +BAoTBk1vcmRvcjEZMBcGA1UECxMQU1NMIGdydW50IHRoaW5nczEWMBQGA1UEAxMN
        +dHVuYWxhLWNsaWVudDEhMB8GCSqGSIb3DQEJARYSY2xpZW50QGZha2UuZG9tYWlu
        +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw01ZcyH/79JWdBIRPgreidVyB
        +SIxWXVLuOOFcyJpwjnLyABwX79+3BlmCBPH2SRESpk3LHu2sWRxK0D3e5vKNzTnC
        +D+BGL9vLn0f3Vuf4Fl9ocfs646vS5QW32mVh/m0w5BKotcFxJGuqgAVBF6CLbovm
        +BM+FeyqsoXl99JZudwIDAQABo4IBQDCCATwwCQYDVR0TBAIwADAsBglghkgBhvhC
        +AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPhD
        +y09NT7xuUhr9+XvhEj+no7qTMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzhRaHTCJ6V
        +xCxtVT8XoYG6pIG3MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3Rv
        +bjE8MDoGA1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBB
        +dXRob3JpdHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQD
        +ExBKYWNrb3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9t
        +YWluggEAMA0GCSqGSIb3DQEBBAUAA4GBAI9fDkPanWFDfgM4muZQnULolTRJdewE
        +jVyFmZRwoOcfHqCLD9biy/c12ZZyvabpjU6x4qyXfy9wAZ2qBLzUAStjd6XeYzyo
        +9fJyr+wREsDUcM9xpvvpHbMnB6rysfOH1quLzsIIGzz5uv93cYYJ755OBAZjROmT
        +IJDHLVDGUPhm
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXgIBAAKBgQCw01ZcyH/79JWdBIRPgreidVyBSIxWXVLuOOFcyJpwjnLyABwX
        +79+3BlmCBPH2SRESpk3LHu2sWRxK0D3e5vKNzTnCD+BGL9vLn0f3Vuf4Fl9ocfs6
        +46vS5QW32mVh/m0w5BKotcFxJGuqgAVBF6CLbovmBM+FeyqsoXl99JZudwIDAQAB
        +AoGAU4chbqbPvkclPYzaq2yGLlneHrwUft+KwzlfS6L/QVgo+CQRIUWQmjaHpaGM
        +YtjVFcg1S1QK1bUqZjTEZT0XKhfbYmqW8yYTfbcDEbnY7esoYlvIlW8qRlPRlTBE
        +utKrtZafmVhLgoNawYGD0aLZofPqpYjbGUlrC7nrem2vNJECQQDVLD3Qb+OlEMET
        +73ApnJhYsK3e+G2LTrtjrS8y5zS4+Xv61XUqvdV7ogzRl0tpvSAmMOItVyoYadkB
        +S3xSIWX9AkEA1Fm1FhkQSZwGG5rf4c6gMN71jJ6JE3/kocdVa0sUjRevIupo4XQ2
        +Vkykxi84MRP8cfHqyjewq7Ozv3op2MGWgwJBAKemsb66IJjzAkaBav7u70nhOf0/
        ++Dc1Zl7QF2y7NVW8sGrnccx5m+ot2lMD4AV6/kvK6jaqdKrapBZGnbGiHqkCQQDI
        +T1r33mqz1R8Z2S2Jtzz6/McKf930a/dC+GLGVEutkILf39lRmytKmv/wB0jtWtoO
        +rlJ5sLDSNzC+1cE1u997AkEAu3IrtGmLKiuS6kDj6W47m+iiTIsuSJtTJb1SbUaK
        +fIoBNFxbvJYW6rUU9+PxpMRaEhzh5s24/jBOE+mlb17mRQ==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/tunala/A-server.pem b/vendor/openssl/openssl/demos/tunala/A-server.pem
        new file mode 100644
        index 000000000..e9f37b189
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/A-server.pem
        @@ -0,0 +1,84 @@
        +Certificate:
        +    Data:
        +        Version: 3 (0x2)
        +        Serial Number: 1 (0x1)
        +        Signature Algorithm: md5WithRSAEncryption
        +        Issuer: C=NZ, L=Wellington, O=Really Irresponsible Authorisation Authority (RIAA), OU=Cert-stamping, CN=Jackov al-Trades/Email=none@fake.domain
        +        Validity
        +            Not Before: Jan 16 05:14:06 2002 GMT
        +            Not After : Jan 14 05:14:06 2012 GMT
        +        Subject: C=NZ, L=Wellington, O=Middle Earth, OU=SSL dev things, CN=tunala-server/Email=server@fake.domain
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +            RSA Public Key: (1024 bit)
        +                Modulus (1024 bit):
        +                    00:a9:3e:62:87:97:13:6b:de:8f:bc:1d:0a:3f:65:
        +                    0c:f9:76:a3:53:ce:97:30:27:0d:c6:df:72:1f:8d:
        +                    5a:ce:58:23:6a:65:e5:e3:72:1a:8d:7f:fe:90:01:
        +                    ea:42:f1:9f:6e:7b:0a:bd:eb:52:15:7b:f4:3d:9c:
        +                    4e:db:74:29:2b:d1:81:9d:b9:9e:18:2b:87:e1:da:
        +                    50:20:3c:59:6c:c9:83:3e:2c:11:0b:78:1e:03:f4:
        +                    56:3a:db:95:6a:75:33:85:a9:7b:cc:3c:4a:67:96:
        +                    f2:24:b2:a0:cb:2e:cc:52:18:16:6f:44:d9:29:64:
        +                    07:2e:fb:56:cc:7c:dc:a2:d7
        +                Exponent: 65537 (0x10001)
        +        X509v3 extensions:
        +            X509v3 Basic Constraints: 
        +                CA:FALSE
        +            Netscape Comment: 
        +                OpenSSL Generated Certificate
        +            X509v3 Subject Key Identifier: 
        +                70:AC:7A:B5:6E:97:C2:82:AF:11:9E:32:CB:8D:48:49:93:B7:DC:22
        +            X509v3 Authority Key Identifier: 
        +                keyid:49:FB:45:72:12:C4:CC:E1:45:A1:D3:08:9E:95:C4:2C:6D:55:3F:17
        +                DirName:/C=NZ/L=Wellington/O=Really Irresponsible Authorisation Authority (RIAA)/OU=Cert-stamping/CN=Jackov al-Trades/Email=none@fake.domain
        +                serial:00
        +
        +    Signature Algorithm: md5WithRSAEncryption
        +        2e:cb:a3:cd:6d:a8:9d:d1:dc:e5:f0:e0:27:7e:4b:5a:90:a8:
        +        85:43:f0:05:f7:04:43:d7:5f:d1:a5:8f:5c:58:eb:fc:da:c6:
        +        7c:e0:0b:2b:98:72:95:f6:79:48:96:7a:fa:0c:6b:09:ec:c6:
        +        8c:91:74:45:9f:8f:0f:16:78:e3:66:14:fa:1e:f4:f0:23:ec:
        +        cd:a9:52:77:20:4d:c5:05:2c:52:b6:7b:f3:42:33:fd:90:1f:
        +        3e:88:6f:9b:23:61:c8:80:3b:e6:57:84:2e:f7:26:c7:35:ed:
        +        00:8b:08:30:9b:aa:21:83:b6:6d:b8:7c:8a:9b:2a:ef:79:3d:
        +        96:31
        +-----BEGIN CERTIFICATE-----
        +MIID+zCCA2SgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox
        +EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp
        +YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy
        +dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3
        +DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTE0MDZaFw0xMjAxMTQw
        +NTE0MDZaMIGNMQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjEVMBMG
        +A1UEChMMTWlkZGxlIEVhcnRoMRcwFQYDVQQLEw5TU0wgZGV2IHRoaW5nczEWMBQG
        +A1UEAxMNdHVuYWxhLXNlcnZlcjEhMB8GCSqGSIb3DQEJARYSc2VydmVyQGZha2Uu
        +ZG9tYWluMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpPmKHlxNr3o+8HQo/
        +ZQz5dqNTzpcwJw3G33IfjVrOWCNqZeXjchqNf/6QAepC8Z9uewq961IVe/Q9nE7b
        +dCkr0YGduZ4YK4fh2lAgPFlsyYM+LBELeB4D9FY625VqdTOFqXvMPEpnlvIksqDL
        +LsxSGBZvRNkpZAcu+1bMfNyi1wIDAQABo4IBQDCCATwwCQYDVR0TBAIwADAsBglg
        +hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
        +BBYEFHCserVul8KCrxGeMsuNSEmTt9wiMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzh
        +RaHTCJ6VxCxtVT8XoYG6pIG3MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2Vs
        +bGluZ3RvbjE8MDoGA1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNh
        +dGlvbiBBdXRob3JpdHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkw
        +FwYDVQQDExBKYWNrb3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZh
        +a2UuZG9tYWluggEAMA0GCSqGSIb3DQEBBAUAA4GBAC7Lo81tqJ3R3OXw4Cd+S1qQ
        +qIVD8AX3BEPXX9Glj1xY6/zaxnzgCyuYcpX2eUiWevoMawnsxoyRdEWfjw8WeONm
        +FPoe9PAj7M2pUncgTcUFLFK2e/NCM/2QHz6Ib5sjYciAO+ZXhC73Jsc17QCLCDCb
        +qiGDtm24fIqbKu95PZYx
        +-----END CERTIFICATE-----
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQCpPmKHlxNr3o+8HQo/ZQz5dqNTzpcwJw3G33IfjVrOWCNqZeXj
        +chqNf/6QAepC8Z9uewq961IVe/Q9nE7bdCkr0YGduZ4YK4fh2lAgPFlsyYM+LBEL
        +eB4D9FY625VqdTOFqXvMPEpnlvIksqDLLsxSGBZvRNkpZAcu+1bMfNyi1wIDAQAB
        +AoGANCwqHZhiAU/TyW6+WPqivEhpYw19p/dyFMuPF9DwnEmpaUROUQY8z0AUznn4
        +qHhp6Jn/nrprTHowucl0ucweYIYVxZoUiUDFpxdFUbzMdFvo6HcyV1Pe4Rt81HaY
        +KYWrTZ6PaPtN65hLms8NhPEdGcGAFlY1owYv4QNGq2bU1JECQQDd32LM0NSfyGmK
        +4ziajqGcvzK9NO2XyV/nJsGlJZNgMh2zm1t7yR28l/6Q2uyU49cCN+2aYULZCAfs
        +taNvxBspAkEAw0alNub+xj2AVQvaxOB1sGfKzsJjHCzKIxUXn/tJi3j0+2asmkBZ
        +Umx1MWr9jKQBnCMciCRUbnMEZiElOxCN/wJAfAeQl6Z19gx206lJzzzEo3dOye54
        +k02DSxijT8q9pBzf9bN3ZK987BybtiZr8p+bZiYVsSOF1wViSLURdD1QYQJAIaMU
        +qH1n24wShBPTrmAfxbBLTgxL+Dl65Eoo1KT7iSvfv0JzbuqwuDL4iPeuD0DdCiE+
        +M/FWHeRwGIuTFzaFzwJBANKwx0jZS/h093w9g0Clw6UzeA1P5VcAt9y+qMC9hO3c
        +4KXwIxQAt9yRaFLpiIR9do5bjjKNnMguf3aO/XRSDQM=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/demos/tunala/CA.pem b/vendor/openssl/openssl/demos/tunala/CA.pem
        new file mode 100644
        index 000000000..7a55b5463
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/CA.pem
        @@ -0,0 +1,24 @@
        +-----BEGIN CERTIFICATE-----
        +MIID9zCCA2CgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox
        +EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp
        +YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy
        +dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3
        +DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTA5NTlaFw0xMjAxMTQw
        +NTA5NTlaMIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjE8MDoG
        +A1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBBdXRob3Jp
        +dHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQDExBKYWNr
        +b3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9tYWluMIGf
        +MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7QdDfFIrJn3X24hKmpkyk3TG0Ivxd
        +K2wWmDPXq1wjr8lUTwrA6hM5Ba9N36jLieWpXhviLOWu9DBza5GmtgCuXloATKTC
        +94xOdKHlciTVujG3wDlLDB5e710Kar84nnj6VueL1RyZ0bmP5PANa4mbGW9Tqc7J
        +CkBTTW2y9d0SgQIDAQABo4IBFTCCAREwHQYDVR0OBBYEFEn7RXISxMzhRaHTCJ6V
        +xCxtVT8XMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzhRaHTCJ6VxCxtVT8XoYG6pIG3
        +MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjE8MDoGA1UEChMz
        +UmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBBdXRob3JpdHkgKFJJ
        +QUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQDExBKYWNrb3YgYWwt
        +VHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9tYWluggEAMAwGA1Ud
        +EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYQo95V/NY+eKxYxkhibZiUQygph+
        +gTfgbDG20MsnH6+8//w5ArHauFCgDrf0P2VyACgq+N4pBTWFGaAaLwbjKy9HCe2E
        +j9C91tO1CqDS4MJkDB5AP13FTkK6fP1ZCiTQranOAp3DlGWTTWsFVyW5kVfQ9diS
        +ZOyJZ9Fit5XM2X0=
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/demos/tunala/INSTALL b/vendor/openssl/openssl/demos/tunala/INSTALL
        new file mode 100644
        index 000000000..a65bbeb8d
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/INSTALL
        @@ -0,0 +1,107 @@
        +There are two ways to build this code;
        +
        +(1) Manually
        +
        +(2) Using all-singing all-dancing (all-confusing) autotools, ie. autoconf,
        +automake, and their little friends (autoheader, etc).
        +
        +=================
        +Building Manually
        +=================
        +
        +There is a basic "Makefile" in this directory that gets moved out of the way and
        +ignored when building with autoconf et al. This Makefile is suitable for
        +building tunala on Linux using gcc. Any other platform probably requires some
        +tweaking. Here are the various bits you might need to do if you want to build
        +this way and the default Makefile isn't sufficient;
        +
        +* Compiler: Edit the "CC" definition in Makefile
        +
        +* Headers, features: tunala.h controls what happens in the non-autoconf world.
        +  It, by default, assumes the system has *everything* (except autoconf's
        +  "config.h") so if a target system is missing something it must define the
        +  appropriate "NO_***" symbols in CFLAGS. These include;
        +
        +  - NO_HAVE_UNISTD_H, NO_HAVE_FCNTL_H, NO_HAVE_LIMITS_H
        +    Indicates the compiling system doesn't have (or need) these header files.
        +  - NO_HAVE_STRSTR, NO_HAVE_STRTOUL
        +    Indicates the compiling system doesn't have these functions. Replacements
        +    are compiled and used in breakage.c
        +  - NO_HAVE_SELECT, NO_HAVE_SOCKET
        +    Pointless symbols - these indicate select() and/or socket() are missing in
        +    which case the program won't compile anyway.
        +
        +  If you want to specify any of these, add them with "-D" prefixed to each in
        +  the CFLAGS definition in Makefile.
        +
        +* Compilation flags: edit DEBUG_FLAGS and/or CFLAGS directly to control the
        +  flags passed to the compiler. This can also be used to change the degree of
        +  optimisation.
        +
        +* Linker flags: some systems (eg. Solaris) require extra linker flags such as;
        +  -ldl, -lsocket, -lnsl, etc. If unsure, bring up the man page for whichever
        +  function is "undefined" when the linker fails - that usually indicates what
        +  you need to add. Make changes to the LINK_FLAGS symbol.
        +
        +* Linker command: if a different linker syntax or even a different program is
        +  required to link, edit the linker line directly in the "tunala:" target
        +  definition - it currently assumes the "CC" (compiler) program is used to link.
        +
        +======================
        +Building Automagically
        +======================
        +
        +Automagic building is handled courtesy of autoconf, automake, etc. There are in
        +fact two steps required to build, and only the first has to be done on a system
        +with these tools installed (and if I was prepared to bloat out the CVS
        +repository, I could store these extra files, but I'm not).
        +
        +First step: "autogunk.sh"
        +-------------------------
        +
        +The "./autogunk.sh" script will call all the necessary autotool commands to
        +create missing files and run automake and autoconf. The result is that a
        +"./configure" script should be generated and a "Makefile.in" generated from the
        +supplied "Makefile.am". NB: This script also moves the "manual" Makefile (see
        +above) out of the way and calls it "Makefile.plain" - the "ungunk" script
        +reverses this to leave the directory it was previously.
        +
        +Once "ungunk" has been run, the resulting directory should be able to build on
        +other systems without autoconf, automake, or libtool. Which is what the second
        +step describes;
        +
        +Second step: "./configure"
        +--------------------------
        +
        +The second step is to run the generated "./configure" script to create a
        +config.h header for your system and to generate a "Makefile" (generated from
        +"Makefile.in") tweaked to compile on your system. This is the standard sort of
        +thing you see in GNU packages, for example, and the standard tricks also work.
        +Eg. to override "configure"'s choice of compiler, set the CC environment
        +variable prior to running configure, eg.
        +
        +    CC=gcc ./configure
        +
        +would cause "gcc" to be used even if there is an otherwise preferable (to
        +autoconf) native compiler on your system.
        +
        +After this run "make" and it should build the "tunala" executable.
        +
        +Notes
        +-----
        +
        +- Some versions of autoconf (or automake?) generate a Makefile syntax that gives
        +  trouble to some "make" programs on some systems (eg. OpenBSD). If this
        +  happens, either build 'Manually' (see above) or use "gmake" instead of "make".
        +  I don't like this either but like even less the idea of sifting into all the
        +  script magic crud that's involved.
        +
        +- On a solaris system I tried, the "configure" script specified some broken
        +  compiler flags in the resulting Makefile that don't even get echoed to
        +  stdout/err when the error happens (evil!). If this happens, go into the
        +  generated Makefile, find the two affected targets ("%.o:" and "%.lo"), and
        +  remove the offending hidden option in the $(COMPILE) line all the sludge after
        +  the two first lines of script (ie. after the "echo" and the "COMPILE" lines).
        +  NB: This will probably only function if "--disable-shared" was used, otherwise
        +  who knows what would result ...
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/Makefile b/vendor/openssl/openssl/demos/tunala/Makefile
        new file mode 100644
        index 000000000..bef1704a3
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/Makefile
        @@ -0,0 +1,41 @@
        +# Edit these to suit
        +#
        +# Oh yeah, and please read the README too.
        +
        +
        +SSL_HOMEDIR=../..
        +SSL_INCLUDEDIR=$(SSL_HOMEDIR)/include
        +SSL_LIBDIR=$(SSL_HOMEDIR)
        +
        +RM=rm -f
        +CC=gcc
        +DEBUG_FLAGS=-g -ggdb3 -Wall -Wshadow
        +INCLUDE_FLAGS=-I$(SSL_INCLUDEDIR)
        +CFLAGS=$(DEBUG_FLAGS) $(INCLUDE_FLAGS) -DNO_CONFIG_H
        +COMPILE=$(CC) $(CFLAGS) -c
        +
        +# Edit, particularly the "-ldl" if not building with "dlfcn" support
        +LINK_FLAGS=-L$(SSL_LIBDIR) -lssl -lcrypto -ldl
        +
        +SRCS=buffer.c cb.c ip.c sm.c tunala.c breakage.c
        +OBJS=buffer.o cb.o ip.o sm.o tunala.o breakage.o
        +
        +TARGETS=tunala
        +
        +default: $(TARGETS)
        +
        +clean:
        +	$(RM) $(OBJS) $(TARGETS) *.bak core
        +
        +.c.o:
        +	$(COMPILE) $<
        +
        +tunala: $(OBJS)
        +	$(CC) -o tunala $(OBJS) $(LINK_FLAGS)
        +
        +# Extra dependencies, should really use makedepend
        +buffer.o: buffer.c tunala.h
        +cb.o: cb.c tunala.h
        +ip.o: ip.c tunala.h
        +sm.o: sm.c tunala.h
        +tunala.o: tunala.c tunala.h
        diff --git a/vendor/openssl/openssl/demos/tunala/Makefile.am b/vendor/openssl/openssl/demos/tunala/Makefile.am
        new file mode 100644
        index 000000000..706c7806c
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/Makefile.am
        @@ -0,0 +1,7 @@
        +# Our includes come from the OpenSSL build-tree we're in
        +INCLUDES		= -I$(top_builddir)/../../include
        +
        +bin_PROGRAMS		= tunala
        +
        +tunala_SOURCES		= tunala.c buffer.c cb.c ip.c sm.c breakage.c
        +tunala_LDADD		= -L$(top_builddir)/../.. -lssl -lcrypto
        diff --git a/vendor/openssl/openssl/demos/tunala/README b/vendor/openssl/openssl/demos/tunala/README
        new file mode 100644
        index 000000000..15690088f
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/README
        @@ -0,0 +1,233 @@
        +This is intended to be an example of a state-machine driven SSL application. It
        +acts as an SSL tunneler (functioning as either the server or client half,
        +depending on command-line arguments). *PLEASE* read the comments in tunala.h
        +before you treat this stuff as anything more than a curiosity - YOU HAVE BEEN
        +WARNED!! There, that's the draconian bit out of the way ...
        +
        +
        +Why "tunala"??
        +--------------
        +
        +I thought I asked you to read tunala.h?? :-)
        +
        +
        +Show me
        +-------
        +
        +If you want to simply see it running, skip to the end and see some example
        +command-line arguments to demonstrate with.
        +
        +
        +Where to look and what to do?
        +-----------------------------
        +
        +The code is split up roughly coinciding with the detaching of an "abstract" SSL
        +state machine (which is the purpose of all this) and its surrounding application
        +specifics. This is primarily to make it possible for me to know when I could cut
        +corners and when I needed to be rigorous (or at least maintain the pretense as
        +such :-).
        +
        +Network stuff:
        +
        +Basically, the network part of all this is what is supposed to be abstracted out
        +of the way. The intention is to illustrate one way to stick OpenSSL's mechanisms
        +inside a little memory-driven sandbox and operate it like a pure state-machine.
        +So, the network code is inside both ip.c (general utility functions and gory
        +IPv4 details) and tunala.c itself, which takes care of application specifics
        +like the main select() loop. The connectivity between the specifics of this
        +application (TCP/IP tunneling and the associated network code) and the
        +underlying abstract SSL state machine stuff is through the use of the "buffer_t"
        +type, declared in tunala.h and implemented in buffer.c.
        +
        +State machine:
        +
        +Which leaves us, generally speaking, with the abstract "state machine" code left
        +over and this is sitting inside sm.c, with declarations inside tunala.h. As can
        +be seen by the definition of the state_machine_t structure and the associated
        +functions to manipulate it, there are the 3 OpenSSL "handles" plus 4 buffer_t
        +structures dealing with IO on both the encrypted and unencrypted sides ("dirty"
        +and "clean" respectively). The "SSL" handle is what facilitates the reading and
        +writing of the unencrypted (tunneled) data. The two "BIO" handles act as the
        +read and write channels for encrypted tunnel traffic - in other applications
        +these are often socket BIOs so that the OpenSSL framework operates with the
        +network layer directly. In this example, those two BIOs are memory BIOs
        +(BIO_s_mem()) so that the sending and receiving of the tunnel traffic stays
        +within the state-machine, and we can handle where this gets send to (or read
        +from) ourselves.
        +
        +
        +Why?
        +----
        +
        +If you take a look at the "state_machine_t" section of tunala.h and the code in
        +sm.c, you will notice that nothing related to the concept of 'transport' is
        +involved. The binding to TCP/IP networking occurs in tunala.c, specifically
        +within the "tunala_item_t" structure that associates a state_machine_t object
        +with 4 file-descriptors. The way to best see where the bridge between the
        +outside world (TCP/IP reads, writes, select()s, file-descriptors, etc) and the
        +state machine is, is to examine the "tunala_item_io()" function in tunala.c.
        +This is currently around lines 641-732 but of course could be subject to change.
        +
        +
        +And...?
        +-------
        +
        +Well, although that function is around 90 lines of code, it could easily have
        +been a lot less only I was trying to address an easily missed "gotcha" (item (2)
        +below). The main() code that drives the select/accept/IO loop initialises new
        +tunala_item_t structures when connections arrive, and works out which
        +file-descriptors go where depending on whether we're an SSL client or server
        +(client --> accepted connection is clean and proxied is dirty, server -->
        +accepted connection is dirty and proxied is clean). What that tunala_item_io()
        +function is attempting to do is 2 things;
        +
        +  (1) Perform all reads and writes on the network directly into the
        +      state_machine_t's buffers (based on a previous select() result), and only
        +      then allow the abstact state_machine_t to "churn()" using those buffers.
        +      This will cause the SSL machine to consume as much input data from the two
        +      "IN" buffers as possible, and generate as much output data into the two
        +      "OUT" buffers as possible. Back up in the main() function, the next main
        +      loop loop will examine these output buffers and select() for writability
        +      on the corresponding sockets if the buffers are non-empty.
        +
        +  (2) Handle the complicated tunneling-specific issue of cascading "close"s.
        +      This is the reason for most of the complexity in the logic - if one side
        +      of the tunnel is closed, you can't simply close the other side and throw
        +      away the whole thing - (a) there may still be outgoing data on the other
        +      side of the tunnel that hasn't been sent yet, (b) the close (or things
        +      happening during the close) may cause more data to be generated that needs
        +      sending on the other side. Of course, this logic is complicated yet futher
        +      by the fact that it's different depending on which side closes first :-)
        +      state_machine_close_clean() will indicate to the state machine that the
        +      unencrypted side of the tunnel has closed, so any existing outgoing data
        +      needs to be flushed, and the SSL stream needs to be closed down using the
        +      appropriate shutdown sequence. state_machine_close_dirty() is simpler
        +      because it indicates that the SSL stream has been disconnected, so all
        +      that remains before closing the other side is to flush out anything that
        +      remains and wait for it to all be sent.
        +
        +Anyway, with those things in mind, the code should be a little easier to follow
        +in terms of "what is *this* bit supposed to achieve??!!".
        +
        +
        +How might this help?
        +--------------------
        +
        +Well, the reason I wrote this is that there seemed to be rather a flood of
        +questions of late on the openssl-dev and openssl-users lists about getting this
        +whole IO logic thing sorted out, particularly by those who were trying to either
        +use non-blocking IO, or wanted SSL in an environment where "something else" was
        +handling the network already and they needed to operate in memory only. This
        +code is loosely based on some other stuff I've been working on, although that
        +stuff is far more complete, far more dependant on a whole slew of other
        +network/framework code I don't want to incorporate here, and far harder to look
        +at for 5 minutes and follow where everything is going. I will be trying over
        +time to suck in a few things from that into this demo in the hopes it might be
        +more useful, and maybe to even make this demo usable as a utility of its own.
        +Possible things include:
        +
        +  * controlling multiple processes/threads - this can be used to combat
        +    latencies and get passed file-descriptor limits on some systems, and it uses
        +    a "controller" process/thread that maintains IPC links with the
        +    processes/threads doing the real work.
        +
        +  * cert verification rules - having some say over which certs get in or out :-)
        +
        +  * control over SSL protocols and cipher suites
        +
        +  * A few other things you can already do in s_client and s_server :-)
        +
        +  * Support (and control over) session resuming, particularly when functioning
        +    as an SSL client.
        +
        +If you have a particular environment where this model might work to let you "do
        +SSL" without having OpenSSL be aware of the transport, then you should find you
        +could use the state_machine_t structure (or your own variant thereof) and hook
        +it up to your transport stuff in much the way tunala.c matches it up with those
        +4 file-descriptors. The state_machine_churn(), state_machine_close_clean(), and
        +state_machine_close_dirty() functions are the main things to understand - after
        +that's done, you just have to ensure you're feeding and bleeding the 4
        +state_machine buffers in a logical fashion. This state_machine loop handles not
        +only handshakes and normal streaming, but also renegotiates - there's no special
        +handling required beyond keeping an eye on those 4 buffers and keeping them in
        +sync with your outer "loop" logic. Ie. if one of the OUT buffers is not empty,
        +you need to find an opportunity to try and forward its data on. If one of the IN
        +buffers is not full, you should keep an eye out for data arriving that should be
        +placed there.
        +
        +This approach could hopefully also allow you to run the SSL protocol in very
        +different environments. As an example, you could support encrypted event-driven
        +IPC where threads/processes pass messages to each other inside an SSL layer;
        +each IPC-message's payload would be in fact the "dirty" content, and the "clean"
        +payload coming out of the tunnel at each end would be the real intended message.
        +Likewise, this could *easily* be made to work across unix domain sockets, or
        +even entirely different network/comms protocols.
        +
        +This is also a quick and easy way to do VPN if you (and the remote network's
        +gateway) support virtual network devices that are encapsulted in a single
        +network connection, perhaps PPP going through an SSL tunnel?
        +
        +
        +Suggestions
        +-----------
        +
        +Please let me know if you find this useful, or if there's anything wrong or
        +simply too confusing about it. Patches are also welcome, but please attach a
        +description of what it changes and why, and "diff -urN" format is preferred.
        +Mail to geoff@openssl.org should do the trick.
        +
        +
        +Example
        +-------
        +
        +Here is an example of how to use "tunala" ...
        +
        +First, it's assumed that OpenSSL has already built, and that you are building
        +inside the ./demos/tunala/ directory. If not - please correct the paths and
        +flags inside the Makefile. Likewise, if you want to tweak the building, it's
        +best to try and do so in the makefile (eg. removing the debug flags and adding
        +optimisation flags).
        +
        +Secondly, this code has mostly only been tested on Linux. However, some
        +autoconf/etc support has been added and the code has been compiled on openbsd
        +and solaris using that.
        +
        +Thirdly, if you are Win32, you probably need to do some *major* rewriting of
        +ip.c to stand a hope in hell. Good luck, and please mail me the diff if you do
        +this, otherwise I will take a look at another time. It can certainly be done,
        +but it's very non-POSIXy.
        +
        +See the INSTALL document for details on building.
        +
        +Now, if you don't have an executable "tunala" compiled, go back to "First,...".
        +Rinse and repeat.
        +
        +Inside one console, try typing;
        +
        +(i)  ./tunala -listen localhost:8080 -proxy localhost:8081 -cacert CA.pem \
        +              -cert A-client.pem -out_totals -v_peer -v_strict
        +
        +In another console, type;
        +
        +(ii) ./tunala -listen localhost:8081 -proxy localhost:23 -cacert CA.pem \
        +              -cert A-server.pem -server 1 -out_totals -v_peer -v_strict
        +
        +Now if you open another console and "telnet localhost 8080", you should be
        +tunneled through to the telnet service on your local machine (if it's running -
        +you could change it to port "22" and tunnel ssh instead if you so desired). When
        +you logout of the telnet session, the tunnel should cleanly shutdown and show
        +you some traffic stats in both consoles. Feel free to experiment. :-)
        +
        +Notes:
        +
        + - the format for the "-listen" argument can skip the host part (eg. "-listen
        +   8080" is fine). If you do, the listening socket will listen on all interfaces
        +   so you can connect from other machines for example. Using the "localhost"
        +   form listens only on 127.0.0.1 so you can only connect locally (unless, of
        +   course, you've set up weird stuff with your networking in which case probably
        +   none of the above applies).
        +
        + - ./tunala -? gives you a list of other command-line options, but tunala.c is
        +   also a good place to look :-)
        +
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/autogunk.sh b/vendor/openssl/openssl/demos/tunala/autogunk.sh
        new file mode 100644
        index 000000000..c9783c626
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/autogunk.sh
        @@ -0,0 +1,25 @@
        +#!/bin/sh
        +
        +# This script tries to follow the "GNU way" w.r.t. the autobits.
        +# This does of course generate a number of irritating files.
        +# Try to get over it (I am getting there myself).
        +
        +# This should generate any missing crud, and then run autoconf which should turn
        +# configure.in into a "./configure" script and "Makefile.am" into a
        +# "Makefile.in". Then running "./configure" should turn "Makefile.in" into
        +# "Makefile" and should generate the config.h containing your systems various
        +# settings. I know ... what a hassle ...
        +
        +# Also, sometimes these autobits things generate bizarre output (looking like
        +# errors). So I direct everything "elsewhere" ...
        +
        +(aclocal
        +autoheader
        +libtoolize --copy --force
        +automake --foreign --add-missing --copy
        +autoconf) 1> /dev/null 2>&1
        +
        +# Move the "no-autotools" Makefile out of the way
        +if test ! -f Makefile.plain; then
        +	mv Makefile Makefile.plain
        +fi
        diff --git a/vendor/openssl/openssl/demos/tunala/autoungunk.sh b/vendor/openssl/openssl/demos/tunala/autoungunk.sh
        new file mode 100644
        index 000000000..21790880d
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/autoungunk.sh
        @@ -0,0 +1,19 @@
        +#!/bin/sh
        +
        +# This script tries to clean up as much as is possible from whatever diabolical
        +# mess has been left in the directory thanks to autoconf, automake, and their
        +# friends.
        +
        +if test -f Makefile.plain; then
        +	if test -f Makefile; then
        +		make distclean
        +	fi
        +	mv Makefile.plain Makefile
        +else
        +	make clean
        +fi
        +
        +rm -f aclocal.m4 config.* configure install-sh \
        +	missing mkinstalldirs stamp-h.* Makefile.in \
        +	ltconfig ltmain.sh depcomp
        +rm -rf autom4te.cache
        diff --git a/vendor/openssl/openssl/demos/tunala/breakage.c b/vendor/openssl/openssl/demos/tunala/breakage.c
        new file mode 100644
        index 000000000..dcdd64b0e
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/breakage.c
        @@ -0,0 +1,66 @@
        +#include "tunala.h"
        +
        +int int_strtoul(const char *str, unsigned long *val)
        +{
        +#ifdef HAVE_STRTOUL
        +	char *tmp;
        +	unsigned long ret = strtoul(str, &tmp, 10);
        +	if((str == tmp) || (*tmp != '\0'))
        +		/* The value didn't parse cleanly */
        +		return 0;
        +	if(ret == ULONG_MAX)
        +		/* We hit a limit */
        +		return 0;
        +	*val = ret;
        +	return 1;
        +#else
        +	char buf[2];
        +	unsigned long ret = 0;
        +	buf[1] = '\0';
        +	if(str == '\0')
        +		/* An empty string ... */
        +		return 0;
        +	while(*str != '\0') {
        +		/* We have to multiply 'ret' by 10 before absorbing the next
        +		 * digit. If this will overflow, catch it now. */
        +		if(ret && (((ULONG_MAX + 10) / ret) < 10))
        +			return 0;
        +		ret *= 10;
        +		if(!isdigit(*str))
        +			return 0;
        +		buf[0] = *str;
        +		ret += atoi(buf);
        +		str++;
        +	}
        +	*val = ret;
        +	return 1;
        +#endif
        +}
        +
        +#ifndef HAVE_STRSTR
        +char *int_strstr(const char *haystack, const char *needle)
        +{
        +	const char *sub_haystack = haystack, *sub_needle = needle;
        +	unsigned int offset = 0;
        +	if(!needle)
        +		return haystack;
        +	if(!haystack)
        +		return NULL;
        +	while((*sub_haystack != '\0') && (*sub_needle != '\0')) {
        +		if(sub_haystack[offset] == sub_needle) {
        +			/* sub_haystack is still a candidate */
        +			offset++;
        +			sub_needle++;
        +		} else {
        +			/* sub_haystack is no longer a possibility */
        +			sub_haystack++;
        +			offset = 0;
        +			sub_needle = needle;
        +		}
        +	}
        +	if(*sub_haystack == '\0')
        +		/* Found nothing */
        +		return NULL;
        +	return sub_haystack;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/demos/tunala/buffer.c b/vendor/openssl/openssl/demos/tunala/buffer.c
        new file mode 100644
        index 000000000..c5cd00420
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/buffer.c
        @@ -0,0 +1,205 @@
        +#include "tunala.h"
        +
        +#ifndef NO_BUFFER
        +
        +void buffer_init(buffer_t *buf)
        +{
        +	buf->used = 0;
        +	buf->total_in = buf->total_out = 0;
        +}
        +
        +void buffer_close(buffer_t *buf)
        +{
        +	/* Our data is static - nothing needs "release", just reset it */
        +	buf->used = 0;
        +}
        +
        +/* Code these simple ones in compact form */
        +unsigned int buffer_used(buffer_t *buf) {
        +	return buf->used; }
        +unsigned int buffer_unused(buffer_t *buf) {
        +	return (MAX_DATA_SIZE - buf->used); }
        +int buffer_full(buffer_t *buf) {
        +	return (buf->used == MAX_DATA_SIZE ? 1 : 0); }
        +int buffer_notfull(buffer_t *buf) {
        +	return (buf->used < MAX_DATA_SIZE ? 1 : 0); }
        +int buffer_empty(buffer_t *buf) {
        +	return (buf->used == 0 ? 1 : 0); }
        +int buffer_notempty(buffer_t *buf) {
        +	return (buf->used > 0 ? 1 : 0); }
        +unsigned long buffer_total_in(buffer_t *buf) {
        +	return buf->total_in; }
        +unsigned long buffer_total_out(buffer_t *buf) {
        +	return buf->total_out; }
        +
        +/* These 3 static (internal) functions don't adjust the "total" variables as
        + * it's not sure when they're called how it should be interpreted. Only the
        + * higher-level "buffer_[to|from]_[fd|SSL|BIO]" functions should alter these
        + * values. */
        +#if 0 /* To avoid "unused" warnings */
        +static unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr,
        +		unsigned int size)
        +{
        +	unsigned int added = MAX_DATA_SIZE - buf->used;
        +	if(added > size)
        +		added = size;
        +	if(added == 0)
        +		return 0;
        +	memcpy(buf->data + buf->used, ptr, added);
        +	buf->used += added;
        +	buf->total_in += added;
        +	return added;
        +}
        +
        +static unsigned int buffer_tobuffer(buffer_t *to, buffer_t *from, int cap)
        +{
        +	unsigned int moved, tomove = from->used;
        +	if((int)tomove > cap)
        +		tomove = cap;
        +	if(tomove == 0)
        +		return 0;
        +	moved = buffer_adddata(to, from->data, tomove);
        +	if(moved == 0)
        +		return 0;
        +	buffer_takedata(from, NULL, moved);
        +	return moved;
        +}
        +#endif
        +
        +static unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr,
        +		unsigned int size)
        +{
        +	unsigned int taken = buf->used;
        +	if(taken > size)
        +		taken = size;
        +	if(taken == 0)
        +		return 0;
        +	if(ptr)
        +		memcpy(ptr, buf->data, taken);
        +	buf->used -= taken;
        +	/* Do we have to scroll? */
        +	if(buf->used > 0)
        +		memmove(buf->data, buf->data + taken, buf->used);
        +	return taken;
        +}
        +
        +#ifndef NO_IP
        +
        +int buffer_from_fd(buffer_t *buf, int fd)
        +{
        +	int toread = buffer_unused(buf);
        +	if(toread == 0)
        +		/* Shouldn't be called in this case! */
        +		abort();
        +	toread = read(fd, buf->data + buf->used, toread);
        +	if(toread > 0) {
        +		buf->used += toread;
        +		buf->total_in += toread;
        +	}
        +	return toread;
        +}
        +
        +int buffer_to_fd(buffer_t *buf, int fd)
        +{
        +	int towrite = buffer_used(buf);
        +	if(towrite == 0)
        +		/* Shouldn't be called in this case! */
        +		abort();
        +	towrite = write(fd, buf->data, towrite);
        +	if(towrite > 0) {
        +		buffer_takedata(buf, NULL, towrite);
        +		buf->total_out += towrite;
        +	}
        +	return towrite;
        +}
        +
        +#endif /* !defined(NO_IP) */
        +
        +#ifndef NO_OPENSSL
        +
        +static void int_ssl_check(SSL *s, int ret)
        +{
        +	int e = SSL_get_error(s, ret);
        +	switch(e) {
        +		/* These seem to be harmless and already "dealt with" by our
        +		 * non-blocking environment. NB: "ZERO_RETURN" is the clean
        +		 * "error" indicating a successfully closed SSL tunnel. We let
        +		 * this happen because our IO loop should not appear to have
        +		 * broken on this condition - and outside the IO loop, the
        +		 * "shutdown" state is checked. */
        +	case SSL_ERROR_NONE:
        +	case SSL_ERROR_WANT_READ:
        +	case SSL_ERROR_WANT_WRITE:
        +	case SSL_ERROR_WANT_X509_LOOKUP:
        +	case SSL_ERROR_ZERO_RETURN:
        +		return;
        +		/* These seem to be indications of a genuine error that should
        +		 * result in the SSL tunnel being regarded as "dead". */
        +	case SSL_ERROR_SYSCALL:
        +	case SSL_ERROR_SSL:
        +		SSL_set_app_data(s, (char *)1);
        +		return;
        +	default:
        +		break;
        +	}
        +	/* For any other errors that (a) exist, and (b) crop up - we need to
        +	 * interpret what to do with them - so "politely inform" the caller that
        +	 * the code needs updating here. */
        +	abort();
        +}
        +
        +void buffer_from_SSL(buffer_t *buf, SSL *ssl)
        +{
        +	int ret;
        +	if(!ssl || buffer_full(buf))
        +		return;
        +	ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
        +	if(ret > 0) {
        +		buf->used += ret;
        +		buf->total_in += ret;
        +	}
        +	if(ret < 0)
        +		int_ssl_check(ssl, ret);
        +}
        +
        +void buffer_to_SSL(buffer_t *buf, SSL *ssl)
        +{
        +	int ret;
        +	if(!ssl || buffer_empty(buf))
        +		return;
        +	ret = SSL_write(ssl, buf->data, buf->used);
        +	if(ret > 0) {
        +		buffer_takedata(buf, NULL, ret);
        +		buf->total_out += ret;
        +	}
        +	if(ret < 0)
        +		int_ssl_check(ssl, ret);
        +}
        +
        +void buffer_from_BIO(buffer_t *buf, BIO *bio)
        +{
        +	int ret;
        +	if(!bio || buffer_full(buf))
        +		return;
        +	ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf));
        +	if(ret > 0) {
        +		buf->used += ret;
        +		buf->total_in += ret;
        +	}
        +}
        +
        +void buffer_to_BIO(buffer_t *buf, BIO *bio)
        +{
        +	int ret;
        +	if(!bio || buffer_empty(buf))
        +		return;
        +	ret = BIO_write(bio, buf->data, buf->used);
        +	if(ret > 0) {
        +		buffer_takedata(buf, NULL, ret);
        +		buf->total_out += ret;
        +	}
        +}
        +
        +#endif /* !defined(NO_OPENSSL) */
        +
        +#endif /* !defined(NO_BUFFER) */
        diff --git a/vendor/openssl/openssl/demos/tunala/cb.c b/vendor/openssl/openssl/demos/tunala/cb.c
        new file mode 100644
        index 000000000..f6e452ae9
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/cb.c
        @@ -0,0 +1,162 @@
        +#include "tunala.h"
        +
        +#ifndef NO_OPENSSL
        +
        +/* For callbacks generating output, here are their file-descriptors. */
        +static FILE *fp_cb_ssl_info = NULL;
        +static FILE *fp_cb_ssl_verify = NULL;
        +/* Output level:
        + *     0 = nothing,
        + *     1 = minimal, just errors,
        + *     2 = minimal, all steps,
        + *     3 = detail, all steps */
        +static unsigned int cb_ssl_verify_level = 1;
        +
        +/* Other static rubbish (to mirror s_cb.c where required) */
        +static int int_verify_depth = 10;
        +
        +/* This function is largely borrowed from the one used in OpenSSL's "s_client"
        + * and "s_server" utilities. */
        +void cb_ssl_info(const SSL *s, int where, int ret)
        +{
        +	const char *str1, *str2;
        +	int w;
        +
        +	if(!fp_cb_ssl_info)
        +		return;
        +
        +	w = where & ~SSL_ST_MASK;
        +	str1 = (w & SSL_ST_CONNECT ? "SSL_connect" : (w & SSL_ST_ACCEPT ?
        +				"SSL_accept" : "undefined")),
        +	str2 = SSL_state_string_long(s);
        +
        +	if (where & SSL_CB_LOOP)
        +		fprintf(fp_cb_ssl_info, "(%s) %s\n", str1, str2);
        +	else if (where & SSL_CB_EXIT) {
        +		if (ret == 0)
        +			fprintf(fp_cb_ssl_info, "(%s) failed in %s\n", str1, str2);
        +/* In a non-blocking model, we get a few of these "error"s simply because we're
        + * calling "reads" and "writes" on the state-machine that are virtual NOPs
        + * simply to avoid wasting the time seeing if we *should* call them. Removing
        + * this case makes the "-out_state" output a lot easier on the eye. */
        +#if 0
        +		else if (ret < 0)
        +			fprintf(fp_cb_ssl_info, "%s:error in %s\n", str1, str2);
        +#endif
        +	}
        +}
        +
        +void cb_ssl_info_set_output(FILE *fp)
        +{
        +	fp_cb_ssl_info = fp;
        +}
        +
        +static const char *int_reason_no_issuer = "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT";
        +static const char *int_reason_not_yet = "X509_V_ERR_CERT_NOT_YET_VALID";
        +static const char *int_reason_before = "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD";
        +static const char *int_reason_expired = "X509_V_ERR_CERT_HAS_EXPIRED";
        +static const char *int_reason_after = "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD";
        +
        +/* Stolen wholesale from apps/s_cb.c :-) And since then, mutilated ... */
        +int cb_ssl_verify(int ok, X509_STORE_CTX *ctx)
        +{
        +	char buf1[256]; /* Used for the subject name */
        +	char buf2[256]; /* Used for the issuer name */
        +	const char *reason = NULL; /* Error reason (if any) */
        +	X509 *err_cert;
        +	int err, depth;
        +
        +	if(!fp_cb_ssl_verify || (cb_ssl_verify_level == 0))
        +		return ok;
        +	err_cert = X509_STORE_CTX_get_current_cert(ctx);
        +	err = X509_STORE_CTX_get_error(ctx);
        +	depth = X509_STORE_CTX_get_error_depth(ctx);
        +
        +	buf1[0] = buf2[0] = '\0';
        +	/* Fill buf1 */
        +	X509_NAME_oneline(X509_get_subject_name(err_cert), buf1, 256);
        +	/* Fill buf2 */
        +	X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf2, 256);
        +	switch (ctx->error) {
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +		reason = int_reason_no_issuer;
        +		break;
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +		reason = int_reason_not_yet;
        +		break;
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +		reason = int_reason_before;
        +		break;
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +		reason = int_reason_expired;
        +		break;
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +		reason = int_reason_after;
        +		break;
        +	}
        +
        +	if((cb_ssl_verify_level == 1) && ok)
        +		return ok;
        +	fprintf(fp_cb_ssl_verify, "chain-depth=%d, ", depth);
        +	if(reason)
        +		fprintf(fp_cb_ssl_verify, "error=%s\n", reason);
        +	else
        +		fprintf(fp_cb_ssl_verify, "error=%d\n", err);
        +	if(cb_ssl_verify_level < 3)
        +		return ok;
        +	fprintf(fp_cb_ssl_verify, "--> subject = %s\n", buf1);
        +	fprintf(fp_cb_ssl_verify, "--> issuer  = %s\n", buf2);
        +	if(!ok)
        +		fprintf(fp_cb_ssl_verify,"--> verify error:num=%d:%s\n",err,
        +			X509_verify_cert_error_string(err));
        +	fprintf(fp_cb_ssl_verify, "--> verify return:%d\n",ok);
        +	return ok;
        +}
        +
        +void cb_ssl_verify_set_output(FILE *fp)
        +{
        +	fp_cb_ssl_verify = fp;
        +}
        +
        +void cb_ssl_verify_set_depth(unsigned int verify_depth)
        +{
        +	int_verify_depth = verify_depth;
        +}
        +
        +void cb_ssl_verify_set_level(unsigned int level)
        +{
        +	if(level < 4)
        +		cb_ssl_verify_level = level;
        +}
        +
        +RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength)
        +{
        +	/* TODO: Perhaps make it so our global key can be generated on-the-fly
        +	 * after certain intervals? */
        +	static RSA *rsa_tmp = NULL;
        +	BIGNUM *bn = NULL;
        +	int ok = 1;
        +	if(!rsa_tmp) {
        +		ok = 0;
        +		if(!(bn = BN_new()))
        +			goto end;
        +		if(!BN_set_word(bn, RSA_F4))
        +			goto end;
        +		if(!(rsa_tmp = RSA_new()))
        +			goto end;
        +		if(!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
        +			goto end;
        +		ok = 1;
        +	}
        +end:
        +	if(bn)
        +		BN_free(bn);
        +	if(!ok) {
        +		RSA_free(rsa_tmp);
        +		rsa_tmp = NULL;
        +	}
        +	return rsa_tmp;
        +}
        +
        +#endif /* !defined(NO_OPENSSL) */
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/configure.in b/vendor/openssl/openssl/demos/tunala/configure.in
        new file mode 100644
        index 000000000..590cdbfd2
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/configure.in
        @@ -0,0 +1,29 @@
        +dnl Process this file with autoconf to produce a configure script.
        +AC_INIT(tunala.c)
        +AM_CONFIG_HEADER(config.h)
        +AM_INIT_AUTOMAKE(tunala, 0.0.1-dev)
        +
        +dnl Checks for programs. (Though skip libtool)
        +AC_PROG_CC
        +dnl AC_PROG_LIBTOOL
        +dnl AM_PROG_LIBTOOL
        +
        +dnl Checks for libraries.
        +AC_CHECK_LIB(dl, dlopen)
        +AC_CHECK_LIB(z, inflate)
        +AC_CHECK_LIB(socket, socket)
        +AC_CHECK_LIB(nsl, gethostbyname)
        +
        +dnl Checks for header files.
        +AC_HEADER_STDC
        +AC_CHECK_HEADERS(fcntl.h limits.h unistd.h)
        +
        +dnl Checks for typedefs, structures, and compiler characteristics.
        +AC_C_CONST
        +
        +dnl Checks for library functions.
        +AC_CHECK_FUNCS(strstr strtoul)
        +AC_CHECK_FUNCS(select socket)
        +AC_CHECK_FUNCS(dlopen)
        +
        +AC_OUTPUT(Makefile)
        diff --git a/vendor/openssl/openssl/demos/tunala/ip.c b/vendor/openssl/openssl/demos/tunala/ip.c
        new file mode 100644
        index 000000000..96ef4e653
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/ip.c
        @@ -0,0 +1,146 @@
        +#include "tunala.h"
        +
        +#ifndef NO_IP
        +
        +#define IP_LISTENER_BACKLOG 511 /* So if it gets masked by 256 or some other
        +				   such value it'll still be respectable */
        +
        +/* Any IP-related initialisations. For now, this means blocking SIGPIPE */
        +int ip_initialise(void)
        +{
        +	struct sigaction sa;
        +
        +	sa.sa_handler = SIG_IGN;
        +	sa.sa_flags = 0;
        +	sigemptyset(&sa.sa_mask);
        +	if(sigaction(SIGPIPE, &sa, NULL) != 0)
        +		return 0;
        +	return 1;
        +}
        +
        +int ip_create_listener_split(const char *ip, unsigned short port)
        +{
        +	struct sockaddr_in in_addr;
        +	int fd = -1;
        +	int reuseVal = 1;
        +
        +	/* Create the socket */
        +	if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        +		goto err;
        +	/* Set the SO_REUSEADDR flag - servers act weird without it */
        +	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)(&reuseVal),
        +				sizeof(reuseVal)) != 0)
        +		goto err;
        +	/* Prepare the listen address stuff */
        +	in_addr.sin_family = AF_INET;
        +	memcpy(&in_addr.sin_addr.s_addr, ip, 4);
        +	in_addr.sin_port = htons(port);
        +	/* Bind to the required port/address/interface */
        +	if(bind(fd, (struct sockaddr *)&in_addr, sizeof(struct sockaddr_in)) != 0)
        +		goto err;
        +	/* Start "listening" */
        +	if(listen(fd, IP_LISTENER_BACKLOG) != 0)
        +		goto err;
        +	return fd;
        +err:
        +	if(fd != -1)
        +		close(fd);
        +	return -1;
        +}
        +
        +int ip_create_connection_split(const char *ip, unsigned short port)
        +{
        +	struct sockaddr_in in_addr;
        +	int flags, fd = -1;
        +
        +	/* Create the socket */
        +	if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        +		goto err;
        +	/* Make it non-blocking */
        +	if(((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
        +			(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0))
        +		goto err;
        +	/* Prepare the connection address stuff */
        +	in_addr.sin_family = AF_INET;
        +	memcpy(&in_addr.sin_addr.s_addr, ip, 4);
        +	in_addr.sin_port = htons(port);
        +	/* Start a connect (non-blocking, in all likelihood) */
        +	if((connect(fd, (struct sockaddr *)&in_addr,
        +			sizeof(struct sockaddr_in)) != 0) &&
        +			(errno != EINPROGRESS))
        +		goto err;
        +	return fd;
        +err:
        +	if(fd != -1)
        +		close(fd);
        +	return -1;
        +}
        +
        +static char all_local_ip[] = {0x00,0x00,0x00,0x00};
        +
        +int ip_parse_address(const char *address, const char **parsed_ip,
        +		unsigned short *parsed_port, int accept_all_ip)
        +{
        +	char buf[256];
        +	struct hostent *lookup;
        +	unsigned long port;
        +	const char *ptr = strstr(address, ":");
        +	const char *ip = all_local_ip;
        +
        +	if(!ptr) {
        +		/* We assume we're listening on all local interfaces and have
        +		 * only specified a port. */
        +		if(!accept_all_ip)
        +			return 0;
        +		ptr = address;
        +		goto determine_port;
        +	}
        +	if((ptr - address) > 255)
        +		return 0;
        +	memset(buf, 0, 256);
        +	memcpy(buf, address, ptr - address);
        +	ptr++;
        +	if((lookup = gethostbyname(buf)) == NULL) {
        +		/* Spit a message to differentiate between lookup failures and
        +		 * bad strings. */
        +		fprintf(stderr, "hostname lookup for '%s' failed\n", buf);
        +		return 0;
        +	}
        +	ip = lookup->h_addr_list[0];
        +determine_port:
        +	if(strlen(ptr) < 1)
        +		return 0;
        +	if(!int_strtoul(ptr, &port) || (port > 65535))
        +		return 0;
        +	*parsed_ip = ip;
        +	*parsed_port = (unsigned short)port;
        +	return 1;
        +}
        +
        +int ip_create_listener(const char *address)
        +{
        +	const char *ip;
        +	unsigned short port;
        +
        +	if(!ip_parse_address(address, &ip, &port, 1))
        +		return -1;
        +	return ip_create_listener_split(ip, port);
        +}
        +
        +int ip_create_connection(const char *address)
        +{
        +	const char *ip;
        +	unsigned short port;
        +
        +	if(!ip_parse_address(address, &ip, &port, 0))
        +		return -1;
        +	return ip_create_connection_split(ip, port);
        +}
        +
        +int ip_accept_connection(int listen_fd)
        +{
        +	return accept(listen_fd, NULL, NULL);
        +}
        +
        +#endif /* !defined(NO_IP) */
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/sm.c b/vendor/openssl/openssl/demos/tunala/sm.c
        new file mode 100644
        index 000000000..25359e67e
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/sm.c
        @@ -0,0 +1,151 @@
        +#include "tunala.h"
        +
        +#ifndef NO_TUNALA
        +
        +void state_machine_init(state_machine_t *machine)
        +{
        +	machine->ssl = NULL;
        +	machine->bio_intossl = machine->bio_fromssl = NULL;
        +	buffer_init(&machine->clean_in);
        +	buffer_init(&machine->clean_out);
        +	buffer_init(&machine->dirty_in);
        +	buffer_init(&machine->dirty_out);
        +}
        +
        +void state_machine_close(state_machine_t *machine)
        +{
        +	if(machine->ssl)
        +		SSL_free(machine->ssl);
        +/* SSL_free seems to decrement the reference counts already so doing this goes
        + * kaboom. */
        +#if 0
        +	if(machine->bio_intossl)
        +		BIO_free(machine->bio_intossl);
        +	if(machine->bio_fromssl)
        +		BIO_free(machine->bio_fromssl);
        +#endif
        +	buffer_close(&machine->clean_in);
        +	buffer_close(&machine->clean_out);
        +	buffer_close(&machine->dirty_in);
        +	buffer_close(&machine->dirty_out);
        +	state_machine_init(machine);
        +}
        +
        +buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type)
        +{
        +	switch(type) {
        +	case SM_CLEAN_IN:
        +		return &machine->clean_in;
        +	case SM_CLEAN_OUT:
        +		return &machine->clean_out;
        +	case SM_DIRTY_IN:
        +		return &machine->dirty_in;
        +	case SM_DIRTY_OUT:
        +		return &machine->dirty_out;
        +	default:
        +		break;
        +	}
        +	/* Should never get here */
        +	abort();
        +	return NULL;
        +}
        +
        +SSL *state_machine_get_SSL(state_machine_t *machine)
        +{
        +	return machine->ssl;
        +}
        +
        +int state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server)
        +{
        +	if(machine->ssl)
        +		/* Shouldn't ever be set twice */
        +		abort();
        +	machine->ssl = ssl;
        +	/* Create the BIOs to handle the dirty side of the SSL */
        +	if((machine->bio_intossl = BIO_new(BIO_s_mem())) == NULL)
        +		abort();
        +	if((machine->bio_fromssl = BIO_new(BIO_s_mem())) == NULL)
        +		abort();
        +	/* Hook up the BIOs on the dirty side of the SSL */
        +	SSL_set_bio(machine->ssl, machine->bio_intossl, machine->bio_fromssl);
        +	if(is_server)
        +		SSL_set_accept_state(machine->ssl);
        +	else
        +		SSL_set_connect_state(machine->ssl);
        +	/* If we're the first one to generate traffic - do it now otherwise we
        +	 * go into the next select empty-handed and our peer will not send data
        +	 * but will similarly wait for us. */
        +	return state_machine_churn(machine);
        +}
        +
        +/* Performs the data-IO loop and returns zero if the machine should close */
        +int state_machine_churn(state_machine_t *machine)
        +{
        +	unsigned int loop;
        +	if(machine->ssl == NULL) {
        +		if(buffer_empty(&machine->clean_out))
        +			/* Time to close this state-machine altogether */
        +			return 0;
        +		else
        +			/* Still buffered data on the clean side to go out */
        +			return 1;
        +	}
        +	/* Do this loop twice to cover any dependencies about which precise
        +	 * order of reads and writes is required. */
        +	for(loop = 0; loop < 2; loop++) {
        +		buffer_to_SSL(&machine->clean_in, machine->ssl);
        +		buffer_to_BIO(&machine->dirty_in, machine->bio_intossl);
        +		buffer_from_SSL(&machine->clean_out, machine->ssl);
        +		buffer_from_BIO(&machine->dirty_out, machine->bio_fromssl);
        +	}
        +	/* We close on the SSL side if the info callback noticed some problems
        +	 * or an SSL shutdown was underway and shutdown traffic had all been
        +	 * sent. */
        +	if(SSL_get_app_data(machine->ssl) || (SSL_get_shutdown(machine->ssl) &&
        +				buffer_empty(&machine->dirty_out))) {
        +		/* Great, we can seal off the dirty side completely */
        +		if(!state_machine_close_dirty(machine))
        +			return 0;
        +	}
        +	/* Either the SSL is alive and well, or the closing process still has
        +	 * outgoing data waiting to be sent */
        +	return 1;
        +}
        +
        +/* Called when the clean side of the SSL has lost its connection */
        +int state_machine_close_clean(state_machine_t *machine)
        +{
        +	/* Well, first thing to do is null out the clean-side buffers - they're
        +	 * no use any more. */
        +	buffer_close(&machine->clean_in);
        +	buffer_close(&machine->clean_out);
        +	/* And start an SSL shutdown */
        +	if(machine->ssl)
        +		SSL_shutdown(machine->ssl);
        +	/* This is an "event", so flush the SSL of any generated traffic */
        +	state_machine_churn(machine);
        +	if(buffer_empty(&machine->dirty_in) &&
        +			buffer_empty(&machine->dirty_out))
        +		return 0;
        +	return 1;
        +}
        +
        +/* Called when the dirty side of the SSL has lost its connection. This is pretty
        + * terminal as all that can be left to do is send any buffered output on the
        + * clean side - after that, we're done. */
        +int state_machine_close_dirty(state_machine_t *machine)
        +{
        +	buffer_close(&machine->dirty_in);
        +	buffer_close(&machine->dirty_out);
        +	buffer_close(&machine->clean_in);
        +	if(machine->ssl)
        +		SSL_free(machine->ssl);
        +	machine->ssl = NULL;
        +	machine->bio_intossl = machine->bio_fromssl = NULL;
        +	if(buffer_empty(&machine->clean_out))
        +		return 0;
        +	return 1;
        +}
        +
        +#endif /* !defined(NO_TUNALA) */
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/test.sh b/vendor/openssl/openssl/demos/tunala/test.sh
        new file mode 100644
        index 000000000..105b44733
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/test.sh
        @@ -0,0 +1,107 @@
        +#!/bin/sh
        +
        +HTTP="localhost:8080"
        +CLIENT_PORT="9020"
        +SERVER_PORT="9021"
        +
        +sub_test ()
        +{
        +	echo "STARTING - $VER $CIPHER"
        +	./tunala -listen localhost:$CLIENT_PORT -proxy localhost:$SERVER_PORT \
        +		-cacert CA.pem -cert A-client.pem -server 0 \
        +		-dh_special standard -v_peer -v_strict \
        +		$VER -cipher $CIPHER 1> tc1.txt 2> tc2.txt &
        +	./tunala -listen localhost:$SERVER_PORT -proxy $HTTP \
        +		-cacert CA.pem -cert A-server.pem -server 1 \
        +		-dh_special standard -v_peer -v_strict \
        +		$VER -cipher $CIPHER 1> ts1.txt 2> ts2.txt &
        +	# Wait for the servers to be listening before starting the wget test
        +	DONE="no"
        +	while [ "$DONE" != "yes" ]; do
        +		L1=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$CLIENT_PORT"`
        +		L2=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$SERVER_PORT"`
        +		if [ "x$L1" != "x" ]; then
        +			DONE="yes"
        +		elif [ "x$L2" != "x" ]; then
        +			DONE="yes"
        +		else
        +			sleep 1
        +		fi
        +	done
        +	HTML=`wget -O - -T 1 http://localhost:$CLIENT_PORT 2> /dev/null | grep "<HTML>"`
        +	if [ "x$HTML" != "x" ]; then
        +		echo "OK - $CIPHER ($VER)"
        +	else
        +		echo "FAIL - $CIPHER ($VER)"
        +		killall tunala
        +		exit 1
        +	fi
        +	killall tunala
        +	# Wait for the servers to stop before returning - otherwise the next
        +	# test my fail to start ... (fscking race conditions)
        +	DONE="yes"
        +	while [ "$DONE" != "no" ]; do
        +		L1=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$CLIENT_PORT"`
        +		L2=`netstat -a | egrep "LISTEN[\t ]*$" | grep ":$SERVER_PORT"`
        +		if [ "x$L1" != "x" ]; then
        +			DONE="yes"
        +		elif [ "x$L2" != "x" ]; then
        +			DONE="yes"
        +		else
        +			DONE="no"
        +		fi
        +	done
        +	exit 0
        +}
        +
        +run_test ()
        +{
        +	(sub_test 1> /dev/null) || exit 1
        +}
        +
        +run_ssl_test ()
        +{
        +killall tunala 1> /dev/null 2> /dev/null
        +echo ""
        +echo "Starting all $PRETTY tests"
        +if [ "$PRETTY" != "SSLv2" ]; then
        +	if [ "$PRETTY" != "SSLv3" ]; then
        +		export VER="-no_ssl2 -no_ssl3"
        +		export OSSL="-tls1"
        +	else
        +		export VER="-no_ssl2 -no_tls1"
        +		export OSSL="-ssl3"
        +	fi
        +else
        +	export VER="-no_ssl3 -no_tls1"
        +	export OSSL="-ssl2"
        +fi
        +LIST="`../../apps/openssl ciphers $OSSL | sed -e 's/:/ /g'`"
        +#echo "$LIST"
        +for i in $LIST; do \
        +	DSS=`echo "$i" | grep "DSS"`
        +	if [ "x$DSS" != "x" ]; then
        +		echo "---- skipping $i (no DSA cert/keys) ----"
        +	else
        +		export CIPHER=$i
        +		run_test
        +		echo "SUCCESS: $i"
        +	fi
        +done;
        +}
        +
        +# Welcome the user
        +echo "Tests will assume an http server running at $HTTP"
        +
        +# TLSv1 test
        +export PRETTY="TLSv1"
        +run_ssl_test
        +
        +# SSLv3 test
        +export PRETTY="SSLv3"
        +run_ssl_test
        +
        +# SSLv2 test
        +export PRETTY="SSLv2"
        +run_ssl_test
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/tunala.c b/vendor/openssl/openssl/demos/tunala/tunala.c
        new file mode 100644
        index 000000000..ec49d3e94
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/tunala.c
        @@ -0,0 +1,1109 @@
        +#if defined(NO_BUFFER) || defined(NO_IP) || defined(NO_OPENSSL)
        +#error "Badness, NO_BUFFER, NO_IP or NO_OPENSSL is defined, turn them *off*"
        +#endif
        +
        +/* Include our bits'n'pieces */
        +#include "tunala.h"
        +
        +
        +/********************************************/
        +/* Our local types that specify our "world" */
        +/********************************************/
        +
        +/* These represent running "tunnels". Eg. if you wanted to do SSL in a
        + * "message-passing" scanario, the "int" file-descriptors might be replaced by
        + * thread or process IDs, and the "select" code might be replaced by message
        + * handling code. Whatever. */
        +typedef struct _tunala_item_t {
        +	/* The underlying SSL state machine. This is a data-only processing unit
        +	 * and we communicate with it by talking to its four "buffers". */
        +	state_machine_t sm;
        +	/* The file-descriptors for the "dirty" (encrypted) side of the SSL
        +	 * setup. In actuality, this is typically a socket and both values are
        +	 * identical. */
        +	int dirty_read, dirty_send;
        +	/* The file-descriptors for the "clean" (unencrypted) side of the SSL
        +	 * setup. These could be stdin/stdout, a socket (both values the same),
        +	 * or whatever you like. */
        +	int clean_read, clean_send;
        +} tunala_item_t;
        +
        +/* This structure is used as the data for running the main loop. Namely, in a
        + * network format such as this, it is stuff for select() - but as pointed out,
        + * when moving the real-world to somewhere else, this might be replaced by
        + * something entirely different. It's basically the stuff that controls when
        + * it's time to do some "work". */
        +typedef struct _select_sets_t {
        +	int max; /* As required as the first argument to select() */
        +	fd_set reads, sends, excepts; /* As passed to select() */
        +} select_sets_t;
        +typedef struct _tunala_selector_t {
        +	select_sets_t last_selected; /* Results of the last select() */
        +	select_sets_t next_select; /* What we'll next select on */
        +} tunala_selector_t;
        +
        +/* This structure is *everything*. We do it to avoid the use of globals so that,
        + * for example, it would be easier to shift things around between async-IO,
        + * thread-based, or multi-fork()ed (or combinations thereof). */
        +typedef struct _tunala_world_t {
        +	/* The file-descriptor we "listen" on for new connections */
        +	int listen_fd;
        +	/* The array of tunnels */
        +	tunala_item_t *tunnels;
        +	/* the number of tunnels in use and allocated, respectively */
        +	unsigned int tunnels_used, tunnels_size;
        +	/* Our outside "loop" context stuff */
        +	tunala_selector_t selector;
        +	/* Our SSL_CTX, which is configured as the SSL client or server and has
        +	 * the various cert-settings and callbacks configured. */
        +	SSL_CTX *ssl_ctx;
        +	/* Simple flag with complex logic :-) Indicates whether we're an SSL
        +	 * server or an SSL client. */
        +	int server_mode;
        +} tunala_world_t;
        +
        +/*****************************/
        +/* Internal static functions */
        +/*****************************/
        +
        +static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
        +		const char *CAfile, const char *cert, const char *key,
        +		const char *dcert, const char *dkey, const char *cipher_list,
        +		const char *dh_file, const char *dh_special, int tmp_rsa,
        +		int ctx_options, int out_state, int out_verify, int verify_mode,
        +		unsigned int verify_depth);
        +static void selector_init(tunala_selector_t *selector);
        +static void selector_add_listener(tunala_selector_t *selector, int fd);
        +static void selector_add_tunala(tunala_selector_t *selector, tunala_item_t *t);
        +static int selector_select(tunala_selector_t *selector);
        +/* This returns -1 for error, 0 for no new connections, or 1 for success, in
        + * which case *newfd is populated. */
        +static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd);
        +static int tunala_world_new_item(tunala_world_t *world, int fd,
        +		const char *ip, unsigned short port, int flipped);
        +static void tunala_world_del_item(tunala_world_t *world, unsigned int idx);
        +static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item);
        +
        +/*********************************************/
        +/* MAIN FUNCTION (and its utility functions) */
        +/*********************************************/
        +
        +static const char *def_proxyhost = "127.0.0.1:443";
        +static const char *def_listenhost = "127.0.0.1:8080";
        +static int def_max_tunnels = 50;
        +static const char *def_cacert = NULL;
        +static const char *def_cert = NULL;
        +static const char *def_key = NULL;
        +static const char *def_dcert = NULL;
        +static const char *def_dkey = NULL;
        +static const char *def_engine_id = NULL;
        +static int def_server_mode = 0;
        +static int def_flipped = 0;
        +static const char *def_cipher_list = NULL;
        +static const char *def_dh_file = NULL;
        +static const char *def_dh_special = NULL;
        +static int def_tmp_rsa = 1;
        +static int def_ctx_options = 0;
        +static int def_verify_mode = 0;
        +static unsigned int def_verify_depth = 10;
        +static int def_out_state = 0;
        +static unsigned int def_out_verify = 0;
        +static int def_out_totals = 0;
        +static int def_out_conns = 0;
        +
        +static const char *helpstring =
        +"\n'Tunala' (A tunneler with a New Zealand accent)\n"
        +"Usage: tunala [options], where options are from;\n"
        +" -listen [host:]<port>  (default = 127.0.0.1:8080)\n"
        +" -proxy <host>:<port>   (default = 127.0.0.1:443)\n"
        +" -maxtunnels <num>      (default = 50)\n"
        +" -cacert <path|NULL>    (default = NULL)\n"
        +" -cert <path|NULL>      (default = NULL)\n"
        +" -key <path|NULL>       (default = whatever '-cert' is)\n"
        +" -dcert <path|NULL>     (usually for DSA, default = NULL)\n"
        +" -dkey <path|NULL>      (usually for DSA, default = whatever '-dcert' is)\n"
        +" -engine <id|NULL>      (default = NULL)\n"
        +" -server <0|1>          (default = 0, ie. an SSL client)\n"
        +" -flipped <0|1>         (makes SSL servers be network clients, and vice versa)\n"
        +" -cipher <list>         (specifies cipher list to use)\n"
        +" -dh_file <path>        (a PEM file containing DH parameters to use)\n"
        +" -dh_special <NULL|generate|standard> (see below: def=NULL)\n"
        +" -no_tmp_rsa            (don't generate temporary RSA keys)\n"
        +" -no_ssl2               (disable SSLv2)\n"
        +" -no_ssl3               (disable SSLv3)\n"
        +" -no_tls1               (disable TLSv1)\n"
        +" -v_peer                (verify the peer certificate)\n"
        +" -v_strict              (do not continue if peer doesn't authenticate)\n"
        +" -v_once                (no verification in renegotiates)\n"
        +" -v_depth <num>         (limit certificate chain depth, default = 10)\n"
        +" -out_conns             (prints client connections and disconnections)\n"
        +" -out_state             (prints SSL handshake states)\n"
        +" -out_verify <0|1|2|3>  (prints certificate verification states: def=1)\n"
        +" -out_totals            (prints out byte-totals when a tunnel closes)\n"
        +" -<h|help|?>            (displays this help screen)\n"
        +"Notes:\n"
        +"(1) It is recommended to specify a cert+key when operating as an SSL server.\n"
        +"    If you only specify '-cert', the same file must contain a matching\n"
        +"    private key.\n"
        +"(2) Either dh_file or dh_special can be used to specify where DH parameters\n"
        +"    will be obtained from (or '-dh_special NULL' for the default choice) but\n"
        +"    you cannot specify both. For dh_special, 'generate' will create new DH\n"
        +"    parameters on startup, and 'standard' will use embedded parameters\n"
        +"    instead.\n"
        +"(3) Normally an ssl client connects to an ssl server - so that an 'ssl client\n"
        +"    tunala' listens for 'clean' client connections and proxies ssl, and an\n"
        +"    'ssl server tunala' listens for ssl connections and proxies 'clean'. With\n"
        +"    '-flipped 1', this behaviour is reversed so that an 'ssl server tunala'\n"
        +"    listens for clean client connections and proxies ssl (but participating\n"
        +"    as an ssl *server* in the SSL/TLS protocol), and an 'ssl client tunala'\n"
        +"    listens for ssl connections (participating as an ssl *client* in the\n"
        +"    SSL/TLS protocol) and proxies 'clean' to the end destination. This can\n"
        +"    be useful for allowing network access to 'servers' where only the server\n"
        +"    needs to authenticate the client (ie. the other way is not required).\n"
        +"    Even with client and server authentication, this 'technique' mitigates\n"
        +"    some DoS (denial-of-service) potential as it will be the network client\n"
        +"    having to perform the first private key operation rather than the other\n"
        +"    way round.\n"
        +"(4) The 'technique' used by setting '-flipped 1' is probably compatible with\n"
        +"    absolutely nothing except another complimentary instance of 'tunala'\n"
        +"    running with '-flipped 1'. :-)\n";
        +
        +/* Default DH parameters for use with "-dh_special standard" ... stolen striaght
        + * from s_server. */
        +static unsigned char dh512_p[]={
        +	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
        +	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
        +	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
        +	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
        +	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
        +	0x47,0x74,0xE8,0x33,
        +	};
        +static unsigned char dh512_g[]={
        +	0x02,
        +	};
        +
        +/* And the function that parses the above "standard" parameters, again, straight
        + * out of s_server. */
        +static DH *get_dh512(void)
        +	{
        +	DH *dh=NULL;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
        +	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		return(NULL);
        +	return(dh);
        +	}
        +
        +/* Various help/error messages used by main() */
        +static int usage(const char *errstr, int isunknownarg)
        +{
        +	if(isunknownarg)
        +		fprintf(stderr, "Error: unknown argument '%s'\n", errstr);
        +	else
        +		fprintf(stderr, "Error: %s\n", errstr);
        +	fprintf(stderr, "%s\n", helpstring);
        +	return 1;
        +}
        +
        +static int err_str0(const char *str0)
        +{
        +	fprintf(stderr, "%s\n", str0);
        +	return 1;
        +}
        +
        +static int err_str1(const char *fmt, const char *str1)
        +{
        +	fprintf(stderr, fmt, str1);
        +	fprintf(stderr, "\n");
        +	return 1;
        +}
        +
        +static int parse_max_tunnels(const char *s, unsigned int *maxtunnels)
        +{
        +	unsigned long l;
        +	if(!int_strtoul(s, &l) || (l < 1) || (l > 1024)) {
        +		fprintf(stderr, "Error, '%s' is an invalid value for "
        +				"maxtunnels\n", s);
        +		return 0;
        +	}
        +	*maxtunnels = (unsigned int)l;
        +	return 1;
        +}
        +
        +static int parse_server_mode(const char *s, int *servermode)
        +{
        +	unsigned long l;
        +	if(!int_strtoul(s, &l) || (l > 1)) {
        +		fprintf(stderr, "Error, '%s' is an invalid value for the "
        +				"server mode\n", s);
        +		return 0;
        +	}
        +	*servermode = (int)l;
        +	return 1;
        +}
        +
        +static int parse_dh_special(const char *s, const char **dh_special)
        +{
        +	if((strcmp(s, "NULL") == 0) || (strcmp(s, "generate") == 0) ||
        +			(strcmp(s, "standard") == 0)) {
        +		*dh_special = s;
        +		return 1;
        +	}
        +	fprintf(stderr, "Error, '%s' is an invalid value for 'dh_special'\n", s);
        +	return 0;
        +}
        +
        +static int parse_verify_level(const char *s, unsigned int *verify_level)
        +{
        +	unsigned long l;
        +	if(!int_strtoul(s, &l) || (l > 3)) {
        +		fprintf(stderr, "Error, '%s' is an invalid value for "
        +				"out_verify\n", s);
        +		return 0;
        +	}
        +	*verify_level = (unsigned int)l;
        +	return 1;
        +}
        +
        +static int parse_verify_depth(const char *s, unsigned int *verify_depth)
        +{
        +	unsigned long l;
        +	if(!int_strtoul(s, &l) || (l < 1) || (l > 50)) {
        +		fprintf(stderr, "Error, '%s' is an invalid value for "
        +				"verify_depth\n", s);
        +		return 0;
        +	}
        +	*verify_depth = (unsigned int)l;
        +	return 1;
        +}
        +
        +/* Some fprintf format strings used when tunnels close */
        +static const char *io_stats_dirty =
        +"    SSL traffic;   %8lu bytes in, %8lu bytes out\n";
        +static const char *io_stats_clean =
        +"    clear traffic; %8lu bytes in, %8lu bytes out\n";
        +
        +int main(int argc, char *argv[])
        +{
        +	unsigned int loop;
        +	int newfd;
        +	tunala_world_t world;
        +	tunala_item_t *t_item;
        +	const char *proxy_ip;
        +	unsigned short proxy_port;
        +	/* Overridables */
        +	const char *proxyhost = def_proxyhost;
        +	const char *listenhost = def_listenhost;
        +	unsigned int max_tunnels = def_max_tunnels;
        +	const char *cacert = def_cacert;
        +	const char *cert = def_cert;
        +	const char *key = def_key;
        +	const char *dcert = def_dcert;
        +	const char *dkey = def_dkey;
        +	const char *engine_id = def_engine_id;
        +	int server_mode = def_server_mode;
        +	int flipped = def_flipped;
        +	const char *cipher_list = def_cipher_list;
        +	const char *dh_file = def_dh_file;
        +	const char *dh_special = def_dh_special;
        +	int tmp_rsa = def_tmp_rsa;
        +	int ctx_options = def_ctx_options;
        +	int verify_mode = def_verify_mode;
        +	unsigned int verify_depth = def_verify_depth;
        +	int out_state = def_out_state;
        +	unsigned int out_verify = def_out_verify;
        +	int out_totals = def_out_totals;
        +	int out_conns = def_out_conns;
        +
        +/* Parse command-line arguments */
        +next_arg:
        +	argc--; argv++;
        +	if(argc > 0) {
        +		if(strcmp(*argv, "-listen") == 0) {
        +			if(argc < 2)
        +				return usage("-listen requires an argument", 0);
        +			argc--; argv++;
        +			listenhost = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-proxy") == 0) {
        +			if(argc < 2)
        +				return usage("-proxy requires an argument", 0);
        +			argc--; argv++;
        +			proxyhost = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-maxtunnels") == 0) {
        +			if(argc < 2)
        +				return usage("-maxtunnels requires an argument", 0);
        +			argc--; argv++;
        +			if(!parse_max_tunnels(*argv, &max_tunnels))
        +				return 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-cacert") == 0) {
        +			if(argc < 2)
        +				return usage("-cacert requires an argument", 0);
        +			argc--; argv++;
        +			if(strcmp(*argv, "NULL") == 0)
        +				cacert = NULL;
        +			else
        +				cacert = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-cert") == 0) {
        +			if(argc < 2)
        +				return usage("-cert requires an argument", 0);
        +			argc--; argv++;
        +			if(strcmp(*argv, "NULL") == 0)
        +				cert = NULL;
        +			else
        +				cert = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-key") == 0) {
        +			if(argc < 2)
        +				return usage("-key requires an argument", 0);
        +			argc--; argv++;
        +			if(strcmp(*argv, "NULL") == 0)
        +				key = NULL;
        +			else
        +				key = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-dcert") == 0) {
        +			if(argc < 2)
        +				return usage("-dcert requires an argument", 0);
        +			argc--; argv++;
        +			if(strcmp(*argv, "NULL") == 0)
        +				dcert = NULL;
        +			else
        +				dcert = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-dkey") == 0) {
        +			if(argc < 2)
        +				return usage("-dkey requires an argument", 0);
        +			argc--; argv++;
        +			if(strcmp(*argv, "NULL") == 0)
        +				dkey = NULL;
        +			else
        +				dkey = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-engine") == 0) {
        +			if(argc < 2)
        +				return usage("-engine requires an argument", 0);
        +			argc--; argv++;
        +			engine_id = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-server") == 0) {
        +			if(argc < 2)
        +				return usage("-server requires an argument", 0);
        +			argc--; argv++;
        +			if(!parse_server_mode(*argv, &server_mode))
        +				return 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-flipped") == 0) {
        +			if(argc < 2)
        +				return usage("-flipped requires an argument", 0);
        +			argc--; argv++;
        +			if(!parse_server_mode(*argv, &flipped))
        +				return 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-cipher") == 0) {
        +			if(argc < 2)
        +				return usage("-cipher requires an argument", 0);
        +			argc--; argv++;
        +			cipher_list = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-dh_file") == 0) {
        +			if(argc < 2)
        +				return usage("-dh_file requires an argument", 0);
        +			if(dh_special)
        +				return usage("cannot mix -dh_file with "
        +						"-dh_special", 0);
        +			argc--; argv++;
        +			dh_file = *argv;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-dh_special") == 0) {
        +			if(argc < 2)
        +				return usage("-dh_special requires an argument", 0);
        +			if(dh_file)
        +				return usage("cannot mix -dh_file with "
        +						"-dh_special", 0);
        +			argc--; argv++;
        +			if(!parse_dh_special(*argv, &dh_special))
        +				return 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-no_tmp_rsa") == 0) {
        +			tmp_rsa = 0;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-no_ssl2") == 0) {
        +			ctx_options |= SSL_OP_NO_SSLv2;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-no_ssl3") == 0) {
        +			ctx_options |= SSL_OP_NO_SSLv3;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-no_tls1") == 0) {
        +			ctx_options |= SSL_OP_NO_TLSv1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-v_peer") == 0) {
        +			verify_mode |= SSL_VERIFY_PEER;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-v_strict") == 0) {
        +			verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-v_once") == 0) {
        +			verify_mode |= SSL_VERIFY_CLIENT_ONCE;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-v_depth") == 0) {
        +			if(argc < 2)
        +				return usage("-v_depth requires an argument", 0);
        +			argc--; argv++;
        +			if(!parse_verify_depth(*argv, &verify_depth))
        +				return 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-out_state") == 0) {
        +			out_state = 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-out_verify") == 0) {
        +			if(argc < 2)
        +				return usage("-out_verify requires an argument", 0);
        +			argc--; argv++;
        +			if(!parse_verify_level(*argv, &out_verify))
        +				return 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-out_totals") == 0) {
        +			out_totals = 1;
        +			goto next_arg;
        +		} else if(strcmp(*argv, "-out_conns") == 0) {
        +			out_conns = 1;
        +			goto next_arg;
        +		} else if((strcmp(*argv, "-h") == 0) ||
        +				(strcmp(*argv, "-help") == 0) ||
        +				(strcmp(*argv, "-?") == 0)) {
        +			fprintf(stderr, "%s\n", helpstring);
        +			return 0;
        +		} else
        +			return usage(*argv, 1);
        +	}
        +	/* Run any sanity checks we want here */
        +	if(!cert && !dcert && server_mode)
        +		fprintf(stderr, "WARNING: you are running an SSL server without "
        +				"a certificate - this may not work!\n");
        +
        +	/* Initialise network stuff */
        +	if(!ip_initialise())
        +		return err_str0("ip_initialise failed");
        +	/* Create the SSL_CTX */
        +	if((world.ssl_ctx = initialise_ssl_ctx(server_mode, engine_id,
        +			cacert, cert, key, dcert, dkey, cipher_list, dh_file,
        +			dh_special, tmp_rsa, ctx_options, out_state, out_verify,
        +			verify_mode, verify_depth)) == NULL)
        +		return err_str1("initialise_ssl_ctx(engine_id=%s) failed",
        +			(engine_id == NULL) ? "NULL" : engine_id);
        +	if(engine_id)
        +		fprintf(stderr, "Info, engine '%s' initialised\n", engine_id);
        +	/* Create the listener */
        +	if((world.listen_fd = ip_create_listener(listenhost)) == -1)
        +		return err_str1("ip_create_listener(%s) failed", listenhost);
        +	fprintf(stderr, "Info, listening on '%s'\n", listenhost);
        +	if(!ip_parse_address(proxyhost, &proxy_ip, &proxy_port, 0))
        +		return err_str1("ip_parse_address(%s) failed", proxyhost);
        +	fprintf(stderr, "Info, proxying to '%s' (%d.%d.%d.%d:%d)\n", proxyhost,
        +			(int)proxy_ip[0], (int)proxy_ip[1],
        +			(int)proxy_ip[2], (int)proxy_ip[3], (int)proxy_port);
        +	fprintf(stderr, "Info, set maxtunnels to %d\n", (int)max_tunnels);
        +	fprintf(stderr, "Info, set to operate as an SSL %s\n",
        +			(server_mode ? "server" : "client"));
        +	/* Initialise the rest of the stuff */
        +	world.tunnels_used = world.tunnels_size = 0;
        +	world.tunnels = NULL;
        +	world.server_mode = server_mode;
        +	selector_init(&world.selector);
        +
        +/* We're ready to loop */
        +main_loop:
        +	/* Should we listen for *new* tunnels? */
        +	if(world.tunnels_used < max_tunnels)
        +		selector_add_listener(&world.selector, world.listen_fd);
        +	/* We should add in our existing tunnels */
        +	for(loop = 0; loop < world.tunnels_used; loop++)
        +		selector_add_tunala(&world.selector, world.tunnels + loop);
        +	/* Now do the select */
        +	switch(selector_select(&world.selector)) {
        +	case -1:
        +		if(errno != EINTR) {
        +			fprintf(stderr, "selector_select returned a "
        +					"badness error.\n");
        +			goto shouldnt_happen;
        +		}
        +		fprintf(stderr, "Warn, selector interrupted by a signal\n");
        +		goto main_loop;
        +	case 0:
        +		fprintf(stderr, "Warn, selector_select returned 0 - signal?""?\n");
        +		goto main_loop;
        +	default:
        +		break;
        +	}
        +	/* Accept new connection if we should and can */
        +	if((world.tunnels_used < max_tunnels) && (selector_get_listener(
        +					&world.selector, world.listen_fd,
        +					&newfd) == 1)) {
        +		/* We have a new connection */
        +		if(!tunala_world_new_item(&world, newfd, proxy_ip,
        +						proxy_port, flipped))
        +			fprintf(stderr, "tunala_world_new_item failed\n");
        +		else if(out_conns)
        +			fprintf(stderr, "Info, new tunnel opened, now up to "
        +					"%d\n", world.tunnels_used);
        +	}
        +	/* Give each tunnel its moment, note the while loop is because it makes
        +	 * the logic easier than with "for" to deal with an array that may shift
        +	 * because of deletes. */
        +	loop = 0;
        +	t_item = world.tunnels;
        +	while(loop < world.tunnels_used) {
        +		if(!tunala_item_io(&world.selector, t_item)) {
        +			/* We're closing whether for reasons of an error or a
        +			 * natural close. Don't increment loop or t_item because
        +			 * the next item is moving to us! */
        +			if(!out_totals)
        +				goto skip_totals;
        +			fprintf(stderr, "Tunnel closing, traffic stats follow\n");
        +			/* Display the encrypted (over the network) stats */
        +			fprintf(stderr, io_stats_dirty,
        +				buffer_total_in(state_machine_get_buffer(
        +						&t_item->sm,SM_DIRTY_IN)),
        +				buffer_total_out(state_machine_get_buffer(
        +						&t_item->sm,SM_DIRTY_OUT)));
        +			/* Display the local (tunnelled) stats. NB: Data we
        +			 * *receive* is data sent *out* of the state_machine on
        +			 * its 'clean' side. Hence the apparent back-to-front
        +			 * OUT/IN mixup here :-) */
        +			fprintf(stderr, io_stats_clean,
        +				buffer_total_out(state_machine_get_buffer(
        +						&t_item->sm,SM_CLEAN_OUT)),
        +				buffer_total_in(state_machine_get_buffer(
        +						&t_item->sm,SM_CLEAN_IN)));
        +skip_totals:
        +			tunala_world_del_item(&world, loop);
        +			if(out_conns)
        +				fprintf(stderr, "Info, tunnel closed, down to %d\n",
        +					world.tunnels_used);
        +		}
        +		else {
        +			/* Move to the next item */
        +			loop++;
        +			t_item++;
        +		}
        +	}
        +	goto main_loop;
        +	/* Should never get here */
        +shouldnt_happen:
        +	abort();
        +	return 1;
        +}
        +
        +/****************/
        +/* OpenSSL bits */
        +/****************/
        +
        +static int ctx_set_cert(SSL_CTX *ctx, const char *cert, const char *key)
        +{
        +	FILE *fp = NULL;
        +	X509 *x509 = NULL;
        +	EVP_PKEY *pkey = NULL;
        +	int toret = 0; /* Assume an error */
        +
        +	/* cert */
        +	if(cert) {
        +		if((fp = fopen(cert, "r")) == NULL) {
        +			fprintf(stderr, "Error opening cert file '%s'\n", cert);
        +			goto err;
        +		}
        +		if(!PEM_read_X509(fp, &x509, NULL, NULL)) {
        +			fprintf(stderr, "Error reading PEM cert from '%s'\n",
        +					cert);
        +			goto err;
        +		}
        +		if(!SSL_CTX_use_certificate(ctx, x509)) {
        +			fprintf(stderr, "Error, cert in '%s' can not be used\n",
        +					cert);
        +			goto err;
        +		}
        +		/* Clear the FILE* for reuse in the "key" code */
        +		fclose(fp);
        +		fp = NULL;
        +		fprintf(stderr, "Info, operating with cert in '%s'\n", cert);
        +		/* If a cert was given without matching key, we assume the same
        +		 * file contains the required key. */
        +		if(!key)
        +			key = cert;
        +	} else {
        +		if(key)
        +			fprintf(stderr, "Error, can't specify a key without a "
        +					"corresponding certificate\n");
        +		else
        +			fprintf(stderr, "Error, ctx_set_cert called with "
        +					"NULLs!\n");
        +		goto err;
        +	}
        +	/* key */
        +	if(key) {
        +		if((fp = fopen(key, "r")) == NULL) {
        +			fprintf(stderr, "Error opening key file '%s'\n", key);
        +			goto err;
        +		}
        +		if(!PEM_read_PrivateKey(fp, &pkey, NULL, NULL)) {
        +			fprintf(stderr, "Error reading PEM key from '%s'\n",
        +					key);
        +			goto err;
        +		}
        +		if(!SSL_CTX_use_PrivateKey(ctx, pkey)) {
        +			fprintf(stderr, "Error, key in '%s' can not be used\n",
        +					key);
        +			goto err;
        +		}
        +		fprintf(stderr, "Info, operating with key in '%s'\n", key);
        +	} else
        +		fprintf(stderr, "Info, operating without a cert or key\n");
        +	/* Success */
        +	toret = 1; err:
        +	if(x509)
        +		X509_free(x509);
        +	if(pkey)
        +		EVP_PKEY_free(pkey);
        +	if(fp)
        +		fclose(fp);
        +	return toret;
        +}
        +
        +static int ctx_set_dh(SSL_CTX *ctx, const char *dh_file, const char *dh_special)
        +{
        +	DH *dh = NULL;
        +	FILE *fp = NULL;
        +
        +	if(dh_special) {
        +		if(strcmp(dh_special, "NULL") == 0)
        +			return 1;
        +		if(strcmp(dh_special, "standard") == 0) {
        +			if((dh = get_dh512()) == NULL) {
        +				fprintf(stderr, "Error, can't parse 'standard'"
        +						" DH parameters\n");
        +				return 0;
        +			}
        +			fprintf(stderr, "Info, using 'standard' DH parameters\n");
        +			goto do_it;
        +		}
        +		if(strcmp(dh_special, "generate") != 0)
        +			/* This shouldn't happen - screening values is handled
        +			 * in main(). */
        +			abort();
        +		fprintf(stderr, "Info, generating DH parameters ... ");
        +		fflush(stderr);
        +		if(!(dh = DH_new()) || !DH_generate_parameters_ex(dh, 512,
        +					DH_GENERATOR_5, NULL)) {
        +			fprintf(stderr, "error!\n");
        +			if(dh)
        +				DH_free(dh);
        +			return 0;
        +		}
        +		fprintf(stderr, "complete\n");
        +		goto do_it;
        +	}
        +	/* So, we're loading dh_file */
        +	if((fp = fopen(dh_file, "r")) == NULL) {
        +		fprintf(stderr, "Error, couldn't open '%s' for DH parameters\n",
        +				dh_file);
        +		return 0;
        +	}
        +	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
        +	fclose(fp);
        +	if(dh == NULL) {
        +		fprintf(stderr, "Error, could not parse DH parameters from '%s'\n",
        +				dh_file);
        +		return 0;
        +	}
        +	fprintf(stderr, "Info, using DH parameters from file '%s'\n", dh_file);
        +do_it:
        +	SSL_CTX_set_tmp_dh(ctx, dh);
        +	DH_free(dh);
        +	return 1;
        +}
        +
        +static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
        +		const char *CAfile, const char *cert, const char *key,
        +		const char *dcert, const char *dkey, const char *cipher_list,
        +		const char *dh_file, const char *dh_special, int tmp_rsa,
        +		int ctx_options, int out_state, int out_verify, int verify_mode,
        +		unsigned int verify_depth)
        +{
        +	SSL_CTX *ctx = NULL, *ret = NULL;
        +	const SSL_METHOD *meth;
        +	ENGINE *e = NULL;
        +
        +        OpenSSL_add_ssl_algorithms();
        +        SSL_load_error_strings();
        +
        +	meth = (server_mode ? SSLv23_server_method() : SSLv23_client_method());
        +	if(meth == NULL)
        +		goto err;
        +	if(engine_id) {
        +		ENGINE_load_builtin_engines();
        +		if((e = ENGINE_by_id(engine_id)) == NULL) {
        +			fprintf(stderr, "Error obtaining '%s' engine, openssl "
        +					"errors follow\n", engine_id);
        +			goto err;
        +		}
        +		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
        +			fprintf(stderr, "Error assigning '%s' engine, openssl "
        +					"errors follow\n", engine_id);
        +			goto err;
        +		}
        +		ENGINE_free(e);
        +	}
        +	if((ctx = SSL_CTX_new(meth)) == NULL)
        +		goto err;
        +	/* cacert */
        +	if(CAfile) {
        +		if(!X509_STORE_load_locations(SSL_CTX_get_cert_store(ctx),
        +					CAfile, NULL)) {
        +			fprintf(stderr, "Error loading CA cert(s) in '%s'\n",
        +					CAfile);
        +			goto err;
        +		}
        +		fprintf(stderr, "Info, operating with CA cert(s) in '%s'\n",
        +				CAfile);
        +	} else
        +		fprintf(stderr, "Info, operating without a CA cert(-list)\n");
        +	if(!SSL_CTX_set_default_verify_paths(ctx)) {
        +		fprintf(stderr, "Error setting default verify paths\n");
        +		goto err;
        +	}
        +
        +	/* cert and key */
        +	if((cert || key) && !ctx_set_cert(ctx, cert, key))
        +		goto err;
        +	/* dcert and dkey */
        +	if((dcert || dkey) && !ctx_set_cert(ctx, dcert, dkey))
        +		goto err;
        +	/* temporary RSA key generation */
        +	if(tmp_rsa)
        +		SSL_CTX_set_tmp_rsa_callback(ctx, cb_generate_tmp_rsa);
        +
        +	/* cipher_list */
        +	if(cipher_list) {
        +		if(!SSL_CTX_set_cipher_list(ctx, cipher_list)) {
        +			fprintf(stderr, "Error setting cipher list '%s'\n",
        +					cipher_list);
        +			goto err;
        +		}
        +		fprintf(stderr, "Info, set cipher list '%s'\n", cipher_list);
        +	} else
        +		fprintf(stderr, "Info, operating with default cipher list\n");
        +
        +	/* dh_file & dh_special */
        +	if((dh_file || dh_special) && !ctx_set_dh(ctx, dh_file, dh_special))
        +		goto err;
        +
        +	/* ctx_options */
        +	SSL_CTX_set_options(ctx, ctx_options);
        +
        +	/* out_state (output of SSL handshake states to screen). */
        +	if(out_state)
        +		cb_ssl_info_set_output(stderr);
        +
        +	/* out_verify */
        +	if(out_verify > 0) {
        +		cb_ssl_verify_set_output(stderr);
        +		cb_ssl_verify_set_level(out_verify);
        +	}
        +
        +	/* verify_depth */
        +	cb_ssl_verify_set_depth(verify_depth);
        +
        +	/* Success! (includes setting verify_mode) */
        +	SSL_CTX_set_info_callback(ctx, cb_ssl_info);
        +	SSL_CTX_set_verify(ctx, verify_mode, cb_ssl_verify);
        +	ret = ctx;
        +err:
        +	if(!ret) {
        +		ERR_print_errors_fp(stderr);
        +		if(ctx)
        +			SSL_CTX_free(ctx);
        +	}
        +	return ret;
        +}
        +
        +/*****************/
        +/* Selector bits */
        +/*****************/
        +
        +static void selector_sets_init(select_sets_t *s)
        +{
        +	s->max = 0;
        +	FD_ZERO(&s->reads);
        +	FD_ZERO(&s->sends);
        +	FD_ZERO(&s->excepts);
        +}
        +static void selector_init(tunala_selector_t *selector)
        +{
        +	selector_sets_init(&selector->last_selected);
        +	selector_sets_init(&selector->next_select);
        +}
        +
        +#define SEL_EXCEPTS 0x00
        +#define SEL_READS   0x01
        +#define SEL_SENDS   0x02
        +static void selector_add_raw_fd(tunala_selector_t *s, int fd, int flags)
        +{
        +	FD_SET(fd, &s->next_select.excepts);
        +	if(flags & SEL_READS)
        +		FD_SET(fd, &s->next_select.reads);
        +	if(flags & SEL_SENDS)
        +		FD_SET(fd, &s->next_select.sends);
        +	/* Adjust "max" */
        +	if(s->next_select.max < (fd + 1))
        +		s->next_select.max = fd + 1;
        +}
        +
        +static void selector_add_listener(tunala_selector_t *selector, int fd)
        +{
        +	selector_add_raw_fd(selector, fd, SEL_READS);
        +}
        +
        +static void selector_add_tunala(tunala_selector_t *s, tunala_item_t *t)
        +{
        +	/* Set clean read if sm.clean_in is not full */
        +	if(t->clean_read != -1) {
        +		selector_add_raw_fd(s, t->clean_read,
        +			(buffer_full(state_machine_get_buffer(&t->sm,
        +				SM_CLEAN_IN)) ? SEL_EXCEPTS : SEL_READS));
        +	}
        +	/* Set clean send if sm.clean_out is not empty */
        +	if(t->clean_send != -1) {
        +		selector_add_raw_fd(s, t->clean_send,
        +			(buffer_empty(state_machine_get_buffer(&t->sm,
        +				SM_CLEAN_OUT)) ? SEL_EXCEPTS : SEL_SENDS));
        +	}
        +	/* Set dirty read if sm.dirty_in is not full */
        +	if(t->dirty_read != -1) {
        +		selector_add_raw_fd(s, t->dirty_read,
        +			(buffer_full(state_machine_get_buffer(&t->sm,
        +				SM_DIRTY_IN)) ? SEL_EXCEPTS : SEL_READS));
        +	}
        +	/* Set dirty send if sm.dirty_out is not empty */
        +	if(t->dirty_send != -1) {
        +		selector_add_raw_fd(s, t->dirty_send,
        +			(buffer_empty(state_machine_get_buffer(&t->sm,
        +				SM_DIRTY_OUT)) ? SEL_EXCEPTS : SEL_SENDS));
        +	}
        +}
        +
        +static int selector_select(tunala_selector_t *selector)
        +{
        +	memcpy(&selector->last_selected, &selector->next_select,
        +			sizeof(select_sets_t));
        +	selector_sets_init(&selector->next_select);
        +	return select(selector->last_selected.max,
        +			&selector->last_selected.reads,
        +			&selector->last_selected.sends,
        +			&selector->last_selected.excepts, NULL);
        +}
        +
        +/* This returns -1 for error, 0 for no new connections, or 1 for success, in
        + * which case *newfd is populated. */
        +static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd)
        +{
        +	if(FD_ISSET(fd, &selector->last_selected.excepts))
        +		return -1;
        +	if(!FD_ISSET(fd, &selector->last_selected.reads))
        +		return 0;
        +	if((*newfd = ip_accept_connection(fd)) == -1)
        +		return -1;
        +	return 1;
        +}
        +
        +/************************/
        +/* "Tunala" world stuff */
        +/************************/
        +
        +static int tunala_world_make_room(tunala_world_t *world)
        +{
        +	unsigned int newsize;
        +	tunala_item_t *newarray;
        +
        +	if(world->tunnels_used < world->tunnels_size)
        +		return 1;
        +	newsize = (world->tunnels_size == 0 ? 16 :
        +			((world->tunnels_size * 3) / 2));
        +	if((newarray = malloc(newsize * sizeof(tunala_item_t))) == NULL)
        +		return 0;
        +	memset(newarray, 0, newsize * sizeof(tunala_item_t));
        +	if(world->tunnels_used > 0)
        +		memcpy(newarray, world->tunnels,
        +			world->tunnels_used * sizeof(tunala_item_t));
        +	if(world->tunnels_size > 0)
        +		free(world->tunnels);
        +	/* migrate */
        +	world->tunnels = newarray;
        +	world->tunnels_size = newsize;
        +	return 1;
        +}
        +
        +static int tunala_world_new_item(tunala_world_t *world, int fd,
        +		const char *ip, unsigned short port, int flipped)
        +{
        +	tunala_item_t *item;
        +	int newfd;
        +	SSL *new_ssl = NULL;
        +
        +	if(!tunala_world_make_room(world))
        +		return 0;
        +	if((new_ssl = SSL_new(world->ssl_ctx)) == NULL) {
        +		fprintf(stderr, "Error creating new SSL\n");
        +		ERR_print_errors_fp(stderr);
        +		return 0;
        +	}
        +	item = world->tunnels + (world->tunnels_used++);
        +	state_machine_init(&item->sm);
        +	item->clean_read = item->clean_send =
        +		item->dirty_read = item->dirty_send = -1;
        +	if((newfd = ip_create_connection_split(ip, port)) == -1)
        +		goto err;
        +	/* Which way round? If we're a server, "fd" is the dirty side and the
        +	 * connection we open is the clean one. For a client, it's the other way
        +	 * around. Unless, of course, we're "flipped" in which case everything
        +	 * gets reversed. :-) */
        +	if((world->server_mode && !flipped) ||
        +			(!world->server_mode && flipped)) {
        +		item->dirty_read = item->dirty_send = fd;
        +		item->clean_read = item->clean_send = newfd;
        +	} else {
        +		item->clean_read = item->clean_send = fd;
        +		item->dirty_read = item->dirty_send = newfd;
        +	}
        +	/* We use the SSL's "app_data" to indicate a call-back induced "kill" */
        +	SSL_set_app_data(new_ssl, NULL);
        +	if(!state_machine_set_SSL(&item->sm, new_ssl, world->server_mode))
        +		goto err;
        +	return 1;
        +err:
        +	tunala_world_del_item(world, world->tunnels_used - 1);
        +	return 0;
        +
        +}
        +
        +static void tunala_world_del_item(tunala_world_t *world, unsigned int idx)
        +{
        +	tunala_item_t *item = world->tunnels + idx;
        +	if(item->clean_read != -1)
        +		close(item->clean_read);
        +	if(item->clean_send != item->clean_read)
        +		close(item->clean_send);
        +	item->clean_read = item->clean_send = -1;
        +	if(item->dirty_read != -1)
        +		close(item->dirty_read);
        +	if(item->dirty_send != item->dirty_read)
        +		close(item->dirty_send);
        +	item->dirty_read = item->dirty_send = -1;
        +	state_machine_close(&item->sm);
        +	/* OK, now we fix the item array */
        +	if(idx + 1 < world->tunnels_used)
        +		/* We need to scroll entries to the left */
        +		memmove(world->tunnels + idx,
        +				world->tunnels + (idx + 1),
        +				(world->tunnels_used - (idx + 1)) *
        +					sizeof(tunala_item_t));
        +	world->tunnels_used--;
        +}
        +
        +static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item)
        +{
        +	int c_r, c_s, d_r, d_s; /* Four boolean flags */
        +
        +	/* Take ourselves out of the gene-pool if there was an except */
        +	if((item->clean_read != -1) && FD_ISSET(item->clean_read,
        +				&selector->last_selected.excepts))
        +		return 0;
        +	if((item->clean_send != -1) && FD_ISSET(item->clean_send,
        +				&selector->last_selected.excepts))
        +		return 0;
        +	if((item->dirty_read != -1) && FD_ISSET(item->dirty_read,
        +				&selector->last_selected.excepts))
        +		return 0;
        +	if((item->dirty_send != -1) && FD_ISSET(item->dirty_send,
        +				&selector->last_selected.excepts))
        +		return 0;
        +	/* Grab our 4 IO flags */
        +	c_r = c_s = d_r = d_s = 0;
        +	if(item->clean_read != -1)
        +		c_r = FD_ISSET(item->clean_read, &selector->last_selected.reads);
        +	if(item->clean_send != -1)
        +		c_s = FD_ISSET(item->clean_send, &selector->last_selected.sends);
        +	if(item->dirty_read != -1)
        +		d_r = FD_ISSET(item->dirty_read, &selector->last_selected.reads);
        +	if(item->dirty_send != -1)
        +		d_s = FD_ISSET(item->dirty_send, &selector->last_selected.sends);
        +	/* If no IO has happened for us, skip needless data looping */
        +	if(!c_r && !c_s && !d_r && !d_s)
        +		return 1;
        +	if(c_r)
        +		c_r = (buffer_from_fd(state_machine_get_buffer(&item->sm,
        +				SM_CLEAN_IN), item->clean_read) <= 0);
        +	if(c_s)
        +		c_s = (buffer_to_fd(state_machine_get_buffer(&item->sm,
        +				SM_CLEAN_OUT), item->clean_send) <= 0);
        +	if(d_r)
        +		d_r = (buffer_from_fd(state_machine_get_buffer(&item->sm,
        +				SM_DIRTY_IN), item->dirty_read) <= 0);
        +	if(d_s)
        +		d_s = (buffer_to_fd(state_machine_get_buffer(&item->sm,
        +				SM_DIRTY_OUT), item->dirty_send) <= 0);
        +	/* If any of the flags is non-zero, that means they need closing */
        +	if(c_r) {
        +		close(item->clean_read);
        +		if(item->clean_send == item->clean_read)
        +			item->clean_send = -1;
        +		item->clean_read = -1;
        +	}
        +	if(c_s && (item->clean_send != -1)) {
        +		close(item->clean_send);
        +		if(item->clean_send == item->clean_read)
        +			item->clean_read = -1;
        +		item->clean_send = -1;
        +	}
        +	if(d_r) {
        +		close(item->dirty_read);
        +		if(item->dirty_send == item->dirty_read)
        +			item->dirty_send = -1;
        +		item->dirty_read = -1;
        +	}
        +	if(d_s && (item->dirty_send != -1)) {
        +		close(item->dirty_send);
        +		if(item->dirty_send == item->dirty_read)
        +			item->dirty_read = -1;
        +		item->dirty_send = -1;
        +	}
        +	/* This function name is attributed to the term donated by David
        +	 * Schwartz on openssl-dev, message-ID:
        +	 * <NCBBLIEPOCNJOAEKBEAKEEDGLIAA.davids@webmaster.com>. :-) */
        +	if(!state_machine_churn(&item->sm))
        +		/* If the SSL closes, it will also zero-out the _in buffers
        +		 * and will in future process just outgoing data. As and
        +		 * when the outgoing data has gone, it will return zero
        +		 * here to tell us to bail out. */
        +		return 0;
        +	/* Otherwise, we return zero if both sides are dead. */
        +	if(((item->clean_read == -1) || (item->clean_send == -1)) &&
        +			((item->dirty_read == -1) || (item->dirty_send == -1)))
        +		return 0;
        +	/* If only one side closed, notify the SSL of this so it can take
        +	 * appropriate action. */
        +	if((item->clean_read == -1) || (item->clean_send == -1)) {
        +		if(!state_machine_close_clean(&item->sm))
        +			return 0;
        +	}
        +	if((item->dirty_read == -1) || (item->dirty_send == -1)) {
        +		if(!state_machine_close_dirty(&item->sm))
        +			return 0;
        +	}
        +	return 1;
        +}
        +
        diff --git a/vendor/openssl/openssl/demos/tunala/tunala.h b/vendor/openssl/openssl/demos/tunala/tunala.h
        new file mode 100644
        index 000000000..3a752f259
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/tunala/tunala.h
        @@ -0,0 +1,215 @@
        +/* Tunala ("Tunneler with a New Zealand accent")
        + *
        + * Written by Geoff Thorpe, but endorsed/supported by noone. Please use this is
        + * if it's useful or informative to you, but it's only here as a scratchpad for
        + * ideas about how you might (or might not) program with OpenSSL. If you deploy
        + * this is in a mission-critical environment, and have not read, understood,
        + * audited, and modified this code to your satisfaction, and the result is that
        + * all hell breaks loose and you are looking for a new employer, then it proves
        + * nothing except perhaps that Darwinism is alive and well. Let's just say, *I*
        + * don't use this in a mission-critical environment, so it would be stupid for
        + * anyone to assume that it is solid and/or tested enough when even its author
        + * doesn't place that much trust in it. You have been warned.
        + *
        + * With thanks to Cryptographic Appliances, Inc.
        + */
        +
        +#ifndef _TUNALA_H
        +#define _TUNALA_H
        +
        +/* pull in autoconf fluff */
        +#ifndef NO_CONFIG_H
        +#include "config.h"
        +#else
        +/* We don't have autoconf, we have to set all of these unless a tweaked Makefile
        + * tells us not to ... */
        +/* headers */
        +#ifndef NO_HAVE_SELECT
        +#define HAVE_SELECT
        +#endif
        +#ifndef NO_HAVE_SOCKET
        +#define HAVE_SOCKET
        +#endif
        +#ifndef NO_HAVE_UNISTD_H
        +#define HAVE_UNISTD_H
        +#endif
        +#ifndef NO_HAVE_FCNTL_H
        +#define HAVE_FCNTL_H
        +#endif
        +#ifndef NO_HAVE_LIMITS_H
        +#define HAVE_LIMITS_H
        +#endif
        +/* features */
        +#ifndef NO_HAVE_STRSTR
        +#define HAVE_STRSTR
        +#endif
        +#ifndef NO_HAVE_STRTOUL
        +#define HAVE_STRTOUL
        +#endif
        +#endif
        +
        +#if !defined(HAVE_SELECT) || !defined(HAVE_SOCKET)
        +#error "can't build without some network basics like select() and socket()"
        +#endif
        +
        +#include <stdlib.h>
        +#ifndef NO_SYSTEM_H
        +#include <string.h>
        +#ifdef HAVE_UNISTD_H
        +#include <unistd.h>
        +#endif
        +#ifdef HAVE_FCNTL_H
        +#include <fcntl.h>
        +#endif
        +#ifdef HAVE_LIMITS_H
        +#include <limits.h>
        +#endif
        +#include <netdb.h>
        +#include <signal.h>
        +#include <sys/socket.h>
        +#include <sys/types.h>
        +#include <netinet/in.h>
        +#endif /* !defined(NO_SYSTEM_H) */
        +
        +#ifndef NO_OPENSSL
        +#include <openssl/err.h>
        +#include <openssl/engine.h>
        +#include <openssl/ssl.h>
        +#endif /* !defined(NO_OPENSSL) */
        +
        +#ifndef OPENSSL_NO_BUFFER
        +/* This is the generic "buffer" type that is used when feeding the
        + * state-machine. It's basically a FIFO with respect to the "adddata" &
        + * "takedata" type functions that operate on it. */
        +#define MAX_DATA_SIZE 16384
        +typedef struct _buffer_t {
        +	unsigned char data[MAX_DATA_SIZE];
        +	unsigned int used;
        +	/* Statistical values - counts the total number of bytes read in and
        +	 * read out (respectively) since "buffer_init()" */
        +	unsigned long total_in, total_out;
        +} buffer_t;
        +
        +/* Initialise a buffer structure before use */
        +void buffer_init(buffer_t *buf);
        +/* Cleanup a buffer structure - presently not needed, but if buffer_t is
        + * converted to using dynamic allocation, this would be required - so should be
        + * called to protect against an explosion of memory leaks later if the change is
        + * made. */
        +void buffer_close(buffer_t *buf);
        +
        +/* Basic functions to manipulate buffers */
        +
        +unsigned int buffer_used(buffer_t *buf); /* How much data in the buffer */
        +unsigned int buffer_unused(buffer_t *buf); /* How much space in the buffer */
        +int buffer_full(buffer_t *buf); /* Boolean, is it full? */
        +int buffer_notfull(buffer_t *buf); /* Boolean, is it not full? */
        +int buffer_empty(buffer_t *buf); /* Boolean, is it empty? */
        +int buffer_notempty(buffer_t *buf); /* Boolean, is it not empty? */
        +unsigned long buffer_total_in(buffer_t *buf); /* Total bytes written to buffer */
        +unsigned long buffer_total_out(buffer_t *buf); /* Total bytes read from buffer */
        +
        +#if 0 /* Currently used only within buffer.c - better to expose only
        +       * higher-level functions anyway */
        +/* Add data to the tail of the buffer, returns the amount that was actually
        + * added (so, you need to check if return value is less than size) */
        +unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr,
        +		unsigned int size);
        +
        +/* Take data from the front of the buffer (and scroll the rest forward). If
        + * "ptr" is NULL, this just removes data off the front of the buffer. Return
        + * value is the amount actually removed (can be less than size if the buffer has
        + * too little data). */
        +unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr,
        +		unsigned int size);
        +
        +/* Flushes as much data as possible out of the "from" buffer into the "to"
        + * buffer. Return value is the amount moved. The amount moved can be restricted
        + * to a maximum by specifying "cap" - setting it to -1 means no limit. */
        +unsigned int buffer_tobuffer(buffer_t *to, buffer_t *from, int cap);
        +#endif
        +
        +#ifndef NO_IP
        +/* Read or write between a file-descriptor and a buffer */
        +int buffer_from_fd(buffer_t *buf, int fd);
        +int buffer_to_fd(buffer_t *buf, int fd);
        +#endif /* !defined(NO_IP) */
        +
        +#ifndef NO_OPENSSL
        +/* Read or write between an SSL or BIO and a buffer */
        +void buffer_from_SSL(buffer_t *buf, SSL *ssl);
        +void buffer_to_SSL(buffer_t *buf, SSL *ssl);
        +void buffer_from_BIO(buffer_t *buf, BIO *bio);
        +void buffer_to_BIO(buffer_t *buf, BIO *bio);
        +
        +/* Callbacks */
        +void cb_ssl_info(const SSL *s, int where, int ret);
        +void cb_ssl_info_set_output(FILE *fp); /* Called if output should be sent too */
        +int cb_ssl_verify(int ok, X509_STORE_CTX *ctx);
        +void cb_ssl_verify_set_output(FILE *fp);
        +void cb_ssl_verify_set_depth(unsigned int verify_depth);
        +void cb_ssl_verify_set_level(unsigned int level);
        +RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength);
        +#endif /* !defined(NO_OPENSSL) */
        +#endif /* !defined(OPENSSL_NO_BUFFER) */
        +
        +#ifndef NO_TUNALA
        +#ifdef OPENSSL_NO_BUFFER
        +#error "TUNALA section of tunala.h requires BUFFER support"
        +#endif
        +typedef struct _state_machine_t {
        +	SSL *ssl;
        +	BIO *bio_intossl;
        +	BIO *bio_fromssl;
        +	buffer_t clean_in, clean_out;
        +	buffer_t dirty_in, dirty_out;
        +} state_machine_t;
        +typedef enum {
        +	SM_CLEAN_IN, SM_CLEAN_OUT,
        +	SM_DIRTY_IN, SM_DIRTY_OUT
        +} sm_buffer_t;
        +void state_machine_init(state_machine_t *machine);
        +void state_machine_close(state_machine_t *machine);
        +buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type);
        +SSL *state_machine_get_SSL(state_machine_t *machine);
        +int state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server);
        +/* Performs the data-IO loop and returns zero if the machine should close */
        +int state_machine_churn(state_machine_t *machine);
        +/* Is used to handle closing conditions - namely when one side of the tunnel has
        + * closed but the other should finish flushing. */
        +int state_machine_close_clean(state_machine_t *machine);
        +int state_machine_close_dirty(state_machine_t *machine);
        +#endif /* !defined(NO_TUNALA) */
        +
        +#ifndef NO_IP
        +/* Initialise anything related to the networking. This includes blocking pesky
        + * SIGPIPE signals. */
        +int ip_initialise(void);
        +/* ip is the 4-byte ip address (eg. 127.0.0.1 is {0x7F,0x00,0x00,0x01}), port is
        + * the port to listen on (host byte order), and the return value is the
        + * file-descriptor or -1 on error. */
        +int ip_create_listener_split(const char *ip, unsigned short port);
        +/* Same semantics as above. */
        +int ip_create_connection_split(const char *ip, unsigned short port);
        +/* Converts a string into the ip/port before calling the above */
        +int ip_create_listener(const char *address);
        +int ip_create_connection(const char *address);
        +/* Just does a string conversion on its own. NB: If accept_all_ip is non-zero,
        + * then the address string could be just a port. Ie. it's suitable for a
        + * listening address but not a connecting address. */
        +int ip_parse_address(const char *address, const char **parsed_ip,
        +		unsigned short *port, int accept_all_ip);
        +/* Accepts an incoming connection through the listener. Assumes selects and
        + * what-not have deemed it an appropriate thing to do. */
        +int ip_accept_connection(int listen_fd);
        +#endif /* !defined(NO_IP) */
        +
        +/* These functions wrap up things that can be portability hassles. */
        +int int_strtoul(const char *str, unsigned long *val);
        +#ifdef HAVE_STRSTR
        +#define int_strstr strstr
        +#else
        +char *int_strstr(const char *haystack, const char *needle);
        +#endif
        +
        +#endif /* !defined(_TUNALA_H) */
        diff --git a/vendor/openssl/openssl/demos/x509/README b/vendor/openssl/openssl/demos/x509/README
        new file mode 100644
        index 000000000..88f9d6c46
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/x509/README
        @@ -0,0 +1,3 @@
        +This directory contains examples of how to contruct
        +various X509 structures. Certificates, certificate requests
        +and CRLs.
        diff --git a/vendor/openssl/openssl/demos/x509/mkcert.c b/vendor/openssl/openssl/demos/x509/mkcert.c
        new file mode 100644
        index 000000000..6a52e5d0f
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/x509/mkcert.c
        @@ -0,0 +1,172 @@
        +/* Certificate creation. Demonstrates some certificate related
        + * operations.
        + */
        +
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include <openssl/pem.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
        +int add_ext(X509 *cert, int nid, char *value);
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *bio_err;
        +	X509 *x509=NULL;
        +	EVP_PKEY *pkey=NULL;
        +
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	mkcert(&x509,&pkey,512,0,365);
        +
        +	RSA_print_fp(stdout,pkey->pkey.rsa,0);
        +	X509_print_fp(stdout,x509);
        +
        +	PEM_write_PrivateKey(stdout,pkey,NULL,NULL,0,NULL, NULL);
        +	PEM_write_X509(stdout,x509);
        +
        +	X509_free(x509);
        +	EVP_PKEY_free(pkey);
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_cleanup();
        +#endif
        +	CRYPTO_cleanup_all_ex_data();
        +
        +	CRYPTO_mem_leaks(bio_err);
        +	BIO_free(bio_err);
        +	return(0);
        +	}
        +
        +static void callback(int p, int n, void *arg)
        +	{
        +	char c='B';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	fputc(c,stderr);
        +	}
        +
        +int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
        +	{
        +	X509 *x;
        +	EVP_PKEY *pk;
        +	RSA *rsa;
        +	X509_NAME *name=NULL;
        +	
        +	if ((pkeyp == NULL) || (*pkeyp == NULL))
        +		{
        +		if ((pk=EVP_PKEY_new()) == NULL)
        +			{
        +			abort(); 
        +			return(0);
        +			}
        +		}
        +	else
        +		pk= *pkeyp;
        +
        +	if ((x509p == NULL) || (*x509p == NULL))
        +		{
        +		if ((x=X509_new()) == NULL)
        +			goto err;
        +		}
        +	else
        +		x= *x509p;
        +
        +	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
        +	if (!EVP_PKEY_assign_RSA(pk,rsa))
        +		{
        +		abort();
        +		goto err;
        +		}
        +	rsa=NULL;
        +
        +	X509_set_version(x,2);
        +	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
        +	X509_gmtime_adj(X509_get_notBefore(x),0);
        +	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
        +	X509_set_pubkey(x,pk);
        +
        +	name=X509_get_subject_name(x);
        +
        +	/* This function creates and adds the entry, working out the
        +	 * correct string type and performing checks on its length.
        +	 * Normally we'd check the return value for errors...
        +	 */
        +	X509_NAME_add_entry_by_txt(name,"C",
        +				MBSTRING_ASC, "UK", -1, -1, 0);
        +	X509_NAME_add_entry_by_txt(name,"CN",
        +				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
        +
        +	/* Its self signed so set the issuer name to be the same as the
        + 	 * subject.
        +	 */
        +	X509_set_issuer_name(x,name);
        +
        +	/* Add various extensions: standard extensions */
        +	add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
        +	add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");
        +
        +	add_ext(x, NID_subject_key_identifier, "hash");
        +
        +	/* Some Netscape specific extensions */
        +	add_ext(x, NID_netscape_cert_type, "sslCA");
        +
        +	add_ext(x, NID_netscape_comment, "example comment extension");
        +
        +
        +#ifdef CUSTOM_EXT
        +	/* Maybe even add our own extension based on existing */
        +	{
        +		int nid;
        +		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
        +		X509V3_EXT_add_alias(nid, NID_netscape_comment);
        +		add_ext(x, nid, "example comment alias");
        +	}
        +#endif
        +	
        +	if (!X509_sign(x,pk,EVP_sha1()))
        +		goto err;
        +
        +	*x509p=x;
        +	*pkeyp=pk;
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +/* Add extension using V3 code: we can set the config file as NULL
        + * because we wont reference any other sections.
        + */
        +
        +int add_ext(X509 *cert, int nid, char *value)
        +	{
        +	X509_EXTENSION *ex;
        +	X509V3_CTX ctx;
        +	/* This sets the 'context' of the extensions. */
        +	/* No configuration database */
        +	X509V3_set_ctx_nodb(&ctx);
        +	/* Issuer and subject certs: both the target since it is self signed,
        +	 * no request and no CRL
        +	 */
        +	X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
        +	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
        +	if (!ex)
        +		return 0;
        +
        +	X509_add_ext(cert,ex,-1);
        +	X509_EXTENSION_free(ex);
        +	return 1;
        +	}
        +	
        diff --git a/vendor/openssl/openssl/demos/x509/mkreq.c b/vendor/openssl/openssl/demos/x509/mkreq.c
        new file mode 100644
        index 000000000..d17e4ade9
        --- /dev/null
        +++ b/vendor/openssl/openssl/demos/x509/mkreq.c
        @@ -0,0 +1,161 @@
        +/* Certificate request creation. Demonstrates some request related
        + * operations.
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include <openssl/pem.h>
        +#include <openssl/conf.h>
        +#include <openssl/x509v3.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +int mkreq(X509_REQ **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days);
        +int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value);
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *bio_err;
        +	X509_REQ *req=NULL;
        +	EVP_PKEY *pkey=NULL;
        +
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	mkreq(&req,&pkey,512,0,365);
        +
        +	RSA_print_fp(stdout,pkey->pkey.rsa,0);
        +	X509_REQ_print_fp(stdout,req);
        +
        +	PEM_write_X509_REQ(stdout,req);
        +
        +	X509_REQ_free(req);
        +	EVP_PKEY_free(pkey);
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_cleanup();
        +#endif
        +	CRYPTO_cleanup_all_ex_data();
        +
        +	CRYPTO_mem_leaks(bio_err);
        +	BIO_free(bio_err);
        +	return(0);
        +	}
        +
        +static void callback(int p, int n, void *arg)
        +	{
        +	char c='B';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	fputc(c,stderr);
        +	}
        +
        +int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
        +	{
        +	X509_REQ *x;
        +	EVP_PKEY *pk;
        +	RSA *rsa;
        +	X509_NAME *name=NULL;
        +	STACK_OF(X509_EXTENSION) *exts = NULL;
        +	
        +	if ((pk=EVP_PKEY_new()) == NULL)
        +		goto err;
        +
        +	if ((x=X509_REQ_new()) == NULL)
        +		goto err;
        +
        +	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
        +	if (!EVP_PKEY_assign_RSA(pk,rsa))
        +		goto err;
        +
        +	rsa=NULL;
        +
        +	X509_REQ_set_pubkey(x,pk);
        +
        +	name=X509_REQ_get_subject_name(x);
        +
        +	/* This function creates and adds the entry, working out the
        +	 * correct string type and performing checks on its length.
        +	 * Normally we'd check the return value for errors...
        +	 */
        +	X509_NAME_add_entry_by_txt(name,"C",
        +				MBSTRING_ASC, "UK", -1, -1, 0);
        +	X509_NAME_add_entry_by_txt(name,"CN",
        +				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);
        +
        +#ifdef REQUEST_EXTENSIONS
        +	/* Certificate requests can contain extensions, which can be used
        +	 * to indicate the extensions the requestor would like added to 
        +	 * their certificate. CAs might ignore them however or even choke
        +	 * if they are present.
        +	 */
        +
        +	/* For request extensions they are all packed in a single attribute.
        +	 * We save them in a STACK and add them all at once later...
        +	 */
        +
        +	exts = sk_X509_EXTENSION_new_null();
        +	/* Standard extenions */
        +
        +	add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment");
        +
        +	/* This is a typical use for request extensions: requesting a value for
        +	 * subject alternative name.
        +	 */
        +
        +	add_ext(exts, NID_subject_alt_name, "email:steve@openssl.org");
        +
        +	/* Some Netscape specific extensions */
        +	add_ext(exts, NID_netscape_cert_type, "client,email");
        +
        +
        +
        +#ifdef CUSTOM_EXT
        +	/* Maybe even add our own extension based on existing */
        +	{
        +		int nid;
        +		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
        +		X509V3_EXT_add_alias(nid, NID_netscape_comment);
        +		add_ext(x, nid, "example comment alias");
        +	}
        +#endif
        +
        +	/* Now we've created the extensions we add them to the request */
        +
        +	X509_REQ_add_extensions(x, exts);
        +
        +	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        +
        +#endif
        +	
        +	if (!X509_REQ_sign(x,pk,EVP_sha1()))
        +		goto err;
        +
        +	*req=x;
        +	*pkeyp=pk;
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +/* Add extension using V3 code: we can set the config file as NULL
        + * because we wont reference any other sections.
        + */
        +
        +int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value)
        +	{
        +	X509_EXTENSION *ex;
        +	ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
        +	if (!ex)
        +		return 0;
        +	sk_X509_EXTENSION_push(sk, ex);
        +
        +	return 1;
        +	}
        +	
        diff --git a/vendor/openssl/openssl/doc/HOWTO/certificates.txt b/vendor/openssl/openssl/doc/HOWTO/certificates.txt
        new file mode 100644
        index 000000000..a8a34c7ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/HOWTO/certificates.txt
        @@ -0,0 +1,105 @@
        +<DRAFT!>
        +			HOWTO certificates
        +
        +1. Introduction
        +
        +How you handle certificates depend a great deal on what your role is.
        +Your role can be one or several of:
        +
        +  - User of some client software
        +  - User of some server software
        +  - Certificate authority
        +
        +This file is for users who wish to get a certificate of their own.
        +Certificate authorities should read ca.txt.
        +
        +In all the cases shown below, the standard configuration file, as
        +compiled into openssl, will be used.  You may find it in /etc/,
        +/usr/local/ssl/ or somewhere else.  The name is openssl.cnf, and
        +is better described in another HOWTO <config.txt?>.  If you want to
        +use a different configuration file, use the argument '-config {file}'
        +with the command shown below.
        +
        +
        +2. Relationship with keys
        +
        +Certificates are related to public key cryptography by containing a
        +public key.  To be useful, there must be a corresponding private key
        +somewhere.  With OpenSSL, public keys are easily derived from private
        +keys, so before you create a certificate or a certificate request, you
        +need to create a private key.
        +
        +Private keys are generated with 'openssl genrsa' if you want a RSA
        +private key, or 'openssl gendsa' if you want a DSA private key.
        +Further information on how to create private keys can be found in
        +another HOWTO <keys.txt?>.  The rest of this text assumes you have
        +a private key in the file privkey.pem.
        +
        +
        +3. Creating a certificate request
        +
        +To create a certificate, you need to start with a certificate
        +request (or, as some certificate authorities like to put
        +it, "certificate signing request", since that's exactly what they do,
        +they sign it and give you the result back, thus making it authentic
        +according to their policies).  A certificate request can then be sent
        +to a certificate authority to get it signed into a certificate, or if
        +you have your own certificate authority, you may sign it yourself, or
        +if you need a self-signed certificate (because you just want a test
        +certificate or because you are setting up your own CA).
        +
        +The certificate request is created like this:
        +
        +  openssl req -new -key privkey.pem -out cert.csr
        +
        +Now, cert.csr can be sent to the certificate authority, if they can
        +handle files in PEM format.  If not, use the extra argument '-outform'
        +followed by the keyword for the format to use (see another HOWTO
        +<formats.txt?>).  In some cases, that isn't sufficient and you will
        +have to be more creative.
        +
        +When the certificate authority has then done the checks the need to
        +do (and probably gotten payment from you), they will hand over your
        +new certificate to you.
        +
        +Section 5 will tell you more on how to handle the certificate you
        +received.
        +
        +
        +4. Creating a self-signed test certificate
        +
        +If you don't want to deal with another certificate authority, or just
        +want to create a test certificate for yourself.  This is similar to
        +creating a certificate request, but creates a certificate instead of
        +a certificate request.  This is NOT the recommended way to create a
        +CA certificate, see ca.txt.
        +
        +  openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
        +
        +
        +5. What to do with the certificate
        +
        +If you created everything yourself, or if the certificate authority
        +was kind enough, your certificate is a raw DER thing in PEM format.
        +Your key most definitely is if you have followed the examples above.
        +However, some (most?) certificate authorities will encode them with
        +things like PKCS7 or PKCS12, or something else.  Depending on your
        +applications, this may be perfectly OK, it all depends on what they
        +know how to decode.  If not, There are a number of OpenSSL tools to
        +convert between some (most?) formats.
        +
        +So, depending on your application, you may have to convert your
        +certificate and your key to various formats, most often also putting
        +them together into one file.  The ways to do this is described in
        +another HOWTO <formats.txt?>, I will just mention the simplest case.
        +In the case of a raw DER thing in PEM format, and assuming that's all
        +right for yor applications, simply concatenating the certificate and
        +the key into a new file and using that one should be enough.  With
        +some applications, you don't even have to do that.
        +
        +
        +By now, you have your cetificate and your private key and can start
        +using the software that depend on it.
        +
        +-- 
        +Richard Levitte
        diff --git a/vendor/openssl/openssl/doc/HOWTO/keys.txt b/vendor/openssl/openssl/doc/HOWTO/keys.txt
        new file mode 100644
        index 000000000..7ae2a3a11
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/HOWTO/keys.txt
        @@ -0,0 +1,73 @@
        +<DRAFT!>
        +			HOWTO keys
        +
        +1. Introduction
        +
        +Keys are the basis of public key algorithms and PKI.  Keys usually
        +come in pairs, with one half being the public key and the other half
        +being the private key.  With OpenSSL, the private key contains the
        +public key information as well, so a public key doesn't need to be
        +generated separately.
        +
        +Public keys come in several flavors, using different cryptographic
        +algorithms.  The most popular ones associated with certificates are
        +RSA and DSA, and this HOWTO will show how to generate each of them.
        +
        +
        +2. To generate a RSA key
        +
        +A RSA key can be used both for encryption and for signing.
        +
        +Generating a key for the RSA algorithm is quite easy, all you have to
        +do is the following:
        +
        +  openssl genrsa -des3 -out privkey.pem 2048
        +
        +With this variant, you will be prompted for a protecting password.  If
        +you don't want your key to be protected by a password, remove the flag
        +'-des3' from the command line above.
        +
        +    NOTE: if you intend to use the key together with a server
        +    certificate, it may be a good thing to avoid protecting it
        +    with a password, since that would mean someone would have to
        +    type in the password every time the server needs to access
        +    the key.
        +
        +The number 2048 is the size of the key, in bits.  Today, 2048 or
        +higher is recommended for RSA keys, as fewer amount of bits is
        +consider insecure or to be insecure pretty soon.
        +
        +
        +3. To generate a DSA key
        +
        +A DSA key can be used for signing only.  This is important to keep
        +in mind to know what kind of purposes a certificate request with a
        +DSA key can really be used for.
        +
        +Generating a key for the DSA algorithm is a two-step process.  First,
        +you have to generate parameters from which to generate the key:
        +
        +  openssl dsaparam -out dsaparam.pem 2048
        +
        +The number 2048 is the size of the key, in bits.  Today, 2048 or
        +higher is recommended for DSA keys, as fewer amount of bits is
        +consider insecure or to be insecure pretty soon.
        +
        +When that is done, you can generate a key using the parameters in
        +question (actually, several keys can be generated from the same
        +parameters):
        +
        +  openssl gendsa -des3 -out privkey.pem dsaparam.pem
        +
        +With this variant, you will be prompted for a protecting password.  If
        +you don't want your key to be protected by a password, remove the flag
        +'-des3' from the command line above.
        +
        +    NOTE: if you intend to use the key together with a server
        +    certificate, it may be a good thing to avoid protecting it
        +    with a password, since that would mean someone would have to
        +    type in the password every time the server needs to access
        +    the key.
        +
        +-- 
        +Richard Levitte
        diff --git a/vendor/openssl/openssl/doc/HOWTO/proxy_certificates.txt b/vendor/openssl/openssl/doc/HOWTO/proxy_certificates.txt
        new file mode 100644
        index 000000000..f98ec3607
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/HOWTO/proxy_certificates.txt
        @@ -0,0 +1,322 @@
        +<DRAFT!>
        +			HOWTO proxy certificates
        +
        +0. WARNING
        +
        +NONE OF THE CODE PRESENTED HERE HAVE BEEN CHECKED!  They are just an
        +example to show you how things can be done.  There may be typos or
        +type conflicts, and you will have to resolve them.
        +
        +1. Introduction
        +
        +Proxy certificates are defined in RFC 3820.  They are really usual
        +certificates with the mandatory extension proxyCertInfo.
        +
        +Proxy certificates are issued by an End Entity (typically a user),
        +either directly with the EE certificate as issuing certificate, or by
        +extension through an already issued proxy certificate..  They are used
        +to extend rights to some other entity (a computer process, typically,
        +or sometimes to the user itself), so it can perform operations in the
        +name of the owner of the EE certificate.
        +
        +See http://www.ietf.org/rfc/rfc3820.txt for more information.
        +
        +
        +2. A warning about proxy certificates
        +
        +Noone seems to have tested proxy certificates with security in mind.
        +Basically, to this date, it seems that proxy certificates have only
        +been used in a world that's highly aware of them.  What would happen
        +if an unsuspecting application is to validate a chain of certificates
        +that contains proxy certificates?  It would usually consider the leaf
        +to be the certificate to check for authorisation data, and since proxy
        +certificates are controlled by the EE certificate owner alone, it's
        +would be normal to consider what the EE certificate owner could do
        +with them.
        +
        +subjectAltName and issuerAltName are forbidden in proxy certificates,
        +and this is enforced in OpenSSL.  The subject must be the same as the
        +issuer, with one commonName added on.
        +
        +Possible threats are, as far as has been imagined so far:
        +
        + - impersonation through commonName (think server certificates).
        + - use of additional extensions, possibly non-standard ones used in
        +   certain environments, that would grant extra or different
        +   authorisation rights.
        +
        +For this reason, OpenSSL requires that the use of proxy certificates
        +be explicitely allowed.  Currently, this can be done using the
        +following methods:
        +
        + - if the application calls X509_verify_cert() itself, it can do the
        +   following prior to that call (ctx is the pointer passed in the call
        +   to X509_verify_cert()):
        +
        +	X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
        +
        + - in all other cases, proxy certificate validation can be enabled
        +   before starting the application by setting the envirnoment variable
        +   OPENSSL_ALLOW_PROXY_CERTS with some non-empty value.
        +
        +There are thoughts to allow proxy certificates with a line in the
        +default openssl.cnf, but that's still in the future.
        +
        +
        +3. How to create proxy cerificates
        +
        +It's quite easy to create proxy certificates, by taking advantage of
        +the lack of checks of the 'openssl x509' application (*ahem*).  But
        +first, you need to create a configuration section that contains a
        +definition of the proxyCertInfo extension, a little like this:
        +
        +  [ v3_proxy ]
        +  # A proxy certificate MUST NEVER be a CA certificate.
        +  basicConstraints=CA:FALSE
        +
        +  # Usual authority key ID
        +  authorityKeyIdentifier=keyid,issuer:always
        +
        +  # Now, for the extension that marks this certificate as a proxy one
        +  proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
        +
        +It's also possible to give the proxy extension in a separate section:
        +
        +  proxyCertInfo=critical,@proxy_ext
        +
        +  [ proxy_ext ]
        +  language=id-ppl-anyLanguage
        +  pathlen=0
        +  policy=text:BC
        +
        +The policy value has a specific syntax, {syntag}:{string}, where the
        +syntag determines what will be done with the string.  The recognised
        +syntags are as follows:
        +
        +  text	indicates that the string is simply the bytes, not
        +	encoded in any kind of way:
        +
        +		policy=text:räksmörgås
        +
        +	Previous versions of this design had a specific tag
        +	for UTF-8 text.  However, since the bytes are copied
        +	as-is anyway, there's no need for it.  Instead, use
        +	the text: tag, like this:
        +
        +		policy=text:räksmörgås
        +
        +  hex	indicates the string is encoded in hex, with colons
        +	between each byte (every second hex digit):
        +
        +		policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73
        +
        +	Previous versions of this design had a tag to insert a
        +	complete DER blob.  However, the only legal use for
        +	this would be to surround the bytes that would go with
        +	the hex: tag with what's needed to construct a correct
        +	OCTET STRING.  Since hex: does that, the DER tag felt
        +	superfluous, and was therefore removed.
        +
        +  file	indicates that the text of the policy should really be
        +	taken from a file.  The string is then really a file
        +	name.  This is useful for policies that are large
        +	(more than a few of lines) XML documents, for example.
        +
        +The 'policy' setting can be split up in multiple lines like this:
        +
        +  0.policy=This is
        +  1.polisy= a multi-
        +  2.policy=line policy.
        +
        +NOTE: the proxy policy value is the part that determines the rights
        +granted to the process using the proxy certificate.  The value is
        +completely dependent on the application reading and interpretting it!
        +
        +Now that you have created an extension section for your proxy
        +certificate, you can now easily create a proxy certificate like this:
        +
        +  openssl req -new -config openssl.cnf \
        +	  -out proxy.req -keyout proxy.key
        +  openssl x509 -req -CAcreateserial -in proxy.req -days 7 \
        +	  -out proxy.crt -CA user.crt -CAkey user.key \
        +	  -extfile openssl.cnf -extensions v3_proxy
        +
        +It's just as easy to create a proxy certificate using another proxy
        +certificate as issuer (note that I'm using a different configuration
        +section for it):
        +
        +  openssl req -new -config openssl.cnf \
        +	  -out proxy2.req -keyout proxy2.key
        +  openssl x509 -req -CAcreateserial -in proxy2.req -days 7 \
        +	  -out proxy2.crt -CA proxy.crt -CAkey proxy.key \
        +	  -extfile openssl.cnf -extensions v3_proxy2
        +
        +
        +4. How to have your application interpret the policy?
        +
        +The basic way to interpret proxy policies is to prepare some default
        +rights, then do a check of the proxy certificate against the a chain
        +of proxy certificates, user certificate and CA certificates, and see
        +what rights came out by the end.  Sounds easy, huh?  It almost is.
        +
        +The slightly complicated part is how to pass data between your
        +application and the certificate validation procedure.
        +
        +You need the following ingredients:
        +
        + - a callback routing that will be called for every certificate that's
        +   validated.  It will be called several times for each certificates,
        +   so you must be attentive to when it's a good time to do the proxy
        +   policy interpretation and check, as well as to fill in the defaults
        +   when the EE certificate is checked.
        +
        + - a structure of data that's shared between your application code and
        +   the callback.
        +
        + - a wrapper function that sets it all up.
        +
        + - an ex_data index function that creates an index into the generic
        +   ex_data store that's attached to an X509 validation context.
        +
        +This is some cookbook code for you to fill in:
        +
        +  /* In this example, I will use a view of granted rights as a bit
        +     array, one bit for each possible right.  */
        +  typedef struct your_rights {
        +    unsigned char rights[total_rights / 8];
        +  } YOUR_RIGHTS;
        +
        +  /* The following procedure will create an index for the ex_data
        +     store in the X509 validation context the first time it's called.
        +     Subsequent calls will return the same index.  */
        +  static int get_proxy_auth_ex_data_idx(void)
        +  {
        +    static volatile int idx = -1;
        +    if (idx < 0)
        +      {
        +        CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
        +        if (idx < 0)
        +          {
        +            idx = X509_STORE_CTX_get_ex_new_index(0,
        +                                                  "for verify callback",
        +                                                  NULL,NULL,NULL);
        +          }
        +        CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
        +      }
        +    return idx;
        +  }
        +
        +  /* Callback to be given to the X509 validation procedure.  */
        +  static int verify_callback(int ok, X509_STORE_CTX *ctx)
        +  {
        +    if (ok == 1) /* It's REALLY important you keep the proxy policy
        +                    check within this secion.  It's important to know
        +                    that when ok is 1, the certificates are checked
        +                    from top to bottom.  You get the CA root first,
        +                    followed by the possible chain of intermediate
        +                    CAs, followed by the EE certificate, followed by
        +                    the possible proxy certificates.  */
        +      {
        +        X509 *xs = ctx->current_cert;
        +
        +        if (xs->ex_flags & EXFLAG_PROXY)
        +          {
        +	    YOUR_RIGHTS *rights =
        +              (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
        +                get_proxy_auth_ex_data_idx());
        +            PROXY_CERT_INFO_EXTENSION *pci =
        +              X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL);
        +
        +            switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
        +              {
        +              case NID_Independent:
        +                /* Do whatever you need to grant explicit rights to
        +                   this particular proxy certificate, usually by
        +                   pulling them from some database.  If there are none
        +                   to be found, clear all rights (making this and any
        +                   subsequent proxy certificate void of any rights).
        +                */
        +                memset(rights->rights, 0, sizeof(rights->rights));
        +                break;
        +              case NID_id_ppl_inheritAll:
        +                /* This is basically a NOP, we simply let the current
        +                   rights stand as they are. */
        +                break;
        +              default:
        +                /* This is usually the most complex section of code.
        +                   You really do whatever you want as long as you
        +                   follow RFC 3820.  In the example we use here, the
        +                   simplest thing to do is to build another, temporary
        +                   bit array and fill it with the rights granted by
        +                   the current proxy certificate, then use it as a
        +                   mask on the accumulated rights bit array, and
        +                   voilà, you now have a new accumulated rights bit
        +                   array.  */
        +                {
        +                  int i;
        +                  YOUR_RIGHTS tmp_rights;
        +		  memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights));
        +
        +                  /* process_rights() is supposed to be a procedure
        +                     that takes a string and it's length, interprets
        +                     it and sets the bits in the YOUR_RIGHTS pointed
        +                     at by the third argument.  */
        +                  process_rights((char *) pci->proxyPolicy->policy->data,
        +                                 pci->proxyPolicy->policy->length,
        +                                 &tmp_rights);
        +
        +                  for(i = 0; i < total_rights / 8; i++)
        +                    rights->rights[i] &= tmp_rights.rights[i];
        +                }
        +                break;
        +              }
        +            PROXY_CERT_INFO_EXTENSION_free(pci);
        +          }
        +        else if (!(xs->ex_flags & EXFLAG_CA))
        +          {
        +            /* We have a EE certificate, let's use it to set default!
        +            */
        +	    YOUR_RIGHTS *rights =
        +              (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
        +                get_proxy_auth_ex_data_idx());
        +
        +            /* The following procedure finds out what rights the owner
        +               of the current certificate has, and sets them in the
        +               YOUR_RIGHTS structure pointed at by the second
        +               argument.  */
        +            set_default_rights(xs, rights);
        +          }
        +      }
        +    return ok;
        +  }
        +
        +  static int my_X509_verify_cert(X509_STORE_CTX *ctx,
        +                                 YOUR_RIGHTS *needed_rights)
        +  {
        +    int i;
        +    int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) = ctx->verify_cb;
        +    YOUR_RIGHTS rights;
        +
        +    X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
        +    X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(), &rights);
        +    X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
        +    ok = X509_verify_cert(ctx);
        +
        +    if (ok == 1)
        +      {
        +        ok = check_needed_rights(rights, needed_rights);
        +      }
        +
        +    X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb);
        +
        +    return ok;
        +  }
        +
        +If you use SSL or TLS, you can easily set up a callback to have the
        +certificates checked properly, using the code above:
        +
        +  SSL_CTX_set_cert_verify_callback(s_ctx, my_X509_verify_cert, &needed_rights);
        +
        +
        +-- 
        +Richard Levitte
        diff --git a/vendor/openssl/openssl/doc/README b/vendor/openssl/openssl/doc/README
        new file mode 100644
        index 000000000..6ecc14d99
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/README
        @@ -0,0 +1,12 @@
        +
        + apps/openssl.pod .... Documentation of OpenSSL `openssl' command
        + crypto/crypto.pod ... Documentation of OpenSSL crypto.h+libcrypto.a
        + ssl/ssl.pod ......... Documentation of OpenSSL ssl.h+libssl.a
        + openssl.txt ......... Assembled documentation files for OpenSSL [not final]
        + ssleay.txt .......... Assembled documentation of ancestor SSLeay [obsolete]
        + standards.txt ....... Assembled pointers to standards, RFCs or internet drafts
        +                       that are related to OpenSSL.
        +
        + An archive of HTML documents for the SSLeay library is available from
        + http://www.columbia.edu/~ariel/ssleay/
        +
        diff --git a/vendor/openssl/openssl/doc/apps/CA.pl.pod b/vendor/openssl/openssl/doc/apps/CA.pl.pod
        new file mode 100644
        index 000000000..d326101cd
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/CA.pl.pod
        @@ -0,0 +1,179 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +CA.pl - friendlier interface for OpenSSL certificate programs
        +
        +=head1 SYNOPSIS
        +
        +B<CA.pl>
        +[B<-?>]
        +[B<-h>]
        +[B<-help>]
        +[B<-newcert>]
        +[B<-newreq>]
        +[B<-newreq-nodes>]
        +[B<-newca>]
        +[B<-xsign>]
        +[B<-sign>]
        +[B<-signreq>]
        +[B<-signcert>]
        +[B<-verify>]
        +[B<files>]
        +
        +=head1 DESCRIPTION
        +
        +The B<CA.pl> script is a perl script that supplies the relevant command line
        +arguments to the B<openssl> command for some common certificate operations.
        +It is intended to simplify the process of certificate creation and management
        +by the use of some simple options.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<?>, B<-h>, B<-help>
        +
        +prints a usage message.
        +
        +=item B<-newcert>
        +
        +creates a new self signed certificate. The private key is written to the file
        +"newkey.pem" and the request written to the file "newreq.pem".
        +
        +=item B<-newreq>
        +
        +creates a new certificate request. The private key is written to the file
        +"newkey.pem" and the request written to the file "newreq.pem".
        +
        +=item B<-newreq-nodes>
        +
        +is like B<-newreq> except that the private key will not be encrypted.
        +
        +=item B<-newca>
        +
        +creates a new CA hierarchy for use with the B<ca> program (or the B<-signcert>
        +and B<-xsign> options). The user is prompted to enter the filename of the CA
        +certificates (which should also contain the private key) or by hitting ENTER
        +details of the CA will be prompted for. The relevant files and directories
        +are created in a directory called "demoCA" in the current directory.
        +
        +=item B<-pkcs12>
        +
        +create a PKCS#12 file containing the user certificate, private key and CA
        +certificate. It expects the user certificate and private key to be in the
        +file "newcert.pem" and the CA certificate to be in the file demoCA/cacert.pem,
        +it creates a file "newcert.p12". This command can thus be called after the
        +B<-sign> option. The PKCS#12 file can be imported directly into a browser.
        +If there is an additional argument on the command line it will be used as the
        +"friendly name" for the certificate (which is typically displayed in the browser
        +list box), otherwise the name "My Certificate" is used.
        +
        +=item B<-sign>, B<-signreq>, B<-xsign>
        +
        +calls the B<ca> program to sign a certificate request. It expects the request
        +to be in the file "newreq.pem". The new certificate is written to the file
        +"newcert.pem" except in the case of the B<-xsign> option when it is written
        +to standard output.
        +
        +
        +=item B<-signCA>
        +
        +this option is the same as the B<-signreq> option except it uses the configuration
        +file section B<v3_ca> and so makes the signed request a valid CA certificate. This
        +is useful when creating intermediate CA from a root CA.
        +
        +=item B<-signcert>
        +
        +this option is the same as B<-sign> except it expects a self signed certificate
        +to be present in the file "newreq.pem".
        +
        +=item B<-verify>
        +
        +verifies certificates against the CA certificate for "demoCA". If no certificates
        +are specified on the command line it tries to verify the file "newcert.pem". 
        +
        +=item B<files>
        +
        +one or more optional certificate file names for use with the B<-verify> command.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Create a CA hierarchy:
        +
        + CA.pl -newca
        +
        +Complete certificate creation example: create a CA, create a request, sign
        +the request and finally create a PKCS#12 file containing it.
        +
        + CA.pl -newca
        + CA.pl -newreq
        + CA.pl -signreq
        + CA.pl -pkcs12 "My Test Certificate"
        +
        +=head1 DSA CERTIFICATES
        +
        +Although the B<CA.pl> creates RSA CAs and requests it is still possible to
        +use it with DSA certificates and requests using the L<req(1)|req(1)> command
        +directly. The following example shows the steps that would typically be taken.
        +
        +Create some DSA parameters:
        +
        + openssl dsaparam -out dsap.pem 1024
        +
        +Create a DSA CA certificate and private key:
        +
        + openssl req -x509 -newkey dsa:dsap.pem -keyout cacert.pem -out cacert.pem
        +
        +Create the CA directories and files:
        +
        + CA.pl -newca
        +
        +enter cacert.pem when prompted for the CA file name.
        +
        +Create a DSA certificate request and private key (a different set of parameters
        +can optionally be created first):
        +
        + openssl req -out newreq.pem -newkey dsa:dsap.pem 
        +
        +Sign the request:
        +
        + CA.pl -signreq
        +
        +=head1 NOTES
        +
        +Most of the filenames mentioned can be modified by editing the B<CA.pl> script.
        +
        +If the demoCA directory already exists then the B<-newca> command will not
        +overwrite it and will do nothing. This can happen if a previous call using
        +the B<-newca> option terminated abnormally. To get the correct behaviour
        +delete the demoCA directory if it already exists.
        +
        +Under some environments it may not be possible to run the B<CA.pl> script
        +directly (for example Win32) and the default configuration file location may
        +be wrong. In this case the command:
        +
        + perl -S CA.pl
        +
        +can be used and the B<OPENSSL_CONF> environment variable changed to point to 
        +the correct path of the configuration file "openssl.cnf".
        +
        +The script is intended as a simple front end for the B<openssl> program for use
        +by a beginner. Its behaviour isn't always what is wanted. For more control over the
        +behaviour of the certificate commands call the B<openssl> command directly.
        +
        +=head1 ENVIRONMENT VARIABLES
        +
        +The variable B<OPENSSL_CONF> if defined allows an alternative configuration
        +file location to be specified, it should contain the full path to the
        +configuration file, not just its directory.
        +
        +=head1 SEE ALSO
        +
        +L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<req(1)|req(1)>, L<pkcs12(1)|pkcs12(1)>,
        +L<config(5)|config(5)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/asn1parse.pod b/vendor/openssl/openssl/doc/apps/asn1parse.pod
        new file mode 100644
        index 000000000..f7bb92621
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/asn1parse.pod
        @@ -0,0 +1,175 @@
        +=pod
        +
        +=head1 NAME
        +
        +asn1parse - ASN.1 parsing tool
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<asn1parse>
        +[B<-inform PEM|DER>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-noout>]
        +[B<-offset number>]
        +[B<-length number>]
        +[B<-i>]
        +[B<-oid filename>]
        +[B<-strparse offset>]
        +[B<-genstr string>]
        +[B<-genconf file>]
        +
        +=head1 DESCRIPTION
        +
        +The B<asn1parse> command is a diagnostic utility that can parse ASN.1
        +structures. It can also be used to extract data from ASN.1 formatted data.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-inform> B<DER|PEM>
        +
        +the input format. B<DER> is binary format and B<PEM> (the default) is base64
        +encoded.
        +
        +=item B<-in filename>
        +
        +the input file, default is standard input
        +
        +=item B<-out filename>
        +
        +output file to place the DER encoded data into. If this
        +option is not present then no data will be output. This is most useful when
        +combined with the B<-strparse> option.
        +
        +=item B<-noout>
        +
        +don't output the parsed version of the input file.
        +
        +=item B<-offset number>
        +
        +starting offset to begin parsing, default is start of file.
        +
        +=item B<-length number>
        +
        +number of bytes to parse, default is until end of file.
        +
        +=item B<-i>
        +
        +indents the output according to the "depth" of the structures.
        +
        +=item B<-oid filename>
        +
        +a file containing additional OBJECT IDENTIFIERs (OIDs). The format of this
        +file is described in the NOTES section below.
        +
        +=item B<-strparse offset>
        +
        +parse the contents octets of the ASN.1 object starting at B<offset>. This
        +option can be used multiple times to "drill down" into a nested structure.
        +
        +=item B<-genstr string>, B<-genconf file>
        +
        +generate encoded data based on B<string>, B<file> or both using
        +L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)> format. If B<file> only is
        +present then the string is obtained from the default section using the name
        +B<asn1>. The encoded data is passed through the ASN1 parser and printed out as
        +though it came from a file, the contents can thus be examined and written to a
        +file using the B<out> option. 
        +
        +=back
        +
        +=head2 OUTPUT
        +
        +The output will typically contain lines like this:
        +
        +  0:d=0  hl=4 l= 681 cons: SEQUENCE          
        +
        +.....
        +
        +  229:d=3  hl=3 l= 141 prim: BIT STRING        
        +  373:d=2  hl=3 l= 162 cons: cont [ 3 ]        
        +  376:d=3  hl=3 l= 159 cons: SEQUENCE          
        +  379:d=4  hl=2 l=  29 cons: SEQUENCE          
        +  381:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
        +  386:d=5  hl=2 l=  22 prim: OCTET STRING      
        +  410:d=4  hl=2 l= 112 cons: SEQUENCE          
        +  412:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
        +  417:d=5  hl=2 l= 105 prim: OCTET STRING      
        +  524:d=4  hl=2 l=  12 cons: SEQUENCE          
        +
        +.....
        +
        +This example is part of a self signed certificate. Each line starts with the
        +offset in decimal. B<d=XX> specifies the current depth. The depth is increased
        +within the scope of any SET or SEQUENCE. B<hl=XX> gives the header length
        +(tag and length octets) of the current type. B<l=XX> gives the length of
        +the contents octets.
        +
        +The B<-i> option can be used to make the output more readable.
        +
        +Some knowledge of the ASN.1 structure is needed to interpret the output. 
        +
        +In this example the BIT STRING at offset 229 is the certificate public key.
        +The contents octets of this will contain the public key information. This can
        +be examined using the option B<-strparse 229> to yield:
        +
        +    0:d=0  hl=3 l= 137 cons: SEQUENCE          
        +    3:d=1  hl=3 l= 129 prim: INTEGER           :E5D21E1F5C8D208EA7A2166C7FAF9F6BDF2059669C60876DDB70840F1A5AAFA59699FE471F379F1DD6A487E7D5409AB6A88D4A9746E24B91D8CF55DB3521015460C8EDE44EE8A4189F7A7BE77D6CD3A9AF2696F486855CF58BF0EDF2B4068058C7A947F52548DDF7E15E96B385F86422BEA9064A3EE9E1158A56E4A6F47E5897
        +  135:d=1  hl=2 l=   3 prim: INTEGER           :010001
        +
        +=head1 NOTES
        +
        +If an OID is not part of OpenSSL's internal table it will be represented in
        +numerical form (for example 1.2.3.4). The file passed to the B<-oid> option 
        +allows additional OIDs to be included. Each line consists of three columns,
        +the first column is the OID in numerical format and should be followed by white
        +space. The second column is the "short name" which is a single word followed
        +by white space. The final column is the rest of the line and is the
        +"long name". B<asn1parse> displays the long name. Example:
        +
        +C<1.2.3.4	shortName	A long name>
        +
        +=head1 EXAMPLES
        +
        +Parse a file:
        +
        + openssl asn1parse -in file.pem
        +
        +Parse a DER file:
        +
        + openssl asn1parse -inform DER -in file.der
        +
        +Generate a simple UTF8String:
        +
        + openssl asn1parse -genstr 'UTF8:Hello World'
        +
        +Generate and write out a UTF8String, don't print parsed output:
        +
        + openssl asn1parse -genstr 'UTF8:Hello World' -noout -out utf8.der
        +
        +Generate using a config file:
        +
        + openssl asn1parse -genconf asn1.cnf -noout -out asn1.der
        +
        +Example config file:
        +
        + asn1=SEQUENCE:seq_sect
        +
        + [seq_sect]
        +
        + field1=BOOL:TRUE
        + field2=EXP:0, UTF8:some random string
        +
        +
        +=head1 BUGS
        +
        +There should be options to change the format of output lines. The output of some
        +ASN.1 types is not well handled (if at all).
        +
        +=head1 SEE ALSO
        +
        +L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/ca.pod b/vendor/openssl/openssl/doc/apps/ca.pod
        new file mode 100644
        index 000000000..9ff0cc361
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/ca.pod
        @@ -0,0 +1,675 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +ca - sample minimal CA application
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<ca>
        +[B<-verbose>]
        +[B<-config filename>]
        +[B<-name section>]
        +[B<-gencrl>]
        +[B<-revoke file>]
        +[B<-crl_reason reason>]
        +[B<-crl_hold instruction>]
        +[B<-crl_compromise time>]
        +[B<-crl_CA_compromise time>]
        +[B<-crldays days>]
        +[B<-crlhours hours>]
        +[B<-crlexts section>]
        +[B<-startdate date>]
        +[B<-enddate date>]
        +[B<-days arg>]
        +[B<-md arg>]
        +[B<-policy arg>]
        +[B<-keyfile arg>]
        +[B<-key arg>]
        +[B<-passin arg>]
        +[B<-cert file>]
        +[B<-selfsign>]
        +[B<-in file>]
        +[B<-out file>]
        +[B<-notext>]
        +[B<-outdir dir>]
        +[B<-infiles>]
        +[B<-spkac file>]
        +[B<-ss_cert file>]
        +[B<-preserveDN>]
        +[B<-noemailDN>]
        +[B<-batch>]
        +[B<-msie_hack>]
        +[B<-extensions section>]
        +[B<-extfile section>]
        +[B<-engine id>]
        +[B<-subj arg>]
        +[B<-utf8>]
        +[B<-multivalue-rdn>]
        +
        +=head1 DESCRIPTION
        +
        +The B<ca> command is a minimal CA application. It can be used
        +to sign certificate requests in a variety of forms and generate
        +CRLs it also maintains a text database of issued certificates
        +and their status.
        +
        +The options descriptions will be divided into each purpose.
        +
        +=head1 CA OPTIONS
        +
        +=over 4
        +
        +=item B<-config filename>
        +
        +specifies the configuration file to use.
        +
        +=item B<-name section>
        +
        +specifies the configuration file section to use (overrides
        +B<default_ca> in the B<ca> section).
        +
        +=item B<-in filename>
        +
        +an input filename containing a single certificate request to be
        +signed by the CA.
        +
        +=item B<-ss_cert filename>
        +
        +a single self signed certificate to be signed by the CA.
        +
        +=item B<-spkac filename>
        +
        +a file containing a single Netscape signed public key and challenge
        +and additional field values to be signed by the CA. See the B<SPKAC FORMAT>
        +section for information on the required format.
        +
        +=item B<-infiles>
        +
        +if present this should be the last option, all subsequent arguments
        +are assumed to the the names of files containing certificate requests. 
        +
        +=item B<-out filename>
        +
        +the output file to output certificates to. The default is standard
        +output. The certificate details will also be printed out to this
        +file.
        +
        +=item B<-outdir directory>
        +
        +the directory to output certificates to. The certificate will be
        +written to a filename consisting of the serial number in hex with
        +".pem" appended.
        +
        +=item B<-cert>
        +
        +the CA certificate file.
        +
        +=item B<-keyfile filename>
        +
        +the private key to sign requests with.
        +
        +=item B<-key password>
        +
        +the password used to encrypt the private key. Since on some
        +systems the command line arguments are visible (e.g. Unix with
        +the 'ps' utility) this option should be used with caution.
        +
        +=item B<-selfsign>
        +
        +indicates the issued certificates are to be signed with the key
        +the certificate requests were signed with (given with B<-keyfile>).
        +Cerificate requests signed with a different key are ignored.  If
        +B<-spkac>, B<-ss_cert> or B<-gencrl> are given, B<-selfsign> is
        +ignored.
        +
        +A consequence of using B<-selfsign> is that the self-signed
        +certificate appears among the entries in the certificate database
        +(see the configuration option B<database>), and uses the same
        +serial number counter as all other certificates sign with the
        +self-signed certificate.
        +
        +=item B<-passin arg>
        +
        +the key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-verbose>
        +
        +this prints extra details about the operations being performed.
        +
        +=item B<-notext>
        +
        +don't output the text form of a certificate to the output file.
        +
        +=item B<-startdate date>
        +
        +this allows the start date to be explicitly set. The format of the
        +date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).
        +
        +=item B<-enddate date>
        +
        +this allows the expiry date to be explicitly set. The format of the
        +date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).
        +
        +=item B<-days arg>
        +
        +the number of days to certify the certificate for.
        +
        +=item B<-md alg>
        +
        +the message digest to use. Possible values include md5, sha1 and mdc2.
        +This option also applies to CRLs.
        +
        +=item B<-policy arg>
        +
        +this option defines the CA "policy" to use. This is a section in
        +the configuration file which decides which fields should be mandatory
        +or match the CA certificate. Check out the B<POLICY FORMAT> section
        +for more information.
        +
        +=item B<-msie_hack>
        +
        +this is a legacy option to make B<ca> work with very old versions of
        +the IE certificate enrollment control "certenr3". It used UniversalStrings
        +for almost everything. Since the old control has various security bugs
        +its use is strongly discouraged. The newer control "Xenroll" does not
        +need this option.
        +
        +=item B<-preserveDN>
        +
        +Normally the DN order of a certificate is the same as the order of the
        +fields in the relevant policy section. When this option is set the order 
        +is the same as the request. This is largely for compatibility with the
        +older IE enrollment control which would only accept certificates if their
        +DNs match the order of the request. This is not needed for Xenroll.
        +
        +=item B<-noemailDN>
        +
        +The DN of a certificate can contain the EMAIL field if present in the
        +request DN, however it is good policy just having the e-mail set into
        +the altName extension of the certificate. When this option is set the
        +EMAIL field is removed from the certificate' subject and set only in
        +the, eventually present, extensions. The B<email_in_dn> keyword can be
        +used in the configuration file to enable this behaviour.
        +
        +=item B<-batch>
        +
        +this sets the batch mode. In this mode no questions will be asked
        +and all certificates will be certified automatically.
        +
        +=item B<-extensions section>
        +
        +the section of the configuration file containing certificate extensions
        +to be added when a certificate is issued (defaults to B<x509_extensions>
        +unless the B<-extfile> option is used). If no extension section is
        +present then, a V1 certificate is created. If the extension section
        +is present (even if it is empty), then a V3 certificate is created. See the:w
        +L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
        +extension section format.
        +
        +=item B<-extfile file>
        +
        +an additional configuration file to read certificate extensions from
        +(using the default section unless the B<-extensions> option is also
        +used).
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<ca>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<-subj arg>
        +
        +supersedes subject name given in the request.
        +The arg must be formatted as I</type0=value0/type1=value1/type2=...>,
        +characters may be escaped by \ (backslash), no spaces are skipped.
        +
        +=item B<-utf8>
        +
        +this option causes field values to be interpreted as UTF8 strings, by 
        +default they are interpreted as ASCII. This means that the field
        +values, whether prompted from a terminal or obtained from a
        +configuration file, must be valid UTF8 strings.
        +
        +=item B<-multivalue-rdn>
        +
        +this option causes the -subj argument to be interpretedt with full
        +support for multivalued RDNs. Example:
        +
        +I</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
        +
        +If -multi-rdn is not used then the UID value is I<123456+CN=John Doe>.
        +
        +=back
        +
        +=head1 CRL OPTIONS
        +
        +=over 4
        +
        +=item B<-gencrl>
        +
        +this option generates a CRL based on information in the index file.
        +
        +=item B<-crldays num>
        +
        +the number of days before the next CRL is due. That is the days from
        +now to place in the CRL nextUpdate field.
        +
        +=item B<-crlhours num>
        +
        +the number of hours before the next CRL is due.
        +
        +=item B<-revoke filename>
        +
        +a filename containing a certificate to revoke.
        +
        +=item B<-crl_reason reason>
        +
        +revocation reason, where B<reason> is one of: B<unspecified>, B<keyCompromise>,
        +B<CACompromise>, B<affiliationChanged>, B<superseded>, B<cessationOfOperation>,
        +B<certificateHold> or B<removeFromCRL>. The matching of B<reason> is case
        +insensitive. Setting any revocation reason will make the CRL v2.
        +
        +In practive B<removeFromCRL> is not particularly useful because it is only used
        +in delta CRLs which are not currently implemented.
        +
        +=item B<-crl_hold instruction>
        +
        +This sets the CRL revocation reason code to B<certificateHold> and the hold
        +instruction to B<instruction> which must be an OID. Although any OID can be
        +used only B<holdInstructionNone> (the use of which is discouraged by RFC2459)
        +B<holdInstructionCallIssuer> or B<holdInstructionReject> will normally be used.
        +
        +=item B<-crl_compromise time>
        +
        +This sets the revocation reason to B<keyCompromise> and the compromise time to
        +B<time>. B<time> should be in GeneralizedTime format that is B<YYYYMMDDHHMMSSZ>.
        +
        +=item B<-crl_CA_compromise time>
        +
        +This is the same as B<crl_compromise> except the revocation reason is set to
        +B<CACompromise>.
        +
        +=item B<-crlexts section>
        +
        +the section of the configuration file containing CRL extensions to
        +include. If no CRL extension section is present then a V1 CRL is
        +created, if the CRL extension section is present (even if it is
        +empty) then a V2 CRL is created. The CRL extensions specified are
        +CRL extensions and B<not> CRL entry extensions.  It should be noted
        +that some software (for example Netscape) can't handle V2 CRLs. See
        +L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
        +extension section format.
        +
        +=back
        +
        +=head1 CONFIGURATION FILE OPTIONS
        +
        +The section of the configuration file containing options for B<ca>
        +is found as follows: If the B<-name> command line option is used,
        +then it names the section to be used. Otherwise the section to
        +be used must be named in the B<default_ca> option of the B<ca> section
        +of the configuration file (or in the default section of the
        +configuration file). Besides B<default_ca>, the following options are
        +read directly from the B<ca> section:
        + RANDFILE
        + preserve
        + msie_hack
        +With the exception of B<RANDFILE>, this is probably a bug and may
        +change in future releases.
        +
        +Many of the configuration file options are identical to command line
        +options. Where the option is present in the configuration file
        +and the command line the command line value is used. Where an
        +option is described as mandatory then it must be present in
        +the configuration file or the command line equivalent (if
        +any) used.
        +
        +=over 4
        +
        +=item B<oid_file>
        +
        +This specifies a file containing additional B<OBJECT IDENTIFIERS>.
        +Each line of the file should consist of the numerical form of the
        +object identifier followed by white space then the short name followed
        +by white space and finally the long name. 
        +
        +=item B<oid_section>
        +
        +This specifies a section in the configuration file containing extra
        +object identifiers. Each line should consist of the short name of the
        +object identifier followed by B<=> and the numerical form. The short
        +and long names are the same when this option is used.
        +
        +=item B<new_certs_dir>
        +
        +the same as the B<-outdir> command line option. It specifies
        +the directory where new certificates will be placed. Mandatory.
        +
        +=item B<certificate>
        +
        +the same as B<-cert>. It gives the file containing the CA
        +certificate. Mandatory.
        +
        +=item B<private_key>
        +
        +same as the B<-keyfile> option. The file containing the
        +CA private key. Mandatory.
        +
        +=item B<RANDFILE>
        +
        +a file used to read and write random number seed information, or
        +an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +
        +=item B<default_days>
        +
        +the same as the B<-days> option. The number of days to certify
        +a certificate for. 
        +
        +=item B<default_startdate>
        +
        +the same as the B<-startdate> option. The start date to certify
        +a certificate for. If not set the current time is used.
        +
        +=item B<default_enddate>
        +
        +the same as the B<-enddate> option. Either this option or
        +B<default_days> (or the command line equivalents) must be
        +present.
        +
        +=item B<default_crl_hours default_crl_days>
        +
        +the same as the B<-crlhours> and the B<-crldays> options. These
        +will only be used if neither command line option is present. At
        +least one of these must be present to generate a CRL.
        +
        +=item B<default_md>
        +
        +the same as the B<-md> option. The message digest to use. Mandatory.
        +
        +=item B<database>
        +
        +the text database file to use. Mandatory. This file must be present
        +though initially it will be empty.
        +
        +=item B<unique_subject>
        +
        +if the value B<yes> is given, the valid certificate entries in the
        +database must have unique subjects.  if the value B<no> is given,
        +several valid certificate entries may have the exact same subject.
        +The default value is B<yes>, to be compatible with older (pre 0.9.8)
        +versions of OpenSSL.  However, to make CA certificate roll-over easier,
        +it's recommended to use the value B<no>, especially if combined with
        +the B<-selfsign> command line option.
        +
        +=item B<serial>
        +
        +a text file containing the next serial number to use in hex. Mandatory.
        +This file must be present and contain a valid serial number.
        +
        +=item B<crlnumber>
        +
        +a text file containing the next CRL number to use in hex. The crl number
        +will be inserted in the CRLs only if this file exists. If this file is
        +present, it must contain a valid CRL number.
        +
        +=item B<x509_extensions>
        +
        +the same as B<-extensions>.
        +
        +=item B<crl_extensions>
        +
        +the same as B<-crlexts>.
        +
        +=item B<preserve>
        +
        +the same as B<-preserveDN>
        +
        +=item B<email_in_dn>
        +
        +the same as B<-noemailDN>. If you want the EMAIL field to be removed
        +from the DN of the certificate simply set this to 'no'. If not present
        +the default is to allow for the EMAIL filed in the certificate's DN.
        +
        +=item B<msie_hack>
        +
        +the same as B<-msie_hack>
        +
        +=item B<policy>
        +
        +the same as B<-policy>. Mandatory. See the B<POLICY FORMAT> section
        +for more information.
        +
        +=item B<name_opt>, B<cert_opt>
        +
        +these options allow the format used to display the certificate details
        +when asking the user to confirm signing. All the options supported by
        +the B<x509> utilities B<-nameopt> and B<-certopt> switches can be used
        +here, except the B<no_signame> and B<no_sigdump> are permanently set
        +and cannot be disabled (this is because the certificate signature cannot
        +be displayed because the certificate has not been signed at this point).
        +
        +For convenience the values B<ca_default> are accepted by both to produce
        +a reasonable output.
        +
        +If neither option is present the format used in earlier versions of
        +OpenSSL is used. Use of the old format is B<strongly> discouraged because
        +it only displays fields mentioned in the B<policy> section, mishandles
        +multicharacter string types and does not display extensions.
        +
        +=item B<copy_extensions>
        +
        +determines how extensions in certificate requests should be handled.
        +If set to B<none> or this option is not present then extensions are
        +ignored and not copied to the certificate. If set to B<copy> then any
        +extensions present in the request that are not already present are copied
        +to the certificate. If set to B<copyall> then all extensions in the
        +request are copied to the certificate: if the extension is already present
        +in the certificate it is deleted first. See the B<WARNINGS> section before
        +using this option.
        +
        +The main use of this option is to allow a certificate request to supply
        +values for certain extensions such as subjectAltName.
        +
        +=back
        +
        +=head1 POLICY FORMAT
        +
        +The policy section consists of a set of variables corresponding to
        +certificate DN fields. If the value is "match" then the field value
        +must match the same field in the CA certificate. If the value is
        +"supplied" then it must be present. If the value is "optional" then
        +it may be present. Any fields not mentioned in the policy section
        +are silently deleted, unless the B<-preserveDN> option is set but
        +this can be regarded more of a quirk than intended behaviour.
        +
        +=head1 SPKAC FORMAT
        +
        +The input to the B<-spkac> command line option is a Netscape
        +signed public key and challenge. This will usually come from
        +the B<KEYGEN> tag in an HTML form to create a new private key. 
        +It is however possible to create SPKACs using the B<spkac> utility.
        +
        +The file should contain the variable SPKAC set to the value of
        +the SPKAC and also the required DN components as name value pairs.
        +If you need to include the same component twice then it can be
        +preceded by a number and a '.'.
        +
        +=head1 EXAMPLES
        +
        +Note: these examples assume that the B<ca> directory structure is
        +already set up and the relevant files already exist. This usually
        +involves creating a CA certificate and private key with B<req>, a
        +serial number file and an empty index file and placing them in
        +the relevant directories.
        +
        +To use the sample configuration file below the directories demoCA,
        +demoCA/private and demoCA/newcerts would be created. The CA
        +certificate would be copied to demoCA/cacert.pem and its private
        +key to demoCA/private/cakey.pem. A file demoCA/serial would be
        +created containing for example "01" and the empty index file
        +demoCA/index.txt.
        +
        +
        +Sign a certificate request:
        +
        + openssl ca -in req.pem -out newcert.pem
        +
        +Sign a certificate request, using CA extensions:
        +
        + openssl ca -in req.pem -extensions v3_ca -out newcert.pem
        +
        +Generate a CRL
        +
        + openssl ca -gencrl -out crl.pem
        +
        +Sign several requests:
        +
        + openssl ca -infiles req1.pem req2.pem req3.pem
        +
        +Certify a Netscape SPKAC:
        +
        + openssl ca -spkac spkac.txt
        +
        +A sample SPKAC file (the SPKAC line has been truncated for clarity):
        +
        + SPKAC=MIG0MGAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PDhCeV/xIxUg8V70YRxK2A5
        + CN=Steve Test
        + emailAddress=steve@openssl.org
        + 0.OU=OpenSSL Group
        + 1.OU=Another Group
        +
        +A sample configuration file with the relevant sections for B<ca>:
        +
        + [ ca ]
        + default_ca      = CA_default            # The default ca section
        + 
        + [ CA_default ]
        +
        + dir            = ./demoCA              # top dir
        + database       = $dir/index.txt        # index file.
        + new_certs_dir	= $dir/newcerts         # new certs dir
        + 
        + certificate    = $dir/cacert.pem       # The CA cert
        + serial         = $dir/serial           # serial no file
        + private_key    = $dir/private/cakey.pem# CA private key
        + RANDFILE       = $dir/private/.rand    # random number file
        + 
        + default_days   = 365                   # how long to certify for
        + default_crl_days= 30                   # how long before next CRL
        + default_md     = md5                   # md to use
        +
        + policy         = policy_any            # default policy
        + email_in_dn    = no                    # Don't add the email into cert DN
        +
        + name_opt	= ca_default		# Subject name display option
        + cert_opt	= ca_default		# Certificate display option
        + copy_extensions = none			# Don't copy extensions from request
        +
        + [ policy_any ]
        + countryName            = supplied
        + stateOrProvinceName    = optional
        + organizationName       = optional
        + organizationalUnitName = optional
        + commonName             = supplied
        + emailAddress           = optional
        +
        +=head1 FILES
        +
        +Note: the location of all files can change either by compile time options,
        +configuration file entries, environment variables or command line options.
        +The values below reflect the default values.
        +
        + /usr/local/ssl/lib/openssl.cnf - master configuration file
        + ./demoCA                       - main CA directory
        + ./demoCA/cacert.pem            - CA certificate
        + ./demoCA/private/cakey.pem     - CA private key
        + ./demoCA/serial                - CA serial number file
        + ./demoCA/serial.old            - CA serial number backup file
        + ./demoCA/index.txt             - CA text database file
        + ./demoCA/index.txt.old         - CA text database backup file
        + ./demoCA/certs                 - certificate output file
        + ./demoCA/.rnd                  - CA random seed information
        +
        +=head1 ENVIRONMENT VARIABLES
        +
        +B<OPENSSL_CONF> reflects the location of master configuration file it can
        +be overridden by the B<-config> command line option.
        +
        +=head1 RESTRICTIONS
        +
        +The text database index file is a critical part of the process and 
        +if corrupted it can be difficult to fix. It is theoretically possible
        +to rebuild the index file from all the issued certificates and a current
        +CRL: however there is no option to do this.
        +
        +V2 CRL features like delta CRLs are not currently supported.
        +
        +Although several requests can be input and handled at once it is only
        +possible to include one SPKAC or self signed certificate.
        +
        +=head1 BUGS
        +
        +The use of an in memory text database can cause problems when large
        +numbers of certificates are present because, as the name implies
        +the database has to be kept in memory.
        +
        +The B<ca> command really needs rewriting or the required functionality
        +exposed at either a command or interface level so a more friendly utility
        +(perl script or GUI) can handle things properly. The scripts B<CA.sh> and
        +B<CA.pl> help a little but not very much.
        +
        +Any fields in a request that are not present in a policy are silently
        +deleted. This does not happen if the B<-preserveDN> option is used. To
        +enforce the absence of the EMAIL field within the DN, as suggested by
        +RFCs, regardless the contents of the request' subject the B<-noemailDN>
        +option can be used. The behaviour should be more friendly and
        +configurable.
        +
        +Cancelling some commands by refusing to certify a certificate can
        +create an empty file.
        +
        +=head1 WARNINGS
        +
        +The B<ca> command is quirky and at times downright unfriendly.
        +
        +The B<ca> utility was originally meant as an example of how to do things
        +in a CA. It was not supposed to be used as a full blown CA itself:
        +nevertheless some people are using it for this purpose.
        +
        +The B<ca> command is effectively a single user command: no locking is
        +done on the various files and attempts to run more than one B<ca> command
        +on the same database can have unpredictable results.
        +
        +The B<copy_extensions> option should be used with caution. If care is
        +not taken then it can be a security risk. For example if a certificate
        +request contains a basicConstraints extension with CA:TRUE and the
        +B<copy_extensions> value is set to B<copyall> and the user does not spot
        +this when the certificate is displayed then this will hand the requestor
        +a valid CA certificate.
        +
        +This situation can be avoided by setting B<copy_extensions> to B<copy>
        +and including basicConstraints with CA:FALSE in the configuration file.
        +Then if the request contains a basicConstraints extension it will be
        +ignored.
        +
        +It is advisable to also include values for other extensions such
        +as B<keyUsage> to prevent a request supplying its own values.
        +
        +Additional restrictions can be placed on the CA certificate itself.
        +For example if the CA certificate has:
        +
        + basicConstraints = CA:TRUE, pathlen:0
        +
        +then even if a certificate is issued with CA:TRUE it will not be valid.
        +
        +=head1 SEE ALSO
        +
        +L<req(1)|req(1)>, L<spkac(1)|spkac(1)>, L<x509(1)|x509(1)>, L<CA.pl(1)|CA.pl(1)>,
        +L<config(5)|config(5)>, L<x509v3_config(5)|x509v3_config(5)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/ciphers.pod b/vendor/openssl/openssl/doc/apps/ciphers.pod
        new file mode 100644
        index 000000000..f44aa00a2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/ciphers.pod
        @@ -0,0 +1,478 @@
        +=pod
        +
        +=head1 NAME
        +
        +ciphers - SSL cipher display and cipher list tool.
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<ciphers>
        +[B<-v>]
        +[B<-V>]
        +[B<-ssl2>]
        +[B<-ssl3>]
        +[B<-tls1>]
        +[B<cipherlist>]
        +
        +=head1 DESCRIPTION
        +
        +The B<ciphers> command converts textual OpenSSL cipher lists into ordered
        +SSL cipher preference lists. It can be used as a test tool to determine
        +the appropriate cipherlist.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-v>
        +
        +Verbose option. List ciphers with a complete description of
        +protocol version (SSLv2 or SSLv3; the latter includes TLS), key exchange,
        +authentication, encryption and mac algorithms used along with any key size
        +restrictions and whether the algorithm is classed as an "export" cipher.
        +Note that without the B<-v> option, ciphers may seem to appear twice
        +in a cipher list; this is when similar ciphers are available for
        +SSL v2 and for SSL v3/TLS v1.
        +
        +=item B<-V>
        +
        +Like B<-V>, but include cipher suite codes in output (hex format).
        +
        +=item B<-ssl3>
        +
        +only include SSL v3 ciphers.
        +
        +=item B<-ssl2>
        +
        +only include SSL v2 ciphers.
        +
        +=item B<-tls1>
        +
        +only include TLS v1 ciphers.
        +
        +=item B<-h>, B<-?>
        +
        +print a brief usage message.
        +
        +=item B<cipherlist>
        +
        +a cipher list to convert to a cipher preference list. If it is not included
        +then the default cipher list will be used. The format is described below.
        +
        +=back
        +
        +=head1 CIPHER LIST FORMAT
        +
        +The cipher list consists of one or more I<cipher strings> separated by colons.
        +Commas or spaces are also acceptable separators but colons are normally used.
        +
        +The actual cipher string can take several different forms.
        +
        +It can consist of a single cipher suite such as B<RC4-SHA>.
        +
        +It can represent a list of cipher suites containing a certain algorithm, or
        +cipher suites of a certain type. For example B<SHA1> represents all ciphers
        +suites using the digest algorithm SHA1 and B<SSLv3> represents all SSL v3
        +algorithms.
        +
        +Lists of cipher suites can be combined in a single cipher string using the
        +B<+> character. This is used as a logical B<and> operation. For example
        +B<SHA1+DES> represents all cipher suites containing the SHA1 B<and> the DES
        +algorithms.
        +
        +Each cipher string can be optionally preceded by the characters B<!>,
        +B<-> or B<+>.
        +
        +If B<!> is used then the ciphers are permanently deleted from the list.
        +The ciphers deleted can never reappear in the list even if they are
        +explicitly stated.
        +
        +If B<-> is used then the ciphers are deleted from the list, but some or
        +all of the ciphers can be added again by later options.
        +
        +If B<+> is used then the ciphers are moved to the end of the list. This
        +option doesn't add any new ciphers it just moves matching existing ones.
        +
        +If none of these characters is present then the string is just interpreted
        +as a list of ciphers to be appended to the current preference list. If the
        +list includes any ciphers already present they will be ignored: that is they
        +will not moved to the end of the list.
        +
        +Additionally the cipher string B<@STRENGTH> can be used at any point to sort
        +the current cipher list in order of encryption algorithm key length.
        +
        +=head1 CIPHER STRINGS
        +
        +The following is a list of all permitted cipher strings and their meanings.
        +
        +=over 4
        +
        +=item B<DEFAULT>
        +
        +the default cipher list. This is determined at compile time and, as of OpenSSL
        +1.0.0, is normally B<ALL:!aNULL:!eNULL>. This must be the first cipher string
        +specified.
        +
        +=item B<COMPLEMENTOFDEFAULT>
        +
        +the ciphers included in B<ALL>, but not enabled by default. Currently
        +this is B<ADH>. Note that this rule does not cover B<eNULL>, which is
        +not included by B<ALL> (use B<COMPLEMENTOFALL> if necessary).
        +
        +=item B<ALL>
        +
        +all cipher suites except the B<eNULL> ciphers which must be explicitly enabled;
        +as of OpenSSL, the B<ALL> cipher suites are reasonably ordered by default
        +
        +=item B<COMPLEMENTOFALL>
        +
        +the cipher suites not enabled by B<ALL>, currently being B<eNULL>.
        +
        +=item B<HIGH>
        +
        +"high" encryption cipher suites. This currently means those with key lengths larger
        +than 128 bits, and some cipher suites with 128-bit keys.
        +
        +=item B<MEDIUM>
        +
        +"medium" encryption cipher suites, currently some of those using 128 bit encryption.
        +
        +=item B<LOW>
        +
        +"low" encryption cipher suites, currently those using 64 or 56 bit encryption algorithms
        +but excluding export cipher suites.
        +
        +=item B<EXP>, B<EXPORT>
        +
        +export encryption algorithms. Including 40 and 56 bits algorithms.
        +
        +=item B<EXPORT40>
        +
        +40 bit export encryption algorithms
        +
        +=item B<EXPORT56>
        +
        +56 bit export encryption algorithms. In OpenSSL 0.9.8c and later the set of
        +56 bit export ciphers is empty unless OpenSSL has been explicitly configured
        +with support for experimental ciphers.
        +
        +=item B<eNULL>, B<NULL>
        +
        +the "NULL" ciphers that is those offering no encryption. Because these offer no
        +encryption at all and are a security risk they are disabled unless explicitly
        +included.
        +
        +=item B<aNULL>
        +
        +the cipher suites offering no authentication. This is currently the anonymous
        +DH algorithms. These cipher suites are vulnerable to a "man in the middle"
        +attack and so their use is normally discouraged.
        +
        +=item B<kRSA>, B<RSA>
        +
        +cipher suites using RSA key exchange.
        +
        +=item B<kEDH>
        +
        +cipher suites using ephemeral DH key agreement.
        +
        +=item B<kDHr>, B<kDHd>
        +
        +cipher suites using DH key agreement and DH certificates signed by CAs with RSA
        +and DSS keys respectively. Not implemented.
        +
        +=item B<aRSA>
        +
        +cipher suites using RSA authentication, i.e. the certificates carry RSA keys.
        +
        +=item B<aDSS>, B<DSS>
        +
        +cipher suites using DSS authentication, i.e. the certificates carry DSS keys.
        +
        +=item B<aDH>
        +
        +cipher suites effectively using DH authentication, i.e. the certificates carry
        +DH keys.  Not implemented.
        +
        +=item B<kFZA>, B<aFZA>, B<eFZA>, B<FZA>
        +
        +ciphers suites using FORTEZZA key exchange, authentication, encryption or all
        +FORTEZZA algorithms. Not implemented.
        +
        +=item B<TLSv1>, B<SSLv3>, B<SSLv2>
        +
        +TLS v1.0, SSL v3.0 or SSL v2.0 cipher suites respectively.
        +
        +=item B<DH>
        +
        +cipher suites using DH, including anonymous DH.
        +
        +=item B<ADH>
        +
        +anonymous DH cipher suites.
        +
        +=item B<AES>
        +
        +cipher suites using AES.
        +
        +=item B<CAMELLIA>
        +
        +cipher suites using Camellia.
        +
        +=item B<3DES>
        +
        +cipher suites using triple DES.
        +
        +=item B<DES>
        +
        +cipher suites using DES (not triple DES).
        +
        +=item B<RC4>
        +
        +cipher suites using RC4.
        +
        +=item B<RC2>
        +
        +cipher suites using RC2.
        +
        +=item B<IDEA>
        +
        +cipher suites using IDEA.
        +
        +=item B<SEED>
        +
        +cipher suites using SEED.
        +
        +=item B<MD5>
        +
        +cipher suites using MD5.
        +
        +=item B<SHA1>, B<SHA>
        +
        +cipher suites using SHA1.
        +
        +=item B<aGOST> 
        +
        +cipher suites using GOST R 34.10 (either 2001 or 94) for authenticaction
        +(needs an engine supporting GOST algorithms). 
        +
        +=item B<aGOST01>
        +
        +cipher suites using GOST R 34.10-2001 authentication.
        +
        +=item B<aGOST94>
        +
        +cipher suites using GOST R 34.10-94 authentication (note that R 34.10-94
        +standard has been expired so use GOST R 34.10-2001)
        +
        +=item B<kGOST>
        +
        +cipher suites, using VKO 34.10 key exchange, specified in the RFC 4357.
        +
        +=item B<GOST94>
        +
        +cipher suites, using HMAC based on GOST R 34.11-94.
        +
        +=item B<GOST89MAC>
        +
        +cipher suites using GOST 28147-89 MAC B<instead of> HMAC.
        +
        +
        +=back
        +
        +=head1 CIPHER SUITE NAMES
        +
        +The following lists give the SSL or TLS cipher suites names from the
        +relevant specification and their OpenSSL equivalents. It should be noted,
        +that several cipher suite names do not include the authentication used,
        +e.g. DES-CBC3-SHA. In these cases, RSA authentication is used.
        +
        +=head2 SSL v3.0 cipher suites.
        +
        + SSL_RSA_WITH_NULL_MD5                   NULL-MD5
        + SSL_RSA_WITH_NULL_SHA                   NULL-SHA
        + SSL_RSA_EXPORT_WITH_RC4_40_MD5          EXP-RC4-MD5
        + SSL_RSA_WITH_RC4_128_MD5                RC4-MD5
        + SSL_RSA_WITH_RC4_128_SHA                RC4-SHA
        + SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5      EXP-RC2-CBC-MD5
        + SSL_RSA_WITH_IDEA_CBC_SHA               IDEA-CBC-SHA
        + SSL_RSA_EXPORT_WITH_DES40_CBC_SHA       EXP-DES-CBC-SHA
        + SSL_RSA_WITH_DES_CBC_SHA                DES-CBC-SHA
        + SSL_RSA_WITH_3DES_EDE_CBC_SHA           DES-CBC3-SHA
        +
        + SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
        + SSL_DH_DSS_WITH_DES_CBC_SHA             Not implemented.
        + SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA        Not implemented.
        + SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
        + SSL_DH_RSA_WITH_DES_CBC_SHA             Not implemented.
        + SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA        Not implemented.
        + SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-DSS-DES-CBC-SHA
        + SSL_DHE_DSS_WITH_DES_CBC_SHA            EDH-DSS-CBC-SHA
        + SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA       EDH-DSS-DES-CBC3-SHA
        + SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-RSA-DES-CBC-SHA
        + SSL_DHE_RSA_WITH_DES_CBC_SHA            EDH-RSA-DES-CBC-SHA
        + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA       EDH-RSA-DES-CBC3-SHA
        +
        + SSL_DH_anon_EXPORT_WITH_RC4_40_MD5      EXP-ADH-RC4-MD5
        + SSL_DH_anon_WITH_RC4_128_MD5            ADH-RC4-MD5
        + SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA   EXP-ADH-DES-CBC-SHA
        + SSL_DH_anon_WITH_DES_CBC_SHA            ADH-DES-CBC-SHA
        + SSL_DH_anon_WITH_3DES_EDE_CBC_SHA       ADH-DES-CBC3-SHA
        +
        + SSL_FORTEZZA_KEA_WITH_NULL_SHA          Not implemented.
        + SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA  Not implemented.
        + SSL_FORTEZZA_KEA_WITH_RC4_128_SHA       Not implemented.
        +
        +=head2 TLS v1.0 cipher suites.
        +
        + TLS_RSA_WITH_NULL_MD5                   NULL-MD5
        + TLS_RSA_WITH_NULL_SHA                   NULL-SHA
        + TLS_RSA_EXPORT_WITH_RC4_40_MD5          EXP-RC4-MD5
        + TLS_RSA_WITH_RC4_128_MD5                RC4-MD5
        + TLS_RSA_WITH_RC4_128_SHA                RC4-SHA
        + TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5      EXP-RC2-CBC-MD5
        + TLS_RSA_WITH_IDEA_CBC_SHA               IDEA-CBC-SHA
        + TLS_RSA_EXPORT_WITH_DES40_CBC_SHA       EXP-DES-CBC-SHA
        + TLS_RSA_WITH_DES_CBC_SHA                DES-CBC-SHA
        + TLS_RSA_WITH_3DES_EDE_CBC_SHA           DES-CBC3-SHA
        +
        + TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
        + TLS_DH_DSS_WITH_DES_CBC_SHA             Not implemented.
        + TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA        Not implemented.
        + TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA    Not implemented.
        + TLS_DH_RSA_WITH_DES_CBC_SHA             Not implemented.
        + TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA        Not implemented.
        + TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-DSS-DES-CBC-SHA
        + TLS_DHE_DSS_WITH_DES_CBC_SHA            EDH-DSS-CBC-SHA
        + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA       EDH-DSS-DES-CBC3-SHA
        + TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA   EXP-EDH-RSA-DES-CBC-SHA
        + TLS_DHE_RSA_WITH_DES_CBC_SHA            EDH-RSA-DES-CBC-SHA
        + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA       EDH-RSA-DES-CBC3-SHA
        +
        + TLS_DH_anon_EXPORT_WITH_RC4_40_MD5      EXP-ADH-RC4-MD5
        + TLS_DH_anon_WITH_RC4_128_MD5            ADH-RC4-MD5
        + TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA   EXP-ADH-DES-CBC-SHA
        + TLS_DH_anon_WITH_DES_CBC_SHA            ADH-DES-CBC-SHA
        + TLS_DH_anon_WITH_3DES_EDE_CBC_SHA       ADH-DES-CBC3-SHA
        +
        +=head2 AES ciphersuites from RFC3268, extending TLS v1.0
        +
        + TLS_RSA_WITH_AES_128_CBC_SHA            AES128-SHA
        + TLS_RSA_WITH_AES_256_CBC_SHA            AES256-SHA
        +
        + TLS_DH_DSS_WITH_AES_128_CBC_SHA         Not implemented.
        + TLS_DH_DSS_WITH_AES_256_CBC_SHA         Not implemented.
        + TLS_DH_RSA_WITH_AES_128_CBC_SHA         Not implemented.
        + TLS_DH_RSA_WITH_AES_256_CBC_SHA         Not implemented.
        +
        + TLS_DHE_DSS_WITH_AES_128_CBC_SHA        DHE-DSS-AES128-SHA
        + TLS_DHE_DSS_WITH_AES_256_CBC_SHA        DHE-DSS-AES256-SHA
        + TLS_DHE_RSA_WITH_AES_128_CBC_SHA        DHE-RSA-AES128-SHA
        + TLS_DHE_RSA_WITH_AES_256_CBC_SHA        DHE-RSA-AES256-SHA
        +
        + TLS_DH_anon_WITH_AES_128_CBC_SHA        ADH-AES128-SHA
        + TLS_DH_anon_WITH_AES_256_CBC_SHA        ADH-AES256-SHA
        +
        +=head2 Camellia ciphersuites from RFC4132, extending TLS v1.0
        +
        + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA      CAMELLIA128-SHA
        + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA      CAMELLIA256-SHA
        +
        + TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA   Not implemented.
        + TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA   Not implemented.
        + TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA   Not implemented.
        + TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA   Not implemented.
        +
        + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA  DHE-DSS-CAMELLIA128-SHA
        + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA  DHE-DSS-CAMELLIA256-SHA
        + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA  DHE-RSA-CAMELLIA128-SHA
        + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA  DHE-RSA-CAMELLIA256-SHA
        +
        + TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA  ADH-CAMELLIA128-SHA
        + TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA  ADH-CAMELLIA256-SHA
        +
        +=head2 SEED ciphersuites from RFC4162, extending TLS v1.0
        +
        + TLS_RSA_WITH_SEED_CBC_SHA              SEED-SHA
        +
        + TLS_DH_DSS_WITH_SEED_CBC_SHA           Not implemented.
        + TLS_DH_RSA_WITH_SEED_CBC_SHA           Not implemented.
        +
        + TLS_DHE_DSS_WITH_SEED_CBC_SHA          DHE-DSS-SEED-SHA
        + TLS_DHE_RSA_WITH_SEED_CBC_SHA          DHE-RSA-SEED-SHA
        +
        + TLS_DH_anon_WITH_SEED_CBC_SHA          ADH-SEED-SHA
        +
        +=head2 GOST ciphersuites from draft-chudov-cryptopro-cptls, extending TLS v1.0
        +
        +Note: these ciphers require an engine which including GOST cryptographic
        +algorithms, such as the B<ccgost> engine, included in the OpenSSL distribution.
        +
        + TLS_GOSTR341094_WITH_28147_CNT_IMIT GOST94-GOST89-GOST89
        + TLS_GOSTR341001_WITH_28147_CNT_IMIT GOST2001-GOST89-GOST89
        + TLS_GOSTR341094_WITH_NULL_GOSTR3411 GOST94-NULL-GOST94
        + TLS_GOSTR341001_WITH_NULL_GOSTR3411 GOST2001-NULL-GOST94
        +
        +=head2 Additional Export 1024 and other cipher suites
        +
        +Note: these ciphers can also be used in SSL v3.
        +
        + TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA     EXP1024-DES-CBC-SHA
        + TLS_RSA_EXPORT1024_WITH_RC4_56_SHA      EXP1024-RC4-SHA
        + TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA EXP1024-DHE-DSS-DES-CBC-SHA
        + TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA  EXP1024-DHE-DSS-RC4-SHA
        + TLS_DHE_DSS_WITH_RC4_128_SHA            DHE-DSS-RC4-SHA
        +
        +=head2 SSL v2.0 cipher suites.
        +
        + SSL_CK_RC4_128_WITH_MD5                 RC4-MD5
        + SSL_CK_RC4_128_EXPORT40_WITH_MD5        EXP-RC4-MD5
        + SSL_CK_RC2_128_CBC_WITH_MD5             RC2-MD5
        + SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    EXP-RC2-MD5
        + SSL_CK_IDEA_128_CBC_WITH_MD5            IDEA-CBC-MD5
        + SSL_CK_DES_64_CBC_WITH_MD5              DES-CBC-MD5
        + SSL_CK_DES_192_EDE3_CBC_WITH_MD5        DES-CBC3-MD5
        +
        +=head1 NOTES
        +
        +The non-ephemeral DH modes are currently unimplemented in OpenSSL
        +because there is no support for DH certificates.
        +
        +Some compiled versions of OpenSSL may not include all the ciphers
        +listed here because some ciphers were excluded at compile time.
        +
        +=head1 EXAMPLES
        +
        +Verbose listing of all OpenSSL ciphers including NULL ciphers:
        +
        + openssl ciphers -v 'ALL:eNULL'
        +
        +Include all ciphers except NULL and anonymous DH then sort by
        +strength:
        +
        + openssl ciphers -v 'ALL:!ADH:@STRENGTH'
        +
        +Include only 3DES ciphers and then place RSA ciphers last:
        +
        + openssl ciphers -v '3DES:+RSA'
        +
        +Include all RC4 ciphers but leave out those without authentication:
        +
        + openssl ciphers -v 'RC4:!COMPLEMENTOFDEFAULT'
        +
        +Include all chiphers with RSA authentication but leave out ciphers without
        +encryption.
        +
        + openssl ciphers -v 'RSA:!COMPLEMENTOFALL'
        +
        +=head1 SEE ALSO
        +
        +L<s_client(1)|s_client(1)>, L<s_server(1)|s_server(1)>, L<ssl(3)|ssl(3)>
        +
        +=head1 HISTORY
        +
        +The B<COMPLENTOFALL> and B<COMPLEMENTOFDEFAULT> selection options
        +for cipherlist strings were added in OpenSSL 0.9.7.
        +The B<-V> option for the B<ciphers> command was added in OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/cms.pod b/vendor/openssl/openssl/doc/apps/cms.pod
        new file mode 100644
        index 000000000..a09588a18
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/cms.pod
        @@ -0,0 +1,602 @@
        +=pod
        +
        +=head1 NAME
        +
        +cms - CMS utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<cms>
        +[B<-encrypt>]
        +[B<-decrypt>]
        +[B<-sign>]
        +[B<-verify>]
        +[B<-cmsout>]
        +[B<-resign>]
        +[B<-data_create>]
        +[B<-data_out>]
        +[B<-digest_create>]
        +[B<-digest_verify>]
        +[B<-compress>]
        +[B<-uncompress>]
        +[B<-EncryptedData_encrypt>]
        +[B<-sign_receipt>]
        +[B<-verify_receipt receipt>]
        +[B<-in filename>]
        +[B<-inform SMIME|PEM|DER>]
        +[B<-rctform SMIME|PEM|DER>]
        +[B<-out filename>]
        +[B<-outform SMIME|PEM|DER>]
        +[B<-stream -indef -noindef>]
        +[B<-noindef>]
        +[B<-content filename>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-print>]
        +[B<-CAfile file>]
        +[B<-CApath dir>]
        +[B<-md digest>]
        +[B<-[cipher]>]
        +[B<-nointern>]
        +[B<-no_signer_cert_verify>]
        +[B<-nocerts>]
        +[B<-noattr>]
        +[B<-nosmimecap>]
        +[B<-binary>]
        +[B<-nodetach>]
        +[B<-certfile file>]
        +[B<-certsout file>]
        +[B<-signer file>]
        +[B<-recip file>]
        +[B<-keyid>]
        +[B<-receipt_request_all -receipt_request_first>]
        +[B<-receipt_request_from emailaddress>]
        +[B<-receipt_request_to emailaddress>]
        +[B<-receipt_request_print>]
        +[B<-secretkey key>]
        +[B<-secretkeyid id>]
        +[B<-econtent_type type>]
        +[B<-inkey file>]
        +[B<-passin arg>]
        +[B<-rand file(s)>]
        +[B<cert.pem...>]
        +[B<-to addr>]
        +[B<-from addr>]
        +[B<-subject subj>]
        +[cert.pem]...
        +
        +=head1 DESCRIPTION
        +
        +The B<cms> command handles S/MIME v3.1 mail. It can encrypt, decrypt, sign and
        +verify, compress and uncompress S/MIME messages.
        +
        +=head1 COMMAND OPTIONS
        +
        +There are fourteen operation options that set the type of operation to be
        +performed. The meaning of the other options varies according to the operation
        +type.
        +
        +=over 4
        +
        +=item B<-encrypt>
        +
        +encrypt mail for the given recipient certificates. Input file is the message
        +to be encrypted. The output file is the encrypted mail in MIME format. The
        +actual CMS type is <B>EnvelopedData<B>.
        +
        +=item B<-decrypt>
        +
        +decrypt mail using the supplied certificate and private key. Expects an
        +encrypted mail message in MIME format for the input file. The decrypted mail
        +is written to the output file.
        +
        +=item B<-sign>
        +
        +sign mail using the supplied certificate and private key. Input file is
        +the message to be signed. The signed message in MIME format is written
        +to the output file.
        +
        +=item B<-verify>
        +
        +verify signed mail. Expects a signed mail message on input and outputs
        +the signed data. Both clear text and opaque signing is supported.
        +
        +=item B<-cmsout>
        +
        +takes an input message and writes out a PEM encoded CMS structure.
        +
        +=item B<-resign>
        +
        +resign a message: take an existing message and one or more new signers.
        +
        +=item B<-data_create>
        +
        +Create a CMS B<Data> type.
        +
        +=item B<-data_out>
        +
        +B<Data> type and output the content.
        +
        +=item B<-digest_create>
        +
        +Create a CMS B<DigestedData> type.
        +
        +=item B<-digest_verify>
        +
        +Verify a CMS B<DigestedData> type and output the content.
        +
        +=item B<-compress>
        +
        +Create a CMS B<CompressedData> type. OpenSSL must be compiled with B<zlib>
        +support for this option to work, otherwise it will output an error.
        +
        +=item B<-uncompress>
        +
        +Uncompress a CMS B<CompressedData> type and output the content. OpenSSL must be
        +compiled with B<zlib> support for this option to work, otherwise it will
        +output an error.
        +
        +=item B<-EncryptedData_encrypt>
        +
        +Encrypt suppled content using supplied symmetric key and algorithm using a CMS
        +B<EncrytedData> type and output the content.
        +
        +=item B<-sign_receipt>
        +
        +Generate and output a signed receipt for the supplied message. The input 
        +message B<must> contain a signed receipt request. Functionality is otherwise
        +similar to the B<-sign> operation.
        +
        +=item B<-verify_receipt receipt>
        +
        +Verify a signed receipt in filename B<receipt>. The input message B<must> 
        +contain the original receipt request. Functionality is otherwise similar
        +to the B<-verify> operation.
        +
        +=item B<-in filename>
        +
        +the input message to be encrypted or signed or the message to be decrypted
        +or verified.
        +
        +=item B<-inform SMIME|PEM|DER>
        +
        +this specifies the input format for the CMS structure. The default
        +is B<SMIME> which reads an S/MIME format message. B<PEM> and B<DER>
        +format change this to expect PEM and DER format CMS structures
        +instead. This currently only affects the input format of the CMS
        +structure, if no CMS structure is being input (for example with
        +B<-encrypt> or B<-sign>) this option has no effect.
        +
        +=item B<-rctform SMIME|PEM|DER>
        +
        +specify the format for a signed receipt for use with the B<-receipt_verify>
        +operation.
        +
        +=item B<-out filename>
        +
        +the message text that has been decrypted or verified or the output MIME
        +format message that has been signed or verified.
        +
        +=item B<-outform SMIME|PEM|DER>
        +
        +this specifies the output format for the CMS structure. The default
        +is B<SMIME> which writes an S/MIME format message. B<PEM> and B<DER>
        +format change this to write PEM and DER format CMS structures
        +instead. This currently only affects the output format of the CMS
        +structure, if no CMS structure is being output (for example with
        +B<-verify> or B<-decrypt>) this option has no effect.
        +
        +=item B<-stream -indef -noindef>
        +
        +the B<-stream> and B<-indef> options are equivalent and enable streaming I/O
        +for encoding operations. This permits single pass processing of data without
        +the need to hold the entire contents in memory, potentially supporting very
        +large files. Streaming is automatically set for S/MIME signing with detached
        +data if the output format is B<SMIME> it is currently off by default for all
        +other operations.
        +
        +=item B<-noindef>
        +
        +disable streaming I/O where it would produce and indefinite length constructed
        +encoding. This option currently has no effect. In future streaming will be
        +enabled by default on all relevant operations and this option will disable it.
        +
        +=item B<-content filename>
        +
        +This specifies a file containing the detached content, this is only
        +useful with the B<-verify> command. This is only usable if the CMS
        +structure is using the detached signature form where the content is
        +not included. This option will override any content if the input format
        +is S/MIME and it uses the multipart/signed MIME content type.
        +
        +=item B<-text>
        +
        +this option adds plain text (text/plain) MIME headers to the supplied
        +message if encrypting or signing. If decrypting or verifying it strips
        +off text headers: if the decrypted or verified message is not of MIME 
        +type text/plain then an error occurs.
        +
        +=item B<-noout>
        +
        +for the B<-cmsout> operation do not output the parsed CMS structure. This
        +is useful when combined with the B<-print> option or if the syntax of the CMS
        +structure is being checked.
        +
        +=item B<-print>
        +
        +for the B<-cmsout> operation print out all fields of the CMS structure. This
        +is mainly useful for testing purposes.
        +
        +=item B<-CAfile file>
        +
        +a file containing trusted CA certificates, only used with B<-verify>.
        +
        +=item B<-CApath dir>
        +
        +a directory containing trusted CA certificates, only used with
        +B<-verify>. This directory must be a standard certificate directory: that
        +is a hash of each subject name (using B<x509 -hash>) should be linked
        +to each certificate.
        +
        +=item B<-md digest>
        +
        +digest algorithm to use when signing or resigning. If not present then the
        +default digest algorithm for the signing key will be used (usually SHA1).
        +
        +=item B<-[cipher]>
        +
        +the encryption algorithm to use. For example triple DES (168 bits) - B<-des3>
        +or 256 bit AES - B<-aes256>. Any standard algorithm name (as used by the
        +EVP_get_cipherbyname() function) can also be used preceded by a dash, for 
        +example B<-aes_128_cbc>. See L<B<enc>|enc(1)> for a list of ciphers
        +supported by your version of OpenSSL.
        +
        +If not specified triple DES is used. Only used with B<-encrypt> and 
        +B<-EncryptedData_create> commands.
        +
        +=item B<-nointern>
        +
        +when verifying a message normally certificates (if any) included in
        +the message are searched for the signing certificate. With this option
        +only the certificates specified in the B<-certfile> option are used.
        +The supplied certificates can still be used as untrusted CAs however.
        +
        +=item B<-no_signer_cert_verify>
        +
        +do not verify the signers certificate of a signed message.
        +
        +=item B<-nocerts>
        +
        +when signing a message the signer's certificate is normally included
        +with this option it is excluded. This will reduce the size of the
        +signed message but the verifier must have a copy of the signers certificate
        +available locally (passed using the B<-certfile> option for example).
        +
        +=item B<-noattr>
        +
        +normally when a message is signed a set of attributes are included which
        +include the signing time and supported symmetric algorithms. With this
        +option they are not included.
        +
        +=item B<-nosmimecap>
        +
        +exclude the list of supported algorithms from signed attributes, other options
        +such as signing time and content type are still included.
        +
        +=item B<-binary>
        +
        +normally the input message is converted to "canonical" format which is
        +effectively using CR and LF as end of line: as required by the S/MIME
        +specification. When this option is present no translation occurs. This
        +is useful when handling binary data which may not be in MIME format.
        +
        +=item B<-nodetach>
        +
        +when signing a message use opaque signing: this form is more resistant
        +to translation by mail relays but it cannot be read by mail agents that
        +do not support S/MIME.  Without this option cleartext signing with
        +the MIME type multipart/signed is used.
        +
        +=item B<-certfile file>
        +
        +allows additional certificates to be specified. When signing these will
        +be included with the message. When verifying these will be searched for
        +the signers certificates. The certificates should be in PEM format.
        +
        +=item B<-certsout file>
        +
        +any certificates contained in the message are written to B<file>.
        +
        +=item B<-signer file>
        +
        +a signing certificate when signing or resigning a message, this option can be
        +used multiple times if more than one signer is required. If a message is being
        +verified then the signers certificates will be written to this file if the
        +verification was successful.
        +
        +=item B<-recip file>
        +
        +the recipients certificate when decrypting a message. This certificate
        +must match one of the recipients of the message or an error occurs.
        +
        +=item B<-keyid>
        +
        +use subject key identifier to identify certificates instead of issuer name and
        +serial number. The supplied certificate B<must> include a subject key
        +identifier extension. Supported by B<-sign> and B<-encrypt> options.
        +
        +=item B<-receipt_request_all -receipt_request_first>
        +
        +for B<-sign> option include a signed receipt request. Indicate requests should
        +be provided by all receipient or first tier recipients (those mailed directly
        +and not from a mailing list). Ignored it B<-receipt_request_from> is included.
        +
        +=item B<-receipt_request_from emailaddress>
        +
        +for B<-sign> option include a signed receipt request. Add an explicit email
        +address where receipts should be supplied.
        +
        +=item B<-receipt_request_to emailaddress>
        +
        +Add an explicit email address where signed receipts should be sent to. This 
        +option B<must> but supplied if a signed receipt it requested.
        +
        +=item B<-receipt_request_print>
        +
        +For the B<-verify> operation print out the contents of any signed receipt
        +requests.
        +
        +=item B<-secretkey key>
        +
        +specify symmetric key to use. The key must be supplied in hex format and be
        +consistent with the algorithm used. Supported by the B<-EncryptedData_encrypt>
        +B<-EncrryptedData_decrypt>, B<-encrypt> and B<-decrypt> options. When used
        +with B<-encrypt> or B<-decrypt> the supplied key is used to wrap or unwrap the
        +content encryption key using an AES key in the B<KEKRecipientInfo> type.
        +
        +=item B<-secretkeyid id>
        +
        +the key identifier for the supplied symmetric key for B<KEKRecipientInfo> type.
        +This option B<must> be present if the B<-secretkey> option is used with
        +B<-encrypt>. With B<-decrypt> operations the B<id> is used to locate the
        +relevant key if it is not supplied then an attempt is used to decrypt any
        +B<KEKRecipientInfo> structures.
        +
        +=item B<-econtent_type type>
        +
        +set the encapsulated content type to B<type> if not supplied the B<Data> type
        +is used. The B<type> argument can be any valid OID name in either text or
        +numerical format. 
        +
        +=item B<-inkey file>
        +
        +the private key to use when signing or decrypting. This must match the
        +corresponding certificate. If this option is not specified then the
        +private key must be included in the certificate file specified with
        +the B<-recip> or B<-signer> file. When signing this option can be used
        +multiple times to specify successive keys.
        +
        +=item B<-passin arg>
        +
        +the private key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<cert.pem...>
        +
        +one or more certificates of message recipients: used when encrypting
        +a message. 
        +
        +=item B<-to, -from, -subject>
        +
        +the relevant mail headers. These are included outside the signed
        +portion of a message so they may be included manually. If signing
        +then many S/MIME mail clients check the signers certificate's email
        +address matches that specified in the From: address.
        +
        +=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
        +
        +Set various certificate chain valiadition option. See the
        +L<B<verify>|verify(1)> manual page for details.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The MIME message must be sent without any blank lines between the
        +headers and the output. Some mail programs will automatically add
        +a blank line. Piping the mail directly to sendmail is one way to
        +achieve the correct format.
        +
        +The supplied message to be signed or encrypted must include the
        +necessary MIME headers or many S/MIME clients wont display it
        +properly (if at all). You can use the B<-text> option to automatically
        +add plain text headers.
        +
        +A "signed and encrypted" message is one where a signed message is
        +then encrypted. This can be produced by encrypting an already signed
        +message: see the examples section.
        +
        +This version of the program only allows one signer per message but it
        +will verify multiple signers on received messages. Some S/MIME clients
        +choke if a message contains multiple signers. It is possible to sign
        +messages "in parallel" by signing an already signed message.
        +
        +The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME
        +clients. Strictly speaking these process CMS enveloped data: CMS
        +encrypted data is used for other purposes.
        +
        +The B<-resign> option uses an existing message digest when adding a new
        +signer. This means that attributes must be present in at least one existing
        +signer using the same message digest or this operation will fail.
        +
        +The B<-stream> and B<-indef> options enable experimental streaming I/O support.
        +As a result the encoding is BER using indefinite length constructed encoding
        +and no longer DER. Streaming is supported for the B<-encrypt> operation and the
        +B<-sign> operation if the content is not detached.
        +
        +Streaming is always used for the B<-sign> operation with detached data but
        +since the content is no longer part of the CMS structure the encoding
        +remains DER.
        +
        +=head1 EXIT CODES
        +
        +=over 4
        +
        +=item 0
        +
        +the operation was completely successfully.
        +
        +=item 1 
        +
        +an error occurred parsing the command options.
        +
        +=item 2
        +
        +one of the input files could not be read.
        +
        +=item 3
        +
        +an error occurred creating the CMS file or when reading the MIME
        +message.
        +
        +=item 4
        +
        +an error occurred decrypting or verifying the message.
        +
        +=item 5
        +
        +the message was verified correctly but an error occurred writing out
        +the signers certificates.
        +
        +=back
        +
        +=head1 COMPATIBILITY WITH PKCS#7 format.
        +
        +The B<smime> utility can only process the older B<PKCS#7> format. The B<cms>
        +utility supports Cryptographic Message Syntax format. Use of some features
        +will result in messages which cannot be processed by applications which only
        +support the older format. These are detailed below.
        +
        +The use of the B<-keyid> option with B<-sign> or B<-encrypt>.
        +
        +The B<-outform PEM> option uses different headers.
        +
        +The B<-compress> option.
        +
        +The B<-secretkey> option when used with B<-encrypt>.
        +
        +Additionally the B<-EncryptedData_create> and B<-data_create> type cannot
        +be processed by the older B<smime> command.
        +
        +=head1 EXAMPLES
        +
        +Create a cleartext signed message:
        +
        + openssl cms -sign -in message.txt -text -out mail.msg \
        +	-signer mycert.pem
        +
        +Create an opaque signed message
        +
        + openssl cms -sign -in message.txt -text -out mail.msg -nodetach \
        +	-signer mycert.pem
        +
        +Create a signed message, include some additional certificates and
        +read the private key from another file:
        +
        + openssl cms -sign -in in.txt -text -out mail.msg \
        +	-signer mycert.pem -inkey mykey.pem -certfile mycerts.pem
        +
        +Create a signed message with two signers, use key identifier:
        +
        + openssl cms -sign -in message.txt -text -out mail.msg \
        +	-signer mycert.pem -signer othercert.pem -keyid
        +
        +Send a signed message under Unix directly to sendmail, including headers:
        +
        + openssl cms -sign -in in.txt -text -signer mycert.pem \
        +	-from steve@openssl.org -to someone@somewhere \
        +	-subject "Signed message" | sendmail someone@somewhere
        +
        +Verify a message and extract the signer's certificate if successful:
        +
        + openssl cms -verify -in mail.msg -signer user.pem -out signedtext.txt
        +
        +Send encrypted mail using triple DES:
        +
        + openssl cms -encrypt -in in.txt -from steve@openssl.org \
        +	-to someone@somewhere -subject "Encrypted message" \
        +	-des3 user.pem -out mail.msg
        +
        +Sign and encrypt mail:
        +
        + openssl cms -sign -in ml.txt -signer my.pem -text \
        +	| openssl cms -encrypt -out mail.msg \
        +	-from steve@openssl.org -to someone@somewhere \
        +	-subject "Signed and Encrypted message" -des3 user.pem
        +
        +Note: the encryption command does not include the B<-text> option because the
        +message being encrypted already has MIME headers.
        +
        +Decrypt mail:
        +
        + openssl cms -decrypt -in mail.msg -recip mycert.pem -inkey key.pem
        +
        +The output from Netscape form signing is a PKCS#7 structure with the
        +detached signature format. You can use this program to verify the
        +signature by line wrapping the base64 encoded structure and surrounding
        +it with:
        +
        + -----BEGIN PKCS7-----
        + -----END PKCS7-----
        +
        +and using the command, 
        +
        + openssl cms -verify -inform PEM -in signature.pem -content content.txt
        +
        +alternatively you can base64 decode the signature and use
        +
        + openssl cms -verify -inform DER -in signature.der -content content.txt
        +
        +Create an encrypted message using 128 bit Camellia:
        +
        + openssl cms -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem
        +
        +Add a signer to an existing message:
        +
        + openssl cms -resign -in mail.msg -signer newsign.pem -out mail2.msg
        +
        +=head1 BUGS
        +
        +The MIME parser isn't very clever: it seems to handle most messages that I've
        +thrown at it but it may choke on others.
        +
        +The code currently will only write out the signer's certificate to a file: if
        +the signer has a separate encryption certificate this must be manually
        +extracted. There should be some heuristic that determines the correct
        +encryption certificate.
        +
        +Ideally a database should be maintained of a certificates for each email
        +address.
        +
        +The code doesn't currently take note of the permitted symmetric encryption
        +algorithms as supplied in the SMIMECapabilities signed attribute. this means the
        +user has to manually include the correct encryption algorithm. It should store
        +the list of permitted ciphers in a database and only use those.
        +
        +No revocation checking is done on the signer's certificate.
        +
        +=head1 HISTORY
        +
        +The use of multiple B<-signer> options and the B<-resign> command were first
        +added in OpenSSL 1.0.0
        +
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/config.pod b/vendor/openssl/openssl/doc/apps/config.pod
        new file mode 100644
        index 000000000..ace34b62b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/config.pod
        @@ -0,0 +1,279 @@
        +
        +=pod
        +
        +=for comment openssl_manual_section:5
        +
        +=head1 NAME
        +
        +config - OpenSSL CONF library configuration files
        +
        +=head1 DESCRIPTION
        +
        +The OpenSSL CONF library can be used to read configuration files.
        +It is used for the OpenSSL master configuration file B<openssl.cnf>
        +and in a few other places like B<SPKAC> files and certificate extension
        +files for the B<x509> utility. OpenSSL applications can also use the
        +CONF library for their own purposes.
        +
        +A configuration file is divided into a number of sections. Each section
        +starts with a line B<[ section_name ]> and ends when a new section is
        +started or end of file is reached. A section name can consist of
        +alphanumeric characters and underscores.
        +
        +The first section of a configuration file is special and is referred
        +to as the B<default> section this is usually unnamed and is from the
        +start of file until the first named section. When a name is being looked up
        +it is first looked up in a named section (if any) and then the
        +default section.
        +
        +The environment is mapped onto a section called B<ENV>.
        +
        +Comments can be included by preceding them with the B<#> character
        +
        +Each section in a configuration file consists of a number of name and
        +value pairs of the form B<name=value>
        +
        +The B<name> string can contain any alphanumeric characters as well as
        +a few punctuation symbols such as B<.> B<,> B<;> and B<_>.
        +
        +The B<value> string consists of the string following the B<=> character
        +until end of line with any leading and trailing white space removed.
        +
        +The value string undergoes variable expansion. This can be done by
        +including the form B<$var> or B<${var}>: this will substitute the value
        +of the named variable in the current section. It is also possible to
        +substitute a value from another section using the syntax B<$section::name>
        +or B<${section::name}>. By using the form B<$ENV::name> environment
        +variables can be substituted. It is also possible to assign values to
        +environment variables by using the name B<ENV::name>, this will work
        +if the program looks up environment variables using the B<CONF> library
        +instead of calling B<getenv()> directly.
        +
        +It is possible to escape certain characters by using any kind of quote
        +or the B<\> character. By making the last character of a line a B<\>
        +a B<value> string can be spread across multiple lines. In addition
        +the sequences B<\n>, B<\r>, B<\b> and B<\t> are recognized.
        +
        +=head1 OPENSSL LIBRARY CONFIGURATION
        +
        +In OpenSSL 0.9.7 and later applications can automatically configure certain
        +aspects of OpenSSL using the master OpenSSL configuration file, or optionally
        +an alternative configuration file. The B<openssl> utility includes this
        +functionality: any sub command uses the master OpenSSL configuration file
        +unless an option is used in the sub command to use an alternative configuration
        +file.
        +
        +To enable library configuration the default section needs to contain an 
        +appropriate line which points to the main configuration section. The default
        +name is B<openssl_conf> which is used by the B<openssl> utility. Other
        +applications may use an alternative name such as B<myapplicaton_conf>.
        +
        +The configuration section should consist of a set of name value pairs which
        +contain specific module configuration information. The B<name> represents
        +the name of the I<configuration module> the meaning of the B<value> is 
        +module specific: it may, for example, represent a further configuration
        +section containing configuration module specific information. E.g.
        +
        + openssl_conf = openssl_init
        +
        + [openssl_init]
        +
        + oid_section = new_oids
        + engines = engine_section
        +
        + [new_oids]
        +
        + ... new oids here ...
        +
        + [engine_section]
        +
        + ... engine stuff here ...
        +
        +Currently there are two configuration modules. One for ASN1 objects another
        +for ENGINE configuration.
        +
        +=head2 ASN1 OBJECT CONFIGURATION MODULE
        +
        +This module has the name B<oid_section>. The value of this variable points
        +to a section containing name value pairs of OIDs: the name is the OID short
        +and long name, the value is the numerical form of the OID. Although some of
        +the B<openssl> utility sub commands already have their own ASN1 OBJECT section
        +functionality not all do. By using the ASN1 OBJECT configuration module
        +B<all> the B<openssl> utility sub commands can see the new objects as well
        +as any compliant applications. For example:
        +
        + [new_oids]
        + 
        + some_new_oid = 1.2.3.4
        + some_other_oid = 1.2.3.5
        +
        +In OpenSSL 0.9.8 it is also possible to set the value to the long name followed
        +by a comma and the numerical OID form. For example:
        +
        + shortName = some object long name, 1.2.3.4
        +
        +=head2 ENGINE CONFIGURATION MODULE
        +
        +This ENGINE configuration module has the name B<engines>. The value of this
        +variable points to a section containing further ENGINE configuration
        +information.
        +
        +The section pointed to by B<engines> is a table of engine names (though see
        +B<engine_id> below) and further sections containing configuration informations
        +specific to each ENGINE.
        +
        +Each ENGINE specific section is used to set default algorithms, load
        +dynamic, perform initialization and send ctrls. The actual operation performed
        +depends on the I<command> name which is the name of the name value pair. The
        +currently supported commands are listed below.
        +
        +For example:
        +
        + [engine_section]
        +
        + # Configure ENGINE named "foo"
        + foo = foo_section
        + # Configure ENGINE named "bar"
        + bar = bar_section
        +
        + [foo_section]
        + ... foo ENGINE specific commands ...
        +
        + [bar_section]
        + ... "bar" ENGINE specific commands ...
        +
        +The command B<engine_id> is used to give the ENGINE name. If used this 
        +command must be first. For example:
        +
        + [engine_section]
        + # This would normally handle an ENGINE named "foo"
        + foo = foo_section
        +
        + [foo_section]
        + # Override default name and use "myfoo" instead.
        + engine_id = myfoo
        +
        +The command B<dynamic_path> loads and adds an ENGINE from the given path. It
        +is equivalent to sending the ctrls B<SO_PATH> with the path argument followed
        +by B<LIST_ADD> with value 2 and B<LOAD> to the dynamic ENGINE. If this is
        +not the required behaviour then alternative ctrls can be sent directly
        +to the dynamic ENGINE using ctrl commands.
        +
        +The command B<init> determines whether to initialize the ENGINE. If the value
        +is B<0> the ENGINE will not be initialized, if B<1> and attempt it made to
        +initialized the ENGINE immediately. If the B<init> command is not present
        +then an attempt will be made to initialize the ENGINE after all commands in
        +its section have been processed.
        +
        +The command B<default_algorithms> sets the default algorithms an ENGINE will
        +supply using the functions B<ENGINE_set_default_string()>
        +
        +If the name matches none of the above command names it is assumed to be a
        +ctrl command which is sent to the ENGINE. The value of the command is the 
        +argument to the ctrl command. If the value is the string B<EMPTY> then no
        +value is sent to the command.
        +
        +For example:
        +
        +
        + [engine_section]
        +
        + # Configure ENGINE named "foo"
        + foo = foo_section
        +
        + [foo_section]
        + # Load engine from DSO
        + dynamic_path = /some/path/fooengine.so
        + # A foo specific ctrl.
        + some_ctrl = some_value
        + # Another ctrl that doesn't take a value.
        + other_ctrl = EMPTY
        + # Supply all default algorithms
        + default_algorithms = ALL
        +
        +=head1 NOTES
        +
        +If a configuration file attempts to expand a variable that doesn't exist
        +then an error is flagged and the file will not load. This can happen
        +if an attempt is made to expand an environment variable that doesn't
        +exist. For example in a previous version of OpenSSL the default OpenSSL
        +master configuration file used the value of B<HOME> which may not be
        +defined on non Unix systems and would cause an error.
        +
        +This can be worked around by including a B<default> section to provide
        +a default value: then if the environment lookup fails the default value
        +will be used instead. For this to work properly the default value must
        +be defined earlier in the configuration file than the expansion. See
        +the B<EXAMPLES> section for an example of how to do this.
        +
        +If the same variable exists in the same section then all but the last
        +value will be silently ignored. In certain circumstances such as with
        +DNs the same field may occur multiple times. This is usually worked
        +around by ignoring any characters before an initial B<.> e.g.
        +
        + 1.OU="My first OU"
        + 2.OU="My Second OU"
        +
        +=head1 EXAMPLES
        +
        +Here is a sample configuration file using some of the features
        +mentioned above.
        +
        + # This is the default section.
        + 
        + HOME=/temp
        + RANDFILE= ${ENV::HOME}/.rnd
        + configdir=$ENV::HOME/config
        +
        + [ section_one ]
        +
        + # We are now in section one.
        +
        + # Quotes permit leading and trailing whitespace
        + any = " any variable name "
        +
        + other = A string that can \
        + cover several lines \
        + by including \\ characters
        +
        + message = Hello World\n
        +
        + [ section_two ]
        +
        + greeting = $section_one::message
        +
        +This next example shows how to expand environment variables safely.
        +
        +Suppose you want a variable called B<tmpfile> to refer to a
        +temporary filename. The directory it is placed in can determined by
        +the the B<TEMP> or B<TMP> environment variables but they may not be
        +set to any value at all. If you just include the environment variable
        +names and the variable doesn't exist then this will cause an error when
        +an attempt is made to load the configuration file. By making use of the
        +default section both values can be looked up with B<TEMP> taking 
        +priority and B</tmp> used if neither is defined:
        +
        + TMP=/tmp
        + # The above value is used if TMP isn't in the environment
        + TEMP=$ENV::TMP
        + # The above value is used if TEMP isn't in the environment
        + tmpfile=${ENV::TEMP}/tmp.filename
        +
        +=head1 BUGS
        +
        +Currently there is no way to include characters using the octal B<\nnn>
        +form. Strings are all null terminated so nulls cannot form part of
        +the value.
        +
        +The escaping isn't quite right: if you want to use sequences like B<\n>
        +you can't use any quote escaping on the same line.
        +
        +Files are loaded in a single pass. This means that an variable expansion
        +will only work if the variables referenced are defined earlier in the
        +file.
        +
        +=head1 SEE ALSO
        +
        +L<x509(1)|x509(1)>, L<req(1)|req(1)>, L<ca(1)|ca(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/crl.pod b/vendor/openssl/openssl/doc/apps/crl.pod
        new file mode 100644
        index 000000000..a40c873b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/crl.pod
        @@ -0,0 +1,117 @@
        +=pod
        +
        +=head1 NAME
        +
        +crl - CRL utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<crl>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-text>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-noout>]
        +[B<-hash>]
        +[B<-issuer>]
        +[B<-lastupdate>]
        +[B<-nextupdate>]
        +[B<-CAfile file>]
        +[B<-CApath dir>]
        +
        +=head1 DESCRIPTION
        +
        +The B<crl> command processes CRL files in DER or PEM format.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. B<DER> format is DER encoded CRL
        +structure. B<PEM> (the default) is a base64 encoded version of
        +the DER form with header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read 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<-text>
        +
        +print out the CRL in text form.
        +
        +=item B<-noout>
        +
        +don't output the encoded version of the CRL.
        +
        +=item B<-hash>
        +
        +output a hash of the issuer name. This can be use to lookup CRLs in
        +a directory by issuer name.
        +
        +=item B<-issuer>
        +
        +output the issuer name.
        +
        +=item B<-lastupdate>
        +
        +output the lastUpdate field.
        +
        +=item B<-nextupdate>
        +
        +output the nextUpdate field.
        +
        +=item B<-CAfile file>
        +
        +verify the signature on a CRL by looking up the issuing certificate in
        +B<file>
        +
        +=item B<-CApath dir>
        +
        +verify the signature on a CRL by looking up the issuing certificate in
        +B<dir>. This directory must be a standard certificate directory: that
        +is a hash of each subject name (using B<x509 -hash>) should be linked
        +to each certificate.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The PEM CRL format uses the header and footer lines:
        +
        + -----BEGIN X509 CRL-----
        + -----END X509 CRL-----
        +
        +=head1 EXAMPLES
        +
        +Convert a CRL file from PEM to DER:
        +
        + openssl crl -in crl.pem -outform DER -out crl.der
        +
        +Output the text form of a DER encoded certificate:
        +
        + openssl crl -in crl.der -text -noout
        +
        +=head1 BUGS
        +
        +Ideally it should be possible to create a CRL using appropriate options
        +and files too.
        +
        +=head1 SEE ALSO
        +
        +L<crl2pkcs7(1)|crl2pkcs7(1)>, L<ca(1)|ca(1)>, L<x509(1)|x509(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/crl2pkcs7.pod b/vendor/openssl/openssl/doc/apps/crl2pkcs7.pod
        new file mode 100644
        index 000000000..3797bc0df
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/crl2pkcs7.pod
        @@ -0,0 +1,91 @@
        +=pod
        +
        +=head1 NAME
        +
        +crl2pkcs7 - Create a PKCS#7 structure from a CRL and certificates.
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<crl2pkcs7>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-certfile filename>]
        +[B<-nocrl>]
        +
        +=head1 DESCRIPTION
        +
        +The B<crl2pkcs7> command takes an optional CRL and one or more
        +certificates and converts them into a PKCS#7 degenerate "certificates
        +only" structure.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the CRL input format. B<DER> format is DER encoded CRL
        +structure.B<PEM> (the default) is a base64 encoded version of
        +the DER form with header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the PKCS#7 structure output format. B<DER> format is DER
        +encoded PKCS#7 structure.B<PEM> (the default) is a base64 encoded version of
        +the DER form with header and footer lines.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a CRL from or standard input if this
        +option is not specified.
        +
        +=item B<-out filename>
        +
        +specifies the output filename to write the PKCS#7 structure to or standard
        +output by default.
        +
        +=item B<-certfile filename>
        +
        +specifies a filename containing one or more certificates in B<PEM> format.
        +All certificates in the file will be added to the PKCS#7 structure. This
        +option can be used more than once to read certificates form multiple
        +files.
        +
        +=item B<-nocrl>
        +
        +normally a CRL is included in the output file. With this option no CRL is
        +included in the output file and a CRL is not read from the input file.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Create a PKCS#7 structure from a certificate and CRL:
        +
        + openssl crl2pkcs7 -in crl.pem -certfile cert.pem -out p7.pem
        +
        +Creates a PKCS#7 structure in DER format with no CRL from several
        +different certificates:
        +
        + openssl crl2pkcs7 -nocrl -certfile newcert.pem 
        +	-certfile demoCA/cacert.pem -outform DER -out p7.der
        +
        +=head1 NOTES
        +
        +The output file is a PKCS#7 signed data structure containing no signers and
        +just certificates and an optional CRL.
        +
        +This utility can be used to send certificates and CAs to Netscape as part of
        +the certificate enrollment process. This involves sending the DER encoded output
        +as MIME type application/x-x509-user-cert.
        +
        +The B<PEM> encoded form with the header and footer lines removed can be used to
        +install user certificates and CAs in MSIE using the Xenroll control.
        +
        +=head1 SEE ALSO
        +
        +L<pkcs7(1)|pkcs7(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/dgst.pod b/vendor/openssl/openssl/doc/apps/dgst.pod
        new file mode 100644
        index 000000000..b035edf08
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/dgst.pod
        @@ -0,0 +1,162 @@
        +=pod
        +
        +=head1 NAME
        +
        +dgst, md5, md4, md2, sha1, sha, mdc2, ripemd160 - message digests
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<dgst> 
        +[B<-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1>]
        +[B<-c>]
        +[B<-d>]
        +[B<-hex>]
        +[B<-binary>]
        +[B<-out filename>]
        +[B<-sign filename>]
        +[B<-keyform arg>]
        +[B<-passin arg>]
        +[B<-verify filename>]
        +[B<-prverify filename>]
        +[B<-signature filename>]
        +[B<-hmac key>]
        +[B<file...>]
        +
        +[B<md5|md4|md2|sha1|sha|mdc2|ripemd160>]
        +[B<-c>]
        +[B<-d>]
        +[B<file...>]
        +
        +=head1 DESCRIPTION
        +
        +The digest functions output the message digest of a supplied file or files
        +in hexadecimal form. They can also be used for digital signing and verification.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-c>
        +
        +print out the digest in two digit groups separated by colons, only relevant if
        +B<hex> format output is used.
        +
        +=item B<-d>
        +
        +print out BIO debugging information.
        +
        +=item B<-hex>
        +
        +digest is to be output as a hex dump. This is the default case for a "normal"
        +digest as opposed to a digital signature.
        +
        +=item B<-binary>
        +
        +output the digest or signature in binary form.
        +
        +=item B<-out filename>
        +
        +filename to output to, or standard output by default.
        +
        +=item B<-sign filename>
        +
        +digitally sign the digest using the private key in "filename".
        +
        +=item B<-keyform arg>
        +
        +Specifies the key format to sign digest with. Only PEM and ENGINE
        +formats are supported by the B<dgst> command.
        +
        +=item B<-engine id>
        +
        +Use engine B<id> for operations (including private key storage).
        +This engine is not used as source for digest algorithms, unless it is
        +also specified in the configuration file.
        +
        +=item B<-sigopt nm:v>
        +
        +Pass options to the signature algorithm during sign or verify operations.
        +Names and values of these options are algorithm-specific.
        +
        +
        +=item B<-passin arg>
        +
        +the private key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-verify filename>
        +
        +verify the signature using the the public key in "filename".
        +The output is either "Verification OK" or "Verification Failure".
        +
        +=item B<-prverify filename>
        +
        +verify the signature using the  the private key in "filename".
        +
        +=item B<-signature filename>
        +
        +the actual signature to verify.
        +
        +=item B<-hmac key>
        +
        +create a hashed MAC using "key".
        +
        +=item B<-mac alg>
        +
        +create MAC (keyed Message Authentication Code). The most popular MAC
        +algorithm is HMAC (hash-based MAC), but there are other MAC algorithms
        +which are not based on hash, for instance B<gost-mac> algorithm,
        +supported by B<ccgost> engine. MAC keys and other options should be set
        +via B<-macopt> parameter.
        +
        +=item B<-macopt nm:v>
        +
        +Passes options to MAC algorithm, specified by B<-mac> key.
        +Following options are supported by both by B<HMAC> and B<gost-mac>:
        +
        +=over 8
        +
        +=item B<key:string>
        +	
        +Specifies MAC key as alphnumeric string (use if key contain printable
        +characters only). String length must conform to any restrictions of
        +the MAC algorithm for example exactly 32 chars for gost-mac.
        +
        +=item B<hexkey:string>
        +
        +Specifies MAC key in hexadecimal form (two hex digits per byte).
        +Key length must conform to any restrictions of the MAC algorithm
        +for example exactly 32 chars for gost-mac.
        +
        +=back
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others. 
        +
        +=item B<file...>
        +
        +file or files to digest. If no files are specified then standard input is
        +used.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The digest of choice for all new applications is SHA1. Other digests are
        +however still widely used.
        +
        +If you wish to sign or verify data using the DSA algorithm then the dss1
        +digest must be used.
        +
        +A source of random numbers is required for certain signing algorithms, in
        +particular DSA.
        +
        +The signing and verify options should only be used if a single file is
        +being signed or verified.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/dhparam.pod b/vendor/openssl/openssl/doc/apps/dhparam.pod
        new file mode 100644
        index 000000000..9edb4ff4e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/dhparam.pod
        @@ -0,0 +1,141 @@
        +=pod
        +
        +=head1 NAME
        +
        +dhparam - DH parameter manipulation and generation
        +
        +=head1 SYNOPSIS
        +
        +B<openssl dhparam>
        +[B<-inform DER|PEM>]
        +[B<-outform DER|PEM>]
        +[B<-in> I<filename>]
        +[B<-out> I<filename>]
        +[B<-dsaparam>]
        +[B<-noout>]
        +[B<-text>]
        +[B<-C>]
        +[B<-2>]
        +[B<-5>]
        +[B<-rand> I<file(s)>]
        +[B<-engine id>]
        +[I<numbits>]
        +
        +=head1 DESCRIPTION
        +
        +This command is used to manipulate DH parameter files.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option uses an ASN1 DER encoded
        +form compatible with the PKCS#3 DHparameter structure. The PEM form is the
        +default format: it consists of the B<DER> format base64 encoded with
        +additional header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in> I<filename>
        +
        +This specifies the input filename to read parameters from or standard input if
        +this option is not specified.
        +
        +=item B<-out> I<filename>
        +
        +This specifies the output filename parameters to. Standard output is used
        +if this option is not present. The output filename should B<not> be the same
        +as the input filename.
        +
        +=item B<-dsaparam>
        +
        +If this option is used, DSA rather than DH parameters are read or created;
        +they are converted to DH format.  Otherwise, "strong" primes (such
        +that (p-1)/2 is also prime) will be used for DH parameter generation.
        +
        +DH parameter generation with the B<-dsaparam> option is much faster,
        +and the recommended exponent length is shorter, which makes DH key
        +exchange more efficient.  Beware that with such DSA-style DH
        +parameters, a fresh DH key should be created for each use to
        +avoid small-subgroup attacks that may be possible otherwise.
        +
        +=item B<-2>, B<-5>
        +
        +The generator to use, either 2 or 5. 2 is the default. If present then the
        +input file is ignored and parameters are generated instead.
        +
        +=item B<-rand> I<file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item I<numbits>
        +
        +this option specifies that a parameter set should be generated of size
        +I<numbits>. It must be the last option. If not present then a value of 512
        +is used. If this option is present then the input file is ignored and 
        +parameters are generated instead.
        +
        +=item B<-noout>
        +
        +this option inhibits the output of the encoded version of the parameters.
        +
        +=item B<-text>
        +
        +this option prints out the DH parameters in human readable form.
        +
        +=item B<-C>
        +
        +this option converts the parameters into C code. The parameters can then
        +be loaded by calling the B<get_dh>I<numbits>B<()> function.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<dhparam>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 WARNINGS
        +
        +The program B<dhparam> combines the functionality of the programs B<dh> and
        +B<gendh> in previous versions of OpenSSL and SSLeay. The B<dh> and B<gendh>
        +programs are retained for now but may have different purposes in future 
        +versions of OpenSSL.
        +
        +=head1 NOTES
        +
        +PEM format DH parameters use the header and footer lines:
        +
        + -----BEGIN DH PARAMETERS-----
        + -----END DH PARAMETERS-----
        +
        +OpenSSL currently only supports the older PKCS#3 DH, not the newer X9.42
        +DH.
        +
        +This program manipulates DH parameters not keys.
        +
        +=head1 BUGS
        +
        +There should be a way to generate and manipulate DH keys.
        +
        +=head1 SEE ALSO
        +
        +L<dsaparam(1)|dsaparam(1)>
        +
        +=head1 HISTORY
        +
        +The B<dhparam> command was added in OpenSSL 0.9.5.
        +The B<-dsaparam> option was added in OpenSSL 0.9.6.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/dsa.pod b/vendor/openssl/openssl/doc/apps/dsa.pod
        new file mode 100644
        index 000000000..ddbc9327f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/dsa.pod
        @@ -0,0 +1,158 @@
        +=pod
        +
        +=head1 NAME
        +
        +dsa - DSA key processing
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<dsa>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-passin arg>]
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-des>]
        +[B<-des3>]
        +[B<-idea>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-modulus>]
        +[B<-pubin>]
        +[B<-pubout>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<dsa> command processes DSA keys. They can be converted between various
        +forms and their components printed out. B<Note> This command uses the
        +traditional SSLeay compatible format for private key encryption: newer
        +applications should use the more secure PKCS#8 format using the B<pkcs8>
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option with a private key uses
        +an ASN1 DER encoded form of an ASN.1 SEQUENCE consisting of the values of
        +version (currently zero), p, q, g, the public and private key components
        +respectively as ASN.1 INTEGERs. When used with a public key it uses a
        +SubjectPublicKeyInfo structure: it is an error if the key is not DSA.
        +
        +The B<PEM> form is the default format: it consists of the B<DER> format base64
        +encoded with additional header and footer lines. In the case of a private key
        +PKCS#8 format is also accepted.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a key from or standard input if this
        +option is not specified. If the key is encrypted a pass phrase will be
        +prompted for.
        +
        +=item B<-passin arg>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write a key to or standard output by
        +is not specified. If any encryption options are set then a pass phrase will be
        +prompted for. The output filename should B<not> be the same as the input
        +filename.
        +
        +=item B<-passout arg>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-des|-des3|-idea>
        +
        +These options encrypt the private key with the DES, triple DES, or the 
        +IDEA ciphers respectively before outputting it. A pass phrase is prompted for.
        +If none of these options is specified the key is written in plain text. This
        +means that using the B<dsa> utility to read in an encrypted key with no
        +encryption option can be used to remove the pass phrase from a key, or by
        +setting the encryption options it can be use to add or change the pass phrase.
        +These options can only be used with PEM format output files.
        +
        +=item B<-text>
        +
        +prints out the public, private key components and parameters.
        +
        +=item B<-noout>
        +
        +this option prevents output of the encoded version of the key.
        +
        +=item B<-modulus>
        +
        +this option prints out the value of the public key component of the key.
        +
        +=item B<-pubin>
        +
        +by default a private key is read from the input file: with this option a
        +public key is read instead.
        +
        +=item B<-pubout>
        +
        +by default a private key is output. With this option a public
        +key will be output instead. This option is automatically set if the input is
        +a public key.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<dsa>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The PEM private key format uses the header and footer lines:
        +
        + -----BEGIN DSA PRIVATE KEY-----
        + -----END DSA PRIVATE KEY-----
        +
        +The PEM public key format uses the header and footer lines:
        +
        + -----BEGIN PUBLIC KEY-----
        + -----END PUBLIC KEY-----
        +
        +=head1 EXAMPLES
        +
        +To remove the pass phrase on a DSA private key:
        +
        + openssl dsa -in key.pem -out keyout.pem
        +
        +To encrypt a private key using triple DES:
        +
        + openssl dsa -in key.pem -des3 -out keyout.pem
        +
        +To convert a private key from PEM to DER format: 
        +
        + openssl dsa -in key.pem -outform DER -out keyout.der
        +
        +To print out the components of a private key to standard output:
        +
        + openssl dsa -in key.pem -text -noout
        +
        +To just output the public part of a private key:
        +
        + openssl dsa -in key.pem -pubout -out pubkey.pem
        +
        +=head1 SEE ALSO
        +
        +L<dsaparam(1)|dsaparam(1)>, L<gendsa(1)|gendsa(1)>, L<rsa(1)|rsa(1)>,
        +L<genrsa(1)|genrsa(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/dsaparam.pod b/vendor/openssl/openssl/doc/apps/dsaparam.pod
        new file mode 100644
        index 000000000..ba5ec4d72
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/dsaparam.pod
        @@ -0,0 +1,110 @@
        +=pod
        +
        +=head1 NAME
        +
        +dsaparam - DSA parameter manipulation and generation
        +
        +=head1 SYNOPSIS
        +
        +B<openssl dsaparam>
        +[B<-inform DER|PEM>]
        +[B<-outform DER|PEM>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-noout>]
        +[B<-text>]
        +[B<-C>]
        +[B<-rand file(s)>]
        +[B<-genkey>]
        +[B<-engine id>]
        +[B<numbits>]
        +
        +=head1 DESCRIPTION
        +
        +This command is used to manipulate or generate DSA parameter files.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option uses an ASN1 DER encoded
        +form compatible with RFC2459 (PKIX) DSS-Parms that is a SEQUENCE consisting
        +of p, q and g respectively. The PEM form is the default format: it consists
        +of the B<DER> format base64 encoded with additional header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read parameters from or standard input if
        +this option is not specified. If the B<numbits> parameter is included then
        +this option will be ignored.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename parameters to. Standard output is used
        +if this option is not present. The output filename should B<not> be the same
        +as the input filename.
        +
        +=item B<-noout>
        +
        +this option inhibits the output of the encoded version of the parameters.
        +
        +=item B<-text>
        +
        +this option prints out the DSA parameters in human readable form.
        +
        +=item B<-C>
        +
        +this option converts the parameters into C code. The parameters can then
        +be loaded by calling the B<get_dsaXXX()> function.
        +
        +=item B<-genkey>
        +
        +this option will generate a DSA either using the specified or generated
        +parameters.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<numbits>
        +
        +this option specifies that a parameter set should be generated of size
        +B<numbits>. It must be the last option. If this option is included then
        +the input file (if any) is ignored.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<dsaparam>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 NOTES
        +
        +PEM format DSA parameters use the header and footer lines:
        +
        + -----BEGIN DSA PARAMETERS-----
        + -----END DSA PARAMETERS-----
        +
        +DSA parameter generation is a slow process and as a result the same set of
        +DSA parameters is often used to generate several distinct keys.
        +
        +=head1 SEE ALSO
        +
        +L<gendsa(1)|gendsa(1)>, L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>,
        +L<rsa(1)|rsa(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/ec.pod b/vendor/openssl/openssl/doc/apps/ec.pod
        new file mode 100644
        index 000000000..ba6dc4689
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/ec.pod
        @@ -0,0 +1,190 @@
        +=pod
        +
        +=head1 NAME
        +
        +ec - EC key processing
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<ec>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-passin arg>]
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-des>]
        +[B<-des3>]
        +[B<-idea>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-param_out>]
        +[B<-pubin>]
        +[B<-pubout>]
        +[B<-conv_form arg>]
        +[B<-param_enc arg>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<ec> command processes EC keys. They can be converted between various
        +forms and their components printed out. B<Note> OpenSSL uses the 
        +private key format specified in 'SEC 1: Elliptic Curve Cryptography'
        +(http://www.secg.org/). To convert a OpenSSL EC private key into the
        +PKCS#8 private key format use the B<pkcs8> command.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option with a private key uses
        +an ASN.1 DER encoded SEC1 private key. When used with a public key it
        +uses the SubjectPublicKeyInfo structur as specified in RFC 3280.
        +The B<PEM> form is the default format: it consists of the B<DER> format base64
        +encoded with additional header and footer lines. In the case of a private key
        +PKCS#8 format is also accepted.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a key from or standard input if this
        +option is not specified. If the key is encrypted a pass phrase will be
        +prompted for.
        +
        +=item B<-passin arg>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write a key to or standard output by
        +is not specified. If any encryption options are set then a pass phrase will be
        +prompted for. The output filename should B<not> be the same as the input
        +filename.
        +
        +=item B<-passout arg>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-des|-des3|-idea>
        +
        +These options encrypt the private key with the DES, triple DES, IDEA or 
        +any other cipher supported by OpenSSL before outputting it. A pass phrase is
        +prompted for.
        +If none of these options is specified the key is written in plain text. This
        +means that using the B<ec> utility to read in an encrypted key with no
        +encryption option can be used to remove the pass phrase from a key, or by
        +setting the encryption options it can be use to add or change the pass phrase.
        +These options can only be used with PEM format output files.
        +
        +=item B<-text>
        +
        +prints out the public, private key components and parameters.
        +
        +=item B<-noout>
        +
        +this option prevents output of the encoded version of the key.
        +
        +=item B<-modulus>
        +
        +this option prints out the value of the public key component of the key.
        +
        +=item B<-pubin>
        +
        +by default a private key is read from the input file: with this option a
        +public key is read instead.
        +
        +=item B<-pubout>
        +
        +by default a private key is output. With this option a public
        +key will be output instead. This option is automatically set if the input is
        +a public key.
        +
        +=item B<-conv_form>
        +
        +This specifies how the points on the elliptic curve are converted
        +into octet strings. Possible values are: B<compressed> (the default
        +value), B<uncompressed> and B<hybrid>. For more information regarding
        +the point conversion forms please read the X9.62 standard.
        +B<Note> Due to patent issues the B<compressed> option is disabled
        +by default for binary curves and can be enabled by defining
        +the preprocessor macro B<OPENSSL_EC_BIN_PT_COMP> at compile time.
        +
        +=item B<-param_enc arg>
        +
        +This specifies how the elliptic curve parameters are encoded.
        +Possible value are: B<named_curve>, i.e. the ec parameters are
        +specified by a OID, or B<explicit> where the ec parameters are
        +explicitly given (see RFC 3279 for the definition of the 
        +EC parameters structures). The default value is B<named_curve>.
        +B<Note> the B<implicitlyCA> alternative ,as specified in RFC 3279,
        +is currently not implemented in OpenSSL.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<ec>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The PEM private key format uses the header and footer lines:
        +
        + -----BEGIN EC PRIVATE KEY-----
        + -----END EC PRIVATE KEY-----
        +
        +The PEM public key format uses the header and footer lines:
        +
        + -----BEGIN PUBLIC KEY-----
        + -----END PUBLIC KEY-----
        +
        +=head1 EXAMPLES
        +
        +To encrypt a private key using triple DES:
        +
        + openssl ec -in key.pem -des3 -out keyout.pem
        +
        +To convert a private key from PEM to DER format: 
        +
        + openssl ec -in key.pem -outform DER -out keyout.der
        +
        +To print out the components of a private key to standard output:
        +
        + openssl ec -in key.pem -text -noout
        +
        +To just output the public part of a private key:
        +
        + openssl ec -in key.pem -pubout -out pubkey.pem
        +
        +To change the parameters encoding to B<explicit>:
        +
        + openssl ec -in key.pem -param_enc explicit -out keyout.pem
        +
        +To change the point conversion form to B<compressed>:
        +
        + openssl ec -in key.pem -conv_form compressed -out keyout.pem
        +
        +=head1 SEE ALSO
        +
        +L<ecparam(1)|ecparam(1)>, L<dsa(1)|dsa(1)>, L<rsa(1)|rsa(1)>
        +
        +=head1 HISTORY
        +
        +The ec command was first introduced in OpenSSL 0.9.8.
        +
        +=head1 AUTHOR
        +
        +Nils Larsch for the OpenSSL project (http://www.openssl.org).
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/ecparam.pod b/vendor/openssl/openssl/doc/apps/ecparam.pod
        new file mode 100644
        index 000000000..788c074d7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/ecparam.pod
        @@ -0,0 +1,179 @@
        +=pod
        +
        +=head1 NAME
        +
        +ecparam - EC parameter manipulation and generation
        +
        +=head1 SYNOPSIS
        +
        +B<openssl ecparam>
        +[B<-inform DER|PEM>]
        +[B<-outform DER|PEM>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-noout>]
        +[B<-text>]
        +[B<-C>]
        +[B<-check>]
        +[B<-name arg>]
        +[B<-list_curve>]
        +[B<-conv_form arg>]
        +[B<-param_enc arg>]
        +[B<-no_seed>]
        +[B<-rand file(s)>]
        +[B<-genkey>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +This command is used to manipulate or generate EC parameter files.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option uses an ASN.1 DER encoded
        +form compatible with RFC 3279 EcpkParameters. The PEM form is the default
        +format: it consists of the B<DER> format base64 encoded with additional 
        +header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read parameters from or standard input if
        +this option is not specified.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename parameters to. Standard output is used
        +if this option is not present. The output filename should B<not> be the same
        +as the input filename.
        +
        +=item B<-noout>
        +
        +This option inhibits the output of the encoded version of the parameters.
        +
        +=item B<-text>
        +
        +This option prints out the EC parameters in human readable form.
        +
        +=item B<-C>
        +
        +This option converts the EC parameters into C code. The parameters can then
        +be loaded by calling the B<get_ec_group_XXX()> function.
        +
        +=item B<-check>
        +
        +Validate the elliptic curve parameters.
        +
        +=item B<-name arg>
        +
        +Use the EC parameters with the specified 'short' name. Use B<-list_curves>
        +to get a list of all currently implemented EC parameters.
        +
        +=item B<-list_curves>
        +
        +If this options is specified B<ecparam> will print out a list of all
        +currently implemented EC parameters names and exit.
        +
        +=item B<-conv_form>
        +
        +This specifies how the points on the elliptic curve are converted
        +into octet strings. Possible values are: B<compressed> (the default
        +value), B<uncompressed> and B<hybrid>. For more information regarding
        +the point conversion forms please read the X9.62 standard.
        +B<Note> Due to patent issues the B<compressed> option is disabled
        +by default for binary curves and can be enabled by defining
        +the preprocessor macro B<OPENSSL_EC_BIN_PT_COMP> at compile time.
        +
        +=item B<-param_enc arg>
        +
        +This specifies how the elliptic curve parameters are encoded.
        +Possible value are: B<named_curve>, i.e. the ec parameters are
        +specified by a OID, or B<explicit> where the ec parameters are
        +explicitly given (see RFC 3279 for the definition of the 
        +EC parameters structures). The default value is B<named_curve>.
        +B<Note> the B<implicitlyCA> alternative ,as specified in RFC 3279,
        +is currently not implemented in OpenSSL.
        +
        +=item B<-no_seed>
        +
        +This option inhibits that the 'seed' for the parameter generation
        +is included in the ECParameters structure (see RFC 3279).
        +
        +=item B<-genkey>
        +
        +This option will generate a EC private key using the specified parameters.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<ecparam>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 NOTES
        +
        +PEM format EC parameters use the header and footer lines:
        +
        + -----BEGIN EC PARAMETERS-----
        + -----END EC PARAMETERS-----
        +
        +OpenSSL is currently not able to generate new groups and therefore
        +B<ecparam> can only create EC parameters from known (named) curves. 
        +
        +=head1 EXAMPLES
        +
        +To create EC parameters with the group 'prime192v1':
        +
        +  openssl ecparam -out ec_param.pem -name prime192v1
        +
        +To create EC parameters with explicit parameters:
        +
        +  openssl ecparam -out ec_param.pem -name prime192v1 -param_enc explicit
        +
        +To validate given EC parameters:
        +
        +  openssl ecparam -in ec_param.pem -check
        +
        +To create EC parameters and a private key:
        +
        +  openssl ecparam -out ec_key.pem -name prime192v1 -genkey
        +
        +To change the point encoding to 'compressed':
        +
        +  openssl ecparam -in ec_in.pem -out ec_out.pem -conv_form compressed
        +
        +To print out the EC parameters to standard output:
        +
        +  openssl ecparam -in ec_param.pem -noout -text
        +
        +=head1 SEE ALSO
        +
        +L<ec(1)|ec(1)>, L<dsaparam(1)|dsaparam(1)>
        +
        +=head1 HISTORY
        +
        +The ecparam command was first introduced in OpenSSL 0.9.8.
        +
        +=head1 AUTHOR
        +
        +Nils Larsch for the OpenSSL project (http://www.openssl.org)
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/enc.pod b/vendor/openssl/openssl/doc/apps/enc.pod
        new file mode 100644
        index 000000000..3dee4ed99
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/enc.pod
        @@ -0,0 +1,329 @@
        +=pod
        +
        +=head1 NAME
        +
        +enc - symmetric cipher routines
        +
        +=head1 SYNOPSIS
        +
        +B<openssl enc -ciphername>
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-pass arg>]
        +[B<-e>]
        +[B<-d>]
        +[B<-a/-base64>]
        +[B<-A>]
        +[B<-k password>]
        +[B<-kfile filename>]
        +[B<-K key>]
        +[B<-iv IV>]
        +[B<-S salt>]
        +[B<-salt>]
        +[B<-nosalt>]
        +[B<-z>]
        +[B<-md>]
        +[B<-p>]
        +[B<-P>]
        +[B<-bufsize number>]
        +[B<-nopad>]
        +[B<-debug>]
        +[B<-none>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The symmetric cipher commands allow data to be encrypted or decrypted
        +using various block and stream ciphers using keys based on passwords
        +or explicitly provided. Base64 encoding or decoding can also be performed
        +either by itself or in addition to the encryption or decryption.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-in filename>
        +
        +the input filename, standard input by default.
        +
        +=item B<-out filename>
        +
        +the output filename, standard output by default.
        +
        +=item B<-pass arg>
        +
        +the password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-salt>
        +
        +use a salt in the key derivation routines. This is the default.
        +
        +=item B<-nosalt>
        +
        +don't use a salt in the key derivation routines. This option B<SHOULD NOT> be
        +used except for test purposes or compatibility with ancient versions of OpenSSL
        +and SSLeay.
        +
        +=item B<-e>
        +
        +encrypt the input data: this is the default.
        +
        +=item B<-d>
        +
        +decrypt the input data.
        +
        +=item B<-a>
        +
        +base64 process the data. This means that if encryption is taking place
        +the data is base64 encoded after encryption. If decryption is set then
        +the input data is base64 decoded before being decrypted.
        +
        +=item B<-base64>
        +
        +same as B<-a>
        +
        +=item B<-A>
        +
        +if the B<-a> option is set then base64 process the data on one line.
        +
        +=item B<-k password>
        +
        +the password to derive the key from. This is for compatibility with previous
        +versions of OpenSSL. Superseded by the B<-pass> argument.
        +
        +=item B<-kfile filename>
        +
        +read the password to derive the key from the first line of B<filename>.
        +This is for compatibility with previous versions of OpenSSL. Superseded by
        +the B<-pass> argument.
        +
        +=item B<-nosalt>
        +
        +do not use a salt 
        +
        +=item B<-salt>
        +
        +use salt (randomly generated or provide with B<-S> option) when
        +encrypting (this is the default).
        +
        +=item B<-S salt>
        +
        +the actual salt to use: this must be represented as a string of hex digits.
        +
        +=item B<-K key>
        +
        +the actual key to use: this must be represented as a string comprised only
        +of hex digits. If only the key is specified, the IV must additionally specified
        +using the B<-iv> option. When both a key and a password are specified, the
        +key given with the B<-K> option will be used and the IV generated from the
        +password will be taken. It probably does not make much sense to specify
        +both key and password.
        +
        +=item B<-iv IV>
        +
        +the actual IV to use: this must be represented as a string comprised only
        +of hex digits. When only the key is specified using the B<-K> option, the
        +IV must explicitly be defined. When a password is being specified using
        +one of the other options, the IV is generated from this password.
        +
        +=item B<-p>
        +
        +print out the key and IV used.
        +
        +=item B<-P>
        +
        +print out the key and IV used then immediately exit: don't do any encryption
        +or decryption.
        +
        +=item B<-bufsize number>
        +
        +set the buffer size for I/O
        +
        +=item B<-nopad>
        +
        +disable standard block padding
        +
        +=item B<-debug>
        +
        +debug the BIOs used for I/O.
        +
        +=item B<-z>
        +
        +Compress or decompress clear text using zlib before encryption or after
        +decryption. This option exists only if OpenSSL with compiled with zlib
        +or zlib-dynamic option.
        +
        +=item B<-none>
        +
        +Use NULL cipher (no encryption or decryption of input).
        +
        +=back
        +
        +=head1 NOTES
        +
        +The program can be called either as B<openssl ciphername> or
        +B<openssl enc -ciphername>. But the first form doesn't work with
        +engine-provided ciphers, because this form is processed before the
        +configuration file is read and any ENGINEs loaded.
        +
        +Engines which provide entirely new encryption algorithms (such as ccgost
        +engine which provides gost89 algorithm) should be configured in the
        +configuration file. Engines, specified in the command line using -engine
        +options can only be used for hadrware-assisted implementations of
        +ciphers, which are supported by OpenSSL core or other engine, specified
        +in the configuration file.
        +
        +When enc command lists supported ciphers, ciphers provided by engines,
        +specified in the configuration files are listed too.
        +
        +A password will be prompted for to derive the key and IV if necessary.
        +
        +The B<-salt> option should B<ALWAYS> be used if the key is being derived
        +from a password unless you want compatibility with previous versions of
        +OpenSSL and SSLeay.
        +
        +Without the B<-salt> option it is possible to perform efficient dictionary
        +attacks on the password and to attack stream cipher encrypted data. The reason
        +for this is that without the salt the same password always generates the same
        +encryption key. When the salt is being used the first eight bytes of the
        +encrypted data are reserved for the salt: it is generated at random when
        +encrypting a file and read from the encrypted file when it is decrypted.
        +
        +Some of the ciphers do not have large keys and others have security
        +implications if not used correctly. A beginner is advised to just use
        +a strong block cipher in CBC mode such as bf or des3.
        +
        +All the block ciphers normally use PKCS#5 padding also known as standard block
        +padding: this allows a rudimentary integrity or password check to be
        +performed. However since the chance of random data passing the test is
        +better than 1 in 256 it isn't a very good test.
        +
        +If padding is disabled then the input data must be a multiple of the cipher
        +block length.
        +
        +All RC2 ciphers have the same key and effective key length.
        +
        +Blowfish and RC5 algorithms use a 128 bit key.
        +
        +=head1 SUPPORTED CIPHERS
        +
        +Note that some of these ciphers can be disabled at compile time
        +and some are available only if an appropriate engine is configured
        +in the configuration file. The output of the B<enc> command run with
        +unsupported options (for example B<openssl enc -help>) includes a
        +list of ciphers, supported by your versesion of OpenSSL, including
        +ones provided by configured engines.
        +
        +
        + base64             Base 64
        +
        + bf-cbc             Blowfish in CBC mode
        + bf                 Alias for bf-cbc
        + bf-cfb             Blowfish in CFB mode
        + bf-ecb             Blowfish in ECB mode
        + bf-ofb             Blowfish in OFB mode
        +
        + cast-cbc           CAST in CBC mode
        + cast               Alias for cast-cbc
        + cast5-cbc          CAST5 in CBC mode
        + cast5-cfb          CAST5 in CFB mode
        + cast5-ecb          CAST5 in ECB mode
        + cast5-ofb          CAST5 in OFB mode
        +
        + des-cbc            DES in CBC mode
        + des                Alias for des-cbc
        + des-cfb            DES in CBC mode
        + des-ofb            DES in OFB mode
        + des-ecb            DES in ECB mode
        +
        + des-ede-cbc        Two key triple DES EDE in CBC mode
        + des-ede            Two key triple DES EDE in ECB mode
        + des-ede-cfb        Two key triple DES EDE in CFB mode
        + des-ede-ofb        Two key triple DES EDE in OFB mode
        +
        + des-ede3-cbc       Three key triple DES EDE in CBC mode
        + des-ede3           Three key triple DES EDE in ECB mode
        + des3               Alias for des-ede3-cbc
        + des-ede3-cfb       Three key triple DES EDE CFB mode
        + des-ede3-ofb       Three key triple DES EDE in OFB mode
        +
        + desx               DESX algorithm.
        +
        + gost89             GOST 28147-89 in CFB mode (provided by ccgost engine)
        + gost89-cnt        `GOST 28147-89 in CNT mode (provided by ccgost engine) 
        +
        + idea-cbc           IDEA algorithm in CBC mode
        + idea               same as idea-cbc
        + idea-cfb           IDEA in CFB mode
        + idea-ecb           IDEA in ECB mode
        + idea-ofb           IDEA in OFB mode
        +
        + rc2-cbc            128 bit RC2 in CBC mode
        + rc2                Alias for rc2-cbc
        + rc2-cfb            128 bit RC2 in CFB mode
        + rc2-ecb            128 bit RC2 in ECB mode
        + rc2-ofb            128 bit RC2 in OFB mode
        + rc2-64-cbc         64 bit RC2 in CBC mode
        + rc2-40-cbc         40 bit RC2 in CBC mode
        +
        + rc4                128 bit RC4
        + rc4-64             64 bit RC4
        + rc4-40             40 bit RC4
        +
        + rc5-cbc            RC5 cipher in CBC mode
        + rc5                Alias for rc5-cbc
        + rc5-cfb            RC5 cipher in CFB mode
        + rc5-ecb            RC5 cipher in ECB mode
        + rc5-ofb            RC5 cipher in OFB mode
        +
        + aes-[128|192|256]-cbc	128/192/256 bit AES in CBC mode
        + aes-[128|192|256]	Alias for aes-[128|192|256]-cbc
        + aes-[128|192|256]-cfb	128/192/256 bit AES in 128 bit CFB mode
        + aes-[128|192|256]-cfb1	128/192/256 bit AES in 1 bit CFB mode
        + aes-[128|192|256]-cfb8	128/192/256 bit AES in 8 bit CFB mode
        + aes-[128|192|256]-ecb	128/192/256 bit AES in ECB mode
        + aes-[128|192|256]-ofb	128/192/256 bit AES in OFB mode
        +
        +=head1 EXAMPLES
        +
        +Just base64 encode a binary file:
        +
        + openssl base64 -in file.bin -out file.b64
        +
        +Decode the same file
        +
        + openssl base64 -d -in file.b64 -out file.bin 
        +
        +Encrypt a file using triple DES in CBC mode using a prompted password:
        +
        + openssl des3 -salt -in file.txt -out file.des3 
        +
        +Decrypt a file using a supplied password:
        +
        + openssl des3 -d -salt -in file.des3 -out file.txt -k mypassword
        +
        +Encrypt a file then base64 encode it (so it can be sent via mail for example)
        +using Blowfish in CBC mode:
        +
        + openssl bf -a -salt -in file.txt -out file.bf
        +
        +Base64 decode a file then decrypt it:
        +
        + openssl bf -d -salt -a -in file.bf -out file.txt
        +
        +Decrypt some data using a supplied 40 bit RC4 key:
        +
        + openssl rc4-40 -in file.rc4 -out file.txt -K 0102030405
        +
        +=head1 BUGS
        +
        +The B<-A> option when used with large files doesn't work properly.
        +
        +There should be an option to allow an iteration count to be included.
        +
        +The B<enc> program only supports a fixed number of algorithms with
        +certain parameters. So if, for example, you want to use RC2 with a
        +76 bit key or RC4 with an 84 bit key you can't use this program.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/errstr.pod b/vendor/openssl/openssl/doc/apps/errstr.pod
        new file mode 100644
        index 000000000..b3c6ccfc9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/errstr.pod
        @@ -0,0 +1,39 @@
        +=pod
        +
        +=head1 NAME
        +
        +errstr - lookup error codes
        +
        +=head1 SYNOPSIS
        +
        +B<openssl errstr error_code>
        +
        +=head1 DESCRIPTION
        +
        +Sometimes an application will not load error message and only
        +numerical forms will be available. The B<errstr> utility can be used to 
        +display the meaning of the hex code. The hex code is the hex digits after the
        +second colon.
        +
        +=head1 EXAMPLE
        +
        +The error code:
        +
        + 27594:error:2006D080:lib(32):func(109):reason(128):bss_file.c:107:
        +
        +can be displayed with:
        + 
        + openssl errstr 2006D080
        +
        +to produce the error message:
        +
        + error:2006D080:BIO routines:BIO_new_file:no such file
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>,
        +L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
        +L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
        +
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/gendsa.pod b/vendor/openssl/openssl/doc/apps/gendsa.pod
        new file mode 100644
        index 000000000..8c7f114ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/gendsa.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        +gendsa - generate a DSA private key from a set of parameters
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<gendsa>
        +[B<-out filename>]
        +[B<-des>]
        +[B<-des3>]
        +[B<-idea>]
        +[B<-rand file(s)>]
        +[B<-engine id>]
        +[B<paramfile>]
        +
        +=head1 DESCRIPTION
        +
        +The B<gendsa> command generates a DSA private key from a DSA parameter file
        +(which will be typically generated by the B<openssl dsaparam> command).
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-des|-des3|-idea>
        +
        +These options encrypt the private key with the DES, triple DES, or the 
        +IDEA ciphers respectively before outputting it. A pass phrase is prompted for.
        +If none of these options is specified no encryption is used.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<gendsa>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<paramfile>
        +
        +This option specifies the DSA parameter file to use. The parameters in this
        +file determine the size of the private key. DSA parameters can be generated
        +and examined using the B<openssl dsaparam> command.
        +
        +=back
        +
        +=head1 NOTES
        +
        +DSA key generation is little more than random number generation so it is
        +much quicker that RSA key generation for example.
        +
        +=head1 SEE ALSO
        +
        +L<dsaparam(1)|dsaparam(1)>, L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>,
        +L<rsa(1)|rsa(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/genpkey.pod b/vendor/openssl/openssl/doc/apps/genpkey.pod
        new file mode 100644
        index 000000000..c74d097fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/genpkey.pod
        @@ -0,0 +1,215 @@
        +=pod
        +
        +=head1 NAME
        +
        +genpkey - generate a private key
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<genpkey>
        +[B<-out filename>]
        +[B<-outform PEM|DER>]
        +[B<-pass arg>]
        +[B<-cipher>]
        +[B<-engine id>]
        +[B<-paramfile file>]
        +[B<-algorithm alg>]
        +[B<-pkeyopt opt:value>]
        +[B<-genparam>]
        +[B<-text>]
        +
        +=head1 DESCRIPTION
        +
        +The B<genpkey> command generates a private key.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-out filename>
        +
        +the output filename. If this argument is not specified then standard output is
        +used.  
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format DER or PEM.
        +
        +=item B<-pass arg>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-cipher>
        +
        +This option encrypts the private key with the supplied cipher. Any algorithm
        +name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<genpkey>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms. If used this option should precede all other
        +options.
        +
        +=item B<-algorithm alg>
        +
        +public key algorithm to use such as RSA, DSA or DH. If used this option must
        +precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm>
        +are mutually exclusive.
        +
        +=item B<-pkeyopt opt:value>
        +
        +set the public key algorithm option B<opt> to B<value>. The precise set of
        +options supported depends on the public key algorithm used and its
        +implementation. See B<KEY GENERATION OPTIONS> below for more details.
        +
        +=item B<-genparam>
        +
        +generate a set of parameters instead of a private key. If used this option must
        +precede and B<-algorithm>, B<-paramfile> or B<-pkeyopt> options.
        +
        +=item B<-paramfile filename>
        +
        +Some public key algorithms generate a private key based on a set of parameters.
        +They can be supplied using this option. If this option is used the public key
        +algorithm used is determined by the parameters. If used this option must
        +precede and B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm>
        +are mutually exclusive.
        +
        +=item B<-text>
        +
        +Print an (unencrypted) text representation of private and public keys and
        +parameters along with the PEM or DER structure.
        +
        +=back
        +
        +=head1 KEY GENERATION OPTIONS
        +
        +The options supported by each algorith and indeed each implementation of an
        +algorithm can vary. The options for the OpenSSL implementations are detailed
        +below.
        +
        +=head1 RSA KEY GENERATION OPTIONS
        +
        +=over 4
        +
        +=item B<rsa_keygen_bits:numbits>
        +
        +The number of bits in the generated key. If not specified 1024 is used.
        +
        +=item B<rsa_keygen_pubexp:value>
        +
        +The RSA public exponent value. This can be a large decimal or
        +hexadecimal value if preceded by B<0x>. Default value is 65537.
        +
        +=back
        +
        +=head1 DSA PARAMETER GENERATION OPTIONS
        +
        +=over 4
        +
        +=item B<dsa_paramgen_bits:numbits>
        +
        +The number of bits in the generated parameters. If not specified 1024 is used.
        +
        +=back
        +
        +=head1 DH PARAMETER GENERATION OPTIONS
        +
        +=over 4
        +
        +=item B<dh_paramgen_prime_len:numbits>
        +
        +The number of bits in the prime parameter B<p>.
        +
        +=item B<dh_paramgen_generator:value>
        +
        +The value to use for the generator B<g>.
        +
        +=back
        +
        +=head1 EC PARAMETER GENERATION OPTIONS
        +
        +=over 4
        +
        +=item B<ec_paramgen_curve:curve>
        +
        +the EC curve to use.
        +
        +=back
        +
        +=head1 GOST2001 KEY GENERATION AND PARAMETER OPTIONS
        +
        +Gost 2001 support is not enabled by default. To enable this algorithm,
        +one should load the ccgost engine in the OpenSSL configuration file.
        +See README.gost file in the engines/ccgost directiry of the source
        +distribution for more details.
        +
        +Use of a parameter file for the GOST R 34.10 algorithm is optional.
        +Parameters can be specified during key generation directly as well as
        +during generation of parameter file.
        +
        +=over 4
        +
        +=item B<paramset:name>
        +
        +Specifies GOST R 34.10-2001 parameter set according to RFC 4357.
        +Parameter set can be specified using abbreviated name, object short name or
        +numeric OID. Following parameter sets are supported:
        +
        +  paramset   OID               Usage
        +  A          1.2.643.2.2.35.1  Signature
        +  B          1.2.643.2.2.35.2  Signature
        +  C          1.2.643.2.2.35.3  Signature
        +  XA         1.2.643.2.2.36.0  Key exchange
        +  XB         1.2.643.2.2.36.1  Key exchange
        +  test       1.2.643.2.2.35.0  Test purposes
        +
        +=back
        +
        +
        +
        +=head1 NOTES
        +
        +The use of the genpkey program is encouraged over the algorithm specific
        +utilities because additional algorithm options and ENGINE provided algorithms
        +can be used.
        +
        +=head1 EXAMPLES
        +
        +Generate an RSA private key using default parameters:
        +
        + openssl genpkey -algorithm RSA -out key.pem 
        +
        +Encrypt output private key using 128 bit AES and the passphrase "hello":
        +
        + openssl genpkey -algorithm RSA -out key.pem -aes-128-cbc -pass pass:hello
        +
        +Generate a 2048 bit RSA key using 3 as the public exponent:
        +
        + openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048 \
        + 						-pkeyopt rsa_keygen_pubexp:3
        +
        +Generate 1024 bit DSA parameters:
        +
        + openssl genpkey -genparam -algorithm DSA -out dsap.pem \
        +						-pkeyopt dsa_paramgen_bits:1024
        +
        +Generate DSA key from parameters:
        +
        + openssl genpkey -paramfile dsap.pem -out dsakey.pem 
        +
        +Generate 1024 bit DH parameters:
        +
        + openssl genpkey -genparam -algorithm DH -out dhp.pem \
        +					-pkeyopt dh_paramgen_prime_len:1024
        +
        +Generate DH key from parameters:
        +
        + openssl genpkey -paramfile dhp.pem -out dhkey.pem 
        +
        +
        +=cut
        +
        diff --git a/vendor/openssl/openssl/doc/apps/genrsa.pod b/vendor/openssl/openssl/doc/apps/genrsa.pod
        new file mode 100644
        index 000000000..7dcac2a77
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/genrsa.pod
        @@ -0,0 +1,96 @@
        +=pod
        +
        +=head1 NAME
        +
        +genrsa - generate an RSA private key
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<genrsa>
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-des>]
        +[B<-des3>]
        +[B<-idea>]
        +[B<-f4>]
        +[B<-3>]
        +[B<-rand file(s)>]
        +[B<-engine id>]
        +[B<numbits>]
        +
        +=head1 DESCRIPTION
        +
        +The B<genrsa> command generates an RSA private key.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-out filename>
        +
        +the output filename. If this argument is not specified then standard output is
        +used.  
        +
        +=item B<-passout arg>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-des|-des3|-idea>
        +
        +These options encrypt the private key with the DES, triple DES, or the 
        +IDEA ciphers respectively before outputting it. If none of these options is
        +specified no encryption is used. If encryption is used a pass phrase is prompted
        +for if it is not supplied via the B<-passout> argument.
        +
        +=item B<-F4|-3>
        +
        +the public exponent to use, either 65537 or 3. The default is 65537.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<genrsa>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<numbits>
        +
        +the size of the private key to generate in bits. This must be the last option
        +specified. The default is 512.
        +
        +=back
        +
        +=head1 NOTES
        +
        +RSA private key generation essentially involves the generation of two prime
        +numbers. When generating a private key various symbols will be output to
        +indicate the progress of the generation. A B<.> represents each number which
        +has passed an initial sieve test, B<+> means a number has passed a single
        +round of the Miller-Rabin primality test. A newline means that the number has
        +passed all the prime tests (the actual number depends on the key size).
        +
        +Because key generation is a random process the time taken to generate a key
        +may vary somewhat.
        +
        +=head1 BUGS
        +
        +A quirk of the prime generation algorithm is that it cannot generate small
        +primes. Therefore the number of bits should not be less that 64. For typical
        +private keys this will not matter because for security reasons they will
        +be much larger (typically 1024 bits).
        +
        +=head1 SEE ALSO
        +
        +L<gendsa(1)|gendsa(1)>
        +
        +=cut
        +
        diff --git a/vendor/openssl/openssl/doc/apps/nseq.pod b/vendor/openssl/openssl/doc/apps/nseq.pod
        new file mode 100644
        index 000000000..989c3108f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/nseq.pod
        @@ -0,0 +1,70 @@
        +=pod
        +
        +=head1 NAME
        +
        +nseq - create or examine a netscape certificate sequence
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<nseq>
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-toseq>]
        +
        +=head1 DESCRIPTION
        +
        +The B<nseq> command takes a file containing a Netscape certificate
        +sequence and prints out the certificates contained in it or takes a
        +file of certificates and converts it into a Netscape certificate
        +sequence.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read or standard input if this
        +option is not specified.
        +
        +=item B<-out filename>
        +
        +specifies the output filename or standard output by default.
        +
        +=item B<-toseq>
        +
        +normally a Netscape certificate sequence will be input and the output
        +is the certificates contained in it. With the B<-toseq> option the
        +situation is reversed: a Netscape certificate sequence is created from
        +a file of certificates.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Output the certificates in a Netscape certificate sequence
        +
        + openssl nseq -in nseq.pem -out certs.pem
        +
        +Create a Netscape certificate sequence
        +
        + openssl nseq -in certs.pem -toseq -out nseq.pem
        +
        +=head1 NOTES
        +
        +The B<PEM> encoded form uses the same headers and footers as a certificate:
        +
        + -----BEGIN CERTIFICATE-----
        + -----END CERTIFICATE-----
        +
        +A Netscape certificate sequence is a Netscape specific form that can be sent
        +to browsers as an alternative to the standard PKCS#7 format when several
        +certificates are sent to the browser: for example during certificate enrollment.
        +It is used by Netscape certificate server for example.
        +
        +=head1 BUGS
        +
        +This program needs a few more options: like allowing DER or PEM input and
        +output files and allowing multiple certificate files to be used.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/ocsp.pod b/vendor/openssl/openssl/doc/apps/ocsp.pod
        new file mode 100644
        index 000000000..af2e12e41
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/ocsp.pod
        @@ -0,0 +1,371 @@
        +=pod
        +
        +=head1 NAME
        +
        +ocsp - Online Certificate Status Protocol utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<ocsp>
        +[B<-out file>]
        +[B<-issuer file>]
        +[B<-cert file>]
        +[B<-serial n>]
        +[B<-signer file>]
        +[B<-signkey file>]
        +[B<-sign_other file>]
        +[B<-no_certs>]
        +[B<-req_text>]
        +[B<-resp_text>]
        +[B<-text>]
        +[B<-reqout file>]
        +[B<-respout file>]
        +[B<-reqin file>]
        +[B<-respin file>]
        +[B<-nonce>]
        +[B<-no_nonce>]
        +[B<-url URL>]
        +[B<-host host:n>]
        +[B<-path>]
        +[B<-CApath dir>]
        +[B<-CAfile file>]
        +[B<-VAfile file>]
        +[B<-validity_period n>]
        +[B<-status_age n>]
        +[B<-noverify>]
        +[B<-verify_other file>]
        +[B<-trust_other>]
        +[B<-no_intern>]
        +[B<-no_signature_verify>]
        +[B<-no_cert_verify>]
        +[B<-no_chain>]
        +[B<-no_cert_checks>]
        +[B<-port num>]
        +[B<-index file>]
        +[B<-CA file>]
        +[B<-rsigner file>]
        +[B<-rkey file>]
        +[B<-rother file>]
        +[B<-resp_no_certs>]
        +[B<-nmin n>]
        +[B<-ndays n>]
        +[B<-resp_key_id>]
        +[B<-nrequest n>]
        +[B<-md5|-sha1|...>]
        +
        +=head1 DESCRIPTION
        +
        +The Online Certificate Status Protocol (OCSP) enables applications to
        +determine the (revocation) state of an identified certificate (RFC 2560).
        +
        +The B<ocsp> command performs many common OCSP tasks. It can be used
        +to print out requests and responses, create requests and send queries
        +to an OCSP responder and behave like a mini OCSP server itself.
        +
        +=head1 OCSP CLIENT OPTIONS
        +
        +=over 4
        +
        +=item B<-out filename>
        +
        +specify output filename, default is standard output.
        +
        +=item B<-issuer filename>
        +
        +This specifies the current issuer certificate. This option can be used
        +multiple times. The certificate specified in B<filename> must be in
        +PEM format. This option B<MUST> come before any B<-cert> options.
        +
        +=item B<-cert filename>
        +
        +Add the certificate B<filename> to the request. The issuer certificate
        +is taken from the previous B<issuer> option, or an error occurs if no
        +issuer certificate is specified.
        +
        +=item B<-serial num>
        +
        +Same as the B<cert> option except the certificate with serial number
        +B<num> is added to the request. The serial number is interpreted as a
        +decimal integer unless preceded by B<0x>. Negative integers can also
        +be specified by preceding the value by a B<-> sign.
        +
        +=item B<-signer filename>, B<-signkey filename>
        +
        +Sign the OCSP request using the certificate specified in the B<signer>
        +option and the private key specified by the B<signkey> option. If
        +the B<signkey> option is not present then the private key is read
        +from the same file as the certificate. If neither option is specified then
        +the OCSP request is not signed.
        +
        +=item B<-sign_other filename>
        +
        +Additional certificates to include in the signed request.
        +
        +=item B<-nonce>, B<-no_nonce>
        +
        +Add an OCSP nonce extension to a request or disable OCSP nonce addition.
        +Normally if an OCSP request is input using the B<respin> option no
        +nonce is added: using the B<nonce> option will force addition of a nonce.
        +If an OCSP request is being created (using B<cert> and B<serial> options)
        +a nonce is automatically added specifying B<no_nonce> overrides this.
        +
        +=item B<-req_text>, B<-resp_text>, B<-text>
        +
        +print out the text form of the OCSP request, response or both respectively.
        +
        +=item B<-reqout file>, B<-respout file>
        +
        +write out the DER encoded certificate request or response to B<file>.
        +
        +=item B<-reqin file>, B<-respin file>
        +
        +read OCSP request or response file from B<file>. These option are ignored
        +if OCSP request or response creation is implied by other options (for example
        +with B<serial>, B<cert> and B<host> options).
        +
        +=item B<-url responder_url>
        +
        +specify the responder URL. Both HTTP and HTTPS (SSL/TLS) URLs can be specified.
        +
        +=item B<-host hostname:port>, B<-path pathname>
        +
        +if the B<host> option is present then the OCSP request is sent to the host
        +B<hostname> on port B<port>. B<path> specifies the HTTP path name to use
        +or "/" by default.
        +
        +=item B<-CAfile file>, B<-CApath pathname>
        +
        +file or pathname containing trusted CA certificates. These are used to verify
        +the signature on the OCSP response.
        +
        +=item B<-verify_other file>
        +
        +file containing additional certificates to search when attempting to locate
        +the OCSP response signing certificate. Some responders omit the actual signer's
        +certificate from the response: this option can be used to supply the necessary
        +certificate in such cases.
        +
        +=item B<-trust_other>
        +
        +the certificates specified by the B<-verify_other> option should be explicitly
        +trusted and no additional checks will be performed on them. This is useful
        +when the complete responder certificate chain is not available or trusting a
        +root CA is not appropriate.
        +
        +=item B<-VAfile file>
        +
        +file containing explicitly trusted responder certificates. Equivalent to the
        +B<-verify_other> and B<-trust_other> options.
        +
        +=item B<-noverify>
        +
        +don't attempt to verify the OCSP response signature or the nonce values. This
        +option will normally only be used for debugging since it disables all verification
        +of the responders certificate.
        +
        +=item B<-no_intern>
        +
        +ignore certificates contained in the OCSP response when searching for the
        +signers certificate. With this option the signers certificate must be specified
        +with either the B<-verify_other> or B<-VAfile> options.
        +
        +=item B<-no_signature_verify>
        +
        +don't check the signature on the OCSP response. Since this option tolerates invalid
        +signatures on OCSP responses it will normally only be used for testing purposes.
        +
        +=item B<-no_cert_verify>
        +
        +don't verify the OCSP response signers certificate at all. Since this option allows
        +the OCSP response to be signed by any certificate it should only be used for
        +testing purposes.
        +
        +=item B<-no_chain>
        +
        +do not use certificates in the response as additional untrusted CA
        +certificates.
        +
        +=item B<-no_cert_checks>
        +
        +don't perform any additional checks on the OCSP response signers certificate.
        +That is do not make any checks to see if the signers certificate is authorised
        +to provide the necessary status information: as a result this option should
        +only be used for testing purposes.
        +
        +=item B<-validity_period nsec>, B<-status_age age>
        +
        +these options specify the range of times, in seconds, which will be tolerated
        +in an OCSP response. Each certificate status response includes a B<notBefore> time and
        +an optional B<notAfter> time. The current time should fall between these two values, but
        +the interval between the two times may be only a few seconds. In practice the OCSP
        +responder and clients clocks may not be precisely synchronised and so such a check
        +may fail. To avoid this the B<-validity_period> option can be used to specify an
        +acceptable error range in seconds, the default value is 5 minutes.
        +
        +If the B<notAfter> time is omitted from a response then this means that new status
        +information is immediately available. In this case the age of the B<notBefore> field
        +is checked to see it is not older than B<age> seconds old. By default this additional
        +check is not performed.
        +
        +=item B<-md5|-sha1|-sha256|-ripemod160|...>
        +
        +this option sets digest algorithm to use for certificate identification
        +in the OCSP request. By default SHA-1 is used. 
        +
        +=back
        +
        +=head1 OCSP SERVER OPTIONS
        +
        +=over 4
        +
        +=item B<-index indexfile>
        +
        +B<indexfile> is a text index file in B<ca> format containing certificate revocation
        +information.
        +
        +If the B<index> option is specified the B<ocsp> utility is in responder mode, otherwise
        +it is in client mode. The request(s) the responder processes can be either specified on
        +the command line (using B<issuer> and B<serial> options), supplied in a file (using the
        +B<respin> option) or via external OCSP clients (if B<port> or B<url> is specified).
        +
        +If the B<index> option is present then the B<CA> and B<rsigner> options must also be
        +present.
        +
        +=item B<-CA file>
        +
        +CA certificate corresponding to the revocation information in B<indexfile>.
        +
        +=item B<-rsigner file>
        +
        +The certificate to sign OCSP responses with.
        +
        +=item B<-rother file>
        +
        +Additional certificates to include in the OCSP response.
        +
        +=item B<-resp_no_certs>
        +
        +Don't include any certificates in the OCSP response.
        +
        +=item B<-resp_key_id>
        +
        +Identify the signer certificate using the key ID, default is to use the subject name.
        +
        +=item B<-rkey file>
        +
        +The private key to sign OCSP responses with: if not present the file specified in the
        +B<rsigner> option is used.
        +
        +=item B<-port portnum>
        +
        +Port to listen for OCSP requests on. The port may also be specified using the B<url>
        +option.
        +
        +=item B<-nrequest number>
        +
        +The OCSP server will exit after receiving B<number> requests, default unlimited. 
        +
        +=item B<-nmin minutes>, B<-ndays days>
        +
        +Number of minutes or days when fresh revocation information is available: used in the
        +B<nextUpdate> field. If neither option is present then the B<nextUpdate> field is 
        +omitted meaning fresh revocation information is immediately available.
        +
        +=back
        +
        +=head1 OCSP Response verification.
        +
        +OCSP Response follows the rules specified in RFC2560.
        +
        +Initially the OCSP responder certificate is located and the signature on
        +the OCSP request checked using the responder certificate's public key.
        +
        +Then a normal certificate verify is performed on the OCSP responder certificate
        +building up a certificate chain in the process. The locations of the trusted
        +certificates used to build the chain can be specified by the B<CAfile>
        +and B<CApath> options or they will be looked for in the standard OpenSSL
        +certificates directory.
        +
        +If the initial verify fails then the OCSP verify process halts with an
        +error.
        +
        +Otherwise the issuing CA certificate in the request is compared to the OCSP
        +responder certificate: if there is a match then the OCSP verify succeeds.
        +
        +Otherwise the OCSP responder certificate's CA is checked against the issuing
        +CA certificate in the request. If there is a match and the OCSPSigning
        +extended key usage is present in the OCSP responder certificate then the
        +OCSP verify succeeds.
        +
        +Otherwise the root CA of the OCSP responders CA is checked to see if it
        +is trusted for OCSP signing. If it is the OCSP verify succeeds.
        +
        +If none of these checks is successful then the OCSP verify fails.
        +
        +What this effectively means if that if the OCSP responder certificate is
        +authorised directly by the CA it is issuing revocation information about
        +(and it is correctly configured) then verification will succeed.
        +
        +If the OCSP responder is a "global responder" which can give details about
        +multiple CAs and has its own separate certificate chain then its root
        +CA can be trusted for OCSP signing. For example:
        +
        + openssl x509 -in ocspCA.pem -addtrust OCSPSigning -out trustedCA.pem
        +
        +Alternatively the responder certificate itself can be explicitly trusted
        +with the B<-VAfile> option.
        +
        +=head1 NOTES
        +
        +As noted, most of the verify options are for testing or debugging purposes.
        +Normally only the B<-CApath>, B<-CAfile> and (if the responder is a 'global
        +VA') B<-VAfile> options need to be used.
        +
        +The OCSP server is only useful for test and demonstration purposes: it is
        +not really usable as a full OCSP responder. It contains only a very
        +simple HTTP request handling and can only handle the POST form of OCSP
        +queries. It also handles requests serially meaning it cannot respond to
        +new requests until it has processed the current one. The text index file
        +format of revocation is also inefficient for large quantities of revocation
        +data.
        +
        +It is possible to run the B<ocsp> application in responder mode via a CGI
        +script using the B<respin> and B<respout> options.
        +
        +=head1 EXAMPLES
        +
        +Create an OCSP request and write it to a file:
        +
        + openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem -reqout req.der
        +
        +Send a query to an OCSP responder with URL http://ocsp.myhost.com/ save the 
        +response to a file and print it out in text form
        +
        + openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \
        +     -url http://ocsp.myhost.com/ -resp_text -respout resp.der
        +
        +Read in an OCSP response and print out text form:
        +
        + openssl ocsp -respin resp.der -text
        +
        +OCSP server on port 8888 using a standard B<ca> configuration, and a separate
        +responder certificate. All requests and responses are printed to a file.
        +
        + openssl ocsp -index demoCA/index.txt -port 8888 -rsigner rcert.pem -CA demoCA/cacert.pem
        +	-text -out log.txt
        +
        +As above but exit after processing one request:
        +
        + openssl ocsp -index demoCA/index.txt -port 8888 -rsigner rcert.pem -CA demoCA/cacert.pem
        +     -nrequest 1
        +
        +Query status information using internally generated request:
        +
        + openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA demoCA/cacert.pem
        +     -issuer demoCA/cacert.pem -serial 1
        +
        +Query status information using request read from a file, write response to a
        +second file.
        +
        + openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA demoCA/cacert.pem
        +     -reqin req.der -respout resp.der
        diff --git a/vendor/openssl/openssl/doc/apps/openssl.pod b/vendor/openssl/openssl/doc/apps/openssl.pod
        new file mode 100644
        index 000000000..64a160c20
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/openssl.pod
        @@ -0,0 +1,422 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +openssl - OpenSSL command line tool
        +
        +=head1 SYNOPSIS
        +
        +B<openssl>
        +I<command>
        +[ I<command_opts> ]
        +[ I<command_args> ]
        +
        +B<openssl> [ B<list-standard-commands> | B<list-message-digest-commands> | B<list-cipher-commands> | B<list-cipher-algorithms> | B<list-message-digest-algorithms> | B<list-public-key-algorithms>]
        +
        +B<openssl> B<no->I<XXX> [ I<arbitrary options> ]
        +
        +=head1 DESCRIPTION
        +
        +OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL
        +v2/v3) and Transport Layer Security (TLS v1) network protocols and related
        +cryptography standards required by them.
        +
        +The B<openssl> program is a command line tool for using the various
        +cryptography functions of OpenSSL's B<crypto> library from the shell. 
        +It can be used for 
        +
        + o  Creation and management of private keys, public keys and parameters
        + o  Public key cryptographic operations
        + o  Creation of X.509 certificates, CSRs and CRLs 
        + o  Calculation of Message Digests
        + o  Encryption and Decryption with Ciphers
        + o  SSL/TLS Client and Server Tests
        + o  Handling of S/MIME signed or encrypted mail
        + o  Time Stamp requests, generation and verification
        +
        +=head1 COMMAND SUMMARY
        +
        +The B<openssl> program provides a rich variety of commands (I<command> in the
        +SYNOPSIS above), each of which often has a wealth of options and arguments
        +(I<command_opts> and I<command_args> in the SYNOPSIS).
        +
        +The pseudo-commands B<list-standard-commands>, B<list-message-digest-commands>,
        +and B<list-cipher-commands> output a list (one entry per line) of the names
        +of all standard commands, message digest commands, or cipher commands,
        +respectively, that are available in the present B<openssl> utility.
        +
        +The pseudo-commands B<list-cipher-algorithms> and
        +B<list-message-digest-algorithms> list all cipher and message digest names, one entry per line. Aliases are listed as:
        +
        + from => to
        +
        +The pseudo-command B<list-public-key-algorithms> lists all supported public
        +key algorithms.
        +
        +The pseudo-command B<no->I<XXX> tests whether a command of the
        +specified name is available.  If no command named I<XXX> exists, it
        +returns 0 (success) and prints B<no->I<XXX>; otherwise it returns 1
        +and prints I<XXX>.  In both cases, the output goes to B<stdout> and
        +nothing is printed to B<stderr>.  Additional command line arguments
        +are always ignored.  Since for each cipher there is a command of the
        +same name, this provides an easy way for shell scripts to test for the
        +availability of ciphers in the B<openssl> program.  (B<no->I<XXX> is
        +not able to detect pseudo-commands such as B<quit>,
        +B<list->I<...>B<-commands>, or B<no->I<XXX> itself.)
        +
        +=head2 STANDARD COMMANDS
        +
        +=over 10
        +
        +=item L<B<asn1parse>|asn1parse(1)>
        +
        +Parse an ASN.1 sequence.
        +
        +=item L<B<ca>|ca(1)>
        +
        +Certificate Authority (CA) Management.  
        +
        +=item L<B<ciphers>|ciphers(1)>
        +
        +Cipher Suite Description Determination.
        +
        +=item L<B<cms>|cms(1)>
        +
        +CMS (Cryptographic Message Syntax) utility
        +
        +=item L<B<crl>|crl(1)>
        +
        +Certificate Revocation List (CRL) Management.
        +
        +=item L<B<crl2pkcs7>|crl2pkcs7(1)>
        +
        +CRL to PKCS#7 Conversion.
        +
        +=item L<B<dgst>|dgst(1)>
        +
        +Message Digest Calculation.
        +
        +=item B<dh>
        +
        +Diffie-Hellman Parameter Management.
        +Obsoleted by L<B<dhparam>|dhparam(1)>.
        +
        +=item L<B<dhparam>|dhparam(1)>
        +
        +Generation and Management of Diffie-Hellman Parameters. Superseded by 
        +L<B<genpkey>|genpkey(1)> and L<B<pkeyparam>|pkeyparam(1)>
        +
        +
        +=item L<B<dsa>|dsa(1)>
        +
        +DSA Data Management.
        +
        +=item L<B<dsaparam>|dsaparam(1)>
        +
        +DSA Parameter Generation and Management. Superseded by 
        +L<B<genpkey>|genpkey(1)> and L<B<pkeyparam>|pkeyparam(1)>
        +
        +=item L<B<ec>|ec(1)>
        +
        +EC (Elliptic curve) key processing
        +
        +=item L<B<ecparam>|ecparam(1)>
        +
        +EC parameter manipulation and generation
        +
        +=item L<B<enc>|enc(1)>
        +
        +Encoding with Ciphers.
        +
        +=item L<B<engine>|engine(1)>
        +
        +Engine (loadble module) information and manipulation.
        +
        +=item L<B<errstr>|errstr(1)>
        +
        +Error Number to Error String Conversion.
        +
        +=item B<gendh>
        +
        +Generation of Diffie-Hellman Parameters.
        +Obsoleted by L<B<dhparam>|dhparam(1)>.
        +
        +=item L<B<gendsa>|gendsa(1)>
        +
        +Generation of DSA Private Key from Parameters. Superseded by 
        +L<B<genpkey>|genpkey(1)> and L<B<pkey>|pkey(1)>
        +
        +=item L<B<genpkey>|genpkey(1)>
        +
        +Generation of Private Key or Parameters.
        +
        +=item L<B<genrsa>|genrsa(1)>
        +
        +Generation of RSA Private Key. Superceded by L<B<genpkey>|genpkey(1)>.
        +
        +=item L<B<nseq>|nseq(1)>
        +
        +Create or examine a netscape certificate sequence
        +
        +=item L<B<ocsp>|ocsp(1)>
        +
        +Online Certificate Status Protocol utility.
        +
        +=item L<B<passwd>|passwd(1)>
        +
        +Generation of hashed passwords.
        +
        +=item L<B<pkcs12>|pkcs12(1)>
        +
        +PKCS#12 Data Management.
        +
        +=item L<B<pkcs7>|pkcs7(1)>
        +
        +PKCS#7 Data Management.
        +
        +=item L<B<pkey>|pkey(1)>
        +
        +Public and private key management.
        +
        +=item L<B<pkeyparam>|pkeyparam(1)>
        +
        +Public key algorithm parameter management.
        +
        +=item L<B<pkeyutl>|pkeyutl(1)>
        +
        +Public key algorithm cryptographic operation utility.
        +
        +=item L<B<rand>|rand(1)>
        +
        +Generate pseudo-random bytes.
        +
        +=item L<B<req>|req(1)>
        +
        +PKCS#10 X.509 Certificate Signing Request (CSR) Management.
        +
        +=item L<B<rsa>|rsa(1)>
        +
        +RSA key management.
        +
        +
        +=item L<B<rsautl>|rsautl(1)>
        +
        +RSA utility for signing, verification, encryption, and decryption. Superseded
        +by  L<B<pkeyutl>|pkeyutl(1)>
        +
        +=item L<B<s_client>|s_client(1)>
        +
        +This implements a generic SSL/TLS client which can establish a transparent
        +connection to a remote server speaking SSL/TLS. It's intended for testing
        +purposes only and provides only rudimentary interface functionality but
        +internally uses mostly all functionality of the OpenSSL B<ssl> library.
        +
        +=item L<B<s_server>|s_server(1)>
        +
        +This implements a generic SSL/TLS server which accepts connections from remote
        +clients speaking SSL/TLS. It's intended for testing purposes only and provides
        +only rudimentary interface functionality but internally uses mostly all
        +functionality of the OpenSSL B<ssl> library.  It provides both an own command
        +line oriented protocol for testing SSL functions and a simple HTTP response
        +facility to emulate an SSL/TLS-aware webserver.
        +
        +=item L<B<s_time>|s_time(1)>
        +
        +SSL Connection Timer.
        +
        +=item L<B<sess_id>|sess_id(1)>
        +
        +SSL Session Data Management.
        +
        +=item L<B<smime>|smime(1)>
        +
        +S/MIME mail processing.
        +
        +=item L<B<speed>|speed(1)>
        +
        +Algorithm Speed Measurement.
        +
        +=item L<B<spkac>|spkac(1)>
        +
        +SPKAC printing and generating utility
        +
        +=item L<B<ts>|ts(1)>
        +
        +Time Stamping Authority tool (client/server)
        +
        +=item L<B<verify>|verify(1)>
        +
        +X.509 Certificate Verification.
        +
        +=item L<B<version>|version(1)>
        +
        +OpenSSL Version Information.
        +
        +=item L<B<x509>|x509(1)>
        +
        +X.509 Certificate Data Management.
        +
        +=back
        +
        +=head2 MESSAGE DIGEST COMMANDS
        +
        +=over 10
        +
        +=item B<md2>
        +
        +MD2 Digest
        +
        +=item B<md5>
        +
        +MD5 Digest
        +
        +=item B<mdc2>
        +
        +MDC2 Digest
        +
        +=item B<rmd160>
        +
        +RMD-160 Digest
        +
        +=item B<sha>            
        +
        +SHA Digest
        +
        +=item B<sha1>           
        +
        +SHA-1 Digest
        +
        +=item B<sha224>
        +
        +SHA-224 Digest
        +
        +=item B<sha256>
        +
        +SHA-256 Digest
        +
        +=item B<sha384>
        +
        +SHA-384 Digest
        +
        +=item B<sha512>
        +
        +SHA-512 Digest
        +
        +=back
        +
        +=head2 ENCODING AND CIPHER COMMANDS
        +
        +=over 10
        +
        +=item B<base64>
        +
        +Base64 Encoding
        +
        +=item B<bf bf-cbc bf-cfb bf-ecb bf-ofb>
        +
        +Blowfish Cipher
        +
        +=item B<cast cast-cbc>
        +
        +CAST Cipher
        +
        +=item B<cast5-cbc cast5-cfb cast5-ecb cast5-ofb>
        +
        +CAST5 Cipher
        +
        +=item B<des des-cbc des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb des-ede-ofb des-ofb>
        +
        +DES Cipher
        +
        +=item B<des3 desx des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb>
        +
        +Triple-DES Cipher
        +
        +=item B<idea idea-cbc idea-cfb idea-ecb idea-ofb>
        +
        +IDEA Cipher
        +
        +=item B<rc2 rc2-cbc rc2-cfb rc2-ecb rc2-ofb>
        +
        +RC2 Cipher
        +
        +=item B<rc4>
        +
        +RC4 Cipher
        +
        +=item B<rc5 rc5-cbc rc5-cfb rc5-ecb rc5-ofb>
        +
        +RC5 Cipher
        +
        +=back
        +
        +=head1 PASS PHRASE ARGUMENTS
        +
        +Several commands accept password arguments, typically using B<-passin>
        +and B<-passout> for input and output passwords respectively. These allow
        +the password to be obtained from a variety of sources. Both of these
        +options take a single argument whose format is described below. If no
        +password argument is given and a password is required then the user is
        +prompted to enter one: this will typically be read from the current
        +terminal with echoing turned off.
        +
        +=over 10
        +
        +=item B<pass:password>
        +
        +the actual password is B<password>. Since the password is visible
        +to utilities (like 'ps' under Unix) this form should only be used
        +where security is not important.
        +
        +=item B<env:var>
        +
        +obtain the password from the environment variable B<var>. Since
        +the environment of other processes is visible on certain platforms
        +(e.g. ps under certain Unix OSes) this option should be used with caution.
        +
        +=item B<file:pathname>
        +
        +the first line of B<pathname> is the password. If the same B<pathname>
        +argument is supplied to B<-passin> and B<-passout> arguments then the first
        +line will be used for the input password and the next line for the output
        +password. B<pathname> need not refer to a regular file: it could for example
        +refer to a device or named pipe.
        +
        +=item B<fd:number>
        +
        +read the password from the file descriptor B<number>. This can be used to
        +send the data via a pipe for example.
        +
        +=item B<stdin>
        +
        +read the password from standard input.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<asn1parse(1)|asn1parse(1)>, L<ca(1)|ca(1)>, L<config(5)|config(5)>,
        +L<crl(1)|crl(1)>, L<crl2pkcs7(1)|crl2pkcs7(1)>, L<dgst(1)|dgst(1)>,
        +L<dhparam(1)|dhparam(1)>, L<dsa(1)|dsa(1)>, L<dsaparam(1)|dsaparam(1)>,
        +L<enc(1)|enc(1)>, L<gendsa(1)|gendsa(1)>, L<genpkey(1)|genpkey(1)>,
        +L<genrsa(1)|genrsa(1)>, L<nseq(1)|nseq(1)>, L<openssl(1)|openssl(1)>,
        +L<passwd(1)|passwd(1)>,
        +L<pkcs12(1)|pkcs12(1)>, L<pkcs7(1)|pkcs7(1)>, L<pkcs8(1)|pkcs8(1)>,
        +L<rand(1)|rand(1)>, L<req(1)|req(1)>, L<rsa(1)|rsa(1)>,
        +L<rsautl(1)|rsautl(1)>, L<s_client(1)|s_client(1)>,
        +L<s_server(1)|s_server(1)>, L<s_time(1)|s_time(1)>,
        +L<smime(1)|smime(1)>, L<spkac(1)|spkac(1)>,
        +L<verify(1)|verify(1)>, L<version(1)|version(1)>, L<x509(1)|x509(1)>,
        +L<crypto(3)|crypto(3)>, L<ssl(3)|ssl(3)>, L<x509v3_config(5)|x509v3_config(5)> 
        +
        +=head1 HISTORY
        +
        +The openssl(1) document appeared in OpenSSL 0.9.2.
        +The B<list->I<XXX>B<-commands> pseudo-commands were added in OpenSSL 0.9.3;
        +The B<list->I<XXX>B<-algorithms> pseudo-commands were added in OpenSSL 1.0.0;
        +the B<no->I<XXX> pseudo-commands were added in OpenSSL 0.9.5a.
        +For notes on the availability of other commands, see their individual
        +manual pages.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/passwd.pod b/vendor/openssl/openssl/doc/apps/passwd.pod
        new file mode 100644
        index 000000000..f44982549
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/passwd.pod
        @@ -0,0 +1,82 @@
        +=pod
        +
        +=head1 NAME
        +
        +passwd - compute password hashes
        +
        +=head1 SYNOPSIS
        +
        +B<openssl passwd>
        +[B<-crypt>]
        +[B<-1>]
        +[B<-apr1>]
        +[B<-salt> I<string>]
        +[B<-in> I<file>]
        +[B<-stdin>]
        +[B<-noverify>]
        +[B<-quiet>]
        +[B<-table>]
        +{I<password>}
        +
        +=head1 DESCRIPTION
        +
        +The B<passwd> command computes the hash of a password typed at
        +run-time or the hash of each password in a list.  The password list is
        +taken from the named file for option B<-in file>, from stdin for
        +option B<-stdin>, or from the command line, or from the terminal otherwise.
        +The Unix standard algorithm B<crypt> and the MD5-based BSD password
        +algorithm B<1> and its Apache variant B<apr1> are available.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-crypt>
        +
        +Use the B<crypt> algorithm (default).
        +
        +=item B<-1>
        +
        +Use the MD5 based BSD password algorithm B<1>.
        +
        +=item B<-apr1>
        +
        +Use the B<apr1> algorithm (Apache variant of the BSD algorithm).
        +
        +=item B<-salt> I<string>
        +
        +Use the specified salt.
        +When reading a password from the terminal, this implies B<-noverify>.
        +
        +=item B<-in> I<file>
        +
        +Read passwords from I<file>.
        +
        +=item B<-stdin>
        +
        +Read passwords from B<stdin>.
        +
        +=item B<-noverify>
        +
        +Don't verify when reading a password from the terminal.
        +
        +=item B<-quiet>
        +
        +Don't output warnings when passwords given at the command line are truncated.
        +
        +=item B<-table>
        +
        +In the output list, prepend the cleartext password and a TAB character
        +to each password hash.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +B<openssl passwd -crypt -salt xx password> prints B<xxj31ZMTZzkVA>.
        +
        +B<openssl passwd -1 -salt xxxxxxxx password> prints B<$1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a.>.
        +
        +B<openssl passwd -apr1 -salt xxxxxxxx password> prints B<$apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0>.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/pkcs12.pod b/vendor/openssl/openssl/doc/apps/pkcs12.pod
        new file mode 100644
        index 000000000..f69a5c5a4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/pkcs12.pod
        @@ -0,0 +1,363 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +pkcs12 - PKCS#12 file utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<pkcs12>
        +[B<-export>]
        +[B<-chain>]
        +[B<-inkey filename>]
        +[B<-certfile filename>]
        +[B<-name name>]
        +[B<-caname name>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-noout>]
        +[B<-nomacver>]
        +[B<-nocerts>]
        +[B<-clcerts>]
        +[B<-cacerts>]
        +[B<-nokeys>]
        +[B<-info>]
        +[B<-des | -des3 | -idea | -aes128 | -aes192 | -aes256 | -camellia128 | -camellia192 | -camellia256 | -nodes>]
        +[B<-noiter>]
        +[B<-maciter | -nomaciter | -nomac>]
        +[B<-twopass>]
        +[B<-descert>]
        +[B<-certpbe cipher>]
        +[B<-keypbe cipher>]
        +[B<-macalg digest>]
        +[B<-keyex>]
        +[B<-keysig>]
        +[B<-password arg>]
        +[B<-passin arg>]
        +[B<-passout arg>]
        +[B<-rand file(s)>]
        +[B<-CAfile file>]
        +[B<-CApath dir>]
        +[B<-CSP name>]
        +
        +=head1 DESCRIPTION
        +
        +The B<pkcs12> command allows PKCS#12 files (sometimes referred to as
        +PFX files) to be created and parsed. PKCS#12 files are used by several
        +programs including Netscape, MSIE and MS Outlook.
        +
        +=head1 COMMAND OPTIONS
        +
        +There are a lot of options the meaning of some depends of whether a PKCS#12 file
        +is being created or parsed. By default a PKCS#12 file is parsed. A PKCS#12
        +file can be created by using the B<-export> option (see below).
        +
        +=head1 PARSING OPTIONS
        +
        +=over 4
        +
        +=item B<-in filename>
        +
        +This specifies filename of the PKCS#12 file to be parsed. Standard input is used
        +by default.
        +
        +=item B<-out filename>
        +
        +The filename to write certificates and private keys to, standard output by
        +default.  They are all written in PEM format.
        +
        +=item B<-pass arg>, B<-passin arg>
        +
        +the PKCS#12 file (i.e. input file) password source. For more information about
        +the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section in
        +L<openssl(1)|openssl(1)>.
        +
        +=item B<-passout arg>
        +
        +pass phrase source to encrypt any outputed private keys with. For more
        +information about the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section
        +in L<openssl(1)|openssl(1)>.
        +
        +=item B<-noout>
        +
        +this option inhibits output of the keys and certificates to the output file
        +version of the PKCS#12 file.
        +
        +=item B<-clcerts>
        +
        +only output client certificates (not CA certificates).
        +
        +=item B<-cacerts>
        +
        +only output CA certificates (not client certificates).
        +
        +=item B<-nocerts>
        +
        +no certificates at all will be output.
        +
        +=item B<-nokeys>
        +
        +no private keys will be output.
        +
        +=item B<-info>
        +
        +output additional information about the PKCS#12 file structure, algorithms used and
        +iteration counts.
        +
        +=item B<-des>
        +
        +use DES to encrypt private keys before outputting.
        +
        +=item B<-des3>
        +
        +use triple DES to encrypt private keys before outputting, this is the default.
        +
        +=item B<-idea>
        +
        +use IDEA to encrypt private keys before outputting.
        +
        +=item B<-aes128>, B<-aes192>, B<-aes256>
        +
        +use AES to encrypt private keys before outputting.
        +
        +=item B<-camellia128>, B<-camellia192>, B<-camellia256>
        +
        +use Camellia to encrypt private keys before outputting.
        +
        +=item B<-nodes>
        +
        +don't encrypt the private keys at all.
        +
        +=item B<-nomacver>
        +
        +don't attempt to verify the integrity MAC before reading the file.
        +
        +=item B<-twopass>
        +
        +prompt for separate integrity and encryption passwords: most software
        +always assumes these are the same so this option will render such
        +PKCS#12 files unreadable.
        +
        +=back
        +
        +=head1 FILE CREATION OPTIONS
        +
        +=over 4
        +
        +=item B<-export>
        +
        +This option specifies that a PKCS#12 file will be created rather than
        +parsed.
        +
        +=item B<-out filename>
        +
        +This specifies filename to write the PKCS#12 file to. Standard output is used
        +by default.
        +
        +=item B<-in filename>
        +
        +The filename to read certificates and private keys from, standard input by
        +default.  They must all be in PEM format. The order doesn't matter but one
        +private key and its corresponding certificate should be present. If additional
        +certificates are present they will also be included in the PKCS#12 file.
        +
        +=item B<-inkey filename>
        +
        +file to read private key from. If not present then a private key must be present
        +in the input file.
        +
        +=item B<-name friendlyname>
        +
        +This specifies the "friendly name" for the certificate and private key. This
        +name is typically displayed in list boxes by software importing the file.
        +
        +=item B<-certfile filename>
        +
        +A filename to read additional certificates from.
        +
        +=item B<-caname friendlyname>
        +
        +This specifies the "friendly name" for other certificates. This option may be
        +used multiple times to specify names for all certificates in the order they
        +appear. Netscape ignores friendly names on other certificates whereas MSIE
        +displays them.
        +
        +=item B<-pass arg>, B<-passout arg>
        +
        +the PKCS#12 file (i.e. output file) password source. For more information about
        +the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section in
        +L<openssl(1)|openssl(1)>.
        +
        +=item B<-passin password>
        +
        +pass phrase source to decrypt any input private keys with. For more information
        +about the format of B<arg> see the B<PASS PHRASE ARGUMENTS> section in
        +L<openssl(1)|openssl(1)>.
        +
        +=item B<-chain>
        +
        +if this option is present then an attempt is made to include the entire
        +certificate chain of the user certificate. The standard CA store is used
        +for this search. If the search fails it is considered a fatal error.
        +
        +=item B<-descert>
        +
        +encrypt the certificate using triple DES, this may render the PKCS#12
        +file unreadable by some "export grade" software. By default the private
        +key is encrypted using triple DES and the certificate using 40 bit RC2.
        +
        +=item B<-keypbe alg>, B<-certpbe alg>
        +
        +these options allow the algorithm used to encrypt the private key and
        +certificates to be selected. Any PKCS#5 v1.5 or PKCS#12 PBE algorithm name
        +can be used (see B<NOTES> section for more information). If a a cipher name
        +(as output by the B<list-cipher-algorithms> command is specified then it
        +is used with PKCS#5 v2.0. For interoperability reasons it is advisable to only
        +use PKCS#12 algorithms.
        +
        +=item B<-keyex|-keysig>
        +
        +specifies that the private key is to be used for key exchange or just signing.
        +This option is only interpreted by MSIE and similar MS software. Normally
        +"export grade" software will only allow 512 bit RSA keys to be used for
        +encryption purposes but arbitrary length keys for signing. The B<-keysig>
        +option marks the key for signing only. Signing only keys can be used for
        +S/MIME signing, authenticode (ActiveX control signing)  and SSL client
        +authentication, however due to a bug only MSIE 5.0 and later support
        +the use of signing only keys for SSL client authentication.
        +
        +=item B<-macalg digest>
        +
        +specify the MAC digest algorithm. If not included them SHA1 will be used.
        +
        +=item B<-nomaciter>, B<-noiter>
        +
        +these options affect the iteration counts on the MAC and key algorithms.
        +Unless you wish to produce files compatible with MSIE 4.0 you should leave
        +these options alone.
        +
        +To discourage attacks by using large dictionaries of common passwords the
        +algorithm that derives keys from passwords can have an iteration count applied
        +to it: this causes a certain part of the algorithm to be repeated and slows it
        +down. The MAC is used to check the file integrity but since it will normally
        +have the same password as the keys and certificates it could also be attacked.
        +By default both MAC and encryption iteration counts are set to 2048, using
        +these options the MAC and encryption iteration counts can be set to 1, since
        +this reduces the file security you should not use these options unless you
        +really have to. Most software supports both MAC and key iteration counts.
        +MSIE 4.0 doesn't support MAC iteration counts so it needs the B<-nomaciter>
        +option.
        +
        +=item B<-maciter>
        +
        +This option is included for compatibility with previous versions, it used
        +to be needed to use MAC iterations counts but they are now used by default.
        +
        +=item B<-nomac>
        +
        +don't attempt to provide the MAC integrity.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<-CAfile file>
        +
        +CA storage as a file.
        +
        +=item B<-CApath dir>
        +
        +CA storage as a directory. This directory must be a standard certificate
        +directory: that is a hash of each subject name (using B<x509 -hash>) should be
        +linked to each certificate.
        +
        +=item B<-CSP name>
        +
        +write B<name> as a Microsoft CSP name.
        +
        +=back
        +
        +=head1 NOTES
        +
        +Although there are a large number of options most of them are very rarely
        +used. For PKCS#12 file parsing only B<-in> and B<-out> need to be used
        +for PKCS#12 file creation B<-export> and B<-name> are also used.
        +
        +If none of the B<-clcerts>, B<-cacerts> or B<-nocerts> options are present
        +then all certificates will be output in the order they appear in the input
        +PKCS#12 files. There is no guarantee that the first certificate present is
        +the one corresponding to the private key. Certain software which requires
        +a private key and certificate and assumes the first certificate in the
        +file is the one corresponding to the private key: this may not always
        +be the case. Using the B<-clcerts> option will solve this problem by only
        +outputting the certificate corresponding to the private key. If the CA
        +certificates are required then they can be output to a separate file using
        +the B<-nokeys -cacerts> options to just output CA certificates.
        +
        +The B<-keypbe> and B<-certpbe> algorithms allow the precise encryption
        +algorithms for private keys and certificates to be specified. Normally
        +the defaults are fine but occasionally software can't handle triple DES
        +encrypted private keys, then the option B<-keypbe PBE-SHA1-RC2-40> can
        +be used to reduce the private key encryption to 40 bit RC2. A complete
        +description of all algorithms is contained in the B<pkcs8> manual page.
        +
        +=head1 EXAMPLES
        +
        +Parse a PKCS#12 file and output it to a file:
        +
        + openssl pkcs12 -in file.p12 -out file.pem
        +
        +Output only client certificates to a file:
        +
        + openssl pkcs12 -in file.p12 -clcerts -out file.pem
        +
        +Don't encrypt the private key:
        + 
        + openssl pkcs12 -in file.p12 -out file.pem -nodes
        +
        +Print some info about a PKCS#12 file:
        +
        + openssl pkcs12 -in file.p12 -info -noout
        +
        +Create a PKCS#12 file:
        +
        + openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate"
        +
        +Include some extra certificates:
        +
        + openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate" \
        +  -certfile othercerts.pem
        +
        +=head1 BUGS
        +
        +Some would argue that the PKCS#12 standard is one big bug :-)
        +
        +Versions of OpenSSL before 0.9.6a had a bug in the PKCS#12 key generation
        +routines. Under rare circumstances this could produce a PKCS#12 file encrypted
        +with an invalid key. As a result some PKCS#12 files which triggered this bug
        +from other implementations (MSIE or Netscape) could not be decrypted
        +by OpenSSL and similarly OpenSSL could produce PKCS#12 files which could
        +not be decrypted by other implementations. The chances of producing such
        +a file are relatively small: less than 1 in 256.
        +
        +A side effect of fixing this bug is that any old invalidly encrypted PKCS#12
        +files cannot no longer be parsed by the fixed version. Under such circumstances
        +the B<pkcs12> utility will report that the MAC is OK but fail with a decryption
        +error when extracting private keys.
        +
        +This problem can be resolved by extracting the private keys and certificates
        +from the PKCS#12 file using an older version of OpenSSL and recreating the PKCS#12
        +file from the keys and certificates using a newer version of OpenSSL. For example:
        +
        + old-openssl -in bad.p12 -out keycerts.pem
        + openssl -in keycerts.pem -export -name "My PKCS#12 file" -out fixed.p12
        +
        +=head1 SEE ALSO
        +
        +L<pkcs8(1)|pkcs8(1)>
        +
        diff --git a/vendor/openssl/openssl/doc/apps/pkcs7.pod b/vendor/openssl/openssl/doc/apps/pkcs7.pod
        new file mode 100644
        index 000000000..acfb8100f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/pkcs7.pod
        @@ -0,0 +1,105 @@
        +=pod
        +
        +=head1 NAME
        +
        +pkcs7 - PKCS#7 utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<pkcs7>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-print_certs>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<pkcs7> command processes PKCS#7 files in DER or PEM format.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. B<DER> format is DER encoded PKCS#7
        +v1.5 structure.B<PEM> (the default) is a base64 encoded version of
        +the DER form with header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read 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<-print_certs>
        +
        +prints out any certificates or CRLs contained in the file. They are
        +preceded by their subject and issuer names in one line format.
        +
        +=item B<-text>
        +
        +prints out certificates details in full rather than just subject and
        +issuer names.
        +
        +=item B<-noout>
        +
        +don't output the encoded version of the PKCS#7 structure (or certificates
        +is B<-print_certs> is set).
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<pkcs7>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Convert a PKCS#7 file from PEM to DER:
        +
        + openssl pkcs7 -in file.pem -outform DER -out file.der
        +
        +Output all certificates in a file:
        +
        + openssl pkcs7 -in file.pem -print_certs -out certs.pem
        +
        +=head1 NOTES
        +
        +The PEM PKCS#7 format uses the header and footer lines:
        +
        + -----BEGIN PKCS7-----
        + -----END PKCS7-----
        +
        +For compatibility with some CAs it will also accept:
        +
        + -----BEGIN CERTIFICATE-----
        + -----END CERTIFICATE-----
        +
        +=head1 RESTRICTIONS
        +
        +There is no option to print out all the fields of a PKCS#7 file.
        +
        +This PKCS#7 routines only understand PKCS#7 v 1.5 as specified in RFC2315 they 
        +cannot currently parse, for example, the new CMS as described in RFC2630.
        +
        +=head1 SEE ALSO
        +
        +L<crl2pkcs7(1)|crl2pkcs7(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/pkcs8.pod b/vendor/openssl/openssl/doc/apps/pkcs8.pod
        new file mode 100644
        index 000000000..84abee78f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/pkcs8.pod
        @@ -0,0 +1,243 @@
        +=pod
        +
        +=head1 NAME
        +
        +pkcs8 - PKCS#8 format private key conversion tool
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<pkcs8>
        +[B<-topk8>]
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-passin arg>]
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-noiter>]
        +[B<-nocrypt>]
        +[B<-nooct>]
        +[B<-embed>]
        +[B<-nsdb>]
        +[B<-v2 alg>]
        +[B<-v1 alg>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<pkcs8> command processes private keys in PKCS#8 format. It can handle
        +both unencrypted PKCS#8 PrivateKeyInfo format and EncryptedPrivateKeyInfo
        +format with a variety of PKCS#5 (v1.5 and v2.0) and PKCS#12 algorithms.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-topk8>
        +
        +Normally a PKCS#8 private key is expected on input and a traditional format
        +private key will be written. With the B<-topk8> option the situation is
        +reversed: it reads a traditional format private key and writes a PKCS#8
        +format key.
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. If a PKCS#8 format key is expected on input
        +then either a B<DER> or B<PEM> encoded version of a PKCS#8 key will be
        +expected. Otherwise the B<DER> or B<PEM> format of the traditional format
        +private key is used.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a key from or standard input if this
        +option is not specified. If the key is encrypted a pass phrase will be
        +prompted for.
        +
        +=item B<-passin arg>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write a key to or standard output by
        +default. If any encryption options are set then a pass phrase will be
        +prompted for. The output filename should B<not> be the same as the input
        +filename.
        +
        +=item B<-passout arg>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-nocrypt>
        +
        +PKCS#8 keys generated or input are normally PKCS#8 EncryptedPrivateKeyInfo
        +structures using an appropriate password based encryption algorithm. With
        +this option an unencrypted PrivateKeyInfo structure is expected or output.
        +This option does not encrypt private keys at all and should only be used
        +when absolutely necessary. Certain software such as some versions of Java
        +code signing software used unencrypted private keys.
        +
        +=item B<-nooct>
        +
        +This option generates RSA private keys in a broken format that some software
        +uses. Specifically the private key should be enclosed in a OCTET STRING
        +but some software just includes the structure itself without the
        +surrounding OCTET STRING.
        +
        +=item B<-embed>
        +
        +This option generates DSA keys in a broken format. The DSA parameters are
        +embedded inside the PrivateKey structure. In this form the OCTET STRING
        +contains an ASN1 SEQUENCE consisting of two structures: a SEQUENCE containing
        +the parameters and an ASN1 INTEGER containing the private key.
        +
        +=item B<-nsdb>
        +
        +This option generates DSA keys in a broken format compatible with Netscape
        +private key databases. The PrivateKey contains a SEQUENCE consisting of
        +the public and private keys respectively.
        +
        +=item B<-v2 alg>
        +
        +This option enables the use of PKCS#5 v2.0 algorithms. Normally PKCS#8
        +private keys are encrypted with the password based encryption algorithm
        +called B<pbeWithMD5AndDES-CBC> this uses 56 bit DES encryption but it
        +was the strongest encryption algorithm supported in PKCS#5 v1.5. Using 
        +the B<-v2> option PKCS#5 v2.0 algorithms are used which can use any
        +encryption algorithm such as 168 bit triple DES or 128 bit RC2 however
        +not many implementations support PKCS#5 v2.0 yet. If you are just using
        +private keys with OpenSSL then this doesn't matter.
        +
        +The B<alg> argument is the encryption algorithm to use, valid values include
        +B<des>, B<des3> and B<rc2>. It is recommended that B<des3> is used.
        +
        +=item B<-v1 alg>
        +
        +This option specifies a PKCS#5 v1.5 or PKCS#12 algorithm to use. A complete
        +list of possible algorithms is included below.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<pkcs8>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The encrypted form of a PEM encode PKCS#8 files uses the following
        +headers and footers:
        +
        + -----BEGIN ENCRYPTED PRIVATE KEY-----
        + -----END ENCRYPTED PRIVATE KEY-----
        +
        +The unencrypted form uses:
        +
        + -----BEGIN PRIVATE KEY-----
        + -----END PRIVATE KEY-----
        +
        +Private keys encrypted using PKCS#5 v2.0 algorithms and high iteration
        +counts are more secure that those encrypted using the traditional
        +SSLeay compatible formats. So if additional security is considered
        +important the keys should be converted.
        +
        +The default encryption is only 56 bits because this is the encryption
        +that most current implementations of PKCS#8 will support.
        +
        +Some software may use PKCS#12 password based encryption algorithms
        +with PKCS#8 format private keys: these are handled automatically
        +but there is no option to produce them.
        +
        +It is possible to write out DER encoded encrypted private keys in
        +PKCS#8 format because the encryption details are included at an ASN1
        +level whereas the traditional format includes them at a PEM level.
        +
        +=head1 PKCS#5 v1.5 and PKCS#12 algorithms.
        +
        +Various algorithms can be used with the B<-v1> command line option,
        +including PKCS#5 v1.5 and PKCS#12. These are described in more detail
        +below.
        +
        +=over 4
        +
        +=item B<PBE-MD2-DES PBE-MD5-DES>
        +
        +These algorithms were included in the original PKCS#5 v1.5 specification.
        +They only offer 56 bits of protection since they both use DES.
        +
        +=item B<PBE-SHA1-RC2-64 PBE-MD2-RC2-64 PBE-MD5-RC2-64 PBE-SHA1-DES>
        +
        +These algorithms are not mentioned in the original PKCS#5 v1.5 specification
        +but they use the same key derivation algorithm and are supported by some
        +software. They are mentioned in PKCS#5 v2.0. They use either 64 bit RC2 or
        +56 bit DES.
        +
        +=item B<PBE-SHA1-RC4-128 PBE-SHA1-RC4-40 PBE-SHA1-3DES PBE-SHA1-2DES PBE-SHA1-RC2-128 PBE-SHA1-RC2-40>
        +
        +These algorithms use the PKCS#12 password based encryption algorithm and
        +allow strong encryption algorithms like triple DES or 128 bit RC2 to be used.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Convert a private from traditional to PKCS#5 v2.0 format using triple
        +DES:
        +
        + openssl pkcs8 -in key.pem -topk8 -v2 des3 -out enckey.pem
        +
        +Convert a private key to PKCS#8 using a PKCS#5 1.5 compatible algorithm
        +(DES):
        +
        + openssl pkcs8 -in key.pem -topk8 -out enckey.pem
        +
        +Convert a private key to PKCS#8 using a PKCS#12 compatible algorithm
        +(3DES):
        +
        + openssl pkcs8 -in key.pem -topk8 -out enckey.pem -v1 PBE-SHA1-3DES
        +
        +Read a DER unencrypted PKCS#8 format private key:
        +
        + openssl pkcs8 -inform DER -nocrypt -in key.der -out key.pem
        +
        +Convert a private key from any PKCS#8 format to traditional format:
        +
        + openssl pkcs8 -in pk8.pem -out key.pem
        +
        +=head1 STANDARDS
        +
        +Test vectors from this PKCS#5 v2.0 implementation were posted to the
        +pkcs-tng mailing list using triple DES, DES and RC2 with high iteration
        +counts, several people confirmed that they could decrypt the private
        +keys produced and Therefore it can be assumed that the PKCS#5 v2.0
        +implementation is reasonably accurate at least as far as these
        +algorithms are concerned.
        +
        +The format of PKCS#8 DSA (and other) private keys is not well documented:
        +it is hidden away in PKCS#11 v2.01, section 11.9. OpenSSL's default DSA
        +PKCS#8 private key format complies with this standard.
        +
        +=head1 BUGS
        +
        +There should be an option that prints out the encryption algorithm
        +in use and other details such as the iteration count.
        +
        +PKCS#8 using triple DES and PKCS#5 v2.0 should be the default private
        +key format for OpenSSL: for compatibility several of the utilities use
        +the old format at present.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(1)|dsa(1)>, L<rsa(1)|rsa(1)>, L<genrsa(1)|genrsa(1)>,
        +L<gendsa(1)|gendsa(1)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/pkey.pod b/vendor/openssl/openssl/doc/apps/pkey.pod
        new file mode 100644
        index 000000000..4851223f3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/pkey.pod
        @@ -0,0 +1,135 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +pkey - public or private key processing tool
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<pkey>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-passin arg>]
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-cipher>]
        +[B<-text>]
        +[B<-text_pub>]
        +[B<-noout>]
        +[B<-pubin>]
        +[B<-pubout>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<pkey> command processes public or private keys. They can be converted
        +between various forms and their components printed out.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format DER or PEM.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a key from or standard input if this
        +option is not specified. If the key is encrypted a pass phrase will be
        +prompted for.
        +
        +=item B<-passin arg>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write a key to or standard output if this
        +option is not specified. If any encryption options are set then a pass phrase
        +will be prompted for. The output filename should B<not> be the same as the input
        +filename.
        +
        +=item B<-passout password>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-cipher>
        +
        +These options encrypt the private key with the supplied cipher. Any algorithm
        +name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>.
        +
        +=item B<-text>
        +
        +prints out the various public or private key components in
        +plain text in addition to the encoded version. 
        +
        +=item B<-text_pub>
        +
        +print out only public key components even if a private key is being processed.
        +
        +=item B<-noout>
        +
        +do not output the encoded version of the key.
        +
        +=item B<-pubin>
        +
        +by default a private key is read from the input file: with this
        +option a public key is read instead.
        +
        +=item B<-pubout>
        +
        +by default a private key is output: with this option a public
        +key will be output instead. This option is automatically set if
        +the input is a public key.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<pkey>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +To remove the pass phrase on an RSA private key:
        +
        + openssl pkey -in key.pem -out keyout.pem
        +
        +To encrypt a private key using triple DES:
        +
        + openssl pkey -in key.pem -des3 -out keyout.pem
        +
        +To convert a private key from PEM to DER format: 
        +
        + openssl pkey -in key.pem -outform DER -out keyout.der
        +
        +To print out the components of a private key to standard output:
        +
        + openssl pkey -in key.pem -text -noout
        +
        +To print out the public components of a private key to standard output:
        +
        + openssl pkey -in key.pem -text_pub -noout
        +
        +To just output the public part of a private key:
        +
        + openssl pkey -in key.pem -pubout -out pubkey.pem
        +
        +=head1 SEE ALSO
        +
        +L<genpkey(1)|genpkey(1)>, L<rsa(1)|rsa(1)>, L<pkcs8(1)|pkcs8(1)>,
        +L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>, L<gendsa(1)|gendsa(1)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/pkeyparam.pod b/vendor/openssl/openssl/doc/apps/pkeyparam.pod
        new file mode 100644
        index 000000000..154f6721a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/pkeyparam.pod
        @@ -0,0 +1,69 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +pkeyparam - public key algorithm parameter processing tool
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<pkeyparam>
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<pkey> command processes public or private keys. They can be converted
        +between various forms and their components printed out.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read parameters from or standard input if
        +this option is not specified.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write parameters to or standard output if
        +this option is not specified.
        +
        +=item B<-text>
        +
        +prints out the parameters in plain text in addition to the encoded version. 
        +
        +=item B<-noout>
        +
        +do not output the encoded version of the parameters.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<pkeyparam>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 EXAMPLE
        +
        +Print out text version of parameters:
        +
        + openssl pkeyparam -in param.pem -text
        +
        +=head1 NOTES
        +
        +There are no B<-inform> or B<-outform> options for this command because only
        +PEM format is supported because the key type is determined by the PEM headers.
        +
        +=head1 SEE ALSO
        +
        +L<genpkey(1)|genpkey(1)>, L<rsa(1)|rsa(1)>, L<pkcs8(1)|pkcs8(1)>,
        +L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>, L<gendsa(1)|gendsa(1)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/pkeyutl.pod b/vendor/openssl/openssl/doc/apps/pkeyutl.pod
        new file mode 100644
        index 000000000..27be9a900
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/pkeyutl.pod
        @@ -0,0 +1,222 @@
        +=pod
        +
        +=head1 NAME
        +
        +pkeyutl - public key algorithm utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<pkeyutl>
        +[B<-in file>]
        +[B<-out file>]
        +[B<-sigfile file>]
        +[B<-inkey file>]
        +[B<-keyform PEM|DER>]
        +[B<-passin arg>]
        +[B<-peerkey file>]
        +[B<-peerform PEM|DER>]
        +[B<-pubin>]
        +[B<-certin>]
        +[B<-rev>]
        +[B<-sign>]
        +[B<-verify>]
        +[B<-verifyrecover>]
        +[B<-encrypt>]
        +[B<-decrypt>]
        +[B<-derive>]
        +[B<-pkeyopt opt:value>]
        +[B<-hexdump>]
        +[B<-asn1parse>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<pkeyutl> command can be used to perform public key operations using
        +any supported 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 a private key.
        +
        +=item B<-keyform PEM|DER>
        +
        +the key format PEM, DER or ENGINE.
        +
        +=item B<-passin arg>
        +
        +the input key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +
        +=item B<-peerkey file>
        +
        +the peer key file, used by key derivation (agreement) operations.
        +
        +=item B<-peerform PEM|DER>
        +
        +the peer key format PEM, DER or ENGINE.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<pkeyutl>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +
        +=item B<-pubin>
        +
        +the input file is a public key. 
        +
        +=item B<-certin>
        +
        +the input is a certificate containing a public key. 
        +
        +=item B<-rev>
        +
        +reverse the order of the input buffer. This is useful for some libraries
        +(such as CryptoAPI) which represent the buffer in little endian format.
        +
        +=item B<-sign>
        +
        +sign the input data and output the signed result. This requires
        +a private key.
        +
        +=item B<-verify>
        +
        +verify the input data against the signature file and indicate if the
        +verification succeeded or failed.
        +
        +=item B<-verifyrecover>
        +
        +verify the input data and output the recovered data.
        +
        +=item B<-encrypt>
        +
        +encrypt the input data using a public key.
        +
        +=item B<-decrypt>
        +
        +decrypt the input data using a private key.
        +
        +=item B<-derive>
        +
        +derive a shared secret using the peer key.
        +
        +=item B<-hexdump>
        +
        +hex dump the output data.
        +
        +=item B<-asn1parse>
        +
        +asn1parse the output data, this is useful when combined with the
        +B<-verifyrecover> option when an ASN1 structure is signed.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The operations and options supported vary according to the key algorithm
        +and its implementation. The OpenSSL operations and options are indicated below.
        +
        +Unless otherwise mentioned all algorithms support the B<digest:alg> option
        +which specifies the digest in use for sign, verify and verifyrecover operations.
        +The value B<alg> should represent a digest name as used in the
        +EVP_get_digestbyname() function for example B<sha1>.
        +
        +=head1 RSA ALGORITHM
        +
        +The RSA algorithm supports encrypt, decrypt, sign, verify and verifyrecover
        +operations in general. Some padding modes only support some of these 
        +operations however.
        +
        +=over 4
        +
        +=item -B<rsa_padding_mode:mode>
        +
        +This sets the RSA padding mode. Acceptable values for B<mode> are B<pkcs1> for
        +PKCS#1 padding, B<sslv23> for SSLv23 padding, B<none> for no padding, B<oaep>
        +for B<OAEP> mode, B<x931> for X9.31 mode and B<pss> for PSS.
        +
        +In PKCS#1 padding if the message digest is not set then the supplied data is 
        +signed or verified directly instead of using a B<DigestInfo> structure. If a
        +digest is set then the a B<DigestInfo> structure is used and its the length
        +must correspond to the digest type.
        +
        +For B<oeap> mode only encryption and decryption is supported.
        +
        +For B<x931> if the digest type is set it is used to format the block data
        +otherwise the first byte is used to specify the X9.31 digest ID. Sign,
        +verify and verifyrecover are can be performed in this mode.
        +
        +For B<pss> mode only sign and verify are supported and the digest type must be
        +specified.
        +
        +=item B<rsa_pss_saltlen:len>
        +
        +For B<pss> mode only this option specifies the salt length. Two special values
        +are supported: -1 sets the salt length to the digest length. When signing -2
        +sets the salt length to the maximum permissible value. When verifying -2 causes
        +the salt length to be automatically determined based on the B<PSS> block
        +structure.
        +
        +=back
        +
        +=head1 DSA ALGORITHM
        +
        +The DSA algorithm supports signing and verification operations only. Currently
        +there are no additional options other than B<digest>. Only the SHA1
        +digest can be used and this digest is assumed by default.
        +
        +=head1 DH ALGORITHM
        +
        +The DH algorithm only supports the derivation operation and no additional
        +options.
        +
        +=head1 EC ALGORITHM
        +
        +The EC algorithm supports sign, verify and derive operations. The sign and
        +verify operations use ECDSA and derive uses ECDH. Currently there are no
        +additional options other than B<digest>. Only the SHA1 digest can be used and
        +this digest is assumed by default.
        +
        +=head1 EXAMPLES
        +
        +Sign some data using a private key:
        +
        + openssl pkeyutl -sign -in file -inkey key.pem -out sig
        +
        +Recover the signed data (e.g. if an RSA key is used):
        +
        + openssl pkeyutl -verifyrecover -in sig -inkey key.pem
        +
        +Verify the signature (e.g. a DSA key):
        +
        + openssl pkeyutl -verify -in file -sigfile sig -inkey key.pem
        +
        +Sign data using a message digest value (this is currently only valid for RSA):
        +
        + openssl pkeyutl -sign -in file -inkey key.pem -out sig -pkeyopt digest:sha256
        +
        +Derive a shared secret value:
        +
        + openssl pkeyutl -derive -inkey key.pem -peerkey pubkey.pem -out secret
        +
        +=head1 SEE ALSO
        +
        +L<genpkey(1)|genpkey(1)>, L<pkey(1)|pkey(1)>, L<rsautl(1)|rsautl(1)>
        +L<dgst(1)|dgst(1)>, L<rsa(1)|rsa(1)>, L<genrsa(1)|genrsa(1)>
        diff --git a/vendor/openssl/openssl/doc/apps/rand.pod b/vendor/openssl/openssl/doc/apps/rand.pod
        new file mode 100644
        index 000000000..d1d213ef4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/rand.pod
        @@ -0,0 +1,55 @@
        +=pod
        +
        +=head1 NAME
        +
        +rand - generate pseudo-random bytes
        +
        +=head1 SYNOPSIS
        +
        +B<openssl rand>
        +[B<-out> I<file>]
        +[B<-rand> I<file(s)>]
        +[B<-base64>]
        +[B<-hex>]
        +I<num>
        +
        +=head1 DESCRIPTION
        +
        +The B<rand> command outputs I<num> pseudo-random bytes after seeding
        +the random number generator once.  As in other B<openssl> command
        +line tools, PRNG seeding uses the file I<$HOME/>B<.rnd> or B<.rnd>
        +in addition to the files given in the B<-rand> option.  A new
        +I<$HOME>/B<.rnd> or B<.rnd> file will be written back if enough
        +seeding was obtained from these sources.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-out> I<file>
        +
        +Write to I<file> instead of standard output.
        +
        +=item B<-rand> I<file(s)>
        +
        +Use specified file or files or EGD socket (see L<RAND_egd(3)|RAND_egd(3)>)
        +for seeding the random number generator.
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<-base64>
        +
        +Perform base64 encoding on the output.
        +
        +=item B<-hex>
        +
        +Show the output as a hex string.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<RAND_bytes(3)|RAND_bytes(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/req.pod b/vendor/openssl/openssl/doc/apps/req.pod
        new file mode 100644
        index 000000000..ff48bbdf2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/req.pod
        @@ -0,0 +1,678 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +req - PKCS#10 certificate request and certificate generating utility.
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<req>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-passin arg>]
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-text>]
        +[B<-pubkey>]
        +[B<-noout>]
        +[B<-verify>]
        +[B<-modulus>]
        +[B<-new>]
        +[B<-rand file(s)>]
        +[B<-newkey rsa:bits>]
        +[B<-newkey alg:file>]
        +[B<-nodes>]
        +[B<-key filename>]
        +[B<-keyform PEM|DER>]
        +[B<-keyout filename>]
        +[B<-keygen_engine id>]
        +[B<-[digest]>]
        +[B<-config filename>]
        +[B<-subj arg>]
        +[B<-multivalue-rdn>]
        +[B<-x509>]
        +[B<-days n>]
        +[B<-set_serial n>]
        +[B<-asn1-kludge>]
        +[B<-no-asn1-kludge>]
        +[B<-newhdr>]
        +[B<-extensions section>]
        +[B<-reqexts section>]
        +[B<-utf8>]
        +[B<-nameopt>]
        +[B<-reqopt>]
        +[B<-subject>]
        +[B<-subj arg>]
        +[B<-batch>]
        +[B<-verbose>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<req> command primarily creates and processes certificate requests
        +in PKCS#10 format. It can additionally create self signed certificates
        +for use as root CAs for example.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option uses an ASN1 DER encoded
        +form compatible with the PKCS#10. The B<PEM> form is the default format: it
        +consists of the B<DER> format base64 encoded with additional header and
        +footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a request from or standard input
        +if this option is not specified. A request is only read if the creation
        +options (B<-new> and B<-newkey>) are not specified.
        +
        +=item B<-passin arg>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write to or standard output by
        +default.
        +
        +=item B<-passout arg>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-text>
        +
        +prints out the certificate request in text form.
        +
        +=item B<-subject>
        +
        +prints out the request subject (or certificate subject if B<-x509> is
        +specified)
        +
        +=item B<-pubkey>
        +
        +outputs the public key.
        +
        +=item B<-noout>
        +
        +this option prevents output of the encoded version of the request.
        +
        +=item B<-modulus>
        +
        +this option prints out the value of the modulus of the public key
        +contained in the request.
        +
        +=item B<-verify>
        +
        +verifies the signature on the request.
        +
        +=item B<-new>
        +
        +this option generates a new certificate request. It will prompt
        +the user for the relevant field values. The actual fields
        +prompted for and their maximum and minimum sizes are specified
        +in the configuration file and any requested extensions.
        +
        +If the B<-key> option is not used it will generate a new RSA private
        +key using information specified in the configuration file.
        +
        +=item B<-subj arg>
        +
        +Replaces subject field of input request with specified data and outputs
        +modified request. The arg must be formatted as
        +I</type0=value0/type1=value1/type2=...>,
        +characters may be escaped by \ (backslash), no spaces are skipped.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<-newkey arg>
        +
        +this option creates a new certificate request and a new private
        +key. The argument takes one of several forms. B<rsa:nbits>, where
        +B<nbits> is the number of bits, generates an RSA key B<nbits>
        +in size. If B<nbits> is omitted, i.e. B<-newkey rsa> specified,
        +the default key size, specified in the configuration file is used.
        +
        +All other algorithms support the B<-newkey alg:file> form, where file may be
        +an algorithm parameter file, created by the B<genpkey -genparam> command
        +or and X.509 certificate for a key with approriate algorithm.
        +
        +B<param:file> generates a key using the parameter file or certificate B<file>,
        +the algorithm is determined by the parameters. B<algname:file> use algorithm
        +B<algname> and parameter file B<file>: the two algorithms must match or an
        +error occurs. B<algname> just uses algorithm B<algname>, and parameters,
        +if neccessary should be specified via B<-pkeyopt> parameter.
        +
        +B<dsa:filename> generates a DSA key using the parameters
        +in the file B<filename>. B<ec:filename> generates EC key (usable both with
        +ECDSA or ECDH algorithms), B<gost2001:filename> generates GOST R
        +34.10-2001 key (requires B<ccgost> engine configured in the configuration
        +file). If just B<gost2001> is specified a parameter set should be
        +specified by B<-pkeyopt paramset:X>
        +
        +
        +=item B<-pkeyopt opt:value>
        +
        +set the public key algorithm option B<opt> to B<value>. The precise set of
        +options supported depends on the public key algorithm used and its
        +implementation. See B<KEY GENERATION OPTIONS> in the B<genpkey> manual page
        +for more details.
        +
        +=item B<-key filename>
        +
        +This specifies the file to read the private key from. It also
        +accepts PKCS#8 format private keys for PEM format files.
        +
        +=item B<-keyform PEM|DER>
        +
        +the format of the private key file specified in the B<-key>
        +argument. PEM is the default.
        +
        +=item B<-keyout filename>
        +
        +this gives the filename to write the newly created private key to.
        +If this option is not specified then the filename present in the
        +configuration file is used.
        +
        +=item B<-nodes>
        +
        +if this option is specified then if a private key is created it
        +will not be encrypted.
        +
        +=item B<-[digest]>
        +
        +this specifies the message digest to sign the request with (such as
        +B<-md5>, B<-sha1>). This overrides the digest algorithm specified in
        +the configuration file.
        +
        +Some public key algorithms may override this choice. For instance, DSA
        +signatures always use SHA1, GOST R 34.10 signatures always use
        +GOST R 34.11-94 (B<-md_gost94>).
        +
        +=item B<-config filename>
        +
        +this allows an alternative configuration file to be specified,
        +this overrides the compile time filename or any specified in
        +the B<OPENSSL_CONF> environment variable.
        +
        +=item B<-subj arg>
        +
        +sets subject name for new request or supersedes the subject name
        +when processing a request.
        +The arg must be formatted as I</type0=value0/type1=value1/type2=...>,
        +characters may be escaped by \ (backslash), no spaces are skipped.
        +
        +=item B<-multivalue-rdn>
        +
        +this option causes the -subj argument to be interpreted with full
        +support for multivalued RDNs. Example:
        +
        +I</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
        +
        +If -multi-rdn is not used then the UID value is I<123456+CN=John Doe>.
        +
        +=item B<-x509>
        +
        +this option outputs a self signed certificate instead of a certificate
        +request. This is typically used to generate a test certificate or
        +a self signed root CA. The extensions added to the certificate
        +(if any) are specified in the configuration file. Unless specified
        +using the B<set_serial> option B<0> will be used for the serial
        +number.
        +
        +=item B<-days n>
        +
        +when the B<-x509> option is being used this specifies the number of
        +days to certify the certificate for. The default is 30 days.
        +
        +=item B<-set_serial n>
        +
        +serial number to use when outputting a self signed certificate. This
        +may be specified as a decimal value or a hex value if preceded by B<0x>.
        +It is possible to use negative serial numbers but this is not recommended.
        +
        +=item B<-extensions section>
        +
        +=item B<-reqexts section>
        +
        +these options specify alternative sections to include certificate
        +extensions (if the B<-x509> option is present) or certificate
        +request extensions. This allows several different sections to
        +be used in the same configuration file to specify requests for
        +a variety of purposes.
        +
        +=item B<-utf8>
        +
        +this option causes field values to be interpreted as UTF8 strings, by 
        +default they are interpreted as ASCII. This means that the field
        +values, whether prompted from a terminal or obtained from a
        +configuration file, must be valid UTF8 strings.
        +
        +=item B<-nameopt option>
        +
        +option which determines how the subject or issuer names are displayed. The
        +B<option> argument can be a single option or multiple options separated by
        +commas.  Alternatively the B<-nameopt> switch may be used more than once to
        +set multiple options. See the L<x509(1)|x509(1)> manual page for details.
        +
        +=item B<-reqopt>
        +
        +customise the output format used with B<-text>. The B<option> argument can be
        +a single option or multiple options separated by commas. 
        +
        +See discission of the  B<-certopt> parameter in the L<B<x509>|x509(1)>
        +command.
        +
        +
        +=item B<-asn1-kludge>
        +
        +by default the B<req> command outputs certificate requests containing
        +no attributes in the correct PKCS#10 format. However certain CAs will only
        +accept requests containing no attributes in an invalid form: this
        +option produces this invalid format.
        +
        +More precisely the B<Attributes> in a PKCS#10 certificate request
        +are defined as a B<SET OF Attribute>. They are B<not OPTIONAL> so
        +if no attributes are present then they should be encoded as an
        +empty B<SET OF>. The invalid form does not include the empty
        +B<SET OF> whereas the correct form does.
        +
        +It should be noted that very few CAs still require the use of this option.
        +
        +=item B<-no-asn1-kludge>
        +
        +Reverses effect of B<-asn1-kludge>
        +
        +=item B<-newhdr>
        +
        +Adds the word B<NEW> to the PEM file header and footer lines on the outputed
        +request. Some software (Netscape certificate server) and some CAs need this.
        +
        +=item B<-batch>
        +
        +non-interactive mode.
        +
        +=item B<-verbose>
        +
        +print extra details about the operations being performed.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<req>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<-keygen_engine id>
        +
        +specifies an engine (by its unique B<id> string) which would be used
        +for key generation operations.
        +
        +=back
        +
        +=head1 CONFIGURATION FILE FORMAT
        +
        +The configuration options are specified in the B<req> section of
        +the configuration file. As with all configuration files if no
        +value is specified in the specific section (i.e. B<req>) then
        +the initial unnamed or B<default> section is searched too.
        +
        +The options available are described in detail below.
        +
        +=over 4
        +
        +=item B<input_password output_password>
        +
        +The passwords for the input private key file (if present) and
        +the output private key file (if one will be created). The
        +command line options B<passin> and B<passout> override the
        +configuration file values.
        +
        +=item B<default_bits>
        +
        +This specifies the default key size in bits. If not specified then
        +512 is used. It is used if the B<-new> option is used. It can be
        +overridden by using the B<-newkey> option.
        +
        +=item B<default_keyfile>
        +
        +This is the default filename to write a private key to. If not
        +specified the key is written to standard output. This can be
        +overridden by the B<-keyout> option.
        +
        +=item B<oid_file>
        +
        +This specifies a file containing additional B<OBJECT IDENTIFIERS>.
        +Each line of the file should consist of the numerical form of the
        +object identifier followed by white space then the short name followed
        +by white space and finally the long name. 
        +
        +=item B<oid_section>
        +
        +This specifies a section in the configuration file containing extra
        +object identifiers. Each line should consist of the short name of the
        +object identifier followed by B<=> and the numerical form. The short
        +and long names are the same when this option is used.
        +
        +=item B<RANDFILE>
        +
        +This specifies a filename in which random number seed information is
        +placed and read from, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +It is used for private key generation.
        +
        +=item B<encrypt_key>
        +
        +If this is set to B<no> then if a private key is generated it is
        +B<not> encrypted. This is equivalent to the B<-nodes> command line
        +option. For compatibility B<encrypt_rsa_key> is an equivalent option.
        +
        +=item B<default_md>
        +
        +This option specifies the digest algorithm to use. Possible values
        +include B<md5 sha1 mdc2>. If not present then MD5 is used. This
        +option can be overridden on the command line.
        +
        +=item B<string_mask>
        +
        +This option masks out the use of certain string types in certain
        +fields. Most users will not need to change this option.
        +
        +It can be set to several values B<default> which is also the default
        +option uses PrintableStrings, T61Strings and BMPStrings if the 
        +B<pkix> value is used then only PrintableStrings and BMPStrings will
        +be used. This follows the PKIX recommendation in RFC2459. If the
        +B<utf8only> option is used then only UTF8Strings will be used: this
        +is the PKIX recommendation in RFC2459 after 2003. Finally the B<nombstr>
        +option just uses PrintableStrings and T61Strings: certain software has
        +problems with BMPStrings and UTF8Strings: in particular Netscape.
        +
        +=item B<req_extensions>
        +
        +this specifies the configuration file section containing a list of
        +extensions to add to the certificate request. It can be overridden
        +by the B<-reqexts> command line switch. See the 
        +L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
        +extension section format.
        +
        +=item B<x509_extensions>
        +
        +this specifies the configuration file section containing a list of
        +extensions to add to certificate generated when the B<-x509> switch
        +is used. It can be overridden by the B<-extensions> command line switch.
        +
        +=item B<prompt>
        +
        +if set to the value B<no> this disables prompting of certificate fields
        +and just takes values from the config file directly. It also changes the
        +expected format of the B<distinguished_name> and B<attributes> sections.
        +
        +=item B<utf8>
        +
        +if set to the value B<yes> then field values to be interpreted as UTF8
        +strings, by default they are interpreted as ASCII. This means that
        +the field values, whether prompted from a terminal or obtained from a
        +configuration file, must be valid UTF8 strings.
        +
        +=item B<attributes>
        +
        +this specifies the section containing any request attributes: its format
        +is the same as B<distinguished_name>. Typically these may contain the
        +challengePassword or unstructuredName types. They are currently ignored
        +by OpenSSL's request signing utilities but some CAs might want them.
        +
        +=item B<distinguished_name>
        +
        +This specifies the section containing the distinguished name fields to
        +prompt for when generating a certificate or certificate request. The format
        +is described in the next section.
        +
        +=back
        +
        +=head1 DISTINGUISHED NAME AND ATTRIBUTE SECTION FORMAT
        +
        +There are two separate formats for the distinguished name and attribute
        +sections. If the B<prompt> option is set to B<no> then these sections
        +just consist of field names and values: for example,
        +
        + CN=My Name
        + OU=My Organization
        + emailAddress=someone@somewhere.org
        +
        +This allows external programs (e.g. GUI based) to generate a template file
        +with all the field names and values and just pass it to B<req>. An example
        +of this kind of configuration file is contained in the B<EXAMPLES> section.
        +
        +Alternatively if the B<prompt> option is absent or not set to B<no> then the
        +file contains field prompting information. It consists of lines of the form:
        +
        + fieldName="prompt"
        + fieldName_default="default field value"
        + fieldName_min= 2
        + fieldName_max= 4
        +
        +"fieldName" is the field name being used, for example commonName (or CN).
        +The "prompt" string is used to ask the user to enter the relevant
        +details. If the user enters nothing then the default value is used if no
        +default value is present then the field is omitted. A field can
        +still be omitted if a default value is present if the user just
        +enters the '.' character.
        +
        +The number of characters entered must be between the fieldName_min and
        +fieldName_max limits: there may be additional restrictions based
        +on the field being used (for example countryName can only ever be
        +two characters long and must fit in a PrintableString).
        +
        +Some fields (such as organizationName) can be used more than once
        +in a DN. This presents a problem because configuration files will
        +not recognize the same name occurring twice. To avoid this problem
        +if the fieldName contains some characters followed by a full stop
        +they will be ignored. So for example a second organizationName can
        +be input by calling it "1.organizationName".
        +
        +The actual permitted field names are any object identifier short or
        +long names. These are compiled into OpenSSL and include the usual
        +values such as commonName, countryName, localityName, organizationName,
        +organizationUnitName, stateOrProvinceName. Additionally emailAddress
        +is include as well as name, surname, givenName initials and dnQualifier.
        +
        +Additional object identifiers can be defined with the B<oid_file> or
        +B<oid_section> options in the configuration file. Any additional fields
        +will be treated as though they were a DirectoryString.
        +
        +
        +=head1 EXAMPLES
        +
        +Examine and verify certificate request:
        +
        + openssl req -in req.pem -text -verify -noout
        +
        +Create a private key and then generate a certificate request from it:
        +
        + openssl genrsa -out key.pem 1024
        + openssl req -new -key key.pem -out req.pem
        +
        +The same but just using req:
        +
        + openssl req -newkey rsa:1024 -keyout key.pem -out req.pem
        +
        +Generate a self signed root certificate:
        +
        + openssl req -x509 -newkey rsa:1024 -keyout key.pem -out req.pem
        +
        +Example of a file pointed to by the B<oid_file> option:
        +
        + 1.2.3.4	shortName	A longer Name
        + 1.2.3.6	otherName	Other longer Name
        +
        +Example of a section pointed to by B<oid_section> making use of variable
        +expansion:
        +
        + testoid1=1.2.3.5
        + testoid2=${testoid1}.6
        +
        +Sample configuration file prompting for field values:
        +
        + [ req ]
        + default_bits		= 1024
        + default_keyfile 	= privkey.pem
        + distinguished_name	= req_distinguished_name
        + attributes		= req_attributes
        + x509_extensions	= v3_ca
        +
        + dirstring_type = nobmp
        +
        + [ req_distinguished_name ]
        + countryName			= Country Name (2 letter code)
        + countryName_default		= AU
        + countryName_min		= 2
        + countryName_max		= 2
        +
        + localityName			= Locality Name (eg, city)
        +
        + organizationalUnitName		= Organizational Unit Name (eg, section)
        +
        + commonName			= Common Name (eg, YOUR name)
        + commonName_max			= 64
        +
        + emailAddress			= Email Address
        + emailAddress_max		= 40
        +
        + [ req_attributes ]
        + challengePassword		= A challenge password
        + challengePassword_min		= 4
        + challengePassword_max		= 20
        +
        + [ v3_ca ]
        +
        + subjectKeyIdentifier=hash
        + authorityKeyIdentifier=keyid:always,issuer:always
        + basicConstraints = CA:true
        +
        +Sample configuration containing all field values:
        +
        +
        + RANDFILE		= $ENV::HOME/.rnd
        +
        + [ req ]
        + default_bits		= 1024
        + default_keyfile 	= keyfile.pem
        + distinguished_name	= req_distinguished_name
        + attributes		= req_attributes
        + prompt			= no
        + output_password	= mypass
        +
        + [ req_distinguished_name ]
        + C			= GB
        + ST			= Test State or Province
        + L			= Test Locality
        + O			= Organization Name
        + OU			= Organizational Unit Name
        + CN			= Common Name
        + emailAddress		= test@email.address
        +
        + [ req_attributes ]
        + challengePassword		= A challenge password
        +
        +
        +=head1 NOTES
        +
        +The header and footer lines in the B<PEM> format are normally:
        +
        + -----BEGIN CERTIFICATE REQUEST-----
        + -----END CERTIFICATE REQUEST-----
        +
        +some software (some versions of Netscape certificate server) instead needs:
        +
        + -----BEGIN NEW CERTIFICATE REQUEST-----
        + -----END NEW CERTIFICATE REQUEST-----
        +
        +which is produced with the B<-newhdr> option but is otherwise compatible.
        +Either form is accepted transparently on input.
        +
        +The certificate requests generated by B<Xenroll> with MSIE have extensions
        +added. It includes the B<keyUsage> extension which determines the type of
        +key (signature only or general purpose) and any additional OIDs entered
        +by the script in an extendedKeyUsage extension.
        +
        +=head1 DIAGNOSTICS
        +
        +The following messages are frequently asked about:
        +
        +	Using configuration from /some/path/openssl.cnf
        +	Unable to load config info
        +
        +This is followed some time later by...
        +
        +	unable to find 'distinguished_name' in config
        +	problems making Certificate Request
        +
        +The first error message is the clue: it can't find the configuration
        +file! Certain operations (like examining a certificate request) don't
        +need a configuration file so its use isn't enforced. Generation of
        +certificates or requests however does need a configuration file. This
        +could be regarded as a bug.
        +
        +Another puzzling message is this:
        +
        +        Attributes:
        +            a0:00
        +
        +this is displayed when no attributes are present and the request includes
        +the correct empty B<SET OF> structure (the DER encoding of which is 0xa0
        +0x00). If you just see:
        +
        +        Attributes:
        +
        +then the B<SET OF> is missing and the encoding is technically invalid (but
        +it is tolerated). See the description of the command line option B<-asn1-kludge>
        +for more information.
        +
        +=head1 ENVIRONMENT VARIABLES
        +
        +The variable B<OPENSSL_CONF> if defined allows an alternative configuration
        +file location to be specified, it will be overridden by the B<-config> command
        +line switch if it is present. For compatibility reasons the B<SSLEAY_CONF>
        +environment variable serves the same purpose but its use is discouraged.
        +
        +=head1 BUGS
        +
        +OpenSSL's handling of T61Strings (aka TeletexStrings) is broken: it effectively
        +treats them as ISO-8859-1 (Latin 1), Netscape and MSIE have similar behaviour.
        +This can cause problems if you need characters that aren't available in
        +PrintableStrings and you don't want to or can't use BMPStrings.
        +
        +As a consequence of the T61String handling the only correct way to represent
        +accented characters in OpenSSL is to use a BMPString: unfortunately Netscape
        +currently chokes on these. If you have to use accented characters with Netscape
        +and MSIE then you currently need to use the invalid T61String form.
        +
        +The current prompting is not very friendly. It doesn't allow you to confirm what
        +you've just entered. Other things like extensions in certificate requests are
        +statically defined in the configuration file. Some of these: like an email
        +address in subjectAltName should be input by the user.
        +
        +=head1 SEE ALSO
        +
        +L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>,
        +L<gendsa(1)|gendsa(1)>, L<config(5)|config(5)>,
        +L<x509v3_config(5)|x509v3_config(5)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/rsa.pod b/vendor/openssl/openssl/doc/apps/rsa.pod
        new file mode 100644
        index 000000000..69b2bef82
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/rsa.pod
        @@ -0,0 +1,189 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +rsa - RSA key processing tool
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<rsa>
        +[B<-inform PEM|NET|DER>]
        +[B<-outform PEM|NET|DER>]
        +[B<-in filename>]
        +[B<-passin arg>]
        +[B<-out filename>]
        +[B<-passout arg>]
        +[B<-sgckey>]
        +[B<-des>]
        +[B<-des3>]
        +[B<-idea>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-modulus>]
        +[B<-check>]
        +[B<-pubin>]
        +[B<-pubout>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<rsa> command processes RSA keys. They can be converted between various
        +forms and their components printed out. B<Note> this command uses the
        +traditional SSLeay compatible format for private key encryption: newer
        +applications should use the more secure PKCS#8 format using the B<pkcs8>
        +utility.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|NET|PEM>
        +
        +This specifies the input format. The B<DER> option uses an ASN1 DER encoded
        +form compatible with the PKCS#1 RSAPrivateKey or SubjectPublicKeyInfo format.
        +The B<PEM> form is the default format: it consists of the B<DER> format base64
        +encoded with additional header and footer lines. On input PKCS#8 format private
        +keys are also accepted. The B<NET> form is a format is described in the B<NOTES>
        +section.
        +
        +=item B<-outform DER|NET|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a key from or standard input if this
        +option is not specified. If the key is encrypted a pass phrase will be
        +prompted for.
        +
        +=item B<-passin arg>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write a key to or standard output if this
        +option is not specified. If any encryption options are set then a pass phrase
        +will be prompted for. The output filename should B<not> be the same as the input
        +filename.
        +
        +=item B<-passout password>
        +
        +the output file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-sgckey>
        +
        +use the modified NET algorithm used with some versions of Microsoft IIS and SGC
        +keys.
        +
        +=item B<-des|-des3|-idea>
        +
        +These options encrypt the private key with the DES, triple DES, or the 
        +IDEA ciphers respectively before outputting it. A pass phrase is prompted for.
        +If none of these options is specified the key is written in plain text. This
        +means that using the B<rsa> utility to read in an encrypted key with no
        +encryption option can be used to remove the pass phrase from a key, or by
        +setting the encryption options it can be use to add or change the pass phrase.
        +These options can only be used with PEM format output files.
        +
        +=item B<-text>
        +
        +prints out the various public or private key components in
        +plain text in addition to the encoded version. 
        +
        +=item B<-noout>
        +
        +this option prevents output of the encoded version of the key.
        +
        +=item B<-modulus>
        +
        +this option prints out the value of the modulus of the key.
        +
        +=item B<-check>
        +
        +this option checks the consistency of an RSA private key.
        +
        +=item B<-pubin>
        +
        +by default a private key is read from the input file: with this
        +option a public key is read instead.
        +
        +=item B<-pubout>
        +
        +by default a private key is output: with this option a public
        +key will be output instead. This option is automatically set if
        +the input is a public key.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<rsa>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The PEM private key format uses the header and footer lines:
        +
        + -----BEGIN RSA PRIVATE KEY-----
        + -----END RSA PRIVATE KEY-----
        +
        +The PEM public key format uses the header and footer lines:
        +
        + -----BEGIN PUBLIC KEY-----
        + -----END PUBLIC KEY-----
        +
        +The B<NET> form is a format compatible with older Netscape servers
        +and Microsoft IIS .key files, this uses unsalted RC4 for its encryption.
        +It is not very secure and so should only be used when necessary.
        +
        +Some newer version of IIS have additional data in the exported .key
        +files. To use these with the utility, view the file with a binary editor
        +and look for the string "private-key", then trace back to the byte
        +sequence 0x30, 0x82 (this is an ASN1 SEQUENCE). Copy all the data
        +from this point onwards to another file and use that as the input
        +to the B<rsa> utility with the B<-inform NET> option. If you get
        +an error after entering the password try the B<-sgckey> option.
        +
        +=head1 EXAMPLES
        +
        +To remove the pass phrase on an RSA private key:
        +
        + openssl rsa -in key.pem -out keyout.pem
        +
        +To encrypt a private key using triple DES:
        +
        + openssl rsa -in key.pem -des3 -out keyout.pem
        +
        +To convert a private key from PEM to DER format: 
        +
        + openssl rsa -in key.pem -outform DER -out keyout.der
        +
        +To print out the components of a private key to standard output:
        +
        + openssl rsa -in key.pem -text -noout
        +
        +To just output the public part of a private key:
        +
        + openssl rsa -in key.pem -pubout -out pubkey.pem
        +
        +=head1 BUGS
        +
        +The command line password arguments don't currently work with
        +B<NET> format.
        +
        +There should be an option that automatically handles .key files,
        +without having to manually edit them.
        +
        +=head1 SEE ALSO
        +
        +L<pkcs8(1)|pkcs8(1)>, L<dsa(1)|dsa(1)>, L<genrsa(1)|genrsa(1)>,
        +L<gendsa(1)|gendsa(1)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/rsautl.pod b/vendor/openssl/openssl/doc/apps/rsautl.pod
        new file mode 100644
        index 000000000..1a498c2f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/rsautl.pod
        @@ -0,0 +1,183 @@
        +=pod
        +
        +=head1 NAME
        +
        +rsautl - RSA utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<rsautl>
        +[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<rsautl> 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<rsautl> 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 -verify -in sig -inkey key.pem
        +
        +Examine the raw signed data:
        +
        + openssl rsautl -verify -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<asn1parse>. Consider the self signed
        +example in certs/pca-cert.pem . Running B<asn1parse> 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 -pubkey -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<dgst(1)|dgst(1)>, L<rsa(1)|rsa(1)>, L<genrsa(1)|genrsa(1)>
        diff --git a/vendor/openssl/openssl/doc/apps/s_client.pod b/vendor/openssl/openssl/doc/apps/s_client.pod
        new file mode 100644
        index 000000000..4ebf7b585
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/s_client.pod
        @@ -0,0 +1,306 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +s_client - SSL/TLS client program
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<s_client>
        +[B<-connect host:port>]
        +[B<-verify depth>]
        +[B<-cert filename>]
        +[B<-certform DER|PEM>]
        +[B<-key filename>]
        +[B<-keyform DER|PEM>]
        +[B<-pass arg>]
        +[B<-CApath directory>]
        +[B<-CAfile filename>]
        +[B<-reconnect>]
        +[B<-pause>]
        +[B<-showcerts>]
        +[B<-debug>]
        +[B<-msg>]
        +[B<-nbio_test>]
        +[B<-state>]
        +[B<-nbio>]
        +[B<-crlf>]
        +[B<-ign_eof>]
        +[B<-quiet>]
        +[B<-ssl2>]
        +[B<-ssl3>]
        +[B<-tls1>]
        +[B<-no_ssl2>]
        +[B<-no_ssl3>]
        +[B<-no_tls1>]
        +[B<-bugs>]
        +[B<-cipher cipherlist>]
        +[B<-starttls protocol>]
        +[B<-engine id>]
        +[B<-tlsextdebug>]
        +[B<-no_ticket>]
        +[B<-sess_out filename>]
        +[B<-sess_in filename>]
        +[B<-rand file(s)>]
        +
        +=head1 DESCRIPTION
        +
        +The B<s_client> command implements a generic SSL/TLS client which connects
        +to a remote host using SSL/TLS. It is a I<very> useful diagnostic tool for
        +SSL servers.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-connect host:port>
        +
        +This specifies the host and optional port to connect to. If not specified
        +then an attempt is made to connect to the local host on port 4433.
        +
        +=item B<-cert certname>
        +
        +The certificate to use, if one is requested by the server. The default is
        +not to use a certificate.
        +
        +=item B<-certform format>
        +
        +The certificate format to use: DER or PEM. PEM is the default.
        +
        +=item B<-key keyfile>
        +
        +The private key to use. If not specified then the certificate file will
        +be used.
        +
        +=item B<-keyform format>
        +
        +The private format to use: DER or PEM. PEM is the default.
        +
        +=item B<-pass arg>
        +
        +the private key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-verify depth>
        +
        +The verify depth to use. This specifies the maximum length of the
        +server certificate chain and turns on server certificate verification.
        +Currently the verify operation continues after errors so all the problems
        +with a certificate chain can be seen. As a side effect the connection
        +will never fail due to a server certificate verify failure.
        +
        +=item B<-CApath directory>
        +
        +The directory to use for server certificate verification. This directory
        +must be in "hash format", see B<verify> for more information. These are
        +also used when building the client certificate chain.
        +
        +=item B<-CAfile file>
        +
        +A file containing trusted certificates to use during server authentication
        +and to use when attempting to build the client certificate chain.
        +
        +=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
        +
        +Set various certificate chain valiadition option. See the
        +L<B<verify>|verify(1)> manual page for details.
        +
        +=item B<-reconnect>
        +
        +reconnects to the same server 5 times using the same session ID, this can
        +be used as a test that session caching is working.
        +
        +=item B<-pause>
        +
        +pauses 1 second between each read and write call.
        +
        +=item B<-showcerts>
        +
        +display the whole server certificate chain: normally only the server
        +certificate itself is displayed.
        +
        +=item B<-prexit>
        +
        +print session information when the program exits. This will always attempt
        +to print out information even if the connection fails. Normally information
        +will only be printed out once if the connection succeeds. This option is useful
        +because the cipher in use may be renegotiated or the connection may fail
        +because a client certificate is required or is requested only after an
        +attempt is made to access a certain URL. Note: the output produced by this
        +option is not always accurate because a connection might never have been
        +established.
        +
        +=item B<-state>
        +
        +prints out the SSL session states.
        +
        +=item B<-debug>
        +
        +print extensive debugging information including a hex dump of all traffic.
        +
        +=item B<-msg>
        +
        +show all protocol messages with hex dump.
        +
        +=item B<-nbio_test>
        +
        +tests non-blocking I/O
        +
        +=item B<-nbio>
        +
        +turns on non-blocking I/O
        +
        +=item B<-crlf>
        +
        +this option translated a line feed from the terminal into CR+LF as required
        +by some servers.
        +
        +=item B<-ign_eof>
        +
        +inhibit shutting down the connection when end of file is reached in the
        +input.
        +
        +=item B<-quiet>
        +
        +inhibit printing of session and certificate information.  This implicitly
        +turns on B<-ign_eof> as well.
        +
        +=item B<-psk_identity identity>
        +
        +Use the PSK identity B<identity> when using a PSK cipher suite.
        +
        +=item B<-psk key>
        +
        +Use the PSK key B<key> when using a PSK cipher suite. The key is
        +given as a hexadecimal number without leading 0x, for example -psk
        +1a2b3c4d.
        +
        +=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>
        +
        +these options disable the use of certain SSL or TLS protocols. By default
        +the initial handshake uses a method which should be compatible with all
        +servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
        +
        +Unfortunately there are a lot of ancient and broken servers in use which
        +cannot handle this technique and will fail to connect. Some servers only
        +work if TLS is turned off with the B<-no_tls> option others will only
        +support SSL v2 and may need the B<-ssl2> option.
        +
        +=item B<-bugs>
        +
        +there are several known bug in SSL and TLS implementations. Adding this
        +option enables various workarounds.
        +
        +=item B<-cipher cipherlist>
        +
        +this allows the cipher list sent by the client to be modified. Although
        +the server determines which cipher suite is used it should take the first
        +supported cipher in the list sent by the client. See the B<ciphers>
        +command for more information.
        +
        +=item B<-starttls protocol>
        +
        +send the protocol-specific message(s) to switch to TLS for communication.
        +B<protocol> is a keyword for the intended protocol.  Currently, the only
        +supported keywords are "smtp", "pop3", "imap", and "ftp".
        +
        +=item B<-tlsextdebug>
        +
        +print out a hex dump of any TLS extensions received from the server.
        +
        +=item B<-no_ticket>
        +
        +disable RFC4507bis session ticket support. 
        +
        +=item B<-sess_out filename>
        +
        +output SSL session to B<filename>
        +
        +=item B<-sess_in sess.pem>
        +
        +load SSL session from B<filename>. The client will attempt to resume a
        +connection from this session.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<s_client>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=back
        +
        +=head1 CONNECTED COMMANDS
        +
        +If a connection is established with an SSL server then any data received
        +from the server is displayed and any key presses will be sent to the
        +server. When used interactively (which means neither B<-quiet> nor B<-ign_eof>
        +have been given), the session will be renegotiated if the line begins with an
        +B<R>, and if the line begins with a B<Q> or if end of file is reached, the
        +connection will be closed down.
        +
        +=head1 NOTES
        +
        +B<s_client> can be used to debug SSL servers. To connect to an SSL HTTP
        +server the command:
        +
        + openssl s_client -connect servername:443
        +
        +would typically be used (https uses port 443). If the connection succeeds
        +then an HTTP command can be given such as "GET /" to retrieve a web page.
        +
        +If the handshake fails then there are several possible causes, if it is
        +nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
        +B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> options can be tried
        +in case it is a buggy server. In particular you should play with these
        +options B<before> submitting a bug report to an OpenSSL mailing list.
        +
        +A frequent problem when attempting to get client certificates working
        +is that a web client complains it has no certificates or gives an empty
        +list to choose from. This is normally because the server is not sending
        +the clients certificate authority in its "acceptable CA list" when it
        +requests a certificate. By using B<s_client> the CA list can be viewed
        +and checked. However some servers only request client authentication
        +after a specific URL is requested. To obtain the list in this case it
        +is necessary to use the B<-prexit> option and send an HTTP request
        +for an appropriate page.
        +
        +If a certificate is specified on the command line using the B<-cert>
        +option it will not be used unless the server specifically requests
        +a client certificate. Therefor merely including a client certificate
        +on the command line is no guarantee that the certificate works.
        +
        +If there are problems verifying a server certificate then the
        +B<-showcerts> option can be used to show the whole chain.
        +
        +Since the SSLv23 client hello cannot include compression methods or extensions
        +these will only be supported if its use is disabled, for example by using the
        +B<-no_sslv2> option.
        +
        +=head1 BUGS
        +
        +Because this program has a lot of options and also because some of
        +the techniques used are rather old, the C source of s_client is rather
        +hard to read and not a model of how things should be done. A typical
        +SSL client program would be much simpler.
        +
        +The B<-verify> option should really exit if the server verification
        +fails.
        +
        +The B<-prexit> option is a bit of a hack. We should really report
        +information whenever a session is renegotiated.
        +
        +=head1 SEE ALSO
        +
        +L<sess_id(1)|sess_id(1)>, L<s_server(1)|s_server(1)>, L<ciphers(1)|ciphers(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/s_server.pod b/vendor/openssl/openssl/doc/apps/s_server.pod
        new file mode 100644
        index 000000000..3e503e17e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/s_server.pod
        @@ -0,0 +1,355 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +s_server - SSL/TLS server program
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<s_server>
        +[B<-accept port>]
        +[B<-context id>]
        +[B<-verify depth>]
        +[B<-Verify depth>]
        +[B<-crl_check>]
        +[B<-crl_check_all>]
        +[B<-cert filename>]
        +[B<-certform DER|PEM>]
        +[B<-key keyfile>]
        +[B<-keyform DER|PEM>]
        +[B<-pass arg>]
        +[B<-dcert filename>]
        +[B<-dcertform DER|PEM>]
        +[B<-dkey keyfile>]
        +[B<-dkeyform DER|PEM>]
        +[B<-dpass arg>]
        +[B<-dhparam filename>]
        +[B<-nbio>]
        +[B<-nbio_test>]
        +[B<-crlf>]
        +[B<-debug>]
        +[B<-msg>]
        +[B<-state>]
        +[B<-CApath directory>]
        +[B<-CAfile filename>]
        +[B<-nocert>]
        +[B<-cipher cipherlist>]
        +[B<-quiet>]
        +[B<-no_tmp_rsa>]
        +[B<-ssl2>]
        +[B<-ssl3>]
        +[B<-tls1>]
        +[B<-no_ssl2>]
        +[B<-no_ssl3>]
        +[B<-no_tls1>]
        +[B<-no_dhe>]
        +[B<-bugs>]
        +[B<-hack>]
        +[B<-www>]
        +[B<-WWW>]
        +[B<-HTTP>]
        +[B<-engine id>]
        +[B<-tlsextdebug>]
        +[B<-no_ticket>]
        +[B<-id_prefix arg>]
        +[B<-rand file(s)>]
        +
        +=head1 DESCRIPTION
        +
        +The B<s_server> command implements a generic SSL/TLS server which listens
        +for connections on a given port using SSL/TLS.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-accept port>
        +
        +the TCP port to listen on for connections. If not specified 4433 is used.
        +
        +=item B<-context id>
        +
        +sets the SSL context id. It can be given any string value. If this option
        +is not present a default value will be used.
        +
        +=item B<-cert certname>
        +
        +The certificate to use, most servers cipher suites require the use of a
        +certificate and some require a certificate with a certain public key type:
        +for example the DSS cipher suites require a certificate containing a DSS
        +(DSA) key. If not specified then the filename "server.pem" will be used.
        +
        +=item B<-certform format>
        +
        +The certificate format to use: DER or PEM. PEM is the default.
        +
        +=item B<-key keyfile>
        +
        +The private key to use. If not specified then the certificate file will
        +be used.
        +
        +=item B<-keyform format>
        +
        +The private format to use: DER or PEM. PEM is the default.
        +
        +=item B<-pass arg>
        +
        +the private key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-dcert filename>, B<-dkey keyname>
        +
        +specify an additional certificate and private key, these behave in the
        +same manner as the B<-cert> and B<-key> options except there is no default
        +if they are not specified (no additional certificate and key is used). As
        +noted above some cipher suites require a certificate containing a key of
        +a certain type. Some cipher suites need a certificate carrying an RSA key
        +and some a DSS (DSA) key. By using RSA and DSS certificates and keys
        +a server can support clients which only support RSA or DSS cipher suites
        +by using an appropriate certificate.
        +
        +=item B<-dcertform format>, B<-dkeyform format>, B<-dpass arg>
        +
        +addtional certificate and private key format and passphrase respectively.
        +
        +=item B<-nocert>
        +
        +if this option is set then no certificate is used. This restricts the
        +cipher suites available to the anonymous ones (currently just anonymous
        +DH).
        +
        +=item B<-dhparam filename>
        +
        +the DH parameter file to use. The ephemeral DH cipher suites generate keys
        +using a set of DH parameters. If not specified then an attempt is made to
        +load the parameters from the server certificate file. If this fails then
        +a static set of parameters hard coded into the s_server program will be used.
        +
        +=item B<-no_dhe>
        +
        +if this option is set then no DH parameters will be loaded effectively
        +disabling the ephemeral DH cipher suites.
        +
        +=item B<-no_tmp_rsa>
        +
        +certain export cipher suites sometimes use a temporary RSA key, this option
        +disables temporary RSA key generation.
        +
        +=item B<-verify depth>, B<-Verify depth>
        +
        +The verify depth to use. This specifies the maximum length of the
        +client certificate chain and makes the server request a certificate from
        +the client. With the B<-verify> option a certificate is requested but the
        +client does not have to send one, with the B<-Verify> option the client
        +must supply a certificate or an error occurs.
        +
        +=item B<-crl_check>, B<-crl_check_all>
        +
        +Check the peer certificate has not been revoked by its CA.
        +The CRL(s) are appended to the certificate file. With the B<-crl_check_all>
        +option all CRLs of all CAs in the chain are checked.
        +
        +=item B<-CApath directory>
        +
        +The directory to use for client certificate verification. This directory
        +must be in "hash format", see B<verify> for more information. These are
        +also used when building the server certificate chain.
        +
        +=item B<-CAfile file>
        +
        +A file containing trusted certificates to use during client authentication
        +and to use when attempting to build the server certificate chain. The list
        +is also used in the list of acceptable client CAs passed to the client when
        +a certificate is requested.
        +
        +=item B<-state>
        +
        +prints out the SSL session states.
        +
        +=item B<-debug>
        +
        +print extensive debugging information including a hex dump of all traffic.
        +
        +=item B<-msg>
        +
        +show all protocol messages with hex dump.
        +
        +=item B<-nbio_test>
        +
        +tests non blocking I/O
        +
        +=item B<-nbio>
        +
        +turns on non blocking I/O
        +
        +=item B<-crlf>
        +
        +this option translated a line feed from the terminal into CR+LF.
        +
        +=item B<-quiet>
        +
        +inhibit printing of session and certificate information.
        +
        +=item B<-psk_hint hint>
        +
        +Use the PSK identity hint B<hint> when using a PSK cipher suite.
        +
        +=item B<-psk key>
        +
        +Use the PSK key B<key> when using a PSK cipher suite. The key is
        +given as a hexadecimal number without leading 0x, for example -psk
        +1a2b3c4d.
        +
        +=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>
        +
        +these options disable the use of certain SSL or TLS protocols. By default
        +the initial handshake uses a method which should be compatible with all
        +servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
        +
        +=item B<-bugs>
        +
        +there are several known bug in SSL and TLS implementations. Adding this
        +option enables various workarounds.
        +
        +=item B<-hack>
        +
        +this option enables a further workaround for some some early Netscape
        +SSL code (?).
        +
        +=item B<-cipher cipherlist>
        +
        +this allows the cipher list used by the server to be modified.  When
        +the client sends a list of supported ciphers the first client cipher
        +also included in the server list is used. Because the client specifies
        +the preference order, the order of the server cipherlist irrelevant. See
        +the B<ciphers> command for more information.
        +
        +=item B<-tlsextdebug>
        +
        +print out a hex dump of any TLS extensions received from the server.
        +
        +=item B<-no_ticket>
        +
        +disable RFC4507bis session ticket support. 
        +
        +=item B<-www>
        +
        +sends a status message back to the client when it connects. This includes
        +lots of information about the ciphers used and various session parameters.
        +The output is in HTML format so this option will normally be used with a
        +web browser.
        +
        +=item B<-WWW>
        +
        +emulates a simple web server. Pages will be resolved relative to the
        +current directory, for example if the URL https://myhost/page.html is
        +requested the file ./page.html will be loaded.
        +
        +=item B<-HTTP>
        +
        +emulates a simple web server. Pages will be resolved relative to the
        +current directory, for example if the URL https://myhost/page.html is
        +requested the file ./page.html will be loaded. The files loaded are
        +assumed to contain a complete and correct HTTP response (lines that
        +are part of the HTTP response line and headers must end with CRLF).
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<s_server>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<-id_prefix arg>
        +
        +generate SSL/TLS session IDs prefixed by B<arg>. This is mostly useful
        +for testing any SSL/TLS code (eg. proxies) that wish to deal with multiple
        +servers, when each of which might be generating a unique range of session
        +IDs (eg. with a certain prefix).
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=back
        +
        +=head1 CONNECTED COMMANDS
        +
        +If a connection request is established with an SSL client and neither the
        +B<-www> nor the B<-WWW> option has been used then normally any data received
        +from the client is displayed and any key presses will be sent to the client. 
        +
        +Certain single letter commands are also recognized which perform special
        +operations: these are listed below.
        +
        +=over 4
        +
        +=item B<q>
        +
        +end the current SSL connection but still accept new connections.
        +
        +=item B<Q>
        +
        +end the current SSL connection and exit.
        +
        +=item B<r>
        +
        +renegotiate the SSL session.
        +
        +=item B<R>
        +
        +renegotiate the SSL session and request a client certificate.
        +
        +=item B<P>
        +
        +send some plain text down the underlying TCP connection: this should
        +cause the client to disconnect due to a protocol violation.
        +
        +=item B<S>
        +
        +print out some session cache status information.
        +
        +=back
        +
        +=head1 NOTES
        +
        +B<s_server> can be used to debug SSL clients. To accept connections from
        +a web browser the command:
        +
        + openssl s_server -accept 443 -www
        +
        +can be used for example.
        +
        +Most web browsers (in particular Netscape and MSIE) only support RSA cipher
        +suites, so they cannot connect to servers which don't use a certificate
        +carrying an RSA key or a version of OpenSSL with RSA disabled.
        +
        +Although specifying an empty list of CAs when requesting a client certificate
        +is strictly speaking a protocol violation, some SSL clients interpret this to
        +mean any CA is acceptable. This is useful for debugging purposes.
        +
        +The session parameters can printed out using the B<sess_id> program.
        +
        +=head1 BUGS
        +
        +Because this program has a lot of options and also because some of
        +the techniques used are rather old, the C source of s_server is rather
        +hard to read and not a model of how things should be done. A typical
        +SSL server program would be much simpler.
        +
        +The output of common ciphers is wrong: it just gives the list of ciphers that
        +OpenSSL recognizes and the client supports.
        +
        +There should be a way for the B<s_server> program to print out details of any
        +unknown cipher suites a client says it supports.
        +
        +=head1 SEE ALSO
        +
        +L<sess_id(1)|sess_id(1)>, L<s_client(1)|s_client(1)>, L<ciphers(1)|ciphers(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/s_time.pod b/vendor/openssl/openssl/doc/apps/s_time.pod
        new file mode 100644
        index 000000000..5a38aa2e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/s_time.pod
        @@ -0,0 +1,173 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +s_time - SSL/TLS performance timing program
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<s_time>
        +[B<-connect host:port>]
        +[B<-www page>]
        +[B<-cert filename>]
        +[B<-key filename>]
        +[B<-CApath directory>]
        +[B<-CAfile filename>]
        +[B<-reuse>]
        +[B<-new>]
        +[B<-verify depth>]
        +[B<-nbio>]
        +[B<-time seconds>]
        +[B<-ssl2>]
        +[B<-ssl3>]
        +[B<-bugs>]
        +[B<-cipher cipherlist>]
        +
        +=head1 DESCRIPTION
        +
        +The B<s_client> command implements a generic SSL/TLS client which connects to a
        +remote host using SSL/TLS. It can request a page from the server and includes
        +the time to transfer the payload data in its timing measurements. It measures
        +the number of connections within a given timeframe, the amount of data
        +transferred (if any), and calculates the average time spent for one connection.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-connect host:port>
        +
        +This specifies the host and optional port to connect to.
        +
        +=item B<-www page>
        +
        +This specifies the page to GET from the server. A value of '/' gets the
        +index.htm[l] page. If this parameter is not specified, then B<s_time> will only
        +perform the handshake to establish SSL connections but not transfer any
        +payload data.
        +
        +=item B<-cert certname>
        +
        +The certificate to use, if one is requested by the server. The default is
        +not to use a certificate. The file is in PEM format.
        +
        +=item B<-key keyfile>
        +
        +The private key to use. If not specified then the certificate file will
        +be used. The file is in PEM format.
        +
        +=item B<-verify depth>
        +
        +The verify depth to use. This specifies the maximum length of the
        +server certificate chain and turns on server certificate verification.
        +Currently the verify operation continues after errors so all the problems
        +with a certificate chain can be seen. As a side effect the connection
        +will never fail due to a server certificate verify failure.
        +
        +=item B<-CApath directory>
        +
        +The directory to use for server certificate verification. This directory
        +must be in "hash format", see B<verify> for more information. These are
        +also used when building the client certificate chain.
        +
        +=item B<-CAfile file>
        +
        +A file containing trusted certificates to use during server authentication
        +and to use when attempting to build the client certificate chain.
        +
        +=item B<-new>
        +
        +performs the timing test using a new session ID for each connection.
        +If neither B<-new> nor B<-reuse> are specified, they are both on by default
        +and executed in sequence.
        +
        +=item B<-reuse>
        +
        +performs the timing test using the same session ID; this can be used as a test
        +that session caching is working. If neither B<-new> nor B<-reuse> are
        +specified, they are both on by default and executed in sequence.
        +
        +=item B<-nbio>
        +
        +turns on non-blocking I/O.
        +
        +=item B<-ssl2>, B<-ssl3>
        +
        +these options disable the use of certain SSL or TLS protocols. By default
        +the initial handshake uses a method which should be compatible with all
        +servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
        +The timing program is not as rich in options to turn protocols on and off as
        +the L<s_client(1)|s_client(1)> program and may not connect to all servers.
        +
        +Unfortunately there are a lot of ancient and broken servers in use which
        +cannot handle this technique and will fail to connect. Some servers only
        +work if TLS is turned off with the B<-ssl3> option; others
        +will only support SSL v2 and may need the B<-ssl2> option.
        +
        +=item B<-bugs>
        +
        +there are several known bug in SSL and TLS implementations. Adding this
        +option enables various workarounds.
        +
        +=item B<-cipher cipherlist>
        +
        +this allows the cipher list sent by the client to be modified. Although
        +the server determines which cipher suite is used it should take the first
        +supported cipher in the list sent by the client.
        +See the L<ciphers(1)|ciphers(1)> command for more information.
        +
        +=item B<-time length>
        +
        +specifies how long (in seconds) B<s_time> should establish connections and
        +optionally transfer payload data from a server. Server and client performance
        +and the link speed determine how many connections B<s_time> can establish.
        +
        +=back
        +
        +=head1 NOTES
        +
        +B<s_client> can be used to measure the performance of an SSL connection.
        +To connect to an SSL HTTP server and get the default page the command
        +
        + openssl s_time -connect servername:443 -www / -CApath yourdir -CAfile yourfile.pem -cipher commoncipher [-ssl3]
        +
        +would typically be used (https uses port 443). 'commoncipher' is a cipher to
        +which both client and server can agree, see the L<ciphers(1)|ciphers(1)> command
        +for details.
        +
        +If the handshake fails then there are several possible causes, if it is
        +nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
        +B<-ssl3> options can be tried
        +in case it is a buggy server. In particular you should play with these
        +options B<before> submitting a bug report to an OpenSSL mailing list.
        +
        +A frequent problem when attempting to get client certificates working
        +is that a web client complains it has no certificates or gives an empty
        +list to choose from. This is normally because the server is not sending
        +the clients certificate authority in its "acceptable CA list" when it
        +requests a certificate. By using L<s_client(1)|s_client(1)> the CA list can be
        +viewed and checked. However some servers only request client authentication
        +after a specific URL is requested. To obtain the list in this case it
        +is necessary to use the B<-prexit> option of L<s_client(1)|s_client(1)> and
        +send an HTTP request for an appropriate page.
        +
        +If a certificate is specified on the command line using the B<-cert>
        +option it will not be used unless the server specifically requests
        +a client certificate. Therefor merely including a client certificate
        +on the command line is no guarantee that the certificate works.
        +
        +=head1 BUGS
        +
        +Because this program does not have all the options of the
        +L<s_client(1)|s_client(1)> program to turn protocols on and off, you may not be
        +able to measure the performance of all protocols with all servers.
        +
        +The B<-verify> option should really exit if the server verification
        +fails.
        +
        +=head1 SEE ALSO
        +
        +L<s_client(1)|s_client(1)>, L<s_server(1)|s_server(1)>, L<ciphers(1)|ciphers(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/sess_id.pod b/vendor/openssl/openssl/doc/apps/sess_id.pod
        new file mode 100644
        index 000000000..9988d2cd3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/sess_id.pod
        @@ -0,0 +1,151 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +sess_id - SSL/TLS session handling utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<sess_id>
        +[B<-inform PEM|DER>]
        +[B<-outform PEM|DER>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-text>]
        +[B<-noout>]
        +[B<-context ID>]
        +
        +=head1 DESCRIPTION
        +
        +The B<sess_id> process the encoded version of the SSL session structure
        +and optionally prints out SSL session details (for example the SSL session
        +master key) in human readable format. Since this is a diagnostic tool that
        +needs some knowledge of the SSL protocol to use properly, most users will
        +not need to use it.
        +
        +=over 4
        +
        +=item B<-inform DER|PEM>
        +
        +This specifies the input format. The B<DER> option uses an ASN1 DER encoded
        +format containing session details. The precise format can vary from one version
        +to the next.  The B<PEM> form is the default format: it consists of the B<DER>
        +format base64 encoded with additional header and footer lines.
        +
        +=item B<-outform DER|PEM>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read session information from or standard
        +input by default.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write session information to or standard
        +output if this option is not specified.
        +
        +=item B<-text>
        +
        +prints out the various public or private key components in
        +plain text in addition to the encoded version. 
        +
        +=item B<-cert>
        +
        +if a certificate is present in the session it will be output using this option,
        +if the B<-text> option is also present then it will be printed out in text form.
        +
        +=item B<-noout>
        +
        +this option prevents output of the encoded version of the session.
        +
        +=item B<-context ID>
        +
        +this option can set the session id so the output session information uses the
        +supplied ID. The ID can be any string of characters. This option wont normally
        +be used.
        +
        +=back
        +
        +=head1 OUTPUT
        +
        +Typical output:
        +
        + SSL-Session:
        +     Protocol  : TLSv1
        +     Cipher    : 0016
        +     Session-ID: 871E62626C554CE95488823752CBD5F3673A3EF3DCE9C67BD916C809914B40ED
        +     Session-ID-ctx: 01000000
        +     Master-Key: A7CEFC571974BE02CAC305269DC59F76EA9F0B180CB6642697A68251F2D2BB57E51DBBB4C7885573192AE9AEE220FACD
        +     Key-Arg   : None
        +     Start Time: 948459261
        +     Timeout   : 300 (sec)
        +     Verify return code 0 (ok)
        +
        +Theses are described below in more detail.
        +
        +=over 4
        +
        +=item B<Protocol>
        +
        +this is the protocol in use TLSv1, SSLv3 or SSLv2.
        +
        +=item B<Cipher>
        +
        +the cipher used this is the actual raw SSL or TLS cipher code, see the SSL
        +or TLS specifications for more information.
        +
        +=item B<Session-ID>
        +
        +the SSL session ID in hex format.
        +
        +=item B<Session-ID-ctx>
        +
        +the session ID context in hex format.
        +
        +=item B<Master-Key>
        +
        +this is the SSL session master key.
        +
        +=item B<Key-Arg>
        +
        +the key argument, this is only used in SSL v2.
        +
        +=item B<Start Time>
        +
        +this is the session start time represented as an integer in standard Unix format.
        +
        +=item B<Timeout>
        +
        +the timeout in seconds.
        +
        +=item B<Verify return code>
        +
        +this is the return code when an SSL client certificate is verified.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The PEM encoded session format uses the header and footer lines:
        +
        + -----BEGIN SSL SESSION PARAMETERS-----
        + -----END SSL SESSION PARAMETERS-----
        +
        +Since the SSL session output contains the master key it is possible to read the contents
        +of an encrypted session using this information. Therefore appropriate security precautions
        +should be taken if the information is being output by a "real" application. This is
        +however strongly discouraged and should only be used for debugging purposes.
        +
        +=head1 BUGS
        +
        +The cipher and start time should be printed out in human readable form.
        +
        +=head1 SEE ALSO
        +
        +L<ciphers(1)|ciphers(1)>, L<s_server(1)|s_server(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/smime.pod b/vendor/openssl/openssl/doc/apps/smime.pod
        new file mode 100644
        index 000000000..e4e89af84
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/smime.pod
        @@ -0,0 +1,445 @@
        +=pod
        +
        +=head1 NAME
        +
        +smime - S/MIME utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<smime>
        +[B<-encrypt>]
        +[B<-decrypt>]
        +[B<-sign>]
        +[B<-resign>]
        +[B<-verify>]
        +[B<-pk7out>]
        +[B<-[cipher]>]
        +[B<-in file>]
        +[B<-certfile file>]
        +[B<-signer file>]
        +[B<-recip  file>]
        +[B<-inform SMIME|PEM|DER>]
        +[B<-passin arg>]
        +[B<-inkey file>]
        +[B<-out file>]
        +[B<-outform SMIME|PEM|DER>]
        +[B<-content file>]
        +[B<-to addr>]
        +[B<-from ad>]
        +[B<-subject s>]
        +[B<-text>]
        +[B<-indef>]
        +[B<-noindef>]
        +[B<-stream>]
        +[B<-rand file(s)>]
        +[B<-md digest>]
        +[cert.pem]...
        +
        +=head1 DESCRIPTION
        +
        +The B<smime> command handles S/MIME mail. It can encrypt, decrypt, sign and
        +verify S/MIME messages.
        +
        +=head1 COMMAND OPTIONS
        +
        +There are six operation options that set the type of operation to be performed.
        +The meaning of the other options varies according to the operation type.
        +
        +=over 4
        +
        +=item B<-encrypt>
        +
        +encrypt mail for the given recipient certificates. Input file is the message
        +to be encrypted. The output file is the encrypted mail in MIME format.
        +
        +=item B<-decrypt>
        +
        +decrypt mail using the supplied certificate and private key. Expects an
        +encrypted mail message in MIME format for the input file. The decrypted mail
        +is written to the output file.
        +
        +=item B<-sign>
        +
        +sign mail using the supplied certificate and private key. Input file is
        +the message to be signed. The signed message in MIME format is written
        +to the output file.
        +
        +=item B<-verify>
        +
        +verify signed mail. Expects a signed mail message on input and outputs
        +the signed data. Both clear text and opaque signing is supported.
        +
        +=item B<-pk7out>
        +
        +takes an input message and writes out a PEM encoded PKCS#7 structure.
        +
        +=item B<-resign>
        +
        +resign a message: take an existing message and one or more new signers.
        +
        +=item B<-in filename>
        +
        +the input message to be encrypted or signed or the MIME message to
        +be decrypted or verified.
        +
        +=item B<-inform SMIME|PEM|DER>
        +
        +this specifies the input format for the PKCS#7 structure. The default
        +is B<SMIME> which reads an S/MIME format message. B<PEM> and B<DER>
        +format change this to expect PEM and DER format PKCS#7 structures
        +instead. This currently only affects the input format of the PKCS#7
        +structure, if no PKCS#7 structure is being input (for example with
        +B<-encrypt> or B<-sign>) this option has no effect.
        +
        +=item B<-out filename>
        +
        +the message text that has been decrypted or verified or the output MIME
        +format message that has been signed or verified.
        +
        +=item B<-outform SMIME|PEM|DER>
        +
        +this specifies the output format for the PKCS#7 structure. The default
        +is B<SMIME> which write an S/MIME format message. B<PEM> and B<DER>
        +format change this to write PEM and DER format PKCS#7 structures
        +instead. This currently only affects the output format of the PKCS#7
        +structure, if no PKCS#7 structure is being output (for example with
        +B<-verify> or B<-decrypt>) this option has no effect.
        +
        +=item B<-stream -indef -noindef>
        +
        +the B<-stream> and B<-indef> options are equivalent and enable streaming I/O
        +for encoding operations. This permits single pass processing of data without
        +the need to hold the entire contents in memory, potentially supporting very
        +large files. Streaming is automatically set for S/MIME signing with detached
        +data if the output format is B<SMIME> it is currently off by default for all
        +other operations.
        +
        +=item B<-noindef>
        +
        +disable streaming I/O where it would produce and indefinite length constructed
        +encoding. This option currently has no effect. In future streaming will be
        +enabled by default on all relevant operations and this option will disable it.
        +
        +=item B<-content filename>
        +
        +This specifies a file containing the detached content, this is only
        +useful with the B<-verify> command. This is only usable if the PKCS#7
        +structure is using the detached signature form where the content is
        +not included. This option will override any content if the input format
        +is S/MIME and it uses the multipart/signed MIME content type.
        +
        +=item B<-text>
        +
        +this option adds plain text (text/plain) MIME headers to the supplied
        +message if encrypting or signing. If decrypting or verifying it strips
        +off text headers: if the decrypted or verified message is not of MIME 
        +type text/plain then an error occurs.
        +
        +=item B<-CAfile file>
        +
        +a file containing trusted CA certificates, only used with B<-verify>.
        +
        +=item B<-CApath dir>
        +
        +a directory containing trusted CA certificates, only used with
        +B<-verify>. This directory must be a standard certificate directory: that
        +is a hash of each subject name (using B<x509 -hash>) should be linked
        +to each certificate.
        +
        +=item B<-md digest>
        +
        +digest algorithm to use when signing or resigning. If not present then the
        +default digest algorithm for the signing key will be used (usually SHA1).
        +
        +=item B<-[cipher]>
        +
        +the encryption algorithm to use. For example DES  (56 bits) - B<-des>,
        +triple DES (168 bits) - B<-des3>,
        +EVP_get_cipherbyname() function) can also be used preceded by a dash, for 
        +example B<-aes_128_cbc>. See L<B<enc>|enc(1)> for list of ciphers
        +supported by your version of OpenSSL.
        +
        +If not specified 40 bit RC2 is used. Only used with B<-encrypt>.
        +
        +=item B<-nointern>
        +
        +when verifying a message normally certificates (if any) included in
        +the message are searched for the signing certificate. With this option
        +only the certificates specified in the B<-certfile> option are used.
        +The supplied certificates can still be used as untrusted CAs however.
        +
        +=item B<-noverify>
        +
        +do not verify the signers certificate of a signed message.
        +
        +=item B<-nochain>
        +
        +do not do chain verification of signers certificates: that is don't
        +use the certificates in the signed message as untrusted CAs.
        +
        +=item B<-nosigs>
        +
        +don't try to verify the signatures on the message.
        +
        +=item B<-nocerts>
        +
        +when signing a message the signer's certificate is normally included
        +with this option it is excluded. This will reduce the size of the
        +signed message but the verifier must have a copy of the signers certificate
        +available locally (passed using the B<-certfile> option for example).
        +
        +=item B<-noattr>
        +
        +normally when a message is signed a set of attributes are included which
        +include the signing time and supported symmetric algorithms. With this
        +option they are not included.
        +
        +=item B<-binary>
        +
        +normally the input message is converted to "canonical" format which is
        +effectively using CR and LF as end of line: as required by the S/MIME
        +specification. When this option is present no translation occurs. This
        +is useful when handling binary data which may not be in MIME format.
        +
        +=item B<-nodetach>
        +
        +when signing a message use opaque signing: this form is more resistant
        +to translation by mail relays but it cannot be read by mail agents that
        +do not support S/MIME.  Without this option cleartext signing with
        +the MIME type multipart/signed is used.
        +
        +=item B<-certfile file>
        +
        +allows additional certificates to be specified. When signing these will
        +be included with the message. When verifying these will be searched for
        +the signers certificates. The certificates should be in PEM format.
        +
        +=item B<-signer file>
        +
        +a signing certificate when signing or resigning a message, this option can be
        +used multiple times if more than one signer is required. If a message is being
        +verified then the signers certificates will be written to this file if the
        +verification was successful.
        +
        +=item B<-recip file>
        +
        +the recipients certificate when decrypting a message. This certificate
        +must match one of the recipients of the message or an error occurs.
        +
        +=item B<-inkey file>
        +
        +the private key to use when signing or decrypting. This must match the
        +corresponding certificate. If this option is not specified then the
        +private key must be included in the certificate file specified with
        +the B<-recip> or B<-signer> file. When signing this option can be used
        +multiple times to specify successive keys.
        +
        +=item B<-passin arg>
        +
        +the private key password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-rand file(s)>
        +
        +a file or files containing random data used to seed the random number
        +generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
        +Multiple files can be specified separated by a OS-dependent character.
        +The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
        +all others.
        +
        +=item B<cert.pem...>
        +
        +one or more certificates of message recipients: used when encrypting
        +a message. 
        +
        +=item B<-to, -from, -subject>
        +
        +the relevant mail headers. These are included outside the signed
        +portion of a message so they may be included manually. If signing
        +then many S/MIME mail clients check the signers certificate's email
        +address matches that specified in the From: address.
        +
        +=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
        +
        +Set various options of certificate chain verification. See
        +L<B<verify>|verify(1)> manual page for details.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The MIME message must be sent without any blank lines between the
        +headers and the output. Some mail programs will automatically add
        +a blank line. Piping the mail directly to sendmail is one way to
        +achieve the correct format.
        +
        +The supplied message to be signed or encrypted must include the
        +necessary MIME headers or many S/MIME clients wont display it
        +properly (if at all). You can use the B<-text> option to automatically
        +add plain text headers.
        +
        +A "signed and encrypted" message is one where a signed message is
        +then encrypted. This can be produced by encrypting an already signed
        +message: see the examples section.
        +
        +This version of the program only allows one signer per message but it
        +will verify multiple signers on received messages. Some S/MIME clients
        +choke if a message contains multiple signers. It is possible to sign
        +messages "in parallel" by signing an already signed message.
        +
        +The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME
        +clients. Strictly speaking these process PKCS#7 enveloped data: PKCS#7
        +encrypted data is used for other purposes.
        +
        +The B<-resign> option uses an existing message digest when adding a new
        +signer. This means that attributes must be present in at least one existing
        +signer using the same message digest or this operation will fail.
        +
        +The B<-stream> and B<-indef> options enable experimental streaming I/O support.
        +As a result the encoding is BER using indefinite length constructed encoding
        +and no longer DER. Streaming is supported for the B<-encrypt> operation and the
        +B<-sign> operation if the content is not detached.
        +
        +Streaming is always used for the B<-sign> operation with detached data but
        +since the content is no longer part of the PKCS#7 structure the encoding
        +remains DER.
        +
        +=head1 EXIT CODES
        +
        +=over 4
        +
        +=item 0
        +
        +the operation was completely successfully.
        +
        +=item 1 
        +
        +an error occurred parsing the command options.
        +
        +=item 2
        +
        +one of the input files could not be read.
        +
        +=item 3
        +
        +an error occurred creating the PKCS#7 file or when reading the MIME
        +message.
        +
        +=item 4
        +
        +an error occurred decrypting or verifying the message.
        +
        +=item 5
        +
        +the message was verified correctly but an error occurred writing out
        +the signers certificates.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Create a cleartext signed message:
        +
        + openssl smime -sign -in message.txt -text -out mail.msg \
        +	-signer mycert.pem
        +
        +Create an opaque signed message:
        +
        + openssl smime -sign -in message.txt -text -out mail.msg -nodetach \
        +	-signer mycert.pem
        +
        +Create a signed message, include some additional certificates and
        +read the private key from another file:
        +
        + openssl smime -sign -in in.txt -text -out mail.msg \
        +	-signer mycert.pem -inkey mykey.pem -certfile mycerts.pem
        +
        +Create a signed message with two signers:
        +
        + openssl smime -sign -in message.txt -text -out mail.msg \
        +	-signer mycert.pem -signer othercert.pem
        +
        +Send a signed message under Unix directly to sendmail, including headers:
        +
        + openssl smime -sign -in in.txt -text -signer mycert.pem \
        +	-from steve@openssl.org -to someone@somewhere \
        +	-subject "Signed message" | sendmail someone@somewhere
        +
        +Verify a message and extract the signer's certificate if successful:
        +
        + openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt
        +
        +Send encrypted mail using triple DES:
        +
        + openssl smime -encrypt -in in.txt -from steve@openssl.org \
        +	-to someone@somewhere -subject "Encrypted message" \
        +	-des3 user.pem -out mail.msg
        +
        +Sign and encrypt mail:
        +
        + openssl smime -sign -in ml.txt -signer my.pem -text \
        +	| openssl smime -encrypt -out mail.msg \
        +	-from steve@openssl.org -to someone@somewhere \
        +	-subject "Signed and Encrypted message" -des3 user.pem
        +
        +Note: the encryption command does not include the B<-text> option because the
        +message being encrypted already has MIME headers.
        +
        +Decrypt mail:
        +
        + openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey key.pem
        +
        +The output from Netscape form signing is a PKCS#7 structure with the
        +detached signature format. You can use this program to verify the
        +signature by line wrapping the base64 encoded structure and surrounding
        +it with:
        +
        + -----BEGIN PKCS7-----
        + -----END PKCS7-----
        +
        +and using the command: 
        +
        + openssl smime -verify -inform PEM -in signature.pem -content content.txt
        +
        +Alternatively you can base64 decode the signature and use:
        +
        + openssl smime -verify -inform DER -in signature.der -content content.txt
        +
        +Create an encrypted message using 128 bit Camellia:
        +
        + openssl smime -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem
        +
        +Add a signer to an existing message:
        +
        + openssl smime -resign -in mail.msg -signer newsign.pem -out mail2.msg
        +
        +=head1 BUGS
        +
        +The MIME parser isn't very clever: it seems to handle most messages that I've
        +thrown at it but it may choke on others.
        +
        +The code currently will only write out the signer's certificate to a file: if
        +the signer has a separate encryption certificate this must be manually
        +extracted. There should be some heuristic that determines the correct
        +encryption certificate.
        +
        +Ideally a database should be maintained of a certificates for each email
        +address.
        +
        +The code doesn't currently take note of the permitted symmetric encryption
        +algorithms as supplied in the SMIMECapabilities signed attribute. This means the
        +user has to manually include the correct encryption algorithm. It should store
        +the list of permitted ciphers in a database and only use those.
        +
        +No revocation checking is done on the signer's certificate.
        +
        +The current code can only handle S/MIME v2 messages, the more complex S/MIME v3
        +structures may cause parsing errors.
        +
        +=head1 HISTORY
        +
        +The use of multiple B<-signer> options and the B<-resign> command were first
        +added in OpenSSL 1.0.0
        +
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/speed.pod b/vendor/openssl/openssl/doc/apps/speed.pod
        new file mode 100644
        index 000000000..1cd1998d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/speed.pod
        @@ -0,0 +1,59 @@
        +=pod
        +
        +=head1 NAME
        +
        +speed - test library performance
        +
        +=head1 SYNOPSIS
        +
        +B<openssl speed>
        +[B<-engine id>]
        +[B<md2>]
        +[B<mdc2>]
        +[B<md5>]
        +[B<hmac>]
        +[B<sha1>]
        +[B<rmd160>]
        +[B<idea-cbc>]
        +[B<rc2-cbc>]
        +[B<rc5-cbc>]
        +[B<bf-cbc>]
        +[B<des-cbc>]
        +[B<des-ede3>]
        +[B<rc4>]
        +[B<rsa512>]
        +[B<rsa1024>]
        +[B<rsa2048>]
        +[B<rsa4096>]
        +[B<dsa512>]
        +[B<dsa1024>]
        +[B<dsa2048>]
        +[B<idea>]
        +[B<rc2>]
        +[B<des>]
        +[B<rsa>]
        +[B<blowfish>]
        +
        +=head1 DESCRIPTION
        +
        +This command is used to test the performance of cryptographic algorithms.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<speed>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=item B<[zero or more test algorithms]>
        +
        +If any options are given, B<speed> tests those algorithms, otherwise all of
        +the above are tested.
        +
        +=back
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/spkac.pod b/vendor/openssl/openssl/doc/apps/spkac.pod
        new file mode 100644
        index 000000000..97fb80e40
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/spkac.pod
        @@ -0,0 +1,133 @@
        +=pod
        +
        +=head1 NAME
        +
        +spkac - SPKAC printing and generating utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<spkac>
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-key keyfile>]
        +[B<-passin arg>]
        +[B<-challenge string>]
        +[B<-pubkey>]
        +[B<-spkac spkacname>]
        +[B<-spksect section>]
        +[B<-noout>]
        +[B<-verify>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<spkac> command processes Netscape signed public key and challenge
        +(SPKAC) files. It can print out their contents, verify the signature and
        +produce its own SPKACs from a supplied private key.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read from or standard input if this
        +option is not specified. Ignored if the B<-key> option is used.
        +
        +=item B<-out filename>
        +
        +specifies the output filename to write to or standard output by
        +default.
        +
        +=item B<-key keyfile>
        +
        +create an SPKAC file using the private key in B<keyfile>. The
        +B<-in>, B<-noout>, B<-spksect> and B<-verify> options are ignored if
        +present.
        +
        +=item B<-passin password>
        +
        +the input file password source. For more information about the format of B<arg>
        +see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
        +
        +=item B<-challenge string>
        +
        +specifies the challenge string if an SPKAC is being created.
        +
        +=item B<-spkac spkacname>
        +
        +allows an alternative name form the variable containing the
        +SPKAC. The default is "SPKAC". This option affects both
        +generated and input SPKAC files.
        +
        +=item B<-spksect section>
        +
        +allows an alternative name form the section containing the
        +SPKAC. The default is the default section.
        +
        +=item B<-noout>
        +
        +don't output the text version of the SPKAC (not used if an
        +SPKAC is being created).
        +
        +=item B<-pubkey>
        +
        +output the public key of an SPKAC (not used if an SPKAC is
        +being created).
        +
        +=item B<-verify>
        +
        +verifies the digital signature on the supplied SPKAC.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<spkac>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Print out the contents of an SPKAC:
        +
        + openssl spkac -in spkac.cnf
        +
        +Verify the signature of an SPKAC:
        +
        + openssl spkac -in spkac.cnf -noout -verify
        +
        +Create an SPKAC using the challenge string "hello":
        +
        + openssl spkac -key key.pem -challenge hello -out spkac.cnf
        +
        +Example of an SPKAC, (long lines split up for clarity):
        +
        + SPKAC=MIG5MGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1cCoq2Wa3Ixs47uI7F\
        + PVwHVIPDx5yso105Y6zpozam135a8R0CpoRvkkigIyXfcCjiVi5oWk+6FfPaD03u\
        + PFoQIDAQABFgVoZWxsbzANBgkqhkiG9w0BAQQFAANBAFpQtY/FojdwkJh1bEIYuc\
        + 2EeM2KHTWPEepWYeawvHD0gQ3DngSC75YCWnnDdq+NQ3F+X4deMx9AaEglZtULwV\
        + 4=
        +
        +=head1 NOTES
        +
        +A created SPKAC with suitable DN components appended can be fed into
        +the B<ca> utility.
        +
        +SPKACs are typically generated by Netscape when a form is submitted
        +containing the B<KEYGEN> tag as part of the certificate enrollment
        +process.
        +
        +The challenge string permits a primitive form of proof of possession
        +of private key. By checking the SPKAC signature and a random challenge
        +string some guarantee is given that the user knows the private key
        +corresponding to the public key being certified. This is important in
        +some applications. Without this it is possible for a previous SPKAC
        +to be used in a "replay attack".
        +
        +=head1 SEE ALSO
        +
        +L<ca(1)|ca(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/ts.pod b/vendor/openssl/openssl/doc/apps/ts.pod
        new file mode 100644
        index 000000000..7fb6caa96
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/ts.pod
        @@ -0,0 +1,594 @@
        +=pod
        +
        +=head1 NAME
        +
        +ts - Time Stamping Authority tool (client/server)
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<ts>
        +B<-query>
        +[B<-rand> file:file...]
        +[B<-config> configfile]
        +[B<-data> file_to_hash]
        +[B<-digest> digest_bytes]
        +[B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>]
        +[B<-policy> object_id]
        +[B<-no_nonce>]
        +[B<-cert>]
        +[B<-in> request.tsq]
        +[B<-out> request.tsq]
        +[B<-text>]
        +
        +B<openssl> B<ts>
        +B<-reply>
        +[B<-config> configfile]
        +[B<-section> tsa_section]
        +[B<-queryfile> request.tsq]
        +[B<-passin> password_src]
        +[B<-signer> tsa_cert.pem]
        +[B<-inkey> private.pem]
        +[B<-chain> certs_file.pem]
        +[B<-policy> object_id]
        +[B<-in> response.tsr]
        +[B<-token_in>]
        +[B<-out> response.tsr]
        +[B<-token_out>]
        +[B<-text>]
        +[B<-engine> id]
        +
        +B<openssl> B<ts>
        +B<-verify>
        +[B<-data> file_to_hash]
        +[B<-digest> digest_bytes]
        +[B<-queryfile> request.tsq]
        +[B<-in> response.tsr]
        +[B<-token_in>]
        +[B<-CApath> trusted_cert_path]
        +[B<-CAfile> trusted_certs.pem]
        +[B<-untrusted> cert_file.pem]
        +
        +=head1 DESCRIPTION
        +
        +The B<ts> command is a basic Time Stamping Authority (TSA) client and server
        +application as specified in RFC 3161 (Time-Stamp Protocol, TSP). A
        +TSA can be part of a PKI deployment and its role is to provide long
        +term proof of the existence of a certain datum before a particular
        +time. Here is a brief description of the protocol:
        +
        +=over 4
        +
        +=item 1.
        +
        +The TSA client computes a one-way hash value for a data file and sends
        +the hash to the TSA.
        +
        +=item 2.
        +
        +The TSA attaches the current date and time to the received hash value,
        +signs them and sends the time stamp token back to the client. By
        +creating this token the TSA certifies the existence of the original
        +data file at the time of response generation.
        +
        +=item 3.
        +
        +The TSA client receives the time stamp token and verifies the
        +signature on it. It also checks if the token contains the same hash
        +value that it had sent to the TSA.
        +
        +=back
        +
        +There is one DER encoded protocol data unit defined for transporting a time
        +stamp request to the TSA and one for sending the time stamp response
        +back to the client. The B<ts> command has three main functions:
        +creating a time stamp request based on a data file,
        +creating a time stamp response based on a request, verifying if a
        +response corresponds to a particular request or a data file.
        +
        +There is no support for sending the requests/responses automatically
        +over HTTP or TCP yet as suggested in RFC 3161. The users must send the
        +requests either by ftp or e-mail.
        +
        +=head1 OPTIONS
        +
        +=head2 Time Stamp Request generation
        +
        +The B<-query> switch can be used for creating and printing a time stamp
        +request with the following options:
        +
        +=over 4
        +
        +=item B<-rand> file:file...
        +
        +The files containing random data for seeding the random number
        +generator. Multiple files can be specified, the separator is B<;> for
        +MS-Windows, B<,> for VMS and B<:> for all other platforms. (Optional)
        +
        +=item B<-config> configfile
        +
        +The configuration file to use, this option overrides the
        +B<OPENSSL_CONF> environment variable. Only the OID section
        +of the config file is used with the B<-query> command. (Optional)
        +
        +=item B<-data> file_to_hash
        +
        +The data file for which the time stamp request needs to be
        +created. stdin is the default if neither the B<-data> nor the B<-digest>
        +parameter is specified. (Optional)
        +
        +=item B<-digest> digest_bytes
        +
        +It is possible to specify the message imprint explicitly without the data
        +file. The imprint must be specified in a hexadecimal format, two characters
        +per byte, the bytes optionally separated by colons (e.g. 1A:F6:01:... or
        +1AF601...). The number of bytes must match the message digest algorithm 
        +in use. (Optional)
        +
        +=item B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>
        +
        +The message digest to apply to the data file, it supports all the message
        +digest algorithms that are supported by the openssl B<dgst> command.
        +The default is SHA-1. (Optional)
        +
        +=item B<-policy> object_id
        +
        +The policy that the client expects the TSA to use for creating the
        +time stamp token. Either the dotted OID notation or OID names defined
        +in the config file can be used. If no policy is requested the TSA will
        +use its own default policy. (Optional)
        +
        +=item B<-no_nonce>
        +
        +No nonce is specified in the request if this option is
        +given. Otherwise a 64 bit long pseudo-random none is
        +included in the request. It is recommended to use nonce to
        +protect against replay-attacks. (Optional)
        +
        +=item B<-cert>
        +
        +The TSA is expected to include its signing certificate in the
        +response. (Optional)
        +
        +=item B<-in> request.tsq
        +
        +This option specifies a previously created time stamp request in DER
        +format that will be printed into the output file. Useful when you need
        +to examine the content of a request in human-readable
        +
        +format. (Optional)
        +
        +=item B<-out> request.tsq
        +
        +Name of the output file to which the request will be written. Default
        +is stdout. (Optional)
        +
        +=item B<-text>
        +
        +If this option is specified the output is human-readable text format
        +instead of DER. (Optional)
        +
        +=back
        +
        +=head2 Time Stamp Response generation
        +
        +A time stamp response (TimeStampResp) consists of a response status
        +and the time stamp token itself (ContentInfo), if the token generation was
        +successful. The B<-reply> command is for creating a time stamp
        +response or time stamp token based on a request and printing the
        +response/token in human-readable format. If B<-token_out> is not
        +specified the output is always a time stamp response (TimeStampResp),
        +otherwise it is a time stamp token (ContentInfo).
        +
        +=over 4
        +
        +=item B<-config> configfile
        +
        +The configuration file to use, this option overrides the
        +B<OPENSSL_CONF> environment variable. See B<CONFIGURATION FILE
        +OPTIONS> for configurable variables. (Optional)
        +
        +=item B<-section> tsa_section
        +
        +The name of the config file section conatining the settings for the
        +response generation. If not specified the default TSA section is
        +used, see B<CONFIGURATION FILE OPTIONS> for details. (Optional)
        +
        +=item B<-queryfile> request.tsq
        +
        +The name of the file containing a DER encoded time stamp request. (Optional)
        +
        +=item B<-passin> password_src
        +
        +Specifies the password source for the private key of the TSA. See
        +B<PASS PHRASE ARGUMENTS> in L<openssl(1)|openssl(1)>. (Optional)
        +
        +=item B<-signer> tsa_cert.pem
        +
        +The signer certificate of the TSA in PEM format. The TSA signing
        +certificate must have exactly one extended key usage assigned to it:
        +timeStamping. The extended key usage must also be critical, otherwise
        +the certificate is going to be refused. Overrides the B<signer_cert>
        +variable of the config file. (Optional)
        +
        +=item B<-inkey> private.pem
        +
        +The signer private key of the TSA in PEM format. Overrides the
        +B<signer_key> config file option. (Optional)
        +
        +=item B<-chain> certs_file.pem
        +
        +The collection of certificates in PEM format that will all
        +be included in the response in addition to the signer certificate if
        +the B<-cert> option was used for the request. This file is supposed to
        +contain the certificate chain for the signer certificate from its
        +issuer upwards. The B<-reply> command does not build a certificate
        +chain automatically. (Optional)
        +
        +=item B<-policy> object_id
        +
        +The default policy to use for the response unless the client
        +explicitly requires a particular TSA policy. The OID can be specified
        +either in dotted notation or with its name. Overrides the
        +B<default_policy> config file option. (Optional)
        +
        +=item B<-in> response.tsr
        +
        +Specifies a previously created time stamp response or time stamp token
        +(if B<-token_in> is also specified) in DER format that will be written
        +to the output file. This option does not require a request, it is
        +useful e.g. when you need to examine the content of a response or
        +token or you want to extract the time stamp token from a response. If
        +the input is a token and the output is a time stamp response a default
        +'granted' status info is added to the token. (Optional)
        +
        +=item B<-token_in>
        +
        +This flag can be used together with the B<-in> option and indicates
        +that the input is a DER encoded time stamp token (ContentInfo) instead
        +of a time stamp response (TimeStampResp). (Optional)
        +
        +=item B<-out> response.tsr
        +
        +The response is written to this file. The format and content of the
        +file depends on other options (see B<-text>, B<-token_out>). The default is
        +stdout. (Optional)
        +
        +=item B<-token_out>
        +
        +The output is a time stamp token (ContentInfo) instead of time stamp
        +response (TimeStampResp). (Optional)
        +
        +=item B<-text>
        +
        +If this option is specified the output is human-readable text format
        +instead of DER. (Optional)
        +
        +=item B<-engine> id
        +
        +Specifying an engine (by its unique B<id> string) will cause B<ts>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms. Default is builtin. (Optional)
        +
        +=back
        +
        +=head2 Time Stamp Response verification
        +
        +The B<-verify> command is for verifying if a time stamp response or time
        +stamp token is valid and matches a particular time stamp request or
        +data file. The B<-verify> command does not use the configuration file.
        +
        +=over 4
        +
        +=item B<-data> file_to_hash
        +
        +The response or token must be verified against file_to_hash. The file
        +is hashed with the message digest algorithm specified in the token. 
        +The B<-digest> and B<-queryfile> options must not be specified with this one.
        +(Optional)
        +
        +=item B<-digest> digest_bytes
        +
        +The response or token must be verified against the message digest specified
        +with this option. The number of bytes must match the message digest algorithm
        +specified in the token. The B<-data> and B<-queryfile> options must not be
        +specified with this one. (Optional)
        +
        +=item B<-queryfile> request.tsq
        +
        +The original time stamp request in DER format. The B<-data> and B<-digest>
        +options must not be specified with this one. (Optional)
        +
        +=item B<-in> response.tsr
        +
        +The time stamp response that needs to be verified in DER format. (Mandatory)
        +
        +=item B<-token_in>
        +
        +This flag can be used together with the B<-in> option and indicates
        +that the input is a DER encoded time stamp token (ContentInfo) instead
        +of a time stamp response (TimeStampResp). (Optional)
        +
        +=item B<-CApath> trusted_cert_path
        +
        +The name of the directory containing the trused CA certificates of the
        +client. See the similar option of L<verify(1)|verify(1)> for additional
        +details. Either this option or B<-CAfile> must be specified. (Optional)
        +
        +
        +=item B<-CAfile> trusted_certs.pem
        +
        +The name of the file containing a set of trusted self-signed CA 
        +certificates in PEM format. See the similar option of 
        +L<verify(1)|verify(1)> for additional details. Either this option 
        +or B<-CApath> must be specified.
        +(Optional)
        +
        +=item B<-untrusted> cert_file.pem
        +
        +Set of additional untrusted certificates in PEM format which may be
        +needed when building the certificate chain for the TSA's signing
        +certificate. This file must contain the TSA signing certificate and
        +all intermediate CA certificates unless the response includes them.
        +(Optional)
        +
        +=back
        +
        +=head1 CONFIGURATION FILE OPTIONS
        +
        +The B<-query> and B<-reply> commands make use of a configuration file
        +defined by the B<OPENSSL_CONF> environment variable. See L<config(5)|config(5)>
        +for a general description of the syntax of the config file. The
        +B<-query> command uses only the symbolic OID names section
        +and it can work without it. However, the B<-reply> command needs the
        +config file for its operation.
        +
        +When there is a command line switch equivalent of a variable the
        +switch always overrides the settings in the config file.
        +
        +=over 4
        +
        +=item B<tsa> section, B<default_tsa>	
        +
        +This is the main section and it specifies the name of another section
        +that contains all the options for the B<-reply> command. This default
        +section can be overriden with the B<-section> command line switch. (Optional)
        +
        +=item B<oid_file>
        +
        +See L<ca(1)|ca(1)> for description. (Optional)
        +
        +=item B<oid_section>
        +
        +See L<ca(1)|ca(1)> for description. (Optional)
        +
        +=item B<RANDFILE>
        +
        +See L<ca(1)|ca(1)> for description. (Optional)
        +
        +=item B<serial>
        +
        +The name of the file containing the hexadecimal serial number of the
        +last time stamp response created. This number is incremented by 1 for
        +each response. If the file does not exist at the time of response
        +generation a new file is created with serial number 1. (Mandatory)
        +
        +=item B<crypto_device>
        +
        +Specifies the OpenSSL engine that will be set as the default for 
        +all available algorithms. The default value is builtin, you can specify 
        +any other engines supported by OpenSSL (e.g. use chil for the NCipher HSM).
        +(Optional)
        +
        +=item B<signer_cert>
        +
        +TSA signing certificate in PEM format. The same as the B<-signer>
        +command line option. (Optional)
        +
        +=item B<certs>
        +
        +A file containing a set of PEM encoded certificates that need to be
        +included in the response. The same as the B<-chain> command line
        +option. (Optional)
        +
        +=item B<signer_key>
        +
        +The private key of the TSA in PEM format. The same as the B<-inkey>
        +command line option. (Optional)
        +
        +=item B<default_policy>
        +
        +The default policy to use when the request does not mandate any
        +policy. The same as the B<-policy> command line option. (Optional)
        +
        +=item B<other_policies>
        +
        +Comma separated list of policies that are also acceptable by the TSA
        +and used only if the request explicitly specifies one of them. (Optional)
        +
        +=item B<digests>
        +
        +The list of message digest algorithms that the TSA accepts. At least
        +one algorithm must be specified. (Mandatory)
        +
        +=item B<accuracy>
        +
        +The accuracy of the time source of the TSA in seconds, milliseconds
        +and microseconds. E.g. secs:1, millisecs:500, microsecs:100. If any of
        +the components is missing zero is assumed for that field. (Optional)
        +
        +=item B<clock_precision_digits>
        +
        +Specifies the maximum number of digits, which represent the fraction of 
        +seconds, that  need to be included in the time field. The trailing zeroes
        +must be removed from the time, so there might actually be fewer digits,
        +or no fraction of seconds at all. Supported only on UNIX platforms.
        +The maximum value is 6, default is 0.
        +(Optional)
        +
        +=item B<ordering>
        +
        +If this option is yes the responses generated by this TSA can always
        +be ordered, even if the time difference between two responses is less
        +than the sum of their accuracies. Default is no. (Optional)
        +
        +=item B<tsa_name>
        +
        +Set this option to yes if the subject name of the TSA must be included in
        +the TSA name field of the response. Default is no. (Optional)
        +
        +=item B<ess_cert_id_chain>
        +
        +The SignedData objects created by the TSA always contain the
        +certificate identifier of the signing certificate in a signed
        +attribute (see RFC 2634, Enhanced Security Services). If this option
        +is set to yes and either the B<certs> variable or the B<-chain> option
        +is specified then the certificate identifiers of the chain will also
        +be included in the SigningCertificate signed attribute. If this
        +variable is set to no, only the signing certificate identifier is
        +included. Default is no. (Optional)
        +
        +=back
        +
        +=head1 ENVIRONMENT VARIABLES
        +
        +B<OPENSSL_CONF> contains the path of the configuration file and can be
        +overriden by the B<-config> command line option.
        +
        +=head1 EXAMPLES
        +
        +All the examples below presume that B<OPENSSL_CONF> is set to a proper
        +configuration file, e.g. the example configuration file 
        +openssl/apps/openssl.cnf will do.
        +
        +=head2 Time Stamp Request
        +
        +To create a time stamp request for design1.txt with SHA-1 
        +without nonce and policy and no certificate is required in the response:
        +
        +  openssl ts -query -data design1.txt -no_nonce \
        +	-out design1.tsq
        +
        +To create a similar time stamp request with specifying the message imprint
        +explicitly:
        +
        +  openssl ts -query -digest b7e5d3f93198b38379852f2c04e78d73abdd0f4b \
        +	 -no_nonce -out design1.tsq
        +
        +To print the content of the previous request in human readable format:
        +
        +  openssl ts -query -in design1.tsq -text
        +
        +To create a time stamp request which includes the MD-5 digest 
        +of design2.txt, requests the signer certificate and nonce,
        +specifies a policy id (assuming the tsa_policy1 name is defined in the
        +OID section of the config file):
        +
        +  openssl ts -query -data design2.txt -md5 \
        +	-policy tsa_policy1 -cert -out design2.tsq
        +
        +=head2 Time Stamp Response
        +
        +Before generating a response a signing certificate must be created for
        +the TSA that contains the B<timeStamping> critical extended key usage extension
        +without any other key usage extensions. You can add the
        +'extendedKeyUsage = critical,timeStamping' line to the user certificate section
        +of the config file to generate a proper certificate. See L<req(1)|req(1)>,
        +L<ca(1)|ca(1)>, L<x509(1)|x509(1)> for instructions. The examples
        +below assume that cacert.pem contains the certificate of the CA,
        +tsacert.pem is the signing certificate issued by cacert.pem and
        +tsakey.pem is the private key of the TSA.
        +
        +To create a time stamp response for a request:
        +
        +  openssl ts -reply -queryfile design1.tsq -inkey tsakey.pem \
        +	-signer tsacert.pem -out design1.tsr
        +
        +If you want to use the settings in the config file you could just write:
        +
        +  openssl ts -reply -queryfile design1.tsq -out design1.tsr
        +
        +To print a time stamp reply to stdout in human readable format:
        +
        +  openssl ts -reply -in design1.tsr -text
        +
        +To create a time stamp token instead of time stamp response:
        +
        +  openssl ts -reply -queryfile design1.tsq -out design1_token.der -token_out
        +
        +To print a time stamp token to stdout in human readable format:
        +
        +  openssl ts -reply -in design1_token.der -token_in -text -token_out
        +
        +To extract the time stamp token from a response:
        +
        +  openssl ts -reply -in design1.tsr -out design1_token.der -token_out
        +
        +To add 'granted' status info to a time stamp token thereby creating a
        +valid response:
        +
        +  openssl ts -reply -in design1_token.der -token_in -out design1.tsr
        +
        +=head2 Time Stamp Verification
        +
        +To verify a time stamp reply against a request:
        +
        +  openssl ts -verify -queryfile design1.tsq -in design1.tsr \
        +	-CAfile cacert.pem -untrusted tsacert.pem
        +
        +To verify a time stamp reply that includes the certificate chain:
        +
        +  openssl ts -verify -queryfile design2.tsq -in design2.tsr \
        +	-CAfile cacert.pem
        +
        +To verify a time stamp token against the original data file:
        +  openssl ts -verify -data design2.txt -in design2.tsr \
        +	-CAfile cacert.pem
        +
        +To verify a time stamp token against a message imprint:
        +  openssl ts -verify -digest b7e5d3f93198b38379852f2c04e78d73abdd0f4b \
        +	 -in design2.tsr -CAfile cacert.pem
        +
        +You could also look at the 'test' directory for more examples.
        +
        +=head1 BUGS
        +
        +If you find any bugs or you have suggestions please write to
        +Zoltan Glozik <zglozik@opentsa.org>. Known issues:
        +
        +=over 4
        +
        +=item * No support for time stamps over SMTP, though it is quite easy
        +to implement an automatic e-mail based TSA with L<procmail(1)|procmail(1)> 
        +and L<perl(1)|perl(1)>. HTTP server support is provided in the form of 
        +a separate apache module. HTTP client support is provided by
        +L<tsget(1)|tsget(1)>. Pure TCP/IP protocol is not supported.
        +
        +=item * The file containing the last serial number of the TSA is not
        +locked when being read or written. This is a problem if more than one
        +instance of L<openssl(1)|openssl(1)> is trying to create a time stamp
        +response at the same time. This is not an issue when using the apache
        +server module, it does proper locking.
        +
        +=item * Look for the FIXME word in the source files.
        +
        +=item * The source code should really be reviewed by somebody else, too.
        +
        +=item * More testing is needed, I have done only some basic tests (see
        +test/testtsa).
        +
        +=back
        +
        +=cut
        +
        +=head1 AUTHOR
        +
        +Zoltan Glozik <zglozik@opentsa.org>, OpenTSA project (http://www.opentsa.org)
        +
        +=head1 SEE ALSO
        +
        +L<tsget(1)|tsget(1)>, L<openssl(1)|openssl(1)>, L<req(1)|req(1)>, 
        +L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>, 
        +L<config(5)|config(5)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/tsget.pod b/vendor/openssl/openssl/doc/apps/tsget.pod
        new file mode 100644
        index 000000000..b05957bee
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/tsget.pod
        @@ -0,0 +1,194 @@
        +=pod
        +
        +=head1 NAME
        +
        +tsget - Time Stamping HTTP/HTTPS client
        +
        +=head1 SYNOPSIS
        +
        +B<tsget>
        +B<-h> server_url
        +[B<-e> extension]
        +[B<-o> output]
        +[B<-v>]
        +[B<-d>]
        +[B<-k> private_key.pem]
        +[B<-p> key_password]
        +[B<-c> client_cert.pem]
        +[B<-C> CA_certs.pem]
        +[B<-P> CA_path]
        +[B<-r> file:file...]
        +[B<-g> EGD_socket]
        +[request]...
        +
        +=head1 DESCRIPTION
        +
        +The B<tsget> command can be used for sending a time stamp request, as
        +specified in B<RFC 3161>, to a time stamp server over HTTP or HTTPS and storing
        +the time stamp response in a file. This tool cannot be used for creating the
        +requests and verifying responses, you can use the OpenSSL B<ts(1)> command to
        +do that. B<tsget> can send several requests to the server without closing
        +the TCP connection if more than one requests are specified on the command
        +line.
        +
        +The tool sends the following HTTP request for each time stamp request:
        +
        +	POST url HTTP/1.1
        +	User-Agent: OpenTSA tsget.pl/<version>
        +	Host: <host>:<port>
        +	Pragma: no-cache
        +	Content-Type: application/timestamp-query
        +	Accept: application/timestamp-reply
        +	Content-Length: length of body
        +
        +	...binary request specified by the user...
        +
        +B<tsget> expects a response of type application/timestamp-reply, which is
        +written to a file without any interpretation.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-h> server_url
        +
        +The URL of the HTTP/HTTPS server listening for time stamp requests.
        +
        +=item B<-e> extension
        +
        +If the B<-o> option is not given this argument specifies the extension of the
        +output files. The base name of the output file will be the same as those of
        +the input files. Default extension is '.tsr'. (Optional)
        +
        +=item B<-o> output
        +
        +This option can be specified only when just one request is sent to the
        +server. The time stamp response will be written to the given output file. '-'
        +means standard output. In case of multiple time stamp requests or the absence
        +of this argument the names of the output files will be derived from the names
        +of the input files and the default or specified extension argument. (Optional)
        +
        +=item B<-v>
        +
        +The name of the currently processed request is printed on standard
        +error. (Optional)
        +
        +=item B<-d>
        +
        +Switches on verbose mode for the underlying B<curl> library. You can see
        +detailed debug messages for the connection. (Optional)
        +
        +=item B<-k> private_key.pem
        +
        +(HTTPS) In case of certificate-based client authentication over HTTPS
        +<private_key.pem> must contain the private key of the user. The private key
        +file can optionally be protected by a passphrase. The B<-c> option must also
        +be specified. (Optional)
        +
        +=item B<-p> key_password
        +
        +(HTTPS) Specifies the passphrase for the private key specified by the B<-k>
        +argument. If this option is omitted and the key is passphrase protected B<tsget>
        +will ask for it. (Optional)
        +
        +=item B<-c> client_cert.pem
        +
        +(HTTPS) In case of certificate-based client authentication over HTTPS
        +<client_cert.pem> must contain the X.509 certificate of the user.  The B<-k>
        +option must also be specified. If this option is not specified no
        +certificate-based client authentication will take place. (Optional)
        +
        +=item B<-C> CA_certs.pem
        +
        +(HTTPS) The trusted CA certificate store. The certificate chain of the peer's
        +certificate must include one of the CA certificates specified in this file.
        +Either option B<-C> or option B<-P> must be given in case of HTTPS. (Optional)
        +
        +=item B<-P> CA_path
        +
        +(HTTPS) The path containing the trusted CA certificates to verify the peer's
        +certificate. The directory must be prepared with the B<c_rehash>
        +OpenSSL utility. Either option B<-C> or option B<-P> must be given in case of
        +HTTPS. (Optional)
        +
        +=item B<-rand> file:file...
        +
        +The files containing random data for seeding the random number
        +generator. Multiple files can be specified, the separator is B<;> for
        +MS-Windows, B<,> for VMS and B<:> for all other platforms. (Optional)
        +
        +=item B<-g> EGD_socket
        +
        +The name of an EGD socket to get random data from. (Optional)
        +
        +=item [request]...
        +
        +List of files containing B<RFC 3161> DER-encoded time stamp requests. If no
        +requests are specifed only one request will be sent to the server and it will be
        +read from the standard input. (Optional)
        +
        +=back
        +
        +=head1 ENVIRONMENT VARIABLES
        +
        +The B<TSGET> environment variable can optionally contain default
        +arguments. The content of this variable is added to the list of command line
        +arguments.
        +
        +=head1 EXAMPLES
        +
        +The examples below presume that B<file1.tsq> and B<file2.tsq> contain valid
        +time stamp requests, tsa.opentsa.org listens at port 8080 for HTTP requests
        +and at port 8443 for HTTPS requests, the TSA service is available at the /tsa
        +absolute path.
        +
        +Get a time stamp response for file1.tsq over HTTP, output is written to 
        +file1.tsr:
        +
        +  tsget -h http://tsa.opentsa.org:8080/tsa file1.tsq
        +
        +Get a time stamp response for file1.tsq and file2.tsq over HTTP showing
        +progress, output is written to file1.reply and file2.reply respectively:
        +
        +  tsget -h http://tsa.opentsa.org:8080/tsa -v -e .reply \
        +	file1.tsq file2.tsq
        +
        +Create a time stamp request, write it to file3.tsq, send it to the server and
        +write the response to file3.tsr:
        +
        +  openssl ts -query -data file3.txt -cert | tee file3.tsq \
        +	| tsget -h http://tsa.opentsa.org:8080/tsa \
        +	-o file3.tsr
        +
        +Get a time stamp response for file1.tsq over HTTPS without client
        +authentication:
        +
        +  tsget -h https://tsa.opentsa.org:8443/tsa \
        +	-C cacerts.pem file1.tsq
        +
        +Get a time stamp response for file1.tsq over HTTPS with certificate-based
        +client authentication (it will ask for the passphrase if client_key.pem is
        +protected):
        +
        +  tsget -h https://tsa.opentsa.org:8443/tsa -C cacerts.pem \
        +	-k client_key.pem -c client_cert.pem file1.tsq
        +
        +You can shorten the previous command line if you make use of the B<TSGET>
        +environment variable. The following commands do the same as the previous
        +example:
        +
        +  TSGET='-h https://tsa.opentsa.org:8443/tsa -C cacerts.pem \
        +	-k client_key.pem -c client_cert.pem'
        +  export TSGET
        +  tsget file1.tsq
        +
        +=head1 AUTHOR
        +
        +Zoltan Glozik <zglozik@opentsa.org>, OpenTSA project (http://www.opentsa.org)
        +
        +=head1 SEE ALSO
        +
        +L<openssl(1)|openssl(1)>, L<ts(1)|ts(1)>, L<curl(1)|curl(1)>, 
        +B<RFC 3161>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/verify.pod b/vendor/openssl/openssl/doc/apps/verify.pod
        new file mode 100644
        index 000000000..da683004b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/verify.pod
        @@ -0,0 +1,406 @@
        +=pod
        +
        +=head1 NAME
        +
        +verify - Utility to verify certificates.
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<verify>
        +[B<-CApath directory>]
        +[B<-CAfile file>]
        +[B<-purpose purpose>]
        +[B<-policy arg>]
        +[B<-ignore_critical>]
        +[B<-crl_check>]
        +[B<-crl_check_all>]
        +[B<-policy_check>]
        +[B<-explicit_policy>]
        +[B<-inhibit_any>]
        +[B<-inhibit_map>]
        +[B<-x509_strict>]
        +[B<-extended_crl>]
        +[B<-use_deltas>]
        +[B<-policy_print>]
        +[B<-untrusted file>]
        +[B<-help>]
        +[B<-issuer_checks>]
        +[B<-verbose>]
        +[B<->]
        +[certificates]
        +
        +
        +=head1 DESCRIPTION
        +
        +The B<verify> command verifies certificate chains.
        +
        +=head1 COMMAND OPTIONS
        +
        +=over 4
        +
        +=item B<-CApath directory>
        +
        +A directory of trusted certificates. The certificates should have names
        +of the form: hash.0 or have symbolic links to them of this
        +form ("hash" is the hashed certificate subject name: see the B<-hash> option
        +of the B<x509> utility). Under Unix the B<c_rehash> script will automatically
        +create symbolic links to a directory of certificates.
        +
        +=item B<-CAfile file>
        +
        +A file of trusted certificates. The file should contain multiple certificates
        +in PEM format concatenated together.
        +
        +=item B<-untrusted file>
        +
        +A file of untrusted certificates. The file should contain multiple certificates
        +in PEM format concatenated together.
        +
        +=item B<-purpose purpose>
        +
        +The intended use for the certificate. If this option is not specified,
        +B<verify> will not consider certificate purpose during chain verification.
        +Currently accepted uses are B<sslclient>, B<sslserver>, B<nssslserver>,
        +B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION> section for more
        +information.
        +
        +=item B<-help>
        +
        +Print out a usage message.
        +
        +=item B<-verbose>
        +
        +Print extra information about the operations being performed.
        +
        +=item B<-issuer_checks>
        +
        +Print out diagnostics relating to searches for the issuer certificate of the
        +current certificate. This shows why each candidate issuer certificate was
        +rejected. The presence of rejection messages does not itself imply that
        +anything is wrong; during the normal verification process, several
        +rejections may take place.
        +
        +=item B<-policy arg>
        +
        +Enable policy processing and add B<arg> to the user-initial-policy-set (see
        +RFC5280). The policy B<arg> can be an object name an OID in numeric form.
        +This argument can appear more than once.
        +
        +=item B<-policy_check>
        +
        +Enables certificate policy processing.
        +
        +=item B<-explicit_policy>
        +
        +Set policy variable require-explicit-policy (see RFC5280).
        +
        +=item B<-inhibit_any>
        +
        +Set policy variable inhibit-any-policy (see RFC5280).
        +
        +=item B<-inhibit_map>
        +
        +Set policy variable inhibit-policy-mapping (see RFC5280).
        +
        +=item B<-policy_print>
        +
        +Print out diagnostics related to policy processing.
        +
        +=item B<-crl_check>
        +
        +Checks end entity certificate validity by attempting to look up a valid CRL.
        +If a valid CRL cannot be found an error occurs. 
        +
        +=item B<-crl_check_all>
        +
        +Checks the validity of B<all> certificates in the chain by attempting
        +to look up valid CRLs.
        +
        +=item B<-ignore_critical>
        +
        +Normally if an unhandled critical extension is present which is not
        +supported by OpenSSL the certificate is rejected (as required by RFC5280).
        +If this option is set critical extensions are ignored.
        +
        +=item B<-x509_strict>
        +
        +For strict X.509 compliance, disable non-compliant workarounds for broken
        +certificates.
        +
        +=item B<-extended_crl>
        +
        +Enable extended CRL features such as indirect CRLs and alternate CRL
        +signing keys.
        +
        +=item B<-use_deltas>
        +
        +Enable support for delta CRLs.
        +
        +=item B<-check_ss_sig>
        +
        +Verify the signature on the self-signed root CA. This is disabled by default
        +because it doesn't add any security.
        +
        +=item B<->
        +
        +Indicates the last option. All arguments following this are assumed to be
        +certificate files. This is useful if the first certificate filename begins
        +with a B<->.
        +
        +=item B<certificates>
        +
        +One or more certificates to verify. If no certificates are given, B<verify>
        +will attempt to read a certificate from standard input. Certificates must be
        +in PEM format.
        +
        +=back
        +
        +=head1 VERIFY OPERATION
        +
        +The B<verify> program uses the same functions as the internal SSL and S/MIME
        +verification, therefore this description applies to these verify operations
        +too.
        +
        +There is one crucial difference between the verify operations performed
        +by the B<verify> program: wherever possible an attempt is made to continue
        +after an error whereas normally the verify operation would halt on the
        +first error. This allows all the problems with a certificate chain to be
        +determined.
        +
        +The verify operation consists of a number of separate steps.
        +
        +Firstly a certificate chain is built up starting from the supplied certificate
        +and ending in the root CA. It is an error if the whole chain cannot be built
        +up. The chain is built up by looking up the issuers certificate of the current
        +certificate. If a certificate is found which is its own issuer it is assumed 
        +to be the root CA.
        +
        +The process of 'looking up the issuers certificate' itself involves a number
        +of steps. In versions of OpenSSL before 0.9.5a the first certificate whose
        +subject name matched the issuer of the current certificate was assumed to be
        +the issuers certificate. In OpenSSL 0.9.6 and later all certificates
        +whose subject name matches the issuer name of the current certificate are 
        +subject to further tests. The relevant authority key identifier components
        +of the current certificate (if present) must match the subject key identifier
        +(if present) and issuer and serial number of the candidate issuer, in addition
        +the keyUsage extension of the candidate issuer (if present) must permit
        +certificate signing.
        +
        +The lookup first looks in the list of untrusted certificates and if no match
        +is found the remaining lookups are from the trusted certificates. The root CA
        +is always looked up in the trusted certificate list: if the certificate to
        +verify is a root certificate then an exact match must be found in the trusted
        +list.
        +
        +The second operation is to check every untrusted certificate's extensions for
        +consistency with the supplied purpose. If the B<-purpose> option is not included
        +then no checks are done. The supplied or "leaf" certificate must have extensions
        +compatible with the supplied purpose and all other certificates must also be valid
        +CA certificates. The precise extensions required are described in more detail in
        +the B<CERTIFICATE EXTENSIONS> section of the B<x509> utility.
        +
        +The third operation is to check the trust settings on the root CA. The root
        +CA should be trusted for the supplied purpose. For compatibility with previous
        +versions of SSLeay and OpenSSL a certificate with no trust settings is considered
        +to be valid for all purposes. 
        +
        +The final operation is to check the validity of the certificate chain. The validity
        +period is checked against the current system time and the notBefore and notAfter
        +dates in the certificate. The certificate signatures are also checked at this
        +point.
        +
        +If all operations complete successfully then certificate is considered valid. If
        +any operation fails then the certificate is not valid.
        +
        +=head1 DIAGNOSTICS
        +
        +When a verify operation fails the output messages can be somewhat cryptic. The
        +general form of the error message is:
        +
        + server.pem: /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
        + error 24 at 1 depth lookup:invalid CA certificate
        +
        +The first line contains the name of the certificate being verified followed by
        +the subject name of the certificate. The second line contains the error number
        +and the depth. The depth is number of the certificate being verified when a
        +problem was detected starting with zero for the certificate being verified itself
        +then 1 for the CA that signed the certificate and so on. Finally a text version
        +of the error number is presented.
        +
        +An exhaustive list of the error codes and messages is shown below, this also
        +includes the name of the error code as defined in the header file x509_vfy.h
        +Some of the error codes are defined but never returned: these are described
        +as "unused".
        +
        +=over 4
        +
        +=item B<0 X509_V_OK: ok>
        +
        +the operation was successful.
        +
        +=item B<2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
        +
        +the issuer certificate of a looked up certificate could not be found. This
        +normally means the list of trusted certificates is not complete.
        +
        +=item B<3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
        +
        +the CRL of a certificate could not be found.
        +
        +=item B<4 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
        +
        +the certificate signature could not be decrypted. This means that the actual signature value
        +could not be determined rather than it not matching the expected value, this is only
        +meaningful for RSA keys.
        +
        +=item B<5 X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature>
        +
        +the CRL signature could not be decrypted: this means that the actual signature value
        +could not be determined rather than it not matching the expected value. Unused.
        +
        +=item B<6 X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key>
        +
        +the public key in the certificate SubjectPublicKeyInfo could not be read.
        +
        +=item B<7 X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure>
        +
        +the signature of the certificate is invalid.
        +
        +=item B<8 X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
        +
        +the signature of the certificate is invalid.
        +
        +=item B<9 X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
        +
        +the certificate is not yet valid: the notBefore date is after the current time.
        +
        +=item B<10 X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired>
        +
        +the certificate has expired: that is the notAfter date is before the current time.
        +
        +=item B<11 X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
        +
        +the CRL is not yet valid.
        +
        +=item B<12 X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
        +
        +the CRL has expired.
        +
        +=item B<13 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
        +
        +the certificate notBefore field contains an invalid time.
        +
        +=item B<14 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field>
        +
        +the certificate notAfter field contains an invalid time.
        +
        +=item B<15 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
        +
        +the CRL lastUpdate field contains an invalid time.
        +
        +=item B<16 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
        +
        +the CRL nextUpdate field contains an invalid time.
        +
        +=item B<17 X509_V_ERR_OUT_OF_MEM: out of memory>
        +
        +an error occurred trying to allocate memory. This should never happen.
        +
        +=item B<18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate>
        +
        +the passed certificate is self signed and the same certificate cannot be found in the list of
        +trusted certificates.
        +
        +=item B<19 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain>
        +
        +the certificate chain could be built up using the untrusted certificates but the root could not
        +be found locally.
        +
        +=item B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
        +
        +the issuer certificate could not be found: this occurs if the issuer
        +certificate of an untrusted certificate cannot be found.
        +
        +=item B<21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
        +
        +no signatures could be verified because the chain contains only one certificate and it is not
        +self signed.
        +
        +=item B<22 X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long>
        +
        +the certificate chain length is greater than the supplied maximum depth. Unused.
        +
        +=item B<23 X509_V_ERR_CERT_REVOKED: certificate revoked>
        +
        +the certificate has been revoked.
        +
        +=item B<24 X509_V_ERR_INVALID_CA: invalid CA certificate>
        +
        +a CA certificate is invalid. Either it is not a CA or its extensions are not consistent
        +with the supplied purpose.
        +
        +=item B<25 X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded>
        +
        +the basicConstraints pathlength parameter has been exceeded.
        +
        +=item B<26 X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose>
        +
        +the supplied certificate cannot be used for the specified purpose.
        +
        +=item B<27 X509_V_ERR_CERT_UNTRUSTED: certificate not trusted>
        +
        +the root CA is not marked as trusted for the specified purpose.
        +
        +=item B<28 X509_V_ERR_CERT_REJECTED: certificate rejected>
        +
        +the root CA is marked to reject the specified purpose.
        +
        +=item B<29 X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch>
        +
        +the current candidate issuer certificate was rejected because its subject name
        +did not match the issuer name of the current certificate. Only displayed when
        +the B<-issuer_checks> option is set.
        +
        +=item B<30 X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch>
        +
        +the current candidate issuer certificate was rejected because its subject key
        +identifier was present and did not match the authority key identifier current
        +certificate. Only displayed when the B<-issuer_checks> option is set.
        +
        +=item B<31 X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch>
        +
        +the current candidate issuer certificate was rejected because its issuer name
        +and serial number was present and did not match the authority key identifier
        +of the current certificate. Only displayed when the B<-issuer_checks> option is set.
        +
        +=item B<32 X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing>
        +
        +the current candidate issuer certificate was rejected because its keyUsage extension
        +does not permit certificate signing.
        +
        +=item B<50 X509_V_ERR_APPLICATION_VERIFICATION: application verification failure>
        +
        +an application specific error. Unused.
        +
        +=back
        +
        +=head1 BUGS
        +
        +Although the issuer checks are a considerably improvement over the old technique they still
        +suffer from limitations in the underlying X509_LOOKUP API. One consequence of this is that
        +trusted certificates with matching subject name must either appear in a file (as specified by the
        +B<-CAfile> option) or a directory (as specified by B<-CApath>. If they occur in both then only
        +the certificates in the file will be recognised.
        +
        +Previous versions of OpenSSL assume certificates with matching subject name are identical and
        +mishandled them.
        +
        +Previous versions of this documentation swapped the meaning of the
        +B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT> and
        +B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.
        +
        +=head1 SEE ALSO
        +
        +L<x509(1)|x509(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/version.pod b/vendor/openssl/openssl/doc/apps/version.pod
        new file mode 100644
        index 000000000..e00324c44
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/version.pod
        @@ -0,0 +1,64 @@
        +=pod
        +
        +=head1 NAME
        +
        +version - print OpenSSL version information
        +
        +=head1 SYNOPSIS
        +
        +B<openssl version>
        +[B<-a>]
        +[B<-v>]
        +[B<-b>]
        +[B<-o>]
        +[B<-f>]
        +[B<-p>]
        +
        +=head1 DESCRIPTION
        +
        +This command is used to print out version information about OpenSSL.
        +
        +=head1 OPTIONS
        +
        +=over 4
        +
        +=item B<-a>
        +
        +all information, this is the same as setting all the other flags.
        +
        +=item B<-v>
        +
        +the current OpenSSL version.
        +
        +=item B<-b>
        +
        +the date the current version of OpenSSL was built.
        +
        +=item B<-o>
        +
        +option information: various options set when the library was built.
        +
        +=item B<-c>
        +
        +compilation flags.
        +
        +=item B<-p>
        +
        +platform setting.
        +
        +=item B<-d>
        +
        +OPENSSLDIR setting.
        +
        +=back
        +
        +=head1 NOTES
        +
        +The output of B<openssl version -a> would typically be used when sending
        +in a bug report.
        +
        +=head1 HISTORY
        +
        +The B<-d> option was added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/x509.pod b/vendor/openssl/openssl/doc/apps/x509.pod
        new file mode 100644
        index 000000000..d2d9eb812
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/x509.pod
        @@ -0,0 +1,861 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +x509 - Certificate display and signing utility
        +
        +=head1 SYNOPSIS
        +
        +B<openssl> B<x509>
        +[B<-inform DER|PEM|NET>]
        +[B<-outform DER|PEM|NET>]
        +[B<-keyform DER|PEM>]
        +[B<-CAform DER|PEM>]
        +[B<-CAkeyform DER|PEM>]
        +[B<-in filename>]
        +[B<-out filename>]
        +[B<-serial>]
        +[B<-hash>]
        +[B<-subject_hash>]
        +[B<-issuer_hash>]
        +[B<-subject>]
        +[B<-issuer>]
        +[B<-nameopt option>]
        +[B<-email>]
        +[B<-ocsp_uri>]
        +[B<-startdate>]
        +[B<-enddate>]
        +[B<-purpose>]
        +[B<-dates>]
        +[B<-modulus>]
        +[B<-pubkey>]
        +[B<-fingerprint>]
        +[B<-alias>]
        +[B<-noout>]
        +[B<-trustout>]
        +[B<-clrtrust>]
        +[B<-clrreject>]
        +[B<-addtrust arg>]
        +[B<-addreject arg>]
        +[B<-setalias arg>]
        +[B<-days arg>]
        +[B<-set_serial n>]
        +[B<-signkey filename>]
        +[B<-x509toreq>]
        +[B<-req>]
        +[B<-CA filename>]
        +[B<-CAkey filename>]
        +[B<-CAcreateserial>]
        +[B<-CAserial filename>]
        +[B<-text>]
        +[B<-C>]
        +[B<-md2|-md5|-sha1|-mdc2>]
        +[B<-clrext>]
        +[B<-extfile filename>]
        +[B<-extensions section>]
        +[B<-engine id>]
        +
        +=head1 DESCRIPTION
        +
        +The B<x509> command is a multi purpose certificate utility. It can be
        +used to display certificate information, convert certificates to
        +various forms, sign certificate requests like a "mini CA" or edit
        +certificate trust settings.
        +
        +Since there are a large number of options they will split up into
        +various sections.
        +
        +=head1 OPTIONS
        +
        +=head2 INPUT, OUTPUT AND GENERAL PURPOSE OPTIONS
        +
        +=over 4
        +
        +=item B<-inform DER|PEM|NET>
        +
        +This specifies the input format normally the command will expect an X509
        +certificate but this can change if other options such as B<-req> are
        +present. The DER format is the DER encoding of the certificate and PEM
        +is the base64 encoding of the DER encoding with header and footer lines
        +added. The NET option is an obscure Netscape server format that is now
        +obsolete.
        +
        +=item B<-outform DER|PEM|NET>
        +
        +This specifies the output format, the options have the same meaning as the 
        +B<-inform> option.
        +
        +=item B<-in filename>
        +
        +This specifies the input filename to read a certificate from or standard input
        +if this option is not specified.
        +
        +=item B<-out filename>
        +
        +This specifies the output filename to write to or standard output by
        +default.
        +
        +=item B<-md2|-md5|-sha1|-mdc2>
        +
        +the digest to use. This affects any signing or display option that uses a message
        +digest, such as the B<-fingerprint>, B<-signkey> and B<-CA> options. If not
        +specified then SHA1 is used. If the key being used to sign with is a DSA key
        +then this option has no effect: SHA1 is always used with DSA keys.
        +
        +=item B<-engine id>
        +
        +specifying an engine (by its unique B<id> string) will cause B<x509>
        +to attempt to obtain a functional reference to the specified engine,
        +thus initialising it if needed. The engine will then be set as the default
        +for all available algorithms.
        +
        +=back
        +
        +=head2 DISPLAY OPTIONS
        +
        +Note: the B<-alias> and B<-purpose> options are also display options
        +but are described in the B<TRUST SETTINGS> section.
        +
        +=over 4
        +
        +=item B<-text>
        +
        +prints out the certificate in text form. Full details are output including the
        +public key, signature algorithms, issuer and subject names, serial number
        +any extensions present and any trust settings.
        +
        +=item B<-certopt option>
        +
        +customise the output format used with B<-text>. The B<option> argument can be
        +a single option or multiple options separated by commas. The B<-certopt> switch
        +may be also be used more than once to set multiple options. See the B<TEXT OPTIONS>
        +section for more information.
        +
        +=item B<-noout>
        +
        +this option prevents output of the encoded version of the request.
        +
        +=item B<-pubkey>
        +
        +outputs the the certificate's SubjectPublicKeyInfo block in PEM format.
        +
        +=item B<-modulus>
        +
        +this option prints out the value of the modulus of the public key
        +contained in the certificate.
        +
        +=item B<-serial>
        +
        +outputs the certificate serial number.
        +
        +=item B<-subject_hash>
        +
        +outputs the "hash" of the certificate subject name. This is used in OpenSSL to
        +form an index to allow certificates in a directory to be looked up by subject
        +name.
        +
        +=item B<-issuer_hash>
        +
        +outputs the "hash" of the certificate issuer name.
        +
        +=item B<-hash>
        +
        +synonym for "-subject_hash" for backward compatibility reasons.
        +
        +=item B<-subject_hash_old>
        +
        +outputs the "hash" of the certificate subject name using the older algorithm
        +as used by OpenSSL versions before 1.0.0.
        +
        +=item B<-issuer_hash_old>
        +
        +outputs the "hash" of the certificate issuer name using the older algorithm
        +as used by OpenSSL versions before 1.0.0.
        +
        +=item B<-subject>
        +
        +outputs the subject name.
        +
        +=item B<-issuer>
        +
        +outputs the issuer name.
        +
        +=item B<-nameopt option>
        +
        +option which determines how the subject or issuer names are displayed. The
        +B<option> argument can be a single option or multiple options separated by
        +commas.  Alternatively the B<-nameopt> switch may be used more than once to
        +set multiple options. See the B<NAME OPTIONS> section for more information.
        +
        +=item B<-email>
        +
        +outputs the email address(es) if any.
        +
        +=item B<-ocsp_uri>
        +
        +outputs the OCSP responder address(es) if any.
        +
        +=item B<-startdate>
        +
        +prints out the start date of the certificate, that is the notBefore date.
        +
        +=item B<-enddate>
        +
        +prints out the expiry date of the certificate, that is the notAfter date.
        +
        +=item B<-dates>
        +
        +prints out the start and expiry dates of a certificate.
        +
        +=item B<-fingerprint>
        +
        +prints out the digest of the DER encoded version of the whole certificate
        +(see digest options).
        +
        +=item B<-C>
        +
        +this outputs the certificate in the form of a C source file.
        +
        +=back
        +
        +=head2 TRUST SETTINGS
        +
        +Please note these options are currently experimental and may well change.
        +
        +A B<trusted certificate> is an ordinary certificate which has several
        +additional pieces of information attached to it such as the permitted
        +and prohibited uses of the certificate and an "alias".
        +
        +Normally when a certificate is being verified at least one certificate
        +must be "trusted". By default a trusted certificate must be stored
        +locally and must be a root CA: any certificate chain ending in this CA
        +is then usable for any purpose.
        +
        +Trust settings currently are only used with a root CA. They allow a finer
        +control over the purposes the root CA can be used for. For example a CA
        +may be trusted for SSL client but not SSL server use.
        +
        +See the description of the B<verify> utility for more information on the
        +meaning of trust settings.
        +
        +Future versions of OpenSSL will recognize trust settings on any
        +certificate: not just root CAs.
        +
        +
        +=over 4
        +
        +=item B<-trustout>
        +
        +this causes B<x509> to output a B<trusted> certificate. An ordinary
        +or trusted certificate can be input but by default an ordinary
        +certificate is output and any trust settings are discarded. With the
        +B<-trustout> option a trusted certificate is output. A trusted
        +certificate is automatically output if any trust settings are modified.
        +
        +=item B<-setalias arg>
        +
        +sets the alias of the certificate. This will allow the certificate
        +to be referred to using a nickname for example "Steve's Certificate".
        +
        +=item B<-alias>
        +
        +outputs the certificate alias, if any.
        +
        +=item B<-clrtrust>
        +
        +clears all the permitted or trusted uses of the certificate.
        +
        +=item B<-clrreject>
        +
        +clears all the prohibited or rejected uses of the certificate.
        +
        +=item B<-addtrust arg>
        +
        +adds a trusted certificate use. Any object name can be used here
        +but currently only B<clientAuth> (SSL client use), B<serverAuth>
        +(SSL server use) and B<emailProtection> (S/MIME email) are used.
        +Other OpenSSL applications may define additional uses.
        +
        +=item B<-addreject arg>
        +
        +adds a prohibited use. It accepts the same values as the B<-addtrust>
        +option.
        +
        +=item B<-purpose>
        +
        +this option performs tests on the certificate extensions and outputs
        +the results. For a more complete description see the B<CERTIFICATE
        +EXTENSIONS> section.
        +
        +=back
        +
        +=head2 SIGNING OPTIONS
        +
        +The B<x509> utility can be used to sign certificates and requests: it
        +can thus behave like a "mini CA".
        +
        +=over 4
        +
        +=item B<-signkey filename>
        +
        +this option causes the input file to be self signed using the supplied
        +private key. 
        +
        +If the input file is a certificate it sets the issuer name to the
        +subject name (i.e.  makes it self signed) changes the public key to the
        +supplied value and changes the start and end dates. The start date is
        +set to the current time and the end date is set to a value determined
        +by the B<-days> option. Any certificate extensions are retained unless
        +the B<-clrext> option is supplied.
        +
        +If the input is a certificate request then a self signed certificate
        +is created using the supplied private key using the subject name in
        +the request.
        +
        +=item B<-clrext>
        +
        +delete any extensions from a certificate. This option is used when a
        +certificate is being created from another certificate (for example with
        +the B<-signkey> or the B<-CA> options). Normally all extensions are
        +retained.
        +
        +=item B<-keyform PEM|DER>
        +
        +specifies the format (DER or PEM) of the private key file used in the
        +B<-signkey> option.
        +
        +=item B<-days arg>
        +
        +specifies the number of days to make a certificate valid for. The default
        +is 30 days.
        +
        +=item B<-x509toreq>
        +
        +converts a certificate into a certificate request. The B<-signkey> option
        +is used to pass the required private key.
        +
        +=item B<-req>
        +
        +by default a certificate is expected on input. With this option a
        +certificate request is expected instead.
        +
        +=item B<-set_serial n>
        +
        +specifies the serial number to use. This option can be used with either
        +the B<-signkey> or B<-CA> options. If used in conjunction with the B<-CA>
        +option the serial number file (as specified by the B<-CAserial> or
        +B<-CAcreateserial> options) is not used.
        +
        +The serial number can be decimal or hex (if preceded by B<0x>). Negative
        +serial numbers can also be specified but their use is not recommended.
        +
        +=item B<-CA filename>
        +
        +specifies the CA certificate to be used for signing. When this option is
        +present B<x509> behaves like a "mini CA". The input file is signed by this
        +CA using this option: that is its issuer name is set to the subject name
        +of the CA and it is digitally signed using the CAs private key.
        +
        +This option is normally combined with the B<-req> option. Without the
        +B<-req> option the input is a certificate which must be self signed.
        +
        +=item B<-CAkey filename>
        +
        +sets the CA private key to sign a certificate with. If this option is
        +not specified then it is assumed that the CA private key is present in
        +the CA certificate file.
        +
        +=item B<-CAserial filename>
        +
        +sets the CA serial number file to use.
        +
        +When the B<-CA> option is used to sign a certificate it uses a serial
        +number specified in a file. This file consist of one line containing
        +an even number of hex digits with the serial number to use. After each
        +use the serial number is incremented and written out to the file again.
        +
        +The default filename consists of the CA certificate file base name with
        +".srl" appended. For example if the CA certificate file is called 
        +"mycacert.pem" it expects to find a serial number file called "mycacert.srl".
        +
        +=item B<-CAcreateserial>
        +
        +with this option the CA serial number file is created if it does not exist:
        +it will contain the serial number "02" and the certificate being signed will
        +have the 1 as its serial number. Normally if the B<-CA> option is specified
        +and the serial number file does not exist it is an error.
        +
        +=item B<-extfile filename>
        +
        +file containing certificate extensions to use. If not specified then
        +no extensions are added to the certificate.
        +
        +=item B<-extensions section>
        +
        +the section to add certificate extensions from. If this option is not
        +specified then the extensions should either be contained in the unnamed
        +(default) section or the default section should contain a variable called
        +"extensions" which contains the section to use. See the
        +L<x509v3_config(5)|x509v3_config(5)> manual page for details of the
        +extension section format.
        +
        +=back
        +
        +=head2 NAME OPTIONS
        +
        +The B<nameopt> command line switch determines how the subject and issuer
        +names are displayed. If no B<nameopt> switch is present the default "oneline"
        +format is used which is compatible with previous versions of OpenSSL.
        +Each option is described in detail below, all options can be preceded by
        +a B<-> to turn the option off. Only the first four will normally be used.
        +
        +=over 4
        +
        +=item B<compat>
        +
        +use the old format. This is equivalent to specifying no name options at all.
        +
        +=item B<RFC2253>
        +
        +displays names compatible with RFC2253 equivalent to B<esc_2253>, B<esc_ctrl>,
        +B<esc_msb>, B<utf8>, B<dump_nostr>, B<dump_unknown>, B<dump_der>,
        +B<sep_comma_plus>, B<dn_rev> and B<sname>.
        +
        +=item B<oneline>
        +
        +a oneline format which is more readable than RFC2253. It is equivalent to
        +specifying the  B<esc_2253>, B<esc_ctrl>, B<esc_msb>, B<utf8>, B<dump_nostr>,
        +B<dump_der>, B<use_quote>, B<sep_comma_plus_space>, B<space_eq> and B<sname>
        +options.
        +
        +=item B<multiline>
        +
        +a multiline format. It is equivalent B<esc_ctrl>, B<esc_msb>, B<sep_multiline>,
        +B<space_eq>, B<lname> and B<align>.
        +
        +=item B<esc_2253>
        +
        +escape the "special" characters required by RFC2253 in a field That is
        +B<,+"E<lt>E<gt>;>. Additionally B<#> is escaped at the beginning of a string
        +and a space character at the beginning or end of a string.
        +
        +=item B<esc_ctrl>
        +
        +escape control characters. That is those with ASCII values less than
        +0x20 (space) and the delete (0x7f) character. They are escaped using the
        +RFC2253 \XX notation (where XX are two hex digits representing the
        +character value).
        +
        +=item B<esc_msb>
        +
        +escape characters with the MSB set, that is with ASCII values larger than
        +127.
        +
        +=item B<use_quote>
        +
        +escapes some characters by surrounding the whole string with B<"> characters,
        +without the option all escaping is done with the B<\> character.
        +
        +=item B<utf8>
        +
        +convert all strings to UTF8 format first. This is required by RFC2253. If
        +you are lucky enough to have a UTF8 compatible terminal then the use
        +of this option (and B<not> setting B<esc_msb>) may result in the correct
        +display of multibyte (international) characters. Is this option is not
        +present then multibyte characters larger than 0xff will be represented
        +using the format \UXXXX for 16 bits and \WXXXXXXXX for 32 bits.
        +Also if this option is off any UTF8Strings will be converted to their
        +character form first.
        +
        +=item B<no_type>
        +
        +this option does not attempt to interpret multibyte characters in any
        +way. That is their content octets are merely dumped as though one octet
        +represents each character. This is useful for diagnostic purposes but
        +will result in rather odd looking output.
        +
        +=item B<show_type>
        +
        +show the type of the ASN1 character string. The type precedes the
        +field contents. For example "BMPSTRING: Hello World".
        +
        +=item B<dump_der>
        +
        +when this option is set any fields that need to be hexdumped will
        +be dumped using the DER encoding of the field. Otherwise just the
        +content octets will be displayed. Both options use the RFC2253
        +B<#XXXX...> format.
        +
        +=item B<dump_nostr>
        +
        +dump non character string types (for example OCTET STRING) if this
        +option is not set then non character string types will be displayed
        +as though each content octet represents a single character.
        +
        +=item B<dump_all>
        +
        +dump all fields. This option when used with B<dump_der> allows the
        +DER encoding of the structure to be unambiguously determined.
        +
        +=item B<dump_unknown>
        +
        +dump any field whose OID is not recognised by OpenSSL.
        +
        +=item B<sep_comma_plus>, B<sep_comma_plus_space>, B<sep_semi_plus_space>,
        +B<sep_multiline>
        +
        +these options determine the field separators. The first character is
        +between RDNs and the second between multiple AVAs (multiple AVAs are
        +very rare and their use is discouraged). The options ending in
        +"space" additionally place a space after the separator to make it
        +more readable. The B<sep_multiline> uses a linefeed character for
        +the RDN separator and a spaced B<+> for the AVA separator. It also
        +indents the fields by four characters.
        +
        +=item B<dn_rev>
        +
        +reverse the fields of the DN. This is required by RFC2253. As a side
        +effect this also reverses the order of multiple AVAs but this is
        +permissible.
        +
        +=item B<nofname>, B<sname>, B<lname>, B<oid>
        +
        +these options alter how the field name is displayed. B<nofname> does
        +not display the field at all. B<sname> uses the "short name" form
        +(CN for commonName for example). B<lname> uses the long form.
        +B<oid> represents the OID in numerical form and is useful for
        +diagnostic purpose.
        +
        +=item B<align>
        +
        +align field values for a more readable output. Only usable with
        +B<sep_multiline>.
        +
        +=item B<space_eq>
        +
        +places spaces round the B<=> character which follows the field
        +name.
        +
        +=back
        +
        +=head2 TEXT OPTIONS
        +
        +As well as customising the name output format, it is also possible to
        +customise the actual fields printed using the B<certopt> options when
        +the B<text> option is present. The default behaviour is to print all fields.
        +
        +=over 4
        +
        +=item B<compatible>
        +
        +use the old format. This is equivalent to specifying no output options at all.
        +
        +=item B<no_header>
        +
        +don't print header information: that is the lines saying "Certificate" and "Data".
        +
        +=item B<no_version>
        +
        +don't print out the version number.
        +
        +=item B<no_serial>
        +
        +don't print out the serial number.
        +
        +=item B<no_signame>
        +
        +don't print out the signature algorithm used.
        +
        +=item B<no_validity>
        +
        +don't print the validity, that is the B<notBefore> and B<notAfter> fields.
        +
        +=item B<no_subject>
        +
        +don't print out the subject name.
        +
        +=item B<no_issuer>
        +
        +don't print out the issuer name.
        +
        +=item B<no_pubkey>
        +
        +don't print out the public key.
        +
        +=item B<no_sigdump>
        +
        +don't give a hexadecimal dump of the certificate signature.
        +
        +=item B<no_aux>
        +
        +don't print out certificate trust information.
        +
        +=item B<no_extensions>
        +
        +don't print out any X509V3 extensions.
        +
        +=item B<ext_default>
        +
        +retain default extension behaviour: attempt to print out unsupported certificate extensions.
        +
        +=item B<ext_error>
        +
        +print an error message for unsupported certificate extensions.
        +
        +=item B<ext_parse>
        +
        +ASN1 parse unsupported extensions.
        +
        +=item B<ext_dump>
        +
        +hex dump unsupported extensions.
        +
        +=item B<ca_default>
        +
        +the value used by the B<ca> utility, equivalent to B<no_issuer>, B<no_pubkey>, B<no_header>,
        +B<no_version>, B<no_sigdump> and B<no_signame>.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Note: in these examples the '\' means the example should be all on one
        +line.
        +
        +Display the contents of a certificate:
        +
        + openssl x509 -in cert.pem -noout -text
        +
        +Display the certificate serial number:
        +
        + openssl x509 -in cert.pem -noout -serial
        +
        +Display the certificate subject name:
        +
        + openssl x509 -in cert.pem -noout -subject
        +
        +Display the certificate subject name in RFC2253 form:
        +
        + openssl x509 -in cert.pem -noout -subject -nameopt RFC2253
        +
        +Display the certificate subject name in oneline form on a terminal
        +supporting UTF8:
        +
        + openssl x509 -in cert.pem -noout -subject -nameopt oneline,-esc_msb
        +
        +Display the certificate MD5 fingerprint:
        +
        + openssl x509 -in cert.pem -noout -fingerprint
        +
        +Display the certificate SHA1 fingerprint:
        +
        + openssl x509 -sha1 -in cert.pem -noout -fingerprint
        +
        +Convert a certificate from PEM to DER format:
        +
        + openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
        +
        +Convert a certificate to a certificate request:
        +
        + openssl x509 -x509toreq -in cert.pem -out req.pem -signkey key.pem
        +
        +Convert a certificate request into a self signed certificate using
        +extensions for a CA:
        +
        + openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca \
        +	-signkey key.pem -out cacert.pem
        +
        +Sign a certificate request using the CA certificate above and add user
        +certificate extensions:
        +
        + openssl x509 -req -in req.pem -extfile openssl.cnf -extensions v3_usr \
        +	-CA cacert.pem -CAkey key.pem -CAcreateserial
        +
        +
        +Set a certificate to be trusted for SSL client use and change set its alias to
        +"Steve's Class 1 CA"
        +
        + openssl x509 -in cert.pem -addtrust clientAuth \
        +	-setalias "Steve's Class 1 CA" -out trust.pem
        +
        +=head1 NOTES
        +
        +The PEM format uses the header and footer lines:
        +
        + -----BEGIN CERTIFICATE-----
        + -----END CERTIFICATE-----
        +
        +it will also handle files containing:
        +
        + -----BEGIN X509 CERTIFICATE-----
        + -----END X509 CERTIFICATE-----
        +
        +Trusted certificates have the lines
        +
        + -----BEGIN TRUSTED CERTIFICATE-----
        + -----END TRUSTED CERTIFICATE-----
        +
        +The conversion to UTF8 format used with the name options assumes that
        +T61Strings use the ISO8859-1 character set. This is wrong but Netscape
        +and MSIE do this as do many certificates. So although this is incorrect
        +it is more likely to display the majority of certificates correctly.
        +
        +The B<-fingerprint> option takes the digest of the DER encoded certificate.
        +This is commonly called a "fingerprint". Because of the nature of message
        +digests the fingerprint of a certificate is unique to that certificate and
        +two certificates with the same fingerprint can be considered to be the same.
        +
        +The Netscape fingerprint uses MD5 whereas MSIE uses SHA1.
        +
        +The B<-email> option searches the subject name and the subject alternative
        +name extension. Only unique email addresses will be printed out: it will
        +not print the same address more than once.
        +
        +=head1 CERTIFICATE EXTENSIONS
        +
        +The B<-purpose> option checks the certificate extensions and determines
        +what the certificate can be used for. The actual checks done are rather
        +complex and include various hacks and workarounds to handle broken
        +certificates and software.
        +
        +The same code is used when verifying untrusted certificates in chains
        +so this section is useful if a chain is rejected by the verify code.
        +
        +The basicConstraints extension CA flag is used to determine whether the
        +certificate can be used as a CA. If the CA flag is true then it is a CA,
        +if the CA flag is false then it is not a CA. B<All> CAs should have the
        +CA flag set to true.
        +
        +If the basicConstraints extension is absent then the certificate is
        +considered to be a "possible CA" other extensions are checked according
        +to the intended use of the certificate. A warning is given in this case
        +because the certificate should really not be regarded as a CA: however
        +it is allowed to be a CA to work around some broken software.
        +
        +If the certificate is a V1 certificate (and thus has no extensions) and
        +it is self signed it is also assumed to be a CA but a warning is again
        +given: this is to work around the problem of Verisign roots which are V1
        +self signed certificates.
        +
        +If the keyUsage extension is present then additional restraints are
        +made on the uses of the certificate. A CA certificate B<must> have the
        +keyCertSign bit set if the keyUsage extension is present.
        +
        +The extended key usage extension places additional restrictions on the
        +certificate uses. If this extension is present (whether critical or not)
        +the key can only be used for the purposes specified.
        +
        +A complete description of each test is given below. The comments about
        +basicConstraints and keyUsage and V1 certificates above apply to B<all>
        +CA certificates.
        +
        +
        +=over 4
        +
        +=item B<SSL Client>
        +
        +The extended key usage extension must be absent or include the "web client
        +authentication" OID.  keyUsage must be absent or it must have the
        +digitalSignature bit set. Netscape certificate type must be absent or it must
        +have the SSL client bit set.
        +
        +=item B<SSL Client CA>
        +
        +The extended key usage extension must be absent or include the "web client
        +authentication" OID. Netscape certificate type must be absent or it must have
        +the SSL CA bit set: this is used as a work around if the basicConstraints
        +extension is absent.
        +
        +=item B<SSL Server>
        +
        +The extended key usage extension must be absent or include the "web server
        +authentication" and/or one of the SGC OIDs.  keyUsage must be absent or it
        +must have the digitalSignature, the keyEncipherment set or both bits set.
        +Netscape certificate type must be absent or have the SSL server bit set.
        +
        +=item B<SSL Server CA>
        +
        +The extended key usage extension must be absent or include the "web server
        +authentication" and/or one of the SGC OIDs.  Netscape certificate type must
        +be absent or the SSL CA bit must be set: this is used as a work around if the
        +basicConstraints extension is absent.
        +
        +=item B<Netscape SSL Server>
        +
        +For Netscape SSL clients to connect to an SSL server it must have the
        +keyEncipherment bit set if the keyUsage extension is present. This isn't
        +always valid because some cipher suites use the key for digital signing.
        +Otherwise it is the same as a normal SSL server.
        +
        +=item B<Common S/MIME Client Tests>
        +
        +The extended key usage extension must be absent or include the "email
        +protection" OID. Netscape certificate type must be absent or should have the
        +S/MIME bit set. If the S/MIME bit is not set in netscape certificate type
        +then the SSL client bit is tolerated as an alternative but a warning is shown:
        +this is because some Verisign certificates don't set the S/MIME bit.
        +
        +=item B<S/MIME Signing>
        +
        +In addition to the common S/MIME client tests the digitalSignature bit must
        +be set if the keyUsage extension is present.
        +
        +=item B<S/MIME Encryption>
        +
        +In addition to the common S/MIME tests the keyEncipherment bit must be set
        +if the keyUsage extension is present.
        +
        +=item B<S/MIME CA>
        +
        +The extended key usage extension must be absent or include the "email
        +protection" OID. Netscape certificate type must be absent or must have the
        +S/MIME CA bit set: this is used as a work around if the basicConstraints
        +extension is absent. 
        +
        +=item B<CRL Signing>
        +
        +The keyUsage extension must be absent or it must have the CRL signing bit
        +set.
        +
        +=item B<CRL Signing CA>
        +
        +The normal CA tests apply. Except in this case the basicConstraints extension
        +must be present.
        +
        +=back
        +
        +=head1 BUGS
        +
        +Extensions in certificates are not transferred to certificate requests and
        +vice versa.
        +
        +It is possible to produce invalid certificates or requests by specifying the
        +wrong private key or using inconsistent options in some cases: these should
        +be checked.
        +
        +There should be options to explicitly set such things as start and end
        +dates rather than an offset from the current time.
        +
        +The code to implement the verify behaviour described in the B<TRUST SETTINGS>
        +is currently being developed. It thus describes the intended behaviour rather
        +than the current behaviour. It is hoped that it will represent reality in
        +OpenSSL 0.9.5 and later.
        +
        +=head1 SEE ALSO
        +
        +L<req(1)|req(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>,
        +L<gendsa(1)|gendsa(1)>, L<verify(1)|verify(1)>,
        +L<x509v3_config(5)|x509v3_config(5)> 
        +
        +=head1 HISTORY
        +
        +Before OpenSSL 0.9.8, the default digest for RSA keys was MD5.
        +
        +The hash algorithm used in the B<-subject_hash> and B<-issuer_hash> options
        +before OpenSSL 1.0.0 was based on the deprecated MD5 algorithm and the encoding
        +of the distinguished name. In OpenSSL 1.0.0 and later it is based on a
        +canonical version of the DN using SHA1. This means that any directories using
        +the old form must have their links rebuilt using B<c_rehash> or similar. 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/apps/x509v3_config.pod b/vendor/openssl/openssl/doc/apps/x509v3_config.pod
        new file mode 100644
        index 000000000..0450067cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/apps/x509v3_config.pod
        @@ -0,0 +1,529 @@
        +=pod
        +
        +=for comment openssl_manual_section:5
        +
        +=head1 NAME
        +
        +x509v3_config - X509 V3 certificate extension configuration format
        +
        +=head1 DESCRIPTION
        +
        +Several of the OpenSSL utilities can add extensions to a certificate or
        +certificate request based on the contents of a configuration file.
        +
        +Typically the application will contain an option to point to an extension
        +section. Each line of the extension section takes the form:
        +
        + extension_name=[critical,] extension_options
        +
        +If B<critical> is present then the extension will be critical.
        +
        +The format of B<extension_options> depends on the value of B<extension_name>.
        +
        +There are four main types of extension: I<string> extensions, I<multi-valued>
        +extensions, I<raw> and I<arbitrary> extensions.
        +
        +String extensions simply have a string which contains either the value itself
        +or how it is obtained.
        +
        +For example:
        +
        + nsComment="This is a Comment"
        +
        +Multi-valued extensions have a short form and a long form. The short form
        +is a list of names and values:
        +
        + basicConstraints=critical,CA:true,pathlen:1
        +
        +The long form allows the values to be placed in a separate section:
        +
        + basicConstraints=critical,@bs_section
        +
        + [bs_section]
        +
        + CA=true
        + pathlen=1
        +
        +Both forms are equivalent.
        +
        +The syntax of raw extensions is governed by the extension code: it can
        +for example contain data in multiple sections. The correct syntax to
        +use is defined by the extension code itself: check out the certificate
        +policies extension for an example.
        +
        +If an extension type is unsupported then the I<arbitrary> extension syntax
        +must be used, see the L<ARBITRARY EXTENSIONS|/"ARBITRARY EXTENSIONS"> section for more details.
        +
        +=head1 STANDARD EXTENSIONS
        +
        +The following sections describe each supported extension in detail.
        +
        +=head2 Basic Constraints.
        +
        +This is a multi valued extension which indicates whether a certificate is
        +a CA certificate. The first (mandatory) name is B<CA> followed by B<TRUE> or
        +B<FALSE>. If B<CA> is B<TRUE> then an optional B<pathlen> name followed by an
        +non-negative value can be included.
        +
        +For example:
        +
        + basicConstraints=CA:TRUE
        +
        + basicConstraints=CA:FALSE
        +
        + basicConstraints=critical,CA:TRUE, pathlen:0
        +
        +A CA certificate B<must> include the basicConstraints value with the CA field
        +set to TRUE. An end user certificate must either set CA to FALSE or exclude the
        +extension entirely. Some software may require the inclusion of basicConstraints
        +with CA set to FALSE for end entity certificates.
        +
        +The pathlen parameter indicates the maximum number of CAs that can appear
        +below this one in a chain. So if you have a CA with a pathlen of zero it can
        +only be used to sign end user certificates and not further CAs.
        +
        +
        +=head2 Key Usage.
        +
        +Key usage is a multi valued extension consisting of a list of names of the
        +permitted key usages.
        +
        +The supporte names are: digitalSignature, nonRepudiation, keyEncipherment,
        +dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly
        +and decipherOnly.
        +
        +Examples:
        +
        + keyUsage=digitalSignature, nonRepudiation
        +
        + keyUsage=critical, keyCertSign
        +
        +
        +=head2 Extended Key Usage.
        +
        +This extensions consists of a list of usages indicating purposes for which
        +the certificate public key can be used for,
        +
        +These can either be object short names of the dotted numerical form of OIDs.
        +While any OID can be used only certain values make sense. In particular the
        +following PKIX, NS and MS values are meaningful:
        +
        + Value			Meaning
        + -----			-------
        + serverAuth		SSL/TLS Web Server Authentication.
        + clientAuth		SSL/TLS Web Client Authentication.
        + codeSigning		Code signing.
        + emailProtection	E-mail Protection (S/MIME).
        + timeStamping		Trusted Timestamping
        + msCodeInd		Microsoft Individual Code Signing (authenticode)
        + msCodeCom		Microsoft Commercial Code Signing (authenticode)
        + msCTLSign		Microsoft Trust List Signing
        + msSGC			Microsoft Server Gated Crypto
        + msEFS			Microsoft Encrypted File System
        + nsSGC			Netscape Server Gated Crypto
        +
        +Examples:
        +
        + extendedKeyUsage=critical,codeSigning,1.2.3.4
        + extendedKeyUsage=nsSGC,msSGC
        +
        +
        +=head2 Subject Key Identifier.
        +
        +This is really a string extension and can take two possible values. Either
        +the word B<hash> which will automatically follow the guidelines in RFC3280
        +or a hex string giving the extension value to include. The use of the hex
        +string is strongly discouraged.
        +
        +Example:
        +
        + subjectKeyIdentifier=hash
        +
        +
        +=head2 Authority Key Identifier.
        +
        +The authority key identifier extension permits two options. keyid and issuer:
        +both can take the optional value "always".
        +
        +If the keyid option is present an attempt is made to copy the subject key
        +identifier from the parent certificate. If the value "always" is present
        +then an error is returned if the option fails.
        +
        +The issuer option copies the issuer and serial number from the issuer
        +certificate. This will only be done if the keyid option fails or
        +is not included unless the "always" flag will always include the value.
        +
        +Example:
        +
        + authorityKeyIdentifier=keyid,issuer
        +
        +
        +=head2 Subject Alternative Name.
        +
        +The subject alternative name extension allows various literal values to be
        +included in the configuration file. These include B<email> (an email address)
        +B<URI> a uniform resource indicator, B<DNS> (a DNS domain name), B<RID> (a
        +registered ID: OBJECT IDENTIFIER), B<IP> (an IP address), B<dirName>
        +(a distinguished name) and otherName.
        +
        +The email option include a special 'copy' value. This will automatically
        +include and email addresses contained in the certificate subject name in
        +the extension.
        +
        +The IP address used in the B<IP> options can be in either IPv4 or IPv6 format.
        +
        +The value of B<dirName> should point to a section containing the distinguished
        +name to use as a set of name value pairs. Multi values AVAs can be formed by
        +preceeding the name with a B<+> character.
        +
        +otherName can include arbitrary data associated with an OID: the value
        +should be the OID followed by a semicolon and the content in standard
        +L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)> format.
        +
        +Examples:
        +
        + subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/
        + subjectAltName=IP:192.168.7.1
        + subjectAltName=IP:13::17
        + subjectAltName=email:my@other.address,RID:1.2.3.4
        + subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
        +
        + subjectAltName=dirName:dir_sect
        +
        + [dir_sect]
        + C=UK
        + O=My Organization
        + OU=My Unit
        + CN=My Name
        +
        +
        +=head2 Issuer Alternative Name.
        +
        +The issuer alternative name option supports all the literal options of
        +subject alternative name. It does B<not> support the email:copy option because
        +that would not make sense. It does support an additional issuer:copy option
        +that will copy all the subject alternative name values from the issuer 
        +certificate (if possible).
        +
        +Example:
        +
        + issuserAltName = issuer:copy
        +
        +
        +=head2 Authority Info Access.
        +
        +The authority information access extension gives details about how to access
        +certain information relating to the CA. Its syntax is accessOID;location
        +where I<location> has the same syntax as subject alternative name (except
        +that email:copy is not supported). accessOID can be any valid OID but only
        +certain values are meaningful, for example OCSP and caIssuers.
        +
        +Example:
        +
        + authorityInfoAccess = OCSP;URI:http://ocsp.my.host/
        + authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html
        +
        +
        +=head2 CRL distribution points.
        +
        +This is a multi-valued extension whose options can be either in name:value pair
        +using the same form as subject alternative name or a single value representing
        +a section name containing all the distribution point fields.
        +
        +For a name:value pair a new DistributionPoint with the fullName field set to
        +the given value both the cRLissuer and reasons fields are omitted in this case.
        +
        +In the single option case the section indicated contains values for each
        +field. In this section:
        +
        +If the name is "fullname" the value field should contain the full name
        +of the distribution point in the same format as subject alternative name.
        +
        +If the name is "relativename" then the value field should contain a section
        +name whose contents represent a DN fragment to be placed in this field.
        +
        +The name "CRLIssuer" if present should contain a value for this field in
        +subject alternative name format.
        +
        +If the name is "reasons" the value field should consist of a comma
        +separated field containing the reasons. Valid reasons are: "keyCompromise",
        +"CACompromise", "affiliationChanged", "superseded", "cessationOfOperation",
        +"certificateHold", "privilegeWithdrawn" and "AACompromise".
        +
        +
        +Simple examples:
        +
        + crlDistributionPoints=URI:http://myhost.com/myca.crl
        + crlDistributionPoints=URI:http://my.com/my.crl,URI:http://oth.com/my.crl
        +
        +Full distribution point example:
        +
        + crlDistributionPoints=crldp1_section
        +
        + [crldp1_section]
        +
        + fullname=URI:http://myhost.com/myca.crl
        + CRLissuer=dirName:issuer_sect
        + reasons=keyCompromise, CACompromise
        +
        + [issuer_sect]
        + C=UK
        + O=Organisation
        + CN=Some Name
        +
        +=head2 Issuing Distribution Point
        +
        +This extension should only appear in CRLs. It is a multi valued extension
        +whose syntax is similar to the "section" pointed to by the CRL distribution
        +points extension with a few differences.
        +
        +The names "reasons" and "CRLissuer" are not recognized.
        +
        +The name "onlysomereasons" is accepted which sets this field. The value is
        +in the same format as the CRL distribution point "reasons" field.
        +
        +The names "onlyuser", "onlyCA", "onlyAA" and "indirectCRL" are also accepted
        +the values should be a boolean value (TRUE or FALSE) to indicate the value of
        +the corresponding field.
        +
        +Example:
        +
        + issuingDistributionPoint=critical, @idp_section
        +
        + [idp_section]
        +
        + fullname=URI:http://myhost.com/myca.crl
        + indirectCRL=TRUE
        + onlysomereasons=keyCompromise, CACompromise
        +
        + [issuer_sect]
        + C=UK
        + O=Organisation
        + CN=Some Name
        +
        + 
        +=head2 Certificate Policies.
        +
        +This is a I<raw> extension. All the fields of this extension can be set by
        +using the appropriate syntax.
        +
        +If you follow the PKIX recommendations and just using one OID then you just
        +include the value of that OID. Multiple OIDs can be set separated by commas,
        +for example:
        +
        + certificatePolicies= 1.2.4.5, 1.1.3.4
        +
        +If you wish to include qualifiers then the policy OID and qualifiers need to
        +be specified in a separate section: this is done by using the @section syntax
        +instead of a literal OID value.
        +
        +The section referred to must include the policy OID using the name
        +policyIdentifier, cPSuri qualifiers can be included using the syntax:
        +
        + CPS.nnn=value
        +
        +userNotice qualifiers can be set using the syntax:
        +
        + userNotice.nnn=@notice
        +
        +The value of the userNotice qualifier is specified in the relevant section.
        +This section can include explicitText, organization and noticeNumbers
        +options. explicitText and organization are text strings, noticeNumbers is a
        +comma separated list of numbers. The organization and noticeNumbers options
        +(if included) must BOTH be present. If you use the userNotice option with IE5
        +then you need the 'ia5org' option at the top level to modify the encoding:
        +otherwise it will not be interpreted properly.
        +
        +Example:
        +
        + certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect
        +
        + [polsect]
        +
        + policyIdentifier = 1.3.5.8
        + CPS.1="http://my.host.name/"
        + CPS.2="http://my.your.name/"
        + userNotice.1=@notice
        +
        + [notice]
        +
        + explicitText="Explicit Text Here"
        + organization="Organisation Name"
        + noticeNumbers=1,2,3,4
        +
        +The B<ia5org> option changes the type of the I<organization> field. In RFC2459
        +it can only be of type DisplayText. In RFC3280 IA5Strring is also permissible.
        +Some software (for example some versions of MSIE) may require ia5org.
        +
        +=head2 Policy Constraints
        +
        +This is a multi-valued extension which consisting of the names
        +B<requireExplicitPolicy> or B<inhibitPolicyMapping> and a non negative intger
        +value. At least one component must be present.
        +
        +Example:
        +
        + policyConstraints = requireExplicitPolicy:3
        +
        +
        +=head2 Inhibit Any Policy
        +
        +This is a string extension whose value must be a non negative integer.
        +
        +Example:
        +
        + inhibitAnyPolicy = 2
        +
        +
        +=head2 Name Constraints
        +
        +The name constraints extension is a multi-valued extension. The name should
        +begin with the word B<permitted> or B<excluded> followed by a B<;>. The rest of
        +the name and the value follows the syntax of subjectAltName except email:copy
        +is not supported and the B<IP> form should consist of an IP addresses and 
        +subnet mask separated by a B</>.
        +
        +Examples:
        +
        + nameConstraints=permitted;IP:192.168.0.0/255.255.0.0
        +
        + nameConstraints=permitted;email:.somedomain.com
        +
        + nameConstraints=excluded;email:.com
        +issuingDistributionPoint = idp_section
        +
        +=head2 OCSP No Check
        +
        +The OCSP No Check extension is a string extension but its value is ignored.
        +
        +Example:
        +
        + noCheck = ignored
        +
        +
        +=head1 DEPRECATED EXTENSIONS
        +
        +The following extensions are non standard, Netscape specific and largely
        +obsolete. Their use in new applications is discouraged.
        +
        +=head2 Netscape String extensions.
        +
        +Netscape Comment (B<nsComment>) is a string extension containing a comment
        +which will be displayed when the certificate is viewed in some browsers.
        +
        +Example:
        +
        + nsComment = "Some Random Comment"
        +
        +Other supported extensions in this category are: B<nsBaseUrl>,
        +B<nsRevocationUrl>, B<nsCaRevocationUrl>, B<nsRenewalUrl>, B<nsCaPolicyUrl>
        +and B<nsSslServerName>.
        +
        +
        +=head2 Netscape Certificate Type
        +
        +This is a multi-valued extensions which consists of a list of flags to be
        +included. It was used to indicate the purposes for which a certificate could
        +be used. The basicConstraints, keyUsage and extended key usage extensions are
        +now used instead.
        +
        +Acceptable values for nsCertType are: B<client>, B<server>, B<email>,
        +B<objsign>, B<reserved>, B<sslCA>, B<emailCA>, B<objCA>.
        +
        +
        +=head1 ARBITRARY EXTENSIONS
        +
        +If an extension is not supported by the OpenSSL code then it must be encoded
        +using the arbitrary extension format. It is also possible to use the arbitrary
        +format for supported extensions. Extreme care should be taken to ensure that
        +the data is formatted correctly for the given extension type.
        +
        +There are two ways to encode arbitrary extensions.
        +
        +The first way is to use the word ASN1 followed by the extension content
        +using the same syntax as L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)>.
        +For example:
        +
        + 1.2.3.4=critical,ASN1:UTF8String:Some random data
        +
        + 1.2.3.4=ASN1:SEQUENCE:seq_sect
        +
        + [seq_sect]
        +
        + field1 = UTF8:field1
        + field2 = UTF8:field2
        +
        +It is also possible to use the word DER to include the raw encoded data in any
        +extension.
        +
        + 1.2.3.4=critical,DER:01:02:03:04
        + 1.2.3.4=DER:01020304
        +
        +The value following DER is a hex dump of the DER encoding of the extension
        +Any extension can be placed in this form to override the default behaviour.
        +For example:
        +
        + basicConstraints=critical,DER:00:01:02:03
        +
        +=head1 WARNING
        +
        +There is no guarantee that a specific implementation will process a given
        +extension. It may therefore be sometimes possible to use certificates for
        +purposes prohibited by their extensions because a specific application does
        +not recognize or honour the values of the relevant extensions.
        +
        +The DER and ASN1 options should be used with caution. It is possible to create
        +totally invalid extensions if they are not used carefully.
        +
        +
        +=head1 NOTES
        +
        +If an extension is multi-value and a field value must contain a comma the long
        +form must be used otherwise the comma would be misinterpreted as a field
        +separator. For example:
        +
        + subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
        +
        +will produce an error but the equivalent form:
        +
        + subjectAltName=@subject_alt_section
        +
        + [subject_alt_section]
        + subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
        +
        +is valid. 
        +
        +Due to the behaviour of the OpenSSL B<conf> library the same field name
        +can only occur once in a section. This means that:
        +
        + subjectAltName=@alt_section
        +
        + [alt_section]
        +
        + email=steve@here
        + email=steve@there
        +
        +will only recognize the last value. This can be worked around by using the form:
        +
        + [alt_section]
        +
        + email.1=steve@here
        + email.2=steve@there
        +
        +=head1 HISTORY
        +
        +The X509v3 extension code was first added to OpenSSL 0.9.2.
        +
        +Policy mappings, inhibit any policy and name constraints support was added in
        +OpenSSL 0.9.8
        +
        +The B<directoryName> and B<otherName> option as well as the B<ASN1> option
        +for arbitrary extensions was added in OpenSSL 0.9.8
        +
        +=head1 SEE ALSO
        +
        +L<req(1)|req(1)>, L<ca(1)|ca(1)>, L<x509(1)|x509(1)>,
        +L<ASN1_generate_nconf(3)|ASN1_generate_nconf(3)>
        +
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/c-indentation.el b/vendor/openssl/openssl/doc/c-indentation.el
        new file mode 100644
        index 000000000..90861d397
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/c-indentation.el
        @@ -0,0 +1,45 @@
        +; This Emacs Lisp file defines a C indentation style that closely
        +; follows most aspects of the one that is used throughout SSLeay,
        +; and hence in OpenSSL.
        +; 
        +; This definition is for the "CC mode" package, which is the default
        +; mode for editing C source files in Emacs 20, not for the older
        +; c-mode.el (which was the default in less recent releaes of Emacs 19).
        +;
        +; Copy the definition in your .emacs file or use M-x eval-buffer.
        +; To activate this indentation style, visit a C file, type
        +; M-x c-set-style <RET> (or C-c . for short), and enter "eay".
        +; To toggle the auto-newline feature of CC mode, type C-c C-a.
        +;
        +; Apparently statement blocks that are not introduced by a statement
        +; such as "if" and that are not the body of a function cannot
        +; be handled too well by CC mode with this indentation style,
        +; so you have to indent them manually (you can use C-q tab).
        +; 
        +; For suggesting improvements, please send e-mail to bodo@openssl.org.
        +
        +(c-add-style "eay"
        +	     '((c-basic-offset . 8)
        +	       (indent-tabs-mode . t)
        +	       (c-comment-only-line-offset . 0)
        +	       (c-hanging-braces-alist)
        +	       (c-offsets-alist	. ((defun-open . +)
        +				   (defun-block-intro . 0)
        +				   (class-open . +)
        +				   (class-close . +)
        +				   (block-open . 0)
        +				   (block-close . 0)
        +				   (substatement-open . +)
        +				   (statement . 0)
        +				   (statement-block-intro . 0)
        +				   (statement-case-open . +)
        +				   (statement-case-intro . +)
        +				   (case-label . -)
        +				   (label . -)
        +				   (arglist-cont-nonempty . +)
        +				   (topmost-intro . -)
        +				   (brace-list-close . 0)
        +				   (brace-list-intro . 0)
        +				   (brace-list-open . +)
        +				   ))))
        +
        diff --git a/vendor/openssl/openssl/doc/crypto/ASN1_OBJECT_new.pod b/vendor/openssl/openssl/doc/crypto/ASN1_OBJECT_new.pod
        new file mode 100644
        index 000000000..9bae40fcc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ASN1_OBJECT_new.pod
        @@ -0,0 +1,45 @@
        +=pod
        +
        +=head1 NAME
        +
        +ASN1_OBJECT_new, ASN1_OBJECT_free, - object allocation functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/asn1.h>
        +
        + ASN1_OBJECT *ASN1_OBJECT_new(void);
        + void ASN1_OBJECT_free(ASN1_OBJECT *a);
        +
        +=head1 DESCRIPTION
        +
        +The ASN1_OBJECT allocation routines, allocate and free an
        +ASN1_OBJECT structure, which represents an ASN1 OBJECT IDENTIFIER.
        +
        +ASN1_OBJECT_new() allocates and initializes a ASN1_OBJECT structure.
        +
        +ASN1_OBJECT_free() frees up the B<ASN1_OBJECT> structure B<a>.
        +
        +=head1 NOTES
        +
        +Although ASN1_OBJECT_new() allocates a new ASN1_OBJECT structure it
        +is almost never used in applications. The ASN1 object utility functions
        +such as OBJ_nid2obj() are used instead.
        +
        +=head1 RETURN VALUES
        +
        +If the allocation fails, ASN1_OBJECT_new() returns B<NULL> and sets an error
        +code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +Otherwise it returns a pointer to the newly allocated structure.
        +
        +ASN1_OBJECT_free() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_ASN1_OBJECT(3)|d2i_ASN1_OBJECT(3)>
        +
        +=head1 HISTORY
        +
        +ASN1_OBJECT_new() and ASN1_OBJECT_free() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ASN1_STRING_length.pod b/vendor/openssl/openssl/doc/crypto/ASN1_STRING_length.pod
        new file mode 100644
        index 000000000..a08e9a0fa
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ASN1_STRING_length.pod
        @@ -0,0 +1,83 @@
        +=pod
        +
        +=head1 NAME
        +
        +ASN1_STRING_dup, ASN1_STRING_cmp, ASN1_STRING_set, ASN1_STRING_length,
        +ASN1_STRING_length_set, ASN1_STRING_type, ASN1_STRING_data -
        +ASN1_STRING utility functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/asn1.h>
        +
        + int ASN1_STRING_length(ASN1_STRING *x);
        + unsigned char * ASN1_STRING_data(ASN1_STRING *x);
        +
        + ASN1_STRING * ASN1_STRING_dup(ASN1_STRING *a);
        +
        + int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
        +
        + int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
        +
        + int ASN1_STRING_type(ASN1_STRING *x);
        +
        + int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
        +
        +=head1 DESCRIPTION
        +
        +These functions allow an B<ASN1_STRING> structure to be manipulated.
        +
        +ASN1_STRING_length() returns the length of the content of B<x>.
        +
        +ASN1_STRING_data() returns an internal pointer to the data of B<x>.
        +Since this is an internal pointer it should B<not> be freed or
        +modified in any way.
        +
        +ASN1_STRING_dup() returns a copy of the structure B<a>.
        +
        +ASN1_STRING_cmp() compares B<a> and B<b> returning 0 if the two
        +are identical. The string types and content are compared.
        +
        +ASN1_STRING_set() sets the data of string B<str> to the buffer
        +B<data> or length B<len>. The supplied data is copied. If B<len>
        +is -1 then the length is determined by strlen(data).
        +
        +ASN1_STRING_type() returns the type of B<x>, using standard constants
        +such as B<V_ASN1_OCTET_STRING>.
        +
        +ASN1_STRING_to_UTF8() converts the string B<in> to UTF8 format, the
        +converted data is allocated in a buffer in B<*out>. The length of
        +B<out> is returned or a negative error code. The buffer B<*out>
        +should be free using OPENSSL_free().
        +
        +=head1 NOTES
        +
        +Almost all ASN1 types in OpenSSL are represented as an B<ASN1_STRING>
        +structure. Other types such as B<ASN1_OCTET_STRING> are simply typedefed
        +to B<ASN1_STRING> and the functions call the B<ASN1_STRING> equivalents.
        +B<ASN1_STRING> is also used for some B<CHOICE> types which consist
        +entirely of primitive string types such as B<DirectoryString> and
        +B<Time>.
        +
        +These functions should B<not> be used to examine or modify B<ASN1_INTEGER>
        +or B<ASN1_ENUMERATED> types: the relevant B<INTEGER> or B<ENUMERATED>
        +utility functions should be used instead.
        +
        +In general it cannot be assumed that the data returned by ASN1_STRING_data()
        +is null terminated or does not contain embedded nulls. The actual format
        +of the data will depend on the actual string type itself: for example
        +for and IA5String the data will be ASCII, for a BMPString two bytes per
        +character in big endian format, UTF8String will be in UTF8 format.
        +
        +Similar care should be take to ensure the data is in the correct format
        +when calling ASN1_STRING_set().
        +
        +=head1 RETURN VALUES
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ASN1_STRING_new.pod b/vendor/openssl/openssl/doc/crypto/ASN1_STRING_new.pod
        new file mode 100644
        index 000000000..8ac2a03ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ASN1_STRING_new.pod
        @@ -0,0 +1,46 @@
        +=pod
        +
        +=head1 NAME
        +
        +ASN1_STRING_new, ASN1_STRING_type_new, ASN1_STRING_free -
        +ASN1_STRING allocation functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/asn1.h>
        +
        + ASN1_STRING * ASN1_STRING_new(void);
        + ASN1_STRING * ASN1_STRING_type_new(int type);
        + void ASN1_STRING_free(ASN1_STRING *a);
        +
        +=head1 DESCRIPTION
        +
        +ASN1_STRING_new() returns an allocated B<ASN1_STRING> structure. Its type
        +is undefined.
        +
        +ASN1_STRING_type_new() returns an allocated B<ASN1_STRING> structure of
        +type B<type>.
        +
        +ASN1_STRING_free() frees up B<a>.
        +
        +=head1 NOTES
        +
        +Other string types call the B<ASN1_STRING> functions. For example
        +ASN1_OCTET_STRING_new() calls ASN1_STRING_type(V_ASN1_OCTET_STRING).
        +
        +=head1 RETURN VALUES
        +
        +ASN1_STRING_new() and ASN1_STRING_type_new() return a valid
        +ASN1_STRING structure or B<NULL> if an error occurred.
        +
        +ASN1_STRING_free() does not return a value.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ASN1_STRING_print_ex.pod b/vendor/openssl/openssl/doc/crypto/ASN1_STRING_print_ex.pod
        new file mode 100644
        index 000000000..3891b8879
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ASN1_STRING_print_ex.pod
        @@ -0,0 +1,96 @@
        +=pod
        +
        +=head1 NAME
        +
        +ASN1_STRING_print_ex, ASN1_STRING_print_ex_fp - ASN1_STRING output routines.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/asn1.h>
        +
        + int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
        + int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
        + int ASN1_STRING_print(BIO *out, ASN1_STRING *str);
        +
        +
        +=head1 DESCRIPTION
        +
        +These functions output an B<ASN1_STRING> structure. B<ASN1_STRING> is used to
        +represent all the ASN1 string types.
        +
        +ASN1_STRING_print_ex() outputs B<str> to B<out>, the format is determined by
        +the options B<flags>. ASN1_STRING_print_ex_fp() is identical except it outputs
        +to B<fp> instead.
        +
        +ASN1_STRING_print() prints B<str> to B<out> but using a different format to
        +ASN1_STRING_print_ex(). It replaces unprintable characters (other than CR, LF)
        +with '.'.
        +
        +=head1 NOTES
        +
        +ASN1_STRING_print() is a legacy function which should be avoided in new applications.
        +
        +Although there are a large number of options frequently B<ASN1_STRFLGS_RFC2253> is 
        +suitable, or on UTF8 terminals B<ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB>.
        +
        +The complete set of supported options for B<flags> is listed below.
        +
        +Various characters can be escaped. If B<ASN1_STRFLGS_ESC_2253> is set the characters
        +determined by RFC2253 are escaped. If B<ASN1_STRFLGS_ESC_CTRL> is set control
        +characters are escaped. If B<ASN1_STRFLGS_ESC_MSB> is set characters with the
        +MSB set are escaped: this option should B<not> be used if the terminal correctly
        +interprets UTF8 sequences.
        +
        +Escaping takes several forms.
        +
        +If the character being escaped is a 16 bit character then the form "\UXXXX" is used
        +using exactly four characters for the hex representation. If it is 32 bits then
        +"\WXXXXXXXX" is used using eight characters of its hex representation. These forms
        +will only be used if UTF8 conversion is not set (see below).
        +
        +Printable characters are normally escaped using the backslash '\' character. If
        +B<ASN1_STRFLGS_ESC_QUOTE> is set then the whole string is instead surrounded by
        +double quote characters: this is arguably more readable than the backslash
        +notation. Other characters use the "\XX" using exactly two characters of the hex
        +representation.
        +
        +If B<ASN1_STRFLGS_UTF8_CONVERT> is set then characters are converted to UTF8
        +format first. If the terminal supports the display of UTF8 sequences then this
        +option will correctly display multi byte characters.
        +
        +If B<ASN1_STRFLGS_IGNORE_TYPE> is set then the string type is not interpreted at
        +all: everything is assumed to be one byte per character. This is primarily for
        +debugging purposes and can result in confusing output in multi character strings.
        +
        +If B<ASN1_STRFLGS_SHOW_TYPE> is set then the string type itself is printed out
        +before its value (for example "BMPSTRING"), this actually uses ASN1_tag2str().
        +
        +The content of a string instead of being interpreted can be "dumped": this just
        +outputs the value of the string using the form #XXXX using hex format for each
        +octet.
        +
        +If B<ASN1_STRFLGS_DUMP_ALL> is set then any type is dumped.
        +
        +Normally non character string types (such as OCTET STRING) are assumed to be
        +one byte per character, if B<ASN1_STRFLGS_DUMP_UNKNOWN> is set then they will
        +be dumped instead.
        +
        +When a type is dumped normally just the content octets are printed, if 
        +B<ASN1_STRFLGS_DUMP_DER> is set then the complete encoding is dumped
        +instead (including tag and length octets).
        +
        +B<ASN1_STRFLGS_RFC2253> includes all the flags required by RFC2253. It is
        +equivalent to:
        + ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB |
        + ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_DUMP_UNKNOWN ASN1_STRFLGS_DUMP_DER
        +
        +=head1 SEE ALSO
        +
        +L<X509_NAME_print_ex(3)|X509_NAME_print_ex(3)>,
        +L<ASN1_tag2str(3)|ASN1_tag2str(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ASN1_generate_nconf.pod b/vendor/openssl/openssl/doc/crypto/ASN1_generate_nconf.pod
        new file mode 100644
        index 000000000..542fd1579
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ASN1_generate_nconf.pod
        @@ -0,0 +1,265 @@
        +=pod
        +
        +=head1 NAME
        +
        +ASN1_generate_nconf, ASN1_generate_v3 - ASN1 generation functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/asn1.h>
        +
        + ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
        + ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
        +
        +=head1 DESCRIPTION
        +
        +These functions generate the ASN1 encoding of a string
        +in an B<ASN1_TYPE> structure.
        +
        +B<str> contains the string to encode B<nconf> or B<cnf> contains
        +the optional configuration information where additional strings
        +will be read from. B<nconf> will typically come from a config
        +file wherease B<cnf> is obtained from an B<X509V3_CTX> structure
        +which will typically be used by X509 v3 certificate extension
        +functions. B<cnf> or B<nconf> can be set to B<NULL> if no additional
        +configuration will be used.
        +
        +=head1 GENERATION STRING FORMAT
        +
        +The actual data encoded is determined by the string B<str> and
        +the configuration information. The general format of the string
        +is:
        +
        +=over 2
        +
        +=item B<[modifier,]type[:value]>
        +
        +=back
        +
        +That is zero or more comma separated modifiers followed by a type
        +followed by an optional colon and a value. The formats of B<type>,
        +B<value> and B<modifier> are explained below.
        +
        +=head2 SUPPORTED TYPES
        +
        +The supported types are listed below. Unless otherwise specified
        +only the B<ASCII> format is permissible.
        +
        +=over 2
        +
        +=item B<BOOLEAN>, B<BOOL>
        +
        +This encodes a boolean type. The B<value> string is mandatory and
        +should be B<TRUE> or B<FALSE>. Additionally B<TRUE>, B<true>, B<Y>,
        +B<y>, B<YES>, B<yes>, B<FALSE>, B<false>, B<N>, B<n>, B<NO> and B<no>
        +are acceptable. 
        +
        +=item B<NULL>
        +
        +Encode the B<NULL> type, the B<value> string must not be present.
        +
        +=item B<INTEGER>, B<INT>
        +
        +Encodes an ASN1 B<INTEGER> type. The B<value> string represents
        +the value of the integer, it can be preceeded by a minus sign and
        +is normally interpreted as a decimal value unless the prefix B<0x>
        +is included.
        +
        +=item B<ENUMERATED>, B<ENUM>
        +
        +Encodes the ASN1 B<ENUMERATED> type, it is otherwise identical to
        +B<INTEGER>.
        +
        +=item B<OBJECT>, B<OID>
        +
        +Encodes an ASN1 B<OBJECT IDENTIFIER>, the B<value> string can be
        +a short name, a long name or numerical format.
        +
        +=item B<UTCTIME>, B<UTC>
        +
        +Encodes an ASN1 B<UTCTime> structure, the value should be in
        +the format B<YYMMDDHHMMSSZ>. 
        +
        +=item B<GENERALIZEDTIME>, B<GENTIME>
        +
        +Encodes an ASN1 B<GeneralizedTime> structure, the value should be in
        +the format B<YYYYMMDDHHMMSSZ>. 
        +
        +=item B<OCTETSTRING>, B<OCT>
        +
        +Encodes an ASN1 B<OCTET STRING>. B<value> represents the contents
        +of this structure, the format strings B<ASCII> and B<HEX> can be
        +used to specify the format of B<value>.
        +
        +=item B<BITSTRING>, B<BITSTR>
        +
        +Encodes an ASN1 B<BIT STRING>. B<value> represents the contents
        +of this structure, the format strings B<ASCII>, B<HEX> and B<BITLIST>
        +can be used to specify the format of B<value>.
        +
        +If the format is anything other than B<BITLIST> the number of unused
        +bits is set to zero.
        +
        +=item B<UNIVERSALSTRING>, B<UNIV>, B<IA5>, B<IA5STRING>, B<UTF8>,
        +B<UTF8String>, B<BMP>, B<BMPSTRING>, B<VISIBLESTRING>,
        +B<VISIBLE>, B<PRINTABLESTRING>, B<PRINTABLE>, B<T61>,
        +B<T61STRING>, B<TELETEXSTRING>, B<GeneralString>, B<NUMERICSTRING>,
        +B<NUMERIC>
        +
        +These encode the corresponding string types. B<value> represents the
        +contents of this structure. The format can be B<ASCII> or B<UTF8>.
        +
        +=item B<SEQUENCE>, B<SEQ>, B<SET>
        +
        +Formats the result as an ASN1 B<SEQUENCE> or B<SET> type. B<value>
        +should be a section name which will contain the contents. The
        +field names in the section are ignored and the values are in the
        +generated string format. If B<value> is absent then an empty SEQUENCE
        +will be encoded.
        +
        +=back
        +
        +=head2 MODIFIERS
        +
        +Modifiers affect the following structure, they can be used to
        +add EXPLICIT or IMPLICIT tagging, add wrappers or to change
        +the string format of the final type and value. The supported
        +formats are documented below.
        +
        +=over 2
        +
        +=item B<EXPLICIT>, B<EXP>
        +
        +Add an explicit tag to the following structure. This string
        +should be followed by a colon and the tag value to use as a
        +decimal value.
        +
        +By following the number with B<U>, B<A>, B<P> or B<C> UNIVERSAL,
        +APPLICATION, PRIVATE or CONTEXT SPECIFIC tagging can be used,
        +the default is CONTEXT SPECIFIC.
        +
        +=item B<IMPLICIT>, B<IMP>
        +
        +This is the same as B<EXPLICIT> except IMPLICIT tagging is used
        +instead.
        +
        +=item B<OCTWRAP>, B<SEQWRAP>, B<SETWRAP>, B<BITWRAP>
        +
        +The following structure is surrounded by an OCTET STRING, a SEQUENCE,
        +a SET or a BIT STRING respectively. For a BIT STRING the number of unused
        +bits is set to zero.
        +
        +=item B<FORMAT>
        +
        +This specifies the format of the ultimate value. It should be followed
        +by a colon and one of the strings B<ASCII>, B<UTF8>, B<HEX> or B<BITLIST>.
        +
        +If no format specifier is included then B<ASCII> is used. If B<UTF8> is
        +specified then the value string must be a valid B<UTF8> string. For B<HEX> the
        +output must be a set of hex digits. B<BITLIST> (which is only valid for a BIT
        +STRING) is a comma separated list of the indices of the set bits, all other
        +bits are zero.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +A simple IA5String:
        +
        + IA5STRING:Hello World
        +
        +An IA5String explicitly tagged:
        +
        + EXPLICIT:0,IA5STRING:Hello World
        +
        +An IA5String explicitly tagged using APPLICATION tagging:
        +
        + EXPLICIT:0A,IA5STRING:Hello World
        +
        +A BITSTRING with bits 1 and 5 set and all others zero:
        +
        + FORMAT:BITLIST,BITSTRING:1,5
        +
        +A more complex example using a config file to produce a
        +SEQUENCE consiting of a BOOL an OID and a UTF8String:
        +
        + asn1 = SEQUENCE:seq_section
        +
        + [seq_section]
        +
        + field1 = BOOLEAN:TRUE
        + field2 = OID:commonName
        + field3 = UTF8:Third field
        +
        +This example produces an RSAPrivateKey structure, this is the
        +key contained in the file client.pem in all OpenSSL distributions
        +(note: the field names such as 'coeff' are ignored and are present just
        +for clarity):
        +
        + asn1=SEQUENCE:private_key
        + [private_key]
        + version=INTEGER:0
        +
        + n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\
        + D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9
        +
        + e=INTEGER:0x010001
        +
        + d=INTEGER:0x6F05EAD2F27FFAEC84BEC360C4B928FD5F3A9865D0FCAAD291E2A52F4A\
        + F810DC6373278C006A0ABBA27DC8C63BF97F7E666E27C5284D7D3B1FFFE16B7A87B51D
        +
        + p=INTEGER:0xF3929B9435608F8A22C208D86795271D54EBDFB09DDEF539AB083DA912\
        + D4BD57
        +
        + q=INTEGER:0xC50016F89DFF2561347ED1186A46E150E28BF2D0F539A1594BBD7FE467\
        + 46EC4F
        +
        + exp1=INTEGER:0x9E7D4326C924AFC1DEA40B45650134966D6F9DFA3A7F9D698CD4ABEA\
        + 9C0A39B9
        +
        + exp2=INTEGER:0xBA84003BB95355AFB7C50DF140C60513D0BA51D637272E355E397779\
        + E7B2458F
        +
        + coeff=INTEGER:0x30B9E4F2AFA5AC679F920FC83F1F2DF1BAF1779CF989447FABC2F5\
        + 628657053A
        +
        +This example is the corresponding public key in a SubjectPublicKeyInfo
        +structure:
        +
        + # Start with a SEQUENCE
        + asn1=SEQUENCE:pubkeyinfo
        +
        + # pubkeyinfo contains an algorithm identifier and the public key wrapped
        + # in a BIT STRING
        + [pubkeyinfo]
        + algorithm=SEQUENCE:rsa_alg
        + pubkey=BITWRAP,SEQUENCE:rsapubkey
        +
        + # algorithm ID for RSA is just an OID and a NULL
        + [rsa_alg]
        + algorithm=OID:rsaEncryption
        + parameter=NULL
        +
        + # Actual public key: modulus and exponent
        + [rsapubkey]
        + n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\
        + D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9
        +
        + e=INTEGER:0x010001
        +
        +=head1 RETURN VALUES
        +
        +ASN1_generate_nconf() and ASN1_generate_v3() return the encoded
        +data as an B<ASN1_TYPE> structure or B<NULL> if an error occurred.
        +
        +The error codes that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +ASN1_generate_nconf() and ASN1_generate_v3() were added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_ctrl.pod b/vendor/openssl/openssl/doc/crypto/BIO_ctrl.pod
        new file mode 100644
        index 000000000..722e8b8f4
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + 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<ofs> 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<b> close flag to B<flag>. B<flag> 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/vendor/openssl/openssl/doc/crypto/BIO_f_base64.pod b/vendor/openssl/openssl/doc/crypto/BIO_f_base64.pod
        new file mode 100644
        index 000000000..438af3b6b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_f_base64.pod
        @@ -0,0 +1,81 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_f_base64 - base64 BIO filter
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        + #include <openssl/evp.h>
        +
        + 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;
        +
        + 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, 512)) > 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/vendor/openssl/openssl/doc/crypto/BIO_f_buffer.pod b/vendor/openssl/openssl/doc/crypto/BIO_f_buffer.pod
        new file mode 100644
        index 000000000..c0dccf1ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_f_buffer.pod
        @@ -0,0 +1,74 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_f_buffer - buffering BIO
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        +
        + 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<size>. The initial
        +buffer size is DEFAULT_BUFFER_SIZE, currently 4096. 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<num>
        +bytes of B<buf>. If B<num> 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
        +
        +L<BIO(3)|BIO(3)>,
        +L<BIO_reset(3)|BIO_reset(3)>,
        +L<BIO_flush(3)|BIO_flush(3)>,
        +L<BIO_pop(3)|BIO_pop(3)>,
        +L<BIO_ctrl(3)|BIO_ctrl(3)>,
        +L<BIO_int_ctrl(3)|BIO_ctrl(3)>
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_f_cipher.pod b/vendor/openssl/openssl/doc/crypto/BIO_f_cipher.pod
        new file mode 100644
        index 000000000..02439cea9
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        + #include <openssl/evp.h>
        +
        + 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 B<b> to B<cipher> using key B<key>
        +and IV B<iv>. B<enc> 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<must> 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/vendor/openssl/openssl/doc/crypto/BIO_f_md.pod b/vendor/openssl/openssl/doc/crypto/BIO_f_md.pod
        new file mode 100644
        index 000000000..2cc41f89d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_f_md.pod
        @@ -0,0 +1,144 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_f_md, BIO_set_md, BIO_get_md, BIO_get_md_ctx - message digest BIO filter
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        + #include <openssl/evp.h>
        +
        + 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<size> parameter is large enough finishes the
        +digest calculation and returns the digest value. BIO_puts() is
        +not supported.
        +
        +BIO_reset() reinitialises a digest BIO.
        +
        +BIO_set_md() sets the message digest of BIO B<b> to B<md>: 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<mdp>, it is a BIO_ctrl() macro.
        +
        +BIO_get_md_ctx() returns the digest BIOs context into B<mdcp>.
        +
        +=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.
        +
        +Before OpenSSL 1.0.0 the call to BIO_get_md_ctx() would only work if the BIO
        +had been initialized for example by calling BIO_set_md() ). In OpenSSL
        +1.0.0 and later the context is always returned and the BIO is state is set
        +to initialized. This allows applications to initialize the context externally
        +if the standard calls such as BIO_set_md() are not sufficiently flexible.
        +
        +=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/vendor/openssl/openssl/doc/crypto/BIO_f_null.pod b/vendor/openssl/openssl/doc/crypto/BIO_f_null.pod
        new file mode 100644
        index 000000000..b057c1840
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_f_null.pod
        @@ -0,0 +1,32 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_f_null - null filter
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        +
        + 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/vendor/openssl/openssl/doc/crypto/BIO_f_ssl.pod b/vendor/openssl/openssl/doc/crypto/BIO_f_ssl.pod
        new file mode 100644
        index 000000000..bc5861ab3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_f_ssl.pod
        @@ -0,0 +1,322 @@
        +=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 <openssl/bio.h>
        + #include <openssl/ssl.h>
        +
        + 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<b> to B<ssl> using
        +the close flag B<c>.
        +
        +BIO_get_ssl() retrieves the SSL pointer of BIO B<b>, it can then be
        +manipulated using the standard SSL library functions.
        +
        +BIO_set_ssl_mode() sets the SSL BIO mode to B<client>. If B<client>
        +is 1 client mode is set. If B<client> is 0 server mode is set.
        +
        +BIO_set_ssl_renegotiate_bytes() sets the renegotiate byte count
        +to B<num>. When set after every B<num> bytes of I/O (read and write) 
        +the SSL session is automatically renegotiated. B<num> must be at
        +least 512 bytes.
        +
        +BIO_set_ssl_renegotiate_timeout() sets the renegotiate timeout to
        +B<seconds>. 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<ctx> and using
        +client mode if B<client> is non zero.
        +
        +BIO_new_ssl_connect() creates a new BIO chain consisting of an
        +SSL BIO (using B<ctx>) 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<ctx>) and a connect
        +BIO.
        +
        +BIO_ssl_copy_session_id() copies an SSL session id between 
        +BIO chains B<from> and B<to>. 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<bio>. 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_s_connect(3)|BIO_s_connect(3)>.
        +
        + 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/plain\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 BUGS
        +
        +In OpenSSL versions before 1.0.0 the BIO_pop() call was handled incorrectly,
        +the I/O BIO reference count was incorrectly incremented (instead of
        +decremented) and dissociated with the SSL BIO even if the SSL BIO was not
        +explicitly being popped (e.g. a pop higher up the chain). Applications which
        +included workarounds for this bug (e.g. freeing BIOs more than once) should
        +be modified to handle this fix or they may free up an already freed BIO.
        +
        +=head1 SEE ALSO
        +
        +TBA
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_find_type.pod b/vendor/openssl/openssl/doc/crypto/BIO_find_type.pod
        new file mode 100644
        index 000000000..bd3b25619
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_find_type.pod
        @@ -0,0 +1,98 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_find_type, BIO_next - BIO chain traversal
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        +
        + 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<b>. If B<type> is a specific type (such as BIO_TYPE_MEM) then a search
        +is made for a BIO of that type. If B<type> is a general type (such as
        +B<BIO_TYPE_SOURCE_SINK>) 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<BIO_TYPE_*> 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<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<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/vendor/openssl/openssl/doc/crypto/BIO_new.pod b/vendor/openssl/openssl/doc/crypto/BIO_new.pod
        new file mode 100644
        index 000000000..2a245fc8d
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + 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<type>.
        +
        +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<type> 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/vendor/openssl/openssl/doc/crypto/BIO_new_CMS.pod b/vendor/openssl/openssl/doc/crypto/BIO_new_CMS.pod
        new file mode 100644
        index 000000000..9e3a4b7f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_new_CMS.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        + BIO_new_CMS - CMS streaming filter BIO
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
        +
        +=head1 DESCRIPTION
        +
        +BIO_new_CMS() returns a streaming filter BIO chain based on B<cms>. The output
        +of the filter is written to B<out>. Any data written to the chain is
        +automatically translated to a BER format CMS structure of the appropriate type.
        +
        +=head1 NOTES
        +
        +The chain returned by this function behaves like a standard filter BIO. It
        +supports non blocking I/O. Content is processed and streamed on the fly and not
        +all held in memory at once: so it is possible to encode very large structures.
        +After all content has been written through the chain BIO_flush() must be called
        +to finalise the structure.
        +
        +The B<CMS_STREAM> flag must be included in the corresponding B<flags>
        +parameter of the B<cms> creation function.
        +
        +If an application wishes to write additional data to B<out> BIOs should be
        +removed from the chain using BIO_pop() and freed with BIO_free() until B<out>
        +is reached. If no additional data needs to be written BIO_free_all() can be
        +called to free up the whole chain.
        +
        +Any content written through the filter is used verbatim: no canonical
        +translation is performed.
        +
        +It is possible to chain multiple BIOs to, for example, create a triple wrapped
        +signed, enveloped, signed structure. In this case it is the applications
        +responsibility to set the inner content type of any outer CMS_ContentInfo
        +structures.
        +
        +Large numbers of small writes through the chain should be avoided as this will
        +produce an output consisting of lots of OCTET STRING structures. Prepending
        +a BIO_f_buffer() buffering BIO will prevent this.
        +
        +=head1 BUGS
        +
        +There is currently no corresponding inverse BIO: i.e. one which can decode
        +a CMS structure on the fly.
        +
        +=head1 RETURN VALUES
        +
        +BIO_new_CMS() returns a BIO chain when successful or NULL if an error
        +occurred. The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_encrypt(3)|CMS_encrypt(3)>
        +
        +=head1 HISTORY
        +
        +BIO_new_CMS() was added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_push.pod b/vendor/openssl/openssl/doc/crypto/BIO_push.pod
        new file mode 100644
        index 000000000..8af1d3c09
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + BIO *	BIO_push(BIO *b,BIO *append);
        + BIO *	BIO_pop(BIO *b);
        +
        +=head1 DESCRIPTION
        +
        +The BIO_push() function appends the BIO B<append> to B<b>, it returns
        +B<b>.
        +
        +BIO_pop() removes the BIO B<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<md1> and B<md2> are digest BIOs, B<b64> is
        +a base64 BIO and B<f> is a file BIO.
        +
        +If the call:
        +
        + BIO_push(b64, f);
        +
        +is made then the new chain will be B<b64-chain>. After making the calls
        +
        + BIO_push(md2, b64);
        + BIO_push(md1, md2);
        +
        +the new chain is B<md1-md2-b64-f>. Data written to B<md1> will be digested
        +by B<md1> and B<md2>, B<base64> encoded and written to B<f>.
        +
        +It should be noted that reading causes data to pass in the reverse
        +direction, that is data is read from B<f>, base64 B<decoded> and digested
        +by B<md1> and B<md2>. If the call:
        +
        + BIO_pop(md2);
        +
        +The call will return B<b64> and the new chain will be B<md1-b64-f> data can
        +be written to B<md1> as before.
        +
        +=head1 RETURN VALUES
        +
        +BIO_push() returns the end of the chain, B<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/vendor/openssl/openssl/doc/crypto/BIO_read.pod b/vendor/openssl/openssl/doc/crypto/BIO_read.pod
        new file mode 100644
        index 000000000..b34528104
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + 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<len> bytes from BIO B<b> and places
        +the data in B<buf>.
        +
        +BIO_gets() performs the BIOs "gets" operation and places the data
        +in B<buf>. Usually this operation will attempt to read a line of data
        +from the BIO of maximum length B<len>. 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<len> bytes from B<buf> to BIO B<b>.
        +
        +BIO_puts() attempts to write a null terminated string B<buf> to BIO B<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<not> 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<BIO_should_retry(3)|BIO_should_retry(3)> 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<BIO_f_buffer(3)|BIO_f_buffer(3)>
        +to the chain.
        +
        +=head1 SEE ALSO
        +
        +L<BIO_should_retry(3)|BIO_should_retry(3)>
        +
        +TBA
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_s_accept.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_accept.pod
        new file mode 100644
        index 000000000..7b63e4621
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_s_accept.pod
        @@ -0,0 +1,195 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_s_accept, 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 <openssl/bio.h>
        +
        + BIO_METHOD *BIO_s_accept(void);
        +
        + long BIO_set_accept_port(BIO *b, char *name);
        + char *BIO_get_accept_port(BIO *b);
        +
        + BIO *BIO_new_accept(char *host_port);
        +
        + long BIO_set_nbio_accept(BIO *b, int n);
        + long BIO_set_accept_bios(BIO *b, char *bio);
        +
        + long BIO_set_bind_mode(BIO *b, long mode);
        + long BIO_get_bind_mode(BIO *b, long dummy);
        +
        + #define BIO_BIND_NORMAL		0
        + #define BIO_BIND_REUSEADDR_IF_UNUSED	1
        + #define BIO_BIND_REUSEADDR		2
        +
        + int BIO_do_accept(BIO *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_s_fd(3)|BIO_s_fd(3)>
        +
        +BIO_set_accept_port() uses the string B<name> 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<host_port>.
        +
        +BIO_set_nbio_accept() sets the accept socket to blocking mode
        +(the default) if B<n> is 0 or non blocking mode if B<n> 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, or request a retry in non blocking mode.
        +
        +=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<connection> will contain a BIO for the recently
        +established connection and B<accept> 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<accept> 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.
        +
        +If the underlying accept socket is non-blocking and BIO_do_accept() is
        +called to await an incoming connection it is possible for
        +BIO_should_io_special() with the reason BIO_RR_ACCEPT. If this happens
        +then it is an indication that an accept attempt would block: the application
        +should take appropriate action to wait until the underlying socket has
        +accepted a connection and retry the call.
        +
        +BIO_set_accept_port(), BIO_get_accept_port(), BIO_set_nbio_accept(),
        +BIO_set_accept_bios(), BIO_set_bind_mode(), BIO_get_bind_mode() and
        +BIO_do_accept() are macros.
        +
        +=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/vendor/openssl/openssl/doc/crypto/BIO_s_bio.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_bio.pod
        new file mode 100644
        index 000000000..8d0a55a02
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_s_bio.pod
        @@ -0,0 +1,182 @@
        +=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 <openssl/bio.h>
        +
        + 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<b>. After this call no further
        +writes on BIO B<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<b> to B<size>.
        +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<bio1>, B<bio2>
        +with write buffer sizes B<writebuf1> and B<writebuf2>. If either size is
        +zero then the default size is used.  BIO_new_bio_pair() does not check whether
        +B<bio1> or B<bio2> do point to some other BIO, the values are overwritten,
        +BIO_free() is not called.
        +
        +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 RETURN VALUES
        +
        +BIO_new_bio_pair() returns 1 on success, with the new BIOs available in
        +B<bio1> and B<bio2>, or 0 on failure, with NULL pointers stored into the
        +locations for B<bio1> and B<bio2>. Check the error stack for more information.
        +
        +[XXXXX: More return values need to be added here]
        +
        +=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, 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 WARNING
        +
        +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 SEE ALSO
        +
        +L<SSL_set_bio(3)|SSL_set_bio(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
        +L<BIO_should_retry(3)|BIO_should_retry(3)>, L<BIO_read(3)|BIO_read(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_s_connect.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_connect.pod
        new file mode 100644
        index 000000000..bcf7d8dca
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_s_connect.pod
        @@ -0,0 +1,192 @@
        +=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 <openssl/bio.h>
        +
        + BIO_METHOD * BIO_s_connect(void);
        +
        + BIO *BIO_new_connect(char *name);
        +
        + long BIO_set_conn_hostname(BIO *b, char *name);
        + long BIO_set_conn_port(BIO *b, char *port);
        + long BIO_set_conn_ip(BIO *b, char *ip);
        + long BIO_set_conn_int_port(BIO *b, char *port);
        + char *BIO_get_conn_hostname(BIO *b);
        + char *BIO_get_conn_port(BIO *b);
        + char *BIO_get_conn_ip(BIO *b, dummy);
        + long BIO_get_conn_int_port(BIO *b, int port);
        +
        + long BIO_set_nbio(BIO *b, long n);
        +
        + int BIO_do_connect(BIO *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<c> if it is not NULL,
        +it also returns the socket . If B<c> is not NULL it should be of
        +type (int *).
        +
        +BIO_set_conn_hostname() uses the string B<name> 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<port>. B<port> 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<ip> 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<port>. B<port> 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<n>. If B<n> is
        +zero then blocking I/O is set. If B<n> 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_new_connect() combines BIO_new() and BIO_set_conn_hostname() into
        +a single call: that is it creates a new connect BIO with B<name>.
        +
        +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.
        +
        +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() and
        +BIO_do_connect() are macros.
        +
        +=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/vendor/openssl/openssl/doc/crypto/BIO_s_fd.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_fd.pod
        new file mode 100644
        index 000000000..b1de1d101
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + 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<ofs> 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<b> to B<fd> and the close
        +flag to B<c>.
        +
        +BIO_get_fd() places the file descriptor in B<c> if it is not NULL, it also
        +returns the file descriptor. If B<c> is not NULL it should be of type
        +(int *).
        +
        +BIO_new_fd() returns a file descriptor BIO using B<fd> and B<close_flag>.
        +
        +=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<BIO_read(3)|BIO_read(3)> and L<BIO_should_retry(3)|BIO_should_retry(3)>
        +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<BIO_seek(3)|BIO_seek(3)>, L<BIO_tell(3)|BIO_tell(3)>,
        +L<BIO_reset(3)|BIO_reset(3)>, L<BIO_read(3)|BIO_read(3)>,
        +L<BIO_write(3)|BIO_write(3)>, L<BIO_puts(3)|BIO_puts(3)>,
        +L<BIO_gets(3)|BIO_gets(3)>, L<BIO_printf(3)|BIO_printf(3)>,
        +L<BIO_set_close(3)|BIO_set_close(3)>, L<BIO_get_close(3)|BIO_get_close(3)>
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_s_file.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_file.pod
        new file mode 100644
        index 000000000..188aea347
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_s_file.pod
        @@ -0,0 +1,148 @@
        +=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 <openssl/bio.h>
        +
        + 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<ofs> 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<mode> the meaning
        +of B<mode> 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<stream>. 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<fp>. B<flags> 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<offset> 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<b> to use file B<name> 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.
        +
        +On Windows BIO_new_files reserves for the filename argument to be
        +UTF-8 encoded. In other words if you have to make it work in multi-
        +lingual environment, encode file names in UTF-8.
        +
        +=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<BIO_seek(3)|BIO_seek(3)>, L<BIO_tell(3)|BIO_tell(3)>,
        +L<BIO_reset(3)|BIO_reset(3)>, L<BIO_flush(3)|BIO_flush(3)>,
        +L<BIO_read(3)|BIO_read(3)>,
        +L<BIO_write(3)|BIO_write(3)>, L<BIO_puts(3)|BIO_puts(3)>,
        +L<BIO_gets(3)|BIO_gets(3)>, L<BIO_printf(3)|BIO_printf(3)>,
        +L<BIO_set_close(3)|BIO_set_close(3)>, L<BIO_get_close(3)|BIO_get_close(3)>
        diff --git a/vendor/openssl/openssl/doc/crypto/BIO_s_mem.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_mem.pod
        new file mode 100644
        index 000000000..8f85e0dce
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + 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<b> when it is
        +empty. If the B<v> 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<v> is non
        +zero then it will return B<v> 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<v> should be set to a negative value, typically -1.
        +
        +BIO_get_mem_data() sets B<pp> 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<bm> and sets the
        +close flag to B<c>, that is B<c> should be either BIO_CLOSE or BIO_NOCLOSE.
        +It is a macro.
        +
        +BIO_get_mem_ptr() places the underlying BUF_MEM structure in B<pp>. It is
        +a macro.
        +
        +BIO_new_mem_buf() creates a memory BIO using B<len> bytes of data at B<buf>,
        +if B<len> is -1 then the B<buf> is assumed to be null terminated and its
        +length is determined by B<strlen>. 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<not> 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 lot 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/vendor/openssl/openssl/doc/crypto/BIO_s_null.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_null.pod
        new file mode 100644
        index 000000000..e5514f723
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_s_null.pod
        @@ -0,0 +1,37 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_s_null - null data sink
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        +
        + 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/vendor/openssl/openssl/doc/crypto/BIO_s_socket.pod b/vendor/openssl/openssl/doc/crypto/BIO_s_socket.pod
        new file mode 100644
        index 000000000..1c8d3a911
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BIO_s_socket.pod
        @@ -0,0 +1,63 @@
        +=pod
        +
        +=head1 NAME
        +
        +BIO_s_socket, BIO_new_socket - socket BIO
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        +
        + BIO_METHOD *BIO_s_socket(void);
        +
        + long BIO_set_fd(BIO *b, int fd, long close_flag);
        + long BIO_get_fd(BIO *b, int *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<b> to B<fd> and the close
        +flag to B<close_flag>.
        +
        +BIO_get_fd() places the socket in B<c> if it is not NULL, it also
        +returns the socket. If B<c> is not NULL it should be of type (int *).
        +
        +BIO_new_socket() returns a socket BIO using B<sock> and B<close_flag>.
        +
        +=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.
        +
        +BIO_set_fd() and BIO_get_fd() are macros.
        +
        +=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/vendor/openssl/openssl/doc/crypto/BIO_set_callback.pod b/vendor/openssl/openssl/doc/crypto/BIO_set_callback.pod
        new file mode 100644
        index 000000000..475955624
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + #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>.
        +
        +B<oper> 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<oper> or'ed with BIO_CB_RETURN.
        +
        +The meaning of the arguments B<argp>, B<argi> and B<argl> depends on
        +the value of B<oper>, that is the operation being performed.
        +
        +B<retvalue> 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<retvalue> when it has
        +finished processing, unless if specifically wishes to modify the
        +value returned to the application.
        +
        +=head1 CALLBACK OPERATIONS
        +
        +=over 4
        +
        +=item B<BIO_free(b)>
        +
        +callback(b, BIO_CB_FREE, NULL, 0L, 0L, 1L) is called before the
        +free operation.
        +
        +=item B<BIO_read(b, out, outl)>
        +
        +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<BIO_write(b, in, inl)>
        +
        +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<BIO_gets(b, out, outl)>
        +
        +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<BIO_puts(b, in)>
        +
        +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<BIO_ctrl(BIO *b, int cmd, long larg, void *parg)>
        +
        +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/vendor/openssl/openssl/doc/crypto/BIO_should_retry.pod b/vendor/openssl/openssl/doc/crypto/BIO_should_retry.pod
        new file mode 100644
        index 000000000..b6d51f719
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/bio.h>
        +
        + #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_retry_type() returns a mask of the cause of a retry condition
        +consisting of the values B<BIO_FLAGS_READ>, B<BIO_FLAGS_WRITE>,
        +B<BIO_FLAGS_IO_SPECIAL> 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<reason> 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/vendor/openssl/openssl/doc/crypto/BN_BLINDING_new.pod b/vendor/openssl/openssl/doc/crypto/BN_BLINDING_new.pod
        new file mode 100644
        index 000000000..5f51fdb47
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_BLINDING_new.pod
        @@ -0,0 +1,115 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_BLINDING_new, BN_BLINDING_free, BN_BLINDING_update, BN_BLINDING_convert, 
        +BN_BLINDING_invert, BN_BLINDING_convert_ex, BN_BLINDING_invert_ex, 
        +BN_BLINDING_get_thread_id, BN_BLINDING_set_thread_id, BN_BLINDING_get_flags,
        +BN_BLINDING_set_flags, BN_BLINDING_create_param - blinding related BIGNUM
        +functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai,
        +	BIGNUM *mod);
        + void BN_BLINDING_free(BN_BLINDING *b);
        + int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
        + int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
        + int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
        + int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b,
        +	BN_CTX *ctx);
        + int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
        +	BN_CTX *ctx);
        + #ifndef OPENSSL_NO_DEPRECATED
        + unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
        + void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
        + #endif
        + CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
        + unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
        + void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
        + BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
        +	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
        +	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
        +	BN_MONT_CTX *m_ctx);
        +
        +=head1 DESCRIPTION
        +
        +BN_BLINDING_new() allocates a new B<BN_BLINDING> structure and copies
        +the B<A> and B<Ai> values into the newly created B<BN_BLINDING> object.
        +
        +BN_BLINDING_free() frees the B<BN_BLINDING> structure.
        +
        +BN_BLINDING_update() updates the B<BN_BLINDING> parameters by squaring
        +the B<A> and B<Ai> or, after specific number of uses and if the
        +necessary parameters are set, by re-creating the blinding parameters.
        +
        +BN_BLINDING_convert_ex() multiplies B<n> with the blinding factor B<A>.
        +If B<r> is not NULL a copy the inverse blinding factor B<Ai> will be
        +returned in B<r> (this is useful if a B<RSA> object is shared amoung
        +several threads). BN_BLINDING_invert_ex() multiplies B<n> with the
        +inverse blinding factor B<Ai>. If B<r> is not NULL it will be used as
        +the inverse blinding.
        +
        +BN_BLINDING_convert() and BN_BLINDING_invert() are wrapper
        +functions for BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex()
        +with B<r> set to NULL.
        +
        +BN_BLINDING_thread_id() provides access to the B<CRYPTO_THREADID>
        +object within the B<BN_BLINDING> structure. This is to help users
        +provide proper locking if needed for multi-threaded use. The "thread
        +id" object of a newly allocated B<BN_BLINDING> structure is
        +initialised to the thread id in which BN_BLINDING_new() was called.
        +
        +BN_BLINDING_get_flags() returns the BN_BLINDING flags. Currently
        +there are two supported flags: B<BN_BLINDING_NO_UPDATE> and
        +B<BN_BLINDING_NO_RECREATE>. B<BN_BLINDING_NO_UPDATE> inhibits the
        +automatic update of the B<BN_BLINDING> parameters after each use
        +and B<BN_BLINDING_NO_RECREATE> inhibits the automatic re-creation
        +of the B<BN_BLINDING> parameters after a fixed number of uses (currently
        +32). In newly allocated B<BN_BLINDING> objects no flags are set.
        +BN_BLINDING_set_flags() sets the B<BN_BLINDING> parameters flags.
        +
        +BN_BLINDING_create_param() creates new B<BN_BLINDING> parameters
        +using the exponent B<e> and the modulus B<m>. B<bn_mod_exp> and
        +B<m_ctx> can be used to pass special functions for exponentiation
        +(normally BN_mod_exp_mont() and B<BN_MONT_CTX>).
        +
        +=head1 RETURN VALUES
        +
        +BN_BLINDING_new() returns the newly allocated B<BN_BLINDING> structure
        +or NULL in case of an error.
        +
        +BN_BLINDING_update(), BN_BLINDING_convert(), BN_BLINDING_invert(),
        +BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() return 1 on
        +success and 0 if an error occured.
        +
        +BN_BLINDING_thread_id() returns a pointer to the thread id object
        +within a B<BN_BLINDING> object.
        +
        +BN_BLINDING_get_flags() returns the currently set B<BN_BLINDING> flags
        +(a B<unsigned long> value).
        +
        +BN_BLINDING_create_param() returns the newly created B<BN_BLINDING> 
        +parameters or NULL on error.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>
        +
        +=head1 HISTORY
        +
        +BN_BLINDING_thread_id was first introduced in OpenSSL 1.0.0, and it
        +deprecates BN_BLINDING_set_thread_id and BN_BLINDING_get_thread_id.
        +
        +BN_BLINDING_convert_ex, BN_BLINDIND_invert_ex, BN_BLINDING_get_thread_id,
        +BN_BLINDING_set_thread_id, BN_BLINDING_set_flags, BN_BLINDING_get_flags
        +and BN_BLINDING_create_param were first introduced in OpenSSL 0.9.8
        +
        +=head1 AUTHOR
        +
        +Nils Larsch for the OpenSSL project (http://www.openssl.org).
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_CTX_new.pod b/vendor/openssl/openssl/doc/crypto/BN_CTX_new.pod
        new file mode 100644
        index 000000000..ad8d07db8
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_CTX_new.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_CTX_new, BN_CTX_init, BN_CTX_free - allocate and free BN_CTX structures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BN_CTX *BN_CTX_new(void);
        +
        + void BN_CTX_init(BN_CTX *c);
        +
        + void BN_CTX_free(BN_CTX *c);
        +
        +=head1 DESCRIPTION
        +
        +A B<BN_CTX> is a structure that holds B<BIGNUM> temporary variables used by
        +library functions. Since dynamic memory allocation to create B<BIGNUM>s
        +is rather expensive when used in conjunction with repeated subroutine
        +calls, the B<BN_CTX> structure is used.
        +
        +BN_CTX_new() allocates and initializes a B<BN_CTX>
        +structure. BN_CTX_init() initializes an existing uninitialized
        +B<BN_CTX>.
        +
        +BN_CTX_free() frees the components of the B<BN_CTX>, and if it was
        +created by BN_CTX_new(), also the structure itself.
        +If L<BN_CTX_start(3)|BN_CTX_start(3)> has been used on the B<BN_CTX>,
        +L<BN_CTX_end(3)|BN_CTX_end(3)> must be called before the B<BN_CTX>
        +may be freed by BN_CTX_free().
        +
        +
        +=head1 RETURN VALUES
        +
        +BN_CTX_new() returns a pointer to the B<BN_CTX>. If the allocation fails,
        +it returns B<NULL> and sets an error code that can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +BN_CTX_init() and BN_CTX_free() have no return values.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>,
        +L<BN_CTX_start(3)|BN_CTX_start(3)>
        +
        +=head1 HISTORY
        +
        +BN_CTX_new() and BN_CTX_free() are available in all versions on SSLeay
        +and OpenSSL. BN_CTX_init() was added in SSLeay 0.9.1b.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_CTX_start.pod b/vendor/openssl/openssl/doc/crypto/BN_CTX_start.pod
        new file mode 100644
        index 000000000..dfcefe1a8
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_CTX_start.pod
        @@ -0,0 +1,52 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_CTX_start, BN_CTX_get, BN_CTX_end - use temporary BIGNUM variables
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + void BN_CTX_start(BN_CTX *ctx);
        +
        + BIGNUM *BN_CTX_get(BN_CTX *ctx);
        +
        + void BN_CTX_end(BN_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +These functions are used to obtain temporary B<BIGNUM> variables from
        +a B<BN_CTX> (which can been created by using L<BN_CTX_new(3)|BN_CTX_new(3)>)
        +in order to save the overhead of repeatedly creating and
        +freeing B<BIGNUM>s in functions that are called from inside a loop.
        +
        +A function must call BN_CTX_start() first. Then, BN_CTX_get() may be
        +called repeatedly to obtain temporary B<BIGNUM>s. All BN_CTX_get()
        +calls must be made before calling any other functions that use the
        +B<ctx> as an argument.
        +
        +Finally, BN_CTX_end() must be called before returning from the function.
        +When BN_CTX_end() is called, the B<BIGNUM> pointers obtained from
        +BN_CTX_get() become invalid.
        +
        +=head1 RETURN VALUES
        +
        +BN_CTX_start() and BN_CTX_end() return no values.
        +
        +BN_CTX_get() returns a pointer to the B<BIGNUM>, or B<NULL> on error.
        +Once BN_CTX_get() has failed, the subsequent calls will return B<NULL>
        +as well, so it is sufficient to check the return value of the last
        +BN_CTX_get() call. In case of an error, an error code is set, which
        +can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +
        +=head1 SEE ALSO
        +
        +L<BN_CTX_new(3)|BN_CTX_new(3)>
        +
        +=head1 HISTORY
        +
        +BN_CTX_start(), BN_CTX_get() and BN_CTX_end() were added in OpenSSL 0.9.5.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_add.pod b/vendor/openssl/openssl/doc/crypto/BN_add.pod
        new file mode 100644
        index 000000000..88c7a799e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_add.pod
        @@ -0,0 +1,126 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_add, BN_sub, BN_mul, BN_sqr, BN_div, BN_mod, BN_nnmod, BN_mod_add,
        +BN_mod_sub, BN_mod_mul, BN_mod_sqr, BN_exp, BN_mod_exp, BN_gcd -
        +arithmetic operations on BIGNUMs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        +
        + int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        +
        + int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
        +
        + int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
        +
        + int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
        +         BN_CTX *ctx);
        +
        + int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        +
        + int BN_nnmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        +
        + int BN_mod_add(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
        +         BN_CTX *ctx);
        +
        + int BN_mod_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
        +         BN_CTX *ctx);
        +
        + int BN_mod_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
        +         BN_CTX *ctx);
        +
        + int BN_mod_sqr(BIGNUM *r, BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        +
        + int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);
        +
        + int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
        +         const BIGNUM *m, BN_CTX *ctx);
        +
        + int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +BN_add() adds I<a> and I<b> and places the result in I<r> (C<r=a+b>).
        +I<r> may be the same B<BIGNUM> as I<a> or I<b>.
        +
        +BN_sub() subtracts I<b> from I<a> and places the result in I<r> (C<r=a-b>).
        +
        +BN_mul() multiplies I<a> and I<b> and places the result in I<r> (C<r=a*b>).
        +I<r> may be the same B<BIGNUM> as I<a> or I<b>.
        +For multiplication by powers of 2, use L<BN_lshift(3)|BN_lshift(3)>.
        +
        +BN_sqr() takes the square of I<a> and places the result in I<r>
        +(C<r=a^2>). I<r> and I<a> may be the same B<BIGNUM>.
        +This function is faster than BN_mul(r,a,a).
        +
        +BN_div() divides I<a> by I<d> and places the result in I<dv> and the
        +remainder in I<rem> (C<dv=a/d, rem=a%d>). Either of I<dv> and I<rem> may
        +be B<NULL>, in which case the respective value is not returned.
        +The result is rounded towards zero; thus if I<a> is negative, the
        +remainder will be zero or negative.
        +For division by powers of 2, use BN_rshift(3).
        +
        +BN_mod() corresponds to BN_div() with I<dv> set to B<NULL>.
        +
        +BN_nnmod() reduces I<a> modulo I<m> and places the non-negative
        +remainder in I<r>.
        +
        +BN_mod_add() adds I<a> to I<b> modulo I<m> and places the non-negative
        +result in I<r>.
        +
        +BN_mod_sub() subtracts I<b> from I<a> modulo I<m> and places the
        +non-negative result in I<r>.
        +
        +BN_mod_mul() multiplies I<a> by I<b> and finds the non-negative
        +remainder respective to modulus I<m> (C<r=(a*b) mod m>). I<r> may be
        +the same B<BIGNUM> as I<a> or I<b>. For more efficient algorithms for
        +repeated computations using the same modulus, see
        +L<BN_mod_mul_montgomery(3)|BN_mod_mul_montgomery(3)> and
        +L<BN_mod_mul_reciprocal(3)|BN_mod_mul_reciprocal(3)>.
        +
        +BN_mod_sqr() takes the square of I<a> modulo B<m> and places the
        +result in I<r>.
        +
        +BN_exp() raises I<a> to the I<p>-th power and places the result in I<r>
        +(C<r=a^p>). This function is faster than repeated applications of
        +BN_mul().
        +
        +BN_mod_exp() computes I<a> to the I<p>-th power modulo I<m> (C<r=a^p %
        +m>). This function uses less time and space than BN_exp().
        +
        +BN_gcd() computes the greatest common divisor of I<a> and I<b> and
        +places the result in I<r>. I<r> may be the same B<BIGNUM> as I<a> or
        +I<b>.
        +
        +For all functions, I<ctx> is a previously allocated B<BN_CTX> used for
        +temporary variables; see L<BN_CTX_new(3)|BN_CTX_new(3)>.
        +
        +Unless noted otherwise, the result B<BIGNUM> must be different from
        +the arguments.
        +
        +=head1 RETURN VALUES
        +
        +For all functions, 1 is returned for success, 0 on error. The return
        +value should always be checked (e.g., C<if (!BN_add(r,a,b)) goto err;>).
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_CTX_new(3)|BN_CTX_new(3)>,
        +L<BN_add_word(3)|BN_add_word(3)>, L<BN_set_bit(3)|BN_set_bit(3)>
        +
        +=head1 HISTORY
        +
        +BN_add(), BN_sub(), BN_sqr(), BN_div(), BN_mod(), BN_mod_mul(),
        +BN_mod_exp() and BN_gcd() are available in all versions of SSLeay and
        +OpenSSL. The I<ctx> argument to BN_mul() was added in SSLeay
        +0.9.1b. BN_exp() appeared in SSLeay 0.9.0.
        +BN_nnmod(), BN_mod_add(), BN_mod_sub(), and BN_mod_sqr() were added in
        +OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_add_word.pod b/vendor/openssl/openssl/doc/crypto/BN_add_word.pod
        new file mode 100644
        index 000000000..70667d289
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_add_word.pod
        @@ -0,0 +1,61 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_add_word, BN_sub_word, BN_mul_word, BN_div_word, BN_mod_word - arithmetic
        +functions on BIGNUMs with integers
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_add_word(BIGNUM *a, BN_ULONG w);
        +
        + int BN_sub_word(BIGNUM *a, BN_ULONG w);
        +
        + int BN_mul_word(BIGNUM *a, BN_ULONG w);
        +
        + BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
        +
        + BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
        +
        +=head1 DESCRIPTION
        +
        +These functions perform arithmetic operations on BIGNUMs with unsigned
        +integers. They are much more efficient than the normal BIGNUM
        +arithmetic operations.
        +
        +BN_add_word() adds B<w> to B<a> (C<a+=w>).
        +
        +BN_sub_word() subtracts B<w> from B<a> (C<a-=w>).
        +
        +BN_mul_word() multiplies B<a> and B<w> (C<a*=w>).
        +
        +BN_div_word() divides B<a> by B<w> (C<a/=w>) and returns the remainder.
        +
        +BN_mod_word() returns the remainder of B<a> divided by B<w> (C<a%w>).
        +
        +For BN_div_word() and BN_mod_word(), B<w> must not be 0.
        +
        +=head1 RETURN VALUES
        +
        +BN_add_word(), BN_sub_word() and BN_mul_word() return 1 for success, 0
        +on error. The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +BN_mod_word() and BN_div_word() return B<a>%B<w> on success and
        +B<(BN_ULONG)-1> if an error occurred.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>
        +
        +=head1 HISTORY
        +
        +BN_add_word() and BN_mod_word() are available in all versions of
        +SSLeay and OpenSSL. BN_div_word() was added in SSLeay 0.8, and
        +BN_sub_word() and BN_mul_word() in SSLeay 0.9.0.
        +
        +Before 0.9.8a the return value for BN_div_word() and BN_mod_word()
        +in case of an error was 0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_bn2bin.pod b/vendor/openssl/openssl/doc/crypto/BN_bn2bin.pod
        new file mode 100644
        index 000000000..a4b17ca60
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_bn2bin.pod
        @@ -0,0 +1,95 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_bn2bin, BN_bin2bn, BN_bn2hex, BN_bn2dec, BN_hex2bn, BN_dec2bn,
        +BN_print, BN_print_fp, BN_bn2mpi, BN_mpi2bn - format conversions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_bn2bin(const BIGNUM *a, unsigned char *to);
        + BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
        +
        + char *BN_bn2hex(const BIGNUM *a);
        + char *BN_bn2dec(const BIGNUM *a);
        + int BN_hex2bn(BIGNUM **a, const char *str);
        + int BN_dec2bn(BIGNUM **a, const char *str);
        +
        + int BN_print(BIO *fp, const BIGNUM *a);
        + int BN_print_fp(FILE *fp, const BIGNUM *a);
        +
        + int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
        + BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);
        +
        +=head1 DESCRIPTION
        +
        +BN_bn2bin() converts the absolute value of B<a> into big-endian form
        +and stores it at B<to>. B<to> must point to BN_num_bytes(B<a>) bytes of
        +memory.
        +
        +BN_bin2bn() converts the positive integer in big-endian form of length
        +B<len> at B<s> into a B<BIGNUM> and places it in B<ret>. If B<ret> is
        +NULL, a new B<BIGNUM> is created.
        +
        +BN_bn2hex() and BN_bn2dec() return printable strings containing the
        +hexadecimal and decimal encoding of B<a> respectively. For negative
        +numbers, the string is prefaced with a leading '-'. The string must be
        +freed later using OPENSSL_free().
        +
        +BN_hex2bn() converts the string B<str> containing a hexadecimal number
        +to a B<BIGNUM> and stores it in **B<bn>. If *B<bn> is NULL, a new
        +B<BIGNUM> is created. If B<bn> is NULL, it only computes the number's
        +length in hexadecimal digits. If the string starts with '-', the
        +number is negative. BN_dec2bn() is the same using the decimal system.
        +
        +BN_print() and BN_print_fp() write the hexadecimal encoding of B<a>,
        +with a leading '-' for negative numbers, to the B<BIO> or B<FILE>
        +B<fp>.
        +
        +BN_bn2mpi() and BN_mpi2bn() convert B<BIGNUM>s from and to a format
        +that consists of the number's length in bytes represented as a 4-byte
        +big-endian number, and the number itself in big-endian format, where
        +the most significant bit signals a negative number (the representation
        +of numbers with the MSB set is prefixed with null byte).
        +
        +BN_bn2mpi() stores the representation of B<a> at B<to>, where B<to>
        +must be large enough to hold the result. The size can be determined by
        +calling BN_bn2mpi(B<a>, NULL).
        +
        +BN_mpi2bn() converts the B<len> bytes long representation at B<s> to
        +a B<BIGNUM> and stores it at B<ret>, or in a newly allocated B<BIGNUM>
        +if B<ret> is NULL.
        +
        +=head1 RETURN VALUES
        +
        +BN_bn2bin() returns the length of the big-endian number placed at B<to>.
        +BN_bin2bn() returns the B<BIGNUM>, NULL on error.
        +
        +BN_bn2hex() and BN_bn2dec() return a null-terminated string, or NULL
        +on error. BN_hex2bn() and BN_dec2bn() return the number's length in
        +hexadecimal or decimal digits, and 0 on error.
        +
        +BN_print_fp() and BN_print() return 1 on success, 0 on write errors.
        +
        +BN_bn2mpi() returns the length of the representation. BN_mpi2bn()
        +returns the B<BIGNUM>, and NULL on error.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_zero(3)|BN_zero(3)>,
        +L<ASN1_INTEGER_to_BN(3)|ASN1_INTEGER_to_BN(3)>,
        +L<BN_num_bytes(3)|BN_num_bytes(3)>
        +
        +=head1 HISTORY
        +
        +BN_bn2bin(), BN_bin2bn(), BN_print_fp() and BN_print() are available
        +in all versions of SSLeay and OpenSSL.
        +
        +BN_bn2hex(), BN_bn2dec(), BN_hex2bn(), BN_dec2bn(), BN_bn2mpi() and
        +BN_mpi2bn() were added in SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_cmp.pod b/vendor/openssl/openssl/doc/crypto/BN_cmp.pod
        new file mode 100644
        index 000000000..23e9ed0b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_cmp.pod
        @@ -0,0 +1,48 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_cmp, BN_ucmp, BN_is_zero, BN_is_one, BN_is_word, BN_is_odd - BIGNUM comparison and test functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_cmp(BIGNUM *a, BIGNUM *b);
        + int BN_ucmp(BIGNUM *a, BIGNUM *b);
        +
        + int BN_is_zero(BIGNUM *a);
        + int BN_is_one(BIGNUM *a);
        + int BN_is_word(BIGNUM *a, BN_ULONG w);
        + int BN_is_odd(BIGNUM *a);
        +
        +=head1 DESCRIPTION
        +
        +BN_cmp() compares the numbers B<a> and B<b>. BN_ucmp() compares their
        +absolute values.
        +
        +BN_is_zero(), BN_is_one() and BN_is_word() test if B<a> equals 0, 1,
        +or B<w> respectively. BN_is_odd() tests if a is odd.
        +
        +BN_is_zero(), BN_is_one(), BN_is_word() and BN_is_odd() are macros.
        +
        +=head1 RETURN VALUES
        +
        +BN_cmp() returns -1 if B<a> E<lt> B<b>, 0 if B<a> == B<b> and 1 if
        +B<a> E<gt> B<b>. BN_ucmp() is the same using the absolute values
        +of B<a> and B<b>.
        +
        +BN_is_zero(), BN_is_one() BN_is_word() and BN_is_odd() return 1 if
        +the condition is true, 0 otherwise.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>
        +
        +=head1 HISTORY
        +
        +BN_cmp(), BN_ucmp(), BN_is_zero(), BN_is_one() and BN_is_word() are
        +available in all versions of SSLeay and OpenSSL.
        +BN_is_odd() was added in SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_copy.pod b/vendor/openssl/openssl/doc/crypto/BN_copy.pod
        new file mode 100644
        index 000000000..388dd7df2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_copy.pod
        @@ -0,0 +1,34 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_copy, BN_dup - copy BIGNUMs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BIGNUM *BN_copy(BIGNUM *to, const BIGNUM *from);
        +
        + BIGNUM *BN_dup(const BIGNUM *from);
        +
        +=head1 DESCRIPTION
        +
        +BN_copy() copies B<from> to B<to>. BN_dup() creates a new B<BIGNUM>
        +containing the value B<from>.
        +
        +=head1 RETURN VALUES
        +
        +BN_copy() returns B<to> on success, NULL on error. BN_dup() returns
        +the new B<BIGNUM>, and NULL on error. The error codes can be obtained
        +by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +BN_copy() and BN_dup() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_generate_prime.pod b/vendor/openssl/openssl/doc/crypto/BN_generate_prime.pod
        new file mode 100644
        index 000000000..7dccacbc1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_generate_prime.pod
        @@ -0,0 +1,102 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_generate_prime, BN_is_prime, BN_is_prime_fasttest - generate primes and test for primality
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BIGNUM *BN_generate_prime(BIGNUM *ret, int num, int safe, BIGNUM *add,
        +     BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg);
        +
        + int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int, int, 
        +     void *), BN_CTX *ctx, void *cb_arg);
        +
        + int BN_is_prime_fasttest(const BIGNUM *a, int checks,
        +     void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg,
        +     int do_trial_division);
        +
        +=head1 DESCRIPTION
        +
        +BN_generate_prime() generates a pseudo-random prime number of B<num>
        +bits.
        +If B<ret> is not B<NULL>, it will be used to store the number.
        +
        +If B<callback> is not B<NULL>, it is called as follows:
        +
        +=over 4
        +
        +=item *
        +
        +B<callback(0, i, cb_arg)> is called after generating the i-th
        +potential prime number.
        +
        +=item *
        +
        +While the number is being tested for primality, B<callback(1, j,
        +cb_arg)> is called as described below.
        +
        +=item *
        +
        +When a prime has been found, B<callback(2, i, cb_arg)> is called.
        +
        +=back
        +
        +The prime may have to fulfill additional requirements for use in
        +Diffie-Hellman key exchange:
        +
        +If B<add> is not B<NULL>, the prime will fulfill the condition p % B<add>
        +== B<rem> (p % B<add> == 1 if B<rem> == B<NULL>) in order to suit a given
        +generator.
        +
        +If B<safe> is true, it will be a safe prime (i.e. a prime p so
        +that (p-1)/2 is also prime).
        +
        +The PRNG must be seeded prior to calling BN_generate_prime().
        +The prime number generation has a negligible error probability.
        +
        +BN_is_prime() and BN_is_prime_fasttest() test if the number B<a> is
        +prime.  The following tests are performed until one of them shows that
        +B<a> is composite; if B<a> passes all these tests, it is considered
        +prime.
        +
        +BN_is_prime_fasttest(), when called with B<do_trial_division == 1>,
        +first attempts trial division by a number of small primes;
        +if no divisors are found by this test and B<callback> is not B<NULL>,
        +B<callback(1, -1, cb_arg)> is called.
        +If B<do_trial_division == 0>, this test is skipped.
        +
        +Both BN_is_prime() and BN_is_prime_fasttest() perform a Miller-Rabin
        +probabilistic primality test with B<checks> iterations. If
        +B<checks == BN_prime_checks>, a number of iterations is used that
        +yields a false positive rate of at most 2^-80 for random input.
        +
        +If B<callback> is not B<NULL>, B<callback(1, j, cb_arg)> is called
        +after the j-th iteration (j = 0, 1, ...). B<ctx> is a
        +pre-allocated B<BN_CTX> (to save the overhead of allocating and
        +freeing the structure in a loop), or B<NULL>.
        +
        +=head1 RETURN VALUES
        +
        +BN_generate_prime() returns the prime number on success, B<NULL> otherwise.
        +
        +BN_is_prime() returns 0 if the number is composite, 1 if it is
        +prime with an error probability of less than 0.25^B<checks>, and
        +-1 on error.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>
        +
        +=head1 HISTORY
        +
        +The B<cb_arg> arguments to BN_generate_prime() and to BN_is_prime()
        +were added in SSLeay 0.9.0. The B<ret> argument to BN_generate_prime()
        +was added in SSLeay 0.9.1.
        +BN_is_prime_fasttest() was added in OpenSSL 0.9.5.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_mod_inverse.pod b/vendor/openssl/openssl/doc/crypto/BN_mod_inverse.pod
        new file mode 100644
        index 000000000..3ea3975c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_mod_inverse.pod
        @@ -0,0 +1,36 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_mod_inverse - compute inverse modulo n
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n,
        +           BN_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +BN_mod_inverse() computes the inverse of B<a> modulo B<n>
        +places the result in B<r> (C<(a*r)%n==1>). If B<r> is NULL,
        +a new B<BIGNUM> is created.
        +
        +B<ctx> is a previously allocated B<BN_CTX> used for temporary
        +variables. B<r> may be the same B<BIGNUM> as B<a> or B<n>.
        +
        +=head1 RETURN VALUES
        +
        +BN_mod_inverse() returns the B<BIGNUM> containing the inverse, and
        +NULL on error. The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>
        +
        +=head1 HISTORY
        +
        +BN_mod_inverse() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_mod_mul_montgomery.pod b/vendor/openssl/openssl/doc/crypto/BN_mod_mul_montgomery.pod
        new file mode 100644
        index 000000000..6b16351b9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_mod_mul_montgomery.pod
        @@ -0,0 +1,101 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_mod_mul_montgomery, BN_MONT_CTX_new, BN_MONT_CTX_init,
        +BN_MONT_CTX_free, BN_MONT_CTX_set, BN_MONT_CTX_copy,
        +BN_from_montgomery, BN_to_montgomery - Montgomery multiplication
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BN_MONT_CTX *BN_MONT_CTX_new(void);
        + void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
        + void BN_MONT_CTX_free(BN_MONT_CTX *mont);
        +
        + int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
        + BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
        +
        + int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
        +         BN_MONT_CTX *mont, BN_CTX *ctx);
        +
        + int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
        +         BN_CTX *ctx);
        +
        + int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
        +         BN_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +These functions implement Montgomery multiplication. They are used
        +automatically when L<BN_mod_exp(3)|BN_mod_exp(3)> is called with suitable input,
        +but they may be useful when several operations are to be performed
        +using the same modulus.
        +
        +BN_MONT_CTX_new() allocates and initializes a B<BN_MONT_CTX> structure.
        +BN_MONT_CTX_init() initializes an existing uninitialized B<BN_MONT_CTX>.
        +
        +BN_MONT_CTX_set() sets up the I<mont> structure from the modulus I<m>
        +by precomputing its inverse and a value R.
        +
        +BN_MONT_CTX_copy() copies the B<BN_MONT_CTX> I<from> to I<to>.
        +
        +BN_MONT_CTX_free() frees the components of the B<BN_MONT_CTX>, and, if
        +it was created by BN_MONT_CTX_new(), also the structure itself.
        +
        +BN_mod_mul_montgomery() computes Mont(I<a>,I<b>):=I<a>*I<b>*R^-1 and places
        +the result in I<r>.
        +
        +BN_from_montgomery() performs the Montgomery reduction I<r> = I<a>*R^-1.
        +
        +BN_to_montgomery() computes Mont(I<a>,R^2), i.e. I<a>*R.
        +Note that I<a> must be non-negative and smaller than the modulus.
        +
        +For all functions, I<ctx> is a previously allocated B<BN_CTX> used for
        +temporary variables.
        +
        +The B<BN_MONT_CTX> structure is defined as follows:
        +
        + typedef struct bn_mont_ctx_st
        +        {
        +        int ri;         /* number of bits in R */
        +        BIGNUM RR;      /* R^2 (used to convert to Montgomery form) */
        +        BIGNUM N;       /* The modulus */
        +        BIGNUM Ni;      /* R*(1/R mod N) - N*Ni = 1
        +                         * (Ni is only stored for bignum algorithm) */
        +        BN_ULONG n0;    /* least significant word of Ni */
        +        int flags;
        +        } BN_MONT_CTX;
        +
        +BN_to_montgomery() is a macro.
        +
        +=head1 RETURN VALUES
        +
        +BN_MONT_CTX_new() returns the newly allocated B<BN_MONT_CTX>, and NULL
        +on error.
        +
        +BN_MONT_CTX_init() and BN_MONT_CTX_free() have no return values.
        +
        +For the other functions, 1 is returned for success, 0 on error.
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 WARNING
        +
        +The inputs must be reduced modulo B<m>, otherwise the result will be
        +outside the expected range.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>,
        +L<BN_CTX_new(3)|BN_CTX_new(3)>
        +
        +=head1 HISTORY
        +
        +BN_MONT_CTX_new(), BN_MONT_CTX_free(), BN_MONT_CTX_set(),
        +BN_mod_mul_montgomery(), BN_from_montgomery() and BN_to_montgomery()
        +are available in all versions of SSLeay and OpenSSL.
        +
        +BN_MONT_CTX_init() and BN_MONT_CTX_copy() were added in SSLeay 0.9.1b.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_mod_mul_reciprocal.pod b/vendor/openssl/openssl/doc/crypto/BN_mod_mul_reciprocal.pod
        new file mode 100644
        index 000000000..74a216ddc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_mod_mul_reciprocal.pod
        @@ -0,0 +1,81 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_mod_mul_reciprocal,  BN_div_recp, BN_RECP_CTX_new, BN_RECP_CTX_init,
        +BN_RECP_CTX_free, BN_RECP_CTX_set - modular multiplication using
        +reciprocal
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BN_RECP_CTX *BN_RECP_CTX_new(void);
        + void BN_RECP_CTX_init(BN_RECP_CTX *recp);
        + void BN_RECP_CTX_free(BN_RECP_CTX *recp);
        +
        + int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
        +
        + int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BN_RECP_CTX *recp,
        +        BN_CTX *ctx);
        +
        + int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
        +        BN_RECP_CTX *recp, BN_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +BN_mod_mul_reciprocal() can be used to perform an efficient
        +L<BN_mod_mul(3)|BN_mod_mul(3)> operation when the operation will be performed
        +repeatedly with the same modulus. It computes B<r>=(B<a>*B<b>)%B<m>
        +using B<recp>=1/B<m>, which is set as described below.  B<ctx> is a
        +previously allocated B<BN_CTX> used for temporary variables.
        +
        +BN_RECP_CTX_new() allocates and initializes a B<BN_RECP> structure.
        +BN_RECP_CTX_init() initializes an existing uninitialized B<BN_RECP>.
        +
        +BN_RECP_CTX_free() frees the components of the B<BN_RECP>, and, if it
        +was created by BN_RECP_CTX_new(), also the structure itself.
        +
        +BN_RECP_CTX_set() stores B<m> in B<recp> and sets it up for computing
        +1/B<m> and shifting it left by BN_num_bits(B<m>)+1 to make it an
        +integer. The result and the number of bits it was shifted left will
        +later be stored in B<recp>.
        +
        +BN_div_recp() divides B<a> by B<m> using B<recp>. It places the quotient
        +in B<dv> and the remainder in B<rem>.
        +
        +The B<BN_RECP_CTX> structure is defined as follows:
        +
        + typedef struct bn_recp_ctx_st
        +	{
        +	BIGNUM N;	/* the divisor */
        +	BIGNUM Nr;	/* the reciprocal */
        +	int num_bits;
        +	int shift;
        +	int flags;
        +	} BN_RECP_CTX;
        +
        +It cannot be shared between threads.
        +
        +=head1 RETURN VALUES
        +
        +BN_RECP_CTX_new() returns the newly allocated B<BN_RECP_CTX>, and NULL
        +on error.
        +
        +BN_RECP_CTX_init() and BN_RECP_CTX_free() have no return values.
        +
        +For the other functions, 1 is returned for success, 0 on error.
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>,
        +L<BN_CTX_new(3)|BN_CTX_new(3)>
        +
        +=head1 HISTORY
        +
        +B<BN_RECP_CTX> was added in SSLeay 0.9.0. Before that, the function
        +BN_reciprocal() was used instead, and the BN_mod_mul_reciprocal()
        +arguments were different.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_new.pod b/vendor/openssl/openssl/doc/crypto/BN_new.pod
        new file mode 100644
        index 000000000..ab7a105e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_new.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_new, BN_init, BN_clear, BN_free, BN_clear_free - allocate and free BIGNUMs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BIGNUM *BN_new(void);
        +
        + void BN_init(BIGNUM *);
        +
        + void BN_clear(BIGNUM *a);
        +
        + void BN_free(BIGNUM *a);
        +
        + void BN_clear_free(BIGNUM *a);
        +
        +=head1 DESCRIPTION
        +
        +BN_new() allocates and initializes a B<BIGNUM> structure. BN_init()
        +initializes an existing uninitialized B<BIGNUM>.
        +
        +BN_clear() is used to destroy sensitive data such as keys when they
        +are no longer needed. It erases the memory used by B<a> and sets it
        +to the value 0.
        +
        +BN_free() frees the components of the B<BIGNUM>, and if it was created
        +by BN_new(), also the structure itself. BN_clear_free() additionally
        +overwrites the data before the memory is returned to the system.
        +
        +=head1 RETURN VALUES
        +
        +BN_new() returns a pointer to the B<BIGNUM>. If the allocation fails,
        +it returns B<NULL> and sets an error code that can be obtained
        +by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +BN_init(), BN_clear(), BN_free() and BN_clear_free() have no return
        +values.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +BN_new(), BN_clear(), BN_free() and BN_clear_free() are available in
        +all versions on SSLeay and OpenSSL.  BN_init() was added in SSLeay
        +0.9.1b.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_num_bytes.pod b/vendor/openssl/openssl/doc/crypto/BN_num_bytes.pod
        new file mode 100644
        index 000000000..a6a2e3f81
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_num_bytes.pod
        @@ -0,0 +1,57 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_num_bits, BN_num_bytes, BN_num_bits_word - get BIGNUM size
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_num_bytes(const BIGNUM *a);
        +
        + int BN_num_bits(const BIGNUM *a);
        +
        + int BN_num_bits_word(BN_ULONG w);
        +
        +=head1 DESCRIPTION
        +
        +BN_num_bytes() returns the size of a B<BIGNUM> in bytes.
        +
        +BN_num_bits_word() returns the number of significant bits in a word.
        +If we take 0x00000432 as an example, it returns 11, not 16, not 32.
        +Basically, except for a zero, it returns I<floor(log2(w))+1>.
        +
        +BN_num_bits() returns the number of significant bits in a B<BIGNUM>,
        +following the same principle as BN_num_bits_word().
        +
        +BN_num_bytes() is a macro.
        +
        +=head1 RETURN VALUES
        +
        +The size.
        +
        +=head1 NOTES
        +
        +Some have tried using BN_num_bits() on individual numbers in RSA keys,
        +DH keys and DSA keys, and found that they don't always come up with
        +the number of bits they expected (something like 512, 1024, 2048,
        +...).  This is because generating a number with some specific number
        +of bits doesn't always set the highest bits, thereby making the number
        +of I<significant> bits a little lower.  If you want to know the "key
        +size" of such a key, either use functions like RSA_size(), DH_size()
        +and DSA_size(), or use BN_num_bytes() and multiply with 8 (although
        +there's no real guarantee that will match the "key size", just a lot
        +more probability).
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<DH_size(3)|DH_size(3)>, L<DSA_size(3)|DSA_size(3)>,
        +L<RSA_size(3)|RSA_size(3)>
        +
        +=head1 HISTORY
        +
        +BN_num_bytes(), BN_num_bits() and BN_num_bits_word() are available in
        +all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_rand.pod b/vendor/openssl/openssl/doc/crypto/BN_rand.pod
        new file mode 100644
        index 000000000..81f93c2eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_rand.pod
        @@ -0,0 +1,58 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_rand, BN_pseudo_rand - generate pseudo-random number
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
        +
        + int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
        +
        + int BN_rand_range(BIGNUM *rnd, BIGNUM *range);
        +
        + int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
        +
        +=head1 DESCRIPTION
        +
        +BN_rand() generates a cryptographically strong pseudo-random number of
        +B<bits> bits in length and stores it in B<rnd>. If B<top> is -1, the
        +most significant bit of the random number can be zero. If B<top> is 0,
        +it is set to 1, and if B<top> is 1, the two most significant bits of
        +the number will be set to 1, so that the product of two such random
        +numbers will always have 2*B<bits> length.  If B<bottom> is true, the
        +number will be odd.
        +
        +BN_pseudo_rand() does the same, but pseudo-random numbers generated by
        +this function are not necessarily unpredictable. They can be used for
        +non-cryptographic purposes and for certain purposes in cryptographic
        +protocols, but usually not for key generation etc.
        +
        +BN_rand_range() generates a cryptographically strong pseudo-random
        +number B<rnd> in the range 0 <lt>= B<rnd> E<lt> B<range>.
        +BN_pseudo_rand_range() does the same, but is based on BN_pseudo_rand(),
        +and hence numbers generated by it are not necessarily unpredictable.
        +
        +The PRNG must be seeded prior to calling BN_rand() or BN_rand_range().
        +
        +=head1 RETURN VALUES
        +
        +The functions return 1 on success, 0 on error.
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
        +L<RAND_add(3)|RAND_add(3)>, L<RAND_bytes(3)|RAND_bytes(3)>
        +
        +=head1 HISTORY
        +
        +BN_rand() is available in all versions of SSLeay and OpenSSL.
        +BN_pseudo_rand() was added in OpenSSL 0.9.5. The B<top> == -1 case
        +and the function BN_rand_range() were added in OpenSSL 0.9.6a.
        +BN_pseudo_rand_range() was added in OpenSSL 0.9.6c.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_set_bit.pod b/vendor/openssl/openssl/doc/crypto/BN_set_bit.pod
        new file mode 100644
        index 000000000..b7c47b9b0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_set_bit.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_set_bit, BN_clear_bit, BN_is_bit_set, BN_mask_bits, BN_lshift,
        +BN_lshift1, BN_rshift, BN_rshift1 - bit operations on BIGNUMs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_set_bit(BIGNUM *a, int n);
        + int BN_clear_bit(BIGNUM *a, int n);
        +
        + int BN_is_bit_set(const BIGNUM *a, int n);
        +
        + int BN_mask_bits(BIGNUM *a, int n);
        +
        + int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
        + int BN_lshift1(BIGNUM *r, BIGNUM *a);
        +
        + int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
        + int BN_rshift1(BIGNUM *r, BIGNUM *a);
        +
        +=head1 DESCRIPTION
        +
        +BN_set_bit() sets bit B<n> in B<a> to 1 (C<a|=(1E<lt>E<lt>n)>). The
        +number is expanded if necessary.
        +
        +BN_clear_bit() sets bit B<n> in B<a> to 0 (C<a&=~(1E<lt>E<lt>n)>). An
        +error occurs if B<a> is shorter than B<n> bits.
        +
        +BN_is_bit_set() tests if bit B<n> in B<a> is set.
        +
        +BN_mask_bits() truncates B<a> to an B<n> bit number
        +(C<a&=~((~0)E<gt>E<gt>n)>).  An error occurs if B<a> already is
        +shorter than B<n> bits.
        +
        +BN_lshift() shifts B<a> left by B<n> bits and places the result in
        +B<r> (C<r=a*2^n>). BN_lshift1() shifts B<a> left by one and places
        +the result in B<r> (C<r=2*a>).
        +
        +BN_rshift() shifts B<a> right by B<n> bits and places the result in
        +B<r> (C<r=a/2^n>). BN_rshift1() shifts B<a> right by one and places
        +the result in B<r> (C<r=a/2>).
        +
        +For the shift functions, B<r> and B<a> may be the same variable.
        +
        +=head1 RETURN VALUES
        +
        +BN_is_bit_set() returns 1 if the bit is set, 0 otherwise.
        +
        +All other functions return 1 for success, 0 on error. The error codes
        +can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<BN_num_bytes(3)|BN_num_bytes(3)>, L<BN_add(3)|BN_add(3)>
        +
        +=head1 HISTORY
        +
        +BN_set_bit(), BN_clear_bit(), BN_is_bit_set(), BN_mask_bits(),
        +BN_lshift(), BN_lshift1(), BN_rshift(), and BN_rshift1() are available
        +in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_swap.pod b/vendor/openssl/openssl/doc/crypto/BN_swap.pod
        new file mode 100644
        index 000000000..79efaa144
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_swap.pod
        @@ -0,0 +1,23 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_swap - exchange BIGNUMs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + void BN_swap(BIGNUM *a, BIGNUM *b);
        +
        +=head1 DESCRIPTION
        +
        +BN_swap() exchanges the values of I<a> and I<b>.
        +
        +L<bn(3)|bn(3)>
        +
        +=head1 HISTORY
        +
        +BN_swap was added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/BN_zero.pod b/vendor/openssl/openssl/doc/crypto/BN_zero.pod
        new file mode 100644
        index 000000000..b555ec398
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/BN_zero.pod
        @@ -0,0 +1,59 @@
        +=pod
        +
        +=head1 NAME
        +
        +BN_zero, BN_one, BN_value_one, BN_set_word, BN_get_word - BIGNUM assignment
        +operations
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + int BN_zero(BIGNUM *a);
        + int BN_one(BIGNUM *a);
        +
        + const BIGNUM *BN_value_one(void);
        +
        + int BN_set_word(BIGNUM *a, unsigned long w);
        + unsigned long BN_get_word(BIGNUM *a);
        +
        +=head1 DESCRIPTION
        +
        +BN_zero(), BN_one() and BN_set_word() set B<a> to the values 0, 1 and
        +B<w> respectively.  BN_zero() and BN_one() are macros.
        +
        +BN_value_one() returns a B<BIGNUM> constant of value 1. This constant
        +is useful for use in comparisons and assignment.
        +
        +BN_get_word() returns B<a>, if it can be represented as an unsigned
        +long.
        +
        +=head1 RETURN VALUES
        +
        +BN_get_word() returns the value B<a>, and 0xffffffffL if B<a> cannot
        +be represented as an unsigned long.
        +
        +BN_zero(), BN_one() and BN_set_word() return 1 on success, 0 otherwise.
        +BN_value_one() returns the constant.
        +
        +=head1 BUGS
        +
        +Someone might change the constant.
        +
        +If a B<BIGNUM> is equal to 0xffffffffL it can be represented as an
        +unsigned long but this value is also returned on error.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<BN_bn2bin(3)|BN_bn2bin(3)>
        +
        +=head1 HISTORY
        +
        +BN_zero(), BN_one() and BN_set_word() are available in all versions of
        +SSLeay and OpenSSL. BN_value_one() and BN_get_word() were added in
        +SSLeay 0.8.
        +
        +BN_value_one() was changed to return a true const BIGNUM * in OpenSSL
        +0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_add0_cert.pod b/vendor/openssl/openssl/doc/crypto/CMS_add0_cert.pod
        new file mode 100644
        index 000000000..9c13f488f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_add0_cert.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_add0_cert, CMS_add1_cert, CMS_get1_certs, CMS_add0_crl, CMS_get1_crls, - CMS certificate and CRL utility functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
        + int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
        + STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
        +
        + int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
        + int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
        + STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
        +
        +
        +=head1 DESCRIPTION
        +
        +CMS_add0_cert() and CMS_add1_cert() add certificate B<cert> to B<cms>.
        +must be of type signed data or enveloped data. 
        +
        +CMS_get1_certs() returns all certificates in B<cms>.
        +
        +CMS_add0_crl() and CMS_add1_crl() add CRL B<crl> to B<cms>. CMS_get1_crls()
        +returns any CRLs in B<cms>.
        +
        +=head1 NOTES
        +
        +The CMS_ContentInfo structure B<cms> must be of type signed data or enveloped
        +data or an error will be returned.
        +
        +For signed data certificates and CRLs are added to the B<certificates> and
        +B<crls> fields of SignedData structure. For enveloped data they are added to
        +B<OriginatorInfo>.
        +
        +As the B<0> implies CMS_add0_cert() adds B<cert> internally to B<cms> and it
        +must not be freed up after the call as opposed to CMS_add1_cert() where B<cert>
        +must be freed up.
        +
        +The same certificate or CRL must not be added to the same cms structure more
        +than once.
        +
        +=head1 RETURN VALUES
        +
        +CMS_add0_cert(), CMS_add1_cert() and CMS_add0_crl() and CMS_add1_crl() return
        +1 for success and 0 for failure. 
        +
        +CMS_get1_certs() and CMS_get1_crls() return the STACK of certificates or CRLs
        +or NULL if there are none or an error occurs. The only error which will occur
        +in practice is if the B<cms> type is invalid.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_encrypt(3)|CMS_encrypt(3)>
        +
        +=head1 HISTORY
        +
        +CMS_add0_cert(), CMS_add1_cert(), CMS_get1_certs(), CMS_add0_crl()
        +and CMS_get1_crls() were all first added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_add1_recipient_cert.pod b/vendor/openssl/openssl/doc/crypto/CMS_add1_recipient_cert.pod
        new file mode 100644
        index 000000000..d7d8e2532
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_add1_recipient_cert.pod
        @@ -0,0 +1,62 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_add1_recipient_cert, CMS_add0_recipient_key - add recipients to a CMS enveloped data structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags);
        +
        + CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, unsigned char *key, size_t keylen, unsigned char *id, size_t idlen, ASN1_GENERALIZEDTIME *date, ASN1_OBJECT *otherTypeId, ASN1_TYPE *otherType);
        +
        +=head1 DESCRIPTION
        +
        +CMS_add1_recipient_cert() adds recipient B<recip> to CMS_ContentInfo enveloped
        +data structure B<cms> as a KeyTransRecipientInfo structure.
        +
        +CMS_add0_recipient_key() adds symmetric key B<key> of length B<keylen> using
        +wrapping algorithm B<nid>, identifier B<id> of length B<idlen> and optional
        +values B<date>, B<otherTypeId> and B<otherType> to CMS_ContentInfo enveloped
        +data structure B<cms> as a KEKRecipientInfo structure.
        +
        +The CMS_ContentInfo structure should be obtained from an initial call to
        +CMS_encrypt() with the flag B<CMS_PARTIAL> set.
        +
        +=head1 NOTES
        +
        +The main purpose of this function is to provide finer control over a CMS
        +enveloped data structure where the simpler CMS_encrypt() function defaults are
        +not appropriate. For example if one or more KEKRecipientInfo structures
        +need to be added. New attributes can also be added using the returned
        +CMS_RecipientInfo structure and the CMS attribute utility functions.
        +
        +OpenSSL will by default identify recipient certificates using issuer name
        +and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
        +identifier value instead. An error occurs if all recipient certificates do not
        +have a subject key identifier extension.
        +
        +Currently only AES based key wrapping algorithms are supported for B<nid>,
        +specifically: NID_id_aes128_wrap, NID_id_aes192_wrap and NID_id_aes256_wrap.
        +If B<nid> is set to B<NID_undef> then an AES wrap algorithm will be used
        +consistent with B<keylen>.
        +
        +=head1 RETURN VALUES
        +
        +CMS_add1_recipient_cert() and CMS_add0_recipient_key() return an internal
        +pointer to the CMS_RecipientInfo structure just added or NULL if an error
        +occurs.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_decrypt(3)|CMS_decrypt(3)>,
        +L<CMS_final(3)|CMS_final(3)>,
        +
        +=head1 HISTORY
        +
        +CMS_add1_recipient_cert() and CMS_add0_recipient_key() were added to OpenSSL
        +0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_compress.pod b/vendor/openssl/openssl/doc/crypto/CMS_compress.pod
        new file mode 100644
        index 000000000..0a0715271
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_compress.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +CMS_compress - create a CMS CompressedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_compress() creates and returns a CMS CompressedData structure. B<comp_nid>
        +is the compression algorithm to use or B<NID_undef> to use the default
        +algorithm (zlib compression). B<in> is the content to be compressed.
        +B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +The only currently supported compression algorithm is zlib using the NID
        +NID_zlib_compression.
        +
        +If zlib support is not compiled into OpenSSL then CMS_compress() will return
        +an error.
        +
        +If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are
        +prepended to the data.
        +
        +Normally the supplied content is translated into MIME canonical format (as
        +required by the S/MIME specifications) if B<CMS_BINARY> is set no translation
        +occurs. This option should be used if the supplied data is in binary format
        +otherwise the translation will corrupt it. If B<CMS_BINARY> is set then
        +B<CMS_TEXT> is ignored.
        +
        +If the B<CMS_STREAM> flag is set a partial B<CMS_ContentInfo> structure is
        +returned suitable for streaming I/O: no data is read from the BIO B<in>.
        +
        +The compressed data is included in the CMS_ContentInfo structure, unless
        +B<CMS_DETACHED> is set in which case it is omitted. This is rarely used in
        +practice and is not supported by SMIME_write_CMS().
        +
        +=head1 NOTES
        +
        +If the flag B<CMS_STREAM> is set the returned B<CMS_ContentInfo> structure is
        +B<not> complete and outputting its contents via a function that does not
        +properly finalize the B<CMS_ContentInfo> structure will give unpredictable
        +results.
        +
        +Several functions including SMIME_write_CMS(), i2d_CMS_bio_stream(),
        +PEM_write_bio_CMS_stream() finalize the structure. Alternatively finalization
        +can be performed by obtaining the streaming ASN1 B<BIO> directly using
        +BIO_new_CMS().
        +
        +Additional compression parameters such as the zlib compression level cannot
        +currently be set.
        +
        +=head1 RETURN VALUES
        +
        +CMS_compress() returns either a CMS_ContentInfo structure or NULL if an error
        +occurred. The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_uncompress(3)|CMS_uncompress(3)>
        +
        +=head1 HISTORY
        +
        +CMS_compress() was added to OpenSSL 0.9.8
        +The B<CMS_STREAM> flag was first supported in OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_decrypt.pod b/vendor/openssl/openssl/doc/crypto/CMS_decrypt.pod
        new file mode 100644
        index 000000000..d857e4f93
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_decrypt.pod
        @@ -0,0 +1,65 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_decrypt - decrypt content from a CMS envelopedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, BIO *out, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_decrypt() extracts and decrypts the content from a CMS EnvelopedData
        +structure. B<pkey> is the private key of the recipient, B<cert> is the
        +recipient's certificate, B<out> is a BIO to write the content to and
        +B<flags> is an optional set of flags.
        +
        +The B<dcont> parameter is used in the rare case where the encrypted content
        +is detached. It will normally be set to NULL.
        +
        +=head1 NOTES
        +
        +OpenSSL_add_all_algorithms() (or equivalent) should be called before using this
        +function or errors about unknown algorithms will occur.
        +
        +Although the recipients certificate is not needed to decrypt the data it is
        +needed to locate the appropriate (of possible several) recipients in the CMS
        +structure. If B<cert> is set to NULL all possible recipients are tried.
        +
        +It is possible to determine the correct recipient key by other means (for
        +example looking them up in a database) and setting them in the CMS structure
        +in advance using the CMS utility functions such as CMS_set1_pkey(). In this
        +case both B<cert> and B<pkey> should be set to NULL.
        +
        +To process KEKRecipientInfo types CMS_set1_key() or CMS_RecipientInfo_set0_key()
        +and CMS_ReceipientInfo_decrypt() should be called before CMS_decrypt() and
        +B<cert> and B<pkey> set to NULL.
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
        +from the content. If the content is not of type B<text/plain> then an error is
        +returned.
        +
        +=head1 RETURN VALUES
        +
        +CMS_decrypt() returns either 1 for success or 0 for failure.
        +The error can be obtained from ERR_get_error(3)
        +
        +=head1 BUGS
        +
        +The lack of single pass processing and the need to hold all data in memory as
        +mentioned in CMS_verify() also applies to CMS_decrypt().
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
        +
        +=head1 HISTORY
        +
        +CMS_decrypt() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_encrypt.pod b/vendor/openssl/openssl/doc/crypto/CMS_encrypt.pod
        new file mode 100644
        index 000000000..1ee5b275e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_encrypt.pod
        @@ -0,0 +1,96 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_encrypt - create a CMS envelopedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_encrypt() creates and returns a CMS EnvelopedData structure. B<certs>
        +is a list of recipient certificates. B<in> is the content to be encrypted.
        +B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +Only certificates carrying RSA keys are supported so the recipient certificates
        +supplied to this function must all contain RSA public keys, though they do not
        +have to be signed using the RSA algorithm.
        +
        +EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use
        +because most clients will support it.
        +
        +The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
        +its parameters. 
        +
        +Many browsers implement a "sign and encrypt" option which is simply an S/MIME
        +envelopedData containing an S/MIME signed message. This can be readily produced
        +by storing the S/MIME signed message in a memory BIO and passing it to
        +CMS_encrypt().
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are
        +prepended to the data.
        +
        +Normally the supplied content is translated into MIME canonical format (as
        +required by the S/MIME specifications) if B<CMS_BINARY> is set no translation
        +occurs. This option should be used if the supplied data is in binary format
        +otherwise the translation will corrupt it. If B<CMS_BINARY> is set then
        +B<CMS_TEXT> is ignored.
        +
        +OpenSSL will by default identify recipient certificates using issuer name
        +and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
        +identifier value instead. An error occurs if all recipient certificates do not
        +have a subject key identifier extension.
        +
        +If the B<CMS_STREAM> flag is set a partial B<CMS_ContentInfo> structure is
        +returned suitable for streaming I/O: no data is read from the BIO B<in>.
        +
        +If the B<CMS_PARTIAL> flag is set a partial B<CMS_ContentInfo> structure is
        +returned to which additional recipients and attributes can be added before
        +finalization.
        +
        +The data being encrypted is included in the CMS_ContentInfo structure, unless
        +B<CMS_DETACHED> is set in which case it is omitted. This is rarely used in
        +practice and is not supported by SMIME_write_CMS().
        +
        +=head1 NOTES
        +
        +If the flag B<CMS_STREAM> is set the returned B<CMS_ContentInfo> structure is
        +B<not> complete and outputting its contents via a function that does not
        +properly finalize the B<CMS_ContentInfo> structure will give unpredictable
        +results.
        +
        +Several functions including SMIME_write_CMS(), i2d_CMS_bio_stream(),
        +PEM_write_bio_CMS_stream() finalize the structure. Alternatively finalization
        +can be performed by obtaining the streaming ASN1 B<BIO> directly using
        +BIO_new_CMS().
        +
        +The recipients specified in B<certs> use a CMS KeyTransRecipientInfo info
        +structure. KEKRecipientInfo is also supported using the flag B<CMS_PARTIAL>
        +and CMS_add0_recipient_key().
        +
        +The parameter B<certs> may be NULL if B<CMS_PARTIAL> is set and recipients
        +added later using CMS_add1_recipient_cert() or CMS_add0_recipient_key().
        +
        +=head1 RETURN VALUES
        +
        +CMS_encrypt() returns either a CMS_ContentInfo structure or NULL if an error
        +occurred. The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_decrypt(3)|CMS_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +CMS_decrypt() was added to OpenSSL 0.9.8
        +The B<CMS_STREAM> flag was first supported in OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_final.pod b/vendor/openssl/openssl/doc/crypto/CMS_final.pod
        new file mode 100644
        index 000000000..36cf96b8a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_final.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_final - finalise a CMS_ContentInfo structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_final() finalises the structure B<cms>. It's purpose is to perform any
        +operations necessary on B<cms> (digest computation for example) and set the
        +appropriate fields. The parameter B<data> contains the content to be 
        +processed. The B<dcont> parameter contains a BIO to write content to after
        +processing: this is only used with detached data and will usually be set to
        +NULL.
        +
        +=head1 NOTES
        +
        +This function will normally be called when the B<CMS_PARTIAL> flag is used. It
        +should only be used when streaming is not performed because the streaming
        +I/O functions perform finalisation operations internally.
        +
        +=head1 RETURN VALUES
        +
        +CMS_final() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_encrypt(3)|CMS_encrypt(3)>
        +
        +=head1 HISTORY
        +
        +CMS_final() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_get0_RecipientInfos.pod b/vendor/openssl/openssl/doc/crypto/CMS_get0_RecipientInfos.pod
        new file mode 100644
        index 000000000..e0355423e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_get0_RecipientInfos.pod
        @@ -0,0 +1,106 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_get0_RecipientInfos, CMS_RecipientInfo_type, CMS_RecipientInfo_ktri_get0_signer_id,CMS_RecipientInfo_ktri_cert_cmp, CMS_RecipientInfo_set0_pkey, CMS_RecipientInfo_kekri_get0_id, CMS_RecipientInfo_kekri_id_cmp, CMS_RecipientInfo_set0_key, CMS_RecipientInfo_decrypt - CMS envelopedData RecipientInfo routines
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
        + int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
        +
        + int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno);
        + int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
        + int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
        +
        + int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, ASN1_OBJECT **potherid, ASN1_TYPE **pothertype);
        + int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, const unsigned char *id, size_t idlen);
        + int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, size_t keylen);
        +
        + int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
        +
        +=head1 DESCRIPTION
        +
        +The function CMS_get0_RecipientInfos() returns all the CMS_RecipientInfo
        +structures associated with a CMS EnvelopedData structure.
        +
        +CMS_RecipientInfo_type() returns the type of CMS_RecipientInfo structure B<ri>.
        +It will currently return CMS_RECIPINFO_TRANS, CMS_RECIPINFO_AGREE,
        +CMS_RECIPINFO_KEK, CMS_RECIPINFO_PASS, or CMS_RECIPINFO_OTHER.
        +
        +CMS_RecipientInfo_ktri_get0_signer_id() retrieves the certificate recipient
        +identifier associated with a specific CMS_RecipientInfo structure B<ri>, which
        +must be of type CMS_RECIPINFO_TRANS. Either the keyidentifier will be set in
        +B<keyid> or B<both> issuer name and serial number in B<issuer> and B<sno>. 
        +
        +CMS_RecipientInfo_ktri_cert_cmp() compares the certificate B<cert> against the
        +CMS_RecipientInfo structure B<ri>, which must be of type CMS_RECIPINFO_TRANS.
        +It returns zero if the comparison is successful and non zero if not.
        +
        +CMS_RecipientInfo_set0_pkey() associates the private key B<pkey> with
        +the CMS_RecipientInfo structure B<ri>, which must be of type
        +CMS_RECIPINFO_TRANS.
        +
        +CMS_RecipientInfo_kekri_get0_id() retrieves the key information from the
        +CMS_RecipientInfo structure B<ri> which must be of type CMS_RECIPINFO_KEK.  Any
        +of the remaining parameters can be NULL if the application is not interested in
        +the value of a field. Where a field is optional and absent NULL will be written
        +to the corresponding parameter. The keyEncryptionAlgorithm field is written to
        +B<palg>, the B<keyIdentifier> field is written to B<pid>, the B<date> field if
        +present is written to B<pdate>, if the B<other> field is present the components
        +B<keyAttrId> and B<keyAttr> are written to parameters B<potherid> and
        +B<pothertype>.
        +
        +CMS_RecipientInfo_kekri_id_cmp() compares the ID in the B<id> and B<idlen>
        +parameters against the B<keyIdentifier> CMS_RecipientInfo structure B<ri>,
        +which must be of type CMS_RECIPINFO_KEK.  It returns zero if the comparison is
        +successful and non zero if not.
        +
        +CMS_RecipientInfo_set0_key() associates the symmetric key B<key> of length
        +B<keylen> with the CMS_RecipientInfo structure B<ri>, which must be of type
        +CMS_RECIPINFO_KEK.
        +
        +CMS_RecipientInfo_decrypt() attempts to decrypt CMS_RecipientInfo structure
        +B<ri> in structure B<cms>. A key must have been associated with the structure
        +first.
        +
        +=head1 NOTES
        +
        +The main purpose of these functions is to enable an application to lookup
        +recipient keys using any appropriate technique when the simpler method
        +of CMS_decrypt() is not appropriate.
        +
        +In typical usage and application will retrieve all CMS_RecipientInfo structures
        +using CMS_get0_RecipientInfos() and check the type of each using
        +CMS_RecpientInfo_type(). Depending on the type the CMS_RecipientInfo structure
        +can be ignored or its key identifier data retrieved using an appropriate
        +function. Then if the corresponding secret or private key can be obtained by
        +any appropriate means it can then associated with the structure and
        +CMS_RecpientInfo_decrypt() called. If successful CMS_decrypt() can be called
        +with a NULL key to decrypt the enveloped content.
        +
        +=head1 RETURN VALUES
        +
        +CMS_get0_RecipientInfos() returns all CMS_RecipientInfo structures, or NULL if
        +an error occurs.
        +
        +CMS_RecipientInfo_ktri_get0_signer_id(), CMS_RecipientInfo_set0_pkey(),
        +CMS_RecipientInfo_kekri_get0_id(), CMS_RecipientInfo_set0_key() and
        +CMS_RecipientInfo_decrypt() return 1 for success or 0 if an error occurs.
        +
        +CMS_RecipientInfo_ktri_cert_cmp() and CMS_RecipientInfo_kekri_cmp() return 0
        +for a successful comparison and non zero otherwise.
        +
        +Any error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_decrypt(3)|CMS_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +These functions were first was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_get0_SignerInfos.pod b/vendor/openssl/openssl/doc/crypto/CMS_get0_SignerInfos.pod
        new file mode 100644
        index 000000000..47f6d2a04
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_get0_SignerInfos.pod
        @@ -0,0 +1,75 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_get0_SignerInfos, CMS_SignerInfo_get0_signer_id, CMS_SignerInfo_cert_cmp, CMS_set1_signer_certs - CMS signedData signer functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
        +
        + int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno);
        + int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
        + void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
        +
        +=head1 DESCRIPTION
        +
        +The function CMS_get0_SignerInfos() returns all the CMS_SignerInfo structures
        +associated with a CMS signedData structure.
        +
        +CMS_SignerInfo_get0_signer_id() retrieves the certificate signer identifier
        +associated with a specific CMS_SignerInfo structure B<si>. Either the
        +keyidentifier will be set in B<keyid> or B<both> issuer name and serial number
        +in B<issuer> and B<sno>.
        +
        +CMS_SignerInfo_cert_cmp() compares the certificate B<cert> against the signer
        +identifier B<si>. It returns zero if the comparison is successful and non zero
        +if not.
        +
        +CMS_SignerInfo_set1_signer_cert() sets the signers certificate of B<si> to
        +B<signer>.
        +
        +=head1 NOTES
        +
        +The main purpose of these functions is to enable an application to lookup
        +signers certificates using any appropriate technique when the simpler method
        +of CMS_verify() is not appropriate.
        +
        +In typical usage and application will retrieve all CMS_SignerInfo structures
        +using CMS_get0_SignerInfo() and retrieve the identifier information using
        +CMS. It will then obtain the signer certificate by some unspecified means
        +(or return and error if it cannot be found) and set it using
        +CMS_SignerInfo_set1_signer_cert().
        +
        +Once all signer certificates have been set CMS_verify() can be used.
        +
        +Although CMS_get0_SignerInfos() can return NULL is an error occur B<or> if
        +there are no signers this is not a problem in practice because the only
        +error which can occur is if the B<cms> structure is not of type signedData
        +due to application error.
        +
        +=head1 RETURN VALUES
        +
        +CMS_get0_SignerInfos() returns all CMS_SignerInfo structures, or NULL there
        +are no signers or an error occurs.
        +
        +CMS_SignerInfo_get0_signer_id() returns 1 for success and 0 for failure.
        +
        +CMS_SignerInfo_cert_cmp() returns 0 for a successful comparison and non
        +zero otherwise.
        +
        +CMS_SignerInfo_set1_signer_cert() does not return a value.
        +
        +Any error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_verify(3)|CMS_verify(3)>
        +
        +=head1 HISTORY
        +
        +These functions were first was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_get0_type.pod b/vendor/openssl/openssl/doc/crypto/CMS_get0_type.pod
        new file mode 100644
        index 000000000..8ff1c3115
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_get0_type.pod
        @@ -0,0 +1,63 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_get0_type, CMS_set1_eContentType, CMS_get0_eContentType - get and set CMS content types
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
        + int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
        + const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
        +
        +=head1 DESCRIPTION
        +
        +CMS_get0_type() returns the content type of a CMS_ContentInfo structure as
        +and ASN1_OBJECT pointer. An application can then decide how to process the
        +CMS_ContentInfo structure based on this value.
        +
        +CMS_set1_eContentType() sets the embedded content type of a CMS_ContentInfo
        +structure. It should be called with CMS functions with the B<CMS_PARTIAL>
        +flag and B<before> the structure is finalised, otherwise the results are
        +undefined.
        +
        +ASN1_OBJECT *CMS_get0_eContentType() returns a pointer to the embedded
        +content type.
        +
        +=head1 NOTES
        +
        +As the B<0> implies CMS_get0_type() and CMS_get0_eContentType() return internal
        +pointers which should B<not> be freed up. CMS_set1_eContentType() copies the
        +supplied OID and it B<should> be freed up after use.
        +
        +The B<ASN1_OBJECT> values returned can be converted to an integer B<NID> value
        +using OBJ_obj2nid(). For the currently supported content types the following
        +values are returned:
        +
        + NID_pkcs7_data
        + NID_pkcs7_signed
        + NID_pkcs7_digest
        + NID_id_smime_ct_compressedData:
        + NID_pkcs7_encrypted
        + NID_pkcs7_enveloped
        +
        +
        +=head1 RETURN VALUES
        +
        +CMS_get0_type() and CMS_get0_eContentType() return and ASN1_OBJECT structure.
        +
        +CMS_set1_eContentType() returns 1 for success or 0 if an error occurred.  The
        +error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +CMS_get0_type(), CMS_set1_eContentType() and CMS_get0_eContentType() were all
        +first added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod b/vendor/openssl/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod
        new file mode 100644
        index 000000000..f546376a1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod
        @@ -0,0 +1,69 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_ReceiptRequest_create0, CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CMS_ReceiptRequest_get0_values - CMS signed receipt request functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo);
        + int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
        + int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
        + void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid, int *pallorfirst, STACK_OF(GENERAL_NAMES) **plist, STACK_OF(GENERAL_NAMES) **prto);
        +
        +=head1 DESCRIPTION
        +
        +CMS_ReceiptRequest_create0() creates a signed receipt request structure. The
        +B<signedContentIdentifier> field is set using B<id> and B<idlen>, or it is set
        +to 32 bytes of pseudo random data if B<id> is NULL. If B<receiptList> is NULL
        +the allOrFirstTier option in B<receiptsFrom> is used and set to the value of
        +the B<allorfirst> parameter. If B<receiptList> is not NULL the B<receiptList>
        +option in B<receiptsFrom> is used. The B<receiptsTo> parameter specifies the
        +B<receiptsTo> field value.
        +
        +The CMS_add1_ReceiptRequest() function adds a signed receipt request B<rr>
        +to SignerInfo structure B<si>.
        +
        +int CMS_get1_ReceiptRequest() looks for a signed receipt request in B<si>, if
        +any is found it is decoded and written to B<prr>.
        +
        +CMS_ReceiptRequest_get0_values() retrieves the values of a receipt request.
        +The signedContentIdentifier is copied to B<pcid>. If the B<allOrFirstTier>
        +option of B<receiptsFrom> is used its value is copied to B<pallorfirst>
        +otherwise the B<receiptList> field is copied to B<plist>. The B<receiptsTo>
        +parameter is copied to B<prto>.
        +
        +=head1 NOTES
        +
        +For more details of the meaning of the fields see RFC2634.
        +
        +The contents of a signed receipt should only be considered meaningful if the
        +corresponding CMS_ContentInfo structure can be successfully verified using
        +CMS_verify().
        +
        +=head1 RETURN VALUES
        +
        +CMS_ReceiptRequest_create0() returns a signed receipt request structure or 
        +NULL if an error occurred.
        +
        +CMS_add1_ReceiptRequest() returns 1 for success or 0 is an error occurred.
        +
        +CMS_get1_ReceiptRequest() returns 1 is a signed receipt request is found and
        +decoded. It returns 0 if a signed receipt request is not present and -1 if
        +it is present but malformed.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_sign_receipt(3)|CMS_sign_receipt(3)>, L<CMS_verify(3)|CMS_verify(3)>
        +L<CMS_verify_receipt(3)|CMS_verify_receipt(3)>
        +
        +=head1 HISTORY
        +
        +CMS_ReceiptRequest_create0(), CMS_add1_ReceiptRequest(),
        +CMS_get1_ReceiptRequest() and CMS_ReceiptRequest_get0_values() were added to
        +OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_sign.pod b/vendor/openssl/openssl/doc/crypto/CMS_sign.pod
        new file mode 100644
        index 000000000..2cc72de32
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_sign.pod
        @@ -0,0 +1,121 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_sign - create a CMS SignedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_sign() creates and returns a CMS SignedData structure. B<signcert> is
        +the certificate to sign with, B<pkey> is the corresponding private key.
        +B<certs> is an optional additional set of certificates to include in the CMS
        +structure (for example any intermediate CAs in the chain). Any or all of
        +these parameters can be B<NULL>, see B<NOTES> below.
        +
        +The data to be signed is read from BIO B<data>.
        +
        +B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +Any of the following flags (ored together) can be passed in the B<flags>
        +parameter.
        +
        +Many S/MIME clients expect the signed content to include valid MIME headers. If
        +the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are prepended
        +to the data.
        +
        +If B<CMS_NOCERTS> is set the signer's certificate will not be included in the
        +CMS_ContentInfo structure, the signer's certificate must still be supplied in
        +the B<signcert> parameter though. This can reduce the size of the signature if
        +the signers certificate can be obtained by other means: for example a
        +previously signed message.
        +
        +The data being signed is included in the CMS_ContentInfo structure, unless
        +B<CMS_DETACHED> is set in which case it is omitted. This is used for
        +CMS_ContentInfo detached signatures which are used in S/MIME plaintext signed
        +messages for example.
        +
        +Normally the supplied content is translated into MIME canonical format (as
        +required by the S/MIME specifications) if B<CMS_BINARY> is set no translation
        +occurs. This option should be used if the supplied data is in binary format
        +otherwise the translation will corrupt it.
        +
        +The SignedData structure includes several CMS signedAttributes including the
        +signing time, the CMS content type and the supported list of ciphers in an
        +SMIMECapabilities attribute. If B<CMS_NOATTR> is set then no signedAttributes
        +will be used. If B<CMS_NOSMIMECAP> is set then just the SMIMECapabilities are
        +omitted.
        +
        +If present the SMIMECapabilities attribute indicates support for the following
        +algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
        +bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
        +If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
        +not loaded.
        +
        +OpenSSL will by default identify signing certificates using issuer name
        +and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
        +identifier value instead. An error occurs if the signing certificate does not
        +have a subject key identifier extension.
        +
        +If the flags B<CMS_STREAM> is set then the returned B<CMS_ContentInfo>
        +structure is just initialized ready to perform the signing operation. The
        +signing is however B<not> performed and the data to be signed is not read from
        +the B<data> parameter. Signing is deferred until after the data has been
        +written. In this way data can be signed in a single pass.
        +
        +If the B<CMS_PARTIAL> flag is set a partial B<CMS_ContentInfo> structure is
        +output to which additional signers and capabilities can be added before
        +finalization.
        +
        +If the flag B<CMS_STREAM> is set the returned B<CMS_ContentInfo> structure is
        +B<not> complete and outputting its contents via a function that does not
        +properly finalize the B<CMS_ContentInfo> structure will give unpredictable
        +results.
        +
        +Several functions including SMIME_write_CMS(), i2d_CMS_bio_stream(),
        +PEM_write_bio_CMS_stream() finalize the structure. Alternatively finalization
        +can be performed by obtaining the streaming ASN1 B<BIO> directly using
        +BIO_new_CMS().
        +
        +If a signer is specified it will use the default digest for the signing
        +algorithm. This is B<SHA1> for both RSA and DSA keys.
        +
        +If B<signcert> and B<pkey> are NULL then a certificates only CMS structure is
        +output.
        +
        +The function CMS_sign() is a basic CMS signing function whose output will be
        +suitable for many purposes. For finer control of the output format the
        +B<certs>, B<signcert> and B<pkey> parameters can all be B<NULL> and the
        +B<CMS_PARTIAL> flag set. Then one or more signers can be added using the
        +function CMS_sign_add1_signer(), non default digests can be used and custom
        +attributes added. B<CMS_final()> must then be called to finalize the
        +structure if streaming is not enabled. 
        +
        +=head1 BUGS
        +
        +Some attributes such as counter signatures are not supported.
        +
        +=head1 RETURN VALUES
        +
        +CMS_sign() returns either a valid CMS_ContentInfo structure or NULL if an error
        +occurred. The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_verify(3)|CMS_verify(3)>
        +
        +=head1 HISTORY
        +
        +CMS_sign() was added to OpenSSL 0.9.8
        +
        +The B<CMS_STREAM> flag is only supported for detached data in OpenSSL 0.9.8,
        +it is supported for embedded data in OpenSSL 1.0.0 and later.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_sign_add1_signer.pod b/vendor/openssl/openssl/doc/crypto/CMS_sign_add1_signer.pod
        new file mode 100644
        index 000000000..bda3ca2ad
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_sign_add1_signer.pod
        @@ -0,0 +1,101 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_sign_add1_signer, CMS_SignerInfo_sign - add a signer to a CMS_ContentInfo signed data structure.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_SignerInfo *CMS_sign_add1_signer(CMS_ContentInfo *cms, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, unsigned int flags);
        +
        + int CMS_SignerInfo_sign(CMS_SignerInfo *si);
        +
        +
        +=head1 DESCRIPTION
        +
        +CMS_sign_add1_signer() adds a signer with certificate B<signcert> and private
        +key B<pkey> using message digest B<md> to CMS_ContentInfo SignedData
        +structure B<cms>.
        +
        +The CMS_ContentInfo structure should be obtained from an initial call to
        +CMS_sign() with the flag B<CMS_PARTIAL> set or in the case or re-signing a
        +valid CMS_ContentInfo SignedData structure.
        +
        +If the B<md> parameter is B<NULL> then the default digest for the public
        +key algorithm will be used.
        +
        +Unless the B<CMS_REUSE_DIGEST> flag is set the returned CMS_ContentInfo
        +structure is not complete and must be finalized either by streaming (if
        +applicable) or a call to CMS_final().
        +
        +The CMS_SignerInfo_sign() function will explicitly sign a CMS_SignerInfo
        +structure, its main use is when B<CMS_REUSE_DIGEST> and B<CMS_PARTIAL> flags
        +are both set.
        +
        +=head1 NOTES
        +
        +The main purpose of CMS_sign_add1_signer() is to provide finer control
        +over a CMS signed data structure where the simpler CMS_sign() function defaults
        +are not appropriate. For example if multiple signers or non default digest
        +algorithms are needed. New attributes can also be added using the returned
        +CMS_SignerInfo structure and the CMS attribute utility functions or the
        +CMS signed receipt request functions.
        +
        +Any of the following flags (ored together) can be passed in the B<flags>
        +parameter.
        +
        +If B<CMS_REUSE_DIGEST> is set then an attempt is made to copy the content
        +digest value from the CMS_ContentInfo structure: to add a signer to an existing
        +structure.  An error occurs if a matching digest value cannot be found to copy.
        +The returned CMS_ContentInfo structure will be valid and finalized when this
        +flag is set.
        +
        +If B<CMS_PARTIAL> is set in addition to B<CMS_REUSE_DIGEST> then the 
        +CMS_SignerInfo structure will not be finalized so additional attributes
        +can be added. In this case an explicit call to CMS_SignerInfo_sign() is
        +needed to finalize it.
        +
        +If B<CMS_NOCERTS> is set the signer's certificate will not be included in the
        +CMS_ContentInfo structure, the signer's certificate must still be supplied in
        +the B<signcert> parameter though. This can reduce the size of the signature if
        +the signers certificate can be obtained by other means: for example a
        +previously signed message.
        +
        +The SignedData structure includes several CMS signedAttributes including the
        +signing time, the CMS content type and the supported list of ciphers in an
        +SMIMECapabilities attribute. If B<CMS_NOATTR> is set then no signedAttributes
        +will be used. If B<CMS_NOSMIMECAP> is set then just the SMIMECapabilities are
        +omitted.
        +
        +OpenSSL will by default identify signing certificates using issuer name
        +and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
        +identifier value instead. An error occurs if the signing certificate does not
        +have a subject key identifier extension.
        +
        +If present the SMIMECapabilities attribute indicates support for the following
        +algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
        +bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
        +If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
        +not loaded.
        +
        +CMS_sign_add1_signer() returns an internal pointer to the CMS_SignerInfo
        +structure just added, this can be used to set additional attributes 
        +before it is finalized.
        +
        +=head1 RETURN VALUES
        +
        +CMS_sign1_add_signers() returns an internal pointer to the CMS_SignerInfo
        +structure just added or NULL if an error occurs.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_final(3)|CMS_final(3)>,
        +
        +=head1 HISTORY
        +
        +CMS_sign_add1_signer() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_sign_receipt.pod b/vendor/openssl/openssl/doc/crypto/CMS_sign_receipt.pod
        new file mode 100644
        index 000000000..cae1f8338
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_sign_receipt.pod
        @@ -0,0 +1,45 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_sign_receipt - create a CMS signed receipt
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_sign_receipt() creates and returns a CMS signed receipt structure. B<si> is
        +the B<CMS_SignerInfo> structure containing the signed receipt request.
        +B<signcert> is the certificate to sign with, B<pkey> is the corresponding
        +private key.  B<certs> is an optional additional set of certificates to include
        +in the CMS structure (for example any intermediate CAs in the chain).
        +
        +B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +This functions behaves in a similar way to CMS_sign() except the flag values
        +B<CMS_DETACHED>, B<CMS_BINARY>, B<CMS_NOATTR>, B<CMS_TEXT> and B<CMS_STREAM>
        +are not supported since they do not make sense in the context of signed
        +receipts.
        +
        +=head1 RETURN VALUES
        +
        +CMS_sign_receipt() returns either a valid CMS_ContentInfo structure or NULL if
        +an error occurred.  The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<CMS_verify_receipt(3)|CMS_verify_receipt(3)>,
        +L<CMS_sign(3)|CMS_sign(3)>
        +
        +=head1 HISTORY
        +
        +CMS_sign_receipt() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_uncompress.pod b/vendor/openssl/openssl/doc/crypto/CMS_uncompress.pod
        new file mode 100644
        index 000000000..c6056b027
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_uncompress.pod
        @@ -0,0 +1,54 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_uncompress - uncompress a CMS CompressedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_uncompress() extracts and uncompresses the content from a CMS
        +CompressedData structure B<cms>. B<data> is a BIO to write the content to and
        +B<flags> is an optional set of flags.
        +
        +The B<dcont> parameter is used in the rare case where the compressed content
        +is detached. It will normally be set to NULL.
        +
        +=head1 NOTES
        +
        +The only currently supported compression algorithm is zlib: if the structure
        +indicates the use of any other algorithm an error is returned.
        +
        +If zlib support is not compiled into OpenSSL then CMS_uncompress() will always
        +return an error.
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
        +from the content. If the content is not of type B<text/plain> then an error is
        +returned.
        +
        +=head1 RETURN VALUES
        +
        +CMS_uncompress() returns either 1 for success or 0 for failure. The error can
        +be obtained from ERR_get_error(3)
        +
        +=head1 BUGS
        +
        +The lack of single pass processing and the need to hold all data in memory as
        +mentioned in CMS_verify() also applies to CMS_decompress().
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_compress(3)|CMS_compress(3)>
        +
        +=head1 HISTORY
        +
        +CMS_uncompress() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_verify.pod b/vendor/openssl/openssl/doc/crypto/CMS_verify.pod
        new file mode 100644
        index 000000000..8f26fdab0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_verify.pod
        @@ -0,0 +1,126 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_verify - verify a CMS SignedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, unsigned int flags);
        +
        + STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
        +
        +=head1 DESCRIPTION
        +
        +CMS_verify() verifies a CMS SignedData structure. B<cms> is the CMS_ContentInfo
        +structure to verify. B<certs> is a set of certificates in which to search for
        +the signing certificate(s). B<store> is a trusted certificate store used for
        +chain verification. B<indata> is the detached content if the content is not
        +present in B<cms>. The content is written to B<out> if it is not NULL.
        +
        +B<flags> is an optional set of flags, which can be used to modify the verify
        +operation.
        +
        +CMS_get0_signers() retrieves the signing certificate(s) from B<cms>, it must
        +be called after a successful CMS_verify() operation.
        +
        +=head1 VERIFY PROCESS
        +
        +Normally the verify process proceeds as follows.
        +
        +Initially some sanity checks are performed on B<cms>. The type of B<cms> must
        +be SignedData. There must be at least one signature on the data and if
        +the content is detached B<indata> cannot be B<NULL>.
        +
        +An attempt is made to locate all the signing certificate(s), first looking in
        +the B<certs> parameter (if it is not NULL) and then looking in any
        +certificates contained in the B<cms> structure itself. If any signing
        +certificate cannot be located the operation fails.
        +
        +Each signing certificate is chain verified using the B<smimesign> purpose and
        +the supplied trusted certificate store. Any internal certificates in the message
        +are used as untrusted CAs. If CRL checking is enabled in B<store> any internal
        +CRLs are used in addition to attempting to look them up in B<store>. If any
        +chain verify fails an error code is returned.
        +
        +Finally the signed content is read (and written to B<out> is it is not NULL)
        +and the signature's checked.
        +
        +If all signature's verify correctly then the function is successful.
        +
        +Any of the following flags (ored together) can be passed in the B<flags>
        +parameter to change the default verify behaviour.
        +
        +If B<CMS_NOINTERN> is set the certificates in the message itself are not
        +searched when locating the signing certificate(s). This means that all the
        +signing certificates must be in the B<certs> parameter.
        +
        +If B<CMS_NOCRL> is set and CRL checking is enabled in B<store> then any
        +CRLs in the message itself are ignored.
        +
        +If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
        +from the content. If the content is not of type B<text/plain> then an error is
        +returned.
        +
        +If B<CMS_NO_SIGNER_CERT_VERIFY> is set the signing certificates are not
        +verified.
        +
        +If B<CMS_NO_ATTR_VERIFY> is set the signed attributes signature is not 
        +verified.
        +
        +If B<CMS_NO_CONTENT_VERIFY> is set then the content digest is not checked.
        +
        +=head1 NOTES
        +
        +One application of B<CMS_NOINTERN> is to only accept messages signed by
        +a small number of certificates. The acceptable certificates would be passed
        +in the B<certs> parameter. In this case if the signer is not one of the
        +certificates supplied in B<certs> then the verify will fail because the
        +signer cannot be found.
        +
        +In some cases the standard techniques for looking up and validating
        +certificates are not appropriate: for example an application may wish to 
        +lookup certificates in a database or perform customised verification. This
        +can be achieved by setting and verifying the signers certificates manually 
        +using the signed data utility functions.
        +
        +Care should be taken when modifying the default verify behaviour, for example
        +setting B<CMS_NO_CONTENT_VERIFY> will totally disable all content verification 
        +and any modified content will be considered valid. This combination is however
        +useful if one merely wishes to write the content to B<out> and its validity
        +is not considered important.
        +
        +Chain verification should arguably be performed using the signing time rather
        +than the current time. However since the signing time is supplied by the
        +signer it cannot be trusted without additional evidence (such as a trusted
        +timestamp).
        +
        +=head1 RETURN VALUES
        +
        +CMS_verify() returns 1 for a successful verification and zero if an error
        +occurred.
        +
        +CMS_get0_signers() returns all signers or NULL if an error occurred.
        +
        +The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 BUGS
        +
        +The trusted certificate store is not searched for the signing certificate,
        +this is primarily due to the inadequacies of the current B<X509_STORE>
        +functionality.
        +
        +The lack of single pass processing means that the signed content must all
        +be held in memory if it is not detached.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>
        +
        +=head1 HISTORY
        +
        +CMS_verify() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CMS_verify_receipt.pod b/vendor/openssl/openssl/doc/crypto/CMS_verify_receipt.pod
        new file mode 100644
        index 000000000..9283e0e04
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CMS_verify_receipt.pod
        @@ -0,0 +1,47 @@
        +=pod
        +
        +=head1 NAME
        +
        + CMS_verify_receipt - verify a CMS signed receipt
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags);
        +
        +=head1 DESCRIPTION
        +
        +CMS_verify_receipt() verifies a CMS signed receipt. B<rcms> is the signed
        +receipt to verify. B<ocms> is the original SignedData structure containing the
        +receipt request. B<certs> is a set of certificates in which to search for the
        +signing certificate. B<store> is a trusted certificate store (used for chain
        +verification). 
        +
        +B<flags> is an optional set of flags, which can be used to modify the verify
        +operation.
        +
        +=head1 NOTES
        +
        +This functions behaves in a similar way to CMS_verify() except the flag values
        +B<CMS_DETACHED>, B<CMS_BINARY>, B<CMS_TEXT> and B<CMS_STREAM> are not
        +supported since they do not make sense in the context of signed receipts.
        +
        +=head1 RETURN VALUES
        +
        +CMS_verify_receipt() returns 1 for a successful verification and zero if an
        +error occurred.
        +
        +The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<CMS_sign_receipt(3)|CMS_sign_receipt(3)>,
        +L<CMS_verify(3)|CMS_verify(3)>,
        +
        +=head1 HISTORY
        +
        +CMS_verify_receipt() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CONF_modules_free.pod b/vendor/openssl/openssl/doc/crypto/CONF_modules_free.pod
        new file mode 100644
        index 000000000..87bc7b783
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CONF_modules_free.pod
        @@ -0,0 +1,47 @@
        +=pod
        +
        +=head1 NAME
        +
        + CONF_modules_free, CONF_modules_finish, CONF_modules_unload -
        + OpenSSL configuration cleanup functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/conf.h>
        +
        + void CONF_modules_free(void);
        + void CONF_modules_finish(void);
        + void CONF_modules_unload(int all);
        +
        +=head1 DESCRIPTION
        +
        +CONF_modules_free() closes down and frees up all memory allocated by all
        +configuration modules.
        +
        +CONF_modules_finish() calls each configuration modules B<finish> handler
        +to free up any configuration that module may have performed.
        +
        +CONF_modules_unload() finishes and unloads configuration modules. If
        +B<all> is set to B<0> only modules loaded from DSOs will be unloads. If
        +B<all> is B<1> all modules, including builtin modules will be unloaded.
        +
        +=head1 NOTES
        +
        +Normally applications will only call CONF_modules_free() at application to
        +tidy up any configuration performed.
        +
        +=head1 RETURN VALUE
        +
        +None of the functions return a value.
        +
        +=head1 SEE ALSO
        +
        +L<conf(5)|conf(5)>, L<OPENSSL_config(3)|OPENSSL_config(3)>,
        +L<CONF_modules_load_file(3), CONF_modules_load_file(3)>
        +
        +=head1 HISTORY
        +
        +CONF_modules_free(), CONF_modules_unload(), and CONF_modules_finish()
        +first appeared in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CONF_modules_load_file.pod b/vendor/openssl/openssl/doc/crypto/CONF_modules_load_file.pod
        new file mode 100644
        index 000000000..9965d69bf
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CONF_modules_load_file.pod
        @@ -0,0 +1,60 @@
        +=pod
        +
        +=head1 NAME
        +
        + CONF_modules_load_file, CONF_modules_load - OpenSSL configuration functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/conf.h>
        +
        + int CONF_modules_load_file(const char *filename, const char *appname,
        +			   unsigned long flags);
        + int CONF_modules_load(const CONF *cnf, const char *appname,
        +		      unsigned long flags);
        +
        +=head1 DESCRIPTION
        +
        +The function CONF_modules_load_file() configures OpenSSL using file
        +B<filename> and application name B<appname>. If B<filename> is NULL
        +the standard OpenSSL configuration file is used. If B<appname> is
        +NULL the standard OpenSSL application name B<openssl_conf> is used.
        +The behaviour can be cutomized using B<flags>.
        +
        +CONF_modules_load() is idential to CONF_modules_load_file() except it
        +read configuration information from B<cnf>. 
        +
        +=head1 NOTES
        +
        +The following B<flags> are currently recognized:
        +
        +B<CONF_MFLAGS_IGNORE_ERRORS> if set errors returned by individual
        +configuration modules are ignored. If not set the first module error is
        +considered fatal and no further modules are loads.
        +
        +Normally any modules errors will add error information to the error queue. If
        +B<CONF_MFLAGS_SILENT> is set no error information is added.
        +
        +If B<CONF_MFLAGS_NO_DSO> is set configuration module loading from DSOs is
        +disabled.
        +
        +B<CONF_MFLAGS_IGNORE_MISSING_FILE> if set will make CONF_load_modules_file()
        +ignore missing configuration files. Normally a missing configuration file
        +return an error.
        +
        +=head1 RETURN VALUE
        +
        +These functions return 1 for success and a zero or negative value for
        +failure. If module errors are not ignored the return code will reflect the
        +return value of the failing module (this will always be zero or negative).
        +
        +=head1 SEE ALSO
        +
        +L<conf(5)|conf(5)>, L<OPENSSL_config(3)|OPENSSL_config(3)>,
        +L<CONF_free(3), CONF_free(3)>, L<err(3),err(3)>
        +
        +=head1 HISTORY
        +
        +CONF_modules_load_file and CONF_modules_load first appeared in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/CRYPTO_set_ex_data.pod b/vendor/openssl/openssl/doc/crypto/CRYPTO_set_ex_data.pod
        new file mode 100644
        index 000000000..7409c02aa
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/CRYPTO_set_ex_data.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +CRYPTO_set_ex_data, CRYPTO_get_ex_data - internal application specific data functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/crypto.h>
        +
        + int CRYPTO_set_ex_data(CRYPTO_EX_DATA *r, int idx, void *arg);
        +
        + void *CRYPTO_get_ex_data(CRYPTO_EX_DATA *r, int idx);
        +
        +=head1 DESCRIPTION
        +
        +Several OpenSSL structures can have application specific data attached to them.
        +These functions are used internally by OpenSSL to manipulate application
        +specific data attached to a specific structure.
        +
        +These functions should only be used by applications to manipulate
        +B<CRYPTO_EX_DATA> structures passed to the B<new_func()>, B<free_func()> and
        +B<dup_func()> callbacks: as passed to B<RSA_get_ex_new_index()> for example.
        +
        +B<CRYPTO_set_ex_data()> is used to set application specific data, the data is
        +supplied in the B<arg> parameter and its precise meaning is up to the
        +application.
        +
        +B<CRYPTO_get_ex_data()> is used to retrieve application specific data. The data
        +is returned to the application, this will be the same value as supplied to
        +a previous B<CRYPTO_set_ex_data()> call.
        +
        +=head1 RETURN VALUES
        +
        +B<CRYPTO_set_ex_data()> returns 1 on success or 0 on failure.
        +
        +B<CRYPTO_get_ex_data()> returns the application data or 0 on failure. 0 may also
        +be valid application data but currently it can only fail if given an invalid B<idx>
        +parameter.
        +
        +On failure an error code can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
        +L<DSA_get_ex_new_index(3)|DSA_get_ex_new_index(3)>,
        +L<DH_get_ex_new_index(3)|DH_get_ex_new_index(3)>
        +
        +=head1 HISTORY
        +
        +CRYPTO_set_ex_data() and CRYPTO_get_ex_data() have been available since SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DH_generate_key.pod b/vendor/openssl/openssl/doc/crypto/DH_generate_key.pod
        new file mode 100644
        index 000000000..81f09fdf4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DH_generate_key.pod
        @@ -0,0 +1,50 @@
        +=pod
        +
        +=head1 NAME
        +
        +DH_generate_key, DH_compute_key - perform Diffie-Hellman key exchange
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        +
        + int DH_generate_key(DH *dh);
        +
        + int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
        +
        +=head1 DESCRIPTION
        +
        +DH_generate_key() performs the first step of a Diffie-Hellman key
        +exchange by generating private and public DH values. By calling
        +DH_compute_key(), these are combined with the other party's public
        +value to compute the shared key.
        +
        +DH_generate_key() expects B<dh> to contain the shared parameters
        +B<dh-E<gt>p> and B<dh-E<gt>g>. It generates a random private DH value
        +unless B<dh-E<gt>priv_key> is already set, and computes the
        +corresponding public value B<dh-E<gt>pub_key>, which can then be
        +published.
        +
        +DH_compute_key() computes the shared secret from the private DH value
        +in B<dh> and the other party's public value in B<pub_key> and stores
        +it in B<key>. B<key> must point to B<DH_size(dh)> bytes of memory.
        +
        +=head1 RETURN VALUES
        +
        +DH_generate_key() returns 1 on success, 0 otherwise.
        +
        +DH_compute_key() returns the size of the shared secret on success, -1
        +on error.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<DH_size(3)|DH_size(3)>
        +
        +=head1 HISTORY
        +
        +DH_generate_key() and DH_compute_key() are available in all versions
        +of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DH_generate_parameters.pod b/vendor/openssl/openssl/doc/crypto/DH_generate_parameters.pod
        new file mode 100644
        index 000000000..9081e9ea7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DH_generate_parameters.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +DH_generate_parameters, DH_check - generate and check Diffie-Hellman parameters
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        +
        + DH *DH_generate_parameters(int prime_len, int generator,
        +     void (*callback)(int, int, void *), void *cb_arg);
        +
        + int DH_check(DH *dh, int *codes);
        +
        +=head1 DESCRIPTION
        +
        +DH_generate_parameters() generates Diffie-Hellman parameters that can
        +be shared among a group of users, and returns them in a newly
        +allocated B<DH> structure. The pseudo-random number generator must be
        +seeded prior to calling DH_generate_parameters().
        +
        +B<prime_len> is the length in bits of the safe prime to be generated.
        +B<generator> is a small number E<gt> 1, typically 2 or 5. 
        +
        +A callback function may be used to provide feedback about the progress
        +of the key generation. If B<callback> is not B<NULL>, it will be
        +called as described in L<BN_generate_prime(3)|BN_generate_prime(3)> while a random prime
        +number is generated, and when a prime has been found, B<callback(3,
        +0, cb_arg)> is called.
        +
        +DH_check() validates Diffie-Hellman parameters. It checks that B<p> is
        +a safe prime, and that B<g> is a suitable generator. In the case of an
        +error, the bit flags DH_CHECK_P_NOT_SAFE_PRIME or
        +DH_NOT_SUITABLE_GENERATOR are set in B<*codes>.
        +DH_UNABLE_TO_CHECK_GENERATOR is set if the generator cannot be
        +checked, i.e. it does not equal 2 or 5.
        +
        +=head1 RETURN VALUES
        +
        +DH_generate_parameters() returns a pointer to the DH structure, or
        +NULL if the parameter generation fails. The error codes can be
        +obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +DH_check() returns 1 if the check could be performed, 0 otherwise.
        +
        +=head1 NOTES
        +
        +DH_generate_parameters() may run for several hours before finding a
        +suitable prime.
        +
        +The parameters generated by DH_generate_parameters() are not to be
        +used in signature schemes.
        +
        +=head1 BUGS
        +
        +If B<generator> is not 2 or 5, B<dh-E<gt>g>=B<generator> is not
        +a usable generator.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
        +L<DH_free(3)|DH_free(3)>
        +
        +=head1 HISTORY
        +
        +DH_check() is available in all versions of SSLeay and OpenSSL.
        +The B<cb_arg> argument to DH_generate_parameters() was added in SSLeay 0.9.0.
        +
        +In versions before OpenSSL 0.9.5, DH_CHECK_P_NOT_STRONG_PRIME is used
        +instead of DH_CHECK_P_NOT_SAFE_PRIME.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DH_get_ex_new_index.pod b/vendor/openssl/openssl/doc/crypto/DH_get_ex_new_index.pod
        new file mode 100644
        index 000000000..fa5eab265
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DH_get_ex_new_index.pod
        @@ -0,0 +1,36 @@
        +=pod
        +
        +=head1 NAME
        +
        +DH_get_ex_new_index, DH_set_ex_data, DH_get_ex_data - add application specific data to DH structures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        +
        + int DH_get_ex_new_index(long argl, void *argp,
        +		CRYPTO_EX_new *new_func,
        +		CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func);
        +
        + int DH_set_ex_data(DH *d, int idx, void *arg);
        +
        + char *DH_get_ex_data(DH *d, int idx);
        +
        +=head1 DESCRIPTION
        +
        +These functions handle application specific data in DH
        +structures. Their usage is identical to that of
        +RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data()
        +as described in L<RSA_get_ex_new_index(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>, L<dh(3)|dh(3)>
        +
        +=head1 HISTORY
        +
        +DH_get_ex_new_index(), DH_set_ex_data() and DH_get_ex_data() are
        +available since OpenSSL 0.9.5.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DH_new.pod b/vendor/openssl/openssl/doc/crypto/DH_new.pod
        new file mode 100644
        index 000000000..60c930093
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DH_new.pod
        @@ -0,0 +1,40 @@
        +=pod
        +
        +=head1 NAME
        +
        +DH_new, DH_free - allocate and free DH objects
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        +
        + DH* DH_new(void);
        +
        + void DH_free(DH *dh);
        +
        +=head1 DESCRIPTION
        +
        +DH_new() allocates and initializes a B<DH> structure.
        +
        +DH_free() frees the B<DH> structure and its components. The values are
        +erased before the memory is returned to the system.
        +
        +=head1 RETURN VALUES
        +
        +If the allocation fails, DH_new() returns B<NULL> and sets an error
        +code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns
        +a pointer to the newly allocated structure.
        +
        +DH_free() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<DH_generate_parameters(3)|DH_generate_parameters(3)>,
        +L<DH_generate_key(3)|DH_generate_key(3)>
        +
        +=head1 HISTORY
        +
        +DH_new() and DH_free() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DH_set_method.pod b/vendor/openssl/openssl/doc/crypto/DH_set_method.pod
        new file mode 100644
        index 000000000..d5cdc3be0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DH_set_method.pod
        @@ -0,0 +1,129 @@
        +=pod
        +
        +=head1 NAME
        +
        +DH_set_default_method, DH_get_default_method,
        +DH_set_method, DH_new_method, DH_OpenSSL - select DH method
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        + #include <openssl/engine.h>
        +
        + void DH_set_default_method(const DH_METHOD *meth);
        +
        + const DH_METHOD *DH_get_default_method(void);
        +
        + int DH_set_method(DH *dh, const DH_METHOD *meth);
        +
        + DH *DH_new_method(ENGINE *engine);
        +
        + const DH_METHOD *DH_OpenSSL(void);
        +
        +=head1 DESCRIPTION
        +
        +A B<DH_METHOD> specifies the functions that OpenSSL uses for Diffie-Hellman
        +operations. By modifying the method, alternative implementations
        +such as hardware accelerators may be used. IMPORTANT: See the NOTES section for
        +important information about how these DH API functions are affected by the use
        +of B<ENGINE> API calls.
        +
        +Initially, the default DH_METHOD is the OpenSSL internal implementation, as
        +returned by DH_OpenSSL().
        +
        +DH_set_default_method() makes B<meth> the default method for all DH
        +structures created later. B<NB>: This is true only whilst no ENGINE has been set
        +as a default for DH, so this function is no longer recommended.
        +
        +DH_get_default_method() returns a pointer to the current default DH_METHOD.
        +However, the meaningfulness of this result is dependent on whether the ENGINE
        +API is being used, so this function is no longer recommended.
        +
        +DH_set_method() selects B<meth> to perform all operations using the key B<dh>.
        +This will replace the DH_METHOD used by the DH key and if the previous method
        +was supplied by an ENGINE, the handle to that ENGINE will be released during the
        +change. It is possible to have DH keys that only work with certain DH_METHOD
        +implementations (eg. from an ENGINE module that supports embedded
        +hardware-protected keys), and in such cases attempting to change the DH_METHOD
        +for the key can have unexpected results.
        +
        +DH_new_method() allocates and initializes a DH structure so that B<engine> will
        +be used for the DH operations. If B<engine> is NULL, the default ENGINE for DH
        +operations is used, and if no default ENGINE is set, the DH_METHOD controlled by
        +DH_set_default_method() is used.
        +
        +=head1 THE DH_METHOD STRUCTURE
        +
        + typedef struct dh_meth_st
        + {
        +     /* name of the implementation */
        +	const char *name;
        +
        +     /* generate private and public DH values for key agreement */
        +        int (*generate_key)(DH *dh);
        +
        +     /* compute shared secret */
        +        int (*compute_key)(unsigned char *key, BIGNUM *pub_key, DH *dh);
        +
        +     /* compute r = a ^ p mod m (May be NULL for some implementations) */
        +        int (*bn_mod_exp)(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
        +                                const BIGNUM *m, BN_CTX *ctx,
        +                                BN_MONT_CTX *m_ctx);
        +
        +     /* called at DH_new */
        +        int (*init)(DH *dh);
        +
        +     /* called at DH_free */
        +        int (*finish)(DH *dh);
        +
        +        int flags;
        +
        +        char *app_data; /* ?? */
        +
        + } DH_METHOD;
        +
        +=head1 RETURN VALUES
        +
        +DH_OpenSSL() and DH_get_default_method() return pointers to the respective
        +B<DH_METHOD>s.
        +
        +DH_set_default_method() returns no value.
        +
        +DH_set_method() returns non-zero if the provided B<meth> was successfully set as
        +the method for B<dh> (including unloading the ENGINE handle if the previous
        +method was supplied by an ENGINE).
        +
        +DH_new_method() returns NULL and sets an error code that can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)> if the allocation fails. Otherwise it
        +returns a pointer to the newly allocated structure.
        +
        +=head1 NOTES
        +
        +As of version 0.9.7, DH_METHOD implementations are grouped together with other
        +algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B<ENGINE> modules. If a
        +default ENGINE is specified for DH functionality using an ENGINE API function,
        +that will override any DH defaults set using the DH API (ie.
        +DH_set_default_method()). For this reason, the ENGINE API is the recommended way
        +to control default implementations for use in DH and other cryptographic
        +algorithms.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<DH_new(3)|DH_new(3)>
        +
        +=head1 HISTORY
        +
        +DH_set_default_method(), DH_get_default_method(), DH_set_method(),
        +DH_new_method() and DH_OpenSSL() were added in OpenSSL 0.9.4.
        +
        +DH_set_default_openssl_method() and DH_get_default_openssl_method() replaced
        +DH_set_default_method() and DH_get_default_method() respectively, and
        +DH_set_method() and DH_new_method() were altered to use B<ENGINE>s rather than
        +B<DH_METHOD>s during development of the engine version of OpenSSL 0.9.6. For
        +0.9.7, the handling of defaults in the ENGINE API was restructured so that this
        +change was reversed, and behaviour of the other functions resembled more closely
        +the previous behaviour. The behaviour of defaults in the ENGINE API now
        +transparently overrides the behaviour of defaults in the DH API without
        +requiring changing these function prototypes.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DH_size.pod b/vendor/openssl/openssl/doc/crypto/DH_size.pod
        new file mode 100644
        index 000000000..97f26fda7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DH_size.pod
        @@ -0,0 +1,33 @@
        +=pod
        +
        +=head1 NAME
        +
        +DH_size - get Diffie-Hellman prime size
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        +
        + int DH_size(DH *dh);
        +
        +=head1 DESCRIPTION
        +
        +This function returns the Diffie-Hellman size in bytes. It can be used
        +to determine how much memory must be allocated for the shared secret
        +computed by DH_compute_key().
        +
        +B<dh-E<gt>p> must not be B<NULL>.
        +
        +=head1 RETURN VALUE
        +
        +The size in bytes.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<DH_generate_key(3)|DH_generate_key(3)>
        +
        +=head1 HISTORY
        +
        +DH_size() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_SIG_new.pod b/vendor/openssl/openssl/doc/crypto/DSA_SIG_new.pod
        new file mode 100644
        index 000000000..3ac614003
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_SIG_new.pod
        @@ -0,0 +1,40 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_SIG_new, DSA_SIG_free - allocate and free DSA signature objects
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + DSA_SIG *DSA_SIG_new(void);
        +
        + void	DSA_SIG_free(DSA_SIG *a);
        +
        +=head1 DESCRIPTION
        +
        +DSA_SIG_new() allocates and initializes a B<DSA_SIG> structure.
        +
        +DSA_SIG_free() frees the B<DSA_SIG> structure and its components. The
        +values are erased before the memory is returned to the system.
        +
        +=head1 RETURN VALUES
        +
        +If the allocation fails, DSA_SIG_new() returns B<NULL> and sets an
        +error code that can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns a pointer
        +to the newly allocated structure.
        +
        +DSA_SIG_free() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<DSA_do_sign(3)|DSA_do_sign(3)>
        +
        +=head1 HISTORY
        +
        +DSA_SIG_new() and DSA_SIG_free() were added in OpenSSL 0.9.3.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_do_sign.pod b/vendor/openssl/openssl/doc/crypto/DSA_do_sign.pod
        new file mode 100644
        index 000000000..5dfc733b2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_do_sign.pod
        @@ -0,0 +1,47 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_do_sign, DSA_do_verify - raw DSA signature operations
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        +
        + int DSA_do_verify(const unsigned char *dgst, int dgst_len,
        +	     DSA_SIG *sig, DSA *dsa);
        +
        +=head1 DESCRIPTION
        +
        +DSA_do_sign() computes a digital signature on the B<len> byte message
        +digest B<dgst> using the private key B<dsa> and returns it in a
        +newly allocated B<DSA_SIG> structure.
        +
        +L<DSA_sign_setup(3)|DSA_sign_setup(3)> may be used to precompute part
        +of the signing operation in case signature generation is
        +time-critical.
        +
        +DSA_do_verify() verifies that the signature B<sig> matches a given
        +message digest B<dgst> of size B<len>.  B<dsa> is the signer's public
        +key.
        +
        +=head1 RETURN VALUES
        +
        +DSA_do_sign() returns the signature, NULL on error.  DSA_do_verify()
        +returns 1 for a valid signature, 0 for an incorrect signature and -1
        +on error. The error codes can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
        +L<DSA_SIG_new(3)|DSA_SIG_new(3)>,
        +L<DSA_sign(3)|DSA_sign(3)>
        +
        +=head1 HISTORY
        +
        +DSA_do_sign() and DSA_do_verify() were added in OpenSSL 0.9.3.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_dup_DH.pod b/vendor/openssl/openssl/doc/crypto/DSA_dup_DH.pod
        new file mode 100644
        index 000000000..7f6f0d111
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_dup_DH.pod
        @@ -0,0 +1,36 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_dup_DH - create a DH structure out of DSA structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + DH * DSA_dup_DH(const DSA *r);
        +
        +=head1 DESCRIPTION
        +
        +DSA_dup_DH() duplicates DSA parameters/keys as DH parameters/keys. q
        +is lost during that conversion, but the resulting DH parameters
        +contain its length.
        +
        +=head1 RETURN VALUE
        +
        +DSA_dup_DH() returns the new B<DH> structure, and NULL on error. The
        +error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 NOTE
        +
        +Be careful to avoid small subgroup attacks when using this.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +DSA_dup_DH() was added in OpenSSL 0.9.4.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_generate_key.pod b/vendor/openssl/openssl/doc/crypto/DSA_generate_key.pod
        new file mode 100644
        index 000000000..af83ccfaa
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_generate_key.pod
        @@ -0,0 +1,34 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_generate_key - generate DSA key pair
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + int DSA_generate_key(DSA *a);
        +
        +=head1 DESCRIPTION
        +
        +DSA_generate_key() expects B<a> to contain DSA parameters. It generates
        +a new key pair and stores it in B<a-E<gt>pub_key> and B<a-E<gt>priv_key>.
        +
        +The PRNG must be seeded prior to calling DSA_generate_key().
        +
        +=head1 RETURN VALUE
        +
        +DSA_generate_key() returns 1 on success, 0 otherwise.
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
        +L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>
        +
        +=head1 HISTORY
        +
        +DSA_generate_key() is available since SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_generate_parameters.pod b/vendor/openssl/openssl/doc/crypto/DSA_generate_parameters.pod
        new file mode 100644
        index 000000000..be7c924ff
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_generate_parameters.pod
        @@ -0,0 +1,105 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_generate_parameters - generate DSA parameters
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + DSA *DSA_generate_parameters(int bits, unsigned char *seed,
        +                int seed_len, int *counter_ret, unsigned long *h_ret,
        +		void (*callback)(int, int, void *), void *cb_arg);
        +
        +=head1 DESCRIPTION
        +
        +DSA_generate_parameters() generates primes p and q and a generator g
        +for use in the DSA.
        +
        +B<bits> is the length of the prime to be generated; the DSS allows a
        +maximum of 1024 bits.
        +
        +If B<seed> is B<NULL> or B<seed_len> E<lt> 20, the primes will be
        +generated at random. Otherwise, the seed is used to generate
        +them. If the given seed does not yield a prime q, a new random
        +seed is chosen and placed at B<seed>.
        +
        +DSA_generate_parameters() places the iteration count in
        +*B<counter_ret> and a counter used for finding a generator in
        +*B<h_ret>, unless these are B<NULL>.
        +
        +A callback function may be used to provide feedback about the progress
        +of the key generation. If B<callback> is not B<NULL>, it will be
        +called as follows:
        +
        +=over 4
        +
        +=item *
        +
        +When a candidate for q is generated, B<callback(0, m++, cb_arg)> is called
        +(m is 0 for the first candidate).
        +
        +=item *
        +
        +When a candidate for q has passed a test by trial division,
        +B<callback(1, -1, cb_arg)> is called.
        +While a candidate for q is tested by Miller-Rabin primality tests,
        +B<callback(1, i, cb_arg)> is called in the outer loop
        +(once for each witness that confirms that the candidate may be prime);
        +i is the loop counter (starting at 0).
        +
        +=item *
        +
        +When a prime q has been found, B<callback(2, 0, cb_arg)> and
        +B<callback(3, 0, cb_arg)> are called.
        +
        +=item *
        +
        +Before a candidate for p (other than the first) is generated and tested,
        +B<callback(0, counter, cb_arg)> is called.
        +
        +=item *
        +
        +When a candidate for p has passed the test by trial division,
        +B<callback(1, -1, cb_arg)> is called.
        +While it is tested by the Miller-Rabin primality test,
        +B<callback(1, i, cb_arg)> is called in the outer loop
        +(once for each witness that confirms that the candidate may be prime).
        +i is the loop counter (starting at 0).
        +
        +=item *
        +
        +When p has been found, B<callback(2, 1, cb_arg)> is called.
        +
        +=item *
        +
        +When the generator has been found, B<callback(3, 1, cb_arg)> is called.
        +
        +=back
        +
        +=head1 RETURN VALUE
        +
        +DSA_generate_parameters() returns a pointer to the DSA structure, or
        +B<NULL> if the parameter generation fails. The error codes can be
        +obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 BUGS
        +
        +Seed lengths E<gt> 20 are not supported.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
        +L<DSA_free(3)|DSA_free(3)>
        +
        +=head1 HISTORY
        +
        +DSA_generate_parameters() appeared in SSLeay 0.8. The B<cb_arg>
        +argument was added in SSLeay 0.9.0.
        +In versions up to OpenSSL 0.9.4, B<callback(1, ...)> was called
        +in the inner loop of the Miller-Rabin test whenever it reached the
        +squaring step (the parameters to B<callback> did not reveal how many
        +witnesses had been tested); since OpenSSL 0.9.5, B<callback(1, ...)>
        +is called as in BN_is_prime(3), i.e. once for each witness.
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_get_ex_new_index.pod b/vendor/openssl/openssl/doc/crypto/DSA_get_ex_new_index.pod
        new file mode 100644
        index 000000000..fb6efc118
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_get_ex_new_index.pod
        @@ -0,0 +1,36 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_get_ex_new_index, DSA_set_ex_data, DSA_get_ex_data - add application specific data to DSA structures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + int DSA_get_ex_new_index(long argl, void *argp,
        +		CRYPTO_EX_new *new_func,
        +		CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func);
        +
        + int DSA_set_ex_data(DSA *d, int idx, void *arg);
        +
        + char *DSA_get_ex_data(DSA *d, int idx);
        +
        +=head1 DESCRIPTION
        +
        +These functions handle application specific data in DSA
        +structures. Their usage is identical to that of
        +RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data()
        +as described in L<RSA_get_ex_new_index(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>, L<dsa(3)|dsa(3)>
        +
        +=head1 HISTORY
        +
        +DSA_get_ex_new_index(), DSA_set_ex_data() and DSA_get_ex_data() are
        +available since OpenSSL 0.9.5.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_new.pod b/vendor/openssl/openssl/doc/crypto/DSA_new.pod
        new file mode 100644
        index 000000000..48e9b82a0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_new.pod
        @@ -0,0 +1,42 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_new, DSA_free - allocate and free DSA objects
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + DSA* DSA_new(void);
        +
        + void DSA_free(DSA *dsa);
        +
        +=head1 DESCRIPTION
        +
        +DSA_new() allocates and initializes a B<DSA> structure. It is equivalent to
        +calling DSA_new_method(NULL).
        +
        +DSA_free() frees the B<DSA> structure and its components. The values are
        +erased before the memory is returned to the system.
        +
        +=head1 RETURN VALUES
        +
        +If the allocation fails, DSA_new() returns B<NULL> and sets an error
        +code that can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns a pointer
        +to the newly allocated structure.
        +
        +DSA_free() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>,
        +L<DSA_generate_key(3)|DSA_generate_key(3)>
        +
        +=head1 HISTORY
        +
        +DSA_new() and DSA_free() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_set_method.pod b/vendor/openssl/openssl/doc/crypto/DSA_set_method.pod
        new file mode 100644
        index 000000000..9c1434bd8
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_set_method.pod
        @@ -0,0 +1,143 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_set_default_method, DSA_get_default_method,
        +DSA_set_method, DSA_new_method, DSA_OpenSSL - select DSA method
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        + #include <openssl/engine.h>
        +
        + void DSA_set_default_method(const DSA_METHOD *meth);
        +
        + const DSA_METHOD *DSA_get_default_method(void);
        +
        + int DSA_set_method(DSA *dsa, const DSA_METHOD *meth);
        +
        + DSA *DSA_new_method(ENGINE *engine);
        +
        + DSA_METHOD *DSA_OpenSSL(void);
        +
        +=head1 DESCRIPTION
        +
        +A B<DSA_METHOD> specifies the functions that OpenSSL uses for DSA
        +operations. By modifying the method, alternative implementations
        +such as hardware accelerators may be used. IMPORTANT: See the NOTES section for
        +important information about how these DSA API functions are affected by the use
        +of B<ENGINE> API calls.
        +
        +Initially, the default DSA_METHOD is the OpenSSL internal implementation,
        +as returned by DSA_OpenSSL().
        +
        +DSA_set_default_method() makes B<meth> the default method for all DSA
        +structures created later. B<NB>: This is true only whilst no ENGINE has
        +been set as a default for DSA, so this function is no longer recommended.
        +
        +DSA_get_default_method() returns a pointer to the current default
        +DSA_METHOD. However, the meaningfulness of this result is dependent on
        +whether the ENGINE API is being used, so this function is no longer 
        +recommended.
        +
        +DSA_set_method() selects B<meth> to perform all operations using the key
        +B<rsa>. This will replace the DSA_METHOD used by the DSA key and if the
        +previous method was supplied by an ENGINE, the handle to that ENGINE will
        +be released during the change. It is possible to have DSA keys that only
        +work with certain DSA_METHOD implementations (eg. from an ENGINE module
        +that supports embedded hardware-protected keys), and in such cases
        +attempting to change the DSA_METHOD for the key can have unexpected
        +results.
        +
        +DSA_new_method() allocates and initializes a DSA structure so that B<engine>
        +will be used for the DSA operations. If B<engine> is NULL, the default engine
        +for DSA operations is used, and if no default ENGINE is set, the DSA_METHOD
        +controlled by DSA_set_default_method() is used.
        +
        +=head1 THE DSA_METHOD STRUCTURE
        +
        +struct
        + {
        +     /* name of the implementation */
        +        const char *name;
        +
        +     /* sign */
        +	DSA_SIG *(*dsa_do_sign)(const unsigned char *dgst, int dlen,
        +                                 DSA *dsa);
        +
        +     /* pre-compute k^-1 and r */
        +	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
        +                                 BIGNUM **rp);
        +
        +     /* verify */
        +	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
        +                                 DSA_SIG *sig, DSA *dsa);
        +
        +     /* compute rr = a1^p1 * a2^p2 mod m (May be NULL for some
        +                                          implementations) */
        +	int (*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);
        +
        +     /* compute r = a ^ p mod m (May be NULL for some implementations) */
        +        int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +                                 const BIGNUM *p, const BIGNUM *m,
        +                                 BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +
        +     /* called at DSA_new */
        +        int (*init)(DSA *DSA);
        +
        +     /* called at DSA_free */
        +        int (*finish)(DSA *DSA);
        +
        +        int flags;
        +
        +        char *app_data; /* ?? */
        +
        + } DSA_METHOD;
        +
        +=head1 RETURN VALUES
        +
        +DSA_OpenSSL() and DSA_get_default_method() return pointers to the respective
        +B<DSA_METHOD>s.
        +
        +DSA_set_default_method() returns no value.
        +
        +DSA_set_method() returns non-zero if the provided B<meth> was successfully set as
        +the method for B<dsa> (including unloading the ENGINE handle if the previous
        +method was supplied by an ENGINE).
        +
        +DSA_new_method() returns NULL and sets an error code that can be
        +obtained by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation
        +fails. Otherwise it returns a pointer to the newly allocated structure.
        +
        +=head1 NOTES
        +
        +As of version 0.9.7, DSA_METHOD implementations are grouped together with other
        +algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B<ENGINE> modules. If a
        +default ENGINE is specified for DSA functionality using an ENGINE API function,
        +that will override any DSA defaults set using the DSA API (ie.
        +DSA_set_default_method()). For this reason, the ENGINE API is the recommended way
        +to control default implementations for use in DSA and other cryptographic
        +algorithms.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<DSA_new(3)|DSA_new(3)>
        +
        +=head1 HISTORY
        +
        +DSA_set_default_method(), DSA_get_default_method(), DSA_set_method(),
        +DSA_new_method() and DSA_OpenSSL() were added in OpenSSL 0.9.4.
        +
        +DSA_set_default_openssl_method() and DSA_get_default_openssl_method() replaced
        +DSA_set_default_method() and DSA_get_default_method() respectively, and
        +DSA_set_method() and DSA_new_method() were altered to use B<ENGINE>s rather than
        +B<DSA_METHOD>s during development of the engine version of OpenSSL 0.9.6. For
        +0.9.7, the handling of defaults in the ENGINE API was restructured so that this
        +change was reversed, and behaviour of the other functions resembled more closely
        +the previous behaviour. The behaviour of defaults in the ENGINE API now
        +transparently overrides the behaviour of defaults in the DSA API without
        +requiring changing these function prototypes.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_sign.pod b/vendor/openssl/openssl/doc/crypto/DSA_sign.pod
        new file mode 100644
        index 000000000..97389e8ec
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_sign.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_sign, DSA_sign_setup, DSA_verify - DSA signatures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + int	DSA_sign(int type, const unsigned char *dgst, int len,
        +		unsigned char *sigret, unsigned int *siglen, DSA *dsa);
        +
        + int	DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp,
        +                BIGNUM **rp);
        +
        + int	DSA_verify(int type, const unsigned char *dgst, int len,
        +		unsigned char *sigbuf, int siglen, DSA *dsa);
        +
        +=head1 DESCRIPTION
        +
        +DSA_sign() computes a digital signature on the B<len> byte message
        +digest B<dgst> using the private key B<dsa> and places its ASN.1 DER
        +encoding at B<sigret>. The length of the signature is places in
        +*B<siglen>. B<sigret> must point to DSA_size(B<dsa>) bytes of memory.
        +
        +DSA_sign_setup() may be used to precompute part of the signing
        +operation in case signature generation is time-critical. It expects
        +B<dsa> to contain DSA parameters. It places the precomputed values
        +in newly allocated B<BIGNUM>s at *B<kinvp> and *B<rp>, after freeing
        +the old ones unless *B<kinvp> and *B<rp> are NULL. These values may
        +be passed to DSA_sign() in B<dsa-E<gt>kinv> and B<dsa-E<gt>r>.
        +B<ctx> is a pre-allocated B<BN_CTX> or NULL.
        +
        +DSA_verify() verifies that the signature B<sigbuf> of size B<siglen>
        +matches a given message digest B<dgst> of size B<len>.
        +B<dsa> is the signer's public key.
        +
        +The B<type> parameter is ignored.
        +
        +The PRNG must be seeded before DSA_sign() (or DSA_sign_setup())
        +is called.
        +
        +=head1 RETURN VALUES
        +
        +DSA_sign() and DSA_sign_setup() return 1 on success, 0 on error.
        +DSA_verify() returns 1 for a valid signature, 0 for an incorrect
        +signature and -1 on error. The error codes can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 CONFORMING TO
        +
        +US Federal Information Processing Standard FIPS 186 (Digital Signature
        +Standard, DSS), ANSI X9.30
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>,
        +L<DSA_do_sign(3)|DSA_do_sign(3)>
        +
        +=head1 HISTORY
        +
        +DSA_sign() and DSA_verify() are available in all versions of SSLeay.
        +DSA_sign_setup() was added in SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/DSA_size.pod b/vendor/openssl/openssl/doc/crypto/DSA_size.pod
        new file mode 100644
        index 000000000..ba4f65036
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/DSA_size.pod
        @@ -0,0 +1,33 @@
        +=pod
        +
        +=head1 NAME
        +
        +DSA_size - get DSA signature size
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        +
        + int DSA_size(const DSA *dsa);
        +
        +=head1 DESCRIPTION
        +
        +This function returns the size of an ASN.1 encoded DSA signature in
        +bytes. It can be used to determine how much memory must be allocated
        +for a DSA signature.
        +
        +B<dsa-E<gt>q> must not be B<NULL>.
        +
        +=head1 RETURN VALUE
        +
        +The size in bytes.
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<DSA_sign(3)|DSA_sign(3)>
        +
        +=head1 HISTORY
        +
        +DSA_size() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_GET_LIB.pod b/vendor/openssl/openssl/doc/crypto/ERR_GET_LIB.pod
        new file mode 100644
        index 000000000..2a129da03
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_GET_LIB.pod
        @@ -0,0 +1,51 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_GET_LIB, ERR_GET_FUNC, ERR_GET_REASON - get library, function and
        +reason code
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + int ERR_GET_LIB(unsigned long e);
        +
        + int ERR_GET_FUNC(unsigned long e);
        +
        + int ERR_GET_REASON(unsigned long e);
        +
        +=head1 DESCRIPTION
        +
        +The error code returned by ERR_get_error() consists of a library
        +number, function code and reason code. ERR_GET_LIB(), ERR_GET_FUNC()
        +and ERR_GET_REASON() can be used to extract these.
        +
        +The library number and function code describe where the error
        +occurred, the reason code is the information about what went wrong.
        +
        +Each sub-library of OpenSSL has a unique library number; function and
        +reason codes are unique within each sub-library.  Note that different
        +libraries may use the same value to signal different functions and
        +reasons.
        +
        +B<ERR_R_...> reason codes such as B<ERR_R_MALLOC_FAILURE> are globally
        +unique. However, when checking for sub-library specific reason codes,
        +be sure to also compare the library number.
        +
        +ERR_GET_LIB(), ERR_GET_FUNC() and ERR_GET_REASON() are macros.
        +
        +=head1 RETURN VALUES
        +
        +The library number, function code and reason code respectively.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +ERR_GET_LIB(), ERR_GET_FUNC() and ERR_GET_REASON() are available in
        +all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_clear_error.pod b/vendor/openssl/openssl/doc/crypto/ERR_clear_error.pod
        new file mode 100644
        index 000000000..566e1f4e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_clear_error.pod
        @@ -0,0 +1,29 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_clear_error - clear the error queue
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + void ERR_clear_error(void);
        +
        +=head1 DESCRIPTION
        +
        +ERR_clear_error() empties the current thread's error queue.
        +
        +=head1 RETURN VALUES
        +
        +ERR_clear_error() has no return value.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +ERR_clear_error() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_error_string.pod b/vendor/openssl/openssl/doc/crypto/ERR_error_string.pod
        new file mode 100644
        index 000000000..cdfa7fe1f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_error_string.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_error_string, ERR_error_string_n, ERR_lib_error_string,
        +ERR_func_error_string, ERR_reason_error_string - obtain human-readable
        +error message
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + char *ERR_error_string(unsigned long e, char *buf);
        + void ERR_error_string_n(unsigned long e, char *buf, size_t len);
        +
        + const char *ERR_lib_error_string(unsigned long e);
        + const char *ERR_func_error_string(unsigned long e);
        + const char *ERR_reason_error_string(unsigned long e);
        +
        +=head1 DESCRIPTION
        +
        +ERR_error_string() generates a human-readable string representing the
        +error code I<e>, and places it at I<buf>. I<buf> must be at least 120
        +bytes long. If I<buf> is B<NULL>, the error string is placed in a
        +static buffer.
        +ERR_error_string_n() is a variant of ERR_error_string() that writes
        +at most I<len> characters (including the terminating 0)
        +and truncates the string if necessary.
        +For ERR_error_string_n(), I<buf> may not be B<NULL>.
        +
        +The string will have the following format:
        +
        + error:[error code]:[library name]:[function name]:[reason string]
        +
        +I<error code> is an 8 digit hexadecimal number, I<library name>,
        +I<function name> and I<reason string> are ASCII text.
        +
        +ERR_lib_error_string(), ERR_func_error_string() and
        +ERR_reason_error_string() return the library name, function
        +name and reason string respectively.
        +
        +The OpenSSL error strings should be loaded by calling
        +L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)> or, for SSL
        +applications, L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
        +first.
        +If there is no text string registered for the given error code,
        +the error string will contain the numeric code.
        +
        +L<ERR_print_errors(3)|ERR_print_errors(3)> can be used to print
        +all error codes currently in the queue.
        +
        +=head1 RETURN VALUES
        +
        +ERR_error_string() returns a pointer to a static buffer containing the
        +string if I<buf> B<== NULL>, I<buf> otherwise.
        +
        +ERR_lib_error_string(), ERR_func_error_string() and
        +ERR_reason_error_string() return the strings, and B<NULL> if
        +none is registered for the error code.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
        +L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
        +L<ERR_print_errors(3)|ERR_print_errors(3)>
        +
        +=head1 HISTORY
        +
        +ERR_error_string() is available in all versions of SSLeay and OpenSSL.
        +ERR_error_string_n() was added in OpenSSL 0.9.6.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_get_error.pod b/vendor/openssl/openssl/doc/crypto/ERR_get_error.pod
        new file mode 100644
        index 000000000..34443045f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_get_error.pod
        @@ -0,0 +1,76 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_get_error, ERR_peek_error, ERR_peek_last_error,
        +ERR_get_error_line, ERR_peek_error_line, ERR_peek_last_error_line,
        +ERR_get_error_line_data, ERR_peek_error_line_data,
        +ERR_peek_last_error_line_data - obtain error code and data
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + unsigned long ERR_get_error(void);
        + unsigned long ERR_peek_error(void);
        + unsigned long ERR_peek_last_error(void);
        +
        + unsigned long ERR_get_error_line(const char **file, int *line);
        + unsigned long ERR_peek_error_line(const char **file, int *line);
        + unsigned long ERR_peek_last_error_line(const char **file, int *line);
        +
        + unsigned long ERR_get_error_line_data(const char **file, int *line,
        +         const char **data, int *flags);
        + unsigned long ERR_peek_error_line_data(const char **file, int *line,
        +         const char **data, int *flags);
        + unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
        +         const char **data, int *flags);
        +
        +=head1 DESCRIPTION
        +
        +ERR_get_error() returns the earliest error code from the thread's error
        +queue and removes the entry. This function can be called repeatedly
        +until there are no more error codes to return.
        +
        +ERR_peek_error() returns the earliest error code from the thread's
        +error queue without modifying it.
        +
        +ERR_peek_last_error() returns the latest error code from the thread's
        +error queue without modifying it.
        +
        +See L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> for obtaining information about
        +location and reason of the error, and
        +L<ERR_error_string(3)|ERR_error_string(3)> for human-readable error
        +messages.
        +
        +ERR_get_error_line(), ERR_peek_error_line() and
        +ERR_peek_last_error_line() are the same as the above, but they
        +additionally store the file name and line number where
        +the error occurred in *B<file> and *B<line>, unless these are B<NULL>.
        +
        +ERR_get_error_line_data(), ERR_peek_error_line_data() and
        +ERR_get_last_error_line_data() store additional data and flags
        +associated with the error code in *B<data>
        +and *B<flags>, unless these are B<NULL>. *B<data> contains a string
        +if *B<flags>&B<ERR_TXT_STRING>. If it has been allocated by OPENSSL_malloc(),
        +*B<flags>&B<ERR_TXT_MALLOCED> is true.
        +
        +=head1 RETURN VALUES
        +
        +The error code, or 0 if there is no error in the queue.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>,
        +L<ERR_GET_LIB(3)|ERR_GET_LIB(3)>
        +
        +=head1 HISTORY
        +
        +ERR_get_error(), ERR_peek_error(), ERR_get_error_line() and
        +ERR_peek_error_line() are available in all versions of SSLeay and
        +OpenSSL. ERR_get_error_line_data() and ERR_peek_error_line_data()
        +were added in SSLeay 0.9.0.
        +ERR_peek_last_error(), ERR_peek_last_error_line() and
        +ERR_peek_last_error_line_data() were added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_load_crypto_strings.pod b/vendor/openssl/openssl/doc/crypto/ERR_load_crypto_strings.pod
        new file mode 100644
        index 000000000..9bdec75a4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_load_crypto_strings.pod
        @@ -0,0 +1,46 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_load_crypto_strings, SSL_load_error_strings, ERR_free_strings -
        +load and free error strings
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + void ERR_load_crypto_strings(void);
        + void ERR_free_strings(void);
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_load_error_strings(void);
        +
        +=head1 DESCRIPTION
        +
        +ERR_load_crypto_strings() registers the error strings for all
        +B<libcrypto> functions. SSL_load_error_strings() does the same,
        +but also registers the B<libssl> error strings.
        +
        +One of these functions should be called before generating
        +textual error messages. However, this is not required when memory
        +usage is an issue.
        +
        +ERR_free_strings() frees all previously loaded error strings.
        +
        +=head1 RETURN VALUES
        +
        +ERR_load_crypto_strings(), SSL_load_error_strings() and
        +ERR_free_strings() return no values.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>
        +
        +=head1 HISTORY
        +
        +ERR_load_error_strings(), SSL_load_error_strings() and
        +ERR_free_strings() are available in all versions of SSLeay and
        +OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_load_strings.pod b/vendor/openssl/openssl/doc/crypto/ERR_load_strings.pod
        new file mode 100644
        index 000000000..5acdd0edb
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_load_strings.pod
        @@ -0,0 +1,54 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_load_strings, ERR_PACK, ERR_get_next_error_library - load
        +arbitrary error strings
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + void ERR_load_strings(int lib, ERR_STRING_DATA str[]);
        +
        + int ERR_get_next_error_library(void);
        +
        + unsigned long ERR_PACK(int lib, int func, int reason);
        +
        +=head1 DESCRIPTION
        +
        +ERR_load_strings() registers error strings for library number B<lib>.
        +
        +B<str> is an array of error string data:
        +
        + typedef struct ERR_string_data_st
        + {
        +        unsigned long error;
        +        char *string;
        + } ERR_STRING_DATA;
        +
        +The error code is generated from the library number and a function and
        +reason code: B<error> = ERR_PACK(B<lib>, B<func>, B<reason>).
        +ERR_PACK() is a macro.
        +
        +The last entry in the array is {0,0}.
        +
        +ERR_get_next_error_library() can be used to assign library numbers
        +to user libraries at runtime.
        +
        +=head1 RETURN VALUE
        +
        +ERR_load_strings() returns no value. ERR_PACK() return the error code.
        +ERR_get_next_error_library() returns a new library number.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)>
        +
        +=head1 HISTORY
        +
        +ERR_load_error_strings() and ERR_PACK() are available in all versions
        +of SSLeay and OpenSSL. ERR_get_next_error_library() was added in
        +SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_print_errors.pod b/vendor/openssl/openssl/doc/crypto/ERR_print_errors.pod
        new file mode 100644
        index 000000000..b100a5fa2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_print_errors.pod
        @@ -0,0 +1,51 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_print_errors, ERR_print_errors_fp - print error messages
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + void ERR_print_errors(BIO *bp);
        + void ERR_print_errors_fp(FILE *fp);
        +
        +=head1 DESCRIPTION
        +
        +ERR_print_errors() is a convenience function that prints the error
        +strings for all errors that OpenSSL has recorded to B<bp>, thus
        +emptying the error queue.
        +
        +ERR_print_errors_fp() is the same, except that the output goes to a
        +B<FILE>.
        +
        +
        +The error strings will have the following format:
        +
        + [pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message]
        +
        +I<error code> is an 8 digit hexadecimal number. I<library name>,
        +I<function name> and I<reason string> are ASCII text, as is I<optional
        +text message> if one was set for the respective error code.
        +
        +If there is no text string registered for the given error code,
        +the error string will contain the numeric code.
        +
        +=head1 RETURN VALUES
        +
        +ERR_print_errors() and ERR_print_errors_fp() return no values.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>,
        +L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
        +L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>
        +
        +=head1 HISTORY
        +
        +ERR_print_errors() and ERR_print_errors_fp()
        +are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_put_error.pod b/vendor/openssl/openssl/doc/crypto/ERR_put_error.pod
        new file mode 100644
        index 000000000..acd241fbe
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_put_error.pod
        @@ -0,0 +1,44 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_put_error, ERR_add_error_data - record an error
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + void ERR_put_error(int lib, int func, int reason, const char *file,
        +         int line);
        +
        + void ERR_add_error_data(int num, ...);
        +
        +=head1 DESCRIPTION
        +
        +ERR_put_error() adds an error code to the thread's error queue. It
        +signals that the error of reason code B<reason> occurred in function
        +B<func> of library B<lib>, in line number B<line> of B<file>.
        +This function is usually called by a macro.
        +
        +ERR_add_error_data() associates the concatenation of its B<num> string
        +arguments with the error code added last.
        +
        +L<ERR_load_strings(3)|ERR_load_strings(3)> can be used to register
        +error strings so that the application can a generate human-readable
        +error messages for the error code.
        +
        +=head1 RETURN VALUES
        +
        +ERR_put_error() and ERR_add_error_data() return
        +no values.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)>
        +
        +=head1 HISTORY
        +
        +ERR_put_error() is available in all versions of SSLeay and OpenSSL.
        +ERR_add_error_data() was added in SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_remove_state.pod b/vendor/openssl/openssl/doc/crypto/ERR_remove_state.pod
        new file mode 100644
        index 000000000..72925fb9f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_remove_state.pod
        @@ -0,0 +1,34 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_remove_state - free a thread's error queue
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + void ERR_remove_state(unsigned long pid);
        +
        +=head1 DESCRIPTION
        +
        +ERR_remove_state() frees the error queue associated with thread B<pid>.
        +If B<pid> == 0, the current thread will have its error queue removed.
        +
        +Since error queue data structures are allocated automatically for new
        +threads, they must be freed when threads are terminated in order to
        +avoid memory leaks.
        +
        +=head1 RETURN VALUE
        +
        +ERR_remove_state() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>
        +
        +=head1 HISTORY
        +
        +ERR_remove_state() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ERR_set_mark.pod b/vendor/openssl/openssl/doc/crypto/ERR_set_mark.pod
        new file mode 100644
        index 000000000..d3ca4f2e7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ERR_set_mark.pod
        @@ -0,0 +1,38 @@
        +=pod
        +
        +=head1 NAME
        +
        +ERR_set_mark, ERR_pop_to_mark - set marks and pop errors until mark
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + int ERR_set_mark(void);
        +
        + int ERR_pop_to_mark(void);
        +
        +=head1 DESCRIPTION
        +
        +ERR_set_mark() sets a mark on the current topmost error record if there
        +is one.
        +
        +ERR_pop_to_mark() will pop the top of the error stack until a mark is found.
        +The mark is then removed.  If there is no mark, the whole stack is removed.
        +
        +=head1 RETURN VALUES
        +
        +ERR_set_mark() returns 0 if the error stack is empty, otherwise 1.
        +
        +ERR_pop_to_mark() returns 0 if there was no mark in the error stack, which
        +implies that the stack became empty, otherwise 1.
        +
        +=head1 SEE ALSO
        +
        +L<err(3)|err(3)>
        +
        +=head1 HISTORY
        +
        +ERR_set_mark() and ERR_pop_to_mark() were added in OpenSSL 0.9.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_BytesToKey.pod b/vendor/openssl/openssl/doc/crypto/EVP_BytesToKey.pod
        new file mode 100644
        index 000000000..d375c46e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_BytesToKey.pod
        @@ -0,0 +1,67 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_BytesToKey - password based encryption routine
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
        +                       const unsigned char *salt,
        +                       const unsigned char *data, int datal, int count,
        +                       unsigned char *key,unsigned char *iv);
        +
        +=head1 DESCRIPTION
        +
        +EVP_BytesToKey() derives a key and IV from various parameters. B<type> is
        +the cipher to derive the key and IV for. B<md> is the message digest to use.
        +The B<salt> paramter is used as a salt in the derivation: it should point to
        +an 8 byte buffer or NULL if no salt is used. B<data> is a buffer containing
        +B<datal> bytes which is used to derive the keying data. B<count> is the
        +iteration count to use. The derived key and IV will be written to B<key>
        +and B<iv> respectively.
        +
        +=head1 NOTES
        +
        +A typical application of this function is to derive keying material for an
        +encryption algorithm from a password in the B<data> parameter.
        +
        +Increasing the B<count> parameter slows down the algorithm which makes it
        +harder for an attacker to peform a brute force attack using a large number
        +of candidate passwords.
        +
        +If the total key and IV length is less than the digest length and
        +B<MD5> is used then the derivation algorithm is compatible with PKCS#5 v1.5
        +otherwise a non standard extension is used to derive the extra data.
        +
        +Newer applications should use more standard algorithms such as PKCS#5
        +v2.0 for key derivation.
        +
        +=head1 KEY DERIVATION ALGORITHM
        +
        +The key and IV is derived by concatenating D_1, D_2, etc until
        +enough data is available for the key and IV. D_i is defined as:
        +
        +	D_i = HASH^count(D_(i-1) || data || salt)
        +
        +where || denotes concatentaion, D_0 is empty, HASH is the digest
        +algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data)
        +is HASH(HASH(data)) and so on.
        +
        +The initial bytes are used for the key and the subsequent bytes for
        +the IV.
        +
        +=head1 RETURN VALUES
        +
        +EVP_BytesToKey() returns the size of the derived key in bytes.
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>, L<rand(3)|rand(3)>,
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>
        +
        +=head1 HISTORY
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_DigestInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_DigestInit.pod
        new file mode 100644
        index 000000000..367691cc7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_DigestInit.pod
        @@ -0,0 +1,279 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_DigestInit_ex, EVP_DigestUpdate,
        +EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE,
        +EVP_MD_CTX_copy_ex, EVP_MD_CTX_copy, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size,
        +EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_type,
        +EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha224, EVP_sha256,
        +EVP_sha384, EVP_sha512, EVP_dss, EVP_dss1, EVP_mdc2,
        +EVP_ripemd160, EVP_get_digestbyname, EVP_get_digestbynid, EVP_get_digestbyobj -
        +EVP digest routines
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
        + EVP_MD_CTX *EVP_MD_CTX_create(void);
        +
        + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
        + int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
        + int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
        +        unsigned int *s);
        +
        + int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
        + void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
        +
        + int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
        +
        + int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
        + int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
        +        unsigned int *s);
        +
        + int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);  
        +
        + #define EVP_MAX_MD_SIZE 64	/* SHA512 */
        +
        + int EVP_MD_type(const EVP_MD *md);
        + int EVP_MD_pkey_type(const EVP_MD *md);	
        + int EVP_MD_size(const EVP_MD *md);
        + int EVP_MD_block_size(const EVP_MD *md);
        +
        + const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
        + #define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
        + #define EVP_MD_CTX_block_size(e)	EVP_MD_block_size((e)->digest)
        + #define EVP_MD_CTX_type(e)		EVP_MD_type((e)->digest)
        +
        + const EVP_MD *EVP_md_null(void);
        + const EVP_MD *EVP_md2(void);
        + const EVP_MD *EVP_md5(void);
        + const EVP_MD *EVP_sha(void);
        + const EVP_MD *EVP_sha1(void);
        + const EVP_MD *EVP_dss(void);
        + const EVP_MD *EVP_dss1(void);
        + const EVP_MD *EVP_mdc2(void);
        + const EVP_MD *EVP_ripemd160(void);
        +
        + const EVP_MD *EVP_sha224(void);
        + const EVP_MD *EVP_sha256(void);
        + const EVP_MD *EVP_sha384(void);
        + const EVP_MD *EVP_sha512(void);
        +
        + const EVP_MD *EVP_get_digestbyname(const char *name);
        + #define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
        + #define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
        +
        +=head1 DESCRIPTION
        +
        +The EVP digest routines are a high level interface to message digests.
        +
        +EVP_MD_CTX_init() initializes digest context B<ctx>.
        +
        +EVP_MD_CTX_create() allocates, initializes and returns a digest context.
        +
        +EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest
        +B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this
        +function. B<type> will typically be supplied by a functionsuch as EVP_sha1().
        +If B<impl> is NULL then the default implementation of digest B<type> is used.
        +
        +EVP_DigestUpdate() hashes B<cnt> bytes of data at B<d> into the
        +digest context B<ctx>. This function can be called several times on the
        +same B<ctx> to hash additional data.
        +
        +EVP_DigestFinal_ex() retrieves the digest value from B<ctx> and places
        +it in B<md>. If the B<s> parameter is not NULL then the number of
        +bytes of data written (i.e. the length of the digest) will be written
        +to the integer at B<s>, at most B<EVP_MAX_MD_SIZE> bytes will be written.
        +After calling EVP_DigestFinal_ex() no additional calls to EVP_DigestUpdate()
        +can be made, but EVP_DigestInit_ex() can be called to initialize a new
        +digest operation.
        +
        +EVP_MD_CTX_cleanup() cleans up digest context B<ctx>, it should be called
        +after a digest context is no longer needed.
        +
        +EVP_MD_CTX_destroy() cleans up digest context B<ctx> and frees up the
        +space allocated to it, it should be called only on a context created
        +using EVP_MD_CTX_create().
        +
        +EVP_MD_CTX_copy_ex() can be used to copy the message digest state from
        +B<in> to B<out>. This is useful if large amounts of data are to be
        +hashed which only differ in the last few bytes. B<out> must be initialized
        +before calling this function.
        +
        +EVP_DigestInit() behaves in the same way as EVP_DigestInit_ex() except
        +the passed context B<ctx> does not have to be initialized, and it always
        +uses the default digest implementation.
        +
        +EVP_DigestFinal() is similar to EVP_DigestFinal_ex() except the digest
        +context B<ctx> is automatically cleaned up.
        +
        +EVP_MD_CTX_copy() is similar to EVP_MD_CTX_copy_ex() except the destination
        +B<out> does not have to be initialized.
        +
        +EVP_MD_size() and EVP_MD_CTX_size() return the size of the message digest
        +when passed an B<EVP_MD> or an B<EVP_MD_CTX> structure, i.e. the size of the
        +hash.
        +
        +EVP_MD_block_size() and EVP_MD_CTX_block_size() return the block size of the
        +message digest when passed an B<EVP_MD> or an B<EVP_MD_CTX> structure.
        +
        +EVP_MD_type() and EVP_MD_CTX_type() return the NID of the OBJECT IDENTIFIER
        +representing the given message digest when passed an B<EVP_MD> structure.
        +For example EVP_MD_type(EVP_sha1()) returns B<NID_sha1>. This function is
        +normally used when setting ASN1 OIDs.
        +
        +EVP_MD_CTX_md() returns the B<EVP_MD> structure corresponding to the passed
        +B<EVP_MD_CTX>.
        +
        +EVP_MD_pkey_type() returns the NID of the public key signing algorithm associated
        +with this digest. For example EVP_sha1() is associated with RSA so this will
        +return B<NID_sha1WithRSAEncryption>. Since digests and signature algorithms
        +are no longer linked this function is only retained for compatibility
        +reasons.
        +
        +EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_sha224(), EVP_sha256(),
        +EVP_sha384(), EVP_sha512(), EVP_mdc2() and EVP_ripemd160() return B<EVP_MD>
        +structures for the MD2, MD5, SHA, SHA1, SHA224, SHA256, SHA384, SHA512, MDC2
        +and RIPEMD160 digest algorithms respectively. 
        +
        +EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest
        +algorithms but using DSS (DSA) for the signature algorithm. Note: there is 
        +no need to use these pseudo-digests in OpenSSL 1.0.0 and later, they are
        +however retained for compatibility.
        +
        +EVP_md_null() is a "null" message digest that does nothing: i.e. the hash it
        +returns is of zero length.
        +
        +EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj()
        +return an B<EVP_MD> structure when passed a digest name, a digest NID or
        +an ASN1_OBJECT structure respectively. The digest table must be initialized
        +using, for example, OpenSSL_add_all_digests() for these functions to work.
        +
        +=head1 RETURN VALUES
        +
        +EVP_DigestInit_ex(), EVP_DigestUpdate() and EVP_DigestFinal_ex() return 1 for
        +success and 0 for failure.
        +
        +EVP_MD_CTX_copy_ex() returns 1 if successful or 0 for failure.
        +
        +EVP_MD_type(), EVP_MD_pkey_type() and EVP_MD_type() return the NID of the
        +corresponding OBJECT IDENTIFIER or NID_undef if none exists.
        +
        +EVP_MD_size(), EVP_MD_block_size(), EVP_MD_CTX_size(e), EVP_MD_size(),
        +EVP_MD_CTX_block_size()	and EVP_MD_block_size() return the digest or block
        +size in bytes.
        +
        +EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_dss(),
        +EVP_dss1(), EVP_mdc2() and EVP_ripemd160() return pointers to the
        +corresponding EVP_MD structures.
        +
        +EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj()
        +return either an B<EVP_MD> structure or NULL if an error occurs.
        +
        +=head1 NOTES
        +
        +The B<EVP> interface to message digests should almost always be used in
        +preference to the low level interfaces. This is because the code then becomes
        +transparent to the digest used and much more flexible.
        +
        +New applications should use the SHA2 digest algorithms such as SHA256. 
        +The other digest algorithms are still in common use.
        +
        +For most applications the B<impl> parameter to EVP_DigestInit_ex() will be
        +set to NULL to use the default digest implementation.
        +
        +The functions EVP_DigestInit(), EVP_DigestFinal() and EVP_MD_CTX_copy() are 
        +obsolete but are retained to maintain compatibility with existing code. New
        +applications should use EVP_DigestInit_ex(), EVP_DigestFinal_ex() and 
        +EVP_MD_CTX_copy_ex() because they can efficiently reuse a digest context
        +instead of initializing and cleaning it up on each call and allow non default
        +implementations of digests to be specified.
        +
        +In OpenSSL 0.9.7 and later if digest contexts are not cleaned up after use
        +memory leaks will occur. 
        +
        +Stack allocation of EVP_MD_CTX structures is common, for example:
        +
        + EVP_MD_CTX mctx;
        + EVP_MD_CTX_init(&mctx);
        +
        +This will cause binary compatibility issues if the size of EVP_MD_CTX
        +structure changes (this will only happen with a major release of OpenSSL).
        +Applications wishing to avoid this should use EVP_MD_CTX_create() instead:
        +
        + EVP_MD_CTX *mctx;
        + mctx = EVP_MD_CTX_create();
        +
        +
        +=head1 EXAMPLE
        +
        +This example digests the data "Test Message\n" and "Hello World\n", using the
        +digest name passed on the command line.
        +
        + #include <stdio.h>
        + #include <openssl/evp.h>
        +
        + main(int argc, char *argv[])
        + {
        + EVP_MD_CTX *mdctx;
        + const EVP_MD *md;
        + char mess1[] = "Test Message\n";
        + char mess2[] = "Hello World\n";
        + unsigned char md_value[EVP_MAX_MD_SIZE];
        + int md_len, i;
        +
        + OpenSSL_add_all_digests();
        +
        + if(!argv[1]) {
        + 	printf("Usage: mdtest digestname\n");
        +	exit(1);
        + }
        +
        + md = EVP_get_digestbyname(argv[1]);
        +
        + if(!md) {
        + 	printf("Unknown message digest %s\n", argv[1]);
        +	exit(1);
        + }
        +
        + mdctx = EVP_MD_CTX_create();
        + EVP_DigestInit_ex(mdctx, md, NULL);
        + EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
        + EVP_DigestUpdate(mdctx, mess2, strlen(mess2));
        + EVP_DigestFinal_ex(mdctx, md_value, &md_len);
        + EVP_MD_CTX_destroy(mdctx);
        +
        + printf("Digest is: ");
        + for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);
        + printf("\n");
        + }
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
        +L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
        +L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
        +
        +=head1 HISTORY
        +
        +EVP_DigestInit(), EVP_DigestUpdate() and EVP_DigestFinal() are
        +available in all versions of SSLeay and OpenSSL.
        +
        +EVP_MD_CTX_init(), EVP_MD_CTX_create(), EVP_MD_CTX_copy_ex(),
        +EVP_MD_CTX_cleanup(), EVP_MD_CTX_destroy(), EVP_DigestInit_ex()
        +and EVP_DigestFinal_ex() were added in OpenSSL 0.9.7.
        +
        +EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(),
        +EVP_dss(), EVP_dss1(), EVP_mdc2() and EVP_ripemd160() were
        +changed to return truely const EVP_MD * in OpenSSL 0.9.7.
        +
        +The link between digests and signing algorithms was fixed in OpenSSL 1.0 and
        +later, so now EVP_sha1() can be used with RSA and DSA, there is no need to
        +use EVP_dss1() any more.
        +
        +OpenSSL 1.0 and later does not include the MD2 digest algorithm in the
        +default configuration due to its security weaknesses.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_DigestSignInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_DigestSignInit.pod
        new file mode 100644
        index 000000000..37d960e3b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_DigestSignInit.pod
        @@ -0,0 +1,87 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
        + int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
        + int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP signature routines are a high level interface to digital signatures.
        +
        +EVP_DigestSignInit() sets up signing context B<ctx> to use digest B<type> from
        +ENGINE B<impl> and private key B<pkey>. B<ctx> must be initialized with
        +EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
        +EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can
        +be used to set alternative signing options.
        +
        +EVP_DigestSignUpdate() hashes B<cnt> bytes of data at B<d> into the
        +signature context B<ctx>. This function can be called several times on the
        +same B<ctx> to include additional data. This function is currently implemented
        +usig a macro.
        +
        +EVP_DigestSignFinal() signs the data in B<ctx> places the signature in B<sig>.
        +If B<sig> is B<NULL> then the maximum size of the output buffer is written to
        +the B<siglen> parameter. If B<sig> is not B<NULL> then before the call the
        +B<siglen> parameter should contain the length of the B<sig> buffer, if the
        +call is successful the signature is written to B<sig> and the amount of data
        +written to B<siglen>.
        +
        +=head1 RETURN VALUES
        +
        +EVP_DigestSignInit() EVP_DigestSignUpdate() and EVP_DigestSignaFinal() return
        +1 for success and 0 or a negative value for failure. In particular a return
        +value of -2 indicates the operation is not supported by the public key
        +algorithm.
        +
        +The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 NOTES
        +
        +The B<EVP> interface to digital signatures should almost always be used in
        +preference to the low level interfaces. This is because the code then becomes
        +transparent to the algorithm used and much more flexible.
        +
        +In previous versions of OpenSSL there was a link between message digest types
        +and public key algorithms. This meant that "clone" digests such as EVP_dss1()
        +needed to be used to sign using SHA1 and DSA. This is no longer necessary and
        +the use of clone digest is now discouraged.
        +
        +For some key types and parameters the random number generator must be seeded
        +or the operation will fail. 
        +
        +The call to EVP_DigestSignFinal() internally finalizes a copy of the digest
        +context. This means that calls to EVP_DigestSignUpdate() and
        +EVP_DigestSignFinal() can be called later to digest and sign additional data.
        +
        +Since only a copy of the digest context is ever finalized the context must
        +be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
        +will occur.
        +
        +The use of EVP_PKEY_size() with these functions is discouraged because some
        +signature operations may have a signature length which depends on the
        +parameters set. As a result EVP_PKEY_size() would have to return a value
        +which indicates the maximum possible signature for any set of parameters.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_DigestVerifyInit(3)|EVP_DigestVerifyInit(3)>,
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
        +L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
        +L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
        +L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
        +
        +=head1 HISTORY
        +
        +EVP_DigestSignInit(), EVP_DigestSignUpdate() and EVP_DigestSignFinal() 
        +were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_DigestVerifyInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_DigestVerifyInit.pod
        new file mode 100644
        index 000000000..f22448897
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_DigestVerifyInit.pod
        @@ -0,0 +1,82 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signature verification functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
        +			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
        + int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
        + int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP signature routines are a high level interface to digital signatures.
        +
        +EVP_DigestVerifyInit() sets up verification context B<ctx> to use digest
        +B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be initialized
        +with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
        +EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this
        +can be used to set alternative verification options.
        +
        +EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
        +verification context B<ctx>. This function can be called several times on the
        +same B<ctx> to include additional data. This function is currently implemented
        +using a macro.
        +
        +EVP_DigestVerifyFinal() verifies the data in B<ctx> against the signature in
        +B<sig> of length B<siglen>.
        +
        +=head1 RETURN VALUES
        +
        +EVP_DigestVerifyInit() and EVP_DigestVerifyUpdate() return 1 for success and 0
        +or a negative value for failure. In particular a return value of -2 indicates
        +the operation is not supported by the public key algorithm.
        +
        +Unlike other functions the return value 0 from EVP_DigestVerifyFinal() only
        +indicates that the signature did not not verify successfully (that is tbs did
        +not match the original data or the signature was of invalid form) it is not an
        +indication of a more serious error.
        +
        +The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 NOTES
        +
        +The B<EVP> interface to digital signatures should almost always be used in
        +preference to the low level interfaces. This is because the code then becomes
        +transparent to the algorithm used and much more flexible.
        +
        +In previous versions of OpenSSL there was a link between message digest types
        +and public key algorithms. This meant that "clone" digests such as EVP_dss1()
        +needed to be used to sign using SHA1 and DSA. This is no longer necessary and
        +the use of clone digest is now discouraged.
        +
        +For some key types and parameters the random number generator must be seeded
        +or the operation will fail. 
        +
        +The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
        +context. This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can
        +be called later to digest and verify additional data.
        +
        +Since only a copy of the digest context is ever finalized the context must
        +be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
        +will occur.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_DigestSignInit(3)|EVP_DigestSignInit(3)>,
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
        +L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
        +L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
        +L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
        +
        +=head1 HISTORY
        +
        +EVP_DigestVerifyInit(), EVP_DigestVerifyUpdate() and EVP_DigestVerifyFinal() 
        +were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_EncryptInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_EncryptInit.pod
        new file mode 100644
        index 000000000..8271d3dfc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_EncryptInit.pod
        @@ -0,0 +1,511 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_CIPHER_CTX_init, EVP_EncryptInit_ex, EVP_EncryptUpdate,
        +EVP_EncryptFinal_ex, EVP_DecryptInit_ex, EVP_DecryptUpdate,
        +EVP_DecryptFinal_ex, EVP_CipherInit_ex, EVP_CipherUpdate,
        +EVP_CipherFinal_ex, EVP_CIPHER_CTX_set_key_length,
        +EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX_cleanup, EVP_EncryptInit,
        +EVP_EncryptFinal, EVP_DecryptInit, EVP_DecryptFinal,
        +EVP_CipherInit, EVP_CipherFinal, EVP_get_cipherbyname,
        +EVP_get_cipherbynid, EVP_get_cipherbyobj, EVP_CIPHER_nid,
        +EVP_CIPHER_block_size, EVP_CIPHER_key_length, EVP_CIPHER_iv_length,
        +EVP_CIPHER_flags, EVP_CIPHER_mode, EVP_CIPHER_type, EVP_CIPHER_CTX_cipher,
        +EVP_CIPHER_CTX_nid, EVP_CIPHER_CTX_block_size, EVP_CIPHER_CTX_key_length,
        +EVP_CIPHER_CTX_iv_length, EVP_CIPHER_CTX_get_app_data,
        +EVP_CIPHER_CTX_set_app_data, EVP_CIPHER_CTX_type, EVP_CIPHER_CTX_flags,
        +EVP_CIPHER_CTX_mode, EVP_CIPHER_param_to_asn1, EVP_CIPHER_asn1_to_param,
        +EVP_CIPHER_CTX_set_padding - EVP cipher routines
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
        +
        + int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +	 ENGINE *impl, unsigned char *key, unsigned char *iv);
        + int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl, unsigned char *in, int inl);
        + int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl);
        +
        + int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +	 ENGINE *impl, unsigned char *key, unsigned char *iv);
        + int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl, unsigned char *in, int inl);
        + int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
        +         int *outl);
        +
        + int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +         ENGINE *impl, unsigned char *key, unsigned char *iv, int enc);
        + int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl, unsigned char *in, int inl);
        + int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
        +         int *outl);
        +
        + int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +         unsigned char *key, unsigned char *iv);
        + int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl);
        +
        + int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +         unsigned char *key, unsigned char *iv);
        + int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
        +         int *outl);
        +
        + int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +         unsigned char *key, unsigned char *iv, int enc);
        + int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
        +         int *outl);
        +
        + int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);
        + int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
        + int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
        + int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
        +
        + const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
        + #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
        + #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
        +
        + #define EVP_CIPHER_nid(e)		((e)->nid)
        + #define EVP_CIPHER_block_size(e)	((e)->block_size)
        + #define EVP_CIPHER_key_length(e)	((e)->key_len)
        + #define EVP_CIPHER_iv_length(e)		((e)->iv_len)
        + #define EVP_CIPHER_flags(e)		((e)->flags)
        + #define EVP_CIPHER_mode(e)		((e)->flags) & EVP_CIPH_MODE)
        + int EVP_CIPHER_type(const EVP_CIPHER *ctx);
        +
        + #define EVP_CIPHER_CTX_cipher(e)	((e)->cipher)
        + #define EVP_CIPHER_CTX_nid(e)		((e)->cipher->nid)
        + #define EVP_CIPHER_CTX_block_size(e)	((e)->cipher->block_size)
        + #define EVP_CIPHER_CTX_key_length(e)	((e)->key_len)
        + #define EVP_CIPHER_CTX_iv_length(e)	((e)->cipher->iv_len)
        + #define EVP_CIPHER_CTX_get_app_data(e)	((e)->app_data)
        + #define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
        + #define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
        + #define EVP_CIPHER_CTX_flags(e)		((e)->cipher->flags)
        + #define EVP_CIPHER_CTX_mode(e)		((e)->cipher->flags & EVP_CIPH_MODE)
        +
        + int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
        + int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
        +
        +=head1 DESCRIPTION
        +
        +The EVP cipher routines are a high level interface to certain
        +symmetric ciphers.
        +
        +EVP_CIPHER_CTX_init() initializes cipher contex B<ctx>.
        +
        +EVP_EncryptInit_ex() sets up cipher context B<ctx> for encryption
        +with cipher B<type> from ENGINE B<impl>. B<ctx> must be initialized
        +before calling this function. B<type> is normally supplied
        +by a function such as EVP_des_cbc(). If B<impl> is NULL then the
        +default implementation is used. B<key> is the symmetric key to use
        +and B<iv> is the IV to use (if necessary), the actual number of bytes
        +used for the key and IV depends on the cipher. It is possible to set
        +all parameters to NULL except B<type> in an initial call and supply
        +the remaining parameters in subsequent calls, all of which have B<type>
        +set to NULL. This is done when the default cipher parameters are not
        +appropriate.
        +
        +EVP_EncryptUpdate() encrypts B<inl> bytes from the buffer B<in> and
        +writes the encrypted version to B<out>. This function can be called
        +multiple times to encrypt successive blocks of data. The amount
        +of data written depends on the block alignment of the encrypted data:
        +as a result the amount of data written may be anything from zero bytes
        +to (inl + cipher_block_size - 1) so B<outl> should contain sufficient
        +room. The actual number of bytes written is placed in B<outl>.
        +
        +If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts
        +the "final" data, that is any data that remains in a partial block.
        +It uses L<standard block padding|/NOTES> (aka PKCS padding). The encrypted
        +final data is written to B<out> which should have sufficient space for
        +one cipher block. The number of bytes written is placed in B<outl>. After
        +this function is called the encryption operation is finished and no further
        +calls to EVP_EncryptUpdate() should be made.
        +
        +If padding is disabled then EVP_EncryptFinal_ex() will not encrypt any more
        +data and it will return an error if any data remains in a partial block:
        +that is if the total data length is not a multiple of the block size. 
        +
        +EVP_DecryptInit_ex(), EVP_DecryptUpdate() and EVP_DecryptFinal_ex() are the
        +corresponding decryption operations. EVP_DecryptFinal() will return an
        +error code if padding is enabled and the final block is not correctly
        +formatted. The parameters and restrictions are identical to the encryption
        +operations except that if padding is enabled the decrypted data buffer B<out>
        +passed to EVP_DecryptUpdate() should have sufficient room for
        +(B<inl> + cipher_block_size) bytes unless the cipher block size is 1 in
        +which case B<inl> bytes is sufficient.
        +
        +EVP_CipherInit_ex(), EVP_CipherUpdate() and EVP_CipherFinal_ex() are
        +functions that can be used for decryption or encryption. The operation
        +performed depends on the value of the B<enc> parameter. It should be set
        +to 1 for encryption, 0 for decryption and -1 to leave the value unchanged
        +(the actual value of 'enc' being supplied in a previous call).
        +
        +EVP_CIPHER_CTX_cleanup() clears all information from a cipher context
        +and free up any allocated memory associate with it. It should be called
        +after all operations using a cipher are complete so sensitive information
        +does not remain in memory.
        +
        +EVP_EncryptInit(), EVP_DecryptInit() and EVP_CipherInit() behave in a
        +similar way to EVP_EncryptInit_ex(), EVP_DecryptInit_ex and
        +EVP_CipherInit_ex() except the B<ctx> paramter does not need to be
        +initialized and they always use the default cipher implementation.
        +
        +EVP_EncryptFinal(), EVP_DecryptFinal() and EVP_CipherFinal() behave in a
        +similar way to EVP_EncryptFinal_ex(), EVP_DecryptFinal_ex() and
        +EVP_CipherFinal_ex() except B<ctx> is automatically cleaned up 
        +after the call.
        +
        +EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
        +return an EVP_CIPHER structure when passed a cipher name, a NID or an
        +ASN1_OBJECT structure.
        +
        +EVP_CIPHER_nid() and EVP_CIPHER_CTX_nid() return the NID of a cipher when
        +passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX> structure.  The actual NID
        +value is an internal value which may not have a corresponding OBJECT
        +IDENTIFIER.
        +
        +EVP_CIPHER_CTX_set_padding() enables or disables padding. By default
        +encryption operations are padded using standard block padding and the
        +padding is checked and removed when decrypting. If the B<pad> parameter
        +is zero then no padding is performed, the total amount of data encrypted
        +or decrypted must then be a multiple of the block size or an error will
        +occur.
        +
        +EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key
        +length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>
        +structure. The constant B<EVP_MAX_KEY_LENGTH> is the maximum key length
        +for all ciphers. Note: although EVP_CIPHER_key_length() is fixed for a
        +given cipher, the value of EVP_CIPHER_CTX_key_length() may be different
        +for variable key length ciphers.
        +
        +EVP_CIPHER_CTX_set_key_length() sets the key length of the cipher ctx.
        +If the cipher is a fixed length cipher then attempting to set the key
        +length to any value other than the fixed value is an error.
        +
        +EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV
        +length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>.
        +It will return zero if the cipher does not use an IV.  The constant
        +B<EVP_MAX_IV_LENGTH> is the maximum IV length for all ciphers.
        +
        +EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block
        +size of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>
        +structure. The constant B<EVP_MAX_IV_LENGTH> is also the maximum block
        +length for all ciphers.
        +
        +EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the type of the passed
        +cipher or context. This "type" is the actual NID of the cipher OBJECT
        +IDENTIFIER as such it ignores the cipher parameters and 40 bit RC2 and
        +128 bit RC2 have the same NID. If the cipher does not have an object
        +identifier or does not have ASN1 support this function will return
        +B<NID_undef>.
        +
        +EVP_CIPHER_CTX_cipher() returns the B<EVP_CIPHER> structure when passed
        +an B<EVP_CIPHER_CTX> structure.
        +
        +EVP_CIPHER_mode() and EVP_CIPHER_CTX_mode() return the block cipher mode:
        +EVP_CIPH_ECB_MODE, EVP_CIPH_CBC_MODE, EVP_CIPH_CFB_MODE or
        +EVP_CIPH_OFB_MODE. If the cipher is a stream cipher then
        +EVP_CIPH_STREAM_CIPHER is returned.
        +
        +EVP_CIPHER_param_to_asn1() sets the AlgorithmIdentifier "parameter" based
        +on the passed cipher. This will typically include any parameters and an
        +IV. The cipher IV (if any) must be set when this call is made. This call
        +should be made before the cipher is actually "used" (before any
        +EVP_EncryptUpdate(), EVP_DecryptUpdate() calls for example). This function
        +may fail if the cipher does not have any ASN1 support.
        +
        +EVP_CIPHER_asn1_to_param() sets the cipher parameters based on an ASN1
        +AlgorithmIdentifier "parameter". The precise effect depends on the cipher
        +In the case of RC2, for example, it will set the IV and effective key length.
        +This function should be called after the base cipher type is set but before
        +the key is set. For example EVP_CipherInit() will be called with the IV and
        +key set to NULL, EVP_CIPHER_asn1_to_param() will be called and finally
        +EVP_CipherInit() again with all parameters except the key set to NULL. It is
        +possible for this function to fail if the cipher does not have any ASN1 support
        +or the parameters cannot be set (for example the RC2 effective key length
        +is not supported.
        +
        +EVP_CIPHER_CTX_ctrl() allows various cipher specific parameters to be determined
        +and set. Currently only the RC2 effective key length and the number of rounds of
        +RC5 can be set.
        +
        +=head1 RETURN VALUES
        +
        +EVP_EncryptInit_ex(), EVP_EncryptUpdate() and EVP_EncryptFinal_ex()
        +return 1 for success and 0 for failure.
        +
        +EVP_DecryptInit_ex() and EVP_DecryptUpdate() return 1 for success and 0 for failure.
        +EVP_DecryptFinal_ex() returns 0 if the decrypt failed or 1 for success.
        +
        +EVP_CipherInit_ex() and EVP_CipherUpdate() return 1 for success and 0 for failure.
        +EVP_CipherFinal_ex() returns 0 for a decryption failure or 1 for success.
        +
        +EVP_CIPHER_CTX_cleanup() returns 1 for success and 0 for failure.
        +
        +EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
        +return an B<EVP_CIPHER> structure or NULL on error.
        +
        +EVP_CIPHER_nid() and EVP_CIPHER_CTX_nid() return a NID.
        +
        +EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block
        +size.
        +
        +EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key
        +length.
        +
        +EVP_CIPHER_CTX_set_padding() always returns 1.
        +
        +EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV
        +length or zero if the cipher does not use an IV.
        +
        +EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the NID of the cipher's
        +OBJECT IDENTIFIER or NID_undef if it has no defined OBJECT IDENTIFIER.
        +
        +EVP_CIPHER_CTX_cipher() returns an B<EVP_CIPHER> structure.
        +
        +EVP_CIPHER_param_to_asn1() and EVP_CIPHER_asn1_to_param() return 1 for 
        +success or zero for failure.
        +
        +=head1 CIPHER LISTING
        +
        +All algorithms have a fixed key length unless otherwise stated.
        +
        +=over 4
        +
        +=item EVP_enc_null()
        +
        +Null cipher: does nothing.
        +
        +=item EVP_des_cbc(void), EVP_des_ecb(void), EVP_des_cfb(void), EVP_des_ofb(void)
        +
        +DES in CBC, ECB, CFB and OFB modes respectively. 
        +
        +=item EVP_des_ede_cbc(void), EVP_des_ede(), EVP_des_ede_ofb(void),  EVP_des_ede_cfb(void)
        +
        +Two key triple DES in CBC, ECB, CFB and OFB modes respectively.
        +
        +=item EVP_des_ede3_cbc(void), EVP_des_ede3(), EVP_des_ede3_ofb(void),  EVP_des_ede3_cfb(void)
        +
        +Three key triple DES in CBC, ECB, CFB and OFB modes respectively.
        +
        +=item EVP_desx_cbc(void)
        +
        +DESX algorithm in CBC mode.
        +
        +=item EVP_rc4(void)
        +
        +RC4 stream cipher. This is a variable key length cipher with default key length 128 bits.
        +
        +=item EVP_rc4_40(void)
        +
        +RC4 stream cipher with 40 bit key length. This is obsolete and new code should use EVP_rc4()
        +and the EVP_CIPHER_CTX_set_key_length() function.
        +
        +=item EVP_idea_cbc() EVP_idea_ecb(void), EVP_idea_cfb(void), EVP_idea_ofb(void), EVP_idea_cbc(void)
        +
        +IDEA encryption algorithm in CBC, ECB, CFB and OFB modes respectively.
        +
        +=item EVP_rc2_cbc(void), EVP_rc2_ecb(void), EVP_rc2_cfb(void), EVP_rc2_ofb(void)
        +
        +RC2 encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key
        +length cipher with an additional parameter called "effective key bits" or "effective key length".
        +By default both are set to 128 bits.
        +
        +=item EVP_rc2_40_cbc(void), EVP_rc2_64_cbc(void)
        +
        +RC2 algorithm in CBC mode with a default key length and effective key length of 40 and 64 bits.
        +These are obsolete and new code should use EVP_rc2_cbc(), EVP_CIPHER_CTX_set_key_length() and
        +EVP_CIPHER_CTX_ctrl() to set the key length and effective key length.
        +
        +=item EVP_bf_cbc(void), EVP_bf_ecb(void), EVP_bf_cfb(void), EVP_bf_ofb(void);
        +
        +Blowfish encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key
        +length cipher.
        +
        +=item EVP_cast5_cbc(void), EVP_cast5_ecb(void), EVP_cast5_cfb(void), EVP_cast5_ofb(void)
        +
        +CAST encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key
        +length cipher.
        +
        +=item EVP_rc5_32_12_16_cbc(void), EVP_rc5_32_12_16_ecb(void), EVP_rc5_32_12_16_cfb(void), EVP_rc5_32_12_16_ofb(void)
        +
        +RC5 encryption algorithm in CBC, ECB, CFB and OFB modes respectively. This is a variable key length
        +cipher with an additional "number of rounds" parameter. By default the key length is set to 128
        +bits and 12 rounds.
        +
        +=back
        +
        +=head1 NOTES
        +
        +Where possible the B<EVP> interface to symmetric ciphers should be used in
        +preference to the low level interfaces. This is because the code then becomes
        +transparent to the cipher used and much more flexible.
        +
        +PKCS padding works by adding B<n> padding bytes of value B<n> to make the total 
        +length of the encrypted data a multiple of the block size. Padding is always
        +added so if the data is already a multiple of the block size B<n> will equal
        +the block size. For example if the block size is 8 and 11 bytes are to be
        +encrypted then 5 padding bytes of value 5 will be added.
        +
        +When decrypting the final block is checked to see if it has the correct form.
        +
        +Although the decryption operation can produce an error if padding is enabled,
        +it is not a strong test that the input data or key is correct. A random block
        +has better than 1 in 256 chance of being of the correct format and problems with
        +the input data earlier on will not produce a final decrypt error.
        +
        +If padding is disabled then the decryption operation will always succeed if
        +the total amount of data decrypted is a multiple of the block size.
        +
        +The functions EVP_EncryptInit(), EVP_EncryptFinal(), EVP_DecryptInit(),
        +EVP_CipherInit() and EVP_CipherFinal() are obsolete but are retained for
        +compatibility with existing code. New code should use EVP_EncryptInit_ex(),
        +EVP_EncryptFinal_ex(), EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(),
        +EVP_CipherInit_ex() and EVP_CipherFinal_ex() because they can reuse an
        +existing context without allocating and freeing it up on each call.
        +
        +=head1 BUGS
        +
        +For RC5 the number of rounds can currently only be set to 8, 12 or 16. This is
        +a limitation of the current RC5 code rather than the EVP interface.
        +
        +EVP_MAX_KEY_LENGTH and EVP_MAX_IV_LENGTH only refer to the internal ciphers with
        +default key lengths. If custom ciphers exceed these values the results are
        +unpredictable. This is because it has become standard practice to define a 
        +generic key as a fixed unsigned char array containing EVP_MAX_KEY_LENGTH bytes.
        +
        +The ASN1 code is incomplete (and sometimes inaccurate) it has only been tested
        +for certain common S/MIME ciphers (RC2, DES, triple DES) in CBC mode.
        +
        +=head1 EXAMPLES
        +
        +Get the number of rounds used in RC5:
        +
        + int nrounds;
        + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &nrounds);
        +
        +Get the RC2 effective key length:
        +
        + int key_bits;
        + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC2_KEY_BITS, 0, &key_bits);
        +
        +Set the number of rounds used in RC5:
        +
        + int nrounds;
        + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, nrounds, NULL);
        +
        +Set the effective key length used in RC2:
        +
        + int key_bits;
        + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
        +
        +Encrypt a string using blowfish:
        +
        + int do_crypt(char *outfile)
        + 	{
        +	unsigned char outbuf[1024];
        +	int outlen, tmplen;
        +	/* Bogus key and IV: we'd normally set these from
        +	 * another source.
        +	 */
        +	unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
        +	unsigned char iv[] = {1,2,3,4,5,6,7,8};
        +	char intext[] = "Some Crypto Text";
        +	EVP_CIPHER_CTX ctx;
        +	FILE *out;
        +	EVP_CIPHER_CTX_init(&ctx);
        +	EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv);
        +
        +	if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext)))
        +		{
        +		/* Error */
        +		return 0;
        +		}
        +	/* Buffer passed to EVP_EncryptFinal() must be after data just
        +	 * encrypted to avoid overwriting it.
        +	 */
        +	if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen))
        +		{
        +		/* Error */
        +		return 0;
        +		}
        +	outlen += tmplen;
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	/* Need binary mode for fopen because encrypted data is
        +	 * binary data. Also cannot use strlen() on it because
        +         * it wont be null terminated and may contain embedded
        +	 * nulls.
        +	 */
        +	out = fopen(outfile, "wb");
        +	fwrite(outbuf, 1, outlen, out);
        +	fclose(out);
        +	return 1;
        +	}
        +
        +The ciphertext from the above example can be decrypted using the B<openssl>
        +utility with the command line:
        + 
        + S<openssl bf -in cipher.bin -K 000102030405060708090A0B0C0D0E0F -iv 0102030405060708 -d>
        +
        +General encryption, decryption function example using FILE I/O and RC2 with an
        +80 bit key:
        +
        + int do_crypt(FILE *in, FILE *out, int do_encrypt)
        + 	{
        +	/* Allow enough space in output buffer for additional block */
        +	inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
        +	int inlen, outlen;
        +	/* Bogus key and IV: we'd normally set these from
        +	 * another source.
        +	 */
        +	unsigned char key[] = "0123456789";
        +	unsigned char iv[] = "12345678";
        +	/* Don't set key or IV because we will modify the parameters */
        +	EVP_CIPHER_CTX_init(&ctx);
        +	EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);
        +	EVP_CIPHER_CTX_set_key_length(&ctx, 10);
        +	/* We finished modifying parameters so now we can set key and IV */
        +	EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
        +
        +	for(;;) 
        +		{
        +		inlen = fread(inbuf, 1, 1024, in);
        +		if(inlen <= 0) break;
        +		if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
        +			{
        +			/* Error */
        +			EVP_CIPHER_CTX_cleanup(&ctx);
        +			return 0;
        +			}
        +		fwrite(outbuf, 1, outlen, out);
        +		}
        +	if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
        +		{
        +		/* Error */
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +		return 0;
        +		}
        +	fwrite(outbuf, 1, outlen, out);
        +
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	return 1;
        +	}
        +
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>
        +
        +=head1 HISTORY
        +
        +EVP_CIPHER_CTX_init(), EVP_EncryptInit_ex(), EVP_EncryptFinal_ex(),
        +EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(), EVP_CipherInit_ex(),
        +EVP_CipherFinal_ex() and EVP_CIPHER_CTX_set_padding() appeared in
        +OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_OpenInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_OpenInit.pod
        new file mode 100644
        index 000000000..2e710da94
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_OpenInit.pod
        @@ -0,0 +1,63 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_OpenInit, EVP_OpenUpdate, EVP_OpenFinal - EVP envelope decryption
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek,
        +		int ekl,unsigned char *iv,EVP_PKEY *priv);
        + int EVP_OpenUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl, unsigned char *in, int inl);
        + int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl);
        +
        +=head1 DESCRIPTION
        +
        +The EVP envelope routines are a high level interface to envelope
        +decryption. They decrypt a public key encrypted symmetric key and
        +then decrypt data using it.
        +
        +EVP_OpenInit() initializes a cipher context B<ctx> for decryption
        +with cipher B<type>. It decrypts the encrypted symmetric key of length
        +B<ekl> bytes passed in the B<ek> parameter using the private key B<priv>.
        +The IV is supplied in the B<iv> parameter.
        +
        +EVP_OpenUpdate() and EVP_OpenFinal() have exactly the same properties
        +as the EVP_DecryptUpdate() and EVP_DecryptFinal() routines, as 
        +documented on the L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> manual
        +page.
        +
        +=head1 NOTES
        +
        +It is possible to call EVP_OpenInit() twice in the same way as
        +EVP_DecryptInit(). The first call should have B<priv> set to NULL
        +and (after setting any cipher parameters) it should be called again
        +with B<type> set to NULL.
        +
        +If the cipher passed in the B<type> parameter is a variable length
        +cipher then the key length will be set to the value of the recovered
        +key length. If the cipher is a fixed length cipher then the recovered
        +key length must match the fixed cipher length.
        +
        +=head1 RETURN VALUES
        +
        +EVP_OpenInit() returns 0 on error or a non zero integer (actually the
        +recovered secret key size) if successful.
        +
        +EVP_OpenUpdate() returns 1 for success or 0 for failure.
        +
        +EVP_OpenFinal() returns 0 if the decrypt failed or 1 for success.
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>, L<rand(3)|rand(3)>,
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>,
        +L<EVP_SealInit(3)|EVP_SealInit(3)>
        +
        +=head1 HISTORY
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
        new file mode 100644
        index 000000000..13b91f1e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
        @@ -0,0 +1,128 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_ctrl, EVP_PKEY_ctrl_str - algorithm specific control operations
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
        +				int cmd, int p1, void *p2);
        + int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
        +						const char *value);
        +
        + int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
        +
        + #include <openssl/rsa.h>
        +
        + int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
        +
        + int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad);
        + int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len);
        + int EVP_PKEY_CTX_set_rsa_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits);
        + int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
        +
        + #include <openssl/dsa.h>
        + int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
        +
        + #include <openssl/dh.h>
        + int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len);
        + int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen);
        +
        + #include <openssl/ec.h>
        + int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
        +
        +=head1 DESCRIPTION
        +
        +The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
        +B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter
        +B<optype> is a mask indicating which operations the control can be applied to.
        +The control command is indicated in B<cmd> and any additional arguments in
        +B<p1> and B<p2>.
        +
        +Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will
        +instead call one of the algorithm specific macros below.
        +
        +The function EVP_PKEY_ctrl_str() allows an application to send an algorithm
        +specific control operation to a context B<ctx> in string form. This is
        +intended to be used for options specified on the command line or in text
        +files. The commands supported are documented in the openssl utility
        +command line pages for the option B<-pkeyopt> which is supported by the
        +B<pkeyutl>, B<genpkey> and B<req> commands.
        +
        +All the remaining "functions" are implemented as macros.
        +
        +The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
        +in a signature. It can be used with any public key algorithm supporting
        +signature operations.
        +
        +The macro EVP_PKEY_CTX_set_rsa_padding() sets the RSA padding mode for B<ctx>.
        +The B<pad> parameter can take the value RSA_PKCS1_PADDING for PKCS#1 padding,
        +RSA_SSLV23_PADDING for SSLv23 padding, RSA_NO_PADDING for no padding,
        +RSA_PKCS1_OAEP_PADDING for OAEP padding (encrypt and decrypt only),
        +RSA_X931_PADDING for X9.31 padding (signature operations only) and 
        +RSA_PKCS1_PSS_PADDING (sign and verify only).
        +
        +Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md()
        +is used. If this macro is called for PKCS#1 padding the plaintext buffer is
        +an actual digest value and is encapsulated in a DigestInfo structure according
        +to PKCS#1 when signing and this structure is expected (and stripped off) when
        +verifying. If this control is not used with RSA and PKCS#1 padding then the
        +supplied data is used directly and not encapsulated. In the case of X9.31
        +padding for RSA the algorithm identifier byte is added or checked and removed
        +if this control is called. If it is not called then the first byte of the plaintext buffer is expected to be the algorithm identifier byte.
        +
        +The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to
        +B<len> as its name implies it is only supported for PSS padding.  Two special
        +values are supported: -1 sets the salt length to the digest length. When
        +signing -2 sets the salt length to the maximum permissible value. When
        +verifying -2 causes the salt length to be automatically determined based on the
        +B<PSS> block structure. If this macro is not called a salt length value of -2
        +is used by default.
        +
        +The EVP_PKEY_CTX_set_rsa_rsa_keygen_bits() macro sets the RSA key length for
        +RSA key genration to B<bits>. If not specified 1024 bits is used.
        +
        +The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value
        +for RSA key generation to B<pubexp> currently it should be an odd integer. The
        +B<pubexp> pointer is used internally by this function so it should not be 
        +modified or free after the call. If this macro is not called then 65537 is used.
        +
        +The macro EVP_PKEY_CTX_set_dsa_paramgen_bits() sets the number of bits used
        +for DSA parameter generation to B<bits>. If not specified 1024 is used.
        +
        +The macro EVP_PKEY_CTX_set_dh_paramgen_prime_len() sets the length of the DH
        +prime parameter B<p> for DH parameter generation. If this macro is not called
        +then 1024 is used.
        +
        +The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B<gen>
        +for DH parameter generation. If not specified 2 is used.
        +
        +The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter
        +generation to B<nid>. For EC parameter generation this macro must be called
        +or an error occurs because there is no default curve.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0
        +or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_CTX_new.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_CTX_new.pod
        new file mode 100644
        index 000000000..a9af86758
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_CTX_new.pod
        @@ -0,0 +1,52 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - public key algorithm context functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
        + EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
        + EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
        + void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_CTX_new() function allocates public key algorithm context using
        +the algorithm specified in B<pkey> and ENGINE B<e>.
        +
        +The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
        +using the algorithm specified by B<id> and ENGINE B<e>. It is normally used
        +when no B<EVP_PKEY> structure is associated with the operations, for example
        +during parameter generation of key genration for some algorithms.
        +
        +EVP_PKEY_CTX_dup() duplicates the context B<ctx>.
        +
        +EVP_PKEY_CTX_free() frees up the context B<ctx>.
        +
        +=head1 NOTES
        +
        +The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used
        +by the OpenSSL high level public key API. Contexts B<MUST NOT> be shared between
        +threads: that is it is not permissible to use the same context simultaneously
        +in two threads.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() returns either
        +the newly allocated B<EVP_PKEY_CTX> structure of B<NULL> if an error occurred.
        +
        +EVP_PKEY_CTX_free() does not return a value.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_new(3)|EVP_PKEY_new(3)>
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_cmp.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_cmp.pod
        new file mode 100644
        index 000000000..4f8185e36
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_cmp.pod
        @@ -0,0 +1,61 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_copy_parameters, EVP_PKEY_missing_parameters, EVP_PKEY_cmp_parameters, EVP_PKEY_cmp - public key parameter and comparison functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
        + int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
        +
        + int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
        + int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
        +
        +=head1 DESCRIPTION
        +
        +The function EVP_PKEY_missing_parameters() returns 1 if the public key
        +parameters of B<pkey> are missing and 0 if they are present or the algorithm
        +doesn't use parameters.
        +
        +The function EVP_PKEY_copy_parameters() copies the parameters from key
        +B<from> to key B<to>.
        +
        +The funcion EVP_PKEY_cmp_parameters() compares the parameters of keys
        +B<a> and B<b>.
        +
        +The funcion EVP_PKEY_cmp() compares the public key components and paramters
        +(if present) of keys B<a> and B<b>.
        +
        +=head1 NOTES
        +
        +The main purpose of the functions EVP_PKEY_missing_parameters() and
        +EVP_PKEY_copy_parameters() is to handle public keys in certificates where the
        +parameters are sometimes omitted from a public key if they are inherited from
        +the CA that signed it.
        +
        +Since OpenSSL private keys contain public key components too the function
        +EVP_PKEY_cmp() can also be used to determine if a private key matches
        +a public key.
        +
        +=head1 RETURN VALUES
        +
        +The function EVP_PKEY_missing_parameters() returns 1 if the public key
        +parameters of B<pkey> are missing and 0 if they are present or the algorithm
        +doesn't use parameters.
        +
        +These functions EVP_PKEY_copy_parameters() returns 1 for success and 0 for
        +failure.
        +
        +The function EVP_PKEY_cmp_parameters() and EVP_PKEY_cmp() return 1 if the
        +keys match, 0 if they don't match, -1 if the key types are different and
        +-2 if the operation is not supported.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod
        new file mode 100644
        index 000000000..847983237
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_decrypt.pod
        @@ -0,0 +1,93 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_decrypt_init, EVP_PKEY_decrypt - decrypt using a public key algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
        +			unsigned char *out, size_t *outlen,
        +			const unsigned char *in, size_t inlen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_decrypt_init() function initializes a public key algorithm
        +context using key B<pkey> for a decryption operation.
        +
        +The EVP_PKEY_decrypt() function performs a public key decryption operation
        +using B<ctx>. The data to be decrypted is specified using the B<in> and
        +B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output
        +buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then
        +before the call the B<outlen> parameter should contain the length of the
        +B<out> buffer, if the call is successful the decrypted data is written to
        +B<out> and the amount of data written to B<outlen>.
        +
        +=head1 NOTES
        +
        +After the call to EVP_PKEY_decrypt_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_decrypt() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0
        +or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Decrypt data using OAEP (for RSA keys):
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *out, *in;
        + size_t outlen, inlen; 
        + EVP_PKEY *key;
        + /* NB: assumes key in, inlen are already set up
        +  * and that key is an RSA private key
        +  */
        + ctx = EVP_PKEY_CTX_new(key);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_decrypt_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0)
        +	/* Error */
        +
        + /* Determine buffer length */
        + if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0)
        +	/* Error */
        +
        + out = OPENSSL_malloc(outlen);
        +
        + if (!out)
        +	/* malloc failure */
        + 
        + if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0)
        +	/* Error */
        +
        + /* Decrypted data is outlen bytes written to buffer out */
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod
        new file mode 100644
        index 000000000..27464be57
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_derive.pod
        @@ -0,0 +1,93 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_derive - derive public key algorithm shared secret.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
        + int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_derive_init() function initializes a public key algorithm
        +context using key B<pkey> for shared secret derivation.
        +
        +The EVP_PKEY_derive_set_peer() function sets the peer key: this will normally
        +be a public key.
        +
        +The EVP_PKEY_derive() derives a shared secret using B<ctx>.
        +If B<key> is B<NULL> then the maximum size of the output buffer is written to
        +the B<keylen> parameter. If B<key> is not B<NULL> then before the call the
        +B<keylen> parameter should contain the length of the B<key> buffer, if the call
        +is successful the shared secret is written to B<key> and the amount of data
        +written to B<keylen>.
        +
        +=head1 NOTES
        +
        +After the call to EVP_PKEY_derive_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_derive() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0
        +or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Derive shared secret (for example DH or EC keys):
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *skey;
        + size_t skeylen;
        + EVP_PKEY *pkey, *peerkey;
        + /* NB: assumes pkey, peerkey have been already set up */
        +
        + ctx = EVP_PKEY_CTX_new(pkey);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_derive_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0)
        +	/* Error */
        +
        + /* Determine buffer length */
        + if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0)
        +	/* Error */
        +
        + skey = OPENSSL_malloc(skeylen);
        +
        + if (!skey)
        +	/* malloc failure */
        + 
        + if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0)
        +	/* Error */
        +
        + /* Shared secret is skey bytes written to buffer skey */
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod
        new file mode 100644
        index 000000000..e495a8124
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_encrypt.pod
        @@ -0,0 +1,93 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_encrypt_init, EVP_PKEY_encrypt - encrypt using a public key algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
        +			unsigned char *out, size_t *outlen,
        +			const unsigned char *in, size_t inlen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_encrypt_init() function initializes a public key algorithm
        +context using key B<pkey> for an encryption operation.
        +
        +The EVP_PKEY_encrypt() function performs a public key encryption operation
        +using B<ctx>. The data to be encrypted is specified using the B<in> and
        +B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output
        +buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then
        +before the call the B<outlen> parameter should contain the length of the
        +B<out> buffer, if the call is successful the encrypted data is written to
        +B<out> and the amount of data written to B<outlen>.
        +
        +=head1 NOTES
        +
        +After the call to EVP_PKEY_encrypt_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_encrypt() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0
        +or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Encrypt data using OAEP (for RSA keys):
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *out, *in;
        + size_t outlen, inlen; 
        + EVP_PKEY *key;
        + /* NB: assumes key in, inlen are already set up
        +  * and that key is an RSA public key
        +  */
        + ctx = EVP_PKEY_CTX_new(key);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_encrypt_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0)
        +	/* Error */
        +
        + /* Determine buffer length */
        + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0)
        +	/* Error */
        +
        + out = OPENSSL_malloc(outlen);
        +
        + if (!out)
        +	/* malloc failure */
        + 
        + if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0)
        +	/* Error */
        +
        + /* Encrypted data is outlen bytes written to buffer out */
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
        new file mode 100644
        index 000000000..8ff597d44
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_get_default_digest_nid - get default signature digest
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        + int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_get_default_digest_nid() function sets B<pnid> to the default
        +message digest NID for the public key signature operations associated with key
        +B<pkey>.
        +
        +=head1 NOTES
        +
        +For all current standard OpenSSL public key algorithms SHA1 is returned.
        +
        +=head1 RETURN VALUES
        +
        +The EVP_PKEY_get_default_digest_nid() function returns 1 if the message digest
        +is advisory (that is other digests can be used) and 2 if it is mandatory (other
        +digests can not be used).  It returns 0 or a negative value for failure. In
        +particular a return value of -2 indicates the operation is not supported by the
        +public key algorithm.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +
        +=head1 HISTORY
        +
        +This function was first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod
        new file mode 100644
        index 000000000..fd431ace6
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_keygen.pod
        @@ -0,0 +1,161 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init, EVP_PKEY_paramgen, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb, EVP_PKEY_CTX_get_keygen_info, EVP_PKEVP_PKEY_CTX_set_app_data, EVP_PKEY_CTX_get_app_data - key and parameter generation functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
        + int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
        +
        + typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
        +
        + void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
        + EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
        +
        + int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
        +
        + void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
        + void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_keygen_init() function initializes a public key algorithm
        +context using key B<pkey> for a key genration operation.
        +
        +The EVP_PKEY_keygen() function performs a key generation operation, the 
        +generated key is written to B<ppkey>.
        +
        +The functions EVP_PKEY_paramgen_init() and EVP_PKEY_paramgen() are similar
        +except parameters are generated.
        +
        +The function EVP_PKEY_set_cb() sets the key or parameter generation callback
        +to B<cb>. The function EVP_PKEY_CTX_get_cb() returns the key or parameter
        +generation callback.
        +
        +The function EVP_PKEY_CTX_get_keygen_info() returns parameters associated
        +with the generation operation. If B<idx> is -1 the total number of
        +parameters available is returned. Any non negative value returns the value of
        +that parameter. EVP_PKEY_CTX_gen_keygen_info() with a non-negative value for
        +B<idx> should only be called within the generation callback.
        +
        +If the callback returns 0 then the key genration operation is aborted and an
        +error occurs. This might occur during a time consuming operation where
        +a user clicks on a "cancel" button.
        +
        +The functions EVP_PKEY_CTX_set_app_data() and EVP_PKEY_CTX_get_app_data() set
        +and retrieve an opaque pointer. This can be used to set some application
        +defined value which can be retrieved in the callback: for example a handle
        +which is used to update a "progress dialog".
        +
        +=head1 NOTES
        +
        +After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init() algorithm
        +specific control operations can be performed to set any appropriate parameters
        +for the operation.
        +
        +The functions EVP_PKEY_keygen() and EVP_PKEY_paramgen() can be called more than
        +once on the same context if several operations are performed using the same
        +parameters.
        +
        +The meaning of the parameters passed to the callback will depend on the
        +algorithm and the specifiic implementation of the algorithm. Some might not
        +give any useful information at all during key or parameter generation. Others
        +might not even call the callback.
        +
        +The operation performed by key or parameter generation depends on the algorithm
        +used. In some cases (e.g. EC with a supplied named curve) the "generation"
        +option merely sets the appropriate fields in an EVP_PKEY structure.
        +
        +In OpenSSL an EVP_PKEY structure containing a private key also contains the
        +public key components and parameters (if any). An OpenSSL private key is
        +equivalent to what some libraries call a "key pair". A private key can be used
        +in functions which require the use of a public key or parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_keygen_init(), EVP_PKEY_paramgen_init(), EVP_PKEY_keygen() and
        +EVP_PKEY_paramgen() return 1 for success and 0 or a negative value for failure.
        +In particular a return value of -2 indicates the operation is not supported by
        +the public key algorithm.
        +
        +=head1 EXAMPLES
        +
        +Generate a 2048 bit RSA key:
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + EVP_PKEY *pkey = NULL;
        + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_keygen_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
        +	/* Error */
        +
        + /* Generate key */
        + if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
        +	/* Error */
        +
        +Generate a key from a set of parameters:
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + EVP_PKEY *pkey = NULL, *param;
        + /* Assumed param is set up already */
        + ctx = EVP_PKEY_CTX_new(param);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_keygen_init(ctx) <= 0)
        +	/* Error */
        +
        + /* Generate key */
        + if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
        +	/* Error */
        +
        +Example of generation callback for OpenSSL public key implementations:
        +
        + /* Application data is a BIO to output status to */
        +
        + EVP_PKEY_CTX_set_app_data(ctx, status_bio);
        +
        + static int genpkey_cb(EVP_PKEY_CTX *ctx)
        +	{
        +	char c='*';
        +	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
        +	int p;
        +	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(b,&c,1);
        +	(void)BIO_flush(b);
        +	return 1;
        +	}
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_new.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_new.pod
        new file mode 100644
        index 000000000..10687e458
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_new.pod
        @@ -0,0 +1,47 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_new, EVP_PKEY_free - private key allocation functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + EVP_PKEY *EVP_PKEY_new(void);
        + void EVP_PKEY_free(EVP_PKEY *key);
        +
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_new() function allocates an empty B<EVP_PKEY> 
        +structure which is used by OpenSSL to store private keys.
        +
        +EVP_PKEY_free() frees up the private key B<key>.
        +
        +=head1 NOTES
        +
        +The B<EVP_PKEY> structure is used by various OpenSSL functions
        +which require a general private key without reference to any
        +particular algorithm.
        +
        +The structure returned by EVP_PKEY_new() is empty. To add a
        +private key to this empty structure the functions described in
        +L<EVP_PKEY_set1_RSA(3)|EVP_PKEY_set1_RSA(3)> should be used.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_new() returns either the newly allocated B<EVP_PKEY>
        +structure of B<NULL> if an error occurred.
        +
        +EVP_PKEY_free() does not return a value.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_set1_RSA(3)|EVP_PKEY_set1_RSA(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_print_private.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_print_private.pod
        new file mode 100644
        index 000000000..ce9d70d7a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_print_private.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_print_public, EVP_PKEY_print_private, EVP_PKEY_print_params - public key algorithm printing routines.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx);
        + int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx);
        + int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
        +				int indent, ASN1_PCTX *pctx);
        +
        +=head1 DESCRIPTION
        +
        +The functions EVP_PKEY_print_public(), EVP_PKEY_print_private() and
        +EVP_PKEY_print_params() print out the public, private or parameter components
        +of key B<pkey> respectively. The key is sent to BIO B<out> in human readable
        +form. The parameter B<indent> indicated how far the printout should be indented.
        +
        +The B<pctx> parameter allows the print output to be finely tuned by using
        +ASN1 printing options. If B<pctx> is set to NULL then default values will
        +be used.
        +
        +=head1 NOTES
        +
        +Currently no public key algorithms include any options in the B<pctx> parameter 
        +parameter.
        +
        +If the key does not include all the components indicated by the function then
        +only those contained in the key will be printed. For example passing a public
        +key to EVP_PKEY_print_private() will only print the public components.
        +
        +=head1 RETURN VALUES
        +
        +These functions all return 1 for success and 0 or a negative value for failure.
        +In particular a return value of -2 indicates the operation is not supported by
        +the public key algorithm.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod
        new file mode 100644
        index 000000000..2db692e27
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod
        @@ -0,0 +1,80 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY,
        +EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
        +EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY,
        +EVP_PKEY_type - EVP_PKEY assignment functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,RSA *key);
        + int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,DSA *key);
        + int EVP_PKEY_set1_DH(EVP_PKEY *pkey,DH *key);
        + int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,EC_KEY *key);
        +
        + RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
        + DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
        + DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
        + EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
        +
        + int EVP_PKEY_assign_RSA(EVP_PKEY *pkey,RSA *key);
        + int EVP_PKEY_assign_DSA(EVP_PKEY *pkey,DSA *key);
        + int EVP_PKEY_assign_DH(EVP_PKEY *pkey,DH *key);
        + int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey,EC_KEY *key);
        +
        + int EVP_PKEY_type(int type);
        +
        +=head1 DESCRIPTION
        +
        +EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
        +EVP_PKEY_set1_EC_KEY() set the key referenced by B<pkey> to B<key>.
        +
        +EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
        +EVP_PKEY_get1_EC_KEY() return the referenced key in B<pkey> or
        +B<NULL> if the key is not of the correct type.
        +
        +EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
        +and EVP_PKEY_assign_EC_KEY() also set the referenced key to B<key>
        +however these use the supplied B<key> internally and so B<key>
        +will be freed when the parent B<pkey> is freed.
        +
        +EVP_PKEY_type() returns the type of key corresponding to the value
        +B<type>. The type of a key can be obtained with
        +EVP_PKEY_type(pkey->type). The return value will be EVP_PKEY_RSA,
        +EVP_PKEY_DSA, EVP_PKEY_DH or EVP_PKEY_EC for the corresponding
        +key types or NID_undef if the key type is unassigned.
        +
        +=head1 NOTES
        +
        +In accordance with the OpenSSL naming convention the key obtained
        +from or assigned to the B<pkey> using the B<1> functions must be
        +freed as well as B<pkey>.
        +
        +EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
        +EVP_PKEY_assign_EC_KEY() are implemented as macros.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
        +EVP_PKEY_set1_EC_KEY() return 1 for success or 0 for failure.
        +
        +EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
        +EVP_PKEY_get1_EC_KEY() return the referenced key or B<NULL> if 
        +an error occurred.
        +
        +EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
        +and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_new(3)|EVP_PKEY_new(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod
        new file mode 100644
        index 000000000..a044f2c13
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_sign.pod
        @@ -0,0 +1,96 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
        +			unsigned char *sig, size_t *siglen,
        +			const unsigned char *tbs, size_t tbslen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_sign_init() function initializes a public key algorithm
        +context using key B<pkey> for a signing operation.
        +
        +The EVP_PKEY_sign() function performs a public key signing operation
        +using B<ctx>. The data to be signed is specified using the B<tbs> and
        +B<tbslen> parameters. If B<sig> is B<NULL> then the maximum size of the output
        +buffer is written to the B<siglen> parameter. If B<sig> is not B<NULL> then
        +before the call the B<siglen> parameter should contain the length of the
        +B<sig> buffer, if the call is successful the signature is written to
        +B<sig> and the amount of data written to B<siglen>.
        +
        +=head1 NOTES
        +
        +After the call to EVP_PKEY_sign_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_sign() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0
        +or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Sign data using RSA with PKCS#1 padding and SHA256 digest:
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *md, *sig;
        + size_t mdlen, siglen; 
        + EVP_PKEY *signing_key;
        + /* NB: assumes signing_key, md and mdlen are already set up
        +  * and that signing_key is an RSA private key
        +  */
        + ctx = EVP_PKEY_CTX_new(signing_key);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_sign_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
        +	/* Error */
        +
        + /* Determine buffer length */
        + if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0)
        +	/* Error */
        +
        + sig = OPENSSL_malloc(siglen);
        +
        + if (!sig)
        +	/* malloc failure */
        + 
        + if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0)
        +	/* Error */
        +
        + /* Signature is siglen bytes written to buffer sig */
        +
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod
        new file mode 100644
        index 000000000..90612ba2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verify.pod
        @@ -0,0 +1,91 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public key algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
        +			const unsigned char *sig, size_t siglen,
        +			const unsigned char *tbs, size_t tbslen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_verify_init() function initializes a public key algorithm
        +context using key B<pkey> for a signature verification operation.
        +
        +The EVP_PKEY_verify() function performs a public key verification operation
        +using B<ctx>. The signature is specified using the B<sig> and
        +B<siglen> parameters. The verified data (i.e. the data believed originally
        +signed) is specified using the B<tbs> and B<tbslen> parameters.
        +
        +=head1 NOTES
        +
        +After the call to EVP_PKEY_verify_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_verify() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_verify_init() and EVP_PKEY_verify() return 1 if the verification was
        +successful and 0 if it failed. Unlike other functions the return value 0 from
        +EVP_PKEY_verify() only indicates that the signature did not not verify
        +successfully (that is tbs did not match the original data or the signature was
        +of invalid form) it is not an indication of a more serious error.
        +
        +A negative value indicates an error other that signature verification failure.
        +In particular a return value of -2 indicates the operation is not supported by
        +the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Verify signature using PKCS#1 and SHA256 digest:
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *md, *sig;
        + size_t mdlen, siglen; 
        + EVP_PKEY *verify_key;
        + /* NB: assumes verify_key, sig, siglen md and mdlen are already set up
        +  * and that verify_key is an RSA public key
        +  */
        + ctx = EVP_PKEY_CTX_new(verify_key);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_verify_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
        +	/* Error */
        +
        + /* Perform operation */
        + ret = EVP_PKEY_verify(ctx, sig, siglen, md, mdlen);
        +
        + /* ret == 1 indicates success, 0 verify failure and < 0 for some
        +  * other error.
        +  */
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod
        new file mode 100644
        index 000000000..23a28a9c4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verify_recover.pod
        @@ -0,0 +1,103 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover - recover signature using a public key algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
        +			unsigned char *rout, size_t *routlen,
        +			const unsigned char *sig, size_t siglen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_verify_recover_init() function initializes a public key algorithm
        +context using key B<pkey> for a verify recover operation.
        +
        +The EVP_PKEY_verify_recover() function recovers signed data
        +using B<ctx>. The signature is specified using the B<sig> and
        +B<siglen> parameters. If B<rout> is B<NULL> then the maximum size of the output
        +buffer is written to the B<routlen> parameter. If B<rout> is not B<NULL> then
        +before the call the B<routlen> parameter should contain the length of the
        +B<rout> buffer, if the call is successful recovered data is written to
        +B<rout> and the amount of data written to B<routlen>.
        +
        +=head1 NOTES
        +
        +Normally an application is only interested in whether a signature verification
        +operation is successful in those cases the EVP_verify() function should be 
        +used.
        +
        +Sometimes however it is useful to obtain the data originally signed using a
        +signing operation. Only certain public key algorithms can recover a signature
        +in this way (for example RSA in PKCS padding mode).
        +
        +After the call to EVP_PKEY_verify_recover_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_verify_recover() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for success
        +and 0 or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Recover digest originally signed using PKCS#1 and SHA256 digest:
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *rout, *sig;
        + size_t routlen, siglen; 
        + EVP_PKEY *verify_key;
        + /* NB: assumes verify_key, sig and siglen are already set up
        +  * and that verify_key is an RSA public key
        +  */
        + ctx = EVP_PKEY_CTX_new(verify_key);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_verify_recover_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
        +	/* Error */
        +
        + /* Determine buffer length */
        + if (EVP_PKEY_verify_recover(ctx, NULL, &routlen, sig, siglen) <= 0)
        +	/* Error */
        +
        + rout = OPENSSL_malloc(routlen);
        +
        + if (!rout)
        +	/* malloc failure */
        + 
        + if (EVP_PKEY_verify_recover(ctx, rout, &routlen, sig, siglen) <= 0)
        +	/* Error */
        +
        + /* Recovered data is routlen bytes written to buffer rout */
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod
        new file mode 100644
        index 000000000..f3605eb82
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod
        @@ -0,0 +1,103 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_PKEY_verifyrecover_init, EVP_PKEY_verifyrecover - recover signature using a public key algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_PKEY_verifyrecover_init(EVP_PKEY_CTX *ctx);
        + int EVP_PKEY_verifyrecover(EVP_PKEY_CTX *ctx,
        +			unsigned char *rout, size_t *routlen,
        +			const unsigned char *sig, size_t siglen);
        +
        +=head1 DESCRIPTION
        +
        +The EVP_PKEY_verifyrecover_init() function initializes a public key algorithm
        +context using key B<pkey> for a verify recover operation.
        +
        +The EVP_PKEY_verifyrecover() function recovers signed data
        +using B<ctx>. The signature is specified using the B<sig> and
        +B<siglen> parameters. If B<rout> is B<NULL> then the maximum size of the output
        +buffer is written to the B<routlen> parameter. If B<rout> is not B<NULL> then
        +before the call the B<routlen> parameter should contain the length of the
        +B<rout> buffer, if the call is successful recovered data is written to
        +B<rout> and the amount of data written to B<routlen>.
        +
        +=head1 NOTES
        +
        +Normally an application is only interested in whether a signature verification
        +operation is successful in those cases the EVP_verify() function should be 
        +used.
        +
        +Sometimes however it is useful to obtain the data originally signed using a
        +signing operation. Only certain public key algorithms can recover a signature
        +in this way (for example RSA in PKCS padding mode).
        +
        +After the call to EVP_PKEY_verifyrecover_init() algorithm specific control
        +operations can be performed to set any appropriate parameters for the
        +operation.
        +
        +The function EVP_PKEY_verifyrecover() can be called more than once on the same
        +context if several operations are performed using the same parameters.
        +
        +=head1 RETURN VALUES
        +
        +EVP_PKEY_verifyrecover_init() and EVP_PKEY_verifyrecover() return 1 for success
        +and 0 or a negative value for failure. In particular a return value of -2
        +indicates the operation is not supported by the public key algorithm.
        +
        +=head1 EXAMPLE
        +
        +Recover digest originally signed using PKCS#1 and SHA256 digest:
        +
        + #include <openssl/evp.h>
        + #include <openssl/rsa.h>
        +
        + EVP_PKEY_CTX *ctx;
        + unsigned char *rout, *sig;
        + size_t routlen, siglen; 
        + EVP_PKEY *verify_key;
        + /* NB: assumes verify_key, sig and siglen are already set up
        +  * and that verify_key is an RSA public key
        +  */
        + ctx = EVP_PKEY_CTX_new(verify_key);
        + if (!ctx)
        +	/* Error occurred */
        + if (EVP_PKEY_verifyrecover_init(ctx) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
        +	/* Error */
        + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
        +	/* Error */
        +
        + /* Determine buffer length */
        + if (EVP_PKEY_verifyrecover(ctx, NULL, &routlen, sig, siglen) <= 0)
        +	/* Error */
        +
        + rout = OPENSSL_malloc(routlen);
        +
        + if (!rout)
        +	/* malloc failure */
        + 
        + if (EVP_PKEY_verifyrecover(ctx, rout, &routlen, sig, siglen) <= 0)
        +	/* Error */
        +
        + /* Recovered data is routlen bytes written to buffer rout */
        +
        +=head1 SEE ALSO
        +
        +L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
        +L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
        +L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
        +L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
        +L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
        +L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
        +
        +=head1 HISTORY
        +
        +These functions were first added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_SealInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_SealInit.pod
        new file mode 100644
        index 000000000..7d793e19e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_SealInit.pod
        @@ -0,0 +1,85 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_SealInit, EVP_SealUpdate, EVP_SealFinal - EVP envelope encryption
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        +                  unsigned char **ek, int *ekl, unsigned char *iv,
        +                  EVP_PKEY **pubk, int npubk);
        + int EVP_SealUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl, unsigned char *in, int inl);
        + int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +         int *outl);
        +
        +=head1 DESCRIPTION
        +
        +The EVP envelope routines are a high level interface to envelope
        +encryption. They generate a random key and IV (if required) then
        +"envelope" it by using public key encryption. Data can then be
        +encrypted using this key.
        +
        +EVP_SealInit() initializes a cipher context B<ctx> for encryption
        +with cipher B<type> using a random secret key and IV. B<type> is normally
        +supplied by a function such as EVP_des_cbc(). The secret key is encrypted
        +using one or more public keys, this allows the same encrypted data to be
        +decrypted using any of the corresponding private keys. B<ek> is an array of
        +buffers where the public key encrypted secret key will be written, each buffer
        +must contain enough room for the corresponding encrypted key: that is
        +B<ek[i]> must have room for B<EVP_PKEY_size(pubk[i])> bytes. The actual
        +size of each encrypted secret key is written to the array B<ekl>. B<pubk> is
        +an array of B<npubk> public keys.
        +
        +The B<iv> parameter is a buffer where the generated IV is written to. It must
        +contain enough room for the corresponding cipher's IV, as determined by (for
        +example) EVP_CIPHER_iv_length(type).
        +
        +If the cipher does not require an IV then the B<iv> parameter is ignored
        +and can be B<NULL>.
        +
        +EVP_SealUpdate() and EVP_SealFinal() have exactly the same properties
        +as the EVP_EncryptUpdate() and EVP_EncryptFinal() routines, as 
        +documented on the L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> manual
        +page. 
        +
        +=head1 RETURN VALUES
        +
        +EVP_SealInit() returns 0 on error or B<npubk> if successful.
        +
        +EVP_SealUpdate() and EVP_SealFinal() return 1 for success and 0 for
        +failure.
        +
        +=head1 NOTES
        +
        +Because a random secret key is generated the random number generator
        +must be seeded before calling EVP_SealInit().
        +
        +The public key must be RSA because it is the only OpenSSL public key
        +algorithm that supports key transport.
        +
        +Envelope encryption is the usual method of using public key encryption
        +on large amounts of data, this is because public key encryption is slow
        +but symmetric encryption is fast. So symmetric encryption is used for
        +bulk encryption and the small random symmetric key used is transferred
        +using public key encryption.
        +
        +It is possible to call EVP_SealInit() twice in the same way as
        +EVP_EncryptInit(). The first call should have B<npubk> set to 0
        +and (after setting any cipher parameters) it should be called again
        +with B<type> set to NULL.
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>, L<rand(3)|rand(3)>,
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>,
        +L<EVP_OpenInit(3)|EVP_OpenInit(3)>
        +
        +=head1 HISTORY
        +
        +EVP_SealFinal() did not return a value before OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_SignInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_SignInit.pod
        new file mode 100644
        index 000000000..620a623ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_SignInit.pod
        @@ -0,0 +1,104 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_SignInit, EVP_SignUpdate, EVP_SignFinal - EVP signing functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
        + int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
        + int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey);
        +
        + void EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);
        +
        + int EVP_PKEY_size(EVP_PKEY *pkey);
        +
        +=head1 DESCRIPTION
        +
        +The EVP signature routines are a high level interface to digital
        +signatures.
        +
        +EVP_SignInit_ex() sets up signing context B<ctx> to use digest
        +B<type> from ENGINE B<impl>. B<ctx> must be initialized with
        +EVP_MD_CTX_init() before calling this function.
        +
        +EVP_SignUpdate() hashes B<cnt> bytes of data at B<d> into the
        +signature context B<ctx>. This function can be called several times on the
        +same B<ctx> to include additional data.
        +
        +EVP_SignFinal() signs the data in B<ctx> using the private key B<pkey> and
        +places the signature in B<sig>. The number of bytes of data written (i.e. the
        +length of the signature) will be written to the integer at B<s>, at most
        +EVP_PKEY_size(pkey) bytes will be written. 
        +
        +EVP_SignInit() initializes a signing context B<ctx> to use the default
        +implementation of digest B<type>.
        +
        +EVP_PKEY_size() returns the maximum size of a signature in bytes. The actual
        +signature returned by EVP_SignFinal() may be smaller.
        +
        +=head1 RETURN VALUES
        +
        +EVP_SignInit_ex(), EVP_SignUpdate() and EVP_SignFinal() return 1
        +for success and 0 for failure.
        +
        +EVP_PKEY_size() returns the maximum size of a signature in bytes.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 NOTES
        +
        +The B<EVP> interface to digital signatures should almost always be used in
        +preference to the low level interfaces. This is because the code then becomes
        +transparent to the algorithm used and much more flexible.
        +
        +Due to the link between message digests and public key algorithms the correct
        +digest algorithm must be used with the correct public key type. A list of
        +algorithms and associated public key algorithms appears in 
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>.
        +
        +When signing with DSA private keys the random number generator must be seeded
        +or the operation will fail. The random number generator does not need to be
        +seeded for RSA signatures.
        +
        +The call to EVP_SignFinal() internally finalizes a copy of the digest context.
        +This means that calls to EVP_SignUpdate() and EVP_SignFinal() can be called
        +later to digest and sign additional data.
        +
        +Since only a copy of the digest context is ever finalized the context must
        +be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
        +will occur.
        +
        +=head1 BUGS
        +
        +Older versions of this documentation wrongly stated that calls to 
        +EVP_SignUpdate() could not be made after calling EVP_SignFinal().
        +
        +Since the private key is passed in the call to EVP_SignFinal() any error
        +relating to the private key (for example an unsuitable key and digest
        +combination) will not be indicated until after potentially large amounts of
        +data have been passed through EVP_SignUpdate().
        +
        +It is not possible to change the signing parameters using these function.
        +
        +The previous two bugs are fixed in the newer EVP_SignDigest*() function.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>,
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
        +L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
        +L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
        +L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
        +
        +=head1 HISTORY
        +
        +EVP_SignInit(), EVP_SignUpdate() and EVP_SignFinal() are
        +available in all versions of SSLeay and OpenSSL.
        +
        +EVP_SignInit_ex() was added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/EVP_VerifyInit.pod b/vendor/openssl/openssl/doc/crypto/EVP_VerifyInit.pod
        new file mode 100644
        index 000000000..9097f0941
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/EVP_VerifyInit.pod
        @@ -0,0 +1,95 @@
        +=pod
        +
        +=head1 NAME
        +
        +EVP_VerifyInit, EVP_VerifyUpdate, EVP_VerifyFinal - EVP signature verification functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
        + int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
        + int EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf, unsigned int siglen,EVP_PKEY *pkey);
        +
        + int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);
        +
        +=head1 DESCRIPTION
        +
        +The EVP signature verification routines are a high level interface to digital
        +signatures.
        +
        +EVP_VerifyInit_ex() sets up verification context B<ctx> to use digest
        +B<type> from ENGINE B<impl>. B<ctx> must be initialized by calling
        +EVP_MD_CTX_init() before calling this function.
        +
        +EVP_VerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
        +verification context B<ctx>. This function can be called several times on the
        +same B<ctx> to include additional data.
        +
        +EVP_VerifyFinal() verifies the data in B<ctx> using the public key B<pkey>
        +and against the B<siglen> bytes at B<sigbuf>.
        +
        +EVP_VerifyInit() initializes verification context B<ctx> to use the default
        +implementation of digest B<type>.
        +
        +=head1 RETURN VALUES
        +
        +EVP_VerifyInit_ex() and EVP_VerifyUpdate() return 1 for success and 0 for
        +failure.
        +
        +EVP_VerifyFinal() returns 1 for a correct signature, 0 for failure and -1 if some
        +other error occurred.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 NOTES
        +
        +The B<EVP> interface to digital signatures should almost always be used in
        +preference to the low level interfaces. This is because the code then becomes
        +transparent to the algorithm used and much more flexible.
        +
        +Due to the link between message digests and public key algorithms the correct
        +digest algorithm must be used with the correct public key type. A list of
        +algorithms and associated public key algorithms appears in 
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>.
        +
        +The call to EVP_VerifyFinal() internally finalizes a copy of the digest context.
        +This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can be called
        +later to digest and verify additional data.
        +
        +Since only a copy of the digest context is ever finalized the context must
        +be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
        +will occur.
        +
        +=head1 BUGS
        +
        +Older versions of this documentation wrongly stated that calls to 
        +EVP_VerifyUpdate() could not be made after calling EVP_VerifyFinal().
        +
        +Since the public key is passed in the call to EVP_SignFinal() any error
        +relating to the private key (for example an unsuitable key and digest
        +combination) will not be indicated until after potentially large amounts of
        +data have been passed through EVP_SignUpdate().
        +
        +It is not possible to change the signing parameters using these function.
        +
        +The previous two bugs are fixed in the newer EVP_VerifyDigest*() function.
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>,
        +L<EVP_SignInit(3)|EVP_SignInit(3)>,
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
        +L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
        +L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
        +L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
        +
        +=head1 HISTORY
        +
        +EVP_VerifyInit(), EVP_VerifyUpdate() and EVP_VerifyFinal() are
        +available in all versions of SSLeay and OpenSSL.
        +
        +EVP_VerifyInit_ex() was added in OpenSSL 0.9.7
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OBJ_nid2obj.pod b/vendor/openssl/openssl/doc/crypto/OBJ_nid2obj.pod
        new file mode 100644
        index 000000000..1e45dd40f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OBJ_nid2obj.pod
        @@ -0,0 +1,151 @@
        +=pod
        +
        +=head1 NAME
        +
        +OBJ_nid2obj, OBJ_nid2ln, OBJ_nid2sn, OBJ_obj2nid, OBJ_txt2nid, OBJ_ln2nid, OBJ_sn2nid,
        +OBJ_cmp, OBJ_dup, OBJ_txt2obj, OBJ_obj2txt, OBJ_create, OBJ_cleanup - ASN1 object utility
        +functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/objects.h>
        +
        + ASN1_OBJECT * OBJ_nid2obj(int n);
        + const char *  OBJ_nid2ln(int n);
        + const char *  OBJ_nid2sn(int n);
        +
        + int OBJ_obj2nid(const ASN1_OBJECT *o);
        + int OBJ_ln2nid(const char *ln);
        + int OBJ_sn2nid(const char *sn);
        +
        + int OBJ_txt2nid(const char *s);
        +
        + ASN1_OBJECT * OBJ_txt2obj(const char *s, int no_name);
        + int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
        +
        + int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
        + ASN1_OBJECT * OBJ_dup(const ASN1_OBJECT *o);
        +
        + int OBJ_create(const char *oid,const char *sn,const char *ln);
        + void OBJ_cleanup(void);
        +
        +=head1 DESCRIPTION
        +
        +The ASN1 object utility functions process ASN1_OBJECT structures which are
        +a representation of the ASN1 OBJECT IDENTIFIER (OID) type.
        +
        +OBJ_nid2obj(), OBJ_nid2ln() and OBJ_nid2sn() convert the NID B<n> to 
        +an ASN1_OBJECT structure, its long name and its short name respectively,
        +or B<NULL> is an error occurred.
        +
        +OBJ_obj2nid(), OBJ_ln2nid(), OBJ_sn2nid() return the corresponding NID
        +for the object B<o>, the long name <ln> or the short name <sn> respectively
        +or NID_undef if an error occurred.
        +
        +OBJ_txt2nid() returns NID corresponding to text string <s>. B<s> can be
        +a long name, a short name or the numerical respresentation of an object.
        +
        +OBJ_txt2obj() converts the text string B<s> into an ASN1_OBJECT structure.
        +If B<no_name> is 0 then long names and short names will be interpreted
        +as well as numerical forms. If B<no_name> is 1 only the numerical form
        +is acceptable.
        +
        +OBJ_obj2txt() converts the B<ASN1_OBJECT> B<a> into a textual representation.
        +The representation is written as a null terminated string to B<buf>
        +at most B<buf_len> bytes are written, truncating the result if necessary.
        +The total amount of space required is returned. If B<no_name> is 0 then
        +if the object has a long or short name then that will be used, otherwise
        +the numerical form will be used. If B<no_name> is 1 then the numerical
        +form will always be used.
        +
        +OBJ_cmp() compares B<a> to B<b>. If the two are identical 0 is returned.
        +
        +OBJ_dup() returns a copy of B<o>.
        +
        +OBJ_create() adds a new object to the internal table. B<oid> is the 
        +numerical form of the object, B<sn> the short name and B<ln> the
        +long name. A new NID is returned for the created object.
        +
        +OBJ_cleanup() cleans up OpenSSLs internal object table: this should
        +be called before an application exits if any new objects were added
        +using OBJ_create().
        +
        +=head1 NOTES
        +
        +Objects in OpenSSL can have a short name, a long name and a numerical
        +identifier (NID) associated with them. A standard set of objects is
        +represented in an internal table. The appropriate values are defined
        +in the header file B<objects.h>.
        +
        +For example the OID for commonName has the following definitions:
        +
        + #define SN_commonName                   "CN"
        + #define LN_commonName                   "commonName"
        + #define NID_commonName                  13
        +
        +New objects can be added by calling OBJ_create().
        +
        +Table objects have certain advantages over other objects: for example
        +their NIDs can be used in a C language switch statement. They are
        +also static constant structures which are shared: that is there
        +is only a single constant structure for each table object.
        +
        +Objects which are not in the table have the NID value NID_undef.
        +
        +Objects do not need to be in the internal tables to be processed,
        +the functions OBJ_txt2obj() and OBJ_obj2txt() can process the numerical
        +form of an OID.
        +
        +=head1 EXAMPLES
        +
        +Create an object for B<commonName>:
        +
        + ASN1_OBJECT *o;
        + o = OBJ_nid2obj(NID_commonName);
        +
        +Check if an object is B<commonName>
        +
        + if (OBJ_obj2nid(obj) == NID_commonName)
        +	/* Do something */
        +
        +Create a new NID and initialize an object from it:
        +
        + int new_nid;
        + ASN1_OBJECT *obj;
        + new_nid = OBJ_create("1.2.3.4", "NewOID", "New Object Identifier");
        +
        + obj = OBJ_nid2obj(new_nid);
        + 
        +Create a new object directly:
        +
        + obj = OBJ_txt2obj("1.2.3.4", 1);
        +
        +=head1 BUGS
        +
        +OBJ_obj2txt() is awkward and messy to use: it doesn't follow the 
        +convention of other OpenSSL functions where the buffer can be set
        +to B<NULL> to determine the amount of data that should be written.
        +Instead B<buf> must point to a valid buffer and B<buf_len> should
        +be set to a positive value. A buffer length of 80 should be more
        +than enough to handle any OID encountered in practice.
        +
        +=head1 RETURN VALUES
        +
        +OBJ_nid2obj() returns an B<ASN1_OBJECT> structure or B<NULL> is an
        +error occurred.
        +
        +OBJ_nid2ln() and OBJ_nid2sn() returns a valid string or B<NULL>
        +on error.
        +
        +OBJ_obj2nid(), OBJ_ln2nid(), OBJ_sn2nid() and OBJ_txt2nid() return
        +a NID or B<NID_undef> on error.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OPENSSL_Applink.pod b/vendor/openssl/openssl/doc/crypto/OPENSSL_Applink.pod
        new file mode 100644
        index 000000000..e54de12cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OPENSSL_Applink.pod
        @@ -0,0 +1,21 @@
        +=pod
        +
        +=head1 NAME
        +
        +OPENSSL_Applink - glue between OpenSSL BIO and Win32 compiler run-time
        +
        +=head1 SYNOPSIS
        +
        + __declspec(dllexport) void **OPENSSL_Applink();
        +
        +=head1 DESCRIPTION
        +
        +OPENSSL_Applink is application-side interface which provides a glue
        +between OpenSSL BIO layer and Win32 compiler run-time environment.
        +Even though it appears at application side, it's essentially OpenSSL
        +private interface. For this reason application developers are not
        +expected to implement it, but to compile provided module with
        +compiler of their choice and link it into the target application.
        +The referred module is available as <openssl>/ms/applink.c.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod b/vendor/openssl/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod
        new file mode 100644
        index 000000000..c39ac35e7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod
        @@ -0,0 +1,101 @@
        +=pod
        +
        +=head1 NAME
        +
        +OPENSSL_VERSION_NUMBER, SSLeay, SSLeay_version - get OpenSSL version number
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/opensslv.h>
        + #define OPENSSL_VERSION_NUMBER 0xnnnnnnnnnL
        +
        + #include <openssl/crypto.h>
        + long SSLeay(void);
        + const char *SSLeay_version(int t);
        +
        +=head1 DESCRIPTION
        +
        +OPENSSL_VERSION_NUMBER is a numeric release version identifier:
        +
        + MMNNFFPPS: major minor fix patch status
        +
        +The status nibble has one of the values 0 for development, 1 to e for betas
        +1 to 14, and f for release.
        +
        +for example
        +
        + 0x000906000 == 0.9.6 dev
        + 0x000906023 == 0.9.6b beta 3
        + 0x00090605f == 0.9.6e release
        +
        +Versions prior to 0.9.3 have identifiers E<lt> 0x0930.
        +Versions between 0.9.3 and 0.9.5 had a version identifier with this
        +interpretation:
        +
        + MMNNFFRBB major minor fix final beta/patch
        +
        +for example
        +
        + 0x000904100 == 0.9.4 release
        + 0x000905000 == 0.9.5 dev
        +
        +Version 0.9.5a had an interim interpretation that is like the current one,
        +except the patch level got the highest bit set, to keep continuity.  The
        +number was therefore 0x0090581f.
        +
        +
        +For backward compatibility, SSLEAY_VERSION_NUMBER is also defined.
        +
        +SSLeay() returns this number. The return value can be compared to the
        +macro to make sure that the correct version of the library has been
        +loaded, especially when using DLLs on Windows systems.
        +
        +SSLeay_version() returns different strings depending on B<t>:
        +
        +=over 4
        +
        +=item SSLEAY_VERSION
        +
        +The text variant of the version number and the release date.  For example,
        +"OpenSSL 0.9.5a 1 Apr 2000".
        +
        +=item SSLEAY_CFLAGS
        +
        +The compiler flags set for the compilation process in the form
        +"compiler: ..."  if available or "compiler: information not available"
        +otherwise.
        +
        +=item SSLEAY_BUILT_ON
        +
        +The date of the build process in the form "built on: ..." if available
        +or "built on: date not available" otherwise.
        +
        +=item SSLEAY_PLATFORM
        +
        +The "Configure" target of the library build in the form "platform: ..."
        +if available or "platform: information not available" otherwise.
        +
        +=item SSLEAY_DIR
        +
        +The "OPENSSLDIR" setting of the library build in the form "OPENSSLDIR: "...""
        +if available or "OPENSSLDIR: N/A" otherwise.
        +
        +=back
        +
        +For an unknown B<t>, the text "not available" is returned.
        +
        +=head1 RETURN VALUE
        +
        +The version number.
        +
        +=head1 SEE ALSO
        +
        +L<crypto(3)|crypto(3)>
        +
        +=head1 HISTORY
        +
        +SSLeay() and SSLEAY_VERSION_NUMBER are available in all versions of SSLeay and OpenSSL.
        +OPENSSL_VERSION_NUMBER is available in all versions of OpenSSL.
        +B<SSLEAY_DIR> was added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OPENSSL_config.pod b/vendor/openssl/openssl/doc/crypto/OPENSSL_config.pod
        new file mode 100644
        index 000000000..e7bba2aac
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OPENSSL_config.pod
        @@ -0,0 +1,82 @@
        +=pod
        +
        +=head1 NAME
        +
        +OPENSSL_config, OPENSSL_no_config - simple OpenSSL configuration functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/conf.h>
        +
        + void OPENSSL_config(const char *config_name);
        + void OPENSSL_no_config(void);
        +
        +=head1 DESCRIPTION
        +
        +OPENSSL_config() configures OpenSSL using the standard B<openssl.cnf>
        +configuration file name using B<config_name>. If B<config_name> is NULL then
        +the default name B<openssl_conf> will be used. Any errors are ignored. Further
        +calls to OPENSSL_config() will have no effect. The configuration file format
        +is documented in the L<conf(5)|conf(5)> manual page.
        +
        +OPENSSL_no_config() disables configuration. If called before OPENSSL_config()
        +no configuration takes place.
        +
        +=head1 NOTES
        +
        +It is B<strongly> recommended that B<all> new applications call OPENSSL_config()
        +or the more sophisticated functions such as CONF_modules_load() during
        +initialization (that is before starting any threads). By doing this
        +an application does not need to keep track of all configuration options
        +and some new functionality can be supported automatically.
        +
        +It is also possible to automatically call OPENSSL_config() when an application
        +calls OPENSSL_add_all_algorithms() by compiling an application with the
        +preprocessor symbol B<OPENSSL_LOAD_CONF> #define'd. In this way configuration
        +can be added without source changes.
        +
        +The environment variable B<OPENSSL_CONF> can be set to specify the location
        +of the configuration file.
        + 
        +Currently ASN1 OBJECTs and ENGINE configuration can be performed future
        +versions of OpenSSL will add new configuration options.
        +
        +There are several reasons why calling the OpenSSL configuration routines is
        +advisable. For example new ENGINE functionality was added to OpenSSL 0.9.7.
        +In OpenSSL 0.9.7 control functions can be supported by ENGINEs, this can be
        +used (among other things) to load dynamic ENGINEs from shared libraries (DSOs).
        +However very few applications currently support the control interface and so
        +very few can load and use dynamic ENGINEs. Equally in future more sophisticated
        +ENGINEs will require certain control operations to customize them. If an
        +application calls OPENSSL_config() it doesn't need to know or care about
        +ENGINE control operations because they can be performed by editing a
        +configuration file.
        +
        +Applications should free up configuration at application closedown by calling
        +CONF_modules_free().
        +
        +=head1 RESTRICTIONS
        +
        +The OPENSSL_config() function is designed to be a very simple "call it and
        +forget it" function. As a result its behaviour is somewhat limited. It ignores
        +all errors silently and it can only load from the standard configuration file
        +location for example.
        +
        +It is however B<much> better than nothing. Applications which need finer
        +control over their configuration functionality should use the configuration
        +functions such as CONF_load_modules() directly.
        +
        +=head1 RETURN VALUES
        +
        +Neither OPENSSL_config() nor OPENSSL_no_config() return a value.
        +
        +=head1 SEE ALSO
        +
        +L<conf(5)|conf(5)>, L<CONF_load_modules_file(3)|CONF_load_modules_file(3)>,
        +L<CONF_modules_free(3),CONF_modules_free(3)>
        +
        +=head1 HISTORY
        +
        +OPENSSL_config() and OPENSSL_no_config() first appeared in OpenSSL 0.9.7
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OPENSSL_ia32cap.pod b/vendor/openssl/openssl/doc/crypto/OPENSSL_ia32cap.pod
        new file mode 100644
        index 000000000..2e659d34a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OPENSSL_ia32cap.pod
        @@ -0,0 +1,43 @@
        +=pod
        +
        +=head1 NAME
        +
        +OPENSSL_ia32cap - finding the IA-32 processor capabilities
        +
        +=head1 SYNOPSIS
        +
        + unsigned long *OPENSSL_ia32cap_loc(void);
        + #define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
        +
        +=head1 DESCRIPTION
        +
        +Value returned by OPENSSL_ia32cap_loc() is address of a variable
        +containing IA-32 processor capabilities bit vector as it appears in EDX
        +register after executing CPUID instruction with EAX=1 input value (see
        +Intel Application Note #241618). Naturally it's meaningful on IA-32[E]
        +platforms only. The variable is normally set up automatically upon
        +toolkit initialization, but can be manipulated afterwards to modify
        +crypto library behaviour. For the moment of this writing six bits are
        +significant, namely:
        +
        +1. bit #28 denoting Hyperthreading, which is used to distiguish
        +   cores with shared cache;
        +2. bit #26 denoting SSE2 support;
        +3. bit #25 denoting SSE support;
        +4. bit #23 denoting MMX support;
        +5. bit #20, reserved by Intel, is used to choose between RC4 code
        +   pathes;
        +6. bit #4 denoting presence of Time-Stamp Counter.
        +
        +For example, clearing bit #26 at run-time disables high-performance
        +SSE2 code present in the crypto library. You might have to do this if
        +target OpenSSL application is executed on SSE2 capable CPU, but under
        +control of OS which does not support SSE2 extentions. Even though you
        +can manipulate the value programmatically, you most likely will find it
        +more appropriate to set up an environment variable with the same name
        +prior starting target application, e.g. on Intel P4 processor 'env
        +OPENSSL_ia32cap=0x12900010 apps/openssl', to achieve same effect
        +without modifying the application source code. Alternatively you can
        +reconfigure the toolkit with no-sse2 option and recompile.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod b/vendor/openssl/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod
        new file mode 100644
        index 000000000..f14dfaf00
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod
        @@ -0,0 +1,51 @@
        +=pod
        +
        +=head1 NAME
        +
        +OPENSSL_load_builtin_modules - add standard configuration modules
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/conf.h>
        +
        + void OPENSSL_load_builtin_modules(void);
        + void ASN1_add_oid_module(void);
        + ENGINE_add_conf_module();
        +
        +=head1 DESCRIPTION
        +
        +The function OPENSSL_load_builtin_modules() adds all the standard OpenSSL
        +configuration modules to the internal list. They can then be used by the
        +OpenSSL configuration code.
        +
        +ASN1_add_oid_module() adds just the ASN1 OBJECT module.
        +
        +ENGINE_add_conf_module() adds just the ENGINE configuration module.
        +
        +=head1 NOTES
        +
        +If the simple configuration function OPENSSL_config() is called then 
        +OPENSSL_load_builtin_modules() is called automatically.
        +
        +Applications which use the configuration functions directly will need to
        +call OPENSSL_load_builtin_modules() themselves I<before> any other 
        +configuration code.
        +
        +Applications should call OPENSSL_load_builtin_modules() to load all
        +configuration modules instead of adding modules selectively: otherwise 
        +functionality may be missing from the application if an when new
        +modules are added.
        +
        +=head1 RETURN VALUE
        +
        +None of the functions return a value.
        +
        +=head1 SEE ALSO
        +
        +L<conf(3)|conf(3)>, L<OPENSSL_config(3)|OPENSSL_config(3)>
        +
        +=head1 HISTORY
        +
        +These functions first appeared in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod b/vendor/openssl/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod
        new file mode 100644
        index 000000000..e63411b5b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        +OpenSSL_add_all_algorithms, OpenSSL_add_all_ciphers, OpenSSL_add_all_digests -
        +add algorithms to internal table
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + void OpenSSL_add_all_algorithms(void);
        + void OpenSSL_add_all_ciphers(void);
        + void OpenSSL_add_all_digests(void);
        +
        + void EVP_cleanup(void);
        +
        +=head1 DESCRIPTION
        +
        +OpenSSL keeps an internal table of digest algorithms and ciphers. It uses
        +this table to lookup ciphers via functions such as EVP_get_cipher_byname().
        +
        +OpenSSL_add_all_digests() adds all digest algorithms to the table.
        +
        +OpenSSL_add_all_algorithms() adds all algorithms to the table (digests and
        +ciphers).
        +
        +OpenSSL_add_all_ciphers() adds all encryption algorithms to the table including
        +password based encryption algorithms.
        +
        +EVP_cleanup() removes all ciphers and digests from the table.
        +
        +=head1 RETURN VALUES
        +
        +None of the functions return a value.
        +
        +=head1 NOTES
        +
        +A typical application will call OpenSSL_add_all_algorithms() initially and
        +EVP_cleanup() before exiting.
        +
        +An application does not need to add algorithms to use them explicitly, for example
        +by EVP_sha1(). It just needs to add them if it (or any of the functions it calls)
        +needs to lookup algorithms.
        +
        +The cipher and digest lookup functions are used in many parts of the library. If
        +the table is not initialized several functions will misbehave and complain they
        +cannot find algorithms. This includes the PEM, PKCS#12, SSL and S/MIME libraries.
        +This is a common query in the OpenSSL mailing lists.
        +
        +Calling OpenSSL_add_all_algorithms() links in all algorithms: as a result a
        +statically linked executable can be quite large. If this is important it is possible
        +to just add the required ciphers and digests.
        +
        +=head1 BUGS
        +
        +Although the functions do not return error codes it is possible for them to fail.
        +This will only happen as a result of a memory allocation failure so this is not
        +too much of a problem in practice.
        +
        +=head1 SEE ALSO
        +
        +L<evp(3)|evp(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>,
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod b/vendor/openssl/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod
        new file mode 100644
        index 000000000..e070c45c2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        + PEM_write_bio_CMS_stream - output CMS_ContentInfo structure in PEM format.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        + #include <openssl/pem.h>
        +
        + int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +PEM_write_bio_CMS_stream() outputs a CMS_ContentInfo structure in PEM format.
        +
        +It is otherwise identical to the function SMIME_write_CMS().
        +
        +=head1 NOTES
        +
        +This function is effectively a version of the PEM_write_bio_CMS() supporting
        +streaming.
        +
        +=head1 RETURN VALUES
        +
        +PEM_write_bio_CMS_stream() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
        +L<CMS_decrypt(3)|CMS_decrypt(3)>,
        +L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>,
        +L<i2d_CMS_bio_stream(3)|i2d_CMS_bio_stream(3)>
        +
        +=head1 HISTORY
        +
        +PEM_write_bio_CMS_stream() was added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod b/vendor/openssl/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod
        new file mode 100644
        index 000000000..16fc9b684
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        +PEM_write_bio_PKCS7_stream - output PKCS7 structure in PEM format.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        + #include <openssl/pem.h>
        +
        + int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +PEM_write_bio_PKCS7_stream() outputs a PKCS7 structure in PEM format.
        +
        +It is otherwise identical to the function SMIME_write_PKCS7().
        +
        +=head1 NOTES
        +
        +This function is effectively a version of the PEM_write_bio_PKCS7() supporting
        +streaming.
        +
        +=head1 RETURN VALUES
        +
        +PEM_write_bio_PKCS7_stream() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
        +L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
        +L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>,
        +L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>,
        +L<i2d_PKCS7_bio_stream(3)|i2d_PKCS7_bio_stream(3)>
        +
        +=head1 HISTORY
        +
        +PEM_write_bio_PKCS7_stream() was added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS12_create.pod b/vendor/openssl/openssl/doc/crypto/PKCS12_create.pod
        new file mode 100644
        index 000000000..de7cab2bd
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS12_create.pod
        @@ -0,0 +1,75 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS12_create - create a PKCS#12 structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs12.h>
        +
        + PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca,
        +				int nid_key, int nid_cert, int iter, int mac_iter, int keytype);
        +
        +=head1 DESCRIPTION
        +
        +PKCS12_create() creates a PKCS#12 structure.
        +
        +B<pass> is the passphrase to use. B<name> is the B<friendlyName> to use for
        +the supplied certifictate and key. B<pkey> is the private key to include in
        +the structure and B<cert> its corresponding certificates. B<ca>, if not B<NULL>
        +is an optional set of certificates to also include in the structure.
        +
        +B<nid_key> and B<nid_cert> are the encryption algorithms that should be used
        +for the key and certificate respectively. B<iter> is the encryption algorithm
        +iteration count to use and B<mac_iter> is the MAC iteration count to use.
        +B<keytype> is the type of key.
        +
        +=head1 NOTES
        +
        +The parameters B<nid_key>, B<nid_cert>, B<iter>, B<mac_iter> and B<keytype>
        +can all be set to zero and sensible defaults will be used.
        +
        +These defaults are: 40 bit RC2 encryption for certificates, triple DES
        +encryption for private keys, a key iteration count of PKCS12_DEFAULT_ITER
        +(currently 2048) and a MAC iteration count of 1.
        +
        +The default MAC iteration count is 1 in order to retain compatibility with
        +old software which did not interpret MAC iteration counts. If such compatibility
        +is not required then B<mac_iter> should be set to PKCS12_DEFAULT_ITER.
        +
        +B<keytype> adds a flag to the store private key. This is a non standard extension
        +that is only currently interpreted by MSIE. If set to zero the flag is omitted,
        +if set to B<KEY_SIG> the key can be used for signing only, if set to B<KEY_EX>
        +it can be used for signing and encryption. This option was useful for old
        +export grade software which could use signing only keys of arbitrary size but
        +had restrictions on the permissible sizes of keys which could be used for
        +encryption.
        +
        +=head1 NEW FUNCTIONALITY IN OPENSSL 0.9.8
        +
        +Some additional functionality was added to PKCS12_create() in OpenSSL
        +0.9.8. These extensions are detailed below.
        +
        +If a certificate contains an B<alias> or B<keyid> then this will be
        +used for the corresponding B<friendlyName> or B<localKeyID> in the
        +PKCS12 structure.
        +
        +Either B<pkey>, B<cert> or both can be B<NULL> to indicate that no key or
        +certficate is required. In previous versions both had to be present or
        +a fatal error is returned.
        +
        +B<nid_key> or B<nid_cert> can be set to -1 indicating that no encryption
        +should be used. 
        +
        +B<mac_iter> can be set to -1 and the MAC will then be omitted entirely.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_PKCS12(3)|d2i_PKCS12(3)>
        +
        +=head1 HISTORY
        +
        +PKCS12_create was added in OpenSSL 0.9.3
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS12_parse.pod b/vendor/openssl/openssl/doc/crypto/PKCS12_parse.pod
        new file mode 100644
        index 000000000..c54cf2ad6
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS12_parse.pod
        @@ -0,0 +1,57 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS12_parse - parse a PKCS#12 structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs12.h>
        +
        +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
        +
        +=head1 DESCRIPTION
        +
        +PKCS12_parse() parses a PKCS12 structure.
        +
        +B<p12> is the B<PKCS12> structure to parse. B<pass> is the passphrase to use.
        +If successful the private key will be written to B<*pkey>, the corresponding
        +certificate to B<*cert> and any additional certificates to B<*ca>.
        +
        +=head1 NOTES
        +
        +The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> in
        +which case additional certificates will be discarded. B<*ca> can also be a
        +valid STACK in which case additional certificates are appended to B<*ca>. If
        +B<*ca> is B<NULL> a new STACK will be allocated.
        +
        +The B<friendlyName> and B<localKeyID> attributes (if present) on each
        +certificate will be stored in the B<alias> and B<keyid> attributes of the
        +B<X509> structure.
        +
        +=head1 RETURN VALUES
        +
        +PKCS12_parse() returns 1 for success and zero if an error occurred.
        +
        +The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 BUGS
        +
        +Only a single private key and corresponding certificate is returned by this
        +function. More complex PKCS#12 files with multiple private keys will only
        +return the first match.
        +
        +Only B<friendlyName> and B<localKeyID> attributes are currently stored in
        +certificates. Other attributes are discarded.
        +
        +Attributes currently cannot be stored in the private key B<EVP_PKEY> structure.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_PKCS12(3)|d2i_PKCS12(3)>
        +
        +=head1 HISTORY
        +
        +PKCS12_parse was added in OpenSSL 0.9.3
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS7_decrypt.pod b/vendor/openssl/openssl/doc/crypto/PKCS7_decrypt.pod
        new file mode 100644
        index 000000000..325699d0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS7_decrypt.pod
        @@ -0,0 +1,55 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS7_decrypt - decrypt content from a PKCS#7 envelopedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +PKCS7_decrypt() extracts and decrypts the content from a PKCS#7 envelopedData
        +structure. B<pkey> is the private key of the recipient, B<cert> is the
        +recipients certificate, B<data> is a BIO to write the content to and
        +B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +OpenSSL_add_all_algorithms() (or equivalent) should be called before using this
        +function or errors about unknown algorithms will occur.
        +
        +Although the recipients certificate is not needed to decrypt the data it is needed
        +to locate the appropriate (of possible several) recipients in the PKCS#7 structure.
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are deleted
        +from the content. If the content is not of type B<text/plain> then an error is
        +returned.
        +
        +=head1 RETURN VALUES
        +
        +PKCS7_decrypt() returns either 1 for success or 0 for failure.
        +The error can be obtained from ERR_get_error(3)
        +
        +=head1 BUGS
        +
        +PKCS7_decrypt() must be passed the correct recipient key and certificate. It would
        +be better if it could look up the correct key and certificate from a database.
        +
        +The lack of single pass processing and need to hold all data in memory as
        +mentioned in PKCS7_sign() also applies to PKCS7_verify().
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
        +
        +=head1 HISTORY
        +
        +PKCS7_decrypt() was added to OpenSSL 0.9.5
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS7_encrypt.pod b/vendor/openssl/openssl/doc/crypto/PKCS7_encrypt.pod
        new file mode 100644
        index 000000000..2cd925a7e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS7_encrypt.pod
        @@ -0,0 +1,80 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS7_encrypt - create a PKCS#7 envelopedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags);
        +
        +=head1 DESCRIPTION
        +
        +PKCS7_encrypt() creates and returns a PKCS#7 envelopedData structure. B<certs>
        +is a list of recipient certificates. B<in> is the content to be encrypted.
        +B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +Only RSA keys are supported in PKCS#7 and envelopedData so the recipient
        +certificates supplied to this function must all contain RSA public keys, though
        +they do not have to be signed using the RSA algorithm.
        +
        +EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use
        +because most clients will support it.
        +
        +Some old "export grade" clients may only support weak encryption using 40 or 64
        +bit RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc()
        +respectively.
        +
        +The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
        +its parameters. 
        +
        +Many browsers implement a "sign and encrypt" option which is simply an S/MIME
        +envelopedData containing an S/MIME signed message. This can be readily produced
        +by storing the S/MIME signed message in a memory BIO and passing it to
        +PKCS7_encrypt().
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are
        +prepended to the data.
        +
        +Normally the supplied content is translated into MIME canonical format (as
        +required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation
        +occurs. This option should be used if the supplied data is in binary format
        +otherwise the translation will corrupt it. If B<PKCS7_BINARY> is set then
        +B<PKCS7_TEXT> is ignored.
        +
        +If the B<PKCS7_STREAM> flag is set a partial B<PKCS7> structure is output
        +suitable for streaming I/O: no data is read from the BIO B<in>.
        +
        +=head1 NOTES
        +
        +If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not>
        +complete and outputting its contents via a function that does not
        +properly finalize the B<PKCS7> structure will give unpredictable 
        +results.
        +
        +Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(),
        +PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
        +can be performed by obtaining the streaming ASN1 B<BIO> directly using
        +BIO_new_PKCS7().
        +
        +=head1 RETURN VALUES
        +
        +PKCS7_encrypt() returns either a PKCS7 structure or NULL if an error occurred.
        +The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +PKCS7_decrypt() was added to OpenSSL 0.9.5
        +The B<PKCS7_STREAM> flag was first supported in OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS7_sign.pod b/vendor/openssl/openssl/doc/crypto/PKCS7_sign.pod
        new file mode 100644
        index 000000000..64a35144f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS7_sign.pod
        @@ -0,0 +1,116 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS7_sign - create a PKCS#7 signedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +PKCS7_sign() creates and returns a PKCS#7 signedData structure. B<signcert> is
        +the certificate to sign with, B<pkey> is the corresponsding private key.
        +B<certs> is an optional additional set of certificates to include in the PKCS#7
        +structure (for example any intermediate CAs in the chain). 
        +
        +The data to be signed is read from BIO B<data>.
        +
        +B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +Any of the following flags (ored together) can be passed in the B<flags>
        +parameter.
        +
        +Many S/MIME clients expect the signed content to include valid MIME headers. If
        +the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended
        +to the data.
        +
        +If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the
        +PKCS7 structure, the signer's certificate must still be supplied in the
        +B<signcert> parameter though. This can reduce the size of the signature if the
        +signers certificate can be obtained by other means: for example a previously
        +signed message.
        +
        +The data being signed is included in the PKCS7 structure, unless
        +B<PKCS7_DETACHED> is set in which case it is omitted. This is used for PKCS7
        +detached signatures which are used in S/MIME plaintext signed messages for
        +example.
        +
        +Normally the supplied content is translated into MIME canonical format (as
        +required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation
        +occurs. This option should be used if the supplied data is in binary format
        +otherwise the translation will corrupt it.
        +
        +The signedData structure includes several PKCS#7 autenticatedAttributes
        +including the signing time, the PKCS#7 content type and the supported list of
        +ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no
        +authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just
        +the SMIMECapabilities are omitted.
        +
        +If present the SMIMECapabilities attribute indicates support for the following
        +algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
        +these algorithms is disabled then it will not be included.
        +
        +If the flags B<PKCS7_STREAM> is set then the returned B<PKCS7> structure is
        +just initialized ready to perform the signing operation. The signing is however
        +B<not> performed and the data to be signed is not read from the B<data>
        +parameter. Signing is deferred until after the data has been written. In this
        +way data can be signed in a single pass.
        +
        +If the B<PKCS7_PARTIAL> flag is set a partial B<PKCS7> structure is output to
        +which additional signers and capabilities can be added before finalization.
        +
        +
        +=head1 NOTES
        +
        +If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not>
        +complete and outputting its contents via a function that does not properly
        +finalize the B<PKCS7> structure will give unpredictable results.
        +
        +Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(),
        +PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
        +can be performed by obtaining the streaming ASN1 B<BIO> directly using
        +BIO_new_PKCS7().
        +
        +If a signer is specified it will use the default digest for the signing
        +algorithm. This is B<SHA1> for both RSA and DSA keys.
        +
        +In OpenSSL 1.0.0 the B<certs>, B<signcert> and B<pkey> parameters can all be
        +B<NULL> if the B<PKCS7_PARTIAL> flag is set. One or more signers can be added
        +using the function B<PKCS7_sign_add_signer()>. B<PKCS7_final()> must also be
        +called to finalize the structure if streaming is not enabled. Alternative
        +signing digests can also be specified using this method.
        +
        +In OpenSSL 1.0.0 if B<signcert> and B<pkey> are NULL then a certificates only
        +PKCS#7 structure is output.
        +
        +In versions of OpenSSL before 1.0.0 the B<signcert> and B<pkey> parameters must
        +B<NOT> be NULL.
        +
        +=head1 BUGS
        +
        +Some advanced attributes such as counter signatures are not supported.
        +
        +=head1 RETURN VALUES
        +
        +PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error
        +occurred.  The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_verify(3)|PKCS7_verify(3)>
        +
        +=head1 HISTORY
        +
        +PKCS7_sign() was added to OpenSSL 0.9.5
        +
        +The B<PKCS7_PARTIAL> flag was added in OpenSSL 1.0.0
        +
        +The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS7_sign_add_signer.pod b/vendor/openssl/openssl/doc/crypto/PKCS7_sign_add_signer.pod
        new file mode 100644
        index 000000000..ebec4d57d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS7_sign_add_signer.pod
        @@ -0,0 +1,87 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS7_sign_add_signer - add a signer PKCS7 signed data structure.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, int flags);
        +
        +
        +=head1 DESCRIPTION
        +
        +PKCS7_sign_add_signer() adds a signer with certificate B<signcert> and private
        +key B<pkey> using message digest B<md> to a PKCS7 signed data structure
        +B<p7>.
        +
        +The PKCS7 structure should be obtained from an initial call to PKCS7_sign()
        +with the flag B<PKCS7_PARTIAL> set or in the case or re-signing a valid PKCS7
        +signed data structure.
        +
        +If the B<md> parameter is B<NULL> then the default digest for the public
        +key algorithm will be used.
        +
        +Unless the B<PKCS7_REUSE_DIGEST> flag is set the returned PKCS7 structure
        +is not complete and must be finalized either by streaming (if applicable) or
        +a call to PKCS7_final().
        +
        +
        +=head1 NOTES
        +
        +The main purpose of this function is to provide finer control over a PKCS#7
        +signed data structure where the simpler PKCS7_sign() function defaults are
        +not appropriate. For example if multiple signers or non default digest
        +algorithms are needed.
        +
        +Any of the following flags (ored together) can be passed in the B<flags>
        +parameter.
        +
        +If B<PKCS7_REUSE_DIGEST> is set then an attempt is made to copy the content
        +digest value from the PKCS7 struture: to add a signer to an existing structure.
        +An error occurs if a matching digest value cannot be found to copy. The
        +returned PKCS7 structure will be valid and finalized when this flag is set.
        +
        +If B<PKCS7_PARTIAL> is set in addition to B<PKCS7_REUSE_DIGEST> then the 
        +B<PKCS7_SIGNER_INO> structure will not be finalized so additional attributes
        +can be added. In this case an explicit call to PKCS7_SIGNER_INFO_sign() is
        +needed to finalize it.
        +
        +If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the
        +PKCS7 structure, the signer's certificate must still be supplied in the
        +B<signcert> parameter though. This can reduce the size of the signature if the
        +signers certificate can be obtained by other means: for example a previously
        +signed message.
        +
        +The signedData structure includes several PKCS#7 autenticatedAttributes
        +including the signing time, the PKCS#7 content type and the supported list of
        +ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no
        +authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just
        +the SMIMECapabilities are omitted.
        +
        +If present the SMIMECapabilities attribute indicates support for the following
        +algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
        +these algorithms is disabled then it will not be included.
        +
        +
        +PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO
        +structure just added, this can be used to set additional attributes 
        +before it is finalized.
        +
        +=head1 RETURN VALUES
        +
        +PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO
        +structure just added or NULL if an error occurs.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
        +L<PKCS7_final(3)|PKCS7_final(3)>,
        +
        +=head1 HISTORY
        +
        +PPKCS7_sign_add_signer() was added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/PKCS7_verify.pod b/vendor/openssl/openssl/doc/crypto/PKCS7_verify.pod
        new file mode 100644
        index 000000000..7c10a4cc3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/PKCS7_verify.pod
        @@ -0,0 +1,118 @@
        +=pod
        +
        +=head1 NAME
        +
        +PKCS7_verify - verify a PKCS#7 signedData structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags);
        +
        + STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
        +
        +=head1 DESCRIPTION
        +
        +PKCS7_verify() verifies a PKCS#7 signedData structure. B<p7> is the PKCS7
        +structure to verify. B<certs> is a set of certificates in which to search for
        +the signer's certificate. B<store> is a trusted certficate store (used for
        +chain verification). B<indata> is the signed data if the content is not
        +present in B<p7> (that is it is detached). The content is written to B<out>
        +if it is not NULL.
        +
        +B<flags> is an optional set of flags, which can be used to modify the verify
        +operation.
        +
        +PKCS7_get0_signers() retrieves the signer's certificates from B<p7>, it does
        +B<not> check their validity or whether any signatures are valid. The B<certs>
        +and B<flags> parameters have the same meanings as in PKCS7_verify().
        +
        +=head1 VERIFY PROCESS
        +
        +Normally the verify process proceeds as follows.
        +
        +Initially some sanity checks are performed on B<p7>. The type of B<p7> must
        +be signedData. There must be at least one signature on the data and if
        +the content is detached B<indata> cannot be B<NULL>.
        +
        +An attempt is made to locate all the signer's certificates, first looking in
        +the B<certs> parameter (if it is not B<NULL>) and then looking in any certificates
        +contained in the B<p7> structure itself. If any signer's certificates cannot be
        +located the operation fails.
        +
        +Each signer's certificate is chain verified using the B<smimesign> purpose and
        +the supplied trusted certificate store. Any internal certificates in the message
        +are used as untrusted CAs. If any chain verify fails an error code is returned.
        +
        +Finally the signed content is read (and written to B<out> is it is not NULL) and
        +the signature's checked.
        +
        +If all signature's verify correctly then the function is successful.
        +
        +Any of the following flags (ored together) can be passed in the B<flags> parameter
        +to change the default verify behaviour. Only the flag B<PKCS7_NOINTERN> is
        +meaningful to PKCS7_get0_signers().
        +
        +If B<PKCS7_NOINTERN> is set the certificates in the message itself are not 
        +searched when locating the signer's certificate. This means that all the signers
        +certificates must be in the B<certs> parameter.
        +
        +If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are deleted
        +from the content. If the content is not of type B<text/plain> then an error is
        +returned.
        +
        +If B<PKCS7_NOVERIFY> is set the signer's certificates are not chain verified.
        +
        +If B<PKCS7_NOCHAIN> is set then the certificates contained in the message are
        +not used as untrusted CAs. This means that the whole verify chain (apart from
        +the signer's certificate) must be contained in the trusted store.
        +
        +If B<PKCS7_NOSIGS> is set then the signatures on the data are not checked.
        +
        +=head1 NOTES
        +
        +One application of B<PKCS7_NOINTERN> is to only accept messages signed by
        +a small number of certificates. The acceptable certificates would be passed
        +in the B<certs> parameter. In this case if the signer is not one of the
        +certificates supplied in B<certs> then the verify will fail because the
        +signer cannot be found.
        +
        +Care should be taken when modifying the default verify behaviour, for example
        +setting B<PKCS7_NOVERIFY|PKCS7_NOSIGS> will totally disable all verification 
        +and any signed message will be considered valid. This combination is however
        +useful if one merely wishes to write the content to B<out> and its validity
        +is not considered important.
        +
        +Chain verification should arguably be performed  using the signing time rather
        +than the current time. However since the signing time is supplied by the
        +signer it cannot be trusted without additional evidence (such as a trusted
        +timestamp).
        +
        +=head1 RETURN VALUES
        +
        +PKCS7_verify() returns 1 for a successful verification and zero or a negative
        +value if an error occurs.
        +
        +PKCS7_get0_signers() returns all signers or B<NULL> if an error occurred.
        +
        +The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 BUGS
        +
        +The trusted certificate store is not searched for the signers certificate,
        +this is primarily due to the inadequacies of the current B<X509_STORE>
        +functionality.
        +
        +The lack of single pass processing and need to hold all data in memory as
        +mentioned in PKCS7_sign() also applies to PKCS7_verify().
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>
        +
        +=head1 HISTORY
        +
        +PKCS7_verify() was added to OpenSSL 0.9.5
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RAND_add.pod b/vendor/openssl/openssl/doc/crypto/RAND_add.pod
        new file mode 100644
        index 000000000..67c66f3e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RAND_add.pod
        @@ -0,0 +1,77 @@
        +=pod
        +
        +=head1 NAME
        +
        +RAND_add, RAND_seed, RAND_status, RAND_event, RAND_screen - add
        +entropy to the PRNG
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + void RAND_seed(const void *buf, int num);
        +
        + void RAND_add(const void *buf, int num, double entropy);
        +
        + int  RAND_status(void);
        +
        + int  RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam);
        + void RAND_screen(void);
        +
        +=head1 DESCRIPTION
        +
        +RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus,
        +if the data at B<buf> are unpredictable to an adversary, this
        +increases the uncertainty about the state and makes the PRNG output
        +less predictable. Suitable input comes from user interaction (random
        +key presses, mouse movements) and certain hardware events. The
        +B<entropy> argument is (the lower bound of) an estimate of how much
        +randomness is contained in B<buf>, measured in bytes. Details about
        +sources of randomness and how to estimate their entropy can be found
        +in the literature, e.g. RFC 1750.
        +
        +RAND_add() may be called with sensitive data such as user entered
        +passwords. The seed values cannot be recovered from the PRNG output.
        +
        +OpenSSL makes sure that the PRNG state is unique for each thread. On
        +systems that provide C</dev/urandom>, the randomness device is used
        +to seed the PRNG transparently. However, on all other systems, the
        +application is responsible for seeding the PRNG by calling RAND_add(),
        +L<RAND_egd(3)|RAND_egd(3)>
        +or L<RAND_load_file(3)|RAND_load_file(3)>.
        +
        +RAND_seed() is equivalent to RAND_add() when B<num == entropy>.
        +
        +RAND_event() collects the entropy from Windows events such as mouse
        +movements and other user interaction. It should be called with the
        +B<iMsg>, B<wParam> and B<lParam> arguments of I<all> messages sent to
        +the window procedure. It will estimate the entropy contained in the
        +event message (if any), and add it to the PRNG. The program can then
        +process the messages as usual.
        +
        +The RAND_screen() function is available for the convenience of Windows
        +programmers. It adds the current contents of the screen to the PRNG.
        +For applications that can catch Windows events, seeding the PRNG by
        +calling RAND_event() is a significantly better source of
        +randomness. It should be noted that both methods cannot be used on
        +servers that run without user interaction.
        +
        +=head1 RETURN VALUES
        +
        +RAND_status() and RAND_event() return 1 if the PRNG has been seeded
        +with enough data, 0 otherwise.
        +
        +The other functions do not return values.
        +
        +=head1 SEE ALSO
        +
        +L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>,
        +L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)>
        +
        +=head1 HISTORY
        +
        +RAND_seed() and RAND_screen() are available in all versions of SSLeay
        +and OpenSSL. RAND_add() and RAND_status() have been added in OpenSSL
        +0.9.5, RAND_event() in OpenSSL 0.9.5a.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RAND_bytes.pod b/vendor/openssl/openssl/doc/crypto/RAND_bytes.pod
        new file mode 100644
        index 000000000..1a9b91e28
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RAND_bytes.pod
        @@ -0,0 +1,50 @@
        +=pod
        +
        +=head1 NAME
        +
        +RAND_bytes, RAND_pseudo_bytes - generate random data
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + int RAND_bytes(unsigned char *buf, int num);
        +
        + int RAND_pseudo_bytes(unsigned char *buf, int num);
        +
        +=head1 DESCRIPTION
        +
        +RAND_bytes() puts B<num> cryptographically strong pseudo-random bytes
        +into B<buf>. An error occurs if the PRNG has not been seeded with
        +enough randomness to ensure an unpredictable byte sequence.
        +
        +RAND_pseudo_bytes() puts B<num> pseudo-random bytes into B<buf>.
        +Pseudo-random byte sequences generated by RAND_pseudo_bytes() will be
        +unique if they are of sufficient length, but are not necessarily
        +unpredictable. They can be used for non-cryptographic purposes and for
        +certain purposes in cryptographic protocols, but usually not for key
        +generation etc.
        +
        +The contents of B<buf> is mixed into the entropy pool before retrieving
        +the new pseudo-random bytes unless disabled at compile time (see FAQ).
        +
        +=head1 RETURN VALUES
        +
        +RAND_bytes() returns 1 on success, 0 otherwise. The error code can be
        +obtained by L<ERR_get_error(3)|ERR_get_error(3)>. RAND_pseudo_bytes() returns 1 if the
        +bytes generated are cryptographically strong, 0 otherwise. Both
        +functions return -1 if they are not supported by the current RAND
        +method.
        +
        +=head1 SEE ALSO
        +
        +L<rand(3)|rand(3)>, L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<RAND_add(3)|RAND_add(3)>
        +
        +=head1 HISTORY
        +
        +RAND_bytes() is available in all versions of SSLeay and OpenSSL.  It
        +has a return value since OpenSSL 0.9.5. RAND_pseudo_bytes() was added
        +in OpenSSL 0.9.5.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RAND_cleanup.pod b/vendor/openssl/openssl/doc/crypto/RAND_cleanup.pod
        new file mode 100644
        index 000000000..3a8f0749a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RAND_cleanup.pod
        @@ -0,0 +1,29 @@
        +=pod
        +
        +=head1 NAME
        +
        +RAND_cleanup - erase the PRNG state
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + void RAND_cleanup(void);
        +
        +=head1 DESCRIPTION
        +
        +RAND_cleanup() erases the memory used by the PRNG.
        +
        +=head1 RETURN VALUE
        +
        +RAND_cleanup() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<rand(3)|rand(3)>
        +
        +=head1 HISTORY
        +
        +RAND_cleanup() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RAND_egd.pod b/vendor/openssl/openssl/doc/crypto/RAND_egd.pod
        new file mode 100644
        index 000000000..8b8c61d16
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RAND_egd.pod
        @@ -0,0 +1,88 @@
        +=pod
        +
        +=head1 NAME
        +
        +RAND_egd - query entropy gathering daemon
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + int RAND_egd(const char *path);
        + int RAND_egd_bytes(const char *path, int bytes);
        +
        + int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
        +
        +=head1 DESCRIPTION
        +
        +RAND_egd() queries the entropy gathering daemon EGD on socket B<path>.
        +It queries 255 bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the
        +OpenSSL built-in PRNG. RAND_egd(path) is a wrapper for
        +RAND_egd_bytes(path, 255);
        +
        +RAND_egd_bytes() queries the entropy gathering daemon EGD on socket B<path>.
        +It queries B<bytes> bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the
        +OpenSSL built-in PRNG.
        +This function is more flexible than RAND_egd().
        +When only one secret key must
        +be generated, it is not necessary to request the full amount 255 bytes from
        +the EGD socket. This can be advantageous, since the amount of entropy
        +that can be retrieved from EGD over time is limited.
        +
        +RAND_query_egd_bytes() performs the actual query of the EGD daemon on socket
        +B<path>. If B<buf> is given, B<bytes> bytes are queried and written into
        +B<buf>. If B<buf> is NULL, B<bytes> bytes are queried and used to seed the
        +OpenSSL built-in PRNG using L<RAND_add(3)|RAND_add(3)>.
        +
        +=head1 NOTES
        +
        +On systems without /dev/*random devices providing entropy from the kernel,
        +the EGD entropy gathering daemon can be used to collect entropy. It provides
        +a socket interface through which entropy can be gathered in chunks up to
        +255 bytes. Several chunks can be queried during one connection.
        +
        +EGD is available from http://www.lothar.com/tech/crypto/ (C<perl
        +Makefile.PL; make; make install> to install). It is run as B<egd>
        +I<path>, where I<path> is an absolute path designating a socket. When
        +RAND_egd() is called with that path as an argument, it tries to read
        +random bytes that EGD has collected. RAND_egd() retrieves entropy from the
        +daemon using the daemon's "non-blocking read" command which shall
        +be answered immediately by the daemon without waiting for additional
        +entropy to be collected. The write and read socket operations in the
        +communication are blocking.
        +
        +Alternatively, the EGD-interface compatible daemon PRNGD can be used. It is
        +available from
        +http://prngd.sourceforge.net/ .
        +PRNGD does employ an internal PRNG itself and can therefore never run
        +out of entropy.
        +
        +OpenSSL automatically queries EGD when entropy is requested via RAND_bytes()
        +or the status is checked via RAND_status() for the first time, if the socket
        +is located at /var/run/egd-pool, /dev/egd-pool or /etc/egd-pool.
        +
        +=head1 RETURN VALUE
        +
        +RAND_egd() and RAND_egd_bytes() return the number of bytes read from the
        +daemon on success, and -1 if the connection failed or the daemon did not
        +return enough data to fully seed the PRNG.
        +
        +RAND_query_egd_bytes() returns the number of bytes read from the daemon on
        +success, and -1 if the connection failed. The PRNG state is not considered.
        +
        +=head1 SEE ALSO
        +
        +L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>,
        +L<RAND_cleanup(3)|RAND_cleanup(3)>
        +
        +=head1 HISTORY
        +
        +RAND_egd() is available since OpenSSL 0.9.5.
        +
        +RAND_egd_bytes() is available since OpenSSL 0.9.6.
        +
        +RAND_query_egd_bytes() is available since OpenSSL 0.9.7.
        +
        +The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RAND_load_file.pod b/vendor/openssl/openssl/doc/crypto/RAND_load_file.pod
        new file mode 100644
        index 000000000..d8c134e62
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RAND_load_file.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +RAND_load_file, RAND_write_file, RAND_file_name - PRNG seed file
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + const char *RAND_file_name(char *buf, size_t num);
        +
        + int RAND_load_file(const char *filename, long max_bytes);
        +
        + int RAND_write_file(const char *filename);
        +
        +=head1 DESCRIPTION
        +
        +RAND_file_name() generates a default path for the random seed
        +file. B<buf> points to a buffer of size B<num> in which to store the
        +filename. The seed file is $RANDFILE if that environment variable is
        +set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is
        +too small for the path name, an error occurs.
        +
        +RAND_load_file() reads a number of bytes from file B<filename> and
        +adds them to the PRNG. If B<max_bytes> is non-negative,
        +up to to B<max_bytes> are read; starting with OpenSSL 0.9.5,
        +if B<max_bytes> is -1, the complete file is read.
        +
        +RAND_write_file() writes a number of random bytes (currently 1024) to
        +file B<filename> which can be used to initialize the PRNG by calling
        +RAND_load_file() in a later session.
        +
        +=head1 RETURN VALUES
        +
        +RAND_load_file() returns the number of bytes read.
        +
        +RAND_write_file() returns the number of bytes written, and -1 if the
        +bytes written were generated without appropriate seed.
        +
        +RAND_file_name() returns a pointer to B<buf> on success, and NULL on
        +error.
        +
        +=head1 SEE ALSO
        +
        +L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)>
        +
        +=head1 HISTORY
        +
        +RAND_load_file(), RAND_write_file() and RAND_file_name() are available in
        +all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RAND_set_rand_method.pod b/vendor/openssl/openssl/doc/crypto/RAND_set_rand_method.pod
        new file mode 100644
        index 000000000..e5b780fad
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RAND_set_rand_method.pod
        @@ -0,0 +1,83 @@
        +=pod
        +
        +=head1 NAME
        +
        +RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay - select RAND method
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + void RAND_set_rand_method(const RAND_METHOD *meth);
        +
        + const RAND_METHOD *RAND_get_rand_method(void);
        +
        + RAND_METHOD *RAND_SSLeay(void);
        +
        +=head1 DESCRIPTION
        +
        +A B<RAND_METHOD> specifies the functions that OpenSSL uses for random number
        +generation. By modifying the method, alternative implementations such as
        +hardware RNGs may be used. IMPORTANT: See the NOTES section for important
        +information about how these RAND API functions are affected by the use of
        +B<ENGINE> API calls.
        +
        +Initially, the default RAND_METHOD is the OpenSSL internal implementation, as
        +returned by RAND_SSLeay().
        +
        +RAND_set_default_method() makes B<meth> the method for PRNG use. B<NB>: This is
        +true only whilst no ENGINE has been set as a default for RAND, so this function
        +is no longer recommended.
        +
        +RAND_get_default_method() returns a pointer to the current RAND_METHOD.
        +However, the meaningfulness of this result is dependent on whether the ENGINE
        +API is being used, so this function is no longer recommended.
        +
        +=head1 THE RAND_METHOD STRUCTURE
        +
        + typedef struct rand_meth_st
        + {
        +        void (*seed)(const void *buf, int num);
        +        int (*bytes)(unsigned char *buf, int num);
        +        void (*cleanup)(void);
        +        void (*add)(const void *buf, int num, int entropy);
        +        int (*pseudorand)(unsigned char *buf, int num);
        +	int (*status)(void);
        + } RAND_METHOD;
        +
        +The components point to the implementation of RAND_seed(),
        +RAND_bytes(), RAND_cleanup(), RAND_add(), RAND_pseudo_rand()
        +and RAND_status().
        +Each component may be NULL if the function is not implemented.
        +
        +=head1 RETURN VALUES
        +
        +RAND_set_rand_method() returns no value. RAND_get_rand_method() and
        +RAND_SSLeay() return pointers to the respective methods.
        +
        +=head1 NOTES
        +
        +As of version 0.9.7, RAND_METHOD implementations are grouped together with other
        +algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B<ENGINE> modules. If a
        +default ENGINE is specified for RAND functionality using an ENGINE API function,
        +that will override any RAND defaults set using the RAND API (ie.
        +RAND_set_rand_method()). For this reason, the ENGINE API is the recommended way
        +to control default implementations for use in RAND and other cryptographic
        +algorithms.
        +
        +=head1 SEE ALSO
        +
        +L<rand(3)|rand(3)>, L<engine(3)|engine(3)>
        +
        +=head1 HISTORY
        +
        +RAND_set_rand_method(), RAND_get_rand_method() and RAND_SSLeay() are
        +available in all versions of OpenSSL.
        +
        +In the engine version of version 0.9.6, RAND_set_rand_method() was altered to
        +take an ENGINE pointer as its argument. As of version 0.9.7, that has been
        +reverted as the ENGINE API transparently overrides RAND defaults if used,
        +otherwise RAND API functions work as before. RAND_set_rand_engine() was also
        +introduced in version 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_blinding_on.pod b/vendor/openssl/openssl/doc/crypto/RSA_blinding_on.pod
        new file mode 100644
        index 000000000..fd2c69abd
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_blinding_on.pod
        @@ -0,0 +1,43 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_blinding_on, RSA_blinding_off - protect the RSA operation from timing attacks
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
        +
        + void RSA_blinding_off(RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +RSA is vulnerable to timing attacks. In a setup where attackers can
        +measure the time of RSA decryption or signature operations, blinding
        +must be used to protect the RSA operation from that attack.
        +
        +RSA_blinding_on() turns blinding on for key B<rsa> and generates a
        +random blinding factor. B<ctx> is B<NULL> or a pre-allocated and
        +initialized B<BN_CTX>. The random number generator must be seeded
        +prior to calling RSA_blinding_on().
        +
        +RSA_blinding_off() turns blinding off and frees the memory used for
        +the blinding factor.
        +
        +=head1 RETURN VALUES
        +
        +RSA_blinding_on() returns 1 on success, and 0 if an error occurred.
        +
        +RSA_blinding_off() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<rsa(3)|rsa(3)>, L<rand(3)|rand(3)>
        +
        +=head1 HISTORY
        +
        +RSA_blinding_on() and RSA_blinding_off() appeared in SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_check_key.pod b/vendor/openssl/openssl/doc/crypto/RSA_check_key.pod
        new file mode 100644
        index 000000000..a5198f3db
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_check_key.pod
        @@ -0,0 +1,67 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_check_key - validate private RSA keys
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_check_key(RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +This function validates RSA keys. It checks that B<p> and B<q> are
        +in fact prime, and that B<n = p*q>.
        +
        +It also checks that B<d*e = 1 mod (p-1*q-1)>,
        +and that B<dmp1>, B<dmq1> and B<iqmp> are set correctly or are B<NULL>.
        +
        +As such, this function can not be used with any arbitrary RSA key object,
        +even if it is otherwise fit for regular RSA operation. See B<NOTES> for more
        +information.
        +
        +=head1 RETURN VALUE
        +
        +RSA_check_key() returns 1 if B<rsa> is a valid RSA key, and 0 otherwise.
        +-1 is returned if an error occurs while checking the key.
        +
        +If the key is invalid or an error occurred, the reason code can be
        +obtained using L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 NOTES
        +
        +This function does not work on RSA public keys that have only the modulus
        +and public exponent elements populated. It performs integrity checks on all
        +the RSA key material, so the RSA key structure must contain all the private
        +key data too.
        +
        +Unlike most other RSA functions, this function does B<not> work
        +transparently with any underlying ENGINE implementation because it uses the
        +key data in the RSA structure directly. An ENGINE implementation can
        +override the way key data is stored and handled, and can even provide
        +support for HSM keys - in which case the RSA structure may contain B<no>
        +key data at all! If the ENGINE in question is only being used for
        +acceleration or analysis purposes, then in all likelihood the RSA key data
        +is complete and untouched, but this can't be assumed in the general case.
        +
        +=head1 BUGS
        +
        +A method of verifying the RSA key using opaque RSA API functions might need
        +to be considered. Right now RSA_check_key() simply uses the RSA structure
        +elements directly, bypassing the RSA_METHOD table altogether (and
        +completely violating encapsulation and object-orientation in the process).
        +The best fix will probably be to introduce a "check_key()" handler to the
        +RSA_METHOD function table so that alternative implementations can also
        +provide their own verifiers.
        +
        +=head1 SEE ALSO
        +
        +L<rsa(3)|rsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +RSA_check_key() appeared in OpenSSL 0.9.4.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_generate_key.pod b/vendor/openssl/openssl/doc/crypto/RSA_generate_key.pod
        new file mode 100644
        index 000000000..52dbb14a5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_generate_key.pod
        @@ -0,0 +1,69 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_generate_key - generate RSA key pair
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + RSA *RSA_generate_key(int num, unsigned long e,
        +    void (*callback)(int,int,void *), void *cb_arg);
        +
        +=head1 DESCRIPTION
        +
        +RSA_generate_key() generates a key pair and returns it in a newly
        +allocated B<RSA> structure. The pseudo-random number generator must
        +be seeded prior to calling RSA_generate_key().
        +
        +The modulus size will be B<num> bits, and the public exponent will be
        +B<e>. Key sizes with B<num> E<lt> 1024 should be considered insecure.
        +The exponent is an odd number, typically 3, 17 or 65537.
        +
        +A callback function may be used to provide feedback about the
        +progress of the key generation. If B<callback> is not B<NULL>, it
        +will be called as follows:
        +
        +=over 4
        +
        +=item *
        +
        +While a random prime number is generated, it is called as
        +described in L<BN_generate_prime(3)|BN_generate_prime(3)>.
        +
        +=item *
        +
        +When the n-th randomly generated prime is rejected as not
        +suitable for the key, B<callback(2, n, cb_arg)> is called.
        +
        +=item *
        +
        +When a random p has been found with p-1 relatively prime to B<e>,
        +it is called as B<callback(3, 0, cb_arg)>.
        +
        +=back
        +
        +The process is then repeated for prime q with B<callback(3, 1, cb_arg)>.
        +
        +=head1 RETURN VALUE
        +
        +If key generation fails, RSA_generate_key() returns B<NULL>; the
        +error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 BUGS
        +
        +B<callback(2, x, cb_arg)> is used with two different meanings.
        +
        +RSA_generate_key() goes into an infinite loop for illegal input values.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>,
        +L<RSA_free(3)|RSA_free(3)>
        +
        +=head1 HISTORY
        +
        +The B<cb_arg> argument was added in SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_get_ex_new_index.pod b/vendor/openssl/openssl/doc/crypto/RSA_get_ex_new_index.pod
        new file mode 100644
        index 000000000..7d0fd1f91
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_get_ex_new_index.pod
        @@ -0,0 +1,120 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_get_ex_new_index, RSA_set_ex_data, RSA_get_ex_data - add application specific data to RSA structures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_get_ex_new_index(long argl, void *argp,
        +		CRYPTO_EX_new *new_func,
        +		CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func);
        +
        + int RSA_set_ex_data(RSA *r, int idx, void *arg);
        +
        + void *RSA_get_ex_data(RSA *r, int idx);
        +
        + typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                           int idx, long argl, void *argp);
        + typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                             int idx, long argl, void *argp);
        + typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
        +                           int idx, long argl, void *argp);
        +
        +=head1 DESCRIPTION
        +
        +Several OpenSSL structures can have application specific data attached to them.
        +This has several potential uses, it can be used to cache data associated with
        +a structure (for example the hash of some part of the structure) or some
        +additional data (for example a handle to the data in an external library).
        +
        +Since the application data can be anything at all it is passed and retrieved
        +as a B<void *> type.
        +
        +The B<RSA_get_ex_new_index()> function is initially called to "register" some
        +new application specific data. It takes three optional function pointers which
        +are called when the parent structure (in this case an RSA structure) is
        +initially created, when it is copied and when it is freed up. If any or all of
        +these function pointer arguments are not used they should be set to NULL. The
        +precise manner in which these function pointers are called is described in more
        +detail below. B<RSA_get_ex_new_index()> also takes additional long and pointer
        +parameters which will be passed to the supplied functions but which otherwise
        +have no special meaning. It returns an B<index> which should be stored
        +(typically in a static variable) and passed used in the B<idx> parameter in
        +the remaining functions. Each successful call to B<RSA_get_ex_new_index()>
        +will return an index greater than any previously returned, this is important
        +because the optional functions are called in order of increasing index value.
        +
        +B<RSA_set_ex_data()> is used to set application specific data, the data is
        +supplied in the B<arg> parameter and its precise meaning is up to the
        +application.
        +
        +B<RSA_get_ex_data()> is used to retrieve application specific data. The data
        +is returned to the application, this will be the same value as supplied to
        +a previous B<RSA_set_ex_data()> call.
        +
        +B<new_func()> is called when a structure is initially allocated (for example
        +with B<RSA_new()>. The parent structure members will not have any meaningful
        +values at this point. This function will typically be used to allocate any
        +application specific structure.
        +
        +B<free_func()> is called when a structure is being freed up. The dynamic parent
        +structure members should not be accessed because they will be freed up when
        +this function is called.
        +
        +B<new_func()> and B<free_func()> take the same parameters. B<parent> is a
        +pointer to the parent RSA structure. B<ptr> is a the application specific data
        +(this wont be of much use in B<new_func()>. B<ad> is a pointer to the
        +B<CRYPTO_EX_DATA> structure from the parent RSA structure: the functions
        +B<CRYPTO_get_ex_data()> and B<CRYPTO_set_ex_data()> can be called to manipulate
        +it. The B<idx> parameter is the index: this will be the same value returned by
        +B<RSA_get_ex_new_index()> when the functions were initially registered. Finally
        +the B<argl> and B<argp> parameters are the values originally passed to the same
        +corresponding parameters when B<RSA_get_ex_new_index()> was called.
        +
        +B<dup_func()> is called when a structure is being copied. Pointers to the
        +destination and source B<CRYPTO_EX_DATA> structures are passed in the B<to> and
        +B<from> parameters respectively. The B<from_d> parameter is passed a pointer to
        +the source application data when the function is called, when the function returns
        +the value is copied to the destination: the application can thus modify the data
        +pointed to by B<from_d> and have different values in the source and destination.
        +The B<idx>, B<argl> and B<argp> parameters are the same as those in B<new_func()>
        +and B<free_func()>.
        +
        +=head1 RETURN VALUES
        +
        +B<RSA_get_ex_new_index()> returns a new index or -1 on failure (note 0 is a valid
        +index value).
        +
        +B<RSA_set_ex_data()> returns 1 on success or 0 on failure.
        +
        +B<RSA_get_ex_data()> returns the application data or 0 on failure. 0 may also
        +be valid application data but currently it can only fail if given an invalid B<idx>
        +parameter.
        +
        +B<new_func()> and B<dup_func()> should return 0 for failure and 1 for success.
        +
        +On failure an error code can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 BUGS
        +
        +B<dup_func()> is currently never called.
        +
        +The return value of B<new_func()> is ignored.
        +
        +The B<new_func()> function isn't very useful because no meaningful values are
        +present in the parent RSA structure when it is called.
        +
        +=head1 SEE ALSO
        +
        +L<rsa(3)|rsa(3)>, L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
        +
        +=head1 HISTORY
        +
        +RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data() are
        +available since SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_new.pod b/vendor/openssl/openssl/doc/crypto/RSA_new.pod
        new file mode 100644
        index 000000000..3d15b9282
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_new.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_new, RSA_free - allocate and free RSA objects
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + RSA * RSA_new(void);
        +
        + void RSA_free(RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +RSA_new() allocates and initializes an B<RSA> structure. It is equivalent to
        +calling RSA_new_method(NULL).
        +
        +RSA_free() frees the B<RSA> structure and its components. The key is
        +erased before the memory is returned to the system.
        +
        +=head1 RETURN VALUES
        +
        +If the allocation fails, RSA_new() returns B<NULL> and sets an error
        +code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns
        +a pointer to the newly allocated structure.
        +
        +RSA_free() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<rsa(3)|rsa(3)>,
        +L<RSA_generate_key(3)|RSA_generate_key(3)>,
        +L<RSA_new_method(3)|RSA_new_method(3)>
        +
        +=head1 HISTORY
        +
        +RSA_new() and RSA_free() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod b/vendor/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod
        new file mode 100644
        index 000000000..b8f678fe7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod
        @@ -0,0 +1,124 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_padding_add_PKCS1_type_1, RSA_padding_check_PKCS1_type_1,
        +RSA_padding_add_PKCS1_type_2, RSA_padding_check_PKCS1_type_2,
        +RSA_padding_add_PKCS1_OAEP, RSA_padding_check_PKCS1_OAEP,
        +RSA_padding_add_SSLv23, RSA_padding_check_SSLv23,
        +RSA_padding_add_none, RSA_padding_check_none - asymmetric encryption
        +padding
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
        +    unsigned char *f, int fl);
        +
        + int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
        +    unsigned char *f, int fl, int rsa_len);
        +
        + int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
        +    unsigned char *f, int fl);
        +
        + int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
        +    unsigned char *f, int fl, int rsa_len);
        +
        + int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
        +    unsigned char *f, int fl, unsigned char *p, int pl);
        +
        + int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
        +    unsigned char *f, int fl, int rsa_len, unsigned char *p, int pl);
        +
        + int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
        +    unsigned char *f, int fl);
        +
        + int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
        +    unsigned char *f, int fl, int rsa_len);
        +
        + int RSA_padding_add_none(unsigned char *to, int tlen,
        +    unsigned char *f, int fl);
        +
        + int RSA_padding_check_none(unsigned char *to, int tlen,
        +    unsigned char *f, int fl, int rsa_len);
        +
        +=head1 DESCRIPTION
        +
        +The RSA_padding_xxx_xxx() functions are called from the RSA encrypt,
        +decrypt, sign and verify functions. Normally they should not be called
        +from application programs.
        +
        +However, they can also be called directly to implement padding for other
        +asymmetric ciphers. RSA_padding_add_PKCS1_OAEP() and
        +RSA_padding_check_PKCS1_OAEP() may be used in an application combined
        +with B<RSA_NO_PADDING> in order to implement OAEP with an encoding
        +parameter.
        +
        +RSA_padding_add_xxx() encodes B<fl> bytes from B<f> so as to fit into
        +B<tlen> bytes and stores the result at B<to>. An error occurs if B<fl>
        +does not meet the size requirements of the encoding method.
        +
        +The following encoding methods are implemented:
        +
        +=over 4
        +
        +=item PKCS1_type_1
        +
        +PKCS #1 v2.0 EMSA-PKCS1-v1_5 (PKCS #1 v1.5 block type 1); used for signatures
        +
        +=item PKCS1_type_2
        +
        +PKCS #1 v2.0 EME-PKCS1-v1_5 (PKCS #1 v1.5 block type 2)
        +
        +=item PKCS1_OAEP
        +
        +PKCS #1 v2.0 EME-OAEP
        +
        +=item SSLv23
        +
        +PKCS #1 EME-PKCS1-v1_5 with SSL-specific modification
        +
        +=item none
        +
        +simply copy the data
        +
        +=back
        +
        +The random number generator must be seeded prior to calling
        +RSA_padding_add_xxx().
        +
        +RSA_padding_check_xxx() verifies that the B<fl> bytes at B<f> contain
        +a valid encoding for a B<rsa_len> byte RSA key in the respective
        +encoding method and stores the recovered data of at most B<tlen> bytes
        +(for B<RSA_NO_PADDING>: of size B<tlen>)
        +at B<to>.
        +
        +For RSA_padding_xxx_OAEP(), B<p> points to the encoding parameter
        +of length B<pl>. B<p> may be B<NULL> if B<pl> is 0.
        +
        +=head1 RETURN VALUES
        +
        +The RSA_padding_add_xxx() functions return 1 on success, 0 on error.
        +The RSA_padding_check_xxx() functions return the length of the
        +recovered data, -1 on error. Error codes can be obtained by calling
        +L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>,
        +L<RSA_private_decrypt(3)|RSA_private_decrypt(3)>,
        +L<RSA_sign(3)|RSA_sign(3)>, L<RSA_verify(3)|RSA_verify(3)>
        +
        +=head1 HISTORY
        +
        +RSA_padding_add_PKCS1_type_1(), RSA_padding_check_PKCS1_type_1(),
        +RSA_padding_add_PKCS1_type_2(), RSA_padding_check_PKCS1_type_2(),
        +RSA_padding_add_SSLv23(), RSA_padding_check_SSLv23(),
        +RSA_padding_add_none() and RSA_padding_check_none() appeared in
        +SSLeay 0.9.0.
        +
        +RSA_padding_add_PKCS1_OAEP() and RSA_padding_check_PKCS1_OAEP() were
        +added in OpenSSL 0.9.2b.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_print.pod b/vendor/openssl/openssl/doc/crypto/RSA_print.pod
        new file mode 100644
        index 000000000..c971e91f4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_print.pod
        @@ -0,0 +1,49 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_print, RSA_print_fp,
        +DSAparams_print, DSAparams_print_fp, DSA_print, DSA_print_fp,
        +DHparams_print, DHparams_print_fp - print cryptographic parameters
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_print(BIO *bp, RSA *x, int offset);
        + int RSA_print_fp(FILE *fp, RSA *x, int offset);
        +
        + #include <openssl/dsa.h>
        +
        + int DSAparams_print(BIO *bp, DSA *x);
        + int DSAparams_print_fp(FILE *fp, DSA *x);
        + int DSA_print(BIO *bp, DSA *x, int offset);
        + int DSA_print_fp(FILE *fp, DSA *x, int offset);
        +
        + #include <openssl/dh.h>
        +
        + int DHparams_print(BIO *bp, DH *x);
        + int DHparams_print_fp(FILE *fp, DH *x);
        +
        +=head1 DESCRIPTION
        +
        +A human-readable hexadecimal output of the components of the RSA
        +key, DSA parameters or key or DH parameters is printed to B<bp> or B<fp>.
        +
        +The output lines are indented by B<offset> spaces.
        +
        +=head1 RETURN VALUES
        +
        +These functions return 1 on success, 0 on error.
        +
        +=head1 SEE ALSO
        +
        +L<dh(3)|dh(3)>, L<dsa(3)|dsa(3)>, L<rsa(3)|rsa(3)>, L<BN_bn2bin(3)|BN_bn2bin(3)>
        +
        +=head1 HISTORY
        +
        +RSA_print(), RSA_print_fp(), DSA_print(), DSA_print_fp(), DH_print(),
        +DH_print_fp() are available in all versions of SSLeay and OpenSSL.
        +DSAparams_print() and DSAparams_print_fp() were added in SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_private_encrypt.pod b/vendor/openssl/openssl/doc/crypto/RSA_private_encrypt.pod
        new file mode 100644
        index 000000000..746a80c79
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_private_encrypt.pod
        @@ -0,0 +1,70 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_private_encrypt, RSA_public_decrypt - low level signature operations
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_private_encrypt(int flen, unsigned char *from,
        +    unsigned char *to, RSA *rsa, int padding);
        +
        + int RSA_public_decrypt(int flen, unsigned char *from, 
        +    unsigned char *to, RSA *rsa, int padding);
        +
        +=head1 DESCRIPTION
        +
        +These functions handle RSA signatures at a low level.
        +
        +RSA_private_encrypt() signs the B<flen> bytes at B<from> (usually a
        +message digest with an algorithm identifier) using the private key
        +B<rsa> and stores the signature in B<to>. B<to> must point to
        +B<RSA_size(rsa)> bytes of memory.
        +
        +B<padding> denotes one of the following modes:
        +
        +=over 4
        +
        +=item RSA_PKCS1_PADDING
        +
        +PKCS #1 v1.5 padding. This function does not handle the
        +B<algorithmIdentifier> specified in PKCS #1. When generating or
        +verifying PKCS #1 signatures, L<RSA_sign(3)|RSA_sign(3)> and L<RSA_verify(3)|RSA_verify(3)> should be
        +used.
        +
        +=item RSA_NO_PADDING
        +
        +Raw RSA signature. This mode should I<only> be used to implement
        +cryptographically sound padding modes in the application code.
        +Signing user data directly with RSA is insecure.
        +
        +=back
        +
        +RSA_public_decrypt() recovers the message digest from the B<flen>
        +bytes long signature at B<from> using the signer's public key
        +B<rsa>. B<to> must point to a memory section large enough to hold the
        +message digest (which is smaller than B<RSA_size(rsa) -
        +11>). B<padding> is the padding mode that was used to sign the data.
        +
        +=head1 RETURN VALUES
        +
        +RSA_private_encrypt() returns the size of the signature (i.e.,
        +RSA_size(rsa)). RSA_public_decrypt() returns the size of the
        +recovered message digest.
        +
        +On error, -1 is returned; the error codes can be
        +obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<rsa(3)|rsa(3)>,
        +L<RSA_sign(3)|RSA_sign(3)>, L<RSA_verify(3)|RSA_verify(3)>
        +
        +=head1 HISTORY
        +
        +The B<padding> argument was added in SSLeay 0.8. RSA_NO_PADDING is
        +available since SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_public_encrypt.pod b/vendor/openssl/openssl/doc/crypto/RSA_public_encrypt.pod
        new file mode 100644
        index 000000000..ab0fe3b2c
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_public_encrypt.pod
        @@ -0,0 +1,84 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_public_encrypt, RSA_private_decrypt - RSA public key cryptography
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_public_encrypt(int flen, unsigned char *from,
        +    unsigned char *to, RSA *rsa, int padding);
        +
        + int RSA_private_decrypt(int flen, unsigned char *from,
        +     unsigned char *to, RSA *rsa, int padding);
        +
        +=head1 DESCRIPTION
        +
        +RSA_public_encrypt() encrypts the B<flen> bytes at B<from> (usually a
        +session key) using the public key B<rsa> and stores the ciphertext in
        +B<to>. B<to> must point to RSA_size(B<rsa>) bytes of memory.
        +
        +B<padding> denotes one of the following modes:
        +
        +=over 4
        +
        +=item RSA_PKCS1_PADDING
        +
        +PKCS #1 v1.5 padding. This currently is the most widely used mode.
        +
        +=item RSA_PKCS1_OAEP_PADDING
        +
        +EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty
        +encoding parameter. This mode is recommended for all new applications.
        +
        +=item RSA_SSLV23_PADDING
        +
        +PKCS #1 v1.5 padding with an SSL-specific modification that denotes
        +that the server is SSL3 capable.
        +
        +=item RSA_NO_PADDING
        +
        +Raw RSA encryption. This mode should I<only> be used to implement
        +cryptographically sound padding modes in the application code.
        +Encrypting user data directly with RSA is insecure.
        +
        +=back
        +
        +B<flen> must be less than RSA_size(B<rsa>) - 11 for the PKCS #1 v1.5
        +based padding modes, less than RSA_size(B<rsa>) - 41 for
        +RSA_PKCS1_OAEP_PADDING and exactly RSA_size(B<rsa>) for RSA_NO_PADDING.
        +The random number generator must be seeded prior to calling
        +RSA_public_encrypt().
        +
        +RSA_private_decrypt() decrypts the B<flen> bytes at B<from> using the
        +private key B<rsa> and stores the plaintext in B<to>. B<to> must point
        +to a memory section large enough to hold the decrypted data (which is
        +smaller than RSA_size(B<rsa>)). B<padding> is the padding mode that
        +was used to encrypt the data.
        +
        +=head1 RETURN VALUES
        +
        +RSA_public_encrypt() returns the size of the encrypted data (i.e.,
        +RSA_size(B<rsa>)). RSA_private_decrypt() returns the size of the
        +recovered plaintext.
        +
        +On error, -1 is returned; the error codes can be
        +obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 CONFORMING TO
        +
        +SSL, PKCS #1 v2.0
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>,
        +L<RSA_size(3)|RSA_size(3)>
        +
        +=head1 HISTORY
        +
        +The B<padding> argument was added in SSLeay 0.8. RSA_NO_PADDING is
        +available since SSLeay 0.9.0, OAEP was added in OpenSSL 0.9.2b.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_set_method.pod b/vendor/openssl/openssl/doc/crypto/RSA_set_method.pod
        new file mode 100644
        index 000000000..2c963d7e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_set_method.pod
        @@ -0,0 +1,202 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_set_default_method, RSA_get_default_method, RSA_set_method,
        +RSA_get_method, RSA_PKCS1_SSLeay, RSA_null_method, RSA_flags,
        +RSA_new_method - select RSA method
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + void RSA_set_default_method(const RSA_METHOD *meth);
        +
        + RSA_METHOD *RSA_get_default_method(void);
        +
        + int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
        +
        + RSA_METHOD *RSA_get_method(const RSA *rsa);
        +
        + RSA_METHOD *RSA_PKCS1_SSLeay(void);
        +
        + RSA_METHOD *RSA_null_method(void);
        +
        + int RSA_flags(const RSA *rsa);
        +
        + RSA *RSA_new_method(RSA_METHOD *method);
        +
        +=head1 DESCRIPTION
        +
        +An B<RSA_METHOD> specifies the functions that OpenSSL uses for RSA
        +operations. By modifying the method, alternative implementations such as
        +hardware accelerators may be used. IMPORTANT: See the NOTES section for
        +important information about how these RSA API functions are affected by the
        +use of B<ENGINE> API calls.
        +
        +Initially, the default RSA_METHOD is the OpenSSL internal implementation,
        +as returned by RSA_PKCS1_SSLeay().
        +
        +RSA_set_default_method() makes B<meth> the default method for all RSA
        +structures created later. B<NB>: This is true only whilst no ENGINE has
        +been set as a default for RSA, so this function is no longer recommended.
        +
        +RSA_get_default_method() returns a pointer to the current default
        +RSA_METHOD. However, the meaningfulness of this result is dependent on
        +whether the ENGINE API is being used, so this function is no longer 
        +recommended.
        +
        +RSA_set_method() selects B<meth> to perform all operations using the key
        +B<rsa>. This will replace the RSA_METHOD used by the RSA key and if the
        +previous method was supplied by an ENGINE, the handle to that ENGINE will
        +be released during the change. It is possible to have RSA keys that only
        +work with certain RSA_METHOD implementations (eg. from an ENGINE module
        +that supports embedded hardware-protected keys), and in such cases
        +attempting to change the RSA_METHOD for the key can have unexpected
        +results.
        +
        +RSA_get_method() returns a pointer to the RSA_METHOD being used by B<rsa>.
        +This method may or may not be supplied by an ENGINE implementation, but if
        +it is, the return value can only be guaranteed to be valid as long as the
        +RSA key itself is valid and does not have its implementation changed by
        +RSA_set_method().
        +
        +RSA_flags() returns the B<flags> that are set for B<rsa>'s current
        +RSA_METHOD. See the BUGS section.
        +
        +RSA_new_method() allocates and initializes an RSA structure so that
        +B<engine> will be used for the RSA operations. If B<engine> is NULL, the
        +default ENGINE for RSA operations is used, and if no default ENGINE is set,
        +the RSA_METHOD controlled by RSA_set_default_method() is used.
        +
        +RSA_flags() returns the B<flags> that are set for B<rsa>'s current method.
        +
        +RSA_new_method() allocates and initializes an B<RSA> structure so that
        +B<method> will be used for the RSA operations. If B<method> is B<NULL>,
        +the default method is used.
        +
        +=head1 THE RSA_METHOD STRUCTURE
        +
        + typedef struct rsa_meth_st
        + {
        +     /* name of the implementation */
        +	const char *name;
        +
        +     /* encrypt */
        +	int (*rsa_pub_enc)(int flen, unsigned char *from,
        +          unsigned char *to, RSA *rsa, int padding);
        +
        +     /* verify arbitrary data */
        +	int (*rsa_pub_dec)(int flen, unsigned char *from,
        +          unsigned char *to, RSA *rsa, int padding);
        +
        +     /* sign arbitrary data */
        +	int (*rsa_priv_enc)(int flen, unsigned char *from,
        +          unsigned char *to, RSA *rsa, int padding);
        +
        +     /* decrypt */
        +	int (*rsa_priv_dec)(int flen, unsigned char *from,
        +          unsigned char *to, RSA *rsa, int padding);
        +
        +     /* compute r0 = r0 ^ I mod rsa->n (May be NULL for some
        +                                        implementations) */
        +	int (*rsa_mod_exp)(BIGNUM *r0, BIGNUM *I, RSA *rsa);
        +
        +     /* compute r = a ^ p mod m (May be NULL for some implementations) */
        +	int (*bn_mod_exp)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
        +          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +
        +     /* called at RSA_new */
        +	int (*init)(RSA *rsa);
        +
        +     /* called at RSA_free */
        +	int (*finish)(RSA *rsa);
        +
        +     /* RSA_FLAG_EXT_PKEY        - rsa_mod_exp is called for private key
        +      *                            operations, even if p,q,dmp1,dmq1,iqmp
        +      *                            are NULL
        +      * RSA_FLAG_SIGN_VER        - enable rsa_sign and rsa_verify
        +      * RSA_METHOD_FLAG_NO_CHECK - don't check pub/private match
        +      */
        +	int flags;
        +
        +	char *app_data; /* ?? */
        +
        +     /* sign. For backward compatibility, this is used only
        +      * if (flags & RSA_FLAG_SIGN_VER)
        +      */
        +	int (*rsa_sign)(int type, unsigned char *m, unsigned int m_len,
        +           unsigned char *sigret, unsigned int *siglen, RSA *rsa);
        +
        +     /* verify. For backward compatibility, this is used only
        +      * if (flags & RSA_FLAG_SIGN_VER)
        +      */
        +	int (*rsa_verify)(int type, unsigned char *m, unsigned int m_len,
        +           unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
        +
        + } RSA_METHOD;
        +
        +=head1 RETURN VALUES
        +
        +RSA_PKCS1_SSLeay(), RSA_PKCS1_null_method(), RSA_get_default_method()
        +and RSA_get_method() return pointers to the respective RSA_METHODs.
        +
        +RSA_set_default_method() returns no value.
        +
        +RSA_set_method() returns a pointer to the old RSA_METHOD implementation
        +that was replaced. However, this return value should probably be ignored
        +because if it was supplied by an ENGINE, the pointer could be invalidated
        +at any time if the ENGINE is unloaded (in fact it could be unloaded as a
        +result of the RSA_set_method() function releasing its handle to the
        +ENGINE). For this reason, the return type may be replaced with a B<void>
        +declaration in a future release.
        +
        +RSA_new_method() returns NULL and sets an error code that can be obtained
        +by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation fails. Otherwise
        +it returns a pointer to the newly allocated structure.
        +
        +=head1 NOTES
        +
        +As of version 0.9.7, RSA_METHOD implementations are grouped together with
        +other algorithmic APIs (eg. DSA_METHOD, EVP_CIPHER, etc) into B<ENGINE>
        +modules. If a default ENGINE is specified for RSA functionality using an
        +ENGINE API function, that will override any RSA defaults set using the RSA
        +API (ie.  RSA_set_default_method()). For this reason, the ENGINE API is the
        +recommended way to control default implementations for use in RSA and other
        +cryptographic algorithms.
        +
        +=head1 BUGS
        +
        +The behaviour of RSA_flags() is a mis-feature that is left as-is for now
        +to avoid creating compatibility problems. RSA functionality, such as the
        +encryption functions, are controlled by the B<flags> value in the RSA key
        +itself, not by the B<flags> value in the RSA_METHOD attached to the RSA key
        +(which is what this function returns). If the flags element of an RSA key
        +is changed, the changes will be honoured by RSA functionality but will not
        +be reflected in the return value of the RSA_flags() function - in effect
        +RSA_flags() behaves more like an RSA_default_flags() function (which does
        +not currently exist).
        +
        +=head1 SEE ALSO
        +
        +L<rsa(3)|rsa(3)>, L<RSA_new(3)|RSA_new(3)>
        +
        +=head1 HISTORY
        +
        +RSA_new_method() and RSA_set_default_method() appeared in SSLeay 0.8.
        +RSA_get_default_method(), RSA_set_method() and RSA_get_method() as
        +well as the rsa_sign and rsa_verify components of RSA_METHOD were
        +added in OpenSSL 0.9.4.
        +
        +RSA_set_default_openssl_method() and RSA_get_default_openssl_method()
        +replaced RSA_set_default_method() and RSA_get_default_method()
        +respectively, and RSA_set_method() and RSA_new_method() were altered to use
        +B<ENGINE>s rather than B<RSA_METHOD>s during development of the engine
        +version of OpenSSL 0.9.6. For 0.9.7, the handling of defaults in the ENGINE
        +API was restructured so that this change was reversed, and behaviour of the
        +other functions resembled more closely the previous behaviour. The
        +behaviour of defaults in the ENGINE API now transparently overrides the
        +behaviour of defaults in the RSA API without requiring changing these
        +function prototypes.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_sign.pod b/vendor/openssl/openssl/doc/crypto/RSA_sign.pod
        new file mode 100644
        index 000000000..8553be8e9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_sign.pod
        @@ -0,0 +1,62 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_sign, RSA_verify - RSA signatures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
        +    unsigned char *sigret, unsigned int *siglen, RSA *rsa);
        +
        + int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
        +    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +RSA_sign() signs the message digest B<m> of size B<m_len> using the
        +private key B<rsa> as specified in PKCS #1 v2.0. It stores the
        +signature in B<sigret> and the signature size in B<siglen>. B<sigret>
        +must point to RSA_size(B<rsa>) bytes of memory.
        +
        +B<type> denotes the message digest algorithm that was used to generate
        +B<m>. It usually is one of B<NID_sha1>, B<NID_ripemd160> and B<NID_md5>;
        +see L<objects(3)|objects(3)> for details. If B<type> is B<NID_md5_sha1>,
        +an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding
        +and no algorithm identifier) is created.
        +
        +RSA_verify() verifies that the signature B<sigbuf> of size B<siglen>
        +matches a given message digest B<m> of size B<m_len>. B<type> denotes
        +the message digest algorithm that was used to generate the signature.
        +B<rsa> is the signer's public key.
        +
        +=head1 RETURN VALUES
        +
        +RSA_sign() returns 1 on success, 0 otherwise.  RSA_verify() returns 1
        +on successful verification, 0 otherwise.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 BUGS
        +
        +Certain signatures with an improper algorithm identifier are accepted
        +for compatibility with SSLeay 0.4.5 :-)
        +
        +=head1 CONFORMING TO
        +
        +SSL, PKCS #1 v2.0
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<objects(3)|objects(3)>,
        +L<rsa(3)|rsa(3)>, L<RSA_private_encrypt(3)|RSA_private_encrypt(3)>,
        +L<RSA_public_decrypt(3)|RSA_public_decrypt(3)> 
        +
        +=head1 HISTORY
        +
        +RSA_sign() and RSA_verify() are available in all versions of SSLeay
        +and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod b/vendor/openssl/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod
        new file mode 100644
        index 000000000..e70380bbf
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod
        @@ -0,0 +1,59 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_sign_ASN1_OCTET_STRING, RSA_verify_ASN1_OCTET_STRING - RSA signatures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m,
        +    unsigned int m_len, unsigned char *sigret, unsigned int *siglen,
        +    RSA *rsa);
        +
        + int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m,
        +    unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
        +    RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +RSA_sign_ASN1_OCTET_STRING() signs the octet string B<m> of size
        +B<m_len> using the private key B<rsa> represented in DER using PKCS #1
        +padding. It stores the signature in B<sigret> and the signature size
        +in B<siglen>. B<sigret> must point to B<RSA_size(rsa)> bytes of
        +memory.
        +
        +B<dummy> is ignored.
        +
        +The random number generator must be seeded prior to calling RSA_sign_ASN1_OCTET_STRING().
        +
        +RSA_verify_ASN1_OCTET_STRING() verifies that the signature B<sigbuf>
        +of size B<siglen> is the DER representation of a given octet string
        +B<m> of size B<m_len>. B<dummy> is ignored. B<rsa> is the signer's
        +public key.
        +
        +=head1 RETURN VALUES
        +
        +RSA_sign_ASN1_OCTET_STRING() returns 1 on success, 0 otherwise.
        +RSA_verify_ASN1_OCTET_STRING() returns 1 on successful verification, 0
        +otherwise.
        +
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 BUGS
        +
        +These functions serve no recognizable purpose.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<objects(3)|objects(3)>,
        +L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<RSA_sign(3)|RSA_sign(3)>,
        +L<RSA_verify(3)|RSA_verify(3)>
        +
        +=head1 HISTORY
        +
        +RSA_sign_ASN1_OCTET_STRING() and RSA_verify_ASN1_OCTET_STRING() were
        +added in SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/RSA_size.pod b/vendor/openssl/openssl/doc/crypto/RSA_size.pod
        new file mode 100644
        index 000000000..5b7f835f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/RSA_size.pod
        @@ -0,0 +1,33 @@
        +=pod
        +
        +=head1 NAME
        +
        +RSA_size - get RSA modulus size
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        +
        + int RSA_size(const RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +This function returns the RSA modulus size in bytes. It can be used to
        +determine how much memory must be allocated for an RSA encrypted
        +value.
        +
        +B<rsa-E<gt>n> must not be B<NULL>.
        +
        +=head1 RETURN VALUE
        +
        +The size in bytes.
        +
        +=head1 SEE ALSO
        +
        +L<rsa(3)|rsa(3)>
        +
        +=head1 HISTORY
        +
        +RSA_size() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/SMIME_read_CMS.pod b/vendor/openssl/openssl/doc/crypto/SMIME_read_CMS.pod
        new file mode 100644
        index 000000000..acc5524c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/SMIME_read_CMS.pod
        @@ -0,0 +1,70 @@
        +=pod
        +
        +=head1 NAME
        +
        + SMIME_read_CMS - parse S/MIME message.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont);
        +
        +=head1 DESCRIPTION
        +
        +SMIME_read_CMS() parses a message in S/MIME format.
        +
        +B<in> is a BIO to read the message from.
        +
        +If cleartext signing is used then the content is saved in a memory bio which is
        +written to B<*bcont>, otherwise B<*bcont> is set to NULL.
        +
        +The parsed CMS_ContentInfo structure is returned or NULL if an
        +error occurred.
        +
        +=head1 NOTES
        +
        +If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can
        +then be passed to CMS_verify() with the B<CMS_DETACHED> flag set.
        +
        +Otherwise the type of the returned structure can be determined
        +using CMS_get0_type().
        +
        +To support future functionality if B<bcont> is not NULL B<*bcont> should be
        +initialized to NULL. For example:
        +
        + BIO *cont = NULL;
        + CMS_ContentInfo *cms;
        +
        + cms = SMIME_read_CMS(in, &cont);
        +
        +=head1 BUGS
        +
        +The MIME parser used by SMIME_read_CMS() is somewhat primitive.  While it will
        +handle most S/MIME messages more complex compound formats may not work.
        +
        +The parser assumes that the CMS_ContentInfo structure is always base64 encoded
        +and will not handle the case where it is in binary format or uses quoted
        +printable format.
        +
        +The use of a memory BIO to hold the signed content limits the size of message
        +which can be processed due to memory restraints: a streaming single pass option
        +should be available.
        +
        +=head1 RETURN VALUES
        +
        +SMIME_read_CMS() returns a valid B<CMS_ContentInfo> structure or B<NULL>
        +if an error occurred. The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_type(3)|CMS_type(3)>
        +L<SMIME_read_CMS(3)|SMIME_read_CMS(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
        +L<CMS_decrypt(3)|CMS_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +SMIME_read_CMS() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/SMIME_read_PKCS7.pod b/vendor/openssl/openssl/doc/crypto/SMIME_read_PKCS7.pod
        new file mode 100644
        index 000000000..9d4671594
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/SMIME_read_PKCS7.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +SMIME_read_PKCS7 - parse S/MIME message.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont);
        +
        +=head1 DESCRIPTION
        +
        +SMIME_read_PKCS7() parses a message in S/MIME format.
        +
        +B<in> is a BIO to read the message from.
        +
        +If cleartext signing is used then the content is saved in
        +a memory bio which is written to B<*bcont>, otherwise
        +B<*bcont> is set to B<NULL>.
        +
        +The parsed PKCS#7 structure is returned or B<NULL> if an
        +error occurred.
        +
        +=head1 NOTES
        +
        +If B<*bcont> is not B<NULL> then the message is clear text
        +signed. B<*bcont> can then be passed to PKCS7_verify() with
        +the B<PKCS7_DETACHED> flag set.
        +
        +Otherwise the type of the returned structure can be determined
        +using PKCS7_type().
        +
        +To support future functionality if B<bcont> is not B<NULL>
        +B<*bcont> should be initialized to B<NULL>. For example:
        +
        + BIO *cont = NULL;
        + PKCS7 *p7;
        +
        + p7 = SMIME_read_PKCS7(in, &cont);
        +
        +=head1 BUGS
        +
        +The MIME parser used by SMIME_read_PKCS7() is somewhat primitive.
        +While it will handle most S/MIME messages more complex compound
        +formats may not work.
        +
        +The parser assumes that the PKCS7 structure is always base64
        +encoded and will not handle the case where it is in binary format
        +or uses quoted printable format.
        +
        +The use of a memory BIO to hold the signed content limits the size
        +of message which can be processed due to memory restraints: a
        +streaming single pass option should be available.
        +
        +=head1 RETURN VALUES
        +
        +SMIME_read_PKCS7() returns a valid B<PKCS7> structure or B<NULL>
        +is an error occurred. The error can be obtained from ERR_get_error(3).
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_type(3)|PKCS7_type(3)>
        +L<SMIME_read_PKCS7(3)|SMIME_read_PKCS7(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
        +L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
        +L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +SMIME_read_PKCS7() was added to OpenSSL 0.9.5
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/SMIME_write_CMS.pod b/vendor/openssl/openssl/doc/crypto/SMIME_write_CMS.pod
        new file mode 100644
        index 000000000..04bedfb42
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/SMIME_write_CMS.pod
        @@ -0,0 +1,64 @@
        +=pod
        +
        +=head1 NAME
        +
        + SMIME_write_CMS - convert CMS structure to S/MIME format.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int SMIME_write_CMS(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +SMIME_write_CMS() adds the appropriate MIME headers to a CMS
        +structure to produce an S/MIME message.
        +
        +B<out> is the BIO to write the data to. B<cms> is the appropriate
        +B<CMS_ContentInfo> structure. If streaming is enabled then the content must be
        +supplied in the B<data> argument. B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If B<CMS_DETACHED> is set then cleartext signing will be used, this option only
        +makes sense for SignedData where B<CMS_DETACHED> is also set when CMS_sign() is
        +called.
        +
        +If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are added to
        +the content, this only makes sense if B<CMS_DETACHED> is also set.
        +
        +If the B<CMS_STREAM> flag is set streaming is performed. This flag should only
        +be set if B<CMS_STREAM> was also set in the previous call to a CMS_ContentInfo
        +creation function.
        +
        +If cleartext signing is being used and B<CMS_STREAM> not set then the data must
        +be read twice: once to compute the signature in CMS_sign() and once to output
        +the S/MIME message.
        +
        +If streaming is performed the content is output in BER format using indefinite
        +length constructed encoding except in the case of signed data with detached
        +content where the content is absent and DER format is used.
        +
        +=head1 BUGS
        +
        +SMIME_write_CMS() always base64 encodes CMS structures, there should be an
        +option to disable this.
        +
        +=head1 RETURN VALUES
        +
        +SMIME_write_CMS() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
        +L<CMS_decrypt(3)|CMS_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +SMIME_write_CMS() was added to OpenSSL 0.9.8
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/SMIME_write_PKCS7.pod b/vendor/openssl/openssl/doc/crypto/SMIME_write_PKCS7.pod
        new file mode 100644
        index 000000000..ca6bd0276
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/SMIME_write_PKCS7.pod
        @@ -0,0 +1,65 @@
        +=pod
        +
        +=head1 NAME
        +
        +SMIME_write_PKCS7 - convert PKCS#7 structure to S/MIME format.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7
        +structure to produce an S/MIME message.
        +
        +B<out> is the BIO to write the data to. B<p7> is the appropriate B<PKCS7>
        +structure. If streaming is enabled then the content must be supplied in the
        +B<data> argument. B<flags> is an optional set of flags.
        +
        +=head1 NOTES
        +
        +The following flags can be passed in the B<flags> parameter.
        +
        +If B<PKCS7_DETACHED> is set then cleartext signing will be used,
        +this option only makes sense for signedData where B<PKCS7_DETACHED>
        +is also set when PKCS7_sign() is also called.
        +
        +If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain>
        +are added to the content, this only makes sense if B<PKCS7_DETACHED>
        +is also set.
        +
        +If the B<PKCS7_STREAM> flag is set streaming is performed. This flag should
        +only be set if B<PKCS7_STREAM> was also set in the previous call to
        +PKCS7_sign() or B<PKCS7_encrypt()>.
        +
        +If cleartext signing is being used and B<PKCS7_STREAM> not set then
        +the data must be read twice: once to compute the signature in PKCS7_sign()
        +and once to output the S/MIME message.
        +
        +If streaming is performed the content is output in BER format using indefinite
        +length constructuted encoding except in the case of signed data with detached
        +content where the content is absent and DER format is used.
        +
        +=head1 BUGS
        +
        +SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there
        +should be an option to disable this.
        +
        +=head1 RETURN VALUES
        +
        +SMIME_write_PKCS7() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
        +L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
        +L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
        +
        +=head1 HISTORY
        +
        +SMIME_write_PKCS7() was added to OpenSSL 0.9.5
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod b/vendor/openssl/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod
        new file mode 100644
        index 000000000..41902c0d4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod
        @@ -0,0 +1,74 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_NAME_ENTRY_get_object, X509_NAME_ENTRY_get_data,
        +X509_NAME_ENTRY_set_object, X509_NAME_ENTRY_set_data,
        +X509_NAME_ENTRY_create_by_txt, X509_NAME_ENTRY_create_by_NID,
        +X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
        + ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
        +
        + int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
        + int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len);
        +
        + X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len);
        + X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len);
        + X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len);
        +
        +=head1 DESCRIPTION
        +
        +X509_NAME_ENTRY_get_object() retrieves the field name of B<ne> in
        +and B<ASN1_OBJECT> structure.
        +
        +X509_NAME_ENTRY_get_data() retrieves the field value of B<ne> in
        +and B<ASN1_STRING> structure.
        +
        +X509_NAME_ENTRY_set_object() sets the field name of B<ne> to B<obj>.
        +
        +X509_NAME_ENTRY_set_data() sets the field value of B<ne> to string type
        +B<type> and value determined by B<bytes> and B<len>.
        +
        +X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_NID()
        +and X509_NAME_ENTRY_create_by_OBJ() create and return an 
        +B<X509_NAME_ENTRY> structure.
        +
        +=head1 NOTES
        +
        +X509_NAME_ENTRY_get_object() and X509_NAME_ENTRY_get_data() can be
        +used to examine an B<X509_NAME_ENTRY> function as returned by 
        +X509_NAME_get_entry() for example.
        +
        +X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_NID(),
        +and X509_NAME_ENTRY_create_by_OBJ() create and return an 
        +
        +X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_OBJ(),
        +X509_NAME_ENTRY_create_by_NID() and X509_NAME_ENTRY_set_data()
        +are seldom used in practice because B<X509_NAME_ENTRY> structures
        +are almost always part of B<X509_NAME> structures and the
        +corresponding B<X509_NAME> functions are typically used to
        +create and add new entries in a single operation.
        +
        +The arguments of these functions support similar options to the similarly
        +named ones of the corresponding B<X509_NAME> functions such as
        +X509_NAME_add_entry_by_txt(). So for example B<type> can be set to
        +B<MBSTRING_ASC> but in the case of X509_set_data() the field name must be
        +set first so the relevant field information can be looked up internally.
        +
        +=head1 RETURN VALUES
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>,
        +L<OBJ_nid2obj(3),OBJ_nid2obj(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod b/vendor/openssl/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod
        new file mode 100644
        index 000000000..1afd008cb
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod
        @@ -0,0 +1,116 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_NAME_add_entry_by_txt, X509_NAME_add_entry_by_OBJ, X509_NAME_add_entry_by_NID,
        +X509_NAME_add_entry, X509_NAME_delete_entry - X509_NAME modification functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set);
        +
        + int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set);
        +
        + int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set);
        +
        + int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set);
        +
        + X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
        +
        +=head1 DESCRIPTION
        +
        +X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ() and
        +X509_NAME_add_entry_by_NID() add a field whose name is defined
        +by a string B<field>, an object B<obj> or a NID B<nid> respectively.
        +The field value to be added is in B<bytes> of length B<len>. If
        +B<len> is -1 then the field length is calculated internally using
        +strlen(bytes).
        +
        +The type of field is determined by B<type> which can either be a
        +definition of the type of B<bytes> (such as B<MBSTRING_ASC>) or a
        +standard ASN1 type (such as B<V_ASN1_IA5STRING>). The new entry is
        +added to a position determined by B<loc> and B<set>.
        +
        +X509_NAME_add_entry() adds a copy of B<X509_NAME_ENTRY> structure B<ne>
        +to B<name>. The new entry is added to a position determined by B<loc>
        +and B<set>. Since a copy of B<ne> is added B<ne> must be freed up after
        +the call.
        +
        +X509_NAME_delete_entry() deletes an entry from B<name> at position
        +B<loc>. The deleted entry is returned and must be freed up.
        +
        +=head1 NOTES
        +
        +The use of string types such as B<MBSTRING_ASC> or B<MBSTRING_UTF8>
        +is strongly recommened for the B<type> parameter. This allows the
        +internal code to correctly determine the type of the field and to
        +apply length checks according to the relevant standards. This is
        +done using ASN1_STRING_set_by_NID().
        +
        +If instead an ASN1 type is used no checks are performed and the
        +supplied data in B<bytes> is used directly.
        +
        +In X509_NAME_add_entry_by_txt() the B<field> string represents
        +the field name using OBJ_txt2obj(field, 0).
        +
        +The B<loc> and B<set> parameters determine where a new entry should
        +be added. For almost all applications B<loc> can be set to -1 and B<set>
        +to 0. This adds a new entry to the end of B<name> as a single valued
        +RelativeDistinguishedName (RDN).
        +
        +B<loc> actually determines the index where the new entry is inserted:
        +if it is -1 it is appended. 
        +
        +B<set> determines how the new type is added. If it is zero a
        +new RDN is created.
        +
        +If B<set> is -1 or 1 it is added to the previous or next RDN
        +structure respectively. This will then be a multivalued RDN:
        +since multivalues RDNs are very seldom used B<set> is almost
        +always set to zero.
        +
        +=head1 EXAMPLES
        +
        +Create an B<X509_NAME> structure:
        +
        +"C=UK, O=Disorganized Organization, CN=Joe Bloggs"
        +
        + X509_NAME *nm;
        + nm = X509_NAME_new();
        + if (nm == NULL)
        +	/* Some error */
        + if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC,
        +			"C", "UK", -1, -1, 0))
        +	/* Error */
        + if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC,
        +			"O", "Disorganized Organization", -1, -1, 0))
        +	/* Error */
        + if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC,
        +			"CN", "Joe Bloggs", -1, -1, 0))
        +	/* Error */
        +
        +=head1 RETURN VALUES
        +
        +X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ(),
        +X509_NAME_add_entry_by_NID() and X509_NAME_add_entry() return 1 for
        +success of 0 if an error occurred.
        +
        +X509_NAME_delete_entry() returns either the deleted B<X509_NAME_ENTRY>
        +structure of B<NULL> if an error occurred.
        +
        +=head1 BUGS
        +
        +B<type> can still be set to B<V_ASN1_APP_CHOOSE> to use a
        +different algorithm to determine field types. Since this form does
        +not understand multicharacter types, performs no length checks and
        +can result in invalid field types its use is strongly discouraged.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>
        +
        +=head1 HISTORY
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod b/vendor/openssl/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod
        new file mode 100644
        index 000000000..3b1f9ff43
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod
        @@ -0,0 +1,108 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_NAME_get_index_by_NID, X509_NAME_get_index_by_OBJ, X509_NAME_get_entry,
        +X509_NAME_entry_count, X509_NAME_get_text_by_NID, X509_NAME_get_text_by_OBJ -
        +X509_NAME lookup and enumeration functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
        + int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos);
        +
        + int X509_NAME_entry_count(X509_NAME *name);
        + X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
        +
        + int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len);
        + int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len);
        +
        +=head1 DESCRIPTION
        +
        +These functions allow an B<X509_NAME> structure to be examined. The
        +B<X509_NAME> structure is the same as the B<Name> type defined in
        +RFC2459 (and elsewhere) and used for example in certificate subject
        +and issuer names.
        +
        +X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ() retrieve
        +the next index matching B<nid> or B<obj> after B<lastpos>. B<lastpos>
        +should initially be set to -1. If there are no more entries -1 is returned.
        +
        +X509_NAME_entry_count() returns the total number of entries in B<name>.
        +
        +X509_NAME_get_entry() retrieves the B<X509_NAME_ENTRY> from B<name>
        +corresponding to index B<loc>. Acceptable values for B<loc> run from
        +0 to (X509_NAME_entry_count(name) - 1). The value returned is an
        +internal pointer which must not be freed.
        +
        +X509_NAME_get_text_by_NID(), X509_NAME_get_text_by_OBJ() retrieve
        +the "text" from the first entry in B<name> which matches B<nid> or
        +B<obj>, if no such entry exists -1 is returned. At most B<len> bytes
        +will be written and the text written to B<buf> will be null
        +terminated. The length of the output string written is returned
        +excluding the terminating null. If B<buf> is <NULL> then the amount
        +of space needed in B<buf> (excluding the final null) is returned. 
        +
        +=head1 NOTES
        +
        +X509_NAME_get_text_by_NID() and X509_NAME_get_text_by_OBJ() are
        +legacy functions which have various limitations which make them
        +of minimal use in practice. They can only find the first matching
        +entry and will copy the contents of the field verbatim: this can
        +be highly confusing if the target is a muticharacter string type
        +like a BMPString or a UTF8String.
        +
        +For a more general solution X509_NAME_get_index_by_NID() or
        +X509_NAME_get_index_by_OBJ() should be used followed by
        +X509_NAME_get_entry() on any matching indices and then the
        +various B<X509_NAME_ENTRY> utility functions on the result.
        +
        +=head1 EXAMPLES
        +
        +Process all entries:
        +
        + int i;
        + X509_NAME_ENTRY *e;
        +
        + for (i = 0; i < X509_NAME_entry_count(nm); i++)
        +	{
        +	e = X509_NAME_get_entry(nm, i);
        +	/* Do something with e */
        +	}
        +
        +Process all commonName entries:
        +
        + int loc;
        + X509_NAME_ENTRY *e;
        +
        + loc = -1;
        + for (;;)
        +	{
        +	lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos);
        +	if (lastpos == -1)
        +		break;
        +	e = X509_NAME_get_entry(nm, lastpos);
        +	/* Do something with e */
        +	}
        +
        +=head1 RETURN VALUES
        +
        +X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ()
        +return the index of the next matching entry or -1 if not found.
        +
        +X509_NAME_entry_count() returns the total number of entries.
        +
        +X509_NAME_get_entry() returns an B<X509_NAME> pointer to the
        +requested entry or B<NULL> if the index is invalid.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_NAME_print_ex.pod b/vendor/openssl/openssl/doc/crypto/X509_NAME_print_ex.pod
        new file mode 100644
        index 000000000..2579a5dc9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_NAME_print_ex.pod
        @@ -0,0 +1,105 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_NAME_print_ex, X509_NAME_print_ex_fp, X509_NAME_print,
        +X509_NAME_oneline - X509_NAME printing routines.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
        + int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
        + char *	X509_NAME_oneline(X509_NAME *a,char *buf,int size);
        + int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
        +
        +=head1 DESCRIPTION
        +
        +X509_NAME_print_ex() prints a human readable version of B<nm> to BIO B<out>. Each
        +line (for multiline formats) is indented by B<indent> spaces. The output format
        +can be extensively customised by use of the B<flags> parameter.
        +
        +X509_NAME_print_ex_fp() is identical to X509_NAME_print_ex() except the output is
        +written to FILE pointer B<fp>.
        +
        +X509_NAME_oneline() prints an ASCII version of B<a> to B<buf>. At most B<size>
        +bytes will be written. If B<buf> is B<NULL> then a buffer is dynamically allocated
        +and returned, otherwise B<buf> is returned.
        +
        +X509_NAME_print() prints out B<name> to B<bp> indenting each line by B<obase> 
        +characters. Multiple lines are used if the output (including indent) exceeds
        +80 characters.
        +
        +=head1 NOTES
        +
        +The functions X509_NAME_oneline() and X509_NAME_print() are legacy functions which
        +produce a non standard output form, they don't handle multi character fields and
        +have various quirks and inconsistencies. Their use is strongly discouraged in new
        +applications.
        +
        +Although there are a large number of possible flags for most purposes
        +B<XN_FLAG_ONELINE>, B<XN_FLAG_MULTILINE> or B<XN_FLAG_RFC2253> will suffice.
        +As noted on the L<ASN1_STRING_print_ex(3)|ASN1_STRING_print_ex(3)> manual page
        +for UTF8 terminals the B<ASN1_STRFLGS_ESC_MSB> should be unset: so for example
        +B<XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB> would be used.
        +
        +The complete set of the flags supported by X509_NAME_print_ex() is listed below.
        +
        +Several options can be ored together.
        +
        +The options B<XN_FLAG_SEP_COMMA_PLUS>, B<XN_FLAG_SEP_CPLUS_SPC>,
        +B<XN_FLAG_SEP_SPLUS_SPC> and B<XN_FLAG_SEP_MULTILINE> determine the field separators
        +to use. Two distinct separators are used between distinct RelativeDistinguishedName
        +components and separate values in the same RDN for a multi-valued RDN. Multi-valued
        +RDNs are currently very rare so the second separator will hardly ever be used.
        +
        +B<XN_FLAG_SEP_COMMA_PLUS> uses comma and plus as separators. B<XN_FLAG_SEP_CPLUS_SPC>
        +uses comma and plus with spaces: this is more readable that plain comma and plus.
        +B<XN_FLAG_SEP_SPLUS_SPC> uses spaced semicolon and plus. B<XN_FLAG_SEP_MULTILINE> uses
        +spaced newline and plus respectively.
        +
        +If B<XN_FLAG_DN_REV> is set the whole DN is printed in reversed order.
        +
        +The fields B<XN_FLAG_FN_SN>, B<XN_FLAG_FN_LN>, B<XN_FLAG_FN_OID>,
        +B<XN_FLAG_FN_NONE> determine how a field name is displayed. It will
        +use the short name (e.g. CN) the long name (e.g. commonName) always
        +use OID numerical form (normally OIDs are only used if the field name is not
        +recognised) and no field name respectively.
        +
        +If B<XN_FLAG_SPC_EQ> is set then spaces will be placed around the '=' character
        +separating field names and values.
        +
        +If B<XN_FLAG_DUMP_UNKNOWN_FIELDS> is set then the encoding of unknown fields is
        +printed instead of the values.
        +
        +If B<XN_FLAG_FN_ALIGN> is set then field names are padded to 20 characters: this
        +is only of use for multiline format.
        +
        +Additionally all the options supported by ASN1_STRING_print_ex() can be used to 
        +control how each field value is displayed.
        +
        +In addition a number options can be set for commonly used formats.
        +
        +B<XN_FLAG_RFC2253> sets options which produce an output compatible with RFC2253 it
        +is equivalent to:
        + B<ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS>
        +
        +
        +B<XN_FLAG_ONELINE> is a more readable one line format which is the same as:
        + B<ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_SPC_EQ | XN_FLAG_FN_SN>
        +
        +B<XN_FLAG_MULTILINE> is a multiline format which is the same as:
        + B<ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN>
        +
        +B<XN_FLAG_COMPAT> uses a format identical to X509_NAME_print(): in fact it calls X509_NAME_print() internally.
        +
        +=head1 SEE ALSO
        +
        +L<ASN1_STRING_print_ex(3)|ASN1_STRING_print_ex(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_get_error.pod b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_get_error.pod
        new file mode 100644
        index 000000000..a883f6c09
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_get_error.pod
        @@ -0,0 +1,303 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        + #include <openssl/x509_vfy.h>
        +
        + int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
        + void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
        + int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
        + X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
        +
        + STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
        +
        + const char *X509_verify_cert_error_string(long n);
        +
        +=head1 DESCRIPTION
        +
        +These functions are typically called after X509_verify_cert() has indicated
        +an error or in a verification callback to determine the nature of an error.
        +
        +X509_STORE_CTX_get_error() returns the error code of B<ctx>, see
        +the B<ERROR CODES> section for a full description of all error codes.
        +
        +X509_STORE_CTX_set_error() sets the error code of B<ctx> to B<s>. For example
        +it might be used in a verification callback to set an error based on additional
        +checks.
        +
        +X509_STORE_CTX_get_error_depth() returns the B<depth> of the error. This is a
        +non-negative integer representing where in the certificate chain the error
        +occurred. If it is zero it occured in the end entity certificate, one if
        +it is the certificate which signed the end entity certificate and so on.
        +
        +X509_STORE_CTX_get_current_cert() returns the certificate in B<ctx> which
        +caused the error or B<NULL> if no certificate is relevant.
        +
        +X509_STORE_CTX_get1_chain() returns a complete validate chain if a previous
        +call to X509_verify_cert() is successful. If the call to X509_verify_cert()
        +is B<not> successful the returned chain may be incomplete or invalid. The
        +returned chain persists after the B<ctx> structure is freed, when it is
        +no longer needed it should be free up using:
        +
        +  sk_X509_pop_free(chain, X509_free);
        +
        +X509_verify_cert_error_string() returns a human readable error string for
        +verification error B<n>.
        +
        +=head1 RETURN VALUES
        +
        +X509_STORE_CTX_get_error() returns B<X509_V_OK> or an error code.
        +
        +X509_STORE_CTX_get_error_depth() returns a non-negative error depth.
        +
        +X509_STORE_CTX_get_current_cert() returns the cerificate which caused the
        +error or B<NULL> if no certificate is relevant to the error.
        +
        +X509_verify_cert_error_string() returns a human readable error string for
        +verification error B<n>.
        +
        +=head1 ERROR CODES
        +
        +A list of error codes and messages is shown below.  Some of the
        +error codes are defined but currently never returned: these are described as
        +"unused".
        +
        +=over 4
        +
        +=item B<X509_V_OK: ok>
        +
        +the operation was successful.
        +
        +=item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
        +
        +the issuer certificate could not be found: this occurs if the issuer certificate
        +of an untrusted certificate cannot be found.
        +
        +=item B<X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
        +
        +the CRL of a certificate could not be found.
        +
        +=item B<X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
        +
        +the certificate signature could not be decrypted. This means that the actual
        +signature value could not be determined rather than it not matching the
        +expected value, this is only meaningful for RSA keys.
        +
        +=item B<X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature>
        +
        +the CRL signature could not be decrypted: this means that the actual signature
        +value could not be determined rather than it not matching the expected value.
        +Unused.
        +
        +=item B<X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key>
        +
        +the public key in the certificate SubjectPublicKeyInfo could not be read.
        +
        +=item B<X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure>
        +
        +the signature of the certificate is invalid.
        +
        +=item B<X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
        +
        +the signature of the certificate is invalid.
        +
        +=item B<X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
        +
        +the certificate is not yet valid: the notBefore date is after the current time.
        +
        +=item B<X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired>
        +
        +the certificate has expired: that is the notAfter date is before the current time.
        +
        +=item B<X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
        +
        +the CRL is not yet valid.
        +
        +=item B<X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
        +
        +the CRL has expired.
        +
        +=item B<X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
        +
        +the certificate notBefore field contains an invalid time.
        +
        +=item B<X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field>
        +
        +the certificate notAfter field contains an invalid time.
        +
        +=item B<X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
        +
        +the CRL lastUpdate field contains an invalid time.
        +
        +=item B<X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
        +
        +the CRL nextUpdate field contains an invalid time.
        +
        +=item B<X509_V_ERR_OUT_OF_MEM: out of memory>
        +
        +an error occurred trying to allocate memory. This should never happen.
        +
        +=item B<X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate>
        +
        +the passed certificate is self signed and the same certificate cannot be found
        +in the list of trusted certificates.
        +
        +=item B<X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain>
        +
        +the certificate chain could be built up using the untrusted certificates but
        +the root could not be found locally.
        +
        +=item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
        +
        +the issuer certificate of a locally looked up certificate could not be found.
        +This normally means the list of trusted certificates is not complete.
        +
        +=item B<X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
        +
        +no signatures could be verified because the chain contains only one certificate
        +and it is not self signed.
        +
        +=item B<X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long>
        +
        +the certificate chain length is greater than the supplied maximum depth. Unused.
        +
        +=item B<X509_V_ERR_CERT_REVOKED: certificate revoked>
        +
        +the certificate has been revoked.
        +
        +=item B<X509_V_ERR_INVALID_CA: invalid CA certificate>
        +
        +a CA certificate is invalid. Either it is not a CA or its extensions are not
        +consistent with the supplied purpose.
        +
        +=item B<X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded>
        +
        +the basicConstraints pathlength parameter has been exceeded.
        +
        +=item B<X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose>
        +
        +the supplied certificate cannot be used for the specified purpose.
        +
        +=item B<X509_V_ERR_CERT_UNTRUSTED: certificate not trusted>
        +
        +the root CA is not marked as trusted for the specified purpose.
        +
        +=item B<X509_V_ERR_CERT_REJECTED: certificate rejected>
        +
        +the root CA is marked to reject the specified purpose.
        +
        +=item B<X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch>
        +
        +the current candidate issuer certificate was rejected because its subject name
        +did not match the issuer name of the current certificate. This is only set
        +if issuer check debugging is enabled it is used for status notification and
        +is B<not> in itself an error.
        +
        +=item B<X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch>
        +
        +the current candidate issuer certificate was rejected because its subject key
        +identifier was present and did not match the authority key identifier current
        +certificate. This is only set if issuer check debugging is enabled it is used
        +for status notification and is B<not> in itself an error.
        +
        +=item B<X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch>
        +
        +the current candidate issuer certificate was rejected because its issuer name
        +and serial number was present and did not match the authority key identifier of
        +the current certificate. This is only set if issuer check debugging is enabled
        +it is used for status notification and is B<not> in itself an error.
        +
        +=item B<X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing>
        +
        +the current candidate issuer certificate was rejected because its keyUsage
        +extension does not permit certificate signing. This is only set if issuer check
        +debugging is enabled it is used for status notification and is B<not> in itself
        +an error.
        +
        +=item B<X509_V_ERR_INVALID_EXTENSION: invalid or inconsistent certificate extension>
        +
        +A certificate extension had an invalid value (for example an incorrect
        +encoding) or some value inconsistent with other extensions.
        +
        +
        +=item B<X509_V_ERR_INVALID_POLICY_EXTENSION: invalid or inconsistent certificate policy extension>
        +
        +A certificate policies extension had an invalid value (for example an incorrect
        +encoding) or some value inconsistent with other extensions. This error only
        +occurs if policy processing is enabled.
        +
        +=item B<X509_V_ERR_NO_EXPLICIT_POLICY: no explicit policy>
        +
        +The verification flags were set to require and explicit policy but none was
        +present.
        +
        +=item B<X509_V_ERR_DIFFERENT_CRL_SCOPE: Different CRL scope>
        +
        +The only CRLs that could be found did not match the scope of the certificate.
        +
        +=item B<X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: Unsupported extension feature>
        +
        +Some feature of a certificate extension is not supported. Unused.
        +
        +=item B<X509_V_ERR_PERMITTED_VIOLATION: permitted subtree violation>
        +
        +A name constraint violation occured in the permitted subtrees.
        +
        +=item B<X509_V_ERR_EXCLUDED_VIOLATION: excluded subtree violation>
        +
        +A name constraint violation occured in the excluded subtrees.
        +
        +=item B<X509_V_ERR_SUBTREE_MINMAX: name constraints minimum and maximum not supported>
        +
        +A certificate name constraints extension included a minimum or maximum field:
        +this is not supported.
        +
        +=item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: unsupported name constraint type>
        +
        +An unsupported name constraint type was encountered. OpenSSL currently only
        +supports directory name, DNS name, email and URI types.
        +
        +=item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: unsupported or invalid name constraint syntax>
        +
        +The format of the name constraint is not recognised: for example an email
        +address format of a form not mentioned in RFC3280. This could be caused by
        +a garbage extension or some new feature not currently supported.
        +
        +=item B<X509_V_ERR_CRL_PATH_VALIDATION_ERROR: CRL path validation error>
        +
        +An error occured when attempting to verify the CRL path. This error can only
        +happen if extended CRL checking is enabled.
        +
        +=item B<X509_V_ERR_APPLICATION_VERIFICATION: application verification failure>
        +
        +an application specific error. This will never be returned unless explicitly
        +set by an application.
        +
        +=head1 NOTES
        +
        +The above functions should be used instead of directly referencing the fields
        +in the B<X509_VERIFY_CTX> structure.
        +
        +In versions of OpenSSL before 1.0 the current certificate returned by
        +X509_STORE_CTX_get_current_cert() was never B<NULL>. Applications should
        +check the return value before printing out any debugging information relating
        +to the current certificate.
        +
        +If an unrecognised error code is passed to X509_verify_cert_error_string() the
        +numerical value of the unknown code is returned in a static buffer. This is not
        +thread safe but will never happen unless an invalid code is passed.
        +
        +=head1 SEE ALSO
        +
        +L<X509_verify_cert(3)|X509_verify_cert(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod
        new file mode 100644
        index 000000000..8d6b9dda4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_get_ex_new_index.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_STORE_CTX_get_ex_new_index, X509_STORE_CTX_set_ex_data, X509_STORE_CTX_get_ex_data - add application specific data to X509_STORE_CTX structures
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509_vfy.h>
        +
        + int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
        +		CRYPTO_EX_new *new_func,
        +		CRYPTO_EX_dup *dup_func,
        +		CRYPTO_EX_free *free_func);
        +
        + int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *d, int idx, void *arg);
        +
        + char *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *d, int idx);
        +
        +=head1 DESCRIPTION
        +
        +These functions handle application specific data in X509_STORE_CTX structures.
        +Their usage is identical to that of RSA_get_ex_new_index(), RSA_set_ex_data()
        +and RSA_get_ex_data() as described in L<RSA_get_ex_new_index(3)>.
        +
        +=head1 NOTES
        +
        +This mechanism is used internally by the B<ssl> library to store the B<SSL>
        +structure associated with a verification operation in an B<X509_STORE_CTX>
        +structure. 
        +
        +=head1 SEE ALSO
        +
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>
        +
        +=head1 HISTORY
        +
        +X509_STORE_CTX_get_ex_new_index(), X509_STORE_CTX_set_ex_data() and
        +X509_STORE_CTX_get_ex_data() are available since OpenSSL 0.9.5.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod
        new file mode 100644
        index 000000000..b17888f14
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod
        @@ -0,0 +1,122 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_init, X509_STORE_CTX_trusted_stack, X509_STORE_CTX_set_cert, X509_STORE_CTX_set_chain, X509_STORE_CTX_set0_crls, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default - X509_STORE_CTX initialisation
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509_vfy.h>
        +
        + X509_STORE_CTX *X509_STORE_CTX_new(void);
        + void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
        + void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
        +
        + int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
        +			 X509 *x509, STACK_OF(X509) *chain);
        +
        + void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
        +
        + void	X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x);
        + void	X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx,STACK_OF(X509) *sk);
        + void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk);
        +
        + X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
        + void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
        + int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
        +
        +=head1 DESCRIPTION
        +
        +These functions initialise an B<X509_STORE_CTX> structure for subsequent use
        +by X509_verify_cert().
        +
        +X509_STORE_CTX_new() returns a newly initialised B<X509_STORE_CTX> structure.
        +
        +X509_STORE_CTX_cleanup() internally cleans up an B<X509_STORE_CTX> structure.
        +The context can then be reused with an new call to X509_STORE_CTX_init().
        +
        +X509_STORE_CTX_free() completely frees up B<ctx>. After this call B<ctx>
        +is no longer valid.
        +
        +X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation.
        +The trusted certificate store is set to B<store>, the end entity certificate
        +to be verified is set to B<x509> and a set of additional certificates (which
        +will be untrusted but may be used to build the chain) in B<chain>. Any or
        +all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>.
        +
        +X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx>
        +to B<sk>. This is an alternative way of specifying trusted certificates 
        +instead of using an B<X509_STORE>.
        +
        +X509_STORE_CTX_set_cert() sets the certificate to be vertified in B<ctx> to
        +B<x>.
        +
        +X509_STORE_CTX_set_chain() sets the additional certificate chain used by B<ctx>
        +to B<sk>.
        +
        +X509_STORE_CTX_set0_crls() sets a set of CRLs to use to aid certificate
        +verification to B<sk>. These CRLs will only be used if CRL verification is
        +enabled in the associated B<X509_VERIFY_PARAM> structure. This might be
        +used where additional "useful" CRLs are supplied as part of a protocol,
        +for example in a PKCS#7 structure.
        +
        +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param() retrieves an intenal pointer
        +to the verification parameters associated with B<ctx>.
        +
        +X509_STORE_CTX_set0_param() sets the intenal verification parameter pointer
        +to B<param>. After this call B<param> should not be used.
        +
        +X509_STORE_CTX_set_default() looks up and sets the default verification
        +method to B<name>. This uses the function X509_VERIFY_PARAM_lookup() to
        +find an appropriate set of parameters from B<name>.
        +
        +=head1 NOTES
        +
        +The certificates and CRLs in a store are used internally and should B<not>
        +be freed up until after the associated B<X509_STORE_CTX> is freed. Legacy
        +applications might implicitly use an B<X509_STORE_CTX> like this:
        +
        +  X509_STORE_CTX ctx;
        +  X509_STORE_CTX_init(&ctx, store, cert, chain);
        +
        +this is B<not> recommended in new applications they should instead do:
        +
        +  X509_STORE_CTX *ctx;
        +  ctx = X509_STORE_CTX_new();
        +  if (ctx == NULL)
        +	/* Bad error */
        +  X509_STORE_CTX_init(ctx, store, cert, chain);
        +
        +=head1 BUGS
        +
        +The certificates and CRLs in a context are used internally and should B<not>
        +be freed up until after the associated B<X509_STORE_CTX> is freed. Copies
        +should be made or reference counts increased instead.
        +
        +=head1 RETURN VALUES
        +
        +X509_STORE_CTX_new() returns an newly allocates context or B<NULL> is an
        +error occurred.
        +
        +X509_STORE_CTX_init() returns 1 for success or 0 if an error occurred.
        +
        +X509_STORE_CTX_get0_param() returns a pointer to an B<X509_VERIFY_PARAM>
        +structure or B<NULL> if an error occurred.
        +
        +X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), X509_STORE_CTX_trusted_stack(),
        +X509_STORE_CTX_set_cert(), X509_STORE_CTX_set_chain(),
        +X509_STORE_CTX_set0_crls() and X509_STORE_CTX_set0_param() do not return
        +values.
        +
        +X509_STORE_CTX_set_default() returns 1 for success or 0 if an error occurred.
        +
        +=head1 SEE ALSO
        +
        +L<X509_verify_cert(3)|X509_verify_cert(3)>
        +L<X509_VERIFY_PARAM_set_flags(3)|X509_VERIFY_PARAM_set_flags(3)>
        +
        +=head1 HISTORY
        +
        +X509_STORE_CTX_set0_crls() was first added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod
        new file mode 100644
        index 000000000..b9787a6ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod
        @@ -0,0 +1,161 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_STORE_CTX_set_verify_cb - set verification callback
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509_vfy.h>
        +
        + void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
        +				int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
        +
        +=head1 DESCRIPTION
        +
        +X509_STORE_CTX_set_verify_cb() sets the verification callback of B<ctx> to
        +B<verify_cb> overwriting any existing callback.
        +
        +The verification callback can be used to customise the operation of certificate
        +verification, either by overriding error conditions or logging errors for
        +debugging purposes.
        +
        +However a verification callback is B<not> essential and the default operation
        +is often sufficient.
        +
        +The B<ok> parameter to the callback indicates the value the callback should
        +return to retain the default behaviour. If it is zero then and error condition
        +is indicated. If it is 1 then no error occurred. If the flag
        +B<X509_V_FLAG_NOTIFY_POLICY> is set then B<ok> is set to 2 to indicate the
        +policy checking is complete.
        +
        +The B<ctx> parameter to the callback is the B<X509_STORE_CTX> structure that
        +is performing the verification operation. A callback can examine this
        +structure and receive additional information about the error, for example
        +by calling X509_STORE_CTX_get_current_cert(). Additional application data can
        +be passed to the callback via the B<ex_data> mechanism.
        +
        +=head1 WARNING
        +
        +In general a verification callback should B<NOT> unconditionally return 1 in
        +all circumstances because this will allow verification to succeed no matter
        +what the error. This effectively removes all security from the application
        +because B<any> certificate (including untrusted generated ones) will be
        +accepted.
        +
        +=head1 NOTES
        +
        +The verification callback can be set and inherited from the parent structure
        +performing the operation. In some cases (such as S/MIME verification) the
        +B<X509_STORE_CTX> structure is created and destroyed internally and the
        +only way to set a custom verification callback is by inheriting it from the
        +associated B<X509_STORE>.
        +
        +=head1 RETURN VALUES
        +
        +X509_STORE_CTX_set_verify_cb() does not return a value.
        +
        +=head1 EXAMPLES
        +
        +Default callback operation:
        +
        + int verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	return ok;
        +	}
        +
        +Simple example, suppose a certificate in the chain is expired and we wish
        +to continue after this error:
        +
        + int verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	/* Tolerate certificate expiration */
        +	if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
        +			return 1;
        +	/* Otherwise don't override */
        +	return ok;
        +	}
        +
        +More complex example, we don't wish to continue after B<any> certificate has
        +expired just one specific case:
        +
        + int verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	int err = X509_STORE_CTX_get_error(ctx);
        +	X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx);
        +	if (err == X509_V_ERR_CERT_HAS_EXPIRED)
        +		{
        +		if (check_is_acceptable_expired_cert(err_cert)
        +			return 1;
        +		}
        +	return ok;
        +	}
        +
        +Full featured logging callback. In this case the B<bio_err> is assumed to be
        +a global logging B<BIO>, an alternative would to store a BIO in B<ctx> using
        +B<ex_data>.
        +	
        + int verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	X509 *err_cert;
        +	int err,depth;
        +
        +	err_cert = X509_STORE_CTX_get_current_cert(ctx);
        +	err =	X509_STORE_CTX_get_error(ctx);
        +	depth =	X509_STORE_CTX_get_error_depth(ctx);
        +
        +	BIO_printf(bio_err,"depth=%d ",depth);
        +	if (err_cert)
        +		{
        +		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
        +					0, XN_FLAG_ONELINE);
        +		BIO_puts(bio_err, "\n");
        +		}
        +	else
        +		BIO_puts(bio_err, "<no cert>\n");
        +	if (!ok)
        +		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
        +			X509_verify_cert_error_string(err));
        +	switch (err)
        +		{
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +		BIO_puts(bio_err,"issuer= ");
        +		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
        +					0, XN_FLAG_ONELINE);
        +		BIO_puts(bio_err, "\n");
        +		break;
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +		BIO_printf(bio_err,"notBefore=");
        +		ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +		BIO_printf(bio_err,"notAfter=");
        +		ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
        +		BIO_printf(bio_err,"\n");
        +		break;
        +	case X509_V_ERR_NO_EXPLICIT_POLICY:
        +		policies_print(bio_err, ctx);
        +		break;
        +		}
        +	if (err == X509_V_OK && ok == 2)
        +		/* print out policies */
        +
        +	BIO_printf(bio_err,"verify return:%d\n",ok);
        +	return(ok);
        +	}
        +
        +=head1 SEE ALSO
        +
        +L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
        +L<X509_STORE_set_verify_cb_func(3)|X509_STORE_set_verify_cb_func(3)>
        +L<X509_STORE_CTX_get_ex_new_index(3)|X509_STORE_CTX_get_ex_new_index(3)>
        +
        +=head1 HISTORY
        +
        +X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and
        +OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod b/vendor/openssl/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod
        new file mode 100644
        index 000000000..29e3bbe3b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod
        @@ -0,0 +1,54 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_STORE_set_verify_cb_func, X509_STORE_set_verify_cb - set verification callback
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509_vfy.h>
        +
        + void X509_STORE_set_verify_cb(X509_STORE *st,
        +				int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
        +
        + void X509_STORE_set_verify_cb_func(X509_STORE *st,
        +				int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
        +
        +=head1 DESCRIPTION
        +
        +X509_STORE_set_verify_cb() sets the verification callback of B<ctx> to
        +B<verify_cb> overwriting any existing callback.
        +
        +X509_STORE_set_verify_cb_func() also sets the verification callback but it
        +is implemented as a macro.
        +
        +=head1 NOTES
        +
        +The verification callback from an B<X509_STORE> is inherited by 
        +the corresponding B<X509_STORE_CTX> structure when it is initialized. This can
        +be used to set the verification callback when the B<X509_STORE_CTX> is 
        +otherwise inaccessible (for example during S/MIME verification).
        +
        +=head1 BUGS
        +
        +The macro version of this function was the only one available before 
        +OpenSSL 1.0.0.
        +
        +=head1 RETURN VALUES
        +
        +X509_STORE_set_verify_cb() and X509_STORE_set_verify_cb_func() do not return
        +a value.
        +
        +=head1 SEE ALSO
        +
        +L<X509_STORE_CTX_set_verify_cb(3)|X509_STORE_CTX_set_verify_cb(3)>
        +L<CMS_verify(3)|CMS_verify(3)>
        +
        +=head1 HISTORY
        +
        +X509_STORE_set_verify_cb_func() is available in all versions of SSLeay and
        +OpenSSL.
        +
        +X509_STORE_set_verify_cb() was added to OpenSSL 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/vendor/openssl/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
        new file mode 100644
        index 000000000..b68eece03
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
        @@ -0,0 +1,171 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies - X509 verification parameters 
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509_vfy.h>
        +
        + int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
        + int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
        +							unsigned long flags);
        + unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
        +
        + int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
        + int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
        +
        + void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
        +
        + int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
        +						ASN1_OBJECT *policy);
        + int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
        +					STACK_OF(ASN1_OBJECT) *policies);
        +
        + void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
        + int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
        +
        +=head1 DESCRIPTION
        +
        +These functions manipulate the B<X509_VERIFY_PARAM> structure associated with
        +a certificate verification operation. 
        +
        +The X509_VERIFY_PARAM_set_flags() function sets the flags in B<param> by oring
        +it with B<flags>. See the B<VERIFICATION FLAGS> section for a complete
        +description of values the B<flags> parameter can take.
        +
        +X509_VERIFY_PARAM_get_flags() returns the flags in B<param>.
        +
        +X509_VERIFY_PARAM_clear_flags() clears the flags B<flags> in B<param>.
        +
        +X509_VERIFY_PARAM_set_purpose() sets the verification purpose in B<param>
        +to B<purpose>. This determines the acceptable purpose of the certificate
        +chain, for example SSL client or SSL server.
        +
        +X509_VERIFY_PARAM_set_trust() sets the trust setting in B<param> to 
        +B<trust>.
        +
        +X509_VERIFY_PARAM_set_time() sets the verification time in B<param> to
        +B<t>. Normally the current time is used.
        +
        +X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled
        +by default) and adds B<policy> to the acceptable policy set.
        +
        +X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled
        +by default) and sets the acceptable policy set to B<policies>. Any existing
        +policy set is cleared. The B<policies> parameter can be B<NULL> to clear
        +an existing policy set.
        +
        +X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to B<depth>.
        +That is the maximum number of untrusted CA certificates that can appear in a
        +chain.
        +
        +=head1 RETURN VALUES
        +
        +X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(), 
        +X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(),
        +X509_VERIFY_PARAM_add0_policy() and X509_VERIFY_PARAM_set1_policies() return 1
        +for success and 0 for failure. 
        +
        +X509_VERIFY_PARAM_get_flags() returns the current verification flags.
        +
        +X509_VERIFY_PARAM_set_time() and X509_VERIFY_PARAM_set_depth() do not return
        +values.
        +
        +X509_VERIFY_PARAM_get_depth() returns the current verification depth.
        +
        +=head1 VERIFICATION FLAGS
        +
        +The verification flags consists of zero or more of the following flags
        +ored together.
        +
        +B<X509_V_FLAG_CRL_CHECK> enables CRL checking for the certificate chain leaf
        +certificate. An error occurs if a suitable CRL cannot be found. 
        +
        +B<X509_V_FLAG_CRL_CHECK_ALL> enables CRL checking for the entire certificate
        +chain.
        +
        +B<X509_V_FLAG_IGNORE_CRITICAL> disabled critical extension checking. By default
        +any unhandled critical extensions in certificates or (if checked) CRLs results
        +in a fatal error. If this flag is set unhandled critical extensions are
        +ignored. B<WARNING> setting this option for anything other than debugging
        +purposes can be a security risk. Finer control over which extensions are
        +supported can be performed in the verification callback.
        +
        +THe B<X509_V_FLAG_X509_STRICT> flag disables workarounds for some broken
        +certificates and makes the verification strictly apply B<X509> rules.
        +
        +B<X509_V_FLAG_ALLOW_PROXY_CERTS> enables proxy certificate verification.
        +
        +B<X509_V_FLAG_POLICY_CHECK> enables certificate policy checking, by default
        +no policy checking is peformed. Additional information is sent to the 
        +verification callback relating to policy checking.
        +
        +B<X509_V_FLAG_EXPLICIT_POLICY>, B<X509_V_FLAG_INHIBIT_ANY> and
        +B<X509_V_FLAG_INHIBIT_MAP> set the B<require explicit policy>, B<inhibit any
        +policy> and B<inhibit policy mapping> flags respectively as defined in
        +B<RFC3280>. Policy checking is automatically enabled if any of these flags
        +are set.
        +
        +If B<X509_V_FLAG_NOTIFY_POLICY> is set and the policy checking is successful
        +a special status code is set to the verification callback. This permits it
        +to examine the valid policy tree and perform additional checks or simply
        +log it for debugging purposes.
        +
        +By default some addtional features such as indirect CRLs and CRLs signed by
        +different keys are disabled. If B<X509_V_FLAG_EXTENDED_CRL_SUPPORT> is set
        +they are enabled.
        +
        +If B<X509_V_FLAG_USE_DELTAS> ise set delta CRLs (if present) are used to
        +determine certificate status. If not set deltas are ignored.
        +
        +B<X509_V_FLAG_CHECK_SS_SIGNATURE> enables checking of the root CA self signed
        +cerificate signature. By default this check is disabled because it doesn't
        +add any additional security but in some cases applications might want to
        +check the signature anyway. A side effect of not checking the root CA
        +signature is that disabled or unsupported message digests on the root CA
        +are not treated as fatal errors.
        +
        +The B<X509_V_FLAG_CB_ISSUER_CHECK> flag enables debugging of certificate
        +issuer checks. It is B<not> needed unless you are logging certificate
        +verification. If this flag is set then additional status codes will be sent
        +to the verification callback and it B<must> be prepared to handle such cases
        +without assuming they are hard errors.
        +
        +=head1 NOTES
        +
        +The above functions should be used to manipulate verification parameters
        +instead of legacy functions which work in specific structures such as
        +X509_STORE_CTX_set_flags().
        +
        +=head1 BUGS
        +
        +Delta CRL checking is currently primitive. Only a single delta can be used and
        +(partly due to limitations of B<X509_STORE>) constructed CRLs are not 
        +maintained.
        +
        +If CRLs checking is enable CRLs are expected to be available in the
        +corresponding B<X509_STORE> structure. No attempt is made to download
        +CRLs from the CRL distribution points extension.
        +
        +=head1 EXAMPLE
        +
        +Enable CRL checking when performing certificate verification during SSL 
        +connections associated with an B<SSL_CTX> structure B<ctx>:
        +
        +  X509_VERIFY_PARAM *param;
        +  param = X509_VERIFY_PARAM_new();
        +  X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
        +  SSL_CTX_set1_param(ctx, param);
        +  X509_VERIFY_PARAM_free(param);
        +
        +=head1 SEE ALSO
        +
        +L<X509_verify_cert(3)|X509_verify_cert(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_new.pod b/vendor/openssl/openssl/doc/crypto/X509_new.pod
        new file mode 100644
        index 000000000..d38872335
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_new.pod
        @@ -0,0 +1,39 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_new, X509_free - X509 certificate ASN1 allocation functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509 *X509_new(void);
        + void X509_free(X509 *a);
        +
        +=head1 DESCRIPTION
        +
        +The X509 ASN1 allocation routines, allocate and free an
        +X509 structure, which represents an X509 certificate.
        +
        +X509_new() allocates and initializes a X509 structure.
        +
        +X509_free() frees up the B<X509> structure B<a>.
        +
        +=head1 RETURN VALUES
        +
        +If the allocation fails, X509_new() returns B<NULL> and sets an error
        +code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +Otherwise it returns a pointer to the newly allocated structure.
        +
        +X509_free() returns no value.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +X509_new() and X509_free() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/X509_verify_cert.pod b/vendor/openssl/openssl/doc/crypto/X509_verify_cert.pod
        new file mode 100644
        index 000000000..5253bdcd7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/X509_verify_cert.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +X509_verify_cert - discover and verify X509 certificte chain
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + int X509_verify_cert(X509_STORE_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +The X509_verify_cert() function attempts to discover and validate a
        +certificate chain based on parameters in B<ctx>. A complete description of
        +the process is contained in the L<verify(1)|verify(1)> manual page.
        +
        +=head1 RETURN VALUES
        +
        +If a complete chain can be built and validated this function returns 1,
        +otherwise it return zero, in exceptional circumstances it can also
        +return a negative code.
        +
        +If the function fails additional error information can be obtained by
        +examining B<ctx> using, for example X509_STORE_CTX_get_error().
        +
        +=head1 NOTES
        +
        +Applications rarely call this function directly but it is used by
        +OpenSSL internally for certificate validation, in both the S/MIME and
        +SSL/TLS code.
        +
        +The negative return value from X509_verify_cert() can only occur if no
        +certificate is set in B<ctx> (due to a programming error) or if a retry
        +operation is requested during internal lookups (which never happens with
        +standard lookup methods). It is however recommended that application check
        +for <= 0 return value on error.
        +
        +=head1 BUGS
        +
        +This function uses the header B<x509.h> as opposed to most chain verification
        +functiosn which use B<x509_vfy.h>.
        +
        +=head1 SEE ALSO
        +
        +L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
        +
        +=head1 HISTORY
        +
        +X509_verify_cert() is available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/bio.pod b/vendor/openssl/openssl/doc/crypto/bio.pod
        new file mode 100644
        index 000000000..f9239226f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/bio.pod
        @@ -0,0 +1,54 @@
        +=pod
        +
        +=head1 NAME
        +
        +bio - I/O abstraction
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bio.h>
        +
        +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<BIO_ctrl(3)|BIO_ctrl(3)>,
        +L<BIO_f_base64(3)|BIO_f_base64(3)>, L<BIO_f_buffer(3)|BIO_f_buffer(3)>,
        +L<BIO_f_cipher(3)|BIO_f_cipher(3)>, L<BIO_f_md(3)|BIO_f_md(3)>,
        +L<BIO_f_null(3)|BIO_f_null(3)>, L<BIO_f_ssl(3)|BIO_f_ssl(3)>,
        +L<BIO_find_type(3)|BIO_find_type(3)>, L<BIO_new(3)|BIO_new(3)>,
        +L<BIO_new_bio_pair(3)|BIO_new_bio_pair(3)>,
        +L<BIO_push(3)|BIO_push(3)>, L<BIO_read(3)|BIO_read(3)>,
        +L<BIO_s_accept(3)|BIO_s_accept(3)>, L<BIO_s_bio(3)|BIO_s_bio(3)>,
        +L<BIO_s_connect(3)|BIO_s_connect(3)>, L<BIO_s_fd(3)|BIO_s_fd(3)>,
        +L<BIO_s_file(3)|BIO_s_file(3)>, L<BIO_s_mem(3)|BIO_s_mem(3)>,
        +L<BIO_s_null(3)|BIO_s_null(3)>, L<BIO_s_socket(3)|BIO_s_socket(3)>,
        +L<BIO_set_callback(3)|BIO_set_callback(3)>,
        +L<BIO_should_retry(3)|BIO_should_retry(3)>
        diff --git a/vendor/openssl/openssl/doc/crypto/blowfish.pod b/vendor/openssl/openssl/doc/crypto/blowfish.pod
        new file mode 100644
        index 000000000..5b2d274c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/blowfish.pod
        @@ -0,0 +1,112 @@
        +=pod
        +
        +=head1 NAME
        +
        +blowfish, BF_set_key, BF_encrypt, BF_decrypt, BF_ecb_encrypt, BF_cbc_encrypt,
        +BF_cfb64_encrypt, BF_ofb64_encrypt, BF_options - Blowfish encryption
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/blowfish.h>
        +
        + void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
        +
        + void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
        +         BF_KEY *key, int enc);
        + void BF_cbc_encrypt(const unsigned char *in, unsigned char *out,
        + 	 long length, BF_KEY *schedule, unsigned char *ivec, int enc);
        + void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        + 	 long length, BF_KEY *schedule, unsigned char *ivec, int *num,
        +         int enc);
        + void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        + 	 long length, BF_KEY *schedule, unsigned char *ivec, int *num);
        + const char *BF_options(void);
        +
        + void BF_encrypt(BF_LONG *data,const BF_KEY *key);
        + void BF_decrypt(BF_LONG *data,const BF_KEY *key);
        +
        +=head1 DESCRIPTION
        +
        +This library implements the Blowfish cipher, which was invented and described
        +by Counterpane (see http://www.counterpane.com/blowfish.html ).
        +
        +Blowfish is a block cipher that operates on 64 bit (8 byte) blocks of data.
        +It uses a variable size key, but typically, 128 bit (16 byte) keys are
        +considered good for strong encryption.  Blowfish can be used in the same
        +modes as DES (see L<des_modes(7)|des_modes(7)>).  Blowfish is currently one
        +of the faster block ciphers.  It is quite a bit faster than DES, and much
        +faster than IDEA or RC2.
        +
        +Blowfish consists of a key setup phase and the actual encryption or decryption
        +phase.
        +
        +BF_set_key() sets up the B<BF_KEY> B<key> using the B<len> bytes long key
        +at B<data>.
        +
        +BF_ecb_encrypt() is the basic Blowfish encryption and decryption function.
        +It encrypts or decrypts the first 64 bits of B<in> using the key B<key>,
        +putting the result in B<out>.  B<enc> decides if encryption (B<BF_ENCRYPT>)
        +or decryption (B<BF_DECRYPT>) shall be performed.  The vector pointed at by
        +B<in> and B<out> must be 64 bits in length, no less.  If they are larger,
        +everything after the first 64 bits is ignored.
        +
        +The mode functions BF_cbc_encrypt(), BF_cfb64_encrypt() and BF_ofb64_encrypt()
        +all operate on variable length data.  They all take an initialization vector
        +B<ivec> which needs to be passed along into the next call of the same function 
        +for the same message.  B<ivec> may be initialized with anything, but the
        +recipient needs to know what it was initialized with, or it won't be able
        +to decrypt.  Some programs and protocols simplify this, like SSH, where
        +B<ivec> is simply initialized to zero.
        +BF_cbc_encrypt() operates on data that is a multiple of 8 bytes long, while
        +BF_cfb64_encrypt() and BF_ofb64_encrypt() are used to encrypt an variable
        +number of bytes (the amount does not have to be an exact multiple of 8).  The
        +purpose of the latter two is to simulate stream ciphers, and therefore, they
        +need the parameter B<num>, which is a pointer to an integer where the current
        +offset in B<ivec> is stored between calls.  This integer must be initialized
        +to zero when B<ivec> is initialized.
        +
        +BF_cbc_encrypt() is the Cipher Block Chaining function for Blowfish.  It
        +encrypts or decrypts the 64 bits chunks of B<in> using the key B<schedule>,
        +putting the result in B<out>.  B<enc> decides if encryption (BF_ENCRYPT) or
        +decryption (BF_DECRYPT) shall be performed.  B<ivec> must point at an 8 byte
        +long initialization vector.
        +
        +BF_cfb64_encrypt() is the CFB mode for Blowfish with 64 bit feedback.
        +It encrypts or decrypts the bytes in B<in> using the key B<schedule>,
        +putting the result in B<out>.  B<enc> decides if encryption (B<BF_ENCRYPT>)
        +or decryption (B<BF_DECRYPT>) shall be performed.  B<ivec> must point at an
        +8 byte long initialization vector. B<num> must point at an integer which must
        +be initially zero.
        +
        +BF_ofb64_encrypt() is the OFB mode for Blowfish with 64 bit feedback.
        +It uses the same parameters as BF_cfb64_encrypt(), which must be initialized
        +the same way.
        +
        +BF_encrypt() and BF_decrypt() are the lowest level functions for Blowfish
        +encryption.  They encrypt/decrypt the first 64 bits of the vector pointed by
        +B<data>, using the key B<key>.  These functions should not be used unless you
        +implement 'modes' of Blowfish.  The alternative is to use BF_ecb_encrypt().
        +If you still want to use these functions, you should be aware that they take
        +each 32-bit chunk in host-byte order, which is little-endian on little-endian
        +platforms and big-endian on big-endian ones.
        +
        +=head1 RETURN VALUES
        +
        +None of the functions presented here return any value.
        +
        +=head1 NOTE
        +
        +Applications should use the higher level functions
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> etc. instead of calling the
        +blowfish functions directly.
        +
        +=head1 SEE ALSO
        +
        +L<des_modes(7)|des_modes(7)>
        +
        +=head1 HISTORY
        +
        +The Blowfish functions are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        +
        diff --git a/vendor/openssl/openssl/doc/crypto/bn.pod b/vendor/openssl/openssl/doc/crypto/bn.pod
        new file mode 100644
        index 000000000..cd2f8e50c
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/bn.pod
        @@ -0,0 +1,181 @@
        +=pod
        +
        +=head1 NAME
        +
        +bn - multiprecision integer arithmetics
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BIGNUM *BN_new(void);
        + void BN_free(BIGNUM *a);
        + void BN_init(BIGNUM *);
        + void BN_clear(BIGNUM *a);
        + void BN_clear_free(BIGNUM *a);
        +
        + BN_CTX *BN_CTX_new(void);
        + void BN_CTX_init(BN_CTX *c);
        + void BN_CTX_free(BN_CTX *c);
        +
        + BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
        + BIGNUM *BN_dup(const BIGNUM *a);
        +
        + BIGNUM *BN_swap(BIGNUM *a, BIGNUM *b);
        +
        + int BN_num_bytes(const BIGNUM *a);
        + int BN_num_bits(const BIGNUM *a);
        + int BN_num_bits_word(BN_ULONG w);
        +
        + void BN_set_negative(BIGNUM *a, int n);
        + int  BN_is_negative(const BIGNUM *a);
        +
        + int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        + int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
        + int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
        + int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
        + int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
        +         BN_CTX *ctx);
        + int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        + int BN_nnmod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        + int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
        +         BN_CTX *ctx);
        + int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
        +         BN_CTX *ctx);
        + int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
        +         BN_CTX *ctx);
        + int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
        + int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);
        + int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
        +         const BIGNUM *m, BN_CTX *ctx);
        + int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
        +
        + int BN_add_word(BIGNUM *a, BN_ULONG w);
        + int BN_sub_word(BIGNUM *a, BN_ULONG w);
        + int BN_mul_word(BIGNUM *a, BN_ULONG w);
        + BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
        + BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
        +
        + int BN_cmp(BIGNUM *a, BIGNUM *b);
        + int BN_ucmp(BIGNUM *a, BIGNUM *b);
        + int BN_is_zero(BIGNUM *a);
        + int BN_is_one(BIGNUM *a);
        + int BN_is_word(BIGNUM *a, BN_ULONG w);
        + int BN_is_odd(BIGNUM *a);
        +
        + int BN_zero(BIGNUM *a);
        + int BN_one(BIGNUM *a);
        + const BIGNUM *BN_value_one(void);
        + int BN_set_word(BIGNUM *a, unsigned long w);
        + unsigned long BN_get_word(BIGNUM *a);
        +
        + int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
        + int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
        + int BN_rand_range(BIGNUM *rnd, BIGNUM *range);
        + int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
        +
        + BIGNUM *BN_generate_prime(BIGNUM *ret, int bits,int safe, BIGNUM *add,
        +         BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg);
        + int BN_is_prime(const BIGNUM *p, int nchecks,
        +         void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg);
        +
        + int BN_set_bit(BIGNUM *a, int n);
        + int BN_clear_bit(BIGNUM *a, int n);
        + int BN_is_bit_set(const BIGNUM *a, int n);
        + int BN_mask_bits(BIGNUM *a, int n);
        + int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
        + int BN_lshift1(BIGNUM *r, BIGNUM *a);
        + int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
        + int BN_rshift1(BIGNUM *r, BIGNUM *a);
        +
        + int BN_bn2bin(const BIGNUM *a, unsigned char *to);
        + BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
        + char *BN_bn2hex(const BIGNUM *a);
        + char *BN_bn2dec(const BIGNUM *a);
        + int BN_hex2bn(BIGNUM **a, const char *str);
        + int BN_dec2bn(BIGNUM **a, const char *str);
        + int BN_print(BIO *fp, const BIGNUM *a);
        + int BN_print_fp(FILE *fp, const BIGNUM *a);
        + int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
        + BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);
        +
        + BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n,
        +     BN_CTX *ctx);
        +
        + BN_RECP_CTX *BN_RECP_CTX_new(void);
        + void BN_RECP_CTX_init(BN_RECP_CTX *recp);
        + void BN_RECP_CTX_free(BN_RECP_CTX *recp);
        + int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
        + int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
        +        BN_RECP_CTX *recp, BN_CTX *ctx);
        +
        + BN_MONT_CTX *BN_MONT_CTX_new(void);
        + void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
        + void BN_MONT_CTX_free(BN_MONT_CTX *mont);
        + int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
        + BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
        + int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
        +         BN_MONT_CTX *mont, BN_CTX *ctx);
        + int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
        +         BN_CTX *ctx);
        + int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
        +         BN_CTX *ctx);
        +
        + BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai,
        +	BIGNUM *mod);
        + void BN_BLINDING_free(BN_BLINDING *b);
        + int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
        + int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
        + int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
        + int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b,
        +	BN_CTX *ctx);
        + int BN_BLINDING_invert_ex(BIGNUM *n,const BIGNUM *r,BN_BLINDING *b,
        +	BN_CTX *ctx);
        + unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
        + void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
        + unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
        + void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
        + BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
        +	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
        +	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
        +	BN_MONT_CTX *m_ctx);
        +
        +=head1 DESCRIPTION
        +
        +This library performs arithmetic operations on integers of arbitrary
        +size. It was written for use in public key cryptography, such as RSA
        +and Diffie-Hellman.
        +
        +It uses dynamic memory allocation for storing its data structures.
        +That means that there is no limit on the size of the numbers
        +manipulated by these functions, but return values must always be
        +checked in case a memory allocation error has occurred.
        +
        +The basic object in this library is a B<BIGNUM>. It is used to hold a
        +single large integer. This type should be considered opaque and fields
        +should not be modified or accessed directly.
        +
        +The creation of B<BIGNUM> objects is described in L<BN_new(3)|BN_new(3)>;
        +L<BN_add(3)|BN_add(3)> describes most of the arithmetic operations.
        +Comparison is described in L<BN_cmp(3)|BN_cmp(3)>; L<BN_zero(3)|BN_zero(3)>
        +describes certain assignments, L<BN_rand(3)|BN_rand(3)> the generation of
        +random numbers, L<BN_generate_prime(3)|BN_generate_prime(3)> deals with prime
        +numbers and L<BN_set_bit(3)|BN_set_bit(3)> with bit operations. The conversion
        +of B<BIGNUM>s to external formats is described in L<BN_bn2bin(3)|BN_bn2bin(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<bn_internal(3)|bn_internal(3)>,
        +L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>,
        +L<BN_new(3)|BN_new(3)>, L<BN_CTX_new(3)|BN_CTX_new(3)>,
        +L<BN_copy(3)|BN_copy(3)>, L<BN_swap(3)|BN_swap(3)>, L<BN_num_bytes(3)|BN_num_bytes(3)>,
        +L<BN_add(3)|BN_add(3)>, L<BN_add_word(3)|BN_add_word(3)>,
        +L<BN_cmp(3)|BN_cmp(3)>, L<BN_zero(3)|BN_zero(3)>, L<BN_rand(3)|BN_rand(3)>,
        +L<BN_generate_prime(3)|BN_generate_prime(3)>, L<BN_set_bit(3)|BN_set_bit(3)>,
        +L<BN_bn2bin(3)|BN_bn2bin(3)>, L<BN_mod_inverse(3)|BN_mod_inverse(3)>,
        +L<BN_mod_mul_reciprocal(3)|BN_mod_mul_reciprocal(3)>,
        +L<BN_mod_mul_montgomery(3)|BN_mod_mul_montgomery(3)>,
        +L<BN_BLINDING_new(3)|BN_BLINDING_new(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/bn_internal.pod b/vendor/openssl/openssl/doc/crypto/bn_internal.pod
        new file mode 100644
        index 000000000..91840b0f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/bn_internal.pod
        @@ -0,0 +1,238 @@
        +=pod
        +
        +=head1 NAME
        +
        +bn_mul_words, bn_mul_add_words, bn_sqr_words, bn_div_words,
        +bn_add_words, bn_sub_words, bn_mul_comba4, bn_mul_comba8,
        +bn_sqr_comba4, bn_sqr_comba8, bn_cmp_words, bn_mul_normal,
        +bn_mul_low_normal, bn_mul_recursive, bn_mul_part_recursive,
        +bn_mul_low_recursive, bn_mul_high, bn_sqr_normal, bn_sqr_recursive,
        +bn_expand, bn_wexpand, bn_expand2, bn_fix_top, bn_check_top,
        +bn_print, bn_dump, bn_set_max, bn_set_high, bn_set_low - BIGNUM
        +library internal functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/bn.h>
        +
        + BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
        + BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num,
        +   BN_ULONG w);
        + void     bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
        + BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
        + BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
        +   int num);
        + BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
        +   int num);
        +
        + void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
        + void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
        + void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a);
        + void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a);
        +
        + int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n);
        +
        + void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
        +   int nb);
        + void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
        + void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
        +   int dna,int dnb,BN_ULONG *tmp);
        + void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
        +   int n, int tna,int tnb, BN_ULONG *tmp);
        + void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
        +   int n2, BN_ULONG *tmp);
        + void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l,
        +   int n2, BN_ULONG *tmp);
        +
        + void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
        + void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *tmp);
        +
        + void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
        + void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
        + void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a);
        +
        + BIGNUM *bn_expand(BIGNUM *a, int bits);
        + BIGNUM *bn_wexpand(BIGNUM *a, int n);
        + BIGNUM *bn_expand2(BIGNUM *a, int n);
        + void bn_fix_top(BIGNUM *a);
        +
        + void bn_check_top(BIGNUM *a);
        + void bn_print(BIGNUM *a);
        + void bn_dump(BN_ULONG *d, int n);
        + void bn_set_max(BIGNUM *a);
        + void bn_set_high(BIGNUM *r, BIGNUM *a, int n);
        + void bn_set_low(BIGNUM *r, BIGNUM *a, int n);
        +
        +=head1 DESCRIPTION
        +
        +This page documents the internal functions used by the OpenSSL
        +B<BIGNUM> implementation. They are described here to facilitate
        +debugging and extending the library. They are I<not> to be used by
        +applications.
        +
        +=head2 The BIGNUM structure
        +
        + typedef struct bignum_st BIGNUM;
        +
        + struct bignum_st
        +        {
        +        BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
        +        int top;        /* Index of last used d +1. */
        +        /* The next are internal book keeping for bn_expand. */
        +        int dmax;       /* Size of the d array. */
        +        int neg;        /* one if the number is negative */
        +        int flags;
        +        };
        +
        +
        +The integer value is stored in B<d>, a malloc()ed array of words (B<BN_ULONG>),
        +least significant word first. A B<BN_ULONG> can be either 16, 32 or 64 bits
        +in size, depending on the 'number of bits' (B<BITS2>) specified in
        +C<openssl/bn.h>.
        +
        +B<dmax> is the size of the B<d> array that has been allocated.  B<top>
        +is the number of words being used, so for a value of 4, bn.d[0]=4 and
        +bn.top=1.  B<neg> is 1 if the number is negative.  When a B<BIGNUM> is
        +B<0>, the B<d> field can be B<NULL> and B<top> == B<0>.
        +
        +B<flags> is a bit field of flags which are defined in C<openssl/bn.h>. The 
        +flags begin with B<BN_FLG_>. The macros BN_set_flags(b,n) and 
        +BN_get_flags(b,n) exist to enable or fetch flag(s) B<n> from B<BIGNUM>
        +structure B<b>.
        +
        +Various routines in this library require the use of temporary
        +B<BIGNUM> variables during their execution.  Since dynamic memory
        +allocation to create B<BIGNUM>s is rather expensive when used in
        +conjunction with repeated subroutine calls, the B<BN_CTX> structure is
        +used.  This structure contains B<BN_CTX_NUM> B<BIGNUM>s, see
        +L<BN_CTX_start(3)|BN_CTX_start(3)>.
        +
        +=head2 Low-level arithmetic operations
        +
        +These functions are implemented in C and for several platforms in
        +assembly language:
        +
        +bn_mul_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num> word
        +arrays B<rp> and B<ap>.  It computes B<ap> * B<w>, places the result
        +in B<rp>, and returns the high word (carry).
        +
        +bn_mul_add_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num>
        +word arrays B<rp> and B<ap>.  It computes B<ap> * B<w> + B<rp>, places
        +the result in B<rp>, and returns the high word (carry).
        +
        +bn_sqr_words(B<rp>, B<ap>, B<n>) operates on the B<num> word array
        +B<ap> and the 2*B<num> word array B<ap>.  It computes B<ap> * B<ap>
        +word-wise, and places the low and high bytes of the result in B<rp>.
        +
        +bn_div_words(B<h>, B<l>, B<d>) divides the two word number (B<h>,B<l>)
        +by B<d> and returns the result.
        +
        +bn_add_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
        +arrays B<ap>, B<bp> and B<rp>.  It computes B<ap> + B<bp>, places the
        +result in B<rp>, and returns the high word (carry).
        +
        +bn_sub_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
        +arrays B<ap>, B<bp> and B<rp>.  It computes B<ap> - B<bp>, places the
        +result in B<rp>, and returns the carry (1 if B<bp> E<gt> B<ap>, 0
        +otherwise).
        +
        +bn_mul_comba4(B<r>, B<a>, B<b>) operates on the 4 word arrays B<a> and
        +B<b> and the 8 word array B<r>.  It computes B<a>*B<b> and places the
        +result in B<r>.
        +
        +bn_mul_comba8(B<r>, B<a>, B<b>) operates on the 8 word arrays B<a> and
        +B<b> and the 16 word array B<r>.  It computes B<a>*B<b> and places the
        +result in B<r>.
        +
        +bn_sqr_comba4(B<r>, B<a>, B<b>) operates on the 4 word arrays B<a> and
        +B<b> and the 8 word array B<r>.
        +
        +bn_sqr_comba8(B<r>, B<a>, B<b>) operates on the 8 word arrays B<a> and
        +B<b> and the 16 word array B<r>.
        +
        +The following functions are implemented in C:
        +
        +bn_cmp_words(B<a>, B<b>, B<n>) operates on the B<n> word arrays B<a>
        +and B<b>.  It returns 1, 0 and -1 if B<a> is greater than, equal and
        +less than B<b>.
        +
        +bn_mul_normal(B<r>, B<a>, B<na>, B<b>, B<nb>) operates on the B<na>
        +word array B<a>, the B<nb> word array B<b> and the B<na>+B<nb> word
        +array B<r>.  It computes B<a>*B<b> and places the result in B<r>.
        +
        +bn_mul_low_normal(B<r>, B<a>, B<b>, B<n>) operates on the B<n> word
        +arrays B<r>, B<a> and B<b>.  It computes the B<n> low words of
        +B<a>*B<b> and places the result in B<r>.
        +
        +bn_mul_recursive(B<r>, B<a>, B<b>, B<n2>, B<dna>, B<dnb>, B<t>) operates
        +on the word arrays B<a> and B<b> of length B<n2>+B<dna> and B<n2>+B<dnb>
        +(B<dna> and B<dnb> are currently allowed to be 0 or negative) and the 2*B<n2>
        +word arrays B<r> and B<t>.  B<n2> must be a power of 2.  It computes
        +B<a>*B<b> and places the result in B<r>.
        +
        +bn_mul_part_recursive(B<r>, B<a>, B<b>, B<n>, B<tna>, B<tnb>, B<tmp>)
        +operates on the word arrays B<a> and B<b> of length B<n>+B<tna> and
        +B<n>+B<tnb> and the 4*B<n> word arrays B<r> and B<tmp>.
        +
        +bn_mul_low_recursive(B<r>, B<a>, B<b>, B<n2>, B<tmp>) operates on the
        +B<n2> word arrays B<r> and B<tmp> and the B<n2>/2 word arrays B<a>
        +and B<b>.
        +
        +bn_mul_high(B<r>, B<a>, B<b>, B<l>, B<n2>, B<tmp>) operates on the
        +B<n2> word arrays B<r>, B<a>, B<b> and B<l> (?) and the 3*B<n2> word
        +array B<tmp>.
        +
        +BN_mul() calls bn_mul_normal(), or an optimized implementation if the
        +factors have the same size: bn_mul_comba8() is used if they are 8
        +words long, bn_mul_recursive() if they are larger than
        +B<BN_MULL_SIZE_NORMAL> and the size is an exact multiple of the word
        +size, and bn_mul_part_recursive() for others that are larger than
        +B<BN_MULL_SIZE_NORMAL>.
        +
        +bn_sqr_normal(B<r>, B<a>, B<n>, B<tmp>) operates on the B<n> word array
        +B<a> and the 2*B<n> word arrays B<tmp> and B<r>.
        +
        +The implementations use the following macros which, depending on the
        +architecture, may use "long long" C operations or inline assembler.
        +They are defined in C<bn_lcl.h>.
        +
        +mul(B<r>, B<a>, B<w>, B<c>) computes B<w>*B<a>+B<c> and places the
        +low word of the result in B<r> and the high word in B<c>.
        +
        +mul_add(B<r>, B<a>, B<w>, B<c>) computes B<w>*B<a>+B<r>+B<c> and
        +places the low word of the result in B<r> and the high word in B<c>.
        +
        +sqr(B<r0>, B<r1>, B<a>) computes B<a>*B<a> and places the low word
        +of the result in B<r0> and the high word in B<r1>.
        +
        +=head2 Size changes
        +
        +bn_expand() ensures that B<b> has enough space for a B<bits> bit
        +number.  bn_wexpand() ensures that B<b> has enough space for an
        +B<n> word number.  If the number has to be expanded, both macros
        +call bn_expand2(), which allocates a new B<d> array and copies the
        +data.  They return B<NULL> on error, B<b> otherwise.
        +
        +The bn_fix_top() macro reduces B<a-E<gt>top> to point to the most
        +significant non-zero word plus one when B<a> has shrunk.
        +
        +=head2 Debugging
        +
        +bn_check_top() verifies that C<((a)-E<gt>top E<gt>= 0 && (a)-E<gt>top
        +E<lt>= (a)-E<gt>dmax)>.  A violation will cause the program to abort.
        +
        +bn_print() prints B<a> to stderr. bn_dump() prints B<n> words at B<d>
        +(in reverse order, i.e. most significant word first) to stderr.
        +
        +bn_set_max() makes B<a> a static number with a B<dmax> of its current size.
        +This is used by bn_set_low() and bn_set_high() to make B<r> a read-only
        +B<BIGNUM> that contains the B<n> low or high words of B<a>.
        +
        +If B<BN_DEBUG> is not defined, bn_check_top(), bn_print(), bn_dump()
        +and bn_set_max() are defined as empty macros.
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/buffer.pod b/vendor/openssl/openssl/doc/crypto/buffer.pod
        new file mode 100644
        index 000000000..781f5b11e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/buffer.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +BUF_MEM_new, BUF_MEM_free, BUF_MEM_grow, BUF_strdup - simple
        +character arrays structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/buffer.h>
        +
        + BUF_MEM *BUF_MEM_new(void);
        +
        + void	BUF_MEM_free(BUF_MEM *a);
        +
        + int	BUF_MEM_grow(BUF_MEM *str, int len);
        +
        + char *	BUF_strdup(const char *str);
        +
        +=head1 DESCRIPTION
        +
        +The buffer library handles simple character arrays. Buffers are used for
        +various purposes in the library, most notably memory BIOs.
        +
        +The library uses the BUF_MEM structure defined in buffer.h:
        +
        + typedef struct buf_mem_st
        + {
        +        int length;     /* current number of bytes */
        +        char *data;
        +        int max;        /* size of buffer */
        + } BUF_MEM;
        +
        +B<length> is the current size of the buffer in bytes, B<max> is the amount of
        +memory allocated to the buffer. There are three functions which handle these
        +and one "miscellaneous" function.
        +
        +BUF_MEM_new() allocates a new buffer of zero size.
        +
        +BUF_MEM_free() frees up an already existing buffer. The data is zeroed
        +before freeing up in case the buffer contains sensitive data.
        +
        +BUF_MEM_grow() changes the size of an already existing buffer to
        +B<len>. Any data already in the buffer is preserved if it increases in
        +size.
        +
        +BUF_strdup() copies a null terminated string into a block of allocated
        +memory and returns a pointer to the allocated block.
        +Unlike the standard C library strdup() this function uses OPENSSL_malloc() and so
        +should be used in preference to the standard library strdup() because it can
        +be used for memory leak checking or replacing the malloc() function.
        +
        +The memory allocated from BUF_strdup() should be freed up using the OPENSSL_free()
        +function.
        +
        +=head1 RETURN VALUES
        +
        +BUF_MEM_new() returns the buffer or NULL on error.
        +
        +BUF_MEM_free() has no return value.
        +
        +BUF_MEM_grow() returns zero on error or the new size (i.e. B<len>).
        +
        +=head1 SEE ALSO
        +
        +L<bio(3)|bio(3)>
        +
        +=head1 HISTORY
        +
        +BUF_MEM_new(), BUF_MEM_free() and BUF_MEM_grow() are available in all
        +versions of SSLeay and OpenSSL. BUF_strdup() was added in SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/crypto.pod b/vendor/openssl/openssl/doc/crypto/crypto.pod
        new file mode 100644
        index 000000000..7a527992b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/crypto.pod
        @@ -0,0 +1,85 @@
        +=pod
        +
        +=head1 NAME
        +
        +crypto - OpenSSL cryptographic library
        +
        +=head1 SYNOPSIS
        +
        +=head1 DESCRIPTION
        +
        +The OpenSSL B<crypto> library implements a wide range of cryptographic
        +algorithms used in various Internet standards. The services provided
        +by this library are used by the OpenSSL implementations of SSL, TLS
        +and S/MIME, and they have also been used to implement SSH, OpenPGP, and
        +other cryptographic standards.
        +
        +=head1 OVERVIEW
        +
        +B<libcrypto> consists of a number of sub-libraries that implement the
        +individual algorithms.
        +
        +The functionality includes symmetric encryption, public key
        +cryptography and key agreement, certificate handling, cryptographic
        +hash functions and a cryptographic pseudo-random number generator.
        +
        +=over 4
        +
        +=item SYMMETRIC CIPHERS
        +
        +L<blowfish(3)|blowfish(3)>, L<cast(3)|cast(3)>, L<des(3)|des(3)>,
        +L<idea(3)|idea(3)>, L<rc2(3)|rc2(3)>, L<rc4(3)|rc4(3)>, L<rc5(3)|rc5(3)> 
        +
        +=item PUBLIC KEY CRYPTOGRAPHY AND KEY AGREEMENT
        +
        +L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rsa(3)|rsa(3)>
        +
        +=item CERTIFICATES
        +
        +L<x509(3)|x509(3)>, L<x509v3(3)|x509v3(3)>
        +
        +=item AUTHENTICATION CODES, HASH FUNCTIONS
        +
        +L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, L<md4(3)|md4(3)>,
        +L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
        +L<sha(3)|sha(3)>
        +
        +=item AUXILIARY FUNCTIONS
        +
        +L<err(3)|err(3)>, L<threads(3)|threads(3)>, L<rand(3)|rand(3)>,
        +L<OPENSSL_VERSION_NUMBER(3)|OPENSSL_VERSION_NUMBER(3)>
        +
        +=item INPUT/OUTPUT, DATA ENCODING
        +
        +L<asn1(3)|asn1(3)>, L<bio(3)|bio(3)>, L<evp(3)|evp(3)>, L<pem(3)|pem(3)>,
        +L<pkcs7(3)|pkcs7(3)>, L<pkcs12(3)|pkcs12(3)> 
        +
        +=item INTERNAL FUNCTIONS
        +
        +L<bn(3)|bn(3)>, L<buffer(3)|buffer(3)>, L<lhash(3)|lhash(3)>,
        +L<objects(3)|objects(3)>, L<stack(3)|stack(3)>,
        +L<txt_db(3)|txt_db(3)> 
        +
        +=back
        +
        +=head1 NOTES
        +
        +Some of the newer functions follow a naming convention using the numbers
        +B<0> and B<1>. For example the functions:
        +
        + int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
        + int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
        +
        +The B<0> version uses the supplied structure pointer directly
        +in the parent and it will be freed up when the parent is freed.
        +In the above example B<crl> would be freed but B<rev> would not.
        +
        +The B<1> function uses a copy of the supplied structure pointer
        +(or in some cases increases its link count) in the parent and
        +so both (B<x> and B<obj> above) should be freed up.
        +
        +=head1 SEE ALSO
        +
        +L<openssl(1)|openssl(1)>, L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_ASN1_OBJECT.pod b/vendor/openssl/openssl/doc/crypto/d2i_ASN1_OBJECT.pod
        new file mode 100644
        index 000000000..45bb18492
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_ASN1_OBJECT.pod
        @@ -0,0 +1,29 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_ASN1_OBJECT, i2d_ASN1_OBJECT - ASN1 OBJECT IDENTIFIER functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/objects.h>
        +
        + ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, long length);
        + int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode an ASN1 OBJECT IDENTIFIER.
        +
        +Othewise these behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_DHparams.pod b/vendor/openssl/openssl/doc/crypto/d2i_DHparams.pod
        new file mode 100644
        index 000000000..1e98aebec
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_DHparams.pod
        @@ -0,0 +1,30 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_DHparams, i2d_DHparams - PKCS#3 DH parameter functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        +
        + DH *d2i_DHparams(DH **a, unsigned char **pp, long length);
        + int i2d_DHparams(DH *a, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode PKCS#3 DH parameters using the
        +DHparameter structure described in PKCS#3.
        +
        +Othewise these behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_DSAPublicKey.pod b/vendor/openssl/openssl/doc/crypto/d2i_DSAPublicKey.pod
        new file mode 100644
        index 000000000..22c1b50f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_DSAPublicKey.pod
        @@ -0,0 +1,83 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_DSAPublicKey, i2d_DSAPublicKey, d2i_DSAPrivateKey, i2d_DSAPrivateKey,
        +d2i_DSA_PUBKEY, i2d_DSA_PUBKEY, d2i_DSA_SIG, i2d_DSA_SIG - DSA key encoding
        +and parsing functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        + #include <openssl/x509.h>
        +
        + DSA * d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
        +
        + int i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
        +
        + DSA * d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
        +
        + int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp);
        +
        + DSA * d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
        +
        + int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
        +
        + DSA * d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
        +
        + int i2d_DSAparams(const DSA *a, unsigned char **pp);
        +
        + DSA * d2i_DSA_SIG(DSA_SIG **a, const unsigned char **pp, long length);
        +
        + int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +d2i_DSAPublicKey() and i2d_DSAPublicKey() decode and encode the DSA public key
        +components structure.
        +
        +d2i_DSA_PUBKEY() and i2d_DSA_PUBKEY() decode and encode an DSA public key using
        +a SubjectPublicKeyInfo (certificate public key) structure.
        +
        +d2i_DSAPrivateKey(), i2d_DSAPrivateKey() decode and encode the DSA private key
        +components.
        +
        +d2i_DSAparams(), i2d_DSAparams() decode and encode the DSA parameters using
        +a B<Dss-Parms> structure as defined in RFC2459.
        +
        +d2i_DSA_SIG(), i2d_DSA_SIG() decode and encode a DSA signature using a
        +B<Dss-Sig-Value> structure as defined in RFC2459.
        +
        +The usage of all of these functions is similar to the d2i_X509() and
        +i2d_X509() described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 NOTES
        +
        +The B<DSA> structure passed to the private key encoding functions should have
        +all the private key components present.
        +
        +The data encoded by the private key functions is unencrypted and therefore 
        +offers no private key security.
        +
        +The B<DSA_PUBKEY> functions should be used in preference to the B<DSAPublicKey>
        +functions when encoding public keys because they use a standard format.
        +
        +The B<DSAPublicKey> functions use an non standard format the actual data encoded
        +depends on the value of the B<write_params> field of the B<a> key parameter.
        +If B<write_params> is zero then only the B<pub_key> field is encoded as an
        +B<INTEGER>. If B<write_params> is 1 then a B<SEQUENCE> consisting of the
        +B<p>, B<q>, B<g> and B<pub_key> respectively fields are encoded.
        +
        +The B<DSAPrivateKey> functions also use a non standard structure consiting
        +consisting of a SEQUENCE containing the B<p>, B<q>, B<g> and B<pub_key> and
        +B<priv_key> fields respectively.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_PKCS8PrivateKey.pod b/vendor/openssl/openssl/doc/crypto/d2i_PKCS8PrivateKey.pod
        new file mode 100644
        index 000000000..a54b77908
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_PKCS8PrivateKey.pod
        @@ -0,0 +1,56 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_PKCS8PrivateKey_bio, d2i_PKCS8PrivateKey_fp,
        +i2d_PKCS8PrivateKey_bio, i2d_PKCS8PrivateKey_fp,
        +i2d_PKCS8PrivateKey_nid_bio, i2d_PKCS8PrivateKey_nid_fp - PKCS#8 format private key functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        + EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
        + EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
        +
        + int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +
        + int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +
        + int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +
        + int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
        +				  char *kstr, int klen,
        +				  pem_password_cb *cb, void *u);
        +
        +=head1 DESCRIPTION
        +
        +The PKCS#8 functions encode and decode private keys in PKCS#8 format using both
        +PKCS#5 v1.5 and PKCS#5 v2.0 password based encryption algorithms.
        +
        +Other than the use of DER as opposed to PEM these functions are identical to the
        +corresponding B<PEM> function as described in the L<pem(3)|pem(3)> manual page.
        +
        +=head1 NOTES
        +
        +Before using these functions L<OpenSSL_add_all_algorithms(3)|OpenSSL_add_all_algorithms(3)>
        +should be called to initialize the internal algorithm lookup tables otherwise errors about
        +unknown algorithms will occur if an attempt is made to decrypt a private key. 
        +
        +These functions are currently the only way to store encrypted private keys using DER format.
        +
        +Currently all the functions use BIOs or FILE pointers, there are no functions which
        +work directly on memory: this can be readily worked around by converting the buffers
        +to memory BIOs, see L<BIO_s_mem(3)|BIO_s_mem(3)> for details.
        +
        +=head1 SEE ALSO
        +
        +L<pem(3)|pem(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_RSAPublicKey.pod b/vendor/openssl/openssl/doc/crypto/d2i_RSAPublicKey.pod
        new file mode 100644
        index 000000000..aa6078bcf
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_RSAPublicKey.pod
        @@ -0,0 +1,67 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey,
        +d2i_RSA_PUBKEY, i2d_RSA_PUBKEY, i2d_Netscape_RSA,
        +d2i_Netscape_RSA - RSA public and private key encoding functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        + #include <openssl/x509.h>
        +
        + RSA * d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length);
        +
        + int i2d_RSAPublicKey(RSA *a, unsigned char **pp);
        +
        + RSA * d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
        +
        + int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
        +
        + RSA * d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length);
        +
        + int i2d_RSAPrivateKey(RSA *a, unsigned char **pp);
        +
        + int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());
        +
        + RSA * d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)());
        +
        +=head1 DESCRIPTION
        +
        +d2i_RSAPublicKey() and i2d_RSAPublicKey() decode and encode a PKCS#1 RSAPublicKey
        +structure.
        +
        +d2i_RSA_PUBKEY() and i2d_RSA_PUBKEY() decode and encode an RSA public key using
        +a SubjectPublicKeyInfo (certificate public key) structure.
        +
        +d2i_RSAPrivateKey(), i2d_RSAPrivateKey() decode and encode a PKCS#1 RSAPrivateKey
        +structure.
        +
        +d2i_Netscape_RSA(), i2d_Netscape_RSA() decode and encode an RSA private key in
        +NET format.
        +
        +The usage of all of these functions is similar to the d2i_X509() and
        +i2d_X509() described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 NOTES
        +
        +The B<RSA> structure passed to the private key encoding functions should have
        +all the PKCS#1 private key components present.
        +
        +The data encoded by the private key functions is unencrypted and therefore 
        +offers no private key security. 
        +
        +The NET format functions are present to provide compatibility with certain very
        +old software. This format has some severe security weaknesses and should be
        +avoided if possible.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_X509.pod b/vendor/openssl/openssl/doc/crypto/d2i_X509.pod
        new file mode 100644
        index 000000000..298ec54a4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_X509.pod
        @@ -0,0 +1,231 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio,
        +i2d_X509_fp - X509 encode and decode functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509 *d2i_X509(X509 **px, const unsigned char **in, int len);
        + int i2d_X509(X509 *x, unsigned char **out);
        +
        + X509 *d2i_X509_bio(BIO *bp, X509 **x);
        + X509 *d2i_X509_fp(FILE *fp, X509 **x);
        +
        + int i2d_X509_bio(BIO *bp, X509 *x);
        + int i2d_X509_fp(FILE *fp, X509 *x);
        +
        +=head1 DESCRIPTION
        +
        +The X509 encode and decode routines encode and parse an
        +B<X509> structure, which represents an X509 certificate.
        +
        +d2i_X509() attempts to decode B<len> bytes at B<*in>. If 
        +successful a pointer to the B<X509> structure is returned. If an error
        +occurred then B<NULL> is returned. If B<px> is not B<NULL> then the
        +returned structure is written to B<*px>. If B<*px> is not B<NULL>
        +then it is assumed that B<*px> contains a valid B<X509>
        +structure and an attempt is made to reuse it. If the call is
        +successful B<*in> is incremented to the byte following the
        +parsed data.
        +
        +i2d_X509() encodes the structure pointed to by B<x> into DER format.
        +If B<out> is not B<NULL> is writes the DER encoded data to the buffer
        +at B<*out>, and increments it to point after the data just written.
        +If the return value is negative an error occurred, otherwise it
        +returns the length of the encoded data. 
        +
        +For OpenSSL 0.9.7 and later if B<*out> is B<NULL> memory will be
        +allocated for a buffer and the encoded data written to it. In this
        +case B<*out> is not incremented and it points to the start of the
        +data just written.
        +
        +d2i_X509_bio() is similar to d2i_X509() except it attempts
        +to parse data from BIO B<bp>.
        +
        +d2i_X509_fp() is similar to d2i_X509() except it attempts
        +to parse data from FILE pointer B<fp>.
        +
        +i2d_X509_bio() is similar to i2d_X509() except it writes
        +the encoding of the structure B<x> to BIO B<bp> and it
        +returns 1 for success and 0 for failure.
        +
        +i2d_X509_fp() is similar to i2d_X509() except it writes
        +the encoding of the structure B<x> to BIO B<bp> and it
        +returns 1 for success and 0 for failure.
        +
        +=head1 NOTES
        +
        +The letters B<i> and B<d> in for example B<i2d_X509> stand for
        +"internal" (that is an internal C structure) and "DER". So that
        +B<i2d_X509> converts from internal to DER.
        +
        +The functions can also understand B<BER> forms.
        +
        +The actual X509 structure passed to i2d_X509() must be a valid
        +populated B<X509> structure it can B<not> simply be fed with an
        +empty structure such as that returned by X509_new().
        +
        +The encoded data is in binary form and may contain embedded zeroes.
        +Therefore any FILE pointers or BIOs should be opened in binary mode.
        +Functions such as B<strlen()> will B<not> return the correct length
        +of the encoded structure.
        +
        +The ways that B<*in> and B<*out> are incremented after the operation
        +can trap the unwary. See the B<WARNINGS> section for some common
        +errors.
        +
        +The reason for the auto increment behaviour is to reflect a typical
        +usage of ASN1 functions: after one structure is encoded or decoded
        +another will processed after it.
        +
        +=head1 EXAMPLES
        +
        +Allocate and encode the DER encoding of an X509 structure:
        +
        + int len;
        + unsigned char *buf, *p;
        +
        + len = i2d_X509(x, NULL);
        +
        + buf = OPENSSL_malloc(len);
        +
        + if (buf == NULL)
        +	/* error */
        +
        + p = buf;
        +
        + i2d_X509(x, &p);
        +
        +If you are using OpenSSL 0.9.7 or later then this can be
        +simplified to:
        +
        +
        + int len;
        + unsigned char *buf;
        +
        + buf = NULL;
        +
        + len = i2d_X509(x, &buf);
        +
        + if (len < 0)
        +	/* error */
        +
        +Attempt to decode a buffer:
        +
        + X509 *x;
        +
        + unsigned char *buf, *p;
        +
        + int len;
        +
        + /* Something to setup buf and len */
        +
        + p = buf;
        +
        + x = d2i_X509(NULL, &p, len);
        +
        + if (x == NULL)
        +    /* Some error */
        +
        +Alternative technique:
        +
        + X509 *x;
        +
        + unsigned char *buf, *p;
        +
        + int len;
        +
        + /* Something to setup buf and len */
        +
        + p = buf;
        +
        + x = NULL;
        +
        + if(!d2i_X509(&x, &p, len))
        +    /* Some error */
        +
        +
        +=head1 WARNINGS
        +
        +The use of temporary variable is mandatory. A common
        +mistake is to attempt to use a buffer directly as follows:
        +
        + int len;
        + unsigned char *buf;
        +
        + len = i2d_X509(x, NULL);
        +
        + buf = OPENSSL_malloc(len);
        +
        + if (buf == NULL)
        +	/* error */
        +
        + i2d_X509(x, &buf);
        +
        + /* Other stuff ... */
        +
        + OPENSSL_free(buf);
        +
        +This code will result in B<buf> apparently containing garbage because
        +it was incremented after the call to point after the data just written.
        +Also B<buf> will no longer contain the pointer allocated by B<OPENSSL_malloc()>
        +and the subsequent call to B<OPENSSL_free()> may well crash.
        +
        +The auto allocation feature (setting buf to NULL) only works on OpenSSL
        +0.9.7 and later. Attempts to use it on earlier versions will typically
        +cause a segmentation violation.
        +
        +Another trap to avoid is misuse of the B<xp> argument to B<d2i_X509()>:
        +
        + X509 *x;
        +
        + if (!d2i_X509(&x, &p, len))
        +	/* Some error */
        +
        +This will probably crash somewhere in B<d2i_X509()>. The reason for this
        +is that the variable B<x> is uninitialized and an attempt will be made to
        +interpret its (invalid) value as an B<X509> structure, typically causing
        +a segmentation violation. If B<x> is set to NULL first then this will not
        +happen.
        +
        +=head1 BUGS
        +
        +In some versions of OpenSSL the "reuse" behaviour of d2i_X509() when 
        +B<*px> is valid is broken and some parts of the reused structure may
        +persist if they are not present in the new one. As a result the use
        +of this "reuse" behaviour is strongly discouraged.
        +
        +i2d_X509() will not return an error in many versions of OpenSSL,
        +if mandatory fields are not initialized due to a programming error
        +then the encoded structure may contain invalid data or omit the
        +fields entirely and will not be parsed by d2i_X509(). This may be
        +fixed in future so code should not assume that i2d_X509() will
        +always succeed.
        +
        +=head1 RETURN VALUES
        +
        +d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
        +or B<NULL> if an error occurs. The error code that can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>. 
        +
        +i2d_X509() returns the number of bytes successfully encoded or a negative
        +value if an error occurs. The error code can be obtained by
        +L<ERR_get_error(3)|ERR_get_error(3)>. 
        +
        +i2d_X509_bio() and i2d_X509_fp() return 1 for success and 0 if an error 
        +occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. 
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>
        +
        +=head1 HISTORY
        +
        +d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio and i2d_X509_fp
        +are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_X509_ALGOR.pod b/vendor/openssl/openssl/doc/crypto/d2i_X509_ALGOR.pod
        new file mode 100644
        index 000000000..9e5cd92ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_X509_ALGOR.pod
        @@ -0,0 +1,30 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_X509_ALGOR, i2d_X509_ALGOR - AlgorithmIdentifier functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **a, unsigned char **pp, long length);
        + int i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode an B<X509_ALGOR> structure which is
        +equivalent to the B<AlgorithmIdentifier> structure.
        +
        +Othewise these behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_X509_CRL.pod b/vendor/openssl/openssl/doc/crypto/d2i_X509_CRL.pod
        new file mode 100644
        index 000000000..224f9e082
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_X509_CRL.pod
        @@ -0,0 +1,37 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_X509_CRL, i2d_X509_CRL, d2i_X509_CRL_bio, d2i_509_CRL_fp,
        +i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509_CRL *d2i_X509_CRL(X509_CRL **a, const unsigned char **pp, long length);
        + int i2d_X509_CRL(X509_CRL *a, unsigned char **pp);
        +
        + X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x);
        + X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x);
        +
        + int i2d_X509_CRL_bio(BIO *bp, X509_CRL *x);
        + int i2d_X509_CRL_fp(FILE *fp, X509_CRL *x);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode an X509 CRL (certificate revocation
        +list).
        +
        +Othewise the functions behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_X509_NAME.pod b/vendor/openssl/openssl/doc/crypto/d2i_X509_NAME.pod
        new file mode 100644
        index 000000000..343ffe151
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_X509_NAME.pod
        @@ -0,0 +1,31 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_X509_NAME, i2d_X509_NAME - X509_NAME encoding functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509_NAME *d2i_X509_NAME(X509_NAME **a, unsigned char **pp, long length);
        + int i2d_X509_NAME(X509_NAME *a, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode an B<X509_NAME> structure which is the
        +the same as the B<Name> type defined in RFC2459 (and elsewhere) and used
        +for example in certificate subject and issuer names.
        +
        +Othewise the functions behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_X509_REQ.pod b/vendor/openssl/openssl/doc/crypto/d2i_X509_REQ.pod
        new file mode 100644
        index 000000000..91c0c1974
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_X509_REQ.pod
        @@ -0,0 +1,36 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_X509_REQ, i2d_X509_REQ, d2i_X509_REQ_bio, d2i_X509_REQ_fp,
        +i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509_REQ *d2i_X509_REQ(X509_REQ **a, const unsigned char **pp, long length);
        + int i2d_X509_REQ(X509_REQ *a, unsigned char **pp);
        +
        + X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x);
        + X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x);
        +
        + int i2d_X509_REQ_bio(BIO *bp, X509_REQ *x);
        + int i2d_X509_REQ_fp(FILE *fp, X509_REQ *x);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode a PKCS#10 certificate request.
        +
        +Othewise these behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/d2i_X509_SIG.pod b/vendor/openssl/openssl/doc/crypto/d2i_X509_SIG.pod
        new file mode 100644
        index 000000000..e48fd79a5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/d2i_X509_SIG.pod
        @@ -0,0 +1,30 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_X509_SIG, i2d_X509_SIG - DigestInfo functions.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        + X509_SIG *d2i_X509_SIG(X509_SIG **a, unsigned char **pp, long length);
        + int i2d_X509_SIG(X509_SIG *a, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +These functions decode and encode an X509_SIG structure which is
        +equivalent to the B<DigestInfo> structure defined in PKCS#1 and PKCS#7.
        +
        +Othewise these behave in a similar way to d2i_X509() and i2d_X509()
        +described in the L<d2i_X509(3)|d2i_X509(3)> manual page.
        +
        +=head1 SEE ALSO
        +
        +L<d2i_X509(3)|d2i_X509(3)>
        +
        +=head1 HISTORY
        +
        +TBA
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/des.pod b/vendor/openssl/openssl/doc/crypto/des.pod
        new file mode 100644
        index 000000000..6f0cf1cc5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/des.pod
        @@ -0,0 +1,358 @@
        +=pod
        +
        +=head1 NAME
        +
        +DES_random_key, DES_set_key, DES_key_sched, DES_set_key_checked,
        +DES_set_key_unchecked, DES_set_odd_parity, DES_is_weak_key,
        +DES_ecb_encrypt, DES_ecb2_encrypt, DES_ecb3_encrypt, DES_ncbc_encrypt,
        +DES_cfb_encrypt, DES_ofb_encrypt, DES_pcbc_encrypt, DES_cfb64_encrypt,
        +DES_ofb64_encrypt, DES_xcbc_encrypt, DES_ede2_cbc_encrypt,
        +DES_ede2_cfb64_encrypt, DES_ede2_ofb64_encrypt, DES_ede3_cbc_encrypt,
        +DES_ede3_cbcm_encrypt, DES_ede3_cfb64_encrypt, DES_ede3_ofb64_encrypt,
        +DES_cbc_cksum, DES_quad_cksum, DES_string_to_key, DES_string_to_2keys,
        +DES_fcrypt, DES_crypt, DES_enc_read, DES_enc_write - DES encryption
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/des.h>
        +
        + void DES_random_key(DES_cblock *ret);
        +
        + int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
        + int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
        + int DES_set_key_checked(const_DES_cblock *key,
        +        DES_key_schedule *schedule);
        + void DES_set_key_unchecked(const_DES_cblock *key,
        +        DES_key_schedule *schedule);
        +
        + void DES_set_odd_parity(DES_cblock *key);
        + int DES_is_weak_key(const_DES_cblock *key);
        +
        + void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, 
        +        DES_key_schedule *ks, int enc);
        + void DES_ecb2_encrypt(const_DES_cblock *input, DES_cblock *output, 
        +        DES_key_schedule *ks1, DES_key_schedule *ks2, int enc);
        + void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, 
        +        DES_key_schedule *ks1, DES_key_schedule *ks2, 
        +        DES_key_schedule *ks3, int enc);
        +
        + void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, 
        +        long length, DES_key_schedule *schedule, DES_cblock *ivec, 
        +        int enc);
        + void DES_cfb_encrypt(const unsigned char *in, unsigned char *out,
        +        int numbits, long length, DES_key_schedule *schedule,
        +        DES_cblock *ivec, int enc);
        + void DES_ofb_encrypt(const unsigned char *in, unsigned char *out,
        +        int numbits, long length, DES_key_schedule *schedule,
        +        DES_cblock *ivec);
        + void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, 
        +        long length, DES_key_schedule *schedule, DES_cblock *ivec, 
        +        int enc);
        + void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
        +        long length, DES_key_schedule *schedule, DES_cblock *ivec,
        +        int *num, int enc);
        + void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,
        +        long length, DES_key_schedule *schedule, DES_cblock *ivec,
        +        int *num);
        +
        + void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, 
        +        long length, DES_key_schedule *schedule, DES_cblock *ivec, 
        +        const_DES_cblock *inw, const_DES_cblock *outw, int enc);
        +
        + void DES_ede2_cbc_encrypt(const unsigned char *input,
        +        unsigned char *output, long length, DES_key_schedule *ks1,
        +        DES_key_schedule *ks2, DES_cblock *ivec, int enc);
        + void DES_ede2_cfb64_encrypt(const unsigned char *in,
        +        unsigned char *out, long length, DES_key_schedule *ks1,
        +        DES_key_schedule *ks2, DES_cblock *ivec, int *num, int enc);
        + void DES_ede2_ofb64_encrypt(const unsigned char *in,
        +        unsigned char *out, long length, DES_key_schedule *ks1,
        +        DES_key_schedule *ks2, DES_cblock *ivec, int *num);
        +
        + void DES_ede3_cbc_encrypt(const unsigned char *input,
        +        unsigned char *output, long length, DES_key_schedule *ks1,
        +        DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec,
        +        int enc);
        + void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, 
        +        long length, DES_key_schedule *ks1, DES_key_schedule *ks2, 
        +        DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2, 
        +        int enc);
        + void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, 
        +        long length, DES_key_schedule *ks1, DES_key_schedule *ks2,
        +        DES_key_schedule *ks3, DES_cblock *ivec, int *num, int enc);
        + void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, 
        +        long length, DES_key_schedule *ks1, 
        +        DES_key_schedule *ks2, DES_key_schedule *ks3, 
        +        DES_cblock *ivec, int *num);
        +
        + DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, 
        +        long length, DES_key_schedule *schedule, 
        +        const_DES_cblock *ivec);
        + DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], 
        +        long length, int out_count, DES_cblock *seed);
        + void DES_string_to_key(const char *str, DES_cblock *key);
        + void DES_string_to_2keys(const char *str, DES_cblock *key1,
        +        DES_cblock *key2);
        +
        + char *DES_fcrypt(const char *buf, const char *salt, char *ret);
        + char *DES_crypt(const char *buf, const char *salt);
        +
        + int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
        +        DES_cblock *iv);
        + int DES_enc_write(int fd, const void *buf, int len,
        +        DES_key_schedule *sched, DES_cblock *iv);
        +
        +=head1 DESCRIPTION
        +
        +This library contains a fast implementation of the DES encryption
        +algorithm.
        +
        +There are two phases to the use of DES encryption.  The first is the
        +generation of a I<DES_key_schedule> from a key, the second is the
        +actual encryption.  A DES key is of type I<DES_cblock>. This type is
        +consists of 8 bytes with odd parity.  The least significant bit in
        +each byte is the parity bit.  The key schedule is an expanded form of
        +the key; it is used to speed the encryption process.
        +
        +DES_random_key() generates a random key.  The PRNG must be seeded
        +prior to using this function (see L<rand(3)|rand(3)>).  If the PRNG
        +could not generate a secure key, 0 is returned.
        +
        +Before a DES key can be used, it must be converted into the
        +architecture dependent I<DES_key_schedule> via the
        +DES_set_key_checked() or DES_set_key_unchecked() function.
        +
        +DES_set_key_checked() will check that the key passed is of odd parity
        +and is not a week or semi-weak key.  If the parity is wrong, then -1
        +is returned.  If the key is a weak key, then -2 is returned.  If an
        +error is returned, the key schedule is not generated.
        +
        +DES_set_key() works like
        +DES_set_key_checked() if the I<DES_check_key> flag is non-zero,
        +otherwise like DES_set_key_unchecked().  These functions are available
        +for compatibility; it is recommended to use a function that does not
        +depend on a global variable.
        +
        +DES_set_odd_parity() sets the parity of the passed I<key> to odd.
        +
        +DES_is_weak_key() returns 1 is the passed key is a weak key, 0 if it
        +is ok.  The probability that a randomly generated key is weak is
        +1/2^52, so it is not really worth checking for them.
        +
        +The following routines mostly operate on an input and output stream of
        +I<DES_cblock>s.
        +
        +DES_ecb_encrypt() is the basic DES encryption routine that encrypts or
        +decrypts a single 8-byte I<DES_cblock> in I<electronic code book>
        +(ECB) mode.  It always transforms the input data, pointed to by
        +I<input>, into the output data, pointed to by the I<output> argument.
        +If the I<encrypt> argument is non-zero (DES_ENCRYPT), the I<input>
        +(cleartext) is encrypted in to the I<output> (ciphertext) using the
        +key_schedule specified by the I<schedule> argument, previously set via
        +I<DES_set_key>. If I<encrypt> is zero (DES_DECRYPT), the I<input> (now
        +ciphertext) is decrypted into the I<output> (now cleartext).  Input
        +and output may overlap.  DES_ecb_encrypt() does not return a value.
        +
        +DES_ecb3_encrypt() encrypts/decrypts the I<input> block by using
        +three-key Triple-DES encryption in ECB mode.  This involves encrypting
        +the input with I<ks1>, decrypting with the key schedule I<ks2>, and
        +then encrypting with I<ks3>.  This routine greatly reduces the chances
        +of brute force breaking of DES and has the advantage of if I<ks1>,
        +I<ks2> and I<ks3> are the same, it is equivalent to just encryption
        +using ECB mode and I<ks1> as the key.
        +
        +The macro DES_ecb2_encrypt() is provided to perform two-key Triple-DES
        +encryption by using I<ks1> for the final encryption.
        +
        +DES_ncbc_encrypt() encrypts/decrypts using the I<cipher-block-chaining>
        +(CBC) mode of DES.  If the I<encrypt> argument is non-zero, the
        +routine cipher-block-chain encrypts the cleartext data pointed to by
        +the I<input> argument into the ciphertext pointed to by the I<output>
        +argument, using the key schedule provided by the I<schedule> argument,
        +and initialization vector provided by the I<ivec> argument.  If the
        +I<length> argument is not an integral multiple of eight bytes, the
        +last block is copied to a temporary area and zero filled.  The output
        +is always an integral multiple of eight bytes.
        +
        +DES_xcbc_encrypt() is RSA's DESX mode of DES.  It uses I<inw> and
        +I<outw> to 'whiten' the encryption.  I<inw> and I<outw> are secret
        +(unlike the iv) and are as such, part of the key.  So the key is sort
        +of 24 bytes.  This is much better than CBC DES.
        +
        +DES_ede3_cbc_encrypt() implements outer triple CBC DES encryption with
        +three keys. This means that each DES operation inside the CBC mode is
        +really an C<C=E(ks3,D(ks2,E(ks1,M)))>.  This mode is used by SSL.
        +
        +The DES_ede2_cbc_encrypt() macro implements two-key Triple-DES by
        +reusing I<ks1> for the final encryption.  C<C=E(ks1,D(ks2,E(ks1,M)))>.
        +This form of Triple-DES is used by the RSAREF library.
        +
        +DES_pcbc_encrypt() encrypt/decrypts using the propagating cipher block
        +chaining mode used by Kerberos v4. Its parameters are the same as
        +DES_ncbc_encrypt().
        +
        +DES_cfb_encrypt() encrypt/decrypts using cipher feedback mode.  This
        +method takes an array of characters as input and outputs and array of
        +characters.  It does not require any padding to 8 character groups.
        +Note: the I<ivec> variable is changed and the new changed value needs to
        +be passed to the next call to this function.  Since this function runs
        +a complete DES ECB encryption per I<numbits>, this function is only
        +suggested for use when sending small numbers of characters.
        +
        +DES_cfb64_encrypt()
        +implements CFB mode of DES with 64bit feedback.  Why is this
        +useful you ask?  Because this routine will allow you to encrypt an
        +arbitrary number of bytes, no 8 byte padding.  Each call to this
        +routine will encrypt the input bytes to output and then update ivec
        +and num.  num contains 'how far' we are though ivec.  If this does
        +not make much sense, read more about cfb mode of DES :-).
        +
        +DES_ede3_cfb64_encrypt() and DES_ede2_cfb64_encrypt() is the same as
        +DES_cfb64_encrypt() except that Triple-DES is used.
        +
        +DES_ofb_encrypt() encrypts using output feedback mode.  This method
        +takes an array of characters as input and outputs and array of
        +characters.  It does not require any padding to 8 character groups.
        +Note: the I<ivec> variable is changed and the new changed value needs to
        +be passed to the next call to this function.  Since this function runs
        +a complete DES ECB encryption per numbits, this function is only
        +suggested for use when sending small numbers of characters.
        +
        +DES_ofb64_encrypt() is the same as DES_cfb64_encrypt() using Output
        +Feed Back mode.
        +
        +DES_ede3_ofb64_encrypt() and DES_ede2_ofb64_encrypt() is the same as
        +DES_ofb64_encrypt(), using Triple-DES.
        +
        +The following functions are included in the DES library for
        +compatibility with the MIT Kerberos library.
        +
        +DES_cbc_cksum() produces an 8 byte checksum based on the input stream
        +(via CBC encryption).  The last 4 bytes of the checksum are returned
        +and the complete 8 bytes are placed in I<output>. This function is
        +used by Kerberos v4.  Other applications should use
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)> etc. instead.
        +
        +DES_quad_cksum() is a Kerberos v4 function.  It returns a 4 byte
        +checksum from the input bytes.  The algorithm can be iterated over the
        +input, depending on I<out_count>, 1, 2, 3 or 4 times.  If I<output> is
        +non-NULL, the 8 bytes generated by each pass are written into
        +I<output>.
        +
        +The following are DES-based transformations:
        +
        +DES_fcrypt() is a fast version of the Unix crypt(3) function.  This
        +version takes only a small amount of space relative to other fast
        +crypt() implementations.  This is different to the normal crypt in
        +that the third parameter is the buffer that the return value is
        +written into.  It needs to be at least 14 bytes long.  This function
        +is thread safe, unlike the normal crypt.
        +
        +DES_crypt() is a faster replacement for the normal system crypt().
        +This function calls DES_fcrypt() with a static array passed as the
        +third parameter.  This emulates the normal non-thread safe semantics
        +of crypt(3).
        +
        +DES_enc_write() writes I<len> bytes to file descriptor I<fd> from
        +buffer I<buf>. The data is encrypted via I<pcbc_encrypt> (default)
        +using I<sched> for the key and I<iv> as a starting vector.  The actual
        +data send down I<fd> consists of 4 bytes (in network byte order)
        +containing the length of the following encrypted data.  The encrypted
        +data then follows, padded with random data out to a multiple of 8
        +bytes.
        +
        +DES_enc_read() is used to read I<len> bytes from file descriptor
        +I<fd> into buffer I<buf>. The data being read from I<fd> is assumed to
        +have come from DES_enc_write() and is decrypted using I<sched> for
        +the key schedule and I<iv> for the initial vector.
        +
        +B<Warning:> The data format used by DES_enc_write() and DES_enc_read()
        +has a cryptographic weakness: When asked to write more than MAXWRITE
        +bytes, DES_enc_write() will split the data into several chunks that
        +are all encrypted using the same IV.  So don't use these functions
        +unless you are sure you know what you do (in which case you might not
        +want to use them anyway).  They cannot handle non-blocking sockets.
        +DES_enc_read() uses an internal state and thus cannot be used on
        +multiple files.
        +
        +I<DES_rw_mode> is used to specify the encryption mode to use with
        +DES_enc_read() and DES_end_write().  If set to I<DES_PCBC_MODE> (the
        +default), DES_pcbc_encrypt is used.  If set to I<DES_CBC_MODE>
        +DES_cbc_encrypt is used.
        +
        +=head1 NOTES
        +
        +Single-key DES is insecure due to its short key size.  ECB mode is
        +not suitable for most applications; see L<des_modes(7)|des_modes(7)>.
        +
        +The L<evp(3)|evp(3)> library provides higher-level encryption functions.
        +
        +=head1 BUGS
        +
        +DES_3cbc_encrypt() is flawed and must not be used in applications.
        +
        +DES_cbc_encrypt() does not modify B<ivec>; use DES_ncbc_encrypt()
        +instead.
        +
        +DES_cfb_encrypt() and DES_ofb_encrypt() operates on input of 8 bits.
        +What this means is that if you set numbits to 12, and length to 2, the
        +first 12 bits will come from the 1st input byte and the low half of
        +the second input byte.  The second 12 bits will have the low 8 bits
        +taken from the 3rd input byte and the top 4 bits taken from the 4th
        +input byte.  The same holds for output.  This function has been
        +implemented this way because most people will be using a multiple of 8
        +and because once you get into pulling bytes input bytes apart things
        +get ugly!
        +
        +DES_string_to_key() is available for backward compatibility with the
        +MIT library.  New applications should use a cryptographic hash function.
        +The same applies for DES_string_to_2key().
        +
        +=head1 CONFORMING TO
        +
        +ANSI X3.106
        +
        +The B<des> library was written to be source code compatible with
        +the MIT Kerberos library.
        +
        +=head1 SEE ALSO
        +
        +crypt(3), L<des_modes(7)|des_modes(7)>, L<evp(3)|evp(3)>, L<rand(3)|rand(3)>
        +
        +=head1 HISTORY
        +
        +In OpenSSL 0.9.7, all des_ functions were renamed to DES_ to avoid
        +clashes with older versions of libdes.  Compatibility des_ functions
        +are provided for a short while, as well as crypt().
        +Declarations for these are in <openssl/des_old.h>. There is no DES_
        +variant for des_random_seed().
        +This will happen to other functions
        +as well if they are deemed redundant (des_random_seed() just calls
        +RAND_seed() and is present for backward compatibility only), buggy or
        +already scheduled for removal.
        +
        +des_cbc_cksum(), des_cbc_encrypt(), des_ecb_encrypt(),
        +des_is_weak_key(), des_key_sched(), des_pcbc_encrypt(),
        +des_quad_cksum(), des_random_key() and des_string_to_key()
        +are available in the MIT Kerberos library;
        +des_check_key_parity(), des_fixup_key_parity() and des_is_weak_key()
        +are available in newer versions of that library.
        +
        +des_set_key_checked() and des_set_key_unchecked() were added in
        +OpenSSL 0.9.5.
        +
        +des_generate_random_block(), des_init_random_number_generator(),
        +des_new_random_key(), des_set_random_generator_seed() and
        +des_set_sequence_number() and des_rand_data() are used in newer
        +versions of Kerberos but are not implemented here.
        +
        +des_random_key() generated cryptographically weak random data in
        +SSLeay and in OpenSSL prior version 0.9.5, as well as in the original
        +MIT library.
        +
        +=head1 AUTHOR
        +
        +Eric Young (eay@cryptsoft.com). Modified for the OpenSSL project
        +(http://www.openssl.org).
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/des_modes.pod b/vendor/openssl/openssl/doc/crypto/des_modes.pod
        new file mode 100644
        index 000000000..e883ca8fd
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/des_modes.pod
        @@ -0,0 +1,255 @@
        +=pod
        +
        +=for comment openssl_manual_section:7
        +
        +=head1 NAME
        +
        +des_modes - the variants of DES and other crypto algorithms of OpenSSL
        +
        +=head1 DESCRIPTION
        +
        +Several crypto algorithms for OpenSSL can be used in a number of modes.  Those
        +are used for using block ciphers in a way similar to stream ciphers, among
        +other things.
        +
        +=head1 OVERVIEW
        +
        +=head2 Electronic Codebook Mode (ECB)
        +
        +Normally, this is found as the function I<algorithm>_ecb_encrypt().
        +
        +=over 2
        +
        +=item *
        +
        +64 bits are enciphered at a time.
        +
        +=item *
        +
        +The order of the blocks can be rearranged without detection.
        +
        +=item *
        +
        +The same plaintext block always produces the same ciphertext block
        +(for the same key) making it vulnerable to a 'dictionary attack'.
        +
        +=item *
        +
        +An error will only affect one ciphertext block.
        +
        +=back
        +
        +=head2 Cipher Block Chaining Mode (CBC)
        +
        +Normally, this is found as the function I<algorithm>_cbc_encrypt().
        +Be aware that des_cbc_encrypt() is not really DES CBC (it does
        +not update the IV); use des_ncbc_encrypt() instead.
        +
        +=over 2
        +
        +=item *
        +
        +a multiple of 64 bits are enciphered at a time.
        +
        +=item *
        +
        +The CBC mode produces the same ciphertext whenever the same
        +plaintext is encrypted using the same key and starting variable.
        +
        +=item *
        +
        +The chaining operation makes the ciphertext blocks dependent on the
        +current and all preceding plaintext blocks and therefore blocks can not
        +be rearranged.
        +
        +=item *
        +
        +The use of different starting variables prevents the same plaintext
        +enciphering to the same ciphertext.
        +
        +=item *
        +
        +An error will affect the current and the following ciphertext blocks.
        +
        +=back
        +
        +=head2 Cipher Feedback Mode (CFB)
        +
        +Normally, this is found as the function I<algorithm>_cfb_encrypt().
        +
        +=over 2
        +
        +=item *
        +
        +a number of bits (j) <= 64 are enciphered at a time.
        +
        +=item *
        +
        +The CFB mode produces the same ciphertext whenever the same
        +plaintext is encrypted using the same key and starting variable.
        +
        +=item *
        +
        +The chaining operation makes the ciphertext variables dependent on the
        +current and all preceding variables and therefore j-bit variables are
        +chained together and can not be rearranged.
        +
        +=item *
        +
        +The use of different starting variables prevents the same plaintext
        +enciphering to the same ciphertext.
        +
        +=item *
        +
        +The strength of the CFB mode depends on the size of k (maximal if
        +j == k).  In my implementation this is always the case.
        +
        +=item *
        +
        +Selection of a small value for j will require more cycles through
        +the encipherment algorithm per unit of plaintext and thus cause
        +greater processing overheads.
        +
        +=item *
        +
        +Only multiples of j bits can be enciphered.
        +
        +=item *
        +
        +An error will affect the current and the following ciphertext variables.
        +
        +=back
        +
        +=head2 Output Feedback Mode (OFB)
        +
        +Normally, this is found as the function I<algorithm>_ofb_encrypt().
        +
        +=over 2
        +
        +
        +=item *
        +
        +a number of bits (j) <= 64 are enciphered at a time.
        +
        +=item *
        +
        +The OFB mode produces the same ciphertext whenever the same
        +plaintext enciphered using the same key and starting variable.  More
        +over, in the OFB mode the same key stream is produced when the same
        +key and start variable are used.  Consequently, for security reasons
        +a specific start variable should be used only once for a given key.
        +
        +=item *
        +
        +The absence of chaining makes the OFB more vulnerable to specific attacks.
        +
        +=item *
        +
        +The use of different start variables values prevents the same
        +plaintext enciphering to the same ciphertext, by producing different
        +key streams.
        +
        +=item *
        +
        +Selection of a small value for j will require more cycles through
        +the encipherment algorithm per unit of plaintext and thus cause
        +greater processing overheads.
        +
        +=item *
        +
        +Only multiples of j bits can be enciphered.
        +
        +=item *
        +
        +OFB mode of operation does not extend ciphertext errors in the
        +resultant plaintext output.  Every bit error in the ciphertext causes
        +only one bit to be in error in the deciphered plaintext.
        +
        +=item *
        +
        +OFB mode is not self-synchronizing.  If the two operation of
        +encipherment and decipherment get out of synchronism, the system needs
        +to be re-initialized.
        +
        +=item *
        +
        +Each re-initialization should use a value of the start variable
        +different from the start variable values used before with the same
        +key.  The reason for this is that an identical bit stream would be
        +produced each time from the same parameters.  This would be
        +susceptible to a 'known plaintext' attack.
        +
        +=back
        +
        +=head2 Triple ECB Mode
        +
        +Normally, this is found as the function I<algorithm>_ecb3_encrypt().
        +
        +=over 2
        +
        +=item *
        +
        +Encrypt with key1, decrypt with key2 and encrypt with key3 again.
        +
        +=item *
        +
        +As for ECB encryption but increases the key length to 168 bits.
        +There are theoretic attacks that can be used that make the effective
        +key length 112 bits, but this attack also requires 2^56 blocks of
        +memory, not very likely, even for the NSA.
        +
        +=item *
        +
        +If both keys are the same it is equivalent to encrypting once with
        +just one key.
        +
        +=item *
        +
        +If the first and last key are the same, the key length is 112 bits.
        +There are attacks that could reduce the effective key strength
        +to only slightly more than 56 bits, but these require a lot of memory.
        +
        +=item *
        +
        +If all 3 keys are the same, this is effectively the same as normal
        +ecb mode.
        +
        +=back
        +
        +=head2 Triple CBC Mode
        +
        +Normally, this is found as the function I<algorithm>_ede3_cbc_encrypt().
        +
        +=over 2
        +
        +
        +=item *
        +
        +Encrypt with key1, decrypt with key2 and then encrypt with key3.
        +
        +=item *
        +
        +As for CBC encryption but increases the key length to 168 bits with
        +the same restrictions as for triple ecb mode.
        +
        +=back
        +
        +=head1 NOTES
        +
        +This text was been written in large parts by Eric Young in his original
        +documentation for SSLeay, the predecessor of OpenSSL.  In turn, he attributed
        +it to:
        +
        +	AS 2805.5.2
        +	Australian Standard
        +	Electronic funds transfer - Requirements for interfaces,
        +	Part 5.2: Modes of operation for an n-bit block cipher algorithm
        +	Appendix A
        +
        +=head1 SEE ALSO
        +
        +L<blowfish(3)|blowfish(3)>, L<des(3)|des(3)>, L<idea(3)|idea(3)>,
        +L<rc2(3)|rc2(3)>
        +
        +=cut
        +
        diff --git a/vendor/openssl/openssl/doc/crypto/dh.pod b/vendor/openssl/openssl/doc/crypto/dh.pod
        new file mode 100644
        index 000000000..c3ccd0620
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/dh.pod
        @@ -0,0 +1,78 @@
        +=pod
        +
        +=head1 NAME
        +
        +dh - Diffie-Hellman key agreement
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dh.h>
        + #include <openssl/engine.h>
        +
        + DH *	DH_new(void);
        + void	DH_free(DH *dh);
        +
        + int	DH_size(const DH *dh);
        +
        + DH *	DH_generate_parameters(int prime_len, int generator,
        +		void (*callback)(int, int, void *), void *cb_arg);
        + int	DH_check(const DH *dh, int *codes);
        +
        + int	DH_generate_key(DH *dh);
        + int	DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
        +
        + void DH_set_default_method(const DH_METHOD *meth);
        + const DH_METHOD *DH_get_default_method(void);
        + int DH_set_method(DH *dh, const DH_METHOD *meth);
        + DH *DH_new_method(ENGINE *engine);
        + const DH_METHOD *DH_OpenSSL(void);
        +
        + int DH_get_ex_new_index(long argl, char *argp, int (*new_func)(),
        +	     int (*dup_func)(), void (*free_func)());
        + int DH_set_ex_data(DH *d, int idx, char *arg);
        + char *DH_get_ex_data(DH *d, int idx);
        +
        + DH *	d2i_DHparams(DH **a, unsigned char **pp, long length);
        + int	i2d_DHparams(const DH *a, unsigned char **pp);
        +
        + int	DHparams_print_fp(FILE *fp, const DH *x);
        + int	DHparams_print(BIO *bp, const DH *x);
        +
        +=head1 DESCRIPTION
        +
        +These functions implement the Diffie-Hellman key agreement protocol.
        +The generation of shared DH parameters is described in
        +L<DH_generate_parameters(3)|DH_generate_parameters(3)>; L<DH_generate_key(3)|DH_generate_key(3)> describes how
        +to perform a key agreement.
        +
        +The B<DH> structure consists of several BIGNUM components.
        +
        + struct
        +        {
        +        BIGNUM *p;		// prime number (shared)
        +        BIGNUM *g;		// generator of Z_p (shared)
        +        BIGNUM *priv_key;	// private DH value x
        +        BIGNUM *pub_key;	// public DH value g^x
        +        // ...
        +        };
        + DH
        +
        +Note that DH keys may use non-standard B<DH_METHOD> implementations,
        +either directly or by the use of B<ENGINE> modules. In some cases (eg. an
        +ENGINE providing support for hardware-embedded keys), these BIGNUM values
        +will not be used by the implementation or may be used for alternative data
        +storage. For this reason, applications should generally avoid using DH
        +structure elements directly and instead use API functions to query or
        +modify keys.
        +
        +=head1 SEE ALSO
        +
        +L<dhparam(1)|dhparam(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<err(3)|err(3)>,
        +L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<engine(3)|engine(3)>,
        +L<DH_set_method(3)|DH_set_method(3)>, L<DH_new(3)|DH_new(3)>,
        +L<DH_get_ex_new_index(3)|DH_get_ex_new_index(3)>,
        +L<DH_generate_parameters(3)|DH_generate_parameters(3)>,
        +L<DH_compute_key(3)|DH_compute_key(3)>, L<d2i_DHparams(3)|d2i_DHparams(3)>,
        +L<RSA_print(3)|RSA_print(3)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/dsa.pod b/vendor/openssl/openssl/doc/crypto/dsa.pod
        new file mode 100644
        index 000000000..da07d2b93
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/dsa.pod
        @@ -0,0 +1,114 @@
        +=pod
        +
        +=head1 NAME
        +
        +dsa - Digital Signature Algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/dsa.h>
        + #include <openssl/engine.h>
        +
        + DSA *	DSA_new(void);
        + void	DSA_free(DSA *dsa);
        +
        + int	DSA_size(const DSA *dsa);
        +
        + DSA *	DSA_generate_parameters(int bits, unsigned char *seed,
        +                int seed_len, int *counter_ret, unsigned long *h_ret,
        +		void (*callback)(int, int, void *), void *cb_arg);
        +
        + DH *	DSA_dup_DH(const DSA *r);
        +
        + int	DSA_generate_key(DSA *dsa);
        +
        + int	DSA_sign(int dummy, const unsigned char *dgst, int len,
        +		unsigned char *sigret, unsigned int *siglen, DSA *dsa);
        + int	DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp,
        +                BIGNUM **rp);
        + int	DSA_verify(int dummy, const unsigned char *dgst, int len,
        +		const unsigned char *sigbuf, int siglen, DSA *dsa);
        +
        + void DSA_set_default_method(const DSA_METHOD *meth);
        + const DSA_METHOD *DSA_get_default_method(void);
        + int DSA_set_method(DSA *dsa, const DSA_METHOD *meth);
        + DSA *DSA_new_method(ENGINE *engine);
        + const DSA_METHOD *DSA_OpenSSL(void);
        +
        + int DSA_get_ex_new_index(long argl, char *argp, int (*new_func)(),
        +	     int (*dup_func)(), void (*free_func)());
        + int DSA_set_ex_data(DSA *d, int idx, char *arg);
        + char *DSA_get_ex_data(DSA *d, int idx);
        +
        + DSA_SIG *DSA_SIG_new(void);
        + void	DSA_SIG_free(DSA_SIG *a);
        + int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
        + DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length);
        +
        + DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        + int	DSA_do_verify(const unsigned char *dgst, int dgst_len,
        +	     DSA_SIG *sig, DSA *dsa);
        +
        + DSA *	d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length);
        + DSA *	d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
        + DSA * 	d2i_DSAparams(DSA **a, unsigned char **pp, long length);
        + int	i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
        + int 	i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
        + int	i2d_DSAparams(const DSA *a,unsigned char **pp);
        +
        + int	DSAparams_print(BIO *bp, const DSA *x);
        + int	DSAparams_print_fp(FILE *fp, const DSA *x);
        + int	DSA_print(BIO *bp, const DSA *x, int off);
        + int	DSA_print_fp(FILE *bp, const DSA *x, int off);
        +
        +=head1 DESCRIPTION
        +
        +These functions implement the Digital Signature Algorithm (DSA).  The
        +generation of shared DSA parameters is described in
        +L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>;
        +L<DSA_generate_key(3)|DSA_generate_key(3)> describes how to
        +generate a signature key. Signature generation and verification are
        +described in L<DSA_sign(3)|DSA_sign(3)>.
        +
        +The B<DSA> structure consists of several BIGNUM components.
        +
        + struct
        +        {
        +        BIGNUM *p;		// prime number (public)
        +        BIGNUM *q;		// 160-bit subprime, q | p-1 (public)
        +        BIGNUM *g;		// generator of subgroup (public)
        +        BIGNUM *priv_key;	// private key x
        +        BIGNUM *pub_key;	// public key y = g^x
        +        // ...
        +        }
        + DSA;
        +
        +In public keys, B<priv_key> is NULL.
        +
        +Note that DSA keys may use non-standard B<DSA_METHOD> implementations,
        +either directly or by the use of B<ENGINE> modules. In some cases (eg. an
        +ENGINE providing support for hardware-embedded keys), these BIGNUM values
        +will not be used by the implementation or may be used for alternative data
        +storage. For this reason, applications should generally avoid using DSA
        +structure elements directly and instead use API functions to query or
        +modify keys.
        +
        +=head1 CONFORMING TO
        +
        +US Federal Information Processing Standard FIPS 186 (Digital Signature
        +Standard, DSS), ANSI X9.30
        +
        +=head1 SEE ALSO
        +
        +L<bn(3)|bn(3)>, L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>,
        +L<rsa(3)|rsa(3)>, L<sha(3)|sha(3)>, L<engine(3)|engine(3)>,
        +L<DSA_new(3)|DSA_new(3)>,
        +L<DSA_size(3)|DSA_size(3)>,
        +L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>,
        +L<DSA_dup_DH(3)|DSA_dup_DH(3)>,
        +L<DSA_generate_key(3)|DSA_generate_key(3)>,
        +L<DSA_sign(3)|DSA_sign(3)>, L<DSA_set_method(3)|DSA_set_method(3)>,
        +L<DSA_get_ex_new_index(3)|DSA_get_ex_new_index(3)>,
        +L<RSA_print(3)|RSA_print(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ecdsa.pod b/vendor/openssl/openssl/doc/crypto/ecdsa.pod
        new file mode 100644
        index 000000000..20edff97f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ecdsa.pod
        @@ -0,0 +1,210 @@
        +=pod
        +
        +=head1 NAME
        +
        +ecdsa - Elliptic Curve Digital Signature Algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ecdsa.h>
        +
        + ECDSA_SIG*	ECDSA_SIG_new(void);
        + void		ECDSA_SIG_free(ECDSA_SIG *sig);
        + int		i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
        + ECDSA_SIG*	d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, 
        +		long len);
        +
        + ECDSA_SIG*	ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
        +			EC_KEY *eckey);
        + ECDSA_SIG*	ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
        +			const BIGNUM *kinv, const BIGNUM *rp,
        +			EC_KEY *eckey);
        + int		ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
        +			const ECDSA_SIG *sig, EC_KEY* eckey);
        + int		ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx,
        +			BIGNUM **kinv, BIGNUM **rp);
        + int		ECDSA_sign(int type, const unsigned char *dgst,
        +			int dgstlen, unsigned char *sig,
        +			unsigned int *siglen, EC_KEY *eckey);
        + int		ECDSA_sign_ex(int type, const unsigned char *dgst,
        +			int dgstlen, unsigned char *sig,
        +			unsigned int *siglen, const BIGNUM *kinv, 
        +			const BIGNUM *rp, EC_KEY *eckey);
        + int		ECDSA_verify(int type, const unsigned char *dgst,
        +			int dgstlen, const unsigned char *sig,
        +			int siglen, EC_KEY *eckey);
        + int		ECDSA_size(const EC_KEY *eckey);
        +
        + const ECDSA_METHOD*	ECDSA_OpenSSL(void);
        + void		ECDSA_set_default_method(const ECDSA_METHOD *meth);
        + const ECDSA_METHOD*	ECDSA_get_default_method(void);
        + int		ECDSA_set_method(EC_KEY *eckey,const ECDSA_METHOD *meth);
        +
        + int		ECDSA_get_ex_new_index(long argl, void *argp,
        +			CRYPTO_EX_new *new_func,
        +			CRYPTO_EX_dup *dup_func,
        +			CRYPTO_EX_free *free_func);
        + int		ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
        + void*		ECDSA_get_ex_data(EC_KEY *d, int idx);
        +
        +=head1 DESCRIPTION
        +
        +The B<ECDSA_SIG> structure consists of two BIGNUMs for the
        +r and s value of a ECDSA signature (see X9.62 or FIPS 186-2).
        +
        + struct
        +	{
        +	BIGNUM *r;
        +	BIGNUM *s;
        + } ECDSA_SIG;
        +
        +ECDSA_SIG_new() allocates a new B<ECDSA_SIG> structure (note: this
        +function also allocates the BIGNUMs) and initialize it.
        +
        +ECDSA_SIG_free() frees the B<ECDSA_SIG> structure B<sig>.
        +
        +i2d_ECDSA_SIG() creates the DER encoding of the ECDSA signature
        +B<sig> and writes the encoded signature to B<*pp> (note: if B<pp>
        +is NULL B<i2d_ECDSA_SIG> returns the expected length in bytes of 
        +the DER encoded signature). B<i2d_ECDSA_SIG> returns the length
        +of the DER encoded signature (or 0 on error).
        +
        +d2i_ECDSA_SIG() decodes a DER encoded ECDSA signature and returns
        +the decoded signature in a newly allocated B<ECDSA_SIG> structure.
        +B<*sig> points to the buffer containing the DER encoded signature
        +of size B<len>.
        +
        +ECDSA_size() returns the maximum length of a DER encoded
        +ECDSA signature created with the private EC key B<eckey>.
        +
        +ECDSA_sign_setup() may be used to precompute parts of the
        +signing operation. B<eckey> is the private EC key and B<ctx>
        +is a pointer to B<BN_CTX> structure (or NULL). The precomputed
        +values or returned in B<kinv> and B<rp> and can be used in a
        +later call to B<ECDSA_sign_ex> or B<ECDSA_do_sign_ex>.
        +
        +ECDSA_sign() is wrapper function for ECDSA_sign_ex with B<kinv>
        +and B<rp> set to NULL.
        +
        +ECDSA_sign_ex() computes a digital signature of the B<dgstlen> bytes
        +hash value B<dgst> using the private EC key B<eckey> and the optional
        +pre-computed values B<kinv> and B<rp>. The DER encoded signatures is
        +stored in B<sig> and it's length is returned in B<sig_len>. Note: B<sig>
        +must point to B<ECDSA_size> bytes of memory. The parameter B<type>
        +is ignored.
        +
        +ECDSA_verify() verifies that the signature in B<sig> of size
        +B<siglen> is a valid ECDSA signature of the hash value
        +value B<dgst> of size B<dgstlen> using the public key B<eckey>.
        +The parameter B<type> is ignored.
        +
        +ECDSA_do_sign() is wrapper function for ECDSA_do_sign_ex with B<kinv>
        +and B<rp> set to NULL.
        +
        +ECDSA_do_sign_ex() computes a digital signature of the B<dgst_len>
        +bytes hash value B<dgst> using the private key B<eckey> and the
        +optional pre-computed values B<kinv> and B<rp>. The signature is
        +returned in a newly allocated B<ECDSA_SIG> structure (or NULL on error).
        +
        +ECDSA_do_verify() verifies that the signature B<sig> is a valid
        +ECDSA signature of the hash value B<dgst> of size B<dgst_len>
        +using the public key B<eckey>.
        +
        +=head1 RETURN VALUES
        +
        +ECDSA_size() returns the maximum length signature or 0 on error.
        +
        +ECDSA_sign_setup() and ECDSA_sign() return 1 if successful or 0
        +on error.
        +
        +ECDSA_verify() and ECDSA_do_verify() return 1 for a valid
        +signature, 0 for an invalid signature and -1 on error.
        +The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
        +
        +=head1 EXAMPLES
        +
        +Creating a ECDSA signature of given SHA-1 hash value using the
        +named curve secp192k1.
        +
        +First step: create a EC_KEY object (note: this part is B<not> ECDSA
        +specific)
        +
        + int        ret;
        + ECDSA_SIG *sig;
        + EC_KEY    *eckey = EC_KEY_new();
        + if (eckey == NULL)
        +	{
        +	/* error */
        +	}
        + key->group = EC_GROUP_new_by_nid(NID_secp192k1);
        + if (key->group == NULL)
        +	{
        +	/* error */
        +	}
        + if (!EC_KEY_generate_key(eckey))
        +	{
        +	/* error */
        +	}
        +
        +Second step: compute the ECDSA signature of a SHA-1 hash value 
        +using B<ECDSA_do_sign> 
        +
        + sig = ECDSA_do_sign(digest, 20, eckey);
        + if (sig == NULL)
        +	{
        +	/* error */
        +	}
        +
        +or using B<ECDSA_sign>
        +
        + unsigned char *buffer, *pp;
        + int            buf_len;
        + buf_len = ECDSA_size(eckey);
        + buffer  = OPENSSL_malloc(buf_len);
        + pp = buffer;
        + if (!ECDSA_sign(0, dgst, dgstlen, pp, &buf_len, eckey);
        +	{
        +	/* error */
        +	}
        +
        +Third step: verify the created ECDSA signature using B<ECDSA_do_verify>
        +
        + ret = ECDSA_do_verify(digest, 20, sig, eckey);
        +
        +or using B<ECDSA_verify>
        +
        + ret = ECDSA_verify(0, digest, 20, buffer, buf_len, eckey);
        +
        +and finally evaluate the return value:
        +
        + if (ret == -1)
        +	{
        +	/* error */
        +	}
        + else if (ret == 0)
        +	{
        +	/* incorrect signature */
        +	}
        + else	/* ret == 1 */
        +	{
        +	/* signature ok */
        +	}
        +
        +=head1 CONFORMING TO
        +
        +ANSI X9.62, US Federal Information Processing Standard FIPS 186-2
        +(Digital Signature Standard, DSS)
        +
        +=head1 SEE ALSO
        +
        +L<dsa(3)|dsa(3)>, L<rsa(3)|rsa(3)>
        +
        +=head1 HISTORY
        +
        +The ecdsa implementation was first introduced in OpenSSL 0.9.8
        +
        +=head1 AUTHOR
        +
        +Nils Larsch for the OpenSSL project (http://www.openssl.org).
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/engine.pod b/vendor/openssl/openssl/doc/crypto/engine.pod
        new file mode 100644
        index 000000000..f5ab1c3e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/engine.pod
        @@ -0,0 +1,599 @@
        +=pod
        +
        +=head1 NAME
        +
        +engine - ENGINE cryptographic module support
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/engine.h>
        +
        + ENGINE *ENGINE_get_first(void);
        + ENGINE *ENGINE_get_last(void);
        + ENGINE *ENGINE_get_next(ENGINE *e);
        + ENGINE *ENGINE_get_prev(ENGINE *e);
        +
        + int ENGINE_add(ENGINE *e);
        + int ENGINE_remove(ENGINE *e);
        +
        + ENGINE *ENGINE_by_id(const char *id);
        +
        + int ENGINE_init(ENGINE *e);
        + int ENGINE_finish(ENGINE *e);
        +
        + void ENGINE_load_openssl(void);
        + void ENGINE_load_dynamic(void);
        + #ifndef OPENSSL_NO_STATIC_ENGINE
        + void ENGINE_load_4758cca(void);
        + void ENGINE_load_aep(void);
        + void ENGINE_load_atalla(void);
        + void ENGINE_load_chil(void);
        + void ENGINE_load_cswift(void);
        + void ENGINE_load_gmp(void);
        + void ENGINE_load_nuron(void);
        + void ENGINE_load_sureware(void);
        + void ENGINE_load_ubsec(void);
        + #endif
        + void ENGINE_load_cryptodev(void);
        + void ENGINE_load_builtin_engines(void);
        +
        + void ENGINE_cleanup(void);
        +
        + ENGINE *ENGINE_get_default_RSA(void);
        + ENGINE *ENGINE_get_default_DSA(void);
        + ENGINE *ENGINE_get_default_ECDH(void);
        + ENGINE *ENGINE_get_default_ECDSA(void);
        + ENGINE *ENGINE_get_default_DH(void);
        + ENGINE *ENGINE_get_default_RAND(void);
        + ENGINE *ENGINE_get_cipher_engine(int nid);
        + ENGINE *ENGINE_get_digest_engine(int nid);
        +
        + int ENGINE_set_default_RSA(ENGINE *e);
        + int ENGINE_set_default_DSA(ENGINE *e);
        + int ENGINE_set_default_ECDH(ENGINE *e);
        + int ENGINE_set_default_ECDSA(ENGINE *e);
        + int ENGINE_set_default_DH(ENGINE *e);
        + int ENGINE_set_default_RAND(ENGINE *e);
        + int ENGINE_set_default_ciphers(ENGINE *e);
        + int ENGINE_set_default_digests(ENGINE *e);
        + int ENGINE_set_default_string(ENGINE *e, const char *list);
        +
        + int ENGINE_set_default(ENGINE *e, unsigned int flags);
        +
        + unsigned int ENGINE_get_table_flags(void);
        + void ENGINE_set_table_flags(unsigned int flags);
        +
        + int ENGINE_register_RSA(ENGINE *e);
        + void ENGINE_unregister_RSA(ENGINE *e);
        + void ENGINE_register_all_RSA(void);
        + int ENGINE_register_DSA(ENGINE *e);
        + void ENGINE_unregister_DSA(ENGINE *e);
        + void ENGINE_register_all_DSA(void);
        + int ENGINE_register_ECDH(ENGINE *e);
        + void ENGINE_unregister_ECDH(ENGINE *e);
        + void ENGINE_register_all_ECDH(void);
        + int ENGINE_register_ECDSA(ENGINE *e);
        + void ENGINE_unregister_ECDSA(ENGINE *e);
        + void ENGINE_register_all_ECDSA(void);
        + int ENGINE_register_DH(ENGINE *e);
        + void ENGINE_unregister_DH(ENGINE *e);
        + void ENGINE_register_all_DH(void);
        + int ENGINE_register_RAND(ENGINE *e);
        + void ENGINE_unregister_RAND(ENGINE *e);
        + void ENGINE_register_all_RAND(void);
        + int ENGINE_register_STORE(ENGINE *e);
        + void ENGINE_unregister_STORE(ENGINE *e);
        + void ENGINE_register_all_STORE(void);
        + int ENGINE_register_ciphers(ENGINE *e);
        + void ENGINE_unregister_ciphers(ENGINE *e);
        + void ENGINE_register_all_ciphers(void);
        + int ENGINE_register_digests(ENGINE *e);
        + void ENGINE_unregister_digests(ENGINE *e);
        + void ENGINE_register_all_digests(void);
        + int ENGINE_register_complete(ENGINE *e);
        + int ENGINE_register_all_complete(void);
        +
        + int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        + int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
        + int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
        +         long i, void *p, void (*f)(void), int cmd_optional);
        + int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
        +         int cmd_optional);
        +
        + int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
        + void *ENGINE_get_ex_data(const ENGINE *e, int idx);
        +
        + int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +
        + ENGINE *ENGINE_new(void);
        + int ENGINE_free(ENGINE *e);
        + int ENGINE_up_ref(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, const RSA_METHOD *rsa_meth);
        + int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
        + int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *dh_meth);
        + int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *dh_meth);
        + int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
        + int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
        + int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *rand_meth);
        + int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
        + 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);
        + int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
        + int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
        + int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
        + int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
        + int ENGINE_set_flags(ENGINE *e, int flags);
        + int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
        +
        + const char *ENGINE_get_id(const ENGINE *e);
        + const char *ENGINE_get_name(const ENGINE *e);
        + const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
        + const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
        + const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
        + const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
        + const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
        + const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
        + const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
        + ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
        + ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
        + ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
        + ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
        + ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
        + ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
        + ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
        + ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
        + const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
        + const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
        + int ENGINE_get_flags(const ENGINE *e);
        + const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
        +
        + EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
        +     UI_METHOD *ui_method, void *callback_data);
        + EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
        +     UI_METHOD *ui_method, void *callback_data);
        +
        + void ENGINE_add_conf_module(void);
        +
        +=head1 DESCRIPTION
        +
        +These functions create, manipulate, and use cryptographic modules in the
        +form of B<ENGINE> objects. These objects act as containers for
        +implementations of cryptographic algorithms, and support a
        +reference-counted mechanism to allow them to be dynamically loaded in and
        +out of the running application.
        +
        +The cryptographic functionality that can be provided by an B<ENGINE>
        +implementation includes the following abstractions;
        +
        + RSA_METHOD - for providing alternative RSA implementations
        + DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD,
        +       STORE_METHOD - similarly for other OpenSSL APIs
        + EVP_CIPHER - potentially multiple cipher algorithms (indexed by 'nid')
        + EVP_DIGEST - potentially multiple hash algorithms (indexed by 'nid')
        + key-loading - loading public and/or private EVP_PKEY keys
        +
        +=head2 Reference counting and handles
        +
        +Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be
        +treated as handles - ie. not only as pointers, but also as references to
        +the underlying ENGINE object. Ie. one should obtain a new reference when
        +making copies of an ENGINE pointer if the copies will be used (and
        +released) independently.
        +
        +ENGINE objects have two levels of reference-counting to match the way in
        +which the objects are used. At the most basic level, each ENGINE pointer is
        +inherently a B<structural> reference - a structural reference is required
        +to use the pointer value at all, as this kind of reference is a guarantee
        +that the structure can not be deallocated until the reference is released.
        +
        +However, a structural reference provides no guarantee that the ENGINE is
        +initiliased and able to use any of its cryptographic
        +implementations. Indeed it's quite possible that most ENGINEs will not
        +initialise at all in typical environments, as ENGINEs are typically used to
        +support specialised hardware. To use an ENGINE's functionality, you need a
        +B<functional> reference. This kind of reference can be considered a
        +specialised form of structural reference, because each functional reference
        +implicitly contains a structural reference as well - however to avoid
        +difficult-to-find programming bugs, it is recommended to treat the two
        +kinds of reference independently. If you have a functional reference to an
        +ENGINE, you have a guarantee that the ENGINE has been initialised ready to
        +perform cryptographic operations and will remain uninitialised
        +until after you have released your reference.
        +
        +I<Structural references>
        +
        +This basic type of reference is used for instantiating new ENGINEs,
        +iterating across OpenSSL's internal linked-list of loaded
        +ENGINEs, reading information about an ENGINE, etc. Essentially a structural
        +reference is sufficient if you only need to query or manipulate the data of
        +an ENGINE implementation rather than use its functionality.
        +
        +The ENGINE_new() function returns a structural reference to a new (empty)
        +ENGINE object. There are other ENGINE API functions that return structural
        +references such as; ENGINE_by_id(), ENGINE_get_first(), ENGINE_get_last(),
        +ENGINE_get_next(), ENGINE_get_prev(). All structural references should be
        +released by a corresponding to call to the ENGINE_free() function - the
        +ENGINE object itself will only actually be cleaned up and deallocated when
        +the last structural reference is released.
        +
        +It should also be noted that many ENGINE API function calls that accept a
        +structural reference will internally obtain another reference - typically
        +this happens whenever the supplied ENGINE will be needed by OpenSSL after
        +the function has returned. Eg. the function to add a new ENGINE to
        +OpenSSL's internal list is ENGINE_add() - if this function returns success,
        +then OpenSSL will have stored a new structural reference internally so the
        +caller is still responsible for freeing their own reference with
        +ENGINE_free() when they are finished with it. In a similar way, some
        +functions will automatically release the structural reference passed to it
        +if part of the function's job is to do so. Eg. the ENGINE_get_next() and
        +ENGINE_get_prev() functions are used for iterating across the internal
        +ENGINE list - they will return a new structural reference to the next (or
        +previous) ENGINE in the list or NULL if at the end (or beginning) of the
        +list, but in either case the structural reference passed to the function is
        +released on behalf of the caller.
        +
        +To clarify a particular function's handling of references, one should
        +always consult that function's documentation "man" page, or failing that
        +the openssl/engine.h header file includes some hints.
        +
        +I<Functional references>
        +
        +As mentioned, functional references exist when the cryptographic
        +functionality of an ENGINE is required to be available. A functional
        +reference can be obtained in one of two ways; from an existing structural
        +reference to the required ENGINE, or by asking OpenSSL for the default
        +operational ENGINE for a given cryptographic purpose.
        +
        +To obtain a functional reference from an existing structural reference,
        +call the ENGINE_init() function. This returns zero if the ENGINE was not
        +already operational and couldn't be successfully initialised (eg. lack of
        +system drivers, no special hardware attached, etc), otherwise it will
        +return non-zero to indicate that the ENGINE is now operational and will
        +have allocated a new B<functional> reference to the ENGINE. All functional
        +references are released by calling ENGINE_finish() (which removes the
        +implicit structural reference as well).
        +
        +The second way to get a functional reference is by asking OpenSSL for a
        +default implementation for a given task, eg. by ENGINE_get_default_RSA(),
        +ENGINE_get_default_cipher_engine(), etc. These are discussed in the next
        +section, though they are not usually required by application programmers as
        +they are used automatically when creating and using the relevant
        +algorithm-specific types in OpenSSL, such as RSA, DSA, EVP_CIPHER_CTX, etc.
        +
        +=head2 Default implementations
        +
        +For each supported abstraction, the ENGINE code maintains an internal table
        +of state to control which implementations are available for a given
        +abstraction and which should be used by default. These implementations are
        +registered in the tables and indexed by an 'nid' value, because
        +abstractions like EVP_CIPHER and EVP_DIGEST support many distinct
        +algorithms and modes, and ENGINEs can support arbitrarily many of them.
        +In the case of other abstractions like RSA, DSA, etc, there is only one
        +"algorithm" so all implementations implicitly register using the same 'nid'
        +index.
        +
        +When a default ENGINE is requested for a given abstraction/algorithm/mode, (eg.
        +when calling RSA_new_method(NULL)), a "get_default" call will be made to the
        +ENGINE subsystem to process the corresponding state table and return a
        +functional reference to an initialised ENGINE whose implementation should be
        +used. If no ENGINE should (or can) be used, it will return NULL and the caller
        +will operate with a NULL ENGINE handle - this usually equates to using the
        +conventional software implementation. In the latter case, OpenSSL will from
        +then on behave the way it used to before the ENGINE API existed.
        +
        +Each state table has a flag to note whether it has processed this
        +"get_default" query since the table was last modified, because to process
        +this question it must iterate across all the registered ENGINEs in the
        +table trying to initialise each of them in turn, in case one of them is
        +operational. If it returns a functional reference to an ENGINE, it will
        +also cache another reference to speed up processing future queries (without
        +needing to iterate across the table). Likewise, it will cache a NULL
        +response if no ENGINE was available so that future queries won't repeat the
        +same iteration unless the state table changes. This behaviour can also be
        +changed; if the ENGINE_TABLE_FLAG_NOINIT flag is set (using
        +ENGINE_set_table_flags()), no attempted initialisations will take place,
        +instead the only way for the state table to return a non-NULL ENGINE to the
        +"get_default" query will be if one is expressly set in the table. Eg.
        +ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except
        +that it also sets the state table's cached response for the "get_default"
        +query. In the case of abstractions like EVP_CIPHER, where implementations are
        +indexed by 'nid', these flags and cached-responses are distinct for each 'nid'
        +value.
        +
        +=head2 Application requirements
        +
        +This section will explain the basic things an application programmer should
        +support to make the most useful elements of the ENGINE functionality
        +available to the user. The first thing to consider is whether the
        +programmer wishes to make alternative ENGINE modules available to the
        +application and user. OpenSSL maintains an internal linked list of
        +"visible" ENGINEs from which it has to operate - at start-up, this list is
        +empty and in fact if an application does not call any ENGINE API calls and
        +it uses static linking against openssl, then the resulting application
        +binary will not contain any alternative ENGINE code at all. So the first
        +consideration is whether any/all available ENGINE implementations should be
        +made visible to OpenSSL - this is controlled by calling the various "load"
        +functions, eg.
        +
        + /* Make the "dynamic" ENGINE available */
        + void ENGINE_load_dynamic(void);
        + /* Make the CryptoSwift hardware acceleration support available */
        + void ENGINE_load_cswift(void);
        + /* Make support for nCipher's "CHIL" hardware available */
        + void ENGINE_load_chil(void);
        + ...
        + /* Make ALL ENGINE implementations bundled with OpenSSL available */
        + void ENGINE_load_builtin_engines(void);
        +
        +Having called any of these functions, ENGINE objects would have been
        +dynamically allocated and populated with these implementations and linked
        +into OpenSSL's internal linked list. At this point it is important to
        +mention an important API function;
        +
        + void ENGINE_cleanup(void);
        +
        +If no ENGINE API functions are called at all in an application, then there
        +are no inherent memory leaks to worry about from the ENGINE functionality,
        +however if any ENGINEs are loaded, even if they are never registered or
        +used, it is necessary to use the ENGINE_cleanup() function to
        +correspondingly cleanup before program exit, if the caller wishes to avoid
        +memory leaks. This mechanism uses an internal callback registration table
        +so that any ENGINE API functionality that knows it requires cleanup can
        +register its cleanup details to be called during ENGINE_cleanup(). This
        +approach allows ENGINE_cleanup() to clean up after any ENGINE functionality
        +at all that your program uses, yet doesn't automatically create linker
        +dependencies to all possible ENGINE functionality - only the cleanup
        +callbacks required by the functionality you do use will be required by the
        +linker.
        +
        +The fact that ENGINEs are made visible to OpenSSL (and thus are linked into
        +the program and loaded into memory at run-time) does not mean they are
        +"registered" or called into use by OpenSSL automatically - that behaviour
        +is something for the application to control. Some applications
        +will want to allow the user to specify exactly which ENGINE they want used
        +if any is to be used at all. Others may prefer to load all support and have
        +OpenSSL automatically use at run-time any ENGINE that is able to
        +successfully initialise - ie. to assume that this corresponds to
        +acceleration hardware attached to the machine or some such thing. There are
        +probably numerous other ways in which applications may prefer to handle
        +things, so we will simply illustrate the consequences as they apply to a
        +couple of simple cases and leave developers to consider these and the
        +source code to openssl's builtin utilities as guides.
        +
        +I<Using a specific ENGINE implementation>
        +
        +Here we'll assume an application has been configured by its user or admin
        +to want to use the "ACME" ENGINE if it is available in the version of
        +OpenSSL the application was compiled with. If it is available, it should be
        +used by default for all RSA, DSA, and symmetric cipher operation, otherwise
        +OpenSSL should use its builtin software as per usual. The following code
        +illustrates how to approach this;
        +
        + ENGINE *e;
        + const char *engine_id = "ACME";
        + ENGINE_load_builtin_engines();
        + e = ENGINE_by_id(engine_id);
        + if(!e)
        +     /* the engine isn't available */
        +     return;
        + if(!ENGINE_init(e)) {
        +     /* the engine couldn't initialise, release 'e' */
        +     ENGINE_free(e);
        +     return;
        + }
        + if(!ENGINE_set_default_RSA(e))
        +     /* This should only happen when 'e' can't initialise, but the previous
        +      * statement suggests it did. */
        +     abort();
        + ENGINE_set_default_DSA(e);
        + ENGINE_set_default_ciphers(e);
        + /* Release the functional reference from ENGINE_init() */
        + ENGINE_finish(e);
        + /* Release the structural reference from ENGINE_by_id() */
        + ENGINE_free(e);
        +
        +I<Automatically using builtin ENGINE implementations>
        +
        +Here we'll assume we want to load and register all ENGINE implementations
        +bundled with OpenSSL, such that for any cryptographic algorithm required by
        +OpenSSL - if there is an ENGINE that implements it and can be initialise,
        +it should be used. The following code illustrates how this can work;
        +
        + /* Load all bundled ENGINEs into memory and make them visible */
        + ENGINE_load_builtin_engines();
        + /* Register all of them for every algorithm they collectively implement */
        + ENGINE_register_all_complete();
        +
        +That's all that's required. Eg. the next time OpenSSL tries to set up an
        +RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to
        +ENGINE_init() and if any of those succeed, that ENGINE will be set as the
        +default for RSA use from then on.
        +
        +=head2 Advanced configuration support
        +
        +There is a mechanism supported by the ENGINE framework that allows each
        +ENGINE implementation to define an arbitrary set of configuration
        +"commands" and expose them to OpenSSL and any applications based on
        +OpenSSL. This mechanism is entirely based on the use of name-value pairs
        +and assumes ASCII input (no unicode or UTF for now!), so it is ideal if
        +applications want to provide a transparent way for users to provide
        +arbitrary configuration "directives" directly to such ENGINEs. It is also
        +possible for the application to dynamically interrogate the loaded ENGINE
        +implementations for the names, descriptions, and input flags of their
        +available "control commands", providing a more flexible configuration
        +scheme. However, if the user is expected to know which ENGINE device he/she
        +is using (in the case of specialised hardware, this goes without saying)
        +then applications may not need to concern themselves with discovering the
        +supported control commands and simply prefer to pass settings into ENGINEs
        +exactly as they are provided by the user.
        +
        +Before illustrating how control commands work, it is worth mentioning what
        +they are typically used for. Broadly speaking there are two uses for
        +control commands; the first is to provide the necessary details to the
        +implementation (which may know nothing at all specific to the host system)
        +so that it can be initialised for use. This could include the path to any
        +driver or config files it needs to load, required network addresses,
        +smart-card identifiers, passwords to initialise protected devices,
        +logging information, etc etc. This class of commands typically needs to be
        +passed to an ENGINE B<before> attempting to initialise it, ie. before
        +calling ENGINE_init(). The other class of commands consist of settings or
        +operations that tweak certain behaviour or cause certain operations to take
        +place, and these commands may work either before or after ENGINE_init(), or
        +in some cases both. ENGINE implementations should provide indications of
        +this in the descriptions attached to builtin control commands and/or in
        +external product documentation.
        +
        +I<Issuing control commands to an ENGINE>
        +
        +Let's illustrate by example; a function for which the caller supplies the
        +name of the ENGINE it wishes to use, a table of string-pairs for use before
        +initialisation, and another table for use after initialisation. Note that
        +the string-pairs used for control commands consist of a command "name"
        +followed by the command "parameter" - the parameter could be NULL in some
        +cases but the name can not. This function should initialise the ENGINE
        +(issuing the "pre" commands beforehand and the "post" commands afterwards)
        +and set it as the default for everything except RAND and then return a
        +boolean success or failure.
        +
        + int generic_load_engine_fn(const char *engine_id,
        +                            const char **pre_cmds, int pre_num,
        +                            const char **post_cmds, int post_num)
        + {
        +     ENGINE *e = ENGINE_by_id(engine_id);
        +     if(!e) return 0;
        +     while(pre_num--) {
        +         if(!ENGINE_ctrl_cmd_string(e, pre_cmds[0], pre_cmds[1], 0)) {
        +             fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id,
        +                 pre_cmds[0], pre_cmds[1] ? pre_cmds[1] : "(NULL)");
        +             ENGINE_free(e);
        +             return 0;
        +         }
        +	 pre_cmds += 2;
        +     }
        +     if(!ENGINE_init(e)) {
        +         fprintf(stderr, "Failed initialisation\n");
        +         ENGINE_free(e);
        +         return 0;
        +     }
        +     /* ENGINE_init() returned a functional reference, so free the structural
        +      * reference from ENGINE_by_id(). */
        +     ENGINE_free(e);
        +     while(post_num--) {
        +         if(!ENGINE_ctrl_cmd_string(e, post_cmds[0], post_cmds[1], 0)) {
        +             fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id,
        +                 post_cmds[0], post_cmds[1] ? post_cmds[1] : "(NULL)");
        +             ENGINE_finish(e);
        +             return 0;
        +         }
        +	 post_cmds += 2;
        +     }
        +     ENGINE_set_default(e, ENGINE_METHOD_ALL & ~ENGINE_METHOD_RAND);
        +     /* Success */
        +     return 1;
        + }
        +
        +Note that ENGINE_ctrl_cmd_string() accepts a boolean argument that can
        +relax the semantics of the function - if set non-zero it will only return
        +failure if the ENGINE supported the given command name but failed while
        +executing it, if the ENGINE doesn't support the command name it will simply
        +return success without doing anything. In this case we assume the user is
        +only supplying commands specific to the given ENGINE so we set this to
        +FALSE.
        +
        +I<Discovering supported control commands>
        +
        +It is possible to discover at run-time the names, numerical-ids, descriptions
        +and input parameters of the control commands supported by an ENGINE using a
        +structural reference. Note that some control commands are defined by OpenSSL
        +itself and it will intercept and handle these control commands on behalf of the
        +ENGINE, ie. the ENGINE's ctrl() handler is not used for the control command.
        +openssl/engine.h defines an index, ENGINE_CMD_BASE, that all control commands
        +implemented by ENGINEs should be numbered from. Any command value lower than
        +this symbol is considered a "generic" command is handled directly by the
        +OpenSSL core routines.
        +
        +It is using these "core" control commands that one can discover the the control
        +commands implemented by a given ENGINE, specifically the commands;
        +
        + #define ENGINE_HAS_CTRL_FUNCTION		10
        + #define ENGINE_CTRL_GET_FIRST_CMD_TYPE		11
        + #define ENGINE_CTRL_GET_NEXT_CMD_TYPE		12
        + #define ENGINE_CTRL_GET_CMD_FROM_NAME		13
        + #define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD	14
        + #define ENGINE_CTRL_GET_NAME_FROM_CMD		15
        + #define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD	16
        + #define ENGINE_CTRL_GET_DESC_FROM_CMD		17
        + #define ENGINE_CTRL_GET_CMD_FLAGS		18
        +
        +Whilst these commands are automatically processed by the OpenSSL framework code,
        +they use various properties exposed by each ENGINE to process these
        +queries. An ENGINE has 3 properties it exposes that can affect how this behaves;
        +it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in
        +the ENGINE's flags, and it can expose an array of control command descriptions.
        +If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will
        +simply pass all these "core" control commands directly to the ENGINE's ctrl()
        +handler (and thus, it must have supplied one), so it is up to the ENGINE to
        +reply to these "discovery" commands itself. If that flag is not set, then the
        +OpenSSL framework code will work with the following rules;
        +
        + if no ctrl() handler supplied;
        +     ENGINE_HAS_CTRL_FUNCTION returns FALSE (zero),
        +     all other commands fail.
        + if a ctrl() handler was supplied but no array of control commands;
        +     ENGINE_HAS_CTRL_FUNCTION returns TRUE,
        +     all other commands fail.
        + if a ctrl() handler and array of control commands was supplied;
        +     ENGINE_HAS_CTRL_FUNCTION returns TRUE,
        +     all other commands proceed processing ...
        +
        +If the ENGINE's array of control commands is empty then all other commands will
        +fail, otherwise; ENGINE_CTRL_GET_FIRST_CMD_TYPE returns the identifier of
        +the first command supported by the ENGINE, ENGINE_GET_NEXT_CMD_TYPE takes the
        +identifier of a command supported by the ENGINE and returns the next command
        +identifier or fails if there are no more, ENGINE_CMD_FROM_NAME takes a string
        +name for a command and returns the corresponding identifier or fails if no such
        +command name exists, and the remaining commands take a command identifier and
        +return properties of the corresponding commands. All except
        +ENGINE_CTRL_GET_FLAGS return the string length of a command name or description,
        +or populate a supplied character buffer with a copy of the command name or
        +description. ENGINE_CTRL_GET_FLAGS returns a bitwise-OR'd mask of the following
        +possible values;
        +
        + #define ENGINE_CMD_FLAG_NUMERIC		(unsigned int)0x0001
        + #define ENGINE_CMD_FLAG_STRING			(unsigned int)0x0002
        + #define ENGINE_CMD_FLAG_NO_INPUT		(unsigned int)0x0004
        + #define ENGINE_CMD_FLAG_INTERNAL		(unsigned int)0x0008
        +
        +If the ENGINE_CMD_FLAG_INTERNAL flag is set, then any other flags are purely
        +informational to the caller - this flag will prevent the command being usable
        +for any higher-level ENGINE functions such as ENGINE_ctrl_cmd_string().
        +"INTERNAL" commands are not intended to be exposed to text-based configuration
        +by applications, administrations, users, etc. These can support arbitrary
        +operations via ENGINE_ctrl(), including passing to and/or from the control
        +commands data of any arbitrary type. These commands are supported in the
        +discovery mechanisms simply to allow applications determinie if an ENGINE
        +supports certain specific commands it might want to use (eg. application "foo"
        +might query various ENGINEs to see if they implement "FOO_GET_VENDOR_LOGO_GIF" -
        +and ENGINE could therefore decide whether or not to support this "foo"-specific
        +extension).
        +
        +=head2 Future developments
        +
        +The ENGINE API and internal architecture is currently being reviewed. Slated for
        +possible release in 0.9.8 is support for transparent loading of "dynamic"
        +ENGINEs (built as self-contained shared-libraries). This would allow ENGINE
        +implementations to be provided independently of OpenSSL libraries and/or
        +OpenSSL-based applications, and would also remove any requirement for
        +applications to explicitly use the "dynamic" ENGINE to bind to shared-library
        +implementations.
        +
        +=head1 SEE ALSO
        +
        +L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/err.pod b/vendor/openssl/openssl/doc/crypto/err.pod
        new file mode 100644
        index 000000000..6f729554d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/err.pod
        @@ -0,0 +1,187 @@
        +=pod
        +
        +=head1 NAME
        +
        +err - error codes
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/err.h>
        +
        + unsigned long ERR_get_error(void);
        + unsigned long ERR_peek_error(void);
        + unsigned long ERR_get_error_line(const char **file, int *line);
        + unsigned long ERR_peek_error_line(const char **file, int *line);
        + unsigned long ERR_get_error_line_data(const char **file, int *line,
        +         const char **data, int *flags);
        + unsigned long ERR_peek_error_line_data(const char **file, int *line,
        +         const char **data, int *flags);
        +
        + int ERR_GET_LIB(unsigned long e);
        + int ERR_GET_FUNC(unsigned long e);
        + int ERR_GET_REASON(unsigned long e);
        +
        + void ERR_clear_error(void);
        +
        + char *ERR_error_string(unsigned long e, char *buf);
        + const char *ERR_lib_error_string(unsigned long e);
        + const char *ERR_func_error_string(unsigned long e);
        + const char *ERR_reason_error_string(unsigned long e);
        +
        + void ERR_print_errors(BIO *bp);
        + void ERR_print_errors_fp(FILE *fp);
        +
        + void ERR_load_crypto_strings(void);
        + void ERR_free_strings(void);
        +
        + void ERR_remove_state(unsigned long pid);
        +
        + void ERR_put_error(int lib, int func, int reason, const char *file,
        +         int line);
        + void ERR_add_error_data(int num, ...);
        +
        + void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
        + unsigned long ERR_PACK(int lib, int func, int reason);
        + int ERR_get_next_error_library(void);
        +
        +=head1 DESCRIPTION
        +
        +When a call to the OpenSSL library fails, this is usually signalled
        +by the return value, and an error code is stored in an error queue
        +associated with the current thread. The B<err> library provides
        +functions to obtain these error codes and textual error messages.
        +
        +The L<ERR_get_error(3)|ERR_get_error(3)> manpage describes how to
        +access error codes.
        +
        +Error codes contain information about where the error occurred, and
        +what went wrong. L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> describes how to
        +extract this information. A method to obtain human-readable error
        +messages is described in L<ERR_error_string(3)|ERR_error_string(3)>.
        +
        +L<ERR_clear_error(3)|ERR_clear_error(3)> can be used to clear the
        +error queue.
        +
        +Note that L<ERR_remove_state(3)|ERR_remove_state(3)> should be used to
        +avoid memory leaks when threads are terminated.
        +
        +=head1 ADDING NEW ERROR CODES TO OPENSSL
        +
        +See L<ERR_put_error(3)> if you want to record error codes in the
        +OpenSSL error system from within your application.
        +
        +The remainder of this section is of interest only if you want to add
        +new error codes to OpenSSL or add error codes from external libraries.
        +
        +=head2 Reporting errors
        +
        +Each sub-library has a specific macro XXXerr() that is used to report
        +errors. Its first argument is a function code B<XXX_F_...>, the second
        +argument is a reason code B<XXX_R_...>. Function codes are derived
        +from the function names; reason codes consist of textual error
        +descriptions. For example, the function ssl23_read() reports a
        +"handshake failure" as follows:
        +
        + SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE);
        +
        +Function and reason codes should consist of upper case characters,
        +numbers and underscores only. The error file generation script translates
        +function codes into function names by looking in the header files
        +for an appropriate function name, if none is found it just uses
        +the capitalized form such as "SSL23_READ" in the above example.
        +
        +The trailing section of a reason code (after the "_R_") is translated
        +into lower case and underscores changed to spaces.
        +
        +When you are using new function or reason codes, run B<make errors>.
        +The necessary B<#define>s will then automatically be added to the
        +sub-library's header file.
        +
        +Although a library will normally report errors using its own specific
        +XXXerr macro, another library's macro can be used. This is normally
        +only done when a library wants to include ASN1 code which must use
        +the ASN1err() macro.
        +
        +=head2 Adding new libraries
        +
        +When adding a new sub-library to OpenSSL, assign it a library number
        +B<ERR_LIB_XXX>, define a macro XXXerr() (both in B<err.h>), add its
        +name to B<ERR_str_libraries[]> (in B<crypto/err/err.c>), and add
        +C<ERR_load_XXX_strings()> to the ERR_load_crypto_strings() function
        +(in B<crypto/err/err_all.c>). Finally, add an entry
        +
        + L	XXX	xxx.h	xxx_err.c
        +
        +to B<crypto/err/openssl.ec>, and add B<xxx_err.c> to the Makefile.
        +Running B<make errors> will then generate a file B<xxx_err.c>, and
        +add all error codes used in the library to B<xxx.h>.
        +
        +Additionally the library include file must have a certain form.
        +Typically it will initially look like this:
        +
        + #ifndef HEADER_XXX_H
        + #define HEADER_XXX_H
        +
        + #ifdef __cplusplus
        + extern "C" {
        + #endif
        +
        + /* Include files */
        +
        + #include <openssl/bio.h>
        + #include <openssl/x509.h>
        +
        + /* Macros, structures and function prototypes */
        +
        +
        + /* BEGIN ERROR CODES */
        +
        +The B<BEGIN ERROR CODES> sequence is used by the error code
        +generation script as the point to place new error codes, any text
        +after this point will be overwritten when B<make errors> is run.
        +The closing #endif etc will be automatically added by the script.
        +
        +The generated C error code file B<xxx_err.c> will load the header
        +files B<stdio.h>, B<openssl/err.h> and B<openssl/xxx.h> so the
        +header file must load any additional header files containing any
        +definitions it uses.
        +
        +=head1 USING ERROR CODES IN EXTERNAL LIBRARIES
        +
        +It is also possible to use OpenSSL's error code scheme in external
        +libraries. The library needs to load its own codes and call the OpenSSL
        +error code insertion script B<mkerr.pl> explicitly to add codes to
        +the header file and generate the C error code file. This will normally
        +be done if the external library needs to generate new ASN1 structures
        +but it can also be used to add more general purpose error code handling.
        +
        +TBA more details
        +
        +=head1 INTERNALS
        +
        +The error queues are stored in a hash table with one B<ERR_STATE>
        +entry for each pid. ERR_get_state() returns the current thread's
        +B<ERR_STATE>. An B<ERR_STATE> can hold up to B<ERR_NUM_ERRORS> error
        +codes. When more error codes are added, the old ones are overwritten,
        +on the assumption that the most recent errors are most important.
        +
        +Error strings are also stored in hash table. The hash tables can
        +be obtained by calling ERR_get_err_state_table(void) and
        +ERR_get_string_table(void) respectively.
        +
        +=head1 SEE ALSO
        +
        +L<CRYPTO_set_id_callback(3)|CRYPTO_set_id_callback(3)>,
        +L<CRYPTO_set_locking_callback(3)|CRYPTO_set_locking_callback(3)>,
        +L<ERR_get_error(3)|ERR_get_error(3)>,
        +L<ERR_GET_LIB(3)|ERR_GET_LIB(3)>,
        +L<ERR_clear_error(3)|ERR_clear_error(3)>,
        +L<ERR_error_string(3)|ERR_error_string(3)>,
        +L<ERR_print_errors(3)|ERR_print_errors(3)>,
        +L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>,
        +L<ERR_remove_state(3)|ERR_remove_state(3)>,
        +L<ERR_put_error(3)|ERR_put_error(3)>,
        +L<ERR_load_strings(3)|ERR_load_strings(3)>,
        +L<SSL_get_error(3)|SSL_get_error(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/evp.pod b/vendor/openssl/openssl/doc/crypto/evp.pod
        new file mode 100644
        index 000000000..9faa34924
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/evp.pod
        @@ -0,0 +1,55 @@
        +=pod
        +
        +=head1 NAME
        +
        +evp - high-level cryptographic functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/evp.h>
        +
        +=head1 DESCRIPTION
        +
        +The EVP library provides a high-level interface to cryptographic
        +functions.
        +
        +B<EVP_Seal>I<...> and B<EVP_Open>I<...> provide public key encryption
        +and decryption to implement digital "envelopes".
        +
        +The B<EVP_Sign>I<...> and B<EVP_Verify>I<...> functions implement
        +digital signatures.
        +
        +Symmetric encryption is available with the B<EVP_Encrypt>I<...>
        +functions.  The B<EVP_Digest>I<...> functions provide message digests.
        +
        +The B<EVP_PKEY>I<...> functions provide a high level interface to
        +asymmetric algorithms.
        +
        +Algorithms are loaded with OpenSSL_add_all_algorithms(3).
        +
        +All the symmetric algorithms (ciphers), digests and asymmetric algorithms
        +(public key algorithms) can be replaced by ENGINE modules providing alternative
        +implementations. If ENGINE implementations of ciphers or digests are registered
        +as defaults, then the various EVP functions will automatically use those
        +implementations automatically in preference to built in software
        +implementations. For more information, consult the engine(3) man page.
        +
        +Although low level algorithm specific functions exist for many algorithms
        +their use is discouraged. They cannot be used with an ENGINE and ENGINE
        +versions of new algorithms cannot be accessed using the low level functions.
        +Also makes code harder to adapt to new algorithms and some options are not 
        +cleanly supported at the low level and some operations are more efficient
        +using the high level interface.
        +
        +=head1 SEE ALSO
        +
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>,
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>,
        +L<EVP_OpenInit(3)|EVP_OpenInit(3)>,
        +L<EVP_SealInit(3)|EVP_SealInit(3)>,
        +L<EVP_SignInit(3)|EVP_SignInit(3)>,
        +L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>,
        +L<OpenSSL_add_all_algorithms(3)|OpenSSL_add_all_algorithms(3)>,
        +L<engine(3)|engine(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/hmac.pod b/vendor/openssl/openssl/doc/crypto/hmac.pod
        new file mode 100644
        index 000000000..d92138d27
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/hmac.pod
        @@ -0,0 +1,106 @@
        +=pod
        +
        +=head1 NAME
        +
        +HMAC, HMAC_Init, HMAC_Update, HMAC_Final, HMAC_cleanup - HMAC message
        +authentication code
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/hmac.h>
        +
        + unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
        +               int key_len, const unsigned char *d, int n,
        +               unsigned char *md, unsigned int *md_len);
        +
        + void HMAC_CTX_init(HMAC_CTX *ctx);
        +
        + int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len,
        +               const EVP_MD *md);
        + int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len,
        +               	   const EVP_MD *md, ENGINE *impl);
        + int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len);
        + int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
        +
        + void HMAC_CTX_cleanup(HMAC_CTX *ctx);
        + void HMAC_cleanup(HMAC_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +HMAC is a MAC (message authentication code), i.e. a keyed hash
        +function used for message authentication, which is based on a hash
        +function.
        +
        +HMAC() computes the message authentication code of the B<n> bytes at
        +B<d> using the hash function B<evp_md> and the key B<key> which is
        +B<key_len> bytes long.
        +
        +It places the result in B<md> (which must have space for the output of
        +the hash function, which is no more than B<EVP_MAX_MD_SIZE> bytes).
        +If B<md> is NULL, the digest is placed in a static array.  The size of
        +the output is placed in B<md_len>, unless it is B<NULL>.
        +
        +B<evp_md> can be EVP_sha1(), EVP_ripemd160() etc.
        +
        +HMAC_CTX_init() initialises a B<HMAC_CTX> before first use. It must be
        +called.
        +
        +HMAC_CTX_cleanup() erases the key and other data from the B<HMAC_CTX>
        +and releases any associated resources. It must be called when an
        +B<HMAC_CTX> is no longer required.
        +
        +HMAC_cleanup() is an alias for HMAC_CTX_cleanup() included for back
        +compatibility with 0.9.6b, it is deprecated.
        +
        +The following functions may be used if the message is not completely
        +stored in memory:
        +
        +HMAC_Init() initializes a B<HMAC_CTX> structure to use the hash
        +function B<evp_md> and the key B<key> which is B<key_len> bytes
        +long. It is deprecated and only included for backward compatibility
        +with OpenSSL 0.9.6b.
        +
        +HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use
        +the function B<evp_md> and key B<key>. Either can be NULL, in which
        +case the existing one will be reused. HMAC_CTX_init() must have been
        +called before the first use of an B<HMAC_CTX> in this
        +function. B<N.B. HMAC_Init() had this undocumented behaviour in
        +previous versions of OpenSSL - failure to switch to HMAC_Init_ex() in
        +programs that expect it will cause them to stop working>.
        +
        +HMAC_Update() can be called repeatedly with chunks of the message to
        +be authenticated (B<len> bytes at B<data>).
        +
        +HMAC_Final() places the message authentication code in B<md>, which
        +must have space for the hash function output.
        +
        +=head1 RETURN VALUES
        +
        +HMAC() returns a pointer to the message authentication code or NULL if
        +an error occurred.
        +
        +HMAC_Init_ex(), HMAC_Update() and HMAC_Final() return 1 for success or 0 if
        +an error occurred.
        +
        +HMAC_CTX_init() and HMAC_CTX_cleanup() do not return values.
        +
        +=head1 CONFORMING TO
        +
        +RFC 2104
        +
        +=head1 SEE ALSO
        +
        +L<sha(3)|sha(3)>, L<evp(3)|evp(3)>
        +
        +=head1 HISTORY
        +
        +HMAC(), HMAC_Init(), HMAC_Update(), HMAC_Final() and HMAC_cleanup()
        +are available since SSLeay 0.9.0.
        +
        +HMAC_CTX_init(), HMAC_Init_ex() and HMAC_CTX_cleanup() are available
        +since OpenSSL 0.9.7.
        +
        +HMAC_Init_ex(), HMAC_Update() and HMAC_Final() did not return values in
        +versions of OpenSSL before 1.0.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/i2d_CMS_bio_stream.pod b/vendor/openssl/openssl/doc/crypto/i2d_CMS_bio_stream.pod
        new file mode 100644
        index 000000000..558bdd081
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/i2d_CMS_bio_stream.pod
        @@ -0,0 +1,44 @@
        +=pod
        +
        +=head1 NAME
        +
        + i2d_CMS_bio_stream - output CMS_ContentInfo structure in BER format.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/cms.h>
        +
        + int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format.
        +
        +It is otherwise identical to the function SMIME_write_CMS().
        +
        +=head1 NOTES
        +
        +This function is effectively a version of the i2d_CMS_bio() supporting
        +streaming.
        +
        +=head1 BUGS
        +
        +The prefix "i2d" is arguably wrong because the function outputs BER format.
        +
        +=head1 RETURN VALUES
        +
        +i2d_CMS_bio_stream() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
        +L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
        +L<CMS_decrypt(3)|CMS_decrypt(3)>,
        +L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>,
        +L<PEM_write_bio_CMS_stream(3)|PEM_write_bio_CMS_stream(3)>
        +
        +=head1 HISTORY
        +
        +i2d_CMS_bio_stream() was added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod b/vendor/openssl/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod
        new file mode 100644
        index 000000000..dc4d884c5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod
        @@ -0,0 +1,44 @@
        +=pod
        +
        +=head1 NAME
        +
        +i2d_PKCS7_bio_stream - output PKCS7 structure in BER format.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pkcs7.h>
        +
        + int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags);
        +
        +=head1 DESCRIPTION
        +
        +i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format.
        +
        +It is otherwise identical to the function SMIME_write_PKCS7().
        +
        +=head1 NOTES
        +
        +This function is effectively a version of the d2i_PKCS7_bio() supporting
        +streaming.
        +
        +=head1 BUGS
        +
        +The prefix "d2i" is arguably wrong because the function outputs BER format.
        +
        +=head1 RETURN VALUES
        +
        +i2d_PKCS7_bio_stream() returns 1 for success or 0 for failure.
        +
        +=head1 SEE ALSO
        +
        +L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
        +L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
        +L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>,
        +L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>,
        +L<PEM_write_bio_PKCS7_stream(3)|PEM_write_bio_PKCS7_stream(3)>
        +
        +=head1 HISTORY
        +
        +i2d_PKCS7_bio_stream() was added to OpenSSL 1.0.0
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/lh_stats.pod b/vendor/openssl/openssl/doc/crypto/lh_stats.pod
        new file mode 100644
        index 000000000..3eeaa72e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/lh_stats.pod
        @@ -0,0 +1,60 @@
        +=pod
        +
        +=head1 NAME
        +
        +lh_stats, lh_node_stats, lh_node_usage_stats, lh_stats_bio,
        +lh_node_stats_bio, lh_node_usage_stats_bio - LHASH statistics
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/lhash.h>
        +
        + void lh_stats(LHASH *table, FILE *out);
        + void lh_node_stats(LHASH *table, FILE *out);
        + void lh_node_usage_stats(LHASH *table, FILE *out);
        +
        + void lh_stats_bio(LHASH *table, BIO *out);
        + void lh_node_stats_bio(LHASH *table, BIO *out);
        + void lh_node_usage_stats_bio(LHASH *table, BIO *out);
        +
        +=head1 DESCRIPTION
        +
        +The B<LHASH> structure records statistics about most aspects of
        +accessing the hash table.  This is mostly a legacy of Eric Young
        +writing this library for the reasons of implementing what looked like
        +a nice algorithm rather than for a particular software product.
        +
        +lh_stats() prints out statistics on the size of the hash table, how
        +many entries are in it, and the number and result of calls to the
        +routines in this library.
        +
        +lh_node_stats() prints the number of entries for each 'bucket' in the
        +hash table.
        +
        +lh_node_usage_stats() prints out a short summary of the state of the
        +hash table.  It prints the 'load' and the 'actual load'.  The load is
        +the average number of data items per 'bucket' in the hash table.  The
        +'actual load' is the average number of items per 'bucket', but only
        +for buckets which contain entries.  So the 'actual load' is the
        +average number of searches that will need to find an item in the hash
        +table, while the 'load' is the average number that will be done to
        +record a miss.
        +
        +lh_stats_bio(), lh_node_stats_bio() and lh_node_usage_stats_bio()
        +are the same as the above, except that the output goes to a B<BIO>.
        +
        +=head1 RETURN VALUES
        +
        +These functions do not return values.
        +
        +=head1 SEE ALSO
        +
        +L<bio(3)|bio(3)>, L<lhash(3)|lhash(3)>
        +
        +=head1 HISTORY
        +
        +These functions are available in all versions of SSLeay and OpenSSL.
        +
        +This manpage is derived from the SSLeay documentation.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/lhash.pod b/vendor/openssl/openssl/doc/crypto/lhash.pod
        new file mode 100644
        index 000000000..73a19b6c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/lhash.pod
        @@ -0,0 +1,302 @@
        +=pod
        +
        +=head1 NAME
        +
        +lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error - dynamic hash table
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/lhash.h>
        +
        + DECLARE_LHASH_OF(<type>);
        +
        + LHASH *lh_<type>_new();
        + void lh_<type>_free(LHASH_OF(<type> *table);
        +
        + <type> *lh_<type>_insert(LHASH_OF(<type> *table, <type> *data);
        + <type> *lh_<type>_delete(LHASH_OF(<type> *table, <type> *data);
        + <type> *lh_retrieve(LHASH_OF<type> *table, <type> *data);
        +
        + void lh_<type>_doall(LHASH_OF(<type> *table, LHASH_DOALL_FN_TYPE func);
        + void lh_<type>_doall_arg(LHASH_OF(<type> *table, LHASH_DOALL_ARG_FN_TYPE func,
        +          <type2>, <type2> *arg);
        +
        + int lh_<type>_error(LHASH_OF(<type> *table);
        +
        + typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *);
        + typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *);
        + typedef void (*LHASH_DOALL_FN_TYPE)(const void *);
        + typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *);
        +
        +=head1 DESCRIPTION
        +
        +This library implements type-checked dynamic hash tables. The hash
        +table entries can be arbitrary structures. Usually they consist of key
        +and value fields.
        +
        +lh_<type>_new() creates a new B<LHASH_OF(<type>> structure to store
        +arbitrary data entries, and provides the 'hash' and 'compare'
        +callbacks to be used in organising the table's entries.  The B<hash>
        +callback takes a pointer to a table entry as its argument and returns
        +an unsigned long hash value for its key field.  The hash value is
        +normally truncated to a power of 2, so make sure that your hash
        +function returns well mixed low order bits.  The B<compare> callback
        +takes two arguments (pointers to two hash table entries), and returns
        +0 if their keys are equal, non-zero otherwise.  If your hash table
        +will contain items of some particular type and the B<hash> and
        +B<compare> callbacks hash/compare these types, then the
        +B<DECLARE_LHASH_HASH_FN> and B<IMPLEMENT_LHASH_COMP_FN> macros can be
        +used to create callback wrappers of the prototypes required by
        +lh_<type>_new().  These provide per-variable casts before calling the
        +type-specific callbacks written by the application author.  These
        +macros, as well as those used for the "doall" callbacks, are defined
        +as;
        +
        + #define DECLARE_LHASH_HASH_FN(name, o_type) \
        +	 unsigned long name##_LHASH_HASH(const void *);
        + #define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
        +	 unsigned long name##_LHASH_HASH(const void *arg) { \
        +		 const o_type *a = arg; \
        +		 return name##_hash(a); }
        + #define LHASH_HASH_FN(name) name##_LHASH_HASH
        +
        + #define DECLARE_LHASH_COMP_FN(name, o_type) \
        +	 int name##_LHASH_COMP(const void *, const void *);
        + #define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
        +	 int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
        +		 const o_type *a = arg1;		    \
        +		 const o_type *b = arg2; \
        +		 return name##_cmp(a,b); }
        + #define LHASH_COMP_FN(name) name##_LHASH_COMP
        +
        + #define DECLARE_LHASH_DOALL_FN(name, o_type) \
        +	 void name##_LHASH_DOALL(void *);
        + #define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
        +	 void name##_LHASH_DOALL(void *arg) { \
        +		 o_type *a = arg; \
        +		 name##_doall(a); }
        + #define LHASH_DOALL_FN(name) name##_LHASH_DOALL
        +
        + #define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
        +	 void name##_LHASH_DOALL_ARG(void *, void *);
        + #define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
        +	 void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
        +		 o_type *a = arg1; \
        +		 a_type *b = arg2; \
        +		 name##_doall_arg(a, b); }
        + #define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
        +
        + An example of a hash table storing (pointers to) structures of type 'STUFF'
        + could be defined as follows;
        +
        + /* Calculates the hash value of 'tohash' (implemented elsewhere) */
        + unsigned long STUFF_hash(const STUFF *tohash);
        + /* Orders 'arg1' and 'arg2' (implemented elsewhere) */
        + int stuff_cmp(const STUFF *arg1, const STUFF *arg2);
        + /* Create the type-safe wrapper functions for use in the LHASH internals */
        + static IMPLEMENT_LHASH_HASH_FN(stuff, STUFF);
        + static IMPLEMENT_LHASH_COMP_FN(stuff, STUFF);
        + /* ... */
        + int main(int argc, char *argv[]) {
        +         /* Create the new hash table using the hash/compare wrappers */
        +         LHASH_OF(STUFF) *hashtable = lh_STUFF_new(LHASH_HASH_FN(STUFF_hash),
        +                                   LHASH_COMP_FN(STUFF_cmp));
        +	 /* ... */
        + }
        +
        +lh_<type>_free() frees the B<LHASH_OF(<type>> structure
        +B<table>. Allocated hash table entries will not be freed; consider
        +using lh_<type>_doall() to deallocate any remaining entries in the
        +hash table (see below).
        +
        +lh_<type>_insert() inserts the structure pointed to by B<data> into
        +B<table>.  If there already is an entry with the same key, the old
        +value is replaced. Note that lh_<type>_insert() stores pointers, the
        +data are not copied.
        +
        +lh_<type>_delete() deletes an entry from B<table>.
        +
        +lh_<type>_retrieve() looks up an entry in B<table>. Normally, B<data>
        +is a structure with the key field(s) set; the function will return a
        +pointer to a fully populated structure.
        +
        +lh_<type>_doall() will, for every entry in the hash table, call
        +B<func> with the data item as its parameter.  For lh_<type>_doall()
        +and lh_<type>_doall_arg(), function pointer casting should be avoided
        +in the callbacks (see B<NOTE>) - instead use the declare/implement
        +macros to create type-checked wrappers that cast variables prior to
        +calling your type-specific callbacks.  An example of this is
        +illustrated here where the callback is used to cleanup resources for
        +items in the hash table prior to the hashtable itself being
        +deallocated:
        +
        + /* Cleans up resources belonging to 'a' (this is implemented elsewhere) */
        + void STUFF_cleanup_doall(STUFF *a);
        + /* Implement a prototype-compatible wrapper for "STUFF_cleanup" */
        + IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF)
        +         /* ... then later in the code ... */
        + /* So to run "STUFF_cleanup" against all items in a hash table ... */
        + lh_STUFF_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup));
        + /* Then the hash table itself can be deallocated */
        + lh_STUFF_free(hashtable);
        +
        +When doing this, be careful if you delete entries from the hash table
        +in your callbacks: the table may decrease in size, moving the item
        +that you are currently on down lower in the hash table - this could
        +cause some entries to be skipped during the iteration.  The second
        +best solution to this problem is to set hash-E<gt>down_load=0 before
        +you start (which will stop the hash table ever decreasing in size).
        +The best solution is probably to avoid deleting items from the hash
        +table inside a "doall" callback!
        +
        +lh_<type>_doall_arg() is the same as lh_<type>_doall() except that
        +B<func> will be called with B<arg> as the second argument and B<func>
        +should be of type B<LHASH_DOALL_ARG_FN_TYPE> (a callback prototype
        +that is passed both the table entry and an extra argument).  As with
        +lh_doall(), you can instead choose to declare your callback with a
        +prototype matching the types you are dealing with and use the
        +declare/implement macros to create compatible wrappers that cast
        +variables before calling your type-specific callbacks.  An example of
        +this is demonstrated here (printing all hash table entries to a BIO
        +that is provided by the caller):
        +
        + /* Prints item 'a' to 'output_bio' (this is implemented elsewhere) */
        + void STUFF_print_doall_arg(const STUFF *a, BIO *output_bio);
        + /* Implement a prototype-compatible wrapper for "STUFF_print" */
        + static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF, const STUFF, BIO)
        +         /* ... then later in the code ... */
        + /* Print out the entire hashtable to a particular BIO */
        + lh_STUFF_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), BIO,
        +                    logging_bio);
        + 
        +lh_<type>_error() can be used to determine if an error occurred in the last
        +operation. lh_<type>_error() is a macro.
        +
        +=head1 RETURN VALUES
        +
        +lh_<type>_new() returns B<NULL> on error, otherwise a pointer to the new
        +B<LHASH> structure.
        +
        +When a hash table entry is replaced, lh_<type>_insert() returns the value
        +being replaced. B<NULL> is returned on normal operation and on error.
        +
        +lh_<type>_delete() returns the entry being deleted.  B<NULL> is returned if
        +there is no such value in the hash table.
        +
        +lh_<type>_retrieve() returns the hash table entry if it has been found,
        +B<NULL> otherwise.
        +
        +lh_<type>_error() returns 1 if an error occurred in the last operation, 0
        +otherwise.
        +
        +lh_<type>_free(), lh_<type>_doall() and lh_<type>_doall_arg() return no values.
        +
        +=head1 NOTE
        +
        +The various LHASH macros and callback types exist to make it possible
        +to write type-checked code without resorting to function-prototype
        +casting - an evil that makes application code much harder to
        +audit/verify and also opens the window of opportunity for stack
        +corruption and other hard-to-find bugs.  It also, apparently, violates
        +ANSI-C.
        +
        +The LHASH code regards table entries as constant data.  As such, it
        +internally represents lh_insert()'d items with a "const void *"
        +pointer type.  This is why callbacks such as those used by lh_doall()
        +and lh_doall_arg() declare their prototypes with "const", even for the
        +parameters that pass back the table items' data pointers - for
        +consistency, user-provided data is "const" at all times as far as the
        +LHASH code is concerned.  However, as callers are themselves providing
        +these pointers, they can choose whether they too should be treating
        +all such parameters as constant.
        +
        +As an example, a hash table may be maintained by code that, for
        +reasons of encapsulation, has only "const" access to the data being
        +indexed in the hash table (ie. it is returned as "const" from
        +elsewhere in their code) - in this case the LHASH prototypes are
        +appropriate as-is.  Conversely, if the caller is responsible for the
        +life-time of the data in question, then they may well wish to make
        +modifications to table item passed back in the lh_doall() or
        +lh_doall_arg() callbacks (see the "STUFF_cleanup" example above).  If
        +so, the caller can either cast the "const" away (if they're providing
        +the raw callbacks themselves) or use the macros to declare/implement
        +the wrapper functions without "const" types.
        +
        +Callers that only have "const" access to data they're indexing in a
        +table, yet declare callbacks without constant types (or cast the
        +"const" away themselves), are therefore creating their own risks/bugs
        +without being encouraged to do so by the API.  On a related note,
        +those auditing code should pay special attention to any instances of
        +DECLARE/IMPLEMENT_LHASH_DOALL_[ARG_]_FN macros that provide types
        +without any "const" qualifiers.
        +
        +=head1 BUGS
        +
        +lh_<type>_insert() returns B<NULL> both for success and error.
        +
        +=head1 INTERNALS
        +
        +The following description is based on the SSLeay documentation:
        +
        +The B<lhash> library implements a hash table described in the
        +I<Communications of the ACM> in 1991.  What makes this hash table
        +different is that as the table fills, the hash table is increased (or
        +decreased) in size via OPENSSL_realloc().  When a 'resize' is done, instead of
        +all hashes being redistributed over twice as many 'buckets', one
        +bucket is split.  So when an 'expand' is done, there is only a minimal
        +cost to redistribute some values.  Subsequent inserts will cause more
        +single 'bucket' redistributions but there will never be a sudden large
        +cost due to redistributing all the 'buckets'.
        +
        +The state for a particular hash table is kept in the B<LHASH> structure.
        +The decision to increase or decrease the hash table size is made
        +depending on the 'load' of the hash table.  The load is the number of
        +items in the hash table divided by the size of the hash table.  The
        +default values are as follows.  If (hash->up_load E<lt> load) =E<gt>
        +expand.  if (hash-E<gt>down_load E<gt> load) =E<gt> contract.  The
        +B<up_load> has a default value of 1 and B<down_load> has a default value
        +of 2.  These numbers can be modified by the application by just
        +playing with the B<up_load> and B<down_load> variables.  The 'load' is
        +kept in a form which is multiplied by 256.  So
        +hash-E<gt>up_load=8*256; will cause a load of 8 to be set.
        +
        +If you are interested in performance the field to watch is
        +num_comp_calls.  The hash library keeps track of the 'hash' value for
        +each item so when a lookup is done, the 'hashes' are compared, if
        +there is a match, then a full compare is done, and
        +hash-E<gt>num_comp_calls is incremented.  If num_comp_calls is not equal
        +to num_delete plus num_retrieve it means that your hash function is
        +generating hashes that are the same for different values.  It is
        +probably worth changing your hash function if this is the case because
        +even if your hash table has 10 items in a 'bucket', it can be searched
        +with 10 B<unsigned long> compares and 10 linked list traverses.  This
        +will be much less expensive that 10 calls to your compare function.
        +
        +lh_strhash() is a demo string hashing function:
        +
        + unsigned long lh_strhash(const char *c);
        +
        +Since the B<LHASH> routines would normally be passed structures, this
        +routine would not normally be passed to lh_<type>_new(), rather it would be
        +used in the function passed to lh_<type>_new().
        +
        +=head1 SEE ALSO
        +
        +L<lh_stats(3)|lh_stats(3)>
        +
        +=head1 HISTORY
        +
        +The B<lhash> library is available in all versions of SSLeay and OpenSSL.
        +lh_error() was added in SSLeay 0.9.1b.
        +
        +This manpage is derived from the SSLeay documentation.
        +
        +In OpenSSL 0.9.7, all lhash functions that were passed function pointers
        +were changed for better type safety, and the function types LHASH_COMP_FN_TYPE,
        +LHASH_HASH_FN_TYPE, LHASH_DOALL_FN_TYPE and LHASH_DOALL_ARG_FN_TYPE 
        +became available.
        +
        +In OpenSSL 1.0.0, the lhash interface was revamped for even better
        +type checking.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/md5.pod b/vendor/openssl/openssl/doc/crypto/md5.pod
        new file mode 100644
        index 000000000..d11d5c32c
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/md5.pod
        @@ -0,0 +1,101 @@
        +=pod
        +
        +=head1 NAME
        +
        +MD2, MD4, MD5, MD2_Init, MD2_Update, MD2_Final, MD4_Init, MD4_Update,
        +MD4_Final, MD5_Init, MD5_Update, MD5_Final - MD2, MD4, and MD5 hash functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/md2.h>
        +
        + unsigned char *MD2(const unsigned char *d, unsigned long n,
        +                  unsigned char *md);
        +
        + int MD2_Init(MD2_CTX *c);
        + int MD2_Update(MD2_CTX *c, const unsigned char *data,
        +                  unsigned long len);
        + int MD2_Final(unsigned char *md, MD2_CTX *c);
        +
        +
        + #include <openssl/md4.h>
        +
        + unsigned char *MD4(const unsigned char *d, unsigned long n,
        +                  unsigned char *md);
        +
        + int MD4_Init(MD4_CTX *c);
        + int MD4_Update(MD4_CTX *c, const void *data,
        +                  unsigned long len);
        + int MD4_Final(unsigned char *md, MD4_CTX *c);
        +
        +
        + #include <openssl/md5.h>
        +
        + unsigned char *MD5(const unsigned char *d, unsigned long n,
        +                  unsigned char *md);
        +
        + int MD5_Init(MD5_CTX *c);
        + int MD5_Update(MD5_CTX *c, const void *data,
        +                  unsigned long len);
        + int MD5_Final(unsigned char *md, MD5_CTX *c);
        +
        +=head1 DESCRIPTION
        +
        +MD2, MD4, and MD5 are cryptographic hash functions with a 128 bit output.
        +
        +MD2(), MD4(), and MD5() compute the MD2, MD4, and MD5 message digest
        +of the B<n> bytes at B<d> and place it in B<md> (which must have space
        +for MD2_DIGEST_LENGTH == MD4_DIGEST_LENGTH == MD5_DIGEST_LENGTH == 16
        +bytes of output). If B<md> is NULL, the digest is placed in a static
        +array.
        +
        +The following functions may be used if the message is not completely
        +stored in memory:
        +
        +MD2_Init() initializes a B<MD2_CTX> structure.
        +
        +MD2_Update() can be called repeatedly with chunks of the message to
        +be hashed (B<len> bytes at B<data>).
        +
        +MD2_Final() places the message digest in B<md>, which must have space
        +for MD2_DIGEST_LENGTH == 16 bytes of output, and erases the B<MD2_CTX>.
        +
        +MD4_Init(), MD4_Update(), MD4_Final(), MD5_Init(), MD5_Update(), and
        +MD5_Final() are analogous using an B<MD4_CTX> and B<MD5_CTX> structure.
        +
        +Applications should use the higher level functions
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>
        +etc. instead of calling the hash functions directly.
        +
        +=head1 NOTE
        +
        +MD2, MD4, and MD5 are recommended only for compatibility with existing
        +applications. In new applications, SHA-1 or RIPEMD-160 should be
        +preferred.
        +
        +=head1 RETURN VALUES
        +
        +MD2(), MD4(), and MD5() return pointers to the hash value. 
        +
        +MD2_Init(), MD2_Update(), MD2_Final(), MD4_Init(), MD4_Update(),
        +MD4_Final(), MD5_Init(), MD5_Update(), and MD5_Final() return 1 for
        +success, 0 otherwise.
        +
        +=head1 CONFORMING TO
        +
        +RFC 1319, RFC 1320, RFC 1321
        +
        +=head1 SEE ALSO
        +
        +L<sha(3)|sha(3)>, L<ripemd(3)|ripemd(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
        +
        +=head1 HISTORY
        +
        +MD2(), MD2_Init(), MD2_Update() MD2_Final(), MD5(), MD5_Init(),
        +MD5_Update() and MD5_Final() are available in all versions of SSLeay
        +and OpenSSL.
        +
        +MD4(), MD4_Init(), and MD4_Update() are available in OpenSSL 0.9.6 and
        +above.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/mdc2.pod b/vendor/openssl/openssl/doc/crypto/mdc2.pod
        new file mode 100644
        index 000000000..41f648af3
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/mdc2.pod
        @@ -0,0 +1,64 @@
        +=pod
        +
        +=head1 NAME
        +
        +MDC2, MDC2_Init, MDC2_Update, MDC2_Final - MDC2 hash function
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/mdc2.h>
        +
        + unsigned char *MDC2(const unsigned char *d, unsigned long n,
        +                  unsigned char *md);
        +
        + int MDC2_Init(MDC2_CTX *c);
        + int MDC2_Update(MDC2_CTX *c, const unsigned char *data,
        +                  unsigned long len);
        + int MDC2_Final(unsigned char *md, MDC2_CTX *c);
        +
        +=head1 DESCRIPTION
        +
        +MDC2 is a method to construct hash functions with 128 bit output from
        +block ciphers.  These functions are an implementation of MDC2 with
        +DES.
        +
        +MDC2() computes the MDC2 message digest of the B<n>
        +bytes at B<d> and places it in B<md> (which must have space for
        +MDC2_DIGEST_LENGTH == 16 bytes of output). If B<md> is NULL, the digest
        +is placed in a static array.
        +
        +The following functions may be used if the message is not completely
        +stored in memory:
        +
        +MDC2_Init() initializes a B<MDC2_CTX> structure.
        +
        +MDC2_Update() can be called repeatedly with chunks of the message to
        +be hashed (B<len> bytes at B<data>).
        +
        +MDC2_Final() places the message digest in B<md>, which must have space
        +for MDC2_DIGEST_LENGTH == 16 bytes of output, and erases the B<MDC2_CTX>.
        +
        +Applications should use the higher level functions
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)> etc. instead of calling the
        +hash functions directly.
        +
        +=head1 RETURN VALUES
        +
        +MDC2() returns a pointer to the hash value. 
        +
        +MDC2_Init(), MDC2_Update() and MDC2_Final() return 1 for success, 0 otherwise.
        +
        +=head1 CONFORMING TO
        +
        +ISO/IEC 10118-2, with DES
        +
        +=head1 SEE ALSO
        +
        +L<sha(3)|sha(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
        +
        +=head1 HISTORY
        +
        +MDC2(), MDC2_Init(), MDC2_Update() and MDC2_Final() are available since
        +SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/pem.pod b/vendor/openssl/openssl/doc/crypto/pem.pod
        new file mode 100644
        index 000000000..d5b189611
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/pem.pod
        @@ -0,0 +1,476 @@
        +=pod
        +
        +=head1 NAME
        +
        +PEM, PEM_read_bio_PrivateKey, PEM_read_PrivateKey, PEM_write_bio_PrivateKey, PEM_write_PrivateKey, PEM_write_bio_PKCS8PrivateKey, PEM_write_PKCS8PrivateKey, PEM_write_bio_PKCS8PrivateKey_nid, PEM_write_PKCS8PrivateKey_nid, PEM_read_bio_PUBKEY, PEM_read_PUBKEY, PEM_write_bio_PUBKEY, PEM_write_PUBKEY, PEM_read_bio_RSAPrivateKey, PEM_read_RSAPrivateKey, PEM_write_bio_RSAPrivateKey, PEM_write_RSAPrivateKey, PEM_read_bio_RSAPublicKey, PEM_read_RSAPublicKey, PEM_write_bio_RSAPublicKey, PEM_write_RSAPublicKey, PEM_read_bio_RSA_PUBKEY, PEM_read_RSA_PUBKEY, PEM_write_bio_RSA_PUBKEY, PEM_write_RSA_PUBKEY, PEM_read_bio_DSAPrivateKey, PEM_read_DSAPrivateKey, PEM_write_bio_DSAPrivateKey, PEM_write_DSAPrivateKey, PEM_read_bio_DSA_PUBKEY, PEM_read_DSA_PUBKEY, PEM_write_bio_DSA_PUBKEY, PEM_write_DSA_PUBKEY, PEM_read_bio_DSAparams, PEM_read_DSAparams, PEM_write_bio_DSAparams, PEM_write_DSAparams, PEM_read_bio_DHparams, PEM_read_DHparams, PEM_write_bio_DHparams, PEM_write_DHparams, PEM_read_bio_X509, PEM_read_X509, PEM_write_bio_X509, PEM_write_X509, PEM_read_bio_X509_AUX, PEM_read_X509_AUX, PEM_write_bio_X509_AUX, PEM_write_X509_AUX, PEM_read_bio_X509_REQ, PEM_read_X509_REQ, PEM_write_bio_X509_REQ, PEM_write_X509_REQ, PEM_write_bio_X509_REQ_NEW, PEM_write_X509_REQ_NEW, PEM_read_bio_X509_CRL, PEM_read_X509_CRL, PEM_write_bio_X509_CRL, PEM_write_X509_CRL, PEM_read_bio_PKCS7, PEM_read_PKCS7, PEM_write_bio_PKCS7, PEM_write_PKCS7, PEM_read_bio_NETSCAPE_CERT_SEQUENCE, PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE, PEM_write_NETSCAPE_CERT_SEQUENCE - PEM routines
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/pem.h>
        +
        + EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x,
        +					pem_password_cb *cb, void *u);
        +
        + EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +					unsigned char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +					unsigned char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +					char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
        +					char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
        +					char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
        +					char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x,
        +					pem_password_cb *cb, void *u);
        +
        + EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x);
        + int PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x);
        +
        + RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
        +					unsigned char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
        +					unsigned char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x);
        +
        + int PEM_write_RSAPublicKey(FILE *fp, RSA *x);
        +
        + RSA *PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + RSA *PEM_read_RSA_PUBKEY(FILE *fp, RSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x);
        +
        + int PEM_write_RSA_PUBKEY(FILE *fp, RSA *x);
        +
        + DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
        +					unsigned char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
        +					unsigned char *kstr, int klen,
        +					pem_password_cb *cb, void *u);
        +
        + DSA *PEM_read_bio_DSA_PUBKEY(BIO *bp, DSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + DSA *PEM_read_DSA_PUBKEY(FILE *fp, DSA **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_DSA_PUBKEY(BIO *bp, DSA *x);
        +
        + int PEM_write_DSA_PUBKEY(FILE *fp, DSA *x);
        +
        + DSA *PEM_read_bio_DSAparams(BIO *bp, DSA **x, pem_password_cb *cb, void *u);
        +
        + DSA *PEM_read_DSAparams(FILE *fp, DSA **x, pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_DSAparams(BIO *bp, DSA *x);
        +
        + int PEM_write_DSAparams(FILE *fp, DSA *x);
        +
        + DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u);
        +
        + DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_DHparams(BIO *bp, DH *x);
        +
        + int PEM_write_DHparams(FILE *fp, DH *x);
        +
        + X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
        +
        + X509 *PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_X509(BIO *bp, X509 *x);
        +
        + int PEM_write_X509(FILE *fp, X509 *x);
        +
        + X509 *PEM_read_bio_X509_AUX(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
        +
        + X509 *PEM_read_X509_AUX(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_X509_AUX(BIO *bp, X509 *x);
        +
        + int PEM_write_X509_AUX(FILE *fp, X509 *x);
        +
        + X509_REQ *PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x,
        +					pem_password_cb *cb, void *u);
        +
        + X509_REQ *PEM_read_X509_REQ(FILE *fp, X509_REQ **x,
        +					pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x);
        +
        + int PEM_write_X509_REQ(FILE *fp, X509_REQ *x);
        +
        + int PEM_write_bio_X509_REQ_NEW(BIO *bp, X509_REQ *x);
        +
        + int PEM_write_X509_REQ_NEW(FILE *fp, X509_REQ *x);
        +
        + X509_CRL *PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x,
        +					pem_password_cb *cb, void *u);
        + X509_CRL *PEM_read_X509_CRL(FILE *fp, X509_CRL **x,
        +					pem_password_cb *cb, void *u);
        + int PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x);
        + int PEM_write_X509_CRL(FILE *fp, X509_CRL *x);
        +
        + PKCS7 *PEM_read_bio_PKCS7(BIO *bp, PKCS7 **x, pem_password_cb *cb, void *u);
        +
        + PKCS7 *PEM_read_PKCS7(FILE *fp, PKCS7 **x, pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_PKCS7(BIO *bp, PKCS7 *x);
        +
        + int PEM_write_PKCS7(FILE *fp, PKCS7 *x);
        +
        + NETSCAPE_CERT_SEQUENCE *PEM_read_bio_NETSCAPE_CERT_SEQUENCE(BIO *bp,
        +						NETSCAPE_CERT_SEQUENCE **x,
        +						pem_password_cb *cb, void *u);
        +
        + NETSCAPE_CERT_SEQUENCE *PEM_read_NETSCAPE_CERT_SEQUENCE(FILE *fp,
        +						NETSCAPE_CERT_SEQUENCE **x,
        +						pem_password_cb *cb, void *u);
        +
        + int PEM_write_bio_NETSCAPE_CERT_SEQUENCE(BIO *bp, NETSCAPE_CERT_SEQUENCE *x);
        +
        + int PEM_write_NETSCAPE_CERT_SEQUENCE(FILE *fp, NETSCAPE_CERT_SEQUENCE *x);
        +
        +=head1 DESCRIPTION
        +
        +The PEM functions read or write structures in PEM format. In
        +this sense PEM format is simply base64 encoded data surrounded
        +by header lines.
        +
        +For more details about the meaning of arguments see the
        +B<PEM FUNCTION ARGUMENTS> section.
        +
        +Each operation has four functions associated with it. For
        +clarity the term "B<foobar> functions" will be used to collectively
        +refer to the PEM_read_bio_foobar(), PEM_read_foobar(),
        +PEM_write_bio_foobar() and PEM_write_foobar() functions.
        +
        +The B<PrivateKey> functions read or write a private key in
        +PEM format using an EVP_PKEY structure. The write routines use
        +"traditional" private key format and can handle both RSA and DSA
        +private keys. The read functions can additionally transparently
        +handle PKCS#8 format encrypted and unencrypted keys too.
        +
        +PEM_write_bio_PKCS8PrivateKey() and PEM_write_PKCS8PrivateKey()
        +write a private key in an EVP_PKEY structure in PKCS#8
        +EncryptedPrivateKeyInfo format using PKCS#5 v2.0 password based encryption
        +algorithms. The B<cipher> argument specifies the encryption algoritm to
        +use: unlike all other PEM routines the encryption is applied at the
        +PKCS#8 level and not in the PEM headers. If B<cipher> is NULL then no
        +encryption is used and a PKCS#8 PrivateKeyInfo structure is used instead.
        +
        +PEM_write_bio_PKCS8PrivateKey_nid() and PEM_write_PKCS8PrivateKey_nid()
        +also write out a private key as a PKCS#8 EncryptedPrivateKeyInfo however
        +it uses PKCS#5 v1.5 or PKCS#12 encryption algorithms instead. The algorithm
        +to use is specified in the B<nid> parameter and should be the NID of the
        +corresponding OBJECT IDENTIFIER (see NOTES section).
        +
        +The B<PUBKEY> functions process a public key using an EVP_PKEY
        +structure. The public key is encoded as a SubjectPublicKeyInfo
        +structure.
        +
        +The B<RSAPrivateKey> functions process an RSA private key using an
        +RSA structure. It handles the same formats as the B<PrivateKey>
        +functions but an error occurs if the private key is not RSA.
        +
        +The B<RSAPublicKey> functions process an RSA public key using an
        +RSA structure. The public key is encoded using a PKCS#1 RSAPublicKey
        +structure.
        +
        +The B<RSA_PUBKEY> functions also process an RSA public key using
        +an RSA structure. However the public key is encoded using a
        +SubjectPublicKeyInfo structure and an error occurs if the public
        +key is not RSA.
        +
        +The B<DSAPrivateKey> functions process a DSA private key using a
        +DSA structure. It handles the same formats as the B<PrivateKey>
        +functions but an error occurs if the private key is not DSA.
        +
        +The B<DSA_PUBKEY> functions process a DSA public key using
        +a DSA structure. The public key is encoded using a
        +SubjectPublicKeyInfo structure and an error occurs if the public
        +key is not DSA.
        +
        +The B<DSAparams> functions process DSA parameters using a DSA
        +structure. The parameters are encoded using a foobar structure.
        +
        +The B<DHparams> functions process DH parameters using a DH
        +structure. The parameters are encoded using a PKCS#3 DHparameter
        +structure.
        +
        +The B<X509> functions process an X509 certificate using an X509
        +structure. They will also process a trusted X509 certificate but
        +any trust settings are discarded.
        +
        +The B<X509_AUX> functions process a trusted X509 certificate using
        +an X509 structure. 
        +
        +The B<X509_REQ> and B<X509_REQ_NEW> functions process a PKCS#10
        +certificate request using an X509_REQ structure. The B<X509_REQ>
        +write functions use B<CERTIFICATE REQUEST> in the header whereas
        +the B<X509_REQ_NEW> functions use B<NEW CERTIFICATE REQUEST>
        +(as required by some CAs). The B<X509_REQ> read functions will
        +handle either form so there are no B<X509_REQ_NEW> read functions.
        +
        +The B<X509_CRL> functions process an X509 CRL using an X509_CRL
        +structure.
        +
        +The B<PKCS7> functions process a PKCS#7 ContentInfo using a PKCS7
        +structure.
        +
        +The B<NETSCAPE_CERT_SEQUENCE> functions process a Netscape Certificate
        +Sequence using a NETSCAPE_CERT_SEQUENCE structure.
        +
        +=head1 PEM FUNCTION ARGUMENTS
        +
        +The PEM functions have many common arguments.
        +
        +The B<bp> BIO parameter (if present) specifies the BIO to read from
        +or write to.
        +
        +The B<fp> FILE parameter (if present) specifies the FILE pointer to
        +read from or write to.
        +
        +The PEM read functions all take an argument B<TYPE **x> and return
        +a B<TYPE *> pointer. Where B<TYPE> is whatever structure the function
        +uses. If B<x> is NULL then the parameter is ignored. If B<x> is not
        +NULL but B<*x> is NULL then the structure returned will be written
        +to B<*x>. If neither B<x> nor B<*x> is NULL then an attempt is made
        +to reuse the structure at B<*x> (but see BUGS and EXAMPLES sections).
        +Irrespective of the value of B<x> a pointer to the structure is always
        +returned (or NULL if an error occurred).
        +
        +The PEM functions which write private keys take an B<enc> parameter
        +which specifies the encryption algorithm to use, encryption is done
        +at the PEM level. If this parameter is set to NULL then the private
        +key is written in unencrypted form.
        +
        +The B<cb> argument is the callback to use when querying for the pass
        +phrase used for encrypted PEM structures (normally only private keys).
        +
        +For the PEM write routines if the B<kstr> parameter is not NULL then
        +B<klen> bytes at B<kstr> are used as the passphrase and B<cb> is
        +ignored.
        +
        +If the B<cb> parameters is set to NULL and the B<u> parameter is not
        +NULL then the B<u> parameter is interpreted as a null terminated string
        +to use as the passphrase. If both B<cb> and B<u> are NULL then the
        +default callback routine is used which will typically prompt for the
        +passphrase on the current terminal with echoing turned off.
        +
        +The default passphrase callback is sometimes inappropriate (for example
        +in a GUI application) so an alternative can be supplied. The callback
        +routine has the following form:
        +
        + int cb(char *buf, int size, int rwflag, void *u);
        +
        +B<buf> is the buffer to write the passphrase to. B<size> is the maximum
        +length of the passphrase (i.e. the size of buf). B<rwflag> is a flag
        +which is set to 0 when reading and 1 when writing. A typical routine
        +will ask the user to verify the passphrase (for example by prompting
        +for it twice) if B<rwflag> is 1. The B<u> parameter has the same
        +value as the B<u> parameter passed to the PEM routine. It allows
        +arbitrary data to be passed to the callback by the application
        +(for example a window handle in a GUI application). The callback
        +B<must> return the number of characters in the passphrase or 0 if
        +an error occurred.
        +
        +=head1 EXAMPLES
        +
        +Although the PEM routines take several arguments in almost all applications
        +most of them are set to 0 or NULL.
        +
        +Read a certificate in PEM format from a BIO:
        +
        + X509 *x;
        + x = PEM_read_bio_X509(bp, NULL, 0, NULL);
        + if (x == NULL)
        +	{
        +	/* Error */
        +	}
        +
        +Alternative method:
        +
        + X509 *x = NULL;
        + if (!PEM_read_bio_X509(bp, &x, 0, NULL))
        +	{
        +	/* Error */
        +	}
        +
        +Write a certificate to a BIO:
        +
        + if (!PEM_write_bio_X509(bp, x))
        +	{
        +	/* Error */
        +	}
        +
        +Write an unencrypted private key to a FILE pointer:
        +
        + if (!PEM_write_PrivateKey(fp, key, NULL, NULL, 0, 0, NULL))
        +	{
        +	/* Error */
        +	}
        +
        +Write a private key (using traditional format) to a BIO using
        +triple DES encryption, the pass phrase is prompted for:
        +
        + if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, NULL))
        +	{
        +	/* Error */
        +	}
        +
        +Write a private key (using PKCS#8 format) to a BIO using triple
        +DES encryption, using the pass phrase "hello":
        +
        + if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, "hello"))
        +	{
        +	/* Error */
        +	}
        +
        +Read a private key from a BIO using the pass phrase "hello":
        +
        + key = PEM_read_bio_PrivateKey(bp, NULL, 0, "hello");
        + if (key == NULL)
        +	{
        +	/* Error */
        +	}
        +
        +Read a private key from a BIO using a pass phrase callback:
        +
        + key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key");
        + if (key == NULL)
        +	{
        +	/* Error */
        +	}
        +
        +Skeleton pass phrase callback:
        +
        + int pass_cb(char *buf, int size, int rwflag, void *u);
        +	{
        +	int len;
        +	char *tmp;
        +	/* We'd probably do something else if 'rwflag' is 1 */
        +	printf("Enter pass phrase for \"%s\"\n", u);
        +
        +	/* get pass phrase, length 'len' into 'tmp' */
        +	tmp = "hello";
        +	len = strlen(tmp);
        +
        +	if (len <= 0) return 0;
        +	/* if too long, truncate */
        +	if (len > size) len = size;
        +	memcpy(buf, tmp, len);
        +	return len;
        +	}
        +
        +=head1 NOTES
        +
        +The old B<PrivateKey> write routines are retained for compatibility.
        +New applications should write private keys using the
        +PEM_write_bio_PKCS8PrivateKey() or PEM_write_PKCS8PrivateKey() routines
        +because they are more secure (they use an iteration count of 2048 whereas
        +the traditional routines use a count of 1) unless compatibility with older
        +versions of OpenSSL is important.
        +
        +The B<PrivateKey> read routines can be used in all applications because
        +they handle all formats transparently.
        +
        +A frequent cause of problems is attempting to use the PEM routines like
        +this:
        +
        + X509 *x;
        + PEM_read_bio_X509(bp, &x, 0, NULL);
        +
        +this is a bug because an attempt will be made to reuse the data at B<x>
        +which is an uninitialised pointer.
        +
        +=head1 PEM ENCRYPTION FORMAT
        +
        +This old B<PrivateKey> routines use a non standard technique for encryption.
        +
        +The private key (or other data) takes the following form: 
        +
        + -----BEGIN RSA PRIVATE KEY-----
        + Proc-Type: 4,ENCRYPTED
        + DEK-Info: DES-EDE3-CBC,3F17F5316E2BAC89
        +
        + ...base64 encoded data...
        + -----END RSA PRIVATE KEY-----
        +
        +The line beginning DEK-Info contains two comma separated pieces of information:
        +the encryption algorithm name as used by EVP_get_cipherbyname() and an 8
        +byte B<salt> encoded as a set of hexadecimal digits.
        +
        +After this is the base64 encoded encrypted data.
        +
        +The encryption key is determined using EVP_bytestokey(), using B<salt> and an
        +iteration count of 1. The IV used is the value of B<salt> and *not* the IV
        +returned by EVP_bytestokey().
        +
        +=head1 BUGS
        +
        +The PEM read routines in some versions of OpenSSL will not correctly reuse
        +an existing structure. Therefore the following:
        +
        + PEM_read_bio_X509(bp, &x, 0, NULL);
        +
        +where B<x> already contains a valid certificate, may not work, whereas: 
        +
        + X509_free(x);
        + x = PEM_read_bio_X509(bp, NULL, 0, NULL);
        +
        +is guaranteed to work.
        +
        +=head1 RETURN CODES
        +
        +The read routines return either a pointer to the structure read or NULL
        +if an error occurred.
        +
        +The write routines return 1 for success or 0 for failure.
        diff --git a/vendor/openssl/openssl/doc/crypto/rand.pod b/vendor/openssl/openssl/doc/crypto/rand.pod
        new file mode 100644
        index 000000000..1c068c85b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/rand.pod
        @@ -0,0 +1,175 @@
        +=pod
        +
        +=head1 NAME
        +
        +rand - pseudo-random number generator
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rand.h>
        +
        + int  RAND_set_rand_engine(ENGINE *engine);
        +
        + int  RAND_bytes(unsigned char *buf, int num);
        + int  RAND_pseudo_bytes(unsigned char *buf, int num);
        +
        + void RAND_seed(const void *buf, int num);
        + void RAND_add(const void *buf, int num, int entropy);
        + int  RAND_status(void);
        +
        + int  RAND_load_file(const char *file, long max_bytes);
        + int  RAND_write_file(const char *file);
        + const char *RAND_file_name(char *file, size_t num);
        +
        + int  RAND_egd(const char *path);
        +
        + void RAND_set_rand_method(const RAND_METHOD *meth);
        + const RAND_METHOD *RAND_get_rand_method(void);
        + RAND_METHOD *RAND_SSLeay(void);
        +
        + void RAND_cleanup(void);
        +
        + /* For Win32 only */
        + void RAND_screen(void);
        + int RAND_event(UINT, WPARAM, LPARAM);
        +
        +=head1 DESCRIPTION
        +
        +Since the introduction of the ENGINE API, the recommended way of controlling
        +default implementations is by using the ENGINE API functions. The default
        +B<RAND_METHOD>, as set by RAND_set_rand_method() and returned by
        +RAND_get_rand_method(), is only used if no ENGINE has been set as the default
        +"rand" implementation. Hence, these two functions are no longer the recommened
        +way to control defaults.
        +
        +If an alternative B<RAND_METHOD> implementation is being used (either set
        +directly or as provided by an ENGINE module), then it is entirely responsible
        +for the generation and management of a cryptographically secure PRNG stream. The
        +mechanisms described below relate solely to the software PRNG implementation
        +built in to OpenSSL and used by default.
        +
        +These functions implement a cryptographically secure pseudo-random
        +number generator (PRNG). It is used by other library functions for
        +example to generate random keys, and applications can use it when they
        +need randomness.
        +
        +A cryptographic PRNG must be seeded with unpredictable data such as
        +mouse movements or keys pressed at random by the user. This is
        +described in L<RAND_add(3)|RAND_add(3)>. Its state can be saved in a seed file
        +(see L<RAND_load_file(3)|RAND_load_file(3)>) to avoid having to go through the
        +seeding process whenever the application is started.
        +
        +L<RAND_bytes(3)|RAND_bytes(3)> describes how to obtain random data from the
        +PRNG. 
        +
        +=head1 INTERNALS
        +
        +The RAND_SSLeay() method implements a PRNG based on a cryptographic
        +hash function.
        +
        +The following description of its design is based on the SSLeay
        +documentation:
        +
        +First up I will state the things I believe I need for a good RNG.
        +
        +=over 4
        +
        +=item 1
        +
        +A good hashing algorithm to mix things up and to convert the RNG 'state'
        +to random numbers.
        +
        +=item 2
        +
        +An initial source of random 'state'.
        +
        +=item 3
        +
        +The state should be very large.  If the RNG is being used to generate
        +4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum).
        +If your RNG state only has 128 bits, you are obviously limiting the
        +search space to 128 bits, not 2048.  I'm probably getting a little
        +carried away on this last point but it does indicate that it may not be
        +a bad idea to keep quite a lot of RNG state.  It should be easier to
        +break a cipher than guess the RNG seed data.
        +
        +=item 4
        +
        +Any RNG seed data should influence all subsequent random numbers
        +generated.  This implies that any random seed data entered will have
        +an influence on all subsequent random numbers generated.
        +
        +=item 5
        +
        +When using data to seed the RNG state, the data used should not be
        +extractable from the RNG state.  I believe this should be a
        +requirement because one possible source of 'secret' semi random
        +data would be a private key or a password.  This data must
        +not be disclosed by either subsequent random numbers or a
        +'core' dump left by a program crash.
        +
        +=item 6
        +
        +Given the same initial 'state', 2 systems should deviate in their RNG state
        +(and hence the random numbers generated) over time if at all possible.
        +
        +=item 7
        +
        +Given the random number output stream, it should not be possible to determine
        +the RNG state or the next random number.
        +
        +=back
        +
        +The algorithm is as follows.
        +
        +There is global state made up of a 1023 byte buffer (the 'state'), a
        +working hash value ('md'), and a counter ('count').
        +
        +Whenever seed data is added, it is inserted into the 'state' as
        +follows.
        +
        +The input is chopped up into units of 20 bytes (or less for
        +the last block).  Each of these blocks is run through the hash
        +function as follows:  The data passed to the hash function
        +is the current 'md', the same number of bytes from the 'state'
        +(the location determined by in incremented looping index) as
        +the current 'block', the new key data 'block', and 'count'
        +(which is incremented after each use).
        +The result of this is kept in 'md' and also xored into the
        +'state' at the same locations that were used as input into the
        +hash function. I
        +believe this system addresses points 1 (hash function; currently
        +SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash
        +function and xor).
        +
        +When bytes are extracted from the RNG, the following process is used.
        +For each group of 10 bytes (or less), we do the following:
        +
        +Input into the hash function the local 'md' (which is initialized from
        +the global 'md' before any bytes are generated), the bytes that are to
        +be overwritten by the random bytes, and bytes from the 'state'
        +(incrementing looping index). From this digest output (which is kept
        +in 'md'), the top (up to) 10 bytes are returned to the caller and the
        +bottom 10 bytes are xored into the 'state'.
        +
        +Finally, after we have finished 'num' random bytes for the caller,
        +'count' (which is incremented) and the local and global 'md' are fed
        +into the hash function and the results are kept in the global 'md'.
        +
        +I believe the above addressed points 1 (use of SHA-1), 6 (by hashing
        +into the 'state' the 'old' data from the caller that is about to be
        +overwritten) and 7 (by not using the 10 bytes given to the caller to
        +update the 'state', but they are used to update 'md').
        +
        +So of the points raised, only 2 is not addressed (but see
        +L<RAND_add(3)|RAND_add(3)>).
        +
        +=head1 SEE ALSO
        +
        +L<BN_rand(3)|BN_rand(3)>, L<RAND_add(3)|RAND_add(3)>,
        +L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_egd(3)|RAND_egd(3)>,
        +L<RAND_bytes(3)|RAND_bytes(3)>,
        +L<RAND_set_rand_method(3)|RAND_set_rand_method(3)>,
        +L<RAND_cleanup(3)|RAND_cleanup(3)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/rc4.pod b/vendor/openssl/openssl/doc/crypto/rc4.pod
        new file mode 100644
        index 000000000..b6d3a4342
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/rc4.pod
        @@ -0,0 +1,62 @@
        +=pod
        +
        +=head1 NAME
        +
        +RC4_set_key, RC4 - RC4 encryption
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rc4.h>
        +
        + void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
        +
        + void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
        +          unsigned char *outdata);
        +
        +=head1 DESCRIPTION
        +
        +This library implements the Alleged RC4 cipher, which is described for
        +example in I<Applied Cryptography>.  It is believed to be compatible
        +with RC4[TM], a proprietary cipher of RSA Security Inc.
        +
        +RC4 is a stream cipher with variable key length.  Typically, 128 bit
        +(16 byte) keys are used for strong encryption, but shorter insecure
        +key sizes have been widely used due to export restrictions.
        +
        +RC4 consists of a key setup phase and the actual encryption or
        +decryption phase.
        +
        +RC4_set_key() sets up the B<RC4_KEY> B<key> using the B<len> bytes long
        +key at B<data>.
        +
        +RC4() encrypts or decrypts the B<len> bytes of data at B<indata> using
        +B<key> and places the result at B<outdata>.  Repeated RC4() calls with
        +the same B<key> yield a continuous key stream.
        +
        +Since RC4 is a stream cipher (the input is XORed with a pseudo-random
        +key stream to produce the output), decryption uses the same function
        +calls as encryption.
        +
        +Applications should use the higher level functions
        +L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>
        +etc. instead of calling the RC4 functions directly.
        +
        +=head1 RETURN VALUES
        +
        +RC4_set_key() and RC4() do not return values.
        +
        +=head1 NOTE
        +
        +Certain conditions have to be observed to securely use stream ciphers.
        +It is not permissible to perform multiple encryptions using the same
        +key stream.
        +
        +=head1 SEE ALSO
        +
        +L<blowfish(3)|blowfish(3)>, L<des(3)|des(3)>, L<rc2(3)|rc2(3)>
        +
        +=head1 HISTORY
        +
        +RC4_set_key() and RC4() are available in all versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ripemd.pod b/vendor/openssl/openssl/doc/crypto/ripemd.pod
        new file mode 100644
        index 000000000..264bb99ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ripemd.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        +RIPEMD160, RIPEMD160_Init, RIPEMD160_Update, RIPEMD160_Final -
        +RIPEMD-160 hash function
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ripemd.h>
        +
        + unsigned char *RIPEMD160(const unsigned char *d, unsigned long n,
        +                  unsigned char *md);
        +
        + int RIPEMD160_Init(RIPEMD160_CTX *c);
        + int RIPEMD160_Update(RIPEMD_CTX *c, const void *data,
        +                  unsigned long len);
        + int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
        +
        +=head1 DESCRIPTION
        +
        +RIPEMD-160 is a cryptographic hash function with a
        +160 bit output.
        +
        +RIPEMD160() computes the RIPEMD-160 message digest of the B<n>
        +bytes at B<d> and places it in B<md> (which must have space for
        +RIPEMD160_DIGEST_LENGTH == 20 bytes of output). If B<md> is NULL, the digest
        +is placed in a static array.
        +
        +The following functions may be used if the message is not completely
        +stored in memory:
        +
        +RIPEMD160_Init() initializes a B<RIPEMD160_CTX> structure.
        +
        +RIPEMD160_Update() can be called repeatedly with chunks of the message to
        +be hashed (B<len> bytes at B<data>).
        +
        +RIPEMD160_Final() places the message digest in B<md>, which must have
        +space for RIPEMD160_DIGEST_LENGTH == 20 bytes of output, and erases
        +the B<RIPEMD160_CTX>.
        +
        +Applications should use the higher level functions
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)> etc. instead of calling the
        +hash functions directly.
        +
        +=head1 RETURN VALUES
        +
        +RIPEMD160() returns a pointer to the hash value. 
        +
        +RIPEMD160_Init(), RIPEMD160_Update() and RIPEMD160_Final() return 1 for
        +success, 0 otherwise.
        +
        +=head1 CONFORMING TO
        +
        +ISO/IEC 10118-3 (draft) (??)
        +
        +=head1 SEE ALSO
        +
        +L<sha(3)|sha(3)>, L<hmac(3)|hmac(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
        +
        +=head1 HISTORY
        +
        +RIPEMD160(), RIPEMD160_Init(), RIPEMD160_Update() and
        +RIPEMD160_Final() are available since SSLeay 0.9.0.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/rsa.pod b/vendor/openssl/openssl/doc/crypto/rsa.pod
        new file mode 100644
        index 000000000..45ac53ffc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/rsa.pod
        @@ -0,0 +1,123 @@
        +=pod
        +
        +=head1 NAME
        +
        +rsa - RSA public key cryptosystem
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/rsa.h>
        + #include <openssl/engine.h>
        +
        + RSA * RSA_new(void);
        + void RSA_free(RSA *rsa);
        +
        + int RSA_public_encrypt(int flen, unsigned char *from,
        +    unsigned char *to, RSA *rsa, int padding);
        + int RSA_private_decrypt(int flen, unsigned char *from,
        +    unsigned char *to, RSA *rsa, int padding);
        + int RSA_private_encrypt(int flen, unsigned char *from,
        +    unsigned char *to, RSA *rsa,int padding);
        + int RSA_public_decrypt(int flen, unsigned char *from, 
        +    unsigned char *to, RSA *rsa,int padding);
        +
        + int RSA_sign(int type, unsigned char *m, unsigned int m_len,
        +    unsigned char *sigret, unsigned int *siglen, RSA *rsa);
        + int RSA_verify(int type, unsigned char *m, unsigned int m_len,
        +    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
        +
        + int RSA_size(const RSA *rsa);
        +
        + RSA *RSA_generate_key(int num, unsigned long e,
        +    void (*callback)(int,int,void *), void *cb_arg);
        +
        + int RSA_check_key(RSA *rsa);
        +
        + int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
        + void RSA_blinding_off(RSA *rsa);
        +
        + void RSA_set_default_method(const RSA_METHOD *meth);
        + const RSA_METHOD *RSA_get_default_method(void);
        + int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
        + const RSA_METHOD *RSA_get_method(const RSA *rsa);
        + RSA_METHOD *RSA_PKCS1_SSLeay(void);
        + RSA_METHOD *RSA_null_method(void);
        + int RSA_flags(const RSA *rsa);
        + RSA *RSA_new_method(ENGINE *engine);
        +
        + int RSA_print(BIO *bp, RSA *x, int offset);
        + int RSA_print_fp(FILE *fp, RSA *x, int offset);
        +
        + int RSA_get_ex_new_index(long argl, char *argp, int (*new_func)(),
        +    int (*dup_func)(), void (*free_func)());
        + int RSA_set_ex_data(RSA *r,int idx,char *arg);
        + char *RSA_get_ex_data(RSA *r, int idx);
        +
        + int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m,
        +    unsigned int m_len, unsigned char *sigret, unsigned int *siglen,
        +    RSA *rsa);
        + int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m,
        +    unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
        +    RSA *rsa);
        +
        +=head1 DESCRIPTION
        +
        +These functions implement RSA public key encryption and signatures
        +as defined in PKCS #1 v2.0 [RFC 2437].
        +
        +The B<RSA> structure consists of several BIGNUM components. It can
        +contain public as well as private RSA keys:
        +
        + struct
        +        {
        +        BIGNUM *n;		// public modulus
        +        BIGNUM *e;		// public exponent
        +        BIGNUM *d;		// private exponent
        +        BIGNUM *p;		// secret prime factor
        +        BIGNUM *q;		// secret prime factor
        +        BIGNUM *dmp1;		// d mod (p-1)
        +        BIGNUM *dmq1;		// d mod (q-1)
        +        BIGNUM *iqmp;		// q^-1 mod p
        +	// ...
        +        };
        + RSA
        +
        +In public keys, the private exponent and the related secret values are
        +B<NULL>.
        +
        +B<p>, B<q>, B<dmp1>, B<dmq1> and B<iqmp> may be B<NULL> in private
        +keys, but the RSA operations are much faster when these values are
        +available.
        +
        +Note that RSA keys may use non-standard B<RSA_METHOD> implementations,
        +either directly or by the use of B<ENGINE> modules. In some cases (eg. an
        +ENGINE providing support for hardware-embedded keys), these BIGNUM values
        +will not be used by the implementation or may be used for alternative data
        +storage. For this reason, applications should generally avoid using RSA
        +structure elements directly and instead use API functions to query or
        +modify keys.
        +
        +=head1 CONFORMING TO
        +
        +SSL, PKCS #1 v2.0
        +
        +=head1 PATENTS
        +
        +RSA was covered by a US patent which expired in September 2000.
        +
        +=head1 SEE ALSO
        +
        +L<rsa(1)|rsa(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>,
        +L<rand(3)|rand(3)>, L<engine(3)|engine(3)>, L<RSA_new(3)|RSA_new(3)>,
        +L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>,
        +L<RSA_sign(3)|RSA_sign(3)>, L<RSA_size(3)|RSA_size(3)>,
        +L<RSA_generate_key(3)|RSA_generate_key(3)>,
        +L<RSA_check_key(3)|RSA_check_key(3)>,
        +L<RSA_blinding_on(3)|RSA_blinding_on(3)>,
        +L<RSA_set_method(3)|RSA_set_method(3)>, L<RSA_print(3)|RSA_print(3)>,
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
        +L<RSA_private_encrypt(3)|RSA_private_encrypt(3)>,
        +L<RSA_sign_ASN1_OCTET_STRING(3)|RSA_sign_ASN1_OCTET_STRING(3)>,
        +L<RSA_padding_add_PKCS1_type_1(3)|RSA_padding_add_PKCS1_type_1(3)> 
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/sha.pod b/vendor/openssl/openssl/doc/crypto/sha.pod
        new file mode 100644
        index 000000000..94ab7bc72
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/sha.pod
        @@ -0,0 +1,70 @@
        +=pod
        +
        +=head1 NAME
        +
        +SHA1, SHA1_Init, SHA1_Update, SHA1_Final - Secure Hash Algorithm
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/sha.h>
        +
        + unsigned char *SHA1(const unsigned char *d, unsigned long n,
        +                  unsigned char *md);
        +
        + int SHA1_Init(SHA_CTX *c);
        + int SHA1_Update(SHA_CTX *c, const void *data,
        +                  unsigned long len);
        + int SHA1_Final(unsigned char *md, SHA_CTX *c);
        +
        +=head1 DESCRIPTION
        +
        +SHA-1 (Secure Hash Algorithm) is a cryptographic hash function with a
        +160 bit output.
        +
        +SHA1() computes the SHA-1 message digest of the B<n>
        +bytes at B<d> and places it in B<md> (which must have space for
        +SHA_DIGEST_LENGTH == 20 bytes of output). If B<md> is NULL, the digest
        +is placed in a static array.
        +
        +The following functions may be used if the message is not completely
        +stored in memory:
        +
        +SHA1_Init() initializes a B<SHA_CTX> structure.
        +
        +SHA1_Update() can be called repeatedly with chunks of the message to
        +be hashed (B<len> bytes at B<data>).
        +
        +SHA1_Final() places the message digest in B<md>, which must have space
        +for SHA_DIGEST_LENGTH == 20 bytes of output, and erases the B<SHA_CTX>.
        +
        +Applications should use the higher level functions
        +L<EVP_DigestInit(3)|EVP_DigestInit(3)>
        +etc. instead of calling the hash functions directly.
        +
        +The predecessor of SHA-1, SHA, is also implemented, but it should be
        +used only when backward compatibility is required.
        +
        +=head1 RETURN VALUES
        +
        +SHA1() returns a pointer to the hash value. 
        +
        +SHA1_Init(), SHA1_Update() and SHA1_Final() return 1 for success, 0 otherwise.
        +
        +=head1 CONFORMING TO
        +
        +SHA: US Federal Information Processing Standard FIPS PUB 180 (Secure Hash
        +Standard),
        +SHA-1: US Federal Information Processing Standard FIPS PUB 180-1 (Secure Hash
        +Standard),
        +ANSI X9.30
        +
        +=head1 SEE ALSO
        +
        +L<ripemd(3)|ripemd(3)>, L<hmac(3)|hmac(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>
        +
        +=head1 HISTORY
        +
        +SHA1(), SHA1_Init(), SHA1_Update() and SHA1_Final() are available in all
        +versions of SSLeay and OpenSSL.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/threads.pod b/vendor/openssl/openssl/doc/crypto/threads.pod
        new file mode 100644
        index 000000000..dc0e9391d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/threads.pod
        @@ -0,0 +1,210 @@
        +=pod
        +
        +=head1 NAME
        +
        +CRYPTO_THREADID_set_callback, CRYPTO_THREADID_get_callback,
        +CRYPTO_THREADID_current, CRYPTO_THREADID_cmp, CRYPTO_THREADID_cpy,
        +CRYPTO_THREADID_hash, CRYPTO_set_locking_callback, CRYPTO_num_locks,
        +CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
        +CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
        +CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/crypto.h>
        +
        + /* Don't use this structure directly. */
        + typedef struct crypto_threadid_st
        +         {
        +         void *ptr;
        +         unsigned long val;
        +         } CRYPTO_THREADID;
        + /* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
        + void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
        + void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
        + int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
        + void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
        + void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
        + int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a,
        +                         const CRYPTO_THREADID *b);
        + void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest,
        +                          const CRYPTO_THREADID *src);
        + unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
        +
        + int CRYPTO_num_locks(void);
        +
        + /* struct CRYPTO_dynlock_value needs to be defined by the user */
        + struct CRYPTO_dynlock_value;
        +
        + void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *
        +	(*dyn_create_function)(char *file, int line));
        + void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)
        +	(int mode, struct CRYPTO_dynlock_value *l,
        +	const char *file, int line));
        + void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)
        +	(struct CRYPTO_dynlock_value *l, const char *file, int line));
        +
        + int CRYPTO_get_new_dynlockid(void);
        +
        + void CRYPTO_destroy_dynlockid(int i);
        +
        + void CRYPTO_lock(int mode, int n, const char *file, int line);
        +
        + #define CRYPTO_w_lock(type)	\
        +	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
        + #define CRYPTO_w_unlock(type)	\
        +	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
        + #define CRYPTO_r_lock(type)	\
        +	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
        + #define CRYPTO_r_unlock(type)	\
        +	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
        + #define CRYPTO_add(addr,amount,type)	\
        +	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
        +
        +=head1 DESCRIPTION
        +
        +OpenSSL can safely be used in multi-threaded applications provided
        +that at least two callback functions are set, locking_function and
        +threadid_func.
        +
        +locking_function(int mode, int n, const char *file, int line) is
        +needed to perform locking on shared data structures. 
        +(Note that OpenSSL uses a number of global data structures that
        +will be implicitly shared whenever multiple threads use OpenSSL.)
        +Multi-threaded applications will crash at random if it is not set.
        +
        +locking_function() must be able to handle up to CRYPTO_num_locks()
        +different mutex locks. It sets the B<n>-th lock if B<mode> &
        +B<CRYPTO_LOCK>, and releases it otherwise.
        +
        +B<file> and B<line> are the file number of the function setting the
        +lock. They can be useful for debugging.
        +
        +threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing
        +thread's identifier into B<id>. The implementation of this callback should not
        +fill in B<id> directly, but should use CRYPTO_THREADID_set_numeric() if thread
        +IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based.
        +If the application does not register such a callback using
        +CRYPTO_THREADID_set_callback(), then a default implementation is used - on
        +Windows and BeOS this uses the system's default thread identifying APIs, and on
        +all other platforms it uses the address of B<errno>. The latter is satisfactory
        +for thread-safety if and only if the platform has a thread-local error number
        +facility.
        +
        +Once threadid_func() is registered, or if the built-in default implementation is
        +to be used;
        +
        +=over 4
        +
        +=item *
        +CRYPTO_THREADID_current() records the currently-executing thread ID into the
        +given B<id> object.
        +
        +=item *
        +CRYPTO_THREADID_cmp() compares two thread IDs (returning zero for equality, ie.
        +the same semantics as memcmp()).
        +
        +=item *
        +CRYPTO_THREADID_cpy() duplicates a thread ID value,
        +
        +=item *
        +CRYPTO_THREADID_hash() returns a numeric value usable as a hash-table key. This
        +is usually the exact numeric or pointer-based thread ID used internally, however
        +this also handles the unusual case where pointers are larger than 'long'
        +variables and the platform's thread IDs are pointer-based - in this case, mixing
        +is done to attempt to produce a unique numeric value even though it is not as
        +wide as the platform's true thread IDs.
        +
        +=back
        +
        +Additionally, OpenSSL supports dynamic locks, and sometimes, some parts
        +of OpenSSL need it for better performance.  To enable this, the following
        +is required:
        +
        +=over 4
        +
        +=item *
        +Three additional callback function, dyn_create_function, dyn_lock_function
        +and dyn_destroy_function.
        +
        +=item *
        +A structure defined with the data that each lock needs to handle.
        +
        +=back
        +
        +struct CRYPTO_dynlock_value has to be defined to contain whatever structure
        +is needed to handle locks.
        +
        +dyn_create_function(const char *file, int line) is needed to create a
        +lock.  Multi-threaded applications might crash at random if it is not set.
        +
        +dyn_lock_function(int mode, CRYPTO_dynlock *l, const char *file, int line)
        +is needed to perform locking off dynamic lock numbered n. Multi-threaded
        +applications might crash at random if it is not set.
        +
        +dyn_destroy_function(CRYPTO_dynlock *l, const char *file, int line) is
        +needed to destroy the lock l. Multi-threaded applications might crash at
        +random if it is not set.
        +
        +CRYPTO_get_new_dynlockid() is used to create locks.  It will call
        +dyn_create_function for the actual creation.
        +
        +CRYPTO_destroy_dynlockid() is used to destroy locks.  It will call
        +dyn_destroy_function for the actual destruction.
        +
        +CRYPTO_lock() is used to lock and unlock the locks.  mode is a bitfield
        +describing what should be done with the lock.  n is the number of the
        +lock as returned from CRYPTO_get_new_dynlockid().  mode can be combined
        +from the following values.  These values are pairwise exclusive, with
        +undefined behaviour if misused (for example, CRYPTO_READ and CRYPTO_WRITE
        +should not be used together):
        +
        +	CRYPTO_LOCK	0x01
        +	CRYPTO_UNLOCK	0x02
        +	CRYPTO_READ	0x04
        +	CRYPTO_WRITE	0x08
        +
        +=head1 RETURN VALUES
        +
        +CRYPTO_num_locks() returns the required number of locks.
        +
        +CRYPTO_get_new_dynlockid() returns the index to the newly created lock.
        +
        +The other functions return no values.
        +
        +=head1 NOTES
        +
        +You can find out if OpenSSL was configured with thread support:
        +
        + #define OPENSSL_THREAD_DEFINES
        + #include <openssl/opensslconf.h>
        + #if defined(OPENSSL_THREADS)
        +   // thread support enabled
        + #else
        +   // no thread support
        + #endif
        +
        +Also, dynamic locks are currently not used internally by OpenSSL, but
        +may do so in the future.
        +
        +=head1 EXAMPLES
        +
        +B<crypto/threads/mttest.c> shows examples of the callback functions on
        +Solaris, Irix and Win32.
        +
        +=head1 HISTORY
        +
        +CRYPTO_set_locking_callback() is
        +available in all versions of SSLeay and OpenSSL.
        +CRYPTO_num_locks() was added in OpenSSL 0.9.4.
        +All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev.
        +B<CRYPTO_THREADID> and associated functions were introduced in OpenSSL 1.0.0
        +to replace (actually, deprecate) the previous CRYPTO_set_id_callback(),
        +CRYPTO_get_id_callback(), and CRYPTO_thread_id() functions which assumed
        +thread IDs to always be represented by 'unsigned long'.
        +
        +=head1 SEE ALSO
        +
        +L<crypto(3)|crypto(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ui.pod b/vendor/openssl/openssl/doc/crypto/ui.pod
        new file mode 100644
        index 000000000..6df68d604
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ui.pod
        @@ -0,0 +1,194 @@
        +=pod
        +
        +=head1 NAME
        +
        +UI_new, UI_new_method, UI_free, UI_add_input_string, UI_dup_input_string,
        +UI_add_verify_string, UI_dup_verify_string, UI_add_input_boolean,
        +UI_dup_input_boolean, UI_add_info_string, UI_dup_info_string,
        +UI_add_error_string, UI_dup_error_string, UI_construct_prompt,
        +UI_add_user_data, UI_get0_user_data, UI_get0_result, UI_process,
        +UI_ctrl, UI_set_default_method, UI_get_default_method, UI_get_method,
        +UI_set_method, UI_OpenSSL, ERR_load_UI_strings - New User Interface
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ui.h>
        +
        + typedef struct ui_st UI;
        + typedef struct ui_method_st UI_METHOD;
        +
        + UI *UI_new(void);
        + UI *UI_new_method(const UI_METHOD *method);
        + void UI_free(UI *ui);
        +
        + int UI_add_input_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize);
        + int UI_dup_input_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize);
        + int UI_add_verify_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf);
        + int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
        +	char *result_buf, int minsize, int maxsize, const char *test_buf);
        + int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int flags, char *result_buf);
        + int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
        +	const char *ok_chars, const char *cancel_chars,
        +	int flags, char *result_buf);
        + int UI_add_info_string(UI *ui, const char *text);
        + int UI_dup_info_string(UI *ui, const char *text);
        + int UI_add_error_string(UI *ui, const char *text);
        + int UI_dup_error_string(UI *ui, const char *text);
        +
        + /* These are the possible flags.  They can be or'ed together. */
        + #define UI_INPUT_FLAG_ECHO		0x01
        + #define UI_INPUT_FLAG_DEFAULT_PWD	0x02
        +
        + char *UI_construct_prompt(UI *ui_method,
        +	const char *object_desc, const char *object_name);
        +
        + void *UI_add_user_data(UI *ui, void *user_data);
        + void *UI_get0_user_data(UI *ui);
        +
        + const char *UI_get0_result(UI *ui, int i);
        +
        + int UI_process(UI *ui);
        +
        + int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)());
        + #define UI_CTRL_PRINT_ERRORS		1
        + #define UI_CTRL_IS_REDOABLE		2
        +
        + void UI_set_default_method(const UI_METHOD *meth);
        + const UI_METHOD *UI_get_default_method(void);
        + const UI_METHOD *UI_get_method(UI *ui);
        + const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
        +
        + UI_METHOD *UI_OpenSSL(void);
        +
        +=head1 DESCRIPTION
        +
        +UI stands for User Interface, and is general purpose set of routines to
        +prompt the user for text-based information.  Through user-written methods
        +(see L<ui_create(3)|ui_create(3)>), prompting can be done in any way
        +imaginable, be it plain text prompting, through dialog boxes or from a
        +cell phone.
        +
        +All the functions work through a context of the type UI.  This context
        +contains all the information needed to prompt correctly as well as a
        +reference to a UI_METHOD, which is an ordered vector of functions that
        +carry out the actual prompting.
        +
        +The first thing to do is to create a UI with UI_new() or UI_new_method(),
        +then add information to it with the UI_add or UI_dup functions.  Also,
        +user-defined random data can be passed down to the underlying method
        +through calls to UI_add_user_data.  The default UI method doesn't care
        +about these data, but other methods might.  Finally, use UI_process()
        +to actually perform the prompting and UI_get0_result() to find the result
        +to the prompt.
        +
        +A UI can contain more than one prompt, which are performed in the given
        +sequence.  Each prompt gets an index number which is returned by the
        +UI_add and UI_dup functions, and has to be used to get the corresponding
        +result with UI_get0_result().
        +
        +The functions are as follows:
        +
        +UI_new() creates a new UI using the default UI method.  When done with
        +this UI, it should be freed using UI_free().
        +
        +UI_new_method() creates a new UI using the given UI method.  When done with
        +this UI, it should be freed using UI_free().
        +
        +UI_OpenSSL() returns the built-in UI method (note: not the default one,
        +since the default can be changed.  See further on).  This method is the
        +most machine/OS dependent part of OpenSSL and normally generates the
        +most problems when porting.
        +
        +UI_free() removes a UI from memory, along with all other pieces of memory
        +that's connected to it, like duplicated input strings, results and others.
        +
        +UI_add_input_string() and UI_add_verify_string() add a prompt to the UI,
        +as well as flags and a result buffer and the desired minimum and maximum
        +sizes of the result.  The given information is used to prompt for
        +information, for example a password, and to verify a password (i.e. having
        +the user enter it twice and check that the same string was entered twice).
        +UI_add_verify_string() takes and extra argument that should be a pointer
        +to the result buffer of the input string that it's supposed to verify, or
        +verification will fail.
        +
        +UI_add_input_boolean() adds a prompt to the UI that's supposed to be answered
        +in a boolean way, with a single character for yes and a different character
        +for no.  A set of characters that can be used to cancel the prompt is given
        +as well.  The prompt itself is really divided in two, one part being the
        +descriptive text (given through the I<prompt> argument) and one describing
        +the possible answers (given through the I<action_desc> argument).
        +
        +UI_add_info_string() and UI_add_error_string() add strings that are shown at
        +the same time as the prompt for extra information or to show an error string.
        +The difference between the two is only conceptual.  With the builtin method,
        +there's no technical difference between them.  Other methods may make a
        +difference between them, however.
        +
        +The flags currently supported are UI_INPUT_FLAG_ECHO, which is relevant for
        +UI_add_input_string() and will have the users response be echoed (when
        +prompting for a password, this flag should obviously not be used, and
        +UI_INPUT_FLAG_DEFAULT_PWD, which means that a default password of some
        +sort will be used (completely depending on the application and the UI
        +method).
        +
        +UI_dup_input_string(), UI_dup_verify_string(), UI_dup_input_boolean(),
        +UI_dup_info_string() and UI_dup_error_string() are basically the same
        +as their UI_add counterparts, except that they make their own copies
        +of all strings.
        +
        +UI_construct_prompt() is a helper function that can be used to create
        +a prompt from two pieces of information: an description and a name.
        +The default constructor (if there is none provided by the method used)
        +creates a string "Enter I<description> for I<name>:".  With the
        +description "pass phrase" and the file name "foo.key", that becomes
        +"Enter pass phrase for foo.key:".  Other methods may create whatever
        +string and may include encodings that will be processed by the other
        +method functions.
        +
        +UI_add_user_data() adds a piece of memory for the method to use at any
        +time.  The builtin UI method doesn't care about this info.  Note that several
        +calls to this function doesn't add data, it replaces the previous blob
        +with the one given as argument.
        +
        +UI_get0_user_data() retrieves the data that has last been given to the
        +UI with UI_add_user_data().
        +
        +UI_get0_result() returns a pointer to the result buffer associated with
        +the information indexed by I<i>.
        +
        +UI_process() goes through the information given so far, does all the printing
        +and prompting and returns.
        +
        +UI_ctrl() adds extra control for the application author.  For now, it
        +understands two commands: UI_CTRL_PRINT_ERRORS, which makes UI_process()
        +print the OpenSSL error stack as part of processing the UI, and
        +UI_CTRL_IS_REDOABLE, which returns a flag saying if the used UI can
        +be used again or not.
        +
        +UI_set_default_method() changes the default UI method to the one given.
        +
        +UI_get_default_method() returns a pointer to the current default UI method.
        +
        +UI_get_method() returns the UI method associated with a given UI.
        +
        +UI_set_method() changes the UI method associated with a given UI.
        +
        +=head1 SEE ALSO
        +
        +L<ui_create(3)|ui_create(3)>, L<ui_compat(3)|ui_compat(3)>
        +
        +=head1 HISTORY
        +
        +The UI section was first introduced in OpenSSL 0.9.7.
        +
        +=head1 AUTHOR
        +
        +Richard Levitte (richard@levitte.org) for the OpenSSL project
        +(http://www.openssl.org).
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/ui_compat.pod b/vendor/openssl/openssl/doc/crypto/ui_compat.pod
        new file mode 100644
        index 000000000..adf2ae5e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/ui_compat.pod
        @@ -0,0 +1,57 @@
        +=pod
        +
        +=head1 NAME
        +
        +des_read_password, des_read_2passwords, des_read_pw_string, des_read_pw -
        +Compatibility user interface functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/des_old.h>
        +
        + int des_read_password(DES_cblock *key,const char *prompt,int verify);
        + int des_read_2passwords(DES_cblock *key1,DES_cblock *key2,
        + 	const char *prompt,int verify);
        +
        + int des_read_pw_string(char *buf,int length,const char *prompt,int verify);
        + int des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
        +
        +=head1 DESCRIPTION
        +
        +The DES library contained a few routines to prompt for passwords.  These
        +aren't necessarely dependent on DES, and have therefore become part of the
        +UI compatibility library.
        +
        +des_read_pw() writes the string specified by I<prompt> to standard output
        +turns echo off and reads an input string from the terminal.  The string is
        +returned in I<buf>, which must have spac for at least I<size> bytes.
        +If I<verify> is set, the user is asked for the password twice and unless
        +the two copies match, an error is returned.  The second password is stored
        +in I<buff>, which must therefore also be at least I<size> bytes.  A return
        +code of -1 indicates a system error, 1 failure due to use interaction, and
        +0 is success.  All other functions described here use des_read_pw() to do
        +the work.
        +
        +des_read_pw_string() is a variant of des_read_pw() that provides a buffer
        +for you if I<verify> is set.
        +
        +des_read_password() calls des_read_pw() and converts the password to a
        +DES key by calling DES_string_to_key(); des_read_2password() operates in
        +the same way as des_read_password() except that it generates two keys
        +by using the DES_string_to_2key() function.
        +
        +=head1 NOTES
        +
        +des_read_pw_string() is available in the MIT Kerberos library as well, and
        +is also available under the name EVP_read_pw_string().
        +
        +=head1 SEE ALSO
        +
        +L<ui(3)|ui(3)>, L<ui_create(3)|ui_create(3)>
        +
        +=head1 AUTHOR
        +
        +Richard Levitte (richard@levitte.org) for the OpenSSL project
        +(http://www.openssl.org).
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/crypto/x509.pod b/vendor/openssl/openssl/doc/crypto/x509.pod
        new file mode 100644
        index 000000000..f9e58e0e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/crypto/x509.pod
        @@ -0,0 +1,64 @@
        +=pod
        +
        +=head1 NAME
        +
        +x509 - X.509 certificate handling
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/x509.h>
        +
        +=head1 DESCRIPTION
        +
        +A X.509 certificate is a structured grouping of information about
        +an individual, a device, or anything one can imagine.  A X.509 CRL
        +(certificate revocation list) is a tool to help determine if a
        +certificate is still valid.  The exact definition of those can be
        +found in the X.509 document from ITU-T, or in RFC3280 from PKIX.
        +In OpenSSL, the type X509 is used to express such a certificate, and
        +the type X509_CRL is used to express a CRL.
        +
        +A related structure is a certificate request, defined in PKCS#10 from
        +RSA Security, Inc, also reflected in RFC2896.  In OpenSSL, the type
        +X509_REQ is used to express such a certificate request.
        +
        +To handle some complex parts of a certificate, there are the types
        +X509_NAME (to express a certificate name), X509_ATTRIBUTE (to express
        +a certificate attributes), X509_EXTENSION (to express a certificate
        +extension) and a few more.
        +
        +Finally, there's the supertype X509_INFO, which can contain a CRL, a
        +certificate and a corresponding private key.
        +
        +B<X509_>I<...>, B<d2i_X509_>I<...> and B<i2d_X509_>I<...> handle X.509
        +certificates, with some exceptions, shown below.
        +
        +B<X509_CRL_>I<...>, B<d2i_X509_CRL_>I<...> and B<i2d_X509_CRL_>I<...>
        +handle X.509 CRLs.
        +
        +B<X509_REQ_>I<...>, B<d2i_X509_REQ_>I<...> and B<i2d_X509_REQ_>I<...>
        +handle PKCS#10 certificate requests.
        +
        +B<X509_NAME_>I<...> handle certificate names.
        +
        +B<X509_ATTRIBUTE_>I<...> handle certificate attributes.
        +
        +B<X509_EXTENSION_>I<...> handle certificate extensions.
        +
        +=head1 SEE ALSO
        +
        +L<X509_NAME_ENTRY_get_object(3)|X509_NAME_ENTRY_get_object(3)>,
        +L<X509_NAME_add_entry_by_txt(3)|X509_NAME_add_entry_by_txt(3)>,
        +L<X509_NAME_add_entry_by_NID(3)|X509_NAME_add_entry_by_NID(3)>,
        +L<X509_NAME_print_ex(3)|X509_NAME_print_ex(3)>,
        +L<X509_NAME_new(3)|X509_NAME_new(3)>,
        +L<d2i_X509(3)|d2i_X509(3)>,
        +L<d2i_X509_ALGOR(3)|d2i_X509_ALGOR(3)>,
        +L<d2i_X509_CRL(3)|d2i_X509_CRL(3)>,
        +L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>,
        +L<d2i_X509_REQ(3)|d2i_X509_REQ(3)>,
        +L<d2i_X509_SIG(3)|d2i_X509_SIG(3)>,
        +L<crypto(3)|crypto(3)>,
        +L<x509v3(3)|x509v3(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/fingerprints.txt b/vendor/openssl/openssl/doc/fingerprints.txt
        new file mode 100644
        index 000000000..7d05a8559
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/fingerprints.txt
        @@ -0,0 +1,57 @@
        +                              Fingerprints
        +
        +OpenSSL releases are signed with PGP/GnuPG keys.  You can find the
        +signatures in separate files in the same location you find the
        +distributions themselves.  The normal file name is the same as the
        +distribution file, with '.asc' added.  For example, the signature for
        +the distribution of OpenSSL 0.9.7f, openssl-0.9.7f.tar.gz, is found in
        +the file openssl-0.9.7f.tar.gz.asc.
        +
        +The following is the list of fingerprints for the keys that are
        +currently in use (have been used since summer 2004) to sign OpenSSL
        +distributions:
        +
        +pub   1024D/F709453B 2003-10-20
        +      Key fingerprint = C4CA B749 C34F 7F4C C04F  DAC9 A7AF 9E78 F709 453B
        +uid                  Richard Levitte <richard@levitte.org>
        +uid                  Richard Levitte <levitte@openssl.org>
        +uid                  Richard Levitte <levitte@lp.se>
        +
        +pub   2048R/F295C759 1998-12-13
        +      Key fingerprint = D0 5D 8C 61 6E 27 E6 60  41 EC B1 B8 D5 7E E5 97
        +uid                  Dr S N Henson <shenson@drh-consultancy.demon.co.uk>
        +
        +pub   1024R/49A563D9 1997-02-24
        +      Key fingerprint = 7B 79 19 FA 71 6B 87 25  0E 77 21 E5 52 D9 83 BF
        +uid                  Mark Cox <mjc@redhat.com>
        +uid                  Mark Cox <mark@awe.com>
        +uid                  Mark Cox <mjc@apache.org>
        +
        +pub   1024R/26BB437D 1997-04-28
        +      Key fingerprint = 00 C9 21 8E D1 AB 70 37  DD 67 A2 3A 0A 6F 8D A5
        +uid                  Ralf S. Engelschall <rse@engelschall.com>
        +
        +pub   1024R/9C58A66D 1997-04-03
        +      Key fingerprint = 13 D0 B8 9D 37 30 C3 ED  AC 9C 24 7D 45 8C 17 67
        +uid                  jaenicke@openssl.org
        +uid                  Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>
        +
        +pub   1024D/2118CF83 1998-07-13
        +      Key fingerprint = 7656 55DE 62E3 96FF 2587  EB6C 4F6D E156 2118 CF83
        +uid                  Ben Laurie <ben@thebunker.net>
        +uid                  Ben Laurie <ben@cryptix.org>
        +uid                  Ben Laurie <ben@algroup.co.uk>
        +sub   4096g/1F5143E7 1998-07-13
        +
        +pub   1024R/5A6A9B85 1994-03-22
        +      Key fingerprint = C7 AC 7E AD 56 6A 65 EC  F6 16 66 83 7E 86 68 28
        +uid                  Bodo Moeller <2005@bmoeller.de>
        +uid                  Bodo Moeller <2003@bmoeller.de>
        +uid                  Bodo Moeller <2004@bmoeller.de>
        +uid                  Bodo Moeller <bmoeller@acm.org>
        +uid                  Bodo Moeller <bodo@openssl.org>
        +uid                  Bodo Moeller <bm@ulf.mali.sub.org>
        +uid                  Bodo Moeller <3moeller@informatik.uni-hamburg.de>
        +uid                  Bodo Moeller <Bodo_Moeller@public.uni-hamburg.de>
        +uid                  Bodo Moeller <3moeller@rzdspc5.informatik.uni-hamburg.de>
        +
        diff --git a/vendor/openssl/openssl/doc/openssl-shared.txt b/vendor/openssl/openssl/doc/openssl-shared.txt
        new file mode 100644
        index 000000000..5cf84a054
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/openssl-shared.txt
        @@ -0,0 +1,32 @@
        +The OpenSSL  shared libraries are often installed in a directory like
        +/usr/local/ssl/lib.
        +
        +If this directory is not in a standard system path for dynamic/shared
        +libraries, then you will have problems linking and executing
        +applications that use OpenSSL libraries UNLESS:
        +
        +* you link with static (archive) libraries.  If you are truly
        +  paranoid about security, you should use static libraries.
        +* you use the GNU libtool code during linking
        +  (http://www.gnu.org/software/libtool/libtool.html)
        +* you use pkg-config during linking (this requires that
        +  PKG_CONFIG_PATH includes the path to the OpenSSL shared
        +  library directory), and make use of -R or -rpath.
        +  (http://www.freedesktop.org/software/pkgconfig/)
        +* you specify the system-wide link path via a command such
        +  as crle(1) on Solaris systems.
        +* you add the OpenSSL shared library directory to /etc/ld.so.conf
        +  and run ldconfig(8) on Linux systems.
        +* you define the LD_LIBRARY_PATH, LIBPATH, SHLIB_PATH (HP),
        +  DYLD_LIBRARY_PATH (MacOS X) or PATH (Cygwin and DJGPP)
        +  environment variable and add the OpenSSL shared library
        +  directory to it.
        +
        +One common tool to check the dynamic dependencies of an executable
        +or dynamic library is ldd(1) on most UNIX systems.
        +
        +See any operating system documentation and manpages about shared
        +libraries for your version of UNIX.  The following manpages may be
        +helpful: ld(1), ld.so(1), ld.so.1(1) [Solaris], dld.sl(1) [HP],
        +ldd(1), crle(1) [Solaris], pldd(1) [Solaris], ldconfig(8) [Linux],
        +chatr(1) [HP].
        diff --git a/vendor/openssl/openssl/doc/openssl.txt b/vendor/openssl/openssl/doc/openssl.txt
        new file mode 100644
        index 000000000..f8817b0a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/openssl.txt
        @@ -0,0 +1,1254 @@
        +
        +This is some preliminary documentation for OpenSSL.
        +
        +Contents:
        +
        + OpenSSL X509V3 extension configuration
        + X509V3 Extension code: programmers guide
        + PKCS#12 Library
        +
        +
        +==============================================================================
        +               OpenSSL X509V3 extension configuration
        +==============================================================================
        +
        +OpenSSL X509V3 extension configuration: preliminary documentation.
        +
        +INTRODUCTION.
        +
        +For OpenSSL 0.9.2 the extension code has be considerably enhanced. It is now
        +possible to add and print out common X509 V3 certificate and CRL extensions.
        +
        +BEGINNERS NOTE
        +
        +For most simple applications you don't need to know too much about extensions:
        +the default openssl.cnf values will usually do sensible things.
        +
        +If you want to know more you can initially quickly look through the sections
        +describing how the standard OpenSSL utilities display and add extensions and
        +then the list of supported extensions.
        +
        +For more technical information about the meaning of extensions see:
        +
        +http://www.imc.org/ietf-pkix/
        +http://home.netscape.com/eng/security/certs.html
        +
        +PRINTING EXTENSIONS.
        +
        +Extension values are automatically printed out for supported extensions.
        +
        +openssl x509 -in cert.pem -text
        +openssl crl -in crl.pem -text
        +
        +will give information in the extension printout, for example:
        +
        +        X509v3 extensions:
        +            X509v3 Basic Constraints: 
        +                CA:TRUE
        +            X509v3 Subject Key Identifier: 
        +                73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15
        +            X509v3 Authority Key Identifier: 
        +                keyid:73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15, DirName:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/Email=email@1.address/Email=email@2.address, serial:00
        +            X509v3 Key Usage: 
        +                Certificate Sign, CRL Sign
        +            X509v3 Subject Alternative Name: 
        +                email:email@1.address, email:email@2.address
        +
        +CONFIGURATION FILES.
        +
        +The OpenSSL utilities 'ca' and 'req' can now have extension sections listing
        +which certificate extensions to include. In each case a line:
        +
        +x509_extensions = extension_section
        +
        +indicates which section contains the extensions. In the case of 'req' the
        +extension section is used when the -x509 option is present to create a
        +self signed root certificate.
        +
        +The 'x509' utility also supports extensions when it signs a certificate.
        +The -extfile option is used to set the configuration file containing the
        +extensions. In this case a line with:
        +
        +extensions = extension_section
        +
        +in the nameless (default) section is used. If no such line is included then
        +it uses the default section.
        +
        +You can also add extensions to CRLs: a line
        +
        +crl_extensions = crl_extension_section
        +
        +will include extensions when the -gencrl option is used with the 'ca' utility.
        +You can add any extension to a CRL but of the supported extensions only
        +issuerAltName and authorityKeyIdentifier make any real sense. Note: these are
        +CRL extensions NOT CRL *entry* extensions which cannot currently be generated.
        +CRL entry extensions can be displayed.
        +
        +NB. At this time Netscape Communicator rejects V2 CRLs: to get an old V1 CRL
        +you should not include a crl_extensions line in the configuration file.
        +
        +As with all configuration files you can use the inbuilt environment expansion
        +to allow the values to be passed in the environment. Therefore if you have
        +several extension sections used for different purposes you can have a line:
        +
        +x509_extensions = $ENV::ENV_EXT
        +
        +and set the ENV_EXT environment variable before calling the relevant utility.
        +
        +EXTENSION SYNTAX.
        +
        +Extensions have the basic form:
        +
        +extension_name=[critical,] extension_options
        +
        +the use of the critical option makes the extension critical. Extreme caution
        +should be made when using the critical flag. If an extension is marked
        +as critical then any client that does not understand the extension should
        +reject it as invalid. Some broken software will reject certificates which
        +have *any* critical extensions (these violates PKIX but we have to live
        +with it).
        +
        +There are three main types of extension: string extensions, multi-valued
        +extensions, and raw extensions.
        +
        +String extensions simply have a string which contains either the value itself
        +or how it is obtained.
        +
        +For example:
        +
        +nsComment="This is a Comment"
        +
        +Multi-valued extensions have a short form and a long form. The short form
        +is a list of names and values:
        +
        +basicConstraints=critical,CA:true,pathlen:1
        +
        +The long form allows the values to be placed in a separate section:
        +
        +basicConstraints=critical,@bs_section
        +
        +[bs_section]
        +
        +CA=true
        +pathlen=1
        +
        +Both forms are equivalent. However it should be noted that in some cases the
        +same name can appear multiple times, for example,
        +
        +subjectAltName=email:steve@here,email:steve@there
        +
        +in this case an equivalent long form is:
        +
        +subjectAltName=@alt_section
        +
        +[alt_section]
        +
        +email.1=steve@here
        +email.2=steve@there
        +
        +This is because the configuration file code cannot handle the same name
        +occurring twice in the same section.
        +
        +The syntax of raw extensions is governed by the extension code: it can
        +for example contain data in multiple sections. The correct syntax to
        +use is defined by the extension code itself: check out the certificate
        +policies extension for an example.
        +
        +There are two ways to encode arbitrary extensions.
        +
        +The first way is to use the word ASN1 followed by the extension content
        +using the same syntax as ASN1_generate_nconf(). For example:
        +
        +1.2.3.4=critical,ASN1:UTF8String:Some random data
        +
        +1.2.3.4=ASN1:SEQUENCE:seq_sect
        +
        +[seq_sect]
        +
        +field1 = UTF8:field1
        +field2 = UTF8:field2
        +
        +It is also possible to use the word DER to include arbitrary data in any
        +extension.
        +
        +1.2.3.4=critical,DER:01:02:03:04
        +1.2.3.4=DER:01020304
        +
        +The value following DER is a hex dump of the DER encoding of the extension
        +Any extension can be placed in this form to override the default behaviour.
        +For example:
        +
        +basicConstraints=critical,DER:00:01:02:03
        +
        +WARNING: DER should be used with caution. It is possible to create totally
        +invalid extensions unless care is taken.
        +
        +CURRENTLY SUPPORTED EXTENSIONS.
        +
        +If you aren't sure about extensions then they can be largely ignored: its only
        +when you want to do things like restrict certificate usage when you need to
        +worry about them. 
        +
        +The only extension that a beginner might want to look at is Basic Constraints.
        +If in addition you want to try Netscape object signing the you should also
        +look at Netscape Certificate Type.
        +
        +Literal String extensions.
        +
        +In each case the 'value' of the extension is placed directly in the
        +extension. Currently supported extensions in this category are: nsBaseUrl,
        +nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,
        +nsSslServerName and nsComment.
        +
        +For example:
        +
        +nsComment="This is a test comment"
        +
        +Bit Strings.
        +
        +Bit string extensions just consist of a list of supported bits, currently
        +two extensions are in this category: PKIX keyUsage and the Netscape specific
        +nsCertType.
        +
        +nsCertType (netscape certificate type) takes the flags: client, server, email,
        +objsign, reserved, sslCA, emailCA, objCA.
        +
        +keyUsage (PKIX key usage) takes the flags: digitalSignature, nonRepudiation,
        +keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign,
        +encipherOnly, decipherOnly.
        +
        +For example:
        +
        +nsCertType=server
        +
        +keyUsage=digitalSignature, nonRepudiation
        +
        +Hints on Netscape Certificate Type.
        +
        +Other than Basic Constraints this is the only extension a beginner might
        +want to use, if you want to try Netscape object signing, otherwise it can
        +be ignored.
        +
        +If you want a certificate that can be used just for object signing then:
        +
        +nsCertType=objsign
        +
        +will do the job. If you want to use it as a normal end user and server
        +certificate as well then
        +
        +nsCertType=objsign,email,server
        +
        +is more appropriate. You cannot use a self signed certificate for object
        +signing (well Netscape signtool can but it cheats!) so you need to create
        +a CA certificate and sign an end user certificate with it.
        +
        +Side note: If you want to conform to the Netscape specifications then you
        +should really also set:
        +
        +nsCertType=objCA
        +
        +in the *CA* certificate for just an object signing CA and
        +
        +nsCertType=objCA,emailCA,sslCA
        +
        +for everything. Current Netscape software doesn't enforce this so it can
        +be omitted.
        +
        +Basic Constraints.
        +
        +This is generally the only extension you need to worry about for simple
        +applications. If you want your certificate to be usable as a CA certificate
        +(in addition to an end user certificate) then you set this to:
        +
        +basicConstraints=CA:TRUE
        +
        +if you want to be certain the certificate cannot be used as a CA then do:
        +
        +basicConstraints=CA:FALSE
        +
        +The rest of this section describes more advanced usage.
        +
        +Basic constraints is a multi-valued extension that supports a CA and an
        +optional pathlen option. The CA option takes the values true and false and
        +pathlen takes an integer. Note if the CA option is false the pathlen option
        +should be omitted. 
        +
        +The pathlen parameter indicates the maximum number of CAs that can appear
        +below this one in a chain. So if you have a CA with a pathlen of zero it can
        +only be used to sign end user certificates and not further CAs. This all
        +assumes that the software correctly interprets this extension of course.
        +
        +Examples:
        +
        +basicConstraints=CA:TRUE
        +basicConstraints=critical,CA:TRUE, pathlen:0
        +
        +NOTE: for a CA to be considered valid it must have the CA option set to
        +TRUE. An end user certificate MUST NOT have the CA value set to true.
        +According to PKIX recommendations it should exclude the extension entirely,
        +however some software may require CA set to FALSE for end entity certificates.
        +
        +Extended Key Usage.
        +
        +This extensions consists of a list of usages.
        +
        +These can either be object short names of the dotted numerical form of OIDs.
        +While any OID can be used only certain values make sense. In particular the
        +following PKIX, NS and MS values are meaningful:
        +
        +Value			Meaning
        +-----			-------
        +serverAuth		SSL/TLS Web Server Authentication.
        +clientAuth		SSL/TLS Web Client Authentication.
        +codeSigning		Code signing.
        +emailProtection		E-mail Protection (S/MIME).
        +timeStamping		Trusted Timestamping
        +msCodeInd		Microsoft Individual Code Signing (authenticode)
        +msCodeCom		Microsoft Commercial Code Signing (authenticode)
        +msCTLSign		Microsoft Trust List Signing
        +msSGC			Microsoft Server Gated Crypto
        +msEFS			Microsoft Encrypted File System
        +nsSGC			Netscape Server Gated Crypto
        +
        +For example, under IE5 a CA can be used for any purpose: by including a list
        +of the above usages the CA can be restricted to only authorised uses.
        +
        +Note: software packages may place additional interpretations on certificate 
        +use, in particular some usages may only work for selected CAs. Don't for example
        +expect just including msSGC or nsSGC will automatically mean that a certificate
        +can be used for SGC ("step up" encryption) otherwise anyone could use it.
        +
        +Examples:
        +
        +extendedKeyUsage=critical,codeSigning,1.2.3.4
        +extendedKeyUsage=nsSGC,msSGC
        +
        +Subject Key Identifier.
        +
        +This is really a string extension and can take two possible values. Either
        +a hex string giving details of the extension value to include or the word
        +'hash' which then automatically follow PKIX guidelines in selecting and
        +appropriate key identifier. The use of the hex string is strongly discouraged.
        +
        +Example: subjectKeyIdentifier=hash
        +
        +Authority Key Identifier.
        +
        +The authority key identifier extension permits two options. keyid and issuer:
        +both can take the optional value "always".
        +
        +If the keyid option is present an attempt is made to copy the subject key
        +identifier from the parent certificate. If the value "always" is present
        +then an error is returned if the option fails.
        +
        +The issuer option copies the issuer and serial number from the issuer
        +certificate. Normally this will only be done if the keyid option fails or
        +is not included: the "always" flag will always include the value.
        +
        +Subject Alternative Name.
        +
        +The subject alternative name extension allows various literal values to be
        +included in the configuration file. These include "email" (an email address)
        +"URI" a uniform resource indicator, "DNS" (a DNS domain name), RID (a
        +registered ID: OBJECT IDENTIFIER), IP (and IP address) and otherName.
        +
        +Also the email option include a special 'copy' value. This will automatically
        +include and email addresses contained in the certificate subject name in
        +the extension.
        +
        +otherName can include arbitrary data associated with an OID: the value
        +should be the OID followed by a semicolon and the content in standard
        +ASN1_generate_nconf() format.
        +
        +Examples:
        +
        +subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/
        +subjectAltName=email:my@other.address,RID:1.2.3.4
        +subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
        +
        +Issuer Alternative Name.
        +
        +The issuer alternative name option supports all the literal options of
        +subject alternative name. It does *not* support the email:copy option because
        +that would not make sense. It does support an additional issuer:copy option
        +that will copy all the subject alternative name values from the issuer 
        +certificate (if possible).
        +
        +Example:
        +
        +issuserAltName = issuer:copy
        +
        +Authority Info Access.
        +
        +The authority information access extension gives details about how to access
        +certain information relating to the CA. Its syntax is accessOID;location
        +where 'location' has the same syntax as subject alternative name (except
        +that email:copy is not supported). accessOID can be any valid OID but only
        +certain values are meaningful for example OCSP and caIssuers. OCSP gives the
        +location of an OCSP responder: this is used by Netscape PSM and other software.
        +
        +Example:
        +
        +authorityInfoAccess = OCSP;URI:http://ocsp.my.host/
        +authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html
        +
        +CRL distribution points.
        +
        +This is a multi-valued extension that supports all the literal options of
        +subject alternative name. Of the few software packages that currently interpret
        +this extension most only interpret the URI option.
        +
        +Currently each option will set a new DistributionPoint with the fullName
        +field set to the given value.
        +
        +Other fields like cRLissuer and reasons cannot currently be set or displayed:
        +at this time no examples were available that used these fields.
        +
        +If you see this extension with <UNSUPPORTED> when you attempt to print it out
        +or it doesn't appear to display correctly then let me know, including the
        +certificate (mail me at steve@openssl.org) .
        +
        +Examples:
        +
        +crlDistributionPoints=URI:http://www.myhost.com/myca.crl
        +crlDistributionPoints=URI:http://www.my.com/my.crl,URI:http://www.oth.com/my.crl
        +
        +Certificate Policies.
        +
        +This is a RAW extension. It attempts to display the contents of this extension:
        +unfortunately this extension is often improperly encoded.
        +
        +The certificate policies extension will rarely be used in practice: few
        +software packages interpret it correctly or at all. IE5 does partially
        +support this extension: but it needs the 'ia5org' option because it will
        +only correctly support a broken encoding. Of the options below only the
        +policy OID, explicitText and CPS options are displayed with IE5.
        +
        +All the fields of this extension can be set by using the appropriate syntax.
        +
        +If you follow the PKIX recommendations of not including any qualifiers and just
        +using only one OID then you just include the value of that OID. Multiple OIDs
        +can be set separated by commas, for example:
        +
        +certificatePolicies= 1.2.4.5, 1.1.3.4
        +
        +If you wish to include qualifiers then the policy OID and qualifiers need to
        +be specified in a separate section: this is done by using the @section syntax
        +instead of a literal OID value.
        +
        +The section referred to must include the policy OID using the name
        +policyIdentifier, cPSuri qualifiers can be included using the syntax:
        +
        +CPS.nnn=value
        +
        +userNotice qualifiers can be set using the syntax:
        +
        +userNotice.nnn=@notice
        +
        +The value of the userNotice qualifier is specified in the relevant section.
        +This section can include explicitText, organization and noticeNumbers
        +options. explicitText and organization are text strings, noticeNumbers is a
        +comma separated list of numbers. The organization and noticeNumbers options
        +(if included) must BOTH be present. If you use the userNotice option with IE5
        +then you need the 'ia5org' option at the top level to modify the encoding:
        +otherwise it will not be interpreted properly.
        +
        +Example:
        +
        +certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect
        +
        +[polsect]
        +
        +policyIdentifier = 1.3.5.8
        +CPS.1="http://my.host.name/"
        +CPS.2="http://my.your.name/"
        +userNotice.1=@notice
        +
        +[notice]
        +
        +explicitText="Explicit Text Here"
        +organization="Organisation Name"
        +noticeNumbers=1,2,3,4
        +
        +TECHNICAL NOTE: the ia5org option changes the type of the 'organization' field,
        +according to PKIX it should be of type DisplayText but Verisign uses an 
        +IA5STRING and IE5 needs this too.
        +
        +Display only extensions.
        +
        +Some extensions are only partially supported and currently are only displayed
        +but cannot be set. These include private key usage period, CRL number, and
        +CRL reason.
        +
        +==============================================================================
        +		X509V3 Extension code: programmers guide
        +==============================================================================
        +
        +The purpose of the extension code is twofold. It allows an extension to be
        +created from a string or structure describing its contents and it prints out an
        +extension in a human or machine readable form.
        +
        +1. Initialisation and cleanup.
        +
        +No special initialisation is needed before calling the extension functions.
        +You used to have to call X509V3_add_standard_extensions(); but this is no longer
        +required and this function no longer does anything.
        +
        +void X509V3_EXT_cleanup(void);
        +
        +This function should be called to cleanup the extension code if any custom
        +extensions have been added. If no custom extensions have been added then this
        +call does nothing. After this call all custom extension code is freed up but
        +you can still use the standard extensions.
        +
        +2. Printing and parsing extensions.
        +
        +The simplest way to print out extensions is via the standard X509 printing
        +routines: if you use the standard X509_print() function, the supported
        +extensions will be printed out automatically.
        +
        +The following functions allow finer control over extension display:
        +
        +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent);
        +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
        +
        +These two functions print out an individual extension to a BIO or FILE pointer.
        +Currently the flag argument is unused and should be set to 0. The 'indent'
        +argument is the number of spaces to indent each line.
        +
        +void *X509V3_EXT_d2i(X509_EXTENSION *ext);
        +
        +This function parses an extension and returns its internal structure. The
        +precise structure you get back depends on the extension being parsed. If the
        +extension if basicConstraints you will get back a pointer to a
        +BASIC_CONSTRAINTS structure. Check out the source in crypto/x509v3 for more
        +details about the structures returned. The returned structure should be freed
        +after use using the relevant free function, BASIC_CONSTRAINTS_free() for 
        +example.
        +
        +void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
        +void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
        +void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
        +void 	*	X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
        +
        +These functions combine the operations of searching for extensions and
        +parsing them. They search a certificate, a CRL a CRL entry or a stack
        +of extensions respectively for extension whose NID is 'nid' and return
        +the parsed result of NULL if an error occurred. For example:
        +
        +BASIC_CONSTRAINTS *bs;
        +bs = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
        +
        +This will search for the basicConstraints extension and either return
        +it value or NULL. NULL can mean either the extension was not found, it
        +occurred more than once or it could not be parsed.
        +
        +If 'idx' is NULL then an extension is only parsed if it occurs precisely
        +once. This is standard behaviour because extensions normally cannot occur
        +more than once. If however more than one extension of the same type can
        +occur it can be used to parse successive extensions for example:
        +
        +int i;
        +void *ext;
        +
        +i = -1;
        +for(;;) {
        +	ext = X509_get_ext_d2i(x, nid, crit, &idx);
        +	if(ext == NULL) break;
        +	 /* Do something with ext */
        +}
        +
        +If 'crit' is not NULL and the extension was found then the int it points to
        +is set to 1 for critical extensions and 0 for non critical. Therefore if the
        +function returns NULL but 'crit' is set to 0 or 1 then the extension was
        +found but it could not be parsed.
        +
        +The int pointed to by crit will be set to -1 if the extension was not found
        +and -2 if the extension occurred more than once (this will only happen if
        +idx is NULL). In both cases the function will return NULL.
        +
        +3. Generating extensions.
        +
        +An extension will typically be generated from a configuration file, or some
        +other kind of configuration database.
        +
        +int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
        +								 X509 *cert);
        +int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
        +								 X509_CRL *crl);
        +
        +These functions add all the extensions in the given section to the given
        +certificate or CRL. They will normally be called just before the certificate
        +or CRL is due to be signed. Both return 0 on error on non zero for success.
        +
        +In each case 'conf' is the LHASH pointer of the configuration file to use
        +and 'section' is the section containing the extension details.
        +
        +See the 'context functions' section for a description of the ctx parameter.
        +
        +
        +X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
        +								 char *value);
        +
        +This function returns an extension based on a name and value pair, if the
        +pair will not need to access other sections in a config file (or there is no
        +config file) then the 'conf' parameter can be set to NULL.
        +
        +X509_EXTENSION *X509V3_EXT_conf_nid(char *conf, X509V3_CTX *ctx, int nid,
        +								 char *value);
        +
        +This function creates an extension in the same way as X509V3_EXT_conf() but
        +takes the NID of the extension rather than its name.
        +
        +For example to produce basicConstraints with the CA flag and a path length of
        +10:
        +
        +x = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,"CA:TRUE,pathlen:10");
        +
        +
        +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
        +
        +This function sets up an extension from its internal structure. The ext_nid
        +parameter is the NID of the extension and 'crit' is the critical flag.
        +
        +4. Context functions.
        +
        +The following functions set and manipulate an extension context structure.
        +The purpose of the extension context is to allow the extension code to
        +access various structures relating to the "environment" of the certificate:
        +for example the issuers certificate or the certificate request.
        +
        +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
        +                                 X509_REQ *req, X509_CRL *crl, int flags);
        +
        +This function sets up an X509V3_CTX structure with details of the certificate
        +environment: specifically the issuers certificate, the subject certificate,
        +the certificate request and the CRL: if these are not relevant or not
        +available then they can be set to NULL. The 'flags' parameter should be set
        +to zero.
        +
        +X509V3_set_ctx_test(ctx)
        +
        +This macro is used to set the 'ctx' structure to a 'test' value: this is to
        +allow the syntax of an extension (or configuration file) to be tested.
        +
        +X509V3_set_ctx_nodb(ctx)
        +
        +This macro is used when no configuration database is present.
        +
        +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
        +
        +This function is used to set the configuration database when it is an LHASH
        +structure: typically a configuration file.
        +
        +The following functions are used to access a configuration database: they
        +should only be used in RAW extensions.
        +
        +char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
        +
        +This function returns the value of the parameter "name" in "section", or NULL
        +if there has been an error.
        +
        +void X509V3_string_free(X509V3_CTX *ctx, char *str);
        +
        +This function frees up the string returned by the above function.
        +
        +STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
        +
        +This function returns a whole section as a STACK_OF(CONF_VALUE) .
        +
        +void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
        +
        +This function frees up the STACK returned by the above function.
        +
        +Note: it is possible to use the extension code with a custom configuration
        +database. To do this the "db_meth" element of the X509V3_CTX structure should
        +be set to an X509V3_CTX_METHOD structure. This structure contains the following
        +function pointers:
        +
        +char * (*get_string)(void *db, char *section, char *value);
        +STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
        +void (*free_string)(void *db, char * string);
        +void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
        +
        +these will be called and passed the 'db' element in the X509V3_CTX structure
        +to access the database. If a given function is not implemented or not required
        +it can be set to NULL.
        +
        +5. String helper functions.
        +
        +There are several "i2s" and "s2i" functions that convert structures to and
        +from ASCII strings. In all the "i2s" cases the returned string should be
        +freed using Free() after use. Since some of these are part of other extension
        +code they may take a 'method' parameter. Unless otherwise stated it can be
        +safely set to NULL.
        +
        +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct);
        +
        +This returns a hex string from an ASN1_OCTET_STRING.
        +
        +char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
        +char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
        +
        +These return a string decimal representations of an ASN1_INTEGER and an
        +ASN1_ENUMERATED type, respectively.
        +
        +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
        +                                                   X509V3_CTX *ctx, char *str);
        +
        +This converts an ASCII hex string to an ASN1_OCTET_STRING.
        +
        +ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
        +
        +This converts a decimal ASCII string into an ASN1_INTEGER.
        +
        +6. Multi valued extension helper functions.
        +
        +The following functions can be used to manipulate STACKs of CONF_VALUE
        +structures, as used by multi valued extensions.
        +
        +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
        +
        +This function expects a boolean value in 'value' and sets 'asn1_bool' to
        +it. That is it sets it to 0 for FALSE or 0xff for TRUE. The following
        +strings are acceptable: "TRUE", "true", "Y", "y", "YES", "yes", "FALSE"
        +"false", "N", "n", "NO" or "no".
        +
        +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
        +
        +This accepts a decimal integer of arbitrary length and sets an ASN1_INTEGER.
        +
        +int X509V3_add_value(const char *name, const char *value,
        +						STACK_OF(CONF_VALUE) **extlist);
        +
        +This simply adds a string name and value pair.
        +
        +int X509V3_add_value_uchar(const char *name, const unsigned char *value,
        +                          			STACK_OF(CONF_VALUE) **extlist);
        +
        +The same as above but for an unsigned character value.
        +
        +int X509V3_add_value_bool(const char *name, int asn1_bool,
        +						STACK_OF(CONF_VALUE) **extlist);
        +
        +This adds either "TRUE" or "FALSE" depending on the value of 'asn1_bool'
        +
        +int X509V3_add_value_bool_nf(char *name, int asn1_bool,
        +						STACK_OF(CONF_VALUE) **extlist);
        +
        +This is the same as above except it adds nothing if asn1_bool is FALSE.
        +
        +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
        +						STACK_OF(CONF_VALUE) **extlist);
        +
        +This function adds the value of the ASN1_INTEGER in decimal form.
        +
        +7. Other helper functions.
        +
        +<to be added>
        +
        +ADDING CUSTOM EXTENSIONS.
        +
        +Currently there are three types of supported extensions. 
        +
        +String extensions are simple strings where the value is placed directly in the
        +extensions, and the string returned is printed out.
        +
        +Multi value extensions are passed a STACK_OF(CONF_VALUE) name and value pairs
        +or return a STACK_OF(CONF_VALUE).
        +
        +Raw extensions are just passed a BIO or a value and it is the extensions
        +responsibility to handle all the necessary printing.
        +
        +There are two ways to add an extension. One is simply as an alias to an already
        +existing extension. An alias is an extension that is identical in ASN1 structure
        +to an existing extension but has a different OBJECT IDENTIFIER. This can be
        +done by calling:
        +
        +int X509V3_EXT_add_alias(int nid_to, int nid_from);
        +
        +'nid_to' is the new extension NID and 'nid_from' is the already existing
        +extension NID.
        +
        +Alternatively an extension can be written from scratch. This involves writing
        +the ASN1 code to encode and decode the extension and functions to print out and
        +generate the extension from strings. The relevant functions are then placed in
        +a X509V3_EXT_METHOD structure and int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
        +called.
        +
        +The X509V3_EXT_METHOD structure is described below.
        +
        +struct {
        +int ext_nid;
        +int ext_flags;
        +X509V3_EXT_NEW ext_new;
        +X509V3_EXT_FREE ext_free;
        +X509V3_EXT_D2I d2i;
        +X509V3_EXT_I2D i2d;
        +X509V3_EXT_I2S i2s;
        +X509V3_EXT_S2I s2i;
        +X509V3_EXT_I2V i2v;
        +X509V3_EXT_V2I v2i;
        +X509V3_EXT_R2I r2i;
        +X509V3_EXT_I2R i2r;
        +
        +void *usr_data;
        +};
        +
        +The elements have the following meanings.
        +
        +ext_nid		is the NID of the object identifier of the extension.
        +
        +ext_flags	is set of flags. Currently the only external flag is
        +		X509V3_EXT_MULTILINE which means a multi valued extensions
        +		should be printed on separate lines.
        +
        +usr_data	is an extension specific pointer to any relevant data. This
        +		allows extensions to share identical code but have different
        +		uses. An example of this is the bit string extension which uses
        +		usr_data to contain a list of the bit names.
        +
        +All the remaining elements are function pointers.
        +
        +ext_new		is a pointer to a function that allocates memory for the
        +		extension ASN1 structure: for example ASN1_OBJECT_new().
        +
        +ext_free	is a pointer to a function that free up memory of the extension
        +		ASN1 structure: for example ASN1_OBJECT_free().
        +
        +d2i		is the standard ASN1 function that converts a DER buffer into
        +		the internal ASN1 structure: for example d2i_ASN1_IA5STRING().
        +
        +i2d		is the standard ASN1 function that converts the internal
        +		structure into the DER representation: for example
        +		i2d_ASN1_IA5STRING().
        +
        +The remaining functions are depend on the type of extension. One i2X and
        +one X2i should be set and the rest set to NULL. The types set do not need
        +to match up, for example the extension could be set using the multi valued
        +v2i function and printed out using the raw i2r.
        +
        +All functions have the X509V3_EXT_METHOD passed to them in the 'method'
        +parameter and an X509V3_CTX structure. Extension code can then access the
        +parent structure via the 'method' parameter to for example make use of the value
        +of usr_data. If the code needs to use detail relating to the request it can
        +use the 'ctx' parameter.
        +
        +A note should be given here about the 'flags' member of the 'ctx' parameter.
        +If it has the value CTX_TEST then the configuration syntax is being checked
        +and no actual certificate or CRL exists. Therefore any attempt in the config
        +file to access such information should silently succeed. If the syntax is OK
        +then it should simply return a (possibly bogus) extension, otherwise it
        +should return NULL.
        +
        +char *i2s(struct v3_ext_method *method, void *ext);
        +
        +This function takes the internal structure in the ext parameter and returns
        +a Malloc'ed string representing its value.
        +
        +void * s2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
        +
        +This function takes the string representation in the ext parameter and returns
        +an allocated internal structure: ext_free() will be used on this internal
        +structure after use.
        +
        +i2v and v2i handle a STACK_OF(CONF_VALUE):
        +
        +typedef struct
        +{
        +        char *section;
        +        char *name;
        +        char *value;
        +} CONF_VALUE;
        +
        +Only the name and value members are currently used.
        +
        +STACK_OF(CONF_VALUE) * i2v(struct v3_ext_method *method, void *ext);
        +
        +This function is passed the internal structure in the ext parameter and
        +returns a STACK of CONF_VALUE structures. The values of name, value,
        +section and the structure itself will be freed up with Free after use.
        +Several helper functions are available to add values to this STACK.
        +
        +void * v2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx,
        +						STACK_OF(CONF_VALUE) *values);
        +
        +This function takes a STACK_OF(CONF_VALUE) structures and should set the
        +values of the external structure. This typically uses the name element to
        +determine which structure element to set and the value element to determine
        +what to set it to. Several helper functions are available for this
        +purpose (see above).
        +
        +int i2r(struct v3_ext_method *method, void *ext, BIO *out, int indent);
        +
        +This function is passed the internal extension structure in the ext parameter
        +and sends out a human readable version of the extension to out. The 'indent'
        +parameter should be noted to determine the necessary amount of indentation
        +needed on the output.
        +
        +void * r2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
        +
        +This is just passed the string representation of the extension. It is intended
        +to be used for more elaborate extensions where the standard single and multi
        +valued options are insufficient. They can use the 'ctx' parameter to parse the
        +configuration database themselves. See the context functions section for details
        +of how to do this.
        +
        +Note: although this type takes the same parameters as the "r2s" function there
        +is a subtle difference. Whereas an "r2i" function can access a configuration
        +database an "s2i" function MUST NOT. This is so the internal code can safely
        +assume that an "s2i" function will work without a configuration database.
        +
        +==============================================================================
        +                            PKCS#12 Library
        +==============================================================================
        +
        +This section describes the internal PKCS#12 support. There are very few
        +differences between the old external library and the new internal code at
        +present. This may well change because the external library will not be updated
        +much in future.
        +
        +This version now includes a couple of high level PKCS#12 functions which
        +generally "do the right thing" and should make it much easier to handle PKCS#12
        +structures.
        +
        +HIGH LEVEL FUNCTIONS.
        +
        +For most applications you only need concern yourself with the high level
        +functions. They can parse and generate simple PKCS#12 files as produced by
        +Netscape and MSIE or indeed any compliant PKCS#12 file containing a single
        +private key and certificate pair.
        +
        +1. Initialisation and cleanup.
        +
        +No special initialisation is needed for the internal PKCS#12 library: the 
        +standard SSLeay_add_all_algorithms() is sufficient. If you do not wish to
        +add all algorithms (you should at least add SHA1 though) then you can manually
        +initialise the PKCS#12 library with:
        +
        +PKCS12_PBE_add();
        +
        +The memory allocated by the PKCS#12 library is freed up when EVP_cleanup() is
        +called or it can be directly freed with:
        +
        +EVP_PBE_cleanup();
        +
        +after this call (or EVP_cleanup() ) no more PKCS#12 library functions should
        +be called.
        +
        +2. I/O functions.
        +
        +i2d_PKCS12_bio(bp, p12)
        +
        +This writes out a PKCS12 structure to a BIO.
        +
        +i2d_PKCS12_fp(fp, p12)
        +
        +This is the same but for a FILE pointer.
        +
        +d2i_PKCS12_bio(bp, p12)
        +
        +This reads in a PKCS12 structure from a BIO.
        +
        +d2i_PKCS12_fp(fp, p12)
        +
        +This is the same but for a FILE pointer.
        +
        +3. High level functions.
        +
        +3.1 Parsing with PKCS12_parse().
        +
        +int PKCS12_parse(PKCS12 *p12, char *pass, EVP_PKEY **pkey, X509 **cert,
        +								 STACK **ca);
        +
        +This function takes a PKCS12 structure and a password (ASCII, null terminated)
        +and returns the private key, the corresponding certificate and any CA
        +certificates. If any of these is not required it can be passed as a NULL.
        +The 'ca' parameter should be either NULL, a pointer to NULL or a valid STACK
        +structure. Typically to read in a PKCS#12 file you might do:
        +
        +p12 = d2i_PKCS12_fp(fp, NULL);
        +PKCS12_parse(p12, password, &pkey, &cert, NULL); 	/* CAs not wanted */
        +PKCS12_free(p12);
        +
        +3.2 PKCS#12 creation with PKCS12_create().
        +
        +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
        +			STACK *ca, int nid_key, int nid_cert, int iter,
        +						 int mac_iter, int keytype);
        +
        +This function will create a PKCS12 structure from a given password, name,
        +private key, certificate and optional STACK of CA certificates. The remaining
        +5 parameters can be set to 0 and sensible defaults will be used.
        +
        +The parameters nid_key and nid_cert are the key and certificate encryption
        +algorithms, iter is the encryption iteration count, mac_iter is the MAC
        +iteration count and keytype is the type of private key. If you really want
        +to know what these last 5 parameters do then read the low level section.
        +
        +Typically to create a PKCS#12 file the following could be used:
        +
        +p12 = PKCS12_create(pass, "My Certificate", pkey, cert, NULL, 0,0,0,0,0);
        +i2d_PKCS12_fp(fp, p12);
        +PKCS12_free(p12);
        +
        +3.3 Changing a PKCS#12 structure password.
        +
        +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
        +
        +This changes the password of an already existing PKCS#12 structure. oldpass
        +is the old password and newpass is the new one. An error occurs if the old
        +password is incorrect.
        +
        +LOW LEVEL FUNCTIONS.
        +
        +In some cases the high level functions do not provide the necessary
        +functionality. For example if you want to generate or parse more complex
        +PKCS#12 files. The sample pkcs12 application uses the low level functions
        +to display details about the internal structure of a PKCS#12 file.
        +
        +Introduction.
        +
        +This is a brief description of how a PKCS#12 file is represented internally:
        +some knowledge of PKCS#12 is assumed.
        +
        +A PKCS#12 object contains several levels.
        +
        +At the lowest level is a PKCS12_SAFEBAG. This can contain a certificate, a
        +CRL, a private key, encrypted or unencrypted, a set of safebags (so the
        +structure can be nested) or other secrets (not documented at present). 
        +A safebag can optionally have attributes, currently these are: a unicode
        +friendlyName (a Unicode string) or a localKeyID (a string of bytes).
        +
        +At the next level is an authSafe which is a set of safebags collected into
        +a PKCS#7 ContentInfo. This can be just plain data, or encrypted itself.
        +
        +At the top level is the PKCS12 structure itself which contains a set of
        +authSafes in an embedded PKCS#7 Contentinfo of type data. In addition it
        +contains a MAC which is a kind of password protected digest to preserve
        +integrity (so any unencrypted stuff below can't be tampered with).
        +
        +The reason for these levels is so various objects can be encrypted in various
        +ways. For example you might want to encrypt a set of private keys with
        +triple-DES and then include the related certificates either unencrypted or
        +with lower encryption. Yes it's the dreaded crypto laws at work again which
        +allow strong encryption on private keys and only weak encryption on other
        +stuff.
        +
        +To build one of these things you turn all certificates and keys into safebags
        +(with optional attributes). You collect the safebags into (one or more) STACKS
        +and convert these into authsafes (encrypted or unencrypted).  The authsafes
        +are collected into a STACK and added to a PKCS12 structure.  Finally a MAC
        +inserted.
        +
        +Pulling one apart is basically the reverse process. The MAC is verified against
        +the given password. The authsafes are extracted and each authsafe split into
        +a set of safebags (possibly involving decryption). Finally the safebags are
        +decomposed into the original keys and certificates and the attributes used to
        +match up private key and certificate pairs.
        +
        +Anyway here are the functions that do the dirty work.
        +
        +1. Construction functions.
        +
        +1.1 Safebag functions.
        +
        +M_PKCS12_x5092certbag(x509)
        +
        +This macro takes an X509 structure and returns a certificate bag. The
        +X509 structure can be freed up after calling this function.
        +
        +M_PKCS12_x509crl2certbag(crl)
        +
        +As above but for a CRL.
        +
        +PKCS8_PRIV_KEY_INFO *PKEY2PKCS8(EVP_PKEY *pkey)
        +
        +Take a private key and convert it into a PKCS#8 PrivateKeyInfo structure.
        +Works for both RSA and DSA private keys. NB since the PKCS#8 PrivateKeyInfo
        +structure contains a private key data in plain text form it should be free'd
        +up as soon as it has been encrypted for security reasons (freeing up the
        +structure zeros out the sensitive data). This can be done with
        +PKCS8_PRIV_KEY_INFO_free().
        +
        +PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
        +
        +This sets the key type when a key is imported into MSIE or Outlook 98. Two
        +values are currently supported: KEY_EX and KEY_SIG. KEY_EX is an exchange type
        +key that can also be used for signing but its size is limited in the export
        +versions of MS software to 512 bits, it is also the default. KEY_SIG is a
        +signing only key but the keysize is unlimited (well 16K is supposed to work).
        +If you are using the domestic version of MSIE then you can ignore this because
        +KEY_EX is not limited and can be used for both.
        +
        +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
        +
        +Convert a PKCS8 private key structure into a keybag. This routine embeds the
        +p8 structure in the keybag so p8 should not be freed up or used after it is
        +called.  The p8 structure will be freed up when the safebag is freed.
        +
        +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8)
        +
        +Convert a PKCS#8 structure into a shrouded key bag (encrypted). p8 is not
        +embedded and can be freed up after use.
        +
        +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
        +int PKCS12_add_friendlyname(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
        +
        +Add a local key id or a friendlyname to a safebag.
        +
        +1.2 Authsafe functions.
        +
        +PKCS7 *PKCS12_pack_p7data(STACK *sk)
        +Take a stack of safebags and convert them into an unencrypted authsafe. The
        +stack of safebags can be freed up after calling this function.
        +
        +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK *bags);
        +
        +As above but encrypted.
        +
        +1.3 PKCS12 functions.
        +
        +PKCS12 *PKCS12_init(int mode)
        +
        +Initialise a PKCS12 structure (currently mode should be NID_pkcs7_data).
        +
        +M_PKCS12_pack_authsafes(p12, safes)
        +
        +This macro takes a STACK of authsafes and adds them to a PKCS#12 structure.
        +
        +int PKCS12_set_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_MD *md_type);
        +
        +Add a MAC to a PKCS12 structure. If EVP_MD is NULL use SHA-1, the spec suggests
        +that SHA-1 should be used.
        +
        +2. Extraction Functions.
        +
        +2.1 Safebags.
        +
        +M_PKCS12_bag_type(bag)
        +
        +Return the type of "bag". Returns one of the following
        +
        +NID_keyBag
        +NID_pkcs8ShroudedKeyBag			7
        +NID_certBag				8
        +NID_crlBag				9
        +NID_secretBag				10
        +NID_safeContentsBag			11
        +
        +M_PKCS12_cert_bag_type(bag)
        +
        +Returns type of certificate bag, following are understood.
        +
        +NID_x509Certificate			14
        +NID_sdsiCertificate			15
        +
        +M_PKCS12_crl_bag_type(bag)
        +
        +Returns crl bag type, currently only NID_crlBag is recognised.
        +
        +M_PKCS12_certbag2x509(bag)
        +
        +This macro extracts an X509 certificate from a certificate bag.
        +
        +M_PKCS12_certbag2x509crl(bag)
        +
        +As above but for a CRL.
        +
        +EVP_PKEY * PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
        +
        +Extract a private key from a PKCS8 private key info structure.
        +
        +M_PKCS12_decrypt_skey(bag, pass, passlen) 
        +
        +Decrypt a shrouded key bag and return a PKCS8 private key info structure.
        +Works with both RSA and DSA keys
        +
        +char *PKCS12_get_friendlyname(bag)
        +
        +Returns the friendlyName of a bag if present or NULL if none. The returned
        +string is a null terminated ASCII string allocated with Malloc(). It should 
        +thus be freed up with Free() after use.
        +
        +2.2 AuthSafe functions.
        +
        +M_PKCS12_unpack_p7data(p7)
        +
        +Extract a STACK of safe bags from a PKCS#7 data ContentInfo.
        +
        +#define M_PKCS12_unpack_p7encdata(p7, pass, passlen)
        +
        +As above but for an encrypted content info.
        +
        +2.3 PKCS12 functions.
        +
        +M_PKCS12_unpack_authsafes(p12)
        +
        +Extract a STACK of authsafes from a PKCS12 structure.
        +
        +M_PKCS12_mac_present(p12)
        +
        +Check to see if a MAC is present.
        +
        +int PKCS12_verify_mac(PKCS12 *p12, unsigned char *pass, int passlen)
        +
        +Verify a MAC on a PKCS12 structure. Returns an error if MAC not present.
        +
        +
        +Notes.
        +
        +1. All the function return 0 or NULL on error.
        +2. Encryption based functions take a common set of parameters. These are
        +described below.
        +
        +pass, passlen
        +ASCII password and length. The password on the MAC is called the "integrity
        +password" the encryption password is called the "privacy password" in the
        +PKCS#12 documentation. The passwords do not have to be the same. If -1 is
        +passed for the length it is worked out by the function itself (currently
        +this is sometimes done whatever is passed as the length but that may change).
        +
        +salt, saltlen
        +A 'salt' if salt is NULL a random salt is used. If saltlen is also zero a
        +default length is used.
        +
        +iter
        +Iteration count. This is a measure of how many times an internal function is
        +called to encrypt the data. The larger this value is the longer it takes, it
        +makes dictionary attacks on passwords harder. NOTE: Some implementations do
        +not support an iteration count on the MAC. If the password for the MAC and
        +encryption is the same then there is no point in having a high iteration
        +count for encryption if the MAC has no count. The MAC could be attacked
        +and the password used for the main decryption.
        +
        +pbe_nid
        +This is the NID of the password based encryption method used. The following are
        +supported.
        +NID_pbe_WithSHA1And128BitRC4
        +NID_pbe_WithSHA1And40BitRC4
        +NID_pbe_WithSHA1And3_Key_TripleDES_CBC
        +NID_pbe_WithSHA1And2_Key_TripleDES_CBC
        +NID_pbe_WithSHA1And128BitRC2_CBC
        +NID_pbe_WithSHA1And40BitRC2_CBC
        +
        +Which you use depends on the implementation you are exporting to. "Export
        +grade" (i.e. cryptographically challenged) products cannot support all
        +algorithms. Typically you may be able to use any encryption on shrouded key
        +bags but they must then be placed in an unencrypted authsafe. Other authsafes
        +may only support 40bit encryption. Of course if you are using SSLeay
        +throughout you can strongly encrypt everything and have high iteration counts
        +on everything.
        +
        +3. For decryption routines only the password and length are needed.
        +
        +4. Unlike the external version the nid's of objects are the values of the
        +constants: that is NID_certBag is the real nid, therefore there is no 
        +PKCS12_obj_offset() function.  Note the object constants are not the same as
        +those of the external version. If you use these constants then you will need
        +to recompile your code.
        +
        +5. With the exception of PKCS12_MAKE_KEYBAG(), after calling any function or 
        +macro of the form PKCS12_MAKE_SOMETHING(other) the "other" structure can be
        +reused or freed up safely.
        +
        diff --git a/vendor/openssl/openssl/doc/openssl_button.gif b/vendor/openssl/openssl/doc/openssl_button.gif
        new file mode 100644
        index 000000000..3d3c90c9f
        Binary files /dev/null and b/vendor/openssl/openssl/doc/openssl_button.gif differ
        diff --git a/vendor/openssl/openssl/doc/openssl_button.html b/vendor/openssl/openssl/doc/openssl_button.html
        new file mode 100644
        index 000000000..44c91bd3d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/openssl_button.html
        @@ -0,0 +1,7 @@
        +
        +<!-- the `Includes OpenSSL Cryptogaphy Software' button      -->
        +<!-- freely usable by any application linked against OpenSSL -->
        +<a   href="http://www.openssl.org/">
        +<img src="openssl_button.gif" 
        +     width=102 height=47 border=0></a>
        +
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CIPHER_get_name.pod b/vendor/openssl/openssl/doc/ssl/SSL_CIPHER_get_name.pod
        new file mode 100644
        index 000000000..eb772b55d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CIPHER_get_name.pod
        @@ -0,0 +1,112 @@
        +=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 <openssl/ssl.h>
        +
        + const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
        + int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *alg_bits);
        + char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
        + char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int size);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CIPHER_get_name() returns a pointer to the name of B<cipher>. 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<cipher>. If
        +B<alg_bits> is not NULL, it contains the number of bits processed by the
        +chosen algorithm. If B<cipher> is NULL, 0 is returned.
        +
        +SSL_CIPHER_get_version() returns the protocol version for B<cipher>, currently
        +"SSLv2", "SSLv3", or "TLSv1". If B<cipher> is NULL, "(NONE)" is returned.
        +
        +SSL_CIPHER_description() returns a textual description of the cipher used
        +into the buffer B<buf> of length B<len> provided. B<len> must be at least
        +128 bytes, otherwise a pointer to the string "Buffer too small" is
        +returned. If B<buf> is NULL, a buffer of 128 bytes is allocated using
        +OPENSSL_malloc(). If the allocation fails, a pointer to 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<alg_bits>), of
        +which however 88bits are fixed. The search space is hence only 40 bits.
        +
        +The string returned by SSL_CIPHER_description() in case of success consists
        +of cleartext information separated by one or more blanks in the following
        +sequence:
        +
        +=over 4
        +
        +=item <ciphername>
        +
        +Textual representation of the cipher name.
        +
        +=item <protocol version>
        +
        +Protocol version: B<SSLv2>, B<SSLv3>. The TLSv1 ciphers are flagged with SSLv3.
        +
        +=item Kx=<key exchange>
        +
        +Key exchange method: B<RSA> (for export ciphers as B<RSA(512)> or
        +B<RSA(1024)>), B<DH> (for export ciphers as B<DH(512)> or B<DH(1024)>),
        +B<DH/RSA>, B<DH/DSS>, B<Fortezza>.
        +
        +=item Au=<authentication>
        +
        +Authentication method: B<RSA>, B<DSS>, B<DH>, B<None>. None is the
        +representation of anonymous ciphers.
        +
        +=item Enc=<symmetric encryption method>
        +
        +Encryption method with number of secret bits: B<DES(40)>, B<DES(56)>,
        +B<3DES(168)>, B<RC4(40)>, B<RC4(56)>, B<RC4(64)>, B<RC4(128)>,
        +B<RC2(40)>, B<RC2(56)>, B<RC2(128)>, B<IDEA(128)>, B<Fortezza>, B<None>.
        +
        +=item Mac=<message authentication code>
        +
        +Message digest: B<MD5>, B<SHA1>.
        +
        +=item <export flag>
        +
        +If the cipher is flagged exportable with respect to old US crypto
        +regulations, the word "B<export>" is printed.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Some examples for the output of SSL_CIPHER_description():
        +
        + EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
        + EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
        + RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5
        + EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
        +
        +=head1 BUGS
        +
        +If SSL_CIPHER_description() is called with B<cipher> being NULL, the
        +library crashes.
        +
        +If SSL_CIPHER_description() cannot handle a built-in cipher, the according
        +description of the cipher property is B<unknown>. This case should not
        +occur.
        +
        +=head1 RETURN VALUES
        +
        +See DESCRIPTION
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_get_current_cipher(3)|SSL_get_current_cipher(3)>,
        +L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>, L<ciphers(1)|ciphers(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_COMP_add_compression_method.pod b/vendor/openssl/openssl/doc/ssl/SSL_COMP_add_compression_method.pod
        new file mode 100644
        index 000000000..42fa66b19
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_COMP_add_compression_method.pod
        @@ -0,0 +1,70 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_COMP_add_compression_method - handle SSL/TLS integrated compression methods
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
        +
        +=head1 DESCRIPTION
        +
        +SSL_COMP_add_compression_method() adds the compression method B<cm> with
        +the identifier B<id> to the list of available compression methods. This
        +list is globally maintained for all SSL operations within this application.
        +It cannot be set for specific SSL_CTX or SSL objects.
        +
        +=head1 NOTES
        +
        +The TLS standard (or SSLv3) allows the integration of compression methods
        +into the communication. The TLS RFC does however not specify compression
        +methods or their corresponding identifiers, so there is currently no compatible
        +way to integrate compression with unknown peers. It is therefore currently not
        +recommended to integrate compression into applications. Applications for
        +non-public use may agree on certain compression methods. Using different
        +compression methods with the same identifier will lead to connection failure.
        +
        +An OpenSSL client speaking a protocol that allows compression (SSLv3, TLSv1)
        +will unconditionally send the list of all compression methods enabled with
        +SSL_COMP_add_compression_method() to the server during the handshake.
        +Unlike the mechanisms to set a cipher list, there is no method available to
        +restrict the list of compression method on a per connection basis.
        +
        +An OpenSSL server will match the identifiers listed by a client against
        +its own compression methods and will unconditionally activate compression
        +when a matching identifier is found. There is no way to restrict the list
        +of compression methods supported on a per connection basis.
        +
        +The OpenSSL library has the compression methods B<COMP_rle()> and (when
        +especially enabled during compilation) B<COMP_zlib()> available.
        +
        +=head1 WARNINGS
        +
        +Once the identities of the compression methods for the TLS protocol have
        +been standardized, the compression API will most likely be changed. Using
        +it in the current state is not recommended.
        +
        +=head1 RETURN VALUES
        +
        +SSL_COMP_add_compression_method() may return the following values:
        +
        +=over 4
        +
        +=item 0
        +
        +The operation succeeded.
        +
        +=item 1
        +
        +The operation failed. Check the error queue to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod
        new file mode 100644
        index 000000000..ee28f5ccc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod
        @@ -0,0 +1,39 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_add_extra_chain_cert - add certificate to chain
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_add_extra_chain_cert(SSL_CTX ctx, X509 *x509)
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_add_extra_chain_cert() adds the certificate B<x509> to the certificate
        +chain presented together with the certificate. Several certificates
        +can be added one after the other.
        +
        +=head1 NOTES
        +
        +When constructing the certificate chain, the chain will be formed from
        +these certificates explicitly specified. If no chain is specified,
        +the library will try to complete the chain from the available CA
        +certificates in the trusted CA storage, see
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_add_extra_chain_cert() returns 1 on success. Check out the
        +error stack to find out the reason for failure otherwise.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
        +L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_add_session.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_add_session.pod
        new file mode 100644
        index 000000000..82676b26b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_add_session.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_add_session, SSL_add_session, SSL_CTX_remove_session, SSL_remove_session - manipulate session cache
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c);
        + int SSL_add_session(SSL_CTX *ctx, SSL_SESSION *c);
        +
        + int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c);
        + int SSL_remove_session(SSL_CTX *ctx, SSL_SESSION *c);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_add_session() adds the session B<c> to the context B<ctx>. The
        +reference count for session B<c> is incremented by 1. If a session with
        +the same session id already exists, the old session is removed by calling
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>.
        +
        +SSL_CTX_remove_session() removes the session B<c> from the context B<ctx>.
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)> is called once for B<c>.
        +
        +SSL_add_session() and SSL_remove_session() are synonyms for their
        +SSL_CTX_*() counterparts.
        +
        +=head1 NOTES
        +
        +When adding a new session to the internal session cache, it is examined
        +whether a session with the same session id already exists. In this case
        +it is assumed that both sessions are identical. If the same session is
        +stored in a different SSL_SESSION object, The old session is
        +removed and replaced by the new session. If the session is actually
        +identical (the SSL_SESSION object is identical), SSL_CTX_add_session()
        +is a no-op, and the return value is 0.
        +
        +If a server SSL_CTX is configured with the SSL_SESS_CACHE_NO_INTERNAL_STORE
        +flag then the internal cache will not be populated automatically by new
        +sessions negotiated by the SSL/TLS implementation, even though the internal
        +cache will be searched automatically for session-resume requests (the
        +latter can be surpressed by SSL_SESS_CACHE_NO_INTERNAL_LOOKUP). So the
        +application can use SSL_CTX_add_session() directly to have full control
        +over the sessions that can be resumed if desired.
        +
        +
        +=head1 RETURN VALUES
        +
        +The following values are returned by all functions:
        +
        +=over 4
        +
        +=item 0
        +
        + The operation failed. In case of the add operation, it was tried to add
        + the same (identical) session twice. In case of the remove operation, the
        + session was not found in the cache.
        +
        +=item 1
        + 
        + The operation succeeded.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_ctrl.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_ctrl.pod
        new file mode 100644
        index 000000000..fb6adcf50
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_ctrl.pod
        @@ -0,0 +1,34 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_ctrl, SSL_CTX_callback_ctrl, SSL_ctrl, SSL_callback_ctrl - internal handling functions for SSL_CTX and SSL objects
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
        + long SSL_CTX_callback_ctrl(SSL_CTX *, int cmd, void (*fp)());
        +
        + long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
        + long SSL_callback_ctrl(SSL *, int cmd, void (*fp)());
        +
        +=head1 DESCRIPTION
        +
        +The SSL_*_ctrl() family of functions is used to manipulate settings of
        +the SSL_CTX and SSL objects. Depending on the command B<cmd> the arguments
        +B<larg>, B<parg>, or B<fp> are evaluated. These functions should never
        +be called directly. All functionalities needed are made available via
        +other functions or macros.
        +
        +=head1 RETURN VALUES
        +
        +The return values of the SSL*_ctrl() functions depend on the command
        +supplied via the B<cmd> parameter.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_flush_sessions.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_flush_sessions.pod
        new file mode 100644
        index 000000000..148c36c87
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_flush_sessions.pod
        @@ -0,0 +1,49 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_flush_sessions, SSL_flush_sessions - remove expired sessions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
        + void SSL_flush_sessions(SSL_CTX *ctx, long tm);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_flush_sessions() causes a run through the session cache of
        +B<ctx> to remove sessions expired at time B<tm>.
        +
        +SSL_flush_sessions() is a synonym for SSL_CTX_flush_sessions().
        +
        +=head1 NOTES
        +
        +If enabled, the internal session cache will collect all sessions established
        +up to the specified maximum number (see SSL_CTX_sess_set_cache_size()).
        +As sessions will not be reused ones they are expired, they should be
        +removed from the cache to save resources. This can either be done
        + automatically whenever 255 new sessions were established (see
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>)
        +or manually by calling SSL_CTX_flush_sessions(). 
        +
        +The parameter B<tm> specifies the time which should be used for the
        +expiration test, in most cases the actual time given by time(0)
        +will be used.
        +
        +SSL_CTX_flush_sessions() will only check sessions stored in the internal
        +cache. When a session is found and removed, the remove_session_cb is however
        +called to synchronize with the external cache (see
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>).
        +
        +=head1 RETURN VALUES
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_free.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_free.pod
        new file mode 100644
        index 000000000..51d867696
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_free.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_free - free an allocated SSL_CTX object
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_free(SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_free() decrements the reference count of B<ctx>, and removes the
        +SSL_CTX object pointed to by B<ctx> 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 cache, the list of ciphers, the list of Client CAs,
        +the certificates and keys.
        +
        +=head1 WARNINGS
        +
        +If a session-remove callback is set (SSL_CTX_sess_set_remove_cb()), this
        +callback will be called for each session being freed from B<ctx>'s
        +session cache. This implies, that all corresponding sessions from an
        +external session cache are removed as well. If this is not desired, the user
        +should explicitly unset the callback by calling
        +SSL_CTX_sess_set_remove_cb(B<ctx>, NULL) prior to calling SSL_CTX_free().
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_free() does not provide diagnostic information.
        +
        +=head1 SEE ALSO
        +
        +L<SSL_CTX_new(3)|SSL_CTX_new(3)>, L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_get_ex_new_index.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_get_ex_new_index.pod
        new file mode 100644
        index 000000000..0c40a91f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_get_ex_new_index.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_get_ex_new_index, SSL_CTX_set_ex_data, SSL_CTX_get_ex_data - internal application specific data functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_get_ex_new_index(long argl, void *argp,
        +                CRYPTO_EX_new *new_func,
        +                CRYPTO_EX_dup *dup_func,
        +                CRYPTO_EX_free *free_func);
        +
        + int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg);
        +
        + void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
        +
        + typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                int idx, long argl, void *argp);
        + typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                int idx, long argl, void *argp);
        + typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
        +                int idx, long argl, void *argp);
        +
        +=head1 DESCRIPTION
        +
        +Several OpenSSL structures can have application specific data attached to them.
        +These functions are used internally by OpenSSL to manipulate application
        +specific data attached to a specific structure.
        +
        +SSL_CTX_get_ex_new_index() is used to register a new index for application
        +specific data.
        +
        +SSL_CTX_set_ex_data() is used to store application data at B<arg> for B<idx>
        +into the B<ctx> object.
        +
        +SSL_CTX_get_ex_data() is used to retrieve the information for B<idx> from
        +B<ctx>.
        +
        +A detailed description for the B<*_get_ex_new_index()> functionality
        +can be found in L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>.
        +The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod
        new file mode 100644
        index 000000000..2a3747e75
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod
        @@ -0,0 +1,50 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_get_verify_mode, SSL_get_verify_mode, SSL_CTX_get_verify_depth, SSL_get_verify_depth, SSL_get_verify_callback, SSL_CTX_get_verify_callback - get currently set verification parameters
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
        + int SSL_get_verify_mode(const SSL *ssl);
        + int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
        + int SSL_get_verify_depth(const SSL *ssl);
        + int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *);
        + int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_get_verify_mode() returns the verification mode currently set in
        +B<ctx>.
        +
        +SSL_get_verify_mode() returns the verification mode currently set in
        +B<ssl>.
        +
        +SSL_CTX_get_verify_depth() returns the verification depth limit currently set
        +in B<ctx>. If no limit has been explicitly set, -1 is returned and the
        +default value will be used.
        +
        +SSL_get_verify_depth() returns the verification depth limit currently set
        +in B<ssl>. If no limit has been explicitly set, -1 is returned and the
        +default value will be used.
        +
        +SSL_CTX_get_verify_callback() returns a function pointer to the verification
        +callback currently set in B<ctx>. If no callback was explicitly set, the
        +NULL pointer is returned and the default callback will be used.
        +
        +SSL_get_verify_callback() returns a function pointer to the verification
        +callback currently set in B<ssl>. If no callback was explicitly set, the
        +NULL pointer is returned and the default callback will be used.
        +
        +=head1 RETURN VALUES
        +
        +See DESCRIPTION
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod
        new file mode 100644
        index 000000000..84a799fc7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod
        @@ -0,0 +1,124 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_load_verify_locations - set default locations for trusted CA
        +certificates
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
        +                                   const char *CApath);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_load_verify_locations() specifies the locations for B<ctx>, at
        +which CA certificates for verification purposes are located. The certificates
        +available via B<CAfile> and B<CApath> are trusted.
        +
        +=head1 NOTES
        +
        +If B<CAfile> is not NULL, it points to a file of CA certificates in PEM
        +format. The file can contain several CA certificates identified by
        +
        + -----BEGIN CERTIFICATE-----
        + ... (CA certificate in base64 encoding) ...
        + -----END CERTIFICATE-----
        +
        +sequences. Before, between, and after the certificates text is allowed
        +which can be used e.g. for descriptions of the certificates.
        +
        +The B<CAfile> is processed on execution of the SSL_CTX_load_verify_locations()
        +function.
        +
        +If B<CApath> is not NULL, it points to a directory containing CA certificates
        +in PEM format. The files each contain one CA certificate. The files are
        +looked up by the CA subject name hash value, which must hence be available.
        +If more than one CA certificate with the same name hash value exist, the
        +extension must be different (e.g. 9d66eef0.0, 9d66eef0.1 etc). The search
        +is performed in the ordering of the extension number, regardless of other
        +properties of the certificates.
        +Use the B<c_rehash> utility to create the necessary links.
        +
        +The certificates in B<CApath> are only looked up when required, e.g. when
        +building the certificate chain or when actually performing the verification
        +of a peer certificate.
        +
        +When looking up CA certificates, the OpenSSL library will first search the
        +certificates in B<CAfile>, then those in B<CApath>. Certificate matching
        +is done based on the subject name, the key identifier (if present), and the
        +serial number as taken from the certificate to be verified. If these data
        +do not match, the next certificate will be tried. If a first certificate
        +matching the parameters is found, the verification process will be performed;
        +no other certificates for the same parameters will be searched in case of
        +failure.
        +
        +In server mode, when requesting a client certificate, the server must send
        +the list of CAs of which it will accept client certificates. This list
        +is not influenced by the contents of B<CAfile> or B<CApath> and must
        +explicitly be set using the
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>
        +family of functions.
        +
        +When building its own certificate chain, an OpenSSL client/server will
        +try to fill in missing certificates from B<CAfile>/B<CApath>, if the
        +certificate chain was not explicitly specified (see
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>.
        +
        +=head1 WARNINGS
        +
        +If several CA certificates matching the name, key identifier, and serial
        +number condition are available, only the first one will be examined. This
        +may lead to unexpected results if the same CA certificate is available
        +with different expiration dates. If a "certificate expired" verification
        +error occurs, no other certificate will be searched. Make sure to not
        +have expired certificates mixed with valid ones.
        +
        +=head1 EXAMPLES
        +
        +Generate a CA certificate file with descriptive text from the CA certificates
        +ca1.pem ca2.pem ca3.pem:
        +
        + #!/bin/sh
        + rm CAfile.pem
        + for i in ca1.pem ca2.pem ca3.pem ; do
        +   openssl x509 -in $i -text >> CAfile.pem
        + done
        +
        +Prepare the directory /some/where/certs containing several CA certificates
        +for use as B<CApath>:
        +
        + cd /some/where/certs
        + c_rehash .
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item 0
        +
        +The operation failed because B<CAfile> and B<CApath> are NULL or the
        +processing at one of the locations specified failed. Check the error
        +stack to find out the reason.
        +
        +=item 1
        +
        +The operation succeeded.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
        +L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
        +L<SSL_CTX_set_cert_store(3)|SSL_CTX_set_cert_store(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_new.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_new.pod
        new file mode 100644
        index 000000000..73e8c47f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_new.pod
        @@ -0,0 +1,94 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_new - create a new SSL_CTX object as framework for TLS/SSL enabled functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_new() creates a new B<SSL_CTX> object as framework to establish
        +TLS/SSL enabled connections.
        +
        +=head1 NOTES
        +
        +The SSL_CTX object uses B<method> 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<method> 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 protocol. A client will send out SSLv3 client hello messages
        +and will indicate that it only understands SSLv3. A server will only understand
        +SSLv3 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(). It will also not understand
        +SSLv3 client hello messages.
        +
        +=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<SSL_CTX_set_options()> or
        +B<SSL_set_options()> 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<SSL_CTX_free(3)|SSL_CTX_free(3)>, L<SSL_accept(3)|SSL_accept(3)>,
        +L<ssl(3)|ssl(3)>,  L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_number.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_number.pod
        new file mode 100644
        index 000000000..19aa4e290
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_number.pod
        @@ -0,0 +1,76 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_sess_number, SSL_CTX_sess_connect, SSL_CTX_sess_connect_good, SSL_CTX_sess_connect_renegotiate, SSL_CTX_sess_accept, SSL_CTX_sess_accept_good, SSL_CTX_sess_accept_renegotiate, SSL_CTX_sess_hits, SSL_CTX_sess_cb_hits, SSL_CTX_sess_misses, SSL_CTX_sess_timeouts, SSL_CTX_sess_cache_full - obtain session cache statistics
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_sess_number(SSL_CTX *ctx);
        + long SSL_CTX_sess_connect(SSL_CTX *ctx);
        + long SSL_CTX_sess_connect_good(SSL_CTX *ctx);
        + long SSL_CTX_sess_connect_renegotiate(SSL_CTX *ctx);
        + long SSL_CTX_sess_accept(SSL_CTX *ctx);
        + long SSL_CTX_sess_accept_good(SSL_CTX *ctx);
        + long SSL_CTX_sess_accept_renegotiate(SSL_CTX *ctx);
        + long SSL_CTX_sess_hits(SSL_CTX *ctx);
        + long SSL_CTX_sess_cb_hits(SSL_CTX *ctx);
        + long SSL_CTX_sess_misses(SSL_CTX *ctx);
        + long SSL_CTX_sess_timeouts(SSL_CTX *ctx);
        + long SSL_CTX_sess_cache_full(SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_sess_number() returns the current number of sessions in the internal
        +session cache.
        +
        +SSL_CTX_sess_connect() returns the number of started SSL/TLS handshakes in
        +client mode.
        +
        +SSL_CTX_sess_connect_good() returns the number of successfully established
        +SSL/TLS sessions in client mode.
        +
        +SSL_CTX_sess_connect_renegotiate() returns the number of start renegotiations
        +in client mode.
        +
        +SSL_CTX_sess_accept() returns the number of started SSL/TLS handshakes in
        +server mode.
        +
        +SSL_CTX_sess_accept_good() returns the number of successfully established
        +SSL/TLS sessions in server mode.
        +
        +SSL_CTX_sess_accept_renegotiate() returns the number of start renegotiations
        +in server mode.
        +
        +SSL_CTX_sess_hits() returns the number of successfully reused sessions.
        +In client mode a session set with L<SSL_set_session(3)|SSL_set_session(3)>
        +successfully reused is counted as a hit. In server mode a session successfully
        +retrieved from internal or external cache is counted as a hit.
        +
        +SSL_CTX_sess_cb_hits() returns the number of successfully retrieved sessions
        +from the external session cache in server mode.
        +
        +SSL_CTX_sess_misses() returns the number of sessions proposed by clients
        +that were not found in the internal session cache in server mode.
        +
        +SSL_CTX_sess_timeouts() returns the number of sessions proposed by clients
        +and either found in the internal or external session cache in server mode,
        + but that were invalid due to timeout. These sessions are not included in
        +the SSL_CTX_sess_hits() count.
        +
        +SSL_CTX_sess_cache_full() returns the number of sessions that were removed
        +because the maximum session cache size was exceeded.
        +
        +=head1 RETURN VALUES
        +
        +The functions return the values indicated in the DESCRIPTION section.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
        +L<SSL_CTX_sess_set_cache_size(3)|SSL_CTX_sess_set_cache_size(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod
        new file mode 100644
        index 000000000..c8b99f4ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod
        @@ -0,0 +1,51 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_sess_set_cache_size, SSL_CTX_sess_get_cache_size - manipulate session cache size
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, long t);
        + long SSL_CTX_sess_get_cache_size(SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_sess_set_cache_size() sets the size of the internal session cache
        +of context B<ctx> to B<t>.
        +
        +SSL_CTX_sess_get_cache_size() returns the currently valid session cache size.
        +
        +=head1 NOTES
        +
        +The internal session cache size is SSL_SESSION_CACHE_MAX_SIZE_DEFAULT,
        +currently 1024*20, so that up to 20000 sessions can be held. This size
        +can be modified using the SSL_CTX_sess_set_cache_size() call. A special
        +case is the size 0, which is used for unlimited size.
        +
        +When the maximum number of sessions is reached, no more new sessions are
        +added to the cache. New space may be added by calling
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> to remove
        +expired sessions.
        +
        +If the size of the session cache is reduced and more sessions are already
        +in the session cache, old session will be removed at the next time a
        +session shall be added. This removal is not synchronized with the
        +expiration of sessions.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_sess_set_cache_size() returns the previously valid size.
        +
        +SSL_CTX_sess_get_cache_size() returns the currently valid size.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod
        new file mode 100644
        index 000000000..b9d54a40a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod
        @@ -0,0 +1,87 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_remove_cb, SSL_CTX_sess_set_get_cb, SSL_CTX_sess_get_new_cb, SSL_CTX_sess_get_remove_cb, SSL_CTX_sess_get_get_cb - provide callback functions for server side external session caching
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
        +			      int (*new_session_cb)(SSL *, SSL_SESSION *));
        + void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
        +	   void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *));
        + void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
        +	   SSL_SESSION (*get_session_cb)(SSL *, unsigned char *, int, int *));
        +
        + int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
        + void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
        + SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *data, int len, int *copy);
        +
        + int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess);
        + void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
        + SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,
        +	       int len, int *copy);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_sess_set_new_cb() sets the callback function, which is automatically
        +called whenever a new session was negotiated.
        +
        +SSL_CTX_sess_set_remove_cb() sets the callback function, which is
        +automatically called whenever a session is removed by the SSL engine,
        +because it is considered faulty or the session has become obsolete because
        +of exceeding the timeout value.
        +
        +SSL_CTX_sess_set_get_cb() sets the callback function which is called,
        +whenever a SSL/TLS client proposed to resume a session but the session
        +could not be found in the internal session cache (see
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>).
        +(SSL/TLS server only.)
        +
        +SSL_CTX_sess_get_new_cb(), SSL_CTX_sess_get_remove_cb(), and
        +SSL_CTX_sess_get_get_cb() allow to retrieve the function pointers of the
        +provided callback functions. If a callback function has not been set,
        +the NULL pointer is returned.
        +
        +=head1 NOTES
        +
        +In order to allow external session caching, synchronization with the internal
        +session cache is realized via callback functions. Inside these callback
        +functions, session can be saved to disk or put into a database using the
        +L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)> interface.
        +
        +The new_session_cb() is called, whenever a new session has been negotiated
        +and session caching is enabled (see
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>).
        +The new_session_cb() is passed the B<ssl> connection and the ssl session
        +B<sess>. If the callback returns B<0>, the session will be immediately
        +removed again.
        +
        +The remove_session_cb() is called, whenever the SSL engine removes a session
        +from the internal cache. This happens when the session is removed because
        +it is expired or when a connection was not shutdown cleanly. It also happens
        +for all sessions in the internal session cache when
        +L<SSL_CTX_free(3)|SSL_CTX_free(3)> is called. The remove_session_cb() is passed
        +the B<ctx> and the ssl session B<sess>. It does not provide any feedback.
        +
        +The get_session_cb() is only called on SSL/TLS servers with the session id
        +proposed by the client. The get_session_cb() is always called, also when
        +session caching was disabled. The get_session_cb() is passed the
        +B<ssl> connection, the session id of length B<length> at the memory location
        +B<data>. With the parameter B<copy> the callback can require the
        +SSL engine to increment the reference count of the SSL_SESSION object,
        +Normally the reference count is not incremented and therefore the
        +session must not be explicitly freed with
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
        +L<SSL_CTX_free(3)|SSL_CTX_free(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_sessions.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sessions.pod
        new file mode 100644
        index 000000000..e05aab3c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_sessions.pod
        @@ -0,0 +1,34 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_sessions - access internal session cache
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_sessions() returns a pointer to the lhash databases containing the
        +internal session cache for B<ctx>.
        +
        +=head1 NOTES
        +
        +The sessions in the internal session cache are kept in an
        +L<lhash(3)|lhash(3)> type database. It is possible to directly
        +access this database e.g. for searching. In parallel, the sessions
        +form a linked list which is maintained separately from the
        +L<lhash(3)|lhash(3)> operations, so that the database must not be
        +modified directly but by using the
        +L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)> family of functions.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<lhash(3)|lhash(3)>,
        +L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cert_store.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cert_store.pod
        new file mode 100644
        index 000000000..6acf0d9f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cert_store.pod
        @@ -0,0 +1,57 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_cert_store, SSL_CTX_get_cert_store - manipulate X509 certificate verification storage
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store);
        + X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_cert_store() sets/replaces the certificate verification storage
        +of B<ctx> to/with B<store>. If another X509_STORE object is currently
        +set in B<ctx>, it will be X509_STORE_free()ed.
        +
        +SSL_CTX_get_cert_store() returns a pointer to the current certificate
        +verification storage.
        +
        +=head1 NOTES
        +
        +In order to verify the certificates presented by the peer, trusted CA
        +certificates must be accessed. These CA certificates are made available
        +via lookup methods, handled inside the X509_STORE. From the X509_STORE
        +the X509_STORE_CTX used when verifying certificates is created.
        +
        +Typically the trusted certificate store is handled indirectly via using
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>.
        +Using the SSL_CTX_set_cert_store() and SSL_CTX_get_cert_store() functions
        +it is possible to manipulate the X509_STORE object beyond the
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
        +call.
        +
        +Currently no detailed documentation on how to use the X509_STORE
        +object is available. Not all members of the X509_STORE are used when
        +the verification takes place. So will e.g. the verify_callback() be
        +overridden with the verify_callback() set via the
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)> family of functions.
        +This document must therefore be updated when documentation about the
        +X509_STORE object and its handling becomes available.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_cert_store() does not return diagnostic output.
        +
        +SSL_CTX_get_cert_store() returns the current setting.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod
        new file mode 100644
        index 000000000..c0f4f8570
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod
        @@ -0,0 +1,75 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_cert_verify_callback - set peer certificate verification procedure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *,void *), void *arg);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_cert_verify_callback() sets the verification callback function for
        +I<ctx>. SSL objects that are created from I<ctx> inherit the setting valid at
        +the time when L<SSL_new(3)|SSL_new(3)> is called.
        +
        +=head1 NOTES
        +
        +Whenever a certificate is verified during a SSL/TLS handshake, a verification
        +function is called. If the application does not explicitly specify a
        +verification callback function, the built-in verification function is used.
        +If a verification callback I<callback> is specified via
        +SSL_CTX_set_cert_verify_callback(), the supplied callback function is called
        +instead. By setting I<callback> to NULL, the default behaviour is restored.
        +
        +When the verification must be performed, I<callback> will be called with
        +the arguments callback(X509_STORE_CTX *x509_store_ctx, void *arg). The 
        +argument I<arg> is specified by the application when setting I<callback>.
        +
        +I<callback> should return 1 to indicate verification success and 0 to
        +indicate verification failure. If SSL_VERIFY_PEER is set and I<callback>
        +returns 0, the handshake will fail. As the verification procedure may
        +allow to continue the connection in case of failure (by always returning 1)
        +the verification result must be set in any case using the B<error>
        +member of I<x509_store_ctx> so that the calling application will be informed
        +about the detailed result of the verification procedure! 
        +
        +Within I<x509_store_ctx>, I<callback> has access to the I<verify_callback>
        +function set using L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>.
        +
        +=head1 WARNINGS
        +
        +Do not mix the verification callback described in this function with the
        +B<verify_callback> function called during the verification process. The
        +latter is set using the L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
        +family of functions.
        +
        +Providing a complete verification procedure including certificate purpose
        +settings etc is a complex task. The built-in procedure is quite powerful
        +and in most cases it should be sufficient to modify its behaviour using
        +the B<verify_callback> function.
        +
        +=head1 BUGS
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_cert_verify_callback() does not provide diagnostic information.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
        +L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
        +
        +=head1 HISTORY
        +
        +Previous to OpenSSL 0.9.7, the I<arg> argument to B<SSL_CTX_set_cert_verify_callback>
        +was ignored, and I<callback> was called simply as
        + int (*callback)(X509_STORE_CTX *)
        +To compile software written for previous versions of OpenSSL, a dummy
        +argument will have to be added to I<callback>.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod
        new file mode 100644
        index 000000000..ed64f6415
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod
        @@ -0,0 +1,70 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_cipher_list, SSL_set_cipher_list - choose list of available SSL_CIPHERs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + 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<ctx>
        +using the control string B<str>. The format of the string is described
        +in L<ciphers(1)|ciphers(1)>. The list of ciphers is inherited by all
        +B<ssl> objects created from B<ctx>.
        +
        +SSL_set_cipher_list() sets the list of ciphers only for B<ssl>.
        +
        +=head1 NOTES
        +
        +The control string B<str> 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.
        +RSA export ciphers with a keylength of 512 bits for the RSA key require
        +a temporary 512 bit RSA key, as typically the supplied key has a length
        +of 1024 bit (see
        +L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
        +RSA ciphers using EDH need a certificate and key and additional DH-parameters
        +(see L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
        +
        +A DSA cipher can only be chosen, when a DSA certificate is available.
        +DSA ciphers always use DH key exchange and therefore need DH-parameters
        +(see L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
        +
        +When these conditions are not met for any cipher in the list (e.g. a
        +client only supports export RSA ciphers with a asymmetric key length
        +of 512 bits and the server is not configured to use temporary RSA
        +keys), the "no shared cipher" (SSL_R_NO_SHARED_CIPHER) error is generated
        +and the handshake will fail.
        +
        +=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<ssl(3)|ssl(3)>, L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>,
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
        +L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
        +L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
        +L<ciphers(1)|ciphers(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod
        new file mode 100644
        index 000000000..632b556d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod
        @@ -0,0 +1,94 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_client_CA_list, SSL_set_client_CA_list, SSL_CTX_add_client_CA,
        +SSL_add_client_CA - set list of CAs sent to the client when requesting a
        +client certificate
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        + 
        + void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *list);
        + void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *list);
        + int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *cacert);
        + int SSL_add_client_CA(SSL *ssl, X509 *cacert);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_client_CA_list() sets the B<list> of CAs sent to the client when
        +requesting a client certificate for B<ctx>.
        +
        +SSL_set_client_CA_list() sets the B<list> of CAs sent to the client when
        +requesting a client certificate for the chosen B<ssl>, overriding the
        +setting valid for B<ssl>'s SSL_CTX object.
        +
        +SSL_CTX_add_client_CA() adds the CA name extracted from B<cacert> to the
        +list of CAs sent to the client when requesting a client certificate for
        +B<ctx>.
        +
        +SSL_add_client_CA() adds the CA name extracted from B<cacert> to the
        +list of CAs sent to the client when requesting a client certificate for
        +the chosen B<ssl>, overriding the setting valid for B<ssl>'s SSL_CTX object.
        +
        +=head1 NOTES
        +
        +When a TLS/SSL server requests a client certificate (see
        +B<SSL_CTX_set_verify_options()>), it sends a list of CAs, for which
        +it will accept certificates, to the client.
        +
        +This list must explicitly be set using SSL_CTX_set_client_CA_list() for
        +B<ctx> and SSL_set_client_CA_list() for the specific B<ssl>. The list
        +specified overrides the previous setting. The CAs listed do not become
        +trusted (B<list> only contains the names, not the complete certificates); use
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)> 
        +to additionally load them for verification.
        +
        +If the list of acceptable CAs is compiled in a file, the
        +L<SSL_load_client_CA_file(3)|SSL_load_client_CA_file(3)>
        +function can be used to help importing the necessary data.
        +
        +SSL_CTX_add_client_CA() and SSL_add_client_CA() can be used to add additional
        +items the list of client CAs. If no list was specified before using
        +SSL_CTX_set_client_CA_list() or SSL_set_client_CA_list(), a new client
        +CA list for B<ctx> or B<ssl> (as appropriate) is opened.
        +
        +These functions are only useful for TLS/SSL servers.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_client_CA_list() and SSL_set_client_CA_list() do not return
        +diagnostic information.
        +
        +SSL_CTX_add_client_CA() and SSL_add_client_CA() have the following return
        +values:
        +
        +=over 4
        +
        +=item 1
        +
        +The operation succeeded.
        +
        +=item 0
        +
        +A failure while manipulating the STACK_OF(X509_NAME) object occurred or
        +the X509_NAME could not be extracted from B<cacert>. Check the error stack
        +to find out the reason.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +Scan all certificates in B<CAfile> and list them as acceptable CAs:
        +
        +  SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
        +L<SSL_load_client_CA_file(3)|SSL_load_client_CA_file(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod
        new file mode 100644
        index 000000000..3465b5c7b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod
        @@ -0,0 +1,94 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_client_cert_cb, SSL_CTX_get_client_cert_cb - handle client certificate callback function
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
        + int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
        + int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_client_cert_cb() sets the B<client_cert_cb()> callback, that is
        +called when a client certificate is requested by a server and no certificate
        +was yet set for the SSL object.
        +
        +When B<client_cert_cb()> is NULL, no callback function is used.
        +
        +SSL_CTX_get_client_cert_cb() returns a pointer to the currently set callback
        +function.
        +
        +client_cert_cb() is the application defined callback. If it wants to
        +set a certificate, a certificate/private key combination must be set
        +using the B<x509> and B<pkey> arguments and "1" must be returned. The
        +certificate will be installed into B<ssl>, see the NOTES and BUGS sections.
        +If no certificate should be set, "0" has to be returned and no certificate
        +will be sent. A negative return value will suspend the handshake and the
        +handshake function will return immediatly. L<SSL_get_error(3)|SSL_get_error(3)>
        +will return SSL_ERROR_WANT_X509_LOOKUP to indicate, that the handshake was
        +suspended. The next call to the handshake function will again lead to the call
        +of client_cert_cb(). It is the job of the client_cert_cb() to store information
        +about the state of the last call, if required to continue.
        +
        +=head1 NOTES
        +
        +During a handshake (or renegotiation) a server may request a certificate
        +from the client. A client certificate must only be sent, when the server
        +did send the request.
        +
        +When a certificate was set using the
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)> family of functions,
        +it will be sent to the server. The TLS standard requires that only a
        +certificate is sent, if it matches the list of acceptable CAs sent by the
        +server. This constraint is violated by the default behavior of the OpenSSL
        +library. Using the callback function it is possible to implement a proper
        +selection routine or to allow a user interaction to choose the certificate to
        +be sent.
        +
        +If a callback function is defined and no certificate was yet defined for the
        +SSL object, the callback function will be called.
        +If the callback function returns a certificate, the OpenSSL library
        +will try to load the private key and certificate data into the SSL
        +object using the SSL_use_certificate() and SSL_use_private_key() functions.
        +Thus it will permanently install the certificate and key for this SSL
        +object. It will not be reset by calling L<SSL_clear(3)|SSL_clear(3)>.
        +If the callback returns no certificate, the OpenSSL library will not send
        +a certificate.
        +
        +=head1 BUGS
        +
        +The client_cert_cb() cannot return a complete certificate chain, it can
        +only return one client certificate. If the chain only has a length of 2,
        +the root CA certificate may be omitted according to the TLS standard and
        +thus a standard conforming answer can be sent to the server. For a
        +longer chain, the client must send the complete chain (with the option
        +to leave out the root CA certificate). This can only be accomplished by
        +either adding the intermediate CA certificates into the trusted
        +certificate store for the SSL_CTX object (resulting in having to add
        +CA certificates that otherwise maybe would not be trusted), or by adding
        +the chain certificates using the
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>
        +function, which is only available for the SSL_CTX object as a whole and that
        +therefore probably can only apply for one client certificate, making
        +the concept of the callback function (to allow the choice from several
        +certificates) questionable.
        +
        +Once the SSL object has been used in conjunction with the callback function,
        +the certificate will be set for the SSL object and will not be cleared
        +even when L<SSL_clear(3)|SSL_clear(3)> is being called. It is therefore
        +mandatory to destroy the SSL object using L<SSL_free(3)|SSL_free(3)>
        +and create a new one to return to the previous state.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
        +L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
        +L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod
        new file mode 100644
        index 000000000..2b87f01ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod
        @@ -0,0 +1,76 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_default_passwd_cb, SSL_CTX_set_default_passwd_cb_userdata - set passwd callback for encrypted PEM file handling
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
        + void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
        +
        + int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_default_passwd_cb() sets the default password callback called
        +when loading/storing a PEM certificate with encryption.
        +
        +SSL_CTX_set_default_passwd_cb_userdata() sets a pointer to B<userdata> which
        +will be provided to the password callback on invocation.
        +
        +The pem_passwd_cb(), which must be provided by the application, hands back the
        +password to be used during decryption. On invocation a pointer to B<userdata>
        +is provided. The pem_passwd_cb must write the password into the provided buffer
        +B<buf> which is of size B<size>. The actual length of the password must
        +be returned to the calling function. B<rwflag> indicates whether the
        +callback is used for reading/decryption (rwflag=0) or writing/encryption
        +(rwflag=1).
        +
        +=head1 NOTES
        +
        +When loading or storing private keys, a password might be supplied to
        +protect the private key. The way this password can be supplied may depend
        +on the application. If only one private key is handled, it can be practical
        +to have pem_passwd_cb() handle the password dialog interactively. If several
        +keys have to be handled, it can be practical to ask for the password once,
        +then keep it in memory and use it several times. In the last case, the
        +password could be stored into the B<userdata> storage and the
        +pem_passwd_cb() only returns the password already stored.
        +
        +When asking for the password interactively, pem_passwd_cb() can use
        +B<rwflag> to check, whether an item shall be encrypted (rwflag=1).
        +In this case the password dialog may ask for the same password twice
        +for comparison in order to catch typos, that would make decryption
        +impossible.
        +
        +Other items in PEM formatting (certificates) can also be encrypted, it is
        +however not usual, as certificate information is considered public.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_default_passwd_cb() and SSL_CTX_set_default_passwd_cb_userdata()
        +do not provide diagnostic information.
        +
        +=head1 EXAMPLES
        +
        +The following example returns the password provided as B<userdata> to the
        +calling function. The password is considered to be a '\0' terminated
        +string. If the password does not fit into the buffer, the password is
        +truncated.
        +
        + int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
        + {
        +  strncpy(buf, (char *)(password), size);
        +  buf[size - 1] = '\0';
        +  return(strlen(buf));
        + }
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod
        new file mode 100644
        index 000000000..798e8443a
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod
        @@ -0,0 +1,150 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, SSL_has_matching_session_id - manipulate generation of SSL session IDs (server only)
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
        +                               unsigned int *id_len);
        +
        + int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb);
        + int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB, cb);
        + int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
        +				 unsigned int id_len);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_generate_session_id() sets the callback function for generating
        +new session ids for SSL/TLS sessions for B<ctx> to be B<cb>.
        +
        +SSL_set_generate_session_id() sets the callback function for generating
        +new session ids for SSL/TLS sessions for B<ssl> to be B<cb>.
        +
        +SSL_has_matching_session_id() checks, whether a session with id B<id>
        +(of length B<id_len>) is already contained in the internal session cache
        +of the parent context of B<ssl>.
        +
        +=head1 NOTES
        +
        +When a new session is established between client and server, the server
        +generates a session id. The session id is an arbitrary sequence of bytes.
        +The length of the session id is 16 bytes for SSLv2 sessions and between
        +1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical
        +but must be unique for the server. Additionally, the session id is
        +transmitted in the clear when reusing the session so it must not contain
        +sensitive information.
        +
        +Without a callback being set, an OpenSSL server will generate a unique
        +session id from pseudo random numbers of the maximum possible length.
        +Using the callback function, the session id can be changed to contain
        +additional information like e.g. a host id in order to improve load balancing
        +or external caching techniques.
        +
        +The callback function receives a pointer to the memory location to put
        +B<id> into and a pointer to the maximum allowed length B<id_len>. The
        +buffer at location B<id> is only guaranteed to have the size B<id_len>.
        +The callback is only allowed to generate a shorter id and reduce B<id_len>;
        +the callback B<must never> increase B<id_len> or write to the location
        +B<id> exceeding the given limit.
        +
        +If a SSLv2 session id is generated and B<id_len> is reduced, it will be
        +restored after the callback has finished and the session id will be padded
        +with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions.
        +The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function
        +to check, whether the session is of type SSLv2.
        +
        +The location B<id> is filled with 0x00 before the callback is called, so the
        +callback may only fill part of the possible length and leave B<id_len>
        +untouched while maintaining reproducibility.
        +
        +Since the sessions must be distinguished, session ids must be unique.
        +Without the callback a random number is used, so that the probability
        +of generating the same session id is extremely small (2^128 possible ids
        +for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the
        +uniqueness of the generated session id, the callback must call
        +SSL_has_matching_session_id() and generate another id if a conflict occurs.
        +If an id conflict is not resolved, the handshake will fail.
        +If the application codes e.g. a unique host id, a unique process number, and
        +a unique sequence number into the session id, uniqueness could easily be
        +achieved without randomness added (it should however be taken care that
        +no confidential information is leaked this way). If the application can not
        +guarantee uniqueness, it is recommended to use the maximum B<id_len> and
        +fill in the bytes not used to code special information with random data
        +to avoid collisions.
        +
        +SSL_has_matching_session_id() will only query the internal session cache,
        +not the external one. Since the session id is generated before the
        +handshake is completed, it is not immediately added to the cache. If
        +another thread is using the same internal session cache, a race condition
        +can occur in that another thread generates the same session id.
        +Collisions can also occur when using an external session cache, since
        +the external cache is not tested with SSL_has_matching_session_id()
        +and the same race condition applies.
        +
        +When calling SSL_has_matching_session_id() for an SSLv2 session with
        +reduced B<id_len>, the match operation will be performed using the
        +fixed length required and with a 0x00 padded id.
        +
        +The callback must return 0 if it cannot generate a session id for whatever
        +reason and return 1 on success.
        +
        +=head1 EXAMPLES
        +
        +The callback function listed will generate a session id with the
        +server id given, and will fill the rest with pseudo random bytes:
        +
        + const char session_id_prefix = "www-18";
        +
        + #define MAX_SESSION_ID_ATTEMPTS 10
        + static int generate_session_id(const SSL *ssl, unsigned char *id,
        +                              unsigned int *id_len)
        +      {
        +      unsigned int count = 0;
        +      const char *version;
        +
        +      version = SSL_get_version(ssl);
        +      if (!strcmp(version, "SSLv2"))
        +	  /* we must not change id_len */;
        +
        +      do      {
        +              RAND_pseudo_bytes(id, *id_len);
        +              /* Prefix the session_id with the required prefix. NB: If our
        +               * prefix is too long, clip it - but there will be worse effects
        +               * anyway, eg. the server could only possibly create 1 session
        +               * ID (ie. the prefix!) so all future session negotiations will
        +               * fail due to conflicts. */
        +              memcpy(id, session_id_prefix,
        +                      (strlen(session_id_prefix) < *id_len) ?
        +                      strlen(session_id_prefix) : *id_len);
        +              }
        +      while(SSL_has_matching_session_id(ssl, id, *id_len) &&
        +              (++count < MAX_SESSION_ID_ATTEMPTS));
        +      if(count >= MAX_SESSION_ID_ATTEMPTS)
        +              return 0;
        +      return 1;
        +      }
        +
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_generate_session_id() and SSL_set_generate_session_id()
        +always return 1.
        +
        +SSL_has_matching_session_id() returns 1 if another session with the
        +same id is already in the cache.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_get_version(3)|SSL_get_version(3)>
        +
        +=head1 HISTORY
        +
        +SSL_CTX_set_generate_session_id(), SSL_set_generate_session_id()
        +and SSL_has_matching_session_id() have been introduced in
        +OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_info_callback.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_info_callback.pod
        new file mode 100644
        index 000000000..0b4affd5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_info_callback.pod
        @@ -0,0 +1,153 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_info_callback, SSL_CTX_get_info_callback, SSL_set_info_callback, SSL_get_info_callback - handle information callback for SSL connections
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*callback)());
        + void (*SSL_CTX_get_info_callback(const SSL_CTX *ctx))();
        +
        + void SSL_set_info_callback(SSL *ssl, void (*callback)());
        + void (*SSL_get_info_callback(const SSL *ssl))();
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_info_callback() sets the B<callback> function, that can be used to
        +obtain state information for SSL objects created from B<ctx> during connection
        +setup and use. The setting for B<ctx> is overridden from the setting for
        +a specific SSL object, if specified.
        +When B<callback> is NULL, not callback function is used.
        +
        +SSL_set_info_callback() sets the B<callback> function, that can be used to
        +obtain state information for B<ssl> during connection setup and use.
        +When B<callback> is NULL, the callback setting currently valid for
        +B<ctx> is used.
        +
        +SSL_CTX_get_info_callback() returns a pointer to the currently set information
        +callback function for B<ctx>.
        +
        +SSL_get_info_callback() returns a pointer to the currently set information
        +callback function for B<ssl>.
        +
        +=head1 NOTES
        +
        +When setting up a connection and during use, it is possible to obtain state
        +information from the SSL/TLS engine. When set, an information callback function
        +is called whenever the state changes, an alert appears, or an error occurs.
        +
        +The callback function is called as B<callback(SSL *ssl, int where, int ret)>.
        +The B<where> argument specifies information about where (in which context)
        +the callback function was called. If B<ret> is 0, an error condition occurred.
        +If an alert is handled, SSL_CB_ALERT is set and B<ret> specifies the alert
        +information.
        +
        +B<where> is a bitmask made up of the following bits:
        +
        +=over 4
        +
        +=item SSL_CB_LOOP
        +
        +Callback has been called to indicate state change inside a loop.
        +
        +=item SSL_CB_EXIT
        +
        +Callback has been called to indicate error exit of a handshake function.
        +(May be soft error with retry option for non-blocking setups.)
        +
        +=item SSL_CB_READ
        +
        +Callback has been called during read operation.
        +
        +=item SSL_CB_WRITE
        +
        +Callback has been called during write operation.
        +
        +=item SSL_CB_ALERT
        +
        +Callback has been called due to an alert being sent or received.
        +
        +=item SSL_CB_READ_ALERT               (SSL_CB_ALERT|SSL_CB_READ)
        +
        +=item SSL_CB_WRITE_ALERT              (SSL_CB_ALERT|SSL_CB_WRITE)
        +
        +=item SSL_CB_ACCEPT_LOOP              (SSL_ST_ACCEPT|SSL_CB_LOOP)
        +
        +=item SSL_CB_ACCEPT_EXIT              (SSL_ST_ACCEPT|SSL_CB_EXIT)
        +
        +=item SSL_CB_CONNECT_LOOP             (SSL_ST_CONNECT|SSL_CB_LOOP)
        +
        +=item SSL_CB_CONNECT_EXIT             (SSL_ST_CONNECT|SSL_CB_EXIT)
        +
        +=item SSL_CB_HANDSHAKE_START
        +
        +Callback has been called because a new handshake is started.
        +
        +=item SSL_CB_HANDSHAKE_DONE           0x20
        +
        +Callback has been called because a handshake is finished.
        +
        +=back
        +
        +The current state information can be obtained using the
        +L<SSL_state_string(3)|SSL_state_string(3)> family of functions.
        +
        +The B<ret> information can be evaluated using the
        +L<SSL_alert_type_string(3)|SSL_alert_type_string(3)> family of functions.
        +
        +=head1 RETURN VALUES
        +
        +SSL_set_info_callback() does not provide diagnostic information.
        +
        +SSL_get_info_callback() returns the current setting.
        +
        +=head1 EXAMPLES
        +
        +The following example callback function prints state strings, information
        +about alerts being handled and error messages to the B<bio_err> BIO.
        +
        + void apps_ssl_info_callback(SSL *s, int where, int ret)
        +	{
        +	const char *str;
        +	int w;
        +
        +	w=where& ~SSL_ST_MASK;
        +
        +	if (w & SSL_ST_CONNECT) str="SSL_connect";
        +	else if (w & SSL_ST_ACCEPT) str="SSL_accept";
        +	else str="undefined";
        +
        +	if (where & SSL_CB_LOOP)
        +		{
        +		BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
        +		}
        +	else if (where & SSL_CB_ALERT)
        +		{
        +		str=(where & SSL_CB_READ)?"read":"write";
        +		BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
        +			str,
        +			SSL_alert_type_string_long(ret),
        +			SSL_alert_desc_string_long(ret));
        +		}
        +	else if (where & SSL_CB_EXIT)
        +		{
        +		if (ret == 0)
        +			BIO_printf(bio_err,"%s:failed in %s\n",
        +				str,SSL_state_string_long(s));
        +		else if (ret < 0)
        +			{
        +			BIO_printf(bio_err,"%s:error in %s\n",
        +				str,SSL_state_string_long(s));
        +			}
        +		}
        +	}
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_state_string(3)|SSL_state_string(3)>,
        +L<SSL_alert_type_string(3)|SSL_alert_type_string(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod
        new file mode 100644
        index 000000000..da68cb9fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod
        @@ -0,0 +1,77 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_max_cert_list, SSL_CTX_get_max_cert_list, SSL_set_max_cert_list, SSL_get_max_cert_list, - manipulate allowed for the peer's certificate chain
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_set_max_cert_list(SSL_CTX *ctx, long size);
        + long SSL_CTX_get_max_cert_list(SSL_CTX *ctx);
        +
        + long SSL_set_max_cert_list(SSL *ssl, long size);
        + long SSL_get_max_cert_list(SSL *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_max_cert_list() sets the maximum size allowed for the peer's
        +certificate chain for all SSL objects created from B<ctx> to be <size> bytes.
        +The SSL objects inherit the setting valid for B<ctx> at the time
        +L<SSL_new(3)|SSL_new(3)> is being called.
        +
        +SSL_CTX_get_max_cert_list() returns the currently set maximum size for B<ctx>.
        +
        +SSL_set_max_cert_list() sets the maximum size allowed for the peer's
        +certificate chain for B<ssl> to be <size> bytes. This setting stays valid
        +until a new value is set.
        +
        +SSL_get_max_cert_list() returns the currently set maximum size for B<ssl>.
        +
        +=head1 NOTES
        +
        +During the handshake process, the peer may send a certificate chain.
        +The TLS/SSL standard does not give any maximum size of the certificate chain.
        +The OpenSSL library handles incoming data by a dynamically allocated buffer.
        +In order to prevent this buffer from growing without bounds due to data
        +received from a faulty or malicious peer, a maximum size for the certificate
        +chain is set.
        +
        +The default value for the maximum certificate chain size is 100kB (30kB
        +on the 16bit DOS platform). This should be sufficient for usual certificate
        +chains (OpenSSL's default maximum chain length is 10, see
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>, and certificates
        +without special extensions have a typical size of 1-2kB).
        +
        +For special applications it can be necessary to extend the maximum certificate
        +chain size allowed to be sent by the peer, see e.g. the work on
        +"Internet X.509 Public Key Infrastructure Proxy Certificate Profile"
        +and "TLS Delegation Protocol" at http://www.ietf.org/ and
        +http://www.globus.org/ .
        +
        +Under normal conditions it should never be necessary to set a value smaller
        +than the default, as the buffer is handled dynamically and only uses the
        +memory actually required by the data sent by the peer.
        +
        +If the maximum certificate chain size allowed is exceeded, the handshake will
        +fail with a SSL_R_EXCESSIVE_MESSAGE_SIZE error.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_max_cert_list() and SSL_set_max_cert_list() return the previously
        +set value.
        +
        +SSL_CTX_get_max_cert_list() and SSL_get_max_cert_list() return the currently
        +set value.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>,
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
        +
        +=head1 HISTORY
        +
        +SSL*_set/get_max_cert_list() have been introduced in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_mode.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_mode.pod
        new file mode 100644
        index 000000000..8cb669dae
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_mode.pod
        @@ -0,0 +1,91 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_mode, SSL_set_mode, SSL_CTX_get_mode, SSL_get_mode - manipulate SSL engine mode
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_set_mode(SSL_CTX *ctx, long mode);
        + long SSL_set_mode(SSL *ssl, long mode);
        +
        + long SSL_CTX_get_mode(SSL_CTX *ctx);
        + long SSL_get_mode(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_mode() adds the mode set via bitmask in B<mode> to B<ctx>.
        +Options already set before are not cleared.
        +
        +SSL_set_mode() adds the mode set via bitmask in B<mode> to B<ssl>.
        +Options already set before are not cleared.
        +
        +SSL_CTX_get_mode() returns the mode set for B<ctx>.
        +
        +SSL_get_mode() returns the mode set for B<ssl>.
        +
        +=head1 NOTES
        +
        +The following mode changes are available:
        +
        +=over 4
        +
        +=item SSL_MODE_ENABLE_PARTIAL_WRITE
        +
        +Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
        +when just a single record has been written). When not set (the default),
        +SSL_write() will only report success once the complete chunk was written.
        +Once SSL_write() returns with r, r bytes have been successfully written
        +and the next call to SSL_write() must only send the n-r bytes left,
        +imitating the behaviour of write().
        +
        +=item SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
        +
        +Make it possible to retry SSL_write() with changed buffer location
        +(the buffer contents must stay the same). This is not the default to avoid
        +the misconception that non-blocking SSL_write() behaves like
        +non-blocking write().
        +
        +=item SSL_MODE_AUTO_RETRY
        +
        +Never bother the application with retries if the transport is blocking.
        +If a renegotiation take place during normal operation, a
        +L<SSL_read(3)|SSL_read(3)> or L<SSL_write(3)|SSL_write(3)> would return
        +with -1 and indicate the need to retry with SSL_ERROR_WANT_READ.
        +In a non-blocking environment applications must be prepared to handle
        +incomplete read/write operations.
        +In a blocking environment, applications are not always prepared to
        +deal with read/write operations returning without success report. The
        +flag SSL_MODE_AUTO_RETRY will cause read/write operations to only
        +return after the handshake and successful completion.
        +
        +=item SSL_MODE_RELEASE_BUFFERS
        +
        +When we no longer need a read buffer or a write buffer for a given SSL,
        +then release the memory we were using to hold it.  Released memory is
        +either appended to a list of unused RAM chunks on the SSL_CTX, or simply
        +freed if the list of unused chunks would become longer than 
        +SSL_CTX->freelist_max_len, which defaults to 32.  Using this flag can
        +save around 34k per idle SSL connection.
        +This flag has no effect on SSL v2 connections, or on DTLS connections.
        +
        +=back
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_mode() and SSL_set_mode() return the new mode bitmask
        +after adding B<mode>.
        +
        +SSL_CTX_get_mode() and SSL_get_mode() return the current bitmask.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_read(3)|SSL_read(3)>, L<SSL_write(3)|SSL_write(3)>
        +
        +=head1 HISTORY
        +
        +SSL_MODE_AUTO_RETRY as been added in OpenSSL 0.9.6.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod
        new file mode 100644
        index 000000000..0015e6ea7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod
        @@ -0,0 +1,99 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_msg_callback, SSL_CTX_set_msg_callback_arg, SSL_set_msg_callback, SSL_get_msg_callback_arg - install callback for observing protocol messages
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
        + void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg);
        +
        + void SSL_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
        + void SSL_set_msg_callback_arg(SSL_CTX *ctx, void *arg);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_msg_callback() or SSL_set_msg_callback() can be used to
        +define a message callback function I<cb> for observing all SSL/TLS
        +protocol messages (such as handshake messages) that are received or
        +sent.  SSL_CTX_set_msg_callback_arg() and SSL_set_msg_callback_arg()
        +can be used to set argument I<arg> to the callback function, which is
        +available for arbitrary application use.
        +
        +SSL_CTX_set_msg_callback() and SSL_CTX_set_msg_callback_arg() specify
        +default settings that will be copied to new B<SSL> objects by
        +L<SSL_new(3)|SSL_new(3)>. SSL_set_msg_callback() and
        +SSL_set_msg_callback_arg() modify the actual settings of an B<SSL>
        +object. Using a B<0> pointer for I<cb> disables the message callback.
        +
        +When I<cb> is called by the SSL/TLS library for a protocol message,
        +the function arguments have the following meaning:
        +
        +=over 4
        +
        +=item I<write_p>
        +
        +This flag is B<0> when a protocol message has been received and B<1>
        +when a protocol message has been sent.
        +
        +=item I<version>
        +
        +The protocol version according to which the protocol message is
        +interpreted by the library. Currently, this is one of
        +B<SSL2_VERSION>, B<SSL3_VERSION> and B<TLS1_VERSION> (for SSL 2.0, SSL
        +3.0 and TLS 1.0, respectively).
        +
        +=item I<content_type>
        +
        +In the case of SSL 2.0, this is always B<0>.  In the case of SSL 3.0
        +or TLS 1.0, this is one of the B<ContentType> values defined in the
        +protocol specification (B<change_cipher_spec(20)>, B<alert(21)>,
        +B<handshake(22)>; but never B<application_data(23)> because the
        +callback will only be called for protocol messages).
        +
        +=item I<buf>, I<len>
        +
        +I<buf> points to a buffer containing the protocol message, which
        +consists of I<len> bytes. The buffer is no longer valid after the
        +callback function has returned.
        +
        +=item I<ssl>
        +
        +The B<SSL> object that received or sent the message.
        +
        +=item I<arg>
        +
        +The user-defined argument optionally defined by
        +SSL_CTX_set_msg_callback_arg() or SSL_set_msg_callback_arg().
        +
        +=back
        +
        +=head1 NOTES
        +
        +Protocol messages are passed to the callback function after decryption
        +and fragment collection where applicable. (Thus record boundaries are
        +not visible.)
        +
        +If processing a received protocol message results in an error,
        +the callback function may not be called.  For example, the callback
        +function will never see messages that are considered too large to be
        +processed.
        +
        +Due to automatic protocol version negotiation, I<version> is not
        +necessarily the protocol version used by the sender of the message: If
        +a TLS 1.0 ClientHello message is received by an SSL 3.0-only server,
        +I<version> will be B<SSL3_VERSION>.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>
        +
        +=head1 HISTORY
        +
        +SSL_CTX_set_msg_callback(), SSL_CTX_set_msg_callback_arg(),
        +SSL_set_msg_callback() and SSL_get_msg_callback_arg() were added in OpenSSL 0.9.7.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_options.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_options.pod
        new file mode 100644
        index 000000000..cc588f3a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_options.pod
        @@ -0,0 +1,346 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options, SSL_clear_options, SSL_CTX_get_options, SSL_get_options, SSL_get_secure_renegotiation_support - manipulate SSL options
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_set_options(SSL_CTX *ctx, long options);
        + long SSL_set_options(SSL *ssl, long options);
        +
        + long SSL_CTX_clear_options(SSL_CTX *ctx, long options);
        + long SSL_clear_options(SSL *ssl, long options);
        +
        + long SSL_CTX_get_options(SSL_CTX *ctx);
        + long SSL_get_options(SSL *ssl);
        +
        + long SSL_get_secure_renegotiation_support(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +Note: all these functions are implemented using macros.
        +
        +SSL_CTX_set_options() adds the options set via bitmask in B<options> to B<ctx>.
        +Options already set before are not cleared!
        +
        +SSL_set_options() adds the options set via bitmask in B<options> to B<ssl>.
        +Options already set before are not cleared!
        +
        +SSL_CTX_clear_options() clears the options set via bitmask in B<options>
        +to B<ctx>.
        +
        +SSL_clear_options() clears the options set via bitmask in B<options> to B<ssl>.
        +
        +SSL_CTX_get_options() returns the options set for B<ctx>.
        +
        +SSL_get_options() returns the options set for B<ssl>.
        +
        +SSL_get_secure_renegotiation_support() indicates whether the peer supports
        +secure renegotiation.
        +
        +=head1 NOTES
        +
        +The behaviour of the SSL library can be changed by setting several options.
        +The options are coded as bitmasks and can be combined by a logical B<or>
        +operation (|).
        +
        +SSL_CTX_set_options() and SSL_set_options() affect the (external)
        +protocol behaviour of the SSL library. The (internal) behaviour of
        +the API can be changed by using the similar
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)> and SSL_set_mode() functions.
        +
        +During a handshake, the option settings of the SSL object are used. When
        +a new SSL object is created from a context using SSL_new(), the current
        +option setting is copied. Changes to B<ctx> do not affect already created
        +SSL objects. SSL_clear() does not affect the settings.
        +
        +The following B<bug workaround> options are available:
        +
        +=over 4
        +
        +=item SSL_OP_MICROSOFT_SESS_ID_BUG
        +
        +www.microsoft.com - when talking SSLv2, if session-id reuse is
        +performed, the session-id passed back in the server-finished message
        +is different from the one decided upon.
        +
        +=item SSL_OP_NETSCAPE_CHALLENGE_BUG
        +
        +Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
        +challenge but then appears to only use 16 bytes when generating the
        +encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
        +According to the SSLv3 spec, one should use 32 bytes for the challenge
        +when operating in SSLv2/v3 compatibility mode, but as mentioned above,
        +this breaks this server so 16 bytes is the way to go.
        +
        +=item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
        +
        +As of OpenSSL 0.9.8q and 1.0.0c, this option has no effect.
        +
        +=item SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
        +
        +...
        +
        +=item SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
        +
        +...
        +
        +=item SSL_OP_MSIE_SSLV2_RSA_PADDING
        +
        +As of OpenSSL 0.9.7h and 0.9.8a, this option has no effect.
        +
        +=item SSL_OP_SSLEAY_080_CLIENT_DH_BUG
        +
        +...
        +
        +=item SSL_OP_TLS_D5_BUG
        +
        +...
        +
        +=item SSL_OP_TLS_BLOCK_PADDING_BUG
        +
        +...
        +
        +=item SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
        +
        +Disables a countermeasure against a SSL 3.0/TLS 1.0 protocol
        +vulnerability affecting CBC ciphers, which cannot be handled by some
        +broken SSL implementations.  This option has no effect for connections
        +using other ciphers.
        +
        +=item SSL_OP_ALL
        +
        +All of the above bug workarounds.
        +
        +=back
        +
        +It is usually safe to use B<SSL_OP_ALL> to enable the bug workaround
        +options if compatibility with somewhat broken implementations is
        +desired.
        +
        +The following B<modifying> options are available:
        +
        +=over 4
        +
        +=item SSL_OP_TLS_ROLLBACK_BUG
        +
        +Disable version rollback attack detection.
        +
        +During the client key exchange, the client must send the same information
        +about acceptable SSL/TLS protocol levels as during the first hello. Some
        +clients violate this rule by adapting to the server's answer. (Example:
        +the client sends a SSLv2 hello and accepts up to SSLv3.1=TLSv1, the server
        +only understands up to SSLv3. In this case the client must still use the
        +same SSLv3.1=TLSv1 announcement. Some clients step down to SSLv3 with respect
        +to the server's answer and violate the version rollback protection.)
        +
        +=item SSL_OP_SINGLE_DH_USE
        +
        +Always create a new key when using temporary/ephemeral DH parameters
        +(see L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
        +This option must be used to prevent small subgroup attacks, when
        +the DH parameters were not generated using "strong" primes
        +(e.g. when using DSA-parameters, see L<dhparam(1)|dhparam(1)>).
        +If "strong" primes were used, it is not strictly necessary to generate
        +a new DH key during each handshake but it is also recommended.
        +B<SSL_OP_SINGLE_DH_USE> should therefore be enabled whenever
        +temporary/ephemeral DH parameters are used.
        +
        +=item SSL_OP_EPHEMERAL_RSA
        +
        +Always use ephemeral (temporary) RSA key when doing RSA operations
        +(see L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
        +According to the specifications this is only done, when a RSA key
        +can only be used for signature operations (namely under export ciphers
        +with restricted RSA keylength). By setting this option, ephemeral
        +RSA keys are always used. This option breaks compatibility with the
        +SSL/TLS specifications and may lead to interoperability problems with
        +clients and should therefore never be used. Ciphers with EDH (ephemeral
        +Diffie-Hellman) key exchange should be used instead.
        +
        +=item SSL_OP_CIPHER_SERVER_PREFERENCE
        +
        +When choosing a cipher, use the server's preferences instead of the client
        +preferences. When not set, the SSL server will always follow the clients
        +preferences. When set, the SSLv3/TLSv1 server will choose following its
        +own preferences. Because of the different protocol, for SSLv2 the server
        +will send its list of preferences to the client and the client chooses.
        +
        +=item SSL_OP_PKCS1_CHECK_1
        +
        +...
        +
        +=item SSL_OP_PKCS1_CHECK_2
        +
        +...
        +
        +=item SSL_OP_NETSCAPE_CA_DN_BUG
        +
        +If we accept a netscape connection, demand a client cert, have a
        +non-self-signed CA which does not have its CA in netscape, and the
        +browser has a cert, it will crash/hang.  Works for 3.x and 4.xbeta 
        +
        +=item SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
        +
        +...
        +
        +=item SSL_OP_NO_SSLv2
        +
        +Do not use the SSLv2 protocol.
        +
        +=item SSL_OP_NO_SSLv3
        +
        +Do not use the SSLv3 protocol.
        +
        +=item SSL_OP_NO_TLSv1
        +
        +Do not use the TLSv1 protocol.
        +
        +=item SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
        +
        +When performing renegotiation as a server, always start a new session
        +(i.e., session resumption requests are only accepted in the initial
        +handshake). This option is not needed for clients.
        +
        +=item SSL_OP_NO_TICKET
        +
        +Normally clients and servers will, where possible, transparently make use
        +of RFC4507bis tickets for stateless session resumption.
        +
        +If this option is set this functionality is disabled and tickets will
        +not be used by clients or servers.
        +
        +=item SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
        +
        +Allow legacy insecure renegotiation between OpenSSL and unpatched clients or
        +servers. See the B<SECURE RENEGOTIATION> section for more details.
        +
        +=item SSL_OP_LEGACY_SERVER_CONNECT
        +
        +Allow legacy insecure renegotiation between OpenSSL and unpatched servers
        +B<only>: this option is currently set by default. See the
        +B<SECURE RENEGOTIATION> section for more details.
        +
        +=back
        +
        +=head1 SECURE RENEGOTIATION
        +
        +OpenSSL 0.9.8m and later always attempts to use secure renegotiation as
        +described in RFC5746. This counters the prefix attack described in
        +CVE-2009-3555 and elsewhere.
        +
        +The deprecated and highly broken SSLv2 protocol does not support
        +renegotiation at all: its use is B<strongly> discouraged.
        +
        +This attack has far reaching consequences which application writers should be
        +aware of. In the description below an implementation supporting secure
        +renegotiation is referred to as I<patched>. A server not supporting secure
        +renegotiation is referred to as I<unpatched>.
        +
        +The following sections describe the operations permitted by OpenSSL's secure
        +renegotiation implementation.
        +
        +=head2 Patched client and server
        +
        +Connections and renegotiation are always permitted by OpenSSL implementations.
        +
        +=head2 Unpatched client and patched OpenSSL server
        +
        +The initial connection suceeds but client renegotiation is denied by the
        +server with a B<no_renegotiation> warning alert if TLS v1.0 is used or a fatal
        +B<handshake_failure> alert in SSL v3.0.
        +
        +If the patched OpenSSL server attempts to renegotiate a fatal
        +B<handshake_failure> alert is sent. This is because the server code may be
        +unaware of the unpatched nature of the client.
        +
        +If the option B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then
        +renegotiation B<always> succeeds.
        +
        +B<NB:> a bug in OpenSSL clients earlier than 0.9.8m (all of which are
        +unpatched) will result in the connection hanging if it receives a
        +B<no_renegotiation> alert. OpenSSL versions 0.9.8m and later will regard
        +a B<no_renegotiation> alert as fatal and respond with a fatal
        +B<handshake_failure> alert. This is because the OpenSSL API currently has
        +no provision to indicate to an application that a renegotiation attempt
        +was refused.
        +
        +=head2 Patched OpenSSL client and unpatched server.
        +
        +If the option B<SSL_OP_LEGACY_SERVER_CONNECT> or
        +B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> is set then initial connections
        +and renegotiation between patched OpenSSL clients and unpatched servers
        +succeeds. If neither option is set then initial connections to unpatched
        +servers will fail.
        +
        +The option B<SSL_OP_LEGACY_SERVER_CONNECT> is currently set by default even
        +though it has security implications: otherwise it would be impossible to
        +connect to unpatched servers (i.e. all of them initially) and this is clearly
        +not acceptable. Renegotiation is permitted because this does not add any
        +additional security issues: during an attack clients do not see any
        +renegotiations anyway.
        +
        +As more servers become patched the option B<SSL_OP_LEGACY_SERVER_CONNECT> will
        +B<not> be set by default in a future version of OpenSSL.
        +
        +OpenSSL client applications wishing to ensure they can connect to unpatched
        +servers should always B<set> B<SSL_OP_LEGACY_SERVER_CONNECT>
        +
        +OpenSSL client applications that want to ensure they can B<not> connect to
        +unpatched servers (and thus avoid any security issues) should always B<clear>
        +B<SSL_OP_LEGACY_SERVER_CONNECT> using SSL_CTX_clear_options() or
        +SSL_clear_options().
        +
        +The difference between the B<SSL_OP_LEGACY_SERVER_CONNECT> and
        +B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> options is that
        +B<SSL_OP_LEGACY_SERVER_CONNECT> enables initial connections and secure
        +renegotiation between OpenSSL clients and unpatched servers B<only>, while
        +B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION> allows initial connections
        +and renegotiation between OpenSSL and unpatched clients or servers.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_options() and SSL_set_options() return the new options bitmask
        +after adding B<options>.
        +
        +SSL_CTX_clear_options() and SSL_clear_options() return the new options bitmask
        +after clearing B<options>.
        +
        +SSL_CTX_get_options() and SSL_get_options() return the current bitmask.
        +
        +SSL_get_secure_renegotiation_support() returns 1 is the peer supports
        +secure renegotiation and 0 if it does not.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
        +L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
        +L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
        +L<dhparam(1)|dhparam(1)>
        +
        +=head1 HISTORY
        +
        +B<SSL_OP_CIPHER_SERVER_PREFERENCE> and
        +B<SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION> have been added in
        +OpenSSL 0.9.7.
        +
        +B<SSL_OP_TLS_ROLLBACK_BUG> has been added in OpenSSL 0.9.6 and was automatically
        +enabled with B<SSL_OP_ALL>. As of 0.9.7, it is no longer included in B<SSL_OP_ALL>
        +and must be explicitly set.
        +
        +B<SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS> has been added in OpenSSL 0.9.6e.
        +Versions up to OpenSSL 0.9.6c do not include the countermeasure that
        +can be disabled with this option (in OpenSSL 0.9.6d, it was always
        +enabled).
        +
        +SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL
        +0.9.8m.
        +
        +B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>, B<SSL_OP_LEGACY_SERVER_CONNECT>
        +and the function SSL_get_secure_renegotiation_support() were first added in
        +OpenSSL 0.9.8m.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod
        new file mode 100644
        index 000000000..573f89a92
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod
        @@ -0,0 +1,81 @@
        +=pod
        +
        +=begin comment
        +
        +Copyright 2005 Nokia. All rights reserved.
        +
        +The portions of the attached software ("Contribution") is developed by
        +Nokia Corporation and is licensed pursuant to the OpenSSL open source
        +license.
        +
        +The Contribution, originally written by Mika Kousa and Pasi Eronen of
        +Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        +support (see RFC 4279) to OpenSSL.
        +
        +No patent licenses or other rights except those expressly stated in
        +the OpenSSL open source license shall be deemed granted or received
        +expressly, by implication, estoppel, or otherwise.
        +
        +No assurances are provided by Nokia that the Contribution does not
        +infringe the patent or other intellectual property rights of any third
        +party or that the license provides you with all the necessary rights
        +to make use of the Contribution.
        +
        +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        +ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        +SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        +OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        +OTHERWISE.
        +
        +=end comment
        +
        +=head1 NAME
        +
        +SSL_CTX_set_psk_client_callback, SSL_set_psk_client_callback - set PSK client callback
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
        +	unsigned int (*callback)(SSL *ssl, const char *hint,
        +	char *identity, unsigned int max_identity_len,
        +	unsigned char *psk, unsigned int max_psk_len));
        + void SSL_set_psk_client_callback(SSL *ssl,
        +	unsigned int (*callback)(SSL *ssl, const char *hint,
        +	char *identity, unsigned int max_identity_len,
        + 	unsigned char *psk, unsigned int max_psk_len));
        +
        +
        +=head1 DESCRIPTION
        +
        +A client application must provide a callback function which is called
        +when the client is sending the ClientKeyExchange message to the server.
        +
        +The purpose of the callback function is to select the PSK identity and
        +the pre-shared key to use during the connection setup phase.
        +
        +The callback is set using functions SSL_CTX_set_psk_client_callback()
        +or SSL_set_psk_client_callback(). The callback function is given the
        +connection in parameter B<ssl>, a B<NULL>-terminated PSK identity hint
        +sent by the server in parameter B<hint>, a buffer B<identity> of
        +length B<max_identity_len> bytes where the the resulting
        +B<NULL>-terminated identity is to be stored, and a buffer B<psk> of
        +length B<max_psk_len> bytes where the resulting pre-shared key is to
        +be stored.
        +
        +=head1 NOTES
        +
        +Note that parameter B<hint> given to the callback may be B<NULL>.
        +
        +=head1 RETURN VALUES
        +
        +Return values from the client callback are interpreted as follows:
        +
        +On success (callback found a PSK identity and a pre-shared key to use)
        +the length (> 0) of B<psk> in bytes is returned.
        +
        +Otherwise or on errors callback should return 0. In this case
        +the connection setup fails.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod
        new file mode 100644
        index 000000000..393f8ff0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod
        @@ -0,0 +1,63 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_quiet_shutdown, SSL_CTX_get_quiet_shutdown, SSL_set_quiet_shutdown, SSL_get_quiet_shutdown - manipulate shutdown behaviour
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
        + int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
        +
        + void SSL_set_quiet_shutdown(SSL *ssl, int mode);
        + int SSL_get_quiet_shutdown(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_quiet_shutdown() sets the "quiet shutdown" flag for B<ctx> to be
        +B<mode>. SSL objects created from B<ctx> inherit the B<mode> valid at the time
        +L<SSL_new(3)|SSL_new(3)> is called. B<mode> may be 0 or 1.
        +
        +SSL_CTX_get_quiet_shutdown() returns the "quiet shutdown" setting of B<ctx>.
        +
        +SSL_set_quiet_shutdown() sets the "quiet shutdown" flag for B<ssl> to be
        +B<mode>. The setting stays valid until B<ssl> is removed with
        +L<SSL_free(3)|SSL_free(3)> or SSL_set_quiet_shutdown() is called again.
        +It is not changed when L<SSL_clear(3)|SSL_clear(3)> is called.
        +B<mode> may be 0 or 1.
        +
        +SSL_get_quiet_shutdown() returns the "quiet shutdown" setting of B<ssl>.
        +
        +=head1 NOTES
        +
        +Normally when a SSL connection is finished, the parties must send out
        +"close notify" alert messages using L<SSL_shutdown(3)|SSL_shutdown(3)>
        +for a clean shutdown.
        +
        +When setting the "quiet shutdown" flag to 1, L<SSL_shutdown(3)|SSL_shutdown(3)>
        +will set the internal flags to SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN.
        +(L<SSL_shutdown(3)|SSL_shutdown(3)> then behaves like
        +L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> called with
        +SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN.)
        +The session is thus considered to be shutdown, but no "close notify" alert
        +is sent to the peer. This behaviour violates the TLS standard.
        +
        +The default is normal shutdown behaviour as described by the TLS standard.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_quiet_shutdown() and SSL_set_quiet_shutdown() do not return
        +diagnostic information.
        +
        +SSL_CTX_get_quiet_shutdown() and SSL_get_quiet_shutdown return the current
        +setting.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_shutdown(3)|SSL_shutdown(3)>,
        +L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>, L<SSL_new(3)|SSL_new(3)>,
        +L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod
        new file mode 100644
        index 000000000..c5d2f43df
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod
        @@ -0,0 +1,137 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_session_cache_mode, SSL_CTX_get_session_cache_mode - enable/disable session caching
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_set_session_cache_mode(SSL_CTX ctx, long mode);
        + long SSL_CTX_get_session_cache_mode(SSL_CTX ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_session_cache_mode() enables/disables session caching
        +by setting the operational mode for B<ctx> to <mode>.
        +
        +SSL_CTX_get_session_cache_mode() returns the currently used cache mode.
        +
        +=head1 NOTES
        +
        +The OpenSSL library can store/retrieve SSL/TLS sessions for later reuse.
        +The sessions can be held in memory for each B<ctx>, if more than one
        +SSL_CTX object is being maintained, the sessions are unique for each SSL_CTX
        +object.
        +
        +In order to reuse a session, a client must send the session's id to the
        +server. It can only send exactly one id.  The server then either 
        +agrees to reuse the session or it starts a full handshake (to create a new
        +session).
        +
        +A server will lookup up the session in its internal session storage. If the
        +session is not found in internal storage or lookups for the internal storage
        +have been deactivated (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP), the server will try
        +the external storage if available.
        +
        +Since a client may try to reuse a session intended for use in a different
        +context, the session id context must be set by the server (see
        +L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>).
        +
        +The following session cache modes and modifiers are available:
        +
        +=over 4
        +
        +=item SSL_SESS_CACHE_OFF
        +
        +No session caching for client or server takes place.
        +
        +=item SSL_SESS_CACHE_CLIENT
        +
        +Client sessions are added to the session cache. As there is no reliable way
        +for the OpenSSL library to know whether a session should be reused or which
        +session to choose (due to the abstract BIO layer the SSL engine does not
        +have details about the connection), the application must select the session
        +to be reused by using the L<SSL_set_session(3)|SSL_set_session(3)>
        +function. This option is not activated by default.
        +
        +=item SSL_SESS_CACHE_SERVER
        +
        +Server sessions are added to the session cache. When a client proposes a
        +session to be reused, the server looks for the corresponding session in (first)
        +the internal session cache (unless SSL_SESS_CACHE_NO_INTERNAL_LOOKUP is set),
        +then (second) in the external cache if available. If the session is found, the
        +server will try to reuse the session.  This is the default.
        +
        +=item SSL_SESS_CACHE_BOTH
        +
        +Enable both SSL_SESS_CACHE_CLIENT and SSL_SESS_CACHE_SERVER at the same time.
        +
        +=item SSL_SESS_CACHE_NO_AUTO_CLEAR
        +
        +Normally the session cache is checked for expired sessions every
        +255 connections using the
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> function. Since
        +this may lead to a delay which cannot be controlled, the automatic
        +flushing may be disabled and
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> can be called
        +explicitly by the application.
        +
        +=item SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
        +
        +By setting this flag, session-resume operations in an SSL/TLS server will not
        +automatically look up sessions in the internal cache, even if sessions are
        +automatically stored there. If external session caching callbacks are in use,
        +this flag guarantees that all lookups are directed to the external cache.
        +As automatic lookup only applies for SSL/TLS servers, the flag has no effect on
        +clients.
        +
        +=item SSL_SESS_CACHE_NO_INTERNAL_STORE
        +
        +Depending on the presence of SSL_SESS_CACHE_CLIENT and/or SSL_SESS_CACHE_SERVER,
        +sessions negotiated in an SSL/TLS handshake may be cached for possible reuse.
        +Normally a new session is added to the internal cache as well as any external
        +session caching (callback) that is configured for the SSL_CTX. This flag will
        +prevent sessions being stored in the internal cache (though the application can
        +add them manually using L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>). Note:
        +in any SSL/TLS servers where external caching is configured, any successful
        +session lookups in the external cache (ie. for session-resume requests) would
        +normally be copied into the local cache before processing continues - this flag
        +prevents these additions to the internal cache as well.
        +
        +=item SSL_SESS_CACHE_NO_INTERNAL
        +
        +Enable both SSL_SESS_CACHE_NO_INTERNAL_LOOKUP and
        +SSL_SESS_CACHE_NO_INTERNAL_STORE at the same time.
        +
        +
        +=back
        +
        +The default mode is SSL_SESS_CACHE_SERVER.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_session_cache_mode() returns the previously set cache mode.
        +
        +SSL_CTX_get_session_cache_mode() returns the currently set cache mode.
        +
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
        +L<SSL_session_reused(3)|SSL_session_reused(3)>,
        +L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
        +L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
        +L<SSL_CTX_sess_set_cache_size(3)|SSL_CTX_sess_set_cache_size(3)>,
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>,
        +L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>,
        +L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>
        +
        +=head1 HISTORY
        +
        +SSL_SESS_CACHE_NO_INTERNAL_STORE and SSL_SESS_CACHE_NO_INTERNAL
        +were introduced in OpenSSL 0.9.6h.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod
        new file mode 100644
        index 000000000..58fc68550
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod
        @@ -0,0 +1,83 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_session_id_context, SSL_set_session_id_context - set context within which session can be reused (server side only)
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
        +                                    unsigned int sid_ctx_len);
        + int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
        +                                unsigned int sid_ctx_len);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_session_id_context() sets the context B<sid_ctx> of length
        +B<sid_ctx_len> within which a session can be reused for the B<ctx> object.
        +
        +SSL_set_session_id_context() sets the context B<sid_ctx> of length
        +B<sid_ctx_len> within which a session can be reused for the B<ssl> object.
        +
        +=head1 NOTES
        +
        +Sessions are generated within a certain context. When exporting/importing
        +sessions with B<i2d_SSL_SESSION>/B<d2i_SSL_SESSION> it would be possible,
        +to re-import a session generated from another context (e.g. another
        +application), which might lead to malfunctions. Therefore each application
        +must set its own session id context B<sid_ctx> which is used to distinguish
        +the contexts and is stored in exported sessions. The B<sid_ctx> can be
        +any kind of binary data with a given length, it is therefore possible
        +to use e.g. the name of the application and/or the hostname and/or service
        +name ...
        +
        +The session id context becomes part of the session. The session id context
        +is set by the SSL/TLS server. The SSL_CTX_set_session_id_context() and
        +SSL_set_session_id_context() functions are therefore only useful on the
        +server side.
        +
        +OpenSSL clients will check the session id context returned by the server
        +when reusing a session.
        +
        +The maximum length of the B<sid_ctx> is limited to
        +B<SSL_MAX_SSL_SESSION_ID_LENGTH>.
        +
        +=head1 WARNINGS
        +
        +If the session id context is not set on an SSL/TLS server and client
        +certificates are used, stored sessions
        +will not be reused but a fatal error will be flagged and the handshake
        +will fail.
        +
        +If a server returns a different session id context to an OpenSSL client
        +when reusing a session, an error will be flagged and the handshake will
        +fail. OpenSSL servers will always return the correct session id context,
        +as an OpenSSL server checks the session id context itself before reusing
        +a session as described above.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_session_id_context() and SSL_set_session_id_context()
        +return the following values:
        +
        +=over 4
        +
        +=item 0
        +
        +The length B<sid_ctx_len> of the session id context B<sid_ctx> exceeded
        +the maximum allowed length of B<SSL_MAX_SSL_SESSION_ID_LENGTH>. The error
        +is logged to the error stack.
        +
        +=item 1
        +
        +The operation succeeded.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod
        new file mode 100644
        index 000000000..254f2b439
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod
        @@ -0,0 +1,61 @@
        +=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 <openssl/ssl.h>
        +
        + int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *method);
        + int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
        + const SSL_METHOD *SSL_get_ssl_method(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_ssl_version() sets a new default TLS/SSL B<method> for SSL objects
        +newly created from this B<ctx>. SSL objects already created with
        +L<SSL_new(3)|SSL_new(3)> are not affected, except when
        +L<SSL_clear(3)|SSL_clear(3)> is being called.
        +
        +SSL_set_ssl_method() sets a new TLS/SSL B<method> for a particular B<ssl>
        +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<ssl>.
        +
        +=head1 NOTES
        +
        +The available B<method> choices are described in
        +L<SSL_CTX_new(3)|SSL_CTX_new(3)>.
        +
        +When L<SSL_clear(3)|SSL_clear(3)> 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<SSL_CTX_new(3)|SSL_CTX_new(3)>, L<SSL_new(3)|SSL_new(3)>,
        +L<SSL_clear(3)|SSL_clear(3)>, L<ssl(3)|ssl(3)>,
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_timeout.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_timeout.pod
        new file mode 100644
        index 000000000..e3de27c47
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_timeout.pod
        @@ -0,0 +1,59 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_timeout, SSL_CTX_get_timeout - manipulate timeout values for session caching
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
        + long SSL_CTX_get_timeout(SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_timeout() sets the timeout for newly created sessions for
        +B<ctx> to B<t>. The timeout value B<t> must be given in seconds.
        +
        +SSL_CTX_get_timeout() returns the currently set timeout value for B<ctx>.
        +
        +=head1 NOTES
        +
        +Whenever a new session is created, it is assigned a maximum lifetime. This
        +lifetime is specified by storing the creation time of the session and the
        +timeout value valid at this time. If the actual time is later than creation
        +time plus timeout, the session is not reused.
        +
        +Due to this realization, all sessions behave according to the timeout value
        +valid at the time of the session negotiation. Changes of the timeout value
        +do not affect already established sessions.
        +
        +The expiration time of a single session can be modified using the
        +L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)> family of functions.
        +
        +Expired sessions are removed from the internal session cache, whenever
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> is called, either
        +directly by the application or automatically (see
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>)
        +
        +The default value for session timeout is decided on a per protocol
        +basis, see L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>.
        +All currently supported protocols have the same default timeout value
        +of 300 seconds.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_timeout() returns the previously set timeout value.
        +
        +SSL_CTX_get_timeout() returns the currently set timeout value.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
        +L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
        new file mode 100644
        index 000000000..29d1f8a6f
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
        @@ -0,0 +1,170 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_tmp_dh_callback, SSL_CTX_set_tmp_dh, SSL_set_tmp_dh_callback, SSL_set_tmp_dh - handle DH keys for ephemeral key exchange
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
        +            DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
        + long SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh);
        +
        + void SSL_set_tmp_dh_callback(SSL_CTX *ctx,
        +            DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
        + long SSL_set_tmp_dh(SSL *ssl, DH *dh)
        +
        + DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength));
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_tmp_dh_callback() sets the callback function for B<ctx> to be
        +used when a DH parameters are required to B<tmp_dh_callback>.
        +The callback is inherited by all B<ssl> objects created from B<ctx>.
        +
        +SSL_CTX_set_tmp_dh() sets DH parameters to be used to be B<dh>.
        +The key is inherited by all B<ssl> objects created from B<ctx>.
        +
        +SSL_set_tmp_dh_callback() sets the callback only for B<ssl>.
        +
        +SSL_set_tmp_dh() sets the parameters only for B<ssl>.
        +
        +These functions apply to SSL/TLS servers only.
        +
        +=head1 NOTES
        +
        +When using a cipher with RSA authentication, an ephemeral DH key exchange
        +can take place. Ciphers with DSA keys always use ephemeral DH keys as well.
        +In these cases, the session data are negotiated using the
        +ephemeral/temporary DH key and the key supplied and certified
        +by the certificate chain is only used for signing.
        +Anonymous ciphers (without a permanent server key) also use ephemeral DH keys.
        +
        +Using ephemeral DH key exchange yields forward secrecy, as the connection
        +can only be decrypted, when the DH key is known. By generating a temporary
        +DH key inside the server application that is lost when the application
        +is left, it becomes impossible for an attacker to decrypt past sessions,
        +even if he gets hold of the normal (certified) key, as this key was
        +only used for signing.
        +
        +In order to perform a DH key exchange the server must use a DH group
        +(DH parameters) and generate a DH key. The server will always generate a new
        +DH key during the negotiation, when the DH parameters are supplied via
        +callback and/or when the SSL_OP_SINGLE_DH_USE option of
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)> is set. It will
        +immediately create a DH key, when DH parameters are supplied via
        +SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. In this case,
        +it may happen that a key is generated on initialization without later
        +being needed, while on the other hand the computer time during the
        +negotiation is being saved.
        +
        +If "strong" primes were used to generate the DH parameters, it is not strictly
        +necessary to generate a new key for each handshake but it does improve forward
        +secrecy. If it is not assured, that "strong" primes were used (see especially
        +the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used
        +in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE
        +has an impact on the computer time needed during negotiation, but it is not
        +very large, so application authors/users should consider to always enable
        +this option.
        +
        +As generating DH parameters is extremely time consuming, an application
        +should not generate the parameters on the fly but supply the parameters.
        +DH parameters can be reused, as the actual key is newly generated during
        +the negotiation. The risk in reusing DH parameters is that an attacker
        +may specialize on a very often used DH group. Applications should therefore
        +generate their own DH parameters during the installation process using the
        +openssl L<dhparam(1)|dhparam(1)> application. In order to reduce the computer
        +time needed for this generation, it is possible to use DSA parameters
        +instead (see L<dhparam(1)|dhparam(1)>), but in this case SSL_OP_SINGLE_DH_USE
        +is mandatory.
        +
        +Application authors may compile in DH parameters. Files dh512.pem,
        +dh1024.pem, dh2048.pem, and dh4096 in the 'apps' directory of current
        +version of the OpenSSL distribution contain the 'SKIP' DH parameters,
        +which use safe primes and were generated verifiably pseudo-randomly.
        +These files can be converted into C code using the B<-C> option of the
        +L<dhparam(1)|dhparam(1)> application.
        +Authors may also generate their own set of parameters using
        +L<dhparam(1)|dhparam(1)>, but a user may not be sure how the parameters were
        +generated. The generation of DH parameters during installation is therefore
        +recommended.
        +
        +An application may either directly specify the DH parameters or
        +can supply the DH parameters via a callback function. The callback approach
        +has the advantage, that the callback may supply DH parameters for different
        +key lengths.
        +
        +The B<tmp_dh_callback> is called with the B<keylength> needed and
        +the B<is_export> information. The B<is_export> flag is set, when the
        +ephemeral DH key exchange is performed with an export cipher.
        +
        +=head1 EXAMPLES
        +
        +Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling
        +partly left out.)
        +
        + ...
        + /* Set up ephemeral DH stuff */
        + DH *dh_512 = NULL;
        + DH *dh_1024 = NULL;
        + FILE *paramfile;
        +
        + ...
        + /* "openssl dhparam -out dh_param_512.pem -2 512" */
        + paramfile = fopen("dh_param_512.pem", "r");
        + if (paramfile) {
        +   dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
        +   fclose(paramfile);
        + }
        + /* "openssl dhparam -out dh_param_1024.pem -2 1024" */
        + paramfile = fopen("dh_param_1024.pem", "r");
        + if (paramfile) {
        +   dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
        +   fclose(paramfile);
        + }
        + ...
        +
        + /* "openssl dhparam -C -2 512" etc... */
        + DH *get_dh512() { ... }
        + DH *get_dh1024() { ... }
        +
        + DH *tmp_dh_callback(SSL *s, int is_export, int keylength)
        + {
        +    DH *dh_tmp=NULL;
        +
        +    switch (keylength) {
        +    case 512:
        +      if (!dh_512)
        +        dh_512 = get_dh512();
        +      dh_tmp = dh_512;
        +      break;
        +    case 1024:
        +      if (!dh_1024) 
        +        dh_1024 = get_dh1024();
        +      dh_tmp = dh_1024;
        +      break;
        +    default:
        +      /* Generating a key on the fly is very costly, so use what is there */
        +      setup_dh_parameters_like_above();
        +    }
        +    return(dh_tmp);
        + }
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_tmp_dh_callback() and SSL_set_tmp_dh_callback() do not return
        +diagnostic output.
        +
        +SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() do return 1 on success and 0
        +on failure. Check the error queue to find out the reason of failure.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
        +L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
        +L<ciphers(1)|ciphers(1)>, L<dhparam(1)|dhparam(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
        new file mode 100644
        index 000000000..534643cd9
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
        @@ -0,0 +1,166 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_tmp_rsa_callback, SSL_CTX_set_tmp_rsa, SSL_CTX_need_tmp_rsa, SSL_set_tmp_rsa_callback, SSL_set_tmp_rsa, SSL_need_tmp_rsa - handle RSA keys for ephemeral key exchange
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
        +            RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength));
        + long SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, RSA *rsa);
        + long SSL_CTX_need_tmp_rsa(SSL_CTX *ctx);
        +
        + void SSL_set_tmp_rsa_callback(SSL_CTX *ctx,
        +            RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength));
        + long SSL_set_tmp_rsa(SSL *ssl, RSA *rsa)
        + long SSL_need_tmp_rsa(SSL *ssl)
        +
        + RSA *(*tmp_rsa_callback)(SSL *ssl, int is_export, int keylength);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_tmp_rsa_callback() sets the callback function for B<ctx> to be
        +used when a temporary/ephemeral RSA key is required to B<tmp_rsa_callback>.
        +The callback is inherited by all SSL objects newly created from B<ctx>
        +with <SSL_new(3)|SSL_new(3)>. Already created SSL objects are not affected.
        +
        +SSL_CTX_set_tmp_rsa() sets the temporary/ephemeral RSA key to be used to be
        +B<rsa>. The key is inherited by all SSL objects newly created from B<ctx>
        +with <SSL_new(3)|SSL_new(3)>. Already created SSL objects are not affected.
        +
        +SSL_CTX_need_tmp_rsa() returns 1, if a temporary/ephemeral RSA key is needed
        +for RSA-based strength-limited 'exportable' ciphersuites because a RSA key
        +with a keysize larger than 512 bits is installed.
        +
        +SSL_set_tmp_rsa_callback() sets the callback only for B<ssl>.
        +
        +SSL_set_tmp_rsa() sets the key only for B<ssl>.
        +
        +SSL_need_tmp_rsa() returns 1, if a temporary/ephemeral RSA key is needed,
        +for RSA-based strength-limited 'exportable' ciphersuites because a RSA key
        +with a keysize larger than 512 bits is installed.
        +
        +These functions apply to SSL/TLS servers only.
        +
        +=head1 NOTES
        +
        +When using a cipher with RSA authentication, an ephemeral RSA key exchange
        +can take place. In this case the session data are negotiated using the
        +ephemeral/temporary RSA key and the RSA key supplied and certified
        +by the certificate chain is only used for signing.
        +
        +Under previous export restrictions, ciphers with RSA keys shorter (512 bits)
        +than the usual key length of 1024 bits were created. To use these ciphers
        +with RSA keys of usual length, an ephemeral key exchange must be performed,
        +as the normal (certified) key cannot be directly used.
        +
        +Using ephemeral RSA key exchange yields forward secrecy, as the connection
        +can only be decrypted, when the RSA key is known. By generating a temporary
        +RSA key inside the server application that is lost when the application
        +is left, it becomes impossible for an attacker to decrypt past sessions,
        +even if he gets hold of the normal (certified) RSA key, as this key was
        +used for signing only. The downside is that creating a RSA key is
        +computationally expensive.
        +
        +Additionally, the use of ephemeral RSA key exchange is only allowed in
        +the TLS standard, when the RSA key can be used for signing only, that is
        +for export ciphers. Using ephemeral RSA key exchange for other purposes
        +violates the standard and can break interoperability with clients.
        +It is therefore strongly recommended to not use ephemeral RSA key
        +exchange and use EDH (Ephemeral Diffie-Hellman) key exchange instead
        +in order to achieve forward secrecy (see
        +L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
        +
        +On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
        +and must be explicitly enabled  using the SSL_OP_EPHEMERAL_RSA option of
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, violating the TLS/SSL
        +standard. When ephemeral RSA key exchange is required for export ciphers,
        +it will automatically be used without this option!
        +
        +An application may either directly specify the key or can supply the key via
        +a callback function. The callback approach has the advantage, that the
        +callback may generate the key only in case it is actually needed. As the
        +generation of a RSA key is however costly, it will lead to a significant
        +delay in the handshake procedure.  Another advantage of the callback function
        +is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
        +usage) while the explicit setting of the key is only useful for key size of
        +512 bits to satisfy the export restricted ciphers and does give away key length
        +if a longer key would be allowed.
        +
        +The B<tmp_rsa_callback> is called with the B<keylength> needed and
        +the B<is_export> information. The B<is_export> flag is set, when the
        +ephemeral RSA key exchange is performed with an export cipher.
        +
        +=head1 EXAMPLES
        +
        +Generate temporary RSA keys to prepare ephemeral RSA key exchange. As the
        +generation of a RSA key costs a lot of computer time, they saved for later
        +reuse. For demonstration purposes, two keys for 512 bits and 1024 bits
        +respectively are generated.
        +
        + ...
        + /* Set up ephemeral RSA stuff */
        + RSA *rsa_512 = NULL;
        + RSA *rsa_1024 = NULL;
        +
        + rsa_512 = RSA_generate_key(512,RSA_F4,NULL,NULL);
        + if (rsa_512 == NULL)
        +     evaluate_error_queue();
        +
        + rsa_1024 = RSA_generate_key(1024,RSA_F4,NULL,NULL);
        + if (rsa_1024 == NULL)
        +   evaluate_error_queue();
        +
        + ...
        +
        + RSA *tmp_rsa_callback(SSL *s, int is_export, int keylength)
        + {
        +    RSA *rsa_tmp=NULL;
        +
        +    switch (keylength) {
        +    case 512:
        +      if (rsa_512)
        +        rsa_tmp = rsa_512;
        +      else { /* generate on the fly, should not happen in this example */
        +        rsa_tmp = RSA_generate_key(keylength,RSA_F4,NULL,NULL);
        +        rsa_512 = rsa_tmp; /* Remember for later reuse */
        +      }
        +      break;
        +    case 1024:
        +      if (rsa_1024)
        +        rsa_tmp=rsa_1024;
        +      else
        +        should_not_happen_in_this_example();
        +      break;
        +    default:
        +      /* Generating a key on the fly is very costly, so use what is there */
        +      if (rsa_1024)
        +        rsa_tmp=rsa_1024;
        +      else
        +        rsa_tmp=rsa_512; /* Use at least a shorter key */
        +    }
        +    return(rsa_tmp);
        + }
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_tmp_rsa_callback() and SSL_set_tmp_rsa_callback() do not return
        +diagnostic output.
        +
        +SSL_CTX_set_tmp_rsa() and SSL_set_tmp_rsa() do return 1 on success and 0
        +on failure. Check the error queue to find out the reason of failure.
        +
        +SSL_CTX_need_tmp_rsa() and SSL_need_tmp_rsa() return 1 if a temporary
        +RSA key is needed and 0 otherwise.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
        +L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
        +L<SSL_new(3)|SSL_new(3)>, L<ciphers(1)|ciphers(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_verify.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_verify.pod
        new file mode 100644
        index 000000000..81566839d
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_set_verify.pod
        @@ -0,0 +1,294 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_set_verify, SSL_set_verify, SSL_CTX_set_verify_depth, SSL_set_verify_depth - set peer certificate verification parameters
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
        +                         int (*verify_callback)(int, X509_STORE_CTX *));
        + void SSL_set_verify(SSL *s, int mode,
        +                     int (*verify_callback)(int, X509_STORE_CTX *));
        + void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
        + void SSL_set_verify_depth(SSL *s, int depth);
        +
        + int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_set_verify() sets the verification flags for B<ctx> to be B<mode> and
        +specifies the B<verify_callback> function to be used. If no callback function
        +shall be specified, the NULL pointer can be used for B<verify_callback>.
        +
        +SSL_set_verify() sets the verification flags for B<ssl> to be B<mode> and
        +specifies the B<verify_callback> function to be used. If no callback function
        +shall be specified, the NULL pointer can be used for B<verify_callback>. In
        +this case last B<verify_callback> set specifically for this B<ssl> remains. If
        +no special B<callback> was set before, the default callback for the underlying
        +B<ctx> is used, that was valid at the time B<ssl> was created with
        +L<SSL_new(3)|SSL_new(3)>.
        +
        +SSL_CTX_set_verify_depth() sets the maximum B<depth> for the certificate chain
        +verification that shall be allowed for B<ctx>. (See the BUGS section.)
        +
        +SSL_set_verify_depth() sets the maximum B<depth> for the certificate chain
        +verification that shall be allowed for B<ssl>. (See the BUGS section.)
        +
        +=head1 NOTES
        +
        +The verification of certificates can be controlled by a set of logically
        +or'ed B<mode> flags:
        +
        +=over 4
        +
        +=item SSL_VERIFY_NONE
        +
        +B<Server mode:> the server will not send a client certificate request to the
        +client, so the client will not send a certificate.
        +
        +B<Client mode:> if not using an anonymous cipher (by default disabled), the
        +server will send a certificate which will be checked. The result of the
        +certificate verification process can be checked after the TLS/SSL handshake
        +using the L<SSL_get_verify_result(3)|SSL_get_verify_result(3)> function.
        +The handshake will be continued regardless of the verification result.
        +
        +=item SSL_VERIFY_PEER
        +
        +B<Server mode:> the server sends a client certificate request to the client.
        +The certificate returned (if any) is checked. If the verification process
        +fails, the TLS/SSL handshake is
        +immediately terminated with an alert message containing the reason for
        +the verification failure.
        +The behaviour can be controlled by the additional
        +SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
        +
        +B<Client mode:> the server certificate is verified. If the verification process
        +fails, the TLS/SSL handshake is
        +immediately terminated with an alert message containing the reason for
        +the verification failure. If no server certificate is sent, because an
        +anonymous cipher is used, SSL_VERIFY_PEER is ignored.
        +
        +=item SSL_VERIFY_FAIL_IF_NO_PEER_CERT
        +
        +B<Server mode:> if the client did not return a certificate, the TLS/SSL
        +handshake is immediately terminated with a "handshake failure" alert.
        +This flag must be used together with SSL_VERIFY_PEER.
        +
        +B<Client mode:> ignored
        +
        +=item SSL_VERIFY_CLIENT_ONCE
        +
        +B<Server mode:> only request a client certificate on the initial TLS/SSL
        +handshake. Do not ask for a client certificate again in case of a
        +renegotiation. This flag must be used together with SSL_VERIFY_PEER.
        +
        +B<Client mode:> ignored
        +
        +=back
        +
        +Exactly one of the B<mode> flags SSL_VERIFY_NONE and SSL_VERIFY_PEER must be
        +set at any time.
        +
        +The actual verification procedure is performed either using the built-in
        +verification procedure or using another application provided verification
        +function set with
        +L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>.
        +The following descriptions apply in the case of the built-in procedure. An
        +application provided procedure also has access to the verify depth information
        +and the verify_callback() function, but the way this information is used
        +may be different.
        +
        +SSL_CTX_set_verify_depth() and SSL_set_verify_depth() set the limit up
        +to which depth certificates in a chain are used during the verification
        +procedure. If the certificate chain is longer than allowed, the certificates
        +above the limit are ignored. Error messages are generated as if these
        +certificates would not be present, most likely a
        +X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY will be issued.
        +The depth count is "level 0:peer certificate", "level 1: CA certificate",
        +"level 2: higher level CA certificate", and so on. Setting the maximum
        +depth to 2 allows the levels 0, 1, and 2. The default depth limit is 9,
        +allowing for the peer certificate and additional 9 CA certificates.
        +
        +The B<verify_callback> function is used to control the behaviour when the
        +SSL_VERIFY_PEER flag is set. It must be supplied by the application and
        +receives two arguments: B<preverify_ok> indicates, whether the verification of
        +the certificate in question was passed (preverify_ok=1) or not
        +(preverify_ok=0). B<x509_ctx> is a pointer to the complete context used
        +for the certificate chain verification.
        +
        +The certificate chain is checked starting with the deepest nesting level
        +(the root CA certificate) and worked upward to the peer's certificate.
        +At each level signatures and issuer attributes are checked. Whenever
        +a verification error is found, the error number is stored in B<x509_ctx>
        +and B<verify_callback> is called with B<preverify_ok>=0. By applying
        +X509_CTX_store_* functions B<verify_callback> can locate the certificate
        +in question and perform additional steps (see EXAMPLES). If no error is
        +found for a certificate, B<verify_callback> is called with B<preverify_ok>=1
        +before advancing to the next level.
        +
        +The return value of B<verify_callback> controls the strategy of the further
        +verification process. If B<verify_callback> returns 0, the verification
        +process is immediately stopped with "verification failed" state. If
        +SSL_VERIFY_PEER is set, a verification failure alert is sent to the peer and
        +the TLS/SSL handshake is terminated. If B<verify_callback> returns 1,
        +the verification process is continued. If B<verify_callback> always returns
        +1, the TLS/SSL handshake will not be terminated with respect to verification
        +failures and the connection will be established. The calling process can
        +however retrieve the error code of the last verification error using
        +L<SSL_get_verify_result(3)|SSL_get_verify_result(3)> or by maintaining its
        +own error storage managed by B<verify_callback>.
        +
        +If no B<verify_callback> is specified, the default callback will be used.
        +Its return value is identical to B<preverify_ok>, so that any verification
        +failure will lead to a termination of the TLS/SSL handshake with an
        +alert message, if SSL_VERIFY_PEER is set.
        +
        +=head1 BUGS
        +
        +In client mode, it is not checked whether the SSL_VERIFY_PEER flag
        +is set, but whether SSL_VERIFY_NONE is not set. This can lead to
        +unexpected behaviour, if the SSL_VERIFY_PEER and SSL_VERIFY_NONE are not
        +used as required (exactly one must be set at any time).
        +
        +The certificate verification depth set with SSL[_CTX]_verify_depth()
        +stops the verification at a certain depth. The error message produced
        +will be that of an incomplete certificate chain and not
        +X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected.
        +
        +=head1 RETURN VALUES
        +
        +The SSL*_set_verify*() functions do not provide diagnostic information.
        +
        +=head1 EXAMPLES
        +
        +The following code sequence realizes an example B<verify_callback> function
        +that will always continue the TLS/SSL handshake regardless of verification
        +failure, if wished. The callback realizes a verification depth limit with
        +more informational output.
        +
        +All verification errors are printed, informations about the certificate chain
        +are printed on request.
        +The example is realized for a server that does allow but not require client
        +certificates.
        +
        +The example makes use of the ex_data technique to store application data
        +into/retrieve application data from the SSL structure
        +(see L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>,
        +L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>).
        +
        + ...
        + typedef struct {
        +   int verbose_mode;
        +   int verify_depth;
        +   int always_continue;
        + } mydata_t;
        + int mydata_index;
        + ...
        + static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
        + {
        +    char    buf[256];
        +    X509   *err_cert;
        +    int     err, depth;
        +    SSL    *ssl;
        +    mydata_t *mydata;
        +
        +    err_cert = X509_STORE_CTX_get_current_cert(ctx);
        +    err = X509_STORE_CTX_get_error(ctx);
        +    depth = X509_STORE_CTX_get_error_depth(ctx);
        +
        +    /*
        +     * Retrieve the pointer to the SSL of the connection currently treated
        +     * and the application specific data stored into the SSL object.
        +     */
        +    ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
        +    mydata = SSL_get_ex_data(ssl, mydata_index);
        +
        +    X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
        +
        +    /*
        +     * Catch a too long certificate chain. The depth limit set using
        +     * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
        +     * that whenever the "depth>verify_depth" condition is met, we
        +     * have violated the limit and want to log this error condition.
        +     * We must do it here, because the CHAIN_TOO_LONG error would not
        +     * be found explicitly; only errors introduced by cutting off the
        +     * additional certificates would be logged.
        +     */
        +    if (depth > mydata->verify_depth) {
        +        preverify_ok = 0;
        +        err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
        +        X509_STORE_CTX_set_error(ctx, err);
        +    } 
        +    if (!preverify_ok) {
        +        printf("verify error:num=%d:%s:depth=%d:%s\n", err,
        +                 X509_verify_cert_error_string(err), depth, buf);
        +    }
        +    else if (mydata->verbose_mode)
        +    {
        +        printf("depth=%d:%s\n", depth, buf);
        +    }
        +
        +    /*
        +     * At this point, err contains the last verification error. We can use
        +     * it for something special
        +     */
        +    if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
        +    {
        +      X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
        +      printf("issuer= %s\n", buf);
        +    }
        +
        +    if (mydata->always_continue)
        +      return 1;
        +    else
        +      return preverify_ok;
        + }
        + ...
        +
        + mydata_t mydata;
        +
        + ...
        + mydata_index = SSL_get_ex_new_index(0, "mydata index", NULL, NULL, NULL);
        +
        + ...
        + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
        +                    verify_callback);
        +
        + /*
        +  * Let the verify_callback catch the verify_depth error so that we get
        +  * an appropriate error in the logfile.
        +  */
        + SSL_CTX_set_verify_depth(verify_depth + 1);
        +
        + /*
        +  * Set up the SSL specific data into "mydata" and store it into th SSL
        +  * structure.
        +  */
        + mydata.verify_depth = verify_depth; ...
        + SSL_set_ex_data(ssl, mydata_index, &mydata);
        +					     
        + ...
        + SSL_accept(ssl);	/* check of success left out for clarity */
        + if (peer = SSL_get_peer_certificate(ssl))
        + {
        +   if (SSL_get_verify_result(ssl) == X509_V_OK)
        +   {
        +     /* The client sent a certificate which verified OK */
        +   }
        + }
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>,
        +L<SSL_CTX_get_verify_mode(3)|SSL_CTX_get_verify_mode(3)>,
        +L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
        +L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
        +L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>,
        +L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>,
        +L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_use_certificate.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_use_certificate.pod
        new file mode 100644
        index 000000000..10be95fdb
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_use_certificate.pod
        @@ -0,0 +1,169 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_CTX_use_certificate, SSL_CTX_use_certificate_ASN1, SSL_CTX_use_certificate_file, SSL_use_certificate, SSL_use_certificate_ASN1, SSL_use_certificate_file, SSL_CTX_use_certificate_chain_file, SSL_CTX_use_PrivateKey, SSL_CTX_use_PrivateKey_ASN1, SSL_CTX_use_PrivateKey_file, SSL_CTX_use_RSAPrivateKey, SSL_CTX_use_RSAPrivateKey_ASN1, SSL_CTX_use_RSAPrivateKey_file, SSL_use_PrivateKey_file, SSL_use_PrivateKey_ASN1, SSL_use_PrivateKey, SSL_use_RSAPrivateKey, SSL_use_RSAPrivateKey_ASN1, SSL_use_RSAPrivateKey_file, SSL_CTX_check_private_key, SSL_check_private_key - load certificate and key data
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
        + int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d);
        + int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
        + int SSL_use_certificate(SSL *ssl, X509 *x);
        + int SSL_use_certificate_ASN1(SSL *ssl, unsigned char *d, int len);
        + int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
        +
        + int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
        +
        + int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
        + int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d,
        +				 long len);
        + int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
        + int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
        + int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len);
        + int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
        + int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
        + int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, unsigned char *d, long len);
        + int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
        + int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
        + int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
        + int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
        +
        + int SSL_CTX_check_private_key(const SSL_CTX *ctx);
        + int SSL_check_private_key(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +These functions load the certificates and private keys into the SSL_CTX
        +or SSL object, respectively.
        +
        +The SSL_CTX_* class of functions loads the certificates and keys into the
        +SSL_CTX object B<ctx>. The information is passed to SSL objects B<ssl>
        +created from B<ctx> with L<SSL_new(3)|SSL_new(3)> by copying, so that
        +changes applied to B<ctx> do not propagate to already existing SSL objects.
        +
        +The SSL_* class of functions only loads certificates and keys into a
        +specific SSL object. The specific information is kept, when
        +L<SSL_clear(3)|SSL_clear(3)> is called for this SSL object.
        +
        +SSL_CTX_use_certificate() loads the certificate B<x> into B<ctx>,
        +SSL_use_certificate() loads B<x> into B<ssl>. The rest of the
        +certificates needed to form the complete certificate chain can be
        +specified using the
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>
        +function.
        +
        +SSL_CTX_use_certificate_ASN1() loads the ASN1 encoded certificate from
        +the memory location B<d> (with length B<len>) into B<ctx>,
        +SSL_use_certificate_ASN1() loads the ASN1 encoded certificate into B<ssl>.
        +
        +SSL_CTX_use_certificate_file() loads the first certificate stored in B<file>
        +into B<ctx>. The formatting B<type> of the certificate must be specified
        +from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1.
        +SSL_use_certificate_file() loads the certificate from B<file> into B<ssl>.
        +See the NOTES section on why SSL_CTX_use_certificate_chain_file()
        +should be preferred.
        +
        +SSL_CTX_use_certificate_chain_file() loads a certificate chain from 
        +B<file> into B<ctx>. The certificates must be in PEM format and must
        +be sorted starting with the subject's certificate (actual client or server
        +certificate), followed by intermediate CA certificates if applicable, and
        +ending at the highest level (root) CA.
        +There is no corresponding function working on a single SSL object.
        +
        +SSL_CTX_use_PrivateKey() adds B<pkey> as private key to B<ctx>.
        +SSL_CTX_use_RSAPrivateKey() adds the private key B<rsa> of type RSA
        +to B<ctx>. SSL_use_PrivateKey() adds B<pkey> as private key to B<ssl>;
        +SSL_use_RSAPrivateKey() adds B<rsa> as private key of type RSA to B<ssl>.
        +If a certificate has already been set and the private does not belong
        +to the certificate an error is returned. To change a certificate, private
        +key pair the new certificate needs to be set with SSL_use_certificate()
        +or SSL_CTX_use_certificate() before setting the private key with
        +SSL_CTX_use_PrivateKey() or SSL_use_PrivateKey(). 
        +
        +
        +SSL_CTX_use_PrivateKey_ASN1() adds the private key of type B<pk>
        +stored at memory location B<d> (length B<len>) to B<ctx>.
        +SSL_CTX_use_RSAPrivateKey_ASN1() adds the private key of type RSA
        +stored at memory location B<d> (length B<len>) to B<ctx>.
        +SSL_use_PrivateKey_ASN1() and SSL_use_RSAPrivateKey_ASN1() add the private
        +key to B<ssl>.
        +
        +SSL_CTX_use_PrivateKey_file() adds the first private key found in
        +B<file> to B<ctx>. The formatting B<type> of the certificate must be specified
        +from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1.
        +SSL_CTX_use_RSAPrivateKey_file() adds the first private RSA key found in
        +B<file> to B<ctx>. SSL_use_PrivateKey_file() adds the first private key found
        +in B<file> to B<ssl>; SSL_use_RSAPrivateKey_file() adds the first private
        +RSA key found to B<ssl>.
        +
        +SSL_CTX_check_private_key() checks the consistency of a private key with
        +the corresponding certificate loaded into B<ctx>. If more than one
        +key/certificate pair (RSA/DSA) is installed, the last item installed will
        +be checked. If e.g. the last item was a RSA certificate or key, the RSA
        +key/certificate pair will be checked. SSL_check_private_key() performs
        +the same check for B<ssl>. If no key/certificate was explicitly added for
        +this B<ssl>, the last item added into B<ctx> will be checked.
        +
        +=head1 NOTES
        +  
        +The internal certificate store of OpenSSL can hold two private key/certificate
        +pairs at a time: one key/certificate of type RSA and one key/certificate
        +of type DSA. The certificate used depends on the cipher select, see
        +also L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>.
        +
        +When reading certificates and private keys from file, files of type
        +SSL_FILETYPE_ASN1 (also known as B<DER>, binary encoding) can only contain
        +one certificate or private key, consequently 
        +SSL_CTX_use_certificate_chain_file() is only applicable to PEM formatting.
        +Files of type SSL_FILETYPE_PEM can contain more than one item.
        +
        +SSL_CTX_use_certificate_chain_file() adds the first certificate found
        +in the file to the certificate store. The other certificates are added
        +to the store of chain certificates using
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>.
        +There exists only one extra chain store, so that the same chain is appended
        +to both types of certificates, RSA and DSA! If it is not intended to use
        +both type of certificate at the same time, it is recommended to use the
        +SSL_CTX_use_certificate_chain_file() instead of the
        +SSL_CTX_use_certificate_file() function in order to allow the use of
        +complete certificate chains even when no trusted CA storage is used or
        +when the CA issuing the certificate shall not be added to the trusted
        +CA storage.
        +
        +If additional certificates are needed to complete the chain during the
        +TLS negotiation, CA certificates are additionally looked up in the
        +locations of trusted CA certificates, see
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>.
        +
        +The private keys loaded from file can be encrypted. In order to successfully
        +load encrypted keys, a function returning the passphrase must have been
        +supplied, see
        +L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>.
        +(Certificate files might be encrypted as well from the technical point
        +of view, it however does not make sense as the data in the certificate
        +is considered public anyway.)
        +
        +=head1 RETURN VALUES
        +
        +On success, the functions return 1.
        +Otherwise check out the error stack to find out the reason.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>,
        +L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>,
        +L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
        +L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>,
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>
        +
        +=head1 HISTORY
        +
        +Support for DER encoded private keys (SSL_FILETYPE_ASN1) in
        +SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() was added
        +in 0.9.8 .
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod b/vendor/openssl/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod
        new file mode 100644
        index 000000000..b80e25be7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod
        @@ -0,0 +1,102 @@
        +=pod
        +
        +=begin comment
        +
        +Copyright 2005 Nokia. All rights reserved.
        +
        +The portions of the attached software ("Contribution") is developed by
        +Nokia Corporation and is licensed pursuant to the OpenSSL open source
        +license.
        +
        +The Contribution, originally written by Mika Kousa and Pasi Eronen of
        +Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        +support (see RFC 4279) to OpenSSL.
        +
        +No patent licenses or other rights except those expressly stated in
        +the OpenSSL open source license shall be deemed granted or received
        +expressly, by implication, estoppel, or otherwise.
        +
        +No assurances are provided by Nokia that the Contribution does not
        +infringe the patent or other intellectual property rights of any third
        +party or that the license provides you with all the necessary rights
        +to make use of the Contribution.
        +
        +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        +ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        +SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        +OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        +OTHERWISE.
        +
        +=end comment
        +
        +=head1 NAME
        +
        +SSL_CTX_use_psk_identity_hint, SSL_use_psk_identity_hint,
        +SSL_CTX_set_psk_server_callback, SSL_set_psk_server_callback - set PSK
        +identity hint to use
        +
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint);
        + int SSL_use_psk_identity_hint(SSL *ssl, const char *hint);
        +
        + void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
        +	unsigned int (*callback)(SSL *ssl, const char *identity,
        +	unsigned char *psk, int max_psk_len));
        + void SSL_set_psk_server_callback(SSL *ssl,
        +	unsigned int (*callback)(SSL *ssl, const char *identity,
        +	unsigned char *psk, int max_psk_len));
        +
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_use_psk_identity_hint() sets the given B<NULL>-terminated PSK
        +identity hint B<hint> to SSL context object
        +B<ctx>. SSL_use_psk_identity_hint() sets the given B<NULL>-terminated
        +PSK identity hint B<hint> to SSL connection object B<ssl>. If B<hint>
        +is B<NULL> the current hint from B<ctx> or B<ssl> is deleted.
        +
        +In the case where PSK identity hint is B<NULL>, the server
        +does not send the ServerKeyExchange message to the client.
        +
        +A server application must provide a callback function which is called
        +when the server receives the ClientKeyExchange message from the
        +client. The purpose of the callback function is to validate the
        +received PSK identity and to fetch the pre-shared key used during the
        +connection setup phase. The callback is set using functions
        +SSL_CTX_set_psk_server_callback() or
        +SSL_set_psk_server_callback(). The callback function is given the
        +connection in parameter B<ssl>, B<NULL>-terminated PSK identity sent
        +by the client in parameter B<identity>, and a buffer B<psk> of length
        +B<max_psk_len> bytes where the pre-shared key is to be stored.
        +
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_use_psk_identity_hint() and SSL_use_psk_identity_hint() return
        +1 on success, 0 otherwise.
        +
        +Return values from the server callback are interpreted as follows:
        +
        +=item > 0
        +
        +PSK identity was found and the server callback has provided the PSK
        +successfully in parameter B<psk>. Return value is the length of
        +B<psk> in bytes. It is an error to return a value greater than
        +B<max_psk_len>.
        +
        +If the PSK identity was not found but the callback instructs the
        +protocol to continue anyway, the callback must provide some random
        +data to B<psk> and return the length of the random data, so the
        +connection will fail with decryption_error before it will be finished
        +completely.
        +
        +=item 0
        +
        +PSK identity was not found. An "unknown_psk_identity" alert message
        +will be sent and the connection setup fails.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_SESSION_free.pod b/vendor/openssl/openssl/doc/ssl/SSL_SESSION_free.pod
        new file mode 100644
        index 000000000..110ec73ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_SESSION_free.pod
        @@ -0,0 +1,55 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_SESSION_free - free an allocated SSL_SESSION structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_SESSION_free(SSL_SESSION *session);
        +
        +=head1 DESCRIPTION
        +
        +SSL_SESSION_free() decrements the reference count of B<session> and removes
        +the B<SSL_SESSION> structure pointed to by B<session> and frees up the allocated
        +memory, if the reference count has reached 0.
        +
        +=head1 NOTES
        +
        +SSL_SESSION objects are allocated, when a TLS/SSL handshake operation
        +is successfully completed. Depending on the settings, see
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +the SSL_SESSION objects are internally referenced by the SSL_CTX and
        +linked into its session cache. SSL objects may be using the SSL_SESSION object;
        +as a session may be reused, several SSL objects may be using one SSL_SESSION
        +object at the same time. It is therefore crucial to keep the reference
        +count (usage information) correct and not delete a SSL_SESSION object
        +that is still used, as this may lead to program failures due to
        +dangling pointers. These failures may also appear delayed, e.g.
        +when an SSL_SESSION object was completely freed as the reference count
        +incorrectly became 0, but it is still referenced in the internal
        +session cache and the cache list is processed during a
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)> operation.
        +
        +SSL_SESSION_free() must only be called for SSL_SESSION objects, for
        +which the reference count was explicitly incremented (e.g.
        +by calling SSL_get1_session(), see L<SSL_get_session(3)|SSL_get_session(3)>)
        +or when the SSL_SESSION object was generated outside a TLS handshake
        +operation, e.g. by using L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>.
        +It must not be called on other SSL_SESSION objects, as this would cause
        +incorrect reference counts and therefore program failures.
        +
        +=head1 RETURN VALUES
        +
        +SSL_SESSION_free() does not provide diagnostic information.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_get_session(3)|SSL_get_session(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
        + L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_SESSION_get_ex_new_index.pod b/vendor/openssl/openssl/doc/ssl/SSL_SESSION_get_ex_new_index.pod
        new file mode 100644
        index 000000000..657cda931
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_SESSION_get_ex_new_index.pod
        @@ -0,0 +1,61 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_SESSION_get_ex_new_index, SSL_SESSION_set_ex_data, SSL_SESSION_get_ex_data - internal application specific data functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_SESSION_get_ex_new_index(long argl, void *argp,
        +                CRYPTO_EX_new *new_func,
        +                CRYPTO_EX_dup *dup_func,
        +                CRYPTO_EX_free *free_func);
        +
        + int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg);
        +
        + void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx);
        +
        + typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                int idx, long argl, void *argp);
        + typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                int idx, long argl, void *argp);
        + typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
        +                int idx, long argl, void *argp);
        +
        +=head1 DESCRIPTION
        +
        +Several OpenSSL structures can have application specific data attached to them.
        +These functions are used internally by OpenSSL to manipulate application
        +specific data attached to a specific structure.
        +
        +SSL_SESSION_get_ex_new_index() is used to register a new index for application
        +specific data.
        +
        +SSL_SESSION_set_ex_data() is used to store application data at B<arg> for B<idx>
        +into the B<session> object.
        +
        +SSL_SESSION_get_ex_data() is used to retrieve the information for B<idx> from
        +B<session>.
        +
        +A detailed description for the B<*_get_ex_new_index()> functionality
        +can be found in L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>.
        +The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.
        +
        +=head1 WARNINGS
        +
        +The application data is only maintained for sessions held in memory. The
        +application data is not included when dumping the session with
        +i2d_SSL_SESSION() (and all functions indirectly calling the dump functions
        +like PEM_write_SSL_SESSION() and PEM_write_bio_SSL_SESSION()) and can
        +therefore not be restored.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_SESSION_get_time.pod b/vendor/openssl/openssl/doc/ssl/SSL_SESSION_get_time.pod
        new file mode 100644
        index 000000000..490337a32
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_SESSION_get_time.pod
        @@ -0,0 +1,64 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_SESSION_get_time, SSL_SESSION_set_time, SSL_SESSION_get_timeout, SSL_SESSION_set_timeout - retrieve and manipulate session time and timeout settings
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_SESSION_get_time(const SSL_SESSION *s);
        + long SSL_SESSION_set_time(SSL_SESSION *s, long tm);
        + long SSL_SESSION_get_timeout(const SSL_SESSION *s);
        + long SSL_SESSION_set_timeout(SSL_SESSION *s, long tm);
        +
        + long SSL_get_time(const SSL_SESSION *s);
        + long SSL_set_time(SSL_SESSION *s, long tm);
        + long SSL_get_timeout(const SSL_SESSION *s);
        + long SSL_set_timeout(SSL_SESSION *s, long tm);
        +
        +=head1 DESCRIPTION
        +
        +SSL_SESSION_get_time() returns the time at which the session B<s> was
        +established. The time is given in seconds since the Epoch and therefore
        +compatible to the time delivered by the time() call.
        +
        +SSL_SESSION_set_time() replaces the creation time of the session B<s> with
        +the chosen value B<tm>.
        +
        +SSL_SESSION_get_timeout() returns the timeout value set for session B<s>
        +in seconds.
        +
        +SSL_SESSION_set_timeout() sets the timeout value for session B<s> in seconds
        +to B<tm>.
        +
        +The SSL_get_time(), SSL_set_time(), SSL_get_timeout(), and SSL_set_timeout()
        +functions are synonyms for the SSL_SESSION_*() counterparts.
        +
        +=head1 NOTES
        +
        +Sessions are expired by examining the creation time and the timeout value.
        +Both are set at creation time of the session to the actual time and the
        +default timeout value at creation, respectively, as set by
        +L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>.
        +Using these functions it is possible to extend or shorten the lifetime
        +of the session.
        +
        +=head1 RETURN VALUES
        +
        +SSL_SESSION_get_time() and SSL_SESSION_get_timeout() return the currently
        +valid values.
        +
        +SSL_SESSION_set_time() and SSL_SESSION_set_timeout() return 1 on success.
        +
        +If any of the function is passed the NULL pointer for the session B<s>, 
        +0 is returned.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
        +L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_accept.pod b/vendor/openssl/openssl/doc/ssl/SSL_accept.pod
        new file mode 100644
        index 000000000..cc724c0d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_accept.pod
        @@ -0,0 +1,76 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_accept - wait for a TLS/SSL client to initiate a TLS/SSL handshake
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + 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<ssl> by setting an underlying B<BIO>.
        +
        +=head1 NOTES
        +
        +The behaviour of SSL_accept() depends on the underlying BIO. 
        +
        +If the underlying BIO is B<blocking>, 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<SSL_ERROR_WANT_READ/WRITE> and SSL_accept()
        +should be called again.
        +
        +If the underlying BIO is B<non-blocking>, SSL_accept() will also return
        +when the underlying BIO could not satisfy the needs of SSL_accept()
        +to continue the handshake, indicating the problem by the return value -1.
        +In this case a call to SSL_get_error() with the
        +return value of SSL_accept() will yield B<SSL_ERROR_WANT_READ> or
        +B<SSL_ERROR_WANT_WRITE>. 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<ret> to find out the reason.
        +
        +=item E<lt>0
        +
        +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<ret>
        +to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_connect(3)|SSL_connect(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
        +L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
        +L<SSL_CTX_new(3)|SSL_CTX_new(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_alert_type_string.pod b/vendor/openssl/openssl/doc/ssl/SSL_alert_type_string.pod
        new file mode 100644
        index 000000000..0329c3486
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_alert_type_string.pod
        @@ -0,0 +1,233 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_alert_type_string, SSL_alert_type_string_long, SSL_alert_desc_string, SSL_alert_desc_string_long - get textual description of alert information
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + const char *SSL_alert_type_string(int value);
        + const char *SSL_alert_type_string_long(int value);
        +
        + const char *SSL_alert_desc_string(int value);
        + const char *SSL_alert_desc_string_long(int value);
        +
        +=head1 DESCRIPTION
        +
        +SSL_alert_type_string() returns a one letter string indicating the
        +type of the alert specified by B<value>.
        +
        +SSL_alert_type_string_long() returns a string indicating the type of the alert
        +specified by B<value>.
        +
        +SSL_alert_desc_string() returns a two letter string as a short form
        +describing the reason of the alert specified by B<value>.
        +
        +SSL_alert_desc_string_long() returns a string describing the reason
        +of the alert specified by B<value>.
        +
        +=head1 NOTES
        +
        +When one side of an SSL/TLS communication wants to inform the peer about
        +a special situation, it sends an alert. The alert is sent as a special message
        +and does not influence the normal data stream (unless its contents results
        +in the communication being canceled).
        +
        +A warning alert is sent, when a non-fatal error condition occurs. The
        +"close notify" alert is sent as a warning alert. Other examples for
        +non-fatal errors are certificate errors ("certificate expired",
        +"unsupported certificate"), for which a warning alert may be sent.
        +(The sending party may however decide to send a fatal error.) The
        +receiving side may cancel the connection on reception of a warning
        +alert on it discretion.
        +
        +Several alert messages must be sent as fatal alert messages as specified
        +by the TLS RFC. A fatal alert always leads to a connection abort.
        +
        +=head1 RETURN VALUES
        +
        +The following strings can occur for SSL_alert_type_string() or
        +SSL_alert_type_string_long():
        +
        +=over 4
        +
        +=item "W"/"warning"
        +
        +=item "F"/"fatal"
        +
        +=item "U"/"unknown"
        +
        +This indicates that no support is available for this alert type.
        +Probably B<value> does not contain a correct alert message.
        +
        +=back
        +
        +The following strings can occur for SSL_alert_desc_string() or
        +SSL_alert_desc_string_long():
        +
        +=over 4
        +
        +=item "CN"/"close notify"
        +
        +The connection shall be closed. This is a warning alert.
        +
        +=item "UM"/"unexpected message"
        +
        +An inappropriate message was received. This alert is always fatal
        +and should never be observed in communication between proper
        +implementations.
        +
        +=item "BM"/"bad record mac"
        +
        +This alert is returned if a record is received with an incorrect
        +MAC. This message is always fatal.
        +
        +=item "DF"/"decompression failure"
        +
        +The decompression function received improper input (e.g. data
        +that would expand to excessive length). This message is always
        +fatal.
        +
        +=item "HF"/"handshake failure"
        +
        +Reception of a handshake_failure alert message indicates that the
        +sender was unable to negotiate an acceptable set of security
        +parameters given the options available. This is a fatal error.
        +
        +=item "NC"/"no certificate"
        +
        +A client, that was asked to send a certificate, does not send a certificate
        +(SSLv3 only).
        +
        +=item "BC"/"bad certificate"
        +
        +A certificate was corrupt, contained signatures that did not
        +verify correctly, etc
        +
        +=item "UC"/"unsupported certificate"
        +
        +A certificate was of an unsupported type.
        +
        +=item "CR"/"certificate revoked"
        +
        +A certificate was revoked by its signer.
        +
        +=item "CE"/"certificate expired"
        +
        +A certificate has expired or is not currently valid.
        +
        +=item "CU"/"certificate unknown"
        +
        +Some other (unspecified) issue arose in processing the
        +certificate, rendering it unacceptable.
        +
        +=item "IP"/"illegal parameter"
        +
        +A field in the handshake was out of range or inconsistent with
        +other fields. This is always fatal.
        +
        +=item "DC"/"decryption failed"
        +
        +A TLSCiphertext decrypted in an invalid way: either it wasn't an
        +even multiple of the block length or its padding values, when
        +checked, weren't correct. This message is always fatal.
        +
        +=item "RO"/"record overflow"
        +
        +A TLSCiphertext record was received which had a length more than
        +2^14+2048 bytes, or a record decrypted to a TLSCompressed record
        +with more than 2^14+1024 bytes. This message is always fatal.
        +
        +=item "CA"/"unknown CA"
        +
        +A valid certificate chain or partial chain was received, but the
        +certificate was not accepted because the CA certificate could not
        +be located or couldn't be matched with a known, trusted CA.  This
        +message is always fatal.
        +
        +=item "AD"/"access denied"
        +
        +A valid certificate was received, but when access control was
        +applied, the sender decided not to proceed with negotiation.
        +This message is always fatal.
        +
        +=item "DE"/"decode error"
        +
        +A message could not be decoded because some field was out of the
        +specified range or the length of the message was incorrect. This
        +message is always fatal.
        +
        +=item "CY"/"decrypt error"
        +
        +A handshake cryptographic operation failed, including being
        +unable to correctly verify a signature, decrypt a key exchange,
        +or validate a finished message.
        +
        +=item "ER"/"export restriction"
        +
        +A negotiation not in compliance with export restrictions was
        +detected; for example, attempting to transfer a 1024 bit
        +ephemeral RSA key for the RSA_EXPORT handshake method. This
        +message is always fatal.
        +
        +=item "PV"/"protocol version"
        +
        +The protocol version the client has attempted to negotiate is
        +recognized, but not supported. (For example, old protocol
        +versions might be avoided for security reasons). This message is
        +always fatal.
        +
        +=item "IS"/"insufficient security"
        +
        +Returned instead of handshake_failure when a negotiation has
        +failed specifically because the server requires ciphers more
        +secure than those supported by the client. This message is always
        +fatal.
        +
        +=item "IE"/"internal error"
        +
        +An internal error unrelated to the peer or the correctness of the
        +protocol makes it impossible to continue (such as a memory
        +allocation failure). This message is always fatal.
        +
        +=item "US"/"user canceled"
        +
        +This handshake is being canceled for some reason unrelated to a
        +protocol failure. If the user cancels an operation after the
        +handshake is complete, just closing the connection by sending a
        +close_notify is more appropriate. This alert should be followed
        +by a close_notify. This message is generally a warning.
        +
        +=item "NR"/"no renegotiation"
        +
        +Sent by the client in response to a hello request or by the
        +server in response to a client hello after initial handshaking.
        +Either of these would normally lead to renegotiation; when that
        +is not appropriate, the recipient should respond with this alert;
        +at that point, the original requester can decide whether to
        +proceed with the connection. One case where this would be
        +appropriate would be where a server has spawned a process to
        +satisfy a request; the process might receive security parameters
        +(key length, authentication, etc.) at startup and it might be
        +difficult to communicate changes to these parameters after that
        +point. This message is always a warning.
        +
        +=item "UP"/"unknown PSK identity"
        +
        +Sent by the server to indicate that it does not recognize a PSK
        +identity or an SRP identity. 
        +
        +=item "UK"/"unknown"
        +
        +This indicates that no description is available for this alert type.
        +Probably B<value> does not contain a correct alert message.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_clear.pod b/vendor/openssl/openssl/doc/ssl/SSL_clear.pod
        new file mode 100644
        index 000000000..d4df1bfac
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_clear.pod
        @@ -0,0 +1,75 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_clear - reset SSL object to allow another connection
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_clear(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +Reset B<ssl> to allow another connection. All settings (method, ciphers,
        +BIOs) are kept.
        +
        +=head1 NOTES
        +
        +SSL_clear is used to prepare an SSL object for a new connection. While all
        +settings are kept, a side effect is the handling of the current SSL session.
        +If a session is still B<open>, it is considered bad and will be removed
        +from the session cache, as required by RFC2246. A session is considered open,
        +if L<SSL_shutdown(3)|SSL_shutdown(3)> was not called for the connection
        +or at least L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> was used to
        +set the SSL_SENT_SHUTDOWN state.
        +
        +If a session was closed cleanly, the session object will be kept and all
        +settings corresponding. This explicitly means, that e.g. the special method
        +used during the session will be kept for the next handshake. So if the
        +session was a TLSv1 session, a SSL client object will use a TLSv1 client
        +method for the next handshake and a SSL server object will use a TLSv1
        +server method, even if SSLv23_*_methods were chosen on startup. This
        +will might lead to connection failures (see L<SSL_new(3)|SSL_new(3)>)
        +for a description of the method's properties.
        +
        +=head1 WARNINGS
        +
        +SSL_clear() resets the SSL object to allow for another connection. The
        +reset operation however keeps several settings of the last sessions
        +(some of these settings were made automatically during the last
        +handshake). It only makes sense for a new connection with the exact
        +same peer that shares these settings, and may fail if that peer
        +changes its settings between connections. Use the sequence
        +L<SSL_get_session(3)|SSL_get_session(3)>;
        +L<SSL_new(3)|SSL_new(3)>;
        +L<SSL_set_session(3)|SSL_set_session(3)>;
        +L<SSL_free(3)|SSL_free(3)>
        +instead to avoid such failures
        +(or simply L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>
        +if session reuse is not desired).
        +
        +=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<SSL_new(3)|SSL_new(3)>, L<SSL_free(3)|SSL_free(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_connect.pod b/vendor/openssl/openssl/doc/ssl/SSL_connect.pod
        new file mode 100644
        index 000000000..cc56ebb75
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_connect.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_connect - initiate the TLS/SSL handshake with an TLS/SSL server
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + 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<ssl> by setting an
        +underlying B<BIO>.
        +
        +=head1 NOTES
        +
        +The behaviour of SSL_connect() depends on the underlying BIO. 
        +
        +If the underlying BIO is B<blocking>, SSL_connect() will only return once the
        +handshake has been finished or an error occurred.
        +
        +If the underlying BIO is B<non-blocking>, SSL_connect() will also return
        +when the underlying BIO could not satisfy the needs of SSL_connect()
        +to continue the handshake, indicating the problem by the return value -1.
        +In this case a call to SSL_get_error() with the
        +return value of SSL_connect() will yield B<SSL_ERROR_WANT_READ> or
        +B<SSL_ERROR_WANT_WRITE>. 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<ret> to find out the reason.
        +
        +=item E<lt>0
        +
        +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<ret>
        +to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_accept(3)|SSL_accept(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
        +L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
        +L<SSL_CTX_new(3)|SSL_CTX_new(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_do_handshake.pod b/vendor/openssl/openssl/doc/ssl/SSL_do_handshake.pod
        new file mode 100644
        index 000000000..243576451
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_do_handshake.pod
        @@ -0,0 +1,75 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_do_handshake - perform a TLS/SSL handshake
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_do_handshake(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_do_handshake() will wait for a SSL/TLS handshake to take place. If the
        +connection is in client mode, the handshake will be started. The handshake
        +routines may have to be explicitly set in advance using either
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)> or
        +L<SSL_set_accept_state(3)|SSL_set_accept_state(3)>.
        +
        +=head1 NOTES
        +
        +The behaviour of SSL_do_handshake() depends on the underlying BIO.
        +
        +If the underlying BIO is B<blocking>, SSL_do_handshake() will only return
        +once the handshake has been finished or an error occurred, except for SGC
        +(Server Gated Cryptography). For SGC, SSL_do_handshake() may return with -1,
        +but SSL_get_error() will yield B<SSL_ERROR_WANT_READ/WRITE> and
        +SSL_do_handshake() should be called again.
        +
        +If the underlying BIO is B<non-blocking>, SSL_do_handshake() will also return
        +when the underlying BIO could not satisfy the needs of SSL_do_handshake()
        +to continue the handshake. In this case a call to SSL_get_error() with the
        +return value of SSL_do_handshake() will yield B<SSL_ERROR_WANT_READ> or
        +B<SSL_ERROR_WANT_WRITE>. The calling process then must repeat the call after
        +taking appropriate action to satisfy the needs of SSL_do_handshake().
        +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<ret> to find out the reason.
        +
        +=item E<lt>0
        +
        +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<ret>
        +to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_connect(3)|SSL_connect(3)>,
        +L<SSL_accept(3)|SSL_accept(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>,
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_free.pod b/vendor/openssl/openssl/doc/ssl/SSL_free.pod
        new file mode 100644
        index 000000000..13c1abd9e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_free.pod
        @@ -0,0 +1,44 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_free - free an allocated SSL structure
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_free(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_free() decrements the reference count of B<ssl>, and removes the SSL
        +structure pointed to by B<ssl> and frees up the allocated memory if the
        +reference count has reached 0.
        +
        +=head1 NOTES
        +
        +SSL_free() 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<ssl>, the B<SSL_SESSION>.
        +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.
        +
        +The ssl session has reference counts from two users: the SSL object, for
        +which the reference count is removed by SSL_free() and the internal
        +session cache. If the session is considered bad, because
        +L<SSL_shutdown(3)|SSL_shutdown(3)> was not called for the connection
        +and L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> was not used to set the
        +SSL_SENT_SHUTDOWN state, the session will also be removed
        +from the session cache as required by RFC2246.
        +
        +=head1 RETURN VALUES
        +
        +SSL_free() does not provide diagnostic information.
        +
        +L<SSL_new(3)|SSL_new(3)>, L<SSL_clear(3)|SSL_clear(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_SSL_CTX.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_SSL_CTX.pod
        new file mode 100644
        index 000000000..659c482c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_SSL_CTX.pod
        @@ -0,0 +1,26 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_SSL_CTX - get the SSL_CTX from which an SSL is created
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_SSL_CTX() returns a pointer to the SSL_CTX object, from which
        +B<ssl> was created with L<SSL_new(3)|SSL_new(3)>.
        +
        +=head1 RETURN VALUES
        +
        +The pointer to the SSL_CTX object is returned.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_ciphers.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_ciphers.pod
        new file mode 100644
        index 000000000..aecadd913
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl);
        + const char *SSL_get_cipher_list(const SSL *ssl, int priority);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_ciphers() returns the stack of available SSL_CIPHERs for B<ssl>,
        +sorted by preference. If B<ssl> 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<ssl> with B<priority>. If B<ssl> is NULL, no ciphers are
        +available, or there are less ciphers than B<priority> available, NULL
        +is returned.
        +
        +=head1 NOTES
        +
        +The details of the ciphers obtained by SSL_get_ciphers() can be obtained using
        +the L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)> family of functions.
        +
        +Call SSL_get_cipher_list() with B<priority> starting from 0 to obtain the
        +sorted list of available ciphers, until NULL is returned.
        +
        +=head1 RETURN VALUES
        +
        +See DESCRIPTION
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
        +L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_client_CA_list.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_client_CA_list.pod
        new file mode 100644
        index 000000000..68181b240
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_client_CA_list.pod
        @@ -0,0 +1,53 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_client_CA_list, SSL_CTX_get_client_CA_list - get list of client CAs
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
        + STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); 
        +
        +=head1 DESCRIPTION
        +
        +SSL_CTX_get_client_CA_list() returns the list of client CAs explicitly set for
        +B<ctx> using L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>.
        +
        +SSL_get_client_CA_list() returns the list of client CAs explicitly
        +set for B<ssl> using SSL_set_client_CA_list() or B<ssl>'s SSL_CTX object with
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>, when in
        +server mode. In client mode, SSL_get_client_CA_list returns the list of
        +client CAs sent from the server, if any.
        +
        +=head1 RETURN VALUES
        +
        +SSL_CTX_set_client_CA_list() and SSL_set_client_CA_list() do not return
        +diagnostic information.
        +
        +SSL_CTX_add_client_CA() and SSL_add_client_CA() have the following return
        +values:
        +
        +=over 4
        +
        +=item STACK_OF(X509_NAMES)
        +
        +List of CA names explicitly set (for B<ctx> or in server mode) or send
        +by the server (client mode).
        +
        +=item NULL
        +
        +No client CA list was explicitly set (for B<ctx> or in server mode) or
        +the server did not send a list of CAs (client mode).
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
        +L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_current_cipher.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_current_cipher.pod
        new file mode 100644
        index 000000000..e5ab12491
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + SSL_CIPHER *SSL_get_current_cipher(const 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<ssl> 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<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)> 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<ssl(3)|ssl(3)>, L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_default_timeout.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_default_timeout.pod
        new file mode 100644
        index 000000000..a648a9b82
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_default_timeout.pod
        @@ -0,0 +1,41 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_default_timeout - get default session timeout value
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + long SSL_get_default_timeout(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_default_timeout() returns the default timeout value assigned to
        +SSL_SESSION objects negotiated for the protocol valid for B<ssl>.
        +
        +=head1 NOTES
        +
        +Whenever a new session is negotiated, it is assigned a timeout value,
        +after which it will not be accepted for session reuse. If the timeout
        +value was not explicitly set using
        +L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>, the hardcoded default
        +timeout for the protocol will be used.
        +
        +SSL_get_default_timeout() return this hardcoded value, which is 300 seconds
        +for all currently supported protocols (SSLv2, SSLv3, and TLSv1).
        +
        +=head1 RETURN VALUES
        +
        +See description.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
        +L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_error.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_error.pod
        new file mode 100644
        index 000000000..48c6b15db
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_error.pod
        @@ -0,0 +1,114 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_error - obtain result code for TLS/SSL I/O operation
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_get_error(const SSL *ssl, int ret);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_error() returns a result code (suitable for the C "switch"
        +statement) for a preceding call to SSL_connect(), SSL_accept(), SSL_do_handshake(),
        +SSL_read(), SSL_peek(), or SSL_write() on B<ssl>.  The value returned by
        +that TLS/SSL I/O function must be passed to SSL_get_error() in parameter
        +B<ret>.
        +
        +In addition to B<ssl> and B<ret>, SSL_get_error() inspects the
        +current thread's OpenSSL error queue.  Thus, SSL_get_error() must be
        +used in the same thread that performed the TLS/SSL I/O operation, and no
        +other OpenSSL function calls should appear in between.  The current
        +thread's error queue must be empty before the TLS/SSL I/O operation is
        +attempted, or SSL_get_error() will not work reliably.
        +
        +=head1 RETURN VALUES
        +
        +The following return values can currently occur:
        +
        +=over 4
        +
        +=item SSL_ERROR_NONE
        +
        +The TLS/SSL I/O operation completed.  This result code is returned
        +if and only if B<ret E<gt> 0>.
        +
        +=item SSL_ERROR_ZERO_RETURN
        +
        +The TLS/SSL connection has been closed.  If the protocol version is SSL 3.0
        +or TLS 1.0, this result code is returned only if a closure
        +alert has occurred in the protocol, i.e. if the connection has been
        +closed cleanly. Note that in this case B<SSL_ERROR_ZERO_RETURN>
        +does not necessarily indicate that the underlying transport
        +has been closed.
        +
        +=item SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE
        +
        +The operation did not complete; the same TLS/SSL I/O function should be
        +called again later.  If, by then, the underlying B<BIO> has data
        +available for reading (if the result code is B<SSL_ERROR_WANT_READ>)
        +or allows writing data (B<SSL_ERROR_WANT_WRITE>), then some TLS/SSL
        +protocol progress will take place, i.e. at least part of an TLS/SSL
        +record will be read or written.  Note that the retry may again lead to
        +a B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE> condition.
        +There is no fixed upper limit for the number of iterations that
        +may be necessary until progress becomes visible at application
        +protocol level.
        +
        +For socket B<BIO>s (e.g. when SSL_set_fd() was used), select() or
        +poll() on the underlying socket can be used to find out when the
        +TLS/SSL I/O function should be retried.
        +
        +Caveat: Any TLS/SSL I/O function can lead to either of
        +B<SSL_ERROR_WANT_READ> and B<SSL_ERROR_WANT_WRITE>.  In particular,
        +SSL_read() or SSL_peek() may want to write data and SSL_write() may want
        +to read data.  This is mainly because TLS/SSL handshakes may occur at any
        +time during the protocol (initiated by either the client or the server);
        +SSL_read(), SSL_peek(), and SSL_write() will handle any pending handshakes.
        +
        +=item SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT
        +
        +The operation did not complete; the same TLS/SSL I/O function should be
        +called again later. The underlying BIO was not connected yet to the peer
        +and the call would block in connect()/accept(). The SSL function should be
        +called again when the connection is established. These messages can only
        +appear with a BIO_s_connect() or BIO_s_accept() BIO, respectively.
        +In order to find out, when the connection has been successfully established,
        +on many platforms select() or poll() for writing on the socket file descriptor
        +can be used.
        +
        +=item SSL_ERROR_WANT_X509_LOOKUP
        +
        +The operation did not complete because an application callback set by
        +SSL_CTX_set_client_cert_cb() has asked to be called again.
        +The TLS/SSL I/O function should be called again later.
        +Details depend on the application.
        +
        +=item SSL_ERROR_SYSCALL
        +
        +Some I/O error occurred.  The OpenSSL error queue may contain more
        +information on the error.  If the error queue is empty
        +(i.e. ERR_get_error() returns 0), B<ret> can be used to find out more
        +about the error: If B<ret == 0>, an EOF was observed that violates
        +the protocol.  If B<ret == -1>, the underlying B<BIO> reported an
        +I/O error (for socket I/O on Unix systems, consult B<errno> for details).
        +
        +=item SSL_ERROR_SSL
        +
        +A failure in the SSL library occurred, usually a protocol error.  The
        +OpenSSL error queue contains more information on the error.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<err(3)|err(3)>
        +
        +=head1 HISTORY
        +
        +SSL_get_error() was added in SSLeay 0.8.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_ex_data_X509_STORE_CTX_idx.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_ex_data_X509_STORE_CTX_idx.pod
        new file mode 100644
        index 000000000..165c6a5b2
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_ex_data_X509_STORE_CTX_idx.pod
        @@ -0,0 +1,61 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_ex_data_X509_STORE_CTX_idx - get ex_data index to access SSL structure
        +from X509_STORE_CTX
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_get_ex_data_X509_STORE_CTX_idx(void);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_ex_data_X509_STORE_CTX_idx() returns the index number under which
        +the pointer to the SSL object is stored into the X509_STORE_CTX object.
        +
        +=head1 NOTES
        +
        +Whenever a X509_STORE_CTX object is created for the verification of the
        +peers certificate during a handshake, a pointer to the SSL object is
        +stored into the X509_STORE_CTX object to identify the connection affected.
        +To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can
        +be used with the correct index. This index is globally the same for all
        +X509_STORE_CTX objects and can be retrieved using
        +SSL_get_ex_data_X509_STORE_CTX_idx(). The index value is set when
        +SSL_get_ex_data_X509_STORE_CTX_idx() is first called either by the application
        +program directly or indirectly during other SSL setup functions or during
        +the handshake.
        +
        +The value depends on other index values defined for X509_STORE_CTX objects
        +before the SSL index is created.
        +
        +=head1 RETURN VALUES
        +
        +=over 4
        +
        +=item E<gt>=0
        +
        +The index value to access the pointer.
        +
        +=item E<lt>0
        +
        +An error occurred, check the error stack for a detailed error message.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +The index returned from SSL_get_ex_data_X509_STORE_CTX_idx() allows to
        +access the SSL object for the connection to be accessed during the
        +verify_callback() when checking the peers certificate. Please check
        +the example in L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_ex_new_index.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_ex_new_index.pod
        new file mode 100644
        index 000000000..228d23d8c
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_ex_new_index.pod
        @@ -0,0 +1,59 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_ex_new_index, SSL_set_ex_data, SSL_get_ex_data - internal application specific data functions
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_get_ex_new_index(long argl, void *argp,
        +                CRYPTO_EX_new *new_func,
        +                CRYPTO_EX_dup *dup_func,
        +                CRYPTO_EX_free *free_func);
        +
        + int SSL_set_ex_data(SSL *ssl, int idx, void *arg);
        +
        + void *SSL_get_ex_data(const SSL *ssl, int idx);
        +
        + typedef int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                int idx, long argl, void *argp);
        + typedef void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
        +                int idx, long argl, void *argp);
        + typedef int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d,
        +                int idx, long argl, void *argp);
        +
        +=head1 DESCRIPTION
        +
        +Several OpenSSL structures can have application specific data attached to them.
        +These functions are used internally by OpenSSL to manipulate application
        +specific data attached to a specific structure.
        +
        +SSL_get_ex_new_index() is used to register a new index for application
        +specific data.
        +
        +SSL_set_ex_data() is used to store application data at B<arg> for B<idx> into
        +the B<ssl> object.
        +
        +SSL_get_ex_data() is used to retrieve the information for B<idx> from
        +B<ssl>.
        +
        +A detailed description for the B<*_get_ex_new_index()> functionality
        +can be found in L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>.
        +The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>.
        +
        +=head1 EXAMPLES
        +
        +An example on how to use the functionality is included in the example
        +verify_callback() in L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>,
        +L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)>,
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_fd.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_fd.pod
        new file mode 100644
        index 000000000..89260b522
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + int SSL_get_fd(const SSL *ssl);
        + int SSL_get_rfd(const SSL *ssl);
        + int SSL_get_wfd(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_fd() returns the file descriptor which is linked to B<ssl>.
        +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<gt>=0
        +
        +The file descriptor linked to B<ssl>.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_set_fd(3)|SSL_set_fd(3)>, L<ssl(3)|ssl(3)> , L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_peer_cert_chain.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_peer_cert_chain.pod
        new file mode 100644
        index 000000000..49fb88f86
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + STACKOF(X509) *SSL_get_peer_cert_chain(const 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 separately using
        +L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>.
        +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<ssl(3)|ssl(3)>, L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_peer_certificate.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_peer_certificate.pod
        new file mode 100644
        index 000000000..ef7c8be18
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_peer_certificate.pod
        @@ -0,0 +1,55 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_peer_certificate - get the X509 certificate of the peer
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + X509 *SSL_get_peer_certificate(const 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
        +
        +Due to the protocol definition, a TLS/SSL server will always send a
        +certificate, if present. A client will only send a certificate when
        +explicitly requested to do so by the server (see
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>). If an anonymous cipher
        +is used, no certificates are sent.
        +
        +That a certificate is returned does not indicate information about the
        +verification state, use L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>
        +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 explicitly 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<ssl(3)|ssl(3)>, L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_psk_identity.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_psk_identity.pod
        new file mode 100644
        index 000000000..fe6291649
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_psk_identity.pod
        @@ -0,0 +1,63 @@
        +=pod
        +
        +=begin comment
        +
        +Copyright 2005 Nokia. All rights reserved.
        +
        +The portions of the attached software ("Contribution") is developed by
        +Nokia Corporation and is licensed pursuant to the OpenSSL open source
        +license.
        +
        +The Contribution, originally written by Mika Kousa and Pasi Eronen of
        +Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        +support (see RFC 4279) to OpenSSL.
        +
        +No patent licenses or other rights except those expressly stated in
        +the OpenSSL open source license shall be deemed granted or received
        +expressly, by implication, estoppel, or otherwise.
        +
        +No assurances are provided by Nokia that the Contribution does not
        +infringe the patent or other intellectual property rights of any third
        +party or that the license provides you with all the necessary rights
        +to make use of the Contribution.
        +
        +THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        +ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        +SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        +OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        +OTHERWISE.
        +
        +=end comment
        +
        +=head1 NAME
        +
        +SSL_get_psk_identity, SSL_get_psk_identity_hint - get PSK client identity and hint
        +
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + const char *SSL_get_psk_identity_hint(const SSL *ssl);
        + const char *SSL_get_psk_identity(const SSL *ssl);
        +
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_psk_identity_hint() is used to retrieve the PSK identity hint
        +used during the connection setup related to SSL object
        +B<ssl>. Similarly, SSL_get_psk_identity() is used to retrieve the PSK
        +identity used during the connection setup.
        +
        +
        +=head1 RETURN VALUES
        +
        +If non-B<NULL>, SSL_get_psk_identity_hint() returns the PSK identity
        +hint and SSL_get_psk_identity() returns the PSK identity. Both are
        +B<NULL>-terminated. SSL_get_psk_identity_hint() may return B<NULL> if
        +no PSK identity hint was used during the connection setup.
        +
        +Note that the return value is valid only during the lifetime of the
        +SSL object B<ssl>.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_rbio.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_rbio.pod
        new file mode 100644
        index 000000000..3d98233ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + 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<ssl>.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_set_bio(3)|SSL_set_bio(3)>, L<ssl(3)|ssl(3)> , L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_session.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_session.pod
        new file mode 100644
        index 000000000..0c41caa92
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_session.pod
        @@ -0,0 +1,73 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_session - retrieve TLS/SSL session data
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + SSL_SESSION *SSL_get_session(const SSL *ssl);
        + SSL_SESSION *SSL_get0_session(const SSL *ssl);
        + SSL_SESSION *SSL_get1_session(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_session() returns a pointer to the B<SSL_SESSION> actually used in
        +B<ssl>. The reference count of the B<SSL_SESSION> is not incremented, so
        +that the pointer can become invalid by other operations.
        +
        +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<SSL_SESSION> is incremented by one.
        +
        +=head1 NOTES
        +
        +The ssl session contains all information required to re-establish the
        +connection without a new handshake.
        +
        +SSL_get0_session() returns a pointer to the actual session. As the
        +reference counter is not incremented, the pointer is only valid while
        +the connection is in use. If L<SSL_clear(3)|SSL_clear(3)> or
        +L<SSL_free(3)|SSL_free(3)> is called, the session may be removed completely
        +(if considered bad), and the pointer obtained will become invalid. Even
        +if the session is valid, it can be removed at any time due to timeout
        +during L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>.
        +
        +If the data is to be kept, SSL_get1_session() will increment the reference
        +count, so that the session will not be implicitly removed by other operations
        +but stays in memory. In order to remove the session
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)> must be explicitly called once
        +to decrement the reference count again.
        +
        +SSL_SESSION objects keep internal link information about the session cache
        +list, when being inserted into one SSL_CTX object's session cache.
        +One SSL_SESSION object, regardless of its reference count, must therefore
        +only be used with one SSL_CTX object (and the SSL objects created
        +from this SSL_CTX object).
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item NULL
        +
        +There is no session available in B<ssl>.
        +
        +=item Pointer to an SSL
        +
        +The return value points to the data of an SSL session.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_free(3)|SSL_free(3)>,
        +L<SSL_clear(3)|SSL_clear(3)>,
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_verify_result.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_verify_result.pod
        new file mode 100644
        index 000000000..55b56a53f
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + long SSL_get_verify_result(const 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 occurred 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 occurred, it does however
        +not indicate success. SSL_get_verify_result() is only useful in connection
        +with L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>.
        +
        +=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<verify(1)|verify(1)>.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_set_verify_result(3)|SSL_set_verify_result(3)>,
        +L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
        +L<verify(1)|verify(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_get_version.pod b/vendor/openssl/openssl/doc/ssl/SSL_get_version.pod
        new file mode 100644
        index 000000000..cc271db2c
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_get_version.pod
        @@ -0,0 +1,46 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_get_version - get the protocol version of a connection.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + const char *SSL_get_version(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_get_cipher_version() returns the name of the protocol used for the
        +connection B<ssl>.
        +
        +=head1 RETURN VALUES
        +
        +The following strings can occur:
        +
        +=over 4
        +
        +=item SSLv2
        +
        +The connection uses the SSLv2 protocol.
        +
        +=item SSLv3
        +
        +The connection uses the SSLv3 protocol.
        +
        +=item TLSv1
        +
        +The connection uses the TLSv1 protocol.
        +
        +=item unknown
        +
        +This indicates that no version has been set (no connection established).
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_library_init.pod b/vendor/openssl/openssl/doc/ssl/SSL_library_init.pod
        new file mode 100644
        index 000000000..8766776fe
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_library_init.pod
        @@ -0,0 +1,57 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_library_init, OpenSSL_add_ssl_algorithms, SSLeay_add_ssl_algorithms
        +- initialize SSL library by registering algorithms
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + 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 SSL/TLS 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.
        +SSL_library_init() is not reentrant. 
        +
        +=head1 WARNING
        +
        +SSL_library_init() adds ciphers and digests used directly and indirectly by
        +SSL/TLS.
        +
        +=head1 EXAMPLES
        +
        +A typical TLS/SSL application will start with the library initialization,
        +and provide readable error messages.
        +
        + SSL_load_error_strings();                /* readable error messages */
        + SSL_library_init();                      /* initialize library */
        +
        +=head1 RETURN VALUES
        +
        +SSL_library_init() always returns "1", so it is safe to discard the return
        +value.
        +
        +=head1 NOTES
        +
        +OpenSSL 0.9.8o and 1.0.0a and later added SHA2 algorithms to SSL_library_init().
        +Applications which need to use SHA2 in earlier versions of OpenSSL should call
        +OpenSSL_add_all_algorithms() as well.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_load_error_strings(3)|SSL_load_error_strings(3)>,
        +L<RAND_add(3)|RAND_add(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_load_client_CA_file.pod b/vendor/openssl/openssl/doc/ssl/SSL_load_client_CA_file.pod
        new file mode 100644
        index 000000000..02527dc2e
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_load_client_CA_file.pod
        @@ -0,0 +1,62 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_load_client_CA_file - load certificate names from file
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
        +
        +=head1 DESCRIPTION
        +
        +SSL_load_client_CA_file() reads certificates from B<file> and returns
        +a STACK_OF(X509_NAME) with the subject names found.
        +
        +=head1 NOTES
        +
        +SSL_load_client_CA_file() reads a file of PEM formatted certificates and
        +extracts the X509_NAMES of the certificates found. While the name suggests
        +the specific usage as support function for
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
        +it is not limited to CA certificates.
        +
        +=head1 EXAMPLES
        +
        +Load names of CAs from file and use it as a client CA list:
        +
        + SSL_CTX *ctx;
        + STACK_OF(X509_NAME) *cert_names;
        +
        + ... 
        + cert_names = SSL_load_client_CA_file("/path/to/CAfile.pem");
        + if (cert_names != NULL)
        +   SSL_CTX_set_client_CA_list(ctx, cert_names);
        + else
        +   error_handling();
        + ...
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item NULL
        +
        +The operation failed, check out the error stack for the reason.
        +
        +=item Pointer to STACK_OF(X509_NAME)
        +
        +Pointer to the subject names of the successfully read certificates.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>,
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_new.pod b/vendor/openssl/openssl/doc/ssl/SSL_new.pod
        new file mode 100644
        index 000000000..25300e978
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_new.pod
        @@ -0,0 +1,44 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_new - create a new SSL structure for a connection
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + SSL *SSL_new(SSL_CTX *ctx);
        +
        +=head1 DESCRIPTION
        +
        +SSL_new() creates a new B<SSL> structure which is needed to hold the
        +data for a TLS/SSL connection. The new structure inherits the settings
        +of the underlying context B<ctx>: 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<SSL_free(3)|SSL_free(3)>, L<SSL_clear(3)|SSL_clear(3)>,
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
        +L<SSL_get_SSL_CTX(3)|SSL_get_SSL_CTX(3)>,
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_pending.pod b/vendor/openssl/openssl/doc/ssl/SSL_pending.pod
        new file mode 100644
        index 000000000..43f2874e8
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_pending.pod
        @@ -0,0 +1,43 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_pending - obtain number of readable bytes buffered in an SSL object
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_pending(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_pending() returns the number of bytes which are available inside
        +B<ssl> for immediate read.
        +
        +=head1 NOTES
        +
        +Data are received in blocks from the peer. Therefore data can be buffered
        +inside B<ssl> and are ready for immediate retrieval with
        +L<SSL_read(3)|SSL_read(3)>.
        +
        +=head1 RETURN VALUES
        +
        +The number of bytes pending is returned.
        +
        +=head1 BUGS
        +
        +SSL_pending() takes into account only bytes from the TLS/SSL record
        +that is currently being processed (if any).  If the B<SSL> object's
        +I<read_ahead> flag is set, additional protocol bytes may have been
        +read containing more TLS/SSL records; these are ignored by
        +SSL_pending().
        +
        +Up to OpenSSL 0.9.6, SSL_pending() does not check if the record type
        +of pending data is application data.
        +
        +=head1 SEE ALSO
        +
        +L<SSL_read(3)|SSL_read(3)>, L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_read.pod b/vendor/openssl/openssl/doc/ssl/SSL_read.pod
        new file mode 100644
        index 000000000..7038cd2d7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_read.pod
        @@ -0,0 +1,124 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_read - read bytes from a TLS/SSL connection.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_read(SSL *ssl, void *buf, int num);
        +
        +=head1 DESCRIPTION
        +
        +SSL_read() tries to read B<num> bytes from the specified B<ssl> into the
        +buffer B<buf>.
        +
        +=head1 NOTES
        +
        +If necessary, SSL_read() will negotiate a TLS/SSL session, if
        +not already explicitly performed by L<SSL_connect(3)|SSL_connect(3)> or
        +L<SSL_accept(3)|SSL_accept(3)>. 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. 
        +
        +For the transparent negotiation to succeed, the B<ssl> must have been
        +initialized to client or server mode. This is being done by calling
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)> or SSL_set_accept_state()
        +before the first call to an SSL_read() or L<SSL_write(3)|SSL_write(3)>
        +function.
        +
        +SSL_read() works based on the SSL/TLS records. The data are received in
        +records (with a maximum record size of 16kB for SSLv3/TLSv1). Only when a
        +record has been completely received, it can be processed (decryption and
        +check of integrity). Therefore data that was not retrieved at the last
        +call of SSL_read() can still be buffered inside the SSL layer and will be
        +retrieved on the next call to SSL_read(). If B<num> is higher than the
        +number of bytes buffered, SSL_read() will return with the bytes buffered.
        +If no more bytes are in the buffer, SSL_read() will trigger the processing
        +of the next record. Only when the record has been received and processed
        +completely, SSL_read() will return reporting success. At most the contents
        +of the record will be returned. As the size of an SSL/TLS record may exceed
        +the maximum packet size of the underlying transport (e.g. TCP), it may
        +be necessary to read several packets from the transport layer before the
        +record is complete and SSL_read() can succeed.
        +
        +If the underlying BIO is B<blocking>, SSL_read() will only return, once the
        +read operation has been finished or an error occurred, except when a
        +renegotiation take place, in which case a SSL_ERROR_WANT_READ may occur. 
        +This behaviour can be controlled with the SSL_MODE_AUTO_RETRY flag of the
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)> call.
        +
        +If the underlying BIO is B<non-blocking>, 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
        +L<SSL_get_error(3)|SSL_get_error(3)> with the
        +return value of SSL_read() will yield B<SSL_ERROR_WANT_READ> or
        +B<SSL_ERROR_WANT_WRITE>. 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.
        +
        +L<SSL_pending(3)|SSL_pending(3)> can be used to find out whether there
        +are buffered bytes available for immediate retrieval. In this case
        +SSL_read() can be called without blocking or actually receiving new
        +data from the underlying socket.
        +
        +=head1 WARNING
        +
        +When an SSL_read() operation has to be repeated because of
        +B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
        +with the same arguments.
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item E<gt>0
        +
        +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. The reason may either be a clean
        +shutdown due to a "close notify" alert sent by the peer (in which case
        +the SSL_RECEIVED_SHUTDOWN flag in the ssl shutdown state is set
        +(see L<SSL_shutdown(3)|SSL_shutdown(3)>,
        +L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>). It is also possible, that
        +the peer simply shut down the underlying transport and the shutdown is
        +incomplete. Call SSL_get_error() with the return value B<ret> to find out,
        +whether an error occurred or the connection was shut down cleanly
        +(SSL_ERROR_ZERO_RETURN).
        +
        +SSLv2 (deprecated) does not support a shutdown alert protocol, so it can
        +only be detected, whether the underlying connection was closed. It cannot
        +be checked, whether the closure was initiated by the peer or by something
        +else.
        +
        +=item E<lt>0
        +
        +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<ret> to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_write(3)|SSL_write(3)>,
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>, L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
        +L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
        +L<SSL_pending(3)|SSL_pending(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
        +L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_rstate_string.pod b/vendor/openssl/openssl/doc/ssl/SSL_rstate_string.pod
        new file mode 100644
        index 000000000..bdb8a1fcd
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_rstate_string.pod
        @@ -0,0 +1,59 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_rstate_string, SSL_rstate_string_long - get textual description of state of an SSL object during read operation
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + const char *SSL_rstate_string(SSL *ssl);
        + const char *SSL_rstate_string_long(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_rstate_string() returns a 2 letter string indicating the current read state
        +of the SSL object B<ssl>.
        +
        +SSL_rstate_string_long() returns a string indicating the current read state of
        +the SSL object B<ssl>.
        +
        +=head1 NOTES
        +
        +When performing a read operation, the SSL/TLS engine must parse the record,
        +consisting of header and body. When working in a blocking environment,
        +SSL_rstate_string[_long]() should always return "RD"/"read done".
        +
        +This function should only seldom be needed in applications.
        +
        +=head1 RETURN VALUES
        +
        +SSL_rstate_string() and SSL_rstate_string_long() can return the following
        +values:
        +
        +=over 4
        +
        +=item "RH"/"read header"
        +
        +The header of the record is being evaluated.
        +
        +=item "RB"/"read body"
        +
        +The body of the record is being evaluated.
        +
        +=item "RD"/"read done"
        +
        +The record has been completely processed.
        +
        +=item "unknown"/"unknown"
        +
        +The read state is unknown. This should never happen.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_session_reused.pod b/vendor/openssl/openssl/doc/ssl/SSL_session_reused.pod
        new file mode 100644
        index 000000000..da7d06264
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_session_reused.pod
        @@ -0,0 +1,45 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_session_reused - query whether a reused session was negotiated during handshake
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_session_reused(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +Query, whether a reused session was negotiated during the handshake.
        +
        +=head1 NOTES
        +
        +During the negotiation, a client can propose to reuse a session. The server
        +then looks up the session in its cache. If both client and server agree
        +on the session, it will be reused and a flag is being set that can be
        +queried by the application.
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item 0
        +
        +A new session was negotiated.
        +
        +=item 1
        +
        +A session was reused.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_set_bio.pod b/vendor/openssl/openssl/doc/ssl/SSL_set_bio.pod
        new file mode 100644
        index 000000000..67c9756d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
        +
        +=head1 DESCRIPTION
        +
        +SSL_set_bio() connects the BIOs B<rbio> and B<wbio> for the read and write
        +operations of the TLS/SSL (encrypted) side of B<ssl>.
        +
        +The SSL engine inherits the behaviour of B<rbio> and B<wbio>, respectively.
        +If a BIO is non-blocking, the B<ssl> will also have non-blocking behaviour.
        +
        +If there was already a BIO connected to B<ssl>, 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<SSL_get_rbio(3)|SSL_get_rbio(3)>,
        +L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_set_connect_state.pod b/vendor/openssl/openssl/doc/ssl/SSL_set_connect_state.pod
        new file mode 100644
        index 000000000..d88a057de
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_set_connect_state.pod
        @@ -0,0 +1,55 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_set_connect_state, SSL_get_accept_state - prepare SSL object to work in client or server mode
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_set_connect_state(SSL *ssl);
        +
        + void SSL_set_accept_state(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_set_connect_state() sets B<ssl> to work in client mode.
        +
        +SSL_set_accept_state() sets B<ssl> to work in server mode.
        +
        +=head1 NOTES
        +
        +When the SSL_CTX object was created with L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
        +it was either assigned a dedicated client method, a dedicated server
        +method, or a generic method, that can be used for both client and
        +server connections. (The method might have been changed with
        +L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)> or
        +SSL_set_ssl_method().)
        +
        +When beginning a new handshake, the SSL engine must know whether it must
        +call the connect (client) or accept (server) routines. Even though it may
        +be clear from the method chosen, whether client or server mode was
        +requested, the handshake routines must be explicitly set.
        +
        +When using the L<SSL_connect(3)|SSL_connect(3)> or
        +L<SSL_accept(3)|SSL_accept(3)> routines, the correct handshake
        +routines are automatically set. When performing a transparent negotiation
        +using L<SSL_write(3)|SSL_write(3)> or L<SSL_read(3)|SSL_read(3)>, the
        +handshake routines must be explicitly set in advance using either
        +SSL_set_connect_state() or SSL_set_accept_state().
        +
        +=head1 RETURN VALUES
        +
        +SSL_set_connect_state() and SSL_set_accept_state() do not return diagnostic
        +information.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>, L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
        +L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>,
        +L<SSL_write(3)|SSL_write(3)>, L<SSL_read(3)|SSL_read(3)>,
        +L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
        +L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_set_fd.pod b/vendor/openssl/openssl/doc/ssl/SSL_set_fd.pod
        new file mode 100644
        index 000000000..70291128f
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + 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<fd> as the input/output facility
        +for the TLS/SSL (encrypted) side of B<ssl>. B<fd> will typically be the
        +socket file descriptor of a network connection.
        +
        +When performing the operation, a B<socket BIO> is automatically created to
        +interface between the B<ssl> and B<fd>. The BIO and hence the SSL engine
        +inherit the behaviour of B<fd>. If B<fd> is non-blocking, the B<ssl> will
        +also have non-blocking behaviour.
        +
        +If there was already a BIO connected to B<ssl>, 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<SSL_get_fd(3)|SSL_get_fd(3)>, L<SSL_set_bio(3)|SSL_set_bio(3)>,
        +L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>, L<ssl(3)|ssl(3)> , L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_set_session.pod b/vendor/openssl/openssl/doc/ssl/SSL_set_session.pod
        new file mode 100644
        index 000000000..5f54714ad
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_set_session.pod
        @@ -0,0 +1,57 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_set_session - set a TLS/SSL session to be used during TLS/SSL connect
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_set_session(SSL *ssl, SSL_SESSION *session);
        +
        +=head1 DESCRIPTION
        +
        +SSL_set_session() sets B<session> 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<session> is incremented
        +by 1. If the session is not reused, the reference count is decremented
        +again during SSL_connect(). Whether the session was reused can be queried
        +with the L<SSL_session_reused(3)|SSL_session_reused(3)> call.
        +
        +If there is already a session set inside B<ssl> (because it was set with
        +SSL_set_session() before or because the same B<ssl> was already used for
        +a connection), SSL_SESSION_free() will be called for that session.
        +
        +=head1 NOTES
        +
        +SSL_SESSION objects keep internal link information about the session cache
        +list, when being inserted into one SSL_CTX object's session cache.
        +One SSL_SESSION object, regardless of its reference count, must therefore
        +only be used with one SSL_CTX object (and the SSL objects created
        +from this SSL_CTX object).
        +
        +=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<ssl(3)|ssl(3)>, L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
        +L<SSL_get_session(3)|SSL_get_session(3)>,
        +L<SSL_session_reused(3)|SSL_session_reused(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_set_shutdown.pod b/vendor/openssl/openssl/doc/ssl/SSL_set_shutdown.pod
        new file mode 100644
        index 000000000..011a022a1
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_set_shutdown.pod
        @@ -0,0 +1,72 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_set_shutdown, SSL_get_shutdown - manipulate shutdown state of an SSL connection
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + void SSL_set_shutdown(SSL *ssl, int mode);
        +
        + int SSL_get_shutdown(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_set_shutdown() sets the shutdown state of B<ssl> to B<mode>.
        +
        +SSL_get_shutdown() returns the shutdown mode of B<ssl>.
        +
        +=head1 NOTES
        +
        +The shutdown state of an ssl connection is a bitmask of:
        +
        +=over 4
        +
        +=item 0
        +
        +No shutdown setting, yet.
        +
        +=item SSL_SENT_SHUTDOWN
        +
        +A "close notify" shutdown alert was sent to the peer, the connection is being
        +considered closed and the session is closed and correct.
        +
        +=item SSL_RECEIVED_SHUTDOWN
        +
        +A shutdown alert was received form the peer, either a normal "close notify"
        +or a fatal error.
        +
        +=back
        +
        +SSL_SENT_SHUTDOWN and SSL_RECEIVED_SHUTDOWN can be set at the same time.
        +
        +The shutdown state of the connection is used to determine the state of
        +the ssl session. If the session is still open, when
        +L<SSL_clear(3)|SSL_clear(3)> or L<SSL_free(3)|SSL_free(3)> is called,
        +it is considered bad and removed according to RFC2246.
        +The actual condition for a correctly closed session is SSL_SENT_SHUTDOWN
        +(according to the TLS RFC, it is acceptable to only send the "close notify"
        +alert but to not wait for the peer's answer, when the underlying connection
        +is closed).
        +SSL_set_shutdown() can be used to set this state without sending a
        +close alert to the peer (see L<SSL_shutdown(3)|SSL_shutdown(3)>).
        +
        +If a "close notify" was received, SSL_RECEIVED_SHUTDOWN will be set,
        +for setting SSL_SENT_SHUTDOWN the application must however still call
        +L<SSL_shutdown(3)|SSL_shutdown(3)> or SSL_set_shutdown() itself.
        +
        +=head1 RETURN VALUES
        +
        +SSL_set_shutdown() does not return diagnostic information.
        +
        +SSL_get_shutdown() returns the current setting.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_shutdown(3)|SSL_shutdown(3)>,
        +L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
        +L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_set_verify_result.pod b/vendor/openssl/openssl/doc/ssl/SSL_set_verify_result.pod
        new file mode 100644
        index 000000000..04ab101aa
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <openssl/ssl.h>
        +
        + void SSL_set_verify_result(SSL *ssl, long verify_result);
        +
        +=head1 DESCRIPTION
        +
        +SSL_set_verify_result() sets B<verify_result> of the object B<ssl> 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<ssl> 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<verify_result> are documented in L<verify(1)|verify(1)>.
        +
        +=head1 RETURN VALUES
        +
        +SSL_set_verify_result() does not provide a return value.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
        +L<SSL_get_peer_certificate(3)|SSL_get_peer_certificate(3)>,
        +L<verify(1)|verify(1)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_shutdown.pod b/vendor/openssl/openssl/doc/ssl/SSL_shutdown.pod
        new file mode 100644
        index 000000000..89911acbc
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_shutdown.pod
        @@ -0,0 +1,125 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_shutdown - shut down a TLS/SSL connection
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_shutdown(SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_shutdown() shuts down an active TLS/SSL connection. It sends the 
        +"close notify" shutdown alert to the peer.
        +
        +=head1 NOTES
        +
        +SSL_shutdown() tries to send the "close notify" shutdown alert to the peer.
        +Whether the operation succeeds or not, the SSL_SENT_SHUTDOWN flag is set and
        +a currently open session is considered closed and good and will be kept in the
        +session cache for further reuse.
        +
        +The shutdown procedure consists of 2 steps: the sending of the "close notify"
        +shutdown alert and the reception of the peer's "close notify" shutdown
        +alert. According to the TLS standard, it is acceptable for an application
        +to only send its shutdown alert and then close the underlying connection
        +without waiting for the peer's response (this way resources can be saved,
        +as the process can already terminate or serve another connection).
        +When the underlying connection shall be used for more communications, the
        +complete shutdown procedure (bidirectional "close notify" alerts) must be
        +performed, so that the peers stay synchronized.
        +
        +SSL_shutdown() supports both uni- and bidirectional shutdown by its 2 step
        +behaviour.
        +
        +=over 4
        +
        +=item When the application is the first party to send the "close notify"
        +alert, SSL_shutdown() will only send the alert and then set the
        +SSL_SENT_SHUTDOWN flag (so that the session is considered good and will
        +be kept in cache). SSL_shutdown() will then return with 0. If a unidirectional
        +shutdown is enough (the underlying connection shall be closed anyway), this
        +first call to SSL_shutdown() is sufficient. In order to complete the
        +bidirectional shutdown handshake, SSL_shutdown() must be called again.
        +The second call will make SSL_shutdown() wait for the peer's "close notify"
        +shutdown alert. On success, the second call to SSL_shutdown() will return
        +with 1.
        +
        +=item If the peer already sent the "close notify" alert B<and> it was
        +already processed implicitly inside another function
        +(L<SSL_read(3)|SSL_read(3)>), the SSL_RECEIVED_SHUTDOWN flag is set.
        +SSL_shutdown() will send the "close notify" alert, set the SSL_SENT_SHUTDOWN
        +flag and will immediately return with 1.
        +Whether SSL_RECEIVED_SHUTDOWN is already set can be checked using the
        +SSL_get_shutdown() (see also L<SSL_set_shutdown(3)|SSL_set_shutdown(3)> call.
        +
        +=back
        +
        +It is therefore recommended, to check the return value of SSL_shutdown()
        +and call SSL_shutdown() again, if the bidirectional shutdown is not yet
        +complete (return value of the first call is 0). As the shutdown is not
        +specially handled in the SSLv2 protocol, SSL_shutdown() will succeed on
        +the first call.
        +
        +The behaviour of SSL_shutdown() additionally depends on the underlying BIO. 
        +
        +If the underlying BIO is B<blocking>, SSL_shutdown() will only return once the
        +handshake step has been finished or an error occurred.
        +
        +If the underlying BIO is B<non-blocking>, 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<SSL_ERROR_WANT_READ> or
        +B<SSL_ERROR_WANT_WRITE>. 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.
        +
        +SSL_shutdown() can be modified to only set the connection to "shutdown"
        +state but not actually send the "close notify" alert messages,
        +see L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>.
        +When "quiet shutdown" is enabled, SSL_shutdown() will always succeed
        +and return 1.
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item 1
        +
        +The shutdown was successfully completed. The "close notify" alert was sent
        +and the peer's "close notify" alert was received.
        +
        +=item 0
        +
        +The shutdown is not yet finished. Call SSL_shutdown() for a second time,
        +if a bidirectional shutdown shall be performed.
        +The output of L<SSL_get_error(3)|SSL_get_error(3)> may be misleading, as an
        +erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred.
        +
        +=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 if
        +action is need to continue the operation for non-blocking BIOs.
        +Call L<SSL_get_error(3)|SSL_get_error(3)> with the return value B<ret>
        +to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_connect(3)|SSL_connect(3)>,
        +L<SSL_accept(3)|SSL_accept(3)>, L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
        +L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
        +L<SSL_clear(3)|SSL_clear(3)>, L<SSL_free(3)|SSL_free(3)>,
        +L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_state_string.pod b/vendor/openssl/openssl/doc/ssl/SSL_state_string.pod
        new file mode 100644
        index 000000000..fe25d47c7
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_state_string.pod
        @@ -0,0 +1,45 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_state_string, SSL_state_string_long - get textual description of state of an SSL object
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + const char *SSL_state_string(const SSL *ssl);
        + const char *SSL_state_string_long(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_state_string() returns a 6 letter string indicating the current state
        +of the SSL object B<ssl>.
        +
        +SSL_state_string_long() returns a string indicating the current state of
        +the SSL object B<ssl>.
        +
        +=head1 NOTES
        +
        +During its use, an SSL objects passes several states. The state is internally
        +maintained. Querying the state information is not very informative before
        +or when a connection has been established. It however can be of significant
        +interest during the handshake.
        +
        +When using non-blocking sockets, the function call performing the handshake
        +may return with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE condition,
        +so that SSL_state_string[_long]() may be called.
        +
        +For both blocking or non-blocking sockets, the details state information
        +can be used within the info_callback function set with the
        +SSL_set_info_callback() call.
        +
        +=head1 RETURN VALUES
        +
        +Detailed description of possible states to be included later.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_want.pod b/vendor/openssl/openssl/doc/ssl/SSL_want.pod
        new file mode 100644
        index 000000000..c0059c0d4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_want.pod
        @@ -0,0 +1,77 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_want, SSL_want_nothing, SSL_want_read, SSL_want_write, SSL_want_x509_lookup - obtain state information TLS/SSL I/O operation
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_want(const SSL *ssl);
        + int SSL_want_nothing(const SSL *ssl);
        + int SSL_want_read(const SSL *ssl);
        + int SSL_want_write(const SSL *ssl);
        + int SSL_want_x509_lookup(const SSL *ssl);
        +
        +=head1 DESCRIPTION
        +
        +SSL_want() returns state information for the SSL object B<ssl>.
        +
        +The other SSL_want_*() calls are shortcuts for the possible states returned
        +by SSL_want().
        +
        +=head1 NOTES
        +
        +SSL_want() examines the internal state information of the SSL object. Its
        +return values are similar to that of L<SSL_get_error(3)|SSL_get_error(3)>.
        +Unlike L<SSL_get_error(3)|SSL_get_error(3)>, which also evaluates the
        +error queue, the results are obtained by examining an internal state flag
        +only. The information must therefore only be used for normal operation under
        +non-blocking I/O. Error conditions are not handled and must be treated
        +using L<SSL_get_error(3)|SSL_get_error(3)>.
        +
        +The result returned by SSL_want() should always be consistent with
        +the result of L<SSL_get_error(3)|SSL_get_error(3)>.
        +
        +=head1 RETURN VALUES
        +
        +The following return values can currently occur for SSL_want():
        +
        +=over 4
        +
        +=item SSL_NOTHING
        +
        +There is no data to be written or to be read.
        +
        +=item SSL_WRITING
        +
        +There are data in the SSL buffer that must be written to the underlying
        +B<BIO> layer in order to complete the actual SSL_*() operation.
        +A call to L<SSL_get_error(3)|SSL_get_error(3)> should return
        +SSL_ERROR_WANT_WRITE.
        +
        +=item SSL_READING
        +
        +More data must be read from the underlying B<BIO> layer in order to
        +complete the actual SSL_*() operation.
        +A call to L<SSL_get_error(3)|SSL_get_error(3)> should return
        +SSL_ERROR_WANT_READ.
        +
        +=item SSL_X509_LOOKUP
        +
        +The operation did not complete because an application callback set by
        +SSL_CTX_set_client_cert_cb() has asked to be called again.
        +A call to L<SSL_get_error(3)|SSL_get_error(3)> should return
        +SSL_ERROR_WANT_X509_LOOKUP.
        +
        +=back
        +
        +SSL_want_nothing(), SSL_want_read(), SSL_want_write(), SSL_want_x509_lookup()
        +return 1, when the corresponding condition is true or 0 otherwise.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<err(3)|err(3)>, L<SSL_get_error(3)|SSL_get_error(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/SSL_write.pod b/vendor/openssl/openssl/doc/ssl/SSL_write.pod
        new file mode 100644
        index 000000000..e013c12d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/SSL_write.pod
        @@ -0,0 +1,109 @@
        +=pod
        +
        +=head1 NAME
        +
        +SSL_write - write bytes to a TLS/SSL connection.
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + int SSL_write(SSL *ssl, const void *buf, int num);
        +
        +=head1 DESCRIPTION
        +
        +SSL_write() writes B<num> bytes from the buffer B<buf> into the specified
        +B<ssl> connection.
        +
        +=head1 NOTES
        +
        +If necessary, SSL_write() will negotiate a TLS/SSL session, if
        +not already explicitly performed by L<SSL_connect(3)|SSL_connect(3)> or
        +L<SSL_accept(3)|SSL_accept(3)>. 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. 
        +
        +For the transparent negotiation to succeed, the B<ssl> must have been
        +initialized to client or server mode. This is being done by calling
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)> or SSL_set_accept_state()
        +before the first call to an L<SSL_read(3)|SSL_read(3)> or SSL_write() function.
        +
        +If the underlying BIO is B<blocking>, SSL_write() will only return, once the
        +write operation has been finished or an error occurred, except when a
        +renegotiation take place, in which case a SSL_ERROR_WANT_READ may occur. 
        +This behaviour can be controlled with the SSL_MODE_AUTO_RETRY flag of the
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)> call.
        +
        +If the underlying BIO is B<non-blocking>, 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
        +L<SSL_get_error(3)|SSL_get_error(3)> with the
        +return value of SSL_write() will yield B<SSL_ERROR_WANT_READ> or
        +B<SSL_ERROR_WANT_WRITE>. As at any time a re-negotiation is possible, a
        +call to SSL_write() can also cause read 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.
        +
        +SSL_write() will only return with success, when the complete contents
        +of B<buf> of length B<num> has been written. This default behaviour
        +can be changed with the SSL_MODE_ENABLE_PARTIAL_WRITE option of
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>. When this flag is set,
        +SSL_write() will also return with success, when a partial write has been
        +successfully completed. In this case the SSL_write() operation is considered
        +completed. The bytes are sent and a new SSL_write() operation with a new
        +buffer (with the already sent bytes removed) must be started.
        +A partial write is performed with the size of a message block, which is
        +16kB for SSLv3/TLSv1.
        +
        +=head1 WARNING
        +
        +When an SSL_write() operation has to be repeated because of
        +B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
        +with the same arguments.
        +
        +When calling SSL_write() with num=0 bytes to be sent the behaviour is
        +undefined.
        +
        +=head1 RETURN VALUES
        +
        +The following return values can occur:
        +
        +=over 4
        +
        +=item E<gt>0
        +
        +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. Probably the underlying connection
        +was closed. Call SSL_get_error() with the return value B<ret> to find out,
        +whether an error occurred or the connection was shut down cleanly
        +(SSL_ERROR_ZERO_RETURN).
        +
        +SSLv2 (deprecated) does not support a shutdown alert protocol, so it can
        +only be detected, whether the underlying connection was closed. It cannot
        +be checked, why the closure happened.
        +
        +=item E<lt>0
        +
        +The write 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<ret> to find out the reason.
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<SSL_get_error(3)|SSL_get_error(3)>, L<SSL_read(3)|SSL_read(3)>,
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>, L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
        +L<SSL_connect(3)|SSL_connect(3)>, L<SSL_accept(3)|SSL_accept(3)>
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
        +L<ssl(3)|ssl(3)>, L<bio(3)|bio(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/d2i_SSL_SESSION.pod b/vendor/openssl/openssl/doc/ssl/d2i_SSL_SESSION.pod
        new file mode 100644
        index 000000000..81d276477
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/d2i_SSL_SESSION.pod
        @@ -0,0 +1,66 @@
        +=pod
        +
        +=head1 NAME
        +
        +d2i_SSL_SESSION, i2d_SSL_SESSION - convert SSL_SESSION object from/to ASN1 representation
        +
        +=head1 SYNOPSIS
        +
        + #include <openssl/ssl.h>
        +
        + SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
        + int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
        +
        +=head1 DESCRIPTION
        +
        +d2i_SSL_SESSION() transforms the external ASN1 representation of an SSL/TLS
        +session, stored as binary data at location B<pp> with length B<length>, into
        +an SSL_SESSION object.
        +
        +i2d_SSL_SESSION() transforms the SSL_SESSION object B<in> into the ASN1
        +representation and stores it into the memory location pointed to by B<pp>.
        +The length of the resulting ASN1 representation is returned. If B<pp> is
        +the NULL pointer, only the length is calculated and returned.
        +
        +=head1 NOTES
        +
        +The SSL_SESSION object is built from several malloc()ed parts, it can
        +therefore not be moved, copied or stored directly. In order to store
        +session data on disk or into a database, it must be transformed into
        +a binary ASN1 representation.
        +
        +When using d2i_SSL_SESSION(), the SSL_SESSION object is automatically
        +allocated. The reference count is 1, so that the session must be
        +explicitly removed using L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
        +unless the SSL_SESSION object is completely taken over, when being called
        +inside the get_session_cb() (see
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>).
        +
        +SSL_SESSION objects keep internal link information about the session cache
        +list, when being inserted into one SSL_CTX object's session cache.
        +One SSL_SESSION object, regardless of its reference count, must therefore
        +only be used with one SSL_CTX object (and the SSL objects created
        +from this SSL_CTX object).
        +
        +When using i2d_SSL_SESSION(), the memory location pointed to by B<pp> must be
        +large enough to hold the binary representation of the session. There is no
        +known limit on the size of the created ASN1 representation, so the necessary
        +amount of space should be obtained by first calling i2d_SSL_SESSION() with
        +B<pp=NULL>, and obtain the size needed, then allocate the memory and
        +call i2d_SSL_SESSION() again.
        +
        +=head1 RETURN VALUES
        +
        +d2i_SSL_SESSION() returns a pointer to the newly allocated SSL_SESSION
        +object. In case of failure the NULL-pointer is returned and the error message
        +can be retrieved from the error stack.
        +
        +i2d_SSL_SESSION() returns the size of the ASN1 representation in bytes.
        +When the session is not valid, B<0> is returned and no operation is performed.
        +
        +=head1 SEE ALSO
        +
        +L<ssl(3)|ssl(3)>, L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>
        +
        +=cut
        diff --git a/vendor/openssl/openssl/doc/ssl/ssl.pod b/vendor/openssl/openssl/doc/ssl/ssl.pod
        new file mode 100644
        index 000000000..6d3ee24e4
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssl/ssl.pod
        @@ -0,0 +1,758 @@
        +
        +=pod
        +
        +=head1 NAME
        +
        +SSL - OpenSSL SSL/TLS library
        +
        +=head1 SYNOPSIS
        +
        +=head1 DESCRIPTION
        +
        +The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v2/v3) and
        +Transport Layer Security (TLS v1) protocols. It provides a rich API which is
        +documented here.
        +
        +At first the library must be initialized; see
        +L<SSL_library_init(3)|SSL_library_init(3)>.
        +
        +Then an B<SSL_CTX> object is created as a framework to establish
        +TLS/SSL enabled connections (see L<SSL_CTX_new(3)|SSL_CTX_new(3)>).
        +Various options regarding certificates, algorithms etc. can be set
        +in this object.
        +
        +When a network connection has been created, it can be assigned to an
        +B<SSL> object. After the B<SSL> object has been created using
        +L<SSL_new(3)|SSL_new(3)>, L<SSL_set_fd(3)|SSL_set_fd(3)> or
        +L<SSL_set_bio(3)|SSL_set_bio(3)> can be used to associate the network
        +connection with the object.
        +
        +Then the TLS/SSL handshake is performed using
        +L<SSL_accept(3)|SSL_accept(3)> or L<SSL_connect(3)|SSL_connect(3)>
        +respectively.
        +L<SSL_read(3)|SSL_read(3)> and L<SSL_write(3)|SSL_write(3)> are used
        +to read and write data on the TLS/SSL connection.
        +L<SSL_shutdown(3)|SSL_shutdown(3)> can be used to shut down the
        +TLS/SSL connection.
        +
        +=head1 DATA STRUCTURES
        +
        +Currently the OpenSSL B<ssl> library functions deals with the following data
        +structures:
        +
        +=over 4
        +
        +=item B<SSL_METHOD> (SSL Method)
        +
        +That's a dispatch structure describing the internal B<ssl> library
        +methods/functions which implement the various protocol versions (SSLv1, SSLv2
        +and TLSv1). It's needed to create an B<SSL_CTX>.
        +
        +=item B<SSL_CIPHER> (SSL Cipher)
        +
        +This structure holds the algorithm information for a particular cipher which
        +are a core part of the SSL/TLS protocol. The available ciphers are configured
        +on a B<SSL_CTX> basis and the actually used ones are then part of the
        +B<SSL_SESSION>.
        +
        +=item B<SSL_CTX> (SSL Context)
        +
        +That's the global context structure which is created by a server or client
        +once per program life-time and which holds mainly default values for the
        +B<SSL> structures which are later created for the connections.
        +
        +=item B<SSL_SESSION> (SSL Session)
        +
        +This is a structure containing the current TLS/SSL session details for a
        +connection: B<SSL_CIPHER>s, client and server certificates, keys, etc.
        +
        +=item B<SSL> (SSL Connection)
        +
        +That's the main SSL/TLS structure which is created by a server or client per
        +established connection. This actually is the core structure in the SSL API.
        +Under run-time the application usually deals with this structure which has
        +links to mostly all other structures.
        +
        +=back
        +
        +
        +=head1 HEADER FILES
        +
        +Currently the OpenSSL B<ssl> library provides the following C header files
        +containing the prototypes for the data structures and and functions:
        +
        +=over 4
        +
        +=item B<ssl.h>
        +
        +That's the common header file for the SSL/TLS API.  Include it into your
        +program to make the API of the B<ssl> library available. It internally
        +includes both more private SSL headers and headers from the B<crypto> library.
        +Whenever you need hard-core details on the internals of the SSL API, look
        +inside this header file.
        +
        +=item B<ssl2.h>
        +
        +That's the sub header file dealing with the SSLv2 protocol only.
        +I<Usually you don't have to include it explicitly because
        +it's already included by ssl.h>.
        +
        +=item B<ssl3.h>
        +
        +That's the sub header file dealing with the SSLv3 protocol only.
        +I<Usually you don't have to include it explicitly because
        +it's already included by ssl.h>.
        +
        +=item B<ssl23.h>
        +
        +That's the sub header file dealing with the combined use of the SSLv2 and
        +SSLv3 protocols.
        +I<Usually you don't have to include it explicitly because
        +it's already included by ssl.h>.
        +
        +=item B<tls1.h>
        +
        +That's the sub header file dealing with the TLSv1 protocol only.
        +I<Usually you don't have to include it explicitly because
        +it's already included by ssl.h>.
        +
        +=back
        +
        +=head1 API FUNCTIONS
        +
        +Currently the OpenSSL B<ssl> library exports 214 API functions.
        +They are documented in the following:
        +
        +=head2 DEALING WITH PROTOCOL METHODS
        +
        +Here we document the various API functions which deal with the SSL/TLS
        +protocol methods defined in B<SSL_METHOD> structures.
        +
        +=over 4
        +
        +=item const SSL_METHOD *B<SSLv2_client_method>(void);
        +
        +Constructor for the SSLv2 SSL_METHOD structure for a dedicated client.
        +
        +=item const SSL_METHOD *B<SSLv2_server_method>(void);
        +
        +Constructor for the SSLv2 SSL_METHOD structure for a dedicated server.
        +
        +=item const SSL_METHOD *B<SSLv2_method>(void);
        +
        +Constructor for the SSLv2 SSL_METHOD structure for combined client and server.
        +
        +=item const SSL_METHOD *B<SSLv3_client_method>(void);
        +
        +Constructor for the SSLv3 SSL_METHOD structure for a dedicated client.
        +
        +=item const SSL_METHOD *B<SSLv3_server_method>(void);
        +
        +Constructor for the SSLv3 SSL_METHOD structure for a dedicated server.
        +
        +=item const SSL_METHOD *B<SSLv3_method>(void);
        +
        +Constructor for the SSLv3 SSL_METHOD structure for combined client and server.
        +
        +=item const SSL_METHOD *B<TLSv1_client_method>(void);
        +
        +Constructor for the TLSv1 SSL_METHOD structure for a dedicated client.
        +
        +=item const SSL_METHOD *B<TLSv1_server_method>(void);
        +
        +Constructor for the TLSv1 SSL_METHOD structure for a dedicated server.
        +
        +=item const SSL_METHOD *B<TLSv1_method>(void);
        +
        +Constructor for the TLSv1 SSL_METHOD structure for combined client and server.
        +
        +=back
        +
        +=head2 DEALING WITH CIPHERS
        +
        +Here we document the various API functions which deal with the SSL/TLS
        +ciphers defined in B<SSL_CIPHER> structures.
        +
        +=over 4
        +
        +=item char *B<SSL_CIPHER_description>(SSL_CIPHER *cipher, char *buf, int len);
        +
        +Write a string to I<buf> (with a maximum size of I<len>) containing a human
        +readable description of I<cipher>. Returns I<buf>.
        +
        +=item int B<SSL_CIPHER_get_bits>(SSL_CIPHER *cipher, int *alg_bits);
        +
        +Determine the number of bits in I<cipher>. Because of export crippled ciphers
        +there are two bits: The bits the algorithm supports in general (stored to
        +I<alg_bits>) and the bits which are actually used (the return value).
        +
        +=item const char *B<SSL_CIPHER_get_name>(SSL_CIPHER *cipher);
        +
        +Return the internal name of I<cipher> as a string. These are the various
        +strings defined by the I<SSL2_TXT_xxx>, I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
        +definitions in the header files.
        +
        +=item char *B<SSL_CIPHER_get_version>(SSL_CIPHER *cipher);
        +
        +Returns a string like "C<TLSv1/SSLv3>" or "C<SSLv2>" which indicates the
        +SSL/TLS protocol version to which I<cipher> belongs (i.e. where it was defined
        +in the specification the first time).
        +
        +=back
        +
        +=head2 DEALING WITH PROTOCOL CONTEXTS
        +
        +Here we document the various API functions which deal with the SSL/TLS
        +protocol context defined in the B<SSL_CTX> structure.
        +
        +=over 4
        +
        +=item int B<SSL_CTX_add_client_CA>(SSL_CTX *ctx, X509 *x);
        +
        +=item long B<SSL_CTX_add_extra_chain_cert>(SSL_CTX *ctx, X509 *x509);
        +
        +=item int B<SSL_CTX_add_session>(SSL_CTX *ctx, SSL_SESSION *c);
        +
        +=item int B<SSL_CTX_check_private_key>(const SSL_CTX *ctx);
        +
        +=item long B<SSL_CTX_ctrl>(SSL_CTX *ctx, int cmd, long larg, char *parg);
        +
        +=item void B<SSL_CTX_flush_sessions>(SSL_CTX *s, long t);
        +
        +=item void B<SSL_CTX_free>(SSL_CTX *a);
        +
        +=item char *B<SSL_CTX_get_app_data>(SSL_CTX *ctx);
        +
        +=item X509_STORE *B<SSL_CTX_get_cert_store>(SSL_CTX *ctx);
        +
        +=item STACK *B<SSL_CTX_get_client_CA_list>(const SSL_CTX *ctx);
        +
        +=item int (*B<SSL_CTX_get_client_cert_cb>(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
        +
        +=item char *B<SSL_CTX_get_ex_data>(const SSL_CTX *s, int idx);
        +
        +=item int B<SSL_CTX_get_ex_new_index>(long argl, char *argp, int (*new_func);(void), int (*dup_func)(void), void (*free_func)(void))
        +
        +=item void (*B<SSL_CTX_get_info_callback>(SSL_CTX *ctx))(SSL *ssl, int cb, int ret);
        +
        +=item int B<SSL_CTX_get_quiet_shutdown>(const SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_get_session_cache_mode>(SSL_CTX *ctx);
        +
        +=item long B<SSL_CTX_get_timeout>(const SSL_CTX *ctx);
        +
        +=item int (*B<SSL_CTX_get_verify_callback>(const SSL_CTX *ctx))(int ok, X509_STORE_CTX *ctx);
        +
        +=item int B<SSL_CTX_get_verify_mode>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_load_verify_locations>(SSL_CTX *ctx, char *CAfile, char *CApath);
        +
        +=item long B<SSL_CTX_need_tmp_RSA>(SSL_CTX *ctx);
        +
        +=item SSL_CTX *B<SSL_CTX_new>(const SSL_METHOD *meth);
        +
        +=item int B<SSL_CTX_remove_session>(SSL_CTX *ctx, SSL_SESSION *c);
        +
        +=item int B<SSL_CTX_sess_accept>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_accept_good>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_accept_renegotiate>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_cache_full>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_cb_hits>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_connect>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_connect_good>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_connect_renegotiate>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_get_cache_size>(SSL_CTX *ctx);
        +
        +=item SSL_SESSION *(*B<SSL_CTX_sess_get_get_cb>(SSL_CTX *ctx))(SSL *ssl, unsigned char *data, int len, int *copy);
        +
        +=item int (*B<SSL_CTX_sess_get_new_cb>(SSL_CTX *ctx)(SSL *ssl, SSL_SESSION *sess);
        +
        +=item void (*B<SSL_CTX_sess_get_remove_cb>(SSL_CTX *ctx)(SSL_CTX *ctx, SSL_SESSION *sess);
        +
        +=item int B<SSL_CTX_sess_hits>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_misses>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_sess_number>(SSL_CTX *ctx);
        +
        +=item void B<SSL_CTX_sess_set_cache_size>(SSL_CTX *ctx,t);
        +
        +=item void B<SSL_CTX_sess_set_get_cb>(SSL_CTX *ctx, SSL_SESSION *(*cb)(SSL *ssl, unsigned char *data, int len, int *copy));
        +
        +=item void B<SSL_CTX_sess_set_new_cb>(SSL_CTX *ctx, int (*cb)(SSL *ssl, SSL_SESSION *sess));
        +
        +=item void B<SSL_CTX_sess_set_remove_cb>(SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess));
        +
        +=item int B<SSL_CTX_sess_timeouts>(SSL_CTX *ctx);
        +
        +=item LHASH *B<SSL_CTX_sessions>(SSL_CTX *ctx);
        +
        +=item void B<SSL_CTX_set_app_data>(SSL_CTX *ctx, void *arg);
        +
        +=item void B<SSL_CTX_set_cert_store>(SSL_CTX *ctx, X509_STORE *cs);
        +
        +=item void B<SSL_CTX_set_cert_verify_cb>(SSL_CTX *ctx, int (*cb)(), char *arg)
        +
        +=item int B<SSL_CTX_set_cipher_list>(SSL_CTX *ctx, char *str);
        +
        +=item void B<SSL_CTX_set_client_CA_list>(SSL_CTX *ctx, STACK *list);
        +
        +=item void B<SSL_CTX_set_client_cert_cb>(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
        +
        +=item void B<SSL_CTX_set_default_passwd_cb>(SSL_CTX *ctx, int (*cb);(void))
        +
        +=item void B<SSL_CTX_set_default_read_ahead>(SSL_CTX *ctx, int m);
        +
        +=item int B<SSL_CTX_set_default_verify_paths>(SSL_CTX *ctx);
        +
        +=item int B<SSL_CTX_set_ex_data>(SSL_CTX *s, int idx, char *arg);
        +
        +=item void B<SSL_CTX_set_info_callback>(SSL_CTX *ctx, void (*cb)(SSL *ssl, int cb, int ret));
        +
        +=item void B<SSL_CTX_set_msg_callback>(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
        +
        +=item void B<SSL_CTX_set_msg_callback_arg>(SSL_CTX *ctx, void *arg);
        +
        +=item void B<SSL_CTX_set_options>(SSL_CTX *ctx, unsigned long op);
        +
        +=item void B<SSL_CTX_set_quiet_shutdown>(SSL_CTX *ctx, int mode);
        +
        +=item void B<SSL_CTX_set_session_cache_mode>(SSL_CTX *ctx, int mode);
        +
        +=item int B<SSL_CTX_set_ssl_version>(SSL_CTX *ctx, const SSL_METHOD *meth);
        +
        +=item void B<SSL_CTX_set_timeout>(SSL_CTX *ctx, long t);
        +
        +=item long B<SSL_CTX_set_tmp_dh>(SSL_CTX* ctx, DH *dh);
        +
        +=item long B<SSL_CTX_set_tmp_dh_callback>(SSL_CTX *ctx, DH *(*cb)(void));
        +
        +=item long B<SSL_CTX_set_tmp_rsa>(SSL_CTX *ctx, RSA *rsa);
        +
        +=item SSL_CTX_set_tmp_rsa_callback
        +
        +C<long B<SSL_CTX_set_tmp_rsa_callback>(SSL_CTX *B<ctx>, RSA *(*B<cb>)(SSL *B<ssl>, int B<export>, int B<keylength>));>
        +
        +Sets the callback which will be called when a temporary private key is
        +required. The B<C<export>> flag will be set if the reason for needing
        +a temp key is that an export ciphersuite is in use, in which case,
        +B<C<keylength>> will contain the required keylength in bits. Generate a key of
        +appropriate size (using ???) and return it.
        +
        +=item SSL_set_tmp_rsa_callback
        +
        +long B<SSL_set_tmp_rsa_callback>(SSL *ssl, RSA *(*cb)(SSL *ssl, int export, int keylength));
        +
        +The same as B<SSL_CTX_set_tmp_rsa_callback>, except it operates on an SSL
        +session instead of a context.
        +
        +=item void B<SSL_CTX_set_verify>(SSL_CTX *ctx, int mode, int (*cb);(void))
        +
        +=item int B<SSL_CTX_use_PrivateKey>(SSL_CTX *ctx, EVP_PKEY *pkey);
        +
        +=item int B<SSL_CTX_use_PrivateKey_ASN1>(int type, SSL_CTX *ctx, unsigned char *d, long len);
        +
        +=item int B<SSL_CTX_use_PrivateKey_file>(SSL_CTX *ctx, char *file, int type);
        +
        +=item int B<SSL_CTX_use_RSAPrivateKey>(SSL_CTX *ctx, RSA *rsa);
        +
        +=item int B<SSL_CTX_use_RSAPrivateKey_ASN1>(SSL_CTX *ctx, unsigned char *d, long len);
        +
        +=item int B<SSL_CTX_use_RSAPrivateKey_file>(SSL_CTX *ctx, char *file, int type);
        +
        +=item int B<SSL_CTX_use_certificate>(SSL_CTX *ctx, X509 *x);
        +
        +=item int B<SSL_CTX_use_certificate_ASN1>(SSL_CTX *ctx, int len, unsigned char *d);
        +
        +=item int B<SSL_CTX_use_certificate_file>(SSL_CTX *ctx, char *file, int type);
        +
        +=item void B<SSL_CTX_set_psk_client_callback>(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len));
        +
        +=item int B<SSL_CTX_use_psk_identity_hint>(SSL_CTX *ctx, const char *hint);
        +
        +=item void B<SSL_CTX_set_psk_server_callback>(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len));
        +
        +
        +
        +
        +=back
        +
        +=head2 DEALING WITH SESSIONS
        +
        +Here we document the various API functions which deal with the SSL/TLS
        +sessions defined in the B<SSL_SESSION> structures.
        +
        +=over 4
        +
        +=item int B<SSL_SESSION_cmp>(const SSL_SESSION *a, const SSL_SESSION *b);
        +
        +=item void B<SSL_SESSION_free>(SSL_SESSION *ss);
        +
        +=item char *B<SSL_SESSION_get_app_data>(SSL_SESSION *s);
        +
        +=item char *B<SSL_SESSION_get_ex_data>(const SSL_SESSION *s, int idx);
        +
        +=item int B<SSL_SESSION_get_ex_new_index>(long argl, char *argp, int (*new_func);(void), int (*dup_func)(void), void (*free_func)(void))
        +
        +=item long B<SSL_SESSION_get_time>(const SSL_SESSION *s);
        +
        +=item long B<SSL_SESSION_get_timeout>(const SSL_SESSION *s);
        +
        +=item unsigned long B<SSL_SESSION_hash>(const SSL_SESSION *a);
        +
        +=item SSL_SESSION *B<SSL_SESSION_new>(void);
        +
        +=item int B<SSL_SESSION_print>(BIO *bp, const SSL_SESSION *x);
        +
        +=item int B<SSL_SESSION_print_fp>(FILE *fp, const SSL_SESSION *x);
        +
        +=item void B<SSL_SESSION_set_app_data>(SSL_SESSION *s, char *a);
        +
        +=item int B<SSL_SESSION_set_ex_data>(SSL_SESSION *s, int idx, char *arg);
        +
        +=item long B<SSL_SESSION_set_time>(SSL_SESSION *s, long t);
        +
        +=item long B<SSL_SESSION_set_timeout>(SSL_SESSION *s, long t);
        +
        +=back
        +
        +=head2 DEALING WITH CONNECTIONS
        +
        +Here we document the various API functions which deal with the SSL/TLS
        +connection defined in the B<SSL> structure.
        +
        +=over 4
        +
        +=item int B<SSL_accept>(SSL *ssl);
        +
        +=item int B<SSL_add_dir_cert_subjects_to_stack>(STACK *stack, const char *dir);
        +
        +=item int B<SSL_add_file_cert_subjects_to_stack>(STACK *stack, const char *file);
        +
        +=item int B<SSL_add_client_CA>(SSL *ssl, X509 *x);
        +
        +=item char *B<SSL_alert_desc_string>(int value);
        +
        +=item char *B<SSL_alert_desc_string_long>(int value);
        +
        +=item char *B<SSL_alert_type_string>(int value);
        +
        +=item char *B<SSL_alert_type_string_long>(int value);
        +
        +=item int B<SSL_check_private_key>(const SSL *ssl);
        +
        +=item void B<SSL_clear>(SSL *ssl);
        +
        +=item long B<SSL_clear_num_renegotiations>(SSL *ssl);
        +
        +=item int B<SSL_connect>(SSL *ssl);
        +
        +=item void B<SSL_copy_session_id>(SSL *t, const SSL *f);
        +
        +=item long B<SSL_ctrl>(SSL *ssl, int cmd, long larg, char *parg);
        +
        +=item int B<SSL_do_handshake>(SSL *ssl);
        +
        +=item SSL *B<SSL_dup>(SSL *ssl);
        +
        +=item STACK *B<SSL_dup_CA_list>(STACK *sk);
        +
        +=item void B<SSL_free>(SSL *ssl);
        +
        +=item SSL_CTX *B<SSL_get_SSL_CTX>(const SSL *ssl);
        +
        +=item char *B<SSL_get_app_data>(SSL *ssl);
        +
        +=item X509 *B<SSL_get_certificate>(const SSL *ssl);
        +
        +=item const char *B<SSL_get_cipher>(const SSL *ssl);
        +
        +=item int B<SSL_get_cipher_bits>(const SSL *ssl, int *alg_bits);
        +
        +=item char *B<SSL_get_cipher_list>(const SSL *ssl, int n);
        +
        +=item char *B<SSL_get_cipher_name>(const SSL *ssl);
        +
        +=item char *B<SSL_get_cipher_version>(const SSL *ssl);
        +
        +=item STACK *B<SSL_get_ciphers>(const SSL *ssl);
        +
        +=item STACK *B<SSL_get_client_CA_list>(const SSL *ssl);
        +
        +=item SSL_CIPHER *B<SSL_get_current_cipher>(SSL *ssl);
        +
        +=item long B<SSL_get_default_timeout>(const SSL *ssl);
        +
        +=item int B<SSL_get_error>(const SSL *ssl, int i);
        +
        +=item char *B<SSL_get_ex_data>(const SSL *ssl, int idx);
        +
        +=item int B<SSL_get_ex_data_X509_STORE_CTX_idx>(void);
        +
        +=item int B<SSL_get_ex_new_index>(long argl, char *argp, int (*new_func);(void), int (*dup_func)(void), void (*free_func)(void))
        +
        +=item int B<SSL_get_fd>(const SSL *ssl);
        +
        +=item void (*B<SSL_get_info_callback>(const SSL *ssl);)()
        +
        +=item STACK *B<SSL_get_peer_cert_chain>(const SSL *ssl);
        +
        +=item X509 *B<SSL_get_peer_certificate>(const SSL *ssl);
        +
        +=item EVP_PKEY *B<SSL_get_privatekey>(SSL *ssl);
        +
        +=item int B<SSL_get_quiet_shutdown>(const SSL *ssl);
        +
        +=item BIO *B<SSL_get_rbio>(const SSL *ssl);
        +
        +=item int B<SSL_get_read_ahead>(const SSL *ssl);
        +
        +=item SSL_SESSION *B<SSL_get_session>(const SSL *ssl);
        +
        +=item char *B<SSL_get_shared_ciphers>(const SSL *ssl, char *buf, int len);
        +
        +=item int B<SSL_get_shutdown>(const SSL *ssl);
        +
        +=item const SSL_METHOD *B<SSL_get_ssl_method>(SSL *ssl);
        +
        +=item int B<SSL_get_state>(const SSL *ssl);
        +
        +=item long B<SSL_get_time>(const SSL *ssl);
        +
        +=item long B<SSL_get_timeout>(const SSL *ssl);
        +
        +=item int (*B<SSL_get_verify_callback>(const SSL *ssl))(int,X509_STORE_CTX *)
        +
        +=item int B<SSL_get_verify_mode>(const SSL *ssl);
        +
        +=item long B<SSL_get_verify_result>(const SSL *ssl);
        +
        +=item char *B<SSL_get_version>(const SSL *ssl);
        +
        +=item BIO *B<SSL_get_wbio>(const SSL *ssl);
        +
        +=item int B<SSL_in_accept_init>(SSL *ssl);
        +
        +=item int B<SSL_in_before>(SSL *ssl);
        +
        +=item int B<SSL_in_connect_init>(SSL *ssl);
        +
        +=item int B<SSL_in_init>(SSL *ssl);
        +
        +=item int B<SSL_is_init_finished>(SSL *ssl);
        +
        +=item STACK *B<SSL_load_client_CA_file>(char *file);
        +
        +=item void B<SSL_load_error_strings>(void);
        +
        +=item SSL *B<SSL_new>(SSL_CTX *ctx);
        +
        +=item long B<SSL_num_renegotiations>(SSL *ssl);
        +
        +=item int B<SSL_peek>(SSL *ssl, void *buf, int num);
        +
        +=item int B<SSL_pending>(const SSL *ssl);
        +
        +=item int B<SSL_read>(SSL *ssl, void *buf, int num);
        +
        +=item int B<SSL_renegotiate>(SSL *ssl);
        +
        +=item char *B<SSL_rstate_string>(SSL *ssl);
        +
        +=item char *B<SSL_rstate_string_long>(SSL *ssl);
        +
        +=item long B<SSL_session_reused>(SSL *ssl);
        +
        +=item void B<SSL_set_accept_state>(SSL *ssl);
        +
        +=item void B<SSL_set_app_data>(SSL *ssl, char *arg);
        +
        +=item void B<SSL_set_bio>(SSL *ssl, BIO *rbio, BIO *wbio);
        +
        +=item int B<SSL_set_cipher_list>(SSL *ssl, char *str);
        +
        +=item void B<SSL_set_client_CA_list>(SSL *ssl, STACK *list);
        +
        +=item void B<SSL_set_connect_state>(SSL *ssl);
        +
        +=item int B<SSL_set_ex_data>(SSL *ssl, int idx, char *arg);
        +
        +=item int B<SSL_set_fd>(SSL *ssl, int fd);
        +
        +=item void B<SSL_set_info_callback>(SSL *ssl, void (*cb);(void))
        +
        +=item void B<SSL_set_msg_callback>(SSL *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
        +
        +=item void B<SSL_set_msg_callback_arg>(SSL *ctx, void *arg);
        +
        +=item void B<SSL_set_options>(SSL *ssl, unsigned long op);
        +
        +=item void B<SSL_set_quiet_shutdown>(SSL *ssl, int mode);
        +
        +=item void B<SSL_set_read_ahead>(SSL *ssl, int yes);
        +
        +=item int B<SSL_set_rfd>(SSL *ssl, int fd);
        +
        +=item int B<SSL_set_session>(SSL *ssl, SSL_SESSION *session);
        +
        +=item void B<SSL_set_shutdown>(SSL *ssl, int mode);
        +
        +=item int B<SSL_set_ssl_method>(SSL *ssl, const SSL_METHOD *meth);
        +
        +=item void B<SSL_set_time>(SSL *ssl, long t);
        +
        +=item void B<SSL_set_timeout>(SSL *ssl, long t);
        +
        +=item void B<SSL_set_verify>(SSL *ssl, int mode, int (*callback);(void))
        +
        +=item void B<SSL_set_verify_result>(SSL *ssl, long arg);
        +
        +=item int B<SSL_set_wfd>(SSL *ssl, int fd);
        +
        +=item int B<SSL_shutdown>(SSL *ssl);
        +
        +=item int B<SSL_state>(const SSL *ssl);
        +
        +=item char *B<SSL_state_string>(const SSL *ssl);
        +
        +=item char *B<SSL_state_string_long>(const SSL *ssl);
        +
        +=item long B<SSL_total_renegotiations>(SSL *ssl);
        +
        +=item int B<SSL_use_PrivateKey>(SSL *ssl, EVP_PKEY *pkey);
        +
        +=item int B<SSL_use_PrivateKey_ASN1>(int type, SSL *ssl, unsigned char *d, long len);
        +
        +=item int B<SSL_use_PrivateKey_file>(SSL *ssl, char *file, int type);
        +
        +=item int B<SSL_use_RSAPrivateKey>(SSL *ssl, RSA *rsa);
        +
        +=item int B<SSL_use_RSAPrivateKey_ASN1>(SSL *ssl, unsigned char *d, long len);
        +
        +=item int B<SSL_use_RSAPrivateKey_file>(SSL *ssl, char *file, int type);
        +
        +=item int B<SSL_use_certificate>(SSL *ssl, X509 *x);
        +
        +=item int B<SSL_use_certificate_ASN1>(SSL *ssl, int len, unsigned char *d);
        +
        +=item int B<SSL_use_certificate_file>(SSL *ssl, char *file, int type);
        +
        +=item int B<SSL_version>(const SSL *ssl);
        +
        +=item int B<SSL_want>(const SSL *ssl);
        +
        +=item int B<SSL_want_nothing>(const SSL *ssl);
        +
        +=item int B<SSL_want_read>(const SSL *ssl);
        +
        +=item int B<SSL_want_write>(const SSL *ssl);
        +
        +=item int B<SSL_want_x509_lookup>(const SSL *ssl);
        +
        +=item int B<SSL_write>(SSL *ssl, const void *buf, int num);
        +
        +=item void B<SSL_set_psk_client_callback>(SSL *ssl, unsigned int (*callback)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len));
        +
        +=item int B<SSL_use_psk_identity_hint>(SSL *ssl, const char *hint);
        +
        +=item void B<SSL_set_psk_server_callback>(SSL *ssl, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len));
        +
        +=item const char *B<SSL_get_psk_identity_hint>(SSL *ssl);
        +
        +=item const char *B<SSL_get_psk_identity>(SSL *ssl);
        +
        +=back
        +
        +=head1 SEE ALSO
        +
        +L<openssl(1)|openssl(1)>, L<crypto(3)|crypto(3)>,
        +L<SSL_accept(3)|SSL_accept(3)>, L<SSL_clear(3)|SSL_clear(3)>,
        +L<SSL_connect(3)|SSL_connect(3)>,
        +L<SSL_CIPHER_get_name(3)|SSL_CIPHER_get_name(3)>,
        +L<SSL_COMP_add_compression_method(3)|SSL_COMP_add_compression_method(3)>,
        +L<SSL_CTX_add_extra_chain_cert(3)|SSL_CTX_add_extra_chain_cert(3)>,
        +L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
        +L<SSL_CTX_ctrl(3)|SSL_CTX_ctrl(3)>,
        +L<SSL_CTX_flush_sessions(3)|SSL_CTX_flush_sessions(3)>,
        +L<SSL_CTX_get_ex_new_index(3)|SSL_CTX_get_ex_new_index(3)>,
        +L<SSL_CTX_get_verify_mode(3)|SSL_CTX_get_verify_mode(3)>,
        +L<SSL_CTX_load_verify_locations(3)|SSL_CTX_load_verify_locations(3)>
        +L<SSL_CTX_new(3)|SSL_CTX_new(3)>,
        +L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
        +L<SSL_CTX_sess_set_cache_size(3)|SSL_CTX_sess_set_cache_size(3)>,
        +L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>,
        +L<SSL_CTX_sessions(3)|SSL_CTX_sessions(3)>,
        +L<SSL_CTX_set_cert_store(3)|SSL_CTX_set_cert_store(3)>,
        +L<SSL_CTX_set_cert_verify_callback(3)|SSL_CTX_set_cert_verify_callback(3)>,
        +L<SSL_CTX_set_cipher_list(3)|SSL_CTX_set_cipher_list(3)>,
        +L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
        +L<SSL_CTX_set_client_cert_cb(3)|SSL_CTX_set_client_cert_cb(3)>,
        +L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>,
        +L<SSL_CTX_set_generate_session_id(3)|SSL_CTX_set_generate_session_id(3)>,
        +L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>,
        +L<SSL_CTX_set_max_cert_list(3)|SSL_CTX_set_max_cert_list(3)>,
        +L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>,
        +L<SSL_CTX_set_msg_callback(3)|SSL_CTX_set_msg_callback(3)>,
        +L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
        +L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
        +L<SSL_CTX_set_session_cache_mode(3)|SSL_CTX_set_session_cache_mode(3)>,
        +L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>,
        +L<SSL_CTX_set_ssl_version(3)|SSL_CTX_set_ssl_version(3)>,
        +L<SSL_CTX_set_timeout(3)|SSL_CTX_set_timeout(3)>,
        +L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>,
        +L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>,
        +L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>,
        +L<SSL_CTX_use_certificate(3)|SSL_CTX_use_certificate(3)>,
        +L<SSL_alert_type_string(3)|SSL_alert_type_string(3)>,
        +L<SSL_do_handshake(3)|SSL_do_handshake(3)>,
        +L<SSL_get_SSL_CTX(3)|SSL_get_SSL_CTX(3)>,
        +L<SSL_get_ciphers(3)|SSL_get_ciphers(3)>,
        +L<SSL_get_client_CA_list(3)|SSL_get_client_CA_list(3)>,
        +L<SSL_get_default_timeout(3)|SSL_get_default_timeout(3)>,
        +L<SSL_get_error(3)|SSL_get_error(3)>,
        +L<SSL_get_ex_data_X509_STORE_CTX_idx(3)|SSL_get_ex_data_X509_STORE_CTX_idx(3)>,
        +L<SSL_get_ex_new_index(3)|SSL_get_ex_new_index(3)>,
        +L<SSL_get_fd(3)|SSL_get_fd(3)>,
        +L<SSL_get_peer_cert_chain(3)|SSL_get_peer_cert_chain(3)>,
        +L<SSL_get_rbio(3)|SSL_get_rbio(3)>,
        +L<SSL_get_session(3)|SSL_get_session(3)>,
        +L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
        +L<SSL_get_version(3)|SSL_get_version(3)>,
        +L<SSL_library_init(3)|SSL_library_init(3)>,
        +L<SSL_load_client_CA_file(3)|SSL_load_client_CA_file(3)>,
        +L<SSL_new(3)|SSL_new(3)>,
        +L<SSL_pending(3)|SSL_pending(3)>,
        +L<SSL_read(3)|SSL_read(3)>,
        +L<SSL_rstate_string(3)|SSL_rstate_string(3)>,
        +L<SSL_session_reused(3)|SSL_session_reused(3)>,
        +L<SSL_set_bio(3)|SSL_set_bio(3)>,
        +L<SSL_set_connect_state(3)|SSL_set_connect_state(3)>,
        +L<SSL_set_fd(3)|SSL_set_fd(3)>,
        +L<SSL_set_session(3)|SSL_set_session(3)>,
        +L<SSL_set_shutdown(3)|SSL_set_shutdown(3)>,
        +L<SSL_shutdown(3)|SSL_shutdown(3)>,
        +L<SSL_state_string(3)|SSL_state_string(3)>,
        +L<SSL_want(3)|SSL_want(3)>,
        +L<SSL_write(3)|SSL_write(3)>,
        +L<SSL_SESSION_free(3)|SSL_SESSION_free(3)>,
        +L<SSL_SESSION_get_ex_new_index(3)|SSL_SESSION_get_ex_new_index(3)>,
        +L<SSL_SESSION_get_time(3)|SSL_SESSION_get_time(3)>,
        +L<d2i_SSL_SESSION(3)|d2i_SSL_SESSION(3)>,
        +L<SSL_CTX_set_psk_client_callback(3)|SSL_CTX_set_psk_client_callback(3)>,
        +L<SSL_CTX_use_psk_identity_hint(3)|SSL_CTX_use_psk_identity_hint(3)>,
        +L<SSL_get_psk_identity(3)|SSL_get_psk_identity(3)>
        +
        +=head1 HISTORY
        +
        +The L<ssl(3)|ssl(3)> document appeared in OpenSSL 0.9.2
        +
        +=cut
        +
        diff --git a/vendor/openssl/openssl/doc/ssleay.txt b/vendor/openssl/openssl/doc/ssleay.txt
        new file mode 100644
        index 000000000..4d2e71486
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/ssleay.txt
        @@ -0,0 +1,7030 @@
        +
        +Bundle of old SSLeay documentation files [OBSOLETE!]
        +
        +*** WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! ***
        +
        +OBSOLETE means that nothing in this document should be trusted.  This
        +document is provided mostly for historical purposes (it wasn't even up
        +to date at the time SSLeay 0.8.1 was released) and as inspiration.  If
        +you copy some snippet of code from this document, please _check_ that
        +it really is correct from all points of view.  For example, you can
        +check with the other documents in this directory tree, or by comparing
        +with relevant parts of the include files.
        +
        +People have done the mistake of trusting what's written here.  Please
        +don't do that.
        +
        +*** WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! ***
        +
        +
        +==== readme ========================================================
        +
        +This is the old 0.6.6 docuementation.  Most of the cipher stuff is still
        +relevent but I'm working (very slowly) on new documentation.
        +The current version can be found online at
        +
        +http://www.cryptsoft.com/ssleay/doc
        +
        +==== API.doc ========================================================
        +
        +SSL - SSLv2/v3/v23 etc.
        +
        +BIO - methods and how they plug together
        +
        +MEM - memory allocation callback
        +
        +CRYPTO - locking for threads
        +
        +EVP - Ciphers/Digests/signatures
        +
        +RSA - methods
        +
        +X509 - certificate retrieval
        +
        +X509 - validation
        +
        +X509 - X509v3 extensions
        +
        +Objects - adding object identifiers
        +
        +ASN.1 - parsing
        +
        +PEM - parsing
        +
        +==== ssl/readme =====================================================
        +
        +22 Jun 1996
        +This file belongs in ../apps, but I'll leave it here because it deals
        +with SSL :-)  It is rather dated but it gives you an idea of how
        +things work.
        +===
        +
        +17 Jul 1995
        +I have been changing things quite a bit and have not fully updated
        +this file, so take what you read with a grain of salt
        +eric
        +===
        +The s_client and s_server programs can be used to test SSL capable
        +IP/port addresses and the verification of the X509 certificates in use
        +by these services.  I strongly advise having a look at the code to get
        +an idea of how to use the authentication under SSLeay.  Any feedback
        +on changes and improvements would be greatly accepted.
        +
        +This file will probably be gibberish unless you have read
        +rfc1421, rfc1422, rfc1423 and rfc1424 which describe PEM
        +authentication.
        +
        +A Brief outline (and examples) how to use them to do so.
        +
        +NOTE:
        +The environment variable SSL_CIPER is used to specify the prefered
        +cipher to use, play around with setting it's value to combinations of
        +RC4-MD5, EXP-RC4-MD5, CBC-DES-MD5, CBC3-DES-MD5, CFB-DES-NULL
        +in a : separated list.
        +
        +This directory contains 3 X509 certificates which can be used by these programs.
        +client.pem: a file containing a certificate and private key to be used
        +	by s_client.
        +server.pem :a file containing a certificate and private key to be used
        +	by s_server.
        +eay1024.pem:the certificate used to sign client.pem and server.pem.
        +	This would be your CA's certificate.  There is also a link
        +	from the file a8556381.0 to eay1024.PEM.  The value a8556381
        +	is returned by 'x509 -hash -noout <eay1024.pem' and is the
        +	value used by X509 verification routines to 'find' this
        +	certificte when search a directory for it.
        +	[the above is not true any more, the CA cert is 
        +	 ../certs/testca.pem which is signed by ../certs/mincomca.pem]
        +
        +When testing the s_server, you may get
        +bind: Address already in use
        +errors.  These indicate the port is still being held by the unix
        +kernel and you are going to have to wait for it to let go of it.  If
        +this is the case, remember to use the port commands on the s_server and
        +s_client to talk on an alternative port.
        +
        +=====
        +s_client.
        +This program can be used to connect to any IP/hostname:port that is
        +talking SSL.  Once connected, it will attempt to authenticate the
        +certificate it was passed and if everything works as expected, a 2
        +directional channel will be open.  Any text typed will be sent to the
        +other end.  type Q<cr> to exit.  Flags are as follows.
        +-host arg	: Arg is the host or IP address to connect to.
        +-port arg	: Arg is the port to connect to (https is 443).
        +-verify arg	: Turn on authentication of the server certificate.
        +		: Arg specifies the 'depth', this will covered below.
        +-cert arg	: The optional certificate to use.  This certificate
        +		: will be returned to the server if the server
        +		: requests it for client authentication.
        +-key arg	: The private key that matches the certificate
        +		: specified by the -cert option.  If this is not
        +		: specified (but -cert is), the -cert file will be
        +		: searched for the Private key.  Both files are
        +		: assumed to be in PEM format.
        +-CApath arg	: When to look for certificates when 'verifying' the
        +		: certificate from the server.
        +-CAfile arg	: A file containing certificates to be used for
        +		: 'verifying' the server certificate.
        +-reconnect	: Once a connection has been made, drop it and
        +		: reconnect with same session-id.  This is for testing :-).
        +
        +The '-verify n' parameter specifies not only to verify the servers
        +certificate but to also only take notice of 'n' levels.  The best way
        +to explain is to show via examples.
        +Given
        +s_server -cert server.PEM is running.
        +
        +s_client
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify error:num=1:unable to get issuer certificate
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +What has happened is that the 'SSLeay demo server' certificate's
        +issuer ('CA') could not be found but because verify is not on, we
        +don't care and the connection has been made anyway.  It is now 'up'
        +using CBC-DES-MD5 mode.  This is an unauthenticate secure channel.
        +You may not be talking to the right person but the data going to them
        +is encrypted.
        +
        +s_client -verify 0
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify error:num=1:unable to get issuer certificate
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +We are 'verifying' but only to depth 0, so since the 'SSLeay demo server'
        +certificate passed the date and checksum, we are happy to proceed.
        +
        +s_client -verify 1
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify error:num=1:unable to get issuer certificate
        +	verify return:0
        +	ERROR
        +	verify error:unable to get issuer certificate
        +In this case we failed to make the connection because we could not
        +authenticate the certificate because we could not find the
        +'CA' certificate.
        +
        +s_client -verify 1 -CAfile eay1024.PEM
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +We loaded the certificates from the file eay1024.PEM.  Everything
        +checked out and so we made the connection.
        +
        +s_client -verify 1 -CApath .
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +We looked in out local directory for issuer certificates and 'found'
        +a8556381.0 and so everything is ok.
        +
        +It is worth noting that 'CA' is a self certified certificate.  If you
        +are passed one of these, it will fail to 'verify' at depth 0 because
        +we need to lookup the certifier of a certificate from some information
        +that we trust and keep locally.
        +
        +SSL_CIPHER=CBC3-DES-MD5:RC4-MD5
        +export SSL_CIPHER
        +s_client -verify 10 -CApath . -reconnect
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	drop the connection and reconnect with the same session id
        +	CIPHER is CBC3-DES-MD5
        +This has done a full connection and then re-estabished it with the
        +same session id but a new socket.  No RSA stuff occures on the second
        +connection.  Note that we said we would prefer to use CBC3-DES-MD5
        +encryption and so, since the server supports it, we are.
        +
        +=====
        +s_server
        +This program accepts SSL connections on a specified port
        +Once connected, it will estabish an SSL connection and optionaly
        +attempt to authenticate the client.  A 2 directional channel will be
        +open.  Any text typed will be sent to the other end.  Type Q<cr> to exit.
        +Flags are as follows.
        +-port arg	: Arg is the port to listen on.
        +-verify arg	: Turn on authentication of the client if they have a
        +		: certificate.  Arg specifies the 'depth'.
        +-Verify arg	: Turn on authentication of the client. If they don't
        +		: have a valid certificate, drop the connection.
        +-cert arg	: The certificate to use.  This certificate
        +		: will be passed to the client.  If it is not
        +		: specified, it will default to server.PEM
        +-key arg	: The private key that matches the certificate
        +		: specified by the -cert option.  If this is not
        +		: specified (but -cert is), the -cert file will be
        +		: searched for the Private key.  Both files are
        +		: assumed to be in PEM format.  Default is server.PEM
        +-CApath arg	: When to look for certificates when 'verifying' the
        +		: certificate from the client.
        +-CAfile arg	: A file containing certificates to be used for
        +		: 'verifying' the client certificate.
        +
        +For the following 'demo'  I will specify the s_server command and
        +the s_client command and then list the output from the s_server.
        +s_server
        +s_client
        +	CONNECTED
        +	CIPHER is CBC-DES-MD5
        +Everything up and running
        +
        +s_server -verify 0
        +s_client  
        +	CONNECTED
        +	CIPHER is CBC-DES-MD5
        +Ok since no certificate was returned and we don't care.
        +
        +s_server -verify 0
        +./s_client -cert client.PEM
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
        +	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify error:num=1:unable to get issuer certificate
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +Ok since we were only verifying to level 0
        +
        +s_server -verify 4
        +s_client -cert client.PEM
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
        +	issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify error:num=1:unable to get issuer certificate
        +	verify return:0
        +	ERROR
        +	verify error:unable to get issuer certificate
        +Bad because we could not authenticate the returned certificate.
        +
        +s_server -verify 4 -CApath .
        +s_client -cert client.PEM
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +Ok because we could authenticate the returned certificate :-).
        +
        +s_server -Verify 0 -CApath .
        +s_client
        +	CONNECTED
        +	ERROR
        +	SSL error:function is:REQUEST_CERTIFICATE
        +		 :error is   :client end did not return a certificate
        +Error because no certificate returned.
        +
        +s_server -Verify 4 -CApath .
        +s_client -cert client.PEM
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +Full authentication of the client.
        +
        +So in summary to do full authentication of both ends
        +s_server -Verify 9 -CApath .
        +s_client -cert client.PEM -CApath . -verify 9
        +From the server side
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo client
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +From the client side
        +	CONNECTED
        +	depth=0 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
        +	verify return:1
        +	depth=1 /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
        +	verify return:1
        +	CIPHER is CBC-DES-MD5
        +
        +For general probing of the 'internet https' servers for the
        +distribution area, run
        +s_client -host www.netscape.com -port 443 -verify 4 -CApath ../rsa/hash
        +Then enter
        +GET /
        +and you should be talking to the https server on that host.
        +
        +www.rsa.com was refusing to respond to connections on 443 when I was
        +testing.
        +
        +have fun :-).
        +
        +eric
        +
        +==== a_verify.doc ========================================================
        +
        +From eay@mincom.com Fri Oct  4 18:29:06 1996
        +Received: by orb.mincom.oz.au id AA29080
        +  (5.65c/IDA-1.4.4 for eay); Fri, 4 Oct 1996 08:29:07 +1000
        +Date: Fri, 4 Oct 1996 08:29:06 +1000 (EST)
        +From: Eric Young <eay@mincom.oz.au>
        +X-Sender: eay@orb
        +To: wplatzer <wplatzer@iaik.tu-graz.ac.at>
        +Cc: Eric Young <eay@mincom.oz.au>, SSL Mailing List <ssl-users@mincom.com>
        +Subject: Re: Netscape's Public Key
        +In-Reply-To: <19961003134837.NTM0049@iaik.tu-graz.ac.at>
        +Message-Id: <Pine.SOL.3.91.961004081346.8018K-100000@orb>
        +Mime-Version: 1.0
        +Content-Type: TEXT/PLAIN; charset=US-ASCII
        +Status: RO
        +X-Status: 
        +
        +On Thu, 3 Oct 1996, wplatzer wrote:
        +> I get Public Key from Netscape (Gold 3.0b4), but cannot do anything
        +> with it... It looks like (asn1parse):
        +> 
        +> 0:d=0 hl=3 l=180 cons: SEQUENCE
        +> 3:d=1 hl=2 l= 96 cons: SEQUENCE
        +> 5:d=2 hl=2 l= 92 cons: SEQUENCE
        +> 7:d=3 hl=2 l= 13 cons: SEQUENCE
        +> 9:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
        +> 20:d=4 hl=2 l= 0 prim: NULL
        +> 22:d=3 hl=2 l= 75 prim: BIT STRING
        +> 99:d=2 hl=2 l= 0 prim: IA5STRING :
        +> 101:d=1 hl=2 l= 13 cons: SEQUENCE
        +> 103:d=2 hl=2 l= 9 prim: OBJECT :md5withRSAEncryption
        +> 114:d=2 hl=2 l= 0 prim: NULL
        +> 116:d=1 hl=2 l= 65 prim: BIT STRING
        +> 
        +> The first BIT STRING is the public key and the second BIT STRING is 
        +> the signature.
        +> But a public key consists of the public exponent and the modulus. Are 
        +> both numbers in the first BIT STRING?
        +> Is there a document simply describing this coding stuff (checking 
        +> signature, get the public key, etc.)?
        +
        +Minimal in SSLeay.  If you want to see what the modulus and exponent are,
        +try asn1parse -offset 25 -length 75 <key.pem
        +asn1parse will currently stuff up on the 'length 75' part (fixed in next 
        +release) but it will print the stuff.  If you are after more 
        +documentation on ASN.1, have a look at www.rsa.com and get their PKCS 
        +documents, most of my initial work on SSLeay was done using them.
        +
        +As for SSLeay,
        +util/crypto.num and util/ssl.num are lists of all exported functions in 
        +the library (but not macros :-(.
        +
        +The ones for extracting public keys from certificates and certificate 
        +requests are EVP_PKEY *      X509_REQ_extract_key(X509_REQ *req);
        +EVP_PKEY *      X509_extract_key(X509 *x509);
        +
        +To verify a signature on a signed ASN.1 object
        +int X509_verify(X509 *a,EVP_PKEY *key);
        +int X509_REQ_verify(X509_REQ *a,EVP_PKEY *key);
        +int X509_CRL_verify(X509_CRL *a,EVP_PKEY *key);
        +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a,EVP_PKEY *key);
        +
        +I should mention that EVP_PKEY can be used to hold a public or a private key,
        +since for  things like RSA and DSS, a public key is just a subset of what 
        +is stored for the private key.
        +
        +To sign any of the above structures
        +
        +int X509_sign(X509 *a,EVP_PKEY *key,EVP_MD *md);
        +int X509_REQ_sign(X509_REQ *a,EVP_PKEY *key,EVP_MD *md);
        +int X509_CRL_sign(X509_CRL *a,EVP_PKEY *key,EVP_MD *md);
        +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *a,EVP_PKEY *key,EVP_MD *md);
        +
        +where md is the message digest to sign with.
        +
        +There are all defined in x509.h and all the _sign and _verify functions are
        +actually macros to the ASN1_sign() and ASN1_verify() functions.
        +These functions will put the correct algorithm identifiers in the correct 
        +places in the structures.
        +
        +eric
        +--
        +Eric Young                  | BOOL is tri-state according to Bill Gates.
        +AARNet: eay@mincom.oz.au    | RTFM Win32 GetMessage().
        +
        +==== x509 =======================================================
        +
        +X509_verify()
        +X509_sign()
        +
        +X509_get_version()
        +X509_get_serialNumber()
        +X509_get_issuer()
        +X509_get_subject()
        +X509_get_notBefore()
        +X509_get_notAfter()
        +X509_get_pubkey()
        +
        +X509_set_version()
        +X509_set_serialNumber()
        +X509_set_issuer()
        +X509_set_subject()
        +X509_set_notBefore()
        +X509_set_notAfter()
        +X509_set_pubkey()
        +
        +X509_get_extensions()
        +X509_set_extensions()
        +
        +X509_EXTENSIONS_clear()
        +X509_EXTENSIONS_retrieve()
        +X509_EXTENSIONS_add()
        +X509_EXTENSIONS_delete()
        +
        +==== x509 attribute ================================================
        +
        +PKCS7
        +	STACK of X509_ATTRIBUTES
        +		ASN1_OBJECT
        +		STACK of ASN1_TYPE
        +
        +So it is
        +
        +p7.xa[].obj
        +p7.xa[].data[]
        +
        +get_obj_by_nid(STACK , nid)
        +get_num_by_nid(STACK , nid)
        +get_data_by_nid(STACK , nid, index)
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_new(void );
        +void		X509_ATTRIBUTE_free(X509_ATTRIBUTE *a);
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **ex,
        +			int nid, STACK *value);
        +
        +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **ex,
        +			int nid, STACK *value);
        +
        +int		X509_ATTRIBUTE_set_object(X509_ATTRIBUTE *ex,ASN1_OBJECT *obj);
        +int		X509_ATTRIBUTE_add_data(X509_ATTRIBUTE *ex, int index,
        +			ASN1_TYPE *value);
        +
        +ASN1_OBJECT *	X509_ATTRIBUTE_get_object(X509_ATTRIBUTE *ex);
        +int 		X509_ATTRIBUTE_get_num(X509_ATTRIBUTE *ne);
        +ASN1_TYPE *	X509_ATTRIBUTE_get_data(X509_ATTRIBUTE *ne,int index);
        +
        +ASN1_TYPE *	X509_ATTRIBUTE_get_data_by_NID(X509_ATTRIBUTE *ne,
        +			ASN1_OBJECT *obj);
        +
        +X509_ATTRIBUTE *PKCS7_get_s_att_by_NID(PKCS7 *p7,int nid);
        +X509_ATTRIBUTE *PKCS7_get_u_att_by_NID(PKCS7 *p7,int nid);
        +
        +==== x509 v3 ========================================================
        +
        +The 'new' system.
        +
        +The X509_EXTENSION_METHOD includes extensions and attributes and/or names. 
        +Basically everthing that can be added to an X509 with an OID identifying it.
        +
        +It operates via 2 methods per object id.
        +int a2i_XXX(X509 *x,char *str,int len);
        +int i2a_XXX(BIO *bp,X509 *x);
        +
        +The a2i_XXX function will add the object with a value converted from the
        +string into the X509.  Len can be -1 in which case the length is calculated
        +via strlen(str).   Applications can always use direct knowledge to load and
        +unload the relevent objects themselves.
        +
        +i2a_XXX will print to the passed BIO, a text representation of the
        +relevet object.  Use a memory BIO if you want it printed to a buffer :-).
        +
        +X509_add_by_NID(X509 *x,int nid,char *str,int len);
        +X509_add_by_OBJ(X509 *x,ASN1_OBJECT *obj,char *str,int len);
        +
        +X509_print_by_name(BIO *bp,X509 *x);
        +X509_print_by_NID(BIO *bp,X509 *x);
        +X509_print_by_OBJ(BIO *bp,X509 *x);
        +
        +==== verify ========================================================
        +
        +X509_verify_cert_chain(
        +	CERT_STORE *cert_store,
        +	STACK /* X509 */ *certs,
        +	int *verify_result,
        +	int (*verify_error_callback)()
        +	char *argument_to_callback, /* SSL */
        +
        +app_verify_callback(
        +	char *app_verify_arg, /* from SSL_CTX */
        +	STACK /* X509 */ *certs,
        +	int *verify_result,
        +	int (*verify_error_callback)()
        +	SSL *s,
        +
        +int X509_verify_cert(
        +	CERT_STORE *cert_store,
        +	X509 *x509,
        +	int *verify_result,
        +	int (*verify_error_callback)(),
        +	char *arg,
        +
        +==== apps.doc ========================================================
        +
        +The applications
        +
        +Ok, where to begin....
        +In the begining, when SSLeay was small (April 1995), there
        +were but few applications, they did happily cohabit in
        +the one bin directory.  Then over time, they did multiply and grow,
        +and they started to look like microsoft software; 500k to print 'hello world'.
        +A new approach was needed.  They were coalessed into one 'Monolithic'
        +application, ssleay.  This one program is composed of many programs that
        +can all be compiled independantly.
        +
        +ssleay has 3 modes of operation.
        +1) If the ssleay binary has the name of one of its component programs, it
        +executes that program and then exits.  This can be achieved by using hard or
        +symbolic links, or failing that, just renaming the binary.
        +2) If the first argument to ssleay is the name of one of the component
        +programs, that program runs that program and then exits.
        +3) If there are no arguments, ssleay enters a 'command' mode.  Each line is
        +interpreted as a program name plus arguments.  After each 'program' is run,
        +ssleay returns to the comand line.
        +
        +dgst	- message digests
        +enc	- encryption and base64 encoding
        +
        +ans1parse - 'pulls' appart ASN.1 encoded objects like certificates.
        +
        +dh	- Diffle-Hellman parameter manipulation.
        +rsa	- RSA manipulations.
        +crl	- Certificate revokion list manipulations
        +x509	- X509 cert fiddles, including signing.
        +pkcs7	- pkcs7 manipulation, only DER versions right now.
        +
        +genrsa	- generate an RSA private key.
        +gendh	- Generate a set of Diffle-Hellman parameters.
        +req	- Generate a PKCS#10 object, a certificate request.
        +
        +s_client - SSL client program
        +s_server - SSL server program
        +s_time	 - A SSL protocol timing program
        +s_mult	 - Another SSL server, but it multiplexes
        +	   connections.
        +s_filter - under development
        +
        +errstr	- Convert SSLeay error numbers to strings.
        +ca	- Sign certificate requests, and generate
        +	  certificate revokion lists
        +crl2pkcs7 - put a crl and certifcates into a pkcs7 object.
        +speed	- Benchmark the ciphers.
        +verify	- Check certificates
        +hashdir - under development
        +
        +[ there a now a few more options, play with the program to see what they
        +  are ]
        +
        +==== asn1.doc ========================================================
        +
        +The ASN.1 Routines.
        +
        +ASN.1 is a specification for how to encode structured 'data' in binary form.
        +The approach I have take to the manipulation of structures and their encoding
        +into ASN.1 is as follows.
        +
        +For each distinct structure there are 4 function of the following form
        +TYPE *TYPE_new(void);
        +void TYPE_free(TYPE *);
        +TYPE *d2i_TYPE(TYPE **a,unsigned char **pp,long length);
        +long i2d_TYPE(TYPE *a,unsigned char **pp); 	/* CHECK RETURN VALUE */
        +
        +where TYPE is the type of the 'object'.  The TYPE that have these functions
        +can be in one of 2 forms, either the internal C malloc()ed data structure
        +or in the DER (a variant of ASN.1 encoding) binary encoding which is just
        +an array of unsigned bytes.  The 'i2d' functions converts from the internal
        +form to the DER form and the 'd2i' functions convert from the DER form to
        +the internal form.
        +
        +The 'new' function returns a malloc()ed version of the structure with all
        +substructures either created or left as NULL pointers.  For 'optional'
        +fields, they are normally left as NULL to indicate no value.  For variable
        +size sub structures (often 'SET OF' or 'SEQUENCE OF' in ASN.1 syntax) the
        +STACK data type is used to hold the values.  Have a read of stack.doc
        +and have a look at the relevant header files to see what I mean.  If there
        +is an error while malloc()ing the structure, NULL is returned.
        +
        +The 'free' function will free() all the sub components of a particular
        +structure.  If any of those sub components have been 'removed', replace
        +them with NULL pointers, the 'free' functions are tolerant of NULL fields.
        +
        +The 'd2i' function copies a binary representation into a C structure.  It
        +operates as follows.  'a' is a pointer to a pointer to
        +the structure to populate, 'pp' is a pointer to a pointer to where the DER
        +byte string is located and 'length' is the length of the '*pp' data.
        +If there are no errors, a pointer to the populated structure is returned.
        +If there is an error, NULL is returned.  Errors can occur because of
        +malloc() failures but normally they will be due to syntax errors in the DER
        +encoded data being parsed. It is also an error if there was an
        +attempt to read more that 'length' bytes from '*p'.  If
        +everything works correctly, the value in '*p' is updated
        +to point at the location just beyond where the DER
        +structure was read from.  In this way, chained calls to 'd2i' type
        +functions can be made, with the pointer into the 'data' array being
        +'walked' along the input byte array.
        +Depending on the value passed for 'a', different things will be done.  If
        +'a' is NULL, a new structure will be malloc()ed and returned.  If '*a' is
        +NULL, a new structure will be malloc()ed and put into '*a' and returned.
        +If '*a' is not NULL, the structure in '*a' will be populated, or in the
        +case of an error, free()ed and then returned.
        +Having these semantics means that a structure
        +can call a 'd2i' function to populate a field and if the field is currently
        +NULL, the structure will be created.
        +
        +The 'i2d' function type is used to copy a C structure to a byte array.
        +The parameter 'a' is the structure to convert and '*p' is where to put it.
        +As for the 'd2i' type structure, 'p' is updated to point after the last
        +byte written.  If p is NULL, no data is written.  The function also returns
        +the number of bytes written.  Where this becomes useful is that if the
        +function is called with a NULL 'p' value, the length is returned.  This can
        +then be used to malloc() an array of bytes and then the same function can
        +be recalled passing the malloced array to be written to. e.g.
        +
        +int len;
        +unsigned char *bytes,*p;
        +len=i2d_X509(x,NULL);	/* get the size of the ASN1 encoding of 'x' */
        +if ((bytes=(unsigned char *)malloc(len)) == NULL)
        +	goto err;
        +p=bytes;
        +i2d_X509(x,&p);
        +
        +Please note that a new variable, 'p' was passed to i2d_X509.  After the
        +call to i2d_X509 p has been incremented by len bytes.
        +
        +Now the reason for this functional organisation is that it allows nested
        +structures to be built up by calling these functions as required.  There
        +are various macros used to help write the general 'i2d', 'd2i', 'new' and
        +'free' functions.  They are discussed in another file and would only be
        +used by some-one wanting to add new structures to the library.  As you
        +might be able to guess, the process of writing ASN.1 files can be a bit CPU
        +expensive for complex structures.  I'm willing to live with this since the
        +simpler library code make my life easier and hopefully most programs using
        +these routines will have their execution profiles dominated by cipher or
        +message digest routines.
        +What follows is a list of 'TYPE' values and the corresponding ASN.1
        +structure and where it is used.
        +
        +TYPE			ASN.1
        +ASN1_INTEGER		INTEGER
        +ASN1_BIT_STRING		BIT STRING
        +ASN1_OCTET_STRING	OCTET STRING
        +ASN1_OBJECT		OBJECT IDENTIFIER
        +ASN1_PRINTABLESTRING	PrintableString
        +ASN1_T61STRING		T61String
        +ASN1_IA5STRING		IA5String
        +ASN1_UTCTIME		UTCTime
        +ASN1_TYPE		Any of the above mentioned types plus SEQUENCE and SET
        +
        +Most of the above mentioned types are actualled stored in the
        +ASN1_BIT_STRING type and macros are used to differentiate between them.
        +The 3 types used are
        +
        +typedef struct asn1_object_st
        +	{
        +	/* both null if a dynamic ASN1_OBJECT, one is
        +	 * defined if a 'static' ASN1_OBJECT */
        +	char *sn,*ln;
        +	int nid;
        +	int length;
        +	unsigned char *data;
        +	} ASN1_OBJECT;
        +This is used to store ASN1 OBJECTS.  Read 'objects.doc' for details ono
        +routines to manipulate this structure.  'sn' and 'ln' are used to hold text
        +strings that represent the object (short name and long or lower case name).
        +These are used by the 'OBJ' library.  'nid' is a number used by the OBJ
        +library to uniquely identify objects.  The ASN1 routines will populate the
        +'length' and 'data' fields which will contain the bit string representing
        +the object.
        +
        +typedef struct asn1_bit_string_st
        +	{
        +	int length;
        +	int type;
        +	unsigned char *data;
        +	} ASN1_BIT_STRING;
        +This structure is used to hold all the other base ASN1 types except for
        +ASN1_UTCTIME (which is really just a 'char *').  Length is the number of
        +bytes held in data and type is the ASN1 type of the object (there is a list
        +in asn1.h).
        +
        +typedef struct asn1_type_st
        +	{
        +	int type;
        +	union	{
        +		char *ptr;
        +		ASN1_INTEGER *		integer;
        +		ASN1_BIT_STRING *	bit_string;
        +		ASN1_OCTET_STRING *	octet_string;
        +		ASN1_OBJECT *		object;
        +		ASN1_PRINTABLESTRING *	printablestring;
        +		ASN1_T61STRING *	t61string;
        +		ASN1_IA5STRING *	ia5string;
        +		ASN1_UTCTIME *		utctime;
        +		ASN1_BIT_STRING *	set;
        +		ASN1_BIT_STRING *	sequence;
        +		} value;
        +	} ASN1_TYPE;
        +This structure is used in a few places when 'any' type of object can be
        +expected.
        +
        +X509			Certificate
        +X509_CINF		CertificateInfo
        +X509_ALGOR		AlgorithmIdentifier
        +X509_NAME		Name			
        +X509_NAME_ENTRY		A single sub component of the name.
        +X509_VAL		Validity
        +X509_PUBKEY		SubjectPublicKeyInfo
        +The above mentioned types are declared in x509.h. They are all quite
        +straight forward except for the X509_NAME/X509_NAME_ENTRY pair.
        +A X509_NAME is a STACK (see stack.doc) of X509_NAME_ENTRY's.
        +typedef struct X509_name_entry_st
        +	{
        +	ASN1_OBJECT *object;
        +	ASN1_BIT_STRING *value;
        +	int set;
        +	int size; 	/* temp variable */
        +	} X509_NAME_ENTRY;
        +The size is a temporary variable used by i2d_NAME and set is the set number
        +for the particular NAME_ENTRY.  A X509_NAME is encoded as a sequence of
        +sequence of sets.  Normally each set contains only a single item.
        +Sometimes it contains more.  Normally throughout this library there will be
        +only one item per set.  The set field contains the 'set' that this entry is
        +a member of.  So if you have just created a X509_NAME structure and
        +populated it with X509_NAME_ENTRYs, you should then traverse the X509_NAME
        +(which is just a STACK) and set the 'set/' field to incrementing numbers.
        +For more details on why this is done, read the ASN.1 spec for Distinguished
        +Names.
        +
        +X509_REQ		CertificateRequest
        +X509_REQ_INFO		CertificateRequestInfo
        +These are used to hold certificate requests.
        +
        +X509_CRL		CertificateRevocationList
        +These are used to hold a certificate revocation list
        +
        +RSAPrivateKey		PrivateKeyInfo
        +RSAPublicKey		PublicKeyInfo
        +Both these 'function groups' operate on 'RSA' structures (see rsa.doc).
        +The difference is that the RSAPublicKey operations only manipulate the m
        +and e fields in the RSA structure.
        +
        +DSAPrivateKey		DSS private key
        +DSAPublicKey		DSS public key
        +Both these 'function groups' operate on 'DSS' structures (see dsa.doc).
        +The difference is that the RSAPublicKey operations only manipulate the 
        +XXX fields in the DSA structure.
        +
        +DHparams		DHParameter
        +This is used to hold the p and g value for The Diffie-Hellman operation.
        +The function deal with the 'DH' strucure (see dh.doc).
        +
        +Now all of these function types can be used with several other functions to give
        +quite useful set of general manipulation routines.  Normally one would
        +not uses these functions directly but use them via macros. 
        +
        +char *ASN1_dup(int (*i2d)(),char *(*d2i)(),char *x);
        +'x' is the input structure case to a 'char *', 'i2d' is the 'i2d_TYPE'
        +function for the type that 'x' is and d2i is the 'd2i_TYPE' function for the
        +type that 'x' is.  As is obvious from the parameters, this function
        +duplicates the strucutre by transforming it into the DER form and then
        +re-loading it into a new strucutre and returning the new strucutre.  This
        +is obviously a bit cpu intensive but when faced with a complex dynamic
        +structure this is the simplest programming approach.  There are macros for
        +duplicating the major data types but is simple to add extras.
        +
        +char *ASN1_d2i_fp(char *(*new)(),char *(*d2i)(),FILE *fp,unsigned char **x);
        +'x' is a pointer to a pointer of the 'desired type'.  new and d2i are the
        +corresponding 'TYPE_new' and 'd2i_TYPE' functions for the type and 'fp' is
        +an open file pointer to read from.  This function reads from 'fp' as much
        +data as it can and then uses 'd2i' to parse the bytes to load and return
        +the parsed strucutre in 'x' (if it was non-NULL) and to actually return the
        +strucutre.  The behavior of 'x' is as per all the other d2i functions.
        +
        +char *ASN1_d2i_bio(char *(*new)(),char *(*d2i)(),BIO *fp,unsigned char **x);
        +The 'BIO' is the new IO type being used in SSLeay (see bio.doc).  This
        +function is the same as ASN1_d2i_fp() except for the BIO argument.
        +ASN1_d2i_fp() actually calls this function.
        +
        +int ASN1_i2d_fp(int (*i2d)(),FILE *out,unsigned char *x);
        +'x' is converted to bytes by 'i2d' and then written to 'out'.  ASN1_i2d_fp
        +and ASN1_d2i_fp are not really symetric since ASN1_i2d_fp will read all
        +available data from the file pointer before parsing a single item while
        +ASN1_i2d_fp can be used to write a sequence of data objects.  To read a
        +series of objects from a file I would sugest loading the file into a buffer
        +and calling the relevent 'd2i' functions.
        +
        +char *ASN1_d2i_bio(char *(*new)(),char *(*d2i)(),BIO *fp,unsigned char **x);
        +This function is the same as ASN1_i2d_fp() except for the BIO argument.
        +ASN1_i2d_fp() actually calls this function.
        +
        +char *	PEM_ASN1_read(char *(*d2i)(),char *name,FILE *fp,char **x,int (*cb)());
        +This function will read the next PEM encoded (base64) object of the same
        +type as 'x' (loaded by the d2i function).  'name' is the name that is in
        +the '-----BEGIN name-----' that designates the start of that object type.
        +If the data is encrypted, 'cb' will be called to prompt for a password.  If
        +it is NULL a default function will be used to prompt from the password.
        +'x' is delt with as per the standard 'd2i' function interface.  This
        +function can be used to read a series of objects from a file.  While any
        +data type can be encrypted (see PEM_ASN1_write) only RSA private keys tend
        +to be encrypted.
        +
        +char *	PEM_ASN1_read_bio(char *(*d2i)(),char *name,BIO *fp,
        +	char **x,int (*cb)());
        +Same as PEM_ASN1_read() except using a BIO.  This is called by
        +PEM_ASN1_read().
        +
        +int	PEM_ASN1_write(int (*i2d)(),char *name,FILE *fp,char *x,EVP_CIPHER *enc,
        +		unsigned char *kstr,int klen,int (*callback)());
        +
        +int	PEM_ASN1_write_bio(int (*i2d)(),char *name,BIO *fp,
        +		char *x,EVP_CIPHER *enc,unsigned char *kstr,int klen,
        +		int (*callback)());
        +
        +int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
        +	ASN1_BIT_STRING *signature, char *data, RSA *rsa, EVP_MD *type);
        +int ASN1_verify(int (*i2d)(), X509_ALGOR *algor1,
        +	ASN1_BIT_STRING *signature,char *data, RSA *rsa);
        +
        +int ASN1_BIT_STRING_cmp(ASN1_BIT_STRING *a, ASN1_BIT_STRING *b);
        +ASN1_BIT_STRING *ASN1_BIT_STRING_type_new(int type );
        +
        +int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
        +void ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
        +ASN1_UTCTIME *ASN1_UTCTIME_dup(ASN1_UTCTIME *a);
        +
        +ASN1_BIT_STRING *d2i_asn1_print_type(ASN1_BIT_STRING **a,unsigned char **pp,
        +		long length,int type);
        +
        +int		i2d_ASN1_SET(STACK *a, unsigned char **pp,
        +			int (*func)(), int ex_tag, int ex_class);
        +STACK *		d2i_ASN1_SET(STACK **a, unsigned char **pp, long length,
        +			char *(*func)(), int ex_tag, int ex_class);
        +
        +int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *object);
        +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
        +int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
        +
        +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
        +long ASN1_INTEGER_get(ASN1_INTEGER *a);
        +ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
        +BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
        +
        +/* given a string, return the correct type.  Max is the maximum number
        + * of bytes to parse.  It stops parsing when 'max' bytes have been
        + * processed or a '\0' is hit */
        +int ASN1_PRINTABLE_type(unsigned char *s,int max);
        +
        +void ASN1_parse(BIO *fp,unsigned char *pp,long len);
        +
        +int i2d_ASN1_bytes(ASN1_BIT_STRING *a, unsigned char **pp, int tag, int class);
        +ASN1_BIT_STRING *d2i_ASN1_bytes(ASN1_OCTET_STRING **a, unsigned char **pp,
        +	long length, int Ptag, int Pclass);
        +
        +/* PARSING */
        +int asn1_Finish(ASN1_CTX *c);
        +
        +/* SPECIALS */
        +int ASN1_get_object(unsigned char **pp, long *plength, int *ptag,
        +	int *pclass, long omax);
        +int ASN1_check_infinite_end(unsigned char **p,long len);
        +void ASN1_put_object(unsigned char **pp, int constructed, int length,
        +	int tag, int class);
        +int ASN1_object_size(int constructed, int length, int tag);
        +
        +X509 *	X509_get_cert(CERTIFICATE_CTX *ctx,X509_NAME * name,X509 *tmp_x509);
        +int  	X509_add_cert(CERTIFICATE_CTX *ctx,X509 *);
        +
        +char *	X509_cert_verify_error_string(int n);
        +int 	X509_add_cert_file(CERTIFICATE_CTX *c,char *file, int type);
        +char *	X509_gmtime (char *s, long adj);
        +int	X509_add_cert_dir (CERTIFICATE_CTX *c,char *dir, int type);
        +int	X509_load_verify_locations (CERTIFICATE_CTX *ctx,
        +		char *file_env, char *dir_env);
        +int	X509_set_default_verify_paths(CERTIFICATE_CTX *cts);
        +X509 *	X509_new_D2i_X509(int len, unsigned char *p);
        +char *	X509_get_default_cert_area(void );
        +char *	X509_get_default_cert_dir(void );
        +char *	X509_get_default_cert_file(void );
        +char *	X509_get_default_cert_dir_env(void );
        +char *	X509_get_default_cert_file_env(void );
        +char *	X509_get_default_private_dir(void );
        +X509_REQ *X509_X509_TO_req(X509 *x, RSA *rsa);
        +int	X509_cert_verify(CERTIFICATE_CTX *ctx,X509 *xs, int (*cb)()); 
        +
        +CERTIFICATE_CTX *CERTIFICATE_CTX_new();
        +void CERTIFICATE_CTX_free(CERTIFICATE_CTX *c);
        +
        +void X509_NAME_print(BIO *fp, X509_NAME *name, int obase);
        +int		X509_print_fp(FILE *fp,X509 *x);
        +int		X509_print(BIO *fp,X509 *x);
        +
        +X509_INFO *	X509_INFO_new(void);
        +void		X509_INFO_free(X509_INFO *a);
        +
        +char *		X509_NAME_oneline(X509_NAME *a);
        +
        +#define X509_verify(x,rsa)
        +#define X509_REQ_verify(x,rsa)
        +#define X509_CRL_verify(x,rsa)
        +
        +#define X509_sign(x,rsa,md)
        +#define X509_REQ_sign(x,rsa,md)
        +#define X509_CRL_sign(x,rsa,md)
        +
        +#define X509_dup(x509)
        +#define d2i_X509_fp(fp,x509)
        +#define i2d_X509_fp(fp,x509)
        +#define d2i_X509_bio(bp,x509)
        +#define i2d_X509_bio(bp,x509)
        +
        +#define X509_CRL_dup(crl)
        +#define d2i_X509_CRL_fp(fp,crl)
        +#define i2d_X509_CRL_fp(fp,crl)
        +#define d2i_X509_CRL_bio(bp,crl)
        +#define i2d_X509_CRL_bio(bp,crl)
        +
        +#define X509_REQ_dup(req)
        +#define d2i_X509_REQ_fp(fp,req)
        +#define i2d_X509_REQ_fp(fp,req)
        +#define d2i_X509_REQ_bio(bp,req)
        +#define i2d_X509_REQ_bio(bp,req)
        +
        +#define RSAPrivateKey_dup(rsa)
        +#define d2i_RSAPrivateKey_fp(fp,rsa)
        +#define i2d_RSAPrivateKey_fp(fp,rsa)
        +#define d2i_RSAPrivateKey_bio(bp,rsa)
        +#define i2d_RSAPrivateKey_bio(bp,rsa)
        +
        +#define X509_NAME_dup(xn)
        +#define X509_NAME_ENTRY_dup(ne)
        +
        +void X509_REQ_print_fp(FILE *fp,X509_REQ *req);
        +void X509_REQ_print(BIO *fp,X509_REQ *req);
        +
        +RSA *X509_REQ_extract_key(X509_REQ *req);
        +RSA *X509_extract_key(X509 *x509);
        +
        +int		X509_issuer_and_serial_cmp(X509 *a, X509 *b);
        +unsigned long	X509_issuer_and_serial_hash(X509 *a);
        +
        +X509_NAME *	X509_get_issuer_name(X509 *a);
        +int		X509_issuer_name_cmp(X509 *a, X509 *b);
        +unsigned long	X509_issuer_name_hash(X509 *a);
        +
        +X509_NAME *	X509_get_subject_name(X509 *a);
        +int		X509_subject_name_cmp(X509 *a,X509 *b);
        +unsigned long	X509_subject_name_hash(X509 *x);
        +
        +int		X509_NAME_cmp (X509_NAME *a, X509_NAME *b);
        +unsigned long	X509_NAME_hash(X509_NAME *x);
        +
        +
        +==== bio.doc ========================================================
        +
        +BIO Routines
        +
        +This documentation is rather sparse, you are probably best 
        +off looking at the code for specific details.
        +
        +The BIO library is a IO abstraction that was originally 
        +inspired by the need to have callbacks to perform IO to FILE 
        +pointers when using Windows 3.1 DLLs.  There are two types 
        +of BIO; a source/sink type and a filter type.
        +The source/sink methods are as follows:
        +-	BIO_s_mem()  memory buffer - a read/write byte array that
        +	grows until memory runs out :-).
        +-	BIO_s_file()  FILE pointer - A wrapper around the normal 
        +	'FILE *' commands, good for use with stdin/stdout.
        +-	BIO_s_fd()  File descriptor - A wrapper around file 
        +	descriptors, often used with pipes.
        +-	BIO_s_socket()  Socket - Used around sockets.  It is 
        +	mostly in the Microsoft world that sockets are different 
        +	from file descriptors and there are all those ugly winsock 
        +	commands.
        +-	BIO_s_null()  Null - read nothing and write nothing.; a 
        +	useful endpoint for filter type BIO's specifically things 
        +	like the message digest BIO.
        +
        +The filter types are
        +-	BIO_f_buffer()  IO buffering - does output buffering into 
        +	larger chunks and performs input buffering to allow gets() 
        +	type functions.
        +-	BIO_f_md()  Message digest - a transparent filter that can 
        +	be asked to return a message digest for the data that has 
        +	passed through it.
        +-	BIO_f_cipher()  Encrypt or decrypt all data passing 
        +	through the filter.
        +-	BIO_f_base64()  Base64 decode on read and encode on write.
        +-	BIO_f_ssl()  A filter that performs SSL encryption on the 
        +	data sent through it.
        +
        +Base BIO functions.
        +The BIO library has a set of base functions that are 
        +implemented for each particular type.  Filter BIOs will 
        +normally call the equivalent function on the source/sink BIO 
        +that they are layered on top of after they have performed 
        +some modification to the data stream.  Multiple filter BIOs 
        +can be 'push' into a stack of modifers, so to read from a 
        +file, unbase64 it, then decrypt it, a BIO_f_cipher, 
        +BIO_f_base64 and a BIO_s_file would probably be used.  If a 
        +sha-1 and md5 message digest needed to be generated, a stack 
        +two BIO_f_md() BIOs and a BIO_s_null() BIO could be used.
        +The base functions are
        +-	BIO *BIO_new(BIO_METHOD *type); Create  a new BIO of  type 'type'.
        +-	int BIO_free(BIO *a); Free a BIO structure.  Depending on 
        +	the configuration, this will free the underlying data 
        +	object for a source/sink BIO.
        +-	int BIO_read(BIO *b, char *data, int len); Read upto 'len' 
        +	bytes into 'data'. 
        +-	int BIO_gets(BIO *bp,char *buf, int size); Depending on 
        +	the BIO, this can either be a 'get special' or a get one 
        +	line of data, as per fgets();
        +-	int BIO_write(BIO *b, char *data, int len); Write 'len' 
        +	bytes from 'data' to the 'b' BIO.
        +-	int BIO_puts(BIO *bp,char *buf); Either a 'put special' or 
        +	a write null terminated string as per fputs().
        +-	long BIO_ctrl(BIO *bp,int cmd,long larg,char *parg);  A 
        +	control function which is used to manipulate the BIO 
        +	structure and modify it's state and or report on it.  This 
        +	function is just about never used directly, rather it 
        +	should be used in conjunction with BIO_METHOD specific 
        +	macros.
        +-	BIO *BIO_push(BIO *new_top, BIO *old); new_top is apped to the
        +	top of the 'old' BIO list.  new_top should be a filter BIO.
        +	All writes will go through 'new_top' first and last on read.
        +	'old' is returned.
        +-	BIO *BIO_pop(BIO *bio); the new topmost BIO is returned, NULL if
        +	there are no more.
        +
        +If a particular low level BIO method is not supported 
        +(normally BIO_gets()), -2 will be returned if that method is 
        +called.  Otherwise the IO methods (read, write, gets, puts) 
        +will return the number of bytes read or written, and 0 or -1 
        +for error (or end of input).  For the -1 case, 
        +BIO_should_retry(bio) can be called to determine if it was a 
        +genuine error or a temporary problem.  -2 will also be 
        +returned if the BIO has not been initalised yet, in all 
        +cases, the correct error codes are set (accessible via the 
        +ERR library).
        +
        +
        +The following functions are convenience functions:
        +-	int BIO_printf(BIO *bio, char * format, ..);  printf but 
        +	to a BIO handle.
        +-	long BIO_ctrl_int(BIO *bp,int cmd,long larg,int iarg); a 
        +	convenience function to allow a different argument types 
        +	to be passed to BIO_ctrl().
        +-	int BIO_dump(BIO *b,char *bytes,int len); output 'len' 
        +	bytes from 'bytes' in a hex dump debug format.
        +-	long BIO_debug_callback(BIO *bio, int cmd, char *argp, int 
        +	argi, long argl, long ret) - a default debug BIO callback, 
        +	this is mentioned below.  To use this one normally has to 
        +	use the BIO_set_callback_arg() function to assign an 
        +	output BIO for the callback to use.
        +-	BIO *BIO_find_type(BIO *bio,int type); when there is a 'stack'
        +	of BIOs, this function scan the list and returns the first
        +	that is of type 'type', as listed in buffer.h under BIO_TYPE_XXX.
        +-	void BIO_free_all(BIO *bio); Free the bio and all other BIOs
        +	in the list.  It walks the bio->next_bio list.
        +
        +
        +
        +Extra commands are normally implemented as macros calling BIO_ctrl().
        +-	BIO_number_read(BIO *bio) - the number of bytes processed 
        +	by BIO_read(bio,.).
        +-	BIO_number_written(BIO *bio) - the number of bytes written 
        +	by BIO_write(bio,.).
        +-	BIO_reset(BIO *bio) - 'reset' the BIO.
        +-	BIO_eof(BIO *bio) - non zero if we are at the current end 
        +	of input.
        +-	BIO_set_close(BIO *bio, int close_flag) - set the close flag.
        +-	BIO_get_close(BIO *bio) - return the close flag.
        +	BIO_pending(BIO *bio) - return the number of bytes waiting 
        +	to be read (normally buffered internally).
        +-	BIO_flush(BIO *bio) - output any data waiting to be output.
        +-	BIO_should_retry(BIO *io) - after a BIO_read/BIO_write 
        +	operation returns 0 or -1, a call to this function will 
        +	return non zero if you should retry the call later (this 
        +	is for non-blocking IO).
        +-	BIO_should_read(BIO *io) - we should retry when data can 
        +	be read.
        +-	BIO_should_write(BIO *io) - we should retry when data can 
        +	be written.
        +-	BIO_method_name(BIO *io) - return a string for the method name.
        +-	BIO_method_type(BIO *io) - return the unique ID of the BIO method.
        +-	BIO_set_callback(BIO *io,  long (*callback)(BIO *io, int 
        +	cmd, char *argp, int argi, long argl, long ret); - sets 
        +	the debug callback.
        +-	BIO_get_callback(BIO *io) - return the assigned function 
        +	as mentioned above.
        +-	BIO_set_callback_arg(BIO *io, char *arg)  - assign some 
        +	data against the BIO.  This is normally used by the debug 
        +	callback but could in reality be used for anything.  To 
        +	get an idea of how all this works, have a look at the code 
        +	in the default debug callback mentioned above.  The 
        +	callback can modify the return values.
        +
        +Details of the BIO_METHOD structure.
        +typedef struct bio_method_st
        +        {
        +	int type;
        +	char *name;
        +	int (*bwrite)();
        +	int (*bread)();
        +	int (*bputs)();
        +	int (*bgets)();
        +	long (*ctrl)();
        +	int (*create)();
        +	int (*destroy)();
        +	} BIO_METHOD;
        +
        +The 'type' is the numeric type of the BIO, these are listed in buffer.h;
        +'Name' is a textual representation of the BIO 'type'.
        +The 7 function pointers point to the respective function 
        +methods, some of which can be NULL if not implemented.
        +The BIO structure
        +typedef struct bio_st
        +	{
        +	BIO_METHOD *method;
        +	long (*callback)(BIO * bio, int mode, char *argp, int 
        +		argi, long argl, long ret);
        +	char *cb_arg; /* first argument for the callback */
        +	int init;
        +	int shutdown;
        +	int flags;      /* extra storage */
        +	int num;
        +	char *ptr;
        +	struct bio_st *next_bio; /* used by filter BIOs */
        +	int references;
        +	unsigned long num_read;
        +	unsigned long num_write;
        +	} BIO;
        +
        +-	'Method' is the BIO method.
        +-	'callback', when configured, is called before and after 
        +	each BIO method is called for that particular BIO.  This 
        +	is intended primarily for debugging and of informational feedback.
        +-	'init' is 0 when the BIO can be used for operation.  
        +	Often, after a BIO is created, a number of operations may 
        +	need to be performed before it is available for use.  An 
        +	example is for BIO_s_sock().  A socket needs to be 
        +	assigned to the BIO before it can be used.
        +-	'shutdown', this flag indicates if the underlying 
        +	communication primitive being used should be closed/freed 
        +	when the BIO is closed.
        +-	'flags' is used to hold extra state.  It is primarily used 
        +	to hold information about why a non-blocking operation 
        +	failed and to record startup protocol information for the 
        +	SSL BIO.
        +-	'num' and 'ptr' are used to hold instance specific state 
        +	like file descriptors or local data structures.
        +-	'next_bio' is used by filter BIOs to hold the pointer of the
        +	next BIO in the chain. written data is sent to this BIO and
        +	data read is taken from it.
        +-	'references' is used to indicate the number of pointers to 
        +	this structure.  This needs to be '1' before a call to 
        +	BIO_free() is made if the BIO_free() function is to 
        +	actually free() the structure, otherwise the reference 
        +	count is just decreased.  The actual BIO subsystem does 
        +	not really use this functionality but it is useful when 
        +	used in more advanced applicaion.
        +-	num_read and num_write are the total number of bytes 
        +	read/written via the 'read()' and 'write()' methods.
        +
        +BIO_ctrl operations.
        +The following is the list of standard commands passed as the 
        +second parameter to BIO_ctrl() and should be supported by 
        +all BIO as best as possible.  Some are optional, some are 
        +manditory, in any case, where is makes sense, a filter BIO 
        +should pass such requests to underlying BIO's.
        +-	BIO_CTRL_RESET	- Reset the BIO back to an initial state.
        +-	BIO_CTRL_EOF	- return 0 if we are not at the end of input, 
        +	non 0 if we are.
        +-	BIO_CTRL_INFO	- BIO specific special command, normal
        +	information return.
        +-	BIO_CTRL_SET	- set IO specific parameter.
        +-	BIO_CTRL_GET	- get IO specific parameter.
        +-	BIO_CTRL_GET_CLOSE - Get the close on BIO_free() flag, one 
        +	of BIO_CLOSE or BIO_NOCLOSE.
        +-	BIO_CTRL_SET_CLOSE - Set the close on BIO_free() flag.
        +-	BIO_CTRL_PENDING - Return the number of bytes available 
        +	for instant reading
        +-	BIO_CTRL_FLUSH	- Output pending data, return number of bytes output.
        +-	BIO_CTRL_SHOULD_RETRY - After an IO error (-1 returned) 
        +	should we 'retry' when IO is possible on the underlying IO object.
        +-	BIO_CTRL_RETRY_TYPE - What kind of IO are we waiting on.
        +
        +The following command is a special BIO_s_file() specific option.
        +-	BIO_CTRL_SET_FILENAME - specify a file to open for IO.
        +
        +The BIO_CTRL_RETRY_TYPE needs a little more explanation.  
        +When performing non-blocking IO, or say reading on a memory 
        +BIO, when no data is present (or cannot be written), 
        +BIO_read() and/or BIO_write() will return -1.  
        +BIO_should_retry(bio) will return true if this is due to an 
        +IO condition rather than an actual error.  In the case of 
        +BIO_s_mem(), a read when there is no data will return -1 and 
        +a should retry when there is more 'read' data.
        +The retry type is deduced from 2 macros
        +BIO_should_read(bio) and BIO_should_write(bio).
        +Now while it may appear obvious that a BIO_read() failure 
        +should indicate that a retry should be performed when more 
        +read data is available, this is often not true when using 
        +things like an SSL BIO.  During the SSL protocol startup 
        +multiple reads and writes are performed, triggered by any 
        +SSL_read or SSL_write.
        +So to write code that will transparently handle either a 
        +socket or SSL BIO,
        +	i=BIO_read(bio,..)
        +	if (I == -1)
        +		{
        +		if (BIO_should_retry(bio))
        +			{
        +			if (BIO_should_read(bio))
        +				{
        +				/* call us again when BIO can be read */
        +				}
        +			if (BIO_should_write(bio))
        +				{
        +				/* call us again when BIO can be written */
        +				}
        +			}
        +		}
        +
        +At this point in time only read and write conditions can be 
        +used but in the future I can see the situation for other 
        +conditions, specifically with SSL there could be a condition 
        +of a X509 certificate lookup taking place and so the non-
        +blocking BIO_read would require a retry when the certificate 
        +lookup subsystem has finished it's lookup.  This is all 
        +makes more sense and is easy to use in a event loop type 
        +setup.
        +When using the SSL BIO, either SSL_read() or SSL_write()s 
        +can be called during the protocol startup and things will 
        +still work correctly.
        +The nice aspect of the use of the BIO_should_retry() macro 
        +is that all the errno codes that indicate a non-fatal error 
        +are encapsulated in one place.  The Windows specific error 
        +codes and WSAGetLastError() calls are also hidden from the 
        +application.
        +
        +Notes on each BIO method.
        +Normally buffer.h is just required but depending on the 
        +BIO_METHOD, ssl.h or evp.h will also be required.
        +
        +BIO_METHOD *BIO_s_mem(void);
        +-	BIO_set_mem_buf(BIO *bio, BUF_MEM *bm, int close_flag) - 
        +	set the underlying BUF_MEM structure for the BIO to use.
        +-	BIO_get_mem_ptr(BIO *bio, char **pp) - if pp is not NULL, 
        +	set it to point to the memory array and return the number 
        +	of bytes available.
        +A read/write BIO.  Any data written is appended to the 
        +memory array and any read is read from the front.  This BIO 
        +can be used for read/write at the same time. BIO_gets() is 
        +supported in the fgets() sense.
        +BIO_CTRL_INFO can be used to retrieve pointers to the memory 
        +buffer and it's length.
        +
        +BIO_METHOD *BIO_s_file(void);
        +-	BIO_set_fp(BIO *bio, FILE *fp, int close_flag) - set 'FILE *' to use.
        +-	BIO_get_fp(BIO *bio, FILE **fp) - get the 'FILE *' in use.
        +-	BIO_read_filename(BIO *bio, char *name) - read from file.
        +-	BIO_write_filename(BIO *bio, char *name) - write to file.
        +-	BIO_append_filename(BIO *bio, char *name) - append to file.
        +This BIO sits over the normal system fread()/fgets() type 
        +functions. Gets() is supported.  This BIO in theory could be 
        +used for read and write but it is best to think of each BIO 
        +of this type as either a read or a write BIO, not both.
        +
        +BIO_METHOD *BIO_s_socket(void);
        +BIO_METHOD *BIO_s_fd(void);
        +-	BIO_sock_should_retry(int i) - the underlying function 
        +	used to determine if a call should be retried; the 
        +	argument is the '0' or '-1' returned by the previous BIO 
        +	operation.
        +-	BIO_fd_should_retry(int i) - same as the 
        +-	BIO_sock_should_retry() except that it is different internally.
        +-	BIO_set_fd(BIO *bio, int fd, int close_flag) - set the 
        +	file descriptor to use
        +-	BIO_get_fd(BIO *bio, int *fd) - get the file descriptor.
        +These two methods are very similar.  Gets() is not 
        +supported, if you want this functionality, put a 
        +BIO_f_buffer() onto it.  This BIO is bi-directional if the 
        +underlying file descriptor is.  This is normally the case 
        +for sockets but not the case for stdio descriptors.
        +
        +BIO_METHOD *BIO_s_null(void);
        +Read and write as much data as you like, it all disappears 
        +into this BIO.
        +
        +BIO_METHOD *BIO_f_buffer(void);
        +-	BIO_get_buffer_num_lines(BIO *bio) - return the number of 
        +	complete lines in the buffer.
        +-	BIO_set_buffer_size(BIO *bio, long size) - set the size of 
        +	the buffers.
        +This type performs input and output buffering.  It performs 
        +both at the same time.  The size of the buffer can be set 
        +via the set buffer size option.  Data buffered for output is 
        +only written when the buffer fills.
        +
        +BIO_METHOD *BIO_f_ssl(void);
        +-	BIO_set_ssl(BIO *bio, SSL *ssl, int close_flag) - the SSL 
        +	structure to use.
        +-	BIO_get_ssl(BIO *bio, SSL **ssl) - get the SSL structure 
        +	in use.
        +The SSL bio is a little different from normal BIOs because 
        +the underlying SSL structure is a little different.  A SSL 
        +structure performs IO via a read and write BIO.  These can 
        +be different and are normally set via the
        +SSL_set_rbio()/SSL_set_wbio() calls.  The SSL_set_fd() calls 
        +are just wrappers that create socket BIOs and then call 
        +SSL_set_bio() where the read and write BIOs are the same.  
        +The BIO_push() operation makes the SSLs IO BIOs the same, so 
        +make sure the BIO pushed is capable of two directional 
        +traffic.  If it is not, you will have to install the BIOs 
        +via the more conventional SSL_set_bio() call.  BIO_pop() will retrieve
        +the 'SSL read' BIO.
        +
        +BIO_METHOD *BIO_f_md(void);
        +-	BIO_set_md(BIO *bio, EVP_MD *md) - set the message digest 
        +	to use.
        +-	BIO_get_md(BIO *bio, EVP_MD **mdp) - return the digest 
        +	method in use in mdp, return 0 if not set yet.
        +-	BIO_reset() reinitializes the digest (EVP_DigestInit()) 
        +	and passes the reset to the underlying BIOs.
        +All data read or written via BIO_read() or BIO_write() to 
        +this BIO will be added to the calculated digest.  This 
        +implies that this BIO is only one directional.  If read and 
        +write operations are performed, two separate BIO_f_md() BIOs 
        +are reuqired to generate digests on both the input and the 
        +output.  BIO_gets(BIO *bio, char *md, int size) will place the 
        +generated digest into 'md' and return the number of bytes.  
        +The EVP_MAX_MD_SIZE should probably be used to size the 'md' 
        +array.  Reading the digest will also reset it.
        +
        +BIO_METHOD *BIO_f_cipher(void);
        +-	BIO_reset() reinitializes the cipher.
        +-	BIO_flush() should be called when the last bytes have been 
        +	output to flush the final block of block ciphers.
        +-	BIO_get_cipher_status(BIO *b), when called after the last 
        +	read from a cipher BIO, returns non-zero if the data 
        +	decrypted correctly, otherwise, 0.
        +-	BIO_set_cipher(BIO *b, EVP_CIPHER *c, unsigned char *key, 
        +	unsigned char *iv, int encrypt)   This function is used to 
        +	setup a cipher BIO.  The length of key and iv are 
        +	specified by the choice of EVP_CIPHER.  Encrypt is 1 to 
        +	encrypt and 0 to decrypt.
        +
        +BIO_METHOD *BIO_f_base64(void);
        +-	BIO_flush() should be called when the last bytes have been output.
        +This BIO base64 encodes when writing and base64 decodes when 
        +reading.  It will scan the input until a suitable begin line 
        +is found.  After reading data, BIO_reset() will reset the 
        +BIO to start scanning again.  Do not mix reading and writing 
        +on the same base64 BIO.  It is meant as a single stream BIO.
        +
        +Directions	type
        +both		BIO_s_mem()
        +one/both	BIO_s_file()
        +both		BIO_s_fd()
        +both		BIO_s_socket() 
        +both		BIO_s_null()
        +both		BIO_f_buffer()
        +one		BIO_f_md()  
        +one		BIO_f_cipher()  
        +one		BIO_f_base64()  
        +both		BIO_f_ssl()
        +
        +It is easy to mix one and two directional BIOs, all one has 
        +to do is to keep two separate BIO pointers for reading and 
        +writing and be careful about usage of underlying BIOs.  The 
        +SSL bio by it's very nature has to be two directional but 
        +the BIO_push() command will push the one BIO into the SSL 
        +BIO for both reading and writing.
        +
        +The best example program to look at is apps/enc.c and/or perhaps apps/dgst.c.
        +
        +
        +==== blowfish.doc ========================================================
        +
        +The Blowfish library.
        +
        +Blowfish is a block cipher that operates on 64bit (8 byte) quantities.  It
        +uses variable size key, but 128bit (16 byte) key would normally be considered
        +good.  It can be used in all the modes that DES can be used.  This
        +library implements the ecb, cbc, cfb64, ofb64 modes.
        +
        +Blowfish is quite a bit faster that DES, and much faster than IDEA or
        +RC2.  It is one of the faster block ciphers.
        +
        +For all calls that have an 'input' and 'output' variables, they can be the
        +same.
        +
        +This library requires the inclusion of 'blowfish.h'.
        +
        +All of the encryption functions take what is called an BF_KEY as an 
        +argument.  An BF_KEY is an expanded form of the Blowfish key.
        +For all modes of the Blowfish algorithm, the BF_KEY used for
        +decryption is the same one that was used for encryption.
        +
        +The define BF_ENCRYPT is passed to specify encryption for the functions
        +that require an encryption/decryption flag. BF_DECRYPT is passed to
        +specify decryption.
        +
        +Please note that any of the encryption modes specified in my DES library
        +could be used with Blowfish.  I have only implemented ecb, cbc, cfb64 and
        +ofb64 for the following reasons.
        +- ecb is the basic Blowfish encryption.
        +- cbc is the normal 'chaining' form for block ciphers.
        +- cfb64 can be used to encrypt single characters, therefore input and output
        +  do not need to be a multiple of 8.
        +- ofb64 is similar to cfb64 but is more like a stream cipher, not as
        +  secure (not cipher feedback) but it does not have an encrypt/decrypt mode.
        +- If you want triple Blowfish, thats 384 bits of key and you must be totally
        +  obsessed with security.  Still, if you want it, it is simple enough to
        +  copy the function from the DES library and change the des_encrypt to
        +  BF_encrypt; an exercise left for the paranoid reader :-).
        +
        +The functions are as follows:
        +
        +void BF_set_key(
        +BF_KEY *ks;
        +int len;
        +unsigned char *key;
        +        BF_set_key converts an 'len' byte key into a BF_KEY.
        +        A 'ks' is an expanded form of the 'key' which is used to
        +        perform actual encryption.  It can be regenerated from the Blowfish key
        +        so it only needs to be kept when encryption or decryption is about
        +        to occur.  Don't save or pass around BF_KEY's since they
        +        are CPU architecture dependent, 'key's are not.  Blowfish is an
        +	interesting cipher in that it can be used with a variable length
        +	key.  'len' is the length of 'key' to be used as the key.
        +	A 'len' of 16 is recomended by me, but blowfish can use upto
        +	72 bytes.  As a warning, blowfish has a very very slow set_key
        +	function, it actually runs BF_encrypt 521 times.
        +	
        +void BF_encrypt(unsigned long *data, BF_KEY *key);
        +void BF_decrypt(unsigned long *data, BF_KEY *key);
        +	These are the Blowfish encryption function that gets called by just
        +	about every other Blowfish routine in the library.  You should not
        +	use this function except to implement 'modes' of Blowfish.
        +	I say this because the
        +	functions that call this routine do the conversion from 'char *' to
        +	long, and this needs to be done to make sure 'non-aligned' memory
        +	access do not occur.
        +	Data is a pointer to 2 unsigned long's and key is the
        +	BF_KEY to use. 
        +
        +void BF_ecb_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +BF_KEY *key,
        +int encrypt);
        +	This is the basic Electronic Code Book form of Blowfish (in DES this
        +	mode is called Electronic Code Book so I'm going to use the term
        +	for blowfish as well.
        +	Input is encrypted into output using the key represented by
        +	key.  Depending on the encrypt, encryption or
        +	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
        +	
        +void BF_cbc_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +BF_KEY *ks,
        +unsigned char *ivec,
        +int encrypt);
        +	This routine implements Blowfish in Cipher Block Chaining mode.
        +	Input, which should be a multiple of 8 bytes is encrypted
        +	(or decrypted) to output which will also be a multiple of 8 bytes.
        +	The number of bytes is in length (and from what I've said above,
        +	should be a multiple of 8).  If length is not a multiple of 8, bad 
        +	things will probably happen.  ivec is the initialisation vector.
        +	This function updates iv after each call so that it can be passed to
        +	the next call to BF_cbc_encrypt().
        +	
        +void BF_cfb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +BF_KEY *schedule,
        +unsigned char *ivec,
        +int *num,
        +int encrypt);
        +	This is one of the more useful functions in this Blowfish library, it
        +	implements CFB mode of Blowfish with 64bit feedback.
        +	This allows you to encrypt an arbitrary number of bytes,
        +	you do not require 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  Num contains 'how far' we are though ivec.
        +	'Encrypt' is used to indicate encryption or decryption.
        +	CFB64 mode operates by using the cipher to generate a stream
        +	of bytes which is used to encrypt the plain text.
        +	The cipher text is then encrypted to generate the next 64 bits to
        +	be xored (incrementally) with the next 64 bits of plain
        +	text.  As can be seen from this, to encrypt or decrypt,
        +	the same 'cipher stream' needs to be generated but the way the next
        +	block of data is gathered for encryption is different for
        +	encryption and decryption.
        +	
        +void BF_ofb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +BF_KEY *schedule,
        +unsigned char *ivec,
        +int *num);
        +	This functions implements OFB mode of Blowfish with 64bit feedback.
        +	This allows you to encrypt an arbitrary number of bytes,
        +	you do not require 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  Num contains 'how far' we are though ivec.
        +	This is in effect a stream cipher, there is no encryption or
        +	decryption mode.
        +	
        +For reading passwords, I suggest using des_read_pw_string() from my DES library.
        +To generate a password from a text string, I suggest using MD5 (or MD2) to
        +produce a 16 byte message digest that can then be passed directly to
        +BF_set_key().
        +
        +=====
        +For more information about the specific Blowfish modes in this library
        +(ecb, cbc, cfb and ofb), read the section entitled 'Modes of DES' from the
        +documentation on my DES library.  What is said about DES is directly
        +applicable for Blowfish.
        +
        +
        +==== bn.doc ========================================================
        +
        +The Big Number library.
        +
        +#include "bn.h" when using this library.
        +
        +This big number library was written for use in implementing the RSA and DH
        +public key encryption algorithms.  As such, features such as negative
        +numbers have not been extensively tested but they should work as expected.
        +This library uses dynamic memory allocation for storing its data structures
        +and so there are no limit on the size of the numbers manipulated by these
        +routines but there is always the requirement to check return codes from
        +functions just in case a memory allocation error has occurred.
        +
        +The basic object in this library is a BIGNUM.  It is used to hold a single
        +large integer.  This type should be considered opaque and fields should not
        +be modified or accessed directly.
        +typedef struct bignum_st
        +	{
        +	int top;	/* Index of last used d. */
        +	BN_ULONG *d;	/* Pointer to an array of 'BITS2' bit chunks. */
        +	int max;	/* Size of the d array. */
        +	int neg;
        +	} BIGNUM;
        +The big number is stored in a malloced array of BN_ULONG's.  A BN_ULONG can
        +be either 16, 32 or 64 bits in size, depending on the 'number of  bits'
        +specified in bn.h. 
        +The 'd' field is this array.  'max' is the size of the 'd' array that has
        +been allocated.  'top' is the 'last' entry being used, so for a value of 4,
        +bn.d[0]=4 and bn.top=1.  'neg' is 1 if the number is negative.
        +When a BIGNUM is '0', the 'd' field can be NULL and top == 0.
        +
        +Various routines in this library require the use of 'temporary' BIGNUM
        +variables during their execution.  Due to the use of dynamic memory
        +allocation to create BIGNUMs being rather expensive when used in
        +conjunction with repeated subroutine calls, the BN_CTX structure is
        +used.  This structure contains BN_CTX BIGNUMs.  BN_CTX
        +is the maximum number of temporary BIGNUMs any publicly exported 
        +function will use.
        +
        +#define BN_CTX	12
        +typedef struct bignum_ctx
        +	{
        +	int tos;			/* top of stack */
        +	BIGNUM *bn[BN_CTX];	/* The variables */
        +	} BN_CTX;
        +
        +The functions that follow have been grouped according to function.  Most
        +arithmetic functions return a result in the first argument, sometimes this
        +first argument can also be an input parameter, sometimes it cannot.  These
        +restrictions are documented.
        +
        +extern BIGNUM *BN_value_one;
        +There is one variable defined by this library, a BIGNUM which contains the
        +number 1.  This variable is useful for use in comparisons and assignment.
        +
        +Get Size functions.
        +
        +int BN_num_bits(BIGNUM *a);
        +	This function returns the size of 'a' in bits.
        +	
        +int BN_num_bytes(BIGNUM *a);
        +	This function (macro) returns the size of 'a' in bytes.
        +	For conversion of BIGNUMs to byte streams, this is the number of
        +	bytes the output string will occupy.  If the output byte
        +	format specifies that the 'top' bit indicates if the number is
        +	signed, so an extra '0' byte is required if the top bit on a
        +	positive number is being written, it is upto the application to
        +	make this adjustment.  Like I said at the start, I don't
        +	really support negative numbers :-).
        +
        +Creation/Destruction routines.
        +
        +BIGNUM *BN_new();
        +	Return a new BIGNUM object.  The number initially has a value of 0.  If
        +	there is an error, NULL is returned.
        +	
        +void	BN_free(BIGNUM *a);
        +	Free()s a BIGNUM.
        +	
        +void	BN_clear(BIGNUM *a);
        +	Sets 'a' to a value of 0 and also zeros all unused allocated
        +	memory.  This function is used to clear a variable of 'sensitive'
        +	data that was held in it.
        +	
        +void	BN_clear_free(BIGNUM *a);
        +	This function zeros the memory used by 'a' and then free()'s it.
        +	This function should be used to BN_free() BIGNUMS that have held
        +	sensitive numeric values like RSA private key values.  Both this
        +	function and BN_clear tend to only be used by RSA and DH routines.
        +
        +BN_CTX *BN_CTX_new(void);
        +	Returns a new BN_CTX.  NULL on error.
        +	
        +void	BN_CTX_free(BN_CTX *c);
        +	Free a BN_CTX structure.  The BIGNUMs in 'c' are BN_clear_free()ed.
        +	
        +BIGNUM *bn_expand(BIGNUM *b, int bits);
        +	This is an internal function that should not normally be used.  It
        +	ensures that 'b' has enough room for a 'bits' bit number.  It is
        +	mostly used by the various BIGNUM routines.  If there is an error,
        +	NULL is returned. if not, 'b' is returned.
        +	
        +BIGNUM *BN_copy(BIGNUM *to, BIGNUM *from);
        +	The 'from' is copied into 'to'.  NULL is returned if there is an
        +	error, otherwise 'to' is returned.
        +
        +BIGNUM *BN_dup(BIGNUM *a);
        +	A new BIGNUM is created and returned containing the value of 'a'.
        +	NULL is returned on error.
        +
        +Comparison and Test Functions.
        +
        +int BN_is_zero(BIGNUM *a)
        +	Return 1 if 'a' is zero, else 0.
        +
        +int BN_is_one(a)
        +	Return 1 is 'a' is one, else 0.
        +
        +int BN_is_word(a,w)
        +	Return 1 if 'a' == w, else 0.  'w' is a BN_ULONG.
        +
        +int BN_cmp(BIGNUM *a, BIGNUM *b);
        +	Return -1 if 'a' is less than 'b', 0 if 'a' and 'b' are the same
        +	and 1 is 'a' is greater than 'b'.  This is a signed comparison.
        +	
        +int BN_ucmp(BIGNUM *a, BIGNUM *b);
        +	This function is the same as BN_cmp except that the comparison
        +	ignores the sign of the numbers.
        +	
        +Arithmetic Functions
        +For all of these functions, 0 is returned if there is an error and 1 is
        +returned for success.  The return value should always be checked.  eg.
        +if (!BN_add(r,a,b)) goto err;
        +Unless explicitly mentioned, the 'return' value can be one of the
        +'parameters' to the function.
        +
        +int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
        +	Add 'a' and 'b' and return the result in 'r'.  This is r=a+b.
        +	
        +int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b);
        +	Subtract 'a' from 'b' and put the result in 'r'. This is r=a-b.
        +	
        +int BN_lshift(BIGNUM *r, BIGNUM *a, int n);
        +	Shift 'a' left by 'n' bits.  This is r=a*(2^n).
        +	
        +int BN_lshift1(BIGNUM *r, BIGNUM *a);
        +	Shift 'a' left by 1 bit.  This form is more efficient than
        +	BN_lshift(r,a,1).  This is r=a*2.
        +	
        +int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
        +	Shift 'a' right by 'n' bits.  This is r=int(a/(2^n)).
        +	
        +int BN_rshift1(BIGNUM *r, BIGNUM *a);
        +	Shift 'a' right by 1 bit.  This form is more efficient than
        +	BN_rshift(r,a,1).  This is r=int(a/2).
        +	
        +int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b);
        +	Multiply a by b and return the result in 'r'. 'r' must not be
        +	either 'a' or 'b'.  It has to be a different BIGNUM.
        +	This is r=a*b.
        +
        +int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
        +	Multiply a by a and return the result in 'r'. 'r' must not be
        +	'a'.  This function is alot faster than BN_mul(r,a,a).  This is r=a*a.
        +
        +int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
        +	Divide 'm' by 'd' and return the result in 'dv' and the remainder
        +	in 'rem'.  Either of 'dv' or 'rem' can be NULL in which case that
        +	value is not returned.  'ctx' needs to be passed as a source of
        +	temporary BIGNUM variables.
        +	This is dv=int(m/d), rem=m%d.
        +	
        +int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
        +	Find the remainder of 'm' divided by 'd' and return it in 'rem'.
        +	'ctx' holds the temporary BIGNUMs required by this function.
        +	This function is more efficient than BN_div(NULL,rem,m,d,ctx);
        +	This is rem=m%d.
        +
        +int BN_mod_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *m,BN_CTX *ctx);
        +	Multiply 'a' by 'b' and return the remainder when divided by 'm'.
        +	'ctx' holds the temporary BIGNUMs required by this function.
        +	This is r=(a*b)%m.
        +
        +int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx);
        +	Raise 'a' to the 'p' power and return the remainder when divided by
        +	'm'.  'ctx' holds the temporary BIGNUMs required by this function.
        +	This is r=(a^p)%m.
        +
        +int BN_reciprocal(BIGNUM *r, BIGNUM *m, BN_CTX *ctx);
        +	Return the reciprocal of 'm'.  'ctx' holds the temporary variables
        +	required.  This function returns -1 on error, otherwise it returns
        +	the number of bits 'r' is shifted left to make 'r' into an integer.
        +	This number of bits shifted is required in BN_mod_mul_reciprocal().
        +	This is r=(1/m)<<(BN_num_bits(m)+1).
        +	
        +int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BIGNUM *m, 
        +	BIGNUM *i, int nb, BN_CTX *ctx);
        +	This function is used to perform an efficient BN_mod_mul()
        +	operation.  If one is going to repeatedly perform BN_mod_mul() with
        +	the same modulus is worth calculating the reciprocal of the modulus
        +	and then using this function.  This operation uses the fact that
        +	a/b == a*r where r is the reciprocal of b.  On modern computers
        +	multiplication is very fast and big number division is very slow.
        +	'x' is multiplied by 'y' and then divided by 'm' and the remainder
        +	is returned.  'i' is the reciprocal of 'm' and 'nb' is the number
        +	of bits as returned from BN_reciprocal().  Normal usage is as follows.
        +	bn=BN_reciprocal(i,m);
        +	for (...)
        +		{ BN_mod_mul_reciprocal(r,x,y,m,i,bn,ctx); }
        +	This is r=(x*y)%m.  Internally it is approximately
        +	r=(x*y)-m*(x*y/m) or r=(x*y)-m*((x*y*i) >> bn)
        +	This function is used in BN_mod_exp() and BN_is_prime().
        +
        +Assignment Operations
        +
        +int BN_one(BIGNUM *a)
        +	Set 'a' to hold the value one.
        +	This is a=1.
        +	
        +int BN_zero(BIGNUM *a)
        +	Set 'a' to hold the value zero.
        +	This is a=0.
        +	
        +int BN_set_word(BIGNUM *a, unsigned long w);
        +	Set 'a' to hold the value of 'w'.  'w' is an unsigned long.
        +	This is a=w.
        +
        +unsigned long BN_get_word(BIGNUM *a);
        +	Returns 'a' in an unsigned long.  Not remarkably, often 'a' will
        +	be bigger than a word, in which case 0xffffffffL is returned.
        +
        +Word Operations
        +These functions are much more efficient that the normal bignum arithmetic
        +operations.
        +
        +BN_ULONG BN_mod_word(BIGNUM *a, unsigned long w);
        +	Return the remainder of 'a' divided by 'w'.
        +	This is return(a%w).
        +	
        +int BN_add_word(BIGNUM *a, unsigned long w);
        +	Add 'w' to 'a'.  This function does not take the sign of 'a' into
        +	account.  This is a+=w;
        +	
        +Bit operations.
        +
        +int BN_is_bit_set(BIGNUM *a, int n);
        +	This function return 1 if bit 'n' is set in 'a' else 0.
        +
        +int BN_set_bit(BIGNUM *a, int n);
        +	This function sets bit 'n' to 1 in 'a'. 
        +	This is a&= ~(1<<n);
        +
        +int BN_clear_bit(BIGNUM *a, int n);
        +	This function sets bit 'n' to zero in 'a'.  Return 0 if less
        +	than 'n' bits in 'a' else 1.  This is a&= ~(1<<n);
        +
        +int BN_mask_bits(BIGNUM *a, int n);
        +	Truncate 'a' to n bits long.  This is a&= ~((~0)<<n)
        +
        +Format conversion routines.
        +
        +BIGNUM *BN_bin2bn(unsigned char *s, int len,BIGNUM *ret);
        +	This function converts 'len' bytes in 's' into a BIGNUM which
        +	is put in 'ret'.  If ret is NULL, a new BIGNUM is created.
        +	Either this new BIGNUM or ret is returned.  The number is
        +	assumed to be in bigendian form in 's'.  By this I mean that
        +	to 'ret' is created as follows for 'len' == 5.
        +	ret = s[0]*2^32 + s[1]*2^24 + s[2]*2^16 + s[3]*2^8 + s[4];
        +	This function cannot be used to convert negative numbers.  It
        +	is always assumed the number is positive.  The application
        +	needs to diddle the 'neg' field of th BIGNUM its self.
        +	The better solution would be to save the numbers in ASN.1 format
        +	since this is a defined standard for storing big numbers.
        +	Look at the functions
        +
        +	ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
        +	BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
        +	int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
        +	ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp,
        +		long length;
        +
        +int BN_bn2bin(BIGNUM *a, unsigned char *to);
        +	This function converts 'a' to a byte string which is put into
        +	'to'.  The representation is big-endian in that the most
        +	significant byte of 'a' is put into to[0].  This function
        +	returns the number of bytes used to hold 'a'.  BN_num_bytes(a)
        +	would return the same value and can be used to determine how
        +	large 'to' needs to be.  If the number is negative, this
        +	information is lost.  Since this library was written to
        +	manipulate large positive integers, the inability to save and
        +	restore them is not considered to be a problem by me :-).
        +	As for BN_bin2bn(), look at the ASN.1 integer encoding funtions
        +	for SSLeay.  They use BN_bin2bn() and BN_bn2bin() internally.
        +	
        +char *BN_bn2ascii(BIGNUM *a);
        +	This function returns a malloc()ed string that contains the
        +	ascii hexadecimal encoding of 'a'.  The number is in bigendian
        +	format with a '-' in front if the number is negative.
        +
        +int BN_ascii2bn(BIGNUM **bn, char *a);
        +	The inverse of BN_bn2ascii.  The function returns the number of
        +	characters from 'a' were processed in generating a the bignum.
        +	error is inticated by 0 being returned.  The number is a
        +	hex digit string, optionally with a leading '-'.  If *bn
        +	is null, a BIGNUM is created and returned via that variable.
        +	
        +int BN_print_fp(FILE *fp, BIGNUM *a);
        +	'a' is printed to file pointer 'fp'.  It is in the same format
        +	that is output from BN_bn2ascii().  0 is returned on error,
        +	1 if things are ok.
        +
        +int BN_print(BIO *bp, BIGNUM *a);
        +	Same as BN_print except that the output is done to the SSLeay libraries
        +	BIO routines.  BN_print_fp() actually calls this function.
        +
        +Miscellaneous Routines.
        +
        +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
        +	This function returns in 'rnd' a random BIGNUM that is bits
        +	long.  If bottom is 1, the number returned is odd.  If top is set,
        +	the top 2 bits of the number are set.  This is useful because if
        +	this is set, 2 'n; bit numbers multiplied together will return a 2n
        +	bit number.  If top was not set, they could produce a 2n-1 bit
        +	number.
        +
        +BIGNUM *BN_mod_inverse(BIGNUM *a, BIGNUM *n,BN_CTX *ctx);
        +	This function create a new BIGNUM and returns it.  This number
        +	is the inverse mod 'n' of 'a'.  By this it is meant that the
        +	returned value 'r' satisfies (a*r)%n == 1.  This function is
        +	used in the generation of RSA keys.  'ctx', as per usual,
        +	is used to hold temporary variables that are required by the
        +	function.  NULL is returned on error.
        +
        +int BN_gcd(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx);
        +	'r' has the greatest common divisor of 'a' and 'b'.  'ctx' is
        +	used for temporary variables and 0 is returned on error.
        +
        +int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(),BN_CTX *ctx,
        +	char *cb_arg);
        +	This function is used to check if a BIGNUM ('p') is prime.
        +	It performs this test by using the Miller-Rabin randomised
        +	primality test.  This is a probalistic test that requires a
        +	number of rounds to ensure the number is prime to a high
        +	degree of probability.  Since this can take quite some time, a
        +	callback function can be passed and it will be called each
        +	time 'p' passes a round of the prime testing.  'callback' will
        +	be called as follows, callback(1,n,cb_arg) where n is the number of
        +	the round, just passed.  As per usual 'ctx' contains temporary
        +	variables used.  If ctx is NULL, it does not matter, a local version
        +	will be malloced.  This parameter is present to save some mallocing
        +	inside the function but probably could be removed.
        +	0 is returned on error.
        +	'ncheck' is the number of Miller-Rabin tests to run.  It is
        +	suggested to use the value 'BN_prime_checks' by default.
        +
        +BIGNUM *BN_generate_prime(
        +int bits,
        +int strong,
        +BIGNUM *a,
        +BIGNUM *rems,
        +void (*callback)());
        +char *cb_arg
        +	This function is used to generate prime numbers.  It returns a
        +	new BIGNUM that has a high probability of being a prime.
        +	'bits' is the number of bits that
        +	are to be in the prime.  If 'strong' is true, the returned prime
        +	will also be a strong prime ((p-1)/2 is also prime).
        +	While searching for the prime ('p'), we
        +	can add the requirement that the prime fill the following
        +	condition p%a == rem.  This can be used to help search for
        +	primes with specific features, which is required when looking
        +	for primes suitable for use with certain 'g' values in the
        +	Diffie-Hellman key exchange algorithm.  If 'a' is NULL,
        +	this condition is not checked.  If rem is NULL, rem is assumed
        +	to be 1.  Since this search for a prime
        +	can take quite some time, if callback is not NULL, it is called
        +	in the following situations.
        +	We have a suspected prime (from a quick sieve),
        +	callback(0,sus_prime++,cb_arg). Each item to be passed to BN_is_prime().
        +	callback(1,round++,cb_arg).  Each successful 'round' in BN_is_prime().
        +	callback(2,round,cb_arg). For each successful BN_is_prime() test.
        +
        +Hints
        +-----
        +
        +DSA wants 64*32 to use word mont mul, but RSA wants to use full.
        +
        +==== callback.doc ========================================================
        +
        +Callback functions used in SSLeay.
        +
        +--------------------------
        +The BIO library.  
        +
        +Each BIO structure can have a callback defined against it.  This callback is
        +called 2 times for each BIO 'function'.  It is passed 6 parameters.
        +BIO_debug_callback() is an example callback which is defined in
        +crypto/buffer/bio_cb.c and is used in apps/dgst.c  This is intended mostly
        +for debuging or to notify the application of IO.
        +
        +long BIO_debug_callback(BIO *bio,int cmd,char *argp,int argi,long argl,
        +	long ret);
        +bio is the BIO being called, cmd is the type of BIO function being called.
        +Look at the BIO_CB_* defines in buffer.h.  Argp and argi are the arguments
        +passed to BIO_read(), BIO_write, BIO_gets(), BIO_puts().  In the case of
        +BIO_ctrl(), argl is also defined.  The first time the callback is called,
        +before the underlying function has been executed, 0 is passed as 'ret', and
        +if the return code from the callback is not > 0, the call is aborted
        +and the returned <= 0 value is returned.
        +The second time the callback is called, the 'cmd' value also has
        +BIO_CB_RETURN logically 'or'ed with it.  The 'ret' value is the value returned
        +from the actuall function call and whatever the callback returns is returned
        +from the BIO function.
        +
        +BIO_set_callback(b,cb) can be used to set the callback function
        +(b is a BIO), and BIO_set_callback_arg(b,arg) can be used to
        +set the cb_arg argument in the BIO strucutre.  This field is only intended
        +to be used by application, primarily in the callback function since it is
        +accessable since the BIO is passed.
        +
        +--------------------------
        +The PEM library.
        +
        +The pem library only really uses one type of callback,
        +static int def_callback(char *buf, int num, int verify);
        +which is used to return a password string if required.
        +'buf' is the buffer to put the string in.  'num' is the size of 'buf'
        +and 'verify' is used to indicate that the password should be checked.
        +This last flag is mostly used when reading a password for encryption.
        +
        +For all of these functions, a NULL callback will call the above mentioned
        +default callback.  This default function does not work under Windows 3.1.
        +For other machines, it will use an application defined prompt string
        +(EVP_set_pw_prompt(), which defines a library wide prompt string)
        +if defined, otherwise it will use it's own PEM password prompt.
        +It will then call EVP_read_pw_string() to get a password from the console.
        +If your application wishes to use nice fancy windows to retrieve passwords,
        +replace this function.  The callback should return the number of bytes read
        +into 'buf'.  If the number of bytes <= 0, it is considered an error.
        +
        +Functions that take this callback are listed below.  For the 'read' type
        +functions, the callback will only be required if the PEM data is encrypted.
        +
        +For the Write functions, normally a password can be passed in 'kstr', of
        +'klen' bytes which will be used if the 'enc' cipher is not NULL.  If
        +'kstr' is NULL, the callback will be used to retrieve a password.
        +
        +int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
        +	int (*callback)());
        +char *PEM_ASN1_read_bio(char *(*d2i)(),char *name,BIO *bp,char **x,int (*cb)());
        +char *PEM_ASN1_read(char *(*d2i)(),char *name,FILE *fp,char **x,int (*cb)());
        +int PEM_ASN1_write_bio(int (*i2d)(),char *name,BIO *bp,char *x,
        +	EVP_CIPHER *enc,unsigned char *kstr,int klen,int (*callback)());
        +int PEM_ASN1_write(int (*i2d)(),char *name,FILE *fp,char *x,
        +	EVP_CIPHER *enc,unsigned char *kstr,int klen,int (*callback)());
        +STACK *PEM_X509_INFO_read(FILE *fp, STACK *sk, int (*cb)());
        +STACK *PEM_X509_INFO_read_bio(BIO *fp, STACK *sk, int (*cb)());
        +
        +#define	PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb)
        +#define	PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb)
        +#define	PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb)
        +#define	PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb)
        +#define	PEM_read_SSL_SESSION(fp,x,cb)
        +#define	PEM_read_X509(fp,x,cb)
        +#define	PEM_read_X509_REQ(fp,x,cb)
        +#define	PEM_read_X509_CRL(fp,x,cb)
        +#define	PEM_read_RSAPrivateKey(fp,x,cb)
        +#define	PEM_read_DSAPrivateKey(fp,x,cb)
        +#define	PEM_read_PrivateKey(fp,x,cb)
        +#define	PEM_read_PKCS7(fp,x,cb)
        +#define	PEM_read_DHparams(fp,x,cb)
        +#define	PEM_read_bio_SSL_SESSION(bp,x,cb)
        +#define	PEM_read_bio_X509(bp,x,cb)
        +#define	PEM_read_bio_X509_REQ(bp,x,cb)
        +#define	PEM_read_bio_X509_CRL(bp,x,cb)
        +#define	PEM_read_bio_RSAPrivateKey(bp,x,cb)
        +#define	PEM_read_bio_DSAPrivateKey(bp,x,cb)
        +#define	PEM_read_bio_PrivateKey(bp,x,cb)
        +#define	PEM_read_bio_PKCS7(bp,x,cb)
        +#define	PEM_read_bio_DHparams(bp,x,cb)
        +int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());
        +RSA *d2i_Netscape_RSA(RSA **a, unsigned char **pp, long length, int (*cb)());
        +
        +Now you will notice that macros like
        +#define PEM_write_X509(fp,x) \
        +                PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
        +		                        (char *)x, NULL,NULL,0,NULL)
        +Don't do encryption normally.  If you want to PEM encrypt your X509 structure,
        +either just call PEM_ASN1_write directly or just define your own
        +macro variant.  As you can see, this macro just sets all encryption related
        +parameters to NULL.
        +
        +
        +--------------------------
        +The SSL library.
        +
        +#define SSL_set_info_callback(ssl,cb)
        +#define SSL_CTX_set_info_callback(ctx,cb)
        +void callback(SSL *ssl,int location,int ret)
        +This callback is called each time around the SSL_connect()/SSL_accept() 
        +state machine.  So it will be called each time the SSL protocol progresses.
        +It is mostly present for use when debugging.  When SSL_connect() or
        +SSL_accept() return, the location flag is SSL_CB_ACCEPT_EXIT or
        +SSL_CB_CONNECT_EXIT and 'ret' is the value about to be returned.
        +Have a look at the SSL_CB_* defines in ssl.h.  If an info callback is defined
        +against the SSL_CTX, it is called unless there is one set against the SSL.
        +Have a look at
        +void client_info_callback() in apps/s_client() for an example.
        +
        +Certificate verification.
        +void SSL_set_verify(SSL *s, int mode, int (*callback) ());
        +void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*callback)());
        +This callback is used to help verify client and server X509 certificates.
        +It is actually passed to X509_cert_verify(), along with the SSL structure
        +so you have to read about X509_cert_verify() :-).  The SSL_CTX version is used
        +if the SSL version is not defined.  X509_cert_verify() is the function used
        +by the SSL part of the library to verify certificates.  This function is
        +nearly always defined by the application.
        +
        +void SSL_CTX_set_cert_verify_cb(SSL_CTX *ctx, int (*cb)(),char *arg);
        +int callback(char *arg,SSL *s,X509 *xs,STACK *cert_chain);
        +This call is used to replace the SSLeay certificate verification code.
        +The 'arg' is kept in the SSL_CTX and is passed to the callback.
        +If the callback returns 0, the certificate is rejected, otherwise it
        +is accepted.  The callback is replacing the X509_cert_verify() call.
        +This feature is not often used, but if you wished to implement
        +some totally different certificate authentication system, this 'hook' is
        +vital.
        +
        +SSLeay keeps a cache of session-ids against each SSL_CTX.  These callbacks can
        +be used to notify the application when a SSL_SESSION is added to the cache
        +or to retrieve a SSL_SESSION that is not in the cache from the application.
        +#define SSL_CTX_sess_set_get_cb(ctx,cb)
        +SSL_SESSION *callback(SSL *s,char *session_id,int session_id_len,int *copy);
        +If defined, this callback is called to return the SESSION_ID for the
        +session-id in 'session_id', of 'session_id_len' bytes.  'copy' is set to 1
        +if the server is to 'take a copy' of the SSL_SESSION structure.  It is 0
        +if the SSL_SESSION is being 'passed in' so the SSLeay library is now
        +responsible for 'free()ing' the structure.  Basically it is used to indicate
        +if the reference count on the SSL_SESSION structure needs to be incremented.
        +
        +#define SSL_CTX_sess_set_new_cb(ctx,cb)
        +int callback(SSL *s, SSL_SESSION *sess);
        +When a new connection is established, if the SSL_SESSION is going to be added
        +to the cache, this callback is called.  Return 1 if a 'copy' is required,
        +otherwise, return 0.  This return value just causes the reference count
        +to be incremented (on return of a 1), this means the application does
        +not need to worry about incrementing the refernece count (and the
        +locking that implies in a multi-threaded application).
        +
        +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,int (*cb)());
        +This sets the SSL password reading function.
        +It is mostly used for windowing applications
        +and used by PEM_read_bio_X509() and PEM_read_bio_RSAPrivateKey()
        +calls inside the SSL library.   The only reason this is present is because the
        +calls to PEM_* functions is hidden in the SSLeay library so you have to
        +pass in the callback some how.
        +
        +#define SSL_CTX_set_client_cert_cb(ctx,cb)
        +int callback(SSL *s,X509 **x509, EVP_PKEY **pkey);
        +Called when a client certificate is requested but there is not one set
        +against the SSL_CTX or the SSL.  If the callback returns 1, x509 and
        +pkey need to point to valid data.  The library will free these when
        +required so if the application wants to keep these around, increment
        +their reference counts.  If 0 is returned, no client cert is
        +available.  If -1 is returned, it is assumed that the callback needs
        +to be called again at a later point in time.  SSL_connect will return
        +-1 and SSL_want_x509_lookup(ssl) returns true.  Remember that
        +application data can be attached to an SSL structure via the
        +SSL_set_app_data(SSL *ssl,char *data) call.
        +
        +--------------------------
        +The X509 library.
        +
        +int X509_cert_verify(CERTIFICATE_CTX *ctx,X509 *xs, int (*cb)(),
        +	int *error,char *arg,STACK *cert_chain);
        +int verify_callback(int ok,X509 *xs,X509 *xi,int depth,int error,char *arg,
        +	STACK *cert_chain);
        +
        +X509_cert_verify() is used to authenticate X509 certificates.  The 'ctx' holds
        +the details of the various caches and files used to locate certificates.
        +'xs' is the certificate to verify and 'cb' is the application callback (more
        +detail later).  'error' will be set to the error code and 'arg' is passed
        +to the 'cb' callback.  Look at the VERIFY_* defines in crypto/x509/x509.h
        +
        +When ever X509_cert_verify() makes a 'negative' decision about a
        +certitificate, the callback is called.  If everything checks out, the
        +callback is called with 'VERIFY_OK' or 'VERIFY_ROOT_OK' (for a self
        +signed cert that is not the passed certificate).
        +
        +The callback is passed the X509_cert_verify opinion of the certificate 
        +in 'ok', the certificate in 'xs', the issuer certificate in 'xi',
        +the 'depth' of the certificate in the verification 'chain', the
        +VERIFY_* code in 'error' and the argument passed to X509_cert_verify()
        +in 'arg'. cert_chain is a list of extra certs to use if they are not
        +in the cache.
        +
        +The callback can be used to look at the error reason, and then return 0
        +for an 'error' or '1' for ok.  This will override the X509_cert_verify()
        +opinion of the certificates validity.  Processing will continue depending on
        +the return value.  If one just wishes to use the callback for informational
        +reason, just return the 'ok' parameter.
        +
        +--------------------------
        +The BN and DH library.
        +
        +BIGNUM *BN_generate_prime(int bits,int strong,BIGNUM *add,
        +	BIGNUM *rem,void (*callback)(int,int));
        +int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int),
        +
        +Read doc/bn.doc for the description of these 2.
        +
        +DH *DH_generate_parameters(int prime_len,int generator,
        +	void (*callback)(int,int));
        +Read doc/bn.doc for the description of the callback, since it is just passed
        +to BN_generate_prime(), except that it is also called as
        +callback(3,0) by this function.
        +
        +--------------------------
        +The CRYPTO library.
        +
        +void CRYPTO_set_locking_callback(void (*func)(int mode,int type,char *file,
        +	int line));
        +void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,
        +	int type,char *file, int line));
        +void CRYPTO_set_id_callback(unsigned long (*func)(void));
        +
        +Read threads.doc for info on these ones.
        +
        +
        +==== cipher.doc ========================================================
        +
        +The Cipher subroutines.
        +
        +These routines require "evp.h" to be included.
        +
        +These functions are a higher level interface to the various cipher
        +routines found in this library.  As such, they allow the same code to be
        +used to encrypt and decrypt via different ciphers with only a change
        +in an initial parameter.  These routines also provide buffering for block
        +ciphers.
        +
        +These routines all take a pointer to the following structure to specify
        +which cipher to use.  If you wish to use a new cipher with these routines,
        +you would probably be best off looking an how an existing cipher is
        +implemented and copying it.  At this point in time, I'm not going to go
        +into many details.  This structure should be considered opaque
        +
        +typedef struct pem_cipher_st
        +	{
        +	int type;
        +	int block_size;
        +	int key_len;
        +	int iv_len;
        +	void (*enc_init)();	/* init for encryption */
        +	void (*dec_init)();	/* init for decryption */
        +	void (*do_cipher)();	/* encrypt data */
        +	} EVP_CIPHER;
        +	
        +The type field is the object NID of the cipher type
        +(read the section on Objects for an explanation of what a NID is).
        +The cipher block_size is how many bytes need to be passed
        +to the cipher at a time.  Key_len is the
        +length of the key the cipher requires and iv_len is the length of the
        +initialisation vector required.  enc_init is the function
        +called to initialise the ciphers context for encryption and dec_init is the
        +function to initialise for decryption (they need to be different, especially
        +for the IDEA cipher).
        +
        +One reason for specifying the Cipher via a pointer to a structure
        +is that if you only use des-cbc, only the des-cbc routines will
        +be included when you link the program.  If you passed an integer
        +that specified which cipher to use, the routine that mapped that
        +integer to a set of cipher functions would cause all the ciphers
        +to be link into the code.  This setup also allows new ciphers
        +to be added by the application (with some restrictions).
        +
        +The thirteen ciphers currently defined in this library are
        +
        +EVP_CIPHER *EVP_des_ecb();     /* DES in ecb mode,     iv=0, block=8, key= 8 */
        +EVP_CIPHER *EVP_des_ede();     /* DES in ecb ede mode, iv=0, block=8, key=16 */
        +EVP_CIPHER *EVP_des_ede3();    /* DES in ecb ede mode, iv=0, block=8, key=24 */
        +EVP_CIPHER *EVP_des_cfb();     /* DES in cfb mode,     iv=8, block=1, key= 8 */
        +EVP_CIPHER *EVP_des_ede_cfb(); /* DES in ede cfb mode, iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_des_ede3_cfb();/* DES in ede cfb mode, iv=8, block=1, key=24 */
        +EVP_CIPHER *EVP_des_ofb();     /* DES in ofb mode,     iv=8, block=1, key= 8 */
        +EVP_CIPHER *EVP_des_ede_ofb(); /* DES in ede ofb mode, iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_des_ede3_ofb();/* DES in ede ofb mode, iv=8, block=1, key=24 */
        +EVP_CIPHER *EVP_des_cbc();     /* DES in cbc mode,     iv=8, block=8, key= 8 */
        +EVP_CIPHER *EVP_des_ede_cbc(); /* DES in cbc ede mode, iv=8, block=8, key=16 */
        +EVP_CIPHER *EVP_des_ede3_cbc();/* DES in cbc ede mode, iv=8, block=8, key=24 */
        +EVP_CIPHER *EVP_desx_cbc();    /* DES in desx cbc mode,iv=8, block=8, key=24 */
        +EVP_CIPHER *EVP_rc4();         /* RC4,                 iv=0, block=1, key=16 */
        +EVP_CIPHER *EVP_idea_ecb();    /* IDEA in ecb mode,    iv=0, block=8, key=16 */
        +EVP_CIPHER *EVP_idea_cfb();    /* IDEA in cfb mode,    iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_idea_ofb();    /* IDEA in ofb mode,    iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_idea_cbc();    /* IDEA in cbc mode,    iv=8, block=8, key=16 */
        +EVP_CIPHER *EVP_rc2_ecb();     /* RC2 in ecb mode,     iv=0, block=8, key=16 */
        +EVP_CIPHER *EVP_rc2_cfb();     /* RC2 in cfb mode,     iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_rc2_ofb();     /* RC2 in ofb mode,     iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_rc2_cbc();     /* RC2 in cbc mode,     iv=8, block=8, key=16 */
        +EVP_CIPHER *EVP_bf_ecb();      /* Blowfish in ecb mode,iv=0, block=8, key=16 */
        +EVP_CIPHER *EVP_bf_cfb();      /* Blowfish in cfb mode,iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_bf_ofb();      /* Blowfish in ofb mode,iv=8, block=1, key=16 */
        +EVP_CIPHER *EVP_bf_cbc();      /* Blowfish in cbc mode,iv=8, block=8, key=16 */
        +
        +The meaning of the compound names is as follows.
        +des	The base cipher is DES.
        +idea	The base cipher is IDEA
        +rc4	The base cipher is RC4-128
        +rc2	The base cipher is RC2-128
        +ecb	Electronic Code Book form of the cipher.
        +cbc	Cipher Block Chaining form of the cipher.
        +cfb	64 bit Cipher Feedback form of the cipher.
        +ofb	64 bit Output Feedback form of the cipher.
        +ede	The cipher is used in Encrypt, Decrypt, Encrypt mode.  The first
        +	and last keys are the same.
        +ede3	The cipher is used in Encrypt, Decrypt, Encrypt mode.
        +
        +All the Cipher routines take a EVP_CIPHER_CTX pointer as an argument.
        +The state of the cipher is kept in this structure.
        +
        +typedef struct EVP_CIPHER_Ctx_st
        +	{
        +	EVP_CIPHER *cipher;
        +	int encrypt;		/* encrypt or decrypt */
        +	int buf_len;		/* number we have left */
        +	unsigned char buf[8];
        +	union	{
        +		.... /* cipher specific stuff */
        +		} c;
        +	} EVP_CIPHER_CTX;
        +
        +Cipher is a pointer the the EVP_CIPHER for the current context.  The encrypt
        +flag indicates encryption or decryption.  buf_len is the number of bytes
        +currently being held in buf.
        +The 'c' union holds the cipher specify context.
        +
        +The following functions are to be used.
        +
        +int EVP_read_pw_string(
        +char *buf,
        +int len,
        +char *prompt,
        +int verify,
        +	This function is the same as des_read_pw_string() (des.doc).
        +
        +void EVP_set_pw_prompt(char *prompt);
        +	This function sets the 'default' prompt to use to use in
        +	EVP_read_pw_string when the prompt parameter is NULL.  If the
        +	prompt parameter is NULL, this 'default prompt' feature is turned
        +	off.  Be warned, this is a global variable so weird things
        +	will happen if it is used under Win16 and care must be taken
        +	with a multi-threaded version of the library.
        +
        +char *EVP_get_pw_prompt();
        +	This returns a pointer to the default prompt string.  NULL
        +	if it is not set.
        +
        +int EVP_BytesToKey(
        +EVP_CIPHER *type,
        +EVP_MD *md,
        +unsigned char *salt,
        +unsigned char *data,
        +int datal,
        +int count,
        +unsigned char *key,
        +unsigned char *iv);
        +	This function is used to generate a key and an initialisation vector
        +	for a specified cipher from a key string and a salt.  Type
        +	specifies the cipher the 'key' is being generated for.  Md is the
        +	message digest algorithm to use to generate the key and iv.  The salt
        +	is an optional 8 byte object that is used to help seed the key
        +	generator.
        +	If the salt value is NULL, it is just not used.  Datal is the
        +	number of bytes to use from 'data' in the key generation.  
        +	This function returns the key size for the specified cipher, if
        +	data is NULL, this value is returns and no other
        +	computation is performed.  Count is
        +	the number of times to loop around the key generator.  I would
        +	suggest leaving it's value as 1.  Key and iv are the structures to
        +	place the returning iv and key in.  If they are NULL, no value is
        +	generated for that particular value.
        +	The algorithm used is as follows
        +	
        +	/* M[] is an array of message digests
        +	 * MD() is the message digest function */
        +	M[0]=MD(data . salt);
        +	for (i=1; i<count; i++) M[0]=MD(M[0]);
        +
        +	i=1
        +	while (data still needed for key and iv)
        +		{
        +		M[i]=MD(M[i-1] . data . salt);
        +		for (i=1; i<count; i++) M[i]=MD(M[i]);
        +		i++;
        +		}
        +
        +	If the salt is NULL, it is not used.
        +	The digests are concatenated together.
        +	M = M[0] . M[1] . M[2] .......
        +
        +	For key= 8, iv=8 => key=M[0.. 8], iv=M[ 9 .. 16].
        +	For key=16, iv=0 => key=M[0..16].
        +	For key=16, iv=8 => key=M[0..16], iv=M[17 .. 24].
        +	For key=24, iv=8 => key=M[0..24], iv=M[25 .. 32].
        +
        +	This routine will produce DES-CBC keys and iv that are compatible
        +	with the PKCS-5 standard when md2 or md5 are used.  If md5 is
        +	used, the salt is NULL and count is 1, this routine will produce
        +	the password to key mapping normally used with RC4.
        +	I have attempted to logically extend the PKCS-5 standard to
        +	generate keys and iv for ciphers that require more than 16 bytes,
        +	if anyone knows what the correct standard is, please inform me.
        +	When using sha or sha1, things are a bit different under this scheme,
        +	since sha produces a 20 byte digest.  So for ciphers requiring
        +	24 bits of data, 20 will come from the first MD and 4 will
        +	come from the second.
        +
        +	I have considered having a separate function so this 'routine'
        +	can be used without the requirement of passing a EVP_CIPHER *,
        +	but I have decided to not bother.  If you wish to use the
        +	function without official EVP_CIPHER structures, just declare
        +	a local one and set the key_len and iv_len fields to the
        +	length you desire.
        +
        +The following routines perform encryption and decryption 'by parts'.  By
        +this I mean that there are groups of 3 routines.  An Init function that is
        +used to specify a cipher and initialise data structures.  An Update routine
        +that does encryption/decryption, one 'chunk' at a time.  And finally a
        +'Final' function that finishes the encryption/decryption process.
        +All these functions take a EVP_CIPHER pointer to specify which cipher to
        +encrypt/decrypt with.  They also take a EVP_CIPHER_CTX object as an
        +argument.  This structure is used to hold the state information associated
        +with the operation in progress.
        +
        +void EVP_EncryptInit(
        +EVP_CIPHER_CTX *ctx,
        +EVP_CIPHER *type,
        +unsigned char *key,
        +unsigned char *iv);
        +	This function initialise a EVP_CIPHER_CTX for encryption using the
        +	cipher passed in the 'type' field.  The cipher is initialised to use
        +	'key' as the key and 'iv' for the initialisation vector (if one is
        +	required).  If the type, key or iv is NULL, the value currently in the
        +	EVP_CIPHER_CTX is reused.  So to perform several decrypt
        +	using the same cipher, key and iv, initialise with the cipher,
        +	key and iv the first time and then for subsequent calls,
        +	reuse 'ctx' but pass NULL for type, key and iv.  You must make sure
        +	to pass a key that is large enough for a particular cipher.  I
        +	would suggest using the EVP_BytesToKey() function.
        +
        +void EVP_EncryptUpdate(
        +EVP_CIPHER_CTX *ctx,
        +unsigned char *out,
        +int *outl,
        +unsigned char *in,
        +int inl);
        +	This function takes 'inl' bytes from 'in' and outputs bytes
        +	encrypted by the cipher 'ctx' was initialised with into 'out'.  The
        +	number of bytes written to 'out' is put into outl.  If a particular
        +	cipher encrypts in blocks, less or more bytes than input may be
        +	output.  Currently the largest block size used by supported ciphers
        +	is 8 bytes, so 'out' should have room for 'inl+7' bytes.  Normally
        +	EVP_EncryptInit() is called once, followed by lots and lots of
        +	calls to EVP_EncryptUpdate, followed by a single EVP_EncryptFinal
        +	call.
        +
        +void EVP_EncryptFinal(
        +EVP_CIPHER_CTX *ctx,
        +unsigned char *out,
        +int *outl);
        +	Because quite a large number of ciphers are block ciphers, there is
        +	often an incomplete block to write out at the end of the
        +	encryption.  EVP_EncryptFinal() performs processing on this last
        +	block.  The last block in encoded in such a way that it is possible
        +	to determine how many bytes in the last block are valid.  For 8 byte
        +	block size ciphers, if only 5 bytes in the last block are valid, the
        +	last three bytes will be filled with the value 3.  If only 2 were
        +	valid, the other 6 would be filled with sixes.  If all 8 bytes are
        +	valid, a extra 8 bytes are appended to the cipher stream containing
        +	nothing but 8 eights.  These last bytes are output into 'out' and
        +	the number of bytes written is put into 'outl'  These last bytes
        +	are output into 'out' and the number of bytes written is put into
        +	'outl'.  This form of block cipher finalisation is compatible with
        +	PKCS-5.  Please remember that even if you are using ciphers like
        +	RC4 that has no blocking and so the function will not write
        +	anything into 'out', it would still be a good idea to pass a
        +	variable for 'out' that can hold 8 bytes just in case the cipher is
        +	changed some time in the future.  It should also be remembered
        +	that the EVP_CIPHER_CTX contains the password and so when one has
        +	finished encryption with a particular EVP_CIPHER_CTX, it is good
        +	practice to zero the structure 
        +	(ie. memset(ctx,0,sizeof(EVP_CIPHER_CTX)).
        +	
        +void EVP_DecryptInit(
        +EVP_CIPHER_CTX *ctx,
        +EVP_CIPHER *type,
        +unsigned char *key,
        +unsigned char *iv);
        +	This function is basically the same as EVP_EncryptInit() accept that
        +	is prepares the EVP_CIPHER_CTX for decryption.
        +
        +void EVP_DecryptUpdate(
        +EVP_CIPHER_CTX *ctx,
        +unsigned char *out,
        +int *outl,
        +unsigned char *in,
        +int inl);
        +	This function is basically the same as EVP_EncryptUpdate()
        +	except that it performs decryption.  There is one
        +	fundamental difference though.  'out' can not be the same as
        +	'in' for any ciphers with a block size greater than 1 if more
        +	than one call to EVP_DecryptUpdate() will be made.  This
        +	is because this routine can hold a 'partial' block between
        +	calls.  When a partial block is decrypted (due to more bytes
        +	being passed via this function, they will be written to 'out'
        +	overwriting the input bytes in 'in' that have not been read
        +	yet.  From this it should also be noted that 'out' should
        +	be at least one 'block size' larger than 'inl'.  This problem
        +	only occurs on the second and subsequent call to
        +	EVP_DecryptUpdate() when using a block cipher.
        +
        +int EVP_DecryptFinal(
        +EVP_CIPHER_CTX *ctx,
        +unsigned char *out,
        +int *outl);
        +	This function is different to EVP_EncryptFinal in that it 'removes'
        +	any padding bytes appended when the data was encrypted.  Due to the
        +	way in which 1 to 8 bytes may have been appended when encryption
        +	using a block cipher, 'out' can end up with 0 to 7 bytes being put
        +	into it.  When decoding the padding bytes, it is possible to detect
        +	an incorrect decryption.  If the decryption appears to be wrong, 0
        +	is returned.  If everything seems ok, 1 is returned.  For ciphers
        +	with a block size of 1 (RC4), this function would normally not
        +	return any bytes and would always return 1.  Just because this
        +	function returns 1 does not mean the decryption was correct. It
        +	would normally be wrong due to either the wrong key/iv or
        +	corruption of the cipher data fed to EVP_DecryptUpdate().
        +	As for EVP_EncryptFinal, it is a good idea to zero the
        +	EVP_CIPHER_CTX after use since the structure contains the key used
        +	to decrypt the data.
        +	
        +The following Cipher routines are convenience routines that call either
        +EVP_EncryptXxx or EVP_DecryptXxx depending on weather the EVP_CIPHER_CTX
        +was setup to encrypt or decrypt.  
        +
        +void EVP_CipherInit(
        +EVP_CIPHER_CTX *ctx,
        +EVP_CIPHER *type,
        +unsigned char *key,
        +unsigned char *iv,
        +int enc);
        +	This function take arguments that are the same as EVP_EncryptInit()
        +	and EVP_DecryptInit() except for the extra 'enc' flag.  If 1, the
        +	EVP_CIPHER_CTX is setup for encryption, if 0, decryption.
        +
        +void EVP_CipherUpdate(
        +EVP_CIPHER_CTX *ctx,
        +unsigned char *out,
        +int *outl,
        +unsigned char *in,
        +int inl);
        +	Again this function calls either EVP_EncryptUpdate() or
        +	EVP_DecryptUpdate() depending on state in the 'ctx' structure.
        +	As noted for EVP_DecryptUpdate(), when this routine is used
        +	for decryption with block ciphers, 'out' should not be the
        +	same as 'in'.
        +
        +int EVP_CipherFinal(
        +EVP_CIPHER_CTX *ctx,
        +unsigned char *outm,
        +int *outl);
        +	This routine call EVP_EncryptFinal() or EVP_DecryptFinal()
        +	depending on the state information in 'ctx'.  1 is always returned
        +	if the mode is encryption, otherwise the return value is the return
        +	value of EVP_DecryptFinal().
        +
        +==== cipher.m ========================================================
        +
        +Date: Tue, 15 Oct 1996 08:16:14 +1000 (EST)
        +From: Eric Young <eay@mincom.com>
        +X-Sender: eay@orb
        +To: Roland Haring <rharing@tandem.cl>
        +Cc: ssl-users@mincom.com
        +Subject: Re: Symmetric encryption with ssleay
        +In-Reply-To: <m0vBpyq-00001aC@tandemnet.tandem.cl>
        +Message-Id: <Pine.SOL.3.91.961015075623.11394A-100000@orb>
        +Mime-Version: 1.0
        +Content-Type: TEXT/PLAIN; charset=US-ASCII
        +Sender: ssl-lists-owner@mincom.com
        +Precedence: bulk
        +Status: RO
        +X-Status: 
        +
        +On Fri, 11 Oct 1996, Roland Haring wrote:
        +> THE_POINT:
        +> 	Would somebody be so kind to give me the minimum basic 
        +> 	calls I need to do to libcrypto.a to get some text encrypted
        +> 	and decrypted again? ...hopefully with code included to do
        +> 	base64 encryption and decryption ... e.g. that sign-it.c code
        +> 	posted some while ago was a big help :-) (please, do not point
        +> 	me to apps/enc.c where I suspect my Heissenbug to be hidden :-)
        +
        +Ok, the base64 encoding stuff in 'enc.c' does the wrong thing sometimes 
        +when the data is less than a line long (this is for decoding).  I'll dig 
        +up the exact fix today and post it.  I am taking longer on 0.6.5 than I 
        +intended so I'll just post this patch.
        +
        +The documentation to read is in
        +doc/cipher.doc,
        +doc/encode.doc (very sparse :-).
        +and perhaps
        +doc/digest.doc,
        +
        +The basic calls to encrypt with say triple DES are
        +
        +Given
        +char key[EVP_MAX_KEY_LENGTH];
        +char iv[EVP_MAX_IV_LENGTH];
        +EVP_CIPHER_CTX ctx;
        +unsigned char out[512+8];
        +int outl;
        +
        +/* optional generation of key/iv data from text password using md5
        + * via an upward compatable verson of PKCS#5. */
        +EVP_BytesToKey(EVP_des_ede3_cbc,EVP_md5,NULL,passwd,strlen(passwd),
        +	key,iv);
        +
        +/* Initalise the EVP_CIPHER_CTX */
        +EVP_EncryptInit(ctx,EVP_des_ede3_cbc,key,iv);
        +
        +while (....)
        +	{
        +	/* This is processing 512 bytes at a time, the bytes are being
        +	 * copied into 'out', outl bytes are output.  'out' should not be the
        +	 * same as 'in' for reasons mentioned in the documentation. */
        +	EVP_EncryptUpdate(ctx,out,&outl,in,512);
        +	}
        +
        +/* Output the last 'block'.  If the cipher is a block cipher, the last
        + * block is encoded in such a way so that a wrong decryption will normally be
        + * detected - again, one of the PKCS standards. */
        +
        +EVP_EncryptFinal(ctx,out,&outl);
        +
        +To decrypt, use the EVP_DecryptXXXXX functions except that EVP_DecryptFinal()
        +will return 0 if the decryption fails (only detectable on block ciphers).
        +
        +You can also use
        +EVP_CipherInit()
        +EVP_CipherUpdate()
        +EVP_CipherFinal()
        +which does either encryption or decryption depending on an extra 
        +parameter to EVP_CipherInit().
        +
        +
        +To do the base64 encoding,
        +EVP_EncodeInit()
        +EVP_EncodeUpdate()
        +EVP_EncodeFinal()
        +
        +EVP_DecodeInit()
        +EVP_DecodeUpdate()
        +EVP_DecodeFinal()
        +
        +where the encoding is quite simple, but the decoding can be a bit more 
        +fun (due to dud input).
        +
        +EVP_DecodeUpdate() returns -1 for an error on an input line, 0 if the 
        +'last line' was just processed, and 1 if more lines should be submitted.
        +
        +EVP_DecodeFinal() returns -1 for an error or 1 if things are ok.
        +
        +So the loop becomes
        +EVP_DecodeInit(....)
        +for (;;)
        +	{
        +	i=EVP_DecodeUpdate(....);
        +	if (i < 0) goto err;
        +
        +	/* process the data */
        +
        +	if (i == 0) break;
        +	}
        +EVP_DecodeFinal(....);
        +/* process the data */
        +
        +The problem in 'enc.c' is that I was stuff the processing up after the 
        +EVP_DecodeFinal(...) when the for(..) loop was not being run (one line of 
        +base64 data) and this was because 'enc.c' tries to scan over a file until
        +it hits the first valid base64 encoded line.
        +
        +hope this helps a bit.
        +eric
        +--
        +Eric Young                  | BOOL is tri-state according to Bill Gates.
        +AARNet: eay@mincom.oz.au    | RTFM Win32 GetMessage().
        +
        +==== conf.doc ========================================================
        +
        +The CONF library.
        +
        +The CONF library is a simple set of routines that can be used to configure
        +programs.  It is a superset of the genenv() function with some extra
        +structure.
        +
        +The library consists of 5 functions.
        +
        +LHASH *CONF_load(LHASH *config,char *file);
        +This function is called to load in a configuration file.  Multiple
        +configuration files can be loaded, with each subsequent 'load' overwriting
        +any already defined 'variables'.  If there is an error, NULL is returned.
        +If config is NULL, a new LHASH structure is created and returned, otherwise
        +the new data in the 'file' is loaded into the 'config' structure.
        +
        +void CONF_free(LHASH *config);
        +This function free()s the data in config.
        +
        +char *CONF_get_string(LHASH *config,char *section,char *name);
        +This function returns the string found in 'config' that corresponds to the
        +'section' and 'name' specified.  Classes and the naming system used will be
        +discussed later in this document.  If the variable is not defined, an NULL
        +is returned.
        +
        +long CONF_get_long(LHASH *config,char *section, char *name);
        +This function is the same as CONF_get_string() except that it converts the
        +string to an long and returns it.  If variable is not a number or the
        +variable does not exist, 0 is returned.  This is a little problematic but I
        +don't know of a simple way around it.
        +
        +STACK *CONF_get_section(LHASH *config, char *section);
        +This function returns a 'stack' of CONF_VALUE items that are all the
        +items defined in a particular section.  DO NOT free() any of the
        +variable returned.  They will disappear when CONF_free() is called.
        +
        +The 'lookup' model.
        +The configuration file is divided into 'sections'.  Each section is started by
        +a line of the form '[ section ]'.  All subsequent variable definitions are
        +of this section.  A variable definition is a simple alpha-numeric name
        +followed by an '=' and then the data.  A section or variable name can be
        +described by a regular expression of the following form '[A-Za-z0-9_]+'.
        +The value of the variable is the text after the '=' until the end of the
        +line, stripped of leading and trailing white space.
        +At this point I should mention that a '#' is a comment character, \ is the
        +escape character, and all three types of quote can be used to stop any
        +special interpretation of the data.
        +Now when the data is being loaded, variable expansion can occur.  This is
        +done by expanding any $NAME sequences into the value represented by the
        +variable NAME.  If the variable is not in the current section, the different
        +section can be specified by using the $SECTION::NAME form.  The ${NAME} form
        +also works and is very useful for expanding variables inside strings.
        +
        +When a variable is looked up, there are 2 special section. 'default', which
        +is the initial section, and 'ENV' which is the processes environment
        +variables (accessed via getenv()).  When a variable is looked up, it is
        +first 'matched' with it's section (if one was specified), if this fails, the
        +'default' section is matched.
        +If the 'lhash' variable passed was NULL, the environment is searched.
        +
        +Now why do we bother with sections?  So we can have multiple programs using
        +the same configuration file, or multiple instances of the same program
        +using different variables.  It also provides a nice mechanism to override
        +the processes environment variables (eg ENV::HOME=/tmp).  If there is a
        +program specific variable missing, we can have default values.
        +Multiple configuration files can be loaded, with each new value clearing
        +any predefined values.  A system config file can provide 'default' values,
        +and application/usr specific files can provide overriding values.
        +
        +Examples
        +
        +# This is a simple example
        +SSLEAY_HOME	= /usr/local/ssl
        +ENV::PATH	= $SSLEAY_HOME/bin:$PATH	# override my path
        +
        +[X509]
        +cert_dir	= $SSLEAY_HOME/certs	# /usr/local/ssl/certs
        +
        +[SSL]
        +CIPHER		= DES-EDE-MD5:RC4-MD5
        +USER_CERT	= $HOME/${USER}di'r 5'	# /home/eay/eaydir 5
        +USER_CERT	= $HOME/\${USER}di\'r	# /home/eay/${USER}di'r
        +USER_CERT	= "$HOME/${US"ER}di\'r	# $HOME/${USER}di'r
        +
        +TEST		= 1234\
        +5678\
        +9ab					# TEST=123456789ab
        +TTT		= 1234\n\n		# TTT=1234<nl><nl>
        +
        +
        +
        +==== des.doc ========================================================
        +
        +The DES library.
        +
        +Please note that this library was originally written to operate with
        +eBones, a version of Kerberos that had had encryption removed when it left
        +the USA and then put back in.  As such there are some routines that I will
        +advise not using but they are still in the library for historical reasons.
        +For all calls that have an 'input' and 'output' variables, they can be the
        +same.
        +
        +This library requires the inclusion of 'des.h'.
        +
        +All of the encryption functions take what is called a des_key_schedule as an 
        +argument.  A des_key_schedule is an expanded form of the des key.
        +A des_key is 8 bytes of odd parity, the type used to hold the key is a
        +des_cblock.  A des_cblock is an array of 8 bytes, often in this library
        +description I will refer to input bytes when the function specifies
        +des_cblock's as input or output, this just means that the variable should
        +be a multiple of 8 bytes.
        +
        +The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
        +specify decryption.  The functions and global variable are as follows:
        +
        +int des_check_key;
        +	DES keys are supposed to be odd parity.  If this variable is set to
        +	a non-zero value, des_set_key() will check that the key has odd
        +	parity and is not one of the known weak DES keys.  By default this
        +	variable is turned off;
        +	
        +void des_set_odd_parity(
        +des_cblock *key );
        +	This function takes a DES key (8 bytes) and sets the parity to odd.
        +	
        +int des_is_weak_key(
        +des_cblock *key );
        +	This function returns a non-zero value if the DES key passed is a
        +	weak, DES key.  If it is a weak key, don't use it, try a different
        +	one.  If you are using 'random' keys, the chances of hitting a weak
        +	key are 1/2^52 so it is probably not worth checking for them.
        +	
        +int des_set_key(
        +des_cblock *key,
        +des_key_schedule schedule);
        +	Des_set_key converts an 8 byte DES key into a des_key_schedule.
        +	A des_key_schedule is an expanded form of the key which is used to
        +	perform actual encryption.  It can be regenerated from the DES key
        +	so it only needs to be kept when encryption or decryption is about
        +	to occur.  Don't save or pass around des_key_schedule's since they
        +	are CPU architecture dependent, DES keys are not.  If des_check_key
        +	is non zero, zero is returned if the key has the wrong parity or
        +	the key is a weak key, else 1 is returned.
        +	
        +int des_key_sched(
        +des_cblock *key,
        +des_key_schedule schedule);
        +	An alternative name for des_set_key().
        +
        +int des_rw_mode;		/* defaults to DES_PCBC_MODE */
        +	This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
        +	This specifies the function to use in the enc_read() and enc_write()
        +	functions.
        +
        +void des_encrypt(
        +unsigned long *data,
        +des_key_schedule ks,
        +int enc);
        +	This is the DES encryption function that gets called by just about
        +	every other DES routine in the library.  You should not use this
        +	function except to implement 'modes' of DES.  I say this because the
        +	functions that call this routine do the conversion from 'char *' to
        +	long, and this needs to be done to make sure 'non-aligned' memory
        +	access do not occur.  The characters are loaded 'little endian',
        +	have a look at my source code for more details on how I use this
        +	function.
        +	Data is a pointer to 2 unsigned long's and ks is the
        +	des_key_schedule to use.  enc, is non zero specifies encryption,
        +	zero if decryption.
        +
        +void des_encrypt2(
        +unsigned long *data,
        +des_key_schedule ks,
        +int enc);
        +	This functions is the same as des_encrypt() except that the DES
        +	initial permutation (IP) and final permutation (FP) have been left
        +	out.  As for des_encrypt(), you should not use this function.
        +	It is used by the routines in my library that implement triple DES.
        +	IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
        +	as des_encrypt() des_encrypt() des_encrypt() except faster :-).
        +
        +void des_ecb_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +des_key_schedule ks,
        +int enc);
        +	This is the basic Electronic Code Book form of DES, the most basic
        +	form.  Input is encrypted into output using the key represented by
        +	ks.  If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
        +	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
        +	(the des_cblock structure is 8 chars).
        +	
        +void des_ecb3_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +des_key_schedule ks1,
        +des_key_schedule ks2,
        +des_key_schedule ks3,
        +int enc);
        +	This is the 3 key EDE mode of ECB DES.  What this means is that 
        +	the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
        +	then encrypted again with ks3, before being put into output;
        +	C=E(ks3,D(ks2,E(ks1,M))).  There is a macro, des_ecb2_encrypt()
        +	that only takes 2 des_key_schedules that implements,
        +	C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
        +	
        +void des_cbc_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int enc);
        +	This routine implements DES in Cipher Block Chaining mode.
        +	Input, which should be a multiple of 8 bytes is encrypted
        +	(or decrypted) to output which will also be a multiple of 8 bytes.
        +	The number of bytes is in length (and from what I've said above,
        +	should be a multiple of 8).  If length is not a multiple of 8, I'm
        +	not being held responsible :-).  ivec is the initialisation vector.
        +	This function does not modify this variable.  To correctly implement
        +	cbc mode, you need to do one of 2 things; copy the last 8 bytes of
        +	cipher text for use as the next ivec in your application,
        +	or use des_ncbc_encrypt(). 
        +	Only this routine has this problem with updating the ivec, all
        +	other routines that are implementing cbc mode update ivec.
        +	
        +void des_ncbc_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +des_key_schedule sk,
        +des_cblock *ivec,
        +int enc);
        +	For historical reasons, des_cbc_encrypt() did not update the
        +	ivec with the value requires so that subsequent calls to
        +	des_cbc_encrypt() would 'chain'.  This was needed so that the same
        +	'length' values would not need to be used when decrypting.
        +	des_ncbc_encrypt() does the right thing.  It is the same as
        +	des_cbc_encrypt accept that ivec is updates with the correct value
        +	to pass in subsequent calls to des_ncbc_encrypt().  I advise using
        +	des_ncbc_encrypt() instead of des_cbc_encrypt();
        +
        +void des_xcbc_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +des_key_schedule sk,
        +des_cblock *ivec,
        +des_cblock *inw,
        +des_cblock *outw,
        +int enc);
        +	This is RSA's DESX mode of DES.  It uses inw and outw to
        +	'whiten' the encryption.  inw and outw are secret (unlike the iv)
        +	and are as such, part of the key.  So the key is sort of 24 bytes.
        +	This is much better than cbc des.
        +	
        +void des_3cbc_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +des_key_schedule sk1,
        +des_key_schedule sk2,
        +des_cblock *ivec1,
        +des_cblock *ivec2,
        +int enc);
        +	This function is flawed, do not use it.  I have left it in the
        +	library because it is used in my des(1) program and will function
        +	correctly when used by des(1).  If I removed the function, people
        +	could end up unable to decrypt files.
        +	This routine implements outer triple cbc encryption using 2 ks and
        +	2 ivec's.  Use des_ede2_cbc_encrypt() instead.
        +	
        +void des_ede3_cbc_encrypt(
        +des_cblock *input,
        +des_cblock *output, 
        +long length,
        +des_key_schedule ks1,
        +des_key_schedule ks2, 
        +des_key_schedule ks3, 
        +des_cblock *ivec,
        +int enc);
        +	This function implements outer triple CBC DES encryption with 3
        +	keys.  What this means is that each 'DES' operation
        +	inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
        +	Again, this is cbc mode so an ivec is requires.
        +	This mode is used by SSL.
        +	There is also a des_ede2_cbc_encrypt() that only uses 2
        +	des_key_schedule's, the first being reused for the final
        +	encryption.  C=E(ks1,D(ks2,E(ks1,M))).  This form of triple DES
        +	is used by the RSAref library.
        +	
        +void des_pcbc_encrypt(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int enc);
        +	This is Propagating Cipher Block Chaining mode of DES.  It is used
        +	by Kerberos v4.  It's parameters are the same as des_ncbc_encrypt().
        +	
        +void des_cfb_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +int numbits,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int enc);
        +	Cipher Feedback Back mode of DES.  This implementation 'feeds back'
        +	in numbit blocks.  The input (and output) is in multiples of numbits
        +	bits.  numbits should to be a multiple of 8 bits.  Length is the
        +	number of bytes input.  If numbits is not a multiple of 8 bits,
        +	the extra bits in the bytes will be considered padding.  So if
        +	numbits is 12, for each 2 input bytes, the 4 high bits of the
        +	second byte will be ignored.  So to encode 72 bits when using
        +	a numbits of 12 take 12 bytes.  To encode 72 bits when using
        +	numbits of 9 will take 16 bytes.  To encode 80 bits when using
        +	numbits of 16 will take 10 bytes. etc, etc.  This padding will
        +	apply to both input and output.
        +
        +	
        +void des_cfb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int *num,
        +int enc);
        +	This is one of the more useful functions in this DES library, it
        +	implements CFB mode of DES with 64bit feedback.  Why is this
        +	useful you ask?  Because this routine will allow you to encrypt an
        +	arbitrary number of bytes, no 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  num contains 'how far' we are though ivec.  If this does
        +	not make much sense, read more about cfb mode of DES :-).
        +	
        +void des_ede3_cfb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +des_key_schedule ks1,
        +des_key_schedule ks2,
        +des_key_schedule ks3,
        +des_cblock *ivec,
        +int *num,
        +int enc);
        +	Same as des_cfb64_encrypt() accept that the DES operation is
        +	triple DES.  As usual, there is a macro for
        +	des_ede2_cfb64_encrypt() which reuses ks1.
        +
        +void des_ofb_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +int numbits,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec);
        +	This is a implementation of Output Feed Back mode of DES.  It is
        +	the same as des_cfb_encrypt() in that numbits is the size of the
        +	units dealt with during input and output (in bits).
        +	
        +void des_ofb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int *num);
        +	The same as des_cfb64_encrypt() except that it is Output Feed Back
        +	mode.
        +
        +void des_ede3_ofb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +des_key_schedule ks1,
        +des_key_schedule ks2,
        +des_key_schedule ks3,
        +des_cblock *ivec,
        +int *num);
        +	Same as des_ofb64_encrypt() accept that the DES operation is
        +	triple DES.  As usual, there is a macro for
        +	des_ede2_ofb64_encrypt() which reuses ks1.
        +
        +int des_read_pw_string(
        +char *buf,
        +int length,
        +char *prompt,
        +int verify);
        +	This routine is used to get a password from the terminal with echo
        +	turned off.  Buf is where the string will end up and length is the
        +	size of buf.  Prompt is a string presented to the 'user' and if
        +	verify is set, the key is asked for twice and unless the 2 copies
        +	match, an error is returned.  A return code of -1 indicates a
        +	system error, 1 failure due to use interaction, and 0 is success.
        +
        +unsigned long des_cbc_cksum(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec);
        +	This function produces an 8 byte checksum from input that it puts in
        +	output and returns the last 4 bytes as a long.  The checksum is
        +	generated via cbc mode of DES in which only the last 8 byes are
        +	kept.  I would recommend not using this function but instead using
        +	the EVP_Digest routines, or at least using MD5 or SHA.  This
        +	function is used by Kerberos v4 so that is why it stays in the
        +	library.
        +	
        +char *des_fcrypt(
        +const char *buf,
        +const char *salt
        +char *ret);
        +	This is my fast version of the unix crypt(3) function.  This version
        +	takes only a small amount of space relative to other fast
        +	crypt() implementations.  This is different to the normal crypt
        +	in that the third parameter is the buffer that the return value
        +	is written into.  It needs to be at least 14 bytes long.  This
        +	function is thread safe, unlike the normal crypt.
        +
        +char *crypt(
        +const char *buf,
        +const char *salt);
        +	This function calls des_fcrypt() with a static array passed as the
        +	third parameter.  This emulates the normal non-thread safe semantics
        +	of crypt(3).
        +
        +void des_string_to_key(
        +char *str,
        +des_cblock *key);
        +	This function takes str and converts it into a DES key.  I would
        +	recommend using MD5 instead and use the first 8 bytes of output.
        +	When I wrote the first version of these routines back in 1990, MD5
        +	did not exist but I feel these routines are still sound.  This
        +	routines is compatible with the one in MIT's libdes.
        +	
        +void des_string_to_2keys(
        +char *str,
        +des_cblock *key1,
        +des_cblock *key2);
        +	This function takes str and converts it into 2 DES keys.
        +	I would recommend using MD5 and using the 16 bytes as the 2 keys.
        +	I have nothing against these 2 'string_to_key' routines, it's just
        +	that if you say that your encryption key is generated by using the
        +	16 bytes of an MD5 hash, every-one knows how you generated your
        +	keys.
        +
        +int des_read_password(
        +des_cblock *key,
        +char *prompt,
        +int verify);
        +	This routine combines des_read_pw_string() with des_string_to_key().
        +
        +int des_read_2passwords(
        +des_cblock *key1,
        +des_cblock *key2,
        +char *prompt,
        +int verify);
        +	This routine combines des_read_pw_string() with des_string_to_2key().
        +
        +void des_random_seed(
        +des_cblock key);
        +	This routine sets a starting point for des_random_key().
        +	
        +void des_random_key(
        +des_cblock ret);
        +	This function return a random key.  Make sure to 'seed' the random
        +	number generator (with des_random_seed()) before using this function.
        +	I personally now use a MD5 based random number system.
        +
        +int des_enc_read(
        +int fd,
        +char *buf,
        +int len,
        +des_key_schedule ks,
        +des_cblock *iv);
        +	This function will write to a file descriptor the encrypted data
        +	from buf.  This data will be preceded by a 4 byte 'byte count' and
        +	will be padded out to 8 bytes.  The encryption is either CBC of
        +	PCBC depending on the value of des_rw_mode.  If it is DES_PCBC_MODE,
        +	pcbc is used, if DES_CBC_MODE, cbc is used.  The default is to use
        +	DES_PCBC_MODE.
        +
        +int des_enc_write(
        +int fd,
        +char *buf,
        +int len,
        +des_key_schedule ks,
        +des_cblock *iv);
        +	This routines read stuff written by des_enc_read() and decrypts it.
        +	I have used these routines quite a lot but I don't believe they are
        +	suitable for non-blocking io.  If you are after a full
        +	authentication/encryption over networks, have a look at SSL instead.
        +
        +unsigned long des_quad_cksum(
        +des_cblock *input,
        +des_cblock *output,
        +long length,
        +int out_count,
        +des_cblock *seed);
        +	This is a function from Kerberos v4 that is not anything to do with
        +	DES but was needed.  It is a cksum that is quicker to generate than
        +	des_cbc_cksum();  I personally would use MD5 routines now.
        +=====
        +Modes of DES
        +Quite a bit of the following information has been taken from
        +	AS 2805.5.2
        +	Australian Standard
        +	Electronic funds transfer - Requirements for interfaces,
        +	Part 5.2: Modes of operation for an n-bit block cipher algorithm
        +	Appendix A
        +
        +There are several different modes in which DES can be used, they are
        +as follows.
        +
        +Electronic Codebook Mode (ECB) (des_ecb_encrypt())
        +- 64 bits are enciphered at a time.
        +- The order of the blocks can be rearranged without detection.
        +- The same plaintext block always produces the same ciphertext block
        +  (for the same key) making it vulnerable to a 'dictionary attack'.
        +- An error will only affect one ciphertext block.
        +
        +Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
        +- a multiple of 64 bits are enciphered at a time.
        +- The CBC mode produces the same ciphertext whenever the same
        +  plaintext is encrypted using the same key and starting variable.
        +- The chaining operation makes the ciphertext blocks dependent on the
        +  current and all preceding plaintext blocks and therefore blocks can not
        +  be rearranged.
        +- The use of different starting variables prevents the same plaintext
        +  enciphering to the same ciphertext.
        +- An error will affect the current and the following ciphertext blocks.
        +
        +Cipher Feedback Mode (CFB) (des_cfb_encrypt())
        +- a number of bits (j) <= 64 are enciphered at a time.
        +- The CFB mode produces the same ciphertext whenever the same
        +  plaintext is encrypted using the same key and starting variable.
        +- The chaining operation makes the ciphertext variables dependent on the
        +  current and all preceding variables and therefore j-bit variables are
        +  chained together and can not be rearranged.
        +- The use of different starting variables prevents the same plaintext
        +  enciphering to the same ciphertext.
        +- The strength of the CFB mode depends on the size of k (maximal if
        +  j == k).  In my implementation this is always the case.
        +- Selection of a small value for j will require more cycles through
        +  the encipherment algorithm per unit of plaintext and thus cause
        +  greater processing overheads.
        +- Only multiples of j bits can be enciphered.
        +- An error will affect the current and the following ciphertext variables.
        +
        +Output Feedback Mode (OFB) (des_ofb_encrypt())
        +- a number of bits (j) <= 64 are enciphered at a time.
        +- The OFB mode produces the same ciphertext whenever the same
        +  plaintext enciphered using the same key and starting variable.  More
        +  over, in the OFB mode the same key stream is produced when the same
        +  key and start variable are used.  Consequently, for security reasons
        +  a specific start variable should be used only once for a given key.
        +- The absence of chaining makes the OFB more vulnerable to specific attacks.
        +- The use of different start variables values prevents the same
        +  plaintext enciphering to the same ciphertext, by producing different
        +  key streams.
        +- Selection of a small value for j will require more cycles through
        +  the encipherment algorithm per unit of plaintext and thus cause
        +  greater processing overheads.
        +- Only multiples of j bits can be enciphered.
        +- OFB mode of operation does not extend ciphertext errors in the
        +  resultant plaintext output.  Every bit error in the ciphertext causes
        +  only one bit to be in error in the deciphered plaintext.
        +- OFB mode is not self-synchronising.  If the two operation of
        +  encipherment and decipherment get out of synchronism, the system needs
        +  to be re-initialised.
        +- Each re-initialisation should use a value of the start variable
        + different from the start variable values used before with the same
        + key.  The reason for this is that an identical bit stream would be
        + produced each time from the same parameters.  This would be
        + susceptible to a ' known plaintext' attack.
        +
        +Triple ECB Mode (des_ecb3_encrypt())
        +- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
        +- As for ECB encryption but increases the key length to 168 bits.
        +  There are theoretic attacks that can be used that make the effective
        +  key length 112 bits, but this attack also requires 2^56 blocks of
        +  memory, not very likely, even for the NSA.
        +- If both keys are the same it is equivalent to encrypting once with
        +  just one key.
        +- If the first and last key are the same, the key length is 112 bits.
        +  There are attacks that could reduce the key space to 55 bit's but it
        +  requires 2^56 blocks of memory.
        +- If all 3 keys are the same, this is effectively the same as normal
        +  ecb mode.
        +
        +Triple CBC Mode (des_ede3_cbc_encrypt())
        +- Encrypt with key1, decrypt with key2 and then encrypt with key3.
        +- As for CBC encryption but increases the key length to 168 bits with
        +  the same restrictions as for triple ecb mode.
        +
        +==== digest.doc ========================================================
        +
        +
        +The Message Digest subroutines.
        +
        +These routines require "evp.h" to be included.
        +
        +These functions are a higher level interface to the various message digest
        +routines found in this library.  As such, they allow the same code to be
        +used to digest via different algorithms with only a change in an initial
        +parameter.  They are basically just a front-end to the MD2, MD5, SHA
        +and SHA1
        +routines.
        +
        +These routines all take a pointer to the following structure to specify
        +which message digest algorithm to use.
        +typedef struct evp_md_st
        +	{
        +	int type;
        +	int pkey_type;
        +	int md_size;
        +	void (*init)();
        +	void (*update)();
        +	void (*final)();
        +
        +	int required_pkey_type; /*EVP_PKEY_xxx */
        +	int (*sign)();
        +	int (*verify)();
        +	} EVP_MD;
        +
        +If additional message digest algorithms are to be supported, a structure of
        +this type needs to be declared and populated and then the Digest routines
        +can be used with that algorithm.  The type field is the object NID of the
        +digest type (read the section on Objects for an explanation).  The pkey_type
        +is the Object type to use when the a message digest is generated by there
        +routines and then is to be signed with the pkey algorithm.  Md_size is
        +the size of the message digest returned.  Init, update
        +and final are the relevant functions to perform the message digest function
        +by parts.  One reason for specifying the message digest to use via this
        +mechanism is that if you only use md5, only the md5 routines will
        +be included in you linked program.  If you passed an integer
        +that specified which message digest to use, the routine that mapped that
        +integer to a set of message digest functions would cause all the message
        +digests functions to be link into the code.  This setup also allows new
        +message digest functions to be added by the application.
        +
        +The six message digests defined in this library are
        +
        +EVP_MD *EVP_md2(void);	/* RSA sign/verify */
        +EVP_MD *EVP_md5(void);	/* RSA sign/verify */
        +EVP_MD *EVP_sha(void);	/* RSA sign/verify */
        +EVP_MD *EVP_sha1(void);	/* RSA sign/verify */
        +EVP_MD *EVP_dss(void);	/* DSA sign/verify */
        +EVP_MD *EVP_dss1(void);	/* DSA sign/verify */
        +
        +All the message digest routines take a EVP_MD_CTX pointer as an argument.
        +The state of the message digest is kept in this structure.
        +
        +typedef struct pem_md_ctx_st
        +	{
        +	EVP_MD *digest;
        +	union	{
        +		unsigned char base[4]; /* this is used in my library as a
        +					* 'pointer' to all union elements
        +					* structures. */
        +		MD2_CTX md2;
        +		MD5_CTX md5;
        +		SHA_CTX sha;
        +		} md;
        +	} EVP_MD_CTX;
        +
        +The Digest functions are as follows.
        +
        +void EVP_DigestInit(
        +EVP_MD_CTX *ctx,
        +EVP_MD *type);
        +	This function is used to initialise the EVP_MD_CTX.  The message
        +	digest that will associated with 'ctx' is specified by 'type'.
        +
        +void EVP_DigestUpdate(
        +EVP_MD_CTX *ctx,
        +unsigned char *data,
        +unsigned int cnt);
        +	This function is used to pass more data to the message digest
        +	function.  'cnt' bytes are digested from 'data'.
        +
        +void EVP_DigestFinal(
        +EVP_MD_CTX *ctx,
        +unsigned char *md,
        +unsigned int *len);
        +	This function finishes the digestion and puts the message digest
        +	into 'md'.  The length of the message digest is put into len;
        +	EVP_MAX_MD_SIZE is the size of the largest message digest that
        +	can be returned from this function.  Len can be NULL if the
        +	size of the digest is not required.
        +	
        +
        +==== encode.doc ========================================================
        +
        +
        +void    EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
        +void    EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,
        +		int *outl,unsigned char *in,int inl);
        +void    EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
        +int     EVP_EncodeBlock(unsigned char *t, unsigned char *f, int n);
        +
        +void    EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
        +int     EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
        +		unsigned char *in, int inl);
        +int     EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
        +		char *out, int *outl);
        +int     EVP_DecodeBlock(unsigned char *t, unsigned
        +		char *f, int n);
        +
        +
        +==== envelope.doc ========================================================
        +
        +The following routines are use to create 'digital' envelopes.
        +By this I mean that they perform various 'higher' level cryptographic
        +functions.  Have a read of 'cipher.doc' and 'digest.doc' since those
        +routines are used by these functions.
        +cipher.doc contains documentation about the cipher part of the
        +envelope library and digest.doc contatins the description of the
        +message digests supported.
        +
        +To 'sign' a document involves generating a message digest and then encrypting
        +the digest with an private key.
        +
        +#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
        +#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
        +Due to the fact this operation is basically just an extended message
        +digest, the first 2 functions are macro calls to Digest generating
        +functions.
        +
        +int     EVP_SignFinal(
        +EVP_MD_CTX *ctx,
        +unsigned char *md,
        +unsigned int *s,
        +EVP_PKEY *pkey);
        +	This finalisation function finishes the generation of the message
        +digest and then encrypts the digest (with the correct message digest 
        +object identifier) with the EVP_PKEY private key.  'ctx' is the message digest
        +context.  'md' will end up containing the encrypted message digest.  This
        +array needs to be EVP_PKEY_size(pkey) bytes long.  's' will actually
        +contain the exact length.  'pkey' of course is the private key.  It is
        +one of EVP_PKEY_RSA or EVP_PKEY_DSA type.
        +If there is an error, 0 is returned, otherwise 1.
        +		
        +Verify is used to check an signed message digest.
        +
        +#define EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
        +#define EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
        +Since the first step is to generate a message digest, the first 2 functions
        +are macros.
        +
        +int EVP_VerifyFinal(
        +EVP_MD_CTX *ctx,
        +unsigned char *md,
        +unsigned int s,
        +EVP_PKEY *pkey);
        +	This function finishes the generation of the message digest and then
        +compares it with the supplied encrypted message digest.  'md' contains the
        +'s' bytes of encrypted message digest.  'pkey' is used to public key decrypt
        +the digest.  It is then compared with the message digest just generated.
        +If they match, 1 is returned else 0.
        +
        +int	EVP_SealInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char **ek,
        +		int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk);
        +Must have at least one public key, error is 0.  I should also mention that
        +the buffers pointed to by 'ek' need to be EVP_PKEY_size(pubk[n]) is size.
        +
        +#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
        +void	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
        +
        +
        +int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek,
        +		int ekl,unsigned char *iv,EVP_PKEY *priv);
        +0 on failure
        +
        +#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
        +
        +int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
        +Decrypt final return code
        +
        +
        +==== error.doc ========================================================
        +
        +The error routines.
        +
        +The 'error' system I've implemented is intended to server 2 purpose, to
        +record the reason why a command failed and to record where in the libraries
        +the failure occurred.  It is more or less setup to record a 'trace' of which
        +library components were being traversed when the error occurred.
        +
        +When an error is recorded, it is done so a as single unsigned long which is
        +composed of three parts.  The top byte is the 'library' number, the middle
        +12 bytes is the function code, and the bottom 12 bits is the 'reason' code.
        +
        +Each 'library', or should a say, 'section' of the SSLeay library has a
        +different unique 'library' error number.  Each function in the library has
        +a number that is unique for that library.  Each 'library' also has a number
        +for each 'error reason' that is only unique for that 'library'.
        +
        +Due to the way these error routines record a 'error trace', there is an
        +array per thread that is used to store the error codes.
        +The various functions in this library are used to access
        +and manipulate this array.
        +
        +void ERR_put_error(int lib, int func,int reason);
        +	This routine records an error in library 'lib', function 'func'
        +and reason 'reason'.  As errors get 'put' into the buffer, they wrap
        +around and overwrite old errors if too many are written.  It is assumed
        +that the last errors are the most important.
        +
        +unsigned long ERR_get_error(void );
        +	This function returns the last error added to the error buffer.
        +In effect it is popping the value off the buffer so repeated calls will
        +continue to return values until there are no more errors to return in which
        +case 0 is returned.
        +
        +unsigned long ERR_peek_error(void );
        +	This function returns the value of the last error added to the
        +error buffer but does not 'pop' it from the buffer.
        +
        +void ERR_clear_error(void );
        +	This function clears the error buffer, discarding all unread
        +errors.
        +
        +While the above described error system obviously produces lots of different
        +error number, a method for 'reporting' these errors in a human readable
        +form is required.  To achieve this, each library has the option of
        +'registering' error strings.
        +
        +typedef struct ERR_string_data_st
        +	{
        +	unsigned long error;
        +	char *string;
        +	} ERR_STRING_DATA;
        +
        +The 'ERR_STRING_DATA' contains an error code and the corresponding text
        +string.  To add new function error strings for a library, the
        +ERR_STRING_DATA needs to be 'registered' with the library.
        +
        +void ERR_load_strings(unsigned long lib,ERR_STRING_DATA *err);
        +	This function 'registers' the array of ERR_STRING_DATA pointed to by
        +'err' as error text strings for the error library 'lib'.
        +
        +void ERR_free_strings(void);
        +	This function free()s all the loaded error strings.
        +
        +char *ERR_error_string(unsigned long error,char *buf);
        +	This function returns a text string that is a human readable
        +version of the error represented by 'error'.  Buff should be at least 120
        +bytes long and if it is NULL, the return value is a pointer to a static
        +variable that will contain the error string, otherwise 'buf' is returned.
        +If there is not a text string registered for a particular error, a text
        +string containing the error number is returned instead.
        +
        +void ERR_print_errors(BIO *bp);
        +void ERR_print_errors_fp(FILE *fp);
        +	This function is a convenience routine that prints the error string
        +for each error until all errors have been accounted for.
        +
        +char *ERR_lib_error_string(unsigned long e);
        +char *ERR_func_error_string(unsigned long e);
        +char *ERR_reason_error_string(unsigned long e);
        +The above three functions return the 3 different components strings for the
        +error 'e'.  ERR_error_string() uses these functions.
        +
        +void ERR_load_ERR_strings(void );
        +	This function 'registers' the error strings for the 'ERR' module.
        +
        +void ERR_load_crypto_strings(void );
        +	This function 'register' the error strings for just about every
        +library in the SSLeay package except for the SSL routines.  There is no
        +need to ever register any error text strings and you will probably save in
        +program size.  If on the other hand you do 'register' all errors, it is
        +quite easy to determine why a particular routine failed.
        +
        +As a final footnote as to why the error system is designed as it is.
        +1) I did not want a single 'global' error code.
        +2) I wanted to know which subroutine a failure occurred in.
        +3) For Windows NT etc, it should be simple to replace the 'key' routines
        +   with code to pass error codes back to the application.
        +4) I wanted the option of meaningful error text strings.
        +
        +Late breaking news - the changes to support threads.
        +
        +Each 'thread' has an 'ERR_STATE' state associated with it.
        +ERR_STATE *ERR_get_state(void ) will return the 'state' for the calling
        +thread/process.
        +
        +ERR_remove_state(unsigned long pid); will 'free()' this state.  If pid == 0
        +the current 'thread/process' will have it's error state removed.
        +If you do not remove the error state of a thread, this could be considered a
        +form of memory leak, so just after 'reaping' a thread that has died,
        +call ERR_remove_state(pid).
        +
        +Have a read of thread.doc for more details for what is required for
        +multi-threading support.  All the other error routines will
        +work correctly when using threads.
        +
        +
        +==== idea.doc ========================================================
        +
        +The IDEA library.
        +IDEA is a block cipher that operates on 64bit (8 byte) quantities.  It
        +uses a 128bit (16 byte) key.  It can be used in all the modes that DES can
        +be used.  This library implements the ecb, cbc, cfb64 and ofb64 modes.
        +
        +For all calls that have an 'input' and 'output' variables, they can be the
        +same.
        +
        +This library requires the inclusion of 'idea.h'.
        +
        +All of the encryption functions take what is called an IDEA_KEY_SCHEDULE as an 
        +argument.  An IDEA_KEY_SCHEDULE is an expanded form of the idea key.
        +For all modes of the IDEA algorithm, the IDEA_KEY_SCHEDULE used for
        +decryption is different to the one used for encryption.
        +
        +The define IDEA_ENCRYPT is passed to specify encryption for the functions
        +that require an encryption/decryption flag. IDEA_DECRYPT is passed to
        +specify decryption.  For some mode there is no encryption/decryption
        +flag since this is determined by the IDEA_KEY_SCHEDULE.
        +
        +So to encrypt you would do the following
        +idea_set_encrypt_key(key,encrypt_ks);
        +idea_ecb_encrypt(...,encrypt_ks);
        +idea_cbc_encrypt(....,encrypt_ks,...,IDEA_ENCRYPT);
        +
        +To Decrypt
        +idea_set_encrypt_key(key,encrypt_ks);
        +idea_set_decrypt_key(encrypt_ks,decrypt_ks);
        +idea_ecb_encrypt(...,decrypt_ks);
        +idea_cbc_encrypt(....,decrypt_ks,...,IDEA_DECRYPT);
        +
        +Please note that any of the encryption modes specified in my DES library
        +could be used with IDEA.  I have only implemented ecb, cbc, cfb64 and
        +ofb64 for the following reasons.
        +- ecb is the basic IDEA encryption.
        +- cbc is the normal 'chaining' form for block ciphers.
        +- cfb64 can be used to encrypt single characters, therefore input and output
        +  do not need to be a multiple of 8.
        +- ofb64 is similar to cfb64 but is more like a stream cipher, not as
        +  secure (not cipher feedback) but it does not have an encrypt/decrypt mode.
        +- If you want triple IDEA, thats 384 bits of key and you must be totally
        +  obsessed with security.  Still, if you want it, it is simple enough to
        +  copy the function from the DES library and change the des_encrypt to
        +  idea_encrypt; an exercise left for the paranoid reader :-).
        +
        +The functions are as follows:
        +
        +void idea_set_encrypt_key(
        +unsigned char *key;
        +IDEA_KEY_SCHEDULE *ks);
        +	idea_set_encrypt_key converts a 16 byte IDEA key into an
        +	IDEA_KEY_SCHEDULE.  The IDEA_KEY_SCHEDULE is an expanded form of
        +	the key which can be used to perform IDEA encryption.
        +	An IDEA_KEY_SCHEDULE is an expanded form of the key which is used to
        +	perform actual encryption.  It can be regenerated from the IDEA key
        +	so it only needs to be kept when encryption is about
        +	to occur.  Don't save or pass around IDEA_KEY_SCHEDULE's since they
        +	are CPU architecture dependent, IDEA keys are not.
        +	
        +void idea_set_decrypt_key(
        +IDEA_KEY_SCHEDULE *encrypt_ks,
        +IDEA_KEY_SCHEDULE *decrypt_ks);
        +	This functions converts an encryption IDEA_KEY_SCHEDULE into a
        +	decryption IDEA_KEY_SCHEDULE.  For all decryption, this conversion
        +	of the key must be done.  In some modes of IDEA, an
        +	encryption/decryption flag is also required, this is because these
        +	functions involve block chaining and the way this is done changes
        +	depending on which of encryption of decryption is being done.
        +	Please note that there is no quick way to generate the decryption
        +	key schedule other than generating the encryption key schedule and
        +	then converting it.
        +
        +void idea_encrypt(
        +unsigned long *data,
        +IDEA_KEY_SCHEDULE *ks);
        +	This is the IDEA encryption function that gets called by just about
        +	every other IDEA routine in the library.  You should not use this
        +	function except to implement 'modes' of IDEA.  I say this because the
        +	functions that call this routine do the conversion from 'char *' to
        +	long, and this needs to be done to make sure 'non-aligned' memory
        +	access do not occur.
        +	Data is a pointer to 2 unsigned long's and ks is the
        +	IDEA_KEY_SCHEDULE to use.  Encryption or decryption depends on the
        +	IDEA_KEY_SCHEDULE.
        +
        +void idea_ecb_encrypt(
        +unsigned char *input,
        +unsigned char *output,
        +IDEA_KEY_SCHEDULE *ks);
        +	This is the basic Electronic Code Book form of IDEA (in DES this
        +	mode is called Electronic Code Book so I'm going to use the term
        +	for idea as well :-).
        +	Input is encrypted into output using the key represented by
        +	ks.  Depending on the IDEA_KEY_SCHEDULE, encryption or
        +	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
        +	
        +void idea_cbc_encrypt(
        +unsigned char *input,
        +unsigned char *output,
        +long length,
        +IDEA_KEY_SCHEDULE *ks,
        +unsigned char *ivec,
        +int enc);
        +	This routine implements IDEA in Cipher Block Chaining mode.
        +	Input, which should be a multiple of 8 bytes is encrypted
        +	(or decrypted) to output which will also be a multiple of 8 bytes.
        +	The number of bytes is in length (and from what I've said above,
        +	should be a multiple of 8).  If length is not a multiple of 8, bad 
        +	things will probably happen.  ivec is the initialisation vector.
        +	This function updates iv after each call so that it can be passed to
        +	the next call to idea_cbc_encrypt().
        +	
        +void idea_cfb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int *num,
        +int enc);
        +	This is one of the more useful functions in this IDEA library, it
        +	implements CFB mode of IDEA with 64bit feedback.
        +	This allows you to encrypt an arbitrary number of bytes,
        +	you do not require 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  Num contains 'how far' we are though ivec.
        +	Enc is used to indicate encryption or decryption.
        +	One very important thing to remember is that when decrypting, use
        +	the encryption form of the key.
        +	CFB64 mode operates by using the cipher to
        +	generate a stream of bytes which is used to encrypt the plain text.
        +	The cipher text is then encrypted to generate the next 64 bits to
        +	be xored (incrementally) with the next 64 bits of plain
        +	text.  As can be seen from this, to encrypt or decrypt,
        +	the same 'cipher stream' needs to be generated but the way the next
        +	block of data is gathered for encryption is different for
        +	encryption and decryption.  What this means is that to encrypt
        +	idea_set_encrypt_key(key,ks);
        +	idea_cfb64_encrypt(...,ks,..,IDEA_ENCRYPT)
        +	do decrypt
        +	idea_set_encrypt_key(key,ks)
        +	idea_cfb64_encrypt(...,ks,...,IDEA_DECRYPT)
        +	Note: The same IDEA_KEY_SCHEDULE but different encryption flags.
        +	For idea_cbc or idea_ecb, idea_set_decrypt_key() would need to be
        +	used to generate the IDEA_KEY_SCHEDULE for decryption.
        +	The reason I'm stressing this point is that I just wasted 3 hours
        +	today trying to decrypt using this mode and the decryption form of
        +	the key :-(.
        +	
        +void idea_ofb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +des_key_schedule ks,
        +des_cblock *ivec,
        +int *num);
        +	This functions implements OFB mode of IDEA with 64bit feedback.
        +	This allows you to encrypt an arbitrary number of bytes,
        +	you do not require 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  Num contains 'how far' we are though ivec.
        +	This is in effect a stream cipher, there is no encryption or
        +	decryption mode.  The same key and iv should be used to
        +	encrypt and decrypt.
        +	
        +For reading passwords, I suggest using des_read_pw_string() from my DES library.
        +To generate a password from a text string, I suggest using MD5 (or MD2) to
        +produce a 16 byte message digest that can then be passed directly to
        +idea_set_encrypt_key().
        +
        +=====
        +For more information about the specific IDEA modes in this library
        +(ecb, cbc, cfb and ofb), read the section entitled 'Modes of DES' from the
        +documentation on my DES library.  What is said about DES is directly
        +applicable for IDEA.
        +
        +
        +==== legal.doc ========================================================
        +
        +From eay@mincom.com Thu Jun 27 00:25:45 1996
        +Received: by orb.mincom.oz.au id AA15821
        +  (5.65c/IDA-1.4.4 for eay); Wed, 26 Jun 1996 14:25:45 +1000
        +Date: Wed, 26 Jun 1996 14:25:45 +1000 (EST)
        +From: Eric Young <eay@mincom.oz.au>
        +X-Sender: eay@orb
        +To: Ken Toll <ktoll@ren.digitalage.com>
        +Cc: Eric Young <eay@mincom.oz.au>, ssl-talk@netscape.com
        +Subject: Re: Unidentified subject!
        +In-Reply-To: <9606261950.ZM28943@ren.digitalage.com>
        +Message-Id: <Pine.SOL.3.91.960626131156.28573K-100000@orb>
        +Mime-Version: 1.0
        +Content-Type: TEXT/PLAIN; charset=US-ASCII
        +Status: O
        +X-Status: 
        +
        +
        +This is a little off topic but since SSLeay is a free implementation of
        +the SSLv2 protocol, I feel it is worth responding on the topic of if it 
        +is actually legal for Americans to use free cryptographic software.
        +
        +On Wed, 26 Jun 1996, Ken Toll wrote:
        +> Is the U.S the only country that SSLeay cannot be used commercially 
        +> (because of RSAref) or is that going to be an issue with every country 
        +> that a client/server application (non-web browser/server) is deployed 
        +> and sold?
        +
        +>From what I understand, the software patents that apply to algorithms 
        +like RSA and DH only apply in the USA.  The IDEA algorithm I believe is 
        +patened in europe (USA?), but considing how little it is used by other SSL 
        +implementations, it quite easily be left out of the SSLeay build
        +(this can be done with a compile flag).
        +
        +Actually if the RSA patent did apply outside the USA, it could be rather
        +interesting since RSA is not alowed to let RSA toolkits outside of the USA
        +[1], and since these are the only forms that they will alow the algorithm
        +to be used in, it would mean that non-one outside of the USA could produce
        +public key software which would be a very strong statment for
        +international patent law to make :-).  This logic is a little flawed but
        +it still points out some of the more interesting permutations of USA
        +patent law and ITAR restrictions. 
        +
        +Inside the USA there is also the unresolved issue of RC4/RC2 which were
        +made public on sci.crypt in Sep 1994 (RC4) and Feb 1996 (RC2).  I have
        +copies of the origional postings if people are interested.  RSA I believe 
        +claim that they were 'trade-secrets' and that some-one broke an NDA in 
        +revealing them.  Other claim they reverse engineered the algorithms from 
        +compiled binaries.  If the algorithms were reverse engineered, I believe 
        +RSA had no legal leg to stand on.  If an NDA was broken, I don't know.
        +Regardless, RSA, I believe, is willing to go to court over the issue so 
        +licencing is probably the best idea, or at least talk to them.
        +If there are people who actually know more about this, pease let me know, I 
        +don't want to vilify or spread miss-information if I can help it.
        +
        +If you are not producing a web browser, it is easy to build SSLeay with
        +RC2/RC4 removed. Since RC4 is the defacto standard cipher in 
        +all web software (and it is damn fast) it is more or less required for 
        +www use. For non www use of SSL, especially for an application where 
        +interoperability with other vendors is not critical just leave it out.
        +
        +Removing IDEA, RC2 and RC4 would only leave DES and Triple DES but 
        +they should be ok.  Considing that Triple DES can encrypt at rates of
        +410k/sec on a pentium 100, and 940k/sec on a P6/200, this is quite 
        +reasonable performance.  Single DES clocks in at 1160k/s and 2467k/s
        +respectivly is actually quite fast for those not so paranoid (56 bit key).[1]
        +
        +> Is it possible to get a certificate for commercial use outside of the U.S.?
        +yes.
        +
        +Thawte Consulting issues certificates (they are the people who sell the
        +	Sioux httpd server and are based in South Africa)
        +Verisign will issue certificates for Sioux (sold from South Africa), so this
        +	proves that they will issue certificate for OS use if they are
        +	happy with the quality of the software.
        +
        +(The above mentioned companies just the ones that I know for sure are issuing
        + certificates outside the USA).
        +
        +There is always the point that if you are using SSL for an intra net, 
        +SSLeay provides programs that can be used so you can issue your own 
        +certificates.  They need polishing but at least it is a good starting point.
        +
        +I am not doing anything outside Australian law by implementing these
        +algorithms (to the best of my knowedge).  It is another example of how 
        +the world legal system does not cope with the internet very well.
        +
        +I may start making shared libraries available (I have now got DLL's for 
        +Windows).  This will mean that distributions into the usa could be 
        +shipped with a version with a reduced cipher set and the versions outside 
        +could use the DLL/shared library with all the ciphers (and without RSAref).
        +
        +This could be completly hidden from the application, so this would not 
        +even require a re-linking.
        +
        +This is the reverse of what people were talking about doing to get around 
        +USA export regulations :-)
        +
        +eric
        +
        +[1]:	The RSAref2.0 tookit is available on at least 3 ftp sites in Europe
        +	and one in South Africa.
        +
        +[2]:	Since I always get questions when I post benchmark numbers :-),
        +	DES performace figures are in 1000's of bytes per second in cbc 
        +	mode using an 8192 byte buffer.  The pentium 100 was running Windows NT 
        +	3.51 DLLs and the 686/200 was running NextStep.
        +	I quote pentium 100 benchmarks because it is basically the
        +	'entry level' computer that most people buy for personal use.
        +	Windows 95 is the OS shipping on those boxes, so I'll give
        +	NT numbers (the same Win32 runtime environment).  The 686
        +	numbers are present as an indication of where we will be in a
        +	few years.
        +--
        +Eric Young                  | BOOL is tri-state according to Bill Gates.
        +AARNet: eay@mincom.oz.au    | RTFM Win32 GetMessage().
        +
        +
        +
        +==== lhash.doc ========================================================
        +
        +The LHASH library.
        +
        +I wrote this library in 1991 and have since forgotten why I called it lhash.
        +It implements a hash table from an article I read at the
        +time from 'Communications of the ACM'.  What makes this hash
        +table different is that as the table fills, the hash table is
        +increased (or decreased) in size via realloc().
        +When a 'resize' is done, instead of all hashes being redistributed over
        +twice as many 'buckets', one bucket is split.  So when an 'expand' is done,
        +there is only a minimal cost to redistribute some values.  Subsequent
        +inserts will cause more single 'bucket' redistributions but there will
        +never be a sudden large cost due to redistributing all the 'buckets'.
        +
        +The state for a particular hash table is kept in the LHASH structure.
        +The LHASH structure also records statistics about most aspects of accessing
        +the hash table.  This is mostly a legacy of my writing this library for
        +the reasons of implementing what looked like a nice algorithm rather than
        +for a particular software product.
        +
        +Internal stuff you probably don't want to know about.
        +The decision to increase or decrease the hash table size is made depending
        +on the 'load' of the hash table.  The load is the number of items in the
        +hash table divided by the size of the hash table.  The default values are
        +as follows.  If (hash->up_load < load) => expand.
        +if (hash->down_load > load) =>  contract.  The 'up_load' has a default value of
        +1 and 'down_load' has a default value of 2.  These numbers can be modified
        +by the application by just playing with the 'up_load' and 'down_load'
        +variables.  The 'load' is kept in a form which is multiplied by 256.  So
        +hash->up_load=8*256; will cause a load of 8 to be set.
        +
        +If you are interested in performance the field to watch is
        +num_comp_calls.  The hash library keeps track of the 'hash' value for
        +each item so when a lookup is done, the 'hashes' are compared, if
        +there is a match, then a full compare is done, and
        +hash->num_comp_calls is incremented.  If num_comp_calls is not equal
        +to num_delete plus num_retrieve it means that your hash function is
        +generating hashes that are the same for different values.  It is
        +probably worth changing your hash function if this is the case because
        +even if your hash table has 10 items in a 'bucked', it can be searched
        +with 10 'unsigned long' compares and 10 linked list traverses.  This
        +will be much less expensive that 10 calls to you compare function.
        +
        +LHASH *lh_new(
        +unsigned long (*hash)(),
        +int (*cmp)());
        +	This function is used to create a new LHASH structure.  It is passed
        +	function pointers that are used to store and retrieve values passed
        +	into the hash table.  The 'hash'
        +	function is a hashing function that will return a hashed value of
        +	it's passed structure.  'cmp' is passed 2 parameters, it returns 0
        +	is they are equal, otherwise, non zero.
        +	If there are any problems (usually malloc failures), NULL is
        +	returned, otherwise a new LHASH structure is returned.  The
        +	hash value is normally truncated to a power of 2, so make sure
        +	that your hash function returns well mixed low order bits.
        +	
        +void lh_free(
        +LHASH *lh);
        +	This function free()s a LHASH structure.  If there is malloced
        +	data in the hash table, it will not be freed.  Consider using the
        +	lh_doall function to deallocate any remaining entries in the hash
        +	table.
        +	
        +char *lh_insert(
        +LHASH *lh,
        +char *data);
        +	This function inserts the data pointed to by data into the lh hash
        +	table.  If there is already and entry in the hash table entry, the
        +	value being replaced is returned.  A NULL is returned if the new
        +	entry does not clash with an entry already in the table (the normal
        +	case) or on a malloc() failure (perhaps I should change this....).
        +	The 'char *data' is exactly what is passed to the hash and
        +	comparison functions specified in lh_new().
        +	
        +char *lh_delete(
        +LHASH *lh,
        +char *data);
        +	This routine deletes an entry from the hash table.  The value being
        +	deleted is returned.  NULL is returned if there is no such value in
        +	the hash table.
        +
        +char *lh_retrieve(
        +LHASH *lh,
        +char *data);
        +	If 'data' is in the hash table it is returned, else NULL is
        +	returned.  The way these routines would normally be uses is that a
        +	dummy structure would have key fields populated and then
        +	ret=lh_retrieve(hash,&dummy);.  Ret would now be a pointer to a fully
        +	populated structure.
        +
        +void lh_doall(
        +LHASH *lh,
        +void (*func)(char *a));
        +	This function will, for every entry in the hash table, call function
        +	'func' with the data item as parameters.
        +	This function can be quite useful when used as follows.
        +	void cleanup(STUFF *a)
        +		{ STUFF_free(a); }
        +	lh_doall(hash,cleanup);
        +	lh_free(hash);
        +	This can be used to free all the entries, lh_free() then
        +	cleans up the 'buckets' that point to nothing.  Be careful
        +	when doing this.  If you delete entries from the hash table,
        +	in the call back function, the table may decrease in size,
        +	moving item that you are
        +	currently on down lower in the hash table.  This could cause
        +	some entries to be skipped.  The best solution to this problem
        +	is to set lh->down_load=0 before you start.  This will stop
        +	the hash table ever being decreased in size.
        +
        +void lh_doall_arg(
        +LHASH *lh;
        +void(*func)(char *a,char *arg));
        +char *arg;
        +	This function is the same as lh_doall except that the function
        +	called will be passed 'arg' as the second argument.
        +	
        +unsigned long lh_strhash(
        +char *c);
        +	This function is a demo string hashing function.  Since the LHASH
        +	routines would normally be passed structures, this routine would
        +	not normally be passed to lh_new(), rather it would be used in the
        +	function passed to lh_new().
        +
        +The next three routines print out various statistics about the state of the
        +passed hash table.  These numbers are all kept in the lhash structure.
        +
        +void lh_stats(
        +LHASH *lh,
        +FILE *out);
        +	This function prints out statistics on the size of the hash table,
        +	how many entries are in it, and the number and result of calls to
        +	the routines in this library.
        +
        +void lh_node_stats(
        +LHASH *lh,
        +FILE *out);
        +	For each 'bucket' in the hash table, the number of entries is
        +	printed.
        +	
        +void lh_node_usage_stats(
        +LHASH *lh,
        +FILE *out);
        +	This function prints out a short summary of the state of the hash
        +	table.  It prints what I call the 'load' and the 'actual load'.
        +	The load is the average number of data items per 'bucket' in the
        +	hash table.  The 'actual load' is the average number of items per
        +	'bucket', but only for buckets which contain entries.  So the
        +	'actual load' is the average number of searches that will need to
        +	find an item in the hash table, while the 'load' is the average number
        +	that will be done to record a miss.
        +
        +==== md2.doc ========================================================
        +
        +The MD2 library.
        +MD2 is a message digest algorithm that can be used to condense an arbitrary
        +length message down to a 16 byte hash.  The functions all need to be passed
        +a MD2_CTX which is used to hold the MD2 context during multiple MD2_Update()
        +function calls.  The normal method of use for this library is as follows
        +
        +MD2_Init(...);
        +MD2_Update(...);
        +...
        +MD2_Update(...);
        +MD2_Final(...);
        +
        +This library requires the inclusion of 'md2.h'.
        +
        +The main negative about MD2 is that it is slow, especially when compared
        +to MD5.
        +
        +The functions are as follows:
        +
        +void MD2_Init(
        +MD2_CTX *c);
        +	This function needs to be called to initiate a MD2_CTX structure for
        +	use.
        +	
        +void MD2_Update(
        +MD2_CTX *c;
        +unsigned char *data;
        +unsigned long len);
        +	This updates the message digest context being generated with 'len'
        +	bytes from the 'data' pointer.  The number of bytes can be any
        +	length.
        +
        +void MD2_Final(
        +unsigned char *md;
        +MD2_CTX *c;
        +	This function is called when a message digest of the data digested
        +	with MD2_Update() is wanted.  The message digest is put in the 'md'
        +	array and is MD2_DIGEST_LENGTH (16) bytes long.
        +
        +unsigned char *MD2(
        +unsigned long n;
        +unsigned char *d;
        +unsigned char *md;
        +	This function performs a MD2_Init(), followed by a MD2_Update()
        +	followed by a MD2_Final() (using a local MD2_CTX).
        +	The resulting digest is put into 'md' if it is not NULL.
        +	Regardless of the value of 'md', the message
        +	digest is returned from the function.  If 'md' was NULL, the message
        +	digest returned is being stored in a static structure.
        +
        +==== md5.doc ========================================================
        +
        +The MD5 library.
        +MD5 is a message digest algorithm that can be used to condense an arbitrary
        +length message down to a 16 byte hash.  The functions all need to be passed
        +a MD5_CTX which is used to hold the MD5 context during multiple MD5_Update()
        +function calls.  This library also contains random number routines that are
        +based on MD5
        +
        +The normal method of use for this library is as follows
        +
        +MD5_Init(...);
        +MD5_Update(...);
        +...
        +MD5_Update(...);
        +MD5_Final(...);
        +
        +This library requires the inclusion of 'md5.h'.
        +
        +The functions are as follows:
        +
        +void MD5_Init(
        +MD5_CTX *c);
        +	This function needs to be called to initiate a MD5_CTX structure for
        +	use.
        +	
        +void MD5_Update(
        +MD5_CTX *c;
        +unsigned char *data;
        +unsigned long len);
        +	This updates the message digest context being generated with 'len'
        +	bytes from the 'data' pointer.  The number of bytes can be any
        +	length.
        +
        +void MD5_Final(
        +unsigned char *md;
        +MD5_CTX *c;
        +	This function is called when a message digest of the data digested
        +	with MD5_Update() is wanted.  The message digest is put in the 'md'
        +	array and is MD5_DIGEST_LENGTH (16) bytes long.
        +
        +unsigned char *MD5(
        +unsigned char *d;
        +unsigned long n;
        +unsigned char *md;
        +	This function performs a MD5_Init(), followed by a MD5_Update()
        +	followed by a MD5_Final() (using a local MD5_CTX).
        +	The resulting digest is put into 'md' if it is not NULL.
        +	Regardless of the value of 'md', the message
        +	digest is returned from the function.  If 'md' was NULL, the message
        +	digest returned is being stored in a static structure.
        +
        +
        +==== memory.doc ========================================================
        +
        +In the interests of debugging SSLeay, there is an option to compile
        +using some simple memory leak checking.
        +
        +All malloc(), free() and realloc() calls in SSLeay now go via
        +Malloc(), Free() and Realloc() (except those in crypto/lhash).
        +
        +If CRYPTO_MDEBUG is defined, these calls are #defined to
        +CRYPTO_malloc(), CRYPTO_free() and CRYPTO_realloc().
        +If it is not defined, they are #defined to malloc(), free() and realloc().
        +
        +the CRYPTO_malloc() routines by default just call the underlying library
        +functons.
        +
        +If CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) is called, memory leak detection is
        +turned on.  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) turns it off.
        +
        +When turned on, each Malloc() or Realloc() call is recored along with the file
        +and line number from where the call was made.   (This is done using the
        +lhash library which always uses normal system malloc(3) routines).
        +
        +void CRYPTO_mem_leaks(BIO *b);
        +void CRYPTO_mem_leaks_fp(FILE *fp);
        +These both print out the list of memory that has not been free()ed.
        +This will probably be rather hard to read, but if you look for the 'top level'
        +structure allocation, this will often give an idea as to what is not being
        +free()ed.  I don't expect people to use this stuff normally.
        +
        +==== ca.1 ========================================================
        +
        +From eay@orb.mincom.oz.au Thu Dec 28 23:56:45 1995
        +Received: by orb.mincom.oz.au id AA07374
        +  (5.65c/IDA-1.4.4 for eay); Thu, 28 Dec 1995 13:56:45 +1000
        +Date: Thu, 28 Dec 1995 13:56:45 +1000 (EST)
        +From: Eric Young <eay@mincom.oz.au>
        +X-Sender: eay@orb
        +To: sameer <sameer@c2.org>
        +Cc: ssleay@mincom.oz.au
        +Subject: Re: 'ca'
        +In-Reply-To: <199512230440.UAA23410@infinity.c2.org>
        +Message-Id: <Pine.SOL.3.91.951228133525.7269A-100000@orb>
        +Mime-Version: 1.0
        +Content-Type: TEXT/PLAIN; charset=US-ASCII
        +Status: RO
        +X-Status: 
        +
        +On Fri, 22 Dec 1995, sameer wrote:
        +> 	I could use documentation on 'ca'. Thanks.
        +
        +Very quickly.
        +The ca program uses the ssleay.conf file for most of its configuration
        +
        +./ca -help
        +
        + -verbose        - Talk alot while doing things
        + -config file    - A config file. If you don't want to use the
        +		   default config file
        + -name arg       - The particular CA definition to use
        +	In the config file, the section to use for parameters.  This lets 
        +	multiple setups to be contained in the one file.  By default, the 
        +	default_ca variable is looked up in the [ ca ] section.  So in the 
        +	shipped ssleay.conf, the CA definition used is CA_default.  It could be 
        +	any other name.
        + -gencrl days    - Generate a new CRL, days is when the next CRL is due
        +	This will generate a new certificate revocion list.
        + -days arg       - number of days to certify the certificate for
        +	When certifiying certificates, this is the number of days to use.
        + -md arg         - md to use, one of md2, md5, sha or sha1
        + -policy arg     - The CA 'policy' to support
        +	I'll describe this later, but there are 2 policies definied in the 
        +	shipped ssleay.conf
        + -keyfile arg    - PEM RSA private key file
        + -key arg        - key to decode the RSA private key if it is encrypted
        +	since we need to keep the CA's RSA key encrypted
        + -cert           - The CA certificate
        + -in file        - The input PEM encoded certificate request(s)
        + -out file       - Where to put the output file(s)
        + -outdir dir     - Where to put output certificates
        +	The -out options concatinates all the output certificied
        +	certificates to one file, -outdir puts them in a directory,
        +	named by serial number.
        + -infiles ....   - The last argument, requests to process
        +	The certificate requests to process, -in is the same.
        +
        +Just about all the above have default values defined in ssleay.conf.
        +
        +The key variables in ssleay.conf are (for the pariticular '-name' being 
        +used, in the default, it is CA_default).
        +
        +dir is where all the CA database stuff is kept.
        +certs is where all the previously issued certificates are kept.
        +The database is a simple text database containing the following tab separated 
        +fields.
        +status: a value of 'R' - revoked, 'E' -expired or 'V' valid.
        +issued date:  When the certificate was certified.
        +revoked date:  When it was revoked, blank if not revoked.
        +serial number:  The certificate serial number.
        +certificate:	Where the certificate is located.
        +CN:	The name of the certificate.
        +
        +The demo file has quite a few made up values it it.  The last 2 were 
        +added by the ca program and are acurate.
        +The CA program does not update the 'certificate' file correctly right now.
        +The serial field should be unique as should the CN/status combination.
        +The ca program checks these at startup.  What still needs to be 
        +wrtten is a program to 'regenerate' the data base file from the issued 
        +certificate list (and a CRL list).
        +
        +Back to the CA_default variables.
        +
        +Most of the variables are commented.
        +
        +policy is the default policy.
        +
        +Ok for policies, they define the order and which fields must be present 
        +in the certificate request and what gets filled in.
        +
        +So a value of
        +countryName             = match
        +means that the country name must match the CA certificate.
        +organizationalUnitName  = optional
        +The org.Unit,Name does not have to be present and
        +commonName              = supplied
        +commonName must be supplied in the certificate request.
        +
        +For the 'policy_match' polocy, the order of the attributes in the 
        +generated certiticate would be
        +countryName
        +stateOrProvinceName
        +organizationName
        +organizationalUnitName
        +commonName
        +emailAddress
        +
        +Have a play, it sort of makes sense.  If you think about how the persona 
        +requests operate, it is similar to the 'policy_match' policy and the
        +'policy_anything' is similar to what versign is doing.
        +
        +I hope this helps a bit.  Some backend scripts are definitly needed to 
        +update the database and to make certificate revocion easy.  All 
        +certificates issued should also be kept forever (or until they expire?)
        +
        +hope this helps
        +eric (who has to run off an buy some cheap knee pads for the caving in 4 
        +days time :-)
        +
        +--
        +Eric Young                  | Signature removed since it was generating
        +AARNet: eay@mincom.oz.au    | more followups than the message contents :-)
        +
        +
        +==== ms3-ca.doc ========================================================
        +
        +Date: Mon, 9 Jun 97 08:00:33 +0200
        +From: Holger.Reif@PrakInf.TU-Ilmenau.DE (Holger Reif)
        +Subject: ms3-ca.doc
        +Organization: TU Ilmenau, Fak. IA, FG Telematik
        +Content-Length: 14575
        +Status: RO
        +X-Status: 
        +
        +Loading client certs into MSIE 3.01
        +===================================
        +
        +This document contains all the information necessary to successfully set up 
        +some scripts to issue client certs to Microsoft Internet Explorer. It 
        +includes the required knowledge about the model MSIE uses for client 
        +certification and includes complete sample scripts ready to play with. The 
        +scripts were tested against a modified ca program of SSLeay 0.6.6 and should 
        +work with the regular ca program that comes with version 0.8.0. I haven't 
        +tested against MSIE 4.0
        +
        +You can use the information contained in this document in either way you 
        +want. However if you feel it saved you a lot of time I ask you to be as fair 
        +as to mention my name: Holger Reif <reif@prakinf.tu-ilmenau.de>.
        +
        +1.) The model used by MSIE
        +--------------------------
        +
        +The Internet Explorer doesn't come with a embedded engine for installing 
        +client certs like Netscape's Navigator. It rather uses the CryptoAPI (CAPI) 
        +defined by Microsoft. CAPI comes with WindowsNT 4.0 or is installed together 
        +with Internet Explorer since 3.01. The advantage of this approach is a higher 
        +flexibility because the certificates in the (per user) system open 
        +certificate store may be used by other applications as well. The drawback 
        +however is that you need to do a bit more work to get a client cert issued.
        +
        +CAPI defines functions which will handle basic cryptographic work, eg. 
        +generating keys, encrypting some data, signing text or building a certificate 
        +request. The procedure is as follows: A CAPI function generates you a key 
        +pair and saves it into the certificate store. After that one builds a 
        +Distinguished Name. Together with that key pair another CAPI function forms a 
        +PKCS#10 request which you somehow need to submit to a CA. Finally the issued 
        +cert is given to a yet another CAPI function which saves it into the 
        +certificate store.
        +
        +The certificate store with the user's keys and certs is in the registry. You 
        +will find it under HKEY_CURRENT_USER/Software/Microsoft/Cryptography/ (I 
        +leave it to you as a little exercise to figure out what all the entries mean 
        +;-). Note that the keys are protected only with the user's usual Windows 
        +login password.
        +
        +2.) The practical usage
        +-----------------------
        +
        +Unfortunatly since CAPI is a system API you can't access its functions from 
        +HTML code directly. For this purpose Microsoft provides a wrapper called 
        +certenr3.dll. This DLL accesses the CAPI functions and provides an interface 
        +usable from Visual Basic Script. One needs to install that library on the 
        +computer which wants to have client cert. The easiest way is to load it as an 
        +ActiveX control (certenr3.dll is properly authenticode signed by MS ;-). If 
        +you have ever enrolled e cert request at a CA you will have installed it.
        +
        +At time of writing certenr3.dll is contained in 
        +http://www.microsoft.com/workshop/prog/security/csa/certenr3.exe. It comes 
        +with an README file which explains the available functions. It is labeled 
        +beta but every CA seems to use it anyway. The license.txt allows you the 
        +usage for your own purposes (as far as I understood) and a somehow limited 
        +distribution. 
        +
        +The two functions of main interest are GenerateKeyPair and AcceptCredentials. 
        +For complete explanation of all possible parameters see the README file. Here 
        +are only minimal required parameters and their values.
        +
        +GenerateKeyPair(sessionID, FASLE, szName, 0, "ClientAuth", TRUE, FALSE, 1)
        +- sessionID is a (locally to that computer) unique string to correlate the 
        +generated key pair with a cert installed later.
        +- szName is the DN of the form "C=DE; S=Thueringen; L=Ilmenau; CN=Holger 
        +Reif; 1.2.840.113549.1.9.1=reif@prakinf.tu-ilmenau.de". Note that S is the 
        +abreviation for StateOrProvince. The recognized abreviation include CN, O, C, 
        +OU, G, I, L, S, T. If the abreviation is unknown (eg. for PKCS#9 email addr) 
        +you need to use the full object identifier. The starting point for searching 
        +them could be crypto/objects.h since all OIDs know to SSLeay are listed 
        +there.
        +- note: the possible ninth parameter which should give a default name to the 
        +certificate storage location doesn't seem to work. Changes to the constant 
        +values in the call above doesn't seem to make sense. You can't generate 
        +PKCS#10 extensions with that function.
        +
        +The result of GenerateKeyPair is the base64 encoded PKCS#10 request. However 
        +it has a little strange format that SSLeay doesn't accept. (BTW I feel the 
        +decision of rejecting that format as standard conforming.) It looks like 
        +follows:
        +	1st line with 76 chars
        +	2nd line with 76 chars
        +	...
        +	(n-2)th line with 76 chars
        +	(n-1)th line contains a multiple of 4 chars less then 76 (possible 
        +empty)
        +	(n)th line has zero or 4 chars (then with 1 or 2 equal signs - the 
        +		original text's lenght wasn'T a multiple of 3) 
        +	The line separator has two chars: 0x0d 0x0a
        +
        +AcceptCredentials(sessionID, credentials, 0, FALSE)
        +- sessionID needs to be the same as while generating the key pair
        +- credentials is the base64 encoded PKCS#7 object containing the cert. 
        +
        +CRL's and CA certs are not required simply just the client cert. (It seems to 
        +me that both are not even checked somehow.) The only format of the base64 
        +encoded object I succesfully used was all characters in a very long string 
        +without line feeds or carriage returns. (Hey, it doesn't matter, only a 
        +computer reads it!)
        +
        +The result should be S_OK. For error handling see the example that comes with 
        +certenr3.dll.
        +
        +A note about ASN.1 character encodings. certenr3.dll seems to know only about 
        +2 of them: UniversalString and PrintableString. First it is definitely wrong 
        +for an email address which is IA5STRING (checked by ssleay's ca). Second 
        +unfortunately MSIE (at least until version 3.02) can't handle UniversalString 
        +correctly - they just blow up you cert store! Therefore ssleay's ca (starting 
        +from version 0.8.0) tries to convert the encodings automatically to IA5STRING 
        +or TeletexString. The beef is it will work only for the latin-1 (western) 
        +charset. Microsoft still has to do abit of homework...
        +
        +3.) An example
        +--------------
        +
        +At least you need two steps: generating the key & request and then installing 
        +the certificate. A real world CA would have some more steps involved, eg. 
        +accepting some license. Note that both scripts shown below are just 
        +experimental state without any warrenty!
        +
        +First how to generate a request. Note that we can't use a static page because 
        +of the sessionID. I generate it from system time plus pid and hope it is 
        +unique enough. Your are free to feed it through md5 to get more impressive 
        +ID's ;-) Then the intended text is read in with sed which inserts the 
        +sessionID. 
        +
        +-----BEGIN ms-enroll.cgi-----
        +#!/bin/sh
        +SESSION_ID=`date '+%y%m%d%H%M%S'`$$
        +echo Content-type: text/html
        +echo
        +sed s/template_for_sessId/$SESSION_ID/ <<EOF
        +<HTML><HEAD>
        +<TITLE>Certificate Enrollment Test Page</TITLE>
        +</HEAD><BODY>
        +
        +<OBJECT
        +    classid="clsid:33BEC9E0-F78F-11cf-B782-00C04FD7BF43"
        +    codebase=certenr3.dll
        +    id=certHelper
        +    >
        +</OBJECT>
        +
        +<CENTER>
        +<H2>enrollment for a personal cert</H2>
        +<BR><HR WIDTH=50%><BR><P>
        +<FORM NAME="MSIE_Enrollment" ACTION="ms-gencert.cgi" ENCTYPE=x-www-form-
        +encoded METHOD=POST>
        +<TABLE>
        +    <TR><TD>Country</TD><TD><INPUT NAME="Country" VALUE=""></TD></TR>
        +    <TR><TD>State</TD><TD><INPUT NAME="StateOrProvince" VALUE=""></TD></TR>
        +    <TR><TD>Location</TD><TD><INPUT NAME="Location" VALUE=""></TD></TR>
        +    <TR><TD>Organization</TD><TD><INPUT NAME="Organization" 
        +VALUE=""></TD></TR>
        +    <TR><TD>Organizational Unit</TD>
        +        <TD><INPUT NAME="OrganizationalUnit" VALUE=""></TD></TR>
        +    <TR><TD>Name</TD><TD><INPUT NAME="CommonName" VALUE=""></TD></TR>
        +    <TR><TD>eMail Address</TD>
        +        <TD><INPUT NAME="EmailAddress" VALUE=""></TD></TR>
        +    <TR><TD></TD>
        +        <TD><INPUT TYPE="BUTTON" NAME="submit" VALUE="Beantragen"></TD></TR>
        +</TABLE>
        +	<INPUT TYPE="hidden" NAME="SessionId" VALUE="template_for_sessId">
        +	<INPUT TYPE="hidden" NAME="Request" VALUE="">
        +</FORM>
        +<BR><HR WIDTH=50%><BR><P>
        +</CENTER>
        +
        +<SCRIPT LANGUAGE=VBS>
        +    Dim DN
        +
        +    Sub Submit_OnClick
        +	Dim TheForm
        +	Set TheForm = Document.MSIE_Enrollment
        +	sessionId	= TheForm.SessionId.value
        +	reqHardware     = FALSE
        +	C		= TheForm.Country.value
        +	SP		= TheForm.StateOrProvince.value
        +	L		= TheForm.Location.value
        +	O		= TheForm.Organization.value
        +	OU		= TheForm.OrganizationalUnit.value
        +	CN              = TheForm.CommonName.value
        +	Email		= TheForm.EmailAddress.value
        +        szPurpose       = "ClientAuth"
        +        doAcceptanceUINow   = FALSE
        +        doOnline        = TRUE
        +
        +	DN = ""
        +
        +	Call Add_RDN("C", C)
        +	Call Add_RDN("S", SP)
        +	Call Add_RDN("L", L)
        +	Call Add_RDN("O", O)
        +	Call Add_RDN("OU", OU)
        +	Call Add_RDN("CN", CN)
        +	Call Add_RDN("1.2.840.113549.1.9.1", Email)
        +		      ' rsadsi
        +				     ' pkcs
        +				       ' pkcs9
        +					 ' eMailAddress
        +        On Error Resume Next
        +        sz10 = certHelper.GenerateKeyPair(sessionId, _
        +                FALSE, DN, 0, ClientAuth, FASLE, TRUE, 1)_
        +        theError = Err.Number
        +        On Error Goto 0
        +        if (sz10 = Empty OR theError <> 0) Then
        +            sz = "The error '" & Hex(theError) & "' occurred." & chr(13) & _
        +                chr(10) & "Your credentials could not be generated."
        +            result = MsgBox(sz, 0, "Credentials Enrollment")
        +            Exit Sub
        +	else 
        +	    TheForm.Request.value = sz10
        +	    TheForm.Submit
        +        end if
        +    End Sub
        +
        +    Sub Add_RDN(sn, value)
        +	if (value <> "") then
        +	    if (DN <> "") then
        +		DN = DN & "; "
        +	    end if
        +	    DN = DN & sn & "=" & value
        +	end if
        +    End Sub
        +</SCRIPT>
        +</BODY>
        +</HTML>
        +EOF
        +-----END ms-enroll.cgi-----
        +
        +Second, how to extract the request and feed the certificate back? We need to 
        +"normalize" the base64 encoding of the PKCS#10 format which means 
        +regenerating the lines and wrapping with BEGIN and END line. This is done by 
        +gawk. The request is taken by ca the normal way. Then the cert needs to be 
        +packed into a PKCS#7 structure (note: the use of a CRL is necessary for 
        +crl2pkcs7 as of version 0.6.6. Starting with 0.8.0 it it might probably be 
        +ommited). Finally we need to format the PKCS#7 object and generate the HTML 
        +text. I use two templates to have a clearer script.
        +
        +1st note: postit2 is slightly modified from a program I found at ncsa's ftp 
        +site. Grab it from http://www.easterngraphics.com/certs/IX9704/postit2.c. You 
        +need utils.c from there too.
        +
        +2nd note: I'm note quite sure wether the gawk script really handles all 
        +possible inputs for the request right! Today I don't use this construction 
        +anymore myself.
        +
        +3d note: the cert must be of version 3! This could be done with the nsComment 
        +line in ssleay.cnf...
        +
        +------BEGIN ms-gencert.cgi-----
        +#!/bin/sh
        +FILE="/tmp/"`date '+%y%m%d%H%M%S'-`$$
        +rm -f "$FILE".*
        +
        +HOME=`pwd`; export HOME  # as ssleay.cnf insists on having such an env var
        +cd /usr/local/ssl #where demoCA (as named in ssleay.conf) is located
        +
        +postit2 -s " " -i 0x0d > "$FILE".inp  # process the FORM vars
        +
        +SESSION_ID=`gawk '$1 == "SessionId" { print $2; exit }' "$FILE".inp`
        +
        +gawk \
        +	'BEGIN { \
        +		OFS = ""; \
        +		print "-----BEGIN CERTIFICATE REQUEST-----"; \
        +		req_seen=0 \
        +	} \
        +	$1 == "Request" { \
        +		req_seen=1; \
        +		if (length($2) == 72) print($2); \
        +		lastline=$2; \
        +		next; \
        +	} \
        +	{ \
        +		if (req_seen == 1) { \
        +			if (length($1) >= 72) print($1); \
        +			else if (length(lastline) < 72) { \
        +				req_seen=0; \
        +				print (lastline,$1); \
        +			} \
        +		lastline=$1; \
        +		} \
        +	} \
        +	END { \
        +		print "-----END CERTIFICATE REQUEST-----"; \
        +	}' > "$FILE".pem < "$FILE".inp 
        +
        +ssleay ca -batch -in "$FILE".pem -key passwd -out "$FILE".out
        +ssleay crl2pkcs7 -certfile "$FILE".out -out "$FILE".pkcs7 -in demoCA/crl.pem
        +
        +sed s/template_for_sessId/$SESSION_ID/ <ms-enroll2a.html >"$FILE".cert
        +/usr/local/bin/gawk \
        +	'BEGIN	{ \
        +		OFS = ""; \
        +		dq = sprintf("%c",34); \
        +	} \
        +	$0 ~ "PKCS7" { next; } \
        +	{ \
        +		print dq$0dq" & _"; \
        +	}' <"$FILE".pkcs7 >> "$FILE".cert
        +cat  ms-enroll2b.html >>"$FILE".cert
        +
        +echo Content-type: text/html
        +echo Content-length: `wc -c "$FILE".cert`
        +echo
        +cat "$FILE".cert
        +rm -f "$FILE".*
        +-----END ms-gencert.cgi-----
        +
        +----BEGIN ms-enroll2a.html----
        +<HTML><HEAD><TITLE>Certificate Acceptance Test Page</TITLE></HEAD><BODY>
        +
        +<OBJECT
        +    classid="clsid:33BEC9E0-F78F-11cf-B782-00C04FD7BF43"
        +    codebase=certenr3.dll
        +    id=certHelper
        +    >
        +</OBJECT>
        +
        +<CENTER>
        +<H2>Your personal certificate</H2>
        +<BR><HR WIDTH=50%><BR><P>
        +Press the button!
        +<P><INPUT TYPE=BUTTON VALUE="Nimm mich!" NAME="InstallCert">
        +</CENTER>
        +<BR><HR WIDTH=50%><BR>
        +
        +<SCRIPT LANGUAGE=VBS>
        +    Sub InstallCert_OnClick
        +
        +	sessionId	= "template_for_sessId"
        +credentials = "" & _
        +----END ms-enroll2a.html----
        +
        +----BEGIN ms-enroll2b.html----
        +""
        +        On Error Resume Next
        +        result = certHelper.AcceptCredentials(sessionId, credentials, 0, 
        +FALSE)
        +        if (IsEmpty(result)) Then
        +           sz = "The error '" & Err.Number & "' occurred." & chr(13) & 
        +chr(10) & "This Digital ID could not be registered."
        +           msgOut = MsgBox(sz, 0, "Credentials Registration Error")
        +           navigate "error.html"
        +        else
        +           sz = "Digital ID successfully registered."
        +           msgOut = MsgBox(sz, 0, "Credentials Registration")
        +           navigate "success.html"
        +        end if
        +	Exit Sub
        +    End Sub
        +</SCRIPT>
        +</BODY>
        +</HTML>
        +----END ms-enroll2b.html----
        +
        +4.) What do do with the cert?
        +-----------------------------
        +
        +The cert is visible (without restarting MSIE) under the following menu:
        +View->Options->Security->Personal certs. You can examine it's contents at 
        +least partially.
        +
        +To use it for client authentication you need to use SSL3.0 (fortunately 
        +SSLeay supports it with 0.8.0). Furthermore MSIE is told to only supports a 
        +kind of automatic selection of certs (I personally wasn't able to test it 
        +myself). But there is a requirement that the issuer of the server cert and 
        +the issuer of the client cert needs to be the same (according to a developer 
        +from MS). Which means: you need may more then one cert to talk to all 
        +servers...
        +
        +I'm sure we will get a bit more experience after ApacheSSL is available for 
        +SSLeay 0.8.8.
        +
        +
        +I hope you enjoyed reading and that in future questions on this topic will 
        +rarely appear on ssl-users@moncom.com ;-)
        +
        +Ilmenau, 9th of June 1997
        +Holger Reif <reif@prakinf.tu-ilmenau.de>
        +-- 
        +read you later  -  Holger Reif
        +----------------------------------------  Signaturprojekt Deutsche Einheit
        +TU Ilmenau - Informatik - Telematik                      (Verdamp lang her)
        +Holger.Reif@PrakInf.TU-Ilmenau.DE         Alt wie ein Baum werden, um ueber
        +http://Remus.PrakInf.TU-Ilmenau.DE/Reif/  alle 7 Bruecken gehen zu koennen
        +
        +
        +==== ns-ca.doc ========================================================
        +
        +The following documentation was supplied by Jeff Barber, who provided the
        +patch to the CA program to add this functionality.
        +
        +eric
        +--
        +Jeff Barber                                Email: jeffb@issl.atl.hp.com
        +
        +Hewlett Packard                            Phone: (404) 648-9503
        +Internet and System Security Lab           Fax:   (404) 648-9516
        +
        +                         oo
        +---------------------cut /\ here for ns-ca.doc ------------------------------
        +
        +This document briefly describes how to use SSLeay to implement a 
        +certificate authority capable of dynamically serving up client
        +certificates for version 3.0 beta 5 (and presumably later) versions of
        +the Netscape Navigator.  Before describing how this is done, it's
        +important to understand a little about how the browser implements its
        +client certificate support.  This is documented in some detail in the
        +URLs based at <URL:http://home.netscape.com/eng/security/certs.html>.
        +Here's a brief overview:
        +
        +-	The Navigator supports a new HTML tag "KEYGEN" which will cause
        +	the browser to generate an RSA key pair when you submit a form
        +	containing the tag.  The public key, along with an optional
        +	challenge (supposedly provided for use in certificate revocation
        +	but I don't use it) is signed, DER-encoded, base-64 encoded
        +	and sent to the web server as the value of the variable
        +	whose NAME is provided in the KEYGEN tag.  The private key is
        +	stored by the browser in a local key database.
        +
        +	This "Signed Public Key And Challenge" (SPKAC) arrives formatted
        +	into 64 character lines (which are of course URL-encoded when 
        +	sent via HTTP -- i.e. spaces, newlines and most punctuatation are
        +	encoded as "%HH" where HH is the hex equivalent of the ASCII code).
        +	Note that the SPKAC does not contain the other usual attributes
        +	of a certificate request, especially the subject name fields.
        +	These must be otherwise encoded in the form for submission along
        +	with the SPKAC.
        +
        +-	Either immediately (in response to this form submission), or at
        +	some later date (a real CA will probably verify your identity in
        +	some way before issuing the certificate), a web server can send a
        +	certificate based on the public key and other attributes back to
        +	the browser by encoding it in DER (the binary form) and sending it
        +	to the browser as MIME type:
        +	"Content-type: application/x-x509-user-cert"
        +
        +	The browser uses the public key encoded in the certificate to
        +	associate the certificate with the appropriate private key in
        +	its local key database.  Now, the certificate is "installed".
        +
        +-	When a server wants to require authentication based on client
        +	certificates, it uses the right signals via the SSL protocol to
        +	trigger the Navigator to ask you which certificate you want to
        +	send.  Whether the certificate is accepted is dependent on CA
        +	certificates and so forth installed in the server and is beyond
        +	the scope of this document.
        +
        +
        +Now, here's how the SSLeay package can be used to provide client 
        +certficates:
        +
        +-	You prepare a file for input to the SSLeay ca application.
        +	The file contains a number of "name = value" pairs that identify
        +	the subject.  The names here are the same subject name component
        +	identifiers used in the CA section of the lib/ssleay.conf file,
        +	such as "emailAddress", "commonName" "organizationName" and so
        +	forth.  Both the long version and the short version (e.g. "Email",
        +	"CN", "O") can be used.
        +
        +	One more name is supported: this one is "SPKAC".  Its value
        +	is simply the value of the base-64 encoded SPKAC sent by the
        +	browser (with all the newlines and other space charaters
        +	removed -- and newline escapes are NOT supported).
        +
        +	[ As of SSLeay 0.6.4, multiple lines are supported.
        +	  Put a \ at the end of each line and it will be joined with the
        +	  previous line with the '\n' removed - eay ]
        +	
        +	Here's a sample input file:
        +
        +C = US
        +SP = Georgia
        +O = Some Organization, Inc.
        +OU = Netscape Compatibility Group
        +CN = John X. Doe
        +Email = jxdoe@someorg.com
        +SPKAC = MIG0MGAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAwmk6FMJ4uAVIYbcvIOx5+bDGTfvL8X5gE+R67ccMk6rCSGbVQz2cetyQtnI+VIs0NwdD6wjuSuVtVFbLoHonowIDAQABFgAwDQYJKoZIhvcNAQEEBQADQQBFZDUWFl6BJdomtN1Bi53mwijy1rRgJ4YirF15yBEDM3DjAQkKXHYOIX+qpz4KXKnl6EYxTnGSFL5wWt8X2iyx
        +
        +-	You execute the ca command (either from a CGI program run out of
        +	the web server, or as a later manual task) giving it the above
        +	file as input.  For example, if the file were named /tmp/cert.req,
        +	you'd run:
        +	$SSLDIR/bin/ca -spkac /tmp/cert.req -out /tmp/cert
        +
        +	The output is in DER format (binary) if a -out argument is 
        +	provided, as above; otherwise, it's in the PEM format (base-64
        +	encoded DER).  Also, the "-batch" switch is implied by the
        +	"-spkac" so you don't get asked whether to complete the signing
        +	(probably it shouldn't work this way but I was only interested
        +	in hacking together an online CA that could be used for issuing
        +	test certificates).
        +
        +	The "-spkac" capability doesn't support multiple files (I think).
        +
        +	Any CHALLENGE provided in the SPKAC is simply ignored.
        +
        +	The interactions between the identification fields you provide
        +	and those identified in your lib/ssleay.conf are the same as if
        +	you did an ordinary "ca -in infile -out outfile" -- that is, if
        +	something is marked as required in the ssleay.conf file and it
        +	isn't found in the -spkac file, the certificate won't be issued.
        +
        +-	Now, you pick up the output from /tmp/cert and pass it back to
        +	the Navigator prepending the Content-type string described earlier.
        +
        +-	In order to run the ca command out of a CGI program, you must
        +	provide a password to decrypt the CA's private key.  You can
        +	do this by using "echo MyKeyPassword | $SSLDIR/bin/ca ..."
        +	I think there's a way to not encrypt the key file in the first
        +	place, but I didn't see how to do that, so I made a small change
        +	to the library that allows the password to be accepted from a pipe.
        +	Either way is UTTERLY INSECURE and a real CA would never do that.
        +
        +	[ You can use the 'ssleay rsa' command to remove the password
        +	  from the private key, or you can use the '-key' option to the
        +	  ca command to specify the decryption key on the command line
        +	  or use the -nodes option when generating the key.
        +	  ca will try to clear the command line version of the password
        +	  but for quite a few operating systems, this is not possible.
        +	  - eric ]
        +
        +So, what do you have to do to make use of this stuff to create an online 
        +demo CA capability with SSLeay?
        +
        +1	Create an HTML form for your users.  The form should contain
        +	fields for all of the required or optional fields in ssleay.conf.
        +	The form must contain a KEYGEN tag somewhere with at least a NAME
        +	attribute.
        +
        +2	Create a CGI program to process the form input submitted by the
        +	browser.  The CGI program must URL-decode the variables and create
        +	the file described above, containing subject identification info
        +	as well as the SPKAC block.  It should then run the the ca program
        +	with the -spkac option.  If it works (check the exit status),
        +	return the new certificate with the appropriate MIME type.  If not,
        +	return the output of the ca command with MIME type "text/plain".
        +
        +3	Set up your web server to accept connections signed by your demo
        +	CA.  This probably involves obtaining the PEM-encoded CA certificate
        +	(ordinarily in $SSLDIR/CA/cacert.pem) and installing it into a
        +	server database.  See your server manual for instructions.
        +
        +
        +==== obj.doc ========================================================
        +
        +The Object library.
        +
        +As part of my Crypto library, I found I required a method of identifying various
        +objects.  These objects normally had 3 different values associated with
        +them, a short text name, a long (or lower case) text name, and an
        +ASN.1 Object Identifier (which is a sequence of numbers).
        +This library contains a static list of objects and functions to lookup
        +according to one type and to return the other types.
        +
        +To use these routines, 'Object.h' needs to be included.
        +
        +For each supported object, #define entries are defined as follows
        +#define SN_Algorithm			"Algorithm"
        +#define LN_algorithm			"algorithm"
        +#define NID_algorithm			38
        +#define OBJ_algorithm			1L,3L,14L,3L,2L
        +
        +SN_  stands for short name.
        +LN_  stands for either long name or lowercase name.
        +NID_ stands for Numeric ID.  I each object has a unique NID and this
        +     should be used internally to identify objects.
        +OBJ_ stands for ASN.1 Object Identifier or ASN1_OBJECT as defined in the
        +     ASN1 routines.  These values are used in ASN1 encoding.
        +
        +The following functions are to be used to return pointers into a static
        +definition of these types.  What this means is "don't try to free() any
        +pointers returned from these functions.
        +
        +ASN1_OBJECT *OBJ_nid2obj(
        +int n);
        +	Return the ASN1_OBJECT that corresponds to a NID of n.
        +	
        +char *OBJ_nid2ln(
        +int n);
        +	Return the long/lower case name of the object represented by the
        +	NID of n.
        +	
        +char *OBJ_nid2sn(
        +int n);
        +	Return the short name for the object represented by the NID of n.
        +
        +ASN1_OBJECT *OBJ_dup(
        +ASN1_OBJECT *o);
        +	Duplicate and return a new ASN1_OBJECT that is the same as the
        +	passed parameter.
        +	
        +int OBJ_obj2nid(
        +ASN1_OBJECT *o);
        +	Given ASN1_OBJECT o, return the NID that corresponds.
        +	
        +int OBJ_ln2nid(
        +char *s);
        +	Given the long/lower case name 's', return the NID of the object.
        +	
        +int OBJ_sn2nid(
        +char *s);
        +	Given the short name 's', return the NID of the object.
        +	
        +char *OBJ_bsearch(
        +char *key,
        +char *base,
        +int num,
        +int size,
        +int (*cmp)());
        +	Since I have come across a few platforms that do not have the
        +	bsearch() function, OBJ_bsearch is my version of that function.
        +	Feel free to use this function, but you may as well just use the
        +	normal system bsearch(3) if it is present.  This version also
        +	has tolerance of being passed NULL pointers.
        +
        +==== keys ===========================================================
        +
        +EVP_PKEY_DSA
        +EVP_PKEY_DSA2
        +EVP_PKEY_DSA3
        +EVP_PKEY_DSA4
        +
        +EVP_PKEY_RSA
        +EVP_PKEY_RSA2
        +
        +valid DSA pkey types
        +	NID_dsa
        +	NID_dsaWithSHA
        +	NID_dsaWithSHA1
        +	NID_dsaWithSHA1_2
        +
        +valid RSA pkey types
        +	NID_rsaEncryption
        +	NID_rsa
        +
        +NID_dsaWithSHA	NID_dsaWithSHA			DSA		SHA
        +NID_dsa		NID_dsaWithSHA1			DSA		SHA1
        +NID_md2		NID_md2WithRSAEncryption	RSA-pkcs1	MD2
        +NID_md5		NID_md5WithRSAEncryption	RSA-pkcs1	MD5
        +NID_mdc2	NID_mdc2WithRSA			RSA-none	MDC2
        +NID_ripemd160	NID_ripemd160WithRSA		RSA-pkcs1	RIPEMD160
        +NID_sha		NID_shaWithRSAEncryption	RSA-pkcs1	SHA
        +NID_sha1	NID_sha1WithRSAEncryption	RSA-pkcs1	SHA1
        +
        +==== rand.doc ========================================================
        +
        +My Random number library.
        +
        +These routines can be used to generate pseudo random numbers and can be
        +used to 'seed' the pseudo random number generator (RNG).  The RNG make no
        +effort to reproduce the same random number stream with each execution.
        +Various other routines in the SSLeay library 'seed' the RNG when suitable
        +'random' input data is available.  Read the section at the end for details
        +on the design of the RNG.
        +
        +void RAND_bytes(
        +unsigned char *buf,
        +int num);
        +	This routine puts 'num' random bytes into 'buf'.  One should make
        +	sure RAND_seed() has been called before using this routine.
        +	
        +void RAND_seed(
        +unsigned char *buf,
        +int num);
        +	This routine adds more 'seed' data the RNG state.  'num' bytes
        +	are added to the RNG state, they are taken from 'buf'.  This
        +	routine can be called with sensitive data such as user entered
        +	passwords.  This sensitive data is in no way recoverable from
        +	the RAND library routines or state.  Try to pass as much data
        +	from 'random' sources as possible into the RNG via this function.
        +	Also strongly consider using the RAND_load_file() and
        +	RAND_write_file() routines.
        +
        +void RAND_cleanup();
        +	When a program has finished with the RAND library, if it so
        +	desires, it can 'zero' all RNG state.
        +	
        +The following 3 routines are convenience routines that can be used to
        +'save' and 'restore' data from/to the RNG and it's state.
        +Since the more 'random' data that is feed as seed data the better, why not
        +keep it around between executions of the program?  Of course the
        +application should pass more 'random' data in via RAND_seed() and 
        +make sure no-one can read the 'random' data file.
        +	
        +char *RAND_file_name(
        +char *buf,
        +int size);
        +	This routine returns a 'default' name for the location of a 'rand'
        +	file.  The 'rand' file should keep a sequence of random bytes used
        +	to initialise the RNG.  The filename is put in 'buf'.  Buf is 'size'
        +	bytes long.  Buf is returned if things go well, if they do not,
        +	NULL is returned.  The 'rand' file name is generated in the
        +	following way.  First, if there is a 'RANDFILE' environment
        +	variable, it is returned.  Second, if there is a 'HOME' environment
        +	variable, $HOME/.rand is returned.  Third, NULL is returned.  NULL
        +	is also returned if a buf would overflow.
        +
        +int RAND_load_file(
        +char *file,
        +long number);
        +	This function 'adds' the 'file' into the RNG state.  It does this by
        +	doing a RAND_seed() on the value returned from a stat() system call
        +	on the file and if 'number' is non-zero, upto 'number' bytes read
        +	from the file.  The number of bytes passed to RAND_seed() is returned.
        +
        +int RAND_write_file(
        +char *file),
        +	RAND_write_file() writes N random bytes to the file 'file', where
        +	N is the size of the internal RND state (currently 1k).
        +	This is a suitable method of saving RNG state for reloading via
        +	RAND_load_file().
        +
        +What follows is a description of this RNG and a description of the rational
        +behind it's design.
        +
        +It should be noted that this RNG is intended to be used to generate
        +'random' keys for various ciphers including generation of DH and RSA keys.  
        +
        +It should also be noted that I have just created a system that I am happy with.
        +It may be overkill but that does not worry me.  I have not spent that much
        +time on this algorithm so if there are glaring errors, please let me know.
        +Speed has not been a consideration in the design of these routines.
        +
        +First up I will state the things I believe I need for a good RNG.
        +1) A good hashing algorithm to mix things up and to convert the RNG 'state'
        +   to random numbers.
        +2) An initial source of random 'state'.
        +3) The state should be very large.  If the RNG is being used to generate
        +   4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum).
        +   If your RNG state only has 128 bits, you are obviously limiting the
        +   search space to 128 bits, not 2048.  I'm probably getting a little
        +   carried away on this last point but it does indicate that it may not be
        +   a bad idea to keep quite a lot of RNG state.  It should be easier to
        +   break a cipher than guess the RNG seed data.
        +4) Any RNG seed data should influence all subsequent random numbers
        +   generated.  This implies that any random seed data entered will have
        +   an influence on all subsequent random numbers generated.
        +5) When using data to seed the RNG state, the data used should not be
        +   extractable from the RNG state.  I believe this should be a
        +   requirement because one possible source of 'secret' semi random
        +   data would be a private key or a password.  This data must
        +   not be disclosed by either subsequent random numbers or a
        +   'core' dump left by a program crash.
        +6) Given the same initial 'state', 2 systems should deviate in their RNG state
        +   (and hence the random numbers generated) over time if at all possible.
        +7) Given the random number output stream, it should not be possible to determine
        +   the RNG state or the next random number.
        +
        +
        +The algorithm is as follows.
        +
        +There is global state made up of a 1023 byte buffer (the 'state'), a
        +working message digest ('md') and a counter ('count').
        +
        +Whenever seed data is added, it is inserted into the 'state' as
        +follows.
        +	The input is chopped up into units of 16 bytes (or less for
        +	the last block).  Each of these blocks is run through the MD5
        +	message digest.  The data passed to the MD5 digest is the
        +	current 'md', the same number of bytes from the 'state'
        +	(the location determined by in incremented looping index) as
        +	the current 'block' and the new key data 'block'.  The result
        +	of this is kept in 'md' and also xored into the 'state' at the
        +	same locations that were used as input into the MD5.
        +	I believe this system addresses points 1 (MD5), 3 (the 'state'),
        +	4 (via the 'md'), 5 (by the use of MD5 and xor).
        +
        +When bytes are extracted from the RNG, the following process is used.
        +For each group of 8 bytes (or less), we do the following,
        +	Input into MD5, the top 8 bytes from 'md', the byte that are
        +	to be overwritten by the random bytes and bytes from the
        +	'state' (incrementing looping index).  From this digest output
        +	(which is kept in 'md'), the top (upto) 8 bytes are
        +	returned to the caller and the bottom (upto) 8 bytes are xored
        +	into the 'state'.
        +	Finally, after we have finished 'generation' random bytes for the
        +	called, 'count' (which is incremented) and 'md' are fed into MD5 and
        +	the results are kept in 'md'.
        +	I believe the above addressed points 1 (use of MD5), 6 (by
        +	hashing into the 'state' the 'old' data from the caller that
        +	is about to be overwritten) and 7 (by not using the 8 bytes
        +	given to the caller to update the 'state', but they are used
        +	to update 'md').
        +
        +So of the points raised, only 2 is not addressed, but sources of
        +random data will always be a problem.
        +	
        +
        +==== rc2.doc ========================================================
        +
        +The RC2 library.
        +
        +RC2 is a block cipher that operates on 64bit (8 byte) quantities.  It
        +uses variable size key, but 128bit (16 byte) key would normally be considered
        +good.  It can be used in all the modes that DES can be used.  This
        +library implements the ecb, cbc, cfb64, ofb64 modes.
        +
        +I have implemented this library from an article posted to sci.crypt on
        +11-Feb-1996.  I personally don't know how far to trust the RC2 cipher.
        +While it is capable of having a key of any size, not much reseach has
        +publically been done on it at this point in time (Apr-1996)
        +since the cipher has only been public for a few months :-)
        +It is of a similar speed to DES and IDEA, so unless it is required for
        +meeting some standard (SSLv2, perhaps S/MIME), it would probably be advisable
        +to stick to IDEA, or for the paranoid, Tripple DES.
        +
        +Mind you, having said all that, I should mention that I just read alot and
        +implement ciphers, I'm a 'babe in the woods' when it comes to evaluating
        +ciphers :-).
        +
        +For all calls that have an 'input' and 'output' variables, they can be the
        +same.
        +
        +This library requires the inclusion of 'rc2.h'.
        +
        +All of the encryption functions take what is called an RC2_KEY as an 
        +argument.  An RC2_KEY is an expanded form of the RC2 key.
        +For all modes of the RC2 algorithm, the RC2_KEY used for
        +decryption is the same one that was used for encryption.
        +
        +The define RC2_ENCRYPT is passed to specify encryption for the functions
        +that require an encryption/decryption flag. RC2_DECRYPT is passed to
        +specify decryption.
        +
        +Please note that any of the encryption modes specified in my DES library
        +could be used with RC2.  I have only implemented ecb, cbc, cfb64 and
        +ofb64 for the following reasons.
        +- ecb is the basic RC2 encryption.
        +- cbc is the normal 'chaining' form for block ciphers.
        +- cfb64 can be used to encrypt single characters, therefore input and output
        +  do not need to be a multiple of 8.
        +- ofb64 is similar to cfb64 but is more like a stream cipher, not as
        +  secure (not cipher feedback) but it does not have an encrypt/decrypt mode.
        +- If you want triple RC2, thats 384 bits of key and you must be totally
        +  obsessed with security.  Still, if you want it, it is simple enough to
        +  copy the function from the DES library and change the des_encrypt to
        +  RC2_encrypt; an exercise left for the paranoid reader :-).
        +
        +The functions are as follows:
        +
        +void RC2_set_key(
        +RC2_KEY *ks;
        +int len;
        +unsigned char *key;
        +int bits;
        +        RC2_set_key converts an 'len' byte key into a RC2_KEY.
        +        A 'ks' is an expanded form of the 'key' which is used to
        +        perform actual encryption.  It can be regenerated from the RC2 key
        +        so it only needs to be kept when encryption or decryption is about
        +        to occur.  Don't save or pass around RC2_KEY's since they
        +        are CPU architecture dependent, 'key's are not.  RC2 is an
        +	interesting cipher in that it can be used with a variable length
        +	key.  'len' is the length of 'key' to be used as the key.
        +	A 'len' of 16 is recomended.  The 'bits' argument is an
        +	interesting addition which I only found out about in Aug 96.
        +	BSAFE uses this parameter to 'limit' the number of bits used
        +	for the key.  To use the 'key' unmodified, set bits to 1024.
        +	This is what old versions of my RC2 library did (SSLeay 0.6.3).
        +	RSAs BSAFE library sets this parameter to be 128 if 128 bit
        +	keys are being used.  So to be compatable with BSAFE, set it
        +	to 128, if you don't want to reduce RC2's key length, leave it
        +	at 1024.
        +	
        +void RC2_encrypt(
        +unsigned long *data,
        +RC2_KEY *key,
        +int encrypt);
        +	This is the RC2 encryption function that gets called by just about
        +	every other RC2 routine in the library.  You should not use this
        +	function except to implement 'modes' of RC2.  I say this because the
        +	functions that call this routine do the conversion from 'char *' to
        +	long, and this needs to be done to make sure 'non-aligned' memory
        +	access do not occur.
        +	Data is a pointer to 2 unsigned long's and key is the
        +	RC2_KEY to use.  Encryption or decryption is indicated by 'encrypt'.
        +	which can have the values RC2_ENCRYPT or RC2_DECRYPT.
        +
        +void RC2_ecb_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +RC2_KEY *key,
        +int encrypt);
        +	This is the basic Electronic Code Book form of RC2 (in DES this
        +	mode is called Electronic Code Book so I'm going to use the term
        +	for rc2 as well.
        +	Input is encrypted into output using the key represented by
        +	key.  Depending on the encrypt, encryption or
        +	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
        +	
        +void RC2_cbc_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +RC2_KEY *ks,
        +unsigned char *ivec,
        +int encrypt);
        +	This routine implements RC2 in Cipher Block Chaining mode.
        +	Input, which should be a multiple of 8 bytes is encrypted
        +	(or decrypted) to output which will also be a multiple of 8 bytes.
        +	The number of bytes is in length (and from what I've said above,
        +	should be a multiple of 8).  If length is not a multiple of 8, bad 
        +	things will probably happen.  ivec is the initialisation vector.
        +	This function updates iv after each call so that it can be passed to
        +	the next call to RC2_cbc_encrypt().
        +	
        +void RC2_cfb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +RC2_KEY *schedule,
        +unsigned char *ivec,
        +int *num,
        +int encrypt);
        +	This is one of the more useful functions in this RC2 library, it
        +	implements CFB mode of RC2 with 64bit feedback.
        +	This allows you to encrypt an arbitrary number of bytes,
        +	you do not require 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  Num contains 'how far' we are though ivec.
        +	'Encrypt' is used to indicate encryption or decryption.
        +	CFB64 mode operates by using the cipher to generate a stream
        +	of bytes which is used to encrypt the plain text.
        +	The cipher text is then encrypted to generate the next 64 bits to
        +	be xored (incrementally) with the next 64 bits of plain
        +	text.  As can be seen from this, to encrypt or decrypt,
        +	the same 'cipher stream' needs to be generated but the way the next
        +	block of data is gathered for encryption is different for
        +	encryption and decryption.
        +	
        +void RC2_ofb64_encrypt(
        +unsigned char *in,
        +unsigned char *out,
        +long length,
        +RC2_KEY *schedule,
        +unsigned char *ivec,
        +int *num);
        +	This functions implements OFB mode of RC2 with 64bit feedback.
        +	This allows you to encrypt an arbitrary number of bytes,
        +	you do not require 8 byte padding.  Each call to this
        +	routine will encrypt the input bytes to output and then update ivec
        +	and num.  Num contains 'how far' we are though ivec.
        +	This is in effect a stream cipher, there is no encryption or
        +	decryption mode.
        +	
        +For reading passwords, I suggest using des_read_pw_string() from my DES library.
        +To generate a password from a text string, I suggest using MD5 (or MD2) to
        +produce a 16 byte message digest that can then be passed directly to
        +RC2_set_key().
        +
        +=====
        +For more information about the specific RC2 modes in this library
        +(ecb, cbc, cfb and ofb), read the section entitled 'Modes of DES' from the
        +documentation on my DES library.  What is said about DES is directly
        +applicable for RC2.
        +
        +
        +==== rc4.doc ========================================================
        +
        +The RC4 library.
        +RC4 is a stream cipher that operates on a byte stream.  It can be used with
        +any length key but I would recommend normally using 16 bytes.
        +
        +This library requires the inclusion of 'rc4.h'.
        +
        +The RC4 encryption function takes what is called an RC4_KEY as an argument.
        +The RC4_KEY is generated by the RC4_set_key function from the key bytes.
        +
        +RC4, being a stream cipher, does not have an encryption or decryption mode.
        +It produces a stream of bytes that the input stream is xor'ed against and
        +so decryption is just a case of 'encrypting' again with the same key.
        +
        +I have only put in one 'mode' for RC4 which is the normal one.  This means
        +there is no initialisation vector and there is no feedback of the cipher
        +text into the cipher.  This implies that you should not ever use the
        +same key twice if you can help it.  If you do, you leave yourself open to
        +known plain text attacks; if you know the plain text and
        +corresponding cipher text in one message, all messages that used the same
        +key can have the cipher text decoded for the corresponding positions in the
        +cipher stream.
        +
        +The main positive feature of RC4 is that it is a very fast cipher; about 4
        +times faster that DES.  This makes it ideally suited to protocols where the
        +key is randomly chosen, like SSL.
        +
        +The functions are as follows:
        +
        +void RC4_set_key(
        +RC4_KEY *key;
        +int len;
        +unsigned char *data);
        +	This function initialises the RC4_KEY structure with the key passed
        +	in 'data', which is 'len' bytes long.  The key data can be any
        +	length but 16 bytes seems to be a good number.
        +
        +void RC4(
        +RC4_KEY *key;
        +unsigned long len;
        +unsigned char *in;
        +unsigned char *out);
        +	Do the actual RC4 encryption/decryption.  Using the 'key', 'len'
        +	bytes are transformed from 'in' to 'out'.  As mentioned above,
        +	decryption is the operation as encryption.
        +
        +==== ref.doc ========================================================
        +
        +I have lots more references etc, and will update this list in the future,
        +30 Aug 1996 - eay
        +
        +
        +SSL	The SSL Protocol - from Netscapes.
        +
        +RC4	Newsgroups: sci.crypt
        +	From: sterndark@netcom.com (David Sterndark)
        +	Subject: RC4 Algorithm revealed.
        +	Message-ID: <sternCvKL4B.Hyy@netcom.com>
        +
        +RC2	Newsgroups: sci.crypt
        +	From: pgut01@cs.auckland.ac.nz (Peter Gutmann)
        +	Subject: Specification for Ron Rivests Cipher No.2
        +	Message-ID: <4fk39f$f70@net.auckland.ac.nz>
        +
        +MD2	RFC1319 The MD2 Message-Digest Algorithm
        +MD5	RFC1321 The MD5 Message-Digest Algorithm
        +
        +X509 Certificates
        +	RFC1421 Privacy Enhancement for Internet Electronic Mail: Part I
        +	RFC1422 Privacy Enhancement for Internet Electronic Mail: Part II
        +	RFC1423 Privacy Enhancement for Internet Electronic Mail: Part III
        +	RFC1424 Privacy Enhancement for Internet Electronic Mail: Part IV
        +
        +RSA and various standard encoding
        +	PKCS#1 RSA Encryption Standard
        +	PKCS#5 Password-Based Encryption Standard
        +	PKCS#7 Cryptographic Message Syntax Standard
        +	A Layman's Guide to a Subset of ASN.1, BER, and DER
        +	An Overview of the PKCS Standards
        +	Some Examples of the PKCS Standards
        +
        +IDEA	Chapter 3 The Block Cipher IDEA
        +
        +RSA, prime number generation and bignum algorithms
        +	Introduction To Algorithms,
        +	Thomas Cormen, Charles Leiserson, Ronald Rivest,
        +	Section 29 Arithmetic Circuits
        +	Section 33 Number-Theoretic Algorithms
        +
        +Fast Private Key algorithm
        +	Fast Decipherment Algorithm for RSA Public-Key Cryptosystem
        +	J.-J. Quisquater and C. Couvreur, Electronics Letters,
        +	14th October 1982, Vol. 18 No. 21
        +
        +Prime number generation and bignum algorithms.
        +	PGP-2.3a
        +
        +==== rsa.doc ========================================================
        +
        +The RSA encryption and utility routines.
        +
        +The RSA routines are built on top of a big number library (the BN library).
        +There are support routines in the X509 library for loading and manipulating
        +the various objects in the RSA library.  When errors are returned, read
        +about the ERR library for how to access the error codes.
        +
        +All RSA encryption is done according to the PKCS-1 standard which is
        +compatible with PEM and RSAref.  This means that any values being encrypted
        +must be less than the size of the modulus in bytes, minus 10, bytes long.
        +
        +This library uses RAND_bytes()() for it's random data, make sure to feed
        +RAND_seed() with lots of interesting and varied data before using these
        +routines.
        +
        +The RSA library has one specific data type, the RSA structure.
        +It is composed of 8 BIGNUM variables (see the BN library for details) and
        +can hold either a private RSA key or a public RSA key.
        +Some RSA libraries have different structures for public and private keys, I
        +don't.  For my libraries, a public key is determined by the fact that the
        +RSA->d value is NULL.  These routines will operate on any size RSA keys.
        +While I'm sure 4096 bit keys are very very secure, they take a lot longer
        +to process that 1024 bit keys :-).
        +
        +The function in the RSA library are as follows.
        +
        +RSA *RSA_new();
        +	This function creates a new RSA object.  The sub-fields of the RSA
        +	type are also malloced so you should always use this routine to
        +	create RSA variables.
        +	
        +void RSA_free(
        +RSA *rsa);
        +	This function 'frees' an RSA structure.  This routine should always
        +	be used to free the RSA structure since it will also 'free' any
        +	sub-fields of the RSA type that need freeing.
        +	
        +int RSA_size(
        +RSA *rsa);	
        +	This function returns the size of the RSA modulus in bytes.  Why do
        +	I need this you may ask, well the reason is that when you encrypt
        +	with RSA, the output string will be the size of the RSA modulus.
        +	So the output for the RSA_encrypt and the input for the RSA_decrypt
        +	routines need to be RSA_size() bytes long, because this is how many
        +	bytes are expected.
        +	
        +For the following 4 RSA encryption routines, it should be noted that
        +RSA_private_decrypt() should be used on the output from 
        +RSA_public_encrypt() and RSA_public_decrypt() should be used on
        +the output from RSA_private_encrypt().
        +	
        +int RSA_public_encrypt(
        +int from_len;
        +unsigned char *from	
        +unsigned char *to	
        +RSA *rsa);
        +	This function implements RSA public encryption, the rsa variable
        +	should be a public key (but can be a private key).  'from_len'
        +	bytes taken from 'from' and encrypted and put into 'to'.  'to' needs
        +	to be at least RSA_size(rsa) bytes long.  The number of bytes
        +	written into 'to' is returned.  -1 is returned on an error.  The
        +	operation performed is
        +	to = from^rsa->e mod rsa->n.
        +	
        +int RSA_private_encrypt(
        +int from_len;
        +unsigned char *from	
        +unsigned char *to	
        +RSA *rsa);
        +	This function implements RSA private encryption, the rsa variable
        +	should be a private key.  'from_len' bytes taken from
        +	'from' and encrypted and put into 'to'.  'to' needs
        +	to be at least RSA_size(rsa) bytes long.  The number of bytes
        +	written into 'to' is returned.  -1 is returned on an error.  The
        +	operation performed is
        +	to = from^rsa->d mod rsa->n.
        +
        +int RSA_public_decrypt(
        +int from_len;
        +unsigned char *from	
        +unsigned char *to	
        +RSA *rsa);
        +	This function implements RSA public decryption, the rsa variable
        +	should be a public key (but can be a private key).  'from_len'
        +	bytes are taken from 'from' and decrypted.  The decrypted data is
        +	put into 'to'.  The number of bytes encrypted is returned.  -1 is
        +	returned to indicate an error. The operation performed is
        +	to = from^rsa->e mod rsa->n.
        +
        +int RSA_private_decrypt(
        +int from_len;
        +unsigned char *from	
        +unsigned char *to	
        +RSA *rsa);
        +	This function implements RSA private decryption, the rsa variable
        +	should be a private key.  'from_len' bytes are taken
        +	from 'from' and decrypted.  The decrypted data is
        +	put into 'to'.  The number of bytes encrypted is returned.  -1 is
        +	returned to indicate an error. The operation performed is
        +	to = from^rsa->d mod rsa->n.
        +
        +int RSA_mod_exp(
        +BIGNUM *n;
        +BIGNUM *p;
        +RSA *rsa);
        +	Normally you will never use this routine.
        +	This is really an internal function which is called by
        +	RSA_private_encrypt() and RSA_private_decrypt().  It performs
        +	n=n^p mod rsa->n except that it uses the 5 extra variables in the
        +	RSA structure to make this more efficient.
        +	
        +RSA *RSA_generate_key(
        +int bits;
        +unsigned long e;
        +void (*callback)();
        +char *cb_arg;
        +	This routine is used to generate RSA private keys.  It takes
        +	quite a period of time to run and should only be used to
        +	generate initial private keys that should then be stored
        +	for later use.  The passed callback function 
        +	will be called periodically so that feedback can be given
        +	as to how this function is progressing.
        +	'bits' is the length desired for the modulus, so it would be 1024
        +	to generate a 1024 bit private key.
        +	'e' is the value to use for the public exponent 'e'.  Traditionally
        +	it is set to either 3 or 0x10001.
        +	The callback function (if not NULL) is called in the following
        +	situations.
        +	when we have generated a suspected prime number to test,
        +	callback(0,num1++,cb_arg).  When it passes a prime number test,
        +	callback(1,num2++,cb_arg).  When it is rejected as one of
        +	the 2 primes required due to gcd(prime,e value) != 0,
        +	callback(2,num3++,cb_arg).  When finally accepted as one
        +	of the 2 primes, callback(3,num4++,cb_arg).
        +
        +
        +==== rsaref.doc ========================================================
        +
        +This package can be compiled to use the RSAref library.
        +This library is not allowed outside of the USA but inside the USA it is
        +claimed by RSA to be the only RSA public key library that can be used
        +besides BSAFE..
        +
        +There are 2 files, rsaref/rsaref.c and rsaref/rsaref.h that contain the glue
        +code to use RSAref.  These files were written by looking at the PGP
        +source code and seeing which routines it used to access RSAref.
        +I have also been sent by some-one a copy of the RSAref header file that
        +contains the library error codes.
        +
        +[ Jun 1996 update - I have recently gotten hold of RSAref 2.0 from
        +  South Africa and have been doing some performace tests. ]
        +	
        +They have now been tested against the recently announced RSAEURO
        +library.
        +
        +There are 2 ways to use SSLeay and RSAref.  First, to build so that
        +the programs must be linked with RSAref, add '-DRSAref' to CFLAG in the top
        +level makefile and -lrsaref (or where ever you are keeping RSAref) to
        +EX_LIBS.
        +
        +To build a makefile via util/mk1mf.pl to do this, use the 'rsaref' option.
        +
        +The second method is to build as per normal and link applications with
        +the RSAglue library.  The correct library order would be
        +cc -o cmd cmd.o -lssl -lRSAglue -lcrypto -lrsaref -ldes
        +The RSAglue library is built in the rsa directory and is NOT
        +automatically installed.
        +
        +Be warned that the RSAEURO library, that is claimed to be compatible
        +with RSAref contains a different value for the maximum number of bits
        +supported.  This changes structure sizes and so if you are using
        +RSAEURO, change the value of RSAref_MAX_BITS in rsa/rsaref.h
        +
        +
        +==== s_mult.doc ========================================================
        +
        +s_mult is a test program I hacked up on a Sunday for testing non-blocking
        +IO.  It has a select loop at it's centre that handles multiple readers
        +and writers.
        +
        +Try the following command
        +ssleay s_mult -echo -nbio -ssl -v
        +echo - sends any sent text back to the sender
        +nbio - turns on non-blocking IO
        +ssl  - accept SSL connections, default is normal text
        +v    - print lots
        +	type Q<cr> to quit
        +
        +In another window, run the following
        +ssleay s_client -pause </etc/termcap
        +
        +The pause option puts in a 1 second pause in each read(2)/write(2) call
        +so the other end will have read()s fail.
        +
        +==== session.doc ========================================================
        +
        +I have just checked over and re-worked the session stuff.
        +The following brief example will ignore all setup information to do with
        +authentication.
        +
        +Things operate as follows.
        +
        +The SSL environment has a 'context', a SSL_CTX structure.  This holds the
        +cached SSL_SESSIONS (which can be reused) and the certificate lookup
        +information.  Each SSL structure needs to be associated with a SSL_CTX.
        +Normally only one SSL_CTX structure is needed per program.
        +
        +SSL_CTX *SSL_CTX_new(void ); 
        +void    SSL_CTX_free(SSL_CTX *);
        +These 2 functions create and destroy SSL_CTX structures
        +
        +The SSL_CTX has a session_cache_mode which is by default,
        +in SSL_SESS_CACHE_SERVER mode.  What this means is that the library
        +will automatically add new session-id's to the cache upon successful
        +SSL_accept() calls.
        +If SSL_SESS_CACHE_CLIENT is set, then client certificates are also added
        +to the cache.
        +SSL_set_session_cache_mode(ctx,mode)  will set the 'mode' and
        +SSL_get_session_cache_mode(ctx) will get the cache 'mode'.
        +The modes can be
        +SSL_SESS_CACHE_OFF	- no caching
        +SSL_SESS_CACHE_CLIENT	- only SSL_connect()
        +SSL_SESS_CACHE_SERVER	- only SSL_accept()
        +SSL_SESS_NO_CACHE_BOTH	- Either SSL_accept() or SSL_connect().
        +If SSL_SESS_CACHE_NO_AUTO_CLEAR is set, old timed out sessions are
        +not automatically removed each 255, SSL_connect()s or SSL_accept()s.
        +
        +By default, upon every 255 successful SSL_connect() or SSL_accept()s,
        +the cache is flush.  Please note that this could be expensive on
        +a heavily loaded SSL server, in which case, turn this off and
        +clear the cache of old entries 'manually' (with one of the functions
        +listed below) every few hours.  Perhaps I should up this number, it is hard
        +to say.  Remember, the '255' new calls is just a mechanism to get called
        +every now and then, in theory at most 255 new session-id's will have been
        +added but if 100 are added every minute, you would still have
        +500 in the cache before any would start being flushed (assuming a 3 minute
        +timeout)..
        +
        +int SSL_CTX_sess_hits(SSL_CTX *ctx);
        +int SSL_CTX_sess_misses(SSL_CTX *ctx);
        +int SSL_CTX_sess_timeouts(SSL_CTX *ctx);
        +These 3 functions return statistics about the SSL_CTX.  These 3 are the
        +number of session id reuses.  hits is the number of reuses, misses are the
        +number of lookups that failed, and timeouts is the number of cached
        +entries ignored because they had timeouted.
        +
        +ctx->new_session_cb is a function pointer to a function of type
        +int new_session_callback(SSL *ssl,SSL_SESSION *new);
        +This function, if set in the SSL_CTX structure is called whenever a new
        +SSL_SESSION is added to the cache.  If the callback returns non-zero, it
        +means that the application will have to do a SSL_SESSION_free()
        +on the structure (this is
        +to do with the cache keeping the reference counts correct, without the
        +application needing to know about it.
        +The 'active' parameter is the current SSL session for which this connection
        +was created.
        +
        +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,int (*cb)());
        +to set the callback,
        +int (*cb)() SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)
        +to get the callback.
        +
        +If the 'get session' callback is set, when a session id is looked up and
        +it is not in the session-id cache, this callback is called.  The callback is
        +of the form
        +SSL_SESSION *get_session_callback(unsigned char *sess_id,int sess_id_len,
        +	int *copy);
        +
        +The get_session_callback is intended to return null if no session id is found.
        +The reference count on the SSL_SESSION in incremented by the SSL library,
        +if copy is 1.  Otherwise, the reference count is not modified.
        +
        +void SSL_CTX_sess_set_get_cb(ctx,cb) sets the callback and
        +int (*cb)()SSL_CTX_sess_get_get_cb(ctx) returns the callback.
        +
        +These callbacks are basically intended to be used by processes to
        +send their session-id's to other processes.  I currently have not implemented
        +non-blocking semantics for these callbacks, it is upto the application
        +to make the callbacks efficient if they require blocking (perhaps
        +by 'saving' them and then 'posting them' when control returns from
        +the SSL_accept().
        +
        +LHASH *SSL_CTX_sessions(SSL_CTX *ctx)
        +This returns the session cache.  The lhash strucutre can be accessed for
        +statistics about the cache.
        +
        +void lh_stats(LHASH *lh, FILE *out);
        +void lh_node_stats(LHASH *lh, FILE *out);
        +void lh_node_usage_stats(LHASH *lh, FILE *out);
        +
        +can be used to print details about it's activity and current state.
        +You can also delve directly into the lhash structure for 14 different
        +counters that are kept against the structure.  When I wrote the lhash library,
        +I was interested in gathering statistics :-).
        +Have a read of doc/lhash.doc in the SSLeay distribution area for more details
        +on the lhash library.
        +
        +Now as mentioned ealier, when a SSL is created, it needs a SSL_CTX.
        +SSL *   SSL_new(SSL_CTX *);
        +
        +This stores a session.  A session is secret information shared between 2
        +SSL contexts.  It will only be created if both ends of the connection have
        +authenticated their peer to their satisfaction.  It basically contains
        +the information required to use a particular secret key cipher.
        +
        +To retrieve the SSL_CTX being used by a SSL,
        +SSL_CTX *SSL_get_SSL_CTX(SSL *s);
        +
        +Now when a SSL session is established between to programs, the 'session'
        +information that is cached in the SSL_CTX can me manipulated by the
        +following functions.
        +int SSL_set_session(SSL *s, SSL_SESSION *session);
        +This will set the SSL_SESSION to use for the next SSL_connect().  If you use
        +this function on an already 'open' established SSL connection, 'bad things
        +will happen'.  This function is meaning-less when used on a ssl strucutre
        +that is just about to be used in a SSL_accept() call since the
        +SSL_accept() will either create a new session or retrieve one from the
        +cache.
        +
        +SSL_SESSION *SSL_get_session(SSL *s);
        +This will return the SSL_SESSION for the current SSL, NULL if there is
        +no session associated with the SSL structure.
        +
        +The SSL sessions are kept in the SSL_CTX in a hash table, to remove a
        +session
        +void    SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
        +and to add one
        +int    SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
        +SSL_CTX_add_session() returns 1 if the session was already in the cache (so it
        +was not added).
        +Whenever a new session is created via SSL_connect()/SSL_accept(),
        +they are automatically added to the cache, depending on the session_cache_mode
        +settings.  SSL_set_session()
        +does not add it to the cache.  Just call SSL_CTX_add_session() if you do want the
        +session added.  For a 'client' this would not normally be the case.
        +SSL_CTX_add_session() is not normally ever used, except for doing 'evil' things
        +which the next 2 funtions help you do.
        +
        +int     i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
        +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,unsigned char **pp,long length);
        +These 2 functions are in the standard ASN1 library form and can be used to
        +load and save to a byte format, the SSL_SESSION structure.
        +With these functions, you can save and read these structures to a files or
        +arbitary byte string.
        +The PEM_write_SSL_SESSION(fp,x) and PEM_read_SSL_SESSION(fp,x,cb) will
        +write to a file pointer in base64 encoding.
        +
        +What you can do with this, is pass session information between separate
        +processes.  Please note, that you will probably also need to modify the
        +timeout information on the SSL_SESSIONs.
        +
        +long SSL_get_time(SSL_SESSION *s)
        +will return the 'time' that the session
        +was loaded.  The timeout is relative to this time.  This information is
        +saved when the SSL_SESSION is converted to binarary but it is stored
        +in as a unix long, which is rather OS dependant, but easy to convert back.
        +
        +long SSL_set_time(SSL_SESSION *s,long t) will set the above mentioned time.
        +The time value is just the value returned from time(3), and should really
        +be defined by be to be time_t.
        +
        +long SSL_get_timeout(SSL_SESSION *s);
        +long SSL_set_timeout(SSL_SESSION *s,long t);
        +These 2 retrieve and set the timeout which is just a number of secconds
        +from the 'SSL_get_time()' value.  When this time period has elapesed,
        +the session will no longer be in the cache (well it will actually be removed
        +the next time it is attempted to be retrieved, so you could 'bump'
        +the timeout so it remains valid).
        +The 'time' and 'timeout' are set on a session when it is created, not reset
        +each time it is reused.  If you did wish to 'bump it', just after establishing
        +a connection, do a
        +SSL_set_time(ssl,time(NULL));
        +
        +You can also use
        +SSL_CTX_set_timeout(SSL_CTX *ctx,unsigned long t) and
        +SSL_CTX_get_timeout(SSL_CTX *ctx) to manipulate the default timeouts for
        +all SSL connections created against a SSL_CTX.  If you set a timeout in
        +an SSL_CTX, all new SSL's created will inherit the timeout.  It can be over
        +written by the SSL_set_timeout(SSL *s,unsigned long t) function call.
        +If you 'set' the timeout back to 0, the system default will be used.
        +
        +SSL_SESSION *SSL_SESSION_new();
        +void SSL_SESSION_free(SSL_SESSION *ses);
        +These 2 functions are used to create and dispose of SSL_SESSION functions.
        +You should not ever normally need to use them unless you are using 
        +i2d_SSL_SESSION() and/or d2i_SSL_SESSION().  If you 'load' a SSL_SESSION
        +via d2i_SSL_SESSION(), you will need to SSL_SESSION_free() it.
        +Both SSL_set_session() and SSL_CTX_add_session() will 'take copies' of the
        +structure (via reference counts) when it is passed to them.
        +
        +SSL_CTX_flush_sessions(ctx,time);
        +The first function will clear all sessions from the cache, which have expired
        +relative to 'time' (which could just be time(NULL)).
        +
        +SSL_CTX_flush_sessions(ctx,0);
        +This is a special case that clears everything.
        +
        +As a final comment, a 'session' is not enough to establish a new
        +connection.  If a session has timed out, a certificate and private key
        +need to have been associated with the SSL structure.
        +SSL_copy_session_id(SSL *to,SSL *from); will copy not only the session
        +strucutre but also the private key and certificate associated with
        +'from'.
        +
        +EXAMPLES.
        +
        +So lets play at being a weird SSL server.
        +
        +/* setup a context */
        +ctx=SSL_CTX_new();
        +
        +/* Lets load some session from binary into the cache, why one would do
        + * this is not toally clear, but passing between programs does make sense
        + * Perhaps you are using 4096 bit keys and are happy to keep them
        + * valid for a week, to avoid the RSA overhead of 15 seconds, I'm not toally
        + * sure, perhaps this is a process called from an SSL inetd and this is being 
        + * passed to the application. */
        +session=d2i_SSL_SESSION(....)
        +SSL_CTX_add_session(ctx,session);
        +
        +/* Lets even add a session from a file */
        +session=PEM_read_SSL_SESSION(....)
        +SSL_CTX_add_session(ctx,session);
        +
        +/* create a new SSL structure */
        +ssl=SSL_new(ctx);
        +
        +/* At this point we want to be able to 'create' new session if
        + * required, so we need a certificate and RSAkey. */
        +SSL_use_RSAPrivateKey_file(ssl,...)
        +SSL_use_certificate_file(ssl,...)
        +
        +/* Now since we are a server, it make little sence to load a session against
        + * the ssl strucutre since a SSL_accept() will either create a new session or
        + * grab an existing one from the cache. */
        +
        +/* grab a socket descriptor */
        +fd=accept(...);
        +
        +/* associated it with the ssl strucutre */
        +SSL_set_fd(ssl,fd);
        +
        +SSL_accept(ssl); /* 'do' SSL using out cert and RSA key */
        +
        +/* Lets print out the session details or lets save it to a file,
        + * perhaps with a secret key cipher, so that we can pass it to the FBI
        + * when they want to decode the session :-).  While we have RSA
        + * this does not matter much but when I do SSLv3, this will allow a mechanism
        + * for the server/client to record the information needed to decode
        + * the traffic that went over the wire, even when using Diffie-Hellman */
        +PEM_write_SSL_SESSION(SSL_get_session(ssl),stdout,....)
        +
        +Lets 'connect' back to the caller using the same session id.
        +
        +ssl2=SSL_new(ctx);
        +fd2=connect(them);
        +SSL_set_fd(ssl2,fd2);
        +SSL_set_session(ssl2,SSL_get_session(ssl));
        +SSL_connect(ssl2);
        +
        +/* what the hell, lets accept no more connections using this session */
        +SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl),SSL_get_session(ssl));
        +
        +/* we could have just as easily used ssl2 since they both are using the
        + * same session.
        + * You will note that both ssl and ssl2 are still using the session, and
        + * the SSL_SESSION structure will be free()ed when both ssl and ssl2
        + * finish using the session.  Also note that you could continue to initiate
        + * connections using this session by doing SSL_get_session(ssl) to get the
        + * existing session, but SSL_accept() will not be able to find it to
        + * use for incoming connections.
        + * Of corse, the session will timeout at the far end and it will no
        + * longer be accepted after a while.  The time and timeout are ignored except
        + * by SSL_accept(). */
        +
        +/* Since we have had our server running for 10 weeks, and memory is getting
        + * short, perhaps we should clear the session cache to remove those
        + * 100000 session entries that have expired.  Some may consider this
        + * a memory leak :-) */
        +
        +SSL_CTX_flush_sessions(ctx,time(NULL));
        +
        +/* Ok, after a bit more time we wish to flush all sessions from the cache
        + * so that all new connections will be authenticated and incure the
        + * public key operation overhead */
        +
        +SSL_CTX_flush_sessions(ctx,0);
        +
        +/* As a final note, to copy everything to do with a SSL, use */
        +SSL_copy_session_id(SSL *to,SSL *from);
        +/* as this also copies the certificate and RSA key so new session can
        + * be established using the same details */
        +
        +
        +==== sha.doc ========================================================
        +
        +The SHA (Secure Hash Algorithm) library.
        +SHA is a message digest algorithm that can be used to condense an arbitrary
        +length message down to a 20 byte hash.  The functions all need to be passed
        +a SHA_CTX which is used to hold the SHA context during multiple SHA_Update()
        +function calls.  The normal method of use for this library is as follows
        +This library contains both SHA and SHA-1 digest algorithms.  SHA-1 is
        +an update to SHA (which should really be called SHA-0 now) which
        +tweaks the algorithm slightly.  The SHA-1 algorithm is used by simply
        +using SHA1_Init(), SHA1_Update(), SHA1_Final() and SHA1() instead of the
        +SHA*() calls
        +
        +SHA_Init(...);
        +SHA_Update(...);
        +...
        +SHA_Update(...);
        +SHA_Final(...);
        +
        +This library requires the inclusion of 'sha.h'.
        +
        +The functions are as follows:
        +
        +void SHA_Init(
        +SHA_CTX *c);
        +	This function needs to be called to initiate a SHA_CTX structure for
        +	use.
        +	
        +void SHA_Update(
        +SHA_CTX *c;
        +unsigned char *data;
        +unsigned long len);
        +	This updates the message digest context being generated with 'len'
        +	bytes from the 'data' pointer.  The number of bytes can be any
        +	length.
        +
        +void SHA_Final(
        +unsigned char *md;
        +SHA_CTX *c;
        +	This function is called when a message digest of the data digested
        +	with SHA_Update() is wanted.  The message digest is put in the 'md'
        +	array and is SHA_DIGEST_LENGTH (20) bytes long.
        +
        +unsigned char *SHA(
        +unsigned char *d;
        +unsigned long n;
        +unsigned char *md;
        +	This function performs a SHA_Init(), followed by a SHA_Update()
        +	followed by a SHA_Final() (using a local SHA_CTX).
        +	The resulting digest is put into 'md' if it is not NULL.
        +	Regardless of the value of 'md', the message
        +	digest is returned from the function.  If 'md' was NULL, the message
        +	digest returned is being stored in a static structure.
        +	
        +
        +==== speed.doc ========================================================
        +
        +To get an idea of the performance of this library, use
        +ssleay speed
        +
        +perl util/sp-diff.pl file1 file2
        +
        +will print out the relative differences between the 2 files which are
        +expected to be the output from the speed program.
        +
        +The performace of the library is very dependant on the Compiler
        +quality and various flags used to build.
        +
        +---
        +
        +These are some numbers I did comparing RSAref and SSLeay on a Pentium 100.
        +[ These numbers are all out of date, as of SSL - 0.6.1 the RSA
        +operations are about 2 times faster, so check the version number ]
        +
        +RSA performance.
        +
        +SSLeay 0.6.0
        +Pentium 100, 32meg, Windows NT Workstation 3.51
        +linux - gcc v 2.7.0 -O3 -fomit-frame-pointer -m486
        +and
        +Windows NT  - Windows NT 3.51 - Visual C++ 4.1   - 586 code + 32bit assember
        +Windows 3.1 - Windows NT 3.51 - Visual C++ 1.52c - 286 code + 32bit assember
        +NT Dos Shell- Windows NT 3.51 - Visual C++ 1.52c - 286 code + 16bit assember
        +
        +Times are how long it takes to do an RSA private key operation.
        +
        +	       512bits 1024bits
        +-------------------------------
        +SSLeay NT dll	0.042s   0.202s see above
        +SSLeay linux	0.046s   0.218s	Assember inner loops (normal build) 
        +SSLeay linux	0.067s   0.380s Pure C code with BN_LLONG defined
        +SSLeay W3.1 dll	0.108s 	 0.478s see above
        +SSLeay linux	0.109s   0.713s C without BN_LLONG.
        +RSAref2.0 linux	0.149s   0.936s
        +SSLeay MS-DOS	0.197s   1.049s see above
        +
        +486DX66, 32meg, Windows NT Server 3.51
        +	       512bits 1024bits
        +-------------------------------
        +SSLeay NT dll   0.084s	 0.495s	<- SSLeay 0.6.3
        +SSLeay NT dll   0.154s   0.882s
        +SSLeay W3.1 dll 0.335s   1.538s
        +SSLeay MS-DOS	0.490s   2.790s
        +
        +What I find cute is that I'm still faster than RSAref when using standard C,
        +without using the 'long long' data type :-), %35 faster for 512bit and we
        +scale up to 3.2 times faster for the 'default linux' build.  I should mention
        +that people should 'try' to use either x86-lnx.s (elf), x86-lnxa.s or
        +x86-sol.s for any x86 based unix they are building on.  The only problems
        +with be with syntax but the performance gain is quite large, especially for
        +servers.  The code is very simple, you just need to modify the 'header'.
        +
        +The message is, if you are stuck using RSAref, the RSA performance will be
        +bad. Considering the code was compiled for a pentium, the 486DX66 number
        +would indicate 'Use RSAref and turn you Pentium 100 into a 486DX66' :-). 
        +[ As of verson 0.6.1, it would be correct to say 'turn you pentium 100
        + into a 486DX33' :-) ]
        +
        +I won't tell people if the DLL's are using RSAref or my stuff if no-one
        +asks :-).
        +
        +eric
        +
        +PS while I know I could speed things up further, I will probably not do
        +   so due to the effort involved.  I did do some timings on the
        +   SSLeay bignum format -> RSAref number format conversion that occurs
        +   each time RSAref is used by SSLeay, and the numbers are trivial.
        +   0.00012s a call for 512bit vs 0.149s for the time spent in the function.
        +   0.00018s for 1024bit vs 0.938s.  Insignificant.
        +   So the 'way to go', to support faster RSA libraries, if people are keen,
        +   is to write 'glue' code in a similar way that I do for RSAref and send it
        +   to me :-).
        +   My base library still has the advantage of being able to operate on 
        +   any size numbers, and is not that far from the performance from the
        +   leaders in the field. (-%30?)
        +   [ Well as of 0.6.1 I am now the leader in the filed on x86 (we at
        +     least very close :-) ]
        +
        +   I suppose I should also mention some other numbers RSAref numbers, again
        +   on my Pentium.
        +		DES CBC		EDE-DES		MD5
        +   RSAref linux	 830k/s		 302k/s		4390k/s
        +   SSLeay linux  855k/s          319k/s        10025k/s
        +   SSLeay NT	1158k/s		 410k/s	       10470k/s
        +   SSLeay w31	 378k/s		 143k/s         2383k/s (fully 16bit)
        +
        +   Got to admit that Visual C++ 4.[01] is a damn fine compiler :-)
        +--
        +Eric Young                  | BOOL is tri-state according to Bill Gates.
        +AARNet: eay@cryptsoft.com   | RTFM Win32 GetMessage().
        +
        +
        +
        +
        +==== ssl-ciph.doc ========================================================
        +
        +This is a quick high level summery of how things work now.
        +
        +Each SSLv2 and SSLv3 cipher is composed of 4 major attributes plus a few extra
        +minor ones.
        +
        +They are 'The key exchange algorithm', which is RSA for SSLv2 but can also
        +be Diffle-Hellman for SSLv3.
        +
        +An 'Authenticion algorithm', which can be RSA, Diffle-Helman, DSS or
        +none.
        +
        +The cipher
        +
        +The MAC digest.
        +
        +A cipher can also be an export cipher and is either an SSLv2 or a
        +SSLv3 ciphers.
        +
        +To specify which ciphers to use, one can either specify all the ciphers,
        +one at a time, or use 'aliases' to specify the preference and order for
        +the ciphers.
        +
        +There are a large number of aliases, but the most importaint are
        +kRSA, kDHr, kDHd and kEDH for key exchange types.
        +
        +aRSA, aDSS, aNULL and aDH for authentication
        +DES, 3DES, RC4, RC2, IDEA and eNULL for ciphers
        +MD5, SHA0 and SHA1 digests
        +
        +Now where this becomes interesting is that these can be put together to
        +specify the order and ciphers you wish to use.
        +
        +To speed this up there are also aliases for certian groups of ciphers.
        +The main ones are
        +SSLv2	- all SSLv2 ciphers
        +SSLv3	- all SSLv3 ciphers
        +EXP	- all export ciphers
        +LOW	- all low strngth ciphers (no export ciphers, normally single DES)
        +MEDIUM	- 128 bit encryption
        +HIGH	- Triple DES
        +
        +These aliases can be joined in a : separated list which specifies to
        +add ciphers, move them to the current location and delete them.
        +
        +A simpler way to look at all of this is to use the 'ssleay ciphers -v' command.
        +The default library cipher spec is
        +!ADH:RC4+RSA:HIGH:MEDIUM:LOW:EXP:+SSLv2:+EXP
        +which means, first, remove from consideration any ciphers that do not
        +authenticate.  Next up, use ciphers using RC4 and RSA.  Next include the HIGH,
        +MEDIUM and the LOW security ciphers.  Finish up by adding all the export
        +ciphers on the end, then 'pull' all the SSLv2 and export ciphers to
        +the end of the list.
        +
        +The results are
        +$ ssleay ciphers -v '!ADH:RC4+RSA:HIGH:MEDIUM:LOW:EXP:+SSLv2:+EXP'
        +
        +RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
        +RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
        +EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
        +EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
        +DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
        +IDEA-CBC-MD5            SSLv3 Kx=RSA      Au=RSA  Enc=IDEA(128) Mac=SHA1
        +EDH-RSA-DES-CBC-SHA     SSLv3 Kx=DH       Au=RSA  Enc=DES(56)   Mac=SHA1
        +EDH-DSS-DES-CBC-SHA     SSLv3 Kx=DH       Au=DSS  Enc=DES(56)   Mac=SHA1
        +DES-CBC-SHA             SSLv3 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=SHA1
        +DES-CBC3-MD5            SSLv2 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=MD5 
        +DES-CBC-MD5             SSLv2 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=MD5 
        +IDEA-CBC-MD5            SSLv2 Kx=RSA      Au=RSA  Enc=IDEA(128) Mac=MD5 
        +RC2-CBC-MD5             SSLv2 Kx=RSA      Au=RSA  Enc=RC2(128)  Mac=MD5 
        +RC4-MD5                 SSLv2 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
        +EXP-EDH-RSA-DES-CBC     SSLv3 Kx=DH(512)  Au=RSA  Enc=DES(40)   Mac=SHA1 export
        +EXP-EDH-DSS-DES-CBC-SHA SSLv3 Kx=DH(512)  Au=DSS  Enc=DES(40)   Mac=SHA1 export
        +EXP-DES-CBC-SHA         SSLv3 Kx=RSA(512) Au=RSA  Enc=DES(40)   Mac=SHA1 export
        +EXP-RC2-CBC-MD5         SSLv3 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
        +EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
        +EXP-RC2-CBC-MD5         SSLv2 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
        +EXP-RC4-MD5             SSLv2 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
        +
        +I would recoment people use the 'ssleay ciphers -v "text"'
        +command to check what they are going to use.
        +
        +Anyway, I'm falling asleep here so I'll do some more tomorrow.
        +
        +eric
        +
        +==== ssl.doc ========================================================
        +
        +SSL_CTX_sessions(SSL_CTX *ctx) - the session-id hash table.
        +
        +/* Session-id cache stats */
        +SSL_CTX_sess_number
        +SSL_CTX_sess_connect
        +SSL_CTX_sess_connect_good
        +SSL_CTX_sess_accept
        +SSL_CTX_sess_accept_good
        +SSL_CTX_sess_hits
        +SSL_CTX_sess_cb_hits
        +SSL_CTX_sess_misses
        +SSL_CTX_sess_timeouts
        +
        +/* Session-id application notification callbacks */
        +SSL_CTX_sess_set_new_cb
        +SSL_CTX_sess_get_new_cb
        +SSL_CTX_sess_set_get_cb
        +SSL_CTX_sess_get_get_cb
        +
        +/* Session-id cache operation mode */
        +SSL_CTX_set_session_cache_mode
        +SSL_CTX_get_session_cache_mode
        +
        +/* Set default timeout values to use. */
        +SSL_CTX_set_timeout
        +SSL_CTX_get_timeout
        +
        +/* Global  SSL initalisation informational callback */
        +SSL_CTX_set_info_callback
        +SSL_CTX_get_info_callback
        +SSL_set_info_callback
        +SSL_get_info_callback
        +
        +/* If the SSL_accept/SSL_connect returned with -1, these indicate when
        + * we should re-call *.
        +SSL_want
        +SSL_want_nothing
        +SSL_want_read
        +SSL_want_write
        +SSL_want_x509_lookup
        +
        +/* Where we are in SSL initalisation, used in non-blocking, perhaps
        + * have a look at ssl/bio_ssl.c */
        +SSL_state
        +SSL_is_init_finished
        +SSL_in_init
        +SSL_in_connect_init
        +SSL_in_accept_init
        +
        +/* Used to set the 'inital' state so SSL_in_connect_init and SSL_in_accept_init
        + * can be used to work out which function to call. */
        +SSL_set_connect_state
        +SSL_set_accept_state
        +
        +/* Where to look for certificates for authentication */
        +SSL_set_default_verify_paths /* calles SSL_load_verify_locations */
        +SSL_load_verify_locations
        +
        +/* get info from an established connection */
        +SSL_get_session
        +SSL_get_certificate
        +SSL_get_SSL_CTX
        +
        +SSL_CTX_new
        +SSL_CTX_free
        +SSL_new
        +SSL_clear
        +SSL_free
        +
        +SSL_CTX_set_cipher_list
        +SSL_get_cipher
        +SSL_set_cipher_list
        +SSL_get_cipher_list
        +SSL_get_shared_ciphers
        +
        +SSL_accept
        +SSL_connect
        +SSL_read
        +SSL_write
        +
        +SSL_debug
        +
        +SSL_get_read_ahead
        +SSL_set_read_ahead
        +SSL_set_verify
        +
        +SSL_pending
        +
        +SSL_set_fd
        +SSL_set_rfd
        +SSL_set_wfd
        +SSL_set_bio
        +SSL_get_fd
        +SSL_get_rbio
        +SSL_get_wbio
        +
        +SSL_use_RSAPrivateKey
        +SSL_use_RSAPrivateKey_ASN1
        +SSL_use_RSAPrivateKey_file
        +SSL_use_PrivateKey
        +SSL_use_PrivateKey_ASN1
        +SSL_use_PrivateKey_file
        +SSL_use_certificate
        +SSL_use_certificate_ASN1
        +SSL_use_certificate_file
        +
        +ERR_load_SSL_strings
        +SSL_load_error_strings
        +
        +/* human readable version of the 'state' of the SSL connection. */
        +SSL_state_string
        +SSL_state_string_long
        +/* These 2 report what kind of IO operation the library was trying to
        + * perform last.  Probably not very usefull. */
        +SSL_rstate_string
        +SSL_rstate_string_long
        +
        +SSL_get_peer_certificate
        +
        +SSL_SESSION_new
        +SSL_SESSION_print_fp
        +SSL_SESSION_print
        +SSL_SESSION_free
        +i2d_SSL_SESSION
        +d2i_SSL_SESSION
        +
        +SSL_get_time
        +SSL_set_time
        +SSL_get_timeout
        +SSL_set_timeout
        +SSL_copy_session_id
        +SSL_set_session
        +SSL_CTX_add_session
        +SSL_CTX_remove_session
        +SSL_CTX_flush_sessions
        +
        +BIO_f_ssl
        +
        +/* used to hold information as to why a certificate verification failed */
        +SSL_set_verify_result
        +SSL_get_verify_result
        +
        +/* can be used by the application to associate data with an SSL structure.
        + * It needs to be 'free()ed' by the application */
        +SSL_set_app_data
        +SSL_get_app_data
        +
        +/* The following all set values that are kept in the SSL_CTX but
        + * are used as the default values when an SSL session is created.
        + * They are over writen by the relevent SSL_xxxx functions */
        +
        +/* SSL_set_verify */
        +void SSL_CTX_set_default_verify
        +
        +/* This callback, if set, totaly overrides the normal SSLeay verification
        + * functions and should return 1 on success and 0 on failure */
        +void SSL_CTX_set_cert_verify_callback
        +
        +/* The following are the same as the equivilent SSL_xxx functions.
        + * Only one copy of this information is kept and if a particular
        + * SSL structure has a local override, it is totally separate structure.
        + */
        +int SSL_CTX_use_RSAPrivateKey
        +int SSL_CTX_use_RSAPrivateKey_ASN1
        +int SSL_CTX_use_RSAPrivateKey_file
        +int SSL_CTX_use_PrivateKey
        +int SSL_CTX_use_PrivateKey_ASN1
        +int SSL_CTX_use_PrivateKey_file
        +int SSL_CTX_use_certificate
        +int SSL_CTX_use_certificate_ASN1
        +int SSL_CTX_use_certificate_file
        +
        +
        +==== ssl_ctx.doc ========================================================
        +
        +This is now a bit dated, quite a few of the SSL_ functions could be
        +SSL_CTX_ functions.  I will update this in the future. 30 Aug 1996
        +
        +From eay@orb.mincom.oz.au Mon Dec 11 21:37:08 1995
        +Received: by orb.mincom.oz.au id AA00696
        +  (5.65c/IDA-1.4.4 for eay); Mon, 11 Dec 1995 11:37:08 +1000
        +Date: Mon, 11 Dec 1995 11:37:08 +1000 (EST)
        +From: Eric Young <eay@mincom.oz.au>
        +X-Sender: eay@orb
        +To: sameer <sameer@c2.org>
        +Cc: Eric Young <eay@mincom.oz.au>
        +Subject: Re: PEM_readX509 oesn't seem to be working
        +In-Reply-To: <199512110102.RAA12521@infinity.c2.org>
        +Message-Id: <Pine.SOL.3.91.951211112115.28608D-100000@orb>
        +Mime-Version: 1.0
        +Content-Type: TEXT/PLAIN; charset=US-ASCII
        +Status: RO
        +X-Status: 
        +
        +On Sun, 10 Dec 1995, sameer wrote:
        +> 	OK, that's solved. I've found out that it is saying "no
        +> certificate set" in SSL_accept because s->conn == NULL
        +> so there is some place I need to initialize s->conn that I am
        +> not initializing it.
        +
        +The full order of things for a server should be.
        +
        +ctx=SSL_CTX_new();
        +
        +/* The next line should not really be using ctx->cert but I'll leave it 
        + * this way right now... I don't want a X509_ routine to know about an SSL
        + * structure, there should be an SSL_load_verify_locations... hmm, I may 
        + * add it tonight.
        + */
        +X509_load_verify_locations(ctx->cert,CAfile,CApath);
        +
        +/* Ok now for each new connection we do the following */
        +con=SSL_new(ctx);
        +SSL_set_fd(con,s);
        +SSL_set_verify(con,verify,verify_callback);
        +
        +/* set the certificate and private key to use. */
        +SSL_use_certificate_ASN1(con,X509_certificate);
        +SSL_use_RSAPrivateKey_ASN1(con,RSA_private_key);
        +
        +SSL_accept(con);
        +
        +SSL_read(con)/SSL_write(con);
        +
        +There is a bit more than that but that is basically the structure.
        +
        +Create a context and specify where to lookup certificates.
        +
        +foreach connection
        +	{
        +	create a SSL structure
        +	set the certificate and private key
        +	do a SSL_accept
        +	
        +	we should now be ok
        +	}
        +
        +eric
        +--
        +Eric Young                  | Signature removed since it was generating
        +AARNet: eay@mincom.oz.au    | more followups than the message contents :-)
        +
        +
        +
        +==== ssleay.doc ========================================================
        +
        +SSLeay: a cryptographic kitchen sink.
        +
        +1st December 1995
        +Way back at the start of April 1995, I was looking for a mindless
        +programming project.  A friend of mine (Tim Hudson) said "why don't you do SSL,
        +it has DES encryption in it and I would not mind using it in a SSL telnet".
        +While it was true I had written a DES library in previous years, litle
        +did I know what an expansive task SSL would turn into.
        +
        +First of all, the SSL protocol contains DES encryption.  Well and good.  My
        +DES library was fast and portable.  It also contained the RSA's RC4 stream
        +cipher.  Again, not a problem, some-one had just posted to sci.crypt
        +something that was claimed to be RC4.  It also contained IDEA, I had the
        +specifications, not a problem to implement.  MD5, an RFC, trivial, at most
        +I could spend a week or so trying to see if I could speed up the
        +implementation.  All in all a nice set of ciphers.
        +Then the first 'expantion of the scope', RSA public key
        +encryption.  Since I did not knowing a thing about public key encryption
        +or number theory, this appeared quite a daunting task.  Just writing a
        +big number library would be problomatic in itself, let alone making it fast.
        +At this point the scope of 'implementing SSL' expands eponentialy.
        +First of all, the RSA private keys  were being kept in ASN.1 format.
        +Thankfully the RSA PKCS series of documents explains this format.  So I now
        +needed to be able to encode and decode arbitary ASN.1 objects.  The Public
        +keys were embeded in X509 certificates.  Hmm... these are not only
        +ASN.1 objects but they make up a heirachy of authentication.  To
        +authenticate a X509 certificate one needs to retrieve it's issuers
        +certificate etc etc.  Hmm..., so I also need to implement some kind
        +of certificate management software.  I would also have to implement
        +software to authenticate certificates.  At this point the support code made
        +the SSL part of my library look quite small.
        +Around this time, the first version of SSLeay was released.
        +
        +Ah, but here was the problem, I was not happy with the code so far.  As may
        +have become obvious, I had been treating all of this as a learning
        +exersize, so I have completely written the library myself.  As such, due
        +to the way it had grown like a fungus, much of the library was not
        +'elagent' or neat.  There were global and static variables all over the
        +place, the SSL part did not even handle non-blocking IO.
        +The Great rewrite began.
        +
        +As of this point in time, the 'Great rewrite' has almost finished.  So what
        +follows is an approximate list of what is actually SSLeay 0.5.0
        +
        +/********* This needs to be updated for 0.6.0+ *************/
        +
        +---
        +The library contains the following routines.  Please note that most of these
        +functions are not specfic for SSL or any other particular cipher
        +implementation.  I have tried to make all the routines as general purpose
        +as possible.  So you should not think of this library as an SSL
        +implemtation, but rather as a library of cryptographic functions
        +that also contains SSL.  I refer to each of these function groupings as
        +libraries since they are often capable of functioning as independant
        +libraries
        +
        +First up, the general ciphers and message digests supported by the library.
        +
        +MD2	rfc???, a standard 'by parts' interface to this algorithm.
        +MD5	rfc???, the same type of interface as for the MD2 library except a
        +	different algorithm.
        +SHA	THe Secure Hash Algorithm.  Again the same type of interface as
        +	MD2/MD5 except the digest is 20 bytes.
        +SHA1	The 'revised' version of SHA.  Just about identical to SHA except
        +	for one tweak of an inner loop.
        +DES	This is my libdes library that has been floating around for the last
        +	few years.  It has been enhanced for no other reason than completeness.
        +	It now supports ecb, cbc, cfb, ofb, cfb64, ofb64 in normal mode and
        +	triple DES modes of ecb, cbc, cfb64 and ofb64.  cfb64 and ofb64 are
        +	functional interfaces to the 64 bit modes of cfb and ofb used in
        +	such a way thay they function as single character interfaces.
        +RC4	The RSA Inc. stream cipher.
        +RC2	The RSA Inc. block cipher.
        +IDEA	An implmentation of the IDEA cipher, the library supports ecb, cbc,
        +	cfb64 and ofb64 modes of operation.
        +
        +Now all the above mentioned ciphers and digests libraries support high
        +speed, minimal 'crap in the way' type interfaces.  For fastest and
        +lowest level access, these routines should be used directly.
        +
        +Now there was also the matter of public key crypto systems.  These are
        +based on large integer arithmatic.
        +
        +BN	This is my large integer library.  It supports all the normal
        +	arithmentic operations.  It uses malloc extensivly and as such has
        +	no limits of the size of the numbers being manipulated.  If you
        +	wish to use 4000 bit RSA moduli, these routines will handle it.
        +	This library also contains routines to 'generate' prime numbers and
        +	to test for primality.  The RSA and DH libraries sit on top of this
        +	library.  As of this point in time, I don't support SHA, but
        +	when I do add it, it will just sit on top of the routines contained
        +	in this library.
        +RSA	This implements the RSA public key algorithm.  It also contains
        +	routines that will generate a new private/public key pair.
        +	All the RSA functions conform to the PKCS#1 standard.
        +DH	This is an implementation of the
        +	Diffie-Hellman protocol.  There are all the require routines for
        +	the protocol, plus extra routines that can be used to generate a
        +	strong prime for use with a specified generator.  While this last
        +	routine is not generally required by applications implementing DH,
        +	It is present for completeness and because I thing it is much
        +	better to be able to 'generate' your own 'magic' numbers as oposed
        +	to using numbers suplied by others.  I conform to the PKCS#3
        +	standard where required.
        +
        +You may have noticed the preceeding section mentions the 'generation' of
        +prime numbers.  Now this requries the use of 'random numbers'. 
        +
        +RAND	This psuedo-random number library is based on MD5 at it's core
        +	and a large internal state (2k bytes).  Once you have entered enough
        +	seed data into this random number algorithm I don't feel
        +	you will ever need to worry about it generating predictable output.
        +	Due to the way I am writing a portable library, I have left the
        +	issue of how to get good initial random seed data upto the
        +	application but I do have support routines for saving and loading a
        +	persistant random number state for use between program runs.
        +	
        +Now to make all these ciphers easier to use, a higher level
        +interface was required.  In this form, the same function would be used to
        +encrypt 'by parts', via any one of the above mentioned ciphers.
        +
        +EVP	The Digital EnVeloPe library is quite large.  At it's core are
        +	function to perform encryption and decryption by parts while using
        +	an initial parameter to specify which of the 17 different ciphers
        +	or 4 different message digests to use.  On top of these are implmented
        +	the digital signature functions, sign, verify, seal and open.
        +	Base64 encoding of binary data is also done in this library.
        +
        +PEM	rfc???? describe the format for Privacy Enhanced eMail.
        +	As part of this standard, methods of encoding digital enveloped
        +	data is an ascii format are defined.  As such, I use a form of these
        +	to encode enveloped data.  While at this point in time full support
        +	for PEM has not been built into the library, a minimal subset of
        +	the secret key and Base64 encoding is present.  These reoutines are
        +	mostly used to Ascii encode binary data with a 'type' associated
        +	with it and perhaps details of private key encryption used to
        +	encrypt the data.
        +	
        +PKCS7	This is another Digital Envelope encoding standard which uses ASN.1
        +	to encode the data.  At this point in time, while there are some
        +	routines to encode and decode this binary format, full support is
        +	not present.
        +	
        +As Mentioned, above, there are several different ways to encode
        +data structures.
        +
        +ASN1	This library is more a set of primatives used to encode the packing
        +	and unpacking of data structures.  It is used by the X509
        +	certificate standard and by the PKCS standards which are used by
        +	this library.  It also contains routines for duplicating and signing
        +	the structures asocisated with X509.
        +	
        +X509	The X509 library contains routines for packing and unpacking,
        +	verifying and just about every thing else you would want to do with
        +	X509 certificates.
        +
        +PKCS7	PKCS-7 is a standard for encoding digital envelope data
        +	structures.  At this point in time the routines will load and save
        +	DER forms of these structees.  They need to be re-worked to support
        +	the BER form which is the normal way PKCS-7 is encoded.  If the
        +	previous 2 sentances don't make much sense, don't worry, this
        +	library is not used by this version of SSLeay anyway.
        +
        +OBJ	ASN.1 uses 'object identifiers' to identify objects.  A set of
        +	functions were requred to translate from ASN.1 to an intenger, to a
        +	character string.  This library provieds these translations
        +	
        +Now I mentioned an X509 library.  X509 specified a hieachy of certificates
        +which needs to be traversed to authenticate particular certificates.
        +
        +METH	This library is used to push 'methods' of retrieving certificates
        +	into the library.  There are some supplied 'methods' with SSLeay
        +	but applications can add new methods if they so desire.
        +	This library has not been finished and is not being used in this
        +	version.
        +	
        +Now all the above are required for use in the initial point of this project.
        +
        +SSL	The SSL protocol.  This is a full implmentation of SSL v 2.  It
        +	support both server and client authentication.  SSL v 3 support
        +	will be added when the SSL v 3 specification is released in it's
        +	final form.
        +
        +Now quite a few of the above mentioned libraries rely on a few 'complex'
        +data structures.  For each of these I have a library.
        +
        +Lhash	This is a hash table library which is used extensivly.
        +
        +STACK	An implemetation of a Stack data structure.
        +
        +BUF	A simple character array structure that also support a function to
        +	check that the array is greater that a certain size, if it is not,
        +	it is realloced so that is it.
        +	
        +TXT_DB	A simple memory based text file data base.  The application can specify
        +	unique indexes that will be enforced at update time.
        +
        +CONF	Most of the programs written for this library require a configuration
        +	file.  Instead of letting programs constantly re-implment this
        +	subsystem, the CONF library provides a consistant and flexable
        +	interface to not only configuration files but also environment
        +	variables.
        +
        +But what about when something goes wrong?
        +The one advantage (and perhaps disadvantage) of all of these
        +functions being in one library was the ability to implement a
        +single error reporting system.
        +	
        +ERR	This library is used to report errors.  The error system records
        +	library number, function number (in the library) and reason
        +	number.  Multiple errors can be reported so that an 'error' trace
        +	is created.  The errors can be printed in numeric or textual form.
        +
        +
        +==== ssluse.doc ========================================================
        +
        +We have an SSL_CTX which contains global information for lots of
        +SSL connections.  The session-id cache and the certificate verificate cache.
        +It also contains default values for use when certificates are used.
        +
        +SSL_CTX
        +	default cipher list
        +	session-id cache
        +	certificate cache
        +	default session-id timeout period
        +	New session-id callback
        +	Required session-id callback
        +	session-id stats
        +	Informational callback
        +	Callback that is set, overrides the SSLeay X509 certificate
        +	  verification
        +	The default Certificate/Private Key pair
        +	Default read ahead mode.
        +	Default verify mode and verify callback.  These are not used
        +	  if the over ride callback mentioned above is used.
        +	
        +Each SSL can have the following defined for it before a connection is made.
        +
        +Certificate
        +Private key
        +Ciphers to use
        +Certificate verify mode and callback
        +IO object to use in the comunication.
        +Some 'read-ahead' mode information.
        +A previous session-id to re-use.
        +
        +A connection is made by using SSL_connect or SSL_accept.
        +When non-blocking IO is being used, there are functions that can be used
        +to determin where and why the SSL_connect or SSL_accept did not complete.
        +This information can be used to recall the functions when the 'error'
        +condition has dissapeared.
        +
        +After the connection has been made, information can be retrived about the
        +SSL session and the session-id values that have been decided upon.
        +The 'peer' certificate can be retrieved.
        +
        +The session-id values include
        +'start time'
        +'timeout length'
        +
        +
        +
        +==== stack.doc ========================================================
        +
        +The stack data structure is used to store an ordered list of objects.
        +It is basically misnamed to call it a stack but it can function that way
        +and that is what I originally used it for.  Due to the way element
        +pointers are kept in a malloc()ed array, the most efficient way to use this
        +structure is to add and delete elements from the end via sk_pop() and
        +sk_push().  If you wish to do 'lookups' sk_find() is quite efficient since
        +it will sort the stack (if required) and then do a binary search to lookup 
        +the requested item.  This sorting occurs automatically so just sk_push()
        +elements on the stack and don't worry about the order.  Do remember that if
        +you do a sk_find(), the order of the elements will change.
        +
        +You should never need to 'touch' this structure directly.
        +typedef struct stack_st
        +	{
        +	unsigned int num;
        +	char **data;
        +	int sorted;
        +
        +	unsigned int num_alloc;
        +	int (*comp)();
        +	} STACK;
        +
        +'num' holds the number of elements in the stack, 'data' is the array of
        +elements.  'sorted' is 1 is the list has been sorted, 0 if not.
        +
        +num_alloc is the number of 'nodes' allocated in 'data'.  When num becomes
        +larger than num_alloc, data is realloced to a larger size.
        +If 'comp' is set, it is a function that is used to compare 2 of the items
        +in the stack.  The function should return -1, 0 or 1, depending on the
        +ordering.
        +
        +#define sk_num(sk)	((sk)->num)
        +#define sk_value(sk,n)	((sk)->data[n])
        +
        +These 2 macros should be used to access the number of elements in the
        +'stack' and to access a pointer to one of the values.
        +
        +STACK *sk_new(int (*c)());
        +	This creates a new stack.  If 'c', the comparison function, is not
        +specified, the various functions that operate on a sorted 'stack' will not
        +work (sk_find()).  NULL is returned on failure.
        +
        +void sk_free(STACK *);
        +	This function free()'s a stack structure.  The elements in the
        +stack will not be freed so one should 'pop' and free all elements from the
        +stack before calling this function or call sk_pop_free() instead.
        +
        +void sk_pop_free(STACK *st; void (*func)());
        +	This function calls 'func' for each element on the stack, passing
        +the element as the argument.  sk_free() is then called to free the 'stack'
        +structure.
        +
        +int sk_insert(STACK *sk,char *data,int where);
        +	This function inserts 'data' into stack 'sk' at location 'where'.
        +If 'where' is larger that the number of elements in the stack, the element
        +is put at the end.  This function tends to be used by other 'stack'
        +functions.  Returns 0 on failure, otherwise the number of elements in the
        +new stack.
        +
        +char *sk_delete(STACK *st,int loc);
        +	Remove the item a location 'loc' from the stack and returns it.
        +Returns NULL if the 'loc' is out of range.
        +
        +char *sk_delete_ptr(STACK *st, char *p);
        +	If the data item pointed to by 'p' is in the stack, it is deleted
        +from the stack and returned.  NULL is returned if the element is not in the
        +stack.
        +
        +int sk_find(STACK *st,char *data);
        +	Returns the location that contains a value that is equal to 
        +the 'data' item.  If the comparison function was not set, this function
        +does a linear search.  This function actually qsort()s the stack if it is not
        +in order and then uses bsearch() to do the initial search.  If the
        +search fails,, -1 is returned.  For mutliple items with the same
        +value, the index of the first in the array is returned.
        +
        +int sk_push(STACK *st,char *data);
        +	Append 'data' to the stack.  0 is returned if there is a failure
        +(due to a malloc failure), else 1.  This is 
        +sk_insert(st,data,sk_num(st));
        +
        +int sk_unshift(STACK *st,char *data);
        +	Prepend 'data' to the front (location 0) of the stack.  This is
        +sk_insert(st,data,0);
        +
        +char *sk_shift(STACK *st);
        +	Return and delete from the stack the first element in the stack.
        +This is sk_delete(st,0);
        +
        +char *sk_pop(STACK *st);
        +	Return and delete the last element on the stack.  This is
        +sk_delete(st,sk_num(sk)-1);
        +
        +void sk_zero(STACK *st);
        +	Removes all items from the stack.  It does not 'free'
        +pointers but is a quick way to clear a 'stack of references'.
        +
        +==== threads.doc ========================================================
        +
        +How to compile SSLeay for multi-threading.
        +
        +Well basically it is quite simple, set the compiler flags and build.
        +I have only really done much testing under Solaris and Windows NT.
        +If you library supports localtime_r() and gmtime_r() add,
        +-DTHREADS to the makefile parameters.  You can probably survive with out
        +this define unless you are going to have multiple threads generating
        +certificates at once.  It will not affect the SSL side of things.
        +
        +The approach I have taken to doing locking is to make the application provide
        +callbacks to perform locking and so that the SSLeay library can distinguish
        +between threads (for the error state).
        +
        +To have a look at an example program, 'cd mt; vi mttest.c'.
        +To build under solaris, sh solaris.sh, for Windows NT or Windows 95,
        +win32.bat
        +
        +This will build mttest which will fire up 10 threads that talk SSL
        +to each other 10 times.
        +To enable everything to work, the application needs to call
        +
        +CRYPTO_set_id_callback(id_function);
        +CRYPTO_set_locking_callback(locking_function);
        +
        +before any multithreading is started.
        +id_function does not need to be defined under Windows NT or 95, the
        +correct function will be called if it is not.  Under unix, getpid()
        +is call if the id_callback is not defined, for Solaris this is wrong
        +(since threads id's are not pid's) but under Linux it is correct
        +(threads are just processes sharing the data segement).
        +
        +The locking_callback is used to perform locking by the SSLeay library.
        +eg.
        +
        +void solaris_locking_callback(mode,type,file,line)
        +int mode;
        +int type;
        +char *file;
        +int line;
        +	{
        +	if (mode & CRYPTO_LOCK)
        +		mutex_lock(&(lock_cs[type]));
        +	else
        +		mutex_unlock(&(lock_cs[type]));
        +	}
        +
        +Now in this case I have used mutexes instead of read/write locks, since they
        +are faster and there are not many read locks in SSLeay, you may as well
        +always use write locks.  file and line are __FILE__ and __LINE__ from
        +the compile and can be usefull when debugging.
        +
        +Now as you can see, 'type' can be one of a range of values, these values are
        +defined in crypto/crypto.h
        +CRYPTO_get_lock_name(type) will return a text version of what the lock is.
        +There are CRYPTO_NUM_LOCKS locks required, so under solaris, the setup
        +for multi-threading can be
        +
        +static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
        +
        +void thread_setup()
        +	{
        +	int i;
        +
        +	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
        +		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
        +	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
        +	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
        +	}
        +
        +As a final note, under Windows NT or Windows 95, you have to be careful
        +not to mix the various threaded, unthreaded and debug libraries.
        +Normally if they are mixed incorrectly, mttest will crash just after printing
        +out some usage statistics at the end.  This is because the
        +different system libraries use different malloc routines and if
        +data is malloc()ed inside crypt32.dll or ssl32.dll and then free()ed by a
        +different library malloc, things get very confused.
        +
        +The default SSLeay DLL builds use /MD, so if you use this on your
        +application, things will work as expected.  If you use /MDd,
        +you will probably have to rebuild SSLeay using this flag.
        +I should modify util/mk1mf.pl so it does all this correctly, but 
        +this has not been done yet.
        +
        +One last warning.  Because locking overheads are actually quite large, the
        +statistics collected against the SSL_CTX for successfull connections etc
        +are not locked when updated.  This does make it possible for these
        +values to be slightly lower than they should be, if you are
        +running multithreaded on a multi-processor box, but this does not really
        +matter much.
        +
        +
        +==== txt_db.doc ========================================================
        +
        +TXT_DB, a simple text based in memory database.
        +
        +It holds rows of ascii data, for which the only special character is '\0'.
        +The rows can be of an unlimited length.
        +
        +==== why.doc ========================================================
        +
        +This file is more of a note for other people who wish to understand why
        +the build environment is the way it is :-).
        +
        +The include files 'depend' as follows.
        +Each of 
        +crypto/*/*.c includes crypto/cryptlib.h
        +ssl/*.c include ssl/ssl_locl.h
        +apps/*.c include apps/apps.h
        +crypto/cryptlib.h, ssl/ssl_locl.h and apps/apps.h
        +all include e_os.h which contains OS/environment specific information.
        +If you need to add something todo with a particular environment,
        +add it to this file.  It is worth remembering that quite a few libraries,
        +like lhash, des, md, sha etc etc do not include crypto/cryptlib.h.  This
        +is because these libraries should be 'independantly compilable' and so I
        +try to keep them this way.
        +e_os.h is not so much a part of SSLeay, as the placing in one spot all the
        +evil OS dependant muck.
        +
        +I wanted to automate as many things as possible.  This includes
        +error number generation.  A
        +make errors
        +will scan the source files for error codes, append them to the correct
        +header files, and generate the functions to print the text version
        +of the error numbers.  So don't even think about adding error numbers by
        +hand, put them in the form
        +XXXerr(XXXX_F_XXXX,YYYY_R_YYYY);
        +on line and it will be automatically picked up my a make errors.
        +
        +In a similar vein, programs to be added into ssleay in the apps directory
        +just need to have an entry added to E_EXE in makefile.ssl and
        +everthing will work as expected.  Don't edit progs.h by hand.
        +
        +make links re-generates the symbolic links that are used.  The reason why
        +I keep everything in its own directory, and don't put all the
        +test programs and header files in 'test' and 'include' is because I want
        +to keep the 'sub-libraries' independant.  I still 'pull' out
        +indervidual libraries for use in specific projects where the code is
        +required.  I have used the 'lhash' library in just about every software
        +project I have worked on :-).
        +
        +make depend generates dependancies and
        +make dclean removes them.
        +
        +You will notice that I use perl quite a bit when I could be using 'sed'.
        +The reason I decided to do this was to just stick to one 'extra' program.
        +For Windows NT, I have perl and no sed.
        +
        +The util/mk1mf.pl program can be used to generate a single makefile.
        +I use this because makefiles under Microsoft are horrific.
        +Each C compiler seems to have different linker formats, which have
        +to be used because the retarted C compilers explode when you do
        +cl -o file *.o.
        +
        +Now some would argue that I should just use the single makefile.  I don't
        +like it during develoment for 2 reasons.  First, the actuall make
        +command takes a long time.  For my current setup, if I'm in
        +crypto/bn and I type make, only the crypto/bn directory gets rebuilt,
        +which is nice when you are modifying prototypes in bn.h which
        +half the SSLeay depends on.  The second is that to add a new souce file
        +I just plonk it in at the required spot in the local makefile.  This
        +then alows me to keep things local, I don't need to modify a 'global'
        +tables (the make for unix, the make for NT, the make for w31...).
        +When I am ripping apart a library structure, it is nice to only
        +have to worry about one directory :-).
        +
        +Having said all this, for the hell of it I put together 2 files that
        +#include all the souce code (generated by doing a ls */*.o after a build).
        +crypto.c takes only 30 seconds to build under NT and 2 minutes under linux
        +for my pentium100.  Much faster that the normal build :-).
        +Again, the problem is that when using libraries, every program linked
        +to libcrypto.a would suddenly get 330k of library when it may only need
        +1k.  This technique does look like a nice way to do shared libraries though.
        +
        +Oh yes, as a final note, to 'build' a distribution, I just type
        +make dist.
        +This cleans and packages everything.  The directory needs to be called
        +SSLeay since the make does a 'cd ..' and renames and tars things up.
        +
        +==== req.1 ========================================================
        +
        +The 'req' command is used to manipulate and deal with pkcs#10
        +certificate requests.
        +
        +It's default mode of operation is to load a certificate and then
        +write it out again.
        +
        +By default the 'req' is read from stdin in 'PEM' format.
        +The -inform option can be used to specify 'pem' format or 'der'
        +format.  PEM format is the base64 encoding of the DER format.
        +
        +By default 'req' then writes the request back out. -outform can be used
        +to indicate the desired output format, be it 'pem' or 'der'.
        +
        +To specify an input file, use the '-in' option and the '-out' option
        +can be used to specify the output file.
        +
        +If you wish to perform a command and not output the certificate
        +request afterwards, use the '-noout' option.
        +
        +When a certificate is loaded, it can be printed in a human readable
        +ascii format via the '-text' option.
        +
        +To check that the signature on a certificate request is correct, use
        +the '-verify' option to make sure that the private key contained in the
        +certificate request corresponds to the signature.
        +
        +Besides the default mode, there is also the 'generate a certificate
        +request' mode.  There are several flags that trigger this mode.
        +
        +-new will generate a new RSA key (if required) and then prompts
        +the user for details for the certificate request.
        +-newkey has an argument that is the number of bits to make the new
        +key.  This function also triggers '-new'.
        +
        +The '-new' option can have a key to use specified instead of having to
        +load one, '-key' is used to specify the file containg the key.
        +-keyform can be used to specify the format of the key.  Only
        +'pem' and 'der' formats are supported, later, 'netscape' format may be added.
        +
        +Finally there is the '-x509' options which makes req output a self
        +signed x509 certificate instead of a certificate request.
        +
        +Now as you may have noticed, there are lots of default options that
        +cannot be specified via the command line.  They are held in a 'template'
        +or 'configuration file'.  The -config option specifies which configuration
        +file to use.  See conf.doc for details on the syntax of this file.
        +
        +The req command uses the 'req' section of the config file.
        +
        +---
        +# The following variables are defined.  For this example I will populate
        +# the various values
        +[ req ]
        +default_bits	= 512		# default number of bits to use.
        +default_keyfile	= testkey.pem	# Where to write the generated keyfile
        +				# if not specified.
        +distinguished_name= req_dn	# The section that contains the
        +				# information about which 'object' we
        +				# want to put in the DN.
        +attributes	= req_attr	# The objects we want for the
        +				# attributes field.
        +encrypt_rsa_key	= no		# Should we encrypt newly generated
        +				# keys.  I strongly recommend 'yes'.
        +
        +# The distinguished name section.  For the following entries, the
        +# object names must exist in the SSLeay header file objects.h.  If they
        +# do not, they will be silently ignored.  The entries have the following
        +# format.
        +# <object_name>		=> string to prompt with
        +# <object_name>_default	=> default value for people
        +# <object_name>_value	=> Automatically use this value for this field.
        +# <object_name>_min	=> minimum number of characters for data (def. 0)
        +# <object_name>_max	=> maximum number of characters for data (def. inf.)
        +# All of these entries are optional except for the first one.
        +[ req_dn ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +
        +stateOrProvinceName		= State or Province Name (full name)
        +stateOrProvinceName_default	= Queensland
        +
        +localityName			= Locality Name (eg, city)
        +
        +organizationName		= Organization Name (eg, company)
        +organizationName_default	= Mincom Pty Ltd
        +
        +organizationalUnitName		= Organizational Unit Name (eg, section)
        +organizationalUnitName_default	= MTR
        +
        +commonName			= Common Name (eg, YOUR name)
        +commonName_max			= 64
        +
        +emailAddress			= Email Address
        +emailAddress_max		= 40
        +
        +# The next section is the attributes section.  This is exactly the
        +# same as for the previous section except that the resulting objects are
        +# put in the attributes field. 
        +[ req_attr ]
        +challengePassword		= A challenge password
        +challengePassword_min		= 4
        +challengePassword_max		= 20
        +
        +unstructuredName		= An optional company name
        +
        +----
        +Also note that the order that attributes appear in this file is the
        +order they will be put into the distinguished name.
        +
        +Once this request has been generated, it can be sent to a CA for
        +certifying.
        +
        +----
        +A few quick examples....
        +
        +To generate a new request and a new key
        +req -new
        +
        +To generate a new request and a 1058 bit key
        +req -newkey 1058
        +
        +To generate a new request using a pre-existing key
        +req -new -key key.pem
        +
        +To generate a self signed x509 certificate from a certificate
        +request using a supplied key, and we want to see the text form of the
        +output certificate (which we will put in the file selfSign.pem
        +req -x509 -in req.pem -key key.pem -text -out selfSign.pem
        +
        +Verify that the signature is correct on a certificate request.
        +req -verify -in req.pem
        +
        +Verify that the signature was made using a specified public key.
        +req -verify -in req.pem -key key.pem
        +
        +Print the contents of a certificate request
        +req -text -in req.pem
        +
        +==== danger ========================================================
        +
        +If you specify a SSLv2 cipher, and the mode is SSLv23 and the server
        +can talk SSLv3, it will claim there is no cipher since you should be
        +using SSLv3.
        +
        +When tracing debug stuff, remember BIO_s_socket() is different to
        +BIO_s_connect().
        +
        +BSD/OS assember is not working
        +
        diff --git a/vendor/openssl/openssl/doc/standards.txt b/vendor/openssl/openssl/doc/standards.txt
        new file mode 100644
        index 000000000..7bada8d35
        --- /dev/null
        +++ b/vendor/openssl/openssl/doc/standards.txt
        @@ -0,0 +1,285 @@
        +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
        +whole or at least great parts) 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)
        +
        +2315 PKCS 7: Cryptographic Message Syntax Version 1.5. B. Kaliski.
        +     March 1998. (Format: TXT=69679 bytes) (Status: INFORMATIONAL)
        +
        +PKCS#8: Private-Key Information Syntax Standard
        +
        +PKCS#12: Personal Information Exchange Syntax Standard, version 1.0.
        +
        +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)
        +
        +2712 Addition of Kerberos Cipher Suites to Transport Layer Security
        +     (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes)
        +     (Status: PROPOSED STANDARD)
        +
        +2898 PKCS #5: Password-Based Cryptography Specification Version 2.0.
        +     B. Kaliski. September 2000. (Format: TXT=68692 bytes) (Status:
        +     INFORMATIONAL)
        +
        +2986 PKCS #10: Certification Request Syntax Specification Version 1.7.
        +     M. Nystrom, B. Kaliski. November 2000. (Format: TXT=27794 bytes)
        +     (Obsoletes RFC2314) (Status: INFORMATIONAL)
        +
        +3174 US Secure Hash Algorithm 1 (SHA1). D. Eastlake 3rd, P. Jones.
        +     September 2001. (Format: TXT=35525 bytes) (Status: INFORMATIONAL)
        +
        +3161 Internet X.509 Public Key Infrastructure, Time-Stamp Protocol (TSP)
        +     C. Adams, P. Cain, D. Pinkas, R. Zuccherato. August 2001
        +     (Status: PROPOSED STANDARD)
        +
        +3268 Advanced Encryption Standard (AES) Ciphersuites for Transport
        +     Layer Security (TLS). P. Chown. June 2002. (Format: TXT=13530 bytes)
        +     (Status: PROPOSED STANDARD)
        +
        +3279 Algorithms and Identifiers for the Internet X.509 Public Key
        +     Infrastructure Certificate and Certificate Revocation List (CRL)
        +     Profile. L. Bassham, W. Polk, R. Housley. April 2002. (Format:
        +     TXT=53833 bytes) (Status: PROPOSED STANDARD)
        +
        +3280 Internet X.509 Public Key Infrastructure Certificate and
        +     Certificate Revocation List (CRL) Profile. R. Housley, W. Polk, W.
        +     Ford, D. Solo. April 2002. (Format: TXT=295556 bytes) (Obsoletes
        +     RFC2459) (Status: PROPOSED STANDARD)
        +
        +3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography
        +     Specifications Version 2.1. J. Jonsson, B. Kaliski. February 2003.
        +     (Format: TXT=143173 bytes) (Obsoletes RFC2437) (Status:           
        +     INFORMATIONAL)                                         
        +
        +3713 A Description of the Camellia Encryption Algorithm. M. Matsui,
        +     J. Nakajima, S. Moriai. April 2004. (Format: TXT=25031 bytes)
        +     (Status: INFORMATIONAL)
        +
        +3820 Internet X.509 Public Key Infrastructure (PKI) Proxy Certificate
        +     Profile. S. Tuecke, V. Welch, D. Engert, L. Pearlman, M. Thompson.
        +     June 2004. (Format: TXT=86374 bytes) (Status: PROPOSED STANDARD)
        +
        +4132 Addition of Camellia Cipher Suites to Transport Layer Security
        +     (TLS). S. Moriai, A. Kato, M. Kanda. July 2005. (Format: TXT=13590
        +     bytes) (Status: PROPOSED STANDARD)
        +
        +4162 Addition of SEED Cipher Suites to Transport Layer Security (TLS).
        +     H.J. Lee, J.H. Yoon, J.I. Lee. August 2005. (Format: TXT=10578 bytes)
        +     (Status: PROPOSED STANDARD)
        +
        +4269 The SEED Encryption Algorithm. H.J. Lee, S.J. Lee, J.H. Yoon,
        +     D.H. Cheon, J.I. Lee. December 2005. (Format: TXT=34390 bytes)
        +     (Obsoletes RFC4009) (Status: INFORMATIONAL)
        +
        +
        +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)
        +
        +2025 The Simple Public-Key GSS-API Mechanism (SPKM). C. Adams. October
        +     1996. (Format: TXT=101692 bytes) (Status: PROPOSED STANDARD)
        +
        +2510 Internet X.509 Public Key Infrastructure Certificate Management
        +     Protocols. C. Adams, S. Farrell. March 1999. (Format: TXT=158178
        +     bytes) (Status: PROPOSED STANDARD)
        +
        +2511 Internet X.509 Certificate Request Message Format. M. Myers, C.
        +     Adams, D. Solo, D. Kemp. March 1999. (Format: TXT=48278 bytes)
        +     (Status: PROPOSED STANDARD)
        +
        +2527 Internet X.509 Public Key Infrastructure Certificate Policy and
        +     Certification Practices Framework. S. Chokhani, W. Ford. March 1999.
        +     (Format: TXT=91860 bytes) (Status: INFORMATIONAL)
        +
        +2538 Storing Certificates in the Domain Name System (DNS). D. Eastlake
        +     3rd, O. Gudmundsson. March 1999. (Format: TXT=19857 bytes) (Status:
        +     PROPOSED STANDARD)
        +
        +2539 Storage of Diffie-Hellman Keys in the Domain Name System (DNS).
        +     D. Eastlake 3rd. March 1999. (Format: TXT=21049 bytes) (Status:
        +     PROPOSED STANDARD)
        +
        +2559 Internet X.509 Public Key Infrastructure Operational Protocols -
        +     LDAPv2. S. Boeyen, T. Howes, P. Richard. April 1999. (Format:
        +     TXT=22889 bytes) (Updates RFC1778) (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)
        +
        +2587 Internet X.509 Public Key Infrastructure LDAPv2 Schema. S.
        +     Boeyen, T. Howes, P. Richard. June 1999. (Format: TXT=15102 bytes)
        +     (Status: PROPOSED STANDARD)
        +
        +2595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999.
        +     (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD)
        +
        +2631 Diffie-Hellman Key Agreement Method. E. Rescorla. June 1999.
        +     (Format: TXT=25932 bytes) (Status: PROPOSED STANDARD)
        +
        +2632 S/MIME Version 3 Certificate Handling. B. Ramsdell, Ed.. June
        +     1999. (Format: TXT=27925 bytes) (Status: PROPOSED STANDARD)
        +
        +2716 PPP EAP TLS Authentication Protocol. B. Aboba, D. Simon. October
        +     1999. (Format: TXT=50108 bytes) (Status: EXPERIMENTAL)
        +
        +2773 Encryption using KEA and SKIPJACK. R. Housley, P. Yee, W. Nace.
        +     February 2000. (Format: TXT=20008 bytes) (Updates RFC0959) (Status:
        +     EXPERIMENTAL)
        +
        +2797 Certificate Management Messages over CMS. M. Myers, X. Liu, J.
        +     Schaad, J. Weinstein. April 2000. (Format: TXT=103357 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)
        +
        +2876 Use of the KEA and SKIPJACK Algorithms in CMS. J. Pawling. July
        +     2000. (Format: TXT=29265 bytes) (Status: INFORMATIONAL)
        +
        +2984 Use of the CAST-128 Encryption Algorithm in CMS. C. Adams.
        +     October 2000. (Format: TXT=11591 bytes) (Status: PROPOSED STANDARD)
        +
        +2985 PKCS #9: Selected Object Classes and Attribute Types Version 2.0.
        +     M. Nystrom, B. Kaliski. November 2000. (Format: TXT=70703 bytes)
        +     (Status: INFORMATIONAL)
        +
        +3029 Internet X.509 Public Key Infrastructure Data Validation and
        +     Certification Server Protocols. C. Adams, P. Sylvester, M. Zolotarev,
        +     R. Zuccherato. February 2001. (Format: TXT=107347 bytes) (Status:
        +     EXPERIMENTAL)
        +
        +3039 Internet X.509 Public Key Infrastructure Qualified Certificates
        +     Profile. S. Santesson, W. Polk, P. Barzin, M. Nystrom. January 2001.
        +     (Format: TXT=67619 bytes) (Status: PROPOSED STANDARD)
        +
        +3058 Use of the IDEA Encryption Algorithm in CMS. S. Teiwes, P.
        +     Hartmann, D. Kuenzi. February 2001. (Format: TXT=17257 bytes)
        +     (Status: INFORMATIONAL)
        +
        +3161 Internet X.509 Public Key Infrastructure Time-Stamp Protocol
        +     (TSP). C. Adams, P. Cain, D. Pinkas, R. Zuccherato. August 2001.
        +     (Format: TXT=54585 bytes) (Status: PROPOSED STANDARD)
        +
        +3185 Reuse of CMS Content Encryption Keys. S. Farrell, S. Turner.
        +     October 2001. (Format: TXT=20404 bytes) (Status: PROPOSED STANDARD)
        +
        +3207 SMTP Service Extension for Secure SMTP over Transport Layer
        +     Security. P. Hoffman. February 2002. (Format: TXT=18679 bytes)
        +     (Obsoletes RFC2487) (Status: PROPOSED STANDARD)
        +
        +3217 Triple-DES and RC2 Key Wrapping. R. Housley. December 2001.
        +     (Format: TXT=19855 bytes) (Status: INFORMATIONAL)
        +
        +3274 Compressed Data Content Type for Cryptographic Message Syntax
        +     (CMS). P. Gutmann. June 2002. (Format: TXT=11276 bytes) (Status:
        +     PROPOSED STANDARD)
        +
        +3278 Use of Elliptic Curve Cryptography (ECC) Algorithms in
        +     Cryptographic Message Syntax (CMS). S. Blake-Wilson, D. Brown, P.
        +     Lambert. April 2002. (Format: TXT=33779 bytes) (Status:
        +     INFORMATIONAL)
        +
        +3281 An Internet Attribute Certificate Profile for Authorization. S.
        +     Farrell, R. Housley. April 2002. (Format: TXT=90580 bytes) (Status:
        +     PROPOSED STANDARD)
        +
        +3369 Cryptographic Message Syntax (CMS). R. Housley. August 2002.
        +     (Format: TXT=113975 bytes) (Obsoletes RFC2630, RFC3211) (Status:
        +     PROPOSED STANDARD)
        +
        +3370 Cryptographic Message Syntax (CMS) Algorithms. R. Housley. August
        +     2002. (Format: TXT=51001 bytes) (Obsoletes RFC2630, RFC3211) (Status:
        +     PROPOSED STANDARD)
        +
        +3377 Lightweight Directory Access Protocol (v3): Technical
        +     Specification. J. Hodges, R. Morgan. September 2002. (Format:
        +     TXT=9981 bytes) (Updates RFC2251, RFC2252, RFC2253, RFC2254, RFC2255,
        +     RFC2256, RFC2829, RFC2830) (Status: PROPOSED STANDARD)
        +
        +3394 Advanced Encryption Standard (AES) Key Wrap Algorithm. J. Schaad,
        +     R. Housley. September 2002. (Format: TXT=73072 bytes) (Status:
        +     INFORMATIONAL)
        +
        +3436 Transport Layer Security over Stream Control Transmission
        +     Protocol. A. Jungmaier, E. Rescorla, M. Tuexen. December 2002.
        +     (Format: TXT=16333 bytes) (Status: PROPOSED STANDARD)
        +
        +3657 Use of the Camellia Encryption Algorithm in Cryptographic 
        +     Message Syntax (CMS). S. Moriai, A. Kato. January 2004.
        +     (Format: TXT=26282 bytes) (Status: PROPOSED STANDARD)
        +
        +"Securing FTP with TLS", 01/27/2000, <draft-murray-auth-ftp-ssl-05.txt>  
        + 
        +
        +To be implemented:
        +------------------
        +
        +These are documents that describe things that are planed to be
        +implemented in the hopefully short future.
        +
        diff --git a/vendor/openssl/openssl/e_os.h b/vendor/openssl/openssl/e_os.h
        new file mode 100644
        index 000000000..79c139257
        --- /dev/null
        +++ b/vendor/openssl/openssl/e_os.h
        @@ -0,0 +1,734 @@
        +/* e_os.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#ifndef HEADER_E_OS_H
        +#define HEADER_E_OS_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#include <openssl/e_os2.h>
        +/* <openssl/e_os2.h> contains what we can justify to make visible
        + * to the outside; this file e_os.h is not part of the exported
        + * interface. */
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Used to checking reference counts, most while doing perl5 stuff :-) */
        +#ifdef REF_PRINT
        +#undef REF_PRINT
        +#define REF_PRINT(a,b)	fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a)
        +#endif
        +
        +#ifndef DEVRANDOM
        +/* set this to a comma-separated list of 'random' device files to try out.
        + * My default, we will try to read at least one of these files */
        +#define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
        +#endif
        +#ifndef DEVRANDOM_EGD
        +/* set this to a comma-seperated list of 'egd' sockets to try out. These
        + * sockets will be tried in the order listed in case accessing the device files
        + * listed in DEVRANDOM did not return enough entropy. */
        +#define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"
        +#endif
        +
        +#if defined(OPENSSL_SYS_VXWORKS)
        +#  define NO_SYS_PARAM_H
        +#  define NO_CHMOD
        +#  define NO_SYSLOG
        +#endif
        +  
        +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
        +# if macintosh==1
        +#  ifndef MAC_OS_GUSI_SOURCE
        +#    define MAC_OS_pre_X
        +#    define NO_SYS_TYPES_H
        +#  endif
        +#  define NO_SYS_PARAM_H
        +#  define NO_CHMOD
        +#  define NO_SYSLOG
        +#  undef  DEVRANDOM
        +#  define GETPID_IS_MEANINGLESS
        +# endif
        +#endif
        +
        +/********************************************************************
        + The Microsoft section
        + ********************************************************************/
        +/* The following is used because of the small stack in some
        + * Microsoft operating systems */
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32)
        +#  define MS_STATIC	static
        +#else
        +#  define MS_STATIC
        +#endif
        +
        +#if defined(OPENSSL_SYS_WIN32) && !defined(WIN32)
        +#  define WIN32
        +#endif
        +#if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS)
        +#  define WINDOWS
        +#endif
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS)
        +#  define MSDOS
        +#endif
        +
        +#if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS)
        +#  define GETPID_IS_MEANINGLESS
        +#endif
        +
        +#ifdef WIN32
        +#define get_last_sys_error()	GetLastError()
        +#define clear_sys_error()	SetLastError(0)
        +#if !defined(WINNT)
        +#define WIN_CONSOLE_BUG
        +#endif
        +#else
        +#define get_last_sys_error()	errno
        +#define clear_sys_error()	errno=0
        +#endif
        +
        +#if defined(WINDOWS)
        +#define get_last_socket_error()	WSAGetLastError()
        +#define clear_socket_error()	WSASetLastError(0)
        +#define readsocket(s,b,n)	recv((s),(b),(n),0)
        +#define writesocket(s,b,n)	send((s),(b),(n),0)
        +#elif defined(__DJGPP__)
        +#define WATT32
        +#define get_last_socket_error()	errno
        +#define clear_socket_error()	errno=0
        +#define closesocket(s)		close_s(s)
        +#define readsocket(s,b,n)	read_s(s,b,n)
        +#define writesocket(s,b,n)	send(s,b,n,0)
        +#elif defined(MAC_OS_pre_X)
        +#define get_last_socket_error()	errno
        +#define clear_socket_error()	errno=0
        +#define closesocket(s)		MacSocket_close(s)
        +#define readsocket(s,b,n)	MacSocket_recv((s),(b),(n),true)
        +#define writesocket(s,b,n)	MacSocket_send((s),(b),(n))
        +#elif defined(OPENSSL_SYS_VMS)
        +#define get_last_socket_error() errno
        +#define clear_socket_error()    errno=0
        +#define ioctlsocket(a,b,c)      ioctl(a,b,c)
        +#define closesocket(s)          close(s)
        +#define readsocket(s,b,n)       recv((s),(b),(n),0)
        +#define writesocket(s,b,n)      send((s),(b),(n),0)
        +#elif defined(OPENSSL_SYS_VXWORKS)
        +#define get_last_socket_error()	errno
        +#define clear_socket_error()	errno=0
        +#define ioctlsocket(a,b,c)	    ioctl((a),(b),(int)(c))
        +#define closesocket(s)		    close(s)
        +#define readsocket(s,b,n)	    read((s),(b),(n))
        +#define writesocket(s,b,n)	    write((s),(char *)(b),(n))
        +#elif defined(OPENSSL_SYS_BEOS_R5)
        +#define get_last_socket_error() errno
        +#define clear_socket_error()    errno=0
        +#define FIONBIO SO_NONBLOCK
        +#define ioctlsocket(a,b,c)		  setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c)))
        +#define readsocket(s,b,n)       recv((s),(b),(n),0)
        +#define writesocket(s,b,n)      send((s),(b),(n),0)
        +#elif defined(OPENSSL_SYS_NETWARE)
        +#if defined(NETWARE_BSDSOCK)
        +#define get_last_socket_error() errno
        +#define clear_socket_error()    errno=0
        +#define closesocket(s)          close(s)
        +#define ioctlsocket(a,b,c)      ioctl(a,b,c)
        +#if defined(NETWARE_LIBC)
        +#define readsocket(s,b,n)       recv((s),(b),(n),0)
        +#define writesocket(s,b,n)      send((s),(b),(n),0)
        +#else
        +#define readsocket(s,b,n)       recv((s),(char*)(b),(n),0)
        +#define writesocket(s,b,n)      send((s),(char*)(b),(n),0)
        +#endif
        +#else
        +#define get_last_socket_error()	WSAGetLastError()
        +#define clear_socket_error()	WSASetLastError(0)
        +#define readsocket(s,b,n)		recv((s),(b),(n),0)
        +#define writesocket(s,b,n)		send((s),(b),(n),0)
        +#endif
        +#else
        +#define get_last_socket_error()	errno
        +#define clear_socket_error()	errno=0
        +#define ioctlsocket(a,b,c)	ioctl(a,b,c)
        +#define closesocket(s)		close(s)
        +#define readsocket(s,b,n)	read((s),(b),(n))
        +#define writesocket(s,b,n)	write((s),(b),(n))
        +#endif
        +
        +#ifdef WIN16 /* never the case */
        +#  define MS_CALLBACK	_far _loadds
        +#  define MS_FAR	_far
        +#else
        +#  define MS_CALLBACK
        +#  define MS_FAR
        +#endif
        +
        +#ifdef OPENSSL_NO_STDIO
        +#  undef OPENSSL_NO_FP_API
        +#  define OPENSSL_NO_FP_API
        +#endif
        +
        +#if (defined(WINDOWS) || defined(MSDOS))
        +
        +#  ifdef __DJGPP__
        +#    include <unistd.h>
        +#    include <sys/stat.h>
        +#    include <sys/socket.h>
        +#    include <tcp.h>
        +#    include <netdb.h>
        +#    define _setmode setmode
        +#    define _O_TEXT O_TEXT
        +#    define _O_BINARY O_BINARY
        +#    undef DEVRANDOM
        +#    define DEVRANDOM "/dev/urandom\x24"
        +#  endif /* __DJGPP__ */
        +
        +#  ifndef S_IFDIR
        +#    define S_IFDIR	_S_IFDIR
        +#  endif
        +
        +#  ifndef S_IFMT
        +#    define S_IFMT	_S_IFMT
        +#  endif
        +
        +#  if !defined(WINNT) && !defined(__DJGPP__)
        +#    define NO_SYSLOG
        +#  endif
        +#  define NO_DIRENT
        +
        +#  ifdef WINDOWS
        +#    if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT)
        +       /*
        +	* Defining _WIN32_WINNT here in e_os.h implies certain "discipline."
        +	* Most notably we ought to check for availability of each specific
        +	* routine with GetProcAddress() and/or guard NT-specific calls with
        +	* GetVersion() < 0x80000000. One can argue that in latter "or" case
        +	* we ought to /DELAYLOAD some .DLLs in order to protect ourselves
        +	* against run-time link errors. This doesn't seem to be necessary,
        +	* because it turned out that already Windows 95, first non-NT Win32
        +	* implementation, is equipped with at least NT 3.51 stubs, dummy
        +	* routines with same name, but which do nothing. Meaning that it's
        +	* apparently sufficient to guard "vanilla" NT calls with GetVersion
        +	* alone, while NT 4.0 and above interfaces ought to be linked with
        +	* GetProcAddress at run-time.
        +	*/
        +#      define _WIN32_WINNT 0x0400
        +#    endif
        +#    if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT)
        +       /*
        +        * Just like defining _WIN32_WINNT including winsock2.h implies
        +        * certain "discipline" for maintaining [broad] binary compatibility.
        +        * As long as structures are invariant among Winsock versions,
        +        * it's sufficient to check for specific Winsock2 API availability
        +        * at run-time [DSO_global_lookup is recommended]...
        +        */
        +#      include <winsock2.h>
        +#      include <ws2tcpip.h>
        +       /* yes, they have to be #included prior to <windows.h> */
        +#    endif
        +#    include <windows.h>
        +#    include <stdio.h>
        +#    include <stddef.h>
        +#    include <errno.h>
        +#    include <string.h>
        +#    ifdef _WIN64
        +#      define strlen(s) _strlen31(s)
        +/* cut strings to 2GB */
        +static unsigned int _strlen31(const char *str)
        +	{
        +	unsigned int len=0;
        +	while (*str && len<0x80000000U) str++, len++;
        +	return len&0x7FFFFFFF;
        +	}
        +#    endif
        +#    include <malloc.h>
        +#    if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace)
        +       /* compensate for bug in VC6 ctype.h */
        +#      undef isspace
        +#      undef isdigit
        +#      undef isalnum
        +#      undef isupper
        +#      undef isxdigit
        +#    endif
        +#    if defined(_MSC_VER) && !defined(_DLL) && defined(stdin)
        +#      if _MSC_VER>=1300
        +#        undef stdin
        +#        undef stdout
        +#        undef stderr
        +         FILE *__iob_func();
        +#        define stdin  (&__iob_func()[0])
        +#        define stdout (&__iob_func()[1])
        +#        define stderr (&__iob_func()[2])
        +#      elif defined(I_CAN_LIVE_WITH_LNK4049)
        +#        undef stdin
        +#        undef stdout
        +#        undef stderr
        +         /* pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
        +          * or in other words with /MD. Declaring implicit import, i.e.
        +          * with _imp_ prefix, works correctly with all compiler options,
        +	  * but without /MD results in LINK warning LNK4049:
        +	  * 'locally defined symbol "__iob" imported'.
        +          */
        +         extern FILE *_imp___iob;
        +#        define stdin  (&_imp___iob[0])
        +#        define stdout (&_imp___iob[1])
        +#        define stderr (&_imp___iob[2])
        +#      endif
        +#    endif
        +#  endif
        +#  include <io.h>
        +#  include <fcntl.h>
        +
        +#  ifdef OPENSSL_SYS_WINCE
        +#    define OPENSSL_NO_POSIX_IO
        +#  endif
        +
        +#  if defined (__BORLANDC__)
        +#    define _setmode setmode
        +#    define _O_TEXT O_TEXT
        +#    define _O_BINARY O_BINARY
        +#    define _int64 __int64
        +#    define _kbhit kbhit
        +#  endif
        +
        +#  define EXIT(n) exit(n)
        +#  define LIST_SEPARATOR_CHAR ';'
        +#  ifndef X_OK
        +#    define X_OK	0
        +#  endif
        +#  ifndef W_OK
        +#    define W_OK	2
        +#  endif
        +#  ifndef R_OK
        +#    define R_OK	4
        +#  endif
        +#  define OPENSSL_CONF	"openssl.cnf"
        +#  define SSLEAY_CONF	OPENSSL_CONF
        +#  define NUL_DEV	"nul"
        +#  define RFILE		".rnd"
        +#  ifdef OPENSSL_SYS_WINCE
        +#    define DEFAULT_HOME  ""
        +#  else
        +#    define DEFAULT_HOME  "C:"
        +#  endif
        +
        +#else /* The non-microsoft world */
        +
        +#  ifdef OPENSSL_SYS_VMS
        +#    define VMS 1
        +  /* some programs don't include stdlib, so exit() and others give implicit 
        +     function warnings */
        +#    include <stdlib.h>
        +#    if defined(__DECC)
        +#      include <unistd.h>
        +#    else
        +#      include <unixlib.h>
        +#    endif
        +#    define OPENSSL_CONF	"openssl.cnf"
        +#    define SSLEAY_CONF		OPENSSL_CONF
        +#    define RFILE		".rnd"
        +#    define LIST_SEPARATOR_CHAR ','
        +#    define NUL_DEV		"NLA0:"
        +  /* We don't have any well-defined random devices on VMS, yet... */
        +#    undef DEVRANDOM
        +  /* We need to do this since VMS has the following coding on status codes:
        +
        +     Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ...
        +               The important thing to know is that odd numbers are considered
        +	       good, while even ones are considered errors.
        +     Bits 3-15: actual status number
        +     Bits 16-27: facility number.  0 is considered "unknown"
        +     Bits 28-31: control bits.  If bit 28 is set, the shell won't try to
        +                 output the message (which, for random codes, just looks ugly)
        +
        +     So, what we do here is to change 0 to 1 to get the default success status,
        +     and everything else is shifted up to fit into the status number field, and
        +     the status is tagged as an error, which I believe is what is wanted here.
        +     -- Richard Levitte
        +  */
        +#    define EXIT(n)		do { int __VMS_EXIT = n; \
        +                                     if (__VMS_EXIT == 0) \
        +				       __VMS_EXIT = 1; \
        +				     else \
        +				       __VMS_EXIT = (n << 3) | 2; \
        +                                     __VMS_EXIT |= 0x10000000; \
        +				     exit(__VMS_EXIT); } while(0)
        +#    define NO_SYS_PARAM_H
        +
        +#  elif defined(OPENSSL_SYS_NETWARE)
        +#    include <fcntl.h>
        +#    include <unistd.h>
        +#    define NO_SYS_TYPES_H
        +#    undef  DEVRANDOM
        +#    ifdef NETWARE_CLIB
        +#      define getpid GetThreadID
        +       extern int GetThreadID(void);
        +/* #      include <conio.h> */
        +       extern int kbhit(void);
        +#    else
        +#      include <screen.h>
        +#    endif
        +#    define NO_SYSLOG
        +#    define _setmode setmode
        +#    define _kbhit kbhit
        +#    define _O_TEXT O_TEXT
        +#    define _O_BINARY O_BINARY
        +#    define OPENSSL_CONF   "openssl.cnf"
        +#    define SSLEAY_CONF    OPENSSL_CONF
        +#    define RFILE    ".rnd"
        +#    define LIST_SEPARATOR_CHAR ';'
        +#    define EXIT(n)  { if (n) printf("ERROR: %d\n", (int)n); exit(n); }
        +
        +#  else
        +     /* !defined VMS */
        +#    ifdef OPENSSL_SYS_MPE
        +#      define NO_SYS_PARAM_H
        +#    endif
        +#    ifdef OPENSSL_UNISTD
        +#      include OPENSSL_UNISTD
        +#    else
        +#      include <unistd.h>
        +#    endif
        +#    ifndef NO_SYS_TYPES_H
        +#      include <sys/types.h>
        +#    endif
        +#    if defined(NeXT) || defined(OPENSSL_SYS_NEWS4)
        +#      define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP
        +                         * (unless when compiling with -D_POSIX_SOURCE,
        +                         * which doesn't work for us) */
        +#    endif
        +#    ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */
        +#      define setvbuf(a, b, c, d) setbuffer((a), (b), (d))
        +       typedef unsigned long clock_t;
        +#    endif
        +#    ifdef OPENSSL_SYS_WIN32_CYGWIN
        +#      include <io.h>
        +#      include <fcntl.h>
        +#    endif
        +
        +#    define OPENSSL_CONF	"openssl.cnf"
        +#    define SSLEAY_CONF		OPENSSL_CONF
        +#    define RFILE		".rnd"
        +#    define LIST_SEPARATOR_CHAR ':'
        +#    define NUL_DEV		"/dev/null"
        +#    define EXIT(n)		exit(n)
        +#  endif
        +
        +#  define SSLeay_getpid()	getpid()
        +
        +#endif
        +
        +
        +/*************/
        +
        +#ifdef USE_SOCKETS
        +#  if defined(WINDOWS) || defined(MSDOS)
        +      /* windows world */
        +
        +#    ifdef OPENSSL_NO_SOCK
        +#      define SSLeay_Write(a,b,c)	(-1)
        +#      define SSLeay_Read(a,b,c)	(-1)
        +#      define SHUTDOWN(fd)		close(fd)
        +#      define SHUTDOWN2(fd)		close(fd)
        +#    elif !defined(__DJGPP__)
        +#      if defined(_WIN32_WCE) && _WIN32_WCE<410
        +#        define getservbyname _masked_declaration_getservbyname
        +#      endif
        +#      if !defined(IPPROTO_IP)
        +         /* winsock[2].h was included already? */
        +#        include <winsock.h>
        +#      endif
        +#      ifdef getservbyname
        +#        undef getservbyname
        +         /* this is used to be wcecompat/include/winsock_extras.h */
        +         struct servent* PASCAL getservbyname(const char*,const char*);
        +#      endif
        +
        +#      ifdef _WIN64
        +/*
        + * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
        + * the value constitutes an index in per-process table of limited size
        + * and not a real pointer.
        + */
        +#        define socket(d,t,p)	((int)socket(d,t,p))
        +#        define accept(s,f,l)	((int)accept(s,f,l))
        +#      endif
        +#      define SSLeay_Write(a,b,c)	send((a),(b),(c),0)
        +#      define SSLeay_Read(a,b,c)	recv((a),(b),(c),0)
        +#      define SHUTDOWN(fd)		{ shutdown((fd),0); closesocket(fd); }
        +#      define SHUTDOWN2(fd)		{ shutdown((fd),2); closesocket(fd); }
        +#    else
        +#      define SSLeay_Write(a,b,c)	write_s(a,b,c,0)
        +#      define SSLeay_Read(a,b,c)	read_s(a,b,c)
        +#      define SHUTDOWN(fd)		close_s(fd)
        +#      define SHUTDOWN2(fd)		close_s(fd)
        +#    endif
        +
        +#  elif defined(MAC_OS_pre_X)
        +
        +#    include "MacSocket.h"
        +#    define SSLeay_Write(a,b,c)		MacSocket_send((a),(b),(c))
        +#    define SSLeay_Read(a,b,c)		MacSocket_recv((a),(b),(c),true)
        +#    define SHUTDOWN(fd)		MacSocket_close(fd)
        +#    define SHUTDOWN2(fd)		MacSocket_close(fd)
        +
        +#  elif defined(OPENSSL_SYS_NETWARE)
        +         /* NetWare uses the WinSock2 interfaces by default, but can be configured for BSD
        +         */
        +#      if defined(NETWARE_BSDSOCK)
        +#        include <sys/socket.h>
        +#        include <netinet/in.h>
        +#        include <sys/time.h>
        +#        if defined(NETWARE_CLIB)
        +#          include <sys/bsdskt.h>
        +#        else
        +#          include <sys/select.h>
        +#        endif
        +#        define INVALID_SOCKET (int)(~0)
        +#      else
        +#        include <novsock2.h>
        +#      endif
        +#      define SSLeay_Write(a,b,c)   send((a),(b),(c),0)
        +#      define SSLeay_Read(a,b,c) recv((a),(b),(c),0)
        +#      define SHUTDOWN(fd)    { shutdown((fd),0); closesocket(fd); }
        +#      define SHUTDOWN2(fd)      { shutdown((fd),2); closesocket(fd); }
        +
        +#  else
        +
        +#    ifndef NO_SYS_PARAM_H
        +#      include <sys/param.h>
        +#    endif
        +#    ifdef OPENSSL_SYS_VXWORKS
        +#      include <time.h> 
        +#    elif !defined(OPENSSL_SYS_MPE)
        +#      include <sys/time.h> /* Needed under linux for FD_XXX */
        +#    endif
        +
        +#    include <netdb.h>
        +#    if defined(OPENSSL_SYS_VMS_NODECC)
        +#      include <socket.h>
        +#      include <in.h>
        +#      include <inet.h>
        +#    else
        +#      include <sys/socket.h>
        +#      ifdef FILIO_H
        +#        include <sys/filio.h> /* Added for FIONBIO under unixware */
        +#      endif
        +#      include <netinet/in.h>
        +#      if !defined(OPENSSL_SYS_BEOS_R5)
        +#      include <arpa/inet.h>
        +#    endif
        +#    endif
        +
        +#    if defined(NeXT) || defined(_NEXT_SOURCE)
        +#      include <sys/fcntl.h>
        +#      include <sys/types.h>
        +#    endif
        +
        +#    ifdef OPENSSL_SYS_AIX
        +#      include <sys/select.h>
        +#    endif
        +
        +#    ifdef __QNX__
        +#      include <sys/select.h>
        +#    endif
        +
        +#    if defined(sun)
        +#      include <sys/filio.h>
        +#    else
        +#      ifndef VMS
        +#        include <sys/ioctl.h>
        +#      else
        +	 /* ioctl is only in VMS > 7.0 and when socketshr is not used */
        +#        if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
        +#          include <sys/ioctl.h>
        +#        endif
        +#      endif
        +#    endif
        +
        +#    ifdef VMS
        +#      include <unixio.h>
        +#      if defined(TCPIP_TYPE_SOCKETSHR)
        +#        include <socketshr.h>
        +#      endif
        +#    endif
        +
        +#    define SSLeay_Read(a,b,c)     read((a),(b),(c))
        +#    define SSLeay_Write(a,b,c)    write((a),(b),(c))
        +#    define SHUTDOWN(fd)    { shutdown((fd),0); closesocket((fd)); }
        +#    define SHUTDOWN2(fd)   { shutdown((fd),2); closesocket((fd)); }
        +#    ifndef INVALID_SOCKET
        +#    define INVALID_SOCKET	(-1)
        +#    endif /* INVALID_SOCKET */
        +#  endif
        +
        +/* Some IPv6 implementations are broken, disable them in known bad
        + * versions.
        + */
        +#  if !defined(OPENSSL_USE_IPV6)
        +#    if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB)
        +#      define OPENSSL_USE_IPV6 1
        +#    else
        +#      define OPENSSL_USE_IPV6 0
        +#    endif
        +#  endif
        +
        +#endif
        +
        +#if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
        +  /* include headers first, so our defines don't break it */
        +#include <stdlib.h>
        +#include <string.h>
        +  /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */
        +# define memmove(s1,s2,n) bcopy((s2),(s1),(n))
        +# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b)))
        +extern char *sys_errlist[]; extern int sys_nerr;
        +# define strerror(errnum) \
        +	(((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum])
        +  /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */
        +#include "crypto/o_str.h"
        +# define memcmp OPENSSL_memcmp
        +#endif
        +
        +#ifndef OPENSSL_EXIT
        +# if defined(MONOLITH) && !defined(OPENSSL_C)
        +#  define OPENSSL_EXIT(n) return(n)
        +# else
        +#  define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0)
        +# endif
        +#endif
        +
        +/***********************************************/
        +
        +#define DG_GCC_BUG	/* gcc < 2.6.3 on DGUX */
        +
        +#ifdef sgi
        +#define IRIX_CC_BUG	/* all version of IRIX I've tested (4.* 5.*) */
        +#endif
        +#ifdef OPENSSL_SYS_SNI
        +#define IRIX_CC_BUG	/* CDS++ up to V2.0Bsomething suffered from the same bug.*/
        +#endif
        +
        +#if defined(OPENSSL_SYS_WINDOWS)
        +#  define strcasecmp _stricmp
        +#  define strncasecmp _strnicmp
        +#elif defined(OPENSSL_SYS_VMS)
        +/* VMS below version 7.0 doesn't have strcasecmp() */
        +#  include "o_str.h"
        +#  define strcasecmp OPENSSL_strcasecmp
        +#  define strncasecmp OPENSSL_strncasecmp
        +#  define OPENSSL_IMPLEMENTS_strncasecmp
        +#elif defined(OPENSSL_SYS_OS2) && defined(__EMX__)
        +#  define strcasecmp stricmp
        +#  define strncasecmp strnicmp
        +#elif defined(OPENSSL_SYS_NETWARE)
        +#  include <string.h>
        +#  if defined(NETWARE_CLIB)
        +#    define strcasecmp stricmp
        +#    define strncasecmp strnicmp
        +#  endif /* NETWARE_CLIB */
        +#endif
        +
        +#if defined(OPENSSL_SYS_OS2) && defined(__EMX__)
        +# include <io.h>
        +# include <fcntl.h>
        +# define NO_SYSLOG
        +#endif
        +
        +/* vxworks */
        +#if defined(OPENSSL_SYS_VXWORKS)
        +#include <ioLib.h>
        +#include <tickLib.h>
        +#include <sysLib.h>
        +
        +#define TTY_STRUCT int
        +
        +#define sleep(a) taskDelay((a) * sysClkRateGet())
        +
        +#include <vxWorks.h>
        +#include <sockLib.h>
        +#include <taskLib.h>
        +
        +#define getpid taskIdSelf
        +
        +/* NOTE: these are implemented by helpers in database app!
        + * if the database is not linked, we need to implement them
        + * elswhere */
        +struct hostent *gethostbyname(const char *name);
        +struct hostent *gethostbyaddr(const char *addr, int length, int type);
        +struct servent *getservbyname(const char *name, const char *proto);
        +
        +#endif
        +/* end vxworks */
        +
        +/* beos */
        +#if defined(OPENSSL_SYS_BEOS_R5)
        +#define SO_ERROR 0
        +#define NO_SYS_UN
        +#define IPPROTO_IP 0
        +#include <OS.h>
        +#endif
        +
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/e_os2.h b/vendor/openssl/openssl/e_os2.h
        new file mode 100644
        index 000000000..d22c0368f
        --- /dev/null
        +++ b/vendor/openssl/openssl/e_os2.h
        @@ -0,0 +1,315 @@
        +/* e_os2.h */
        +/* ====================================================================
        + * 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 <openssl/opensslconf.h>
        +
        +#ifndef HEADER_E_OS2_H
        +#define HEADER_E_OS2_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/******************************************************************************
        + * Detect operating systems.  This probably needs completing.
        + * The result is that at least one OPENSSL_SYS_os macro should be defined.
        + * However, if none is defined, Unix is assumed.
        + **/
        +
        +#define OPENSSL_SYS_UNIX
        +
        +/* ----------------------- Macintosh, before MacOS X ----------------------- */
        +#if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_MACINTOSH_CLASSIC
        +#endif
        +
        +/* ----------------------- NetWare ----------------------------------------- */
        +#if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_NETWARE
        +#endif
        +
        +/* ---------------------- Microsoft operating systems ---------------------- */
        +
        +/* Note that MSDOS actually denotes 32-bit environments running on top of
        +   MS-DOS, such as DJGPP one. */
        +#if defined(OPENSSL_SYSNAME_MSDOS)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_MSDOS
        +#endif
        +
        +/* For 32 bit environment, there seems to be the CygWin environment and then
        +   all the others that try to do the same thing Microsoft does... */
        +#if defined(OPENSSL_SYSNAME_UWIN)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_WIN32_UWIN
        +#else
        +# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32)
        +#  undef OPENSSL_SYS_UNIX
        +#  define OPENSSL_SYS_WIN32_CYGWIN
        +# else
        +#  if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
        +#   undef OPENSSL_SYS_UNIX
        +#   define OPENSSL_SYS_WIN32
        +#  endif
        +#  if defined(OPENSSL_SYSNAME_WINNT)
        +#   undef OPENSSL_SYS_UNIX
        +#   define OPENSSL_SYS_WINNT
        +#  endif
        +#  if defined(OPENSSL_SYSNAME_WINCE)
        +#   undef OPENSSL_SYS_UNIX
        +#   define OPENSSL_SYS_WINCE
        +#  endif
        +# endif
        +#endif
        +
        +/* Anything that tries to look like Microsoft is "Windows" */
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_WINDOWS
        +# ifndef OPENSSL_SYS_MSDOS
        +#  define OPENSSL_SYS_MSDOS
        +# endif
        +#endif
        +
        +/* DLL settings.  This part is a bit tough, because it's up to the application
        +   implementor how he or she will link the application, so it requires some
        +   macro to be used. */
        +#ifdef OPENSSL_SYS_WINDOWS
        +# ifndef OPENSSL_OPT_WINDLL
        +#  if defined(_WINDLL) /* This is used when building OpenSSL to indicate that
        +                          DLL linkage should be used */
        +#   define OPENSSL_OPT_WINDLL
        +#  endif
        +# endif
        +#endif
        +
        +/* -------------------------------- OpenVMS -------------------------------- */
        +#if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_VMS
        +# if defined(__DECC)
        +#  define OPENSSL_SYS_VMS_DECC
        +# elif defined(__DECCXX)
        +#  define OPENSSL_SYS_VMS_DECC
        +#  define OPENSSL_SYS_VMS_DECCXX
        +# else
        +#  define OPENSSL_SYS_VMS_NODECC
        +# endif
        +#endif
        +
        +/* --------------------------------- OS/2 ---------------------------------- */
        +#if defined(__EMX__) || defined(__OS2__)
        +# undef OPENSSL_SYS_UNIX
        +# define OPENSSL_SYS_OS2
        +#endif
        +
        +/* --------------------------------- Unix ---------------------------------- */
        +#ifdef OPENSSL_SYS_UNIX
        +# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
        +#  define OPENSSL_SYS_LINUX
        +# endif
        +# ifdef OPENSSL_SYSNAME_MPE
        +#  define OPENSSL_SYS_MPE
        +# endif
        +# ifdef OPENSSL_SYSNAME_SNI
        +#  define OPENSSL_SYS_SNI
        +# endif
        +# ifdef OPENSSL_SYSNAME_ULTRASPARC
        +#  define OPENSSL_SYS_ULTRASPARC
        +# endif
        +# ifdef OPENSSL_SYSNAME_NEWS4
        +#  define OPENSSL_SYS_NEWS4
        +# endif
        +# ifdef OPENSSL_SYSNAME_MACOSX
        +#  define OPENSSL_SYS_MACOSX
        +# endif
        +# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
        +#  define OPENSSL_SYS_MACOSX_RHAPSODY
        +#  define OPENSSL_SYS_MACOSX
        +# endif
        +# ifdef OPENSSL_SYSNAME_SUNOS
        +#  define OPENSSL_SYS_SUNOS
        +#endif
        +# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
        +#  define OPENSSL_SYS_CRAY
        +# endif
        +# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
        +#  define OPENSSL_SYS_AIX
        +# endif
        +#endif
        +
        +/* --------------------------------- VOS ----------------------------------- */
        +#if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
        +# define OPENSSL_SYS_VOS
        +#ifdef __HPPA__
        +# define OPENSSL_SYS_VOS_HPPA
        +#endif
        +#ifdef __IA32__
        +# define OPENSSL_SYS_VOS_IA32
        +#endif
        +#endif
        +
        +/* ------------------------------- VxWorks --------------------------------- */
        +#ifdef OPENSSL_SYSNAME_VXWORKS
        +# define OPENSSL_SYS_VXWORKS
        +#endif
        +
        +/* --------------------------------- BeOS ---------------------------------- */
        +#if defined(__BEOS__)
        +# define OPENSSL_SYS_BEOS
        +# include <sys/socket.h>
        +# if defined(BONE_VERSION)
        +#  define OPENSSL_SYS_BEOS_BONE
        +# else
        +#  define OPENSSL_SYS_BEOS_R5
        +# endif
        +#endif
        +
        +/**
        + * That's it for OS-specific stuff
        + *****************************************************************************/
        +
        +
        +/* Specials for I/O an exit */
        +#ifdef OPENSSL_SYS_MSDOS
        +# define OPENSSL_UNISTD_IO <io.h>
        +# define OPENSSL_DECLARE_EXIT extern void exit(int);
        +#else
        +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD
        +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */
        +#endif
        +
        +/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
        +   certain global symbols that, with some compilers under VMS, have to be
        +   defined and declared explicitely with globaldef and globalref.
        +   Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
        +   DLL exports and imports for compilers under Win32.  These are a little
        +   more complicated to use.  Basically, for any library that exports some
        +   global variables, the following code must be present in the header file
        +   that declares them, before OPENSSL_EXTERN is used:
        +
        +   #ifdef SOME_BUILD_FLAG_MACRO
        +   # undef OPENSSL_EXTERN
        +   # define OPENSSL_EXTERN OPENSSL_EXPORT
        +   #endif
        +
        +   The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
        +   have some generally sensible values, and for OPENSSL_EXTERN to have the
        +   value OPENSSL_IMPORT.
        +*/
        +
        +#if defined(OPENSSL_SYS_VMS_NODECC)
        +# define OPENSSL_EXPORT globalref
        +# define OPENSSL_IMPORT globalref
        +# define OPENSSL_GLOBAL globaldef
        +#elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
        +# define OPENSSL_EXPORT extern __declspec(dllexport)
        +# define OPENSSL_IMPORT extern __declspec(dllimport)
        +# define OPENSSL_GLOBAL
        +#else
        +# define OPENSSL_EXPORT extern
        +# define OPENSSL_IMPORT extern
        +# define OPENSSL_GLOBAL
        +#endif
        +#define OPENSSL_EXTERN OPENSSL_IMPORT
        +
        +/* Macros to allow global variables to be reached through function calls when
        +   required (if a shared library version requires it, for example.
        +   The way it's done allows definitions like this:
        +
        +	// in foobar.c
        +	OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
        +	// in foobar.h
        +	OPENSSL_DECLARE_GLOBAL(int,foobar);
        +	#define foobar OPENSSL_GLOBAL_REF(foobar)
        +*/
        +#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
        +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)			\
        +	type *_shadow_##name(void)					\
        +	{ static type _hide_##name=value; return &_hide_##name; }
        +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
        +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
        +#else
        +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
        +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
        +# define OPENSSL_GLOBAL_REF(name) _shadow_##name
        +#endif
        +
        +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE)
        +#  define ossl_ssize_t long
        +#endif
        +
        +#ifdef OPENSSL_SYS_MSDOS
        +#  define ossl_ssize_t long
        +#endif
        +
        +#if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
        +#  define ssize_t int
        +#endif
        +
        +#if defined(__ultrix) && !defined(ssize_t)
        +#  define ossl_ssize_t int 
        +#endif
        +
        +#ifndef ossl_ssize_t
        +#  define ossl_ssize_t ssize_t
        +#endif
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/Makefile b/vendor/openssl/openssl/engines/Makefile
        new file mode 100644
        index 000000000..2fa953440
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/Makefile
        @@ -0,0 +1,335 @@
        +#
        +# OpenSSL/engines/Makefile
        +#
        +
        +DIR=	engines
        +TOP=	..
        +CC=	cc
        +INCLUDES= -I../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +ENGDIRS= ccgost
        +
        +RECURSIVE_MAKE=	[ -z "$(ENGDIRS)" ] || for i in $(ENGDIRS) ; do \
        +		    (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
        +		    $(MAKE) -e TOP=../.. DIR=$$i $$target ) || exit 1; \
        +		done;
        +
        +PEX_LIBS=
        +EX_LIBS=
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile engines.com install.com engine_vector.mar
        +TEST=
        +APPS=
        +
        +LIB=$(TOP)/libcrypto.a
        +LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi
        +
        +LIBSRC=	e_4758cca.c \
        +	e_aep.c \
        +	e_atalla.c \
        +	e_cswift.c \
        +	e_gmp.c \
        +	e_chil.c \
        +	e_nuron.c \
        +	e_sureware.c \
        +	e_ubsec.c \
        +	e_padlock.c \
        +	e_capi.c
        +LIBOBJ= e_4758cca.o \
        +	e_aep.o \
        +	e_atalla.o \
        +	e_cswift.o \
        +	e_gmp.o \
        +	e_chil.o \
        +	e_nuron.o \
        +	e_sureware.o \
        +	e_ubsec.o \
        +	e_padlock.o \
        +	e_capi.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= 
        +HEADER=	e_4758cca_err.c e_4758cca_err.h \
        +	e_aep_err.c e_aep_err.h \
        +	e_atalla_err.c e_atalla_err.h \
        +	e_cswift_err.c e_cswift_err.h \
        +	e_gmp_err.c e_gmp_err.h \
        +	e_chil_err.c e_chil_err.h \
        +	e_nuron_err.c e_nuron_err.h \
        +	e_sureware_err.c e_sureware_err.h \
        +	e_ubsec_err.c e_ubsec_err.h \
        +	e_capi_err.c e_capi_err.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ..; $(MAKE) DIRS=$(DIR) all)
        +
        +all:	lib subdirs
        +
        +lib:	$(LIBOBJ)
        +	@if [ -n "$(SHARED_LIBS)" ]; then \
        +		set -e; \
        +		for l in $(LIBNAMES); do \
        +			$(MAKE) -f ../Makefile.shared -e \
        +				LIBNAME=$$l LIBEXTRAS=e_$$l.o \
        +				LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
        +				link_o.$(SHLIB_TARGET); \
        +		done; \
        +	else \
        +		$(AR) $(LIB) $(LIBOBJ); \
        +		$(RANLIB) $(LIB) || echo Never mind.; \
        +	fi; \
        +	touch lib
        +
        +subdirs:
        +	echo $(EDIRS)
        +	@target=all; $(RECURSIVE_MAKE)
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +	@target=files; $(RECURSIVE_MAKE)
        +
        +links:
        +	@target=links; $(RECURSIVE_MAKE)
        +
        +# XXXXX This currently only works on systems that use .so as suffix
        +# for shared libraries as well as for Cygwin which uses the
        +# dlfcn_name_converter and therefore stores the engines with .so suffix, too.
        +# XXXXX This was extended to HP-UX dl targets, which use .sl suffix.
        +# XXXXX This was extended to mingw targets, which use eay32.dll suffix without lib as prefix.
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@if [ -n "$(SHARED_LIBS)" ]; then \
        +		set -e; \
        +		$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines; \
        +		for l in $(LIBNAMES); do \
        +			( echo installing $$l; \
        +			  pfx=lib; \
        +			  if [ "$(PLATFORM)" != "Cygwin" ]; then \
        +				case "$(CFLAGS)" in \
        +				*DSO_BEOS*)	sfx=".so";;	\
        +				*DSO_DLFCN*)	sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;;	\
        +				*DSO_DL*)	sfx=".sl";;	\
        +				*DSO_WIN32*)	sfx="eay32.dll"; pfx=;;	\
        +				*)		sfx=".bad";;	\
        +				esac; \
        +				cp $$pfx$$l$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \
        +			  else \
        +				sfx=".so"; \
        +				cp cyg$$l.dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \
        +			  fi; \
        +			  chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \
        +			  mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx ); \
        +		done; \
        +	fi
        +	@target=install; $(RECURSIVE_MAKE)
        +
        +tags:
        +	ctags $(SRC)
        +
        +errors:
        +	set -e; for l in $(LIBNAMES); do \
        +		$(PERL) ../util/mkerr.pl -conf e_$$l.ec \
        +			-nostatic -staticloader -write e_$$l.c; \
        +	done
        +	(cd ccgost; $(MAKE) PERL=$(PERL) errors)
        +
        +tests:
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +	@target=lint; $(RECURSIVE_MAKE)
        +
        +depend:
        +	@if [ -z "$(THIS)" ]; then \
        +	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
        +	fi
        +	@[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
        +	@[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +	@target=dclean; $(RECURSIVE_MAKE)
        +
        +clean:
        +	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +	@target=clean; $(RECURSIVE_MAKE)
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +e_4758cca.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_4758cca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_4758cca.o: ../include/openssl/crypto.h ../include/openssl/dso.h
        +e_4758cca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_4758cca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_4758cca.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_4758cca.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_4758cca.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_4758cca.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_4758cca.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_4758cca.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +e_4758cca.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +e_4758cca.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +e_4758cca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +e_4758cca.o: e_4758cca.c e_4758cca_err.c e_4758cca_err.h
        +e_4758cca.o: vendor_defns/hw_4758_cca.h
        +e_aep.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_aep.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_aep.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_aep.o: ../include/openssl/dsa.h ../include/openssl/dso.h
        +e_aep.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_aep.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_aep.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_aep.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_aep.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_aep.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_aep.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_aep.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +e_aep.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_aep.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +e_aep.o: ../include/openssl/x509_vfy.h e_aep.c e_aep_err.c e_aep_err.h
        +e_aep.o: vendor_defns/aep.h
        +e_atalla.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_atalla.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_atalla.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_atalla.o: ../include/openssl/dsa.h ../include/openssl/dso.h
        +e_atalla.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_atalla.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_atalla.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_atalla.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_atalla.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_atalla.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_atalla.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_atalla.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +e_atalla.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_atalla.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +e_atalla.o: ../include/openssl/x509_vfy.h e_atalla.c e_atalla_err.c
        +e_atalla.o: e_atalla_err.h vendor_defns/atalla.h
        +e_capi.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_capi.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_capi.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +e_capi.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +e_capi.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +e_capi.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_capi.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_capi.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_capi.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_capi.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +e_capi.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +e_capi.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_capi.c
        +e_chil.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_chil.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_chil.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_chil.o: ../include/openssl/dso.h ../include/openssl/e_os2.h
        +e_chil.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +e_chil.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +e_chil.o: ../include/openssl/err.h ../include/openssl/evp.h
        +e_chil.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +e_chil.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +e_chil.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +e_chil.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +e_chil.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +e_chil.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +e_chil.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_chil.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
        +e_chil.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_chil.c
        +e_chil.o: e_chil_err.c e_chil_err.h vendor_defns/hwcryptohook.h
        +e_cswift.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_cswift.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_cswift.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_cswift.o: ../include/openssl/dsa.h ../include/openssl/dso.h
        +e_cswift.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_cswift.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_cswift.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_cswift.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_cswift.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_cswift.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_cswift.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_cswift.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +e_cswift.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +e_cswift.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +e_cswift.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_cswift.c
        +e_cswift.o: e_cswift_err.c e_cswift_err.h vendor_defns/cswift.h
        +e_gmp.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_gmp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_gmp.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +e_gmp.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +e_gmp.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +e_gmp.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_gmp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_gmp.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_gmp.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_gmp.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +e_gmp.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_gmp.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +e_gmp.o: ../include/openssl/x509_vfy.h e_gmp.c
        +e_nuron.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_nuron.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_nuron.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_nuron.o: ../include/openssl/dsa.h ../include/openssl/dso.h
        +e_nuron.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_nuron.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_nuron.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_nuron.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_nuron.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_nuron.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_nuron.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_nuron.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +e_nuron.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_nuron.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +e_nuron.o: ../include/openssl/x509_vfy.h e_nuron.c e_nuron_err.c e_nuron_err.h
        +e_padlock.o: ../include/openssl/aes.h ../include/openssl/asn1.h
        +e_padlock.o: ../include/openssl/bio.h ../include/openssl/buffer.h
        +e_padlock.o: ../include/openssl/crypto.h ../include/openssl/dso.h
        +e_padlock.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_padlock.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_padlock.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_padlock.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_padlock.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_padlock.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_padlock.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_padlock.o: ../include/openssl/rand.h ../include/openssl/safestack.h
        +e_padlock.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_padlock.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +e_padlock.o: ../include/openssl/x509_vfy.h e_padlock.c
        +e_sureware.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_sureware.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_sureware.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_sureware.o: ../include/openssl/dsa.h ../include/openssl/dso.h
        +e_sureware.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_sureware.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_sureware.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_sureware.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_sureware.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_sureware.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_sureware.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +e_sureware.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +e_sureware.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +e_sureware.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +e_sureware.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +e_sureware.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +e_sureware.o: e_sureware.c e_sureware_err.c e_sureware_err.h
        +e_sureware.o: vendor_defns/sureware.h
        +e_ubsec.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +e_ubsec.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +e_ubsec.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +e_ubsec.o: ../include/openssl/dsa.h ../include/openssl/dso.h
        +e_ubsec.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +e_ubsec.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +e_ubsec.o: ../include/openssl/engine.h ../include/openssl/err.h
        +e_ubsec.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +e_ubsec.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +e_ubsec.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +e_ubsec.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +e_ubsec.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +e_ubsec.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +e_ubsec.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +e_ubsec.o: ../include/openssl/x509_vfy.h e_ubsec.c e_ubsec_err.c e_ubsec_err.h
        +e_ubsec.o: vendor_defns/hw_ubsec.h
        diff --git a/vendor/openssl/openssl/engines/alpha.opt b/vendor/openssl/openssl/engines/alpha.opt
        new file mode 100644
        index 000000000..1dc71bf4b
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/alpha.opt
        @@ -0,0 +1 @@
        +SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
        diff --git a/vendor/openssl/openssl/engines/axp.opt b/vendor/openssl/openssl/engines/axp.opt
        new file mode 100644
        index 000000000..1dc71bf4b
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/axp.opt
        @@ -0,0 +1 @@
        +SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
        diff --git a/vendor/openssl/openssl/engines/capierr.bat b/vendor/openssl/openssl/engines/capierr.bat
        new file mode 100644
        index 000000000..274ffac2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/capierr.bat
        @@ -0,0 +1 @@
        +perl ../util/mkerr.pl -conf e_capi.ec -nostatic -staticloader -write e_capi.c
        diff --git a/vendor/openssl/openssl/engines/ccgost/Makefile b/vendor/openssl/openssl/engines/ccgost/Makefile
        new file mode 100644
        index 000000000..d661c1082
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/Makefile
        @@ -0,0 +1,275 @@
        +DIR=ccgost
        +TOP=../..
        +CC=cc
        +INCLUDES= -I../../include
        +CFLAG=-g
        +MAKEFILE= Makefile
        +AR= ar r
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +LIB=$(TOP)/libcrypto.a
        +
        +LIBSRC= gost2001.c gost2001_keyx.c gost89.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_params.c gost_pmeth.c gost_sign.c
        +
        +LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.o gost89.o gost94_keyx.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_params.o gost_pmeth.o gost_sign.o
        +
        +SRC=$(LIBSRC)
        +
        +LIBNAME=gost
        +
        +top: 
        +	(cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all)
        +
        +all: lib
        +
        +tags:
        +	ctags $(SRC)
        +
        +errors:
        +	$(PERL) ../../util/mkerr.pl -conf gost.ec -nostatic -write $(SRC)
        +
        +lib: $(LIBOBJ)
        +	if [ -n "$(SHARED_LIBS)" ]; then \
        +		$(MAKE) -f $(TOP)/Makefile.shared -e \
        +			LIBNAME=$(LIBNAME) \
        +			LIBEXTRAS='$(LIBOBJ)' \
        +			LIBDEPS='-L$(TOP) -lcrypto' \
        +			link_o.$(SHLIB_TARGET); \
        +	else \
        +		$(AR) $(LIB) $(LIBOBJ); \
        +	fi
        +	@touch lib
        +
        +install:
        +	[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	if [ -n "$(SHARED_LIBS)" ]; then \
        +		set -e; \
        +		echo installing $(LIBNAME); \
        +		pfx=lib; \
        +		if [ "$(PLATFORM)" != "Cygwin" ]; then \
        +			case "$(CFLAGS)" in \
        +			*DSO_BEOS*) sfx=".so";; \
        +			*DSO_DLFCN*) sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;; \
        +			*DSO_DL*) sfx=".sl";; \
        +			*DSO_WIN32*) sfx="eay32.dll"; pfx=;; \
        +			*) sfx=".bad";; \
        +			esac; \
        +			cp $${pfx}$(LIBNAME)$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
        +		else \
        +			sfx=".so"; \
        +			cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
        +		fi; \
        +		chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
        +		mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx; \
        +	fi
        +
        +links:
        +
        +tests:
        +
        +depend:
        +	@if [ -z "$(THIS)" ]; then \
        +	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
        +	else \
        +	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
        +	fi
        +
        +files:
        +
        +
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +
        +clean:
        +	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +gost2001.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost2001.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost2001.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost2001.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost2001.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost2001.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost2001.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +gost2001.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +gost2001.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +gost2001.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost2001.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +gost2001.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +gost2001.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +gost2001.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +gost2001.o: e_gost_err.h gost2001.c gost89.h gost_lcl.h gost_params.h
        +gost2001.o: gosthash.h
        +gost2001_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost2001_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost2001_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost2001_keyx.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost2001_keyx.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost2001_keyx.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost2001_keyx.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +gost2001_keyx.o: ../../include/openssl/obj_mac.h
        +gost2001_keyx.o: ../../include/openssl/objects.h
        +gost2001_keyx.o: ../../include/openssl/opensslconf.h
        +gost2001_keyx.o: ../../include/openssl/opensslv.h
        +gost2001_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +gost2001_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +gost2001_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost2001_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost2001_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost2001_keyx.c
        +gost2001_keyx.o: gost2001_keyx.h gost89.h gost_keywrap.h gost_lcl.h gosthash.h
        +gost89.o: gost89.c gost89.h
        +gost94_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost94_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost94_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost94_keyx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
        +gost94_keyx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +gost94_keyx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +gost94_keyx.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
        +gost94_keyx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +gost94_keyx.o: ../../include/openssl/objects.h
        +gost94_keyx.o: ../../include/openssl/opensslconf.h
        +gost94_keyx.o: ../../include/openssl/opensslv.h
        +gost94_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +gost94_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
        +gost94_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost94_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost94_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
        +gost94_keyx.o: gost94_keyx.c gost_keywrap.h gost_lcl.h gosthash.h
        +gost_ameth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
        +gost_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +gost_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +gost_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +gost_ameth.o: ../../include/openssl/engine.h ../../include/openssl/err.h
        +gost_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +gost_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +gost_ameth.o: ../../include/openssl/opensslconf.h
        +gost_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +gost_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost_ameth.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
        +gost_ameth.o: gost_ameth.c gost_lcl.h gost_params.h gosthash.h
        +gost_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +gost_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +gost_asn1.o: ../../include/openssl/opensslconf.h
        +gost_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +gost_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost_asn1.o: ../../include/openssl/x509_vfy.h gost89.h gost_asn1.c gost_lcl.h
        +gost_asn1.o: gosthash.h
        +gost_crypt.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_crypt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_crypt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost_crypt.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost_crypt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost_crypt.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost_crypt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +gost_crypt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +gost_crypt.o: ../../include/openssl/opensslconf.h
        +gost_crypt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_crypt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +gost_crypt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +gost_crypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +gost_crypt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +gost_crypt.o: e_gost_err.h gost89.h gost_crypt.c gost_lcl.h gosthash.h
        +gost_ctl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_ctl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_ctl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost_ctl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost_ctl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost_ctl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost_ctl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +gost_ctl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +gost_ctl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +gost_ctl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_ctl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +gost_ctl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost_ctl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost_ctl.o: ../../include/openssl/x509_vfy.h gost89.h gost_ctl.c gost_lcl.h
        +gost_ctl.o: gosthash.h
        +gost_eng.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_eng.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_eng.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost_eng.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
        +gost_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +gost_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
        +gost_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +gost_eng.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost_eng.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost_eng.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h gost_eng.c
        +gost_eng.o: gost_lcl.h gosthash.h
        +gost_keywrap.o: gost89.h gost_keywrap.c gost_keywrap.h
        +gost_md.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_md.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost_md.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost_md.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost_md.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +gost_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +gost_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
        +gost_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
        +gost_md.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +gost_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +gost_md.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +gost_md.o: e_gost_err.h gost89.h gost_lcl.h gost_md.c gosthash.h
        +gost_params.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
        +gost_params.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
        +gost_params.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +gost_params.o: ../../include/openssl/opensslconf.h
        +gost_params.o: ../../include/openssl/opensslv.h
        +gost_params.o: ../../include/openssl/ossl_typ.h
        +gost_params.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
        +gost_params.o: ../../include/openssl/symhacks.h gost_params.c gost_params.h
        +gost_pmeth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
        +gost_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
        +gost_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
        +gost_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
        +gost_pmeth.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
        +gost_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
        +gost_pmeth.o: ../../include/openssl/objects.h
        +gost_pmeth.o: ../../include/openssl/opensslconf.h
        +gost_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
        +gost_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
        +gost_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
        +gost_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
        +gost_pmeth.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_pmeth.c
        +gost_pmeth.o: gosthash.h
        +gost_sign.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
        +gost_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
        +gost_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
        +gost_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
        +gost_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
        +gost_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
        +gost_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
        +gost_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
        +gost_sign.o: ../../include/openssl/opensslconf.h
        +gost_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
        +gost_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
        +gost_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
        +gost_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
        +gost_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
        +gost_sign.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_sign.c
        +gost_sign.o: gosthash.h
        +gosthash.o: gost89.h gosthash.c gosthash.h
        diff --git a/vendor/openssl/openssl/engines/ccgost/README.gost b/vendor/openssl/openssl/engines/ccgost/README.gost
        new file mode 100644
        index 000000000..c96cccc7b
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/README.gost
        @@ -0,0 +1,300 @@
        +GOST ENGINE
        +
        +This engine provides implementation of Russian cryptography standard.
        +This is also an example of adding new cryptoalgorithms into OpenSSL
        +without changing its core. If OpenSSL is compiled with dynamic engine
        +support, new algorithms can be added even without recompilation of
        +OpenSSL and applications which use it.
        +
        +ALGORITHMS SUPPORTED
        +
        +GOST R 34.10-94 and GOST R 34.10-2001 - digital signature algorithms.
        +   Also support key exchange based on public keys. See RFC 4357 for
        +   details of VKO key exchange algorithm. These algorithms use
        +   256 bit private keys. Public keys are 1024 bit for 94 and 512 bit for
        +   2001 (which is elliptic-curve based). Key exchange algorithms
        +   (VKO R 34.10) are supported on these keys too.
        +   
        +GOST R 34.11-94  Message digest algorithm. 256-bit hash value
        +
        +GOST 28147-89 - Symmetric cipher  with 256-bit key. Various modes are
        +   defined in the standard, but only CFB and CNT modes are implemented
        +   in the engine. To make statistical analysis more difficult, key
        +   meshing is supported (see RFC 4357).
        +
        +GOST 28147-89 MAC mode. Message authentication code. While most MAC
        +    algorithms  out there are based on hash functions using HMAC
        +	algorithm, this algoritm is based on symmetric cipher. 
        +	It has 256-bit symmetric key and only 32 bits of MAC value
        +	(while HMAC has same key size and value size). 
        +
        +	It is implemented as combination of EVP_PKEY type and EVP_MD type.
        +
        +USAGE OF THESE ALGORITHMS
        +
        +This engine is designed to allow usage of this algorithms in the
        +high-level openssl functions, such as PKI, S/MIME and TLS.
        +
        +See RFC 4490 for S/MIME with GOST algorithms and RFC 4491 for PKI.
        +TLS support is implemented according IETF
        +draft-chudov-cryptopro-cptls-03.txt and is compatible with
        +CryptoPro CSP 3.0 and 3.6 as well as with MagPro CSP. 
        +GOST ciphersuites implemented in CryptoPro CSP 2.0 are not supported
        +because they use ciphersuite numbers used now by AES ciphersuites.
        +
        +To use the engine you have to load it via openssl configuration
        +file. Applications should read openssl configuration file or provide
        +their own means to load engines. Also, applications which operate with
        +private keys, should use generic EVP_PKEY API instead of using RSA or
        +other algorithm-specific API.
        +
        +CONFIGURATION FILE
        +
        +Configuration file should include following statement in the global
        +section, i.e. before first bracketed section header (see config(5) for details)
        +
        +   openssl_conf = openssl_def
        +
        +where openssl_def is name of the section in configuration file which
        +describes global defaults.
        +
        +This section should contain following statement:
        +
        +   [openssl_def]
        +   engines = engine_section
        +
        +which points to the section which describes list of the engines to be
        +loaded. This section should contain:
        +
        +	[engine_section]
        +	gost = gost_section
        +
        +And section which describes configuration of the engine should contain
        +
        +	[gost_section]
        +	engine_id = gost
        +	dynamic_path = /usr/lib/ssl/engines/libgost.so
        +	default_algorithms = ALL
        +	CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
        +
        +Where engine_id parameter specifies name of engine (should be "gost").
        +dynamic_path is a location of the loadable shared library implementing the
        +engine. If the engine is compiled statically or is located in the OpenSSL
        +engines directory, this line can be omitted. 
        +default_algorithms parameter specifies that all algorithms, provided by
        +engine, should be used.
        +
        +The CRYPT_PARAMS parameter is engine-specific. It allows the user to choose
        +between different parameter sets of symmetric cipher algorithm. RFC 4357
        +specifies several parameters for the GOST 28147-89 algorithm, but OpenSSL
        +doesn't provide user interface to choose one when encrypting. So use engine
        +configuration parameter instead.
        +
        +Value of this parameter can be either short name, defined in OpenSSL
        +obj_dat.h header file or numeric representation of OID, defined in RFC
        +4357. 
        +
        +USAGE WITH COMMAND LINE openssl UTILITY
        +
        +1. Generation of private key
        +
        +	openssl genpkey -algorithm gost2001 -pkeyopt paramset:A -out seckey.pem
        +
        +  Use -algorithm option to specify algorithm.
        +  Use -pkeyopt option to pass paramset to algorithm. The following paramsets
        +  are supported by 
        +  	gost94: 0,A,B,C,D,XA,XB,XC
        +	gost2001: 0,A,B,C,XA,XB
        +  You can also use numeric representation of OID as to destinate
        +  paramset.
        +
        +  Paramsets starting with X are intended to use for key exchange keys.
        +  Paramsets without X are for digital signature keys.
        +
        +  Paramset for both algorithms 0 is the test paramset which should be used
        +  only for test purposes.
        +
        +There are no algorithm-specific things with generation of certificate
        +request once you have a private key.
        +
        +2. Generation of certificate request along with private/public keypar
        +
        +   openssl req -newkey gost2001 -pkeyopt paramset:A
        +
        +   Syntax of -pkeyopt parameter is identical with genpkey command.
        +
        +   You can also use oldstyle syntax -newkey gost2001:paramfile, but in
        +   this case you should create parameter file first. 
        +
        +   It can be created with
        +
        +   openssl genpkey -genparam -algorithm gost2001 -pkeyopt paramset:A\
        +      -out paramfile.
        +
        +3. S/MIME operations
        +
        +If you want to send encrypted mail using GOST algorithms, don't forget
        +to specify -gost89 as encryption algorithm for OpenSSL smime command.
        +While OpenSSL is clever enough to find out that GOST R 34.11-94 digest
        +must be used for digital signing with GOST private key, it have no way
        +to derive symmetric encryption algorithm from key exchange keys.
        +
        +4. TLS operations
        +
        +OpenSSL supports all four ciphersuites defined in the IETF draft.
        +Once you've loaded GOST key and certificate into your TLS server,
        +ciphersuites which use GOST 28147-89 encryption are enabled.
        +
        +Ciphersuites with NULL encryption should be enabled explicitely if
        +needed.
        +
        +GOST2001-GOST89-GOST89 Uses GOST R 34.10-2001 for auth and key exchange
        +		GOST 28147-89 for encryption and GOST 28147-89 MAC
        +GOST94-GOST89-GOST89 Uses GOST R 34.10-94 for auth and key exchange
        +		GOST 28147-89 for encryption and GOST 28147-89 MAC
        +GOST2001-NULL-GOST94 Uses GOST R 34.10-2001 for auth and key exchange,
        +        no encryption and HMAC, based on GOST R 34.11-94
        +GOST94-NULL-GOST94 Uses GOST R 34.10-94 for auth and key exchange,
        +        no encryption and HMAC, based on GOST R 34.11-94
        +
        +Gost 94 and gost 2001 keys can be used simultaneously in the TLS server.
        +RSA, DSA and EC keys can be used simultaneously with GOST keys, if
        +server implementation supports loading more than two private
        +key/certificate pairs. In this case ciphersuites which use any of loaded
        +keys would be supported and clients can negotiate ones they wish.
        +
        +This allows creation of TLS servers which use GOST ciphersuites for
        +Russian clients and RSA/DSA ciphersuites for foreign clients.
        +
        +5. Calculation of digests and symmetric encryption
        + OpenSSL provides specific commands (like sha1, aes etc) for calculation
        + of digests and symmetric encryption. Since such commands cannot be
        + added dynamically, no such commands are provided for GOST algorithms.
        + Use generic commands 'dgst' and 'enc'.
        +
        + Calculation of GOST R 34.11-94 message digest
        +
        + openssl dgst -md_gost94 datafile
        +
        + Note that GOST R 34.11-94 specifies that digest value should be
        + interpreted as little-endian number, but OpenSSL outputs just hex dump
        + of digest value.
        +
        + So, to obtain correct digest value, such as produced by gostsum utility
        + included in the engine distribution, bytes of output should be
        + reversed.
        + 
        + Calculation of HMAC based on GOST R 34.11-94
        +
        + openssl dgst -md_gost94 -mac hmac -macopt key:<32 bytes of key> datafile
        +  
        +  (or use hexkey if key contain NUL bytes)
        + Calculation of GOST 28147 MAC
        +
        + openssl dgst -mac gost-mac -macopt key:<32 bytes of key> datafile
        +
        + Note absense of an option that specifies digest algorithm. gost-mac
        + algorithm supports only one digest (which is actually part of
        + implementation of this mac) and OpenSSL is clever enough to find out
        + this.
        +
        + Encryption with GOST 28147 CFB mode
        + openssl enc -gost89 -out encrypted-file -in plain-text-file -k <passphrase>  
        + Encryption with GOST 28147 CNT mode
        + openssl enc -gost89-cnt -out encrypted-file -in plain-text-file -k <passphrase>
        +
        +
        +6. Encrypting private keys and PKCS12
        +
        +To produce PKCS12 files compatible with MagPro CSP, you need to use
        +GOST algorithm for encryption of PKCS12 file and also GOST R 34.11-94
        +hash to derive key from password.
        +
        +openssl pksc12 -export -inkey gost.pem -in gost_cert.pem -keypbe gost89\
        +   -certpbe gost89 -macalg md_gost94
        + 
        +7. Testing speed of symmetric ciphers.
        +   
        +To test performance of GOST symmetric ciphers you should use -evp switch
        +of the openssl speed command. Engine-provided ciphers couldn't be
        +accessed by cipher-specific functions, only via generic evp interface
        +
        + openssl speed -evp gost89
        + openssl speed -evp gost89-cnt
        +
        +
        +PROGRAMMING INTERFACES DETAILS
        +
        +Applications never should access engine directly. They only use provided
        +EVP_PKEY API. But there are some details, which should be taken into
        +account.
        +
        +EVP provides two kinds of API for key exchange:
        +
        +1. EVP_PKEY_encrypt/EVP_PKEY_decrypt functions, intended to use with
        +	RSA-like public key encryption algorithms
        +
        +2. EVP_PKEY_derive, intended to use with Diffie-Hellman-like shared key
        +computing algorithms.
        +
        +Although VKO R 34.10 algorithms, described in the RFC 4357 are
        +definitely second case, engine provides BOTH API for GOST R 34.10 keys.
        +
        +EVP_PKEY_derive just invokes appropriate VKO algorithm and computes
        +256 bit shared key. VKO R 34.10-2001 requires 64 bits of random user key
        +material (UKM). This UKM should be transmitted to other party, so it is
        +not generated inside derive function.
        +
        +It should be set by EVP_PKEY_CTX_ctrl function using
        +EVP_PKEY_CTRL_SET_IV command after call of EVP_PKEY_derive_init, but
        +before EVP_PKEY_derive.
        +	unsigned char ukm[8];
        +	RAND_bytes(ukm,8);
        +   EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, 8, ukm)
        +
        +EVP_PKEY_encrypt encrypts provided session key with VKO shared key and
        +packs it into GOST key transport structure, described in the RFC 4490.
        +
        +It typically uses ephemeral key pair to compute shared key and packs its
        +public part along with encrypted key. So, for most cases use of 
        +EVP_PKEY_encrypt/EVP_PKEY_decrypt with GOST keys is almost same as with
        +RSA.
        +
        +However, if peerkey field in the EVP_PKEY_CTX structure is set (using
        +EVP_PKEY_derive_set_peerkey function) to EVP_PKEY structure which has private
        +key and uses same parameters as the public key from which this EVP_PKEY_CTX is
        +created, EVP_PKEY_encrypt will use this private key to compute shared key and
        +set ephemeral key in the GOST_key_transport structure to NULL. In this case
        +pkey and peerkey fields in the EVP_PKEY_CTX are used upside-down.
        +
        +If EVP_PKEY_decrypt encounters GOST_key_transport structure with NULL
        +public key field, it tries to use peerkey field from the context to
        +compute shared key. In this case peerkey field should really contain
        +peer public key.
        +
        +Encrypt operation supports EVP_PKEY_CTRL_SET_IV operation as well.
        +It can be used when some specific restriction on UKM are imposed by
        +higher level protocol. For instance, description of GOST ciphersuites
        +requires UKM to be derived from shared secret. 
        +
        +If UKM is not set by this control command, encrypt operation would
        +generate random UKM.
        +
        +
        +This sources include implementation of GOST 28147-89 and GOST R 34.11-94
        +which are completely indepentent from OpenSSL and can be used separately
        +(files gost89.c, gost89.h, gosthash.c, gosthash.h) Utility gostsum (file
        +gostsum.c) is provided as example of such separate usage. This is
        +program, simular to md5sum and sha1sum utilities, but calculates GOST R
        +34.11-94 hash.
        +
        +Makefile doesn't include rule for compiling gostsum.
        +Use command
        +
        +$(CC) -o gostsum gostsum.c gost89.c gosthash.c
        +where $(CC) is name of your C compiler.
        +
        +Implementations of GOST R 34.10-xx, including VKO algorithms heavily
        +depends on OpenSSL BIGNUM and Elliptic Curve libraries.
        +
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/e_gost_err.c b/vendor/openssl/openssl/engines/ccgost/e_gost_err.c
        new file mode 100644
        index 000000000..9a79a374e
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/e_gost_err.c
        @@ -0,0 +1,212 @@
        +/* e_gost_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2009 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_gost_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA GOST_str_functs[]=
        +	{
        +{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS),	"DECODE_GOST_ALGOR_PARAMS"},
        +{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS),	"ENCODE_GOST_ALGOR_PARAMS"},
        +{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS),	"FILL_GOST2001_PARAMS"},
        +{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS),	"FILL_GOST94_PARAMS"},
        +{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS),	"GET_ENCRYPTION_PARAMS"},
        +{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC),	"GOST2001_COMPUTE_PUBLIC"},
        +{ERR_FUNC(GOST_F_GOST2001_DO_SIGN),	"GOST2001_DO_SIGN"},
        +{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY),	"GOST2001_DO_VERIFY"},
        +{ERR_FUNC(GOST_F_GOST2001_KEYGEN),	"GOST2001_KEYGEN"},
        +{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS),	"GOST89_GET_ASN1_PARAMETERS"},
        +{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS),	"GOST89_SET_ASN1_PARAMETERS"},
        +{ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC),	"GOST94_COMPUTE_PUBLIC"},
        +{ERR_FUNC(GOST_F_GOST_CIPHER_CTL),	"GOST_CIPHER_CTL"},
        +{ERR_FUNC(GOST_F_GOST_DO_SIGN),	"GOST_DO_SIGN"},
        +{ERR_FUNC(GOST_F_GOST_DO_VERIFY),	"GOST_DO_VERIFY"},
        +{ERR_FUNC(GOST_F_GOST_IMIT_CTRL),	"GOST_IMIT_CTRL"},
        +{ERR_FUNC(GOST_F_GOST_IMIT_FINAL),	"GOST_IMIT_FINAL"},
        +{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE),	"GOST_IMIT_UPDATE"},
        +{ERR_FUNC(GOST_F_PARAM_COPY_GOST01),	"PARAM_COPY_GOST01"},
        +{ERR_FUNC(GOST_F_PARAM_COPY_GOST94),	"PARAM_COPY_GOST94"},
        +{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT),	"PKEY_GOST01CP_DECRYPT"},
        +{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT),	"PKEY_GOST01CP_ENCRYPT"},
        +{ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN),	"PKEY_GOST01CP_KEYGEN"},
        +{ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN),	"PKEY_GOST01_PARAMGEN"},
        +{ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE),	"PKEY_GOST2001_DERIVE"},
        +{ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT),	"PKEY_GOST94CP_DECRYPT"},
        +{ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT),	"PKEY_GOST94CP_ENCRYPT"},
        +{ERR_FUNC(GOST_F_PKEY_GOST94CP_KEYGEN),	"PKEY_GOST94CP_KEYGEN"},
        +{ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN),	"PKEY_GOST94_PARAMGEN"},
        +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL),	"PKEY_GOST_CTRL"},
        +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR),	"PKEY_GOST_CTRL01_STR"},
        +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR),	"PKEY_GOST_CTRL94_STR"},
        +{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL),	"PKEY_GOST_MAC_CTRL"},
        +{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR),	"PKEY_GOST_MAC_CTRL_STR"},
        +{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN),	"PKEY_GOST_MAC_KEYGEN"},
        +{ERR_FUNC(GOST_F_PRINT_GOST_01),	"PRINT_GOST_01"},
        +{ERR_FUNC(GOST_F_PRIV_DECODE_GOST),	"PRIV_DECODE_GOST"},
        +{ERR_FUNC(GOST_F_PUB_DECODE_GOST01),	"PUB_DECODE_GOST01"},
        +{ERR_FUNC(GOST_F_PUB_DECODE_GOST94),	"PUB_DECODE_GOST94"},
        +{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01),	"PUB_ENCODE_GOST01"},
        +{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE),	"UNPACK_CC_SIGNATURE"},
        +{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE),	"UNPACK_CP_SIGNATURE"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA GOST_str_reasons[]=
        +	{
        +{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
        +{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
        +{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
        +{ERR_REASON(GOST_R_CTRL_CALL_FAILED)     ,"ctrl call failed"},
        +{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
        +{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"},
        +{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
        +{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
        +{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"},
        +{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"},
        +{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"},
        +{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE)  ,"invalid digest type"},
        +{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"},
        +{ERR_REASON(GOST_R_INVALID_IV_LENGTH)    ,"invalid iv length"},
        +{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
        +{ERR_REASON(GOST_R_INVALID_PARAMSET)     ,"invalid paramset"},
        +{ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED),"key is not initalized"},
        +{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
        +{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
        +{ERR_REASON(GOST_R_MAC_KEY_NOT_SET)      ,"mac key not set"},
        +{ERR_REASON(GOST_R_MALLOC_FAILURE)       ,"malloc failure"},
        +{ERR_REASON(GOST_R_NO_MEMORY)            ,"no memory"},
        +{ERR_REASON(GOST_R_NO_PARAMETERS_SET)    ,"no parameters set"},
        +{ERR_REASON(GOST_R_NO_PEER_KEY)          ,"no peer key"},
        +{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
        +{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
        +{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"},
        +{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"},
        +{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
        +{ERR_REASON(GOST_R_SIGNATURE_MISMATCH)   ,"signature mismatch"},
        +{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
        +{ERR_REASON(GOST_R_UKM_NOT_SET)          ,"ukm not set"},
        +{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"},
        +{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef GOST_LIB_NAME
        +static ERR_STRING_DATA GOST_lib_name[]=
        +        {
        +{0	,GOST_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int GOST_lib_error_code=0;
        +static int GOST_error_init=1;
        +
        +void ERR_load_GOST_strings(void)
        +	{
        +	if (GOST_lib_error_code == 0)
        +		GOST_lib_error_code=ERR_get_next_error_library();
        +
        +	if (GOST_error_init)
        +		{
        +		GOST_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(GOST_lib_error_code,GOST_str_functs);
        +		ERR_load_strings(GOST_lib_error_code,GOST_str_reasons);
        +#endif
        +
        +#ifdef GOST_LIB_NAME
        +		GOST_lib_name->error = ERR_PACK(GOST_lib_error_code,0,0);
        +		ERR_load_strings(0,GOST_lib_name);
        +#endif
        +		}
        +	}
        +
        +void ERR_unload_GOST_strings(void)
        +	{
        +	if (GOST_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(GOST_lib_error_code,GOST_str_functs);
        +		ERR_unload_strings(GOST_lib_error_code,GOST_str_reasons);
        +#endif
        +
        +#ifdef GOST_LIB_NAME
        +		ERR_unload_strings(0,GOST_lib_name);
        +#endif
        +		GOST_error_init=1;
        +		}
        +	}
        +
        +void ERR_GOST_error(int function, int reason, char *file, int line)
        +	{
        +	if (GOST_lib_error_code == 0)
        +		GOST_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(GOST_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/ccgost/e_gost_err.h b/vendor/openssl/openssl/engines/ccgost/e_gost_err.h
        new file mode 100644
        index 000000000..6dc500079
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/e_gost_err.h
        @@ -0,0 +1,156 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2005 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_GOST_ERR_H
        +#define HEADER_GOST_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_GOST_strings(void);
        +void ERR_unload_GOST_strings(void);
        +void ERR_GOST_error(int function, int reason, char *file, int line);
        +#define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the GOST functions. */
        +
        +/* Function codes. */
        +#define GOST_F_DECODE_GOST_ALGOR_PARAMS			 99
        +#define GOST_F_ENCODE_GOST_ALGOR_PARAMS			 100
        +#define GOST_F_FILL_GOST2001_PARAMS			 101
        +#define GOST_F_FILL_GOST94_PARAMS			 102
        +#define GOST_F_GET_ENCRYPTION_PARAMS			 103
        +#define GOST_F_GOST2001_COMPUTE_PUBLIC			 104
        +#define GOST_F_GOST2001_DO_SIGN				 105
        +#define GOST_F_GOST2001_DO_VERIFY			 106
        +#define GOST_F_GOST2001_KEYGEN				 107
        +#define GOST_F_GOST89_GET_ASN1_PARAMETERS		 108
        +#define GOST_F_GOST89_SET_ASN1_PARAMETERS		 109
        +#define GOST_F_GOST94_COMPUTE_PUBLIC			 110
        +#define GOST_F_GOST_CIPHER_CTL				 111
        +#define GOST_F_GOST_DO_SIGN				 112
        +#define GOST_F_GOST_DO_VERIFY				 113
        +#define GOST_F_GOST_IMIT_CTRL				 114
        +#define GOST_F_GOST_IMIT_FINAL				 140
        +#define GOST_F_GOST_IMIT_UPDATE				 115
        +#define GOST_F_PARAM_COPY_GOST01			 116
        +#define GOST_F_PARAM_COPY_GOST94			 117
        +#define GOST_F_PKEY_GOST01CP_DECRYPT			 118
        +#define GOST_F_PKEY_GOST01CP_ENCRYPT			 119
        +#define GOST_F_PKEY_GOST01CP_KEYGEN			 120
        +#define GOST_F_PKEY_GOST01_PARAMGEN			 138
        +#define GOST_F_PKEY_GOST2001_DERIVE			 121
        +#define GOST_F_PKEY_GOST94CP_DECRYPT			 122
        +#define GOST_F_PKEY_GOST94CP_ENCRYPT			 123
        +#define GOST_F_PKEY_GOST94CP_KEYGEN			 124
        +#define GOST_F_PKEY_GOST94_PARAMGEN			 139
        +#define GOST_F_PKEY_GOST_CTRL				 125
        +#define GOST_F_PKEY_GOST_CTRL01_STR			 126
        +#define GOST_F_PKEY_GOST_CTRL94_STR			 127
        +#define GOST_F_PKEY_GOST_MAC_CTRL			 128
        +#define GOST_F_PKEY_GOST_MAC_CTRL_STR			 129
        +#define GOST_F_PKEY_GOST_MAC_KEYGEN			 130
        +#define GOST_F_PRINT_GOST_01				 131
        +#define GOST_F_PRIV_DECODE_GOST				 132
        +#define GOST_F_PUB_DECODE_GOST01			 133
        +#define GOST_F_PUB_DECODE_GOST94			 134
        +#define GOST_F_PUB_ENCODE_GOST01			 135
        +#define GOST_F_UNPACK_CC_SIGNATURE			 136
        +#define GOST_F_UNPACK_CP_SIGNATURE			 137
        +
        +/* Reason codes. */
        +#define GOST_R_BAD_KEY_PARAMETERS_FORMAT		 99
        +#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT		 100
        +#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY		 101
        +#define GOST_R_CTRL_CALL_FAILED				 132
        +#define GOST_R_ERROR_COMPUTING_SHARED_KEY		 102
        +#define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO		 103
        +#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO		 104
        +#define GOST_R_INCOMPATIBLE_ALGORITHMS			 105
        +#define GOST_R_INCOMPATIBLE_PEER_KEY			 131
        +#define GOST_R_INVALID_CIPHER_PARAMS			 106
        +#define GOST_R_INVALID_CIPHER_PARAM_OID			 107
        +#define GOST_R_INVALID_DIGEST_TYPE			 108
        +#define GOST_R_INVALID_GOST94_PARMSET			 109
        +#define GOST_R_INVALID_IV_LENGTH			 110
        +#define GOST_R_INVALID_MAC_KEY_LENGTH			 111
        +#define GOST_R_INVALID_PARAMSET				 112
        +#define GOST_R_KEY_IS_NOT_INITALIZED			 113
        +#define GOST_R_KEY_IS_NOT_INITIALIZED			 114
        +#define GOST_R_KEY_PARAMETERS_MISSING			 115
        +#define GOST_R_MAC_KEY_NOT_SET				 116
        +#define GOST_R_MALLOC_FAILURE				 117
        +#define GOST_R_NO_MEMORY				 118
        +#define GOST_R_NO_PARAMETERS_SET			 119
        +#define GOST_R_NO_PEER_KEY				 120
        +#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR	 121
        +#define GOST_R_PUBLIC_KEY_UNDEFINED			 122
        +#define GOST_R_RANDOM_GENERATOR_ERROR			 123
        +#define GOST_R_RANDOM_GENERATOR_FAILURE			 124
        +#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED		 125
        +#define GOST_R_SIGNATURE_MISMATCH			 126
        +#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q		 127
        +#define GOST_R_UKM_NOT_SET				 128
        +#define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND		 129
        +#define GOST_R_UNSUPPORTED_PARAMETER_SET		 130
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/ccgost/e_gost_err.proto b/vendor/openssl/openssl/engines/ccgost/e_gost_err.proto
        new file mode 100644
        index 000000000..c57bd1bd8
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/e_gost_err.proto
        @@ -0,0 +1,61 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2005 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_GOST_ERR_H
        +#define HEADER_GOST_ERR_H
        +
        +#define GOST_LIB_NAME "GOST engine"
        +#ifdef __cplusplus
        + extern "C" {
        +#endif
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost.ec b/vendor/openssl/openssl/engines/ccgost/gost.ec
        new file mode 100644
        index 000000000..6c2c85e57
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost.ec
        @@ -0,0 +1,5 @@
        +L GOST 			e_gost_err.h			e_gost_err.c
        +L NONE    		asymm.h    			NONE
        +L NONE    		md.h    			NONE
        +L NONE    		crypt.h    			NONE
        +L NONE			gostkeyx.h			NONE
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost2001.c b/vendor/openssl/openssl/engines/ccgost/gost2001.c
        new file mode 100644
        index 000000000..dacd82d2b
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost2001.c
        @@ -0,0 +1,343 @@
        +/**********************************************************************
        + *                          gost2001.c                                *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *          Implementation of GOST R 34.10-2001      				  *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include "gost_lcl.h"
        +#include "gost_params.h"
        +#include <string.h>
        +#include <openssl/rand.h>
        +#include <openssl/ecdsa.h>
        +#include <openssl/err.h>
        +#include "e_gost_err.h"
        +#ifdef DEBUG_SIGN
        +extern 
        +void dump_signature(const char *message,const unsigned char *buffer,size_t len);
        +void dump_dsa_sig(const char *message, DSA_SIG *sig);
        +#else
        +
        +#define dump_signature(a,b,c)
        +#define dump_dsa_sig(a,b)
        +#endif
        +
        +/*
        + * Fills EC_KEY structure hidden in the app_data field of DSA structure
        + * with parameter information, extracted from parameter array in
        + * params.c file.
        + *
        + * Also fils DSA->q field with copy of EC_GROUP order field to make
        + * DSA_size function work
        + */ 
        +int fill_GOST2001_params(EC_KEY *eckey, int nid)
        +	{
        +	R3410_2001_params *params = R3410_2001_paramset;
        +	EC_GROUP *grp=NULL;
        +	BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL;
        +	EC_POINT *P=NULL;
        +	BN_CTX *ctx=BN_CTX_new();
        +	int ok=0;
        +	
        +	BN_CTX_start(ctx);
        +	p=BN_CTX_get(ctx);
        +	a=BN_CTX_get(ctx);
        +	b=BN_CTX_get(ctx);
        +	x=BN_CTX_get(ctx);
        +	y=BN_CTX_get(ctx);
        +	q=BN_CTX_get(ctx);
        +	while (params->nid!=NID_undef && params->nid != nid) params++;
        +	if (params->nid == NID_undef)
        +		{
        +		GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
        +		goto err;
        +		}	
        +	BN_hex2bn(&p,params->p);
        +	BN_hex2bn(&a,params->a);
        +	BN_hex2bn(&b,params->b);
        +	
        +	grp = EC_GROUP_new_curve_GFp(p,a,b,ctx);
        +
        +	P = EC_POINT_new(grp);
        +
        +	BN_hex2bn(&x,params->x);
        +	BN_hex2bn(&y,params->y);
        +	EC_POINT_set_affine_coordinates_GFp(grp,P,x,y,ctx);
        +	BN_hex2bn(&q,params->q);
        +#ifdef DEBUG_KEYS
        +	fprintf(stderr,"Set params index %d oid %s\nq=",
        +		(params-R3410_2001_paramset),OBJ_nid2sn(params->nid));
        +	BN_print_fp(stderr,q);
        +	fprintf(stderr,"\n");
        +#endif	
        +
        +	EC_GROUP_set_generator(grp,P,q,NULL);
        +	EC_GROUP_set_curve_name(grp,params->nid);
        +
        +	EC_KEY_set_group(eckey,grp);
        +	ok=1;
        +	err:
        +	EC_POINT_free(P);
        +	EC_GROUP_free(grp);
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	return ok;
        +	}	
        +
        +
        +/*
        + * Computes gost2001 signature as DSA_SIG structure 
        + *
        + *
        + */ 
        +DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
        +	{
        +	DSA_SIG *newsig = NULL;
        +	BIGNUM *md = hashsum2bn(dgst);
        +	BIGNUM *order = NULL;
        +	const EC_GROUP *group;
        +	const BIGNUM *priv_key;
        +	BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL;
        +	EC_POINT *C=NULL;
        +	BN_CTX *ctx = BN_CTX_new();	
        +	BN_CTX_start(ctx);
        +	OPENSSL_assert(dlen==32);
        +	newsig=DSA_SIG_new();
        +	if (!newsig) 
        +		{
        +		GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY);
        +		goto err;
        +		}	
        +	group = EC_KEY_get0_group(eckey);
        +	order=BN_CTX_get(ctx);
        +	EC_GROUP_get_order(group,order,ctx);
        +	priv_key = EC_KEY_get0_private_key(eckey);
        +	e = BN_CTX_get(ctx);
        +	BN_mod(e,md,order,ctx);
        +#ifdef DEBUG_SIGN
        +	fprintf(stderr,"digest as bignum=");
        +	BN_print_fp(stderr,md);
        +	fprintf(stderr,"\ndigest mod q=");
        +	BN_print_fp(stderr,e);
        +	fprintf(stderr,"\n");
        +#endif		
        +	if (BN_is_zero(e))
        +		{
        +		BN_one(e);
        +		}   
        +	k =BN_CTX_get(ctx);
        +	C=EC_POINT_new(group);
        +	do 
        +		{
        +		do 
        +			{
        +			if (!BN_rand_range(k,order)) 
        +				{
        +				GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
        +				DSA_SIG_free(newsig);
        +				newsig = NULL;
        +				goto err;
        +				}	
        +			if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
        +				{
        +				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
        +				DSA_SIG_free(newsig);
        +				newsig = NULL;
        +				goto err;
        +				}	
        +			if (!X) X=BN_CTX_get(ctx);
        +			if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
        +				{
        +				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
        +				DSA_SIG_free(newsig);
        +				newsig = NULL;
        +				goto err;
        +				}	
        +			if (!r) r=BN_CTX_get(ctx);
        +			BN_nnmod(r,X,order,ctx);
        +			}
        +		while (BN_is_zero(r));
        +		/* s =  (r*priv_key+k*e) mod order */
        +		if (!tmp) tmp = BN_CTX_get(ctx);
        +		BN_mod_mul(tmp,priv_key,r,order,ctx);
        +		if (!tmp2) tmp2 = BN_CTX_get(ctx);
        +		BN_mod_mul(tmp2,k,e,order,ctx);
        +		if (!s) s=BN_CTX_get(ctx);
        +		BN_mod_add(s,tmp,tmp2,order,ctx);
        +		}
        +	while (BN_is_zero(s));	
        +
        +	newsig->s=BN_dup(s);
        +	newsig->r=BN_dup(r);
        +	err:			
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	EC_POINT_free(C);
        +	BN_free(md);
        +	return newsig;
        +	}
        +/*
        + * Verifies gost 2001 signature
        + *
        + */ 
        +int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
        +	DSA_SIG *sig, EC_KEY *ec)
        +	{
        +	BN_CTX *ctx=BN_CTX_new();
        +	const EC_GROUP *group = EC_KEY_get0_group(ec);
        +	BIGNUM *order;
        +	BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
        +	BIGNUM *X=NULL,*tmp=NULL;
        +	EC_POINT *C = NULL;
        +	const EC_POINT *pub_key=NULL;
        +	int ok=0;
        +
        +	BN_CTX_start(ctx);
        +	order = BN_CTX_get(ctx);
        +	e = BN_CTX_get(ctx);
        +	z1 = BN_CTX_get(ctx);
        +	z2 = BN_CTX_get(ctx);
        +	tmp = BN_CTX_get(ctx);
        +	X= BN_CTX_get(ctx);	
        +	R=BN_CTX_get(ctx);
        +	v=BN_CTX_get(ctx);
        +	
        +	EC_GROUP_get_order(group,order,ctx);
        +	pub_key = EC_KEY_get0_public_key(ec);
        +	if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
        +		(BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) 
        +		{
        +		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
        +		goto err;
        +
        +		}
        +	md = hashsum2bn(dgst);
        +
        +	BN_mod(e,md,order,ctx);
        +#ifdef DEBUG_SIGN
        +	fprintf(stderr,"digest as bignum: ");
        +	BN_print_fp(stderr,md);
        +	fprintf(stderr,"\ndigest mod q: ");
        +	BN_print_fp(stderr,e);
        +#endif	
        +	if (BN_is_zero(e)) BN_one(e);
        +	v=BN_mod_inverse(v,e,order,ctx);
        +	BN_mod_mul(z1,sig->s,v,order,ctx);
        +	BN_sub(tmp,order,sig->r);
        +	BN_mod_mul(z2,tmp,v,order,ctx);
        +#ifdef DEBUG_SIGN
        +	fprintf(stderr,"\nInverted digest value: ");
        +	BN_print_fp(stderr,v);
        +	fprintf(stderr,"\nz1: ");
        +	BN_print_fp(stderr,z1);
        +	fprintf(stderr,"\nz2: ");
        +	BN_print_fp(stderr,z2);
        +#endif	
        +	C = EC_POINT_new(group);
        +	if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) 
        +		{	
        +		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
        +		goto err;
        +		}	
        +	if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) 
        +		{
        +		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
        +		goto err;
        +		}
        +	BN_mod(R,X,order,ctx);
        +#ifdef DEBUG_SIGN
        +	fprintf(stderr,"\nX=");
        +	BN_print_fp(stderr,X);
        +	fprintf(stderr,"\nX mod q=");
        +	BN_print_fp(stderr,R);
        +	fprintf(stderr,"\n");
        +#endif	
        +	if (BN_cmp(R,sig->r)!=0)
        +		{
        +		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
        +		}
        +	else
        +		{
        +		ok = 1;
        +		}
        +	err:
        +	EC_POINT_free(C);
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	BN_free(md);
        +	return ok;
        +	}
        +/*
        + * Computes GOST R 34.10-2001 public key
        + *
        + *
        + */ 
        +int gost2001_compute_public(EC_KEY *ec) 
        +	{
        +	const EC_GROUP *group = EC_KEY_get0_group(ec);
        +	EC_POINT *pub_key=NULL;
        +	const BIGNUM *priv_key=NULL;
        +	BN_CTX *ctx=NULL;
        +	int ok=0;
        +
        +	if (!group)
        +		{
        +		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
        +		return 0;
        +		}	
        +	ctx=BN_CTX_new();
        +	BN_CTX_start(ctx);
        +	if (!(priv_key=EC_KEY_get0_private_key(ec))) 
        +		{
        +		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
        +		goto err;
        +		}	
        +
        +	pub_key = EC_POINT_new(group);
        +	if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx)) 
        +		{
        +		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
        +		goto err;
        +		}	
        +	if (!EC_KEY_set_public_key(ec,pub_key))
        +		{
        +		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
        +		goto err;
        +		}	
        +	ok = 256;
        +	err:
        +	BN_CTX_end(ctx);
        +	EC_POINT_free(pub_key);
        +	BN_CTX_free(ctx);
        +	return ok;
        +	}
        +/*
        + * 
        + * Generates GOST R 34.10-2001 keypair
        + *
        + *
        + */ 
        +int gost2001_keygen(EC_KEY *ec)
        +	{
        +	BIGNUM *order = BN_new(),*d=BN_new();
        +	const EC_GROUP *group = EC_KEY_get0_group(ec);
        +	EC_GROUP_get_order(group,order,NULL);
        +	
        +	do 
        +		{
        +		if (!BN_rand_range(d,order)) 
        +			{
        +			GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
        +			BN_free(d);
        +			BN_free(order);
        +			return 0;
        +			}	
        +		}
        +	while (BN_is_zero(d));
        +	EC_KEY_set_private_key(ec,d);
        +	BN_free(d);
        +	BN_free(order);
        +	return gost2001_compute_public(ec);
        +	}
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost2001_keyx.c b/vendor/openssl/openssl/engines/ccgost/gost2001_keyx.c
        new file mode 100644
        index 000000000..c74810285
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost2001_keyx.c
        @@ -0,0 +1,308 @@
        +/**********************************************************************
        + *                          gost_keyx.c                               *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *   VK0 34.10-2001 key exchange and GOST R 34.10-2001                *
        + *   based PKCS7/SMIME support                                        *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <openssl/evp.h>
        +#include <openssl/rand.h>
        +#include <string.h>
        +#include <openssl/objects.h>
        +#include "gost89.h"
        +#include "gosthash.h"
        +#include "e_gost_err.h"
        +#include "gost_keywrap.h"
        +#include "gost_lcl.h"
        +#include "gost2001_keyx.h"
        +
        +
        +
        +/* Implementation of CryptoPro VKO 34.10-2001 algorithm */
        +static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,const EC_POINT *pub_key,EC_KEY *priv_key,const unsigned char *ukm)
        +	{
        +	unsigned char ukm_be[8],databuf[64],hashbuf[64];
        +	BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL;
        +	const BIGNUM* key=EC_KEY_get0_private_key(priv_key);
        +	EC_POINT *pnt=EC_POINT_new(EC_KEY_get0_group(priv_key));
        +	int i;
        +	gost_hash_ctx hash_ctx;
        +	BN_CTX *ctx = BN_CTX_new();
        +
        +	for (i=0;i<8;i++)
        +		{
        +		ukm_be[7-i]=ukm[i];
        +		}
        +	BN_CTX_start(ctx);
        +	UKM=getbnfrombuf(ukm_be,8);
        +	p=BN_CTX_get(ctx);
        +	order = BN_CTX_get(ctx);
        +	X=BN_CTX_get(ctx);
        +	Y=BN_CTX_get(ctx);
        +	EC_GROUP_get_order(EC_KEY_get0_group(priv_key),order,ctx);
        +	BN_mod_mul(p,key,UKM,order,ctx);	
        +	EC_POINT_mul(EC_KEY_get0_group(priv_key),pnt,NULL,pub_key,p,ctx);
        +	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key),
        +		pnt,X,Y,ctx);
        +	/*Serialize elliptic curve point same way as we do it when saving
        +	 * key */
        +	store_bignum(Y,databuf,32);
        +	store_bignum(X,databuf+32,32);
        + 	/* And reverse byte order of whole buffer */
        +	for (i=0;i<64;i++)
        +		{
        +		hashbuf[63-i]=databuf[i];
        +		}
        +	init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
        +	start_hash(&hash_ctx);
        +	hash_block(&hash_ctx,hashbuf,64);
        +	finish_hash(&hash_ctx,shared_key);
        +	done_gost_hash_ctx(&hash_ctx);
        +	BN_free(UKM);
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	EC_POINT_free(pnt);
        +	return 32;
        +	}
        +
        +
        +/*
        + * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001
        + * algorithm
        + */
        +int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
        +{
        +	/* Public key of peer in the ctx field peerkey
        +	 * Our private key in the ctx pkey
        +	 * ukm is in the algorithm specific context data
        +	 */
        +	EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
        +	EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
        +	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +	
        +	if (!data->shared_ukm) {
        +		GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET);
        +		return 0;
        +	}	
        +
        +	if (key == NULL) {
        +		*keylen = 32;
        +		return 32;
        +	}	
        +	
        +	*keylen=VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
        +		(EC_KEY *)EVP_PKEY_get0(my_key),data->shared_ukm);
        +	return 1;	
        +}
        +
        +
        +
        +
        +/*  
        + * EVP_PKEY_METHOD callback encrypt  
        + * Implementation of GOST2001 key transport, cryptocom variation 
        + */
        +/* Generates ephemeral key based on pubk algorithm
        + * computes shared key using VKO and returns filled up
        + * GOST_KEY_TRANSPORT structure
        + */
        +
        +/*  
        + * EVP_PKEY_METHOD callback encrypt  
        + * Implementation of GOST2001 key transport, cryptopo variation 
        + */
        +
        +int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) 
        +	{
        +	GOST_KEY_TRANSPORT *gkt=NULL; 
        +	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
        +	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
        +	const struct gost_cipher_info *param=get_encryption_params(NULL);
        +	unsigned char ukm[8], shared_key[32], crypted_key[44];
        +	int ret=0;
        +	int key_is_ephemeral=1;
        +	gost_ctx cctx;
        +	EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx);
        +	if (data->shared_ukm) 
        +		{
        +		memcpy(ukm, data->shared_ukm,8);
        +		} 
        +	else if (out) 
        +		{
        +		
        +		if (RAND_bytes(ukm,8)<=0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
        +				GOST_R_RANDOM_GENERATOR_FAILURE);
        +			return 0;
        +			}	
        +		}	
        +	/* Check for private key in the peer_key of context */	
        +	if (sec_key) 
        +		{
        +		key_is_ephemeral=0;
        +		if (!gost_get0_priv_key(sec_key)) 
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
        +			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
        +			goto err;
        +			}	
        +		} 
        +	else 
        +		{
        +		key_is_ephemeral=1;
        +		if (out) 
        +			{
        +			sec_key = EVP_PKEY_new();
        +			EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new());
        +			EVP_PKEY_copy_parameters(sec_key,pubk);
        +			if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) 
        +				{
        +				goto err;
        +				}	
        +			}
        +		}
        +	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
        +		{
        +		param= gost_cipher_list+1;
        +		}	
        +    if (out) 
        +		{
        +		VKO_compute_key(shared_key,32,EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),EVP_PKEY_get0(sec_key),ukm);
        +		gost_init(&cctx,param->sblock);	
        +		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
        +		}
        +	gkt = GOST_KEY_TRANSPORT_new();
        +	if (!gkt)
        +		{
        +		goto err;
        +		}	
        +	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
        +			ukm,8))
        +		{
        +		goto err;
        +		}	
        +	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
        +		{
        +		goto err;
        +		}
        +	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
        +		{
        +		goto err;
        +		}
        +	if (key_is_ephemeral) {	
        +		if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk))
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
        +					GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
        +			goto err;
        +			}	
        +	}		
        +	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
        +	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
        +	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
        +	if (!key_is_ephemeral)
        +		{
        +		/* Set control "public key from client certificate used" */
        +		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
        +				GOST_R_CTRL_CALL_FAILED);
        +			goto err;
        +			}
        +		}
        +	if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1;
        +	GOST_KEY_TRANSPORT_free(gkt);
        +	return ret;	
        +	err:		
        +	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
        +	GOST_KEY_TRANSPORT_free(gkt);
        +	return -1;
        +	}
        +/*  
        + * EVP_PKEY_METHOD callback decrypt  
        + * Implementation of GOST2001 key transport, cryptopo variation 
        + */
        +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_len, const unsigned char *in, size_t in_len)
        +	{
        +	const unsigned char *p = in;
        +	EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
        +	GOST_KEY_TRANSPORT *gkt = NULL;
        +	int ret=0;	
        +	unsigned char wrappedKey[44];
        +	unsigned char sharedKey[32];
        +	gost_ctx ctx;
        +	const struct gost_cipher_info *param=NULL;
        +	EVP_PKEY *eph_key=NULL, *peerkey=NULL;
        +
        +	if (!key)
        +		{
        +		*key_len = 32;
        +		return 1;
        +		}	
        +	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
        +		in_len);
        +	if (!gkt)
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
        +		return -1;
        +		}	
        +
        +	/* If key transport structure contains public key, use it */
        +	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
        +	if (eph_key)
        +		{
        +		if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
        +				GOST_R_INCOMPATIBLE_PEER_KEY);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		/* Set control "public key from client certificate used" */
        +		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
        +				GOST_R_CTRL_CALL_FAILED);
        +			goto err;
        +			}
        +		}
        +	peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
        +	if (!peerkey)
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
        +			GOST_R_NO_PEER_KEY);
        +		goto err;
        +		}
        +		
        +	param = get_encryption_params(gkt->key_agreement_info->cipher);
        +    if(!param){
        +        goto err;
        +    }
        +
        +	gost_init(&ctx,param->sblock);	
        +	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
        +	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
        +	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
        +	memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
        +	OPENSSL_assert(gkt->key_info->imit->length==4);
        +	memcpy(wrappedKey+40,gkt->key_info->imit->data,4);	
        +	VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)),
        +		EVP_PKEY_get0(priv),wrappedKey);
        +	if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key))
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
        +			GOST_R_ERROR_COMPUTING_SHARED_KEY);
        +		goto err;
        +		}	
        +				
        +	ret=1;
        +err:	
        +	if (eph_key) EVP_PKEY_free(eph_key);
        +	if (gkt) GOST_KEY_TRANSPORT_free(gkt);
        +	return ret;
        +	}
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost2001_keyx.h b/vendor/openssl/openssl/engines/ccgost/gost2001_keyx.h
        new file mode 100644
        index 000000000..a014d9c1e
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost2001_keyx.h
        @@ -0,0 +1,10 @@
        +GOST_KEY_TRANSPORT *
        +make_rfc4490_keytransport_2001(EVP_PKEY *pubk, BIGNUM *eph_key,
        +                               const unsigned char *key, size_t keylen,
        +                               unsigned char *ukm, size_t ukm_len);
        +
        +int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,
        +                                    GOST_KEY_TRANSPORT *gkt,
        +                                    unsigned char *key_buf,
        +                                    int key_buf_len) ;
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost89.c b/vendor/openssl/openssl/engines/ccgost/gost89.c
        new file mode 100644
        index 000000000..b0568c6b3
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost89.c
        @@ -0,0 +1,421 @@
        +/**********************************************************************
        + *                        gost89.c                                    *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *          Implementation of GOST 28147-89 encryption algorithm      *
        + *            No OpenSSL libraries required to compile and use        *
        + *                              this code                             *
        + **********************************************************************/ 
        +#include <string.h>
        +#include "gost89.h"
        +/* Substitution blocks from RFC 4357 
        +   
        +   Note: our implementation of gost 28147-89 algorithm 
        +   uses S-box matrix rotated 90 degrees counterclockwise, relative to 
        +   examples given in RFC.
        +  
        +
        +*/
        +
        +/* Substitution blocks from test examples for GOST R 34.11-94*/
        +gost_subst_block GostR3411_94_TestParamSet = {
        +	{0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC},
        +	{0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC},
        +	{0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE},
        +	{0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2},
        +	{0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3},
        +	{0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB},
        +	{0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9},
        +	{0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3}
        +	};  
        +/* Substitution blocks for hash function 1.2.643.2.9.1.6.1  */
        +gost_subst_block GostR3411_94_CryptoProParamSet= {
        +	{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
        +	{0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB},
        +	{0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3},
        +	{0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5},
        +	{0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3},
        +	{0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
        +	{0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8},
        +	{0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
        +	} ;
        +
        +/* Test paramset from GOST 28147 */
        +gost_subst_block Gost28147_TestParamSet =
        +	{
        +	{0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
        +	{0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD},
        +	{0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4},
        +	{0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4},
        +	{0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8},
        +	{0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB},
        +	{0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5},
        +	{0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6}
        +	};
        +
        +
        +
        +
        +/* 1.2.643.2.2.31.1 */
        +gost_subst_block Gost28147_CryptoProParamSetA= {
        +	{0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4},
        +	{0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE},
        +	{0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6},
        +	{0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6},
        +	{0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6},
        +	{0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9},
        +	{0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1},
        +	{0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
        +	};
        +/* 1.2.643.2.2.31.2 */
        +gost_subst_block Gost28147_CryptoProParamSetB= 
        +	{
        +	{0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
        +	{0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE},
        +	{0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5},
        +	{0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3},
        +	{0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8},
        +	{0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4},
        +	{0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE},
        +	{0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
        +	};
        +/* 1.2.643.2.2.31.3 */
        +gost_subst_block Gost28147_CryptoProParamSetC= 
        +	{
        +	{0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
        +	{0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7},
        +	{0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD},
        +	{0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7},
        +	{0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4},
        +	{0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB},
        +	{0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3},
        +	{0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
        +	};
        +
        +/* 1.2.643.2.2.31.4 */ 
        +gost_subst_block Gost28147_CryptoProParamSetD=
        +	{
        +	{0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
        +	{0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7},
        +	{0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6},
        +	{0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1},
        +	{0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8},
        +	{0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2},
        +	{0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1},
        +	{0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
        +	};
        +
        +
        +const byte CryptoProKeyMeshingKey[]={
        +	0x69, 0x00, 0x72, 0x22,   0x64, 0xC9, 0x04, 0x23,
        +    0x8D, 0x3A, 0xDB, 0x96,   0x46, 0xE9, 0x2A, 0xC4,
        +    0x18, 0xFE, 0xAC, 0x94,   0x00, 0xED, 0x07, 0x12,
        +    0xC0, 0x86, 0xDC, 0xC2,   0xEF, 0x4C, 0xA9, 0x2B
        +	};	
        +/* Initialization of gost_ctx subst blocks*/
        +static void kboxinit(gost_ctx *c, const gost_subst_block *b)
        +	{ 
        +	int i; 
        +	
        +	for (i = 0; i < 256; i++)
        +		{
        +		c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24;
        +		c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16;
        +		c->k43[i] = (b->k4[i>>4] <<4  | b->k3 [i &15])<<8;
        +		c->k21[i] = b->k2[i>>4] <<4  | b->k1 [i &15];
        +
        +		}
        +	}
        +
        +/* Part of GOST 28147 algorithm moved into separate function */
        +static word32 f(gost_ctx *c,word32 x) 
        +	{
        +	x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]| 
        +		c->k43[x>> 8 & 255] | c->k21[x & 255]; 
        +	/* Rotate left 11 bits */ 
        +	return x<<11 | x>>(32-11);
        +	}
        +/* Low-level encryption routine - encrypts one 64 bit block*/
        +void gostcrypt(gost_ctx *c, const byte *in, byte *out)
        +	{ 
        +	register word32 n1, n2; /* As named in the GOST */ 
        +	n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); 
        +	n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); 
        +	/* Instead of swapping halves, swap names each round */ 
        + 	 
        +	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
        +	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
        +	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); 
        +	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
        +  
        +	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
        +	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
        +	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
        +	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
        +                               
        +	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
        +	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
        +	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
        +	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
        +                               
        +	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
        +	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
        +	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
        +	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
        + 
        +	out[0] = (byte)(n2&0xff);  out[1] = (byte)((n2>>8)&0xff);
        +	out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24); 
        +	out[4] = (byte)(n1&0xff);  out[5] = (byte)((n1>>8)&0xff);
        +	out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
        +	} 
        +/* Low-level decryption routine. Decrypts one 64-bit block */
        +void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
        +	{ 
        +	register word32 n1, n2; /* As named in the GOST */ 
        +	n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); 
        +	n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); 
        +	
        +	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
        +	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
        +	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
        +	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
        +	
        +	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
        +	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
        +	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
        +	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
        +	
        +	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
        +	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
        +	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
        +	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
        +	
        +	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
        +	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
        +	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
        +	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
        +
        +	out[0] = (byte)(n2&0xff);  out[1] = (byte)((n2>>8)&0xff);
        +	out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
        +	out[4] = (byte)(n1&0xff);  out[5] = (byte)((n1>>8)&0xff);
        +	out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
        +	} 
        +
        +/* Encrypts several blocks in ECB mode */
        +void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
        +	{ 
        +	int i; 
        +	for(i=0;i<blocks;i++)
        +		{ 
        +		gostcrypt(c,clear,cipher); 
        +		clear+=8;
        +		cipher+=8;
        +		}
        +	}
        +/* Decrypts several blocks in ECB mode */
        +void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
        +	{ 
        +	int i; 
        +	for(i=0;i<blocks;i++)
        +		{ 
        +		gostdecrypt(c,cipher,clear); 
        +		clear+=8; 
        +		cipher+=8;
        +		}
        +	}
        +
        +/* Encrypts several full blocks in CFB mode using 8byte IV */
        +void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks)
        +	{
        +	byte cur_iv[8];
        +	byte gamma[8];
        +	int i,j;
        +	const byte *in;
        +	byte *out;
        +	memcpy(cur_iv,iv,8);
        +	for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8)
        +		{
        +		gostcrypt(ctx,cur_iv,gamma);
        +		for (j=0;j<8;j++)
        +			{
        +			cur_iv[j]=out[j]=in[j]^gamma[j];
        +			}
        +		}	
        +	}	
        +/* Decrypts several full blocks in CFB mode using 8byte IV */
        +void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,  int blocks)
        +	{
        +	byte cur_iv[8];
        +	byte gamma[8];
        +	int i,j;
        +	const byte *in;
        +	byte *out;
        +	memcpy(cur_iv,iv,8);
        +	for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8)
        +		{
        +		gostcrypt(ctx,cur_iv,gamma);
        +		for (j=0;j<8;j++)
        +			{
        +			out[j]=(cur_iv[j]=in[j])^gamma[j];
        +			}
        +		}	
        +	}	
        +
        +/* Encrypts one block using specified key */
        +void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock) 
        +	{
        +	gost_key(c,key);
        +	gostcrypt(c,inblock,outblock);
        +	}
        +
        +/* Set 256 bit  key into context */
        +void gost_key(gost_ctx *c, const byte *k) 
        +	{ 
        +	int i,j; 
        +	for(i=0,j=0;i<8;i++,j+=4)
        +		{
        +		c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24);
        +		}		
        +	} 
        +
        +/* Retrieve 256-bit key from context */
        +void gost_get_key(gost_ctx *c, byte *k) 
        +	{
        +	int i,j; 
        +	for(i=0,j=0;i<8;i++,j+=4)
        +		{
        +		k[j]=(byte)(c->k[i]& 0xFF);
        +		k[j+1]=(byte)((c->k[i]>>8 )&0xFF);
        +		k[j+2]=(byte)((c->k[i]>>16) &0xFF);
        +		k[j+3]=(byte)((c->k[i]>>24) &0xFF);
        +		}		
        +	}
        +
        +/* Initalize context. Provides default value for subst_block */
        +void gost_init(gost_ctx *c, const gost_subst_block *b)
        +	{ 	
        +	if(!b)
        +		{
        +		b=&GostR3411_94_TestParamSet;
        +		}	
        +	kboxinit(c,b); 
        +	}
        +
        +/* Cleans up key from context */
        +void gost_destroy(gost_ctx *c)
        +	{ 
        +	int i; for(i=0;i<8;i++) c->k[i]=0; 
        +	} 
        +
        +/* Compute GOST 28147 mac block 
        + * 
        + * Parameters
        + *   gost_ctx *c - context initalized with substitution blocks and key
        + *   buffer - 8-byte mac state buffer
        + *   block 8-byte block to process.
        + * */
        +void mac_block(gost_ctx *c,byte *buffer,const  byte *block)
        +	{
        +	register word32 n1, n2; /* As named in the GOST */ 
        +	int i;
        +	for (i=0; i<8; i++)
        +		{
        +		buffer[i]^=block[i];
        +		}	  
        +	n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24); 
        +	n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24); 
        +	/* Instead of swapping halves, swap names each round */ 
        + 	 
        +	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
        +	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
        +	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); 
        +	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
        +  
        +	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
        +	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
        +	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
        +	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
        +
        +	buffer[0] = (byte)(n1&0xff);  buffer[1] = (byte)((n1>>8)&0xff);
        +	buffer[2] = (byte)((n1>>16)&0xff); buffer[3] = (byte)(n1>>24);
        +	buffer[4] = (byte)(n2&0xff);  buffer[5] = (byte)((n2>>8)&0xff);
        +	buffer[6] = (byte)((n2>>16)&0xff); buffer[7] = (byte)(n2>>24);
        +	}
        +
        +/* Get mac with specified number of bits from MAC state buffer */
        +void get_mac(byte *buffer,int nbits,byte *out)
        +	{
        +	int nbytes= nbits >> 3;
        +	int rembits = nbits & 7;
        +	int mask =rembits?((1<rembits)-1):0;
        +	int i;
        +	for (i=0;i<nbytes;i++) out[i]=buffer[i];
        +	if (rembits) out[i]=buffer[i]&mask;
        +	}	
        +
        +/* Compute mac of specified length (in bits) from data. 
        + * Context should be initialized with key and subst blocks */
        +int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
        +	unsigned int data_len,unsigned char *mac) 
        +	{
        +	byte buffer[8]={0,0,0,0,0,0,0,0};
        +	byte buf2[8];
        +	unsigned int i;
        +	for (i=0;i+8<=data_len;i+=8) 
        +		mac_block(ctx,buffer,data+i);
        +	if (i<data_len)
        +		{
        +		memset(buf2,0,8);
        +		memcpy(buf2,data+i,data_len-i);
        +		mac_block(ctx,buffer,buf2);
        +		i+=8;
        +		}
        +	if (i==8)
        +		{
        +		memset(buf2,0,8);
        +		mac_block(ctx,buffer,buf2);
        +		}
        +	get_mac(buffer,mac_len,mac);
        +	return 1;
        +	}
        +
        +/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
        +int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned char *data,
        +	unsigned int data_len,unsigned char *mac) 
        +	{
        +	byte buffer[8];
        +	byte buf2[8];
        +	unsigned int i;
        +	memcpy (buffer,iv,8);
        +	for (i=0;i+8<=data_len;i+=8) 
        +		mac_block(ctx,buffer,data+i);
        +	if (i<data_len)
        +		{
        +		memset(buf2,0,8);
        +		memcpy(buf2,data+i,data_len-i);
        +		mac_block(ctx,buffer,buf2);
        +		i+=8;
        +		}	
        +	if (i==8)
        +		{
        +		memset(buf2,0,8);
        +		mac_block(ctx,buffer,buf2);
        +		}
        +	get_mac(buffer,mac_len,mac);
        +	return 1;
        +	}
        +
        +/* Implements key meshing algorithm by modifing ctx and IV in place */
        +void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv)
        +	{
        +	unsigned char newkey[32],newiv[8];
        +	/* Set static keymeshing key */
        +	/* "Decrypt" key with keymeshing key */
        +	gost_dec(ctx,CryptoProKeyMeshingKey,newkey,4);
        +	/* set new key */
        +	gost_key(ctx,newkey);
        +	/* Encrypt iv with new key */
        +	gostcrypt(ctx,iv,newiv);
        +	memcpy(iv,newiv,8);
        +	}
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost89.h b/vendor/openssl/openssl/engines/ccgost/gost89.h
        new file mode 100644
        index 000000000..215785251
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost89.h
        @@ -0,0 +1,96 @@
        +/**********************************************************************
        + *                        gost89.h                                    *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *     This file is distributed under the same license as OpenSSL     *
        + *                                                                    *
        + *          Declarations for GOST 28147-89 encryption algorithm       *
        + *            No OpenSSL libraries required to compile and use        *
        + *                       this code                                    *
        + **********************************************************************/            
        +#ifndef GOST89_H
        +#define GOST89_H
        +
        +/* Typedef for unsigned 32-bit integer */
        +#if __LONG_MAX__ > 2147483647L 
        +typedef unsigned int u4; 
        +#else 
        +typedef unsigned long u4; 
        +#endif 
        +/* Typedef for unsigned 8-bit integer */
        +typedef unsigned char byte; 
        +
        +/* Internal representation of GOST substitution blocks */
        +typedef struct {
        +		byte k8[16];
        +		byte k7[16];
        +		byte k6[16];
        +		byte k5[16];
        +		byte k4[16];
        +		byte k3[16];
        +		byte k2[16];
        +		byte k1[16];
        +} gost_subst_block;		
        +
        +
        +/* Cipher context includes key and preprocessed  substitution block */
        +typedef struct { 
        +		u4 k[8]; 
        +		/* Constant s-boxes -- set up in gost_init(). */ 
        +		u4 k87[256],k65[256],k43[256],k21[256]; 
        +} gost_ctx; 
        +/* Note: encrypt and decrypt expect full blocks--padding blocks is 
        +         caller's responsibility. All bulk encryption is done in 
        +		 ECB mode by these calls. Other modes may be added easily 
        +		 enough.                                            */
        +/* Encrypt several full blocks in ECB mode */
        +void gost_enc(gost_ctx *ctx, const byte *clear,byte *cipher, int blocks); 
        +/* Decrypt several full blocks in ECB mode */
        +void gost_dec(gost_ctx *ctx, const byte *cipher,byte *clear, int blocks); 
        +/* Encrypts several full blocks in CFB mode using 8byte IV */
        +void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher,int  blocks);
        +/* Decrypts several full blocks in CFB mode using 8byte IV */
        +void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,int  blocks);
        +
        +/* Encrypt one  block */
        +void gostcrypt(gost_ctx *c, const byte *in, byte *out);
        +/* Decrypt one  block */
        +void gostdecrypt(gost_ctx *c, const byte *in,byte *out);
        +/* Set key into context */
        +void gost_key(gost_ctx *ctx, const byte *key); 
        +/* Get key from context */
        +void gost_get_key(gost_ctx *ctx, byte *key);
        +/* Set S-blocks into context */
        +void gost_init(gost_ctx *ctx, const gost_subst_block *subst_block); 
        +/* Clean up context */
        +void gost_destroy(gost_ctx *ctx);
        +/* Intermediate function used for calculate hash */
        +void gost_enc_with_key(gost_ctx *,byte *key,byte *inblock,byte *outblock);
        +/* Compute MAC of given length in bits from data */
        +int gost_mac(gost_ctx *ctx,int hmac_len,const unsigned char *data,
        +		unsigned int data_len,unsigned char *hmac) ;
        +/* Compute MAC of given length in bits from data, using non-zero 8-byte
        + * IV (non-standard, for use in CryptoPro key transport only */
        +int gost_mac_iv(gost_ctx *ctx,int hmac_len,const unsigned char *iv,const unsigned char *data,
        +		unsigned int data_len,unsigned char *hmac) ;
        +/* Perform one step of MAC calculation like gostcrypt */
        +void mac_block(gost_ctx *c,byte *buffer,const  byte *block); 
        +/* Extracts MAC value from mac state buffer */
        +void get_mac(byte *buffer,int nbits,byte *out);
        +/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/
        +void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv);
        +/* Parameter sets specified in RFC 4357 */
        +extern gost_subst_block GostR3411_94_TestParamSet;
        +extern gost_subst_block GostR3411_94_CryptoProParamSet;
        +extern gost_subst_block Gost28147_TestParamSet;
        +extern gost_subst_block Gost28147_CryptoProParamSetA;
        +extern gost_subst_block Gost28147_CryptoProParamSetB;
        +extern gost_subst_block Gost28147_CryptoProParamSetC;
        +extern gost_subst_block Gost28147_CryptoProParamSetD;
        +extern const byte CryptoProKeyMeshingKey[]; 
        +#if __LONG_MAX__ > 2147483647L 
        +typedef unsigned int word32; 
        +#else 
        +typedef unsigned long word32; 
        +#endif 
        +
        +#endif
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost94_keyx.c b/vendor/openssl/openssl/engines/ccgost/gost94_keyx.c
        new file mode 100644
        index 000000000..0d7d3ffe6
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost94_keyx.c
        @@ -0,0 +1,291 @@
        +/**********************************************************************
        + *                             gost94_keyx.c                          *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *     Implements generation and parsing of GOST_KEY_TRANSPORT for    *
        + *     			GOST R 34.10-94 algorithms                            *
        + *																	  *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <string.h>
        +#include <openssl/dh.h>
        +#include <openssl/rand.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +
        +#include "gost89.h"
        +#include "gosthash.h"
        +#include "e_gost_err.h"
        +#include "gost_keywrap.h"
        +#include "gost_lcl.h"
        +/* Common functions for both 94 and 2001 key exchange schemes */
        +/* Implementation of the Diffi-Hellman key agreement scheme based on
        + * GOST-94 keys */
        +
        +/* Computes Diffie-Hellman key and stores it into buffer in
        + * little-endian byte order as expected by both versions of GOST 94
        + * algorithm
        + */
        +static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) 
        +	{
        +	unsigned char be_key[128];
        +	int i,key_size;
        +	key_size=DH_compute_key(be_key,pub_key,dh);
        +	if (!key_size) return 0;
        +	memset(pair_key,0,128);
        +	for (i=0;i<key_size;i++)
        +		{
        +		pair_key[i]=be_key[key_size-1-i];
        +		}
        +	return key_size;	
        +	}	
        +
        +/*
        + * Computes 256 bit Key exchange key as specified in RFC 4357 
        + */
        +static int make_cp_exchange_key(BIGNUM *priv_key,EVP_PKEY *pubk, unsigned char *shared_key)
        +	{
        +	unsigned char dh_key [128];
        +	int ret;
        +	gost_hash_ctx hash_ctx;
        +	DH *dh = DH_new();
        +	
        +	if (!dh)
        +		return 0;
        +	memset(dh_key,0,128);
        +	dh->g = BN_dup(pubk->pkey.dsa->g);
        +	dh->p = BN_dup(pubk->pkey.dsa->p);
        +	dh->priv_key = BN_dup(priv_key);
        +	ret=compute_pair_key_le(dh_key,((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,dh) ;
        +	DH_free(dh);
        +	if (!ret)	return 0;
        +	init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
        +	start_hash(&hash_ctx);
        +	hash_block(&hash_ctx,dh_key,128);
        +	finish_hash(&hash_ctx,shared_key);
        +	done_gost_hash_ctx(&hash_ctx);
        +	return 1;
        +	}
        +
        +/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */
        +
        +int pkey_gost94_derive(EVP_PKEY_CTX *ctx,unsigned char *key,size_t *keylen)
        +	{
        +		EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx);
        +		EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx);
        +		*keylen = 32;
        +		if (key == NULL) return 1;
        +
        +		return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
        +	}
        +
        +/* EVP_PKEY_METHOD callback encrypt for
        + * GOST R 34.10-94 cryptopro modification
        + */
        +
        +
        +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) 
        +	{
        +	GOST_KEY_TRANSPORT *gkt=NULL;
        +	unsigned char shared_key[32], ukm[8],crypted_key[44];
        +	const struct gost_cipher_info *param=get_encryption_params(NULL);
        +	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
        +	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +	gost_ctx cctx;
        +	int key_is_ephemeral=1;
        +	EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);
        +
        +	/* Do not use vizir cipher parameters with cryptopro */
        +	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
        +		{
        +		param= gost_cipher_list+1;
        +		}	
        +
        +	if (mykey) 
        +		{
        +		/* If key already set, it is not ephemeral */
        +		key_is_ephemeral=0;
        +		if (!gost_get0_priv_key(mykey)) 
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
        +			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
        +			goto err;
        +			}	
        +		} 
        +	else 
        +		{
        +		/* Otherwise generate ephemeral key */
        +		key_is_ephemeral = 1;
        +		if (out) 
        +			{
        +			mykey = EVP_PKEY_new();
        +			EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new());
        +			EVP_PKEY_copy_parameters(mykey,pubk);
        +			if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) 
        +				{
        +				goto err;
        +				}	
        +			}
        +		}	
        +	if (out)
        +		make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key);
        +	if (data->shared_ukm) 
        +		{
        +		memcpy(ukm,data->shared_ukm,8);
        +		}
        +	else if (out) 
        +		{	
        +		if (RAND_bytes(ukm,8)<=0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
        +					GOST_R_RANDOM_GENERATOR_FAILURE);
        +			goto err;
        +			}	
        +		}
        +		
        +	if (out) {
        +		gost_init(&cctx,param->sblock);
        +		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
        +	}	
        +	gkt = GOST_KEY_TRANSPORT_new();
        +	if (!gkt)
        +		{
        +		goto memerr;
        +		}	
        +	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
        +			ukm,8))
        +		{
        +		goto memerr;
        +		}	
        +	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
        +		{
        +		goto memerr;
        +		}
        +	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
        +		{
        +		goto memerr;
        +		}
        +	if (key_is_ephemeral) {	
        +	if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk))
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
        +		goto err;
        +		}
        +		if (out) EVP_PKEY_free(mykey);
        +	}	
        +	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
        +	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
        +	*outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL);
        +	if (*outlen <= 0)
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
        +		goto err;
        +		}
        +	if (!key_is_ephemeral)
        +		{
        +		/* Set control "public key from client certificate used" */
        +		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
        +				GOST_R_CTRL_CALL_FAILED);
        +			goto err;
        +			}
        +		}
        +	GOST_KEY_TRANSPORT_free(gkt);
        +	return 1;	
        +	memerr:
        +		if (key_is_ephemeral) {
        +			EVP_PKEY_free(mykey);
        +		}	
        +	GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
        +		GOST_R_MALLOC_FAILURE);
        +	err:		
        +	GOST_KEY_TRANSPORT_free(gkt);
        +	return -1;
        +	}
        +
        +	
        +/* EVP_PLEY_METHOD callback decrypt for
        + * GOST R 34.10-94 cryptopro modification
        + */
        +int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) {
        +	const unsigned char *p = in;
        +	GOST_KEY_TRANSPORT *gkt = NULL;
        +	unsigned char wrappedKey[44];
        +	unsigned char sharedKey[32];
        +	gost_ctx cctx;
        +	const struct gost_cipher_info *param=NULL;
        +	EVP_PKEY *eph_key=NULL, *peerkey=NULL;
        +	EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); 
        +	
        +	if (!key)
        +		{
        +		*key_len = 32;
        +		return 1;
        +		}	
        +	
        +	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
        +		in_len);
        +	if (!gkt)
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
        +		return 0;
        +		}	
        +	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
        +	if (eph_key)
        +		{
        +		if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
        +				GOST_R_INCOMPATIBLE_PEER_KEY);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		/* Set control "public key from client certificate used" */
        +		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
        +				GOST_R_CTRL_CALL_FAILED);
        +			goto err;
        +			}
        +		}
        +	peerkey = EVP_PKEY_CTX_get0_peerkey(ctx);
        +	if (!peerkey)
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
        +			GOST_R_NO_PEER_KEY);
        +		goto err;
        +		}
        +
        +	param = get_encryption_params(gkt->key_agreement_info->cipher);
        +    if(!param){
        +        goto err;
        +    }
        +	
        +	gost_init(&cctx,param->sblock);	
        +	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
        +	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
        +	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
        +	memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
        +	OPENSSL_assert(gkt->key_info->imit->length==4);
        +	memcpy(wrappedKey+40,gkt->key_info->imit->data,4);	
        +	make_cp_exchange_key(gost_get0_priv_key(priv),peerkey,sharedKey);
        +	if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key))
        +		{
        +		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
        +			GOST_R_ERROR_COMPUTING_SHARED_KEY);
        +		goto err;
        +		}	
        +				
        +	EVP_PKEY_free(eph_key);
        +	GOST_KEY_TRANSPORT_free(gkt);
        +	return 1;
        +err:
        +	EVP_PKEY_free(eph_key);
        +	GOST_KEY_TRANSPORT_free(gkt);
        +	return -1;
        +	}	
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_ameth.c b/vendor/openssl/openssl/engines/ccgost/gost_ameth.c
        new file mode 100644
        index 000000000..2cde1fcfd
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_ameth.c
        @@ -0,0 +1,945 @@
        +/**********************************************************************
        + *                          gost_ameth.c                              *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *       Implementation of RFC 4490/4491 ASN1 method                  *
        + *       for OpenSSL                                                  *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/engine.h>
        +#include <openssl/evp.h>
        +#include <openssl/asn1.h>
        +#ifndef OPENSSL_NO_CMS
        +#include <openssl/cms.h>
        +#endif
        +#include "gost_params.h"
        +#include "gost_lcl.h"
        +#include "e_gost_err.h"
        +
        +int gost94_nid_by_params(DSA *p) 
        +	{
        +	R3410_params *gost_params;
        +	BIGNUM *q=BN_new();
        +	for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) 
        +		{
        +		BN_dec2bn(&q,gost_params->q);
        +		if (!BN_cmp(q,p->q)) 
        +			{
        +			BN_free(q);
        +			return gost_params->nid;
        +			}
        +		}	
        +	BN_free(q);
        +	return NID_undef;
        +	}
        +
        +static ASN1_STRING  *encode_gost_algor_params(const EVP_PKEY *key)
        +	{
        +	ASN1_STRING *params = ASN1_STRING_new();
        +	GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
        +	int pkey_param_nid = NID_undef;
        +
        +	if (!params || !gkp) 
        +		{
        +		GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
        +			ERR_R_MALLOC_FAILURE);
        +		ASN1_STRING_free(params);
        +		params = NULL;
        +		goto err;
        +		}	
        +	switch (EVP_PKEY_base_id(key)) 
        +		{
        +		case NID_id_GostR3410_2001:
        +			pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key)));
        +			break;
        +		case NID_id_GostR3410_94:
        +			pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
        +			if (pkey_param_nid == NID_undef) 
        +				{
        +				GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
        +					GOST_R_INVALID_GOST94_PARMSET);
        +				ASN1_STRING_free(params);
        +				params=NULL;
        +				goto err;
        +				}	
        +			break;
        +		}	
        +	gkp->key_params = OBJ_nid2obj(pkey_param_nid);
        +	gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
        +	/*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);*/
        +	params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
        +	if (params->length <=0 ) 
        +		{
        +		GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
        +			ERR_R_MALLOC_FAILURE);
        +		ASN1_STRING_free(params);
        +		params = NULL;
        +		goto err;
        +		}
        +	params ->type = V_ASN1_SEQUENCE;
        +	err:
        +	GOST_KEY_PARAMS_free(gkp);
        +	return params;
        +	}
        +
        +/* Parses GOST algorithm parameters from X509_ALGOR and
        + * modifies pkey setting NID and parameters
        + */
        +static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 
        +	{
        +	ASN1_OBJECT *palg_obj =NULL;
        +	int ptype = V_ASN1_UNDEF;
        +	int pkey_nid = NID_undef,param_nid = NID_undef;
        +        void *_pval;
        +	ASN1_STRING *pval = NULL;
        +	const unsigned char  *p;
        +	GOST_KEY_PARAMS *gkp = NULL;
        +
        +	X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
        +        pval = _pval;
        +	if (ptype != V_ASN1_SEQUENCE) 
        +		{
        +		GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
        +			GOST_R_BAD_KEY_PARAMETERS_FORMAT);
        +		return 0;
        +		}	
        +	p=pval->data;
        +	pkey_nid = OBJ_obj2nid(palg_obj);
        +
        +	gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length);
        +	if (!gkp) 
        +		{
        +		GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
        +			GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
        +		return 0;
        +		}	
        +	param_nid = OBJ_obj2nid(gkp->key_params);
        +	GOST_KEY_PARAMS_free(gkp);
        +	EVP_PKEY_set_type(pkey,pkey_nid);
        +	switch (pkey_nid) 
        +		{
        +		case NID_id_GostR3410_94:
        +		{
        +		DSA *dsa= EVP_PKEY_get0(pkey);
        +		if (!dsa) 
        +			{
        +			dsa = DSA_new();
        +			if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0;
        +			}
        +		if (!fill_GOST94_params(dsa,param_nid)) return 0;
        +		break;
        +		}
        +		case NID_id_GostR3410_2001:
        +		{
        +		EC_KEY *ec = EVP_PKEY_get0(pkey);
        +		if (!ec) 
        +			{
        +			ec = EC_KEY_new();
        +			if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0;
        +			}
        +		if (!fill_GOST2001_params(ec,param_nid)) return 0;
        +		}
        +		}
        +
        +	return 1;
        +	}
        +
        +static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) 
        +	{
        +	switch (EVP_PKEY_base_id(pkey)) 
        +		{
        +		case NID_id_GostR3410_94:
        +		{
        +		DSA *dsa = EVP_PKEY_get0(pkey);
        +		if (!dsa) 
        +			{
        +			dsa = DSA_new();
        +			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
        +			}	
        +		dsa->priv_key = BN_dup(priv);
        +		if (!EVP_PKEY_missing_parameters(pkey)) 
        +			gost94_compute_public(dsa);
        +		break;
        +		}	
        +		case NID_id_GostR3410_2001:
        +		{
        +		EC_KEY *ec = EVP_PKEY_get0(pkey);
        +		if (!ec) 
        +			{
        +			ec = EC_KEY_new();
        +			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
        +			}	
        +		if (!EC_KEY_set_private_key(ec,priv)) return 0;
        +		if (!EVP_PKEY_missing_parameters(pkey)) 
        +			gost2001_compute_public(ec);
        +		break;
        +		}
        +		}
        +	return 1;		
        +	}
        +BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) 
        +	{
        +	switch (EVP_PKEY_base_id(pkey)) 
        +		{
        +		case NID_id_GostR3410_94:
        +		{
        +		DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
        +		if (!dsa) 
        +			{
        +			return NULL;
        +			}	
        +		if (!dsa->priv_key) return NULL;
        +		return dsa->priv_key;
        +		break;
        +		}	
        +		case NID_id_GostR3410_2001:
        +		{
        +		EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
        +		const BIGNUM* priv;
        +		if (!ec) 
        +			{
        +			return NULL;
        +			}	
        +		if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
        +		return (BIGNUM *)priv;
        +		break;
        +		}
        +		}
        +	return NULL;		
        +	}
        +
        +static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
        +	long arg1, void *arg2)
        +	{
        +	switch (op)
        +		{
        +		case ASN1_PKEY_CTRL_PKCS7_SIGN:
        +			if (arg1 == 0) 
        +				{
        +				X509_ALGOR *alg1 = NULL, *alg2 = NULL;
        +				int nid = EVP_PKEY_base_id(pkey);
        +				PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2, 
        +					NULL, &alg1, &alg2);
        +				X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
        +					V_ASN1_NULL, 0);
        +				if (nid == NID_undef) 
        +					{
        +					return (-1);
        +					}
        +				X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
        +				}
        +			return 1;
        +#ifndef OPENSSL_NO_CMS
        +		case ASN1_PKEY_CTRL_CMS_SIGN:
        +			if (arg1 == 0) 
        +				{
        +				X509_ALGOR *alg1 = NULL, *alg2 = NULL;
        +				int nid = EVP_PKEY_base_id(pkey);
        +				CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 
        +					NULL, NULL, &alg1, &alg2);
        +				X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
        +					V_ASN1_NULL, 0);
        +				if (nid == NID_undef) 
        +					{
        +					return (-1);
        +					}
        +				X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
        +				}
        +			return 1;
        +#endif
        +		case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
        +			if (arg1 == 0)
        +				{
        +				X509_ALGOR *alg;
        +				ASN1_STRING * params = encode_gost_algor_params(pkey);
        +				if (!params) 
        +					{
        +					return -1;
        +					}
        +				PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg);
        +				X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
        +					V_ASN1_SEQUENCE, params);
        +				}
        +			return 1;
        +#ifndef OPENSSL_NO_CMS
        +		case ASN1_PKEY_CTRL_CMS_ENVELOPE:
        +			if (arg1 == 0)
        +				{
        +				X509_ALGOR *alg;
        +				ASN1_STRING * params = encode_gost_algor_params(pkey);
        +				if (!params) 
        +					{
        +					return -1;
        +					}
        +				CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, NULL, &alg);
        +				X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
        +					V_ASN1_SEQUENCE, params);
        +				}
        +			return 1;
        +#endif
        +		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        +			*(int *)arg2 = NID_id_GostR3411_94;
        +			return 2;
        +		}
        +	
        +	return -2;
        +	}
        +/*----------------------- free functions * ------------------------------*/
        +static void pkey_free_gost94(EVP_PKEY *key) 
        +	{
        +	if (key->pkey.dsa) 
        +		{
        +		DSA_free(key->pkey.dsa);
        +		}
        +	}
        +
        +static void pkey_free_gost01(EVP_PKEY *key) 
        +	{
        +	if (key->pkey.ec) 
        +		{
        +		EC_KEY_free(key->pkey.ec);
        +		}
        +	}	
        +
        +/* ------------------ private key functions  -----------------------------*/
        +static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 
        +	{
        +	const unsigned char *pkey_buf = NULL,*p=NULL;
        +	int priv_len = 0;
        +	BIGNUM *pk_num=NULL;
        +	int ret =0;
        +	X509_ALGOR *palg =NULL;
        +	ASN1_OBJECT *palg_obj = NULL;
        +	ASN1_INTEGER *priv_key=NULL;
        +
        +	if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) 
        +		return 0;
        +	p = pkey_buf;
        +	if (!decode_gost_algor_params(pk,palg)) 
        +		{
        +		return 0;
        +		}
        +	if (V_ASN1_OCTET_STRING == *p) 
        +		{
        +		/* New format - Little endian octet string */
        +		unsigned char rev_buf[32];
        +		int i;
        +		ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len);
        +		if (!s||s->length !=32) 
        +			{
        +			GOSTerr(GOST_F_PRIV_DECODE_GOST,
        +				EVP_R_DECODE_ERROR);
        +			return 0;	
        +			}
        +		for (i=0;i<32;i++)
        +			{
        +			rev_buf[31-i]=s->data[i];
        +			}
        +		ASN1_STRING_free(s);
        +		pk_num = getbnfrombuf(rev_buf,32);
        +		} 
        +	else
        +		{
        +		priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
        +		if (!priv_key) return 0;
        +		ret= ((pk_num =  ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ;
        +		ASN1_INTEGER_free(priv_key);
        +		if (!ret)
        +			{
        +			GOSTerr(GOST_F_PRIV_DECODE_GOST,
        +				EVP_R_DECODE_ERROR);
        +			return 0;	
        +			}
        +		}
        +
        +	ret= gost_set_priv_key(pk,pk_num);
        +	BN_free(pk_num);
        +	return ret;
        +	}
        +
        +/* ----------------------------------------------------------------------*/
        +static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
        +	{
        +	ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
        +	ASN1_STRING *params = encode_gost_algor_params(pk);
        +	unsigned char *priv_buf = NULL;
        +	int priv_len;
        +
        +	ASN1_INTEGER *asn1key=NULL;
        +	if (!params) 
        +		{
        +		return 0;
        +		}
        +	asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL);
        +	priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf);
        +	ASN1_INTEGER_free(asn1key);
        +	return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
        +		priv_buf,priv_len);
        +	}
        +/* --------- printing keys --------------------------------*/
        +static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx, int type) 
        +	{
        +	int param_nid = NID_undef;
        +
        +	if (type == 2) 
        +		{
        +		BIGNUM *key;
        +
        +		if (!BIO_indent(out,indent,128)) return 0;
        +		BIO_printf(out,"Private key: ");
        +		key = gost_get0_priv_key(pkey);
        +		if (!key) 
        +			BIO_printf(out,"<undefined>");
        +		else 
        +			BN_print(out,key);
        +		BIO_printf(out,"\n");
        +		}
        +	if (type >= 1)
        +		{
        +		BIGNUM *pubkey;
        +		
        +		pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
        +		BIO_indent(out,indent,128);
        +		BIO_printf(out,"Public key: ");
        +		BN_print(out,pubkey);
        +		BIO_printf(out,"\n");
        +	}	
        +
        +	param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
        +	BIO_indent(out,indent,128);
        +	BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid));
        +	return 1;
        +}
        +
        +static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx) 
        +	{
        +	return print_gost_94(out, pkey, indent, pctx,0);
        +	}
        +
        +static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx)
        +	{
        +	return print_gost_94(out,pkey, indent, pctx,1);
        +	}
        +static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx) 
        +	{
        +	return print_gost_94(out,pkey,indent,pctx,2);
        +	}
        +
        +static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx, int type)
        +	{
        +	int param_nid = NID_undef;
        +	if (type == 2) 
        +		{
        +		BIGNUM *key;
        +
        +		if (!BIO_indent(out,indent,128)) return 0;
        +		BIO_printf(out,"Private key: ");
        +		key = gost_get0_priv_key(pkey);
        +		if (!key) 
        +			BIO_printf(out,"<undefined)");
        +		else 
        +			BN_print(out,key);
        +		BIO_printf(out,"\n");
        +		}
        +	if (type >= 1) 
        +		{
        +		BN_CTX *ctx = BN_CTX_new();
        +		BIGNUM *X,*Y;
        +		const EC_POINT *pubkey;
        +		const EC_GROUP *group;
        +
        +		if (!ctx) 
        +			{
        +			GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +		BN_CTX_start(ctx);
        +		X = BN_CTX_get(ctx);
        +		Y = BN_CTX_get(ctx);
        +		pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
        +		group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
        +		if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) 
        +			{
        +			GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB);
        +			BN_CTX_free(ctx);
        +			return 0;
        +			}
        +		if (!BIO_indent(out,indent,128)) return 0;
        +		BIO_printf(out,"Public key:\n");
        +		if (!BIO_indent(out,indent+3,128)) return 0;
        +		BIO_printf(out,"X:");
        +		BN_print(out,X);
        +		BIO_printf(out,"\n");
        +		BIO_indent(out,indent+3,128);
        +		BIO_printf(out,"Y:");
        +		BN_print(out,Y);
        +		BIO_printf(out,"\n");
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +
        +	param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
        +	if (!BIO_indent(out,indent,128)) return 0;
        +	BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid));
        +	return 1;
        +}
        +static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx) 
        +	{	
        +	return print_gost_01(out,pkey,indent,pctx,0);
        +	}
        +static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx)
        +	{
        +	return print_gost_01(out,pkey, indent, pctx,1);
        +	}
        +static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent,
        +	ASN1_PCTX *pctx) 
        +	{
        +	return print_gost_01(out,pkey,indent,pctx,2);
        +	}
        +/* ---------------------------------------------------------------------*/
        +static int param_missing_gost94(const EVP_PKEY *pk) 
        +	{
        +	const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
        +	if (!dsa) return 1;
        +	if (!dsa->q) return 1;
        +	return 0;
        +	}
        +
        +static int param_missing_gost01(const EVP_PKEY *pk) 
        +	{
        +	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
        +	if (!ec) return 1;
        +	if (!EC_KEY_get0_group(ec)) return 1;
        +	return 0;
        +	}
        +
        +static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 
        +	{
        +	const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
        +	DSA *dto = EVP_PKEY_get0(to);
        +	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
        +		{
        +		GOSTerr(GOST_F_PARAM_COPY_GOST94,
        +			GOST_R_INCOMPATIBLE_ALGORITHMS);
        +		return 0;
        +		}	
        +	if (!dfrom) 
        +		{
        +		GOSTerr(GOST_F_PARAM_COPY_GOST94,
        +			GOST_R_KEY_PARAMETERS_MISSING);
        +		return 0;
        +		}	
        +	if (!dto) 
        +		{
        +		dto = DSA_new();
        +		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),dto);
        +		}	
        +#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);	
        +	COPYBIGNUM(dto,dfrom,p)
        +		COPYBIGNUM(dto,dfrom,q)
        +		COPYBIGNUM(dto,dfrom,g)
        +
        +		if (dto->priv_key) 
        +			gost94_compute_public(dto);
        +	return 1;	
        +	}
        +static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 
        +	{
        +	EC_KEY *eto = EVP_PKEY_get0(to);
        +	const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
        +	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
        +		{
        +		GOSTerr(GOST_F_PARAM_COPY_GOST01,
        +			GOST_R_INCOMPATIBLE_ALGORITHMS);
        +		return 0;
        +		}	
        +	if (!efrom) 
        +		{
        +		GOSTerr(GOST_F_PARAM_COPY_GOST01,
        +			GOST_R_KEY_PARAMETERS_MISSING);
        +		return 0;
        +		}	
        +	if (!eto) 
        +		{
        +		eto = EC_KEY_new();
        +		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
        +		}	
        +	EC_KEY_set_group(eto,EC_KEY_get0_group(efrom));
        +	if (EC_KEY_get0_private_key(eto)) 
        +		{
        +		gost2001_compute_public(eto);
        +		}
        +	return 1;
        +	}
        +
        +static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 
        +	{
        +	const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
        +	const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
        +	if (!BN_cmp(da->q,db->q)) return 1;
        +	return 0;
        +	}
        +
        +static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 
        +	{
        +	if (EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a)))==
        +		EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b)))) 
        +		{
        +		return 1;
        +		}
        +	return 0;
        +
        +	}
        +
        +/* ---------- Public key functions * --------------------------------------*/
        +static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
        +	{
        +	X509_ALGOR *palg = NULL;
        +	const unsigned char *pubkey_buf = NULL;
        +	unsigned char *databuf;
        +	ASN1_OBJECT *palgobj = NULL;
        +	int pub_len,i,j;
        +	DSA *dsa;
        +	ASN1_OCTET_STRING *octet= NULL;
        +
        +	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
        +			&palg, pub)) return 0;
        +	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
        +	if (!decode_gost_algor_params(pk,palg)) return 0;
        +	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
        +	if (!octet) 
        +		{
        +		GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}	
        +	databuf = OPENSSL_malloc(octet->length);
        +	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
        +		{
        +		databuf[j]=octet->data[i];
        +		}	
        +	dsa = EVP_PKEY_get0(pk);
        +	dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL);
        +	ASN1_OCTET_STRING_free(octet);
        +	OPENSSL_free(databuf);
        +	return 1;
        +
        +	}
        +
        +static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
        +	{
        +	ASN1_OBJECT *algobj = NULL;
        +	ASN1_OCTET_STRING *octet = NULL;
        +	void *pval = NULL;
        +	unsigned char *buf=NULL,*databuf,*sptr;
        +	int i,j,data_len,ret=0;
        +
        +	int ptype = V_ASN1_UNDEF;
        +	DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
        +	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
        +	if (pk->save_parameters) 
        +		{
        +		ASN1_STRING *params = encode_gost_algor_params(pk);
        +		pval = params;
        +		ptype = V_ASN1_SEQUENCE;
        +		}	
        +	data_len = BN_num_bytes(dsa->pub_key);
        +	databuf = OPENSSL_malloc(data_len);
        +	BN_bn2bin(dsa->pub_key,databuf);
        +	octet = ASN1_OCTET_STRING_new();
        +	ASN1_STRING_set(octet,NULL,data_len);
        +	sptr = ASN1_STRING_data(octet);
        +	for (i=0,j=data_len-1; i< data_len;i++,j--)
        +		{
        +		sptr[i]=databuf[j];
        +		}
        +	OPENSSL_free(databuf);
        +	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
        +	ASN1_BIT_STRING_free(octet);
        +	if (ret <0)  return 0;
        +	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
        +	}
        +
        +static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
        +	{
        +	X509_ALGOR *palg = NULL;
        +	const unsigned char *pubkey_buf = NULL;
        +	unsigned char *databuf;
        +	ASN1_OBJECT *palgobj = NULL;
        +	int pub_len,i,j;
        +	EC_POINT *pub_key;
        +	BIGNUM *X,*Y;
        +	ASN1_OCTET_STRING *octet= NULL;
        +	int len;
        +	const EC_GROUP *group;
        +
        +	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
        +			&palg, pub)) return 0;
        +	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
        +	if (!decode_gost_algor_params(pk,palg)) return 0;
        +	group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
        +	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
        +	if (!octet) 
        +		{
        +		GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}	
        +	databuf = OPENSSL_malloc(octet->length);
        +	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
        +		{
        +		databuf[j]=octet->data[i];
        +		}
        +	len=octet->length/2;
        +	ASN1_OCTET_STRING_free(octet);	
        +	
        +	Y= getbnfrombuf(databuf,len);
        +	X= getbnfrombuf(databuf+len,len);
        +	OPENSSL_free(databuf);
        +	pub_key = EC_POINT_new(group);
        +	if (!EC_POINT_set_affine_coordinates_GFp(group
        +			,pub_key,X,Y,NULL))
        +		{
        +		GOSTerr(GOST_F_PUB_DECODE_GOST01,
        +			ERR_R_EC_LIB);
        +		EC_POINT_free(pub_key);
        +		BN_free(X);
        +		BN_free(Y);
        +		return 0;
        +		}	
        +	BN_free(X);
        +	BN_free(Y);
        +	if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key))
        +		{
        +		GOSTerr(GOST_F_PUB_DECODE_GOST01,
        +			ERR_R_EC_LIB);
        +		EC_POINT_free(pub_key);
        +		return 0;
        +		}	
        +	EC_POINT_free(pub_key);
        +	return 1;
        +
        +	}
        +
        +static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
        +	{
        +	ASN1_OBJECT *algobj = NULL;
        +	ASN1_OCTET_STRING *octet = NULL;
        +	void *pval = NULL;
        +	unsigned char *buf=NULL,*databuf,*sptr;
        +	int i,j,data_len,ret=0;
        +	const EC_POINT *pub_key;
        +	BIGNUM *X,*Y,*order;
        +	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
        +	int ptype = V_ASN1_UNDEF;
        +
        +	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
        +	if (pk->save_parameters) 
        +		{
        +		ASN1_STRING *params = encode_gost_algor_params(pk);
        +		pval = params;
        +		ptype = V_ASN1_SEQUENCE;
        +		}
        +	order = BN_new();
        +	EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
        +	pub_key=EC_KEY_get0_public_key(ec);
        +	if (!pub_key) 
        +		{
        +		GOSTerr(GOST_F_PUB_ENCODE_GOST01,
        +			GOST_R_PUBLIC_KEY_UNDEFINED);
        +		return 0;
        +		}	
        +	X=BN_new();
        +	Y=BN_new();
        +	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
        +		pub_key,X,Y,NULL);
        +	data_len = 2*BN_num_bytes(order);
        +	BN_free(order);
        +	databuf = OPENSSL_malloc(data_len);
        +	memset(databuf,0,data_len);
        +	
        +	store_bignum(X,databuf+data_len/2,data_len/2);
        +	store_bignum(Y,databuf,data_len/2);
        +
        +	BN_free(X);
        +	BN_free(Y);
        +	octet = ASN1_OCTET_STRING_new();
        +	ASN1_STRING_set(octet,NULL,data_len);
        +	sptr=ASN1_STRING_data(octet);
        +    for (i=0,j=data_len-1;i<data_len;i++,j--) 
        +		{
        +        sptr[i]=databuf[j];
        +		}
        +    OPENSSL_free(databuf);
        +	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
        +	ASN1_BIT_STRING_free(octet);
        +	if (ret <0)  return 0;
        +	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
        +	}
        +
        +static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
        +	{
        +	const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
        +	const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
        +	if (da && db && da->pub_key && db->pub_key
        +		&& !BN_cmp(da->pub_key,db->pub_key)) 
        +		{
        +		return 1;
        +		}		
        +	return 0;
        +	}
        +
        +static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b)
        +	{
        +	const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
        +	const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
        +	const EC_POINT *ka,*kb;
        +	int ret=0;
        +	if (!ea || !eb) return 0;
        +	ka = EC_KEY_get0_public_key(ea);
        +	kb = EC_KEY_get0_public_key(eb);
        +	if (!ka || !kb) return 0;
        +	ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ;
        +	return ret;
        +	}
        +
        +
        +
        +
        +static int pkey_size_gost(const EVP_PKEY *pk)
        +	{
        +	return 64;
        +	}
        +
        +static int pkey_bits_gost(const EVP_PKEY *pk)
        +	{
        +	return 256;
        +	}
        +/*------------------------ ASN1 METHOD for GOST MAC  -------------------*/
        +static void  mackey_free_gost(EVP_PKEY *pk)
        +	{
        +		if (pk->pkey.ptr) {
        +			OPENSSL_free(pk->pkey.ptr);
        +		}	
        +	}
        +static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        +{
        +	switch (op)
        +		{
        +		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        +			*(int *)arg2 = NID_id_Gost28147_89_MAC;
        +			return 2;
        +		}
        +	return -2;
        +}	
        +
        +static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 
        +{
        +   int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
        +   return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
        +}
        +static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 
        +{
        +   int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
        +   return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
        +}
        +
        +static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
        +{
        +	ASN1_OBJECT *obj=NULL;
        +	DSA *dsa = EVP_PKEY_get0(pkey);
        +	int nid;
        +	if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
        +		return 0;
        +	}
        +	nid = OBJ_obj2nid(obj);
        +	ASN1_OBJECT_free(obj);
        +	if (!dsa) 
        +		{
        +		dsa=DSA_new();
        +		if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0;
        +		}
        +	if (!fill_GOST94_params(dsa,nid)) return 0;
        +	return 1;
        +}	
        +
        +static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) {
        +	ASN1_OBJECT *obj=NULL;
        +	int nid;
        +	EC_KEY *ec = EVP_PKEY_get0(pkey);
        +	if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
        +		return 0;
        +	}
        +	nid = OBJ_obj2nid(obj);
        +	ASN1_OBJECT_free(obj);
        +	if (!ec) 
        +		{
        +		ec = EC_KEY_new();
        +		if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0;
        +		}	
        +	if (!fill_GOST2001_params(ec, nid)) return 0;
        +	return 1;
        +}	
        +
        +
        +
        +
        +
        +/* ----------------------------------------------------------------------*/
        +int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) 
        +	{
        +	*ameth =	EVP_PKEY_asn1_new(nid, 
        +		ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 
        +	if (!*ameth) return 0;
        +	switch (nid) 
        +		{
        +		case NID_id_GostR3410_94:
        +			EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
        +			EVP_PKEY_asn1_set_private (*ameth, 
        +				priv_decode_gost, priv_encode_gost, 
        +				priv_print_gost94);
        +
        +			EVP_PKEY_asn1_set_param (*ameth, 
        +				gost94_param_decode, gost94_param_encode,
        +				param_missing_gost94, param_copy_gost94, 
        +				param_cmp_gost94,param_print_gost94 );
        +			EVP_PKEY_asn1_set_public (*ameth,
        +				pub_decode_gost94, pub_encode_gost94,
        +				pub_cmp_gost94, pub_print_gost94,
        +				pkey_size_gost, pkey_bits_gost);
        +	
        +			EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
        +			break;
        +		case NID_id_GostR3410_2001:
        +			EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01);
        +			EVP_PKEY_asn1_set_private (*ameth, 
        +				priv_decode_gost, priv_encode_gost, 
        +				priv_print_gost01);
        +
        +			EVP_PKEY_asn1_set_param (*ameth, 
        +				gost2001_param_decode, gost2001_param_encode,
        +				param_missing_gost01, param_copy_gost01, 
        +				param_cmp_gost01, param_print_gost01);
        +			EVP_PKEY_asn1_set_public (*ameth,
        +				pub_decode_gost01, pub_encode_gost01,
        +				pub_cmp_gost01, pub_print_gost01,
        +				pkey_size_gost, pkey_bits_gost);
        +	
        +			EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
        +			break;
        +		case NID_id_Gost28147_89_MAC:
        +			EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
        +			EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost);	
        +			break;
        +		}		
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_asn1.c b/vendor/openssl/openssl/engines/ccgost/gost_asn1.c
        new file mode 100644
        index 000000000..318ecfce5
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_asn1.c
        @@ -0,0 +1,55 @@
        +/**********************************************************************
        + *                          gost_keytrans.c                           *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *   ASN1 structure definition for GOST key transport                 *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <stdio.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include "gost_lcl.h"
        +
        +ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
        +	ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
        +	ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0)
        +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
        +
        +ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = {
        +	ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(GOST_KEY_INFO, imit,          ASN1_OCTET_STRING)
        +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO)
        +
        +ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = {
        +	ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT),
        +	ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
        +	ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
        +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
        +
        +ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = {
        +	ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
        +	ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
        +	ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT),
        +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
        +
        +ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = {
        +	ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
        +	ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT),
        +} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
        +
        +ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /*FIXME incomplete*/
        +	ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
        +} ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
        +
        +IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_crypt.c b/vendor/openssl/openssl/engines/ccgost/gost_crypt.c
        new file mode 100644
        index 000000000..52aef15ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_crypt.c
        @@ -0,0 +1,634 @@
        +/**********************************************************************
        + *                          gost_crypt.c                              *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *       OpenSSL interface to GOST 28147-89 cipher functions          *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <string.h>
        +#include "gost89.h"
        +#include <openssl/rand.h>
        +#include "e_gost_err.h"
        +#include "gost_lcl.h"
        +
        +#if !defined(CCGOST_DEBUG) && !defined(DEBUG)
        +# ifndef NDEBUG
        +#  define NDEBUG
        +# endif
        +#endif
        +#include <assert.h>
        +
        +static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 
        +	const unsigned char *iv, int enc);
        +static int	gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc);
        +/* Handles block of data in CFB mode */			
        +static int	gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, size_t inl);
        +/* Handles block of data in CNT mode */			
        +static int	gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, size_t inl);
        +/* Cleanup function */			
        +static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
        +/* set/get cipher parameters */
        +static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
        +static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
        +/* Control function */
        +static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr);
        +
        +EVP_CIPHER cipher_gost = 
        +	{
        +	NID_id_Gost28147_89,
        +	1,/*block_size*/
        +	32,/*key_size*/
        +	8,/*iv_len */
        +	EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
        +	EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
        +	gost_cipher_init,
        +	gost_cipher_do_cfb,
        +	gost_cipher_cleanup,
        +	sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
        +	gost89_set_asn1_parameters,
        +	gost89_get_asn1_parameters,
        +	gost_cipher_ctl,
        +	NULL,
        +	};
        +
        +EVP_CIPHER cipher_gost_cpacnt = 
        +	{
        +	NID_gost89_cnt,
        +	1,/*block_size*/
        +	32,/*key_size*/
        +	8,/*iv_len */
        +	EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
        +	EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
        +	gost_cipher_init_cpa,
        +	gost_cipher_do_cnt,
        +	gost_cipher_cleanup,
        +	sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
        +	gost89_set_asn1_parameters,
        +	gost89_get_asn1_parameters,
        +	gost_cipher_ctl,
        +	NULL,
        +	};
        +
        +/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
        +/* Init functions which set specific parameters */
        +static int gost_imit_init_cpa(EVP_MD_CTX *ctx);
        +/* process block of data */
        +static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count);
        +/* Return computed value */
        +static int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md);
        +/* Copies context */
        +static int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
        +static int gost_imit_cleanup(EVP_MD_CTX *ctx);
        +/* Control function, knows how to set MAC key.*/
        +static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr);
        +
        +EVP_MD imit_gost_cpa =
        +	{
        +	NID_id_Gost28147_89_MAC,
        +	NID_undef,
        +	4,
        +	0,
        +	gost_imit_init_cpa,
        +	gost_imit_update,
        +	gost_imit_final,
        +	gost_imit_copy,
        +	gost_imit_cleanup,
        +	NULL,
        +	NULL,
        +	{0,0,0,0,0},
        +	8,
        +	sizeof(struct ossl_gost_imit_ctx), 
        +	gost_imit_ctrl
        +	};
        +
        +/* 
        + * Correspondence between gost parameter OIDs and substitution blocks
        + * NID field is filed by register_gost_NID function in engine.c
        + * upon engine initialization
        + */
        +
        +struct gost_cipher_info gost_cipher_list[]=
        +	{
        +/* NID */  /* Subst block */          /* Key meshing*/
        +/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
        +	{NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
        +	{NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
        +	{NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
        +	{NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
        +	{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
        +	{NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,1},
        +	{NID_undef,NULL,0}
        +	};	
        +
        +/*  get encryption parameters from crypto network settings
        +	FIXME For now we use environment var CRYPT_PARAMS as place to 
        +	store these settings. Actually, it is better to use engine control   command, read from configuration file to set them */
        +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
        +	{
        +	int nid;
        +	struct gost_cipher_info *param;
        +	if (!obj)
        +		{
        +		const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
        +		if (!params || !strlen(params)) 
        +			return &gost_cipher_list[1];
        +
        +		nid = OBJ_txt2nid(params);
        +		if (nid == NID_undef)
        +			{
        +			GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
        +				GOST_R_INVALID_CIPHER_PARAM_OID);
        +			return NULL;
        +			}	
        +		}
        +	else
        +		{
        +		nid= OBJ_obj2nid(obj);
        +		}
        +	for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; 
        +		 param++);
        +	if (!param->sblock)
        +		{
        +		GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
        +		return NULL;
        +		}	
        +	return param;
        +	}
        +
        +/* Sets cipher param from paramset NID. */
        +static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid)
        +	{
        +	const struct gost_cipher_info *param;
        +	param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
        +	if (!param) return 0;
        +	
        +	c->paramNID = param->nid;
        +	c->key_meshing=param->key_meshing;
        +	c->count=0;
        +	gost_init(&(c->cctx), param->sblock);
        +	return 1;
        +	}
        +
        +/* Initializes EVP_CIPHER_CTX by paramset NID */
        +static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc, int paramNID,int mode)
        +	{
        +	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
        +	if (ctx->app_data == NULL)
        +		{
        +		if (!gost_cipher_set_param(c,paramNID)) return 0;
        +		ctx->app_data = ctx->cipher_data;
        +		}
        +	if (key) gost_key(&(c->cctx),key);
        +	if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
        +	memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
        +	return 1;
        +	}	
        +
        +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc)
        +	{
        +	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
        +	gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
        +	c->key_meshing=1;
        +	c->count=0;
        +	if(key) gost_key(&(c->cctx),key);
        +	if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
        +	memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
        +	return 1;
        +	}
        +
        +/* Initializes EVP_CIPHER_CTX with default values */
        +int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +	const unsigned char *iv, int enc)
        +	{
        +	return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
        +	}	
        +/* Wrapper around gostcrypt function from gost89.c which perform
        + * key meshing when nesseccary 
        + */
        +static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
        +	{
        +	struct ossl_gost_cipher_ctx *c = ctx;
        +	assert(c->count%8 == 0 && c->count <= 1024);
        +	if (c->key_meshing && c->count==1024)
        +		{
        +		cryptopro_key_meshing(&(c->cctx),iv);
        +		}	
        +	gostcrypt(&(c->cctx),iv,buf);
        +	c->count = c->count%1024 + 8;
        +	}
        +
        +static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
        +	{
        +	struct ossl_gost_cipher_ctx *c = ctx;
        +	word32 g,go;
        +	unsigned char buf1[8];
        +	assert(c->count%8 == 0 && c->count <= 1024);
        +	if (c->key_meshing && c->count==1024)
        +		{
        +		cryptopro_key_meshing(&(c->cctx),iv);
        +		}
        +	if (c->count==0)
        +		{
        +		gostcrypt(&(c->cctx),iv,buf1);
        +		}
        +	else
        +		{
        +		memcpy(buf1,iv,8);
        +		}	
        +	g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
        +	g += 0x01010101;
        +	buf1[0]=(unsigned char)(g&0xff);
        +	buf1[1]=(unsigned char)((g>>8)&0xff);
        +	buf1[2]=(unsigned char)((g>>16)&0xff);
        +	buf1[3]=(unsigned char)((g>>24)&0xff);
        +	g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|(buf1[7]<<24);
        +	go = g;
        +	g += 0x01010104;
        +	if (go > g)      /*  overflow*/
        +		g++;
        +	buf1[4]=(unsigned char)(g&0xff);
        +	buf1[5]=(unsigned char)((g>>8)&0xff);
        +	buf1[6]=(unsigned char)((g>>16)&0xff);
        +	buf1[7]=(unsigned char)((g>>24)&0xff);
        +	memcpy(iv,buf1,8);
        +	gostcrypt(&(c->cctx),buf1,buf);
        +	c->count = c->count%1024 + 8;
        +	}
        +
        +/* GOST encryption in CFB mode */
        +int	gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, size_t inl)
        +	{
        +	const unsigned char *in_ptr=in;
        +	unsigned char *out_ptr=out;
        +	size_t i=0;
        +	size_t j=0;
        +/* process partial block if any */
        +	if (ctx->num) 
        +		{
        +		for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
        +			{
        +			if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
        +			*out_ptr=ctx->buf[j]^(*in_ptr);
        +			if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
        +			}	
        +		if (j==8)
        +			{
        +			memcpy(ctx->iv,ctx->buf+8,8);
        +			ctx->num=0;
        +			}
        +		else
        +			{
        +			ctx->num=j;
        +			return 1;
        +			}	
        +		}	
        +
        +	for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
        +		{
        +		/*block cipher current iv */
        +		gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
        +		/*xor next block of input text with it and output it*/
        +		/*output this block */
        +		if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
        +		for (j=0;j<8;j++)
        +			{
        +			out_ptr[j]=ctx->buf[j]^in_ptr[j];
        +			}	
        +		/* Encrypt */
        +		/* Next iv is next block of cipher text*/
        +		if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
        +		}
        +/* Process rest of buffer */
        +	if (i<inl)
        +		{
        +		gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
        +		if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,inl-i);
        +		for (j=0;i<inl;j++,i++)
        +			{
        +			out_ptr[j]=ctx->buf[j]^in_ptr[j];
        +			}			
        +		ctx->num = j;
        +		if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
        +		}
        +	else
        +		{
        +		ctx->num = 0;
        +		}	
        +	return 1;
        +	}
        +
        +static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +	const unsigned char *in, size_t inl)
        +	{
        +	const unsigned char *in_ptr=in;
        +	unsigned char *out_ptr=out;
        +	size_t i=0;
        +	size_t j;
        +/* process partial block if any */
        +	if (ctx->num) 
        +		{
        +		for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
        +			{
        +			*out_ptr=ctx->buf[j]^(*in_ptr);
        +			}	
        +		if (j==8)
        +			{
        +			ctx->num=0;
        +			}
        +		else
        +			{
        +			ctx->num=j;
        +			return 1;
        +			}	
        +		}	
        +
        +	for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
        +		{
        +		/*block cipher current iv */
        +		/* Encrypt */
        +		gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
        +		/*xor next block of input text with it and output it*/
        +		/*output this block */
        +		for (j=0;j<8;j++)
        +			{
        +			out_ptr[j]=ctx->buf[j]^in_ptr[j];
        +			}	
        +		}
        +/* Process rest of buffer */
        +	if (i<inl)
        +		{
        +		gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
        +		for (j=0;i<inl;j++,i++)
        +			{
        +			out_ptr[j]=ctx->buf[j]^in_ptr[j];
        +			}			
        +		ctx->num = j;
        +		}
        +	else
        +		{
        +		ctx->num = 0;
        +		}	
        +	return 1;
        +	}
        +
        +/* Cleaning up of EVP_CIPHER_CTX */
        +int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) 
        +	{
        +	gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx);
        +	ctx->app_data = NULL;
        +	return 1;
        +	}	
        +
        +/* Control function for gost cipher */
        +int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
        +	{
        +	switch (type)
        +		{
        +		case EVP_CTRL_RAND_KEY:
        +		{
        +		if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
        +			{
        +			GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
        +			return -1;
        +			}
        +		break;
        +		}
        +		case EVP_CTRL_PBE_PRF_NID:
        +			if (ptr) {
        +				*((int *)ptr)=  NID_id_HMACGostR3411_94;
        +				return 1;
        +			} else {
        +				return 0;
        +			}	
        +				
        +		default:
        +			GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
        +			return -1;
        +		}
        +	return 1;
        +	}
        +
        +/* Set cipher parameters from ASN1 structure */
        +int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
        +	{
        +	int len=0;
        +	unsigned char *buf=NULL;
        +	unsigned char *p=NULL;
        +	struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
        +	GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
        +	ASN1_OCTET_STRING *os = NULL;
        +	if (!gcp)
        +		{
        +		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
        +		return 0;
        +		}
        +	if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
        +		{
        +		GOST_CIPHER_PARAMS_free(gcp);
        +		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
        +		return 0;
        +		}
        +	ASN1_OBJECT_free(gcp->enc_param_set);
        +	gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
        +
        +	len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
        +	p = buf = (unsigned char*)OPENSSL_malloc(len);
        +	if (!buf)
        +		{
        +		GOST_CIPHER_PARAMS_free(gcp);
        +		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
        +		return 0;
        +		}
        +	i2d_GOST_CIPHER_PARAMS(gcp, &p);
        +	GOST_CIPHER_PARAMS_free(gcp);
        +
        +	os = ASN1_OCTET_STRING_new();
        +
        +	if(!os || !ASN1_OCTET_STRING_set(os, buf, len))
        +		{
        +		OPENSSL_free(buf);
        +		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
        +		return 0;
        +		}
        +	OPENSSL_free(buf);
        +
        +	ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
        +	return 1;
        +	}
        +
        +/* Store parameters into ASN1 structure */
        +int  gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
        +	{
        +	int ret = -1;
        +	int len; 
        +	GOST_CIPHER_PARAMS *gcp = NULL;
        +	unsigned char *p;
        +	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
        +	if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
        +		{
        +		return ret;
        +		}
        +
        +	p = params->value.sequence->data;
        +
        +	gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
        +		params->value.sequence->length);
        +
        +	len = gcp->iv->length;
        +	if (len != ctx->cipher->iv_len)
        +		{
        +		GOST_CIPHER_PARAMS_free(gcp);
        +		GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
        +			GOST_R_INVALID_IV_LENGTH);
        +		return -1;
        +		}
        +	if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
        +		{
        +		GOST_CIPHER_PARAMS_free(gcp);
        +		return -1;
        +		}
        +	memcpy(ctx->oiv, gcp->iv->data, len);
        +
        +	GOST_CIPHER_PARAMS_free(gcp);
        +
        +	return 1;
        +	}
        +
        +
        +int gost_imit_init_cpa(EVP_MD_CTX *ctx)
        +	{
        +	struct ossl_gost_imit_ctx *c = ctx->md_data;
        +	memset(c->buffer,0,sizeof(c->buffer));
        +	memset(c->partial_block,0,sizeof(c->partial_block));
        +	c->count = 0;
        +	c->bytes_left=0;
        +	c->key_meshing=1;
        +	gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
        +	return 1;
        +	}
        +
        +static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data)
        +	{
        +	unsigned char buffer[8];
        +	/* We are using local buffer for iv because CryptoPro doesn't 
        +	 * interpret internal state of MAC algorithm as iv during keymeshing
        +	 * (but does initialize internal state from iv in key transport
        +	 */
        +	assert(c->count%8 == 0 && c->count <= 1024);
        +	if (c->key_meshing && c->count==1024)
        +		{
        +		cryptopro_key_meshing(&(c->cctx),buffer);
        +		}
        +	mac_block(&(c->cctx),c->buffer,data);
        +	c->count = c->count%1024 + 8;
        +	}
        +
        +int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
        +	{
        +	struct ossl_gost_imit_ctx *c = ctx->md_data;
        +	const unsigned char *p = data;
        +	size_t bytes = count,i;
        +	if (!(c->key_set)) {
        +		GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
        +		return 0;
        +	}
        +	if (c->bytes_left)
        +		{
        +		for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
        +			{
        +			c->partial_block[i]=*p;
        +			}
        +		if (i==8)
        +			{
        +			mac_block_mesh(c,c->partial_block);
        +			}
        +		else
        +			{
        +			c->bytes_left = i;
        +			return 1;
        +			}		
        +		}	
        +	while (bytes>8)
        +		{
        +		mac_block_mesh(c,p);
        +		p+=8;
        +		bytes-=8;
        +		}
        +	if (bytes>0)
        +		{
        +		memcpy(c->partial_block,p,bytes);
        +		}	
        +	c->bytes_left=bytes;
        +	return 1;
        +	}
        +
        +int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{
        +	struct ossl_gost_imit_ctx *c = ctx->md_data;
        +	if (!c->key_set) {
        +		GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
        +		return 0;
        +	}
        +	if (c->count==0 && c->bytes_left)
        +		{
        +		unsigned char buffer[8];
        +		memset(buffer, 0, 8);
        +		gost_imit_update(ctx, buffer, 8);
        +		}
        +	if (c->bytes_left)
        +		{
        +		int i;
        +		for (i=c->bytes_left;i<8;i++)
        +			{
        +			c->partial_block[i]=0;
        +			}
        +		mac_block_mesh(c,c->partial_block);
        +		}
        +	get_mac(c->buffer,32,md);
        +	return 1;
        +	}
        +
        +int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr)
        +	{
        +	switch (type)
        +		{
        +		case EVP_MD_CTRL_KEY_LEN:
        +			*((unsigned int*)(ptr)) = 32;
        +			return 1;
        +		case EVP_MD_CTRL_SET_KEY:
        +		{
        +		if (arg!=32) {
        +			GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
        +			return 0;
        +		}
        +
        +		gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr)	;
        +		((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
        +		return 1;
        +
        +		}
        +		default:
        +			return 0;
        +		}		
        +	}
        +
        +int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
        +	{
        +	memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
        +	return 1;
        +	}
        +
        +/* Clean up imit ctx */
        +int gost_imit_cleanup(EVP_MD_CTX *ctx)
        +	{
        +	memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_ctl.c b/vendor/openssl/openssl/engines/ccgost/gost_ctl.c
        new file mode 100644
        index 000000000..d3cd17181
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_ctl.c
        @@ -0,0 +1,89 @@
        +/**********************************************************************
        + *                        gost_ctl.c                                  *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *       This file is distributed under the same license as OpenSSL   *
        + *                                                                    *
        + *        Implementation of control commands for GOST engine          *
        + *            OpenSSL 0.9.9 libraries required                        *
        + **********************************************************************/            
        +#include <stdlib.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/engine.h>
        +#include <openssl/buffer.h>
        +#include "gost_lcl.h"
        +
        +static char *gost_params[GOST_PARAM_MAX+1]={NULL};
        +static const char *gost_envnames[]={"CRYPT_PARAMS"};
        +const ENGINE_CMD_DEFN gost_cmds[]=
        +	{
        +/*	{ GOST_CTRL_RNG,
        +	"RNG",
        +	"Type of random number generator to use",
        +	ENGINE_CMD_FLAG_STRING
        +	},
        +	{ GOST_CTRL_RNG_PARAMS,
        +	"RNG_PARAMS",
        +	"Parameter for random number generator",
        +	ENGINE_CMD_FLAG_STRING
        +	},
        +*/	  { GOST_CTRL_CRYPT_PARAMS,
        +		"CRYPT_PARAMS",
        +		"OID of default GOST 28147-89 parameters",
        +		ENGINE_CMD_FLAG_STRING
        +			},
        +{0,NULL,NULL,0}
        +	};
        +
        +void gost_param_free() 
        +{
        +	int i;
        +	for (i=0;i<=GOST_PARAM_MAX;i++) 
        +		if (gost_params[i]!=NULL) 
        +			{
        +			OPENSSL_free(gost_params[i]);
        +			gost_params[i]=NULL;
        +			}
        +		
        +}
        +
        +int gost_control_func(ENGINE *e,int cmd,long i, void *p, void (*f)(void))
        +	{
        +	int param = cmd-ENGINE_CMD_BASE;
        +	int ret=0;
        +	if (param <0 || param >GOST_PARAM_MAX) return -1;
        +	ret=gost_set_default_param(param,p);
        +	return ret;
        +	}
        +
        +const char *get_gost_engine_param(int param) 
        +	{
        +	char *tmp;
        +	if (param <0 || param >GOST_PARAM_MAX) return NULL;
        +	if (gost_params[param]!=NULL) 
        +		{
        +		return gost_params[param];
        +		}
        +	tmp = getenv(gost_envnames[param]);
        +	if (tmp) 
        +		{
        +		if (gost_params[param]) OPENSSL_free(gost_params[param]);
        +		gost_params[param] = BUF_strdup(tmp);
        +		return gost_params[param];
        +		}	
        +	return NULL;
        +	}	
        +
        +int gost_set_default_param(int param, const char *value) 
        +	{
        +	const char *tmp;
        +	if (param <0 || param >GOST_PARAM_MAX) return 0;
        +	tmp = getenv(gost_envnames[param]);
        +	/* if there is value in the environment, use it, else -passed string * */
        +	if (!tmp) tmp=value;
        +	if (gost_params[param]) OPENSSL_free(gost_params[param]);
        +	gost_params[param] = BUF_strdup(tmp);
        +
        +	return 1;
        +	}	
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_eng.c b/vendor/openssl/openssl/engines/ccgost/gost_eng.c
        new file mode 100644
        index 000000000..8f29bf6f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_eng.c
        @@ -0,0 +1,288 @@
        +/**********************************************************************
        + *                          gost_eng.c                                *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *              Main file of GOST engine                              *
        + *       for OpenSSL                                                  *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/evp.h>
        +#include <openssl/engine.h>
        +#include <openssl/obj_mac.h>
        +#include "e_gost_err.h"
        +#include "gost_lcl.h"
        +static const char *engine_gost_id = "gost";
        +static const char *engine_gost_name = "Reference implementation of GOST engine";
        +
        +/* Symmetric cipher and digest function registrar */
        +
        +static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        +	const int **nids, int nid);
        +
        +static int gost_digests(ENGINE *e, const EVP_MD **digest,
        +	const int **nids, int ind);
        +
        +static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
        +	const int **nids, int nid);
        +
        +static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
        +	const int **nids, int nid);
        +
        +static int gost_cipher_nids[] =
        +    {NID_id_Gost28147_89, NID_gost89_cnt,0};
        +
        +static int gost_digest_nids[] =
        +	{NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0};
        +
        +static int gost_pkey_meth_nids[] = 
        +	{NID_id_GostR3410_94,
        +	 NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0};
        +
        +static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
        +	 *pmeth_GostR3410_2001 = NULL,
        +	*pmeth_Gost28147_MAC = NULL;
        +
        +static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL,
        +	*ameth_GostR3410_2001 = NULL,
        +	*ameth_Gost28147_MAC = NULL;
        +
        +
        +static int gost_engine_init(ENGINE *e)
        +	{ 
        +	return 1;
        +	}
        +
        +static int gost_engine_finish(ENGINE *e)
        +	{ 
        +	return 1;
        +	}
        +
        +static int gost_engine_destroy(ENGINE *e)
        +	{ 
        +	gost_param_free();
        +
        +	pmeth_GostR3410_94 = NULL;
        +	pmeth_GostR3410_2001 = NULL;
        +	pmeth_Gost28147_MAC = NULL;
        +	ameth_GostR3410_94 = NULL;
        +	ameth_GostR3410_2001 = NULL;
        +	ameth_Gost28147_MAC = NULL;
        +	return 1;
        +	}
        +
        +static int bind_gost (ENGINE *e,const char *id) 
        +	{
        +	int ret = 0;
        +	if (id && strcmp(id, engine_gost_id)) return 0;
        +	if (ameth_GostR3410_94)
        +		{
        +		printf("GOST engine already loaded\n");
        +		goto end;
        +		}
        +
        +	if (!ENGINE_set_id(e, engine_gost_id)) 
        +		{
        +		printf("ENGINE_set_id failed\n"); 
        +		goto end;
        +		}	
        +	if (!ENGINE_set_name(e, engine_gost_name)) 
        +		{
        +		printf("ENGINE_set_name failed\n");
        +		goto end;
        +		}	
        +	if (!ENGINE_set_digests(e, gost_digests)) 
        +		{
        +		printf("ENGINE_set_digests failed\n");
        +		goto end;
        +		}	
        +	if (! ENGINE_set_ciphers(e, gost_ciphers)) 
        +		{
        +		printf("ENGINE_set_ciphers failed\n");
        +		goto end;
        +		}	
        +	if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) 
        +		{
        +		printf("ENGINE_set_pkey_meths failed\n");
        +		goto end;
        +		}	
        +	if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) 
        +		{
        +		printf("ENGINE_set_pkey_asn1_meths failed\n");
        +		goto end;
        +		}	
        +	/* Control function and commands */
        +	if (!ENGINE_set_cmd_defns(e,gost_cmds)) 
        +		{
        +		fprintf(stderr,"ENGINE_set_cmd_defns failed\n");
        +		goto end;
        +		}	
        +	if (!ENGINE_set_ctrl_function(e,gost_control_func)) 
        +		{
        +		fprintf(stderr,"ENGINE_set_ctrl_func failed\n");
        +		goto end;
        +		}	
        +	if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
        +		|| ! ENGINE_set_init_function(e,gost_engine_init)
        +		|| ! ENGINE_set_finish_function(e,gost_engine_finish))
        +		{
        +		goto end;
        +		}
        +
        +	if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end;
        +	if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end;
        +	if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
        +		"GOST-MAC", "GOST 28147-89 MAC")) goto end;
        +
        +	if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
        +	if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end;
        +	if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
        +		goto end;
        +	if ( ! ENGINE_register_ciphers(e)
        +		|| ! ENGINE_register_digests(e)
        +		|| ! ENGINE_register_pkey_meths(e)
        +		/* These two actually should go in LIST_ADD command */
        +		|| ! EVP_add_cipher(&cipher_gost)
        +		|| ! EVP_add_cipher(&cipher_gost_cpacnt)
        +		|| ! EVP_add_digest(&digest_gost)
        +		|| ! EVP_add_digest(&imit_gost_cpa)
        +		)
        +		{
        +		goto end;
        +		}
        +
        +	ERR_load_GOST_strings();
        +	ret = 1;
        +	end:
        +	return ret;
        +	}	
        +
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +#endif  /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +static int gost_digests(ENGINE *e, const EVP_MD **digest,
        +	const int **nids, int nid)
        +	{ 
        +	int ok =1 ;
        +	if (!digest) 
        +		{
        +		*nids = gost_digest_nids;
        +		return 2; 
        +		}
        +	/*printf("Digest no %d requested\n",nid);*/
        +	if(nid == NID_id_GostR3411_94) 
        +		{
        +		*digest = &digest_gost;
        +		}
        +	else if (nid == NID_id_Gost28147_89_MAC) 
        +		{
        +		*digest = &imit_gost_cpa;
        +		}
        +	else
        +		{
        +		ok =0;
        +		*digest = NULL;
        +		}
        +	return ok;
        +	}	
        +	
        +static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
        +	const int **nids, int nid) 
        +	{
        +	int ok = 1;
        +	if (!cipher) 
        +		{
        +		*nids = gost_cipher_nids;
        +		return 2; /* two ciphers are supported */
        +		}
        +
        +	if(nid == NID_id_Gost28147_89) 
        +		{
        +		*cipher = &cipher_gost;
        +		}
        +	else if  (nid == NID_gost89_cnt) 
        +		{
        +		*cipher = &cipher_gost_cpacnt;
        +		}
        +	else	
        +		{
        +		ok = 0;
        +		*cipher = NULL;
        +		}
        +	return ok;
        +	}	
        +
        +static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
        +	const int **nids, int nid)
        +	{
        +	if (!pmeth) 
        +		{
        +		*nids = gost_pkey_meth_nids;
        +		return 3;
        +		}
        +
        +	switch (nid) 
        +		{
        +		case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
        +		case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1;
        +		case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1;
        +		default:;
        +		}
        +	
        +	*pmeth = NULL;
        +	return 0;
        +	}
        +
        +static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
        +	const int **nids, int nid)
        +	{
        +	if (!ameth) 
        +		{
        +		*nids = gost_pkey_meth_nids;
        +		return 3;
        +		}
        +	switch (nid) 
        +		{
        +		case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
        +		case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1;
        +		case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1;
        +	
        +		default:;
        +		}
        +	
        +	*ameth = NULL;
        +	return 0;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_gost(void)
        +	{	
        +	ENGINE *ret = ENGINE_new();
        +	if (!ret)
        +		return NULL;
        +	if (!bind_gost(ret,engine_gost_id)) 
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +	
        +void ENGINE_load_gost(void)
        +	{
        +	ENGINE *toadd;
        +	if (pmeth_GostR3410_94)
        +		return;
        +	toadd = engine_gost();
        +	if (!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif	
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_keywrap.c b/vendor/openssl/openssl/engines/ccgost/gost_keywrap.c
        new file mode 100644
        index 000000000..c618f6da2
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_keywrap.c
        @@ -0,0 +1,109 @@
        +/**********************************************************************
        + *                          keywrap.c                                 *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + * Implementation of CryptoPro key wrap algorithm, as defined in      *
        + *               RFC 4357 p 6.3 and 6.4                               *
        + *                  Doesn't need OpenSSL                              *
        + **********************************************************************/
        +#include <string.h>
        +#include "gost89.h"
        +#include "gost_keywrap.h"
        +
        +/* Diversifies key using random UserKey Material
        + * Implements RFC 4357 p 6.5 key diversification algorithm 
        + * 
        + * inputKey - 32byte key to be diversified
        + * ukm - 8byte user key material
        + * outputKey - 32byte buffer to store diversified key 
        + *
        + */
        +void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
        +	{
        +
        +	u4 k,s1,s2;
        +	int i,j,mask;
        +	unsigned char S[8];
        +	memcpy(outputKey,inputKey,32);
        +	for (i=0;i<8;i++) 
        +		{
        +		/* Make array of integers from key */
        +		/* Compute IV S*/
        +		s1=0,s2=0;
        +		for (j=0,mask=1;j<8;j++,mask<<=1) 
        +			{
        +			k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
        +				(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
        +			if (mask & ukm[i]) 
        +				{
        +				s1+=k;
        +				}
        +			else 
        +				{
        +				s2+=k;
        +				}
        +			}
        +		S[0]=(unsigned char)(s1&0xff);
        +		S[1]=(unsigned char)((s1>>8)&0xff);
        +		S[2]=(unsigned char)((s1>>16)&0xff);
        +		S[3]=(unsigned char)((s1>>24)&0xff); 
        +		S[4]=(unsigned char)(s2&0xff);
        +		S[5]=(unsigned char)((s2>>8)&0xff);
        +		S[6]=(unsigned char)((s2>>16)&0xff);
        +		S[7]=(unsigned char)((s2>>24)&0xff); 
        +		gost_key(ctx,outputKey);
        +		gost_enc_cfb(ctx,S,outputKey,outputKey,4);
        +		}
        +	}	
        +	
        +
        +/*
        + * Wraps key using RFC 4357 6.3
        + * ctx - gost encryption context, initialized with some S-boxes 
        + * keyExchangeKey (KEK) 32-byte (256-bit) shared key
        + * ukm - 8 byte (64 bit) user key material, 
        + * sessionKey - 32-byte (256-bit) key to be wrapped
        + * wrappedKey - 44-byte buffer to store wrapped key
        + */ 
        +
        +int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
        +	const	unsigned char *sessionKey, unsigned char *wrappedKey) 
        +	{
        +	unsigned char kek_ukm[32];
        +	keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
        +	gost_key(ctx,kek_ukm);
        +	memcpy(wrappedKey,ukm,8);
        +	gost_enc(ctx,sessionKey,wrappedKey+8,4);
        +	gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
        +	return 1;
        +	}
        +/*
        + * Unwraps key using RFC 4357 6.4
        + * ctx - gost encryption context, initialized with some S-boxes 
        + * keyExchangeKey 32-byte shared key
        + * wrappedKey  44 byte key to be unwrapped (concatenation of 8-byte UKM,
        + * 32 byte  encrypted key and 4 byte MAC  
        + * 
        + * sessionKEy - 32byte buffer to store sessionKey in
        + * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
        + */ 
        +
        +int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
        +	const unsigned char *wrappedKey, unsigned char *sessionKey) 
        +	{
        +	unsigned char kek_ukm[32],cek_mac[4];
        +	keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey 
        +		/* First 8 bytes of wrapped Key is ukm */
        +		,kek_ukm);
        +	gost_key(ctx,kek_ukm);
        +	gost_dec(ctx,wrappedKey+8,sessionKey,4);
        +	gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
        +	if (memcmp(cek_mac,wrappedKey+40,4)) 
        +		{
        +		return 0;
        +		}		
        +	return 1;		
        +	}	
        +
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_keywrap.h b/vendor/openssl/openssl/engines/ccgost/gost_keywrap.h
        new file mode 100644
        index 000000000..37c2a0f73
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_keywrap.h
        @@ -0,0 +1,56 @@
        +/**********************************************************************
        + *                         gost_keywrap.h                             *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *       This file is distributed under the same license as OpenSSL   *
        + *                                                                    *
        + * Implementation of CryptoPro key wrap algorithm, as defined in      *
        + * RFC 4357 p 6.3 and 6.4                                             *
        + * Doesn't need OpenSSL                                               *
        + **********************************************************************/
        +#ifndef GOST_KEYWRAP_H
        +#define GOST_KEYWRAP_H
        +#include <string.h>
        +#include "gost89.h"
        +/* Diversifies key using random UserKey Material
        + * Implements RFC 4357 p 6.5 key diversification algorithm 
        + * 
        + * inputKey - 32byte key to be diversified
        + * ukm - 8byte user key material
        + * outputKey - 32byte buffer to store diversified key 
        + *
        + */
        +void keyDiversifyCryptoPro(gost_ctx *ctx,
        +	const unsigned char *inputKey, 
        +	const unsigned char *ukm, 
        +	unsigned char *outputKey);
        +/*
        + * Wraps key using RFC 4357 6.3
        + * ctx - gost encryption context, initialized with some S-boxes 
        + * keyExchangeKey (KEK) 32-byte (256-bit) shared key
        + * ukm - 8 byte (64 bit) user key material, 
        + * sessionKey - 32-byte (256-bit) key to be wrapped
        + * wrappedKey - 44-byte buffer to store wrapped key
        + */ 
        +
        +int keyWrapCryptoPro(gost_ctx *ctx,
        +	const unsigned char *keyExchangeKey, 
        +	const unsigned char *ukm,
        +	const	unsigned char *sessionKey, 
        +	unsigned char *wrappedKey) ;
        +/*
        + * Unwraps key using RFC 4357 6.4
        + * ctx - gost encryption context, initialized with some S-boxes 
        + * keyExchangeKey 32-byte shared key
        + * wrappedKey  44 byte key to be unwrapped (concatenation of 8-byte UKM,
        + * 32 byte  encrypted key and 4 byte MAC  
        + * 
        + * sessionKEy - 32byte buffer to store sessionKey in
        + * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
        + */ 
        +
        +
        +int keyUnwrapCryptoPro(gost_ctx *ctx,
        +	const unsigned char *keyExchangeKey,
        +	const unsigned char *wrappedKey, 
        +	unsigned char *sessionKey) ;
        +#endif
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_lcl.h b/vendor/openssl/openssl/engines/ccgost/gost_lcl.h
        new file mode 100644
        index 000000000..00aa42cea
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_lcl.h
        @@ -0,0 +1,218 @@
        +#ifndef GOST_TOOLS_H
        +#define GOST_TOOLS_H
        +/**********************************************************************
        + *                        gost_lcl.h                                  *
        + *             Copyright (c) 2006 Cryptocom LTD                       *
        + *       This file is distributed under the same license as OpenSSL   *
        + *                                                                    *
        + *         Internal declarations  used in GOST engine                *
        + *         OpenSSL 0.9.9 libraries required to compile and use        *
        + *                              this code                             *
        + **********************************************************************/ 
        +#include <openssl/bn.h>
        +#include <openssl/evp.h>
        +#include <openssl/dsa.h>
        +#include <openssl/asn1t.h>
        +#include <openssl/x509.h>
        +#include <openssl/engine.h>
        +#include <openssl/ec.h>
        +#include "gost89.h"
        +#include "gosthash.h"
        +/* Control commands */
        +#define GOST_PARAM_CRYPT_PARAMS 0
        +#define GOST_PARAM_MAX 0
        +#define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS)
        +
        +	extern const ENGINE_CMD_DEFN gost_cmds[];
        +	int gost_control_func(ENGINE *e,int cmd, long i, void *p, void (*f)(void));
        +	const char *get_gost_engine_param(int param);	
        +	int gost_set_default_param(int param, const char *value); 
        +	void gost_param_free(void);
        +
        +/* method registration */
        +
        +	int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info);
        +	int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags);
        +
        +/* Gost-specific pmeth control-function parameters */
        +/* For GOST R34.10 parameters */
        +#define param_ctrl_string "paramset"
        +#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1)
        +/* For GOST 28147 MAC */
        +#define key_ctrl_string "key"
        +#define hexkey_ctrl_string "hexkey"
        +#define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3)
        +/* Pmeth internal representation */
        +	struct gost_pmeth_data {
        +   	    int sign_param_nid; /* Should be set whenever parameters are filled */
        +		EVP_MD *md;
        +		unsigned char *shared_ukm;
        +		int peer_key_used;
        +	};
        +
        +	struct gost_mac_pmeth_data {
        +		int key_set;
        +		EVP_MD *md;
        +		unsigned char key[32];
        +	}	;
        +/* GOST-specific ASN1 structures */
        +
        +
        +typedef struct {
        +	ASN1_OCTET_STRING *encrypted_key;
        +	ASN1_OCTET_STRING *imit;
        +} GOST_KEY_INFO;
        +
        +DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO)
        +
        +typedef struct {
        +	ASN1_OBJECT *cipher;
        +	X509_PUBKEY *ephem_key;
        +	ASN1_OCTET_STRING *eph_iv;
        +} GOST_KEY_AGREEMENT_INFO;
        +
        +DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
        +	
        +typedef struct {
        +	GOST_KEY_INFO *key_info;
        +	GOST_KEY_AGREEMENT_INFO *key_agreement_info;
        +} GOST_KEY_TRANSPORT;
        +
        +DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
        +
        +typedef struct { /* FIXME incomplete */
        +	GOST_KEY_TRANSPORT *gkt;
        +} GOST_CLIENT_KEY_EXCHANGE_PARAMS;
        +
        +/* Hacks to shorten symbols to 31 characters or less, or OpenVMS.
        +   This mimics what's done in symhacks.h, but since this is a very
        +   local header file, I prefered to put this hack directly here.
        +   -- Richard Levitte */
        +#ifdef OPENSSL_SYS_VMS
        +#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it
        +#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it	GOST_CLIENT_KEY_EXC_PARAMS_it
        +#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new
        +#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new	GOST_CLIENT_KEY_EXC_PARAMS_new
        +#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free
        +#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free	GOST_CLIENT_KEY_EXC_PARAMS_free
        +#undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS
        +#define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS	d2i_GOST_CLIENT_KEY_EXC_PARAMS
        +#undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS
        +#define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS	i2d_GOST_CLIENT_KEY_EXC_PARAMS
        +#endif /* End of hack */
        +DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
        +typedef struct {
        +	ASN1_OBJECT *key_params;
        +	ASN1_OBJECT *hash_params;
        +	ASN1_OBJECT *cipher_params;
        +} GOST_KEY_PARAMS;
        +
        +DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
        +
        +typedef struct {
        +	ASN1_OCTET_STRING *iv;
        +	ASN1_OBJECT *enc_param_set;
        +} GOST_CIPHER_PARAMS; 
        +
        +DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
        +/*============== Message digest  and cipher related structures  ==========*/
        +	 /* Structure used as EVP_MD_CTX-md_data. 
        +	  * It allows to avoid storing in the md-data pointers to
        +	  * dynamically allocated memory.
        +	  *
        +	  * I cannot invent better way to avoid memory leaks, because
        +	  * openssl insist on invoking Init on Final-ed digests, and there
        +	  * is no reliable way to find out whether pointer in the passed
        +	  * md_data is valid or not.
        +	  * */
        +struct ossl_gost_digest_ctx {
        +	gost_hash_ctx dctx;
        +	gost_ctx cctx;
        +};	
        +/* EVP_MD structure for GOST R 34.11 */
        +extern EVP_MD digest_gost;
        +/* EVP_MD structure for GOST 28147 in MAC mode */
        +extern EVP_MD imit_gost_cpa;
        +/* Cipher context used for EVP_CIPHER operation */
        +struct ossl_gost_cipher_ctx {
        +	int paramNID;
        +	unsigned int count;
        +	int key_meshing;
        +	gost_ctx cctx;
        +};	
        +/* Structure to map parameter NID to S-block */
        +struct gost_cipher_info {
        +	int nid;
        +	gost_subst_block *sblock;
        +	int key_meshing;
        +};
        +/* Context for MAC */
        +struct ossl_gost_imit_ctx {
        +	gost_ctx cctx;
        +	unsigned char buffer[8];
        +	unsigned char partial_block[8];
        +	unsigned int count;
        +	int key_meshing;
        +	int bytes_left;
        +	int key_set;
        +};	
        +/* Table which maps parameter NID to S-blocks */
        +extern struct gost_cipher_info gost_cipher_list[];
        +/* Find encryption params from ASN1_OBJECT */
        +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj);
        +/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */
        +extern EVP_CIPHER cipher_gost;
        +extern EVP_CIPHER cipher_gost_cpacnt;
        +#define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3)
        +#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4)
        +/* EVP_PKEY_METHOD key encryption callbacks */
        +/* From gost94_keyx.c */
        +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len );
        +
        +int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
        +/* From gost2001_keyx.c */
        +int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len );
        +
        +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
        +/* derive functions */
        +/* From gost2001_keyx.c */
        +int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
        +/* From gost94_keyx.c */
        +int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
        +/* Internal functions for signature algorithms */
        +int fill_GOST94_params(DSA *dsa,int nid);
        +int fill_GOST2001_params(EC_KEY *eckey, int nid);
        +int gost_sign_keygen(DSA *dsa) ;
        +int gost2001_keygen(EC_KEY *ec) ;
        +
        +DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa) ;
        +DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey);
        +
        +int gost_do_verify(const unsigned char *dgst, int dgst_len,
        +		DSA_SIG *sig, DSA *dsa) ;
        +int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
        +			DSA_SIG *sig, EC_KEY *ec);
        +int gost2001_compute_public(EC_KEY *ec) ;
        +int gost94_compute_public(DSA *dsa) ;
        +/*============== miscellaneous functions============================= */
        +/* from gost_sign.c */
        +/* Convert GOST R 34.11 hash sum to bignum according to standard */
        +BIGNUM *hashsum2bn(const unsigned char *dgst) ;
        +/* Store bignum in byte array of given length, prepending by zeros
        + * if nesseccary */
        +int store_bignum(BIGNUM *bn, unsigned char *buf,int len);
        +/* Read bignum, which can have few MSB all-zeros    from buffer*/ 
        +BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len);
        +/* Pack GOST R 34.10 signature according to CryptoPro rules */
        +int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen); 
        +/* Unpack GOST R 34.10 signature according to CryptoPro rules */
        +DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) ;
        +/* from ameth.c */
        +/* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001  keys*/
        +/* Returns pointer into EVP_PKEY structure */
        +BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) ;
        +/* Find NID by GOST 94 parameters */
        +int gost94_nid_by_params(DSA *p) ;
        +
        +
        +#endif
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_md.c b/vendor/openssl/openssl/engines/ccgost/gost_md.c
        new file mode 100644
        index 000000000..417e10887
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_md.c
        @@ -0,0 +1,75 @@
        +/**********************************************************************
        + *                          md_gost.c                                 *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *       OpenSSL interface to GOST R 34.11-94 hash functions          *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <string.h>
        +#include "gost_lcl.h"
        +#include "gosthash.h"
        +#include "e_gost_err.h"
        +
        +/* implementation of GOST 34.11 hash function See gost_md.c*/
        +static int gost_digest_init(EVP_MD_CTX *ctx);
        +static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count);
        +static int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md);
        +static int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
        +static int gost_digest_cleanup(EVP_MD_CTX *ctx);
        +
        +EVP_MD digest_gost=  
        +	{
        +	NID_id_GostR3411_94,
        +	NID_undef,
        +	32,
        +	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
        +	gost_digest_init,
        +	gost_digest_update,
        +	gost_digest_final,
        +	gost_digest_copy,
        +	gost_digest_cleanup,
        +	NULL,
        +	NULL,
        +	{NID_undef,NID_undef,0,0,0},
        +	32,
        +	sizeof(struct ossl_gost_digest_ctx ),
        +	NULL
        +	};
        +
        +int gost_digest_init(EVP_MD_CTX *ctx) 
        +	{
        +	struct ossl_gost_digest_ctx *c = ctx->md_data;
        +	memset(&(c->dctx),0,sizeof(gost_hash_ctx));
        +	gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
        +	c->dctx.cipher_ctx= &(c->cctx);
        +	return 1;
        +	}
        +
        +int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) 
        +	{
        +	return hash_block((gost_hash_ctx *)ctx->md_data,data,count);	
        +	}
        +
        +int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
        +	{
        +	return finish_hash((gost_hash_ctx *)ctx->md_data,md);
        +	
        +	}
        +
        +int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) 
        +	{
        +	struct ossl_gost_digest_ctx *md_ctx=to->md_data;
        +	if (to->md_data && from->md_data) {
        +		memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx));
        +		md_ctx->dctx.cipher_ctx=&(md_ctx->cctx);
        +	}
        +	return 1;
        +	}		
        +
        +int gost_digest_cleanup(EVP_MD_CTX *ctx) 
        +	{
        +	if (ctx->md_data)
        +	memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx));
        +	return 1;
        +	}	
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_params.c b/vendor/openssl/openssl/engines/ccgost/gost_params.c
        new file mode 100644
        index 000000000..40fc343af
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_params.c
        @@ -0,0 +1,198 @@
        +/**********************************************************************
        + *                        params.c                                    *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357    *
        + *         OpenSSL 0.9.9 libraries required to compile and use        *
        + *                              this code                             *
        + **********************************************************************/ 
        +#include "gost_params.h"
        +#include <openssl/objects.h>
        +/* Parameters of GOST 34.10 */
        +
        +R3410_params R3410_paramset[]={
        +/* Paramset A */
        +{NID_id_GostR3410_94_CryptoPro_A_ParamSet,
        +"100997906755055304772081815535925224869"
        +"8410825720534578748235158755771479905292727772441528526992987964833"
        +"5669968284202797289605274717317548059048560713474685214192868091256"
        +"1502802222185647539190902656116367847270145019066794290930185446216"
        +"3997308722217328898303231940973554032134009725883228768509467406639"
        +"62",
        +"127021248288932417465907042777176443525"
        +"7876535089165358128175072657050312609850984974231883334834011809259"
        +"9999512098893413065920561499672425412104927434935707492031276956145"
        +"1689224110579311248812610229678534638401693520013288995000362260684"
        +"2227508135323070045173416336850045410625869714168836867788425378203"
        +"83",
        +"683631961449557007844441656118272528951"
        +"02170888761442055095051287550314083023"},
        +{NID_id_GostR3410_94_CryptoPro_B_ParamSet,
        +"429418261486158041438734477379555023926"
        +"7234596860714306679811299408947123142002706038521669956384871995765"
        +"7284814898909770759462613437669456364882730370838934791080835932647"
        +"9767786019153434744009610342313166725786869204821949328786333602033"
        +"8479709268434224762105576023501613261478065276102850944540333865234"
        +"1",
        +"139454871199115825601409655107690713107"
        +"0417070599280317977580014543757653577229840941243685222882398330391"
        +"1468164807668823692122073732267216074074777170091113455043205380464"
        +"7694904686120113087816240740184800477047157336662926249423571248823"
        +"9685422217536601433914856808405203368594584948031873412885804895251"
        +"63",
        +"79885141663410976897627118935756323747307951916507639758300472692338873533959"
        +},
        +{NID_id_GostR3410_94_CryptoPro_C_ParamSet,
        +"816552717970881016017893191415300348226"
        +"2544051353358162468249467681876621283478212884286545844013955142622"
        +"2087723485023722868022275009502224827866201744494021697716482008353"
        +"6398202298024892620480898699335508064332313529725332208819456895108"
        +"5155178100221003459370588291073071186553005962149936840737128710832"
        +"3",
        +"110624679233511963040518952417017040248"
        +"5862954819831383774196396298584395948970608956170224210628525560327"
        +"8638246716655439297654402921844747893079518669992827880792192992701"
        +"1428546551433875806377110443534293554066712653034996277099320715774"
        +"3542287621283671843703709141350171945045805050291770503634517804938"
        +"01",
        +"113468861199819350564868233378875198043"
        +"267947776488510997961231672532899549103"
        +},
        +{NID_id_GostR3410_94_CryptoPro_D_ParamSet,
        +"756976611021707301782128757801610628085"
        +"5283803109571158829574281419208532589041660017017859858216341400371"
        +"4687551412794400562878935266630754392677014598582103365983119173924"
        +"4732511225464712252386803315902707727668715343476086350472025298282"
        +"7271461690125050616858238384366331089777463541013033926723743254833"
        +"7",
        +"905457649621929965904290958774625315611"
        +"3056083907389766971404812524422262512556054474620855996091570786713"
        +"5849550236741915584185990627801066465809510095784713989819413820871"
        +"5964648914493053407920737078890520482730623038837767710173664838239"
        +"8574828787891286471201460474326612697849693665518073864436497893214"
        +"9",
        +"108988435796353506912374591498972192620"
        +"190487557619582334771735390599299211593"
        +},
        +
        +{NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,
        +"1335318132727206734338595199483190012179423759678474868994823595993"
        +"6964252873471246159040332773182141032801252925387191478859899310331"
        +"0567744136196364803064721377826656898686468463277710150809401182608"
        +"7702016153249904683329312949209127762411378780302243557466062839716"
        +"59376426832674269780880061631528163475887",
        +"14201174159756348119636828602231808974327613839524373876287257344192"
        +"74593935127189736311660784676003608489466235676257952827747192122419"
        +"29071046134208380636394084512691828894000571524625445295769349356752"
        +"72895683154177544176313938445719175509684710784659566254794231229333"
        +"8483924514339614727760681880609734239",
        +"91771529896554605945588149018382750217296858393520724172743325725474"
        +"374979801"
        +},
        +{NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,
        +"8890864727828423151699995801875757891031463338652579140051973659"
        +"3048131440685857067369829407947744496306656291505503608252399443"
        +"7900272386749145996230867832228661977543992816745254823298629859"
        +"8753575466286051738837854736167685769017780335804511440773337196"
        +"2538423532919394477873664752824509986617878992443177",
        +"1028946126624994859676552074360530315217970499989304888248413244"
        +"8474923022758470167998871003604670704877377286176171227694098633"
        +"1539089568784129110109512690503345393869871295783467257264868341"
        +"7200196629860561193666752429682367397084815179752036423595736533"
        +"68957392061769855284593965042530895046088067160269433",
        +"9109671391802626916582318050603555673628769498182593088388796888"
        +"5281641595199"
        +},
        +{NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,
        +"4430618464297584182473135030809859326863990650118941756995270074"
        +"8609973181426950235239623239110557450826919295792878938752101867"
        +"7047181623251027516953100431855964837602657827828194249605561893"
        +"6965865325513137194483136247773653468410118796740709840825496997"
        +"9375560722345106704721086025979309968763193072908334",
        +"1246996366993477513607147265794064436203408861395055989217248455"
        +"7299870737698999651480662364723992859320868822848751165438350943"
        +"3276647222625940615560580450040947211826027729977563540237169063"
        +"0448079715771649447778447000597419032457722226253269698374446528"
        +"35352729304393746106576383349151001715930924115499549",
        +"6787876137336591234380295020065682527118129468050147943114675429"
        +"4748422492761"
        +},
        +
        +
        +{NID_undef,NULL, NULL, NULL}
        +};
        +	
        +R3410_2001_params R3410_2001_paramset[]={
        +	/* default_cc_sign01_param 1.2.643.2.9.1.8.1 */
        +	{NID_id_GostR3410_2001_ParamSet_cc,
        +	/* A */	
        +	"C0000000000000000000000000000000000000000000000000000000000003c4",
        +	/* B */
        +	"2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c",
        +	/* P */
        +	"C0000000000000000000000000000000000000000000000000000000000003C7",
        +	/* Q */
        +	"5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85",
        +	/* X */
        +	"2",
        +	/* Y */
        +	"a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"
        +	},
        +	/* 1.2.643.2.2.35.0 */
        +	{NID_id_GostR3410_2001_TestParamSet,
        +	"7",
        +	"5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E",
        +	"8000000000000000000000000000000000000000000000000000000000000431",
        +	"8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3",
        +	"2",
        +	"08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"
        +	},
        +	/*1.2.643.2.2.35.1*/
        +	{NID_id_GostR3410_2001_CryptoPro_A_ParamSet,
        +	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
        +	"a6",
        +	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
        +	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
        +	"1",
        +	"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
        +	},
        +	/*1.2.643.2.2.35.2*/
        +	{NID_id_GostR3410_2001_CryptoPro_B_ParamSet,	
        +	"8000000000000000000000000000000000000000000000000000000000000C96",
        +	"3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B",
        +	"8000000000000000000000000000000000000000000000000000000000000C99",
        +	"800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F",
        +	"1",	
        +	"3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"
        +	},
        +	/*1.2.643.2.2.35.3*/
        +	{NID_id_GostR3410_2001_CryptoPro_C_ParamSet,
        +	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
        +	"805a",
        +	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
        +	"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
        +	"0",
        +	"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
        +	},
        +	/*1.2.643.2.2.36.0*/
        +	{NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,
        +	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
        +	"a6",
        +	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
        +	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
        +	"1",
        +	"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
        +	},
        +	/*1.2.643.2.2.36.1*/
        +	{NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,
        +	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
        +	"805a",
        +	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
        +	"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
        +	"0",
        +	"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
        +	},
        +	{ 0,NULL,NULL,NULL,NULL,NULL,NULL
        +	}
        +};
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_params.h b/vendor/openssl/openssl/engines/ccgost/gost_params.h
        new file mode 100644
        index 000000000..4c3f5567d
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_params.h
        @@ -0,0 +1,34 @@
        +/**********************************************************************
        + *                        gost_params.h                               *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *       This file is distributed under the same license as OpenSSL   *
        + *                                                                    *
        + *       Declaration of structures used to represent  GOST R 34.10    *
        + * 	               parameter sets, defined in RFC 4357                *
        + *         OpenSSL 0.9.9 libraries required to compile and use        *
        + *                              this code                             *
        + **********************************************************************/ 
        +#ifndef GOST_PARAMSET_H
        +#define GOST_PARAMSET_H
        +typedef struct R3410 {
        +		int nid;
        +		char *a;
        +		char *p;
        +		char *q;
        +} R3410_params;
        +
        +extern R3410_params R3410_paramset[];
        +
        +typedef struct R3410_2001 {
        +		int nid;
        +		char *a;
        +		char *b;
        +		char *p;
        +		char *q;
        +		char *x;
        +		char *y;
        +} R3410_2001_params;
        +
        +extern R3410_2001_params R3410_2001_paramset[];
        +
        +#endif
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_pmeth.c b/vendor/openssl/openssl/engines/ccgost/gost_pmeth.c
        new file mode 100644
        index 000000000..f91c9b193
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_pmeth.c
        @@ -0,0 +1,628 @@
        +/**********************************************************************
        + *                          gost_pmeth.c                              *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
        + *       for OpenSSL                                                  *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/ec.h>
        +#include <openssl/x509v3.h> /*For string_to_hex */
        +#include <stdlib.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include "gost_params.h"
        +#include "gost_lcl.h"
        +#include "e_gost_err.h"
        +/*-------init, cleanup, copy - uniform for all algs  ---------------*/
        +/* Allocates new gost_pmeth_data structure and assigns it as data */
        +static int pkey_gost_init(EVP_PKEY_CTX *ctx)
        +	{
        +	struct gost_pmeth_data *data;
        +	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
        +	data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
        +	if (!data) return 0;
        +	memset(data,0,sizeof(struct gost_pmeth_data));
        +	if (pkey && EVP_PKEY_get0(pkey)) 
        +		{
        +		switch (EVP_PKEY_base_id(pkey)) {
        +		case NID_id_GostR3410_94:
        +		  data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
        +		  break;
        +		case NID_id_GostR3410_2001:
        +		   data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
        +		break;
        +		default:
        +			return 0;
        +		}	  
        +		}
        +	EVP_PKEY_CTX_set_data(ctx,data);
        +	return 1;
        +	}
        +
        +/* Copies contents of gost_pmeth_data structure */
        +static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	struct gost_pmeth_data *dst_data,*src_data;
        +	if (!pkey_gost_init(dst))
        +		{
        +		return 0;
        +		}
        +	src_data = EVP_PKEY_CTX_get_data(src);
        +	dst_data = EVP_PKEY_CTX_get_data(dst);
        +	*dst_data = *src_data;
        +	if (src_data -> shared_ukm) {
        +		dst_data->shared_ukm=NULL;
        +	}	
        +	return 1;
        +	}
        +
        +/* Frees up gost_pmeth_data structure */
        +static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
        +	{
        +	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +	if (data->shared_ukm) OPENSSL_free(data->shared_ukm);
        +	OPENSSL_free(data);
        +	}	
        +
        +/* --------------------- control functions  ------------------------------*/
        +static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
        +	switch (type)
        +		{
        +		case EVP_PKEY_CTRL_MD:
        +		{
        +		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
        +			return 0;
        +			}
        +		pctx->md = (EVP_MD *)p2;
        +		return 1;
        +		}
        +		break;
        +
        +		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
        +		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
        +		case EVP_PKEY_CTRL_PKCS7_SIGN:
        +		case EVP_PKEY_CTRL_DIGESTINIT:
        +#ifndef OPENSSL_NO_CMS		
        +		case EVP_PKEY_CTRL_CMS_ENCRYPT:
        +		case EVP_PKEY_CTRL_CMS_DECRYPT:
        +		case EVP_PKEY_CTRL_CMS_SIGN:
        +#endif		
        +			return 1;
        +
        +		case EVP_PKEY_CTRL_GOST_PARAMSET:
        +			pctx->sign_param_nid = (int)p1;
        +			return 1;
        +		case EVP_PKEY_CTRL_SET_IV:
        +			pctx->shared_ukm=OPENSSL_malloc((int)p1);
        +			memcpy(pctx->shared_ukm,p2,(int) p1);
        +			return 1;
        +		case EVP_PKEY_CTRL_PEER_KEY:
        +			if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
        +				return 1;
        +			if (p1 == 2)		/* TLS: peer key used? */
        +				return pctx->peer_key_used;
        +			if (p1 == 3)		/* TLS: peer key used! */
        +				return (pctx->peer_key_used = 1);
        +			return -2;
        +		}
        +	return -2;
        +	}
        +
        +
        +static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
        +	const char *type, const char *value)
        +	{
        +	int param_nid=0;
        +	if(!strcmp(type, param_ctrl_string))
        +		{
        +		if (!value)
        +			{
        +			return 0;
        +			}
        +		if (strlen(value) == 1)
        +			{
        +			switch(toupper((unsigned char)value[0]))
        +				{
        +				case 'A':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
        +					break;
        +				case 'B':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
        +					break;
        +				case 'C':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
        +					break;
        +				case 'D':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
        +					break;
        +				default:
        +					return 0;
        +					break;
        +				}
        +			}
        +		else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
        +			{
        +			switch (toupper((unsigned char)value[1]))
        +				{
        +				case 'A':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
        +					break;
        +				case 'B':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
        +					break;
        +				case 'C':
        +					param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
        +					break;
        +				default:
        +					return 0;
        +					break;
        +				}
        +			}
        +		else
        +			{
        +			R3410_params *p = R3410_paramset;
        +			param_nid = OBJ_txt2nid(value);
        +			if (param_nid == NID_undef)
        +				{
        +				return 0;
        +				}
        +			for (;p->nid != NID_undef;p++)
        +				{
        +				if (p->nid == param_nid) break;
        +				}
        +			if (p->nid == NID_undef)
        +				{
        +				GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
        +					GOST_R_INVALID_PARAMSET);
        +				return 0;
        +				}
        +			}
        +
        +		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
        +			param_nid, NULL);
        +		}
        +	return -2;
        +	}
        +
        +static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
        +	const char *type, const char *value)
        +	{
        +	int param_nid=0;
        +	if(!strcmp(type, param_ctrl_string))
        +		{
        +		if (!value)
        +			{
        +			return 0;
        +			}
        +		if (strlen(value) == 1)
        +			{
        +			switch(toupper((unsigned char)value[0]))
        +				{
        +				case 'A':
        +					param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
        +					break;	
        +				case 'B':
        +					param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
        +					break;
        +				case 'C':
        +					param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
        +					break;
        +				case '0':
        +					param_nid = NID_id_GostR3410_2001_TestParamSet;
        +					break;
        +				default:
        +					return 0;
        +					break;
        +				}
        +			}
        +		else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
        +			{
        +			switch (toupper((unsigned char)value[1]))
        +				{
        +				case 'A':
        +					param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
        +					break;
        +				case 'B':
        +					param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
        +					break;
        +				default:
        +					return 0;
        +					break;
        +				}
        +			}
        +		else
        +			{
        +			R3410_2001_params *p = R3410_2001_paramset;
        +			param_nid = OBJ_txt2nid(value);
        +			if (param_nid == NID_undef)
        +				{
        +				return 0;
        +				}
        +			for (;p->nid != NID_undef;p++)
        +				{
        +				if (p->nid == param_nid) break;
        +				}
        +			if (p->nid == NID_undef)
        +				{
        +				GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
        +					GOST_R_INVALID_PARAMSET);
        +				return 0;
        +				}
        +			}
        +
        +		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
        +			param_nid, NULL);
        +		}
        +	return -2;
        +	}
        +
        +/* --------------------- key generation  --------------------------------*/
        +
        +static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) {
        +	return 1;
        +}	
        +static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 
        +	{
        +	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +	DSA *dsa=NULL;
        +	if (data->sign_param_nid == NID_undef)
        +		{
        +			GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN,
        +				GOST_R_NO_PARAMETERS_SET);
        +			return 0;
        +		}
        +	dsa = DSA_new();
        +	if (!fill_GOST94_params(dsa,data->sign_param_nid))
        +		{
        +		DSA_free(dsa);
        +		return 0;
        +		}
        +	EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
        +	return 1;
        +	}
        +static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +	EC_KEY *ec=NULL;
        +
        +	if (data->sign_param_nid == NID_undef)
        +		{
        +			GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN,
        +				GOST_R_NO_PARAMETERS_SET);
        +			return 0;
        +		}
        +	if (!ec) 	
        +		ec = EC_KEY_new();
        +	if (!fill_GOST2001_params(ec,data->sign_param_nid))
        +		{
        +		EC_KEY_free(ec);
        +		return 0;
        +		}
        +	EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
        +	return 1;
        +	}
        +
        +/* Generates Gost_R3410_94_cp key */
        +static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	DSA *dsa;
        +	if (!pkey_gost94_paramgen(ctx,pkey)) return 0;
        +	dsa = EVP_PKEY_get0(pkey);
        +	gost_sign_keygen(dsa);
        +	return 1;
        +	}
        +
        +/* Generates GOST_R3410 2001 key and assigns it using specified type */
        +static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	EC_KEY *ec;
        +    if (!pkey_gost01_paramgen(ctx,pkey)) return 0;
        +	ec = EVP_PKEY_get0(pkey);
        +	gost2001_keygen(ec);
        +	return 1;
        +	}
        +
        +
        +
        +/* ----------- sign callbacks --------------------------------------*/
        +
        +static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +	const unsigned char *tbs, size_t tbs_len)
        +	{
        +	DSA_SIG *unpacked_sig=NULL;
        +	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
        +	if (!siglen) return 0;
        +	if (!sig)
        +		{
        +		*siglen= 64; /* better to check size of pkey->pkey.dsa-q */
        +		return 1;
        +		}	
        +	unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
        +	if (!unpacked_sig)
        +		{
        +		return 0;
        +		}
        +	return pack_sign_cp(unpacked_sig,32,sig,siglen);
        +	}
        +
        +static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
        +	const unsigned char *tbs, size_t tbs_len)
        +	{
        +	DSA_SIG *unpacked_sig=NULL;
        +	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
        +	if (!siglen) return 0;
        +	if (!sig)
        +		{
        +		*siglen= 64; /* better to check size of curve order*/
        +		return 1;
        +		}	
        +	unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
        +	if (!unpacked_sig)
        +		{
        +		return 0;
        +		}
        +	return pack_sign_cp(unpacked_sig,32,sig,siglen);
        +	}
        +
        +/* ------------------- verify callbacks ---------------------------*/
        +
        +static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
        +	size_t siglen, const unsigned char *tbs, size_t tbs_len)
        +	{
        +	int ok = 0;
        +	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
        +	DSA_SIG *s=unpack_cp_signature(sig,siglen);
        +	if (!s) return 0;
        +	if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
        +	DSA_SIG_free(s);
        +	return ok;
        +	}
        +
        +
        +static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
        +	size_t siglen, const unsigned char *tbs, size_t tbs_len)
        +	{
        +	int ok = 0;
        +	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
        +	DSA_SIG *s=unpack_cp_signature(sig,siglen);
        +	if (!s) return 0;
        +#ifdef DEBUG_SIGN	
        +	fprintf(stderr,"R=");
        +	BN_print_fp(stderr,s->r);
        +	fprintf(stderr,"\nS=");
        +	BN_print_fp(stderr,s->s);
        +	fprintf(stderr,"\n");
        +#endif	
        +	if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
        +	DSA_SIG_free(s);
        +	return ok;
        +	}
        +
        +/* ------------- encrypt init -------------------------------------*/
        +/* Generates ephermeral key */
        +static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
        +	{
        +	return 1;
        +	}
        +/* --------------- Derive init ------------------------------------*/
        +static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
        +{
        +	return 1;
        +}
        +/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
        +static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
        +	{
        +	struct gost_mac_pmeth_data *data;
        +	data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
        +	if (!data) return 0;
        +	memset(data,0,sizeof(struct gost_mac_pmeth_data));
        +	EVP_PKEY_CTX_set_data(ctx,data);
        +	return 1;
        +	}	
        +static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
        +	{
        +	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +	OPENSSL_free(data);
        +	}	
        +static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
        +	{
        +	struct gost_mac_pmeth_data *dst_data,*src_data;
        +	if (!pkey_gost_mac_init(dst))
        +		{
        +		return 0;
        +		}
        +	src_data = EVP_PKEY_CTX_get_data(src);
        +	dst_data = EVP_PKEY_CTX_get_data(dst);
        +	*dst_data = *src_data;
        +	return 1;
        +	}
        +	
        +static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
        +	{
        +	struct gost_mac_pmeth_data *data =
        +(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
        +
        +	switch (type)
        +		{
        +		case EVP_PKEY_CTRL_MD:
        +		{
        +		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
        +			return 0;
        +			}
        +		data->md = (EVP_MD *)p2;
        +		return 1;
        +		}
        +		break;
        +
        +		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
        +		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
        +		case EVP_PKEY_CTRL_PKCS7_SIGN:
        +			return 1;
        +		case EVP_PKEY_CTRL_SET_MAC_KEY:
        +			if (p1 != 32) 
        +				{
        +				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
        +					GOST_R_INVALID_MAC_KEY_LENGTH);
        +				return 0;
        +				}
        +
        +			memcpy(data->key,p2,32);
        +			data->key_set = 1;
        +			return 1;
        +		case EVP_PKEY_CTRL_DIGESTINIT:
        +			{ 
        +			EVP_MD_CTX *mctx = p2;
        +			void *key;
        +			if (!data->key_set)
        +				{ 
        +				EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
        +				if (!pkey) 
        +					{
        +					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
        +					return 0;
        +					}
        +				key = EVP_PKEY_get0(pkey);
        +				if (!key) 
        +					{
        +					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
        +					return 0;
        +					}
        +				} else {
        +				key = &(data->key);
        +				}
        +			return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
        +			}  
        +		}	
        +	return -2;
        +	}
        +static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
        +	const char *type, const char *value)
        +	{
        +	if (!strcmp(type, key_ctrl_string)) 
        +		{
        +		if (strlen(value)!=32) 
        +			{
        +			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
        +				GOST_R_INVALID_MAC_KEY_LENGTH);
        +			return 0;	
        +			}
        +		return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
        +			32,(char *)value);
        +		}
        +	if (!strcmp(type, hexkey_ctrl_string)) 
        +		{
        +			long keylen; int ret;
        +			unsigned char *keybuf=string_to_hex(value,&keylen);
        +			if (keylen != 32) 
        +				{
        +				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
        +					GOST_R_INVALID_MAC_KEY_LENGTH);
        +				OPENSSL_free(keybuf);
        +				return 0;	
        +				}
        +			ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
        +				32,keybuf);
        +			OPENSSL_free(keybuf);
        +			return ret;
        +	
        +		}
        +	return -2;
        +	}	
        +
        +static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +		struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
        +		unsigned char *keydata;
        +		if (!data->key_set) 
        +		{
        +			GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
        +			return 0;
        +		}
        +		keydata = OPENSSL_malloc(32);
        +		memcpy(keydata,data->key,32);
        +		EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
        +		return 1;
        +	}
        +
        +static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
        +	{
        +	return 1;
        +}
        +
        +static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
        +	{
        +		unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
        +		int ret;
        +		if (!sig) 
        +			{
        +			*siglen = 4;
        +			return 1;
        +			}
        +		ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
        +		*siglen = tmpsiglen;
        +		return ret;
        +	}
        +/* ----------------------------------------------------------------*/
        +int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
        +	{
        +	*pmeth = EVP_PKEY_meth_new(id, flags);
        +	if (!*pmeth) return 0;
        +
        +	switch (id)
        +		{
        +		case NID_id_GostR3410_94:
        +			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
        +			EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
        +			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
        +			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
        +			EVP_PKEY_meth_set_encrypt(*pmeth,
        +				pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
        +			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
        +			EVP_PKEY_meth_set_derive(*pmeth,
        +				pkey_gost_derive_init, pkey_gost94_derive);
        +			EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen);	
        +			break;
        +		case NID_id_GostR3410_2001:
        +			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
        +			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
        +			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);
        +
        +			EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);
        +
        +			EVP_PKEY_meth_set_encrypt(*pmeth,
        +				pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
        +			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
        +			EVP_PKEY_meth_set_derive(*pmeth,
        +				pkey_gost_derive_init, pkey_gost2001_derive);
        +			EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen);	
        +			break;
        +		case NID_id_Gost28147_89_MAC:
        +			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
        +			EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
        +			EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
        +			EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
        +			EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
        +			EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
        +			return 1;
        +		default: /*Unsupported method*/
        +			return 0;
        +		}
        +	EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
        +	EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
        +
        +	EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
        +	/*FIXME derive etc...*/
        +	
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/engines/ccgost/gost_sign.c b/vendor/openssl/openssl/engines/ccgost/gost_sign.c
        new file mode 100644
        index 000000000..409565435
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gost_sign.c
        @@ -0,0 +1,321 @@
        +/**********************************************************************
        + *                          gost_sign.c                               *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *       Implementation of GOST R 34.10-94 signature algorithm        *
        + *       for OpenSSL                                                  *
        + *          Requires OpenSSL 0.9.9 for compilation                    *
        + **********************************************************************/
        +#include <string.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +#include <openssl/dsa.h>
        +#include <openssl/evp.h>
        +
        +#include "gost_params.h"
        +#include "gost_lcl.h"
        +#include "e_gost_err.h"
        +
        +#ifdef DEBUG_SIGN
        +void dump_signature(const char *message,const unsigned char *buffer,size_t len)
        +	{
        +	size_t i;
        +	fprintf(stderr,"signature %s Length=%d",message,len);
        +	for (i=0; i<len; i++)
        +		{
        +		if (i% 16 ==0) fputc('\n',stderr);
        +		fprintf (stderr," %02x",buffer[i]);
        +		}
        +	fprintf(stderr,"\nEnd of signature\n");
        +	}
        +
        +void dump_dsa_sig(const char *message, DSA_SIG *sig)
        +	{
        +	fprintf(stderr,"%s\nR=",message);
        +	BN_print_fp(stderr,sig->r);
        +	fprintf(stderr,"\nS=");
        +	BN_print_fp(stderr,sig->s);
        +	fprintf(stderr,"\n");
        +	}
        +
        +#else
        +
        +#define dump_signature(a,b,c)
        +#define dump_dsa_sig(a,b)
        +#endif
        +
        +/*
        + * Computes signature and returns it as DSA_SIG structure
        + */
        +DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
        +	{
        +	BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
        +	DSA_SIG *newsig = DSA_SIG_new();
        +	BIGNUM *md = hashsum2bn(dgst);
        +	/* check if H(M) mod q is zero */
        +	BN_CTX *ctx=BN_CTX_new();
        +	BN_CTX_start(ctx);
        +	if (!newsig)
        +		{
        +		GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
        +		goto err;
        +		}	
        +	tmp=BN_CTX_get(ctx);
        +	k = BN_CTX_get(ctx);
        +	tmp2 = BN_CTX_get(ctx);
        +	BN_mod(tmp,md,dsa->q,ctx);
        +	if (BN_is_zero(tmp))
        +		{
        +		BN_one(md);
        +		}	
        +	do
        +		{
        +		do
        +			{
        +			/*Generate random number k less than q*/
        +			BN_rand_range(k,dsa->q);
        +			/* generate r = (a^x mod p) mod q */
        +			BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
        +			if (!(newsig->r)) newsig->r=BN_new();
        +			BN_mod(newsig->r,tmp,dsa->q,ctx);
        +			}
        +		while (BN_is_zero(newsig->r));
        +		/* generate s = (xr + k(Hm)) mod q */
        +		BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
        +		BN_mod_mul(tmp2,k,md,dsa->q,ctx);
        +		if (!newsig->s) newsig->s=BN_new();
        +		BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
        +		}
        +	while (BN_is_zero(newsig->s));		
        +	err:
        +	BN_free(md);
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	return newsig;
        +	}	
        +
        +
        +/*
        + * Packs signature according to Cryptocom rules
        + * and frees up DSA_SIG structure
        + */
        +/*
        +int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
        +	{
        +	*siglen = 2*order;
        +	memset(sig,0,*siglen);
        +	store_bignum(s->r, sig,order);
        +	store_bignum(s->s, sig + order,order);
        +	dump_signature("serialized",sig,*siglen);
        +	DSA_SIG_free(s);
        +	return 1;
        +	}
        +*/
        +/*
        + * Packs signature according to Cryptopro rules
        + * and frees up DSA_SIG structure
        + */
        +int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
        +	{
        +	*siglen = 2*order;
        +	memset(sig,0,*siglen);
        +	store_bignum(s->s, sig, order);
        +	store_bignum(s->r, sig+order,order);
        +	dump_signature("serialized",sig,*siglen);
        +	DSA_SIG_free(s);
        +	return 1;
        +	}
        +
        +/*
        + * Verifies signature passed as DSA_SIG structure
        + *
        + */
        +
        +int gost_do_verify(const unsigned char *dgst, int dgst_len,
        +	DSA_SIG *sig, DSA *dsa)
        +	{
        +	BIGNUM *md, *tmp=NULL;
        +	BIGNUM *q2=NULL;
        +	BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
        +	BIGNUM *tmp2=NULL,*tmp3=NULL;
        +	int ok;
        +	BN_CTX *ctx = BN_CTX_new();
        +
        +	BN_CTX_start(ctx);
        +	if (BN_cmp(sig->s,dsa->q)>=1||
        +		BN_cmp(sig->r,dsa->q)>=1)
        +		{
        +		GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
        +		return 0;
        +		}
        +	md=hashsum2bn(dgst);
        +	
        +	tmp=BN_CTX_get(ctx);
        +	v=BN_CTX_get(ctx);
        +	q2=BN_CTX_get(ctx);
        +	z1=BN_CTX_get(ctx);
        +	z2=BN_CTX_get(ctx);
        +	tmp2=BN_CTX_get(ctx);
        +	tmp3=BN_CTX_get(ctx);
        +	u = BN_CTX_get(ctx);
        +	
        +	BN_mod(tmp,md,dsa->q,ctx);
        +	if (BN_is_zero(tmp))
        +		{
        +		BN_one(md);
        +		}
        +	BN_copy(q2,dsa->q);
        +	BN_sub_word(q2,2);
        +	BN_mod_exp(v,md,q2,dsa->q,ctx);
        +	BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
        +	BN_sub(tmp,dsa->q,sig->r);
        +	BN_mod_mul(z2,tmp,v,dsa->p,ctx);
        +	BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
        +	BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
        +	BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
        +	BN_mod(u,tmp3,dsa->q,ctx);
        +	ok= BN_cmp(u,sig->r);
        +	
        +	BN_free(md);
        +	BN_CTX_end(ctx);
        +	BN_CTX_free(ctx);
        +	if (ok!=0)
        +		{
        +		GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
        +		}	
        +	return (ok==0);
        +	}
        +
        +/*
        + * Computes public keys for GOST R 34.10-94 algorithm
        + *
        + */
        +int gost94_compute_public(DSA *dsa)
        +	{
        +	/* Now fill algorithm parameters with correct values */
        +	BN_CTX *ctx = BN_CTX_new();
        +	if (!dsa->g)
        +		{
        +		GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
        +		return 0;
        +		}	
        +	/* Compute public key  y = a^x mod p */
        +	dsa->pub_key=BN_new();
        +	BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
        +	BN_CTX_free(ctx);
        +	return 1;
        +	}
        +
        +/*
        + * Fill GOST 94 params, searching them in R3410_paramset array
        + * by nid of paramset
        + *
        + */
        +int fill_GOST94_params(DSA *dsa,int nid)
        +	{
        +	R3410_params *params=R3410_paramset;
        +	while (params->nid!=NID_undef && params->nid !=nid) params++;
        +	if (params->nid == NID_undef)
        +		{
        +		GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
        +		return 0;
        +		}	
        +#define dump_signature(a,b,c)
        +	if (dsa->p) { BN_free(dsa->p); }
        +	dsa->p=NULL;
        +	BN_dec2bn(&(dsa->p),params->p);
        +	if (dsa->q) { BN_free(dsa->q); }
        +	dsa->q=NULL;
        +	BN_dec2bn(&(dsa->q),params->q);
        +	if (dsa->g) { BN_free(dsa->g); }
        +	dsa->g=NULL;
        +	BN_dec2bn(&(dsa->g),params->a);
        +	return 1;
        +	}	
        +
        +/*
        + *  Generate GOST R 34.10-94 keypair
        + *
        + *
        + */
        +int gost_sign_keygen(DSA *dsa)
        +	{
        +	dsa->priv_key = BN_new();
        +	BN_rand_range(dsa->priv_key,dsa->q);
        +	return gost94_compute_public( dsa);
        +	}
        +
        +/* Unpack signature according to cryptocom rules  */
        +/*
        +DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
        +	{
        +	DSA_SIG *s;
        +	s = DSA_SIG_new();
        +	if (s == NULL)
        +		{
        +		GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
        +		return(NULL);
        +		}
        +	s->r = getbnfrombuf(sig, siglen/2);
        +	s->s = getbnfrombuf(sig + siglen/2, siglen/2);
        +	return s;
        +	}
        +*/
        +/* Unpack signature according to cryptopro rules  */
        +DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
        +	{
        +	DSA_SIG *s;
        +
        +	s = DSA_SIG_new();
        +	if (s == NULL)
        +		{
        +		GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
        +		return NULL;
        +		}
        +	s->s = getbnfrombuf(sig , siglen/2);
        +	s->r = getbnfrombuf(sig + siglen/2, siglen/2);
        +	return s;
        +	}
        +
        +/* Convert little-endian byte array into bignum */
        +BIGNUM *hashsum2bn(const unsigned char *dgst)
        +	{
        +	unsigned char buf[32];
        +	int i;
        +	for (i=0;i<32;i++)
        +		{
        +		buf[31-i]=dgst[i];
        +		}
        +	return getbnfrombuf(buf,32);
        +	}
        +
        +/* Convert byte buffer to bignum, skipping leading zeros*/
        +BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
        +	{
        +	while (*buf==0&&len>0)
        +		{
        +		buf++; len--;
        +		}
        +	if (len)
        +		{
        +		return BN_bin2bn(buf,len,NULL);
        +		}
        +	else
        +		{
        +		BIGNUM *b=BN_new();
        +		BN_zero(b);
        +		return b;
        +		}
        +	}
        +
        +/* Pack bignum into byte buffer of given size, filling all leading bytes
        + * by zeros */
        +int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
        +	{
        +	int bytes = BN_num_bytes(bn);
        +	if (bytes>len) return 0;
        +	memset(buf,0,len);
        +	BN_bn2bin(bn,buf+len-bytes);
        +	return 1;
        +	}	
        diff --git a/vendor/openssl/openssl/engines/ccgost/gosthash.c b/vendor/openssl/openssl/engines/ccgost/gosthash.c
        new file mode 100644
        index 000000000..8c278aa64
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gosthash.c
        @@ -0,0 +1,255 @@
        +/**********************************************************************
        + *                          gosthash.c                                *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *    Implementation of GOST R 34.11-94 hash function                 *
        + *       uses on gost89.c and gost89.h Doesn't need OpenSSL           *
        + **********************************************************************/
        +#include <string.h>
        +
        +#include "gost89.h"
        +#include "gosthash.h"
        +
        +
        +/* Use OPENSSL_malloc for memory allocation if compiled with 
        + * -DOPENSSL_BUILD, and libc malloc otherwise
        + */
        +#ifndef MYALLOC
        +# ifdef OPENSSL_BUILD
        +#  include <openssl/crypto.h>
        +#  define MYALLOC(size) OPENSSL_malloc(size)
        +#  define MYFREE(ptr) OPENSSL_free(ptr)
        +# else
        +#  define MYALLOC(size) malloc(size)
        +#  define MYFREE(ptr) free(ptr)
        +# endif
        +#endif
        +/* Following functions are various bit meshing routines used in
        + * GOST R 34.11-94 algorithms */
        +static void swap_bytes (byte *w, byte *k) 
        +	{
        +	int i,j;
        +	for (i=0;i<4;i++)	
        +		for (j=0;j<8;j++) 
        +			k[i+4*j]=w[8*i+j];
        +
        +	}
        +
        +/* was A_A */
        +static void circle_xor8 (const byte *w, byte *k) 
        +	{
        +	byte buf[8];
        +	int i;
        +	memcpy(buf,w,8);
        +	memmove(k,w+8,24);
        +	for(i=0;i<8;i++) 
        +		k[i+24]=buf[i]^k[i];
        +	}
        +
        +/* was R_R */
        +static void transform_3 (byte *data) 
        +	{
        +	unsigned short int acc;
        +	acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
        +		((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
        +	memmove(data,data+2,30);
        +	data[30]=acc&0xff;
        +	data[31]=acc>>8;
        +	}
        +
        +/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
        +static int add_blocks(int n,byte *left, const byte *right) 
        +	{
        +	int i;
        +	int carry=0;
        +	int sum;
        +	for (i=0;i<n;i++) 
        +		{
        +	   	sum=(int)left[i]+(int)right[i]+carry;
        +		left[i]=sum & 0xff;
        +		carry=sum>>8;
        +		}
        +	return carry;
        +	} 
        +
        +/* Xor two sequences of bytes */
        +static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
        +	{
        +	size_t i;
        +	for (i=0;i<len;i++) result[i]=a[i]^b[i];
        +	}	
        +
        +/* 
        + * 	Calculate H(i+1) = Hash(Hi,Mi) 
        + * 	Where H and M are 32 bytes long
        + */
        +static int hash_step(gost_ctx *c,byte *H,const byte *M) 
        +	{
        +	byte U[32],W[32],V[32],S[32],Key[32];
        +	int i;
        +	/* Compute first key */
        +	xor_blocks(W,H,M,32);
        +	swap_bytes(W,Key);
        +	/* Encrypt first 8 bytes of H with first key*/
        +	gost_enc_with_key(c,Key,H,S);
        +	/* Compute second key*/
        +	circle_xor8(H,U);
        +	circle_xor8(M,V);
        +	circle_xor8(V,V);
        +	xor_blocks(W,U,V,32);
        +	swap_bytes(W,Key);
        +	/* encrypt second 8 bytes of H with second key*/
        +	gost_enc_with_key(c,Key,H+8,S+8);
        +	/* compute third key */
        +	circle_xor8(U,U);
        +	U[31]=~U[31]; U[29]=~U[29]; U[28]=~U[28]; U[24]=~U[24];
        +	U[23]=~U[23]; U[20]=~U[20]; U[18]=~U[18]; U[17]=~U[17];
        +	U[14]=~U[14]; U[12]=~U[12]; U[10]=~U[10]; U[ 8]=~U[ 8];
        +	U[ 7]=~U[ 7]; U[ 5]=~U[ 5]; U[ 3]=~U[ 3]; U[ 1]=~U[ 1];
        +	circle_xor8(V,V);
        +	circle_xor8(V,V);
        +	xor_blocks(W,U,V,32);
        +	swap_bytes(W,Key);
        +	/* encrypt third 8 bytes of H with third key*/
        +	gost_enc_with_key(c,Key,H+16,S+16);
        +	/* Compute fourth key */
        +	circle_xor8(U,U);
        +	circle_xor8(V,V);
        +	circle_xor8(V,V);
        +	xor_blocks(W,U,V,32);
        +	swap_bytes(W,Key);
        +	/* Encrypt last 8 bytes with fourth key */
        +	gost_enc_with_key(c,Key,H+24,S+24);
        +	for (i=0;i<12;i++) 
        +		transform_3(S);
        +	xor_blocks(S,S,M,32);
        +	transform_3(S);
        +	xor_blocks(S,S,H,32);
        +	for (i=0;i<61;i++) 
        +		transform_3(S);
        +	memcpy(H,S,32);
        +	return 1;
        +	}
        +
        +/* Initialize gost_hash ctx - cleans up temporary structures and
        + * set up substitution blocks
        + */
        +int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
        +	{	
        +	memset(ctx,0,sizeof(gost_hash_ctx));
        +	ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
        +	if (!ctx->cipher_ctx)
        +		{
        +		return 0;
        +		}		
        +	gost_init(ctx->cipher_ctx,subst_block);
        +	return 1;
        +	}
        +
        +/*
        + * Free cipher CTX if it is dynamically allocated. Do not use
        + * if cipher ctx is statically allocated as in OpenSSL implementation of
        + * GOST hash algroritm
        + *
        + */ 
        +void done_gost_hash_ctx(gost_hash_ctx *ctx) 
        +	{
        +	/* No need to use gost_destroy, because cipher keys are not really
        +	 * secret when hashing */
        +	MYFREE(ctx->cipher_ctx);
        +	}
        +
        +/*
        + * reset state of hash context to begin hashing new message
        + */
        +int start_hash(gost_hash_ctx *ctx)
        +	{
        +	if (!ctx->cipher_ctx) return 0;
        +	memset(&(ctx->H),0,32);
        +	memset(&(ctx->S),0,32);
        +	ctx->len = 0L;
        +	ctx->left=0;
        +	return 1;
        +	}
        +
        +/*
        + * Hash block of arbitrary length
        + *
        + *
        + */
        +int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
        +	{
        +	const byte *curptr=block;
        +	const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
        +	if (ctx->left)
        +		{
        +		/*There are some bytes from previous step*/
        +		unsigned int add_bytes = 32-ctx->left;
        +		if (add_bytes>length)
        +			{
        +			add_bytes = length;
        +			}	
        +		memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
        +		ctx->left+=add_bytes;
        +		if (ctx->left<32)
        +			{
        +			return 1;
        +			}	
        +		curptr=block+add_bytes;
        +		hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
        +		add_blocks(32,ctx->S,ctx->remainder);
        +		ctx->len+=32;
        +		ctx->left=0;
        +		}
        +	while (curptr<=barrier)
        +		{	
        +		hash_step(ctx->cipher_ctx,ctx->H,curptr);
        +			
        +		add_blocks(32,ctx->S,curptr);
        +		ctx->len+=32;
        +		curptr+=32;
        +		}	
        +	if (curptr!=block+length)
        +		{
        +		ctx->left=block+length-curptr;
        +		memcpy(ctx->remainder,curptr,ctx->left);
        +		}	
        +	return 1;	
        +	}
        +
        +/*
        + * Compute hash value from current state of ctx
        + * state of hash ctx becomes invalid and cannot be used for further
        + * hashing.
        + */ 
        +int finish_hash(gost_hash_ctx *ctx,byte *hashval)
        +	{
        +	byte buf[32];
        +	byte H[32];
        +	byte S[32];
        +	ghosthash_len fin_len=ctx->len;
        +	byte *bptr;
        +	memcpy(H,ctx->H,32);
        +	memcpy(S,ctx->S,32);
        +	if (ctx->left)
        +		{
        +		memset(buf,0,32);
        +		memcpy(buf,ctx->remainder,ctx->left);
        +		hash_step(ctx->cipher_ctx,H,buf);
        +		add_blocks(32,S,buf);
        +		fin_len+=ctx->left;
        +		}
        +	memset(buf,0,32);
        +	bptr=buf;
        +	fin_len<<=3; /* Hash length in BITS!!*/
        +	while(fin_len>0)
        +		{
        +		*(bptr++)=(byte)(fin_len&0xFF);
        +		fin_len>>=8;
        +		};
        +	hash_step(ctx->cipher_ctx,H,buf);
        +	hash_step(ctx->cipher_ctx,H,S);
        +	memcpy(hashval,H,32);
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/engines/ccgost/gosthash.h b/vendor/openssl/openssl/engines/ccgost/gosthash.h
        new file mode 100644
        index 000000000..4a2e441ec
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gosthash.h
        @@ -0,0 +1,48 @@
        +/**********************************************************************
        + *                          gosthash.h                                *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *       This file is distributed under the same license as OpenSSL   *
        + *                                                                    *
        + *    Declaration of GOST R 34.11-94 hash functions                   *
        + *       uses  and gost89.h Doesn't need OpenSSL                      *
        + **********************************************************************/
        +#ifndef GOSTHASH_H
        +#define GOSTHASH_H
        +#include "gost89.h"
        +#include <stdlib.h>
        +
        +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
        +typedef __int64 ghosthash_len;
        +#elif defined(__arch64__)
        +typedef long ghosthash_len;
        +#else
        +typedef long long ghosthash_len;
        +#endif
        +
        +typedef struct gost_hash_ctx {
        +		ghosthash_len len;
        +		gost_ctx *cipher_ctx;
        +		int left;
        +		byte H[32];
        +		byte S[32];
        +		byte remainder[32];
        +} gost_hash_ctx;		
        +
        +
        +/* Initalizes gost hash ctx, including creation of gost cipher ctx */
        +
        +int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block);
        +void done_gost_hash_ctx(gost_hash_ctx *ctx);
        +
        +/* Cleans up all fields, except cipher ctx preparing ctx for computing
        + * of new hash value */
        +int start_hash(gost_hash_ctx *ctx);
        +
        +/* Hashes block of data */
        +int hash_block(gost_hash_ctx *ctx, const byte *block, size_t length);
        +
        +/* Finalizes computation of hash  and fills buffer (which should be at
        + * least 32 bytes long) with value of computed hash. */
        +int finish_hash(gost_hash_ctx *ctx, byte *hashval);
        +
        +#endif	
        diff --git a/vendor/openssl/openssl/engines/ccgost/gostsum.c b/vendor/openssl/openssl/engines/ccgost/gostsum.c
        new file mode 100644
        index 000000000..d57112eb5
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ccgost/gostsum.c
        @@ -0,0 +1,210 @@
        +/**********************************************************************
        + *                        gostsum.c                                   *
        + *             Copyright (c) 2005-2006 Cryptocom LTD                  *
        + *         This file is distributed under the same license as OpenSSL *
        + *                                                                    *
        + *        Almost drop-in replacement for md5sum and sha1sum           *
        + *          which computes GOST R 34.11-94 hashsum instead            *
        + *                                                                    *
        + **********************************************************************/
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <unistd.h>
        +#include <limits.h>
        +#include <fcntl.h>
        +#include <string.h>
        +#include "gosthash.h"
        +#define BUF_SIZE 262144
        +int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode);
        +int hash_stream(gost_hash_ctx *ctx,int fd, char *sum);
        +int get_line(FILE *f,char *hash,char *filename);
        +void help()
        +	{
        +	fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
        +		"\t-c check message digests (default is generate)\n"
        +		"\t-v verbose, print file names when checking\n"
        +		"\t-b read files in binary mode\n"
        +		"\t-t use test GOST paramset (default is CryptoPro paramset)\n"
        +		"The input for -c should be the list of message digests and file names\n"
        +		"that is printed on stdout by this program when it generates digests.\n");
        +	exit(3);
        +	}
        +
        +#ifndef O_BINARY
        +#define O_BINARY 0
        +#endif
        +
        +int main(int argc,char **argv)
        +	{
        +	int c,i;
        +	int verbose=0;
        +	int errors=0;
        +	int open_mode = O_RDONLY;
        +	gost_subst_block *b=  &GostR3411_94_CryptoProParamSet;
        +	FILE *check_file = NULL;
        +	gost_hash_ctx ctx;
        +	
        +	while( (c=getopt(argc,argv,"bc::tv"))!=-1)
        +		{
        +		switch (c)
        +			{
        +			case 'v': verbose=1; break;
        +			case 't': b= &GostR3411_94_TestParamSet; break;
        +			case 'b': open_mode |= O_BINARY; break;
        +			case 'c':
        +				if (optarg)
        +					{
        +					check_file = fopen(optarg,"r");
        +					if (!check_file)
        +						{
        +						perror(optarg);
        +						exit(2);
        +						}
        +					}
        +				else
        +					{
        +				  	check_file= stdin;
        +					}
        +				break;
        +			default:
        +				fprintf(stderr,"invalid option %c",optopt);
        +				help();
        +			}
        +		}
        +	init_gost_hash_ctx(&ctx,b);
        +	if (check_file)
        +		{
        +		char inhash[65],calcsum[65],filename[PATH_MAX];
        +		int failcount=0,count=0;;
        +		if (check_file==stdin && optind<argc)
        +			{
        +			check_file=fopen(argv[optind],"r");
        +			if (!check_file)
        +				{	
        +				perror(argv[optind]);
        +				exit(2);
        +				}
        +			}	
        +		while (get_line(check_file,inhash,filename))
        +			{
        +			if (!hash_file(&ctx,filename,calcsum,open_mode))
        +				{
        +				exit (2);
        +				}	
        +			count++;
        +			if (!strncmp(calcsum,inhash,65))
        +				{
        +				if (verbose)
        +					{
        +					fprintf(stderr,"%s\tOK\n",filename);
        +					}
        +				}
        +			else
        +				{
        +				if (verbose)
        +					{
        +					fprintf(stderr,"%s\tFAILED\n",filename);
        +					}
        +				else
        +					{
        +					fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
        +						argv[0],filename);
        +					}
        +				failcount++;
        +				}
        +			}	
        +		if (verbose && failcount)
        +			{
        +			fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n",
        +				argv[0],failcount,count);
        +			}
        +		exit (failcount?1:0);
        +		}
        +	if (optind==argc)
        +		{
        +		char sum[65];
        +		if (!hash_stream(&ctx,fileno(stdin),sum))
        +			{
        +			perror("stdin");
        +			exit(1);
        +			}	
        +		printf("%s -\n",sum);
        +		exit(0);
        +		}	
        +	for (i=optind;i<argc;i++)
        +		{
        +		char sum[65];
        +		if (!hash_file(&ctx,argv[i],sum,open_mode))
        +			{
        +			errors++;
        +			}
        +		else
        +			{	
        +			printf("%s %s\n",sum,argv[i]);
        +			}
        +		}	
        +	exit(errors?1:0);	
        +	}
        +
        +int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode)
        +	{
        +	int fd;
        +	if ((fd=open(filename,mode))<0)
        +		{
        +		perror(filename);
        +		return 0;
        +		}
        +	if (!hash_stream(ctx,fd,sum))
        +		{
        +		perror(filename);
        +		return 0;
        +		}	
        +	close(fd);
        +	return 1;
        +	}
        +
        +int hash_stream(gost_hash_ctx *ctx,int fd, char *sum)
        +	{
        +	unsigned char buffer[BUF_SIZE];
        +	ssize_t bytes;
        +	int i;
        +	start_hash(ctx);
        +	while ((bytes=read(fd,buffer,BUF_SIZE))>0)
        +		{
        +		hash_block(ctx,buffer,bytes);
        +		}
        +	if (bytes<0)
        +		{
        +		return 0;
        +		}	
        +	finish_hash(ctx,buffer);
        +	for (i=0;i<32;i++)
        +		{
        +		sprintf(sum+2*i,"%02x",buffer[31-i]);
        +		}
        +	return 1;
        +	}	
        +	
        +int get_line(FILE *f,char *hash,char *filename)
        +	{
        +	int i;
        +	if (fread(hash,1,64,f)<64) return 0;
        +	hash[64]=0;
        +	for (i=0;i<64;i++)
        +		{
        +		if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F'
        +				&& hash[i]<'a')||hash[i]>'f')
        +			{
        +			fprintf(stderr,"Not a hash value '%s'\n",hash);
        +			return 0;
        +			}
        +		}	
        +	if (fgetc(f)!=' ')
        +		{
        +		fprintf(stderr,"Malformed input line\n");
        +		return 0;
        +		}
        +	i=strlen(fgets(filename,PATH_MAX,f));
        +	while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
        +	return 1;
        +	}	
        diff --git a/vendor/openssl/openssl/engines/e_4758cca.c b/vendor/openssl/openssl/engines/e_4758cca.c
        new file mode 100644
        index 000000000..443182bd3
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_4758cca.c
        @@ -0,0 +1,987 @@
        +/* Author: Maurice Gittens <maurice@gittens.nl>                       */
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/dso.h>
        +#include <openssl/x509.h>
        +#include <openssl/objects.h>
        +#include <openssl/engine.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_4758_CCA
        +
        +#ifdef FLAT_INC
        +#include "hw_4758_cca.h"
        +#else
        +#include "vendor_defns/hw_4758_cca.h"
        +#endif
        +
        +#include "e_4758cca_err.c"
        +
        +static int ibm_4758_cca_destroy(ENGINE *e);
        +static int ibm_4758_cca_init(ENGINE *e);
        +static int ibm_4758_cca_finish(ENGINE *e);
        +static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +
        +/* rsa functions */
        +/*---------------*/
        +#ifndef OPENSSL_NO_RSA
        +static int cca_rsa_pub_enc(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int cca_rsa_priv_dec(int flen, const unsigned char *from,
        +		unsigned char *to, RSA *rsa,int padding);
        +static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
        +		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
        +static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
        +	const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
        +
        +/* utility functions */
        +/*-----------------------*/
        +static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
        +		UI_METHOD *ui_method, void *callback_data);
        +static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
        +		UI_METHOD *ui_method, void *callback_data);
        +
        +static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
        +		unsigned char *exponent, long *modulusLength,
        +		long *modulusFieldLength, unsigned char *modulus);
        +#endif
        +
        +/* RAND number functions */
        +/*-----------------------*/
        +static int cca_get_random_bytes(unsigned char*, int);
        +static int cca_random_status(void);
        +
        +#ifndef OPENSSL_NO_RSA
        +static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
        +		int idx,long argl, void *argp);
        +#endif
        +
        +/* Function pointers for CCA verbs */
        +/*---------------------------------*/
        +#ifndef OPENSSL_NO_RSA
        +static F_KEYRECORDREAD keyRecordRead;
        +static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
        +static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
        +static F_PUBLICKEYEXTRACT publicKeyExtract;
        +static F_PKAENCRYPT pkaEncrypt;
        +static F_PKADECRYPT pkaDecrypt;
        +#endif
        +static F_RANDOMNUMBERGENERATE randomNumberGenerate;
        +
        +/* static variables */
        +/*------------------*/
        +static const char *CCA4758_LIB_NAME = NULL;
        +static const char *get_CCA4758_LIB_NAME(void)
        +	{
        +	if(CCA4758_LIB_NAME)
        +		return CCA4758_LIB_NAME;
        +	return CCA_LIB_NAME;
        +	}
        +static void free_CCA4758_LIB_NAME(void)
        +	{
        +	if(CCA4758_LIB_NAME)
        +		OPENSSL_free((void*)CCA4758_LIB_NAME);
        +	CCA4758_LIB_NAME = NULL;
        +	}
        +static long set_CCA4758_LIB_NAME(const char *name)
        +	{
        +	free_CCA4758_LIB_NAME();
        +	return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
        +	}
        +#ifndef OPENSSL_NO_RSA
        +static const char* n_keyRecordRead = CSNDKRR;
        +static const char* n_digitalSignatureGenerate = CSNDDSG;
        +static const char* n_digitalSignatureVerify = CSNDDSV;
        +static const char* n_publicKeyExtract = CSNDPKX;
        +static const char* n_pkaEncrypt = CSNDPKE;
        +static const char* n_pkaDecrypt = CSNDPKD;
        +#endif
        +static const char* n_randomNumberGenerate = CSNBRNG;
        +
        +#ifndef OPENSSL_NO_RSA
        +static int hndidx = -1;
        +#endif
        +static DSO *dso = NULL;
        +
        +/* openssl engine initialization structures */
        +/*------------------------------------------*/
        +
        +#define CCA4758_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN	cca4758_cmd_defns[] = {
        +	{CCA4758_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the '4758cca' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA_METHOD ibm_4758_cca_rsa =
        +	{
        +	"IBM 4758 CCA RSA method",
        +	cca_rsa_pub_enc,
        +	NULL,
        +	NULL,
        +	cca_rsa_priv_dec,
        +	NULL, /*rsa_mod_exp,*/
        +	NULL, /*mod_exp_mont,*/
        +	NULL, /* init */
        +	NULL, /* finish */
        +	RSA_FLAG_SIGN_VER,	  /* flags */
        +	NULL, /* app_data */
        +	cca_rsa_sign, /* rsa_sign */
        +	cca_rsa_verify, /* rsa_verify */
        +	NULL /* rsa_keygen */
        +	};
        +#endif
        +
        +static RAND_METHOD ibm_4758_cca_rand =
        +	{
        +	/* "IBM 4758 RAND method", */
        +	NULL, /* seed */
        +	cca_get_random_bytes, /* get random bytes from the card */
        +	NULL, /* cleanup */
        +	NULL, /* add */
        +	cca_get_random_bytes, /* pseudo rand */
        +	cca_random_status, /* status */
        +	};
        +
        +static const char *engine_4758_cca_id = "4758cca";
        +static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
        +/* Compatibility hack, the dynamic library uses this form in the path */
        +static const char *engine_4758_cca_id_alt = "4758_cca";
        +#endif
        +
        +/* engine implementation */
        +/*-----------------------*/
        +static int bind_helper(ENGINE *e)
        +	{
        +	if(!ENGINE_set_id(e, engine_4758_cca_id) ||
        +			!ENGINE_set_name(e, engine_4758_cca_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
        +#endif
        +			!ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
        +			!ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
        +			!ENGINE_set_init_function(e, ibm_4758_cca_init) ||
        +			!ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
        +			!ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
        +			!ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
        +#endif
        +			!ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
        +		return 0;
        +	/* Ensure the error handling is set up */
        +	ERR_load_CCA4758_strings();
        +	return 1;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_4758_cca(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_4758cca(void)
        +	{
        +	ENGINE *e_4758 = engine_4758_cca();
        +	if (!e_4758) return;
        +	ENGINE_add(e_4758);
        +	ENGINE_free(e_4758);
        +	ERR_clear_error();   
        +	}
        +#endif
        +
        +static int ibm_4758_cca_destroy(ENGINE *e)
        +	{
        +	ERR_unload_CCA4758_strings();
        +	free_CCA4758_LIB_NAME();
        +	return 1;
        +	}
        +
        +static int ibm_4758_cca_init(ENGINE *e)
        +	{
        +	if(dso)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
        +		goto err;
        +		}
        +
        +	dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
        +	if(!dso)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
        +		goto err;
        +		}
        +
        +#ifndef OPENSSL_NO_RSA
        +	if(!(keyRecordRead = (F_KEYRECORDREAD)
        +				DSO_bind_func(dso, n_keyRecordRead)) ||
        +			!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
        +				DSO_bind_func(dso, n_randomNumberGenerate)) ||
        +			!(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
        +				DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
        +			!(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
        +				DSO_bind_func(dso, n_digitalSignatureVerify)) ||
        +			!(publicKeyExtract = (F_PUBLICKEYEXTRACT)
        +				DSO_bind_func(dso, n_publicKeyExtract)) ||
        +			!(pkaEncrypt = (F_PKAENCRYPT)
        +				DSO_bind_func(dso, n_pkaEncrypt)) ||
        +			!(pkaDecrypt = (F_PKADECRYPT)
        +				DSO_bind_func(dso, n_pkaDecrypt)))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
        +		goto err;
        +		}
        +#else
        +	if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
        +				DSO_bind_func(dso, n_randomNumberGenerate)))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
        +		goto err;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +	hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
        +		NULL, NULL, cca_ex_free);
        +#endif
        +
        +	return 1;
        +err:
        +	if(dso)
        +		DSO_free(dso);
        +	dso = NULL;
        +
        +#ifndef OPENSSL_NO_RSA
        +	keyRecordRead = (F_KEYRECORDREAD)0;
        +	digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
        +	digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
        +	publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
        +	pkaEncrypt = (F_PKAENCRYPT)0;
        +	pkaDecrypt = (F_PKADECRYPT)0;
        +#endif
        +	randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
        +	return 0;
        +	}
        +
        +static int ibm_4758_cca_finish(ENGINE *e)
        +	{
        +	free_CCA4758_LIB_NAME();
        +	if(!dso)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
        +				CCA4758_R_NOT_LOADED);
        +		return 0;
        +		}
        +	if(!DSO_free(dso))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
        +				CCA4758_R_UNIT_FAILURE);
        +		return 0;
        +		}
        +	dso = NULL;
        +#ifndef OPENSSL_NO_RSA
        +	keyRecordRead = (F_KEYRECORDREAD)0;
        +	randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
        +	digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
        +	digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
        +	publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
        +	pkaEncrypt = (F_PKAENCRYPT)0;
        +	pkaDecrypt = (F_PKADECRYPT)0;
        +#endif
        +	randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
        +	return 1;
        +	}
        +
        +static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int initialised = ((dso == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case CCA4758_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
        +					ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
        +					CCA4758_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		return set_CCA4758_LIB_NAME((const char *)p);
        +	default:
        +		break;
        +		}
        +	CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
        +			CCA4758_R_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +#define MAX_CCA_PKA_TOKEN_SIZE 2500
        +
        +static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
        +			UI_METHOD *ui_method, void *callback_data)
        +	{
        +	RSA *rtmp = NULL;
        +	EVP_PKEY *res = NULL;
        +	unsigned char* keyToken = NULL;
        +	unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
        +	long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
        +	long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
        +	long returnCode;
        +	long reasonCode;
        +	long exitDataLength = 0;
        +	long ruleArrayLength = 0;
        +	unsigned char exitData[8];
        +	unsigned char ruleArray[8];
        +	unsigned char keyLabel[64];
        +	unsigned long keyLabelLength = strlen(key_id);
        +	unsigned char modulus[256];
        +	long modulusFieldLength = sizeof(modulus);
        +	long modulusLength = 0;
        +	unsigned char exponent[256];
        +	long exponentLength = sizeof(exponent);
        +
        +	if (keyLabelLength > sizeof(keyLabel))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
        +		CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +		return NULL;
        +		}
        +
        +	memset(keyLabel,' ', sizeof(keyLabel));
        +	memcpy(keyLabel, key_id, keyLabelLength);
        +
        +	keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
        +	if (!keyToken)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
        +				ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
        +		exitData, &ruleArrayLength, ruleArray, keyLabel,
        +		&keyTokenLength, keyToken+sizeof(long));
        +
        +	if (returnCode)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
        +			CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
        +		goto err;
        +		}
        +
        +	publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
        +		exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
        +		keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
        +
        +	if (returnCode)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
        +			CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
        +		goto err;
        +		}
        +
        +	if (!getModulusAndExponent(pubKeyToken, &exponentLength,
        +			exponent, &modulusLength, &modulusFieldLength,
        +			modulus))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
        +			CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
        +		goto err;
        +		}
        +
        +	(*(long*)keyToken) = keyTokenLength;
        +	rtmp = RSA_new_method(e);
        +	RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
        +
        +	rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
        +	rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
        +	rtmp->flags |= RSA_FLAG_EXT_PKEY;
        +
        +	res = EVP_PKEY_new();
        +	EVP_PKEY_assign_RSA(res, rtmp);
        +
        +	return res;
        +err:
        +	if (keyToken)
        +		OPENSSL_free(keyToken);
        +	return NULL;
        +	}
        +
        +static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
        +			UI_METHOD *ui_method, void *callback_data)
        +	{
        +	RSA *rtmp = NULL;
        +	EVP_PKEY *res = NULL;
        +	unsigned char* keyToken = NULL;
        +	long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
        +	long returnCode;
        +	long reasonCode;
        +	long exitDataLength = 0;
        +	long ruleArrayLength = 0;
        +	unsigned char exitData[8];
        +	unsigned char ruleArray[8];
        +	unsigned char keyLabel[64];
        +	unsigned long keyLabelLength = strlen(key_id);
        +	unsigned char modulus[512];
        +	long modulusFieldLength = sizeof(modulus);
        +	long modulusLength = 0;
        +	unsigned char exponent[512];
        +	long exponentLength = sizeof(exponent);
        +
        +	if (keyLabelLength > sizeof(keyLabel))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
        +			CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +		return NULL;
        +		}
        +
        +	memset(keyLabel,' ', sizeof(keyLabel));
        +	memcpy(keyLabel, key_id, keyLabelLength);
        +
        +	keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
        +	if (!keyToken)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
        +				ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
        +		&ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
        +		keyToken+sizeof(long));
        +
        +	if (returnCode)
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
        +				ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
        +			exponent, &modulusLength, &modulusFieldLength, modulus))
        +		{
        +		CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
        +			CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
        +		goto err;
        +		}
        +
        +	(*(long*)keyToken) = keyTokenLength;
        +	rtmp = RSA_new_method(e);
        +	RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
        +	rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
        +	rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
        +	rtmp->flags |= RSA_FLAG_EXT_PKEY;
        +	res = EVP_PKEY_new();
        +	EVP_PKEY_assign_RSA(res, rtmp);
        +
        +	return res;
        +err:
        +	if (keyToken)
        +		OPENSSL_free(keyToken);
        +	return NULL;
        +	}
        +
        +static int cca_rsa_pub_enc(int flen, const unsigned char *from,
        +			unsigned char *to, RSA *rsa,int padding)
        +	{
        +	long returnCode;
        +	long reasonCode;
        +	long lflen = flen;
        +	long exitDataLength = 0;
        +	unsigned char exitData[8];
        +	long ruleArrayLength = 1;
        +	unsigned char ruleArray[8] = "PKCS-1.2";
        +	long dataStructureLength = 0;
        +	unsigned char dataStructure[8];
        +	long outputLength = RSA_size(rsa);
        +	long keyTokenLength;
        +	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
        +
        +	keyTokenLength = *(long*)keyToken;
        +	keyToken+=sizeof(long);
        +
        +	pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
        +		&ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
        +		&dataStructureLength, dataStructure, &keyTokenLength,
        +		keyToken, &outputLength, to);
        +
        +	if (returnCode || reasonCode)
        +		return -(returnCode << 16 | reasonCode);
        +	return outputLength;
        +	}
        +
        +static int cca_rsa_priv_dec(int flen, const unsigned char *from,
        +			unsigned char *to, RSA *rsa,int padding)
        +	{
        +	long returnCode;
        +	long reasonCode;
        +	long lflen = flen;
        +	long exitDataLength = 0;
        +	unsigned char exitData[8];
        +	long ruleArrayLength = 1;
        +	unsigned char ruleArray[8] = "PKCS-1.2";
        +	long dataStructureLength = 0;
        +	unsigned char dataStructure[8];
        +	long outputLength = RSA_size(rsa);
        +	long keyTokenLength;
        +	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
        +
        +	keyTokenLength = *(long*)keyToken;
        +	keyToken+=sizeof(long);
        +
        +	pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
        +		&ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
        +		&dataStructureLength, dataStructure, &keyTokenLength,
        +		keyToken, &outputLength, to);
        +
        +	return (returnCode | reasonCode) ? 0 : 1;
        +	}
        +
        +#define SSL_SIG_LEN 36
        +
        +static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
        +	const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
        +	{
        +	long returnCode;
        +	long reasonCode;
        +	long lsiglen = siglen;
        +	long exitDataLength = 0;
        +	unsigned char exitData[8];
        +	long ruleArrayLength = 1;
        +	unsigned char ruleArray[8] = "PKCS-1.1";
        +	long keyTokenLength;
        +	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
        +	long length = SSL_SIG_LEN;
        +	long keyLength ;
        +	unsigned char *hashBuffer = NULL;
        +	X509_SIG sig;
        +	ASN1_TYPE parameter;
        +	X509_ALGOR algorithm;
        +	ASN1_OCTET_STRING digest;
        +
        +	keyTokenLength = *(long*)keyToken;
        +	keyToken+=sizeof(long);
        +
        +	if (type == NID_md5 || type == NID_sha1)
        +		{
        +		sig.algor = &algorithm;
        +		algorithm.algorithm = OBJ_nid2obj(type);
        +
        +		if (!algorithm.algorithm)
        +			{
        +			CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
        +				CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
        +			return 0;
        +			}
        +
        +		if (!algorithm.algorithm->length)
        +			{
        +			CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
        +				CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
        +			return 0;
        +			}
        +
        +		parameter.type = V_ASN1_NULL;
        +		parameter.value.ptr = NULL;
        +		algorithm.parameter = &parameter;
        +
        +		sig.digest = &digest;
        +		sig.digest->data = (unsigned char*)m;
        +		sig.digest->length = m_len;
        +
        +		length = i2d_X509_SIG(&sig, NULL);
        +		}
        +
        +	keyLength = RSA_size(rsa);
        +
        +	if (length - RSA_PKCS1_PADDING > keyLength)
        +		{
        +		CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
        +			CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +		return 0;
        +		}
        +
        +	switch (type)
        +		{
        +		case NID_md5_sha1 :
        +			if (m_len != SSL_SIG_LEN)
        +				{
        +				CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
        +				CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +				return 0;
        +				}
        +
        +			hashBuffer = (unsigned char *)m;
        +			length = m_len;
        +			break;
        +		case NID_md5 :
        +			{
        +			unsigned char *ptr;
        +			ptr = hashBuffer = OPENSSL_malloc(
        +					(unsigned int)keyLength+1);
        +			if (!hashBuffer)
        +				{
        +				CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
        +						ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +
        +			i2d_X509_SIG(&sig, &ptr);
        +			}
        +			break;
        +		case NID_sha1 :
        +			{
        +			unsigned char *ptr;
        +			ptr = hashBuffer = OPENSSL_malloc(
        +					(unsigned int)keyLength+1);
        +			if (!hashBuffer)
        +				{
        +				CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
        +						ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +			i2d_X509_SIG(&sig, &ptr);
        +			}
        +			break;
        +		default:
        +			return 0;
        +		}
        +
        +	digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
        +		exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
        +		keyToken, &length, hashBuffer, &lsiglen,
        +						(unsigned char *)sigbuf);
        +
        +	if (type == NID_sha1 || type == NID_md5)
        +		{
        +		OPENSSL_cleanse(hashBuffer, keyLength+1);
        +		OPENSSL_free(hashBuffer);
        +		}
        +
        +	return ((returnCode || reasonCode) ? 0 : 1);
        +	}
        +
        +#define SSL_SIG_LEN 36
        +
        +static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
        +		unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
        +	{
        +	long returnCode;
        +	long reasonCode;
        +	long exitDataLength = 0;
        +	unsigned char exitData[8];
        +	long ruleArrayLength = 1;
        +	unsigned char ruleArray[8] = "PKCS-1.1";
        +	long outputLength=256;
        +	long outputBitLength;
        +	long keyTokenLength;
        +	unsigned char *hashBuffer = NULL;
        +	unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
        +	long length = SSL_SIG_LEN;
        +	long keyLength ;
        +	X509_SIG sig;
        +	ASN1_TYPE parameter;
        +	X509_ALGOR algorithm;
        +	ASN1_OCTET_STRING digest;
        +
        +	keyTokenLength = *(long*)keyToken;
        +	keyToken+=sizeof(long);
        +
        +	if (type == NID_md5 || type == NID_sha1)
        +		{
        +		sig.algor = &algorithm;
        +		algorithm.algorithm = OBJ_nid2obj(type);
        +
        +		if (!algorithm.algorithm)
        +			{
        +			CCA4758err(CCA4758_F_CCA_RSA_SIGN,
        +				CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
        +			return 0;
        +			}
        +
        +		if (!algorithm.algorithm->length)
        +			{
        +			CCA4758err(CCA4758_F_CCA_RSA_SIGN,
        +				CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
        +			return 0;
        +			}
        +
        +		parameter.type = V_ASN1_NULL;
        +		parameter.value.ptr = NULL;
        +		algorithm.parameter = &parameter;
        +
        +		sig.digest = &digest;
        +		sig.digest->data = (unsigned char*)m;
        +		sig.digest->length = m_len;
        +
        +		length = i2d_X509_SIG(&sig, NULL);
        +		}
        +
        +	keyLength = RSA_size(rsa);
        +
        +	if (length - RSA_PKCS1_PADDING > keyLength)
        +		{
        +		CCA4758err(CCA4758_F_CCA_RSA_SIGN,
        +			CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +		return 0;
        +		}
        +
        +	switch (type)
        +		{
        +		case NID_md5_sha1 :
        +			if (m_len != SSL_SIG_LEN)
        +				{
        +				CCA4758err(CCA4758_F_CCA_RSA_SIGN,
        +				CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +				return 0;
        +				}
        +			hashBuffer = (unsigned char*)m;
        +			length = m_len;
        +			break;
        +		case NID_md5 :
        +			{
        +			unsigned char *ptr;
        +			ptr = hashBuffer = OPENSSL_malloc(
        +					(unsigned int)keyLength+1);
        +			if (!hashBuffer)
        +				{
        +				CCA4758err(CCA4758_F_CCA_RSA_SIGN,
        +						ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +			i2d_X509_SIG(&sig, &ptr);
        +			}
        +			break;
        +		case NID_sha1 :
        +			{
        +			unsigned char *ptr;
        +			ptr = hashBuffer = OPENSSL_malloc(
        +					(unsigned int)keyLength+1);
        +			if (!hashBuffer)
        +				{
        +				CCA4758err(CCA4758_F_CCA_RSA_SIGN,
        +						ERR_R_MALLOC_FAILURE);
        +				return 0;
        +				}
        +			i2d_X509_SIG(&sig, &ptr);
        +			}
        +			break;
        +		default:
        +			return 0;
        +		}
        +
        +	digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
        +		exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
        +		keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
        +		sigret);
        +
        +	if (type == NID_sha1 || type == NID_md5)
        +		{
        +		OPENSSL_cleanse(hashBuffer, keyLength+1);
        +		OPENSSL_free(hashBuffer);
        +		}
        +
        +	*siglen = outputLength;
        +
        +	return ((returnCode || reasonCode) ? 0 : 1);
        +	}
        +
        +static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
        +		unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
        +		unsigned char *modulus)
        +	{
        +	unsigned long len;
        +
        +	if (*token++ != (char)0x1E) /* internal PKA token? */
        +		return 0;
        +
        +	if (*token++) /* token version must be zero */
        +		return 0;
        +
        +	len = *token++;
        +	len = len << 8;
        +	len |= (unsigned char)*token++;
        +
        +	token += 4; /* skip reserved bytes */
        +
        +	if (*token++ == (char)0x04)
        +		{
        +		if (*token++) /* token version must be zero */
        +			return 0;
        +
        +		len = *token++;
        +		len = len << 8;
        +		len |= (unsigned char)*token++;
        +
        +		token+=2; /* skip reserved section */
        +
        +		len = *token++;
        +		len = len << 8;
        +		len |= (unsigned char)*token++;
        +
        +		*exponentLength = len;
        +
        +		len = *token++;
        +		len = len << 8;
        +		len |= (unsigned char)*token++;
        +
        +		*modulusLength = len;
        +
        +		len = *token++;
        +		len = len << 8;
        +		len |= (unsigned char)*token++;
        +
        +		*modulusFieldLength = len;
        +
        +		memcpy(exponent, token, *exponentLength);
        +		token+= *exponentLength;
        +
        +		memcpy(modulus, token, *modulusFieldLength);
        +		return 1;
        +		}
        +	return 0;
        +	}
        +
        +#endif /* OPENSSL_NO_RSA */
        +
        +static int cca_random_status(void)
        +	{
        +	return 1;
        +	}
        +
        +static int cca_get_random_bytes(unsigned char* buf, int num)
        +	{
        +	long ret_code;
        +	long reason_code;
        +	long exit_data_length;
        +	unsigned char exit_data[4];
        +	unsigned char form[] = "RANDOM  ";
        +	unsigned char rand_buf[8];
        +
        +	while(num >= (int)sizeof(rand_buf))
        +		{
        +		randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
        +			exit_data, form, rand_buf);
        +		if (ret_code)
        +			return 0;
        +		num -= sizeof(rand_buf);
        +		memcpy(buf, rand_buf, sizeof(rand_buf));
        +		buf += sizeof(rand_buf);
        +		}
        +
        +	if (num)
        +		{
        +		randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
        +			form, rand_buf);
        +		if (ret_code)
        +			return 0;
        +		memcpy(buf, rand_buf, num);
        +		}
        +
        +	return 1;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
        +		long argl, void *argp)
        +	{
        +	if (item)
        +		OPENSSL_free(item);
        +	}
        +#endif
        +
        +/* Goo to handle building as a dynamic engine */
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_4758_cca_id) != 0) &&
        +			(strcmp(id, engine_4758_cca_id_alt) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW_4758_CCA */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_4758cca.ec b/vendor/openssl/openssl/engines/e_4758cca.ec
        new file mode 100644
        index 000000000..f30ed02c0
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_4758cca.ec
        @@ -0,0 +1 @@
        +L CCA4758	e_4758cca_err.h		e_4758cca_err.c
        diff --git a/vendor/openssl/openssl/engines/e_4758cca_err.c b/vendor/openssl/openssl/engines/e_4758cca_err.c
        new file mode 100644
        index 000000000..6ecdc6e62
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_4758cca_err.c
        @@ -0,0 +1,153 @@
        +/* e_4758cca_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_4758cca_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA CCA4758_str_functs[]=
        +	{
        +{ERR_FUNC(CCA4758_F_CCA_RSA_SIGN),	"CCA_RSA_SIGN"},
        +{ERR_FUNC(CCA4758_F_CCA_RSA_VERIFY),	"CCA_RSA_VERIFY"},
        +{ERR_FUNC(CCA4758_F_IBM_4758_CCA_CTRL),	"IBM_4758_CCA_CTRL"},
        +{ERR_FUNC(CCA4758_F_IBM_4758_CCA_FINISH),	"IBM_4758_CCA_FINISH"},
        +{ERR_FUNC(CCA4758_F_IBM_4758_CCA_INIT),	"IBM_4758_CCA_INIT"},
        +{ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PRIVKEY),	"IBM_4758_LOAD_PRIVKEY"},
        +{ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PUBKEY),	"IBM_4758_LOAD_PUBKEY"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CCA4758_str_reasons[]=
        +	{
        +{ERR_REASON(CCA4758_R_ALREADY_LOADED)    ,"already loaded"},
        +{ERR_REASON(CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD),"asn1 oid unknown for md"},
        +{ERR_REASON(CCA4758_R_COMMAND_NOT_IMPLEMENTED),"command not implemented"},
        +{ERR_REASON(CCA4758_R_DSO_FAILURE)       ,"dso failure"},
        +{ERR_REASON(CCA4758_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
        +{ERR_REASON(CCA4758_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
        +{ERR_REASON(CCA4758_R_NOT_LOADED)        ,"not loaded"},
        +{ERR_REASON(CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
        +{ERR_REASON(CCA4758_R_UNIT_FAILURE)      ,"unit failure"},
        +{ERR_REASON(CCA4758_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef CCA4758_LIB_NAME
        +static ERR_STRING_DATA CCA4758_lib_name[]=
        +        {
        +{0	,CCA4758_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int CCA4758_lib_error_code=0;
        +static int CCA4758_error_init=1;
        +
        +static void ERR_load_CCA4758_strings(void)
        +	{
        +	if (CCA4758_lib_error_code == 0)
        +		CCA4758_lib_error_code=ERR_get_next_error_library();
        +
        +	if (CCA4758_error_init)
        +		{
        +		CCA4758_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_functs);
        +		ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
        +#endif
        +
        +#ifdef CCA4758_LIB_NAME
        +		CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code,0,0);
        +		ERR_load_strings(0,CCA4758_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_CCA4758_strings(void)
        +	{
        +	if (CCA4758_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_functs);
        +		ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
        +#endif
        +
        +#ifdef CCA4758_LIB_NAME
        +		ERR_unload_strings(0,CCA4758_lib_name);
        +#endif
        +		CCA4758_error_init=1;
        +		}
        +	}
        +
        +static void ERR_CCA4758_error(int function, int reason, char *file, int line)
        +	{
        +	if (CCA4758_lib_error_code == 0)
        +		CCA4758_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(CCA4758_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_4758cca_err.h b/vendor/openssl/openssl/engines/e_4758cca_err.h
        new file mode 100644
        index 000000000..26087edbf
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_4758cca_err.h
        @@ -0,0 +1,97 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_CCA4758_ERR_H
        +#define HEADER_CCA4758_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_CCA4758_strings(void);
        +static void ERR_unload_CCA4758_strings(void);
        +static void ERR_CCA4758_error(int function, int reason, char *file, int line);
        +#define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the CCA4758 functions. */
        +
        +/* Function codes. */
        +#define CCA4758_F_CCA_RSA_SIGN				 105
        +#define CCA4758_F_CCA_RSA_VERIFY			 106
        +#define CCA4758_F_IBM_4758_CCA_CTRL			 100
        +#define CCA4758_F_IBM_4758_CCA_FINISH			 101
        +#define CCA4758_F_IBM_4758_CCA_INIT			 102
        +#define CCA4758_F_IBM_4758_LOAD_PRIVKEY			 103
        +#define CCA4758_F_IBM_4758_LOAD_PUBKEY			 104
        +
        +/* Reason codes. */
        +#define CCA4758_R_ALREADY_LOADED			 100
        +#define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD		 101
        +#define CCA4758_R_COMMAND_NOT_IMPLEMENTED		 102
        +#define CCA4758_R_DSO_FAILURE				 103
        +#define CCA4758_R_FAILED_LOADING_PRIVATE_KEY		 104
        +#define CCA4758_R_FAILED_LOADING_PUBLIC_KEY		 105
        +#define CCA4758_R_NOT_LOADED				 106
        +#define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 107
        +#define CCA4758_R_UNIT_FAILURE				 108
        +#define CCA4758_R_UNKNOWN_ALGORITHM_TYPE		 109
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_aep.c b/vendor/openssl/openssl/engines/e_aep.c
        new file mode 100644
        index 000000000..1953f0643
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_aep.c
        @@ -0,0 +1,1139 @@
        +/* ====================================================================
        + * 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 <stdio.h>
        +#include <openssl/bn.h>
        +#include <string.h>
        +
        +#include <openssl/e_os2.h>
        +#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__)
        +#include <sys/types.h>
        +#include <unistd.h>
        +#else
        +#include <process.h>
        +typedef int pid_t;
        +#endif
        +
        +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
        +#define getpid GetThreadID
        +extern int GetThreadID(void);
        +#elif defined(_WIN32) && !defined(__WATCOMC__)
        +#define getpid _getpid
        +#endif
        +
        +#include <openssl/crypto.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#include <openssl/buffer.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_AEP
        +#ifdef FLAT_INC
        +#include "aep.h"
        +#else
        +#include "vendor_defns/aep.h"
        +#endif
        +
        +#define AEP_LIB_NAME "aep engine"
        +#define FAIL_TO_SW 0x10101010
        +
        +#include "e_aep_err.c"
        +
        +static int aep_init(ENGINE *e);
        +static int aep_finish(ENGINE *e);
        +static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +static int aep_destroy(ENGINE *e);
        +
        +static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
        +static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
        +static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
        +static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
        +
        +/* BIGNUM stuff */
        +#ifndef OPENSSL_NO_RSA
        +static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx);
        +
        +static AEP_RV aep_mod_exp_crt(BIGNUM *r,const  BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
        +	const BIGNUM *iqmp, BN_CTX *ctx);
        +#endif
        +
        +/* RSA stuff */
        +#ifndef OPENSSL_NO_RSA
        +static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +#endif
        +
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +#ifndef OPENSSL_NO_RSA
        +static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* DSA stuff */
        +#ifndef OPENSSL_NO_DSA
        +static int aep_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 aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +	BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* DH stuff */
        +/* This function is aliased to mod_exp (with the DH and mont dropped). */
        +#ifndef OPENSSL_NO_DH
        +static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* rand stuff   */
        +#ifdef AEPRAND
        +static int aep_rand(unsigned char *buf, int num);
        +static int aep_rand_status(void);
        +#endif
        +
        +/* Bignum conversion stuff */
        +static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
        +static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
        +	unsigned char* AEP_BigNum);
        +static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
        +	unsigned char* AEP_BigNum);
        +
        +/* The definitions for control commands specific to this engine */
        +#define AEP_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN aep_cmd_defns[] =
        +	{
        +	{ AEP_CMD_SO_PATH,
        +	  "SO_PATH",
        +	  "Specifies the path to the 'aep' shared library",
        +	  ENGINE_CMD_FLAG_STRING
        +	},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD aep_rsa =
        +	{
        +	"Aep RSA method",
        +	NULL,                /*rsa_pub_encrypt*/
        +	NULL,                /*rsa_pub_decrypt*/
        +	NULL,                /*rsa_priv_encrypt*/
        +	NULL,                /*rsa_priv_encrypt*/
        +	aep_rsa_mod_exp,     /*rsa_mod_exp*/
        +	aep_mod_exp_mont,    /*bn_mod_exp*/
        +	NULL,                /*init*/
        +	NULL,                /*finish*/
        +	0,                   /*flags*/
        +	NULL,                /*app_data*/
        +	NULL,                /*rsa_sign*/
        +	NULL,                /*rsa_verify*/
        +	NULL                 /*rsa_keygen*/
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* Our internal DSA_METHOD that we provide pointers to */
        +static DSA_METHOD aep_dsa =
        +	{
        +	"Aep DSA method",
        +	NULL,                /* dsa_do_sign */
        +	NULL,                /* dsa_sign_setup */
        +	NULL,                /* dsa_do_verify */
        +	aep_dsa_mod_exp,     /* dsa_mod_exp */
        +	aep_mod_exp_dsa,     /* bn_mod_exp */
        +	NULL,                /* init */
        +	NULL,                /* finish */
        +	0,                   /* flags */
        +	NULL,                /* app_data */
        +	NULL,                /* dsa_paramgen */
        +	NULL                 /* dsa_keygen */
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* Our internal DH_METHOD that we provide pointers to */
        +static DH_METHOD aep_dh =
        +	{
        +	"Aep DH method",
        +	NULL,
        +	NULL,
        +	aep_mod_exp_dh,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +#ifdef AEPRAND
        +/* our internal RAND_method that we provide pointers to  */
        +static RAND_METHOD aep_random =
        +	{
        +	/*"AEP RAND method", */
        +	NULL,
        +	aep_rand,
        +	NULL,
        +	NULL,
        +	aep_rand,
        +	aep_rand_status,
        +	};
        +#endif
        +
        +/*Define an array of structures to hold connections*/
        +static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
        +
        +/*Used to determine if this is a new process*/
        +static pid_t    recorded_pid = 0;
        +
        +#ifdef AEPRAND
        +static AEP_U8   rand_block[RAND_BLK_SIZE];
        +static AEP_U32  rand_block_bytes = 0;
        +#endif
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_aep_id = "aep";
        +static const char *engine_aep_name = "Aep hardware engine support";
        +
        +static int max_key_len = 2176;
        +
        +
        +/* This internal function is used by ENGINE_aep() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_aep(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD  *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	const DSA_METHOD  *meth2;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD	  *meth3;
        +#endif
        +
        +	if(!ENGINE_set_id(e, engine_aep_id) ||
        +		!ENGINE_set_name(e, engine_aep_name) ||
        +#ifndef OPENSSL_NO_RSA
        +		!ENGINE_set_RSA(e, &aep_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +		!ENGINE_set_DSA(e, &aep_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		!ENGINE_set_DH(e, &aep_dh) ||
        +#endif
        +#ifdef AEPRAND
        +		!ENGINE_set_RAND(e, &aep_random) ||
        +#endif
        +		!ENGINE_set_init_function(e, aep_init) ||
        +		!ENGINE_set_destroy_function(e, aep_destroy) ||
        +		!ENGINE_set_finish_function(e, aep_finish) ||
        +		!ENGINE_set_ctrl_function(e, aep_ctrl) ||
        +		!ENGINE_set_cmd_defns(e, aep_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* We know that the "PKCS1_SSLeay()" functions hook properly
        +	 * to the aep-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();
        +	aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
        +	aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
        +	aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
        +	aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
        +#endif
        +
        +
        +#ifndef OPENSSL_NO_DSA
        +	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
        +	 * bits. */
        +	meth2 = DSA_OpenSSL();
        +	aep_dsa.dsa_do_sign    = meth2->dsa_do_sign;
        +	aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
        +	aep_dsa.dsa_do_verify  = meth2->dsa_do_verify;
        +
        +	aep_dsa = *DSA_get_default_method(); 
        +	aep_dsa.dsa_mod_exp = aep_dsa_mod_exp; 
        +	aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth3 = DH_OpenSSL();
        +	aep_dh.generate_key = meth3->generate_key;
        +	aep_dh.compute_key  = meth3->compute_key;
        +	aep_dh.bn_mod_exp   = meth3->bn_mod_exp;
        +#endif
        +
        +	/* Ensure the aep error handling is set up */
        +	ERR_load_AEPHK_strings();
        +
        +	return 1;
        +}
        +
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_helper(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_aep_id) != 0))
        +		return 0;
        +	if(!bind_aep(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
        +#else
        +static ENGINE *engine_aep(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_aep(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_aep(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_aep();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* This is a process-global DSO handle used for loading and unloading
        + * the Aep 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 *aep_dso = NULL;
        +
        +/* These are the static string constants for the DSO file name and the function
        + * symbol names to bind to. 
        +*/
        +static const char *AEP_LIBNAME = NULL;
        +static const char *get_AEP_LIBNAME(void)
        +	{
        +	if(AEP_LIBNAME)
        +		return AEP_LIBNAME;
        +	return "aep";
        +	}
        +static void free_AEP_LIBNAME(void)
        +	{
        +	if(AEP_LIBNAME)
        +		OPENSSL_free((void*)AEP_LIBNAME);
        +	AEP_LIBNAME = NULL;
        +	}
        +static long set_AEP_LIBNAME(const char *name)
        +	{
        +	free_AEP_LIBNAME();
        +	return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
        +	}
        +
        +static const char *AEP_F1    = "AEP_ModExp";
        +static const char *AEP_F2    = "AEP_ModExpCrt";
        +#ifdef AEPRAND
        +static const char *AEP_F3    = "AEP_GenRandom";
        +#endif
        +static const char *AEP_F4    = "AEP_Finalize";
        +static const char *AEP_F5    = "AEP_Initialize";
        +static const char *AEP_F6    = "AEP_OpenConnection";
        +static const char *AEP_F7    = "AEP_SetBNCallBacks";
        +static const char *AEP_F8    = "AEP_CloseConnection";
        +
        +/* These are the function pointers that are (un)set when the library has
        + * successfully (un)loaded. */
        +static t_AEP_OpenConnection    *p_AEP_OpenConnection  = NULL;
        +static t_AEP_CloseConnection   *p_AEP_CloseConnection = NULL;
        +static t_AEP_ModExp            *p_AEP_ModExp          = NULL;
        +static t_AEP_ModExpCrt         *p_AEP_ModExpCrt       = NULL;
        +#ifdef AEPRAND
        +static t_AEP_GenRandom         *p_AEP_GenRandom       = NULL;
        +#endif
        +static t_AEP_Initialize        *p_AEP_Initialize      = NULL;
        +static t_AEP_Finalize          *p_AEP_Finalize        = NULL;
        +static t_AEP_SetBNCallBacks    *p_AEP_SetBNCallBacks  = NULL;
        +
        +/* (de)initialisation functions. */
        +static int aep_init(ENGINE *e)
        +	{
        +	t_AEP_ModExp          *p1;
        +	t_AEP_ModExpCrt       *p2;
        +#ifdef AEPRAND
        +	t_AEP_GenRandom       *p3;
        +#endif
        +	t_AEP_Finalize        *p4;
        +	t_AEP_Initialize      *p5;
        +	t_AEP_OpenConnection  *p6;
        +	t_AEP_SetBNCallBacks  *p7;
        +	t_AEP_CloseConnection *p8;
        +
        +	int to_return = 0;
        + 
        +	if(aep_dso != NULL)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
        +		goto err;
        +		}
        +	/* Attempt to load libaep.so. */
        +
        +	aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
        +  
        +	if(aep_dso == NULL)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
        +		goto err;
        +		}
        +
        +	if(	!(p1 = (t_AEP_ModExp *)     DSO_bind_func( aep_dso,AEP_F1))  ||
        +		!(p2 = (t_AEP_ModExpCrt*)   DSO_bind_func( aep_dso,AEP_F2))  ||
        +#ifdef AEPRAND
        +		!(p3 = (t_AEP_GenRandom*)   DSO_bind_func( aep_dso,AEP_F3))  ||
        +#endif
        +		!(p4 = (t_AEP_Finalize*)    DSO_bind_func( aep_dso,AEP_F4))  ||
        +		!(p5 = (t_AEP_Initialize*)  DSO_bind_func( aep_dso,AEP_F5))  ||
        +		!(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6))  ||
        +		!(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7))  ||
        +		!(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
        +		{
        +		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
        +		goto err;
        +		}
        +
        +	/* Copy the pointers */
        +  
        +	p_AEP_ModExp           = p1;
        +	p_AEP_ModExpCrt        = p2;
        +#ifdef AEPRAND
        +	p_AEP_GenRandom        = p3;
        +#endif
        +	p_AEP_Finalize         = p4;
        +	p_AEP_Initialize       = p5;
        +	p_AEP_OpenConnection   = p6;
        +	p_AEP_SetBNCallBacks   = p7;
        +	p_AEP_CloseConnection  = p8;
        + 
        +	to_return = 1;
        + 
        +	return to_return;
        +
        + err: 
        +
        +	if(aep_dso)
        +		DSO_free(aep_dso);
        +	aep_dso = NULL;
        +		
        +	p_AEP_OpenConnection    = NULL;
        +	p_AEP_ModExp            = NULL;
        +	p_AEP_ModExpCrt         = NULL;
        +#ifdef AEPRAND
        +	p_AEP_GenRandom         = NULL;
        +#endif
        +	p_AEP_Initialize        = NULL;
        +	p_AEP_Finalize          = NULL;
        +	p_AEP_SetBNCallBacks    = NULL;
        +	p_AEP_CloseConnection   = NULL;
        +
        +	return to_return;
        +	}
        +
        +/* Destructor (complements the "ENGINE_aep()" constructor) */
        +static int aep_destroy(ENGINE *e)
        +	{
        +	free_AEP_LIBNAME();
        +	ERR_unload_AEPHK_strings();
        +	return 1;
        +	}
        +
        +static int aep_finish(ENGINE *e)
        +	{
        +	int to_return = 0, in_use;
        +	AEP_RV rv;
        +
        +	if(aep_dso == NULL)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
        +		goto err;
        +		}
        +
        +	rv = aep_close_all_connections(0, &in_use);
        +	if (rv != AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
        +		goto err;
        +		}
        +	if (in_use)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
        +		goto err;
        +		}
        +
        +	rv = p_AEP_Finalize();
        +	if (rv != AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
        +		goto err;
        +		}
        +
        +	if(!DSO_free(aep_dso))
        +		{
        +		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +
        +	aep_dso = NULL;
        +	p_AEP_CloseConnection   = NULL;
        +	p_AEP_OpenConnection    = NULL;
        +	p_AEP_ModExp            = NULL;
        +	p_AEP_ModExpCrt         = NULL;
        +#ifdef AEPRAND
        +	p_AEP_GenRandom         = NULL;
        +#endif
        +	p_AEP_Initialize        = NULL;
        +	p_AEP_Finalize          = NULL;
        +	p_AEP_SetBNCallBacks    = NULL;
        +
        +	to_return = 1;
        + err:
        +	return to_return;
        +	}
        +
        +static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int initialised = ((aep_dso == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case AEP_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_CTRL,
        +				ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_CTRL,
        +				AEPHK_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		return set_AEP_LIBNAME((const char*)p);
        +	default:
        +		break;
        +		}
        +	AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	int to_return = 0;
        +	int 	r_len = 0;
        +	AEP_CONNECTION_HNDL hConnection;
        +	AEP_RV rv;
        +	
        +	r_len = BN_num_bits(m);
        +
        +	/* Perform in software if modulus is too large for hardware. */
        +
        +	if (r_len > max_key_len){
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +		return BN_mod_exp(r, a, p, m, ctx);
        +	} 
        +
        +	/*Grab a connection from the pool*/
        +	rv = aep_get_connection(&hConnection);
        +	if (rv != AEP_R_OK)
        +		{     
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
        +		return BN_mod_exp(r, a, p, m, ctx);
        +		}
        +
        +	/*To the card with the mod exp*/
        +	rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
        +
        +	if (rv !=  AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
        +		rv = aep_close_connection(hConnection);
        +		return BN_mod_exp(r, a, p, m, ctx);
        +		}
        +
        +	/*Return the connection to the pool*/
        +	rv = aep_return_connection(hConnection);
        +	if (rv != AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_RETURN_CONNECTION_FAILED); 
        +		goto err;
        +		}
        +
        +	to_return = 1;
        + err:
        +	return to_return;
        +	}
        +	
        +#ifndef OPENSSL_NO_RSA
        +static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *q, const BIGNUM *dmp1,
        +	const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
        +	{
        +	AEP_RV rv = AEP_R_OK;
        +	AEP_CONNECTION_HNDL hConnection;
        +
        +	/*Grab a connection from the pool*/
        +	rv = aep_get_connection(&hConnection);
        +	if (rv != AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
        +		return FAIL_TO_SW;
        +		}
        +
        +	/*To the card with the mod exp*/
        +	rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
        +		(void*)iqmp,(void*)r,NULL);
        +	if (rv != AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
        +		rv = aep_close_connection(hConnection);
        +		return FAIL_TO_SW;
        +		}
        +
        +	/*Return the connection to the pool*/
        +	rv = aep_return_connection(hConnection);
        +	if (rv != AEP_R_OK)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_RETURN_CONNECTION_FAILED); 
        +		goto err;
        +		}
        + 
        + err:
        +	return rv;
        +	}
        +#endif
        +	
        +
        +#ifdef AEPRAND
        +static int aep_rand(unsigned char *buf,int len )
        +	{
        +	AEP_RV rv = AEP_R_OK;
        +	AEP_CONNECTION_HNDL hConnection;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +
        +	/*Can the request be serviced with what's already in the buffer?*/
        +	if (len <= rand_block_bytes)
        +		{
        +		memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
        +		rand_block_bytes -= len;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +		}
        +	else
        +		/*If not the get another block of random bytes*/
        +		{
        +		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +
        +		rv = aep_get_connection(&hConnection);
        +		if (rv !=  AEP_R_OK)
        +			{ 
        +			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);             
        +			goto err_nounlock;
        +			}
        +
        +		if (len > RAND_BLK_SIZE)
        +			{
        +			rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
        +			if (rv !=  AEP_R_OK)
        +				{  
        +				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
        +				goto err_nounlock;
        +				}
        +			}
        +		else
        +			{
        +			CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        +
        +			rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
        +			if (rv !=  AEP_R_OK)
        +				{       
        +				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
        +	      
        +				goto err;
        +				}
        +
        +			rand_block_bytes = RAND_BLK_SIZE;
        +
        +			memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
        +			rand_block_bytes -= len;
        +
        +			CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        +			}
        +
        +		rv = aep_return_connection(hConnection);
        +		if (rv != AEP_R_OK)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
        +	  
        +			goto err_nounlock;
        +			}
        +		}
        +  
        +	return 1;
        + err:
        +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
        + err_nounlock:
        +	return 0;
        +	}
        +	
        +static int aep_rand_status(void)
        +{
        +	return 1;
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	int to_return = 0;
        +	AEP_RV rv = AEP_R_OK;
        +
        +	if (!aep_dso)
        +		{
        +		AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
        +		goto err;
        +		}
        +
        +	/*See if we have all the necessary bits for a crt*/
        +	if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
        +		{
        +		rv =  aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
        +
        +		if (rv == FAIL_TO_SW){
        +			const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +			to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
        +			goto err;
        +		}
        +		else if (rv != AEP_R_OK)
        +			goto err;
        +		}
        +	else
        +		{
        +		if (!rsa->d || !rsa->n)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
        +			goto err;
        +			}
        + 
        +		rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
        +		if  (rv != AEP_R_OK)
        +			goto err;
        +	
        +		}
        +
        +	to_return = 1;
        +
        + err:
        +	return to_return;
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +static int aep_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 (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
        +	/* let t = a2 ^ p2 mod m */
        +	if (!aep_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 aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +	BN_MONT_CTX *m_ctx)
        +	{  
        +	return aep_mod_exp(r, a, p, m, ctx); 
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	return aep_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +	BN_MONT_CTX *m_ctx)
        +	{
        +	return aep_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +
        +static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
        +	{
        +	int count;
        +	AEP_RV rv = AEP_R_OK;
        +
        +	/*Get the current process id*/
        +	pid_t curr_pid;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +
        +	curr_pid = getpid();
        +
        +	/*Check if this is the first time this is being called from the current
        +	  process*/
        +	if (recorded_pid != curr_pid)
        +		{
        +		/*Remember our pid so we can check if we're in a new process*/
        +		recorded_pid = curr_pid;
        +
        +		/*Call Finalize to make sure we have not inherited some data
        +		  from a parent process*/
        +		p_AEP_Finalize();
        +     
        +		/*Initialise the AEP API*/
        +		rv = p_AEP_Initialize(NULL);
        +
        +		if (rv != AEP_R_OK)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
        +			recorded_pid = 0;
        +			goto end;
        +			}
        +
        +		/*Set the AEP big num call back functions*/
        +		rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
        +			&ConvertAEPBigNum);
        +
        +		if (rv != AEP_R_OK)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
        +			recorded_pid = 0;
        +			goto end;
        +			}
        +
        +#ifdef AEPRAND
        +		/*Reset the rand byte count*/
        +		rand_block_bytes = 0;
        +#endif
        +
        +		/*Init the structures*/
        +		for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
        +			{
        +			aep_app_conn_table[count].conn_state = NotConnected;
        +			aep_app_conn_table[count].conn_hndl  = 0;
        +			}
        +
        +		/*Open a connection*/
        +		rv = p_AEP_OpenConnection(phConnection);
        +
        +		if (rv != AEP_R_OK)
        +			{
        +			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
        +			recorded_pid = 0;
        +			goto end;
        +			}
        +
        +		aep_app_conn_table[0].conn_state = InUse;
        +		aep_app_conn_table[0].conn_hndl = *phConnection;
        +		goto end;
        +		}
        +	/*Check the existing connections to see if we can find a free one*/
        +	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
        +		{
        +		if (aep_app_conn_table[count].conn_state == Connected)
        +			{
        +			aep_app_conn_table[count].conn_state = InUse;
        +			*phConnection = aep_app_conn_table[count].conn_hndl;
        +			goto end;
        +			}
        +		}
        +	/*If no connections available, we're going to have to try
        +	  to open a new one*/
        +	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
        +		{
        +		if (aep_app_conn_table[count].conn_state == NotConnected)
        +			{
        +			/*Open a connection*/
        +			rv = p_AEP_OpenConnection(phConnection);
        +
        +			if (rv != AEP_R_OK)
        +				{	      
        +				AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
        +				goto end;
        +				}
        +
        +			aep_app_conn_table[count].conn_state = InUse;
        +			aep_app_conn_table[count].conn_hndl = *phConnection;
        +			goto end;
        +			}
        +		}
        +	rv = AEP_R_GENERAL_ERROR;
        + end:
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return rv;
        +	}
        +
        +
        +static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
        +	{
        +	int count;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +
        +	/*Find the connection item that matches this connection handle*/
        +	for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
        +		{
        +		if (aep_app_conn_table[count].conn_hndl == hConnection)
        +			{
        +			aep_app_conn_table[count].conn_state = Connected;
        +			break;
        +			}
        +		}
        +
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +
        +	return AEP_R_OK;
        +	}
        +
        +static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
        +	{
        +	int count;
        +	AEP_RV rv = AEP_R_OK;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +
        +	/*Find the connection item that matches this connection handle*/
        +	for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
        +		{
        +		if (aep_app_conn_table[count].conn_hndl == hConnection)
        +			{
        +			rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
        +			if (rv != AEP_R_OK)
        +				goto end;
        +			aep_app_conn_table[count].conn_state = NotConnected;
        +			aep_app_conn_table[count].conn_hndl  = 0;
        +			break;
        +			}
        +		}
        +
        + end:
        +	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return rv;
        +	}
        +
        +static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
        +	{
        +	int count;
        +	AEP_RV rv = AEP_R_OK;
        +
        +	*in_use = 0;
        +	if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
        +		{
        +		switch (aep_app_conn_table[count].conn_state)
        +			{
        +		case Connected:
        +			rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
        +			if (rv != AEP_R_OK)
        +				goto end;
        +			aep_app_conn_table[count].conn_state = NotConnected;
        +			aep_app_conn_table[count].conn_hndl  = 0;
        +			break;
        +		case InUse:
        +			(*in_use)++;
        +			break;
        +		case NotConnected:
        +			break;
        +			}
        +		}
        + end:
        +	if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +	return rv;
        +	}
        +
        +/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
        +  Note only 32bit Openssl build support*/
        +
        +static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
        +	{
        +	BIGNUM* bn;
        +
        +	/*Cast the ArbBigNum pointer to our BIGNUM struct*/
        +	bn = (BIGNUM*) ArbBigNum;
        +
        +#ifdef SIXTY_FOUR_BIT_LONG
        +	*BigNumSize = bn->top << 3;
        +#else
        +	/*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
        +	  words) multiplies by 4*/
        +	*BigNumSize = bn->top << 2;
        +#endif
        +
        +	return AEP_R_OK;
        +	}
        +
        +static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
        +	unsigned char* AEP_BigNum)
        +	{
        +	BIGNUM* bn;
        +
        +#ifndef SIXTY_FOUR_BIT_LONG
        +	unsigned char* buf;
        +	int i;
        +#endif
        +
        +	/*Cast the ArbBigNum pointer to our BIGNUM struct*/
        +	bn = (BIGNUM*) ArbBigNum;
        +
        +#ifdef SIXTY_FOUR_BIT_LONG
        +  	memcpy(AEP_BigNum, bn->d, BigNumSize);
        +#else
        +	/*Must copy data into a (monotone) least significant byte first format
        +	  performing endian conversion if necessary*/
        +	for(i=0;i<bn->top;i++)
        +		{
        +		buf = (unsigned char*)&bn->d[i];
        +
        +		*((AEP_U32*)AEP_BigNum) = (AEP_U32)
        +			((unsigned) buf[1] << 8 | buf[0]) |
        +			((unsigned) buf[3] << 8 | buf[2])  << 16;
        +
        +		AEP_BigNum += 4;
        +		}
        +#endif
        +
        +	return AEP_R_OK;
        +	}
        +
        +/*Turn an AEP Big Num back to a user big num*/
        +static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
        +	unsigned char* AEP_BigNum)
        +	{
        +	BIGNUM* bn;
        +#ifndef SIXTY_FOUR_BIT_LONG
        +	int i;
        +#endif
        +
        +	bn = (BIGNUM*)ArbBigNum;
        +
        +	/*Expand the result bn so that it can hold our big num.
        +	  Size is in bits*/
        +	bn_expand(bn, (int)(BigNumSize << 3));
        +
        +#ifdef SIXTY_FOUR_BIT_LONG
        +	bn->top = BigNumSize >> 3;
        +	
        +	if((BigNumSize & 7) != 0)
        +		bn->top++;
        +
        +	memset(bn->d, 0, bn->top << 3);	
        +
        +	memcpy(bn->d, AEP_BigNum, BigNumSize);
        +#else
        +	bn->top = BigNumSize >> 2;
        + 
        +	for(i=0;i<bn->top;i++)
        +		{
        +		bn->d[i] = (AEP_U32)
        +			((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
        +			((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
        +		AEP_BigNum += 4;
        +		}
        +#endif
        +
        +	return AEP_R_OK;
        +}	
        +	
        +#endif /* !OPENSSL_NO_HW_AEP */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_aep.ec b/vendor/openssl/openssl/engines/e_aep.ec
        new file mode 100644
        index 000000000..8eae642e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_aep.ec
        @@ -0,0 +1 @@
        +L AEPHK		e_aep_err.h			e_aep_err.c
        diff --git a/vendor/openssl/openssl/engines/e_aep_err.c b/vendor/openssl/openssl/engines/e_aep_err.c
        new file mode 100644
        index 000000000..3f95881ca
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_aep_err.c
        @@ -0,0 +1,161 @@
        +/* e_aep_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_aep_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA AEPHK_str_functs[]=
        +	{
        +{ERR_FUNC(AEPHK_F_AEP_CTRL),	"AEP_CTRL"},
        +{ERR_FUNC(AEPHK_F_AEP_FINISH),	"AEP_FINISH"},
        +{ERR_FUNC(AEPHK_F_AEP_GET_CONNECTION),	"AEP_GET_CONNECTION"},
        +{ERR_FUNC(AEPHK_F_AEP_INIT),	"AEP_INIT"},
        +{ERR_FUNC(AEPHK_F_AEP_MOD_EXP),	"AEP_MOD_EXP"},
        +{ERR_FUNC(AEPHK_F_AEP_MOD_EXP_CRT),	"AEP_MOD_EXP_CRT"},
        +{ERR_FUNC(AEPHK_F_AEP_RAND),	"AEP_RAND"},
        +{ERR_FUNC(AEPHK_F_AEP_RSA_MOD_EXP),	"AEP_RSA_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA AEPHK_str_reasons[]=
        +	{
        +{ERR_REASON(AEPHK_R_ALREADY_LOADED)      ,"already loaded"},
        +{ERR_REASON(AEPHK_R_CLOSE_HANDLES_FAILED),"close handles failed"},
        +{ERR_REASON(AEPHK_R_CONNECTIONS_IN_USE)  ,"connections in use"},
        +{ERR_REASON(AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(AEPHK_R_FINALIZE_FAILED)     ,"finalize failed"},
        +{ERR_REASON(AEPHK_R_GET_HANDLE_FAILED)   ,"get handle failed"},
        +{ERR_REASON(AEPHK_R_GET_RANDOM_FAILED)   ,"get random failed"},
        +{ERR_REASON(AEPHK_R_INIT_FAILURE)        ,"init failure"},
        +{ERR_REASON(AEPHK_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{ERR_REASON(AEPHK_R_MOD_EXP_CRT_FAILED)  ,"mod exp crt failed"},
        +{ERR_REASON(AEPHK_R_MOD_EXP_FAILED)      ,"mod exp failed"},
        +{ERR_REASON(AEPHK_R_NOT_LOADED)          ,"not loaded"},
        +{ERR_REASON(AEPHK_R_OK)                  ,"ok"},
        +{ERR_REASON(AEPHK_R_RETURN_CONNECTION_FAILED),"return connection failed"},
        +{ERR_REASON(AEPHK_R_SETBNCALLBACK_FAILURE),"setbncallback failure"},
        +{ERR_REASON(AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
        +{ERR_REASON(AEPHK_R_UNIT_FAILURE)        ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef AEPHK_LIB_NAME
        +static ERR_STRING_DATA AEPHK_lib_name[]=
        +        {
        +{0	,AEPHK_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int AEPHK_lib_error_code=0;
        +static int AEPHK_error_init=1;
        +
        +static void ERR_load_AEPHK_strings(void)
        +	{
        +	if (AEPHK_lib_error_code == 0)
        +		AEPHK_lib_error_code=ERR_get_next_error_library();
        +
        +	if (AEPHK_error_init)
        +		{
        +		AEPHK_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_functs);
        +		ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
        +#endif
        +
        +#ifdef AEPHK_LIB_NAME
        +		AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code,0,0);
        +		ERR_load_strings(0,AEPHK_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_AEPHK_strings(void)
        +	{
        +	if (AEPHK_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_functs);
        +		ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
        +#endif
        +
        +#ifdef AEPHK_LIB_NAME
        +		ERR_unload_strings(0,AEPHK_lib_name);
        +#endif
        +		AEPHK_error_init=1;
        +		}
        +	}
        +
        +static void ERR_AEPHK_error(int function, int reason, char *file, int line)
        +	{
        +	if (AEPHK_lib_error_code == 0)
        +		AEPHK_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(AEPHK_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_aep_err.h b/vendor/openssl/openssl/engines/e_aep_err.h
        new file mode 100644
        index 000000000..35b2e7426
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_aep_err.h
        @@ -0,0 +1,105 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_AEPHK_ERR_H
        +#define HEADER_AEPHK_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_AEPHK_strings(void);
        +static void ERR_unload_AEPHK_strings(void);
        +static void ERR_AEPHK_error(int function, int reason, char *file, int line);
        +#define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the AEPHK functions. */
        +
        +/* Function codes. */
        +#define AEPHK_F_AEP_CTRL				 100
        +#define AEPHK_F_AEP_FINISH				 101
        +#define AEPHK_F_AEP_GET_CONNECTION			 102
        +#define AEPHK_F_AEP_INIT				 103
        +#define AEPHK_F_AEP_MOD_EXP				 104
        +#define AEPHK_F_AEP_MOD_EXP_CRT				 105
        +#define AEPHK_F_AEP_RAND				 106
        +#define AEPHK_F_AEP_RSA_MOD_EXP				 107
        +
        +/* Reason codes. */
        +#define AEPHK_R_ALREADY_LOADED				 100
        +#define AEPHK_R_CLOSE_HANDLES_FAILED			 101
        +#define AEPHK_R_CONNECTIONS_IN_USE			 102
        +#define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
        +#define AEPHK_R_FINALIZE_FAILED				 104
        +#define AEPHK_R_GET_HANDLE_FAILED			 105
        +#define AEPHK_R_GET_RANDOM_FAILED			 106
        +#define AEPHK_R_INIT_FAILURE				 107
        +#define AEPHK_R_MISSING_KEY_COMPONENTS			 108
        +#define AEPHK_R_MOD_EXP_CRT_FAILED			 109
        +#define AEPHK_R_MOD_EXP_FAILED				 110
        +#define AEPHK_R_NOT_LOADED				 111
        +#define AEPHK_R_OK					 112
        +#define AEPHK_R_RETURN_CONNECTION_FAILED		 113
        +#define AEPHK_R_SETBNCALLBACK_FAILURE			 114
        +#define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 116
        +#define AEPHK_R_UNIT_FAILURE				 115
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_atalla.c b/vendor/openssl/openssl/engines/e_atalla.c
        new file mode 100644
        index 000000000..fabaa86a5
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_atalla.c
        @@ -0,0 +1,607 @@
        +/* crypto/engine/hw_atalla.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_ATALLA
        +
        +#ifdef FLAT_INC
        +#include "atalla.h"
        +#else
        +#include "vendor_defns/atalla.h"
        +#endif
        +
        +#define ATALLA_LIB_NAME "atalla engine"
        +#include "e_atalla_err.c"
        +
        +static int atalla_destroy(ENGINE *e);
        +static int atalla_init(ENGINE *e);
        +static int atalla_finish(ENGINE *e);
        +static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +
        +/* BIGNUM stuff */
        +static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx);
        +
        +#ifndef OPENSSL_NO_RSA
        +/* RSA stuff */
        +static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* 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);
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* DH stuff */
        +/* This function is alised to mod_exp (with the DH and mont dropped). */
        +static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
        +		const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* The definitions for control commands specific to this engine */
        +#define ATALLA_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
        +	{ATALLA_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'atasi' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* 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,
        +	NULL
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* 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 */
        +	NULL, /* dsa_paramgen */
        +	NULL /* dsa_keygen */
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* 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,
        +	NULL
        +	};
        +#endif
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_atalla_id = "atalla";
        +static const char *engine_atalla_name = "Atalla hardware engine support";
        +
        +/* This internal function is used by ENGINE_atalla() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	const DSA_METHOD *meth2;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth3;
        +#endif
        +	if(!ENGINE_set_id(e, engine_atalla_id) ||
        +			!ENGINE_set_name(e, engine_atalla_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &atalla_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			!ENGINE_set_DSA(e, &atalla_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH(e, &atalla_dh) ||
        +#endif
        +			!ENGINE_set_destroy_function(e, atalla_destroy) ||
        +			!ENGINE_set_init_function(e, atalla_init) ||
        +			!ENGINE_set_finish_function(e, atalla_finish) ||
        +			!ENGINE_set_ctrl_function(e, atalla_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, atalla_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* 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;
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	/* 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;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth3 = DH_OpenSSL();
        +	atalla_dh.generate_key = meth3->generate_key;
        +	atalla_dh.compute_key = meth3->compute_key;
        +#endif
        +
        +	/* Ensure the atalla error handling is set up */
        +	ERR_load_ATALLA_strings();
        +	return 1;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_atalla(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_atalla(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_atalla();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* 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;
        +
        +/* 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 = NULL;
        +static const char *get_ATALLA_LIBNAME(void)
        +	{
        +		if(ATALLA_LIBNAME)
        +			return ATALLA_LIBNAME;
        +		return "atasi";
        +	}
        +static void free_ATALLA_LIBNAME(void)
        +	{
        +		if(ATALLA_LIBNAME)
        +			OPENSSL_free((void*)ATALLA_LIBNAME);
        +		ATALLA_LIBNAME = NULL;
        +	}
        +static long set_ATALLA_LIBNAME(const char *name)
        +	{
        +	free_ATALLA_LIBNAME();
        +	return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
        +	}
        +static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
        +static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
        +static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
        +
        +/* Destructor (complements the "ENGINE_atalla()" constructor) */
        +static int atalla_destroy(ENGINE *e)
        +	{
        +	free_ATALLA_LIBNAME();
        +	/* Unload the atalla error strings so any error state including our
        +	 * functs or reasons won't lead to a segfault (they simply get displayed
        +	 * without corresponding string data because none will be found). */
        +	ERR_unload_ATALLA_strings();
        +	return 1;
        +	}
        +
        +/* (de)initialisation functions. */
        +static int atalla_init(ENGINE *e)
        +	{
        +	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)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_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, get_ATALLA_LIBNAME(), NULL, 0);
        +	if(atalla_dso == NULL)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
        +		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)))
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
        +		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)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	/* Everything's fine. */
        +	return 1;
        +err:
        +	if(atalla_dso)
        +		DSO_free(atalla_dso);
        +	atalla_dso = NULL;
        +	p_Atalla_GetHardwareConfig = NULL;
        +	p_Atalla_RSAPrivateKeyOpFn = NULL;
        +	p_Atalla_GetPerformanceStatistics = NULL;
        +	return 0;
        +	}
        +
        +static int atalla_finish(ENGINE *e)
        +	{
        +	free_ATALLA_LIBNAME();
        +	if(atalla_dso == NULL)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
        +		return 0;
        +		}
        +	if(!DSO_free(atalla_dso))
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
        +		return 0;
        +		}
        +	atalla_dso = NULL;
        +	p_Atalla_GetHardwareConfig = NULL;
        +	p_Atalla_RSAPrivateKeyOpFn = NULL;
        +	p_Atalla_GetPerformanceStatistics = NULL;
        +	return 1;
        +	}
        +
        +static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int initialised = ((atalla_dso == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case ATALLA_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		return set_ATALLA_LIBNAME((const char *)p);
        +	default:
        +		break;
        +		}
        +	ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +static int atalla_mod_exp(BIGNUM *r, const 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 <grin>. 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)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
        +		goto err;
        +		}
        +	/* Prepare the params */
        +	BN_CTX_start(ctx);
        +	modulus = BN_CTX_get(ctx);
        +	exponent = BN_CTX_get(ctx);
        +	argument = BN_CTX_get(ctx);
        +	result = BN_CTX_get(ctx);
        +	if (!result)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_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))
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_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)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
        +		goto err;
        +		}
        +	/* Convert the response */
        +	BN_bin2bn((unsigned char *)result->d, numbytes, r);
        +	to_return = 1;
        +err:
        +	BN_CTX_end(ctx);
        +	return to_return;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	int to_return = 0;
        +
        +	if(!atalla_dso)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
        +		goto err;
        +		}
        +	if(!rsa->d || !rsa->n)
        +		{
        +		ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
        +		goto err;
        +		}
        +	to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
        +err:
        +	return to_return;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* 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);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int atalla_mod_exp_mont(BIGNUM *r, const 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
        +
        +#ifndef OPENSSL_NO_DH
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
        +		const 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
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_atalla_id) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW_ATALLA */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_atalla.ec b/vendor/openssl/openssl/engines/e_atalla.ec
        new file mode 100644
        index 000000000..1d735e1b2
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_atalla.ec
        @@ -0,0 +1 @@
        +L ATALLA	e_atalla_err.h			e_atalla_err.c
        diff --git a/vendor/openssl/openssl/engines/e_atalla_err.c b/vendor/openssl/openssl/engines/e_atalla_err.c
        new file mode 100644
        index 000000000..fd3e0049c
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_atalla_err.c
        @@ -0,0 +1,149 @@
        +/* e_atalla_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_atalla_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA ATALLA_str_functs[]=
        +	{
        +{ERR_FUNC(ATALLA_F_ATALLA_CTRL),	"ATALLA_CTRL"},
        +{ERR_FUNC(ATALLA_F_ATALLA_FINISH),	"ATALLA_FINISH"},
        +{ERR_FUNC(ATALLA_F_ATALLA_INIT),	"ATALLA_INIT"},
        +{ERR_FUNC(ATALLA_F_ATALLA_MOD_EXP),	"ATALLA_MOD_EXP"},
        +{ERR_FUNC(ATALLA_F_ATALLA_RSA_MOD_EXP),	"ATALLA_RSA_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ATALLA_str_reasons[]=
        +	{
        +{ERR_REASON(ATALLA_R_ALREADY_LOADED)     ,"already loaded"},
        +{ERR_REASON(ATALLA_R_BN_CTX_FULL)        ,"bn ctx full"},
        +{ERR_REASON(ATALLA_R_BN_EXPAND_FAIL)     ,"bn expand fail"},
        +{ERR_REASON(ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(ATALLA_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{ERR_REASON(ATALLA_R_NOT_LOADED)         ,"not loaded"},
        +{ERR_REASON(ATALLA_R_REQUEST_FAILED)     ,"request failed"},
        +{ERR_REASON(ATALLA_R_UNIT_FAILURE)       ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef ATALLA_LIB_NAME
        +static ERR_STRING_DATA ATALLA_lib_name[]=
        +        {
        +{0	,ATALLA_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int ATALLA_lib_error_code=0;
        +static int ATALLA_error_init=1;
        +
        +static void ERR_load_ATALLA_strings(void)
        +	{
        +	if (ATALLA_lib_error_code == 0)
        +		ATALLA_lib_error_code=ERR_get_next_error_library();
        +
        +	if (ATALLA_error_init)
        +		{
        +		ATALLA_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_functs);
        +		ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
        +#endif
        +
        +#ifdef ATALLA_LIB_NAME
        +		ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code,0,0);
        +		ERR_load_strings(0,ATALLA_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_ATALLA_strings(void)
        +	{
        +	if (ATALLA_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_functs);
        +		ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
        +#endif
        +
        +#ifdef ATALLA_LIB_NAME
        +		ERR_unload_strings(0,ATALLA_lib_name);
        +#endif
        +		ATALLA_error_init=1;
        +		}
        +	}
        +
        +static void ERR_ATALLA_error(int function, int reason, char *file, int line)
        +	{
        +	if (ATALLA_lib_error_code == 0)
        +		ATALLA_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(ATALLA_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_atalla_err.h b/vendor/openssl/openssl/engines/e_atalla_err.h
        new file mode 100644
        index 000000000..36e09bf42
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_atalla_err.h
        @@ -0,0 +1,93 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_ATALLA_ERR_H
        +#define HEADER_ATALLA_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_ATALLA_strings(void);
        +static void ERR_unload_ATALLA_strings(void);
        +static void ERR_ATALLA_error(int function, int reason, char *file, int line);
        +#define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the ATALLA functions. */
        +
        +/* Function codes. */
        +#define ATALLA_F_ATALLA_CTRL				 100
        +#define ATALLA_F_ATALLA_FINISH				 101
        +#define ATALLA_F_ATALLA_INIT				 102
        +#define ATALLA_F_ATALLA_MOD_EXP				 103
        +#define ATALLA_F_ATALLA_RSA_MOD_EXP			 104
        +
        +/* Reason codes. */
        +#define ATALLA_R_ALREADY_LOADED				 100
        +#define ATALLA_R_BN_CTX_FULL				 101
        +#define ATALLA_R_BN_EXPAND_FAIL				 102
        +#define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
        +#define ATALLA_R_MISSING_KEY_COMPONENTS			 104
        +#define ATALLA_R_NOT_LOADED				 105
        +#define ATALLA_R_REQUEST_FAILED				 106
        +#define ATALLA_R_UNIT_FAILURE				 107
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_capi.c b/vendor/openssl/openssl/engines/e_capi.c
        new file mode 100644
        index 000000000..c1085b56c
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_capi.c
        @@ -0,0 +1,1842 @@
        +/* engines/e_capi.c */
        +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        + * project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2008 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.
        + * ====================================================================
        + */
        +
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/bn.h>
        +
        +#ifdef OPENSSL_SYS_WIN32
        +#ifndef OPENSSL_NO_CAPIENG
        +
        +#include <openssl/rsa.h>
        +
        +#include <windows.h>
        +
        +#ifndef _WIN32_WINNT
        +#define _WIN32_WINNT 0x0400
        +#endif
        +
        +#include <wincrypt.h>
        +
        +/*
        + * This module uses several "new" interfaces, among which is
        + * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
        + * one of possible values you can pass to function in question. By
        + * checking if it's defined we can see if wincrypt.h and accompanying
        + * crypt32.lib are in shape. The native MingW32 headers up to and
        + * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
        + * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
        + * so we check for these too and avoid compiling.
        + * Yes, it's rather "weak" test and if compilation fails,
        + * then re-configure with -DOPENSSL_NO_CAPIENG.
        + */
        +#if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
        +    defined(CERT_STORE_PROV_SYSTEM_A) && \
        +    defined(CERT_STORE_READONLY_FLAG)
        +# define __COMPILE_CAPIENG
        +#endif /* CERT_KEY_PROV_INFO_PROP_ID */
        +#endif /* OPENSSL_NO_CAPIENG */
        +#endif /* OPENSSL_SYS_WIN32 */
        +
        +#ifdef __COMPILE_CAPIENG
        +
        +#undef X509_EXTENSIONS
        +#undef X509_CERT_PAIR
        +
        +/* Definitions which may be missing from earlier version of headers */
        +#ifndef CERT_STORE_OPEN_EXISTING_FLAG
        +#define CERT_STORE_OPEN_EXISTING_FLAG                   0x00004000
        +#endif
        +
        +#ifndef CERT_STORE_CREATE_NEW_FLAG
        +#define CERT_STORE_CREATE_NEW_FLAG                      0x00002000
        +#endif
        +
        +#ifndef CERT_SYSTEM_STORE_CURRENT_USER
        +#define CERT_SYSTEM_STORE_CURRENT_USER			0x00010000
        +#endif 
        +
        +#include <openssl/engine.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +
        +#include "e_capi_err.h"
        +#include "e_capi_err.c"
        +
        +
        +static const char *engine_capi_id = "capi";
        +static const char *engine_capi_name = "CryptoAPI ENGINE";
        +
        +typedef struct CAPI_CTX_st CAPI_CTX;
        +typedef struct CAPI_KEY_st CAPI_KEY;
        +
        +static void capi_addlasterror(void);
        +static void capi_adderror(DWORD err);
        +
        +static void CAPI_trace(CAPI_CTX *ctx, char *format, ...);
        +
        +static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
        +static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
        +int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
        +void capi_free_key(CAPI_KEY *key);
        +
        +static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
        +
        +CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id);
        +
        +static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
        +             unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
        +static int capi_rsa_priv_enc(int flen, const unsigned char *from,
        +                unsigned char *to, RSA *rsa, int padding);
        +static int capi_rsa_priv_dec(int flen, const unsigned char *from,
        +                unsigned char *to, RSA *rsa, int padding);
        +static int capi_rsa_free(RSA *rsa);
        +
        +static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
        +							DSA *dsa);
        +static int capi_dsa_free(DSA *dsa);
        +
        +static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
        +	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
        +	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
        +
        +static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
        +#ifdef OPENSSL_CAPIENG_DIALOG
        +static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
        +#endif
        +
        +typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR,
        +						LPCWSTR, DWORD, DWORD,
        +						void *);
        +typedef HWND (WINAPI *GETCONSWIN)(void);
        +
        +/* This structure contains CAPI ENGINE specific data:
        + * it contains various global options and affects how
        + * other functions behave.
        + */
        +
        +#define CAPI_DBG_TRACE	2
        +#define CAPI_DBG_ERROR	1
        +
        +struct CAPI_CTX_st {
        +	int debug_level;
        +	char *debug_file;
        +	/* Parameters to use for container lookup */
        +	DWORD keytype;
        +	LPSTR cspname;
        +	DWORD csptype;
        +	/* Certificate store name to use */
        +	LPSTR storename;
        +	LPSTR ssl_client_store;
        +	/* System store flags */
        +	DWORD store_flags;
        +
        +/* Lookup string meanings in load_private_key */
        +/* Substring of subject: uses "storename" */
        +#define CAPI_LU_SUBSTR		1
        +/* Friendly name: uses storename */
        +#define CAPI_LU_FNAME		2
        +/* Container name: uses cspname, keytype */
        +#define CAPI_LU_CONTNAME	3
        +	int lookup_method;
        +/* Info to dump with dumpcerts option */
        +/* Issuer and serial name strings */
        +#define CAPI_DMP_SUMMARY	0x1
        +/* Friendly name */
        +#define CAPI_DMP_FNAME		0x2
        +/* Full X509_print dump */
        +#define CAPI_DMP_FULL		0x4
        +/* Dump PEM format certificate */
        +#define CAPI_DMP_PEM		0x8
        +/* Dump pseudo key (if possible) */
        +#define CAPI_DMP_PSKEY		0x10
        +/* Dump key info (if possible) */
        +#define CAPI_DMP_PKEYINFO	0x20
        +
        +	DWORD dump_flags;
        +	int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
        +
        +	CERTDLG certselectdlg;
        +	GETCONSWIN getconswindow;
        +};
        +
        +
        +static CAPI_CTX *capi_ctx_new();
        +static void capi_ctx_free(CAPI_CTX *ctx);
        +static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check);
        +static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx);
        +
        +#define CAPI_CMD_LIST_CERTS		ENGINE_CMD_BASE
        +#define CAPI_CMD_LOOKUP_CERT		(ENGINE_CMD_BASE + 1)
        +#define CAPI_CMD_DEBUG_LEVEL		(ENGINE_CMD_BASE + 2)
        +#define CAPI_CMD_DEBUG_FILE		(ENGINE_CMD_BASE + 3)
        +#define CAPI_CMD_KEYTYPE		(ENGINE_CMD_BASE + 4)
        +#define CAPI_CMD_LIST_CSPS		(ENGINE_CMD_BASE + 5)
        +#define CAPI_CMD_SET_CSP_IDX		(ENGINE_CMD_BASE + 6)
        +#define CAPI_CMD_SET_CSP_NAME		(ENGINE_CMD_BASE + 7)
        +#define CAPI_CMD_SET_CSP_TYPE		(ENGINE_CMD_BASE + 8)
        +#define CAPI_CMD_LIST_CONTAINERS	(ENGINE_CMD_BASE + 9)
        +#define CAPI_CMD_LIST_OPTIONS		(ENGINE_CMD_BASE + 10)
        +#define CAPI_CMD_LOOKUP_METHOD		(ENGINE_CMD_BASE + 11)
        +#define CAPI_CMD_STORE_NAME		(ENGINE_CMD_BASE + 12)
        +#define CAPI_CMD_STORE_FLAGS		(ENGINE_CMD_BASE + 13)
        +
        +static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
        +	{CAPI_CMD_LIST_CERTS,
        +		"list_certs",
        +		"List all certificates in store",
        +		ENGINE_CMD_FLAG_NO_INPUT},
        +	{CAPI_CMD_LOOKUP_CERT,
        +		"lookup_cert",
        +		"Lookup and output certificates",
        +		ENGINE_CMD_FLAG_STRING},
        +	{CAPI_CMD_DEBUG_LEVEL,
        +		"debug_level",
        +		"debug level (1=errors, 2=trace)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{CAPI_CMD_DEBUG_FILE,
        +		"debug_file",
        +		"debugging filename)",
        +		ENGINE_CMD_FLAG_STRING},
        +	{CAPI_CMD_KEYTYPE,
        +		"key_type",
        +		"Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{CAPI_CMD_LIST_CSPS,
        +		"list_csps",
        +		"List all CSPs",
        +		ENGINE_CMD_FLAG_NO_INPUT},
        +	{CAPI_CMD_SET_CSP_IDX,
        +		"csp_idx",
        +		"Set CSP by index",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{CAPI_CMD_SET_CSP_NAME,
        +		"csp_name",
        +		"Set CSP name, (default CSP used if not specified)",
        +		ENGINE_CMD_FLAG_STRING},
        +	{CAPI_CMD_SET_CSP_TYPE,
        +		"csp_type",
        +		"Set CSP type, (default RSA_PROV_FULL)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{CAPI_CMD_LIST_CONTAINERS,
        +		"list_containers",
        +		"list container names",
        +		ENGINE_CMD_FLAG_NO_INPUT},
        +	{CAPI_CMD_LIST_OPTIONS,
        +		"list_options",
        +		"Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
        +		"32=private key info)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{CAPI_CMD_LOOKUP_METHOD,
        +		"lookup_method",
        +		"Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{CAPI_CMD_STORE_NAME,
        +		"store_name",
        +		"certificate store name, default \"MY\"",
        +		ENGINE_CMD_FLAG_STRING},
        +	{CAPI_CMD_STORE_FLAGS,
        +		"store_flags",
        +		"Certificate store flags: 1 = system store",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +
        +	{0, NULL, NULL, 0}
        +	};
        +
        +static int capi_idx = -1;
        +static int rsa_capi_idx = -1;
        +static int dsa_capi_idx = -1;
        +static int cert_capi_idx = -1;
        +
        +static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int ret = 1;
        +	CAPI_CTX *ctx;
        +	BIO *out;
        +	if (capi_idx == -1)
        +		{
        +		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
        +		return 0;
        +		}
        +	ctx = ENGINE_get_ex_data(e, capi_idx);
        +	out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +	switch (cmd)
        +		{
        +		case CAPI_CMD_LIST_CSPS:
        +		ret = capi_list_providers(ctx, out);
        +		break;
        +
        +		case CAPI_CMD_LIST_CERTS:
        +		ret = capi_list_certs(ctx, out, NULL);
        +		break;
        +
        +		case CAPI_CMD_LOOKUP_CERT:
        +		ret = capi_list_certs(ctx, out, p);
        +		break;
        +
        +		case CAPI_CMD_LIST_CONTAINERS:
        +		ret = capi_list_containers(ctx, out);
        +		break;
        +
        +		case CAPI_CMD_STORE_NAME:
        +		if (ctx->storename)
        +			OPENSSL_free(ctx->storename);
        +		ctx->storename = BUF_strdup(p);
        +		CAPI_trace(ctx, "Setting store name to %s\n", p);
        +		break;
        +
        +		case CAPI_CMD_STORE_FLAGS:
        +		if (i & 1)
        +			{
        +			ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
        +			ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
        +			}
        +		else
        +			{
        +			ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
        +			ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
        +			}
        +		CAPI_trace(ctx, "Setting flags to %d\n", i);
        +		break;
        +
        +		case CAPI_CMD_DEBUG_LEVEL:
        +		ctx->debug_level = (int)i;
        +		CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
        +		break;
        +
        +		case CAPI_CMD_DEBUG_FILE:
        +		ctx->debug_file = BUF_strdup(p);
        +		CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
        +		break;
        +
        +		case CAPI_CMD_KEYTYPE:
        +		ctx->keytype = i;
        +		CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
        +		break;
        +
        +		case CAPI_CMD_SET_CSP_IDX:
        +		ret = capi_ctx_set_provname_idx(ctx, i);
        +		break;
        +
        +		case CAPI_CMD_LIST_OPTIONS:
        +		ctx->dump_flags = i;
        +		break;
        +
        +		case CAPI_CMD_LOOKUP_METHOD:
        +		if (i < 1 || i > 3)
        +			{
        +			CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
        +			return 0;
        +			}
        +		ctx->lookup_method = i;
        +		break;
        +
        +		case CAPI_CMD_SET_CSP_NAME:
        +		ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
        +		break;
        +
        +		case CAPI_CMD_SET_CSP_TYPE:
        +		ctx->csptype = i;
        +		break;
        +
        +		default:
        +		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
        +		ret = 0;
        +	}
        +
        +	BIO_free(out);
        +	return ret;
        +
        +	}
        +
        +static RSA_METHOD capi_rsa_method =
        +	{
        +	"CryptoAPI RSA method",
        +	0,				/* pub_enc */
        +	0,				/* pub_dec */
        +	capi_rsa_priv_enc,		/* priv_enc */
        +	capi_rsa_priv_dec,		/* priv_dec */
        +	0,				/* rsa_mod_exp */
        +	0,				/* bn_mod_exp */
        +	0,				/* init	*/
        +	capi_rsa_free,			/* finish */
        +	RSA_FLAG_SIGN_VER, 		/* flags */
        +	NULL,				/* app_data */
        +	capi_rsa_sign,			/* rsa_sign */
        +	0				/* rsa_verify */
        +	};
        +
        +static DSA_METHOD capi_dsa_method =
        +	{
        +	"CryptoAPI DSA method",
        +	capi_dsa_do_sign,		/* dsa_do_sign */
        +	0,				/* dsa_sign_setup */
        +	0,				/* dsa_do_verify */
        +	0,				/* dsa_mod_exp */
        +	0,				/* bn_mod_exp */
        +	0,				/* init	*/
        +	capi_dsa_free,			/* finish */
        +	0, 				/* flags */
        +	NULL,				/* app_data */
        +	0,				/* dsa_paramgen */
        +	0				/* dsa_keygen */
        +	};
        +
        +static int capi_init(ENGINE *e)
        +	{
        +	CAPI_CTX *ctx;
        +	const RSA_METHOD *ossl_rsa_meth;
        +	const DSA_METHOD *ossl_dsa_meth;
        +
        +	if (capi_idx < 0)
        +		{
        +		capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
        +		if (capi_idx < 0)
        +			goto memerr;
        +
        +		cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
        +
        +		/* Setup RSA_METHOD */
        +		rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
        +		ossl_rsa_meth = RSA_PKCS1_SSLeay();
        +		capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
        +		capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
        +		capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
        +		capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
        +
        +		/* Setup DSA Method */
        +		dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
        +		ossl_dsa_meth = DSA_OpenSSL();
        +		capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
        +		capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
        +		capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
        +		}
        +
        +	ctx = capi_ctx_new();
        +	if (!ctx)
        +		goto memerr;
        +
        +	ENGINE_set_ex_data(e, capi_idx, ctx);
        +
        +#ifdef OPENSSL_CAPIENG_DIALOG
        +	{
        +	HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
        +	HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
        +	if (cryptui)
        +		ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
        +	if (kernel)
        +		ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
        +	if (cryptui && !OPENSSL_isservice())
        +		ctx->client_cert_select = cert_select_dialog;
        +	}
        +#endif
        +		
        +
        +	return 1;
        +
        +	memerr:
        +	CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
        +	return 0;
        +
        +	return 1;
        +	}
        +
        +static int capi_destroy(ENGINE *e)
        +	{
        +	ERR_unload_CAPI_strings();
        +	return 1;
        +	}
        +
        +static int capi_finish(ENGINE *e)
        +	{
        +	CAPI_CTX *ctx;
        +	ctx = ENGINE_get_ex_data(e, capi_idx);
        +	capi_ctx_free(ctx);
        +	ENGINE_set_ex_data(e, capi_idx, NULL);
        +	return 1;
        +	}
        +
        +
        +/* CryptoAPI key application data. This contains
        + * a handle to the private key container (for sign operations)
        + * and a handle to the key (for decrypt operations).
        + */
        +
        +struct CAPI_KEY_st
        +	{
        +	/* Associated certificate context (if any) */
        +	PCCERT_CONTEXT pcert;
        +	HCRYPTPROV hprov;
        +	HCRYPTKEY key;
        +	DWORD keyspec;
        +	};
        +
        +static int bind_capi(ENGINE *e)
        +	{
        +	if (!ENGINE_set_id(e, engine_capi_id)
        +		|| !ENGINE_set_name(e, engine_capi_name)
        +		|| !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)
        +		|| !ENGINE_set_init_function(e, capi_init)
        +		|| !ENGINE_set_finish_function(e, capi_finish)
        +		|| !ENGINE_set_destroy_function(e, capi_destroy)
        +		|| !ENGINE_set_RSA(e, &capi_rsa_method)
        +		|| !ENGINE_set_DSA(e, &capi_dsa_method)
        +		|| !ENGINE_set_load_privkey_function(e, capi_load_privkey)
        +		|| !ENGINE_set_load_ssl_client_cert_function(e,
        +						capi_load_ssl_client_cert)
        +		|| !ENGINE_set_cmd_defns(e, capi_cmd_defns)
        +		|| !ENGINE_set_ctrl_function(e, capi_ctrl))
        +			return 0;
        +	ERR_load_CAPI_strings();
        +
        +	return 1;
        +
        +	}
        +
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_helper(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_capi_id) != 0))
        +		return 0;
        +	if(!bind_capi(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
        +#else
        +static ENGINE *engine_capi(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_capi(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_capi(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_capi();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +
        +static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
        +	{
        +	int i;
        +	/* Reverse buffer in place: since this is a keyblob structure
        +	 * that will be freed up after conversion anyway it doesn't 
        +	 * matter if we change it.
        +	 */
        +	for(i = 0; i < binlen / 2; i++)
        +		{
        +		unsigned char c;
        +		c = bin[i];
        +		bin[i] = bin[binlen - i - 1];
        +		bin[binlen - i - 1] = c;
        +		}
        +
        +	if (!BN_bin2bn(bin, binlen, bn))
        +		return 0;
        +	return 1;
        +	}
        +
        +/* Given a CAPI_KEY get an EVP_PKEY structure */
        +
        +static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key)
        +	{
        +	unsigned char *pubkey = NULL;
        +	DWORD len;
        +	BLOBHEADER *bh;
        +	RSA *rkey = NULL;
        +	DSA *dkey = NULL;
        +	EVP_PKEY *ret = NULL;
        +	if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len))
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
        +		capi_addlasterror();
        +		return NULL;
        +		}
        +
        +	pubkey = OPENSSL_malloc(len);
        +
        +	if (!pubkey)
        +		goto memerr;
        +
        +	if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len))
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +
        +	bh = (BLOBHEADER *)pubkey;
        +	if (bh->bType != PUBLICKEYBLOB)
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
        +		goto err;
        +		}
        +	if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX)
        +		{
        +		RSAPUBKEY *rp;
        +		DWORD rsa_modlen;
        +		unsigned char *rsa_modulus;
        +		rp = (RSAPUBKEY *)(bh + 1);
        +		if (rp->magic != 0x31415352)
        +			{
        +			char magstr[10];
        +			BIO_snprintf(magstr, 10, "%lx", rp->magic);
        +			CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
        +			ERR_add_error_data(2, "magic=0x", magstr);
        +			goto err;
        +			}
        +		rsa_modulus = (unsigned char *)(rp + 1);
        +		rkey = RSA_new_method(eng);
        +		if (!rkey)
        +			goto memerr;
        +
        +		rkey->e = BN_new();
        +		rkey->n = BN_new();
        +
        +		if (!rkey->e || !rkey->n)
        +			goto memerr;
        +
        +		if (!BN_set_word(rkey->e, rp->pubexp))
        +			goto memerr;
        +
        +		rsa_modlen = rp->bitlen / 8;
        +		if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
        +			goto memerr;
        +
        +		RSA_set_ex_data(rkey, rsa_capi_idx, key);
        +
        +		if (!(ret = EVP_PKEY_new()))
        +			goto memerr;
        +
        +		EVP_PKEY_assign_RSA(ret, rkey);
        +		rkey = NULL;
        +
        +		}
        +	else if (bh->aiKeyAlg == CALG_DSS_SIGN)
        +		{
        +		DSSPUBKEY *dp;
        +		DWORD dsa_plen;
        +		unsigned char *btmp;
        +		dp = (DSSPUBKEY *)(bh + 1);
        +		if (dp->magic != 0x31535344)
        +			{
        +			char magstr[10];
        +			BIO_snprintf(magstr, 10, "%lx", dp->magic);
        +			CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
        +			ERR_add_error_data(2, "magic=0x", magstr);
        +			goto err;
        +			}
        +		dsa_plen = dp->bitlen / 8;
        +		btmp = (unsigned char *)(dp + 1);
        +		dkey = DSA_new_method(eng);
        +		if (!dkey)
        +			goto memerr;
        +		dkey->p = BN_new();
        +		dkey->q = BN_new();
        +		dkey->g = BN_new();
        +		dkey->pub_key = BN_new();
        +		if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
        +			goto memerr;
        +		if (!lend_tobn(dkey->p, btmp, dsa_plen))
        +			goto memerr;
        +		btmp += dsa_plen;
        +		if (!lend_tobn(dkey->q, btmp, 20))
        +			goto memerr;
        +		btmp += 20;
        +		if (!lend_tobn(dkey->g, btmp, dsa_plen))
        +			goto memerr;
        +		btmp += dsa_plen;
        +		if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
        +			goto memerr;
        +		btmp += dsa_plen;
        +
        +		DSA_set_ex_data(dkey, dsa_capi_idx, key);
        +
        +		if (!(ret = EVP_PKEY_new()))
        +			goto memerr;
        +
        +		EVP_PKEY_assign_DSA(ret, dkey);
        +		dkey = NULL;
        +		}
        +	else
        +		{
        +		char algstr[10];
        +		BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
        +		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
        +		ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
        +		goto err;
        +		}
        +
        +
        +	err:
        +	if (pubkey)
        +		OPENSSL_free(pubkey);
        +	if (!ret)
        +		{
        +		if (rkey)
        +			RSA_free(rkey);
        +		if (dkey)
        +			DSA_free(dkey);
        +		}
        +
        +	return ret;
        +
        +memerr:
        +	CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
        +	goto err;
        +
        +	}
        +
        +static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data)
        +	{
        +	CAPI_CTX *ctx;
        +	CAPI_KEY *key;
        +	EVP_PKEY *ret;
        +	ctx = ENGINE_get_ex_data(eng, capi_idx);
        +
        +	if (!ctx)
        +		{
        +		CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
        +		return NULL;
        +		}
        +
        +	key = capi_find_key(ctx, key_id);
        +
        +	if (!key)
        +		return NULL;
        +
        +	ret = capi_get_pkey(eng, key);
        +
        +	if (!ret)
        +		capi_free_key(key);
        +	return ret;
        +
        +	}
        +
        +/* CryptoAPI RSA operations */
        +
        +int capi_rsa_priv_enc(int flen, const unsigned char *from,
        +                unsigned char *to, RSA *rsa, int padding)
        +	{
        +	CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
        +	return -1;
        +	}
        +
        +int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
        +             unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
        +	{
        +	ALG_ID alg;
        +	HCRYPTHASH hash;
        +	DWORD slen;
        +	unsigned int i;
        +	int ret = -1;
        +	CAPI_KEY *capi_key;
        +	CAPI_CTX *ctx;
        +
        +	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
        +
        +	CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");
        +
        +	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
        +	if (!capi_key)
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
        +		return -1;
        +		}
        +/* Convert the signature type to a CryptoAPI algorithm ID */
        +	switch(dtype)
        +		{
        +	case NID_sha1:
        +		alg = CALG_SHA1;
        +		break;
        +
        +	case NID_md5:
        +		alg = CALG_MD5;
        +		break;
        +
        +	case NID_md5_sha1:
        +		alg = CALG_SSL3_SHAMD5;
        +		break;
        +	default:
        +		{
        +		char algstr[10];
        +		BIO_snprintf(algstr, 10, "%lx", dtype);
        +		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
        +		ERR_add_error_data(2, "NID=0x", algstr);
        +		return -1;
        +		}
        +	}
        +
        +
        +
        +/* Create the hash object */
        +	if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
        +		capi_addlasterror();
        +		return -1;
        +		}
        +/* Set the hash value to the value passed */
        +
        +	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +
        +
        +/* Finally sign it */
        +	slen = RSA_size(rsa);
        +	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +	else
        +		{
        +		ret = 1;
        +		/* Inplace byte reversal of signature */
        +		for(i = 0; i < slen / 2; i++)
        +			{
        +			unsigned char c;
        +			c = sigret[i];
        +			sigret[i] = sigret[slen - i - 1];
        +			sigret[slen - i - 1] = c;
        +			}
        +		*siglen = slen;
        +		}
        +
        +	/* Now cleanup */
        +
        +err:
        +	CryptDestroyHash(hash);
        +
        +	return ret;
        +	}
        +
        +int capi_rsa_priv_dec(int flen, const unsigned char *from,
        +                unsigned char *to, RSA *rsa, int padding)
        +	{
        +	int i;
        +	unsigned char *tmpbuf;
        +	CAPI_KEY *capi_key;
        +	CAPI_CTX *ctx;
        +	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
        +
        +	CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");
        +
        +
        +	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
        +	if (!capi_key)
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
        +		return -1;
        +		}
        +
        +	if(padding != RSA_PKCS1_PADDING)
        +		{
        +		char errstr[10];
        +		BIO_snprintf(errstr, 10, "%d", padding);
        +		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
        +		ERR_add_error_data(2, "padding=", errstr);
        +		return -1;
        +		}
        +
        +	/* Create temp reverse order version of input */
        +	if(!(tmpbuf = OPENSSL_malloc(flen)) ) 
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
        +		return -1;
        +		}
        +	for(i = 0; i < flen; i++)
        +		tmpbuf[flen - i - 1] = from[i];
        +	
        +	/* Finally decrypt it */
        +	if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
        +		{
        +		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
        +		capi_addlasterror();
        +		OPENSSL_free(tmpbuf);
        +		return -1;
        +		} 
        +	else memcpy(to, tmpbuf, flen);
        +
        +	OPENSSL_free(tmpbuf);
        +
        +	return flen;
        +	}
        +
        +static int capi_rsa_free(RSA *rsa)
        +	{
        +	CAPI_KEY *capi_key;
        +	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
        +	capi_free_key(capi_key);
        +	RSA_set_ex_data(rsa, rsa_capi_idx, 0);
        +	return 1;
        +	}
        +
        +/* CryptoAPI DSA operations */
        +
        +static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
        +								DSA *dsa)
        +	{
        +	HCRYPTHASH hash;
        +	DWORD slen;
        +	DSA_SIG *ret = NULL;
        +	CAPI_KEY *capi_key;
        +	CAPI_CTX *ctx;
        +	unsigned char csigbuf[40];
        +
        +	ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);
        +
        +	CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");
        +
        +	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
        +
        +	if (!capi_key)
        +		{
        +		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
        +		return NULL;
        +		}
        +
        +	if (dlen != 20)
        +		{
        +		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
        +		return NULL;
        +		}
        +
        +	/* Create the hash object */
        +	if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
        +		{
        +		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
        +		capi_addlasterror();
        +		return NULL;
        +		}
        +
        +	/* Set the hash value to the value passed */
        +	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
        +		{
        +		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +
        +
        +	/* Finally sign it */
        +	slen = sizeof(csigbuf);
        +	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
        +		{
        +		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +	else
        +		{
        +		ret = DSA_SIG_new();
        +		if (!ret)
        +			goto err;
        +		ret->r = BN_new();
        +		ret->s = BN_new();
        +		if (!ret->r || !ret->s)
        +			goto err;
        +		if (!lend_tobn(ret->r, csigbuf, 20)
        +			|| !lend_tobn(ret->s, csigbuf + 20, 20))
        +			{
        +			DSA_SIG_free(ret);
        +			ret = NULL;
        +			goto err;
        +			}
        +		}
        +
        +	/* Now cleanup */
        +
        +err:
        +	OPENSSL_cleanse(csigbuf, 40);
        +	CryptDestroyHash(hash);
        +	return ret;
        +	}
        +
        +static int capi_dsa_free(DSA *dsa)
        +	{
        +	CAPI_KEY *capi_key;
        +	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
        +	capi_free_key(capi_key);
        +	DSA_set_ex_data(dsa, dsa_capi_idx, 0);
        +	return 1;
        +	}
        +
        +static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr)
        +	{
        +	BIO *out;
        +
        +	if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
        +		return;
        +	out = BIO_new_file(ctx->debug_file, "a+");
        +	BIO_vprintf(out, format, argptr);
        +	BIO_free(out);
        +	}
        +
        +static void CAPI_trace(CAPI_CTX *ctx, char *format, ...)
        +	{
        +	va_list args;
        +	va_start(args, format);
        +	capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
        +	va_end(args);
        +	}
        +
        +static void capi_addlasterror(void)
        +	{
        +	capi_adderror(GetLastError());
        +	}
        +
        +static void capi_adderror(DWORD err)
        +	{
        +	char errstr[10];
        +	BIO_snprintf(errstr, 10, "%lX", err);
        +	ERR_add_error_data(2, "Error code= 0x", errstr);
        +	}
        +
        +static char *wide_to_asc(LPWSTR wstr)
        +	{
        +	char *str;
        +	int len_0,sz;
        +
        +	if (!wstr)
        +		return NULL;
        +	len_0 = (int)wcslen(wstr)+1;	/* WideCharToMultiByte expects int */
        +        sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL);
        +	if (!sz)
        +		{
        +		CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
        +		return NULL;
        +		}
        +	str = OPENSSL_malloc(sz);
        +	if (!str)
        +		{
        +		CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL))
        +		{
        +		OPENSSL_free(str);
        +		CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
        +		return NULL;
        +		}
        +	return str;
        +	}
        +
        +static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
        +	{
        +	LPSTR name;
        +	DWORD len, err;
        +	CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
        +	if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len))
        +		{
        +		err = GetLastError();
        +		if (err == ERROR_NO_MORE_ITEMS)
        +			return 2;
        +		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
        +		capi_adderror(err);
        +		return 0;
        +		}
        +	name = OPENSSL_malloc(len);
        +	if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len))
        +		{
        +		err = GetLastError();
        +		if (err == ERROR_NO_MORE_ITEMS)
        +			return 2;
        +		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
        +		capi_adderror(err);
        +		return 0;
        +		}
        +	*pname = name;
        +	CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype);
        +
        +	return 1;
        +	}
        +
        +static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
        +	{
        +	DWORD idx, ptype;
        +	int ret;
        +	LPSTR provname = NULL;
        +	CAPI_trace(ctx, "capi_list_providers\n");
        +	BIO_printf(out, "Available CSPs:\n");
        +	for(idx = 0; ; idx++)
        +		{
        +		ret = capi_get_provname(ctx, &provname, &ptype, idx);
        +		if (ret == 2)
        +			break;
        +		if (ret == 0)
        +			break;
        +		BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
        +		OPENSSL_free(provname);
        +		}
        +	return 1;
        +	}
        +
        +static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
        +	{
        +	int ret = 1;
        +	HCRYPTPROV hprov;
        +	DWORD err, idx, flags, buflen = 0, clen;
        +	LPSTR cname;
        +	CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
        +	if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
        +		{
        +		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
        +		capi_addlasterror();
        +		return 0;
        +		}
        +	if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
        +		{
        +		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
        +		capi_addlasterror();
        +		CryptReleaseContext(hprov, 0);
        +		return 0;
        +		}
        +	CAPI_trace(ctx, "Got max container len %d\n", buflen);
        +	if (buflen == 0)
        +		buflen = 1024;
        +	cname = OPENSSL_malloc(buflen);
        +	if (!cname)
        +		{
        +		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	for (idx = 0;;idx++)
        +		{
        +		clen = buflen;
        +		cname[0] = 0;
        +
        +		if (idx == 0)
        +			flags = CRYPT_FIRST;
        +		else
        +			flags = 0;
        +		if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags))
        +			{
        +			err = GetLastError();
        +			if (err == ERROR_NO_MORE_ITEMS)
        +				goto done;
        +			CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
        +			capi_adderror(err);
        +			goto err;
        +			}
        +		CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
        +		if (!cname[0] && (clen == buflen))
        +			{
        +			CAPI_trace(ctx, "Enumerate bug: using workaround\n");
        +			goto done;
        +			}
        +		BIO_printf(out, "%d. %s\n", idx, cname);
        +		}
        +	err:
        +
        +	ret = 0;
        +
        +	done:
        +	if (cname)
        +		OPENSSL_free(cname);
        +	CryptReleaseContext(hprov, 0);
        +
        +	return ret;
        +	}
        +
        +CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
        +	{
        +	DWORD len;
        +	CRYPT_KEY_PROV_INFO *pinfo;
        +	
        +	if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
        +		return NULL;
        +	pinfo = OPENSSL_malloc(len);
        +	if (!pinfo)
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len))
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
        +		capi_addlasterror();
        +		OPENSSL_free(pinfo);
        +		return NULL;
        +		}
        +	return pinfo;
        +	}
        +
        +static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo)
        +	{
        +	char *provname = NULL, *contname = NULL;
        +	if (!pinfo)
        +		{
        +		BIO_printf(out, "  No Private Key\n");
        +		return;
        +		}
        +	provname = wide_to_asc(pinfo->pwszProvName);
        +	contname = wide_to_asc(pinfo->pwszContainerName);
        +	if (!provname || !contname)
        +		goto err;
        +
        +	BIO_printf(out, "  Private Key Info:\n");
        +	BIO_printf(out, "    Provider Name:  %s, Provider Type %d\n", provname, pinfo->dwProvType);
        +	BIO_printf(out, "    Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec);
        +	err:
        +	if (provname)
        +		OPENSSL_free(provname);
        +	if (contname)
        +		OPENSSL_free(contname);
        +	}
        +
        +char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
        +	{
        +	LPWSTR wfname;
        +	DWORD dlen;
        +
        +	CAPI_trace(ctx, "capi_cert_get_fname\n");
        +	if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
        +		return NULL;
        +	wfname = OPENSSL_malloc(dlen);
        +	if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
        +		{
        +		char *fname = wide_to_asc(wfname);
        +		OPENSSL_free(wfname);
        +		return fname;
        +		}
        +	CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
        +	capi_addlasterror();
        +
        +	OPENSSL_free(wfname);
        +	return NULL;
        +	}
        +
        +
        +void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
        +	{
        +	X509 *x;
        +	unsigned char *p;
        +	unsigned long flags = ctx->dump_flags;
        +	if (flags & CAPI_DMP_FNAME)
        +		{
        +		char *fname;
        +		fname = capi_cert_get_fname(ctx, cert);
        +		if (fname)
        +			{
        +			BIO_printf(out, "  Friendly Name \"%s\"\n", fname);
        +			OPENSSL_free(fname);
        +			}
        +		else
        +			BIO_printf(out, "  <No Friendly Name>\n");
        +		}
        +
        +	p = cert->pbCertEncoded;
        +	x = d2i_X509(NULL, &p, cert->cbCertEncoded);
        +	if (!x)
        +		BIO_printf(out, "  <Can't parse certificate>\n");
        +	if (flags & CAPI_DMP_SUMMARY)
        +		{
        +		BIO_printf(out, "  Subject: ");
        +		X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
        +		BIO_printf(out, "\n  Issuer: ");
        +		X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
        +		BIO_printf(out, "\n");
        +		}
        +	if (flags & CAPI_DMP_FULL)
        +		X509_print_ex(out, x, XN_FLAG_ONELINE,0);
        +
        +	if (flags & CAPI_DMP_PKEYINFO)
        +		{
        +		CRYPT_KEY_PROV_INFO *pinfo;
        +		pinfo = capi_get_prov_info(ctx, cert);
        +		capi_dump_prov_info(ctx, out, pinfo);
        +		if (pinfo)
        +			OPENSSL_free(pinfo);
        +		}
        +
        +	if (flags & CAPI_DMP_PEM)
        +		PEM_write_bio_X509(out, x);
        +	X509_free(x);
        +	}
        +
        +HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename)
        +	{
        +	HCERTSTORE hstore;
        +
        +	if (!storename)
        +		storename = ctx->storename;
        +	if (!storename)
        +		storename = "MY";
        +	CAPI_trace(ctx, "Opening certificate store %s\n", storename);
        +
        +	hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, 
        +				ctx->store_flags, storename);
        +	if (!hstore)
        +		{
        +		CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
        +		capi_addlasterror();
        +		}
        +	return hstore;
        +	}
        +
        +int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
        +	{
        +	char *storename;
        +	int idx;
        +	int ret = 1;
        +	HCERTSTORE hstore;
        +	PCCERT_CONTEXT cert = NULL;
        +
        +	storename = ctx->storename;
        +	if (!storename)
        +		storename = "MY";
        +	CAPI_trace(ctx, "Listing certs for store %s\n", storename);
        +
        +	hstore = capi_open_store(ctx, storename);
        +	if (!hstore)
        +		return 0;
        +	if (id)
        +		{
        +		cert = capi_find_cert(ctx, id, hstore);
        +		if (!cert)
        +			{
        +			ret = 0;
        +			goto err;
        +			}
        +		capi_dump_cert(ctx, out, cert);
        +		CertFreeCertificateContext(cert);
        +		}
        +	else
        +		{
        +		for(idx = 0;;idx++)
        +			{
        +			LPWSTR fname = NULL;
        +			cert = CertEnumCertificatesInStore(hstore, cert);
        +			if (!cert)
        +				break;
        +			BIO_printf(out, "Certificate %d\n", idx);
        +			capi_dump_cert(ctx, out, cert);
        +			}
        +		}
        +	err:
        +	CertCloseStore(hstore, 0);
        +	return ret;
        +	}
        +
        +static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore)
        +	{
        +	PCCERT_CONTEXT cert = NULL;
        +	char *fname = NULL;
        +	int match;
        +	switch(ctx->lookup_method)
        +		{
        +		case CAPI_LU_SUBSTR:
        +			return CertFindCertificateInStore(hstore,
        +					X509_ASN_ENCODING, 0,
        +					CERT_FIND_SUBJECT_STR_A, id, NULL);
        +		case CAPI_LU_FNAME:
        +			for(;;)
        +				{
        +				cert = CertEnumCertificatesInStore(hstore, cert);
        +				if (!cert)
        +					return NULL;
        +				fname = capi_cert_get_fname(ctx, cert);
        +				if (fname)
        +					{
        +					if (strcmp(fname, id))
        +						match = 0;
        +					else
        +						match = 1;
        +					OPENSSL_free(fname);
        +					if (match)
        +						return cert;
        +					}
        +				}
        +		default:
        +			return NULL;
        +		}
        +	}
        +
        +static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
        +	{
        +	CAPI_KEY *key;
        +    DWORD dwFlags = 0; 
        +	key = OPENSSL_malloc(sizeof(CAPI_KEY));
        +	CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 
        +						contname, provname, ptype);
        +    if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
        +        dwFlags = CRYPT_MACHINE_KEYSET;
        +    if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, dwFlags)) 
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +	if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
        +		{
        +		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
        +		capi_addlasterror();
        +		CryptReleaseContext(key->hprov, 0);
        +		goto err;
        +		}
        +	key->keyspec = keyspec;
        +	key->pcert = NULL;
        +	return key;
        +
        +	err:
        +	OPENSSL_free(key);
        +	return NULL;
        +	}
        +
        +static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
        +	{
        +	CAPI_KEY *key = NULL;
        +	CRYPT_KEY_PROV_INFO *pinfo = NULL;
        +	char *provname = NULL, *contname = NULL;
        +	pinfo = capi_get_prov_info(ctx, cert);
        +	if (!pinfo)
        +		goto err;
        +	provname = wide_to_asc(pinfo->pwszProvName);
        +	contname = wide_to_asc(pinfo->pwszContainerName);
        +	if (!provname || !contname)
        +		goto err;
        +	key = capi_get_key(ctx, contname, provname,
        +				pinfo->dwProvType, pinfo->dwKeySpec);
        +
        +	err:
        +	if (pinfo)
        +		OPENSSL_free(pinfo);
        +	if (provname)
        +		OPENSSL_free(provname);
        +	if (contname)
        +		OPENSSL_free(contname);
        +	return key;
        +	}
        +
        +CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id)
        +	{
        +	PCCERT_CONTEXT cert;
        +	HCERTSTORE hstore;
        +	CAPI_KEY *key = NULL;
        +	switch (ctx->lookup_method)
        +		{
        +		case CAPI_LU_SUBSTR:
        +		case CAPI_LU_FNAME:
        +		hstore = capi_open_store(ctx, NULL);
        +		if (!hstore)
        +			return NULL;
        +		cert = capi_find_cert(ctx, id, hstore);
        +		if (cert)
        +			{
        +			key = capi_get_cert_key(ctx, cert);
        +			CertFreeCertificateContext(cert);
        +			}
        +		CertCloseStore(hstore, 0);
        +		break;
        +
        +		case CAPI_LU_CONTNAME:
        +		key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype,
        +							ctx->keytype);
        +		break;
        +		}
        +
        +	return key;
        +	}
        +
        +void capi_free_key(CAPI_KEY *key)
        +	{
        +	if (!key)
        +		return;
        +	CryptDestroyKey(key->key);
        +	CryptReleaseContext(key->hprov, 0);
        +	if (key->pcert)
        +		CertFreeCertificateContext(key->pcert);
        +	OPENSSL_free(key);
        +	}
        +
        +
        +/* Initialize a CAPI_CTX structure */
        +
        +static CAPI_CTX *capi_ctx_new()
        +	{
        +	CAPI_CTX *ctx;
        +	ctx = OPENSSL_malloc(sizeof(CAPI_CTX));
        +	if (!ctx)
        +		{
        +		CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +	ctx->cspname = NULL;
        +	ctx->csptype = PROV_RSA_FULL;
        +	ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME;
        +	ctx->keytype = AT_KEYEXCHANGE;
        +	ctx->storename = NULL;
        +	ctx->ssl_client_store = NULL;
        +	ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
        +				CERT_STORE_READONLY_FLAG |
        +				CERT_SYSTEM_STORE_CURRENT_USER;
        +	ctx->lookup_method = CAPI_LU_SUBSTR;
        +	ctx->debug_level = 0;
        +	ctx->debug_file = NULL;
        +	ctx->client_cert_select = cert_select_simple;
        +	return ctx;
        +	}
        +
        +static void capi_ctx_free(CAPI_CTX *ctx)
        +	{
        +	CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
        +	if (!ctx)
        +		return;
        +	if (ctx->cspname)
        +		OPENSSL_free(ctx->cspname);
        +	if (ctx->debug_file)
        +		OPENSSL_free(ctx->debug_file);
        +	if (ctx->storename)
        +		OPENSSL_free(ctx->storename);
        +	if (ctx->ssl_client_store)
        +		OPENSSL_free(ctx->ssl_client_store);
        +	OPENSSL_free(ctx);
        +	}
        +
        +static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
        +	{
        +	CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
        +	if (check)
        +		{
        +		HCRYPTPROV hprov;
        +		if (!CryptAcquireContextA(&hprov, NULL, pname, type,
        +						CRYPT_VERIFYCONTEXT))
        +			{
        +			CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
        +			capi_addlasterror();
        +			return 0;
        +			}
        +		CryptReleaseContext(hprov, 0);
        +		}
        +	if (ctx->cspname)
        +		OPENSSL_free(ctx->cspname);
        +	ctx->cspname = BUF_strdup(pname);
        +	ctx->csptype = type;
        +	return 1;
        +	}
        +
        +static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
        +	{
        +	LPSTR pname;
        +	DWORD type;
        +	int res;
        +	if (capi_get_provname(ctx, &pname, &type, idx) != 1)
        +		return 0;
        +	res = capi_ctx_set_provname(ctx, pname, type, 0);
        +	OPENSSL_free(pname);
        +	return res;
        +	}
        +
        +static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
        +	{
        +	int i;
        +	X509_NAME *nm;
        +	/* Special case: empty list: match anything */
        +	if (sk_X509_NAME_num(ca_dn) <= 0)
        +		return 1;
        +	for (i = 0; i < sk_X509_NAME_num(ca_dn); i++)
        +		{
        +		nm = sk_X509_NAME_value(ca_dn, i);
        +		if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
        +				return 1;
        +		}
        +	return 0;
        +	}
        +
        +
        +
        +static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
        +	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
        +	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
        +	{
        +	STACK_OF(X509) *certs = NULL;
        +	X509 *x;
        +	char *storename;
        +	const char *p;
        +	int i, client_cert_idx;
        +	HCERTSTORE hstore;
        +	PCCERT_CONTEXT cert = NULL, excert = NULL;
        +	CAPI_CTX *ctx;
        +	CAPI_KEY *key;
        +	ctx = ENGINE_get_ex_data(e, capi_idx);
        +
        +	*pcert = NULL;
        +	*pkey = NULL;
        +
        +	storename = ctx->ssl_client_store;
        +	if (!storename)
        +		storename = "MY";
        +
        +	hstore = capi_open_store(ctx, storename);
        +	if (!hstore)
        +		return 0;
        +	/* Enumerate all certificates collect any matches */
        +	for(i = 0;;i++)
        +		{
        +		cert = CertEnumCertificatesInStore(hstore, cert);
        +		if (!cert)
        +			break;
        +		p = cert->pbCertEncoded;
        +		x = d2i_X509(NULL, &p, cert->cbCertEncoded);
        +		if (!x)
        +			{
        +			CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
        +			continue;
        +			}
        +		if (cert_issuer_match(ca_dn, x)
        +			&& X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0))
        +			{
        +			key = capi_get_cert_key(ctx, cert);
        +			if (!key)
        +				{
        +				X509_free(x);
        +				continue;
        +				}
        +			/* Match found: attach extra data to it so
        +			 * we can retrieve the key later.
        +			 */
        +			excert = CertDuplicateCertificateContext(cert);
        +			key->pcert = excert;
        +			X509_set_ex_data(x, cert_capi_idx, key);
        +
        +			if (!certs)
        +				certs = sk_X509_new_null();
        +
        +			sk_X509_push(certs, x);
        +			}
        +		else
        +			X509_free(x);
        +
        +		}
        +
        +	if (cert)
        +		CertFreeCertificateContext(cert);
        +	if (hstore)
        +		CertCloseStore(hstore, 0);
        +
        +	if (!certs)
        +		return 0;
        +
        +
        +	/* Select the appropriate certificate */
        +
        +	client_cert_idx = ctx->client_cert_select(e, ssl, certs);
        +
        +	/* Set the selected certificate and free the rest */
        +
        +	for(i = 0; i < sk_X509_num(certs); i++)
        +		{
        +		x = sk_X509_value(certs, i);
        +		if (i == client_cert_idx)
        +			*pcert = x;
        +		else
        +			{
        +			key = X509_get_ex_data(x, cert_capi_idx);
        +			capi_free_key(key);
        +			X509_free(x);
        +			}
        +		}
        +
        +	sk_X509_free(certs);
        +
        +	if (!*pcert)
        +		return 0;
        +
        +	/* Setup key for selected certificate */
        +
        +	key = X509_get_ex_data(*pcert, cert_capi_idx);
        +	*pkey = capi_get_pkey(e, key);
        +	X509_set_ex_data(*pcert, cert_capi_idx, NULL);
        +
        +	return 1;
        +
        +	}
        +
        +
        +/* Simple client cert selection function: always select first */
        +
        +static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
        +	{
        +	return 0;
        +	}
        +
        +#ifdef OPENSSL_CAPIENG_DIALOG
        +
        +/* More complex cert selection function, using standard function
        + * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
        + */
        +
        +/* Definitions which are in cryptuiapi.h but this is not present in older
        + * versions of headers.
        + */
        +
        +#ifndef CRYPTUI_SELECT_LOCATION_COLUMN
        +#define CRYPTUI_SELECT_LOCATION_COLUMN                   0x000000010
        +#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN                0x000000004
        +#endif
        +
        +#define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
        +#define dlg_prompt L"Select a certificate to use for authentication"
        +#define dlg_columns	 CRYPTUI_SELECT_LOCATION_COLUMN \
        +			|CRYPTUI_SELECT_INTENDEDUSE_COLUMN
        +
        +static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
        +	{
        +	X509 *x;
        +	HCERTSTORE dstore;
        +	PCCERT_CONTEXT cert;
        +	CAPI_CTX *ctx;
        +	CAPI_KEY *key;
        +	HWND hwnd;
        +	int i, idx = -1;
        +	if (sk_X509_num(certs) == 1)
        +		return 0;
        +	ctx = ENGINE_get_ex_data(e, capi_idx);
        +	/* Create an in memory store of certificates */
        +	dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
        +					CERT_STORE_CREATE_NEW_FLAG, NULL);
        +	if (!dstore)
        +		{
        +		CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
        +		capi_addlasterror();
        +		goto err;
        +		}
        +	/* Add all certificates to store */
        +	for(i = 0; i < sk_X509_num(certs); i++)
        +		{
        +		x = sk_X509_value(certs, i);
        +		key = X509_get_ex_data(x, cert_capi_idx);
        +
        +		if (!CertAddCertificateContextToStore(dstore, key->pcert,
        +						CERT_STORE_ADD_NEW, NULL))
        +			{
        +			CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
        +			capi_addlasterror();
        +			goto err;
        +			}
        +
        +		}
        +	hwnd = GetForegroundWindow();
        +	if (!hwnd)
        +		hwnd = GetActiveWindow();
        +	if (!hwnd && ctx->getconswindow)
        +		hwnd = ctx->getconswindow();
        +	/* Call dialog to select one */
        +	cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
        +						dlg_columns, 0, NULL);
        +
        +	/* Find matching cert from list */
        +	if (cert)
        +		{
        +		for(i = 0; i < sk_X509_num(certs); i++)
        +			{
        +			x = sk_X509_value(certs, i);
        +			key = X509_get_ex_data(x, cert_capi_idx);
        +			if (CertCompareCertificate(
        +				X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        +					cert->pCertInfo,
        +					key->pcert->pCertInfo))
        +				{
        +				idx = i;
        +				break;
        +				}
        +			}
        +		}
        +
        +	err:
        +	if (dstore)
        +		CertCloseStore(dstore, 0);
        +	return idx;
        +
        +	}
        +#endif
        +
        +#else /* !__COMPILE_CAPIENG */
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +OPENSSL_EXPORT
        +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
        +OPENSSL_EXPORT
        +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +#else
        +void ENGINE_load_capi(void){}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_capi.ec b/vendor/openssl/openssl/engines/e_capi.ec
        new file mode 100644
        index 000000000..d2ad668a9
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_capi.ec
        @@ -0,0 +1 @@
        +L       CAPI    e_capi_err.h e_capi_err.c
        diff --git a/vendor/openssl/openssl/engines/e_capi_err.c b/vendor/openssl/openssl/engines/e_capi_err.c
        new file mode 100644
        index 000000000..a1fbd04cb
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_capi_err.c
        @@ -0,0 +1,184 @@
        +/* e_capi_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2009 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_capi_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA CAPI_str_functs[]=
        +	{
        +{ERR_FUNC(CAPI_F_CAPI_CERT_GET_FNAME),	"CAPI_CERT_GET_FNAME"},
        +{ERR_FUNC(CAPI_F_CAPI_CTRL),	"CAPI_CTRL"},
        +{ERR_FUNC(CAPI_F_CAPI_CTX_NEW),	"CAPI_CTX_NEW"},
        +{ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME),	"CAPI_CTX_SET_PROVNAME"},
        +{ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN),	"CAPI_DSA_DO_SIGN"},
        +{ERR_FUNC(CAPI_F_CAPI_GET_KEY),	"CAPI_GET_KEY"},
        +{ERR_FUNC(CAPI_F_CAPI_GET_PKEY),	"CAPI_GET_PKEY"},
        +{ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME),	"CAPI_GET_PROVNAME"},
        +{ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO),	"CAPI_GET_PROV_INFO"},
        +{ERR_FUNC(CAPI_F_CAPI_INIT),	"CAPI_INIT"},
        +{ERR_FUNC(CAPI_F_CAPI_LIST_CONTAINERS),	"CAPI_LIST_CONTAINERS"},
        +{ERR_FUNC(CAPI_F_CAPI_LOAD_PRIVKEY),	"CAPI_LOAD_PRIVKEY"},
        +{ERR_FUNC(CAPI_F_CAPI_OPEN_STORE),	"CAPI_OPEN_STORE"},
        +{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_DEC),	"CAPI_RSA_PRIV_DEC"},
        +{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_ENC),	"CAPI_RSA_PRIV_ENC"},
        +{ERR_FUNC(CAPI_F_CAPI_RSA_SIGN),	"CAPI_RSA_SIGN"},
        +{ERR_FUNC(CAPI_F_CERT_SELECT_DIALOG),	"CERT_SELECT_DIALOG"},
        +{ERR_FUNC(CAPI_F_CLIENT_CERT_SELECT),	"CLIENT_CERT_SELECT"},
        +{ERR_FUNC(CAPI_F_WIDE_TO_ASC),	"WIDE_TO_ASC"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CAPI_str_reasons[]=
        +	{
        +{ERR_REASON(CAPI_R_CANT_CREATE_HASH_OBJECT),"cant create hash object"},
        +{ERR_REASON(CAPI_R_CANT_FIND_CAPI_CONTEXT),"cant find capi context"},
        +{ERR_REASON(CAPI_R_CANT_GET_KEY)         ,"cant get key"},
        +{ERR_REASON(CAPI_R_CANT_SET_HASH_VALUE)  ,"cant set hash value"},
        +{ERR_REASON(CAPI_R_CRYPTACQUIRECONTEXT_ERROR),"cryptacquirecontext error"},
        +{ERR_REASON(CAPI_R_CRYPTENUMPROVIDERS_ERROR),"cryptenumproviders error"},
        +{ERR_REASON(CAPI_R_DECRYPT_ERROR)        ,"decrypt error"},
        +{ERR_REASON(CAPI_R_ENGINE_NOT_INITIALIZED),"engine not initialized"},
        +{ERR_REASON(CAPI_R_ENUMCONTAINERS_ERROR) ,"enumcontainers error"},
        +{ERR_REASON(CAPI_R_ERROR_ADDING_CERT)    ,"error adding cert"},
        +{ERR_REASON(CAPI_R_ERROR_CREATING_STORE) ,"error creating store"},
        +{ERR_REASON(CAPI_R_ERROR_GETTING_FRIENDLY_NAME),"error getting friendly name"},
        +{ERR_REASON(CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO),"error getting key provider info"},
        +{ERR_REASON(CAPI_R_ERROR_OPENING_STORE)  ,"error opening store"},
        +{ERR_REASON(CAPI_R_ERROR_SIGNING_HASH)   ,"error signing hash"},
        +{ERR_REASON(CAPI_R_FUNCTION_NOT_SUPPORTED),"function not supported"},
        +{ERR_REASON(CAPI_R_GETUSERKEY_ERROR)     ,"getuserkey error"},
        +{ERR_REASON(CAPI_R_INVALID_DIGEST_LENGTH),"invalid digest length"},
        +{ERR_REASON(CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid dsa public key blob magic number"},
        +{ERR_REASON(CAPI_R_INVALID_LOOKUP_METHOD),"invalid lookup method"},
        +{ERR_REASON(CAPI_R_INVALID_PUBLIC_KEY_BLOB),"invalid public key blob"},
        +{ERR_REASON(CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid rsa public key blob magic number"},
        +{ERR_REASON(CAPI_R_PUBKEY_EXPORT_ERROR)  ,"pubkey export error"},
        +{ERR_REASON(CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR),"pubkey export length error"},
        +{ERR_REASON(CAPI_R_UNKNOWN_COMMAND)      ,"unknown command"},
        +{ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID),"unsupported algorithm nid"},
        +{ERR_REASON(CAPI_R_UNSUPPORTED_PADDING)  ,"unsupported padding"},
        +{ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM),"unsupported public key algorithm"},
        +{ERR_REASON(CAPI_R_WIN32_ERROR)          ,"win32 error"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef CAPI_LIB_NAME
        +static ERR_STRING_DATA CAPI_lib_name[]=
        +        {
        +{0	,CAPI_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int CAPI_lib_error_code=0;
        +static int CAPI_error_init=1;
        +
        +static void ERR_load_CAPI_strings(void)
        +	{
        +	if (CAPI_lib_error_code == 0)
        +		CAPI_lib_error_code=ERR_get_next_error_library();
        +
        +	if (CAPI_error_init)
        +		{
        +		CAPI_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(CAPI_lib_error_code,CAPI_str_functs);
        +		ERR_load_strings(CAPI_lib_error_code,CAPI_str_reasons);
        +#endif
        +
        +#ifdef CAPI_LIB_NAME
        +		CAPI_lib_name->error = ERR_PACK(CAPI_lib_error_code,0,0);
        +		ERR_load_strings(0,CAPI_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_CAPI_strings(void)
        +	{
        +	if (CAPI_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(CAPI_lib_error_code,CAPI_str_functs);
        +		ERR_unload_strings(CAPI_lib_error_code,CAPI_str_reasons);
        +#endif
        +
        +#ifdef CAPI_LIB_NAME
        +		ERR_unload_strings(0,CAPI_lib_name);
        +#endif
        +		CAPI_error_init=1;
        +		}
        +	}
        +
        +static void ERR_CAPI_error(int function, int reason, char *file, int line)
        +	{
        +	if (CAPI_lib_error_code == 0)
        +		CAPI_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(CAPI_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_capi_err.h b/vendor/openssl/openssl/engines/e_capi_err.h
        new file mode 100644
        index 000000000..efa700103
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_capi_err.h
        @@ -0,0 +1,128 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2008 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_CAPI_ERR_H
        +#define HEADER_CAPI_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_CAPI_strings(void);
        +static void ERR_unload_CAPI_strings(void);
        +static void ERR_CAPI_error(int function, int reason, char *file, int line);
        +#define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the CAPI functions. */
        +
        +/* Function codes. */
        +#define CAPI_F_CAPI_CERT_GET_FNAME			 99
        +#define CAPI_F_CAPI_CTRL				 100
        +#define CAPI_F_CAPI_CTX_NEW				 101
        +#define CAPI_F_CAPI_CTX_SET_PROVNAME			 102
        +#define CAPI_F_CAPI_DSA_DO_SIGN				 114
        +#define CAPI_F_CAPI_GET_KEY				 103
        +#define CAPI_F_CAPI_GET_PKEY				 115
        +#define CAPI_F_CAPI_GET_PROVNAME			 104
        +#define CAPI_F_CAPI_GET_PROV_INFO			 105
        +#define CAPI_F_CAPI_INIT				 106
        +#define CAPI_F_CAPI_LIST_CONTAINERS			 107
        +#define CAPI_F_CAPI_LOAD_PRIVKEY			 108
        +#define CAPI_F_CAPI_OPEN_STORE				 109
        +#define CAPI_F_CAPI_RSA_PRIV_DEC			 110
        +#define CAPI_F_CAPI_RSA_PRIV_ENC			 111
        +#define CAPI_F_CAPI_RSA_SIGN				 112
        +#define CAPI_F_CERT_SELECT_DIALOG			 117
        +#define CAPI_F_CLIENT_CERT_SELECT			 116
        +#define CAPI_F_WIDE_TO_ASC				 113
        +
        +/* Reason codes. */
        +#define CAPI_R_CANT_CREATE_HASH_OBJECT			 99
        +#define CAPI_R_CANT_FIND_CAPI_CONTEXT			 100
        +#define CAPI_R_CANT_GET_KEY				 101
        +#define CAPI_R_CANT_SET_HASH_VALUE			 102
        +#define CAPI_R_CRYPTACQUIRECONTEXT_ERROR		 103
        +#define CAPI_R_CRYPTENUMPROVIDERS_ERROR			 104
        +#define CAPI_R_DECRYPT_ERROR				 105
        +#define CAPI_R_ENGINE_NOT_INITIALIZED			 106
        +#define CAPI_R_ENUMCONTAINERS_ERROR			 107
        +#define CAPI_R_ERROR_ADDING_CERT			 125
        +#define CAPI_R_ERROR_CREATING_STORE			 126
        +#define CAPI_R_ERROR_GETTING_FRIENDLY_NAME		 108
        +#define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO		 109
        +#define CAPI_R_ERROR_OPENING_STORE			 110
        +#define CAPI_R_ERROR_SIGNING_HASH			 111
        +#define CAPI_R_FUNCTION_NOT_SUPPORTED			 112
        +#define CAPI_R_GETUSERKEY_ERROR				 113
        +#define CAPI_R_INVALID_DIGEST_LENGTH			 124
        +#define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER	 122
        +#define CAPI_R_INVALID_LOOKUP_METHOD			 114
        +#define CAPI_R_INVALID_PUBLIC_KEY_BLOB			 115
        +#define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER	 123
        +#define CAPI_R_PUBKEY_EXPORT_ERROR			 116
        +#define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR		 117
        +#define CAPI_R_UNKNOWN_COMMAND				 118
        +#define CAPI_R_UNSUPPORTED_ALGORITHM_NID		 119
        +#define CAPI_R_UNSUPPORTED_PADDING			 120
        +#define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM		 121
        +#define CAPI_R_WIN32_ERROR				 127
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_chil.c b/vendor/openssl/openssl/engines/e_chil.c
        new file mode 100644
        index 000000000..fdc2100e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_chil.c
        @@ -0,0 +1,1356 @@
        +/* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
        +/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
        + * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org)
        + * for the OpenSSL project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/pem.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#include <openssl/ui.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_CHIL
        +
        +/* 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
        +
        +#define HWCRHK_LIB_NAME "CHIL engine"
        +#include "e_chil_err.c"
        +
        +static int hwcrhk_destroy(ENGINE *e);
        +static int hwcrhk_init(ENGINE *e);
        +static int hwcrhk_finish(ENGINE *e);
        +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 
        +
        +/* 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, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx);
        +
        +#ifndef OPENSSL_NO_RSA
        +/* RSA stuff */
        +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +static int hwcrhk_rsa_finish(RSA *rsa);
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* DH stuff */
        +/* This function is alised to mod_exp (with the DH and mont dropped). */
        +static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
        +	const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* 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(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +
        +/* Interaction stuff */
        +static int hwcrhk_insert_card(const char *prompt_info,
        +	const char *wrong_info,
        +	HWCryptoHook_PassphraseContext *ppctx,
        +	HWCryptoHook_CallerContext *cactx);
        +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 *logstr, const char *message);
        +
        +/* The definitions for control commands specific to this engine */
        +#define HWCRHK_CMD_SO_PATH		ENGINE_CMD_BASE
        +#define HWCRHK_CMD_FORK_CHECK		(ENGINE_CMD_BASE + 1)
        +#define HWCRHK_CMD_THREAD_LOCKING	(ENGINE_CMD_BASE + 2)
        +#define HWCRHK_CMD_SET_USER_INTERFACE   (ENGINE_CMD_BASE + 3)
        +#define HWCRHK_CMD_SET_CALLBACK_DATA    (ENGINE_CMD_BASE + 4)
        +static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
        +	{HWCRHK_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'hwcrhk' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{HWCRHK_CMD_FORK_CHECK,
        +		"FORK_CHECK",
        +		"Turns fork() checking on (non-zero) or off (zero)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{HWCRHK_CMD_THREAD_LOCKING,
        +		"THREAD_LOCKING",
        +		"Turns thread-safe locking on (zero) or off (non-zero)",
        +		ENGINE_CMD_FLAG_NUMERIC},
        +	{HWCRHK_CMD_SET_USER_INTERFACE,
        +		"SET_USER_INTERFACE",
        +		"Set the global user interface (internal)",
        +		ENGINE_CMD_FLAG_INTERNAL},
        +	{HWCRHK_CMD_SET_CALLBACK_DATA,
        +		"SET_CALLBACK_DATA",
        +		"Set the global user interface extra data (internal)",
        +		ENGINE_CMD_FLAG_INTERNAL},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD hwcrhk_rsa =
        +	{
        +	"CHIL RSA method",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	hwcrhk_rsa_mod_exp,
        +	hwcrhk_mod_exp_mont,
        +	NULL,
        +	hwcrhk_rsa_finish,
        +	0,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* Our internal DH_METHOD that we provide pointers to */
        +static DH_METHOD hwcrhk_dh =
        +	{
        +	"CHIL DH method",
        +	NULL,
        +	NULL,
        +	hwcrhk_mod_exp_dh,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +static RAND_METHOD hwcrhk_rand =
        +	{
        +	/* "CHIL RAND method", */
        +	NULL,
        +	hwcrhk_rand_bytes,
        +	NULL,
        +	NULL,
        +	hwcrhk_rand_bytes,
        +	hwcrhk_rand_status,
        +	};
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_hwcrhk_id = "chil";
        +static const char *engine_hwcrhk_name = "CHIL hardware engine support";
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE 
        +/* Compatibility hack, the dynamic library uses this form in the path */
        +static const char *engine_hwcrhk_id_alt = "ncipher";
        +#endif
        +
        +/* 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
        +	{
        +        UI_METHOD *ui_method;
        +	void *callback_data;
        +	};
        +
        +/* hwcryptohook.h has some typedefs that turn
        +   struct HWCryptoHook_CallerContextValue
        +   into HWCryptoHook_CallerContext */
        +struct HWCryptoHook_CallerContextValue
        +	{
        +	pem_password_cb *password_callback; /* Deprecated!  Only present for
        +                                               backward compatibility! */
        +        UI_METHOD *ui_method;
        +	void *callback_data;
        +	};
        +
        +/* 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;}
        +
        +static BIO *logstream = NULL;
        +static int disable_mutex_callbacks = 0;
        +
        +/* One might wonder why these are needed, since one can pass down at least
        +   a UI_METHOD and a pointer to callback data to the key-loading functions.
        +   The thing is that the ModExp and RSAImmed functions can load keys as well,
        +   if the data they get is in a special, nCipher-defined format (hint: if you
        +   look at the private exponent of the RSA data as a string, you'll see this
        +   string: "nCipher KM tool key id", followed by some bytes, followed a key
        +   identity string, followed by more bytes.  This happens when you use "embed"
        +   keys instead of "hwcrhk" keys).  Unfortunately, those functions do not take
        +   any passphrase or caller context, and our functions can't really take any
        +   callback data either.  Still, the "insert_card" and "get_passphrase"
        +   callbacks may be called down the line, and will need to know what user
        +   interface callbacks to call, and having callback data from the application
        +   may be a nice thing as well, so we need to keep track of that globally. */
        +static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
        +
        +/* Stuff to pass to the HWCryptoHook library */
        +static HWCryptoHook_InitInfo hwcrhk_globals = {
        +	HWCryptoHook_InitFlags_SimpleForkCheck,	/* 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 */
        +	hwcrhk_insert_card,	/* insert a card */
        +	hwcrhk_log_message	/* Log message */
        +};
        +
        +
        +/* Now, to our own code */
        +
        +/* This internal function is used by ENGINE_chil() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth2;
        +#endif
        +	if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
        +			!ENGINE_set_name(e, engine_hwcrhk_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &hwcrhk_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH(e, &hwcrhk_dh) ||
        +#endif
        +			!ENGINE_set_RAND(e, &hwcrhk_rand) ||
        +			!ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
        +			!ENGINE_set_init_function(e, hwcrhk_init) ||
        +			!ENGINE_set_finish_function(e, hwcrhk_finish) ||
        +			!ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
        +			!ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
        +			!ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
        +			!ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* 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;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth2 = DH_OpenSSL();
        +	hwcrhk_dh.generate_key = meth2->generate_key;
        +	hwcrhk_dh.compute_key = meth2->compute_key;
        +#endif
        +
        +	/* Ensure the hwcrhk error handling is set up */
        +	ERR_load_HWCRHK_strings();
        +	return 1;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_chil(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_chil(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_chil();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* 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;
        +#ifndef OPENSSL_NO_RSA
        +static int hndidx_rsa = -1;    /* Index for KM handle.  Not really used yet. */
        +#endif
        +
        +/* 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;
        +#ifndef OPENSSL_NO_RSA
        +static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
        +#endif
        +static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
        +#ifndef OPENSSL_NO_RSA
        +static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
        +static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
        +static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
        +#endif
        +static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
        +
        +/* Used in the DSO operations. */
        +static const char *HWCRHK_LIBNAME = NULL;
        +static void free_HWCRHK_LIBNAME(void)
        +	{
        +	if(HWCRHK_LIBNAME)
        +		OPENSSL_free((void*)HWCRHK_LIBNAME);
        +	HWCRHK_LIBNAME = NULL;
        +	}
        +static const char *get_HWCRHK_LIBNAME(void)
        +	{
        +	if(HWCRHK_LIBNAME)
        +		return HWCRHK_LIBNAME;
        +	return "nfhwcrhk";
        +	}
        +static long set_HWCRHK_LIBNAME(const char *name)
        +	{
        +	free_HWCRHK_LIBNAME();
        +	return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
        +	}
        +static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
        +static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
        +static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
        +#ifndef OPENSSL_NO_RSA
        +static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
        +#endif
        +static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
        +#ifndef OPENSSL_NO_RSA
        +static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
        +static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
        +static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
        +#endif
        +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,
        +        HWCryptoHook_CallerContext *cac)
        +	{
        +	char tempbuf[1024];
        +	HWCryptoHook_ErrMsgBuf rmsg;
        +
        +	rmsg.buf = tempbuf;
        +	rmsg.size = sizeof(tempbuf);
        +
        +        *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
        +		cac);
        +	if (!*hac)
        +                return 0;
        +        return 1;
        +	}
        + 
        +/* similarly to release one. */
        +static void release_context(HWCryptoHook_ContextHandle hac)
        +	{
        +	p_hwcrhk_Finish(hac);
        +	}
        +
        +/* Destructor (complements the "ENGINE_chil()" constructor) */
        +static int hwcrhk_destroy(ENGINE *e)
        +	{
        +	free_HWCRHK_LIBNAME();
        +	ERR_unload_HWCRHK_strings();
        +	return 1;
        +	}
        +
        +/* (de)initialisation functions. */
        +static int hwcrhk_init(ENGINE *e)
        +	{
        +	HWCryptoHook_Init_t *p1;
        +	HWCryptoHook_Finish_t *p2;
        +	HWCryptoHook_ModExp_t *p3;
        +#ifndef OPENSSL_NO_RSA
        +	HWCryptoHook_RSA_t *p4;
        +	HWCryptoHook_RSALoadKey_t *p5;
        +	HWCryptoHook_RSAGetPublicKey_t *p6;
        +	HWCryptoHook_RSAUnloadKey_t *p7;
        +#endif
        +	HWCryptoHook_RandomBytes_t *p8;
        +	HWCryptoHook_ModExpCRT_t *p9;
        +
        +	if(hwcrhk_dso != NULL)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
        +		goto err;
        +		}
        +	/* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
        +	hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
        +	if(hwcrhk_dso == NULL)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_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)) ||
        +#ifndef OPENSSL_NO_RSA
        +		!(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)) ||
        +#endif
        +		!(p8 = (HWCryptoHook_RandomBytes_t *)
        +			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
        +		!(p9 = (HWCryptoHook_ModExpCRT_t *)
        +			DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
        +		goto err;
        +		}
        +	/* Copy the pointers */
        +	p_hwcrhk_Init = p1;
        +	p_hwcrhk_Finish = p2;
        +	p_hwcrhk_ModExp = p3;
        +#ifndef OPENSSL_NO_RSA
        +	p_hwcrhk_RSA = p4;
        +	p_hwcrhk_RSALoadKey = p5;
        +	p_hwcrhk_RSAGetPublicKey = p6;
        +	p_hwcrhk_RSAUnloadKey = p7;
        +#endif
        +	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)
        +		{
        +		if (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, &password_context))
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	/* Everything's fine. */
        +#ifndef OPENSSL_NO_RSA
        +	if (hndidx_rsa == -1)
        +		hndidx_rsa = RSA_get_ex_new_index(0,
        +			"nFast HWCryptoHook RSA key handle",
        +			NULL, NULL, NULL);
        +#endif
        +	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;
        +#ifndef OPENSSL_NO_RSA
        +	p_hwcrhk_RSA = NULL;
        +	p_hwcrhk_RSALoadKey = NULL;
        +	p_hwcrhk_RSAGetPublicKey = NULL;
        +	p_hwcrhk_RSAUnloadKey = NULL;
        +#endif
        +	p_hwcrhk_ModExpCRT = NULL;
        +	p_hwcrhk_RandomBytes = NULL;
        +	return 0;
        +	}
        +
        +static int hwcrhk_finish(ENGINE *e)
        +	{
        +	int to_return = 1;
        +	free_HWCRHK_LIBNAME();
        +	if(hwcrhk_dso == NULL)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
        +		to_return = 0;
        +		goto err;
        +		}
        +	release_context(hwcrhk_context);
        +	if(!DSO_free(hwcrhk_dso))
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_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;
        +#ifndef OPENSSL_NO_RSA
        +	p_hwcrhk_RSA = NULL;
        +	p_hwcrhk_RSALoadKey = NULL;
        +	p_hwcrhk_RSAGetPublicKey = NULL;
        +	p_hwcrhk_RSAUnloadKey = NULL;
        +#endif
        +	p_hwcrhk_ModExpCRT = NULL;
        +	p_hwcrhk_RandomBytes = NULL;
        +	return to_return;
        +	}
        +
        +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int to_return = 1;
        +
        +	switch(cmd)
        +		{
        +	case HWCRHK_CMD_SO_PATH:
        +		if(hwcrhk_dso)
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		if(p == NULL)
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		return set_HWCRHK_LIBNAME((const char *)p);
        +	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
        +			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
        +		}
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		break;
        +	case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
        +		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +		password_context.password_callback = (pem_password_cb *)f;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		break;
        +	case ENGINE_CTRL_SET_USER_INTERFACE:
        +	case HWCRHK_CMD_SET_USER_INTERFACE:
        +		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +		password_context.ui_method = (UI_METHOD *)p;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		break;
        +	case ENGINE_CTRL_SET_CALLBACK_DATA:
        +	case HWCRHK_CMD_SET_CALLBACK_DATA:
        +		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +		password_context.callback_data = p;
        +		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:
        +	case HWCRHK_CMD_FORK_CHECK:
        +		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;
        +	case HWCRHK_CMD_THREAD_LOCKING:
        +		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        +		disable_mutex_callbacks = ((i == 0) ? 0 : 1);
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		break;
        +
        +	/* The command isn't understood by this engine */
        +	default:
        +		HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
        +			HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +		to_return = 0;
        +		break;
        +		}
        +
        +	return to_return;
        +	}
        +
        +static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rtmp = NULL;
        +#endif
        +	EVP_PKEY *res = NULL;
        +#ifndef OPENSSL_NO_RSA
        +	HWCryptoHook_MPI e, n;
        +	HWCryptoHook_RSAKeyHandle *hptr;
        +#endif
        +#if !defined(OPENSSL_NO_RSA)
        +	char tempbuf[1024];
        +	HWCryptoHook_ErrMsgBuf rmsg;
        +	HWCryptoHook_PassphraseContext ppctx;
        +#endif
        +
        +#if !defined(OPENSSL_NO_RSA)
        +	rmsg.buf = tempbuf;
        +	rmsg.size = sizeof(tempbuf);
        +#endif
        +
        +	if(!hwcrhk_context)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
        +			HWCRHK_R_NOT_INITIALISED);
        +		goto err;
        +		}
        +#ifndef OPENSSL_NO_RSA
        +	hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
        +	if (!hptr)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
        +			ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +        ppctx.ui_method = ui_method;
        +	ppctx.callback_data = callback_data;
        +	if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
        +		&rmsg, &ppctx))
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
        +			HWCRHK_R_CHIL_ERROR);
        +		ERR_add_error_data(1,rmsg.buf);
        +		goto err;
        +		}
        +	if (!*hptr)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
        +			HWCRHK_R_NO_KEY);
        +		goto err;
        +		}
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	rtmp = RSA_new_method(eng);
        +	RSA_set_ex_data(rtmp, hndidx_rsa, (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)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,HWCRHK_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))
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
        +			HWCRHK_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);
        +#endif
        +
        +        if (!res)
        +                HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
        +                        HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
        +
        +	return res;
        + err:
        +#ifndef OPENSSL_NO_RSA
        +	if (rtmp)
        +		RSA_free(rtmp);
        +#endif
        +	return NULL;
        +	}
        +
        +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data)
        +	{
        +	EVP_PKEY *res = NULL;
        +
        +#ifndef OPENSSL_NO_RSA
        +        res = hwcrhk_load_privkey(eng, key_id,
        +                ui_method, callback_data);
        +#endif
        +
        +	if (res)
        +		switch(res->type)
        +			{
        +#ifndef OPENSSL_NO_RSA
        +		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;
        +			rsa->n = NULL;
        +			rsa->e = NULL;
        +			CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
        +			RSA_free(rsa);
        +			}
        +			break;
        +#endif
        +		default:
        +			HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
        +				HWCRHK_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, const 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 = sizeof(tempbuf);
        +
        +	if(!hwcrhk_context)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_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)
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
        +			}
        +		else
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
        +			}
        +		ERR_add_error_data(1,rmsg.buf);
        +		goto err;
        +		}
        +
        +	to_return = 1;
        +err:
        +	return to_return;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA 
        +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	char tempbuf[1024];
        +	HWCryptoHook_ErrMsgBuf rmsg;
        +	HWCryptoHook_RSAKeyHandle *hptr;
        +	int to_return = 0, ret;
        +
        +	rmsg.buf = tempbuf;
        +	rmsg.size = sizeof(tempbuf);
        +
        +	if(!hwcrhk_context)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,HWCRHK_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_rsa))
        +		!= NULL)
        +		{
        +		HWCryptoHook_MPI m_a, m_r;
        +
        +		if(!rsa->n)
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
        +				HWCRHK_R_MISSING_KEY_COMPONENTS);
        +			goto err;
        +			}
        +
        +		/* 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)
        +				{
        +				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
        +					HWCRHK_R_REQUEST_FALLBACK);
        +				}
        +			else
        +				{
        +				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
        +					HWCRHK_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)
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
        +				HWCRHK_R_MISSING_KEY_COMPONENTS);
        +			goto err;
        +			}
        +
        +		/* 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, &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)
        +				{
        +				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
        +					HWCRHK_R_REQUEST_FALLBACK);
        +				}
        +			else
        +				{
        +				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
        +					HWCRHK_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;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int hwcrhk_mod_exp_mont(BIGNUM *r, const 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);
        +	}
        +
        +static int hwcrhk_rsa_finish(RSA *rsa)
        +	{
        +	HWCryptoHook_RSAKeyHandle *hptr;
        +
        +	hptr = RSA_get_ex_data(rsa, hndidx_rsa);
        +	if (hptr)
        +                {
        +                p_hwcrhk_RSAUnloadKey(*hptr, NULL);
        +                OPENSSL_free(hptr);
        +		RSA_set_ex_data(rsa, hndidx_rsa, NULL);
        +                }
        +	return 1;
        +	}
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
        +		const 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);
        +	}
        +#endif
        +
        +/* 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 = sizeof(tempbuf);
        +
        +	if(!hwcrhk_context)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_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)
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
        +				HWCRHK_R_REQUEST_FALLBACK);
        +			}
        +		else
        +			{
        +			HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
        +				HWCRHK_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;
        +	}
        +
        +/* 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 1; /* failure */
        +	return 0; /* success */
        +	}
        +
        +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
        +	{
        +	CRYPTO_w_lock(mt->lockid);
        +	return 0;
        +	}
        +
        +static 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)
        +	{
        +	pem_password_cb *callback = NULL;
        +	void *callback_data = NULL;
        +        UI_METHOD *ui_method = NULL;
        +	/* Despite what the documentation says prompt_info can be
        +	 * an empty string.
        +	 */
        +	if (prompt_info && !*prompt_info)
        +		prompt_info = NULL;
        +
        +        if (cactx)
        +                {
        +                if (cactx->ui_method)
        +                        ui_method = cactx->ui_method;
        +		if (cactx->password_callback)
        +			callback = cactx->password_callback;
        +		if (cactx->callback_data)
        +			callback_data = cactx->callback_data;
        +                }
        +	if (ppctx)
        +		{
        +                if (ppctx->ui_method)
        +                        {
        +                        ui_method = ppctx->ui_method;
        +                        callback = NULL;
        +                        }
        +		if (ppctx->callback_data)
        +			callback_data = ppctx->callback_data;
        +		}
        +	if (callback == NULL && ui_method == NULL)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
        +		return -1;
        +		}
        +
        +        if (ui_method)
        +                {
        +                UI *ui = UI_new_method(ui_method);
        +                if (ui)
        +                        {
        +                        int ok;
        +                        char *prompt = UI_construct_prompt(ui,
        +                                "pass phrase", prompt_info);
        +
        +                        ok = UI_add_input_string(ui,prompt,
        +                                UI_INPUT_FLAG_DEFAULT_PWD,
        +				buf,0,(*len_io) - 1);
        +                        UI_add_user_data(ui, callback_data);
        +			UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
        +
        +			if (ok >= 0)
        +				do
        +					{
        +					ok=UI_process(ui);
        +					}
        +				while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
        +
        +                        if (ok >= 0)
        +                                *len_io = strlen(buf);
        +
        +                        UI_free(ui);
        +                        OPENSSL_free(prompt);
        +                        }
        +                }
        +        else
        +                {
        +                *len_io = callback(buf, *len_io, 0, callback_data);
        +                }
        +	if(!*len_io)
        +		return -1;
        +	return 0;
        +	}
        +
        +static int hwcrhk_insert_card(const char *prompt_info,
        +		      const char *wrong_info,
        +		      HWCryptoHook_PassphraseContext *ppctx,
        +		      HWCryptoHook_CallerContext *cactx)
        +        {
        +        int ok = -1;
        +        UI *ui;
        +	void *callback_data = NULL;
        +        UI_METHOD *ui_method = NULL;
        +
        +        if (cactx)
        +                {
        +                if (cactx->ui_method)
        +                        ui_method = cactx->ui_method;
        +		if (cactx->callback_data)
        +			callback_data = cactx->callback_data;
        +                }
        +	if (ppctx)
        +		{
        +                if (ppctx->ui_method)
        +                        ui_method = ppctx->ui_method;
        +		if (ppctx->callback_data)
        +			callback_data = ppctx->callback_data;
        +		}
        +	if (ui_method == NULL)
        +		{
        +		HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
        +			HWCRHK_R_NO_CALLBACK);
        +		return -1;
        +		}
        +
        +	ui = UI_new_method(ui_method);
        +
        +	if (ui)
        +		{
        +		char answer;
        +		char buf[BUFSIZ];
        +		/* Despite what the documentation says wrong_info can be
        +	 	 * an empty string.
        +		 */
        +		if (wrong_info && *wrong_info)
        +			BIO_snprintf(buf, sizeof(buf)-1,
        +				"Current card: \"%s\"\n", wrong_info);
        +		else
        +			buf[0] = 0;
        +		ok = UI_dup_info_string(ui, buf);
        +		if (ok >= 0 && prompt_info)
        +			{
        +			BIO_snprintf(buf, sizeof(buf)-1,
        +				"Insert card \"%s\"", prompt_info);
        +			ok = UI_dup_input_boolean(ui, buf,
        +				"\n then hit <enter> or C<enter> to cancel\n",
        +				"\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
        +			}
        +		UI_add_user_data(ui, callback_data);
        +
        +		if (ok >= 0)
        +			ok = UI_process(ui);
        +		UI_free(ui);
        +
        +		if (ok == -2 || (ok >= 0 && answer == 'C'))
        +			ok = 1;
        +		else if (ok < 0)
        +			ok = -1;
        +		else
        +			ok = 0;
        +		}
        +	return ok;
        +	}
        +
        +static void hwcrhk_log_message(void *logstr, const char *message)
        +	{
        +	BIO *lstream = NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_BIO);
        +	if (logstr)
        +		lstream=*(BIO **)logstr;
        +	if (lstream)
        +		{
        +		BIO_printf(lstream, "%s\n", message);
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
        +	}
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */	   
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_hwcrhk_id) != 0) &&
        +			(strcmp(id, engine_hwcrhk_id_alt) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW_CHIL */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_chil.ec b/vendor/openssl/openssl/engines/e_chil.ec
        new file mode 100644
        index 000000000..b5a76e17d
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_chil.ec
        @@ -0,0 +1 @@
        +L HWCRHK	e_chil_err.h			e_chil_err.c
        diff --git a/vendor/openssl/openssl/engines/e_chil_err.c b/vendor/openssl/openssl/engines/e_chil_err.c
        new file mode 100644
        index 000000000..c5983b2fd
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_chil_err.c
        @@ -0,0 +1,160 @@
        +/* e_chil_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_chil_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA HWCRHK_str_functs[]=
        +	{
        +{ERR_FUNC(HWCRHK_F_HWCRHK_CTRL),	"HWCRHK_CTRL"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_FINISH),	"HWCRHK_FINISH"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS),	"HWCRHK_GET_PASS"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_INIT),	"HWCRHK_INIT"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD),	"HWCRHK_INSERT_CARD"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY),	"HWCRHK_LOAD_PRIVKEY"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY),	"HWCRHK_LOAD_PUBKEY"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP),	"HWCRHK_MOD_EXP"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES),	"HWCRHK_RAND_BYTES"},
        +{ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP),	"HWCRHK_RSA_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA HWCRHK_str_reasons[]=
        +	{
        +{ERR_REASON(HWCRHK_R_ALREADY_LOADED)     ,"already loaded"},
        +{ERR_REASON(HWCRHK_R_BIO_WAS_FREED)      ,"bio was freed"},
        +{ERR_REASON(HWCRHK_R_CHIL_ERROR)         ,"chil error"},
        +{ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(HWCRHK_R_DSO_FAILURE)        ,"dso failure"},
        +{ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{ERR_REASON(HWCRHK_R_NOT_INITIALISED)    ,"not initialised"},
        +{ERR_REASON(HWCRHK_R_NOT_LOADED)         ,"not loaded"},
        +{ERR_REASON(HWCRHK_R_NO_CALLBACK)        ,"no callback"},
        +{ERR_REASON(HWCRHK_R_NO_KEY)             ,"no key"},
        +{ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED),"private key algorithms disabled"},
        +{ERR_REASON(HWCRHK_R_REQUEST_FAILED)     ,"request failed"},
        +{ERR_REASON(HWCRHK_R_REQUEST_FALLBACK)   ,"request fallback"},
        +{ERR_REASON(HWCRHK_R_UNIT_FAILURE)       ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef HWCRHK_LIB_NAME
        +static ERR_STRING_DATA HWCRHK_lib_name[]=
        +        {
        +{0	,HWCRHK_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int HWCRHK_lib_error_code=0;
        +static int HWCRHK_error_init=1;
        +
        +static void ERR_load_HWCRHK_strings(void)
        +	{
        +	if (HWCRHK_lib_error_code == 0)
        +		HWCRHK_lib_error_code=ERR_get_next_error_library();
        +
        +	if (HWCRHK_error_init)
        +		{
        +		HWCRHK_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
        +		ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
        +#endif
        +
        +#ifdef HWCRHK_LIB_NAME
        +		HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code,0,0);
        +		ERR_load_strings(0,HWCRHK_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_HWCRHK_strings(void)
        +	{
        +	if (HWCRHK_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
        +		ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
        +#endif
        +
        +#ifdef HWCRHK_LIB_NAME
        +		ERR_unload_strings(0,HWCRHK_lib_name);
        +#endif
        +		HWCRHK_error_init=1;
        +		}
        +	}
        +
        +static void ERR_HWCRHK_error(int function, int reason, char *file, int line)
        +	{
        +	if (HWCRHK_lib_error_code == 0)
        +		HWCRHK_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(HWCRHK_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_chil_err.h b/vendor/openssl/openssl/engines/e_chil_err.h
        new file mode 100644
        index 000000000..3c42a0239
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_chil_err.h
        @@ -0,0 +1,104 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_HWCRHK_ERR_H
        +#define HEADER_HWCRHK_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_HWCRHK_strings(void);
        +static void ERR_unload_HWCRHK_strings(void);
        +static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
        +#define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the HWCRHK functions. */
        +
        +/* Function codes. */
        +#define HWCRHK_F_HWCRHK_CTRL				 100
        +#define HWCRHK_F_HWCRHK_FINISH				 101
        +#define HWCRHK_F_HWCRHK_GET_PASS			 102
        +#define HWCRHK_F_HWCRHK_INIT				 103
        +#define HWCRHK_F_HWCRHK_INSERT_CARD			 104
        +#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY			 105
        +#define HWCRHK_F_HWCRHK_LOAD_PUBKEY			 106
        +#define HWCRHK_F_HWCRHK_MOD_EXP				 107
        +#define HWCRHK_F_HWCRHK_RAND_BYTES			 108
        +#define HWCRHK_F_HWCRHK_RSA_MOD_EXP			 109
        +
        +/* Reason codes. */
        +#define HWCRHK_R_ALREADY_LOADED				 100
        +#define HWCRHK_R_BIO_WAS_FREED				 101
        +#define HWCRHK_R_CHIL_ERROR				 102
        +#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED		 103
        +#define HWCRHK_R_DSO_FAILURE				 104
        +#define HWCRHK_R_MISSING_KEY_COMPONENTS			 105
        +#define HWCRHK_R_NOT_INITIALISED			 106
        +#define HWCRHK_R_NOT_LOADED				 107
        +#define HWCRHK_R_NO_CALLBACK				 108
        +#define HWCRHK_R_NO_KEY					 109
        +#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED	 110
        +#define HWCRHK_R_REQUEST_FAILED				 111
        +#define HWCRHK_R_REQUEST_FALLBACK			 112
        +#define HWCRHK_R_UNIT_FAILURE				 113
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_cswift.c b/vendor/openssl/openssl/engines/e_cswift.c
        new file mode 100644
        index 000000000..2e64ff327
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_cswift.c
        @@ -0,0 +1,1129 @@
        +/* crypto/engine/hw_cswift.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_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
        +
        +#define CSWIFT_LIB_NAME "cswift engine"
        +#include "e_cswift_err.c"
        +
        +#define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)
        +
        +static int cswift_destroy(ENGINE *e);
        +static int cswift_init(ENGINE *e);
        +static int cswift_finish(ENGINE *e);
        +static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +#ifndef OPENSSL_NO_RSA
        +static int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
        +#endif
        +
        +/* BIGNUM stuff */
        +static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx);
        +#ifndef OPENSSL_NO_RSA
        +static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
        +		const BIGNUM *iqmp, BN_CTX *ctx);
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +/* RSA stuff */
        +static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* 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);
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* DH stuff */
        +/* This function is alised to mod_exp (with the DH and mont dropped). */
        +static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
        +		const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +
        +/* RAND stuff */
        +static int cswift_rand_bytes(unsigned char *buf, int num);
        +static int cswift_rand_status(void);
        +
        +/* The definitions for control commands specific to this engine */
        +#define CSWIFT_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
        +	{CSWIFT_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'cswift' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* 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,
        +	NULL
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* 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 */
        +	NULL, /* dsa_paramgen */
        +	NULL /* dsa_keygen */
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* 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,
        +	NULL
        +	};
        +#endif
        +
        +static RAND_METHOD cswift_random =
        +    {
        +    /* "CryptoSwift RAND method", */
        +    NULL,
        +    cswift_rand_bytes,
        +    NULL,
        +    NULL,
        +    cswift_rand_bytes,
        +    cswift_rand_status,
        +    };
        +
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_cswift_id = "cswift";
        +static const char *engine_cswift_name = "CryptoSwift hardware engine support";
        +
        +/* This internal function is used by ENGINE_cswift() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth2;
        +#endif
        +	if(!ENGINE_set_id(e, engine_cswift_id) ||
        +			!ENGINE_set_name(e, engine_cswift_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &cswift_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			!ENGINE_set_DSA(e, &cswift_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH(e, &cswift_dh) ||
        +#endif
        +			!ENGINE_set_RAND(e, &cswift_random) ||
        +			!ENGINE_set_destroy_function(e, cswift_destroy) ||
        +			!ENGINE_set_init_function(e, cswift_init) ||
        +			!ENGINE_set_finish_function(e, cswift_finish) ||
        +			!ENGINE_set_ctrl_function(e, cswift_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, cswift_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* 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;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth2 = DH_OpenSSL();
        +	cswift_dh.generate_key = meth2->generate_key;
        +	cswift_dh.compute_key = meth2->compute_key;
        +#endif
        +
        +	/* Ensure the cswift error handling is set up */
        +	ERR_load_CSWIFT_strings();
        +	return 1;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_cswift(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_cswift(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_cswift();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* 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 = NULL;
        +static const char *get_CSWIFT_LIBNAME(void)
        +	{
        +	if(CSWIFT_LIBNAME)
        +		return CSWIFT_LIBNAME;
        +	return "swift";
        +	}
        +static void free_CSWIFT_LIBNAME(void)
        +	{
        +	if(CSWIFT_LIBNAME)
        +		OPENSSL_free((void*)CSWIFT_LIBNAME);
        +	CSWIFT_LIBNAME = NULL;
        +	}
        +static long set_CSWIFT_LIBNAME(const char *name)
        +	{
        +	free_CSWIFT_LIBNAME();
        +	return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
        +	}
        +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);
        +	}
        +
        +/* Destructor (complements the "ENGINE_cswift()" constructor) */
        +static int cswift_destroy(ENGINE *e)
        +	{
        +	free_CSWIFT_LIBNAME();
        +	ERR_unload_CSWIFT_strings();
        +	return 1;
        +	}
        +
        +/* (de)initialisation functions. */
        +static int cswift_init(ENGINE *e)
        +	{
        +        SW_CONTEXT_HANDLE hac;
        +        t_swAcquireAccContext *p1;
        +        t_swAttachKeyParam *p2;
        +        t_swSimpleRequest *p3;
        +        t_swReleaseAccContext *p4;
        +
        +	if(cswift_dso != NULL)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
        +		goto err;
        +		}
        +	/* Attempt to load libswift.so/swift.dll/whatever. */
        +	cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
        +	if(cswift_dso == NULL)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
        +		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)))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
        +		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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	release_context(hac);
        +	/* Everything's fine. */
        +	return 1;
        +err:
        +	if(cswift_dso)
        +	{
        +		DSO_free(cswift_dso);
        +		cswift_dso = NULL;
        +	}
        +	p_CSwift_AcquireAccContext = NULL;
        +	p_CSwift_AttachKeyParam = NULL;
        +	p_CSwift_SimpleRequest = NULL;
        +	p_CSwift_ReleaseAccContext = NULL;
        +	return 0;
        +	}
        +
        +static int cswift_finish(ENGINE *e)
        +	{
        +	free_CSWIFT_LIBNAME();
        +	if(cswift_dso == NULL)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
        +		return 0;
        +		}
        +	if(!DSO_free(cswift_dso))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
        +		return 0;
        +		}
        +	cswift_dso = NULL;
        +	p_CSwift_AcquireAccContext = NULL;
        +	p_CSwift_AttachKeyParam = NULL;
        +	p_CSwift_SimpleRequest = NULL;
        +	p_CSwift_ReleaseAccContext = NULL;
        +	return 1;
        +	}
        +
        +static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int initialised = ((cswift_dso == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case CSWIFT_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		return set_CSWIFT_LIBNAME((const char *)p);
        +	default:
        +		break;
        +		}
        +	CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +/* Un petit mod_exp */
        +static int cswift_mod_exp(BIGNUM *r, const 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 <grin>. 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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	acquired = 1;
        +	/* Prepare the params */
        +	BN_CTX_start(ctx);
        +	modulus = BN_CTX_get(ctx);
        +	exponent = BN_CTX_get(ctx);
        +	argument = BN_CTX_get(ctx);
        +	result = BN_CTX_get(ctx);
        +	if(!result)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_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:
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
        +		goto err;
        +	default:
        +		{
        +		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_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[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_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);
        +	BN_CTX_end(ctx);
        +	return to_return;
        +	}
        +
        +
        +#ifndef OPENSSL_NO_RSA
        +int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
        +{
        +	int mod;
        +	int numbytes = BN_num_bytes(in);
        +
        +	mod = 0;
        +	while( ((out->nbytes = (numbytes+mod)) % 32) )
        +	{
        +		mod++;
        +	}
        +	out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
        +	if(!out->value)
        +	{
        +		return 0;
        +	}
        +	BN_bn2bin(in, &out->value[mod]);
        +	if(mod)
        +		memset(out->value, 0, mod);
        +
        +	return 1;
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Un petit mod_exp chinois */
        +static int cswift_mod_exp_crt(BIGNUM *r, const 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 *result = NULL;
        +	BIGNUM *argument = NULL;
        +	int to_return = 0; /* expect failure */
        +	int acquired = 0;
        +
        +	sw_param.up.crt.p.value = NULL;
        +	sw_param.up.crt.q.value = NULL;
        +	sw_param.up.crt.dmp1.value = NULL;
        +	sw_param.up.crt.dmq1.value = NULL;
        +	sw_param.up.crt.iqmp.value = NULL;
        + 
        +	if(!get_context(&hac))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	acquired = 1;
        +
        +	/* Prepare the params */
        +	argument = BN_new();
        +	result = BN_new();
        +	if(!result || !argument)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
        +		goto err;
        +		}
        +
        +
        +	sw_param.type = SW_ALG_CRT;
        +	/************************************************************************/
        +	/* 04/02/2003                                                           */
        +	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
        +	/* limitation of cswift with values not a multiple of 32                */
        +	/************************************************************************/
        +	if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
        +	{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +	if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
        +	{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +	if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
        +	{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +	if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
        +	{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +	if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
        +	{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +	if(	!bn_wexpand(argument, a->top) ||
        +			!bn_wexpand(result, p->top + q->top))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
        +		goto err;
        +		}
        +
        +	/* Attach the key params */
        +	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
        +	switch(sw_status)
        +		{
        +	case SW_OK:
        +		break;
        +	case SW_ERR_INPUT_SIZE:
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
        +		goto err;
        +	default:
        +		{
        +		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_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[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_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(sw_param.up.crt.p.value)
        +		OPENSSL_free(sw_param.up.crt.p.value);
        +	if(sw_param.up.crt.q.value)
        +		OPENSSL_free(sw_param.up.crt.q.value);
        +	if(sw_param.up.crt.dmp1.value)
        +		OPENSSL_free(sw_param.up.crt.dmp1.value);
        +	if(sw_param.up.crt.dmq1.value)
        +		OPENSSL_free(sw_param.up.crt.dmq1.value);
        +	if(sw_param.up.crt.iqmp.value)
        +		OPENSSL_free(sw_param.up.crt.iqmp.value);
        +	if(result)
        +		BN_free(result);
        +	if(argument)
        +		BN_free(argument);
        +	if(acquired)
        +		release_context(hac);
        +	return to_return;
        +	}
        +#endif
        + 
        +#ifndef OPENSSL_NO_RSA
        +static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	int to_return = 0;
        +	const RSA_METHOD * def_rsa_method;
        +
        +	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
        +		goto err;
        +		}
        +
        +	/* Try the limits of RSA (2048 bits) */
        +	if(BN_num_bytes(rsa->p) > 128 ||
        +		BN_num_bytes(rsa->q) > 128 ||
        +		BN_num_bytes(rsa->dmp1) > 128 ||
        +		BN_num_bytes(rsa->dmq1) > 128 ||
        +		BN_num_bytes(rsa->iqmp) > 128)
        +	{
        +#ifdef RSA_NULL
        +		def_rsa_method=RSA_null_method();
        +#else
        +#if 0
        +		def_rsa_method=RSA_PKCS1_RSAref();
        +#else
        +		def_rsa_method=RSA_PKCS1_SSLeay();
        +#endif
        +#endif
        +		if(def_rsa_method)
        +			return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx);
        +	}
        +
        +	to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
        +		rsa->dmq1, rsa->iqmp, ctx);
        +err:
        +	return to_return;
        +	}
        +
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	const RSA_METHOD * def_rsa_method;
        +
        +	/* Try the limits of RSA (2048 bits) */
        +	if(BN_num_bytes(r) > 256 ||
        +		BN_num_bytes(a) > 256 ||
        +		BN_num_bytes(m) > 256)
        +	{
        +#ifdef RSA_NULL
        +		def_rsa_method=RSA_null_method();
        +#else
        +#if 0
        +		def_rsa_method=RSA_PKCS1_RSAref();
        +#else
        +		def_rsa_method=RSA_PKCS1_SSLeay();
        +#endif
        +#endif
        +		if(def_rsa_method)
        +			return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
        +	}
        +
        +	return cswift_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif	/* OPENSSL_NO_RSA */
        +
        +#ifndef OPENSSL_NO_DSA
        +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;
        +	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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	acquired = 1;
        +	/* Prepare the params */
        +	BN_CTX_start(ctx);
        +	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(!result)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_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:
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
        +		goto err;
        +	default:
        +		{
        +		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_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[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
        +		sprintf(tmpbuf, "%ld", sw_status);
        +		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
        +		goto err;
        +		}
        +	/* Convert the response */
        +	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(ctx)
        +		{
        +		BN_CTX_end(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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
        +		goto err;
        +		}
        +	acquired = 1;
        +	/* Prepare the params */
        +	BN_CTX_start(ctx);
        +	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(!argument)
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_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))
        +		{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_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:
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
        +		goto err;
        +	default:
        +		{
        +		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_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[DECIMAL_SIZE(sw_status)+1];
        +		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_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(ctx)
        +		{
        +		BN_CTX_end(ctx);
        +		BN_CTX_free(ctx);
        +		}
        +	return to_return;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
        +		const 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
        +
        +/* Random bytes are good */
        +static int cswift_rand_bytes(unsigned char *buf, int num)
        +{
        +	SW_CONTEXT_HANDLE hac;
        +	SW_STATUS swrc;
        +	SW_LARGENUMBER largenum;
        +	int acquired = 0;
        +	int to_return = 0; /* assume failure */
        +	unsigned char buf32[1024];
        +
        +
        +	if (!get_context(&hac))
        +	{
        +		CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE);
        +		goto err;
        +	}
        +	acquired = 1;
        +
        +	/************************************************************************/
        +	/* 04/02/2003                                                           */
        +	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
        +	/* limitation of cswift with values not a multiple of 32                */
        +	/************************************************************************/
        +
        +	while(num >= (int)sizeof(buf32))
        +	{
        +		largenum.value = buf;
        +		largenum.nbytes = sizeof(buf32);
        +		/* tell CryptoSwift how many bytes we want and where we want it.
        +		 * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
        +		 *       - CryptoSwift can only do multiple of 32-bits. */
        +		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
        +		if (swrc != SW_OK)
        +		{
        +			char tmpbuf[20];
        +			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
        +			sprintf(tmpbuf, "%ld", swrc);
        +			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
        +			goto err;
        +		}
        +		buf += sizeof(buf32);
        +		num -= sizeof(buf32);
        +	}
        +	if(num)
        +	{
        +		largenum.nbytes = sizeof(buf32);
        +		largenum.value = buf32;
        +		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
        +		if (swrc != SW_OK)
        +		{
        +			char tmpbuf[20];
        +			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
        +			sprintf(tmpbuf, "%ld", swrc);
        +			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
        +			goto err;
        +		}
        +		memcpy(buf, largenum.value, num);
        +	}
        +
        +	to_return = 1;  /* success */
        +err:
        +	if (acquired)
        +		release_context(hac);
        +
        +	return to_return;
        +}
        +
        +static int cswift_rand_status(void)
        +{
        +	return 1;
        +}
        +
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_cswift_id) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW_CSWIFT */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_cswift.ec b/vendor/openssl/openssl/engines/e_cswift.ec
        new file mode 100644
        index 000000000..a7f9d1143
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_cswift.ec
        @@ -0,0 +1 @@
        +L CSWIFT	e_cswift_err.h			e_cswift_err.c
        diff --git a/vendor/openssl/openssl/engines/e_cswift_err.c b/vendor/openssl/openssl/engines/e_cswift_err.c
        new file mode 100644
        index 000000000..c7942a31f
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_cswift_err.c
        @@ -0,0 +1,154 @@
        +/* e_cswift_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_cswift_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA CSWIFT_str_functs[]=
        +	{
        +{ERR_FUNC(CSWIFT_F_CSWIFT_CTRL),	"CSWIFT_CTRL"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_DSA_SIGN),	"CSWIFT_DSA_SIGN"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_DSA_VERIFY),	"CSWIFT_DSA_VERIFY"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_FINISH),	"CSWIFT_FINISH"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_INIT),	"CSWIFT_INIT"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP),	"CSWIFT_MOD_EXP"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP_CRT),	"CSWIFT_MOD_EXP_CRT"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_RAND_BYTES),	"CSWIFT_RAND_BYTES"},
        +{ERR_FUNC(CSWIFT_F_CSWIFT_RSA_MOD_EXP),	"CSWIFT_RSA_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA CSWIFT_str_reasons[]=
        +	{
        +{ERR_REASON(CSWIFT_R_ALREADY_LOADED)     ,"already loaded"},
        +{ERR_REASON(CSWIFT_R_BAD_KEY_SIZE)       ,"bad key size"},
        +{ERR_REASON(CSWIFT_R_BN_CTX_FULL)        ,"bn ctx full"},
        +{ERR_REASON(CSWIFT_R_BN_EXPAND_FAIL)     ,"bn expand fail"},
        +{ERR_REASON(CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(CSWIFT_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{ERR_REASON(CSWIFT_R_NOT_LOADED)         ,"not loaded"},
        +{ERR_REASON(CSWIFT_R_REQUEST_FAILED)     ,"request failed"},
        +{ERR_REASON(CSWIFT_R_UNIT_FAILURE)       ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef CSWIFT_LIB_NAME
        +static ERR_STRING_DATA CSWIFT_lib_name[]=
        +        {
        +{0	,CSWIFT_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int CSWIFT_lib_error_code=0;
        +static int CSWIFT_error_init=1;
        +
        +static void ERR_load_CSWIFT_strings(void)
        +	{
        +	if (CSWIFT_lib_error_code == 0)
        +		CSWIFT_lib_error_code=ERR_get_next_error_library();
        +
        +	if (CSWIFT_error_init)
        +		{
        +		CSWIFT_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
        +		ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
        +#endif
        +
        +#ifdef CSWIFT_LIB_NAME
        +		CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code,0,0);
        +		ERR_load_strings(0,CSWIFT_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_CSWIFT_strings(void)
        +	{
        +	if (CSWIFT_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
        +		ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
        +#endif
        +
        +#ifdef CSWIFT_LIB_NAME
        +		ERR_unload_strings(0,CSWIFT_lib_name);
        +#endif
        +		CSWIFT_error_init=1;
        +		}
        +	}
        +
        +static void ERR_CSWIFT_error(int function, int reason, char *file, int line)
        +	{
        +	if (CSWIFT_lib_error_code == 0)
        +		CSWIFT_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(CSWIFT_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_cswift_err.h b/vendor/openssl/openssl/engines/e_cswift_err.h
        new file mode 100644
        index 000000000..69c2a9f87
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_cswift_err.h
        @@ -0,0 +1,98 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_CSWIFT_ERR_H
        +#define HEADER_CSWIFT_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_CSWIFT_strings(void);
        +static void ERR_unload_CSWIFT_strings(void);
        +static void ERR_CSWIFT_error(int function, int reason, char *file, int line);
        +#define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the CSWIFT functions. */
        +
        +/* Function codes. */
        +#define CSWIFT_F_CSWIFT_CTRL				 100
        +#define CSWIFT_F_CSWIFT_DSA_SIGN			 101
        +#define CSWIFT_F_CSWIFT_DSA_VERIFY			 102
        +#define CSWIFT_F_CSWIFT_FINISH				 103
        +#define CSWIFT_F_CSWIFT_INIT				 104
        +#define CSWIFT_F_CSWIFT_MOD_EXP				 105
        +#define CSWIFT_F_CSWIFT_MOD_EXP_CRT			 106
        +#define CSWIFT_F_CSWIFT_RAND_BYTES			 108
        +#define CSWIFT_F_CSWIFT_RSA_MOD_EXP			 107
        +
        +/* Reason codes. */
        +#define CSWIFT_R_ALREADY_LOADED				 100
        +#define CSWIFT_R_BAD_KEY_SIZE				 101
        +#define CSWIFT_R_BN_CTX_FULL				 102
        +#define CSWIFT_R_BN_EXPAND_FAIL				 103
        +#define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED		 104
        +#define CSWIFT_R_MISSING_KEY_COMPONENTS			 105
        +#define CSWIFT_R_NOT_LOADED				 106
        +#define CSWIFT_R_REQUEST_FAILED				 107
        +#define CSWIFT_R_UNIT_FAILURE				 108
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_gmp.c b/vendor/openssl/openssl/engines/e_gmp.c
        new file mode 100644
        index 000000000..a3d47151e
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_gmp.c
        @@ -0,0 +1,480 @@
        +/* crypto/engine/e_gmp.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2003.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 engine is not (currently) compiled in by default. Do enable it,
        + * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and
        + * headers must reside in one of the paths searched by the compiler/linker,
        + * otherwise paths must be specified - eg. try configuring with
        + * "enable-gmp -I<includepath> -L<libpath> -lgmp". YMMV. */
        +
        +/* As for what this does - it's a largely unoptimised implementation of an
        + * ENGINE that uses the GMP library to perform RSA private key operations. To
        + * obtain more information about what "unoptimised" means, see my original mail
        + * on the subject (though ignore the build instructions which have since
        + * changed);
        + *
        + *    http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html
        + *
        + * On my athlon system at least, it appears the builtin OpenSSL code is now
        + * slightly faster, which is to say that the RSA-related MPI performance
        + * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty
        + * balanced for this chip, and so the performance degradation in this ENGINE by
        + * having to convert to/from GMP formats (and not being able to cache
        + * montgomery forms) is probably the difference. However, if some unconfirmed
        + * reports from users is anything to go by, the situation on some other
        + * chipsets might be a good deal more favourable to the GMP version (eg. PPC).
        + * Feedback welcome. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_GMP
        +
        +#include <gmp.h>
        +
        +#define E_GMP_LIB_NAME "gmp engine"
        +#include "e_gmp_err.c"
        +
        +static int e_gmp_destroy(ENGINE *e);
        +static int e_gmp_init(ENGINE *e);
        +static int e_gmp_finish(ENGINE *e);
        +static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 
        +
        +#ifndef OPENSSL_NO_RSA
        +/* RSA stuff */
        +static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +static int e_gmp_rsa_finish(RSA *r);
        +#endif
        +
        +/* The definitions for control commands specific to this engine */
        +/* #define E_GMP_CMD_SO_PATH		ENGINE_CMD_BASE */
        +static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = {
        +#if 0
        +	{E_GMP_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'e_gmp' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +#endif
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD e_gmp_rsa =
        +	{
        +	"GMP RSA method",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	e_gmp_rsa_mod_exp,
        +	NULL,
        +	NULL,
        +	e_gmp_rsa_finish,
        +	/* These flags initialise montgomery crud that GMP ignores, however it
        +	 * makes sure the public key ops (which are done in openssl) don't seem
        +	 * *slower* than usual :-) */
        +	RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_e_gmp_id = "gmp";
        +static const char *engine_e_gmp_name = "GMP engine support";
        +
        +/* This internal function is used by ENGINE_gmp() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +	if(!ENGINE_set_id(e, engine_e_gmp_id) ||
        +			!ENGINE_set_name(e, engine_e_gmp_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &e_gmp_rsa) ||
        +#endif
        +			!ENGINE_set_destroy_function(e, e_gmp_destroy) ||
        +			!ENGINE_set_init_function(e, e_gmp_init) ||
        +			!ENGINE_set_finish_function(e, e_gmp_finish) ||
        +			!ENGINE_set_ctrl_function(e, e_gmp_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, e_gmp_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	meth1 = RSA_PKCS1_SSLeay();
        +	e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
        +	e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
        +	e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
        +	e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
        +	e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp;
        +#endif
        +
        +	/* Ensure the e_gmp error handling is set up */
        +	ERR_load_GMP_strings();
        +	return 1;
        +	}
        +
        +static ENGINE *engine_gmp(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_gmp(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_gmp();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Used to attach our own key-data to an RSA structure */
        +static int hndidx_rsa = -1;
        +#endif
        +
        +static int e_gmp_destroy(ENGINE *e)
        +	{
        +	ERR_unload_GMP_strings();
        +	return 1;
        +	}
        +
        +/* (de)initialisation functions. */
        +static int e_gmp_init(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	if (hndidx_rsa == -1)
        +		hndidx_rsa = RSA_get_ex_new_index(0,
        +			"GMP-based RSA key handle",
        +			NULL, NULL, NULL);
        +#endif
        +	if (hndidx_rsa == -1)
        +		return 0;
        +	return 1;
        +	}
        +
        +static int e_gmp_finish(ENGINE *e)
        +	{
        +	return 1;
        +	}
        +
        +static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int to_return = 1;
        +
        +	switch(cmd)
        +		{
        +#if 0
        +	case E_GMP_CMD_SO_PATH:
        +		/* ... */
        +#endif
        +	/* The command isn't understood by this engine */
        +	default:
        +		GMPerr(GMP_F_E_GMP_CTRL,
        +			GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +		to_return = 0;
        +		break;
        +		}
        +
        +	return to_return;
        +	}
        +
        +
        +/* Most often limb sizes will be the same. If not, we use hex conversion
        + * which is neat, but extremely inefficient. */
        +static int bn2gmp(const BIGNUM *bn, mpz_t g)
        +	{
        +	bn_check_top(bn);
        +	if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
        +			(BN_BITS2 == GMP_NUMB_BITS)) 
        +		{
        +		/* The common case */
        +		if(!_mpz_realloc (g, bn->top))
        +			return 0;
        +		memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0]));
        +		g->_mp_size = bn->top;
        +		if(bn->neg)
        +			g->_mp_size = -g->_mp_size;
        +		return 1;
        +		}
        +	else
        +		{
        +		int toret;
        +		char *tmpchar = BN_bn2hex(bn);
        +		if(!tmpchar) return 0;
        +		toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
        +		OPENSSL_free(tmpchar);
        +		return toret;
        +		}
        +	}
        +
        +static int gmp2bn(mpz_t g, BIGNUM *bn)
        +	{
        +	if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
        +			(BN_BITS2 == GMP_NUMB_BITS))
        +		{
        +		/* The common case */
        +		int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size;
        +		BN_zero(bn);
        +		if(bn_expand2 (bn, s) == NULL)
        +			return 0;
        +		bn->top = s;
        +		memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0]));
        +		bn_correct_top(bn);
        +		bn->neg = g->_mp_size >= 0 ? 0 : 1;
        +		return 1;
        +		}
        +	else
        +		{
        +		int toret;
        +		char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
        +		if(!tmpchar) return 0;
        +		mpz_get_str(tmpchar, 16, g);
        +		toret = BN_hex2bn(&bn, tmpchar);
        +		OPENSSL_free(tmpchar);
        +		return toret;
        +		}
        +	}
        +
        +#ifndef OPENSSL_NO_RSA 
        +typedef struct st_e_gmp_rsa_ctx
        +	{
        +	int public_only;
        +	mpz_t n;
        +	mpz_t d;
        +	mpz_t e;
        +	mpz_t p;
        +	mpz_t q;
        +	mpz_t dmp1;
        +	mpz_t dmq1;
        +	mpz_t iqmp;
        +	mpz_t r0, r1, I0, m1;
        +	} E_GMP_RSA_CTX;
        +
        +static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa)
        +	{
        +	E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
        +	if(hptr) return hptr;
        +	hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX));
        +	if(!hptr) return NULL;
        +	/* These inits could probably be replaced by more intelligent
        +	 * mpz_init2() versions, to reduce malloc-thrashing. */
        +	mpz_init(hptr->n);
        +	mpz_init(hptr->d);
        +	mpz_init(hptr->e);
        +	mpz_init(hptr->p);
        +	mpz_init(hptr->q);
        +	mpz_init(hptr->dmp1);
        +	mpz_init(hptr->dmq1);
        +	mpz_init(hptr->iqmp);
        +	mpz_init(hptr->r0);
        +	mpz_init(hptr->r1);
        +	mpz_init(hptr->I0);
        +	mpz_init(hptr->m1);
        +	if(!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e))
        +		goto err;
        +	if(!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
        +		{
        +		hptr->public_only = 1;
        +		return hptr;
        +		}
        +	if(!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) ||
        +			!bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) ||
        +			!bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp))
        +		goto err;
        +	hptr->public_only = 0;
        +	RSA_set_ex_data(rsa, hndidx_rsa, hptr);
        +	return hptr;
        +err:
        +	mpz_clear(hptr->n);
        +	mpz_clear(hptr->d);
        +	mpz_clear(hptr->e);
        +	mpz_clear(hptr->p);
        +	mpz_clear(hptr->q);
        +	mpz_clear(hptr->dmp1);
        +	mpz_clear(hptr->dmq1);
        +	mpz_clear(hptr->iqmp);
        +	mpz_clear(hptr->r0);
        +	mpz_clear(hptr->r1);
        +	mpz_clear(hptr->I0);
        +	mpz_clear(hptr->m1);
        +	OPENSSL_free(hptr);
        +	return NULL;
        +	}
        +
        +static int e_gmp_rsa_finish(RSA *rsa)
        +	{
        +	E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
        +	if(!hptr) return 0;
        +	mpz_clear(hptr->n);
        +	mpz_clear(hptr->d);
        +	mpz_clear(hptr->e);
        +	mpz_clear(hptr->p);
        +	mpz_clear(hptr->q);
        +	mpz_clear(hptr->dmp1);
        +	mpz_clear(hptr->dmq1);
        +	mpz_clear(hptr->iqmp);
        +	mpz_clear(hptr->r0);
        +	mpz_clear(hptr->r1);
        +	mpz_clear(hptr->I0);
        +	mpz_clear(hptr->m1);
        +	OPENSSL_free(hptr);
        +	RSA_set_ex_data(rsa, hndidx_rsa, NULL);
        +	return 1;
        +	}
        +
        +static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	E_GMP_RSA_CTX *hptr;
        +	int to_return = 0;
        +
        +	hptr = e_gmp_get_rsa(rsa);
        +	if(!hptr)
        +		{
        +		GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
        +				GMP_R_KEY_CONTEXT_ERROR);
        +		return 0;
        +		}
        +	if(hptr->public_only)
        +		{
        +		GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
        +				GMP_R_MISSING_KEY_COMPONENTS);
        +		return 0;
        +		}
        +
        +	/* ugh!!! */
        +	if(!bn2gmp(I, hptr->I0))
        +		return 0;
        +
        +	/* This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into
        +	 * GMP-speak. It may be that GMP's API facilitates cleaner formulations
        +	 * of this stuff, eg. better handling of negatives, or functions that
        +	 * combine operations. */
        +
        +	mpz_mod(hptr->r1, hptr->I0, hptr->q);
        +	mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q);
        +
        +	mpz_mod(hptr->r1, hptr->I0, hptr->p);
        +	mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p);
        +
        +	mpz_sub(hptr->r0, hptr->r0, hptr->m1);
        +
        +	if(mpz_sgn(hptr->r0) < 0)
        +		mpz_add(hptr->r0, hptr->r0, hptr->p);
        +	mpz_mul(hptr->r1, hptr->r0, hptr->iqmp);
        +	mpz_mod(hptr->r0, hptr->r1, hptr->p);
        +
        +	if(mpz_sgn(hptr->r0) < 0)
        +		mpz_add(hptr->r0, hptr->r0, hptr->p);
        +	mpz_mul(hptr->r1, hptr->r0, hptr->q);
        +	mpz_add(hptr->r0, hptr->r1, hptr->m1);
        +
        +	/* ugh!!! */
        +	if(gmp2bn(hptr->r0, r))
        +		to_return = 1;
        +
        +	return 1;
        +	}
        +#endif
        +
        +#endif /* !OPENSSL_NO_GMP */
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */	   
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +#ifndef OPENSSL_NO_GMP
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_e_gmp_id) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#else
        +OPENSSL_EXPORT
        +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
        +OPENSSL_EXPORT
        +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
        +#endif
        +#endif /* !OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_gmp.ec b/vendor/openssl/openssl/engines/e_gmp.ec
        new file mode 100644
        index 000000000..72ec447fb
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_gmp.ec
        @@ -0,0 +1 @@
        +L GMP		e_gmp_err.h			e_gmp_err.c
        diff --git a/vendor/openssl/openssl/engines/e_gmp_err.c b/vendor/openssl/openssl/engines/e_gmp_err.c
        new file mode 100644
        index 000000000..61db95679
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_gmp_err.c
        @@ -0,0 +1,141 @@
        +/* e_gmp_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_gmp_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA GMP_str_functs[]=
        +	{
        +{ERR_FUNC(GMP_F_E_GMP_CTRL),	"E_GMP_CTRL"},
        +{ERR_FUNC(GMP_F_E_GMP_RSA_MOD_EXP),	"E_GMP_RSA_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA GMP_str_reasons[]=
        +	{
        +{ERR_REASON(GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(GMP_R_KEY_CONTEXT_ERROR)     ,"key context error"},
        +{ERR_REASON(GMP_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef GMP_LIB_NAME
        +static ERR_STRING_DATA GMP_lib_name[]=
        +        {
        +{0	,GMP_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int GMP_lib_error_code=0;
        +static int GMP_error_init=1;
        +
        +static void ERR_load_GMP_strings(void)
        +	{
        +	if (GMP_lib_error_code == 0)
        +		GMP_lib_error_code=ERR_get_next_error_library();
        +
        +	if (GMP_error_init)
        +		{
        +		GMP_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(GMP_lib_error_code,GMP_str_functs);
        +		ERR_load_strings(GMP_lib_error_code,GMP_str_reasons);
        +#endif
        +
        +#ifdef GMP_LIB_NAME
        +		GMP_lib_name->error = ERR_PACK(GMP_lib_error_code,0,0);
        +		ERR_load_strings(0,GMP_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_GMP_strings(void)
        +	{
        +	if (GMP_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(GMP_lib_error_code,GMP_str_functs);
        +		ERR_unload_strings(GMP_lib_error_code,GMP_str_reasons);
        +#endif
        +
        +#ifdef GMP_LIB_NAME
        +		ERR_unload_strings(0,GMP_lib_name);
        +#endif
        +		GMP_error_init=1;
        +		}
        +	}
        +
        +static void ERR_GMP_error(int function, int reason, char *file, int line)
        +	{
        +	if (GMP_lib_error_code == 0)
        +		GMP_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(GMP_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_gmp_err.h b/vendor/openssl/openssl/engines/e_gmp_err.h
        new file mode 100644
        index 000000000..dd05dfd80
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_gmp_err.h
        @@ -0,0 +1,85 @@
        +/* ====================================================================
        + * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * 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_GMP_ERR_H
        +#define HEADER_GMP_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_GMP_strings(void);
        +static void ERR_unload_GMP_strings(void);
        +static void ERR_GMP_error(int function, int reason, char *file, int line);
        +#define GMPerr(f,r) ERR_GMP_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the GMP functions. */
        +
        +/* Function codes. */
        +#define GMP_F_E_GMP_CTRL				 100
        +#define GMP_F_E_GMP_RSA_MOD_EXP				 101
        +
        +/* Reason codes. */
        +#define GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED		 100
        +#define GMP_R_KEY_CONTEXT_ERROR				 101
        +#define GMP_R_MISSING_KEY_COMPONENTS			 102
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_nuron.c b/vendor/openssl/openssl/engines/e_nuron.c
        new file mode 100644
        index 000000000..4c2537cbc
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_nuron.c
        @@ -0,0 +1,434 @@
        +/* crypto/engine/hw_nuron.c */
        +/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
        + * Thorpe's Atalla implementation.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_NURON
        +
        +#define NURON_LIB_NAME "nuron engine"
        +#include "e_nuron_err.c"
        +
        +static const char *NURON_LIBNAME = NULL;
        +static const char *get_NURON_LIBNAME(void)
        +	{
        +	if(NURON_LIBNAME)
        +		return NURON_LIBNAME;
        +	return "nuronssl";
        +	}
        +static void free_NURON_LIBNAME(void)
        +	{
        +	if(NURON_LIBNAME)
        +		OPENSSL_free((void*)NURON_LIBNAME);
        +	NURON_LIBNAME = NULL;
        +	}
        +static long set_NURON_LIBNAME(const char *name)
        +	{
        +	free_NURON_LIBNAME();
        +	return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
        +	}
        +static const char *NURON_F1 = "nuron_mod_exp";
        +
        +/* The definitions for control commands specific to this engine */
        +#define NURON_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
        +	{NURON_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'nuronssl' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
        +static tfnModExp *pfnModExp = NULL;
        +
        +static DSO *pvDSOHandle = NULL;
        +
        +static int nuron_destroy(ENGINE *e)
        +	{
        +	free_NURON_LIBNAME();
        +	ERR_unload_NURON_strings();
        +	return 1;
        +	}
        +
        +static int nuron_init(ENGINE *e)
        +	{
        +	if(pvDSOHandle != NULL)
        +		{
        +		NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
        +		return 0;
        +		}
        +
        +	pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL,
        +		DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
        +	if(!pvDSOHandle)
        +		{
        +		NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
        +		return 0;
        +		}
        +
        +	pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
        +	if(!pfnModExp)
        +		{
        +		NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int nuron_finish(ENGINE *e)
        +	{
        +	free_NURON_LIBNAME();
        +	if(pvDSOHandle == NULL)
        +		{
        +		NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
        +		return 0;
        +		}
        +	if(!DSO_free(pvDSOHandle))
        +		{
        +		NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
        +		return 0;
        +		}
        +	pvDSOHandle=NULL;
        +	pfnModExp=NULL;
        +	return 1;
        +	}
        +
        +static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case NURON_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		return set_NURON_LIBNAME((const char *)p);
        +	default:
        +		break;
        +		}
        +	NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +}
        +
        +static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
        +			 const BIGNUM *m,BN_CTX *ctx)
        +	{
        +	if(!pvDSOHandle)
        +		{
        +		NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
        +		return 0;
        +		}
        +	return pfnModExp(r,a,p,m);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	return nuron_mod_exp(r0,I,rsa->d,rsa->n,ctx);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* 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 nuron_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 (!nuron_mod_exp(rr,a1,p1,m,ctx))
        +		goto end;
        +	/* let t = a2 ^ p2 mod m */
        +	if (!nuron_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 nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +			     const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +			     BN_MONT_CTX *m_ctx)
        +	{
        +	return nuron_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +#ifndef OPENSSL_NO_RSA
        +static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			      const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	return nuron_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
        +		const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +	{
        +	return nuron_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA_METHOD nuron_rsa =
        +	{
        +	"Nuron RSA method",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	nuron_rsa_mod_exp,
        +	nuron_mod_exp_mont,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +static DSA_METHOD nuron_dsa =
        +	{
        +	"Nuron DSA method",
        +	NULL, /* dsa_do_sign */
        +	NULL, /* dsa_sign_setup */
        +	NULL, /* dsa_do_verify */
        +	nuron_dsa_mod_exp, /* dsa_mod_exp */
        +	nuron_mod_exp_dsa, /* bn_mod_exp */
        +	NULL, /* init */
        +	NULL, /* finish */
        +	0, /* flags */
        +	NULL, /* app_data */
        +	NULL, /* dsa_paramgen */
        +	NULL /* dsa_keygen */
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +static DH_METHOD nuron_dh =
        +	{
        +	"Nuron DH method",
        +	NULL,
        +	NULL,
        +	nuron_mod_exp_dh,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_nuron_id = "nuron";
        +static const char *engine_nuron_name = "Nuron hardware engine support";
        +
        +/* This internal function is used by ENGINE_nuron() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	const DSA_METHOD *meth2;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth3;
        +#endif
        +	if(!ENGINE_set_id(e, engine_nuron_id) ||
        +			!ENGINE_set_name(e, engine_nuron_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &nuron_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			!ENGINE_set_DSA(e, &nuron_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH(e, &nuron_dh) ||
        +#endif
        +			!ENGINE_set_destroy_function(e, nuron_destroy) ||
        +			!ENGINE_set_init_function(e, nuron_init) ||
        +			!ENGINE_set_finish_function(e, nuron_finish) ||
        +			!ENGINE_set_ctrl_function(e, nuron_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, nuron_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* We know that the "PKCS1_SSLeay()" functions hook properly
        +	 * to the nuron-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();
        +	nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
        +	nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
        +	nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
        +	nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
        +	 * bits. */
        +	meth2=DSA_OpenSSL();
        +	nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
        +	nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
        +	nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth3=DH_OpenSSL();
        +	nuron_dh.generate_key=meth3->generate_key;
        +	nuron_dh.compute_key=meth3->compute_key;
        +#endif
        +
        +	/* Ensure the nuron error handling is set up */
        +	ERR_load_NURON_strings();
        +	return 1;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_nuron(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_nuron(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_nuron();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */	   
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_nuron_id) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW_NURON */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_nuron.ec b/vendor/openssl/openssl/engines/e_nuron.ec
        new file mode 100644
        index 000000000..cfa430dfc
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_nuron.ec
        @@ -0,0 +1 @@
        +L NURON		e_nuron_err.h			e_nuron_err.c
        diff --git a/vendor/openssl/openssl/engines/e_nuron_err.c b/vendor/openssl/openssl/engines/e_nuron_err.c
        new file mode 100644
        index 000000000..9a7864f42
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_nuron_err.c
        @@ -0,0 +1,146 @@
        +/* e_nuron_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_nuron_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA NURON_str_functs[]=
        +	{
        +{ERR_FUNC(NURON_F_NURON_CTRL),	"NURON_CTRL"},
        +{ERR_FUNC(NURON_F_NURON_FINISH),	"NURON_FINISH"},
        +{ERR_FUNC(NURON_F_NURON_INIT),	"NURON_INIT"},
        +{ERR_FUNC(NURON_F_NURON_MOD_EXP),	"NURON_MOD_EXP"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA NURON_str_reasons[]=
        +	{
        +{ERR_REASON(NURON_R_ALREADY_LOADED)      ,"already loaded"},
        +{ERR_REASON(NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(NURON_R_DSO_FAILURE)         ,"dso failure"},
        +{ERR_REASON(NURON_R_DSO_FUNCTION_NOT_FOUND),"dso function not found"},
        +{ERR_REASON(NURON_R_DSO_NOT_FOUND)       ,"dso not found"},
        +{ERR_REASON(NURON_R_NOT_LOADED)          ,"not loaded"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef NURON_LIB_NAME
        +static ERR_STRING_DATA NURON_lib_name[]=
        +        {
        +{0	,NURON_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int NURON_lib_error_code=0;
        +static int NURON_error_init=1;
        +
        +static void ERR_load_NURON_strings(void)
        +	{
        +	if (NURON_lib_error_code == 0)
        +		NURON_lib_error_code=ERR_get_next_error_library();
        +
        +	if (NURON_error_init)
        +		{
        +		NURON_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(NURON_lib_error_code,NURON_str_functs);
        +		ERR_load_strings(NURON_lib_error_code,NURON_str_reasons);
        +#endif
        +
        +#ifdef NURON_LIB_NAME
        +		NURON_lib_name->error = ERR_PACK(NURON_lib_error_code,0,0);
        +		ERR_load_strings(0,NURON_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_NURON_strings(void)
        +	{
        +	if (NURON_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(NURON_lib_error_code,NURON_str_functs);
        +		ERR_unload_strings(NURON_lib_error_code,NURON_str_reasons);
        +#endif
        +
        +#ifdef NURON_LIB_NAME
        +		ERR_unload_strings(0,NURON_lib_name);
        +#endif
        +		NURON_error_init=1;
        +		}
        +	}
        +
        +static void ERR_NURON_error(int function, int reason, char *file, int line)
        +	{
        +	if (NURON_lib_error_code == 0)
        +		NURON_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(NURON_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_nuron_err.h b/vendor/openssl/openssl/engines/e_nuron_err.h
        new file mode 100644
        index 000000000..219babbb4
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_nuron_err.h
        @@ -0,0 +1,90 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_NURON_ERR_H
        +#define HEADER_NURON_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_NURON_strings(void);
        +static void ERR_unload_NURON_strings(void);
        +static void ERR_NURON_error(int function, int reason, char *file, int line);
        +#define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the NURON functions. */
        +
        +/* Function codes. */
        +#define NURON_F_NURON_CTRL				 100
        +#define NURON_F_NURON_FINISH				 101
        +#define NURON_F_NURON_INIT				 102
        +#define NURON_F_NURON_MOD_EXP				 103
        +
        +/* Reason codes. */
        +#define NURON_R_ALREADY_LOADED				 100
        +#define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED		 101
        +#define NURON_R_DSO_FAILURE				 102
        +#define NURON_R_DSO_FUNCTION_NOT_FOUND			 103
        +#define NURON_R_DSO_NOT_FOUND				 104
        +#define NURON_R_NOT_LOADED				 105
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_padlock.c b/vendor/openssl/openssl/engines/e_padlock.c
        new file mode 100644
        index 000000000..9f7a85a8d
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_padlock.c
        @@ -0,0 +1,1239 @@
        +/* 
        + * Support for VIA PadLock Advanced Cryptography Engine (ACE)
        + * Written by Michal Ludvig <michal@logix.cz>
        + *            http://www.logix.cz/michal
        + *
        + * Big thanks to Andy Polyakov for a help with optimization, 
        + * assembler fixes, port to MS Windows and a lot of other 
        + * valuable work on this engine!
        + */
        +
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer.
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/crypto.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_AES
        +#include <openssl/aes.h>
        +#endif
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_PADLOCK
        +
        +/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
        +#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
        +#  ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +#    define DYNAMIC_ENGINE
        +#  endif
        +#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
        +#  ifdef ENGINE_DYNAMIC_SUPPORT
        +#    define DYNAMIC_ENGINE
        +#  endif
        +#else
        +#  error "Only OpenSSL >= 0.9.7 is supported"
        +#endif
        +
        +/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
        +   Not only that it doesn't exist elsewhere, but it
        +   even can't be compiled on other platforms!
        + 
        +   In addition, because of the heavy use of inline assembler,
        +   compiler choice is limited to GCC and Microsoft C. */
        +#undef COMPILE_HW_PADLOCK
        +#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
        +# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
        +     (defined(_MSC_VER) && defined(_M_IX86))
        +#  define COMPILE_HW_PADLOCK
        +# endif
        +#endif
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +#ifdef COMPILE_HW_PADLOCK
        +static ENGINE *ENGINE_padlock (void);
        +#endif
        +
        +void ENGINE_load_padlock (void)
        +{
        +/* On non-x86 CPUs it just returns. */
        +#ifdef COMPILE_HW_PADLOCK
        +	ENGINE *toadd = ENGINE_padlock ();
        +	if (!toadd) return;
        +	ENGINE_add (toadd);
        +	ENGINE_free (toadd);
        +	ERR_clear_error ();
        +#endif
        +}
        +
        +#endif
        +
        +#ifdef COMPILE_HW_PADLOCK
        +/* We do these includes here to avoid header problems on platforms that
        +   do not have the VIA padlock anyway... */
        +#include <stdlib.h>
        +#ifdef _WIN32
        +# include <malloc.h>
        +# ifndef alloca
        +#  define alloca _alloca
        +# endif
        +#elif defined(__GNUC__)
        +# ifndef alloca
        +#  define alloca(s) __builtin_alloca(s)
        +# endif
        +#endif
        +
        +/* Function for ENGINE detection and control */
        +static int padlock_available(void);
        +static int padlock_init(ENGINE *e);
        +
        +/* RNG Stuff */
        +static RAND_METHOD padlock_rand;
        +
        +/* Cipher Stuff */
        +#ifndef OPENSSL_NO_AES
        +static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
        +#endif
        +
        +/* Engine names */
        +static const char *padlock_id = "padlock";
        +static char padlock_name[100];
        +
        +/* Available features */
        +static int padlock_use_ace = 0;	/* Advanced Cryptography Engine */
        +static int padlock_use_rng = 0;	/* Random Number Generator */
        +#ifndef OPENSSL_NO_AES
        +static int padlock_aes_align_required = 1;
        +#endif
        +
        +/* ===== Engine "management" functions ===== */
        +
        +/* Prepare the ENGINE structure for registration */
        +static int
        +padlock_bind_helper(ENGINE *e)
        +{
        +	/* Check available features */
        +	padlock_available();
        +
        +#if 1	/* disable RNG for now, see commentary in vicinity of RNG code */
        +	padlock_use_rng=0;
        +#endif
        +
        +	/* Generate a nice engine name with available features */
        +	BIO_snprintf(padlock_name, sizeof(padlock_name),
        +		"VIA PadLock (%s, %s)", 
        +		 padlock_use_rng ? "RNG" : "no-RNG",
        +		 padlock_use_ace ? "ACE" : "no-ACE");
        +
        +	/* Register everything or return with an error */ 
        +	if (!ENGINE_set_id(e, padlock_id) ||
        +	    !ENGINE_set_name(e, padlock_name) ||
        +
        +	    !ENGINE_set_init_function(e, padlock_init) ||
        +#ifndef OPENSSL_NO_AES
        +	    (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
        +#endif
        +	    (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
        +		return 0;
        +	}
        +
        +	/* Everything looks good */
        +	return 1;
        +}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +
        +/* Constructor */
        +static ENGINE *
        +ENGINE_padlock(void)
        +{
        +	ENGINE *eng = ENGINE_new();
        +
        +	if (!eng) {
        +		return NULL;
        +	}
        +
        +	if (!padlock_bind_helper(eng)) {
        +		ENGINE_free(eng);
        +		return NULL;
        +	}
        +
        +	return eng;
        +}
        +
        +#endif
        +
        +/* Check availability of the engine */
        +static int
        +padlock_init(ENGINE *e)
        +{
        +	return (padlock_use_rng || padlock_use_ace);
        +}
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library.
        + */
        +#ifdef DYNAMIC_ENGINE
        +static int
        +padlock_bind_fn(ENGINE *e, const char *id)
        +{
        +	if (id && (strcmp(id, padlock_id) != 0)) {
        +		return 0;
        +	}
        +
        +	if (!padlock_bind_helper(e))  {
        +		return 0;
        +	}
        +
        +	return 1;
        +}
        +
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
        +#endif /* DYNAMIC_ENGINE */
        +
        +/* ===== Here comes the "real" engine ===== */
        +
        +#ifndef OPENSSL_NO_AES
        +/* Some AES-related constants */
        +#define AES_BLOCK_SIZE		16
        +#define AES_KEY_SIZE_128	16
        +#define AES_KEY_SIZE_192	24
        +#define AES_KEY_SIZE_256	32
        +
        +/* Here we store the status information relevant to the 
        +   current context. */
        +/* BIG FAT WARNING:
        + * 	Inline assembler in PADLOCK_XCRYPT_ASM()
        + * 	depends on the order of items in this structure.
        + * 	Don't blindly modify, reorder, etc!
        + */
        +struct padlock_cipher_data
        +{
        +	unsigned char iv[AES_BLOCK_SIZE];	/* Initialization vector */
        +	union {	unsigned int pad[4];
        +		struct {
        +			int rounds:4;
        +			int dgst:1;	/* n/a in C3 */
        +			int align:1;	/* n/a in C3 */
        +			int ciphr:1;	/* n/a in C3 */
        +			unsigned int keygen:1;
        +			int interm:1;
        +			unsigned int encdec:1;
        +			int ksize:2;
        +		} b;
        +	} cword;		/* Control word */
        +	AES_KEY ks;		/* Encryption key */
        +};
        +
        +/*
        + * Essentially this variable belongs in thread local storage.
        + * Having this variable global on the other hand can only cause
        + * few bogus key reloads [if any at all on single-CPU system],
        + * so we accept the penatly...
        + */
        +static volatile struct padlock_cipher_data *padlock_saved_context;
        +#endif
        +
        +/*
        + * =======================================================
        + * Inline assembler section(s).
        + * =======================================================
        + * Order of arguments is chosen to facilitate Windows port
        + * using __fastcall calling convention. If you wish to add
        + * more routines, keep in mind that first __fastcall
        + * argument is passed in %ecx and second - in %edx.
        + * =======================================================
        + */
        +#if defined(__GNUC__) && __GNUC__>=2
        +/*
        + * As for excessive "push %ebx"/"pop %ebx" found all over.
        + * When generating position-independent code GCC won't let
        + * us use "b" in assembler templates nor even respect "ebx"
        + * in "clobber description." Therefore the trouble...
        + */
        +
        +/* Helper function - check if a CPUID instruction
        +   is available on this CPU */
        +static int
        +padlock_insn_cpuid_available(void)
        +{
        +	int result = -1;
        +
        +	/* We're checking if the bit #21 of EFLAGS 
        +	   can be toggled. If yes = CPUID is available. */
        +	asm volatile (
        +		"pushf\n"
        +		"popl %%eax\n"
        +		"xorl $0x200000, %%eax\n"
        +		"movl %%eax, %%ecx\n"
        +		"andl $0x200000, %%ecx\n"
        +		"pushl %%eax\n"
        +		"popf\n"
        +		"pushf\n"
        +		"popl %%eax\n"
        +		"andl $0x200000, %%eax\n"
        +		"xorl %%eax, %%ecx\n"
        +		"movl %%ecx, %0\n"
        +		: "=r" (result) : : "eax", "ecx");
        +	
        +	return (result == 0);
        +}
        +
        +/* Load supported features of the CPU to see if
        +   the PadLock is available. */
        +static int
        +padlock_available(void)
        +{
        +	char vendor_string[16];
        +	unsigned int eax, edx;
        +
        +	/* First check if the CPUID instruction is available at all... */
        +	if (! padlock_insn_cpuid_available())
        +		return 0;
        +
        +	/* Are we running on the Centaur (VIA) CPU? */
        +	eax = 0x00000000;
        +	vendor_string[12] = 0;
        +	asm volatile (
        +		"pushl	%%ebx\n"
        +		"cpuid\n"
        +		"movl	%%ebx,(%%edi)\n"
        +		"movl	%%edx,4(%%edi)\n"
        +		"movl	%%ecx,8(%%edi)\n"
        +		"popl	%%ebx"
        +		: "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
        +	if (strcmp(vendor_string, "CentaurHauls") != 0)
        +		return 0;
        +
        +	/* Check for Centaur Extended Feature Flags presence */
        +	eax = 0xC0000000;
        +	asm volatile ("pushl %%ebx; cpuid; popl	%%ebx"
        +		: "+a"(eax) : : "ecx", "edx");
        +	if (eax < 0xC0000001)
        +		return 0;
        +
        +	/* Read the Centaur Extended Feature Flags */
        +	eax = 0xC0000001;
        +	asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
        +		: "+a"(eax), "=d"(edx) : : "ecx");
        +
        +	/* Fill up some flags */
        +	padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
        +	padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
        +
        +	return padlock_use_ace + padlock_use_rng;
        +}
        +
        +#ifndef OPENSSL_NO_AES
        +/* Our own htonl()/ntohl() */
        +static inline void
        +padlock_bswapl(AES_KEY *ks)
        +{
        +	size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
        +	unsigned int *key = ks->rd_key;
        +
        +	while (i--) {
        +		asm volatile ("bswapl %0" : "+r"(*key));
        +		key++;
        +	}
        +}
        +#endif
        +
        +/* Force key reload from memory to the CPU microcode.
        +   Loading EFLAGS from the stack clears EFLAGS[30] 
        +   which does the trick. */
        +static inline void
        +padlock_reload_key(void)
        +{
        +	asm volatile ("pushfl; popfl");
        +}
        +
        +#ifndef OPENSSL_NO_AES
        +/*
        + * This is heuristic key context tracing. At first one
        + * believes that one should use atomic swap instructions,
        + * but it's not actually necessary. Point is that if
        + * padlock_saved_context was changed by another thread
        + * after we've read it and before we compare it with cdata,
        + * our key *shall* be reloaded upon thread context switch
        + * and we are therefore set in either case...
        + */
        +static inline void
        +padlock_verify_context(struct padlock_cipher_data *cdata)
        +{
        +	asm volatile (
        +	"pushfl\n"
        +"	btl	$30,(%%esp)\n"
        +"	jnc	1f\n"
        +"	cmpl	%2,%1\n"
        +"	je	1f\n"
        +"	popfl\n"
        +"	subl	$4,%%esp\n"
        +"1:	addl	$4,%%esp\n"
        +"	movl	%2,%0"
        +	:"+m"(padlock_saved_context)
        +	: "r"(padlock_saved_context), "r"(cdata) : "cc");
        +}
        +
        +/* Template for padlock_xcrypt_* modes */
        +/* BIG FAT WARNING: 
        + * 	The offsets used with 'leal' instructions
        + * 	describe items of the 'padlock_cipher_data'
        + * 	structure.
        + */
        +#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt)	\
        +static inline void *name(size_t cnt,		\
        +	struct padlock_cipher_data *cdata,	\
        +	void *out, const void *inp) 		\
        +{	void *iv; 				\
        +	asm volatile ( "pushl	%%ebx\n"	\
        +		"	leal	16(%0),%%edx\n"	\
        +		"	leal	32(%0),%%ebx\n"	\
        +			rep_xcrypt "\n"		\
        +		"	popl	%%ebx"		\
        +		: "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
        +		: "0"(cdata), "1"(cnt), "2"(out), "3"(inp)  \
        +		: "edx", "cc", "memory");	\
        +	return iv;				\
        +}
        +
        +/* Generate all functions with appropriate opcodes */
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8")	/* rep xcryptecb */
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0")	/* rep xcryptcbc */
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0")	/* rep xcryptcfb */
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8")	/* rep xcryptofb */
        +#endif
        +
        +/* The RNG call itself */
        +static inline unsigned int
        +padlock_xstore(void *addr, unsigned int edx_in)
        +{
        +	unsigned int eax_out;
        +
        +	asm volatile (".byte 0x0f,0xa7,0xc0"	/* xstore */
        +	    : "=a"(eax_out),"=m"(*(unsigned *)addr)
        +	    : "D"(addr), "d" (edx_in)
        +	    );
        +
        +	return eax_out;
        +}
        +
        +/* Why not inline 'rep movsd'? I failed to find information on what
        + * value in Direction Flag one can expect and consequently have to
        + * apply "better-safe-than-sorry" approach and assume "undefined."
        + * I could explicitly clear it and restore the original value upon
        + * return from padlock_aes_cipher, but it's presumably too much
        + * trouble for too little gain...
        + *
        + * In case you wonder 'rep xcrypt*' instructions above are *not*
        + * affected by the Direction Flag and pointers advance toward
        + * larger addresses unconditionally.
        + */ 
        +static inline unsigned char *
        +padlock_memcpy(void *dst,const void *src,size_t n)
        +{
        +	long       *d=dst;
        +	const long *s=src;
        +
        +	n /= sizeof(*d);
        +	do { *d++ = *s++; } while (--n);
        +
        +	return dst;
        +}
        +
        +#elif defined(_MSC_VER)
        +/*
        + * Unlike GCC these are real functions. In order to minimize impact
        + * on performance we adhere to __fastcall calling convention in
        + * order to get two first arguments passed through %ecx and %edx.
        + * Which kind of suits very well, as instructions in question use
        + * both %ecx and %edx as input:-)
        + */
        +#define REP_XCRYPT(code)		\
        +	_asm _emit 0xf3			\
        +	_asm _emit 0x0f _asm _emit 0xa7	\
        +	_asm _emit code
        +
        +/* BIG FAT WARNING: 
        + * 	The offsets used with 'lea' instructions
        + * 	describe items of the 'padlock_cipher_data'
        + * 	structure.
        + */
        +#define PADLOCK_XCRYPT_ASM(name,code)	\
        +static void * __fastcall 		\
        +	name (size_t cnt, void *cdata,	\
        +	void *outp, const void *inp)	\
        +{	_asm	mov	eax,edx		\
        +	_asm	lea	edx,[eax+16]	\
        +	_asm	lea	ebx,[eax+32]	\
        +	_asm	mov	edi,outp	\
        +	_asm	mov	esi,inp		\
        +	REP_XCRYPT(code)		\
        +}
        +
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
        +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
        +
        +static int __fastcall
        +padlock_xstore(void *outp,unsigned int code)
        +{	_asm	mov	edi,ecx
        +	_asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
        +}
        +
        +static void __fastcall
        +padlock_reload_key(void)
        +{	_asm pushfd _asm popfd		}
        +
        +static void __fastcall
        +padlock_verify_context(void *cdata)
        +{	_asm	{
        +		pushfd
        +		bt	DWORD PTR[esp],30
        +		jnc	skip
        +		cmp	ecx,padlock_saved_context
        +		je	skip
        +		popfd
        +		sub	esp,4
        +	skip:	add	esp,4
        +		mov	padlock_saved_context,ecx
        +		}
        +}
        +
        +static int
        +padlock_available(void)
        +{	_asm	{
        +		pushfd
        +		pop	eax
        +		mov	ecx,eax
        +		xor	eax,1<<21
        +		push	eax
        +		popfd
        +		pushfd
        +		pop	eax
        +		xor	eax,ecx
        +		bt	eax,21
        +		jnc	noluck
        +		mov	eax,0
        +		cpuid
        +		xor	eax,eax
        +		cmp	ebx,'tneC'
        +		jne	noluck
        +		cmp	edx,'Hrua'
        +		jne	noluck
        +		cmp	ecx,'slua'
        +		jne	noluck
        +		mov	eax,0xC0000000
        +		cpuid
        +		mov	edx,eax
        +		xor	eax,eax
        +		cmp	edx,0xC0000001
        +		jb	noluck
        +		mov	eax,0xC0000001
        +		cpuid
        +		xor	eax,eax
        +		bt	edx,6
        +		jnc	skip_a
        +		bt	edx,7
        +		jnc	skip_a
        +		mov	padlock_use_ace,1
        +		inc	eax
        +	skip_a:	bt	edx,2
        +		jnc	skip_r
        +		bt	edx,3
        +		jnc	skip_r
        +		mov	padlock_use_rng,1
        +		inc	eax
        +	skip_r:
        +	noluck:
        +		}
        +}
        +
        +static void __fastcall
        +padlock_bswapl(void *key)
        +{	_asm	{
        +		pushfd
        +		cld
        +		mov	esi,ecx
        +		mov	edi,ecx
        +		mov	ecx,60
        +	up:	lodsd
        +		bswap	eax
        +		stosd
        +		loop	up
        +		popfd
        +		}
        +}
        +
        +/* MS actually specifies status of Direction Flag and compiler even
        + * manages to compile following as 'rep movsd' all by itself...
        + */
        +#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
        +#endif
        +
        +/* ===== AES encryption/decryption ===== */
        +#ifndef OPENSSL_NO_AES
        +
        +#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
        +#define NID_aes_128_cfb	NID_aes_128_cfb128
        +#endif
        +
        +#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
        +#define NID_aes_128_ofb	NID_aes_128_ofb128
        +#endif
        +
        +#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
        +#define NID_aes_192_cfb	NID_aes_192_cfb128
        +#endif
        +
        +#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
        +#define NID_aes_192_ofb	NID_aes_192_ofb128
        +#endif
        +
        +#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
        +#define NID_aes_256_cfb	NID_aes_256_cfb128
        +#endif
        +
        +#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
        +#define NID_aes_256_ofb	NID_aes_256_ofb128
        +#endif
        +
        +/* List of supported ciphers. */
        +static int padlock_cipher_nids[] = {
        +	NID_aes_128_ecb,
        +	NID_aes_128_cbc,
        +	NID_aes_128_cfb,
        +	NID_aes_128_ofb,
        +
        +	NID_aes_192_ecb,
        +	NID_aes_192_cbc,
        +	NID_aes_192_cfb,
        +	NID_aes_192_ofb,
        +
        +	NID_aes_256_ecb,
        +	NID_aes_256_cbc,
        +	NID_aes_256_cfb,
        +	NID_aes_256_ofb,
        +};
        +static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
        +				      sizeof(padlock_cipher_nids[0]));
        +
        +/* Function prototypes ... */
        +static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +				const unsigned char *iv, int enc);
        +static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        +			      const unsigned char *in, size_t nbytes);
        +
        +#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) +		\
        +	( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F )	)
        +#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
        +	NEAREST_ALIGNED(ctx->cipher_data))
        +
        +#define EVP_CIPHER_block_size_ECB	AES_BLOCK_SIZE
        +#define EVP_CIPHER_block_size_CBC	AES_BLOCK_SIZE
        +#define EVP_CIPHER_block_size_OFB	1
        +#define EVP_CIPHER_block_size_CFB	1
        +
        +/* Declaring so many ciphers by hand would be a pain.
        +   Instead introduce a bit of preprocessor magic :-) */
        +#define	DECLARE_AES_EVP(ksize,lmode,umode)	\
        +static const EVP_CIPHER padlock_aes_##ksize##_##lmode = {	\
        +	NID_aes_##ksize##_##lmode,		\
        +	EVP_CIPHER_block_size_##umode,	\
        +	AES_KEY_SIZE_##ksize,		\
        +	AES_BLOCK_SIZE,			\
        +	0 | EVP_CIPH_##umode##_MODE,	\
        +	padlock_aes_init_key,		\
        +	padlock_aes_cipher,		\
        +	NULL,				\
        +	sizeof(struct padlock_cipher_data) + 16,	\
        +	EVP_CIPHER_set_asn1_iv,		\
        +	EVP_CIPHER_get_asn1_iv,		\
        +	NULL,				\
        +	NULL				\
        +}
        +
        +DECLARE_AES_EVP(128,ecb,ECB);
        +DECLARE_AES_EVP(128,cbc,CBC);
        +DECLARE_AES_EVP(128,cfb,CFB);
        +DECLARE_AES_EVP(128,ofb,OFB);
        +
        +DECLARE_AES_EVP(192,ecb,ECB);
        +DECLARE_AES_EVP(192,cbc,CBC);
        +DECLARE_AES_EVP(192,cfb,CFB);
        +DECLARE_AES_EVP(192,ofb,OFB);
        +
        +DECLARE_AES_EVP(256,ecb,ECB);
        +DECLARE_AES_EVP(256,cbc,CBC);
        +DECLARE_AES_EVP(256,cfb,CFB);
        +DECLARE_AES_EVP(256,ofb,OFB);
        +
        +static int
        +padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
        +{
        +	/* No specific cipher => return a list of supported nids ... */
        +	if (!cipher) {
        +		*nids = padlock_cipher_nids;
        +		return padlock_cipher_nids_num;
        +	}
        +
        +	/* ... or the requested "cipher" otherwise */
        +	switch (nid) {
        +	  case NID_aes_128_ecb:
        +	    *cipher = &padlock_aes_128_ecb;
        +	    break;
        +	  case NID_aes_128_cbc:
        +	    *cipher = &padlock_aes_128_cbc;
        +	    break;
        +	  case NID_aes_128_cfb:
        +	    *cipher = &padlock_aes_128_cfb;
        +	    break;
        +	  case NID_aes_128_ofb:
        +	    *cipher = &padlock_aes_128_ofb;
        +	    break;
        +
        +	  case NID_aes_192_ecb:
        +	    *cipher = &padlock_aes_192_ecb;
        +	    break;
        +	  case NID_aes_192_cbc:
        +	    *cipher = &padlock_aes_192_cbc;
        +	    break;
        +	  case NID_aes_192_cfb:
        +	    *cipher = &padlock_aes_192_cfb;
        +	    break;
        +	  case NID_aes_192_ofb:
        +	    *cipher = &padlock_aes_192_ofb;
        +	    break;
        +
        +	  case NID_aes_256_ecb:
        +	    *cipher = &padlock_aes_256_ecb;
        +	    break;
        +	  case NID_aes_256_cbc:
        +	    *cipher = &padlock_aes_256_cbc;
        +	    break;
        +	  case NID_aes_256_cfb:
        +	    *cipher = &padlock_aes_256_cfb;
        +	    break;
        +	  case NID_aes_256_ofb:
        +	    *cipher = &padlock_aes_256_ofb;
        +	    break;
        +
        +	  default:
        +	    /* Sorry, we don't support this NID */
        +	    *cipher = NULL;
        +	    return 0;
        +	}
        +
        +	return 1;
        +}
        +
        +/* Prepare the encryption key for PadLock usage */
        +static int
        +padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
        +		      const unsigned char *iv, int enc)
        +{
        +	struct padlock_cipher_data *cdata;
        +	int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
        +
        +	if (key==NULL) return 0;	/* ERROR */
        +
        +	cdata = ALIGNED_CIPHER_DATA(ctx);
        +	memset(cdata, 0, sizeof(struct padlock_cipher_data));
        +
        +	/* Prepare Control word. */
        +	if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
        +		cdata->cword.b.encdec = 0;
        +	else
        +		cdata->cword.b.encdec = (ctx->encrypt == 0);
        +	cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
        +	cdata->cword.b.ksize = (key_len - 128) / 64;
        +
        +	switch(key_len) {
        +		case 128:
        +			/* PadLock can generate an extended key for
        +			   AES128 in hardware */
        +			memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
        +			cdata->cword.b.keygen = 0;
        +			break;
        +
        +		case 192:
        +		case 256:
        +			/* Generate an extended AES key in software.
        +			   Needed for AES192/AES256 */
        +			/* Well, the above applies to Stepping 8 CPUs
        +			   and is listed as hardware errata. They most
        +			   likely will fix it at some point and then
        +			   a check for stepping would be due here. */
        +			if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
        +			    EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
        +			    enc)
        +				AES_set_encrypt_key(key, key_len, &cdata->ks);
        +			else
        +				AES_set_decrypt_key(key, key_len, &cdata->ks);
        +#ifndef AES_ASM
        +			/* OpenSSL C functions use byte-swapped extended key. */
        +			padlock_bswapl(&cdata->ks);
        +#endif
        +			cdata->cword.b.keygen = 1;
        +			break;
        +
        +		default:
        +			/* ERROR */
        +			return 0;
        +	}
        +
        +	/*
        +	 * This is done to cover for cases when user reuses the
        +	 * context for new key. The catch is that if we don't do
        +	 * this, padlock_eas_cipher might proceed with old key...
        +	 */
        +	padlock_reload_key ();
        +
        +	return 1;
        +}
        +
        +/* 
        + * Simplified version of padlock_aes_cipher() used when
        + * 1) both input and output buffers are at aligned addresses.
        + * or when
        + * 2) running on a newer CPU that doesn't require aligned buffers.
        + */
        +static int
        +padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
        +		const unsigned char *in_arg, size_t nbytes)
        +{
        +	struct padlock_cipher_data *cdata;
        +	void  *iv;
        +
        +	cdata = ALIGNED_CIPHER_DATA(ctx);
        +	padlock_verify_context(cdata);
        +
        +	switch (EVP_CIPHER_CTX_mode(ctx)) {
        +	case EVP_CIPH_ECB_MODE:
        +		padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
        +		break;
        +
        +	case EVP_CIPH_CBC_MODE:
        +		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
        +		iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
        +		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
        +		break;
        +
        +	case EVP_CIPH_CFB_MODE:
        +		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
        +		iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
        +		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
        +		break;
        +
        +	case EVP_CIPH_OFB_MODE:
        +		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
        +		padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
        +		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
        +		break;
        +
        +	default:
        +		return 0;
        +	}
        +
        +	memset(cdata->iv, 0, AES_BLOCK_SIZE);
        +
        +	return 1;
        +}
        +
        +#ifndef  PADLOCK_CHUNK
        +# define PADLOCK_CHUNK	512	/* Must be a power of 2 larger than 16 */
        +#endif
        +#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
        +# error "insane PADLOCK_CHUNK..."
        +#endif
        +
        +/* Re-align the arguments to 16-Bytes boundaries and run the 
        +   encryption function itself. This function is not AES-specific. */
        +static int
        +padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
        +		   const unsigned char *in_arg, size_t nbytes)
        +{
        +	struct padlock_cipher_data *cdata;
        +	const  void *inp;
        +	unsigned char  *out;
        +	void  *iv;
        +	int    inp_misaligned, out_misaligned, realign_in_loop;
        +	size_t chunk, allocated=0;
        +
        +	/* ctx->num is maintained in byte-oriented modes,
        +	   such as CFB and OFB... */
        +	if ((chunk = ctx->num)) { /* borrow chunk variable */
        +		unsigned char *ivp=ctx->iv;
        +
        +		switch (EVP_CIPHER_CTX_mode(ctx)) {
        +		case EVP_CIPH_CFB_MODE:
        +			if (chunk >= AES_BLOCK_SIZE)
        +				return 0; /* bogus value */
        +
        +			if (ctx->encrypt)
        +				while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
        +					ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
        +					chunk++, nbytes--;
        +				}
        +			else	while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
        +					unsigned char c = *(in_arg++);
        +					*(out_arg++) = c ^ ivp[chunk];
        +					ivp[chunk++] = c, nbytes--;
        +				}
        +
        +			ctx->num = chunk%AES_BLOCK_SIZE;
        +			break;
        +		case EVP_CIPH_OFB_MODE:
        +			if (chunk >= AES_BLOCK_SIZE)
        +				return 0; /* bogus value */
        +
        +			while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
        +				*(out_arg++) = *(in_arg++) ^ ivp[chunk];
        +				chunk++, nbytes--;
        +			}
        +
        +			ctx->num = chunk%AES_BLOCK_SIZE;
        +			break;
        +		}
        +	}
        +
        +	if (nbytes == 0)
        +		return 1;
        +#if 0
        +	if (nbytes % AES_BLOCK_SIZE)
        +		return 0; /* are we expected to do tail processing? */
        +#else
        +	/* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
        +	   modes and arbitrary value in byte-oriented modes, such as
        +	   CFB and OFB... */
        +#endif
        +
        +	/* VIA promises CPUs that won't require alignment in the future.
        +	   For now padlock_aes_align_required is initialized to 1 and
        +	   the condition is never met... */
        +	/* C7 core is capable to manage unaligned input in non-ECB[!]
        +	   mode, but performance penalties appear to be approximately
        +	   same as for software alignment below or ~3x. They promise to
        +	   improve it in the future, but for now we can just as well
        +	   pretend that it can only handle aligned input... */
        +	if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
        +		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
        +
        +	inp_misaligned = (((size_t)in_arg) & 0x0F);
        +	out_misaligned = (((size_t)out_arg) & 0x0F);
        +
        +	/* Note that even if output is aligned and input not,
        +	 * I still prefer to loop instead of copy the whole
        +	 * input and then encrypt in one stroke. This is done
        +	 * in order to improve L1 cache utilization... */
        +	realign_in_loop = out_misaligned|inp_misaligned;
        +
        +	if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
        +		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
        +
        +	/* this takes one "if" out of the loops */
        +	chunk  = nbytes;
        +	chunk %= PADLOCK_CHUNK;
        +	if (chunk==0) chunk = PADLOCK_CHUNK;
        +
        +	if (out_misaligned) {
        +		/* optmize for small input */
        +		allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
        +		out = alloca(0x10 + allocated);
        +		out = NEAREST_ALIGNED(out);
        +	}
        +	else
        +		out = out_arg;
        +
        +	cdata = ALIGNED_CIPHER_DATA(ctx);
        +	padlock_verify_context(cdata);
        +
        +	switch (EVP_CIPHER_CTX_mode(ctx)) {
        +	case EVP_CIPH_ECB_MODE:
        +		do	{
        +			if (inp_misaligned)
        +				inp = padlock_memcpy(out, in_arg, chunk);
        +			else
        +				inp = in_arg;
        +			in_arg += chunk;
        +
        +			padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
        +
        +			if (out_misaligned)
        +				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
        +			else
        +				out     = out_arg+=chunk;
        +
        +			nbytes -= chunk;
        +			chunk   = PADLOCK_CHUNK;
        +		} while (nbytes);
        +		break;
        +
        +	case EVP_CIPH_CBC_MODE:
        +		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
        +		goto cbc_shortcut;
        +		do	{
        +			if (iv != cdata->iv)
        +				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
        +			chunk = PADLOCK_CHUNK;
        +		cbc_shortcut: /* optimize for small input */
        +			if (inp_misaligned)
        +				inp = padlock_memcpy(out, in_arg, chunk);
        +			else
        +				inp = in_arg;
        +			in_arg += chunk;
        +
        +			iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
        +
        +			if (out_misaligned)
        +				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
        +			else
        +				out     = out_arg+=chunk;
        +
        +		} while (nbytes -= chunk);
        +		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
        +		break;
        +
        +	case EVP_CIPH_CFB_MODE:
        +		memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
        +		chunk &= ~(AES_BLOCK_SIZE-1);
        +		if (chunk)	goto cfb_shortcut;
        +		else		goto cfb_skiploop;
        +		do	{
        +			if (iv != cdata->iv)
        +				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
        +			chunk = PADLOCK_CHUNK;
        +		cfb_shortcut: /* optimize for small input */
        +			if (inp_misaligned)
        +				inp = padlock_memcpy(out, in_arg, chunk);
        +			else
        +				inp = in_arg;
        +			in_arg += chunk;
        +
        +			iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
        +
        +			if (out_misaligned)
        +				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
        +			else
        +				out     = out_arg+=chunk;
        +
        +			nbytes -= chunk;
        +		} while (nbytes >= AES_BLOCK_SIZE);
        +
        +		cfb_skiploop:
        +		if (nbytes) {
        +			unsigned char *ivp = cdata->iv;
        +
        +			if (iv != ivp) {
        +				memcpy(ivp, iv, AES_BLOCK_SIZE);
        +				iv = ivp;
        +			}
        +			ctx->num = nbytes;
        +			if (cdata->cword.b.encdec) {
        +				cdata->cword.b.encdec=0;
        +				padlock_reload_key();
        +				padlock_xcrypt_ecb(1,cdata,ivp,ivp);
        +				cdata->cword.b.encdec=1;
        +				padlock_reload_key();
        +				while(nbytes) {
        +					unsigned char c = *(in_arg++);
        +					*(out_arg++) = c ^ *ivp;
        +					*(ivp++) = c, nbytes--;
        +				}
        +			}
        +			else {	padlock_reload_key();
        +				padlock_xcrypt_ecb(1,cdata,ivp,ivp);
        +				padlock_reload_key();
        +				while (nbytes) {
        +					*ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
        +					ivp++, nbytes--;
        +				}
        +			}
        +		}
        +
        +		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
        +		break;
        +
        +	case EVP_CIPH_OFB_MODE:
        +		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
        +		chunk &= ~(AES_BLOCK_SIZE-1);
        +		if (chunk) do	{
        +			if (inp_misaligned)
        +				inp = padlock_memcpy(out, in_arg, chunk);
        +			else
        +				inp = in_arg;
        +			in_arg += chunk;
        +
        +			padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
        +
        +			if (out_misaligned)
        +				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
        +			else
        +				out     = out_arg+=chunk;
        +
        +			nbytes -= chunk;
        +			chunk   = PADLOCK_CHUNK;
        +		} while (nbytes >= AES_BLOCK_SIZE);
        +
        +		if (nbytes) {
        +			unsigned char *ivp = cdata->iv;
        +
        +			ctx->num = nbytes;
        +			padlock_reload_key();	/* empirically found */
        +			padlock_xcrypt_ecb(1,cdata,ivp,ivp);
        +			padlock_reload_key();	/* empirically found */
        +			while (nbytes) {
        +				*(out_arg++) = *(in_arg++) ^ *ivp;
        +				ivp++, nbytes--;
        +			}
        +		}
        +
        +		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
        +		break;
        +
        +	default:
        +		return 0;
        +	}
        +
        +	/* Clean the realign buffer if it was used */
        +	if (out_misaligned) {
        +		volatile unsigned long *p=(void *)out;
        +		size_t   n = allocated/sizeof(*p);
        +		while (n--) *p++=0;
        +	}
        +
        +	memset(cdata->iv, 0, AES_BLOCK_SIZE);
        +
        +	return 1;
        +}
        +
        +#endif /* OPENSSL_NO_AES */
        +
        +/* ===== Random Number Generator ===== */
        +/*
        + * This code is not engaged. The reason is that it does not comply
        + * with recommendations for VIA RNG usage for secure applications
        + * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
        + * provide meaningful error control...
        + */
        +/* Wrapper that provides an interface between the API and 
        +   the raw PadLock RNG */
        +static int
        +padlock_rand_bytes(unsigned char *output, int count)
        +{
        +	unsigned int eax, buf;
        +
        +	while (count >= 8) {
        +		eax = padlock_xstore(output, 0);
        +		if (!(eax&(1<<6)))	return 0; /* RNG disabled */
        +		/* this ---vv--- covers DC bias, Raw Bits and String Filter */
        +		if (eax&(0x1F<<10))	return 0;
        +		if ((eax&0x1F)==0)	continue; /* no data, retry... */
        +		if ((eax&0x1F)!=8)	return 0; /* fatal failure...  */
        +		output += 8;
        +		count  -= 8;
        +	}
        +	while (count > 0) {
        +		eax = padlock_xstore(&buf, 3);
        +		if (!(eax&(1<<6)))	return 0; /* RNG disabled */
        +		/* this ---vv--- covers DC bias, Raw Bits and String Filter */
        +		if (eax&(0x1F<<10))	return 0;
        +		if ((eax&0x1F)==0)	continue; /* no data, retry... */
        +		if ((eax&0x1F)!=1)	return 0; /* fatal failure...  */
        +		*output++ = (unsigned char)buf;
        +		count--;
        +	}
        +	*(volatile unsigned int *)&buf=0;
        +
        +	return 1;
        +}
        +
        +/* Dummy but necessary function */
        +static int
        +padlock_rand_status(void)
        +{
        +	return 1;
        +}
        +
        +/* Prepare structure for registration */
        +static RAND_METHOD padlock_rand = {
        +	NULL,			/* seed */
        +	padlock_rand_bytes,	/* bytes */
        +	NULL,			/* cleanup */
        +	NULL,			/* add */
        +	padlock_rand_bytes,	/* pseudorand */
        +	padlock_rand_status,	/* rand status */
        +};
        +
        +#else  /* !COMPILE_HW_PADLOCK */
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +OPENSSL_EXPORT
        +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
        +OPENSSL_EXPORT
        +int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +#endif
        +#endif /* COMPILE_HW_PADLOCK */
        +
        +#endif /* !OPENSSL_NO_HW_PADLOCK */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_padlock.ec b/vendor/openssl/openssl/engines/e_padlock.ec
        new file mode 100644
        index 000000000..5c8a1d26a
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_padlock.ec
        @@ -0,0 +1 @@
        +L PADLOCK	e_padlock_err.h			e_padlock_err.c
        diff --git a/vendor/openssl/openssl/engines/e_sureware.c b/vendor/openssl/openssl/engines/e_sureware.c
        new file mode 100644
        index 000000000..cd0fa4c39
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_sureware.c
        @@ -0,0 +1,1055 @@
        +/* Written by Corinne Dive-Reclus(cdive@baltimore.com)
        +* 
        +*
        +* Redistribution and use in source and binary forms, with or without
        +* modification, are permitted provided that the following conditions
        +* are met:
        +*
        +* 1. Redistributions of source code must retain the above copyright
        +*    notice, this list of conditions and the following disclaimer. 
        +*
        +* 2. Redistributions in binary form must 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/)"
        +*
        +* Written by Corinne Dive-Reclus(cdive@baltimore.com)
        +*
        +* Copyright@2001 Baltimore Technologies Ltd.
        +* All right Reserved.
        +*																								*	
        +*		THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND																			*
        +*		ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE					* 
        +*		IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE				*
        +*		ARE DISCLAIMED.  IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE						*
        +*		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL				*
        +*		DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS					*
        +*		OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)					*
        +*		HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT				*
        +*		LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY				*
        +*		OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF					*
        +*		SUCH DAMAGE.																			*
        +====================================================================*/
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/pem.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_SUREWARE
        +
        +#ifdef FLAT_INC
        +#include "sureware.h"
        +#else
        +#include "vendor_defns/sureware.h"
        +#endif
        +
        +#define SUREWARE_LIB_NAME "sureware engine"
        +#include "e_sureware_err.c"
        +
        +static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +static int surewarehk_destroy(ENGINE *e);
        +static int surewarehk_init(ENGINE *e);
        +static int surewarehk_finish(ENGINE *e);
        +static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +	const BIGNUM *m, BN_CTX *ctx);
        +
        +/* RSA stuff */
        +#ifndef OPENSSL_NO_RSA
        +static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
        +			RSA *rsa,int padding);
        +static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
        +			    RSA *rsa,int padding);
        +#endif
        +
        +/* RAND stuff */
        +static int surewarehk_rand_bytes(unsigned char *buf, int num);
        +static void surewarehk_rand_seed(const void *buf, int num);
        +static void surewarehk_rand_add(const void *buf, int num, double entropy);
        +
        +/* KM stuff */
        +static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
        +	UI_METHOD *ui_method, void *callback_data);
        +static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
        +	int idx,long argl, void *argp);
        +#if 0
        +static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
        +	int idx,long argl, void *argp);
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +/* This function is aliased to mod_exp (with the mont stuff dropped). */
        +static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +{
        +	return surewarehk_modexp(r, a, p, m, ctx);
        +}
        +
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD surewarehk_rsa =
        +	{
        +	"SureWare RSA method",
        +	NULL, /* pub_enc*/
        +	NULL, /* pub_dec*/
        +	surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/
        +	surewarehk_rsa_priv_dec, /* priv_dec*/
        +	NULL, /*mod_exp*/
        +	surewarehk_mod_exp_mont, /*mod_exp_mongomery*/
        +	NULL, /* init*/
        +	NULL, /* finish*/
        +	0,	/* RSA flag*/
        +	NULL, 
        +	NULL, /* OpenSSL sign*/
        +	NULL, /* OpenSSL verify*/
        +	NULL  /* keygen */
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* Our internal DH_METHOD that we provide pointers to */
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +{
        +	return surewarehk_modexp(r, a, p, m, ctx);
        +}
        +
        +static DH_METHOD surewarehk_dh =
        +	{
        +	"SureWare DH method",
        +	NULL,/*gen_key*/
        +	NULL,/*agree,*/
        +	surewarehk_modexp_dh, /*dh mod exp*/
        +	NULL, /* init*/
        +	NULL, /* finish*/
        +	0,    /* flags*/
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +static RAND_METHOD surewarehk_rand =
        +	{
        +	/* "SureWare RAND method", */
        +	surewarehk_rand_seed,
        +	surewarehk_rand_bytes,
        +	NULL,/*cleanup*/
        +	surewarehk_rand_add,
        +	surewarehk_rand_bytes,
        +	NULL,/*rand_status*/
        +	};
        +
        +#ifndef OPENSSL_NO_DSA
        +/* DSA stuff */
        +static	DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        +static int surewarehk_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 (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end;
        +	/* let t = a2 ^ p2 mod m */
        +	if (!surewarehk_modexp(&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 DSA_METHOD surewarehk_dsa =
        +	{
        +	 "SureWare DSA method", 
        +	surewarehk_dsa_do_sign,
        +	NULL,/*sign setup*/
        +	NULL,/*verify,*/
        +	surewarehk_dsa_mod_exp,/*mod exp*/
        +	NULL,/*bn mod exp*/
        +	NULL, /*init*/
        +	NULL,/*finish*/
        +	0,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +static const char *engine_sureware_id = "sureware";
        +static const char *engine_sureware_name = "SureWare hardware engine support";
        +
        +/* 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!!!) */
        +static int bind_sureware(ENGINE *e)
        +{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	const DSA_METHOD *meth2;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	const DH_METHOD *meth3;
        +#endif
        +
        +	if(!ENGINE_set_id(e, engine_sureware_id) ||
        +	   !ENGINE_set_name(e, engine_sureware_name) ||
        +#ifndef OPENSSL_NO_RSA
        +	   !ENGINE_set_RSA(e, &surewarehk_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	   !ENGINE_set_DSA(e, &surewarehk_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	   !ENGINE_set_DH(e, &surewarehk_dh) ||
        +#endif
        +	   !ENGINE_set_RAND(e, &surewarehk_rand) ||
        +	   !ENGINE_set_destroy_function(e, surewarehk_destroy) ||
        +	   !ENGINE_set_init_function(e, surewarehk_init) ||
        +	   !ENGINE_set_finish_function(e, surewarehk_finish) ||
        +	   !ENGINE_set_ctrl_function(e, surewarehk_ctrl) ||
        +	   !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) ||
        +	   !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey))
        +	  return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* 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();
        +	if (meth1)
        +	{
        +		surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
        +		surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
        +	 * bits. */
        +	meth2 = DSA_OpenSSL();
        +	if (meth2)
        +	{
        +		surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth3 = DH_OpenSSL();
        +	if (meth3)
        +	{
        +		surewarehk_dh.generate_key = meth3->generate_key;
        +		surewarehk_dh.compute_key = meth3->compute_key;
        +	}
        +#endif
        +
        +	/* Ensure the sureware error handling is set up */
        +	ERR_load_SUREWARE_strings();
        +	return 1;
        +}
        +
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_helper(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_sureware_id) != 0))
        +		return 0;
        +	if(!bind_sureware(e))
        +		return 0;
        +	return 1;
        +	}       
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
        +#else
        +static ENGINE *engine_sureware(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_sureware(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_sureware(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_sureware();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* This is a process-global DSO handle used for loading and unloading
        + * the SureWareHook 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 *surewarehk_dso = NULL;
        +#ifndef OPENSSL_NO_RSA
        +static int rsaHndidx = -1;	/* Index for KM handle.  Not really used yet. */
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +static int dsaHndidx = -1;	/* Index for KM handle.  Not really used yet. */
        +#endif
        +
        +/* These are the function pointers that are (un)set when the library has
        + * successfully (un)loaded. */
        +static SureWareHook_Init_t *p_surewarehk_Init = NULL;
        +static SureWareHook_Finish_t *p_surewarehk_Finish = NULL;
        +static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL;
        +static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL;
        +static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL;
        +static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL;
        +static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL;
        +static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL;
        +static SureWareHook_Free_t *p_surewarehk_Free=NULL;
        +static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL;
        +static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL;
        +static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL;
        +static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL;
        +
        +/* Used in the DSO operations. */
        +static const char *surewarehk_LIBNAME = "SureWareHook";
        +static const char *n_surewarehk_Init = "SureWareHook_Init";
        +static const char *n_surewarehk_Finish = "SureWareHook_Finish";
        +static const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes";
        +static const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed";
        +static const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey";
        +static const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey";
        +static const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey";
        +static const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey";
        +static const char *n_surewarehk_Free="SureWareHook_Free";
        +static const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec";
        +static const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign";
        +static const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign";
        +static const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp";
        +static BIO *logstream = NULL;
        +
        +/* SureWareHook 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. 
        +*/
        +static int threadsafe=1;
        +static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +{
        +	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
        +				SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED);
        +		}
        +		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);
        +		threadsafe = 0;
        +		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        +		break;
        +
        +	/* The command isn't understood by this engine */
        +	default:
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
        +			ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +		to_return = 0;
        +		break;
        +		}
        +
        +	return to_return;
        +}
        +
        +/* Destructor (complements the "ENGINE_surewarehk()" constructor) */
        +static int surewarehk_destroy(ENGINE *e)
        +{
        +	ERR_unload_SUREWARE_strings();
        +	return 1;
        +}
        +
        +/* (de)initialisation functions. */
        +static int surewarehk_init(ENGINE *e)
        +{
        +	char msg[64]="ENGINE_init";
        +	SureWareHook_Init_t *p1=NULL;
        +	SureWareHook_Finish_t *p2=NULL;
        +	SureWareHook_Rand_Bytes_t *p3=NULL;
        +	SureWareHook_Rand_Seed_t *p4=NULL;
        +	SureWareHook_Load_Privkey_t *p5=NULL;
        +	SureWareHook_Load_Rsa_Pubkey_t *p6=NULL;
        +	SureWareHook_Free_t *p7=NULL;
        +	SureWareHook_Rsa_Priv_Dec_t *p8=NULL;
        +	SureWareHook_Rsa_Sign_t *p9=NULL;
        +	SureWareHook_Dsa_Sign_t *p12=NULL;
        +	SureWareHook_Info_Pubkey_t *p13=NULL;
        +	SureWareHook_Load_Dsa_Pubkey_t *p14=NULL;
        +	SureWareHook_Mod_Exp_t *p15=NULL;
        +
        +	if(surewarehk_dso != NULL)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED);
        +		goto err;
        +	}
        +	/* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */
        +	surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0);
        +	if(surewarehk_dso == NULL)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
        +		goto err;
        +	}
        +	if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) ||
        +	   !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) ||
        +	   !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) ||
        +	   !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) ||
        +	   !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) ||
        +	   !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) ||
        +	   !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) ||
        +	   !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) ||
        +	   !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) ||
        +	   !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) ||
        +	   !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) ||
        +	   !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) ||
        +	   !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp)))
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
        +		goto err;
        +	}
        +	/* Copy the pointers */
        +	p_surewarehk_Init = p1;
        +	p_surewarehk_Finish = p2;
        +	p_surewarehk_Rand_Bytes = p3;
        +	p_surewarehk_Rand_Seed = p4;
        +	p_surewarehk_Load_Privkey = p5;
        +	p_surewarehk_Load_Rsa_Pubkey = p6;
        +	p_surewarehk_Free = p7;
        +	p_surewarehk_Rsa_Priv_Dec = p8;
        +	p_surewarehk_Rsa_Sign = p9;
        +	p_surewarehk_Dsa_Sign = p12;
        +	p_surewarehk_Info_Pubkey = p13;
        +	p_surewarehk_Load_Dsa_Pubkey = p14;
        +	p_surewarehk_Mod_Exp = p15;
        +	/* Contact the hardware and initialises it. */
        +	if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
        +		goto err;
        +	}
        +	if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
        +		goto err;
        +	}
        +	/* try to load the default private key, if failed does not return a failure but
        +           wait for an explicit ENGINE_load_privakey */
        +	surewarehk_load_privkey(e,NULL,NULL,NULL);
        +
        +	/* Everything's fine. */
        +#ifndef OPENSSL_NO_RSA
        +	if (rsaHndidx == -1)
        +		rsaHndidx = RSA_get_ex_new_index(0,
        +						"SureWareHook RSA key handle",
        +						NULL, NULL, surewarehk_ex_free);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	if (dsaHndidx == -1)
        +		dsaHndidx = DSA_get_ex_new_index(0,
        +						"SureWareHook DSA key handle",
        +						NULL, NULL, surewarehk_ex_free);
        +#endif
        +
        +	return 1;
        +err:
        +	if(surewarehk_dso)
        +		DSO_free(surewarehk_dso);
        +	surewarehk_dso = NULL;
        +	p_surewarehk_Init = NULL;
        +	p_surewarehk_Finish = NULL;
        +	p_surewarehk_Rand_Bytes = NULL;
        +	p_surewarehk_Rand_Seed = NULL;
        +	p_surewarehk_Load_Privkey = NULL;
        +	p_surewarehk_Load_Rsa_Pubkey = NULL;
        +	p_surewarehk_Free = NULL;
        +	p_surewarehk_Rsa_Priv_Dec = NULL;
        +	p_surewarehk_Rsa_Sign = NULL;
        +	p_surewarehk_Dsa_Sign = NULL;
        +	p_surewarehk_Info_Pubkey = NULL;
        +	p_surewarehk_Load_Dsa_Pubkey = NULL;
        +	p_surewarehk_Mod_Exp = NULL;
        +	return 0;
        +}
        +
        +static int surewarehk_finish(ENGINE *e)
        +{
        +	int to_return = 1;
        +	if(surewarehk_dso == NULL)
        +		{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED);
        +		to_return = 0;
        +		goto err;
        +		}
        +	p_surewarehk_Finish();
        +	if(!DSO_free(surewarehk_dso))
        +		{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE);
        +		to_return = 0;
        +		goto err;
        +		}
        + err:
        +	if (logstream)
        +		BIO_free(logstream);
        +	surewarehk_dso = NULL;
        +	p_surewarehk_Init = NULL;
        +	p_surewarehk_Finish = NULL;
        +	p_surewarehk_Rand_Bytes = NULL;
        +	p_surewarehk_Rand_Seed = NULL;
        +	p_surewarehk_Load_Privkey = NULL;
        +	p_surewarehk_Load_Rsa_Pubkey = NULL;
        +	p_surewarehk_Free = NULL;
        +	p_surewarehk_Rsa_Priv_Dec = NULL;
        +	p_surewarehk_Rsa_Sign = NULL;
        +	p_surewarehk_Dsa_Sign = NULL;
        +	p_surewarehk_Info_Pubkey = NULL;
        +	p_surewarehk_Load_Dsa_Pubkey = NULL;
        +	p_surewarehk_Mod_Exp = NULL;
        +	return to_return;
        +}
        +
        +static void surewarehk_error_handling(char *const msg,int func,int ret)
        +{
        +	switch (ret)
        +	{
        +		case SUREWAREHOOK_ERROR_UNIT_FAILURE:
        +			ENGINEerr(func,SUREWARE_R_UNIT_FAILURE);
        +			break;
        +		case SUREWAREHOOK_ERROR_FALLBACK:
        +			ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK);
        +			break;
        +		case SUREWAREHOOK_ERROR_DATA_SIZE:
        +			ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +			break;
        +		case SUREWAREHOOK_ERROR_INVALID_PAD:
        +			ENGINEerr(func,SUREWARE_R_PADDING_CHECK_FAILED);
        +			break;
        +		default:
        +			ENGINEerr(func,SUREWARE_R_REQUEST_FAILED);
        +			break;
        +		case 1:/*nothing*/
        +			msg[0]='\0';
        +	}
        +	if (*msg)
        +	{
        +		ERR_add_error_data(1,msg);
        +		if (logstream)
        +		{
        +			CRYPTO_w_lock(CRYPTO_LOCK_BIO);
        +			BIO_write(logstream, msg, strlen(msg));
        +			CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
        +		}
        +	}
        +}
        +
        +static int surewarehk_rand_bytes(unsigned char *buf, int num)
        +{
        +	int ret=0;
        +	char msg[64]="ENGINE_rand_bytes";
        +	if(!p_surewarehk_Rand_Bytes)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +	{
        +		ret = p_surewarehk_Rand_Bytes(msg,buf, num);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret);
        +	}
        +	return ret==1 ? 1 : 0;
        +}
        +
        +static void surewarehk_rand_seed(const void *buf, int num)
        +{
        +	int ret=0;
        +	char msg[64]="ENGINE_rand_seed";
        +	if(!p_surewarehk_Rand_Seed)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +	{
        +		ret = p_surewarehk_Rand_Seed(msg,buf, num);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret);
        +	}
        +}
        +
        +static void surewarehk_rand_add(const void *buf, int num, double entropy)
        +{
        +	surewarehk_rand_seed(buf,num);
        +}
        +
        +static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype)
        +{
        +	EVP_PKEY *res = NULL;
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rsatmp = NULL;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	DSA *dsatmp=NULL;
        +#endif
        +	char msg[64]="sureware_load_public";
        +	int ret=0;
        +	if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_NOT_INITIALISED);
        +		goto err;
        +	}
        +	switch (keytype)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	case 1: /*RSA*/
        +		/* set private external reference */
        +		rsatmp = RSA_new_method(e);
        +		RSA_set_ex_data(rsatmp,rsaHndidx,hptr);
        +		rsatmp->flags |= RSA_FLAG_EXT_PKEY;
        +
        +		/* set public big nums*/
        +		rsatmp->e = BN_new();
        +		rsatmp->n = BN_new();
        +		bn_expand2(rsatmp->e, el/sizeof(BN_ULONG));
        +		bn_expand2(rsatmp->n, el/sizeof(BN_ULONG));
        +		if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))|| 
        +			!rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG)))
        +			goto err;
        +		ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el,
        +						 (unsigned long *)rsatmp->n->d,
        +						 (unsigned long *)rsatmp->e->d);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret);
        +		if (ret!=1)
        +		{
        +			SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
        +			goto err;
        +		}
        +		/* normalise pub e and pub n */
        +		rsatmp->e->top=el/sizeof(BN_ULONG);
        +		bn_fix_top(rsatmp->e);
        +		rsatmp->n->top=el/sizeof(BN_ULONG);
        +		bn_fix_top(rsatmp->n);
        +		/* create an EVP object: engine + rsa key */
        +		res = EVP_PKEY_new();
        +		EVP_PKEY_assign_RSA(res, rsatmp);
        +		break;
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +	case 2:/*DSA*/
        +		/* set private/public external reference */
        +		dsatmp = DSA_new_method(e);
        +		DSA_set_ex_data(dsatmp,dsaHndidx,hptr);
        +		/*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/
        +
        +		/* set public key*/
        +		dsatmp->pub_key = BN_new();
        +		dsatmp->p = BN_new();
        +		dsatmp->q = BN_new();
        +		dsatmp->g = BN_new();
        +		bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG));
        +		bn_expand2(dsatmp->p, el/sizeof(BN_ULONG));
        +		bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG));
        +		bn_expand2(dsatmp->g, el/sizeof(BN_ULONG));
        +		if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))|| 
        +			!dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) ||
        +			!dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) ||
        +			!dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG)))
        +			goto err;
        +
        +		ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el,
        +						 (unsigned long *)dsatmp->pub_key->d, 
        +						 (unsigned long *)dsatmp->p->d,
        +						 (unsigned long *)dsatmp->q->d,
        +						 (unsigned long *)dsatmp->g->d);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret);
        +		if (ret!=1)
        +		{
        +			SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
        +			goto err;
        +		}
        +		/* set parameters */
        +		/* normalise pubkey and parameters in case of */
        +		dsatmp->pub_key->top=el/sizeof(BN_ULONG);
        +		bn_fix_top(dsatmp->pub_key);
        +		dsatmp->p->top=el/sizeof(BN_ULONG);
        +		bn_fix_top(dsatmp->p);
        +		dsatmp->q->top=20/sizeof(BN_ULONG);
        +		bn_fix_top(dsatmp->q);
        +		dsatmp->g->top=el/sizeof(BN_ULONG);
        +		bn_fix_top(dsatmp->g);
        +
        +		/* create an EVP object: engine + rsa key */
        +		res = EVP_PKEY_new();
        +		EVP_PKEY_assign_DSA(res, dsatmp);
        +		break;
        +#endif
        +
        +	default:
        +		SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
        +		goto err;
        +	}
        +	return res;
        + err:
        +#ifndef OPENSSL_NO_RSA
        +	if (rsatmp)
        +		RSA_free(rsatmp);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	if (dsatmp)
        +		DSA_free(dsatmp);
        +#endif
        +	return NULL;
        +}
        +
        +static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
        +					 UI_METHOD *ui_method, void *callback_data)
        +{
        +	EVP_PKEY *res = NULL;
        +	int ret=0;
        +	unsigned long el=0;
        +	char *hptr=NULL;
        +	char keytype=0;
        +	char msg[64]="ENGINE_load_privkey";
        +
        +	if(!p_surewarehk_Load_Privkey)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +	{
        +		ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype);
        +		if (ret!=1)
        +		{
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
        +			ERR_add_error_data(1,msg);		
        +		}
        +		else
        +			res=sureware_load_public(e,key_id,hptr,el,keytype);
        +	}
        +	return res;
        +}
        +
        +static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
        +					 UI_METHOD *ui_method, void *callback_data)
        +{
        +	EVP_PKEY *res = NULL;
        +	int ret=0;
        +	unsigned long el=0;
        +	char *hptr=NULL;
        +	char keytype=0;
        +	char msg[64]="ENGINE_load_pubkey";
        +
        +	if(!p_surewarehk_Info_Pubkey)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +	{
        +		/* call once to identify if DSA or RSA */
        +		ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype);
        +		if (ret!=1)
        +		{
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
        +			ERR_add_error_data(1,msg);
        +		}
        +		else
        +			res=sureware_load_public(e,key_id,hptr,el,keytype);
        +	}
        +	return res;
        +}
        +
        +/* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware)
        +, called when ex_data is freed */
        +static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
        +	int idx,long argl, void *argp)
        +{
        +	if(!p_surewarehk_Free)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +		p_surewarehk_Free((char *)item,0);
        +}
        +
        +#if 0
        +/* not currently used (bug?) */
        +/* This cleans up an DH KM key (destroys the key into hardware), 
        +called when ex_data is freed */
        +static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
        +	int idx,long argl, void *argp)
        +{
        +	if(!p_surewarehk_Free)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +		p_surewarehk_Free((char *)item,1);
        +}
        +#endif
        +
        +/*
        +* return number of decrypted bytes
        +*/
        +#ifndef OPENSSL_NO_RSA
        +static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
        +			RSA *rsa,int padding)
        +{
        +	int ret=0,tlen;
        +	char *buf=NULL,*hptr=NULL;
        +	char msg[64]="ENGINE_rsa_priv_dec";
        +	if (!p_surewarehk_Rsa_Priv_Dec)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED);
        +	}
        +	/* extract ref to private key */
        +	else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS);
        +		goto err;
        +	}
        +	/* analyse what padding we can do into the hardware */
        +	if (padding==RSA_PKCS1_PADDING)
        +	{
        +		/* do it one shot */
        +		ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
        +		if (ret!=1)
        +			goto err;
        +		ret=tlen;
        +	}
        +	else /* do with no padding into hardware */
        +	{
        +		ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
        +		if (ret!=1)
        +			goto err;
        +		/* intermediate buffer for padding */
        +		if ((buf=OPENSSL_malloc(tlen)) == NULL)
        +		{
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		memcpy(buf,to,tlen);/* transfert to into buf */
        +		switch (padding) /* check padding in software */
        +		{
        +#ifndef OPENSSL_NO_SHA
        +		case RSA_PKCS1_OAEP_PADDING:
        +			ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0);
        +			break;
        +#endif
        + 		case RSA_SSLV23_PADDING:
        +			ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen);
        +			break;
        +		case RSA_NO_PADDING:
        +			ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen);
        +			break;
        +		default:
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_UNKNOWN_PADDING_TYPE);
        +			goto err;
        +		}
        +		if (ret < 0)
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_PADDING_CHECK_FAILED);
        +	}
        +err:
        +	if (buf)
        +	{
        +		OPENSSL_cleanse(buf,tlen);
        +		OPENSSL_free(buf);
        +	}
        +	return ret;
        +}
        +
        +/*
        +* Does what OpenSSL rsa_priv_enc does.
        +*/
        +static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
        +			    RSA *rsa,int padding)
        +{
        +	int ret=0,tlen;
        +	char *hptr=NULL;
        +	char msg[64]="ENGINE_rsa_sign";
        +	if (!p_surewarehk_Rsa_Sign)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,ENGINE_R_NOT_INITIALISED);
        +	}
        +	/* extract ref to private key */
        +	else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
        +	}
        +	else
        +	{
        +		switch (padding)
        +		{
        +		case RSA_PKCS1_PADDING: /* do it in one shot */
        +			ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
        +			surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_SIGN,ret);
        +			break;
        +		case RSA_NO_PADDING:
        +		default:
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_UNKNOWN_PADDING_TYPE);
        +		}
        +	}
        +	return ret==1 ? tlen : ret;
        +}
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* DSA sign and verify */
        +static	DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa)
        +{
        +	int ret=0;
        +	char *hptr=NULL;
        +	DSA_SIG *psign=NULL;
        +	char msg[64]="ENGINE_dsa_do_sign";
        +	if (!p_surewarehk_Dsa_Sign)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED);
        +		goto err;
        +	}
        +	/* extract ref to private key */
        +	else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx)))
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
        +		goto err;
        +	}
        +	else
        +	{
        +		if((psign = DSA_SIG_new()) == NULL)
        +		{
        +			SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +		}
        +		psign->r=BN_new();
        +		psign->s=BN_new();
        +		bn_expand2(psign->r, 20/sizeof(BN_ULONG));
        +		bn_expand2(psign->s, 20/sizeof(BN_ULONG));
        +		if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) ||
        +			!psign->s || psign->s->dmax!=20/sizeof(BN_ULONG))
        +			goto err;
        +		ret=p_surewarehk_Dsa_Sign(msg,flen,from,
        +					  (unsigned long *)psign->r->d,
        +					  (unsigned long *)psign->s->d,
        +					  hptr);
        +		surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret);
        +	}
        +	psign->r->top=20/sizeof(BN_ULONG);
        +	bn_fix_top(psign->r);
        +	psign->s->top=20/sizeof(BN_ULONG);
        +	bn_fix_top(psign->s);
        +
        +err:	
        +	if (psign)
        +	{
        +		DSA_SIG_free(psign);
        +		psign=NULL;
        +	}
        +	return psign;
        +}
        +#endif
        +
        +static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			     const BIGNUM *m, BN_CTX *ctx)
        +{
        +	int ret=0;
        +	char msg[64]="ENGINE_modexp";
        +	if (!p_surewarehk_Mod_Exp)
        +	{
        +		SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP,ENGINE_R_NOT_INITIALISED);
        +	}
        +	else
        +	{
        +		bn_expand2(r,m->top);
        +		if (r && r->dmax==m->top)
        +		{
        +			/* do it*/
        +			ret=p_surewarehk_Mod_Exp(msg,
        +						 m->top*sizeof(BN_ULONG),
        +						 (unsigned long *)m->d,
        +						 p->top*sizeof(BN_ULONG),
        +						 (unsigned long *)p->d,
        +						 a->top*sizeof(BN_ULONG),
        +						 (unsigned long *)a->d,
        +						 (unsigned long *)r->d);
        +			surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MODEXP,ret);
        +			if (ret==1)
        +			{
        +				/* normalise result */
        +				r->top=m->top;
        +				bn_fix_top(r);
        +			}
        +		}
        +	}
        +	return ret;
        +}
        +#endif /* !OPENSSL_NO_HW_SureWare */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_sureware.ec b/vendor/openssl/openssl/engines/e_sureware.ec
        new file mode 100644
        index 000000000..3d266b8b7
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_sureware.ec
        @@ -0,0 +1 @@
        +L SUREWARE	e_sureware_err.h		e_sureware_err.c
        diff --git a/vendor/openssl/openssl/engines/e_sureware_err.c b/vendor/openssl/openssl/engines/e_sureware_err.c
        new file mode 100644
        index 000000000..d4ca68c1d
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_sureware_err.c
        @@ -0,0 +1,158 @@
        +/* e_sureware_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_sureware_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA SUREWARE_str_functs[]=
        +	{
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_CTRL),	"SUREWAREHK_CTRL"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_DH_EX_FREE),	"SUREWAREHK_DH_EX_FREE"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN),	"SUREWAREHK_DSA_DO_SIGN"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_EX_FREE),	"SUREWAREHK_EX_FREE"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_FINISH),	"SUREWAREHK_FINISH"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_INIT),	"SUREWAREHK_INIT"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY),	"SUREWAREHK_LOAD_PRIVKEY"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY),	"SUREWAREHK_LOAD_PUBKEY"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_MODEXP),	"SUREWAREHK_MODEXP"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_BYTES),	"SUREWAREHK_RAND_BYTES"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_SEED),	"SUREWAREHK_RAND_SEED"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC),	"SUREWAREHK_RSA_PRIV_DEC"},
        +{ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_SIGN),	"SUREWAREHK_RSA_SIGN"},
        +{ERR_FUNC(SUREWARE_F_SUREWARE_LOAD_PUBLIC),	"SUREWARE_LOAD_PUBLIC"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA SUREWARE_str_reasons[]=
        +	{
        +{ERR_REASON(SUREWARE_R_BIO_WAS_FREED)    ,"bio was freed"},
        +{ERR_REASON(SUREWARE_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{ERR_REASON(SUREWARE_R_PADDING_CHECK_FAILED),"padding check failed"},
        +{ERR_REASON(SUREWARE_R_REQUEST_FAILED)   ,"request failed"},
        +{ERR_REASON(SUREWARE_R_REQUEST_FALLBACK) ,"request fallback"},
        +{ERR_REASON(SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
        +{ERR_REASON(SUREWARE_R_UNIT_FAILURE)     ,"unit failure"},
        +{ERR_REASON(SUREWARE_R_UNKNOWN_PADDING_TYPE),"unknown padding type"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef SUREWARE_LIB_NAME
        +static ERR_STRING_DATA SUREWARE_lib_name[]=
        +        {
        +{0	,SUREWARE_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int SUREWARE_lib_error_code=0;
        +static int SUREWARE_error_init=1;
        +
        +static void ERR_load_SUREWARE_strings(void)
        +	{
        +	if (SUREWARE_lib_error_code == 0)
        +		SUREWARE_lib_error_code=ERR_get_next_error_library();
        +
        +	if (SUREWARE_error_init)
        +		{
        +		SUREWARE_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
        +		ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
        +#endif
        +
        +#ifdef SUREWARE_LIB_NAME
        +		SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code,0,0);
        +		ERR_load_strings(0,SUREWARE_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_SUREWARE_strings(void)
        +	{
        +	if (SUREWARE_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
        +		ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
        +#endif
        +
        +#ifdef SUREWARE_LIB_NAME
        +		ERR_unload_strings(0,SUREWARE_lib_name);
        +#endif
        +		SUREWARE_error_init=1;
        +		}
        +	}
        +
        +static void ERR_SUREWARE_error(int function, int reason, char *file, int line)
        +	{
        +	if (SUREWARE_lib_error_code == 0)
        +		SUREWARE_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(SUREWARE_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_sureware_err.h b/vendor/openssl/openssl/engines/e_sureware_err.h
        new file mode 100644
        index 000000000..ec8ed0c59
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_sureware_err.h
        @@ -0,0 +1,102 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_SUREWARE_ERR_H
        +#define HEADER_SUREWARE_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_SUREWARE_strings(void);
        +static void ERR_unload_SUREWARE_strings(void);
        +static void ERR_SUREWARE_error(int function, int reason, char *file, int line);
        +#define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the SUREWARE functions. */
        +
        +/* Function codes. */
        +#define SUREWARE_F_SUREWAREHK_CTRL			 100
        +#define SUREWARE_F_SUREWAREHK_DH_EX_FREE		 112
        +#define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN		 101
        +#define SUREWARE_F_SUREWAREHK_EX_FREE			 102
        +#define SUREWARE_F_SUREWAREHK_FINISH			 103
        +#define SUREWARE_F_SUREWAREHK_INIT			 104
        +#define SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY		 105
        +#define SUREWARE_F_SUREWAREHK_LOAD_PUBKEY		 113
        +#define SUREWARE_F_SUREWAREHK_MODEXP			 107
        +#define SUREWARE_F_SUREWAREHK_RAND_BYTES		 108
        +#define SUREWARE_F_SUREWAREHK_RAND_SEED			 109
        +#define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC		 110
        +#define SUREWARE_F_SUREWAREHK_RSA_SIGN			 111
        +#define SUREWARE_F_SUREWARE_LOAD_PUBLIC			 106
        +
        +/* Reason codes. */
        +#define SUREWARE_R_BIO_WAS_FREED			 100
        +#define SUREWARE_R_MISSING_KEY_COMPONENTS		 105
        +#define SUREWARE_R_PADDING_CHECK_FAILED			 106
        +#define SUREWARE_R_REQUEST_FAILED			 101
        +#define SUREWARE_R_REQUEST_FALLBACK			 102
        +#define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 103
        +#define SUREWARE_R_UNIT_FAILURE				 104
        +#define SUREWARE_R_UNKNOWN_PADDING_TYPE			 107
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/e_ubsec.c b/vendor/openssl/openssl/engines/e_ubsec.c
        new file mode 100644
        index 000000000..aa5709bd8
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_ubsec.c
        @@ -0,0 +1,1069 @@
        +/* crypto/engine/hw_ubsec.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + *
        + * Cloned shamelessly by Joe Tardo. 
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/crypto.h>
        +#include <openssl/buffer.h>
        +#include <openssl/dso.h>
        +#include <openssl/engine.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#ifndef OPENSSL_NO_HW
        +#ifndef OPENSSL_NO_HW_UBSEC
        +
        +#ifdef FLAT_INC
        +#include "hw_ubsec.h"
        +#else
        +#include "vendor_defns/hw_ubsec.h"
        +#endif
        +
        +#define UBSEC_LIB_NAME "ubsec engine"
        +#include "e_ubsec_err.c"
        +
        +#define FAIL_TO_SOFTWARE -15
        +
        +static int ubsec_destroy(ENGINE *e);
        +static int ubsec_init(ENGINE *e);
        +static int ubsec_finish(ENGINE *e);
        +static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        +static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx);
        +#ifndef OPENSSL_NO_RSA
        +static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			const BIGNUM *q, const BIGNUM *dp,
        +			const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
        +static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
        +static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#ifdef NOT_USED
        +static int ubsec_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 ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx);
        +#endif
        +static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
        +static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
        +                                DSA_SIG *sig, DSA *dsa);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx);
        +static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
        +static int ubsec_dh_generate_key(DH *dh);
        +#endif
        +
        +#ifdef NOT_USED
        +static int ubsec_rand_bytes(unsigned char *buf, int num);
        +static int ubsec_rand_status(void);
        +#endif
        +
        +#define UBSEC_CMD_SO_PATH		ENGINE_CMD_BASE
        +static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
        +	{UBSEC_CMD_SO_PATH,
        +		"SO_PATH",
        +		"Specifies the path to the 'ubsec' shared library",
        +		ENGINE_CMD_FLAG_STRING},
        +	{0, NULL, NULL, 0}
        +	};
        +
        +#ifndef OPENSSL_NO_RSA
        +/* Our internal RSA_METHOD that we provide pointers to */
        +static RSA_METHOD ubsec_rsa =
        +	{
        +	"UBSEC RSA method",
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL,
        +	ubsec_rsa_mod_exp,
        +	ubsec_mod_exp_mont,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +/* Our internal DSA_METHOD that we provide pointers to */
        +static DSA_METHOD ubsec_dsa =
        +	{
        +	"UBSEC DSA method",
        +	ubsec_dsa_do_sign, /* dsa_do_sign */
        +	NULL, /* dsa_sign_setup */
        +	ubsec_dsa_verify, /* dsa_do_verify */
        +	NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
        +	NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
        +	NULL, /* init */
        +	NULL, /* finish */
        +	0, /* flags */
        +	NULL, /* app_data */
        +	NULL, /* dsa_paramgen */
        +	NULL /* dsa_keygen */
        +	};
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* Our internal DH_METHOD that we provide pointers to */
        +static DH_METHOD ubsec_dh =
        +	{
        +	"UBSEC DH method",
        +	ubsec_dh_generate_key,
        +	ubsec_dh_compute_key,
        +	ubsec_mod_exp_dh,
        +	NULL,
        +	NULL,
        +	0,
        +	NULL,
        +	NULL
        +	};
        +#endif
        +
        +/* Constants used when creating the ENGINE */
        +static const char *engine_ubsec_id = "ubsec";
        +static const char *engine_ubsec_name = "UBSEC hardware engine support";
        +
        +/* This internal function is used by ENGINE_ubsec() and possibly by the
        + * "dynamic" ENGINE support too */
        +static int bind_helper(ENGINE *e)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	const RSA_METHOD *meth1;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#ifndef HAVE_UBSEC_DH
        +	const DH_METHOD *meth3;
        +#endif /* HAVE_UBSEC_DH */
        +#endif
        +	if(!ENGINE_set_id(e, engine_ubsec_id) ||
        +			!ENGINE_set_name(e, engine_ubsec_name) ||
        +#ifndef OPENSSL_NO_RSA
        +			!ENGINE_set_RSA(e, &ubsec_rsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			!ENGINE_set_DSA(e, &ubsec_dsa) ||
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			!ENGINE_set_DH(e, &ubsec_dh) ||
        +#endif
        +			!ENGINE_set_destroy_function(e, ubsec_destroy) ||
        +			!ENGINE_set_init_function(e, ubsec_init) ||
        +			!ENGINE_set_finish_function(e, ubsec_finish) ||
        +			!ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
        +			!ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
        +		return 0;
        +
        +#ifndef OPENSSL_NO_RSA
        +	/* We know that the "PKCS1_SSLeay()" functions hook properly
        +	 * to the Broadcom-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();
        +	ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
        +	ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
        +	ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
        +	ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +#ifndef HAVE_UBSEC_DH
        +	/* Much the same for Diffie-Hellman */
        +	meth3 = DH_OpenSSL();
        +	ubsec_dh.generate_key = meth3->generate_key;
        +	ubsec_dh.compute_key = meth3->compute_key;
        +#endif /* HAVE_UBSEC_DH */
        +#endif
        +
        +	/* Ensure the ubsec error handling is set up */
        +	ERR_load_UBSEC_strings();
        +	return 1;
        +	}
        +
        +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
        +static ENGINE *engine_ubsec(void)
        +	{
        +	ENGINE *ret = ENGINE_new();
        +	if(!ret)
        +		return NULL;
        +	if(!bind_helper(ret))
        +		{
        +		ENGINE_free(ret);
        +		return NULL;
        +		}
        +	return ret;
        +	}
        +
        +void ENGINE_load_ubsec(void)
        +	{
        +	/* Copied from eng_[openssl|dyn].c */
        +	ENGINE *toadd = engine_ubsec();
        +	if(!toadd) return;
        +	ENGINE_add(toadd);
        +	ENGINE_free(toadd);
        +	ERR_clear_error();
        +	}
        +#endif
        +
        +/* This is a process-global DSO handle used for loading and unloading
        + * the UBSEC 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 *ubsec_dso = NULL;
        +
        +/* These are the function pointers that are (un)set when the library has
        + * successfully (un)loaded. */
        +
        +static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
        +static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
        +static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
        +static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
        +#ifndef OPENSSL_NO_DH
        +static t_UBSEC_diffie_hellman_generate_ioctl 
        +	*p_UBSEC_diffie_hellman_generate_ioctl = NULL;
        +static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
        +static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
        +static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
        +#endif
        +static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
        +static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
        +static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
        +
        +static int max_key_len = 1024;  /* ??? */
        +
        +/* 
        + * These are the static string constants for the DSO file name and the function
        + * symbol names to bind to. 
        + */
        +
        +static const char *UBSEC_LIBNAME = NULL;
        +static const char *get_UBSEC_LIBNAME(void)
        +	{
        +	if(UBSEC_LIBNAME)
        +		return UBSEC_LIBNAME;
        +	return "ubsec";
        +	}
        +static void free_UBSEC_LIBNAME(void)
        +	{
        +	if(UBSEC_LIBNAME)
        +		OPENSSL_free((void*)UBSEC_LIBNAME);
        +	UBSEC_LIBNAME = NULL;
        +	}
        +static long set_UBSEC_LIBNAME(const char *name)
        +	{
        +	free_UBSEC_LIBNAME();
        +	return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
        +	}
        +static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
        +static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
        +static const char *UBSEC_F3 = "ubsec_open";
        +static const char *UBSEC_F4 = "ubsec_close";
        +#ifndef OPENSSL_NO_DH
        +static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
        +static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
        +#endif
        +/* #ifndef OPENSSL_NO_RSA */
        +static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
        +static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
        +/* #endif */
        +#ifndef OPENSSL_NO_DSA
        +static const char *UBSEC_F9 = "dsa_sign_ioctl";
        +static const char *UBSEC_F10 = "dsa_verify_ioctl";
        +#endif
        +static const char *UBSEC_F11 = "math_accelerate_ioctl";
        +static const char *UBSEC_F12 = "rng_ioctl";
        +static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
        +
        +/* Destructor (complements the "ENGINE_ubsec()" constructor) */
        +static int ubsec_destroy(ENGINE *e)
        +	{
        +	free_UBSEC_LIBNAME();
        +	ERR_unload_UBSEC_strings();
        +	return 1;
        +	}
        +
        +/* (de)initialisation functions. */
        +static int ubsec_init(ENGINE *e)
        +	{
        +	t_UBSEC_ubsec_bytes_to_bits *p1;
        +	t_UBSEC_ubsec_bits_to_bytes *p2;
        +	t_UBSEC_ubsec_open *p3;
        +	t_UBSEC_ubsec_close *p4;
        +#ifndef OPENSSL_NO_DH
        +	t_UBSEC_diffie_hellman_generate_ioctl *p5;
        +	t_UBSEC_diffie_hellman_agree_ioctl *p6;
        +#endif
        +/* #ifndef OPENSSL_NO_RSA */
        +	t_UBSEC_rsa_mod_exp_ioctl *p7;
        +	t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
        +/* #endif */
        +#ifndef OPENSSL_NO_DSA
        +	t_UBSEC_dsa_sign_ioctl *p9;
        +	t_UBSEC_dsa_verify_ioctl *p10;
        +#endif
        +	t_UBSEC_math_accelerate_ioctl *p11;
        +	t_UBSEC_rng_ioctl *p12;
        +        t_UBSEC_max_key_len_ioctl *p13;
        +	int fd = 0;
        +
        +	if(ubsec_dso != NULL)
        +		{
        +		UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
        +		goto err;
        +		}
        +	/* 
        +	 * Attempt to load libubsec.so/ubsec.dll/whatever. 
        +	 */
        +	ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
        +	if(ubsec_dso == NULL)
        +		{
        +		UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
        +		goto err;
        +		}
        +
        +	if (
        +	!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
        +	!(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
        +	!(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
        +	!(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
        +#ifndef OPENSSL_NO_DH
        +	!(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) 
        +				DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
        +	!(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) 
        +				DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
        +#endif
        +/* #ifndef OPENSSL_NO_RSA */
        +	!(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
        +	!(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
        +/* #endif */
        +#ifndef OPENSSL_NO_DSA
        +	!(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
        +	!(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
        +#endif
        +	!(p11 = (t_UBSEC_math_accelerate_ioctl *) 
        +				DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
        +	!(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
        +        !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
        +		{
        +		UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
        +		goto err;
        +		}
        +
        +	/* Copy the pointers */
        +	p_UBSEC_ubsec_bytes_to_bits = p1;
        +	p_UBSEC_ubsec_bits_to_bytes = p2;
        +	p_UBSEC_ubsec_open = p3;
        +	p_UBSEC_ubsec_close = p4;
        +#ifndef OPENSSL_NO_DH
        +	p_UBSEC_diffie_hellman_generate_ioctl = p5;
        +	p_UBSEC_diffie_hellman_agree_ioctl = p6;
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	p_UBSEC_rsa_mod_exp_ioctl = p7;
        +	p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	p_UBSEC_dsa_sign_ioctl = p9;
        +	p_UBSEC_dsa_verify_ioctl = p10;
        +#endif
        +	p_UBSEC_math_accelerate_ioctl = p11;
        +	p_UBSEC_rng_ioctl = p12;
        +        p_UBSEC_max_key_len_ioctl = p13;
        +
        +	/* Perform an open to see if there's actually any unit running. */
        +	if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
        +	{
        +	   p_UBSEC_ubsec_close(fd);
        +	   return 1;
        +	}
        +	else
        +	{
        +	  UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
        +	}
        +
        +err:
        +	if(ubsec_dso)
        +		DSO_free(ubsec_dso);
        +	ubsec_dso = NULL;
        +	p_UBSEC_ubsec_bytes_to_bits = NULL;
        +	p_UBSEC_ubsec_bits_to_bytes = NULL;
        +	p_UBSEC_ubsec_open = NULL;
        +	p_UBSEC_ubsec_close = NULL;
        +#ifndef OPENSSL_NO_DH
        +	p_UBSEC_diffie_hellman_generate_ioctl = NULL;
        +	p_UBSEC_diffie_hellman_agree_ioctl = NULL;
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	p_UBSEC_rsa_mod_exp_ioctl = NULL;
        +	p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	p_UBSEC_dsa_sign_ioctl = NULL;
        +	p_UBSEC_dsa_verify_ioctl = NULL;
        +#endif
        +	p_UBSEC_math_accelerate_ioctl = NULL;
        +	p_UBSEC_rng_ioctl = NULL;
        +        p_UBSEC_max_key_len_ioctl = NULL;
        +
        +	return 0;
        +	}
        +
        +static int ubsec_finish(ENGINE *e)
        +	{
        +	free_UBSEC_LIBNAME();
        +	if(ubsec_dso == NULL)
        +		{
        +		UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
        +		return 0;
        +		}
        +	if(!DSO_free(ubsec_dso))
        +		{
        +		UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
        +		return 0;
        +		}
        +	ubsec_dso = NULL;
        +	p_UBSEC_ubsec_bytes_to_bits = NULL;
        +	p_UBSEC_ubsec_bits_to_bytes = NULL;
        +	p_UBSEC_ubsec_open = NULL;
        +	p_UBSEC_ubsec_close = NULL;
        +#ifndef OPENSSL_NO_DH
        +	p_UBSEC_diffie_hellman_generate_ioctl = NULL;
        +	p_UBSEC_diffie_hellman_agree_ioctl = NULL;
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	p_UBSEC_rsa_mod_exp_ioctl = NULL;
        +	p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	p_UBSEC_dsa_sign_ioctl = NULL;
        +	p_UBSEC_dsa_verify_ioctl = NULL;
        +#endif
        +	p_UBSEC_math_accelerate_ioctl = NULL;
        +	p_UBSEC_rng_ioctl = NULL;
        +        p_UBSEC_max_key_len_ioctl = NULL;
        +	return 1;
        +	}
        +
        +static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
        +	{
        +	int initialised = ((ubsec_dso == NULL) ? 0 : 1);
        +	switch(cmd)
        +		{
        +	case UBSEC_CMD_SO_PATH:
        +		if(p == NULL)
        +			{
        +			UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
        +			return 0;
        +			}
        +		if(initialised)
        +			{
        +			UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
        +			return 0;
        +			}
        +		return set_UBSEC_LIBNAME((const char *)p);
        +	default:
        +		break;
        +		}
        +	UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        +	return 0;
        +	}
        +
        +static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx)
        +	{
        +	int 	y_len = 0;
        +	int 	fd;
        +
        +	if(ubsec_dso == NULL)
        +	{
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
        +		return 0;
        +	}
        +
        +	/* Check if hardware can't handle this argument. */
        +	y_len = BN_num_bits(m);
        +	if (y_len > max_key_len) {
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +                return BN_mod_exp(r, a, p, m, ctx);
        +	} 
        +
        +	if(!bn_wexpand(r, m->top))
        +	{
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
        +		return 0;
        +	}
        +
        +	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
        +		fd = 0;
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE);
        +                return BN_mod_exp(r, a, p, m, ctx);
        +	}
        +
        +	if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
        +		(unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d, 
        +		BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
        +	{
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +
        +                return BN_mod_exp(r, a, p, m, ctx);
        +	}
        +
        +	p_UBSEC_ubsec_close(fd);
        +
        +	r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
        +	return 1;
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        +	{
        +	int to_return = 0;
        +
        +	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
        +		{
        +		UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
        +		goto err;
        +		}
        +
        +	to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
        +		    rsa->dmq1, rsa->iqmp, ctx);
        +	if (to_return == FAIL_TO_SOFTWARE)
        +	{
        +	  /*
        +	   * Do in software as hardware failed.
        +	   */
        +	   const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +	   to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
        +	}
        +err:
        +	return to_return;
        +	}
        +
        +static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +			const BIGNUM *q, const BIGNUM *dp,
        +			const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
        +	{
        +	int	y_len,
        +		fd;
        +
        +	y_len = BN_num_bits(p) + BN_num_bits(q);
        +
        +	/* Check if hardware can't handle this argument. */
        +	if (y_len > max_key_len) {
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
        +		return FAIL_TO_SOFTWARE;
        +	} 
        +
        +	if (!bn_wexpand(r, p->top + q->top + 1)) {
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
        +		return 0;
        +	}
        +
        +	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
        +		fd = 0;
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE);
        +		return FAIL_TO_SOFTWARE;
        +	}
        +
        +	if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
        +		(unsigned char *)a->d, BN_num_bits(a), 
        +		(unsigned char *)qinv->d, BN_num_bits(qinv),
        +		(unsigned char *)dp->d, BN_num_bits(dp),
        +		(unsigned char *)p->d, BN_num_bits(p),
        +		(unsigned char *)dq->d, BN_num_bits(dq),
        +		(unsigned char *)q->d, BN_num_bits(q),
        +		(unsigned char *)r->d,  &y_len) != 0) {
        +		UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +		return FAIL_TO_SOFTWARE;
        +	}
        +
        +	p_UBSEC_ubsec_close(fd);
        +
        +	r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
        +	return 1;
        +}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +#ifdef NOT_USED
        +static int ubsec_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 (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
        +	/* let t = a2 ^ p2 mod m */
        +	if (!ubsec_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 ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        +		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx)
        +	{
        +	return ubsec_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +
        +/*
        + * This function is aliased to mod_exp (with the mont stuff dropped).
        + */
        +static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        +		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        +        {
        +	int ret = 0;
        +
        + 	/* Do in software if the key is too large for the hardware. */
        +	if (BN_num_bits(m) > max_key_len)
        +                {
        +		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
        +		ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
        +                }
        +        else
        +                {
        +		ret = ubsec_mod_exp(r, a, p, m, ctx);
        +                }
        +	
        +	return ret;
        +        }
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* This function is aliased to mod_exp (with the dh and mont dropped). */
        +static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
        +		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        +		BN_MONT_CTX *m_ctx)
        +	{
        +	return ubsec_mod_exp(r, a, p, m, ctx);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DSA
        +static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        +	{
        +	DSA_SIG *to_return = NULL;
        +	int s_len = 160, r_len = 160, d_len, fd;
        +	BIGNUM m, *r=NULL, *s=NULL;
        +
        +	BN_init(&m);
        +
        +	s = BN_new();
        +	r = BN_new();
        +	if ((s == NULL) || (r==NULL))
        +		goto err;
        +
        +	d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
        +
        +        if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
        +       	   (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
        +		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +
        +	if (BN_bin2bn(dgst,dlen,&m) == NULL) {
        +		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
        +		goto err;
        +	} 
        +
        +	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
        +                const DSA_METHOD *meth;
        +		fd = 0;
        +		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE);
        +                meth = DSA_OpenSSL();
        +                to_return =  meth->dsa_do_sign(dgst, dlen, dsa);
        +		goto err;
        +	}
        +
        +	if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
        +		(unsigned char *)dgst, d_len,
        +		NULL, 0,  /* compute random value */
        +		(unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 
        +		(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
        +		(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
        +		(unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
        +		(unsigned char *)r->d, &r_len,
        +		(unsigned char *)s->d, &s_len ) != 0) {
        +                const DSA_METHOD *meth;
        +
        +		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +                meth = DSA_OpenSSL();
        +                to_return = meth->dsa_do_sign(dgst, dlen, dsa);
        +
        +		goto err;
        +	}
        +
        +	p_UBSEC_ubsec_close(fd);
        +
        +	r->top = (160+BN_BITS2-1)/BN_BITS2;
        +	s->top = (160+BN_BITS2-1)/BN_BITS2;
        +
        +	to_return = DSA_SIG_new();
        +	if(to_return == NULL) {
        +		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +
        +	to_return->r = r;
        +	to_return->s = s;
        +
        +err:
        +	if (!to_return) {
        +		if (r) BN_free(r);
        +		if (s) BN_free(s);
        +	}                                 
        +	BN_clear_free(&m);
        +	return to_return;
        +}
        +
        +static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
        +                                DSA_SIG *sig, DSA *dsa)
        +	{
        +	int v_len, d_len;
        +	int to_return = 0;
        +	int fd;
        +	BIGNUM v, *pv = &v;
        +
        +	BN_init(&v);
        +
        +	if(!bn_wexpand(pv, dsa->p->top)) {
        +		UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
        +		goto err;
        +	}
        +
        +	v_len = BN_num_bits(dsa->p);
        +
        +	d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
        +
        +	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
        +                const DSA_METHOD *meth;
        +		fd = 0;
        +		UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE);
        +                meth = DSA_OpenSSL();
        +                to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
        +		goto err;
        +	}
        +
        +	if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
        +		(unsigned char *)dgst, d_len,
        +		(unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 
        +		(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
        +		(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
        +		(unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
        +		(unsigned char *)sig->r->d, BN_num_bits(sig->r),
        +		(unsigned char *)sig->s->d, BN_num_bits(sig->s),
        +		(unsigned char *)v.d, &v_len) != 0) {
        +                const DSA_METHOD *meth;
        +		UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +
        +                meth = DSA_OpenSSL();
        +                to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
        +
        +		goto err;
        +	}
        +
        +	p_UBSEC_ubsec_close(fd);
        +
        +	to_return = 1;
        +err:
        +	BN_clear_free(&v);
        +	return to_return;
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
        +        {
        +        int      ret      = -1,
        +                 k_len,
        +                 fd;
        +
        +        k_len = BN_num_bits(dh->p);
        +
        +        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
        +                {
        +                const DH_METHOD *meth;
        +                UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE);
        +                meth = DH_OpenSSL();
        +                ret = meth->compute_key(key, pub_key, dh);
        +                goto err;
        +                }
        +
        +        if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
        +                                               (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
        +                                               (unsigned char *)pub_key->d, BN_num_bits(pub_key),
        +                                               (unsigned char *)dh->p->d, BN_num_bits(dh->p),
        +                                               key, &k_len) != 0)
        +                {
        +                /* Hardware's a no go, failover to software */
        +                const DH_METHOD *meth;
        +                UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +
        +                meth = DH_OpenSSL();
        +                ret = meth->compute_key(key, pub_key, dh);
        +
        +                goto err;
        +                }
        +
        +        p_UBSEC_ubsec_close(fd);
        +
        +        ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
        +err:
        +        return ret;
        +        }
        +
        +static int ubsec_dh_generate_key(DH *dh)
        +        {
        +        int      ret               = 0,
        +                 random_bits       = 0,
        +                 pub_key_len       = 0,
        +                 priv_key_len      = 0,
        +                 fd;
        +        BIGNUM   *pub_key          = NULL;
        +        BIGNUM   *priv_key         = NULL;
        +
        +        /* 
        +         *  How many bits should Random x be? dh_key.c
        +         *  sets the range from 0 to num_bits(modulus) ???
        +         */
        +
        +        if (dh->priv_key == NULL)
        +                {
        +                priv_key = BN_new();
        +                if (priv_key == NULL) goto err;
        +                priv_key_len = BN_num_bits(dh->p);
        +                if(bn_wexpand(priv_key, dh->p->top) == NULL) goto err;
        +                do
        +                        if (!BN_rand_range(priv_key, dh->p)) goto err;
        +                while (BN_is_zero(priv_key));
        +                random_bits = BN_num_bits(priv_key);
        +                }
        +        else
        +                {
        +                priv_key = dh->priv_key;
        +                }
        +
        +        if (dh->pub_key == NULL)
        +                {
        +                pub_key = BN_new();
        +                pub_key_len = BN_num_bits(dh->p);
        +                if(bn_wexpand(pub_key, dh->p->top) == NULL) goto err;
        +                if(pub_key == NULL) goto err;
        +                }
        +        else
        +                {
        +                pub_key = dh->pub_key;
        +                }
        +
        +        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
        +                {
        +                const DH_METHOD *meth;
        +                UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE);
        +                meth = DH_OpenSSL();
        +                ret = meth->generate_key(dh);
        +                goto err;
        +                }
        +
        +        if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
        +                                                  (unsigned char *)priv_key->d, &priv_key_len,
        +                                                  (unsigned char *)pub_key->d,  &pub_key_len,
        +                                                  (unsigned char *)dh->g->d, BN_num_bits(dh->g),
        +                                                  (unsigned char *)dh->p->d, BN_num_bits(dh->p),
        +                                                  0, 0, random_bits) != 0)
        +                {
        +                /* Hardware's a no go, failover to software */
        +                const DH_METHOD *meth;
        +
        +                UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +
        +                meth = DH_OpenSSL();
        +                ret = meth->generate_key(dh);
        +
        +                goto err;
        +                }
        +
        +        p_UBSEC_ubsec_close(fd);
        +
        +        dh->pub_key = pub_key;
        +        dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
        +        dh->priv_key = priv_key;
        +        dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
        +
        +        ret = 1;
        +err:
        +        return ret;
        +        }
        +#endif
        +
        +#ifdef NOT_USED
        +static int ubsec_rand_bytes(unsigned char * buf,
        +                            int num)
        +        {
        +        int      ret      = 0,
        +                 fd;
        +
        +        if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
        +                {
        +                const RAND_METHOD *meth;
        +                UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE);
        +                num = p_UBSEC_ubsec_bits_to_bytes(num);
        +                meth = RAND_SSLeay();
        +                meth->seed(buf, num);
        +                ret = meth->bytes(buf, num);
        +                goto err;
        +                }
        +
        +        num *= 8; /* bytes to bits */
        +
        +        if (p_UBSEC_rng_ioctl(fd,
        +                              UBSEC_RNG_DIRECT,
        +                              buf,
        +                              &num) != 0)
        +                {
        +                /* Hardware's a no go, failover to software */
        +                const RAND_METHOD *meth;
        +
        +                UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED);
        +                p_UBSEC_ubsec_close(fd);
        +
        +                num = p_UBSEC_ubsec_bits_to_bytes(num);
        +                meth = RAND_SSLeay();
        +                meth->seed(buf, num);
        +                ret = meth->bytes(buf, num);
        +
        +                goto err;
        +                }
        +
        +        p_UBSEC_ubsec_close(fd);
        +
        +        ret = 1;
        +err:
        +        return(ret);
        +        }
        +
        +
        +static int ubsec_rand_status(void)
        +	{
        +	return 0;
        +	}
        +#endif
        +
        +/* This stuff is needed if this ENGINE is being compiled into a self-contained
        + * shared-library. */
        +#ifndef OPENSSL_NO_DYNAMIC_ENGINE
        +static int bind_fn(ENGINE *e, const char *id)
        +	{
        +	if(id && (strcmp(id, engine_ubsec_id) != 0))
        +		return 0;
        +	if(!bind_helper(e))
        +		return 0;
        +	return 1;
        +	}
        +IMPLEMENT_DYNAMIC_CHECK_FN()
        +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
        +#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
        +
        +#endif /* !OPENSSL_NO_HW_UBSEC */
        +#endif /* !OPENSSL_NO_HW */
        diff --git a/vendor/openssl/openssl/engines/e_ubsec.ec b/vendor/openssl/openssl/engines/e_ubsec.ec
        new file mode 100644
        index 000000000..99b923356
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_ubsec.ec
        @@ -0,0 +1 @@
        +L UBSEC		e_ubsec_err.h			e_ubsec_err.c
        diff --git a/vendor/openssl/openssl/engines/e_ubsec_err.c b/vendor/openssl/openssl/engines/e_ubsec_err.c
        new file mode 100644
        index 000000000..14c3d61e2
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_ubsec_err.c
        @@ -0,0 +1,157 @@
        +/* e_ubsec_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/err.h>
        +#include "e_ubsec_err.h"
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(0,func,0)
        +#define ERR_REASON(reason) ERR_PACK(0,0,reason)
        +
        +static ERR_STRING_DATA UBSEC_str_functs[]=
        +	{
        +{ERR_FUNC(UBSEC_F_UBSEC_CTRL),	"UBSEC_CTRL"},
        +{ERR_FUNC(UBSEC_F_UBSEC_DH_COMPUTE_KEY),	"UBSEC_DH_COMPUTE_KEY"},
        +{ERR_FUNC(UBSEC_F_UBSEC_DH_GENERATE_KEY),	"UBSEC_DH_GENERATE_KEY"},
        +{ERR_FUNC(UBSEC_F_UBSEC_DSA_DO_SIGN),	"UBSEC_DSA_DO_SIGN"},
        +{ERR_FUNC(UBSEC_F_UBSEC_DSA_VERIFY),	"UBSEC_DSA_VERIFY"},
        +{ERR_FUNC(UBSEC_F_UBSEC_FINISH),	"UBSEC_FINISH"},
        +{ERR_FUNC(UBSEC_F_UBSEC_INIT),	"UBSEC_INIT"},
        +{ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP),	"UBSEC_MOD_EXP"},
        +{ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP_CRT),	"UBSEC_MOD_EXP_CRT"},
        +{ERR_FUNC(UBSEC_F_UBSEC_RAND_BYTES),	"UBSEC_RAND_BYTES"},
        +{ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP),	"UBSEC_RSA_MOD_EXP"},
        +{ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT),	"UBSEC_RSA_MOD_EXP_CRT"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA UBSEC_str_reasons[]=
        +	{
        +{ERR_REASON(UBSEC_R_ALREADY_LOADED)      ,"already loaded"},
        +{ERR_REASON(UBSEC_R_BN_EXPAND_FAIL)      ,"bn expand fail"},
        +{ERR_REASON(UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
        +{ERR_REASON(UBSEC_R_DSO_FAILURE)         ,"dso failure"},
        +{ERR_REASON(UBSEC_R_MISSING_KEY_COMPONENTS),"missing key components"},
        +{ERR_REASON(UBSEC_R_NOT_LOADED)          ,"not loaded"},
        +{ERR_REASON(UBSEC_R_REQUEST_FAILED)      ,"request failed"},
        +{ERR_REASON(UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
        +{ERR_REASON(UBSEC_R_UNIT_FAILURE)        ,"unit failure"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef UBSEC_LIB_NAME
        +static ERR_STRING_DATA UBSEC_lib_name[]=
        +        {
        +{0	,UBSEC_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int UBSEC_lib_error_code=0;
        +static int UBSEC_error_init=1;
        +
        +static void ERR_load_UBSEC_strings(void)
        +	{
        +	if (UBSEC_lib_error_code == 0)
        +		UBSEC_lib_error_code=ERR_get_next_error_library();
        +
        +	if (UBSEC_error_init)
        +		{
        +		UBSEC_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_functs);
        +		ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
        +#endif
        +
        +#ifdef UBSEC_LIB_NAME
        +		UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code,0,0);
        +		ERR_load_strings(0,UBSEC_lib_name);
        +#endif
        +		}
        +	}
        +
        +static void ERR_unload_UBSEC_strings(void)
        +	{
        +	if (UBSEC_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_functs);
        +		ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
        +#endif
        +
        +#ifdef UBSEC_LIB_NAME
        +		ERR_unload_strings(0,UBSEC_lib_name);
        +#endif
        +		UBSEC_error_init=1;
        +		}
        +	}
        +
        +static void ERR_UBSEC_error(int function, int reason, char *file, int line)
        +	{
        +	if (UBSEC_lib_error_code == 0)
        +		UBSEC_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(UBSEC_lib_error_code,function,reason,file,line);
        +	}
        diff --git a/vendor/openssl/openssl/engines/e_ubsec_err.h b/vendor/openssl/openssl/engines/e_ubsec_err.h
        new file mode 100644
        index 000000000..b10b2387f
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/e_ubsec_err.h
        @@ -0,0 +1,101 @@
        +/* ====================================================================
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#ifndef HEADER_UBSEC_ERR_H
        +#define HEADER_UBSEC_ERR_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +static void ERR_load_UBSEC_strings(void);
        +static void ERR_unload_UBSEC_strings(void);
        +static void ERR_UBSEC_error(int function, int reason, char *file, int line);
        +#define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__)
        +
        +/* Error codes for the UBSEC functions. */
        +
        +/* Function codes. */
        +#define UBSEC_F_UBSEC_CTRL				 100
        +#define UBSEC_F_UBSEC_DH_COMPUTE_KEY			 101
        +#define UBSEC_F_UBSEC_DH_GENERATE_KEY			 111
        +#define UBSEC_F_UBSEC_DSA_DO_SIGN			 102
        +#define UBSEC_F_UBSEC_DSA_VERIFY			 103
        +#define UBSEC_F_UBSEC_FINISH				 104
        +#define UBSEC_F_UBSEC_INIT				 105
        +#define UBSEC_F_UBSEC_MOD_EXP				 106
        +#define UBSEC_F_UBSEC_MOD_EXP_CRT			 110
        +#define UBSEC_F_UBSEC_RAND_BYTES			 107
        +#define UBSEC_F_UBSEC_RSA_MOD_EXP			 108
        +#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT			 109
        +
        +/* Reason codes. */
        +#define UBSEC_R_ALREADY_LOADED				 100
        +#define UBSEC_R_BN_EXPAND_FAIL				 101
        +#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED		 102
        +#define UBSEC_R_DSO_FAILURE				 103
        +#define UBSEC_R_MISSING_KEY_COMPONENTS			 104
        +#define UBSEC_R_NOT_LOADED				 105
        +#define UBSEC_R_REQUEST_FAILED				 106
        +#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL		 107
        +#define UBSEC_R_UNIT_FAILURE				 108
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/engines/engine_vector.mar b/vendor/openssl/openssl/engines/engine_vector.mar
        new file mode 100644
        index 000000000..7d968e7b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/engine_vector.mar
        @@ -0,0 +1,24 @@
        +;
        +; Transfer vector for VAX shareable image
        +;
        +	.TITLE ENGINE
        +	.IDENT /ENGINE/
        +;
        +; Define macro to assist in building transfer vector entries.  Each entry
        +; should take no more than 8 bytes.
        +;
        +	.MACRO FTRANSFER_ENTRY routine
        +	.ALIGN QUAD
        +	.TRANSFER routine
        +	.MASK	routine
        +	JMP	routine+2
        +	.ENDM FTRANSFER_ENTRY
        +;
        +; Place entries in own program section.
        +;
        +	.PSECT $$ENGINE,QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT
        +ENGINE_xfer:
        +	FTRANSFER_ENTRY bind_engine
        +	FTRANSFER_ENTRY v_check
        +	.BLKB 32768-<.-ENGINE_xfer>	; 64 pages total.
        +	.END
        diff --git a/vendor/openssl/openssl/engines/ia64.opt b/vendor/openssl/openssl/engines/ia64.opt
        new file mode 100644
        index 000000000..1dc71bf4b
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/ia64.opt
        @@ -0,0 +1 @@
        +SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE)
        diff --git a/vendor/openssl/openssl/engines/makeengines.com b/vendor/openssl/openssl/engines/makeengines.com
        new file mode 100644
        index 000000000..6329fbbf0
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/makeengines.com
        @@ -0,0 +1,1125 @@
        +$!
        +$!  MAKEENGINES.COM
        +$!  Written By:  Richard Levitte
        +$!               richard@levitte.org
        +$!
        +$!  This command file compiles and creates the various engines in form
        +$!  of shared images.  They are placed in [.xxx.EXE.ENGINES], where "xxx"
        +$!  is ALPHA, IA64 or VAX, depending on your hardware.
        +$!
        +$!  P1	if this is ENGINES or ALL, the engines will build, otherwise not.
        +$!
        +$!  P2	DEBUG or NODEBUG to compile with or without debugger information.
        +$!
        +$!  P3  VAXC		for VAX C
        +$!	DECC		for DEC C
        +$!	GNUC		for GNU C (untested)
        +$!
        +$!  P4	if defined, sets the TCP/IP libraries to use.  UCX or TCPIP is
        +$!	used by default since most other implementations come with a
        +$!	compatibility library.  The value must be one of the following:
        +$!
        +$!	UCX		for UCX
        +$!	SOCKETSHR	for SOCKETSHR+NETLIB
        +$!	TCPIP		for TCPIP (post UCX)
        +$!
        +$!  P5	if defined, tells the compiler not to use special threads.
        +$!
        +$!  P6	if defined, denotes which engines to build.  If not defined,
        +$!	all available engines are built.
        +$!
        +$!  P7, if defined, specifies the C pointer size.  Ignored on VAX.
        +$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
        +$!      Supported values are:
        +$!
        +$!	""	Compile with default (/NOPOINTER_SIZE)
        +$!	32	Compile with /POINTER_SIZE=32 (SHORT)
        +$!	64	Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
        +$!               (Automatically select ARGV if compiler supports it.)
        +$!      64=      Compile with /POINTER_SIZE=64 (LONG).
        +$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
        +$!
        +$!  P8, if defined, specifies a directory where ZLIB files (zlib.h,
        +$!  libz.olb) may be found.  Optionally, a non-default object library
        +$!  name may be included ("dev:[dir]libz_64.olb", for example).
        +$!
        +$!-----------------------------------------------------------------------------
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ on control_c then goto exit
        +$!
        +$! Set the default TCP/IP library to link against if needed
        +$!
        +$ TCPIP_LIB = ""
        +$ ZLIB_LIB = ""
        +$!
        +$! Check What Architecture We Are Using.
        +$!
        +$ IF (F$GETSYI("CPU").LT.128)
        +$ THEN
        +$!
        +$!  The Architecture Is VAX.
        +$!
        +$   ARCH = "VAX"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
        +$!
        +$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
        +$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
        +$!
        +$! End The Architecture Check.
        +$!
        +$ ENDIF
        +$!
        +$ ARCHD = ARCH
        +$ LIB32 = "32"
        +$ OPT_FILE = ""
        +$ POINTER_SIZE = ""
        +$!
        +$! Set the names of the engines we want to build
        +$! NOTE: Some might think this list ugly.  However, it's made this way to
        +$! reflect the LIBNAMES variable in Makefile as closely as possible,
        +$! thereby making it fairly easy to verify that the lists are the same.
        +$! NOTE: gmp isn't built, as it's mostly a test engine and brings in another
        +$! library that isn't necessarely ported to VMS.
        +$!
        +$ ENGINES = "," + P6
        +$ IF ENGINES .EQS. "," THEN -
        +	ENGINES = ",4758cca,aep,atalla,cswift,chil,nuron,sureware,ubsec,padlock,"
        +$!
        +$! GOST requires a 64-bit integer type, unavailable on VAX.
        +$!
        +$ IF (ARCH .NES. "VAX") THEN -
        +       ENGINES = ENGINES+ ",ccgost"
        +$!
        +$! Check options.
        +$!
        +$ OPT_PHASE = P1
        +$ ACCEPT_PHASE = "ALL,ENGINES"
        +$ OPT_DEBUG = P2
        +$ OPT_COMPILER = P3
        +$ OPT_TCPIP_LIB = P4
        +$ OPT_SPECIAL_THREADS = P5
        +$ OPT_POINTER_SIZE = P7
        +$ ZLIB = P8
        +$
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Set the goal directories, and create them if necessary
        +$!
        +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.ENGINES]
        +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.ENGINES]
        +$ IF F$PARSE(OBJ_DIR) .EQS. "" THEN CREATE/DIRECTORY 'OBJ_DIR'
        +$ IF F$PARSE(EXE_DIR) .EQS. "" THEN CREATE/DIRECTORY 'EXE_DIR'
        +$!
        +$! Set the goal files, and create them if necessary
        +$!
        +$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
        +$ IF F$SEARCH(CRYPTO_LIB) .EQS. "" THEN LIBRARY/CREATE/OBJECT 'CRYPTO_LIB'
        +$!
        +$! Specify the destination directory in any /MAP option.
        +$!
        +$ if (LINKMAP .eqs. "MAP")
        +$ then
        +$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
        +$ endif
        +$!
        +$! Add the location prefix to the linker options file name.
        +$!
        +$ if (OPT_FILE .nes. "")
        +$ then
        +$   OPT_FILE = EXE_DIR+ OPT_FILE
        +$ endif
        +$!
        +$! Initialise.
        +$!
        +$ GOSUB INITIALISE
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Define what goes into each engine.  VAX includes a transfer vector.
        +$!
        +$ ENGINE_ = ""
        +$ TV_OBJ = ""
        +$ IF ARCH .EQS. "VAX"
        +$ THEN
        +$   ENGINE_ = "engine_vector.mar"
        +$   TV_OBJ_NAME = OBJ_DIR + F$PARSE(ENGINE_,,,"NAME","SYNTAX_ONLY") + ".OBJ"
        +$   TV_OBJ = ",''TV_OBJ_NAME'"
        +$ ENDIF
        +$ ENGINE_4758CCA = "e_4758cca"
        +$ ENGINE_aep = "e_aep"
        +$ ENGINE_atalla = "e_atalla"
        +$ ENGINE_cswift = "e_cswift"
        +$ ENGINE_chil = "e_chil"
        +$ ENGINE_nuron = "e_nuron"
        +$ ENGINE_sureware = "e_sureware"
        +$ ENGINE_ubsec = "e_ubsec"
        +$ ENGINE_padlock = "e_padlock"
        +$
        +$ ENGINE_ccgost_SUBDIR = "ccgost"
        +$ ENGINE_ccgost = "e_gost_err,gost2001_keyx,gost2001,gost89,gost94_keyx,"+ -
        +		  "gost_ameth,gost_asn1,gost_crypt,gost_ctl,gost_eng,"+ -
        +		  "gosthash,gost_keywrap,gost_md,gost_params,gost_pmeth,"+ -
        +		  "gost_sign"
        +$!
        +$! Define which programs need to be linked with a TCP/IP library
        +$!
        +$ TCPIP_ENGINES = ",,"
        +$ IF COMPILER .EQS. "VAXC" THEN -
        +     TCPIP_ENGINES = ",,"
        +$!
        +$! Set up two loops, one that keeps track of the engines,
        +$! and one that keeps track of all the files going into
        +$! the current engine.
        +$!
        +$! Here's the start of the engine loop.
        +$!
        +$ ENGINE_COUNTER = 0
        +$ ENGINE_NEXT:
        +$!
        +$! Extract the current engine name, and if we've reached the end, stop
        +$!
        +$ ENGINE_NAME = F$ELEMENT(ENGINE_COUNTER,",",ENGINES)
        +$ IF (ENGINE_NAME.EQS.",") THEN GOTO ENGINE_DONE
        +$!
        +$ ENGINE_COUNTER = ENGINE_COUNTER + 1
        +$!
        +$! Set up the engine library names.
        +$!
        +$ LIB_ENGINE = "ENGINE_" + ENGINE_NAME
        +$!
        +$! Check if the library module name actually is defined
        +$!
        +$ IF F$TYPE('LIB_ENGINE') .EQS. ""
        +$ THEN
        +$   WRITE SYS$ERROR ""
        +$   WRITE SYS$ERROR "The module ",ENGINE_NAME," does not exist.  Continuing..."
        +$   WRITE SYS$ERROR ""
        +$   GOTO ENGINE_NEXT
        +$ ENDIF
        +$!
        +$! Talk to the user
        +$!
        +$ IF ENGINE_NAME .NES. ""
        +$ THEN
        +$   WRITE SYS$OUTPUT "Compiling The ",ENGINE_NAME," Library Files. (",BUILDALL,")"
        +$ ELSE
        +$   WRITE SYS$OUTPUT "Compiling Support Files. (",BUILDALL,")"
        +$ ENDIF
        +$!
        +$! Create a .OPT file for the object files (for a real engine name).
        +$!
        +$ IF ENGINE_NAME .NES. ""
        +$ THEN
        +$   OPEN /WRITE OBJECTS 'EXE_DIR''ENGINE_NAME'.OPT
        +$ ENDIF
        +$!
        +$! Here's the start of per-engine module loop.
        +$!
        +$ FILE_COUNTER = 0
        +$ FILE_NEXT:
        +$!
        +$! Extract the file name from the file list, and if we've reached the end, stop
        +$!
        +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_ENGINE')
        +$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
        +$!
        +$ FILE_COUNTER = FILE_COUNTER + 1
        +$!
        +$ IF FILE_NAME .EQS. "" THEN GOTO FILE_NEXT
        +$!
        +$! Set up the source and object reference
        +$!
        +$ IF F$TYPE('LIB_ENGINE'_SUBDIR) .EQS. ""
        +$ THEN
        +$     SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[].C",,,"SYNTAX_ONLY")
        +$ ELSE
        +$     SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[."+'LIB_ENGINE'_SUBDIR+"].C",,,"SYNTAX_ONLY")
        +$ ENDIF
        +$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
        +$!
        +$! If we get some problem, we just go on trying to build the next module.
        +$ ON WARNING THEN GOTO FILE_NEXT
        +$!
        +$! Check if the module we want to compile is actually there.
        +$!
        +$ IF F$SEARCH(SOURCE_FILE) .EQS. ""
        +$ THEN
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$   GOTO EXIT
        +$ ENDIF
        +$!
        +$! Talk to the user.
        +$!
        +$ WRITE SYS$OUTPUT "	",FILE_NAME,""
        +$!
        +$! Do the dirty work.
        +$!
        +$ ON ERROR THEN GOTO FILE_NEXT
        +$ IF F$EDIT(F$PARSE(SOURCE_FILE,,,"TYPE","SYNTAX_ONLY"),"UPCASE") .EQS. ".MAR"
        +$ THEN
        +$   MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$ ELSE
        +$   CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$ ENDIF
        +$!
        +$! Write the entry to the .OPT file (for a real engine name).
        +$!
        +$ IF ENGINE_NAME .NES. ""
        +$ THEN
        +$   WRITE OBJECTS OBJECT_FILE
        +$ ENDIF
        +$!
        +$! Next file
        +$!
        +$ GOTO FILE_NEXT
        +$!
        +$ FILE_DONE:
        +$!
        +$! Do not link the support files.
        +$!
        +$ IF ENGINE_NAME .EQS. "" THEN GOTO ENGINE_NEXT
        +$!
        +$! Close the linker options file (for a real engine name).
        +$!
        +$ CLOSE OBJECTS
        +$!
        +$! Now, there are two ways to handle this.  We can either build 
        +$! shareable images or stick the engine object file into libcrypto.
        +$! For now, the latter is NOT supported.
        +$!
        +$!!!!! LIBRARY/REPLACE 'CRYPTO_LIB' 'OBJECT_FILE'
        +$!
        +$! For shareable libraries, we need to do things a little differently
        +$! depending on if we link with a TCP/IP library or not.
        +$!
        +$ ENGINE_OPT := SYS$DISK:[]'ARCH'.OPT
        +$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
        +   'EXE_DIR''ENGINE_NAME'.OPT /OPTIONS -
        +   'TV_OBJ', -
        +   'CRYPTO_LIB' /LIBRARY, -
        +   'ENGINE_OPT' /OPTIONS -
        +   'TCPIP_LIB' -
        +   'ZLIB_LIB' -
        +   ,'OPT_FILE' /OPTIONS
        +$!
        +$! Next engine
        +$!
        +$ GOTO ENGINE_NEXT
        +$!
        +$ ENGINE_DONE:
        +$!
        +$! Talk to the user
        +$!
        +$ WRITE SYS$OUTPUT "All Done..."
        +$ EXIT:
        +$ GOSUB CLEANUP
        +$ EXIT
        +$!
        +$! Check For The Link Option FIle.
        +$!
        +$ CHECK_OPT_FILE:
        +$!
        +$! Check To See If We Need To Make A VAX C Option File.
        +$!
        +$ IF (COMPILER.EQS."VAXC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A VAX C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A VAX C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable VAX C Runtime Library.
        +!
        +SYS$SHARE:VAXCRTL.EXE/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The VAXC Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A GNU C Option File.
        +$!
        +$ IF (COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A GNU C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A GNU C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +GNU_CC:[000000]GCCLIB/LIBRARY
        +SYS$SHARE:VAXCRTL/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The GNU C Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A DEC C Option File.
        +$!
        +$ IF (COMPILER.EQS."DECC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A DEC C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
        +$!
        +$     IF ARCH .EQS. "VAX"
        +$     THEN
        +$!
        +$!      We Need A DEC C Linker Option File For VAX.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable DEC C Runtime Library.
        +!
        +SYS$SHARE:DECC$SHR.EXE/SHARE
        +$EOD
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Create The non-VAX Linker Option File.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File For non-VAX To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
        +SYS$SHARE:CMA$OPEN_RTL/SHARE
        +$EOD
        +$!
        +$!    End The DEC C Option File Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The Option File Search.
        +$!
        +$   ENDIF
        +$!
        +$! End The DEC C Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What Linker Option File We Are Using.
        +$!
        +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Check To See If OPT_PHASE Is Blank.
        +$!
        +$ IF (OPT_PHASE.EQS."ALL")
        +$ THEN
        +$!
        +$!   OPT_PHASE Is Blank, So Build Everything.
        +$!
        +$    BUILDALL = "ALL"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Else, Check To See If OPT_PHASE Has A Valid Argument.
        +$!
        +$   IF ("," + ACCEPT_PHASE + ",") - ("," + OPT_PHASE + ",") -
        +       .NES. ("," + ACCEPT_PHASE + ",")
        +$   THEN
        +$!
        +$!    A Valid Argument.
        +$!
        +$     BUILDALL = OPT_PHASE
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The option ",OPT_PHASE," is invalid.  The valid options are:"
        +$     WRITE SYS$OUTPUT ""
        +$     IF ("," + ACCEPT_PHASE + ",") - ",ALL," -
        +	.NES. ("," + ACCEPT_PHASE + ",") THEN -
        +	WRITE SYS$OUTPUT "    ALL      :  just build everything."
        +$     IF ("," + ACCEPT_PHASE + ",") - ",ENGINES," -
        +	.NES. ("," + ACCEPT_PHASE + ",") THEN -
        +	WRITE SYS$OUTPUT "    ENGINES  :  to compile just the [.xxx.EXE.ENGINES]*.EXE hareable images."
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT " where 'xxx' stands for:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha architecture."
        +$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 architecture."
        +$     WRITE SYS$OUTPUT "    VAX      :  VAX architecture."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The OPT_PHASE Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If OPT_DEBUG Is Blank.
        +$!
        +$ IF (OPT_DEBUG.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!  OPT_DEBUG Is NODEBUG, So Compile Without The Debugger Information.
        +$!
        +$   DEBUGGER = "NODEBUG"
        +$   LINKMAP = "NOMAP"
        +$   TRACEBACK = "NOTRACEBACK" 
        +$   GCC_OPTIMIZE = "OPTIMIZE"
        +$   CC_OPTIMIZE = "OPTIMIZE"
        +$   MACRO_OPTIMIZE = "OPTIMIZE"
        +$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
        +$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (OPT_DEBUG.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER = "DEBUG"
        +$     LINKMAP = "MAP"
        +$     TRACEBACK = "TRACEBACK"
        +$     GCC_OPTIMIZE = "NOOPTIMIZE"
        +$     CC_OPTIMIZE = "NOOPTIMIZE"
        +$     MACRO_OPTIMIZE = "NOOPTIMIZE"
        +$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
        +$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
        +$   ELSE 
        +$!
        +$!    They Entered An Invalid Option.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",OPT_DEBUG," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "     DEBUG   :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "     NODEBUG :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The OPT_DEBUG Check.
        +$!
        +$ ENDIF
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For OPT_SPECIAL_THREADS.
        +$!
        +$ IF (OPT_SPECIAL_THREADS.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN :=
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The OPT_SPECIAL_THREADS Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check OPT_POINTER_SIZE (P7).
        +$!
        +$ IF (OPT_POINTER_SIZE .NES. "") .AND. (ARCH .NES. "VAX")
        +$ THEN
        +$!
        +$   IF (OPT_POINTER_SIZE .EQS. "32")
        +$   THEN
        +$     POINTER_SIZE = " /POINTER_SIZE=32"
        +$   ELSE
        +$     POINTER_SIZE = F$EDIT( OPT_POINTER_SIZE, "COLLAPSE, UPCASE")
        +$     IF ((POINTER_SIZE .EQS. "64") .OR. -
        +       (POINTER_SIZE .EQS. "64=") .OR. -
        +       (POINTER_SIZE .EQS. "64=ARGV"))
        +$     THEN
        +$       ARCHD = ARCH+ "_64"
        +$       LIB32 = ""
        +$       POINTER_SIZE = " /POINTER_SIZE=64"
        +$     ELSE
        +$!
        +$!      Tell The User Entered An Invalid Option.
        +$!
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", OPT_POINTER_SIZE, -
        +         " Is Invalid.  The Valid Options Are:"
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT -
        +         "    """"       :  Compile with default (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    32       :  Compile with 32-bit (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
        +$       WRITE SYS$OUTPUT ""
        +$! 
        +$!      Time To EXIT.
        +$!
        +$       EXIT
        +$!
        +$     ENDIF
        +$!
        +$   ENDIF
        +$!
        +$! End The OPT_POINTER_SIZE Check.
        +$!
        +$ ENDIF
        +$!
        +$! Set basic C compiler /INCLUDE directories.
        +$!
        +$ CC_INCLUDES = "SYS$DISK:[],SYS$DISK:[.VENDOR_DEFNS]"
        +$!
        +$! Check To See If OPT_COMPILER Is Blank.
        +$!
        +$ IF (OPT_COMPILER.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     OPT_COMPILER = "GNUC"
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Check To See If We Have VAXC Or DECC.
        +$!
        +$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
        +$     THEN 
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       OPT_COMPILER = "DECC"
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       OPT_COMPILER = "VAXC"
        +$!
        +$!    End The VAXC Compiler Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  End The Compiler Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Have A Option For OPT_TCPIP_LIB.
        +$!
        +$ IF (OPT_TCPIP_LIB.EQS."")
        +$ THEN
        +$!
        +$!  Find out what socket library we have available
        +$!
        +$   IF F$PARSE("SOCKETSHR:") .NES. ""
        +$   THEN
        +$!
        +$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
        +$!
        +$     OPT_TCPIP_LIB = "SOCKETSHR"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
        +$!
        +$!    Else, let's look for something else
        +$!
        +$   ELSE
        +$!
        +$!    Like UCX (the reason to do this before Multinet is that the UCX
        +$!    emulation is easier to use...)
        +$!
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
        +	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
        +	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
        +$     THEN
        +$!
        +$!	Last resort: a UCX or UCX-compatible library
        +$!
        +$	OPT_TCPIP_LIB = "UCX"
        +$!
        +$!      Tell the user
        +$!
        +$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
        +$!
        +$!	That was all...
        +$!
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Set Up Initial CC Definitions, Possibly With User Ones
        +$!
        +$ CCDEFS = "TCPIP_TYPE_''OPT_TCPIP_LIB',DSO_VMS"
        +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
        +$ CCEXTRAFLAGS = ""
        +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
        +$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX"
        +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
        +	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
        +$!
        +$! Check To See If We Have A ZLIB Option.
        +$!
        +$ IF (ZLIB .NES. "")
        +$ THEN
        +$!
        +$!  Check for expected ZLIB files.
        +$!
        +$   err = 0
        +$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
        +$   if (f$search( file1) .eqs. "")
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
        +$     err = 1
        +$   endif
        +$   file1 = f$parse( "A.;", ZLIB)- "A.;"
        +$!
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     if (err .eq. 0)
        +$     then
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     endif
        +$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
        +$     WRITE SYS$OUTPUT ""
        +$     err = err+ 2
        +$   endif
        +$   if (err .eq. 1)
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$   endif
        +$!
        +$   if (err .ne. 0)
        +$   then
        +$     EXIT
        +$   endif
        +$!
        +$   CCDEFS = """ZLIB=1"", "+ CCDEFS
        +$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
        +$   ZLIB_LIB = ", ''file2' /library"
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
        +$!
        +$! End The ZLIB Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Check To See If The User Entered A Valid Parameter.
        +$!
        +$ IF (OPT_COMPILER.EQS."VAXC").OR.(OPT_COMPILER.EQS."DECC").OR.(OPT_COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!    Check To See If The User Wanted DECC.
        +$!
        +$   IF (OPT_COMPILER.EQS."DECC")
        +$   THEN
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    Use DECC...
        +$!
        +$     CC = "CC"
        +$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
        +	 THEN CC = "CC/DECC"
        +$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
        +       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
        +       " /INCLUDE=(''CC_INCLUDES') " + -
        +       CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
        +$!
        +$!  End DECC Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use VAXC.
        +$!
        +$   IF (OPT_COMPILER.EQS."VAXC")
        +$   THEN
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$!
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    Compile Using VAXC.
        +$!
        +$     CC = "CC"
        +$     IF ARCH.NES."VAX"
        +$     THEN
        +$	WRITE SYS$OUTPUT "There is no VAX C on Alpha!"
        +$	EXIT
        +$     ENDIF
        +$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
        +$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + -
        +	   CCEXTRAFLAGS
        +$     CCDEFS = """VAXC""," + CCDEFS
        +$!
        +$!    Define <sys> As SYS$COMMON:[SYSLIB]
        +$!
        +$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
        +$!
        +$!  End VAXC Check
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use GNU C.
        +$!
        +$   IF (OPT_COMPILER.EQS."GNUC")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    Use GNU C...
        +$!
        +$     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + -
        +	   CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
        +$!
        +$!  End The GNU C Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Set up default defines
        +$!
        +$   CCDEFS = """FLAT_INC=1""," + CCDEFS
        +$!
        +$!  Finish up the definition of CC.
        +$!
        +$   IF COMPILER .EQS. "DECC"
        +$   THEN
        +$     IF CCDISABLEWARNINGS .NES. ""
        +$     THEN
        +$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
        +$     ENDIF
        +$   ELSE
        +$     CCDISABLEWARNINGS = ""
        +$   ENDIF
        +$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
        +$!
        +$!  Show user the result
        +$!
        +$   WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",OPT_COMPILER," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$! End The Valid Argument Check.
        +$!
        +$ ENDIF
        +$!
        +$! Build a MACRO command for the architecture at hand
        +$!
        +$ IF ARCH .EQS. "VAX"
        +$ THEN
        +$   MACRO = "MACRO/''DEBUGGER'"
        +$ ELSE
        +$   MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
        +$ ENDIF
        +$!
        +$!  Show user the result
        +$!
        +$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
        +$!
        +$! Time to check the contents, and to make sure we get the correct library.
        +$!
        +$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR" .OR. OPT_TCPIP_LIB.EQS."MULTINET" -
        +     .OR. OPT_TCPIP_LIB.EQS."UCX" .OR. OPT_TCPIP_LIB.EQS."TCPIP" -
        +     .OR. OPT_TCPIP_LIB.EQS."NONE"
        +$ THEN
        +$!
        +$!  Check to see if SOCKETSHR was chosen
        +$!
        +$   IF OPT_TCPIP_LIB.EQS."SOCKETSHR"
        +$   THEN
        +$!
        +$!    Set the library to use SOCKETSHR
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
        +$!
        +$!    Done with SOCKETSHR
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if MULTINET was chosen
        +$!
        +$   IF OPT_TCPIP_LIB.EQS."MULTINET"
        +$   THEN
        +$!
        +$!    Set the library to use UCX emulation.
        +$!
        +$     OPT_TCPIP_LIB = "UCX"
        +$!
        +$!    Done with MULTINET
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if UCX was chosen
        +$!
        +$   IF OPT_TCPIP_LIB.EQS."UCX"
        +$   THEN
        +$!
        +$!    Set the library to use UCX.
        +$!
        +$     TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
        +$     THEN
        +$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
        +$     ELSE
        +$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
        +	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
        +$     ENDIF
        +$!
        +$!    Done with UCX
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if TCPIP was chosen
        +$!
        +$   IF OPT_TCPIP_LIB.EQS."TCPIP"
        +$   THEN
        +$!
        +$!    Set the library to use TCPIP (post UCX).
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if NONE was chosen
        +$!
        +$   IF OPT_TCPIP_LIB.EQS."NONE"
        +$   THEN
        +$!
        +$!    Do not use a TCPIP library.
        +$!
        +$     TCPIP_LIB = ""
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",OPT_TCPIP_LIB," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
        +$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
        +$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$!  Done with TCP/IP libraries
        +$!
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        +$!
        +$ INITIALISE:
        +$!
        +$! Save old value of the logical name OPENSSL
        +$!
        +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
        +$!
        +$! Save directory information
        +$!
        +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
        +$ __HERE = F$EDIT(__HERE,"UPCASE")
        +$ __TOP = __HERE - "ENGINES]"
        +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
        +$!
        +$! Set up the logical name OPENSSL to point at the include directory
        +$!
        +$ DEFINE OPENSSL /NOLOG '__INCLUDE'
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        +$ CLEANUP:
        +$!
        +$! Restore the saved logical name OPENSSL, if it had a value.
        +$!
        +$ if (f$type( __SAVE_OPENSSL) .nes. "")
        +$ then
        +$   IF __SAVE_OPENSSL .EQS. ""
        +$   THEN
        +$     DEASSIGN OPENSSL
        +$   ELSE
        +$     DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
        +$   ENDIF
        +$ endif
        +$!
        +$! Close any open files.
        +$!
        +$ if (f$trnlnm( "objects", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close objects
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        diff --git a/vendor/openssl/openssl/engines/vax.opt b/vendor/openssl/openssl/engines/vax.opt
        new file mode 100644
        index 000000000..72e6bd895
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vax.opt
        @@ -0,0 +1,9 @@
        +!
        +! Ensure transfer vector is at beginning of image
        +!
        +CLUSTER=FIRST
        +COLLECT=FIRST,$$ENGINE
        +!
        +! make psects nonshareable so image can be installed.
        +!
        +PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/aep.h b/vendor/openssl/openssl/engines/vendor_defns/aep.h
        new file mode 100644
        index 000000000..5e9754fe4
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/aep.h
        @@ -0,0 +1,178 @@
        +/* This header declares the necessary definitions for using the exponentiation
        + * acceleration capabilities, and rnd number generation of the AEP card. 
        + *
        + */
        +
        +/*
        + *
        + * Some AEP defines
        + *
        + */
        +
        +/*Successful return value*/
        +#define AEP_R_OK                                0x00000000
        +
        +/*Miscelleanous unsuccessful return value*/
        +#define AEP_R_GENERAL_ERROR                     0x10000001
        +
        +/*Insufficient host memory*/
        +#define AEP_R_HOST_MEMORY                       0x10000002
        +
        +#define AEP_R_FUNCTION_FAILED                   0x10000006
        +
        +/*Invalid arguments in function call*/
        +#define AEP_R_ARGUMENTS_BAD                     0x10020000
        +
        +#define AEP_R_NO_TARGET_RESOURCES				0x10030000
        +
        +/*Error occuring on socket operation*/
        +#define AEP_R_SOCKERROR							0x10000010
        +
        +/*Socket has been closed from the other end*/
        +#define AEP_R_SOCKEOF							0x10000011
        +
        +/*Invalid handles*/
        +#define AEP_R_CONNECTION_HANDLE_INVALID         0x100000B3
        +
        +#define AEP_R_TRANSACTION_HANDLE_INVALID		0x10040000
        +
        +/*Transaction has not yet returned from accelerator*/
        +#define AEP_R_TRANSACTION_NOT_READY				0x00010000
        +
        +/*There is already a thread waiting on this transaction*/
        +#define AEP_R_TRANSACTION_CLAIMED				0x10050000
        +
        +/*The transaction timed out*/
        +#define AEP_R_TIMED_OUT							0x10060000
        +
        +#define AEP_R_FXN_NOT_IMPLEMENTED				0x10070000
        +
        +#define AEP_R_TARGET_ERROR						0x10080000
        +
        +/*Error in the AEP daemon process*/
        +#define AEP_R_DAEMON_ERROR						0x10090000
        +
        +/*Invalid ctx id*/
        +#define AEP_R_INVALID_CTX_ID					0x10009000
        +
        +#define AEP_R_NO_KEY_MANAGER					0x1000a000
        +
        +/*Error obtaining a mutex*/
        +#define AEP_R_MUTEX_BAD                         0x000001A0
        +
        +/*Fxn call before AEP_Initialise ot after AEP_Finialise*/
        +#define AEP_R_AEPAPI_NOT_INITIALIZED			0x10000190
        +
        +/*AEP_Initialise has already been called*/
        +#define AEP_R_AEPAPI_ALREADY_INITIALIZED		0x10000191
        +
        +/*Maximum number of connections to daemon reached*/
        +#define AEP_R_NO_MORE_CONNECTION_HNDLS			0x10000200
        +
        +/*
        + *
        + * Some AEP Type definitions
        + *
        + */
        +
        +/* an unsigned 8-bit value */
        +typedef unsigned char				AEP_U8;
        +
        +/* an unsigned 8-bit character */
        +typedef char					AEP_CHAR;
        +
        +/* a BYTE-sized Boolean flag */
        +typedef AEP_U8					AEP_BBOOL;
        +
        +/*Unsigned value, at least 16 bits long*/
        +typedef unsigned short				AEP_U16;
        +
        +/* an unsigned value, at least 32 bits long */
        +#ifdef SIXTY_FOUR_BIT_LONG
        +typedef unsigned int				AEP_U32;
        +#else
        +typedef unsigned long				AEP_U32;
        +#endif
        +
        +#ifdef SIXTY_FOUR_BIT_LONG
        +typedef unsigned long				AEP_U64;
        +#else
        +typedef struct { unsigned long l1, l2; }	AEP_U64;
        +#endif
        +
        +/* at least 32 bits; each bit is a Boolean flag */
        +typedef AEP_U32			AEP_FLAGS;
        +
        +typedef AEP_U8	    	*AEP_U8_PTR;
        +typedef AEP_CHAR    	*AEP_CHAR_PTR;
        +typedef AEP_U32			*AEP_U32_PTR;
        +typedef AEP_U64			*AEP_U64_PTR;
        +typedef void        	*AEP_VOID_PTR;
        +
        +/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */
        +typedef AEP_VOID_PTR 	*AEP_VOID_PTR_PTR;
        +
        +/*Used to identify an AEP connection handle*/
        +typedef AEP_U32					AEP_CONNECTION_HNDL;
        +
        +/*Pointer to an AEP connection handle*/
        +typedef AEP_CONNECTION_HNDL 	*AEP_CONNECTION_HNDL_PTR;
        +
        +/*Used by an application (in conjunction with the apps process id) to 
        +identify an individual transaction*/
        +typedef AEP_U32					AEP_TRANSACTION_ID;
        +
        +/*Pointer to an applications transaction identifier*/
        +typedef AEP_TRANSACTION_ID 		*AEP_TRANSACTION_ID_PTR;
        +
        +/*Return value type*/
        +typedef AEP_U32					AEP_RV;
        +
        +#define MAX_PROCESS_CONNECTIONS 256
        +
        +#define RAND_BLK_SIZE 1024
        +
        +typedef enum{
        +        NotConnected=   0,
        +        Connected=              1,
        +        InUse=                  2
        +} AEP_CONNECTION_STATE;
        +
        +
        +typedef struct AEP_CONNECTION_ENTRY{
        +        AEP_CONNECTION_STATE    conn_state;
        +        AEP_CONNECTION_HNDL     conn_hndl;
        +} AEP_CONNECTION_ENTRY;
        +
        +
        +typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection);
        +typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection);
        +
        +typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection,
        +			    AEP_VOID_PTR pA, AEP_VOID_PTR pP,
        +			    AEP_VOID_PTR pN,
        +			    AEP_VOID_PTR pResult,
        +			    AEP_TRANSACTION_ID* pidTransID);
        +
        +typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection,
        +			       AEP_VOID_PTR pA, AEP_VOID_PTR pP,
        +			       AEP_VOID_PTR pQ,
        +			       AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1,
        +			       AEP_VOID_PTR pIqmp,
        +			       AEP_VOID_PTR pResult,
        +			       AEP_TRANSACTION_ID* pidTransID);
        +
        +#ifdef AEPRAND
        +typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection,
        +			       AEP_U32 Len,
        +			       AEP_U32 Type,
        +			       AEP_VOID_PTR pResult,
        +			       AEP_TRANSACTION_ID* pidTransID);
        +#endif
        +
        +typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs);
        +typedef AEP_RV t_AEP_Finalize(void);
        +typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize),
        +				    AEP_RV (*MakeAEPBigNumFunc)(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum),
        +				    AEP_RV (*ConverAEPBigNumFunc)(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum));
        +
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/atalla.h b/vendor/openssl/openssl/engines/vendor_defns/atalla.h
        new file mode 100644
        index 000000000..149970d44
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/atalla.h
        @@ -0,0 +1,48 @@
        +/* 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);
        +
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/cswift.h b/vendor/openssl/openssl/engines/vendor_defns/cswift.h
        new file mode 100644
        index 000000000..60079326b
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/cswift.h
        @@ -0,0 +1,234 @@
        +/* 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 <sgidefs.h>
        +typedef __uint32_t        SW_U32;
        +#else
        +typedef unsigned long     SW_U32;                 /* 32 bit integer   */
        +#endif
        + 
        +#if defined(OPENSSL_SYS_WIN32)
        +  typedef struct _SW_U64 {
        +      SW_U32 low32;
        +      SW_U32 high32;
        +  } SW_U64;                                         /* 64 bit integer   */
        +#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
        +  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;               
        +
        +#if defined(OPENSSL_SYS_WIN32)
        +    #include <windows.h>
        +    typedef HANDLE          SW_OSHANDLE;          /* handle to kernel object */
        +    #define SW_OS_INVALID_HANDLE  INVALID_HANDLE_VALUE
        +    #define SW_CALLCONV _stdcall
        +#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
        +    /* async callback mechanisms */
        +    /* swiftCallbackLevel */
        +    #define SW_MAC_CALLBACK_LEVEL_NO         0		
        +    #define SW_MAC_CALLBACK_LEVEL_HARDWARE   1	/* from the hardware ISR */
        +    #define SW_MAC_CALLBACK_LEVEL_SECONDARY  2	/* as secondary ISR */
        +    typedef int             SW_MAC_CALLBACK_LEVEL;
        +    typedef int             SW_OSHANDLE;
        +    #define SW_OS_INVALID_HANDLE  (-1)
        +    #define SW_CALLCONV
        +#else /* Unix variants */
        +    typedef int             SW_OSHANDLE;          /* handle to driver */
        +    #define SW_OS_INVALID_HANDLE  (-1)
        +    #define SW_CALLCONV
        +#endif 
        +
        +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 SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
        +typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
        +                                                SW_PARAM *key_params);
        +typedef SW_STATUS SW_CALLCONV 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 SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
        +
        +#ifdef __cplusplus
        +}
        +#endif /* __cplusplus */
        +
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/hw_4758_cca.h b/vendor/openssl/openssl/engines/vendor_defns/hw_4758_cca.h
        new file mode 100644
        index 000000000..296636e81
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/hw_4758_cca.h
        @@ -0,0 +1,149 @@
        +/**********************************************************************/
        +/*                                                                    */
        +/*  Prototypes of the CCA verbs used by the 4758 CCA openssl driver   */
        +/*                                                                    */
        +/*  Maurice Gittens <maurice@gittens.nl>                              */
        +/*                                                                    */
        +/**********************************************************************/
        +
        +#ifndef __HW_4758_CCA__
        +#define __HW_4758_CCA__
        +
        +/*
        + *  Only WIN32 support for now
        + */
        +#if defined(WIN32)
        +
        +  #define CCA_LIB_NAME "CSUNSAPI"
        +
        +  #define CSNDPKX   "CSNDPKX_32"
        +  #define CSNDKRR   "CSNDKRR_32"
        +  #define CSNDPKE   "CSNDPKE_32"
        +  #define CSNDPKD   "CSNDPKD_32"
        +  #define CSNDDSV   "CSNDDSV_32"
        +  #define CSNDDSG   "CSNDDSG_32"
        +  #define CSNBRNG   "CSNBRNG_32"
        +
        +  #define SECURITYAPI __stdcall
        +#else
        +    /* Fixme!!         
        +      Find out the values of these constants for other platforms.
        +    */
        +  #define CCA_LIB_NAME "CSUNSAPI"
        +
        +  #define CSNDPKX   "CSNDPKX"
        +  #define CSNDKRR   "CSNDKRR"
        +  #define CSNDPKE   "CSNDPKE"
        +  #define CSNDPKD   "CSNDPKD"
        +  #define CSNDDSV   "CSNDDSV"
        +  #define CSNDDSG   "CSNDDSG"
        +  #define CSNBRNG   "CSNBRNG"
        +
        +  #define SECURITYAPI
        +#endif
        +
        +/*
        + * security API prototypes
        + */
        +
        +/* PKA Key Record Read */
        +typedef void (SECURITYAPI *F_KEYRECORDREAD)
        +             (long          * return_code,
        +              long          * reason_code,
        +              long          * exit_data_length,
        +              unsigned char * exit_data,
        +              long          * rule_array_count,
        +              unsigned char * rule_array,
        +              unsigned char * key_label,
        +              long          * key_token_length,
        +              unsigned char * key_token);
        +
        +/* Random Number Generate */
        +typedef void (SECURITYAPI *F_RANDOMNUMBERGENERATE)
        +             (long          * return_code,
        +              long          * reason_code,
        +              long          * exit_data_length,
        +              unsigned char * exit_data,
        +              unsigned char * form,
        +              unsigned char * random_number);
        +
        +/* Digital Signature Generate */
        +typedef void (SECURITYAPI *F_DIGITALSIGNATUREGENERATE)
        +             (long          * return_code,
        +              long          * reason_code,
        +              long          * exit_data_length,
        +              unsigned char * exit_data,
        +              long          * rule_array_count,
        +              unsigned char * rule_array,
        +              long          * PKA_private_key_id_length,
        +              unsigned char * PKA_private_key_id,
        +              long          * hash_length,
        +              unsigned char * hash,
        +              long          * signature_field_length,
        +              long          * signature_bit_length,
        +              unsigned char * signature_field);
        +
        +/* Digital Signature Verify */
        +typedef void (SECURITYAPI *F_DIGITALSIGNATUREVERIFY)(
        +              long          * return_code,
        +              long          * reason_code,
        +              long          * exit_data_length,
        +              unsigned char * exit_data,
        +              long          * rule_array_count,
        +              unsigned char * rule_array,
        +              long          * PKA_public_key_id_length,
        +              unsigned char * PKA_public_key_id,
        +              long          * hash_length,
        +              unsigned char * hash,
        +              long          * signature_field_length,
        +              unsigned char * signature_field);
        +
        +/* PKA Public Key Extract */
        +typedef void (SECURITYAPI *F_PUBLICKEYEXTRACT)(
        +              long          * return_code,
        +              long          * reason_code,
        +              long          * exit_data_length,
        +              unsigned char * exit_data,
        +              long          * rule_array_count,
        +              unsigned char * rule_array,
        +              long          * source_key_identifier_length,
        +              unsigned char * source_key_identifier,
        +              long          * target_key_token_length,
        +              unsigned char * target_key_token);
        +
        +/* PKA Encrypt */
        +typedef void   (SECURITYAPI *F_PKAENCRYPT)
        +               (long          *  return_code,
        +                 long          *  reason_code,
        +                 long          *  exit_data_length,
        +                 unsigned char *  exit_data,
        +                 long          *  rule_array_count,
        +                 unsigned char *  rule_array,
        +                 long          *  key_value_length,
        +                 unsigned char *  key_value,
        +                 long          *  data_struct_length,
        +                 unsigned char *  data_struct,
        +                 long          *  RSA_public_key_length,
        +                 unsigned char *  RSA_public_key,
        +                 long          *  RSA_encipher_length,
        +                 unsigned char *  RSA_encipher );
        +
        +/* PKA Decrypt */
        +typedef void    (SECURITYAPI *F_PKADECRYPT)
        +                (long          *  return_code,
        +                 long          *  reason_code,
        +                 long          *  exit_data_length,
        +                 unsigned char *  exit_data,
        +                 long          *  rule_array_count,
        +                 unsigned char *  rule_array,
        +                 long          *  enciphered_key_length,
        +                 unsigned char *  enciphered_key,
        +                 long          *  data_struct_length,
        +                 unsigned char *  data_struct,
        +                 long          *  RSA_private_key_length,
        +                 unsigned char *  RSA_private_key,
        +                 long          *  key_value_length,
        +                 unsigned char *  key_value    );
        +
        +
        +#endif
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/hw_ubsec.h b/vendor/openssl/openssl/engines/vendor_defns/hw_ubsec.h
        new file mode 100644
        index 000000000..b6619d40f
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/hw_ubsec.h
        @@ -0,0 +1,100 @@
        +/******************************************************************************
        + *
        + *  Copyright 2000
        + *  Broadcom Corporation
        + *  16215 Alton Parkway
        + *  PO Box 57013
        + *  Irvine CA 92619-7013
        + *
        + *****************************************************************************/
        +/* 
        + * Broadcom Corporation uBSec SDK 
        + */
        +/*
        + * Character device header file.
        + */
        +/*
        + * Revision History:
        + *
        + * October 2000 JTT Created.
        + */
        +
        +#define MAX_PUBLIC_KEY_BITS (1024)
        +#define MAX_PUBLIC_KEY_BYTES (1024/8)
        +#define SHA_BIT_SIZE  (160)
        +#define MAX_CRYPTO_KEY_LENGTH 24
        +#define MAX_MAC_KEY_LENGTH 64
        +#define UBSEC_CRYPTO_DEVICE_NAME ((unsigned char *)"/dev/ubscrypt")
        +#define UBSEC_KEY_DEVICE_NAME ((unsigned char *)"/dev/ubskey")
        +
        +/* Math command types. */
        +#define UBSEC_MATH_MODADD 0x0001
        +#define UBSEC_MATH_MODSUB 0x0002
        +#define UBSEC_MATH_MODMUL 0x0004
        +#define UBSEC_MATH_MODEXP 0x0008
        +#define UBSEC_MATH_MODREM 0x0010
        +#define UBSEC_MATH_MODINV 0x0020
        +
        +typedef long ubsec_MathCommand_t;
        +typedef long ubsec_RNGCommand_t;
        +
        +typedef struct ubsec_crypto_context_s {
        +	unsigned int	flags;
        +	unsigned char	crypto[MAX_CRYPTO_KEY_LENGTH];
        +	unsigned char 	auth[MAX_MAC_KEY_LENGTH];
        +} ubsec_crypto_context_t, *ubsec_crypto_context_p;
        +
        +/* 
        + * Predeclare the function pointer types that we dynamically load from the DSO.
        + */
        +
        +typedef int t_UBSEC_ubsec_bytes_to_bits(unsigned char *n, int bytes);
        +
        +typedef int t_UBSEC_ubsec_bits_to_bytes(int bits);
        +
        +typedef int t_UBSEC_ubsec_open(unsigned char *device);
        +
        +typedef int t_UBSEC_ubsec_close(int fd);
        +
        +typedef int t_UBSEC_diffie_hellman_generate_ioctl (int fd,
        +	unsigned char *x, int *x_len, unsigned char *y, int *y_len, 
        +	unsigned char *g, int g_len, unsigned char *m, int m_len,
        +	unsigned char *userX, int userX_len, int random_bits);
        +
        +typedef int t_UBSEC_diffie_hellman_agree_ioctl (int fd,
        +	unsigned char *x, int x_len, unsigned char *y, int y_len, 
        +	unsigned char *m, int m_len, unsigned char *k, int *k_len);
        +
        +typedef int t_UBSEC_rsa_mod_exp_ioctl (int fd,
        +	unsigned char *x, int x_len, unsigned char *m, int m_len,
        +	unsigned char *e, int e_len, unsigned char *y, int *y_len);
        +
        +typedef int t_UBSEC_rsa_mod_exp_crt_ioctl (int fd,
        +	unsigned char *x, int x_len, unsigned char *qinv, int qinv_len,
        +	unsigned char *edq, int edq_len, unsigned char *q, int q_len,
        +	unsigned char *edp, int edp_len, unsigned char *p, int p_len,
        +	unsigned char *y, int *y_len);
        +
        +typedef int t_UBSEC_dsa_sign_ioctl (int fd,
        +	int hash, unsigned char *data, int data_len, 
        +	unsigned char *rndom, int random_len, 
        +	unsigned char *p, int p_len, unsigned char *q, int q_len,
        +	unsigned char *g, int g_len, unsigned char *key, int key_len,
        +	unsigned char *r, int *r_len, unsigned char *s, int *s_len);
        +
        +typedef int t_UBSEC_dsa_verify_ioctl (int fd,
        +	int hash, unsigned char *data, int data_len,
        +	unsigned char *p, int p_len, unsigned char *q, int q_len,
        +	unsigned char *g, int g_len, unsigned char *key, int key_len,
        +	unsigned char *r, int r_len, unsigned char *s, int s_len,
        +	unsigned char *v, int *v_len);
        +
        +typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command,
        +	unsigned char *ModN, int *ModN_len, unsigned char *ExpE, int *ExpE_len, 
        +	unsigned char *ParamA, int *ParamA_len, unsigned char *ParamB, int *ParamB_len,
        +	unsigned char *Result, int *Result_len);
        +
        +typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command,
        +	unsigned char *Result, int *Result_len);
        +
        +typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len);
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/hwcryptohook.h b/vendor/openssl/openssl/engines/vendor_defns/hwcryptohook.h
        new file mode 100644
        index 000000000..482f1f2d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/hwcryptohook.h
        @@ -0,0 +1,486 @@
        +/*
        + * ModExp / RSA (with/without KM) plugin API
        + *
        + * The application will load a dynamic library which
        + * exports entrypoint(s) defined in this file.
        + *
        + * This set of entrypoints provides only a multithreaded,
        + * synchronous-within-each-thread, facility.
        + *
        + *
        + * This file is Copyright 1998-2000 nCipher Corporation Limited.
        + *
        + * Redistribution and use in source and binary forms, with opr 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
        + *
        + * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR
        + * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any
        + * damages arising directly or indirectly from this file, its use or
        + * this licence.  Without prejudice to the generality of the
        + * foregoing: all liability shall be excluded for direct, indirect,
        + * special, incidental, consequential or other damages or any loss of
        + * profits, business, revenue goodwill or anticipated savings;
        + * liability shall be excluded even if nCipher or anyone else has been
        + * advised of the possibility of damage.  In any event, if the
        + * exclusion of liability is not effective, the liability of nCipher
        + * or any author or distributor shall be limited to the lesser of the
        + * price paid and 1,000 pounds sterling. This licence only fails to
        + * exclude or limit liability for death or personal injury arising out
        + * of negligence, and only to the extent that such an exclusion or
        + * limitation is not effective.
        + *
        + * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL
        + * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not
        + * limited to, any implied warranties of merchantability, fitness for
        + * a particular purpose, satisfactory quality, and/or non-infringement
        + * of any third party rights.
        + *
        + * US Government use: This software and documentation is Commercial
        + * Computer Software and Computer Software Documentation, as defined in
        + * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in
        + * Noncommercial Computer Software and Noncommercial Computer Software
        + * Documentation."  Use, duplication or disclosure by the Government is
        + * subject to the terms and conditions specified here.
        + *
        + * By using or distributing this file you will be accepting these
        + * terms and conditions, including the limitation of liability and
        + * lack of warranty.  If you do not wish to accept these terms and
        + * conditions, DO NOT USE THE FILE.
        + *
        + *
        + * The actual dynamically loadable plugin, and the library files for
        + * static linking, which are also provided in some distributions, are
        + * not covered by the licence described above.  You should have
        + * received a separate licence with terms and conditions for these
        + * library files; if you received the library files without a licence,
        + * please contact nCipher.
        + *
        + *
        + * $Id: hwcryptohook.h,v 1.1 2002/10/11 17:10:59 levitte Exp $
        + */
        +
        +#ifndef HWCRYPTOHOOK_H
        +#define HWCRYPTOHOOK_H
        +
        +#include <sys/types.h>
        +#include <stdio.h>
        +
        +#ifndef HWCRYPTOHOOK_DECLARE_APPTYPES
        +#define HWCRYPTOHOOK_DECLARE_APPTYPES 1
        +#endif
        +
        +#define HWCRYPTOHOOK_ERROR_FAILED   -1
        +#define HWCRYPTOHOOK_ERROR_FALLBACK -2
        +#define HWCRYPTOHOOK_ERROR_MPISIZE  -3
        +
        +#if HWCRYPTOHOOK_DECLARE_APPTYPES
        +
        +/* These structs are defined by the application and opaque to the
        + * crypto plugin.  The application may define these as it sees fit.
        + * Default declarations are provided here, but the application may
        + *  #define HWCRYPTOHOOK_DECLARE_APPTYPES 0
        + * to prevent these declarations, and instead provide its own
        + * declarations of these types.  (Pointers to them must still be
        + * ordinary pointers to structs or unions, or the resulting combined
        + * program will have a type inconsistency.)
        + */
        +typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex;
        +typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar;
        +typedef struct HWCryptoHook_PassphraseContextValue HWCryptoHook_PassphraseContext;
        +typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext;
        +
        +#endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */
        +
        +/* These next two structs are opaque to the application.  The crypto
        + * plugin will return pointers to them; the caller simply manipulates
        + * the pointers.
        + */
        +typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle;
        +typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle;
        +
        +typedef struct {
        +  char *buf;
        +  size_t size;
        +} HWCryptoHook_ErrMsgBuf;
        +/* Used for error reporting.  When a HWCryptoHook function fails it
        + * will return a sentinel value (0 for pointer-valued functions, or a
        + * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for
        + * integer-valued ones).  It will, if an ErrMsgBuf is passed, also put
        + * an error message there.
        + * 
        + * size is the size of the buffer, and will not be modified.  If you
        + * pass 0 for size you must pass 0 for buf, and nothing will be
        + * recorded (just as if you passed 0 for the struct pointer).
        + * Messages written to the buffer will always be null-terminated, even
        + * when truncated to fit within size bytes.
        + *
        + * The contents of the buffer are not defined if there is no error.
        + */
        +
        +typedef struct HWCryptoHook_MPIStruct {
        +  unsigned char *buf;
        +  size_t size;
        +} HWCryptoHook_MPI;
        +/* When one of these is returned, a pointer is passed to the function.
        + * At call, size is the space available.  Afterwards it is updated to
        + * be set to the actual length (which may be more than the space available,
        + * if there was not enough room and the result was truncated).
        + * buf (the pointer) is not updated.
        + *
        + * size is in bytes and may be zero at call or return, but must be a
        + * multiple of the limb size.  Zero limbs at the MS end are not
        + * permitted.
        + */
        +
        +#define HWCryptoHook_InitFlags_FallbackModExp    0x0002UL
        +#define HWCryptoHook_InitFlags_FallbackRSAImmed  0x0004UL
        +/* Enable requesting fallback to software in case of problems with the
        + * hardware support.  This indicates to the crypto provider that the
        + * application is prepared to fall back to software operation if the
        + * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK.
        + * Without this flag those calls will never return
        + * HWCRYPTOHOOK_ERROR_FALLBACK.  The flag will also cause the crypto
        + * provider to avoid repeatedly attempting to contact dead hardware
        + * within a short interval, if appropriate.
        + */
        +
        +#define HWCryptoHook_InitFlags_SimpleForkCheck   0x0010UL
        +/* Without _SimpleForkCheck the library is allowed to assume that the
        + * application will not fork and call the library in the child(ren).
        + *
        + * When it is specified, this is allowed.  However, after a fork
        + * neither parent nor child may unload any loaded keys or call
        + * _Finish.  Instead, they should call exit (or die with a signal)
        + * without calling _Finish.  After all the children have died the
        + * parent may unload keys or call _Finish.
        + *
        + * This flag only has any effect on UN*X platforms.
        + */
        +
        +typedef struct {
        +  unsigned long flags;
        +  void *logstream; /* usually a FILE*.  See below. */
        +
        +  size_t limbsize; /* bignum format - size of radix type, must be power of 2 */
        +  int mslimbfirst; /* 0 or 1 */
        +  int msbytefirst; /* 0 or 1; -1 = native */
        +
        +  /* All the callback functions should return 0 on success, or a
        +   * nonzero integer (whose value will be visible in the error message
        +   * put in the buffer passed to the call).
        +   *
        +   * If a callback is not available pass a null function pointer.
        +   *
        +   * The callbacks may not call down again into the crypto plugin.
        +   */
        +  
        +  /* For thread-safety.  Set everything to 0 if you promise only to be
        +   * singlethreaded.  maxsimultaneous is the number of calls to
        +   * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA.  If you don't know what to
        +   * put there then say 0 and the hook library will use a default.
        +   *
        +   * maxmutexes is a small limit on the number of simultaneous mutexes
        +   * which will be requested by the library.  If there is no small
        +   * limit, set it to 0.  If the crypto plugin cannot create the
        +   * advertised number of mutexes the calls to its functions may fail.
        +   * If a low number of mutexes is advertised the plugin will try to
        +   * do the best it can.  Making larger numbers of mutexes available
        +   * may improve performance and parallelism by reducing contention
        +   * over critical sections.  Unavailability of any mutexes, implying
        +   * single-threaded operation, should be indicated by the setting
        +   * mutex_init et al to 0.
        +   */
        +  int maxmutexes;
        +  int maxsimultaneous;
        +  size_t mutexsize;
        +  int (*mutex_init)(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext *cactx);
        +  int (*mutex_acquire)(HWCryptoHook_Mutex*);
        +  void (*mutex_release)(HWCryptoHook_Mutex*);
        +  void (*mutex_destroy)(HWCryptoHook_Mutex*);
        +
        +  /* For greater efficiency, can use condition vars internally for
        +   * synchronisation.  In this case maxsimultaneous is ignored, but
        +   * the other mutex stuff must be available.  In singlethreaded
        +   * programs, set everything to 0.
        +   */
        +  size_t condvarsize;
        +  int (*condvar_init)(HWCryptoHook_CondVar*, HWCryptoHook_CallerContext *cactx);
        +  int (*condvar_wait)(HWCryptoHook_CondVar*, HWCryptoHook_Mutex*);
        +  void (*condvar_signal)(HWCryptoHook_CondVar*);
        +  void (*condvar_broadcast)(HWCryptoHook_CondVar*);
        +  void (*condvar_destroy)(HWCryptoHook_CondVar*);
        +  
        +  /* The semantics of acquiring and releasing mutexes and broadcasting
        +   * and waiting on condition variables are expected to be those from
        +   * POSIX threads (pthreads).  The mutexes may be (in pthread-speak)
        +   * fast mutexes, recursive mutexes, or nonrecursive ones.
        +   * 
        +   * The _release/_signal/_broadcast and _destroy functions must
        +   * always succeed when given a valid argument; if they are given an
        +   * invalid argument then the program (crypto plugin + application)
        +   * has an internal error, and they should abort the program.
        +   */
        +
        +  int (*getpassphrase)(const char *prompt_info,
        +                       int *len_io, char *buf,
        +                       HWCryptoHook_PassphraseContext *ppctx,
        +                       HWCryptoHook_CallerContext *cactx);
        +  /* Passphrases and the prompt_info, if they contain high-bit-set
        +   * characters, are UTF-8.  The prompt_info may be a null pointer if
        +   * no prompt information is available (it should not be an empty
        +   * string).  It will not contain text like `enter passphrase';
        +   * instead it might say something like `Operator Card for John
        +   * Smith' or `SmartCard in nFast Module #1, Slot #1'.
        +   *
        +   * buf points to a buffer in which to return the passphrase; on
        +   * entry *len_io is the length of the buffer.  It should be updated
        +   * by the callback.  The returned passphrase should not be
        +   * null-terminated by the callback.
        +   */
        +  
        +  int (*getphystoken)(const char *prompt_info,
        +                      const char *wrong_info,
        +                      HWCryptoHook_PassphraseContext *ppctx,
        +                      HWCryptoHook_CallerContext *cactx);
        +  /* Requests that the human user physically insert a different
        +   * smartcard, DataKey, etc.  The plugin should check whether the
        +   * currently inserted token(s) are appropriate, and if they are it
        +   * should not make this call.
        +   *
        +   * prompt_info is as before.  wrong_info is a description of the
        +   * currently inserted token(s) so that the user is told what
        +   * something is.  wrong_info, like prompt_info, may be null, but
        +   * should not be an empty string.  Its contents should be
        +   * syntactically similar to that of prompt_info. 
        +   */
        +  
        +  /* Note that a single LoadKey operation might cause several calls to
        +   * getpassphrase and/or requestphystoken.  If requestphystoken is
        +   * not provided (ie, a null pointer is passed) then the plugin may
        +   * not support loading keys for which authorisation by several cards
        +   * is required.  If getpassphrase is not provided then cards with
        +   * passphrases may not be supported.
        +   *
        +   * getpassphrase and getphystoken do not need to check that the
        +   * passphrase has been entered correctly or the correct token
        +   * inserted; the crypto plugin will do that.  If this is not the
        +   * case then the crypto plugin is responsible for calling these
        +   * routines again as appropriate until the correct token(s) and
        +   * passphrase(s) are supplied as required, or until any retry limits
        +   * implemented by the crypto plugin are reached.
        +   *
        +   * In either case, the application must allow the user to say `no'
        +   * or `cancel' to indicate that they do not know the passphrase or
        +   * have the appropriate token; this should cause the callback to
        +   * return nonzero indicating error.
        +   */
        +
        +  void (*logmessage)(void *logstream, const char *message);
        +  /* A log message will be generated at least every time something goes
        +   * wrong and an ErrMsgBuf is filled in (or would be if one was
        +   * provided).  Other diagnostic information may be written there too,
        +   * including more detailed reasons for errors which are reported in an
        +   * ErrMsgBuf.
        +   *
        +   * When a log message is generated, this callback is called.  It
        +   * should write a message to the relevant logging arrangements.
        +   *
        +   * The message string passed will be null-terminated and may be of arbitrary
        +   * length.  It will not be prefixed by the time and date, nor by the
        +   * name of the library that is generating it - if this is required,
        +   * the logmessage callback must do it.  The message will not have a
        +   * trailing newline (though it may contain internal newlines).
        +   *
        +   * If a null pointer is passed for logmessage a default function is
        +   * used.  The default function treats logstream as a FILE* which has
        +   * been converted to a void*.  If logstream is 0 it does nothing.
        +   * Otherwise it prepends the date and time and library name and
        +   * writes the message to logstream.  Each line will be prefixed by a
        +   * descriptive string containing the date, time and identity of the
        +   * crypto plugin.  Errors on the logstream are not reported
        +   * anywhere, and the default function doesn't flush the stream, so
        +   * the application must set the buffering how it wants it.
        +   *
        +   * The crypto plugin may also provide a facility to have copies of
        +   * log messages sent elsewhere, and or for adjusting the verbosity
        +   * of the log messages; any such facilities will be configured by
        +   * external means.
        +   */
        +
        +} HWCryptoHook_InitInfo;
        +
        +typedef
        +HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo *initinfo,
        +                                               size_t initinfosize,
        +                                               const HWCryptoHook_ErrMsgBuf *errors,
        +                                               HWCryptoHook_CallerContext *cactx);
        +extern HWCryptoHook_Init_t HWCryptoHook_Init;
        +
        +/* Caller should set initinfosize to the size of the HWCryptoHook struct,
        + * so it can be extended later.
        + *
        + * On success, a message for display or logging by the server,
        + * including the name and version number of the plugin, will be filled
        + * in into *errors; on failure *errors is used for error handling, as
        + * usual.
        + */
        +
        +/* All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED
        + * on most failures.  HWCRYPTOHOOK_ERROR_MPISIZE means at least one of
        + * the output MPI buffer(s) was too small; the sizes of all have been
        + * set to the desired size (and for those where the buffer was large
        + * enough, the value may have been copied in), and no error message
        + * has been recorded.
        + *
        + * You may pass 0 for the errors struct.  In any case, unless you set
        + * _NoStderr at init time then messages may be reported to stderr.
        + */
        +
        +/* The RSAImmed* functions (and key managed RSA) only work with
        + * modules which have an RSA patent licence - currently that means KM
        + * units; the ModExp* ones work with all modules, so you need a patent
        + * licence in the software in the US.  They are otherwise identical.
        + */
        +
        +typedef
        +void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx);
        +extern HWCryptoHook_Finish_t HWCryptoHook_Finish;
        +/* You must not have any calls going or keys loaded when you call this. */
        +
        +typedef
        +int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx,
        +                               unsigned char *buf, size_t len,
        +                               const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes;
        +
        +typedef
        +int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx,
        +                          HWCryptoHook_MPI a,
        +                          HWCryptoHook_MPI p,
        +                          HWCryptoHook_MPI n,
        +                          HWCryptoHook_MPI *r,
        +                          const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp;
        +
        +typedef
        +int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx,
        +                               HWCryptoHook_MPI m,
        +                               HWCryptoHook_MPI e,
        +                               HWCryptoHook_MPI n,
        +                               HWCryptoHook_MPI *r,
        +                               const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub;
        +
        +typedef
        +int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx,
        +                             HWCryptoHook_MPI a,
        +                             HWCryptoHook_MPI p,
        +                             HWCryptoHook_MPI q,
        +                             HWCryptoHook_MPI dmp1,
        +                             HWCryptoHook_MPI dmq1,
        +                             HWCryptoHook_MPI iqmp,
        +                             HWCryptoHook_MPI *r,
        +                             const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT;
        +
        +typedef
        +int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx,
        +                                HWCryptoHook_MPI m,
        +                                HWCryptoHook_MPI p,
        +                                HWCryptoHook_MPI q,
        +                                HWCryptoHook_MPI dmp1,
        +                                HWCryptoHook_MPI dmq1,
        +                                HWCryptoHook_MPI iqmp,
        +                                HWCryptoHook_MPI *r,
        +                                const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv;
        +
        +/* The RSAImmed* and ModExp* functions may return E_FAILED or
        + * E_FALLBACK for failure.
        + *
        + * E_FAILED means the failure is permanent and definite and there
        + *    should be no attempt to fall back to software.  (Eg, for some
        + *    applications, which support only the acceleration-only
        + *    functions, the `key material' may actually be an encoded key
        + *    identifier, and doing the operation in software would give wrong
        + *    answers.)
        + *
        + * E_FALLBACK means that doing the computation in software would seem
        + *    reasonable.  If an application pays attention to this and is
        + *    able to fall back, it should also set the Fallback init flags.
        + */
        +
        +typedef
        +int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx,
        +                              const char *key_ident,
        +                              HWCryptoHook_RSAKeyHandle *keyhandle_r,
        +                              const HWCryptoHook_ErrMsgBuf *errors,
        +                              HWCryptoHook_PassphraseContext *ppctx);
        +extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey;
        +/* The key_ident is a null-terminated string configured by the
        + * user via the application's usual configuration mechanisms.
        + * It is provided to the user by the crypto provider's key management
        + * system.  The user must be able to enter at least any string of between
        + * 1 and 1023 characters inclusive, consisting of printable 7-bit
        + * ASCII characters.  The provider should avoid using
        + * any characters except alphanumerics and the punctuation
        + * characters  _ - + . / @ ~  (the user is expected to be able
        + * to enter these without quoting).  The string may be case-sensitive.
        + * The application may allow the user to enter other NULL-terminated strings,
        + * and the provider must cope (returning an error if the string is not
        + * valid).
        + *
        + * If the key does not exist, no error is recorded and 0 is returned;
        + * keyhandle_r will be set to 0 instead of to a key handle.
        + */
        +
        +typedef
        +int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k,
        +                                   HWCryptoHook_MPI *n,
        +                                   HWCryptoHook_MPI *e,
        +                                   const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey;
        +/* The crypto plugin will not store certificates.
        + *
        + * Although this function for acquiring the public key value is
        + * provided, it is not the purpose of this API to deal fully with the
        + * handling of the public key.
        + *
        + * It is expected that the crypto supplier's key generation program
        + * will provide general facilities for producing X.509
        + * self-certificates and certificate requests in PEM format.  These
        + * will be given to the user so that they can configure them in the
        + * application, send them to CAs, or whatever.
        + *
        + * In case this kind of certificate handling is not appropriate, the
        + * crypto supplier's key generation program should be able to be
        + * configured not to generate such a self-certificate or certificate
        + * request.  Then the application will need to do all of this, and
        + * will need to store and handle the public key and certificates
        + * itself.
        + */
        +
        +typedef
        +int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k,
        +                                const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey;
        +/* Might fail due to locking problems, or other serious internal problems. */
        +
        +typedef
        +int HWCryptoHook_RSA_t(HWCryptoHook_MPI m,
        +                       HWCryptoHook_RSAKeyHandle k,
        +                       HWCryptoHook_MPI *r,
        +                       const HWCryptoHook_ErrMsgBuf *errors);
        +extern HWCryptoHook_RSA_t HWCryptoHook_RSA;
        +/* RSA private key operation (sign or decrypt) - raw, unpadded. */
        +
        +#endif /*HWCRYPTOHOOK_H*/
        diff --git a/vendor/openssl/openssl/engines/vendor_defns/sureware.h b/vendor/openssl/openssl/engines/vendor_defns/sureware.h
        new file mode 100644
        index 000000000..e46b000dd
        --- /dev/null
        +++ b/vendor/openssl/openssl/engines/vendor_defns/sureware.h
        @@ -0,0 +1,239 @@
        +/*
        +* Written by Corinne Dive-Reclus(cdive@baltimore.com)
        +*
        +* Copyright@2001 Baltimore Technologies Ltd.
        +*																								*	
        +*		THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND																			*
        +*		ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE					* 
        +*		IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE				*
        +*		ARE DISCLAIMED.  IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE						*
        +*		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL				*
        +*		DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS					*
        +*		OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)					*
        +*		HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT				*
        +*		LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY				*
        +*		OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF					*
        +*		SUCH DAMAGE.																			*
        +*
        +* 
        +*/
        +#ifdef WIN32
        +#define SW_EXPORT	__declspec ( dllexport )
        +#else
        +#define SW_EXPORT
        +#endif
        +
        +/*
        +*	List of exposed SureWare errors
        +*/
        +#define SUREWAREHOOK_ERROR_FAILED		-1
        +#define SUREWAREHOOK_ERROR_FALLBACK		-2
        +#define SUREWAREHOOK_ERROR_UNIT_FAILURE -3
        +#define SUREWAREHOOK_ERROR_DATA_SIZE -4
        +#define SUREWAREHOOK_ERROR_INVALID_PAD -5
        +/*
        +* -----------------WARNING-----------------------------------
        +* In all the following functions:
        +* msg is a string with at least 24 bytes free.
        +* A 24 bytes string will be concatenated to the existing content of msg. 
        +*/
        +/*
        +*	SureWare Initialisation function
        +*	in param threadsafe, if !=0, thread safe enabled
        +*	return SureWareHOOK_ERROR_UNIT_FAILURE if failure, 1 if success
        +*/
        +typedef int SureWareHook_Init_t(char*const msg,int threadsafe);
        +extern SW_EXPORT SureWareHook_Init_t SureWareHook_Init;
        +/*
        +*	SureWare Finish function
        +*/
        +typedef void SureWareHook_Finish_t(void);
        +extern SW_EXPORT SureWareHook_Finish_t SureWareHook_Finish;
        +/*
        +*	 PRE_CONDITION:
        +*		DO NOT CALL ANY OF THE FOLLOWING FUNCTIONS IN CASE OF INIT FAILURE
        +*/
        +/*
        +*	SureWare RAND Bytes function
        +*	In case of failure, the content of buf is unpredictable.
        +*	return 1 if success
        +*			SureWareHOOK_ERROR_FALLBACK if function not available in hardware
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
        +*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
        +*
        +*	in/out param buf : a num bytes long buffer where random bytes will be put
        +*	in param num : the number of bytes into buf
        +*/
        +typedef int SureWareHook_Rand_Bytes_t(char*const msg,unsigned char *buf, int num);
        +extern SW_EXPORT SureWareHook_Rand_Bytes_t SureWareHook_Rand_Bytes;
        +
        +/*
        +*	SureWare RAND Seed function
        +*	Adds some seed to the Hardware Random Number Generator
        +*	return 1 if success
        +*			SureWareHOOK_ERROR_FALLBACK if function not available in hardware
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
        +*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
        +*
        +*	in param buf : the seed to add into the HRNG
        +*	in param num : the number of bytes into buf
        +*/
        +typedef int SureWareHook_Rand_Seed_t(char*const msg,const void *buf, int num);
        +extern SW_EXPORT SureWareHook_Rand_Seed_t SureWareHook_Rand_Seed;
        +
        +/*
        +*	SureWare Load Private Key function
        +*	return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*	No hardware is contact for this function.
        +*
        +*	in param key_id :the name of the private protected key file without the extension
        +						".sws"
        +*	out param hptr : a pointer to a buffer allocated by SureWare_Hook
        +*	out param num: the effective key length in bytes
        +*	out param keytype: 1 if RSA 2 if DSA
        +*/
        +typedef int SureWareHook_Load_Privkey_t(char*const msg,const char *key_id,char **hptr,unsigned long *num,char *keytype);
        +extern SW_EXPORT SureWareHook_Load_Privkey_t SureWareHook_Load_Privkey;
        +
        +/*
        +*	SureWare Info Public Key function
        +*	return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*	No hardware is contact for this function.
        +*
        +*	in param key_id :the name of the private protected key file without the extension
        +						".swp"
        +*	out param hptr : a pointer to a buffer allocated by SureWare_Hook
        +*	out param num: the effective key length in bytes
        +*	out param keytype: 1 if RSA 2 if DSA
        +*/
        +typedef int SureWareHook_Info_Pubkey_t(char*const msg,const char *key_id,unsigned long *num,
        +										char *keytype);
        +extern SW_EXPORT SureWareHook_Info_Pubkey_t SureWareHook_Info_Pubkey;
        +
        +/*
        +*	SureWare Load Public Key function
        +*	return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*	No hardware is contact for this function.
        +*
        +*	in param key_id :the name of the public protected key file without the extension
        +						".swp"
        +*	in param num : the bytes size of n and e
        +*	out param n: where to write modulus in bn format
        +*	out param e: where to write exponent in bn format
        +*/
        +typedef int SureWareHook_Load_Rsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
        +										unsigned long *n, unsigned long *e);
        +extern SW_EXPORT SureWareHook_Load_Rsa_Pubkey_t SureWareHook_Load_Rsa_Pubkey;
        +
        +/*
        +*	SureWare Load DSA Public Key function
        +*	return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*	No hardware is contact for this function.
        +*
        +*	in param key_id :the name of the public protected key file without the extension
        +						".swp"
        +*	in param num : the bytes size of n and e
        +*	out param pub: where to write pub key in bn format
        +*	out param p: where to write prime in bn format
        +*	out param q: where to write sunprime (length 20 bytes) in bn format
        +*	out param g: where to write base in bn format
        +*/
        +typedef int SureWareHook_Load_Dsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
        +										unsigned long *pub, unsigned long *p,unsigned long*q,
        +										unsigned long *g);
        +extern SW_EXPORT SureWareHook_Load_Dsa_Pubkey_t SureWareHook_Load_Dsa_Pubkey;
        +
        +/*
        +*	SureWare Free function
        +*	Destroy the key into the hardware if destroy==1
        +*/
        +typedef void SureWareHook_Free_t(char *p,int destroy);
        +extern SW_EXPORT SureWareHook_Free_t SureWareHook_Free;
        +
        +#define SUREWARE_PKCS1_PAD 1
        +#define SUREWARE_ISO9796_PAD 2
        +#define SUREWARE_NO_PAD 0
        +/*
        +* SureWare RSA Private Decryption
        +* return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
        +*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
        +*
        +*	in param flen : byte size of from and to
        +*	in param from : encrypted data buffer, should be a not-null valid pointer
        +*	out param tlen: byte size of decrypted data, if error, unexpected value
        +*	out param to : decrypted data buffer, should be a not-null valid pointer
        +*   in param prsa: a protected key pointer, should be a not-null valid pointer
        +*   int padding: padding id as follow
        +*					SUREWARE_PKCS1_PAD
        +*					SUREWARE_NO_PAD
        +*
        +*/
        +typedef int SureWareHook_Rsa_Priv_Dec_t(char*const msg,int flen,unsigned char *from,
        +										int *tlen,unsigned char *to,
        +										char *prsa,int padding);
        +extern SW_EXPORT SureWareHook_Rsa_Priv_Dec_t SureWareHook_Rsa_Priv_Dec;
        +/*
        +* SureWare RSA Signature
        +* return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
        +*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
        +*
        +*	in param flen : byte size of from and to
        +*	in param from : encrypted data buffer, should be a not-null valid pointer
        +*	out param tlen: byte size of decrypted data, if error, unexpected value
        +*	out param to : decrypted data buffer, should be a not-null valid pointer
        +*   in param prsa: a protected key pointer, should be a not-null valid pointer
        +*   int padding: padding id as follow
        +*					SUREWARE_PKCS1_PAD
        +*					SUREWARE_ISO9796_PAD
        +*
        +*/
        +typedef int SureWareHook_Rsa_Sign_t(char*const msg,int flen,unsigned char *from,
        +										int *tlen,unsigned char *to,
        +										char *prsa,int padding);
        +extern SW_EXPORT SureWareHook_Rsa_Sign_t SureWareHook_Rsa_Sign;
        +/*
        +* SureWare DSA Signature
        +* return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
        +*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
        +*
        +*	in param flen : byte size of from and to
        +*	in param from : encrypted data buffer, should be a not-null valid pointer
        +*	out param to : decrypted data buffer, should be a 40bytes valid pointer
        +*   in param pdsa: a protected key pointer, should be a not-null valid pointer
        +*
        +*/
        +typedef int SureWareHook_Dsa_Sign_t(char*const msg,int flen,const unsigned char *from,
        +										unsigned long *r,unsigned long *s,char *pdsa);
        +extern SW_EXPORT SureWareHook_Dsa_Sign_t SureWareHook_Dsa_Sign;
        +
        +
        +/*
        +* SureWare Mod Exp
        +* return 1 if success
        +*			SureWareHOOK_ERROR_FAILED if error while processing
        +*			SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
        +*			SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
        +*
        +*	mod and res are mlen bytes long.
        +*	exp is elen bytes long
        +*	data is dlen bytes long
        +*	mlen,elen and dlen are all multiple of sizeof(unsigned long)
        +*/
        +typedef int SureWareHook_Mod_Exp_t(char*const msg,int mlen,const unsigned long *mod,
        +									int elen,const unsigned long *exponent,
        +									int dlen,unsigned long *data,
        +									unsigned long *res);
        +extern SW_EXPORT SureWareHook_Mod_Exp_t SureWareHook_Mod_Exp;
        +
        diff --git a/vendor/openssl/openssl/include/openssl/aes.h b/vendor/openssl/openssl/include/openssl/aes.h
        new file mode 100644
        index 000000000..f646d41f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/aes.h
        @@ -0,0 +1 @@
        +#include "../../crypto/aes/aes.h"
        diff --git a/vendor/openssl/openssl/include/openssl/asn1.h b/vendor/openssl/openssl/include/openssl/asn1.h
        new file mode 100644
        index 000000000..5432ed8dc
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/asn1.h
        @@ -0,0 +1 @@
        +#include "../../crypto/asn1/asn1.h"
        diff --git a/vendor/openssl/openssl/include/openssl/asn1_mac.h b/vendor/openssl/openssl/include/openssl/asn1_mac.h
        new file mode 100644
        index 000000000..214787c47
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/asn1_mac.h
        @@ -0,0 +1 @@
        +#include "../../crypto/asn1/asn1_mac.h"
        diff --git a/vendor/openssl/openssl/include/openssl/asn1t.h b/vendor/openssl/openssl/include/openssl/asn1t.h
        new file mode 100644
        index 000000000..4de87a9c6
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/asn1t.h
        @@ -0,0 +1 @@
        +#include "../../crypto/asn1/asn1t.h"
        diff --git a/vendor/openssl/openssl/include/openssl/bio.h b/vendor/openssl/openssl/include/openssl/bio.h
        new file mode 100644
        index 000000000..34f8a2df0
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/bio.h
        @@ -0,0 +1 @@
        +#include "../../crypto/bio/bio.h"
        diff --git a/vendor/openssl/openssl/include/openssl/blowfish.h b/vendor/openssl/openssl/include/openssl/blowfish.h
        new file mode 100644
        index 000000000..8d515feb0
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/blowfish.h
        @@ -0,0 +1 @@
        +#include "../../crypto/bf/blowfish.h"
        diff --git a/vendor/openssl/openssl/include/openssl/bn.h b/vendor/openssl/openssl/include/openssl/bn.h
        new file mode 100644
        index 000000000..f47d65a93
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/bn.h
        @@ -0,0 +1 @@
        +#include "../../crypto/bn/bn.h"
        diff --git a/vendor/openssl/openssl/include/openssl/buffer.h b/vendor/openssl/openssl/include/openssl/buffer.h
        new file mode 100644
        index 000000000..1d2c2a2ec
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/buffer.h
        @@ -0,0 +1 @@
        +#include "../../crypto/buffer/buffer.h"
        diff --git a/vendor/openssl/openssl/include/openssl/camellia.h b/vendor/openssl/openssl/include/openssl/camellia.h
        new file mode 100644
        index 000000000..5a0a141ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/camellia.h
        @@ -0,0 +1 @@
        +#include "../../crypto/camellia/camellia.h"
        diff --git a/vendor/openssl/openssl/include/openssl/cast.h b/vendor/openssl/openssl/include/openssl/cast.h
        new file mode 100644
        index 000000000..12cf92c4a
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/cast.h
        @@ -0,0 +1 @@
        +#include "../../crypto/cast/cast.h"
        diff --git a/vendor/openssl/openssl/include/openssl/cmac.h b/vendor/openssl/openssl/include/openssl/cmac.h
        new file mode 100644
        index 000000000..a7579aeab
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/cmac.h
        @@ -0,0 +1 @@
        +#include "../../crypto/cmac/cmac.h"
        diff --git a/vendor/openssl/openssl/include/openssl/cms.h b/vendor/openssl/openssl/include/openssl/cms.h
        new file mode 100644
        index 000000000..8687c7fe4
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/cms.h
        @@ -0,0 +1 @@
        +#include "../../crypto/cms/cms.h"
        diff --git a/vendor/openssl/openssl/include/openssl/comp.h b/vendor/openssl/openssl/include/openssl/comp.h
        new file mode 100644
        index 000000000..d14e36cc3
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/comp.h
        @@ -0,0 +1 @@
        +#include "../../crypto/comp/comp.h"
        diff --git a/vendor/openssl/openssl/include/openssl/conf.h b/vendor/openssl/openssl/include/openssl/conf.h
        new file mode 100644
        index 000000000..3882c82f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/conf.h
        @@ -0,0 +1 @@
        +#include "../../crypto/conf/conf.h"
        diff --git a/vendor/openssl/openssl/include/openssl/conf_api.h b/vendor/openssl/openssl/include/openssl/conf_api.h
        new file mode 100644
        index 000000000..039335785
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/conf_api.h
        @@ -0,0 +1 @@
        +#include "../../crypto/conf/conf_api.h"
        diff --git a/vendor/openssl/openssl/include/openssl/crypto.h b/vendor/openssl/openssl/include/openssl/crypto.h
        new file mode 100644
        index 000000000..7e3d91e42
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/crypto.h
        @@ -0,0 +1 @@
        +#include "../../crypto/crypto.h"
        diff --git a/vendor/openssl/openssl/include/openssl/des.h b/vendor/openssl/openssl/include/openssl/des.h
        new file mode 100644
        index 000000000..1d6631e9b
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/des.h
        @@ -0,0 +1 @@
        +#include "../../crypto/des/des.h"
        diff --git a/vendor/openssl/openssl/include/openssl/des_old.h b/vendor/openssl/openssl/include/openssl/des_old.h
        new file mode 100644
        index 000000000..e5828733c
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/des_old.h
        @@ -0,0 +1 @@
        +#include "../../crypto/des/des_old.h"
        diff --git a/vendor/openssl/openssl/include/openssl/dh.h b/vendor/openssl/openssl/include/openssl/dh.h
        new file mode 100644
        index 000000000..f70a767ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/dh.h
        @@ -0,0 +1 @@
        +#include "../../crypto/dh/dh.h"
        diff --git a/vendor/openssl/openssl/include/openssl/dsa.h b/vendor/openssl/openssl/include/openssl/dsa.h
        new file mode 100644
        index 000000000..0365acfe6
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/dsa.h
        @@ -0,0 +1 @@
        +#include "../../crypto/dsa/dsa.h"
        diff --git a/vendor/openssl/openssl/include/openssl/dso.h b/vendor/openssl/openssl/include/openssl/dso.h
        new file mode 100644
        index 000000000..f3c8de230
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/dso.h
        @@ -0,0 +1 @@
        +#include "../../crypto/dso/dso.h"
        diff --git a/vendor/openssl/openssl/include/openssl/dtls1.h b/vendor/openssl/openssl/include/openssl/dtls1.h
        new file mode 100644
        index 000000000..ac8ab5745
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/dtls1.h
        @@ -0,0 +1 @@
        +#include "../../ssl/dtls1.h"
        diff --git a/vendor/openssl/openssl/include/openssl/e_os2.h b/vendor/openssl/openssl/include/openssl/e_os2.h
        new file mode 100644
        index 000000000..ab3f1ee44
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/e_os2.h
        @@ -0,0 +1 @@
        +#include "../../e_os2.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ebcdic.h b/vendor/openssl/openssl/include/openssl/ebcdic.h
        new file mode 100644
        index 000000000..6dedc7051
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ebcdic.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ebcdic.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ec.h b/vendor/openssl/openssl/include/openssl/ec.h
        new file mode 100644
        index 000000000..7d2061452
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ec.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ec/ec.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ecdh.h b/vendor/openssl/openssl/include/openssl/ecdh.h
        new file mode 100644
        index 000000000..ad6e3dc9c
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ecdh.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ecdh/ecdh.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ecdsa.h b/vendor/openssl/openssl/include/openssl/ecdsa.h
        new file mode 100644
        index 000000000..da4512309
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ecdsa.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ecdsa/ecdsa.h"
        diff --git a/vendor/openssl/openssl/include/openssl/engine.h b/vendor/openssl/openssl/include/openssl/engine.h
        new file mode 100644
        index 000000000..2dceaac6c
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/engine.h
        @@ -0,0 +1 @@
        +#include "../../crypto/engine/engine.h"
        diff --git a/vendor/openssl/openssl/include/openssl/err.h b/vendor/openssl/openssl/include/openssl/err.h
        new file mode 100644
        index 000000000..caf89a936
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/err.h
        @@ -0,0 +1 @@
        +#include "../../crypto/err/err.h"
        diff --git a/vendor/openssl/openssl/include/openssl/evp.h b/vendor/openssl/openssl/include/openssl/evp.h
        new file mode 100644
        index 000000000..dd7bcda8f
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/evp.h
        @@ -0,0 +1 @@
        +#include "../../crypto/evp/evp.h"
        diff --git a/vendor/openssl/openssl/include/openssl/hmac.h b/vendor/openssl/openssl/include/openssl/hmac.h
        new file mode 100644
        index 000000000..202128bf5
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/hmac.h
        @@ -0,0 +1 @@
        +#include "../../crypto/hmac/hmac.h"
        diff --git a/vendor/openssl/openssl/include/openssl/idea.h b/vendor/openssl/openssl/include/openssl/idea.h
        new file mode 100644
        index 000000000..bdf697d68
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/idea.h
        @@ -0,0 +1 @@
        +#include "../../crypto/idea/idea.h"
        diff --git a/vendor/openssl/openssl/include/openssl/krb5_asn.h b/vendor/openssl/openssl/include/openssl/krb5_asn.h
        new file mode 100644
        index 000000000..0d3feea28
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/krb5_asn.h
        @@ -0,0 +1 @@
        +#include "../../crypto/krb5/krb5_asn.h"
        diff --git a/vendor/openssl/openssl/include/openssl/kssl.h b/vendor/openssl/openssl/include/openssl/kssl.h
        new file mode 100644
        index 000000000..719634aad
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/kssl.h
        @@ -0,0 +1 @@
        +#include "../../ssl/kssl.h"
        diff --git a/vendor/openssl/openssl/include/openssl/lhash.h b/vendor/openssl/openssl/include/openssl/lhash.h
        new file mode 100644
        index 000000000..2d3db87cd
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/lhash.h
        @@ -0,0 +1 @@
        +#include "../../crypto/lhash/lhash.h"
        diff --git a/vendor/openssl/openssl/include/openssl/md2.h b/vendor/openssl/openssl/include/openssl/md2.h
        new file mode 100644
        index 000000000..4c3398cc4
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/md2.h
        @@ -0,0 +1 @@
        +#include "../../crypto/md2/md2.h"
        diff --git a/vendor/openssl/openssl/include/openssl/md4.h b/vendor/openssl/openssl/include/openssl/md4.h
        new file mode 100644
        index 000000000..611806e5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/md4.h
        @@ -0,0 +1 @@
        +#include "../../crypto/md4/md4.h"
        diff --git a/vendor/openssl/openssl/include/openssl/md5.h b/vendor/openssl/openssl/include/openssl/md5.h
        new file mode 100644
        index 000000000..aa8cd0bf8
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/md5.h
        @@ -0,0 +1 @@
        +#include "../../crypto/md5/md5.h"
        diff --git a/vendor/openssl/openssl/include/openssl/mdc2.h b/vendor/openssl/openssl/include/openssl/mdc2.h
        new file mode 100644
        index 000000000..ac284a179
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/mdc2.h
        @@ -0,0 +1 @@
        +#include "../../crypto/mdc2/mdc2.h"
        diff --git a/vendor/openssl/openssl/include/openssl/modes.h b/vendor/openssl/openssl/include/openssl/modes.h
        new file mode 100644
        index 000000000..f57fcfea8
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/modes.h
        @@ -0,0 +1 @@
        +#include "../../crypto/modes/modes.h"
        diff --git a/vendor/openssl/openssl/include/openssl/obj_mac.h b/vendor/openssl/openssl/include/openssl/obj_mac.h
        new file mode 100644
        index 000000000..3890fa9bc
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/obj_mac.h
        @@ -0,0 +1 @@
        +#include "../../crypto/objects/obj_mac.h"
        diff --git a/vendor/openssl/openssl/include/openssl/objects.h b/vendor/openssl/openssl/include/openssl/objects.h
        new file mode 100644
        index 000000000..5365a044b
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/objects.h
        @@ -0,0 +1 @@
        +#include "../../crypto/objects/objects.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ocsp.h b/vendor/openssl/openssl/include/openssl/ocsp.h
        new file mode 100644
        index 000000000..50e2885ce
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ocsp.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ocsp/ocsp.h"
        diff --git a/vendor/openssl/openssl/include/openssl/opensslconf.h b/vendor/openssl/openssl/include/openssl/opensslconf.h
        new file mode 100644
        index 000000000..221be629b
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/opensslconf.h
        @@ -0,0 +1 @@
        +#include "../../crypto/opensslconf.h"
        diff --git a/vendor/openssl/openssl/include/openssl/opensslv.h b/vendor/openssl/openssl/include/openssl/opensslv.h
        new file mode 100644
        index 000000000..c39a0c388
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/opensslv.h
        @@ -0,0 +1 @@
        +#include "../../crypto/opensslv.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ossl_typ.h b/vendor/openssl/openssl/include/openssl/ossl_typ.h
        new file mode 100644
        index 000000000..ddd7e580d
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ossl_typ.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ossl_typ.h"
        diff --git a/vendor/openssl/openssl/include/openssl/pem.h b/vendor/openssl/openssl/include/openssl/pem.h
        new file mode 100644
        index 000000000..5bcc5c59e
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/pem.h
        @@ -0,0 +1 @@
        +#include "../../crypto/pem/pem.h"
        diff --git a/vendor/openssl/openssl/include/openssl/pem2.h b/vendor/openssl/openssl/include/openssl/pem2.h
        new file mode 100644
        index 000000000..bcd3acf85
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/pem2.h
        @@ -0,0 +1 @@
        +#include "../../crypto/pem/pem2.h"
        diff --git a/vendor/openssl/openssl/include/openssl/pkcs12.h b/vendor/openssl/openssl/include/openssl/pkcs12.h
        new file mode 100644
        index 000000000..0b5fbbfe8
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/pkcs12.h
        @@ -0,0 +1 @@
        +#include "../../crypto/pkcs12/pkcs12.h"
        diff --git a/vendor/openssl/openssl/include/openssl/pkcs7.h b/vendor/openssl/openssl/include/openssl/pkcs7.h
        new file mode 100644
        index 000000000..2e19d7c4c
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/pkcs7.h
        @@ -0,0 +1 @@
        +#include "../../crypto/pkcs7/pkcs7.h"
        diff --git a/vendor/openssl/openssl/include/openssl/pqueue.h b/vendor/openssl/openssl/include/openssl/pqueue.h
        new file mode 100644
        index 000000000..9681ff52c
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/pqueue.h
        @@ -0,0 +1 @@
        +#include "../../crypto/pqueue/pqueue.h"
        diff --git a/vendor/openssl/openssl/include/openssl/rand.h b/vendor/openssl/openssl/include/openssl/rand.h
        new file mode 100644
        index 000000000..9d1521bd4
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/rand.h
        @@ -0,0 +1 @@
        +#include "../../crypto/rand/rand.h"
        diff --git a/vendor/openssl/openssl/include/openssl/rc2.h b/vendor/openssl/openssl/include/openssl/rc2.h
        new file mode 100644
        index 000000000..f2f2bd1f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/rc2.h
        @@ -0,0 +1 @@
        +#include "../../crypto/rc2/rc2.h"
        diff --git a/vendor/openssl/openssl/include/openssl/rc4.h b/vendor/openssl/openssl/include/openssl/rc4.h
        new file mode 100644
        index 000000000..306de2f40
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/rc4.h
        @@ -0,0 +1 @@
        +#include "../../crypto/rc4/rc4.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ripemd.h b/vendor/openssl/openssl/include/openssl/ripemd.h
        new file mode 100644
        index 000000000..11351fc81
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ripemd.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ripemd/ripemd.h"
        diff --git a/vendor/openssl/openssl/include/openssl/rsa.h b/vendor/openssl/openssl/include/openssl/rsa.h
        new file mode 100644
        index 000000000..975e5d355
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/rsa.h
        @@ -0,0 +1 @@
        +#include "../../crypto/rsa/rsa.h"
        diff --git a/vendor/openssl/openssl/include/openssl/safestack.h b/vendor/openssl/openssl/include/openssl/safestack.h
        new file mode 100644
        index 000000000..8a282b858
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/safestack.h
        @@ -0,0 +1 @@
        +#include "../../crypto/stack/safestack.h"
        diff --git a/vendor/openssl/openssl/include/openssl/seed.h b/vendor/openssl/openssl/include/openssl/seed.h
        new file mode 100644
        index 000000000..bbbf596df
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/seed.h
        @@ -0,0 +1 @@
        +#include "../../crypto/seed/seed.h"
        diff --git a/vendor/openssl/openssl/include/openssl/sha.h b/vendor/openssl/openssl/include/openssl/sha.h
        new file mode 100644
        index 000000000..ab9d94c38
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/sha.h
        @@ -0,0 +1 @@
        +#include "../../crypto/sha/sha.h"
        diff --git a/vendor/openssl/openssl/include/openssl/srp.h b/vendor/openssl/openssl/include/openssl/srp.h
        new file mode 100644
        index 000000000..821747677
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/srp.h
        @@ -0,0 +1 @@
        +#include "../../crypto/srp/srp.h"
        diff --git a/vendor/openssl/openssl/include/openssl/srtp.h b/vendor/openssl/openssl/include/openssl/srtp.h
        new file mode 100644
        index 000000000..e185494a5
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/srtp.h
        @@ -0,0 +1 @@
        +#include "../../ssl/srtp.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ssl.h b/vendor/openssl/openssl/include/openssl/ssl.h
        new file mode 100644
        index 000000000..0b0589c63
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ssl.h
        @@ -0,0 +1 @@
        +#include "../../ssl/ssl.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ssl2.h b/vendor/openssl/openssl/include/openssl/ssl2.h
        new file mode 100644
        index 000000000..11b22055e
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ssl2.h
        @@ -0,0 +1 @@
        +#include "../../ssl/ssl2.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ssl23.h b/vendor/openssl/openssl/include/openssl/ssl23.h
        new file mode 100644
        index 000000000..fe4dae666
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ssl23.h
        @@ -0,0 +1 @@
        +#include "../../ssl/ssl23.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ssl3.h b/vendor/openssl/openssl/include/openssl/ssl3.h
        new file mode 100644
        index 000000000..0fb66a6f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ssl3.h
        @@ -0,0 +1 @@
        +#include "../../ssl/ssl3.h"
        diff --git a/vendor/openssl/openssl/include/openssl/stack.h b/vendor/openssl/openssl/include/openssl/stack.h
        new file mode 100644
        index 000000000..295968cc1
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/stack.h
        @@ -0,0 +1 @@
        +#include "../../crypto/stack/stack.h"
        diff --git a/vendor/openssl/openssl/include/openssl/store.h b/vendor/openssl/openssl/include/openssl/store.h
        new file mode 100644
        index 000000000..84dc39fe7
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/store.h
        @@ -0,0 +1 @@
        +#include "../../crypto/store/store.h"
        diff --git a/vendor/openssl/openssl/include/openssl/symhacks.h b/vendor/openssl/openssl/include/openssl/symhacks.h
        new file mode 100644
        index 000000000..f946f4ffc
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/symhacks.h
        @@ -0,0 +1 @@
        +#include "../../crypto/symhacks.h"
        diff --git a/vendor/openssl/openssl/include/openssl/tls1.h b/vendor/openssl/openssl/include/openssl/tls1.h
        new file mode 100644
        index 000000000..c43a70ff3
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/tls1.h
        @@ -0,0 +1 @@
        +#include "../../ssl/tls1.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ts.h b/vendor/openssl/openssl/include/openssl/ts.h
        new file mode 100644
        index 000000000..fe8a2cb51
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ts.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ts/ts.h"
        diff --git a/vendor/openssl/openssl/include/openssl/txt_db.h b/vendor/openssl/openssl/include/openssl/txt_db.h
        new file mode 100644
        index 000000000..167621b6f
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/txt_db.h
        @@ -0,0 +1 @@
        +#include "../../crypto/txt_db/txt_db.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ui.h b/vendor/openssl/openssl/include/openssl/ui.h
        new file mode 100644
        index 000000000..43dd3ae83
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ui.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ui/ui.h"
        diff --git a/vendor/openssl/openssl/include/openssl/ui_compat.h b/vendor/openssl/openssl/include/openssl/ui_compat.h
        new file mode 100644
        index 000000000..c83f160d8
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/ui_compat.h
        @@ -0,0 +1 @@
        +#include "../../crypto/ui/ui_compat.h"
        diff --git a/vendor/openssl/openssl/include/openssl/whrlpool.h b/vendor/openssl/openssl/include/openssl/whrlpool.h
        new file mode 100644
        index 000000000..e2424fadd
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/whrlpool.h
        @@ -0,0 +1 @@
        +#include "../../crypto/whrlpool/whrlpool.h"
        diff --git a/vendor/openssl/openssl/include/openssl/x509.h b/vendor/openssl/openssl/include/openssl/x509.h
        new file mode 100644
        index 000000000..a4651a286
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/x509.h
        @@ -0,0 +1 @@
        +#include "../../crypto/x509/x509.h"
        diff --git a/vendor/openssl/openssl/include/openssl/x509_vfy.h b/vendor/openssl/openssl/include/openssl/x509_vfy.h
        new file mode 100644
        index 000000000..b897aa087
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/x509_vfy.h
        @@ -0,0 +1 @@
        +#include "../../crypto/x509/x509_vfy.h"
        diff --git a/vendor/openssl/openssl/include/openssl/x509v3.h b/vendor/openssl/openssl/include/openssl/x509v3.h
        new file mode 100644
        index 000000000..363795e55
        --- /dev/null
        +++ b/vendor/openssl/openssl/include/openssl/x509v3.h
        @@ -0,0 +1 @@
        +#include "../../crypto/x509v3/x509v3.h"
        diff --git a/vendor/openssl/openssl/install.com b/vendor/openssl/openssl/install.com
        new file mode 100644
        index 000000000..6a0ea2d4d
        --- /dev/null
        +++ b/vendor/openssl/openssl/install.com
        @@ -0,0 +1,136 @@
        +$! INSTALL.COM -- Installs the files in a given directory tree
        +$!
        +$! Author: Richard Levitte <richard@levitte.org>
        +$! Time of creation: 22-MAY-1998 10:13
        +$!
        +$! P1  root of the directory tree
        +$! P2  "64" for 64-bit pointers.
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ def_orig = f$environment( "default")
        +$ on error then goto tidy
        +$ on control_c then goto tidy
        +$!
        +$ if (p1 .eqs. "")
        +$ then
        +$   write sys$output "First argument missing."
        +$   write sys$output -
        +     "It should be the directory where you want things installed."
        +$   exit
        +$ endif
        +$!
        +$ if (f$getsyi("cpu") .lt. 128)
        +$ then
        +$   arch = "VAX"
        +$ else
        +$   arch = f$edit( f$getsyi( "arch_name"), "upcase")
        +$   if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$!
        +$ archd = arch
        +$!
        +$ if (p2 .nes. "")
        +$ then
        +$   if (p2 .eqs. "64")
        +$   then
        +$     archd = arch+ "_64"
        +$   else
        +$     if (p2 .nes. "32")
        +$     then
        +$       write sys$output "Second argument invalid."
        +$       write sys$output "It should be "32", "64", or nothing."
        +$       exit
        +$     endif
        +$   endif
        +$ endif
        +$!
        +$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
        +$ root_dev = f$parse( root, , , "device", "syntax_only")
        +$ root_dir = f$parse( root, , , "directory", "syntax_only") -
        +		   - ".][000000" - "[000000." - "][" - "[" - "]"
        +$ root = root_dev + "[" + root_dir
        +$!
        +$ define /nolog wrk_sslroot 'root'.] /trans=conc
        +$ define /nolog wrk_sslcerts wrk_sslroot:[certs]
        +$ define /nolog wrk_sslinclude wrk_sslroot:[include]
        +$ define /nolog wrk_ssllib wrk_sslroot:[lib]
        +$ define /nolog wrk_sslprivate wrk_sslroot:[private]
        +$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
        +$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
        +$!
        +$! Exhibit the destination directory.
        +$!
        +$ write sys$output "   Installing to (WRK_SSLROOT) ="
        +$ write sys$output "    ''f$trnlnm( "wrk_sslroot")'"
        +$ write sys$output ""
        +$!
        +$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
        +   create /directory /log wrk_sslroot:[000000]
        +$ if f$parse("wrk_sslxexe:") .eqs. "" then -
        +   create /directory /log wrk_sslxexe:
        +$ if f$parse("wrk_sslxlib:") .eqs. "" then -
        +   create /directory /log wrk_sslxlib:
        +$ if f$parse("wrk_ssllib:") .eqs. "" then -
        +   create /directory /log wrk_ssllib:
        +$ if f$parse("wrk_sslinclude:") .eqs. "" then -
        +   create /directory /log wrk_sslinclude:
        +$ if f$parse("wrk_sslcerts:") .eqs. "" then -
        +   create /directory /log wrk_sslcerts:
        +$ if f$parse("wrk_sslprivate:") .eqs. "" then -
        +   create /directory /log wrk_sslprivate:
        +$ if f$parse("wrk_sslroot:[VMS]") .EQS. "" THEN -
        +   create /directory /log wrk_sslroot:[VMS]
        +$!
        +$ sdirs := CRYPTO, SSL, APPS, VMS !!!, RSAREF, TEST, TOOLS
        +$ exheader := e_os2.h
        +$!
        +$ copy /protection = w:re 'exheader' wrk_sslinclude: /log
        +$!
        +$ i = 0
        +$ loop_sdirs: 
        +$   d = f$edit( f$element(i, ",", sdirs), "trim")
        +$   i = i + 1
        +$   if d .eqs. "," then goto loop_sdirs_end
        +$   write sys$output "Installing ", d, " files."
        +$   set default [.'d']
        +$   @ install-'d'.com 'root'] 'p2'
        +$   set default 'def_orig'
        +$ goto loop_sdirs
        +$ loop_sdirs_end:
        +$!
        +$ write sys$output ""
        +$ write sys$output "	Installation done!"
        +$ write sys$output ""
        +$ if (f$search( root+ "...]*.*;-1") .nes. "")
        +$ then
        +$   write sys$output "	You might want to purge ", root, "...]"
        +$   write sys$output ""
        +$ endif
        +$!
        +$ tidy:
        +$!
        +$ set default 'def_orig'
        +$!
        +$ call deass wrk_sslroot
        +$ call deass wrk_sslcerts
        +$ call deass wrk_sslinclude
        +$ call deass wrk_ssllib
        +$ call deass wrk_sslprivate
        +$ call deass wrk_sslxexe
        +$ call deass wrk_sslxlib
        +$!
        +$ exit
        +$!
        +$ deass: subroutine
        +$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
        +$ then
        +$   deassign /process 'p1'
        +$ endif
        +$ endsubroutine
        +$!
        diff --git a/vendor/openssl/openssl/makevms.com b/vendor/openssl/openssl/makevms.com
        new file mode 100644
        index 000000000..de1dbd905
        --- /dev/null
        +++ b/vendor/openssl/openssl/makevms.com
        @@ -0,0 +1,1543 @@
        +$!
        +$! MAKEVMS.COM
        +$! Original Author:  UNKNOWN
        +$! Rewritten By:  Robert Byer
        +$!                Vice-President
        +$!                A-Com Computing, Inc.
        +$!                byer@mail.all-net.net
        +$!
        +$! Changes by Richard Levitte <richard@levitte.org>
        +$!	      Zoltan Arpadffy <zoli@polarhome.com>
        +$!
        +$! This procedure creates the SSL libraries of "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
        +$! "[.xxx.EXE.SSL]LIBSSL.OLB"
        +$! The "xxx" denotes the machine architecture of ALPHA, IA64 or VAX.
        +$!
        +$! This procedures accepts two command line options listed below.
        +$!
        +$! P1 specifies one of the following build options:
        +$!
        +$!      ALL       Just build "everything".
        +$!      CONFIG    Just build the "[.CRYPTO._xxx]OPENSSLCONF.H" file.
        +$!      BUILDINF  Just build the "[.CRYPTO._xxx]BUILDINF.H" file.
        +$!      SOFTLINKS Just fix the Unix soft links.
        +$!      BUILDALL  Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done.
        +$!      CRYPTO    Just build the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
        +$!      CRYPTO/x  Just build the x part of the
        +$!                "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
        +$!      SSL       Just build the "[.xxx.EXE.SSL]LIBSSL.OLB" library.
        +$!      SSL_TASK  Just build the "[.xxx.EXE.SSL]SSL_TASK.EXE" program.
        +$!      TEST      Just build the "[.xxx.EXE.TEST]" test programs for OpenSSL.
        +$!      APPS      Just build the "[.xxx.EXE.APPS]" application programs for OpenSSL.
        +$!      ENGINES   Just build the "[.xxx.EXE.ENGINES]" application programs for OpenSSL.
        +$!
        +$! P2, if defined, specifies the C pointer size.  Ignored on VAX.
        +$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
        +$!      Supported values are:
        +$!
        +$!      ""       Compile with default (/NOPOINTER_SIZE).
        +$!      32       Compile with /POINTER_SIZE=32 (SHORT).
        +$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]).
        +$!               (Automatically select ARGV if compiler supports it.)
        +$!      64=      Compile with /POINTER_SIZE=64 (LONG).
        +$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
        +$!
        +$! P3 specifies DEBUG or NODEBUG, to compile with or without debugging
        +$!    information.
        +$!
        +$! P4 specifies which compiler to try to compile under.
        +$!
        +$!	  VAXC	 For VAX C.
        +$!	  DECC	 For DEC C.
        +$!	  GNUC	 For GNU C.
        +$!	  LINK   To only link the programs from existing object files.
        +$!               (not yet implemented)
        +$!
        +$! If you don't specify a compiler, it will try to determine which
        +$! "C" compiler to use.
        +$!
        +$! P5, if defined, sets a TCP/IP library to use, through one of the following
        +$! keywords:
        +$!
        +$!	UCX		for UCX or UCX emulation
        +$!	TCPIP		for TCP/IP Services or TCP/IP Services emulation
        +$!			(this is prefered over UCX)
        +$!	SOCKETSHR	for SOCKETSHR+NETLIB
        +$!	NONE		to avoid specifying which TCP/IP implementation to
        +$!			use at build time (this works with DEC C).  This is
        +$!			the default.
        +$!
        +$! P6, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up).
        +$!
        +$! P7, if defined, specifies a directory where ZLIB files (zlib.h,
        +$! libz.olb) may be found.  Optionally, a non-default object library
        +$! name may be included ("dev:[dir]libz_64.olb", for example).
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ DEF_ORIG = F$ENVIRONMENT( "DEFAULT")
        +$ ON ERROR THEN GOTO TIDY
        +$ ON CONTROL_C THEN GOTO TIDY
        +$!
        +$! Check if we're in a batch job, and make sure we get to 
        +$! the directory this script is in
        +$!
        +$ IF F$MODE() .EQS. "BATCH"
        +$ THEN
        +$   COMNAME=F$ENVIRONMENT("PROCEDURE")
        +$   COMPATH=F$PARSE("A.;",COMNAME) - "A.;"
        +$   SET DEF 'COMPATH'
        +$ ENDIF
        +$!
        +$! Check What Architecture We Are Using.
        +$!
        +$ IF (F$GETSYI("CPU").LT.128)
        +$ THEN
        +$!
        +$!  The Architecture Is VAX.
        +$!
        +$   ARCH = "VAX"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
        +$!
        +$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
        +$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
        +$!
        +$! End The Architecture Check.
        +$!
        +$ ENDIF
        +$!
        +$ ARCHD = ARCH
        +$ LIB32 = "32"
        +$ POINTER_SIZE = ""
        +$!
        +$! Get VMS version.
        +$!
        +$ VMS_VERSION = f$edit( f$getsyi( "VERSION"), "TRIM")
        +$!
        +$! Check To Make Sure We Have Valid Command Line Parameters.
        +$!
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Check To See What We Are To Do.
        +$!
        +$ IF (BUILDCOMMAND.EQS."ALL")
        +$ THEN
        +$!
        +$!  Start with building the OpenSSL configuration file.
        +$!
        +$   GOSUB CONFIG
        +$!
        +$!  Create The "BUILDINF.H" Include File.
        +$!
        +$   GOSUB BUILDINF
        +$!
        +$!  Fix The Unix Softlinks.
        +$!
        +$   GOSUB SOFTLINKS
        +$!
        +$ ENDIF
        +$!
        +$ IF (BUILDCOMMAND.EQS."ALL".OR.BUILDCOMMAND.EQS."BUILDALL")
        +$ THEN
        +$!
        +$!  Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
        +$!
        +$   GOSUB CRYPTO
        +$!
        +$!  Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
        +$!
        +$   GOSUB SSL
        +$!
        +$!  Build The [.xxx.EXE.SSL]SSL_TASK.EXE DECNet SSL Engine.
        +$!
        +$   GOSUB SSL_TASK
        +$!
        +$!  Build The [.xxx.EXE.TEST] OpenSSL Test Utilities.
        +$!
        +$   GOSUB TEST
        +$!
        +$!  Build The [.xxx.EXE.APPS] OpenSSL Application Utilities.
        +$!
        +$   GOSUB APPS
        +$!
        +$!  Build The [.xxx.EXE.ENGINES] OpenSSL Shareable Engines.
        +$!
        +$   GOSUB ENGINES
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!    Build Just What The User Wants Us To Build.
        +$!
        +$     GOSUB 'BUILDCOMMAND'
        +$!
        +$ ENDIF
        +$!
        +$! Time To EXIT.
        +$!
        +$ GOTO TIDY
        +$!
        +$! Rebuild The [.CRYPTO._xxx]OPENSSLCONF.H" file.
        +$!
        +$ CONFIG:
        +$!
        +$! Tell The User We Are Creating The [.CRYPTO._xxx]OPENSSLCONF.H File.
        +$!
        +$ WRITE SYS$OUTPUT "Creating [.CRYPTO.''ARCHD']OPENSSLCONF.H Include File."
        +$!
        +$! First, make sure the directory exists.
        +$!
        +$ IF F$PARSE("SYS$DISK:[.CRYPTO.''ARCHD']") .EQS. "" THEN -
        +     CREATE/DIRECTORY SYS$DISK:[.CRYPTO.'ARCHD']
        +$!
        +$! Different tar/UnZip versions/option may have named the file differently
        +$ IF F$SEARCH("[.crypto]opensslconf.h_in") .NES. ""
        +$ THEN
        +$   OPENSSLCONF_H_IN = "[.crypto]opensslconf.h_in"
        +$ ELSE
        +$   IF F$SEARCH( "[.crypto]opensslconf_h.in") .NES. ""
        +$   THEN
        +$     OPENSSLCONF_H_IN = "[.crypto]opensslconf_h.in"
        +$   ELSE
        +$     ! For ODS-5
        +$     IF F$SEARCH( "[.crypto]opensslconf.h.in") .NES. ""
        +$     THEN
        +$       OPENSSLCONF_H_IN = "[.crypto]opensslconf.h.in"
        +$     ELSE
        +$       WRITE SYS$ERROR "Couldn't find a [.crypto]opensslconf.h.in.  Exiting!"
        +$       $STATUS = %X00018294 ! "%RMS-F-FNF, file not found".
        +$       GOTO TIDY
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Create The [.CRYPTO._xxx]OPENSSLCONF.H File.
        +$! Make sure it has the right format.
        +$!
        +$ OSCH_NAME = "SYS$DISK:[.CRYPTO.''ARCHD']OPENSSLCONF.H"
        +$ CREATE /FDL=SYS$INPUT: 'OSCH_NAME'
        +RECORD
        +        FORMAT stream_lf
        +$ OPEN /APPEND H_FILE 'OSCH_NAME'
        +$!
        +$! Write The [.CRYPTO._xxx]OPENSSLCONF.H File.
        +$!
        +$ WRITE H_FILE "/* This file was automatically built using makevms.com */"
        +$ WRITE H_FILE "/* and ''OPENSSLCONF_H_IN' */"
        +$!
        +$! Write a few macros that indicate how this system was built.
        +$!
        +$ WRITE H_FILE ""
        +$ WRITE H_FILE "#ifndef OPENSSL_SYS_VMS"
        +$ WRITE H_FILE "# define OPENSSL_SYS_VMS"
        +$ WRITE H_FILE "#endif"
        +$
        +$! One of the best way to figure out what the list should be is to do
        +$! the following on a Unix system:
        +$!   grep OPENSSL_NO_ crypto/*/*.h ssl/*.h engines/*.h engines/*/*.h|grep ':# *if'|sed -e 's/^.*def //'|sort|uniq
        +$! For that reason, the list will also always end up in alphabetical order
        +$ CONFIG_LOGICALS := AES,-
        +		     ASM,INLINE_ASM,-
        +		     BF,-
        +		     BIO,-
        +		     BUFFER,-
        +		     BUF_FREELISTS,-
        +		     CAMELLIA,-
        +		     CAST,-
        +		     CMS,-
        +		     COMP,-
        +		     DEPRECATED,-
        +		     DES,-
        +		     DGRAM,-
        +		     DH,-
        +		     DSA,-
        +		     EC,-
        +		     EC2M,-
        +		     ECDH,-
        +		     ECDSA,-
        +		     EC_NISTP_64_GCC_128,-
        +		     ENGINE,-
        +		     ERR,-
        +		     EVP,-
        +		     FP_API,-
        +		     GMP,-
        +		     GOST,-
        +		     HASH_COMP,-
        +		     HMAC,-
        +		     IDEA,-
        +		     JPAKE,-
        +		     KRB5,-
        +		     LHASH,-
        +		     MD2,-
        +		     MD4,-
        +		     MD5,-
        +		     MDC2,-
        +		     OCSP,-
        +		     PSK,-
        +		     RC2,-
        +		     RC4,-
        +		     RC5,-
        +		     RFC3779,-
        +		     RIPEMD,-
        +		     RSA,-
        +		     SEED,-
        +		     SHA,-
        +		     SHA0,-
        +		     SHA1,-
        +		     SHA256,-
        +		     SHA512,-
        +		     SOCK,-
        +		     SRP,-
        +		     SSL2,-
        +		     SSL_INTERN,-
        +		     STACK,-
        +		     STATIC_ENGINE,-
        +		     STDIO,-
        +		     STORE,-
        +		     TLSEXT,-
        +		     WHIRLPOOL,-
        +		     X509
        +$! Add a few that we know about
        +$ CONFIG_LOGICALS := 'CONFIG_LOGICALS',-
        +		     THREADS
        +$! The following rules, which dictate how some algorithm choices affect
        +$! others, are picked from Configure.
        +$! Quick syntax:
        +$!  list = item[ ; list]
        +$!  item = algos / dependents
        +$!  algos = algo [, algos]
        +$!  dependents = dependent [, dependents]
        +$! When a list of algos is specified in one item, it means that they must
        +$! all be disabled for the rule to apply.
        +$! When a list of dependents is specified in one item, it means that they
        +$! will all be disabled if the rule applies.
        +$! Rules are checked sequentially.  If a rule disables an algorithm, it will
        +$! affect all following rules that depend on that algorithm being disabled.
        +$! To force something to be enabled or disabled, have no algorithms in the
        +$! algos part.
        +$ CONFIG_DISABLE_RULES := RIJNDAEL/AES;-
        +			  DES/MDC2;-
        +			  EC/ECDSA,ECDH;-
        +			  MD5/SSL2,SSL3,TLS1;-
        +			  SHA/SSL3,TLS1;-
        +			  RSA/SSL2;-
        +			  RSA,DSA/SSL2;-
        +			  DH/SSL3,TLS1;-
        +			  TLS1/TLSEXT;-
        +			  EC/GOST;-
        +			  DSA/GOST;-
        +			  DH/GOST;-
        +			  /STATIC_ENGINE;-
        +			  /KRB5;-
        +			  /EC_NISTP_64_GCC_128
        +$ CONFIG_ENABLE_RULES := ZLIB_DYNAMIC/ZLIB;-
        +			 /THREADS
        +$
        +$! Architecture specific rule addtions
        +$ IF ARCH .EQS. "VAX"
        +$ THEN
        +$   ! Disable algorithms that require 64-bit integers in C
        +$   CONFIG_DISABLE_RULES = CONFIG_DISABLE_RULES + -
        +			   ";/GOST" + -
        +			   ";/WHIRLPOOL"
        +$ ENDIF
        +$
        +$ CONFIG_LOG_I = 0
        +$ CONFIG_LOG_LOOP1:
        +$   CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
        +$   CONFIG_LOG_I = CONFIG_LOG_I + 1
        +$   IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP1
        +$   IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP1_END
        +$   IF F$TRNLNM("OPENSSL_NO_"+CONFIG_LOG_E)
        +$   THEN
        +$       CONFIG_DISABLED_'CONFIG_LOG_E' := YES
        +$       CONFIG_ENABLED_'CONFIG_LOG_E' := NO
        +$	CONFIG_CHANGED_'CONFIG_LOG_E' := YES
        +$   ELSE
        +$       CONFIG_DISABLED_'CONFIG_LOG_E' := NO
        +$       CONFIG_ENABLED_'CONFIG_LOG_E' := YES
        +$	! Because all algorithms are assumed enabled by default
        +$	CONFIG_CHANGED_'CONFIG_LOG_E' := NO
        +$   ENDIF
        +$   GOTO CONFIG_LOG_LOOP1
        +$ CONFIG_LOG_LOOP1_END:
        +$
        +$! Apply cascading disable rules
        +$ CONFIG_DISABLE_I = 0
        +$ CONFIG_DISABLE_LOOP0:
        +$   CONFIG_DISABLE_E = F$EDIT(F$ELEMENT(CONFIG_DISABLE_I,";", -
        +     CONFIG_DISABLE_RULES),"TRIM")
        +$   CONFIG_DISABLE_I = CONFIG_DISABLE_I + 1
        +$   IF CONFIG_DISABLE_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP0
        +$   IF CONFIG_DISABLE_E .EQS. ";" THEN GOTO CONFIG_DISABLE_LOOP0_END
        +$
        +$   CONFIG_DISABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_DISABLE_E),"TRIM")
        +$   CONFIG_DISABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_DISABLE_E),"TRIM")
        +$   TO_DISABLE := YES
        +$   CONFIG_ALGO_I = 0
        +$   CONFIG_DISABLE_LOOP1:
        +$     CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",", -
        +       CONFIG_DISABLE_ALGOS),"TRIM")
        +$     CONFIG_ALGO_I = CONFIG_ALGO_I + 1
        +$     IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP1
        +$     IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP1_END
        +$     IF F$TYPE(CONFIG_DISABLED_'CONFIG_ALGO_E') .EQS. ""
        +$     THEN
        +$	TO_DISABLE := NO
        +$     ELSE
        +$	IF .NOT. CONFIG_DISABLED_'CONFIG_ALGO_E' THEN TO_DISABLE := NO
        +$     ENDIF
        +$     GOTO CONFIG_DISABLE_LOOP1
        +$   CONFIG_DISABLE_LOOP1_END:
        +$
        +$   IF TO_DISABLE
        +$   THEN
        +$     CONFIG_DEPENDENT_I = 0
        +$     CONFIG_DISABLE_LOOP2:
        +$	CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",", -
        +         CONFIG_DISABLE_DEPENDENTS),"TRIM")
        +$	CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
        +$	IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP2
        +$	IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP2_END
        +$       CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := YES
        +$       CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := NO
        +$	! Better not to assume defaults at this point...
        +$	CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
        +$	WRITE SYS$ERROR -
        +         "''CONFIG_DEPENDENT_E' disabled by rule ''CONFIG_DISABLE_E'"
        +$	GOTO CONFIG_DISABLE_LOOP2
        +$     CONFIG_DISABLE_LOOP2_END:
        +$   ENDIF
        +$   GOTO CONFIG_DISABLE_LOOP0
        +$ CONFIG_DISABLE_LOOP0_END:
        +$	
        +$! Apply cascading enable rules
        +$ CONFIG_ENABLE_I = 0
        +$ CONFIG_ENABLE_LOOP0:
        +$   CONFIG_ENABLE_E = F$EDIT(F$ELEMENT(CONFIG_ENABLE_I,";", -
        +     CONFIG_ENABLE_RULES),"TRIM")
        +$   CONFIG_ENABLE_I = CONFIG_ENABLE_I + 1
        +$   IF CONFIG_ENABLE_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP0
        +$   IF CONFIG_ENABLE_E .EQS. ";" THEN GOTO CONFIG_ENABLE_LOOP0_END
        +$
        +$   CONFIG_ENABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_ENABLE_E),"TRIM")
        +$   CONFIG_ENABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_ENABLE_E),"TRIM")
        +$   TO_ENABLE := YES
        +$   CONFIG_ALGO_I = 0
        +$   CONFIG_ENABLE_LOOP1:
        +$     CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",", -
        +       CONFIG_ENABLE_ALGOS),"TRIM")
        +$     CONFIG_ALGO_I = CONFIG_ALGO_I + 1
        +$     IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP1
        +$     IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP1_END
        +$     IF F$TYPE(CONFIG_ENABLED_'CONFIG_ALGO_E') .EQS. ""
        +$     THEN
        +$	TO_ENABLE := NO
        +$     ELSE
        +$	IF .NOT. CONFIG_ENABLED_'CONFIG_ALGO_E' THEN TO_ENABLE := NO
        +$     ENDIF
        +$     GOTO CONFIG_ENABLE_LOOP1
        +$   CONFIG_ENABLE_LOOP1_END:
        +$
        +$   IF TO_ENABLE
        +$   THEN
        +$     CONFIG_DEPENDENT_I = 0
        +$     CONFIG_ENABLE_LOOP2:
        +$	CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",", -
        +         CONFIG_ENABLE_DEPENDENTS),"TRIM")
        +$	CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
        +$	IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP2
        +$	IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP2_END
        +$       CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := NO
        +$       CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := YES
        +$	! Better not to assume defaults at this point...
        +$	CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
        +$	WRITE SYS$ERROR -
        +         "''CONFIG_DEPENDENT_E' enabled by rule ''CONFIG_ENABLE_E'"
        +$	GOTO CONFIG_ENABLE_LOOP2
        +$     CONFIG_ENABLE_LOOP2_END:
        +$   ENDIF
        +$   GOTO CONFIG_ENABLE_LOOP0
        +$ CONFIG_ENABLE_LOOP0_END:
        +$
        +$! Write to the configuration
        +$ CONFIG_LOG_I = 0
        +$ CONFIG_LOG_LOOP2:
        +$   CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
        +$   CONFIG_LOG_I = CONFIG_LOG_I + 1
        +$   IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP2
        +$   IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP2_END
        +$   IF CONFIG_CHANGED_'CONFIG_LOG_E'
        +$   THEN
        +$     IF CONFIG_DISABLED_'CONFIG_LOG_E'
        +$     THEN
        +$	WRITE H_FILE "#ifndef OPENSSL_NO_",CONFIG_LOG_E
        +$	WRITE H_FILE "# define OPENSSL_NO_",CONFIG_LOG_E
        +$	WRITE H_FILE "#endif"
        +$     ELSE
        +$	WRITE H_FILE "#ifndef OPENSSL_",CONFIG_LOG_E
        +$	WRITE H_FILE "# define OPENSSL_",CONFIG_LOG_E
        +$	WRITE H_FILE "#endif"
        +$     ENDIF
        +$   ENDIF
        +$   GOTO CONFIG_LOG_LOOP2
        +$ CONFIG_LOG_LOOP2_END:
        +$!
        +$ WRITE H_FILE ""
        +$ WRITE H_FILE "/* 2011-02-23 SMS."
        +$ WRITE H_FILE " * On VMS (V8.3), setvbuf() doesn't support a 64-bit"
        +$ WRITE H_FILE " * ""in"" pointer, and the help says:"
        +$ WRITE H_FILE " *       Please note that the previously documented"
        +$ WRITE H_FILE " *       value _IONBF is not supported."
        +$ WRITE H_FILE " * So, skip it on VMS."
        +$ WRITE H_FILE " */"
        +$ WRITE H_FILE "#define OPENSSL_NO_SETVBUF_IONBF"
        +$ WRITE H_FILE "/* STCP support comes with TCPIP 5.7 ECO 2 "
        +$ WRITE H_FILE " * enable on newer systems / 2012-02-24 arpadffy */"
        +$ WRITE H_FILE "#define OPENSSL_NO_SCTP"
        +$ WRITE H_FILE ""
        +$!
        +$! Add in the common "crypto/opensslconf.h.in".
        +$!
        +$ TYPE 'OPENSSLCONF_H_IN' /OUTPUT=H_FILE:
        +$!
        +$ IF ARCH .NES. "VAX"
        +$ THEN
        +$!
        +$!  Write the non-VAX specific data
        +$!
        +$   WRITE H_FILE "#if defined(HEADER_RC4_H)"
        +$   WRITE H_FILE "#undef RC4_INT"
        +$   WRITE H_FILE "#define RC4_INT unsigned int"
        +$   WRITE H_FILE "#undef RC4_CHUNK"
        +$   WRITE H_FILE "#define RC4_CHUNK unsigned long long"
        +$   WRITE H_FILE "#endif"
        +$!
        +$   WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
        +$   WRITE H_FILE "#undef DES_LONG"
        +$   WRITE H_FILE "#define DES_LONG unsigned int"
        +$   WRITE H_FILE "#undef DES_PTR"
        +$   WRITE H_FILE "#define DES_PTR"
        +$   WRITE H_FILE "#undef DES_RISC1"
        +$   WRITE H_FILE "#undef DES_RISC2"
        +$   WRITE H_FILE "#define DES_RISC1"
        +$   WRITE H_FILE "#undef DES_UNROLL"
        +$   WRITE H_FILE "#define DES_UNROLL"
        +$   WRITE H_FILE "#endif"
        +$!
        +$   WRITE H_FILE "#if defined(HEADER_BN_H)"
        +$   WRITE H_FILE "#undef BN_LLONG"	! Never define with SIXTY_FOUR_BIT
        +$   WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
        +$   WRITE H_FILE "#undef SIXTY_FOUR_BIT"
        +$   WRITE H_FILE "#define SIXTY_FOUR_BIT"
        +$   WRITE H_FILE "#undef THIRTY_TWO_BIT"
        +$   WRITE H_FILE "#undef SIXTEEN_BIT"
        +$   WRITE H_FILE "#undef EIGHT_BIT"
        +$   WRITE H_FILE "#endif"
        +$
        +$   WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
        +$!
        +$!  Else...
        +$!
        +$ ELSE
        +$!
        +$!  Write the VAX specific data
        +$!
        +$   WRITE H_FILE "#if defined(HEADER_RC4_H)"
        +$   WRITE H_FILE "#undef RC4_INT"
        +$   WRITE H_FILE "#define RC4_INT unsigned char"
        +$   WRITE H_FILE "#undef RC4_CHUNK"
        +$   WRITE H_FILE "#define RC4_CHUNK unsigned long"
        +$   WRITE H_FILE "#endif"
        +$!
        +$   WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
        +$   WRITE H_FILE "#undef DES_LONG"
        +$   WRITE H_FILE "#define DES_LONG unsigned long"
        +$   WRITE H_FILE "#undef DES_PTR"
        +$   WRITE H_FILE "#define DES_PTR"
        +$   WRITE H_FILE "#undef DES_RISC1"
        +$   WRITE H_FILE "#undef DES_RISC2"
        +$   WRITE H_FILE "#undef DES_UNROLL"
        +$   WRITE H_FILE "#endif"
        +$!
        +$   WRITE H_FILE "#if defined(HEADER_BN_H)"
        +$   WRITE H_FILE "#undef BN_LLONG"	! VAX C/DEC C doesn't have long long
        +$   WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
        +$   WRITE H_FILE "#undef SIXTY_FOUR_BIT"
        +$   WRITE H_FILE "#undef THIRTY_TWO_BIT"
        +$   WRITE H_FILE "#define THIRTY_TWO_BIT"
        +$   WRITE H_FILE "#undef SIXTEEN_BIT"
        +$   WRITE H_FILE "#undef EIGHT_BIT"
        +$   WRITE H_FILE "#endif"
        +$!
        +$! Oddly enough, the following symbol is tested in crypto/sha/sha512.c
        +$! before sha.h gets included (and HEADER_SHA_H defined), so we will not
        +$! protect this one...
        +$   WRITE H_FILE "#undef OPENSSL_NO_SHA512"
        +$   WRITE H_FILE "#define OPENSSL_NO_SHA512"
        +$!
        +$   WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
        +$   WRITE H_FILE "#define OPENSSL_EXPORT_VAR_AS_FUNCTION"
        +$!
        +$!  End
        +$!
        +$ ENDIF
        +$!
        +$! Close the [.CRYPTO._xxx]OPENSSLCONF.H file
        +$!
        +$ CLOSE H_FILE
        +$!
        +$! Purge The [.CRYPTO._xxx]OPENSSLCONF.H file
        +$!
        +$ PURGE SYS$DISK:[.CRYPTO.'ARCHD']OPENSSLCONF.H
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Rebuild The "[.CRYPTO._xxx]BUILDINF.H" file.
        +$!
        +$ BUILDINF:
        +$!
        +$! Tell The User We Are Creating The [.CRYPTO._xxx]BUILDINF.H File.
        +$!
        +$ WRITE SYS$OUTPUT "Creating [.CRYPTO.''ARCHD']BUILDINF.H Include File."
        +$!
        +$! Create The [.CRYPTO._xxx]BUILDINF.H File.
        +$!
        +$ BIH_NAME = "SYS$DISK:[.CRYPTO.''ARCHD']BUILDINF.H"
        +$ CREATE /FDL=SYS$INPUT: 'BIH_NAME'
        +RECORD
        +        FORMAT stream_lf
        +$!
        +$ OPEN /APPEND H_FILE 'bih_name'
        +$!
        +$! Get The Current Date & Time.
        +$!
        +$ TIME = F$TIME()
        +$!
        +$! Write The [.CRYPTO._xxx]BUILDINF.H File.
        +$!
        +$ CFLAGS = ""
        +$ if (POINTER_SIZE .nes. "")
        +$ then
        +$   CFLAGS = CFLAGS+ "/POINTER_SIZE=''POINTER_SIZE'"
        +$ endif
        +$ if (ZLIB .nes. "")
        +$ then
        +$   if (CFLAGS .nes. "") then CFLAGS = CFLAGS+ " "
        +$   CFLAGS = CFLAGS+ "/DEFINE=ZLIB"
        +$ endif
        +$! 
        +$ WRITE H_FILE "#define CFLAGS ""''CFLAGS'"""
        +$ WRITE H_FILE "#define PLATFORM ""VMS ''ARCHD' ''VMS_VERSION'"""
        +$ WRITE H_FILE "#define DATE ""''TIME'"" "
        +$!
        +$! Close The [.CRYPTO._xxx]BUILDINF.H File.
        +$!
        +$ CLOSE H_FILE
        +$!
        +$! Purge The [.CRYPTO._xxx]BUILDINF.H File.
        +$!
        +$ PURGE SYS$DISK:[.CRYPTO.'ARCHD']BUILDINF.H
        +$!
        +$! Delete [.CRYPTO]BUILDINF.H File, as there might be some residue from Unix.
        +$!
        +$ IF F$SEARCH("[.CRYPTO]BUILDINF.H") .NES. "" THEN -
        +     DELETE SYS$DISK:[.CRYPTO]BUILDINF.H;*
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Copy a lot of files around.
        +$!
        +$ SOFTLINKS: 
        +$!
        +$!!!! Tell The User We Are Partly Rebuilding The [.APPS] Directory.
        +$!!!!
        +$!!! WRITE SYS$OUTPUT "Rebuilding The '[.APPS]MD4.C' File."
        +$!!!!
        +$!!! DELETE SYS$DISK:[.APPS]MD4.C;*
        +$!!!!
        +$!!!! Copy MD4.C from [.CRYPTO.MD4] into [.APPS]
        +$!!!!
        +$!!! COPY SYS$DISK:[.CRYPTO.MD4]MD4.C SYS$DISK:[.APPS]
        +$!
        +$! Ensure that the [.include.openssl] directory contains a full set of
        +$! real header files.  The distribution kit may have left real or fake
        +$! symlinks there.  Rather than think about what's there, simply delete
        +$! the destination files (fake or real symlinks) before copying the real
        +$! header files in.  (Copying a real header file onto a real symlink
        +$! merely duplicates the real header file at its source.)
        +$!
        +$! Tell The User We Are Rebuilding The [.include.openssl] Directory.
        +$!
        +$ WRITE SYS$OUTPUT "Rebuilding The '[.include.openssl]' Directory."
        +$!
        +$! First, make sure the directory exists.  If it did exist, delete all
        +$! the existing header files (or fake or real symlinks).
        +$!
        +$ if f$parse( "sys$disk:[.include.openssl]") .eqs. ""
        +$ then
        +$   create /directory sys$disk:[.include.openssl]
        +$ else
        +$   delete sys$disk:[.include.openssl]*.h;*
        +$ endif
        +$!
        +$! Copy All The ".H" Files From The Main Directory.
        +$!
        +$ EXHEADER := e_os2.h
        +$ copy 'exheader' sys$disk:[.include.openssl]
        +$!
        +$! Copy All The ".H" Files From The [.CRYPTO] Directory Tree.
        +$!
        +$ SDIRS := , -
        +   'ARCHD', -
        +   OBJECTS, -
        +   MD2, MD4, MD5, SHA, MDC2, HMAC, RIPEMD, WHRLPOOL, -
        +   DES, AES, RC2, RC4, RC5, IDEA, BF, CAST, CAMELLIA, SEED, MODES, -
        +   BN, EC, RSA, DSA, ECDSA, DH, ECDH, DSO, ENGINE, -
        +   BUFFER, BIO, STACK, LHASH, RAND, ERR, -
        +   EVP, ASN1, PEM, X509, X509V3, CONF, TXT_DB, PKCS7, PKCS12, -
        +   COMP, OCSP, UI, KRB5, -
        +   CMS, PQUEUE, TS, JPAKE, SRP, STORE, CMAC
        +$!
        +$ EXHEADER_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
        +$ EXHEADER_'ARCHD' := opensslconf.h
        +$ EXHEADER_OBJECTS := objects.h, obj_mac.h
        +$ EXHEADER_MD2 := md2.h
        +$ EXHEADER_MD4 := md4.h
        +$ EXHEADER_MD5 := md5.h
        +$ EXHEADER_SHA := sha.h
        +$ EXHEADER_MDC2 := mdc2.h
        +$ EXHEADER_HMAC := hmac.h
        +$ EXHEADER_RIPEMD := ripemd.h
        +$ EXHEADER_WHRLPOOL := whrlpool.h
        +$ EXHEADER_DES := des.h, des_old.h
        +$ EXHEADER_AES := aes.h
        +$ EXHEADER_RC2 := rc2.h
        +$ EXHEADER_RC4 := rc4.h
        +$ EXHEADER_RC5 := rc5.h
        +$ EXHEADER_IDEA := idea.h
        +$ EXHEADER_BF := blowfish.h
        +$ EXHEADER_CAST := cast.h
        +$ EXHEADER_CAMELLIA := camellia.h
        +$ EXHEADER_SEED := seed.h
        +$ EXHEADER_MODES := modes.h
        +$ EXHEADER_BN := bn.h
        +$ EXHEADER_EC := ec.h
        +$ EXHEADER_RSA := rsa.h
        +$ EXHEADER_DSA := dsa.h
        +$ EXHEADER_ECDSA := ecdsa.h
        +$ EXHEADER_DH := dh.h
        +$ EXHEADER_ECDH := ecdh.h
        +$ EXHEADER_DSO := dso.h
        +$ EXHEADER_ENGINE := engine.h
        +$ EXHEADER_BUFFER := buffer.h
        +$ EXHEADER_BIO := bio.h
        +$ EXHEADER_STACK := stack.h, safestack.h
        +$ EXHEADER_LHASH := lhash.h
        +$ EXHEADER_RAND := rand.h
        +$ EXHEADER_ERR := err.h
        +$ EXHEADER_EVP := evp.h
        +$ EXHEADER_ASN1 := asn1.h, asn1_mac.h, asn1t.h
        +$ EXHEADER_PEM := pem.h, pem2.h
        +$ EXHEADER_X509 := x509.h, x509_vfy.h
        +$ EXHEADER_X509V3 := x509v3.h
        +$ EXHEADER_CONF := conf.h, conf_api.h
        +$ EXHEADER_TXT_DB := txt_db.h
        +$ EXHEADER_PKCS7 := pkcs7.h
        +$ EXHEADER_PKCS12 := pkcs12.h
        +$ EXHEADER_COMP := comp.h
        +$ EXHEADER_OCSP := ocsp.h
        +$ EXHEADER_UI := ui.h, ui_compat.h
        +$ EXHEADER_KRB5 := krb5_asn.h
        +$ EXHEADER_CMS := cms.h
        +$ EXHEADER_PQUEUE := pqueue.h
        +$ EXHEADER_TS := ts.h
        +$ EXHEADER_JPAKE := jpake.h
        +$ EXHEADER_SRP := srp.h
        +$!!! EXHEADER_STORE := store.h, str_compat.h
        +$ EXHEADER_STORE := store.h
        +$ EXHEADER_CMAC := cmac.h
        +$!
        +$ i = 0
        +$ loop_sdirs:
        +$   sdir = f$edit( f$element( i, ",", sdirs), "trim")
        +$   i = i + 1
        +$   if (sdir .eqs. ",") then goto loop_sdirs_end
        +$   hdr_list = exheader_'sdir'
        +$   if (sdir .nes. "") then sdir = "."+ sdir
        +$   copy [.crypto'sdir']'hdr_list' sys$disk:[.include.openssl]
        +$ goto loop_sdirs
        +$ loop_sdirs_end:
        +$!
        +$! Copy All The ".H" Files From The [.SSL] Directory.
        +$!
        +$! (keep these in the same order as ssl/Makefile)
        +$ EXHEADER := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h
        +$ copy sys$disk:[.ssl]'exheader' sys$disk:[.include.openssl]
        +$!
        +$! Purge the [.include.openssl] header files.
        +$!
        +$ purge sys$disk:[.include.openssl]*.h
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Build The "[.xxx.EXE.CRYPTO]SSL_LIBCRYPTO''LIB32'.OLB" Library.
        +$!
        +$ CRYPTO:
        +$!
        +$! Tell The User What We Are Doing.
        +$!
        +$ WRITE SYS$OUTPUT ""
        +$ WRITE SYS$OUTPUT -
        +   "Building The [.",ARCHD,".EXE.CRYPTO]SSL_LIBCRYPTO''LIB32'.OLB Library."
        +$!
        +$! Go To The [.CRYPTO] Directory.
        +$!
        +$ SET DEFAULT SYS$DISK:[.CRYPTO]
        +$!
        +$! Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
        +$!  
        +$ @CRYPTO-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
        +   "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Build The [.xxx.EXE.CRYPTO]*.EXE Test Applications.
        +$!  
        +$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
        +   "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Go Back To The Main Directory.
        +$!
        +$ SET DEFAULT [-]
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Build The "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library.
        +$!
        +$ SSL:
        +$!
        +$! Tell The User What We Are Doing.
        +$!
        +$ WRITE SYS$OUTPUT ""
        +$ WRITE SYS$OUTPUT -
        +   "Building The [.",ARCHD,".EXE.SSL]SSL_LIBSSL''LIB32'.OLB Library."
        +$!
        +$! Go To The [.SSL] Directory.
        +$!
        +$ SET DEFAULT SYS$DISK:[.SSL]
        +$!
        +$! Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
        +$!
        +$ @SSL-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
        +   "''ISSEVEN'" "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Go Back To The Main Directory.
        +$!
        +$ SET DEFAULT [-]
        +$!
        +$! Time To Return.
        +$!
        +$ RETURN
        +$!
        +$! Build The "[.xxx.EXE.SSL]SSL_TASK.EXE" Program.
        +$!
        +$ SSL_TASK:
        +$!
        +$! Tell The User What We Are Doing.
        +$!
        +$ WRITE SYS$OUTPUT ""
        +$ WRITE SYS$OUTPUT -
        +   "Building DECNet Based SSL Engine, [.",ARCHD,".EXE.SSL]SSL_TASK.EXE"
        +$!
        +$! Go To The [.SSL] Directory.
        +$!
        +$ SET DEFAULT SYS$DISK:[.SSL]
        +$!
        +$! Build The [.xxx.EXE.SSL]SSL_TASK.EXE
        +$!
        +$ @SSL-LIB SSL_TASK 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
        +   "''ISSEVEN'" "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Go Back To The Main Directory.
        +$!
        +$ SET DEFAULT [-]
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Build The OpenSSL Test Programs.
        +$!
        +$ TEST:
        +$!
        +$! Tell The User What We Are Doing.
        +$!
        +$ WRITE SYS$OUTPUT ""
        +$ WRITE SYS$OUTPUT "Building The OpenSSL [.",ARCHD,".EXE.TEST] Test Utilities."
        +$!
        +$! Go To The [.TEST] Directory.
        +$!
        +$ SET DEFAULT SYS$DISK:[.TEST]
        +$!
        +$! Build The Test Programs.
        +$!
        +$ @MAKETESTS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" -
        +   "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Go Back To The Main Directory.
        +$!
        +$ SET DEFAULT [-]
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Build The OpenSSL Application Programs.
        +$!
        +$ APPS:
        +$!
        +$! Tell The User What We Are Doing.
        +$!
        +$ WRITE SYS$OUTPUT ""
        +$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCHD,".EXE.APPS] Applications."
        +$!
        +$! Go To The [.APPS] Directory.
        +$!
        +$ SET DEFAULT SYS$DISK:[.APPS]
        +$!
        +$! Build The Application Programs.
        +$!
        +$ @MAKEAPPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" -
        +   "" "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Go Back To The Main Directory.
        +$!
        +$ SET DEFAULT [-]
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Build The OpenSSL Application Programs.
        +$!
        +$ ENGINES:
        +$!
        +$! Tell The User What We Are Doing.
        +$!
        +$ WRITE SYS$OUTPUT ""
        +$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCHD,".EXE.ENGINES] Engines."
        +$!
        +$! Go To The [.ENGINES] Directory.
        +$!
        +$ SET DEFAULT SYS$DISK:[.ENGINES]
        +$!
        +$! Build The Application Programs.
        +$!
        +$ @MAKEENGINES ENGINES 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" -
        +   "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'" "''ZLIB'"
        +$!
        +$! Go Back To The Main Directory.
        +$!
        +$ SET DEFAULT [-]
        +$!
        +$! That's All, Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Check if there's a "part", and separate it out
        +$!
        +$ BUILDPART = F$ELEMENT(1,"/",P1)
        +$ IF BUILDPART .EQS. "/"
        +$ THEN
        +$   BUILDPART = ""
        +$ ELSE
        +$   P1 = F$EXTRACT(0,F$LENGTH(P1) - F$LENGTH(BUILDPART) - 1, P1)
        +$ ENDIF
        +$!
        +$! Check To See If P1 Is Blank.
        +$!
        +$ IF (P1.EQS."ALL")
        +$ THEN
        +$!
        +$!   P1 Is ALL, So Build Everything.
        +$!
        +$    BUILDCOMMAND = "ALL"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Else, Check To See If P1 Has A Valid Argument.
        +$!
        +$   IF (P1.EQS."CONFIG").OR.(P1.EQS."BUILDINF").OR.(P1.EQS."SOFTLINKS") -
        +       .OR.(P1.EQS."BUILDALL") -
        +       .OR.(P1.EQS."CRYPTO").OR.(P1.EQS."SSL") -
        +       .OR.(P1.EQS."SSL_TASK").OR.(P1.EQS."TEST").OR.(P1.EQS."APPS") -
        +       .OR.(P1.EQS."ENGINES")
        +$   THEN
        +$!
        +$!    A Valid Argument.
        +$!
        +$     BUILDCOMMAND = P1
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "USAGE:   @MAKEVMS.COM [Target] [Pointer size] [Debug option] <Compiler>"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "Example: @MAKEVMS.COM ALL """" NODEBUG "
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Target ",P1," Is Invalid.  The Valid Target Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
        +$     WRITE SYS$OUTPUT "    CONFIG   :  Just build the [.CRYPTO._xxx]OPENSSLCONF.H file."
        +$     WRITE SYS$OUTPUT "    BUILDINF :  Just build the [.CRYPTO._xxx]BUILDINF.H file."
        +$     WRITE SYS$OUTPUT "    SOFTLINKS:  Just Fix The Unix soft links."
        +$     WRITE SYS$OUTPUT "    BUILDALL :  Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done."
        +$     WRITE SYS$OUTPUT "    CRYPTO   :  To Build Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
        +$     WRITE SYS$OUTPUT "    CRYPTO/x :  To Build Just The x Part Of The"
        +$     WRITE SYS$OUTPUT "                [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
        +$     WRITE SYS$OUTPUT "    SSL      :  To Build Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
        +$     WRITE SYS$OUTPUT "    SSL_TASK :  To Build Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
        +$     WRITE SYS$OUTPUT "    TEST     :  To Build Just The OpenSSL Test Programs."
        +$     WRITE SYS$OUTPUT "    APPS     :  To Build Just The OpenSSL Application Programs."
        +$     WRITE SYS$OUTPUT "    ENGINES  :  To Build Just The ENGINES"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha Architecture."
        +$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 Architecture."
        +$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     GOTO TIDY
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P1 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check P2 (POINTER_SIZE).
        +$!
        +$ IF (P2 .NES. "") .AND. (ARCH .NES. "VAX")
        +$ THEN
        +$!
        +$   IF (P2 .EQS. "32")
        +$   THEN
        +$     POINTER_SIZE = "32"
        +$   ELSE
        +$     POINTER_SIZE = F$EDIT( P2, "COLLAPSE, UPCASE")
        +$     IF ((POINTER_SIZE .EQS. "64") .OR. -
        +       (POINTER_SIZE .EQS. "64=") .OR. -
        +       (POINTER_SIZE .EQS. "64=ARGV"))
        +$     THEN
        +$       ARCHD = ARCH+ "_64"
        +$       LIB32 = ""
        +$     ELSE
        +$!
        +$!      Tell The User Entered An Invalid Option.
        +$!
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", P2, -
        +         " Is Invalid.  The Valid Options Are:"
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT -
        +         "    """"       :  Compile with default (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    32       :  Compile with 32-bit (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
        +$       WRITE SYS$OUTPUT ""
        +$! 
        +$!      Time To EXIT.
        +$!
        +$       GOTO TIDY
        +$!
        +$     ENDIF
        +$!
        +$   ENDIF
        +$!
        +$! End The P2 (POINTER_SIZE) Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If P3 Is Blank.
        +$!
        +$ IF (P3.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!   P3 Is NODEBUG, So Compile Without Debugger Information.
        +$!
        +$    DEBUGGER = "NODEBUG"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (P3.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER = "DEBUG"
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User Entered An Invalid Option.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     GOTO TIDY
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P3 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If P4 Is Blank.
        +$!
        +$ IF (P4.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!  End The GNU C Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Have VAXC Or DECC.
        +$!
        +$   IF (F$GETSYI("CPU").GE.128).OR.(F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC")
        +$   THEN 
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$!
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Check To See If The User Entered A Valid Parameter.
        +$!
        +$   IF (P4.EQS."VAXC").OR.(P4.EQS."DECC").OR.(P4.EQS."GNUC")!.OR.(P4.EQS."LINK")
        +$   THEN
        +$!
        +$!    Check To See If The User Wanted To Just LINK.
        +$!
        +$     IF (P4.EQS."LINK")
        +$     THEN
        +$!
        +$!      Looks Like LINK-only
        +$!
        +$       COMPILER = "LINK"
        +$!
        +$!      Tell The User We Are Only Linking.
        +$!
        +$       WRITE SYS$OUTPUT "LINK Only.  This actually NOT YET SUPPORTED!"
        +$!
        +$!    End LINK Check.
        +$!
        +$     ENDIF
        +$!
        +$!    Check To See If The User Wanted DECC.
        +$!
        +$     IF (P4.EQS."DECC")
        +$     THEN
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       COMPILER = "DECC"
        +$!
        +$!      Tell The User We Are Using DECC.
        +$!
        +$       WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    End DECC Check.
        +$!
        +$     ENDIF
        +$!
        +$!    Check To See If We Are To Use VAXC.
        +$!
        +$     IF (P4.EQS."VAXC")
        +$     THEN
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       COMPILER = "VAXC"
        +$!
        +$!      Tell The User We Are Using VAX C.
        +$!
        +$       WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    End VAXC Check
        +$!
        +$     ENDIF
        +$!
        +$!    Check To See If We Are To Use GNU C.
        +$!
        +$     IF (P4.EQS."GNUC")
        +$     THEN
        +$!
        +$!      Looks Like GNUC, Set To Use GNUC.
        +$!
        +$       COMPILER = "GNUC"
        +$!
        +$!      Tell The User We Are Using GNUC.
        +$!
        +$       WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    End The GNU C Check.
        +$!
        +$     ENDIF
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P4," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$     WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$     WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     GOTO TIDY
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P4 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Time to check the contents of P5, and to make sure we get the correct
        +$! library.
        +$!
        +$ IF P5.EQS."SOCKETSHR" .OR. P5.EQS."MULTINET" .OR. P5.EQS."UCX" -
        +     .OR. P5.EQS."TCPIP" .OR. P5.EQS."NONE"
        +$ THEN
        +$!
        +$!  Check to see if SOCKETSHR was chosen
        +$!
        +$   IF P5.EQS."SOCKETSHR"
        +$   THEN
        +$!
        +$!    Set the library to use SOCKETSHR
        +$!
        +$     TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
        +$!
        +$!    Done with SOCKETSHR
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if MULTINET was chosen
        +$!
        +$   IF P5.EQS."MULTINET"
        +$   THEN
        +$!
        +$!    Set the library to use UCX emulation.
        +$!
        +$     P5 = "UCX"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using MultiNet via UCX emulation for TCP/IP"
        +$!
        +$!    Done with MULTINET
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if UCX was chosen
        +$!
        +$   IF P5.EQS."UCX"
        +$   THEN
        +$!
        +$!    Set the library to use UCX.
        +$!
        +$     TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
        +$!
        +$!    Done with UCX
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if TCPIP was chosen
        +$!
        +$   IF P5.EQS."TCPIP"
        +$   THEN
        +$!
        +$!    Set the library to use TCPIP (post UCX).
        +$!
        +$     TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using TCPIP (post UCX) for TCP/IP"
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if NONE was chosen
        +$!
        +$   IF P5.EQS."NONE"
        +$   THEN
        +$!
        +$!    Do not use a TCPIP library.
        +$!
        +$     TCPIP_LIB = ""
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "A specific TCPIP library will not be used."
        +$!
        +$!    Done with NONE.
        +$!
        +$   ENDIF
        +$!
        +$!  Set the TCPIP_TYPE symbol
        +$!
        +$   TCPIP_TYPE = P5
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$   IF P5 .NES. ""
        +$   THEN
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P5," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
        +$     WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
        +$     WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP TCP/IP (post UCX) library."
        +$     WRITE SYS$OUTPUT "    NONE       :  To not link with a specific TCP/IP library."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     GOTO TIDY
        +$   ELSE
        +$!
        +$! If TCPIP is not defined, then hardcode it to make
        +$! it clear that no TCPIP is desired.
        +$!
        +$     IF P5 .EQS. ""
        +$     THEN
        +$       TCPIP_LIB = ""
        +$       TCPIP_TYPE = "NONE"
        +$     ELSE
        +$!
        +$!    Set the TCPIP_TYPE symbol
        +$!
        +$       TCPIP_TYPE = P5
        +$     ENDIF
        +$   ENDIF
        +$!
        +$!  Done with TCP/IP libraries
        +$!
        +$ ENDIF
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For P6.
        +$!
        +$ IF (P6.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN :=
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,VMS_VERSION))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P6 Check.
        +$!
        +$ ENDIF
        +$!
        +$!
        +$! Check To See If We Have A ZLIB Option.
        +$!
        +$ ZLIB = P7
        +$ IF (ZLIB .NES. "")
        +$ THEN
        +$!
        +$!  Check for expected ZLIB files.
        +$!
        +$   err = 0
        +$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
        +$   if (f$search( file1) .eqs. "")
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
        +$     err = 1
        +$   endif
        +$!
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     if (err .eq. 0)
        +$     then
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     endif
        +$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
        +$     WRITE SYS$OUTPUT ""
        +$     err = err+ 2
        +$   endif
        +$   if (err .eq. 1)
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$   endif
        +$!
        +$   if (err .ne. 0)
        +$   then
        +$     GOTO TIDY
        +$   endif
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
        +$!
        +$! End The ZLIB Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        +$!
        +$ TIDY:
        +$!
        +$! Close any open files.
        +$!
        +$ if (f$trnlnm( "h_file", "LNM$PROCESS", 0, "SUPERVISOR") .nes. "") then -
        +   close h_file
        +$!
        +$! Restore the original default device:[directory].
        +$!
        +$ SET DEFAULT 'DEF_ORIG'
        +$!
        +$ EXIT
        +$!
        diff --git a/vendor/openssl/openssl/ms/.rnd b/vendor/openssl/openssl/ms/.rnd
        new file mode 100644
        index 000000000..0566b46df
        Binary files /dev/null and b/vendor/openssl/openssl/ms/.rnd differ
        diff --git a/vendor/openssl/openssl/ms/32all.bat b/vendor/openssl/openssl/ms/32all.bat
        new file mode 100644
        index 000000000..aaab9b0c9
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/32all.bat
        @@ -0,0 +1,20 @@
        +set OPTS=no-asm
        +
        +perl Configure VC-WIN32
        +perl util\mkfiles.pl >MINFO
        +perl util\mk1mf.pl %OPTS% debug VC-WIN32 >d32.mak
        +perl util\mk1mf.pl %OPTS% VC-WIN32 >32.mak
        +perl util\mk1mf.pl %OPTS% debug dll VC-WIN32 >d32dll.mak
        +perl util\mk1mf.pl %OPTS% dll VC-WIN32 >32dll.mak
        +perl util\mkdef.pl 32 libeay > ms\libeay32.def
        +perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
        +
        +nmake -f d32.mak
        +@if errorlevel 1 goto end
        +nmake -f 32.mak
        +@if errorlevel 1 goto end
        +nmake -f d32dll.mak
        +@if errorlevel 1 goto end
        +nmake -f 32dll.mak
        +
        +:end
        diff --git a/vendor/openssl/openssl/ms/README b/vendor/openssl/openssl/ms/README
        new file mode 100644
        index 000000000..07f1925d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/README
        @@ -0,0 +1,13 @@
        +Run these makefiles from the top level as in
        +nmake -f ms\makefilename
        +to build with visual C++ 4.[01].
        +
        +The results will be in the out directory.
        +
        +These makefiles and def files were generated by typing
        +
        +perl util\mk1mf.pl VC-NT >ms/nt.mak
        +perl util\mk1mf.pl VC-NT dll >ms/ntdll.mak
        +
        +perl util\mkdef.pl 32 crypto > ms/crypto32.def
        +perl util\mkdef.pl 32 ssl > ms/ssl32.def
        diff --git a/vendor/openssl/openssl/ms/applink.c b/vendor/openssl/openssl/ms/applink.c
        new file mode 100644
        index 000000000..54a0a6426
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/applink.c
        @@ -0,0 +1,94 @@
        +#define APPLINK_STDIN	1
        +#define APPLINK_STDOUT	2
        +#define APPLINK_STDERR	3
        +#define APPLINK_FPRINTF	4
        +#define APPLINK_FGETS	5
        +#define APPLINK_FREAD	6
        +#define APPLINK_FWRITE	7
        +#define APPLINK_FSETMOD	8
        +#define APPLINK_FEOF	9
        +#define APPLINK_FCLOSE 	10	/* should not be used */
        +
        +#define APPLINK_FOPEN	11	/* solely for completeness */
        +#define APPLINK_FSEEK	12
        +#define APPLINK_FTELL	13
        +#define APPLINK_FFLUSH	14
        +#define APPLINK_FERROR	15
        +#define APPLINK_CLEARERR 16
        +#define APPLINK_FILENO	17	/* to be used with below */
        +
        +#define APPLINK_OPEN	18	/* formally can't be used, as flags can vary */
        +#define APPLINK_READ	19
        +#define APPLINK_WRITE	20
        +#define APPLINK_LSEEK	21
        +#define APPLINK_CLOSE	22
        +#define APPLINK_MAX	22	/* always same as last macro */
        +
        +#ifndef APPMACROS_ONLY
        +#include <stdio.h>
        +#include <io.h>
        +#include <fcntl.h>
        +
        +static void *app_stdin(void)		{ return stdin;  }
        +static void *app_stdout(void)		{ return stdout; }
        +static void *app_stderr(void)		{ return stderr; }
        +static int   app_feof(FILE *fp)		{ return feof(fp); }
        +static int   app_ferror(FILE *fp)	{ return ferror(fp); }
        +static void  app_clearerr(FILE *fp)	{ clearerr(fp); }
        +static int   app_fileno(FILE *fp)	{ return _fileno(fp); }
        +static int   app_fsetmod(FILE *fp,char mod)
        +{ return _setmode (_fileno(fp),mod=='b'?_O_BINARY:_O_TEXT); }
        +
        +#ifdef __cplusplus
        +extern "C" {
        +#endif
        +
        +__declspec(dllexport)
        +void **
        +#if defined(__BORLANDC__)
        +__stdcall	/* __stdcall appears to be the only way to get the name
        +		 * decoration right with Borland C. Otherwise it works
        +		 * purely incidentally, as we pass no parameters. */
        +#else
        +__cdecl
        +#endif
        +OPENSSL_Applink(void)
        +{ static int once=1;
        +  static void *OPENSSL_ApplinkTable[APPLINK_MAX+1]={(void *)APPLINK_MAX};
        +
        +    if (once)
        +    {	OPENSSL_ApplinkTable[APPLINK_STDIN]	= app_stdin;
        +	OPENSSL_ApplinkTable[APPLINK_STDOUT]	= app_stdout;
        +	OPENSSL_ApplinkTable[APPLINK_STDERR]	= app_stderr;
        +	OPENSSL_ApplinkTable[APPLINK_FPRINTF]	= fprintf;
        +	OPENSSL_ApplinkTable[APPLINK_FGETS]	= fgets;
        +	OPENSSL_ApplinkTable[APPLINK_FREAD]	= fread;
        +	OPENSSL_ApplinkTable[APPLINK_FWRITE]	= fwrite;
        +	OPENSSL_ApplinkTable[APPLINK_FSETMOD]	= app_fsetmod;
        +	OPENSSL_ApplinkTable[APPLINK_FEOF]	= app_feof;
        +	OPENSSL_ApplinkTable[APPLINK_FCLOSE]	= fclose;
        +
        +	OPENSSL_ApplinkTable[APPLINK_FOPEN]	= fopen;
        +	OPENSSL_ApplinkTable[APPLINK_FSEEK]	= fseek;
        +	OPENSSL_ApplinkTable[APPLINK_FTELL]	= ftell;
        +	OPENSSL_ApplinkTable[APPLINK_FFLUSH]	= fflush;
        +	OPENSSL_ApplinkTable[APPLINK_FERROR]	= app_ferror;
        +	OPENSSL_ApplinkTable[APPLINK_CLEARERR]	= app_clearerr;
        +	OPENSSL_ApplinkTable[APPLINK_FILENO]	= app_fileno;
        +
        +	OPENSSL_ApplinkTable[APPLINK_OPEN]	= _open;
        +	OPENSSL_ApplinkTable[APPLINK_READ]	= _read;
        +	OPENSSL_ApplinkTable[APPLINK_WRITE]	= _write;
        +	OPENSSL_ApplinkTable[APPLINK_LSEEK]	= _lseek;
        +	OPENSSL_ApplinkTable[APPLINK_CLOSE]	= _close;
        +
        +	once = 0;
        +    }
        +
        +  return OPENSSL_ApplinkTable;
        +}
        +
        +#ifdef __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/ms/bcb4.bat b/vendor/openssl/openssl/ms/bcb4.bat
        new file mode 100644
        index 000000000..00fb9e845
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/bcb4.bat
        @@ -0,0 +1,6 @@
        +perl Configure BC-32
        +perl util\mkfiles.pl > MINFO
        +
        +@rem create make file
        +perl util\mk1mf.pl no-asm BC-NT > bcb.mak
        +
        diff --git a/vendor/openssl/openssl/ms/certCA.srl b/vendor/openssl/openssl/ms/certCA.srl
        new file mode 100644
        index 000000000..2cfaa3ba2
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/certCA.srl
        @@ -0,0 +1 @@
        +1D
        diff --git a/vendor/openssl/openssl/ms/certCA.ss b/vendor/openssl/openssl/ms/certCA.ss
        new file mode 100644
        index 000000000..b48c657ae
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/certCA.ss
        @@ -0,0 +1,10 @@
        +-----BEGIN CERTIFICATE-----
        +MIIBXDCCAQYCAQAwDQYJKoZIhvcNAQEEBQAwOTELMAkGA1UEBhMCQVUxFzAVBgNV
        +BAoTDkRvZGd5IEJyb3RoZXJzMREwDwYDVQQDEwhEb2RneSBDQTAeFw05ODA3MjEw
        +NjUwMTZaFw05ODA4MjAwNjUwMTZaMDkxCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5E
        +b2RneSBCcm90aGVyczERMA8GA1UEAxMIRG9kZ3kgQ0EwXDANBgkqhkiG9w0BAQEF
        +AANLADBIAkEA0DQLenM/ncK6CwSEJhOO1WfZUPUEi4pvos9fHW459jh3rRDADgi3
        +fiCYxoRVSQhvB47kDZ3ViNg5yrDhy7F9ywIDAQABMA0GCSqGSIb3DQEBBAUAA0EA
        +S564l3SBxJ+QcIXthGGDyP5zkxTf/1fHfelW9LNgu6lZTdy9Dlp/NecPekzRmZEM
        +WiGXGkKNeuo8PsnGJHP9Qg==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/ms/certU.ss b/vendor/openssl/openssl/ms/certU.ss
        new file mode 100644
        index 000000000..095ea1433
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/certU.ss
        @@ -0,0 +1,10 @@
        +-----BEGIN CERTIFICATE-----
        +MIIBcTCCARsCARwwDQYJKoZIhvcNAQEEBQAwOTELMAkGA1UEBhMCQVUxFzAVBgNV
        +BAoTDkRvZGd5IEJyb3RoZXJzMREwDwYDVQQDEwhEb2RneSBDQTAeFw05ODA3MjEw
        +NjUwMjdaFw05ODA4MjAwNjUwMjdaME4xCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5E
        +b2RneSBCcm90aGVyczESMBAGA1UEAxMJQnJvdGhlciAxMRIwEAYDVQQDEwlCcm90
        +aGVyIDIwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0e4qorOr/zuLB9NvRaXhJVaI
        +HaGGasa7eMAjVPitWAXkN+DxXiGH1CnMgQraKiYzsEVP15xtxkevEvK5jJpOwwID
        +AQABMA0GCSqGSIb3DQEBBAUAA0EAZhcPV+SWwaszFuDTYc6fUurcV9OeXUqoxSQy
        +MnLZPTyWubHbbkUr9fUfdf7Cc7dFqGzag05VHkNQUS9VjMzjIQ==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/ms/cmp.pl b/vendor/openssl/openssl/ms/cmp.pl
        new file mode 100644
        index 000000000..95b257fe4
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/cmp.pl
        @@ -0,0 +1,47 @@
        +#!/usr/local/bin/perl
        +
        +($#ARGV == 1) || die "usage: cmp.pl <file1> <file2>\n";
        +
        +open(IN0,"<$ARGV[0]") || die "unable to open $ARGV[0]\n";
        +open(IN1,"<$ARGV[1]") || die "unable to open $ARGV[1]\n";
        +binmode IN0;
        +binmode IN1;
        +
        +$tot=0;
        +$ret=1;
        +for (;;)
        +	{
        +	$n1=sysread(IN0,$b1,4096);
        +	$n2=sysread(IN1,$b2,4096);
        +
        +	last if ($n1 != $n2);
        +	last if ($b1 ne $b2);
        +	last if ($n1 < 0);
        +	if ($n1 == 0)
        +		{
        +		$ret=0;
        +		last;
        +		}
        +	$tot+=$n1;
        +	}
        +
        +close(IN0);
        +close(IN1);
        +if ($ret)
        +	{
        +	printf STDERR "$ARGV[0] and $ARGV[1] are different\n";
        +	@a1=unpack("C*",$b1);
        +	@a2=unpack("C*",$b2);
        +	for ($i=0; $i<=$#a1; $i++)
        +		{
        +		if ($a1[$i] ne $a2[$i])
        +			{
        +			printf "%02X %02X <<\n",$a1[$i],$a2[$i];
        +			last;
        +			}
        +		}
        +	$nm=$tot+$n1;
        +	$tot+=$i+1;
        +	printf STDERR "diff at char $tot of $nm\n";
        +	}
        +exit($ret);
        diff --git a/vendor/openssl/openssl/ms/do_ms.bat b/vendor/openssl/openssl/ms/do_ms.bat
        new file mode 100644
        index 000000000..55014d3fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/do_ms.bat
        @@ -0,0 +1,11 @@
        +
        +perl util\mkfiles.pl >MINFO
        +perl util\mk1mf.pl no-asm VC-WIN32 >ms\nt.mak
        +perl util\mk1mf.pl dll no-asm VC-WIN32 >ms\ntdll.mak
        +if x%OSVERSION% == x goto skipce
        +perl util\mk1mf.pl no-asm VC-CE >ms\ce.mak
        +perl util\mk1mf.pl dll no-asm VC-CE >ms\cedll.mak
        +:skipce
        +
        +perl util\mkdef.pl 32 libeay > ms\libeay32.def
        +perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
        diff --git a/vendor/openssl/openssl/ms/do_nasm.bat b/vendor/openssl/openssl/ms/do_nasm.bat
        new file mode 100644
        index 000000000..7b3f3edbf
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/do_nasm.bat
        @@ -0,0 +1,8 @@
        +
        +perl util\mkfiles.pl >MINFO
        +perl util\mk1mf.pl nasm VC-WIN32 >ms\nt.mak
        +perl util\mk1mf.pl dll nasm VC-WIN32 >ms\ntdll.mak
        +perl util\mk1mf.pl nasm BC-NT >ms\bcb.mak
        +
        +perl util\mkdef.pl 32 libeay > ms\libeay32.def
        +perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
        diff --git a/vendor/openssl/openssl/ms/do_nt.bat b/vendor/openssl/openssl/ms/do_nt.bat
        new file mode 100644
        index 000000000..e2d525e05
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/do_nt.bat
        @@ -0,0 +1,7 @@
        +
        +perl util\mkfiles.pl >MINFO
        +perl util\mk1mf.pl no-asm VC-NT >ms\nt.mak
        +perl util\mk1mf.pl dll no-asm VC-NT >ms\ntdll.mak
        +
        +perl util\mkdef.pl libeay NT > ms\libeay32.def
        +perl util\mkdef.pl ssleay NT > ms\ssleay32.def
        diff --git a/vendor/openssl/openssl/ms/do_win64a.bat b/vendor/openssl/openssl/ms/do_win64a.bat
        new file mode 100644
        index 000000000..ff8b19ccf
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/do_win64a.bat
        @@ -0,0 +1,19 @@
        +perl util\mkfiles.pl >MINFO
        +
        +cmd /c "nasm -f win64 -v" >NUL: 2>&1
        +if %errorlevel% neq 0 goto ml64
        +
        +perl ms\uplink-x86_64.pl nasm > ms\uptable.asm
        +nasm -f win64 -o ms\uptable.obj ms\uptable.asm
        +goto proceed
        +
        +:ml64
        +perl ms\uplink-x86_64.pl masm > ms\uptable.asm
        +ml64 -c -Foms\uptable.obj ms\uptable.asm
        +
        +:proceed
        +perl util\mk1mf.pl VC-WIN64A >ms\nt.mak
        +perl util\mk1mf.pl dll VC-WIN64A >ms\ntdll.mak
        +
        +perl util\mkdef.pl 32 libeay > ms\libeay32.def
        +perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
        diff --git a/vendor/openssl/openssl/ms/do_win64i.bat b/vendor/openssl/openssl/ms/do_win64i.bat
        new file mode 100644
        index 000000000..088f5e1d0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/do_win64i.bat
        @@ -0,0 +1,9 @@
        +
        +perl util\mkfiles.pl >MINFO
        +perl ms\uplink-ia64.pl > ms\uptable.asm
        +ias -o ms\uptable.obj ms\uptable.asm
        +perl util\mk1mf.pl VC-WIN64I >ms\nt.mak
        +perl util\mk1mf.pl dll VC-WIN64I >ms\ntdll.mak
        +
        +perl util\mkdef.pl 32 libeay > ms\libeay32.def
        +perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
        diff --git a/vendor/openssl/openssl/ms/keyCA.ss b/vendor/openssl/openssl/ms/keyCA.ss
        new file mode 100644
        index 000000000..933c2cd6e
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/keyCA.ss
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBOwIBAAJBANA0C3pzP53CugsEhCYTjtVn2VD1BIuKb6LPXx1uOfY4d60QwA4I
        +t34gmMaEVUkIbweO5A2d1YjYOcqw4cuxfcsCAwEAAQJAOT9WOKEfyN0WEpl3TJDs
        +ITmgw2XbjhLOh1HFsW3xegWlaOuhL/wGamz7n7zzL/RQF3JP/VvpGk2F8VD9JhwT
        +wQIhAPmqM3fLttBoCQuwQRdIPfB7Ps3THqx6N8AJ04z3I1ejAiEA1XyDd7bLpWrw
        +/oA8CmR4b/KCGfvRwAL/Qej/rQliw7kCIQCYRzSvO8ScpuflhjKdZcXJuRJcbgnG
        +f6Ejc5rh3xdiawIhALMmLdzEFNjXiSzIx5mg/kBTLUJIw5dx7GqO8B9xBORhAiA5
        +oTN/hgvvrkkmRsHQpNBmzAEGBzhMEEq9lD6ZWrTSRg==
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/ms/keyU.ss b/vendor/openssl/openssl/ms/keyU.ss
        new file mode 100644
        index 000000000..05d356e7a
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/keyU.ss
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBANHuKqKzq/87iwfTb0Wl4SVWiB2hhmrGu3jAI1T4rVgF5Dfg8V4h
        +h9QpzIEK2iomM7BFT9ecbcZHrxLyuYyaTsMCAwEAAQJBAIxtM6n4ZCJscxj+D13Y
        +k13Fn3Gqvd6pJ3ijlj7dxh6tRBBQ3W9qmQflyvEc81giI2XtbVYBOEJKtJ1cWWZm
        +gAkCIQDpEoOuc4KCI5ti6aMJvtxlXWNHbkXCxtbeIjH4+FnH9QIhAOaU3XVeWWOK
        +PnnO87KniDjHQqWLnooivDGRK+FUKeDXAiEA2MjEvFVqFVvDIsxHPkBNROcI+Z6i
        +ulkx76kErBtrfqUCIHN5uBLQZmngUPuFtiwRlLoCqJDphENfs+oK7vPQx4xPAiEA
        +hnY2Ulrpld83IG6bUs95Loc8Fk81hez5YwmhsFEXVtk=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/ms/mingw32.bat b/vendor/openssl/openssl/ms/mingw32.bat
        new file mode 100644
        index 000000000..06b573387
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/mingw32.bat
        @@ -0,0 +1,90 @@
        +@rem OpenSSL with Mingw32+GNU as
        +@rem ---------------------------
        +
        +perl Configure mingw %1 %2 %3 %4 %5 %6 %7 %8
        +
        +@echo off
        +
        +perl -e "exit 1 if '%1' eq 'no-asm'"
        +if errorlevel 1 goto noasm
        +
        +echo Generating x86 for GNU assember
        +
        +echo Bignum
        +cd crypto\bn\asm
        +perl bn-586.pl gaswin > bn-win32.s
        +perl co-586.pl gaswin > co-win32.s
        +cd ..\..\..
        +
        +echo DES
        +cd crypto\des\asm
        +perl des-586.pl gaswin > d-win32.s
        +cd ..\..\..
        +
        +echo crypt
        +cd crypto\des\asm
        +perl crypt586.pl gaswin > y-win32.s
        +cd ..\..\..
        +
        +echo Blowfish
        +cd crypto\bf\asm
        +perl bf-586.pl gaswin > b-win32.s
        +cd ..\..\..
        +
        +echo CAST5
        +cd crypto\cast\asm
        +perl cast-586.pl gaswin > c-win32.s
        +cd ..\..\..
        +
        +echo RC4
        +cd crypto\rc4\asm
        +perl rc4-586.pl gaswin > r4-win32.s
        +cd ..\..\..
        +
        +echo MD5
        +cd crypto\md5\asm
        +perl md5-586.pl gaswin > m5-win32.s
        +cd ..\..\..
        +
        +echo SHA1
        +cd crypto\sha\asm
        +perl sha1-586.pl gaswin > s1-win32.s
        +cd ..\..\..
        +
        +echo RIPEMD160
        +cd crypto\ripemd\asm
        +perl rmd-586.pl gaswin > rm-win32.s
        +cd ..\..\..
        +
        +echo RC5\32
        +cd crypto\rc5\asm
        +perl rc5-586.pl gaswin > r5-win32.s
        +cd ..\..\..
        +
        +:noasm
        +
        +echo Generating makefile
        +perl util\mkfiles.pl >MINFO
        +perl util\mk1mf.pl gaswin Mingw32 >ms\mingw32a.mak
        +echo Generating DLL definition files
        +perl util\mkdef.pl 32 libeay >ms\libeay32.def
        +if errorlevel 1 goto end
        +perl util\mkdef.pl 32 ssleay >ms\ssleay32.def
        +if errorlevel 1 goto end
        +
        +rem copy ms\tlhelp32.h outinc
        +
        +echo Building the libraries
        +mingw32-make -f ms/mingw32a.mak
        +if errorlevel 1 goto end
        +
        +echo Generating the DLLs and input libraries
        +dllwrap --dllname libeay32.dll --output-lib out/libeay32.a --def ms/libeay32.def out/libcrypto.a -lws2_32 -lgdi32
        +if errorlevel 1 goto end
        +dllwrap --dllname libssl32.dll --output-lib out/libssl32.a --def ms/ssleay32.def out/libssl.a out/libeay32.a
        +if errorlevel 1 goto end
        +
        +echo Done compiling OpenSSL
        +
        +:end
        +
        diff --git a/vendor/openssl/openssl/ms/mw.bat b/vendor/openssl/openssl/ms/mw.bat
        new file mode 100644
        index 000000000..35e00a450
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/mw.bat
        @@ -0,0 +1,26 @@
        +@rem OpenSSL with Mingw32
        +@rem --------------------
        +
        +@rem Makefile
        +perl util\mkfiles.pl >MINFO
        +perl util\mk1mf.pl Mingw32 >ms\mingw32.mak
        +@rem DLL definition files
        +perl util\mkdef.pl 32 libeay >ms\libeay32.def
        +if errorlevel 1 goto end
        +perl util\mkdef.pl 32 ssleay >ms\ssleay32.def
        +if errorlevel 1 goto end
        +
        +@rem Build the libraries
        +make -f ms/mingw32.mak
        +if errorlevel 1 goto end
        +
        +@rem Generate the DLLs and input libraries
        +dllwrap --dllname libeay32.dll --output-lib out/libeay32.a --def ms/libeay32.def out/libcrypto.a -lws2_32 -lgdi32
        +if errorlevel 1 goto end
        +dllwrap --dllname libssl32.dll --output-lib out/libssl32.a --def ms/ssleay32.def out/libssl.a out/libeay32.a
        +if errorlevel 1 goto end
        +
        +echo Done compiling OpenSSL
        +
        +:end
        +
        diff --git a/vendor/openssl/openssl/ms/req2CA.ss b/vendor/openssl/openssl/ms/req2CA.ss
        new file mode 100644
        index 000000000..d061fb2a0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/req2CA.ss
        @@ -0,0 +1,29 @@
        +Certificate Request:
        +    Data:
        +        Version: 0 (0x0)
        +        Subject: C=AU, O=Dodgy Brothers, CN=Dodgy CA
        +        Subject Public Key Info:
        +            Public Key Algorithm: rsaEncryption
        +            RSA Public Key: (512 bit)
        +                Modulus (512 bit):
        +                    00:d0:34:0b:7a:73:3f:9d:c2:ba:0b:04:84:26:13:
        +                    8e:d5:67:d9:50:f5:04:8b:8a:6f:a2:cf:5f:1d:6e:
        +                    39:f6:38:77:ad:10:c0:0e:08:b7:7e:20:98:c6:84:
        +                    55:49:08:6f:07:8e:e4:0d:9d:d5:88:d8:39:ca:b0:
        +                    e1:cb:b1:7d:cb
        +                Exponent: 65537 (0x10001)
        +        Attributes:
        +            a0:00
        +    Signature Algorithm: md5WithRSAEncryption
        +        8d:15:e6:8e:49:0f:07:fb:e0:72:ad:f0:04:9a:c8:5d:e7:1b:
        +        ed:99:c9:c3:3c:f5:8e:4d:a1:5e:e1:40:75:2c:24:f0:c6:dd:
        +        10:87:35:26:1d:cc:79:3f:a2:c6:a0:04:c8:52:78:ed:26:32:
        +        d3:1b:a7:cd:5e:8c:55:92:dd:88
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIHzMIGeAgEAMDkxCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5Eb2RneSBCcm90aGVy
        +czERMA8GA1UEAxMIRG9kZ3kgQ0EwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0DQL
        +enM/ncK6CwSEJhOO1WfZUPUEi4pvos9fHW459jh3rRDADgi3fiCYxoRVSQhvB47k
        +DZ3ViNg5yrDhy7F9ywIDAQABoAAwDQYJKoZIhvcNAQEEBQADQQCNFeaOSQ8H++By
        +rfAEmshd5xvtmcnDPPWOTaFe4UB1LCTwxt0QhzUmHcx5P6LGoATIUnjtJjLTG6fN
        +XoxVkt2I
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/ms/reqCA.ss b/vendor/openssl/openssl/ms/reqCA.ss
        new file mode 100644
        index 000000000..1f7138cad
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/reqCA.ss
        @@ -0,0 +1,8 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIHzMIGeAgEAMDkxCzAJBgNVBAYTAkFVMRcwFQYDVQQKEw5Eb2RneSBCcm90aGVy
        +czERMA8GA1UEAxMIRG9kZ3kgQ0EwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0DQL
        +enM/ncK6CwSEJhOO1WfZUPUEi4pvos9fHW459jh3rRDADgi3fiCYxoRVSQhvB47k
        +DZ3ViNg5yrDhy7F9ywIDAQABoAAwDQYJKoZIhvcNAQEFBQADQQA5DZSZgDXs8flG
        +GZf4SGr8QpqkxSu9bZOYp/ySuz1khj7aupBrvZBmqZcZx4ZjAUN7UQpMWu2gyfKa
        +mAiiLPFN
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/ms/reqU.ss b/vendor/openssl/openssl/ms/reqU.ss
        new file mode 100644
        index 000000000..91cce5966
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/reqU.ss
        @@ -0,0 +1,8 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIIBCDCBswIBADBOMQswCQYDVQQGEwJBVTEXMBUGA1UEChMORG9kZ3kgQnJvdGhl
        +cnMxEjAQBgNVBAMTCUJyb3RoZXIgMTESMBAGA1UEAxMJQnJvdGhlciAyMFwwDQYJ
        +KoZIhvcNAQEBBQADSwAwSAJBANHuKqKzq/87iwfTb0Wl4SVWiB2hhmrGu3jAI1T4
        +rVgF5Dfg8V4hh9QpzIEK2iomM7BFT9ecbcZHrxLyuYyaTsMCAwEAAaAAMA0GCSqG
        +SIb3DQEBAgUAA0EAhB0p6LbiVq+XshLo5sBQN0rsROC1OgWrdS6ZUmMaigOKK069
        +r1o+dGwbM5VCYGTZf0PW9OtGuArGct0laL5h4w==
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/ms/speed32.bat b/vendor/openssl/openssl/ms/speed32.bat
        new file mode 100644
        index 000000000..95f7ce950
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/speed32.bat
        @@ -0,0 +1,37 @@
        +set makefile=ms\nt.mak
        +
        +perl Configure b
        +del tmp\*.obj
        +nmake -f %makefile%
        +nmake -f %makefile%
        +nmake -f %makefile%
        +out\ssleay version -v -b -f >speed.1
        +out\ssleay speed >speed.1l
        +
        +perl Configure bl-4c-2c
        +del tmp\rc4*.obj tmp\bn*.obj tmp\md2_dgst.obj
        +nmake -f %makefile%
        +nmake -f %makefile%
        +nmake -f %makefile%
        +out\ssleay speed rc4 rsa md2 >speed.2l
        +
        +perl Configure bl-4c-ri
        +del tmp\rc4*.obj
        +nmake -f %makefile%
        +nmake -f %makefile%
        +nmake -f %makefile%
        +out\ssleay speed rc4 >speed.3l
        +
        +perl Configure b2-is-ri-dp
        +del tmp\i_*.obj tmp\rc4*.obj tmp\ecb_enc.obj tmp\bn*.obj
        +nmake -f %makefile%
        +nmake -f %makefile%
        +nmake -f %makefile%
        +out\ssleay speed rsa rc4 idea des >speed.4l
        +
        +type speed.1 >speed.log
        +type speed.1l >>speed.log
        +perl util\sp-diff.pl speed.1l speed.2l >>speed.log
        +perl util\sp-diff.pl speed.1l speed.3l >>speed.log
        +perl util\sp-diff.pl speed.1l speed.4l >>speed.log
        +
        diff --git a/vendor/openssl/openssl/ms/tenc.bat b/vendor/openssl/openssl/ms/tenc.bat
        new file mode 100644
        index 000000000..a4fa7f365
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/tenc.bat
        @@ -0,0 +1,14 @@
        +rem called by testenc
        +
        +echo test %1 %2 %3 %4 %5 %6 
        +%ssleay% %1 %2 %3 %4 %5 %6 -e -bufsize 113 -k test -in %input% -out %tmp1%
        +%ssleay% %1 %2 %3 %4 %5 %6 -d -bufsize 157 -k test -in %tmp1% -out %out1%
        +%cmp% %input% %out1%
        +if errorlevel 1 goto err
        +
        +echo test base64 %1 %2 %3 %4 %5 %6 
        +%ssleay% %1 %2 %3 %4 %5 %6 -a -e -bufsize 113 -k test -in %input% -out %tmp1%
        +%ssleay% %1 %2 %3 %4 %5 %6 -a -d -bufsize 157 -k test -in %tmp1% -out %out1%
        +%cmp% %input% %out1%
        +
        +:err
        diff --git a/vendor/openssl/openssl/ms/tencce.bat b/vendor/openssl/openssl/ms/tencce.bat
        new file mode 100644
        index 000000000..c8b1acd4b
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/tencce.bat
        @@ -0,0 +1,19 @@
        +rem called by testencce
        +
        +echo test %1 %2 %3 %4 %5 %6 
        +cecopy %input% CE:\OpenSSL
        +cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -e -bufsize 113 -k test -in \OpenSSL\%input% -out \OpenSSL\%tmp1%
        +cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -d -bufsize 157 -k test -in \OpenSSL\%tmp1% -out \OpenSSL\%out1%
        +del %out1% >nul 2>&1
        +cecopy CE:\OpenSSL\%out1% .
        +%cmp% %input% %out1%
        +if errorlevel 1 goto err
        +
        +echo test base64 %1 %2 %3 %4 %5 %6 
        +cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -a -e -bufsize 113 -k test -in \OpenSSL\%input% -out \OpenSSL\%tmp1%
        +cerun CE:\OpenSSL\%ssleay% %1 %2 %3 %4 %5 %6 -a -d -bufsize 157 -k test -in \OpenSSL\%tmp1% -out \OpenSSL\%out1%
        +del %out1% >nul 2>&1
        +cecopy CE:\OpenSSL\%out1% .
        +%cmp% %input% %out1%
        +
        +:err
        diff --git a/vendor/openssl/openssl/ms/test.bat b/vendor/openssl/openssl/ms/test.bat
        new file mode 100644
        index 000000000..f490546eb
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/test.bat
        @@ -0,0 +1,185 @@
        +@echo off
        +
        +set test=..\ms
        +set opath=%PATH%
        +PATH=..\ms;%PATH%
        +set OPENSSL_CONF=..\apps\openssl.cnf
        +
        +rem run this from inside the bin directory
        +
        +echo rsa_test
        +rsa_test
        +if errorlevel 1 goto done
        +
        +echo destest
        +destest
        +if errorlevel 1 goto done
        +
        +echo ideatest
        +ideatest
        +if errorlevel 1 goto done
        +
        +echo bftest
        +bftest
        +if errorlevel 1 goto done
        +
        +echo shatest
        +shatest
        +if errorlevel 1 goto done
        +
        +echo sha1test
        +sha1test
        +if errorlevel 1 goto done
        +
        +echo md5test
        +md5test
        +if errorlevel 1 goto done
        +
        +echo rc2test
        +rc2test
        +if errorlevel 1 goto done
        +
        +echo rc4test
        +rc4test
        +if errorlevel 1 goto done
        +
        +echo randtest
        +randtest
        +if errorlevel 1 goto done
        +
        +echo dhtest
        +dhtest
        +if errorlevel 1 goto done
        +
        +echo exptest
        +exptest
        +if errorlevel 1 goto done
        +
        +echo dsatest
        +dsatest
        +if errorlevel 1 goto done
        +
        +echo ectest
        +ectest
        +if errorlevel 1 goto done
        +
        +echo testenc
        +call %test%\testenc openssl
        +if errorlevel 1 goto done
        +
        +echo testpem
        +call %test%\testpem openssl
        +if errorlevel 1 goto done
        +
        +echo testss
        +call %test%\testss openssl
        +if errorlevel 1 goto done
        +
        +set SSL_TEST=ssltest -key keyU.ss -cert certU.ss -c_key keyU.ss -c_cert certU.ss -CAfile certCA.ss
        +
        +echo test sslv2
        +ssltest -ssl2
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with server authentication
        +%SSL_TEST% -ssl2 -server_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with client authentication
        +%SSL_TEST% -ssl2 -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with both client and server authentication
        +%SSL_TEST% -ssl2 -server_auth -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv3
        +ssltest -ssl3
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with server authentication
        +%SSL_TEST% -ssl3 -server_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with client authentication
        +%SSL_TEST% -ssl3 -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with both client and server authentication
        +%SSL_TEST% -ssl3 -server_auth -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3
        +ssltest
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with server authentication
        +%SSL_TEST% -server_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with client authentication
        +%SSL_TEST% -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with both client and server authentication
        +%SSL_TEST% -server_auth -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2 via BIO pair
        +ssltest -bio_pair -ssl2
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with 1024 bit DHE via BIO pair
        +ssltest -bio_pair -dhe1024dsa -v
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with server authentication via BIO pair
        +%SSL_TEST% -bio_pair -ssl2 -server_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with client authentication via BIO pair
        +%SSL_TEST% -bio_pair -ssl2 -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with both client and server authentication via BIO pair
        +%SSL_TEST% -bio_pair -ssl2 -server_auth -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv3 via BIO pair
        +ssltest -bio_pair -ssl3
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with server authentication via BIO pair
        +%SSL_TEST% -bio_pair -ssl3 -server_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with client authentication  via BIO pair
        +%SSL_TEST% -bio_pair -ssl3 -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with both client and server authentication via BIO pair
        +%SSL_TEST% -bio_pair -ssl3 -server_auth -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 via BIO pair
        +ssltest -bio_pair
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with server authentication
        +%SSL_TEST% -bio_pair -server_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with client authentication via BIO pair
        +%SSL_TEST% -bio_pair -client_auth
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with both client and server authentication via BIO pair
        +%SSL_TEST% -bio_pair -server_auth -client_auth
        +if errorlevel 1 goto done
        +
        +echo passed all tests
        +goto end
        +:done
        +echo problems.....
        +:end
        +PATH=%opath%
        diff --git a/vendor/openssl/openssl/ms/testce.bat b/vendor/openssl/openssl/ms/testce.bat
        new file mode 100644
        index 000000000..2ab010be6
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testce.bat
        @@ -0,0 +1,234 @@
        +@echo off
        +
        +cemkdir CE:\OpenSSL
        +
        +set test=..\ms
        +set opath=%PATH%
        +PATH=..\ms;%PATH%
        +cecopy ..\apps\openssl.cnf CE:\OpenSSL
        +set OPENSSL_CONF=\OpenSSL\openssl.cnf
        +set HOME=\OpenSSL
        +set CERUN_PASS_ENV=OPENSSL_CONF HOME
        +
        +rem run this from inside the bin directory
        +
        +rem Copy the DLL's (though they'll only exist if we're in out32dll)
        +if exist libeay32.dll cecopy libeay32.dll CE:\OpenSSL
        +if exist ssleay32.dll cecopy ssleay32.dll CE:\OpenSSL
        +
        +echo rsa_test
        +call %test%\testce2 rsa_test
        +if errorlevel 1 goto done
        +
        +echo destest
        +call %test%\testce2 destest
        +if errorlevel 1 goto done
        +
        +echo ideatest
        +call %test%\testce2 ideatest
        +if errorlevel 1 goto done
        +
        +echo bftest
        +call %test%\testce2 bftest
        +if errorlevel 1 goto done
        +
        +echo shatest
        +call %test%\testce2 shatest
        +if errorlevel 1 goto done
        +
        +echo sha1test
        +call %test%\testce2 sha1test
        +if errorlevel 1 goto done
        +
        +echo md5test
        +call %test%\testce2 md5test
        +if errorlevel 1 goto done
        +
        +echo md2test
        +call %test%\testce2 md2test
        +if errorlevel 1 goto done
        +
        +echo mdc2test
        +call %test%\testce2 mdc2test
        +if errorlevel 1 goto done
        +
        +echo rc2test
        +call %test%\testce2 rc2test
        +if errorlevel 1 goto done
        +
        +echo rc4test
        +call %test%\testce2 rc4test
        +if errorlevel 1 goto done
        +
        +echo randtest
        +call %test%\testce2 randtest
        +if errorlevel 1 goto done
        +
        +echo dhtest
        +call %test%\testce2 dhtest
        +if errorlevel 1 goto done
        +
        +echo exptest
        +call %test%\testce2 exptest
        +if errorlevel 1 goto done
        +
        +echo dsatest
        +call %test%\testce2 dsatest
        +if errorlevel 1 goto done
        +
        +echo testenc
        +call %test%\testencce openssl.exe
        +if errorlevel 1 goto done
        +
        +echo testpem
        +call %test%\testpemce openssl.exe
        +if errorlevel 1 goto done
        +
        +cecopy openssl.exe CE:\OpenSSL
        +
        +echo verify
        +copy ..\certs\*.pem cert.tmp >nul
        +cecopy cert.tmp CE:\OpenSSL
        +cemkdir CE:\OpenSSL\certs
        +rem cecopy ..\certs\*.pem CE:\OpenSSL\certs
        +cecopy ..\certs\ca-cert.pem CE:\OpenSSL\certs
        +cecopy ..\certs\dsa-ca.pem CE:\OpenSSL\certs
        +cecopy ..\certs\dsa-pca.pem CE:\OpenSSL\certs
        +cecopy ..\certs\factory.pem CE:\OpenSSL\certs
        +cecopy ..\certs\ICE-CA.pem CE:\OpenSSL\certs
        +cecopy ..\certs\ICE-root.pem CE:\OpenSSL\certs
        +cecopy ..\certs\ICE-user.pem CE:\OpenSSL\certs
        +cecopy ..\certs\nortelCA.pem CE:\OpenSSL\certs
        +cecopy ..\certs\pca-cert.pem CE:\OpenSSL\certs
        +cecopy ..\certs\RegTP-4R.pem CE:\OpenSSL\certs
        +cecopy ..\certs\RegTP-5R.pem CE:\OpenSSL\certs
        +cecopy ..\certs\RegTP-6R.pem CE:\OpenSSL\certs
        +cecopy ..\certs\rsa-cca.pem CE:\OpenSSL\certs
        +cecopy ..\certs\thawteCb.pem CE:\OpenSSL\certs
        +cecopy ..\certs\thawteCp.pem CE:\OpenSSL\certs
        +cecopy ..\certs\timCA.pem CE:\OpenSSL\certs
        +cecopy ..\certs\tjhCA.pem CE:\OpenSSL\certs
        +cecopy ..\certs\vsign1.pem CE:\OpenSSL\certs
        +cecopy ..\certs\vsign2.pem CE:\OpenSSL\certs
        +cecopy ..\certs\vsign3.pem CE:\OpenSSL\certs
        +cecopy ..\certs\vsignss.pem CE:\OpenSSL\certs
        +cecopy ..\certs\vsigntca.pem CE:\OpenSSL\certs
        +cerun CE:\OpenSSL\openssl verify -CAfile \OpenSSL\cert.tmp \OpenSSL\certs\*.pem
        +
        +echo testss
        +call %test%\testssce openssl.exe
        +if errorlevel 1 goto done
        +
        +cecopy ssltest.exe CE:\OpenSSL
        +cecopy ..\apps\server.pem CE:\OpenSSL
        +cecopy ..\apps\client.pem CE:\OpenSSL
        +
        +echo test sslv2
        +cerun CE:\OpenSSL\ssltest -ssl2
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with server authentication
        +cerun CE:\OpenSSL\ssltest -ssl2 -server_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with client authentication
        +cerun CE:\OpenSSL\ssltest -ssl2 -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with both client and server authentication
        +cerun CE:\OpenSSL\ssltest -ssl2 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv3
        +cerun CE:\OpenSSL\ssltest -ssl3
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with server authentication
        +cerun CE:\OpenSSL\ssltest -ssl3 -server_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with client authentication
        +cerun CE:\OpenSSL\ssltest -ssl3 -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with both client and server authentication
        +cerun CE:\OpenSSL\ssltest -ssl3 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3
        +cerun CE:\OpenSSL\ssltest
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with server authentication
        +cerun CE:\OpenSSL\ssltest -server_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with client authentication
        +cerun CE:\OpenSSL\ssltest -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with both client and server authentication
        +cerun CE:\OpenSSL\ssltest -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2 via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl2
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with 1024 bit DHE via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -dhe1024dsa -v
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with server authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl2 -server_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with client authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl2 -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2 with both client and server authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl2 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv3 via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl3
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with server authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl3 -server_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with client authentication  via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl3 -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv3 with both client and server authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -ssl3 -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 via BIO pair
        +cerun CE:\OpenSSL\ssltest
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with server authentication
        +cerun CE:\OpenSSL\ssltest -bio_pair -server_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with client authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +echo test sslv2/sslv3 with both client and server authentication via BIO pair
        +cerun CE:\OpenSSL\ssltest -bio_pair -server_auth -client_auth -CAfile \OpenSSL\cert.tmp
        +if errorlevel 1 goto done
        +
        +del cert.tmp
        +
        +echo passed all tests
        +goto end
        +:done
        +echo problems.....
        +:end
        +PATH=%opath%
        +
        diff --git a/vendor/openssl/openssl/ms/testce2.bat b/vendor/openssl/openssl/ms/testce2.bat
        new file mode 100644
        index 000000000..24265b948
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testce2.bat
        @@ -0,0 +1,2 @@
        +cecopy %1.exe CE:\OpenSSL
        +cerun CE:\OpenSSL\%1 %2 %3 %4 %5 %6 %7 %8 %9
        diff --git a/vendor/openssl/openssl/ms/testenc.bat b/vendor/openssl/openssl/ms/testenc.bat
        new file mode 100644
        index 000000000..f8e90939e
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testenc.bat
        @@ -0,0 +1,94 @@
        +@echo off
        +echo start testenc
        +
        +path=..\ms;%path%
        +set ssleay=%1%
        +set input=..\ms\testenc.bat
        +set tmp1=..\ms\cipher.out
        +set out1=..\ms\clear.out
        +set cmp=perl ..\ms\cmp.pl
        +
        +cd
        +call tenc.bat enc
        +if errorlevel 1 goto err
        +
        +call tenc.bat rc4
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-cfb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede-cfb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede3-cfb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ofb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede-ofb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede3-ofb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ecb
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede3
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-cbc
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede-cbc
        +if errorlevel 1 goto err
        +
        +call tenc.bat des-ede3-cbc
        +if errorlevel 1 goto err
        +
        +call tenc.bat idea-ecb
        +if errorlevel 1 goto err
        +
        +call tenc.bat idea-cfb
        +if errorlevel 1 goto err
        +
        +call tenc.bat idea-ofb
        +if errorlevel 1 goto err
        +
        +call tenc.bat idea-cbc
        +if errorlevel 1 goto err
        +
        +call tenc.bat rc2-ecb
        +if errorlevel 1 goto err
        +
        +call tenc.bat rc2-cfb
        +if errorlevel 1 goto err
        +
        +call tenc.bat rc2-ofb
        +if errorlevel 1 goto err
        +
        +call tenc.bat rc2-cbc
        +if errorlevel 1 goto err
        +
        +call tenc.bat bf-ecb
        +if errorlevel 1 goto err
        +
        +call tenc.bat bf-cfb
        +if errorlevel 1 goto err
        +
        +call tenc.bat bf-ofb
        +if errorlevel 1 goto err
        +
        +call tenc.bat bf-cbc
        +if errorlevel 1 goto err
        +
        +echo OK
        +del %out1%
        +del %tmp1%
        +:err
        +
        diff --git a/vendor/openssl/openssl/ms/testencce.bat b/vendor/openssl/openssl/ms/testencce.bat
        new file mode 100644
        index 000000000..1da3e0861
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testencce.bat
        @@ -0,0 +1,97 @@
        +@echo off
        +echo start testenc
        +
        +path=..\ms;%path%
        +set ssleay=%1%
        +copy ..\ms\testenc.bat >nul
        +set input=testenc.bat
        +set tmp1=cipher.out
        +set out1=clear.out
        +set cmp=perl ..\ms\cmp.pl
        +
        +cecopy %ssleay% CE:\OpenSSL
        +
        +cd
        +call tencce.bat enc
        +if errorlevel 1 goto err
        +
        +call tencce.bat rc4
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-cfb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede-cfb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede3-cfb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ofb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede-ofb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede3-ofb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ecb
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede3
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-cbc
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede-cbc
        +if errorlevel 1 goto err
        +
        +call tencce.bat des-ede3-cbc
        +if errorlevel 1 goto err
        +
        +call tencce.bat idea-ecb
        +if errorlevel 1 goto err
        +
        +call tencce.bat idea-cfb
        +if errorlevel 1 goto err
        +
        +call tencce.bat idea-ofb
        +if errorlevel 1 goto err
        +
        +call tencce.bat idea-cbc
        +if errorlevel 1 goto err
        +
        +call tencce.bat rc2-ecb
        +if errorlevel 1 goto err
        +
        +call tencce.bat rc2-cfb
        +if errorlevel 1 goto err
        +
        +call tencce.bat rc2-ofb
        +if errorlevel 1 goto err
        +
        +call tencce.bat rc2-cbc
        +if errorlevel 1 goto err
        +
        +call tencce.bat bf-ecb
        +if errorlevel 1 goto err
        +
        +call tencce.bat bf-cfb
        +if errorlevel 1 goto err
        +
        +call tencce.bat bf-ofb
        +if errorlevel 1 goto err
        +
        +call tencce.bat bf-cbc
        +if errorlevel 1 goto err
        +
        +echo OK
        +del %out1% >nul 2>&1
        +del %tmp1% >nul 2>&1
        +:err
        +
        diff --git a/vendor/openssl/openssl/ms/testpem.bat b/vendor/openssl/openssl/ms/testpem.bat
        new file mode 100644
        index 000000000..8b2e844d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testpem.bat
        @@ -0,0 +1,32 @@
        +@echo off
        +set ssleay=%1%
        +set tmp1=pem.out
        +set cmp=fc.exe
        +
        +call tpem.bat crl ..\test\testcrl.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat pkcs7 ..\test\testp7.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat req ..\test\testreq2.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat rsa ..\test\testrsa.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat x509 ..\test\testx509.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat x509 ..\test\v3-cert1.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat x509 ..\test\v3-cert1.pem
        +if errorlevel 1 goto err
        +
        +call tpem.bat sess_id ..\test\testsid.pem
        +if errorlevel 1 goto err
        +
        +echo OK
        +del %tmp1%
        +:err
        diff --git a/vendor/openssl/openssl/ms/testpemce.bat b/vendor/openssl/openssl/ms/testpemce.bat
        new file mode 100644
        index 000000000..ac64a7912
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testpemce.bat
        @@ -0,0 +1,42 @@
        +@echo off
        +set ssleay=%1%
        +set tmp1=pem.out
        +set cmp=fc.exe
        +
        +cecopy %ssleay% CE:\OpenSSL
        +
        +copy ..\test\testcrl.pem >nul
        +call tpemce.bat crl testcrl.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\testp7.pem >nul
        +call tpemce.bat pkcs7 testp7.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\testreq2.pem >nul
        +call tpemce.bat req testreq2.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\testrsa.pem >nul
        +call tpemce.bat rsa testrsa.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\testx509.pem >nul
        +call tpemce.bat x509 testx509.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\v3-cert1.pem >nul
        +call tpemce.bat x509 v3-cert1.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\v3-cert1.pem >nul
        +call tpemce.bat x509 v3-cert1.pem
        +if errorlevel 1 goto err
        +
        +copy ..\test\testsid.pem >nul
        +call tpemce.bat sess_id testsid.pem
        +if errorlevel 1 goto err
        +
        +echo OK
        +del %tmp1% >nul 2>&1
        +:err
        diff --git a/vendor/openssl/openssl/ms/testss.bat b/vendor/openssl/openssl/ms/testss.bat
        new file mode 100644
        index 000000000..5afa131db
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testss.bat
        @@ -0,0 +1,98 @@
        +@echo off
        +
        +rem set ssleay=..\out\ssleay
        +set ssleay=%1
        +
        +set reqcmd=%ssleay% req
        +set x509cmd=%ssleay% x509 -sha1
        +set verifycmd=%ssleay% verify
        +
        +set CAkey=keyCA.ss
        +set CAcert=certCA.ss
        +set CAserial=certCA.srl
        +set CAreq=reqCA.ss
        +set CAconf=..\test\CAss.cnf
        +set CAreq2=req2CA.ss	
        +
        +set Uconf=..\test\Uss.cnf
        +set Ukey=keyU.ss
        +set Ureq=reqU.ss
        +set Ucert=certU.ss
        +
        +echo make a certificate request using 'req'
        +%reqcmd% -config %CAconf% -out %CAreq% -keyout %CAkey% -new
        +if errorlevel 1 goto e_req
        +
        +echo convert the certificate request into a self signed certificate using 'x509'
        +%x509cmd% -CAcreateserial -in %CAreq% -days 30 -req -out %CAcert% -signkey %CAkey% >err.ss
        +if errorlevel 1 goto e_x509
        +
        +echo --
        +echo convert a certificate into a certificate request using 'x509'
        +%x509cmd% -in %CAcert% -x509toreq -signkey %CAkey% -out %CAreq2% >err.ss
        +if errorlevel 1 goto e_x509_2
        +
        +%reqcmd% -verify -in %CAreq% -noout
        +if errorlevel 1 goto e_vrfy_1
        +
        +%reqcmd% -verify -in %CAreq2% -noout
        +if errorlevel 1 goto e_vrfy_2
        +
        +%verifycmd% -CAfile %CAcert% %CAcert%
        +if errorlevel 1 goto e_vrfy_3
        +
        +echo --
        +echo make another certificate request using 'req'
        +%reqcmd% -config %Uconf% -out %Ureq% -keyout %Ukey% -new >err.ss
        +if errorlevel 1 goto e_req_gen
        +
        +echo --
        +echo sign certificate request with the just created CA via 'x509'
        +%x509cmd% -CAcreateserial -in %Ureq% -days 30 -req -out %Ucert% -CA %CAcert% -CAkey %CAkey% -CAserial %CAserial%
        +if errorlevel 1 goto e_x_sign
        +
        +%verifycmd% -CAfile %CAcert% %Ucert%
        +echo --
        +echo Certificate details
        +%x509cmd% -subject -issuer -startdate -enddate -noout -in %Ucert%
        +
        +echo Everything appeared to work
        +echo --
        +echo The generated CA certificate is %CAcert%
        +echo The generated CA private key is %CAkey%
        +echo The current CA signing serial number is in %CAserial%
        +
        +echo The generated user certificate is %Ucert%
        +echo The generated user private key is %Ukey%
        +echo --
        +
        +del err.ss
        +
        +goto end
        +
        +:e_req
        +echo error using 'req' to generate a certificate request
        +goto end
        +:e_x509
        +echo error using 'x509' to self sign a certificate request
        +goto end
        +:e_x509_2
        +echo error using 'x509' convert a certificate to a certificate request
        +goto end
        +:e_vrfy_1
        +echo first generated request is invalid
        +goto end
        +:e_vrfy_2
        +echo second generated request is invalid
        +goto end
        +:e_vrfy_3
        +echo first generated cert is invalid
        +goto end
        +:e_req_gen
        +echo error using 'req' to generate a certificate request
        +goto end
        +:e_x_sign
        +echo error using 'x509' to sign a certificate request
        +goto end
        +
        +:end
        diff --git a/vendor/openssl/openssl/ms/testssce.bat b/vendor/openssl/openssl/ms/testssce.bat
        new file mode 100644
        index 000000000..18381ed2f
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/testssce.bat
        @@ -0,0 +1,104 @@
        +rem set ssleay=..\out\ssleay
        +set ssleay=%1
        +
        +set reqcmd=%ssleay% req
        +set x509cmd=%ssleay% x509
        +set verifycmd=%ssleay% verify
        +
        +set CAkey=\OpenSSL\keyCA.ss
        +set CAcert=\OpenSSL\certCA.ss
        +set CAserial=\OpenSSL\certCA.srl
        +set CAreq=\OpenSSL\reqCA.ss
        +cecopy ..\test\CAss.cnf CE:\OpenSSL
        +set CAconf=\OpenSSL\CAss.cnf
        +set CAreq2=\OpenSSL\req2CA.ss	
        +
        +cecopy ..\test\Uss.cnf CE:\OpenSSL
        +set Uconf=\OpenSSL\Uss.cnf
        +set Ukey=\OpenSSL\keyU.ss
        +set Ureq=\OpenSSL\reqU.ss
        +set Ucert=\OpenSSL\certU.ss
        +
        +echo make a certificate request using 'req'
        +cerun CE:\OpenSSL\%reqcmd% -config %CAconf% -out %CAreq% -keyout %CAkey% -new
        +if errorlevel 1 goto e_req
        +
        +echo convert the certificate request into a self signed certificate using 'x509'
        +cerun CE:\OpenSSL\%x509cmd% -CAcreateserial -in %CAreq% -days 30 -req -out %CAcert% -signkey %CAkey% "> \OpenSSL\err.ss"
        +if errorlevel 1 goto e_x509
        +
        +echo --
        +echo convert a certificate into a certificate request using 'x509'
        +cerun CE:\OpenSSL\%x509cmd% -in %CAcert% -x509toreq -signkey %CAkey% -out %CAreq2% "> \OpenSSL\err.ss"
        +if errorlevel 1 goto e_x509_2
        +
        +cerun CE:\OpenSSL\%reqcmd% -verify -in %CAreq% -noout
        +if errorlevel 1 goto e_vrfy_1
        +
        +cerun CE:\OpenSSL\%reqcmd% -verify -in %CAreq2% -noout
        +if errorlevel 1 goto e_vrfy_2
        +
        +cerun CE:\OpenSSL\%verifycmd% -CAfile %CAcert% %CAcert%
        +if errorlevel 1 goto e_vrfy_3
        +
        +echo --
        +echo make another certificate request using 'req'
        +cerun CE:\OpenSSL\%reqcmd% -config %Uconf% -out %Ureq% -keyout %Ukey% -new "> \OpenSSL\err.ss"
        +if errorlevel 1 goto e_req_gen
        +
        +echo --
        +echo sign certificate request with the just created CA via 'x509'
        +cerun CE:\OpenSSL\%x509cmd% -CAcreateserial -in %Ureq% -days 30 -req -out %Ucert% -CA %CAcert% -CAkey %CAkey% -CAserial %CAserial%
        +if errorlevel 1 goto e_x_sign
        +
        +cerun CE:\OpenSSL\%verifycmd% -CAfile %CAcert% %Ucert%
        +echo --
        +echo Certificate details
        +cerun CE:\OpenSSL\%x509cmd% -subject -issuer -startdate -enddate -noout -in %Ucert%
        +
        +cecopy CE:%CAcert% .
        +cecopy CE:%CAkey% .
        +cecopy CE:%CAserial% .
        +cecopy CE:%Ucert% .
        +cecopy CE:%Ukey% .
        +
        +echo Everything appeared to work
        +echo --
        +echo The generated CA certificate is %CAcert%
        +echo The generated CA private key is %CAkey%
        +echo The current CA signing serial number is in %CAserial%
        +
        +echo The generated user certificate is %Ucert%
        +echo The generated user private key is %Ukey%
        +echo --
        +
        +cedel CE:\OpenSSL\err.ss
        +
        +goto end
        +
        +:e_req
        +echo error using 'req' to generate a certificate request
        +goto end
        +:e_x509
        +echo error using 'x509' to self sign a certificate request
        +goto end
        +:e_x509_2
        +echo error using 'x509' convert a certificate to a certificate request
        +goto end
        +:e_vrfy_1
        +echo first generated request is invalid
        +goto end
        +:e_vrfy_2
        +echo second generated request is invalid
        +goto end
        +:e_vrfy_3
        +echo first generated cert is invalid
        +goto end
        +:e_req_gen
        +echo error using 'req' to generate a certificate request
        +goto end
        +:e_x_sign
        +echo error using 'x509' to sign a certificate request
        +goto end
        +
        +:end
        diff --git a/vendor/openssl/openssl/ms/tlhelp32.h b/vendor/openssl/openssl/ms/tlhelp32.h
        new file mode 100644
        index 000000000..8f4222e34
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/tlhelp32.h
        @@ -0,0 +1,136 @@
        +/*
        +	tlhelp32.h - Include file for Tool help functions.
        +
        +	Written by Mumit Khan <khan@nanotech.wisc.edu>
        +
        +	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/vendor/openssl/openssl/ms/tpem.bat b/vendor/openssl/openssl/ms/tpem.bat
        new file mode 100644
        index 000000000..cd01792e9
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/tpem.bat
        @@ -0,0 +1,6 @@
        +rem called by testpem
        +
        +echo test %1 %2
        +%ssleay% %1 -in %2 -out %tmp1%
        +%cmp% %2 %tmp1%
        +
        diff --git a/vendor/openssl/openssl/ms/tpemce.bat b/vendor/openssl/openssl/ms/tpemce.bat
        new file mode 100644
        index 000000000..483f559cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/tpemce.bat
        @@ -0,0 +1,8 @@
        +rem called by testpemce
        +
        +echo test %1 %2
        +cecopy %2 CE:\OpenSSL
        +cerun CE:\OpenSSL\%ssleay% %1 -in \OpenSSL\%2 -out \OpenSSL\%tmp1%
        +del %tmp1% >nul 2>&1
        +cecopy CE:\OpenSSL\%tmp1% .
        +%cmp% %2 %tmp1%
        diff --git a/vendor/openssl/openssl/ms/uplink-common.pl b/vendor/openssl/openssl/ms/uplink-common.pl
        new file mode 100644
        index 000000000..1d20e6e03
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink-common.pl
        @@ -0,0 +1,22 @@
        +#!/usr/bin/env perl
        +#
        +# pull APPLINK_MAX value from applink.c...
        +$applink_c=$0;
        +$applink_c=~s|[^/\\]+$||g;
        +$applink_c.="applink.c";
        +open(INPUT,$applink_c) || die "can't open $applink_c: $!";
        +@max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
        +close(INPUT);
        +($#max==0) or die "can't find APPLINK_MAX in $applink_c";
        +
        +$max[0]=~/APPLINK_MAX\s+(\d+)/;
        +$N=$1;	# number of entries in OPENSSL_UplinkTable not including
        +	# OPENSSL_UplinkTable[0], which contains this value...
        +
        +1;
        +
        +# Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
        +# which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
        +# and then dereference themselves. Latter shall result in endless
        +# loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
        +# something else, e.g. as 'table[index]=unimplemented;'...
        diff --git a/vendor/openssl/openssl/ms/uplink-ia64.pl b/vendor/openssl/openssl/ms/uplink-ia64.pl
        new file mode 100644
        index 000000000..4204c73d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink-ia64.pl
        @@ -0,0 +1,50 @@
        +#!/usr/bin/env perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC,"${dir}.");
        +
        +require "uplink-common.pl";
        +
        +local $V=8;	# max number of args uplink functions may accept...
        +my $loc0 = "r".(32+$V);
        +print <<___;
        +.text
        +.global	OPENSSL_Uplink#
        +.type	OPENSSL_Uplink#,\@function
        +
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +.proc	lazy$i#
        +lazy$i:
        +	.prologue
        +{ .mii;	.save	ar.pfs,$loc0
        +	alloc	loc0=ar.pfs,$V,3,2,0
        +	.save	b0,loc1
        +	mov	loc1=b0
        +	addl	loc2=\@ltoff(OPENSSL_UplinkTable#),gp	};;
        +	.body
        +{ .mmi;	ld8	out0=[loc2]
        +	mov	out1=$i					};;
        +{ .mib;	add	loc2=8*$i,out0
        +	br.call.sptk.many	b0=OPENSSL_Uplink#	};;
        +{ .mmi;	ld8	r31=[loc2];;
        +	ld8	r30=[r31],8				};;
        +{ .mii;	ld8	gp=[r31]
        +	mov	b6=r30
        +	mov	b0=loc1					};;
        +{ .mib;	mov	ar.pfs=loc0
        +	br.many	b6					};;
        +.endp	lazy$i#
        +
        +___
        +}
        +print <<___;
        +.data
        +.global OPENSSL_UplinkTable#
        +OPENSSL_UplinkTable:    data8   $N      // amount of following entries
        +___
        +for ($i=1;$i<=$N;$i++) {   print "      data8   \@fptr(lazy$i#)\n";   }
        +print <<___;
        +.size   OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
        +___
        diff --git a/vendor/openssl/openssl/ms/uplink-x86.pl b/vendor/openssl/openssl/ms/uplink-x86.pl
        new file mode 100644
        index 000000000..0dffc14fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink-x86.pl
        @@ -0,0 +1,33 @@
        +#!/usr/bin/env perl
        +
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +push(@INC, "${dir}.", "${dir}../crypto/perlasm");
        +require "x86asm.pl";
        +
        +require "uplink-common.pl";
        +
        +&asm_init($ARGV[0],"uplink-x86");
        +
        +&external_label("OPENSSL_Uplink");
        +&public_label("OPENSSL_UplinkTable");
        +
        +for ($i=1;$i<=$N;$i++) {
        +&function_begin_B("_\$lazy${i}");
        +	&lea	("eax",&DWP(&label("OPENSSL_UplinkTable")));
        +	&push	("eax");
        +	&push	($i);
        +	&call	(&label("OPENSSL_Uplink"));
        +	&add	("esp",8);
        +	&pop	("eax");
        +	&jmp_ptr(&DWP(4*$i,"eax"));
        +&function_end_B("_\$lazy${i}");
        +}
        +
        +&dataseg();
        +&align(4);
        +&set_label("OPENSSL_UplinkTable");
        +&data_word($N);
        +for ($i=1;$i<=$N;$i++) {
        +&data_word(&label("_\$lazy${i}"));
        +}
        +&asm_finish();
        diff --git a/vendor/openssl/openssl/ms/uplink-x86_64.pl b/vendor/openssl/openssl/ms/uplink-x86_64.pl
        new file mode 100644
        index 000000000..48bf559ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink-x86_64.pl
        @@ -0,0 +1,65 @@
        +#!/usr/bin/env perl
        +
        +$output=shift;
        +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
        +open OUT,"| \"$^X\" ${dir}../crypto/perlasm/x86_64-xlate.pl $output";
        +*STDOUT=*OUT;
        +push(@INC,"${dir}.");
        +
        +require "uplink-common.pl";
        +
        +$prefix="_lazy";
        +
        +print <<___;
        +.text
        +.extern	OPENSSL_Uplink
        +.globl	OPENSSL_UplinkTable
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +.type	$prefix${i},\@abi-omnipotent
        +.align	16
        +$prefix${i}:
        +	.byte	0x48,0x83,0xEC,0x28	# sub rsp,40
        +	mov	%rcx,48(%rsp)
        +	mov	%rdx,56(%rsp)
        +	mov	%r8,64(%rsp)
        +	mov	%r9,72(%rsp)
        +	lea	OPENSSL_UplinkTable(%rip),%rcx
        +	mov	\$$i,%rdx
        +	call	OPENSSL_Uplink
        +	mov	48(%rsp),%rcx
        +	mov	56(%rsp),%rdx
        +	mov	64(%rsp),%r8
        +	mov	72(%rsp),%r9
        +	lea	OPENSSL_UplinkTable(%rip),%rax
        +	add	\$40,%rsp
        +	jmp	*8*$i(%rax)
        +$prefix${i}_end:
        +.size	$prefix${i},.-$prefix${i}
        +___
        +}
        +print <<___;
        +.data
        +OPENSSL_UplinkTable:
        +        .quad   $N
        +___
        +for ($i=1;$i<=$N;$i++) {   print "      .quad   $prefix$i\n";   }
        +print <<___;
        +.section	.pdata,"r"
        +.align		4
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +	.rva	$prefix${i},$prefix${i}_end,${prefix}_unwind_info
        +___
        +}
        +print <<___;
        +.section	.xdata,"r"
        +.align		8
        +${prefix}_unwind_info:
        +	.byte	0x01,0x04,0x01,0x00
        +	.byte	0x04,0x42,0x00,0x00
        +___
        +
        +close STDOUT;
        diff --git a/vendor/openssl/openssl/ms/uplink.c b/vendor/openssl/openssl/ms/uplink.c
        new file mode 100644
        index 000000000..6d59cb1f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink.c
        @@ -0,0 +1,117 @@
        +#if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE)
        +#define UNICODE
        +#endif
        +#if defined(UNICODE) && !defined(_UNICODE)
        +#define _UNICODE
        +#endif
        +#if defined(_UNICODE) && !defined(UNICODE)
        +#define UNICODE
        +#endif
        +
        +#include <windows.h>
        +#include <tchar.h>
        +#include <stdio.h>
        +#include "uplink.h"
        +void OPENSSL_showfatal(const char *,...);
        +
        +static TCHAR msg[128];
        +
        +static void unimplemented (void)
        +{   OPENSSL_showfatal (sizeof(TCHAR)==sizeof(char)?"%s\n":"%S\n",msg);
        +    ExitProcess (1);
        +}
        +
        +void OPENSSL_Uplink (volatile void **table, int index)
        +{ static HMODULE volatile apphandle=NULL;
        +  static void ** volatile applinktable=NULL;
        +  int len;
        +  void (*func)(void)=unimplemented;
        +  HANDLE h;
        +  void **p;
        +
        +    /* Note that the below code is not MT-safe in respect to msg
        +     * buffer, but what's the worst thing that can happen? Error
        +     * message might be misleading or corrupted. As error condition
        +     * is fatal and should never be risen, I accept the risk... */
        +    /* One can argue that I should have used InterlockedExchangePointer
        +     * or something to update static variables and table[]. Well,
        +     * store instructions are as atomic as they can get and assigned
        +     * values are effectively constant... So that volatile qualifier
        +     * should be sufficient [it prohibits compiler to reorder memory
        +     * access instructions]. */
        +    do {
        +	len = _sntprintf (msg,sizeof(msg)/sizeof(TCHAR),
        +			  _T("OPENSSL_Uplink(%p,%02X): "),table,index);
        +	_tcscpy (msg+len,_T("unimplemented function"));
        +
        +	if ((h=apphandle)==NULL)
        +	{   if  ((h=GetModuleHandle(NULL))==NULL)
        +	    {	apphandle=(HMODULE)-1;
        +		_tcscpy (msg+len,_T("no host application"));
        +		break;
        +	    }
        +	    apphandle = h;
        +	}
        +	if ((h=apphandle)==(HMODULE)-1) /* revalidate */
        +	    break;
        +
        +	if (applinktable==NULL)
        +	{ void**(*applink)();
        +
        +	    applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink");
        +	    if (applink==NULL)
        +	    {	apphandle=(HMODULE)-1;
        +		_tcscpy (msg+len,_T("no OPENSSL_Applink"));
        +		break;
        +	    }
        +	    p = (*applink)();
        +	    if (p==NULL)
        +	    {	apphandle=(HMODULE)-1;
        +		_tcscpy (msg+len,_T("no ApplinkTable"));
        +		break;
        +	    }
        +	    applinktable = p;
        +	}
        +	else
        +	    p = applinktable;
        +
        +	if (index > (int)p[0])
        +	    break;
        +
        +	if (p[index]) func = p[index];
        +    } while (0);
        +
        +    table[index] = func;
        +}    
        +
        +#if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM)
        +#define LAZY(i)		\
        +__declspec(naked) static void lazy##i (void) { 	\
        +	_asm	push i				\
        +	_asm	push OFFSET OPENSSL_UplinkTable	\
        +	_asm	call OPENSSL_Uplink		\
        +	_asm	add  esp,8			\
        +	_asm	jmp  OPENSSL_UplinkTable+4*i	}
        +
        +#if APPLINK_MAX>25
        +#error "Add more stubs..."
        +#endif
        +/* make some in advance... */
        +LAZY(1)  LAZY(2)  LAZY(3)  LAZY(4)  LAZY(5)
        +LAZY(6)  LAZY(7)  LAZY(8)  LAZY(9)  LAZY(10)
        +LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15)
        +LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20)
        +LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25)
        +void *OPENSSL_UplinkTable[] = {
        +	(void *)APPLINK_MAX,
        +	lazy1, lazy2, lazy3, lazy4, lazy5,
        +	lazy6, lazy7, lazy8, lazy9, lazy10,
        +	lazy11,lazy12,lazy13,lazy14,lazy15,
        +	lazy16,lazy17,lazy18,lazy19,lazy20,
        +	lazy21,lazy22,lazy23,lazy24,lazy25,
        +};
        +#endif
        +
        +#ifdef SELFTEST
        +main() {  UP_fprintf(UP_stdout,"hello, world!\n"); }
        +#endif
        diff --git a/vendor/openssl/openssl/ms/uplink.h b/vendor/openssl/openssl/ms/uplink.h
        new file mode 100644
        index 000000000..4881ba7d4
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink.h
        @@ -0,0 +1,29 @@
        +#define APPMACROS_ONLY
        +#include "applink.c"
        +
        +extern void *OPENSSL_UplinkTable[];
        +
        +#define UP_stdin  (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDIN])()
        +#define UP_stdout (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDOUT])()
        +#define UP_stderr (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDERR])()
        +#define UP_fprintf (*(int (*)(void *,const char *,...))OPENSSL_UplinkTable[APPLINK_FPRINTF])
        +#define UP_fgets  (*(char *(*)(char *,int,void *))OPENSSL_UplinkTable[APPLINK_FGETS])
        +#define UP_fread  (*(size_t (*)(void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FREAD])
        +#define UP_fwrite (*(size_t (*)(const void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FWRITE])
        +#define UP_fsetmod (*(int (*)(void *,char))OPENSSL_UplinkTable[APPLINK_FSETMOD])
        +#define UP_feof   (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FEOF])
        +#define UP_fclose (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FCLOSE])
        +
        +#define UP_fopen  (*(void *(*)(const char *,const char *))OPENSSL_UplinkTable[APPLINK_FOPEN])
        +#define UP_fseek  (*(int (*)(void *,long,int))OPENSSL_UplinkTable[APPLINK_FSEEK])
        +#define UP_ftell  (*(long (*)(void *))OPENSSL_UplinkTable[APPLINK_FTELL])
        +#define UP_fflush (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FFLUSH])
        +#define UP_ferror (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FERROR])
        +#define UP_clearerr (*(void (*)(void *))OPENSSL_UplinkTable[APPLINK_CLEARERR])
        +#define UP_fileno (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FILENO])
        +
        +#define UP_open   (*(int (*)(const char *,int,...))OPENSSL_UplinkTable[APPLINK_OPEN])
        +#define UP_read   (*(ossl_ssize_t (*)(int,void *,size_t))OPENSSL_UplinkTable[APPLINK_READ])
        +#define UP_write  (*(ossl_ssize_t (*)(int,const void *,size_t))OPENSSL_UplinkTable[APPLINK_WRITE])
        +#define UP_lseek  (*(long (*)(int,long,int))OPENSSL_UplinkTable[APPLINK_LSEEK])
        +#define UP_close  (*(int (*)(int))OPENSSL_UplinkTable[APPLINK_CLOSE])
        diff --git a/vendor/openssl/openssl/ms/uplink.pl b/vendor/openssl/openssl/ms/uplink.pl
        new file mode 100644
        index 000000000..102400e88
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/uplink.pl
        @@ -0,0 +1,204 @@
        +#!/usr/bin/env perl
        +#
        +# For Microsoft CL this is implemented as inline assembler. So that
        +# even though this script can generate even Win32 code, we'll be
        +# using it primarily to generate Win64 modules. Both IA-64 and AMD64
        +# are supported...
        +
        +# pull APPLINK_MAX value from applink.c...
        +$applink_c=$0;
        +$applink_c=~s|[^/\\]+$||g;
        +$applink_c.="applink.c";
        +open(INPUT,$applink_c) || die "can't open $applink_c: $!";
        +@max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
        +close(INPUT);
        +($#max==0) or die "can't find APPLINK_MAX in $applink_c";
        +
        +$max[0]=~/APPLINK_MAX\s+(\d+)/;
        +$N=$1;	# number of entries in OPENSSL_UplinkTable not including
        +	# OPENSSL_UplinkTable[0], which contains this value...
        +
        +# Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
        +# which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
        +# and then dereference themselves. Latter shall result in endless
        +# loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
        +# something else, e.g. as 'table[index]=unimplemented;'...
        +
        +$arg = shift;
        +#( defined shift || open STDOUT,">$arg" ) || die "can't open $arg: $!";
        +
        +if ($arg =~ /win32n/)	{ ia32nasm();  }
        +elsif ($arg =~ /win32/)	{ ia32masm();  }
        +elsif ($arg =~ /coff/)	{ ia32gas();   }
        +elsif ($arg =~ /win64i/ or $arg =~ /ia64/)	{ ia64ias();   }
        +elsif ($arg =~ /win64a/ or $arg =~ /amd64/)	{ amd64masm(); }
        +else	{ die "nonsense $arg"; }
        +
        +sub ia32gas() {
        +print <<___;
        +.text
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +.def	.Lazy$i;	.scl	3;	.type	32;	.endef
        +.align	4
        +.Lazy$i:
        +	pushl	\$$i
        +	pushl	\$_OPENSSL_UplinkTable
        +	call	_OPENSSL_Uplink
        +	addl	\$8,%esp
        +	jmp	*(_OPENSSL_UplinkTable+4*$i)
        +___
        +}
        +print <<___;
        +.data
        +.align	4
        +.globl  _OPENSSL_UplinkTable
        +_OPENSSL_UplinkTable:
        +	.long	$N
        +___
        +for ($i=1;$i<=$N;$i++) {   print "	.long	.Lazy$i\n";   }
        +}
        +
        +sub ia32masm() {
        +print <<___;
        +.386P
        +.model	FLAT
        +
        +_DATA	SEGMENT
        +PUBLIC	_OPENSSL_UplinkTable
        +_OPENSSL_UplinkTable	DD	$N	; amount of following entries
        +___
        +for ($i=1;$i<=$N;$i++) {   print "	DD	FLAT:\$lazy$i\n";   }
        +print <<___;
        +_DATA	ENDS
        +
        +_TEXT	SEGMENT
        +EXTRN	_OPENSSL_Uplink:NEAR
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +ALIGN	4
        +\$lazy$i	PROC NEAR
        +	push	$i
        +	push	OFFSET FLAT:_OPENSSL_UplinkTable
        +	call	_OPENSSL_Uplink
        +	add	esp,8
        +	jmp	DWORD PTR _OPENSSL_UplinkTable+4*$i
        +\$lazy$i	ENDP
        +___
        +}
        +print <<___;
        +ALIGN	4
        +_TEXT	ENDS
        +END
        +___
        +}
        +
        +sub ia32nasm() {
        +print <<___;
        +SEGMENT	.data
        +GLOBAL	_OPENSSL_UplinkTable
        +_OPENSSL_UplinkTable	DD	$N	; amount of following entries
        +___
        +for ($i=1;$i<=$N;$i++) {   print "	DD	\$lazy$i\n";   }
        +print <<___;
        +
        +SEGMENT	.text
        +EXTERN	_OPENSSL_Uplink
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +ALIGN	4
        +\$lazy$i:
        +	push	$i
        +	push	_OPENSSL_UplinkTable
        +	call	_OPENSSL_Uplink
        +	add	esp,8
        +	jmp	[_OPENSSL_UplinkTable+4*$i]
        +___
        +}
        +print <<___;
        +ALIGN	4
        +END
        +___
        +}
        +
        +sub ia64ias () {
        +local $V=8;	# max number of args uplink functions may accept...
        +print <<___;
        +.data
        +.global	OPENSSL_UplinkTable#
        +OPENSSL_UplinkTable:	data8	$N	// amount of following entries
        +___
        +for ($i=1;$i<=$N;$i++) {   print "	data8	\@fptr(lazy$i#)\n";   }
        +print <<___;
        +.size	OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
        +
        +.text
        +.global	OPENSSL_Uplink#
        +.type	OPENSSL_Uplink#,\@function
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +.proc	lazy$i
        +lazy$i:
        +{ .mii;	alloc	loc0=ar.pfs,$V,3,2,0
        +	mov	loc1=b0
        +	addl	loc2=\@ltoff(OPENSSL_UplinkTable#),gp	};;
        +{ .mmi;	ld8	out0=[loc2]
        +	mov	out1=$i					};;
        +{ .mib;	adds	loc2=8*$i,out0
        +	br.call.sptk.many	b0=OPENSSL_Uplink#	};;
        +{ .mmi;	ld8	r31=[loc2];;
        +	ld8	r30=[r31],8				};;
        +{ .mii;	ld8	gp=[r31]
        +	mov	b6=r30
        +	mov	b0=loc1					};;
        +{ .mib; mov	ar.pfs=loc0
        +	br.many	b6					};;
        +.endp	lazy$i#
        +___
        +}
        +}
        +
        +sub amd64masm() {
        +print <<___;
        +_DATA	SEGMENT
        +PUBLIC	OPENSSL_UplinkTable
        +OPENSSL_UplinkTable	DQ	$N
        +___
        +for ($i=1;$i<=$N;$i++) {   print "	DQ	\$lazy$i\n";   }
        +print <<___;
        +_DATA	ENDS
        +
        +_TEXT	SEGMENT
        +EXTERN	OPENSSL_Uplink:PROC
        +___
        +for ($i=1;$i<=$N;$i++) {
        +print <<___;
        +ALIGN	4
        +\$lazy$i	PROC
        +	push	r9
        +	push	r8
        +	push	rdx
        +	push	rcx
        +	sub	rsp,40
        +	lea	rcx,OFFSET OPENSSL_UplinkTable
        +	mov	rdx,$i
        +	call	OPENSSL_Uplink
        +	add	rsp,40
        +	pop	rcx
        +	pop	rdx
        +	pop	r8
        +	pop	r9
        +	jmp	QWORD PTR OPENSSL_UplinkTable+8*$i
        +\$lazy$i	ENDP
        +___
        +}
        +print <<___;
        +_TEXT	ENDS
        +END
        +___
        +}
        +
        diff --git a/vendor/openssl/openssl/ms/x86asm.bat b/vendor/openssl/openssl/ms/x86asm.bat
        new file mode 100644
        index 000000000..03563c6b0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ms/x86asm.bat
        @@ -0,0 +1,57 @@
        +
        +@echo off
        +echo Generating x86 assember
        +
        +echo Bignum
        +cd crypto\bn\asm
        +perl x86.pl win32n > bn-win32.asm
        +cd ..\..\..
        +
        +echo DES
        +cd crypto\des\asm
        +perl des-586.pl win32n > d-win32.asm
        +cd ..\..\..
        +
        +echo "crypt(3)"
        +
        +cd crypto\des\asm
        +perl crypt586.pl win32n > y-win32.asm
        +cd ..\..\..
        +
        +echo Blowfish
        +
        +cd crypto\bf\asm
        +perl bf-586.pl win32n > b-win32.asm
        +cd ..\..\..
        +
        +echo CAST5
        +cd crypto\cast\asm
        +perl cast-586.pl win32n > c-win32.asm
        +cd ..\..\..
        +
        +echo RC4
        +cd crypto\rc4\asm
        +perl rc4-586.pl win32n > r4-win32.asm
        +cd ..\..\..
        +
        +echo MD5
        +cd crypto\md5\asm
        +perl md5-586.pl win32n > m5-win32.asm
        +cd ..\..\..
        +
        +echo SHA1
        +cd crypto\sha\asm
        +perl sha1-586.pl win32n > s1-win32.asm
        +cd ..\..\..
        +
        +echo RIPEMD160
        +cd crypto\ripemd\asm
        +perl rmd-586.pl win32n > rm-win32.asm
        +cd ..\..\..
        +
        +echo RC5\32
        +cd crypto\rc5\asm
        +perl rc5-586.pl win32n > r5-win32.asm
        +cd ..\..\..
        +
        +echo on
        diff --git a/vendor/openssl/openssl/openssl.doxy b/vendor/openssl/openssl/openssl.doxy
        new file mode 100644
        index 000000000..479c31147
        --- /dev/null
        +++ b/vendor/openssl/openssl/openssl.doxy
        @@ -0,0 +1,7 @@
        +PROJECT_NAME=OpenSSL
        +GENERATE_LATEX=no
        +OUTPUT_DIRECTORY=doxygen
        +INPUT=ssl include
        +FILE_PATTERNS=*.c *.h
        +RECURSIVE=yes
        +PREDEFINED=DOXYGEN
        diff --git a/vendor/openssl/openssl/openssl.spec b/vendor/openssl/openssl/openssl.spec
        new file mode 100644
        index 000000000..8ad98b363
        --- /dev/null
        +++ b/vendor/openssl/openssl/openssl.spec
        @@ -0,0 +1,213 @@
        +%define _unpackaged_files_terminate_build 0
        +%define libmaj 1
        +%define libmin 0
        +%define librel 1
        +%define librev e
        +Release: 1
        +
        +%define openssldir /var/ssl
        +
        +Summary: Secure Sockets Layer and cryptography libraries and tools
        +Name: openssl
        +#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 <djm@mindrot.org>
        +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
        +%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
        +%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 --openssldir=%{openssldir}
        +
        +perl util/perlpath.pl /usr/bin/perl
        +
        +%ifarch i386 i486 i586 i686
        +./Configure %{CONFIG_FLAGS} linux-elf shared
        +%endif
        +%ifarch ppc
        +./Configure %{CONFIG_FLAGS} linux-ppc shared
        +%endif
        +%ifarch alpha
        +./Configure %{CONFIG_FLAGS} linux-alpha shared
        +%endif
        +%ifarch x86_64
        +./Configure %{CONFIG_FLAGS} linux-x86_64 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 MANDIR=/usr/man MANSUFFIX=ssl INSTALL_PREFIX="$RPM_BUILD_ROOT" install
        +
        +# Make backwards-compatibility symlink to ssleay
        +ln -sf /usr/bin/openssl $RPM_BUILD_ROOT/usr/bin/ssleay
        +
        +%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}/misc
        +%dir %attr(0750,root,root) %{openssldir}/private
        +
        +%files devel
        +%defattr(0644,root,root,0755)
        +%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
        +
        +%attr(0644,root,root) /usr/lib/*.a
        +%attr(0644,root,root) /usr/lib/pkgconfig/openssl.pc
        +%attr(0644,root,root) /usr/include/openssl/*
        +%attr(0644,root,root) /usr/man/man[3]/*
        +
        +%files doc
        +%defattr(0644,root,root,0755)
        +%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
        +%doc doc
        +
        +%post
        +ldconfig
        +
        +%postun
        +ldconfig
        +
        +%changelog
        +* Sun Jun  6 2005 Richard Levitte <richard@levitte.org>
        +- Remove the incorrect installation of '%{openssldir}/lib'.
        +* Wed May  7 2003 Richard Levitte <richard@levitte.org>
        +- Add /usr/lib/pkgconfig/openssl.pc to the development section.
        +* Thu Mar 22 2001 Richard Levitte <richard@levitte.org>
        +- Removed redundant subsection that re-installed libcrypto.a and libssl.a
        +  as well.  Also remove RSAref stuff completely, since it's not needed
        +  any more.
        +* Thu Mar 15 2001 Jeremiah Johnson <jjohnson@penguincomputing.com>
        +- Removed redundant subsection that re-installed libcrypto.so.0.9.6 and
        +  libssl.so.0.9.6.  As well as the subsection that created symlinks for
        +  these.  make install handles all this.
        +* Sat Oct 21 2000 Horms <horms@vergenet.net>
        +- Make sure symlinks are created by using -f flag to ln.
        +  Otherwise some .so libraries are copied rather than
        +  linked in the resulting binary RPM. This causes the package
        +  to be larger than neccessary and makes ldconfig complain.
        +* Fri Oct 13 2000 Horms <horms@vergenet.net>
        +- Make defattr is set for files in all packages so packages built as
        +  non-root will still be installed with files owned by root.
        +* Thu Sep 14 2000 Richard Levitte <richard@levitte.org>
        +- 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 <djm@mindrot.org>
        +- Merged patches to spec
        +- Updated to 0.9.5beta2 (now with manpages)
        +* Sat Feb  5 2000 Michal Jaegermann <michal@harddata.com>
        +- added 'linux-alpha' to configuration
        +- fixed nasty absolute links
        +* Tue Jan 25 2000 Bennett Todd <bet@rahul.net>
        +- Added -DSSL_ALLOW_ADH, bumped Release to 4
        +* Thu Oct 14 1999 Damien Miller <djm@mindrot.org>
        +- Set default permissions
        +- Removed documentation from devel sub-package
        +* Thu Sep 30 1999 Damien Miller <djm@mindrot.org>
        +- Added "make test" stage
        +- GPG signed
        +* Tue Sep 10 1999 Damien Miller <damien@ibs.com.au>
        +- Updated to version 0.9.4
        +* Tue May 25 1999 Damien Miller <damien@ibs.com.au>
        +- Updated to version 0.9.3
        +- Added attributes for all files
        +- Paramatised openssl directory
        +* Sat Mar 20 1999 Carlo M. Arenas Belon <carenas@jmconsultores.com.pe>
        +- 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 <gomez@slib.fr>
        +- Added bnrec patch
        +* Tue Dec 29 1998 Jonathan Ruano <kobalt@james.encomix.es>
        +- minimum spec and patches changes for openssl
        +- modified for openssl sources
        +* Sat Aug  8 1998 Khimenko Victor <khim@sch57.msk.ru>
        +- shared library creating process honours $RPM_OPT_FLAGS
        +- shared libarry supports threads (as well as static library)
        +* Wed Jul 22 1998 Khimenko Victor <khim@sch57.msk.ru>
        +- building of shared library completely reworked
        +* Tue Jul 21 1998 Khimenko Victor <khim@sch57.msk.ru>
        +- RPM is BuildRoot'ed
        +* Tue Feb 10 1998 Khimenko Victor <khim@sch57.msk.ru>
        +- all stuff is moved out of /usr/local
        diff --git a/vendor/openssl/openssl/os2/OS2-EMX.cmd b/vendor/openssl/openssl/os2/OS2-EMX.cmd
        new file mode 100644
        index 000000000..5924b50b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/os2/OS2-EMX.cmd
        @@ -0,0 +1,102 @@
        +@echo off
        +
        +perl Configure OS2-EMX
        +perl util\mkfiles.pl > MINFO
        +
        +@rem create make file
        +perl util\mk1mf.pl OS2-EMX > OS2-EMX.mak
        +perl util\mk1mf.pl dll OS2-EMX > OS2-EMX-DLL.mak
        +
        +echo Generating export definition files
        +perl util\mkdef.pl crypto OS2 > os2\crypto.def
        +perl util\mkdef.pl ssl OS2 > os2\ssl.def
        +
        +echo Generating x86 for GNU assember
        +
        +echo Bignum
        +cd crypto\bn\asm
        +rem perl x86.pl a.out > bn-os2.asm
        +perl bn-586.pl a.out > bn-os2.asm 
        +perl co-586.pl a.out > co-os2.asm 
        +cd ..\..\..
        +
        +echo DES
        +cd crypto\des\asm
        +perl des-586.pl a.out > d-os2.asm
        +cd ..\..\..
        +
        +echo crypt(3)
        +cd crypto\des\asm
        +perl crypt586.pl a.out > y-os2.asm
        +cd ..\..\..
        +
        +echo Blowfish
        +cd crypto\bf\asm
        +perl bf-586.pl a.out > b-os2.asm
        +cd ..\..\..
        +
        +echo CAST5
        +cd crypto\cast\asm
        +perl cast-586.pl a.out > c-os2.asm
        +cd ..\..\..
        +
        +echo RC4
        +cd crypto\rc4\asm
        +perl rc4-586.pl a.out > r4-os2.asm
        +cd ..\..\..
        +
        +echo MD5
        +cd crypto\md5\asm
        +perl md5-586.pl a.out > m5-os2.asm
        +cd ..\..\..
        +
        +echo SHA1
        +cd crypto\sha\asm
        +perl sha1-586.pl a.out > s1-os2.asm
        +cd ..\..\..
        +
        +echo RIPEMD160
        +cd crypto\ripemd\asm
        +perl rmd-586.pl a.out > rm-os2.asm
        +cd ..\..\..
        +
        +echo RC5\32
        +cd crypto\rc5\asm
        +perl rc5-586.pl a.out > r5-os2.asm
        +cd ..\..\..
        +
        +cd os2
        +
        +if exist noname\backward_ssl.def goto nomkdir
        +mkdir noname
        +:nomkdir
        +
        +perl backwardify.pl		crypto.def	>backward_crypto.def
        +perl backwardify.pl		ssl.def		>backward_ssl.def
        +perl backwardify.pl -noname	crypto.def	>noname\backward_crypto.def
        +perl backwardify.pl -noname	ssl.def		>noname\backward_ssl.def
        +
        +echo Creating backward compatibility forwarder dlls:
        +echo  crypto.dll
        +gcc -Zomf -Zdll -Zcrtdll -o crypto.dll backward_crypto.def 2>&1 | grep -v L4085
        +echo  ssl.dll
        +gcc -Zomf -Zdll -Zcrtdll -o ssl.dll backward_ssl.def 2>&1 | grep -v L4085
        +
        +echo Creating smaller backward compatibility forwarder dlls:
        +echo These DLLs are not good for runtime resolution of symbols.
        +echo  noname\crypto.dll
        +gcc -Zomf -Zdll -Zcrtdll -o noname/crypto.dll noname/backward_crypto.def 2>&1 | grep -v L4085
        +echo  noname\ssl.dll
        +gcc -Zomf -Zdll -Zcrtdll -o noname/ssl.dll noname/backward_ssl.def 2>&1 | grep -v L4085
        +
        +echo Compressing forwarders (it is ok if lxlite is not found):
        +lxlite *.dll noname/*.dll
        +
        +cd ..
        +
        +echo Now run:
        +echo For static build:
        +echo  make -f OS2-EMX.mak
        +echo For dynamic build:
        +echo  make -f OS2-EMX-DLL.mak
        +echo then rename crypto.dll to cryptssl.dll, ssl.dll to open_ssl.dll
        diff --git a/vendor/openssl/openssl/os2/backwardify.pl b/vendor/openssl/openssl/os2/backwardify.pl
        new file mode 100644
        index 000000000..272423c8f
        --- /dev/null
        +++ b/vendor/openssl/openssl/os2/backwardify.pl
        @@ -0,0 +1,32 @@
        +#!/usr/bin/perl -w
        +use strict;
        +
        +# Use as $0
        +# Use as $0 -noname
        +
        +my $did_library;
        +my $did_description;
        +my $do_exports;
        +my @imports;
        +my $noname = (@ARGV and $ARGV[0] eq '-noname' and shift);
        +while (<>) {
        +  unless ($did_library) {
        +    s/\b(cryptssl)\b/crypto/ and $did_library = $1 if /^LIBRARY\s+cryptssl\b/;
        +    s/\b(open_ssl)\b/ssl/    and $did_library = $1 if /^LIBRARY\s+open_ssl\b/;
        +  }
        +  unless ($did_description) {
        +    s&^(DESCRIPTION\s+(['"])).*&${1}\@#www.openssl.org/:#\@forwarder DLL for pre-0.9.7c+ OpenSSL to the new dll naming scheme$2& and $did_description++;
        +  }
        +  if ($do_exports) {{
        +    last unless /\S/;
        +    warn, last unless /^ \s* ( \w+ ) \s+ \@(\d+)\s*$/x;
        +    push @imports, [$1, $2];
        +    s/$/ NONAME/ if $noname;
        +  }}
        +  $do_exports++ if not $do_exports and /^EXPORTS/;
        +  print $_;
        +}
        +print "IMPORTS\n";
        +for my $imp (@imports) {
        +  print "\t$imp->[0]=$did_library.$imp->[1]\n";
        +}
        diff --git a/vendor/openssl/openssl/shlib/Makefile.hpux10-cc b/vendor/openssl/openssl/shlib/Makefile.hpux10-cc
        new file mode 100644
        index 000000000..89c28dcf4
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/Makefile.hpux10-cc
        @@ -0,0 +1,34 @@
        +# Makefile.hpux-cc
        +
        +major=0.9.8
        +
        +slib=libssl
        +sh_slib=$(slib).sl.$(major)
        +
        +clib=libcrypto
        +sh_clib=$(clib).sl.$(major)
        +
        +all : $(clib).sl $(slib).sl
        +
        +
        +$(clib)_pic.a : $(clib).a
        +	echo "Copying $? to $@"
        +	cp -p $? $@
        +
        +$(slib)_pic.a : $(slib).a
        +	echo "Copying $? to $@"
        +	cp -p $? $@
        +
        +$(sh_clib) : $(clib)_pic.a
        +	ld -b -s -z +h $@ -o $@ -Fl $(clib)_pic.a -ldld -lc 
        +
        +$(clib).sl : $(sh_clib)
        +	rm -f $@
        +	ln -s $? $@
        +
        +$(sh_slib) : $(slib)_pic.a $(clib).sl
        +	ld -b -s -z +h $@ -o $@ -Fl $(slib)_pic.a -ldld -lc
        +        
        +$(slib).sl : $(sh_slib)
        +	rm -f $@
        +	ln -s $? $@
        diff --git a/vendor/openssl/openssl/shlib/README b/vendor/openssl/openssl/shlib/README
        new file mode 100644
        index 000000000..fea07a59e
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/README
        @@ -0,0 +1 @@
        +Only the windows NT and, linux builds have been tested for SSLeay 0.8.0
        diff --git a/vendor/openssl/openssl/shlib/hpux10-cc.sh b/vendor/openssl/openssl/shlib/hpux10-cc.sh
        new file mode 100644
        index 000000000..ceeb8c523
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/hpux10-cc.sh
        @@ -0,0 +1,92 @@
        +#!/usr/bin/sh
        +#
        +# Run this script from the OpenSSL root directory:
        +# sh shlib/hpux10-cc.sh
        +# 
        +# HP-UX (10.20) shared library installation:
        +# Compile and install OpenSSL with best possible optimization:
        +# - shared libraries are compiled and installed with +O4 optimization
        +# - executable(s) are compiled and installed with +O4 optimization
        +# - static libraries are compiled and installed with +O3 optimization,
        +#   to avoid the time consuming +O4 link-time optimization when using
        +#   these libraries. (The shared libs are already optimized during build
        +#   at +O4.)
        +#
        +# This script must be run with appropriate privileges to install into
        +# /usr/local/ssl. HP-UX prevents used executables and shared libraries
        +# from being deleted or overwritten. Stop all processes using already
        +# installed items of OpenSSL.
        +#
        +# WARNING: At high optimization levels, HP's ANSI-C compiler can chew up
        +#          large amounts of memory and CPU time. Make sure to have at least
        +#          128MB of RAM available and that your kernel is configured to allow
        +#          at least 128MB data size (maxdsiz parameter which can be obtained
        +#          by multiplying 'echo maxdsiz/D | adb -k /stand/vmunix /dev/kmem'
        +#          by 'getconf PAGE_SIZE').
        +#          The installation process can take several hours, even on fast
        +#          machines. +O4 optimization of the libcrypto.sl shared library may
        +#          take 1 hour on a C200 (200MHz PA8200 CPU), +O3 compilation of
        +#          fcrypt_b.c can take 20 minutes on this machine. Stay patient.
        +#
        +# SITEFLAGS: site specific flags. I do use +DAportable, since I have to
        +# support older PA1.1-type CPUs. Your mileage may vary.
        +# +w1 enables enhanced warnings, useful when working with snaphots.
        +#
        +SITEFLAGS="+DAportable +w1"
        +#
        +# Set the default additions to build with HP-UX.
        +# -D_REENTRANT must/should be defined on HP-UX manually, since we do call
        +# Configure directly.
        +# +Oall increases the optimization done.
        +#
        +MYFLAGS="-D_REENTRANT +Oall $SITEFLAGS"
        +
        +# Configure for pic and build the static pic libraries
        +perl5 Configure no-shared hpux-parisc-cc-o4 +Z ${MYFLAGS}
        +make clean
        +make DIRS="crypto ssl"
        +# Rename the static pic libs and build dynamic libraries from them
        +# Be prepared to see a lot of warnings about shared libraries being built
        +# with optimizations higher than +O2. When using these libraries, it is
        +# not possible to replace internal library functions with functions from
        +# the program to be linked.
        +#
        +make -f shlib/Makefile.hpux10-cc
        +
        +# Copy the libraries to /usr/local/ssl/lib (they have to be in their
        +# final location when linking applications).
        +# If the directories are still there, no problem.
        +mkdir /usr/local
        +mkdir /usr/local/ssl
        +mkdir /usr/local/ssl/lib
        +chmod 444 lib*_pic.a
        +chmod 555 lib*.sl.0.9.8
        +cp -p lib*_pic.a lib*.sl.0.9.8 /usr/local/ssl/lib
        +(cd /usr/local/ssl/lib ; ln -sf libcrypto.sl.0.9.8 libcrypto.sl ; ln -sf libssl.sl.0.9.8 libssl.sl)
        +
        +# Reconfigure without pic to compile the executables. Unfortunately, while
        +# performing this task we have to recompile the library components, even
        +# though we use the already installed shared libs anyway.
        +#
        +perl5 Configure no-shared hpux-parisc-cc-o4 ${MYFLAGS}
        +
        +make clean
        +
        +# Hack the Makefiles to pick up the dynamic libraries during linking
        +#
        +sed 's/^PEX_LIBS=.*$/PEX_LIBS=-L\/usr\/local\/ssl\/lib/' Makefile.ssl >xxx; mv xxx Makefile.ssl
        +sed 's/-L\.\.//' apps/Makefile.ssl >xxx; mv xxx apps/Makefile.ssl
        +sed 's/-L\.\.//' test/Makefile.ssl >xxx; mv xxx test/Makefile.ssl
        +# Build the static libs and the executables in one make.
        +make
        +# Install everything
        +make install
        +
        +# Finally build the static libs with +O3. This time we only need the libraries,
        +# once created, they are simply copied into place.
        +#
        +perl5 Configure no-shared hpux-parisc-cc ${MYFLAGS}
        +make clean
        +make DIRS="crypto ssl"
        +chmod 644 libcrypto.a libssl.a
        +cp -p libcrypto.a libssl.a /usr/local/ssl/lib
        diff --git a/vendor/openssl/openssl/shlib/irix.sh b/vendor/openssl/openssl/shlib/irix.sh
        new file mode 100644
        index 000000000..22e4e6ad5
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/irix.sh
        @@ -0,0 +1,7 @@
        +FLAGS="-DTERMIOS -O2 -mips2 -DB_ENDIAN -fomit-frame-pointer -Wall -Iinclude"
        +SHFLAGS="-DPIC -fpic"
        +
        +gcc -c -Icrypto $SHFLAGS $FLAGS -o crypto.o crypto/crypto.c
        +ld -shared -o libcrypto.so crypto.o
        +gcc -c -Issl $SHFLAGS $FLAGS -o ssl.o ssl/ssl.c
        +ld -shared -o libssl.so ssl.o
        diff --git a/vendor/openssl/openssl/shlib/sco5-shared-gcc.sh b/vendor/openssl/openssl/shlib/sco5-shared-gcc.sh
        new file mode 100644
        index 000000000..fe4a457b5
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/sco5-shared-gcc.sh
        @@ -0,0 +1,48 @@
        +#!/bin/sh
        +
        +major="0"
        +minor="9.7b"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major.$minor
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major.$minor
        +
        +FLAGS="-O3 -fomit-frame-pointer"
        +SHFLAGS="-DPIC -fPIC"
        +
        +touch $sh_clib
        +touch $sh_slib
        +
        +echo collecting all object files for $clib.so
        +OBJS=
        +find . -name \*.o -print > allobjs
        +for obj in `ar t libcrypto.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $clib.so
        +gcc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
        +
        +rm -f $clib.so
        +ln -s $sh_clib $clib.so
        +
        +echo collecting all object files for $slib.so
        +OBJS=
        +for obj in `ar t libssl.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $slib.so
        +gcc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
        +
        +rm -f $slib.so
        +ln -s $sh_slib $slib.so
        +
        +mv libRSAglue.a libRSAglue.a.orig
        +mv libcrypto.a  libcrypto.a.orig
        +mv libssl.a     libssl.a.orig
        +
        diff --git a/vendor/openssl/openssl/shlib/sco5-shared-installed b/vendor/openssl/openssl/shlib/sco5-shared-installed
        new file mode 100644
        index 000000000..509902833
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/sco5-shared-installed
        @@ -0,0 +1,28 @@
        +#!/bin/sh
        +
        +major="0"
        +minor="9.7b"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major.$minor
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major.$minor
        +
        +# If you want them in /usr/local/lib then change INSTALLTOP to point there.
        +#INSTALLTOP=/usr/local/ssl/lib
        +INSTALLTOP=/usr/local/lib
        +
        +cp -p $sh_clib $INSTALLTOP
        +cp -p $sh_slib $INSTALLTOP
        +
        +PWD=`pwd`
        +cd $INSTALLTOP
        +rm -f $INSTALLTOP/$clib.so
        +ln -s $INSTALLTOP/$sh_clib $clib.so
        +
        +rm -f $INSTALLTOP/$slib.so
        +ln -s $INSTALLTOP/$sh_slib $slib.so
        +
        +cd $PWD
        +
        diff --git a/vendor/openssl/openssl/shlib/sco5-shared.sh b/vendor/openssl/openssl/shlib/sco5-shared.sh
        new file mode 100644
        index 000000000..b3365d9f5
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/sco5-shared.sh
        @@ -0,0 +1,48 @@
        +#!/bin/sh
        +
        +major="0"
        +minor="9.7b"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major.$minor
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major.$minor
        +
        +FLAGS="-O -DFILIO_H -Kalloca"
        +SHFLAGS="-Kpic -DPIC"
        +
        +touch $sh_clib
        +touch $sh_slib
        +
        +echo collecting all object files for $clib.so
        +OBJS=
        +find . -name \*.o -print > allobjs
        +for obj in `ar t libcrypto.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $clib.so
        +cc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
        +
        +rm -f $clib.so
        +ln -s $sh_clib $clib.so
        +
        +echo collecting all object files for $slib.so
        +OBJS=
        +for obj in `ar t libssl.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $slib.so
        +cc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
        +
        +rm -f $slib.so
        +ln -s $sh_slib $slib.so
        +
        +mv libRSAglue.a libRSAglue.a.orig
        +mv libcrypto.a  libcrypto.a.orig
        +mv libssl.a     libssl.a.orig
        +
        diff --git a/vendor/openssl/openssl/shlib/solaris-sc4.sh b/vendor/openssl/openssl/shlib/solaris-sc4.sh
        new file mode 100644
        index 000000000..b0766b35f
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/solaris-sc4.sh
        @@ -0,0 +1,42 @@
        +#!/bin/sh
        +
        +major="1"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major
        +
        +echo collecting all object files for $clib.so
        +OBJS=
        +find . -name \*.o -print > allobjs
        +for obj in `ar t libcrypto.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $clib.so
        +cc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
        +
        +rm -f $clib.so
        +ln -s $sh_clib $clib.so
        +
        +echo collecting all object files for $slib.so
        +OBJS=
        +for obj in `ar t libssl.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $slib.so
        +cc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
        +	
        +rm -f $slib.so
        +ln -s $sh_slib $slib.so
        +
        +rm -f allobjs
        +
        +mv libRSAglue.a libRSAglue.a.orig
        +mv libcrypto.a  libcrypto.a.orig
        +mv libssl.a     libssl.a.orig 
        diff --git a/vendor/openssl/openssl/shlib/solaris.sh b/vendor/openssl/openssl/shlib/solaris.sh
        new file mode 100644
        index 000000000..03475f12b
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/solaris.sh
        @@ -0,0 +1,36 @@
        +#!/bin/sh
        +
        +echo "#define DATE      \"`date`\"" >crypto/date.h
        +
        +major="0"
        +minor="8.0"
        +slib=libssl
        +clib=libcrypto
        +CC=gcc
        +CPP='gcc -E'
        +AS=as
        +#FLAGS='-DTERMIO -O3 -DL_ENDIAN -fomit-frame-pointer -mv8 -Wall'
        +FLAGS='-DTERMIO -g2 -ggdb -DL_ENDIAN -Wall -DREF_CHECK -DCRYPTO_MDEBUG'
        +INCLUDE='-Iinclude -Icrypto -Issl'
        +SHFLAGS='-DPIC -fpic'
        +
        +CFLAGS="$FLAGS $INCLUDE $SHFLAGS"
        +ASM_OBJ="";
        +
        +echo compiling bignum assember
        +$AS -o bn_asm.o crypto/bn/asm/sparc.s
        +CFLAGS="$CFLAGS -DBN_ASM"
        +ASM_OBJ="$ASM_OBJ bn_asm.o"
        +
        +echo compiling $clib
        +$CC -c $CFLAGS -DCFLAGS="\"$FLAGS\"" -o crypto.o crypto/crypto.c
        +
        +echo linking $clib.so
        +gcc $CFLAGS -shared -o $clib.so.$major.$minor crypto.o $ASM_OBJ -lnsl -lsocket
        +
        +echo compiling $slib.so
        +$CC -c $CFLAGS -o ssl.o ssl/ssl.c
        +
        +echo building $slib.so
        +gcc $CFLAGS -shared -o $slib.so ssl.o -L. -lcrypto
        +
        diff --git a/vendor/openssl/openssl/shlib/sun.sh b/vendor/openssl/openssl/shlib/sun.sh
        new file mode 100644
        index 000000000..a890bbd37
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/sun.sh
        @@ -0,0 +1,8 @@
        +FLAGS="-DTERMIO -O3 -DB_ENDIAN -fomit-frame-pointer -mv8 -Wall -Iinclude"
        +SHFLAGS="-DPIC -fpic"
        +
        +gcc -c -Icrypto $SHFLAGS -fpic $FLAGS -o crypto.o crypto/crypto.c
        +ld -G -z text -o libcrypto.so crypto.o
        +
        +gcc -c -Issl $SHFLAGS $FLAGS -o ssl.o ssl/ssl.c
        +ld -G -z text -o libssl.so ssl.o
        diff --git a/vendor/openssl/openssl/shlib/svr5-shared-gcc.sh b/vendor/openssl/openssl/shlib/svr5-shared-gcc.sh
        new file mode 100644
        index 000000000..c5d0cc56a
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/svr5-shared-gcc.sh
        @@ -0,0 +1,48 @@
        +#!/usr/bin/sh
        +
        +major="0"
        +minor="9.7b"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major.$minor
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major.$minor
        +
        +FLAGS="-O3 -DFILIO_H -fomit-frame-pointer -pthread"
        +SHFLAGS="-DPIC -fPIC"
        +
        +touch $sh_clib
        +touch $sh_slib
        +
        +echo collecting all object files for $clib.so
        +OBJS=
        +find . -name \*.o -print > allobjs
        +for obj in `ar t libcrypto.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $clib.so
        +gcc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
        +
        +rm -f $clib.so
        +ln -s $sh_clib $clib.so
        +
        +echo collecting all object files for $slib.so
        +OBJS=
        +for obj in `ar t libssl.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $slib.so
        +gcc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
        +
        +rm -f $slib.so
        +ln -s $sh_slib $slib.so
        +
        +mv libRSAglue.a libRSAglue.a.orig
        +mv libcrypto.a  libcrypto.a.orig
        +mv libssl.a     libssl.a.orig
        +
        diff --git a/vendor/openssl/openssl/shlib/svr5-shared-installed b/vendor/openssl/openssl/shlib/svr5-shared-installed
        new file mode 100644
        index 000000000..b1def35d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/svr5-shared-installed
        @@ -0,0 +1,27 @@
        +#!/usr/bin/sh
        +
        +major="0"
        +minor="9.7b"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major.$minor
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major.$minor
        +
        +# If you want them in /usr/local/lib then change INSTALLTOP to point there.
        +#INSTALLTOP=/usr/local/ssl/lib
        +INSTALLTOP=/usr/local/lib
        +
        +cp -p $sh_clib $INSTALLTOP
        +cp -p $sh_slib $INSTALLTOP
        +
        +PWD=`pwd`
        +cd $INSTALLTOP
        +rm -f $INSTALLTOP/$clib.so
        +ln -s $INSTALLTOP/$sh_clib $clib.so
        +
        +rm -f $INSTALLTOP/$slib.so
        +ln -s $INSTALLTOP/$sh_slib $slib.so
        +
        +cd $PWD
        diff --git a/vendor/openssl/openssl/shlib/svr5-shared.sh b/vendor/openssl/openssl/shlib/svr5-shared.sh
        new file mode 100644
        index 000000000..9edf26e9a
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/svr5-shared.sh
        @@ -0,0 +1,48 @@
        +#!/usr/bin/sh
        +
        +major="0"
        +minor="9.7b"
        +
        +slib=libssl
        +sh_slib=$slib.so.$major.$minor
        +
        +clib=libcrypto
        +sh_clib=$clib.so.$major.$minor
        +
        +FLAGS="-O -DFILIO_H -Kalloca -Kthread"
        +SHFLAGS="-Kpic -DPIC"
        +
        +touch $sh_clib
        +touch $sh_slib
        +
        +echo collecting all object files for $clib.so
        +OBJS=
        +find . -name \*.o -print > allobjs
        +for obj in `ar t libcrypto.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $clib.so
        +cc -G -o $sh_clib -h $sh_clib $OBJS -lnsl -lsocket
        +
        +rm -f $clib.so
        +ln -s $sh_clib $clib.so
        +
        +echo collecting all object files for $slib.so
        +OBJS=
        +for obj in `ar t libssl.a`
        +do
        +	OBJS="$OBJS `grep $obj allobjs`"
        +done
        +
        +echo linking $slib.so
        +cc -G -o $sh_slib -h $sh_slib $OBJS -L. -lcrypto
        +
        +rm -f $slib.so
        +ln -s $sh_slib $slib.so
        +
        +mv libRSAglue.a libRSAglue.a.orig
        +mv libcrypto.a  libcrypto.a.orig
        +mv libssl.a     libssl.a.orig
        +
        diff --git a/vendor/openssl/openssl/shlib/win32.bat b/vendor/openssl/openssl/shlib/win32.bat
        new file mode 100644
        index 000000000..2b0faaa17
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/win32.bat
        @@ -0,0 +1,18 @@
        +rem win32 dll build
        +
        +set OPTIONS1=-DDES_ASM -DBN_ASM -DBF_ASM -DFLAT_INC -Iout -Itmp -DL_ENDIAN
        +set OPTIONS2=/W3 /WX /Ox /Gs0 /GF /Gy /nologo
        +
        +set OPTIONS=%OPTIONS1% %OPTIONS2%
        +
        +rem ml /coff /c crypto\bf\asm\b-win32.asm
        +rem ml /coff /c crypto\des\asm\c-win32.asm
        +rem ml /coff /c crypto\des\asm\d-win32.asm
        +rem ml /coff /c crypto\bn\asm\x86nt32.asm
        +
        +cl /Focrypto.obj -DWIN32 %OPTIONS% -c crypto\crypto.c
        +cl /Fossl.obj -DWIN32 %OPTIONS% -c ssl\ssl.c
        +cl /Foeay.obj -DWIN32 %OPTIONS% -c apps\eay.c
        +
        +cl /Fessleay.exe %OPTIONS% eay.obj ssl.obj crypto.obj crypto\bf\asm\b-win32.obj crypto\des\asm\c-win32.obj crypto\des\asm\d-win32.obj crypto\bn\asm\x86nt32.obj user32.lib gdi32.lib ws2_32.lib
        +
        diff --git a/vendor/openssl/openssl/shlib/win32dll.bat b/vendor/openssl/openssl/shlib/win32dll.bat
        new file mode 100644
        index 000000000..844e3537c
        --- /dev/null
        +++ b/vendor/openssl/openssl/shlib/win32dll.bat
        @@ -0,0 +1,13 @@
        +rem win32 dll build
        +
        +set OPTIONS1=-DDES_ASM -DBN_ASM -DBF_ASM -DFLAT_INC -Iout -Itmp -DL_ENDIAN
        +set OPTIONS2=/W3 /WX /Ox /Gf /nologo
        +
        +set OPTIONS=%OPTIONS1% %OPTIONS2%
        +
        +cl /Felibeay32.dll /GD /MD /LD -DWIN32 %OPTIONS% ms\libeay32.def crypto\crypto.c crypto\bf\asm\b-win32.obj crypto\des\asm\c-win32.obj crypto\des\asm\d-win32.obj crypto\bn\asm\x86nt32.obj user32.lib gdi32.lib ws2_32.lib
        +
        +cl /Fessleay32.dll /GD /MD /LD -DWIN32 %OPTIONS% ms\ssleay32.def ssl\ssl.c libeay32.lib
        +
        +cl /Fessleay.exe /MD -DWIN32 %OPTIONS% apps\eay.c ssleay32.lib libeay32.lib user32.lib ws2_32.lib
        +
        diff --git a/vendor/openssl/openssl/ssl/Makefile b/vendor/openssl/openssl/ssl/Makefile
        new file mode 100644
        index 000000000..debe07405
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/Makefile
        @@ -0,0 +1,1061 @@
        +#
        +# OpenSSL/ssl/Makefile
        +#
        +
        +DIR=	ssl
        +TOP=	..
        +CC=	cc
        +INCLUDES= -I../crypto -I$(TOP) -I../include $(KRB5_INCLUDES)
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +AR=		ar r
        +# KRB5 stuff
        +KRB5_INCLUDES=
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile README ssl-lib.com install.com
        +TEST=ssltest.c
        +APPS=
        +
        +LIB=$(TOP)/libssl.a
        +SHARED_LIB= libssl$(SHLIB_EXT)
        +LIBSRC=	\
        +	s2_meth.c   s2_srvr.c s2_clnt.c  s2_lib.c  s2_enc.c s2_pkt.c \
        +	s3_meth.c   s3_srvr.c s3_clnt.c  s3_lib.c  s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \
        +	s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c          s23_pkt.c \
        +	t1_meth.c   t1_srvr.c t1_clnt.c  t1_lib.c  t1_enc.c \
        +	d1_meth.c   d1_srvr.c d1_clnt.c  d1_lib.c  d1_pkt.c \
        +	d1_both.c d1_enc.c d1_srtp.c \
        +	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
        +	ssl_ciph.c ssl_stat.c ssl_rsa.c \
        +	ssl_asn1.c ssl_txt.c ssl_algs.c \
        +	bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
        +LIBOBJ= \
        +	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
        +	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \
        +	s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o          s23_pkt.o \
        +	t1_meth.o   t1_srvr.o t1_clnt.o  t1_lib.o  t1_enc.o \
        +	d1_meth.o   d1_srvr.o d1_clnt.o  d1_lib.o  d1_pkt.o \
        +	d1_both.o d1_enc.o d1_srtp.o\
        +	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
        +	ssl_ciph.o ssl_stat.o ssl_rsa.o \
        +	ssl_asn1.o ssl_txt.o ssl_algs.o \
        +	bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
        +
        +SRC= $(LIBSRC)
        +
        +EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h srtp.h
        +HEADER=	$(EXHEADER) ssl_locl.h kssl_lcl.h
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ..; $(MAKE) DIRS=$(DIR) all)
        +
        +all:	shared
        +
        +lib:	$(LIBOBJ)
        +	$(AR) $(LIB) $(LIBOBJ)
        +	$(RANLIB) $(LIB) || echo Never mind.
        +	@touch lib
        +
        +shared: lib
        +	if [ -n "$(SHARED_LIBS)" ]; then \
        +		(cd ..; $(MAKE) $(SHARED_LIB)); \
        +	fi
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +	@$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
        +	@$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
        +	@$(PERL) $(TOP)/util/mklink.pl ../apps $(APPS)
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
        +	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:
        +	@if [ -z "$(THIS)" ]; then \
        +	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
        +	else \
        +	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
        +	fi
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +
        +clean:
        +	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +bio_ssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +bio_ssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +bio_ssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +bio_ssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +bio_ssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +bio_ssl.o: ../include/openssl/err.h ../include/openssl/evp.h
        +bio_ssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +bio_ssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +bio_ssl.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +bio_ssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +bio_ssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +bio_ssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +bio_ssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +bio_ssl.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +bio_ssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +bio_ssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +bio_ssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +bio_ssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bio_ssl.c
        +d1_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_both.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +d1_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +d1_both.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_both.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_both.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_both.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_both.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_both.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +d1_both.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +d1_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +d1_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +d1_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +d1_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +d1_both.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +d1_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +d1_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +d1_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +d1_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +d1_both.o: ../include/openssl/x509_vfy.h d1_both.c ssl_locl.h
        +d1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +d1_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
        +d1_clnt.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +d1_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_clnt.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +d1_clnt.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +d1_clnt.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +d1_clnt.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +d1_clnt.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +d1_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +d1_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +d1_clnt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +d1_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +d1_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +d1_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +d1_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_clnt.c
        +d1_clnt.o: kssl_lcl.h ssl_locl.h
        +d1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +d1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +d1_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +d1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +d1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +d1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +d1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +d1_enc.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +d1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +d1_enc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +d1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +d1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +d1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +d1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_enc.c
        +d1_enc.o: ssl_locl.h
        +d1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +d1_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +d1_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +d1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +d1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +d1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +d1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +d1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +d1_lib.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +d1_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +d1_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +d1_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +d1_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_lib.c
        +d1_lib.o: ssl_locl.h
        +d1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +d1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +d1_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +d1_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +d1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +d1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +d1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +d1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +d1_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +d1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +d1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +d1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +d1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_meth.c
        +d1_meth.o: ssl_locl.h
        +d1_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +d1_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +d1_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +d1_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +d1_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +d1_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +d1_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +d1_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +d1_pkt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +d1_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +d1_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +d1_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +d1_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +d1_pkt.o: ../include/openssl/x509_vfy.h d1_pkt.c ssl_locl.h
        +d1_srtp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_srtp.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +d1_srtp.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +d1_srtp.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_srtp.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_srtp.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_srtp.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_srtp.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_srtp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +d1_srtp.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +d1_srtp.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +d1_srtp.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +d1_srtp.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +d1_srtp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +d1_srtp.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +d1_srtp.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +d1_srtp.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +d1_srtp.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +d1_srtp.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_srtp.c
        +d1_srtp.o: srtp.h ssl_locl.h
        +d1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +d1_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +d1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
        +d1_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +d1_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +d1_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +d1_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +d1_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +d1_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +d1_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +d1_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +d1_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +d1_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +d1_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +d1_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +d1_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +d1_srvr.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +d1_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +d1_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +d1_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +d1_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_srvr.c
        +d1_srvr.o: ssl_locl.h
        +kssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +kssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +kssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +kssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +kssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +kssl.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +kssl.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
        +kssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +kssl.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +kssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +kssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +kssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +kssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +kssl.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +kssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +kssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +kssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +kssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl.c
        +kssl.o: kssl_lcl.h
        +s23_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s23_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s23_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s23_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s23_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s23_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s23_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s23_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s23_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s23_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s23_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s23_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s23_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s23_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s23_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s23_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s23_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s23_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s23_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s23_clnt.o: ../include/openssl/x509_vfy.h s23_clnt.c ssl_locl.h
        +s23_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s23_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s23_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s23_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s23_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s23_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s23_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s23_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s23_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s23_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s23_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s23_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s23_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s23_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s23_lib.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s23_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s23_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s23_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s23_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_lib.c
        +s23_lib.o: ssl_locl.h
        +s23_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s23_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s23_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s23_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s23_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s23_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s23_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s23_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s23_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s23_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s23_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s23_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s23_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s23_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s23_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s23_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s23_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s23_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s23_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_meth.c
        +s23_meth.o: ssl_locl.h
        +s23_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s23_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s23_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s23_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s23_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s23_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s23_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s23_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s23_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s23_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s23_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s23_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s23_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s23_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s23_pkt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s23_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s23_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s23_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s23_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_pkt.c
        +s23_pkt.o: ssl_locl.h
        +s23_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s23_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s23_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s23_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s23_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s23_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s23_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s23_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s23_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s23_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s23_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s23_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s23_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s23_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s23_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s23_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s23_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s23_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s23_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s23_srvr.o: ../include/openssl/x509_vfy.h s23_srvr.c ssl_locl.h
        +s2_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s2_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s2_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s2_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s2_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s2_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s2_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s2_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s2_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s2_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s2_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s2_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s2_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s2_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s2_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s2_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s2_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s2_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s2_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s2_clnt.o: ../include/openssl/x509_vfy.h s2_clnt.c ssl_locl.h
        +s2_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s2_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s2_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s2_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s2_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s2_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s2_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s2_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s2_enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s2_enc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s2_enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s2_enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s2_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s2_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s2_enc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s2_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s2_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s2_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s2_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_enc.c
        +s2_enc.o: ssl_locl.h
        +s2_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s2_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s2_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s2_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s2_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s2_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s2_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s2_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s2_lib.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +s2_lib.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +s2_lib.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +s2_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +s2_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +s2_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s2_lib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s2_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s2_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s2_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s2_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s2_lib.o: ../include/openssl/x509_vfy.h s2_lib.c ssl_locl.h
        +s2_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s2_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s2_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s2_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s2_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s2_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s2_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s2_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s2_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s2_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s2_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s2_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s2_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s2_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s2_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s2_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s2_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s2_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s2_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_meth.c
        +s2_meth.o: ssl_locl.h
        +s2_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s2_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s2_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s2_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s2_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s2_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s2_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s2_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s2_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s2_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s2_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s2_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s2_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s2_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s2_pkt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s2_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s2_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s2_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s2_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_pkt.c
        +s2_pkt.o: ssl_locl.h
        +s2_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s2_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s2_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s2_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s2_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s2_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s2_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s2_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s2_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s2_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s2_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s2_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s2_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s2_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s2_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s2_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s2_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s2_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s2_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s2_srvr.o: ../include/openssl/x509_vfy.h s2_srvr.c ssl_locl.h
        +s3_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_both.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s3_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s3_both.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_both.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_both.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s3_both.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s3_both.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s3_both.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s3_both.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s3_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s3_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s3_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s3_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s3_both.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s3_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s3_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h
        +s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_cbc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s3_cbc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s3_cbc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_cbc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_cbc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s3_cbc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s3_cbc.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h
        +s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
        +s3_clnt.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +s3_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +s3_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
        +s3_clnt.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +s3_clnt.o: ../include/openssl/lhash.h ../include/openssl/md5.h
        +s3_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s3_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s3_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s3_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s3_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s3_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s3_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s3_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s3_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s3_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s3_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s3_clnt.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_clnt.c ssl_locl.h
        +s3_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s3_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s3_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s3_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s3_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s3_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +s3_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +s3_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +s3_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +s3_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +s3_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s3_enc.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s3_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s3_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s3_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s3_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s3_enc.o: ../include/openssl/x509_vfy.h s3_enc.c ssl_locl.h
        +s3_lib.o: ../crypto/ec/ec_lcl.h ../e_os.h ../include/openssl/asn1.h
        +s3_lib.o: ../include/openssl/bio.h ../include/openssl/bn.h
        +s3_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s3_lib.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +s3_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
        +s3_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +s3_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +s3_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
        +s3_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +s3_lib.o: ../include/openssl/lhash.h ../include/openssl/md5.h
        +s3_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s3_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s3_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s3_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s3_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s3_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s3_lib.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s3_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s3_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s3_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s3_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
        +s3_lib.o: s3_lib.c ssl_locl.h
        +s3_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s3_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s3_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s3_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s3_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s3_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s3_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s3_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s3_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s3_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +s3_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +s3_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +s3_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +s3_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +s3_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +s3_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_meth.c
        +s3_meth.o: ssl_locl.h
        +s3_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_pkt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +s3_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +s3_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s3_pkt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s3_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +s3_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s3_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s3_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s3_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s3_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s3_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s3_pkt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s3_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s3_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s3_pkt.o: ../include/openssl/x509_vfy.h s3_pkt.c ssl_locl.h
        +s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
        +s3_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +s3_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
        +s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
        +s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +s3_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
        +ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +ssl_algs.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_algs.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_algs.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +ssl_algs.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ssl_algs.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ssl_algs.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ssl_algs.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssl_algs.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssl_algs.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssl_algs.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +ssl_algs.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_algs.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_algs.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_algs.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_algs.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_algs.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_algs.c
        +ssl_algs.o: ssl_locl.h
        +ssl_asn1.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
        +ssl_asn1.o: ../include/openssl/bio.h ../include/openssl/buffer.h
        +ssl_asn1.o: ../include/openssl/comp.h ../include/openssl/crypto.h
        +ssl_asn1.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
        +ssl_asn1.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ssl_asn1.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ssl_asn1.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ssl_asn1.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ssl_asn1.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ssl_asn1.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ssl_asn1.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ssl_asn1.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ssl_asn1.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +ssl_asn1.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +ssl_asn1.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +ssl_asn1.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +ssl_asn1.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +ssl_asn1.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ssl_asn1.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +ssl_asn1.o: ../include/openssl/x509_vfy.h ssl_asn1.c ssl_locl.h
        +ssl_cert.o: ../crypto/o_dir.h ../e_os.h ../include/openssl/asn1.h
        +ssl_cert.o: ../include/openssl/bio.h ../include/openssl/bn.h
        +ssl_cert.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_cert.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +ssl_cert.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +ssl_cert.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_cert.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_cert.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +ssl_cert.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ssl_cert.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ssl_cert.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ssl_cert.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssl_cert.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssl_cert.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssl_cert.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +ssl_cert.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_cert.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_cert.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_cert.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_cert.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_cert.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +ssl_cert.o: ../include/openssl/x509v3.h ssl_cert.c ssl_locl.h
        +ssl_ciph.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_ciph.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_ciph.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +ssl_ciph.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_ciph.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_ciph.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ssl_ciph.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ssl_ciph.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ssl_ciph.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ssl_ciph.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ssl_ciph.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ssl_ciph.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ssl_ciph.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +ssl_ciph.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +ssl_ciph.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +ssl_ciph.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +ssl_ciph.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +ssl_ciph.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ssl_ciph.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +ssl_ciph.o: ../include/openssl/x509_vfy.h ssl_ciph.c ssl_locl.h
        +ssl_err.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_err.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_err.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +ssl_err.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ssl_err.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ssl_err.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ssl_err.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ssl_err.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ssl_err.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ssl_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ssl_err.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ssl_err.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +ssl_err.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_err.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_err.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_err.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_err.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_err.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err.c
        +ssl_err2.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_err2.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_err2.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
        +ssl_err2.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ssl_err2.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ssl_err2.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ssl_err2.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ssl_err2.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ssl_err2.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ssl_err2.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ssl_err2.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ssl_err2.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +ssl_err2.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_err2.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_err2.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_err2.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_err2.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_err2.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err2.c
        +ssl_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +ssl_lib.o: ../include/openssl/dh.h ../include/openssl/dsa.h
        +ssl_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_lib.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ssl_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ssl_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ssl_lib.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ssl_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +ssl_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssl_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssl_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssl_lib.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +ssl_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +ssl_lib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +ssl_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +ssl_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +ssl_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ssl_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +ssl_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h kssl_lcl.h
        +ssl_lib.o: ssl_lib.c ssl_locl.h
        +ssl_rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_rsa.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_rsa.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +ssl_rsa.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_rsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_rsa.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +ssl_rsa.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ssl_rsa.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ssl_rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ssl_rsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssl_rsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssl_rsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssl_rsa.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +ssl_rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_rsa.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_rsa.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_rsa.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_rsa.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_rsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +ssl_rsa.o: ssl_rsa.c
        +ssl_sess.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_sess.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_sess.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +ssl_sess.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_sess.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_sess.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ssl_sess.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ssl_sess.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +ssl_sess.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ssl_sess.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ssl_sess.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ssl_sess.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +ssl_sess.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +ssl_sess.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +ssl_sess.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_sess.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_sess.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_sess.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_sess.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_sess.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +ssl_sess.o: ssl_sess.c
        +ssl_stat.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_stat.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_stat.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +ssl_stat.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_stat.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_stat.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +ssl_stat.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ssl_stat.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ssl_stat.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ssl_stat.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssl_stat.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssl_stat.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssl_stat.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +ssl_stat.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_stat.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_stat.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_stat.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_stat.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_stat.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +ssl_stat.o: ssl_stat.c
        +ssl_txt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssl_txt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +ssl_txt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +ssl_txt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +ssl_txt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ssl_txt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +ssl_txt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ssl_txt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ssl_txt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ssl_txt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssl_txt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssl_txt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssl_txt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +ssl_txt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ssl_txt.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssl_txt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssl_txt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssl_txt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssl_txt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +ssl_txt.o: ssl_txt.c
        +t1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +t1_clnt.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +t1_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +t1_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +t1_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +t1_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +t1_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +t1_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +t1_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +t1_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +t1_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +t1_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +t1_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +t1_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +t1_clnt.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +t1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +t1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +t1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +t1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +t1_clnt.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_clnt.c
        +t1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +t1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +t1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +t1_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +t1_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +t1_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +t1_enc.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +t1_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +t1_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +t1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +t1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +t1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +t1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +t1_enc.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +t1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +t1_enc.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +t1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +t1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +t1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +t1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +t1_enc.o: t1_enc.c
        +t1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +t1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +t1_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
        +t1_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
        +t1_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +t1_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +t1_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
        +t1_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +t1_lib.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +t1_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
        +t1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +t1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +t1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +t1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +t1_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +t1_lib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +t1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +t1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +t1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +t1_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +t1_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h ssl_locl.h
        +t1_lib.o: t1_lib.c
        +t1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +t1_meth.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +t1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +t1_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +t1_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +t1_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +t1_meth.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +t1_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +t1_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +t1_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +t1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +t1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +t1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +t1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +t1_meth.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +t1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +t1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +t1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +t1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +t1_meth.o: t1_meth.c
        +t1_reneg.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +t1_reneg.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +t1_reneg.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +t1_reneg.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +t1_reneg.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +t1_reneg.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +t1_reneg.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +t1_reneg.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +t1_reneg.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +t1_reneg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +t1_reneg.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +t1_reneg.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +t1_reneg.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
        +t1_reneg.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +t1_reneg.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +t1_reneg.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +t1_reneg.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +t1_reneg.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +t1_reneg.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
        +t1_reneg.o: t1_reneg.c
        +t1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +t1_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
        +t1_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
        +t1_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
        +t1_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +t1_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +t1_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +t1_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +t1_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +t1_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +t1_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +t1_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +t1_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +t1_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +t1_srvr.o: ../include/openssl/sha.h ../include/openssl/srtp.h
        +t1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +t1_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
        +tls_srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +tls_srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +tls_srp.o: ../include/openssl/comp.h ../include/openssl/crypto.h
        +tls_srp.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
        +tls_srp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +tls_srp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +tls_srp.o: ../include/openssl/err.h ../include/openssl/evp.h
        +tls_srp.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
        +tls_srp.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +tls_srp.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +tls_srp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +tls_srp.o: ../include/openssl/pem.h ../include/openssl/pem2.h
        +tls_srp.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
        +tls_srp.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +tls_srp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +tls_srp.o: ../include/openssl/srp.h ../include/openssl/srtp.h
        +tls_srp.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
        +tls_srp.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
        +tls_srp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +tls_srp.o: ../include/openssl/tls1.h ../include/openssl/x509.h
        +tls_srp.o: ../include/openssl/x509_vfy.h ssl_locl.h tls_srp.c
        diff --git a/vendor/openssl/openssl/ssl/bio_ssl.c b/vendor/openssl/openssl/ssl/bio_ssl.c
        new file mode 100644
        index 000000000..e9552caee
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/bio_ssl.c
        @@ -0,0 +1,605 @@
        +/* ssl/bio_ssl.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <errno.h>
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +static int ssl_write(BIO *h, const char *buf, int num);
        +static int ssl_read(BIO *h, char *buf, int size);
        +static int ssl_puts(BIO *h, const char *str);
        +static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
        +static int ssl_new(BIO *h);
        +static int ssl_free(BIO *data);
        +static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
        +typedef struct bio_ssl_st
        +	{
        +	SSL *ssl; /* The ssl handle :-) */
        +	/* re-negotiate every time the total number of bytes is this size */
        +	int num_renegotiates;
        +	unsigned long renegotiate_count;
        +	unsigned long byte_count;
        +	unsigned long renegotiate_timeout;
        +	unsigned long last_time;
        +	} BIO_SSL;
        +
        +static BIO_METHOD methods_sslp=
        +	{
        +	BIO_TYPE_SSL,"ssl",
        +	ssl_write,
        +	ssl_read,
        +	ssl_puts,
        +	NULL, /* ssl_gets, */
        +	ssl_ctrl,
        +	ssl_new,
        +	ssl_free,
        +	ssl_callback_ctrl,
        +	};
        +
        +BIO_METHOD *BIO_f_ssl(void)
        +	{
        +	return(&methods_sslp);
        +	}
        +
        +static int ssl_new(BIO *bi)
        +	{
        +	BIO_SSL *bs;
        +
        +	bs=(BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL));
        +	if (bs == NULL)
        +		{
        +		BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	memset(bs,0,sizeof(BIO_SSL));
        +	bi->init=0;
        +	bi->ptr=(char *)bs;
        +	bi->flags=0;
        +	return(1);
        +	}
        +
        +static int ssl_free(BIO *a)
        +	{
        +	BIO_SSL *bs;
        +
        +	if (a == NULL) return(0);
        +	bs=(BIO_SSL *)a->ptr;
        +	if (bs->ssl != NULL) SSL_shutdown(bs->ssl);
        +	if (a->shutdown)
        +		{
        +		if (a->init && (bs->ssl != NULL))
        +			SSL_free(bs->ssl);
        +		a->init=0;
        +		a->flags=0;
        +		}
        +	if (a->ptr != NULL)
        +		OPENSSL_free(a->ptr);
        +	return(1);
        +	}
        +	
        +static int ssl_read(BIO *b, char *out, int outl)
        +	{
        +	int ret=1;
        +	BIO_SSL *sb;
        +	SSL *ssl;
        +	int retry_reason=0;
        +	int r=0;
        +
        +	if (out == NULL) return(0);
        +	sb=(BIO_SSL *)b->ptr;
        +	ssl=sb->ssl;
        +
        +	BIO_clear_retry_flags(b);
        +
        +#if 0
        +	if (!SSL_is_init_finished(ssl))
        +		{
        +/*		ret=SSL_do_handshake(ssl); */
        +		if (ret > 0)
        +			{
        +
        +			outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
        +			ret= -1;
        +			goto end;
        +			}
        +		}
        +#endif
        +/*	if (ret > 0) */
        +	ret=SSL_read(ssl,out,outl);
        +
        +	switch (SSL_get_error(ssl,ret))
        +		{
        +	case SSL_ERROR_NONE:
        +		if (ret <= 0) break;
        +		if (sb->renegotiate_count > 0)
        +			{
        +			sb->byte_count+=ret;
        +			if (sb->byte_count > sb->renegotiate_count)
        +				{
        +				sb->byte_count=0;
        +				sb->num_renegotiates++;
        +				SSL_renegotiate(ssl);
        +				r=1;
        +				}
        +			}
        +		if ((sb->renegotiate_timeout > 0) && (!r))
        +			{
        +			unsigned long tm;
        +
        +			tm=(unsigned long)time(NULL);
        +			if (tm > sb->last_time+sb->renegotiate_timeout)
        +				{
        +				sb->last_time=tm;
        +				sb->num_renegotiates++;
        +				SSL_renegotiate(ssl);
        +				}
        +			}
        +
        +		break;
        +	case SSL_ERROR_WANT_READ:
        +		BIO_set_retry_read(b);
        +		break;
        +	case SSL_ERROR_WANT_WRITE:
        +		BIO_set_retry_write(b);
        +		break;
        +	case SSL_ERROR_WANT_X509_LOOKUP:
        +		BIO_set_retry_special(b);
        +		retry_reason=BIO_RR_SSL_X509_LOOKUP;
        +		break;
        +	case SSL_ERROR_WANT_ACCEPT:
        +		BIO_set_retry_special(b);
        +		retry_reason=BIO_RR_ACCEPT;
        +		break;
        +	case SSL_ERROR_WANT_CONNECT:
        +		BIO_set_retry_special(b);
        +		retry_reason=BIO_RR_CONNECT;
        +		break;
        +	case SSL_ERROR_SYSCALL:
        +	case SSL_ERROR_SSL:
        +	case SSL_ERROR_ZERO_RETURN:
        +	default:
        +		break;
        +		}
        +
        +	b->retry_reason=retry_reason;
        +	return(ret);
        +	}
        +
        +static int ssl_write(BIO *b, const char *out, int outl)
        +	{
        +	int ret,r=0;
        +	int retry_reason=0;
        +	SSL *ssl;
        +	BIO_SSL *bs;
        +
        +	if (out == NULL) return(0);
        +	bs=(BIO_SSL *)b->ptr;
        +	ssl=bs->ssl;
        +
        +	BIO_clear_retry_flags(b);
        +
        +/*	ret=SSL_do_handshake(ssl);
        +	if (ret > 0) */
        +	ret=SSL_write(ssl,out,outl);
        +
        +	switch (SSL_get_error(ssl,ret))
        +		{
        +	case SSL_ERROR_NONE:
        +		if (ret <= 0) break;
        +		if (bs->renegotiate_count > 0)
        +			{
        +			bs->byte_count+=ret;
        +			if (bs->byte_count > bs->renegotiate_count)
        +				{
        +				bs->byte_count=0;
        +				bs->num_renegotiates++;
        +				SSL_renegotiate(ssl);
        +				r=1;
        +				}
        +			}
        +		if ((bs->renegotiate_timeout > 0) && (!r))
        +			{
        +			unsigned long tm;
        +
        +			tm=(unsigned long)time(NULL);
        +			if (tm > bs->last_time+bs->renegotiate_timeout)
        +				{
        +				bs->last_time=tm;
        +				bs->num_renegotiates++;
        +				SSL_renegotiate(ssl);
        +				}
        +			}
        +		break;
        +	case SSL_ERROR_WANT_WRITE:
        +		BIO_set_retry_write(b);
        +		break;
        +	case SSL_ERROR_WANT_READ:
        +		BIO_set_retry_read(b);
        +		break;
        +	case SSL_ERROR_WANT_X509_LOOKUP:
        +		BIO_set_retry_special(b);
        +		retry_reason=BIO_RR_SSL_X509_LOOKUP;
        +		break;
        +	case SSL_ERROR_WANT_CONNECT:
        +		BIO_set_retry_special(b);
        +		retry_reason=BIO_RR_CONNECT;
        +	case SSL_ERROR_SYSCALL:
        +	case SSL_ERROR_SSL:
        +	default:
        +		break;
        +		}
        +
        +	b->retry_reason=retry_reason;
        +	return(ret);
        +	}
        +
        +static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
        +	{
        +	SSL **sslp,*ssl;
        +	BIO_SSL *bs;
        +	BIO *dbio,*bio;
        +	long ret=1;
        +
        +	bs=(BIO_SSL *)b->ptr;
        +	ssl=bs->ssl;
        +	if ((ssl == NULL)  && (cmd != BIO_C_SET_SSL))
        +		return(0);
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_RESET:
        +		SSL_shutdown(ssl);
        +
        +		if (ssl->handshake_func == ssl->method->ssl_connect)
        +			SSL_set_connect_state(ssl);
        +		else if (ssl->handshake_func == ssl->method->ssl_accept)
        +			SSL_set_accept_state(ssl);
        +
        +		SSL_clear(ssl);
        +
        +		if (b->next_bio != NULL)
        +			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
        +		else if (ssl->rbio != NULL)
        +			ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
        +		else
        +			ret=1;
        +		break;
        +	case BIO_CTRL_INFO:
        +		ret=0;
        +		break;
        +	case BIO_C_SSL_MODE:
        +		if (num) /* client mode */
        +			SSL_set_connect_state(ssl);
        +		else
        +			SSL_set_accept_state(ssl);
        +		break;
        +	case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
        +		ret=bs->renegotiate_timeout;
        +		if (num < 60) num=5;
        +		bs->renegotiate_timeout=(unsigned long)num;
        +		bs->last_time=(unsigned long)time(NULL);
        +		break;
        +	case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
        +		ret=bs->renegotiate_count;
        +		if ((long)num >=512)
        +			bs->renegotiate_count=(unsigned long)num;
        +		break;
        +	case BIO_C_GET_SSL_NUM_RENEGOTIATES:
        +		ret=bs->num_renegotiates;
        +		break;
        +	case BIO_C_SET_SSL:
        +		if (ssl != NULL)
        +			{
        +			ssl_free(b);
        +			if (!ssl_new(b))
        +				return 0;
        +			}
        +		b->shutdown=(int)num;
        +		ssl=(SSL *)ptr;
        +		((BIO_SSL *)b->ptr)->ssl=ssl;
        +		bio=SSL_get_rbio(ssl);
        +		if (bio != NULL)
        +			{
        +			if (b->next_bio != NULL)
        +				BIO_push(bio,b->next_bio);
        +			b->next_bio=bio;
        +			CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO);
        +			}
        +		b->init=1;
        +		break;
        +	case BIO_C_GET_SSL:
        +		if (ptr != NULL)
        +			{
        +			sslp=(SSL **)ptr;
        +			*sslp=ssl;
        +			}
        +		else
        +			ret=0;
        +		break;
        +	case BIO_CTRL_GET_CLOSE:
        +		ret=b->shutdown;
        +		break;
        +	case BIO_CTRL_SET_CLOSE:
        +		b->shutdown=(int)num;
        +		break;
        +	case BIO_CTRL_WPENDING:
        +		ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_PENDING:
        +		ret=SSL_pending(ssl);
        +		if (ret == 0)
        +			ret=BIO_pending(ssl->rbio);
        +		break;
        +	case BIO_CTRL_FLUSH:
        +		BIO_clear_retry_flags(b);
        +		ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
        +		BIO_copy_next_retry(b);
        +		break;
        +	case BIO_CTRL_PUSH:
        +		if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio))
        +			{
        +			SSL_set_bio(ssl,b->next_bio,b->next_bio);
        +			CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
        +			}
        +		break;
        +	case BIO_CTRL_POP:
        +		/* Only detach if we are the BIO explicitly being popped */
        +		if (b == ptr)
        +			{
        +			/* Shouldn't happen in practice because the
        +			 * rbio and wbio are the same when pushed.
        +			 */
        +			if (ssl->rbio != ssl->wbio)
        +				BIO_free_all(ssl->wbio);
        +			if (b->next_bio != NULL)
        +				CRYPTO_add(&b->next_bio->references,-1,CRYPTO_LOCK_BIO);
        +			ssl->wbio=NULL;
        +			ssl->rbio=NULL;
        +			}
        +		break;
        +	case BIO_C_DO_STATE_MACHINE:
        +		BIO_clear_retry_flags(b);
        +
        +		b->retry_reason=0;
        +		ret=(int)SSL_do_handshake(ssl);
        +
        +		switch (SSL_get_error(ssl,(int)ret))
        +			{
        +		case SSL_ERROR_WANT_READ:
        +			BIO_set_flags(b,
        +				BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
        +			break;
        +		case SSL_ERROR_WANT_WRITE:
        +			BIO_set_flags(b,
        +				BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
        +			break;
        +		case SSL_ERROR_WANT_CONNECT:
        +			BIO_set_flags(b,
        +				BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
        +			b->retry_reason=b->next_bio->retry_reason;
        +			break;
        +		default:
        +			break;
        +			}
        +		break;
        +	case BIO_CTRL_DUP:
        +		dbio=(BIO *)ptr;
        +		if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
        +			SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
        +		((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl);
        +		((BIO_SSL *)dbio->ptr)->renegotiate_count=
        +			((BIO_SSL *)b->ptr)->renegotiate_count;
        +		((BIO_SSL *)dbio->ptr)->byte_count=
        +			((BIO_SSL *)b->ptr)->byte_count;
        +		((BIO_SSL *)dbio->ptr)->renegotiate_timeout=
        +			((BIO_SSL *)b->ptr)->renegotiate_timeout;
        +		((BIO_SSL *)dbio->ptr)->last_time=
        +			((BIO_SSL *)b->ptr)->last_time;
        +		ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL);
        +		break;
        +	case BIO_C_GET_FD:
        +		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
        +		break;
        +	case BIO_CTRL_SET_CALLBACK:
        +		{
        +#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
        +		SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		ret = -1;
        +#else
        +		ret=0;
        +#endif
        +		}
        +		break;
        +	case BIO_CTRL_GET_CALLBACK:
        +		{
        +		void (**fptr)(const SSL *xssl,int type,int val);
        +
        +		fptr=(void (**)(const SSL *xssl,int type,int val))ptr;
        +		*fptr=SSL_get_info_callback(ssl);
        +		}
        +		break;
        +	default:
        +		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
        +	{
        +	SSL *ssl;
        +	BIO_SSL *bs;
        +	long ret=1;
        +
        +	bs=(BIO_SSL *)b->ptr;
        +	ssl=bs->ssl;
        +	switch (cmd)
        +		{
        +	case BIO_CTRL_SET_CALLBACK:
        +		{
        +		/* FIXME: setting this via a completely different prototype
        +		   seems like a crap idea */
        +		SSL_set_info_callback(ssl,(void (*)(const SSL *,int,int))fp);
        +		}
        +		break;
        +	default:
        +		ret=BIO_callback_ctrl(ssl->rbio,cmd,fp);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +static int ssl_puts(BIO *bp, const char *str)
        +	{
        +	int n,ret;
        +
        +	n=strlen(str);
        +	ret=BIO_write(bp,str,n);
        +	return(ret);
        +	}
        +
        +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
        +	{
        +#ifndef OPENSSL_NO_SOCK
        +	BIO *ret=NULL,*buf=NULL,*ssl=NULL;
        +
        +	if ((buf=BIO_new(BIO_f_buffer())) == NULL)
        +		return(NULL);
        +	if ((ssl=BIO_new_ssl_connect(ctx)) == NULL)
        +		goto err;
        +	if ((ret=BIO_push(buf,ssl)) == NULL)
        +		goto err;
        +	return(ret);
        +err:
        +	if (buf != NULL) BIO_free(buf);
        +	if (ssl != NULL) BIO_free(ssl);
        +#endif
        +	return(NULL);
        +	}
        +
        +BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
        +	{
        +#ifndef OPENSSL_NO_SOCK
        +	BIO *ret=NULL,*con=NULL,*ssl=NULL;
        +
        +	if ((con=BIO_new(BIO_s_connect())) == NULL)
        +		return(NULL);
        +	if ((ssl=BIO_new_ssl(ctx,1)) == NULL)
        +		goto err;
        +	if ((ret=BIO_push(ssl,con)) == NULL)
        +		goto err;
        +	return(ret);
        +err:
        +	if (con != NULL) BIO_free(con);
        +#endif
        +	return(NULL);
        +	}
        +
        +BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
        +	{
        +	BIO *ret;
        +	SSL *ssl;
        +
        +	if ((ret=BIO_new(BIO_f_ssl())) == NULL)
        +		return(NULL);
        +	if ((ssl=SSL_new(ctx)) == NULL)
        +		{
        +		BIO_free(ret);
        +		return(NULL);
        +		}
        +	if (client)
        +		SSL_set_connect_state(ssl);
        +	else
        +		SSL_set_accept_state(ssl);
        +		
        +	BIO_set_ssl(ret,ssl,BIO_CLOSE);
        +	return(ret);
        +	}
        +
        +int BIO_ssl_copy_session_id(BIO *t, BIO *f)
        +	{
        +	t=BIO_find_type(t,BIO_TYPE_SSL);
        +	f=BIO_find_type(f,BIO_TYPE_SSL);
        +	if ((t == NULL) || (f == NULL))
        +		return(0);
        +	if (	(((BIO_SSL *)t->ptr)->ssl == NULL) || 
        +		(((BIO_SSL *)f->ptr)->ssl == NULL))
        +		return(0);
        +	SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl);
        +	return(1);
        +	}
        +
        +void BIO_ssl_shutdown(BIO *b)
        +	{
        +	SSL *s;
        +
        +	while (b != NULL)
        +		{
        +		if (b->method->type == BIO_TYPE_SSL)
        +			{
        +			s=((BIO_SSL *)b->ptr)->ssl;
        +			SSL_shutdown(s);
        +			break;
        +			}
        +		b=b->next_bio;
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/ssl/d1_both.c b/vendor/openssl/openssl/ssl/d1_both.c
        new file mode 100644
        index 000000000..de8bab873
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_both.c
        @@ -0,0 +1,1591 @@
        +/* ssl/d1_both.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <limits.h>
        +#include <string.h>
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
        +
        +#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \
        +			if ((end) - (start) <= 8) { \
        +				long ii; \
        +				for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
        +			} else { \
        +				long ii; \
        +				bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
        +				for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
        +				bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
        +			} }
        +
        +#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \
        +			long ii; \
        +			OPENSSL_assert((msg_len) > 0); \
        +			is_complete = 1; \
        +			if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
        +			if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
        +				if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
        +
        +#if 0
        +#define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \
        +			long ii; \
        +			printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \
        +			printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \
        +			printf("\n"); }
        +#endif
        +
        +static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
        +static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
        +
        +/* XDTLS:  figure out the right values */
        +static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
        +
        +static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
        +static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, 
        +	unsigned long frag_len);
        +static unsigned char *dtls1_write_message_header(SSL *s,
        +	unsigned char *p);
        +static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
        +	unsigned long len, unsigned short seq_num, unsigned long frag_off, 
        +	unsigned long frag_len);
        +static long dtls1_get_message_fragment(SSL *s, int st1, int stn, 
        +	long max, int *ok);
        +
        +static hm_fragment *
        +dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
        +	{
        +	hm_fragment *frag = NULL;
        +	unsigned char *buf = NULL;
        +	unsigned char *bitmask = NULL;
        +
        +	frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
        +	if ( frag == NULL)
        +		return NULL;
        +
        +	if (frag_len)
        +		{
        +		buf = (unsigned char *)OPENSSL_malloc(frag_len);
        +		if ( buf == NULL)
        +			{
        +			OPENSSL_free(frag);
        +			return NULL;
        +			}
        +		}
        +
        +	/* zero length fragment gets zero frag->fragment */
        +	frag->fragment = buf;
        +
        +	/* Initialize reassembly bitmask if necessary */
        +	if (reassembly)
        +		{
        +		bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
        +		if (bitmask == NULL)
        +			{
        +			if (buf != NULL) OPENSSL_free(buf);
        +			OPENSSL_free(frag);
        +			return NULL;
        +			}
        +		memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len));
        +		}
        +
        +	frag->reassembly = bitmask;
        +
        +	return frag;
        +	}
        +
        +static void
        +dtls1_hm_fragment_free(hm_fragment *frag)
        +	{
        +	if (frag->fragment) OPENSSL_free(frag->fragment);
        +	if (frag->reassembly) OPENSSL_free(frag->reassembly);
        +	OPENSSL_free(frag);
        +	}
        +
        +/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
        +int dtls1_do_write(SSL *s, int type)
        +	{
        +	int ret;
        +	int curr_mtu;
        +	unsigned int len, frag_off, mac_size, blocksize;
        +
        +	/* AHA!  Figure out the MTU, and stick to the right size */
        +	if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
        +		{
        +		s->d1->mtu = 
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
        +
        +		/* I've seen the kernel return bogus numbers when it doesn't know
        +		 * (initial write), so just make sure we have a reasonable number */
        +		if (s->d1->mtu < dtls1_min_mtu())
        +			{
        +			s->d1->mtu = 0;
        +			s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, 
        +				s->d1->mtu, NULL);
        +			}
        +		}
        +#if 0 
        +	mtu = s->d1->mtu;
        +
        +	fprintf(stderr, "using MTU = %d\n", mtu);
        +
        +	mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
        +
        +	curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
        +
        +	if ( curr_mtu > 0)
        +		mtu = curr_mtu;
        +	else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
        +		return ret;
        +
        +	if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
        +		{
        +		ret = BIO_flush(SSL_get_wbio(s));
        +		if ( ret <= 0)
        +			return ret;
        +		mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
        +		}
        +#endif
        +
        +	OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());  /* should have something reasonable now */
        +
        +	if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)
        +		OPENSSL_assert(s->init_num == 
        +			(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
        +
        +	if (s->write_hash)
        +		mac_size = EVP_MD_CTX_size(s->write_hash);
        +	else
        +		mac_size = 0;
        +
        +	if (s->enc_write_ctx && 
        +		(EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE))
        +		blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
        +	else
        +		blocksize = 0;
        +
        +	frag_off = 0;
        +	while( s->init_num)
        +		{
        +		curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 
        +			DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
        +
        +		if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
        +			{
        +			/* grr.. we could get an error if MTU picked was wrong */
        +			ret = BIO_flush(SSL_get_wbio(s));
        +			if ( ret <= 0)
        +				return ret;
        +			curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
        +				mac_size - blocksize;
        +			}
        +
        +		if ( s->init_num > curr_mtu)
        +			len = curr_mtu;
        +		else
        +			len = s->init_num;
        +
        +
        +		/* XDTLS: this function is too long.  split out the CCS part */
        +		if ( type == SSL3_RT_HANDSHAKE)
        +			{
        +			if ( s->init_off != 0)
        +				{
        +				OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
        +				s->init_off -= DTLS1_HM_HEADER_LENGTH;
        +				s->init_num += DTLS1_HM_HEADER_LENGTH;
        +
        +				/* write atleast DTLS1_HM_HEADER_LENGTH bytes */
        +				if ( len <= DTLS1_HM_HEADER_LENGTH)  
        +					len += DTLS1_HM_HEADER_LENGTH;
        +				}
        +
        +			dtls1_fix_message_header(s, frag_off, 
        +				len - DTLS1_HM_HEADER_LENGTH);
        +
        +			dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
        +
        +			OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
        +			}
        +
        +		ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
        +			len);
        +		if (ret < 0)
        +			{
        +			/* might need to update MTU here, but we don't know
        +			 * which previous packet caused the failure -- so can't
        +			 * really retransmit anything.  continue as if everything
        +			 * is fine and wait for an alert to handle the
        +			 * retransmit 
        +			 */
        +			if ( BIO_ctrl(SSL_get_wbio(s),
        +				BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
        +				s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
        +					BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
        +			else
        +				return(-1);
        +			}
        +		else
        +			{
        +
        +			/* bad if this assert fails, only part of the handshake
        +			 * message got sent.  but why would this happen? */
        +			OPENSSL_assert(len == (unsigned int)ret);
        +
        +			if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting)
        +				{
        +				/* should not be done for 'Hello Request's, but in that case
        +				 * we'll ignore the result anyway */
        +				unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off];
        +				const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
        +				int xlen;
        +
        +				if (frag_off == 0 && s->version != DTLS1_BAD_VER)
        +					{
        +					/* reconstruct message header is if it
        +					 * is being sent in single fragment */
        +					*p++ = msg_hdr->type;
        +					l2n3(msg_hdr->msg_len,p);
        +					s2n (msg_hdr->seq,p);
        +					l2n3(0,p);
        +					l2n3(msg_hdr->msg_len,p);
        +					p  -= DTLS1_HM_HEADER_LENGTH;
        +					xlen = ret;
        +					}
        +				else
        +					{
        +					p  += DTLS1_HM_HEADER_LENGTH;
        +					xlen = ret - DTLS1_HM_HEADER_LENGTH;
        +					}
        +
        +				ssl3_finish_mac(s, p, xlen);
        +				}
        +
        +			if (ret == s->init_num)
        +				{
        +				if (s->msg_callback)
        +					s->msg_callback(1, s->version, type, s->init_buf->data, 
        +						(size_t)(s->init_off + s->init_num), s, 
        +						s->msg_callback_arg);
        +
        +				s->init_off = 0;  /* done writing this message */
        +				s->init_num = 0;
        +
        +				return(1);
        +				}
        +			s->init_off+=ret;
        +			s->init_num-=ret;
        +			frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
        +			}
        +		}
        +	return(0);
        +	}
        +
        +
        +/* Obtain handshake message of message type 'mt' (any if mt == -1),
        + * maximum acceptable body length 'max'.
        + * Read an entire handshake message.  Handshake messages arrive in
        + * fragments.
        + */
        +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
        +	{
        +	int i, al;
        +	struct hm_header_st *msg_hdr;
        +	unsigned char *p;
        +	unsigned long msg_len;
        +
        +	/* s3->tmp is used to store messages that are unexpected, caused
        +	 * by the absence of an optional handshake message */
        +	if (s->s3->tmp.reuse_message)
        +		{
        +		s->s3->tmp.reuse_message=0;
        +		if ((mt >= 0) && (s->s3->tmp.message_type != mt))
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
        +			goto f_err;
        +			}
        +		*ok=1;
        +		s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
        +		s->init_num = (int)s->s3->tmp.message_size;
        +		return s->init_num;
        +		}
        +
        +	msg_hdr = &s->d1->r_msg_hdr;
        +	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
        +
        +again:
        +	i = dtls1_get_message_fragment(s, st1, stn, max, ok);
        +	if ( i == DTLS1_HM_BAD_FRAGMENT ||
        +		i == DTLS1_HM_FRAGMENT_RETRY)  /* bad fragment received */
        +		goto again;
        +	else if ( i <= 0 && !*ok)
        +		return i;
        +
        +	p = (unsigned char *)s->init_buf->data;
        +	msg_len = msg_hdr->msg_len;
        +
        +	/* reconstruct message header */
        +	*(p++) = msg_hdr->type;
        +	l2n3(msg_len,p);
        +	s2n (msg_hdr->seq,p);
        +	l2n3(0,p);
        +	l2n3(msg_len,p);
        +	if (s->version != DTLS1_BAD_VER) {
        +		p       -= DTLS1_HM_HEADER_LENGTH;
        +		msg_len += DTLS1_HM_HEADER_LENGTH;
        +	}
        +
        +	ssl3_finish_mac(s, p, msg_len);
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
        +			p, msg_len,
        +			s, s->msg_callback_arg);
        +
        +	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
        +
        +	/* Don't change sequence numbers while listening */
        +	if (!s->d1->listen)
        +		s->d1->handshake_read_seq++;
        +
        +	s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
        +	return s->init_num;
        +
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +	*ok = 0;
        +	return -1;
        +	}
        +
        +
        +static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max)
        +	{
        +	size_t frag_off,frag_len,msg_len;
        +
        +	msg_len  = msg_hdr->msg_len;
        +	frag_off = msg_hdr->frag_off;
        +	frag_len = msg_hdr->frag_len;
        +
        +	/* sanity checking */
        +	if ( (frag_off+frag_len) > msg_len)
        +		{
        +		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
        +		return SSL_AD_ILLEGAL_PARAMETER;
        +		}
        +
        +	if ( (frag_off+frag_len) > (unsigned long)max)
        +		{
        +		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
        +		return SSL_AD_ILLEGAL_PARAMETER;
        +		}
        +
        +	if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
        +		{
        +		/* msg_len is limited to 2^24, but is effectively checked
        +		 * against max above */
        +		if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENGTH))
        +			{
        +			SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
        +			return SSL_AD_INTERNAL_ERROR;
        +			}
        +
        +		s->s3->tmp.message_size  = msg_len;
        +		s->d1->r_msg_hdr.msg_len = msg_len;
        +		s->s3->tmp.message_type  = msg_hdr->type;
        +		s->d1->r_msg_hdr.type    = msg_hdr->type;
        +		s->d1->r_msg_hdr.seq     = msg_hdr->seq;
        +		}
        +	else if (msg_len != s->d1->r_msg_hdr.msg_len)
        +		{
        +		/* They must be playing with us! BTW, failure to enforce
        +		 * upper limit would open possibility for buffer overrun. */
        +		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
        +		return SSL_AD_ILLEGAL_PARAMETER;
        +		}
        +
        +	return 0; /* no error */
        +	}
        +
        +
        +static int
        +dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
        +	{
        +	/* (0) check whether the desired fragment is available
        +	 * if so:
        +	 * (1) copy over the fragment to s->init_buf->data[]
        +	 * (2) update s->init_num
        +	 */
        +	pitem *item;
        +	hm_fragment *frag;
        +	int al;
        +
        +	*ok = 0;
        +	item = pqueue_peek(s->d1->buffered_messages);
        +	if ( item == NULL)
        +		return 0;
        +
        +	frag = (hm_fragment *)item->data;
        +	
        +	/* Don't return if reassembly still in progress */
        +	if (frag->reassembly != NULL)
        +		return 0;
        +
        +	if ( s->d1->handshake_read_seq == frag->msg_header.seq)
        +		{
        +		unsigned long frag_len = frag->msg_header.frag_len;
        +		pqueue_pop(s->d1->buffered_messages);
        +
        +		al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
        +
        +		if (al==0) /* no alert */
        +			{
        +			unsigned char *p = (unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
        +			memcpy(&p[frag->msg_header.frag_off],
        +				frag->fragment,frag->msg_header.frag_len);
        +			}
        +
        +		dtls1_hm_fragment_free(frag);
        +		pitem_free(item);
        +
        +		if (al==0)
        +			{
        +			*ok = 1;
        +			return frag_len;
        +			}
        +
        +		ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +		s->init_num = 0;
        +		*ok = 0;
        +		return -1;
        +		}
        +	else
        +		return 0;
        +	}
        +
        +
        +static int
        +dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
        +	{
        +	hm_fragment *frag = NULL;
        +	pitem *item = NULL;
        +	int i = -1, is_complete;
        +	unsigned char seq64be[8];
        +	unsigned long frag_len = msg_hdr->frag_len, max_len;
        +
        +	if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
        +		goto err;
        +
        +	/* Determine maximum allowed message size. Depends on (user set)
        +	 * maximum certificate length, but 16k is minimum.
        +	 */
        +	if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list)
        +		max_len = s->max_cert_list;
        +	else
        +		max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
        +
        +	if ((msg_hdr->frag_off+frag_len) > max_len)
        +		goto err;
        +
        +	/* Try to find item in queue */
        +	memset(seq64be,0,sizeof(seq64be));
        +	seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
        +	seq64be[7] = (unsigned char) msg_hdr->seq;
        +	item = pqueue_find(s->d1->buffered_messages, seq64be);
        +
        +	if (item == NULL)
        +		{
        +		frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
        +		if ( frag == NULL)
        +			goto err;
        +		memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
        +		frag->msg_header.frag_len = frag->msg_header.msg_len;
        +		frag->msg_header.frag_off = 0;
        +		}
        +	else
        +		frag = (hm_fragment*) item->data;
        +
        +	/* If message is already reassembled, this must be a
        +	 * retransmit and can be dropped.
        +	 */
        +	if (frag->reassembly == NULL)
        +		{
        +		unsigned char devnull [256];
        +
        +		while (frag_len)
        +			{
        +			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
        +				devnull,
        +				frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
        +			if (i<=0) goto err;
        +			frag_len -= i;
        +			}
        +		return DTLS1_HM_FRAGMENT_RETRY;
        +		}
        +
        +	/* read the body of the fragment (header has already been read */
        +	i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
        +		frag->fragment + msg_hdr->frag_off,frag_len,0);
        +	if (i<=0 || (unsigned long)i!=frag_len)
        +		goto err;
        +
        +	RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
        +	                    (long)(msg_hdr->frag_off + frag_len));
        +
        +	RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
        +	                           is_complete);
        +
        +	if (is_complete)
        +		{
        +		OPENSSL_free(frag->reassembly);
        +		frag->reassembly = NULL;
        +		}
        +
        +	if (item == NULL)
        +		{
        +		memset(seq64be,0,sizeof(seq64be));
        +		seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
        +		seq64be[7] = (unsigned char)(msg_hdr->seq);
        +
        +		item = pitem_new(seq64be, frag);
        +		if (item == NULL)
        +			{
        +			goto err;
        +			i = -1;
        +			}
        +
        +		pqueue_insert(s->d1->buffered_messages, item);
        +		}
        +
        +	return DTLS1_HM_FRAGMENT_RETRY;
        +
        +err:
        +	if (frag != NULL) dtls1_hm_fragment_free(frag);
        +	if (item != NULL) OPENSSL_free(item);
        +	*ok = 0;
        +	return i;
        +	}
        +
        +
        +static int
        +dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
        +{
        +	int i=-1;
        +	hm_fragment *frag = NULL;
        +	pitem *item = NULL;
        +	unsigned char seq64be[8];
        +	unsigned long frag_len = msg_hdr->frag_len;
        +
        +	if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
        +		goto err;
        +
        +	/* Try to find item in queue, to prevent duplicate entries */
        +	memset(seq64be,0,sizeof(seq64be));
        +	seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
        +	seq64be[7] = (unsigned char) msg_hdr->seq;
        +	item = pqueue_find(s->d1->buffered_messages, seq64be);
        +
        +	/* If we already have an entry and this one is a fragment,
        +	 * don't discard it and rather try to reassemble it.
        +	 */
        +	if (item != NULL && frag_len < msg_hdr->msg_len)
        +		item = NULL;
        +
        +	/* Discard the message if sequence number was already there, is
        +	 * too far in the future, already in the queue or if we received
        +	 * a FINISHED before the SERVER_HELLO, which then must be a stale
        +	 * retransmit.
        +	 */
        +	if (msg_hdr->seq <= s->d1->handshake_read_seq ||
        +		msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
        +		(s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED))
        +		{
        +		unsigned char devnull [256];
        +
        +		while (frag_len)
        +			{
        +			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
        +				devnull,
        +				frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
        +			if (i<=0) goto err;
        +			frag_len -= i;
        +			}
        +		}
        +	else
        +		{
        +		if (frag_len && frag_len < msg_hdr->msg_len)
        +			return dtls1_reassemble_fragment(s, msg_hdr, ok);
        +
        +		frag = dtls1_hm_fragment_new(frag_len, 0);
        +		if ( frag == NULL)
        +			goto err;
        +
        +		memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
        +
        +		if (frag_len)
        +			{
        +			/* read the body of the fragment (header has already been read */
        +			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
        +				frag->fragment,frag_len,0);
        +			if (i<=0 || (unsigned long)i!=frag_len)
        +				goto err;
        +			}
        +
        +		memset(seq64be,0,sizeof(seq64be));
        +		seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
        +		seq64be[7] = (unsigned char)(msg_hdr->seq);
        +
        +		item = pitem_new(seq64be, frag);
        +		if ( item == NULL)
        +			goto err;
        +
        +		pqueue_insert(s->d1->buffered_messages, item);
        +		}
        +
        +	return DTLS1_HM_FRAGMENT_RETRY;
        +
        +err:
        +	if ( frag != NULL) dtls1_hm_fragment_free(frag);
        +	if ( item != NULL) OPENSSL_free(item);
        +	*ok = 0;
        +	return i;
        +	}
        +
        +
        +static long
        +dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
        +	{
        +	unsigned char wire[DTLS1_HM_HEADER_LENGTH];
        +	unsigned long len, frag_off, frag_len;
        +	int i,al;
        +	struct hm_header_st msg_hdr;
        +
        +	/* see if we have the required fragment already */
        +	if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
        +		{
        +		if (*ok)	s->init_num = frag_len;
        +		return frag_len;
        +		}
        +
        +	/* read handshake message header */
        +	i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire,
        +		DTLS1_HM_HEADER_LENGTH, 0);
        +	if (i <= 0) 	/* nbio, or an error */
        +		{
        +		s->rwstate=SSL_READING;
        +		*ok = 0;
        +		return i;
        +		}
        +	/* Handshake fails if message header is incomplete */
        +	if (i != DTLS1_HM_HEADER_LENGTH)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
        +		goto f_err;
        +		}
        +
        +	/* parse the message fragment header */
        +	dtls1_get_message_header(wire, &msg_hdr);
        +
        +	/* 
        +	 * if this is a future (or stale) message it gets buffered
        +	 * (or dropped)--no further processing at this time
        +	 * While listening, we accept seq 1 (ClientHello with cookie)
        +	 * although we're still expecting seq 0 (ClientHello)
        +	 */
        +	if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1))
        +		return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
        +
        +	len = msg_hdr.msg_len;
        +	frag_off = msg_hdr.frag_off;
        +	frag_len = msg_hdr.frag_len;
        +
        +	if (frag_len && frag_len < len)
        +		return dtls1_reassemble_fragment(s, &msg_hdr, ok);
        +
        +	if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
        +		wire[0] == SSL3_MT_HELLO_REQUEST)
        +		{
        +		/* The server may always send 'Hello Request' messages --
        +		 * we are doing a handshake anyway now, so ignore them
        +		 * if their format is correct. Does not count for
        +		 * 'Finished' MAC. */
        +		if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0)
        +			{
        +			if (s->msg_callback)
        +				s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
        +					wire, DTLS1_HM_HEADER_LENGTH, s, 
        +					s->msg_callback_arg);
        +			
        +			s->init_num = 0;
        +			return dtls1_get_message_fragment(s, st1, stn,
        +				max, ok);
        +			}
        +		else /* Incorrectly formated Hello request */
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
        +			goto f_err;
        +			}
        +		}
        +
        +	if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
        +		goto f_err;
        +
        +	/* XDTLS:  ressurect this when restart is in place */
        +	s->state=stn;
        +
        +	if ( frag_len > 0)
        +		{
        +		unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
        +
        +		i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
        +			&p[frag_off],frag_len,0);
        +		/* XDTLS:  fix this--message fragments cannot span multiple packets */
        +		if (i <= 0)
        +			{
        +			s->rwstate=SSL_READING;
        +			*ok = 0;
        +			return i;
        +			}
        +		}
        +	else
        +		i = 0;
        +
        +	/* XDTLS:  an incorrectly formatted fragment should cause the 
        +	 * handshake to fail */
        +	if (i != (int)frag_len)
        +		{
        +		al=SSL3_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETER);
        +		goto f_err;
        +		}
        +
        +	*ok = 1;
        +
        +	/* Note that s->init_num is *not* used as current offset in
        +	 * s->init_buf->data, but as a counter summing up fragments'
        +	 * lengths: as soon as they sum up to handshake packet
        +	 * length, we assume we have got all the fragments. */
        +	s->init_num = frag_len;
        +	return frag_len;
        +
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +	s->init_num = 0;
        +
        +	*ok=0;
        +	return(-1);
        +	}
        +
        +int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
        +	{
        +	unsigned char *p,*d;
        +	int i;
        +	unsigned long l;
        +
        +	if (s->state == a)
        +		{
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[DTLS1_HM_HEADER_LENGTH]);
        +
        +		i=s->method->ssl3_enc->final_finish_mac(s,
        +			sender,slen,s->s3->tmp.finish_md);
        +		s->s3->tmp.finish_md_len = i;
        +		memcpy(p, s->s3->tmp.finish_md, i);
        +		p+=i;
        +		l=i;
        +
        +	/* Copy the finished so we can use it for
        +	 * renegotiation checks
        +	 */
        +	if(s->type == SSL_ST_CONNECT)
        +		{
        +		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
        +		memcpy(s->s3->previous_client_finished, 
        +		       s->s3->tmp.finish_md, i);
        +		s->s3->previous_client_finished_len=i;
        +		}
        +	else
        +		{
        +		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
        +		memcpy(s->s3->previous_server_finished, 
        +		       s->s3->tmp.finish_md, i);
        +		s->s3->previous_server_finished_len=i;
        +		}
        +
        +#ifdef OPENSSL_SYS_WIN16
        +		/* MSVC 1.5 does not clear the top bytes of the word unless
        +		 * I do this.
        +		 */
        +		l&=0xffff;
        +#endif
        +
        +		d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
        +		s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +
        +		s->state=b;
        +		}
        +
        +	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +/* for these 2 messages, we need to
        + * ssl->enc_read_ctx			re-init
        + * ssl->s3->read_sequence		zero
        + * ssl->s3->read_mac_secret		re-init
        + * ssl->session->read_sym_enc		assign
        + * ssl->session->read_compression	assign
        + * ssl->session->read_hash		assign
        + */
        +int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
        +	{ 
        +	unsigned char *p;
        +
        +	if (s->state == a)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*p++=SSL3_MT_CCS;
        +		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
        +		s->init_num=DTLS1_CCS_HEADER_LENGTH;
        +
        +		if (s->version == DTLS1_BAD_VER) {
        +			s->d1->next_handshake_write_seq++;
        +			s2n(s->d1->handshake_write_seq,p);
        +			s->init_num+=2;
        +		}
        +
        +		s->init_off=0;
        +
        +		dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, 
        +			s->d1->handshake_write_seq, 0, 0);
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 1);
        +
        +		s->state=b;
        +		}
        +
        +	/* SSL3_ST_CW_CHANGE_B */
        +	return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
        +	}
        +
        +static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
        +	{
        +	int n;
        +	unsigned char *p;
        +
        +	n=i2d_X509(x,NULL);
        +	if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
        +		{
        +		SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
        +		return 0;
        +		}
        +	p=(unsigned char *)&(buf->data[*l]);
        +	l2n3(n,p);
        +	i2d_X509(x,&p);
        +	*l+=n+3;
        +
        +	return 1;
        +	}
        +unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
        +	{
        +	unsigned char *p;
        +	int i;
        +	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
        +	BUF_MEM *buf;
        +
        +	/* TLSv1 sends a chain with nothing in it, instead of an alert */
        +	buf=s->init_buf;
        +	if (!BUF_MEM_grow_clean(buf,10))
        +		{
        +		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	if (x != NULL)
        +		{
        +		X509_STORE_CTX xs_ctx;
        +
        +		if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
        +  			{
        +  			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
        +  			return(0);
        +  			}
        +  
        +		X509_verify_cert(&xs_ctx);
        +		/* Don't leave errors in the queue */
        +		ERR_clear_error();
        +		for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
        +  			{
        +			x = sk_X509_value(xs_ctx.chain, i);
        +
        +			if (!dtls1_add_cert_to_buf(buf, &l, x))
        +  				{
        +				X509_STORE_CTX_cleanup(&xs_ctx);
        +				return 0;
        +  				}
        +  			}
        +  		X509_STORE_CTX_cleanup(&xs_ctx);
        +  		}
        +  	/* Thawte special :-) */
        +	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
        +		{
        +		x=sk_X509_value(s->ctx->extra_certs,i);
        +		if (!dtls1_add_cert_to_buf(buf, &l, x))
        +			return 0;
        +		}
        +
        +	l-= (3 + DTLS1_HM_HEADER_LENGTH);
        +
        +	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
        +	l2n3(l,p);
        +	l+=3;
        +	p=(unsigned char *)&(buf->data[0]);
        +	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);
        +
        +	l+=DTLS1_HM_HEADER_LENGTH;
        +	return(l);
        +	}
        +
        +int dtls1_read_failed(SSL *s, int code)
        +	{
        +	if ( code > 0)
        +		{
        +		fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
        +		return 1;
        +		}
        +
        +	if (!dtls1_is_timer_expired(s))
        +		{
        +		/* not a timeout, none of our business, 
        +		   let higher layers handle this.  in fact it's probably an error */
        +		return code;
        +		}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	if (!SSL_in_init(s) && !s->tlsext_hb_pending)  /* done, no need to send a retransmit */
        +#else
        +	if (!SSL_in_init(s))  /* done, no need to send a retransmit */
        +#endif
        +		{
        +		BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
        +		return code;
        +		}
        +
        +#if 0 /* for now, each alert contains only one record number */
        +	item = pqueue_peek(state->rcvd_records);
        +	if ( item )
        +		{
        +		/* send an alert immediately for all the missing records */
        +		}
        +	else
        +#endif
        +
        +#if 0  /* no more alert sending, just retransmit the last set of messages */
        +	if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
        +		ssl3_send_alert(s,SSL3_AL_WARNING,
        +			DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
        +#endif
        +
        +	return dtls1_handle_timeout(s);
        +	}
        +
        +int
        +dtls1_get_queue_priority(unsigned short seq, int is_ccs)
        +	{
        +	/* The index of the retransmission queue actually is the message sequence number,
        +	 * since the queue only contains messages of a single handshake. However, the
        +	 * ChangeCipherSpec has no message sequence number and so using only the sequence
        +	 * will result in the CCS and Finished having the same index. To prevent this,
        +	 * the sequence number is multiplied by 2. In case of a CCS 1 is subtracted.
        +	 * This does not only differ CSS and Finished, it also maintains the order of the
        +	 * index (important for priority queues) and fits in the unsigned short variable.
        +	 */	
        +	return seq * 2 - is_ccs;
        +	}
        +
        +int
        +dtls1_retransmit_buffered_messages(SSL *s)
        +	{
        +	pqueue sent = s->d1->sent_messages;
        +	piterator iter;
        +	pitem *item;
        +	hm_fragment *frag;
        +	int found = 0;
        +
        +	iter = pqueue_iterator(sent);
        +
        +	for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
        +		{
        +		frag = (hm_fragment *)item->data;
        +			if ( dtls1_retransmit_message(s,
        +				(unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs),
        +				0, &found) <= 0 && found)
        +			{
        +			fprintf(stderr, "dtls1_retransmit_message() failed\n");
        +			return -1;
        +			}
        +		}
        +
        +	return 1;
        +	}
        +
        +int
        +dtls1_buffer_message(SSL *s, int is_ccs)
        +	{
        +	pitem *item;
        +	hm_fragment *frag;
        +	unsigned char seq64be[8];
        +
        +	/* this function is called immediately after a message has 
        +	 * been serialized */
        +	OPENSSL_assert(s->init_off == 0);
        +
        +	frag = dtls1_hm_fragment_new(s->init_num, 0);
        +
        +	memcpy(frag->fragment, s->init_buf->data, s->init_num);
        +
        +	if ( is_ccs)
        +		{
        +		OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
        +			       ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num);
        +		}
        +	else
        +		{
        +		OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
        +			DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
        +		}
        +
        +	frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
        +	frag->msg_header.seq = s->d1->w_msg_hdr.seq;
        +	frag->msg_header.type = s->d1->w_msg_hdr.type;
        +	frag->msg_header.frag_off = 0;
        +	frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
        +	frag->msg_header.is_ccs = is_ccs;
        +
        +	/* save current state*/
        +	frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
        +	frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
        +	frag->msg_header.saved_retransmit_state.compress = s->compress;
        +	frag->msg_header.saved_retransmit_state.session = s->session;
        +	frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
        +	
        +	memset(seq64be,0,sizeof(seq64be));
        +	seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
        +														  frag->msg_header.is_ccs)>>8);
        +	seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
        +														  frag->msg_header.is_ccs));
        +
        +	item = pitem_new(seq64be, frag);
        +	if ( item == NULL)
        +		{
        +		dtls1_hm_fragment_free(frag);
        +		return 0;
        +		}
        +
        +#if 0
        +	fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
        +	fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
        +	fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
        +#endif
        +
        +	pqueue_insert(s->d1->sent_messages, item);
        +	return 1;
        +	}
        +
        +int
        +dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
        +	int *found)
        +	{
        +	int ret;
        +	/* XDTLS: for now assuming that read/writes are blocking */
        +	pitem *item;
        +	hm_fragment *frag ;
        +	unsigned long header_length;
        +	unsigned char seq64be[8];
        +	struct dtls1_retransmit_state saved_state;
        +	unsigned char save_write_sequence[8];
        +
        +	/*
        +	  OPENSSL_assert(s->init_num == 0);
        +	  OPENSSL_assert(s->init_off == 0);
        +	 */
        +
        +	/* XDTLS:  the requested message ought to be found, otherwise error */
        +	memset(seq64be,0,sizeof(seq64be));
        +	seq64be[6] = (unsigned char)(seq>>8);
        +	seq64be[7] = (unsigned char)seq;
        +
        +	item = pqueue_find(s->d1->sent_messages, seq64be);
        +	if ( item == NULL)
        +		{
        +		fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
        +		*found = 0;
        +		return 0;
        +		}
        +
        +	*found = 1;
        +	frag = (hm_fragment *)item->data;
        +
        +	if ( frag->msg_header.is_ccs)
        +		header_length = DTLS1_CCS_HEADER_LENGTH;
        +	else
        +		header_length = DTLS1_HM_HEADER_LENGTH;
        +
        +	memcpy(s->init_buf->data, frag->fragment, 
        +		frag->msg_header.msg_len + header_length);
        +		s->init_num = frag->msg_header.msg_len + header_length;
        +
        +	dtls1_set_message_header_int(s, frag->msg_header.type, 
        +		frag->msg_header.msg_len, frag->msg_header.seq, 0, 
        +		frag->msg_header.frag_len);
        +
        +	/* save current state */
        +	saved_state.enc_write_ctx = s->enc_write_ctx;
        +	saved_state.write_hash = s->write_hash;
        +	saved_state.compress = s->compress;
        +	saved_state.session = s->session;
        +	saved_state.epoch = s->d1->w_epoch;
        +	saved_state.epoch = s->d1->w_epoch;
        +	
        +	s->d1->retransmitting = 1;
        +	
        +	/* restore state in which the message was originally sent */
        +	s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
        +	s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
        +	s->compress = frag->msg_header.saved_retransmit_state.compress;
        +	s->session = frag->msg_header.saved_retransmit_state.session;
        +	s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
        +	
        +	if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
        +	{
        +		memcpy(save_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
        +		memcpy(s->s3->write_sequence, s->d1->last_write_sequence, sizeof(s->s3->write_sequence));
        +	}
        +	
        +	ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 
        +						 SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
        +	
        +	/* restore current state */
        +	s->enc_write_ctx = saved_state.enc_write_ctx;
        +	s->write_hash = saved_state.write_hash;
        +	s->compress = saved_state.compress;
        +	s->session = saved_state.session;
        +	s->d1->w_epoch = saved_state.epoch;
        +	
        +	if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
        +	{
        +		memcpy(s->d1->last_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
        +		memcpy(s->s3->write_sequence, save_write_sequence, sizeof(s->s3->write_sequence));
        +	}
        +
        +	s->d1->retransmitting = 0;
        +
        +	(void)BIO_flush(SSL_get_wbio(s));
        +	return ret;
        +	}
        +
        +/* call this function when the buffered messages are no longer needed */
        +void
        +dtls1_clear_record_buffer(SSL *s)
        +	{
        +	pitem *item;
        +
        +	for(item = pqueue_pop(s->d1->sent_messages);
        +		item != NULL; item = pqueue_pop(s->d1->sent_messages))
        +		{
        +		dtls1_hm_fragment_free((hm_fragment *)item->data);
        +		pitem_free(item);
        +		}
        +	}
        +
        +
        +unsigned char *
        +dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
        +			unsigned long len, unsigned long frag_off, unsigned long frag_len)
        +	{
        +	/* Don't change sequence numbers while listening */
        +	if (frag_off == 0 && !s->d1->listen)
        +		{
        +		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
        +		s->d1->next_handshake_write_seq++;
        +		}
        +
        +	dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
        +		frag_off, frag_len);
        +
        +	return p += DTLS1_HM_HEADER_LENGTH;
        +	}
        +
        +
        +/* don't actually do the writing, wait till the MTU has been retrieved */
        +static void
        +dtls1_set_message_header_int(SSL *s, unsigned char mt,
        +			    unsigned long len, unsigned short seq_num, unsigned long frag_off,
        +			    unsigned long frag_len)
        +	{
        +	struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
        +
        +	msg_hdr->type = mt;
        +	msg_hdr->msg_len = len;
        +	msg_hdr->seq = seq_num;
        +	msg_hdr->frag_off = frag_off;
        +	msg_hdr->frag_len = frag_len;
        +	}
        +
        +static void
        +dtls1_fix_message_header(SSL *s, unsigned long frag_off,
        +			unsigned long frag_len)
        +	{
        +	struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
        +
        +	msg_hdr->frag_off = frag_off;
        +	msg_hdr->frag_len = frag_len;
        +	}
        +
        +static unsigned char *
        +dtls1_write_message_header(SSL *s, unsigned char *p)
        +	{
        +	struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
        +
        +	*p++ = msg_hdr->type;
        +	l2n3(msg_hdr->msg_len, p);
        +
        +	s2n(msg_hdr->seq, p);
        +	l2n3(msg_hdr->frag_off, p);
        +	l2n3(msg_hdr->frag_len, p);
        +
        +	return p;
        +	}
        +
        +unsigned int 
        +dtls1_min_mtu(void)
        +	{
        +	return (g_probable_mtu[(sizeof(g_probable_mtu) / 
        +		sizeof(g_probable_mtu[0])) - 1]);
        +	}
        +
        +static unsigned int 
        +dtls1_guess_mtu(unsigned int curr_mtu)
        +	{
        +	unsigned int i;
        +
        +	if ( curr_mtu == 0 )
        +		return g_probable_mtu[0] ;
        +
        +	for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
        +		if ( curr_mtu > g_probable_mtu[i])
        +			return g_probable_mtu[i];
        +
        +	return curr_mtu;
        +	}
        +
        +void
        +dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
        +	{
        +	memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
        +	msg_hdr->type = *(data++);
        +	n2l3(data, msg_hdr->msg_len);
        +
        +	n2s(data, msg_hdr->seq);
        +	n2l3(data, msg_hdr->frag_off);
        +	n2l3(data, msg_hdr->frag_len);
        +	}
        +
        +void
        +dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
        +	{
        +	memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
        +
        +	ccs_hdr->type = *(data++);
        +	}
        +
        +int dtls1_shutdown(SSL *s)
        +	{
        +	int ret;
        +#ifndef OPENSSL_NO_SCTP
        +	if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
        +	    !(s->shutdown & SSL_SENT_SHUTDOWN))
        +		{
        +		ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
        +		if (ret < 0) return -1;
        +
        +		if (ret == 0)
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, NULL);
        +		}
        +#endif
        +	ret = ssl3_shutdown(s);
        +#ifndef OPENSSL_NO_SCTP
        +	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
        +#endif
        +	return ret;
        +	}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +int
        +dtls1_process_heartbeat(SSL *s)
        +	{
        +	unsigned char *p = &s->s3->rrec.data[0], *pl;
        +	unsigned short hbtype;
        +	unsigned int payload;
        +	unsigned int padding = 16; /* Use minimum padding */
        +
        +	/* Read type and payload length first */
        +	hbtype = *p++;
        +	n2s(p, payload);
        +	pl = p;
        +
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
        +			&s->s3->rrec.data[0], s->s3->rrec.length,
        +			s, s->msg_callback_arg);
        +
        +	if (hbtype == TLS1_HB_REQUEST)
        +		{
        +		unsigned char *buffer, *bp;
        +		int r;
        +
        +		/* Allocate memory for the response, size is 1 byte
        +		 * message type, plus 2 bytes payload length, plus
        +		 * payload, plus padding
        +		 */
        +		buffer = OPENSSL_malloc(1 + 2 + payload + padding);
        +		bp = buffer;
        +
        +		/* Enter response type, length and copy payload */
        +		*bp++ = TLS1_HB_RESPONSE;
        +		s2n(payload, bp);
        +		memcpy(bp, pl, payload);
        +		bp += payload;
        +		/* Random padding */
        +		RAND_pseudo_bytes(bp, padding);
        +
        +		r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
        +
        +		if (r >= 0 && s->msg_callback)
        +			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
        +				buffer, 3 + payload + padding,
        +				s, s->msg_callback_arg);
        +
        +		OPENSSL_free(buffer);
        +
        +		if (r < 0)
        +			return r;
        +		}
        +	else if (hbtype == TLS1_HB_RESPONSE)
        +		{
        +		unsigned int seq;
        +
        +		/* We only send sequence numbers (2 bytes unsigned int),
        +		 * and 16 random bytes, so we just try to read the
        +		 * sequence number */
        +		n2s(pl, seq);
        +
        +		if (payload == 18 && seq == s->tlsext_hb_seq)
        +			{
        +			dtls1_stop_timer(s);
        +			s->tlsext_hb_seq++;
        +			s->tlsext_hb_pending = 0;
        +			}
        +		}
        +
        +	return 0;
        +	}
        +
        +int
        +dtls1_heartbeat(SSL *s)
        +	{
        +	unsigned char *buf, *p;
        +	int ret;
        +	unsigned int payload = 18; /* Sequence number + random bytes */
        +	unsigned int padding = 16; /* Use minimum padding */
        +
        +	/* Only send if peer supports and accepts HB requests... */
        +	if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
        +	    s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
        +		{
        +		SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
        +		return -1;
        +		}
        +
        +	/* ...and there is none in flight yet... */
        +	if (s->tlsext_hb_pending)
        +		{
        +		SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
        +		return -1;
        +		}
        +
        +	/* ...and no handshake in progress. */
        +	if (SSL_in_init(s) || s->in_handshake)
        +		{
        +		SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
        +		return -1;
        +		}
        +
        +	/* Check if padding is too long, payload and padding
        +	 * must not exceed 2^14 - 3 = 16381 bytes in total.
        +	 */
        +	OPENSSL_assert(payload + padding <= 16381);
        +
        +	/* Create HeartBeat message, we just use a sequence number
        +	 * as payload to distuingish different messages and add
        +	 * some random stuff.
        +	 *  - Message Type, 1 byte
        +	 *  - Payload Length, 2 bytes (unsigned int)
        +	 *  - Payload, the sequence number (2 bytes uint)
        +	 *  - Payload, random bytes (16 bytes uint)
        +	 *  - Padding
        +	 */
        +	buf = OPENSSL_malloc(1 + 2 + payload + padding);
        +	p = buf;
        +	/* Message Type */
        +	*p++ = TLS1_HB_REQUEST;
        +	/* Payload length (18 bytes here) */
        +	s2n(payload, p);
        +	/* Sequence number */
        +	s2n(s->tlsext_hb_seq, p);
        +	/* 16 random bytes */
        +	RAND_pseudo_bytes(p, 16);
        +	p += 16;
        +	/* Random padding */
        +	RAND_pseudo_bytes(p, padding);
        +
        +	ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
        +	if (ret >= 0)
        +		{
        +		if (s->msg_callback)
        +			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
        +				buf, 3 + payload + padding,
        +				s, s->msg_callback_arg);
        +
        +		dtls1_start_timer(s);
        +		s->tlsext_hb_pending = 1;
        +		}
        +
        +	OPENSSL_free(buf);
        +
        +	return ret;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/d1_clnt.c b/vendor/openssl/openssl/ssl/d1_clnt.c
        new file mode 100644
        index 000000000..a6ed09c51
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_clnt.c
        @@ -0,0 +1,1710 @@
        +/* ssl/d1_clnt.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_KRB5
        +#include "kssl_lcl.h"
        +#endif
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/md5.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +static const SSL_METHOD *dtls1_get_client_method(int ver);
        +static int dtls1_get_hello_verify(SSL *s);
        +
        +static const SSL_METHOD *dtls1_get_client_method(int ver)
        +	{
        +	if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
        +		return(DTLSv1_client_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
        +			ssl_undefined_function,
        +			dtls1_connect,
        +			dtls1_get_client_method)
        +
        +int dtls1_connect(SSL *s)
        +	{
        +	BUF_MEM *buf=NULL;
        +	unsigned long Time=(unsigned long)time(NULL);
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int ret= -1;
        +	int new_state,state,skip=0;
        +#ifndef OPENSSL_NO_SCTP
        +	unsigned char sctpauthkey[64];
        +	char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
        +#endif
        +
        +	RAND_add(&Time,sizeof(Time),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +	
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
        +
        +#ifndef OPENSSL_NO_SCTP
        +	/* Notify SCTP BIO socket to enter handshake
        +	 * mode and prevent stream identifier other
        +	 * than 0. Will be ignored if no SCTP is used.
        +	 */
        +	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
        +#endif
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	/* If we're awaiting a HeartbeatResponse, pretend we
        +	 * already got and don't await it anymore, because
        +	 * Heartbeats don't make sense during handshakes anyway.
        +	 */
        +	if (s->tlsext_hb_pending)
        +		{
        +		dtls1_stop_timer(s);
        +		s->tlsext_hb_pending = 0;
        +		s->tlsext_hb_seq++;
        +		}
        +#endif
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch(s->state)
        +			{
        +		case SSL_ST_RENEGOTIATE:
        +			s->renegotiate=1;
        +			s->state=SSL_ST_CONNECT;
        +			s->ctx->stats.sess_connect_renegotiate++;
        +			/* break */
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_CONNECT:
        +		case SSL_ST_BEFORE|SSL_ST_CONNECT:
        +		case SSL_ST_OK|SSL_ST_CONNECT:
        +
        +			s->server=0;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00) &&
        +			    (s->version & 0xff00 ) != (DTLS1_BAD_VER & 0xff00))
        +				{
        +				SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
        +				ret = -1;
        +				goto end;
        +				}
        +				
        +			/* s->version=SSL3_VERSION; */
        +			s->type=SSL_ST_CONNECT;
        +
        +			if (s->init_buf == NULL)
        +				{
        +				if ((buf=BUF_MEM_new()) == NULL)
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				s->init_buf=buf;
        +				buf=NULL;
        +				}
        +
        +			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
        +
        +			/* setup buffing BIO */
        +			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
        +
        +			/* don't push the buffering BIO quite yet */
        +
        +			s->state=SSL3_ST_CW_CLNT_HELLO_A;
        +			s->ctx->stats.sess_connect++;
        +			s->init_num=0;
        +			/* mark client_random uninitialized */
        +			memset(s->s3->client_random,0,sizeof(s->s3->client_random));
        +			s->d1->send_cookie = 0;
        +			s->hit = 0;
        +			break;
        +
        +#ifndef OPENSSL_NO_SCTP
        +		case DTLS1_SCTP_ST_CR_READ_SOCK:
        +
        +			if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
        +			{
        +				s->s3->in_read_app_data=2;
        +				s->rwstate=SSL_READING;
        +				BIO_clear_retry_flags(SSL_get_rbio(s));
        +				BIO_set_retry_read(SSL_get_rbio(s));
        +				ret = -1;
        +				goto end;
        +			}
        +
        +			s->state=s->s3->tmp.next_state;
        +			break;
        +
        +		case DTLS1_SCTP_ST_CW_WRITE_SOCK:
        +			/* read app data until dry event */
        +
        +			ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
        +			if (ret < 0) goto end;
        +
        +			if (ret == 0)
        +			{
        +				s->s3->in_read_app_data=2;
        +				s->rwstate=SSL_READING;
        +				BIO_clear_retry_flags(SSL_get_rbio(s));
        +				BIO_set_retry_read(SSL_get_rbio(s));
        +				ret = -1;
        +				goto end;
        +			}
        +
        +			s->state=s->d1->next_state;
        +			break;
        +#endif
        +
        +		case SSL3_ST_CW_CLNT_HELLO_A:
        +		case SSL3_ST_CW_CLNT_HELLO_B:
        +
        +			s->shutdown=0;
        +
        +			/* every DTLS ClientHello resets Finished MAC */
        +			ssl3_init_finished_mac(s);
        +
        +			dtls1_start_timer(s);
        +			ret=dtls1_client_hello(s);
        +			if (ret <= 0) goto end;
        +
        +			if ( s->d1->send_cookie)
        +				{
        +				s->state=SSL3_ST_CW_FLUSH;
        +				s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A;
        +				}
        +			else
        +				s->state=SSL3_ST_CR_SRVR_HELLO_A;
        +
        +			s->init_num=0;
        +
        +#ifndef OPENSSL_NO_SCTP
        +			/* Disable buffering for SCTP */
        +			if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +				{
        +#endif
        +				/* turn on buffering for the next lot of output */
        +				if (s->bbio != s->wbio)
        +					s->wbio=BIO_push(s->bbio,s->wbio);
        +#ifndef OPENSSL_NO_SCTP
        +				}
        +#endif
        +
        +			break;
        +
        +		case SSL3_ST_CR_SRVR_HELLO_A:
        +		case SSL3_ST_CR_SRVR_HELLO_B:
        +			ret=ssl3_get_server_hello(s);
        +			if (ret <= 0) goto end;
        +			else
        +				{
        +				if (s->hit)
        +					{
        +#ifndef OPENSSL_NO_SCTP
        +					/* Add new shared key for SCTP-Auth,
        +					 * will be ignored if no SCTP used.
        +					 */
        +					snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
        +					         DTLS1_SCTP_AUTH_LABEL);
        +
        +					SSL_export_keying_material(s, sctpauthkey,
        +					                           sizeof(sctpauthkey), labelbuffer,
        +					                           sizeof(labelbuffer), NULL, 0, 0);
        +
        +					BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
        +							 sizeof(sctpauthkey), sctpauthkey);
        +#endif
        +
        +					s->state=SSL3_ST_CR_FINISHED_A;
        +					}
        +				else
        +					s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
        +				}
        +			s->init_num=0;
        +			break;
        +
        +		case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
        +		case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
        +
        +			ret = dtls1_get_hello_verify(s);
        +			if ( ret <= 0)
        +				goto end;
        +			dtls1_stop_timer(s);
        +			if ( s->d1->send_cookie) /* start again, with a cookie */
        +				s->state=SSL3_ST_CW_CLNT_HELLO_A;
        +			else
        +				s->state = SSL3_ST_CR_CERT_A;
        +			s->init_num = 0;
        +			break;
        +
        +		case SSL3_ST_CR_CERT_A:
        +		case SSL3_ST_CR_CERT_B:
        +#ifndef OPENSSL_NO_TLSEXT
        +			ret=ssl3_check_finished(s);
        +			if (ret <= 0) goto end;
        +			if (ret == 2)
        +				{
        +				s->hit = 1;
        +				if (s->tlsext_ticket_expected)
        +					s->state=SSL3_ST_CR_SESSION_TICKET_A;
        +				else
        +					s->state=SSL3_ST_CR_FINISHED_A;
        +				s->init_num=0;
        +				break;
        +				}
        +#endif
        +			/* Check if it is anon DH or PSK */
        +			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
        +			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +				{
        +				ret=ssl3_get_server_certificate(s);
        +				if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (s->tlsext_status_expected)
        +					s->state=SSL3_ST_CR_CERT_STATUS_A;
        +				else
        +					s->state=SSL3_ST_CR_KEY_EXCH_A;
        +				}
        +			else
        +				{
        +				skip = 1;
        +				s->state=SSL3_ST_CR_KEY_EXCH_A;
        +				}
        +#else
        +				}
        +			else
        +				skip=1;
        +
        +			s->state=SSL3_ST_CR_KEY_EXCH_A;
        +#endif
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CR_KEY_EXCH_A:
        +		case SSL3_ST_CR_KEY_EXCH_B:
        +			ret=ssl3_get_key_exchange(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_CERT_REQ_A;
        +			s->init_num=0;
        +
        +			/* at this point we check that we have the
        +			 * required stuff from the server */
        +			if (!ssl3_check_cert_and_algorithm(s))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			break;
        +
        +		case SSL3_ST_CR_CERT_REQ_A:
        +		case SSL3_ST_CR_CERT_REQ_B:
        +			ret=ssl3_get_certificate_request(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_SRVR_DONE_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CR_SRVR_DONE_A:
        +		case SSL3_ST_CR_SRVR_DONE_B:
        +			ret=ssl3_get_server_done(s);
        +			if (ret <= 0) goto end;
        +			dtls1_stop_timer(s);
        +			if (s->s3->tmp.cert_req)
        +				s->s3->tmp.next_state=SSL3_ST_CW_CERT_A;
        +			else
        +				s->s3->tmp.next_state=SSL3_ST_CW_KEY_EXCH_A;
        +			s->init_num=0;
        +
        +#ifndef OPENSSL_NO_SCTP			
        +			if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
        +			    state == SSL_ST_RENEGOTIATE)
        +				s->state=DTLS1_SCTP_ST_CR_READ_SOCK;
        +			else
        +#endif			
        +			s->state=s->s3->tmp.next_state;
        +			break;
        +
        +		case SSL3_ST_CW_CERT_A:
        +		case SSL3_ST_CW_CERT_B:
        +		case SSL3_ST_CW_CERT_C:
        +		case SSL3_ST_CW_CERT_D:
        +			dtls1_start_timer(s);
        +			ret=dtls1_send_client_certificate(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CW_KEY_EXCH_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_KEY_EXCH_A:
        +		case SSL3_ST_CW_KEY_EXCH_B:
        +			dtls1_start_timer(s);
        +			ret=dtls1_send_client_key_exchange(s);
        +			if (ret <= 0) goto end;
        +
        +#ifndef OPENSSL_NO_SCTP
        +			/* Add new shared key for SCTP-Auth,
        +			 * will be ignored if no SCTP used.
        +			 */
        +			snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
        +			         DTLS1_SCTP_AUTH_LABEL);
        +
        +			SSL_export_keying_material(s, sctpauthkey,
        +			                           sizeof(sctpauthkey), labelbuffer,
        +			                           sizeof(labelbuffer), NULL, 0, 0);
        +
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
        +					 sizeof(sctpauthkey), sctpauthkey);
        +#endif
        +
        +			/* EAY EAY EAY need to check for DH fix cert
        +			 * sent back */
        +			/* For TLS, cert_req is set to 2, so a cert chain
        +			 * of nothing is sent, but no verify packet is sent */
        +			if (s->s3->tmp.cert_req == 1)
        +				{
        +				s->state=SSL3_ST_CW_CERT_VRFY_A;
        +				}
        +			else
        +				{
        +#ifndef OPENSSL_NO_SCTP
        +				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +					{
        +					s->d1->next_state=SSL3_ST_CW_CHANGE_A;
        +					s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
        +					}
        +				else
        +#endif
        +					s->state=SSL3_ST_CW_CHANGE_A;
        +				s->s3->change_cipher_spec=0;
        +				}
        +
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_CERT_VRFY_A:
        +		case SSL3_ST_CW_CERT_VRFY_B:
        +			dtls1_start_timer(s);
        +			ret=dtls1_send_client_verify(s);
        +			if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_SCTP
        +			if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +			{
        +				s->d1->next_state=SSL3_ST_CW_CHANGE_A;
        +				s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
        +			}
        +			else
        +#endif
        +				s->state=SSL3_ST_CW_CHANGE_A;
        +			s->init_num=0;
        +			s->s3->change_cipher_spec=0;
        +			break;
        +
        +		case SSL3_ST_CW_CHANGE_A:
        +		case SSL3_ST_CW_CHANGE_B:
        +			if (!s->hit)
        +				dtls1_start_timer(s);
        +			ret=dtls1_send_change_cipher_spec(s,
        +				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
        +			if (ret <= 0) goto end;
        +
        +#ifndef OPENSSL_NO_SCTP
        +			/* Change to new shared key of SCTP-Auth,
        +			 * will be ignored if no SCTP used.
        +			 */
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
        +#endif
        +
        +			s->state=SSL3_ST_CW_FINISHED_A;
        +			s->init_num=0;
        +
        +			s->session->cipher=s->s3->tmp.new_cipher;
        +#ifdef OPENSSL_NO_COMP
        +			s->session->compress_meth=0;
        +#else
        +			if (s->s3->tmp.new_compression == NULL)
        +				s->session->compress_meth=0;
        +			else
        +				s->session->compress_meth=
        +					s->s3->tmp.new_compression->id;
        +#endif
        +			if (!s->method->ssl3_enc->setup_key_block(s))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			if (!s->method->ssl3_enc->change_cipher_state(s,
        +				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			
        +			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
        +			break;
        +
        +		case SSL3_ST_CW_FINISHED_A:
        +		case SSL3_ST_CW_FINISHED_B:
        +			if (!s->hit)
        +				dtls1_start_timer(s);
        +			ret=dtls1_send_finished(s,
        +				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
        +				s->method->ssl3_enc->client_finished_label,
        +				s->method->ssl3_enc->client_finished_label_len);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CW_FLUSH;
        +
        +			/* clear flags */
        +			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
        +			if (s->hit)
        +				{
        +				s->s3->tmp.next_state=SSL_ST_OK;
        +#ifndef OPENSSL_NO_SCTP
        +				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +					{
        +						s->d1->next_state = s->s3->tmp.next_state;
        +						s->s3->tmp.next_state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
        +					}
        +#endif
        +				if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
        +					{
        +					s->state=SSL_ST_OK;
        +#ifndef OPENSSL_NO_SCTP
        +					if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +						{
        +							s->d1->next_state = SSL_ST_OK;
        +							s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
        +						}
        +#endif
        +					s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
        +					s->s3->delay_buf_pop_ret=0;
        +					}
        +				}
        +			else
        +				{
        +#ifndef OPENSSL_NO_TLSEXT
        +				/* Allow NewSessionTicket if ticket expected */
        +				if (s->tlsext_ticket_expected)
        +					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
        +				else
        +#endif
        +				
        +				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
        +				}
        +			s->init_num=0;
        +			break;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		case SSL3_ST_CR_SESSION_TICKET_A:
        +		case SSL3_ST_CR_SESSION_TICKET_B:
        +			ret=ssl3_get_new_session_ticket(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_FINISHED_A;
        +			s->init_num=0;
        +		break;
        +
        +		case SSL3_ST_CR_CERT_STATUS_A:
        +		case SSL3_ST_CR_CERT_STATUS_B:
        +			ret=ssl3_get_cert_status(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_KEY_EXCH_A;
        +			s->init_num=0;
        +		break;
        +#endif
        +
        +		case SSL3_ST_CR_FINISHED_A:
        +		case SSL3_ST_CR_FINISHED_B:
        +			s->d1->change_cipher_spec_ok = 1;
        +			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
        +				SSL3_ST_CR_FINISHED_B);
        +			if (ret <= 0) goto end;
        +			dtls1_stop_timer(s);
        +
        +			if (s->hit)
        +				s->state=SSL3_ST_CW_CHANGE_A;
        +			else
        +				s->state=SSL_ST_OK;
        +
        +#ifndef OPENSSL_NO_SCTP
        +			if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
        +				state == SSL_ST_RENEGOTIATE)
        +				{
        +				s->d1->next_state=s->state;
        +				s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
        +				}
        +#endif
        +
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_FLUSH:
        +			s->rwstate=SSL_WRITING;
        +			if (BIO_flush(s->wbio) <= 0)
        +				{
        +				/* If the write error was fatal, stop trying */
        +				if (!BIO_should_retry(s->wbio))
        +					{
        +					s->rwstate=SSL_NOTHING;
        +					s->state=s->s3->tmp.next_state;
        +					}
        +				
        +				ret= -1;
        +				goto end;
        +				}
        +			s->rwstate=SSL_NOTHING;
        +			s->state=s->s3->tmp.next_state;
        +			break;
        +
        +		case SSL_ST_OK:
        +			/* clean a few things up */
        +			ssl3_cleanup_key_block(s);
        +
        +#if 0
        +			if (s->init_buf != NULL)
        +				{
        +				BUF_MEM_free(s->init_buf);
        +				s->init_buf=NULL;
        +				}
        +#endif
        +
        +			/* If we are not 'joining' the last two packets,
        +			 * remove the buffering now */
        +			if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
        +				ssl_free_wbio_buffer(s);
        +			/* else do it later in ssl3_write */
        +
        +			s->init_num=0;
        +			s->renegotiate=0;
        +			s->new_session=0;
        +
        +			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
        +			if (s->hit) s->ctx->stats.sess_hit++;
        +
        +			ret=1;
        +			/* s->server=0; */
        +			s->handshake_func=dtls1_connect;
        +			s->ctx->stats.sess_connect_good++;
        +
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
        +
        +			/* done with handshaking */
        +			s->d1->handshake_read_seq  = 0;
        +			s->d1->next_handshake_write_seq = 0;
        +			goto end;
        +			/* break; */
        +			
        +		default:
        +			SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* break; */
        +			}
        +
        +		/* did we do anything */
        +		if (!s->s3->tmp.reuse_message && !skip)
        +			{
        +			if (s->debug)
        +				{
        +				if ((ret=BIO_flush(s->wbio)) <= 0)
        +					goto end;
        +				}
        +
        +			if ((cb != NULL) && (s->state != state))
        +				{
        +				new_state=s->state;
        +				s->state=state;
        +				cb(s,SSL_CB_CONNECT_LOOP,1);
        +				s->state=new_state;
        +				}
        +			}
        +		skip=0;
        +		}
        +end:
        +	s->in_handshake--;
        +	
        +#ifndef OPENSSL_NO_SCTP
        +	/* Notify SCTP BIO socket to leave handshake
        +	 * mode and allow stream identifier other
        +	 * than 0. Will be ignored if no SCTP is used.
        +	 */
        +	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
        +#endif
        +
        +	if (buf != NULL)
        +		BUF_MEM_free(buf);
        +	if (cb != NULL)
        +		cb(s,SSL_CB_CONNECT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +int dtls1_client_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	unsigned int i,j;
        +	unsigned long Time,l;
        +	SSL_COMP *comp;
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
        +		{
        +		SSL_SESSION *sess = s->session;
        +		if ((s->session == NULL) ||
        +			(s->session->ssl_version != s->version) ||
        +#ifdef OPENSSL_NO_TLSEXT
        +			!sess->session_id_length ||
        +#else
        +			(!sess->session_id_length && !sess->tlsext_tick) ||
        +#endif
        +			(s->session->not_resumable))
        +			{
        +			if (!ssl_get_new_session(s,0))
        +				goto err;
        +			}
        +		/* else use the pre-loaded session */
        +
        +		p=s->s3->client_random;
        +
        +		/* if client_random is initialized, reuse it, we are
        +		 * required to use same upon reply to HelloVerify */
        +		for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
        +		if (i==sizeof(s->s3->client_random))
        +			{
        +			Time=(unsigned long)time(NULL);	/* Time */
        +			l2n(Time,p);
        +			RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
        +			}
        +
        +		/* Do the message type and length last */
        +		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
        +
        +		*(p++)=s->version>>8;
        +		*(p++)=s->version&0xff;
        +		s->client_version=s->version;
        +
        +		/* Random stuff */
        +		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
        +		p+=SSL3_RANDOM_SIZE;
        +
        +		/* Session ID */
        +		if (s->new_session)
        +			i=0;
        +		else
        +			i=s->session->session_id_length;
        +		*(p++)=i;
        +		if (i != 0)
        +			{
        +			if (i > sizeof s->session->session_id)
        +				{
        +				SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			memcpy(p,s->session->session_id,i);
        +			p+=i;
        +			}
        +		
        +		/* cookie stuff */
        +		if ( s->d1->cookie_len > sizeof(s->d1->cookie))
        +			{
        +			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		*(p++) = s->d1->cookie_len;
        +		memcpy(p, s->d1->cookie, s->d1->cookie_len);
        +		p += s->d1->cookie_len;
        +
        +		/* Ciphers supported */
        +		i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
        +			goto err;
        +			}
        +		s2n(i,p);
        +		p+=i;
        +
        +		/* COMPRESSION */
        +		if (s->ctx->comp_methods == NULL)
        +			j=0;
        +		else
        +			j=sk_SSL_COMP_num(s->ctx->comp_methods);
        +		*(p++)=1+j;
        +		for (i=0; i<j; i++)
        +			{
        +			comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
        +			*(p++)=comp->id;
        +			}
        +		*(p++)=0; /* Add the NULL method */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
        +			{
        +			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +#endif		
        +
        +		l=(p-d);
        +		d=buf;
        +
        +		d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l);
        +
        +		s->state=SSL3_ST_CW_CLNT_HELLO_B;
        +		/* number of bytes to write */
        +		s->init_num=p-buf;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +
        +	/* SSL3_ST_CW_CLNT_HELLO_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +	return(-1);
        +	}
        +
        +static int dtls1_get_hello_verify(SSL *s)
        +	{
        +	int n, al, ok = 0;
        +	unsigned char *data;
        +	unsigned int cookie_len;
        +
        +	n=s->method->ssl_get_message(s,
        +		DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
        +		DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST)
        +		{
        +		s->d1->send_cookie = 0;
        +		s->s3->tmp.reuse_message=1;
        +		return(1);
        +		}
        +
        +	data = (unsigned char *)s->init_msg;
        +
        +	if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff)))
        +		{
        +		SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION);
        +		s->version=(s->version&0xff00)|data[1];
        +		al = SSL_AD_PROTOCOL_VERSION;
        +		goto f_err;
        +		}
        +	data+=2;
        +
        +	cookie_len = *(data++);
        +	if ( cookie_len > sizeof(s->d1->cookie))
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		goto f_err;
        +		}
        +
        +	memcpy(s->d1->cookie, data, cookie_len);
        +	s->d1->cookie_len = cookie_len;
        +
        +	s->d1->send_cookie = 1;
        +	return 1;
        +
        +f_err:
        +	ssl3_send_alert(s, SSL3_AL_FATAL, al);
        +	return -1;
        +	}
        +
        +int dtls1_send_client_key_exchange(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	int n;
        +	unsigned long alg_k;
        +#ifndef OPENSSL_NO_RSA
        +	unsigned char *q;
        +	EVP_PKEY *pkey=NULL;
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +        KSSL_ERR kssl_err;
        +#endif /* OPENSSL_NO_KRB5 */
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *clnt_ecdh = NULL;
        +	const EC_POINT *srvr_ecpoint = NULL;
        +	EVP_PKEY *srvr_pub_pkey = NULL;
        +	unsigned char *encodedPoint = NULL;
        +	int encoded_pt_len = 0;
        +	BN_CTX * bn_ctx = NULL;
        +#endif
        +
        +	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
        +		{
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[DTLS1_HM_HEADER_LENGTH]);
        +		
        +		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
        +
        +                /* Fool emacs indentation */
        +                if (0) {}
        +#ifndef OPENSSL_NO_RSA
        +		else if (alg_k & SSL_kRSA)
        +			{
        +			RSA *rsa;
        +			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
        +
        +			if (s->session->sess_cert->peer_rsa_tmp != NULL)
        +				rsa=s->session->sess_cert->peer_rsa_tmp;
        +			else
        +				{
        +				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
        +				if ((pkey == NULL) ||
        +					(pkey->type != EVP_PKEY_RSA) ||
        +					(pkey->pkey.rsa == NULL))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +					goto err;
        +					}
        +				rsa=pkey->pkey.rsa;
        +				EVP_PKEY_free(pkey);
        +				}
        +				
        +			tmp_buf[0]=s->client_version>>8;
        +			tmp_buf[1]=s->client_version&0xff;
        +			if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
        +					goto err;
        +
        +			s->session->master_key_length=sizeof tmp_buf;
        +
        +			q=p;
        +			/* Fix buf for TLS and [incidentally] DTLS */
        +			if (s->version > SSL3_VERSION)
        +				p+=2;
        +			n=RSA_public_encrypt(sizeof tmp_buf,
        +				tmp_buf,p,rsa,RSA_PKCS1_PADDING);
        +#ifdef PKCS1_CHECK
        +			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
        +			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
        +#endif
        +			if (n <= 0)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
        +				goto err;
        +				}
        +
        +			/* Fix buf for TLS and [incidentally] DTLS */
        +			if (s->version > SSL3_VERSION)
        +				{
        +				s2n(n,q);
        +				n+=2;
        +				}
        +
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,
        +					tmp_buf,sizeof tmp_buf);
        +			OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
        +			}
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +		else if (alg_k & SSL_kKRB5)
        +                        {
        +                        krb5_error_code	krb5rc;
        +                        KSSL_CTX	*kssl_ctx = s->kssl_ctx;
        +                        /*  krb5_data	krb5_ap_req;  */
        +                        krb5_data	*enc_ticket;
        +                        krb5_data	authenticator, *authp = NULL;
        +			EVP_CIPHER_CTX	ciph_ctx;
        +			const EVP_CIPHER *enc = NULL;
        +			unsigned char	iv[EVP_MAX_IV_LENGTH];
        +			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
        +			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH 
        +						+ EVP_MAX_IV_LENGTH];
        +			int 		padl, outl = sizeof(epms);
        +
        +			EVP_CIPHER_CTX_init(&ciph_ctx);
        +
        +#ifdef KSSL_DEBUG
        +                        printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
        +                                alg_k, SSL_kKRB5);
        +#endif	/* KSSL_DEBUG */
        +
        +			authp = NULL;
        +#ifdef KRB5SENDAUTH
        +			if (KRB5SENDAUTH)  authp = &authenticator;
        +#endif	/* KRB5SENDAUTH */
        +
        +                        krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
        +				&kssl_err);
        +			enc = kssl_map_enc(kssl_ctx->enctype);
        +                        if (enc == NULL)
        +                            goto err;
        +#ifdef KSSL_DEBUG
        +                        {
        +                        printf("kssl_cget_tkt rtn %d\n", krb5rc);
        +                        if (krb5rc && kssl_err.text)
        +			  printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
        +                        }
        +#endif	/* KSSL_DEBUG */
        +
        +                        if (krb5rc)
        +                                {
        +                                ssl3_send_alert(s,SSL3_AL_FATAL,
        +						SSL_AD_HANDSHAKE_FAILURE);
        +                                SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +						kssl_err.reason);
        +                                goto err;
        +                                }
        +
        +			/*  20010406 VRS - Earlier versions used KRB5 AP_REQ
        +			**  in place of RFC 2712 KerberosWrapper, as in:
        +			**
        +                        **  Send ticket (copy to *p, set n = length)
        +                        **  n = krb5_ap_req.length;
        +                        **  memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
        +                        **  if (krb5_ap_req.data)  
        +                        **    kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
        +                        **
        +			**  Now using real RFC 2712 KerberosWrapper
        +			**  (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
        +			**  Note: 2712 "opaque" types are here replaced
        +			**  with a 2-byte length followed by the value.
        +			**  Example:
        +			**  KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
        +			**  Where "xx xx" = length bytes.  Shown here with
        +			**  optional authenticator omitted.
        +			*/
        +
        +			/*  KerberosWrapper.Ticket		*/
        +			s2n(enc_ticket->length,p);
        +			memcpy(p, enc_ticket->data, enc_ticket->length);
        +			p+= enc_ticket->length;
        +			n = enc_ticket->length + 2;
        +
        +			/*  KerberosWrapper.Authenticator	*/
        +			if (authp  &&  authp->length)  
        +				{
        +				s2n(authp->length,p);
        +				memcpy(p, authp->data, authp->length);
        +				p+= authp->length;
        +				n+= authp->length + 2;
        +				
        +				free(authp->data);
        +				authp->data = NULL;
        +				authp->length = 0;
        +				}
        +			else
        +				{
        +				s2n(0,p);/*  null authenticator length	*/
        +				n+=2;
        +				}
        + 
        +			if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0)
        +			    goto err;
        +
        +			/*  20010420 VRS.  Tried it this way; failed.
        +			**	EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
        +			**	EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
        +			**				kssl_ctx->length);
        +			**	EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
        +			*/
        +
        +			memset(iv, 0, sizeof iv);  /* per RFC 1510 */
        +			EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
        +				kssl_ctx->key,iv);
        +			EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
        +				sizeof tmp_buf);
        +			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
        +			outl += padl;
        +			if (outl > (int)sizeof epms)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			EVP_CIPHER_CTX_cleanup(&ciph_ctx);
        +
        +			/*  KerberosWrapper.EncryptedPreMasterSecret	*/
        +			s2n(outl,p);
        +			memcpy(p, epms, outl);
        +			p+=outl;
        +			n+=outl + 2;
        +
        +                        s->session->master_key_length=
        +                                s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,
        +					tmp_buf, sizeof tmp_buf);
        +
        +			OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
        +			OPENSSL_cleanse(epms, outl);
        +                        }
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
        +			{
        +			DH *dh_srvr,*dh_clnt;
        +
        +			if (s->session->sess_cert->peer_dh_tmp != NULL)
        +				dh_srvr=s->session->sess_cert->peer_dh_tmp;
        +			else
        +				{
        +				/* we get them from the cert */
        +				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
        +				goto err;
        +				}
        +			
        +			/* generate a new random key */
        +			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				goto err;
        +				}
        +			if (!DH_generate_key(dh_clnt))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				goto err;
        +				}
        +
        +			/* use the 'p' output buffer for the DH key, but
        +			 * make sure to clear it out afterwards */
        +
        +			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
        +
        +			if (n <= 0)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				goto err;
        +				}
        +
        +			/* generate master key from the result */
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,p,n);
        +			/* clean up */
        +			memset(p,0,n);
        +
        +			/* send off the data */
        +			n=BN_num_bytes(dh_clnt->pub_key);
        +			s2n(n,p);
        +			BN_bn2bin(dh_clnt->pub_key,p);
        +			n+=2;
        +
        +			DH_free(dh_clnt);
        +
        +			/* perhaps clean things up a bit EAY EAY EAY EAY*/
        +			}
        +#endif
        +#ifndef OPENSSL_NO_ECDH 
        +		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
        +			{
        +			const EC_GROUP *srvr_group = NULL;
        +			EC_KEY *tkey;
        +			int ecdh_clnt_cert = 0;
        +			int field_size = 0;
        +
        +			/* Did we send out the client's
        +			 * ECDH share for use in premaster
        +			 * computation as part of client certificate?
        +			 * If so, set ecdh_clnt_cert to 1.
        +			 */
        +			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
        +				{
        +				/* XXX: For now, we do not support client
        +				 * authentication using ECDH certificates.
        +				 * To add such support, one needs to add
        +				 * code that checks for appropriate 
        +				 * conditions and sets ecdh_clnt_cert to 1.
        +				 * For example, the cert have an ECC
        +				 * key on the same curve as the server's
        +				 * and the key should be authorized for
        +				 * key agreement.
        +				 *
        +				 * One also needs to add code in ssl3_connect
        +				 * to skip sending the certificate verify
        +				 * message.
        +				 *
        +				 * if ((s->cert->key->privatekey != NULL) &&
        +				 *     (s->cert->key->privatekey->type ==
        +				 *      EVP_PKEY_EC) && ...)
        +				 * ecdh_clnt_cert = 1;
        +				 */
        +				}
        +
        +			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
        +				{
        +				tkey = s->session->sess_cert->peer_ecdh_tmp;
        +				}
        +			else
        +				{
        +				/* Get the Server Public Key from Cert */
        +				srvr_pub_pkey = X509_get_pubkey(s->session-> \
        +				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
        +				if ((srvr_pub_pkey == NULL) ||
        +				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
        +				    (srvr_pub_pkey->pkey.ec == NULL))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +					    ERR_R_INTERNAL_ERROR);
        +					goto err;
        +					}
        +
        +				tkey = srvr_pub_pkey->pkey.ec;
        +				}
        +
        +			srvr_group   = EC_KEY_get0_group(tkey);
        +			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
        +
        +			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +				    ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
        +				goto err;
        +				}
        +			if (ecdh_clnt_cert) 
        +				{ 
        +				/* Reuse key info from our certificate
        +				 * We only need our private key to perform
        +				 * the ECDH computation.
        +				 */
        +				const BIGNUM *priv_key;
        +				tkey = s->cert->key->privatekey->pkey.ec;
        +				priv_key = EC_KEY_get0_private_key(tkey);
        +				if (priv_key == NULL)
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
        +					goto err;
        +					}
        +				}
        +			else 
        +				{
        +				/* Generate a new ECDH key pair */
        +				if (!(EC_KEY_generate_key(clnt_ecdh)))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
        +					goto err;
        +					}
        +				}
        +
        +			/* use the 'p' output buffer for the ECDH key, but
        +			 * make sure to clear it out afterwards
        +			 */
        +
        +			field_size = EC_GROUP_get_degree(srvr_group);
        +			if (field_size <= 0)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 
        +				       ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
        +			if (n <= 0)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 
        +				       ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			/* generate master key from the result */
        +			s->session->master_key_length = s->method->ssl3_enc \
        +			    -> generate_master_secret(s, 
        +				s->session->master_key,
        +				p, n);
        +
        +			memset(p, 0, n); /* clean up */
        +
        +			if (ecdh_clnt_cert) 
        +				{
        +				/* Send empty client key exch message */
        +				n = 0;
        +				}
        +			else 
        +				{
        +				/* First check the size of encoding and
        +				 * allocate memory accordingly.
        +				 */
        +				encoded_pt_len = 
        +				    EC_POINT_point2oct(srvr_group, 
        +					EC_KEY_get0_public_key(clnt_ecdh), 
        +					POINT_CONVERSION_UNCOMPRESSED, 
        +					NULL, 0, NULL);
        +
        +				encodedPoint = (unsigned char *) 
        +				    OPENSSL_malloc(encoded_pt_len * 
        +					sizeof(unsigned char)); 
        +				bn_ctx = BN_CTX_new();
        +				if ((encodedPoint == NULL) || 
        +				    (bn_ctx == NULL)) 
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +
        +				/* Encode the public key */
        +				n = EC_POINT_point2oct(srvr_group, 
        +				    EC_KEY_get0_public_key(clnt_ecdh), 
        +				    POINT_CONVERSION_UNCOMPRESSED, 
        +				    encodedPoint, encoded_pt_len, bn_ctx);
        +
        +				*p = n; /* length of encoded point */
        +				/* Encoded point will be copied here */
        +				p += 1; 
        +				/* copy the point */
        +				memcpy((unsigned char *)p, encodedPoint, n);
        +				/* increment n to account for length field */
        +				n += 1; 
        +				}
        +
        +			/* Free allocated memory */
        +			BN_CTX_free(bn_ctx);
        +			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
        +			if (clnt_ecdh != NULL) 
        +				 EC_KEY_free(clnt_ecdh);
        +			EVP_PKEY_free(srvr_pub_pkey);
        +			}
        +#endif /* !OPENSSL_NO_ECDH */
        +
        +#ifndef OPENSSL_NO_PSK
        +		else if (alg_k & SSL_kPSK)
        +			{
        +			char identity[PSK_MAX_IDENTITY_LEN];
        +			unsigned char *t = NULL;
        +			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
        +			unsigned int pre_ms_len = 0, psk_len = 0;
        +			int psk_err = 1;
        +
        +			n = 0;
        +			if (s->psk_client_callback == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +					SSL_R_PSK_NO_CLIENT_CB);
        +				goto err;
        +				}
        +
        +			psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
        +				identity, PSK_MAX_IDENTITY_LEN,
        +				psk_or_pre_ms, sizeof(psk_or_pre_ms));
        +			if (psk_len > PSK_MAX_PSK_LEN)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_INTERNAL_ERROR);
        +				goto psk_err;
        +				}
        +			else if (psk_len == 0)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +					SSL_R_PSK_IDENTITY_NOT_FOUND);
        +				goto psk_err;
        +				}
        +
        +			/* create PSK pre_master_secret */
        +			pre_ms_len = 2+psk_len+2+psk_len;
        +			t = psk_or_pre_ms;
        +			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
        +			s2n(psk_len, t);
        +			memset(t, 0, psk_len);
        +			t+=psk_len;
        +			s2n(psk_len, t);
        +
        +			if (s->session->psk_identity_hint != NULL)
        +				OPENSSL_free(s->session->psk_identity_hint);
        +			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
        +			if (s->ctx->psk_identity_hint != NULL &&
        +				s->session->psk_identity_hint == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto psk_err;
        +				}
        +
        +			if (s->session->psk_identity != NULL)
        +				OPENSSL_free(s->session->psk_identity);
        +			s->session->psk_identity = BUF_strdup(identity);
        +			if (s->session->psk_identity == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto psk_err;
        +				}
        +
        +			s->session->master_key_length =
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,
        +					psk_or_pre_ms, pre_ms_len); 
        +			n = strlen(identity);
        +			s2n(n, p);
        +			memcpy(p, identity, n);
        +			n+=2;
        +			psk_err = 0;
        +		psk_err:
        +			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
        +			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
        +			if (psk_err != 0)
        +				{
        +				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
        +				goto err;
        +				}
        +			}
        +#endif
        +		else
        +			{
        +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
        +			SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		
        +		d = dtls1_set_message_header(s, d,
        +		SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n);
        +		/*
        +		 *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
        +		 l2n3(n,d);
        +		 l2n(s->d1->handshake_write_seq,d);
        +		 s->d1->handshake_write_seq++;
        +		*/
        +		
        +		s->state=SSL3_ST_CW_KEY_EXCH_B;
        +		/* number of bytes to write */
        +		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +	
        +	/* SSL3_ST_CW_KEY_EXCH_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +#ifndef OPENSSL_NO_ECDH
        +	BN_CTX_free(bn_ctx);
        +	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
        +	if (clnt_ecdh != NULL) 
        +		EC_KEY_free(clnt_ecdh);
        +	EVP_PKEY_free(srvr_pub_pkey);
        +#endif
        +	return(-1);
        +	}
        +
        +int dtls1_send_client_verify(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        +	EVP_PKEY *pkey;
        +#ifndef OPENSSL_NO_RSA
        +	unsigned u=0;
        +#endif
        +	unsigned long n;
        +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
        +	int j;
        +#endif
        +
        +	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
        +		{
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[DTLS1_HM_HEADER_LENGTH]);
        +		pkey=s->cert->key->privatekey;
        +
        +		s->method->ssl3_enc->cert_verify_mac(s,
        +		NID_sha1,
        +			&(data[MD5_DIGEST_LENGTH]));
        +
        +#ifndef OPENSSL_NO_RSA
        +		if (pkey->type == EVP_PKEY_RSA)
        +			{
        +			s->method->ssl3_enc->cert_verify_mac(s,
        +				NID_md5,
        +				&(data[0]));
        +			if (RSA_sign(NID_md5_sha1, data,
        +					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
        +					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
        +				goto err;
        +				}
        +			s2n(u,p);
        +			n=u+2;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			if (pkey->type == EVP_PKEY_DSA)
        +			{
        +			if (!DSA_sign(pkey->save_type,
        +				&(data[MD5_DIGEST_LENGTH]),
        +				SHA_DIGEST_LENGTH,&(p[2]),
        +				(unsigned int *)&j,pkey->pkey.dsa))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
        +				goto err;
        +				}
        +			s2n(j,p);
        +			n=j+2;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +			if (pkey->type == EVP_PKEY_EC)
        +			{
        +			if (!ECDSA_sign(pkey->save_type,
        +				&(data[MD5_DIGEST_LENGTH]),
        +				SHA_DIGEST_LENGTH,&(p[2]),
        +				(unsigned int *)&j,pkey->pkey.ec))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,
        +				    ERR_R_ECDSA_LIB);
        +				goto err;
        +				}
        +			s2n(j,p);
        +			n=j+2;
        +			}
        +		else
        +#endif
        +			{
        +			SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +
        +		d = dtls1_set_message_header(s, d,
        +			SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ;
        +
        +		s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +
        +		s->state = SSL3_ST_CW_CERT_VRFY_B;
        +		}
        +
        +	/* s->state = SSL3_ST_CW_CERT_VRFY_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +	return(-1);
        +	}
        +
        +int dtls1_send_client_certificate(SSL *s)
        +	{
        +	X509 *x509=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	int i;
        +	unsigned long l;
        +
        +	if (s->state ==	SSL3_ST_CW_CERT_A)
        +		{
        +		if ((s->cert == NULL) ||
        +			(s->cert->key->x509 == NULL) ||
        +			(s->cert->key->privatekey == NULL))
        +			s->state=SSL3_ST_CW_CERT_B;
        +		else
        +			s->state=SSL3_ST_CW_CERT_C;
        +		}
        +
        +	/* We need to get a client cert */
        +	if (s->state == SSL3_ST_CW_CERT_B)
        +		{
        +		/* If we get an error, we need to
        +		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
        +		 * We then get retied later */
        +		i=0;
        +		i = ssl_do_client_cert_cb(s, &x509, &pkey);
        +		if (i < 0)
        +			{
        +			s->rwstate=SSL_X509_LOOKUP;
        +			return(-1);
        +			}
        +		s->rwstate=SSL_NOTHING;
        +		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
        +			{
        +			s->state=SSL3_ST_CW_CERT_B;
        +			if (	!SSL_use_certificate(s,x509) ||
        +				!SSL_use_PrivateKey(s,pkey))
        +				i=0;
        +			}
        +		else if (i == 1)
        +			{
        +			i=0;
        +			SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
        +			}
        +
        +		if (x509 != NULL) X509_free(x509);
        +		if (pkey != NULL) EVP_PKEY_free(pkey);
        +		if (i == 0)
        +			{
        +			if (s->version == SSL3_VERSION)
        +				{
        +				s->s3->tmp.cert_req=0;
        +				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
        +				return(1);
        +				}
        +			else
        +				{
        +				s->s3->tmp.cert_req=2;
        +				}
        +			}
        +
        +		/* Ok, we have a cert */
        +		s->state=SSL3_ST_CW_CERT_C;
        +		}
        +
        +	if (s->state == SSL3_ST_CW_CERT_C)
        +		{
        +		s->state=SSL3_ST_CW_CERT_D;
        +		l=dtls1_output_cert_chain(s,
        +			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
        +		s->init_num=(int)l;
        +		s->init_off=0;
        +
        +		/* set header called by dtls1_output_cert_chain() */
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +	/* SSL3_ST_CW_CERT_D */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +
        diff --git a/vendor/openssl/openssl/ssl/d1_enc.c b/vendor/openssl/openssl/ssl/d1_enc.c
        new file mode 100644
        index 000000000..712c4647f
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_enc.c
        @@ -0,0 +1,260 @@
        +/* ssl/d1_enc.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/hmac.h>
        +#include <openssl/md5.h>
        +#include <openssl/rand.h>
        +#ifdef KSSL_DEBUG
        +#include <openssl/des.h>
        +#endif
        +
        +/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
        + *
        + * Returns:
        + *   0: (in non-constant time) if the record is publically invalid (i.e. too
        + *       short etc).
        + *   1: if the record's padding is valid / the encryption was successful.
        + *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
        + *       an internal error occured. */
        +int dtls1_enc(SSL *s, int send)
        +	{
        +	SSL3_RECORD *rec;
        +	EVP_CIPHER_CTX *ds;
        +	unsigned long l;
        +	int bs,i,j,k,mac_size=0;
        +	const EVP_CIPHER *enc;
        +
        +	if (send)
        +		{
        +		if (EVP_MD_CTX_md(s->write_hash))
        +			{
        +			mac_size=EVP_MD_CTX_size(s->write_hash);
        +			if (mac_size < 0)
        +				return -1;
        +			}
        +		ds=s->enc_write_ctx;
        +		rec= &(s->s3->wrec);
        +		if (s->enc_write_ctx == NULL)
        +			enc=NULL;
        +		else
        +			{
        +			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
        +			if ( rec->data != rec->input)
        +				/* we can't write into the input stream */
        +				fprintf(stderr, "%s:%d: rec->data != rec->input\n",
        +					__FILE__, __LINE__);
        +			else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
        +				{
        +				if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
        +					return -1;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		if (EVP_MD_CTX_md(s->read_hash))
        +			{
        +			mac_size=EVP_MD_CTX_size(s->read_hash);
        +			OPENSSL_assert(mac_size >= 0);
        +			}
        +		ds=s->enc_read_ctx;
        +		rec= &(s->s3->rrec);
        +		if (s->enc_read_ctx == NULL)
        +			enc=NULL;
        +		else
        +			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
        +		}
        +
        +#ifdef KSSL_DEBUG
        +	printf("dtls1_enc(%d)\n", send);
        +#endif    /* KSSL_DEBUG */
        +
        +	if ((s->session == NULL) || (ds == NULL) ||
        +		(enc == NULL))
        +		{
        +		memmove(rec->data,rec->input,rec->length);
        +		rec->input=rec->data;
        +		}
        +	else
        +		{
        +		l=rec->length;
        +		bs=EVP_CIPHER_block_size(ds->cipher);
        +
        +		if ((bs != 1) && send)
        +			{
        +			i=bs-((int)l%bs);
        +
        +			/* Add weird padding of upto 256 bytes */
        +
        +			/* we need to add 'i' padding bytes of value j */
        +			j=i-1;
        +			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
        +				{
        +				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
        +					j++;
        +				}
        +			for (k=(int)l; k<(int)(l+i); k++)
        +				rec->input[k]=j;
        +			l+=i;
        +			rec->length+=i;
        +			}
        +
        +#ifdef KSSL_DEBUG
        +		{
        +                unsigned long ui;
        +		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
        +                        ds,rec->data,rec->input,l);
        +		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
        +                        ds->buf_len, ds->cipher->key_len,
        +                        DES_KEY_SZ, DES_SCHEDULE_SZ,
        +                        ds->cipher->iv_len);
        +		printf("\t\tIV: ");
        +		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
        +		printf("\n");
        +		printf("\trec->input=");
        +		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
        +		printf("\n");
        +		}
        +#endif	/* KSSL_DEBUG */
        +
        +		if (!send)
        +			{
        +			if (l == 0 || l%bs != 0)
        +				return 0;
        +			}
        +		
        +		EVP_Cipher(ds,rec->data,rec->input,l);
        +
        +#ifdef KSSL_DEBUG
        +		{
        +                unsigned long i;
        +                printf("\trec->data=");
        +		for (i=0; i<l; i++)
        +                        printf(" %02x", rec->data[i]);  printf("\n");
        +                }
        +#endif	/* KSSL_DEBUG */
        +
        +		if ((bs != 1) && !send)
        +			return tls1_cbc_remove_padding(s, rec, bs, mac_size);
        +		}
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/d1_lib.c b/vendor/openssl/openssl/ssl/d1_lib.c
        new file mode 100644
        index 000000000..f61f71818
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_lib.c
        @@ -0,0 +1,482 @@
        +/* ssl/d1_lib.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#define USE_SOCKETS
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
        +#include <sys/timeb.h>
        +#endif
        +
        +static void get_current_time(struct timeval *t);
        +const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
        +int dtls1_listen(SSL *s, struct sockaddr *client);
        +
        +SSL3_ENC_METHOD DTLSv1_enc_data={
        +    dtls1_enc,
        +	tls1_mac,
        +	tls1_setup_key_block,
        +	tls1_generate_master_secret,
        +	tls1_change_cipher_state,
        +	tls1_final_finish_mac,
        +	TLS1_FINISH_MAC_LENGTH,
        +	tls1_cert_verify_mac,
        +	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
        +	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
        +	tls1_alert_code,
        +	tls1_export_keying_material,
        +	};
        +
        +long dtls1_default_timeout(void)
        +	{
        +	/* 2 hours, the 24 hours mentioned in the DTLSv1 spec
        +	 * is way too long for http, the cache would over fill */
        +	return(60*60*2);
        +	}
        +
        +int dtls1_new(SSL *s)
        +	{
        +	DTLS1_STATE *d1;
        +
        +	if (!ssl3_new(s)) return(0);
        +	if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0);
        +	memset(d1,0, sizeof *d1);
        +
        +	/* d1->handshake_epoch=0; */
        +
        +	d1->unprocessed_rcds.q=pqueue_new();
        +	d1->processed_rcds.q=pqueue_new();
        +	d1->buffered_messages = pqueue_new();
        +	d1->sent_messages=pqueue_new();
        +	d1->buffered_app_data.q=pqueue_new();
        +
        +	if ( s->server)
        +		{
        +		d1->cookie_len = sizeof(s->d1->cookie);
        +		}
        +
        +	if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 
        +        || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
        +		{
        +        if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
        +        if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
        +        if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
        +		if ( d1->sent_messages) pqueue_free(d1->sent_messages);
        +		if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
        +		OPENSSL_free(d1);
        +		return (0);
        +		}
        +
        +	s->d1=d1;
        +	s->method->ssl_clear(s);
        +	return(1);
        +	}
        +
        +static void dtls1_clear_queues(SSL *s)
        +	{
        +    pitem *item = NULL;
        +    hm_fragment *frag = NULL;
        +	DTLS1_RECORD_DATA *rdata;
        +
        +    while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
        +        {
        +		rdata = (DTLS1_RECORD_DATA *) item->data;
        +		if (rdata->rbuf.buf)
        +			{
        +			OPENSSL_free(rdata->rbuf.buf);
        +			}
        +        OPENSSL_free(item->data);
        +        pitem_free(item);
        +        }
        +
        +    while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL)
        +        {
        +		rdata = (DTLS1_RECORD_DATA *) item->data;
        +		if (rdata->rbuf.buf)
        +			{
        +			OPENSSL_free(rdata->rbuf.buf);
        +			}
        +        OPENSSL_free(item->data);
        +        pitem_free(item);
        +        }
        +
        +    while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
        +        {
        +        frag = (hm_fragment *)item->data;
        +        OPENSSL_free(frag->fragment);
        +        OPENSSL_free(frag);
        +        pitem_free(item);
        +        }
        +
        +    while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
        +        {
        +        frag = (hm_fragment *)item->data;
        +        OPENSSL_free(frag->fragment);
        +        OPENSSL_free(frag);
        +        pitem_free(item);
        +        }
        +
        +	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
        +		{
        +		frag = (hm_fragment *)item->data;
        +		OPENSSL_free(frag->fragment);
        +		OPENSSL_free(frag);
        +		pitem_free(item);
        +		}
        +	}
        +
        +void dtls1_free(SSL *s)
        +	{
        +	ssl3_free(s);
        +
        +	dtls1_clear_queues(s);
        +
        +    pqueue_free(s->d1->unprocessed_rcds.q);
        +    pqueue_free(s->d1->processed_rcds.q);
        +    pqueue_free(s->d1->buffered_messages);
        +	pqueue_free(s->d1->sent_messages);
        +	pqueue_free(s->d1->buffered_app_data.q);
        +
        +	OPENSSL_free(s->d1);
        +	}
        +
        +void dtls1_clear(SSL *s)
        +	{
        +    pqueue unprocessed_rcds;
        +    pqueue processed_rcds;
        +    pqueue buffered_messages;
        +	pqueue sent_messages;
        +	pqueue buffered_app_data;
        +	unsigned int mtu;
        +
        +	if (s->d1)
        +		{
        +		unprocessed_rcds = s->d1->unprocessed_rcds.q;
        +		processed_rcds = s->d1->processed_rcds.q;
        +		buffered_messages = s->d1->buffered_messages;
        +		sent_messages = s->d1->sent_messages;
        +		buffered_app_data = s->d1->buffered_app_data.q;
        +		mtu = s->d1->mtu;
        +
        +		dtls1_clear_queues(s);
        +
        +		memset(s->d1, 0, sizeof(*(s->d1)));
        +
        +		if (s->server)
        +			{
        +			s->d1->cookie_len = sizeof(s->d1->cookie);
        +			}
        +
        +		if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
        +			{
        +			s->d1->mtu = mtu;
        +			}
        +
        +		s->d1->unprocessed_rcds.q = unprocessed_rcds;
        +		s->d1->processed_rcds.q = processed_rcds;
        +		s->d1->buffered_messages = buffered_messages;
        +		s->d1->sent_messages = sent_messages;
        +		s->d1->buffered_app_data.q = buffered_app_data;
        +		}
        +
        +	ssl3_clear(s);
        +	if (s->options & SSL_OP_CISCO_ANYCONNECT)
        +		s->version=DTLS1_BAD_VER;
        +	else
        +		s->version=DTLS1_VERSION;
        +	}
        +
        +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
        +	{
        +	int ret=0;
        +
        +	switch (cmd)
        +		{
        +	case DTLS_CTRL_GET_TIMEOUT:
        +		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
        +			{
        +			ret = 1;
        +			}
        +		break;
        +	case DTLS_CTRL_HANDLE_TIMEOUT:
        +		ret = dtls1_handle_timeout(s);
        +		break;
        +	case DTLS_CTRL_LISTEN:
        +		ret = dtls1_listen(s, parg);
        +		break;
        +
        +	default:
        +		ret = ssl3_ctrl(s, cmd, larg, parg);
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +/*
        + * As it's impossible to use stream ciphers in "datagram" mode, this
        + * simple filter is designed to disengage them in DTLS. Unfortunately
        + * there is no universal way to identify stream SSL_CIPHER, so we have
        + * to explicitly list their SSL_* codes. Currently RC4 is the only one
        + * available, but if new ones emerge, they will have to be added...
        + */
        +const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
        +	{
        +	const SSL_CIPHER *ciph = ssl3_get_cipher(u);
        +
        +	if (ciph != NULL)
        +		{
        +		if (ciph->algorithm_enc == SSL_RC4)
        +			return NULL;
        +		}
        +
        +	return ciph;
        +	}
        +
        +void dtls1_start_timer(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_SCTP
        +	/* Disable timer for SCTP */
        +	if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +		{
        +		memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
        +		return;
        +		}
        +#endif
        +
        +	/* If timer is not set, initialize duration with 1 second */
        +	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
        +		{
        +		s->d1->timeout_duration = 1;
        +		}
        +	
        +	/* Set timeout to current time */
        +	get_current_time(&(s->d1->next_timeout));
        +
        +	/* Add duration to current time */
        +	s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
        +	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
        +	}
        +
        +struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
        +	{
        +	struct timeval timenow;
        +
        +	/* If no timeout is set, just return NULL */
        +	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
        +		{
        +		return NULL;
        +		}
        +
        +	/* Get current time */
        +	get_current_time(&timenow);
        +
        +	/* If timer already expired, set remaining time to 0 */
        +	if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
        +		(s->d1->next_timeout.tv_sec == timenow.tv_sec &&
        +		 s->d1->next_timeout.tv_usec <= timenow.tv_usec))
        +		{
        +		memset(timeleft, 0, sizeof(struct timeval));
        +		return timeleft;
        +		}
        +
        +	/* Calculate time left until timer expires */
        +	memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
        +	timeleft->tv_sec -= timenow.tv_sec;
        +	timeleft->tv_usec -= timenow.tv_usec;
        +	if (timeleft->tv_usec < 0)
        +		{
        +		timeleft->tv_sec--;
        +		timeleft->tv_usec += 1000000;
        +		}
        +
        +	/* If remaining time is less than 15 ms, set it to 0
        +	 * to prevent issues because of small devergences with
        +	 * socket timeouts.
        +	 */
        +	if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000)
        +		{
        +		memset(timeleft, 0, sizeof(struct timeval));
        +		}
        +	
        +
        +	return timeleft;
        +	}
        +
        +int dtls1_is_timer_expired(SSL *s)
        +	{
        +	struct timeval timeleft;
        +
        +	/* Get time left until timeout, return false if no timer running */
        +	if (dtls1_get_timeout(s, &timeleft) == NULL)
        +		{
        +		return 0;
        +		}
        +
        +	/* Return false if timer is not expired yet */
        +	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
        +		{
        +		return 0;
        +		}
        +
        +	/* Timer expired, so return true */	
        +	return 1;
        +	}
        +
        +void dtls1_double_timeout(SSL *s)
        +	{
        +	s->d1->timeout_duration *= 2;
        +	if (s->d1->timeout_duration > 60)
        +		s->d1->timeout_duration = 60;
        +	dtls1_start_timer(s);
        +	}
        +
        +void dtls1_stop_timer(SSL *s)
        +	{
        +	/* Reset everything */
        +	memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
        +	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
        +	s->d1->timeout_duration = 1;
        +	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
        +	/* Clear retransmission buffer */
        +	dtls1_clear_record_buffer(s);
        +	}
        +
        +int dtls1_check_timeout_num(SSL *s)
        +	{
        +	s->d1->timeout.num_alerts++;
        +
        +	/* Reduce MTU after 2 unsuccessful retransmissions */
        +	if (s->d1->timeout.num_alerts > 2)
        +		{
        +		s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);		
        +		}
        +
        +	if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
        +		{
        +		/* fail the connection, enough alerts have been sent */
        +		SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED);
        +		return -1;
        +		}
        +
        +	return 0;
        +	}
        +
        +int dtls1_handle_timeout(SSL *s)
        +	{
        +	/* if no timer is expired, don't do anything */
        +	if (!dtls1_is_timer_expired(s))
        +		{
        +		return 0;
        +		}
        +
        +	dtls1_double_timeout(s);
        +
        +	if (dtls1_check_timeout_num(s) < 0)
        +		return -1;
        +
        +	s->d1->timeout.read_timeouts++;
        +	if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
        +		{
        +		s->d1->timeout.read_timeouts = 1;
        +		}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	if (s->tlsext_hb_pending)
        +		{
        +		s->tlsext_hb_pending = 0;
        +		return dtls1_heartbeat(s);
        +		}
        +#endif
        +
        +	dtls1_start_timer(s);
        +	return dtls1_retransmit_buffered_messages(s);
        +	}
        +
        +static void get_current_time(struct timeval *t)
        +{
        +#ifdef OPENSSL_SYS_WIN32
        +	struct _timeb tb;
        +	_ftime(&tb);
        +	t->tv_sec = (long)tb.time;
        +	t->tv_usec = (long)tb.millitm * 1000;
        +#elif defined(OPENSSL_SYS_VMS)
        +	struct timeb tb;
        +	ftime(&tb);
        +	t->tv_sec = (long)tb.time;
        +	t->tv_usec = (long)tb.millitm * 1000;
        +#else
        +	gettimeofday(t, NULL);
        +#endif
        +}
        +
        +int dtls1_listen(SSL *s, struct sockaddr *client)
        +	{
        +	int ret;
        +
        +	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
        +	s->d1->listen = 1;
        +
        +	ret = SSL_accept(s);
        +	if (ret <= 0) return ret;
        +	
        +	(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/ssl/d1_meth.c b/vendor/openssl/openssl/ssl/d1_meth.c
        new file mode 100644
        index 000000000..5c4004bfe
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_meth.c
        @@ -0,0 +1,77 @@
        +/* ssl/d1_meth.h */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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 <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +static const SSL_METHOD *dtls1_get_method(int ver);
        +static const SSL_METHOD *dtls1_get_method(int ver)
        +	{
        +	if (ver == DTLS1_VERSION)
        +		return(DTLSv1_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_dtls1_meth_func(DTLSv1_method,
        +			dtls1_accept,
        +			dtls1_connect,
        +			dtls1_get_method)
        +
        diff --git a/vendor/openssl/openssl/ssl/d1_pkt.c b/vendor/openssl/openssl/ssl/d1_pkt.c
        new file mode 100644
        index 000000000..0bf87be6d
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_pkt.c
        @@ -0,0 +1,1893 @@
        +/* ssl/d1_pkt.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "ssl_locl.h"
        +#include <openssl/evp.h>
        +#include <openssl/buffer.h>
        +#include <openssl/pqueue.h>
        +#include <openssl/rand.h>
        +
        +/* mod 128 saturating subtract of two 64-bit values in big-endian order */
        +static int satsub64be(const unsigned char *v1,const unsigned char *v2)
        +{	int ret,sat,brw,i;
        +
        +	if (sizeof(long) == 8) do
        +	{	const union { long one; char little; } is_endian = {1};
        +		long l;
        +
        +		if (is_endian.little)			break;
        +		/* not reached on little-endians */
        +		/* following test is redundant, because input is
        +		 * always aligned, but I take no chances... */
        +		if (((size_t)v1|(size_t)v2)&0x7)	break;
        +
        +		l  = *((long *)v1);
        +		l -= *((long *)v2);
        +		if (l>128)		return 128;
        +		else if (l<-128)	return -128;
        +		else			return (int)l;
        +	} while (0);
        +
        +	ret = (int)v1[7]-(int)v2[7];
        +	sat = 0;
        +	brw = ret>>8;	/* brw is either 0 or -1 */
        +	if (ret & 0x80)
        +	{	for (i=6;i>=0;i--)
        +		{	brw += (int)v1[i]-(int)v2[i];
        +			sat |= ~brw;
        +			brw >>= 8;
        +		}
        +	}
        +	else
        +	{	for (i=6;i>=0;i--)
        +		{	brw += (int)v1[i]-(int)v2[i];
        +			sat |= brw;
        +			brw >>= 8;
        +		}
        +	}
        +	brw <<= 8;	/* brw is either 0 or -256 */
        +
        +	if (sat&0xff)	return brw | 0x80;
        +	else		return brw + (ret&0xFF);
        +}
        +
        +static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
        +	int len, int peek);
        +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
        +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
        +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 
        +    unsigned int *is_next_epoch);
        +#if 0
        +static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
        +	unsigned short *priority, unsigned long *offset);
        +#endif
        +static int dtls1_buffer_record(SSL *s, record_pqueue *q,
        +	unsigned char *priority);
        +static int dtls1_process_record(SSL *s);
        +
        +/* copy buffered record into SSL structure */
        +static int
        +dtls1_copy_record(SSL *s, pitem *item)
        +    {
        +    DTLS1_RECORD_DATA *rdata;
        +
        +    rdata = (DTLS1_RECORD_DATA *)item->data;
        +    
        +    if (s->s3->rbuf.buf != NULL)
        +        OPENSSL_free(s->s3->rbuf.buf);
        +    
        +    s->packet = rdata->packet;
        +    s->packet_length = rdata->packet_length;
        +    memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
        +    memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
        +	
        +	/* Set proper sequence number for mac calculation */
        +	memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
        +    
        +    return(1);
        +    }
        +
        +
        +static int
        +dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
        +	{
        +	DTLS1_RECORD_DATA *rdata;
        +	pitem *item;
        +
        +	/* Limit the size of the queue to prevent DOS attacks */
        +	if (pqueue_size(queue->q) >= 100)
        +		return 0;
        +		
        +	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
        +	item = pitem_new(priority, rdata);
        +	if (rdata == NULL || item == NULL)
        +		{
        +		if (rdata != NULL) OPENSSL_free(rdata);
        +		if (item != NULL) pitem_free(item);
        +		
        +		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
        +		return(0);
        +		}
        +	
        +	rdata->packet = s->packet;
        +	rdata->packet_length = s->packet_length;
        +	memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
        +	memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));
        +
        +	item->data = rdata;
        +
        +#ifndef OPENSSL_NO_SCTP
        +	/* Store bio_dgram_sctp_rcvinfo struct */
        +	if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
        +	    (s->state == SSL3_ST_SR_FINISHED_A || s->state == SSL3_ST_CR_FINISHED_A)) {
        +		BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo);
        +	}
        +#endif
        +
        +	/* insert should not fail, since duplicates are dropped */
        +	if (pqueue_insert(queue->q, item) == NULL)
        +		{
        +		OPENSSL_free(rdata);
        +		pitem_free(item);
        +		return(0);
        +		}
        +
        +	s->packet = NULL;
        +	s->packet_length = 0;
        +	memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
        +	memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
        +	
        +	if (!ssl3_setup_buffers(s))
        +		{
        +		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
        +		OPENSSL_free(rdata);
        +		pitem_free(item);
        +		return(0);
        +		}
        +	
        +	return(1);
        +	}
        +
        +
        +static int
        +dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
        +    {
        +    pitem *item;
        +
        +    item = pqueue_pop(queue->q);
        +    if (item)
        +        {
        +        dtls1_copy_record(s, item);
        +
        +        OPENSSL_free(item->data);
        +		pitem_free(item);
        +
        +        return(1);
        +        }
        +
        +    return(0);
        +    }
        +
        +
        +/* retrieve a buffered record that belongs to the new epoch, i.e., not processed 
        + * yet */
        +#define dtls1_get_unprocessed_record(s) \
        +                   dtls1_retrieve_buffered_record((s), \
        +                   &((s)->d1->unprocessed_rcds))
        +
        +/* retrieve a buffered record that belongs to the current epoch, ie, processed */
        +#define dtls1_get_processed_record(s) \
        +                   dtls1_retrieve_buffered_record((s), \
        +                   &((s)->d1->processed_rcds))
        +
        +static int
        +dtls1_process_buffered_records(SSL *s)
        +    {
        +    pitem *item;
        +    
        +    item = pqueue_peek(s->d1->unprocessed_rcds.q);
        +    if (item)
        +        {
        +        /* Check if epoch is current. */
        +        if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
        +            return(1);  /* Nothing to do. */
        +        
        +        /* Process all the records. */
        +        while (pqueue_peek(s->d1->unprocessed_rcds.q))
        +            {
        +            dtls1_get_unprocessed_record(s);
        +            if ( ! dtls1_process_record(s))
        +                return(0);
        +            dtls1_buffer_record(s, &(s->d1->processed_rcds), 
        +                s->s3->rrec.seq_num);
        +            }
        +        }
        +
        +    /* sync epoch numbers once all the unprocessed records 
        +     * have been processed */
        +    s->d1->processed_rcds.epoch = s->d1->r_epoch;
        +    s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
        +
        +    return(1);
        +    }
        +
        +
        +#if 0
        +
        +static int
        +dtls1_get_buffered_record(SSL *s)
        +	{
        +	pitem *item;
        +	PQ_64BIT priority = 
        +		(((PQ_64BIT)s->d1->handshake_read_seq) << 32) | 
        +		((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
        +	
        +	if ( ! SSL_in_init(s))  /* if we're not (re)negotiating, 
        +							   nothing buffered */
        +		return 0;
        +
        +
        +	item = pqueue_peek(s->d1->rcvd_records);
        +	if (item && item->priority == priority)
        +		{
        +		/* Check if we've received the record of interest.  It must be
        +		 * a handshake record, since data records as passed up without
        +		 * buffering */
        +		DTLS1_RECORD_DATA *rdata;
        +		item = pqueue_pop(s->d1->rcvd_records);
        +		rdata = (DTLS1_RECORD_DATA *)item->data;
        +		
        +		if (s->s3->rbuf.buf != NULL)
        +			OPENSSL_free(s->s3->rbuf.buf);
        +		
        +		s->packet = rdata->packet;
        +		s->packet_length = rdata->packet_length;
        +		memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
        +		memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
        +		
        +		OPENSSL_free(item->data);
        +		pitem_free(item);
        +		
        +		/* s->d1->next_expected_seq_num++; */
        +		return(1);
        +		}
        +	
        +	return 0;
        +	}
        +
        +#endif
        +
        +static int
        +dtls1_process_record(SSL *s)
        +{
        +	int i,al;
        +	int enc_err;
        +	SSL_SESSION *sess;
        +	SSL3_RECORD *rr;
        +	unsigned int mac_size, orig_len;
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +
        +	rr= &(s->s3->rrec);
        +	sess = s->session;
        +
        +	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
        +	 * and we have that many bytes in s->packet
        +	 */
        +	rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]);
        +
        +	/* ok, we can now read from 's->packet' data into 'rr'
        +	 * rr->input points at rr->length bytes, which
        +	 * need to be copied into rr->data by either
        +	 * the decryption or by the decompression
        +	 * When the data is 'copied' into the rr->data buffer,
        +	 * rr->input will be pointed at the new buffer */ 
        +
        +	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
        +	 * rr->length bytes of encrypted compressed stuff. */
        +
        +	/* check is not needed I believe */
        +	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
        +		{
        +		al=SSL_AD_RECORD_OVERFLOW;
        +		SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
        +		goto f_err;
        +		}
        +
        +	/* decrypt in place in 'rr->input' */
        +	rr->data=rr->input;
        +
        +	enc_err = s->method->ssl3_enc->enc(s,0);
        +	/* enc_err is:
        +	 *    0: (in non-constant time) if the record is publically invalid.
        +	 *    1: if the padding is valid
        +	 *    -1: if the padding is invalid */
        +	if (enc_err == 0)
        +		{
        +		/* For DTLS we simply ignore bad packets. */
        +		rr->length = 0;
        +		s->packet_length = 0;
        +		goto err;
        +		}
        +
        +#ifdef TLS_DEBUG
        +printf("dec %d\n",rr->length);
        +{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
        +printf("\n");
        +#endif
        +
        +	/* r->length is now the compressed data plus mac */
        +	if ((sess != NULL) &&
        +	    (s->enc_read_ctx != NULL) &&
        +	    (EVP_MD_CTX_md(s->read_hash) != NULL))
        +		{
        +		/* s->read_hash != NULL => mac_size != -1 */
        +		unsigned char *mac = NULL;
        +		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
        +		mac_size=EVP_MD_CTX_size(s->read_hash);
        +		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
        +
        +		/* kludge: *_cbc_remove_padding passes padding length in rr->type */
        +		orig_len = rr->length+((unsigned int)rr->type>>8);
        +
        +		/* orig_len is the length of the record before any padding was
        +		 * removed. This is public information, as is the MAC in use,
        +		 * therefore we can safely process the record in a different
        +		 * amount of time if it's too short to possibly contain a MAC.
        +		 */
        +		if (orig_len < mac_size ||
        +		    /* CBC records must have a padding length byte too. */
        +		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
        +		     orig_len < mac_size+1))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
        +			goto f_err;
        +			}
        +
        +		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
        +			{
        +			/* We update the length so that the TLS header bytes
        +			 * can be constructed correctly but we need to extract
        +			 * the MAC in constant time from within the record,
        +			 * without leaking the contents of the padding bytes.
        +			 * */
        +			mac = mac_tmp;
        +			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
        +			rr->length -= mac_size;
        +			}
        +		else
        +			{
        +			/* In this case there's no padding, so |orig_len|
        +			 * equals |rec->length| and we checked that there's
        +			 * enough bytes for |mac_size| above. */
        +			rr->length -= mac_size;
        +			mac = &rr->data[rr->length];
        +			}
        +
        +		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
        +		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
        +			enc_err = -1;
        +		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
        +			enc_err = -1;
        +		}
        +
        +	if (enc_err < 0)
        +		{
        +		/* decryption failed, silently discard message */
        +		rr->length = 0;
        +		s->packet_length = 0;
        +		goto err;
        +		}
        +
        +	/* r->length is now just compressed */
        +	if (s->expand != NULL)
        +		{
        +		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
        +			{
        +			al=SSL_AD_RECORD_OVERFLOW;
        +			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
        +			goto f_err;
        +			}
        +		if (!ssl3_do_uncompress(s))
        +			{
        +			al=SSL_AD_DECOMPRESSION_FAILURE;
        +			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
        +			goto f_err;
        +			}
        +		}
        +
        +	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
        +		{
        +		al=SSL_AD_RECORD_OVERFLOW;
        +		SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
        +		goto f_err;
        +		}
        +
        +	rr->off=0;
        +	/* So at this point the following is true
        +	 * ssl->s3->rrec.type 	is the type of record
        +	 * ssl->s3->rrec.length	== number of bytes in record
        +	 * ssl->s3->rrec.off	== offset to first valid byte
        +	 * ssl->s3->rrec.data	== where to take bytes from, increment
        +	 *			   after use :-).
        +	 */
        +
        +	/* we have pulled in a full packet so zero things */
        +	s->packet_length=0;
        +	dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
        +	return(1);
        +
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	return(0);
        +}
        +
        +
        +/* Call this to get a new input record.
        + * It will return <= 0 if more data is needed, normally due to an error
        + * or non-blocking IO.
        + * When it finishes, one packet has been decoded and can be found in
        + * ssl->s3->rrec.type    - is the type of record
        + * ssl->s3->rrec.data, 	 - data
        + * ssl->s3->rrec.length, - number of bytes
        + */
        +/* used only by dtls1_read_bytes */
        +int dtls1_get_record(SSL *s)
        +	{
        +	int ssl_major,ssl_minor;
        +	int i,n;
        +	SSL3_RECORD *rr;
        +	unsigned char *p = NULL;
        +	unsigned short version;
        +	DTLS1_BITMAP *bitmap;
        +	unsigned int is_next_epoch;
        +
        +	rr= &(s->s3->rrec);
        +
        +	/* The epoch may have changed.  If so, process all the
        +	 * pending records.  This is a non-blocking operation. */
        +	dtls1_process_buffered_records(s);
        +
        +	/* if we're renegotiating, then there may be buffered records */
        +	if (dtls1_get_processed_record(s))
        +		return 1;
        +
        +	/* get something from the wire */
        +again:
        +	/* check if we have the header */
        +	if (	(s->rstate != SSL_ST_READ_BODY) ||
        +		(s->packet_length < DTLS1_RT_HEADER_LENGTH)) 
        +		{
        +		n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
        +		/* read timeout is handled by dtls1_read_bytes */
        +		if (n <= 0) return(n); /* error or non-blocking */
        +
        +		/* this packet contained a partial record, dump it */
        +		if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
        +			{
        +			s->packet_length = 0;
        +			goto again;
        +			}
        +
        +		s->rstate=SSL_ST_READ_BODY;
        +
        +		p=s->packet;
        +
        +		/* Pull apart the header into the DTLS1_RECORD */
        +		rr->type= *(p++);
        +		ssl_major= *(p++);
        +		ssl_minor= *(p++);
        +		version=(ssl_major<<8)|ssl_minor;
        +
        +		/* sequence number is 64 bits, with top 2 bytes = epoch */ 
        +		n2s(p,rr->epoch);
        +
        +		memcpy(&(s->s3->read_sequence[2]), p, 6);
        +		p+=6;
        +
        +		n2s(p,rr->length);
        +
        +		/* Lets check version */
        +		if (!s->first_packet)
        +			{
        +			if (version != s->version)
        +				{
        +				/* unexpected version, silently discard */
        +				rr->length = 0;
        +				s->packet_length = 0;
        +				goto again;
        +				}
        +			}
        +
        +		if ((version & 0xff00) != (s->version & 0xff00))
        +			{
        +			/* wrong version, silently discard record */
        +			rr->length = 0;
        +			s->packet_length = 0;
        +			goto again;
        +			}
        +
        +		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
        +			{
        +			/* record too long, silently discard it */
        +			rr->length = 0;
        +			s->packet_length = 0;
        +			goto again;
        +			}
        +
        +		/* now s->rstate == SSL_ST_READ_BODY */
        +		}
        +
        +	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */
        +
        +	if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)
        +		{
        +		/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
        +		i=rr->length;
        +		n=ssl3_read_n(s,i,i,1);
        +		if (n <= 0) return(n); /* error or non-blocking io */
        +
        +		/* this packet contained a partial record, dump it */
        +		if ( n != i)
        +			{
        +			rr->length = 0;
        +			s->packet_length = 0;
        +			goto again;
        +			}
        +
        +		/* now n == rr->length,
        +		 * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
        +		}
        +	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
        +
        +	/* match epochs.  NULL means the packet is dropped on the floor */
        +	bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
        +	if ( bitmap == NULL)
        +		{
        +		rr->length = 0;
        +		s->packet_length = 0;  /* dump this record */
        +		goto again;   /* get another record */
        +		}
        +
        +#ifndef OPENSSL_NO_SCTP
        +	/* Only do replay check if no SCTP bio */
        +	if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
        +  		{
        +#endif
        +		/* Check whether this is a repeat, or aged record.
        +		 * Don't check if we're listening and this message is
        +		 * a ClientHello. They can look as if they're replayed,
        +		 * since they arrive from different connections and
        +		 * would be dropped unnecessarily.
        +		 */
        +		if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
        +		    *p == SSL3_MT_CLIENT_HELLO) &&
        +		    !dtls1_record_replay_check(s, bitmap))
        +			{
        +			rr->length = 0;
        +			s->packet_length=0; /* dump this record */
        +			goto again;     /* get another record */
        +			}
        +#ifndef OPENSSL_NO_SCTP
        +  		}
        +#endif
        +
        +	/* just read a 0 length packet */
        +	if (rr->length == 0) goto again;
        +
        +	/* If this record is from the next epoch (either HM or ALERT),
        +	 * and a handshake is currently in progress, buffer it since it
        +	 * cannot be processed at this time. However, do not buffer
        +	 * anything while listening.
        +	 */
        +	if (is_next_epoch)
        +		{
        +		if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
        +			{
        +			dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
        +			}
        +		rr->length = 0;
        +		s->packet_length = 0;
        +		goto again;
        +		}
        +
        +	if (!dtls1_process_record(s))
        +		{
        +		rr->length = 0;
        +		s->packet_length = 0;  /* dump this record */
        +		goto again;   /* get another record */
        +		}
        +
        +	return(1);
        +
        +	}
        +
        +/* Return up to 'len' payload bytes received in 'type' records.
        + * 'type' is one of the following:
        + *
        + *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
        + *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
        + *   -  0 (during a shutdown, no data has to be returned)
        + *
        + * If we don't have stored data to work from, read a SSL/TLS record first
        + * (possibly multiple records if we still don't have anything to return).
        + *
        + * This function must handle any surprises the peer may have for us, such as
        + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
        + * a surprise, but handled as if it were), or renegotiation requests.
        + * Also if record payloads contain fragments too small to process, we store
        + * them until there is enough for the respective protocol (the record protocol
        + * may use arbitrary fragmentation and even interleaving):
        + *     Change cipher spec protocol
        + *             just 1 byte needed, no need for keeping anything stored
        + *     Alert protocol
        + *             2 bytes needed (AlertLevel, AlertDescription)
        + *     Handshake protocol
        + *             4 bytes needed (HandshakeType, uint24 length) -- we just have
        + *             to detect unexpected Client Hello and Hello Request messages
        + *             here, anything else is handled by higher layers
        + *     Application data protocol
        + *             none of our business
        + */
        +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        +	{
        +	int al,i,j,ret;
        +	unsigned int n;
        +	SSL3_RECORD *rr;
        +	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
        +
        +	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
        +		if (!ssl3_setup_buffers(s))
        +			return(-1);
        +
        +    /* XXX: check what the second '&& type' is about */
        +	if ((type && (type != SSL3_RT_APPLICATION_DATA) && 
        +		(type != SSL3_RT_HANDSHAKE) && type) ||
        +	    (peek && (type != SSL3_RT_APPLICATION_DATA)))
        +		{
        +		SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +
        +	/* check whether there's a handshake message (client hello?) waiting */
        +	if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))
        +		return ret;
        +
        +	/* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
        +
        +#ifndef OPENSSL_NO_SCTP
        +	/* Continue handshake if it had to be interrupted to read
        +	 * app data with SCTP.
        +	 */
        +	if ((!s->in_handshake && SSL_in_init(s)) ||
        +	    (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
        +	     (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) &&
        +	     s->s3->in_read_app_data != 2))
        +#else
        +	if (!s->in_handshake && SSL_in_init(s))
        +#endif
        +		{
        +		/* type == SSL3_RT_APPLICATION_DATA */
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		}
        +
        +start:
        +	s->rwstate=SSL_NOTHING;
        +
        +	/* s->s3->rrec.type	    - is the type of record
        +	 * s->s3->rrec.data,    - data
        +	 * s->s3->rrec.off,     - offset into 'data' for next read
        +	 * s->s3->rrec.length,  - number of bytes. */
        +	rr = &(s->s3->rrec);
        +
        +	/* We are not handshaking and have no data yet,
        +	 * so process data buffered during the last handshake
        +	 * in advance, if any.
        +	 */
        +	if (s->state == SSL_ST_OK && rr->length == 0)
        +		{
        +		pitem *item;
        +		item = pqueue_pop(s->d1->buffered_app_data.q);
        +		if (item)
        +			{
        +#ifndef OPENSSL_NO_SCTP
        +			/* Restore bio_dgram_sctp_rcvinfo struct */
        +			if (BIO_dgram_is_sctp(SSL_get_rbio(s)))
        +				{
        +				DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *) item->data;
        +				BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo);
        +				}
        +#endif
        +
        +			dtls1_copy_record(s, item);
        +
        +			OPENSSL_free(item->data);
        +			pitem_free(item);
        +			}
        +		}
        +
        +	/* Check for timeout */
        +	if (dtls1_handle_timeout(s) > 0)
        +		goto start;
        +
        +	/* get new packet if necessary */
        +	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
        +		{
        +		ret=dtls1_get_record(s);
        +		if (ret <= 0) 
        +			{
        +			ret = dtls1_read_failed(s, ret);
        +			/* anything other than a timeout is an error */
        +			if (ret <= 0)  
        +				return(ret);
        +			else
        +				goto start;
        +			}
        +		}
        +
        +	/* we now have a packet which can be read and processed */
        +
        +	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
        +	                               * reset by ssl3_get_finished */
        +		&& (rr->type != SSL3_RT_HANDSHAKE))
        +		{
        +		/* We now have application data between CCS and Finished.
        +		 * Most likely the packets were reordered on their way, so
        +		 * buffer the application data for later processing rather
        +		 * than dropping the connection.
        +		 */
        +		dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
        +		rr->length = 0;
        +		goto start;
        +		}
        +
        +	/* If the other end has shut down, throw anything we read away
        +	 * (even in 'peek' mode) */
        +	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
        +		{
        +		rr->length=0;
        +		s->rwstate=SSL_NOTHING;
        +		return(0);
        +		}
        +
        +
        +	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
        +		{
        +		/* make sure that we are not getting application data when we
        +		 * are doing a handshake for the first time */
        +		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
        +			(s->enc_read_ctx == NULL))
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
        +			goto f_err;
        +			}
        +
        +		if (len <= 0) return(len);
        +
        +		if ((unsigned int)len > rr->length)
        +			n = rr->length;
        +		else
        +			n = (unsigned int)len;
        +
        +		memcpy(buf,&(rr->data[rr->off]),n);
        +		if (!peek)
        +			{
        +			rr->length-=n;
        +			rr->off+=n;
        +			if (rr->length == 0)
        +				{
        +				s->rstate=SSL_ST_READ_HEADER;
        +				rr->off=0;
        +				}
        +			}
        +
        +#ifndef OPENSSL_NO_SCTP
        +			/* We were about to renegotiate but had to read
        +			 * belated application data first, so retry.
        +			 */
        +			if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
        +			    rr->type == SSL3_RT_APPLICATION_DATA &&
        +			    (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))
        +				{
        +				s->rwstate=SSL_READING;
        +				BIO_clear_retry_flags(SSL_get_rbio(s));
        +				BIO_set_retry_read(SSL_get_rbio(s));
        +				}
        +
        +			/* We might had to delay a close_notify alert because
        +			 * of reordered app data. If there was an alert and there
        +			 * is no message to read anymore, finally set shutdown.
        +			 */
        +			if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
        +			    s->d1->shutdown_received && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
        +				{
        +				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
        +				return(0);
        +				}
        +#endif			
        +		return(n);
        +		}
        +
        +
        +	/* If we get here, then type != rr->type; if we have a handshake
        +	 * message, then it was unexpected (Hello Request or Client Hello). */
        +
        +	/* In case of record types for which we have 'fragment' storage,
        +	 * fill that so that we can process the data at a fixed place.
        +	 */
        +		{
        +		unsigned int k, dest_maxlen = 0;
        +		unsigned char *dest = NULL;
        +		unsigned int *dest_len = NULL;
        +
        +		if (rr->type == SSL3_RT_HANDSHAKE)
        +			{
        +			dest_maxlen = sizeof s->d1->handshake_fragment;
        +			dest = s->d1->handshake_fragment;
        +			dest_len = &s->d1->handshake_fragment_len;
        +			}
        +		else if (rr->type == SSL3_RT_ALERT)
        +			{
        +			dest_maxlen = sizeof(s->d1->alert_fragment);
        +			dest = s->d1->alert_fragment;
        +			dest_len = &s->d1->alert_fragment_len;
        +			}
        +#ifndef OPENSSL_NO_HEARTBEATS
        +		else if (rr->type == TLS1_RT_HEARTBEAT)
        +			{
        +			dtls1_process_heartbeat(s);
        +
        +			/* Exit and notify application to read again */
        +			rr->length = 0;
        +			s->rwstate=SSL_READING;
        +			BIO_clear_retry_flags(SSL_get_rbio(s));
        +			BIO_set_retry_read(SSL_get_rbio(s));
        +			return(-1);
        +			}
        +#endif
        +		/* else it's a CCS message, or application data or wrong */
        +		else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
        +			{
        +			/* Application data while renegotiating
        +			 * is allowed. Try again reading.
        +			 */
        +			if (rr->type == SSL3_RT_APPLICATION_DATA)
        +				{
        +				BIO *bio;
        +				s->s3->in_read_app_data=2;
        +				bio=SSL_get_rbio(s);
        +				s->rwstate=SSL_READING;
        +				BIO_clear_retry_flags(bio);
        +				BIO_set_retry_read(bio);
        +				return(-1);
        +				}
        +
        +			/* Not certain if this is the right error handling */
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
        +			goto f_err;
        +			}
        +
        +		if (dest_maxlen > 0)
        +			{
        +            /* XDTLS:  In a pathalogical case, the Client Hello
        +             *  may be fragmented--don't always expect dest_maxlen bytes */
        +			if ( rr->length < dest_maxlen)
        +				{
        +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
        +				/*
        +				 * for normal alerts rr->length is 2, while
        +				 * dest_maxlen is 7 if we were to handle this
        +				 * non-existing alert...
        +				 */
        +				FIX ME
        +#endif
        +				s->rstate=SSL_ST_READ_HEADER;
        +				rr->length = 0;
        +				goto start;
        +				}
        +
        +			/* now move 'n' bytes: */
        +			for ( k = 0; k < dest_maxlen; k++)
        +				{
        +				dest[k] = rr->data[rr->off++];
        +				rr->length--;
        +				}
        +			*dest_len = dest_maxlen;
        +			}
        +		}
        +
        +	/* s->d1->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;
        +	 * s->d1->alert_fragment_len == 7      iff  rr->type == SSL3_RT_ALERT.
        +	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
        +
        +	/* If we are a client, check for an incoming 'Hello Request': */
        +	if ((!s->server) &&
        +		(s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
        +		(s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
        +		(s->session != NULL) && (s->session->cipher != NULL))
        +		{
        +		s->d1->handshake_fragment_len = 0;
        +
        +		if ((s->d1->handshake_fragment[1] != 0) ||
        +			(s->d1->handshake_fragment[2] != 0) ||
        +			(s->d1->handshake_fragment[3] != 0))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
        +			goto err;
        +			}
        +
        +		/* no need to check sequence number on HELLO REQUEST messages */
        +
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
        +				s->d1->handshake_fragment, 4, s, s->msg_callback_arg);
        +
        +		if (SSL_is_init_finished(s) &&
        +			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
        +			!s->s3->renegotiate)
        +			{
        +			s->new_session = 1;
        +			ssl3_renegotiate(s);
        +			if (ssl3_renegotiate_check(s))
        +				{
        +				i=s->handshake_func(s);
        +				if (i < 0) return(i);
        +				if (i == 0)
        +					{
        +					SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +					return(-1);
        +					}
        +
        +				if (!(s->mode & SSL_MODE_AUTO_RETRY))
        +					{
        +					if (s->s3->rbuf.left == 0) /* no read-ahead left? */
        +						{
        +						BIO *bio;
        +						/* In the case where we try to read application data,
        +						 * but we trigger an SSL handshake, we return -1 with
        +						 * the retry option set.  Otherwise renegotiation may
        +						 * cause nasty problems in the blocking world */
        +						s->rwstate=SSL_READING;
        +						bio=SSL_get_rbio(s);
        +						BIO_clear_retry_flags(bio);
        +						BIO_set_retry_read(bio);
        +						return(-1);
        +						}
        +					}
        +				}
        +			}
        +		/* we either finished a handshake or ignored the request,
        +		 * now try again to obtain the (application) data we were asked for */
        +		goto start;
        +		}
        +
        +	if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)
        +		{
        +		int alert_level = s->d1->alert_fragment[0];
        +		int alert_descr = s->d1->alert_fragment[1];
        +
        +		s->d1->alert_fragment_len = 0;
        +
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, SSL3_RT_ALERT, 
        +				s->d1->alert_fragment, 2, s, s->msg_callback_arg);
        +
        +		if (s->info_callback != NULL)
        +			cb=s->info_callback;
        +		else if (s->ctx->info_callback != NULL)
        +			cb=s->ctx->info_callback;
        +
        +		if (cb != NULL)
        +			{
        +			j = (alert_level << 8) | alert_descr;
        +			cb(s, SSL_CB_READ_ALERT, j);
        +			}
        +
        +		if (alert_level == 1) /* warning */
        +			{
        +			s->s3->warn_alert = alert_descr;
        +			if (alert_descr == SSL_AD_CLOSE_NOTIFY)
        +				{
        +#ifndef OPENSSL_NO_SCTP
        +				/* With SCTP and streams the socket may deliver app data
        +				 * after a close_notify alert. We have to check this
        +				 * first so that nothing gets discarded.
        +				 */
        +				if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
        +					BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
        +					{
        +					s->d1->shutdown_received = 1;
        +					s->rwstate=SSL_READING;
        +					BIO_clear_retry_flags(SSL_get_rbio(s));
        +					BIO_set_retry_read(SSL_get_rbio(s));
        +					return -1;
        +					}
        +#endif
        +				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
        +				return(0);
        +				}
        +#if 0
        +            /* XXX: this is a possible improvement in the future */
        +			/* now check if it's a missing record */
        +			if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
        +				{
        +				unsigned short seq;
        +				unsigned int frag_off;
        +				unsigned char *p = &(s->d1->alert_fragment[2]);
        +
        +				n2s(p, seq);
        +				n2l3(p, frag_off);
        +
        +				dtls1_retransmit_message(s,
        +										 dtls1_get_queue_priority(frag->msg_header.seq, 0),
        +										 frag_off, &found);
        +				if ( ! found  && SSL_in_init(s))
        +					{
        +					/* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
        +					/* requested a message not yet sent, 
        +					   send an alert ourselves */
        +					ssl3_send_alert(s,SSL3_AL_WARNING,
        +						DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
        +					}
        +				}
        +#endif
        +			}
        +		else if (alert_level == 2) /* fatal */
        +			{
        +			char tmp[16];
        +
        +			s->rwstate=SSL_NOTHING;
        +			s->s3->fatal_alert = alert_descr;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
        +			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
        +			ERR_add_error_data(2,"SSL alert number ",tmp);
        +			s->shutdown|=SSL_RECEIVED_SHUTDOWN;
        +			SSL_CTX_remove_session(s->ctx,s->session);
        +			return(0);
        +			}
        +		else
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
        +			goto f_err;
        +			}
        +
        +		goto start;
        +		}
        +
        +	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
        +		{
        +		s->rwstate=SSL_NOTHING;
        +		rr->length=0;
        +		return(0);
        +		}
        +
        +	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
        +		{
        +		struct ccs_header_st ccs_hdr;
        +		unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
        +
        +		dtls1_get_ccs_header(rr->data, &ccs_hdr);
        +
        +		if (s->version == DTLS1_BAD_VER)
        +			ccs_hdr_len = 3;
        +
        +		/* 'Change Cipher Spec' is just a single byte, so we know
        +		 * exactly what the record payload has to look like */
        +		/* XDTLS: check that epoch is consistent */
        +		if (	(rr->length != ccs_hdr_len) || 
        +			(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
        +			{
        +			i=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
        +			goto err;
        +			}
        +
        +		rr->length=0;
        +
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, 
        +				rr->data, 1, s, s->msg_callback_arg);
        +
        +		/* We can't process a CCS now, because previous handshake
        +		 * messages are still missing, so just drop it.
        +		 */
        +		if (!s->d1->change_cipher_spec_ok)
        +			{
        +			goto start;
        +			}
        +
        +		s->d1->change_cipher_spec_ok = 0;
        +
        +		s->s3->change_cipher_spec=1;
        +		if (!ssl3_do_change_cipher_spec(s))
        +			goto err;
        +
        +		/* do this whenever CCS is processed */
        +		dtls1_reset_seq_numbers(s, SSL3_CC_READ);
        +
        +		if (s->version == DTLS1_BAD_VER)
        +			s->d1->handshake_read_seq++;
        +
        +#ifndef OPENSSL_NO_SCTP
        +		/* Remember that a CCS has been received,
        +		 * so that an old key of SCTP-Auth can be
        +		 * deleted when a CCS is sent. Will be ignored
        +		 * if no SCTP is used
        +		 */
        +		BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL);
        +#endif
        +
        +		goto start;
        +		}
        +
        +	/* Unexpected handshake message (Client Hello, or protocol violation) */
        +	if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && 
        +		!s->in_handshake)
        +		{
        +		struct hm_header_st msg_hdr;
        +		
        +		/* this may just be a stale retransmit */
        +		dtls1_get_message_header(rr->data, &msg_hdr);
        +		if( rr->epoch != s->d1->r_epoch)
        +			{
        +			rr->length = 0;
        +			goto start;
        +			}
        +
        +		/* If we are server, we may have a repeated FINISHED of the
        +		 * client here, then retransmit our CCS and FINISHED.
        +		 */
        +		if (msg_hdr.type == SSL3_MT_FINISHED)
        +			{
        +			if (dtls1_check_timeout_num(s) < 0)
        +				return -1;
        +
        +			dtls1_retransmit_buffered_messages(s);
        +			rr->length = 0;
        +			goto start;
        +			}
        +
        +		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
        +			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
        +			{
        +#if 0 /* worked only because C operator preferences are not as expected (and
        +       * because this is not really needed for clients except for detecting
        +       * protocol violations): */
        +			s->state=SSL_ST_BEFORE|(s->server)
        +				?SSL_ST_ACCEPT
        +				:SSL_ST_CONNECT;
        +#else
        +			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
        +#endif
        +			s->renegotiate=1;
        +			s->new_session=1;
        +			}
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +
        +		if (!(s->mode & SSL_MODE_AUTO_RETRY))
        +			{
        +			if (s->s3->rbuf.left == 0) /* no read-ahead left? */
        +				{
        +				BIO *bio;
        +				/* In the case where we try to read application data,
        +				 * but we trigger an SSL handshake, we return -1 with
        +				 * the retry option set.  Otherwise renegotiation may
        +				 * cause nasty problems in the blocking world */
        +				s->rwstate=SSL_READING;
        +				bio=SSL_get_rbio(s);
        +				BIO_clear_retry_flags(bio);
        +				BIO_set_retry_read(bio);
        +				return(-1);
        +				}
        +			}
        +		goto start;
        +		}
        +
        +	switch (rr->type)
        +		{
        +	default:
        +#ifndef OPENSSL_NO_TLS
        +		/* TLS just ignores unknown message types */
        +		if (s->version == TLS1_VERSION)
        +			{
        +			rr->length = 0;
        +			goto start;
        +			}
        +#endif
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
        +		goto f_err;
        +	case SSL3_RT_CHANGE_CIPHER_SPEC:
        +	case SSL3_RT_ALERT:
        +	case SSL3_RT_HANDSHAKE:
        +		/* we already handled all of these, with the possible exception
        +		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
        +		 * should not happen when type != rr->type */
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
        +		goto f_err;
        +	case SSL3_RT_APPLICATION_DATA:
        +		/* At this point, we were expecting handshake data,
        +		 * but have application data.  If the library was
        +		 * running inside ssl3_read() (i.e. in_read_app_data
        +		 * is set) and it makes sense to read application data
        +		 * at this point (session renegotiation not yet started),
        +		 * we will indulge it.
        +		 */
        +		if (s->s3->in_read_app_data &&
        +			(s->s3->total_renegotiations != 0) &&
        +			((
        +				(s->state & SSL_ST_CONNECT) &&
        +				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
        +				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)
        +				) || (
        +					(s->state & SSL_ST_ACCEPT) &&
        +					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
        +					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)
        +					)
        +				))
        +			{
        +			s->s3->in_read_app_data=2;
        +			return(-1);
        +			}
        +		else
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
        +			goto f_err;
        +			}
        +		}
        +	/* not reached */
        +
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	return(-1);
        +	}
        +
        +int
        +dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
        +	{
        +	int i;
        +
        +#ifndef OPENSSL_NO_SCTP
        +		/* Check if we have to continue an interrupted handshake
        +		 * for reading belated app data with SCTP.
        +		 */
        +		if ((SSL_in_init(s) && !s->in_handshake) ||
        +		    (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
        +		     (s->state == DTLS1_SCTP_ST_SR_READ_SOCK || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)))
        +#else
        +		if (SSL_in_init(s) && !s->in_handshake)
        +#endif
        +		{
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return -1;
        +			}
        +		}
        +
        +	if (len > SSL3_RT_MAX_PLAIN_LENGTH)
        +		{
        +			SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG);
        +			return -1;
        +		}
        +
        +	i = dtls1_write_bytes(s, type, buf_, len);
        +	return i;
        +	}
        +
        +
        +	/* this only happens when a client hello is received and a handshake 
        +	 * is started. */
        +static int
        +have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
        +	int len, int peek)
        +	{
        +	
        +	if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))
        +		/* (partially) satisfy request from storage */
        +		{
        +		unsigned char *src = s->d1->handshake_fragment;
        +		unsigned char *dst = buf;
        +		unsigned int k,n;
        +		
        +		/* peek == 0 */
        +		n = 0;
        +		while ((len > 0) && (s->d1->handshake_fragment_len > 0))
        +			{
        +			*dst++ = *src++;
        +			len--; s->d1->handshake_fragment_len--;
        +			n++;
        +			}
        +		/* move any remaining fragment bytes: */
        +		for (k = 0; k < s->d1->handshake_fragment_len; k++)
        +			s->d1->handshake_fragment[k] = *src++;
        +		return n;
        +		}
        +	
        +	return 0;
        +	}
        +
        +
        +
        +
        +/* Call this to write data in records of type 'type'
        + * It will return <= 0 if not all data has been sent or non-blocking IO.
        + */
        +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
        +	{
        +	int i;
        +
        +	OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
        +	s->rwstate=SSL_NOTHING;
        +	i=do_dtls1_write(s, type, buf, len, 0);
        +	return i;
        +	}
        +
        +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
        +	{
        +	unsigned char *p,*pseq;
        +	int i,mac_size,clear=0;
        +	int prefix_len = 0;
        +	SSL3_RECORD *wr;
        +	SSL3_BUFFER *wb;
        +	SSL_SESSION *sess;
        +	int bs;
        +
        +	/* first check if there is a SSL3_BUFFER still being written
        +	 * out.  This will happen with non blocking IO */
        +	if (s->s3->wbuf.left != 0)
        +		{
        +		OPENSSL_assert(0); /* XDTLS:  want to see if we ever get here */
        +		return(ssl3_write_pending(s,type,buf,len));
        +		}
        +
        +	/* If we have an alert to send, lets send it */
        +	if (s->s3->alert_dispatch)
        +		{
        +		i=s->method->ssl_dispatch_alert(s);
        +		if (i <= 0)
        +			return(i);
        +		/* if it went, fall through and send more stuff */
        +		}
        +
        +	if (len == 0 && !create_empty_fragment)
        +		return 0;
        +
        +	wr= &(s->s3->wrec);
        +	wb= &(s->s3->wbuf);
        +	sess=s->session;
        +
        +	if (	(sess == NULL) ||
        +		(s->enc_write_ctx == NULL) ||
        +		(EVP_MD_CTX_md(s->write_hash) == NULL))
        +		clear=1;
        +
        +	if (clear)
        +		mac_size=0;
        +	else
        +		{
        +		mac_size=EVP_MD_CTX_size(s->write_hash);
        +		if (mac_size < 0)
        +			goto err;
        +		}
        +
        +	/* DTLS implements explicit IV, so no need for empty fragments */
        +#if 0
        +	/* 'create_empty_fragment' is true only when this function calls itself */
        +	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
        +	    && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
        +		{
        +		/* countermeasure against known-IV weakness in CBC ciphersuites
        +		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
        +		 */
        +
        +		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
        +			{
        +			/* recursive function call with 'create_empty_fragment' set;
        +			 * this prepares and buffers the data for an empty fragment
        +			 * (these 'prefix_len' bytes are sent out later
        +			 * together with the actual payload) */
        +			prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
        +			if (prefix_len <= 0)
        +				goto err;
        +
        +			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
        +				{
        +				/* insufficient space */
        +				SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			}
        +		
        +		s->s3->empty_fragment_done = 1;
        +		}
        +#endif
        +	p = wb->buf + prefix_len;
        +
        +	/* write the header */
        +
        +	*(p++)=type&0xff;
        +	wr->type=type;
        +
        +	*(p++)=(s->version>>8);
        +	*(p++)=s->version&0xff;
        +
        +	/* field where we are to write out packet epoch, seq num and len */
        +	pseq=p; 
        +	p+=10;
        +
        +	/* lets setup the record stuff. */
        +
        +	/* Make space for the explicit IV in case of CBC.
        +	 * (this is a bit of a boundary violation, but what the heck).
        +	 */
        +	if ( s->enc_write_ctx && 
        +		(EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE))
        +		bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
        +	else
        +		bs = 0;
        +
        +	wr->data=p + bs;  /* make room for IV in case of CBC */
        +	wr->length=(int)len;
        +	wr->input=(unsigned char *)buf;
        +
        +	/* we now 'read' from wr->input, wr->length bytes into
        +	 * wr->data */
        +
        +	/* first we compress */
        +	if (s->compress != NULL)
        +		{
        +		if (!ssl3_do_compress(s))
        +			{
        +			SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		memcpy(wr->data,wr->input,wr->length);
        +		wr->input=wr->data;
        +		}
        +
        +	/* we should still have the output to wr->data and the input
        +	 * from wr->input.  Length should be wr->length.
        +	 * wr->data still points in the wb->buf */
        +
        +	if (mac_size != 0)
        +		{
        +		if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
        +			goto err;
        +		wr->length+=mac_size;
        +		}
        +
        +	/* this is true regardless of mac size */
        +	wr->input=p;
        +	wr->data=p;
        +
        +
        +	/* ssl3_enc can only have an error on read */
        +	if (bs)	/* bs != 0 in case of CBC */
        +		{
        +		RAND_pseudo_bytes(p,bs);
        +		/* master IV and last CBC residue stand for
        +		 * the rest of randomness */
        +		wr->length += bs;
        +		}
        +
        +	s->method->ssl3_enc->enc(s,1);
        +
        +	/* record length after mac and block padding */
        +/*	if (type == SSL3_RT_APPLICATION_DATA ||
        +	(type == SSL3_RT_ALERT && ! SSL_in_init(s))) */
        +	
        +	/* there's only one epoch between handshake and app data */
        +	
        +	s2n(s->d1->w_epoch, pseq);
        +
        +	/* XDTLS: ?? */
        +/*	else
        +	s2n(s->d1->handshake_epoch, pseq); */
        +
        +	memcpy(pseq, &(s->s3->write_sequence[2]), 6);
        +	pseq+=6;
        +	s2n(wr->length,pseq);
        +
        +	/* we should now have
        +	 * wr->data pointing to the encrypted data, which is
        +	 * wr->length long */
        +	wr->type=type; /* not needed but helps for debugging */
        +	wr->length+=DTLS1_RT_HEADER_LENGTH;
        +
        +#if 0  /* this is now done at the message layer */
        +	/* buffer the record, making it easy to handle retransmits */
        +	if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
        +		dtls1_buffer_record(s, wr->data, wr->length, 
        +			*((PQ_64BIT *)&(s->s3->write_sequence[0])));
        +#endif
        +
        +	ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
        +
        +	if (create_empty_fragment)
        +		{
        +		/* we are in a recursive call;
        +		 * just return the length, don't write out anything here
        +		 */
        +		return wr->length;
        +		}
        +
        +	/* now let's set up wb */
        +	wb->left = prefix_len + wr->length;
        +	wb->offset = 0;
        +
        +	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
        +	s->s3->wpend_tot=len;
        +	s->s3->wpend_buf=buf;
        +	s->s3->wpend_type=type;
        +	s->s3->wpend_ret=len;
        +
        +	/* we now just need to write the buffer */
        +	return ssl3_write_pending(s,type,buf,len);
        +err:
        +	return -1;
        +	}
        +
        +
        +
        +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
        +	{
        +	int cmp;
        +	unsigned int shift;
        +	const unsigned char *seq = s->s3->read_sequence;
        +
        +	cmp = satsub64be(seq,bitmap->max_seq_num);
        +	if (cmp > 0)
        +		{
        +		memcpy (s->s3->rrec.seq_num,seq,8);
        +		return 1; /* this record in new */
        +		}
        +	shift = -cmp;
        +	if (shift >= sizeof(bitmap->map)*8)
        +		return 0; /* stale, outside the window */
        +	else if (bitmap->map & (1UL<<shift))
        +		return 0; /* record previously received */
        +
        +	memcpy (s->s3->rrec.seq_num,seq,8);
        +	return 1;
        +	}
        +
        +
        +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
        +	{
        +	int cmp;
        +	unsigned int shift;
        +	const unsigned char *seq = s->s3->read_sequence;
        +
        +	cmp = satsub64be(seq,bitmap->max_seq_num);
        +	if (cmp > 0)
        +		{
        +		shift = cmp;
        +		if (shift < sizeof(bitmap->map)*8)
        +			bitmap->map <<= shift, bitmap->map |= 1UL;
        +		else
        +			bitmap->map = 1UL;
        +		memcpy(bitmap->max_seq_num,seq,8);
        +		}
        +	else	{
        +		shift = -cmp;
        +		if (shift < sizeof(bitmap->map)*8)
        +			bitmap->map |= 1UL<<shift;
        +		}
        +	}
        +
        +
        +int dtls1_dispatch_alert(SSL *s)
        +	{
        +	int i,j;
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	unsigned char buf[DTLS1_AL_HEADER_LENGTH];
        +	unsigned char *ptr = &buf[0];
        +
        +	s->s3->alert_dispatch=0;
        +
        +	memset(buf, 0x00, sizeof(buf));
        +	*ptr++ = s->s3->send_alert[0];
        +	*ptr++ = s->s3->send_alert[1];
        +
        +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
        +	if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
        +		{	
        +		s2n(s->d1->handshake_read_seq, ptr);
        +#if 0
        +		if ( s->d1->r_msg_hdr.frag_off == 0)  /* waiting for a new msg */
        +
        +		else
        +			s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
        +#endif
        +
        +#if 0
        +		fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);
        +#endif
        +		l2n3(s->d1->r_msg_hdr.frag_off, ptr);
        +		}
        +#endif
        +
        +	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
        +	if (i <= 0)
        +		{
        +		s->s3->alert_dispatch=1;
        +		/* fprintf( stderr, "not done with alert\n" ); */
        +		}
        +	else
        +		{
        +		if (s->s3->send_alert[0] == SSL3_AL_FATAL
        +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
        +		    || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
        +#endif
        +		    )
        +			(void)BIO_flush(s->wbio);
        +
        +		if (s->msg_callback)
        +			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 
        +				2, s, s->msg_callback_arg);
        +
        +		if (s->info_callback != NULL)
        +			cb=s->info_callback;
        +		else if (s->ctx->info_callback != NULL)
        +			cb=s->ctx->info_callback;
        +
        +		if (cb != NULL)
        +			{
        +			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
        +			cb(s,SSL_CB_WRITE_ALERT,j);
        +			}
        +		}
        +	return(i);
        +	}
        +
        +
        +static DTLS1_BITMAP *
        +dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch)
        +    {
        +    
        +    *is_next_epoch = 0;
        +
        +    /* In current epoch, accept HM, CCS, DATA, & ALERT */
        +    if (rr->epoch == s->d1->r_epoch)
        +        return &s->d1->bitmap;
        +
        +    /* Only HM and ALERT messages can be from the next epoch */
        +    else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
        +        (rr->type == SSL3_RT_HANDSHAKE ||
        +            rr->type == SSL3_RT_ALERT))
        +        {
        +        *is_next_epoch = 1;
        +        return &s->d1->next_bitmap;
        +        }
        +
        +    return NULL;
        +    }
        +
        +#if 0
        +static int
        +dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority,
        +	unsigned long *offset)
        +	{
        +
        +	/* alerts are passed up immediately */
        +	if ( rr->type == SSL3_RT_APPLICATION_DATA ||
        +		rr->type == SSL3_RT_ALERT)
        +		return 0;
        +
        +	/* Only need to buffer if a handshake is underway.
        +	 * (this implies that Hello Request and Client Hello are passed up
        +	 * immediately) */
        +	if ( SSL_in_init(s))
        +		{
        +		unsigned char *data = rr->data;
        +		/* need to extract the HM/CCS sequence number here */
        +		if ( rr->type == SSL3_RT_HANDSHAKE ||
        +			rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
        +			{
        +			unsigned short seq_num;
        +			struct hm_header_st msg_hdr;
        +			struct ccs_header_st ccs_hdr;
        +
        +			if ( rr->type == SSL3_RT_HANDSHAKE)
        +				{
        +				dtls1_get_message_header(data, &msg_hdr);
        +				seq_num = msg_hdr.seq;
        +				*offset = msg_hdr.frag_off;
        +				}
        +			else
        +				{
        +				dtls1_get_ccs_header(data, &ccs_hdr);
        +				seq_num = ccs_hdr.seq;
        +				*offset = 0;
        +				}
        +				
        +			/* this is either a record we're waiting for, or a
        +			 * retransmit of something we happened to previously 
        +			 * receive (higher layers will drop the repeat silently */
        +			if ( seq_num < s->d1->handshake_read_seq)
        +				return 0;
        +			if (rr->type == SSL3_RT_HANDSHAKE && 
        +				seq_num == s->d1->handshake_read_seq &&
        +				msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
        +				return 0;
        +			else if ( seq_num == s->d1->handshake_read_seq &&
        +				(rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
        +					msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
        +				return 0;
        +			else
        +				{
        +				*priority = seq_num;
        +				return 1;
        +				}
        +			}
        +		else /* unknown record type */
        +			return 0;
        +		}
        +
        +	return 0;
        +	}
        +#endif
        +
        +void
        +dtls1_reset_seq_numbers(SSL *s, int rw)
        +	{
        +	unsigned char *seq;
        +	unsigned int seq_bytes = sizeof(s->s3->read_sequence);
        +
        +	if ( rw & SSL3_CC_READ)
        +		{
        +		seq = s->s3->read_sequence;
        +		s->d1->r_epoch++;
        +		memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
        +		memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
        +		}
        +	else
        +		{
        +		seq = s->s3->write_sequence;
        +		memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
        +		s->d1->w_epoch++;
        +		}
        +
        +	memset(seq, 0x00, seq_bytes);
        +	}
        diff --git a/vendor/openssl/openssl/ssl/d1_srtp.c b/vendor/openssl/openssl/ssl/d1_srtp.c
        new file mode 100644
        index 000000000..ab9c41922
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_srtp.c
        @@ -0,0 +1,494 @@
        +/* ssl/t1_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 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).
        + *
        + */
        +/*
        +  DTLS code by Eric Rescorla <ekr@rtfm.com>
        +
        +  Copyright (C) 2006, Network Resonance, Inc.
        +  Copyright (C) 2011, RTFM, Inc.
        +*/
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +#ifndef OPENSSL_NO_SRTP
        +
        +#include "srtp.h"
        +
        +
        +static SRTP_PROTECTION_PROFILE srtp_known_profiles[]=
        +    {
        +    {
        +    "SRTP_AES128_CM_SHA1_80",
        +    SRTP_AES128_CM_SHA1_80,
        +    },
        +    {
        +    "SRTP_AES128_CM_SHA1_32",
        +    SRTP_AES128_CM_SHA1_32,
        +    },
        +#if 0
        +    {
        +    "SRTP_NULL_SHA1_80",
        +    SRTP_NULL_SHA1_80,
        +    },
        +    {
        +    "SRTP_NULL_SHA1_32",
        +    SRTP_NULL_SHA1_32,
        +    },
        +#endif
        +    {0}
        +    };
        +
        +static int find_profile_by_name(char *profile_name,
        +				SRTP_PROTECTION_PROFILE **pptr,unsigned len)
        +	{
        +	SRTP_PROTECTION_PROFILE *p;
        +
        +	p=srtp_known_profiles;
        +	while(p->name)
        +		{
        +		if((len == strlen(p->name)) && !strncmp(p->name,profile_name,
        +							len))
        +			{
        +			*pptr=p;
        +			return 0;
        +			}
        +
        +		p++;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int find_profile_by_num(unsigned profile_num,
        +			       SRTP_PROTECTION_PROFILE **pptr)
        +	{
        +	SRTP_PROTECTION_PROFILE *p;
        +
        +	p=srtp_known_profiles;
        +	while(p->name)
        +		{
        +		if(p->id == profile_num)
        +			{
        +			*pptr=p;
        +			return 0;
        +			}
        +		p++;
        +		}
        +
        +	return 1;
        +	}
        +
        +static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
        +	{
        +	STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
        +
        +	char *col;
        +	char *ptr=(char *)profiles_string;
        +    
        +	SRTP_PROTECTION_PROFILE *p;
        +
        +	if(!(profiles=sk_SRTP_PROTECTION_PROFILE_new_null()))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
        +		return 1;
        +		}
        +    
        +	do
        +		{
        +		col=strchr(ptr,':');
        +
        +		if(!find_profile_by_name(ptr,&p,
        +					 col ? col-ptr : (int)strlen(ptr)))
        +			{
        +			sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
        +			return 1;
        +			}
        +
        +		if(col) ptr=col+1;
        +		} while (col);
        +
        +	*out=profiles;
        +    
        +	return 0;
        +	}
        +    
        +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,const char *profiles)
        +	{
        +	return ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles);
        +	}
        +
        +int SSL_set_tlsext_use_srtp(SSL *s,const char *profiles)
        +	{
        +	return ssl_ctx_make_profiles(profiles,&s->srtp_profiles);
        +	}
        +
        +
        +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
        +	{
        +	if(s != NULL)
        +		{
        +		if(s->srtp_profiles != NULL)
        +			{
        +			return s->srtp_profiles;
        +			}
        +		else if((s->ctx != NULL) &&
        +			(s->ctx->srtp_profiles != NULL))
        +			{
        +			return s->ctx->srtp_profiles;
        +			}
        +		}
        +
        +	return NULL;
        +	}
        +
        +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
        +	{
        +	return s->srtp_profile;
        +	}
        +
        +/* Note: this function returns 0 length if there are no 
        +   profiles specified */
        +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
        +	{
        +	int ct=0;
        +	int i;
        +	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0;
        +	SRTP_PROTECTION_PROFILE *prof;
        +    
        +	clnt=SSL_get_srtp_profiles(s);    
        +	ct=sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
        +
        +	if(p)
        +		{
        +		if(ct==0)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
        +			return 1;
        +			}
        +
        +		if((2 + ct*2 + 1) > maxlen)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
        +			return 1;
        +			}
        +
        +                /* Add the length */
        +                s2n(ct * 2, p);
        +		for(i=0;i<ct;i++)
        +			{
        +			prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
        +			s2n(prof->id,p);
        +			}
        +
        +                /* Add an empty use_mki value */
        +                *p++ = 0;
        +		}
        +
        +	*len=2 + ct*2 + 1;
        +    
        +	return 0;
        +	}
        +
        +
        +int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
        +	{
        +	SRTP_PROTECTION_PROFILE *cprof,*sprof;
        +	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
        +        int ct;
        +        int mki_len;
        +	int i,j;
        +	int id;
        +	int ret;
        +
        +         /* Length value + the MKI length */
        +        if(len < 3)
        +		{            
        +		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +                }
        +
        +        /* Pull off the length of the cipher suite list */
        +        n2s(d, ct);
        +        len -= 2;
        +        
        +        /* Check that it is even */
        +	if(ct%2)
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +		}
        +        
        +        /* Check that lengths are consistent */
        +	if(len < (ct + 1)) 
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +		}
        +
        +        
        +	clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
        +
        +	while(ct)
        +		{
        +		n2s(d,id);
        +		ct-=2;
        +                len-=2;
        +
        +		if(!find_profile_by_num(id,&cprof))
        +			{
        +			sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
        +			}
        +		else
        +			{
        +			; /* Ignore */
        +			}
        +		}
        +
        +        /* Now extract the MKI value as a sanity check, but discard it for now */
        +        mki_len = *d;
        +        d++; len--;
        +
        +        if (mki_len != len)
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +		}
        +
        +	srvr=SSL_get_srtp_profiles(s);
        +
        +	/* Pick our most preferred profile. If no profiles have been
        +	 configured then the outer loop doesn't run 
        +	 (sk_SRTP_PROTECTION_PROFILE_num() = -1)
        +	 and so we just return without doing anything */
        +	for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++)
        +		{
        +		sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i);
        +
        +		for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++)
        +			{
        +			cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j);
        +            
        +			if(cprof->id==sprof->id)
        +				{
        +				s->srtp_profile=sprof;
        +				*al=0;
        +				ret=0;
        +				goto done;
        +				}
        +			}
        +		}
        +
        +	ret=0;
        +    
        +done:
        +	if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt);
        +
        +	return ret;
        +	}
        +
        +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
        +	{
        +	if(p)
        +		{
        +		if(maxlen < 5)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
        +			return 1;
        +			}
        +
        +		if(s->srtp_profile==0)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_USE_SRTP_NOT_NEGOTIATED);
        +			return 1;
        +			}
        +                s2n(2, p);
        +		s2n(s->srtp_profile->id,p);
        +                *p++ = 0;
        +		}
        +	*len=5;
        +    
        +	return 0;
        +	}
        +    
        +
        +int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
        +	{
        +	unsigned id;
        +	int i;
        +        int ct;
        +
        +	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
        +	SRTP_PROTECTION_PROFILE *prof;
        +
        +	if(len!=5)
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +		}
        +
        +        n2s(d, ct);
        +	if(ct!=2)
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +		}
        +
        +	n2s(d,id);
        +        if (*d)  /* Must be no MKI, since we never offer one */
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE);
        +		*al=SSL_AD_ILLEGAL_PARAMETER;
        +		return 1;
        +		}
        +
        +	clnt=SSL_get_srtp_profiles(s);
        +
        +	/* Throw an error if the server gave us an unsolicited extension */
        +	if (clnt == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_NO_SRTP_PROFILES);
        +		*al=SSL_AD_DECODE_ERROR;
        +		return 1;
        +		}
        +    
        +	/* Check to see if the server gave us something we support
        +	   (and presumably offered)
        +	*/
        +	for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(clnt);i++)
        +		{
        +		prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
        +	    
        +		if(prof->id == id)
        +			{
        +			s->srtp_profile=prof;
        +			*al=0;
        +			return 0;
        +			}
        +		}
        +
        +	SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        +	*al=SSL_AD_DECODE_ERROR;
        +	return 1;
        +	}
        +
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/d1_srvr.c b/vendor/openssl/openssl/ssl/d1_srvr.c
        new file mode 100644
        index 000000000..29421da9a
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/d1_srvr.c
        @@ -0,0 +1,1711 @@
        +/* ssl/d1_srvr.c */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@OpenSSL.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/md5.h>
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +static const SSL_METHOD *dtls1_get_server_method(int ver);
        +static int dtls1_send_hello_verify_request(SSL *s);
        +
        +static const SSL_METHOD *dtls1_get_server_method(int ver)
        +	{
        +	if (ver == DTLS1_VERSION)
        +		return(DTLSv1_server_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,
        +			dtls1_accept,
        +			ssl_undefined_function,
        +			dtls1_get_server_method)
        +
        +int dtls1_accept(SSL *s)
        +	{
        +	BUF_MEM *buf;
        +	unsigned long Time=(unsigned long)time(NULL);
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	unsigned long alg_k;
        +	int ret= -1;
        +	int new_state,state,skip=0;
        +	int listen;
        +#ifndef OPENSSL_NO_SCTP
        +	unsigned char sctpauthkey[64];
        +	char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
        +#endif
        +
        +	RAND_add(&Time,sizeof(Time),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +	
        +	listen = s->d1->listen;
        +
        +	/* init things to blank */
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
        +
        +	s->d1->listen = listen;
        +#ifndef OPENSSL_NO_SCTP
        +	/* Notify SCTP BIO socket to enter handshake
        +	 * mode and prevent stream identifier other
        +	 * than 0. Will be ignored if no SCTP is used.
        +	 */
        +	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
        +#endif
        +
        +	if (s->cert == NULL)
        +		{
        +		SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
        +		return(-1);
        +		}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	/* If we're awaiting a HeartbeatResponse, pretend we
        +	 * already got and don't await it anymore, because
        +	 * Heartbeats don't make sense during handshakes anyway.
        +	 */
        +	if (s->tlsext_hb_pending)
        +		{
        +		dtls1_stop_timer(s);
        +		s->tlsext_hb_pending = 0;
        +		s->tlsext_hb_seq++;
        +		}
        +#endif
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch (s->state)
        +			{
        +		case SSL_ST_RENEGOTIATE:
        +			s->renegotiate=1;
        +			/* s->state=SSL_ST_ACCEPT; */
        +
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_ACCEPT:
        +		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
        +		case SSL_ST_OK|SSL_ST_ACCEPT:
        +
        +			s->server=1;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00))
        +				{
        +				SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
        +				return -1;
        +				}
        +			s->type=SSL_ST_ACCEPT;
        +
        +			if (s->init_buf == NULL)
        +				{
        +				if ((buf=BUF_MEM_new()) == NULL)
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				s->init_buf=buf;
        +				}
        +
        +			if (!ssl3_setup_buffers(s))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			s->init_num=0;
        +
        +			if (s->state != SSL_ST_RENEGOTIATE)
        +				{
        +				/* Ok, we now need to push on a buffering BIO so that
        +				 * the output is sent in a way that TCP likes :-)
        +				 * ...but not with SCTP :-)
        +				 */
        +#ifndef OPENSSL_NO_SCTP
        +				if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +#endif
        +					if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
        +
        +				ssl3_init_finished_mac(s);
        +				s->state=SSL3_ST_SR_CLNT_HELLO_A;
        +				s->ctx->stats.sess_accept++;
        +				}
        +			else
        +				{
        +				/* s->state == SSL_ST_RENEGOTIATE,
        +				 * we will just send a HelloRequest */
        +				s->ctx->stats.sess_accept_renegotiate++;
        +				s->state=SSL3_ST_SW_HELLO_REQ_A;
        +				}
        +
        +			break;
        +
        +		case SSL3_ST_SW_HELLO_REQ_A:
        +		case SSL3_ST_SW_HELLO_REQ_B:
        +
        +			s->shutdown=0;
        +			dtls1_start_timer(s);
        +			ret=dtls1_send_hello_request(s);
        +			if (ret <= 0) goto end;
        +			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			s->init_num=0;
        +
        +			ssl3_init_finished_mac(s);
        +			break;
        +
        +		case SSL3_ST_SW_HELLO_REQ_C:
        +			s->state=SSL_ST_OK;
        +			break;
        +
        +		case SSL3_ST_SR_CLNT_HELLO_A:
        +		case SSL3_ST_SR_CLNT_HELLO_B:
        +		case SSL3_ST_SR_CLNT_HELLO_C:
        +
        +			s->shutdown=0;
        +			ret=ssl3_get_client_hello(s);
        +			if (ret <= 0) goto end;
        +			dtls1_stop_timer(s);
        +
        +			if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
        +				s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
        +			else
        +				s->state = SSL3_ST_SW_SRVR_HELLO_A;
        +
        +			s->init_num=0;
        +
        +			/* Reflect ClientHello sequence to remain stateless while listening */
        +			if (listen)
        +				{
        +				memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence));
        +				}
        +
        +			/* If we're just listening, stop here */
        +			if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
        +				{
        +				ret = 2;
        +				s->d1->listen = 0;
        +				/* Set expected sequence numbers
        +				 * to continue the handshake.
        +				 */
        +				s->d1->handshake_read_seq = 2;
        +				s->d1->handshake_write_seq = 1;
        +				s->d1->next_handshake_write_seq = 1;
        +				goto end;
        +				}
        +			
        +			break;
        +			
        +		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
        +		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
        +
        +			ret = dtls1_send_hello_verify_request(s);
        +			if ( ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
        +
        +			/* HelloVerifyRequest resets Finished MAC */
        +			if (s->version != DTLS1_BAD_VER)
        +				ssl3_init_finished_mac(s);
        +			break;
        +			
        +#ifndef OPENSSL_NO_SCTP
        +		case DTLS1_SCTP_ST_SR_READ_SOCK:
        +			
        +			if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))		
        +				{
        +				s->s3->in_read_app_data=2;
        +				s->rwstate=SSL_READING;
        +				BIO_clear_retry_flags(SSL_get_rbio(s));
        +				BIO_set_retry_read(SSL_get_rbio(s));
        +				ret = -1;
        +				goto end;
        +				}
        +			
        +			s->state=SSL3_ST_SR_FINISHED_A;
        +			break;
        +			
        +		case DTLS1_SCTP_ST_SW_WRITE_SOCK:
        +			ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
        +			if (ret < 0) goto end;
        +			
        +			if (ret == 0)
        +				{
        +				if (s->d1->next_state != SSL_ST_OK)
        +					{
        +					s->s3->in_read_app_data=2;
        +					s->rwstate=SSL_READING;
        +					BIO_clear_retry_flags(SSL_get_rbio(s));
        +					BIO_set_retry_read(SSL_get_rbio(s));
        +					ret = -1;
        +					goto end;
        +					}
        +				}
        +
        +			s->state=s->d1->next_state;
        +			break;
        +#endif
        +
        +		case SSL3_ST_SW_SRVR_HELLO_A:
        +		case SSL3_ST_SW_SRVR_HELLO_B:
        +			s->renegotiate = 2;
        +			dtls1_start_timer(s);
        +			ret=dtls1_send_server_hello(s);
        +			if (ret <= 0) goto end;
        +
        +			if (s->hit)
        +				{
        +#ifndef OPENSSL_NO_SCTP
        +				/* Add new shared key for SCTP-Auth,
        +				 * will be ignored if no SCTP used.
        +				 */
        +				snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
        +				         DTLS1_SCTP_AUTH_LABEL);
        +
        +				SSL_export_keying_material(s, sctpauthkey,
        +				                           sizeof(sctpauthkey), labelbuffer,
        +				                           sizeof(labelbuffer), NULL, 0, 0);
        +				
        +				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
        +                         sizeof(sctpauthkey), sctpauthkey);
        +#endif
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (s->tlsext_ticket_expected)
        +					s->state=SSL3_ST_SW_SESSION_TICKET_A;
        +				else
        +					s->state=SSL3_ST_SW_CHANGE_A;
        +#else
        +				s->state=SSL3_ST_SW_CHANGE_A;
        +#endif
        +				}
        +			else
        +				s->state=SSL3_ST_SW_CERT_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_CERT_A:
        +		case SSL3_ST_SW_CERT_B:
        +			/* Check if it is anon DH or normal PSK */
        +			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
        +				&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +				{
        +				dtls1_start_timer(s);
        +				ret=dtls1_send_server_certificate(s);
        +				if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (s->tlsext_status_expected)
        +					s->state=SSL3_ST_SW_CERT_STATUS_A;
        +				else
        +					s->state=SSL3_ST_SW_KEY_EXCH_A;
        +				}
        +			else
        +				{
        +				skip = 1;
        +				s->state=SSL3_ST_SW_KEY_EXCH_A;
        +				}
        +#else
        +				}
        +			else
        +				skip=1;
        +
        +			s->state=SSL3_ST_SW_KEY_EXCH_A;
        +#endif
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_KEY_EXCH_A:
        +		case SSL3_ST_SW_KEY_EXCH_B:
        +			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
        +
        +			/* clear this, it may get reset by
        +			 * send_server_key_exchange */
        +			if ((s->options & SSL_OP_EPHEMERAL_RSA)
        +#ifndef OPENSSL_NO_KRB5
        +				&& !(alg_k & SSL_kKRB5)
        +#endif /* OPENSSL_NO_KRB5 */
        +				)
        +				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
        +				 * even when forbidden by protocol specs
        +				 * (handshake may fail as clients are not required to
        +				 * be able to handle this) */
        +				s->s3->tmp.use_rsa_tmp=1;
        +			else
        +				s->s3->tmp.use_rsa_tmp=0;
        +
        +			/* only send if a DH key exchange or
        +			 * RSA but we have a sign only certificate */
        +			if (s->s3->tmp.use_rsa_tmp
        +			/* PSK: send ServerKeyExchange if PSK identity
        +			 * hint if provided */
        +#ifndef OPENSSL_NO_PSK
        +			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
        +#endif
        +			    || (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
        +			    || (alg_k & SSL_kEECDH)
        +			    || ((alg_k & SSL_kRSA)
        +				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
        +				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
        +					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
        +					)
        +				    )
        +				)
        +			    )
        +				{
        +				dtls1_start_timer(s);
        +				ret=dtls1_send_server_key_exchange(s);
        +				if (ret <= 0) goto end;
        +				}
        +			else
        +				skip=1;
        +
        +			s->state=SSL3_ST_SW_CERT_REQ_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_CERT_REQ_A:
        +		case SSL3_ST_SW_CERT_REQ_B:
        +			if (/* don't request cert unless asked for it: */
        +				!(s->verify_mode & SSL_VERIFY_PEER) ||
        +				/* if SSL_VERIFY_CLIENT_ONCE is set,
        +				 * don't request cert during re-negotiation: */
        +				((s->session->peer != NULL) &&
        +				 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
        +				/* never request cert in anonymous ciphersuites
        +				 * (see section "Certificate request" in SSL 3 drafts
        +				 * and in RFC 2246): */
        +				((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
        +				 /* ... except when the application insists on verification
        +				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
        +				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
        +				 /* never request cert in Kerberos ciphersuites */
        +				(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
        +				/* With normal PSK Certificates and
        +				 * Certificate Requests are omitted */
        +				|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +				{
        +				/* no cert request */
        +				skip=1;
        +				s->s3->tmp.cert_request=0;
        +				s->state=SSL3_ST_SW_SRVR_DONE_A;
        +#ifndef OPENSSL_NO_SCTP
        +				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +					{
        +					s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
        +					s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
        +					}
        +#endif
        +				}
        +			else
        +				{
        +				s->s3->tmp.cert_request=1;
        +				dtls1_start_timer(s);
        +				ret=dtls1_send_certificate_request(s);
        +				if (ret <= 0) goto end;
        +#ifndef NETSCAPE_HANG_BUG
        +				s->state=SSL3_ST_SW_SRVR_DONE_A;
        +#ifndef OPENSSL_NO_SCTP
        +				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +					{
        +					s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
        +					s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
        +					}
        +#endif
        +#else
        +				s->state=SSL3_ST_SW_FLUSH;
        +				s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
        +#ifndef OPENSSL_NO_SCTP
        +				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +					{
        +					s->d1->next_state = s->s3->tmp.next_state;
        +					s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK;
        +					}
        +#endif
        +#endif
        +				s->init_num=0;
        +				}
        +			break;
        +
        +		case SSL3_ST_SW_SRVR_DONE_A:
        +		case SSL3_ST_SW_SRVR_DONE_B:
        +			dtls1_start_timer(s);
        +			ret=dtls1_send_server_done(s);
        +			if (ret <= 0) goto end;
        +			s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			s->init_num=0;
        +			break;
        +		
        +		case SSL3_ST_SW_FLUSH:
        +			s->rwstate=SSL_WRITING;
        +			if (BIO_flush(s->wbio) <= 0)
        +				{
        +				/* If the write error was fatal, stop trying */
        +				if (!BIO_should_retry(s->wbio))
        +					{
        +					s->rwstate=SSL_NOTHING;
        +					s->state=s->s3->tmp.next_state;
        +					}
        +				
        +				ret= -1;
        +				goto end;
        +				}
        +			s->rwstate=SSL_NOTHING;
        +			s->state=s->s3->tmp.next_state;
        +			break;
        +
        +		case SSL3_ST_SR_CERT_A:
        +		case SSL3_ST_SR_CERT_B:
        +			/* Check for second client hello (MS SGC) */
        +			ret = ssl3_check_client_hello(s);
        +			if (ret <= 0)
        +				goto end;
        +			if (ret == 2)
        +				{
        +				dtls1_stop_timer(s);
        +				s->state = SSL3_ST_SR_CLNT_HELLO_C;
        +				}
        +			else {
        +				/* could be sent for a DH cert, even if we
        +				 * have not asked for it :-) */
        +				ret=ssl3_get_client_certificate(s);
        +				if (ret <= 0) goto end;
        +				s->init_num=0;
        +				s->state=SSL3_ST_SR_KEY_EXCH_A;
        +			}
        +			break;
        +
        +		case SSL3_ST_SR_KEY_EXCH_A:
        +		case SSL3_ST_SR_KEY_EXCH_B:
        +			ret=ssl3_get_client_key_exchange(s);
        +			if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_SCTP
        +			/* Add new shared key for SCTP-Auth,
        +			 * will be ignored if no SCTP used.
        +			 */
        +			snprintf((char *) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
        +			         DTLS1_SCTP_AUTH_LABEL);
        +
        +			SSL_export_keying_material(s, sctpauthkey,
        +			                           sizeof(sctpauthkey), labelbuffer,
        +			                           sizeof(labelbuffer), NULL, 0, 0);
        +
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
        +			         sizeof(sctpauthkey), sctpauthkey);
        +#endif
        +
        +			s->state=SSL3_ST_SR_CERT_VRFY_A;
        +			s->init_num=0;
        +
        +			if (ret == 2)
        +				{
        +				/* For the ECDH ciphersuites when
        +				 * the client sends its ECDH pub key in
        +				 * a certificate, the CertificateVerify
        +				 * message is not sent.
        +				 */
        +				s->state=SSL3_ST_SR_FINISHED_A;
        +				s->init_num = 0;
        +				}
        +			else
        +				{
        +				s->state=SSL3_ST_SR_CERT_VRFY_A;
        +				s->init_num=0;
        +
        +				/* We need to get hashes here so if there is
        +				 * a client cert, it can be verified */ 
        +				s->method->ssl3_enc->cert_verify_mac(s,
        +					NID_md5,
        +					&(s->s3->tmp.cert_verify_md[0]));
        +				s->method->ssl3_enc->cert_verify_mac(s,
        +					NID_sha1,
        +					&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
        +				}
        +			break;
        +
        +		case SSL3_ST_SR_CERT_VRFY_A:
        +		case SSL3_ST_SR_CERT_VRFY_B:
        +
        +			s->d1->change_cipher_spec_ok = 1;
        +			/* we should decide if we expected this one */
        +			ret=ssl3_get_cert_verify(s);
        +			if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_SCTP
        +			if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
        +			    state == SSL_ST_RENEGOTIATE)
        +				s->state=DTLS1_SCTP_ST_SR_READ_SOCK;
        +			else
        +#endif			
        +				s->state=SSL3_ST_SR_FINISHED_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SR_FINISHED_A:
        +		case SSL3_ST_SR_FINISHED_B:
        +			s->d1->change_cipher_spec_ok = 1;
        +			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
        +				SSL3_ST_SR_FINISHED_B);
        +			if (ret <= 0) goto end;
        +			dtls1_stop_timer(s);
        +			if (s->hit)
        +				s->state=SSL_ST_OK;
        +#ifndef OPENSSL_NO_TLSEXT
        +			else if (s->tlsext_ticket_expected)
        +				s->state=SSL3_ST_SW_SESSION_TICKET_A;
        +#endif
        +			else
        +				s->state=SSL3_ST_SW_CHANGE_A;
        +			s->init_num=0;
        +			break;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		case SSL3_ST_SW_SESSION_TICKET_A:
        +		case SSL3_ST_SW_SESSION_TICKET_B:
        +			ret=dtls1_send_newsession_ticket(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_CHANGE_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_CERT_STATUS_A:
        +		case SSL3_ST_SW_CERT_STATUS_B:
        +			ret=ssl3_send_cert_status(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_KEY_EXCH_A;
        +			s->init_num=0;
        +			break;
        +
        +#endif
        +
        +		case SSL3_ST_SW_CHANGE_A:
        +		case SSL3_ST_SW_CHANGE_B:
        +
        +			s->session->cipher=s->s3->tmp.new_cipher;
        +			if (!s->method->ssl3_enc->setup_key_block(s))
        +				{ ret= -1; goto end; }
        +
        +			ret=dtls1_send_change_cipher_spec(s,
        +				SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
        +
        +			if (ret <= 0) goto end;
        +
        +#ifndef OPENSSL_NO_SCTP
        +			/* Change to new shared key of SCTP-Auth,
        +			 * will be ignored if no SCTP used.
        +			 */
        +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
        +#endif
        +
        +			s->state=SSL3_ST_SW_FINISHED_A;
        +			s->init_num=0;
        +
        +			if (!s->method->ssl3_enc->change_cipher_state(s,
        +				SSL3_CHANGE_CIPHER_SERVER_WRITE))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
        +			break;
        +
        +		case SSL3_ST_SW_FINISHED_A:
        +		case SSL3_ST_SW_FINISHED_B:
        +			ret=dtls1_send_finished(s,
        +				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
        +				s->method->ssl3_enc->server_finished_label,
        +				s->method->ssl3_enc->server_finished_label_len);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			if (s->hit)
        +				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
        +			else
        +				{
        +				s->s3->tmp.next_state=SSL_ST_OK;
        +#ifndef OPENSSL_NO_SCTP
        +				if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
        +					{
        +					s->d1->next_state = s->s3->tmp.next_state;
        +					s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK;
        +					}
        +#endif
        +				}
        +			s->init_num=0;
        +			break;
        +
        +		case SSL_ST_OK:
        +			/* clean a few things up */
        +			ssl3_cleanup_key_block(s);
        +
        +#if 0
        +			BUF_MEM_free(s->init_buf);
        +			s->init_buf=NULL;
        +#endif
        +
        +			/* remove buffering on output */
        +			ssl_free_wbio_buffer(s);
        +
        +			s->init_num=0;
        +
        +			if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */
        +				{
        +				s->renegotiate=0;
        +				s->new_session=0;
        +				
        +				ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
        +				
        +				s->ctx->stats.sess_accept_good++;
        +				/* s->server=1; */
        +				s->handshake_func=dtls1_accept;
        +
        +				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
        +				}
        +			
        +			ret = 1;
        +
        +			/* done handshaking, next message is client hello */
        +			s->d1->handshake_read_seq = 0;
        +			/* next message is server hello */
        +			s->d1->handshake_write_seq = 0;
        +			s->d1->next_handshake_write_seq = 0;
        +			goto end;
        +			/* break; */
        +
        +		default:
        +			SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* break; */
        +			}
        +		
        +		if (!s->s3->tmp.reuse_message && !skip)
        +			{
        +			if (s->debug)
        +				{
        +				if ((ret=BIO_flush(s->wbio)) <= 0)
        +					goto end;
        +				}
        +
        +
        +			if ((cb != NULL) && (s->state != state))
        +				{
        +				new_state=s->state;
        +				s->state=state;
        +				cb(s,SSL_CB_ACCEPT_LOOP,1);
        +				s->state=new_state;
        +				}
        +			}
        +		skip=0;
        +		}
        +end:
        +	/* BIO_flush(s->wbio); */
        +
        +	s->in_handshake--;
        +#ifndef OPENSSL_NO_SCTP
        +		/* Notify SCTP BIO socket to leave handshake
        +		 * mode and prevent stream identifier other
        +		 * than 0. Will be ignored if no SCTP is used.
        +		 */
        +		BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
        +#endif
        +
        +	if (cb != NULL)
        +		cb(s,SSL_CB_ACCEPT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +int dtls1_send_hello_request(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL3_ST_SW_HELLO_REQ_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0);
        +
        +		s->state=SSL3_ST_SW_HELLO_REQ_B;
        +		/* number of bytes to write */
        +		s->init_num=DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +
        +		/* no need to buffer this message, since there are no retransmit 
        +		 * requests for it */
        +		}
        +
        +	/* SSL3_ST_SW_HELLO_REQ_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int dtls1_send_hello_verify_request(SSL *s)
        +	{
        +	unsigned int msg_len;
        +	unsigned char *msg, *buf, *p;
        +
        +	if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A)
        +		{
        +		buf = (unsigned char *)s->init_buf->data;
        +
        +		msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
        +		*(p++) = s->version >> 8;
        +		*(p++) = s->version & 0xFF;
        +
        +		if (s->ctx->app_gen_cookie_cb == NULL ||
        +		     s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
        +			 &(s->d1->cookie_len)) == 0)
        +			{
        +			SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
        +			return 0;
        +			}
        +
        +		*(p++) = (unsigned char) s->d1->cookie_len;
        +		memcpy(p, s->d1->cookie, s->d1->cookie_len);
        +		p += s->d1->cookie_len;
        +		msg_len = p - msg;
        +
        +		dtls1_set_message_header(s, buf,
        +			DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, msg_len);
        +
        +		s->state=DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
        +		/* number of bytes to write */
        +		s->init_num=p-buf;
        +		s->init_off=0;
        +		}
        +
        +	/* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int dtls1_send_server_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	int i;
        +	unsigned int sl;
        +	unsigned long l,Time;
        +
        +	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
        +		{
        +		buf=(unsigned char *)s->init_buf->data;
        +		p=s->s3->server_random;
        +		Time=(unsigned long)time(NULL);			/* Time */
        +		l2n(Time,p);
        +		RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
        +		/* Do the message type and length last */
        +		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
        +
        +		*(p++)=s->version>>8;
        +		*(p++)=s->version&0xff;
        +
        +		/* Random stuff */
        +		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
        +		p+=SSL3_RANDOM_SIZE;
        +
        +		/* now in theory we have 3 options to sending back the
        +		 * session id.  If it is a re-use, we send back the
        +		 * old session-id, if it is a new session, we send
        +		 * back the new session-id or we send back a 0 length
        +		 * session-id if we want it to be single use.
        +		 * Currently I will not implement the '0' length session-id
        +		 * 12-Jan-98 - I'll now support the '0' length stuff.
        +		 */
        +		if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER))
        +			s->session->session_id_length=0;
        +
        +		sl=s->session->session_id_length;
        +		if (sl > sizeof s->session->session_id)
        +			{
        +			SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		*(p++)=sl;
        +		memcpy(p,s->session->session_id,sl);
        +		p+=sl;
        +
        +		/* put the cipher */
        +		if (s->s3->tmp.new_cipher == NULL)
        +			return -1;
        +		i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
        +		p+=i;
        +
        +		/* put the compression method */
        +#ifdef OPENSSL_NO_COMP
        +		*(p++)=0;
        +#else
        +		if (s->s3->tmp.new_compression == NULL)
        +			*(p++)=0;
        +		else
        +			*(p++)=s->s3->tmp.new_compression->id;
        +#endif
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
        +			{
        +			SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +#endif
        +
        +		/* do the header */
        +		l=(p-d);
        +		d=buf;
        +
        +		d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
        +
        +		s->state=SSL3_ST_SW_SRVR_HELLO_B;
        +		/* number of bytes to write */
        +		s->init_num=p-buf;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +
        +	/* SSL3_ST_SW_SRVR_HELLO_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int dtls1_send_server_done(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL3_ST_SW_SRVR_DONE_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +
        +		/* do the header */
        +		p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0);
        +
        +		s->state=SSL3_ST_SW_SRVR_DONE_B;
        +		/* number of bytes to write */
        +		s->init_num=DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +
        +	/* SSL3_ST_SW_SRVR_DONE_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int dtls1_send_server_key_exchange(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	unsigned char *q;
        +	int j,num;
        +	RSA *rsa;
        +	unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        +	unsigned int u;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	DH *dh=NULL,*dhp;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh=NULL, *ecdhp;
        +	unsigned char *encodedPoint = NULL;
        +	int encodedlen = 0;
        +	int curve_id = 0;
        +	BN_CTX *bn_ctx = NULL; 
        +#endif
        +	EVP_PKEY *pkey;
        +	unsigned char *p,*d;
        +	int al,i;
        +	unsigned long type;
        +	int n;
        +	CERT *cert;
        +	BIGNUM *r[4];
        +	int nr[4],kn;
        +	BUF_MEM *buf;
        +	EVP_MD_CTX md_ctx;
        +
        +	EVP_MD_CTX_init(&md_ctx);
        +	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
        +		{
        +		type=s->s3->tmp.new_cipher->algorithm_mkey;
        +		cert=s->cert;
        +
        +		buf=s->init_buf;
        +
        +		r[0]=r[1]=r[2]=r[3]=NULL;
        +		n=0;
        +#ifndef OPENSSL_NO_RSA
        +		if (type & SSL_kRSA)
        +			{
        +			rsa=cert->rsa_tmp;
        +			if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
        +				{
        +				rsa=s->cert->rsa_tmp_cb(s,
        +				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
        +				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
        +				if(rsa == NULL)
        +				{
        +					al=SSL_AD_HANDSHAKE_FAILURE;
        +					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
        +					goto f_err;
        +				}
        +				RSA_up_ref(rsa);
        +				cert->rsa_tmp=rsa;
        +				}
        +			if (rsa == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
        +				goto f_err;
        +				}
        +			r[0]=rsa->n;
        +			r[1]=rsa->e;
        +			s->s3->tmp.use_rsa_tmp=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			if (type & SSL_kEDH)
        +			{
        +			dhp=cert->dh_tmp;
        +			if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
        +				dhp=s->cert->dh_tmp_cb(s,
        +				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
        +				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
        +			if (dhp == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
        +				goto f_err;
        +				}
        +
        +			if (s->s3->tmp.dh != NULL)
        +				{
        +				DH_free(dh);
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			if ((dh=DHparams_dup(dhp)) == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				goto err;
        +				}
        +
        +			s->s3->tmp.dh=dh;
        +			if ((dhp->pub_key == NULL ||
        +			     dhp->priv_key == NULL ||
        +			     (s->options & SSL_OP_SINGLE_DH_USE)))
        +				{
        +				if(!DH_generate_key(dh))
        +				    {
        +				    SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
        +					   ERR_R_DH_LIB);
        +				    goto err;
        +				    }
        +				}
        +			else
        +				{
        +				dh->pub_key=BN_dup(dhp->pub_key);
        +				dh->priv_key=BN_dup(dhp->priv_key);
        +				if ((dh->pub_key == NULL) ||
        +					(dh->priv_key == NULL))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
        +					goto err;
        +					}
        +				}
        +			r[0]=dh->p;
        +			r[1]=dh->g;
        +			r[2]=dh->pub_key;
        +			}
        +		else 
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +			if (type & SSL_kEECDH)
        +			{
        +			const EC_GROUP *group;
        +
        +			ecdhp=cert->ecdh_tmp;
        +			if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
        +				{
        +				ecdhp=s->cert->ecdh_tmp_cb(s,
        +				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
        +				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
        +				}
        +			if (ecdhp == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
        +				goto f_err;
        +				}
        +
        +			if (s->s3->tmp.ecdh != NULL)
        +				{
        +				EC_KEY_free(s->s3->tmp.ecdh); 
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			/* Duplicate the ECDH structure. */
        +			if (ecdhp == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +			if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			s->s3->tmp.ecdh=ecdh;
        +			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
        +			    (EC_KEY_get0_private_key(ecdh) == NULL) ||
        +			    (s->options & SSL_OP_SINGLE_ECDH_USE))
        +				{
        +				if(!EC_KEY_generate_key(ecdh))
        +				    {
        +				    SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				    goto err;
        +				    }
        +				}
        +
        +			if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
        +			    (EC_KEY_get0_public_key(ecdh)  == NULL) ||
        +			    (EC_KEY_get0_private_key(ecdh) == NULL))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
        +			    (EC_GROUP_get_degree(group) > 163)) 
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
        +				goto err;
        +				}
        +
        +			/* XXX: For now, we only support ephemeral ECDH
        +			 * keys over named (not generic) curves. For 
        +			 * supported named curves, curve_id is non-zero.
        +			 */
        +			if ((curve_id = 
        +			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
        +			    == 0)
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
        +				goto err;
        +				}
        +
        +			/* Encode the public key.
        +			 * First check the size of encoding and
        +			 * allocate memory accordingly.
        +			 */
        +			encodedlen = EC_POINT_point2oct(group, 
        +			    EC_KEY_get0_public_key(ecdh),
        +			    POINT_CONVERSION_UNCOMPRESSED, 
        +			    NULL, 0, NULL);
        +
        +			encodedPoint = (unsigned char *) 
        +			    OPENSSL_malloc(encodedlen*sizeof(unsigned char)); 
        +			bn_ctx = BN_CTX_new();
        +			if ((encodedPoint == NULL) || (bn_ctx == NULL))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +
        +			encodedlen = EC_POINT_point2oct(group, 
        +			    EC_KEY_get0_public_key(ecdh), 
        +			    POINT_CONVERSION_UNCOMPRESSED, 
        +			    encodedPoint, encodedlen, bn_ctx);
        +
        +			if (encodedlen == 0) 
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			BN_CTX_free(bn_ctx);  bn_ctx=NULL;
        +
        +			/* XXX: For now, we only support named (not 
        +			 * generic) curves in ECDH ephemeral key exchanges.
        +			 * In this situation, we need four additional bytes
        +			 * to encode the entire ServerECDHParams
        +			 * structure. 
        +			 */
        +			n = 4 + encodedlen;
        +
        +			/* We'll generate the serverKeyExchange message
        +			 * explicitly so we can set these to NULLs
        +			 */
        +			r[0]=NULL;
        +			r[1]=NULL;
        +			r[2]=NULL;
        +			r[3]=NULL;
        +			}
        +		else 
        +#endif /* !OPENSSL_NO_ECDH */
        +#ifndef OPENSSL_NO_PSK
        +			if (type & SSL_kPSK)
        +				{
        +				/* reserve size for record length and PSK identity hint*/
        +				n+=2+strlen(s->ctx->psk_identity_hint);
        +				}
        +			else
        +#endif /* !OPENSSL_NO_PSK */
        +			{
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
        +			goto f_err;
        +			}
        +		for (i=0; r[i] != NULL; i++)
        +			{
        +			nr[i]=BN_num_bytes(r[i]);
        +			n+=2+nr[i];
        +			}
        +
        +		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
        +			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +			{
        +			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher, NULL))
        +				== NULL)
        +				{
        +				al=SSL_AD_DECODE_ERROR;
        +				goto f_err;
        +				}
        +			kn=EVP_PKEY_size(pkey);
        +			}
        +		else
        +			{
        +			pkey=NULL;
        +			kn=0;
        +			}
        +
        +		if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn))
        +			{
        +			SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
        +			goto err;
        +			}
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[DTLS1_HM_HEADER_LENGTH]);
        +
        +		for (i=0; r[i] != NULL; i++)
        +			{
        +			s2n(nr[i],p);
        +			BN_bn2bin(r[i],p);
        +			p+=nr[i];
        +			}
        +
        +#ifndef OPENSSL_NO_ECDH
        +		if (type & SSL_kEECDH) 
        +			{
        +			/* XXX: For now, we only support named (not generic) curves.
        +			 * In this situation, the serverKeyExchange message has:
        +			 * [1 byte CurveType], [2 byte CurveName]
        +			 * [1 byte length of encoded point], followed by
        +			 * the actual encoded point itself
        +			 */
        +			*p = NAMED_CURVE_TYPE;
        +			p += 1;
        +			*p = 0;
        +			p += 1;
        +			*p = curve_id;
        +			p += 1;
        +			*p = encodedlen;
        +			p += 1;
        +			memcpy((unsigned char*)p, 
        +			    (unsigned char *)encodedPoint, 
        +			    encodedlen);
        +			OPENSSL_free(encodedPoint);
        +			p += encodedlen;
        +			}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +		if (type & SSL_kPSK)
        +			{
        +			/* copy PSK identity hint */
        +			s2n(strlen(s->ctx->psk_identity_hint), p); 
        +			strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint));
        +			p+=strlen(s->ctx->psk_identity_hint);
        +			}
        +#endif
        +
        +		/* not anonymous */
        +		if (pkey != NULL)
        +			{
        +			/* n is the length of the params, they start at
        +			 * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space
        +			 * at the end. */
        +#ifndef OPENSSL_NO_RSA
        +			if (pkey->type == EVP_PKEY_RSA)
        +				{
        +				q=md_buf;
        +				j=0;
        +				for (num=2; num > 0; num--)
        +					{
        +					EVP_DigestInit_ex(&md_ctx,(num == 2)
        +						?s->ctx->md5:s->ctx->sha1, NULL);
        +					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +					EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +					EVP_DigestUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
        +					EVP_DigestFinal_ex(&md_ctx,q,
        +						(unsigned int *)&i);
        +					q+=i;
        +					j+=i;
        +					}
        +				if (RSA_sign(NID_md5_sha1, md_buf, j,
        +					&(p[2]), &u, pkey->pkey.rsa) <= 0)
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
        +					goto err;
        +					}
        +				s2n(u,p);
        +				n+=u+2;
        +				}
        +			else
        +#endif
        +#if !defined(OPENSSL_NO_DSA)
        +				if (pkey->type == EVP_PKEY_DSA)
        +				{
        +				/* lets do DSS */
        +				EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
        +				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
        +				if (!EVP_SignFinal(&md_ctx,&(p[2]),
        +					(unsigned int *)&i,pkey))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
        +					goto err;
        +					}
        +				s2n(i,p);
        +				n+=i+2;
        +				}
        +			else
        +#endif
        +#if !defined(OPENSSL_NO_ECDSA)
        +				if (pkey->type == EVP_PKEY_EC)
        +				{
        +				/* let's do ECDSA */
        +				EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
        +				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
        +				if (!EVP_SignFinal(&md_ctx,&(p[2]),
        +					(unsigned int *)&i,pkey))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
        +					goto err;
        +					}
        +				s2n(i,p);
        +				n+=i+2;
        +				}
        +			else
        +#endif
        +				{
        +				/* Is this error check actually needed? */
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
        +				goto f_err;
        +				}
        +			}
        +
        +		d = dtls1_set_message_header(s, d,
        +			SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n);
        +
        +		/* we should now have things packed up, so lets send
        +		 * it off */
        +		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +
        +	s->state = SSL3_ST_SW_KEY_EXCH_B;
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +#ifndef OPENSSL_NO_ECDH
        +	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
        +	BN_CTX_free(bn_ctx);
        +#endif
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return(-1);
        +	}
        +
        +int dtls1_send_certificate_request(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	int i,j,nl,off,n;
        +	STACK_OF(X509_NAME) *sk=NULL;
        +	X509_NAME *name;
        +	BUF_MEM *buf;
        +	unsigned int msg_len;
        +
        +	if (s->state == SSL3_ST_SW_CERT_REQ_A)
        +		{
        +		buf=s->init_buf;
        +
        +		d=p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
        +
        +		/* get the list of acceptable cert types */
        +		p++;
        +		n=ssl3_get_req_cert_type(s,p);
        +		d[0]=n;
        +		p+=n;
        +		n++;
        +
        +		off=n;
        +		p+=2;
        +		n+=2;
        +
        +		sk=SSL_get_client_CA_list(s);
        +		nl=0;
        +		if (sk != NULL)
        +			{
        +			for (i=0; i<sk_X509_NAME_num(sk); i++)
        +				{
        +				name=sk_X509_NAME_value(sk,i);
        +				j=i2d_X509_NAME(name,NULL);
        +				if (!BUF_MEM_grow_clean(buf,DTLS1_HM_HEADER_LENGTH+n+j+2))
        +					{
        +					SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
        +					goto err;
        +					}
        +				p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+n]);
        +				if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
        +					{
        +					s2n(j,p);
        +					i2d_X509_NAME(name,&p);
        +					n+=2+j;
        +					nl+=2+j;
        +					}
        +				else
        +					{
        +					d=p;
        +					i2d_X509_NAME(name,&p);
        +					j-=2; s2n(j,d); j+=2;
        +					n+=j;
        +					nl+=j;
        +					}
        +				}
        +			}
        +		/* else no CA names */
        +		p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+off]);
        +		s2n(nl,p);
        +
        +		d=(unsigned char *)buf->data;
        +		*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
        +		l2n3(n,d);
        +		s2n(s->d1->handshake_write_seq,d);
        +		s->d1->handshake_write_seq++;
        +
        +		/* we should now have things packed up, so lets send
        +		 * it off */
        +
        +		s->init_num=n+DTLS1_HM_HEADER_LENGTH;
        +		s->init_off=0;
        +#ifdef NETSCAPE_HANG_BUG
        +/* XXX: what to do about this? */
        +		p=(unsigned char *)s->init_buf->data + s->init_num;
        +
        +		/* do the header */
        +		*(p++)=SSL3_MT_SERVER_DONE;
        +		*(p++)=0;
        +		*(p++)=0;
        +		*(p++)=0;
        +		s->init_num += 4;
        +#endif
        +
        +		/* XDTLS:  set message header ? */
        +		msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
        +		dtls1_set_message_header(s, (void *)s->init_buf->data,
        +			SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len);
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +
        +		s->state = SSL3_ST_SW_CERT_REQ_B;
        +		}
        +
        +	/* SSL3_ST_SW_CERT_REQ_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +	return(-1);
        +	}
        +
        +int dtls1_send_server_certificate(SSL *s)
        +	{
        +	unsigned long l;
        +	X509 *x;
        +
        +	if (s->state == SSL3_ST_SW_CERT_A)
        +		{
        +		x=ssl_get_server_send_cert(s);
        +		if (x == NULL)
        +			{
        +			/* VRS: allow null cert if auth == KRB5 */
        +			if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) ||
        +			    (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5))
        +				{
        +				SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
        +				return(0);
        +				}
        +			}
        +
        +		l=dtls1_output_cert_chain(s,x);
        +		s->state=SSL3_ST_SW_CERT_B;
        +		s->init_num=(int)l;
        +		s->init_off=0;
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +
        +	/* SSL3_ST_SW_CERT_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +int dtls1_send_newsession_ticket(SSL *s)
        +	{
        +	if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
        +		{
        +		unsigned char *p, *senc, *macstart;
        +		int len, slen;
        +		unsigned int hlen, msg_len;
        +		EVP_CIPHER_CTX ctx;
        +		HMAC_CTX hctx;
        +		SSL_CTX *tctx = s->initial_ctx;
        +		unsigned char iv[EVP_MAX_IV_LENGTH];
        +		unsigned char key_name[16];
        +
        +		/* get session encoding length */
        +		slen = i2d_SSL_SESSION(s->session, NULL);
        +		/* Some length values are 16 bits, so forget it if session is
        + 		 * too long
        + 		 */
        +		if (slen > 0xFF00)
        +			return -1;
        +		/* Grow buffer if need be: the length calculation is as
        + 		 * follows 12 (DTLS handshake message header) +
        + 		 * 4 (ticket lifetime hint) + 2 (ticket length) +
        + 		 * 16 (key name) + max_iv_len (iv length) +
        + 		 * session_length + max_enc_block_size (max encrypted session
        + 		 * length) + max_md_size (HMAC).
        + 		 */
        +		if (!BUF_MEM_grow(s->init_buf,
        +			DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH +
        +			EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
        +			return -1;
        +		senc = OPENSSL_malloc(slen);
        +		if (!senc)
        +			return -1;
        +		p = senc;
        +		i2d_SSL_SESSION(s->session, &p);
        +
        +		p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
        +		EVP_CIPHER_CTX_init(&ctx);
        +		HMAC_CTX_init(&hctx);
        +		/* Initialize HMAC and cipher contexts. If callback present
        +		 * it does all the work otherwise use generated values
        +		 * from parent ctx.
        +		 */
        +		if (tctx->tlsext_ticket_key_cb)
        +			{
        +			if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
        +							 &hctx, 1) < 0)
        +				{
        +				OPENSSL_free(senc);
        +				return -1;
        +				}
        +			}
        +		else
        +			{
        +			RAND_pseudo_bytes(iv, 16);
        +			EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
        +					tctx->tlsext_tick_aes_key, iv);
        +			HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
        +					tlsext_tick_md(), NULL);
        +			memcpy(key_name, tctx->tlsext_tick_key_name, 16);
        +			}
        +		l2n(s->session->tlsext_tick_lifetime_hint, p);
        +		/* Skip ticket length for now */
        +		p += 2;
        +		/* Output key name */
        +		macstart = p;
        +		memcpy(p, key_name, 16);
        +		p += 16;
        +		/* output IV */
        +		memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
        +		p += EVP_CIPHER_CTX_iv_length(&ctx);
        +		/* Encrypt session data */
        +		EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
        +		p += len;
        +		EVP_EncryptFinal(&ctx, p, &len);
        +		p += len;
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +
        +		HMAC_Update(&hctx, macstart, p - macstart);
        +		HMAC_Final(&hctx, p, &hlen);
        +		HMAC_CTX_cleanup(&hctx);
        +
        +		p += hlen;
        +		/* Now write out lengths: p points to end of data written */
        +		/* Total length */
        +		len = p - (unsigned char *)(s->init_buf->data);
        +		/* Ticket length */
        +		p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
        +		s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p);
        +
        +		/* number of bytes to write */
        +		s->init_num= len;
        +		s->state=SSL3_ST_SW_SESSION_TICKET_B;
        +		s->init_off=0;
        +		OPENSSL_free(senc);
        +
        +		/* XDTLS:  set message header ? */
        +		msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
        +		dtls1_set_message_header(s, (void *)s->init_buf->data,
        +			SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len);
        +
        +		/* buffer the message to handle re-xmits */
        +		dtls1_buffer_message(s, 0);
        +		}
        +
        +	/* SSL3_ST_SW_SESSION_TICKET_B */
        +	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/dtls1.h b/vendor/openssl/openssl/ssl/dtls1.h
        new file mode 100644
        index 000000000..e65d50119
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/dtls1.h
        @@ -0,0 +1,287 @@
        +/* ssl/dtls1.h */
        +/* 
        + * DTLS implementation written by Nagendra Modadugu
        + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2005 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_DTLS1_H
        +#define HEADER_DTLS1_H
        +
        +#include <openssl/buffer.h>
        +#include <openssl/pqueue.h>
        +#ifdef OPENSSL_SYS_VMS
        +#include <resource.h>
        +#include <sys/timeb.h>
        +#endif
        +#ifdef OPENSSL_SYS_WIN32
        +/* Needed for struct timeval */
        +#include <winsock.h>
        +#elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
        +#include <sys/timeval.h>
        +#else
        +#if defined(OPENSSL_SYS_VXWORKS)
        +#include <sys/times.h>
        +#else
        +#include <sys/time.h>
        +#endif
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#define DTLS1_VERSION			0xFEFF
        +#define DTLS1_BAD_VER			0x0100
        +
        +#if 0
        +/* this alert description is not specified anywhere... */
        +#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
        +#endif
        +
        +/* lengths of messages */
        +#define DTLS1_COOKIE_LENGTH                     256
        +
        +#define DTLS1_RT_HEADER_LENGTH                  13
        +
        +#define DTLS1_HM_HEADER_LENGTH                  12
        +
        +#define DTLS1_HM_BAD_FRAGMENT                   -2
        +#define DTLS1_HM_FRAGMENT_RETRY                 -3
        +
        +#define DTLS1_CCS_HEADER_LENGTH                  1
        +
        +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
        +#define DTLS1_AL_HEADER_LENGTH                   7
        +#else
        +#define DTLS1_AL_HEADER_LENGTH                   2
        +#endif
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +#ifndef OPENSSL_NO_SCTP
        +#define DTLS1_SCTP_AUTH_LABEL	"EXPORTER_DTLS_OVER_SCTP"
        +#endif
        +
        +typedef struct dtls1_bitmap_st
        +	{
        +	unsigned long map;		/* track 32 packets on 32-bit systems
        +					   and 64 - on 64-bit systems */
        +	unsigned char max_seq_num[8];	/* max record number seen so far,
        +					   64-bit value in big-endian
        +					   encoding */
        +	} DTLS1_BITMAP;
        +
        +struct dtls1_retransmit_state
        +	{
        +	EVP_CIPHER_CTX *enc_write_ctx;	/* cryptographic state */
        +	EVP_MD_CTX *write_hash;			/* used for mac generation */
        +#ifndef OPENSSL_NO_COMP
        +	COMP_CTX *compress;				/* compression */
        +#else
        +	char *compress;	
        +#endif
        +	SSL_SESSION *session;
        +	unsigned short epoch;
        +	};
        +
        +struct hm_header_st
        +	{
        +	unsigned char type;
        +	unsigned long msg_len;
        +	unsigned short seq;
        +	unsigned long frag_off;
        +	unsigned long frag_len;
        +	unsigned int is_ccs;
        +	struct dtls1_retransmit_state saved_retransmit_state;
        +	};
        +
        +struct ccs_header_st
        +	{
        +	unsigned char type;
        +	unsigned short seq;
        +	};
        +
        +struct dtls1_timeout_st
        +	{
        +	/* Number of read timeouts so far */
        +	unsigned int read_timeouts;
        +	
        +	/* Number of write timeouts so far */
        +	unsigned int write_timeouts;
        +	
        +	/* Number of alerts received so far */
        +	unsigned int num_alerts;
        +	};
        +
        +typedef struct record_pqueue_st
        +	{
        +	unsigned short epoch;
        +	pqueue q;
        +	} record_pqueue;
        +
        +typedef struct hm_fragment_st
        +	{
        +	struct hm_header_st msg_header;
        +	unsigned char *fragment;
        +	unsigned char *reassembly;
        +	} hm_fragment;
        +
        +typedef struct dtls1_state_st
        +	{
        +	unsigned int send_cookie;
        +	unsigned char cookie[DTLS1_COOKIE_LENGTH];
        +	unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
        +	unsigned int cookie_len;
        +
        +	/* 
        +	 * The current data and handshake epoch.  This is initially
        +	 * undefined, and starts at zero once the initial handshake is
        +	 * completed 
        +	 */
        +	unsigned short r_epoch;
        +	unsigned short w_epoch;
        +
        +	/* records being received in the current epoch */
        +	DTLS1_BITMAP bitmap;
        +
        +	/* renegotiation starts a new set of sequence numbers */
        +	DTLS1_BITMAP next_bitmap;
        +
        +	/* handshake message numbers */
        +	unsigned short handshake_write_seq;
        +	unsigned short next_handshake_write_seq;
        +
        +	unsigned short handshake_read_seq;
        +
        +	/* save last sequence number for retransmissions */
        +	unsigned char last_write_sequence[8];
        +
        +	/* Received handshake records (processed and unprocessed) */
        +	record_pqueue unprocessed_rcds;
        +	record_pqueue processed_rcds;
        +
        +	/* Buffered handshake messages */
        +	pqueue buffered_messages;
        +
        +	/* Buffered (sent) handshake records */
        +	pqueue sent_messages;
        +
        +	/* Buffered application records.
        +	 * Only for records between CCS and Finished
        +	 * to prevent either protocol violation or
        +	 * unnecessary message loss.
        +	 */
        +	record_pqueue buffered_app_data;
        +
        +	/* Is set when listening for new connections with dtls1_listen() */
        +	unsigned int listen;
        +
        +	unsigned int mtu; /* max DTLS packet size */
        +
        +	struct hm_header_st w_msg_hdr;
        +	struct hm_header_st r_msg_hdr;
        +
        +	struct dtls1_timeout_st timeout;
        +
        +	/* Indicates when the last handshake msg or heartbeat sent will timeout */
        +	struct timeval next_timeout;
        +
        +	/* Timeout duration */
        +	unsigned short timeout_duration;
        +
        +	/* storage for Alert/Handshake protocol data received but not
        +	 * yet processed by ssl3_read_bytes: */
        +	unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
        +	unsigned int alert_fragment_len;
        +	unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
        +	unsigned int handshake_fragment_len;
        +
        +	unsigned int retransmitting;
        +	unsigned int change_cipher_spec_ok;
        +
        +#ifndef OPENSSL_NO_SCTP
        +	/* used when SSL_ST_XX_FLUSH is entered */
        +	int next_state;
        +
        +	int shutdown_received;
        +#endif
        +
        +	} DTLS1_STATE;
        +
        +typedef struct dtls1_record_data_st
        +	{
        +	unsigned char *packet;
        +	unsigned int   packet_length;
        +	SSL3_BUFFER    rbuf;
        +	SSL3_RECORD    rrec;
        +#ifndef OPENSSL_NO_SCTP
        +	struct bio_dgram_sctp_rcvinfo recordinfo;
        +#endif
        +	} DTLS1_RECORD_DATA;
        +
        +#endif
        +
        +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
        +#define DTLS1_TMO_READ_COUNT                      2
        +#define DTLS1_TMO_WRITE_COUNT                     2
        +
        +#define DTLS1_TMO_ALERT_COUNT                     12
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/ssl/install-ssl.com b/vendor/openssl/openssl/ssl/install-ssl.com
        new file mode 100644
        index 000000000..afe6967f8
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/install-ssl.com
        @@ -0,0 +1,136 @@
        +$! INSTALL-SSL.COM -- Installs the files in a given directory tree
        +$!
        +$! Author: Richard Levitte <richard@levitte.org>
        +$! Time of creation: 22-MAY-1998 10:13
        +$!
        +$! P1  root of the directory tree
        +$! P2  "64" for 64-bit pointers.
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$ on error then goto tidy
        +$ on control_c then goto tidy
        +$!
        +$ if p1 .eqs. ""
        +$ then
        +$   write sys$output "First argument missing."
        +$   write sys$output -
        +     "It should be the directory where you want things installed."
        +$   exit
        +$ endif
        +$!
        +$ if (f$getsyi( "cpu") .lt. 128)
        +$ then
        +$     arch = "VAX"
        +$ else
        +$     arch = f$edit( f$getsyi( "arch_name"), "upcase")
        +$     if (arch .eqs. "") then arch = "UNK"
        +$ endif
        +$!
        +$ archd = arch
        +$ lib32 = "32"
        +$ shr = "_SHR32"
        +$!
        +$ if (p2 .nes. "")
        +$ then
        +$   if (p2 .eqs. "64")
        +$   then
        +$     archd = arch+ "_64"
        +$     lib32 = ""
        +$     shr = "_SHR"
        +$   else
        +$     if (p2 .nes. "32")
        +$     then
        +$       write sys$output "Second argument invalid."
        +$       write sys$output "It should be "32", "64", or nothing."
        +$       exit
        +$     endif
        +$   endif
        +$ endif
        +$!
        +$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
        +$ root_dev = f$parse(root,,,"device","syntax_only")
        +$ root_dir = f$parse(root,,,"directory","syntax_only") - -
        +   "[000000." - "][" - "[" - "]"
        +$ root = root_dev + "[" + root_dir
        +$!
        +$ define /nolog wrk_sslroot 'root'.] /trans=conc
        +$ define /nolog wrk_sslinclude wrk_sslroot:[include]
        +$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
        +$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
        +$!
        +$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
        +   create /directory /log wrk_sslroot:[000000]
        +$ if f$parse("wrk_sslinclude:") .eqs. "" then -
        +   create /directory /log wrk_sslinclude:
        +$ if f$parse("wrk_sslxexe:") .eqs. "" then -
        +   create /directory /log wrk_sslxexe:
        +$ if f$parse("wrk_sslxlib:") .eqs. "" then -
        +   create /directory /log wrk_sslxlib:
        +$!
        +$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h
        +$ e_exe := ssl_task
        +$ libs := ssl_libssl
        +$!
        +$ xexe_dir := [-.'archd'.exe.ssl]
        +$!
        +$ copy /protection = w:re 'exheader' wrk_sslinclude: /log
        +$!
        +$ i = 0
        +$ loop_exe:
        +$   e = f$edit( f$element( i, ",", e_exe), "trim")
        +$   i = i + 1
        +$   if e .eqs. "," then goto loop_exe_end
        +$   set noon
        +$   file = xexe_dir+ e+ ".exe"
        +$   if f$search( file) .nes. ""
        +$   then
        +$     copy /protection = w:re 'file' wrk_sslxexe: /log
        +$   endif
        +$   set on
        +$ goto loop_exe
        +$ loop_exe_end:
        +$!
        +$ i = 0
        +$ loop_lib: 
        +$   e = f$edit(f$element(i, ",", libs),"trim")
        +$   i = i + 1
        +$   if e .eqs. "," then goto loop_lib_end
        +$   set noon
        +$! Object library.
        +$   file = xexe_dir+ e+ lib32+ ".olb"
        +$   if f$search( file) .nes. ""
        +$   then
        +$     copy /protection = w:re 'file' wrk_sslxlib: /log
        +$   endif
        +$! Shareable image.
        +$   file = xexe_dir+ e+ shr+ ".exe"
        +$   if f$search( file) .nes. ""
        +$   then
        +$     copy /protection = w:re 'file' wrk_sslxlib: /log
        +$   endif
        +$   set on
        +$ goto loop_lib
        +$ loop_lib_end:
        +$!
        +$ tidy:
        +$!
        +$ call deass wrk_sslroot
        +$ call deass wrk_sslinclude
        +$ call deass wrk_sslxexe
        +$ call deass wrk_sslxlib
        +$!
        +$ exit
        +$!
        +$ deass: subroutine
        +$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
        +$ then
        +$   deassign /process 'p1'
        +$ endif
        +$ endsubroutine
        +$!
        diff --git a/vendor/openssl/openssl/ssl/kssl.c b/vendor/openssl/openssl/ssl/kssl.c
        new file mode 100644
        index 000000000..fd7c67bb1
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/kssl.c
        @@ -0,0 +1,2221 @@
        +/* ssl/kssl.c -*- mode: C; c-file-style: "eay" -*- */
        +/* Written by Vern Staats <staatsvr@asc.hpc.mil> 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).
        + *
        + */
        +
        +
        +/*  ssl/kssl.c  --  Routines to support (& debug) Kerberos5 auth for openssl
        +**
        +**  19990701	VRS 	Started.
        +**  200011??	Jeffrey Altman, Richard Levitte
        +**          		Generalized for Heimdal, Newer MIT, & Win32.
        +**          		Integrated into main OpenSSL 0.9.7 snapshots.
        +**  20010413	Simon Wilkinson, VRS
        +**          		Real RFC2712 KerberosWrapper replaces AP_REQ.
        +*/
        +
        +#include <openssl/opensslconf.h>
        +
        +#include <string.h>
        +
        +#define KRB5_PRIVATE	1
        +
        +#include <openssl/ssl.h>
        +#include <openssl/evp.h>
        +#include <openssl/objects.h>
        +#include <openssl/krb5_asn.h>
        +#include "kssl_lcl.h"
        +
        +#ifndef OPENSSL_NO_KRB5
        +
        +#ifndef ENOMEM
        +#define ENOMEM KRB5KRB_ERR_GENERIC
        +#endif
        +
        +/* 
        + * When OpenSSL is built on Windows, we do not want to require that
        + * the Kerberos DLLs be available in order for the OpenSSL DLLs to
        + * work.  Therefore, all Kerberos routines are loaded at run time
        + * and we do not link to a .LIB file.
        + */
        +
        +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
        +/* 
        + * The purpose of the following pre-processor statements is to provide
        + * compatibility with different releases of MIT Kerberos for Windows.
        + * All versions up to 1.2 used macros.  But macros do not allow for
        + * a binary compatible interface for DLLs.  Therefore, all macros are
        + * being replaced by function calls.  The following code will allow
        + * an OpenSSL DLL built on Windows to work whether or not the macro
        + * or function form of the routines are utilized.
        + */
        +#ifdef  krb5_cc_get_principal
        +#define NO_DEF_KRB5_CCACHE
        +#undef  krb5_cc_get_principal
        +#endif
        +#define krb5_cc_get_principal    kssl_krb5_cc_get_principal
        +
        +#define krb5_free_data_contents  kssl_krb5_free_data_contents   
        +#define krb5_free_context        kssl_krb5_free_context         
        +#define krb5_auth_con_free       kssl_krb5_auth_con_free        
        +#define krb5_free_principal      kssl_krb5_free_principal       
        +#define krb5_mk_req_extended     kssl_krb5_mk_req_extended      
        +#define krb5_get_credentials     kssl_krb5_get_credentials      
        +#define krb5_cc_default          kssl_krb5_cc_default           
        +#define krb5_sname_to_principal  kssl_krb5_sname_to_principal   
        +#define krb5_init_context        kssl_krb5_init_context         
        +#define krb5_free_ticket         kssl_krb5_free_ticket          
        +#define krb5_rd_req              kssl_krb5_rd_req               
        +#define krb5_kt_default          kssl_krb5_kt_default           
        +#define krb5_kt_resolve          kssl_krb5_kt_resolve           
        +/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */
        +#ifndef krb5_kt_close
        +#define krb5_kt_close            kssl_krb5_kt_close
        +#endif /* krb5_kt_close */
        +#ifndef krb5_kt_get_entry
        +#define krb5_kt_get_entry        kssl_krb5_kt_get_entry
        +#endif /* krb5_kt_get_entry */
        +#define krb5_auth_con_init       kssl_krb5_auth_con_init        
        +
        +#define krb5_principal_compare   kssl_krb5_principal_compare
        +#define krb5_decrypt_tkt_part    kssl_krb5_decrypt_tkt_part
        +#define krb5_timeofday           kssl_krb5_timeofday
        +#define krb5_rc_default          kssl_krb5_rc_default
        +
        +#ifdef krb5_rc_initialize
        +#undef krb5_rc_initialize
        +#endif
        +#define krb5_rc_initialize   kssl_krb5_rc_initialize
        +
        +#ifdef krb5_rc_get_lifespan
        +#undef krb5_rc_get_lifespan
        +#endif
        +#define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan
        +
        +#ifdef krb5_rc_destroy
        +#undef krb5_rc_destroy
        +#endif
        +#define krb5_rc_destroy      kssl_krb5_rc_destroy
        +
        +#define valid_cksumtype      kssl_valid_cksumtype
        +#define krb5_checksum_size   kssl_krb5_checksum_size
        +#define krb5_kt_free_entry   kssl_krb5_kt_free_entry
        +#define krb5_auth_con_setrcache  kssl_krb5_auth_con_setrcache
        +#define krb5_auth_con_getrcache  kssl_krb5_auth_con_getrcache
        +#define krb5_get_server_rcache   kssl_krb5_get_server_rcache
        +
        +/* Prototypes for built in stubs */
        +void kssl_krb5_free_data_contents(krb5_context, krb5_data *);
        +void kssl_krb5_free_principal(krb5_context, krb5_principal );
        +krb5_error_code kssl_krb5_kt_resolve(krb5_context,
        +                                     krb5_const char *,
        +                                     krb5_keytab *);
        +krb5_error_code kssl_krb5_kt_default(krb5_context,
        +                                     krb5_keytab *);
        +krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *);
        +krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, 
        +                                 krb5_const krb5_data *,
        +                                 krb5_const_principal, krb5_keytab, 
        +                                 krb5_flags *,krb5_ticket **);
        +
        +krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal,
        +                                         krb5_const_principal);
        +krb5_error_code kssl_krb5_mk_req_extended(krb5_context,
        +                                          krb5_auth_context  *,
        +                                          krb5_const krb5_flags,
        +                                          krb5_data  *,
        +                                          krb5_creds  *,
        +                                          krb5_data  * );
        +krb5_error_code kssl_krb5_init_context(krb5_context *);
        +void kssl_krb5_free_context(krb5_context);
        +krb5_error_code kssl_krb5_cc_default(krb5_context,krb5_ccache  *);
        +krb5_error_code kssl_krb5_sname_to_principal(krb5_context,
        +                                             krb5_const char  *,
        +                                             krb5_const char  *,
        +                                             krb5_int32,
        +                                             krb5_principal  *);
        +krb5_error_code kssl_krb5_get_credentials(krb5_context,
        +                                          krb5_const krb5_flags,
        +                                          krb5_ccache,
        +                                          krb5_creds  *,
        +                                          krb5_creds  *  *);
        +krb5_error_code kssl_krb5_auth_con_init(krb5_context,
        +                                        krb5_auth_context  *);
        +krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, 
        +                                           krb5_ccache cache,
        +                                           krb5_principal *principal);
        +krb5_error_code kssl_krb5_auth_con_free(krb5_context,krb5_auth_context);
        +size_t kssl_krb5_checksum_size(krb5_context context,krb5_cksumtype ctype);
        +krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype);
        +krb5_error_code krb5_kt_free_entry(krb5_context,krb5_keytab_entry FAR * );
        +krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, 
        +                                             krb5_auth_context, 
        +                                             krb5_rcache);
        +krb5_error_code kssl_krb5_get_server_rcache(krb5_context, 
        +                                            krb5_const krb5_data *,
        +                                            krb5_rcache *);
        +krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, 
        +                                             krb5_auth_context,
        +                                             krb5_rcache *);
        +
        +/* Function pointers (almost all Kerberos functions are _stdcall) */
        +static void (_stdcall *p_krb5_free_data_contents)(krb5_context, krb5_data *)
        +	=NULL;
        +static void (_stdcall *p_krb5_free_principal)(krb5_context, krb5_principal )
        +	=NULL;
        +static krb5_error_code(_stdcall *p_krb5_kt_resolve)
        +			(krb5_context, krb5_const char *, krb5_keytab *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_kt_default)(krb5_context,
        +                                                     krb5_keytab *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_free_ticket)(krb5_context, 
        +                                                      krb5_ticket *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_rd_req)(krb5_context, 
        +                                                 krb5_auth_context *, 
        +                                                 krb5_const krb5_data *,
        +                                                 krb5_const_principal, 
        +                                                 krb5_keytab, krb5_flags *,
        +                                                 krb5_ticket **)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_mk_req_extended)
        +			(krb5_context, krb5_auth_context *,
        +			 krb5_const krb5_flags, krb5_data *, krb5_creds *,
        +			 krb5_data * )=NULL;
        +static krb5_error_code (_stdcall *p_krb5_init_context)(krb5_context *)=NULL;
        +static void (_stdcall *p_krb5_free_context)(krb5_context)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_cc_default)(krb5_context,
        +                                                     krb5_ccache  *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_sname_to_principal)
        +			(krb5_context, krb5_const char *, krb5_const char *,
        +			 krb5_int32, krb5_principal *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_get_credentials)
        +			(krb5_context, krb5_const krb5_flags, krb5_ccache,
        +			 krb5_creds *, krb5_creds **)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_auth_con_init)
        +			(krb5_context, krb5_auth_context *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_cc_get_principal)
        +			(krb5_context context, krb5_ccache cache,
        +			 krb5_principal *principal)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_auth_con_free)
        +			(krb5_context, krb5_auth_context)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_decrypt_tkt_part)
        +                        (krb5_context, krb5_const krb5_keyblock *,
        +                                           krb5_ticket *)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_timeofday)
        +                        (krb5_context context, krb5_int32 *timeret)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_rc_default)
        +                        (krb5_context context, krb5_rcache *rc)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_rc_initialize)
        +                        (krb5_context context, krb5_rcache rc,
        +                                     krb5_deltat lifespan)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_rc_get_lifespan)
        +                        (krb5_context context, krb5_rcache rc,
        +                                       krb5_deltat *lifespan)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_rc_destroy)
        +                        (krb5_context context, krb5_rcache rc)=NULL;
        +static krb5_boolean (_stdcall *p_krb5_principal_compare)
        +                     (krb5_context, krb5_const_principal, krb5_const_principal)=NULL;
        +static size_t (_stdcall *p_krb5_checksum_size)(krb5_context context,krb5_cksumtype ctype)=NULL;
        +static krb5_boolean (_stdcall *p_valid_cksumtype)(krb5_cksumtype ctype)=NULL;
        +static krb5_error_code (_stdcall *p_krb5_kt_free_entry)
        +                        (krb5_context,krb5_keytab_entry * )=NULL;
        +static krb5_error_code (_stdcall * p_krb5_auth_con_setrcache)(krb5_context, 
        +                                                               krb5_auth_context, 
        +                                                               krb5_rcache)=NULL;
        +static krb5_error_code (_stdcall * p_krb5_get_server_rcache)(krb5_context, 
        +                                                              krb5_const krb5_data *, 
        +                                                              krb5_rcache *)=NULL;
        +static krb5_error_code (* p_krb5_auth_con_getrcache)(krb5_context, 
        +                                                      krb5_auth_context,
        +                                                      krb5_rcache *)=NULL;
        +static krb5_error_code (_stdcall * p_krb5_kt_close)(krb5_context context, 
        +                                                    krb5_keytab keytab)=NULL;
        +static krb5_error_code (_stdcall * p_krb5_kt_get_entry)(krb5_context context, 
        +                                                        krb5_keytab keytab,
        +                       krb5_const_principal principal, krb5_kvno vno,
        +                       krb5_enctype enctype, krb5_keytab_entry *entry)=NULL;
        +static int krb5_loaded = 0;     /* only attempt to initialize func ptrs once */
        +
        +/* Function to Load the Kerberos 5 DLL and initialize function pointers */
        +void
        +load_krb5_dll(void)
        +	{
        +	HANDLE hKRB5_32;
        +    
        +	krb5_loaded++;
        +	hKRB5_32 = LoadLibrary(TEXT("KRB5_32"));
        +	if (!hKRB5_32)
        +		return;
        +
        +	(FARPROC) p_krb5_free_data_contents =
        +		GetProcAddress( hKRB5_32, "krb5_free_data_contents" );
        +	(FARPROC) p_krb5_free_context =
        +		GetProcAddress( hKRB5_32, "krb5_free_context" );
        +	(FARPROC) p_krb5_auth_con_free =
        +		GetProcAddress( hKRB5_32, "krb5_auth_con_free" );
        +	(FARPROC) p_krb5_free_principal =
        +		GetProcAddress( hKRB5_32, "krb5_free_principal" );
        +	(FARPROC) p_krb5_mk_req_extended =
        +		GetProcAddress( hKRB5_32, "krb5_mk_req_extended" );
        +	(FARPROC) p_krb5_get_credentials =
        +		GetProcAddress( hKRB5_32, "krb5_get_credentials" );
        +	(FARPROC) p_krb5_cc_get_principal =
        +		GetProcAddress( hKRB5_32, "krb5_cc_get_principal" );
        +	(FARPROC) p_krb5_cc_default =
        +		GetProcAddress( hKRB5_32, "krb5_cc_default" );
        +	(FARPROC) p_krb5_sname_to_principal =
        +		GetProcAddress( hKRB5_32, "krb5_sname_to_principal" );
        +	(FARPROC) p_krb5_init_context =
        +		GetProcAddress( hKRB5_32, "krb5_init_context" );
        +	(FARPROC) p_krb5_free_ticket =
        +		GetProcAddress( hKRB5_32, "krb5_free_ticket" );
        +	(FARPROC) p_krb5_rd_req =
        +		GetProcAddress( hKRB5_32, "krb5_rd_req" );
        +	(FARPROC) p_krb5_principal_compare =
        +		GetProcAddress( hKRB5_32, "krb5_principal_compare" );
        +	(FARPROC) p_krb5_decrypt_tkt_part =
        +		GetProcAddress( hKRB5_32, "krb5_decrypt_tkt_part" );
        +	(FARPROC) p_krb5_timeofday =
        +		GetProcAddress( hKRB5_32, "krb5_timeofday" );
        +	(FARPROC) p_krb5_rc_default =
        +		GetProcAddress( hKRB5_32, "krb5_rc_default" );
        +	(FARPROC) p_krb5_rc_initialize =
        +		GetProcAddress( hKRB5_32, "krb5_rc_initialize" );
        +	(FARPROC) p_krb5_rc_get_lifespan =
        +		GetProcAddress( hKRB5_32, "krb5_rc_get_lifespan" );
        +	(FARPROC) p_krb5_rc_destroy =
        +		GetProcAddress( hKRB5_32, "krb5_rc_destroy" );
        +	(FARPROC) p_krb5_kt_default =
        +		GetProcAddress( hKRB5_32, "krb5_kt_default" );
        +	(FARPROC) p_krb5_kt_resolve =
        +		GetProcAddress( hKRB5_32, "krb5_kt_resolve" );
        +	(FARPROC) p_krb5_auth_con_init =
        +		GetProcAddress( hKRB5_32, "krb5_auth_con_init" );
        +        (FARPROC) p_valid_cksumtype =
        +                GetProcAddress( hKRB5_32, "valid_cksumtype" );
        +        (FARPROC) p_krb5_checksum_size =
        +                GetProcAddress( hKRB5_32, "krb5_checksum_size" );
        +        (FARPROC) p_krb5_kt_free_entry =
        +                GetProcAddress( hKRB5_32, "krb5_kt_free_entry" );
        +        (FARPROC) p_krb5_auth_con_setrcache =
        +                GetProcAddress( hKRB5_32, "krb5_auth_con_setrcache" );
        +        (FARPROC) p_krb5_get_server_rcache =
        +                GetProcAddress( hKRB5_32, "krb5_get_server_rcache" );
        +        (FARPROC) p_krb5_auth_con_getrcache =
        +                GetProcAddress( hKRB5_32, "krb5_auth_con_getrcache" );
        +        (FARPROC) p_krb5_kt_close =
        +                GetProcAddress( hKRB5_32, "krb5_kt_close" );
        +        (FARPROC) p_krb5_kt_get_entry =
        +                GetProcAddress( hKRB5_32, "krb5_kt_get_entry" );
        +	}
        +
        +/* Stubs for each function to be dynamicly loaded */
        +void
        +kssl_krb5_free_data_contents(krb5_context CO, krb5_data  * data)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_free_data_contents )
        +		p_krb5_free_data_contents(CO,data);
        +	}
        +
        +krb5_error_code
        +kssl_krb5_mk_req_extended (krb5_context CO,
        +                          krb5_auth_context  * pACO,
        +                          krb5_const krb5_flags F,
        +                          krb5_data  * pD1,
        +                          krb5_creds  * pC,
        +                          krb5_data  * pD2)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_mk_req_extended )
        +		return(p_krb5_mk_req_extended(CO,pACO,F,pD1,pC,pD2));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +krb5_error_code
        +kssl_krb5_auth_con_init(krb5_context CO,
        +                       krb5_auth_context  * pACO)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_auth_con_init )
        +		return(p_krb5_auth_con_init(CO,pACO));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +krb5_error_code
        +kssl_krb5_auth_con_free (krb5_context CO,
        +                        krb5_auth_context ACO)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_auth_con_free )
        +		return(p_krb5_auth_con_free(CO,ACO));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +krb5_error_code
        +kssl_krb5_get_credentials(krb5_context CO,
        +                         krb5_const krb5_flags F,
        +                         krb5_ccache CC,
        +                         krb5_creds  * pCR,
        +                         krb5_creds  ** ppCR)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_get_credentials )
        +		return(p_krb5_get_credentials(CO,F,CC,pCR,ppCR));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +krb5_error_code
        +kssl_krb5_sname_to_principal(krb5_context CO,
        +                            krb5_const char  * pC1,
        +                            krb5_const char  * pC2,
        +                            krb5_int32 I,
        +                            krb5_principal  * pPR)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_sname_to_principal )
        +		return(p_krb5_sname_to_principal(CO,pC1,pC2,I,pPR));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +kssl_krb5_cc_default(krb5_context CO,
        +                    krb5_ccache  * pCC)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_cc_default )
        +		return(p_krb5_cc_default(CO,pCC));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +kssl_krb5_init_context(krb5_context * pCO)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_init_context )
        +		return(p_krb5_init_context(pCO));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +void
        +kssl_krb5_free_context(krb5_context CO)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_free_context )
        +		p_krb5_free_context(CO);
        +	}
        +
        +void
        +kssl_krb5_free_principal(krb5_context c, krb5_principal p)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_free_principal )
        +		p_krb5_free_principal(c,p);
        +	}
        +
        +krb5_error_code
        +kssl_krb5_kt_resolve(krb5_context con,
        +                    krb5_const char * sz,
        +                    krb5_keytab * kt)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_kt_resolve )
        +		return(p_krb5_kt_resolve(con,sz,kt));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +kssl_krb5_kt_default(krb5_context con,
        +                    krb5_keytab * kt)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_kt_default )
        +		return(p_krb5_kt_default(con,kt));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +kssl_krb5_free_ticket(krb5_context con,
        +                     krb5_ticket * kt)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_free_ticket )
        +		return(p_krb5_free_ticket(con,kt));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +kssl_krb5_rd_req(krb5_context con, krb5_auth_context * pacon,
        +                krb5_const krb5_data * data,
        +                krb5_const_principal princ, krb5_keytab keytab,
        +                krb5_flags * flags, krb5_ticket ** pptkt)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_rd_req )
        +		return(p_krb5_rd_req(con,pacon,data,princ,keytab,flags,pptkt));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_boolean
        +krb5_principal_compare(krb5_context con, krb5_const_principal princ1,
        +                krb5_const_principal princ2)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_principal_compare )
        +		return(p_krb5_principal_compare(con,princ1,princ2));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys,
        +                krb5_ticket *ticket)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_decrypt_tkt_part )
        +		return(p_krb5_decrypt_tkt_part(con,keys,ticket));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +krb5_timeofday(krb5_context con, krb5_int32 *timeret)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_timeofday )
        +		return(p_krb5_timeofday(con,timeret));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +krb5_rc_default(krb5_context con, krb5_rcache *rc)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_rc_default )
        +		return(p_krb5_rc_default(con,rc));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_rc_initialize )
        +		return(p_krb5_rc_initialize(con, rc, lifespan));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_rc_get_lifespan )
        +		return(p_krb5_rc_get_lifespan(con, rc, lifespanp));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +krb5_rc_destroy(krb5_context con, krb5_rcache rc)
        +	{
        +	if (!krb5_loaded)
        +		load_krb5_dll();
        +
        +	if ( p_krb5_rc_destroy )
        +		return(p_krb5_rc_destroy(con, rc));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +size_t 
        +krb5_checksum_size(krb5_context context,krb5_cksumtype ctype)
        +        {
        +        if (!krb5_loaded)
        +                load_krb5_dll();
        +
        +        if ( p_krb5_checksum_size )
        +                return(p_krb5_checksum_size(context, ctype));
        +        else
        +                return KRB5KRB_ERR_GENERIC;
        +        }
        +
        +krb5_boolean 
        +valid_cksumtype(krb5_cksumtype ctype)
        +        {
        +        if (!krb5_loaded)
        +                load_krb5_dll();
        +
        +        if ( p_valid_cksumtype )
        +                return(p_valid_cksumtype(ctype));
        +        else
        +                return KRB5KRB_ERR_GENERIC;
        +        }
        +
        +krb5_error_code 
        +krb5_kt_free_entry(krb5_context con,krb5_keytab_entry * entry)
        +        {
        +        if (!krb5_loaded)
        +                load_krb5_dll();
        +
        +        if ( p_krb5_kt_free_entry )
        +                return(p_krb5_kt_free_entry(con,entry));
        +        else
        +                return KRB5KRB_ERR_GENERIC;
        +        }
        +                 
        +/* Structure definitions  */
        +#ifndef NO_DEF_KRB5_CCACHE
        +#ifndef krb5_x
        +#define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1))
        +#define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0))
        +#endif 
        +
        +typedef	krb5_pointer	krb5_cc_cursor;	/* cursor for sequential lookup */
        +
        +typedef struct _krb5_ccache
        +	{
        +	krb5_magic magic;
        +	struct _krb5_cc_ops FAR *ops;
        +	krb5_pointer data;
        +	} *krb5_ccache;
        +
        +typedef struct _krb5_cc_ops
        +	{
        +	krb5_magic magic;
        +	char  *prefix;
        +	char  * (KRB5_CALLCONV *get_name)
        +		(krb5_context, krb5_ccache);
        +	krb5_error_code (KRB5_CALLCONV *resolve)
        +		(krb5_context, krb5_ccache  *, const char  *);
        +	krb5_error_code (KRB5_CALLCONV *gen_new)
        +		(krb5_context, krb5_ccache  *);
        +	krb5_error_code (KRB5_CALLCONV *init)
        +		(krb5_context, krb5_ccache, krb5_principal);
        +	krb5_error_code (KRB5_CALLCONV *destroy)
        +		(krb5_context, krb5_ccache);
        +	krb5_error_code (KRB5_CALLCONV *close)
        +		(krb5_context, krb5_ccache);
        +	krb5_error_code (KRB5_CALLCONV *store)
        +		(krb5_context, krb5_ccache, krb5_creds  *);
        +	krb5_error_code (KRB5_CALLCONV *retrieve)
        +		(krb5_context, krb5_ccache,
        +		krb5_flags, krb5_creds  *, krb5_creds  *);
        +	krb5_error_code (KRB5_CALLCONV *get_princ)
        +		(krb5_context, krb5_ccache, krb5_principal  *);
        +	krb5_error_code (KRB5_CALLCONV *get_first)
        +		(krb5_context, krb5_ccache, krb5_cc_cursor  *);
        +	krb5_error_code (KRB5_CALLCONV *get_next)
        +		(krb5_context, krb5_ccache,
        +		krb5_cc_cursor  *, krb5_creds  *);
        +	krb5_error_code (KRB5_CALLCONV *end_get)
        +		(krb5_context, krb5_ccache, krb5_cc_cursor  *);
        +	krb5_error_code (KRB5_CALLCONV *remove_cred)
        +		(krb5_context, krb5_ccache,
        +		krb5_flags, krb5_creds  *);
        +	krb5_error_code (KRB5_CALLCONV *set_flags)
        +		(krb5_context, krb5_ccache, krb5_flags);
        +	} krb5_cc_ops;
        +#endif /* NO_DEF_KRB5_CCACHE */
        +
        +krb5_error_code 
        +kssl_krb5_cc_get_principal
        +    (krb5_context context, krb5_ccache cache,
        +      krb5_principal *principal)
        +	{
        +	if ( p_krb5_cc_get_principal )
        +		return(p_krb5_cc_get_principal(context,cache,principal));
        +	else
        +		return(krb5_x
        +			((cache)->ops->get_princ,(context, cache, principal)));
        +	}
        +
        +krb5_error_code
        +kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon,
        +                             krb5_rcache rcache)
        +        {
        +        if ( p_krb5_auth_con_setrcache )
        +                 return(p_krb5_auth_con_setrcache(con,acon,rcache));
        +        else
        +                 return KRB5KRB_ERR_GENERIC;
        +        }
        +
        +krb5_error_code
        +kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data * data,
        +                            krb5_rcache * rcache) 
        +        {
        +	if ( p_krb5_get_server_rcache )
        +		return(p_krb5_get_server_rcache(con,data,rcache));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +        }
        +
        +krb5_error_code
        +kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon,
        +                             krb5_rcache * prcache)
        +        {
        +	if ( p_krb5_auth_con_getrcache )
        +		return(p_krb5_auth_con_getrcache(con,acon, prcache));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        + 
        +krb5_error_code
        +kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab)
        +	{
        +	if ( p_krb5_kt_close )
        +		return(p_krb5_kt_close(context,keytab));
        +	else 
        +		return KRB5KRB_ERR_GENERIC;
        +	}
        +
        +krb5_error_code
        +kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
        +                       krb5_const_principal principal, krb5_kvno vno,
        +                       krb5_enctype enctype, krb5_keytab_entry *entry)
        +	{
        +	if ( p_krb5_kt_get_entry )
        +		return(p_krb5_kt_get_entry(context,keytab,principal,vno,enctype,entry));
        +	else
        +		return KRB5KRB_ERR_GENERIC;
        +        }
        +#endif  /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */
        +
        +
        +/* memory allocation functions for non-temporary storage
        + * (e.g. stuff that gets saved into the kssl context) */
        +static void* kssl_calloc(size_t nmemb, size_t size)
        +{
        +	void* p;
        +	
        +	p=OPENSSL_malloc(nmemb*size);
        +	if (p){
        +		memset(p, 0, nmemb*size);
        +	}
        +	return p;
        +}
        +
        +#define kssl_malloc(size) OPENSSL_malloc((size))
        +#define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size)
        +#define kssl_free(ptr) OPENSSL_free((ptr))
        +
        +
        +char
        +*kstring(char *string)
        +        {
        +        static char	*null = "[NULL]";
        +
        +	return ((string == NULL)? null: string);
        +        }
        +
        +/*	Given KRB5 enctype (basically DES or 3DES),
        +**	return closest match openssl EVP_ encryption algorithm.
        +**	Return NULL for unknown or problematic (krb5_dk_encrypt) enctypes.
        +**	Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are OK.
        +*/
        +const EVP_CIPHER *
        +kssl_map_enc(krb5_enctype enctype)
        +        {
        +	switch (enctype)
        +		{
        +	case ENCTYPE_DES_HMAC_SHA1:		/*    EVP_des_cbc();       */
        +	case ENCTYPE_DES_CBC_CRC:
        +	case ENCTYPE_DES_CBC_MD4:
        +	case ENCTYPE_DES_CBC_MD5:
        +	case ENCTYPE_DES_CBC_RAW:
        +				return EVP_des_cbc();
        +				break;
        +	case ENCTYPE_DES3_CBC_SHA1:		/*    EVP_des_ede3_cbc();  */
        +	case ENCTYPE_DES3_CBC_SHA:
        +	case ENCTYPE_DES3_CBC_RAW:
        +				return EVP_des_ede3_cbc();
        +				break;
        +	default:                return NULL;
        +				break;
        +		}
        +	}
        +
        +
        +/*	Return true:1 if p "looks like" the start of the real authenticator
        +**	described in kssl_skip_confound() below.  The ASN.1 pattern is
        +**	"62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and
        +**	xx and yy are possibly multi-byte length fields.
        +*/
        +static int 	kssl_test_confound(unsigned char *p)
        +	{
        +	int 	len = 2;
        +	int 	xx = 0, yy = 0;
        +
        +	if (*p++ != 0x62)  return 0;
        +	if (*p > 0x82)  return 0;
        +	switch(*p)  {
        +		case 0x82:  p++;          xx = (*p++ << 8);  xx += *p++;  break;
        +		case 0x81:  p++;          xx =  *p++;  break;
        +		case 0x80:  return 0;
        +		default:    xx = *p++;  break;
        +		}
        +	if (*p++ != 0x30)  return 0;
        +	if (*p > 0x82)  return 0;
        +	switch(*p)  {
        +		case 0x82:  p++; len+=2;  yy = (*p++ << 8);  yy += *p++;  break;
        +		case 0x81:  p++; len++;   yy =  *p++;  break;
        +		case 0x80:  return 0;
        +		default:    yy = *p++;  break;
        +		}
        +
        +	return (xx - len == yy)? 1: 0;
        +	}
        +
        +/*	Allocate, fill, and return cksumlens array of checksum lengths.
        +**	This array holds just the unique elements from the krb5_cksumarray[].
        +**	array[n] == 0 signals end of data.
        +**
        +**      The krb5_cksumarray[] was an internal variable that has since been
        +**      replaced by a more general method for storing the data.  It should
        +**      not be used.  Instead we use real API calls and make a guess for 
        +**      what the highest assigned CKSUMTYPE_ constant is.  As of 1.2.2
        +**      it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3).  So we will use 0x0010.
        +*/
        +static size_t  *populate_cksumlens(void)
        +	{
        +	int 		i, j, n;
        +	static size_t 	*cklens = NULL;
        +
        +#ifdef KRB5_MIT_OLD11
        +	n = krb5_max_cksum;
        +#else
        +	n = 0x0010;
        +#endif	/* KRB5_MIT_OLD11 */
        + 
        +#ifdef KRB5CHECKAUTH
        +	if (!cklens && !(cklens = (size_t *) calloc(sizeof(int),n+1)))  return NULL;
        +
        +	for (i=0; i < n; i++)  {
        +		if (!valid_cksumtype(i))  continue;	/*  array has holes  */
        +		for (j=0; j < n; j++)  {
        +			if (cklens[j] == 0)  {
        +				cklens[j] = krb5_checksum_size(NULL,i);
        +				break;		/*  krb5 elem was new: add   */
        +				}
        +			if (cklens[j] == krb5_checksum_size(NULL,i))  {
        +				break;		/*  ignore duplicate elements */
        +				}
        +			}
        +		}
        +#endif	/* KRB5CHECKAUTH */
        +
        +	return cklens;
        +	}
        +
        +/*	Return pointer to start of real authenticator within authenticator, or
        +**	return NULL on error.
        +**	Decrypted authenticator looks like this:
        +**		[0 or 8 byte confounder] [4-24 byte checksum] [real authent'r]
        +**	This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the
        +**	krb5_auth_con_getcksumtype() function advertised in its krb5.h.
        +*/
        +unsigned char	*kssl_skip_confound(krb5_enctype etype, unsigned char *a)
        +	{
        +	int 		i, conlen;
        +	size_t		cklen;
        +	static size_t 	*cksumlens = NULL;
        +	unsigned char	*test_auth;
        +
        +	conlen = (etype)? 8: 0;
        +
        +	if (!cksumlens  &&  !(cksumlens = populate_cksumlens()))  return NULL;
        +	for (i=0; (cklen = cksumlens[i]) != 0; i++)
        +		{
        +		test_auth = a + conlen + cklen;
        +		if (kssl_test_confound(test_auth))  return test_auth;
        +		}
        +
        +	return NULL;
        +	}
        +
        +
        +/*	Set kssl_err error info when reason text is a simple string
        +**		kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; }
        +*/
        +void
        +kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
        +        {
        +	if (kssl_err == NULL)  return;
        +
        +	kssl_err->reason = reason;
        +	BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text);
        +	return;
        +        }
        +
        +
        +/*	Display contents of krb5_data struct, for debugging
        +*/
        +void
        +print_krb5_data(char *label, krb5_data *kdata)
        +        {
        +	int i;
        +
        +	printf("%s[%d] ", label, kdata->length);
        +	for (i=0; i < (int)kdata->length; i++)
        +                {
        +		if (0 &&  isprint((int) kdata->data[i]))
        +                        printf(	"%c ",  kdata->data[i]);
        +		else
        +                        printf(	"%02x ", (unsigned char) kdata->data[i]);
        +		}
        +	printf("\n");
        +        }
        +
        +
        +/*	Display contents of krb5_authdata struct, for debugging
        +*/
        +void
        +print_krb5_authdata(char *label, krb5_authdata **adata)
        +        {
        +	if (adata == NULL)
        +                {
        +		printf("%s, authdata==0\n", label);
        +		return;
        +		}
        +	printf("%s [%p]\n", label, (void *)adata);
        +#if 0
        +	{
        +        int 	i;
        +	printf("%s[at%d:%d] ", label, adata->ad_type, adata->length);
        +	for (i=0; i < adata->length; i++)
        +                {
        +                printf((isprint(adata->contents[i]))? "%c ": "%02x",
        +                        adata->contents[i]);
        +		}
        +	printf("\n");
        +	}
        +#endif
        +	}
        +
        +
        +/*	Display contents of krb5_keyblock struct, for debugging
        +*/
        +void
        +print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
        +        {
        +	int i;
        +
        +	if (keyblk == NULL)
        +                {
        +		printf("%s, keyblk==0\n", label);
        +		return;
        +		}
        +#ifdef KRB5_HEIMDAL
        +	printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype,
        +					   keyblk->keyvalue->length);
        +	for (i=0; i < (int)keyblk->keyvalue->length; i++)
        +                {
        +		printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
        +		}
        +	printf("\n");
        +#else
        +	printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
        +	for (i=0; i < (int)keyblk->length; i++)
        +                {
        +		printf("%02x",keyblk->contents[i]);
        +		}
        +	printf("\n");
        +#endif
        +        }
        +
        +
        +/*	Display contents of krb5_principal_data struct, for debugging
        +**	(krb5_principal is typedef'd == krb5_principal_data *)
        +*/
        +static void
        +print_krb5_princ(char *label, krb5_principal_data *princ)
        +        {
        +	int i, ui, uj;
        +
        +	printf("%s principal Realm: ", label);
        +	if (princ == NULL)  return;
        +	for (ui=0; ui < (int)princ->realm.length; ui++)  putchar(princ->realm.data[ui]);
        +	printf(" (nametype %d) has %d strings:\n", princ->type,princ->length);
        +	for (i=0; i < (int)princ->length; i++)
        +                {
        +		printf("\t%d [%d]: ", i, princ->data[i].length);
        +		for (uj=0; uj < (int)princ->data[i].length; uj++)  {
        +			putchar(princ->data[i].data[uj]);
        +			}
        +		printf("\n");
        +		}
        +	return;
        +        }
        +
        +
        +/*	Given krb5 service (typically "kssl") and hostname in kssl_ctx,
        +**	Return encrypted Kerberos ticket for service @ hostname.
        +**	If authenp is non-NULL, also return encrypted authenticator,
        +**	whose data should be freed by caller.
        +**	(Originally was: Create Kerberos AP_REQ message for SSL Client.)
        +**
        +**	19990628	VRS 	Started; Returns Kerberos AP_REQ message.
        +**	20010409	VRS 	Modified for RFC2712; Returns enc tkt.
        +**	20010606	VRS 	May also return optional authenticator.
        +*/
        +krb5_error_code
        +kssl_cget_tkt(	/* UPDATE */	KSSL_CTX *kssl_ctx,
        +                /* OUT    */	krb5_data **enc_ticketp,
        +                /* UPDATE */	krb5_data *authenp,
        +                /* OUT    */	KSSL_ERR *kssl_err)
        +	{
        +	krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
        +	krb5_context		krb5context = NULL;
        +	krb5_auth_context	krb5auth_context = NULL;
        +	krb5_ccache 		krb5ccdef = NULL;
        +	krb5_creds		krb5creds, *krb5credsp = NULL;
        +	krb5_data		krb5_app_req;
        +
        +	kssl_err_set(kssl_err, 0, "");
        +	memset((char *)&krb5creds, 0, sizeof(krb5creds));
        +
        +	if (!kssl_ctx)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "No kssl_ctx defined.\n");
        +		goto err;
        +		}
        +	else if (!kssl_ctx->service_host)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "kssl_ctx service_host undefined.\n");
        +		goto err;
        +		}
        +
        +	if ((krb5rc = krb5_init_context(&krb5context)) != 0)
        +                {
        +		BIO_snprintf(kssl_err->text,KSSL_ERR_MAX,
        +                        "krb5_init_context() fails: %d\n", krb5rc);
        +		kssl_err->reason = SSL_R_KRB5_C_INIT;
        +		goto err;
        +		}
        +
        +	if ((krb5rc = krb5_sname_to_principal(krb5context,
        +                kssl_ctx->service_host,
        +                (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
        +                KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
        +                {
        +		BIO_snprintf(kssl_err->text,KSSL_ERR_MAX,
        +                        "krb5_sname_to_principal() fails for %s/%s\n",
        +                        kssl_ctx->service_host,
        +                        (kssl_ctx->service_name)? kssl_ctx->service_name:
        +						  KRB5SVC);
        +		kssl_err->reason = SSL_R_KRB5_C_INIT;
        +		goto err;
        +		}
        +
        +	if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
        +                        "krb5_cc_default fails.\n");
        +		goto err;
        +		}
        +
        +	if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
        +                &krb5creds.client)) != 0)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
        +                        "krb5_cc_get_principal() fails.\n");
        +		goto err;
        +		}
        +
        +	if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
        +                &krb5creds, &krb5credsp)) != 0)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED,
        +                        "krb5_get_credentials() fails.\n");
        +		goto err;
        +		}
        +
        +	*enc_ticketp = &krb5credsp->ticket;
        +#ifdef KRB5_HEIMDAL
        +	kssl_ctx->enctype = krb5credsp->session.keytype;
        +#else
        +	kssl_ctx->enctype = krb5credsp->keyblock.enctype;
        +#endif
        +
        +	krb5rc = KRB5KRB_ERR_GENERIC;
        +	/*	caller should free data of krb5_app_req  */
        +	/*  20010406 VRS deleted for real KerberosWrapper
        +	**  20010605 VRS reinstated to offer Authenticator to KerberosWrapper
        +	*/
        +	krb5_app_req.length = 0;
        +	if (authenp)
        +                {
        +		krb5_data	krb5in_data;
        +		const unsigned char	*p;
        +		long		arlen;
        +		KRB5_APREQBODY	*ap_req;
        +
        +		authenp->length = 0;
        +		krb5in_data.data = NULL;
        +		krb5in_data.length = 0;
        +		if ((krb5rc = krb5_mk_req_extended(krb5context,
        +			&krb5auth_context, 0, &krb5in_data, krb5credsp,
        +			&krb5_app_req)) != 0)
        +			{
        +			kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ,
        +				"krb5_mk_req_extended() fails.\n");
        +			goto err;
        +			}
        +
        +		arlen = krb5_app_req.length;
        +		p = (unsigned char *)krb5_app_req.data;
        +		ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen);
        +		if (ap_req)
        +			{
        +			authenp->length = i2d_KRB5_ENCDATA(
        +					ap_req->authenticator, NULL);
        +			if (authenp->length  && 
        +				(authenp->data = malloc(authenp->length)))
        +				{
        +				unsigned char	*adp = (unsigned char *)authenp->data;
        +				authenp->length = i2d_KRB5_ENCDATA(
        +						ap_req->authenticator, &adp);
        +				}
        +			}
        +
        +		if (ap_req)  KRB5_APREQ_free((KRB5_APREQ *) ap_req);
        +		if (krb5_app_req.length)  
        +                        kssl_krb5_free_data_contents(krb5context,&krb5_app_req);
        +		}
        +#ifdef KRB5_HEIMDAL
        +	if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
        +                        "kssl_ctx_setkey() fails.\n");
        +		}
        +#else
        +	if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
        +                        "kssl_ctx_setkey() fails.\n");
        +		}
        +#endif
        +	else	krb5rc = 0;
        +
        + err:
        +#ifdef KSSL_DEBUG
        +	kssl_ctx_show(kssl_ctx);
        +#endif	/* KSSL_DEBUG */
        +
        +	if (krb5creds.client)	krb5_free_principal(krb5context,
        +							krb5creds.client);
        +	if (krb5creds.server)	krb5_free_principal(krb5context,
        +							krb5creds.server);
        +	if (krb5auth_context)	krb5_auth_con_free(krb5context,
        +							krb5auth_context);
        +	if (krb5context)	krb5_free_context(krb5context);
        +	return (krb5rc);
        +	}
        +
        +
        +/*  Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket.
        +**  Return Kerberos error code and kssl_err struct on error.
        +**  Allocates krb5_ticket and krb5_principal; caller should free these.
        +**
        +**	20010410	VRS	Implemented krb5_decode_ticket() as
        +**				old_krb5_decode_ticket(). Missing from MIT1.0.6.
        +**	20010615	VRS 	Re-cast as openssl/asn1 d2i_*() functions.
        +**				Re-used some of the old krb5_decode_ticket()
        +**				code here.  This tkt should alloc/free just
        +**				like the real thing.
        +*/
        +static krb5_error_code
        +kssl_TKT2tkt(	/* IN     */	krb5_context	krb5context,
        +		/* IN     */	KRB5_TKTBODY	*asn1ticket,
        +		/* OUT    */	krb5_ticket	**krb5ticket,
        +		/* OUT    */	KSSL_ERR *kssl_err  )
        +        {
        +        krb5_error_code			krb5rc = KRB5KRB_ERR_GENERIC;
        +	krb5_ticket 			*new5ticket = NULL;
        +	ASN1_GENERALSTRING		*gstr_svc, *gstr_host;
        +
        +	*krb5ticket = NULL;
        +
        +	if (asn1ticket == NULL  ||  asn1ticket->realm == NULL  ||
        +		asn1ticket->sname == NULL  || 
        +		sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2)
        +		{
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"Null field in asn1ticket.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		return KRB5KRB_ERR_GENERIC;
        +		}
        +
        +	if ((new5ticket = (krb5_ticket *) calloc(1, sizeof(krb5_ticket)))==NULL)
        +		{
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"Unable to allocate new krb5_ticket.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		return ENOMEM;		/*  or  KRB5KRB_ERR_GENERIC;	*/
        +		}
        +
        +	gstr_svc  = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0);
        +	gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1);
        +
        +	if ((krb5rc = kssl_build_principal_2(krb5context,
        +			&new5ticket->server,
        +			asn1ticket->realm->length, (char *)asn1ticket->realm->data,
        +			gstr_svc->length,  (char *)gstr_svc->data,
        +			gstr_host->length, (char *)gstr_host->data)) != 0)
        +		{
        +		free(new5ticket);
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"Error building ticket server principal.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		return krb5rc;		/*  or  KRB5KRB_ERR_GENERIC;	*/
        +		}
        +
        +	krb5_princ_type(krb5context, new5ticket->server) =
        +			asn1ticket->sname->nametype->data[0];
        +	new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0];
        +	new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0];
        +	new5ticket->enc_part.ciphertext.length =
        +			asn1ticket->encdata->cipher->length;
        +	if ((new5ticket->enc_part.ciphertext.data =
        +		calloc(1, asn1ticket->encdata->cipher->length)) == NULL)
        +		{
        +		free(new5ticket);
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"Error allocating cipher in krb5ticket.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		return KRB5KRB_ERR_GENERIC;
        +		}
        +	else
        +		{
        +		memcpy(new5ticket->enc_part.ciphertext.data,
        +			asn1ticket->encdata->cipher->data,
        +			asn1ticket->encdata->cipher->length);
        +		}
        +
        +	*krb5ticket = new5ticket;
        +	return 0;
        +	}
        +
        +
        +/*	Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"),
        +**		and krb5 AP_REQ message & message length,
        +**	Return Kerberos session key and client principle
        +**		to SSL Server in KSSL_CTX *kssl_ctx.
        +**
        +**	19990702	VRS 	Started.
        +*/
        +krb5_error_code
        +kssl_sget_tkt(	/* UPDATE */	KSSL_CTX		*kssl_ctx,
        +		/* IN     */	krb5_data		*indata,
        +		/* OUT    */	krb5_ticket_times	*ttimes,
        +		/* OUT    */	KSSL_ERR		*kssl_err  )
        +        {
        +        krb5_error_code			krb5rc = KRB5KRB_ERR_GENERIC;
        +        static krb5_context		krb5context = NULL;
        +	static krb5_auth_context	krb5auth_context = NULL;
        +	krb5_ticket 			*krb5ticket = NULL;
        +	KRB5_TKTBODY 			*asn1ticket = NULL;
        +	const unsigned char		*p;
        +	krb5_keytab 			krb5keytab = NULL;
        +	krb5_keytab_entry		kt_entry;
        +	krb5_principal			krb5server;
        +        krb5_rcache                     rcache = NULL;
        +
        +	kssl_err_set(kssl_err, 0, "");
        +
        +	if (!kssl_ctx)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +			"No kssl_ctx defined.\n");
        +		goto err;
        +		}
        +
        +#ifdef KSSL_DEBUG
        +	printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
        +#endif	/* KSSL_DEBUG */
        +
        +	if (!krb5context  &&  (krb5rc = krb5_init_context(&krb5context)))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "krb5_init_context() fails.\n");
        +		goto err;
        +		}
        +	if (krb5auth_context  &&
        +		(krb5rc = krb5_auth_con_free(krb5context, krb5auth_context)))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "krb5_auth_con_free() fails.\n");
        +		goto err;
        +		}
        +	else  krb5auth_context = NULL;
        +	if (!krb5auth_context  &&
        +		(krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context)))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "krb5_auth_con_init() fails.\n");
        +		goto err;
        +		}
        +
        + 
        +	if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context,
        +		&rcache)))
        +		{
        + 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +			"krb5_auth_con_getrcache() fails.\n");
        + 		goto err;
        +		}
        + 
        +	if ((krb5rc = krb5_sname_to_principal(krb5context, NULL,
        +                (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
        +                KRB5_NT_SRV_HST, &krb5server)) != 0)
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "krb5_sname_to_principal() fails.\n");
        +		goto err;
        +		}
        +
        +	if (rcache == NULL) 
        +                {
        +                if ((krb5rc = krb5_get_server_rcache(krb5context,
        +			krb5_princ_component(krb5context, krb5server, 0),
        +			&rcache)))
        +                        {
        +		        kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                                "krb5_get_server_rcache() fails.\n");
        +                  	goto err;
        +                        }
        +                }
        +
        +        if ((krb5rc = krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache)))
        +                {
        +                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +			"krb5_auth_con_setrcache() fails.\n");
        +                goto err;
        +                }
        +
        +
        +	/*	kssl_ctx->keytab_file == NULL ==> use Kerberos default
        +	*/
        +	if (kssl_ctx->keytab_file)
        +		{
        +		krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
        +                        &krb5keytab);
        +		if (krb5rc)
        +			{
        +			kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +				"krb5_kt_resolve() fails.\n");
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +                krb5rc = krb5_kt_default(krb5context,&krb5keytab);
        +                if (krb5rc)
        +			{
        +			kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 
        +				"krb5_kt_default() fails.\n");
        +			goto err;
        +			}
        +		}
        +
        +	/*	Actual Kerberos5 krb5_recvauth() has initial conversation here
        +	**	o	check KRB5_SENDAUTH_BADAUTHVERS
        +	**		unless KRB5_RECVAUTH_SKIP_VERSION
        +	**	o	check KRB5_SENDAUTH_BADAPPLVERS
        +	**	o	send "0" msg if all OK
        +	*/
        +
        +	/*  20010411 was using AP_REQ instead of true KerberosWrapper
        +	**
        +	**  if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context,
        +	**			&krb5in_data, krb5server, krb5keytab,
        +	**			&ap_option, &krb5ticket)) != 0)  { Error }
        +	*/
        +
        +	p = (unsigned char *)indata->data;
        +	if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p,
        +						(long) indata->length)) == NULL)
        +		{
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"d2i_KRB5_TICKET() ASN.1 decode failure.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		goto err;
        +		}
        +	
        +	/* Was:  krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) */
        +	if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket,
        +					kssl_err)) != 0)
        +		{
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"Error converting ASN.1 ticket to krb5_ticket.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		goto err;
        +		}
        +
        +	if (! krb5_principal_compare(krb5context, krb5server,
        +						  krb5ticket->server))  {
        +		krb5rc = KRB5_PRINC_NOMATCH;
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"server principal != ticket principal\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		goto err;
        +		}
        +	if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab,
        +			krb5ticket->server, krb5ticket->enc_part.kvno,
        +			krb5ticket->enc_part.enctype, &kt_entry)) != 0)  {
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"krb5_kt_get_entry() fails with %x.\n", krb5rc);
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		goto err;
        +		}
        +	if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key,
        +			krb5ticket)) != 0)  {
        +		BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
        +			"krb5_decrypt_tkt_part() failed.\n");
        +		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
        +		goto err;
        +		}
        +	else  {
        +		krb5_kt_free_entry(krb5context, &kt_entry);
        +#ifdef KSSL_DEBUG
        +		{
        +		int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs;
        +		printf("Decrypted ticket fields:\n");
        +		printf("\tflags: %X, transit-type: %X",
        +			krb5ticket->enc_part2->flags,
        +			krb5ticket->enc_part2->transited.tr_type);
        +		print_krb5_data("\ttransit-data: ",
        +			&(krb5ticket->enc_part2->transited.tr_contents));
        +		printf("\tcaddrs: %p, authdata: %p\n",
        +			krb5ticket->enc_part2->caddrs,
        +			krb5ticket->enc_part2->authorization_data);
        +		if (paddr)
        +			{
        +			printf("\tcaddrs:\n");
        +			for (i=0; paddr[i] != NULL; i++)
        +				{
        +				krb5_data d;
        +				d.length=paddr[i]->length;
        +				d.data=paddr[i]->contents;
        +				print_krb5_data("\t\tIP: ", &d);
        +				}
        +			}
        +		printf("\tstart/auth/end times: %d / %d / %d\n",
        +			krb5ticket->enc_part2->times.starttime,
        +			krb5ticket->enc_part2->times.authtime,
        +			krb5ticket->enc_part2->times.endtime);
        +		}
        +#endif	/* KSSL_DEBUG */
        +		}
        +
        +	krb5rc = KRB5_NO_TKT_SUPPLIED;
        +	if (!krb5ticket  ||	!krb5ticket->enc_part2  ||
        +                !krb5ticket->enc_part2->client  ||
        +                !krb5ticket->enc_part2->client->data  ||
        +                !krb5ticket->enc_part2->session)
        +                {
        +                kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
        +                        "bad ticket from krb5_rd_req.\n");
        +		}
        +	else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT,
        +		 &krb5ticket->enc_part2->client->realm,
        +		 krb5ticket->enc_part2->client->data,
        +		 krb5ticket->enc_part2->client->length))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
        +                        "kssl_ctx_setprinc() fails.\n");
        +		}
        +	else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session))
        +                {
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
        +                        "kssl_ctx_setkey() fails.\n");
        +		}
        +	else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID)
        +                {
        +		krb5rc = KRB5KRB_AP_ERR_TKT_INVALID;
        +                kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
        +                        "invalid ticket from krb5_rd_req.\n");
        +		}
        +	else	krb5rc = 0;
        +
        +	kssl_ctx->enctype	= krb5ticket->enc_part.enctype;
        +	ttimes->authtime	= krb5ticket->enc_part2->times.authtime;
        +	ttimes->starttime	= krb5ticket->enc_part2->times.starttime;
        +	ttimes->endtime 	= krb5ticket->enc_part2->times.endtime;
        +	ttimes->renew_till	= krb5ticket->enc_part2->times.renew_till;
        +
        + err:
        +#ifdef KSSL_DEBUG
        +	kssl_ctx_show(kssl_ctx);
        +#endif	/* KSSL_DEBUG */
        +
        +	if (asn1ticket) 	KRB5_TICKET_free((KRB5_TICKET *) asn1ticket);
        +        if (krb5keytab)         krb5_kt_close(krb5context, krb5keytab);
        +	if (krb5ticket) 	krb5_free_ticket(krb5context, krb5ticket);
        +	if (krb5server) 	krb5_free_principal(krb5context, krb5server);
        +	return (krb5rc);
        +        }
        +
        +
        +/*	Allocate & return a new kssl_ctx struct.
        +*/
        +KSSL_CTX	*
        +kssl_ctx_new(void)
        +        {
        +	return ((KSSL_CTX *) kssl_calloc(1, sizeof(KSSL_CTX)));
        +        }
        +
        +
        +/*	Frees a kssl_ctx struct and any allocated memory it holds.
        +**	Returns NULL.
        +*/
        +KSSL_CTX	*
        +kssl_ctx_free(KSSL_CTX *kssl_ctx)
        +        {
        +	if (kssl_ctx == NULL)  return kssl_ctx;
        +
        +	if (kssl_ctx->key)  		OPENSSL_cleanse(kssl_ctx->key,
        +							      kssl_ctx->length);
        +	if (kssl_ctx->key)  		kssl_free(kssl_ctx->key);
        +	if (kssl_ctx->client_princ) 	kssl_free(kssl_ctx->client_princ);
        +	if (kssl_ctx->service_host) 	kssl_free(kssl_ctx->service_host);
        +	if (kssl_ctx->service_name) 	kssl_free(kssl_ctx->service_name);
        +	if (kssl_ctx->keytab_file) 	kssl_free(kssl_ctx->keytab_file);
        +
        +	kssl_free(kssl_ctx);
        +	return (KSSL_CTX *) NULL;
        +        }
        +
        +
        +/*	Given an array of (krb5_data *) entity (and optional realm),
        +**	set the plain (char *) client_princ or service_host member
        +**	of the kssl_ctx struct.
        +*/
        +krb5_error_code
        +kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
        +        krb5_data *realm, krb5_data *entity, int nentities)
        +        {
        +	char	**princ;
        +	int 	length;
        +	int i;
        +
        +	if (kssl_ctx == NULL  ||  entity == NULL)  return KSSL_CTX_ERR;
        +
        +	switch (which)
        +                {
        +        case KSSL_CLIENT:	princ = &kssl_ctx->client_princ;	break;
        +        case KSSL_SERVER:	princ = &kssl_ctx->service_host;	break;
        +        default:		return KSSL_CTX_ERR;			break;
        +		}
        +	if (*princ)  kssl_free(*princ);
        +
        +	/* Add up all the entity->lengths */
        +	length = 0;
        +	for (i=0; i < nentities; i++)
        +		{
        +		length += entity[i].length;
        +		}
        +	/* Add in space for the '/' character(s) (if any) */
        +	length += nentities-1;
        +	/* Space for the ('@'+realm+NULL | NULL) */
        +	length += ((realm)? realm->length + 2: 1);
        +
        +	if ((*princ = kssl_calloc(1, length)) == NULL)
        +		return KSSL_CTX_ERR;
        +	else
        +		{
        +		for (i = 0; i < nentities; i++)
        +			{
        +			strncat(*princ, entity[i].data, entity[i].length);
        +			if (i < nentities-1)
        +				{
        +				strcat (*princ, "/");
        +				}
        +			}
        +		if (realm)
        +                        {
        +			strcat (*princ, "@");
        +			(void) strncat(*princ, realm->data, realm->length);
        +			}
        +		}
        +
        +	return KSSL_CTX_OK;
        +        }
        +
        +
        +/*	Set one of the plain (char *) string members of the kssl_ctx struct.
        +**	Default values should be:
        +**		which == KSSL_SERVICE	=>	"khost" (KRB5SVC)
        +**		which == KSSL_KEYTAB	=>	"/etc/krb5.keytab" (KRB5KEYTAB)
        +*/
        +krb5_error_code
        +kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
        +        {
        +	char	**string;
        +
        +	if (!kssl_ctx)  return KSSL_CTX_ERR;
        +
        +	switch (which)
        +                {
        +        case KSSL_SERVICE:	string = &kssl_ctx->service_name;	break;
        +        case KSSL_SERVER:	string = &kssl_ctx->service_host;	break;
        +        case KSSL_CLIENT:	string = &kssl_ctx->client_princ;	break;
        +        case KSSL_KEYTAB:	string = &kssl_ctx->keytab_file;	break;
        +        default:		return KSSL_CTX_ERR;			break;
        +		}
        +	if (*string)  kssl_free(*string);
        +
        +	if (!text)
        +                {
        +		*string = '\0';
        +		return KSSL_CTX_OK;
        +		}
        +
        +	if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL)
        +		return KSSL_CTX_ERR;
        +	else
        +		strcpy(*string, text);
        +
        +	return KSSL_CTX_OK;
        +        }
        +
        +
        +/*	Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx
        +**	struct.  Clear kssl_ctx->key if Kerberos session key is NULL.
        +*/
        +krb5_error_code
        +kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
        +        {
        +	int 		length;
        +	krb5_enctype	enctype;
        +	krb5_octet FAR	*contents = NULL;
        +
        +	if (!kssl_ctx)  return KSSL_CTX_ERR;
        +
        +	if (kssl_ctx->key)
        +                {
        +		OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length);
        +		kssl_free(kssl_ctx->key);
        +		}
        +
        +	if (session)
        +                {
        +
        +#ifdef KRB5_HEIMDAL
        +		length = session->keyvalue->length;
        +		enctype = session->keytype;
        +		contents = session->keyvalue->contents;
        +#else
        +		length = session->length;
        +		enctype = session->enctype;
        +		contents = session->contents;
        +#endif
        +		kssl_ctx->enctype = enctype;
        +		kssl_ctx->length  = length;
        +		}
        +	else
        +                {
        +		kssl_ctx->enctype = ENCTYPE_UNKNOWN;
        +		kssl_ctx->length  = 0;
        +		return KSSL_CTX_OK;
        +		}
        +
        +	if ((kssl_ctx->key =
        +                (krb5_octet FAR *) kssl_calloc(1, kssl_ctx->length)) == NULL)
        +                {
        +		kssl_ctx->length  = 0;
        +		return KSSL_CTX_ERR;
        +		}
        +	else
        +		memcpy(kssl_ctx->key, contents, length);
        +
        +	return KSSL_CTX_OK;
        +        }
        +
        +
        +/*	Display contents of kssl_ctx struct
        +*/
        +void
        +kssl_ctx_show(KSSL_CTX *kssl_ctx)
        +        {
        +	int 	i;
        +
        +	printf("kssl_ctx: ");
        +	if (kssl_ctx == NULL)
        +                {
        +		printf("NULL\n");
        +		return;
        +		}
        +	else
        +		printf("%p\n", (void *)kssl_ctx);
        +
        +	printf("\tservice:\t%s\n",
        +                (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL");
        +	printf("\tclient:\t%s\n",
        +                (kssl_ctx->client_princ)? kssl_ctx->client_princ: "NULL");
        +	printf("\tserver:\t%s\n",
        +                (kssl_ctx->service_host)? kssl_ctx->service_host: "NULL");
        +	printf("\tkeytab:\t%s\n",
        +                (kssl_ctx->keytab_file)? kssl_ctx->keytab_file: "NULL");
        +	printf("\tkey [%d:%d]:\t",
        +                kssl_ctx->enctype, kssl_ctx->length);
        +
        +	for (i=0; i < kssl_ctx->length  &&  kssl_ctx->key; i++)
        +                {
        +		printf("%02x", kssl_ctx->key[i]);
        +		}
        +	printf("\n");
        +	return;
        +        }
        +
        +    int 
        +    kssl_keytab_is_available(KSSL_CTX *kssl_ctx)
        +{
        +    krb5_context		krb5context = NULL;
        +    krb5_keytab 		krb5keytab = NULL;
        +    krb5_keytab_entry           entry;
        +    krb5_principal              princ = NULL;
        +    krb5_error_code  		krb5rc = KRB5KRB_ERR_GENERIC;
        +    int rc = 0;
        +
        +    if ((krb5rc = krb5_init_context(&krb5context)))
        +        return(0);
        +
        +    /*	kssl_ctx->keytab_file == NULL ==> use Kerberos default
        +    */
        +    if (kssl_ctx->keytab_file)
        +    {
        +        krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
        +                                  &krb5keytab);
        +        if (krb5rc)
        +            goto exit;
        +    }
        +    else
        +    {
        +        krb5rc = krb5_kt_default(krb5context,&krb5keytab);
        +        if (krb5rc)
        +            goto exit;
        +    }
        +
        +    /* the host key we are looking for */
        +    krb5rc = krb5_sname_to_principal(krb5context, NULL, 
        +                                     kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC,
        +                                     KRB5_NT_SRV_HST, &princ);
        +
        +    if (krb5rc)
        +	goto exit;
        +
        +    krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, 
        +                                princ,
        +                                0 /* IGNORE_VNO */,
        +                                0 /* IGNORE_ENCTYPE */,
        +                                &entry);
        +    if ( krb5rc == KRB5_KT_NOTFOUND ) {
        +        rc = 1;
        +        goto exit;
        +    } else if ( krb5rc )
        +        goto exit;
        +    
        +    krb5_kt_free_entry(krb5context, &entry);
        +    rc = 1;
        +
        +  exit:
        +    if (krb5keytab)     krb5_kt_close(krb5context, krb5keytab);
        +    if (princ)          krb5_free_principal(krb5context, princ);
        +    if (krb5context)	krb5_free_context(krb5context);
        +    return(rc);
        +}
        +
        +int 
        +kssl_tgt_is_available(KSSL_CTX *kssl_ctx)
        +        {
        +        krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
        +        krb5_context		krb5context = NULL;
        +        krb5_ccache 		krb5ccdef = NULL;
        +        krb5_creds		krb5creds, *krb5credsp = NULL;
        +        int                     rc = 0;
        +
        +        memset((char *)&krb5creds, 0, sizeof(krb5creds));
        +
        +        if (!kssl_ctx)
        +            return(0);
        +
        +        if (!kssl_ctx->service_host)
        +            return(0);
        +
        +        if ((krb5rc = krb5_init_context(&krb5context)) != 0)
        +            goto err;
        +
        +        if ((krb5rc = krb5_sname_to_principal(krb5context,
        +                                              kssl_ctx->service_host,
        +                                              (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
        +                                              KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
        +            goto err;
        +
        +        if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
        +            goto err;
        +
        +        if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
        +                                             &krb5creds.client)) != 0)
        +            goto err;
        +
        +        if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
        +                                            &krb5creds, &krb5credsp)) != 0)
        +            goto err;
        +
        +        rc = 1;
        +
        +      err:
        +#ifdef KSSL_DEBUG
        +	kssl_ctx_show(kssl_ctx);
        +#endif	/* KSSL_DEBUG */
        +
        +	if (krb5creds.client)	krb5_free_principal(krb5context, krb5creds.client);
        +	if (krb5creds.server)	krb5_free_principal(krb5context, krb5creds.server);
        +	if (krb5context)	krb5_free_context(krb5context);
        +        return(rc);
        +	}
        +
        +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32)
        +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data)
        +	{
        +#ifdef KRB5_HEIMDAL
        +	data->length = 0;
        +        if (data->data)
        +            free(data->data);
        +#elif defined(KRB5_MIT_OLD11)
        +	if (data->data)  {
        +		krb5_xfree(data->data);
        +		data->data = 0;
        +		}
        +#else
        +	krb5_free_data_contents(NULL, data);
        +#endif
        +	}
        +#endif /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */
        +
        +
        +/*  Given pointers to KerberosTime and struct tm structs, convert the
        +**  KerberosTime string to struct tm.  Note that KerberosTime is a
        +**  ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional
        +**  seconds as defined in RFC 1510.
        +**  Return pointer to the (partially) filled in struct tm on success,
        +**  return NULL on failure.
        +*/
        +static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
        +	{
        +	char 		c, *p;
        +
        +	if (!k_tm)  return NULL;
        +	if (gtime == NULL  ||  gtime->length < 14)  return NULL;
        +	if (gtime->data == NULL)  return NULL;
        +
        +	p = (char *)&gtime->data[14];
        +
        +	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_sec  = atoi(p);      *(p+2) = c;
        +	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_min  = atoi(p);      *(p+2) = c;
        +	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_hour = atoi(p);      *(p+2) = c;
        +	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_mday = atoi(p);      *(p+2) = c;
        +	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_mon  = atoi(p)-1;    *(p+2) = c;
        +	c = *p;	 *p = '\0';  p -= 4;  k_tm->tm_year = atoi(p)-1900; *(p+4) = c;
        +
        +	return k_tm;
        +	}
        +
        +
        +/*  Helper function for kssl_validate_times().
        +**  We need context->clockskew, but krb5_context is an opaque struct.
        +**  So we try to sneek the clockskew out through the replay cache.
        +**	If that fails just return a likely default (300 seconds).
        +*/
        +static krb5_deltat get_rc_clockskew(krb5_context context)
        +	{
        +	krb5_rcache 	rc;
        +	krb5_deltat 	clockskew;
        +
        +	if (krb5_rc_default(context, &rc))  return KSSL_CLOCKSKEW;
        +	if (krb5_rc_initialize(context, rc, 0))  return KSSL_CLOCKSKEW;
        +	if (krb5_rc_get_lifespan(context, rc, &clockskew))  {
        +		clockskew = KSSL_CLOCKSKEW;
        +		}
        +	(void) krb5_rc_destroy(context, rc);
        +	return clockskew;
        +	}
        +
        +
        +/*  kssl_validate_times() combines (and more importantly exposes)
        +**  the MIT KRB5 internal function krb5_validate_times() and the
        +**  in_clock_skew() macro.  The authenticator client time is checked
        +**  to be within clockskew secs of the current time and the current
        +**  time is checked to be within the ticket start and expire times.
        +**  Either check may be omitted by supplying a NULL value.
        +**  Returns 0 for valid times, SSL_R_KRB5* error codes otherwise.
        +**  See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c
        +**  20010420 VRS
        +*/
        +krb5_error_code  kssl_validate_times(	krb5_timestamp atime,
        +					krb5_ticket_times *ttimes)
        +	{
        +	krb5_deltat 	skew;
        +	krb5_timestamp	start, now;
        +	krb5_error_code	rc;
        +	krb5_context	context;
        +
        +	if ((rc = krb5_init_context(&context)))	 return SSL_R_KRB5_S_BAD_TICKET;
        +	skew = get_rc_clockskew(context); 
        +	if ((rc = krb5_timeofday(context,&now))) return SSL_R_KRB5_S_BAD_TICKET;
        +	krb5_free_context(context);
        +
        +	if (atime  &&  labs(atime - now) >= skew)  return SSL_R_KRB5_S_TKT_SKEW;
        +
        +	if (! ttimes)  return 0;
        +
        +	start = (ttimes->starttime != 0)? ttimes->starttime: ttimes->authtime;
        +	if (start - now > skew)  return SSL_R_KRB5_S_TKT_NYV;
        +	if ((now - ttimes->endtime) > skew)  return SSL_R_KRB5_S_TKT_EXPIRED;
        +
        +#ifdef KSSL_DEBUG
        +	printf("kssl_validate_times: %d |<-  | %d - %d | < %d  ->| %d\n",
        +		start, atime, now, skew, ttimes->endtime);
        +#endif	/* KSSL_DEBUG */
        +
        +	return 0;
        +	}
        +
        +
        +/*  Decode and decrypt given DER-encoded authenticator, then pass
        +**  authenticator ctime back in *atimep (or 0 if time unavailable).
        +**  Returns krb5_error_code and kssl_err on error.  A NULL 
        +**  authenticator (authentp->length == 0) is not considered an error.
        +**  Note that kssl_check_authent() makes use of the KRB5 session key;
        +**  you must call kssl_sget_tkt() to get the key before calling this routine.
        +*/
        +krb5_error_code  kssl_check_authent(
        +			/* IN     */	KSSL_CTX	*kssl_ctx,
        +                        /* IN     */   	krb5_data	*authentp,
        +			/* OUT    */	krb5_timestamp	*atimep,
        +			/* OUT    */    KSSL_ERR	*kssl_err  )
        +	{
        +        krb5_error_code		krb5rc = 0;
        +	KRB5_ENCDATA		*dec_authent = NULL;
        +	KRB5_AUTHENTBODY	*auth = NULL;
        +	krb5_enctype		enctype;
        +	EVP_CIPHER_CTX		ciph_ctx;
        +	const EVP_CIPHER	*enc = NULL;
        +	unsigned char		iv[EVP_MAX_IV_LENGTH];
        +	const unsigned char	*p;
        +	unsigned char		*unenc_authent;
        +	int 			outl, unencbufsize;
        +	struct tm		tm_time, *tm_l, *tm_g;
        +	time_t			now, tl, tg, tr, tz_offset;
        +
        +	EVP_CIPHER_CTX_init(&ciph_ctx);
        +	*atimep = 0;
        +	kssl_err_set(kssl_err, 0, "");
        +
        +#ifndef KRB5CHECKAUTH
        +	authentp = NULL;
        +#else
        +#if	KRB5CHECKAUTH == 0
        +	authentp = NULL;
        +#endif
        +#endif	/* KRB5CHECKAUTH */
        +
        +	if (authentp == NULL  ||  authentp->length == 0)  return 0;
        +
        +#ifdef KSSL_DEBUG
        +        {
        +        unsigned int ui;
        +	printf("kssl_check_authent: authenticator[%d]:\n",authentp->length);
        +	p = authentp->data; 
        +	for (ui=0; ui < authentp->length; ui++)  printf("%02x ",p[ui]);
        +	printf("\n");
        +        }
        +#endif	/* KSSL_DEBUG */
        +
        +	unencbufsize = 2 * authentp->length;
        +	if ((unenc_authent = calloc(1, unencbufsize)) == NULL)
        +		{
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +			"Unable to allocate authenticator buffer.\n");
        +		krb5rc = KRB5KRB_ERR_GENERIC;
        +		goto err;
        +		}
        +
        +	p = (unsigned char *)authentp->data;
        +	if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p,
        +					(long) authentp->length)) == NULL) 
        +		{
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "Error decoding authenticator.\n");
        +		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
        +		goto err;
        +		}
        +
        +	enctype = dec_authent->etype->data[0];	/* should = kssl_ctx->enctype */
        +#if !defined(KRB5_MIT_OLD11)
        +            switch ( enctype ) {
        +            case ENCTYPE_DES3_CBC_SHA1:		/*    EVP_des_ede3_cbc();  */
        +            case ENCTYPE_DES3_CBC_SHA:
        +            case ENCTYPE_DES3_CBC_RAW:
        +                krb5rc = 0;                     /* Skip, can't handle derived keys */
        +                goto err;
        +            }
        +#endif
        +	enc = kssl_map_enc(enctype);
        +	memset(iv, 0, sizeof iv);       /* per RFC 1510 */
        +
        +	if (enc == NULL)
        +		{
        +		/*  Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1.
        +		**  This enctype indicates the authenticator was encrypted
        +		**  using key-usage derived keys which openssl cannot decrypt.
        +		*/
        +		goto err;
        +		}
        +
        +        if (!EVP_CipherInit(&ciph_ctx,enc,kssl_ctx->key,iv,0))
        +                {
        +                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "EVP_CipherInit error decrypting authenticator.\n");
        +                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
        +                goto err;
        +                }
        +        outl = dec_authent->cipher->length;
        +        if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl))
        +                {
        +                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "EVP_Cipher error decrypting authenticator.\n");
        +                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
        +                goto err;
        +                }
        +        EVP_CIPHER_CTX_cleanup(&ciph_ctx);
        +
        +#ifdef KSSL_DEBUG
        +	{
        +	int padl;
        +	printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl);
        +	for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]);
        +	printf("\n");
        +	}
        +#endif	/* KSSL_DEBUG */
        +
        +	if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL)
        +		{
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "confounded by authenticator.\n");
        +		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
        +		goto err;
        +		}
        +	outl -= p - unenc_authent;
        +
        +	if ((auth = (KRB5_AUTHENTBODY *) d2i_KRB5_AUTHENT(NULL, &p,
        +							  (long) outl))==NULL)
        +		{
        +		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
        +                        "Error decoding authenticator body.\n");
        +		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
        +		goto err;
        +		}
        +
        +	memset(&tm_time,0,sizeof(struct tm));
        +	if (k_gmtime(auth->ctime, &tm_time)  &&
        +		((tr = mktime(&tm_time)) != (time_t)(-1)))
        + 		{
        + 		now  = time(&now);
        + 		tm_l = localtime(&now); 	tl = mktime(tm_l);
        + 		tm_g = gmtime(&now);		tg = mktime(tm_g);
        + 		tz_offset = tg - tl;
        +
        +		*atimep = (krb5_timestamp)(tr - tz_offset);
        + 		}
        +
        +#ifdef KSSL_DEBUG
        +	printf("kssl_check_authent: returns %d for client time ", *atimep);
        +	if (auth && auth->ctime && auth->ctime->length && auth->ctime->data)
        +		printf("%.*s\n", auth->ctime->length, auth->ctime->data);
        +	else	printf("NULL\n");
        +#endif	/* KSSL_DEBUG */
        +
        + err:
        +	if (auth)		KRB5_AUTHENT_free((KRB5_AUTHENT *) auth);
        +	if (dec_authent)	KRB5_ENCDATA_free(dec_authent);
        +	if (unenc_authent)	free(unenc_authent);
        +	EVP_CIPHER_CTX_cleanup(&ciph_ctx);
        +	return krb5rc;
        +	}
        +
        +
        +/*  Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host),
        +**  because I dont't know how to stub varargs.
        +**  Returns krb5_error_code == ENOMEM on alloc error, otherwise
        +**  passes back newly constructed principal, which should be freed by caller.
        +*/
        +krb5_error_code  kssl_build_principal_2(
        +			/* UPDATE */	krb5_context	context,
        +			/* OUT    */	krb5_principal	*princ,
        +			/* IN     */	int rlen,  const char *realm,
        +			/* IN	  */	int slen,  const char *svc,
        +			/* IN	  */	int hlen,  const char *host)
        +	{
        +	krb5_data		*p_data = NULL;
        +	krb5_principal		new_p = NULL;
        +        char			*new_r = NULL;
        +
        +	if ((p_data = (krb5_data *) calloc(2, sizeof(krb5_data))) == NULL  ||
        +	    (new_p = (krb5_principal) calloc(1, sizeof(krb5_principal_data)))
        +			== NULL)  goto err;
        +	new_p->length = 2;
        +	new_p->data = p_data;
        +
        +	if ((new_r = calloc(1, rlen + 1)) == NULL)  goto err;
        +	memcpy(new_r, realm, rlen);
        +	krb5_princ_set_realm_length(context, new_p, rlen);
        +	krb5_princ_set_realm_data(context, new_p, new_r);
        +
        +	if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL)  goto err;
        +	memcpy(new_p->data[0].data, svc, slen);
        +	new_p->data[0].length = slen;
        +
        +	if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL)  goto err;
        +	memcpy(new_p->data[1].data, host, hlen);
        +	new_p->data[1].length = hlen;
        +	
        +	krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN;
        +	*princ = new_p;
        +	return 0;
        +
        + err:
        +	if (new_p  &&  new_p[0].data)	free(new_p[0].data);
        +	if (new_p  &&  new_p[1].data)	free(new_p[1].data);
        +	if (new_p)	free(new_p);
        +	if (new_r)	free(new_r);
        +	return ENOMEM;
        +	}
        +
        +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx)
        +	{
        +	s->kssl_ctx = kctx;
        +	} 
        +
        +KSSL_CTX * SSL_get0_kssl_ctx(SSL *s)
        +	{
        +	return s->kssl_ctx;
        +	}
        +
        +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx)
        +	{
        +	if (kctx)
        +		return kctx->client_princ;
        +	return NULL;
        +	}
        +
        +#else /* !OPENSSL_NO_KRB5 */
        +
        +#if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS)
        +static void *dummy=&dummy;
        +#endif
        +
        +#endif	/* !OPENSSL_NO_KRB5	*/
        +
        diff --git a/vendor/openssl/openssl/ssl/kssl.h b/vendor/openssl/openssl/ssl/kssl.h
        new file mode 100644
        index 000000000..8242fd5ee
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/kssl.h
        @@ -0,0 +1,183 @@
        +/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
        +/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
        + * 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).
        + *
        + */
        +
        +/*
        +**	19990701	VRS 	Started.
        +*/
        +
        +#ifndef	KSSL_H
        +#define	KSSL_H
        +
        +#include <openssl/opensslconf.h>
        +
        +#ifndef OPENSSL_NO_KRB5
        +
        +#include <stdio.h>
        +#include <ctype.h>
        +#include <krb5.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/*
        +**	Depending on which KRB5 implementation used, some types from
        +**	the other may be missing.  Resolve that here and now
        +*/
        +#ifdef KRB5_HEIMDAL
        +typedef unsigned char krb5_octet;
        +#define FAR
        +#else
        +
        +#ifndef FAR
        +#define FAR
        +#endif
        +
        +#endif
        +
        +/*	Uncomment this to debug kssl problems or
        +**	to trace usage of the Kerberos session key
        +**
        +**	#define		KSSL_DEBUG
        +*/
        +
        +#ifndef	KRB5SVC
        +#define KRB5SVC	"host"
        +#endif
        +
        +#ifndef	KRB5KEYTAB
        +#define KRB5KEYTAB	"/etc/krb5.keytab"
        +#endif
        +
        +#ifndef KRB5SENDAUTH
        +#define KRB5SENDAUTH	1
        +#endif
        +
        +#ifndef KRB5CHECKAUTH
        +#define KRB5CHECKAUTH	1
        +#endif
        +
        +#ifndef KSSL_CLOCKSKEW
        +#define	KSSL_CLOCKSKEW	300;
        +#endif
        +
        +#define	KSSL_ERR_MAX	255
        +typedef struct kssl_err_st  {
        +	int  reason;
        +	char text[KSSL_ERR_MAX+1];
        +	} KSSL_ERR;
        +
        +
        +/*	Context for passing
        +**		(1) Kerberos session key to SSL, and
        +**		(2)	Config data between application and SSL lib
        +*/
        +typedef struct kssl_ctx_st
        +        {
        +                                /*	used by:    disposition:            */
        +	char *service_name;	/*	C,S	    default ok (kssl)       */
        +	char *service_host;	/*	C	    input, REQUIRED         */
        +	char *client_princ;	/*	S	    output from krb5 ticket */
        +	char *keytab_file;	/*      S	    NULL (/etc/krb5.keytab) */
        +	char *cred_cache;	/*	C	    NULL (default)          */
        +	krb5_enctype enctype;
        +	int length;
        +	krb5_octet FAR *key;
        +	} KSSL_CTX;
        +
        +#define	KSSL_CLIENT 	1
        +#define KSSL_SERVER 	2
        +#define	KSSL_SERVICE	3
        +#define	KSSL_KEYTAB 	4
        +
        +#define KSSL_CTX_OK 	0
        +#define KSSL_CTX_ERR	1
        +#define KSSL_NOMEM	2
        +
        +/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
        +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
        +KSSL_CTX *kssl_ctx_new(void);
        +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
        +void kssl_ctx_show(KSSL_CTX *kssl_ctx);
        +krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
        +        krb5_data *realm, krb5_data *entity, int nentities);
        +krb5_error_code	kssl_cget_tkt(KSSL_CTX *kssl_ctx,  krb5_data **enc_tktp,
        +        krb5_data *authenp, KSSL_ERR *kssl_err);
        +krb5_error_code	kssl_sget_tkt(KSSL_CTX *kssl_ctx,  krb5_data *indata,
        +        krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
        +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
        +void	kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
        +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
        +krb5_error_code  kssl_build_principal_2(krb5_context context,
        +			krb5_principal *princ, int rlen, const char *realm,
        +			int slen, const char *svc, int hlen, const char *host);
        +krb5_error_code  kssl_validate_times(krb5_timestamp atime,
        +					krb5_ticket_times *ttimes);
        +krb5_error_code  kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
        +			            krb5_timestamp *atimep, KSSL_ERR *kssl_err);
        +unsigned char	*kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
        +
        +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx);
        +KSSL_CTX * SSL_get0_kssl_ctx(SSL *s);
        +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif	/* OPENSSL_NO_KRB5	*/
        +#endif	/* KSSL_H 	*/
        diff --git a/vendor/openssl/openssl/ssl/kssl_lcl.h b/vendor/openssl/openssl/ssl/kssl_lcl.h
        new file mode 100644
        index 000000000..c039c91b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/kssl_lcl.h
        @@ -0,0 +1,87 @@
        +/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
        +/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
        + * 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	KSSL_LCL_H
        +#define	KSSL_LCL_H
        +
        +#include <openssl/kssl.h>
        +
        +#ifndef OPENSSL_NO_KRB5
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Private (internal to OpenSSL) */
        +void print_krb5_data(char *label, krb5_data *kdata);
        +void print_krb5_authdata(char *label, krb5_authdata **adata);
        +void print_krb5_keyblock(char *label, krb5_keyblock *keyblk);
        +
        +char *kstring(char *string);
        +char *knumber(int len, krb5_octet *contents);
        +
        +const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
        +
        +int kssl_keytab_is_available(KSSL_CTX *kssl_ctx);
        +int kssl_tgt_is_available(KSSL_CTX *kssl_ctx);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif	/* OPENSSL_NO_KRB5	*/
        +#endif	/* KSSL_LCL_H 	*/
        diff --git a/vendor/openssl/openssl/ssl/s23_clnt.c b/vendor/openssl/openssl/ssl/s23_clnt.c
        new file mode 100644
        index 000000000..47673e740
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s23_clnt.c
        @@ -0,0 +1,779 @@
        +/* ssl/s23_clnt.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-2006 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 <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +
        +static const SSL_METHOD *ssl23_get_client_method(int ver);
        +static int ssl23_client_hello(SSL *s);
        +static int ssl23_get_server_hello(SSL *s);
        +static const SSL_METHOD *ssl23_get_client_method(int ver)
        +	{
        +#ifndef OPENSSL_NO_SSL2
        +	if (ver == SSL2_VERSION)
        +		return(SSLv2_client_method());
        +#endif
        +	if (ver == SSL3_VERSION)
        +		return(SSLv3_client_method());
        +	else if (ver == TLS1_VERSION)
        +		return(TLSv1_client_method());
        +	else if (ver == TLS1_1_VERSION)
        +		return(TLSv1_1_client_method());
        +	else if (ver == TLS1_2_VERSION)
        +		return(TLSv1_2_client_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl23_meth_func(SSLv23_client_method,
        +			ssl_undefined_function,
        +			ssl23_connect,
        +			ssl23_get_client_method)
        +
        +int ssl23_connect(SSL *s)
        +	{
        +	BUF_MEM *buf=NULL;
        +	unsigned long Time=(unsigned long)time(NULL);
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int ret= -1;
        +	int new_state,state;
        +
        +	RAND_add(&Time,sizeof(Time),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +	
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch(s->state)
        +			{
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_CONNECT:
        +		case SSL_ST_BEFORE|SSL_ST_CONNECT:
        +		case SSL_ST_OK|SSL_ST_CONNECT:
        +
        +			if (s->session != NULL)
        +				{
        +				SSLerr(SSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE);
        +				ret= -1;
        +				goto end;
        +				}
        +			s->server=0;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			/* s->version=TLS1_VERSION; */
        +			s->type=SSL_ST_CONNECT;
        +
        +			if (s->init_buf == NULL)
        +				{
        +				if ((buf=BUF_MEM_new()) == NULL)
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				s->init_buf=buf;
        +				buf=NULL;
        +				}
        +
        +			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
        +
        +			ssl3_init_finished_mac(s);
        +
        +			s->state=SSL23_ST_CW_CLNT_HELLO_A;
        +			s->ctx->stats.sess_connect++;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL23_ST_CW_CLNT_HELLO_A:
        +		case SSL23_ST_CW_CLNT_HELLO_B:
        +
        +			s->shutdown=0;
        +			ret=ssl23_client_hello(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL23_ST_CR_SRVR_HELLO_A;
        +			s->init_num=0;
        +
        +			break;
        +
        +		case SSL23_ST_CR_SRVR_HELLO_A:
        +		case SSL23_ST_CR_SRVR_HELLO_B:
        +			ret=ssl23_get_server_hello(s);
        +			if (ret >= 0) cb=NULL;
        +			goto end;
        +			/* break; */
        +
        +		default:
        +			SSLerr(SSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* break; */
        +			}
        +
        +		if (s->debug) { (void)BIO_flush(s->wbio); }
        +
        +		if ((cb != NULL) && (s->state != state))
        +			{
        +			new_state=s->state;
        +			s->state=state;
        +			cb(s,SSL_CB_CONNECT_LOOP,1);
        +			s->state=new_state;
        +			}
        +		}
        +end:
        +	s->in_handshake--;
        +	if (buf != NULL)
        +		BUF_MEM_free(buf);
        +	if (cb != NULL)
        +		cb(s,SSL_CB_CONNECT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +static int ssl23_no_ssl2_ciphers(SSL *s)
        +	{
        +	SSL_CIPHER *cipher;
        +	STACK_OF(SSL_CIPHER) *ciphers;
        +	int i;
        +	ciphers = SSL_get_ciphers(s);
        +	for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
        +		{
        +		cipher = sk_SSL_CIPHER_value(ciphers, i);
        +		if (cipher->algorithm_ssl == SSL_SSLV2)
        +			return 0;
        +		}
        +	return 1;
        +	}
        +
        +static int ssl23_client_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	int i,ch_len;
        +	unsigned long Time,l;
        +	int ssl2_compat;
        +	int version = 0, version_major, version_minor;
        +#ifndef OPENSSL_NO_COMP
        +	int j;
        +	SSL_COMP *comp;
        +#endif
        +	int ret;
        +	unsigned long mask, options = s->options;
        +
        +	ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1;
        +
        +	if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
        +		ssl2_compat = 0;
        +
        +	/*
        +	 * SSL_OP_NO_X disables all protocols above X *if* there are
        +	 * some protocols below X enabled. This is required in order
        +	 * to maintain "version capability" vector contiguous. So
        +	 * that if application wants to disable TLS1.0 in favour of
        +	 * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the
        +	 * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.
        +	 */
        +	mask =	SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1
        +#if !defined(OPENSSL_NO_SSL3)
        +		|SSL_OP_NO_SSLv3
        +#endif
        +#if !defined(OPENSSL_NO_SSL2)
        +		|(ssl2_compat?SSL_OP_NO_SSLv2:0)
        +#endif
        +		;
        +#if !defined(OPENSSL_NO_TLS1_2_CLIENT)
        +	version = TLS1_2_VERSION;
        +
        +	if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask)
        +		version = TLS1_1_VERSION;
        +#else
        +	version = TLS1_1_VERSION;
        +#endif
        +	mask &= ~SSL_OP_NO_TLSv1_1;
        +	if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask)
        +		version = TLS1_VERSION;
        +	mask &= ~SSL_OP_NO_TLSv1;
        +#if !defined(OPENSSL_NO_SSL3)
        +	if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask)
        +		version = SSL3_VERSION;
        +	mask &= ~SSL_OP_NO_SSLv3;
        +#endif
        +#if !defined(OPENSSL_NO_SSL2)
        +	if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask)
        +		version = SSL2_VERSION;
        +#endif
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (version != SSL2_VERSION)
        +		{
        +		/* have to disable SSL 2.0 compatibility if we need TLS extensions */
        +
        +		if (s->tlsext_hostname != NULL)
        +			ssl2_compat = 0;
        +		if (s->tlsext_status_type != -1)
        +			ssl2_compat = 0;
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +		if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
        +			ssl2_compat = 0;
        +#endif
        +		}
        +#endif
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
        +		{
        +#if 0
        +		/* don't reuse session-id's */
        +		if (!ssl_get_new_session(s,0))
        +			{
        +			return(-1);
        +			}
        +#endif
        +
        +		p=s->s3->client_random;
        +		Time=(unsigned long)time(NULL);		/* Time */
        +		l2n(Time,p);
        +		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
        +			return -1;
        +
        +		if (version == TLS1_2_VERSION)
        +			{
        +			version_major = TLS1_2_VERSION_MAJOR;
        +			version_minor = TLS1_2_VERSION_MINOR;
        +			}
        +		else if (version == TLS1_1_VERSION)
        +			{
        +			version_major = TLS1_1_VERSION_MAJOR;
        +			version_minor = TLS1_1_VERSION_MINOR;
        +			}
        +		else if (version == TLS1_VERSION)
        +			{
        +			version_major = TLS1_VERSION_MAJOR;
        +			version_minor = TLS1_VERSION_MINOR;
        +			}
        +#ifdef OPENSSL_FIPS
        +		else if(FIPS_mode())
        +			{
        +			SSLerr(SSL_F_SSL23_CLIENT_HELLO,
        +					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
        +			return -1;
        +			}
        +#endif
        +		else if (version == SSL3_VERSION)
        +			{
        +			version_major = SSL3_VERSION_MAJOR;
        +			version_minor = SSL3_VERSION_MINOR;
        +			}
        +		else if (version == SSL2_VERSION)
        +			{
        +			version_major = SSL2_VERSION_MAJOR;
        +			version_minor = SSL2_VERSION_MINOR;
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE);
        +			return(-1);
        +			}
        +
        +		s->client_version = version;
        +
        +		if (ssl2_compat)
        +			{
        +			/* create SSL 2.0 compatible Client Hello */
        +
        +			/* two byte record header will be written last */
        +			d = &(buf[2]);
        +			p = d + 9; /* leave space for message type, version, individual length fields */
        +
        +			*(d++) = SSL2_MT_CLIENT_HELLO;
        +			*(d++) = version_major;
        +			*(d++) = version_minor;
        +			
        +			/* Ciphers supported */
        +			i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p,0);
        +			if (i == 0)
        +				{
        +				/* no ciphers */
        +				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
        +				return -1;
        +				}
        +			s2n(i,d);
        +			p+=i;
        +			
        +			/* put in the session-id length (zero since there is no reuse) */
        +#if 0
        +			s->session->session_id_length=0;
        +#endif
        +			s2n(0,d);
        +
        +			if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
        +				ch_len=SSL2_CHALLENGE_LENGTH;
        +			else
        +				ch_len=SSL2_MAX_CHALLENGE_LENGTH;
        +
        +			/* write out sslv2 challenge */
        +			/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32),
        +			   because it is one of SSL2_MAX_CHALLENGE_LENGTH (32)
        +			   or SSL2_MAX_CHALLENGE_LENGTH (16), but leave the
        +			   check in for futurproofing */
        +			if (SSL3_RANDOM_SIZE < ch_len)
        +				i=SSL3_RANDOM_SIZE;
        +			else
        +				i=ch_len;
        +			s2n(i,d);
        +			memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE);
        +			if (RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0)
        +				return -1;
        +
        +			memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i);
        +			p+=i;
        +
        +			i= p- &(buf[2]);
        +			buf[0]=((i>>8)&0xff)|0x80;
        +			buf[1]=(i&0xff);
        +
        +			/* number of bytes to write */
        +			s->init_num=i+2;
        +			s->init_off=0;
        +
        +			ssl3_finish_mac(s,&(buf[2]),i);
        +			}
        +		else
        +			{
        +			/* create Client Hello in SSL 3.0/TLS 1.0 format */
        +
        +			/* do the record header (5 bytes) and handshake message header (4 bytes) last */
        +			d = p = &(buf[9]);
        +			
        +			*(p++) = version_major;
        +			*(p++) = version_minor;
        +
        +			/* Random stuff */
        +			memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
        +			p += SSL3_RANDOM_SIZE;
        +
        +			/* Session ID (zero since there is no reuse) */
        +			*(p++) = 0;
        +
        +			/* Ciphers supported (using SSL 3.0/TLS 1.0 format) */
        +			i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),ssl3_put_cipher_by_char);
        +			if (i == 0)
        +				{
        +				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
        +				return -1;
        +				}
        +#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
        +			/* Some servers hang if client hello > 256 bytes
        +			 * as hack workaround chop number of supported ciphers
        +			 * to keep it well below this if we use TLS v1.2
        +			 */
        +			if (TLS1_get_version(s) >= TLS1_2_VERSION
        +				&& i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
        +				i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
        +#endif
        +			s2n(i,p);
        +			p+=i;
        +
        +			/* COMPRESSION */
        +#ifdef OPENSSL_NO_COMP
        +			*(p++)=1;
        +#else
        +			if ((s->options & SSL_OP_NO_COMPRESSION)
        +						|| !s->ctx->comp_methods)
        +				j=0;
        +			else
        +				j=sk_SSL_COMP_num(s->ctx->comp_methods);
        +			*(p++)=1+j;
        +			for (i=0; i<j; i++)
        +				{
        +				comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
        +				*(p++)=comp->id;
        +				}
        +#endif
        +			*(p++)=0; /* Add the NULL method */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +			/* TLS extensions*/
        +			if (ssl_prepare_clienthello_tlsext(s) <= 0)
        +				{
        +				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
        +				return -1;
        +				}
        +			if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
        +				return -1;
        +				}
        +#endif
        +			
        +			l = p-d;
        +
        +			/* fill in 4-byte handshake header */
        +			d=&(buf[5]);
        +			*(d++)=SSL3_MT_CLIENT_HELLO;
        +			l2n3(l,d);
        +
        +			l += 4;
        +
        +			if (l > SSL3_RT_MAX_PLAIN_LENGTH)
        +				{
        +				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
        +				return -1;
        +				}
        +			
        +			/* fill in 5-byte record header */
        +			d=buf;
        +			*(d++) = SSL3_RT_HANDSHAKE;
        +			*(d++) = version_major;
        +			/* Some servers hang if we use long client hellos
        +			 * and a record number > TLS 1.0.
        +			 */
        +			if (TLS1_get_client_version(s) > TLS1_VERSION)
        +				*(d++) = 1;
        +			else
        +				*(d++) = version_minor;
        +			s2n((int)l,d);
        +
        +			/* number of bytes to write */
        +			s->init_num=p-buf;
        +			s->init_off=0;
        +
        +			ssl3_finish_mac(s,&(buf[5]), s->init_num - 5);
        +			}
        +
        +		s->state=SSL23_ST_CW_CLNT_HELLO_B;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_CW_CLNT_HELLO_B */
        +	ret = ssl23_write_bytes(s);
        +
        +	if ((ret >= 2) && s->msg_callback)
        +		{
        +		/* Client Hello has been sent; tell msg_callback */
        +
        +		if (ssl2_compat)
        +			s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg);
        +		else
        +			s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data+5, ret-5, s, s->msg_callback_arg);
        +		}
        +
        +	return ret;
        +	}
        +
        +static int ssl23_get_server_hello(SSL *s)
        +	{
        +	char buf[8];
        +	unsigned char *p;
        +	int i;
        +	int n;
        +
        +	n=ssl23_read_bytes(s,7);
        +
        +	if (n != 7) return(n);
        +	p=s->packet;
        +
        +	memcpy(buf,p,n);
        +
        +	if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) &&
        +		(p[5] == 0x00) && (p[6] == 0x02))
        +		{
        +#ifdef OPENSSL_NO_SSL2
        +		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
        +		goto err;
        +#else
        +		/* we are talking sslv2 */
        +		/* we need to clean up the SSLv3 setup and put in the
        +		 * sslv2 stuff. */
        +		int ch_len;
        +
        +		if (s->options & SSL_OP_NO_SSLv2)
        +			{
        +			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
        +			goto err;
        +			}
        +		if (s->s2 == NULL)
        +			{
        +			if (!ssl2_new(s))
        +				goto err;
        +			}
        +		else
        +			ssl2_clear(s);
        +
        +		if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
        +			ch_len=SSL2_CHALLENGE_LENGTH;
        +		else
        +			ch_len=SSL2_MAX_CHALLENGE_LENGTH;
        +
        +		/* write out sslv2 challenge */
        +		/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because
        +		   it is one of SSL2_MAX_CHALLENGE_LENGTH (32) or
        +		   SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for
        +		   futurproofing */
        +		i=(SSL3_RANDOM_SIZE < ch_len)
        +			?SSL3_RANDOM_SIZE:ch_len;
        +		s->s2->challenge_length=i;
        +		memcpy(s->s2->challenge,
        +			&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i);
        +
        +		if (s->s3 != NULL) ssl3_free(s);
        +
        +		if (!BUF_MEM_grow_clean(s->init_buf,
        +			SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
        +			{
        +			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB);
        +			goto err;
        +			}
        +
        +		s->state=SSL2_ST_GET_SERVER_HELLO_A;
        +		if (!(s->client_version == SSL2_VERSION))
        +			/* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */
        +			s->s2->ssl2_rollback=1;
        +
        +		/* setup the 7 bytes we have read so we get them from
        +		 * the sslv2 buffer */
        +		s->rstate=SSL_ST_READ_HEADER;
        +		s->packet_length=n;
        +		s->packet= &(s->s2->rbuf[0]);
        +		memcpy(s->packet,buf,n);
        +		s->s2->rbuf_left=n;
        +		s->s2->rbuf_offs=0;
        +
        +		/* we have already written one */
        +		s->s2->write_sequence=1;
        +
        +		s->method=SSLv2_client_method();
        +		s->handshake_func=s->method->ssl_connect;
        +#endif
        +		}
        +	else if (p[1] == SSL3_VERSION_MAJOR &&
        +	         p[2] <= TLS1_2_VERSION_MINOR &&
        +	         ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
        +	          (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
        +		{
        +		/* we have sslv3 or tls1 (server hello or alert) */
        +
        +		if ((p[2] == SSL3_VERSION_MINOR) &&
        +			!(s->options & SSL_OP_NO_SSLv3))
        +			{
        +#ifdef OPENSSL_FIPS
        +			if(FIPS_mode())
        +				{
        +				SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
        +					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
        +				goto err;
        +				}
        +#endif
        +			s->version=SSL3_VERSION;
        +			s->method=SSLv3_client_method();
        +			}
        +		else if ((p[2] == TLS1_VERSION_MINOR) &&
        +			!(s->options & SSL_OP_NO_TLSv1))
        +			{
        +			s->version=TLS1_VERSION;
        +			s->method=TLSv1_client_method();
        +			}
        +		else if ((p[2] == TLS1_1_VERSION_MINOR) &&
        +			!(s->options & SSL_OP_NO_TLSv1_1))
        +			{
        +			s->version=TLS1_1_VERSION;
        +			s->method=TLSv1_1_client_method();
        +			}
        +		else if ((p[2] == TLS1_2_VERSION_MINOR) &&
        +			!(s->options & SSL_OP_NO_TLSv1_2))
        +			{
        +			s->version=TLS1_2_VERSION;
        +			s->method=TLSv1_2_client_method();
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
        +			goto err;
        +			}
        +
        +		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
        +			{
        +			/* fatal alert */
        +
        +			void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +			int j;
        +
        +			if (s->info_callback != NULL)
        +				cb=s->info_callback;
        +			else if (s->ctx->info_callback != NULL)
        +				cb=s->ctx->info_callback;
        + 
        +			i=p[5];
        +			if (cb != NULL)
        +				{
        +				j=(i<<8)|p[6];
        +				cb(s,SSL_CB_READ_ALERT,j);
        +				}
        +			
        +			if (s->msg_callback)
        +				s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg);
        +
        +			s->rwstate=SSL_NOTHING;
        +			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
        +			goto err;
        +			}
        +
        +		if (!ssl_init_wbio_buffer(s,1)) goto err;
        +
        +		/* we are in this state */
        +		s->state=SSL3_ST_CR_SRVR_HELLO_A;
        +
        +		/* put the 7 bytes we have read into the input buffer
        +		 * for SSLv3 */
        +		s->rstate=SSL_ST_READ_HEADER;
        +		s->packet_length=n;
        +		if (s->s3->rbuf.buf == NULL)
        +			if (!ssl3_setup_read_buffer(s))
        +				goto err;
        +		s->packet= &(s->s3->rbuf.buf[0]);
        +		memcpy(s->packet,buf,n);
        +		s->s3->rbuf.left=n;
        +		s->s3->rbuf.offset=0;
        +
        +		s->handshake_func=s->method->ssl_connect;
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNKNOWN_PROTOCOL);
        +		goto err;
        +		}
        +	s->init_num=0;
        +
        +	/* Since, if we are sending a ssl23 client hello, we are not
        +	 * reusing a session-id */
        +	if (!ssl_get_new_session(s,0))
        +		goto err;
        +
        +	return(SSL_connect(s));
        +err:
        +	return(-1);
        +	}
        diff --git a/vendor/openssl/openssl/ssl/s23_lib.c b/vendor/openssl/openssl/ssl/s23_lib.c
        new file mode 100644
        index 000000000..3bf728318
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s23_lib.c
        @@ -0,0 +1,187 @@
        +/* ssl/s23_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +long ssl23_default_timeout(void)
        +	{
        +	return(300);
        +	}
        +
        +int ssl23_num_ciphers(void)
        +	{
        +	return(ssl3_num_ciphers()
        +#ifndef OPENSSL_NO_SSL2
        +	       + ssl2_num_ciphers()
        +#endif
        +	    );
        +	}
        +
        +const SSL_CIPHER *ssl23_get_cipher(unsigned int u)
        +	{
        +	unsigned int uu=ssl3_num_ciphers();
        +
        +	if (u < uu)
        +		return(ssl3_get_cipher(u));
        +	else
        +#ifndef OPENSSL_NO_SSL2
        +		return(ssl2_get_cipher(u-uu));
        +#else
        +		return(NULL);
        +#endif
        +	}
        +
        +/* This function needs to check if the ciphers required are actually
        + * available */
        +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
        +	{
        +	const SSL_CIPHER *cp;
        +
        +	cp=ssl3_get_cipher_by_char(p);
        +#ifndef OPENSSL_NO_SSL2
        +	if (cp == NULL)
        +		cp=ssl2_get_cipher_by_char(p);
        +#endif
        +	return(cp);
        +	}
        +
        +int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
        +	{
        +	long l;
        +
        +	/* We can write SSLv2 and SSLv3 ciphers */
        +	if (p != NULL)
        +		{
        +		l=c->id;
        +		p[0]=((unsigned char)(l>>16L))&0xFF;
        +		p[1]=((unsigned char)(l>> 8L))&0xFF;
        +		p[2]=((unsigned char)(l     ))&0xFF;
        +		}
        +	return(3);
        +	}
        +
        +int ssl23_read(SSL *s, void *buf, int len)
        +	{
        +	int n;
        +
        +	clear_sys_error();
        +	if (SSL_in_init(s) && (!s->in_handshake))
        +		{
        +		n=s->handshake_func(s);
        +		if (n < 0) return(n);
        +		if (n == 0)
        +			{
        +			SSLerr(SSL_F_SSL23_READ,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		return(SSL_read(s,buf,len));
        +		}
        +	else
        +		{
        +		ssl_undefined_function(s);
        +		return(-1);
        +		}
        +	}
        +
        +int ssl23_peek(SSL *s, void *buf, int len)
        +	{
        +	int n;
        +
        +	clear_sys_error();
        +	if (SSL_in_init(s) && (!s->in_handshake))
        +		{
        +		n=s->handshake_func(s);
        +		if (n < 0) return(n);
        +		if (n == 0)
        +			{
        +			SSLerr(SSL_F_SSL23_PEEK,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		return(SSL_peek(s,buf,len));
        +		}
        +	else
        +		{
        +		ssl_undefined_function(s);
        +		return(-1);
        +		}
        +	}
        +
        +int ssl23_write(SSL *s, const void *buf, int len)
        +	{
        +	int n;
        +
        +	clear_sys_error();
        +	if (SSL_in_init(s) && (!s->in_handshake))
        +		{
        +		n=s->handshake_func(s);
        +		if (n < 0) return(n);
        +		if (n == 0)
        +			{
        +			SSLerr(SSL_F_SSL23_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		return(SSL_write(s,buf,len));
        +		}
        +	else
        +		{
        +		ssl_undefined_function(s);
        +		return(-1);
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/ssl/s23_meth.c b/vendor/openssl/openssl/ssl/s23_meth.c
        new file mode 100644
        index 000000000..40eae0f0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s23_meth.c
        @@ -0,0 +1,92 @@
        +/* ssl/s23_meth.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +static const SSL_METHOD *ssl23_get_method(int ver);
        +static const SSL_METHOD *ssl23_get_method(int ver)
        +	{
        +#ifndef OPENSSL_NO_SSL2
        +	if (ver == SSL2_VERSION)
        +		return(SSLv2_method());
        +	else
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +	if (ver == SSL3_VERSION)
        +		return(SSLv3_method());
        +	else
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +	if (ver == TLS1_VERSION)
        +		return(TLSv1_method());
        +	else if (ver == TLS1_1_VERSION)
        +		return(TLSv1_1_method());
        +	else if (ver == TLS1_2_VERSION)
        +		return(TLSv1_2_method());
        +	else
        +#endif
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl23_meth_func(SSLv23_method,
        +			ssl23_accept,
        +			ssl23_connect,
        +			ssl23_get_method)
        +
        diff --git a/vendor/openssl/openssl/ssl/s23_pkt.c b/vendor/openssl/openssl/ssl/s23_pkt.c
        new file mode 100644
        index 000000000..4ca6a1b25
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s23_pkt.c
        @@ -0,0 +1,117 @@
        +/* ssl/s23_pkt.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "ssl_locl.h"
        +#include <openssl/evp.h>
        +#include <openssl/buffer.h>
        +
        +int ssl23_write_bytes(SSL *s)
        +	{
        +	int i,num,tot;
        +	char *buf;
        +
        +	buf=s->init_buf->data;
        +	tot=s->init_off;
        +	num=s->init_num;
        +	for (;;)
        +		{
        +		s->rwstate=SSL_WRITING;
        +		i=BIO_write(s->wbio,&(buf[tot]),num);
        +		if (i <= 0)
        +			{
        +			s->init_off=tot;
        +			s->init_num=num;
        +			return(i);
        +			}
        +		s->rwstate=SSL_NOTHING;
        +		if (i == num) return(tot+i);
        +
        +		num-=i;
        +		tot+=i;
        +		}
        +	}
        +
        +/* return regularly only when we have read (at least) 'n' bytes */
        +int ssl23_read_bytes(SSL *s, int n)
        +	{
        +	unsigned char *p;
        +	int j;
        +
        +	if (s->packet_length < (unsigned int)n)
        +		{
        +		p=s->packet;
        +
        +		for (;;)
        +			{
        +			s->rwstate=SSL_READING;
        +			j=BIO_read(s->rbio,(char *)&(p[s->packet_length]),
        +				n-s->packet_length);
        +			if (j <= 0)
        +				return(j);
        +			s->rwstate=SSL_NOTHING;
        +			s->packet_length+=j;
        +			if (s->packet_length >= (unsigned int)n)
        +				return(s->packet_length);
        +			}
        +		}
        +	return(n);
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/s23_srvr.c b/vendor/openssl/openssl/ssl/s23_srvr.c
        new file mode 100644
        index 000000000..487784901
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s23_srvr.c
        @@ -0,0 +1,638 @@
        +/* ssl/s23_srvr.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-2006 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 <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +
        +static const SSL_METHOD *ssl23_get_server_method(int ver);
        +int ssl23_get_client_hello(SSL *s);
        +static const SSL_METHOD *ssl23_get_server_method(int ver)
        +	{
        +#ifndef OPENSSL_NO_SSL2
        +	if (ver == SSL2_VERSION)
        +		return(SSLv2_server_method());
        +#endif
        +	if (ver == SSL3_VERSION)
        +		return(SSLv3_server_method());
        +	else if (ver == TLS1_VERSION)
        +		return(TLSv1_server_method());
        +	else if (ver == TLS1_1_VERSION)
        +		return(TLSv1_1_server_method());
        +	else if (ver == TLS1_2_VERSION)
        +		return(TLSv1_2_server_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl23_meth_func(SSLv23_server_method,
        +			ssl23_accept,
        +			ssl_undefined_function,
        +			ssl23_get_server_method)
        +
        +int ssl23_accept(SSL *s)
        +	{
        +	BUF_MEM *buf;
        +	unsigned long Time=(unsigned long)time(NULL);
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int ret= -1;
        +	int new_state,state;
        +
        +	RAND_add(&Time,sizeof(Time),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +	
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch(s->state)
        +			{
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_ACCEPT:
        +		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
        +		case SSL_ST_OK|SSL_ST_ACCEPT:
        +
        +			s->server=1;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			/* s->version=SSL3_VERSION; */
        +			s->type=SSL_ST_ACCEPT;
        +
        +			if (s->init_buf == NULL)
        +				{
        +				if ((buf=BUF_MEM_new()) == NULL)
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				s->init_buf=buf;
        +				}
        +
        +			ssl3_init_finished_mac(s);
        +
        +			s->state=SSL23_ST_SR_CLNT_HELLO_A;
        +			s->ctx->stats.sess_accept++;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL23_ST_SR_CLNT_HELLO_A:
        +		case SSL23_ST_SR_CLNT_HELLO_B:
        +
        +			s->shutdown=0;
        +			ret=ssl23_get_client_hello(s);
        +			if (ret >= 0) cb=NULL;
        +			goto end;
        +			/* break; */
        +
        +		default:
        +			SSLerr(SSL_F_SSL23_ACCEPT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* break; */
        +			}
        +
        +		if ((cb != NULL) && (s->state != state))
        +			{
        +			new_state=s->state;
        +			s->state=state;
        +			cb(s,SSL_CB_ACCEPT_LOOP,1);
        +			s->state=new_state;
        +			}
        +		}
        +end:
        +	s->in_handshake--;
        +	if (cb != NULL)
        +		cb(s,SSL_CB_ACCEPT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +
        +int ssl23_get_client_hello(SSL *s)
        +	{
        +	char buf_space[11]; /* Request this many bytes in initial read.
        +	                     * We can detect SSL 3.0/TLS 1.0 Client Hellos
        +	                     * ('type == 3') correctly only when the following
        +	                     * is in a single record, which is not guaranteed by
        +	                     * the protocol specification:
        +	                     * Byte  Content
        +	                     *  0     type            \
        +	                     *  1/2   version          > record header
        +	                     *  3/4   length          /
        +	                     *  5     msg_type        \
        +	                     *  6-8   length           > Client Hello message
        +	                     *  9/10  client_version  /
        +	                     */
        +	char *buf= &(buf_space[0]);
        +	unsigned char *p,*d,*d_len,*dd;
        +	unsigned int i;
        +	unsigned int csl,sil,cl;
        +	int n=0,j;
        +	int type=0;
        +	int v[2];
        +
        +	if (s->state ==	SSL23_ST_SR_CLNT_HELLO_A)
        +		{
        +		/* read the initial header */
        +		v[0]=v[1]=0;
        +
        +		if (!ssl3_setup_buffers(s)) goto err;
        +
        +		n=ssl23_read_bytes(s, sizeof buf_space);
        +		if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */
        +
        +		p=s->packet;
        +
        +		memcpy(buf,p,n);
        +
        +		if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO))
        +			{
        +			/*
        +			 * SSLv2 header
        +			 */
        +			if ((p[3] == 0x00) && (p[4] == 0x02))
        +				{
        +				v[0]=p[3]; v[1]=p[4];
        +				/* SSLv2 */
        +				if (!(s->options & SSL_OP_NO_SSLv2))
        +					type=1;
        +				}
        +			else if (p[3] == SSL3_VERSION_MAJOR)
        +				{
        +				v[0]=p[3]; v[1]=p[4];
        +				/* SSLv3/TLSv1 */
        +				if (p[4] >= TLS1_VERSION_MINOR)
        +					{
        +					if (p[4] >= TLS1_2_VERSION_MINOR &&
        +					   !(s->options & SSL_OP_NO_TLSv1_2))
        +						{
        +						s->version=TLS1_2_VERSION;
        +						s->state=SSL23_ST_SR_CLNT_HELLO_B;
        +						}
        +					else if (p[4] >= TLS1_1_VERSION_MINOR &&
        +					   !(s->options & SSL_OP_NO_TLSv1_1))
        +						{
        +						s->version=TLS1_1_VERSION;
        +						/* type=2; */ /* done later to survive restarts */
        +						s->state=SSL23_ST_SR_CLNT_HELLO_B;
        +						}
        +					else if (!(s->options & SSL_OP_NO_TLSv1))
        +						{
        +						s->version=TLS1_VERSION;
        +						/* type=2; */ /* done later to survive restarts */
        +						s->state=SSL23_ST_SR_CLNT_HELLO_B;
        +						}
        +					else if (!(s->options & SSL_OP_NO_SSLv3))
        +						{
        +						s->version=SSL3_VERSION;
        +						/* type=2; */
        +						s->state=SSL23_ST_SR_CLNT_HELLO_B;
        +						}
        +					else if (!(s->options & SSL_OP_NO_SSLv2))
        +						{
        +						type=1;
        +						}
        +					}
        +				else if (!(s->options & SSL_OP_NO_SSLv3))
        +					{
        +					s->version=SSL3_VERSION;
        +					/* type=2; */
        +					s->state=SSL23_ST_SR_CLNT_HELLO_B;
        +					}
        +				else if (!(s->options & SSL_OP_NO_SSLv2))
        +					type=1;
        +
        +				}
        +			}
        +		else if ((p[0] == SSL3_RT_HANDSHAKE) &&
        +			 (p[1] == SSL3_VERSION_MAJOR) &&
        +			 (p[5] == SSL3_MT_CLIENT_HELLO) &&
        +			 ((p[3] == 0 && p[4] < 5 /* silly record length? */)
        +				|| (p[9] >= p[1])))
        +			{
        +			/*
        +			 * SSLv3 or tls1 header
        +			 */
        +			
        +			v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */
        +			/* We must look at client_version inside the Client Hello message
        +			 * to get the correct minor version.
        +			 * However if we have only a pathologically small fragment of the
        +			 * Client Hello message, this would be difficult, and we'd have
        +			 * to read more records to find out.
        +			 * No known SSL 3.0 client fragments ClientHello like this,
        +			 * so we simply assume TLS 1.0 to avoid protocol version downgrade
        +			 * attacks. */
        +			if (p[3] == 0 && p[4] < 6)
        +				{
        +#if 0
        +				SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
        +				goto err;
        +#else
        +				v[1] = TLS1_VERSION_MINOR;
        +#endif
        +				}
        +			/* if major version number > 3 set minor to a value
        +			 * which will use the highest version 3 we support.
        +			 * If TLS 2.0 ever appears we will need to revise
        +			 * this....
        +			 */
        +			else if (p[9] > SSL3_VERSION_MAJOR)
        +				v[1]=0xff;
        +			else
        +				v[1]=p[10]; /* minor version according to client_version */
        +			if (v[1] >= TLS1_VERSION_MINOR)
        +				{
        +				if (v[1] >= TLS1_2_VERSION_MINOR &&
        +					!(s->options & SSL_OP_NO_TLSv1_2))
        +					{
        +					s->version=TLS1_2_VERSION;
        +					type=3;
        +					}
        +				else if (v[1] >= TLS1_1_VERSION_MINOR &&
        +					!(s->options & SSL_OP_NO_TLSv1_1))
        +					{
        +					s->version=TLS1_1_VERSION;
        +					type=3;
        +					}
        +				else if (!(s->options & SSL_OP_NO_TLSv1))
        +					{
        +					s->version=TLS1_VERSION;
        +					type=3;
        +					}
        +				else if (!(s->options & SSL_OP_NO_SSLv3))
        +					{
        +					s->version=SSL3_VERSION;
        +					type=3;
        +					}
        +				}
        +			else
        +				{
        +				/* client requests SSL 3.0 */
        +				if (!(s->options & SSL_OP_NO_SSLv3))
        +					{
        +					s->version=SSL3_VERSION;
        +					type=3;
        +					}
        +				else if (!(s->options & SSL_OP_NO_TLSv1))
        +					{
        +					/* we won't be able to use TLS of course,
        +					 * but this will send an appropriate alert */
        +					s->version=TLS1_VERSION;
        +					type=3;
        +					}
        +				}
        +			}
        +		else if ((strncmp("GET ", (char *)p,4) == 0) ||
        +			 (strncmp("POST ",(char *)p,5) == 0) ||
        +			 (strncmp("HEAD ",(char *)p,5) == 0) ||
        +			 (strncmp("PUT ", (char *)p,4) == 0))
        +			{
        +			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST);
        +			goto err;
        +			}
        +		else if (strncmp("CONNECT",(char *)p,7) == 0)
        +			{
        +			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST);
        +			goto err;
        +			}
        +		}
        +
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && (s->version < TLS1_VERSION))
        +		{
        +		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
        +					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
        +		goto err;
        +		}
        +#endif
        +
        +	if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
        +		{
        +		/* we have SSLv3/TLSv1 in an SSLv2 header
        +		 * (other cases skip this state) */
        +
        +		type=2;
        +		p=s->packet;
        +		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
        +		v[1] = p[4];
        +
        +		n=((p[0]&0x7f)<<8)|p[1];
        +		if (n > (1024*4))
        +			{
        +			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
        +			goto err;
        +			}
        +
        +		j=ssl23_read_bytes(s,n+2);
        +		if (j <= 0) return(j);
        +
        +		ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
        +		if (s->msg_callback)
        +			s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */
        +
        +		p=s->packet;
        +		p+=5;
        +		n2s(p,csl);
        +		n2s(p,sil);
        +		n2s(p,cl);
        +		d=(unsigned char *)s->init_buf->data;
        +		if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format
        +		                                          * Client Hello, can we? Error condition should be
        +		                                          * '>' otherweise */
        +			{
        +			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH);
        +			goto err;
        +			}
        +
        +		/* record header: msg_type ... */
        +		*(d++) = SSL3_MT_CLIENT_HELLO;
        +		/* ... and length (actual value will be written later) */
        +		d_len = d;
        +		d += 3;
        +
        +		/* client_version */
        +		*(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
        +		*(d++) = v[1];
        +
        +		/* lets populate the random area */
        +		/* get the challenge_length */
        +		i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl;
        +		memset(d,0,SSL3_RANDOM_SIZE);
        +		memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i);
        +		d+=SSL3_RANDOM_SIZE;
        +
        +		/* no session-id reuse */
        +		*(d++)=0;
        +
        +		/* ciphers */
        +		j=0;
        +		dd=d;
        +		d+=2;
        +		for (i=0; i<csl; i+=3)
        +			{
        +			if (p[i] != 0) continue;
        +			*(d++)=p[i+1];
        +			*(d++)=p[i+2];
        +			j+=2;
        +			}
        +		s2n(j,dd);
        +
        +		/* COMPRESSION */
        +		*(d++)=1;
        +		*(d++)=0;
        +		
        +#if 0
        +                /* copy any remaining data with may be extensions */
        +	        p = p+csl+sil+cl;
        +		while (p <  s->packet+s->packet_length)
        +			{
        +			*(d++)=*(p++);
        +			}
        +#endif
        +
        +		i = (d-(unsigned char *)s->init_buf->data) - 4;
        +		l2n3((long)i, d_len);
        +
        +		/* get the data reused from the init_buf */
        +		s->s3->tmp.reuse_message=1;
        +		s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO;
        +		s->s3->tmp.message_size=i;
        +		}
        +
        +	/* imaginary new state (for program structure): */
        +	/* s->state = SSL23_SR_CLNT_HELLO_C */
        +
        +	if (type == 1)
        +		{
        +#ifdef OPENSSL_NO_SSL2
        +		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
        +		goto err;
        +#else
        +		/* we are talking sslv2 */
        +		/* we need to clean up the SSLv3/TLSv1 setup and put in the
        +		 * sslv2 stuff. */
        +
        +		if (s->s2 == NULL)
        +			{
        +			if (!ssl2_new(s))
        +				goto err;
        +			}
        +		else
        +			ssl2_clear(s);
        +
        +		if (s->s3 != NULL) ssl3_free(s);
        +
        +		if (!BUF_MEM_grow_clean(s->init_buf,
        +			SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
        +			{
        +			goto err;
        +			}
        +
        +		s->state=SSL2_ST_GET_CLIENT_HELLO_A;
        +		if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3)
        +			s->s2->ssl2_rollback=0;
        +		else
        +			/* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0
        +			 * (SSL 3.0 draft/RFC 2246, App. E.2) */
        +			s->s2->ssl2_rollback=1;
        +
        +		/* setup the n bytes we have read so we get them from
        +		 * the sslv2 buffer */
        +		s->rstate=SSL_ST_READ_HEADER;
        +		s->packet_length=n;
        +		s->packet= &(s->s2->rbuf[0]);
        +		memcpy(s->packet,buf,n);
        +		s->s2->rbuf_left=n;
        +		s->s2->rbuf_offs=0;
        +
        +		s->method=SSLv2_server_method();
        +		s->handshake_func=s->method->ssl_accept;
        +#endif
        +		}
        +
        +	if ((type == 2) || (type == 3))
        +		{
        +		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
        +
        +		if (!ssl_init_wbio_buffer(s,1)) goto err;
        +
        +		/* we are in this state */
        +		s->state=SSL3_ST_SR_CLNT_HELLO_A;
        +
        +		if (type == 3)
        +			{
        +			/* put the 'n' bytes we have read into the input buffer
        +			 * for SSLv3 */
        +			s->rstate=SSL_ST_READ_HEADER;
        +			s->packet_length=n;
        +			if (s->s3->rbuf.buf == NULL)
        +				if (!ssl3_setup_read_buffer(s))
        +					goto err;
        +
        +			s->packet= &(s->s3->rbuf.buf[0]);
        +			memcpy(s->packet,buf,n);
        +			s->s3->rbuf.left=n;
        +			s->s3->rbuf.offset=0;
        +			}
        +		else
        +			{
        +			s->packet_length=0;
        +			s->s3->rbuf.left=0;
        +			s->s3->rbuf.offset=0;
        +			}
        +		if (s->version == TLS1_2_VERSION)
        +			s->method = TLSv1_2_server_method();
        +		else if (s->version == TLS1_1_VERSION)
        +			s->method = TLSv1_1_server_method();
        +		else if (s->version == TLS1_VERSION)
        +			s->method = TLSv1_server_method();
        +		else
        +			s->method = SSLv3_server_method();
        +#if 0 /* ssl3_get_client_hello does this */
        +		s->client_version=(v[0]<<8)|v[1];
        +#endif
        +		s->handshake_func=s->method->ssl_accept;
        +		}
        +	
        +	if ((type < 1) || (type > 3))
        +		{
        +		/* bad, very bad */
        +		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL);
        +		goto err;
        +		}
        +	s->init_num=0;
        +
        +	if (buf != buf_space) OPENSSL_free(buf);
        +	return(SSL_accept(s));
        +err:
        +	if (buf != buf_space) OPENSSL_free(buf);
        +	return(-1);
        +	}
        diff --git a/vendor/openssl/openssl/ssl/s2_clnt.c b/vendor/openssl/openssl/ssl/s2_clnt.c
        new file mode 100644
        index 000000000..03b6cf967
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s2_clnt.c
        @@ -0,0 +1,1127 @@
        +/* ssl/s2_clnt.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_SSL2
        +#include <stdio.h>
        +#include <openssl/rand.h>
        +#include <openssl/buffer.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +
        +static const SSL_METHOD *ssl2_get_client_method(int ver);
        +static int get_server_finished(SSL *s);
        +static int get_server_verify(SSL *s);
        +static int get_server_hello(SSL *s);
        +static int client_hello(SSL *s); 
        +static int client_master_key(SSL *s);
        +static int client_finished(SSL *s);
        +static int client_certificate(SSL *s);
        +static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
        +	unsigned char *to,int padding);
        +#define BREAK	break
        +
        +static const SSL_METHOD *ssl2_get_client_method(int ver)
        +	{
        +	if (ver == SSL2_VERSION)
        +		return(SSLv2_client_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl2_meth_func(SSLv2_client_method,
        +			ssl_undefined_function,
        +			ssl2_connect,
        +			ssl2_get_client_method)
        +
        +int ssl2_connect(SSL *s)
        +	{
        +	unsigned long l=(unsigned long)time(NULL);
        +	BUF_MEM *buf=NULL;
        +	int ret= -1;
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int new_state,state;
        +
        +	RAND_add(&l,sizeof(l),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +
        +	/* init things to blank */
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch (s->state)
        +			{
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_CONNECT:
        +		case SSL_ST_BEFORE|SSL_ST_CONNECT:
        +		case SSL_ST_OK|SSL_ST_CONNECT:
        +
        +			s->server=0;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			s->version=SSL2_VERSION;
        +			s->type=SSL_ST_CONNECT;
        +
        +			buf=s->init_buf;
        +			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			if (!BUF_MEM_grow(buf,
        +				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
        +				{
        +				if (buf == s->init_buf)
        +					buf=NULL;
        +				ret= -1;
        +				goto end;
        +				}
        +			s->init_buf=buf;
        +			buf=NULL;
        +			s->init_num=0;
        +			s->state=SSL2_ST_SEND_CLIENT_HELLO_A;
        +			s->ctx->stats.sess_connect++;
        +			s->handshake_func=ssl2_connect;
        +			BREAK;
        +
        +		case SSL2_ST_SEND_CLIENT_HELLO_A:
        +		case SSL2_ST_SEND_CLIENT_HELLO_B:
        +			s->shutdown=0;
        +			ret=client_hello(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_GET_SERVER_HELLO_A;
        +			BREAK;
        +		
        +		case SSL2_ST_GET_SERVER_HELLO_A:
        +		case SSL2_ST_GET_SERVER_HELLO_B:
        +			ret=get_server_hello(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			if (!s->hit) /* new session */
        +				{
        +				s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_A;
        +				BREAK; 
        +				}
        +			else
        +				{
        +				s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
        +				break;
        +				}
        +	
        +		case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:
        +		case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:
        +			ret=client_master_key(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
        +			break;
        +
        +		case SSL2_ST_CLIENT_START_ENCRYPTION:
        +			/* Ok, we now have all the stuff needed to
        +			 * start encrypting, so lets fire it up :-) */
        +			if (!ssl2_enc_init(s,1))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			s->s2->clear_text=0;
        +			s->state=SSL2_ST_SEND_CLIENT_FINISHED_A;
        +			break;
        +
        +		case SSL2_ST_SEND_CLIENT_FINISHED_A:
        +		case SSL2_ST_SEND_CLIENT_FINISHED_B:
        +			ret=client_finished(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_GET_SERVER_VERIFY_A;
        +			break;
        +
        +		case SSL2_ST_GET_SERVER_VERIFY_A:
        +		case SSL2_ST_GET_SERVER_VERIFY_B:
        +			ret=get_server_verify(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_GET_SERVER_FINISHED_A;
        +			break;
        +
        +		case SSL2_ST_GET_SERVER_FINISHED_A:
        +		case SSL2_ST_GET_SERVER_FINISHED_B:
        +			ret=get_server_finished(s);
        +			if (ret <= 0) goto end;
        +			break;
        +
        +		case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:
        +		case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:
        +		case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:
        +		case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:
        +		case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:
        +			ret=client_certificate(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_GET_SERVER_FINISHED_A;
        +			break;
        +
        +		case SSL_ST_OK:
        +			if (s->init_buf != NULL)
        +				{
        +				BUF_MEM_free(s->init_buf);
        +				s->init_buf=NULL;
        +				}
        +			s->init_num=0;
        +		/*	ERR_clear_error();*/
        +
        +			/* If we want to cache session-ids in the client
        +			 * and we successfully add the session-id to the
        +			 * cache, and there is a callback, then pass it out.
        +			 * 26/11/96 - eay - only add if not a re-used session.
        +			 */
        +
        +			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
        +			if (s->hit) s->ctx->stats.sess_hit++;
        +
        +			ret=1;
        +			/* s->server=0; */
        +			s->ctx->stats.sess_connect_good++;
        +
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
        +
        +			goto end;
        +			/* break; */
        +		default:
        +			SSLerr(SSL_F_SSL2_CONNECT,SSL_R_UNKNOWN_STATE);
        +			return(-1);
        +			/* break; */
        +			}
        +
        +		if ((cb != NULL) && (s->state != state))
        +			{
        +			new_state=s->state;
        +			s->state=state;
        +			cb(s,SSL_CB_CONNECT_LOOP,1);
        +			s->state=new_state;
        +			}
        +		}
        +end:
        +	s->in_handshake--;
        +	if (buf != NULL)
        +		BUF_MEM_free(buf);
        +	if (cb != NULL) 
        +		cb(s,SSL_CB_CONNECT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +static int get_server_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p;
        +	int i,j;
        +	unsigned long len;
        +	STACK_OF(SSL_CIPHER) *sk=NULL,*cl, *prio, *allow;
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	p=buf;
        +	if (s->state == SSL2_ST_GET_SERVER_HELLO_A)
        +		{
        +		i=ssl2_read(s,(char *)&(buf[s->init_num]),11-s->init_num);
        +		if (i < (11-s->init_num)) 
        +			return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
        +		s->init_num = 11;
        +
        +		if (*(p++) != SSL2_MT_SERVER_HELLO)
        +			{
        +			if (p[-1] != SSL2_MT_ERROR)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_SERVER_HELLO,
        +					SSL_R_READ_WRONG_PACKET_TYPE);
        +				}
        +			else
        +				SSLerr(SSL_F_GET_SERVER_HELLO,
        +					SSL_R_PEER_ERROR);
        +			return(-1);
        +			}
        +#if 0
        +		s->hit=(*(p++))?1:0;
        +		/* Some [PPC?] compilers fail to increment p in above
        +		   statement, e.g. one provided with Rhapsody 5.5, but
        +		   most recent example XL C 11.1 for AIX, even without
        +		   optimization flag... */
        +#else
        +		s->hit=(*p)?1:0; p++;
        +#endif
        +		s->s2->tmp.cert_type= *(p++);
        +		n2s(p,i);
        +		if (i < s->version) s->version=i;
        +		n2s(p,i); s->s2->tmp.cert_length=i;
        +		n2s(p,i); s->s2->tmp.csl=i;
        +		n2s(p,i); s->s2->tmp.conn_id_length=i;
        +		s->state=SSL2_ST_GET_SERVER_HELLO_B;
        +		}
        +
        +	/* SSL2_ST_GET_SERVER_HELLO_B */
        +	len = 11 + (unsigned long)s->s2->tmp.cert_length + (unsigned long)s->s2->tmp.csl + (unsigned long)s->s2->tmp.conn_id_length;
        +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
        +		{
        +		SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_MESSAGE_TOO_LONG);
        +		return -1;
        +		}
        +	j = (int)len - s->init_num;
        +	i = ssl2_read(s,(char *)&(buf[s->init_num]),j);
        +	if (i != j) return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, buf, (size_t)len, s, s->msg_callback_arg); /* SERVER-HELLO */
        +
        +	/* things are looking good */
        +
        +	p = buf + 11;
        +	if (s->hit)
        +		{
        +		if (s->s2->tmp.cert_length != 0) 
        +			{
        +			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);
        +			return(-1);
        +			}
        +		if (s->s2->tmp.cert_type != 0)
        +			{
        +			if (!(s->options &
        +				SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG))
        +				{
        +				SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO);
        +				return(-1);
        +				}
        +			}
        +		if (s->s2->tmp.csl != 0)
        +			{
        +			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);
        +			return(-1);
        +			}
        +		}
        +	else
        +		{
        +#ifdef undef
        +		/* very bad */
        +		memset(s->session->session_id,0,
        +			SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);
        +		s->session->session_id_length=0;
        +		*/
        +#endif
        +
        +		/* we need to do this in case we were trying to reuse a 
        +		 * client session but others are already reusing it.
        +		 * If this was a new 'blank' session ID, the session-id
        +		 * length will still be 0 */
        +		if (s->session->session_id_length > 0)
        +			{
        +			if (!ssl_get_new_session(s,0))
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				return(-1);
        +				}
        +			}
        +
        +		if (ssl2_set_certificate(s,s->s2->tmp.cert_type,
        +			s->s2->tmp.cert_length,p) <= 0)
        +			{
        +			ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
        +			return(-1);
        +			}
        +		p+=s->s2->tmp.cert_length;
        +
        +		if (s->s2->tmp.csl == 0)
        +			{
        +			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
        +			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_LIST);
        +			return(-1);
        +			}
        +
        +		/* We have just received a list of ciphers back from the
        +		 * server.  We need to get the ones that match, then select
        +		 * the one we want the most :-). */
        +
        +		/* load the ciphers */
        +		sk=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.csl,
        +					    &s->session->ciphers);
        +		p+=s->s2->tmp.csl;
        +		if (sk == NULL)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_GET_SERVER_HELLO,ERR_R_MALLOC_FAILURE);
        +			return(-1);
        +			}
        +
        +		(void)sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp);
        +
        +		/* get the array of ciphers we will accept */
        +		cl=SSL_get_ciphers(s);
        +		(void)sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp);
        +
        +		/*
        +		 * If server preference flag set, choose the first
        +		 * (highest priority) cipher the server sends, otherwise
        +		 * client preference has priority.
        +		 */
        +		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
        +		    {
        +		    prio = sk;
        +		    allow = cl;
        +		    }
        +		else
        +		    {
        +		    prio = cl;
        +		    allow = sk;
        +		    }
        +		/* In theory we could have ciphers sent back that we
        +		 * don't want to use but that does not matter since we
        +		 * will check against the list we originally sent and
        +		 * for performance reasons we should not bother to match
        +		 * the two lists up just to check. */
        +		for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
        +			{
        +			if (sk_SSL_CIPHER_find(allow,
        +					     sk_SSL_CIPHER_value(prio,i)) >= 0)
        +				break;
        +			}
        +
        +		if (i >= sk_SSL_CIPHER_num(prio))
        +			{
        +			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
        +			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_MATCH);
        +			return(-1);
        +			}
        +		s->session->cipher=sk_SSL_CIPHER_value(prio,i);
        +
        +
        +		if (s->session->peer != NULL) /* can't happen*/
        +			{
        +			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
        +			return(-1);
        +			}
        +
        +		s->session->peer = s->session->sess_cert->peer_key->x509;
        +		/* peer_key->x509 has been set by ssl2_set_certificate. */
        +		CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
        +		}
        +
        +	if (s->session->sess_cert == NULL 
        +      || s->session->peer != s->session->sess_cert->peer_key->x509)
        +		/* can't happen */
        +		{
        +		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
        +		return(-1);
        +		}
        +		
        +	s->s2->conn_id_length=s->s2->tmp.conn_id_length;
        +	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
        +		{
        +		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG);
        +		return -1;
        +		}
        +	memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
        +	return(1);
        +	}
        +
        +static int client_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +/*	CIPHER **cipher;*/
        +	int i,n,j;
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A)
        +		{
        +		if ((s->session == NULL) ||
        +			(s->session->ssl_version != s->version))
        +			{
        +			if (!ssl_get_new_session(s,0))
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				return(-1);
        +				}
        +			}
        +		/* else use the pre-loaded session */
        +
        +		p=buf;					/* header */
        +		d=p+9;					/* data section */
        +		*(p++)=SSL2_MT_CLIENT_HELLO;		/* type */
        +		s2n(SSL2_VERSION,p);			/* version */
        +		n=j=0;
        +
        +		n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d,0);
        +		d+=n;
        +
        +		if (n == 0)
        +			{
        +			SSLerr(SSL_F_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
        +			return(-1);
        +			}
        +
        +		s2n(n,p);			/* cipher spec num bytes */
        +
        +		if ((s->session->session_id_length > 0) &&
        +			(s->session->session_id_length <=
        +			SSL2_MAX_SSL_SESSION_ID_LENGTH))
        +			{
        +			i=s->session->session_id_length;
        +			s2n(i,p);		/* session id length */
        +			memcpy(d,s->session->session_id,(unsigned int)i);
        +			d+=i;
        +			}
        +		else
        +			{
        +			s2n(0,p);
        +			}
        +
        +		s->s2->challenge_length=SSL2_CHALLENGE_LENGTH;
        +		s2n(SSL2_CHALLENGE_LENGTH,p);		/* challenge length */
        +		/*challenge id data*/
        +		if (RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH) <= 0)
        +			return -1;
        +		memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH);
        +		d+=SSL2_CHALLENGE_LENGTH;
        +
        +		s->state=SSL2_ST_SEND_CLIENT_HELLO_B;
        +		s->init_num=d-buf;
        +		s->init_off=0;
        +		}
        +	/* SSL2_ST_SEND_CLIENT_HELLO_B */
        +	return(ssl2_do_write(s));
        +	}
        +
        +static int client_master_key(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	int clear,enc,karg,i;
        +	SSL_SESSION *sess;
        +	const EVP_CIPHER *c;
        +	const EVP_MD *md;
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
        +		{
        +
        +		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
        +			{
        +			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
        +			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
        +			return(-1);
        +			}
        +		sess=s->session;
        +		p=buf;
        +		d=p+10;
        +		*(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */
        +
        +		i=ssl_put_cipher_by_char(s,sess->cipher,p);
        +		p+=i;
        +
        +		/* make key_arg data */
        +		i=EVP_CIPHER_iv_length(c);
        +		sess->key_arg_length=i;
        +		if (i > SSL_MAX_KEY_ARG_LENGTH)
        +			{
        +			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		if (i > 0)
        +			if (RAND_pseudo_bytes(sess->key_arg,i) <= 0)
        +				return -1;
        +
        +		/* make a master key */
        +		i=EVP_CIPHER_key_length(c);
        +		sess->master_key_length=i;
        +		if (i > 0)
        +			{
        +			if (i > (int)sizeof(sess->master_key))
        +				{
        +				ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
        +				return -1;
        +				}
        +			if (RAND_bytes(sess->master_key,i) <= 0)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				return(-1);
        +				}
        +			}
        +
        +		if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
        +			enc=8;
        +		else if (SSL_C_IS_EXPORT(sess->cipher))
        +			enc=5;
        +		else
        +			enc=i;
        +
        +		if ((int)i < enc)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR);
        +			return(-1);
        +			}
        +		clear=i-enc;
        +		s2n(clear,p);
        +		memcpy(d,sess->master_key,(unsigned int)clear);
        +		d+=clear;
        +
        +		enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
        +			&(sess->master_key[clear]),d,
        +			(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
        +		if (enc <= 0)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR);
        +			return(-1);
        +			}
        +#ifdef PKCS1_CHECK
        +		if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++;
        +		if (s->options & SSL_OP_PKCS1_CHECK_2)
        +			sess->master_key[clear]++;
        +#endif
        +		s2n(enc,p);
        +		d+=enc;
        +		karg=sess->key_arg_length;	
        +		s2n(karg,p); /* key arg size */
        +		if (karg > (int)sizeof(sess->key_arg))
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		memcpy(d,sess->key_arg,(unsigned int)karg);
        +		d+=karg;
        +
        +		s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B;
        +		s->init_num=d-buf;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */
        +	return(ssl2_do_write(s));
        +	}
        +
        +static int client_finished(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*(p++)=SSL2_MT_CLIENT_FINISHED;
        +		if (s->s2->conn_id_length > sizeof s->s2->conn_id)
        +			{
        +			SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		memcpy(p,s->s2->conn_id,(unsigned int)s->s2->conn_id_length);
        +
        +		s->state=SSL2_ST_SEND_CLIENT_FINISHED_B;
        +		s->init_num=s->s2->conn_id_length+1;
        +		s->init_off=0;
        +		}
        +	return(ssl2_do_write(s));
        +	}
        +
        +/* read the data and then respond */
        +static int client_certificate(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	int i;
        +	unsigned int n;
        +	int cert_ch_len;
        +	unsigned char *cert_ch;
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +
        +	/* We have a cert associated with the SSL, so attach it to
        +	 * the session if it does not have one */
        +
        +	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A)
        +		{
        +		i=ssl2_read(s,(char *)&(buf[s->init_num]),
        +			SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num);
        +		if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num))
        +			return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i));
        +		s->init_num += i;
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */
        +
        +		/* type=buf[0]; */
        +		/* type eq x509 */
        +		if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
        +			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE);
        +			return(-1);
        +			}
        +
        +		if ((s->cert == NULL) ||
        +			(s->cert->key->x509 == NULL) ||
        +			(s->cert->key->privatekey == NULL))
        +			{
        +			s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
        +			}
        +		else
        +			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
        +		}
        +
        +	cert_ch = buf + 2;
        +	cert_ch_len = s->init_num - 2;
        +
        +	if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE)
        +		{
        +		X509 *x509=NULL;
        +		EVP_PKEY *pkey=NULL;
        +
        +		/* If we get an error we need to
        +		 * ssl->rwstate=SSL_X509_LOOKUP;
        +		 * return(error);
        +		 * We should then be retried when things are ok and we
        +		 * can get a cert or not */
        +
        +		i=0;
        +		if (s->ctx->client_cert_cb != NULL)
        +			{
        +			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
        +			}
        +
        +		if (i < 0)
        +			{
        +			s->rwstate=SSL_X509_LOOKUP;
        +			return(-1);
        +			}
        +		s->rwstate=SSL_NOTHING;
        +
        +		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
        +			{
        +			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
        +			if (	!SSL_use_certificate(s,x509) || 
        +				!SSL_use_PrivateKey(s,pkey))
        +				{
        +				i=0;
        +				}
        +			X509_free(x509);
        +			EVP_PKEY_free(pkey);
        +			}
        +		else if (i == 1)
        +			{
        +			if (x509 != NULL) X509_free(x509);
        +			if (pkey != NULL) EVP_PKEY_free(pkey);
        +			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
        +			i=0;
        +			}
        +
        +		if (i == 0)
        +			{
        +			/* We have no client certificate to respond with
        +			 * so send the correct error message back */
        +			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
        +			p=buf;
        +			*(p++)=SSL2_MT_ERROR;
        +			s2n(SSL2_PE_NO_CERTIFICATE,p);
        +			s->init_off=0;
        +			s->init_num=3;
        +			/* Write is done at the end */
        +			}
        +		}
        +
        +	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
        +		{
        +		return(ssl2_do_write(s));
        +		}
        +
        +	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
        +		{
        +		EVP_MD_CTX ctx;
        +
        +		/* ok, now we calculate the checksum
        +		 * do it first so we can reuse buf :-) */
        +		p=buf;
        +		EVP_MD_CTX_init(&ctx);
        +		EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
        +		EVP_SignUpdate(&ctx,s->s2->key_material,
        +			       s->s2->key_material_length);
        +		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
        +		i=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
        +		/* Don't update the signature if it fails - FIXME: probably should handle this better */
        +		if(i > 0)
        +			EVP_SignUpdate(&ctx,buf,(unsigned int)i);
        +
        +		p=buf;
        +		d=p+6;
        +		*(p++)=SSL2_MT_CLIENT_CERTIFICATE;
        +		*(p++)=SSL2_CT_X509_CERTIFICATE;
        +		n=i2d_X509(s->cert->key->x509,&d);
        +		s2n(n,p);
        +
        +		if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
        +			{
        +			/* this is not good.  If things have failed it
        +			 * means there so something wrong with the key.
        +			 * We will continue with a 0 length signature
        +			 */
        +			}
        +		EVP_MD_CTX_cleanup(&ctx);
        +		s2n(n,p);
        +		d+=n;
        +
        +		s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
        +		s->init_num=d-buf;
        +		s->init_off=0;
        +		}
        +	/* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
        +	return(ssl2_do_write(s));
        +	}
        +
        +static int get_server_verify(SSL *s)
        +	{
        +	unsigned char *p;
        +	int i, n, len;
        +
        +	p=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_GET_SERVER_VERIFY_A)
        +		{
        +		i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
        +		if (i < (1-s->init_num)) 
        +			return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
        +		s->init_num += i;
        +
        +		s->state= SSL2_ST_GET_SERVER_VERIFY_B;
        +		if (*p != SSL2_MT_SERVER_VERIFY)
        +			{
        +			if (p[0] != SSL2_MT_ERROR)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_SERVER_VERIFY,
        +					SSL_R_READ_WRONG_PACKET_TYPE);
        +				}
        +			else
        +				{
        +				SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_PEER_ERROR);
        +				/* try to read the error message */
        +				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
        +				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
        +				}
        +			return(-1);
        +			}
        +		}
        +	
        +	p=(unsigned char *)s->init_buf->data;
        +	len = 1 + s->s2->challenge_length;
        +	n =  len - s->init_num;
        +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
        +	if (i < n)
        +		return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
        +	p += 1;
        +
        +	if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
        +		return(-1);
        +		}
        +	return(1);
        +	}
        +
        +static int get_server_finished(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p;
        +	int i, n, len;
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	p=buf;
        +	if (s->state == SSL2_ST_GET_SERVER_FINISHED_A)
        +		{
        +		i=ssl2_read(s,(char *)&(buf[s->init_num]),1-s->init_num);
        +		if (i < (1-s->init_num))
        +			return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
        +		s->init_num += i;
        +
        +		if (*p == SSL2_MT_REQUEST_CERTIFICATE)
        +			{
        +			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_A;
        +			return(1);
        +			}
        +		else if (*p != SSL2_MT_SERVER_FINISHED)
        +			{
        +			if (p[0] != SSL2_MT_ERROR)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
        +				}
        +			else
        +				{
        +				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_PEER_ERROR);
        +				/* try to read the error message */
        +				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
        +				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
        +				}
        +			return(-1);
        +			}
        +		s->state=SSL2_ST_GET_SERVER_FINISHED_B;
        +		}
        +
        +	len = 1 + SSL2_SSL_SESSION_ID_LENGTH;
        +	n = len - s->init_num;
        +	i = ssl2_read(s,(char *)&(buf[s->init_num]), n);
        +	if (i < n) /* XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, that's the maximum */
        +		return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
        +	s->init_num += i;
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* SERVER-FINISHED */
        +
        +	if (!s->hit) /* new session */
        +		{
        +		/* new session-id */
        +		/* Make sure we were not trying to re-use an old SSL_SESSION
        +		 * or bad things can happen */
        +		/* ZZZZZZZZZZZZZ */
        +		s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
        +		memcpy(s->session->session_id,p+1,SSL2_SSL_SESSION_ID_LENGTH);
        +		}
        +	else
        +		{
        +		if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG))
        +			{
        +			if ((s->session->session_id_length > sizeof s->session->session_id)
        +			    || (0 != memcmp(buf + 1, s->session->session_id,
        +			                    (unsigned int)s->session->session_id_length)))
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_SSL_SESSION_ID_IS_DIFFERENT);
        +				return(-1);
        +				}
        +			}
        +		}
        +	s->state = SSL_ST_OK;
        +	return(1);
        +	}
        +
        +/* loads in the certificate from the server */
        +int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
        +	{
        +	STACK_OF(X509) *sk=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	SESS_CERT *sc=NULL;
        +	int i;
        +	X509 *x509=NULL;
        +	int ret=0;
        +	
        +	x509=d2i_X509(NULL,&data,(long)len);
        +	if (x509 == NULL)
        +		{
        +		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB);
        +		goto err;
        +		}
        +
        +	if ((sk=sk_X509_new_null()) == NULL || !sk_X509_push(sk,x509))
        +		{
        +		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	i=ssl_verify_cert_chain(s,sk);
        +		
        +	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
        +		{
        +		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
        +		goto err;
        +		}
        +	ERR_clear_error(); /* but we keep s->verify_result */
        +	s->session->verify_result = s->verify_result;
        +
        +	/* server's cert for this session */
        +	sc=ssl_sess_cert_new();
        +	if (sc == NULL)
        +		{
        +		ret= -1;
        +		goto err;
        +		}
        +	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
        +	s->session->sess_cert=sc;
        +
        +	sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
        +	sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);
        +
        +	pkey=X509_get_pubkey(x509);
        +	x509=NULL;
        +	if (pkey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
        +		goto err;
        +		}
        +	if (pkey->type != EVP_PKEY_RSA)
        +		{
        +		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA);
        +		goto err;
        +		}
        +
        +	if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
        +		goto err;
        +	ret=1;
        +err:
        +	sk_X509_free(sk);
        +	X509_free(x509);
        +	EVP_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
        +	     unsigned char *to, int padding)
        +	{
        +	EVP_PKEY *pkey=NULL;
        +	int i= -1;
        +
        +	if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
        +		((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
        +		{
        +		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
        +		return(-1);
        +		}
        +	if (pkey->type != EVP_PKEY_RSA)
        +		{
        +		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
        +		goto end;
        +		}
        +
        +	/* we have the public key */
        +	i=RSA_public_encrypt(len,from,to,pkey->pkey.rsa,padding);
        +	if (i < 0)
        +		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,ERR_R_RSA_LIB);
        +end:
        +	EVP_PKEY_free(pkey);
        +	return(i);
        +	}
        +#else /* !OPENSSL_NO_SSL2 */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s2_enc.c b/vendor/openssl/openssl/ssl/s2_enc.c
        new file mode 100644
        index 000000000..ff3395f45
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s2_enc.c
        @@ -0,0 +1,193 @@
        +/* ssl/s2_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_SSL2
        +#include <stdio.h>
        +
        +int ssl2_enc_init(SSL *s, int client)
        +	{
        +	/* Max number of bytes needed */
        +	EVP_CIPHER_CTX *rs,*ws;
        +	const EVP_CIPHER *c;
        +	const EVP_MD *md;
        +	int num;
        +
        +	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
        +		{
        +		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
        +		SSLerr(SSL_F_SSL2_ENC_INIT,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
        +		return(0);
        +		}
        +	ssl_replace_hash(&s->read_hash,md);
        +	ssl_replace_hash(&s->write_hash,md);
        +
        +	if ((s->enc_read_ctx == NULL) &&
        +		((s->enc_read_ctx=(EVP_CIPHER_CTX *)
        +		OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL))
        +		goto err;
        +
        +	/* make sure it's intialized in case the malloc for enc_write_ctx fails
        +	 * and we exit with an error */
        +	rs= s->enc_read_ctx;
        +	EVP_CIPHER_CTX_init(rs);
        +
        +	if ((s->enc_write_ctx == NULL) &&
        +		((s->enc_write_ctx=(EVP_CIPHER_CTX *)
        +		OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL))
        +		goto err;
        +
        +	ws= s->enc_write_ctx;
        +	EVP_CIPHER_CTX_init(ws);
        +
        +	num=c->key_len;
        +	s->s2->key_material_length=num*2;
        +	OPENSSL_assert(s->s2->key_material_length <= sizeof s->s2->key_material);
        +
        +	if (ssl2_generate_key_material(s) <= 0)
        +		return 0;
        +
        +	OPENSSL_assert(c->iv_len <= (int)sizeof(s->session->key_arg));
        +	EVP_EncryptInit_ex(ws,c,NULL,&(s->s2->key_material[(client)?num:0]),
        +		s->session->key_arg);
        +	EVP_DecryptInit_ex(rs,c,NULL,&(s->s2->key_material[(client)?0:num]),
        +		s->session->key_arg);
        +	s->s2->read_key=  &(s->s2->key_material[(client)?0:num]);
        +	s->s2->write_key= &(s->s2->key_material[(client)?num:0]);
        +	return(1);
        +err:
        +	SSLerr(SSL_F_SSL2_ENC_INIT,ERR_R_MALLOC_FAILURE);
        +	return(0);
        +	}
        +
        +/* read/writes from s->s2->mac_data using length for encrypt and 
        + * decrypt.  It sets s->s2->padding and s->[rw]length
        + * if we are encrypting */
        +void ssl2_enc(SSL *s, int send)
        +	{
        +	EVP_CIPHER_CTX *ds;
        +	unsigned long l;
        +	int bs;
        +
        +	if (send)
        +		{
        +		ds=s->enc_write_ctx;
        +		l=s->s2->wlength;
        +		}
        +	else
        +		{
        +		ds=s->enc_read_ctx;
        +		l=s->s2->rlength;
        +		}
        +
        +	/* check for NULL cipher */
        +	if (ds == NULL) return;
        +
        +
        +	bs=ds->cipher->block_size;
        +	/* This should be using (bs-1) and bs instead of 7 and 8, but
        +	 * what the hell. */
        +	if (bs == 8)
        +		l=(l+7)/8*8;
        +
        +	EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l);
        +	}
        +
        +void ssl2_mac(SSL *s, unsigned char *md, int send)
        +	{
        +	EVP_MD_CTX c;
        +	unsigned char sequence[4],*p,*sec,*act;
        +	unsigned long seq;
        +	unsigned int len;
        +
        +	if (send)
        +		{
        +		seq=s->s2->write_sequence;
        +		sec=s->s2->write_key;
        +		len=s->s2->wact_data_length;
        +		act=s->s2->wact_data;
        +		}
        +	else
        +		{
        +		seq=s->s2->read_sequence;
        +		sec=s->s2->read_key;
        +		len=s->s2->ract_data_length;
        +		act=s->s2->ract_data;
        +		}
        +
        +	p= &(sequence[0]);
        +	l2n(seq,p);
        +
        +	/* There has to be a MAC algorithm. */
        +	EVP_MD_CTX_init(&c);
        +	EVP_MD_CTX_copy(&c, s->read_hash);
        +	EVP_DigestUpdate(&c,sec,
        +		EVP_CIPHER_CTX_key_length(s->enc_read_ctx));
        +	EVP_DigestUpdate(&c,act,len); 
        +	/* the above line also does the pad data */
        +	EVP_DigestUpdate(&c,sequence,4); 
        +	EVP_DigestFinal_ex(&c,md,NULL);
        +	EVP_MD_CTX_cleanup(&c);
        +	}
        +#else /* !OPENSSL_NO_SSL2 */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s2_lib.c b/vendor/openssl/openssl/ssl/s2_lib.c
        new file mode 100644
        index 000000000..991460410
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s2_lib.c
        @@ -0,0 +1,556 @@
        +/* ssl/s2_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 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 "ssl_locl.h"
        +#ifndef OPENSSL_NO_SSL2
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/md5.h>
        +
        +const char ssl2_version_str[]="SSLv2" OPENSSL_VERSION_PTEXT;
        +
        +#define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER))
        +
        +/* list of available SSLv2 ciphers (sorted by id) */
        +OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[]={
        +#if 0
        +/* NULL_WITH_MD5 v3 */
        +	{
        +	1,
        +	SSL2_TXT_NULL_WITH_MD5,
        +	SSL2_CK_NULL_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eNULL,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_EXPORT|SSL_EXP40|SSL_STRONG_NONE,
        +	0,
        +	0,
        +	0,
        +	},
        +#endif
        +
        +/* RC4_128_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_RC4_128_WITH_MD5,
        +	SSL2_CK_RC4_128_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	0,
        +	128,
        +	128,
        +	},
        +
        +/* RC4_128_EXPORT40_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_RC4_128_EXPORT40_WITH_MD5,
        +	SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL2_CF_5_BYTE_ENC,
        +	40,
        +	128,
        +	},
        +
        +/* RC2_128_CBC_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_RC2_128_CBC_WITH_MD5,
        +	SSL2_CK_RC2_128_CBC_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC2,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	0,
        +	128,
        +	128,
        +	},
        +
        +/* RC2_128_CBC_EXPORT40_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5,
        +	SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC2,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL2_CF_5_BYTE_ENC,
        +	40,
        +	128,
        +	},
        +
        +#ifndef OPENSSL_NO_IDEA
        +/* IDEA_128_CBC_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_IDEA_128_CBC_WITH_MD5,
        +	SSL2_CK_IDEA_128_CBC_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_IDEA,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	0,
        +	128,
        +	128,
        +	},
        +#endif
        +
        +/* DES_64_CBC_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_DES_64_CBC_WITH_MD5,
        +	SSL2_CK_DES_64_CBC_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_DES,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_NOT_EXP|SSL_LOW,
        +	0,
        +	56,
        +	56,
        +	},
        +
        +/* DES_192_EDE3_CBC_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5,
        +	SSL2_CK_DES_192_EDE3_CBC_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_3DES,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	0,
        +	168,
        +	168,
        +	},
        +
        +#if 0
        +/* RC4_64_WITH_MD5 */
        +	{
        +	1,
        +	SSL2_TXT_RC4_64_WITH_MD5,
        +	SSL2_CK_RC4_64_WITH_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV2,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL2_CF_8_BYTE_ENC,
        +	64,
        +	64,
        +	},
        +#endif
        +
        +#if 0
        +/* NULL SSLeay (testing) */
        +	{	
        +	0,
        +	SSL2_TXT_NULL,
        +	SSL2_CK_NULL,
        +	0,
        +	0,
        +	0,
        +	0,
        +	SSL_SSLV2,
        +	SSL_STRONG_NONE,
        +	0,
        +	0,
        +	0,
        +	},
        +#endif
        +
        +/* end of list :-) */
        +	};
        +
        +long ssl2_default_timeout(void)
        +	{
        +	return(300);
        +	}
        +
        +int ssl2_num_ciphers(void)
        +	{
        +	return(SSL2_NUM_CIPHERS);
        +	}
        +
        +const SSL_CIPHER *ssl2_get_cipher(unsigned int u)
        +	{
        +	if (u < SSL2_NUM_CIPHERS)
        +		return(&(ssl2_ciphers[SSL2_NUM_CIPHERS-1-u]));
        +	else
        +		return(NULL);
        +	}
        +
        +int ssl2_pending(const SSL *s)
        +	{
        +	return SSL_in_init(s) ? 0 : s->s2->ract_data_length;
        +	}
        +
        +int ssl2_new(SSL *s)
        +	{
        +	SSL2_STATE *s2;
        +
        +	if ((s2=OPENSSL_malloc(sizeof *s2)) == NULL) goto err;
        +	memset(s2,0,sizeof *s2);
        +
        +#if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2
        +#  error "assertion failed"
        +#endif
        +
        +	if ((s2->rbuf=OPENSSL_malloc(
        +		SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2)) == NULL) goto err;
        +	/* wbuf needs one byte more because when using two-byte headers,
        +	 * we leave the first byte unused in do_ssl_write (s2_pkt.c) */
        +	if ((s2->wbuf=OPENSSL_malloc(
        +		SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+3)) == NULL) goto err;
        +	s->s2=s2;
        +
        +	ssl2_clear(s);
        +	return(1);
        +err:
        +	if (s2 != NULL)
        +		{
        +		if (s2->wbuf != NULL) OPENSSL_free(s2->wbuf);
        +		if (s2->rbuf != NULL) OPENSSL_free(s2->rbuf);
        +		OPENSSL_free(s2);
        +		}
        +	return(0);
        +	}
        +
        +void ssl2_free(SSL *s)
        +	{
        +	SSL2_STATE *s2;
        +
        +	if(s == NULL)
        +	    return;
        +
        +	s2=s->s2;
        +	if (s2->rbuf != NULL) OPENSSL_free(s2->rbuf);
        +	if (s2->wbuf != NULL) OPENSSL_free(s2->wbuf);
        +	OPENSSL_cleanse(s2,sizeof *s2);
        +	OPENSSL_free(s2);
        +	s->s2=NULL;
        +	}
        +
        +void ssl2_clear(SSL *s)
        +	{
        +	SSL2_STATE *s2;
        +	unsigned char *rbuf,*wbuf;
        +
        +	s2=s->s2;
        +
        +	rbuf=s2->rbuf;
        +	wbuf=s2->wbuf;
        +
        +	memset(s2,0,sizeof *s2);
        +
        +	s2->rbuf=rbuf;
        +	s2->wbuf=wbuf;
        +	s2->clear_text=1;
        +	s->packet=s2->rbuf;
        +	s->version=SSL2_VERSION;
        +	s->packet_length=0;
        +	}
        +
        +long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
        +	{
        +	int ret=0;
        +
        +	switch(cmd)
        +		{
        +	case SSL_CTRL_GET_SESSION_REUSED:
        +		ret=s->hit;
        +		break;
        +	default:
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
        +	{
        +	return(0);
        +	}
        +
        +long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
        +	{
        +	return(0);
        +	}
        +
        +long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
        +	{
        +	return(0);
        +	}
        +
        +/* This function needs to check if the ciphers required are actually
        + * available */
        +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
        +	{
        +	SSL_CIPHER c;
        +	const SSL_CIPHER *cp;
        +	unsigned long id;
        +
        +	id=0x02000000L|((unsigned long)p[0]<<16L)|
        +		((unsigned long)p[1]<<8L)|(unsigned long)p[2];
        +	c.id=id;
        +	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
        +	if ((cp == NULL) || (cp->valid == 0))
        +		return NULL;
        +	else
        +		return cp;
        +	}
        +
        +int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
        +	{
        +	long l;
        +
        +	if (p != NULL)
        +		{
        +		l=c->id;
        +		if ((l & 0xff000000) != 0x02000000) return(0);
        +		p[0]=((unsigned char)(l>>16L))&0xFF;
        +		p[1]=((unsigned char)(l>> 8L))&0xFF;
        +		p[2]=((unsigned char)(l     ))&0xFF;
        +		}
        +	return(3);
        +	}
        +
        +int ssl2_generate_key_material(SSL *s)
        +	{
        +	unsigned int i;
        +	EVP_MD_CTX ctx;
        +	unsigned char *km;
        +	unsigned char c='0';
        +	const EVP_MD *md5;
        +	int md_size;
        +
        +	md5 = EVP_md5();
        +
        +#ifdef CHARSET_EBCDIC
        +	c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0',
        +				see SSLv2 docu */
        +#endif
        +	EVP_MD_CTX_init(&ctx);
        +	km=s->s2->key_material;
        +
        + 	if (s->session->master_key_length < 0 ||
        +			s->session->master_key_length > (int)sizeof(s->session->master_key))
        + 		{
        + 		SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
        + 		return 0;
        + 		}
        +	md_size = EVP_MD_size(md5);
        +	if (md_size < 0)
        +	    return 0;
        +	for (i=0; i<s->s2->key_material_length; i += md_size)
        +		{
        +		if (((km - s->s2->key_material) + md_size) >
        +				(int)sizeof(s->s2->key_material))
        +			{
        +			/* EVP_DigestFinal_ex() below would write beyond buffer */
        +			SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
        +			return 0;
        +			}
        +
        +		EVP_DigestInit_ex(&ctx, md5, NULL);
        +
        +		OPENSSL_assert(s->session->master_key_length >= 0
        +		    && s->session->master_key_length
        +		    < (int)sizeof(s->session->master_key));
        +		EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length);
        +		EVP_DigestUpdate(&ctx,&c,1);
        +		c++;
        +		EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length);
        +		EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length);
        +		EVP_DigestFinal_ex(&ctx,km,NULL);
        +		km += md_size;
        +		}
        +
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return 1;
        +	}
        +
        +void ssl2_return_error(SSL *s, int err)
        +	{
        +	if (!s->error)
        +		{
        +		s->error=3;
        +		s->error_code=err;
        +
        +		ssl2_write_error(s);
        +		}
        +	}
        +
        +
        +void ssl2_write_error(SSL *s)
        +	{
        +	unsigned char buf[3];
        +	int i,error;
        +
        +	buf[0]=SSL2_MT_ERROR;
        +	buf[1]=(s->error_code>>8)&0xff;
        +	buf[2]=(s->error_code)&0xff;
        +
        +/*	state=s->rwstate;*/
        +
        +	error=s->error; /* number of bytes left to write */
        +	s->error=0;
        +	OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf));
        +	i=ssl2_write(s,&(buf[3-error]),error);
        +
        +/*	if (i == error) s->rwstate=state; */
        +
        +	if (i < 0)
        +		s->error=error;
        +	else
        +		{
        +		s->error=error-i;
        +
        +		if (s->error == 0)
        +			if (s->msg_callback)
        +				s->msg_callback(1, s->version, 0, buf, 3, s, s->msg_callback_arg); /* ERROR */
        +		}
        +	}
        +
        +int ssl2_shutdown(SSL *s)
        +	{
        +	s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +	return(1);
        +	}
        +#else /* !OPENSSL_NO_SSL2 */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s2_meth.c b/vendor/openssl/openssl/ssl/s2_meth.c
        new file mode 100644
        index 000000000..f0e8ca593
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s2_meth.c
        @@ -0,0 +1,84 @@
        +/* ssl/s2_meth.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 "ssl_locl.h"
        +#ifndef OPENSSL_NO_SSL2
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +
        +static const SSL_METHOD *ssl2_get_method(int ver);
        +static const SSL_METHOD *ssl2_get_method(int ver)
        +	{
        +	if (ver == SSL2_VERSION)
        +		return(SSLv2_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl2_meth_func(SSLv2_method,
        +			 ssl2_accept,
        +			 ssl2_connect,
        +			 ssl2_get_method)
        +
        +#else /* !OPENSSL_NO_SSL2 */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s2_pkt.c b/vendor/openssl/openssl/ssl/s2_pkt.c
        new file mode 100644
        index 000000000..8bb6ab8ba
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s2_pkt.c
        @@ -0,0 +1,743 @@
        +/* ssl/s2_pkt.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_SSL2
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +
        +static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
        +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
        +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
        +static int ssl_mt_error(int n);
        +
        +
        +/* SSL 2.0 imlementation for SSL_read/SSL_peek -
        + * This routine will return 0 to len bytes, decrypted etc if required.
        + */
        +static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
        +	{
        +	int n;
        +	unsigned char mac[MAX_MAC_SIZE];
        +	unsigned char *p;
        +	int i;
        +	int mac_size;
        +
        + ssl2_read_again:
        +	if (SSL_in_init(s) && !s->in_handshake)
        +		{
        +		n=s->handshake_func(s);
        +		if (n < 0) return(n);
        +		if (n == 0)
        +			{
        +			SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		}
        +
        +	clear_sys_error();
        +	s->rwstate=SSL_NOTHING;
        +	if (len <= 0) return(len);
        +
        +	if (s->s2->ract_data_length != 0) /* read from buffer */
        +		{
        +		if (len > s->s2->ract_data_length)
        +			n=s->s2->ract_data_length;
        +		else
        +			n=len;
        +
        +		memcpy(buf,s->s2->ract_data,(unsigned int)n);
        +		if (!peek)
        +			{
        +			s->s2->ract_data_length-=n;
        +			s->s2->ract_data+=n;
        +			if (s->s2->ract_data_length == 0)
        +				s->rstate=SSL_ST_READ_HEADER;
        +			}
        +
        +		return(n);
        +		}
        +
        +	/* s->s2->ract_data_length == 0
        +	 * 
        +	 * Fill the buffer, then goto ssl2_read_again.
        +	 */
        +
        +	if (s->rstate == SSL_ST_READ_HEADER)
        +		{
        +		if (s->first_packet)
        +			{
        +			n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
        +			if (n <= 0) return(n); /* error or non-blocking */
        +			s->first_packet=0;
        +			p=s->packet;
        +			if (!((p[0] & 0x80) && (
        +				(p[2] == SSL2_MT_CLIENT_HELLO) ||
        +				(p[2] == SSL2_MT_SERVER_HELLO))))
        +				{
        +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET);
        +				return(-1);
        +				}
        +			}
        +		else
        +			{
        +			n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
        +			if (n <= 0) return(n); /* error or non-blocking */
        +			}
        +		/* part read stuff */
        +
        +		s->rstate=SSL_ST_READ_BODY;
        +		p=s->packet;
        +		/* Do header */
        +		/*s->s2->padding=0;*/
        +		s->s2->escape=0;
        +		s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]);
        +		if ((p[0] & TWO_BYTE_BIT))		/* Two byte header? */
        +			{
        +			s->s2->three_byte_header=0;
        +			s->s2->rlength&=TWO_BYTE_MASK;	
        +			}
        +		else
        +			{
        +			s->s2->three_byte_header=1;
        +			s->s2->rlength&=THREE_BYTE_MASK;
        +
        +			/* security >s2->escape */
        +			s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0;
        +			}
        +		}
        +
        +	if (s->rstate == SSL_ST_READ_BODY)
        +		{
        +		n=s->s2->rlength+2+s->s2->three_byte_header;
        +		if (n > (int)s->packet_length)
        +			{
        +			n-=s->packet_length;
        +			i=read_n(s,(unsigned int)n,(unsigned int)n,1);
        +			if (i <= 0) return(i); /* ERROR */
        +			}
        +
        +		p= &(s->packet[2]);
        +		s->rstate=SSL_ST_READ_HEADER;
        +		if (s->s2->three_byte_header)
        +			s->s2->padding= *(p++);
        +		else	s->s2->padding=0;
        +
        +		/* Data portion */
        +		if (s->s2->clear_text)
        +			{
        +			mac_size = 0;
        +			s->s2->mac_data=p;
        +			s->s2->ract_data=p;
        +			if (s->s2->padding)
        +				{
        +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
        +				return(-1);
        +				}
        +			}
        +		else
        +			{
        +			mac_size=EVP_MD_CTX_size(s->read_hash);
        +			if (mac_size < 0)
        +				return -1;
        +			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
        +			s->s2->mac_data=p;
        +			s->s2->ract_data= &p[mac_size];
        +			if (s->s2->padding + mac_size > s->s2->rlength)
        +				{
        +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
        +				return(-1);
        +				}
        +			}
        +
        +		s->s2->ract_data_length=s->s2->rlength;
        +		/* added a check for length > max_size in case
        +		 * encryption was not turned on yet due to an error */
        +		if ((!s->s2->clear_text) &&
        +			(s->s2->rlength >= (unsigned int)mac_size))
        +			{
        +			ssl2_enc(s,0);
        +			s->s2->ract_data_length-=mac_size;
        +			ssl2_mac(s,mac,0);
        +			s->s2->ract_data_length-=s->s2->padding;
        +			if (	(CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) ||
        +				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
        +				{
        +				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
        +				return(-1);
        +				}
        +			}
        +		INC32(s->s2->read_sequence); /* expect next number */
        +		/* s->s2->ract_data is now available for processing */
        +
        +		/* Possibly the packet that we just read had 0 actual data bytes.
        +		 * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
        +		 * In this case, returning 0 would be interpreted by the caller
        +		 * as indicating EOF, so it's not a good idea.  Instead, we just
        +		 * continue reading; thus ssl2_read_internal may have to process
        +		 * multiple packets before it can return.
        +		 *
        +		 * [Note that using select() for blocking sockets *never* guarantees
        +		 * that the next SSL_read will not block -- the available
        +		 * data may contain incomplete packets, and except for SSL 2,
        +		 * renegotiation can confuse things even more.] */
        +
        +		goto ssl2_read_again; /* This should really be
        +		                       * "return ssl2_read(s,buf,len)",
        +		                       * but that would allow for
        +		                       * denial-of-service attacks if a
        +		                       * C compiler is used that does not
        +		                       * recognize end-recursion. */
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
        +			return(-1);
        +		}
        +	}
        +
        +int ssl2_read(SSL *s, void *buf, int len)
        +	{
        +	return ssl2_read_internal(s, buf, len, 0);
        +	}
        +
        +int ssl2_peek(SSL *s, void *buf, int len)
        +	{
        +	return ssl2_read_internal(s, buf, len, 1);
        +	}
        +
        +static int read_n(SSL *s, unsigned int n, unsigned int max,
        +	     unsigned int extend)
        +	{
        +	int i,off,newb;
        +
        +	/* if there is stuff still in the buffer from a previous read,
        +	 * and there is more than we want, take some. */
        +	if (s->s2->rbuf_left >= (int)n)
        +		{
        +		if (extend)
        +			s->packet_length+=n;
        +		else
        +			{
        +			s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]);
        +			s->packet_length=n;
        +			}
        +		s->s2->rbuf_left-=n;
        +		s->s2->rbuf_offs+=n;
        +		return(n);
        +		}
        +
        +	if (!s->read_ahead) max=n;
        +	if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2))
        +		max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2;
        +	
        +
        +	/* Else we want more than we have.
        +	 * First, if there is some left or we want to extend */
        +	off=0;
        +	if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend))
        +		{
        +		newb=s->s2->rbuf_left;
        +		if (extend)
        +			{
        +			off=s->packet_length;
        +			if (s->packet != s->s2->rbuf)
        +				memcpy(s->s2->rbuf,s->packet,
        +					(unsigned int)newb+off);
        +			}
        +		else if (s->s2->rbuf_offs != 0)
        +			{
        +			memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]),
        +				(unsigned int)newb);
        +			s->s2->rbuf_offs=0;
        +			}
        +		s->s2->rbuf_left=0;
        +		}
        +	else
        +		newb=0;
        +
        +	/* off is the offset to start writing too.
        +	 * r->s2->rbuf_offs is the 'unread data', now 0. 
        +	 * newb is the number of new bytes so far
        +	 */
        +	s->packet=s->s2->rbuf;
        +	while (newb < (int)n)
        +		{
        +		clear_sys_error();
        +		if (s->rbio != NULL)
        +			{
        +			s->rwstate=SSL_READING;
        +			i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]),
        +				max-newb);
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET);
        +			i= -1;
        +			}
        +#ifdef PKT_DEBUG
        +		if (s->debug & 0x01) sleep(1);
        +#endif
        +		if (i <= 0)
        +			{
        +			s->s2->rbuf_left+=newb;
        +			return(i);
        +			}
        +		newb+=i;
        +		}
        +
        +	/* record unread data */
        +	if (newb > (int)n)
        +		{
        +		s->s2->rbuf_offs=n+off;
        +		s->s2->rbuf_left=newb-n;
        +		}
        +	else
        +		{
        +		s->s2->rbuf_offs=0;
        +		s->s2->rbuf_left=0;
        +		}
        +	if (extend)
        +		s->packet_length+=n;
        +	else
        +		s->packet_length=n;
        +	s->rwstate=SSL_NOTHING;
        +	return(n);
        +	}
        +
        +int ssl2_write(SSL *s, const void *_buf, int len)
        +	{
        +	const unsigned char *buf=_buf;
        +	unsigned int n,tot;
        +	int i;
        +
        +	if (SSL_in_init(s) && !s->in_handshake)
        +		{
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		}
        +
        +	if (s->error)
        +		{
        +		ssl2_write_error(s);
        +		if (s->error)
        +			return(-1);
        +		}
        +
        +	clear_sys_error();
        +	s->rwstate=SSL_NOTHING;
        +	if (len <= 0) return(len);
        +
        +	tot=s->s2->wnum;
        +	s->s2->wnum=0;
        +
        +	n=(len-tot);
        +	for (;;)
        +		{
        +		i=n_do_ssl_write(s,&(buf[tot]),n);
        +		if (i <= 0)
        +			{
        +			s->s2->wnum=tot;
        +			return(i);
        +			}
        +		if ((i == (int)n) ||
        +			(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))
        +			{
        +			return(tot+i);
        +			}
        +		
        +		n-=i;
        +		tot+=i;
        +		}
        +	}
        +
        +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
        +	{
        +	int i;
        +
        +	/* s->s2->wpend_len != 0 MUST be true. */
        +
        +	/* check that they have given us the same buffer to
        +	 * write */
        +	if ((s->s2->wpend_tot > (int)len) ||
        +		((s->s2->wpend_buf != buf) &&
        +		 !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
        +		{
        +		SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
        +		return(-1);
        +		}
        +
        +	for (;;)
        +		{
        +		clear_sys_error();
        +		if (s->wbio != NULL)
        +			{
        +			s->rwstate=SSL_WRITING;
        +			i=BIO_write(s->wbio,
        +				(char *)&(s->s2->write_ptr[s->s2->wpend_off]),
        +				(unsigned int)s->s2->wpend_len);
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET);
        +			i= -1;
        +			}
        +#ifdef PKT_DEBUG
        +		if (s->debug & 0x01) sleep(1);
        +#endif
        +		if (i == s->s2->wpend_len)
        +			{
        +			s->s2->wpend_len=0;
        +			s->rwstate=SSL_NOTHING;
        +			return(s->s2->wpend_ret);
        +			}
        +		else if (i <= 0)
        +			return(i);
        +		s->s2->wpend_off+=i;
        +		s->s2->wpend_len-=i;
        +		}
        +	}
        +
        +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
        +	{
        +	unsigned int j,k,olen,p,bs;
        +	int mac_size;
        +	register unsigned char *pp;
        +
        +	olen=len;
        +
        +	/* first check if there is data from an encryption waiting to
        +	 * be sent - it must be sent because the other end is waiting.
        +	 * This will happen with non-blocking IO.  We print it and then
        +	 * return.
        +	 */
        +	if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
        +
        +	/* set mac_size to mac size */
        +	if (s->s2->clear_text)
        +		mac_size=0;
        +	else
        +		{
        +		mac_size=EVP_MD_CTX_size(s->write_hash);
        +		if (mac_size < 0)
        +			return -1;
        +		}
        +
        +	/* lets set the pad p */
        +	if (s->s2->clear_text)
        +		{
        +		if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
        +			len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
        +		p=0;
        +		s->s2->three_byte_header=0;
        +		/* len=len; */
        +		}
        +	else
        +		{
        +		bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
        +		j=len+mac_size;
        +		/* Two-byte headers allow for a larger record length than
        +		 * three-byte headers, but we can't use them if we need
        +		 * padding or if we have to set the escape bit. */
        +		if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
        +			(!s->s2->escape))
        +			{
        +			if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
        +				j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
        +			/* set k to the max number of bytes with 2
        +			 * byte header */
        +			k=j-(j%bs);
        +			/* how many data bytes? */
        +			len=k-mac_size; 
        +			s->s2->three_byte_header=0;
        +			p=0;
        +			}
        +		else if ((bs <= 1) && (!s->s2->escape))
        +			{
        +			/* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus
        +			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */
        +			s->s2->three_byte_header=0;
        +			p=0;
        +			}
        +		else /* we may have to use a 3 byte header */
        +			{
        +			/* If s->s2->escape is not set, then
        +			 * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus
        +			 * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */
        +			p=(j%bs);
        +			p=(p == 0)?0:(bs-p);
        +			if (s->s2->escape)
        +				{
        +				s->s2->three_byte_header=1;
        +				if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
        +					j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER;
        +				}
        +			else
        +				s->s2->three_byte_header=(p == 0)?0:1;
        +			}
        +		}
        +
        +	/* Now
        +	 *      j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER
        +	 * holds, and if s->s2->three_byte_header is set, then even
        +	 *      j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER.
        +	 */
        +
        +	/* mac_size is the number of MAC bytes
        +	 * len is the number of data bytes we are going to send
        +	 * p is the number of padding bytes
        +	 * (if it is a two-byte header, then p == 0) */
        +
        +	s->s2->wlength=len;
        +	s->s2->padding=p;
        +	s->s2->mac_data= &(s->s2->wbuf[3]);
        +	s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
        +	/* we copy the data into s->s2->wbuf */
        +	memcpy(s->s2->wact_data,buf,len);
        +	if (p)
        +		memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */
        +
        +	if (!s->s2->clear_text)
        +		{
        +		s->s2->wact_data_length=len+p;
        +		ssl2_mac(s,s->s2->mac_data,1);
        +		s->s2->wlength+=p+mac_size;
        +		ssl2_enc(s,1);
        +		}
        +
        +	/* package up the header */
        +	s->s2->wpend_len=s->s2->wlength;
        +	if (s->s2->three_byte_header) /* 3 byte header */
        +		{
        +		pp=s->s2->mac_data;
        +		pp-=3;
        +		pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8);
        +		if (s->s2->escape) pp[0]|=SEC_ESC_BIT;
        +		pp[1]=s->s2->wlength&0xff;
        +		pp[2]=s->s2->padding;
        +		s->s2->wpend_len+=3;
        +		}
        +	else
        +		{
        +		pp=s->s2->mac_data;
        +		pp-=2;
        +		pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT;
        +		pp[1]=s->s2->wlength&0xff;
        +		s->s2->wpend_len+=2;
        +		}
        +	s->s2->write_ptr=pp;
        +	
        +	INC32(s->s2->write_sequence); /* expect next number */
        +
        +	/* lets try to actually write the data */
        +	s->s2->wpend_tot=olen;
        +	s->s2->wpend_buf=buf;
        +
        +	s->s2->wpend_ret=len;
        +
        +	s->s2->wpend_off=0;
        +	return(write_pending(s,buf,olen));
        +	}
        +
        +int ssl2_part_read(SSL *s, unsigned long f, int i)
        +	{
        +	unsigned char *p;
        +	int j;
        +
        +	if (i < 0)
        +		{
        +		/* ssl2_return_error(s); */
        +		/* for non-blocking io,
        +		 * this is not necessarily fatal */
        +		return(i);
        +		}
        +	else
        +		{
        +		s->init_num+=i;
        +
        +		/* Check for error.  While there are recoverable errors,
        +		 * this function is not called when those must be expected;
        +		 * any error detected here is fatal. */
        +		if (s->init_num >= 3)
        +			{
        +			p=(unsigned char *)s->init_buf->data;
        +			if (p[0] == SSL2_MT_ERROR)
        +				{
        +				j=(p[1]<<8)|p[2];
        +				SSLerr((int)f,ssl_mt_error(j));
        +				s->init_num -= 3;
        +				if (s->init_num > 0)
        +					memmove(p, p+3, s->init_num);
        +				}
        +			}
        +
        +		/* If it's not an error message, we have some error anyway --
        +		 * the message was shorter than expected.  This too is treated
        +		 * as fatal (at least if SSL_get_error is asked for its opinion). */
        +		return(0);
        +		}
        +	}
        +
        +int ssl2_do_write(SSL *s)
        +	{
        +	int ret;
        +
        +	ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num);
        +	if (ret == s->init_num)
        +		{
        +		if (s->msg_callback)
        +			s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
        +		return(1);
        +		}
        +	if (ret < 0)
        +		return(-1);
        +	s->init_off+=ret;
        +	s->init_num-=ret;
        +	return(0);
        +	}
        +
        +static int ssl_mt_error(int n)
        +	{
        +	int ret;
        +
        +	switch (n)
        +		{
        +	case SSL2_PE_NO_CIPHER:
        +		ret=SSL_R_PEER_ERROR_NO_CIPHER;
        +		break;
        +	case SSL2_PE_NO_CERTIFICATE:
        +		ret=SSL_R_PEER_ERROR_NO_CERTIFICATE;
        +		break;
        +	case SSL2_PE_BAD_CERTIFICATE:
        +		ret=SSL_R_PEER_ERROR_CERTIFICATE;
        +		break;
        +	case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:
        +		ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
        +		break;
        +	default:
        +		ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE;
        +		break;
        +		}
        +	return(ret);
        +	}
        +#else /* !OPENSSL_NO_SSL2 */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s2_srvr.c b/vendor/openssl/openssl/ssl/s2_srvr.c
        new file mode 100644
        index 000000000..2cba426bb
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s2_srvr.c
        @@ -0,0 +1,1148 @@
        +/* ssl/s2_srvr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_SSL2
        +#include <stdio.h>
        +#include <openssl/bio.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +
        +static const SSL_METHOD *ssl2_get_server_method(int ver);
        +static int get_client_master_key(SSL *s);
        +static int get_client_hello(SSL *s);
        +static int server_hello(SSL *s); 
        +static int get_client_finished(SSL *s);
        +static int server_verify(SSL *s);
        +static int server_finish(SSL *s);
        +static int request_certificate(SSL *s);
        +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
        +	unsigned char *to,int padding);
        +#define BREAK	break
        +
        +static const SSL_METHOD *ssl2_get_server_method(int ver)
        +	{
        +	if (ver == SSL2_VERSION)
        +		return(SSLv2_server_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
        +			ssl2_accept,
        +			ssl_undefined_function,
        +			ssl2_get_server_method)
        +
        +int ssl2_accept(SSL *s)
        +	{
        +	unsigned long l=(unsigned long)time(NULL);
        +	BUF_MEM *buf=NULL;
        +	int ret= -1;
        +	long num1;
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int new_state,state;
        +
        +	RAND_add(&l,sizeof(l),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +
        +	/* init things to blank */
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
        +
        +	if (s->cert == NULL)
        +		{
        +		SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
        +		return(-1);
        +		}
        +
        +	clear_sys_error();
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch (s->state)
        +			{
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_ACCEPT:
        +		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
        +		case SSL_ST_OK|SSL_ST_ACCEPT:
        +
        +			s->server=1;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			s->version=SSL2_VERSION;
        +			s->type=SSL_ST_ACCEPT;
        +
        +			buf=s->init_buf;
        +			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
        +				{ ret= -1; goto end; }
        +			if (!BUF_MEM_grow(buf,(int)
        +				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
        +				{ ret= -1; goto end; }
        +			s->init_buf=buf;
        +			s->init_num=0;
        +			s->ctx->stats.sess_accept++;
        +			s->handshake_func=ssl2_accept;
        +			s->state=SSL2_ST_GET_CLIENT_HELLO_A;
        +			BREAK;
        +
        +		case SSL2_ST_GET_CLIENT_HELLO_A:
        +		case SSL2_ST_GET_CLIENT_HELLO_B:
        +		case SSL2_ST_GET_CLIENT_HELLO_C:
        +			s->shutdown=0;
        +			ret=get_client_hello(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_SEND_SERVER_HELLO_A;
        +			BREAK;
        +
        +		case SSL2_ST_SEND_SERVER_HELLO_A:
        +		case SSL2_ST_SEND_SERVER_HELLO_B:
        +			ret=server_hello(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			if (!s->hit)
        +				{
        +				s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
        +				BREAK;
        +				}
        +			else
        +				{
        +				s->state=SSL2_ST_SERVER_START_ENCRYPTION;
        +				BREAK;
        +				}
        +		case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
        +		case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
        +			ret=get_client_master_key(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_SERVER_START_ENCRYPTION;
        +			BREAK;
        +
        +		case SSL2_ST_SERVER_START_ENCRYPTION:
        +			/* Ok we how have sent all the stuff needed to
        +			 * start encrypting, the next packet back will
        +			 * be encrypted. */
        +			if (!ssl2_enc_init(s,0))
        +				{ ret= -1; goto end; }
        +			s->s2->clear_text=0;
        +			s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
        +			BREAK;
        +
        +		case SSL2_ST_SEND_SERVER_VERIFY_A:
        +		case SSL2_ST_SEND_SERVER_VERIFY_B:
        +			ret=server_verify(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			if (s->hit)
        +				{
        +				/* If we are in here, we have been
        +				 * buffering the output, so we need to
        +				 * flush it and remove buffering from
        +				 * future traffic */
        +				s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
        +				BREAK;
        +				}
        +			else
        +				{
        +				s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
        +				break;
        +				}
        +
        + 		case SSL2_ST_SEND_SERVER_VERIFY_C:
        + 			/* get the number of bytes to write */
        + 			num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
        + 			if (num1 > 0)
        + 				{
        +				s->rwstate=SSL_WRITING;
        + 				num1=BIO_flush(s->wbio);
        + 				if (num1 <= 0) { ret= -1; goto end; }
        +				s->rwstate=SSL_NOTHING;
        +				}
        +
        + 			/* flushed and now remove buffering */
        + 			s->wbio=BIO_pop(s->wbio);
        +
        + 			s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
        +  			BREAK;
        +
        +		case SSL2_ST_GET_CLIENT_FINISHED_A:
        +		case SSL2_ST_GET_CLIENT_FINISHED_B:
        +			ret=get_client_finished(s);
        +			if (ret <= 0)
        +				goto end;
        +			s->init_num=0;
        +			s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
        +			BREAK;
        +
        +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
        +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
        +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
        +		case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
        +			/* don't do a 'request certificate' if we
        +			 * don't want to, or we already have one, and
        +			 * we only want to do it once. */
        +			if (!(s->verify_mode & SSL_VERIFY_PEER) ||
        +				((s->session->peer != NULL) &&
        +				(s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
        +				{
        +				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
        +				break;
        +				}
        +			else
        +				{
        +				ret=request_certificate(s);
        +				if (ret <= 0) goto end;
        +				s->init_num=0;
        +				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
        +				}
        +			BREAK;
        +
        +		case SSL2_ST_SEND_SERVER_FINISHED_A:
        +		case SSL2_ST_SEND_SERVER_FINISHED_B:
        +			ret=server_finish(s);
        +			if (ret <= 0) goto end;
        +			s->init_num=0;
        +			s->state=SSL_ST_OK;
        +			break;
        +
        +		case SSL_ST_OK:
        +			BUF_MEM_free(s->init_buf);
        +			ssl_free_wbio_buffer(s);
        +			s->init_buf=NULL;
        +			s->init_num=0;
        +		/*	ERR_clear_error();*/
        +
        +			ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
        +
        +			s->ctx->stats.sess_accept_good++;
        +			/* s->server=1; */
        +			ret=1;
        +
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
        +
        +			goto end;
        +			/* BREAK; */
        +
        +		default:
        +			SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* BREAK; */
        +			}
        +		
        +		if ((cb != NULL) && (s->state != state))
        +			{
        +			new_state=s->state;
        +			s->state=state;
        +			cb(s,SSL_CB_ACCEPT_LOOP,1);
        +			s->state=new_state;
        +			}
        +		}
        +end:
        +	s->in_handshake--;
        +	if (cb != NULL)
        +		cb(s,SSL_CB_ACCEPT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +static int get_client_master_key(SSL *s)
        +	{
        +	int is_export,i,n,keya,ek;
        +	unsigned long len;
        +	unsigned char *p;
        +	const SSL_CIPHER *cp;
        +	const EVP_CIPHER *c;
        +	const EVP_MD *md;
        +
        +	p=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
        +		{
        +		i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
        +
        +		if (i < (10-s->init_num))
        +			return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
        +		s->init_num = 10;
        +
        +		if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
        +			{
        +			if (p[-1] != SSL2_MT_ERROR)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
        +				}
        +			else
        +				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
        +			return(-1);
        +			}
        +
        +		cp=ssl2_get_cipher_by_char(p);
        +		if (cp == NULL)
        +			{
        +			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
        +			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
        +			return(-1);
        +			}
        +		s->session->cipher= cp;
        +
        +		p+=3;
        +		n2s(p,i); s->s2->tmp.clear=i;
        +		n2s(p,i); s->s2->tmp.enc=i;
        +		n2s(p,i);
        +		if(i > SSL_MAX_KEY_ARG_LENGTH)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
        +			return -1;
        +			}
        +		s->session->key_arg_length=i;
        +		s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
        +		}
        +
        +	/* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
        +	p=(unsigned char *)s->init_buf->data;
        +	if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +	keya=s->session->key_arg_length;
        +	len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
        +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
        +		return -1;
        +		}
        +	n = (int)len - s->init_num;
        +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
        +	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
        +	p += 10;
        +
        +	memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
        +		(unsigned int)keya);
        +
        +	if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
        +		return(-1);
        +		}
        +	i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
        +		&(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
        +		(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
        +
        +	is_export=SSL_C_IS_EXPORT(s->session->cipher);
        +	
        +	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
        +		{
        +		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
        +		return(0);
        +		}
        +
        +	if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
        +		{
        +		is_export=1;
        +		ek=8;
        +		}
        +	else
        +		ek=5;
        +
        +	/* bad decrypt */
        +#if 1
        +	/* If a bad decrypt, continue with protocol but with a
        +	 * random master secret (Bleichenbacher attack) */
        +	if ((i < 0) ||
        +		((!is_export && (i != EVP_CIPHER_key_length(c)))
        +		|| (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
        +			(unsigned int)EVP_CIPHER_key_length(c))))))
        +		{
        +		ERR_clear_error();
        +		if (is_export)
        +			i=ek;
        +		else
        +			i=EVP_CIPHER_key_length(c);
        +		if (RAND_pseudo_bytes(p,i) <= 0)
        +			return 0;
        +		}
        +#else
        +	if (i < 0)
        +		{
        +		error=1;
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
        +		}
        +	/* incorrect number of key bytes for non export cipher */
        +	else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
        +		|| (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
        +			EVP_CIPHER_key_length(c)))))
        +		{
        +		error=1;
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
        +		}
        +	if (error)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		return(-1);
        +		}
        +#endif
        +
        +	if (is_export) i+=s->s2->tmp.clear;
        +
        +	if (i > SSL_MAX_MASTER_KEY_LENGTH)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +	s->session->master_key_length=i;
        +	memcpy(s->session->master_key,p,(unsigned int)i);
        +	return(1);
        +	}
        +
        +static int get_client_hello(SSL *s)
        +	{
        +	int i,n;
        +	unsigned long len;
        +	unsigned char *p;
        +	STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
        +	STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
        +	STACK_OF(SSL_CIPHER) *prio, *allow;
        +	int z;
        +
        +	/* This is a bit of a hack to check for the correct packet
        +	 * type the first time round. */
        +	if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
        +		{
        +		s->first_packet=1;
        +		s->state=SSL2_ST_GET_CLIENT_HELLO_B;
        +		}
        +
        +	p=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
        +		{
        +		i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
        +		if (i < (9-s->init_num)) 
        +			return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
        +		s->init_num = 9;
        +	
        +		if (*(p++) != SSL2_MT_CLIENT_HELLO)
        +			{
        +			if (p[-1] != SSL2_MT_ERROR)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
        +				}
        +			else
        +				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
        +			return(-1);
        +			}
        +		n2s(p,i);
        +		if (i < s->version) s->version=i;
        +		n2s(p,i); s->s2->tmp.cipher_spec_length=i;
        +		n2s(p,i); s->s2->tmp.session_id_length=i;
        +		n2s(p,i); s->s2->challenge_length=i;
        +		if (	(i < SSL2_MIN_CHALLENGE_LENGTH) ||
        +			(i > SSL2_MAX_CHALLENGE_LENGTH))
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
        +			return(-1);
        +			}
        +		s->state=SSL2_ST_GET_CLIENT_HELLO_C;
        +		}
        +
        +	/* SSL2_ST_GET_CLIENT_HELLO_C */
        +	p=(unsigned char *)s->init_buf->data;
        +	len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
        +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
        +		return -1;
        +		}
        +	n = (int)len - s->init_num;
        +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
        +	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
        +	p += 9;
        +
        +	/* get session-id before cipher stuff so we can get out session
        +	 * structure if it is cached */
        +	/* session-id */
        +	if ((s->s2->tmp.session_id_length != 0) && 
        +		(s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
        +		return(-1);
        +		}
        +
        +	if (s->s2->tmp.session_id_length == 0)
        +		{
        +		if (!ssl_get_new_session(s,1))
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			return(-1);
        +			}
        +		}
        +	else
        +		{
        +		i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
        +			s->s2->tmp.session_id_length, NULL);
        +		if (i == 1)
        +			{ /* previous session */
        +			s->hit=1;
        +			}
        +		else if (i == -1)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			return(-1);
        +			}
        +		else
        +			{
        +			if (s->cert == NULL)
        +				{
        +				ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
        +				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
        +				return(-1);
        +				}
        +
        +			if (!ssl_get_new_session(s,1))
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				return(-1);
        +				}
        +			}
        +		}
        +
        +	if (!s->hit)
        +		{
        +		cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
        +			&s->session->ciphers);
        +		if (cs == NULL) goto mem_err;
        +
        +		cl=SSL_get_ciphers(s);
        +
        +		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
        +		    {
        +		    prio=sk_SSL_CIPHER_dup(cl);
        +		    if (prio == NULL) goto mem_err;
        +		    allow = cs;
        +		    }
        +		else
        +		    {
        +		    prio = cs;
        +		    allow = cl;
        +		    }
        +		for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
        +			{
        +			if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
        +				{
        +				(void)sk_SSL_CIPHER_delete(prio,z);
        +				z--;
        +				}
        +			}
        +		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
        +		    {
        +		    sk_SSL_CIPHER_free(s->session->ciphers);
        +		    s->session->ciphers = prio;
        +		    }
        +		/* s->session->ciphers should now have a list of
        +		 * ciphers that are on both the client and server.
        +		 * This list is ordered by the order the client sent
        +		 * the ciphers or in the order of the server's preference
        +		 * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
        +		 */
        +		}
        +	p+=s->s2->tmp.cipher_spec_length;
        +	/* done cipher selection */
        +
        +	/* session id extracted already */
        +	p+=s->s2->tmp.session_id_length;
        +
        +	/* challenge */
        +	if (s->s2->challenge_length > sizeof s->s2->challenge)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +	memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
        +	return(1);
        +mem_err:
        +	SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
        +	return(0);
        +	}
        +
        +static int server_hello(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	int n,hit;
        +
        +	p=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
        +		{
        +		d=p+11;
        +		*(p++)=SSL2_MT_SERVER_HELLO;		/* type */
        +		hit=s->hit;
        +		*(p++)=(unsigned char)hit;
        +#if 1
        +		if (!hit)
        +			{
        +			if (s->session->sess_cert != NULL)
        +				/* This can't really happen because get_client_hello
        +				 * has called ssl_get_new_session, which does not set
        +				 * sess_cert. */
        +				ssl_sess_cert_free(s->session->sess_cert);
        +			s->session->sess_cert = ssl_sess_cert_new();
        +			if (s->session->sess_cert == NULL)
        +				{
        +				SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
        +				return(-1);
        +				}
        +			}
        +		/* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
        +		 * depending on whether it survived in the internal cache
        +		 * or was retrieved from an external cache.
        +		 * If it is NULL, we cannot put any useful data in it anyway,
        +		 * so we don't touch it.
        +		 */
        +
        +#else /* That's what used to be done when cert_st and sess_cert_st were
        +	   * the same. */
        +		if (!hit)
        +			{			/* else add cert to session */
        +			CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
        +			if (s->session->sess_cert != NULL)
        +				ssl_cert_free(s->session->sess_cert);
        +			s->session->sess_cert=s->cert;		
        +			}
        +		else	/* We have a session id-cache hit, if the
        +			 * session-id has no certificate listed against
        +			 * the 'cert' structure, grab the 'old' one
        +			 * listed against the SSL connection */
        +			{
        +			if (s->session->sess_cert == NULL)
        +				{
        +				CRYPTO_add(&s->cert->references,1,
        +					CRYPTO_LOCK_SSL_CERT);
        +				s->session->sess_cert=s->cert;
        +				}
        +			}
        +#endif
        +
        +		if (s->cert == NULL)
        +			{
        +			ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
        +			SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
        +			return(-1);
        +			}
        +
        +		if (hit)
        +			{
        +			*(p++)=0;		/* no certificate type */
        +			s2n(s->version,p);	/* version */
        +			s2n(0,p);		/* cert len */
        +			s2n(0,p);		/* ciphers len */
        +			}
        +		else
        +			{
        +			/* EAY EAY */
        +			/* put certificate type */
        +			*(p++)=SSL2_CT_X509_CERTIFICATE;
        +			s2n(s->version,p);	/* version */
        +			n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
        +			s2n(n,p);		/* certificate length */
        +			i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
        +			n=0;
        +			
        +			/* lets send out the ciphers we like in the
        +			 * prefered order */
        +			n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
        +			d+=n;
        +			s2n(n,p);		/* add cipher length */
        +			}
        +
        +		/* make and send conn_id */
        +		s2n(SSL2_CONNECTION_ID_LENGTH,p);	/* add conn_id length */
        +		s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
        +		if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
        +			return -1;
        +		memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
        +		d+=SSL2_CONNECTION_ID_LENGTH;
        +
        +		s->state=SSL2_ST_SEND_SERVER_HELLO_B;
        +		s->init_num=d-(unsigned char *)s->init_buf->data;
        +		s->init_off=0;
        +		}
        +	/* SSL2_ST_SEND_SERVER_HELLO_B */
        + 	/* If we are using TCP/IP, the performance is bad if we do 2
        + 	 * writes without a read between them.  This occurs when
        + 	 * Session-id reuse is used, so I will put in a buffering module
        + 	 */
        + 	if (s->hit)
        + 		{
        +		if (!ssl_init_wbio_buffer(s,1)) return(-1);
        + 		}
        + 
        +	return(ssl2_do_write(s));
        +	}
        +
        +static int get_client_finished(SSL *s)
        +	{
        +	unsigned char *p;
        +	int i, n;
        +	unsigned long len;
        +
        +	p=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
        +		{
        +		i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
        +		if (i < 1-s->init_num)
        +			return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
        +		s->init_num += i;
        +
        +		if (*p != SSL2_MT_CLIENT_FINISHED)
        +			{
        +			if (*p != SSL2_MT_ERROR)
        +				{
        +				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
        +				}
        +			else
        +				{
        +				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
        +				/* try to read the error message */
        +				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
        +				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
        +				}
        +			return(-1);
        +			}
        +		s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
        +		}
        +
        +	/* SSL2_ST_GET_CLIENT_FINISHED_B */
        +	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +	len = 1 + (unsigned long)s->s2->conn_id_length;
        +	n = (int)len - s->init_num;
        +	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
        +	if (i < n)
        +		{
        +		return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
        +		}
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
        +	p += 1;
        +	if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
        +		{
        +		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +		SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
        +		return(-1);
        +		}
        +	return(1);
        +	}
        +
        +static int server_verify(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*(p++)=SSL2_MT_SERVER_VERIFY;
        +		if (s->s2->challenge_length > sizeof s->s2->challenge)
        +			{
        +			SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
        +		/* p+=s->s2->challenge_length; */
        +
        +		s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
        +		s->init_num=s->s2->challenge_length+1;
        +		s->init_off=0;
        +		}
        +	return(ssl2_do_write(s));
        +	}
        +
        +static int server_finish(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*(p++)=SSL2_MT_SERVER_FINISHED;
        +
        +		if (s->session->session_id_length > sizeof s->session->session_id)
        +			{
        +			SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
        +		/* p+=s->session->session_id_length; */
        +
        +		s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
        +		s->init_num=s->session->session_id_length+1;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL2_ST_SEND_SERVER_FINISHED_B */
        +	return(ssl2_do_write(s));
        +	}
        +
        +/* send the request and check the response */
        +static int request_certificate(SSL *s)
        +	{
        +	const unsigned char *cp;
        +	unsigned char *p,*p2,*buf2;
        +	unsigned char *ccd;
        +	int i,j,ctype,ret= -1;
        +	unsigned long len;
        +	X509 *x509=NULL;
        +	STACK_OF(X509) *sk=NULL;
        +
        +	ccd=s->s2->tmp.ccl;
        +	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*(p++)=SSL2_MT_REQUEST_CERTIFICATE;
        +		*(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
        +		if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
        +			return -1;
        +		memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
        +
        +		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
        +		s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
        +		s->init_off=0;
        +		}
        +
        +	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
        +		{
        +		i=ssl2_do_write(s);
        +		if (i <= 0)
        +			{
        +			ret=i;
        +			goto end;
        +			}
        +
        +		s->init_num=0;
        +		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
        +		}
        +
        +	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
        +		if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
        +		                        * (probably NO-CERTIFICATE-ERROR) */
        +			{
        +			ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
        +			goto end;
        +			}
        +		s->init_num += i;
        +
        +		if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
        +			{
        +			n2s(p,i);
        +			if (i != SSL2_PE_NO_CERTIFICATE)
        +				{
        +				/* not the error message we expected -- let ssl2_part_read handle it */
        +				s->init_num -= 3;
        +				ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
        +				goto end;
        +				}
        +
        +			if (s->msg_callback)
        +				s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
        +
        +			/* this is the one place where we can recover from an SSL 2.0 error */
        +
        +			if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
        +				{
        +				ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
        +				SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
        +				goto end;
        +				}
        +			ret=1;
        +			goto end;
        +			}
        +		if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
        +			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
        +			goto end;
        +			}
        +		if (s->init_num != 6)
        +			{
        +			SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
        +			goto end;
        +			}
        +		
        +		/* ok we have a response */
        +		/* certificate type, there is only one right now. */
        +		ctype= *(p++);
        +		if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
        +			{
        +			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
        +			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
        +			goto end;
        +			}
        +		n2s(p,i); s->s2->tmp.clen=i;
        +		n2s(p,i); s->s2->tmp.rlen=i;
        +		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
        +		}
        +
        +	/* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
        +	p=(unsigned char *)s->init_buf->data;
        +	len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
        +	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
        +		{
        +		SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
        +		goto end;
        +		}
        +	j = (int)len - s->init_num;
        +	i = ssl2_read(s,(char *)&(p[s->init_num]),j);
        +	if (i < j) 
        +		{
        +		ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
        +		goto end;
        +		}
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
        +	p += 6;
        +
        +	cp = p;
        +	x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
        +	if (x509 == NULL)
        +		{
        +		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
        +		goto msg_end;
        +		}
        +
        +	if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
        +		{
        +		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +		goto msg_end;
        +		}
        +
        +	i=ssl_verify_cert_chain(s,sk);
        +
        +	if (i > 0)	/* we like the packet, now check the chksum */
        +		{
        +		EVP_MD_CTX ctx;
        +		EVP_PKEY *pkey=NULL;
        +
        +		EVP_MD_CTX_init(&ctx);
        +		if (!EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL)
        +		    || !EVP_VerifyUpdate(&ctx,s->s2->key_material,
        +					 s->s2->key_material_length)
        +		    || !EVP_VerifyUpdate(&ctx,ccd,
        +					 SSL2_MIN_CERT_CHALLENGE_LENGTH))
        +			goto msg_end;
        +
        +		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
        +		buf2=OPENSSL_malloc((unsigned int)i);
        +		if (buf2 == NULL)
        +			{
        +			SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +			goto msg_end;
        +			}
        +		p2=buf2;
        +		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
        +		if (!EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i))
        +			{
        +			OPENSSL_free(buf2);
        +			goto msg_end;
        +			}
        +		OPENSSL_free(buf2);
        +
        +		pkey=X509_get_pubkey(x509);
        +		if (pkey == NULL) goto end;
        +		i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
        +		EVP_PKEY_free(pkey);
        +		EVP_MD_CTX_cleanup(&ctx);
        +
        +		if (i > 0)
        +			{
        +			if (s->session->peer != NULL)
        +				X509_free(s->session->peer);
        +			s->session->peer=x509;
        +			CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
        +			s->session->verify_result = s->verify_result;
        +			ret=1;
        +			goto end;
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
        +			goto msg_end;
        +			}
        +		}
        +	else
        +		{
        +msg_end:
        +		ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
        +		}
        +end:
        +	sk_X509_free(sk);
        +	X509_free(x509);
        +	return(ret);
        +	}
        +
        +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
        +	     unsigned char *to, int padding)
        +	{
        +	RSA *rsa;
        +	int i;
        +
        +	if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
        +		{
        +		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
        +		return(-1);
        +		}
        +	if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
        +		{
        +		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
        +		return(-1);
        +		}
        +	rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
        +
        +	/* we have the public key */
        +	i=RSA_private_decrypt(len,from,to,rsa,padding);
        +	if (i < 0)
        +		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
        +	return(i);
        +	}
        +#else /* !OPENSSL_NO_SSL2 */
        +
        +# if PEDANTIC
        +static void *dummy=&dummy;
        +# endif
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s3_both.c b/vendor/openssl/openssl/ssl/s3_both.c
        new file mode 100644
        index 000000000..ead01c82a
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_both.c
        @@ -0,0 +1,847 @@
        +/* ssl/s3_both.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-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include <limits.h>
        +#include <string.h>
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
        +int ssl3_do_write(SSL *s, int type)
        +	{
        +	int ret;
        +
        +	ret=ssl3_write_bytes(s,type,&s->init_buf->data[s->init_off],
        +	                     s->init_num);
        +	if (ret < 0) return(-1);
        +	if (type == SSL3_RT_HANDSHAKE)
        +		/* should not be done for 'Hello Request's, but in that case
        +		 * we'll ignore the result anyway */
        +		ssl3_finish_mac(s,(unsigned char *)&s->init_buf->data[s->init_off],ret);
        +	
        +	if (ret == s->init_num)
        +		{
        +		if (s->msg_callback)
        +			s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
        +		return(1);
        +		}
        +	s->init_off+=ret;
        +	s->init_num-=ret;
        +	return(0);
        +	}
        +
        +int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
        +	{
        +	unsigned char *p,*d;
        +	int i;
        +	unsigned long l;
        +
        +	if (s->state == a)
        +		{
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[4]);
        +
        +		i=s->method->ssl3_enc->final_finish_mac(s,
        +			sender,slen,s->s3->tmp.finish_md);
        +		s->s3->tmp.finish_md_len = i;
        +		memcpy(p, s->s3->tmp.finish_md, i);
        +		p+=i;
        +		l=i;
        +
        +                /* Copy the finished so we can use it for
        +                   renegotiation checks */
        +                if(s->type == SSL_ST_CONNECT)
        +                        {
        +                         OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
        +                         memcpy(s->s3->previous_client_finished, 
        +                             s->s3->tmp.finish_md, i);
        +                         s->s3->previous_client_finished_len=i;
        +                        }
        +                else
        +                        {
        +                        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
        +                        memcpy(s->s3->previous_server_finished, 
        +                            s->s3->tmp.finish_md, i);
        +                        s->s3->previous_server_finished_len=i;
        +                        }
        +
        +#ifdef OPENSSL_SYS_WIN16
        +		/* MSVC 1.5 does not clear the top bytes of the word unless
        +		 * I do this.
        +		 */
        +		l&=0xffff;
        +#endif
        +
        +		*(d++)=SSL3_MT_FINISHED;
        +		l2n3(l,d);
        +		s->init_num=(int)l+4;
        +		s->init_off=0;
        +
        +		s->state=b;
        +		}
        +
        +	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
        +static void ssl3_take_mac(SSL *s)
        +	{
        +	const char *sender;
        +	int slen;
        +
        +	if (s->state & SSL_ST_CONNECT)
        +		{
        +		sender=s->method->ssl3_enc->server_finished_label;
        +		slen=s->method->ssl3_enc->server_finished_label_len;
        +		}
        +	else
        +		{
        +		sender=s->method->ssl3_enc->client_finished_label;
        +		slen=s->method->ssl3_enc->client_finished_label_len;
        +		}
        +
        +	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
        +		sender,slen,s->s3->tmp.peer_finish_md);
        +	}
        +#endif
        +
        +int ssl3_get_finished(SSL *s, int a, int b)
        +	{
        +	int al,i,ok;
        +	long n;
        +	unsigned char *p;
        +
        +#ifdef OPENSSL_NO_NEXTPROTONEG
        +	/* the mac has already been generated when we received the
        +	 * change cipher spec message and is in s->s3->tmp.peer_finish_md.
        +	 */ 
        +#endif
        +
        +	n=s->method->ssl_get_message(s,
        +		a,
        +		b,
        +		SSL3_MT_FINISHED,
        +		64, /* should actually be 36+4 :-) */
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	/* If this occurs, we have missed a message */
        +	if (!s->s3->change_cipher_spec)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS);
        +		goto f_err;
        +		}
        +	s->s3->change_cipher_spec=0;
        +
        +	p = (unsigned char *)s->init_msg;
        +	i = s->s3->tmp.peer_finish_md_len;
        +
        +	if (i != n)
        +		{
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH);
        +		goto f_err;
        +		}
        +
        +	if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
        +		{
        +		al=SSL_AD_DECRYPT_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
        +		goto f_err;
        +		}
        +
        +        /* Copy the finished so we can use it for
        +           renegotiation checks */
        +        if(s->type == SSL_ST_ACCEPT)
        +                {
        +                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
        +                memcpy(s->s3->previous_client_finished, 
        +                    s->s3->tmp.peer_finish_md, i);
        +                s->s3->previous_client_finished_len=i;
        +                }
        +        else
        +                {
        +                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
        +                memcpy(s->s3->previous_server_finished, 
        +                    s->s3->tmp.peer_finish_md, i);
        +                s->s3->previous_server_finished_len=i;
        +                }
        +
        +	return(1);
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +	return(0);
        +	}
        +
        +/* for these 2 messages, we need to
        + * ssl->enc_read_ctx			re-init
        + * ssl->s3->read_sequence		zero
        + * ssl->s3->read_mac_secret		re-init
        + * ssl->session->read_sym_enc		assign
        + * ssl->session->read_compression	assign
        + * ssl->session->read_hash		assign
        + */
        +int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
        +	{ 
        +	unsigned char *p;
        +
        +	if (s->state == a)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*p=SSL3_MT_CCS;
        +		s->init_num=1;
        +		s->init_off=0;
        +
        +		s->state=b;
        +		}
        +
        +	/* SSL3_ST_CW_CHANGE_B */
        +	return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
        +	}
        +
        +static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
        +	{
        +	int n;
        +	unsigned char *p;
        +
        +	n=i2d_X509(x,NULL);
        +	if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
        +		{
        +		SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
        +		return(-1);
        +		}
        +	p=(unsigned char *)&(buf->data[*l]);
        +	l2n3(n,p);
        +	i2d_X509(x,&p);
        +	*l+=n+3;
        +
        +	return(0);
        +	}
        +
        +unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
        +	{
        +	unsigned char *p;
        +	int i;
        +	unsigned long l=7;
        +	BUF_MEM *buf;
        +	int no_chain;
        +
        +	if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
        +		no_chain = 1;
        +	else
        +		no_chain = 0;
        +
        +	/* TLSv1 sends a chain with nothing in it, instead of an alert */
        +	buf=s->init_buf;
        +	if (!BUF_MEM_grow_clean(buf,10))
        +		{
        +		SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	if (x != NULL)
        +		{
        +		if (no_chain)
        +			{
        +			if (ssl3_add_cert_to_buf(buf, &l, x))
        +				return(0);
        +			}
        +		else
        +			{
        +			X509_STORE_CTX xs_ctx;
        +
        +			if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
        +				{
        +				SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
        +				return(0);
        +				}
        +			X509_verify_cert(&xs_ctx);
        +			/* Don't leave errors in the queue */
        +			ERR_clear_error();
        +			for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
        +				{
        +				x = sk_X509_value(xs_ctx.chain, i);
        +
        +				if (ssl3_add_cert_to_buf(buf, &l, x))
        +					{
        +					X509_STORE_CTX_cleanup(&xs_ctx);
        +					return 0;
        +					}
        +				}
        +			X509_STORE_CTX_cleanup(&xs_ctx);
        +			}
        +		}
        +	/* Thawte special :-) */
        +	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
        +		{
        +		x=sk_X509_value(s->ctx->extra_certs,i);
        +		if (ssl3_add_cert_to_buf(buf, &l, x))
        +			return(0);
        +		}
        +
        +	l-=7;
        +	p=(unsigned char *)&(buf->data[4]);
        +	l2n3(l,p);
        +	l+=3;
        +	p=(unsigned char *)&(buf->data[0]);
        +	*(p++)=SSL3_MT_CERTIFICATE;
        +	l2n3(l,p);
        +	l+=4;
        +	return(l);
        +	}
        +
        +/* Obtain handshake message of message type 'mt' (any if mt == -1),
        + * maximum acceptable body length 'max'.
        + * The first four bytes (msg_type and length) are read in state 'st1',
        + * the body is read in state 'stn'.
        + */
        +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
        +	{
        +	unsigned char *p;
        +	unsigned long l;
        +	long n;
        +	int i,al;
        +
        +	if (s->s3->tmp.reuse_message)
        +		{
        +		s->s3->tmp.reuse_message=0;
        +		if ((mt >= 0) && (s->s3->tmp.message_type != mt))
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
        +			goto f_err;
        +			}
        +		*ok=1;
        +		s->init_msg = s->init_buf->data + 4;
        +		s->init_num = (int)s->s3->tmp.message_size;
        +		return s->init_num;
        +		}
        +
        +	p=(unsigned char *)s->init_buf->data;
        +
        +	if (s->state == st1) /* s->init_num < 4 */
        +		{
        +		int skip_message;
        +
        +		do
        +			{
        +			while (s->init_num < 4)
        +				{
        +				i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
        +					&p[s->init_num],4 - s->init_num, 0);
        +				if (i <= 0)
        +					{
        +					s->rwstate=SSL_READING;
        +					*ok = 0;
        +					return i;
        +					}
        +				s->init_num+=i;
        +				}
        +			
        +			skip_message = 0;
        +			if (!s->server)
        +				if (p[0] == SSL3_MT_HELLO_REQUEST)
        +					/* The server may always send 'Hello Request' messages --
        +					 * we are doing a handshake anyway now, so ignore them
        +					 * if their format is correct. Does not count for
        +					 * 'Finished' MAC. */
        +					if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
        +						{
        +						s->init_num = 0;
        +						skip_message = 1;
        +
        +						if (s->msg_callback)
        +							s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, s->msg_callback_arg);
        +						}
        +			}
        +		while (skip_message);
        +
        +		/* s->init_num == 4 */
        +
        +		if ((mt >= 0) && (*p != mt))
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
        +			goto f_err;
        +			}
        +		if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
        +					(st1 == SSL3_ST_SR_CERT_A) &&
        +					(stn == SSL3_ST_SR_CERT_B))
        +			{
        +			/* At this point we have got an MS SGC second client
        +			 * hello (maybe we should always allow the client to
        +			 * start a new handshake?). We need to restart the mac.
        +			 * Don't increment {num,total}_renegotiations because
        +			 * we have not completed the handshake. */
        +			ssl3_init_finished_mac(s);
        +			}
        +
        +		s->s3->tmp.message_type= *(p++);
        +
        +		n2l3(p,l);
        +		if (l > (unsigned long)max)
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
        +			goto f_err;
        +			}
        +		if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
        +			goto f_err;
        +			}
        +		if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
        +			goto err;
        +			}
        +		s->s3->tmp.message_size=l;
        +		s->state=stn;
        +
        +		s->init_msg = s->init_buf->data + 4;
        +		s->init_num = 0;
        +		}
        +
        +	/* next state (stn) */
        +	p = s->init_msg;
        +	n = s->s3->tmp.message_size - s->init_num;
        +	while (n > 0)
        +		{
        +		i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
        +		if (i <= 0)
        +			{
        +			s->rwstate=SSL_READING;
        +			*ok = 0;
        +			return i;
        +			}
        +		s->init_num += i;
        +		n -= i;
        +		}
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	/* If receiving Finished, record MAC of prior handshake messages for
        +	 * Finished verification. */
        +	if (*s->init_buf->data == SSL3_MT_FINISHED)
        +		ssl3_take_mac(s);
        +#endif
        +
        +	/* Feed this message into MAC computation. */
        +	ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
        +	*ok=1;
        +	return s->init_num;
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	*ok=0;
        +	return(-1);
        +	}
        +
        +int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
        +	{
        +	EVP_PKEY *pk;
        +	int ret= -1,i;
        +
        +	if (pkey == NULL)
        +		pk=X509_get_pubkey(x);
        +	else
        +		pk=pkey;
        +	if (pk == NULL) goto err;
        +
        +	i=pk->type;
        +	if (i == EVP_PKEY_RSA)
        +		{
        +		ret=SSL_PKEY_RSA_ENC;
        +		}
        +	else if (i == EVP_PKEY_DSA)
        +		{
        +		ret=SSL_PKEY_DSA_SIGN;
        +		}
        +#ifndef OPENSSL_NO_EC
        +	else if (i == EVP_PKEY_EC)
        +		{
        +		ret = SSL_PKEY_ECC;
        +		}	
        +#endif
        +	else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) 
        +		{
        +		ret = SSL_PKEY_GOST94;
        +		}
        +	else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) 
        +		{
        +		ret = SSL_PKEY_GOST01;
        +		}
        +err:
        +	if(!pkey) EVP_PKEY_free(pk);
        +	return(ret);
        +	}
        +
        +int ssl_verify_alarm_type(long type)
        +	{
        +	int al;
        +
        +	switch(type)
        +		{
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        +	case X509_V_ERR_UNABLE_TO_GET_CRL:
        +	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
        +		al=SSL_AD_UNKNOWN_CA;
        +		break;
        +	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
        +	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
        +	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
        +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
        +	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
        +	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
        +	case X509_V_ERR_CERT_NOT_YET_VALID:
        +	case X509_V_ERR_CRL_NOT_YET_VALID:
        +	case X509_V_ERR_CERT_UNTRUSTED:
        +	case X509_V_ERR_CERT_REJECTED:
        +		al=SSL_AD_BAD_CERTIFICATE;
        +		break;
        +	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
        +	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
        +		al=SSL_AD_DECRYPT_ERROR;
        +		break;
        +	case X509_V_ERR_CERT_HAS_EXPIRED:
        +	case X509_V_ERR_CRL_HAS_EXPIRED:
        +		al=SSL_AD_CERTIFICATE_EXPIRED;
        +		break;
        +	case X509_V_ERR_CERT_REVOKED:
        +		al=SSL_AD_CERTIFICATE_REVOKED;
        +		break;
        +	case X509_V_ERR_OUT_OF_MEM:
        +		al=SSL_AD_INTERNAL_ERROR;
        +		break;
        +	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        +	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
        +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
        +	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
        +	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
        +	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
        +	case X509_V_ERR_INVALID_CA:
        +		al=SSL_AD_UNKNOWN_CA;
        +		break;
        +	case X509_V_ERR_APPLICATION_VERIFICATION:
        +		al=SSL_AD_HANDSHAKE_FAILURE;
        +		break;
        +	case X509_V_ERR_INVALID_PURPOSE:
        +		al=SSL_AD_UNSUPPORTED_CERTIFICATE;
        +		break;
        +	default:
        +		al=SSL_AD_CERTIFICATE_UNKNOWN;
        +		break;
        +		}
        +	return(al);
        +	}
        +
        +#ifndef OPENSSL_NO_BUF_FREELISTS
        +/* On some platforms, malloc() performance is bad enough that you can't just
        + * free() and malloc() buffers all the time, so we need to use freelists from
        + * unused buffers.  Currently, each freelist holds memory chunks of only a
        + * given size (list->chunklen); other sized chunks are freed and malloced.
        + * This doesn't help much if you're using many different SSL option settings
        + * with a given context.  (The options affecting buffer size are
        + * max_send_fragment, read buffer vs write buffer,
        + * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and
        + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.)  Using a separate freelist for every
        + * possible size is not an option, since max_send_fragment can take on many
        + * different values.
        + *
        + * If you are on a platform with a slow malloc(), and you're using SSL
        + * connections with many different settings for these options, and you need to
        + * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options:
        + *    - Link against a faster malloc implementation.
        + *    - Use a separate SSL_CTX for each option set.
        + *    - Improve this code.
        + */
        +static void *
        +freelist_extract(SSL_CTX *ctx, int for_read, int sz)
        +	{
        +	SSL3_BUF_FREELIST *list;
        +	SSL3_BUF_FREELIST_ENTRY *ent = NULL;
        +	void *result = NULL;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +	list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
        +	if (list != NULL && sz == (int)list->chunklen)
        +		ent = list->head;
        +	if (ent != NULL)
        +		{
        +		list->head = ent->next;
        +		result = ent;
        +		if (--list->len == 0)
        +			list->chunklen = 0;
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +	if (!result)
        +		result = OPENSSL_malloc(sz);
        +	return result;
        +}
        +
        +static void
        +freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem)
        +	{
        +	SSL3_BUF_FREELIST *list;
        +	SSL3_BUF_FREELIST_ENTRY *ent;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +	list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
        +	if (list != NULL &&
        +	    (sz == list->chunklen || list->chunklen == 0) &&
        +	    list->len < ctx->freelist_max_len &&
        +	    sz >= sizeof(*ent))
        +		{
        +		list->chunklen = sz;
        +		ent = mem;
        +		ent->next = list->head;
        +		list->head = ent;
        +		++list->len;
        +		mem = NULL;
        +		}
        +
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +	if (mem)
        +		OPENSSL_free(mem);
        +	}
        +#else
        +#define freelist_extract(c,fr,sz) OPENSSL_malloc(sz)
        +#define freelist_insert(c,fr,sz,m) OPENSSL_free(m)
        +#endif
        +
        +int ssl3_setup_read_buffer(SSL *s)
        +	{
        +	unsigned char *p;
        +	size_t len,align=0,headerlen;
        +	
        +	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
        +		headerlen = DTLS1_RT_HEADER_LENGTH;
        +	else
        +		headerlen = SSL3_RT_HEADER_LENGTH;
        +
        +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        +	align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
        +#endif
        +
        +	if (s->s3->rbuf.buf == NULL)
        +		{
        +		len = SSL3_RT_MAX_PLAIN_LENGTH
        +			+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
        +			+ headerlen + align;
        +		if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
        +			{
        +			s->s3->init_extra = 1;
        +			len += SSL3_RT_MAX_EXTRA;
        +			}
        +#ifndef OPENSSL_NO_COMP
        +		if (!(s->options & SSL_OP_NO_COMPRESSION))
        +			len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
        +#endif
        +		if ((p=freelist_extract(s->ctx, 1, len)) == NULL)
        +			goto err;
        +		s->s3->rbuf.buf = p;
        +		s->s3->rbuf.len = len;
        +		}
        +
        +	s->packet= &(s->s3->rbuf.buf[0]);
        +	return 1;
        +
        +err:
        +	SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER,ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +int ssl3_setup_write_buffer(SSL *s)
        +	{
        +	unsigned char *p;
        +	size_t len,align=0,headerlen;
        +
        +	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
        +		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
        +	else
        +		headerlen = SSL3_RT_HEADER_LENGTH;
        +
        +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        +	align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
        +#endif
        +
        +	if (s->s3->wbuf.buf == NULL)
        +		{
        +		len = s->max_send_fragment
        +			+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
        +			+ headerlen + align;
        +#ifndef OPENSSL_NO_COMP
        +		if (!(s->options & SSL_OP_NO_COMPRESSION))
        +			len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
        +#endif
        +		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
        +			len += headerlen + align
        +				+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
        +
        +		if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
        +			goto err;
        +		s->s3->wbuf.buf = p;
        +		s->s3->wbuf.len = len;
        +		}
        +
        +	return 1;
        +
        +err:
        +	SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER,ERR_R_MALLOC_FAILURE);
        +	return 0;
        +	}
        +
        +
        +int ssl3_setup_buffers(SSL *s)
        +	{
        +	if (!ssl3_setup_read_buffer(s))
        +		return 0;
        +	if (!ssl3_setup_write_buffer(s))
        +		return 0;
        +	return 1;
        +	}
        +
        +int ssl3_release_write_buffer(SSL *s)
        +	{
        +	if (s->s3->wbuf.buf != NULL)
        +		{
        +		freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf);
        +		s->s3->wbuf.buf = NULL;
        +		}
        +	return 1;
        +	}
        +
        +int ssl3_release_read_buffer(SSL *s)
        +	{
        +	if (s->s3->rbuf.buf != NULL)
        +		{
        +		freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf);
        +		s->s3->rbuf.buf = NULL;
        +		}
        +	return 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/s3_cbc.c b/vendor/openssl/openssl/ssl/s3_cbc.c
        new file mode 100644
        index 000000000..02edf3f91
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_cbc.c
        @@ -0,0 +1,790 @@
        +/* ssl/s3_cbc.c */
        +/* ====================================================================
        + * Copyright (c) 2012 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 "ssl_locl.h"
        +
        +#include <openssl/md5.h>
        +#include <openssl/sha.h>
        +
        +/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
        + * field. (SHA-384/512 have 128-bit length.) */
        +#define MAX_HASH_BIT_COUNT_BYTES 16
        +
        +/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
        + * Currently SHA-384/512 has a 128-byte block size and that's the largest
        + * supported by TLS.) */
        +#define MAX_HASH_BLOCK_SIZE 128
        +
        +/* Some utility functions are needed:
        + *
        + * These macros return the given value with the MSB copied to all the other
        + * bits. They use the fact that arithmetic shift shifts-in the sign bit.
        + * However, this is not ensured by the C standard so you may need to replace
        + * them with something else on odd CPUs. */
        +#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
        +#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
        +
        +/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
        +static unsigned constant_time_lt(unsigned a, unsigned b)
        +	{
        +	a -= b;
        +	return DUPLICATE_MSB_TO_ALL(a);
        +	}
        +
        +/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
        +static unsigned constant_time_ge(unsigned a, unsigned b)
        +	{
        +	a -= b;
        +	return DUPLICATE_MSB_TO_ALL(~a);
        +	}
        +
        +/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
        +static unsigned char constant_time_eq_8(unsigned a, unsigned b)
        +	{
        +	unsigned c = a ^ b;
        +	c--;
        +	return DUPLICATE_MSB_TO_ALL_8(c);
        +	}
        +
        +/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
        + * record in |rec| by updating |rec->length| in constant time.
        + *
        + * block_size: the block size of the cipher used to encrypt the record.
        + * returns:
        + *   0: (in non-constant time) if the record is publicly invalid.
        + *   1: if the padding was valid
        + *  -1: otherwise. */
        +int ssl3_cbc_remove_padding(const SSL* s,
        +			    SSL3_RECORD *rec,
        +			    unsigned block_size,
        +			    unsigned mac_size)
        +	{
        +	unsigned padding_length, good;
        +	const unsigned overhead = 1 /* padding length byte */ + mac_size;
        +
        +	/* These lengths are all public so we can test them in non-constant
        +	 * time. */
        +	if (overhead > rec->length)
        +		return 0;
        +
        +	padding_length = rec->data[rec->length-1];
        +	good = constant_time_ge(rec->length, padding_length+overhead);
        +	/* SSLv3 requires that the padding is minimal. */
        +	good &= constant_time_ge(block_size, padding_length+1);
        +	padding_length = good & (padding_length+1);
        +	rec->length -= padding_length;
        +	rec->type |= padding_length<<8;	/* kludge: pass padding length */
        +	return (int)((good & 1) | (~good & -1));
        +}
        +
        +/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
        + * record in |rec| in constant time and returns 1 if the padding is valid and
        + * -1 otherwise. It also removes any explicit IV from the start of the record
        + * without leaking any timing about whether there was enough space after the
        + * padding was removed.
        + *
        + * block_size: the block size of the cipher used to encrypt the record.
        + * returns:
        + *   0: (in non-constant time) if the record is publicly invalid.
        + *   1: if the padding was valid
        + *  -1: otherwise. */
        +int tls1_cbc_remove_padding(const SSL* s,
        +			    SSL3_RECORD *rec,
        +			    unsigned block_size,
        +			    unsigned mac_size)
        +	{
        +	unsigned padding_length, good, to_check, i;
        +	const unsigned overhead = 1 /* padding length byte */ + mac_size;
        +	/* Check if version requires explicit IV */
        +	if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION)
        +		{
        +		/* These lengths are all public so we can test them in
        +		 * non-constant time.
        +		 */
        +		if (overhead + block_size > rec->length)
        +			return 0;
        +		/* We can now safely skip explicit IV */
        +		rec->data += block_size;
        +		rec->input += block_size;
        +		rec->length -= block_size;
        +		}
        +	else if (overhead > rec->length)
        +		return 0;
        +
        +	padding_length = rec->data[rec->length-1];
        +
        +	/* NB: if compression is in operation the first packet may not be of
        +	 * even length so the padding bug check cannot be performed. This bug
        +	 * workaround has been around since SSLeay so hopefully it is either
        +	 * fixed now or no buggy implementation supports compression [steve]
        +	 */
        +	if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand)
        +		{
        +		/* First packet is even in size, so check */
        +		if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) &&
        +		    !(padding_length & 1))
        +			{
        +			s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
        +			}
        +		if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) &&
        +		    padding_length > 0)
        +			{
        +			padding_length--;
        +			}
        +		}
        +
        +	if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
        +		{
        +		/* padding is already verified */
        +		rec->length -= padding_length + 1;
        +		return 1;
        +		}
        +
        +	good = constant_time_ge(rec->length, overhead+padding_length);
        +	/* The padding consists of a length byte at the end of the record and
        +	 * then that many bytes of padding, all with the same value as the
        +	 * length byte. Thus, with the length byte included, there are i+1
        +	 * bytes of padding.
        +	 *
        +	 * We can't check just |padding_length+1| bytes because that leaks
        +	 * decrypted information. Therefore we always have to check the maximum
        +	 * amount of padding possible. (Again, the length of the record is
        +	 * public information so we can use it.) */
        +	to_check = 255; /* maximum amount of padding. */
        +	if (to_check > rec->length-1)
        +		to_check = rec->length-1;
        +
        +	for (i = 0; i < to_check; i++)
        +		{
        +		unsigned char mask = constant_time_ge(padding_length, i);
        +		unsigned char b = rec->data[rec->length-1-i];
        +		/* The final |padding_length+1| bytes should all have the value
        +		 * |padding_length|. Therefore the XOR should be zero. */
        +		good &= ~(mask&(padding_length ^ b));
        +		}
        +
        +	/* If any of the final |padding_length+1| bytes had the wrong value,
        +	 * one or more of the lower eight bits of |good| will be cleared. We
        +	 * AND the bottom 8 bits together and duplicate the result to all the
        +	 * bits. */
        +	good &= good >> 4;
        +	good &= good >> 2;
        +	good &= good >> 1;
        +	good <<= sizeof(good)*8-1;
        +	good = DUPLICATE_MSB_TO_ALL(good);
        +
        +	padding_length = good & (padding_length+1);
        +	rec->length -= padding_length;
        +	rec->type |= padding_length<<8;	/* kludge: pass padding length */
        +
        +	return (int)((good & 1) | (~good & -1));
        +	}
        +
        +/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
        + * constant time (independent of the concrete value of rec->length, which may
        + * vary within a 256-byte window).
        + *
        + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
        + * this function.
        + *
        + * On entry:
        + *   rec->orig_len >= md_size
        + *   md_size <= EVP_MAX_MD_SIZE
        + *
        + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
        + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
        + * a single or pair of cache-lines, then the variable memory accesses don't
        + * actually affect the timing. CPUs with smaller cache-lines [if any] are
        + * not multi-core and are not considered vulnerable to cache-timing attacks.
        + */
        +#define CBC_MAC_ROTATE_IN_PLACE
        +
        +void ssl3_cbc_copy_mac(unsigned char* out,
        +		       const SSL3_RECORD *rec,
        +		       unsigned md_size,unsigned orig_len)
        +	{
        +#if defined(CBC_MAC_ROTATE_IN_PLACE)
        +	unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE];
        +	unsigned char *rotated_mac;
        +#else
        +	unsigned char rotated_mac[EVP_MAX_MD_SIZE];
        +#endif
        +
        +	/* mac_end is the index of |rec->data| just after the end of the MAC. */
        +	unsigned mac_end = rec->length;
        +	unsigned mac_start = mac_end - md_size;
        +	/* scan_start contains the number of bytes that we can ignore because
        +	 * the MAC's position can only vary by 255 bytes. */
        +	unsigned scan_start = 0;
        +	unsigned i, j;
        +	unsigned div_spoiler;
        +	unsigned rotate_offset;
        +
        +	OPENSSL_assert(orig_len >= md_size);
        +	OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
        +
        +#if defined(CBC_MAC_ROTATE_IN_PLACE)
        +	rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63);
        +#endif
        +
        +	/* This information is public so it's safe to branch based on it. */
        +	if (orig_len > md_size + 255 + 1)
        +		scan_start = orig_len - (md_size + 255 + 1);
        +	/* div_spoiler contains a multiple of md_size that is used to cause the
        +	 * modulo operation to be constant time. Without this, the time varies
        +	 * based on the amount of padding when running on Intel chips at least.
        +	 *
        +	 * The aim of right-shifting md_size is so that the compiler doesn't
        +	 * figure out that it can remove div_spoiler as that would require it
        +	 * to prove that md_size is always even, which I hope is beyond it. */
        +	div_spoiler = md_size >> 1;
        +	div_spoiler <<= (sizeof(div_spoiler)-1)*8;
        +	rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
        +
        +	memset(rotated_mac, 0, md_size);
        +	for (i = scan_start, j = 0; i < orig_len; i++)
        +		{
        +		unsigned char mac_started = constant_time_ge(i, mac_start);
        +		unsigned char mac_ended = constant_time_ge(i, mac_end);
        +		unsigned char b = rec->data[i];
        +		rotated_mac[j++] |= b & mac_started & ~mac_ended;
        +		j &= constant_time_lt(j,md_size);
        +		}
        +
        +	/* Now rotate the MAC */
        +#if defined(CBC_MAC_ROTATE_IN_PLACE)
        +	j = 0;
        +	for (i = 0; i < md_size; i++)
        +		{
        +		/* in case cache-line is 32 bytes, touch second line */
        +		((volatile unsigned char *)rotated_mac)[rotate_offset^32];
        +		out[j++] = rotated_mac[rotate_offset++];
        +		rotate_offset &= constant_time_lt(rotate_offset,md_size);
        +		}
        +#else
        +	memset(out, 0, md_size);
        +	rotate_offset = md_size - rotate_offset;
        +	rotate_offset &= constant_time_lt(rotate_offset,md_size);
        +	for (i = 0; i < md_size; i++)
        +		{
        +		for (j = 0; j < md_size; j++)
        +			out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
        +		rotate_offset++;
        +		rotate_offset &= constant_time_lt(rotate_offset,md_size);
        +		}
        +#endif
        +	}
        +
        +/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
        + * little-endian order. The value of p is advanced by four. */
        +#define u32toLE(n, p) \
        +	(*((p)++)=(unsigned char)(n), \
        +	 *((p)++)=(unsigned char)(n>>8), \
        +	 *((p)++)=(unsigned char)(n>>16), \
        +	 *((p)++)=(unsigned char)(n>>24))
        +
        +/* These functions serialize the state of a hash and thus perform the standard
        + * "final" operation without adding the padding and length that such a function
        + * typically does. */
        +static void tls1_md5_final_raw(void* ctx, unsigned char *md_out)
        +	{
        +	MD5_CTX *md5 = ctx;
        +	u32toLE(md5->A, md_out);
        +	u32toLE(md5->B, md_out);
        +	u32toLE(md5->C, md_out);
        +	u32toLE(md5->D, md_out);
        +	}
        +
        +static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
        +	{
        +	SHA_CTX *sha1 = ctx;
        +	l2n(sha1->h0, md_out);
        +	l2n(sha1->h1, md_out);
        +	l2n(sha1->h2, md_out);
        +	l2n(sha1->h3, md_out);
        +	l2n(sha1->h4, md_out);
        +	}
        +#define LARGEST_DIGEST_CTX SHA_CTX
        +
        +#ifndef OPENSSL_NO_SHA256
        +static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
        +	{
        +	SHA256_CTX *sha256 = ctx;
        +	unsigned i;
        +
        +	for (i = 0; i < 8; i++)
        +		{
        +		l2n(sha256->h[i], md_out);
        +		}
        +	}
        +#undef  LARGEST_DIGEST_CTX
        +#define LARGEST_DIGEST_CTX SHA256_CTX
        +#endif
        +
        +#ifndef OPENSSL_NO_SHA512
        +static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
        +	{
        +	SHA512_CTX *sha512 = ctx;
        +	unsigned i;
        +
        +	for (i = 0; i < 8; i++)
        +		{
        +		l2n8(sha512->h[i], md_out);
        +		}
        +	}
        +#undef  LARGEST_DIGEST_CTX
        +#define LARGEST_DIGEST_CTX SHA512_CTX
        +#endif
        +
        +/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
        + * which ssl3_cbc_digest_record supports. */
        +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
        +	{
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode())
        +		return 0;
        +#endif
        +	switch (EVP_MD_CTX_type(ctx))
        +		{
        +		case NID_md5:
        +		case NID_sha1:
        +#ifndef OPENSSL_NO_SHA256
        +		case NID_sha224:
        +		case NID_sha256:
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +		case NID_sha384:
        +		case NID_sha512:
        +#endif
        +			return 1;
        +		default:
        +			return 0;
        +		}
        +	}
        +
        +/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
        + * record.
        + *
        + *   ctx: the EVP_MD_CTX from which we take the hash function.
        + *     ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
        + *   md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
        + *   md_out_size: if non-NULL, the number of output bytes is written here.
        + *   header: the 13-byte, TLS record header.
        + *   data: the record data itself, less any preceeding explicit IV.
        + *   data_plus_mac_size: the secret, reported length of the data and MAC
        + *     once the padding has been removed.
        + *   data_plus_mac_plus_padding_size: the public length of the whole
        + *     record, including padding.
        + *   is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
        + *
        + * On entry: by virtue of having been through one of the remove_padding
        + * functions, above, we know that data_plus_mac_size is large enough to contain
        + * a padding byte and MAC. (If the padding was invalid, it might contain the
        + * padding too. ) */
        +void ssl3_cbc_digest_record(
        +	const EVP_MD_CTX *ctx,
        +	unsigned char* md_out,
        +	size_t* md_out_size,
        +	const unsigned char header[13],
        +	const unsigned char *data,
        +	size_t data_plus_mac_size,
        +	size_t data_plus_mac_plus_padding_size,
        +	const unsigned char *mac_secret,
        +	unsigned mac_secret_length,
        +	char is_sslv3)
        +	{
        +	union {	double align;
        +		unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state;
        +	void (*md_final_raw)(void *ctx, unsigned char *md_out);
        +	void (*md_transform)(void *ctx, const unsigned char *block);
        +	unsigned md_size, md_block_size = 64;
        +	unsigned sslv3_pad_length = 40, header_length, variance_blocks,
        +		 len, max_mac_bytes, num_blocks,
        +		 num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
        +	unsigned int bits;	/* at most 18 bits */
        +	unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
        +	/* hmac_pad is the masked HMAC key. */
        +	unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
        +	unsigned char first_block[MAX_HASH_BLOCK_SIZE];
        +	unsigned char mac_out[EVP_MAX_MD_SIZE];
        +	unsigned i, j, md_out_size_u;
        +	EVP_MD_CTX md_ctx;
        +	/* mdLengthSize is the number of bytes in the length field that terminates
        +	* the hash. */
        +	unsigned md_length_size = 8;
        +	char length_is_big_endian = 1;
        +
        +	/* This is a, hopefully redundant, check that allows us to forget about
        +	 * many possible overflows later in this function. */
        +	OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
        +
        +	switch (EVP_MD_CTX_type(ctx))
        +		{
        +		case NID_md5:
        +			MD5_Init((MD5_CTX*)md_state.c);
        +			md_final_raw = tls1_md5_final_raw;
        +			md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
        +			md_size = 16;
        +			sslv3_pad_length = 48;
        +			length_is_big_endian = 0;
        +			break;
        +		case NID_sha1:
        +			SHA1_Init((SHA_CTX*)md_state.c);
        +			md_final_raw = tls1_sha1_final_raw;
        +			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
        +			md_size = 20;
        +			break;
        +#ifndef OPENSSL_NO_SHA256
        +		case NID_sha224:
        +			SHA224_Init((SHA256_CTX*)md_state.c);
        +			md_final_raw = tls1_sha256_final_raw;
        +			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
        +			md_size = 224/8;
        +			break;
        +		case NID_sha256:
        +			SHA256_Init((SHA256_CTX*)md_state.c);
        +			md_final_raw = tls1_sha256_final_raw;
        +			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
        +			md_size = 32;
        +			break;
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +		case NID_sha384:
        +			SHA384_Init((SHA512_CTX*)md_state.c);
        +			md_final_raw = tls1_sha512_final_raw;
        +			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
        +			md_size = 384/8;
        +			md_block_size = 128;
        +			md_length_size = 16;
        +			break;
        +		case NID_sha512:
        +			SHA512_Init((SHA512_CTX*)md_state.c);
        +			md_final_raw = tls1_sha512_final_raw;
        +			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
        +			md_size = 64;
        +			md_block_size = 128;
        +			md_length_size = 16;
        +			break;
        +#endif
        +		default:
        +			/* ssl3_cbc_record_digest_supported should have been
        +			 * called first to check that the hash function is
        +			 * supported. */
        +			OPENSSL_assert(0);
        +			if (md_out_size)
        +				*md_out_size = -1;
        +			return;
        +		}
        +
        +	OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
        +	OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
        +	OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
        +
        +	header_length = 13;
        +	if (is_sslv3)
        +		{
        +		header_length =
        +			mac_secret_length +
        +			sslv3_pad_length +
        +			8 /* sequence number */ +
        +			1 /* record type */ +
        +			2 /* record length */;
        +		}
        +
        +	/* variance_blocks is the number of blocks of the hash that we have to
        +	 * calculate in constant time because they could be altered by the
        +	 * padding value.
        +	 *
        +	 * In SSLv3, the padding must be minimal so the end of the plaintext
        +	 * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
        +	 * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
        +	 * termination (0x80 + 64-bit length) don't fit in the final block, we
        +	 * say that the final two blocks can vary based on the padding.
        +	 *
        +	 * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
        +	 * required to be minimal. Therefore we say that the final six blocks
        +	 * can vary based on the padding.
        +	 *
        +	 * Later in the function, if the message is short and there obviously
        +	 * cannot be this many blocks then variance_blocks can be reduced. */
        +	variance_blocks = is_sslv3 ? 2 : 6;
        +	/* From now on we're dealing with the MAC, which conceptually has 13
        +	 * bytes of `header' before the start of the data (TLS) or 71/75 bytes
        +	 * (SSLv3) */
        +	len = data_plus_mac_plus_padding_size + header_length;
        +	/* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
        +	* |header|, assuming that there's no padding. */
        +	max_mac_bytes = len - md_size - 1;
        +	/* num_blocks is the maximum number of hash blocks. */
        +	num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
        +	/* In order to calculate the MAC in constant time we have to handle
        +	 * the final blocks specially because the padding value could cause the
        +	 * end to appear somewhere in the final |variance_blocks| blocks and we
        +	 * can't leak where. However, |num_starting_blocks| worth of data can
        +	 * be hashed right away because no padding value can affect whether
        +	 * they are plaintext. */
        +	num_starting_blocks = 0;
        +	/* k is the starting byte offset into the conceptual header||data where
        +	 * we start processing. */
        +	k = 0;
        +	/* mac_end_offset is the index just past the end of the data to be
        +	 * MACed. */
        +	mac_end_offset = data_plus_mac_size + header_length - md_size;
        +	/* c is the index of the 0x80 byte in the final hash block that
        +	 * contains application data. */
        +	c = mac_end_offset % md_block_size;
        +	/* index_a is the hash block number that contains the 0x80 terminating
        +	 * value. */
        +	index_a = mac_end_offset / md_block_size;
        +	/* index_b is the hash block number that contains the 64-bit hash
        +	 * length, in bits. */
        +	index_b = (mac_end_offset + md_length_size) / md_block_size;
        +	/* bits is the hash-length in bits. It includes the additional hash
        +	 * block for the masked HMAC key, or whole of |header| in the case of
        +	 * SSLv3. */
        +
        +	/* For SSLv3, if we're going to have any starting blocks then we need
        +	 * at least two because the header is larger than a single block. */
        +	if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0))
        +		{
        +		num_starting_blocks = num_blocks - variance_blocks;
        +		k = md_block_size*num_starting_blocks;
        +		}
        +
        +	bits = 8*mac_end_offset;
        +	if (!is_sslv3)
        +		{
        +		/* Compute the initial HMAC block. For SSLv3, the padding and
        +		 * secret bytes are included in |header| because they take more
        +		 * than a single block. */
        +		bits += 8*md_block_size;
        +		memset(hmac_pad, 0, md_block_size);
        +		OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
        +		memcpy(hmac_pad, mac_secret, mac_secret_length);
        +		for (i = 0; i < md_block_size; i++)
        +			hmac_pad[i] ^= 0x36;
        +
        +		md_transform(md_state.c, hmac_pad);
        +		}
        +
        +	if (length_is_big_endian)
        +		{
        +		memset(length_bytes,0,md_length_size-4);
        +		length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
        +		length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
        +		length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
        +		length_bytes[md_length_size-1] = (unsigned char)bits;
        +		}
        +	else
        +		{
        +		memset(length_bytes,0,md_length_size);
        +		length_bytes[md_length_size-5] = (unsigned char)(bits>>24);
        +		length_bytes[md_length_size-6] = (unsigned char)(bits>>16);
        +		length_bytes[md_length_size-7] = (unsigned char)(bits>>8);
        +		length_bytes[md_length_size-8] = (unsigned char)bits;
        +		}
        +
        +	if (k > 0)
        +		{
        +		if (is_sslv3)
        +			{
        +			/* The SSLv3 header is larger than a single block.
        +			 * overhang is the number of bytes beyond a single
        +			 * block that the header consumes: either 7 bytes
        +			 * (SHA1) or 11 bytes (MD5). */
        +			unsigned overhang = header_length-md_block_size;
        +			md_transform(md_state.c, header);
        +			memcpy(first_block, header + md_block_size, overhang);
        +			memcpy(first_block + overhang, data, md_block_size-overhang);
        +			md_transform(md_state.c, first_block);
        +			for (i = 1; i < k/md_block_size - 1; i++)
        +				md_transform(md_state.c, data + md_block_size*i - overhang);
        +			}
        +		else
        +			{
        +			/* k is a multiple of md_block_size. */
        +			memcpy(first_block, header, 13);
        +			memcpy(first_block+13, data, md_block_size-13);
        +			md_transform(md_state.c, first_block);
        +			for (i = 1; i < k/md_block_size; i++)
        +				md_transform(md_state.c, data + md_block_size*i - 13);
        +			}
        +		}
        +
        +	memset(mac_out, 0, sizeof(mac_out));
        +
        +	/* We now process the final hash blocks. For each block, we construct
        +	 * it in constant time. If the |i==index_a| then we'll include the 0x80
        +	 * bytes and zero pad etc. For each block we selectively copy it, in
        +	 * constant time, to |mac_out|. */
        +	for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++)
        +		{
        +		unsigned char block[MAX_HASH_BLOCK_SIZE];
        +		unsigned char is_block_a = constant_time_eq_8(i, index_a);
        +		unsigned char is_block_b = constant_time_eq_8(i, index_b);
        +		for (j = 0; j < md_block_size; j++)
        +			{
        +			unsigned char b = 0, is_past_c, is_past_cp1;
        +			if (k < header_length)
        +				b = header[k];
        +			else if (k < data_plus_mac_plus_padding_size + header_length)
        +				b = data[k-header_length];
        +			k++;
        +
        +			is_past_c = is_block_a & constant_time_ge(j, c);
        +			is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
        +			/* If this is the block containing the end of the
        +			 * application data, and we are at the offset for the
        +			 * 0x80 value, then overwrite b with 0x80. */
        +			b = (b&~is_past_c) | (0x80&is_past_c);
        +			/* If this the the block containing the end of the
        +			 * application data and we're past the 0x80 value then
        +			 * just write zero. */
        +			b = b&~is_past_cp1;
        +			/* If this is index_b (the final block), but not
        +			 * index_a (the end of the data), then the 64-bit
        +			 * length didn't fit into index_a and we're having to
        +			 * add an extra block of zeros. */
        +			b &= ~is_block_b | is_block_a;
        +
        +			/* The final bytes of one of the blocks contains the
        +			 * length. */
        +			if (j >= md_block_size - md_length_size)
        +				{
        +				/* If this is index_b, write a length byte. */
        +				b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
        +				}
        +			block[j] = b;
        +			}
        +
        +		md_transform(md_state.c, block);
        +		md_final_raw(md_state.c, block);
        +		/* If this is index_b, copy the hash value to |mac_out|. */
        +		for (j = 0; j < md_size; j++)
        +			mac_out[j] |= block[j]&is_block_b;
        +		}
        +
        +	EVP_MD_CTX_init(&md_ctx);
        +	EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */);
        +	if (is_sslv3)
        +		{
        +		/* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
        +		memset(hmac_pad, 0x5c, sslv3_pad_length);
        +
        +		EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
        +		EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
        +		EVP_DigestUpdate(&md_ctx, mac_out, md_size);
        +		}
        +	else
        +		{
        +		/* Complete the HMAC in the standard manner. */
        +		for (i = 0; i < md_block_size; i++)
        +			hmac_pad[i] ^= 0x6a;
        +
        +		EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
        +		EVP_DigestUpdate(&md_ctx, mac_out, md_size);
        +		}
        +	EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
        +	if (md_out_size)
        +		*md_out_size = md_out_size_u;
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	}
        +
        +#ifdef OPENSSL_FIPS
        +
        +/* Due to the need to use EVP in FIPS mode we can't reimplement digests but
        + * we can ensure the number of blocks processed is equal for all cases
        + * by digesting additional data.
        + */
        +
        +void tls_fips_digest_extra(
        +	const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
        +	const unsigned char *data, size_t data_len, size_t orig_len)
        +	{
        +	size_t block_size, digest_pad, blocks_data, blocks_orig;
        +	if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE)
        +		return;
        +	block_size = EVP_MD_CTX_block_size(mac_ctx);
        +	/* We are in FIPS mode if we get this far so we know we have only SHA*
        +	 * digests and TLS to deal with.
        +	 * Minimum digest padding length is 17 for SHA384/SHA512 and 9
        +	 * otherwise.
        +	 * Additional header is 13 bytes. To get the number of digest blocks
        +	 * processed round up the amount of data plus padding to the nearest
        +	 * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise.
        +	 * So we have:
        +	 * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size
        +	 * equivalently:
        +	 * blocks = (payload_len + digest_pad + 12)/block_size + 1
        +	 * HMAC adds a constant overhead.
        +	 * We're ultimately only interested in differences so this becomes
        +	 * blocks = (payload_len + 29)/128
        +	 * for SHA384/SHA512 and
        +	 * blocks = (payload_len + 21)/64
        +	 * otherwise.
        +	 */
        +	digest_pad = block_size == 64 ? 21 : 29;
        +	blocks_orig = (orig_len + digest_pad)/block_size;
        +	blocks_data = (data_len + digest_pad)/block_size;
        +	/* MAC enough blocks to make up the difference between the original
        +	 * and actual lengths plus one extra block to ensure this is never a
        +	 * no op. The "data" pointer should always have enough space to
        +	 * perform this operation as it is large enough for a maximum
        +	 * length TLS buffer. 
        +	 */
        +	EVP_DigestSignUpdate(mac_ctx, data,
        +				(blocks_orig - blocks_data + 1) * block_size);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/s3_clnt.c b/vendor/openssl/openssl/ssl/s3_clnt.c
        new file mode 100644
        index 000000000..344e2eb1a
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_clnt.c
        @@ -0,0 +1,3373 @@
        +/* ssl/s3_clnt.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-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * ECC cipher suite support in OpenSSL originally written by
        + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include "kssl_lcl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/md5.h>
        +#ifdef OPENSSL_FIPS
        +#include <openssl/fips.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +static const SSL_METHOD *ssl3_get_client_method(int ver);
        +static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
        +
        +static const SSL_METHOD *ssl3_get_client_method(int ver)
        +	{
        +	if (ver == SSL3_VERSION)
        +		return(SSLv3_client_method());
        +	else
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
        +			ssl_undefined_function,
        +			ssl3_connect,
        +			ssl3_get_client_method)
        +
        +int ssl3_connect(SSL *s)
        +	{
        +	BUF_MEM *buf=NULL;
        +	unsigned long Time=(unsigned long)time(NULL);
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int ret= -1;
        +	int new_state,state,skip=0;
        +
        +	RAND_add(&Time,sizeof(Time),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +	
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	/* If we're awaiting a HeartbeatResponse, pretend we
        +	 * already got and don't await it anymore, because
        +	 * Heartbeats don't make sense during handshakes anyway.
        +	 */
        +	if (s->tlsext_hb_pending)
        +		{
        +		s->tlsext_hb_pending = 0;
        +		s->tlsext_hb_seq++;
        +		}
        +#endif
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch(s->state)
        +			{
        +		case SSL_ST_RENEGOTIATE:
        +			s->renegotiate=1;
        +			s->state=SSL_ST_CONNECT;
        +			s->ctx->stats.sess_connect_renegotiate++;
        +			/* break */
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_CONNECT:
        +		case SSL_ST_BEFORE|SSL_ST_CONNECT:
        +		case SSL_ST_OK|SSL_ST_CONNECT:
        +
        +			s->server=0;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			if ((s->version & 0xff00 ) != 0x0300)
        +				{
        +				SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR);
        +				ret = -1;
        +				goto end;
        +				}
        +				
        +			/* s->version=SSL3_VERSION; */
        +			s->type=SSL_ST_CONNECT;
        +
        +			if (s->init_buf == NULL)
        +				{
        +				if ((buf=BUF_MEM_new()) == NULL)
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				s->init_buf=buf;
        +				buf=NULL;
        +				}
        +
        +			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
        +
        +			/* setup buffing BIO */
        +			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
        +
        +			/* don't push the buffering BIO quite yet */
        +
        +			ssl3_init_finished_mac(s);
        +
        +			s->state=SSL3_ST_CW_CLNT_HELLO_A;
        +			s->ctx->stats.sess_connect++;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_CLNT_HELLO_A:
        +		case SSL3_ST_CW_CLNT_HELLO_B:
        +
        +			s->shutdown=0;
        +			ret=ssl3_client_hello(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_SRVR_HELLO_A;
        +			s->init_num=0;
        +
        +			/* turn on buffering for the next lot of output */
        +			if (s->bbio != s->wbio)
        +				s->wbio=BIO_push(s->bbio,s->wbio);
        +
        +			break;
        +
        +		case SSL3_ST_CR_SRVR_HELLO_A:
        +		case SSL3_ST_CR_SRVR_HELLO_B:
        +			ret=ssl3_get_server_hello(s);
        +			if (ret <= 0) goto end;
        +
        +			if (s->hit)
        +				{
        +				s->state=SSL3_ST_CR_FINISHED_A;
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (s->tlsext_ticket_expected)
        +					{
        +					/* receive renewed session ticket */
        +					s->state=SSL3_ST_CR_SESSION_TICKET_A;
        +					}
        +#endif
        +				}
        +			else
        +				s->state=SSL3_ST_CR_CERT_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CR_CERT_A:
        +		case SSL3_ST_CR_CERT_B:
        +#ifndef OPENSSL_NO_TLSEXT
        +			ret=ssl3_check_finished(s);
        +			if (ret <= 0) goto end;
        +			if (ret == 2)
        +				{
        +				s->hit = 1;
        +				if (s->tlsext_ticket_expected)
        +					s->state=SSL3_ST_CR_SESSION_TICKET_A;
        +				else
        +					s->state=SSL3_ST_CR_FINISHED_A;
        +				s->init_num=0;
        +				break;
        +				}
        +#endif
        +			/* Check if it is anon DH/ECDH */
        +			/* or PSK */
        +			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
        +			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +				{
        +				ret=ssl3_get_server_certificate(s);
        +				if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (s->tlsext_status_expected)
        +					s->state=SSL3_ST_CR_CERT_STATUS_A;
        +				else
        +					s->state=SSL3_ST_CR_KEY_EXCH_A;
        +				}
        +			else
        +				{
        +				skip = 1;
        +				s->state=SSL3_ST_CR_KEY_EXCH_A;
        +				}
        +#else
        +				}
        +			else
        +				skip=1;
        +
        +			s->state=SSL3_ST_CR_KEY_EXCH_A;
        +#endif
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CR_KEY_EXCH_A:
        +		case SSL3_ST_CR_KEY_EXCH_B:
        +			ret=ssl3_get_key_exchange(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_CERT_REQ_A;
        +			s->init_num=0;
        +
        +			/* at this point we check that we have the
        +			 * required stuff from the server */
        +			if (!ssl3_check_cert_and_algorithm(s))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			break;
        +
        +		case SSL3_ST_CR_CERT_REQ_A:
        +		case SSL3_ST_CR_CERT_REQ_B:
        +			ret=ssl3_get_certificate_request(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_SRVR_DONE_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CR_SRVR_DONE_A:
        +		case SSL3_ST_CR_SRVR_DONE_B:
        +			ret=ssl3_get_server_done(s);
        +			if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_SRP
        +			if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP)
        +				{
        +				if ((ret = SRP_Calc_A_param(s))<=0)
        +					{
        +					SSLerr(SSL_F_SSL3_CONNECT,SSL_R_SRP_A_CALC);
        +					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
        +					goto end;
        +					}
        +				}
        +#endif
        +			if (s->s3->tmp.cert_req)
        +				s->state=SSL3_ST_CW_CERT_A;
        +			else
        +				s->state=SSL3_ST_CW_KEY_EXCH_A;
        +			s->init_num=0;
        +
        +			break;
        +
        +		case SSL3_ST_CW_CERT_A:
        +		case SSL3_ST_CW_CERT_B:
        +		case SSL3_ST_CW_CERT_C:
        +		case SSL3_ST_CW_CERT_D:
        +			ret=ssl3_send_client_certificate(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CW_KEY_EXCH_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_KEY_EXCH_A:
        +		case SSL3_ST_CW_KEY_EXCH_B:
        +			ret=ssl3_send_client_key_exchange(s);
        +			if (ret <= 0) goto end;
        +			/* EAY EAY EAY need to check for DH fix cert
        +			 * sent back */
        +			/* For TLS, cert_req is set to 2, so a cert chain
        +			 * of nothing is sent, but no verify packet is sent */
        +			/* XXX: For now, we do not support client 
        +			 * authentication in ECDH cipher suites with
        +			 * ECDH (rather than ECDSA) certificates.
        +			 * We need to skip the certificate verify 
        +			 * message when client's ECDH public key is sent 
        +			 * inside the client certificate.
        +			 */
        +			if (s->s3->tmp.cert_req == 1)
        +				{
        +				s->state=SSL3_ST_CW_CERT_VRFY_A;
        +				}
        +			else
        +				{
        +				s->state=SSL3_ST_CW_CHANGE_A;
        +				s->s3->change_cipher_spec=0;
        +				}
        +			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
        +				{
        +				s->state=SSL3_ST_CW_CHANGE_A;
        +				s->s3->change_cipher_spec=0;
        +				}
        +
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_CERT_VRFY_A:
        +		case SSL3_ST_CW_CERT_VRFY_B:
        +			ret=ssl3_send_client_verify(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CW_CHANGE_A;
        +			s->init_num=0;
        +			s->s3->change_cipher_spec=0;
        +			break;
        +
        +		case SSL3_ST_CW_CHANGE_A:
        +		case SSL3_ST_CW_CHANGE_B:
        +			ret=ssl3_send_change_cipher_spec(s,
        +				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
        +			if (ret <= 0) goto end;
        +
        +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
        +			s->state=SSL3_ST_CW_FINISHED_A;
        +#else
        +			if (s->s3->next_proto_neg_seen)
        +				s->state=SSL3_ST_CW_NEXT_PROTO_A;
        +			else
        +				s->state=SSL3_ST_CW_FINISHED_A;
        +#endif
        +			s->init_num=0;
        +
        +			s->session->cipher=s->s3->tmp.new_cipher;
        +#ifdef OPENSSL_NO_COMP
        +			s->session->compress_meth=0;
        +#else
        +			if (s->s3->tmp.new_compression == NULL)
        +				s->session->compress_meth=0;
        +			else
        +				s->session->compress_meth=
        +					s->s3->tmp.new_compression->id;
        +#endif
        +			if (!s->method->ssl3_enc->setup_key_block(s))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			if (!s->method->ssl3_enc->change_cipher_state(s,
        +				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			break;
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +		case SSL3_ST_CW_NEXT_PROTO_A:
        +		case SSL3_ST_CW_NEXT_PROTO_B:
        +			ret=ssl3_send_next_proto(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CW_FINISHED_A;
        +			break;
        +#endif
        +
        +		case SSL3_ST_CW_FINISHED_A:
        +		case SSL3_ST_CW_FINISHED_B:
        +			ret=ssl3_send_finished(s,
        +				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
        +				s->method->ssl3_enc->client_finished_label,
        +				s->method->ssl3_enc->client_finished_label_len);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CW_FLUSH;
        +
        +			/* clear flags */
        +			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
        +			if (s->hit)
        +				{
        +				s->s3->tmp.next_state=SSL_ST_OK;
        +				if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
        +					{
        +					s->state=SSL_ST_OK;
        +					s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
        +					s->s3->delay_buf_pop_ret=0;
        +					}
        +				}
        +			else
        +				{
        +#ifndef OPENSSL_NO_TLSEXT
        +				/* Allow NewSessionTicket if ticket expected */
        +				if (s->tlsext_ticket_expected)
        +					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
        +				else
        +#endif
        +				
        +				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
        +				}
        +			s->init_num=0;
        +			break;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		case SSL3_ST_CR_SESSION_TICKET_A:
        +		case SSL3_ST_CR_SESSION_TICKET_B:
        +			ret=ssl3_get_new_session_ticket(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_FINISHED_A;
        +			s->init_num=0;
        +		break;
        +
        +		case SSL3_ST_CR_CERT_STATUS_A:
        +		case SSL3_ST_CR_CERT_STATUS_B:
        +			ret=ssl3_get_cert_status(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_CR_KEY_EXCH_A;
        +			s->init_num=0;
        +		break;
        +#endif
        +
        +		case SSL3_ST_CR_FINISHED_A:
        +		case SSL3_ST_CR_FINISHED_B:
        +
        +			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
        +				SSL3_ST_CR_FINISHED_B);
        +			if (ret <= 0) goto end;
        +
        +			if (s->hit)
        +				s->state=SSL3_ST_CW_CHANGE_A;
        +			else
        +				s->state=SSL_ST_OK;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_CW_FLUSH:
        +			s->rwstate=SSL_WRITING;
        +			if (BIO_flush(s->wbio) <= 0)
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			s->rwstate=SSL_NOTHING;
        +			s->state=s->s3->tmp.next_state;
        +			break;
        +
        +		case SSL_ST_OK:
        +			/* clean a few things up */
        +			ssl3_cleanup_key_block(s);
        +
        +			if (s->init_buf != NULL)
        +				{
        +				BUF_MEM_free(s->init_buf);
        +				s->init_buf=NULL;
        +				}
        +
        +			/* If we are not 'joining' the last two packets,
        +			 * remove the buffering now */
        +			if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
        +				ssl_free_wbio_buffer(s);
        +			/* else do it later in ssl3_write */
        +
        +			s->init_num=0;
        +			s->renegotiate=0;
        +			s->new_session=0;
        +
        +			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
        +			if (s->hit) s->ctx->stats.sess_hit++;
        +
        +			ret=1;
        +			/* s->server=0; */
        +			s->handshake_func=ssl3_connect;
        +			s->ctx->stats.sess_connect_good++;
        +
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
        +
        +			goto end;
        +			/* break; */
        +			
        +		default:
        +			SSLerr(SSL_F_SSL3_CONNECT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* break; */
        +			}
        +
        +		/* did we do anything */
        +		if (!s->s3->tmp.reuse_message && !skip)
        +			{
        +			if (s->debug)
        +				{
        +				if ((ret=BIO_flush(s->wbio)) <= 0)
        +					goto end;
        +				}
        +
        +			if ((cb != NULL) && (s->state != state))
        +				{
        +				new_state=s->state;
        +				s->state=state;
        +				cb(s,SSL_CB_CONNECT_LOOP,1);
        +				s->state=new_state;
        +				}
        +			}
        +		skip=0;
        +		}
        +end:
        +	s->in_handshake--;
        +	if (buf != NULL)
        +		BUF_MEM_free(buf);
        +	if (cb != NULL)
        +		cb(s,SSL_CB_CONNECT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +
        +int ssl3_client_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	int i;
        +	unsigned long Time,l;
        +#ifndef OPENSSL_NO_COMP
        +	int j;
        +	SSL_COMP *comp;
        +#endif
        +
        +	buf=(unsigned char *)s->init_buf->data;
        +	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
        +		{
        +		SSL_SESSION *sess = s->session;
        +		if ((sess == NULL) ||
        +			(sess->ssl_version != s->version) ||
        +#ifdef OPENSSL_NO_TLSEXT
        +			!sess->session_id_length ||
        +#else
        +			(!sess->session_id_length && !sess->tlsext_tick) ||
        +#endif
        +			(sess->not_resumable))
        +			{
        +			if (!ssl_get_new_session(s,0))
        +				goto err;
        +			}
        +		/* else use the pre-loaded session */
        +
        +		p=s->s3->client_random;
        +		Time=(unsigned long)time(NULL);			/* Time */
        +		l2n(Time,p);
        +		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
        +			goto err;
        +
        +		/* Do the message type and length last */
        +		d=p= &(buf[4]);
        +
        +		/* version indicates the negotiated version: for example from
        +		 * an SSLv2/v3 compatible client hello). The client_version
        +		 * field is the maximum version we permit and it is also
        +		 * used in RSA encrypted premaster secrets. Some servers can
        +		 * choke if we initially report a higher version then
        +		 * renegotiate to a lower one in the premaster secret. This
        +		 * didn't happen with TLS 1.0 as most servers supported it
        +		 * but it can with TLS 1.1 or later if the server only supports
        +		 * 1.0.
        +		 *
        +		 * Possible scenario with previous logic:
        +		 * 	1. Client hello indicates TLS 1.2
        +		 * 	2. Server hello says TLS 1.0
        +		 *	3. RSA encrypted premaster secret uses 1.2.
        +		 * 	4. Handhaked proceeds using TLS 1.0.
        +		 *	5. Server sends hello request to renegotiate.
        +		 *	6. Client hello indicates TLS v1.0 as we now
        +		 *	   know that is maximum server supports.
        +		 *	7. Server chokes on RSA encrypted premaster secret
        +		 *	   containing version 1.0.
        +		 *
        +		 * For interoperability it should be OK to always use the
        +		 * maximum version we support in client hello and then rely
        +		 * on the checking of version to ensure the servers isn't
        +		 * being inconsistent: for example initially negotiating with
        +		 * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
        +		 * client_version in client hello and not resetting it to
        +		 * the negotiated version.
        +		 */
        +#if 0
        +		*(p++)=s->version>>8;
        +		*(p++)=s->version&0xff;
        +		s->client_version=s->version;
        +#else
        +		*(p++)=s->client_version>>8;
        +		*(p++)=s->client_version&0xff;
        +#endif
        +
        +		/* Random stuff */
        +		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
        +		p+=SSL3_RANDOM_SIZE;
        +
        +		/* Session ID */
        +		if (s->new_session)
        +			i=0;
        +		else
        +			i=s->session->session_id_length;
        +		*(p++)=i;
        +		if (i != 0)
        +			{
        +			if (i > (int)sizeof(s->session->session_id))
        +				{
        +				SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			memcpy(p,s->session->session_id,i);
        +			p+=i;
        +			}
        +		
        +		/* Ciphers supported */
        +		i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
        +			goto err;
        +			}
        +#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
        +			/* Some servers hang if client hello > 256 bytes
        +			 * as hack workaround chop number of supported ciphers
        +			 * to keep it well below this if we use TLS v1.2
        +			 */
        +			if (TLS1_get_version(s) >= TLS1_2_VERSION
        +				&& i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
        +				i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
        +#endif
        +		s2n(i,p);
        +		p+=i;
        +
        +		/* COMPRESSION */
        +#ifdef OPENSSL_NO_COMP
        +		*(p++)=1;
        +#else
        +
        +		if ((s->options & SSL_OP_NO_COMPRESSION)
        +					|| !s->ctx->comp_methods)
        +			j=0;
        +		else
        +			j=sk_SSL_COMP_num(s->ctx->comp_methods);
        +		*(p++)=1+j;
        +		for (i=0; i<j; i++)
        +			{
        +			comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
        +			*(p++)=comp->id;
        +			}
        +#endif
        +		*(p++)=0; /* Add the NULL method */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		/* TLS extensions*/
        +		if (ssl_prepare_clienthello_tlsext(s) <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
        +			goto err;
        +			}
        +		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +#endif
        +		
        +		l=(p-d);
        +		d=buf;
        +		*(d++)=SSL3_MT_CLIENT_HELLO;
        +		l2n3(l,d);
        +
        +		s->state=SSL3_ST_CW_CLNT_HELLO_B;
        +		/* number of bytes to write */
        +		s->init_num=p-buf;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_CW_CLNT_HELLO_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +	return(-1);
        +	}
        +
        +int ssl3_get_server_hello(SSL *s)
        +	{
        +	STACK_OF(SSL_CIPHER) *sk;
        +	const SSL_CIPHER *c;
        +	unsigned char *p,*d;
        +	int i,al,ok;
        +	unsigned int j;
        +	long n;
        +#ifndef OPENSSL_NO_COMP
        +	SSL_COMP *comp;
        +#endif
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_SRVR_HELLO_A,
        +		SSL3_ST_CR_SRVR_HELLO_B,
        +		-1,
        +		20000, /* ?? */
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	if ( SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
        +		{
        +		if ( s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST)
        +			{
        +			if ( s->d1->send_cookie == 0)
        +				{
        +				s->s3->tmp.reuse_message = 1;
        +				return 1;
        +				}
        +			else /* already sent a cookie */
        +				{
        +				al=SSL_AD_UNEXPECTED_MESSAGE;
        +				SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE);
        +				goto f_err;
        +				}
        +			}
        +		}
        +	
        +	if ( s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE);
        +		goto f_err;
        +		}
        +
        +	d=p=(unsigned char *)s->init_msg;
        +
        +	if ((p[0] != (s->version>>8)) || (p[1] != (s->version&0xff)))
        +		{
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_SSL_VERSION);
        +		s->version=(s->version&0xff00)|p[1];
        +		al=SSL_AD_PROTOCOL_VERSION;
        +		goto f_err;
        +		}
        +	p+=2;
        +
        +	/* load the server hello data */
        +	/* load the server random */
        +	memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE);
        +	p+=SSL3_RANDOM_SIZE;
        +
        +	/* get the session-id */
        +	j= *(p++);
        +
        +	if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE))
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_LONG);
        +		goto f_err;
        +		}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	/* check if we want to resume the session based on external pre-shared secret */
        +	if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
        +		{
        +		SSL_CIPHER *pref_cipher=NULL;
        +		s->session->master_key_length=sizeof(s->session->master_key);
        +		if (s->tls_session_secret_cb(s, s->session->master_key,
        +					     &s->session->master_key_length,
        +					     NULL, &pref_cipher,
        +					     s->tls_session_secret_cb_arg))
        +			{
        +			s->session->cipher = pref_cipher ?
        +				pref_cipher : ssl_get_cipher_by_char(s, p+j);
        +			}
        +		}
        +#endif /* OPENSSL_NO_TLSEXT */
        +
        +	if (j != 0 && j == s->session->session_id_length
        +	    && memcmp(p,s->session->session_id,j) == 0)
        +	    {
        +	    if(s->sid_ctx_length != s->session->sid_ctx_length
        +	       || memcmp(s->session->sid_ctx,s->sid_ctx,s->sid_ctx_length))
        +		{
        +		/* actually a client application bug */
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
        +		goto f_err;
        +		}
        +	    s->hit=1;
        +	    }
        +	else	/* a miss or crap from the other end */
        +		{
        +		/* If we were trying for session-id reuse, make a new
        +		 * SSL_SESSION so we don't stuff up other people */
        +		s->hit=0;
        +		if (s->session->session_id_length > 0)
        +			{
        +			if (!ssl_get_new_session(s,0))
        +				{
        +				al=SSL_AD_INTERNAL_ERROR;
        +				goto f_err;
        +				}
        +			}
        +		s->session->session_id_length=j;
        +		memcpy(s->session->session_id,p,j); /* j could be 0 */
        +		}
        +	p+=j;
        +	c=ssl_get_cipher_by_char(s,p);
        +	if (c == NULL)
        +		{
        +		/* unknown cipher */
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
        +		goto f_err;
        +		}
        +	/* TLS v1.2 only ciphersuites require v1.2 or later */
        +	if ((c->algorithm_ssl & SSL_TLSV1_2) && 
        +		(TLS1_get_version(s) < TLS1_2_VERSION))
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
        +		goto f_err;
        +		}
        +	p+=ssl_put_cipher_by_char(s,NULL,NULL);
        +
        +	sk=ssl_get_ciphers_by_id(s);
        +	i=sk_SSL_CIPHER_find(sk,c);
        +	if (i < 0)
        +		{
        +		/* we did not say we would use this cipher */
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
        +		goto f_err;
        +		}
        +
        +	/* Depending on the session caching (internal/external), the cipher
        +	   and/or cipher_id values may not be set. Make sure that
        +	   cipher_id is set and use it for comparison. */
        +	if (s->session->cipher)
        +		s->session->cipher_id = s->session->cipher->id;
        +	if (s->hit && (s->session->cipher_id != c->id))
        +		{
        +/* Workaround is now obsolete */
        +#if 0
        +		if (!(s->options &
        +			SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))
        +#endif
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
        +			goto f_err;
        +			}
        +		}
        +	s->s3->tmp.new_cipher=c;
        +	/* Don't digest cached records if TLS v1.2: we may need them for
        +	 * client authentication.
        +	 */
        +	if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s))
        +		{
        +		al = SSL_AD_INTERNAL_ERROR;
        +		goto f_err;
        +		}
        +	/* lets get the compression algorithm */
        +	/* COMPRESSION */
        +#ifdef OPENSSL_NO_COMP
        +	if (*(p++) != 0)
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
        +		goto f_err;
        +		}
        +	/* If compression is disabled we'd better not try to resume a session
        +	 * using compression.
        +	 */
        +	if (s->session->compress_meth != 0)
        +		{
        +		al=SSL_AD_INTERNAL_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
        +		goto f_err;
        +		}
        +#else
        +	j= *(p++);
        +	if (s->hit && j != s->session->compress_meth)
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED);
        +		goto f_err;
        +		}
        +	if (j == 0)
        +		comp=NULL;
        +	else if (s->options & SSL_OP_NO_COMPRESSION)
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED);
        +		goto f_err;
        +		}
        +	else
        +		comp=ssl3_comp_find(s->ctx->comp_methods,j);
        +	
        +	if ((j != 0) && (comp == NULL))
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
        +		goto f_err;
        +		}
        +	else
        +		{
        +		s->s3->tmp.new_compression=comp;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	/* TLS extensions*/
        +	if (s->version >= SSL3_VERSION)
        +		{
        +		if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
        +			{
        +			/* 'al' set by ssl_parse_serverhello_tlsext */
        +			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_PARSE_TLSEXT);
        +			goto f_err; 
        +			}
        +		if (ssl_check_serverhello_tlsext(s) <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
        +				goto err;
        +			}
        +		}
        +#endif
        +
        +	if (p != (d+n))
        +		{
        +		/* wrong packet length */
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
        +		goto f_err;
        +		}
        +
        +	return(1);
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	return(-1);
        +	}
        +
        +int ssl3_get_server_certificate(SSL *s)
        +	{
        +	int al,i,ok,ret= -1;
        +	unsigned long n,nc,llen,l;
        +	X509 *x=NULL;
        +	const unsigned char *q,*p;
        +	unsigned char *d;
        +	STACK_OF(X509) *sk=NULL;
        +	SESS_CERT *sc;
        +	EVP_PKEY *pkey=NULL;
        +	int need_cert = 1; /* VRS: 0=> will allow null cert if auth == KRB5 */
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_CERT_A,
        +		SSL3_ST_CR_CERT_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) ||
        +		((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && 
        +		(s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)))
        +		{
        +		s->s3->tmp.reuse_message=1;
        +		return(1);
        +		}
        +
        +	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE);
        +		goto f_err;
        +		}
        +	p=d=(unsigned char *)s->init_msg;
        +
        +	if ((sk=sk_X509_new_null()) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	n2l3(p,llen);
        +	if (llen+3 != n)
        +		{
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	for (nc=0; nc<llen; )
        +		{
        +		n2l3(p,l);
        +		if ((l+nc+3) > llen)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
        +			goto f_err;
        +			}
        +
        +		q=p;
        +		x=d2i_X509(NULL,&q,l);
        +		if (x == NULL)
        +			{
        +			al=SSL_AD_BAD_CERTIFICATE;
        +			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_ASN1_LIB);
        +			goto f_err;
        +			}
        +		if (q != (p+l))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
        +			goto f_err;
        +			}
        +		if (!sk_X509_push(sk,x))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		x=NULL;
        +		nc+=l+3;
        +		p=q;
        +		}
        +
        +	i=ssl_verify_cert_chain(s,sk);
        +	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
        +#ifndef OPENSSL_NO_KRB5
        +	    && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
        +		 (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
        +#endif /* OPENSSL_NO_KRB5 */
        +		)
        +		{
        +		al=ssl_verify_alarm_type(s->verify_result);
        +		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
        +		goto f_err; 
        +		}
        +	ERR_clear_error(); /* but we keep s->verify_result */
        +
        +	sc=ssl_sess_cert_new();
        +	if (sc == NULL) goto err;
        +
        +	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
        +	s->session->sess_cert=sc;
        +
        +	sc->cert_chain=sk;
        +	/* Inconsistency alert: cert_chain does include the peer's
        +	 * certificate, which we don't include in s3_srvr.c */
        +	x=sk_X509_value(sk,0);
        +	sk=NULL;
        + 	/* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/
        +
        +	pkey=X509_get_pubkey(x);
        +
        +	/* VRS: allow null cert if auth == KRB5 */
        +	need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
        +	            (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
        +	            ? 0 : 1;
        +
        +#ifdef KSSL_DEBUG
        +	printf("pkey,x = %p, %p\n", pkey,x);
        +	printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
        +	printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
        +		s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert);
        +#endif    /* KSSL_DEBUG */
        +
        +	if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey)))
        +		{
        +		x=NULL;
        +		al=SSL3_AL_FATAL;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
        +			SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
        +		goto f_err;
        +		}
        +
        +	i=ssl_cert_type(x,pkey);
        +	if (need_cert && i < 0)
        +		{
        +		x=NULL;
        +		al=SSL3_AL_FATAL;
        +		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
        +			SSL_R_UNKNOWN_CERTIFICATE_TYPE);
        +		goto f_err;
        +		}
        +
        +	if (need_cert)
        +		{
        +		sc->peer_cert_type=i;
        +		CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
        +		/* Why would the following ever happen?
        +		 * We just created sc a couple of lines ago. */
        +		if (sc->peer_pkeys[i].x509 != NULL)
        +			X509_free(sc->peer_pkeys[i].x509);
        +		sc->peer_pkeys[i].x509=x;
        +		sc->peer_key= &(sc->peer_pkeys[i]);
        +
        +		if (s->session->peer != NULL)
        +			X509_free(s->session->peer);
        +		CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
        +		s->session->peer=x;
        +		}
        +	else
        +		{
        +		sc->peer_cert_type=i;
        +		sc->peer_key= NULL;
        +
        +		if (s->session->peer != NULL)
        +			X509_free(s->session->peer);
        +		s->session->peer=NULL;
        +		}
        +	s->session->verify_result = s->verify_result;
        +
        +	x=NULL;
        +	ret=1;
        +
        +	if (0)
        +		{
        +f_err:
        +		ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +		}
        +err:
        +	EVP_PKEY_free(pkey);
        +	X509_free(x);
        +	sk_X509_pop_free(sk,X509_free);
        +	return(ret);
        +	}
        +
        +int ssl3_get_key_exchange(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	unsigned char *q,md_buf[EVP_MAX_MD_SIZE*2];
        +#endif
        +	EVP_MD_CTX md_ctx;
        +	unsigned char *param,*p;
        +	int al,i,j,param_len,ok;
        +	long n,alg_k,alg_a;
        +	EVP_PKEY *pkey=NULL;
        +	const EVP_MD *md = NULL;
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rsa=NULL;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	DH *dh=NULL;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh = NULL;
        +	BN_CTX *bn_ctx = NULL;
        +	EC_POINT *srvr_ecpoint = NULL;
        +	int curve_nid = 0;
        +	int encoded_pt_len = 0;
        +#endif
        +
        +	/* use same message size as in ssl3_get_certificate_request()
        +	 * as ServerKeyExchange message may be skipped */
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_KEY_EXCH_A,
        +		SSL3_ST_CR_KEY_EXCH_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +	if (!ok) return((int)n);
        +
        +	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
        +		{
        +#ifndef OPENSSL_NO_PSK
        +		/* In plain PSK ciphersuite, ServerKeyExchange can be
        +		   omitted if no identity hint is sent. Set
        +		   session->sess_cert anyway to avoid problems
        +		   later.*/
        +		if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
        +			{
        +			s->session->sess_cert=ssl_sess_cert_new();
        +			if (s->ctx->psk_identity_hint)
        +				OPENSSL_free(s->ctx->psk_identity_hint);
        +			s->ctx->psk_identity_hint = NULL;
        +			}
        +#endif
        +		s->s3->tmp.reuse_message=1;
        +		return(1);
        +		}
        +
        +	param=p=(unsigned char *)s->init_msg;
        +	if (s->session->sess_cert != NULL)
        +		{
        +#ifndef OPENSSL_NO_RSA
        +		if (s->session->sess_cert->peer_rsa_tmp != NULL)
        +			{
        +			RSA_free(s->session->sess_cert->peer_rsa_tmp);
        +			s->session->sess_cert->peer_rsa_tmp=NULL;
        +			}
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		if (s->session->sess_cert->peer_dh_tmp)
        +			{
        +			DH_free(s->session->sess_cert->peer_dh_tmp);
        +			s->session->sess_cert->peer_dh_tmp=NULL;
        +			}
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +		if (s->session->sess_cert->peer_ecdh_tmp)
        +			{
        +			EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
        +			s->session->sess_cert->peer_ecdh_tmp=NULL;
        +			}
        +#endif
        +		}
        +	else
        +		{
        +		s->session->sess_cert=ssl_sess_cert_new();
        +		}
        +
        +	param_len=0;
        +	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
        +	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
        +	EVP_MD_CTX_init(&md_ctx);
        +
        +#ifndef OPENSSL_NO_PSK
        +	if (alg_k & SSL_kPSK)
        +		{
        +		char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
        +
        +		al=SSL_AD_HANDSHAKE_FAILURE;
        +		n2s(p,i);
        +		param_len=i+2;
        +		/* Store PSK identity hint for later use, hint is used
        +		 * in ssl3_send_client_key_exchange.  Assume that the
        +		 * maximum length of a PSK identity hint can be as
        +		 * long as the maximum length of a PSK identity. */
        +		if (i > PSK_MAX_IDENTITY_LEN)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
        +				SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto f_err;
        +			}
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
        +				SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
        +			goto f_err;
        +			}
        +		/* If received PSK identity hint contains NULL
        +		 * characters, the hint is truncated from the first
        +		 * NULL. p may not be ending with NULL, so create a
        +		 * NULL-terminated string. */
        +		memcpy(tmp_id_hint, p, i);
        +		memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
        +		if (s->ctx->psk_identity_hint != NULL)
        +			OPENSSL_free(s->ctx->psk_identity_hint);
        +		s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
        +		if (s->ctx->psk_identity_hint == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
        +			goto f_err;
        +			}	   
        +
        +		p+=i;
        +		n-=param_len;
        +		}
        +	else
        +#endif /* !OPENSSL_NO_PSK */
        +#ifndef OPENSSL_NO_SRP
        +	if (alg_k & SSL_kSRP)
        +		{
        +		n2s(p,i);
        +		param_len=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +
        +		n2s(p,i);
        +		param_len+=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +
        +		i = (unsigned int)(p[0]);
        +		p++;
        +		param_len+=i+1;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +
        +		n2s(p,i);
        +		param_len+=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +		n-=param_len;
        +
        +/* We must check if there is a certificate */
        +#ifndef OPENSSL_NO_RSA
        +		if (alg_a & SSL_aRSA)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
        +#else
        +		if (0)
        +			;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +		else if (alg_a & SSL_aDSS)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
        +#endif
        +		}
        +	else
        +#endif /* !OPENSSL_NO_SRP */
        +#ifndef OPENSSL_NO_RSA
        +	if (alg_k & SSL_kRSA)
        +		{
        +		if ((rsa=RSA_new()) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		n2s(p,i);
        +		param_len=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +
        +		n2s(p,i);
        +		param_len+=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +		n-=param_len;
        +
        +		/* this should be because we are using an export cipher */
        +		if (alg_a & SSL_aRSA)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
        +		else
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		s->session->sess_cert->peer_rsa_tmp=rsa;
        +		rsa=NULL;
        +		}
        +#else /* OPENSSL_NO_RSA */
        +	if (0)
        +		;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	else if (alg_k & SSL_kEDH)
        +		{
        +		if ((dh=DH_new()) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);
        +			goto err;
        +			}
        +		n2s(p,i);
        +		param_len=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(dh->p=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +
        +		n2s(p,i);
        +		param_len+=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(dh->g=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +
        +		n2s(p,i);
        +		param_len+=i+2;
        +		if (param_len > n)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);
        +			goto f_err;
        +			}
        +		if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
        +			goto err;
        +			}
        +		p+=i;
        +		n-=param_len;
        +
        +#ifndef OPENSSL_NO_RSA
        +		if (alg_a & SSL_aRSA)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
        +#else
        +		if (0)
        +			;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +		else if (alg_a & SSL_aDSS)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
        +#endif
        +		/* else anonymous DH, so no certificate or pkey. */
        +
        +		s->session->sess_cert->peer_dh_tmp=dh;
        +		dh=NULL;
        +		}
        +	else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd))
        +		{
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
        +		goto f_err;
        +		}
        +#endif /* !OPENSSL_NO_DH */
        +
        +#ifndef OPENSSL_NO_ECDH
        +	else if (alg_k & SSL_kEECDH)
        +		{
        +		EC_GROUP *ngroup;
        +		const EC_GROUP *group;
        +
        +		if ((ecdh=EC_KEY_new()) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* Extract elliptic curve parameters and the
        +		 * server's ephemeral ECDH public key.
        +		 * Keep accumulating lengths of various components in
        +		 * param_len and make sure it never exceeds n.
        +		 */
        +
        +		/* XXX: For now we only support named (not generic) curves
        +		 * and the ECParameters in this case is just three bytes.
        +		 */
        +		param_len=3;
        +		if ((param_len > n) ||
        +		    (*p != NAMED_CURVE_TYPE) || 
        +		    ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) 
        +			{
        +			al=SSL_AD_INTERNAL_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
        +			goto f_err;
        +			}
        +
        +		ngroup = EC_GROUP_new_by_curve_name(curve_nid);
        +		if (ngroup == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		if (EC_KEY_set_group(ecdh, ngroup) == 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		EC_GROUP_free(ngroup);
        +
        +		group = EC_KEY_get0_group(ecdh);
        +
        +		if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
        +		    (EC_GROUP_get_degree(group) > 163))
        +			{
        +			al=SSL_AD_EXPORT_RESTRICTION;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
        +			goto f_err;
        +			}
        +
        +		p+=3;
        +
        +		/* Next, get the encoded ECPoint */
        +		if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
        +		    ((bn_ctx = BN_CTX_new()) == NULL))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		encoded_pt_len = *p;  /* length of encoded point */
        +		p+=1;
        +		param_len += (1 + encoded_pt_len);
        +		if ((param_len > n) ||
        +		    (EC_POINT_oct2point(group, srvr_ecpoint, 
        +			p, encoded_pt_len, bn_ctx) == 0))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT);
        +			goto f_err;
        +			}
        +
        +		n-=param_len;
        +		p+=encoded_pt_len;
        +
        +		/* The ECC/TLS specification does not mention
        +		 * the use of DSA to sign ECParameters in the server
        +		 * key exchange message. We do support RSA and ECDSA.
        +		 */
        +		if (0) ;
        +#ifndef OPENSSL_NO_RSA
        +		else if (alg_a & SSL_aRSA)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +		else if (alg_a & SSL_aECDSA)
        +			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
        +#endif
        +		/* else anonymous ECDH, so no certificate or pkey. */
        +		EC_KEY_set_public_key(ecdh, srvr_ecpoint);
        +		s->session->sess_cert->peer_ecdh_tmp=ecdh;
        +		ecdh=NULL;
        +		BN_CTX_free(bn_ctx);
        +		bn_ctx = NULL;
        +		EC_POINT_free(srvr_ecpoint);
        +		srvr_ecpoint = NULL;
        +		}
        +	else if (alg_k)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
        +		goto f_err;
        +		}
        +#endif /* !OPENSSL_NO_ECDH */
        +
        +
        +	/* p points to the next byte, there are 'n' bytes left */
        +
        +	/* if it was signed, check the signature */
        +	if (pkey != NULL)
        +		{
        +		if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +			{
        +			int sigalg = tls12_get_sigid(pkey);
        +			/* Should never happen */
        +			if (sigalg == -1)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			/* Check key type is consistent with signature */
        +			if (sigalg != (int)p[1])
        +				{
        +				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_TYPE);
        +				al=SSL_AD_DECODE_ERROR;
        +				goto f_err;
        +				}
        +			md = tls12_get_hash(p[0]);
        +			if (md == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
        +				al=SSL_AD_DECODE_ERROR;
        +				goto f_err;
        +				}
        +#ifdef SSL_DEBUG
        +fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
        +#endif
        +			p += 2;
        +			n -= 2;
        +			}
        +		else
        +			md = EVP_sha1();
        +			
        +		n2s(p,i);
        +		n-=2;
        +		j=EVP_PKEY_size(pkey);
        +
        +		if ((i != n) || (n > j) || (n <= 0))
        +			{
        +			/* wrong packet length */
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);
        +			goto f_err;
        +			}
        +
        +#ifndef OPENSSL_NO_RSA
        +		if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION)
        +			{
        +			int num;
        +
        +			j=0;
        +			q=md_buf;
        +			for (num=2; num > 0; num--)
        +				{
        +				EVP_MD_CTX_set_flags(&md_ctx,
        +					EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +				EVP_DigestInit_ex(&md_ctx,(num == 2)
        +					?s->ctx->md5:s->ctx->sha1, NULL);
        +				EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_DigestUpdate(&md_ctx,param,param_len);
        +				EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
        +				q+=i;
        +				j+=i;
        +				}
        +			i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
        +								pkey->pkey.rsa);
        +			if (i < 0)
        +				{
        +				al=SSL_AD_DECRYPT_ERROR;
        +				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT);
        +				goto f_err;
        +				}
        +			if (i == 0)
        +				{
        +				/* bad signature */
        +				al=SSL_AD_DECRYPT_ERROR;
        +				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
        +				goto f_err;
        +				}
        +			}
        +		else
        +#endif
        +			{
        +			EVP_VerifyInit_ex(&md_ctx, md, NULL);
        +			EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +			EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +			EVP_VerifyUpdate(&md_ctx,param,param_len);
        +			if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
        +				{
        +				/* bad signature */
        +				al=SSL_AD_DECRYPT_ERROR;
        +				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
        +				goto f_err;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK))
        +			/* aNULL or kPSK do not need public keys */
        +			{
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		/* still data left over */
        +		if (n != 0)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
        +			goto f_err;
        +			}
        +		}
        +	EVP_PKEY_free(pkey);
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return(1);
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	EVP_PKEY_free(pkey);
        +#ifndef OPENSSL_NO_RSA
        +	if (rsa != NULL)
        +		RSA_free(rsa);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	if (dh != NULL)
        +		DH_free(dh);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	BN_CTX_free(bn_ctx);
        +	EC_POINT_free(srvr_ecpoint);
        +	if (ecdh != NULL)
        +		EC_KEY_free(ecdh);
        +#endif
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return(-1);
        +	}
        +
        +int ssl3_get_certificate_request(SSL *s)
        +	{
        +	int ok,ret=0;
        +	unsigned long n,nc,l;
        +	unsigned int llen, ctype_num,i;
        +	X509_NAME *xn=NULL;
        +	const unsigned char *p,*q;
        +	unsigned char *d;
        +	STACK_OF(X509_NAME) *ca_sk=NULL;
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_CERT_REQ_A,
        +		SSL3_ST_CR_CERT_REQ_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	s->s3->tmp.cert_req=0;
        +
        +	if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
        +		{
        +		s->s3->tmp.reuse_message=1;
        +		/* If we get here we don't need any cached handshake records
        +		 * as we wont be doing client auth.
        +		 */
        +		if (s->s3->handshake_buffer)
        +			{
        +			if (!ssl3_digest_cached_records(s))
        +				goto err;
        +			}
        +		return(1);
        +		}
        +
        +	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST)
        +		{
        +		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
        +		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_WRONG_MESSAGE_TYPE);
        +		goto err;
        +		}
        +
        +	/* TLS does not like anon-DH with client cert */
        +	if (s->version > SSL3_VERSION)
        +		{
        +		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
        +			{
        +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
        +			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
        +			goto err;
        +			}
        +		}
        +
        +	p=d=(unsigned char *)s->init_msg;
        +
        +	if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	/* get the certificate types */
        +	ctype_num= *(p++);
        +	if (ctype_num > SSL3_CT_NUMBER)
        +		ctype_num=SSL3_CT_NUMBER;
        +	for (i=0; i<ctype_num; i++)
        +		s->s3->tmp.ctype[i]= p[i];
        +	p+=ctype_num;
        +	if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +		{
        +		n2s(p, llen);
        +		/* Check we have enough room for signature algorithms and
        +		 * following length value.
        +		 */
        +		if ((unsigned long)(p - d + llen + 2) > n)
        +			{
        +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +		if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
        +			{
        +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
        +			goto err;
        +			}
        +		p += llen;
        +		}
        +
        +	/* get the CA RDNs */
        +	n2s(p,llen);
        +#if 0
        +{
        +FILE *out;
        +out=fopen("/tmp/vsign.der","w");
        +fwrite(p,1,llen,out);
        +fclose(out);
        +}
        +#endif
        +
        +	if ((unsigned long)(p - d + llen) != n)
        +		{
        +		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +		SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
        +		goto err;
        +		}
        +
        +	for (nc=0; nc<llen; )
        +		{
        +		n2s(p,l);
        +		if ((l+nc+2) > llen)
        +			{
        +			if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
        +				goto cont; /* netscape bugs */
        +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_TOO_LONG);
        +			goto err;
        +			}
        +
        +		q=p;
        +
        +		if ((xn=d2i_X509_NAME(NULL,&q,l)) == NULL)
        +			{
        +			/* If netscape tolerance is on, ignore errors */
        +			if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG)
        +				goto cont;
        +			else
        +				{
        +				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +				SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_ASN1_LIB);
        +				goto err;
        +				}
        +			}
        +
        +		if (q != (p+l))
        +			{
        +			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_LENGTH_MISMATCH);
        +			goto err;
        +			}
        +		if (!sk_X509_NAME_push(ca_sk,xn))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		p+=l;
        +		nc+=l+2;
        +		}
        +
        +	if (0)
        +		{
        +cont:
        +		ERR_clear_error();
        +		}
        +
        +	/* we should setup a certificate to return.... */
        +	s->s3->tmp.cert_req=1;
        +	s->s3->tmp.ctype_num=ctype_num;
        +	if (s->s3->tmp.ca_names != NULL)
        +		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
        +	s->s3->tmp.ca_names=ca_sk;
        +	ca_sk=NULL;
        +
        +	ret=1;
        +err:
        +	if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free);
        +	return(ret);
        +	}
        +
        +static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
        +	{
        +	return(X509_NAME_cmp(*a,*b));
        +	}
        +#ifndef OPENSSL_NO_TLSEXT
        +int ssl3_get_new_session_ticket(SSL *s)
        +	{
        +	int ok,al,ret=0, ticklen;
        +	long n;
        +	const unsigned char *p;
        +	unsigned char *d;
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_SESSION_TICKET_A,
        +		SSL3_ST_CR_SESSION_TICKET_B,
        +		-1,
        +		16384,
        +		&ok);
        +
        +	if (!ok)
        +		return((int)n);
        +
        +	if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
        +		{
        +		s->s3->tmp.reuse_message=1;
        +		return(1);
        +		}
        +	if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
        +		goto f_err;
        +		}
        +	if (n < 6)
        +		{
        +		/* need at least ticket_lifetime_hint + ticket length */
        +		al = SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +
        +	p=d=(unsigned char *)s->init_msg;
        +	n2l(p, s->session->tlsext_tick_lifetime_hint);
        +	n2s(p, ticklen);
        +	/* ticket_lifetime_hint + ticket_length + ticket */
        +	if (ticklen + 6 != n)
        +		{
        +		al = SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	if (s->session->tlsext_tick)
        +		{
        +		OPENSSL_free(s->session->tlsext_tick);
        +		s->session->tlsext_ticklen = 0;
        +		}
        +	s->session->tlsext_tick = OPENSSL_malloc(ticklen);
        +	if (!s->session->tlsext_tick)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	memcpy(s->session->tlsext_tick, p, ticklen);
        +	s->session->tlsext_ticklen = ticklen;
        +	/* There are two ways to detect a resumed ticket sesion.
        +	 * One is to set an appropriate session ID and then the server
        +	 * must return a match in ServerHello. This allows the normal
        +	 * client session ID matching to work and we know much 
        +	 * earlier that the ticket has been accepted.
        +	 * 
        +	 * The other way is to set zero length session ID when the
        +	 * ticket is presented and rely on the handshake to determine
        +	 * session resumption.
        +	 *
        +	 * We choose the former approach because this fits in with
        +	 * assumptions elsewhere in OpenSSL. The session ID is set
        +	 * to the SHA256 (or SHA1 is SHA256 is disabled) hash of the
        +	 * ticket.
        +	 */ 
        +	EVP_Digest(p, ticklen,
        +			s->session->session_id, &s->session->session_id_length,
        +#ifndef OPENSSL_NO_SHA256
        +							EVP_sha256(), NULL);
        +#else
        +							EVP_sha1(), NULL);
        +#endif
        +	ret=1;
        +	return(ret);
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	return(-1);
        +	}
        +
        +int ssl3_get_cert_status(SSL *s)
        +	{
        +	int ok, al;
        +	unsigned long resplen,n;
        +	const unsigned char *p;
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_CERT_STATUS_A,
        +		SSL3_ST_CR_CERT_STATUS_B,
        +		SSL3_MT_CERTIFICATE_STATUS,
        +		16384,
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +	if (n < 4)
        +		{
        +		/* need at least status type + length */
        +		al = SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	p = (unsigned char *)s->init_msg;
        +	if (*p++ != TLSEXT_STATUSTYPE_ocsp)
        +		{
        +		al = SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_UNSUPPORTED_STATUS_TYPE);
        +		goto f_err;
        +		}
        +	n2l3(p, resplen);
        +	if (resplen + 4 != n)
        +		{
        +		al = SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	if (s->tlsext_ocsp_resp)
        +		OPENSSL_free(s->tlsext_ocsp_resp);
        +	s->tlsext_ocsp_resp = BUF_memdup(p, resplen);
        +	if (!s->tlsext_ocsp_resp)
        +		{
        +		al = SSL_AD_INTERNAL_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,ERR_R_MALLOC_FAILURE);
        +		goto f_err;
        +		}
        +	s->tlsext_ocsp_resplen = resplen;
        +	if (s->ctx->tlsext_status_cb)
        +		{
        +		int ret;
        +		ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
        +		if (ret == 0)
        +			{
        +			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
        +			SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_INVALID_STATUS_RESPONSE);
        +			goto f_err;
        +			}
        +		if (ret < 0)
        +			{
        +			al = SSL_AD_INTERNAL_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CERT_STATUS,ERR_R_MALLOC_FAILURE);
        +			goto f_err;
        +			}
        +		}
        +	return 1;
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +	return(-1);
        +	}
        +#endif
        +
        +int ssl3_get_server_done(SSL *s)
        +	{
        +	int ok,ret=0;
        +	long n;
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_SRVR_DONE_A,
        +		SSL3_ST_CR_SRVR_DONE_B,
        +		SSL3_MT_SERVER_DONE,
        +		30, /* should be very small, like 0 :-) */
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +	if (n > 0)
        +		{
        +		/* should contain no data */
        +		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
        +		SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_LENGTH_MISMATCH);
        +		return -1;
        +		}
        +	ret=1;
        +	return(ret);
        +	}
        +
        +
        +int ssl3_send_client_key_exchange(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	int n;
        +	unsigned long alg_k;
        +#ifndef OPENSSL_NO_RSA
        +	unsigned char *q;
        +	EVP_PKEY *pkey=NULL;
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +	KSSL_ERR kssl_err;
        +#endif /* OPENSSL_NO_KRB5 */
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *clnt_ecdh = NULL;
        +	const EC_POINT *srvr_ecpoint = NULL;
        +	EVP_PKEY *srvr_pub_pkey = NULL;
        +	unsigned char *encodedPoint = NULL;
        +	int encoded_pt_len = 0;
        +	BN_CTX * bn_ctx = NULL;
        +#endif
        +
        +	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
        +		{
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[4]);
        +
        +		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
        +
        +		/* Fool emacs indentation */
        +		if (0) {}
        +#ifndef OPENSSL_NO_RSA
        +		else if (alg_k & SSL_kRSA)
        +			{
        +			RSA *rsa;
        +			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
        +
        +			if (s->session->sess_cert->peer_rsa_tmp != NULL)
        +				rsa=s->session->sess_cert->peer_rsa_tmp;
        +			else
        +				{
        +				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
        +				if ((pkey == NULL) ||
        +					(pkey->type != EVP_PKEY_RSA) ||
        +					(pkey->pkey.rsa == NULL))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +					goto err;
        +					}
        +				rsa=pkey->pkey.rsa;
        +				EVP_PKEY_free(pkey);
        +				}
        +				
        +			tmp_buf[0]=s->client_version>>8;
        +			tmp_buf[1]=s->client_version&0xff;
        +			if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
        +					goto err;
        +
        +			s->session->master_key_length=sizeof tmp_buf;
        +
        +			q=p;
        +			/* Fix buf for TLS and beyond */
        +			if (s->version > SSL3_VERSION)
        +				p+=2;
        +			n=RSA_public_encrypt(sizeof tmp_buf,
        +				tmp_buf,p,rsa,RSA_PKCS1_PADDING);
        +#ifdef PKCS1_CHECK
        +			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
        +			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
        +#endif
        +			if (n <= 0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
        +				goto err;
        +				}
        +
        +			/* Fix buf for TLS and beyond */
        +			if (s->version > SSL3_VERSION)
        +				{
        +				s2n(n,q);
        +				n+=2;
        +				}
        +
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,
        +					tmp_buf,sizeof tmp_buf);
        +			OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
        +			}
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +		else if (alg_k & SSL_kKRB5)
        +			{
        +			krb5_error_code	krb5rc;
        +			KSSL_CTX	*kssl_ctx = s->kssl_ctx;
        +			/*  krb5_data	krb5_ap_req;  */
        +			krb5_data	*enc_ticket;
        +			krb5_data	authenticator, *authp = NULL;
        +			EVP_CIPHER_CTX	ciph_ctx;
        +			const EVP_CIPHER *enc = NULL;
        +			unsigned char	iv[EVP_MAX_IV_LENGTH];
        +			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
        +			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH 
        +						+ EVP_MAX_IV_LENGTH];
        +			int 		padl, outl = sizeof(epms);
        +
        +			EVP_CIPHER_CTX_init(&ciph_ctx);
        +
        +#ifdef KSSL_DEBUG
        +			printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
        +				alg_k, SSL_kKRB5);
        +#endif	/* KSSL_DEBUG */
        +
        +			authp = NULL;
        +#ifdef KRB5SENDAUTH
        +			if (KRB5SENDAUTH)  authp = &authenticator;
        +#endif	/* KRB5SENDAUTH */
        +
        +			krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
        +				&kssl_err);
        +			enc = kssl_map_enc(kssl_ctx->enctype);
        +			if (enc == NULL)
        +			    goto err;
        +#ifdef KSSL_DEBUG
        +			{
        +			printf("kssl_cget_tkt rtn %d\n", krb5rc);
        +			if (krb5rc && kssl_err.text)
        +			  printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
        +			}
        +#endif	/* KSSL_DEBUG */
        +
        +			if (krb5rc)
        +				{
        +				ssl3_send_alert(s,SSL3_AL_FATAL,
        +						SSL_AD_HANDSHAKE_FAILURE);
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +						kssl_err.reason);
        +				goto err;
        +				}
        +
        +			/*  20010406 VRS - Earlier versions used KRB5 AP_REQ
        +			**  in place of RFC 2712 KerberosWrapper, as in:
        +			**
        +			**  Send ticket (copy to *p, set n = length)
        +			**  n = krb5_ap_req.length;
        +			**  memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
        +			**  if (krb5_ap_req.data)  
        +			**    kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
        +			**
        +			**  Now using real RFC 2712 KerberosWrapper
        +			**  (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
        +			**  Note: 2712 "opaque" types are here replaced
        +			**  with a 2-byte length followed by the value.
        +			**  Example:
        +			**  KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
        +			**  Where "xx xx" = length bytes.  Shown here with
        +			**  optional authenticator omitted.
        +			*/
        +
        +			/*  KerberosWrapper.Ticket		*/
        +			s2n(enc_ticket->length,p);
        +			memcpy(p, enc_ticket->data, enc_ticket->length);
        +			p+= enc_ticket->length;
        +			n = enc_ticket->length + 2;
        +
        +			/*  KerberosWrapper.Authenticator	*/
        +			if (authp  &&  authp->length)  
        +				{
        +				s2n(authp->length,p);
        +				memcpy(p, authp->data, authp->length);
        +				p+= authp->length;
        +				n+= authp->length + 2;
        +				
        +				free(authp->data);
        +				authp->data = NULL;
        +				authp->length = 0;
        +				}
        +			else
        +				{
        +				s2n(0,p);/*  null authenticator length	*/
        +				n+=2;
        +				}
        + 
        +			    tmp_buf[0]=s->client_version>>8;
        +			    tmp_buf[1]=s->client_version&0xff;
        +			    if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
        +				goto err;
        +
        +			/*  20010420 VRS.  Tried it this way; failed.
        +			**	EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
        +			**	EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
        +			**				kssl_ctx->length);
        +			**	EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
        +			*/
        +
        +			memset(iv, 0, sizeof iv);  /* per RFC 1510 */
        +			EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
        +				kssl_ctx->key,iv);
        +			EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
        +				sizeof tmp_buf);
        +			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
        +			outl += padl;
        +			if (outl > (int)sizeof epms)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			EVP_CIPHER_CTX_cleanup(&ciph_ctx);
        +
        +			/*  KerberosWrapper.EncryptedPreMasterSecret	*/
        +			s2n(outl,p);
        +			memcpy(p, epms, outl);
        +			p+=outl;
        +			n+=outl + 2;
        +
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,
        +					tmp_buf, sizeof tmp_buf);
        +
        +			OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
        +			OPENSSL_cleanse(epms, outl);
        +			}
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
        +			{
        +			DH *dh_srvr,*dh_clnt;
        +
        +			if (s->session->sess_cert == NULL) 
        +				{
        +				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
        +				goto err;
        +				}
        +
        +			if (s->session->sess_cert->peer_dh_tmp != NULL)
        +				dh_srvr=s->session->sess_cert->peer_dh_tmp;
        +			else
        +				{
        +				/* we get them from the cert */
        +				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
        +				goto err;
        +				}
        +			
        +			/* generate a new random key */
        +			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				goto err;
        +				}
        +			if (!DH_generate_key(dh_clnt))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				DH_free(dh_clnt);
        +				goto err;
        +				}
        +
        +			/* use the 'p' output buffer for the DH key, but
        +			 * make sure to clear it out afterwards */
        +
        +			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
        +
        +			if (n <= 0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				DH_free(dh_clnt);
        +				goto err;
        +				}
        +
        +			/* generate master key from the result */
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,p,n);
        +			/* clean up */
        +			memset(p,0,n);
        +
        +			/* send off the data */
        +			n=BN_num_bytes(dh_clnt->pub_key);
        +			s2n(n,p);
        +			BN_bn2bin(dh_clnt->pub_key,p);
        +			n+=2;
        +
        +			DH_free(dh_clnt);
        +
        +			/* perhaps clean things up a bit EAY EAY EAY EAY*/
        +			}
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH 
        +		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
        +			{
        +			const EC_GROUP *srvr_group = NULL;
        +			EC_KEY *tkey;
        +			int ecdh_clnt_cert = 0;
        +			int field_size = 0;
        +
        +			/* Did we send out the client's
        +			 * ECDH share for use in premaster
        +			 * computation as part of client certificate?
        +			 * If so, set ecdh_clnt_cert to 1.
        +			 */
        +			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
        +				{
        +				/* XXX: For now, we do not support client
        +				 * authentication using ECDH certificates.
        +				 * To add such support, one needs to add
        +				 * code that checks for appropriate 
        +				 * conditions and sets ecdh_clnt_cert to 1.
        +				 * For example, the cert have an ECC
        +				 * key on the same curve as the server's
        +				 * and the key should be authorized for
        +				 * key agreement.
        +				 *
        +				 * One also needs to add code in ssl3_connect
        +				 * to skip sending the certificate verify
        +				 * message.
        +				 *
        +				 * if ((s->cert->key->privatekey != NULL) &&
        +				 *     (s->cert->key->privatekey->type ==
        +				 *      EVP_PKEY_EC) && ...)
        +				 * ecdh_clnt_cert = 1;
        +				 */
        +				}
        +
        +			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
        +				{
        +				tkey = s->session->sess_cert->peer_ecdh_tmp;
        +				}
        +			else
        +				{
        +				/* Get the Server Public Key from Cert */
        +				srvr_pub_pkey = X509_get_pubkey(s->session-> \
        +				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
        +				if ((srvr_pub_pkey == NULL) ||
        +				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
        +				    (srvr_pub_pkey->pkey.ec == NULL))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					    ERR_R_INTERNAL_ERROR);
        +					goto err;
        +					}
        +
        +				tkey = srvr_pub_pkey->pkey.ec;
        +				}
        +
        +			srvr_group   = EC_KEY_get0_group(tkey);
        +			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
        +
        +			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +				    ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
        +				goto err;
        +				}
        +			if (ecdh_clnt_cert) 
        +				{ 
        +				/* Reuse key info from our certificate
        +				 * We only need our private key to perform
        +				 * the ECDH computation.
        +				 */
        +				const BIGNUM *priv_key;
        +				tkey = s->cert->key->privatekey->pkey.ec;
        +				priv_key = EC_KEY_get0_private_key(tkey);
        +				if (priv_key == NULL)
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
        +					goto err;
        +					}
        +				}
        +			else 
        +				{
        +				/* Generate a new ECDH key pair */
        +				if (!(EC_KEY_generate_key(clnt_ecdh)))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
        +					goto err;
        +					}
        +				}
        +
        +			/* use the 'p' output buffer for the ECDH key, but
        +			 * make sure to clear it out afterwards
        +			 */
        +
        +			field_size = EC_GROUP_get_degree(srvr_group);
        +			if (field_size <= 0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 
        +				       ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
        +			if (n <= 0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 
        +				       ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			/* generate master key from the result */
        +			s->session->master_key_length = s->method->ssl3_enc \
        +			    -> generate_master_secret(s, 
        +				s->session->master_key,
        +				p, n);
        +
        +			memset(p, 0, n); /* clean up */
        +
        +			if (ecdh_clnt_cert) 
        +				{
        +				/* Send empty client key exch message */
        +				n = 0;
        +				}
        +			else 
        +				{
        +				/* First check the size of encoding and
        +				 * allocate memory accordingly.
        +				 */
        +				encoded_pt_len = 
        +				    EC_POINT_point2oct(srvr_group, 
        +					EC_KEY_get0_public_key(clnt_ecdh), 
        +					POINT_CONVERSION_UNCOMPRESSED, 
        +					NULL, 0, NULL);
        +
        +				encodedPoint = (unsigned char *) 
        +				    OPENSSL_malloc(encoded_pt_len * 
        +					sizeof(unsigned char)); 
        +				bn_ctx = BN_CTX_new();
        +				if ((encodedPoint == NULL) || 
        +				    (bn_ctx == NULL)) 
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +					goto err;
        +					}
        +
        +				/* Encode the public key */
        +				n = EC_POINT_point2oct(srvr_group, 
        +				    EC_KEY_get0_public_key(clnt_ecdh), 
        +				    POINT_CONVERSION_UNCOMPRESSED, 
        +				    encodedPoint, encoded_pt_len, bn_ctx);
        +
        +				*p = n; /* length of encoded point */
        +				/* Encoded point will be copied here */
        +				p += 1; 
        +				/* copy the point */
        +				memcpy((unsigned char *)p, encodedPoint, n);
        +				/* increment n to account for length field */
        +				n += 1; 
        +				}
        +
        +			/* Free allocated memory */
        +			BN_CTX_free(bn_ctx);
        +			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
        +			if (clnt_ecdh != NULL) 
        +				 EC_KEY_free(clnt_ecdh);
        +			EVP_PKEY_free(srvr_pub_pkey);
        +			}
        +#endif /* !OPENSSL_NO_ECDH */
        +		else if (alg_k & SSL_kGOST) 
        +			{
        +			/* GOST key exchange message creation */
        +			EVP_PKEY_CTX *pkey_ctx;
        +			X509 *peer_cert; 
        +			size_t msglen;
        +			unsigned int md_len;
        +			int keytype;
        +			unsigned char premaster_secret[32],shared_ukm[32], tmp[256];
        +			EVP_MD_CTX *ukm_hash;
        +			EVP_PKEY *pub_key;
        +
        +			/* Get server sertificate PKEY and create ctx from it */
        +			peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST01)].x509;
        +			if (!peer_cert) 
        +				peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST94)].x509;
        +			if (!peer_cert)		{
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
        +					goto err;
        +				}	
        +				
        +			pkey_ctx=EVP_PKEY_CTX_new(pub_key=X509_get_pubkey(peer_cert),NULL);
        +			/* If we have send a certificate, and certificate key
        +
        +			 * parameters match those of server certificate, use
        +			 * certificate key for key exchange
        +			 */
        +
        +			 /* Otherwise, generate ephemeral key pair */
        +					
        +			EVP_PKEY_encrypt_init(pkey_ctx);
        +			  /* Generate session key */	
        +		    RAND_bytes(premaster_secret,32);
        +			/* If we have client certificate, use its secret as peer key */
        +			if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
        +				if (EVP_PKEY_derive_set_peer(pkey_ctx,s->cert->key->privatekey) <=0) {
        +					/* If there was an error - just ignore it. Ephemeral key
        +					* would be used
        +					*/
        +					ERR_clear_error();
        +				}
        +			}			
        +			/* Compute shared IV and store it in algorithm-specific
        +			 * context data */
        +			ukm_hash = EVP_MD_CTX_create();
        +			EVP_DigestInit(ukm_hash,EVP_get_digestbynid(NID_id_GostR3411_94));
        +			EVP_DigestUpdate(ukm_hash,s->s3->client_random,SSL3_RANDOM_SIZE);
        +			EVP_DigestUpdate(ukm_hash,s->s3->server_random,SSL3_RANDOM_SIZE);
        +			EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
        +			EVP_MD_CTX_destroy(ukm_hash);
        +			if (EVP_PKEY_CTX_ctrl(pkey_ctx,-1,EVP_PKEY_OP_ENCRYPT,EVP_PKEY_CTRL_SET_IV,
        +				8,shared_ukm)<0) {
        +					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +						SSL_R_LIBRARY_BUG);
        +					goto err;
        +				}	
        +			/* Make GOST keytransport blob message */
        +			/*Encapsulate it into sequence */
        +			*(p++)=V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
        +			msglen=255;
        +			if (EVP_PKEY_encrypt(pkey_ctx,tmp,&msglen,premaster_secret,32)<0) {
        +			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					SSL_R_LIBRARY_BUG);
        +				goto err;
        +			}
        +			if (msglen >= 0x80)
        +				{
        +				*(p++)=0x81;
        +				*(p++)= msglen & 0xff;
        +				n=msglen+3;
        +				}
        +			else
        +				{
        +				*(p++)= msglen & 0xff;
        +				n=msglen+2;
        +				}
        +			memcpy(p, tmp, msglen);
        +			/* Check if pubkey from client certificate was used */
        +			if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
        +				{
        +				/* Set flag "skip certificate verify" */
        +				s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
        +				}
        +			EVP_PKEY_CTX_free(pkey_ctx);
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,premaster_secret,32);
        +			EVP_PKEY_free(pub_key);
        +
        +			}
        +#ifndef OPENSSL_NO_SRP
        +		else if (alg_k & SSL_kSRP)
        +			{
        +			if (s->srp_ctx.A != NULL)
        +				{
        +				/* send off the data */
        +				n=BN_num_bytes(s->srp_ctx.A);
        +				s2n(n,p);
        +				BN_bn2bin(s->srp_ctx.A,p);
        +				n+=2;
        +				}
        +			else
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			if (s->session->srp_username != NULL)
        +				OPENSSL_free(s->session->srp_username);
        +			s->session->srp_username = BUF_strdup(s->srp_ctx.login);
        +			if (s->session->srp_username == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +			if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			}
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +		else if (alg_k & SSL_kPSK)
        +			{
        +			char identity[PSK_MAX_IDENTITY_LEN];
        +			unsigned char *t = NULL;
        +			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
        +			unsigned int pre_ms_len = 0, psk_len = 0;
        +			int psk_err = 1;
        +
        +			n = 0;
        +			if (s->psk_client_callback == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					SSL_R_PSK_NO_CLIENT_CB);
        +				goto err;
        +				}
        +
        +			psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
        +				identity, PSK_MAX_IDENTITY_LEN,
        +				psk_or_pre_ms, sizeof(psk_or_pre_ms));
        +			if (psk_len > PSK_MAX_PSK_LEN)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_INTERNAL_ERROR);
        +				goto psk_err;
        +				}
        +			else if (psk_len == 0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					SSL_R_PSK_IDENTITY_NOT_FOUND);
        +				goto psk_err;
        +				}
        +
        +			/* create PSK pre_master_secret */
        +			pre_ms_len = 2+psk_len+2+psk_len;
        +			t = psk_or_pre_ms;
        +			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
        +			s2n(psk_len, t);
        +			memset(t, 0, psk_len);
        +			t+=psk_len;
        +			s2n(psk_len, t);
        +
        +			if (s->session->psk_identity_hint != NULL)
        +				OPENSSL_free(s->session->psk_identity_hint);
        +			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
        +			if (s->ctx->psk_identity_hint != NULL &&
        +				s->session->psk_identity_hint == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto psk_err;
        +				}
        +
        +			if (s->session->psk_identity != NULL)
        +				OPENSSL_free(s->session->psk_identity);
        +			s->session->psk_identity = BUF_strdup(identity);
        +			if (s->session->psk_identity == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto psk_err;
        +				}
        +
        +			s->session->master_key_length =
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,
        +					psk_or_pre_ms, pre_ms_len); 
        +			n = strlen(identity);
        +			s2n(n, p);
        +			memcpy(p, identity, n);
        +			n+=2;
        +			psk_err = 0;
        +		psk_err:
        +			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
        +			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
        +			if (psk_err != 0)
        +				{
        +				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
        +				goto err;
        +				}
        +			}
        +#endif
        +		else
        +			{
        +			ssl3_send_alert(s, SSL3_AL_FATAL,
        +			    SSL_AD_HANDSHAKE_FAILURE);
        +			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
        +			    ERR_R_INTERNAL_ERROR);
        +			goto err;
        +			}
        +		
        +		*(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
        +		l2n3(n,d);
        +
        +		s->state=SSL3_ST_CW_KEY_EXCH_B;
        +		/* number of bytes to write */
        +		s->init_num=n+4;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_CW_KEY_EXCH_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +#ifndef OPENSSL_NO_ECDH
        +	BN_CTX_free(bn_ctx);
        +	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
        +	if (clnt_ecdh != NULL) 
        +		EC_KEY_free(clnt_ecdh);
        +	EVP_PKEY_free(srvr_pub_pkey);
        +#endif
        +	return(-1);
        +	}
        +
        +int ssl3_send_client_verify(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        +	EVP_PKEY *pkey;
        +	EVP_PKEY_CTX *pctx=NULL;
        +	EVP_MD_CTX mctx;
        +	unsigned u=0;
        +	unsigned long n;
        +	int j;
        +
        +	EVP_MD_CTX_init(&mctx);
        +
        +	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
        +		{
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[4]);
        +		pkey=s->cert->key->privatekey;
        +/* Create context from key and test if sha1 is allowed as digest */
        +		pctx = EVP_PKEY_CTX_new(pkey,NULL);
        +		EVP_PKEY_sign_init(pctx);
        +		if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
        +			{
        +			if (TLS1_get_version(s) < TLS1_2_VERSION)
        +				s->method->ssl3_enc->cert_verify_mac(s,
        +						NID_sha1,
        +						&(data[MD5_DIGEST_LENGTH]));
        +			}
        +		else
        +			{
        +			ERR_clear_error();
        +			}
        +		/* For TLS v1.2 send signature algorithm and signature
        +		 * using agreed digest and cached handshake records.
        +		 */
        +		if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +			{
        +			long hdatalen = 0;
        +			void *hdata;
        +			const EVP_MD *md = s->cert->key->digest;
        +			hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,
        +								&hdata);
        +			if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
        +						ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			p += 2;
        +#ifdef SSL_DEBUG
        +			fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
        +							EVP_MD_name(md));
        +#endif
        +			if (!EVP_SignInit_ex(&mctx, md, NULL)
        +				|| !EVP_SignUpdate(&mctx, hdata, hdatalen)
        +				|| !EVP_SignFinal(&mctx, p + 2, &u, pkey))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
        +						ERR_R_EVP_LIB);
        +				goto err;
        +				}
        +			s2n(u,p);
        +			n = u + 4;
        +			if (!ssl3_digest_cached_records(s))
        +				goto err;
        +			}
        +		else
        +#ifndef OPENSSL_NO_RSA
        +		if (pkey->type == EVP_PKEY_RSA)
        +			{
        +			s->method->ssl3_enc->cert_verify_mac(s,
        +				NID_md5,
        +			 	&(data[0]));
        +			if (RSA_sign(NID_md5_sha1, data,
        +					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
        +					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
        +				goto err;
        +				}
        +			s2n(u,p);
        +			n=u+2;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			if (pkey->type == EVP_PKEY_DSA)
        +			{
        +			if (!DSA_sign(pkey->save_type,
        +				&(data[MD5_DIGEST_LENGTH]),
        +				SHA_DIGEST_LENGTH,&(p[2]),
        +				(unsigned int *)&j,pkey->pkey.dsa))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
        +				goto err;
        +				}
        +			s2n(j,p);
        +			n=j+2;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +			if (pkey->type == EVP_PKEY_EC)
        +			{
        +			if (!ECDSA_sign(pkey->save_type,
        +				&(data[MD5_DIGEST_LENGTH]),
        +				SHA_DIGEST_LENGTH,&(p[2]),
        +				(unsigned int *)&j,pkey->pkey.ec))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
        +				    ERR_R_ECDSA_LIB);
        +				goto err;
        +				}
        +			s2n(j,p);
        +			n=j+2;
        +			}
        +		else
        +#endif
        +		if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) 
        +		{
        +		unsigned char signbuf[64];
        +		int i;
        +		size_t sigsize=64;
        +		s->method->ssl3_enc->cert_verify_mac(s,
        +			NID_id_GostR3411_94,
        +			data);
        +		if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
        +			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
        +			ERR_R_INTERNAL_ERROR);
        +			goto err;
        +		}
        +		for (i=63,j=0; i>=0; j++, i--) {
        +			p[2+j]=signbuf[i];
        +		}	
        +		s2n(j,p);
        +		n=j+2;
        +		}
        +		else
        +		{
        +			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
        +			goto err;
        +		}
        +		*(d++)=SSL3_MT_CERTIFICATE_VERIFY;
        +		l2n3(n,d);
        +
        +		s->state=SSL3_ST_CW_CERT_VRFY_B;
        +		s->init_num=(int)n+4;
        +		s->init_off=0;
        +		}
        +	EVP_MD_CTX_cleanup(&mctx);
        +	EVP_PKEY_CTX_free(pctx);
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +	EVP_MD_CTX_cleanup(&mctx);
        +	EVP_PKEY_CTX_free(pctx);
        +	return(-1);
        +	}
        +
        +int ssl3_send_client_certificate(SSL *s)
        +	{
        +	X509 *x509=NULL;
        +	EVP_PKEY *pkey=NULL;
        +	int i;
        +	unsigned long l;
        +
        +	if (s->state ==	SSL3_ST_CW_CERT_A)
        +		{
        +		if ((s->cert == NULL) ||
        +			(s->cert->key->x509 == NULL) ||
        +			(s->cert->key->privatekey == NULL))
        +			s->state=SSL3_ST_CW_CERT_B;
        +		else
        +			s->state=SSL3_ST_CW_CERT_C;
        +		}
        +
        +	/* We need to get a client cert */
        +	if (s->state == SSL3_ST_CW_CERT_B)
        +		{
        +		/* If we get an error, we need to
        +		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
        +		 * We then get retied later */
        +		i=0;
        +		i = ssl_do_client_cert_cb(s, &x509, &pkey);
        +		if (i < 0)
        +			{
        +			s->rwstate=SSL_X509_LOOKUP;
        +			return(-1);
        +			}
        +		s->rwstate=SSL_NOTHING;
        +		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
        +			{
        +			s->state=SSL3_ST_CW_CERT_B;
        +			if (	!SSL_use_certificate(s,x509) ||
        +				!SSL_use_PrivateKey(s,pkey))
        +				i=0;
        +			}
        +		else if (i == 1)
        +			{
        +			i=0;
        +			SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
        +			}
        +
        +		if (x509 != NULL) X509_free(x509);
        +		if (pkey != NULL) EVP_PKEY_free(pkey);
        +		if (i == 0)
        +			{
        +			if (s->version == SSL3_VERSION)
        +				{
        +				s->s3->tmp.cert_req=0;
        +				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
        +				return(1);
        +				}
        +			else
        +				{
        +				s->s3->tmp.cert_req=2;
        +				}
        +			}
        +
        +		/* Ok, we have a cert */
        +		s->state=SSL3_ST_CW_CERT_C;
        +		}
        +
        +	if (s->state == SSL3_ST_CW_CERT_C)
        +		{
        +		s->state=SSL3_ST_CW_CERT_D;
        +		l=ssl3_output_cert_chain(s,
        +			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
        +		s->init_num=(int)l;
        +		s->init_off=0;
        +		}
        +	/* SSL3_ST_CW_CERT_D */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +#define has_bits(i,m)	(((i)&(m)) == (m))
        +
        +int ssl3_check_cert_and_algorithm(SSL *s)
        +	{
        +	int i,idx;
        +	long alg_k,alg_a;
        +	EVP_PKEY *pkey=NULL;
        +	SESS_CERT *sc;
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rsa;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	DH *dh;
        +#endif
        +
        +	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
        +	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
        +
        +	/* we don't have a certificate */
        +	if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
        +		return(1);
        +
        +	sc=s->session->sess_cert;
        +	if (sc == NULL)
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +
        +#ifndef OPENSSL_NO_RSA
        +	rsa=s->session->sess_cert->peer_rsa_tmp;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	dh=s->session->sess_cert->peer_dh_tmp;
        +#endif
        +
        +	/* This is the passed certificate */
        +
        +	idx=sc->peer_cert_type;
        +#ifndef OPENSSL_NO_ECDH
        +	if (idx == SSL_PKEY_ECC)
        +		{
        +		if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
        +		    						s) == 0) 
        +			{ /* check failed */
        +			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT);
        +			goto f_err;
        +			}
        +		else 
        +			{
        +			return 1;
        +			}
        +		}
        +#endif
        +	pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);
        +	i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);
        +	EVP_PKEY_free(pkey);
        +
        +	
        +	/* Check that we have a certificate if we require one */
        +	if ((alg_a & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT);
        +		goto f_err;
        +		}
        +#ifndef OPENSSL_NO_DSA
        +	else if ((alg_a & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT);
        +		goto f_err;
        +		}
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	if ((alg_k & SSL_kRSA) &&
        +		!(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL)))
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT);
        +		goto f_err;
        +		}
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	if ((alg_k & SSL_kEDH) &&
        +		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
        +		goto f_err;
        +		}
        +	else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
        +		goto f_err;
        +		}
        +#ifndef OPENSSL_NO_DSA
        +	else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
        +		{
        +		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
        +		goto f_err;
        +		}
        +#endif
        +#endif
        +
        +	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
        +		{
        +#ifndef OPENSSL_NO_RSA
        +		if (alg_k & SSL_kRSA)
        +			{
        +			if (rsa == NULL
        +			    || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
        +				{
        +				SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
        +				goto f_err;
        +				}
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
        +			    {
        +			    if (dh == NULL
        +				|| DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
        +				{
        +				SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY);
        +				goto f_err;
        +				}
        +			}
        +		else
        +#endif
        +			{
        +			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
        +			goto f_err;
        +			}
        +		}
        +	return(1);
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
        +err:
        +	return(0);
        +	}
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +int ssl3_send_next_proto(SSL *s)
        +	{
        +	unsigned int len, padding_len;
        +	unsigned char *d;
        +
        +	if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
        +		{
        +		len = s->next_proto_negotiated_len;
        +		padding_len = 32 - ((len + 2) % 32);
        +		d = (unsigned char *)s->init_buf->data;
        +		d[4] = len;
        +		memcpy(d + 5, s->next_proto_negotiated, len);
        +		d[5 + len] = padding_len;
        +		memset(d + 6 + len, 0, padding_len);
        +		*(d++)=SSL3_MT_NEXT_PROTO;
        +		l2n3(2 + len + padding_len, d);
        +		s->state = SSL3_ST_CW_NEXT_PROTO_B;
        +		s->init_num = 4 + 2 + len + padding_len;
        +		s->init_off = 0;
        +		}
        +
        +	return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
        +}
        +#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
        +
        +/* Check to see if handshake is full or resumed. Usually this is just a
        + * case of checking to see if a cache hit has occurred. In the case of
        + * session tickets we have to check the next message to be sure.
        + */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +int ssl3_check_finished(SSL *s)
        +	{
        +	int ok;
        +	long n;
        +	/* If we have no ticket it cannot be a resumed session. */
        +	if (!s->session->tlsext_tick)
        +		return 1;
        +	/* this function is called when we really expect a Certificate
        +	 * message, so permit appropriate message length */
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_CR_CERT_A,
        +		SSL3_ST_CR_CERT_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +	if (!ok) return((int)n);
        +	s->s3->tmp.reuse_message = 1;
        +	if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
        +		|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
        +		return 2;
        +
        +	return 1;
        +	}
        +#endif
        +
        +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
        +	{
        +	int i = 0;
        +#ifndef OPENSSL_NO_ENGINE
        +	if (s->ctx->client_cert_engine)
        +		{
        +		i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
        +						SSL_get_client_CA_list(s),
        +						px509, ppkey, NULL, NULL, NULL);
        +		if (i != 0)
        +			return i;
        +		}
        +#endif
        +	if (s->ctx->client_cert_cb)
        +		i = s->ctx->client_cert_cb(s,px509,ppkey);
        +	return i;
        +	}
        diff --git a/vendor/openssl/openssl/ssl/s3_enc.c b/vendor/openssl/openssl/ssl/s3_enc.c
        new file mode 100644
        index 000000000..e3cd4f062
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_enc.c
        @@ -0,0 +1,898 @@
        +/* ssl/s3_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/evp.h>
        +#include <openssl/md5.h>
        +
        +static unsigned char ssl3_pad_1[48]={
        +	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
        +	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
        +	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
        +	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
        +	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
        +	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36 };
        +
        +static unsigned char ssl3_pad_2[48]={
        +	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
        +	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
        +	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
        +	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
        +	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
        +	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c };
        +static int ssl3_handshake_mac(SSL *s, int md_nid,
        +	const char *sender, int len, unsigned char *p);
        +static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
        +	{
        +	EVP_MD_CTX m5;
        +	EVP_MD_CTX s1;
        +	unsigned char buf[16],smd[SHA_DIGEST_LENGTH];
        +	unsigned char c='A';
        +	unsigned int i,j,k;
        +
        +#ifdef CHARSET_EBCDIC
        +	c = os_toascii[c]; /*'A' in ASCII */
        +#endif
        +	k=0;
        +	EVP_MD_CTX_init(&m5);
        +	EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +	EVP_MD_CTX_init(&s1);
        +	for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
        +		{
        +		k++;
        +		if (k > sizeof buf)
        +			{
        +			/* bug: 'buf' is too small for this ciphersuite */
        +			SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
        +			return 0;
        +			}
        +		
        +		for (j=0; j<k; j++)
        +			buf[j]=c;
        +		c++;
        +		EVP_DigestInit_ex(&s1,EVP_sha1(), NULL);
        +		EVP_DigestUpdate(&s1,buf,k);
        +		EVP_DigestUpdate(&s1,s->session->master_key,
        +			s->session->master_key_length);
        +		EVP_DigestUpdate(&s1,s->s3->server_random,SSL3_RANDOM_SIZE);
        +		EVP_DigestUpdate(&s1,s->s3->client_random,SSL3_RANDOM_SIZE);
        +		EVP_DigestFinal_ex(&s1,smd,NULL);
        +
        +		EVP_DigestInit_ex(&m5,EVP_md5(), NULL);
        +		EVP_DigestUpdate(&m5,s->session->master_key,
        +			s->session->master_key_length);
        +		EVP_DigestUpdate(&m5,smd,SHA_DIGEST_LENGTH);
        +		if ((int)(i+MD5_DIGEST_LENGTH) > num)
        +			{
        +			EVP_DigestFinal_ex(&m5,smd,NULL);
        +			memcpy(km,smd,(num-i));
        +			}
        +		else
        +			EVP_DigestFinal_ex(&m5,km,NULL);
        +
        +		km+=MD5_DIGEST_LENGTH;
        +		}
        +	OPENSSL_cleanse(smd,SHA_DIGEST_LENGTH);
        +	EVP_MD_CTX_cleanup(&m5);
        +	EVP_MD_CTX_cleanup(&s1);
        +	return 1;
        +	}
        +
        +int ssl3_change_cipher_state(SSL *s, int which)
        +	{
        +	unsigned char *p,*mac_secret;
        +	unsigned char exp_key[EVP_MAX_KEY_LENGTH];
        +	unsigned char exp_iv[EVP_MAX_IV_LENGTH];
        +	unsigned char *ms,*key,*iv,*er1,*er2;
        +	EVP_CIPHER_CTX *dd;
        +	const EVP_CIPHER *c;
        +#ifndef OPENSSL_NO_COMP
        +	COMP_METHOD *comp;
        +#endif
        +	const EVP_MD *m;
        +	EVP_MD_CTX md;
        +	int is_exp,n,i,j,k,cl;
        +	int reuse_dd = 0;
        +
        +	is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
        +	c=s->s3->tmp.new_sym_enc;
        +	m=s->s3->tmp.new_hash;
        +	/* m == NULL will lead to a crash later */
        +	OPENSSL_assert(m);
        +#ifndef OPENSSL_NO_COMP
        +	if (s->s3->tmp.new_compression == NULL)
        +		comp=NULL;
        +	else
        +		comp=s->s3->tmp.new_compression->method;
        +#endif
        +
        +	if (which & SSL3_CC_READ)
        +		{
        +		if (s->enc_read_ctx != NULL)
        +			reuse_dd = 1;
        +		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
        +			goto err;
        +		else
        +			/* make sure it's intialized in case we exit later with an error */
        +			EVP_CIPHER_CTX_init(s->enc_read_ctx);
        +		dd= s->enc_read_ctx;
        +
        +		ssl_replace_hash(&s->read_hash,m);
        +#ifndef OPENSSL_NO_COMP
        +		/* COMPRESS */
        +		if (s->expand != NULL)
        +			{
        +			COMP_CTX_free(s->expand);
        +			s->expand=NULL;
        +			}
        +		if (comp != NULL)
        +			{
        +			s->expand=COMP_CTX_new(comp);
        +			if (s->expand == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
        +				goto err2;
        +				}
        +			if (s->s3->rrec.comp == NULL)
        +				s->s3->rrec.comp=(unsigned char *)
        +					OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
        +			if (s->s3->rrec.comp == NULL)
        +				goto err;
        +			}
        +#endif
        +		memset(&(s->s3->read_sequence[0]),0,8);
        +		mac_secret= &(s->s3->read_mac_secret[0]);
        +		}
        +	else
        +		{
        +		if (s->enc_write_ctx != NULL)
        +			reuse_dd = 1;
        +		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
        +			goto err;
        +		else
        +			/* make sure it's intialized in case we exit later with an error */
        +			EVP_CIPHER_CTX_init(s->enc_write_ctx);
        +		dd= s->enc_write_ctx;
        +		ssl_replace_hash(&s->write_hash,m);
        +#ifndef OPENSSL_NO_COMP
        +		/* COMPRESS */
        +		if (s->compress != NULL)
        +			{
        +			COMP_CTX_free(s->compress);
        +			s->compress=NULL;
        +			}
        +		if (comp != NULL)
        +			{
        +			s->compress=COMP_CTX_new(comp);
        +			if (s->compress == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
        +				goto err2;
        +				}
        +			}
        +#endif
        +		memset(&(s->s3->write_sequence[0]),0,8);
        +		mac_secret= &(s->s3->write_mac_secret[0]);
        +		}
        +
        +	if (reuse_dd)
        +		EVP_CIPHER_CTX_cleanup(dd);
        +
        +	p=s->s3->tmp.key_block;
        +	i=EVP_MD_size(m);
        +	if (i < 0)
        +		goto err2;
        +	cl=EVP_CIPHER_key_length(c);
        +	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
        +		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
        +	/* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
        +	k=EVP_CIPHER_iv_length(c);
        +	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
        +		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
        +		{
        +		ms=  &(p[ 0]); n=i+i;
        +		key= &(p[ n]); n+=j+j;
        +		iv=  &(p[ n]); n+=k+k;
        +		er1= &(s->s3->client_random[0]);
        +		er2= &(s->s3->server_random[0]);
        +		}
        +	else
        +		{
        +		n=i;
        +		ms=  &(p[ n]); n+=i+j;
        +		key= &(p[ n]); n+=j+k;
        +		iv=  &(p[ n]); n+=k;
        +		er1= &(s->s3->server_random[0]);
        +		er2= &(s->s3->client_random[0]);
        +		}
        +
        +	if (n > s->s3->tmp.key_block_length)
        +		{
        +		SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
        +		goto err2;
        +		}
        +
        +	EVP_MD_CTX_init(&md);
        +	memcpy(mac_secret,ms,i);
        +	if (is_exp)
        +		{
        +		/* In here I set both the read and write key/iv to the
        +		 * same value since only the correct one will be used :-).
        +		 */
        +		EVP_DigestInit_ex(&md,EVP_md5(), NULL);
        +		EVP_DigestUpdate(&md,key,j);
        +		EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
        +		EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
        +		EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL);
        +		key= &(exp_key[0]);
        +
        +		if (k > 0)
        +			{
        +			EVP_DigestInit_ex(&md,EVP_md5(), NULL);
        +			EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
        +			EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
        +			EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL);
        +			iv= &(exp_iv[0]);
        +			}
        +		}
        +
        +	s->session->key_arg_length=0;
        +
        +	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
        +
        +	OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
        +	OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
        +	EVP_MD_CTX_cleanup(&md);
        +	return(1);
        +err:
        +	SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
        +err2:
        +	return(0);
        +	}
        +
        +int ssl3_setup_key_block(SSL *s)
        +	{
        +	unsigned char *p;
        +	const EVP_CIPHER *c;
        +	const EVP_MD *hash;
        +	int num;
        +	int ret = 0;
        +	SSL_COMP *comp;
        +
        +	if (s->s3->tmp.key_block_length != 0)
        +		return(1);
        +
        +	if (!ssl_cipher_get_evp(s->session,&c,&hash,NULL,NULL,&comp))
        +		{
        +		SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
        +		return(0);
        +		}
        +
        +	s->s3->tmp.new_sym_enc=c;
        +	s->s3->tmp.new_hash=hash;
        +#ifdef OPENSSL_NO_COMP
        +	s->s3->tmp.new_compression=NULL;
        +#else
        +	s->s3->tmp.new_compression=comp;
        +#endif
        +
        +	num=EVP_MD_size(hash);
        +	if (num < 0)
        +		return 0;
        +
        +	num=EVP_CIPHER_key_length(c)+num+EVP_CIPHER_iv_length(c);
        +	num*=2;
        +
        +	ssl3_cleanup_key_block(s);
        +
        +	if ((p=OPENSSL_malloc(num)) == NULL)
        +		goto err;
        +
        +	s->s3->tmp.key_block_length=num;
        +	s->s3->tmp.key_block=p;
        +
        +	ret = ssl3_generate_key_block(s,p,num);
        +
        +	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
        +		{
        +		/* enable vulnerability countermeasure for CBC ciphers with
        +		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
        +		 */
        +		s->s3->need_empty_fragments = 1;
        +
        +		if (s->session->cipher != NULL)
        +			{
        +			if (s->session->cipher->algorithm_enc == SSL_eNULL)
        +				s->s3->need_empty_fragments = 0;
        +			
        +#ifndef OPENSSL_NO_RC4
        +			if (s->session->cipher->algorithm_enc == SSL_RC4)
        +				s->s3->need_empty_fragments = 0;
        +#endif
        +			}
        +		}
        +
        +	return ret;
        +		
        +err:
        +	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
        +	return(0);
        +	}
        +
        +void ssl3_cleanup_key_block(SSL *s)
        +	{
        +	if (s->s3->tmp.key_block != NULL)
        +		{
        +		OPENSSL_cleanse(s->s3->tmp.key_block,
        +			s->s3->tmp.key_block_length);
        +		OPENSSL_free(s->s3->tmp.key_block);
        +		s->s3->tmp.key_block=NULL;
        +		}
        +	s->s3->tmp.key_block_length=0;
        +	}
        +
        +/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
        + *
        + * Returns:
        + *   0: (in non-constant time) if the record is publically invalid (i.e. too
        + *       short etc).
        + *   1: if the record's padding is valid / the encryption was successful.
        + *   -1: if the record's padding is invalid or, if sending, an internal error
        + *       occured.
        + */
        +int ssl3_enc(SSL *s, int send)
        +	{
        +	SSL3_RECORD *rec;
        +	EVP_CIPHER_CTX *ds;
        +	unsigned long l;
        +	int bs,i,mac_size=0;
        +	const EVP_CIPHER *enc;
        +
        +	if (send)
        +		{
        +		ds=s->enc_write_ctx;
        +		rec= &(s->s3->wrec);
        +		if (s->enc_write_ctx == NULL)
        +			enc=NULL;
        +		else
        +			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
        +		}
        +	else
        +		{
        +		ds=s->enc_read_ctx;
        +		rec= &(s->s3->rrec);
        +		if (s->enc_read_ctx == NULL)
        +			enc=NULL;
        +		else
        +			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
        +		}
        +
        +	if ((s->session == NULL) || (ds == NULL) ||
        +		(enc == NULL))
        +		{
        +		memmove(rec->data,rec->input,rec->length);
        +		rec->input=rec->data;
        +		}
        +	else
        +		{
        +		l=rec->length;
        +		bs=EVP_CIPHER_block_size(ds->cipher);
        +
        +		/* COMPRESS */
        +
        +		if ((bs != 1) && send)
        +			{
        +			i=bs-((int)l%bs);
        +
        +			/* we need to add 'i-1' padding bytes */
        +			l+=i;
        +			/* the last of these zero bytes will be overwritten
        +			 * with the padding length. */
        +			memset(&rec->input[rec->length], 0, i);
        +			rec->length+=i;
        +			rec->input[l-1]=(i-1);
        +			}
        +		
        +		if (!send)
        +			{
        +			if (l == 0 || l%bs != 0)
        +				return 0;
        +			/* otherwise, rec->length >= bs */
        +			}
        +		
        +		EVP_Cipher(ds,rec->data,rec->input,l);
        +
        +		if (EVP_MD_CTX_md(s->read_hash) != NULL)
        +			mac_size = EVP_MD_CTX_size(s->read_hash);
        +		if ((bs != 1) && !send)
        +			return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
        +		}
        +	return(1);
        +	}
        +
        +void ssl3_init_finished_mac(SSL *s)
        +	{
        +	if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer);
        +	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
        +    s->s3->handshake_buffer=BIO_new(BIO_s_mem());	
        +	(void)BIO_set_close(s->s3->handshake_buffer,BIO_CLOSE);
        +	}
        +
        +void ssl3_free_digest_list(SSL *s) 
        +	{
        +	int i;
        +	if (!s->s3->handshake_dgst) return;
        +	for (i=0;i<SSL_MAX_DIGEST;i++) 
        +		{
        +		if (s->s3->handshake_dgst[i])
        +			EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
        +		}
        +	OPENSSL_free(s->s3->handshake_dgst);
        +	s->s3->handshake_dgst=NULL;
        +	}	
        +
        +
        +
        +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
        +	{
        +	if (s->s3->handshake_buffer && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) 
        +		{
        +		BIO_write (s->s3->handshake_buffer,(void *)buf,len);
        +		} 
        +	else 
        +		{
        +		int i;
        +		for (i=0;i< SSL_MAX_DIGEST;i++) 
        +			{
        +			if (s->s3->handshake_dgst[i]!= NULL)
        +			EVP_DigestUpdate(s->s3->handshake_dgst[i],buf,len);
        +			}
        +		}	
        +	}
        +
        +int ssl3_digest_cached_records(SSL *s)
        +	{
        +	int i;
        +	long mask;
        +	const EVP_MD *md;
        +	long hdatalen;
        +	void *hdata;
        +
        +	/* Allocate handshake_dgst array */
        +	ssl3_free_digest_list(s);
        +	s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
        +	memset(s->s3->handshake_dgst,0,SSL_MAX_DIGEST *sizeof(EVP_MD_CTX *));
        +	hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,&hdata);
        +	if (hdatalen <= 0)
        +		{
        +		SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
        +		return 0;
        +		}
        +
        +	/* Loop through bitso of algorithm2 field and create MD_CTX-es */
        +	for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++) 
        +		{
        +		if ((mask & ssl_get_algorithm2(s)) && md) 
        +			{
        +			s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
        +#ifdef OPENSSL_FIPS
        +			if (EVP_MD_nid(md) == NID_md5)
        +				{
        +				EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
        +						EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +				}
        +#endif
        +			EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
        +			EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen);
        +			} 
        +		else 
        +			{	
        +			s->s3->handshake_dgst[i]=NULL;
        +			}
        +		}
        +	if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
        +		{
        +		/* Free handshake_buffer BIO */
        +		BIO_free(s->s3->handshake_buffer);
        +		s->s3->handshake_buffer = NULL;
        +		}
        +
        +	return 1;
        +	}
        +
        +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
        +	{
        +	return(ssl3_handshake_mac(s,md_nid,NULL,0,p));
        +	}
        +int ssl3_final_finish_mac(SSL *s, 
        +	     const char *sender, int len, unsigned char *p)
        +	{
        +	int ret;
        +	ret=ssl3_handshake_mac(s,NID_md5,sender,len,p);
        +	p+=ret;
        +	ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p);
        +	return(ret);
        +	}
        +static int ssl3_handshake_mac(SSL *s, int md_nid,
        +	     const char *sender, int len, unsigned char *p)
        +	{
        +	unsigned int ret;
        +	int npad,n;
        +	unsigned int i;
        +	unsigned char md_buf[EVP_MAX_MD_SIZE];
        +	EVP_MD_CTX ctx,*d=NULL;
        +
        +	if (s->s3->handshake_buffer) 
        +		if (!ssl3_digest_cached_records(s))
        +			return 0;
        +
        +	/* Search for digest of specified type in the handshake_dgst
        +	 * array*/
        +	for (i=0;i<SSL_MAX_DIGEST;i++) 
        +		{
        +		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) 
        +		  	{
        +		  	d=s->s3->handshake_dgst[i];
        +			break;
        +			}
        +		}
        +	if (!d) {
        +		SSLerr(SSL_F_SSL3_HANDSHAKE_MAC,SSL_R_NO_REQUIRED_DIGEST);
        +		return 0;
        +	}	
        +	EVP_MD_CTX_init(&ctx);
        +	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +	EVP_MD_CTX_copy_ex(&ctx,d);
        +	n=EVP_MD_CTX_size(&ctx);
        +	if (n < 0)
        +		return 0;
        +
        +	npad=(48/n)*n;
        +	if (sender != NULL)
        +		EVP_DigestUpdate(&ctx,sender,len);
        +	EVP_DigestUpdate(&ctx,s->session->master_key,
        +		s->session->master_key_length);
        +	EVP_DigestUpdate(&ctx,ssl3_pad_1,npad);
        +	EVP_DigestFinal_ex(&ctx,md_buf,&i);
        +
        +	EVP_DigestInit_ex(&ctx,EVP_MD_CTX_md(&ctx), NULL);
        +	EVP_DigestUpdate(&ctx,s->session->master_key,
        +		s->session->master_key_length);
        +	EVP_DigestUpdate(&ctx,ssl3_pad_2,npad);
        +	EVP_DigestUpdate(&ctx,md_buf,i);
        +	EVP_DigestFinal_ex(&ctx,p,&ret);
        +
        +	EVP_MD_CTX_cleanup(&ctx);
        +
        +	return((int)ret);
        +	}
        +
        +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
        +	{
        +	SSL3_RECORD *rec;
        +	unsigned char *mac_sec,*seq;
        +	EVP_MD_CTX md_ctx;
        +	const EVP_MD_CTX *hash;
        +	unsigned char *p,rec_char;
        +	size_t md_size, orig_len;
        +	int npad;
        +	int t;
        +
        +	if (send)
        +		{
        +		rec= &(ssl->s3->wrec);
        +		mac_sec= &(ssl->s3->write_mac_secret[0]);
        +		seq= &(ssl->s3->write_sequence[0]);
        +		hash=ssl->write_hash;
        +		}
        +	else
        +		{
        +		rec= &(ssl->s3->rrec);
        +		mac_sec= &(ssl->s3->read_mac_secret[0]);
        +		seq= &(ssl->s3->read_sequence[0]);
        +		hash=ssl->read_hash;
        +		}
        +
        +	t=EVP_MD_CTX_size(hash);
        +	if (t < 0)
        +		return -1;
        +	md_size=t;
        +	npad=(48/md_size)*md_size;
        +
        +	/* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */
        +	orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
        +	rec->type &= 0xff;
        +
        +	if (!send &&
        +	    EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
        +	    ssl3_cbc_record_digest_supported(hash))
        +		{
        +		/* This is a CBC-encrypted record. We must avoid leaking any
        +		 * timing-side channel information about how many blocks of
        +		 * data we are hashing because that gives an attacker a
        +		 * timing-oracle. */
        +
        +		/* npad is, at most, 48 bytes and that's with MD5:
        +		 *   16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
        +		 *
        +		 * With SHA-1 (the largest hash speced for SSLv3) the hash size
        +		 * goes up 4, but npad goes down by 8, resulting in a smaller
        +		 * total size. */
        +		unsigned char header[75];
        +		unsigned j = 0;
        +		memcpy(header+j, mac_sec, md_size);
        +		j += md_size;
        +		memcpy(header+j, ssl3_pad_1, npad);
        +		j += npad;
        +		memcpy(header+j, seq, 8);
        +		j += 8;
        +		header[j++] = rec->type;
        +		header[j++] = rec->length >> 8;
        +		header[j++] = rec->length & 0xff;
        +
        +		ssl3_cbc_digest_record(
        +			hash,
        +			md, &md_size,
        +			header, rec->input,
        +			rec->length + md_size, orig_len,
        +			mac_sec, md_size,
        +			1 /* is SSLv3 */);
        +		}
        +	else
        +		{
        +		unsigned int md_size_u;
        +		/* Chop the digest off the end :-) */
        +		EVP_MD_CTX_init(&md_ctx);
        +
        +		EVP_MD_CTX_copy_ex( &md_ctx,hash);
        +		EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
        +		EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
        +		EVP_DigestUpdate(&md_ctx,seq,8);
        +		rec_char=rec->type;
        +		EVP_DigestUpdate(&md_ctx,&rec_char,1);
        +		p=md;
        +		s2n(rec->length,p);
        +		EVP_DigestUpdate(&md_ctx,md,2);
        +		EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
        +		EVP_DigestFinal_ex( &md_ctx,md,NULL);
        +
        +		EVP_MD_CTX_copy_ex( &md_ctx,hash);
        +		EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
        +		EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
        +		EVP_DigestUpdate(&md_ctx,md,md_size);
        +		EVP_DigestFinal_ex( &md_ctx,md,&md_size_u);
        +		md_size = md_size_u;
        +
        +		EVP_MD_CTX_cleanup(&md_ctx);
        +	}
        +
        +	ssl3_record_sequence_update(seq);
        +	return(md_size);
        +	}
        +
        +void ssl3_record_sequence_update(unsigned char *seq)
        +	{
        +	int i;
        +
        +	for (i=7; i>=0; i--)
        +		{
        +		++seq[i];
        +		if (seq[i] != 0) break; 
        +		}
        +	}
        +
        +int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
        +	     int len)
        +	{
        +	static const unsigned char *salt[3]={
        +#ifndef CHARSET_EBCDIC
        +		(const unsigned char *)"A",
        +		(const unsigned char *)"BB",
        +		(const unsigned char *)"CCC",
        +#else
        +		(const unsigned char *)"\x41",
        +		(const unsigned char *)"\x42\x42",
        +		(const unsigned char *)"\x43\x43\x43",
        +#endif
        +		};
        +	unsigned char buf[EVP_MAX_MD_SIZE];
        +	EVP_MD_CTX ctx;
        +	int i,ret=0;
        +	unsigned int n;
        +
        +	EVP_MD_CTX_init(&ctx);
        +	for (i=0; i<3; i++)
        +		{
        +		EVP_DigestInit_ex(&ctx,s->ctx->sha1, NULL);
        +		EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i]));
        +		EVP_DigestUpdate(&ctx,p,len);
        +		EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]),
        +			SSL3_RANDOM_SIZE);
        +		EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]),
        +			SSL3_RANDOM_SIZE);
        +		EVP_DigestFinal_ex(&ctx,buf,&n);
        +
        +		EVP_DigestInit_ex(&ctx,s->ctx->md5, NULL);
        +		EVP_DigestUpdate(&ctx,p,len);
        +		EVP_DigestUpdate(&ctx,buf,n);
        +		EVP_DigestFinal_ex(&ctx,out,&n);
        +		out+=n;
        +		ret+=n;
        +		}
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return(ret);
        +	}
        +
        +int ssl3_alert_code(int code)
        +	{
        +	switch (code)
        +		{
        +	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
        +	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
        +	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
        +	case SSL_AD_DECRYPTION_FAILED:	return(SSL3_AD_BAD_RECORD_MAC);
        +	case SSL_AD_RECORD_OVERFLOW:	return(SSL3_AD_BAD_RECORD_MAC);
        +	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
        +	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_NO_CERTIFICATE:	return(SSL3_AD_NO_CERTIFICATE);
        +	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
        +	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
        +	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
        +	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
        +	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
        +	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
        +	case SSL_AD_UNKNOWN_CA:		return(SSL3_AD_BAD_CERTIFICATE);
        +	case SSL_AD_ACCESS_DENIED:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_DECODE_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_DECRYPT_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_EXPORT_RESTRICTION:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_PROTOCOL_VERSION:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_INTERNAL_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_USER_CANCELLED:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_NO_RENEGOTIATION:	return(-1); /* Don't send it :-) */
        +	case SSL_AD_UNSUPPORTED_EXTENSION: return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_UNRECOGNIZED_NAME:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
        +	default:			return(-1);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/s3_lib.c b/vendor/openssl/openssl/ssl/s3_lib.c
        new file mode 100644
        index 000000000..e7c5dcb80
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_lib.c
        @@ -0,0 +1,4282 @@
        +/* ssl/s3_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * ECC cipher suite support in OpenSSL originally written by
        + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +#include "kssl_lcl.h"
        +#ifndef OPENSSL_NO_TLSEXT
        +#ifndef OPENSSL_NO_EC
        +#include "../crypto/ec/ec_lcl.h"
        +#endif /* OPENSSL_NO_EC */
        +#endif /* OPENSSL_NO_TLSEXT */
        +#include <openssl/md5.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +
        +const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT;
        +
        +#define SSL3_NUM_CIPHERS	(sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER))
        +
        +/* list of available SSLv3 ciphers (sorted by id) */
        +OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        +
        +/* The RSA ciphers */
        +/* Cipher 01 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_NULL_MD5,
        +	SSL3_CK_RSA_NULL_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eNULL,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_STRONG_NONE,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +/* Cipher 02 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_NULL_SHA,
        +	SSL3_CK_RSA_NULL_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +/* Cipher 03 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_RC4_40_MD5,
        +	SSL3_CK_RSA_RC4_40_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 04 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_RC4_128_MD5,
        +	SSL3_CK_RSA_RC4_128_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 05 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_RC4_128_SHA,
        +	SSL3_CK_RSA_RC4_128_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 06 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_RC2_40_MD5,
        +	SSL3_CK_RSA_RC2_40_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC2,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 07 */
        +#ifndef OPENSSL_NO_IDEA
        +	{
        +	1,
        +	SSL3_TXT_RSA_IDEA_128_SHA,
        +	SSL3_CK_RSA_IDEA_128_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_IDEA,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +#endif
        +
        +/* Cipher 08 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_DES_40_CBC_SHA,
        +	SSL3_CK_RSA_DES_40_CBC_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 09 */
        +	{
        +	1,
        +	SSL3_TXT_RSA_DES_64_CBC_SHA,
        +	SSL3_CK_RSA_DES_64_CBC_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 0A */
        +	{
        +	1,
        +	SSL3_TXT_RSA_DES_192_CBC3_SHA,
        +	SSL3_CK_RSA_DES_192_CBC3_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* The DH ciphers */
        +/* Cipher 0B */
        +	{
        +	0,
        +	SSL3_TXT_DH_DSS_DES_40_CBC_SHA,
        +	SSL3_CK_DH_DSS_DES_40_CBC_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 0C */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	SSL3_TXT_DH_DSS_DES_64_CBC_SHA,
        +	SSL3_CK_DH_DSS_DES_64_CBC_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 0D */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	SSL3_TXT_DH_DSS_DES_192_CBC3_SHA,
        +	SSL3_CK_DH_DSS_DES_192_CBC3_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* Cipher 0E */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	SSL3_TXT_DH_RSA_DES_40_CBC_SHA,
        +	SSL3_CK_DH_RSA_DES_40_CBC_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 0F */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	SSL3_TXT_DH_RSA_DES_64_CBC_SHA,
        +	SSL3_CK_DH_RSA_DES_64_CBC_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 10 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	SSL3_TXT_DH_RSA_DES_192_CBC3_SHA,
        +	SSL3_CK_DH_RSA_DES_192_CBC3_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* The Ephemeral DH ciphers */
        +/* Cipher 11 */
        +	{
        +	1,
        +	SSL3_TXT_EDH_DSS_DES_40_CBC_SHA,
        +	SSL3_CK_EDH_DSS_DES_40_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 12 */
        +	{
        +	1,
        +	SSL3_TXT_EDH_DSS_DES_64_CBC_SHA,
        +	SSL3_CK_EDH_DSS_DES_64_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 13 */
        +	{
        +	1,
        +	SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA,
        +	SSL3_CK_EDH_DSS_DES_192_CBC3_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* Cipher 14 */
        +	{
        +	1,
        +	SSL3_TXT_EDH_RSA_DES_40_CBC_SHA,
        +	SSL3_CK_EDH_RSA_DES_40_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 15 */
        +	{
        +	1,
        +	SSL3_TXT_EDH_RSA_DES_64_CBC_SHA,
        +	SSL3_CK_EDH_RSA_DES_64_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 16 */
        +	{
        +	1,
        +	SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA,
        +	SSL3_CK_EDH_RSA_DES_192_CBC3_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* Cipher 17 */
        +	{
        +	1,
        +	SSL3_TXT_ADH_RC4_40_MD5,
        +	SSL3_CK_ADH_RC4_40_MD5,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 18 */
        +	{
        +	1,
        +	SSL3_TXT_ADH_RC4_128_MD5,
        +	SSL3_CK_ADH_RC4_128_MD5,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 19 */
        +	{
        +	1,
        +	SSL3_TXT_ADH_DES_40_CBC_SHA,
        +	SSL3_CK_ADH_DES_40_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 1A */
        +	{
        +	1,
        +	SSL3_TXT_ADH_DES_64_CBC_SHA,
        +	SSL3_CK_ADH_DES_64_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 1B */
        +	{
        +	1,
        +	SSL3_TXT_ADH_DES_192_CBC_SHA,
        +	SSL3_CK_ADH_DES_192_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* Fortezza ciphersuite from SSL 3.0 spec */
        +#if 0
        +/* Cipher 1C */
        +	{
        +	0,
        +	SSL3_TXT_FZA_DMS_NULL_SHA,
        +	SSL3_CK_FZA_DMS_NULL_SHA,
        +	SSL_kFZA,
        +	SSL_aFZA,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_STRONG_NONE,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +/* Cipher 1D */
        +	{
        +	0,
        +	SSL3_TXT_FZA_DMS_FZA_SHA,
        +	SSL3_CK_FZA_DMS_FZA_SHA,
        +	SSL_kFZA,
        +	SSL_aFZA,
        +	SSL_eFZA,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_STRONG_NONE,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +/* Cipher 1E */
        +	{
        +	0,
        +	SSL3_TXT_FZA_DMS_RC4_SHA,
        +	SSL3_CK_FZA_DMS_RC4_SHA,
        +	SSL_kFZA,
        +	SSL_aFZA,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +#endif
        +
        +#ifndef OPENSSL_NO_KRB5
        +/* The Kerberos ciphers*/
        +/* Cipher 1E */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_DES_64_CBC_SHA,
        +	SSL3_CK_KRB5_DES_64_CBC_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 1F */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_DES_192_CBC3_SHA,
        +	SSL3_CK_KRB5_DES_192_CBC3_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* Cipher 20 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_RC4_128_SHA,
        +	SSL3_CK_KRB5_RC4_128_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 21 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_IDEA_128_CBC_SHA,
        +	SSL3_CK_KRB5_IDEA_128_CBC_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_IDEA,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 22 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_DES_64_CBC_MD5,
        +	SSL3_CK_KRB5_DES_64_CBC_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_DES,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_LOW,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +/* Cipher 23 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_DES_192_CBC3_MD5,
        +	SSL3_CK_KRB5_DES_192_CBC3_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_3DES,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +/* Cipher 24 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_RC4_128_MD5,
        +	SSL3_CK_KRB5_RC4_128_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 25 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_IDEA_128_CBC_MD5,
        +	SSL3_CK_KRB5_IDEA_128_CBC_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_IDEA,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 26 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_DES_40_CBC_SHA,
        +	SSL3_CK_KRB5_DES_40_CBC_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 27 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_RC2_40_CBC_SHA,
        +	SSL3_CK_KRB5_RC2_40_CBC_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_RC2,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 28 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_RC4_40_SHA,
        +	SSL3_CK_KRB5_RC4_40_SHA,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 29 */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_DES_40_CBC_MD5,
        +	SSL3_CK_KRB5_DES_40_CBC_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_DES,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	56,
        +	},
        +
        +/* Cipher 2A */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_RC2_40_CBC_MD5,
        +	SSL3_CK_KRB5_RC2_40_CBC_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_RC2,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +
        +/* Cipher 2B */
        +	{
        +	1,
        +	SSL3_TXT_KRB5_RC4_40_MD5,
        +	SSL3_CK_KRB5_RC4_40_MD5,
        +	SSL_kKRB5,
        +	SSL_aKRB5,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_SSLV3,
        +	SSL_EXPORT|SSL_EXP40,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	40,
        +	128,
        +	},
        +#endif	/* OPENSSL_NO_KRB5 */
        +
        +/* New AES ciphersuites */
        +/* Cipher 2F */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_AES_128_SHA,
        +	TLS1_CK_RSA_WITH_AES_128_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +/* Cipher 30 */
        +	{
        +	0,
        +	TLS1_TXT_DH_DSS_WITH_AES_128_SHA,
        +	TLS1_CK_DH_DSS_WITH_AES_128_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +/* Cipher 31 */
        +	{
        +	0,
        +	TLS1_TXT_DH_RSA_WITH_AES_128_SHA,
        +	TLS1_CK_DH_RSA_WITH_AES_128_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +/* Cipher 32 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_AES_128_SHA,
        +	TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +/* Cipher 33 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
        +	TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +/* Cipher 34 */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_AES_128_SHA,
        +	TLS1_CK_ADH_WITH_AES_128_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +/* Cipher 35 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_AES_256_SHA,
        +	TLS1_CK_RSA_WITH_AES_256_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +/* Cipher 36 */
        +	{
        +	0,
        +	TLS1_TXT_DH_DSS_WITH_AES_256_SHA,
        +	TLS1_CK_DH_DSS_WITH_AES_256_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +/* Cipher 37 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_RSA_WITH_AES_256_SHA,
        +	TLS1_CK_DH_RSA_WITH_AES_256_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +/* Cipher 38 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_AES_256_SHA,
        +	TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +/* Cipher 39 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
        +	TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 3A */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_AES_256_SHA,
        +	TLS1_CK_ADH_WITH_AES_256_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* TLS v1.2 ciphersuites */
        +	/* Cipher 3B */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_NULL_SHA256,
        +	TLS1_CK_RSA_WITH_NULL_SHA256,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eNULL,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +	/* Cipher 3C */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_AES_128_SHA256,
        +	TLS1_CK_RSA_WITH_AES_128_SHA256,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 3D */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_AES_256_SHA256,
        +	TLS1_CK_RSA_WITH_AES_256_SHA256,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 3E */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
        +	TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 3F */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_RSA_WITH_AES_128_SHA256,
        +	TLS1_CK_DH_RSA_WITH_AES_128_SHA256,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 40 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256,
        +	TLS1_CK_DHE_DSS_WITH_AES_128_SHA256,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +#ifndef OPENSSL_NO_CAMELLIA
        +	/* Camellia ciphersuites from RFC4132 (128-bit portion) */
        +
        +	/* Cipher 41 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA,
        +	TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_CAMELLIA128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 42 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
        +	TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_CAMELLIA128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 43 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
        +	TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_CAMELLIA128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 44 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
        +	TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_CAMELLIA128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 45 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
        +	TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_CAMELLIA128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 46 */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA,
        +	TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_CAMELLIA128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +#endif /* OPENSSL_NO_CAMELLIA */
        +
        +#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES
        +	/* New TLS Export CipherSuites from expired ID */
        +#if 0
        +	/* Cipher 60 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5,
        +	TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_MD5,
        +	SSL_TLSV1,
        +	SSL_EXPORT|SSL_EXP56,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	128,
        +	},
        +
        +	/* Cipher 61 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
        +	TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC2,
        +	SSL_MD5,
        +	SSL_TLSV1,
        +	SSL_EXPORT|SSL_EXP56,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	128,
        +	},
        +#endif
        +
        +	/* Cipher 62 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA,
        +	TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_EXPORT|SSL_EXP56,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +	/* Cipher 63 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
        +	TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_EXPORT|SSL_EXP56,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	56,
        +	},
        +
        +	/* Cipher 64 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA,
        +	TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_EXPORT|SSL_EXP56,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	128,
        +	},
        +
        +	/* Cipher 65 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
        +	TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_EXPORT|SSL_EXP56,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	56,
        +	128,
        +	},
        +
        +	/* Cipher 66 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA,
        +	TLS1_CK_DHE_DSS_WITH_RC4_128_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +#endif
        +
        +	/* TLS v1.2 ciphersuites */
        +	/* Cipher 67 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
        +	TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 68 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
        +	TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_AES256,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 69 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_RSA_WITH_AES_256_SHA256,
        +	TLS1_CK_DH_RSA_WITH_AES_256_SHA256,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_AES256,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 6A */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256,
        +	TLS1_CK_DHE_DSS_WITH_AES_256_SHA256,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_AES256,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 6B */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
        +	TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 6C */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_AES_128_SHA256,
        +	TLS1_CK_ADH_WITH_AES_128_SHA256,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 6D */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_AES_256_SHA256,
        +	TLS1_CK_ADH_WITH_AES_256_SHA256,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_AES256,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* GOST Ciphersuites */
        +
        +	{
        +	1,
        +	"GOST94-GOST89-GOST89",
        +	0x3000080,
        +	SSL_kGOST,
        +	SSL_aGOST94,
        +	SSL_eGOST2814789CNT,
        +	SSL_GOST89MAC,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC,
        +	256,
        +	256
        +	},
        +	{
        +	1,
        +	"GOST2001-GOST89-GOST89",
        +	0x3000081,
        +	SSL_kGOST,
        +	SSL_aGOST01,
        +	SSL_eGOST2814789CNT,
        +	SSL_GOST89MAC,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC,
        +	256,
        +	256
        +	},
        +	{
        +	1,
        +	"GOST94-NULL-GOST94",
        +	0x3000082,
        +	SSL_kGOST,
        +	SSL_aGOST94,
        +	SSL_eNULL,
        +	SSL_GOST94,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE,
        +	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94,
        +	0,
        +	0
        +	},
        +	{
        +	1,
        +	"GOST2001-NULL-GOST94",
        +	0x3000083,
        +	SSL_kGOST,
        +	SSL_aGOST01,
        +	SSL_eNULL,
        +	SSL_GOST94,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE,
        +	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94,
        +	0,
        +	0
        +	},
        +
        +#ifndef OPENSSL_NO_CAMELLIA
        +	/* Camellia ciphersuites from RFC4132 (256-bit portion) */
        +
        +	/* Cipher 84 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA,
        +	TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_CAMELLIA256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +	/* Cipher 85 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
        +	TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_CAMELLIA256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 86 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
        +	TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_CAMELLIA256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 87 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
        +	TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_CAMELLIA256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 88 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
        +	TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_CAMELLIA256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 89 */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA,
        +	TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_CAMELLIA256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +#endif /* OPENSSL_NO_CAMELLIA */
        +
        +#ifndef OPENSSL_NO_PSK
        +	/* Cipher 8A */
        +	{
        +	1,
        +	TLS1_TXT_PSK_WITH_RC4_128_SHA,
        +	TLS1_CK_PSK_WITH_RC4_128_SHA,
        +	SSL_kPSK,
        +	SSL_aPSK,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 8B */
        +	{
        +	1,
        +	TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA,
        +	TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA,
        +	SSL_kPSK,
        +	SSL_aPSK,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher 8C */
        +	{
        +	1,
        +	TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
        +	SSL_kPSK,
        +	SSL_aPSK,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 8D */
        +	{
        +	1,
        +	TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
        +	SSL_kPSK,
        +	SSL_aPSK,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +#endif  /* OPENSSL_NO_PSK */
        +
        +#ifndef OPENSSL_NO_SEED
        +	/* SEED ciphersuites from RFC4162 */
        +
        +	/* Cipher 96 */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_SEED_SHA,
        +	TLS1_CK_RSA_WITH_SEED_SHA,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_SEED,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 97 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_DSS_WITH_SEED_SHA,
        +	TLS1_CK_DH_DSS_WITH_SEED_SHA,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_SEED,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 98 */
        +	{
        +	0, /* not implemented (non-ephemeral DH) */
        +	TLS1_TXT_DH_RSA_WITH_SEED_SHA,
        +	TLS1_CK_DH_RSA_WITH_SEED_SHA,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_SEED,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 99 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_SEED_SHA,
        +	TLS1_CK_DHE_DSS_WITH_SEED_SHA,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_SEED,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 9A */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_SEED_SHA,
        +	TLS1_CK_DHE_RSA_WITH_SEED_SHA,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_SEED,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 9B */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_SEED_SHA,
        +	TLS1_CK_ADH_WITH_SEED_SHA,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_SEED,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +#endif /* OPENSSL_NO_SEED */
        +
        +	/* GCM ciphersuites from RFC5288 */
        +
        +	/* Cipher 9C */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 9D */
        +	{
        +	1,
        +	TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher 9E */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher 9F */
        +	{
        +	1,
        +	TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kEDH,
        +	SSL_aRSA,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher A0 */
        +	{
        +	0,
        +	TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher A1 */
        +	{
        +	0,
        +	TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kDHr,
        +	SSL_aDH,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher A2 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher A3 */
        +	{
        +	1,
        +	TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384,
        +	SSL_kEDH,
        +	SSL_aDSS,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher A4 */
        +	{
        +	0,
        +	TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher A5 */
        +	{
        +	0,
        +	TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
        +	SSL_kDHd,
        +	SSL_aDH,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher A6 */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_ADH_WITH_AES_128_GCM_SHA256,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher A7 */
        +	{
        +	1,
        +	TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_ADH_WITH_AES_256_GCM_SHA384,
        +	SSL_kEDH,
        +	SSL_aNULL,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +#ifndef OPENSSL_NO_ECDH
        +	/* Cipher C001 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA,
        +	TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +	/* Cipher C002 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA,
        +	TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C003 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
        +	TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C004 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C005 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C006 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
        +	TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +	/* Cipher C007 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
        +	TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C008 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
        +	TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C009 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C00A */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C00B */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_NULL_SHA,
        +	TLS1_CK_ECDH_RSA_WITH_NULL_SHA,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +	/* Cipher C00C */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA,
        +	TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C00D */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA,
        +	TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C00E */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C00F */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C010 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA,
        +	TLS1_CK_ECDHE_RSA_WITH_NULL_SHA,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +	/* Cipher C011 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
        +	TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C012 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
        +	TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C013 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C014 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C015 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_anon_WITH_NULL_SHA,
        +	TLS1_CK_ECDH_anon_WITH_NULL_SHA,
        +	SSL_kEECDH,
        +	SSL_aNULL,
        +	SSL_eNULL,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	0,
        +	0,
        +	},
        +
        +	/* Cipher C016 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA,
        +	TLS1_CK_ECDH_anon_WITH_RC4_128_SHA,
        +	SSL_kEECDH,
        +	SSL_aNULL,
        +	SSL_RC4,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_MEDIUM,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C017 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA,
        +	TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA,
        +	SSL_kEECDH,
        +	SSL_aNULL,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C018 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA,
        +	SSL_kEECDH,
        +	SSL_aNULL,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C019 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA,
        +	SSL_kEECDH,
        +	SSL_aNULL,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +#endif	/* OPENSSL_NO_ECDH */
        +
        +#ifndef OPENSSL_NO_SRP
        +	/* Cipher C01A */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
        +	TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aNULL,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C01B */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
        +	TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aRSA,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C01C */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
        +	TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aDSS,
        +	SSL_3DES,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	168,
        +	168,
        +	},
        +
        +	/* Cipher C01D */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aNULL,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C01E */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C01F */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
        +	TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aDSS,
        +	SSL_AES128,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C020 */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aNULL,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C021 */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C022 */
        +	{
        +	1,
        +	TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
        +	TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
        +	SSL_kSRP,
        +	SSL_aDSS,
        +	SSL_AES256,
        +	SSL_SHA1,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +#endif  /* OPENSSL_NO_SRP */
        +#ifndef OPENSSL_NO_ECDH
        +
        +	/* HMAC based TLS v1.2 ciphersuites from RFC5289 */
        +
        +	/* Cipher C023 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
        +	TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C024 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
        +	TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_AES256,
        +	SSL_SHA384,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C025 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256,
        +	TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C026 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384,
        +	TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_AES256,
        +	SSL_SHA384,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C027 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
        +	TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C028 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
        +	TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_AES256,
        +	SSL_SHA384,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C029 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256,
        +	TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_AES128,
        +	SSL_SHA256,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C02A */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384,
        +	TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_AES256,
        +	SSL_SHA384,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* GCM based TLS v1.2 ciphersuites from RFC5289 */
        +
        +	/* Cipher C02B */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C02C */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kEECDH,
        +	SSL_aECDSA,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C02D */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C02E */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kECDHe,
        +	SSL_aECDH,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C02F */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C030 */
        +	{
        +	1,
        +	TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kEECDH,
        +	SSL_aRSA,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +	/* Cipher C031 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256,
        +	TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_AES128GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
        +	128,
        +	128,
        +	},
        +
        +	/* Cipher C032 */
        +	{
        +	1,
        +	TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384,
        +	TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384,
        +	SSL_kECDHr,
        +	SSL_aECDH,
        +	SSL_AES256GCM,
        +	SSL_AEAD,
        +	SSL_TLSV1_2,
        +	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
        +	SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
        +	256,
        +	256,
        +	},
        +
        +#endif /* OPENSSL_NO_ECDH */
        +
        +
        +#ifdef TEMP_GOST_TLS
        +/* Cipher FF00 */
        +	{
        +	1,
        +	"GOST-MD5",
        +	0x0300ff00,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eGOST2814789CNT,
        +	SSL_MD5,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256,
        +	},
        +	{
        +	1,
        +	"GOST-GOST94",
        +	0x0300ff01,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eGOST2814789CNT,
        +	SSL_GOST94,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256
        +	},
        +	{
        +	1,
        +	"GOST-GOST89MAC",
        +	0x0300ff02,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eGOST2814789CNT,
        +	SSL_GOST89MAC,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
        +	256,
        +	256
        +	},
        +	{
        +	1,
        +	"GOST-GOST89STREAM",
        +	0x0300ff03,
        +	SSL_kRSA,
        +	SSL_aRSA,
        +	SSL_eGOST2814789CNT,
        +	SSL_GOST89MAC,
        +	SSL_TLSV1,
        +	SSL_NOT_EXP|SSL_HIGH,
        +	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF|TLS1_STREAM_MAC,
        +	256,
        +	256
        +	},
        +#endif
        +
        +/* end of list */
        +	};
        +
        +SSL3_ENC_METHOD SSLv3_enc_data={
        +	ssl3_enc,
        +	n_ssl3_mac,
        +	ssl3_setup_key_block,
        +	ssl3_generate_master_secret,
        +	ssl3_change_cipher_state,
        +	ssl3_final_finish_mac,
        +	MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
        +	ssl3_cert_verify_mac,
        +	SSL3_MD_CLIENT_FINISHED_CONST,4,
        +	SSL3_MD_SERVER_FINISHED_CONST,4,
        +	ssl3_alert_code,
        +	(int (*)(SSL *, unsigned char *, size_t, const char *,
        +		 size_t, const unsigned char *, size_t,
        +		 int use_context))ssl_undefined_function,
        +	};
        +
        +long ssl3_default_timeout(void)
        +	{
        +	/* 2 hours, the 24 hours mentioned in the SSLv3 spec
        +	 * is way too long for http, the cache would over fill */
        +	return(60*60*2);
        +	}
        +
        +int ssl3_num_ciphers(void)
        +	{
        +	return(SSL3_NUM_CIPHERS);
        +	}
        +
        +const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
        +	{
        +	if (u < SSL3_NUM_CIPHERS)
        +		return(&(ssl3_ciphers[SSL3_NUM_CIPHERS-1-u]));
        +	else
        +		return(NULL);
        +	}
        +
        +int ssl3_pending(const SSL *s)
        +	{
        +	if (s->rstate == SSL_ST_READ_BODY)
        +		return 0;
        +	
        +	return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0;
        +	}
        +
        +int ssl3_new(SSL *s)
        +	{
        +	SSL3_STATE *s3;
        +
        +	if ((s3=OPENSSL_malloc(sizeof *s3)) == NULL) goto err;
        +	memset(s3,0,sizeof *s3);
        +	memset(s3->rrec.seq_num,0,sizeof(s3->rrec.seq_num));
        +	memset(s3->wrec.seq_num,0,sizeof(s3->wrec.seq_num));
        +
        +	s->s3=s3;
        +
        +#ifndef OPENSSL_NO_SRP
        +	SSL_SRP_CTX_init(s);
        +#endif
        +	s->method->ssl_clear(s);
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        +void ssl3_free(SSL *s)
        +	{
        +	if(s == NULL)
        +	    return;
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	if (s->s3->client_opaque_prf_input != NULL)
        +		OPENSSL_free(s->s3->client_opaque_prf_input);
        +	if (s->s3->server_opaque_prf_input != NULL)
        +		OPENSSL_free(s->s3->server_opaque_prf_input);
        +#endif
        +
        +	ssl3_cleanup_key_block(s);
        +	if (s->s3->rbuf.buf != NULL)
        +		ssl3_release_read_buffer(s);
        +	if (s->s3->wbuf.buf != NULL)
        +		ssl3_release_write_buffer(s);
        +	if (s->s3->rrec.comp != NULL)
        +		OPENSSL_free(s->s3->rrec.comp);
        +#ifndef OPENSSL_NO_DH
        +	if (s->s3->tmp.dh != NULL)
        +		DH_free(s->s3->tmp.dh);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if (s->s3->tmp.ecdh != NULL)
        +		EC_KEY_free(s->s3->tmp.ecdh);
        +#endif
        +
        +	if (s->s3->tmp.ca_names != NULL)
        +		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
        +	if (s->s3->handshake_buffer) {
        +		BIO_free(s->s3->handshake_buffer);
        +	}
        +	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
        +#ifndef OPENSSL_NO_SRP
        +	SSL_SRP_CTX_free(s);
        +#endif
        +	OPENSSL_cleanse(s->s3,sizeof *s->s3);
        +	OPENSSL_free(s->s3);
        +	s->s3=NULL;
        +	}
        +
        +void ssl3_clear(SSL *s)
        +	{
        +	unsigned char *rp,*wp;
        +	size_t rlen, wlen;
        +	int init_extra;
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	if (s->s3->client_opaque_prf_input != NULL)
        +		OPENSSL_free(s->s3->client_opaque_prf_input);
        +	s->s3->client_opaque_prf_input = NULL;
        +	if (s->s3->server_opaque_prf_input != NULL)
        +		OPENSSL_free(s->s3->server_opaque_prf_input);
        +	s->s3->server_opaque_prf_input = NULL;
        +#endif
        +
        +	ssl3_cleanup_key_block(s);
        +	if (s->s3->tmp.ca_names != NULL)
        +		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
        +
        +	if (s->s3->rrec.comp != NULL)
        +		{
        +		OPENSSL_free(s->s3->rrec.comp);
        +		s->s3->rrec.comp=NULL;
        +		}
        +#ifndef OPENSSL_NO_DH
        +	if (s->s3->tmp.dh != NULL)
        +		{
        +		DH_free(s->s3->tmp.dh);
        +		s->s3->tmp.dh = NULL;
        +		}
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if (s->s3->tmp.ecdh != NULL)
        +		{
        +		EC_KEY_free(s->s3->tmp.ecdh);
        +		s->s3->tmp.ecdh = NULL;
        +		}
        +#endif
        +
        +	rp = s->s3->rbuf.buf;
        +	wp = s->s3->wbuf.buf;
        +	rlen = s->s3->rbuf.len;
        + 	wlen = s->s3->wbuf.len;
        +	init_extra = s->s3->init_extra;
        +	if (s->s3->handshake_buffer) {
        +		BIO_free(s->s3->handshake_buffer);
        +		s->s3->handshake_buffer = NULL;
        +	}
        +	if (s->s3->handshake_dgst) {
        +		ssl3_free_digest_list(s);
        +	}	
        +	memset(s->s3,0,sizeof *s->s3);
        +	s->s3->rbuf.buf = rp;
        +	s->s3->wbuf.buf = wp;
        +	s->s3->rbuf.len = rlen;
        + 	s->s3->wbuf.len = wlen;
        +	s->s3->init_extra = init_extra;
        +
        +	ssl_free_wbio_buffer(s);
        +
        +	s->packet_length=0;
        +	s->s3->renegotiate=0;
        +	s->s3->total_renegotiations=0;
        +	s->s3->num_renegotiations=0;
        +	s->s3->in_read_app_data=0;
        +	s->version=SSL3_VERSION;
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	if (s->next_proto_negotiated)
        +		{
        +		OPENSSL_free(s->next_proto_negotiated);
        +		s->next_proto_negotiated = NULL;
        +		s->next_proto_negotiated_len = 0;
        +		}
        +#endif
        +	}
        +
        +#ifndef OPENSSL_NO_SRP
        +static char * MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg)
        +	{
        +	return BUF_strdup(s->srp_ctx.info) ;
        +	}
        +#endif
        +
        +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
        +	{
        +	int ret=0;
        +
        +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
        +	if (
        +#ifndef OPENSSL_NO_RSA
        +	    cmd == SSL_CTRL_SET_TMP_RSA ||
        +	    cmd == SSL_CTRL_SET_TMP_RSA_CB ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	    cmd == SSL_CTRL_SET_TMP_DH ||
        +	    cmd == SSL_CTRL_SET_TMP_DH_CB ||
        +#endif
        +		0)
        +		{
        +		if (!ssl_cert_inst(&s->cert))
        +		    	{
        +			SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		}
        +#endif
        +
        +	switch (cmd)
        +		{
        +	case SSL_CTRL_GET_SESSION_REUSED:
        +		ret=s->hit;
        +		break;
        +	case SSL_CTRL_GET_CLIENT_CERT_REQUEST:
        +		break;
        +	case SSL_CTRL_GET_NUM_RENEGOTIATIONS:
        +		ret=s->s3->num_renegotiations;
        +		break;
        +	case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS:
        +		ret=s->s3->num_renegotiations;
        +		s->s3->num_renegotiations=0;
        +		break;
        +	case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS:
        +		ret=s->s3->total_renegotiations;
        +		break;
        +	case SSL_CTRL_GET_FLAGS:
        +		ret=(int)(s->s3->flags);
        +		break;
        +#ifndef OPENSSL_NO_RSA
        +	case SSL_CTRL_NEED_TMP_RSA:
        +		if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) &&
        +		    ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) ||
        +		     (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > (512/8))))
        +			ret = 1;
        +		break;
        +	case SSL_CTRL_SET_TMP_RSA:
        +		{
        +			RSA *rsa = (RSA *)parg;
        +			if (rsa == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
        +				return(ret);
        +				}
        +			if ((rsa = RSAPrivateKey_dup(rsa)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB);
        +				return(ret);
        +				}
        +			if (s->cert->rsa_tmp != NULL)
        +				RSA_free(s->cert->rsa_tmp);
        +			s->cert->rsa_tmp = rsa;
        +			ret = 1;
        +		}
        +		break;
        +	case SSL_CTRL_SET_TMP_RSA_CB:
        +		{
        +		SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return(ret);
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	case SSL_CTRL_SET_TMP_DH:
        +		{
        +			DH *dh = (DH *)parg;
        +			if (dh == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
        +				return(ret);
        +				}
        +			if ((dh = DHparams_dup(dh)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
        +				return(ret);
        +				}
        +			if (!(s->options & SSL_OP_SINGLE_DH_USE))
        +				{
        +				if (!DH_generate_key(dh))
        +					{
        +					DH_free(dh);
        +					SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
        +					return(ret);
        +					}
        +				}
        +			if (s->cert->dh_tmp != NULL)
        +				DH_free(s->cert->dh_tmp);
        +			s->cert->dh_tmp = dh;
        +			ret = 1;
        +		}
        +		break;
        +	case SSL_CTRL_SET_TMP_DH_CB:
        +		{
        +		SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return(ret);
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	case SSL_CTRL_SET_TMP_ECDH:
        +		{
        +		EC_KEY *ecdh = NULL;
        + 			
        +		if (parg == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
        +			return(ret);
        +			}
        +		if (!EC_KEY_up_ref((EC_KEY *)parg))
        +			{
        +			SSLerr(SSL_F_SSL3_CTRL,ERR_R_ECDH_LIB);
        +			return(ret);
        +			}
        +		ecdh = (EC_KEY *)parg;
        +		if (!(s->options & SSL_OP_SINGLE_ECDH_USE))
        +			{
        +			if (!EC_KEY_generate_key(ecdh))
        +				{
        +				EC_KEY_free(ecdh);
        +				SSLerr(SSL_F_SSL3_CTRL,ERR_R_ECDH_LIB);
        +				return(ret);
        +				}
        +			}
        +		if (s->cert->ecdh_tmp != NULL)
        +			EC_KEY_free(s->cert->ecdh_tmp);
        +		s->cert->ecdh_tmp = ecdh;
        +		ret = 1;
        +		}
        +		break;
        +	case SSL_CTRL_SET_TMP_ECDH_CB:
        +		{
        +		SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return(ret);
        +		}
        +		break;
        +#endif /* !OPENSSL_NO_ECDH */
        +#ifndef OPENSSL_NO_TLSEXT
        +	case SSL_CTRL_SET_TLSEXT_HOSTNAME:
        + 		if (larg == TLSEXT_NAMETYPE_host_name)
        +			{
        +			if (s->tlsext_hostname != NULL) 
        +				OPENSSL_free(s->tlsext_hostname);
        +			s->tlsext_hostname = NULL;
        +
        +			ret = 1;
        +			if (parg == NULL) 
        +				break;
        +			if (strlen((char *)parg) > TLSEXT_MAXLEN_host_name)
        +				{
        +				SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
        +				return 0;
        +				}
        +			if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
        +				return 0;
        +				}
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
        +			return 0;
        +			}
        + 		break;
        +	case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
        +		s->tlsext_debug_arg=parg;
        +		ret = 1;
        +		break;
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT:
        +		if (larg > 12288) /* actual internal limit is 2^16 for the complete hello message
        +		                   * (including the cert chain and everything) */
        +			{
        +			SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG);
        +			break;
        +			}
        +		if (s->tlsext_opaque_prf_input != NULL)
        +			OPENSSL_free(s->tlsext_opaque_prf_input);
        +		if ((size_t)larg == 0)
        +			s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
        +		else
        +			s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg);
        +		if (s->tlsext_opaque_prf_input != NULL)
        +			{
        +			s->tlsext_opaque_prf_input_len = (size_t)larg;
        +			ret = 1;
        +			}
        +		else
        +			s->tlsext_opaque_prf_input_len = 0;
        +		break;
        +#endif
        +
        +	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
        +		s->tlsext_status_type=larg;
        +		ret = 1;
        +		break;
        +
        +	case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS:
        +		*(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts;
        +		ret = 1;
        +		break;
        +
        +	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS:
        +		s->tlsext_ocsp_exts = parg;
        +		ret = 1;
        +		break;
        +
        +	case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS:
        +		*(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids;
        +		ret = 1;
        +		break;
        +
        +	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS:
        +		s->tlsext_ocsp_ids = parg;
        +		ret = 1;
        +		break;
        +
        +	case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP:
        +		*(unsigned char **)parg = s->tlsext_ocsp_resp;
        +		return s->tlsext_ocsp_resplen;
        +		
        +	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
        +		if (s->tlsext_ocsp_resp)
        +			OPENSSL_free(s->tlsext_ocsp_resp);
        +		s->tlsext_ocsp_resp = parg;
        +		s->tlsext_ocsp_resplen = larg;
        +		ret = 1;
        +		break;
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT:
        +		if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
        +			ret = dtls1_heartbeat(s);
        +		else
        +			ret = tls1_heartbeat(s);
        +		break;
        +
        +	case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING:
        +		ret = s->tlsext_hb_pending;
        +		break;
        +
        +	case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS:
        +		if (larg)
        +			s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
        +		else
        +			s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
        +		ret = 1;
        +		break;
        +#endif
        +
        +#endif /* !OPENSSL_NO_TLSEXT */
        +	default:
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
        +	{
        +	int ret=0;
        +
        +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
        +	if (
        +#ifndef OPENSSL_NO_RSA
        +	    cmd == SSL_CTRL_SET_TMP_RSA_CB ||
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	    cmd == SSL_CTRL_SET_TMP_DH_CB ||
        +#endif
        +		0)
        +		{
        +		if (!ssl_cert_inst(&s->cert))
        +			{
        +			SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		}
        +#endif
        +
        +	switch (cmd)
        +		{
        +#ifndef OPENSSL_NO_RSA
        +	case SSL_CTRL_SET_TMP_RSA_CB:
        +		{
        +		s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	case SSL_CTRL_SET_TMP_DH_CB:
        +		{
        +		s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	case SSL_CTRL_SET_TMP_ECDH_CB:
        +		{
        +		s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_TLSEXT
        +	case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
        +		s->tlsext_debug_cb=(void (*)(SSL *,int ,int,
        +					unsigned char *, int, void *))fp;
        +		break;
        +#endif
        +	default:
        +		break;
        +		}
        +	return(ret);
        +	}
        +
        +long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
        +	{
        +	CERT *cert;
        +
        +	cert=ctx->cert;
        +
        +	switch (cmd)
        +		{
        +#ifndef OPENSSL_NO_RSA
        +	case SSL_CTRL_NEED_TMP_RSA:
        +		if (	(cert->rsa_tmp == NULL) &&
        +			((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) ||
        +			 (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > (512/8)))
        +			)
        +			return(1);
        +		else
        +			return(0);
        +		/* break; */
        +	case SSL_CTRL_SET_TMP_RSA:
        +		{
        +		RSA *rsa;
        +		int i;
        +
        +		rsa=(RSA *)parg;
        +		i=1;
        +		if (rsa == NULL)
        +			i=0;
        +		else
        +			{
        +			if ((rsa=RSAPrivateKey_dup(rsa)) == NULL)
        +				i=0;
        +			}
        +		if (!i)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_RSA_LIB);
        +			return(0);
        +			}
        +		else
        +			{
        +			if (cert->rsa_tmp != NULL)
        +				RSA_free(cert->rsa_tmp);
        +			cert->rsa_tmp=rsa;
        +			return(1);
        +			}
        +		}
        +		/* break; */
        +	case SSL_CTRL_SET_TMP_RSA_CB:
        +		{
        +		SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return(0);
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	case SSL_CTRL_SET_TMP_DH:
        +		{
        +		DH *new=NULL,*dh;
        +
        +		dh=(DH *)parg;
        +		if ((new=DHparams_dup(dh)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_DH_LIB);
        +			return 0;
        +			}
        +		if (!(ctx->options & SSL_OP_SINGLE_DH_USE))
        +			{
        +			if (!DH_generate_key(new))
        +				{
        +				SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_DH_LIB);
        +				DH_free(new);
        +				return 0;
        +				}
        +			}
        +		if (cert->dh_tmp != NULL)
        +			DH_free(cert->dh_tmp);
        +		cert->dh_tmp=new;
        +		return 1;
        +		}
        +		/*break; */
        +	case SSL_CTRL_SET_TMP_DH_CB:
        +		{
        +		SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return(0);
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	case SSL_CTRL_SET_TMP_ECDH:
        +		{
        +		EC_KEY *ecdh = NULL;
        + 			
        +		if (parg == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_ECDH_LIB);
        +			return 0;
        +			}
        +		ecdh = EC_KEY_dup((EC_KEY *)parg);
        +		if (ecdh == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_EC_LIB);
        +			return 0;
        +			}
        +		if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE))
        +			{
        +			if (!EC_KEY_generate_key(ecdh))
        +				{
        +				EC_KEY_free(ecdh);
        +				SSLerr(SSL_F_SSL3_CTX_CTRL,ERR_R_ECDH_LIB);
        +				return 0;
        +				}
        +			}
        +
        +		if (cert->ecdh_tmp != NULL)
        +			{
        +			EC_KEY_free(cert->ecdh_tmp);
        +			}
        +		cert->ecdh_tmp = ecdh;
        +		return 1;
        +		}
        +		/* break; */
        +	case SSL_CTRL_SET_TMP_ECDH_CB:
        +		{
        +		SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +		return(0);
        +		}
        +		break;
        +#endif /* !OPENSSL_NO_ECDH */
        +#ifndef OPENSSL_NO_TLSEXT
        +	case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG:
        +		ctx->tlsext_servername_arg=parg;
        +		break;
        +	case SSL_CTRL_SET_TLSEXT_TICKET_KEYS:
        +	case SSL_CTRL_GET_TLSEXT_TICKET_KEYS:
        +		{
        +		unsigned char *keys = parg;
        +		if (!keys)
        +			return 48;
        +		if (larg != 48)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
        +			return 0;
        +			}
        +		if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS)
        +			{
        +			memcpy(ctx->tlsext_tick_key_name, keys, 16);
        +			memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16);
        +			memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16);
        +			}
        +		else
        +			{
        +			memcpy(keys, ctx->tlsext_tick_key_name, 16);
        +			memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16);
        +			memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16);
        +			}
        +		return 1;
        +		}
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
        +		ctx->tlsext_opaque_prf_input_callback_arg = parg;
        +		return 1;
        +#endif
        +
        +	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG:
        +		ctx->tlsext_status_arg=parg;
        +		return 1;
        +		break;
        +
        +#ifndef OPENSSL_NO_SRP
        +	case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
        +		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
        +		if (ctx->srp_ctx.login != NULL)
        +			OPENSSL_free(ctx->srp_ctx.login);
        +		ctx->srp_ctx.login = NULL;
        +		if (parg == NULL)
        +			break;
        +		if (strlen((const char *)parg) > 255 || strlen((const char *)parg) < 1)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
        +			return 0;
        +			} 
        +		if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
        +			return 0;
        +			}
        +		break;
        +	case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
        +		ctx->srp_ctx.SRP_give_srp_client_pwd_callback=srp_password_from_info_cb;
        +		ctx->srp_ctx.info=parg;
        +		break;
        +	case SSL_CTRL_SET_SRP_ARG:
        +		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
        +		ctx->srp_ctx.SRP_cb_arg=parg;
        +		break;
        +
        +	case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
        +		ctx->srp_ctx.strength=larg;
        +		break;
        +#endif
        +#endif /* !OPENSSL_NO_TLSEXT */
        +
        +	/* A Thawte special :-) */
        +	case SSL_CTRL_EXTRA_CHAIN_CERT:
        +		if (ctx->extra_certs == NULL)
        +			{
        +			if ((ctx->extra_certs=sk_X509_new_null()) == NULL)
        +				return(0);
        +			}
        +		sk_X509_push(ctx->extra_certs,(X509 *)parg);
        +		break;
        +
        +	case SSL_CTRL_GET_EXTRA_CHAIN_CERTS:
        +		*(STACK_OF(X509) **)parg =  ctx->extra_certs;
        +		break;
        +
        +	case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
        +		if (ctx->extra_certs)
        +			{
        +			sk_X509_pop_free(ctx->extra_certs, X509_free);
        +			ctx->extra_certs = NULL;
        +			}
        +		break;
        +
        +	default:
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
        +	{
        +	CERT *cert;
        +
        +	cert=ctx->cert;
        +
        +	switch (cmd)
        +		{
        +#ifndef OPENSSL_NO_RSA
        +	case SSL_CTRL_SET_TMP_RSA_CB:
        +		{
        +		cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	case SSL_CTRL_SET_TMP_DH_CB:
        +		{
        +		cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	case SSL_CTRL_SET_TMP_ECDH_CB:
        +		{
        +		cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
        +		}
        +		break;
        +#endif
        +#ifndef OPENSSL_NO_TLSEXT
        +	case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
        +		ctx->tlsext_servername_callback=(int (*)(SSL *,int *,void *))fp;
        +		break;
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB:
        +		ctx->tlsext_opaque_prf_input_callback = (int (*)(SSL *,void *, size_t, void *))fp;
        +		break;
        +#endif
        +
        +	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB:
        +		ctx->tlsext_status_cb=(int (*)(SSL *,void *))fp;
        +		break;
        +
        +	case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
        +		ctx->tlsext_ticket_key_cb=(int (*)(SSL *,unsigned char  *,
        +						unsigned char *,
        +						EVP_CIPHER_CTX *,
        +						HMAC_CTX *, int))fp;
        +		break;
        +
        +#ifndef OPENSSL_NO_SRP
        +	case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
        +		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
        +		ctx->srp_ctx.SRP_verify_param_callback=(int (*)(SSL *,void *))fp;
        +		break;
        +	case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
        +		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
        +		ctx->srp_ctx.TLS_ext_srp_username_callback=(int (*)(SSL *,int *,void *))fp;
        +		break;
        +	case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
        +		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
        +		ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
        +		break;
        +#endif
        +#endif
        +	default:
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +/* This function needs to check if the ciphers required are actually
        + * available */
        +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
        +	{
        +	SSL_CIPHER c;
        +	const SSL_CIPHER *cp;
        +	unsigned long id;
        +
        +	id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1];
        +	c.id=id;
        +	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
        +#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES
        +if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]);
        +#endif
        +	if (cp == NULL || cp->valid == 0)
        +		return NULL;
        +	else
        +		return cp;
        +	}
        +
        +int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
        +	{
        +	long l;
        +
        +	if (p != NULL)
        +		{
        +		l=c->id;
        +		if ((l & 0xff000000) != 0x03000000) return(0);
        +		p[0]=((unsigned char)(l>> 8L))&0xFF;
        +		p[1]=((unsigned char)(l     ))&0xFF;
        +		}
        +	return(2);
        +	}
        +
        +SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
        +	     STACK_OF(SSL_CIPHER) *srvr)
        +	{
        +	SSL_CIPHER *c,*ret=NULL;
        +	STACK_OF(SSL_CIPHER) *prio, *allow;
        +	int i,ii,ok;
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC)
        +	unsigned int j;
        +	int ec_ok, ec_nid;
        +	unsigned char ec_search1 = 0, ec_search2 = 0;
        +#endif
        +	CERT *cert;
        +	unsigned long alg_k,alg_a,mask_k,mask_a,emask_k,emask_a;
        +
        +	/* Let's see which ciphers we can support */
        +	cert=s->cert;
        +
        +#if 0
        +	/* Do not set the compare functions, because this may lead to a
        +	 * reordering by "id". We want to keep the original ordering.
        +	 * We may pay a price in performance during sk_SSL_CIPHER_find(),
        +	 * but would have to pay with the price of sk_SSL_CIPHER_dup().
        +	 */
        +	sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp);
        +	sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp);
        +#endif
        +
        +#ifdef CIPHER_DEBUG
        +	printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
        +	for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
        +		{
        +		c=sk_SSL_CIPHER_value(srvr,i);
        +		printf("%p:%s\n",(void *)c,c->name);
        +		}
        +	printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
        +	for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
        +	    {
        +	    c=sk_SSL_CIPHER_value(clnt,i);
        +	    printf("%p:%s\n",(void *)c,c->name);
        +	    }
        +#endif
        +
        +	if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
        +		{
        +		prio = srvr;
        +		allow = clnt;
        +		}
        +	else
        +		{
        +		prio = clnt;
        +		allow = srvr;
        +		}
        +
        +	for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
        +		{
        +		c=sk_SSL_CIPHER_value(prio,i);
        +
        +		/* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
        +		if ((c->algorithm_ssl & SSL_TLSV1_2) && 
        +			(TLS1_get_version(s) < TLS1_2_VERSION))
        +			continue;
        +
        +		ssl_set_cert_masks(cert,c);
        +		mask_k = cert->mask_k;
        +		mask_a = cert->mask_a;
        +		emask_k = cert->export_mask_k;
        +		emask_a = cert->export_mask_a;
        +#ifndef OPENSSL_NO_SRP
        +		mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
        +		emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
        +#endif
        +			
        +#ifdef KSSL_DEBUG
        +/*		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
        +#endif    /* KSSL_DEBUG */
        +
        +		alg_k=c->algorithm_mkey;
        +		alg_a=c->algorithm_auth;
        +
        +#ifndef OPENSSL_NO_KRB5
        +		if (alg_k & SSL_kKRB5)
        +			{
        +			if ( !kssl_keytab_is_available(s->kssl_ctx) )
        +			    continue;
        +			}
        +#endif /* OPENSSL_NO_KRB5 */
        +#ifndef OPENSSL_NO_PSK
        +		/* with PSK there must be server callback set */
        +		if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL)
        +			continue;
        +#endif /* OPENSSL_NO_PSK */
        +
        +		if (SSL_C_IS_EXPORT(c))
        +			{
        +			ok = (alg_k & emask_k) && (alg_a & emask_a);
        +#ifdef CIPHER_DEBUG
        +			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
        +			       (void *)c,c->name);
        +#endif
        +			}
        +		else
        +			{
        +			ok = (alg_k & mask_k) && (alg_a & mask_a);
        +#ifdef CIPHER_DEBUG
        +			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
        +			       c->name);
        +#endif
        +			}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +#ifndef OPENSSL_NO_EC
        +		if (
        +			/* if we are considering an ECC cipher suite that uses our certificate */
        +			(alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
        +			/* and we have an ECC certificate */
        +			&& (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
        +			/* and the client specified a Supported Point Formats extension */
        +			&& ((s->session->tlsext_ecpointformatlist_length > 0) && (s->session->tlsext_ecpointformatlist != NULL))
        +			/* and our certificate's point is compressed */
        +			&& (
        +				(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL)
        +				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL)
        +				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL)
        +				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL)
        +				&& (
        +					(*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED)
        +					|| (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1)
        +					)
        +				)
        +		)
        +			{
        +			ec_ok = 0;
        +			/* if our certificate's curve is over a field type that the client does not support
        +			 * then do not allow this cipher suite to be negotiated */
        +			if (
        +				(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
        +				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
        +				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
        +				&& (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
        +			)
        +				{
        +				for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++)
        +					{
        +					if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime)
        +						{
        +						ec_ok = 1;
        +						break;
        +						}
        +					}
        +				}
        +			else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
        +				{
        +				for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++)
        +					{
        +					if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2)
        +						{
        +						ec_ok = 1;
        +						break;
        +						}
        +					}
        +				}
        +			ok = ok && ec_ok;
        +			}
        +		if (
        +			/* if we are considering an ECC cipher suite that uses our certificate */
        +			(alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
        +			/* and we have an ECC certificate */
        +			&& (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
        +			/* and the client specified an EllipticCurves extension */
        +			&& ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
        +		)
        +			{
        +			ec_ok = 0;
        +			if (
        +				(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
        +				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
        +			)
        +				{
        +				ec_nid = EC_GROUP_get_curve_name(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group);
        +				if ((ec_nid == 0)
        +					&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
        +				)
        +					{
        +					if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
        +						{
        +						ec_search1 = 0xFF;
        +						ec_search2 = 0x01;
        +						}
        +					else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
        +						{
        +						ec_search1 = 0xFF;
        +						ec_search2 = 0x02;
        +						}
        +					}
        +				else
        +					{
        +					ec_search1 = 0x00;
        +					ec_search2 = tls1_ec_nid2curve_id(ec_nid);
        +					}
        +				if ((ec_search1 != 0) || (ec_search2 != 0))
        +					{
        +					for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
        +						{
        +						if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
        +							{
        +							ec_ok = 1;
        +							break;
        +							}
        +						}
        +					}
        +				}
        +			ok = ok && ec_ok;
        +			}
        +		if (
        +			/* if we are considering an ECC cipher suite that uses an ephemeral EC key */
        +			(alg_k & SSL_kEECDH)
        +			/* and we have an ephemeral EC key */
        +			&& (s->cert->ecdh_tmp != NULL)
        +			/* and the client specified an EllipticCurves extension */
        +			&& ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
        +		)
        +			{
        +			ec_ok = 0;
        +			if (s->cert->ecdh_tmp->group != NULL)
        +				{
        +				ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group);
        +				if ((ec_nid == 0)
        +					&& (s->cert->ecdh_tmp->group->meth != NULL)
        +				)
        +					{
        +					if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_prime_field)
        +						{
        +						ec_search1 = 0xFF;
        +						ec_search2 = 0x01;
        +						}
        +					else if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_characteristic_two_field)
        +						{
        +						ec_search1 = 0xFF;
        +						ec_search2 = 0x02;
        +						}
        +					}
        +				else
        +					{
        +					ec_search1 = 0x00;
        +					ec_search2 = tls1_ec_nid2curve_id(ec_nid);
        +					}
        +				if ((ec_search1 != 0) || (ec_search2 != 0))
        +					{
        +					for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
        +						{
        +						if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
        +							{
        +							ec_ok = 1;
        +							break;
        +							}
        +						}
        +					}
        +				}
        +			ok = ok && ec_ok;
        +			}
        +#endif /* OPENSSL_NO_EC */
        +#endif /* OPENSSL_NO_TLSEXT */
        +
        +		if (!ok) continue;
        +		ii=sk_SSL_CIPHER_find(allow,c);
        +		if (ii >= 0)
        +			{
        +			ret=sk_SSL_CIPHER_value(allow,ii);
        +			break;
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
        +	{
        +	int ret=0;
        +	unsigned long alg_k;
        +
        +	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
        +
        +#ifndef OPENSSL_NO_GOST
        +	if (s->version >= TLS1_VERSION)
        +		{
        +		if (alg_k & SSL_kGOST)
        +			{
        +			p[ret++]=TLS_CT_GOST94_SIGN;
        +			p[ret++]=TLS_CT_GOST01_SIGN;
        +			return(ret);
        +			}
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	if (alg_k & (SSL_kDHr|SSL_kEDH))
        +		{
        +#  ifndef OPENSSL_NO_RSA
        +		p[ret++]=SSL3_CT_RSA_FIXED_DH;
        +#  endif
        +#  ifndef OPENSSL_NO_DSA
        +		p[ret++]=SSL3_CT_DSS_FIXED_DH;
        +#  endif
        +		}
        +	if ((s->version == SSL3_VERSION) &&
        +		(alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
        +		{
        +#  ifndef OPENSSL_NO_RSA
        +		p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH;
        +#  endif
        +#  ifndef OPENSSL_NO_DSA
        +		p[ret++]=SSL3_CT_DSS_EPHEMERAL_DH;
        +#  endif
        +		}
        +#endif /* !OPENSSL_NO_DH */
        +#ifndef OPENSSL_NO_RSA
        +	p[ret++]=SSL3_CT_RSA_SIGN;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	p[ret++]=SSL3_CT_DSS_SIGN;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION))
        +		{
        +		p[ret++]=TLS_CT_RSA_FIXED_ECDH;
        +		p[ret++]=TLS_CT_ECDSA_FIXED_ECDH;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDSA
        +	/* ECDSA certs can be used with RSA cipher suites as well 
        +	 * so we don't need to check for SSL_kECDH or SSL_kEECDH
        +	 */
        +	if (s->version >= TLS1_VERSION)
        +		{
        +		p[ret++]=TLS_CT_ECDSA_SIGN;
        +		}
        +#endif	
        +	return(ret);
        +	}
        +
        +int ssl3_shutdown(SSL *s)
        +	{
        +	int ret;
        +
        +	/* Don't do anything much if we have not done the handshake or
        +	 * we don't want to send messages :-) */
        +	if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE))
        +		{
        +		s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        +		return(1);
        +		}
        +
        +	if (!(s->shutdown & SSL_SENT_SHUTDOWN))
        +		{
        +		s->shutdown|=SSL_SENT_SHUTDOWN;
        +#if 1
        +		ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_CLOSE_NOTIFY);
        +#endif
        +		/* our shutdown alert has been sent now, and if it still needs
        +	 	 * to be written, s->s3->alert_dispatch will be true */
        +	 	if (s->s3->alert_dispatch)
        +	 		return(-1);	/* return WANT_WRITE */
        +		}
        +	else if (s->s3->alert_dispatch)
        +		{
        +		/* resend it if not sent */
        +#if 1
        +		ret=s->method->ssl_dispatch_alert(s);
        +		if(ret == -1)
        +			{
        +			/* we only get to return -1 here the 2nd/Nth
        +			 * invocation, we must  have already signalled
        +			 * return 0 upon a previous invoation,
        +			 * return WANT_WRITE */
        +			return(ret);
        +			}
        +#endif
        +		}
        +	else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN))
        +		{
        +		/* If we are waiting for a close from our peer, we are closed */
        +		s->method->ssl_read_bytes(s,0,NULL,0,0);
        +		if(!(s->shutdown & SSL_RECEIVED_SHUTDOWN))
        +			{
        +			return(-1);	/* return WANT_READ */
        +			}
        +		}
        +
        +	if ((s->shutdown == (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) &&
        +		!s->s3->alert_dispatch)
        +		return(1);
        +	else
        +		return(0);
        +	}
        +
        +int ssl3_write(SSL *s, const void *buf, int len)
        +	{
        +	int ret,n;
        +
        +#if 0
        +	if (s->shutdown & SSL_SEND_SHUTDOWN)
        +		{
        +		s->rwstate=SSL_NOTHING;
        +		return(0);
        +		}
        +#endif
        +	clear_sys_error();
        +	if (s->s3->renegotiate) ssl3_renegotiate_check(s);
        +
        +	/* This is an experimental flag that sends the
        +	 * last handshake message in the same packet as the first
        +	 * use data - used to see if it helps the TCP protocol during
        +	 * session-id reuse */
        +	/* The second test is because the buffer may have been removed */
        +	if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
        +		{
        +		/* First time through, we write into the buffer */
        +		if (s->s3->delay_buf_pop_ret == 0)
        +			{
        +			ret=ssl3_write_bytes(s,SSL3_RT_APPLICATION_DATA,
        +					     buf,len);
        +			if (ret <= 0) return(ret);
        +
        +			s->s3->delay_buf_pop_ret=ret;
        +			}
        +
        +		s->rwstate=SSL_WRITING;
        +		n=BIO_flush(s->wbio);
        +		if (n <= 0) return(n);
        +		s->rwstate=SSL_NOTHING;
        +
        +		/* We have flushed the buffer, so remove it */
        +		ssl_free_wbio_buffer(s);
        +		s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
        +
        +		ret=s->s3->delay_buf_pop_ret;
        +		s->s3->delay_buf_pop_ret=0;
        +		}
        +	else
        +		{
        +		ret=s->method->ssl_write_bytes(s,SSL3_RT_APPLICATION_DATA,
        +			buf,len);
        +		if (ret <= 0) return(ret);
        +		}
        +
        +	return(ret);
        +	}
        +
        +static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
        +	{
        +	int ret;
        +	
        +	clear_sys_error();
        +	if (s->s3->renegotiate) ssl3_renegotiate_check(s);
        +	s->s3->in_read_app_data=1;
        +	ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
        +	if ((ret == -1) && (s->s3->in_read_app_data == 2))
        +		{
        +		/* ssl3_read_bytes decided to call s->handshake_func, which
        +		 * called ssl3_read_bytes to read handshake data.
        +		 * However, ssl3_read_bytes actually found application data
        +		 * and thinks that application data makes sense here; so disable
        +		 * handshake processing and try to read application data again. */
        +		s->in_handshake++;
        +		ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
        +		s->in_handshake--;
        +		}
        +	else
        +		s->s3->in_read_app_data=0;
        +
        +	return(ret);
        +	}
        +
        +int ssl3_read(SSL *s, void *buf, int len)
        +	{
        +	return ssl3_read_internal(s, buf, len, 0);
        +	}
        +
        +int ssl3_peek(SSL *s, void *buf, int len)
        +	{
        +	return ssl3_read_internal(s, buf, len, 1);
        +	}
        +
        +int ssl3_renegotiate(SSL *s)
        +	{
        +	if (s->handshake_func == NULL)
        +		return(1);
        +
        +	if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
        +		return(0);
        +
        +	s->s3->renegotiate=1;
        +	return(1);
        +	}
        +
        +int ssl3_renegotiate_check(SSL *s)
        +	{
        +	int ret=0;
        +
        +	if (s->s3->renegotiate)
        +		{
        +		if (	(s->s3->rbuf.left == 0) &&
        +			(s->s3->wbuf.left == 0) &&
        +			!SSL_in_init(s))
        +			{
        +/*
        +if we are the server, and we have sent a 'RENEGOTIATE' message, we
        +need to go to SSL_ST_ACCEPT.
        +*/
        +			/* SSL_ST_ACCEPT */
        +			s->state=SSL_ST_RENEGOTIATE;
        +			s->s3->renegotiate=0;
        +			s->s3->num_renegotiations++;
        +			s->s3->total_renegotiations++;
        +			ret=1;
        +			}
        +		}
        +	return(ret);
        +	}
        +/* If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch
        + * to new SHA256 PRF and handshake macs
        + */
        +long ssl_get_algorithm2(SSL *s)
        +	{
        +	long alg2 = s->s3->tmp.new_cipher->algorithm2;
        +	if (TLS1_get_version(s) >= TLS1_2_VERSION &&
        +	    alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
        +		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
        +	return alg2;
        +	}
        +		
        diff --git a/vendor/openssl/openssl/ssl/s3_meth.c b/vendor/openssl/openssl/ssl/s3_meth.c
        new file mode 100644
        index 000000000..cdddb17b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_meth.c
        @@ -0,0 +1,77 @@
        +/* ssl/s3_meth.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +static const SSL_METHOD *ssl3_get_method(int ver);
        +static const SSL_METHOD *ssl3_get_method(int ver)
        +	{
        +	if (ver == SSL3_VERSION)
        +		return(SSLv3_method());
        +	else 
        +		return(NULL);
        +	}
        +
        +IMPLEMENT_ssl3_meth_func(SSLv3_method,
        +			 ssl3_accept,
        +			 ssl3_connect,
        +			 ssl3_get_method)
        +
        +
        diff --git a/vendor/openssl/openssl/ssl/s3_pkt.c b/vendor/openssl/openssl/ssl/s3_pkt.c
        new file mode 100644
        index 000000000..804291e27
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_pkt.c
        @@ -0,0 +1,1523 @@
        +/* ssl/s3_pkt.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-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +
        +#include <stdio.h>
        +#include <errno.h>
        +#define USE_SOCKETS
        +#include "ssl_locl.h"
        +#include <openssl/evp.h>
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +
        +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        +			 unsigned int len, int create_empty_fragment);
        +static int ssl3_get_record(SSL *s);
        +
        +int ssl3_read_n(SSL *s, int n, int max, int extend)
        +	{
        +	/* If extend == 0, obtain new n-byte packet; if extend == 1, increase
        +	 * packet by another n bytes.
        +	 * The packet will be in the sub-array of s->s3->rbuf.buf specified
        +	 * by s->packet and s->packet_length.
        +	 * (If s->read_ahead is set, 'max' bytes may be stored in rbuf
        +	 * [plus s->packet_length bytes if extend == 1].)
        +	 */
        +	int i,len,left;
        +	long align=0;
        +	unsigned char *pkt;
        +	SSL3_BUFFER *rb;
        +
        +	if (n <= 0) return n;
        +
        +	rb    = &(s->s3->rbuf);
        +	if (rb->buf == NULL)
        +		if (!ssl3_setup_read_buffer(s))
        +			return -1;
        +
        +	left  = rb->left;
        +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        +	align = (long)rb->buf + SSL3_RT_HEADER_LENGTH;
        +	align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
        +#endif
        +
        +	if (!extend)
        +		{
        +		/* start with empty packet ... */
        +		if (left == 0)
        +			rb->offset = align;
        +		else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH)
        +			{
        +			/* check if next packet length is large
        +			 * enough to justify payload alignment... */
        +			pkt = rb->buf + rb->offset;
        +			if (pkt[0] == SSL3_RT_APPLICATION_DATA
        +			    && (pkt[3]<<8|pkt[4]) >= 128)
        +				{
        +				/* Note that even if packet is corrupted
        +				 * and its length field is insane, we can
        +				 * only be led to wrong decision about
        +				 * whether memmove will occur or not.
        +				 * Header values has no effect on memmove
        +				 * arguments and therefore no buffer
        +				 * overrun can be triggered. */
        +				memmove (rb->buf+align,pkt,left);
        +				rb->offset = align;
        +				}
        +			}
        +		s->packet = rb->buf + rb->offset;
        +		s->packet_length = 0;
        +		/* ... now we can act as if 'extend' was set */
        +		}
        +
        +	/* For DTLS/UDP reads should not span multiple packets
        +	 * because the read operation returns the whole packet
        +	 * at once (as long as it fits into the buffer). */
        +	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
        +		{
        +		if (left > 0 && n > left)
        +			n = left;
        +		}
        +
        +	/* if there is enough in the buffer from a previous read, take some */
        +	if (left >= n)
        +		{
        +		s->packet_length+=n;
        +		rb->left=left-n;
        +		rb->offset+=n;
        +		return(n);
        +		}
        +
        +	/* else we need to read more data */
        +
        +	len = s->packet_length;
        +	pkt = rb->buf+align;
        +	/* Move any available bytes to front of buffer:
        +	 * 'len' bytes already pointed to by 'packet',
        +	 * 'left' extra ones at the end */
        +	if (s->packet != pkt) /* len > 0 */
        +		{
        +		memmove(pkt, s->packet, len+left);
        +		s->packet = pkt;
        +		rb->offset = len + align;
        +		}
        +
        +	if (n > (int)(rb->len - rb->offset)) /* does not happen */
        +		{
        +		SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +
        +	if (!s->read_ahead)
        +		/* ignore max parameter */
        +		max = n;
        +	else
        +		{
        +		if (max < n)
        +			max = n;
        +		if (max > (int)(rb->len - rb->offset))
        +			max = rb->len - rb->offset;
        +		}
        +
        +	while (left < n)
        +		{
        +		/* Now we have len+left bytes at the front of s->s3->rbuf.buf
        +		 * and need to read in more until we have len+n (up to
        +		 * len+max if possible) */
        +
        +		clear_sys_error();
        +		if (s->rbio != NULL)
        +			{
        +			s->rwstate=SSL_READING;
        +			i=BIO_read(s->rbio,pkt+len+left, max-left);
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET);
        +			i = -1;
        +			}
        +
        +		if (i <= 0)
        +			{
        +			rb->left = left;
        +			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
        +			    SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
        +				if (len+left == 0)
        +					ssl3_release_read_buffer(s);
        +			return(i);
        +			}
        +		left+=i;
        +		/* reads should *never* span multiple packets for DTLS because
        +		 * the underlying transport protocol is message oriented as opposed
        +		 * to byte oriented as in the TLS case. */
        +		if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
        +			{
        +			if (n > left)
        +				n = left; /* makes the while condition false */
        +			}
        +		}
        +
        +	/* done reading, now the book-keeping */
        +	rb->offset += n;
        +	rb->left = left - n;
        +	s->packet_length += n;
        +	s->rwstate=SSL_NOTHING;
        +	return(n);
        +	}
        +
        +/* Call this to get a new input record.
        + * It will return <= 0 if more data is needed, normally due to an error
        + * or non-blocking IO.
        + * When it finishes, one packet has been decoded and can be found in
        + * ssl->s3->rrec.type    - is the type of record
        + * ssl->s3->rrec.data, 	 - data
        + * ssl->s3->rrec.length, - number of bytes
        + */
        +/* used only by ssl3_read_bytes */
        +static int ssl3_get_record(SSL *s)
        +	{
        +	int ssl_major,ssl_minor,al;
        +	int enc_err,n,i,ret= -1;
        +	SSL3_RECORD *rr;
        +	SSL_SESSION *sess;
        +	unsigned char *p;
        +	unsigned char md[EVP_MAX_MD_SIZE];
        +	short version;
        +	unsigned mac_size, orig_len;
        +	size_t extra;
        +
        +	rr= &(s->s3->rrec);
        +	sess=s->session;
        +
        +	if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
        +		extra=SSL3_RT_MAX_EXTRA;
        +	else
        +		extra=0;
        +	if (extra && !s->s3->init_extra)
        +		{
        +		/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
        +		 * set after ssl3_setup_buffers() was done */
        +		SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +
        +again:
        +	/* check if we have the header */
        +	if (	(s->rstate != SSL_ST_READ_BODY) ||
        +		(s->packet_length < SSL3_RT_HEADER_LENGTH)) 
        +		{
        +		n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
        +		if (n <= 0) return(n); /* error or non-blocking */
        +		s->rstate=SSL_ST_READ_BODY;
        +
        +		p=s->packet;
        +
        +		/* Pull apart the header into the SSL3_RECORD */
        +		rr->type= *(p++);
        +		ssl_major= *(p++);
        +		ssl_minor= *(p++);
        +		version=(ssl_major<<8)|ssl_minor;
        +		n2s(p,rr->length);
        +#if 0
        +fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
        +#endif
        +
        +		/* Lets check version */
        +		if (!s->first_packet)
        +			{
        +			if (version != s->version)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
        +                                if ((s->version & 0xFF00) == (version & 0xFF00))
        +                                	/* Send back error using their minor version number :-) */
        +					s->version = (unsigned short)version;
        +				al=SSL_AD_PROTOCOL_VERSION;
        +				goto f_err;
        +				}
        +			}
        +
        +		if ((version>>8) != SSL3_VERSION_MAJOR)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
        +			goto err;
        +			}
        +
        +		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
        +			{
        +			al=SSL_AD_RECORD_OVERFLOW;
        +			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
        +			goto f_err;
        +			}
        +
        +		/* now s->rstate == SSL_ST_READ_BODY */
        +		}
        +
        +	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */
        +
        +	if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH)
        +		{
        +		/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
        +		i=rr->length;
        +		n=ssl3_read_n(s,i,i,1);
        +		if (n <= 0) return(n); /* error or non-blocking io */
        +		/* now n == rr->length,
        +		 * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */
        +		}
        +
        +	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
        +
        +	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
        +	 * and we have that many bytes in s->packet
        +	 */
        +	rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);
        +
        +	/* ok, we can now read from 's->packet' data into 'rr'
        +	 * rr->input points at rr->length bytes, which
        +	 * need to be copied into rr->data by either
        +	 * the decryption or by the decompression
        +	 * When the data is 'copied' into the rr->data buffer,
        +	 * rr->input will be pointed at the new buffer */ 
        +
        +	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
        +	 * rr->length bytes of encrypted compressed stuff. */
        +
        +	/* check is not needed I believe */
        +	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
        +		{
        +		al=SSL_AD_RECORD_OVERFLOW;
        +		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
        +		goto f_err;
        +		}
        +
        +	/* decrypt in place in 'rr->input' */
        +	rr->data=rr->input;
        +
        +	enc_err = s->method->ssl3_enc->enc(s,0);
        +	/* enc_err is:
        +	 *    0: (in non-constant time) if the record is publically invalid.
        +	 *    1: if the padding is valid
        +	 *    -1: if the padding is invalid */
        +	if (enc_err == 0)
        +		{
        +		al=SSL_AD_DECRYPTION_FAILED;
        +		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
        +		goto f_err;
        +		}
        +
        +#ifdef TLS_DEBUG
        +printf("dec %d\n",rr->length);
        +{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
        +printf("\n");
        +#endif
        +
        +	/* r->length is now the compressed data plus mac */
        +	if ((sess != NULL) &&
        +	    (s->enc_read_ctx != NULL) &&
        +	    (EVP_MD_CTX_md(s->read_hash) != NULL))
        +		{
        +		/* s->read_hash != NULL => mac_size != -1 */
        +		unsigned char *mac = NULL;
        +		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
        +		mac_size=EVP_MD_CTX_size(s->read_hash);
        +		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
        +
        +		/* kludge: *_cbc_remove_padding passes padding length in rr->type */
        +		orig_len = rr->length+((unsigned int)rr->type>>8);
        +
        +		/* orig_len is the length of the record before any padding was
        +		 * removed. This is public information, as is the MAC in use,
        +		 * therefore we can safely process the record in a different
        +		 * amount of time if it's too short to possibly contain a MAC.
        +		 */
        +		if (orig_len < mac_size ||
        +		    /* CBC records must have a padding length byte too. */
        +		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
        +		     orig_len < mac_size+1))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
        +			goto f_err;
        +			}
        +
        +		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
        +			{
        +			/* We update the length so that the TLS header bytes
        +			 * can be constructed correctly but we need to extract
        +			 * the MAC in constant time from within the record,
        +			 * without leaking the contents of the padding bytes.
        +			 * */
        +			mac = mac_tmp;
        +			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
        +			rr->length -= mac_size;
        +			}
        +		else
        +			{
        +			/* In this case there's no padding, so |orig_len|
        +			 * equals |rec->length| and we checked that there's
        +			 * enough bytes for |mac_size| above. */
        +			rr->length -= mac_size;
        +			mac = &rr->data[rr->length];
        +			}
        +
        +		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
        +		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
        +			enc_err = -1;
        +		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
        +			enc_err = -1;
        +		}
        +
        +	if (enc_err < 0)
        +		{
        +		/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
        +		 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
        +		 * failure is directly visible from the ciphertext anyway,
        +		 * we should not reveal which kind of error occured -- this
        +		 * might become visible to an attacker (e.g. via a logfile) */
        +		al=SSL_AD_BAD_RECORD_MAC;
        +		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
        +		goto f_err;
        +		}
        +
        +	/* r->length is now just compressed */
        +	if (s->expand != NULL)
        +		{
        +		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra)
        +			{
        +			al=SSL_AD_RECORD_OVERFLOW;
        +			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
        +			goto f_err;
        +			}
        +		if (!ssl3_do_uncompress(s))
        +			{
        +			al=SSL_AD_DECOMPRESSION_FAILURE;
        +			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
        +			goto f_err;
        +			}
        +		}
        +
        +	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)
        +		{
        +		al=SSL_AD_RECORD_OVERFLOW;
        +		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
        +		goto f_err;
        +		}
        +
        +	rr->off=0;
        +	/* So at this point the following is true
        +	 * ssl->s3->rrec.type 	is the type of record
        +	 * ssl->s3->rrec.length	== number of bytes in record
        +	 * ssl->s3->rrec.off	== offset to first valid byte
        +	 * ssl->s3->rrec.data	== where to take bytes from, increment
        +	 *			   after use :-).
        +	 */
        +
        +	/* we have pulled in a full packet so zero things */
        +	s->packet_length=0;
        +
        +	/* just read a 0 length packet */
        +	if (rr->length == 0) goto again;
        +
        +#if 0
        +fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
        +#endif
        +
        +	return(1);
        +
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	return(ret);
        +	}
        +
        +int ssl3_do_uncompress(SSL *ssl)
        +	{
        +#ifndef OPENSSL_NO_COMP
        +	int i;
        +	SSL3_RECORD *rr;
        +
        +	rr= &(ssl->s3->rrec);
        +	i=COMP_expand_block(ssl->expand,rr->comp,
        +		SSL3_RT_MAX_PLAIN_LENGTH,rr->data,(int)rr->length);
        +	if (i < 0)
        +		return(0);
        +	else
        +		rr->length=i;
        +	rr->data=rr->comp;
        +#endif
        +	return(1);
        +	}
        +
        +int ssl3_do_compress(SSL *ssl)
        +	{
        +#ifndef OPENSSL_NO_COMP
        +	int i;
        +	SSL3_RECORD *wr;
        +
        +	wr= &(ssl->s3->wrec);
        +	i=COMP_compress_block(ssl->compress,wr->data,
        +		SSL3_RT_MAX_COMPRESSED_LENGTH,
        +		wr->input,(int)wr->length);
        +	if (i < 0)
        +		return(0);
        +	else
        +		wr->length=i;
        +
        +	wr->input=wr->data;
        +#endif
        +	return(1);
        +	}
        +
        +/* Call this to write data in records of type 'type'
        + * It will return <= 0 if not all data has been sent or non-blocking IO.
        + */
        +int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
        +	{
        +	const unsigned char *buf=buf_;
        +	unsigned int tot,n,nw;
        +	int i;
        +
        +	s->rwstate=SSL_NOTHING;
        +	tot=s->s3->wnum;
        +	s->s3->wnum=0;
        +
        +	if (SSL_in_init(s) && !s->in_handshake)
        +		{
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return -1;
        +			}
        +		}
        +
        +	n=(len-tot);
        +	for (;;)
        +		{
        +		if (n > s->max_send_fragment)
        +			nw=s->max_send_fragment;
        +		else
        +			nw=n;
        +
        +		i=do_ssl3_write(s, type, &(buf[tot]), nw, 0);
        +		if (i <= 0)
        +			{
        +			s->s3->wnum=tot;
        +			return i;
        +			}
        +
        +		if ((i == (int)n) ||
        +			(type == SSL3_RT_APPLICATION_DATA &&
        +			 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
        +			{
        +			/* next chunk of data should get another prepended empty fragment
        +			 * in ciphersuites with known-IV weakness: */
        +			s->s3->empty_fragment_done = 0;
        +			
        +			return tot+i;
        +			}
        +
        +		n-=i;
        +		tot+=i;
        +		}
        +	}
        +
        +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        +			 unsigned int len, int create_empty_fragment)
        +	{
        +	unsigned char *p,*plen;
        +	int i,mac_size,clear=0;
        +	int prefix_len=0;
        +	int eivlen;
        +	long align=0;
        +	SSL3_RECORD *wr;
        +	SSL3_BUFFER *wb=&(s->s3->wbuf);
        +	SSL_SESSION *sess;
        +
        + 	if (wb->buf == NULL)
        +		if (!ssl3_setup_write_buffer(s))
        +			return -1;
        +
        +	/* first check if there is a SSL3_BUFFER still being written
        +	 * out.  This will happen with non blocking IO */
        +	if (wb->left != 0)
        +		return(ssl3_write_pending(s,type,buf,len));
        +
        +	/* If we have an alert to send, lets send it */
        +	if (s->s3->alert_dispatch)
        +		{
        +		i=s->method->ssl_dispatch_alert(s);
        +		if (i <= 0)
        +			return(i);
        +		/* if it went, fall through and send more stuff */
        +		}
        +
        +	if (len == 0 && !create_empty_fragment)
        +		return 0;
        +
        +	wr= &(s->s3->wrec);
        +	sess=s->session;
        +
        +	if (	(sess == NULL) ||
        +		(s->enc_write_ctx == NULL) ||
        +		(EVP_MD_CTX_md(s->write_hash) == NULL))
        +		{
        +#if 1
        +		clear=s->enc_write_ctx?0:1;	/* must be AEAD cipher */
        +#else
        +		clear=1;
        +#endif
        +		mac_size=0;
        +		}
        +	else
        +		{
        +		mac_size=EVP_MD_CTX_size(s->write_hash);
        +		if (mac_size < 0)
        +			goto err;
        +		}
        +
        +	/* 'create_empty_fragment' is true only when this function calls itself */
        +	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
        +		{
        +		/* countermeasure against known-IV weakness in CBC ciphersuites
        +		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
        +
        +		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
        +			{
        +			/* recursive function call with 'create_empty_fragment' set;
        +			 * this prepares and buffers the data for an empty fragment
        +			 * (these 'prefix_len' bytes are sent out later
        +			 * together with the actual payload) */
        +			prefix_len = do_ssl3_write(s, type, buf, 0, 1);
        +			if (prefix_len <= 0)
        +				goto err;
        +
        +			if (prefix_len >
        +		(SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
        +				{
        +				/* insufficient space */
        +				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +			}
        +		
        +		s->s3->empty_fragment_done = 1;
        +		}
        +
        +	if (create_empty_fragment)
        +		{
        +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        +		/* extra fragment would be couple of cipher blocks,
        +		 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
        +		 * if we want to align the real payload, then we can
        +		 * just pretent we simply have two headers. */
        +		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH;
        +		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
        +#endif
        +		p = wb->buf + align;
        +		wb->offset  = align;
        +		}
        +	else if (prefix_len)
        +		{
        +		p = wb->buf + wb->offset + prefix_len;
        +		}
        +	else
        +		{
        +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        +		align = (long)wb->buf + SSL3_RT_HEADER_LENGTH;
        +		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
        +#endif
        +		p = wb->buf + align;
        +		wb->offset  = align;
        +		}
        +
        +	/* write the header */
        +
        +	*(p++)=type&0xff;
        +	wr->type=type;
        +
        +	*(p++)=(s->version>>8);
        +	/* Some servers hang if iniatial client hello is larger than 256
        +	 * bytes and record version number > TLS 1.0
        +	 */
        +	if (s->state == SSL3_ST_CW_CLNT_HELLO_B
        +				&& !s->renegotiate
        +				&& TLS1_get_version(s) > TLS1_VERSION)
        +		*(p++) = 0x1;
        +	else
        +		*(p++)=s->version&0xff;
        +
        +	/* field where we are to write out packet length */
        +	plen=p; 
        +	p+=2;
        +	/* Explicit IV length, block ciphers and TLS version 1.1 or later */
        +	if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
        +		{
        +		int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
        +		if (mode == EVP_CIPH_CBC_MODE)
        +			{
        +			eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
        +			if (eivlen <= 1)
        +				eivlen = 0;
        +			}
        +		/* Need explicit part of IV for GCM mode */
        +		else if (mode == EVP_CIPH_GCM_MODE)
        +			eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +		else
        +			eivlen = 0;
        +		}
        +	else 
        +		eivlen = 0;
        +
        +	/* lets setup the record stuff. */
        +	wr->data=p + eivlen;
        +	wr->length=(int)len;
        +	wr->input=(unsigned char *)buf;
        +
        +	/* we now 'read' from wr->input, wr->length bytes into
        +	 * wr->data */
        +
        +	/* first we compress */
        +	if (s->compress != NULL)
        +		{
        +		if (!ssl3_do_compress(s))
        +			{
        +			SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE);
        +			goto err;
        +			}
        +		}
        +	else
        +		{
        +		memcpy(wr->data,wr->input,wr->length);
        +		wr->input=wr->data;
        +		}
        +
        +	/* we should still have the output to wr->data and the input
        +	 * from wr->input.  Length should be wr->length.
        +	 * wr->data still points in the wb->buf */
        +
        +	if (mac_size != 0)
        +		{
        +		if (s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0)
        +			goto err;
        +		wr->length+=mac_size;
        +		}
        +
        +	wr->input=p;
        +	wr->data=p;
        +
        +	if (eivlen)
        +		{
        +	/*	if (RAND_pseudo_bytes(p, eivlen) <= 0)
        +			goto err; */
        +		wr->length += eivlen;
        +		}
        +
        +	/* ssl3_enc can only have an error on read */
        +	s->method->ssl3_enc->enc(s,1);
        +
        +	/* record length after mac and block padding */
        +	s2n(wr->length,plen);
        +
        +	/* we should now have
        +	 * wr->data pointing to the encrypted data, which is
        +	 * wr->length long */
        +	wr->type=type; /* not needed but helps for debugging */
        +	wr->length+=SSL3_RT_HEADER_LENGTH;
        +
        +	if (create_empty_fragment)
        +		{
        +		/* we are in a recursive call;
        +		 * just return the length, don't write out anything here
        +		 */
        +		return wr->length;
        +		}
        +
        +	/* now let's set up wb */
        +	wb->left = prefix_len + wr->length;
        +
        +	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
        +	s->s3->wpend_tot=len;
        +	s->s3->wpend_buf=buf;
        +	s->s3->wpend_type=type;
        +	s->s3->wpend_ret=len;
        +
        +	/* we now just need to write the buffer */
        +	return ssl3_write_pending(s,type,buf,len);
        +err:
        +	return -1;
        +	}
        +
        +/* if s->s3->wbuf.left != 0, we need to call this */
        +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
        +	unsigned int len)
        +	{
        +	int i;
        +	SSL3_BUFFER *wb=&(s->s3->wbuf);
        +
        +/* XXXX */
        +	if ((s->s3->wpend_tot > (int)len)
        +		|| ((s->s3->wpend_buf != buf) &&
        +			!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
        +		|| (s->s3->wpend_type != type))
        +		{
        +		SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
        +		return(-1);
        +		}
        +
        +	for (;;)
        +		{
        +		clear_sys_error();
        +		if (s->wbio != NULL)
        +			{
        +			s->rwstate=SSL_WRITING;
        +			i=BIO_write(s->wbio,
        +				(char *)&(wb->buf[wb->offset]),
        +				(unsigned int)wb->left);
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET);
        +			i= -1;
        +			}
        +		if (i == wb->left)
        +			{
        +			wb->left=0;
        +			wb->offset+=i;
        +			if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
        +			    SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
        +				ssl3_release_write_buffer(s);
        +			s->rwstate=SSL_NOTHING;
        +			return(s->s3->wpend_ret);
        +			}
        +		else if (i <= 0) {
        +			if (s->version == DTLS1_VERSION ||
        +			    s->version == DTLS1_BAD_VER) {
        +				/* For DTLS, just drop it. That's kind of the whole
        +				   point in using a datagram service */
        +				wb->left = 0;
        +			}
        +			return(i);
        +		}
        +		wb->offset+=i;
        +		wb->left-=i;
        +		}
        +	}
        +
        +/* Return up to 'len' payload bytes received in 'type' records.
        + * 'type' is one of the following:
        + *
        + *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
        + *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
        + *   -  0 (during a shutdown, no data has to be returned)
        + *
        + * If we don't have stored data to work from, read a SSL/TLS record first
        + * (possibly multiple records if we still don't have anything to return).
        + *
        + * This function must handle any surprises the peer may have for us, such as
        + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
        + * a surprise, but handled as if it were), or renegotiation requests.
        + * Also if record payloads contain fragments too small to process, we store
        + * them until there is enough for the respective protocol (the record protocol
        + * may use arbitrary fragmentation and even interleaving):
        + *     Change cipher spec protocol
        + *             just 1 byte needed, no need for keeping anything stored
        + *     Alert protocol
        + *             2 bytes needed (AlertLevel, AlertDescription)
        + *     Handshake protocol
        + *             4 bytes needed (HandshakeType, uint24 length) -- we just have
        + *             to detect unexpected Client Hello and Hello Request messages
        + *             here, anything else is handled by higher layers
        + *     Application data protocol
        + *             none of our business
        + */
        +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        +	{
        +	int al,i,j,ret;
        +	unsigned int n;
        +	SSL3_RECORD *rr;
        +	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
        +
        +	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
        +		if (!ssl3_setup_read_buffer(s))
        +			return(-1);
        +
        +	if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) ||
        +	    (peek && (type != SSL3_RT_APPLICATION_DATA)))
        +		{
        +		SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
        +		return -1;
        +		}
        +
        +	if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0))
        +		/* (partially) satisfy request from storage */
        +		{
        +		unsigned char *src = s->s3->handshake_fragment;
        +		unsigned char *dst = buf;
        +		unsigned int k;
        +
        +		/* peek == 0 */
        +		n = 0;
        +		while ((len > 0) && (s->s3->handshake_fragment_len > 0))
        +			{
        +			*dst++ = *src++;
        +			len--; s->s3->handshake_fragment_len--;
        +			n++;
        +			}
        +		/* move any remaining fragment bytes: */
        +		for (k = 0; k < s->s3->handshake_fragment_len; k++)
        +			s->s3->handshake_fragment[k] = *src++;
        +		return n;
        +	}
        +
        +	/* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
        +
        +	if (!s->in_handshake && SSL_in_init(s))
        +		{
        +		/* type == SSL3_RT_APPLICATION_DATA */
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +		}
        +start:
        +	s->rwstate=SSL_NOTHING;
        +
        +	/* s->s3->rrec.type	    - is the type of record
        +	 * s->s3->rrec.data,    - data
        +	 * s->s3->rrec.off,     - offset into 'data' for next read
        +	 * s->s3->rrec.length,  - number of bytes. */
        +	rr = &(s->s3->rrec);
        +
        +	/* get new packet if necessary */
        +	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
        +		{
        +		ret=ssl3_get_record(s);
        +		if (ret <= 0) return(ret);
        +		}
        +
        +	/* we now have a packet which can be read and processed */
        +
        +	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
        +	                               * reset by ssl3_get_finished */
        +		&& (rr->type != SSL3_RT_HANDSHAKE))
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
        +		goto f_err;
        +		}
        +
        +	/* If the other end has shut down, throw anything we read away
        +	 * (even in 'peek' mode) */
        +	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
        +		{
        +		rr->length=0;
        +		s->rwstate=SSL_NOTHING;
        +		return(0);
        +		}
        +
        +
        +	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
        +		{
        +		/* make sure that we are not getting application data when we
        +		 * are doing a handshake for the first time */
        +		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
        +			(s->enc_read_ctx == NULL))
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
        +			goto f_err;
        +			}
        +
        +		if (len <= 0) return(len);
        +
        +		if ((unsigned int)len > rr->length)
        +			n = rr->length;
        +		else
        +			n = (unsigned int)len;
        +
        +		memcpy(buf,&(rr->data[rr->off]),n);
        +		if (!peek)
        +			{
        +			rr->length-=n;
        +			rr->off+=n;
        +			if (rr->length == 0)
        +				{
        +				s->rstate=SSL_ST_READ_HEADER;
        +				rr->off=0;
        +				if (s->mode & SSL_MODE_RELEASE_BUFFERS)
        +					ssl3_release_read_buffer(s);
        +				}
        +			}
        +		return(n);
        +		}
        +
        +
        +	/* If we get here, then type != rr->type; if we have a handshake
        +	 * message, then it was unexpected (Hello Request or Client Hello). */
        +
        +	/* In case of record types for which we have 'fragment' storage,
        +	 * fill that so that we can process the data at a fixed place.
        +	 */
        +		{
        +		unsigned int dest_maxlen = 0;
        +		unsigned char *dest = NULL;
        +		unsigned int *dest_len = NULL;
        +
        +		if (rr->type == SSL3_RT_HANDSHAKE)
        +			{
        +			dest_maxlen = sizeof s->s3->handshake_fragment;
        +			dest = s->s3->handshake_fragment;
        +			dest_len = &s->s3->handshake_fragment_len;
        +			}
        +		else if (rr->type == SSL3_RT_ALERT)
        +			{
        +			dest_maxlen = sizeof s->s3->alert_fragment;
        +			dest = s->s3->alert_fragment;
        +			dest_len = &s->s3->alert_fragment_len;
        +			}
        +#ifndef OPENSSL_NO_HEARTBEATS
        +		else if (rr->type == TLS1_RT_HEARTBEAT)
        +			{
        +			tls1_process_heartbeat(s);
        +
        +			/* Exit and notify application to read again */
        +			rr->length = 0;
        +			s->rwstate=SSL_READING;
        +			BIO_clear_retry_flags(SSL_get_rbio(s));
        +			BIO_set_retry_read(SSL_get_rbio(s));
        +			return(-1);
        +			}
        +#endif
        +
        +		if (dest_maxlen > 0)
        +			{
        +			n = dest_maxlen - *dest_len; /* available space in 'dest' */
        +			if (rr->length < n)
        +				n = rr->length; /* available bytes */
        +
        +			/* now move 'n' bytes: */
        +			while (n-- > 0)
        +				{
        +				dest[(*dest_len)++] = rr->data[rr->off++];
        +				rr->length--;
        +				}
        +
        +			if (*dest_len < dest_maxlen)
        +				goto start; /* fragment was too small */
        +			}
        +		}
        +
        +	/* s->s3->handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
        +	 * s->s3->alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.
        +	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
        +
        +	/* If we are a client, check for an incoming 'Hello Request': */
        +	if ((!s->server) &&
        +		(s->s3->handshake_fragment_len >= 4) &&
        +		(s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
        +		(s->session != NULL) && (s->session->cipher != NULL))
        +		{
        +		s->s3->handshake_fragment_len = 0;
        +
        +		if ((s->s3->handshake_fragment[1] != 0) ||
        +			(s->s3->handshake_fragment[2] != 0) ||
        +			(s->s3->handshake_fragment[3] != 0))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
        +			goto f_err;
        +			}
        +
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
        +
        +		if (SSL_is_init_finished(s) &&
        +			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
        +			!s->s3->renegotiate)
        +			{
        +			ssl3_renegotiate(s);
        +			if (ssl3_renegotiate_check(s))
        +				{
        +				i=s->handshake_func(s);
        +				if (i < 0) return(i);
        +				if (i == 0)
        +					{
        +					SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +					return(-1);
        +					}
        +
        +				if (!(s->mode & SSL_MODE_AUTO_RETRY))
        +					{
        +					if (s->s3->rbuf.left == 0) /* no read-ahead left? */
        +						{
        +						BIO *bio;
        +						/* In the case where we try to read application data,
        +						 * but we trigger an SSL handshake, we return -1 with
        +						 * the retry option set.  Otherwise renegotiation may
        +						 * cause nasty problems in the blocking world */
        +						s->rwstate=SSL_READING;
        +						bio=SSL_get_rbio(s);
        +						BIO_clear_retry_flags(bio);
        +						BIO_set_retry_read(bio);
        +						return(-1);
        +						}
        +					}
        +				}
        +			}
        +		/* we either finished a handshake or ignored the request,
        +		 * now try again to obtain the (application) data we were asked for */
        +		goto start;
        +		}
        +	/* If we are a server and get a client hello when renegotiation isn't
        +	 * allowed send back a no renegotiation alert and carry on.
        +	 * WARNING: experimental code, needs reviewing (steve)
        +	 */
        +	if (s->server &&
        +		SSL_is_init_finished(s) &&
        +    		!s->s3->send_connection_binding &&
        +		(s->version > SSL3_VERSION) &&
        +		(s->s3->handshake_fragment_len >= 4) &&
        +		(s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
        +		(s->session != NULL) && (s->session->cipher != NULL) &&
        +		!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
        +		
        +		{
        +		/*s->s3->handshake_fragment_len = 0;*/
        +		rr->length = 0;
        +		ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
        +		goto start;
        +		}
        +	if (s->s3->alert_fragment_len >= 2)
        +		{
        +		int alert_level = s->s3->alert_fragment[0];
        +		int alert_descr = s->s3->alert_fragment[1];
        +
        +		s->s3->alert_fragment_len = 0;
        +
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, SSL3_RT_ALERT, s->s3->alert_fragment, 2, s, s->msg_callback_arg);
        +
        +		if (s->info_callback != NULL)
        +			cb=s->info_callback;
        +		else if (s->ctx->info_callback != NULL)
        +			cb=s->ctx->info_callback;
        +
        +		if (cb != NULL)
        +			{
        +			j = (alert_level << 8) | alert_descr;
        +			cb(s, SSL_CB_READ_ALERT, j);
        +			}
        +
        +		if (alert_level == 1) /* warning */
        +			{
        +			s->s3->warn_alert = alert_descr;
        +			if (alert_descr == SSL_AD_CLOSE_NOTIFY)
        +				{
        +				s->shutdown |= SSL_RECEIVED_SHUTDOWN;
        +				return(0);
        +				}
        +			/* This is a warning but we receive it if we requested
        +			 * renegotiation and the peer denied it. Terminate with
        +			 * a fatal alert because if application tried to
        +			 * renegotiatie it presumably had a good reason and
        +			 * expects it to succeed.
        +			 *
        +			 * In future we might have a renegotiation where we
        +			 * don't care if the peer refused it where we carry on.
        +			 */
        +			else if (alert_descr == SSL_AD_NO_RENEGOTIATION)
        +				{
        +				al = SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
        +				goto f_err;
        +				}
        +#ifdef SSL_AD_MISSING_SRP_USERNAME
        +			else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
        +				return(0);
        +#endif
        +			}
        +		else if (alert_level == 2) /* fatal */
        +			{
        +			char tmp[16];
        +
        +			s->rwstate=SSL_NOTHING;
        +			s->s3->fatal_alert = alert_descr;
        +			SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
        +			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
        +			ERR_add_error_data(2,"SSL alert number ",tmp);
        +			s->shutdown|=SSL_RECEIVED_SHUTDOWN;
        +			SSL_CTX_remove_session(s->ctx,s->session);
        +			return(0);
        +			}
        +		else
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
        +			goto f_err;
        +			}
        +
        +		goto start;
        +		}
        +
        +	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
        +		{
        +		s->rwstate=SSL_NOTHING;
        +		rr->length=0;
        +		return(0);
        +		}
        +
        +	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
        +		{
        +		/* 'Change Cipher Spec' is just a single byte, so we know
        +		 * exactly what the record payload has to look like */
        +		if (	(rr->length != 1) || (rr->off != 0) ||
        +			(rr->data[0] != SSL3_MT_CCS))
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
        +			goto f_err;
        +			}
        +
        +		/* Check we have a cipher to change to */
        +		if (s->s3->tmp.new_cipher == NULL)
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
        +			goto f_err;
        +			}
        +
        +		rr->length=0;
        +
        +		if (s->msg_callback)
        +			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg);
        +
        +		s->s3->change_cipher_spec=1;
        +		if (!ssl3_do_change_cipher_spec(s))
        +			goto err;
        +		else
        +			goto start;
        +		}
        +
        +	/* Unexpected handshake message (Client Hello, or protocol violation) */
        +	if ((s->s3->handshake_fragment_len >= 4) &&	!s->in_handshake)
        +		{
        +		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
        +			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
        +			{
        +#if 0 /* worked only because C operator preferences are not as expected (and
        +       * because this is not really needed for clients except for detecting
        +       * protocol violations): */
        +			s->state=SSL_ST_BEFORE|(s->server)
        +				?SSL_ST_ACCEPT
        +				:SSL_ST_CONNECT;
        +#else
        +			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
        +#endif
        +			s->renegotiate=1;
        +			s->new_session=1;
        +			}
        +		i=s->handshake_func(s);
        +		if (i < 0) return(i);
        +		if (i == 0)
        +			{
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
        +			return(-1);
        +			}
        +
        +		if (!(s->mode & SSL_MODE_AUTO_RETRY))
        +			{
        +			if (s->s3->rbuf.left == 0) /* no read-ahead left? */
        +				{
        +				BIO *bio;
        +				/* In the case where we try to read application data,
        +				 * but we trigger an SSL handshake, we return -1 with
        +				 * the retry option set.  Otherwise renegotiation may
        +				 * cause nasty problems in the blocking world */
        +				s->rwstate=SSL_READING;
        +				bio=SSL_get_rbio(s);
        +				BIO_clear_retry_flags(bio);
        +				BIO_set_retry_read(bio);
        +				return(-1);
        +				}
        +			}
        +		goto start;
        +		}
        +
        +	switch (rr->type)
        +		{
        +	default:
        +#ifndef OPENSSL_NO_TLS
        +		/* TLS up to v1.1 just ignores unknown message types:
        +		 * TLS v1.2 give an unexpected message alert.
        +		 */
        +		if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION)
        +			{
        +			rr->length = 0;
        +			goto start;
        +			}
        +#endif
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
        +		goto f_err;
        +	case SSL3_RT_CHANGE_CIPHER_SPEC:
        +	case SSL3_RT_ALERT:
        +	case SSL3_RT_HANDSHAKE:
        +		/* we already handled all of these, with the possible exception
        +		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
        +		 * should not happen when type != rr->type */
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_READ_BYTES,ERR_R_INTERNAL_ERROR);
        +		goto f_err;
        +	case SSL3_RT_APPLICATION_DATA:
        +		/* At this point, we were expecting handshake data,
        +		 * but have application data.  If the library was
        +		 * running inside ssl3_read() (i.e. in_read_app_data
        +		 * is set) and it makes sense to read application data
        +		 * at this point (session renegotiation not yet started),
        +		 * we will indulge it.
        +		 */
        +		if (s->s3->in_read_app_data &&
        +			(s->s3->total_renegotiations != 0) &&
        +			((
        +				(s->state & SSL_ST_CONNECT) &&
        +				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
        +				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)
        +				) || (
        +					(s->state & SSL_ST_ACCEPT) &&
        +					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
        +					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)
        +					)
        +				))
        +			{
        +			s->s3->in_read_app_data=2;
        +			return(-1);
        +			}
        +		else
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
        +			goto f_err;
        +			}
        +		}
        +	/* not reached */
        +
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +	return(-1);
        +	}
        +
        +int ssl3_do_change_cipher_spec(SSL *s)
        +	{
        +	int i;
        +	const char *sender;
        +	int slen;
        +
        +	if (s->state & SSL_ST_ACCEPT)
        +		i=SSL3_CHANGE_CIPHER_SERVER_READ;
        +	else
        +		i=SSL3_CHANGE_CIPHER_CLIENT_READ;
        +
        +	if (s->s3->tmp.key_block == NULL)
        +		{
        +		if (s->session == NULL) 
        +			{
        +			/* might happen if dtls1_read_bytes() calls this */
        +			SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
        +			return (0);
        +			}
        +
        +		s->session->cipher=s->s3->tmp.new_cipher;
        +		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
        +		}
        +
        +	if (!s->method->ssl3_enc->change_cipher_state(s,i))
        +		return(0);
        +
        +	/* we have to record the message digest at
        +	 * this point so we can get it before we read
        +	 * the finished message */
        +	if (s->state & SSL_ST_CONNECT)
        +		{
        +		sender=s->method->ssl3_enc->server_finished_label;
        +		slen=s->method->ssl3_enc->server_finished_label_len;
        +		}
        +	else
        +		{
        +		sender=s->method->ssl3_enc->client_finished_label;
        +		slen=s->method->ssl3_enc->client_finished_label_len;
        +		}
        +
        +	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
        +		sender,slen,s->s3->tmp.peer_finish_md);
        +
        +	return(1);
        +	}
        +
        +int ssl3_send_alert(SSL *s, int level, int desc)
        +	{
        +	/* Map tls/ssl alert value to correct one */
        +	desc=s->method->ssl3_enc->alert_value(desc);
        +	if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
        +		desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */
        +	if (desc < 0) return -1;
        +	/* If a fatal one, remove from cache */
        +	if ((level == 2) && (s->session != NULL))
        +		SSL_CTX_remove_session(s->ctx,s->session);
        +
        +	s->s3->alert_dispatch=1;
        +	s->s3->send_alert[0]=level;
        +	s->s3->send_alert[1]=desc;
        +	if (s->s3->wbuf.left == 0) /* data still being written out? */
        +		return s->method->ssl_dispatch_alert(s);
        +	/* else data is still being written out, we will get written
        +	 * some time in the future */
        +	return -1;
        +	}
        +
        +int ssl3_dispatch_alert(SSL *s)
        +	{
        +	int i,j;
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +
        +	s->s3->alert_dispatch=0;
        +	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);
        +	if (i <= 0)
        +		{
        +		s->s3->alert_dispatch=1;
        +		}
        +	else
        +		{
        +		/* Alert sent to BIO.  If it is important, flush it now.
        +		 * If the message does not get sent due to non-blocking IO,
        +		 * we will not worry too much. */
        +		if (s->s3->send_alert[0] == SSL3_AL_FATAL)
        +			(void)BIO_flush(s->wbio);
        +
        +		if (s->msg_callback)
        +			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, s->msg_callback_arg);
        +
        +		if (s->info_callback != NULL)
        +			cb=s->info_callback;
        +		else if (s->ctx->info_callback != NULL)
        +			cb=s->ctx->info_callback;
        +
        +		if (cb != NULL)
        +			{
        +			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
        +			cb(s,SSL_CB_WRITE_ALERT,j);
        +			}
        +		}
        +	return(i);
        +	}
        diff --git a/vendor/openssl/openssl/ssl/s3_srvr.c b/vendor/openssl/openssl/ssl/s3_srvr.c
        new file mode 100644
        index 000000000..bfb848054
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/s3_srvr.c
        @@ -0,0 +1,3601 @@
        +/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */
        +/* 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-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * ECC cipher suite support in OpenSSL originally written by
        + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#define REUSE_CIPHER_BUG
        +#define NETSCAPE_HANG_BUG
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include "kssl_lcl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/hmac.h>
        +#include <openssl/x509.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +#ifndef OPENSSL_NO_KRB5
        +#include <openssl/krb5_asn.h>
        +#endif
        +#include <openssl/md5.h>
        +
        +static const SSL_METHOD *ssl3_get_server_method(int ver);
        +
        +static const SSL_METHOD *ssl3_get_server_method(int ver)
        +	{
        +	if (ver == SSL3_VERSION)
        +		return(SSLv3_server_method());
        +	else
        +		return(NULL);
        +	}
        +
        +#ifndef OPENSSL_NO_SRP
        +static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
        +	{
        +	int ret = SSL_ERROR_NONE;
        +
        +	*al = SSL_AD_UNRECOGNIZED_NAME;
        +
        +	if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
        +	    (s->srp_ctx.TLS_ext_srp_username_callback != NULL))
        +		{
        +		if(s->srp_ctx.login == NULL)
        +			{
        +			/* RFC 5054 says SHOULD reject, 
        +			   we do so if There is no srp login name */
        +			ret = SSL3_AL_FATAL;
        +			*al = SSL_AD_UNKNOWN_PSK_IDENTITY;
        +			}
        +		else
        +			{
        +			ret = SSL_srp_server_param_with_username(s,al);
        +			}
        +		}
        +	return ret;
        +	}
        +#endif
        +
        +IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
        +			ssl3_accept,
        +			ssl_undefined_function,
        +			ssl3_get_server_method)
        +
        +int ssl3_accept(SSL *s)
        +	{
        +	BUF_MEM *buf;
        +	unsigned long alg_k,Time=(unsigned long)time(NULL);
        +	void (*cb)(const SSL *ssl,int type,int val)=NULL;
        +	int ret= -1;
        +	int new_state,state,skip=0;
        +
        +	RAND_add(&Time,sizeof(Time),0);
        +	ERR_clear_error();
        +	clear_sys_error();
        +
        +	if (s->info_callback != NULL)
        +		cb=s->info_callback;
        +	else if (s->ctx->info_callback != NULL)
        +		cb=s->ctx->info_callback;
        +
        +	/* init things to blank */
        +	s->in_handshake++;
        +	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
        +
        +	if (s->cert == NULL)
        +		{
        +		SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
        +		return(-1);
        +		}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	/* If we're awaiting a HeartbeatResponse, pretend we
        +	 * already got and don't await it anymore, because
        +	 * Heartbeats don't make sense during handshakes anyway.
        +	 */
        +	if (s->tlsext_hb_pending)
        +		{
        +		s->tlsext_hb_pending = 0;
        +		s->tlsext_hb_seq++;
        +		}
        +#endif
        +
        +	for (;;)
        +		{
        +		state=s->state;
        +
        +		switch (s->state)
        +			{
        +		case SSL_ST_RENEGOTIATE:
        +			s->renegotiate=1;
        +			/* s->state=SSL_ST_ACCEPT; */
        +
        +		case SSL_ST_BEFORE:
        +		case SSL_ST_ACCEPT:
        +		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
        +		case SSL_ST_OK|SSL_ST_ACCEPT:
        +
        +			s->server=1;
        +			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
        +
        +			if ((s->version>>8) != 3)
        +				{
        +				SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
        +				return -1;
        +				}
        +			s->type=SSL_ST_ACCEPT;
        +
        +			if (s->init_buf == NULL)
        +				{
        +				if ((buf=BUF_MEM_new()) == NULL)
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
        +					{
        +					ret= -1;
        +					goto end;
        +					}
        +				s->init_buf=buf;
        +				}
        +
        +			if (!ssl3_setup_buffers(s))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			s->init_num=0;
        +			s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
        +
        +			if (s->state != SSL_ST_RENEGOTIATE)
        +				{
        +				/* Ok, we now need to push on a buffering BIO so that
        +				 * the output is sent in a way that TCP likes :-)
        +				 */
        +				if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
        +				
        +				ssl3_init_finished_mac(s);
        +				s->state=SSL3_ST_SR_CLNT_HELLO_A;
        +				s->ctx->stats.sess_accept++;
        +				}
        +			else if (!s->s3->send_connection_binding &&
        +				!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
        +				{
        +				/* Server attempting to renegotiate with
        +				 * client that doesn't support secure
        +				 * renegotiation.
        +				 */
        +				SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
        +				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
        +				ret = -1;
        +				goto end;
        +				}
        +			else
        +				{
        +				/* s->state == SSL_ST_RENEGOTIATE,
        +				 * we will just send a HelloRequest */
        +				s->ctx->stats.sess_accept_renegotiate++;
        +				s->state=SSL3_ST_SW_HELLO_REQ_A;
        +				}
        +			break;
        +
        +		case SSL3_ST_SW_HELLO_REQ_A:
        +		case SSL3_ST_SW_HELLO_REQ_B:
        +
        +			s->shutdown=0;
        +			ret=ssl3_send_hello_request(s);
        +			if (ret <= 0) goto end;
        +			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			s->init_num=0;
        +
        +			ssl3_init_finished_mac(s);
        +			break;
        +
        +		case SSL3_ST_SW_HELLO_REQ_C:
        +			s->state=SSL_ST_OK;
        +			break;
        +
        +		case SSL3_ST_SR_CLNT_HELLO_A:
        +		case SSL3_ST_SR_CLNT_HELLO_B:
        +		case SSL3_ST_SR_CLNT_HELLO_C:
        +
        +			s->shutdown=0;
        +			if (s->rwstate != SSL_X509_LOOKUP)
        +			{
        +				ret=ssl3_get_client_hello(s);
        +				if (ret <= 0) goto end;
        +			}
        +#ifndef OPENSSL_NO_SRP
        +			{
        +			int al;
        +			if ((ret = ssl_check_srp_ext_ClientHello(s,&al))  < 0)
        +					{
        +					/* callback indicates firther work to be done */
        +					s->rwstate=SSL_X509_LOOKUP;
        +					goto end;
        +					}
        +			if (ret != SSL_ERROR_NONE)
        +				{
        +				ssl3_send_alert(s,SSL3_AL_FATAL,al);	
        +				/* This is not really an error but the only means to
        +                                   for a client to detect whether srp is supported. */
        + 				   if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY) 	
        +					SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);			
        +				ret = SSL_TLSEXT_ERR_ALERT_FATAL;			
        +				ret= -1;
        +				goto end;	
        +				}
        +			}
        +#endif		
        +			
        +			s->renegotiate = 2;
        +			s->state=SSL3_ST_SW_SRVR_HELLO_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_SRVR_HELLO_A:
        +		case SSL3_ST_SW_SRVR_HELLO_B:
        +			ret=ssl3_send_server_hello(s);
        +			if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_TLSEXT
        +			if (s->hit)
        +				{
        +				if (s->tlsext_ticket_expected)
        +					s->state=SSL3_ST_SW_SESSION_TICKET_A;
        +				else
        +					s->state=SSL3_ST_SW_CHANGE_A;
        +				}
        +#else
        +			if (s->hit)
        +					s->state=SSL3_ST_SW_CHANGE_A;
        +#endif
        +			else
        +				s->state=SSL3_ST_SW_CERT_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_CERT_A:
        +		case SSL3_ST_SW_CERT_B:
        +			/* Check if it is anon DH or anon ECDH, */
        +			/* normal PSK or KRB5 or SRP */
        +			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
        +				&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
        +				&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
        +				{
        +				ret=ssl3_send_server_certificate(s);
        +				if (ret <= 0) goto end;
        +#ifndef OPENSSL_NO_TLSEXT
        +				if (s->tlsext_status_expected)
        +					s->state=SSL3_ST_SW_CERT_STATUS_A;
        +				else
        +					s->state=SSL3_ST_SW_KEY_EXCH_A;
        +				}
        +			else
        +				{
        +				skip = 1;
        +				s->state=SSL3_ST_SW_KEY_EXCH_A;
        +				}
        +#else
        +				}
        +			else
        +				skip=1;
        +
        +			s->state=SSL3_ST_SW_KEY_EXCH_A;
        +#endif
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_KEY_EXCH_A:
        +		case SSL3_ST_SW_KEY_EXCH_B:
        +			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
        +
        +			/* clear this, it may get reset by
        +			 * send_server_key_exchange */
        +			if ((s->options & SSL_OP_EPHEMERAL_RSA)
        +#ifndef OPENSSL_NO_KRB5
        +				&& !(alg_k & SSL_kKRB5)
        +#endif /* OPENSSL_NO_KRB5 */
        +				)
        +				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
        +				 * even when forbidden by protocol specs
        +				 * (handshake may fail as clients are not required to
        +				 * be able to handle this) */
        +				s->s3->tmp.use_rsa_tmp=1;
        +			else
        +				s->s3->tmp.use_rsa_tmp=0;
        +
        +
        +			/* only send if a DH key exchange, fortezza or
        +			 * RSA but we have a sign only certificate
        +			 *
        +			 * PSK: may send PSK identity hints
        +			 *
        +			 * For ECC ciphersuites, we send a serverKeyExchange
        +			 * message only if the cipher suite is either
        +			 * ECDH-anon or ECDHE. In other cases, the
        +			 * server certificate contains the server's
        +			 * public key for key exchange.
        +			 */
        +			if (s->s3->tmp.use_rsa_tmp
        +			/* PSK: send ServerKeyExchange if PSK identity
        +			 * hint if provided */
        +#ifndef OPENSSL_NO_PSK
        +			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +			    /* SRP: send ServerKeyExchange */
        +			    || (alg_k & SSL_kSRP)
        +#endif
        +			    || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
        +			    || (alg_k & SSL_kEECDH)
        +			    || ((alg_k & SSL_kRSA)
        +				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
        +				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
        +					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
        +					)
        +				    )
        +				)
        +			    )
        +				{
        +				ret=ssl3_send_server_key_exchange(s);
        +				if (ret <= 0) goto end;
        +				}
        +			else
        +				skip=1;
        +
        +			s->state=SSL3_ST_SW_CERT_REQ_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_CERT_REQ_A:
        +		case SSL3_ST_SW_CERT_REQ_B:
        +			if (/* don't request cert unless asked for it: */
        +				!(s->verify_mode & SSL_VERIFY_PEER) ||
        +				/* if SSL_VERIFY_CLIENT_ONCE is set,
        +				 * don't request cert during re-negotiation: */
        +				((s->session->peer != NULL) &&
        +				 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
        +				/* never request cert in anonymous ciphersuites
        +				 * (see section "Certificate request" in SSL 3 drafts
        +				 * and in RFC 2246): */
        +				((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
        +				 /* ... except when the application insists on verification
        +				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
        +				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
        +				 /* never request cert in Kerberos ciphersuites */
        +				(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
        +				/* With normal PSK Certificates and
        +				 * Certificate Requests are omitted */
        +				|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +				{
        +				/* no cert request */
        +				skip=1;
        +				s->s3->tmp.cert_request=0;
        +				s->state=SSL3_ST_SW_SRVR_DONE_A;
        +				if (s->s3->handshake_buffer)
        +					if (!ssl3_digest_cached_records(s))
        +						return -1;
        +				}
        +			else
        +				{
        +				s->s3->tmp.cert_request=1;
        +				ret=ssl3_send_certificate_request(s);
        +				if (ret <= 0) goto end;
        +#ifndef NETSCAPE_HANG_BUG
        +				s->state=SSL3_ST_SW_SRVR_DONE_A;
        +#else
        +				s->state=SSL3_ST_SW_FLUSH;
        +				s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
        +#endif
        +				s->init_num=0;
        +				}
        +			break;
        +
        +		case SSL3_ST_SW_SRVR_DONE_A:
        +		case SSL3_ST_SW_SRVR_DONE_B:
        +			ret=ssl3_send_server_done(s);
        +			if (ret <= 0) goto end;
        +			s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			s->init_num=0;
        +			break;
        +		
        +		case SSL3_ST_SW_FLUSH:
        +
        +			/* This code originally checked to see if
        +			 * any data was pending using BIO_CTRL_INFO
        +			 * and then flushed. This caused problems
        +			 * as documented in PR#1939. The proposed
        +			 * fix doesn't completely resolve this issue
        +			 * as buggy implementations of BIO_CTRL_PENDING
        +			 * still exist. So instead we just flush
        +			 * unconditionally.
        +			 */
        +
        +			s->rwstate=SSL_WRITING;
        +			if (BIO_flush(s->wbio) <= 0)
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +			s->rwstate=SSL_NOTHING;
        +
        +			s->state=s->s3->tmp.next_state;
        +			break;
        +
        +		case SSL3_ST_SR_CERT_A:
        +		case SSL3_ST_SR_CERT_B:
        +			/* Check for second client hello (MS SGC) */
        +			ret = ssl3_check_client_hello(s);
        +			if (ret <= 0)
        +				goto end;
        +			if (ret == 2)
        +				s->state = SSL3_ST_SR_CLNT_HELLO_C;
        +			else {
        +				if (s->s3->tmp.cert_request)
        +					{
        +					ret=ssl3_get_client_certificate(s);
        +					if (ret <= 0) goto end;
        +					}
        +				s->init_num=0;
        +				s->state=SSL3_ST_SR_KEY_EXCH_A;
        +			}
        +			break;
        +
        +		case SSL3_ST_SR_KEY_EXCH_A:
        +		case SSL3_ST_SR_KEY_EXCH_B:
        +			ret=ssl3_get_client_key_exchange(s);
        +			if (ret <= 0)
        +				goto end;
        +			if (ret == 2)
        +				{
        +				/* For the ECDH ciphersuites when
        +				 * the client sends its ECDH pub key in
        +				 * a certificate, the CertificateVerify
        +				 * message is not sent.
        +				 * Also for GOST ciphersuites when
        +				 * the client uses its key from the certificate
        +				 * for key exchange.
        +				 */
        +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
        +				s->state=SSL3_ST_SR_FINISHED_A;
        +#else
        +				if (s->s3->next_proto_neg_seen)
        +					s->state=SSL3_ST_SR_NEXT_PROTO_A;
        +				else
        +					s->state=SSL3_ST_SR_FINISHED_A;
        +#endif
        +				s->init_num = 0;
        +				}
        +			else if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +				{
        +				s->state=SSL3_ST_SR_CERT_VRFY_A;
        +				s->init_num=0;
        +				if (!s->session->peer)
        +					break;
        +				/* For TLS v1.2 freeze the handshake buffer
        +				 * at this point and digest cached records.
        +				 */
        +				if (!s->s3->handshake_buffer)
        +					{
        +					SSLerr(SSL_F_SSL3_ACCEPT,ERR_R_INTERNAL_ERROR);
        +					return -1;
        +					}
        +				s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
        +				if (!ssl3_digest_cached_records(s))
        +					return -1;
        +				}
        +			else
        +				{
        +				int offset=0;
        +				int dgst_num;
        +
        +				s->state=SSL3_ST_SR_CERT_VRFY_A;
        +				s->init_num=0;
        +
        +				/* We need to get hashes here so if there is
        +				 * a client cert, it can be verified
        +				 * FIXME - digest processing for CertificateVerify
        +				 * should be generalized. But it is next step
        +				 */
        +				if (s->s3->handshake_buffer)
        +					if (!ssl3_digest_cached_records(s))
        +						return -1;
        +				for (dgst_num=0; dgst_num<SSL_MAX_DIGEST;dgst_num++)	
        +					if (s->s3->handshake_dgst[dgst_num]) 
        +						{
        +						int dgst_size;
        +
        +						s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset]));
        +						dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
        +						if (dgst_size < 0)
        +							{
        +							ret = -1;
        +							goto end;
        +							}
        +						offset+=dgst_size;
        +						}		
        +				}
        +			break;
        +
        +		case SSL3_ST_SR_CERT_VRFY_A:
        +		case SSL3_ST_SR_CERT_VRFY_B:
        +
        +			/* we should decide if we expected this one */
        +			ret=ssl3_get_cert_verify(s);
        +			if (ret <= 0) goto end;
        +
        +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
        +			s->state=SSL3_ST_SR_FINISHED_A;
        +#else
        +			if (s->s3->next_proto_neg_seen)
        +				s->state=SSL3_ST_SR_NEXT_PROTO_A;
        +			else
        +				s->state=SSL3_ST_SR_FINISHED_A;
        +#endif
        +			s->init_num=0;
        +			break;
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +		case SSL3_ST_SR_NEXT_PROTO_A:
        +		case SSL3_ST_SR_NEXT_PROTO_B:
        +			ret=ssl3_get_next_proto(s);
        +			if (ret <= 0) goto end;
        +			s->init_num = 0;
        +			s->state=SSL3_ST_SR_FINISHED_A;
        +			break;
        +#endif
        +
        +		case SSL3_ST_SR_FINISHED_A:
        +		case SSL3_ST_SR_FINISHED_B:
        +			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
        +				SSL3_ST_SR_FINISHED_B);
        +			if (ret <= 0) goto end;
        +			if (s->hit)
        +				s->state=SSL_ST_OK;
        +#ifndef OPENSSL_NO_TLSEXT
        +			else if (s->tlsext_ticket_expected)
        +				s->state=SSL3_ST_SW_SESSION_TICKET_A;
        +#endif
        +			else
        +				s->state=SSL3_ST_SW_CHANGE_A;
        +			s->init_num=0;
        +			break;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +		case SSL3_ST_SW_SESSION_TICKET_A:
        +		case SSL3_ST_SW_SESSION_TICKET_B:
        +			ret=ssl3_send_newsession_ticket(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_CHANGE_A;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL3_ST_SW_CERT_STATUS_A:
        +		case SSL3_ST_SW_CERT_STATUS_B:
        +			ret=ssl3_send_cert_status(s);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_KEY_EXCH_A;
        +			s->init_num=0;
        +			break;
        +
        +#endif
        +
        +		case SSL3_ST_SW_CHANGE_A:
        +		case SSL3_ST_SW_CHANGE_B:
        +
        +			s->session->cipher=s->s3->tmp.new_cipher;
        +			if (!s->method->ssl3_enc->setup_key_block(s))
        +				{ ret= -1; goto end; }
        +
        +			ret=ssl3_send_change_cipher_spec(s,
        +				SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
        +
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_FINISHED_A;
        +			s->init_num=0;
        +
        +			if (!s->method->ssl3_enc->change_cipher_state(s,
        +				SSL3_CHANGE_CIPHER_SERVER_WRITE))
        +				{
        +				ret= -1;
        +				goto end;
        +				}
        +
        +			break;
        +
        +		case SSL3_ST_SW_FINISHED_A:
        +		case SSL3_ST_SW_FINISHED_B:
        +			ret=ssl3_send_finished(s,
        +				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
        +				s->method->ssl3_enc->server_finished_label,
        +				s->method->ssl3_enc->server_finished_label_len);
        +			if (ret <= 0) goto end;
        +			s->state=SSL3_ST_SW_FLUSH;
        +			if (s->hit)
        +				{
        +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
        +				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
        +#else
        +				if (s->s3->next_proto_neg_seen)
        +					s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
        +				else
        +					s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
        +#endif
        +				}
        +			else
        +				s->s3->tmp.next_state=SSL_ST_OK;
        +			s->init_num=0;
        +			break;
        +
        +		case SSL_ST_OK:
        +			/* clean a few things up */
        +			ssl3_cleanup_key_block(s);
        +
        +			BUF_MEM_free(s->init_buf);
        +			s->init_buf=NULL;
        +
        +			/* remove buffering on output */
        +			ssl_free_wbio_buffer(s);
        +
        +			s->init_num=0;
        +
        +			if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */
        +				{
        +				s->renegotiate=0;
        +				s->new_session=0;
        +				
        +				ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
        +				
        +				s->ctx->stats.sess_accept_good++;
        +				/* s->server=1; */
        +				s->handshake_func=ssl3_accept;
        +
        +				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
        +				}
        +			
        +			ret = 1;
        +			goto end;
        +			/* break; */
        +
        +		default:
        +			SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_UNKNOWN_STATE);
        +			ret= -1;
        +			goto end;
        +			/* break; */
        +			}
        +		
        +		if (!s->s3->tmp.reuse_message && !skip)
        +			{
        +			if (s->debug)
        +				{
        +				if ((ret=BIO_flush(s->wbio)) <= 0)
        +					goto end;
        +				}
        +
        +
        +			if ((cb != NULL) && (s->state != state))
        +				{
        +				new_state=s->state;
        +				s->state=state;
        +				cb(s,SSL_CB_ACCEPT_LOOP,1);
        +				s->state=new_state;
        +				}
        +			}
        +		skip=0;
        +		}
        +end:
        +	/* BIO_flush(s->wbio); */
        +
        +	s->in_handshake--;
        +	if (cb != NULL)
        +		cb(s,SSL_CB_ACCEPT_EXIT,ret);
        +	return(ret);
        +	}
        +
        +int ssl3_send_hello_request(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL3_ST_SW_HELLO_REQ_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +		*(p++)=SSL3_MT_HELLO_REQUEST;
        +		*(p++)=0;
        +		*(p++)=0;
        +		*(p++)=0;
        +
        +		s->state=SSL3_ST_SW_HELLO_REQ_B;
        +		/* number of bytes to write */
        +		s->init_num=4;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_SW_HELLO_REQ_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int ssl3_check_client_hello(SSL *s)
        +	{
        +	int ok;
        +	long n;
        +
        +	/* this function is called when we really expect a Certificate message,
        +	 * so permit appropriate message length */
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_SR_CERT_A,
        +		SSL3_ST_SR_CERT_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +	if (!ok) return((int)n);
        +	s->s3->tmp.reuse_message = 1;
        +	if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
        +		{
        +		/* We only allow the client to restart the handshake once per
        +		 * negotiation. */
        +		if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
        +			{
        +			SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
        +			return -1;
        +			}
        +		/* Throw away what we have done so far in the current handshake,
        +		 * which will now be aborted. (A full SSL_clear would be too much.) */
        +#ifndef OPENSSL_NO_DH
        +		if (s->s3->tmp.dh != NULL)
        +			{
        +			DH_free(s->s3->tmp.dh);
        +			s->s3->tmp.dh = NULL;
        +			}
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +		if (s->s3->tmp.ecdh != NULL)
        +			{
        +			EC_KEY_free(s->s3->tmp.ecdh);
        +			s->s3->tmp.ecdh = NULL;
        +			}
        +#endif
        +		s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
        +		return 2;
        +		}
        +	return 1;
        +}
        +
        +int ssl3_get_client_hello(SSL *s)
        +	{
        +	int i,j,ok,al,ret= -1;
        +	unsigned int cookie_len;
        +	long n;
        +	unsigned long id;
        +	unsigned char *p,*d,*q;
        +	SSL_CIPHER *c;
        +#ifndef OPENSSL_NO_COMP
        +	SSL_COMP *comp=NULL;
        +#endif
        +	STACK_OF(SSL_CIPHER) *ciphers=NULL;
        +
        +	/* We do this so that we will respond with our native type.
        +	 * If we are TLSv1 and we get SSLv3, we will respond with TLSv1,
        +	 * This down switching should be handled by a different method.
        +	 * If we are SSLv3, we will respond with SSLv3, even if prompted with
        +	 * TLSv1.
        +	 */
        +	if (s->state == SSL3_ST_SR_CLNT_HELLO_A
        +		)
        +		{
        +		s->state=SSL3_ST_SR_CLNT_HELLO_B;
        +		}
        +	s->first_packet=1;
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_SR_CLNT_HELLO_B,
        +		SSL3_ST_SR_CLNT_HELLO_C,
        +		SSL3_MT_CLIENT_HELLO,
        +		SSL3_RT_MAX_PLAIN_LENGTH,
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +	s->first_packet=0;
        +	d=p=(unsigned char *)s->init_msg;
        +
        +	/* use version from inside client hello, not from record header
        +	 * (may differ: see RFC 2246, Appendix E, second paragraph) */
        +	s->client_version=(((int)p[0])<<8)|(int)p[1];
        +	p+=2;
        +
        +	if ((s->version == DTLS1_VERSION && s->client_version > s->version) ||
        +	    (s->version != DTLS1_VERSION && s->client_version < s->version))
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
        +		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
        +			{
        +			/* similar to ssl3_get_record, send alert using remote version number */
        +			s->version = s->client_version;
        +			}
        +		al = SSL_AD_PROTOCOL_VERSION;
        +		goto f_err;
        +		}
        +
        +	/* If we require cookies and this ClientHello doesn't
        +	 * contain one, just return since we do not want to
        +	 * allocate any memory yet. So check cookie length...
        +	 */
        +	if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)
        +		{
        +		unsigned int session_length, cookie_length;
        +		
        +		session_length = *(p + SSL3_RANDOM_SIZE);
        +		cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
        +
        +		if (cookie_length == 0)
        +			return 1;
        +		}
        +
        +	/* load the client random */
        +	memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE);
        +	p+=SSL3_RANDOM_SIZE;
        +
        +	/* get the session-id */
        +	j= *(p++);
        +
        +	s->hit=0;
        +	/* Versions before 0.9.7 always allow clients to resume sessions in renegotiation.
        +	 * 0.9.7 and later allow this by default, but optionally ignore resumption requests
        +	 * with flag SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather
        +	 * than a change to default behavior so that applications relying on this for security
        +	 * won't even compile against older library versions).
        +	 *
        +	 * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to request
        +	 * renegotiation but not a new session (s->new_session remains unset): for servers,
        +	 * this essentially just means that the SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
        +	 * setting will be ignored.
        +	 */
        +	if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
        +		{
        +		if (!ssl_get_new_session(s,1))
        +			goto err;
        +		}
        +	else
        +		{
        +		i=ssl_get_prev_session(s, p, j, d + n);
        +		if (i == 1)
        +			{ /* previous session */
        +			s->hit=1;
        +			}
        +		else if (i == -1)
        +			goto err;
        +		else /* i == 0 */
        +			{
        +			if (!ssl_get_new_session(s,1))
        +				goto err;
        +			}
        +		}
        +
        +	p+=j;
        +
        +	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
        +		{
        +		/* cookie stuff */
        +		cookie_len = *(p++);
        +
        +		/* 
        +		 * The ClientHello may contain a cookie even if the
        +		 * HelloVerify message has not been sent--make sure that it
        +		 * does not cause an overflow.
        +		 */
        +		if ( cookie_len > sizeof(s->d1->rcvd_cookie))
        +			{
        +			/* too much data */
        +			al = SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
        +			goto f_err;
        +			}
        +
        +		/* verify the cookie if appropriate option is set. */
        +		if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
        +			cookie_len > 0)
        +			{
        +			memcpy(s->d1->rcvd_cookie, p, cookie_len);
        +
        +			if ( s->ctx->app_verify_cookie_cb != NULL)
        +				{
        +				if ( s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
        +					cookie_len) == 0)
        +					{
        +					al=SSL_AD_HANDSHAKE_FAILURE;
        +					SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
        +						SSL_R_COOKIE_MISMATCH);
        +					goto f_err;
        +					}
        +				/* else cookie verification succeeded */
        +				}
        +			else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, 
        +						  s->d1->cookie_len) != 0) /* default verification */
        +				{
        +					al=SSL_AD_HANDSHAKE_FAILURE;
        +					SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
        +						SSL_R_COOKIE_MISMATCH);
        +					goto f_err;
        +				}
        +
        +			ret = 2;
        +			}
        +
        +		p += cookie_len;
        +		}
        +
        +	n2s(p,i);
        +	if ((i == 0) && (j != 0))
        +		{
        +		/* we need a cipher if we are not resuming a session */
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED);
        +		goto f_err;
        +		}
        +	if ((p+i) >= (d+n))
        +		{
        +		/* not enough data */
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	if ((i > 0) && (ssl_bytes_to_cipher_list(s,p,i,&(ciphers))
        +		== NULL))
        +		{
        +		goto err;
        +		}
        +	p+=i;
        +
        +	/* If it is a hit, check that the cipher is in the list */
        +	if ((s->hit) && (i > 0))
        +		{
        +		j=0;
        +		id=s->session->cipher->id;
        +
        +#ifdef CIPHER_DEBUG
        +		printf("client sent %d ciphers\n",sk_num(ciphers));
        +#endif
        +		for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
        +			{
        +			c=sk_SSL_CIPHER_value(ciphers,i);
        +#ifdef CIPHER_DEBUG
        +			printf("client [%2d of %2d]:%s\n",
        +				i,sk_num(ciphers),SSL_CIPHER_get_name(c));
        +#endif
        +			if (c->id == id)
        +				{
        +				j=1;
        +				break;
        +				}
        +			}
        +/* Disabled because it can be used in a ciphersuite downgrade
        + * attack: CVE-2010-4180.
        + */
        +#if 0
        +		if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
        +			{
        +			/* Special case as client bug workaround: the previously used cipher may
        +			 * not be in the current list, the client instead might be trying to
        +			 * continue using a cipher that before wasn't chosen due to server
        +			 * preferences.  We'll have to reject the connection if the cipher is not
        +			 * enabled, though. */
        +			c = sk_SSL_CIPHER_value(ciphers, 0);
        +			if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0)
        +				{
        +				s->session->cipher = c;
        +				j = 1;
        +				}
        +			}
        +#endif
        +		if (j == 0)
        +			{
        +			/* we need to have the cipher in the cipher
        +			 * list if we are asked to reuse it */
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
        +			goto f_err;
        +			}
        +		}
        +
        +	/* compression */
        +	i= *(p++);
        +	if ((p+i) > (d+n))
        +		{
        +		/* not enough data */
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	q=p;
        +	for (j=0; j<i; j++)
        +		{
        +		if (p[j] == 0) break;
        +		}
        +
        +	p+=i;
        +	if (j >= i)
        +		{
        +		/* no compress */
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_COMPRESSION_SPECIFIED);
        +		goto f_err;
        +		}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	/* TLS extensions*/
        +	if (s->version >= SSL3_VERSION)
        +		{
        +		if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
        +			{
        +			/* 'al' set by ssl_parse_clienthello_tlsext */
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
        +			goto f_err;
        +			}
        +		}
        +		if (ssl_check_clienthello_tlsext_early(s) <= 0) {
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
        +			goto err;
        +		}
        +
        +	/* Check if we want to use external pre-shared secret for this
        +	 * handshake for not reused session only. We need to generate
        +	 * server_random before calling tls_session_secret_cb in order to allow
        +	 * SessionTicket processing to use it in key derivation. */
        +	{
        +		unsigned long Time;
        +		unsigned char *pos;
        +		Time=(unsigned long)time(NULL);			/* Time */
        +		pos=s->s3->server_random;
        +		l2n(Time,pos);
        +		if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
        +			{
        +			al=SSL_AD_INTERNAL_ERROR;
        +			goto f_err;
        +			}
        +	}
        +
        +	if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
        +		{
        +		SSL_CIPHER *pref_cipher=NULL;
        +
        +		s->session->master_key_length=sizeof(s->session->master_key);
        +		if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
        +			ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
        +			{
        +			s->hit=1;
        +			s->session->ciphers=ciphers;
        +			s->session->verify_result=X509_V_OK;
        +
        +			ciphers=NULL;
        +
        +			/* check if some cipher was preferred by call back */
        +			pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
        +			if (pref_cipher == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
        +				goto f_err;
        +				}
        +
        +			s->session->cipher=pref_cipher;
        +
        +			if (s->cipher_list)
        +				sk_SSL_CIPHER_free(s->cipher_list);
        +
        +			if (s->cipher_list_by_id)
        +				sk_SSL_CIPHER_free(s->cipher_list_by_id);
        +
        +			s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
        +			s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
        +			}
        +		}
        +#endif
        +
        +	/* Worst case, we will use the NULL compression, but if we have other
        +	 * options, we will now look for them.  We have i-1 compression
        +	 * algorithms from the client, starting at q. */
        +	s->s3->tmp.new_compression=NULL;
        +#ifndef OPENSSL_NO_COMP
        +	/* This only happens if we have a cache hit */
        +	if (s->session->compress_meth != 0)
        +		{
        +		int m, comp_id = s->session->compress_meth;
        +		/* Perform sanity checks on resumed compression algorithm */
        +		/* Can't disable compression */
        +		if (s->options & SSL_OP_NO_COMPRESSION)
        +			{
        +			al=SSL_AD_INTERNAL_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
        +			goto f_err;
        +			}
        +		/* Look for resumed compression method */
        +		for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++)
        +			{
        +			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
        +			if (comp_id == comp->id)
        +				{
        +				s->s3->tmp.new_compression=comp;
        +				break;
        +				}
        +			}
        +		if (s->s3->tmp.new_compression == NULL)
        +			{
        +			al=SSL_AD_INTERNAL_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM);
        +			goto f_err;
        +			}
        +		/* Look for resumed method in compression list */
        +		for (m = 0; m < i; m++)
        +			{
        +			if (q[m] == comp_id)
        +				break;
        +			}
        +		if (m >= i)
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING);
        +			goto f_err;
        +			}
        +		}
        +	else if (s->hit)
        +		comp = NULL;
        +	else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
        +		{ /* See if we have a match */
        +		int m,nn,o,v,done=0;
        +
        +		nn=sk_SSL_COMP_num(s->ctx->comp_methods);
        +		for (m=0; m<nn; m++)
        +			{
        +			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
        +			v=comp->id;
        +			for (o=0; o<i; o++)
        +				{
        +				if (v == q[o])
        +					{
        +					done=1;
        +					break;
        +					}
        +				}
        +			if (done) break;
        +			}
        +		if (done)
        +			s->s3->tmp.new_compression=comp;
        +		else
        +			comp=NULL;
        +		}
        +#else
        +	/* If compression is disabled we'd better not try to resume a session
        +	 * using compression.
        +	 */
        +	if (s->session->compress_meth != 0)
        +		{
        +		al=SSL_AD_INTERNAL_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
        +		goto f_err;
        +		}
        +#endif
        +
        +	/* Given s->session->ciphers and SSL_get_ciphers, we must
        +	 * pick a cipher */
        +
        +	if (!s->hit)
        +		{
        +#ifdef OPENSSL_NO_COMP
        +		s->session->compress_meth=0;
        +#else
        +		s->session->compress_meth=(comp == NULL)?0:comp->id;
        +#endif
        +		if (s->session->ciphers != NULL)
        +			sk_SSL_CIPHER_free(s->session->ciphers);
        +		s->session->ciphers=ciphers;
        +		if (ciphers == NULL)
        +			{
        +			al=SSL_AD_ILLEGAL_PARAMETER;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);
        +			goto f_err;
        +			}
        +		ciphers=NULL;
        +		c=ssl3_choose_cipher(s,s->session->ciphers,
        +				     SSL_get_ciphers(s));
        +
        +		if (c == NULL)
        +			{
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
        +			goto f_err;
        +			}
        +		s->s3->tmp.new_cipher=c;
        +		}
        +	else
        +		{
        +		/* Session-id reuse */
        +#ifdef REUSE_CIPHER_BUG
        +		STACK_OF(SSL_CIPHER) *sk;
        +		SSL_CIPHER *nc=NULL;
        +		SSL_CIPHER *ec=NULL;
        +
        +		if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)
        +			{
        +			sk=s->session->ciphers;
        +			for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
        +				{
        +				c=sk_SSL_CIPHER_value(sk,i);
        +				if (c->algorithm_enc & SSL_eNULL)
        +					nc=c;
        +				if (SSL_C_IS_EXPORT(c))
        +					ec=c;
        +				}
        +			if (nc != NULL)
        +				s->s3->tmp.new_cipher=nc;
        +			else if (ec != NULL)
        +				s->s3->tmp.new_cipher=ec;
        +			else
        +				s->s3->tmp.new_cipher=s->session->cipher;
        +			}
        +		else
        +#endif
        +		s->s3->tmp.new_cipher=s->session->cipher;
        +		}
        +
        +	if (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER))
        +		{
        +		if (!ssl3_digest_cached_records(s))
        +			{
        +			al = SSL_AD_INTERNAL_ERROR;
        +			goto f_err;
        +			}
        +		}
        +	
        +	/* we now have the following setup. 
        +	 * client_random
        +	 * cipher_list 		- our prefered list of ciphers
        +	 * ciphers 		- the clients prefered list of ciphers
        +	 * compression		- basically ignored right now
        +	 * ssl version is set	- sslv3
        +	 * s->session		- The ssl session has been setup.
        +	 * s->hit		- session reuse flag
        +	 * s->tmp.new_cipher	- the new cipher to use.
        +	 */
        +
        +	/* Handles TLS extensions that we couldn't check earlier */
        +	if (s->version >= SSL3_VERSION)
        +		{
        +		if (ssl_check_clienthello_tlsext_late(s) <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
        +			goto err;
        +			}
        +		}
        +
        +	if (ret < 0) ret=1;
        +	if (0)
        +		{
        +f_err:
        +		ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +		}
        +err:
        +	if (ciphers != NULL) sk_SSL_CIPHER_free(ciphers);
        +	return(ret);
        +	}
        +
        +int ssl3_send_server_hello(SSL *s)
        +	{
        +	unsigned char *buf;
        +	unsigned char *p,*d;
        +	int i,sl;
        +	unsigned long l;
        +#ifdef OPENSSL_NO_TLSEXT
        +	unsigned long Time;
        +#endif
        +
        +	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
        +		{
        +		buf=(unsigned char *)s->init_buf->data;
        +#ifdef OPENSSL_NO_TLSEXT
        +		p=s->s3->server_random;
        +		/* Generate server_random if it was not needed previously */
        +		Time=(unsigned long)time(NULL);			/* Time */
        +		l2n(Time,p);
        +		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
        +			return -1;
        +#endif
        +		/* Do the message type and length last */
        +		d=p= &(buf[4]);
        +
        +		*(p++)=s->version>>8;
        +		*(p++)=s->version&0xff;
        +
        +		/* Random stuff */
        +		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
        +		p+=SSL3_RANDOM_SIZE;
        +
        +		/* There are several cases for the session ID to send
        +		 * back in the server hello:
        +		 * - For session reuse from the session cache,
        +		 *   we send back the old session ID.
        +		 * - If stateless session reuse (using a session ticket)
        +		 *   is successful, we send back the client's "session ID"
        +		 *   (which doesn't actually identify the session).
        +		 * - If it is a new session, we send back the new
        +		 *   session ID.
        +		 * - However, if we want the new session to be single-use,
        +		 *   we send back a 0-length session ID.
        +		 * s->hit is non-zero in either case of session reuse,
        +		 * so the following won't overwrite an ID that we're supposed
        +		 * to send back.
        +		 */
        +		if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
        +			&& !s->hit)
        +			s->session->session_id_length=0;
        +
        +		sl=s->session->session_id_length;
        +		if (sl > (int)sizeof(s->session->session_id))
        +			{
        +			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +		*(p++)=sl;
        +		memcpy(p,s->session->session_id,sl);
        +		p+=sl;
        +
        +		/* put the cipher */
        +		i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
        +		p+=i;
        +
        +		/* put the compression method */
        +#ifdef OPENSSL_NO_COMP
        +			*(p++)=0;
        +#else
        +		if (s->s3->tmp.new_compression == NULL)
        +			*(p++)=0;
        +		else
        +			*(p++)=s->s3->tmp.new_compression->id;
        +#endif
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (ssl_prepare_serverhello_tlsext(s) <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
        +			return -1;
        +			}
        +		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
        +			return -1;
        +			}
        +#endif
        +		/* do the header */
        +		l=(p-d);
        +		d=buf;
        +		*(d++)=SSL3_MT_SERVER_HELLO;
        +		l2n3(l,d);
        +
        +		s->state=SSL3_ST_SW_SRVR_HELLO_B;
        +		/* number of bytes to write */
        +		s->init_num=p-buf;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_SW_SRVR_HELLO_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int ssl3_send_server_done(SSL *s)
        +	{
        +	unsigned char *p;
        +
        +	if (s->state == SSL3_ST_SW_SRVR_DONE_A)
        +		{
        +		p=(unsigned char *)s->init_buf->data;
        +
        +		/* do the header */
        +		*(p++)=SSL3_MT_SERVER_DONE;
        +		*(p++)=0;
        +		*(p++)=0;
        +		*(p++)=0;
        +
        +		s->state=SSL3_ST_SW_SRVR_DONE_B;
        +		/* number of bytes to write */
        +		s->init_num=4;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_SW_SRVR_DONE_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int ssl3_send_server_key_exchange(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_RSA
        +	unsigned char *q;
        +	int j,num;
        +	RSA *rsa;
        +	unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        +	unsigned int u;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	DH *dh=NULL,*dhp;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh=NULL, *ecdhp;
        +	unsigned char *encodedPoint = NULL;
        +	int encodedlen = 0;
        +	int curve_id = 0;
        +	BN_CTX *bn_ctx = NULL; 
        +#endif
        +	EVP_PKEY *pkey;
        +	const EVP_MD *md = NULL;
        +	unsigned char *p,*d;
        +	int al,i;
        +	unsigned long type;
        +	int n;
        +	CERT *cert;
        +	BIGNUM *r[4];
        +	int nr[4],kn;
        +	BUF_MEM *buf;
        +	EVP_MD_CTX md_ctx;
        +
        +	EVP_MD_CTX_init(&md_ctx);
        +	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
        +		{
        +		type=s->s3->tmp.new_cipher->algorithm_mkey;
        +		cert=s->cert;
        +
        +		buf=s->init_buf;
        +
        +		r[0]=r[1]=r[2]=r[3]=NULL;
        +		n=0;
        +#ifndef OPENSSL_NO_RSA
        +		if (type & SSL_kRSA)
        +			{
        +			rsa=cert->rsa_tmp;
        +			if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
        +				{
        +				rsa=s->cert->rsa_tmp_cb(s,
        +				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
        +				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
        +				if(rsa == NULL)
        +				{
        +					al=SSL_AD_HANDSHAKE_FAILURE;
        +					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
        +					goto f_err;
        +				}
        +				RSA_up_ref(rsa);
        +				cert->rsa_tmp=rsa;
        +				}
        +			if (rsa == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
        +				goto f_err;
        +				}
        +			r[0]=rsa->n;
        +			r[1]=rsa->e;
        +			s->s3->tmp.use_rsa_tmp=1;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_DH
        +			if (type & SSL_kEDH)
        +			{
        +			dhp=cert->dh_tmp;
        +			if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
        +				dhp=s->cert->dh_tmp_cb(s,
        +				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
        +				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
        +			if (dhp == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
        +				goto f_err;
        +				}
        +
        +			if (s->s3->tmp.dh != NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			if ((dh=DHparams_dup(dhp)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
        +				goto err;
        +				}
        +
        +			s->s3->tmp.dh=dh;
        +			if ((dhp->pub_key == NULL ||
        +			     dhp->priv_key == NULL ||
        +			     (s->options & SSL_OP_SINGLE_DH_USE)))
        +				{
        +				if(!DH_generate_key(dh))
        +				    {
        +				    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
        +					   ERR_R_DH_LIB);
        +				    goto err;
        +				    }
        +				}
        +			else
        +				{
        +				dh->pub_key=BN_dup(dhp->pub_key);
        +				dh->priv_key=BN_dup(dhp->priv_key);
        +				if ((dh->pub_key == NULL) ||
        +					(dh->priv_key == NULL))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
        +					goto err;
        +					}
        +				}
        +			r[0]=dh->p;
        +			r[1]=dh->g;
        +			r[2]=dh->pub_key;
        +			}
        +		else 
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +			if (type & SSL_kEECDH)
        +			{
        +			const EC_GROUP *group;
        +
        +			ecdhp=cert->ecdh_tmp;
        +			if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
        +				{
        +				ecdhp=s->cert->ecdh_tmp_cb(s,
        +				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
        +				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
        +				}
        +			if (ecdhp == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
        +				goto f_err;
        +				}
        +
        +			if (s->s3->tmp.ecdh != NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			/* Duplicate the ECDH structure. */
        +			if (ecdhp == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +			if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			s->s3->tmp.ecdh=ecdh;
        +			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
        +			    (EC_KEY_get0_private_key(ecdh) == NULL) ||
        +			    (s->options & SSL_OP_SINGLE_ECDH_USE))
        +				{
        +				if(!EC_KEY_generate_key(ecdh))
        +				    {
        +				    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				    goto err;
        +				    }
        +				}
        +
        +			if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
        +			    (EC_KEY_get0_public_key(ecdh)  == NULL) ||
        +			    (EC_KEY_get0_private_key(ecdh) == NULL))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
        +			    (EC_GROUP_get_degree(group) > 163)) 
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
        +				goto err;
        +				}
        +
        +			/* XXX: For now, we only support ephemeral ECDH
        +			 * keys over named (not generic) curves. For 
        +			 * supported named curves, curve_id is non-zero.
        +			 */
        +			if ((curve_id = 
        +			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
        +			    == 0)
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
        +				goto err;
        +				}
        +
        +			/* Encode the public key.
        +			 * First check the size of encoding and
        +			 * allocate memory accordingly.
        +			 */
        +			encodedlen = EC_POINT_point2oct(group, 
        +			    EC_KEY_get0_public_key(ecdh),
        +			    POINT_CONVERSION_UNCOMPRESSED, 
        +			    NULL, 0, NULL);
        +
        +			encodedPoint = (unsigned char *) 
        +			    OPENSSL_malloc(encodedlen*sizeof(unsigned char)); 
        +			bn_ctx = BN_CTX_new();
        +			if ((encodedPoint == NULL) || (bn_ctx == NULL))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +
        +			encodedlen = EC_POINT_point2oct(group, 
        +			    EC_KEY_get0_public_key(ecdh), 
        +			    POINT_CONVERSION_UNCOMPRESSED, 
        +			    encodedPoint, encodedlen, bn_ctx);
        +
        +			if (encodedlen == 0) 
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
        +				goto err;
        +				}
        +
        +			BN_CTX_free(bn_ctx);  bn_ctx=NULL;
        +
        +			/* XXX: For now, we only support named (not 
        +			 * generic) curves in ECDH ephemeral key exchanges.
        +			 * In this situation, we need four additional bytes
        +			 * to encode the entire ServerECDHParams
        +			 * structure. 
        +			 */
        +			n = 4 + encodedlen;
        +
        +			/* We'll generate the serverKeyExchange message
        +			 * explicitly so we can set these to NULLs
        +			 */
        +			r[0]=NULL;
        +			r[1]=NULL;
        +			r[2]=NULL;
        +			r[3]=NULL;
        +			}
        +		else 
        +#endif /* !OPENSSL_NO_ECDH */
        +#ifndef OPENSSL_NO_PSK
        +			if (type & SSL_kPSK)
        +				{
        +				/* reserve size for record length and PSK identity hint*/
        +				n+=2+strlen(s->ctx->psk_identity_hint);
        +				}
        +			else
        +#endif /* !OPENSSL_NO_PSK */
        +#ifndef OPENSSL_NO_SRP
        +		if (type & SSL_kSRP)
        +			{
        +			if ((s->srp_ctx.N == NULL) ||
        +				(s->srp_ctx.g == NULL) ||
        +				(s->srp_ctx.s == NULL) ||
        +				(s->srp_ctx.B == NULL))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM);
        +				goto err;
        +				}
        +			r[0]=s->srp_ctx.N;
        +			r[1]=s->srp_ctx.g;
        +			r[2]=s->srp_ctx.s;
        +			r[3]=s->srp_ctx.B;
        +			}
        +		else 
        +#endif
        +			{
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
        +			goto f_err;
        +			}
        +		for (i=0; r[i] != NULL && i<4; i++)
        +			{
        +			nr[i]=BN_num_bytes(r[i]);
        +#ifndef OPENSSL_NO_SRP
        +			if ((i == 2) && (type & SSL_kSRP))
        +				n+=1+nr[i];
        +			else
        +#endif
        +			n+=2+nr[i];
        +			}
        +
        +		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
        +			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
        +			{
        +			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
        +				== NULL)
        +				{
        +				al=SSL_AD_DECODE_ERROR;
        +				goto f_err;
        +				}
        +			kn=EVP_PKEY_size(pkey);
        +			}
        +		else
        +			{
        +			pkey=NULL;
        +			kn=0;
        +			}
        +
        +		if (!BUF_MEM_grow_clean(buf,n+4+kn))
        +			{
        +			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
        +			goto err;
        +			}
        +		d=(unsigned char *)s->init_buf->data;
        +		p= &(d[4]);
        +
        +		for (i=0; r[i] != NULL && i<4; i++)
        +			{
        +#ifndef OPENSSL_NO_SRP
        +			if ((i == 2) && (type & SSL_kSRP))
        +				{
        +				*p = nr[i];
        +				p++;
        +				}
        +			else
        +#endif
        +			s2n(nr[i],p);
        +			BN_bn2bin(r[i],p);
        +			p+=nr[i];
        +			}
        +
        +#ifndef OPENSSL_NO_ECDH
        +		if (type & SSL_kEECDH) 
        +			{
        +			/* XXX: For now, we only support named (not generic) curves.
        +			 * In this situation, the serverKeyExchange message has:
        +			 * [1 byte CurveType], [2 byte CurveName]
        +			 * [1 byte length of encoded point], followed by
        +			 * the actual encoded point itself
        +			 */
        +			*p = NAMED_CURVE_TYPE;
        +			p += 1;
        +			*p = 0;
        +			p += 1;
        +			*p = curve_id;
        +			p += 1;
        +			*p = encodedlen;
        +			p += 1;
        +			memcpy((unsigned char*)p, 
        +			    (unsigned char *)encodedPoint, 
        +			    encodedlen);
        +			OPENSSL_free(encodedPoint);
        +			encodedPoint = NULL;
        +			p += encodedlen;
        +			}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +		if (type & SSL_kPSK)
        +			{
        +			/* copy PSK identity hint */
        +			s2n(strlen(s->ctx->psk_identity_hint), p); 
        +			strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint));
        +			p+=strlen(s->ctx->psk_identity_hint);
        +			}
        +#endif
        +
        +		/* not anonymous */
        +		if (pkey != NULL)
        +			{
        +			/* n is the length of the params, they start at &(d[4])
        +			 * and p points to the space at the end. */
        +#ifndef OPENSSL_NO_RSA
        +			if (pkey->type == EVP_PKEY_RSA
        +					&& TLS1_get_version(s) < TLS1_2_VERSION)
        +				{
        +				q=md_buf;
        +				j=0;
        +				for (num=2; num > 0; num--)
        +					{
        +					EVP_MD_CTX_set_flags(&md_ctx,
        +						EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +					EVP_DigestInit_ex(&md_ctx,(num == 2)
        +						?s->ctx->md5:s->ctx->sha1, NULL);
        +					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +					EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +					EVP_DigestUpdate(&md_ctx,&(d[4]),n);
        +					EVP_DigestFinal_ex(&md_ctx,q,
        +						(unsigned int *)&i);
        +					q+=i;
        +					j+=i;
        +					}
        +				if (RSA_sign(NID_md5_sha1, md_buf, j,
        +					&(p[2]), &u, pkey->pkey.rsa) <= 0)
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
        +					goto err;
        +					}
        +				s2n(u,p);
        +				n+=u+2;
        +				}
        +			else
        +#endif
        +			if (md)
        +				{
        +				/* For TLS1.2 and later send signature
        +				 * algorithm */
        +				if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +					{
        +					if (!tls12_get_sigandhash(p, pkey, md))
        +						{
        +						/* Should never happen */
        +						al=SSL_AD_INTERNAL_ERROR;
        +						SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +						goto f_err;
        +						}
        +					p+=2;
        +					}
        +#ifdef SSL_DEBUG
        +				fprintf(stderr, "Using hash %s\n",
        +							EVP_MD_name(md));
        +#endif
        +				EVP_SignInit_ex(&md_ctx, md, NULL);
        +				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
        +				EVP_SignUpdate(&md_ctx,&(d[4]),n);
        +				if (!EVP_SignFinal(&md_ctx,&(p[2]),
        +					(unsigned int *)&i,pkey))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_EVP);
        +					goto err;
        +					}
        +				s2n(i,p);
        +				n+=i+2;
        +				if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +					n+= 2;
        +				}
        +			else
        +				{
        +				/* Is this error check actually needed? */
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
        +				goto f_err;
        +				}
        +			}
        +
        +		*(d++)=SSL3_MT_SERVER_KEY_EXCHANGE;
        +		l2n3(n,d);
        +
        +		/* we should now have things packed up, so lets send
        +		 * it off */
        +		s->init_num=n+4;
        +		s->init_off=0;
        +		}
        +
        +	s->state = SSL3_ST_SW_KEY_EXCH_B;
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +err:
        +#ifndef OPENSSL_NO_ECDH
        +	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
        +	BN_CTX_free(bn_ctx);
        +#endif
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return(-1);
        +	}
        +
        +int ssl3_send_certificate_request(SSL *s)
        +	{
        +	unsigned char *p,*d;
        +	int i,j,nl,off,n;
        +	STACK_OF(X509_NAME) *sk=NULL;
        +	X509_NAME *name;
        +	BUF_MEM *buf;
        +
        +	if (s->state == SSL3_ST_SW_CERT_REQ_A)
        +		{
        +		buf=s->init_buf;
        +
        +		d=p=(unsigned char *)&(buf->data[4]);
        +
        +		/* get the list of acceptable cert types */
        +		p++;
        +		n=ssl3_get_req_cert_type(s,p);
        +		d[0]=n;
        +		p+=n;
        +		n++;
        +
        +		if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +			{
        +			nl = tls12_get_req_sig_algs(s, p + 2);
        +			s2n(nl, p);
        +			p += nl + 2;
        +			n += nl + 2;
        +			}
        +
        +		off=n;
        +		p+=2;
        +		n+=2;
        +
        +		sk=SSL_get_client_CA_list(s);
        +		nl=0;
        +		if (sk != NULL)
        +			{
        +			for (i=0; i<sk_X509_NAME_num(sk); i++)
        +				{
        +				name=sk_X509_NAME_value(sk,i);
        +				j=i2d_X509_NAME(name,NULL);
        +				if (!BUF_MEM_grow_clean(buf,4+n+j+2))
        +					{
        +					SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
        +					goto err;
        +					}
        +				p=(unsigned char *)&(buf->data[4+n]);
        +				if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
        +					{
        +					s2n(j,p);
        +					i2d_X509_NAME(name,&p);
        +					n+=2+j;
        +					nl+=2+j;
        +					}
        +				else
        +					{
        +					d=p;
        +					i2d_X509_NAME(name,&p);
        +					j-=2; s2n(j,d); j+=2;
        +					n+=j;
        +					nl+=j;
        +					}
        +				}
        +			}
        +		/* else no CA names */
        +		p=(unsigned char *)&(buf->data[4+off]);
        +		s2n(nl,p);
        +
        +		d=(unsigned char *)buf->data;
        +		*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
        +		l2n3(n,d);
        +
        +		/* we should now have things packed up, so lets send
        +		 * it off */
        +
        +		s->init_num=n+4;
        +		s->init_off=0;
        +#ifdef NETSCAPE_HANG_BUG
        +		p=(unsigned char *)s->init_buf->data + s->init_num;
        +
        +		/* do the header */
        +		*(p++)=SSL3_MT_SERVER_DONE;
        +		*(p++)=0;
        +		*(p++)=0;
        +		*(p++)=0;
        +		s->init_num += 4;
        +#endif
        +
        +		s->state = SSL3_ST_SW_CERT_REQ_B;
        +		}
        +
        +	/* SSL3_ST_SW_CERT_REQ_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +err:
        +	return(-1);
        +	}
        +
        +int ssl3_get_client_key_exchange(SSL *s)
        +	{
        +	int i,al,ok;
        +	long n;
        +	unsigned long alg_k;
        +	unsigned char *p;
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rsa=NULL;
        +	EVP_PKEY *pkey=NULL;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	BIGNUM *pub=NULL;
        +	DH *dh_srvr;
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +	KSSL_ERR kssl_err;
        +#endif /* OPENSSL_NO_KRB5 */
        +
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *srvr_ecdh = NULL;
        +	EVP_PKEY *clnt_pub_pkey = NULL;
        +	EC_POINT *clnt_ecpoint = NULL;
        +	BN_CTX *bn_ctx = NULL; 
        +#endif
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_SR_KEY_EXCH_A,
        +		SSL3_ST_SR_KEY_EXCH_B,
        +		SSL3_MT_CLIENT_KEY_EXCHANGE,
        +		2048, /* ??? */
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +	p=(unsigned char *)s->init_msg;
        +
        +	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
        +
        +#ifndef OPENSSL_NO_RSA
        +	if (alg_k & SSL_kRSA)
        +		{
        +		/* FIX THIS UP EAY EAY EAY EAY */
        +		if (s->s3->tmp.use_rsa_tmp)
        +			{
        +			if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
        +				rsa=s->cert->rsa_tmp;
        +			/* Don't do a callback because rsa_tmp should
        +			 * be sent already */
        +			if (rsa == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY);
        +				goto f_err;
        +
        +				}
        +			}
        +		else
        +			{
        +			pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
        +			if (	(pkey == NULL) ||
        +				(pkey->type != EVP_PKEY_RSA) ||
        +				(pkey->pkey.rsa == NULL))
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);
        +				goto f_err;
        +				}
        +			rsa=pkey->pkey.rsa;
        +			}
        +
        +		/* TLS and [incidentally] DTLS{0xFEFF} */
        +		if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER)
        +			{
        +			n2s(p,i);
        +			if (n != i+2)
        +				{
        +				if (!(s->options & SSL_OP_TLS_D5_BUG))
        +					{
        +					SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
        +					goto err;
        +					}
        +				else
        +					p-=2;
        +				}
        +			else
        +				n=i;
        +			}
        +
        +		i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
        +
        +		al = -1;
        +		
        +		if (i != SSL_MAX_MASTER_KEY_LENGTH)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
        +			}
        +
        +		if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
        +			{
        +			/* The premaster secret must contain the same version number as the
        +			 * ClientHello to detect version rollback attacks (strangely, the
        +			 * protocol does not offer such protection for DH ciphersuites).
        +			 * However, buggy clients exist that send the negotiated protocol
        +			 * version instead if the server does not support the requested
        +			 * protocol version.
        +			 * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
        +			if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
        +				(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
        +				{
        +				al=SSL_AD_DECODE_ERROR;
        +				/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
        +
        +				/* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
        +				 * (http://eprint.iacr.org/2003/052/) exploits the version
        +				 * number check as a "bad version oracle" -- an alert would
        +				 * reveal that the plaintext corresponding to some ciphertext
        +				 * made up by the adversary is properly formatted except
        +				 * that the version number is wrong.  To avoid such attacks,
        +				 * we should treat this just like any other decryption error. */
        +				}
        +			}
        +
        +		if (al != -1)
        +			{
        +			/* Some decryption failure -- use random value instead as countermeasure
        +			 * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
        +			 * (see RFC 2246, section 7.4.7.1). */
        +			ERR_clear_error();
        +			i = SSL_MAX_MASTER_KEY_LENGTH;
        +			p[0] = s->client_version >> 8;
        +			p[1] = s->client_version & 0xff;
        +			if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
        +				goto err;
        +			}
        +	
        +		s->session->master_key_length=
        +			s->method->ssl3_enc->generate_master_secret(s,
        +				s->session->master_key,
        +				p,i);
        +		OPENSSL_cleanse(p,i);
        +		}
        +	else
        +#endif
        +#ifndef OPENSSL_NO_DH
        +		if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
        +		{
        +		n2s(p,i);
        +		if (n != i+2)
        +			{
        +			if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG))
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
        +				goto err;
        +				}
        +			else
        +				{
        +				p-=2;
        +				i=(int)n;
        +				}
        +			}
        +
        +		if (n == 0L) /* the parameters are in the cert */
        +			{
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS);
        +			goto f_err;
        +			}
        +		else
        +			{
        +			if (s->s3->tmp.dh == NULL)
        +				{
        +				al=SSL_AD_HANDSHAKE_FAILURE;
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
        +				goto f_err;
        +				}
        +			else
        +				dh_srvr=s->s3->tmp.dh;
        +			}
        +
        +		pub=BN_bin2bn(p,i,NULL);
        +		if (pub == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB);
        +			goto err;
        +			}
        +
        +		i=DH_compute_key(p,pub,dh_srvr);
        +
        +		if (i <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
        +			BN_clear_free(pub);
        +			goto err;
        +			}
        +
        +		DH_free(s->s3->tmp.dh);
        +		s->s3->tmp.dh=NULL;
        +
        +		BN_clear_free(pub);
        +		pub=NULL;
        +		s->session->master_key_length=
        +			s->method->ssl3_enc->generate_master_secret(s,
        +				s->session->master_key,p,i);
        +		OPENSSL_cleanse(p,i);
        +		}
        +	else
        +#endif
        +#ifndef OPENSSL_NO_KRB5
        +	if (alg_k & SSL_kKRB5)
        +		{
        +		krb5_error_code		krb5rc;
        +		krb5_data		enc_ticket;
        +		krb5_data		authenticator;
        +		krb5_data		enc_pms;
        +		KSSL_CTX		*kssl_ctx = s->kssl_ctx;
        +		EVP_CIPHER_CTX		ciph_ctx;
        +		const EVP_CIPHER	*enc = NULL;
        +		unsigned char		iv[EVP_MAX_IV_LENGTH];
        +		unsigned char		pms[SSL_MAX_MASTER_KEY_LENGTH
        +					       + EVP_MAX_BLOCK_LENGTH];
        +		int		     padl, outl;
        +		krb5_timestamp		authtime = 0;
        +		krb5_ticket_times	ttimes;
        +
        +		EVP_CIPHER_CTX_init(&ciph_ctx);
        +
        +		if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
        +
        +		n2s(p,i);
        +		enc_ticket.length = i;
        +
        +		if (n < (long)(enc_ticket.length + 6))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +
        +		enc_ticket.data = (char *)p;
        +		p+=enc_ticket.length;
        +
        +		n2s(p,i);
        +		authenticator.length = i;
        +
        +		if (n < (long)(enc_ticket.length + authenticator.length + 6))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +
        +		authenticator.data = (char *)p;
        +		p+=authenticator.length;
        +
        +		n2s(p,i);
        +		enc_pms.length = i;
        +		enc_pms.data = (char *)p;
        +		p+=enc_pms.length;
        +
        +		/* Note that the length is checked again below,
        +		** after decryption
        +		*/
        +		if(enc_pms.length > sizeof pms)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +			       SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +
        +		if (n != (long)(enc_ticket.length + authenticator.length +
        +						enc_pms.length + 6))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +
        +		if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
        +					&kssl_err)) != 0)
        +			{
        +#ifdef KSSL_DEBUG
        +			printf("kssl_sget_tkt rtn %d [%d]\n",
        +				krb5rc, kssl_err.reason);
        +			if (kssl_err.text)
        +				printf("kssl_err text= %s\n", kssl_err.text);
        +#endif	/* KSSL_DEBUG */
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				kssl_err.reason);
        +			goto err;
        +			}
        +
        +		/*  Note: no authenticator is not considered an error,
        +		**  but will return authtime == 0.
        +		*/
        +		if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
        +					&authtime, &kssl_err)) != 0)
        +			{
        +#ifdef KSSL_DEBUG
        +			printf("kssl_check_authent rtn %d [%d]\n",
        +				krb5rc, kssl_err.reason);
        +			if (kssl_err.text)
        +				printf("kssl_err text= %s\n", kssl_err.text);
        +#endif	/* KSSL_DEBUG */
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				kssl_err.reason);
        +			goto err;
        +			}
        +
        +		if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
        +			goto err;
        +			}
        +
        +#ifdef KSSL_DEBUG
        +		kssl_ctx_show(kssl_ctx);
        +#endif	/* KSSL_DEBUG */
        +
        +		enc = kssl_map_enc(kssl_ctx->enctype);
        +		if (enc == NULL)
        +		    goto err;
        +
        +		memset(iv, 0, sizeof iv);	/* per RFC 1510 */
        +
        +		if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DECRYPTION_FAILED);
        +			goto err;
        +			}
        +		if (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
        +					(unsigned char *)enc_pms.data, enc_pms.length))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DECRYPTION_FAILED);
        +			goto err;
        +			}
        +		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +		if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DECRYPTION_FAILED);
        +			goto err;
        +			}
        +		outl += padl;
        +		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_DATA_LENGTH_TOO_LONG);
        +			goto err;
        +			}
        +		if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff))))
        +		    {
        +		    /* The premaster secret must contain the same version number as the
        +		     * ClientHello to detect version rollback attacks (strangely, the
        +		     * protocol does not offer such protection for DH ciphersuites).
        +		     * However, buggy clients exist that send random bytes instead of
        +		     * the protocol version.
        +		     * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. 
        +		     * (Perhaps we should have a separate BUG value for the Kerberos cipher)
        +		     */
        +		    if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +			       SSL_AD_DECODE_ERROR);
        +			goto err;
        +			}
        +		    }
        +
        +		EVP_CIPHER_CTX_cleanup(&ciph_ctx);
        +
        +		s->session->master_key_length=
        +			s->method->ssl3_enc->generate_master_secret(s,
        +				s->session->master_key, pms, outl);
        +
        +		if (kssl_ctx->client_princ)
        +			{
        +			size_t len = strlen(kssl_ctx->client_princ);
        +			if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
        +				{
        +				s->session->krb5_client_princ_len = len;
        +				memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
        +				}
        +			}
        +
        +
        +		/*  Was doing kssl_ctx_free() here,
        +		**  but it caused problems for apache.
        +		**  kssl_ctx = kssl_ctx_free(kssl_ctx);
        +		**  if (s->kssl_ctx)  s->kssl_ctx = NULL;
        +		*/
        +		}
        +	else
        +#endif	/* OPENSSL_NO_KRB5 */
        +
        +#ifndef OPENSSL_NO_ECDH
        +		if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
        +		{
        +		int ret = 1;
        +		int field_size = 0;
        +		const EC_KEY   *tkey;
        +		const EC_GROUP *group;
        +		const BIGNUM *priv_key;
        +
        +		/* initialize structures for server's ECDH key pair */
        +		if ((srvr_ecdh = EC_KEY_new()) == NULL) 
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +			    ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		/* Let's get server private key and group information */
        +		if (alg_k & (SSL_kECDHr|SSL_kECDHe))
        +			{ 
        +			/* use the certificate */
        +			tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
        +			}
        +		else
        +			{
        +			/* use the ephermeral values we saved when
        +			 * generating the ServerKeyExchange msg.
        +			 */
        +			tkey = s->s3->tmp.ecdh;
        +			}
        +
        +		group    = EC_KEY_get0_group(tkey);
        +		priv_key = EC_KEY_get0_private_key(tkey);
        +
        +		if (!EC_KEY_set_group(srvr_ecdh, group) ||
        +		    !EC_KEY_set_private_key(srvr_ecdh, priv_key))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +			       ERR_R_EC_LIB);
        +			goto err;
        +			}
        +
        +		/* Let's get client's public key */
        +		if ((clnt_ecpoint = EC_POINT_new(group)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +			    ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +
        +		if (n == 0L) 
        +			{
        +			/* Client Publickey was in Client Certificate */
        +
        +			 if (alg_k & SSL_kEECDH)
        +				 {
        +				 al=SSL_AD_HANDSHAKE_FAILURE;
        +				 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
        +				 goto f_err;
        +				 }
        +			if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
        +			    == NULL) || 
        +			    (clnt_pub_pkey->type != EVP_PKEY_EC))
        +				{
        +				/* XXX: For now, we do not support client
        +				 * authentication using ECDH certificates
        +				 * so this branch (n == 0L) of the code is
        +				 * never executed. When that support is
        +				 * added, we ought to ensure the key 
        +				 * received in the certificate is 
        +				 * authorized for key agreement.
        +				 * ECDH_compute_key implicitly checks that
        +				 * the two ECDH shares are for the same
        +				 * group.
        +				 */
        +			   	al=SSL_AD_HANDSHAKE_FAILURE;
        +			   	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
        +			   	goto f_err;
        +			   	}
        +
        +			if (EC_POINT_copy(clnt_ecpoint,
        +			    EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					ERR_R_EC_LIB);
        +				goto err;
        +				}
        +			ret = 2; /* Skip certificate verify processing */
        +			}
        +		else
        +			{
        +			/* Get client's public key from encoded point
        +			 * in the ClientKeyExchange message.
        +			 */
        +			if ((bn_ctx = BN_CTX_new()) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				    ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +			/* Get encoded point length */
        +			i = *p; 
        +			p += 1;
        +			if (n != 1 + i)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				    ERR_R_EC_LIB);
        +				goto err;
        +				}
        +			if (EC_POINT_oct2point(group, 
        +			    clnt_ecpoint, p, i, bn_ctx) == 0)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				    ERR_R_EC_LIB);
        +				goto err;
        +				}
        +			/* p is pointing to somewhere in the buffer
        +			 * currently, so set it to the start 
        +			 */ 
        +			p=(unsigned char *)s->init_buf->data;
        +			}
        +
        +		/* Compute the shared pre-master secret */
        +		field_size = EC_GROUP_get_degree(group);
        +		if (field_size <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, 
        +			       ERR_R_ECDH_LIB);
        +			goto err;
        +			}
        +		i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
        +		if (i <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +			    ERR_R_ECDH_LIB);
        +			goto err;
        +			}
        +
        +		EVP_PKEY_free(clnt_pub_pkey);
        +		EC_POINT_free(clnt_ecpoint);
        +		EC_KEY_free(srvr_ecdh);
        +		BN_CTX_free(bn_ctx);
        +		EC_KEY_free(s->s3->tmp.ecdh);
        +		s->s3->tmp.ecdh = NULL; 
        +
        +		/* Compute the master secret */
        +		s->session->master_key_length = s->method->ssl3_enc-> \
        +		    generate_master_secret(s, s->session->master_key, p, i);
        +		
        +		OPENSSL_cleanse(p, i);
        +		return (ret);
        +		}
        +	else
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +		if (alg_k & SSL_kPSK)
        +			{
        +			unsigned char *t = NULL;
        +			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
        +			unsigned int pre_ms_len = 0, psk_len = 0;
        +			int psk_err = 1;
        +			char tmp_id[PSK_MAX_IDENTITY_LEN+1];
        +
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +
        +			n2s(p,i);
        +			if (n != i+2)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					SSL_R_LENGTH_MISMATCH);
        +				goto psk_err;
        +				}
        +			if (i > PSK_MAX_IDENTITY_LEN)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					SSL_R_DATA_LENGTH_TOO_LONG);
        +				goto psk_err;
        +				}
        +			if (s->psk_server_callback == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				       SSL_R_PSK_NO_SERVER_CB);
        +				goto psk_err;
        +				}
        +
        +			/* Create guaranteed NULL-terminated identity
        +			 * string for the callback */
        +			memcpy(tmp_id, p, i);
        +			memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
        +			psk_len = s->psk_server_callback(s, tmp_id,
        +				psk_or_pre_ms, sizeof(psk_or_pre_ms));
        +			OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1);
        +
        +			if (psk_len > PSK_MAX_PSK_LEN)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					ERR_R_INTERNAL_ERROR);
        +				goto psk_err;
        +				}
        +			else if (psk_len == 0)
        +				{
        +				/* PSK related to the given identity not found */
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				       SSL_R_PSK_IDENTITY_NOT_FOUND);
        +				al=SSL_AD_UNKNOWN_PSK_IDENTITY;
        +				goto psk_err;
        +				}
        +
        +			/* create PSK pre_master_secret */
        +			pre_ms_len=2+psk_len+2+psk_len;
        +			t = psk_or_pre_ms;
        +			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
        +			s2n(psk_len, t);
        +			memset(t, 0, psk_len);
        +			t+=psk_len;
        +			s2n(psk_len, t);
        +
        +			if (s->session->psk_identity != NULL)
        +				OPENSSL_free(s->session->psk_identity);
        +			s->session->psk_identity = BUF_strdup((char *)p);
        +			if (s->session->psk_identity == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto psk_err;
        +				}
        +
        +			if (s->session->psk_identity_hint != NULL)
        +				OPENSSL_free(s->session->psk_identity_hint);
        +			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
        +			if (s->ctx->psk_identity_hint != NULL &&
        +				s->session->psk_identity_hint == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto psk_err;
        +				}
        +
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key, psk_or_pre_ms, pre_ms_len);
        +			psk_err = 0;
        +		psk_err:
        +			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
        +			if (psk_err != 0)
        +				goto f_err;
        +			}
        +		else
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +		if (alg_k & SSL_kSRP)
        +			{
        +			int param_len;
        +
        +			n2s(p,i);
        +			param_len=i+2;
        +			if (param_len > n)
        +				{
        +				al=SSL_AD_DECODE_ERROR;
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH);
        +				goto f_err;
        +				}
        +			if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL)))
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB);
        +				goto err;
        +				}
        +			if (s->session->srp_username != NULL)
        +				OPENSSL_free(s->session->srp_username);
        +			s->session->srp_username = BUF_strdup(s->srp_ctx.login);
        +			if (s->session->srp_username == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +					ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +
        +			if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
        +				goto err;
        +				}
        +
        +			p+=i;
        +			}
        +		else
        +#endif	/* OPENSSL_NO_SRP */
        +		if (alg_k & SSL_kGOST) 
        +			{
        +			int ret = 0;
        +			EVP_PKEY_CTX *pkey_ctx;
        +			EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
        +			unsigned char premaster_secret[32], *start;
        +			size_t outlen=32, inlen;
        +			unsigned long alg_a;
        +
        +			/* Get our certificate private key*/
        +			alg_a = s->s3->tmp.new_cipher->algorithm_auth;
        +			if (alg_a & SSL_aGOST94)
        +				pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey;
        +			else if (alg_a & SSL_aGOST01)
        +				pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
        +
        +			pkey_ctx = EVP_PKEY_CTX_new(pk,NULL);
        +			EVP_PKEY_decrypt_init(pkey_ctx);
        +			/* If client certificate is present and is of the same type, maybe
        +			 * use it for key exchange.  Don't mind errors from
        +			 * EVP_PKEY_derive_set_peer, because it is completely valid to use
        +			 * a client certificate for authorization only. */
        +			client_pub_pkey = X509_get_pubkey(s->session->peer);
        +			if (client_pub_pkey)
        +				{
        +				if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
        +					ERR_clear_error();
        +				}
        +			/* Decrypt session key */
        +			if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) 
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
        +				goto gerr;
        +				}
        +			if (p[1] == 0x81)
        +				{
        +				start = p+3;
        +				inlen = p[2];
        +				}
        +			else if (p[1] < 0x80)
        +				{
        +				start = p+2;
        +				inlen = p[1];
        +				}
        +			else
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
        +				goto gerr;
        +				}
        +			if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
        +
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
        +				goto gerr;
        +				}
        +			/* Generate master secret */
        +			s->session->master_key_length=
        +				s->method->ssl3_enc->generate_master_secret(s,
        +					s->session->master_key,premaster_secret,32);
        +			/* Check if pubkey from client certificate was used */
        +			if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
        +				ret = 2;
        +			else
        +				ret = 1;
        +		gerr:
        +			EVP_PKEY_free(client_pub_pkey);
        +			EVP_PKEY_CTX_free(pkey_ctx);
        +			if (ret)
        +				return ret;
        +			else
        +				goto err;
        +			}
        +		else
        +		{
        +		al=SSL_AD_HANDSHAKE_FAILURE;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
        +				SSL_R_UNKNOWN_CIPHER_TYPE);
        +		goto f_err;
        +		}
        +
        +	return(1);
        +f_err:
        +	ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
        +err:
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EVP_PKEY_free(clnt_pub_pkey);
        +	EC_POINT_free(clnt_ecpoint);
        +	if (srvr_ecdh != NULL) 
        +		EC_KEY_free(srvr_ecdh);
        +	BN_CTX_free(bn_ctx);
        +#endif
        +	return(-1);
        +	}
        +
        +int ssl3_get_cert_verify(SSL *s)
        +	{
        +	EVP_PKEY *pkey=NULL;
        +	unsigned char *p;
        +	int al,ok,ret=0;
        +	long n;
        +	int type=0,i,j;
        +	X509 *peer;
        +	const EVP_MD *md = NULL;
        +	EVP_MD_CTX mctx;
        +	EVP_MD_CTX_init(&mctx);
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_SR_CERT_VRFY_A,
        +		SSL3_ST_SR_CERT_VRFY_B,
        +		-1,
        +		516, /* Enough for 4096 bit RSA key with TLS v1.2 */
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	if (s->session->peer != NULL)
        +		{
        +		peer=s->session->peer;
        +		pkey=X509_get_pubkey(peer);
        +		type=X509_certificate_type(peer,pkey);
        +		}
        +	else
        +		{
        +		peer=NULL;
        +		pkey=NULL;
        +		}
        +
        +	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
        +		{
        +		s->s3->tmp.reuse_message=1;
        +		if ((peer != NULL) && (type & EVP_PKT_SIGN))
        +			{
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
        +			goto f_err;
        +			}
        +		ret=1;
        +		goto end;
        +		}
        +
        +	if (peer == NULL)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_NO_CLIENT_CERT_RECEIVED);
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		goto f_err;
        +		}
        +
        +	if (!(type & EVP_PKT_SIGN))
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
        +		al=SSL_AD_ILLEGAL_PARAMETER;
        +		goto f_err;
        +		}
        +
        +	if (s->s3->change_cipher_spec)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY);
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		goto f_err;
        +		}
        +
        +	/* we now have a signature that we need to verify */
        +	p=(unsigned char *)s->init_msg;
        +	/* Check for broken implementations of GOST ciphersuites */
        +	/* If key is GOST and n is exactly 64, it is bare
        +	 * signature without length field */
        +	if (n==64 && (pkey->type==NID_id_GostR3410_94 ||
        +		pkey->type == NID_id_GostR3410_2001) )
        +		{
        +		i=64;
        +		} 
        +	else 
        +		{	
        +		if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +			{
        +			int sigalg = tls12_get_sigid(pkey);
        +			/* Should never happen */
        +			if (sigalg == -1)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
        +				al=SSL_AD_INTERNAL_ERROR;
        +				goto f_err;
        +				}
        +			/* Check key type is consistent with signature */
        +			if (sigalg != (int)p[1])
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_TYPE);
        +				al=SSL_AD_DECODE_ERROR;
        +				goto f_err;
        +				}
        +			md = tls12_get_hash(p[0]);
        +			if (md == NULL)
        +				{
        +				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_UNKNOWN_DIGEST);
        +				al=SSL_AD_DECODE_ERROR;
        +				goto f_err;
        +				}
        +#ifdef SSL_DEBUG
        +fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
        +#endif
        +			p += 2;
        +			n -= 2;
        +			}
        +		n2s(p,i);
        +		n-=2;
        +		if (i > n)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH);
        +			al=SSL_AD_DECODE_ERROR;
        +			goto f_err;
        +			}
        +    	}
        +	j=EVP_PKEY_size(pkey);
        +	if ((i > j) || (n > j) || (n <= 0))
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_SIZE);
        +		al=SSL_AD_DECODE_ERROR;
        +		goto f_err;
        +		}
        +
        +	if (TLS1_get_version(s) >= TLS1_2_VERSION)
        +		{
        +		long hdatalen = 0;
        +		void *hdata;
        +		hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
        +		if (hdatalen <= 0)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
        +			al=SSL_AD_INTERNAL_ERROR;
        +			goto f_err;
        +			}
        +#ifdef SSL_DEBUG
        +		fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
        +							EVP_MD_name(md));
        +#endif
        +		if (!EVP_VerifyInit_ex(&mctx, md, NULL)
        +			|| !EVP_VerifyUpdate(&mctx, hdata, hdatalen))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB);
        +			al=SSL_AD_INTERNAL_ERROR;
        +			goto f_err;
        +			}
        +
        +		if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0)
        +			{
        +			al=SSL_AD_DECRYPT_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_SIGNATURE);
        +			goto f_err;
        +			}
        +		}
        +	else
        +#ifndef OPENSSL_NO_RSA 
        +	if (pkey->type == EVP_PKEY_RSA)
        +		{
        +		i=RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
        +			MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, p, i, 
        +							pkey->pkey.rsa);
        +		if (i < 0)
        +			{
        +			al=SSL_AD_DECRYPT_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_DECRYPT);
        +			goto f_err;
        +			}
        +		if (i == 0)
        +			{
        +			al=SSL_AD_DECRYPT_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_SIGNATURE);
        +			goto f_err;
        +			}
        +		}
        +	else
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +		if (pkey->type == EVP_PKEY_DSA)
        +		{
        +		j=DSA_verify(pkey->save_type,
        +			&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
        +			SHA_DIGEST_LENGTH,p,i,pkey->pkey.dsa);
        +		if (j <= 0)
        +			{
        +			/* bad signature */
        +			al=SSL_AD_DECRYPT_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_DSA_SIGNATURE);
        +			goto f_err;
        +			}
        +		}
        +	else
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +		if (pkey->type == EVP_PKEY_EC)
        +		{
        +		j=ECDSA_verify(pkey->save_type,
        +			&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
        +			SHA_DIGEST_LENGTH,p,i,pkey->pkey.ec);
        +		if (j <= 0)
        +			{
        +			/* bad signature */
        +			al=SSL_AD_DECRYPT_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
        +			    SSL_R_BAD_ECDSA_SIGNATURE);
        +			goto f_err;
        +			}
        +		}
        +	else
        +#endif
        +	if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001)
        +		{   unsigned char signature[64];
        +			int idx;
        +			EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey,NULL);
        +			EVP_PKEY_verify_init(pctx);
        +			if (i!=64) {
        +				fprintf(stderr,"GOST signature length is %d",i);
        +			}	
        +			for (idx=0;idx<64;idx++) {
        +				signature[63-idx]=p[idx];
        +			}	
        +			j=EVP_PKEY_verify(pctx,signature,64,s->s3->tmp.cert_verify_md,32);
        +			EVP_PKEY_CTX_free(pctx);
        +			if (j<=0) 
        +				{
        +				al=SSL_AD_DECRYPT_ERROR;
        +				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
        +					SSL_R_BAD_ECDSA_SIGNATURE);
        +				goto f_err;
        +				}	
        +		}
        +	else	
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
        +		al=SSL_AD_UNSUPPORTED_CERTIFICATE;
        +		goto f_err;
        +		}
        +
        +
        +	ret=1;
        +	if (0)
        +		{
        +f_err:
        +		ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +		}
        +end:
        +	if (s->s3->handshake_buffer)
        +		{
        +		BIO_free(s->s3->handshake_buffer);
        +		s->s3->handshake_buffer = NULL;
        +		s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
        +		}
        +	EVP_MD_CTX_cleanup(&mctx);
        +	EVP_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +int ssl3_get_client_certificate(SSL *s)
        +	{
        +	int i,ok,al,ret= -1;
        +	X509 *x=NULL;
        +	unsigned long l,nc,llen,n;
        +	const unsigned char *p,*q;
        +	unsigned char *d;
        +	STACK_OF(X509) *sk=NULL;
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_SR_CERT_A,
        +		SSL3_ST_SR_CERT_B,
        +		-1,
        +		s->max_cert_list,
        +		&ok);
        +
        +	if (!ok) return((int)n);
        +
        +	if	(s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE)
        +		{
        +		if (	(s->verify_mode & SSL_VERIFY_PEER) &&
        +			(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			goto f_err;
        +			}
        +		/* If tls asked for a client cert, the client must return a 0 list */
        +		if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
        +			al=SSL_AD_UNEXPECTED_MESSAGE;
        +			goto f_err;
        +			}
        +		s->s3->tmp.reuse_message=1;
        +		return(1);
        +		}
        +
        +	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)
        +		{
        +		al=SSL_AD_UNEXPECTED_MESSAGE;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE);
        +		goto f_err;
        +		}
        +	p=d=(unsigned char *)s->init_msg;
        +
        +	if ((sk=sk_X509_new_null()) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	n2l3(p,llen);
        +	if (llen+3 != n)
        +		{
        +		al=SSL_AD_DECODE_ERROR;
        +		SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_LENGTH_MISMATCH);
        +		goto f_err;
        +		}
        +	for (nc=0; nc<llen; )
        +		{
        +		n2l3(p,l);
        +		if ((l+nc+3) > llen)
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
        +			goto f_err;
        +			}
        +
        +		q=p;
        +		x=d2i_X509(NULL,&p,l);
        +		if (x == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_ASN1_LIB);
        +			goto err;
        +			}
        +		if (p != (q+l))
        +			{
        +			al=SSL_AD_DECODE_ERROR;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);
        +			goto f_err;
        +			}
        +		if (!sk_X509_push(sk,x))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		x=NULL;
        +		nc+=l+3;
        +		}
        +
        +	if (sk_X509_num(sk) <= 0)
        +		{
        +		/* TLS does not mind 0 certs returned */
        +		if (s->version == SSL3_VERSION)
        +			{
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATES_RETURNED);
        +			goto f_err;
        +			}
        +		/* Fail for TLS only if we required a certificate */
        +		else if ((s->verify_mode & SSL_VERIFY_PEER) &&
        +			 (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
        +			al=SSL_AD_HANDSHAKE_FAILURE;
        +			goto f_err;
        +			}
        +		/* No client certificate so digest cached records */
        +		if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s))
        +			{
        +			al=SSL_AD_INTERNAL_ERROR;
        +			goto f_err;
        +			}
        +		}
        +	else
        +		{
        +		i=ssl_verify_cert_chain(s,sk);
        +		if (i <= 0)
        +			{
        +			al=ssl_verify_alarm_type(s->verify_result);
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED);
        +			goto f_err;
        +			}
        +		}
        +
        +	if (s->session->peer != NULL) /* This should not be needed */
        +		X509_free(s->session->peer);
        +	s->session->peer=sk_X509_shift(sk);
        +	s->session->verify_result = s->verify_result;
        +
        +	/* With the current implementation, sess_cert will always be NULL
        +	 * when we arrive here. */
        +	if (s->session->sess_cert == NULL)
        +		{
        +		s->session->sess_cert = ssl_sess_cert_new();
        +		if (s->session->sess_cert == NULL)
        +			{
        +			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
        +			goto err;
        +			}
        +		}
        +	if (s->session->sess_cert->cert_chain != NULL)
        +		sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
        +	s->session->sess_cert->cert_chain=sk;
        +	/* Inconsistency alert: cert_chain does *not* include the
        +	 * peer's own certificate, while we do include it in s3_clnt.c */
        +
        +	sk=NULL;
        +
        +	ret=1;
        +	if (0)
        +		{
        +f_err:
        +		ssl3_send_alert(s,SSL3_AL_FATAL,al);
        +		}
        +err:
        +	if (x != NULL) X509_free(x);
        +	if (sk != NULL) sk_X509_pop_free(sk,X509_free);
        +	return(ret);
        +	}
        +
        +int ssl3_send_server_certificate(SSL *s)
        +	{
        +	unsigned long l;
        +	X509 *x;
        +
        +	if (s->state == SSL3_ST_SW_CERT_A)
        +		{
        +		x=ssl_get_server_send_cert(s);
        +		if (x == NULL)
        +			{
        +			/* VRS: allow null cert if auth == KRB5 */
        +			if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
        +			    (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5))
        +				{
        +				SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
        +				return(0);
        +				}
        +			}
        +
        +		l=ssl3_output_cert_chain(s,x);
        +		s->state=SSL3_ST_SW_CERT_B;
        +		s->init_num=(int)l;
        +		s->init_off=0;
        +		}
        +
        +	/* SSL3_ST_SW_CERT_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +/* send a new session ticket (not necessarily for a new session) */
        +int ssl3_send_newsession_ticket(SSL *s)
        +	{
        +	if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
        +		{
        +		unsigned char *p, *senc, *macstart;
        +		const unsigned char *const_p;
        +		int len, slen_full, slen;
        +		SSL_SESSION *sess;
        +		unsigned int hlen;
        +		EVP_CIPHER_CTX ctx;
        +		HMAC_CTX hctx;
        +		SSL_CTX *tctx = s->initial_ctx;
        +		unsigned char iv[EVP_MAX_IV_LENGTH];
        +		unsigned char key_name[16];
        +
        +		/* get session encoding length */
        +		slen_full = i2d_SSL_SESSION(s->session, NULL);
        +		/* Some length values are 16 bits, so forget it if session is
        + 		 * too long
        + 		 */
        +		if (slen_full > 0xFF00)
        +			return -1;
        +		senc = OPENSSL_malloc(slen_full);
        +		if (!senc)
        +			return -1;
        +		p = senc;
        +		i2d_SSL_SESSION(s->session, &p);
        +
        +		/* create a fresh copy (not shared with other threads) to clean up */
        +		const_p = senc;
        +		sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
        +		if (sess == NULL)
        +			{
        +			OPENSSL_free(senc);
        +			return -1;
        +			}
        +		sess->session_id_length = 0; /* ID is irrelevant for the ticket */
        +
        +		slen = i2d_SSL_SESSION(sess, NULL);
        +		if (slen > slen_full) /* shouldn't ever happen */
        +			{
        +			OPENSSL_free(senc);
        +			return -1;
        +			}
        +		p = senc;
        +		i2d_SSL_SESSION(sess, &p);
        +		SSL_SESSION_free(sess);
        +
        +		/* Grow buffer if need be: the length calculation is as
        + 		 * follows 1 (size of message name) + 3 (message length
        + 		 * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
        + 		 * 16 (key name) + max_iv_len (iv length) +
        + 		 * session_length + max_enc_block_size (max encrypted session
        + 		 * length) + max_md_size (HMAC).
        + 		 */
        +		if (!BUF_MEM_grow(s->init_buf,
        +			26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
        +			EVP_MAX_MD_SIZE + slen))
        +			return -1;
        +
        +		p=(unsigned char *)s->init_buf->data;
        +		/* do the header */
        +		*(p++)=SSL3_MT_NEWSESSION_TICKET;
        +		/* Skip message length for now */
        +		p += 3;
        +		EVP_CIPHER_CTX_init(&ctx);
        +		HMAC_CTX_init(&hctx);
        +		/* Initialize HMAC and cipher contexts. If callback present
        +		 * it does all the work otherwise use generated values
        +		 * from parent ctx.
        +		 */
        +		if (tctx->tlsext_ticket_key_cb)
        +			{
        +			if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
        +							 &hctx, 1) < 0)
        +				{
        +				OPENSSL_free(senc);
        +				return -1;
        +				}
        +			}
        +		else
        +			{
        +			RAND_pseudo_bytes(iv, 16);
        +			EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
        +					tctx->tlsext_tick_aes_key, iv);
        +			HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
        +					tlsext_tick_md(), NULL);
        +			memcpy(key_name, tctx->tlsext_tick_key_name, 16);
        +			}
        +
        +		/* Ticket lifetime hint (advisory only):
        +		 * We leave this unspecified for resumed session (for simplicity),
        +		 * and guess that tickets for new sessions will live as long
        +		 * as their sessions. */
        +		l2n(s->hit ? 0 : s->session->timeout, p);
        +
        +		/* Skip ticket length for now */
        +		p += 2;
        +		/* Output key name */
        +		macstart = p;
        +		memcpy(p, key_name, 16);
        +		p += 16;
        +		/* output IV */
        +		memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
        +		p += EVP_CIPHER_CTX_iv_length(&ctx);
        +		/* Encrypt session data */
        +		EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
        +		p += len;
        +		EVP_EncryptFinal(&ctx, p, &len);
        +		p += len;
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +
        +		HMAC_Update(&hctx, macstart, p - macstart);
        +		HMAC_Final(&hctx, p, &hlen);
        +		HMAC_CTX_cleanup(&hctx);
        +
        +		p += hlen;
        +		/* Now write out lengths: p points to end of data written */
        +		/* Total length */
        +		len = p - (unsigned char *)s->init_buf->data;
        +		p=(unsigned char *)s->init_buf->data + 1;
        +		l2n3(len - 4, p); /* Message length */
        +		p += 4;
        +		s2n(len - 10, p);  /* Ticket length */
        +
        +		/* number of bytes to write */
        +		s->init_num= len;
        +		s->state=SSL3_ST_SW_SESSION_TICKET_B;
        +		s->init_off=0;
        +		OPENSSL_free(senc);
        +		}
        +
        +	/* SSL3_ST_SW_SESSION_TICKET_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +int ssl3_send_cert_status(SSL *s)
        +	{
        +	if (s->state == SSL3_ST_SW_CERT_STATUS_A)
        +		{
        +		unsigned char *p;
        +		/* Grow buffer if need be: the length calculation is as
        + 		 * follows 1 (message type) + 3 (message length) +
        + 		 * 1 (ocsp response type) + 3 (ocsp response length)
        + 		 * + (ocsp response)
        + 		 */
        +		if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
        +			return -1;
        +
        +		p=(unsigned char *)s->init_buf->data;
        +
        +		/* do the header */
        +		*(p++)=SSL3_MT_CERTIFICATE_STATUS;
        +		/* message length */
        +		l2n3(s->tlsext_ocsp_resplen + 4, p);
        +		/* status type */
        +		*(p++)= s->tlsext_status_type;
        +		/* length of OCSP response */
        +		l2n3(s->tlsext_ocsp_resplen, p);
        +		/* actual response */
        +		memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
        +		/* number of bytes to write */
        +		s->init_num = 8 + s->tlsext_ocsp_resplen;
        +		s->state=SSL3_ST_SW_CERT_STATUS_B;
        +		s->init_off = 0;
        +		}
        +
        +	/* SSL3_ST_SW_CERT_STATUS_B */
        +	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        +	}
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
        + * sets the next_proto member in s if found */
        +int ssl3_get_next_proto(SSL *s)
        +	{
        +	int ok;
        +	int proto_len, padding_len;
        +	long n;
        +	const unsigned char *p;
        +
        +	/* Clients cannot send a NextProtocol message if we didn't see the
        +	 * extension in their ClientHello */
        +	if (!s->s3->next_proto_neg_seen)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
        +		return -1;
        +		}
        +
        +	n=s->method->ssl_get_message(s,
        +		SSL3_ST_SR_NEXT_PROTO_A,
        +		SSL3_ST_SR_NEXT_PROTO_B,
        +		SSL3_MT_NEXT_PROTO,
        +		514,  /* See the payload format below */
        +		&ok);
        +
        +	if (!ok)
        +		return((int)n);
        +
        +	/* s->state doesn't reflect whether ChangeCipherSpec has been received
        +	 * in this handshake, but s->s3->change_cipher_spec does (will be reset
        +	 * by ssl3_get_finished). */
        +	if (!s->s3->change_cipher_spec)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
        +		return -1;
        +		}
        +
        +	if (n < 2)
        +		return 0;  /* The body must be > 1 bytes long */
        +
        +	p=(unsigned char *)s->init_msg;
        +
        +	/* The payload looks like:
        +	 *   uint8 proto_len;
        +	 *   uint8 proto[proto_len];
        +	 *   uint8 padding_len;
        +	 *   uint8 padding[padding_len];
        +	 */
        +	proto_len = p[0];
        +	if (proto_len + 2 > s->init_num)
        +		return 0;
        +	padding_len = p[proto_len + 1];
        +	if (proto_len + padding_len + 2 != s->init_num)
        +		return 0;
        +
        +	s->next_proto_negotiated = OPENSSL_malloc(proto_len);
        +	if (!s->next_proto_negotiated)
        +		{
        +		SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,ERR_R_MALLOC_FAILURE);
        +		return 0;
        +		}
        +	memcpy(s->next_proto_negotiated, p + 1, proto_len);
        +	s->next_proto_negotiated_len = proto_len;
        +
        +	return 1;
        +	}
        +# endif
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/srtp.h b/vendor/openssl/openssl/ssl/srtp.h
        new file mode 100644
        index 000000000..c0cf33ef2
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/srtp.h
        @@ -0,0 +1,145 @@
        +/* ssl/tls1.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 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).
        + *
        + */
        +/*
        +  DTLS code by Eric Rescorla <ekr@rtfm.com>
        +
        +  Copyright (C) 2006, Network Resonance, Inc.
        +  Copyright (C) 2011, RTFM, Inc.
        +*/
        +
        +#ifndef HEADER_D1_SRTP_H
        +#define HEADER_D1_SRTP_H
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +     
        +#define SRTP_AES128_CM_SHA1_80 0x0001
        +#define SRTP_AES128_CM_SHA1_32 0x0002
        +#define SRTP_AES128_F8_SHA1_80 0x0003
        +#define SRTP_AES128_F8_SHA1_32 0x0004
        +#define SRTP_NULL_SHA1_80      0x0005
        +#define SRTP_NULL_SHA1_32      0x0006
        +
        +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
        +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
        +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
        +
        +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
        +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +
        +#endif
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl-lib.com b/vendor/openssl/openssl/ssl/ssl-lib.com
        new file mode 100644
        index 000000000..a77f7707f
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl-lib.com
        @@ -0,0 +1,1214 @@
        +$!
        +$!  SSL-LIB.COM
        +$!  Written By:  Robert Byer
        +$!               Vice-President
        +$!               A-Com Computing, Inc.
        +$!               byer@mail.all-net.net
        +$!
        +$!  Changes by Richard Levitte <richard@levitte.org>
        +$!
        +$!  This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB" 
        +$!  library for OpenSSL.  The "xxx" denotes the machine architecture of
        +$!  ALPHA, IA64 or VAX.
        +$!
        +$!  It is written to detect what type of machine you are compiling on
        +$!  (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC 
        +$!  or GNU C) or you can specify which compiler to use.
        +$!
        +$!  Specify the following as P1 to build just that part or ALL to just
        +$!  build everything.
        +$!
        +$!    		LIBRARY    To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library.
        +$!    		SSL_TASK   To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE
        +$!
        +$!  Specify DEBUG or NODEBUG as P2 to compile with or without debugger
        +$!  information.
        +$!
        +$!  Specify which compiler at P3 to try to compile under.
        +$!
        +$!	   VAXC	 For VAX C.
        +$!	   DECC	 For DEC C.
        +$!	   GNUC	 For GNU C.
        +$!
        +$!  If you don't specify a compiler, it will try to determine which
        +$!  "C" compiler to use.
        +$!
        +$!  P4, if defined, sets a TCP/IP library to use, through one of the following
        +$!  keywords:
        +$!
        +$!	UCX		for UCX
        +$!	TCPIP		for TCPIP (post UCX)
        +$!	SOCKETSHR	for SOCKETSHR+NETLIB
        +$!
        +$!  P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
        +$!
        +$!  P6, if defined, specifies the C pointer size.  Ignored on VAX.
        +$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
        +$!      Supported values are:
        +$!
        +$!      ""       Compile with default (/NOPOINTER_SIZE)
        +$!      32       Compile with /POINTER_SIZE=32 (SHORT)
        +$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
        +$!               (Automatically select ARGV if compiler supports it.)
        +$!      64=      Compile with /POINTER_SIZE=64 (LONG).
        +$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
        +$!
        +$!  P7, if defined, specifies a directory where ZLIB files (zlib.h,
        +$!  libz.olb) may be found.  Optionally, a non-default object library
        +$!  name may be included ("dev:[dir]libz_64.olb", for example).
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$! Define A TCP/IP Library That We Will Need To Link To.
        +$! (That Is, If We Need To Link To One.)
        +$!
        +$ TCPIP_LIB = ""
        +$ ZLIB_LIB = ""
        +$!
        +$! Check What Architecture We Are Using.
        +$!
        +$ IF (F$GETSYI("CPU").LT.128)
        +$ THEN
        +$!
        +$!  The Architecture Is VAX.
        +$!
        +$   ARCH = "VAX"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
        +$!
        +$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
        +$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
        +$!
        +$! End The Architecture Check.
        +$!
        +$ ENDIF
        +$!
        +$ ARCHD = ARCH
        +$ LIB32 = "32"
        +$ OPT_FILE = ""
        +$ POINTER_SIZE = ""
        +$!
        +$! Check To Make Sure We Have Valid Command Line Parameters.
        +$!
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Define The OBJ and EXE Directories.
        +$!
        +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.SSL]
        +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.SSL]
        +$!
        +$! Specify the destination directory in any /MAP option.
        +$!
        +$ if (LINKMAP .eqs. "MAP")
        +$ then
        +$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
        +$ endif
        +$!
        +$! Add the location prefix to the linker options file name.
        +$!
        +$ if (OPT_FILE .nes. "")
        +$ then
        +$   OPT_FILE = EXE_DIR+ OPT_FILE
        +$ endif
        +$!
        +$! Initialise logical names and such
        +$!
        +$ GOSUB INITIALISE
        +$!
        +$! Tell The User What Kind of Machine We Run On.
        +$!
        +$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
        +$!
        +$! Check To See If The Architecture Specific OBJ Directory Exists.
        +$!
        +$ IF (F$PARSE(OBJ_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIR 'OBJ_DIR'
        +$!
        +$! End The Architecture Specific OBJ Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If The Architecture Specific Directory Exists.
        +$!
        +$ IF (F$PARSE(EXE_DIR).EQS."")
        +$ THEN
        +$!
        +$!  It Dosen't Exist, So Create It.
        +$!
        +$   CREATE/DIR 'EXE_DIR'
        +$!
        +$! End The Architecture Specific Directory Check.
        +$!
        +$ ENDIF
        +$!
        +$! Define The Library Name.
        +$!
        +$ SSL_LIB := 'EXE_DIR'SSL_LIBSSL'LIB32'.OLB
        +$!
        +$! Define The CRYPTO-LIB We Are To Use.
        +$!
        +$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
        +$!
        +$! Set up exceptional compilations.
        +$!
        +$ CC5_SHOWN = 0
        +$!
        +$! Check To See What We Are To Do.
        +$!
        +$ IF (BUILDALL.EQS."TRUE")
        +$ THEN
        +$!
        +$!  Since Nothing Special Was Specified, Do Everything.
        +$!
        +$   GOSUB LIBRARY
        +$   GOSUB SSL_TASK
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Build Just What The User Wants Us To Build.
        +$!
        +$   GOSUB 'BUILDALL'
        +$!
        +$! End The BUILDALL Check.
        +$!
        +$ ENDIF
        +$!
        +$! Time To EXIT.
        +$!
        +$ EXIT:
        +$ GOSUB CLEANUP
        +$ EXIT   
        +$!
        +$! Compile The Library.
        +$!
        +$ LIBRARY:
        +$!
        +$! Check To See If We Already Have A "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library...
        +$!
        +$ IF (F$SEARCH(SSL_LIB).EQS."")
        +$ THEN
        +$!
        +$! Guess Not, Create The Library.
        +$!
        +$   LIBRARY/CREATE/OBJECT 'SSL_LIB'
        +$!
        +$! End The Library Exist Check.
        +$!
        +$ ENDIF
        +$!
        +$! Define The Different SSL "library" Files.
        +$!
        +$ LIB_SSL = "s2_meth,s2_srvr,s2_clnt,s2_lib,s2_enc,s2_pkt,"+ -
        +	    "s3_meth,s3_srvr,s3_clnt,s3_lib,s3_enc,s3_pkt,s3_both,"+ -
        +	    "s23_meth,s23_srvr,s23_clnt,s23_lib,s23_pkt,"+ -
        +	    "t1_meth,t1_srvr,t1_clnt,t1_lib,t1_enc,"+ -
        +	    "d1_meth,d1_srvr,d1_clnt,d1_lib,d1_pkt,"+ -
        +	    "d1_both,d1_enc,d1_srtp,"+ -
        +	    "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ -
        +	    "ssl_ciph,ssl_stat,ssl_rsa,"+ -
        +	    "ssl_asn1,ssl_txt,ssl_algs,"+ -
        +	    "bio_ssl,ssl_err,kssl,tls_srp,t1_reneg"
        +$!
        +$ COMPILEWITH_CC5 = ""
        +$!
        +$! Tell The User That We Are Compiling The Library.
        +$!
        +$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library."
        +$!
        +$! Define A File Counter And Set It To "0"
        +$!
        +$ FILE_COUNTER = 0
        +$!
        +$! Top Of The File Loop.
        +$!
        +$ NEXT_FILE:
        +$!
        +$! O.K, Extract The File Name From The File List.
        +$!
        +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_SSL)
        +$!
        +$! Check To See If We Are At The End Of The File List.
        +$!
        +$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
        +$!
        +$! Increment The Counter.
        +$!
        +$ FILE_COUNTER = FILE_COUNTER + 1
        +$!
        +$! Create The Source File Name.
        +$!
        +$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
        +$!
        +$! Create The Object File Name.
        +$!
        +$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
        +$ ON WARNING THEN GOTO NEXT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Is Actually There.
        +$!
        +$ IF (F$SEARCH(SOURCE_FILE).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The File Exists Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What File We Are Compiling.
        +$!
        +$ WRITE SYS$OUTPUT "	",FILE_NAME,".c"
        +$!
        +$! Compile The File.
        +$!
        +$ ON ERROR THEN GOTO NEXT_FILE
        +$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$!
        +$! Add It To The Library.
        +$!
        +$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE'
        +$!
        +$! Time To Clean Up The Object File.
        +$!
        +$ DELETE 'OBJECT_FILE';*
        +$!
        +$! Go Back And Get The Next File Name.
        +$!
        +$ GOTO NEXT_FILE
        +$!
        +$! All Done With This Library.
        +$!
        +$ FILE_DONE:
        +$!
        +$! Tell The User That We Are All Done.
        +$!
        +$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled."
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$ SSL_TASK:
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Is Actually There.
        +$!
        +$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   EXIT
        +$!
        +$! End The SSL_TASK.C File Check.
        +$!
        +$ ENDIF
        +$!
        +$ COMPILEWITH_CC5 = "" !!! ",ssl_task,"
        +$!
        +$! Tell The User We Are Creating The SSL_TASK.
        +$!
        +$! Tell The User We Are Creating The SSL_TASK.
        +$!
        +$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine."	
        +$!
        +$!  Tell The User What File We Are Compiling.
        +$!
        +$ FILE_NAME = "ssl_task"
        +$ WRITE SYS$OUTPUT "	",FILE_NAME,".c"
        +$!
        +$! Compile The File.
        +$!
        +$ ON ERROR THEN GOTO SSL_TASK_END
        +$!
        +$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ ","
        +$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5
        +$ THEN
        +$   if (.not. CC5_SHOWN)
        +$   then
        +$     CC5_SHOWN = 1
        +$     write sys$output "        \Using special rule (5)"
        +$     x = "    "+ CC5
        +$     write /symbol sys$output x
        +$   endif
        +$   CC5 /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C
        +$ ELSE
        +$   CC /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C
        +$ ENDIF
        +$!
        +$! Link The Program.
        +$!
        +$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_DIR'SSL_TASK.EXE -
        +   'OBJ_DIR'SSL_TASK.OBJ, -
        +   'SSL_LIB'/LIBRARY, -
        +   'CRYPTO_LIB'/LIBRARY -
        +   'TCPIP_LIB' -
        +   'ZLIB_LIB' -
        +   ,'OPT_FILE' /OPTIONS
        +$!
        +$! Time To Return.
        +$!
        +$SSL_TASK_END:
        +$ RETURN
        +$!
        +$! Check For The Link Option FIle.
        +$!
        +$ CHECK_OPT_FILE:
        +$!
        +$! Check To See If We Need To Make A VAX C Option File.
        +$!
        +$ IF (COMPILER.EQS."VAXC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A VAX C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A VAX C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable VAX C Runtime Library.
        +!
        +SYS$SHARE:VAXCRTL.EXE/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The VAXC Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A GNU C Option File.
        +$!
        +$ IF (COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A GNU C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A GNU C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +GNU_CC:[000000]GCCLIB/LIBRARY
        +SYS$SHARE:VAXCRTL/SHARE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The GNU C Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A DEC C Option File.
        +$!
        +$ IF (COMPILER.EQS."DECC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A DEC C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
        +$!
        +$     IF (ARCH.EQS."VAX")
        +$     THEN
        +$!
        +$!      We Need A DEC C Linker Option File For VAX.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable DEC C Runtime Library.
        +!
        +SYS$SHARE:DECC$SHR.EXE/SHARE
        +$EOD
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Create The non-VAX Linker Option File.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File For non-VAX To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
        +SYS$SHARE:CMA$OPEN_RTL/SHARE
        +$EOD
        +$!
        +$!    End The DEC C Option File Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The Option File Search.
        +$!
        +$   ENDIF
        +$!
        +$! End The DEC C Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What Linker Option File We Are Using.
        +$!
        +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$ LIB_CHECK:
        +$!
        +$! Look For The VAX Library LIBSSL.OLB.
        +$!
        +$ IF (F$SEARCH(SSL_LIB).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User We Can't Find The LIBSSL.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
        +$   WRITE SYS$OUTPUT "We Can't Link Without It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$!
        +$! End The LIBSSL.OLB Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Look For The Library LIBCRYPTO.OLB.
        +$!
        +$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
        +$   WRITE SYS$OUTPUT "We Can't Link Without It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$!
        +$! End The LIBCRYPTO.OLB Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Time To Return.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Check To See If P1 Is Blank.
        +$!
        +$ IF (P1.EQS."ALL")
        +$ THEN
        +$!
        +$!   P1 Is Blank, So Build Everything.
        +$!
        +$    BUILDALL = "TRUE"
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Else, Check To See If P1 Has A Valid Argument.
        +$!
        +$   IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK")
        +$   THEN
        +$!
        +$!    A Valid Argument.
        +$!
        +$     BUILDALL = P1
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User We Don't Know What They Want.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALL      :  Just Build Everything."
        +$     WRITE SYS$OUTPUT "    LIBRARY  :  To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
        +$     WRITE SYS$OUTPUT "    SSL_TASK :  To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    ALPHA[64]:  Alpha Architecture."
        +$     WRITE SYS$OUTPUT "    IA64[64] :  IA64 Architecture."
        +$     WRITE SYS$OUTPUT "    VAX      :  VAX Architecture."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P1 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If P2 Is Blank.
        +$!
        +$ IF (P2.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!  P2 Is NODEBUG, So Compile Without Debugger Information.
        +$!
        +$   DEBUGGER  = "NODEBUG"
        +$   LINKMAP = "NOMAP"
        +$   TRACEBACK = "NOTRACEBACK" 
        +$   GCC_OPTIMIZE = "OPTIMIZE"
        +$   CC_OPTIMIZE = "OPTIMIZE"
        +$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
        +$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (P2.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER  = "DEBUG"
        +$     LINKMAP = "MAP"
        +$     TRACEBACK = "TRACEBACK"
        +$     GCC_OPTIMIZE = "NOOPTIMIZE"
        +$     CC_OPTIMIZE = "NOOPTIMIZE"
        +$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
        +$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
        +$   ELSE
        +$!
        +$!    Tell The User Entered An Invalid Option.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P2 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For P5.
        +$!
        +$ IF (P5.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN :=
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P5 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check P6 (POINTER_SIZE).
        +$!
        +$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX")
        +$ THEN
        +$!
        +$   IF (P6 .EQS. "32")
        +$   THEN
        +$     POINTER_SIZE = " /POINTER_SIZE=32"
        +$   ELSE
        +$     POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE")
        +$     IF ((POINTER_SIZE .EQS. "64") .OR. -
        +       (POINTER_SIZE .EQS. "64=") .OR. -
        +       (POINTER_SIZE .EQS. "64=ARGV"))
        +$     THEN
        +$       ARCHD = ARCH+ "_64"
        +$       LIB32 = ""
        +$       POINTER_SIZE = " /POINTER_SIZE=64"
        +$     ELSE
        +$!
        +$!      Tell The User Entered An Invalid Option.
        +$!
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", P6, -
        +         " Is Invalid.  The Valid Options Are:"
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT -
        +         "    """"       :  Compile with default (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    32       :  Compile with 32-bit (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
        +$       WRITE SYS$OUTPUT ""
        +$! 
        +$!      Time To EXIT.
        +$!
        +$       EXIT
        +$!
        +$     ENDIF
        +$!
        +$   ENDIF
        +$!
        +$! End The P6 (POINTER_SIZE) Check.
        +$!
        +$ ENDIF
        +$!
        +$! Set basic C compiler /INCLUDE directories.
        +$!
        +$ CC_INCLUDES = "SYS$DISK:[-.CRYPTO],SYS$DISK:[-]"
        +$!
        +$! Check To See If P3 Is Blank.
        +$!
        +$ IF (P3.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     P3 = "GNUC"
        +$!
        +$!  End The GNU C Compiler Check.
        +$!
        +$   ELSE
        +$!
        +$!  Check To See If We Have VAXC Or DECC.
        +$!
        +$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
        +$     THEN 
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       P3 = "DECC"
        +$!
        +$!      Else...
        +$!
        +$     ELSE
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       P3 = "VAXC"
        +$!
        +$!    End The VAXC Compiler Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  End The Compiler Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Have A Option For P4.
        +$!
        +$ IF (P4.EQS."")
        +$ THEN
        +$!
        +$!  Find out what socket library we have available
        +$!
        +$   IF F$PARSE("SOCKETSHR:") .NES. ""
        +$   THEN
        +$!
        +$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
        +$!
        +$     P4 = "SOCKETSHR"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
        +$!
        +$!    Else, let's look for something else
        +$!
        +$   ELSE
        +$!
        +$!    Like UCX (the reason to do this before Multinet is that the UCX
        +$!    emulation is easier to use...)
        +$!
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
        +	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
        +	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
        +$     THEN
        +$!
        +$!	Last resort: a UCX or UCX-compatible library
        +$!
        +$	P4 = "UCX"
        +$!
        +$!      Tell the user
        +$!
        +$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
        +$!
        +$!	That was all...
        +$!
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Set Up Initial CC Definitions, Possibly With User Ones
        +$!
        +$ CCDEFS = "TCPIP_TYPE_''P4'"
        +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
        +$ CCEXTRAFLAGS = ""
        +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
        +$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
        +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
        +	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
        +$!
        +$! Check To See If We Have A ZLIB Option.
        +$!
        +$ ZLIB = P7
        +$ IF (ZLIB .NES. "")
        +$ THEN
        +$!
        +$!  Check for expected ZLIB files.
        +$!
        +$   err = 0
        +$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
        +$   if (f$search( file1) .eqs. "")
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
        +$     err = 1
        +$   endif
        +$   file1 = f$parse( "A.;", ZLIB)- "A.;"
        +$!
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     if (err .eq. 0)
        +$     then
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     endif
        +$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
        +$     WRITE SYS$OUTPUT ""
        +$     err = err+ 2
        +$   endif
        +$   if (err .eq. 1)
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$   endif
        +$!
        +$   if (err .ne. 0)
        +$   then
        +$     EXIT
        +$   endif
        +$!
        +$   CCDEFS = """ZLIB=1"", "+ CCDEFS
        +$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
        +$   ZLIB_LIB = ", ''file2' /library"
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
        +$!
        +$! End The ZLIB Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Check To See If The User Entered A Valid Parameter.
        +$!
        +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If The User Wanted DECC.
        +$!
        +$   IF (P3.EQS."DECC")
        +$   THEN
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    Use DECC...
        +$!
        +$     CC = "CC"
        +$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
        +	 THEN CC = "CC/DECC"
        +$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
        +       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
        +       " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
        +$!
        +$!  End DECC Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use VAXC.
        +$!
        +$   IF (P3.EQS."VAXC")
        +$   THEN
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$!
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    Compile Using VAXC.
        +$!
        +$     CC = "CC"
        +$     IF ARCH.NES."VAX"
        +$     THEN
        +$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
        +$	EXIT
        +$     ENDIF
        +$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
        +$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
        +$     CCDEFS = CCDEFS + ",""VAXC"""
        +$!
        +$!    Define <sys> As SYS$COMMON:[SYSLIB]
        +$!
        +$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
        +$!
        +$!  End VAXC Check
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use GNU C.
        +$!
        +$   IF (P3.EQS."GNUC")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    Use GNU C...
        +$!
        +$     IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
        +$     CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
        +$!
        +$!  End The GNU C Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Set up default defines
        +$!
        +$   CCDEFS = """FLAT_INC=1""," + CCDEFS
        +$!
        +$!  Finish up the definition of CC.
        +$!
        +$   IF COMPILER .EQS. "DECC"
        +$   THEN
        +$     IF CCDISABLEWARNINGS .EQS. ""
        +$     THEN
        +$       CC4DISABLEWARNINGS = "DOLLARID"
        +$     ELSE
        +$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
        +$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
        +$     ENDIF
        +$     CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
        +$   ELSE
        +$     CCDISABLEWARNINGS = ""
        +$     CC4DISABLEWARNINGS = ""
        +$   ENDIF
        +$   CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
        +$   CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
        +$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
        +$   IF COMPILER .EQS. "DECC"
        +$   THEN
        +$     CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
        +$     CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
        +$   ELSE
        +$     CC4 = CC
        +$     CC5 = CC3
        +$   ENDIF
        +$!
        +$!  Show user the result
        +$!
        +$   WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$ ENDIF
        +$!
        +$! Time to check the contents, and to make sure we get the correct library.
        +$!
        +$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
        +     .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
        +$ THEN
        +$!
        +$!  Check to see if SOCKETSHR was chosen
        +$!
        +$   IF P4.EQS."SOCKETSHR"
        +$   THEN
        +$!
        +$!    Set the library to use SOCKETSHR
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
        +$!
        +$!    Done with SOCKETSHR
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if MULTINET was chosen
        +$!
        +$   IF P4.EQS."MULTINET"
        +$   THEN
        +$!
        +$!    Set the library to use UCX emulation.
        +$!
        +$     P4 = "UCX"
        +$!
        +$!    Done with MULTINET
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if UCX was chosen
        +$!
        +$   IF P4.EQS."UCX"
        +$   THEN
        +$!
        +$!    Set the library to use UCX.
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
        +$     THEN
        +$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
        +$     ELSE
        +$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
        +	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
        +$     ENDIF
        +$!
        +$!    Done with UCX
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if TCPIP was chosen
        +$!
        +$   IF P4.EQS."TCPIP"
        +$   THEN
        +$!
        +$!    Set the library to use TCPIP (post UCX).
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if NONE was chosen
        +$!
        +$   IF P4.EQS."NONE"
        +$   THEN
        +$!
        +$!    Do not use a TCPIP library.
        +$!
        +$     TCPIP_LIB = ""
        +$!
        +$!    Done with NONE
        +$!
        +$   ENDIF
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P4," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
        +$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
        +$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$!  Done with TCP/IP libraries
        +$!
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        +$!
        +$ INITIALISE:
        +$!
        +$! Save old value of the logical name OPENSSL
        +$!
        +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
        +$!
        +$! Save directory information
        +$!
        +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
        +$ __HERE = F$EDIT(__HERE,"UPCASE")
        +$ __TOP = __HERE - "SSL]"
        +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
        +$!
        +$! Set up the logical name OPENSSL to point at the include directory
        +$!
        +$ DEFINE OPENSSL/NOLOG '__INCLUDE'
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        +$ CLEANUP:
        +$!
        +$! Restore the logical name OPENSSL if it had a value
        +$!
        +$ IF __SAVE_OPENSSL .EQS. ""
        +$ THEN
        +$   DEASSIGN OPENSSL
        +$ ELSE
        +$   DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
        +$ ENDIF
        +$!
        +$! Done
        +$!
        +$ RETURN
        diff --git a/vendor/openssl/openssl/ssl/ssl.h b/vendor/openssl/openssl/ssl/ssl.h
        new file mode 100644
        index 000000000..593579ed3
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl.h
        @@ -0,0 +1,2579 @@
        +/* ssl/ssl.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#ifndef HEADER_SSL_H 
        +#define HEADER_SSL_H 
        +
        +#include <openssl/e_os2.h>
        +
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +#include <openssl/bio.h>
        +#endif
        +#ifndef OPENSSL_NO_DEPRECATED
        +#ifndef OPENSSL_NO_X509
        +#include <openssl/x509.h>
        +#endif
        +#include <openssl/crypto.h>
        +#include <openssl/lhash.h>
        +#include <openssl/buffer.h>
        +#endif
        +#include <openssl/pem.h>
        +#include <openssl/hmac.h>
        +
        +#include <openssl/kssl.h>
        +#include <openssl/safestack.h>
        +#include <openssl/symhacks.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* SSLeay version number for ASN.1 encoding of the session information */
        +/* Version 0 - initial version
        + * Version 1 - added the optional peer certificate
        + */
        +#define SSL_SESSION_ASN1_VERSION 0x0001
        +
        +/* text strings for the ciphers */
        +#define SSL_TXT_NULL_WITH_MD5		SSL2_TXT_NULL_WITH_MD5			
        +#define SSL_TXT_RC4_128_WITH_MD5	SSL2_TXT_RC4_128_WITH_MD5		
        +#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	
        +#define SSL_TXT_RC2_128_CBC_WITH_MD5	SSL2_TXT_RC2_128_CBC_WITH_MD5		
        +#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	
        +#define SSL_TXT_IDEA_128_CBC_WITH_MD5	SSL2_TXT_IDEA_128_CBC_WITH_MD5		
        +#define SSL_TXT_DES_64_CBC_WITH_MD5	SSL2_TXT_DES_64_CBC_WITH_MD5		
        +#define SSL_TXT_DES_64_CBC_WITH_SHA	SSL2_TXT_DES_64_CBC_WITH_SHA		
        +#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	
        +#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	
        +
        +/*    VRS Additional Kerberos5 entries
        + */
        +#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
        +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
        +#define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
        +#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
        +#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5       
        +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5       
        +#define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
        +#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 
        +
        +#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA 
        +#define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA 
        +#define SSL_TXT_KRB5_RC4_40_SHA	      SSL3_TXT_KRB5_RC4_40_SHA
        +#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5 
        +#define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5 
        +#define SSL_TXT_KRB5_RC4_40_MD5	      SSL3_TXT_KRB5_RC4_40_MD5
        +
        +#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
        +#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
        +#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
        +#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
        +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
        +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
        +#define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256
        +
        +#define SSL_MAX_SSL_SESSION_ID_LENGTH		32
        +#define SSL_MAX_SID_CTX_LENGTH			32
        +
        +#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES	(512/8)
        +#define SSL_MAX_KEY_ARG_LENGTH			8
        +#define SSL_MAX_MASTER_KEY_LENGTH		48
        +
        +
        +/* These are used to specify which ciphers to use and not to use */
        +
        +#define SSL_TXT_EXP40		"EXPORT40"
        +#define SSL_TXT_EXP56		"EXPORT56"
        +#define SSL_TXT_LOW		"LOW"
        +#define SSL_TXT_MEDIUM		"MEDIUM"
        +#define SSL_TXT_HIGH		"HIGH"
        +#define SSL_TXT_FIPS		"FIPS"
        +
        +#define SSL_TXT_kFZA		"kFZA" /* unused! */
        +#define	SSL_TXT_aFZA		"aFZA" /* unused! */
        +#define SSL_TXT_eFZA		"eFZA" /* unused! */
        +#define SSL_TXT_FZA		"FZA"  /* unused! */
        +
        +#define	SSL_TXT_aNULL		"aNULL"
        +#define	SSL_TXT_eNULL		"eNULL"
        +#define	SSL_TXT_NULL		"NULL"
        +
        +#define SSL_TXT_kRSA		"kRSA"
        +#define SSL_TXT_kDHr		"kDHr" /* no such ciphersuites supported! */
        +#define SSL_TXT_kDHd		"kDHd" /* no such ciphersuites supported! */
        +#define SSL_TXT_kDH 		"kDH"  /* no such ciphersuites supported! */
        +#define SSL_TXT_kEDH		"kEDH"
        +#define SSL_TXT_kKRB5     	"kKRB5"
        +#define SSL_TXT_kECDHr		"kECDHr"
        +#define SSL_TXT_kECDHe		"kECDHe"
        +#define SSL_TXT_kECDH		"kECDH"
        +#define SSL_TXT_kEECDH		"kEECDH"
        +#define SSL_TXT_kPSK            "kPSK"
        +#define SSL_TXT_kGOST		"kGOST"
        +#define SSL_TXT_kSRP		"kSRP"
        +
        +#define	SSL_TXT_aRSA		"aRSA"
        +#define	SSL_TXT_aDSS		"aDSS"
        +#define	SSL_TXT_aDH		"aDH" /* no such ciphersuites supported! */
        +#define	SSL_TXT_aECDH		"aECDH"
        +#define SSL_TXT_aKRB5     	"aKRB5"
        +#define SSL_TXT_aECDSA		"aECDSA"
        +#define SSL_TXT_aPSK            "aPSK"
        +#define SSL_TXT_aGOST94	"aGOST94"
        +#define SSL_TXT_aGOST01 "aGOST01"
        +#define SSL_TXT_aGOST  "aGOST"
        +
        +#define	SSL_TXT_DSS		"DSS"
        +#define SSL_TXT_DH		"DH"
        +#define SSL_TXT_EDH		"EDH" /* same as "kEDH:-ADH" */
        +#define SSL_TXT_ADH		"ADH"
        +#define SSL_TXT_RSA		"RSA"
        +#define SSL_TXT_ECDH		"ECDH"
        +#define SSL_TXT_EECDH		"EECDH" /* same as "kEECDH:-AECDH" */
        +#define SSL_TXT_AECDH		"AECDH"
        +#define SSL_TXT_ECDSA		"ECDSA"
        +#define SSL_TXT_KRB5      	"KRB5"
        +#define SSL_TXT_PSK             "PSK"
        +#define SSL_TXT_SRP		"SRP"
        +
        +#define SSL_TXT_DES		"DES"
        +#define SSL_TXT_3DES		"3DES"
        +#define SSL_TXT_RC4		"RC4"
        +#define SSL_TXT_RC2		"RC2"
        +#define SSL_TXT_IDEA		"IDEA"
        +#define SSL_TXT_SEED		"SEED"
        +#define SSL_TXT_AES128		"AES128"
        +#define SSL_TXT_AES256		"AES256"
        +#define SSL_TXT_AES		"AES"
        +#define SSL_TXT_AES_GCM		"AESGCM"
        +#define SSL_TXT_CAMELLIA128	"CAMELLIA128"
        +#define SSL_TXT_CAMELLIA256	"CAMELLIA256"
        +#define SSL_TXT_CAMELLIA	"CAMELLIA"
        +
        +#define SSL_TXT_MD5		"MD5"
        +#define SSL_TXT_SHA1		"SHA1"
        +#define SSL_TXT_SHA		"SHA" /* same as "SHA1" */
        +#define SSL_TXT_GOST94		"GOST94" 
        +#define SSL_TXT_GOST89MAC		"GOST89MAC" 
        +#define SSL_TXT_SHA256		"SHA256"
        +#define SSL_TXT_SHA384		"SHA384"
        +
        +#define SSL_TXT_SSLV2		"SSLv2"
        +#define SSL_TXT_SSLV3		"SSLv3"
        +#define SSL_TXT_TLSV1		"TLSv1"
        +#define SSL_TXT_TLSV1_1		"TLSv1.1"
        +#define SSL_TXT_TLSV1_2		"TLSv1.2"
        +
        +#define SSL_TXT_EXP		"EXP"
        +#define SSL_TXT_EXPORT		"EXPORT"
        +
        +#define SSL_TXT_ALL		"ALL"
        +
        +/*
        + * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
        + * ciphers normally not being used.
        + * Example: "RC4" will activate all ciphers using RC4 including ciphers
        + * without authentication, which would normally disabled by DEFAULT (due
        + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
        + * will make sure that it is also disabled in the specific selection.
        + * COMPLEMENTOF* identifiers are portable between version, as adjustments
        + * to the default cipher setup will also be included here.
        + *
        + * COMPLEMENTOFDEFAULT does not experience the same special treatment that
        + * DEFAULT gets, as only selection is being done and no sorting as needed
        + * for DEFAULT.
        + */
        +#define SSL_TXT_CMPALL		"COMPLEMENTOFALL"
        +#define SSL_TXT_CMPDEF		"COMPLEMENTOFDEFAULT"
        +
        +/* The following cipher list is used by default.
        + * It also is substituted when an application-defined cipher list string
        + * starts with 'DEFAULT'. */
        +#define SSL_DEFAULT_CIPHER_LIST	"ALL:!aNULL:!eNULL:!SSLv2"
        +/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
        + * starts with a reasonable order, and all we have to do for DEFAULT is
        + * throwing out anonymous and unencrypted ciphersuites!
        + * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable
        + * some of them.)
        + */
        +
        +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
        +#define SSL_SENT_SHUTDOWN	1
        +#define SSL_RECEIVED_SHUTDOWN	2
        +
        +#ifdef __cplusplus
        +}
        +#endif
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
        +#define OPENSSL_NO_SSL2
        +#endif
        +
        +#define SSL_FILETYPE_ASN1	X509_FILETYPE_ASN1
        +#define SSL_FILETYPE_PEM	X509_FILETYPE_PEM
        +
        +/* This is needed to stop compilers complaining about the
        + * 'struct ssl_st *' function parameters used to prototype callbacks
        + * in SSL_CTX. */
        +typedef struct ssl_st *ssl_crock_st;
        +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
        +typedef struct ssl_method_st SSL_METHOD;
        +typedef struct ssl_cipher_st SSL_CIPHER;
        +typedef struct ssl_session_st SSL_SESSION;
        +
        +DECLARE_STACK_OF(SSL_CIPHER)
        +
        +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
        +typedef struct srtp_protection_profile_st
        +       {
        +       const char *name;
        +       unsigned long id;
        +       } SRTP_PROTECTION_PROFILE;
        +
        +DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
        +
        +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
        +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
        +
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +/* used to hold info on the particular ciphers used */
        +struct ssl_cipher_st
        +	{
        +	int valid;
        +	const char *name;		/* text name */
        +	unsigned long id;		/* id, 4 bytes, first is version */
        +
        +	/* changed in 0.9.9: these four used to be portions of a single value 'algorithms' */
        +	unsigned long algorithm_mkey;	/* key exchange algorithm */
        +	unsigned long algorithm_auth;	/* server authentication */
        +	unsigned long algorithm_enc;	/* symmetric encryption */
        +	unsigned long algorithm_mac;	/* symmetric authentication */
        +	unsigned long algorithm_ssl;	/* (major) protocol version */
        +
        +	unsigned long algo_strength;	/* strength and export flags */
        +	unsigned long algorithm2;	/* Extra flags */
        +	int strength_bits;		/* Number of bits really used */
        +	int alg_bits;			/* Number of bits for algorithm */
        +	};
        +
        +
        +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
        +struct ssl_method_st
        +	{
        +	int version;
        +	int (*ssl_new)(SSL *s);
        +	void (*ssl_clear)(SSL *s);
        +	void (*ssl_free)(SSL *s);
        +	int (*ssl_accept)(SSL *s);
        +	int (*ssl_connect)(SSL *s);
        +	int (*ssl_read)(SSL *s,void *buf,int len);
        +	int (*ssl_peek)(SSL *s,void *buf,int len);
        +	int (*ssl_write)(SSL *s,const void *buf,int len);
        +	int (*ssl_shutdown)(SSL *s);
        +	int (*ssl_renegotiate)(SSL *s);
        +	int (*ssl_renegotiate_check)(SSL *s);
        +	long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
        +		max, int *ok);
        +	int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, 
        +		int peek);
        +	int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
        +	int (*ssl_dispatch_alert)(SSL *s);
        +	long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
        +	long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
        +	const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
        +	int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
        +	int (*ssl_pending)(const SSL *s);
        +	int (*num_ciphers)(void);
        +	const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
        +	const struct ssl_method_st *(*get_ssl_method)(int version);
        +	long (*get_timeout)(void);
        +	struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
        +	int (*ssl_version)(void);
        +	long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
        +	long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
        +	};
        +
        +/* Lets make this into an ASN.1 type structure as follows
        + * SSL_SESSION_ID ::= SEQUENCE {
        + *	version 		INTEGER,	-- structure version number
        + *	SSLversion 		INTEGER,	-- SSL version number
        + *	Cipher 			OCTET STRING,	-- the 3 byte cipher ID
        + *	Session_ID 		OCTET STRING,	-- the Session ID
        + *	Master_key 		OCTET STRING,	-- the master key
        + *	KRB5_principal		OCTET STRING	-- optional Kerberos principal
        + *	Key_Arg [ 0 ] IMPLICIT	OCTET STRING,	-- the optional Key argument
        + *	Time [ 1 ] EXPLICIT	INTEGER,	-- optional Start Time
        + *	Timeout [ 2 ] EXPLICIT	INTEGER,	-- optional Timeout ins seconds
        + *	Peer [ 3 ] EXPLICIT	X509,		-- optional Peer Certificate
        + *	Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
        + *	Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
        + *	HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension 
        + *	PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
        + *	PSK_identity [ 8 ] EXPLICIT OCTET STRING,  -- optional PSK identity
        + *	Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket
        + *	Ticket [10]             EXPLICIT OCTET STRING, -- session ticket (clients only)
        + *	Compression_meth [11]   EXPLICIT OCTET STRING, -- optional compression method
        + *	SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username
        + *	}
        + * Look in ssl/ssl_asn1.c for more details
        + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
        + */
        +struct ssl_session_st
        +	{
        +	int ssl_version;	/* what ssl version session info is
        +				 * being kept in here? */
        +
        +	/* only really used in SSLv2 */
        +	unsigned int key_arg_length;
        +	unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
        +	int master_key_length;
        +	unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
        +	/* session_id - valid? */
        +	unsigned int session_id_length;
        +	unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
        +	/* this is used to determine whether the session is being reused in
        +	 * the appropriate context. It is up to the application to set this,
        +	 * via SSL_new */
        +	unsigned int sid_ctx_length;
        +	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
        +
        +#ifndef OPENSSL_NO_KRB5
        +        unsigned int krb5_client_princ_len;
        +        unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
        +#endif /* OPENSSL_NO_KRB5 */
        +#ifndef OPENSSL_NO_PSK
        +	char *psk_identity_hint;
        +	char *psk_identity;
        +#endif
        +	/* Used to indicate that session resumption is not allowed.
        +	 * Applications can also set this bit for a new session via
        +	 * not_resumable_session_cb to disable session caching and tickets. */
        +	int not_resumable;
        +
        +	/* The cert is the certificate used to establish this connection */
        +	struct sess_cert_st /* SESS_CERT */ *sess_cert;
        +
        +	/* This is the cert for the other end.
        +	 * On clients, it will be the same as sess_cert->peer_key->x509
        +	 * (the latter is not enough as sess_cert is not retained
        +	 * in the external representation of sessions, see ssl_asn1.c). */
        +	X509 *peer;
        +	/* when app_verify_callback accepts a session where the peer's certificate
        +	 * is not ok, we must remember the error for session reuse: */
        +	long verify_result; /* only for servers */
        +
        +	int references;
        +	long timeout;
        +	long time;
        +
        +	unsigned int compress_meth;	/* Need to lookup the method */
        +
        +	const SSL_CIPHER *cipher;
        +	unsigned long cipher_id;	/* when ASN.1 loaded, this
        +					 * needs to be used to load
        +					 * the 'cipher' structure */
        +
        +	STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
        +
        +	CRYPTO_EX_DATA ex_data; /* application specific data */
        +
        +	/* These are used to make removal of session-ids more
        +	 * efficient and to implement a maximum cache size. */
        +	struct ssl_session_st *prev,*next;
        +#ifndef OPENSSL_NO_TLSEXT
        +	char *tlsext_hostname;
        +#ifndef OPENSSL_NO_EC
        +	size_t tlsext_ecpointformatlist_length;
        +	unsigned char *tlsext_ecpointformatlist; /* peer's list */
        +	size_t tlsext_ellipticcurvelist_length;
        +	unsigned char *tlsext_ellipticcurvelist; /* peer's list */
        +#endif /* OPENSSL_NO_EC */
        +	/* RFC4507 info */
        +	unsigned char *tlsext_tick;	/* Session ticket */
        +	size_t tlsext_ticklen;		/* Session ticket length */
        +	long tlsext_tick_lifetime_hint;	/* Session lifetime hint in seconds */
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	char *srp_username;
        +#endif
        +	};
        +
        +#endif
        +
        +#define SSL_OP_MICROSOFT_SESS_ID_BUG			0x00000001L
        +#define SSL_OP_NETSCAPE_CHALLENGE_BUG			0x00000002L
        +/* Allow initial connection to servers that don't support RI */
        +#define SSL_OP_LEGACY_SERVER_CONNECT			0x00000004L
        +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L
        +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
        +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
        +#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x00000040L /* no effect since 0.9.7h and 0.9.8b */
        +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x00000080L
        +#define SSL_OP_TLS_D5_BUG				0x00000100L
        +#define SSL_OP_TLS_BLOCK_PADDING_BUG			0x00000200L
        +
        +/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
        + * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
        + * the workaround is not needed.  Unfortunately some broken SSL/TLS
        + * implementations cannot handle it at all, which is why we include
        + * it in SSL_OP_ALL. */
        +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
        +
        +/* SSL_OP_ALL: various bug workarounds that should be rather harmless.
        + *             This used to be 0x000FFFFFL before 0.9.7. */
        +#define SSL_OP_ALL					0x80000BFFL
        +
        +/* DTLS options */
        +#define SSL_OP_NO_QUERY_MTU                 0x00001000L
        +/* Turn on Cookie Exchange (on relevant for servers) */
        +#define SSL_OP_COOKIE_EXCHANGE              0x00002000L
        +/* Don't use RFC4507 ticket extension */
        +#define SSL_OP_NO_TICKET	            0x00004000L
        +/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client)  */
        +#define SSL_OP_CISCO_ANYCONNECT		    0x00008000L
        +
        +/* As server, disallow session resumption on renegotiation */
        +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
        +/* Don't use compression even if supported */
        +#define SSL_OP_NO_COMPRESSION				0x00020000L
        +/* Permit unsafe legacy renegotiation */
        +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION	0x00040000L
        +/* If set, always create a new key when using tmp_ecdh parameters */
        +#define SSL_OP_SINGLE_ECDH_USE				0x00080000L
        +/* If set, always create a new key when using tmp_dh parameters */
        +#define SSL_OP_SINGLE_DH_USE				0x00100000L
        +/* Set to always use the tmp_rsa key when doing RSA operations,
        + * even when this violates protocol specs */
        +#define SSL_OP_EPHEMERAL_RSA				0x00200000L
        +/* Set on servers to choose the cipher according to the server's
        + * preferences */
        +#define SSL_OP_CIPHER_SERVER_PREFERENCE			0x00400000L
        +/* If set, a server will allow a client to issue a SSLv3.0 version number
        + * as latest version supported in the premaster secret, even when TLSv1.0
        + * (version 3.1) was announced in the client hello. Normally this is
        + * forbidden to prevent version rollback attacks. */
        +#define SSL_OP_TLS_ROLLBACK_BUG				0x00800000L
        +
        +#define SSL_OP_NO_SSLv2					0x01000000L
        +#define SSL_OP_NO_SSLv3					0x02000000L
        +#define SSL_OP_NO_TLSv1					0x04000000L
        +#define SSL_OP_NO_TLSv1_2				0x08000000L
        +#define SSL_OP_NO_TLSv1_1				0x10000000L
        +
        +/* These next two were never actually used for anything since SSLeay
        + * zap so we have some more flags.
        + */
        +/* The next flag deliberately changes the ciphertest, this is a check
        + * for the PKCS#1 attack */
        +#define SSL_OP_PKCS1_CHECK_1				0x0
        +#define SSL_OP_PKCS1_CHECK_2				0x0
        +
        +#define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
        +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
        +/* Make server add server-hello extension from early version of
        + * cryptopro draft, when GOST ciphersuite is negotiated. 
        + * Required for interoperability with CryptoPro CSP 3.x 
        + */
        +#define SSL_OP_CRYPTOPRO_TLSEXT_BUG			0x80000000L
        +
        +/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
        + * when just a single record has been written): */
        +#define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
        +/* Make it possible to retry SSL_write() with changed buffer location
        + * (buffer contents must stay the same!); this is not the default to avoid
        + * the misconception that non-blocking SSL_write() behaves like
        + * non-blocking write(): */
        +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
        +/* Never bother the application with retries if the transport
        + * is blocking: */
        +#define SSL_MODE_AUTO_RETRY 0x00000004L
        +/* Don't attempt to automatically build certificate chain */
        +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
        +/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and
        + * TLS only.)  "Released" buffers are put onto a free-list in the context
        + * or just freed (depending on the context's setting for freelist_max_len). */
        +#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
        +
        +/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
        + * they cannot be used to clear bits. */
        +
        +#define SSL_CTX_set_options(ctx,op) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
        +#define SSL_CTX_clear_options(ctx,op) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
        +#define SSL_CTX_get_options(ctx) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
        +#define SSL_set_options(ssl,op) \
        +	SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
        +#define SSL_clear_options(ssl,op) \
        +	SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
        +#define SSL_get_options(ssl) \
        +        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
        +
        +#define SSL_CTX_set_mode(ctx,op) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
        +#define SSL_CTX_clear_mode(ctx,op) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
        +#define SSL_CTX_get_mode(ctx) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
        +#define SSL_clear_mode(ssl,op) \
        +	SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
        +#define SSL_set_mode(ssl,op) \
        +	SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
        +#define SSL_get_mode(ssl) \
        +        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
        +#define SSL_set_mtu(ssl, mtu) \
        +        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
        +
        +#define SSL_get_secure_renegotiation_support(ssl) \
        +	SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +#define SSL_heartbeat(ssl) \
        +        SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL)
        +#endif
        +
        +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
        +void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
        +#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
        +#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
        +
        +#ifndef OPENSSL_NO_SRP
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +typedef struct srp_ctx_st
        +	{
        +	/* param for all the callbacks */
        +	void *SRP_cb_arg;
        +	/* set client Hello login callback */
        +	int (*TLS_ext_srp_username_callback)(SSL *, int *, void *);
        +	/* set SRP N/g param callback for verification */
        +	int (*SRP_verify_param_callback)(SSL *, void *);
        +	/* set SRP client passwd callback */
        +	char *(*SRP_give_srp_client_pwd_callback)(SSL *, void *);
        +
        +	char *login;
        +	BIGNUM *N,*g,*s,*B,*A;
        +	BIGNUM *a,*b,*v;
        +	char *info;
        +	int strength;
        +
        +	unsigned long srp_Mask;
        +	} SRP_CTX;
        +
        +#endif
        +
        +/* see tls_srp.c */
        +int SSL_SRP_CTX_init(SSL *s);
        +int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
        +int SSL_SRP_CTX_free(SSL *ctx);
        +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
        +int SSL_srp_server_param_with_username(SSL *s, int *ad);
        +int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key);
        +int SRP_Calc_A_param(SSL *s);
        +int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key);
        +
        +#endif
        +
        +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
        +#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
        +#else
        +#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */
        +#endif
        +
        +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT	(1024*20)
        +
        +/* This callback type is used inside SSL_CTX, SSL, and in the functions that set
        + * them. It is used to override the generation of SSL/TLS session IDs in a
        + * server. Return value should be zero on an error, non-zero to proceed. Also,
        + * callbacks should themselves check if the id they generate is unique otherwise
        + * the SSL handshake will fail with an error - callbacks can do this using the
        + * 'ssl' value they're passed by;
        + *      SSL_has_matching_session_id(ssl, id, *id_len)
        + * The length value passed in is set at the maximum size the session ID can be.
        + * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
        + * can alter this length to be less if desired, but under SSLv2 session IDs are
        + * supposed to be fixed at 16 bytes so the id will be padded after the callback
        + * returns in this case. It is also an error for the callback to set the size to
        + * zero. */
        +typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
        +				unsigned int *id_len);
        +
        +typedef struct ssl_comp_st SSL_COMP;
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +struct ssl_comp_st
        +	{
        +	int id;
        +	const char *name;
        +#ifndef OPENSSL_NO_COMP
        +	COMP_METHOD *method;
        +#else
        +	char *method;
        +#endif
        +	};
        +
        +DECLARE_STACK_OF(SSL_COMP)
        +DECLARE_LHASH_OF(SSL_SESSION);
        +
        +struct ssl_ctx_st
        +	{
        +	const SSL_METHOD *method;
        +
        +	STACK_OF(SSL_CIPHER) *cipher_list;
        +	/* same as above but sorted for lookup */
        +	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
        +
        +	struct x509_store_st /* X509_STORE */ *cert_store;
        +	LHASH_OF(SSL_SESSION) *sessions;
        +	/* Most session-ids that will be cached, default is
        +	 * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
        +	unsigned long session_cache_size;
        +	struct ssl_session_st *session_cache_head;
        +	struct ssl_session_st *session_cache_tail;
        +
        +	/* This can have one of 2 values, ored together,
        +	 * SSL_SESS_CACHE_CLIENT,
        +	 * SSL_SESS_CACHE_SERVER,
        +	 * Default is SSL_SESSION_CACHE_SERVER, which means only
        +	 * SSL_accept which cache SSL_SESSIONS. */
        +	int session_cache_mode;
        +
        +	/* If timeout is not 0, it is the default timeout value set
        +	 * when SSL_new() is called.  This has been put in to make
        +	 * life easier to set things up */
        +	long session_timeout;
        +
        +	/* If this callback is not null, it will be called each
        +	 * time a session id is added to the cache.  If this function
        +	 * returns 1, it means that the callback will do a
        +	 * SSL_SESSION_free() when it has finished using it.  Otherwise,
        +	 * on 0, it means the callback has finished with it.
        +	 * If remove_session_cb is not null, it will be called when
        +	 * a session-id is removed from the cache.  After the call,
        +	 * OpenSSL will SSL_SESSION_free() it. */
        +	int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess);
        +	void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess);
        +	SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl,
        +		unsigned char *data,int len,int *copy);
        +
        +	struct
        +		{
        +		int sess_connect;	/* SSL new conn - started */
        +		int sess_connect_renegotiate;/* SSL reneg - requested */
        +		int sess_connect_good;	/* SSL new conne/reneg - finished */
        +		int sess_accept;	/* SSL new accept - started */
        +		int sess_accept_renegotiate;/* SSL reneg - requested */
        +		int sess_accept_good;	/* SSL accept/reneg - finished */
        +		int sess_miss;		/* session lookup misses  */
        +		int sess_timeout;	/* reuse attempt on timeouted session */
        +		int sess_cache_full;	/* session removed due to full cache */
        +		int sess_hit;		/* session reuse actually done */
        +		int sess_cb_hit;	/* session-id that was not
        +					 * in the cache was
        +					 * passed back via the callback.  This
        +					 * indicates that the application is
        +					 * supplying session-id's from other
        +					 * processes - spooky :-) */
        +		} stats;
        +
        +	int references;
        +
        +	/* if defined, these override the X509_verify_cert() calls */
        +	int (*app_verify_callback)(X509_STORE_CTX *, void *);
        +	void *app_verify_arg;
        +	/* before OpenSSL 0.9.7, 'app_verify_arg' was ignored
        +	 * ('app_verify_callback' was called with just one argument) */
        +
        +	/* Default password callback. */
        +	pem_password_cb *default_passwd_callback;
        +
        +	/* Default password callback user data. */
        +	void *default_passwd_callback_userdata;
        +
        +	/* get client cert callback */
        +	int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
        +
        +    /* cookie generate callback */
        +    int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, 
        +        unsigned int *cookie_len);
        +
        +    /* verify cookie callback */
        +    int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, 
        +        unsigned int cookie_len);
        +
        +	CRYPTO_EX_DATA ex_data;
        +
        +	const EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */
        +	const EVP_MD *md5;	/* For SSLv3/TLSv1 'ssl3-md5' */
        +	const EVP_MD *sha1;   /* For SSLv3/TLSv1 'ssl3->sha1' */
        +
        +	STACK_OF(X509) *extra_certs;
        +	STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
        +
        +
        +	/* Default values used when no per-SSL value is defined follow */
        +
        +	void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */
        +
        +	/* what we put in client cert requests */
        +	STACK_OF(X509_NAME) *client_CA;
        +
        +
        +	/* Default values to use in SSL structures follow (these are copied by SSL_new) */
        +
        +	unsigned long options;
        +	unsigned long mode;
        +	long max_cert_list;
        +
        +	struct cert_st /* CERT */ *cert;
        +	int read_ahead;
        +
        +	/* callback that allows applications to peek at protocol messages */
        +	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
        +	void *msg_callback_arg;
        +
        +	int verify_mode;
        +	unsigned int sid_ctx_length;
        +	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
        +	int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
        +
        +	/* Default generate session ID callback. */
        +	GEN_SESSION_CB generate_session_id;
        +
        +	X509_VERIFY_PARAM *param;
        +
        +#if 0
        +	int purpose;		/* Purpose setting */
        +	int trust;		/* Trust setting */
        +#endif
        +
        +	int quiet_shutdown;
        +
        +	/* Maximum amount of data to send in one fragment.
        +	 * actual record size can be more than this due to
        +	 * padding and MAC overheads.
        +	 */
        +	unsigned int max_send_fragment;
        +
        +#ifndef OPENSSL_ENGINE
        +	/* Engine to pass requests for client certs to
        +	 */
        +	ENGINE *client_cert_engine;
        +#endif
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	/* TLS extensions servername callback */
        +	int (*tlsext_servername_callback)(SSL*, int *, void *);
        +	void *tlsext_servername_arg;
        +	/* RFC 4507 session ticket keys */
        +	unsigned char tlsext_tick_key_name[16];
        +	unsigned char tlsext_tick_hmac_key[16];
        +	unsigned char tlsext_tick_aes_key[16];
        +	/* Callback to support customisation of ticket key setting */
        +	int (*tlsext_ticket_key_cb)(SSL *ssl,
        +					unsigned char *name, unsigned char *iv,
        +					EVP_CIPHER_CTX *ectx,
        + 					HMAC_CTX *hctx, int enc);
        +
        +	/* certificate status request info */
        +	/* Callback for status request */
        +	int (*tlsext_status_cb)(SSL *ssl, void *arg);
        +	void *tlsext_status_arg;
        +
        +	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
        +	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
        +	void *tlsext_opaque_prf_input_callback_arg;
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +	char *psk_identity_hint;
        +	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
        +		unsigned int max_identity_len, unsigned char *psk,
        +		unsigned int max_psk_len);
        +	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
        +		unsigned char *psk, unsigned int max_psk_len);
        +#endif
        +
        +#ifndef OPENSSL_NO_BUF_FREELISTS
        +#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
        +	unsigned int freelist_max_len;
        +	struct ssl3_buf_freelist_st *wbuf_freelist;
        +	struct ssl3_buf_freelist_st *rbuf_freelist;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	SRP_CTX srp_ctx; /* ctx for SRP authentication */
        +#endif
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	/* Next protocol negotiation information */
        +	/* (for experimental NPN extension). */
        +
        +	/* For a server, this contains a callback function by which the set of
        +	 * advertised protocols can be provided. */
        +	int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
        +			                 unsigned int *len, void *arg);
        +	void *next_protos_advertised_cb_arg;
        +	/* For a client, this contains a callback function that selects the
        +	 * next protocol from the list provided by the server. */
        +	int (*next_proto_select_cb)(SSL *s, unsigned char **out,
        +				    unsigned char *outlen,
        +				    const unsigned char *in,
        +				    unsigned int inlen,
        +				    void *arg);
        +	void *next_proto_select_cb_arg;
        +# endif
        +        /* SRTP profiles we are willing to do from RFC 5764 */
        +        STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;  
        +#endif
        +	};
        +
        +#endif
        +
        +#define SSL_SESS_CACHE_OFF			0x0000
        +#define SSL_SESS_CACHE_CLIENT			0x0001
        +#define SSL_SESS_CACHE_SERVER			0x0002
        +#define SSL_SESS_CACHE_BOTH	(SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
        +#define SSL_SESS_CACHE_NO_AUTO_CLEAR		0x0080
        +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
        +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP	0x0100
        +#define SSL_SESS_CACHE_NO_INTERNAL_STORE	0x0200
        +#define SSL_SESS_CACHE_NO_INTERNAL \
        +	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
        +
        +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
        +#define SSL_CTX_sess_number(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
        +#define SSL_CTX_sess_connect(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
        +#define SSL_CTX_sess_connect_good(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
        +#define SSL_CTX_sess_connect_renegotiate(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
        +#define SSL_CTX_sess_accept(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
        +#define SSL_CTX_sess_accept_renegotiate(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
        +#define SSL_CTX_sess_accept_good(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
        +#define SSL_CTX_sess_hits(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
        +#define SSL_CTX_sess_cb_hits(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
        +#define SSL_CTX_sess_misses(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
        +#define SSL_CTX_sess_timeouts(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
        +#define SSL_CTX_sess_cache_full(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
        +
        +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
        +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
        +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess));
        +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
        +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,int len,int *copy));
        +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *Data, int len, int *copy);
        +void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,int val));
        +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
        +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
        +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
        +#ifndef OPENSSL_NO_ENGINE
        +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
        +#endif
        +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
        +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
        +					   int (*cb) (SSL *ssl,
        +						      const unsigned char **out,
        +						      unsigned int *outlen,
        +						      void *arg),
        +					   void *arg);
        +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
        +				      int (*cb) (SSL *ssl,
        +						 unsigned char **out,
        +						 unsigned char *outlen,
        +						 const unsigned char *in,
        +						 unsigned int inlen,
        +						 void *arg),
        +				      void *arg);
        +
        +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
        +			  const unsigned char *in, unsigned int inlen,
        +			  const unsigned char *client, unsigned int client_len);
        +void SSL_get0_next_proto_negotiated(const SSL *s,
        +				    const unsigned char **data, unsigned *len);
        +
        +#define OPENSSL_NPN_UNSUPPORTED	0
        +#define OPENSSL_NPN_NEGOTIATED	1
        +#define OPENSSL_NPN_NO_OVERLAP	2
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +/* the maximum length of the buffer given to callbacks containing the
        + * resulting identity/psk */
        +#define PSK_MAX_IDENTITY_LEN 128
        +#define PSK_MAX_PSK_LEN 256
        +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, 
        +	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
        +		char *identity, unsigned int max_identity_len, unsigned char *psk,
        +		unsigned int max_psk_len));
        +void SSL_set_psk_client_callback(SSL *ssl, 
        +	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
        +		char *identity, unsigned int max_identity_len, unsigned char *psk,
        +		unsigned int max_psk_len));
        +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 
        +	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
        +		unsigned char *psk, unsigned int max_psk_len));
        +void SSL_set_psk_server_callback(SSL *ssl,
        +	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
        +		unsigned char *psk, unsigned int max_psk_len));
        +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
        +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
        +const char *SSL_get_psk_identity_hint(const SSL *s);
        +const char *SSL_get_psk_identity(const SSL *s);
        +#endif
        +
        +#define SSL_NOTHING	1
        +#define SSL_WRITING	2
        +#define SSL_READING	3
        +#define SSL_X509_LOOKUP	4
        +
        +/* These will only be used when doing non-blocking IO */
        +#define SSL_want_nothing(s)	(SSL_want(s) == SSL_NOTHING)
        +#define SSL_want_read(s)	(SSL_want(s) == SSL_READING)
        +#define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
        +#define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
        +
        +#define SSL_MAC_FLAG_READ_MAC_STREAM 1
        +#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +struct ssl_st
        +	{
        +	/* protocol version
        +	 * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION)
        +	 */
        +	int version;
        +	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
        +
        +	const SSL_METHOD *method; /* SSLv3 */
        +
        +	/* There are 2 BIO's even though they are normally both the
        +	 * same.  This is so data can be read and written to different
        +	 * handlers */
        +
        +#ifndef OPENSSL_NO_BIO
        +	BIO *rbio; /* used by SSL_read */
        +	BIO *wbio; /* used by SSL_write */
        +	BIO *bbio; /* used during session-id reuse to concatenate
        +		    * messages */
        +#else
        +	char *rbio; /* used by SSL_read */
        +	char *wbio; /* used by SSL_write */
        +	char *bbio;
        +#endif
        +	/* This holds a variable that indicates what we were doing
        +	 * when a 0 or -1 is returned.  This is needed for
        +	 * non-blocking IO so we know what request needs re-doing when
        +	 * in SSL_accept or SSL_connect */
        +	int rwstate;
        +
        +	/* true when we are actually in SSL_accept() or SSL_connect() */
        +	int in_handshake;
        +	int (*handshake_func)(SSL *);
        +
        +	/* Imagine that here's a boolean member "init" that is
        +	 * switched as soon as SSL_set_{accept/connect}_state
        +	 * is called for the first time, so that "state" and
        +	 * "handshake_func" are properly initialized.  But as
        +	 * handshake_func is == 0 until then, we use this
        +	 * test instead of an "init" member.
        +	 */
        +
        +	int server;	/* are we the server side? - mostly used by SSL_clear*/
        +
        +	int new_session;/* Generate a new session or reuse an old one.
        +	                 * NB: For servers, the 'new' session may actually be a previously
        +	                 * cached session or even the previous session unless
        +	                 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
        +	int quiet_shutdown;/* don't send shutdown packets */
        +	int shutdown;	/* we have shut things down, 0x01 sent, 0x02
        +			 * for received */
        +	int state;	/* where we are */
        +	int rstate;	/* where we are when reading */
        +
        +	BUF_MEM *init_buf;	/* buffer used during init */
        +	void *init_msg;   	/* pointer to handshake message body, set by ssl3_get_message() */
        +	int init_num;		/* amount read/written */
        +	int init_off;		/* amount read/written */
        +
        +	/* used internally to point at a raw packet */
        +	unsigned char *packet;
        +	unsigned int packet_length;
        +
        +	struct ssl2_state_st *s2; /* SSLv2 variables */
        +	struct ssl3_state_st *s3; /* SSLv3 variables */
        +	struct dtls1_state_st *d1; /* DTLSv1 variables */
        +
        +	int read_ahead;		/* Read as many input bytes as possible
        +	               	 	 * (for non-blocking reads) */
        +
        +	/* callback that allows applications to peek at protocol messages */
        +	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
        +	void *msg_callback_arg;
        +
        +	int hit;		/* reusing a previous session */
        +
        +	X509_VERIFY_PARAM *param;
        +
        +#if 0
        +	int purpose;		/* Purpose setting */
        +	int trust;		/* Trust setting */
        +#endif
        +
        +	/* crypto */
        +	STACK_OF(SSL_CIPHER) *cipher_list;
        +	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
        +
        +	/* These are the ones being used, the ones in SSL_SESSION are
        +	 * the ones to be 'copied' into these ones */
        +	int mac_flags; 
        +	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
        +	EVP_MD_CTX *read_hash;		/* used for mac generation */
        +#ifndef OPENSSL_NO_COMP
        +	COMP_CTX *expand;			/* uncompress */
        +#else
        +	char *expand;
        +#endif
        +
        +	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
        +	EVP_MD_CTX *write_hash;		/* used for mac generation */
        +#ifndef OPENSSL_NO_COMP
        +	COMP_CTX *compress;			/* compression */
        +#else
        +	char *compress;	
        +#endif
        +
        +	/* session info */
        +
        +	/* client cert? */
        +	/* This is used to hold the server certificate used */
        +	struct cert_st /* CERT */ *cert;
        +
        +	/* the session_id_context is used to ensure sessions are only reused
        +	 * in the appropriate context */
        +	unsigned int sid_ctx_length;
        +	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
        +
        +	/* This can also be in the session once a session is established */
        +	SSL_SESSION *session;
        +
        +	/* Default generate session ID callback. */
        +	GEN_SESSION_CB generate_session_id;
        +
        +	/* Used in SSL2 and SSL3 */
        +	int verify_mode;	/* 0 don't care about verify failure.
        +				 * 1 fail if verify fails */
        +	int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */
        +
        +	void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */
        +
        +	int error;		/* error bytes to be written */
        +	int error_code;		/* actual code */
        +
        +#ifndef OPENSSL_NO_KRB5
        +	KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */
        +#endif	/* OPENSSL_NO_KRB5 */
        +
        +#ifndef OPENSSL_NO_PSK
        +	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
        +		unsigned int max_identity_len, unsigned char *psk,
        +		unsigned int max_psk_len);
        +	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
        +		unsigned char *psk, unsigned int max_psk_len);
        +#endif
        +
        +	SSL_CTX *ctx;
        +	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
        +	 * and SSL_write() calls, good for nbio debuging :-) */
        +	int debug;	
        +
        +	/* extra application data */
        +	long verify_result;
        +	CRYPTO_EX_DATA ex_data;
        +
        +	/* for server side, keep the list of CA_dn we can use */
        +	STACK_OF(X509_NAME) *client_CA;
        +
        +	int references;
        +	unsigned long options; /* protocol behaviour */
        +	unsigned long mode; /* API behaviour */
        +	long max_cert_list;
        +	int first_packet;
        +	int client_version;	/* what was passed, used for
        +				 * SSLv3/TLS rollback check */
        +	unsigned int max_send_fragment;
        +#ifndef OPENSSL_NO_TLSEXT
        +	/* TLS extension debug callback */
        +	void (*tlsext_debug_cb)(SSL *s, int client_server, int type,
        +					unsigned char *data, int len,
        +					void *arg);
        +	void *tlsext_debug_arg;
        +	char *tlsext_hostname;
        +	int servername_done;   /* no further mod of servername 
        +	                          0 : call the servername extension callback.
        +	                          1 : prepare 2, allow last ack just after in server callback.
        +	                          2 : don't call servername callback, no ack in server hello
        +	                       */
        +	/* certificate status request info */
        +	/* Status type or -1 if no status type */
        +	int tlsext_status_type;
        +	/* Expect OCSP CertificateStatus message */
        +	int tlsext_status_expected;
        +	/* OCSP status request only */
        +	STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
        +	X509_EXTENSIONS *tlsext_ocsp_exts;
        +	/* OCSP response received or to be sent */
        +	unsigned char *tlsext_ocsp_resp;
        +	int tlsext_ocsp_resplen;
        +
        +	/* RFC4507 session ticket expected to be received or sent */
        +	int tlsext_ticket_expected;
        +#ifndef OPENSSL_NO_EC
        +	size_t tlsext_ecpointformatlist_length;
        +	unsigned char *tlsext_ecpointformatlist; /* our list */
        +	size_t tlsext_ellipticcurvelist_length;
        +	unsigned char *tlsext_ellipticcurvelist; /* our list */
        +#endif /* OPENSSL_NO_EC */
        +
        +	/* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */
        +	void *tlsext_opaque_prf_input;
        +	size_t tlsext_opaque_prf_input_len;
        +
        +	/* TLS Session Ticket extension override */
        +	TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
        +
        +	/* TLS Session Ticket extension callback */
        +	tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
        +	void *tls_session_ticket_ext_cb_arg;
        +
        +	/* TLS pre-shared secret session resumption */
        +	tls_session_secret_cb_fn tls_session_secret_cb;
        +	void *tls_session_secret_cb_arg;
        +
        +	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	/* Next protocol negotiation. For the client, this is the protocol that
        +	 * we sent in NextProtocol and is set when handling ServerHello
        +	 * extensions.
        +	 *
        +	 * For a server, this is the client's selected_protocol from
        +	 * NextProtocol and is set when handling the NextProtocol message,
        +	 * before the Finished message. */
        +	unsigned char *next_proto_negotiated;
        +	unsigned char next_proto_negotiated_len;
        +#endif
        +
        +#define session_ctx initial_ctx
        +
        +	STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;  /* What we'll do */
        +	SRTP_PROTECTION_PROFILE *srtp_profile;            /* What's been chosen */
        +
        +	unsigned int tlsext_heartbeat;  /* Is use of the Heartbeat extension negotiated?
        +	                                   0: disabled
        +	                                   1: enabled
        +	                                   2: enabled, but not allowed to send Requests
        +	                                 */
        +	unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */
        +	unsigned int tlsext_hb_seq;     /* HeartbeatRequest sequence number */
        +#else
        +#define session_ctx ctx
        +#endif /* OPENSSL_NO_TLSEXT */
        +
        +	int renegotiate;/* 1 if we are renegotiating.
        +	                 * 2 if we are a server and are inside a handshake
        +	                 * (i.e. not just sending a HelloRequest) */
        +
        +#ifndef OPENSSL_NO_SRP
        +	SRP_CTX srp_ctx; /* ctx for SRP authentication */
        +#endif
        +	};
        +
        +#endif
        +
        +#ifdef __cplusplus
        +}
        +#endif
        +
        +#include <openssl/ssl2.h>
        +#include <openssl/ssl3.h>
        +#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
        +#include <openssl/dtls1.h> /* Datagram TLS */
        +#include <openssl/ssl23.h>
        +#include <openssl/srtp.h>  /* Support for the use_srtp extension */
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* compatibility */
        +#define SSL_set_app_data(s,arg)		(SSL_set_ex_data(s,0,(char *)arg))
        +#define SSL_get_app_data(s)		(SSL_get_ex_data(s,0))
        +#define SSL_SESSION_set_app_data(s,a)	(SSL_SESSION_set_ex_data(s,0,(char *)a))
        +#define SSL_SESSION_get_app_data(s)	(SSL_SESSION_get_ex_data(s,0))
        +#define SSL_CTX_get_app_data(ctx)	(SSL_CTX_get_ex_data(ctx,0))
        +#define SSL_CTX_set_app_data(ctx,arg)	(SSL_CTX_set_ex_data(ctx,0,(char *)arg))
        +
        +/* The following are the possible values for ssl->state are are
        + * used to indicate where we are up to in the SSL connection establishment.
        + * The macros that follow are about the only things you should need to use
        + * and even then, only when using non-blocking IO.
        + * It can also be useful to work out where you were when the connection
        + * failed */
        +
        +#define SSL_ST_CONNECT			0x1000
        +#define SSL_ST_ACCEPT			0x2000
        +#define SSL_ST_MASK			0x0FFF
        +#define SSL_ST_INIT			(SSL_ST_CONNECT|SSL_ST_ACCEPT)
        +#define SSL_ST_BEFORE			0x4000
        +#define SSL_ST_OK			0x03
        +#define SSL_ST_RENEGOTIATE		(0x04|SSL_ST_INIT)
        +
        +#define SSL_CB_LOOP			0x01
        +#define SSL_CB_EXIT			0x02
        +#define SSL_CB_READ			0x04
        +#define SSL_CB_WRITE			0x08
        +#define SSL_CB_ALERT			0x4000 /* used in callback */
        +#define SSL_CB_READ_ALERT		(SSL_CB_ALERT|SSL_CB_READ)
        +#define SSL_CB_WRITE_ALERT		(SSL_CB_ALERT|SSL_CB_WRITE)
        +#define SSL_CB_ACCEPT_LOOP		(SSL_ST_ACCEPT|SSL_CB_LOOP)
        +#define SSL_CB_ACCEPT_EXIT		(SSL_ST_ACCEPT|SSL_CB_EXIT)
        +#define SSL_CB_CONNECT_LOOP		(SSL_ST_CONNECT|SSL_CB_LOOP)
        +#define SSL_CB_CONNECT_EXIT		(SSL_ST_CONNECT|SSL_CB_EXIT)
        +#define SSL_CB_HANDSHAKE_START		0x10
        +#define SSL_CB_HANDSHAKE_DONE		0x20
        +
        +/* Is the SSL_connection established? */
        +#define SSL_get_state(a)		SSL_state(a)
        +#define SSL_is_init_finished(a)		(SSL_state(a) == SSL_ST_OK)
        +#define SSL_in_init(a)			(SSL_state(a)&SSL_ST_INIT)
        +#define SSL_in_before(a)		(SSL_state(a)&SSL_ST_BEFORE)
        +#define SSL_in_connect_init(a)		(SSL_state(a)&SSL_ST_CONNECT)
        +#define SSL_in_accept_init(a)		(SSL_state(a)&SSL_ST_ACCEPT)
        +
        +/* The following 2 states are kept in ssl->rstate when reads fail,
        + * you should not need these */
        +#define SSL_ST_READ_HEADER			0xF0
        +#define SSL_ST_READ_BODY			0xF1
        +#define SSL_ST_READ_DONE			0xF2
        +
        +/* Obtain latest Finished message
        + *   -- that we sent (SSL_get_finished)
        + *   -- that we expected from peer (SSL_get_peer_finished).
        + * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
        +size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
        +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
        +
        +/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options
        + * are 'ored' with SSL_VERIFY_PEER if they are desired */
        +#define SSL_VERIFY_NONE			0x00
        +#define SSL_VERIFY_PEER			0x01
        +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT	0x02
        +#define SSL_VERIFY_CLIENT_ONCE		0x04
        +
        +#define OpenSSL_add_ssl_algorithms()	SSL_library_init()
        +#define SSLeay_add_ssl_algorithms()	SSL_library_init()
        +
        +/* this is for backward compatibility */
        +#if 0 /* NEW_SSLEAY */
        +#define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
        +#define SSL_set_pref_cipher(c,n)	SSL_set_cipher_list(c,n)
        +#define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
        +#define SSL_remove_session(a,b)		SSL_CTX_remove_session((a),(b))
        +#define SSL_flush_sessions(a,b)		SSL_CTX_flush_sessions((a),(b))
        +#endif
        +/* More backward compatibility */
        +#define SSL_get_cipher(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))
        +#define SSL_get_cipher_name(s) \
        +		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
        +#define SSL_get_time(a)		SSL_SESSION_get_time(a)
        +#define SSL_set_time(a,b)	SSL_SESSION_set_time((a),(b))
        +#define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
        +#define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
        +
        +#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
        +#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
        +
        +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
        +
        +#define SSL_AD_REASON_OFFSET		1000 /* offset to get SSL_R_... value from SSL_AD_... */
        +
        +/* These alert types are for SSLv3 and TLSv1 */
        +#define SSL_AD_CLOSE_NOTIFY		SSL3_AD_CLOSE_NOTIFY
        +#define SSL_AD_UNEXPECTED_MESSAGE	SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
        +#define SSL_AD_BAD_RECORD_MAC		SSL3_AD_BAD_RECORD_MAC     /* fatal */
        +#define SSL_AD_DECRYPTION_FAILED	TLS1_AD_DECRYPTION_FAILED
        +#define SSL_AD_RECORD_OVERFLOW		TLS1_AD_RECORD_OVERFLOW
        +#define SSL_AD_DECOMPRESSION_FAILURE	SSL3_AD_DECOMPRESSION_FAILURE/* fatal */
        +#define SSL_AD_HANDSHAKE_FAILURE	SSL3_AD_HANDSHAKE_FAILURE/* fatal */
        +#define SSL_AD_NO_CERTIFICATE		SSL3_AD_NO_CERTIFICATE /* Not for TLS */
        +#define SSL_AD_BAD_CERTIFICATE		SSL3_AD_BAD_CERTIFICATE
        +#define SSL_AD_UNSUPPORTED_CERTIFICATE	SSL3_AD_UNSUPPORTED_CERTIFICATE
        +#define SSL_AD_CERTIFICATE_REVOKED	SSL3_AD_CERTIFICATE_REVOKED
        +#define SSL_AD_CERTIFICATE_EXPIRED	SSL3_AD_CERTIFICATE_EXPIRED
        +#define SSL_AD_CERTIFICATE_UNKNOWN	SSL3_AD_CERTIFICATE_UNKNOWN
        +#define SSL_AD_ILLEGAL_PARAMETER	SSL3_AD_ILLEGAL_PARAMETER   /* fatal */
        +#define SSL_AD_UNKNOWN_CA		TLS1_AD_UNKNOWN_CA	/* fatal */
        +#define SSL_AD_ACCESS_DENIED		TLS1_AD_ACCESS_DENIED	/* fatal */
        +#define SSL_AD_DECODE_ERROR		TLS1_AD_DECODE_ERROR	/* fatal */
        +#define SSL_AD_DECRYPT_ERROR		TLS1_AD_DECRYPT_ERROR
        +#define SSL_AD_EXPORT_RESTRICTION	TLS1_AD_EXPORT_RESTRICTION/* fatal */
        +#define SSL_AD_PROTOCOL_VERSION		TLS1_AD_PROTOCOL_VERSION /* fatal */
        +#define SSL_AD_INSUFFICIENT_SECURITY	TLS1_AD_INSUFFICIENT_SECURITY/* fatal */
        +#define SSL_AD_INTERNAL_ERROR		TLS1_AD_INTERNAL_ERROR	/* fatal */
        +#define SSL_AD_USER_CANCELLED		TLS1_AD_USER_CANCELLED
        +#define SSL_AD_NO_RENEGOTIATION		TLS1_AD_NO_RENEGOTIATION
        +#define SSL_AD_UNSUPPORTED_EXTENSION	TLS1_AD_UNSUPPORTED_EXTENSION
        +#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
        +#define SSL_AD_UNRECOGNIZED_NAME	TLS1_AD_UNRECOGNIZED_NAME
        +#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
        +#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
        +#define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
        +
        +#define SSL_ERROR_NONE			0
        +#define SSL_ERROR_SSL			1
        +#define SSL_ERROR_WANT_READ		2
        +#define SSL_ERROR_WANT_WRITE		3
        +#define SSL_ERROR_WANT_X509_LOOKUP	4
        +#define SSL_ERROR_SYSCALL		5 /* look at error stack/return value/errno */
        +#define SSL_ERROR_ZERO_RETURN		6
        +#define SSL_ERROR_WANT_CONNECT		7
        +#define SSL_ERROR_WANT_ACCEPT		8
        +
        +#define SSL_CTRL_NEED_TMP_RSA			1
        +#define SSL_CTRL_SET_TMP_RSA			2
        +#define SSL_CTRL_SET_TMP_DH			3
        +#define SSL_CTRL_SET_TMP_ECDH			4
        +#define SSL_CTRL_SET_TMP_RSA_CB			5
        +#define SSL_CTRL_SET_TMP_DH_CB			6
        +#define SSL_CTRL_SET_TMP_ECDH_CB		7
        +
        +#define SSL_CTRL_GET_SESSION_REUSED		8
        +#define SSL_CTRL_GET_CLIENT_CERT_REQUEST	9
        +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS		10
        +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS	11
        +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS	12
        +#define SSL_CTRL_GET_FLAGS			13
        +#define SSL_CTRL_EXTRA_CHAIN_CERT		14
        +
        +#define SSL_CTRL_SET_MSG_CALLBACK               15
        +#define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
        +
        +/* only applies to datagram connections */
        +#define SSL_CTRL_SET_MTU                17
        +/* Stats */
        +#define SSL_CTRL_SESS_NUMBER			20
        +#define SSL_CTRL_SESS_CONNECT			21
        +#define SSL_CTRL_SESS_CONNECT_GOOD		22
        +#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE	23
        +#define SSL_CTRL_SESS_ACCEPT			24
        +#define SSL_CTRL_SESS_ACCEPT_GOOD		25
        +#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE	26
        +#define SSL_CTRL_SESS_HIT			27
        +#define SSL_CTRL_SESS_CB_HIT			28
        +#define SSL_CTRL_SESS_MISSES			29
        +#define SSL_CTRL_SESS_TIMEOUTS			30
        +#define SSL_CTRL_SESS_CACHE_FULL		31
        +#define SSL_CTRL_OPTIONS			32
        +#define SSL_CTRL_MODE				33
        +
        +#define SSL_CTRL_GET_READ_AHEAD			40
        +#define SSL_CTRL_SET_READ_AHEAD			41
        +#define SSL_CTRL_SET_SESS_CACHE_SIZE		42
        +#define SSL_CTRL_GET_SESS_CACHE_SIZE		43
        +#define SSL_CTRL_SET_SESS_CACHE_MODE		44
        +#define SSL_CTRL_GET_SESS_CACHE_MODE		45
        +
        +#define SSL_CTRL_GET_MAX_CERT_LIST		50
        +#define SSL_CTRL_SET_MAX_CERT_LIST		51
        +
        +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT		52
        +
        +/* see tls1.h for macros based on these */
        +#ifndef OPENSSL_NO_TLSEXT
        +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB	53
        +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG	54
        +#define SSL_CTRL_SET_TLSEXT_HOSTNAME		55
        +#define SSL_CTRL_SET_TLSEXT_DEBUG_CB		56
        +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG		57
        +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS		58
        +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS		59
        +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT	60
        +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB	61
        +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
        +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB	63
        +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG	64
        +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE	65
        +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS	66
        +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS	67
        +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS	68
        +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS	69
        +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP	70
        +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP	71
        +
        +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB	72
        +
        +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB	75
        +#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB		76
        +#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB		77
        +
        +#define SSL_CTRL_SET_SRP_ARG		78
        +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME		79
        +#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH		80
        +#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD		81
        +#ifndef OPENSSL_NO_HEARTBEATS
        +#define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT				85
        +#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING		86
        +#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS	87
        +#endif
        +#endif
        +
        +#define DTLS_CTRL_GET_TIMEOUT		73
        +#define DTLS_CTRL_HANDLE_TIMEOUT	74
        +#define DTLS_CTRL_LISTEN			75
        +
        +#define SSL_CTRL_GET_RI_SUPPORT			76
        +#define SSL_CTRL_CLEAR_OPTIONS			77
        +#define SSL_CTRL_CLEAR_MODE			78
        +
        +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS		82
        +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS	83
        +
        +#define DTLSv1_get_timeout(ssl, arg) \
        +	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
        +#define DTLSv1_handle_timeout(ssl) \
        +	SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
        +#define DTLSv1_listen(ssl, peer) \
        +	SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer)
        +
        +#define SSL_session_reused(ssl) \
        +	SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
        +#define SSL_num_renegotiations(ssl) \
        +	SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
        +#define SSL_clear_num_renegotiations(ssl) \
        +	SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
        +#define SSL_total_renegotiations(ssl) \
        +	SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
        +
        +#define SSL_CTX_need_tmp_RSA(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
        +#define SSL_CTX_set_tmp_rsa(ctx,rsa) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
        +#define SSL_CTX_set_tmp_dh(ctx,dh) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
        +#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
        +
        +#define SSL_need_tmp_RSA(ssl) \
        +	SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
        +#define SSL_set_tmp_rsa(ssl,rsa) \
        +	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
        +#define SSL_set_tmp_dh(ssl,dh) \
        +	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
        +#define SSL_set_tmp_ecdh(ssl,ecdh) \
        +	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
        +
        +#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
        +#define SSL_CTX_get_extra_chain_certs(ctx,px509) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509)
        +#define SSL_CTX_clear_extra_chain_certs(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
        +
        +#ifndef OPENSSL_NO_BIO
        +BIO_METHOD *BIO_f_ssl(void);
        +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 *ssl_bio);
        +
        +#endif
        +
        +int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
        +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
        +void	SSL_CTX_free(SSL_CTX *);
        +long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
        +long SSL_CTX_get_timeout(const SSL_CTX *ctx);
        +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
        +void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *);
        +int SSL_want(const SSL *s);
        +int	SSL_clear(SSL *s);
        +
        +void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
        +
        +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
        +int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
        +char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
        +const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
        +unsigned long 	SSL_CIPHER_get_id(const SSL_CIPHER *c);
        +
        +int	SSL_get_fd(const SSL *s);
        +int	SSL_get_rfd(const SSL *s);
        +int	SSL_get_wfd(const SSL *s);
        +const char  * SSL_get_cipher_list(const SSL *s,int n);
        +char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
        +int	SSL_get_read_ahead(const SSL * s);
        +int	SSL_pending(const SSL *s);
        +#ifndef OPENSSL_NO_SOCK
        +int	SSL_set_fd(SSL *s, int fd);
        +int	SSL_set_rfd(SSL *s, int fd);
        +int	SSL_set_wfd(SSL *s, int fd);
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +void	SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio);
        +BIO *	SSL_get_rbio(const SSL *s);
        +BIO *	SSL_get_wbio(const SSL *s);
        +#endif
        +int	SSL_set_cipher_list(SSL *s, const char *str);
        +void	SSL_set_read_ahead(SSL *s, int yes);
        +int	SSL_get_verify_mode(const SSL *s);
        +int	SSL_get_verify_depth(const SSL *s);
        +int	(*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
        +void	SSL_set_verify(SSL *s, int mode,
        +		       int (*callback)(int ok,X509_STORE_CTX *ctx));
        +void	SSL_set_verify_depth(SSL *s, int depth);
        +#ifndef OPENSSL_NO_RSA
        +int	SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
        +#endif
        +int	SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
        +int	SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
        +int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
        +int	SSL_use_certificate(SSL *ssl, X509 *x);
        +int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
        +
        +#ifndef OPENSSL_NO_STDIO
        +int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
        +int	SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
        +int	SSL_use_certificate_file(SSL *ssl, const char *file, int type);
        +int	SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
        +int	SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
        +int	SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
        +int	SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */
        +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
        +int	SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
        +					    const char *file);
        +#ifndef OPENSSL_SYS_VMS
        +#ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
        +int	SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
        +					   const char *dir);
        +#endif
        +#endif
        +
        +#endif
        +
        +void	SSL_load_error_strings(void );
        +const char *SSL_state_string(const SSL *s);
        +const char *SSL_rstate_string(const SSL *s);
        +const char *SSL_state_string_long(const SSL *s);
        +const char *SSL_rstate_string_long(const SSL *s);
        +long	SSL_SESSION_get_time(const SSL_SESSION *s);
        +long	SSL_SESSION_set_time(SSL_SESSION *s, long t);
        +long	SSL_SESSION_get_timeout(const SSL_SESSION *s);
        +long	SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
        +void	SSL_copy_session_id(SSL *to,const SSL *from);
        +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
        +int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
        +			       unsigned int sid_ctx_len);
        +
        +SSL_SESSION *SSL_SESSION_new(void);
        +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
        +					unsigned int *len);
        +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s);
        +#ifndef OPENSSL_NO_FP_API
        +int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
        +#endif
        +#ifndef OPENSSL_NO_BIO
        +int	SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
        +#endif
        +void	SSL_SESSION_free(SSL_SESSION *ses);
        +int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
        +int	SSL_set_session(SSL *to, SSL_SESSION *session);
        +int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
        +int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
        +int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
        +int	SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
        +int	SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
        +					unsigned int id_len);
        +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp,
        +			     long length);
        +
        +#ifdef HEADER_X509_H
        +X509 *	SSL_get_peer_certificate(const SSL *s);
        +#endif
        +
        +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
        +
        +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
        +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
        +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *);
        +void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
        +			int (*callback)(int, X509_STORE_CTX *));
        +void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
        +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
        +#ifndef OPENSSL_NO_RSA
        +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
        +#endif
        +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
        +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
        +int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
        +	const unsigned char *d, long len);
        +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
        +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
        +
        +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
        +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
        +
        +int SSL_CTX_check_private_key(const SSL_CTX *ctx);
        +int SSL_check_private_key(const SSL *ctx);
        +
        +int	SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
        +				       unsigned int sid_ctx_len);
        +
        +SSL *	SSL_new(SSL_CTX *ctx);
        +int	SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
        +				   unsigned int sid_ctx_len);
        +
        +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
        +int SSL_set_purpose(SSL *s, int purpose);
        +int SSL_CTX_set_trust(SSL_CTX *s, int trust);
        +int SSL_set_trust(SSL *s, int trust);
        +
        +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
        +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
        +
        +#ifndef OPENSSL_NO_SRP
        +int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name);
        +int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password);
        +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
        +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
        +					char *(*cb)(SSL *,void *));
        +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
        +					  int (*cb)(SSL *,void *));
        +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
        +				      int (*cb)(SSL *,int *,void *));
        +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
        +
        +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
        +			     BIGNUM *sa, BIGNUM *v, char *info);
        +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
        +				const char *grp);
        +
        +BIGNUM *SSL_get_srp_g(SSL *s);
        +BIGNUM *SSL_get_srp_N(SSL *s);
        +
        +char *SSL_get_srp_username(SSL *s);
        +char *SSL_get_srp_userinfo(SSL *s);
        +#endif
        +
        +void	SSL_free(SSL *ssl);
        +int 	SSL_accept(SSL *ssl);
        +int 	SSL_connect(SSL *ssl);
        +int 	SSL_read(SSL *ssl,void *buf,int num);
        +int 	SSL_peek(SSL *ssl,void *buf,int num);
        +int 	SSL_write(SSL *ssl,const void *buf,int num);
        +long	SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
        +long	SSL_callback_ctrl(SSL *, int, void (*)(void));
        +long	SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg);
        +long	SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
        +
        +int	SSL_get_error(const SSL *s,int ret_code);
        +const char *SSL_get_version(const SSL *s);
        +
        +/* This sets the 'default' SSL version that SSL_new() will create */
        +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
        +
        +#ifndef OPENSSL_NO_SSL2
        +const SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
        +const SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
        +const SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
        +#endif
        +
        +const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
        +const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
        +const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
        +
        +const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
        +const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
        +const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
        +
        +const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
        +const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
        +const SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
        +
        +const SSL_METHOD *TLSv1_1_method(void);		/* TLSv1.1 */
        +const SSL_METHOD *TLSv1_1_server_method(void);	/* TLSv1.1 */
        +const SSL_METHOD *TLSv1_1_client_method(void);	/* TLSv1.1 */
        +
        +const SSL_METHOD *TLSv1_2_method(void);		/* TLSv1.2 */
        +const SSL_METHOD *TLSv1_2_server_method(void);	/* TLSv1.2 */
        +const SSL_METHOD *TLSv1_2_client_method(void);	/* TLSv1.2 */
        +
        +
        +const SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
        +const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
        +const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
        +
        +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
        +
        +int SSL_do_handshake(SSL *s);
        +int SSL_renegotiate(SSL *s);
        +int SSL_renegotiate_abbreviated(SSL *s);
        +int SSL_renegotiate_pending(SSL *s);
        +int SSL_shutdown(SSL *s);
        +
        +const SSL_METHOD *SSL_get_ssl_method(SSL *s);
        +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
        +const char *SSL_alert_type_string_long(int value);
        +const char *SSL_alert_type_string(int value);
        +const char *SSL_alert_desc_string_long(int value);
        +const char *SSL_alert_desc_string(int value);
        +
        +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
        +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
        +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
        +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
        +int SSL_add_client_CA(SSL *ssl,X509 *x);
        +int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
        +
        +void SSL_set_connect_state(SSL *s);
        +void SSL_set_accept_state(SSL *s);
        +
        +long SSL_get_default_timeout(const SSL *s);
        +
        +int SSL_library_init(void );
        +
        +char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size);
        +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
        +
        +SSL *SSL_dup(SSL *ssl);
        +
        +X509 *SSL_get_certificate(const SSL *ssl);
        +/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl);
        +
        +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode);
        +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
        +void SSL_set_quiet_shutdown(SSL *ssl,int mode);
        +int SSL_get_quiet_shutdown(const SSL *ssl);
        +void SSL_set_shutdown(SSL *ssl,int mode);
        +int SSL_get_shutdown(const SSL *ssl);
        +int SSL_version(const SSL *ssl);
        +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
        +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
        +	const char *CApath);
        +#define SSL_get0_session SSL_get_session /* just peek at pointer */
        +SSL_SESSION *SSL_get_session(const SSL *ssl);
        +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
        +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
        +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx);
        +void SSL_set_info_callback(SSL *ssl,
        +			   void (*cb)(const SSL *ssl,int type,int val));
        +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
        +int SSL_state(const SSL *ssl);
        +void SSL_set_state(SSL *ssl, int state);
        +
        +void SSL_set_verify_result(SSL *ssl,long v);
        +long SSL_get_verify_result(const SSL *ssl);
        +
        +int SSL_set_ex_data(SSL *ssl,int idx,void *data);
        +void *SSL_get_ex_data(const SSL *ssl,int idx);
        +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +
        +int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data);
        +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx);
        +int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +
        +int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data);
        +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx);
        +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
        +
        +int SSL_get_ex_data_X509_STORE_CTX_idx(void );
        +
        +#define SSL_CTX_sess_set_cache_size(ctx,t) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
        +#define SSL_CTX_sess_get_cache_size(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
        +#define SSL_CTX_set_session_cache_mode(ctx,m) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
        +#define SSL_CTX_get_session_cache_mode(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
        +
        +#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
        +#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
        +#define SSL_CTX_get_read_ahead(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
        +#define SSL_CTX_set_read_ahead(ctx,m) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
        +#define SSL_CTX_get_max_cert_list(ctx) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
        +#define SSL_CTX_set_max_cert_list(ctx,m) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
        +#define SSL_get_max_cert_list(ssl) \
        +	SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
        +#define SSL_set_max_cert_list(ssl,m) \
        +	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
        +
        +#define SSL_CTX_set_max_send_fragment(ctx,m) \
        +	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
        +#define SSL_set_max_send_fragment(ssl,m) \
        +	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
        +
        +     /* NB: the keylength is only applicable when is_export is true */
        +#ifndef OPENSSL_NO_RSA
        +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
        +				  RSA *(*cb)(SSL *ssl,int is_export,
        +					     int keylength));
        +
        +void SSL_set_tmp_rsa_callback(SSL *ssl,
        +				  RSA *(*cb)(SSL *ssl,int is_export,
        +					     int keylength));
        +#endif
        +#ifndef OPENSSL_NO_DH
        +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
        +				 DH *(*dh)(SSL *ssl,int is_export,
        +					   int keylength));
        +void SSL_set_tmp_dh_callback(SSL *ssl,
        +				 DH *(*dh)(SSL *ssl,int is_export,
        +					   int keylength));
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
        +				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
        +					   int keylength));
        +void SSL_set_tmp_ecdh_callback(SSL *ssl,
        +				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
        +					   int keylength));
        +#endif
        +
        +#ifndef OPENSSL_NO_COMP
        +const COMP_METHOD *SSL_get_current_compression(SSL *s);
        +const COMP_METHOD *SSL_get_current_expansion(SSL *s);
        +const char *SSL_COMP_get_name(const COMP_METHOD *comp);
        +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
        +int SSL_COMP_add_compression_method(int id,COMP_METHOD *cm);
        +#else
        +const void *SSL_get_current_compression(SSL *s);
        +const void *SSL_get_current_expansion(SSL *s);
        +const char *SSL_COMP_get_name(const void *comp);
        +void *SSL_COMP_get_compression_methods(void);
        +int SSL_COMP_add_compression_method(int id,void *cm);
        +#endif
        +
        +/* TLS extensions functions */
        +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
        +
        +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
        +				  void *arg);
        +
        +/* Pre-shared secret session resumption functions */
        +int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
        +
        +void SSL_set_debug(SSL *s, int debug);
        +int SSL_cache_hit(SSL *s);
        +
        +/* BEGIN ERROR CODES */
        +/* The following lines are auto generated by the script mkerr.pl. Any changes
        + * made after this point may be overwritten when the script is next run.
        + */
        +void ERR_load_SSL_strings(void);
        +
        +/* Error codes for the SSL functions. */
        +
        +/* Function codes. */
        +#define SSL_F_CLIENT_CERTIFICATE			 100
        +#define SSL_F_CLIENT_FINISHED				 167
        +#define SSL_F_CLIENT_HELLO				 101
        +#define SSL_F_CLIENT_MASTER_KEY				 102
        +#define SSL_F_D2I_SSL_SESSION				 103
        +#define SSL_F_DO_DTLS1_WRITE				 245
        +#define SSL_F_DO_SSL3_WRITE				 104
        +#define SSL_F_DTLS1_ACCEPT				 246
        +#define SSL_F_DTLS1_ADD_CERT_TO_BUF			 295
        +#define SSL_F_DTLS1_BUFFER_RECORD			 247
        +#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM			 316
        +#define SSL_F_DTLS1_CLIENT_HELLO			 248
        +#define SSL_F_DTLS1_CONNECT				 249
        +#define SSL_F_DTLS1_ENC					 250
        +#define SSL_F_DTLS1_GET_HELLO_VERIFY			 251
        +#define SSL_F_DTLS1_GET_MESSAGE				 252
        +#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT		 253
        +#define SSL_F_DTLS1_GET_RECORD				 254
        +#define SSL_F_DTLS1_HANDLE_TIMEOUT			 297
        +#define SSL_F_DTLS1_HEARTBEAT				 305
        +#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
        +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 288
        +#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 256
        +#define SSL_F_DTLS1_PROCESS_RECORD			 257
        +#define SSL_F_DTLS1_READ_BYTES				 258
        +#define SSL_F_DTLS1_READ_FAILED				 259
        +#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST		 260
        +#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE		 261
        +#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE		 262
        +#define SSL_F_DTLS1_SEND_CLIENT_VERIFY			 263
        +#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST		 264
        +#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE		 265
        +#define SSL_F_DTLS1_SEND_SERVER_HELLO			 266
        +#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE		 267
        +#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES		 268
        +#define SSL_F_GET_CLIENT_FINISHED			 105
        +#define SSL_F_GET_CLIENT_HELLO				 106
        +#define SSL_F_GET_CLIENT_MASTER_KEY			 107
        +#define SSL_F_GET_SERVER_FINISHED			 108
        +#define SSL_F_GET_SERVER_HELLO				 109
        +#define SSL_F_GET_SERVER_VERIFY				 110
        +#define SSL_F_I2D_SSL_SESSION				 111
        +#define SSL_F_READ_N					 112
        +#define SSL_F_REQUEST_CERTIFICATE			 113
        +#define SSL_F_SERVER_FINISH				 239
        +#define SSL_F_SERVER_HELLO				 114
        +#define SSL_F_SERVER_VERIFY				 240
        +#define SSL_F_SSL23_ACCEPT				 115
        +#define SSL_F_SSL23_CLIENT_HELLO			 116
        +#define SSL_F_SSL23_CONNECT				 117
        +#define SSL_F_SSL23_GET_CLIENT_HELLO			 118
        +#define SSL_F_SSL23_GET_SERVER_HELLO			 119
        +#define SSL_F_SSL23_PEEK				 237
        +#define SSL_F_SSL23_READ				 120
        +#define SSL_F_SSL23_WRITE				 121
        +#define SSL_F_SSL2_ACCEPT				 122
        +#define SSL_F_SSL2_CONNECT				 123
        +#define SSL_F_SSL2_ENC_INIT				 124
        +#define SSL_F_SSL2_GENERATE_KEY_MATERIAL		 241
        +#define SSL_F_SSL2_PEEK					 234
        +#define SSL_F_SSL2_READ					 125
        +#define SSL_F_SSL2_READ_INTERNAL			 236
        +#define SSL_F_SSL2_SET_CERTIFICATE			 126
        +#define SSL_F_SSL2_WRITE				 127
        +#define SSL_F_SSL3_ACCEPT				 128
        +#define SSL_F_SSL3_ADD_CERT_TO_BUF			 296
        +#define SSL_F_SSL3_CALLBACK_CTRL			 233
        +#define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
        +#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
        +#define SSL_F_SSL3_CHECK_CLIENT_HELLO			 304
        +#define SSL_F_SSL3_CLIENT_HELLO				 131
        +#define SSL_F_SSL3_CONNECT				 132
        +#define SSL_F_SSL3_CTRL					 213
        +#define SSL_F_SSL3_CTX_CTRL				 133
        +#define SSL_F_SSL3_DIGEST_CACHED_RECORDS		 293
        +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 292
        +#define SSL_F_SSL3_ENC					 134
        +#define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
        +#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
        +#define SSL_F_SSL3_GET_CERT_STATUS			 289
        +#define SSL_F_SSL3_GET_CERT_VERIFY			 136
        +#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE		 137
        +#define SSL_F_SSL3_GET_CLIENT_HELLO			 138
        +#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE		 139
        +#define SSL_F_SSL3_GET_FINISHED				 140
        +#define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
        +#define SSL_F_SSL3_GET_MESSAGE				 142
        +#define SSL_F_SSL3_GET_NEW_SESSION_TICKET		 283
        +#define SSL_F_SSL3_GET_NEXT_PROTO			 306
        +#define SSL_F_SSL3_GET_RECORD				 143
        +#define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
        +#define SSL_F_SSL3_GET_SERVER_DONE			 145
        +#define SSL_F_SSL3_GET_SERVER_HELLO			 146
        +#define SSL_F_SSL3_HANDSHAKE_MAC			 285
        +#define SSL_F_SSL3_NEW_SESSION_TICKET			 287
        +#define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
        +#define SSL_F_SSL3_PEEK					 235
        +#define SSL_F_SSL3_READ_BYTES				 148
        +#define SSL_F_SSL3_READ_N				 149
        +#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST		 150
        +#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE		 151
        +#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE		 152
        +#define SSL_F_SSL3_SEND_CLIENT_VERIFY			 153
        +#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE		 154
        +#define SSL_F_SSL3_SEND_SERVER_HELLO			 242
        +#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE		 155
        +#define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
        +#define SSL_F_SSL3_SETUP_READ_BUFFER			 156
        +#define SSL_F_SSL3_SETUP_WRITE_BUFFER			 291
        +#define SSL_F_SSL3_WRITE_BYTES				 158
        +#define SSL_F_SSL3_WRITE_PENDING			 159
        +#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 298
        +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 277
        +#define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT		 307
        +#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
        +#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
        +#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 299
        +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 278
        +#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT		 308
        +#define SSL_F_SSL_BAD_METHOD				 160
        +#define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
        +#define SSL_F_SSL_CERT_DUP				 221
        +#define SSL_F_SSL_CERT_INST				 222
        +#define SSL_F_SSL_CERT_INSTANTIATE			 214
        +#define SSL_F_SSL_CERT_NEW				 162
        +#define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
        +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 280
        +#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG		 279
        +#define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
        +#define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
        +#define SSL_F_SSL_CLEAR					 164
        +#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD		 165
        +#define SSL_F_SSL_CREATE_CIPHER_LIST			 166
        +#define SSL_F_SSL_CTRL					 232
        +#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY			 168
        +#define SSL_F_SSL_CTX_MAKE_PROFILES			 309
        +#define SSL_F_SSL_CTX_NEW				 169
        +#define SSL_F_SSL_CTX_SET_CIPHER_LIST			 269
        +#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE		 290
        +#define SSL_F_SSL_CTX_SET_PURPOSE			 226
        +#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT		 219
        +#define SSL_F_SSL_CTX_SET_SSL_VERSION			 170
        +#define SSL_F_SSL_CTX_SET_TRUST				 229
        +#define SSL_F_SSL_CTX_USE_CERTIFICATE			 171
        +#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1		 172
        +#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE	 220
        +#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE		 173
        +#define SSL_F_SSL_CTX_USE_PRIVATEKEY			 174
        +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1		 175
        +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE		 176
        +#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT		 272
        +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY			 177
        +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1		 178
        +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE		 179
        +#define SSL_F_SSL_DO_HANDSHAKE				 180
        +#define SSL_F_SSL_GET_NEW_SESSION			 181
        +#define SSL_F_SSL_GET_PREV_SESSION			 217
        +#define SSL_F_SSL_GET_SERVER_SEND_CERT			 182
        +#define SSL_F_SSL_GET_SERVER_SEND_PKEY			 317
        +#define SSL_F_SSL_GET_SIGN_PKEY				 183
        +#define SSL_F_SSL_INIT_WBIO_BUFFER			 184
        +#define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
        +#define SSL_F_SSL_NEW					 186
        +#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 300
        +#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 302
        +#define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT	 310
        +#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 301
        +#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 303
        +#define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT	 311
        +#define SSL_F_SSL_PEEK					 270
        +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 281
        +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 282
        +#define SSL_F_SSL_READ					 223
        +#define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
        +#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
        +#define SSL_F_SSL_SESSION_NEW				 189
        +#define SSL_F_SSL_SESSION_PRINT_FP			 190
        +#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT		 312
        +#define SSL_F_SSL_SESS_CERT_NEW				 225
        +#define SSL_F_SSL_SET_CERT				 191
        +#define SSL_F_SSL_SET_CIPHER_LIST			 271
        +#define SSL_F_SSL_SET_FD				 192
        +#define SSL_F_SSL_SET_PKEY				 193
        +#define SSL_F_SSL_SET_PURPOSE				 227
        +#define SSL_F_SSL_SET_RFD				 194
        +#define SSL_F_SSL_SET_SESSION				 195
        +#define SSL_F_SSL_SET_SESSION_ID_CONTEXT		 218
        +#define SSL_F_SSL_SET_SESSION_TICKET_EXT		 294
        +#define SSL_F_SSL_SET_TRUST				 228
        +#define SSL_F_SSL_SET_WFD				 196
        +#define SSL_F_SSL_SHUTDOWN				 224
        +#define SSL_F_SSL_SRP_CTX_INIT				 313
        +#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION		 243
        +#define SSL_F_SSL_UNDEFINED_FUNCTION			 197
        +#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
        +#define SSL_F_SSL_USE_CERTIFICATE			 198
        +#define SSL_F_SSL_USE_CERTIFICATE_ASN1			 199
        +#define SSL_F_SSL_USE_CERTIFICATE_FILE			 200
        +#define SSL_F_SSL_USE_PRIVATEKEY			 201
        +#define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
        +#define SSL_F_SSL_USE_PRIVATEKEY_FILE			 203
        +#define SSL_F_SSL_USE_PSK_IDENTITY_HINT			 273
        +#define SSL_F_SSL_USE_RSAPRIVATEKEY			 204
        +#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1		 205
        +#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE		 206
        +#define SSL_F_SSL_VERIFY_CERT_CHAIN			 207
        +#define SSL_F_SSL_WRITE					 208
        +#define SSL_F_TLS1_CERT_VERIFY_MAC			 286
        +#define SSL_F_TLS1_CHANGE_CIPHER_STATE			 209
        +#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT		 274
        +#define SSL_F_TLS1_ENC					 210
        +#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL		 314
        +#define SSL_F_TLS1_HEARTBEAT				 315
        +#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT		 275
        +#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT		 276
        +#define SSL_F_TLS1_PRF					 284
        +#define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
        +#define SSL_F_WRITE_PENDING				 212
        +
        +/* Reason codes. */
        +#define SSL_R_APP_DATA_IN_HANDSHAKE			 100
        +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
        +#define SSL_R_BAD_ALERT_RECORD				 101
        +#define SSL_R_BAD_AUTHENTICATION_TYPE			 102
        +#define SSL_R_BAD_CHANGE_CIPHER_SPEC			 103
        +#define SSL_R_BAD_CHECKSUM				 104
        +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK		 106
        +#define SSL_R_BAD_DECOMPRESSION				 107
        +#define SSL_R_BAD_DH_G_LENGTH				 108
        +#define SSL_R_BAD_DH_PUB_KEY_LENGTH			 109
        +#define SSL_R_BAD_DH_P_LENGTH				 110
        +#define SSL_R_BAD_DIGEST_LENGTH				 111
        +#define SSL_R_BAD_DSA_SIGNATURE				 112
        +#define SSL_R_BAD_ECC_CERT				 304
        +#define SSL_R_BAD_ECDSA_SIGNATURE			 305
        +#define SSL_R_BAD_ECPOINT				 306
        +#define SSL_R_BAD_HANDSHAKE_LENGTH			 332
        +#define SSL_R_BAD_HELLO_REQUEST				 105
        +#define SSL_R_BAD_LENGTH				 271
        +#define SSL_R_BAD_MAC_DECODE				 113
        +#define SSL_R_BAD_MAC_LENGTH				 333
        +#define SSL_R_BAD_MESSAGE_TYPE				 114
        +#define SSL_R_BAD_PACKET_LENGTH				 115
        +#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER		 116
        +#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH		 316
        +#define SSL_R_BAD_RESPONSE_ARGUMENT			 117
        +#define SSL_R_BAD_RSA_DECRYPT				 118
        +#define SSL_R_BAD_RSA_ENCRYPT				 119
        +#define SSL_R_BAD_RSA_E_LENGTH				 120
        +#define SSL_R_BAD_RSA_MODULUS_LENGTH			 121
        +#define SSL_R_BAD_RSA_SIGNATURE				 122
        +#define SSL_R_BAD_SIGNATURE				 123
        +#define SSL_R_BAD_SRP_A_LENGTH				 347
        +#define SSL_R_BAD_SRP_B_LENGTH				 348
        +#define SSL_R_BAD_SRP_G_LENGTH				 349
        +#define SSL_R_BAD_SRP_N_LENGTH				 350
        +#define SSL_R_BAD_SRP_S_LENGTH				 351
        +#define SSL_R_BAD_SRTP_MKI_VALUE			 352
        +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST		 353
        +#define SSL_R_BAD_SSL_FILETYPE				 124
        +#define SSL_R_BAD_SSL_SESSION_ID_LENGTH			 125
        +#define SSL_R_BAD_STATE					 126
        +#define SSL_R_BAD_WRITE_RETRY				 127
        +#define SSL_R_BIO_NOT_SET				 128
        +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG			 129
        +#define SSL_R_BN_LIB					 130
        +#define SSL_R_CA_DN_LENGTH_MISMATCH			 131
        +#define SSL_R_CA_DN_TOO_LONG				 132
        +#define SSL_R_CCS_RECEIVED_EARLY			 133
        +#define SSL_R_CERTIFICATE_VERIFY_FAILED			 134
        +#define SSL_R_CERT_LENGTH_MISMATCH			 135
        +#define SSL_R_CHALLENGE_IS_DIFFERENT			 136
        +#define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
        +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
        +#define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
        +#define SSL_R_CLIENTHELLO_TLSEXT			 226
        +#define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
        +#define SSL_R_COMPRESSION_DISABLED			 343
        +#define SSL_R_COMPRESSION_FAILURE			 141
        +#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	 307
        +#define SSL_R_COMPRESSION_LIBRARY_ERROR			 142
        +#define SSL_R_CONNECTION_ID_IS_DIFFERENT		 143
        +#define SSL_R_CONNECTION_TYPE_NOT_SET			 144
        +#define SSL_R_COOKIE_MISMATCH				 308
        +#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED		 145
        +#define SSL_R_DATA_LENGTH_TOO_LONG			 146
        +#define SSL_R_DECRYPTION_FAILED				 147
        +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 281
        +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
        +#define SSL_R_DIGEST_CHECK_FAILED			 149
        +#define SSL_R_DTLS_MESSAGE_TOO_BIG			 334
        +#define SSL_R_DUPLICATE_COMPRESSION_ID			 309
        +#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT		 317
        +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING			 318
        +#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE	 322
        +#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE	 323
        +#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER		 310
        +#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST	 354
        +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG			 150
        +#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY		 282
        +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST		 151
        +#define SSL_R_EXCESSIVE_MESSAGE_SIZE			 152
        +#define SSL_R_EXTRA_DATA_IN_MESSAGE			 153
        +#define SSL_R_GOT_A_FIN_BEFORE_A_CCS			 154
        +#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS		 355
        +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION		 356
        +#define SSL_R_HTTPS_PROXY_REQUEST			 155
        +#define SSL_R_HTTP_REQUEST				 156
        +#define SSL_R_ILLEGAL_PADDING				 283
        +#define SSL_R_INCONSISTENT_COMPRESSION			 340
        +#define SSL_R_INVALID_CHALLENGE_LENGTH			 158
        +#define SSL_R_INVALID_COMMAND				 280
        +#define SSL_R_INVALID_COMPRESSION_ALGORITHM		 341
        +#define SSL_R_INVALID_PURPOSE				 278
        +#define SSL_R_INVALID_SRP_USERNAME			 357
        +#define SSL_R_INVALID_STATUS_RESPONSE			 328
        +#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 325
        +#define SSL_R_INVALID_TRUST				 279
        +#define SSL_R_KEY_ARG_TOO_LONG				 284
        +#define SSL_R_KRB5					 285
        +#define SSL_R_KRB5_C_CC_PRINC				 286
        +#define SSL_R_KRB5_C_GET_CRED				 287
        +#define SSL_R_KRB5_C_INIT				 288
        +#define SSL_R_KRB5_C_MK_REQ				 289
        +#define SSL_R_KRB5_S_BAD_TICKET				 290
        +#define SSL_R_KRB5_S_INIT				 291
        +#define SSL_R_KRB5_S_RD_REQ				 292
        +#define SSL_R_KRB5_S_TKT_EXPIRED			 293
        +#define SSL_R_KRB5_S_TKT_NYV				 294
        +#define SSL_R_KRB5_S_TKT_SKEW				 295
        +#define SSL_R_LENGTH_MISMATCH				 159
        +#define SSL_R_LENGTH_TOO_SHORT				 160
        +#define SSL_R_LIBRARY_BUG				 274
        +#define SSL_R_LIBRARY_HAS_NO_CIPHERS			 161
        +#define SSL_R_MESSAGE_TOO_LONG				 296
        +#define SSL_R_MISSING_DH_DSA_CERT			 162
        +#define SSL_R_MISSING_DH_KEY				 163
        +#define SSL_R_MISSING_DH_RSA_CERT			 164
        +#define SSL_R_MISSING_DSA_SIGNING_CERT			 165
        +#define SSL_R_MISSING_EXPORT_TMP_DH_KEY			 166
        +#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY		 167
        +#define SSL_R_MISSING_RSA_CERTIFICATE			 168
        +#define SSL_R_MISSING_RSA_ENCRYPTING_CERT		 169
        +#define SSL_R_MISSING_RSA_SIGNING_CERT			 170
        +#define SSL_R_MISSING_SRP_PARAM				 358
        +#define SSL_R_MISSING_TMP_DH_KEY			 171
        +#define SSL_R_MISSING_TMP_ECDH_KEY			 311
        +#define SSL_R_MISSING_TMP_RSA_KEY			 172
        +#define SSL_R_MISSING_TMP_RSA_PKEY			 173
        +#define SSL_R_MISSING_VERIFY_MESSAGE			 174
        +#define SSL_R_MULTIPLE_SGC_RESTARTS			 346
        +#define SSL_R_NON_SSLV2_INITIAL_PACKET			 175
        +#define SSL_R_NO_CERTIFICATES_RETURNED			 176
        +#define SSL_R_NO_CERTIFICATE_ASSIGNED			 177
        +#define SSL_R_NO_CERTIFICATE_RETURNED			 178
        +#define SSL_R_NO_CERTIFICATE_SET			 179
        +#define SSL_R_NO_CERTIFICATE_SPECIFIED			 180
        +#define SSL_R_NO_CIPHERS_AVAILABLE			 181
        +#define SSL_R_NO_CIPHERS_PASSED				 182
        +#define SSL_R_NO_CIPHERS_SPECIFIED			 183
        +#define SSL_R_NO_CIPHER_LIST				 184
        +#define SSL_R_NO_CIPHER_MATCH				 185
        +#define SSL_R_NO_CLIENT_CERT_METHOD			 331
        +#define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
        +#define SSL_R_NO_COMPRESSION_SPECIFIED			 187
        +#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER		 330
        +#define SSL_R_NO_METHOD_SPECIFIED			 188
        +#define SSL_R_NO_PRIVATEKEY				 189
        +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
        +#define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
        +#define SSL_R_NO_PUBLICKEY				 192
        +#define SSL_R_NO_RENEGOTIATION				 339
        +#define SSL_R_NO_REQUIRED_DIGEST			 324
        +#define SSL_R_NO_SHARED_CIPHER				 193
        +#define SSL_R_NO_SRTP_PROFILES				 359
        +#define SSL_R_NO_VERIFY_CALLBACK			 194
        +#define SSL_R_NULL_SSL_CTX				 195
        +#define SSL_R_NULL_SSL_METHOD_PASSED			 196
        +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
        +#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
        +#define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
        +#define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG			 327
        +#define SSL_R_PACKET_LENGTH_TOO_LONG			 198
        +#define SSL_R_PARSE_TLSEXT				 227
        +#define SSL_R_PATH_TOO_LONG				 270
        +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
        +#define SSL_R_PEER_ERROR				 200
        +#define SSL_R_PEER_ERROR_CERTIFICATE			 201
        +#define SSL_R_PEER_ERROR_NO_CERTIFICATE			 202
        +#define SSL_R_PEER_ERROR_NO_CIPHER			 203
        +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE	 204
        +#define SSL_R_PRE_MAC_LENGTH_TOO_LONG			 205
        +#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS		 206
        +#define SSL_R_PROTOCOL_IS_SHUTDOWN			 207
        +#define SSL_R_PSK_IDENTITY_NOT_FOUND			 223
        +#define SSL_R_PSK_NO_CLIENT_CB				 224
        +#define SSL_R_PSK_NO_SERVER_CB				 225
        +#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR			 208
        +#define SSL_R_PUBLIC_KEY_IS_NOT_RSA			 209
        +#define SSL_R_PUBLIC_KEY_NOT_RSA			 210
        +#define SSL_R_READ_BIO_NOT_SET				 211
        +#define SSL_R_READ_TIMEOUT_EXPIRED			 312
        +#define SSL_R_READ_WRONG_PACKET_TYPE			 212
        +#define SSL_R_RECORD_LENGTH_MISMATCH			 213
        +#define SSL_R_RECORD_TOO_LARGE				 214
        +#define SSL_R_RECORD_TOO_SMALL				 298
        +#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 335
        +#define SSL_R_RENEGOTIATION_ENCODING_ERR		 336
        +#define SSL_R_RENEGOTIATION_MISMATCH			 337
        +#define SSL_R_REQUIRED_CIPHER_MISSING			 215
        +#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING	 342
        +#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
        +#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
        +#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
        +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 345
        +#define SSL_R_SERVERHELLO_TLSEXT			 275
        +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
        +#define SSL_R_SHORT_READ				 219
        +#define SSL_R_SIGNATURE_ALGORITHMS_ERROR		 360
        +#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
        +#define SSL_R_SRP_A_CALC				 361
        +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES		 362
        +#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG	 363
        +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE		 364
        +#define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
        +#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
        +#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT		 321
        +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 319
        +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 320
        +#define SSL_R_SSL3_SESSION_ID_TOO_LONG			 300
        +#define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
        +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
        +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC		 1020
        +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED		 1045
        +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED		 1044
        +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN		 1046
        +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE		 1030
        +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE		 1040
        +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER		 1047
        +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE		 1041
        +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		 1010
        +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE	 1043
        +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION	 228
        +#define SSL_R_SSL_HANDSHAKE_FAILURE			 229
        +#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS		 230
        +#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED		 301
        +#define SSL_R_SSL_SESSION_ID_CONFLICT			 302
        +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG		 273
        +#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH		 303
        +#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT		 231
        +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED			 1049
        +#define SSL_R_TLSV1_ALERT_DECODE_ERROR			 1050
        +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
        +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
        +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
        +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
        +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
        +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100
        +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		 1070
        +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		 1022
        +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
        +#define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
        +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE		 1114
        +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	 1113
        +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		 1111
        +#define SSL_R_TLSV1_UNRECOGNIZED_NAME			 1112
        +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION		 1110
        +#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
        +#define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT		 365
        +#define SSL_R_TLS_HEARTBEAT_PENDING			 366
        +#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL		 367
        +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 157
        +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
        +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
        +#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
        +#define SSL_R_UNABLE_TO_DECODE_DH_CERTS			 236
        +#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS		 313
        +#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY		 237
        +#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS		 238
        +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS		 314
        +#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS	 239
        +#define SSL_R_UNABLE_TO_FIND_SSL_METHOD			 240
        +#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES		 241
        +#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES		 242
        +#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES		 243
        +#define SSL_R_UNEXPECTED_MESSAGE			 244
        +#define SSL_R_UNEXPECTED_RECORD				 245
        +#define SSL_R_UNINITIALIZED				 276
        +#define SSL_R_UNKNOWN_ALERT_TYPE			 246
        +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE			 247
        +#define SSL_R_UNKNOWN_CIPHER_RETURNED			 248
        +#define SSL_R_UNKNOWN_CIPHER_TYPE			 249
        +#define SSL_R_UNKNOWN_DIGEST				 368
        +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE			 250
        +#define SSL_R_UNKNOWN_PKEY_TYPE				 251
        +#define SSL_R_UNKNOWN_PROTOCOL				 252
        +#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
        +#define SSL_R_UNKNOWN_SSL_VERSION			 254
        +#define SSL_R_UNKNOWN_STATE				 255
        +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 338
        +#define SSL_R_UNSUPPORTED_CIPHER			 256
        +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
        +#define SSL_R_UNSUPPORTED_DIGEST_TYPE			 326
        +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 315
        +#define SSL_R_UNSUPPORTED_PROTOCOL			 258
        +#define SSL_R_UNSUPPORTED_SSL_VERSION			 259
        +#define SSL_R_UNSUPPORTED_STATUS_TYPE			 329
        +#define SSL_R_USE_SRTP_NOT_NEGOTIATED			 369
        +#define SSL_R_WRITE_BIO_NOT_SET				 260
        +#define SSL_R_WRONG_CIPHER_RETURNED			 261
        +#define SSL_R_WRONG_MESSAGE_TYPE			 262
        +#define SSL_R_WRONG_NUMBER_OF_KEY_BITS			 263
        +#define SSL_R_WRONG_SIGNATURE_LENGTH			 264
        +#define SSL_R_WRONG_SIGNATURE_SIZE			 265
        +#define SSL_R_WRONG_SIGNATURE_TYPE			 370
        +#define SSL_R_WRONG_SSL_VERSION				 266
        +#define SSL_R_WRONG_VERSION_NUMBER			 267
        +#define SSL_R_X509_LIB					 268
        +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS		 269
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/ssl2.h b/vendor/openssl/openssl/ssl/ssl2.h
        new file mode 100644
        index 000000000..eb25dcb0b
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl2.h
        @@ -0,0 +1,272 @@
        +/* ssl/ssl2.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_SSL2_H 
        +#define HEADER_SSL2_H 
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Protocol Version Codes */
        +#define SSL2_VERSION		0x0002
        +#define SSL2_VERSION_MAJOR	0x00
        +#define SSL2_VERSION_MINOR	0x02
        +/* #define SSL2_CLIENT_VERSION	0x0002 */
        +/* #define SSL2_SERVER_VERSION	0x0002 */
        +
        +/* Protocol Message Codes */
        +#define SSL2_MT_ERROR			0
        +#define SSL2_MT_CLIENT_HELLO		1
        +#define SSL2_MT_CLIENT_MASTER_KEY	2
        +#define SSL2_MT_CLIENT_FINISHED		3
        +#define SSL2_MT_SERVER_HELLO		4
        +#define SSL2_MT_SERVER_VERIFY		5
        +#define SSL2_MT_SERVER_FINISHED		6
        +#define SSL2_MT_REQUEST_CERTIFICATE	7
        +#define SSL2_MT_CLIENT_CERTIFICATE	8
        +
        +/* Error Message Codes */
        +#define SSL2_PE_UNDEFINED_ERROR		0x0000
        +#define SSL2_PE_NO_CIPHER		0x0001
        +#define SSL2_PE_NO_CERTIFICATE		0x0002
        +#define SSL2_PE_BAD_CERTIFICATE		0x0004
        +#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
        +
        +/* Cipher Kind Values */
        +#define SSL2_CK_NULL_WITH_MD5			0x02000000 /* v3 */
        +#define SSL2_CK_RC4_128_WITH_MD5		0x02010080
        +#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5	0x02020080
        +#define SSL2_CK_RC2_128_CBC_WITH_MD5		0x02030080
        +#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5	0x02040080
        +#define SSL2_CK_IDEA_128_CBC_WITH_MD5		0x02050080
        +#define SSL2_CK_DES_64_CBC_WITH_MD5		0x02060040
        +#define SSL2_CK_DES_64_CBC_WITH_SHA		0x02060140 /* v3 */
        +#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5	0x020700c0
        +#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA	0x020701c0 /* v3 */
        +#define SSL2_CK_RC4_64_WITH_MD5			0x02080080 /* MS hack */
        + 
        +#define SSL2_CK_DES_64_CFB64_WITH_MD5_1		0x02ff0800 /* SSLeay */
        +#define SSL2_CK_NULL				0x02ff0810 /* SSLeay */
        +
        +#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1	"DES-CFB-M1"
        +#define SSL2_TXT_NULL_WITH_MD5			"NULL-MD5"
        +#define SSL2_TXT_RC4_128_WITH_MD5		"RC4-MD5"
        +#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	"EXP-RC4-MD5"
        +#define SSL2_TXT_RC2_128_CBC_WITH_MD5		"RC2-CBC-MD5"
        +#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	"EXP-RC2-CBC-MD5"
        +#define SSL2_TXT_IDEA_128_CBC_WITH_MD5		"IDEA-CBC-MD5"
        +#define SSL2_TXT_DES_64_CBC_WITH_MD5		"DES-CBC-MD5"
        +#define SSL2_TXT_DES_64_CBC_WITH_SHA		"DES-CBC-SHA"
        +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	"DES-CBC3-MD5"
        +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	"DES-CBC3-SHA"
        +#define SSL2_TXT_RC4_64_WITH_MD5		"RC4-64-MD5"
        +
        +#define SSL2_TXT_NULL				"NULL"
        +
        +/* Flags for the SSL_CIPHER.algorithm2 field */
        +#define SSL2_CF_5_BYTE_ENC			0x01
        +#define SSL2_CF_8_BYTE_ENC			0x02
        +
        +/* Certificate Type Codes */
        +#define SSL2_CT_X509_CERTIFICATE		0x01
        +
        +/* Authentication Type Code */
        +#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION		0x01
        +
        +#define SSL2_MAX_SSL_SESSION_ID_LENGTH		32
        +
        +/* Upper/Lower Bounds */
        +#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS	256
        +#ifdef OPENSSL_SYS_MPE
        +#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	29998u
        +#else
        +#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	32767u  /* 2^15-1 */
        +#endif
        +#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER	16383 /* 2^14-1 */
        +
        +#define SSL2_CHALLENGE_LENGTH	16
        +/*#define SSL2_CHALLENGE_LENGTH	32 */
        +#define SSL2_MIN_CHALLENGE_LENGTH	16
        +#define SSL2_MAX_CHALLENGE_LENGTH	32
        +#define SSL2_CONNECTION_ID_LENGTH	16
        +#define SSL2_MAX_CONNECTION_ID_LENGTH	16
        +#define SSL2_SSL_SESSION_ID_LENGTH	16
        +#define SSL2_MAX_CERT_CHALLENGE_LENGTH	32
        +#define SSL2_MIN_CERT_CHALLENGE_LENGTH	16
        +#define SSL2_MAX_KEY_MATERIAL_LENGTH	24
        +
        +#ifndef HEADER_SSL_LOCL_H
        +#define  CERT		char
        +#endif
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +typedef struct ssl2_state_st
        +	{
        +	int three_byte_header;
        +	int clear_text;		/* clear text */
        +	int escape;		/* not used in SSLv2 */
        +	int ssl2_rollback;	/* used if SSLv23 rolled back to SSLv2 */
        +
        +	/* non-blocking io info, used to make sure the same
        +	 * args were passwd */
        +	unsigned int wnum;	/* number of bytes sent so far */
        +	int wpend_tot;
        +	const unsigned char *wpend_buf;
        +
        +	int wpend_off;	/* offset to data to write */
        +	int wpend_len; 	/* number of bytes passwd to write */
        +	int wpend_ret; 	/* number of bytes to return to caller */
        +
        +	/* buffer raw data */
        +	int rbuf_left;
        +	int rbuf_offs;
        +	unsigned char *rbuf;
        +	unsigned char *wbuf;
        +
        +	unsigned char *write_ptr;/* used to point to the start due to
        +				  * 2/3 byte header. */
        +
        +	unsigned int padding;
        +	unsigned int rlength; /* passed to ssl2_enc */
        +	int ract_data_length; /* Set when things are encrypted. */
        +	unsigned int wlength; /* passed to ssl2_enc */
        +	int wact_data_length; /* Set when things are decrypted. */
        +	unsigned char *ract_data;
        +	unsigned char *wact_data;
        +	unsigned char *mac_data;
        +
        +	unsigned char *read_key;
        +	unsigned char *write_key;
        +
        +		/* Stuff specifically to do with this SSL session */
        +	unsigned int challenge_length;
        +	unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
        +	unsigned int conn_id_length;
        +	unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
        +	unsigned int key_material_length;
        +	unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2];
        +
        +	unsigned long read_sequence;
        +	unsigned long write_sequence;
        +
        +	struct	{
        +		unsigned int conn_id_length;
        +		unsigned int cert_type;	
        +		unsigned int cert_length;
        +		unsigned int csl; 
        +		unsigned int clear;
        +		unsigned int enc; 
        +		unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
        +		unsigned int cipher_spec_length;
        +		unsigned int session_id_length;
        +		unsigned int clen;
        +		unsigned int rlen;
        +		} tmp;
        +	} SSL2_STATE;
        +
        +#endif
        +
        +/* SSLv2 */
        +/* client */
        +#define SSL2_ST_SEND_CLIENT_HELLO_A		(0x10|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_HELLO_B		(0x11|SSL_ST_CONNECT)
        +#define SSL2_ST_GET_SERVER_HELLO_A		(0x20|SSL_ST_CONNECT)
        +#define SSL2_ST_GET_SERVER_HELLO_B		(0x21|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A	(0x30|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B	(0x31|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_FINISHED_A		(0x40|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_FINISHED_B		(0x41|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A	(0x50|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B	(0x51|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C	(0x52|SSL_ST_CONNECT)
        +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D	(0x53|SSL_ST_CONNECT)
        +#define SSL2_ST_GET_SERVER_VERIFY_A		(0x60|SSL_ST_CONNECT)
        +#define SSL2_ST_GET_SERVER_VERIFY_B		(0x61|SSL_ST_CONNECT)
        +#define SSL2_ST_GET_SERVER_FINISHED_A		(0x70|SSL_ST_CONNECT)
        +#define SSL2_ST_GET_SERVER_FINISHED_B		(0x71|SSL_ST_CONNECT)
        +#define SSL2_ST_CLIENT_START_ENCRYPTION		(0x80|SSL_ST_CONNECT)
        +#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE	(0x90|SSL_ST_CONNECT)
        +/* server */
        +#define SSL2_ST_GET_CLIENT_HELLO_A		(0x10|SSL_ST_ACCEPT)
        +#define SSL2_ST_GET_CLIENT_HELLO_B		(0x11|SSL_ST_ACCEPT)
        +#define SSL2_ST_GET_CLIENT_HELLO_C		(0x12|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_HELLO_A		(0x20|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_HELLO_B		(0x21|SSL_ST_ACCEPT)
        +#define SSL2_ST_GET_CLIENT_MASTER_KEY_A		(0x30|SSL_ST_ACCEPT)
        +#define SSL2_ST_GET_CLIENT_MASTER_KEY_B		(0x31|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_VERIFY_A		(0x40|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_VERIFY_B		(0x41|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_VERIFY_C		(0x42|SSL_ST_ACCEPT)
        +#define SSL2_ST_GET_CLIENT_FINISHED_A		(0x50|SSL_ST_ACCEPT)
        +#define SSL2_ST_GET_CLIENT_FINISHED_B		(0x51|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_FINISHED_A		(0x60|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_SERVER_FINISHED_B		(0x61|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A	(0x70|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B	(0x71|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C	(0x72|SSL_ST_ACCEPT)
        +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D	(0x73|SSL_ST_ACCEPT)
        +#define SSL2_ST_SERVER_START_ENCRYPTION		(0x80|SSL_ST_ACCEPT)
        +#define SSL2_ST_X509_GET_SERVER_CERTIFICATE	(0x90|SSL_ST_ACCEPT)
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl23.h b/vendor/openssl/openssl/ssl/ssl23.h
        new file mode 100644
        index 000000000..d3228983c
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl23.h
        @@ -0,0 +1,83 @@
        +/* ssl/ssl23.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_SSL23_H 
        +#define HEADER_SSL23_H 
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/*client */
        +/* write to server */
        +#define SSL23_ST_CW_CLNT_HELLO_A	(0x210|SSL_ST_CONNECT)
        +#define SSL23_ST_CW_CLNT_HELLO_B	(0x211|SSL_ST_CONNECT)
        +/* read from server */
        +#define SSL23_ST_CR_SRVR_HELLO_A	(0x220|SSL_ST_CONNECT)
        +#define SSL23_ST_CR_SRVR_HELLO_B	(0x221|SSL_ST_CONNECT)
        +
        +/* server */
        +/* read from client */
        +#define SSL23_ST_SR_CLNT_HELLO_A	(0x210|SSL_ST_ACCEPT)
        +#define SSL23_ST_SR_CLNT_HELLO_B	(0x211|SSL_ST_ACCEPT)
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl3.h b/vendor/openssl/openssl/ssl/ssl3.h
        new file mode 100644
        index 000000000..247e88c2d
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl3.h
        @@ -0,0 +1,684 @@
        +/* ssl/ssl3.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#ifndef HEADER_SSL3_H 
        +#define HEADER_SSL3_H 
        +
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#include <openssl/buffer.h>
        +#include <openssl/evp.h>
        +#include <openssl/ssl.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
        +#define SSL3_CK_SCSV				0x030000FF
        +
        +#define SSL3_CK_RSA_NULL_MD5			0x03000001
        +#define SSL3_CK_RSA_NULL_SHA			0x03000002
        +#define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
        +#define SSL3_CK_RSA_RC4_128_MD5			0x03000004
        +#define SSL3_CK_RSA_RC4_128_SHA			0x03000005
        +#define SSL3_CK_RSA_RC2_40_MD5			0x03000006
        +#define SSL3_CK_RSA_IDEA_128_SHA		0x03000007
        +#define SSL3_CK_RSA_DES_40_CBC_SHA		0x03000008
        +#define SSL3_CK_RSA_DES_64_CBC_SHA		0x03000009
        +#define SSL3_CK_RSA_DES_192_CBC3_SHA		0x0300000A
        +
        +#define SSL3_CK_DH_DSS_DES_40_CBC_SHA		0x0300000B
        +#define SSL3_CK_DH_DSS_DES_64_CBC_SHA		0x0300000C
        +#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 	0x0300000D
        +#define SSL3_CK_DH_RSA_DES_40_CBC_SHA		0x0300000E
        +#define SSL3_CK_DH_RSA_DES_64_CBC_SHA		0x0300000F
        +#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 	0x03000010
        +
        +#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA		0x03000011
        +#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA		0x03000012
        +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA	0x03000013
        +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA		0x03000014
        +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA		0x03000015
        +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA	0x03000016
        +
        +#define SSL3_CK_ADH_RC4_40_MD5			0x03000017
        +#define SSL3_CK_ADH_RC4_128_MD5			0x03000018
        +#define SSL3_CK_ADH_DES_40_CBC_SHA		0x03000019
        +#define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
        +#define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
        +
        +#if 0
        +	#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
        +	#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
        +	#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
        +		 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
        +		 of the ietf-tls list */
        +	#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
        +	#endif
        +#endif
        +
        +/*    VRS Additional Kerberos5 entries
        + */
        +#define SSL3_CK_KRB5_DES_64_CBC_SHA		0x0300001E
        +#define SSL3_CK_KRB5_DES_192_CBC3_SHA		0x0300001F
        +#define SSL3_CK_KRB5_RC4_128_SHA		0x03000020
        +#define SSL3_CK_KRB5_IDEA_128_CBC_SHA	       	0x03000021
        +#define SSL3_CK_KRB5_DES_64_CBC_MD5       	0x03000022
        +#define SSL3_CK_KRB5_DES_192_CBC3_MD5       	0x03000023
        +#define SSL3_CK_KRB5_RC4_128_MD5	       	0x03000024
        +#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 		0x03000025
        +
        +#define SSL3_CK_KRB5_DES_40_CBC_SHA 		0x03000026
        +#define SSL3_CK_KRB5_RC2_40_CBC_SHA 		0x03000027
        +#define SSL3_CK_KRB5_RC4_40_SHA	 		0x03000028
        +#define SSL3_CK_KRB5_DES_40_CBC_MD5 		0x03000029
        +#define SSL3_CK_KRB5_RC2_40_CBC_MD5 		0x0300002A
        +#define SSL3_CK_KRB5_RC4_40_MD5	 		0x0300002B
        +
        +#define SSL3_TXT_RSA_NULL_MD5			"NULL-MD5"
        +#define SSL3_TXT_RSA_NULL_SHA			"NULL-SHA"
        +#define SSL3_TXT_RSA_RC4_40_MD5 		"EXP-RC4-MD5"
        +#define SSL3_TXT_RSA_RC4_128_MD5		"RC4-MD5"
        +#define SSL3_TXT_RSA_RC4_128_SHA		"RC4-SHA"
        +#define SSL3_TXT_RSA_RC2_40_MD5			"EXP-RC2-CBC-MD5"
        +#define SSL3_TXT_RSA_IDEA_128_SHA		"IDEA-CBC-SHA"
        +#define SSL3_TXT_RSA_DES_40_CBC_SHA		"EXP-DES-CBC-SHA"
        +#define SSL3_TXT_RSA_DES_64_CBC_SHA		"DES-CBC-SHA"
        +#define SSL3_TXT_RSA_DES_192_CBC3_SHA		"DES-CBC3-SHA"
        +
        +#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA		"EXP-DH-DSS-DES-CBC-SHA"
        +#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA		"DH-DSS-DES-CBC-SHA"
        +#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA 	"DH-DSS-DES-CBC3-SHA"
        +#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA		"EXP-DH-RSA-DES-CBC-SHA"
        +#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA		"DH-RSA-DES-CBC-SHA"
        +#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA 	"DH-RSA-DES-CBC3-SHA"
        +
        +#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA		"EXP-EDH-DSS-DES-CBC-SHA"
        +#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA		"EDH-DSS-DES-CBC-SHA"
        +#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA	"EDH-DSS-DES-CBC3-SHA"
        +#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA		"EXP-EDH-RSA-DES-CBC-SHA"
        +#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA		"EDH-RSA-DES-CBC-SHA"
        +#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA	"EDH-RSA-DES-CBC3-SHA"
        +
        +#define SSL3_TXT_ADH_RC4_40_MD5			"EXP-ADH-RC4-MD5"
        +#define SSL3_TXT_ADH_RC4_128_MD5		"ADH-RC4-MD5"
        +#define SSL3_TXT_ADH_DES_40_CBC_SHA		"EXP-ADH-DES-CBC-SHA"
        +#define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
        +#define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
        +
        +#if 0
        +	#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
        +	#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
        +	#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
        +#endif
        +
        +#define SSL3_TXT_KRB5_DES_64_CBC_SHA		"KRB5-DES-CBC-SHA"
        +#define SSL3_TXT_KRB5_DES_192_CBC3_SHA		"KRB5-DES-CBC3-SHA"
        +#define SSL3_TXT_KRB5_RC4_128_SHA		"KRB5-RC4-SHA"
        +#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA	       	"KRB5-IDEA-CBC-SHA"
        +#define SSL3_TXT_KRB5_DES_64_CBC_MD5       	"KRB5-DES-CBC-MD5"
        +#define SSL3_TXT_KRB5_DES_192_CBC3_MD5       	"KRB5-DES-CBC3-MD5"
        +#define SSL3_TXT_KRB5_RC4_128_MD5		"KRB5-RC4-MD5"
        +#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 		"KRB5-IDEA-CBC-MD5"
        +
        +#define SSL3_TXT_KRB5_DES_40_CBC_SHA 		"EXP-KRB5-DES-CBC-SHA"
        +#define SSL3_TXT_KRB5_RC2_40_CBC_SHA 		"EXP-KRB5-RC2-CBC-SHA"
        +#define SSL3_TXT_KRB5_RC4_40_SHA	 	"EXP-KRB5-RC4-SHA"
        +#define SSL3_TXT_KRB5_DES_40_CBC_MD5 		"EXP-KRB5-DES-CBC-MD5"
        +#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 		"EXP-KRB5-RC2-CBC-MD5"
        +#define SSL3_TXT_KRB5_RC4_40_MD5	 	"EXP-KRB5-RC4-MD5"
        +
        +#define SSL3_SSL_SESSION_ID_LENGTH		32
        +#define SSL3_MAX_SSL_SESSION_ID_LENGTH		32
        +
        +#define SSL3_MASTER_SECRET_SIZE			48
        +#define SSL3_RANDOM_SIZE			32
        +#define SSL3_SESSION_ID_SIZE			32
        +#define SSL3_RT_HEADER_LENGTH			5
        +
        +#ifndef SSL3_ALIGN_PAYLOAD
        + /* Some will argue that this increases memory footprint, but it's
        +  * not actually true. Point is that malloc has to return at least
        +  * 64-bit aligned pointers, meaning that allocating 5 bytes wastes
        +  * 3 bytes in either case. Suggested pre-gaping simply moves these
        +  * wasted bytes from the end of allocated region to its front,
        +  * but makes data payload aligned, which improves performance:-) */
        +# define SSL3_ALIGN_PAYLOAD			8
        +#else
        +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
        +#  error "insane SSL3_ALIGN_PAYLOAD"
        +#  undef SSL3_ALIGN_PAYLOAD
        +# endif
        +#endif
        +
        +/* This is the maximum MAC (digest) size used by the SSL library.
        + * Currently maximum of 20 is used by SHA1, but we reserve for
        + * future extension for 512-bit hashes.
        + */
        +
        +#define SSL3_RT_MAX_MD_SIZE			64
        +
        +/* Maximum block size used in all ciphersuites. Currently 16 for AES.
        + */
        +
        +#define	SSL_RT_MAX_CIPHER_BLOCK_SIZE		16
        +
        +#define SSL3_RT_MAX_EXTRA			(16384)
        +
        +/* Maximum plaintext length: defined by SSL/TLS standards */
        +#define SSL3_RT_MAX_PLAIN_LENGTH		16384
        +/* Maximum compression overhead: defined by SSL/TLS standards */
        +#define SSL3_RT_MAX_COMPRESSED_OVERHEAD		1024
        +
        +/* The standards give a maximum encryption overhead of 1024 bytes.
        + * In practice the value is lower than this. The overhead is the maximum
        + * number of padding bytes (256) plus the mac size.
        + */
        +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD	(256 + SSL3_RT_MAX_MD_SIZE)
        +
        +/* OpenSSL currently only uses a padding length of at most one block so
        + * the send overhead is smaller.
        + */
        +
        +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
        +			(SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
        +
        +/* If compression isn't used don't include the compression overhead */
        +
        +#ifdef OPENSSL_NO_COMP
        +#define SSL3_RT_MAX_COMPRESSED_LENGTH		SSL3_RT_MAX_PLAIN_LENGTH
        +#else
        +#define SSL3_RT_MAX_COMPRESSED_LENGTH	\
        +		(SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
        +#endif
        +#define SSL3_RT_MAX_ENCRYPTED_LENGTH	\
        +		(SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
        +#define SSL3_RT_MAX_PACKET_SIZE		\
        +		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
        +
        +#define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
        +#define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
        +
        +#define SSL3_VERSION			0x0300
        +#define SSL3_VERSION_MAJOR		0x03
        +#define SSL3_VERSION_MINOR		0x00
        +
        +#define SSL3_RT_CHANGE_CIPHER_SPEC	20
        +#define SSL3_RT_ALERT			21
        +#define SSL3_RT_HANDSHAKE		22
        +#define SSL3_RT_APPLICATION_DATA	23
        +#define TLS1_RT_HEARTBEAT		24
        +
        +#define SSL3_AL_WARNING			1
        +#define SSL3_AL_FATAL			2
        +
        +#define SSL3_AD_CLOSE_NOTIFY		 0
        +#define SSL3_AD_UNEXPECTED_MESSAGE	10	/* fatal */
        +#define SSL3_AD_BAD_RECORD_MAC		20	/* fatal */
        +#define SSL3_AD_DECOMPRESSION_FAILURE	30	/* fatal */
        +#define SSL3_AD_HANDSHAKE_FAILURE	40	/* fatal */
        +#define SSL3_AD_NO_CERTIFICATE		41
        +#define SSL3_AD_BAD_CERTIFICATE		42
        +#define SSL3_AD_UNSUPPORTED_CERTIFICATE	43
        +#define SSL3_AD_CERTIFICATE_REVOKED	44
        +#define SSL3_AD_CERTIFICATE_EXPIRED	45
        +#define SSL3_AD_CERTIFICATE_UNKNOWN	46
        +#define SSL3_AD_ILLEGAL_PARAMETER	47	/* fatal */
        +
        +#define TLS1_HB_REQUEST		1
        +#define TLS1_HB_RESPONSE	2
        +	
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +typedef struct ssl3_record_st
        +	{
        +/*r */	int type;               /* type of record */
        +/*rw*/	unsigned int length;    /* How many bytes available */
        +/*r */	unsigned int off;       /* read/write offset into 'buf' */
        +/*rw*/	unsigned char *data;    /* pointer to the record data */
        +/*rw*/	unsigned char *input;   /* where the decode bytes are */
        +/*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
        +/*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
        +/*r */  unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
        +	} SSL3_RECORD;
        +
        +typedef struct ssl3_buffer_st
        +	{
        +	unsigned char *buf;     /* at least SSL3_RT_MAX_PACKET_SIZE bytes,
        +	                         * see ssl3_setup_buffers() */
        +	size_t len;             /* buffer size */
        +	int offset;             /* where to 'copy from' */
        +	int left;               /* how many bytes left */
        +	} SSL3_BUFFER;
        +
        +#endif
        +
        +#define SSL3_CT_RSA_SIGN			1
        +#define SSL3_CT_DSS_SIGN			2
        +#define SSL3_CT_RSA_FIXED_DH			3
        +#define SSL3_CT_DSS_FIXED_DH			4
        +#define SSL3_CT_RSA_EPHEMERAL_DH		5
        +#define SSL3_CT_DSS_EPHEMERAL_DH		6
        +#define SSL3_CT_FORTEZZA_DMS			20
        +/* SSL3_CT_NUMBER is used to size arrays and it must be large
        + * enough to contain all of the cert types defined either for
        + * SSLv3 and TLSv1.
        + */
        +#define SSL3_CT_NUMBER			9
        +
        +
        +#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
        +#define SSL3_FLAGS_DELAY_CLIENT_FINISHED	0x0002
        +#define SSL3_FLAGS_POP_BUFFER			0x0004
        +#define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
        +#define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
        +#define TLS1_FLAGS_KEEP_HANDSHAKE		0x0020
        + 
        +/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
        + * restart a handshake because of MS SGC and so prevents us
        + * from restarting the handshake in a loop. It's reset on a
        + * renegotiation, so effectively limits the client to one restart
        + * per negotiation. This limits the possibility of a DDoS
        + * attack where the client handshakes in a loop using SGC to
        + * restart. Servers which permit renegotiation can still be
        + * effected, but we can't prevent that.
        + */
        +#define SSL3_FLAGS_SGC_RESTART_DONE		0x0040
        +
        +#ifndef OPENSSL_NO_SSL_INTERN
        +
        +typedef struct ssl3_state_st
        +	{
        +	long flags;
        +	int delay_buf_pop_ret;
        +
        +	unsigned char read_sequence[8];
        +	int read_mac_secret_size;
        +	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
        +	unsigned char write_sequence[8];
        +	int write_mac_secret_size;
        +	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
        +
        +	unsigned char server_random[SSL3_RANDOM_SIZE];
        +	unsigned char client_random[SSL3_RANDOM_SIZE];
        +
        +	/* flags for countermeasure against known-IV weakness */
        +	int need_empty_fragments;
        +	int empty_fragment_done;
        +
        +	/* The value of 'extra' when the buffers were initialized */
        +	int init_extra;
        +
        +	SSL3_BUFFER rbuf;	/* read IO goes into here */
        +	SSL3_BUFFER wbuf;	/* write IO goes into here */
        +
        +	SSL3_RECORD rrec;	/* each decoded record goes in here */
        +	SSL3_RECORD wrec;	/* goes out from here */
        +
        +	/* storage for Alert/Handshake protocol data received but not
        +	 * yet processed by ssl3_read_bytes: */
        +	unsigned char alert_fragment[2];
        +	unsigned int alert_fragment_len;
        +	unsigned char handshake_fragment[4];
        +	unsigned int handshake_fragment_len;
        +
        +	/* partial write - check the numbers match */
        +	unsigned int wnum;	/* number of bytes sent so far */
        +	int wpend_tot;		/* number bytes written */
        +	int wpend_type;
        +	int wpend_ret;		/* number of bytes submitted */
        +	const unsigned char *wpend_buf;
        +
        +	/* used during startup, digest all incoming/outgoing packets */
        +	BIO *handshake_buffer;
        +	/* When set of handshake digests is determined, buffer is hashed
        +	 * and freed and MD_CTX-es for all required digests are stored in
        +	 * this array */
        +	EVP_MD_CTX **handshake_dgst;
        +	/* this is set whenerver we see a change_cipher_spec message
        +	 * come in when we are not looking for one */
        +	int change_cipher_spec;
        +
        +	int warn_alert;
        +	int fatal_alert;
        +	/* we allow one fatal and one warning alert to be outstanding,
        +	 * send close alert via the warning alert */
        +	int alert_dispatch;
        +	unsigned char send_alert[2];
        +
        +	/* This flag is set when we should renegotiate ASAP, basically when
        +	 * there is no more data in the read or write buffers */
        +	int renegotiate;
        +	int total_renegotiations;
        +	int num_renegotiations;
        +
        +	int in_read_app_data;
        +
        +	/* Opaque PRF input as used for the current handshake.
        +	 * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined
        +	 * (otherwise, they are merely present to improve binary compatibility) */
        +	void *client_opaque_prf_input;
        +	size_t client_opaque_prf_input_len;
        +	void *server_opaque_prf_input;
        +	size_t server_opaque_prf_input_len;
        +
        +	struct	{
        +		/* actually only needs to be 16+20 */
        +		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
        +
        +		/* actually only need to be 16+20 for SSLv3 and 12 for TLS */
        +		unsigned char finish_md[EVP_MAX_MD_SIZE*2];
        +		int finish_md_len;
        +		unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
        +		int peer_finish_md_len;
        +
        +		unsigned long message_size;
        +		int message_type;
        +
        +		/* used to hold the new cipher we are going to use */
        +		const SSL_CIPHER *new_cipher;
        +#ifndef OPENSSL_NO_DH
        +		DH *dh;
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +		EC_KEY *ecdh; /* holds short lived ECDH key */
        +#endif
        +
        +		/* used when SSL_ST_FLUSH_DATA is entered */
        +		int next_state;			
        +
        +		int reuse_message;
        +
        +		/* used for certificate requests */
        +		int cert_req;
        +		int ctype_num;
        +		char ctype[SSL3_CT_NUMBER];
        +		STACK_OF(X509_NAME) *ca_names;
        +
        +		int use_rsa_tmp;
        +
        +		int key_block_length;
        +		unsigned char *key_block;
        +
        +		const EVP_CIPHER *new_sym_enc;
        +		const EVP_MD *new_hash;
        +		int new_mac_pkey_type;
        +		int new_mac_secret_size;
        +#ifndef OPENSSL_NO_COMP
        +		const SSL_COMP *new_compression;
        +#else
        +		char *new_compression;
        +#endif
        +		int cert_request;
        +		} tmp;
        +
        +        /* Connection binding to prevent renegotiation attacks */
        +        unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
        +        unsigned char previous_client_finished_len;
        +        unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
        +        unsigned char previous_server_finished_len;
        +        int send_connection_binding; /* TODOEKR */
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	/* Set if we saw the Next Protocol Negotiation extension from our peer. */
        +	int next_proto_neg_seen;
        +#endif
        +	} SSL3_STATE;
        +
        +#endif
        +
        +/* SSLv3 */
        +/*client */
        +/* extra state */
        +#define SSL3_ST_CW_FLUSH		(0x100|SSL_ST_CONNECT)
        +#ifndef OPENSSL_NO_SCTP
        +#define DTLS1_SCTP_ST_CW_WRITE_SOCK			(0x310|SSL_ST_CONNECT)
        +#define DTLS1_SCTP_ST_CR_READ_SOCK			(0x320|SSL_ST_CONNECT)
        +#endif	
        +/* write to server */
        +#define SSL3_ST_CW_CLNT_HELLO_A		(0x110|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CLNT_HELLO_B		(0x111|SSL_ST_CONNECT)
        +/* read from server */
        +#define SSL3_ST_CR_SRVR_HELLO_A		(0x120|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_SRVR_HELLO_B		(0x121|SSL_ST_CONNECT)
        +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
        +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CERT_A		(0x130|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CERT_B		(0x131|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_KEY_EXCH_A		(0x140|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_KEY_EXCH_B		(0x141|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CERT_REQ_A		(0x150|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CERT_REQ_B		(0x151|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_SRVR_DONE_A		(0x160|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_SRVR_DONE_B		(0x161|SSL_ST_CONNECT)
        +/* write to server */
        +#define SSL3_ST_CW_CERT_A		(0x170|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CERT_B		(0x171|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CERT_C		(0x172|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CERT_D		(0x173|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_KEY_EXCH_A		(0x180|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_KEY_EXCH_B		(0x181|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CERT_VRFY_A		(0x190|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +#define SSL3_ST_CW_NEXT_PROTO_A		(0x200|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_NEXT_PROTO_B		(0x201|SSL_ST_CONNECT)
        +#endif
        +#define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
        +#define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
        +/* read from server */
        +#define SSL3_ST_CR_CHANGE_A		(0x1C0|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CHANGE_B		(0x1C1|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_FINISHED_A		(0x1D0|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_FINISHED_B		(0x1D1|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_SESSION_TICKET_A	(0x1E0|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_SESSION_TICKET_B	(0x1E1|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CERT_STATUS_A	(0x1F0|SSL_ST_CONNECT)
        +#define SSL3_ST_CR_CERT_STATUS_B	(0x1F1|SSL_ST_CONNECT)
        +
        +/* server */
        +/* extra state */
        +#define SSL3_ST_SW_FLUSH		(0x100|SSL_ST_ACCEPT)
        +#ifndef OPENSSL_NO_SCTP
        +#define DTLS1_SCTP_ST_SW_WRITE_SOCK			(0x310|SSL_ST_ACCEPT)
        +#define DTLS1_SCTP_ST_SR_READ_SOCK			(0x320|SSL_ST_ACCEPT)
        +#endif	
        +/* read from client */
        +/* Do not change the number values, they do matter */
        +#define SSL3_ST_SR_CLNT_HELLO_A		(0x110|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CLNT_HELLO_B		(0x111|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CLNT_HELLO_C		(0x112|SSL_ST_ACCEPT)
        +/* write to client */
        +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
        +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_HELLO_REQ_A		(0x120|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_HELLO_REQ_B		(0x121|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_HELLO_REQ_C		(0x122|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_SRVR_HELLO_A		(0x130|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_SRVR_HELLO_B		(0x131|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CERT_A		(0x140|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CERT_B		(0x141|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_KEY_EXCH_A		(0x150|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_KEY_EXCH_B		(0x151|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CERT_REQ_A		(0x160|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CERT_REQ_B		(0x161|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_SRVR_DONE_A		(0x170|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_SRVR_DONE_B		(0x171|SSL_ST_ACCEPT)
        +/* read from client */
        +#define SSL3_ST_SR_CERT_A		(0x180|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CERT_B		(0x181|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_KEY_EXCH_A		(0x190|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_KEY_EXCH_B		(0x191|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CERT_VRFY_A		(0x1A0|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +#define SSL3_ST_SR_NEXT_PROTO_A		(0x210|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_NEXT_PROTO_B		(0x211|SSL_ST_ACCEPT)
        +#endif
        +#define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
        +#define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
        +/* write to client */
        +#define SSL3_ST_SW_CHANGE_A		(0x1D0|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CHANGE_B		(0x1D1|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_FINISHED_A		(0x1E0|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_FINISHED_B		(0x1E1|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_SESSION_TICKET_A	(0x1F0|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_SESSION_TICKET_B	(0x1F1|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CERT_STATUS_A	(0x200|SSL_ST_ACCEPT)
        +#define SSL3_ST_SW_CERT_STATUS_B	(0x201|SSL_ST_ACCEPT)
        +
        +#define SSL3_MT_HELLO_REQUEST			0
        +#define SSL3_MT_CLIENT_HELLO			1
        +#define SSL3_MT_SERVER_HELLO			2
        +#define	SSL3_MT_NEWSESSION_TICKET		4
        +#define SSL3_MT_CERTIFICATE			11
        +#define SSL3_MT_SERVER_KEY_EXCHANGE		12
        +#define SSL3_MT_CERTIFICATE_REQUEST		13
        +#define SSL3_MT_SERVER_DONE			14
        +#define SSL3_MT_CERTIFICATE_VERIFY		15
        +#define SSL3_MT_CLIENT_KEY_EXCHANGE		16
        +#define SSL3_MT_FINISHED			20
        +#define SSL3_MT_CERTIFICATE_STATUS		22
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +#define SSL3_MT_NEXT_PROTO			67
        +#endif
        +#define DTLS1_MT_HELLO_VERIFY_REQUEST    3
        +
        +
        +#define SSL3_MT_CCS				1
        +
        +/* These are used when changing over to a new cipher */
        +#define SSL3_CC_READ		0x01
        +#define SSL3_CC_WRITE		0x02
        +#define SSL3_CC_CLIENT		0x10
        +#define SSL3_CC_SERVER		0x20
        +#define SSL3_CHANGE_CIPHER_CLIENT_WRITE	(SSL3_CC_CLIENT|SSL3_CC_WRITE)	
        +#define SSL3_CHANGE_CIPHER_SERVER_READ	(SSL3_CC_SERVER|SSL3_CC_READ)
        +#define SSL3_CHANGE_CIPHER_CLIENT_READ	(SSL3_CC_CLIENT|SSL3_CC_READ)
        +#define SSL3_CHANGE_CIPHER_SERVER_WRITE	(SSL3_CC_SERVER|SSL3_CC_WRITE)
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl_algs.c b/vendor/openssl/openssl/ssl/ssl_algs.c
        new file mode 100644
        index 000000000..9c34d1972
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_algs.c
        @@ -0,0 +1,150 @@
        +/* ssl/ssl_algs.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include <openssl/lhash.h>
        +#include "ssl_locl.h"
        +
        +int SSL_library_init(void)
        +	{
        +
        +#ifndef OPENSSL_NO_DES
        +	EVP_add_cipher(EVP_des_cbc());
        +	EVP_add_cipher(EVP_des_ede3_cbc());
        +#endif
        +#ifndef OPENSSL_NO_IDEA
        +	EVP_add_cipher(EVP_idea_cbc());
        +#endif
        +#ifndef OPENSSL_NO_RC4
        +	EVP_add_cipher(EVP_rc4());
        +#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__))
        +	EVP_add_cipher(EVP_rc4_hmac_md5());
        +#endif
        +#endif  
        +#ifndef OPENSSL_NO_RC2
        +	EVP_add_cipher(EVP_rc2_cbc());
        +	/* Not actually used for SSL/TLS but this makes PKCS#12 work
        +	 * if an application only calls SSL_library_init().
        +	 */
        +	EVP_add_cipher(EVP_rc2_40_cbc());
        +#endif
        +#ifndef OPENSSL_NO_AES
        +	EVP_add_cipher(EVP_aes_128_cbc());
        +	EVP_add_cipher(EVP_aes_192_cbc());
        +	EVP_add_cipher(EVP_aes_256_cbc());
        +	EVP_add_cipher(EVP_aes_128_gcm());
        +	EVP_add_cipher(EVP_aes_256_gcm());
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
        +	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
        +	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
        +#endif
        +
        +#endif
        +#ifndef OPENSSL_NO_CAMELLIA
        +	EVP_add_cipher(EVP_camellia_128_cbc());
        +	EVP_add_cipher(EVP_camellia_256_cbc());
        +#endif
        +
        +#ifndef OPENSSL_NO_SEED
        +	EVP_add_cipher(EVP_seed_cbc());
        +#endif
        +  
        +#ifndef OPENSSL_NO_MD5
        +	EVP_add_digest(EVP_md5());
        +	EVP_add_digest_alias(SN_md5,"ssl2-md5");
        +	EVP_add_digest_alias(SN_md5,"ssl3-md5");
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
        +	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
        +	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +	EVP_add_digest(EVP_sha224());
        +	EVP_add_digest(EVP_sha256());
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +	EVP_add_digest(EVP_sha384());
        +	EVP_add_digest(EVP_sha512());
        +#endif
        +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)
        +	EVP_add_digest(EVP_dss1()); /* DSA with sha1 */
        +	EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
        +	EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
        +	EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	EVP_add_digest(EVP_ecdsa());
        +#endif
        +	/* If you want support for phased out ciphers, add the following */
        +#if 0
        +	EVP_add_digest(EVP_sha());
        +	EVP_add_digest(EVP_dss());
        +#endif
        +#ifndef OPENSSL_NO_COMP
        +	/* This will initialise the built-in compression algorithms.
        +	   The value returned is a STACK_OF(SSL_COMP), but that can
        +	   be discarded safely */
        +	(void)SSL_COMP_get_compression_methods();
        +#endif
        +	/* initialize cipher/digest methods table */
        +	ssl_load_ciphers();
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl_asn1.c b/vendor/openssl/openssl/ssl/ssl_asn1.c
        new file mode 100644
        index 000000000..38540be1e
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_asn1.c
        @@ -0,0 +1,642 @@
        +/* ssl/ssl_asn1.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 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include "ssl_locl.h"
        +#include <openssl/asn1_mac.h>
        +#include <openssl/objects.h>
        +#include <openssl/x509.h>
        +
        +typedef struct ssl_session_asn1_st
        +	{
        +	ASN1_INTEGER version;
        +	ASN1_INTEGER ssl_version;
        +	ASN1_OCTET_STRING cipher;
        +	ASN1_OCTET_STRING comp_id;
        +	ASN1_OCTET_STRING master_key;
        +	ASN1_OCTET_STRING session_id;
        +	ASN1_OCTET_STRING session_id_context;
        +	ASN1_OCTET_STRING key_arg;
        +#ifndef OPENSSL_NO_KRB5
        +        ASN1_OCTET_STRING krb5_princ;
        +#endif /* OPENSSL_NO_KRB5 */
        +	ASN1_INTEGER time;
        +	ASN1_INTEGER timeout;
        +	ASN1_INTEGER verify_result;
        +#ifndef OPENSSL_NO_TLSEXT
        +	ASN1_OCTET_STRING tlsext_hostname;
        +	ASN1_INTEGER tlsext_tick_lifetime;
        +	ASN1_OCTET_STRING tlsext_tick;
        +#endif /* OPENSSL_NO_TLSEXT */
        +#ifndef OPENSSL_NO_PSK
        +	ASN1_OCTET_STRING psk_identity_hint;
        +	ASN1_OCTET_STRING psk_identity;
        +#endif /* OPENSSL_NO_PSK */
        +#ifndef OPENSSL_NO_SRP
        +	ASN1_OCTET_STRING srp_username;
        +#endif /* OPENSSL_NO_SRP */
        +	} SSL_SESSION_ASN1;
        +
        +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
        +	{
        +#define LSIZE2 (sizeof(long)*2)
        +	int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0;
        +	unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
        +	unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
        +#ifndef OPENSSL_NO_TLSEXT
        +	int v6=0,v9=0,v10=0;
        +	unsigned char ibuf6[LSIZE2];
        +#endif
        +#ifndef OPENSSL_NO_COMP
        +	unsigned char cbuf;
        +	int v11=0;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	int v12=0;
        +#endif
        +	long l;
        +	SSL_SESSION_ASN1 a;
        +	M_ASN1_I2D_vars(in);
        +
        +	if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
        +		return(0);
        +
        +	/* Note that I cheat in the following 2 assignments.  I know
        +	 * that if the ASN1_INTEGER passed to ASN1_INTEGER_set
        +	 * is > sizeof(long)+1, the buffer will not be re-OPENSSL_malloc()ed.
        +	 * This is a bit evil but makes things simple, no dynamic allocation
        +	 * to clean up :-) */
        +	a.version.length=LSIZE2;
        +	a.version.type=V_ASN1_INTEGER;
        +	a.version.data=ibuf1;
        +	ASN1_INTEGER_set(&(a.version),SSL_SESSION_ASN1_VERSION);
        +
        +	a.ssl_version.length=LSIZE2;
        +	a.ssl_version.type=V_ASN1_INTEGER;
        +	a.ssl_version.data=ibuf2;
        +	ASN1_INTEGER_set(&(a.ssl_version),in->ssl_version);
        +
        +	a.cipher.type=V_ASN1_OCTET_STRING;
        +	a.cipher.data=buf;
        +
        +	if (in->cipher == NULL)
        +		l=in->cipher_id;
        +	else
        +		l=in->cipher->id;
        +	if (in->ssl_version == SSL2_VERSION)
        +		{
        +		a.cipher.length=3;
        +		buf[0]=((unsigned char)(l>>16L))&0xff;
        +		buf[1]=((unsigned char)(l>> 8L))&0xff;
        +		buf[2]=((unsigned char)(l     ))&0xff;
        +		}
        +	else
        +		{
        +		a.cipher.length=2;
        +		buf[0]=((unsigned char)(l>>8L))&0xff;
        +		buf[1]=((unsigned char)(l    ))&0xff;
        +		}
        +
        +#ifndef OPENSSL_NO_COMP
        +	if (in->compress_meth)
        +		{
        +		cbuf = (unsigned char)in->compress_meth;
        +		a.comp_id.length = 1;
        +		a.comp_id.type = V_ASN1_OCTET_STRING;
        +		a.comp_id.data = &cbuf;
        +		}
        +#endif
        +
        +	a.master_key.length=in->master_key_length;
        +	a.master_key.type=V_ASN1_OCTET_STRING;
        +	a.master_key.data=in->master_key;
        +
        +	a.session_id.length=in->session_id_length;
        +	a.session_id.type=V_ASN1_OCTET_STRING;
        +	a.session_id.data=in->session_id;
        +
        +	a.session_id_context.length=in->sid_ctx_length;
        +	a.session_id_context.type=V_ASN1_OCTET_STRING;
        +	a.session_id_context.data=in->sid_ctx;
        +
        +	a.key_arg.length=in->key_arg_length;
        +	a.key_arg.type=V_ASN1_OCTET_STRING;
        +	a.key_arg.data=in->key_arg;
        +
        +#ifndef OPENSSL_NO_KRB5
        +	if (in->krb5_client_princ_len)
        +		{
        +		a.krb5_princ.length=in->krb5_client_princ_len;
        +		a.krb5_princ.type=V_ASN1_OCTET_STRING;
        +		a.krb5_princ.data=in->krb5_client_princ;
        +		}
        +#endif /* OPENSSL_NO_KRB5 */
        +
        +	if (in->time != 0L)
        +		{
        +		a.time.length=LSIZE2;
        +		a.time.type=V_ASN1_INTEGER;
        +		a.time.data=ibuf3;
        +		ASN1_INTEGER_set(&(a.time),in->time);
        +		}
        +
        +	if (in->timeout != 0L)
        +		{
        +		a.timeout.length=LSIZE2;
        +		a.timeout.type=V_ASN1_INTEGER;
        +		a.timeout.data=ibuf4;
        +		ASN1_INTEGER_set(&(a.timeout),in->timeout);
        +		}
        +
        +	if (in->verify_result != X509_V_OK)
        +		{
        +		a.verify_result.length=LSIZE2;
        +		a.verify_result.type=V_ASN1_INTEGER;
        +		a.verify_result.data=ibuf5;
        +		ASN1_INTEGER_set(&a.verify_result,in->verify_result);
        +		}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (in->tlsext_hostname)
        +                {
        +                a.tlsext_hostname.length=strlen(in->tlsext_hostname);
        +                a.tlsext_hostname.type=V_ASN1_OCTET_STRING;
        +                a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname;
        +                }
        +	if (in->tlsext_tick)
        +                {
        +                a.tlsext_tick.length= in->tlsext_ticklen;
        +                a.tlsext_tick.type=V_ASN1_OCTET_STRING;
        +                a.tlsext_tick.data=(unsigned char *)in->tlsext_tick;
        +                }
        +	if (in->tlsext_tick_lifetime_hint > 0)
        +		{
        +		a.tlsext_tick_lifetime.length=LSIZE2;
        +		a.tlsext_tick_lifetime.type=V_ASN1_INTEGER;
        +		a.tlsext_tick_lifetime.data=ibuf6;
        +		ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint);
        +		}
        +#endif /* OPENSSL_NO_TLSEXT */
        +#ifndef OPENSSL_NO_PSK
        +	if (in->psk_identity_hint)
        +		{
        +		a.psk_identity_hint.length=strlen(in->psk_identity_hint);
        +		a.psk_identity_hint.type=V_ASN1_OCTET_STRING;
        +		a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint);
        +		}
        +	if (in->psk_identity)
        +		{
        +		a.psk_identity.length=strlen(in->psk_identity);
        +		a.psk_identity.type=V_ASN1_OCTET_STRING;
        +		a.psk_identity.data=(unsigned char *)(in->psk_identity);
        +		}
        +#endif /* OPENSSL_NO_PSK */
        +#ifndef OPENSSL_NO_SRP
        +	if (in->srp_username)
        +		{
        +		a.srp_username.length=strlen(in->srp_username);
        +		a.srp_username.type=V_ASN1_OCTET_STRING;
        +		a.srp_username.data=(unsigned char *)(in->srp_username);
        +		}
        +#endif /* OPENSSL_NO_SRP */
        +
        +	M_ASN1_I2D_len(&(a.version),		i2d_ASN1_INTEGER);
        +	M_ASN1_I2D_len(&(a.ssl_version),	i2d_ASN1_INTEGER);
        +	M_ASN1_I2D_len(&(a.cipher),		i2d_ASN1_OCTET_STRING);
        +	M_ASN1_I2D_len(&(a.session_id),		i2d_ASN1_OCTET_STRING);
        +	M_ASN1_I2D_len(&(a.master_key),		i2d_ASN1_OCTET_STRING);
        +#ifndef OPENSSL_NO_KRB5
        +	if (in->krb5_client_princ_len)
        +        	M_ASN1_I2D_len(&(a.krb5_princ),	i2d_ASN1_OCTET_STRING);
        +#endif /* OPENSSL_NO_KRB5 */
        +	if (in->key_arg_length > 0)
        +		M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING);
        +	if (in->time != 0L)
        +		M_ASN1_I2D_len_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
        +	if (in->timeout != 0L)
        +		M_ASN1_I2D_len_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
        +	if (in->peer != NULL)
        +		M_ASN1_I2D_len_EXP_opt(in->peer,i2d_X509,3,v3);
        +	M_ASN1_I2D_len_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,v4);
        +	if (in->verify_result != X509_V_OK)
        +		M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5);
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (in->tlsext_tick_lifetime_hint > 0)
        +      	 	M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
        +	if (in->tlsext_tick)
        +        	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
        +	if (in->tlsext_hostname)
        +        	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
        +#ifndef OPENSSL_NO_COMP
        +	if (in->compress_meth)
        +        	M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
        +#endif
        +#endif /* OPENSSL_NO_TLSEXT */
        +#ifndef OPENSSL_NO_PSK
        +	if (in->psk_identity_hint)
        +        	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
        +	if (in->psk_identity)
        +        	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
        +#endif /* OPENSSL_NO_PSK */
        +#ifndef OPENSSL_NO_SRP
        +	if (in->srp_username)
        +        	M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
        +#endif /* OPENSSL_NO_SRP */
        +
        +	M_ASN1_I2D_seq_total();
        +
        +	M_ASN1_I2D_put(&(a.version),		i2d_ASN1_INTEGER);
        +	M_ASN1_I2D_put(&(a.ssl_version),	i2d_ASN1_INTEGER);
        +	M_ASN1_I2D_put(&(a.cipher),		i2d_ASN1_OCTET_STRING);
        +	M_ASN1_I2D_put(&(a.session_id),		i2d_ASN1_OCTET_STRING);
        +	M_ASN1_I2D_put(&(a.master_key),		i2d_ASN1_OCTET_STRING);
        +#ifndef OPENSSL_NO_KRB5
        +	if (in->krb5_client_princ_len)
        +        	M_ASN1_I2D_put(&(a.krb5_princ),	i2d_ASN1_OCTET_STRING);
        +#endif /* OPENSSL_NO_KRB5 */
        +	if (in->key_arg_length > 0)
        +		M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0);
        +	if (in->time != 0L)
        +		M_ASN1_I2D_put_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
        +	if (in->timeout != 0L)
        +		M_ASN1_I2D_put_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
        +	if (in->peer != NULL)
        +		M_ASN1_I2D_put_EXP_opt(in->peer,i2d_X509,3,v3);
        +	M_ASN1_I2D_put_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,
        +			       v4);
        +	if (in->verify_result != X509_V_OK)
        +		M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5);
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (in->tlsext_hostname)
        +        	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
        +#endif /* OPENSSL_NO_TLSEXT */
        +#ifndef OPENSSL_NO_PSK
        +	if (in->psk_identity_hint)
        +		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
        +	if (in->psk_identity)
        +		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
        +#endif /* OPENSSL_NO_PSK */
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (in->tlsext_tick_lifetime_hint > 0)
        +      	 	M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
        +	if (in->tlsext_tick)
        +        	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
        +#endif /* OPENSSL_NO_TLSEXT */
        +#ifndef OPENSSL_NO_COMP
        +	if (in->compress_meth)
        +        	M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	if (in->srp_username)
        +		M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
        +#endif /* OPENSSL_NO_SRP */
        +	M_ASN1_I2D_finish();
        +	}
        +
        +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
        +			     long length)
        +	{
        +	int ssl_version=0,i;
        +	long id;
        +	ASN1_INTEGER ai,*aip;
        +	ASN1_OCTET_STRING os,*osp;
        +	M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new);
        +
        +	aip= &ai;
        +	osp= &os;
        +
        +	M_ASN1_D2I_Init();
        +	M_ASN1_D2I_start_sequence();
        +
        +	ai.data=NULL; ai.length=0;
        +	M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
        +	if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
        +
        +	/* we don't care about the version right now :-) */
        +	M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
        +	ssl_version=(int)ASN1_INTEGER_get(aip);
        +	ret->ssl_version=ssl_version;
        +	if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
        +
        +	os.data=NULL; os.length=0;
        +	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
        +	if (ssl_version == SSL2_VERSION)
        +		{
        +		if (os.length != 3)
        +			{
        +			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
        +			goto err;
        +			}
        +		id=0x02000000L|
        +			((unsigned long)os.data[0]<<16L)|
        +			((unsigned long)os.data[1]<< 8L)|
        +			 (unsigned long)os.data[2];
        +		}
        +	else if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
        +		{
        +		if (os.length != 2)
        +			{
        +			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
        +			goto err;
        +			}
        +		id=0x03000000L|
        +			((unsigned long)os.data[0]<<8L)|
        +			 (unsigned long)os.data[1];
        +		}
        +	else
        +		{
        +		c.error=SSL_R_UNKNOWN_SSL_VERSION;
        +		goto err;
        +		}
        +	
        +	ret->cipher=NULL;
        +	ret->cipher_id=id;
        +
        +	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
        +	if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
        +		i=SSL3_MAX_SSL_SESSION_ID_LENGTH;
        +	else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */
        +		i=SSL2_MAX_SSL_SESSION_ID_LENGTH;
        +
        +	if (os.length > i)
        +		os.length = i;
        +	if (os.length > (int)sizeof(ret->session_id)) /* can't happen */
        +		os.length = sizeof(ret->session_id);
        +
        +	ret->session_id_length=os.length;
        +	OPENSSL_assert(os.length <= (int)sizeof(ret->session_id));
        +	memcpy(ret->session_id,os.data,os.length);
        +
        +	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
        +	if (os.length > SSL_MAX_MASTER_KEY_LENGTH)
        +		ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
        +	else
        +		ret->master_key_length=os.length;
        +	memcpy(ret->master_key,os.data,ret->master_key_length);
        +
        +	os.length=0;
        +
        +#ifndef OPENSSL_NO_KRB5
        +	os.length=0;
        +	M_ASN1_D2I_get_opt(osp,d2i_ASN1_OCTET_STRING,V_ASN1_OCTET_STRING);
        +	if (os.data)
        +		{
        +        	if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
        +            		ret->krb5_client_princ_len=0;
        +		else
        +			ret->krb5_client_princ_len=os.length;
        +		memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len);
        +		OPENSSL_free(os.data);
        +		os.data = NULL;
        +		os.length = 0;
        +		}
        +	else
        +		ret->krb5_client_princ_len=0;
        +#endif /* OPENSSL_NO_KRB5 */
        +
        +	M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING);
        +	if (os.length > SSL_MAX_KEY_ARG_LENGTH)
        +		ret->key_arg_length=SSL_MAX_KEY_ARG_LENGTH;
        +	else
        +		ret->key_arg_length=os.length;
        +	memcpy(ret->key_arg,os.data,ret->key_arg_length);
        +	if (os.data != NULL) OPENSSL_free(os.data);
        +
        +	ai.length=0;
        +	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1);
        +	if (ai.data != NULL)
        +		{
        +		ret->time=ASN1_INTEGER_get(aip);
        +		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
        +		}
        +	else
        +		ret->time=(unsigned long)time(NULL);
        +
        +	ai.length=0;
        +	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,2);
        +	if (ai.data != NULL)
        +		{
        +		ret->timeout=ASN1_INTEGER_get(aip);
        +		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
        +		}
        +	else
        +		ret->timeout=3;
        +
        +	if (ret->peer != NULL)
        +		{
        +		X509_free(ret->peer);
        +		ret->peer=NULL;
        +		}
        +	M_ASN1_D2I_get_EXP_opt(ret->peer,d2i_X509,3);
        +
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,4);
        +
        +	if(os.data != NULL)
        +	    {
        +	    if (os.length > SSL_MAX_SID_CTX_LENGTH)
        +		{
        +		c.error=SSL_R_BAD_LENGTH;
        +		goto err;
        +		}
        +	    else
        +		{
        +		ret->sid_ctx_length=os.length;
        +		memcpy(ret->sid_ctx,os.data,os.length);
        +		}
        +	    OPENSSL_free(os.data); os.data=NULL; os.length=0;
        +	    }
        +	else
        +	    ret->sid_ctx_length=0;
        +
        +	ai.length=0;
        +	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,5);
        +	if (ai.data != NULL)
        +		{
        +		ret->verify_result=ASN1_INTEGER_get(aip);
        +		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
        +		}
        +	else
        +		ret->verify_result=X509_V_OK;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6);
        +	if (os.data)
        +		{
        +		ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length);
        +		OPENSSL_free(os.data);
        +		os.data = NULL;
        +		os.length = 0;
        +		}
        +	else
        +		ret->tlsext_hostname=NULL;
        +#endif /* OPENSSL_NO_TLSEXT */
        +
        +#ifndef OPENSSL_NO_PSK
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7);
        +	if (os.data)
        +		{
        +		ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length);
        +		OPENSSL_free(os.data);
        +		os.data = NULL;
        +		os.length = 0;
        +		}
        +	else
        +		ret->psk_identity_hint=NULL;
        +
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,8);
        +	if (os.data)
        +		{
        +		ret->psk_identity = BUF_strndup((char *)os.data, os.length);
        +		OPENSSL_free(os.data);
        +		os.data = NULL;
        +		os.length = 0;
        +		}
        +	else
        +		ret->psk_identity=NULL;
        +#endif /* OPENSSL_NO_PSK */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	ai.length=0;
        +	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9);
        +	if (ai.data != NULL)
        +		{
        +		ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip);
        +		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
        +		}
        +	else if (ret->tlsext_ticklen && ret->session_id_length)
        +		ret->tlsext_tick_lifetime_hint = -1;
        +	else
        +		ret->tlsext_tick_lifetime_hint=0;
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
        +	if (os.data)
        +		{
        +		ret->tlsext_tick = os.data;
        +		ret->tlsext_ticklen = os.length;
        +		os.data = NULL;
        +		os.length = 0;
        +		}
        +	else
        +		ret->tlsext_tick=NULL;
        +#endif /* OPENSSL_NO_TLSEXT */
        +#ifndef OPENSSL_NO_COMP
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
        +	if (os.data)
        +		{
        +		ret->compress_meth = os.data[0];
        +		OPENSSL_free(os.data);
        +		os.data = NULL;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_SRP
        +	os.length=0;
        +	os.data=NULL;
        +	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,12);
        +	if (os.data)
        +		{
        +		ret->srp_username = BUF_strndup((char *)os.data, os.length);
        +		OPENSSL_free(os.data);
        +		os.data = NULL;
        +		os.length = 0;
        +		}
        +	else
        +		ret->srp_username=NULL;
        +#endif /* OPENSSL_NO_SRP */
        +
        +	M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
        +	}
        diff --git a/vendor/openssl/openssl/ssl/ssl_cert.c b/vendor/openssl/openssl/ssl/ssl_cert.c
        new file mode 100644
        index 000000000..5123a8918
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_cert.c
        @@ -0,0 +1,853 @@
        +/*! \file ssl/ssl_cert.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-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +
        +#include <stdio.h>
        +
        +#include "e_os.h"
        +#ifndef NO_SYS_TYPES_H
        +# include <sys/types.h>
        +#endif
        +
        +#include "o_dir.h"
        +#include <openssl/objects.h>
        +#include <openssl/bio.h>
        +#include <openssl/pem.h>
        +#include <openssl/x509v3.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#include <openssl/bn.h>
        +#include "ssl_locl.h"
        +
        +int SSL_get_ex_data_X509_STORE_CTX_idx(void)
        +	{
        +	static volatile int ssl_x509_store_ctx_idx= -1;
        +	int got_write_lock = 0;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
        +
        +	if (ssl_x509_store_ctx_idx < 0)
        +		{
        +		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
        +		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +		got_write_lock = 1;
        +		
        +		if (ssl_x509_store_ctx_idx < 0)
        +			{
        +			ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
        +				0,"SSL for verify callback",NULL,NULL,NULL);
        +			}
        +		}
        +
        +	if (got_write_lock)
        +		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +	else
        +		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
        +	
        +	return ssl_x509_store_ctx_idx;
        +	}
        +
        +static void ssl_cert_set_default_md(CERT *cert)
        +	{
        +	/* Set digest values to defaults */
        +#ifndef OPENSSL_NO_DSA
        +	cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
        +	cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
        +#endif
        +	}
        +
        +CERT *ssl_cert_new(void)
        +	{
        +	CERT *ret;
        +
        +	ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
        +	if (ret == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +	memset(ret,0,sizeof(CERT));
        +
        +	ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
        +	ret->references=1;
        +	ssl_cert_set_default_md(ret);
        +	return(ret);
        +	}
        +
        +CERT *ssl_cert_dup(CERT *cert)
        +	{
        +	CERT *ret;
        +	int i;
        +
        +	ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
        +	if (ret == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
        +		return(NULL);
        +		}
        +
        +	memset(ret, 0, sizeof(CERT));
        +
        +	ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
        +	/* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
        +	 * if you find that more readable */
        +
        +	ret->valid = cert->valid;
        +	ret->mask_k = cert->mask_k;
        +	ret->mask_a = cert->mask_a;
        +	ret->export_mask_k = cert->export_mask_k;
        +	ret->export_mask_a = cert->export_mask_a;
        +
        +#ifndef OPENSSL_NO_RSA
        +	if (cert->rsa_tmp != NULL)
        +		{
        +		RSA_up_ref(cert->rsa_tmp);
        +		ret->rsa_tmp = cert->rsa_tmp;
        +		}
        +	ret->rsa_tmp_cb = cert->rsa_tmp_cb;
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +	if (cert->dh_tmp != NULL)
        +		{
        +		ret->dh_tmp = DHparams_dup(cert->dh_tmp);
        +		if (ret->dh_tmp == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
        +			goto err;
        +			}
        +		if (cert->dh_tmp->priv_key)
        +			{
        +			BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
        +			if (!b)
        +				{
        +				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
        +				goto err;
        +				}
        +			ret->dh_tmp->priv_key = b;
        +			}
        +		if (cert->dh_tmp->pub_key)
        +			{
        +			BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
        +			if (!b)
        +				{
        +				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
        +				goto err;
        +				}
        +			ret->dh_tmp->pub_key = b;
        +			}
        +		}
        +	ret->dh_tmp_cb = cert->dh_tmp_cb;
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	if (cert->ecdh_tmp)
        +		{
        +		ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
        +		if (ret->ecdh_tmp == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
        +			goto err;
        +			}
        +		}
        +	ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
        +#endif
        +
        +	for (i = 0; i < SSL_PKEY_NUM; i++)
        +		{
        +		if (cert->pkeys[i].x509 != NULL)
        +			{
        +			ret->pkeys[i].x509 = cert->pkeys[i].x509;
        +			CRYPTO_add(&ret->pkeys[i].x509->references, 1,
        +				CRYPTO_LOCK_X509);
        +			}
        +		
        +		if (cert->pkeys[i].privatekey != NULL)
        +			{
        +			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
        +			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
        +				CRYPTO_LOCK_EVP_PKEY);
        +
        +			switch(i) 
        +				{
        +				/* If there was anything special to do for
        +				 * certain types of keys, we'd do it here.
        +				 * (Nothing at the moment, I think.) */
        +
        +			case SSL_PKEY_RSA_ENC:
        +			case SSL_PKEY_RSA_SIGN:
        +				/* We have an RSA key. */
        +				break;
        +				
        +			case SSL_PKEY_DSA_SIGN:
        +				/* We have a DSA key. */
        +				break;
        +				
        +			case SSL_PKEY_DH_RSA:
        +			case SSL_PKEY_DH_DSA:
        +				/* We have a DH key. */
        +				break;
        +
        +			case SSL_PKEY_ECC:
        +				/* We have an ECC key */
        +				break;
        +
        +			default:
        +				/* Can't happen. */
        +				SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
        +				}
        +			}
        +		}
        +	
        +	/* ret->extra_certs *should* exist, but currently the own certificate
        +	 * chain is held inside SSL_CTX */
        +
        +	ret->references=1;
        +	/* Set digests to defaults. NB: we don't copy existing values as they
        +	 * will be set during handshake.
        +	 */
        +	ssl_cert_set_default_md(ret);
        +
        +	return(ret);
        +	
        +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
        +err:
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	if (ret->rsa_tmp != NULL)
        +		RSA_free(ret->rsa_tmp);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	if (ret->dh_tmp != NULL)
        +		DH_free(ret->dh_tmp);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if (ret->ecdh_tmp != NULL)
        +		EC_KEY_free(ret->ecdh_tmp);
        +#endif
        +
        +	for (i = 0; i < SSL_PKEY_NUM; i++)
        +		{
        +		if (ret->pkeys[i].x509 != NULL)
        +			X509_free(ret->pkeys[i].x509);
        +		if (ret->pkeys[i].privatekey != NULL)
        +			EVP_PKEY_free(ret->pkeys[i].privatekey);
        +		}
        +
        +	return NULL;
        +	}
        +
        +
        +void ssl_cert_free(CERT *c)
        +	{
        +	int i;
        +
        +	if(c == NULL)
        +	    return;
        +
        +	i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
        +#ifdef REF_PRINT
        +	REF_PRINT("CERT",c);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"ssl_cert_free, bad reference count\n");
        +		abort(); /* ok */
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +	if (c->rsa_tmp) RSA_free(c->rsa_tmp);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	if (c->dh_tmp) DH_free(c->dh_tmp);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
        +#endif
        +
        +	for (i=0; i<SSL_PKEY_NUM; i++)
        +		{
        +		if (c->pkeys[i].x509 != NULL)
        +			X509_free(c->pkeys[i].x509);
        +		if (c->pkeys[i].privatekey != NULL)
        +			EVP_PKEY_free(c->pkeys[i].privatekey);
        +#if 0
        +		if (c->pkeys[i].publickey != NULL)
        +			EVP_PKEY_free(c->pkeys[i].publickey);
        +#endif
        +		}
        +	OPENSSL_free(c);
        +	}
        +
        +int ssl_cert_inst(CERT **o)
        +	{
        +	/* Create a CERT if there isn't already one
        +	 * (which cannot really happen, as it is initially created in
        +	 * SSL_CTX_new; but the earlier code usually allows for that one
        +	 * being non-existant, so we follow that behaviour, as it might
        +	 * turn out that there actually is a reason for it -- but I'm
        +	 * not sure that *all* of the existing code could cope with
        +	 * s->cert being NULL, otherwise we could do without the
        +	 * initialization in SSL_CTX_new).
        +	 */
        +	
        +	if (o == NULL) 
        +		{
        +		SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (*o == NULL)
        +		{
        +		if ((*o = ssl_cert_new()) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
        +			return(0);
        +			}
        +		}
        +	return(1);
        +	}
        +
        +
        +SESS_CERT *ssl_sess_cert_new(void)
        +	{
        +	SESS_CERT *ret;
        +
        +	ret = OPENSSL_malloc(sizeof *ret);
        +	if (ret == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
        +		return NULL;
        +		}
        +
        +	memset(ret, 0 ,sizeof *ret);
        +	ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
        +	ret->references = 1;
        +
        +	return ret;
        +	}
        +
        +void ssl_sess_cert_free(SESS_CERT *sc)
        +	{
        +	int i;
        +
        +	if (sc == NULL)
        +		return;
        +
        +	i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
        +#ifdef REF_PRINT
        +	REF_PRINT("SESS_CERT", sc);
        +#endif
        +	if (i > 0)
        +		return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
        +		abort(); /* ok */
        +		}
        +#endif
        +
        +	/* i == 0 */
        +	if (sc->cert_chain != NULL)
        +		sk_X509_pop_free(sc->cert_chain, X509_free);
        +	for (i = 0; i < SSL_PKEY_NUM; i++)
        +		{
        +		if (sc->peer_pkeys[i].x509 != NULL)
        +			X509_free(sc->peer_pkeys[i].x509);
        +#if 0 /* We don't have the peer's private key.  These lines are just
        +	   * here as a reminder that we're still using a not-quite-appropriate
        +	   * data structure. */
        +		if (sc->peer_pkeys[i].privatekey != NULL)
        +			EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
        +#endif
        +		}
        +
        +#ifndef OPENSSL_NO_RSA
        +	if (sc->peer_rsa_tmp != NULL)
        +		RSA_free(sc->peer_rsa_tmp);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	if (sc->peer_dh_tmp != NULL)
        +		DH_free(sc->peer_dh_tmp);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	if (sc->peer_ecdh_tmp != NULL)
        +		EC_KEY_free(sc->peer_ecdh_tmp);
        +#endif
        +
        +	OPENSSL_free(sc);
        +	}
        +
        +int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
        +	{
        +	sc->peer_cert_type = type;
        +	return(1);
        +	}
        +
        +int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
        +	{
        +	X509 *x;
        +	int i;
        +	X509_STORE_CTX ctx;
        +
        +	if ((sk == NULL) || (sk_X509_num(sk) == 0))
        +		return(0);
        +
        +	x=sk_X509_value(sk,0);
        +	if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
        +		{
        +		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
        +		return(0);
        +		}
        +#if 0
        +	if (SSL_get_verify_depth(s) >= 0)
        +		X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
        +#endif
        +	X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
        +
        +	/* We need to inherit the verify parameters. These can be determined by
        +	 * the context: if its a server it will verify SSL client certificates
        +	 * or vice versa.
        +	 */
        +
        +	X509_STORE_CTX_set_default(&ctx,
        +				s->server ? "ssl_client" : "ssl_server");
        +	/* Anything non-default in "param" should overwrite anything in the
        +	 * ctx.
        +	 */
        +	X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
        +
        +	if (s->verify_callback)
        +		X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
        +
        +	if (s->ctx->app_verify_callback != NULL)
        +#if 1 /* new with OpenSSL 0.9.7 */
        +		i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
        +#else
        +		i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
        +#endif
        +	else
        +		{
        +#ifndef OPENSSL_NO_X509_VERIFY
        +		i=X509_verify_cert(&ctx);
        +#else
        +		i=0;
        +		ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
        +		SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
        +#endif
        +		}
        +
        +	s->verify_result=ctx.error;
        +	X509_STORE_CTX_cleanup(&ctx);
        +
        +	return(i);
        +	}
        +
        +static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
        +	{
        +	if (*ca_list != NULL)
        +		sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
        +
        +	*ca_list=name_list;
        +	}
        +
        +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
        +	{
        +	int i;
        +	STACK_OF(X509_NAME) *ret;
        +	X509_NAME *name;
        +
        +	ret=sk_X509_NAME_new_null();
        +	for (i=0; i<sk_X509_NAME_num(sk); i++)
        +		{
        +		name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
        +		if ((name == NULL) || !sk_X509_NAME_push(ret,name))
        +			{
        +			sk_X509_NAME_pop_free(ret,X509_NAME_free);
        +			return(NULL);
        +			}
        +		}
        +	return(ret);
        +	}
        +
        +void SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *name_list)
        +	{
        +	set_client_CA_list(&(s->client_CA),name_list);
        +	}
        +
        +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *name_list)
        +	{
        +	set_client_CA_list(&(ctx->client_CA),name_list);
        +	}
        +
        +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
        +	{
        +	return(ctx->client_CA);
        +	}
        +
        +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
        +	{
        +	if (s->type == SSL_ST_CONNECT)
        +		{ /* we are in the client */
        +		if (((s->version>>8) == SSL3_VERSION_MAJOR) &&
        +			(s->s3 != NULL))
        +			return(s->s3->tmp.ca_names);
        +		else
        +			return(NULL);
        +		}
        +	else
        +		{
        +		if (s->client_CA != NULL)
        +			return(s->client_CA);
        +		else
        +			return(s->ctx->client_CA);
        +		}
        +	}
        +
        +static int add_client_CA(STACK_OF(X509_NAME) **sk,X509 *x)
        +	{
        +	X509_NAME *name;
        +
        +	if (x == NULL) return(0);
        +	if ((*sk == NULL) && ((*sk=sk_X509_NAME_new_null()) == NULL))
        +		return(0);
        +		
        +	if ((name=X509_NAME_dup(X509_get_subject_name(x))) == NULL)
        +		return(0);
        +
        +	if (!sk_X509_NAME_push(*sk,name))
        +		{
        +		X509_NAME_free(name);
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +int SSL_add_client_CA(SSL *ssl,X509 *x)
        +	{
        +	return(add_client_CA(&(ssl->client_CA),x));
        +	}
        +
        +int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
        +	{
        +	return(add_client_CA(&(ctx->client_CA),x));
        +	}
        +
        +static int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
        +	{
        +	return(X509_NAME_cmp(*a,*b));
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +/*!
        + * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
        + * it doesn't really have anything to do with clients (except that a common use
        + * for a stack of CAs is to send it to the client). Actually, it doesn't have
        + * much to do with CAs, either, since it will load any old cert.
        + * \param file the file containing one or more certs.
        + * \return a ::STACK containing the certs.
        + */
        +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
        +	{
        +	BIO *in;
        +	X509 *x=NULL;
        +	X509_NAME *xn=NULL;
        +	STACK_OF(X509_NAME) *ret = NULL,*sk;
        +
        +	sk=sk_X509_NAME_new(xname_cmp);
        +
        +	in=BIO_new(BIO_s_file_internal());
        +
        +	if ((sk == NULL) || (in == NULL))
        +		{
        +		SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	
        +	if (!BIO_read_filename(in,file))
        +		goto err;
        +
        +	for (;;)
        +		{
        +		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
        +			break;
        +		if (ret == NULL)
        +			{
        +			ret = sk_X509_NAME_new_null();
        +			if (ret == NULL)
        +				{
        +				SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			}
        +		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
        +		/* check for duplicates */
        +		xn=X509_NAME_dup(xn);
        +		if (xn == NULL) goto err;
        +		if (sk_X509_NAME_find(sk,xn) >= 0)
        +			X509_NAME_free(xn);
        +		else
        +			{
        +			sk_X509_NAME_push(sk,xn);
        +			sk_X509_NAME_push(ret,xn);
        +			}
        +		}
        +
        +	if (0)
        +		{
        +err:
        +		if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
        +		ret=NULL;
        +		}
        +	if (sk != NULL) sk_X509_NAME_free(sk);
        +	if (in != NULL) BIO_free(in);
        +	if (x != NULL) X509_free(x);
        +	if (ret != NULL)
        +		ERR_clear_error();
        +	return(ret);
        +	}
        +#endif
        +
        +/*!
        + * Add a file of certs to a stack.
        + * \param stack the stack to add to.
        + * \param file the file to add from. All certs in this file that are not
        + * already in the stack will be added.
        + * \return 1 for success, 0 for failure. Note that in the case of failure some
        + * certs may have been added to \c stack.
        + */
        +
        +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
        +					const char *file)
        +	{
        +	BIO *in;
        +	X509 *x=NULL;
        +	X509_NAME *xn=NULL;
        +	int ret=1;
        +	int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
        +	
        +	oldcmp=sk_X509_NAME_set_cmp_func(stack,xname_cmp);
        +	
        +	in=BIO_new(BIO_s_file_internal());
        +	
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +	
        +	if (!BIO_read_filename(in,file))
        +		goto err;
        +	
        +	for (;;)
        +		{
        +		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
        +			break;
        +		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
        +		xn=X509_NAME_dup(xn);
        +		if (xn == NULL) goto err;
        +		if (sk_X509_NAME_find(stack,xn) >= 0)
        +			X509_NAME_free(xn);
        +		else
        +			sk_X509_NAME_push(stack,xn);
        +		}
        +
        +	ERR_clear_error();
        +
        +	if (0)
        +		{
        +err:
        +		ret=0;
        +		}
        +	if(in != NULL)
        +		BIO_free(in);
        +	if(x != NULL)
        +		X509_free(x);
        +	
        +	(void)sk_X509_NAME_set_cmp_func(stack,oldcmp);
        +
        +	return ret;
        +	}
        +
        +/*!
        + * Add a directory of certs to a stack.
        + * \param stack the stack to append to.
        + * \param dir the directory to append from. All files in this directory will be
        + * examined as potential certs. Any that are acceptable to
        + * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
        + * included.
        + * \return 1 for success, 0 for failure. Note that in the case of failure some
        + * certs may have been added to \c stack.
        + */
        +
        +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
        +				       const char *dir)
        +	{
        +	OPENSSL_DIR_CTX *d = NULL;
        +	const char *filename;
        +	int ret = 0;
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
        +
        +	/* Note that a side effect is that the CAs will be sorted by name */
        +
        +	while((filename = OPENSSL_DIR_read(&d, dir)))
        +		{
        +		char buf[1024];
        +		int r;
        +
        +		if(strlen(dir)+strlen(filename)+2 > sizeof buf)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG);
        +			goto err;
        +			}
        +
        +#ifdef OPENSSL_SYS_VMS
        +		r = BIO_snprintf(buf,sizeof buf,"%s%s",dir,filename);
        +#else
        +		r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,filename);
        +#endif
        +		if (r <= 0 || r >= (int)sizeof(buf))
        +			goto err;
        +		if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
        +			goto err;
        +		}
        +
        +	if (errno)
        +		{
        +		SYSerr(SYS_F_OPENDIR, get_last_sys_error());
        +		ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
        +		SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
        +		goto err;
        +		}
        +
        +	ret = 1;
        +
        +err:
        +	if (d) OPENSSL_DIR_end(&d);
        +	CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
        +	return ret;
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl_ciph.c b/vendor/openssl/openssl/ssl/ssl_ciph.c
        new file mode 100644
        index 000000000..0aba8e048
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_ciph.c
        @@ -0,0 +1,1853 @@
        +/* ssl/ssl_ciph.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-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include "ssl_locl.h"
        +
        +#define SSL_ENC_DES_IDX		0
        +#define SSL_ENC_3DES_IDX	1
        +#define SSL_ENC_RC4_IDX		2
        +#define SSL_ENC_RC2_IDX		3
        +#define SSL_ENC_IDEA_IDX	4
        +#define SSL_ENC_NULL_IDX	5
        +#define SSL_ENC_AES128_IDX	6
        +#define SSL_ENC_AES256_IDX	7
        +#define SSL_ENC_CAMELLIA128_IDX	8
        +#define SSL_ENC_CAMELLIA256_IDX	9
        +#define SSL_ENC_GOST89_IDX	10
        +#define SSL_ENC_SEED_IDX    	11
        +#define SSL_ENC_AES128GCM_IDX	12
        +#define SSL_ENC_AES256GCM_IDX	13
        +#define SSL_ENC_NUM_IDX		14
        +
        +
        +static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
        +	NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
        +	};
        +
        +#define SSL_COMP_NULL_IDX	0
        +#define SSL_COMP_ZLIB_IDX	1
        +#define SSL_COMP_NUM_IDX	2
        +
        +static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
        +
        +#define SSL_MD_MD5_IDX	0
        +#define SSL_MD_SHA1_IDX	1
        +#define SSL_MD_GOST94_IDX 2
        +#define SSL_MD_GOST89MAC_IDX 3
        +#define SSL_MD_SHA256_IDX 4
        +#define SSL_MD_SHA384_IDX 5
        +/*Constant SSL_MAX_DIGEST equal to size of digests array should be 
        + * defined in the
        + * ssl_locl.h */
        +#define SSL_MD_NUM_IDX	SSL_MAX_DIGEST 
        +static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
        +	NULL,NULL,NULL,NULL,NULL,NULL
        +	};
        +/* PKEY_TYPE for GOST89MAC is known in advance, but, because
        + * implementation is engine-provided, we'll fill it only if
        + * corresponding EVP_PKEY_METHOD is found 
        + */
        +static int  ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
        +	EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,
        +	EVP_PKEY_HMAC,EVP_PKEY_HMAC
        +	};
        +
        +static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
        +	0,0,0,0,0,0
        +	};
        +
        +static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
        +	SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
        +	SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256,
        +	SSL_HANDSHAKE_MAC_SHA384
        +	};
        +
        +#define CIPHER_ADD	1
        +#define CIPHER_KILL	2
        +#define CIPHER_DEL	3
        +#define CIPHER_ORD	4
        +#define CIPHER_SPECIAL	5
        +
        +typedef struct cipher_order_st
        +	{
        +	const SSL_CIPHER *cipher;
        +	int active;
        +	int dead;
        +	struct cipher_order_st *next,*prev;
        +	} CIPHER_ORDER;
        +
        +static const SSL_CIPHER cipher_aliases[]={
        +	/* "ALL" doesn't include eNULL (must be specifically enabled) */
        +	{0,SSL_TXT_ALL,0,     0,0,~SSL_eNULL,0,0,0,0,0,0},
        +	/* "COMPLEMENTOFALL" */
        +	{0,SSL_TXT_CMPALL,0,  0,0,SSL_eNULL,0,0,0,0,0,0},
        +
        +	/* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in ALL!) */
        +	{0,SSL_TXT_CMPDEF,0,  SSL_kEDH|SSL_kEECDH,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0},
        +
        +	/* key exchange aliases
        +	 * (some of those using only a single bit here combine
        +	 * multiple key exchange algs according to the RFCs,
        +	 * e.g. kEDH combines DHE_DSS and DHE_RSA) */
        +	{0,SSL_TXT_kRSA,0,    SSL_kRSA,  0,0,0,0,0,0,0,0},
        +
        +	{0,SSL_TXT_kDHr,0,    SSL_kDHr,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
        +	{0,SSL_TXT_kDHd,0,    SSL_kDHd,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
        +	{0,SSL_TXT_kDH,0,     SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
        +	{0,SSL_TXT_kEDH,0,    SSL_kEDH,  0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_DH,0,      SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0},
        +
        +	{0,SSL_TXT_kKRB5,0,   SSL_kKRB5, 0,0,0,0,0,0,0,0},
        +
        +	{0,SSL_TXT_kECDHr,0,  SSL_kECDHr,0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_kECDHe,0,  SSL_kECDHe,0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_kECDH,0,   SSL_kECDHr|SSL_kECDHe,0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_kEECDH,0,  SSL_kEECDH,0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_ECDH,0,    SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0},
        +
        +        {0,SSL_TXT_kPSK,0,    SSL_kPSK,  0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_kSRP,0,    SSL_kSRP,  0,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0},
        +
        +	/* server authentication aliases */
        +	{0,SSL_TXT_aRSA,0,    0,SSL_aRSA,  0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aDSS,0,    0,SSL_aDSS,  0,0,0,0,0,0,0},
        +	{0,SSL_TXT_DSS,0,     0,SSL_aDSS,   0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aKRB5,0,   0,SSL_aKRB5, 0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aNULL,0,   0,SSL_aNULL, 0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aDH,0,     0,SSL_aDH,   0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
        +	{0,SSL_TXT_aECDH,0,   0,SSL_aECDH, 0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aECDSA,0,  0,SSL_aECDSA,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_ECDSA,0,   0,SSL_aECDSA, 0,0,0,0,0,0,0},
        +        {0,SSL_TXT_aPSK,0,    0,SSL_aPSK,  0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0},
        +
        +	/* aliases combining key exchange and server authentication */
        +	{0,SSL_TXT_EDH,0,     SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_EECDH,0,   SSL_kEECDH,~SSL_aNULL,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_NULL,0,    0,0,SSL_eNULL, 0,0,0,0,0,0},
        +	{0,SSL_TXT_KRB5,0,    SSL_kKRB5,SSL_aKRB5,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_RSA,0,     SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_ADH,0,     SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_AECDH,0,   SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0},
        +        {0,SSL_TXT_PSK,0,     SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0},
        +	{0,SSL_TXT_SRP,0,     SSL_kSRP,0,0,0,0,0,0,0,0},
        +
        +
        +	/* symmetric encryption aliases */
        +	{0,SSL_TXT_DES,0,     0,0,SSL_DES,   0,0,0,0,0,0},
        +	{0,SSL_TXT_3DES,0,    0,0,SSL_3DES,  0,0,0,0,0,0},
        +	{0,SSL_TXT_RC4,0,     0,0,SSL_RC4,   0,0,0,0,0,0},
        +	{0,SSL_TXT_RC2,0,     0,0,SSL_RC2,   0,0,0,0,0,0},
        +	{0,SSL_TXT_IDEA,0,    0,0,SSL_IDEA,  0,0,0,0,0,0},
        +	{0,SSL_TXT_SEED,0,    0,0,SSL_SEED,  0,0,0,0,0,0},
        +	{0,SSL_TXT_eNULL,0,   0,0,SSL_eNULL, 0,0,0,0,0,0},
        +	{0,SSL_TXT_AES128,0,  0,0,SSL_AES128|SSL_AES128GCM,0,0,0,0,0,0},
        +	{0,SSL_TXT_AES256,0,  0,0,SSL_AES256|SSL_AES256GCM,0,0,0,0,0,0},
        +	{0,SSL_TXT_AES,0,     0,0,SSL_AES,0,0,0,0,0,0},
        +	{0,SSL_TXT_AES_GCM,0, 0,0,SSL_AES128GCM|SSL_AES256GCM,0,0,0,0,0,0},
        +	{0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
        +	{0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
        +	{0,SSL_TXT_CAMELLIA   ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
        +
        +	/* MAC aliases */	
        +	{0,SSL_TXT_MD5,0,     0,0,0,SSL_MD5,   0,0,0,0,0},
        +	{0,SSL_TXT_SHA1,0,    0,0,0,SSL_SHA1,  0,0,0,0,0},
        +	{0,SSL_TXT_SHA,0,     0,0,0,SSL_SHA1,  0,0,0,0,0},
        +	{0,SSL_TXT_GOST94,0,     0,0,0,SSL_GOST94,  0,0,0,0,0},
        +	{0,SSL_TXT_GOST89MAC,0,     0,0,0,SSL_GOST89MAC,  0,0,0,0,0},
        +	{0,SSL_TXT_SHA256,0,    0,0,0,SSL_SHA256,  0,0,0,0,0},
        +	{0,SSL_TXT_SHA384,0,    0,0,0,SSL_SHA384,  0,0,0,0,0},
        +
        +	/* protocol version aliases */
        +	{0,SSL_TXT_SSLV2,0,   0,0,0,0,SSL_SSLV2, 0,0,0,0},
        +	{0,SSL_TXT_SSLV3,0,   0,0,0,0,SSL_SSLV3, 0,0,0,0},
        +	{0,SSL_TXT_TLSV1,0,   0,0,0,0,SSL_TLSV1, 0,0,0,0},
        +	{0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0},
        +
        +	/* export flag */
        +	{0,SSL_TXT_EXP,0,     0,0,0,0,0,SSL_EXPORT,0,0,0},
        +	{0,SSL_TXT_EXPORT,0,  0,0,0,0,0,SSL_EXPORT,0,0,0},
        +
        +	/* strength classes */
        +	{0,SSL_TXT_EXP40,0,   0,0,0,0,0,SSL_EXP40, 0,0,0},
        +	{0,SSL_TXT_EXP56,0,   0,0,0,0,0,SSL_EXP56, 0,0,0},
        +	{0,SSL_TXT_LOW,0,     0,0,0,0,0,SSL_LOW,   0,0,0},
        +	{0,SSL_TXT_MEDIUM,0,  0,0,0,0,0,SSL_MEDIUM,0,0,0},
        +	{0,SSL_TXT_HIGH,0,    0,0,0,0,0,SSL_HIGH,  0,0,0},
        +	/* FIPS 140-2 approved ciphersuite */
        +	{0,SSL_TXT_FIPS,0,    0,0,~SSL_eNULL,0,0,SSL_FIPS,  0,0,0},
        +	};
        +/* Search for public key algorithm with given name and 
        + * return its pkey_id if it is available. Otherwise return 0
        + */
        +#ifdef OPENSSL_NO_ENGINE
        +
        +static int get_optional_pkey_id(const char *pkey_name)
        +	{
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	int pkey_id=0;
        +	ameth = EVP_PKEY_asn1_find_str(NULL,pkey_name,-1);
        +	if (ameth) 
        +		{
        +		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
        +		}		
        +	return pkey_id;
        +	}
        +
        +#else
        +
        +static int get_optional_pkey_id(const char *pkey_name)
        +	{
        +	const EVP_PKEY_ASN1_METHOD *ameth;
        +	ENGINE *tmpeng = NULL;
        +	int pkey_id=0;
        +	ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1);
        +	if (ameth)
        +		{
        +		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
        +		}
        +	if (tmpeng) ENGINE_finish(tmpeng);
        +	return pkey_id;
        +	}
        +
        +#endif
        +
        +void ssl_load_ciphers(void)
        +	{
        +	ssl_cipher_methods[SSL_ENC_DES_IDX]= 
        +		EVP_get_cipherbyname(SN_des_cbc);
        +	ssl_cipher_methods[SSL_ENC_3DES_IDX]=
        +		EVP_get_cipherbyname(SN_des_ede3_cbc);
        +	ssl_cipher_methods[SSL_ENC_RC4_IDX]=
        +		EVP_get_cipherbyname(SN_rc4);
        +	ssl_cipher_methods[SSL_ENC_RC2_IDX]= 
        +		EVP_get_cipherbyname(SN_rc2_cbc);
        +#ifndef OPENSSL_NO_IDEA
        +	ssl_cipher_methods[SSL_ENC_IDEA_IDX]= 
        +		EVP_get_cipherbyname(SN_idea_cbc);
        +#else
        +	ssl_cipher_methods[SSL_ENC_IDEA_IDX]= NULL;
        +#endif
        +	ssl_cipher_methods[SSL_ENC_AES128_IDX]=
        +	  EVP_get_cipherbyname(SN_aes_128_cbc);
        +	ssl_cipher_methods[SSL_ENC_AES256_IDX]=
        +	  EVP_get_cipherbyname(SN_aes_256_cbc);
        +	ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX]=
        +	  EVP_get_cipherbyname(SN_camellia_128_cbc);
        +	ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]=
        +	  EVP_get_cipherbyname(SN_camellia_256_cbc);
        +	ssl_cipher_methods[SSL_ENC_GOST89_IDX]=
        +	  EVP_get_cipherbyname(SN_gost89_cnt);
        +	ssl_cipher_methods[SSL_ENC_SEED_IDX]=
        +	  EVP_get_cipherbyname(SN_seed_cbc);
        +
        +	ssl_cipher_methods[SSL_ENC_AES128GCM_IDX]=
        +	  EVP_get_cipherbyname(SN_aes_128_gcm);
        +	ssl_cipher_methods[SSL_ENC_AES256GCM_IDX]=
        +	  EVP_get_cipherbyname(SN_aes_256_gcm);
        +
        +	ssl_digest_methods[SSL_MD_MD5_IDX]=
        +		EVP_get_digestbyname(SN_md5);
        +	ssl_mac_secret_size[SSL_MD_MD5_IDX]=
        +		EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);
        +	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0);
        +	ssl_digest_methods[SSL_MD_SHA1_IDX]=
        +		EVP_get_digestbyname(SN_sha1);
        +	ssl_mac_secret_size[SSL_MD_SHA1_IDX]=
        +		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]);
        +	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0);
        +	ssl_digest_methods[SSL_MD_GOST94_IDX]=
        +		EVP_get_digestbyname(SN_id_GostR3411_94);
        +	if (ssl_digest_methods[SSL_MD_GOST94_IDX])
        +		{	
        +		ssl_mac_secret_size[SSL_MD_GOST94_IDX]=
        +			EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]);
        +		OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0);
        +		}
        +	ssl_digest_methods[SSL_MD_GOST89MAC_IDX]=
        +		EVP_get_digestbyname(SN_id_Gost28147_89_MAC);
        +		ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
        +		if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) {
        +			ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32;
        +		}		
        +
        +	ssl_digest_methods[SSL_MD_SHA256_IDX]=
        +		EVP_get_digestbyname(SN_sha256);
        +	ssl_mac_secret_size[SSL_MD_SHA256_IDX]=
        +		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]);
        +	ssl_digest_methods[SSL_MD_SHA384_IDX]=
        +		EVP_get_digestbyname(SN_sha384);
        +	ssl_mac_secret_size[SSL_MD_SHA384_IDX]=
        +		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]);
        +	}
        +#ifndef OPENSSL_NO_COMP
        +
        +static int sk_comp_cmp(const SSL_COMP * const *a,
        +			const SSL_COMP * const *b)
        +	{
        +	return((*a)->id-(*b)->id);
        +	}
        +
        +static void load_builtin_compressions(void)
        +	{
        +	int got_write_lock = 0;
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_SSL);
        +	if (ssl_comp_methods == NULL)
        +		{
        +		CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
        +		CRYPTO_w_lock(CRYPTO_LOCK_SSL);
        +		got_write_lock = 1;
        +		
        +		if (ssl_comp_methods == NULL)
        +			{
        +			SSL_COMP *comp = NULL;
        +
        +			MemCheck_off();
        +			ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
        +			if (ssl_comp_methods != NULL)
        +				{
        +				comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
        +				if (comp != NULL)
        +					{
        +					comp->method=COMP_zlib();
        +					if (comp->method
        +						&& comp->method->type == NID_undef)
        +						OPENSSL_free(comp);
        +					else
        +						{
        +						comp->id=SSL_COMP_ZLIB_IDX;
        +						comp->name=comp->method->name;
        +						sk_SSL_COMP_push(ssl_comp_methods,comp);
        +						}
        +					}
        +					sk_SSL_COMP_sort(ssl_comp_methods);
        +				}
        +			MemCheck_on();
        +			}
        +		}
        +	
        +	if (got_write_lock)
        +		CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
        +	else
        +		CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
        +	}
        +#endif
        +
        +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
        +	     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp)
        +	{
        +	int i;
        +	const SSL_CIPHER *c;
        +
        +	c=s->cipher;
        +	if (c == NULL) return(0);
        +	if (comp != NULL)
        +		{
        +		SSL_COMP ctmp;
        +#ifndef OPENSSL_NO_COMP
        +		load_builtin_compressions();
        +#endif
        +
        +		*comp=NULL;
        +		ctmp.id=s->compress_meth;
        +		if (ssl_comp_methods != NULL)
        +			{
        +			i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
        +			if (i >= 0)
        +				*comp=sk_SSL_COMP_value(ssl_comp_methods,i);
        +			else
        +				*comp=NULL;
        +			}
        +		}
        +
        +	if ((enc == NULL) || (md == NULL)) return(0);
        +
        +	switch (c->algorithm_enc)
        +		{
        +	case SSL_DES:
        +		i=SSL_ENC_DES_IDX;
        +		break;
        +	case SSL_3DES:
        +		i=SSL_ENC_3DES_IDX;
        +		break;
        +	case SSL_RC4:
        +		i=SSL_ENC_RC4_IDX;
        +		break;
        +	case SSL_RC2:
        +		i=SSL_ENC_RC2_IDX;
        +		break;
        +	case SSL_IDEA:
        +		i=SSL_ENC_IDEA_IDX;
        +		break;
        +	case SSL_eNULL:
        +		i=SSL_ENC_NULL_IDX;
        +		break;
        +	case SSL_AES128:
        +		i=SSL_ENC_AES128_IDX;
        +		break;
        +	case SSL_AES256:
        +		i=SSL_ENC_AES256_IDX;
        +		break;
        +	case SSL_CAMELLIA128:
        +		i=SSL_ENC_CAMELLIA128_IDX;
        +		break;
        +	case SSL_CAMELLIA256:
        +		i=SSL_ENC_CAMELLIA256_IDX;
        +		break;
        +	case SSL_eGOST2814789CNT:
        +		i=SSL_ENC_GOST89_IDX;
        +		break;
        +	case SSL_SEED:
        +		i=SSL_ENC_SEED_IDX;
        +		break;
        +	case SSL_AES128GCM:
        +		i=SSL_ENC_AES128GCM_IDX;
        +		break;
        +	case SSL_AES256GCM:
        +		i=SSL_ENC_AES256GCM_IDX;
        +		break;
        +	default:
        +		i= -1;
        +		break;
        +		}
        +
        +	if ((i < 0) || (i > SSL_ENC_NUM_IDX))
        +		*enc=NULL;
        +	else
        +		{
        +		if (i == SSL_ENC_NULL_IDX)
        +			*enc=EVP_enc_null();
        +		else
        +			*enc=ssl_cipher_methods[i];
        +		}
        +
        +	switch (c->algorithm_mac)
        +		{
        +	case SSL_MD5:
        +		i=SSL_MD_MD5_IDX;
        +		break;
        +	case SSL_SHA1:
        +		i=SSL_MD_SHA1_IDX;
        +		break;
        +	case SSL_SHA256:
        +		i=SSL_MD_SHA256_IDX;
        +		break;
        +	case SSL_SHA384:
        +		i=SSL_MD_SHA384_IDX;
        +		break;
        +	case SSL_GOST94:
        +		i = SSL_MD_GOST94_IDX;
        +		break;
        +	case SSL_GOST89MAC:
        +		i = SSL_MD_GOST89MAC_IDX;
        +		break;
        +	default:
        +		i= -1;
        +		break;
        +		}
        +	if ((i < 0) || (i > SSL_MD_NUM_IDX))
        +	{
        +		*md=NULL; 
        +		if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
        +		if (mac_secret_size!=NULL) *mac_secret_size = 0;
        +		if (c->algorithm_mac == SSL_AEAD)
        +			mac_pkey_type = NULL;
        +	}
        +	else
        +	{
        +		*md=ssl_digest_methods[i];
        +		if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
        +		if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
        +	}
        +
        +	if ((*enc != NULL) &&
        +	    (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) &&
        +	    (!mac_pkey_type||*mac_pkey_type != NID_undef))
        +		{
        +		const EVP_CIPHER *evp;
        +
        +		if (s->ssl_version>>8 != TLS1_VERSION_MAJOR ||
        +		    s->ssl_version < TLS1_VERSION)
        +			return 1;
        +
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return 1;
        +#endif
        +
        +		if	(c->algorithm_enc == SSL_RC4 &&
        +			 c->algorithm_mac == SSL_MD5 &&
        +			 (evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
        +			*enc = evp, *md = NULL;
        +		else if (c->algorithm_enc == SSL_AES128 &&
        +			 c->algorithm_mac == SSL_SHA1 &&
        +			 (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
        +			*enc = evp, *md = NULL;
        +		else if (c->algorithm_enc == SSL_AES256 &&
        +			 c->algorithm_mac == SSL_SHA1 &&
        +			 (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
        +			*enc = evp, *md = NULL;
        +		return(1);
        +		}
        +	else
        +		return(0);
        +	}
        +
        +int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) 
        +{
        +	if (idx <0||idx>=SSL_MD_NUM_IDX) 
        +		{
        +		return 0;
        +		}
        +	*mask = ssl_handshake_digest_flag[idx];
        +	if (*mask)
        +		*md = ssl_digest_methods[idx];
        +	else
        +		*md = NULL;
        +	return 1;
        +}
        +
        +#define ITEM_SEP(a) \
        +	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
        +
        +static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
        +	     CIPHER_ORDER **tail)
        +	{
        +	if (curr == *tail) return;
        +	if (curr == *head)
        +		*head=curr->next;
        +	if (curr->prev != NULL)
        +		curr->prev->next=curr->next;
        +	if (curr->next != NULL)
        +		curr->next->prev=curr->prev;
        +	(*tail)->next=curr;
        +	curr->prev= *tail;
        +	curr->next=NULL;
        +	*tail=curr;
        +	}
        +
        +static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
        +	     CIPHER_ORDER **tail)
        +	{
        +	if (curr == *head) return;
        +	if (curr == *tail)
        +		*tail=curr->prev;
        +	if (curr->next != NULL)
        +		curr->next->prev=curr->prev;
        +	if (curr->prev != NULL)
        +		curr->prev->next=curr->next;
        +	(*head)->prev=curr;
        +	curr->next= *head;
        +	curr->prev=NULL;
        +	*head=curr;
        +	}
        +
        +static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, unsigned long *enc, unsigned long *mac, unsigned long *ssl)
        +	{
        +	*mkey = 0;
        +	*auth = 0;
        +	*enc = 0;
        +	*mac = 0;
        +	*ssl = 0;
        +
        +#ifdef OPENSSL_NO_RSA
        +	*mkey |= SSL_kRSA;
        +	*auth |= SSL_aRSA;
        +#endif
        +#ifdef OPENSSL_NO_DSA
        +	*auth |= SSL_aDSS;
        +#endif
        +	*mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */
        +	*auth |= SSL_aDH;
        +#ifdef OPENSSL_NO_DH
        +	*mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH;
        +	*auth |= SSL_aDH;
        +#endif
        +#ifdef OPENSSL_NO_KRB5
        +	*mkey |= SSL_kKRB5;
        +	*auth |= SSL_aKRB5;
        +#endif
        +#ifdef OPENSSL_NO_ECDSA
        +	*auth |= SSL_aECDSA;
        +#endif
        +#ifdef OPENSSL_NO_ECDH
        +	*mkey |= SSL_kECDHe|SSL_kECDHr;
        +	*auth |= SSL_aECDH;
        +#endif
        +#ifdef OPENSSL_NO_PSK
        +	*mkey |= SSL_kPSK;
        +	*auth |= SSL_aPSK;
        +#endif
        +#ifdef OPENSSL_NO_SRP
        +	*mkey |= SSL_kSRP;
        +#endif
        +	/* Check for presence of GOST 34.10 algorithms, and if they
        +	 * do not present, disable  appropriate auth and key exchange */
        +	if (!get_optional_pkey_id("gost94")) {
        +		*auth |= SSL_aGOST94;
        +	}
        +	if (!get_optional_pkey_id("gost2001")) {
        +		*auth |= SSL_aGOST01;
        +	}
        +	/* Disable GOST key exchange if no GOST signature algs are available * */
        +	if ((*auth & (SSL_aGOST94|SSL_aGOST01)) == (SSL_aGOST94|SSL_aGOST01)) {
        +		*mkey |= SSL_kGOST;
        +	}	
        +#ifdef SSL_FORBID_ENULL
        +	*enc |= SSL_eNULL;
        +#endif
        +		
        +
        +
        +	*enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0;
        +	*enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0;
        +
        +	*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
        +	*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
        +	*mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0;
        +	*mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384:0;
        +	*mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
        +	*mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
        +
        +	}
        +
        +static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
        +                int num_of_ciphers,
        +                unsigned long disabled_mkey, unsigned long disabled_auth,
        +                unsigned long disabled_enc, unsigned long disabled_mac,
        +                unsigned long disabled_ssl,
        +                CIPHER_ORDER *co_list,
        +                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
        +	{
        +	int i, co_list_num;
        +	const SSL_CIPHER *c;
        +
        +	/*
        +	 * We have num_of_ciphers descriptions compiled in, depending on the
        +	 * method selected (SSLv2 and/or SSLv3, TLSv1 etc).
        +	 * These will later be sorted in a linked list with at most num
        +	 * entries.
        +	 */
        +
        +	/* Get the initial list of ciphers */
        +	co_list_num = 0;	/* actual count of ciphers */
        +	for (i = 0; i < num_of_ciphers; i++)
        +		{
        +		c = ssl_method->get_cipher(i);
        +		/* drop those that use any of that is not available */
        +		if ((c != NULL) && c->valid &&
        +#ifdef OPENSSL_FIPS
        +		    (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) &&
        +#endif
        +		    !(c->algorithm_mkey & disabled_mkey) &&
        +		    !(c->algorithm_auth & disabled_auth) &&
        +		    !(c->algorithm_enc & disabled_enc) &&
        +		    !(c->algorithm_mac & disabled_mac) &&
        +		    !(c->algorithm_ssl & disabled_ssl))
        +			{
        +			co_list[co_list_num].cipher = c;
        +			co_list[co_list_num].next = NULL;
        +			co_list[co_list_num].prev = NULL;
        +			co_list[co_list_num].active = 0;
        +			co_list_num++;
        +#ifdef KSSL_DEBUG
        +			printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
        +#endif	/* KSSL_DEBUG */
        +			/*
        +			if (!sk_push(ca_list,(char *)c)) goto err;
        +			*/
        +			}
        +		}
        +
        +	/*
        +	 * Prepare linked list from list entries
        +	 */	
        +	if (co_list_num > 0)
        +		{
        +		co_list[0].prev = NULL;
        +
        +		if (co_list_num > 1)
        +			{
        +			co_list[0].next = &co_list[1];
        +			
        +			for (i = 1; i < co_list_num - 1; i++)
        +				{
        +				co_list[i].prev = &co_list[i - 1];
        +				co_list[i].next = &co_list[i + 1];
        +				}
        +
        +			co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
        +			}
        +		
        +		co_list[co_list_num - 1].next = NULL;
        +
        +		*head_p = &co_list[0];
        +		*tail_p = &co_list[co_list_num - 1];
        +		}
        +	}
        +
        +static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list,
        +                        int num_of_group_aliases,
        +                        unsigned long disabled_mkey, unsigned long disabled_auth,
        +                        unsigned long disabled_enc, unsigned long disabled_mac,
        +                        unsigned long disabled_ssl,
        +			CIPHER_ORDER *head)
        +	{
        +	CIPHER_ORDER *ciph_curr;
        +	const SSL_CIPHER **ca_curr;
        +	int i;
        +	unsigned long mask_mkey = ~disabled_mkey;
        +	unsigned long mask_auth = ~disabled_auth;
        +	unsigned long mask_enc = ~disabled_enc;
        +	unsigned long mask_mac = ~disabled_mac;
        +	unsigned long mask_ssl = ~disabled_ssl;
        +
        +	/*
        +	 * First, add the real ciphers as already collected
        +	 */
        +	ciph_curr = head;
        +	ca_curr = ca_list;
        +	while (ciph_curr != NULL)
        +		{
        +		*ca_curr = ciph_curr->cipher;
        +		ca_curr++;
        +		ciph_curr = ciph_curr->next;
        +		}
        +
        +	/*
        +	 * Now we add the available ones from the cipher_aliases[] table.
        +	 * They represent either one or more algorithms, some of which
        +	 * in any affected category must be supported (set in enabled_mask),
        +	 * or represent a cipher strength value (will be added in any case because algorithms=0).
        +	 */
        +	for (i = 0; i < num_of_group_aliases; i++)
        +		{
        +		unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey;
        +		unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth;
        +		unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc;
        +		unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac;
        +		unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl;
        +
        +		if (algorithm_mkey)
        +			if ((algorithm_mkey & mask_mkey) == 0)
        +				continue;
        +	
        +		if (algorithm_auth)
        +			if ((algorithm_auth & mask_auth) == 0)
        +				continue;
        +		
        +		if (algorithm_enc)
        +			if ((algorithm_enc & mask_enc) == 0)
        +				continue;
        +		
        +		if (algorithm_mac)
        +			if ((algorithm_mac & mask_mac) == 0)
        +				continue;
        +		
        +		if (algorithm_ssl)
        +			if ((algorithm_ssl & mask_ssl) == 0)
        +				continue;
        +		
        +		*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
        +		ca_curr++;
        +		}
        +
        +	*ca_curr = NULL;	/* end of list */
        +	}
        +
        +static void ssl_cipher_apply_rule(unsigned long cipher_id,
        +                unsigned long alg_mkey, unsigned long alg_auth,
        +                unsigned long alg_enc, unsigned long alg_mac,
        +                unsigned long alg_ssl,
        +		unsigned long algo_strength,
        +		int rule, int strength_bits,
        +		CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
        +	{
        +	CIPHER_ORDER *head, *tail, *curr, *curr2, *last;
        +	const SSL_CIPHER *cp;
        +	int reverse = 0;
        +
        +#ifdef CIPHER_DEBUG
        +	printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
        +		rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
        +#endif
        +
        +	if (rule == CIPHER_DEL)
        +		reverse = 1; /* needed to maintain sorting between currently deleted ciphers */
        +
        +	head = *head_p;
        +	tail = *tail_p;
        +
        +	if (reverse)
        +		{
        +		curr = tail;
        +		last = head;
        +		}
        +	else
        +		{
        +		curr = head;
        +		last = tail;
        +		}
        +
        +	curr2 = curr;
        +	for (;;)
        +		{
        +		if ((curr == NULL) || (curr == last)) break;
        +		curr = curr2;
        +		curr2 = reverse ? curr->prev : curr->next;
        +
        +		cp = curr->cipher;
        +
        +		/*
        +		 * Selection criteria is either the value of strength_bits
        +		 * or the algorithms used.
        +		 */
        +		if (strength_bits >= 0)
        +			{
        +			if (strength_bits != cp->strength_bits)
        +				continue;
        +			}
        +		else
        +			{
        +#ifdef CIPHER_DEBUG
        +			printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
        +#endif
        +
        +			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
        +				continue;
        +			if (alg_auth && !(alg_auth & cp->algorithm_auth))
        +				continue;
        +			if (alg_enc && !(alg_enc & cp->algorithm_enc))
        +				continue;
        +			if (alg_mac && !(alg_mac & cp->algorithm_mac))
        +				continue;
        +			if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
        +				continue;
        +			if ((algo_strength & SSL_EXP_MASK) && !(algo_strength & SSL_EXP_MASK & cp->algo_strength))
        +				continue;
        +			if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
        +				continue;
        +			}
        +
        +#ifdef CIPHER_DEBUG
        +		printf("Action = %d\n", rule);
        +#endif
        +
        +		/* add the cipher if it has not been added yet. */
        +		if (rule == CIPHER_ADD)
        +			{
        +			/* reverse == 0 */
        +			if (!curr->active)
        +				{
        +				ll_append_tail(&head, curr, &tail);
        +				curr->active = 1;
        +				}
        +			}
        +		/* Move the added cipher to this location */
        +		else if (rule == CIPHER_ORD)
        +			{
        +			/* reverse == 0 */
        +			if (curr->active)
        +				{
        +				ll_append_tail(&head, curr, &tail);
        +				}
        +			}
        +		else if	(rule == CIPHER_DEL)
        +			{
        +			/* reverse == 1 */
        +			if (curr->active)
        +				{
        +				/* most recently deleted ciphersuites get best positions
        +				 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
        +				 * works in reverse to maintain the order) */
        +				ll_append_head(&head, curr, &tail);
        +				curr->active = 0;
        +				}
        +			}
        +		else if (rule == CIPHER_KILL)
        +			{
        +			/* reverse == 0 */
        +			if (head == curr)
        +				head = curr->next;
        +			else
        +				curr->prev->next = curr->next;
        +			if (tail == curr)
        +				tail = curr->prev;
        +			curr->active = 0;
        +			if (curr->next != NULL)
        +				curr->next->prev = curr->prev;
        +			if (curr->prev != NULL)
        +				curr->prev->next = curr->next;
        +			curr->next = NULL;
        +			curr->prev = NULL;
        +			}
        +		}
        +
        +	*head_p = head;
        +	*tail_p = tail;
        +	}
        +
        +static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
        +				    CIPHER_ORDER **tail_p)
        +	{
        +	int max_strength_bits, i, *number_uses;
        +	CIPHER_ORDER *curr;
        +
        +	/*
        +	 * This routine sorts the ciphers with descending strength. The sorting
        +	 * must keep the pre-sorted sequence, so we apply the normal sorting
        +	 * routine as '+' movement to the end of the list.
        +	 */
        +	max_strength_bits = 0;
        +	curr = *head_p;
        +	while (curr != NULL)
        +		{
        +		if (curr->active &&
        +		    (curr->cipher->strength_bits > max_strength_bits))
        +		    max_strength_bits = curr->cipher->strength_bits;
        +		curr = curr->next;
        +		}
        +
        +	number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
        +	if (!number_uses)
        +		{
        +		SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
        +
        +	/*
        +	 * Now find the strength_bits values actually used
        +	 */
        +	curr = *head_p;
        +	while (curr != NULL)
        +		{
        +		if (curr->active)
        +			number_uses[curr->cipher->strength_bits]++;
        +		curr = curr->next;
        +		}
        +	/*
        +	 * Go through the list of used strength_bits values in descending
        +	 * order.
        +	 */
        +	for (i = max_strength_bits; i >= 0; i--)
        +		if (number_uses[i] > 0)
        +			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p);
        +
        +	OPENSSL_free(number_uses);
        +	return(1);
        +	}
        +
        +static int ssl_cipher_process_rulestr(const char *rule_str,
        +                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p,
        +                const SSL_CIPHER **ca_list)
        +	{
        +	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
        +	const char *l, *buf;
        +	int j, multi, found, rule, retval, ok, buflen;
        +	unsigned long cipher_id = 0;
        +	char ch;
        +
        +	retval = 1;
        +	l = rule_str;
        +	for (;;)
        +		{
        +		ch = *l;
        +
        +		if (ch == '\0')
        +			break;		/* done */
        +		if (ch == '-')
        +			{ rule = CIPHER_DEL; l++; }
        +		else if (ch == '+')
        +			{ rule = CIPHER_ORD; l++; }
        +		else if (ch == '!')
        +			{ rule = CIPHER_KILL; l++; }
        +		else if (ch == '@')
        +			{ rule = CIPHER_SPECIAL; l++; }
        +		else
        +			{ rule = CIPHER_ADD; }
        +
        +		if (ITEM_SEP(ch))
        +			{
        +			l++;
        +			continue;
        +			}
        +
        +		alg_mkey = 0;
        +		alg_auth = 0;
        +		alg_enc = 0;
        +		alg_mac = 0;
        +		alg_ssl = 0;
        +		algo_strength = 0;
        +
        +		for (;;)
        +			{
        +			ch = *l;
        +			buf = l;
        +			buflen = 0;
        +#ifndef CHARSET_EBCDIC
        +			while (	((ch >= 'A') && (ch <= 'Z')) ||
        +				((ch >= '0') && (ch <= '9')) ||
        +				((ch >= 'a') && (ch <= 'z')) ||
        +				 (ch == '-') || (ch == '.'))
        +#else
        +			while (	isalnum(ch) || (ch == '-') || (ch == '.'))
        +#endif
        +				 {
        +				 ch = *(++l);
        +				 buflen++;
        +				 }
        +
        +			if (buflen == 0)
        +				{
        +				/*
        +				 * We hit something we cannot deal with,
        +				 * it is no command or separator nor
        +				 * alphanumeric, so we call this an error.
        +				 */
        +				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
        +				       SSL_R_INVALID_COMMAND);
        +				retval = found = 0;
        +				l++;
        +				break;
        +				}
        +
        +			if (rule == CIPHER_SPECIAL)
        +				{
        +				found = 0; /* unused -- avoid compiler warning */
        +				break;	/* special treatment */
        +				}
        +
        +			/* check for multi-part specification */
        +			if (ch == '+')
        +				{
        +				multi=1;
        +				l++;
        +				}
        +			else
        +				multi=0;
        +
        +			/*
        +			 * Now search for the cipher alias in the ca_list. Be careful
        +			 * with the strncmp, because the "buflen" limitation
        +			 * will make the rule "ADH:SOME" and the cipher
        +			 * "ADH-MY-CIPHER" look like a match for buflen=3.
        +			 * So additionally check whether the cipher name found
        +			 * has the correct length. We can save a strlen() call:
        +			 * just checking for the '\0' at the right place is
        +			 * sufficient, we have to strncmp() anyway. (We cannot
        +			 * use strcmp(), because buf is not '\0' terminated.)
        +			 */
        +			j = found = 0;
        +			cipher_id = 0;
        +			while (ca_list[j])
        +				{
        +				if (!strncmp(buf, ca_list[j]->name, buflen) &&
        +				    (ca_list[j]->name[buflen] == '\0'))
        +					{
        +					found = 1;
        +					break;
        +					}
        +				else
        +					j++;
        +				}
        +
        +			if (!found)
        +				break;	/* ignore this entry */
        +
        +			if (ca_list[j]->algorithm_mkey)
        +				{
        +				if (alg_mkey)
        +					{
        +					alg_mkey &= ca_list[j]->algorithm_mkey;
        +					if (!alg_mkey) { found = 0; break; }
        +					}
        +				else
        +					alg_mkey = ca_list[j]->algorithm_mkey;
        +				}
        +
        +			if (ca_list[j]->algorithm_auth)
        +				{
        +				if (alg_auth)
        +					{
        +					alg_auth &= ca_list[j]->algorithm_auth;
        +					if (!alg_auth) { found = 0; break; }
        +					}
        +				else
        +					alg_auth = ca_list[j]->algorithm_auth;
        +				}
        +			
        +			if (ca_list[j]->algorithm_enc)
        +				{
        +				if (alg_enc)
        +					{
        +					alg_enc &= ca_list[j]->algorithm_enc;
        +					if (!alg_enc) { found = 0; break; }
        +					}
        +				else
        +					alg_enc = ca_list[j]->algorithm_enc;
        +				}
        +						
        +			if (ca_list[j]->algorithm_mac)
        +				{
        +				if (alg_mac)
        +					{
        +					alg_mac &= ca_list[j]->algorithm_mac;
        +					if (!alg_mac) { found = 0; break; }
        +					}
        +				else
        +					alg_mac = ca_list[j]->algorithm_mac;
        +				}
        +			
        +			if (ca_list[j]->algo_strength & SSL_EXP_MASK)
        +				{
        +				if (algo_strength & SSL_EXP_MASK)
        +					{
        +					algo_strength &= (ca_list[j]->algo_strength & SSL_EXP_MASK) | ~SSL_EXP_MASK;
        +					if (!(algo_strength & SSL_EXP_MASK)) { found = 0; break; }
        +					}
        +				else
        +					algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK;
        +				}
        +
        +			if (ca_list[j]->algo_strength & SSL_STRONG_MASK)
        +				{
        +				if (algo_strength & SSL_STRONG_MASK)
        +					{
        +					algo_strength &= (ca_list[j]->algo_strength & SSL_STRONG_MASK) | ~SSL_STRONG_MASK;
        +					if (!(algo_strength & SSL_STRONG_MASK)) { found = 0; break; }
        +					}
        +				else
        +					algo_strength |= ca_list[j]->algo_strength & SSL_STRONG_MASK;
        +				}
        +			
        +			if (ca_list[j]->valid)
        +				{
        +				/* explicit ciphersuite found; its protocol version
        +				 * does not become part of the search pattern!*/
        +
        +				cipher_id = ca_list[j]->id;
        +				}
        +			else
        +				{
        +				/* not an explicit ciphersuite; only in this case, the
        +				 * protocol version is considered part of the search pattern */
        +
        +				if (ca_list[j]->algorithm_ssl)
        +					{
        +					if (alg_ssl)
        +						{
        +						alg_ssl &= ca_list[j]->algorithm_ssl;
        +						if (!alg_ssl) { found = 0; break; }
        +						}
        +					else
        +						alg_ssl = ca_list[j]->algorithm_ssl;
        +					}
        +				}
        +			
        +			if (!multi) break;
        +			}
        +
        +		/*
        +		 * Ok, we have the rule, now apply it
        +		 */
        +		if (rule == CIPHER_SPECIAL)
        +			{	/* special command */
        +			ok = 0;
        +			if ((buflen == 8) &&
        +				!strncmp(buf, "STRENGTH", 8))
        +				ok = ssl_cipher_strength_sort(head_p, tail_p);
        +			else
        +				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
        +					SSL_R_INVALID_COMMAND);
        +			if (ok == 0)
        +				retval = 0;
        +			/*
        +			 * We do not support any "multi" options
        +			 * together with "@", so throw away the
        +			 * rest of the command, if any left, until
        +			 * end or ':' is found.
        +			 */
        +			while ((*l != '\0') && !ITEM_SEP(*l))
        +				l++;
        +			}
        +		else if (found)
        +			{
        +			ssl_cipher_apply_rule(cipher_id,
        +				alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength,
        +				rule, -1, head_p, tail_p);
        +			}
        +		else
        +			{
        +			while ((*l != '\0') && !ITEM_SEP(*l))
        +				l++;
        +			}
        +		if (*l == '\0') break; /* done */
        +		}
        +
        +	return(retval);
        +	}
        +
        +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
        +		STACK_OF(SSL_CIPHER) **cipher_list,
        +		STACK_OF(SSL_CIPHER) **cipher_list_by_id,
        +		const char *rule_str)
        +	{
        +	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
        +	unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
        +	STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
        +	const char *rule_p;
        +	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
        +	const SSL_CIPHER **ca_list = NULL;
        +
        +	/*
        +	 * Return with error if nothing to do.
        +	 */
        +	if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
        +		return NULL;
        +
        +	/*
        +	 * To reduce the work to do we only want to process the compiled
        +	 * in algorithms, so we first get the mask of disabled ciphers.
        +	 */
        +	ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
        +
        +	/*
        +	 * Now we have to collect the available ciphers from the compiled
        +	 * in ciphers. We cannot get more than the number compiled in, so
        +	 * it is used for allocation.
        +	 */
        +	num_of_ciphers = ssl_method->num_ciphers();
        +#ifdef KSSL_DEBUG
        +	printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
        +#endif    /* KSSL_DEBUG */
        +	co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
        +	if (co_list == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
        +		return(NULL);	/* Failure */
        +		}
        +
        +	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
        +	                           disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
        +	                           co_list, &head, &tail);
        +
        +
        +	/* Now arrange all ciphers by preference: */
        +
        +	/* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */
        +	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
        +	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
        +
        +	/* AES is our preferred symmetric cipher */
        +	ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
        +
        +	/* Temporarily enable everything else for sorting */
        +	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
        +
        +	/* Low priority for MD5 */
        +	ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +
        +	/* Move anonymous ciphers to the end.  Usually, these will remain disabled.
        +	 * (For applications that allow them, they aren't too bad, but we prefer
        +	 * authenticated ciphers.) */
        +	ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +
        +	/* Move ciphers without forward secrecy to the end */
        +	ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +	/* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); */
        +	ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +	ssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +	ssl_cipher_apply_rule(0, SSL_kKRB5, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +
        +	/* RC4 is sort-of broken -- move the the end */
        +	ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
        +
        +	/* Now sort by symmetric encryption strength.  The above ordering remains
        +	 * in force within each class */
        +	if (!ssl_cipher_strength_sort(&head, &tail))
        +		{
        +		OPENSSL_free(co_list);
        +		return NULL;
        +		}
        +
        +	/* Now disable everything (maintaining the ordering!) */
        +	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
        +
        +
        +	/*
        +	 * We also need cipher aliases for selecting based on the rule_str.
        +	 * There might be two types of entries in the rule_str: 1) names
        +	 * of ciphers themselves 2) aliases for groups of ciphers.
        +	 * For 1) we need the available ciphers and for 2) the cipher
        +	 * groups of cipher_aliases added together in one list (otherwise
        +	 * we would be happy with just the cipher_aliases table).
        +	 */
        +	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
        +	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
        +	ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
        +	if (ca_list == NULL)
        +		{
        +		OPENSSL_free(co_list);
        +		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
        +		return(NULL);	/* Failure */
        +		}
        +	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
        +	                           disabled_mkey, disabled_auth, disabled_enc,
        +				   disabled_mac, disabled_ssl, head);
        +
        +	/*
        +	 * If the rule_string begins with DEFAULT, apply the default rule
        +	 * before using the (possibly available) additional rules.
        +	 */
        +	ok = 1;
        +	rule_p = rule_str;
        +	if (strncmp(rule_str,"DEFAULT",7) == 0)
        +		{
        +		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
        +			&head, &tail, ca_list);
        +		rule_p += 7;
        +		if (*rule_p == ':')
        +			rule_p++;
        +		}
        +
        +	if (ok && (strlen(rule_p) > 0))
        +		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list);
        +
        +	OPENSSL_free((void *)ca_list);	/* Not needed anymore */
        +
        +	if (!ok)
        +		{	/* Rule processing failure */
        +		OPENSSL_free(co_list);
        +		return(NULL);
        +		}
        +	
        +	/*
        +	 * Allocate new "cipherstack" for the result, return with error
        +	 * if we cannot get one.
        +	 */
        +	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
        +		{
        +		OPENSSL_free(co_list);
        +		return(NULL);
        +		}
        +
        +	/*
        +	 * The cipher selection for the list is done. The ciphers are added
        +	 * to the resulting precedence to the STACK_OF(SSL_CIPHER).
        +	 */
        +	for (curr = head; curr != NULL; curr = curr->next)
        +		{
        +#ifdef OPENSSL_FIPS
        +		if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
        +#else
        +		if (curr->active)
        +#endif
        +			{
        +			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
        +#ifdef CIPHER_DEBUG
        +			printf("<%s>\n",curr->cipher->name);
        +#endif
        +			}
        +		}
        +	OPENSSL_free(co_list);	/* Not needed any longer */
        +
        +	tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
        +	if (tmp_cipher_list == NULL)
        +		{
        +		sk_SSL_CIPHER_free(cipherstack);
        +		return NULL;
        +		}
        +	if (*cipher_list != NULL)
        +		sk_SSL_CIPHER_free(*cipher_list);
        +	*cipher_list = cipherstack;
        +	if (*cipher_list_by_id != NULL)
        +		sk_SSL_CIPHER_free(*cipher_list_by_id);
        +	*cipher_list_by_id = tmp_cipher_list;
        +	(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
        +
        +	sk_SSL_CIPHER_sort(*cipher_list_by_id);
        +	return(cipherstack);
        +	}
        +
        +char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
        +	{
        +	int is_export,pkl,kl;
        +	const char *ver,*exp_str;
        +	const char *kx,*au,*enc,*mac;
        +	unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2;
        +#ifdef KSSL_DEBUG
        +	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n";
        +#else
        +	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
        +#endif /* KSSL_DEBUG */
        +
        +	alg_mkey = cipher->algorithm_mkey;
        +	alg_auth = cipher->algorithm_auth;
        +	alg_enc = cipher->algorithm_enc;
        +	alg_mac = cipher->algorithm_mac;
        +	alg_ssl = cipher->algorithm_ssl;
        +
        +	alg2=cipher->algorithm2;
        +
        +	is_export=SSL_C_IS_EXPORT(cipher);
        +	pkl=SSL_C_EXPORT_PKEYLENGTH(cipher);
        +	kl=SSL_C_EXPORT_KEYLENGTH(cipher);
        +	exp_str=is_export?" export":"";
        +	
        +	if (alg_ssl & SSL_SSLV2)
        +		ver="SSLv2";
        +	else if (alg_ssl & SSL_SSLV3)
        +		ver="SSLv3";
        +	else if (alg_ssl & SSL_TLSV1_2)
        +		ver="TLSv1.2";
        +	else
        +		ver="unknown";
        +
        +	switch (alg_mkey)
        +		{
        +	case SSL_kRSA:
        +		kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";
        +		break;
        +	case SSL_kDHr:
        +		kx="DH/RSA";
        +		break;
        +	case SSL_kDHd:
        +		kx="DH/DSS";
        +		break;
        +        case SSL_kKRB5:
        +		kx="KRB5";
        +		break;
        +	case SSL_kEDH:
        +		kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
        +		break;
        +	case SSL_kECDHr:
        +		kx="ECDH/RSA";
        +		break;
        +	case SSL_kECDHe:
        +		kx="ECDH/ECDSA";
        +		break;
        +	case SSL_kEECDH:
        +		kx="ECDH";
        +		break;
        +	case SSL_kPSK:
        +		kx="PSK";
        +		break;
        +	case SSL_kSRP:
        +		kx="SRP";
        +		break;
        +	default:
        +		kx="unknown";
        +		}
        +
        +	switch (alg_auth)
        +		{
        +	case SSL_aRSA:
        +		au="RSA";
        +		break;
        +	case SSL_aDSS:
        +		au="DSS";
        +		break;
        +	case SSL_aDH:
        +		au="DH";
        +		break;
        +        case SSL_aKRB5:
        +		au="KRB5";
        +		break;
        +        case SSL_aECDH:
        +		au="ECDH";
        +		break;
        +	case SSL_aNULL:
        +		au="None";
        +		break;
        +	case SSL_aECDSA:
        +		au="ECDSA";
        +		break;
        +	case SSL_aPSK:
        +		au="PSK";
        +		break;
        +	default:
        +		au="unknown";
        +		break;
        +		}
        +
        +	switch (alg_enc)
        +		{
        +	case SSL_DES:
        +		enc=(is_export && kl == 5)?"DES(40)":"DES(56)";
        +		break;
        +	case SSL_3DES:
        +		enc="3DES(168)";
        +		break;
        +	case SSL_RC4:
        +		enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)")
        +		  :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");
        +		break;
        +	case SSL_RC2:
        +		enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)";
        +		break;
        +	case SSL_IDEA:
        +		enc="IDEA(128)";
        +		break;
        +	case SSL_eNULL:
        +		enc="None";
        +		break;
        +	case SSL_AES128:
        +		enc="AES(128)";
        +		break;
        +	case SSL_AES256:
        +		enc="AES(256)";
        +		break;
        +	case SSL_AES128GCM:
        +		enc="AESGCM(128)";
        +		break;
        +	case SSL_AES256GCM:
        +		enc="AESGCM(256)";
        +		break;
        +	case SSL_CAMELLIA128:
        +		enc="Camellia(128)";
        +		break;
        +	case SSL_CAMELLIA256:
        +		enc="Camellia(256)";
        +		break;
        +	case SSL_SEED:
        +		enc="SEED(128)";
        +		break;
        +	default:
        +		enc="unknown";
        +		break;
        +		}
        +
        +	switch (alg_mac)
        +		{
        +	case SSL_MD5:
        +		mac="MD5";
        +		break;
        +	case SSL_SHA1:
        +		mac="SHA1";
        +		break;
        +	case SSL_SHA256:
        +		mac="SHA256";
        +		break;
        +	case SSL_SHA384:
        +		mac="SHA384";
        +		break;
        +	case SSL_AEAD:
        +		mac="AEAD";
        +		break;
        +	default:
        +		mac="unknown";
        +		break;
        +		}
        +
        +	if (buf == NULL)
        +		{
        +		len=128;
        +		buf=OPENSSL_malloc(len);
        +		if (buf == NULL) return("OPENSSL_malloc Error");
        +		}
        +	else if (len < 128)
        +		return("Buffer too small");
        +
        +#ifdef KSSL_DEBUG
        +	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl);
        +#else
        +	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str);
        +#endif /* KSSL_DEBUG */
        +	return(buf);
        +	}
        +
        +char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
        +	{
        +	int i;
        +
        +	if (c == NULL) return("(NONE)");
        +	i=(int)(c->id>>24L);
        +	if (i == 3)
        +		return("TLSv1/SSLv3");
        +	else if (i == 2)
        +		return("SSLv2");
        +	else
        +		return("unknown");
        +	}
        +
        +/* return the actual cipher being used */
        +const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
        +	{
        +	if (c != NULL)
        +		return(c->name);
        +	return("(NONE)");
        +	}
        +
        +/* number of bits for symmetric cipher */
        +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
        +	{
        +	int ret=0;
        +
        +	if (c != NULL)
        +		{
        +		if (alg_bits != NULL) *alg_bits = c->alg_bits;
        +		ret = c->strength_bits;
        +		}
        +	return(ret);
        +	}
        +
        +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c)
        +	{
        +	return c->id;
        +	}
        +
        +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
        +	{
        +	SSL_COMP *ctmp;
        +	int i,nn;
        +
        +	if ((n == 0) || (sk == NULL)) return(NULL);
        +	nn=sk_SSL_COMP_num(sk);
        +	for (i=0; i<nn; i++)
        +		{
        +		ctmp=sk_SSL_COMP_value(sk,i);
        +		if (ctmp->id == n)
        +			return(ctmp);
        +		}
        +	return(NULL);
        +	}
        +
        +#ifdef OPENSSL_NO_COMP
        +void *SSL_COMP_get_compression_methods(void)
        +	{
        +	return NULL;
        +	}
        +int SSL_COMP_add_compression_method(int id, void *cm)
        +	{
        +	return 1;
        +	}
        +
        +const char *SSL_COMP_get_name(const void *comp)
        +	{
        +	return NULL;
        +	}
        +#else
        +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
        +	{
        +	load_builtin_compressions();
        +	return(ssl_comp_methods);
        +	}
        +
        +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
        +	{
        +	SSL_COMP *comp;
        +
        +        if (cm == NULL || cm->type == NID_undef)
        +                return 1;
        +
        +	/* According to draft-ietf-tls-compression-04.txt, the
        +	   compression number ranges should be the following:
        +
        +	   0 to 63:    methods defined by the IETF
        +	   64 to 192:  external party methods assigned by IANA
        +	   193 to 255: reserved for private use */
        +	if (id < 193 || id > 255)
        +		{
        +		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
        +		return 0;
        +		}
        +
        +	MemCheck_off();
        +	comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
        +	comp->id=id;
        +	comp->method=cm;
        +	load_builtin_compressions();
        +	if (ssl_comp_methods
        +		&& sk_SSL_COMP_find(ssl_comp_methods,comp) >= 0)
        +		{
        +		OPENSSL_free(comp);
        +		MemCheck_on();
        +		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_DUPLICATE_COMPRESSION_ID);
        +		return(1);
        +		}
        +	else if ((ssl_comp_methods == NULL)
        +		|| !sk_SSL_COMP_push(ssl_comp_methods,comp))
        +		{
        +		OPENSSL_free(comp);
        +		MemCheck_on();
        +		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE);
        +		return(1);
        +		}
        +	else
        +		{
        +		MemCheck_on();
        +		return(0);
        +		}
        +	}
        +
        +const char *SSL_COMP_get_name(const COMP_METHOD *comp)
        +	{
        +	if (comp)
        +		return comp->name;
        +	return NULL;
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/ssl_err.c b/vendor/openssl/openssl/ssl/ssl_err.c
        new file mode 100644
        index 000000000..370fb57e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_err.c
        @@ -0,0 +1,610 @@
        +/* ssl/ssl_err.c */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0)
        +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason)
        +
        +static ERR_STRING_DATA SSL_str_functs[]=
        +	{
        +{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE),	"CLIENT_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_CLIENT_FINISHED),	"CLIENT_FINISHED"},
        +{ERR_FUNC(SSL_F_CLIENT_HELLO),	"CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_CLIENT_MASTER_KEY),	"CLIENT_MASTER_KEY"},
        +{ERR_FUNC(SSL_F_D2I_SSL_SESSION),	"d2i_SSL_SESSION"},
        +{ERR_FUNC(SSL_F_DO_DTLS1_WRITE),	"DO_DTLS1_WRITE"},
        +{ERR_FUNC(SSL_F_DO_SSL3_WRITE),	"DO_SSL3_WRITE"},
        +{ERR_FUNC(SSL_F_DTLS1_ACCEPT),	"DTLS1_ACCEPT"},
        +{ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF),	"DTLS1_ADD_CERT_TO_BUF"},
        +{ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD),	"DTLS1_BUFFER_RECORD"},
        +{ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM),	"DTLS1_CHECK_TIMEOUT_NUM"},
        +{ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO),	"DTLS1_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_DTLS1_CONNECT),	"DTLS1_CONNECT"},
        +{ERR_FUNC(SSL_F_DTLS1_ENC),	"DTLS1_ENC"},
        +{ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY),	"DTLS1_GET_HELLO_VERIFY"},
        +{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE),	"DTLS1_GET_MESSAGE"},
        +{ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT),	"DTLS1_GET_MESSAGE_FRAGMENT"},
        +{ERR_FUNC(SSL_F_DTLS1_GET_RECORD),	"DTLS1_GET_RECORD"},
        +{ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT),	"DTLS1_HANDLE_TIMEOUT"},
        +{ERR_FUNC(SSL_F_DTLS1_HEARTBEAT),	"DTLS1_HEARTBEAT"},
        +{ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN),	"DTLS1_OUTPUT_CERT_CHAIN"},
        +{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT),	"DTLS1_PREPROCESS_FRAGMENT"},
        +{ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE),	"DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
        +{ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD),	"DTLS1_PROCESS_RECORD"},
        +{ERR_FUNC(SSL_F_DTLS1_READ_BYTES),	"DTLS1_READ_BYTES"},
        +{ERR_FUNC(SSL_F_DTLS1_READ_FAILED),	"DTLS1_READ_FAILED"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST),	"DTLS1_SEND_CERTIFICATE_REQUEST"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE),	"DTLS1_SEND_CLIENT_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE),	"DTLS1_SEND_CLIENT_KEY_EXCHANGE"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY),	"DTLS1_SEND_CLIENT_VERIFY"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST),	"DTLS1_SEND_HELLO_VERIFY_REQUEST"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE),	"DTLS1_SEND_SERVER_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO),	"DTLS1_SEND_SERVER_HELLO"},
        +{ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE),	"DTLS1_SEND_SERVER_KEY_EXCHANGE"},
        +{ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES),	"DTLS1_WRITE_APP_DATA_BYTES"},
        +{ERR_FUNC(SSL_F_GET_CLIENT_FINISHED),	"GET_CLIENT_FINISHED"},
        +{ERR_FUNC(SSL_F_GET_CLIENT_HELLO),	"GET_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY),	"GET_CLIENT_MASTER_KEY"},
        +{ERR_FUNC(SSL_F_GET_SERVER_FINISHED),	"GET_SERVER_FINISHED"},
        +{ERR_FUNC(SSL_F_GET_SERVER_HELLO),	"GET_SERVER_HELLO"},
        +{ERR_FUNC(SSL_F_GET_SERVER_VERIFY),	"GET_SERVER_VERIFY"},
        +{ERR_FUNC(SSL_F_I2D_SSL_SESSION),	"i2d_SSL_SESSION"},
        +{ERR_FUNC(SSL_F_READ_N),	"READ_N"},
        +{ERR_FUNC(SSL_F_REQUEST_CERTIFICATE),	"REQUEST_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_SERVER_FINISH),	"SERVER_FINISH"},
        +{ERR_FUNC(SSL_F_SERVER_HELLO),	"SERVER_HELLO"},
        +{ERR_FUNC(SSL_F_SERVER_VERIFY),	"SERVER_VERIFY"},
        +{ERR_FUNC(SSL_F_SSL23_ACCEPT),	"SSL23_ACCEPT"},
        +{ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO),	"SSL23_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_SSL23_CONNECT),	"SSL23_CONNECT"},
        +{ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO),	"SSL23_GET_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO),	"SSL23_GET_SERVER_HELLO"},
        +{ERR_FUNC(SSL_F_SSL23_PEEK),	"SSL23_PEEK"},
        +{ERR_FUNC(SSL_F_SSL23_READ),	"SSL23_READ"},
        +{ERR_FUNC(SSL_F_SSL23_WRITE),	"SSL23_WRITE"},
        +{ERR_FUNC(SSL_F_SSL2_ACCEPT),	"SSL2_ACCEPT"},
        +{ERR_FUNC(SSL_F_SSL2_CONNECT),	"SSL2_CONNECT"},
        +{ERR_FUNC(SSL_F_SSL2_ENC_INIT),	"SSL2_ENC_INIT"},
        +{ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL),	"SSL2_GENERATE_KEY_MATERIAL"},
        +{ERR_FUNC(SSL_F_SSL2_PEEK),	"SSL2_PEEK"},
        +{ERR_FUNC(SSL_F_SSL2_READ),	"SSL2_READ"},
        +{ERR_FUNC(SSL_F_SSL2_READ_INTERNAL),	"SSL2_READ_INTERNAL"},
        +{ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE),	"SSL2_SET_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_SSL2_WRITE),	"SSL2_WRITE"},
        +{ERR_FUNC(SSL_F_SSL3_ACCEPT),	"SSL3_ACCEPT"},
        +{ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF),	"SSL3_ADD_CERT_TO_BUF"},
        +{ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL),	"SSL3_CALLBACK_CTRL"},
        +{ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE),	"SSL3_CHANGE_CIPHER_STATE"},
        +{ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),	"SSL3_CHECK_CERT_AND_ALGORITHM"},
        +{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO),	"SSL3_CHECK_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO),	"SSL3_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_SSL3_CONNECT),	"SSL3_CONNECT"},
        +{ERR_FUNC(SSL_F_SSL3_CTRL),	"SSL3_CTRL"},
        +{ERR_FUNC(SSL_F_SSL3_CTX_CTRL),	"SSL3_CTX_CTRL"},
        +{ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS),	"SSL3_DIGEST_CACHED_RECORDS"},
        +{ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC),	"SSL3_DO_CHANGE_CIPHER_SPEC"},
        +{ERR_FUNC(SSL_F_SSL3_ENC),	"SSL3_ENC"},
        +{ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK),	"SSL3_GENERATE_KEY_BLOCK"},
        +{ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),	"SSL3_GET_CERTIFICATE_REQUEST"},
        +{ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS),	"SSL3_GET_CERT_STATUS"},
        +{ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY),	"SSL3_GET_CERT_VERIFY"},
        +{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE),	"SSL3_GET_CLIENT_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO),	"SSL3_GET_CLIENT_HELLO"},
        +{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE),	"SSL3_GET_CLIENT_KEY_EXCHANGE"},
        +{ERR_FUNC(SSL_F_SSL3_GET_FINISHED),	"SSL3_GET_FINISHED"},
        +{ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE),	"SSL3_GET_KEY_EXCHANGE"},
        +{ERR_FUNC(SSL_F_SSL3_GET_MESSAGE),	"SSL3_GET_MESSAGE"},
        +{ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET),	"SSL3_GET_NEW_SESSION_TICKET"},
        +{ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO),	"SSL3_GET_NEXT_PROTO"},
        +{ERR_FUNC(SSL_F_SSL3_GET_RECORD),	"SSL3_GET_RECORD"},
        +{ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE),	"SSL3_GET_SERVER_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE),	"SSL3_GET_SERVER_DONE"},
        +{ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO),	"SSL3_GET_SERVER_HELLO"},
        +{ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC),	"ssl3_handshake_mac"},
        +{ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET),	"SSL3_NEW_SESSION_TICKET"},
        +{ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN),	"SSL3_OUTPUT_CERT_CHAIN"},
        +{ERR_FUNC(SSL_F_SSL3_PEEK),	"SSL3_PEEK"},
        +{ERR_FUNC(SSL_F_SSL3_READ_BYTES),	"SSL3_READ_BYTES"},
        +{ERR_FUNC(SSL_F_SSL3_READ_N),	"SSL3_READ_N"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST),	"SSL3_SEND_CERTIFICATE_REQUEST"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE),	"SSL3_SEND_CLIENT_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE),	"SSL3_SEND_CLIENT_KEY_EXCHANGE"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY),	"SSL3_SEND_CLIENT_VERIFY"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE),	"SSL3_SEND_SERVER_CERTIFICATE"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO),	"SSL3_SEND_SERVER_HELLO"},
        +{ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE),	"SSL3_SEND_SERVER_KEY_EXCHANGE"},
        +{ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK),	"SSL3_SETUP_KEY_BLOCK"},
        +{ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER),	"SSL3_SETUP_READ_BUFFER"},
        +{ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER),	"SSL3_SETUP_WRITE_BUFFER"},
        +{ERR_FUNC(SSL_F_SSL3_WRITE_BYTES),	"SSL3_WRITE_BYTES"},
        +{ERR_FUNC(SSL_F_SSL3_WRITE_PENDING),	"SSL3_WRITE_PENDING"},
        +{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
        +{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),	"SSL_ADD_CLIENTHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT),	"SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"},
        +{ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),	"SSL_add_dir_cert_subjects_to_stack"},
        +{ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),	"SSL_add_file_cert_subjects_to_stack"},
        +{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT),	"SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
        +{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),	"SSL_ADD_SERVERHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT),	"SSL_ADD_SERVERHELLO_USE_SRTP_EXT"},
        +{ERR_FUNC(SSL_F_SSL_BAD_METHOD),	"SSL_BAD_METHOD"},
        +{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST),	"SSL_BYTES_TO_CIPHER_LIST"},
        +{ERR_FUNC(SSL_F_SSL_CERT_DUP),	"SSL_CERT_DUP"},
        +{ERR_FUNC(SSL_F_SSL_CERT_INST),	"SSL_CERT_INST"},
        +{ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE),	"SSL_CERT_INSTANTIATE"},
        +{ERR_FUNC(SSL_F_SSL_CERT_NEW),	"SSL_CERT_NEW"},
        +{ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY),	"SSL_check_private_key"},
        +{ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),	"SSL_CHECK_SERVERHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),	"SSL_CHECK_SRVR_ECC_CERT_AND_ALG"},
        +{ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR),	"SSL_CIPHER_PROCESS_RULESTR"},
        +{ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT),	"SSL_CIPHER_STRENGTH_SORT"},
        +{ERR_FUNC(SSL_F_SSL_CLEAR),	"SSL_clear"},
        +{ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD),	"SSL_COMP_add_compression_method"},
        +{ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST),	"SSL_CREATE_CIPHER_LIST"},
        +{ERR_FUNC(SSL_F_SSL_CTRL),	"SSL_ctrl"},
        +{ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY),	"SSL_CTX_check_private_key"},
        +{ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES),	"SSL_CTX_MAKE_PROFILES"},
        +{ERR_FUNC(SSL_F_SSL_CTX_NEW),	"SSL_CTX_new"},
        +{ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST),	"SSL_CTX_set_cipher_list"},
        +{ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE),	"SSL_CTX_set_client_cert_engine"},
        +{ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE),	"SSL_CTX_set_purpose"},
        +{ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT),	"SSL_CTX_set_session_id_context"},
        +{ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION),	"SSL_CTX_set_ssl_version"},
        +{ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST),	"SSL_CTX_set_trust"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE),	"SSL_CTX_use_certificate"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1),	"SSL_CTX_use_certificate_ASN1"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE),	"SSL_CTX_use_certificate_chain_file"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE),	"SSL_CTX_use_certificate_file"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY),	"SSL_CTX_use_PrivateKey"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1),	"SSL_CTX_use_PrivateKey_ASN1"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE),	"SSL_CTX_use_PrivateKey_file"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT),	"SSL_CTX_use_psk_identity_hint"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY),	"SSL_CTX_use_RSAPrivateKey"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1),	"SSL_CTX_use_RSAPrivateKey_ASN1"},
        +{ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE),	"SSL_CTX_use_RSAPrivateKey_file"},
        +{ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE),	"SSL_do_handshake"},
        +{ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION),	"SSL_GET_NEW_SESSION"},
        +{ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION),	"SSL_GET_PREV_SESSION"},
        +{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT),	"SSL_GET_SERVER_SEND_CERT"},
        +{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY),	"SSL_GET_SERVER_SEND_PKEY"},
        +{ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY),	"SSL_GET_SIGN_PKEY"},
        +{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER),	"SSL_INIT_WBIO_BUFFER"},
        +{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE),	"SSL_load_client_CA_file"},
        +{ERR_FUNC(SSL_F_SSL_NEW),	"SSL_new"},
        +{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
        +{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT),	"SSL_PARSE_CLIENTHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT),	"SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT"},
        +{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT),	"SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
        +{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT),	"SSL_PARSE_SERVERHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT),	"SSL_PARSE_SERVERHELLO_USE_SRTP_EXT"},
        +{ERR_FUNC(SSL_F_SSL_PEEK),	"SSL_peek"},
        +{ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT),	"SSL_PREPARE_CLIENTHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT),	"SSL_PREPARE_SERVERHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_SSL_READ),	"SSL_read"},
        +{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT),	"SSL_RSA_PRIVATE_DECRYPT"},
        +{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT),	"SSL_RSA_PUBLIC_ENCRYPT"},
        +{ERR_FUNC(SSL_F_SSL_SESSION_NEW),	"SSL_SESSION_new"},
        +{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP),	"SSL_SESSION_print_fp"},
        +{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT),	"SSL_SESSION_set1_id_context"},
        +{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW),	"SSL_SESS_CERT_NEW"},
        +{ERR_FUNC(SSL_F_SSL_SET_CERT),	"SSL_SET_CERT"},
        +{ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST),	"SSL_set_cipher_list"},
        +{ERR_FUNC(SSL_F_SSL_SET_FD),	"SSL_set_fd"},
        +{ERR_FUNC(SSL_F_SSL_SET_PKEY),	"SSL_SET_PKEY"},
        +{ERR_FUNC(SSL_F_SSL_SET_PURPOSE),	"SSL_set_purpose"},
        +{ERR_FUNC(SSL_F_SSL_SET_RFD),	"SSL_set_rfd"},
        +{ERR_FUNC(SSL_F_SSL_SET_SESSION),	"SSL_set_session"},
        +{ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT),	"SSL_set_session_id_context"},
        +{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT),	"SSL_set_session_ticket_ext"},
        +{ERR_FUNC(SSL_F_SSL_SET_TRUST),	"SSL_set_trust"},
        +{ERR_FUNC(SSL_F_SSL_SET_WFD),	"SSL_set_wfd"},
        +{ERR_FUNC(SSL_F_SSL_SHUTDOWN),	"SSL_shutdown"},
        +{ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT),	"SSL_SRP_CTX_init"},
        +{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION),	"SSL_UNDEFINED_CONST_FUNCTION"},
        +{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION),	"SSL_UNDEFINED_FUNCTION"},
        +{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION),	"SSL_UNDEFINED_VOID_FUNCTION"},
        +{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE),	"SSL_use_certificate"},
        +{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1),	"SSL_use_certificate_ASN1"},
        +{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE),	"SSL_use_certificate_file"},
        +{ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY),	"SSL_use_PrivateKey"},
        +{ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1),	"SSL_use_PrivateKey_ASN1"},
        +{ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE),	"SSL_use_PrivateKey_file"},
        +{ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT),	"SSL_use_psk_identity_hint"},
        +{ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY),	"SSL_use_RSAPrivateKey"},
        +{ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1),	"SSL_use_RSAPrivateKey_ASN1"},
        +{ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE),	"SSL_use_RSAPrivateKey_file"},
        +{ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN),	"SSL_VERIFY_CERT_CHAIN"},
        +{ERR_FUNC(SSL_F_SSL_WRITE),	"SSL_write"},
        +{ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC),	"tls1_cert_verify_mac"},
        +{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE),	"TLS1_CHANGE_CIPHER_STATE"},
        +{ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT),	"TLS1_CHECK_SERVERHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_TLS1_ENC),	"TLS1_ENC"},
        +{ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL),	"TLS1_EXPORT_KEYING_MATERIAL"},
        +{ERR_FUNC(SSL_F_TLS1_HEARTBEAT),	"SSL_F_TLS1_HEARTBEAT"},
        +{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT),	"TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT),	"TLS1_PREPARE_SERVERHELLO_TLSEXT"},
        +{ERR_FUNC(SSL_F_TLS1_PRF),	"tls1_prf"},
        +{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK),	"TLS1_SETUP_KEY_BLOCK"},
        +{ERR_FUNC(SSL_F_WRITE_PENDING),	"WRITE_PENDING"},
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA SSL_str_reasons[]=
        +	{
        +{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) ,"app data in handshake"},
        +{ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),"attempt to reuse session in different context"},
        +{ERR_REASON(SSL_R_BAD_ALERT_RECORD)      ,"bad alert record"},
        +{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"},
        +{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"},
        +{ERR_REASON(SSL_R_BAD_CHECKSUM)          ,"bad checksum"},
        +{ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK),"bad data returned by callback"},
        +{ERR_REASON(SSL_R_BAD_DECOMPRESSION)     ,"bad decompression"},
        +{ERR_REASON(SSL_R_BAD_DH_G_LENGTH)       ,"bad dh g length"},
        +{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH) ,"bad dh pub key length"},
        +{ERR_REASON(SSL_R_BAD_DH_P_LENGTH)       ,"bad dh p length"},
        +{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH)     ,"bad digest length"},
        +{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE)     ,"bad dsa signature"},
        +{ERR_REASON(SSL_R_BAD_ECC_CERT)          ,"bad ecc cert"},
        +{ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE)   ,"bad ecdsa signature"},
        +{ERR_REASON(SSL_R_BAD_ECPOINT)           ,"bad ecpoint"},
        +{ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH)  ,"bad handshake length"},
        +{ERR_REASON(SSL_R_BAD_HELLO_REQUEST)     ,"bad hello request"},
        +{ERR_REASON(SSL_R_BAD_LENGTH)            ,"bad length"},
        +{ERR_REASON(SSL_R_BAD_MAC_DECODE)        ,"bad mac decode"},
        +{ERR_REASON(SSL_R_BAD_MAC_LENGTH)        ,"bad mac length"},
        +{ERR_REASON(SSL_R_BAD_MESSAGE_TYPE)      ,"bad message type"},
        +{ERR_REASON(SSL_R_BAD_PACKET_LENGTH)     ,"bad packet length"},
        +{ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),"bad protocol version number"},
        +{ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH),"bad psk identity hint length"},
        +{ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) ,"bad response argument"},
        +{ERR_REASON(SSL_R_BAD_RSA_DECRYPT)       ,"bad rsa decrypt"},
        +{ERR_REASON(SSL_R_BAD_RSA_ENCRYPT)       ,"bad rsa encrypt"},
        +{ERR_REASON(SSL_R_BAD_RSA_E_LENGTH)      ,"bad rsa e length"},
        +{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"},
        +{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE)     ,"bad rsa signature"},
        +{ERR_REASON(SSL_R_BAD_SIGNATURE)         ,"bad signature"},
        +{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH)      ,"bad srp a length"},
        +{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH)      ,"bad srp b length"},
        +{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH)      ,"bad srp g length"},
        +{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH)      ,"bad srp n length"},
        +{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH)      ,"bad srp s length"},
        +{ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE)    ,"bad srtp mki value"},
        +{ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST),"bad srtp protection profile list"},
        +{ERR_REASON(SSL_R_BAD_SSL_FILETYPE)      ,"bad ssl filetype"},
        +{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
        +{ERR_REASON(SSL_R_BAD_STATE)             ,"bad state"},
        +{ERR_REASON(SSL_R_BAD_WRITE_RETRY)       ,"bad write retry"},
        +{ERR_REASON(SSL_R_BIO_NOT_SET)           ,"bio not set"},
        +{ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),"block cipher pad is wrong"},
        +{ERR_REASON(SSL_R_BN_LIB)                ,"bn lib"},
        +{ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) ,"ca dn length mismatch"},
        +{ERR_REASON(SSL_R_CA_DN_TOO_LONG)        ,"ca dn too long"},
        +{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY)    ,"ccs received early"},
        +{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
        +{ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH)  ,"cert length mismatch"},
        +{ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
        +{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
        +{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
        +{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
        +{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT)    ,"clienthello tlsext"},
        +{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"},
        +{ERR_REASON(SSL_R_COMPRESSION_DISABLED)  ,"compression disabled"},
        +{ERR_REASON(SSL_R_COMPRESSION_FAILURE)   ,"compression failure"},
        +{ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),"compression id not within private range"},
        +{ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),"compression library error"},
        +{ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT),"connection id is different"},
        +{ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET),"connection type not set"},
        +{ERR_REASON(SSL_R_COOKIE_MISMATCH)       ,"cookie mismatch"},
        +{ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),"data between ccs and finished"},
        +{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG)  ,"data length too long"},
        +{ERR_REASON(SSL_R_DECRYPTION_FAILED)     ,"decryption failed"},
        +{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
        +{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
        +{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED)   ,"digest check failed"},
        +{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG)  ,"dtls message too big"},
        +{ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID),"duplicate compression id"},
        +{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT),"ecc cert not for key agreement"},
        +{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING),"ecc cert not for signing"},
        +{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"},
        +{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"},
        +{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
        +{ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST),"empty srtp protection profile list"},
        +{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
        +{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
        +{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
        +{ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
        +{ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
        +{ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
        +{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
        +{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
        +{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST)   ,"https proxy request"},
        +{ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
        +{ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
        +{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
        +{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
        +{ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
        +{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
        +{ERR_REASON(SSL_R_INVALID_PURPOSE)       ,"invalid purpose"},
        +{ERR_REASON(SSL_R_INVALID_SRP_USERNAME)  ,"invalid srp username"},
        +{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
        +{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
        +{ERR_REASON(SSL_R_INVALID_TRUST)         ,"invalid trust"},
        +{ERR_REASON(SSL_R_KEY_ARG_TOO_LONG)      ,"key arg too long"},
        +{ERR_REASON(SSL_R_KRB5)                  ,"krb5"},
        +{ERR_REASON(SSL_R_KRB5_C_CC_PRINC)       ,"krb5 client cc principal (no tkt?)"},
        +{ERR_REASON(SSL_R_KRB5_C_GET_CRED)       ,"krb5 client get cred"},
        +{ERR_REASON(SSL_R_KRB5_C_INIT)           ,"krb5 client init"},
        +{ERR_REASON(SSL_R_KRB5_C_MK_REQ)         ,"krb5 client mk_req (expired tkt?)"},
        +{ERR_REASON(SSL_R_KRB5_S_BAD_TICKET)     ,"krb5 server bad ticket"},
        +{ERR_REASON(SSL_R_KRB5_S_INIT)           ,"krb5 server init"},
        +{ERR_REASON(SSL_R_KRB5_S_RD_REQ)         ,"krb5 server rd_req (keytab perms?)"},
        +{ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED)    ,"krb5 server tkt expired"},
        +{ERR_REASON(SSL_R_KRB5_S_TKT_NYV)        ,"krb5 server tkt not yet valid"},
        +{ERR_REASON(SSL_R_KRB5_S_TKT_SKEW)       ,"krb5 server tkt skew"},
        +{ERR_REASON(SSL_R_LENGTH_MISMATCH)       ,"length mismatch"},
        +{ERR_REASON(SSL_R_LENGTH_TOO_SHORT)      ,"length too short"},
        +{ERR_REASON(SSL_R_LIBRARY_BUG)           ,"library bug"},
        +{ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS),"library has no ciphers"},
        +{ERR_REASON(SSL_R_MESSAGE_TOO_LONG)      ,"message too long"},
        +{ERR_REASON(SSL_R_MISSING_DH_DSA_CERT)   ,"missing dh dsa cert"},
        +{ERR_REASON(SSL_R_MISSING_DH_KEY)        ,"missing dh key"},
        +{ERR_REASON(SSL_R_MISSING_DH_RSA_CERT)   ,"missing dh rsa cert"},
        +{ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT),"missing dsa signing cert"},
        +{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY),"missing export tmp dh key"},
        +{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY),"missing export tmp rsa key"},
        +{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"},
        +{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"},
        +{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"},
        +{ERR_REASON(SSL_R_MISSING_SRP_PARAM)     ,"can't find SRP server param"},
        +{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY)    ,"missing tmp dh key"},
        +{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY)  ,"missing tmp ecdh key"},
        +{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY)   ,"missing tmp rsa key"},
        +{ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY)  ,"missing tmp rsa pkey"},
        +{ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"},
        +{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"},
        +{ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"},
        +{ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"},
        +{ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"},
        +{ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED),"no certificate returned"},
        +{ERR_REASON(SSL_R_NO_CERTIFICATE_SET)    ,"no certificate set"},
        +{ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED),"no certificate specified"},
        +{ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE)  ,"no ciphers available"},
        +{ERR_REASON(SSL_R_NO_CIPHERS_PASSED)     ,"no ciphers passed"},
        +{ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED)  ,"no ciphers specified"},
        +{ERR_REASON(SSL_R_NO_CIPHER_LIST)        ,"no cipher list"},
        +{ERR_REASON(SSL_R_NO_CIPHER_MATCH)       ,"no cipher match"},
        +{ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) ,"no client cert method"},
        +{ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED),"no client cert received"},
        +{ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"},
        +{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"},
        +{ERR_REASON(SSL_R_NO_METHOD_SPECIFIED)   ,"no method specified"},
        +{ERR_REASON(SSL_R_NO_PRIVATEKEY)         ,"no privatekey"},
        +{ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
        +{ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
        +{ERR_REASON(SSL_R_NO_PUBLICKEY)          ,"no publickey"},
        +{ERR_REASON(SSL_R_NO_RENEGOTIATION)      ,"no renegotiation"},
        +{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST)    ,"digest requred for handshake isn't computed"},
        +{ERR_REASON(SSL_R_NO_SHARED_CIPHER)      ,"no shared cipher"},
        +{ERR_REASON(SSL_R_NO_SRTP_PROFILES)      ,"no srtp profiles"},
        +{ERR_REASON(SSL_R_NO_VERIFY_CALLBACK)    ,"no verify callback"},
        +{ERR_REASON(SSL_R_NULL_SSL_CTX)          ,"null ssl ctx"},
        +{ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED),"null ssl method passed"},
        +{ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"},
        +{ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),"old session compression algorithm not returned"},
        +{ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"},
        +{ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG),"opaque PRF input too long"},
        +{ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"},
        +{ERR_REASON(SSL_R_PARSE_TLSEXT)          ,"parse tlsext"},
        +{ERR_REASON(SSL_R_PATH_TOO_LONG)         ,"path too long"},
        +{ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),"peer did not return a certificate"},
        +{ERR_REASON(SSL_R_PEER_ERROR)            ,"peer error"},
        +{ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE),"peer error certificate"},
        +{ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE),"peer error no certificate"},
        +{ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER)  ,"peer error no cipher"},
        +{ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE),"peer error unsupported certificate type"},
        +{ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG),"pre mac length too long"},
        +{ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS),"problems mapping cipher functions"},
        +{ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN)  ,"protocol is shutdown"},
        +{ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND),"psk identity not found"},
        +{ERR_REASON(SSL_R_PSK_NO_CLIENT_CB)      ,"psk no client cb"},
        +{ERR_REASON(SSL_R_PSK_NO_SERVER_CB)      ,"psk no server cb"},
        +{ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR),"public key encrypt error"},
        +{ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) ,"public key is not rsa"},
        +{ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
        +{ERR_REASON(SSL_R_READ_BIO_NOT_SET)      ,"read bio not set"},
        +{ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED)  ,"read timeout expired"},
        +{ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE),"read wrong packet type"},
        +{ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH),"record length mismatch"},
        +{ERR_REASON(SSL_R_RECORD_TOO_LARGE)      ,"record too large"},
        +{ERR_REASON(SSL_R_RECORD_TOO_SMALL)      ,"record too small"},
        +{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG),"renegotiate ext too long"},
        +{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"},
        +{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"},
        +{ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"},
        +{ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING),"required compresssion algorithm missing"},
        +{ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"},
        +{ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"},
        +{ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"},
        +{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
        +{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT)    ,"serverhello tlsext"},
        +{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
        +{ERR_REASON(SSL_R_SHORT_READ)            ,"short read"},
        +{ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),"signature algorithms error"},
        +{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
        +{ERR_REASON(SSL_R_SRP_A_CALC)            ,"error with the srp params"},
        +{ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES),"srtp could not allocate profiles"},
        +{ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG),"srtp protection profile list too long"},
        +{ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE),"srtp unknown protection profile"},
        +{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
        +{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
        +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
        +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),"ssl3 ext invalid servername"},
        +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),"ssl3 ext invalid servername type"},
        +{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG),"ssl3 session id too long"},
        +{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT),"ssl3 session id too short"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE),"sslv3 alert bad certificate"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC),"sslv3 alert bad record mac"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED),"sslv3 alert certificate expired"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED),"sslv3 alert certificate revoked"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN),"sslv3 alert certificate unknown"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE),"sslv3 alert decompression failure"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE),"sslv3 alert handshake failure"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER),"sslv3 alert illegal parameter"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE),"sslv3 alert no certificate"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE),"sslv3 alert unexpected message"},
        +{ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE),"sslv3 alert unsupported certificate"},
        +{ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION),"ssl ctx has no default ssl version"},
        +{ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE) ,"ssl handshake failure"},
        +{ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS),"ssl library has no ciphers"},
        +{ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED),"ssl session id callback failed"},
        +{ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT),"ssl session id conflict"},
        +{ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG),"ssl session id context too long"},
        +{ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH),"ssl session id has bad length"},
        +{ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT),"ssl session id is different"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED),"tlsv1 alert access denied"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR),"tlsv1 alert decode error"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION),"tlsv1 alert protocol version"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),"tlsv1 alert record overflow"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1 alert unknown ca"},
        +{ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1 alert user cancelled"},
        +{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),"tlsv1 bad certificate hash value"},
        +{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),"tlsv1 bad certificate status response"},
        +{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),"tlsv1 certificate unobtainable"},
        +{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
        +{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
        +{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
        +{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbearts"},
        +{ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) ,"heartbeat request already pending"},
        +{ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),"tls illegal exporter label"},
        +{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
        +{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"},
        +{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),"tls rsa encrypted value length is wrong"},
        +{ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),"tried to use unsupported cipher"},
        +{ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS),"unable to decode dh certs"},
        +{ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS),"unable to decode ecdh certs"},
        +{ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY),"unable to extract public key"},
        +{ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS),"unable to find dh parameters"},
        +{ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS),"unable to find ecdh parameters"},
        +{ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS),"unable to find public key parameters"},
        +{ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD),"unable to find ssl method"},
        +{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES),"unable to load ssl2 md5 routines"},
        +{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES),"unable to load ssl3 md5 routines"},
        +{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),"unable to load ssl3 sha1 routines"},
        +{ERR_REASON(SSL_R_UNEXPECTED_MESSAGE)    ,"unexpected message"},
        +{ERR_REASON(SSL_R_UNEXPECTED_RECORD)     ,"unexpected record"},
        +{ERR_REASON(SSL_R_UNINITIALIZED)         ,"uninitialized"},
        +{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE)    ,"unknown alert type"},
        +{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
        +{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
        +{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE)   ,"unknown cipher type"},
        +{ERR_REASON(SSL_R_UNKNOWN_DIGEST)        ,"unknown digest"},
        +{ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),"unknown key exchange type"},
        +{ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE)     ,"unknown pkey type"},
        +{ERR_REASON(SSL_R_UNKNOWN_PROTOCOL)      ,"unknown protocol"},
        +{ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),"unknown remote error type"},
        +{ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION)   ,"unknown ssl version"},
        +{ERR_REASON(SSL_R_UNKNOWN_STATE)         ,"unknown state"},
        +{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE),"unsupported digest type"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL)  ,"unsupported protocol"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
        +{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
        +{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED),"use srtp not negotiated"},
        +{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET)     ,"write bio not set"},
        +{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
        +{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE)    ,"wrong message type"},
        +{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS),"wrong number of key bits"},
        +{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
        +{ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE)  ,"wrong signature size"},
        +{ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE)  ,"wrong signature type"},
        +{ERR_REASON(SSL_R_WRONG_SSL_VERSION)     ,"wrong ssl version"},
        +{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER)  ,"wrong version number"},
        +{ERR_REASON(SSL_R_X509_LIB)              ,"x509 lib"},
        +{ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS),"x509 verification setup problems"},
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +void ERR_load_SSL_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(SSL_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings(0,SSL_str_functs);
        +		ERR_load_strings(0,SSL_str_reasons);
        +		}
        +#endif
        +	}
        diff --git a/vendor/openssl/openssl/ssl/ssl_err2.c b/vendor/openssl/openssl/ssl/ssl_err2.c
        new file mode 100644
        index 000000000..ea95a5f98
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_err2.c
        @@ -0,0 +1,70 @@
        +/* ssl/ssl_err2.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +
        +void SSL_load_error_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +	ERR_load_crypto_strings();
        +	ERR_load_SSL_strings();
        +#endif
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/ssl_lib.c b/vendor/openssl/openssl/ssl/ssl_lib.c
        new file mode 100644
        index 000000000..14d143da0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_lib.c
        @@ -0,0 +1,3265 @@
        +/*! \file ssl/ssl_lib.c
        + *  \brief Version independent SSL functions.
        + */
        +/* 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-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#ifdef REF_CHECK
        +#  include <assert.h>
        +#endif
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include "kssl_lcl.h"
        +#include <openssl/objects.h>
        +#include <openssl/lhash.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/rand.h>
        +#include <openssl/ocsp.h>
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +
        +const char *SSL_version_str=OPENSSL_VERSION_TEXT;
        +
        +SSL3_ENC_METHOD ssl3_undef_enc_method={
        +	/* evil casts, but these functions are only called if there's a library bug */
        +	(int (*)(SSL *,int))ssl_undefined_function,
        +	(int (*)(SSL *, unsigned char *, int))ssl_undefined_function,
        +	ssl_undefined_function,
        +	(int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function,
        +	(int (*)(SSL*, int))ssl_undefined_function,
        +	(int (*)(SSL *,  const char*, int, unsigned char *))ssl_undefined_function,
        +	0,	/* finish_mac_length */
        +	(int (*)(SSL *, int, unsigned char *))ssl_undefined_function,
        +	NULL,	/* client_finished_label */
        +	0,	/* client_finished_label_len */
        +	NULL,	/* server_finished_label */
        +	0,	/* server_finished_label_len */
        +	(int (*)(int))ssl_undefined_function,
        +	(int (*)(SSL *, unsigned char *, size_t, const char *,
        +		 size_t, const unsigned char *, size_t,
        +		 int use_context)) ssl_undefined_function,
        +	};
        +
        +int SSL_clear(SSL *s)
        +	{
        +
        +	if (s->method == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CLEAR,SSL_R_NO_METHOD_SPECIFIED);
        +		return(0);
        +		}
        +
        +	if (ssl_clear_bad_session(s))
        +		{
        +		SSL_SESSION_free(s->session);
        +		s->session=NULL;
        +		}
        +
        +	s->error=0;
        +	s->hit=0;
        +	s->shutdown=0;
        +
        +#if 0 /* Disabled since version 1.10 of this file (early return not
        +       * needed because SSL_clear is not called when doing renegotiation) */
        +	/* This is set if we are doing dynamic renegotiation so keep
        +	 * the old cipher.  It is sort of a SSL_clear_lite :-) */
        +	if (s->renegotiate) return(1);
        +#else
        +	if (s->renegotiate)
        +		{
        +		SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);
        +		return 0;
        +		}
        +#endif
        +
        +	s->type=0;
        +
        +	s->state=SSL_ST_BEFORE|((s->server)?SSL_ST_ACCEPT:SSL_ST_CONNECT);
        +
        +	s->version=s->method->version;
        +	s->client_version=s->version;
        +	s->rwstate=SSL_NOTHING;
        +	s->rstate=SSL_ST_READ_HEADER;
        +#if 0
        +	s->read_ahead=s->ctx->read_ahead;
        +#endif
        +
        +	if (s->init_buf != NULL)
        +		{
        +		BUF_MEM_free(s->init_buf);
        +		s->init_buf=NULL;
        +		}
        +
        +	ssl_clear_cipher_ctx(s);
        +	ssl_clear_hash_ctx(&s->read_hash);
        +	ssl_clear_hash_ctx(&s->write_hash);
        +
        +	s->first_packet=0;
        +
        +#if 1
        +	/* Check to see if we were changed into a different method, if
        +	 * so, revert back if we are not doing session-id reuse. */
        +	if (!s->in_handshake && (s->session == NULL) && (s->method != s->ctx->method))
        +		{
        +		s->method->ssl_free(s);
        +		s->method=s->ctx->method;
        +		if (!s->method->ssl_new(s))
        +			return(0);
        +		}
        +	else
        +#endif
        +		s->method->ssl_clear(s);
        +	return(1);
        +	}
        +
        +/** Used to change an SSL_CTXs default SSL method type */
        +int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth)
        +	{
        +	STACK_OF(SSL_CIPHER) *sk;
        +
        +	ctx->method=meth;
        +
        +	sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list),
        +		&(ctx->cipher_list_by_id),
        +		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
        +	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
        +		return(0);
        +		}
        +	return(1);
        +	}
        +
        +SSL *SSL_new(SSL_CTX *ctx)
        +	{
        +	SSL *s;
        +
        +	if (ctx == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_NEW,SSL_R_NULL_SSL_CTX);
        +		return(NULL);
        +		}
        +	if (ctx->method == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_NEW,SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
        +		return(NULL);
        +		}
        +
        +	s=(SSL *)OPENSSL_malloc(sizeof(SSL));
        +	if (s == NULL) goto err;
        +	memset(s,0,sizeof(SSL));
        +
        +#ifndef	OPENSSL_NO_KRB5
        +	s->kssl_ctx = kssl_ctx_new();
        +#endif	/* OPENSSL_NO_KRB5 */
        +
        +	s->options=ctx->options;
        +	s->mode=ctx->mode;
        +	s->max_cert_list=ctx->max_cert_list;
        +
        +	if (ctx->cert != NULL)
        +		{
        +		/* Earlier library versions used to copy the pointer to
        +		 * the CERT, not its contents; only when setting new
        +		 * parameters for the per-SSL copy, ssl_cert_new would be
        +		 * called (and the direct reference to the per-SSL_CTX
        +		 * settings would be lost, but those still were indirectly
        +		 * accessed for various purposes, and for that reason they
        +		 * used to be known as s->ctx->default_cert).
        +		 * Now we don't look at the SSL_CTX's CERT after having
        +		 * duplicated it once. */
        +
        +		s->cert = ssl_cert_dup(ctx->cert);
        +		if (s->cert == NULL)
        +			goto err;
        +		}
        +	else
        +		s->cert=NULL; /* Cannot really happen (see SSL_CTX_new) */
        +
        +	s->read_ahead=ctx->read_ahead;
        +	s->msg_callback=ctx->msg_callback;
        +	s->msg_callback_arg=ctx->msg_callback_arg;
        +	s->verify_mode=ctx->verify_mode;
        +#if 0
        +	s->verify_depth=ctx->verify_depth;
        +#endif
        +	s->sid_ctx_length=ctx->sid_ctx_length;
        +	OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
        +	memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
        +	s->verify_callback=ctx->default_verify_callback;
        +	s->generate_session_id=ctx->generate_session_id;
        +
        +	s->param = X509_VERIFY_PARAM_new();
        +	if (!s->param)
        +		goto err;
        +	X509_VERIFY_PARAM_inherit(s->param, ctx->param);
        +#if 0
        +	s->purpose = ctx->purpose;
        +	s->trust = ctx->trust;
        +#endif
        +	s->quiet_shutdown=ctx->quiet_shutdown;
        +	s->max_send_fragment = ctx->max_send_fragment;
        +
        +	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
        +	s->ctx=ctx;
        +#ifndef OPENSSL_NO_TLSEXT
        +	s->tlsext_debug_cb = 0;
        +	s->tlsext_debug_arg = NULL;
        +	s->tlsext_ticket_expected = 0;
        +	s->tlsext_status_type = -1;
        +	s->tlsext_status_expected = 0;
        +	s->tlsext_ocsp_ids = NULL;
        +	s->tlsext_ocsp_exts = NULL;
        +	s->tlsext_ocsp_resp = NULL;
        +	s->tlsext_ocsp_resplen = -1;
        +	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
        +	s->initial_ctx=ctx;
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	s->next_proto_negotiated = NULL;
        +# endif
        +#endif
        +
        +	s->verify_result=X509_V_OK;
        +
        +	s->method=ctx->method;
        +
        +	if (!s->method->ssl_new(s))
        +		goto err;
        +
        +	s->references=1;
        +	s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
        +
        +	SSL_clear(s);
        +
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
        +
        +#ifndef OPENSSL_NO_PSK
        +	s->psk_client_callback=ctx->psk_client_callback;
        +	s->psk_server_callback=ctx->psk_server_callback;
        +#endif
        +
        +	return(s);
        +err:
        +	if (s != NULL)
        +		{
        +		if (s->cert != NULL)
        +			ssl_cert_free(s->cert);
        +		if (s->ctx != NULL)
        +			SSL_CTX_free(s->ctx); /* decrement reference count */
        +		OPENSSL_free(s);
        +		}
        +	SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
        +	return(NULL);
        +	}
        +
        +int SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
        +				   unsigned int sid_ctx_len)
        +    {
        +    if(sid_ctx_len > sizeof ctx->sid_ctx)
        +	{
        +	SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
        +	return 0;
        +	}
        +    ctx->sid_ctx_length=sid_ctx_len;
        +    memcpy(ctx->sid_ctx,sid_ctx,sid_ctx_len);
        +
        +    return 1;
        +    }
        +
        +int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
        +			       unsigned int sid_ctx_len)
        +    {
        +    if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
        +	{
        +	SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
        +	return 0;
        +	}
        +    ssl->sid_ctx_length=sid_ctx_len;
        +    memcpy(ssl->sid_ctx,sid_ctx,sid_ctx_len);
        +
        +    return 1;
        +    }
        +
        +int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +	ctx->generate_session_id = cb;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +	return 1;
        +	}
        +
        +int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
        +	{
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL);
        +	ssl->generate_session_id = cb;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
        +	return 1;
        +	}
        +
        +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
        +				unsigned int id_len)
        +	{
        +	/* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
        +	 * we can "construct" a session to give us the desired check - ie. to
        +	 * find if there's a session in the hash table that would conflict with
        +	 * any new session built out of this id/id_len and the ssl_version in
        +	 * use by this SSL. */
        +	SSL_SESSION r, *p;
        +
        +	if(id_len > sizeof r.session_id)
        +		return 0;
        +
        +	r.ssl_version = ssl->version;
        +	r.session_id_length = id_len;
        +	memcpy(r.session_id, id, id_len);
        +	/* NB: SSLv2 always uses a fixed 16-byte session ID, so even if a
        +	 * callback is calling us to check the uniqueness of a shorter ID, it
        +	 * must be compared as a padded-out ID because that is what it will be
        +	 * converted to when the callback has finished choosing it. */
        +	if((r.ssl_version == SSL2_VERSION) &&
        +			(id_len < SSL2_SSL_SESSION_ID_LENGTH))
        +		{
        +		memset(r.session_id + id_len, 0,
        +			SSL2_SSL_SESSION_ID_LENGTH - id_len);
        +		r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
        +		}
        +
        +	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
        +	p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
        +	CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
        +	return (p != NULL);
        +	}
        +
        +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
        +	{
        +	return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
        +	}
        +
        +int SSL_set_purpose(SSL *s, int purpose)
        +	{
        +	return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
        +	}
        +
        +int SSL_CTX_set_trust(SSL_CTX *s, int trust)
        +	{
        +	return X509_VERIFY_PARAM_set_trust(s->param, trust);
        +	}
        +
        +int SSL_set_trust(SSL *s, int trust)
        +	{
        +	return X509_VERIFY_PARAM_set_trust(s->param, trust);
        +	}
        +
        +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
        +	{
        +	return X509_VERIFY_PARAM_set1(ctx->param, vpm);
        +	}
        +
        +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
        +	{
        +	return X509_VERIFY_PARAM_set1(ssl->param, vpm);
        +	}
        +
        +void SSL_free(SSL *s)
        +	{
        +	int i;
        +
        +	if(s == NULL)
        +	    return;
        +
        +	i=CRYPTO_add(&s->references,-1,CRYPTO_LOCK_SSL);
        +#ifdef REF_PRINT
        +	REF_PRINT("SSL",s);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"SSL_free, bad reference count\n");
        +		abort(); /* ok */
        +		}
        +#endif
        +
        +	if (s->param)
        +		X509_VERIFY_PARAM_free(s->param);
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
        +
        +	if (s->bbio != NULL)
        +		{
        +		/* If the buffering BIO is in place, pop it off */
        +		if (s->bbio == s->wbio)
        +			{
        +			s->wbio=BIO_pop(s->wbio);
        +			}
        +		BIO_free(s->bbio);
        +		s->bbio=NULL;
        +		}
        +	if (s->rbio != NULL)
        +		BIO_free_all(s->rbio);
        +	if ((s->wbio != NULL) && (s->wbio != s->rbio))
        +		BIO_free_all(s->wbio);
        +
        +	if (s->init_buf != NULL) BUF_MEM_free(s->init_buf);
        +
        +	/* add extra stuff */
        +	if (s->cipher_list != NULL) sk_SSL_CIPHER_free(s->cipher_list);
        +	if (s->cipher_list_by_id != NULL) sk_SSL_CIPHER_free(s->cipher_list_by_id);
        +
        +	/* Make the next call work :-) */
        +	if (s->session != NULL)
        +		{
        +		ssl_clear_bad_session(s);
        +		SSL_SESSION_free(s->session);
        +		}
        +
        +	ssl_clear_cipher_ctx(s);
        +	ssl_clear_hash_ctx(&s->read_hash);
        +	ssl_clear_hash_ctx(&s->write_hash);
        +
        +	if (s->cert != NULL) ssl_cert_free(s->cert);
        +	/* Free up if allocated */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (s->tlsext_hostname)
        +		OPENSSL_free(s->tlsext_hostname);
        +	if (s->initial_ctx) SSL_CTX_free(s->initial_ctx);
        +#ifndef OPENSSL_NO_EC
        +	if (s->tlsext_ecpointformatlist) OPENSSL_free(s->tlsext_ecpointformatlist);
        +	if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist);
        +#endif /* OPENSSL_NO_EC */
        +	if (s->tlsext_opaque_prf_input) OPENSSL_free(s->tlsext_opaque_prf_input);
        +	if (s->tlsext_ocsp_exts)
        +		sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
        +						X509_EXTENSION_free);
        +	if (s->tlsext_ocsp_ids)
        +		sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
        +	if (s->tlsext_ocsp_resp)
        +		OPENSSL_free(s->tlsext_ocsp_resp);
        +#endif
        +
        +	if (s->client_CA != NULL)
        +		sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
        +
        +	if (s->method != NULL) s->method->ssl_free(s);
        +
        +	if (s->ctx) SSL_CTX_free(s->ctx);
        +
        +#ifndef	OPENSSL_NO_KRB5
        +	if (s->kssl_ctx != NULL)
        +		kssl_ctx_free(s->kssl_ctx);
        +#endif	/* OPENSSL_NO_KRB5 */
        +
        +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        +	if (s->next_proto_negotiated)
        +		OPENSSL_free(s->next_proto_negotiated);
        +#endif
        +
        +#ifndef OPENSSL_NO_SRTP
        +        if (s->srtp_profiles)
        +            sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
        +#endif
        +
        +	OPENSSL_free(s);
        +	}
        +
        +void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
        +	{
        +	/* If the output buffering BIO is still in place, remove it
        +	 */
        +	if (s->bbio != NULL)
        +		{
        +		if (s->wbio == s->bbio)
        +			{
        +			s->wbio=s->wbio->next_bio;
        +			s->bbio->next_bio=NULL;
        +			}
        +		}
        +	if ((s->rbio != NULL) && (s->rbio != rbio))
        +		BIO_free_all(s->rbio);
        +	if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
        +		BIO_free_all(s->wbio);
        +	s->rbio=rbio;
        +	s->wbio=wbio;
        +	}
        +
        +BIO *SSL_get_rbio(const SSL *s)
        +	{ return(s->rbio); }
        +
        +BIO *SSL_get_wbio(const SSL *s)
        +	{ return(s->wbio); }
        +
        +int SSL_get_fd(const SSL *s)
        +	{
        +	return(SSL_get_rfd(s));
        +	}
        +
        +int SSL_get_rfd(const SSL *s)
        +	{
        +	int ret= -1;
        +	BIO *b,*r;
        +
        +	b=SSL_get_rbio(s);
        +	r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
        +	if (r != NULL)
        +		BIO_get_fd(r,&ret);
        +	return(ret);
        +	}
        +
        +int SSL_get_wfd(const SSL *s)
        +	{
        +	int ret= -1;
        +	BIO *b,*r;
        +
        +	b=SSL_get_wbio(s);
        +	r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
        +	if (r != NULL)
        +		BIO_get_fd(r,&ret);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_SOCK
        +int SSL_set_fd(SSL *s,int fd)
        +	{
        +	int ret=0;
        +	BIO *bio=NULL;
        +
        +	bio=BIO_new(BIO_s_socket());
        +
        +	if (bio == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_SET_FD,ERR_R_BUF_LIB);
        +		goto err;
        +		}
        +	BIO_set_fd(bio,fd,BIO_NOCLOSE);
        +	SSL_set_bio(s,bio,bio);
        +	ret=1;
        +err:
        +	return(ret);
        +	}
        +
        +int SSL_set_wfd(SSL *s,int fd)
        +	{
        +	int ret=0;
        +	BIO *bio=NULL;
        +
        +	if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET)
        +		|| ((int)BIO_get_fd(s->rbio,NULL) != fd))
        +		{
        +		bio=BIO_new(BIO_s_socket());
        +
        +		if (bio == NULL)
        +			{ SSLerr(SSL_F_SSL_SET_WFD,ERR_R_BUF_LIB); goto err; }
        +		BIO_set_fd(bio,fd,BIO_NOCLOSE);
        +		SSL_set_bio(s,SSL_get_rbio(s),bio);
        +		}
        +	else
        +		SSL_set_bio(s,SSL_get_rbio(s),SSL_get_rbio(s));
        +	ret=1;
        +err:
        +	return(ret);
        +	}
        +
        +int SSL_set_rfd(SSL *s,int fd)
        +	{
        +	int ret=0;
        +	BIO *bio=NULL;
        +
        +	if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET)
        +		|| ((int)BIO_get_fd(s->wbio,NULL) != fd))
        +		{
        +		bio=BIO_new(BIO_s_socket());
        +
        +		if (bio == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_SET_RFD,ERR_R_BUF_LIB);
        +			goto err;
        +			}
        +		BIO_set_fd(bio,fd,BIO_NOCLOSE);
        +		SSL_set_bio(s,bio,SSL_get_wbio(s));
        +		}
        +	else
        +		SSL_set_bio(s,SSL_get_wbio(s),SSL_get_wbio(s));
        +	ret=1;
        +err:
        +	return(ret);
        +	}
        +#endif
        +
        +
        +/* return length of latest Finished message we sent, copy to 'buf' */
        +size_t SSL_get_finished(const SSL *s, void *buf, size_t count)
        +	{
        +	size_t ret = 0;
        +	
        +	if (s->s3 != NULL)
        +		{
        +		ret = s->s3->tmp.finish_md_len;
        +		if (count > ret)
        +			count = ret;
        +		memcpy(buf, s->s3->tmp.finish_md, count);
        +		}
        +	return ret;
        +	}
        +
        +/* return length of latest Finished message we expected, copy to 'buf' */
        +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count)
        +	{
        +	size_t ret = 0;
        +	
        +	if (s->s3 != NULL)
        +		{
        +		ret = s->s3->tmp.peer_finish_md_len;
        +		if (count > ret)
        +			count = ret;
        +		memcpy(buf, s->s3->tmp.peer_finish_md, count);
        +		}
        +	return ret;
        +	}
        +
        +
        +int SSL_get_verify_mode(const SSL *s)
        +	{
        +	return(s->verify_mode);
        +	}
        +
        +int SSL_get_verify_depth(const SSL *s)
        +	{
        +	return X509_VERIFY_PARAM_get_depth(s->param);
        +	}
        +
        +int (*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *)
        +	{
        +	return(s->verify_callback);
        +	}
        +
        +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
        +	{
        +	return(ctx->verify_mode);
        +	}
        +
        +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
        +	{
        +	return X509_VERIFY_PARAM_get_depth(ctx->param);
        +	}
        +
        +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *)
        +	{
        +	return(ctx->default_verify_callback);
        +	}
        +
        +void SSL_set_verify(SSL *s,int mode,
        +		    int (*callback)(int ok,X509_STORE_CTX *ctx))
        +	{
        +	s->verify_mode=mode;
        +	if (callback != NULL)
        +		s->verify_callback=callback;
        +	}
        +
        +void SSL_set_verify_depth(SSL *s,int depth)
        +	{
        +	X509_VERIFY_PARAM_set_depth(s->param, depth);
        +	}
        +
        +void SSL_set_read_ahead(SSL *s,int yes)
        +	{
        +	s->read_ahead=yes;
        +	}
        +
        +int SSL_get_read_ahead(const SSL *s)
        +	{
        +	return(s->read_ahead);
        +	}
        +
        +int SSL_pending(const SSL *s)
        +	{
        +	/* SSL_pending cannot work properly if read-ahead is enabled
        +	 * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)),
        +	 * and it is impossible to fix since SSL_pending cannot report
        +	 * errors that may be observed while scanning the new data.
        +	 * (Note that SSL_pending() is often used as a boolean value,
        +	 * so we'd better not return -1.)
        +	 */
        +	return(s->method->ssl_pending(s));
        +	}
        +
        +X509 *SSL_get_peer_certificate(const SSL *s)
        +	{
        +	X509 *r;
        +	
        +	if ((s == NULL) || (s->session == NULL))
        +		r=NULL;
        +	else
        +		r=s->session->peer;
        +
        +	if (r == NULL) return(r);
        +
        +	CRYPTO_add(&r->references,1,CRYPTO_LOCK_X509);
        +
        +	return(r);
        +	}
        +
        +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
        +	{
        +	STACK_OF(X509) *r;
        +	
        +	if ((s == NULL) || (s->session == NULL) || (s->session->sess_cert == NULL))
        +		r=NULL;
        +	else
        +		r=s->session->sess_cert->cert_chain;
        +
        +	/* If we are a client, cert_chain includes the peer's own
        +	 * certificate; if we are a server, it does not. */
        +	
        +	return(r);
        +	}
        +
        +/* Now in theory, since the calling process own 't' it should be safe to
        + * modify.  We need to be able to read f without being hassled */
        +void SSL_copy_session_id(SSL *t,const SSL *f)
        +	{
        +	CERT *tmp;
        +
        +	/* Do we need to to SSL locking? */
        +	SSL_set_session(t,SSL_get_session(f));
        +
        +	/* what if we are setup as SSLv2 but want to talk SSLv3 or
        +	 * vice-versa */
        +	if (t->method != f->method)
        +		{
        +		t->method->ssl_free(t);	/* cleanup current */
        +		t->method=f->method;	/* change method */
        +		t->method->ssl_new(t);	/* setup new */
        +		}
        +
        +	tmp=t->cert;
        +	if (f->cert != NULL)
        +		{
        +		CRYPTO_add(&f->cert->references,1,CRYPTO_LOCK_SSL_CERT);
        +		t->cert=f->cert;
        +		}
        +	else
        +		t->cert=NULL;
        +	if (tmp != NULL) ssl_cert_free(tmp);
        +	SSL_set_session_id_context(t,f->sid_ctx,f->sid_ctx_length);
        +	}
        +
        +/* Fix this so it checks all the valid key/cert options */
        +int SSL_CTX_check_private_key(const SSL_CTX *ctx)
        +	{
        +	if (	(ctx == NULL) ||
        +		(ctx->cert == NULL) ||
        +		(ctx->cert->key->x509 == NULL))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
        +		return(0);
        +		}
        +	if 	(ctx->cert->key->privatekey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
        +		return(0);
        +		}
        +	return(X509_check_private_key(ctx->cert->key->x509, ctx->cert->key->privatekey));
        +	}
        +
        +/* Fix this function so that it takes an optional type parameter */
        +int SSL_check_private_key(const SSL *ssl)
        +	{
        +	if (ssl == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (ssl->cert == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
        +		return 0;
        +		}
        +	if (ssl->cert->key->x509 == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
        +		return(0);
        +		}
        +	if (ssl->cert->key->privatekey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_PRIVATE_KEY_ASSIGNED);
        +		return(0);
        +		}
        +	return(X509_check_private_key(ssl->cert->key->x509,
        +		ssl->cert->key->privatekey));
        +	}
        +
        +int SSL_accept(SSL *s)
        +	{
        +	if (s->handshake_func == 0)
        +		/* Not properly initialized yet */
        +		SSL_set_accept_state(s);
        +
        +	return(s->method->ssl_accept(s));
        +	}
        +
        +int SSL_connect(SSL *s)
        +	{
        +	if (s->handshake_func == 0)
        +		/* Not properly initialized yet */
        +		SSL_set_connect_state(s);
        +
        +	return(s->method->ssl_connect(s));
        +	}
        +
        +long SSL_get_default_timeout(const SSL *s)
        +	{
        +	return(s->method->get_timeout());
        +	}
        +
        +int SSL_read(SSL *s,void *buf,int num)
        +	{
        +	if (s->handshake_func == 0)
        +		{
        +		SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
        +		return -1;
        +		}
        +
        +	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
        +		{
        +		s->rwstate=SSL_NOTHING;
        +		return(0);
        +		}
        +	return(s->method->ssl_read(s,buf,num));
        +	}
        +
        +int SSL_peek(SSL *s,void *buf,int num)
        +	{
        +	if (s->handshake_func == 0)
        +		{
        +		SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
        +		return -1;
        +		}
        +
        +	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
        +		{
        +		return(0);
        +		}
        +	return(s->method->ssl_peek(s,buf,num));
        +	}
        +
        +int SSL_write(SSL *s,const void *buf,int num)
        +	{
        +	if (s->handshake_func == 0)
        +		{
        +		SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
        +		return -1;
        +		}
        +
        +	if (s->shutdown & SSL_SENT_SHUTDOWN)
        +		{
        +		s->rwstate=SSL_NOTHING;
        +		SSLerr(SSL_F_SSL_WRITE,SSL_R_PROTOCOL_IS_SHUTDOWN);
        +		return(-1);
        +		}
        +	return(s->method->ssl_write(s,buf,num));
        +	}
        +
        +int SSL_shutdown(SSL *s)
        +	{
        +	/* Note that this function behaves differently from what one might
        +	 * expect.  Return values are 0 for no success (yet),
        +	 * 1 for success; but calling it once is usually not enough,
        +	 * even if blocking I/O is used (see ssl3_shutdown).
        +	 */
        +
        +	if (s->handshake_func == 0)
        +		{
        +		SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED);
        +		return -1;
        +		}
        +
        +	if ((s != NULL) && !SSL_in_init(s))
        +		return(s->method->ssl_shutdown(s));
        +	else
        +		return(1);
        +	}
        +
        +int SSL_renegotiate(SSL *s)
        +	{
        +	if (s->renegotiate == 0)
        +		s->renegotiate=1;
        +
        +	s->new_session=1;
        +
        +	return(s->method->ssl_renegotiate(s));
        +	}
        +
        +int SSL_renegotiate_abbreviated(SSL *s)
        +	{
        +	if (s->renegotiate == 0)
        +		s->renegotiate=1;
        +
        +	s->new_session=0;
        +
        +	return(s->method->ssl_renegotiate(s));
        +	}
        +
        +int SSL_renegotiate_pending(SSL *s)
        +	{
        +	/* becomes true when negotiation is requested;
        +	 * false again once a handshake has finished */
        +	return (s->renegotiate != 0);
        +	}
        +
        +long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
        +	{
        +	long l;
        +
        +	switch (cmd)
        +		{
        +	case SSL_CTRL_GET_READ_AHEAD:
        +		return(s->read_ahead);
        +	case SSL_CTRL_SET_READ_AHEAD:
        +		l=s->read_ahead;
        +		s->read_ahead=larg;
        +		return(l);
        +
        +	case SSL_CTRL_SET_MSG_CALLBACK_ARG:
        +		s->msg_callback_arg = parg;
        +		return 1;
        +
        +	case SSL_CTRL_OPTIONS:
        +		return(s->options|=larg);
        +	case SSL_CTRL_CLEAR_OPTIONS:
        +		return(s->options&=~larg);
        +	case SSL_CTRL_MODE:
        +		return(s->mode|=larg);
        +	case SSL_CTRL_CLEAR_MODE:
        +		return(s->mode &=~larg);
        +	case SSL_CTRL_GET_MAX_CERT_LIST:
        +		return(s->max_cert_list);
        +	case SSL_CTRL_SET_MAX_CERT_LIST:
        +		l=s->max_cert_list;
        +		s->max_cert_list=larg;
        +		return(l);
        +	case SSL_CTRL_SET_MTU:
        +#ifndef OPENSSL_NO_DTLS1
        +		if (larg < (long)dtls1_min_mtu())
        +			return 0;
        +#endif
        +
        +		if (SSL_version(s) == DTLS1_VERSION ||
        +		    SSL_version(s) == DTLS1_BAD_VER)
        +			{
        +			s->d1->mtu = larg;
        +			return larg;
        +			}
        +		return 0;
        +	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
        +		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
        +			return 0;
        +		s->max_send_fragment = larg;
        +		return 1;
        +	case SSL_CTRL_GET_RI_SUPPORT:
        +		if (s->s3)
        +			return s->s3->send_connection_binding;
        +		else return 0;
        +	default:
        +		return(s->method->ssl_ctrl(s,cmd,larg,parg));
        +		}
        +	}
        +
        +long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
        +	{
        +	switch(cmd)
        +		{
        +	case SSL_CTRL_SET_MSG_CALLBACK:
        +		s->msg_callback = (void (*)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))(fp);
        +		return 1;
        +		
        +	default:
        +		return(s->method->ssl_callback_ctrl(s,cmd,fp));
        +		}
        +	}
        +
        +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
        +	{
        +	return ctx->sessions;
        +	}
        +
        +long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg)
        +	{
        +	long l;
        +
        +	switch (cmd)
        +		{
        +	case SSL_CTRL_GET_READ_AHEAD:
        +		return(ctx->read_ahead);
        +	case SSL_CTRL_SET_READ_AHEAD:
        +		l=ctx->read_ahead;
        +		ctx->read_ahead=larg;
        +		return(l);
        +		
        +	case SSL_CTRL_SET_MSG_CALLBACK_ARG:
        +		ctx->msg_callback_arg = parg;
        +		return 1;
        +
        +	case SSL_CTRL_GET_MAX_CERT_LIST:
        +		return(ctx->max_cert_list);
        +	case SSL_CTRL_SET_MAX_CERT_LIST:
        +		l=ctx->max_cert_list;
        +		ctx->max_cert_list=larg;
        +		return(l);
        +
        +	case SSL_CTRL_SET_SESS_CACHE_SIZE:
        +		l=ctx->session_cache_size;
        +		ctx->session_cache_size=larg;
        +		return(l);
        +	case SSL_CTRL_GET_SESS_CACHE_SIZE:
        +		return(ctx->session_cache_size);
        +	case SSL_CTRL_SET_SESS_CACHE_MODE:
        +		l=ctx->session_cache_mode;
        +		ctx->session_cache_mode=larg;
        +		return(l);
        +	case SSL_CTRL_GET_SESS_CACHE_MODE:
        +		return(ctx->session_cache_mode);
        +
        +	case SSL_CTRL_SESS_NUMBER:
        +		return(lh_SSL_SESSION_num_items(ctx->sessions));
        +	case SSL_CTRL_SESS_CONNECT:
        +		return(ctx->stats.sess_connect);
        +	case SSL_CTRL_SESS_CONNECT_GOOD:
        +		return(ctx->stats.sess_connect_good);
        +	case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
        +		return(ctx->stats.sess_connect_renegotiate);
        +	case SSL_CTRL_SESS_ACCEPT:
        +		return(ctx->stats.sess_accept);
        +	case SSL_CTRL_SESS_ACCEPT_GOOD:
        +		return(ctx->stats.sess_accept_good);
        +	case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
        +		return(ctx->stats.sess_accept_renegotiate);
        +	case SSL_CTRL_SESS_HIT:
        +		return(ctx->stats.sess_hit);
        +	case SSL_CTRL_SESS_CB_HIT:
        +		return(ctx->stats.sess_cb_hit);
        +	case SSL_CTRL_SESS_MISSES:
        +		return(ctx->stats.sess_miss);
        +	case SSL_CTRL_SESS_TIMEOUTS:
        +		return(ctx->stats.sess_timeout);
        +	case SSL_CTRL_SESS_CACHE_FULL:
        +		return(ctx->stats.sess_cache_full);
        +	case SSL_CTRL_OPTIONS:
        +		return(ctx->options|=larg);
        +	case SSL_CTRL_CLEAR_OPTIONS:
        +		return(ctx->options&=~larg);
        +	case SSL_CTRL_MODE:
        +		return(ctx->mode|=larg);
        +	case SSL_CTRL_CLEAR_MODE:
        +		return(ctx->mode&=~larg);
        +	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
        +		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
        +			return 0;
        +		ctx->max_send_fragment = larg;
        +		return 1;
        +	default:
        +		return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
        +		}
        +	}
        +
        +long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
        +	{
        +	switch(cmd)
        +		{
        +	case SSL_CTRL_SET_MSG_CALLBACK:
        +		ctx->msg_callback = (void (*)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))(fp);
        +		return 1;
        +
        +	default:
        +		return(ctx->method->ssl_ctx_callback_ctrl(ctx,cmd,fp));
        +		}
        +	}
        +
        +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
        +	{
        +	long l;
        +
        +	l=a->id-b->id;
        +	if (l == 0L)
        +		return(0);
        +	else
        +		return((l > 0)?1:-1);
        +	}
        +
        +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
        +			const SSL_CIPHER * const *bp)
        +	{
        +	long l;
        +
        +	l=(*ap)->id-(*bp)->id;
        +	if (l == 0L)
        +		return(0);
        +	else
        +		return((l > 0)?1:-1);
        +	}
        +
        +/** return a STACK of the ciphers available for the SSL and in order of
        + * preference */
        +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
        +	{
        +	if (s != NULL)
        +		{
        +		if (s->cipher_list != NULL)
        +			{
        +			return(s->cipher_list);
        +			}
        +		else if ((s->ctx != NULL) &&
        +			(s->ctx->cipher_list != NULL))
        +			{
        +			return(s->ctx->cipher_list);
        +			}
        +		}
        +	return(NULL);
        +	}
        +
        +/** return a STACK of the ciphers available for the SSL and in order of
        + * algorithm id */
        +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
        +	{
        +	if (s != NULL)
        +		{
        +		if (s->cipher_list_by_id != NULL)
        +			{
        +			return(s->cipher_list_by_id);
        +			}
        +		else if ((s->ctx != NULL) &&
        +			(s->ctx->cipher_list_by_id != NULL))
        +			{
        +			return(s->ctx->cipher_list_by_id);
        +			}
        +		}
        +	return(NULL);
        +	}
        +
        +/** The old interface to get the same thing as SSL_get_ciphers() */
        +const char *SSL_get_cipher_list(const SSL *s,int n)
        +	{
        +	SSL_CIPHER *c;
        +	STACK_OF(SSL_CIPHER) *sk;
        +
        +	if (s == NULL) return(NULL);
        +	sk=SSL_get_ciphers(s);
        +	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n))
        +		return(NULL);
        +	c=sk_SSL_CIPHER_value(sk,n);
        +	if (c == NULL) return(NULL);
        +	return(c->name);
        +	}
        +
        +/** specify the ciphers to be used by default by the SSL_CTX */
        +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
        +	{
        +	STACK_OF(SSL_CIPHER) *sk;
        +	
        +	sk=ssl_create_cipher_list(ctx->method,&ctx->cipher_list,
        +		&ctx->cipher_list_by_id,str);
        +	/* ssl_create_cipher_list may return an empty stack if it
        +	 * was unable to find a cipher matching the given rule string
        +	 * (for example if the rule string specifies a cipher which
        +	 * has been disabled). This is not an error as far as
        +	 * ssl_create_cipher_list is concerned, and hence
        +	 * ctx->cipher_list and ctx->cipher_list_by_id has been
        +	 * updated. */
        +	if (sk == NULL)
        +		return 0;
        +	else if (sk_SSL_CIPHER_num(sk) == 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +/** specify the ciphers to be used by the SSL */
        +int SSL_set_cipher_list(SSL *s,const char *str)
        +	{
        +	STACK_OF(SSL_CIPHER) *sk;
        +	
        +	sk=ssl_create_cipher_list(s->ctx->method,&s->cipher_list,
        +		&s->cipher_list_by_id,str);
        +	/* see comment in SSL_CTX_set_cipher_list */
        +	if (sk == NULL)
        +		return 0;
        +	else if (sk_SSL_CIPHER_num(sk) == 0)
        +		{
        +		SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
        +		return 0;
        +		}
        +	return 1;
        +	}
        +
        +/* works well for SSLv2, not so good for SSLv3 */
        +char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
        +	{
        +	char *p;
        +	STACK_OF(SSL_CIPHER) *sk;
        +	SSL_CIPHER *c;
        +	int i;
        +
        +	if ((s->session == NULL) || (s->session->ciphers == NULL) ||
        +		(len < 2))
        +		return(NULL);
        +
        +	p=buf;
        +	sk=s->session->ciphers;
        +	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
        +		{
        +		int n;
        +
        +		c=sk_SSL_CIPHER_value(sk,i);
        +		n=strlen(c->name);
        +		if (n+1 > len)
        +			{
        +			if (p != buf)
        +				--p;
        +			*p='\0';
        +			return buf;
        +			}
        +		strcpy(p,c->name);
        +		p+=n;
        +		*(p++)=':';
        +		len-=n+1;
        +		}
        +	p[-1]='\0';
        +	return(buf);
        +	}
        +
        +int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
        +			     int (*put_cb)(const SSL_CIPHER *, unsigned char *))
        +	{
        +	int i,j=0;
        +	SSL_CIPHER *c;
        +	unsigned char *q;
        +#ifndef OPENSSL_NO_KRB5
        +	int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
        +#endif /* OPENSSL_NO_KRB5 */
        +
        +	if (sk == NULL) return(0);
        +	q=p;
        +
        +	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
        +		{
        +		c=sk_SSL_CIPHER_value(sk,i);
        +		/* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
        +		if ((c->algorithm_ssl & SSL_TLSV1_2) && 
        +			(TLS1_get_client_version(s) < TLS1_2_VERSION))
        +			continue;
        +#ifndef OPENSSL_NO_KRB5
        +		if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&
        +		    nokrb5)
        +		    continue;
        +#endif /* OPENSSL_NO_KRB5 */
        +#ifndef OPENSSL_NO_PSK
        +		/* with PSK there must be client callback set */
        +		if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) &&
        +		    s->psk_client_callback == NULL)
        +			continue;
        +#endif /* OPENSSL_NO_PSK */
        +		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
        +		p+=j;
        +		}
        +	/* If p == q, no ciphers and caller indicates an error. Otherwise
        +	 * add SCSV if not renegotiating.
        +	 */
        +	if (p != q && !s->renegotiate)
        +		{
        +		static SSL_CIPHER scsv =
        +			{
        +			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
        +			};
        +		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
        +		p+=j;
        +#ifdef OPENSSL_RI_DEBUG
        +		fprintf(stderr, "SCSV sent by client\n");
        +#endif
        +		}
        +
        +	return(p-q);
        +	}
        +
        +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
        +					       STACK_OF(SSL_CIPHER) **skp)
        +	{
        +	const SSL_CIPHER *c;
        +	STACK_OF(SSL_CIPHER) *sk;
        +	int i,n;
        +	if (s->s3)
        +		s->s3->send_connection_binding = 0;
        +
        +	n=ssl_put_cipher_by_char(s,NULL,NULL);
        +	if ((num%n) != 0)
        +		{
        +		SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
        +		return(NULL);
        +		}
        +	if ((skp == NULL) || (*skp == NULL))
        +		sk=sk_SSL_CIPHER_new_null(); /* change perhaps later */
        +	else
        +		{
        +		sk= *skp;
        +		sk_SSL_CIPHER_zero(sk);
        +		}
        +
        +	for (i=0; i<num; i+=n)
        +		{
        +		/* Check for SCSV */
        +		if (s->s3 && (n != 3 || !p[0]) &&
        +			(p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
        +			(p[n-1] == (SSL3_CK_SCSV & 0xff)))
        +			{
        +			/* SCSV fatal if renegotiating */
        +			if (s->renegotiate)
        +				{
        +				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
        +				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); 
        +				goto err;
        +				}
        +			s->s3->send_connection_binding = 1;
        +			p += n;
        +#ifdef OPENSSL_RI_DEBUG
        +			fprintf(stderr, "SCSV received by server\n");
        +#endif
        +			continue;
        +			}
        +
        +		c=ssl_get_cipher_by_char(s,p);
        +		p+=n;
        +		if (c != NULL)
        +			{
        +			if (!sk_SSL_CIPHER_push(sk,c))
        +				{
        +				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
        +				goto err;
        +				}
        +			}
        +		}
        +
        +	if (skp != NULL)
        +		*skp=sk;
        +	return(sk);
        +err:
        +	if ((skp == NULL) || (*skp == NULL))
        +		sk_SSL_CIPHER_free(sk);
        +	return(NULL);
        +	}
        +
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +/** return a servername extension value if provided in Client Hello, or NULL.
        + * So far, only host_name types are defined (RFC 3546).
        + */
        +
        +const char *SSL_get_servername(const SSL *s, const int type)
        +	{
        +	if (type != TLSEXT_NAMETYPE_host_name)
        +		return NULL;
        +
        +	return s->session && !s->tlsext_hostname ?
        +		s->session->tlsext_hostname :
        +		s->tlsext_hostname;
        +	}
        +
        +int SSL_get_servername_type(const SSL *s)
        +	{
        +	if (s->session && (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname))
        +		return TLSEXT_NAMETYPE_host_name;
        +	return -1;
        +	}
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +/* SSL_select_next_proto implements the standard protocol selection. It is
        + * expected that this function is called from the callback set by
        + * SSL_CTX_set_next_proto_select_cb.
        + *
        + * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
        + * strings. The length byte itself is not included in the length. A byte
        + * string of length 0 is invalid. No byte string may be truncated.
        + *
        + * The current, but experimental algorithm for selecting the protocol is:
        + *
        + * 1) If the server doesn't support NPN then this is indicated to the
        + * callback. In this case, the client application has to abort the connection
        + * or have a default application level protocol.
        + *
        + * 2) If the server supports NPN, but advertises an empty list then the
        + * client selects the first protcol in its list, but indicates via the
        + * API that this fallback case was enacted.
        + *
        + * 3) Otherwise, the client finds the first protocol in the server's list
        + * that it supports and selects this protocol. This is because it's
        + * assumed that the server has better information about which protocol
        + * a client should use.
        + *
        + * 4) If the client doesn't support any of the server's advertised
        + * protocols, then this is treated the same as case 2.
        + *
        + * It returns either
        + * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
        + * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
        + */
        +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsigned char *server, unsigned int server_len, const unsigned char *client, unsigned int client_len)
        +	{
        +	unsigned int i, j;
        +	const unsigned char *result;
        +	int status = OPENSSL_NPN_UNSUPPORTED;
        +
        +	/* For each protocol in server preference order, see if we support it. */
        +	for (i = 0; i < server_len; )
        +		{
        +		for (j = 0; j < client_len; )
        +			{
        +			if (server[i] == client[j] &&
        +			    memcmp(&server[i+1], &client[j+1], server[i]) == 0)
        +				{
        +				/* We found a match */
        +				result = &server[i];
        +				status = OPENSSL_NPN_NEGOTIATED;
        +				goto found;
        +				}
        +			j += client[j];
        +			j++;
        +			}
        +		i += server[i];
        +		i++;
        +		}
        +
        +	/* There's no overlap between our protocols and the server's list. */
        +	result = client;
        +	status = OPENSSL_NPN_NO_OVERLAP;
        +
        +	found:
        +	*out = (unsigned char *) result + 1;
        +	*outlen = result[0];
        +	return status;
        +	}
        +
        +/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
        + * requested protocol for this connection and returns 0. If the client didn't
        + * request any protocol, then *data is set to NULL.
        + *
        + * Note that the client can request any protocol it chooses. The value returned
        + * from this function need not be a member of the list of supported protocols
        + * provided by the callback.
        + */
        +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len)
        +	{
        +	*data = s->next_proto_negotiated;
        +	if (!*data) {
        +		*len = 0;
        +	} else {
        +		*len = s->next_proto_negotiated_len;
        +	}
        +}
        +
        +/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
        + * TLS server needs a list of supported protocols for Next Protocol
        + * Negotiation. The returned list must be in wire format.  The list is returned
        + * by setting |out| to point to it and |outlen| to its length. This memory will
        + * not be modified, but one should assume that the SSL* keeps a reference to
        + * it.
        + *
        + * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise. Otherwise, no
        + * such extension will be included in the ServerHello. */
        +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg), void *arg)
        +	{
        +	ctx->next_protos_advertised_cb = cb;
        +	ctx->next_protos_advertised_cb_arg = arg;
        +	}
        +
        +/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
        + * client needs to select a protocol from the server's provided list. |out|
        + * must be set to point to the selected protocol (which may be within |in|).
        + * The length of the protocol name must be written into |outlen|. The server's
        + * advertised protocols are provided in |in| and |inlen|. The callback can
        + * assume that |in| is syntactically valid.
        + *
        + * The client must select a protocol. It is fatal to the connection if this
        + * callback returns a value other than SSL_TLSEXT_ERR_OK.
        + */
        +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg), void *arg)
        +	{
        +	ctx->next_proto_select_cb = cb;
        +	ctx->next_proto_select_cb_arg = arg;
        +	}
        +# endif
        +#endif
        +
        +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
        +	const char *label, size_t llen, const unsigned char *p, size_t plen,
        +	int use_context)
        +	{
        +	if (s->version < TLS1_VERSION)
        +		return -1;
        +
        +	return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
        +							   llen, p, plen,
        +							   use_context);
        +	}
        +
        +static unsigned long ssl_session_hash(const SSL_SESSION *a)
        +	{
        +	unsigned long l;
        +
        +	l=(unsigned long)
        +		((unsigned int) a->session_id[0]     )|
        +		((unsigned int) a->session_id[1]<< 8L)|
        +		((unsigned long)a->session_id[2]<<16L)|
        +		((unsigned long)a->session_id[3]<<24L);
        +	return(l);
        +	}
        +
        +/* NB: If this function (or indeed the hash function which uses a sort of
        + * coarser function than this one) is changed, ensure
        + * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
        + * able to construct an SSL_SESSION that will collide with any existing session
        + * with a matching session ID. */
        +static int ssl_session_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
        +	{
        +	if (a->ssl_version != b->ssl_version)
        +		return(1);
        +	if (a->session_id_length != b->session_id_length)
        +		return(1);
        +	return(memcmp(a->session_id,b->session_id,a->session_id_length));
        +	}
        +
        +/* These wrapper functions should remain rather than redeclaring
        + * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
        + * variable. The reason is that the functions aren't static, they're exposed via
        + * ssl.h. */
        +static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION)
        +static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION)
        +
        +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
        +	{
        +	SSL_CTX *ret=NULL;
        +
        +	if (meth == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);
        +		return(NULL);
        +		}
        +
        +#ifdef OPENSSL_FIPS
        +	if (FIPS_mode() && (meth->version < TLS1_VERSION))	
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
        +		return NULL;
        +		}
        +#endif
        +
        +	if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
        +		goto err;
        +		}
        +	ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
        +	if (ret == NULL)
        +		goto err;
        +
        +	memset(ret,0,sizeof(SSL_CTX));
        +
        +	ret->method=meth;
        +
        +	ret->cert_store=NULL;
        +	ret->session_cache_mode=SSL_SESS_CACHE_SERVER;
        +	ret->session_cache_size=SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
        +	ret->session_cache_head=NULL;
        +	ret->session_cache_tail=NULL;
        +
        +	/* We take the system default */
        +	ret->session_timeout=meth->get_timeout();
        +
        +	ret->new_session_cb=0;
        +	ret->remove_session_cb=0;
        +	ret->get_session_cb=0;
        +	ret->generate_session_id=0;
        +
        +	memset((char *)&ret->stats,0,sizeof(ret->stats));
        +
        +	ret->references=1;
        +	ret->quiet_shutdown=0;
        +
        +/*	ret->cipher=NULL;*/
        +/*	ret->s2->challenge=NULL;
        +	ret->master_key=NULL;
        +	ret->key_arg=NULL;
        +	ret->s2->conn_id=NULL; */
        +
        +	ret->info_callback=NULL;
        +
        +	ret->app_verify_callback=0;
        +	ret->app_verify_arg=NULL;
        +
        +	ret->max_cert_list=SSL_MAX_CERT_LIST_DEFAULT;
        +	ret->read_ahead=0;
        +	ret->msg_callback=0;
        +	ret->msg_callback_arg=NULL;
        +	ret->verify_mode=SSL_VERIFY_NONE;
        +#if 0
        +	ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
        +#endif
        +	ret->sid_ctx_length=0;
        +	ret->default_verify_callback=NULL;
        +	if ((ret->cert=ssl_cert_new()) == NULL)
        +		goto err;
        +
        +	ret->default_passwd_callback=0;
        +	ret->default_passwd_callback_userdata=NULL;
        +	ret->client_cert_cb=0;
        +	ret->app_gen_cookie_cb=0;
        +	ret->app_verify_cookie_cb=0;
        +
        +	ret->sessions=lh_SSL_SESSION_new();
        +	if (ret->sessions == NULL) goto err;
        +	ret->cert_store=X509_STORE_new();
        +	if (ret->cert_store == NULL) goto err;
        +
        +	ssl_create_cipher_list(ret->method,
        +		&ret->cipher_list,&ret->cipher_list_by_id,
        +		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
        +	if (ret->cipher_list == NULL
        +	    || sk_SSL_CIPHER_num(ret->cipher_list) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_LIBRARY_HAS_NO_CIPHERS);
        +		goto err2;
        +		}
        +
        +	ret->param = X509_VERIFY_PARAM_new();
        +	if (!ret->param)
        +		goto err;
        +
        +	if ((ret->rsa_md5=EVP_get_digestbyname("ssl2-md5")) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES);
        +		goto err2;
        +		}
        +	if ((ret->md5=EVP_get_digestbyname("ssl3-md5")) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
        +		goto err2;
        +		}
        +	if ((ret->sha1=EVP_get_digestbyname("ssl3-sha1")) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
        +		goto err2;
        +		}
        +
        +	if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL)
        +		goto err;
        +
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
        +
        +	ret->extra_certs=NULL;
        +	ret->comp_methods=SSL_COMP_get_compression_methods();
        +
        +	ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	ret->tlsext_servername_callback = 0;
        +	ret->tlsext_servername_arg = NULL;
        +	/* Setup RFC4507 ticket keys */
        +	if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0)
        +		|| (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0)
        +		|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0))
        +		ret->options |= SSL_OP_NO_TICKET;
        +
        +	ret->tlsext_status_cb = 0;
        +	ret->tlsext_status_arg = NULL;
        +
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +	ret->next_protos_advertised_cb = 0;
        +	ret->next_proto_select_cb = 0;
        +# endif
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +	ret->psk_identity_hint=NULL;
        +	ret->psk_client_callback=NULL;
        +	ret->psk_server_callback=NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	SSL_CTX_SRP_CTX_init(ret);
        +#endif
        +#ifndef OPENSSL_NO_BUF_FREELISTS
        +	ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
        +	ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
        +	if (!ret->rbuf_freelist)
        +		goto err;
        +	ret->rbuf_freelist->chunklen = 0;
        +	ret->rbuf_freelist->len = 0;
        +	ret->rbuf_freelist->head = NULL;
        +	ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
        +	if (!ret->wbuf_freelist)
        +		{
        +		OPENSSL_free(ret->rbuf_freelist);
        +		goto err;
        +		}
        +	ret->wbuf_freelist->chunklen = 0;
        +	ret->wbuf_freelist->len = 0;
        +	ret->wbuf_freelist->head = NULL;
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +	ret->client_cert_engine = NULL;
        +#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
        +#define eng_strx(x)	#x
        +#define eng_str(x)	eng_strx(x)
        +	/* Use specific client engine automatically... ignore errors */
        +	{
        +	ENGINE *eng;
        +	eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
        +	if (!eng)
        +		{
        +		ERR_clear_error();
        +		ENGINE_load_builtin_engines();
        +		eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
        +		}
        +	if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng))
        +		ERR_clear_error();
        +	}
        +#endif
        +#endif
        +	/* Default is to connect to non-RI servers. When RI is more widely
        +	 * deployed might change this.
        +	 */
        +	ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
        +
        +	return(ret);
        +err:
        +	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
        +err2:
        +	if (ret != NULL) SSL_CTX_free(ret);
        +	return(NULL);
        +	}
        +
        +#if 0
        +static void SSL_COMP_free(SSL_COMP *comp)
        +    { OPENSSL_free(comp); }
        +#endif
        +
        +#ifndef OPENSSL_NO_BUF_FREELISTS
        +static void
        +ssl_buf_freelist_free(SSL3_BUF_FREELIST *list)
        +	{
        +	SSL3_BUF_FREELIST_ENTRY *ent, *next;
        +	for (ent = list->head; ent; ent = next)
        +		{
        +		next = ent->next;
        +		OPENSSL_free(ent);
        +		}
        +	OPENSSL_free(list);
        +	}
        +#endif
        +
        +void SSL_CTX_free(SSL_CTX *a)
        +	{
        +	int i;
        +
        +	if (a == NULL) return;
        +
        +	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_SSL_CTX);
        +#ifdef REF_PRINT
        +	REF_PRINT("SSL_CTX",a);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"SSL_CTX_free, bad reference count\n");
        +		abort(); /* ok */
        +		}
        +#endif
        +
        +	if (a->param)
        +		X509_VERIFY_PARAM_free(a->param);
        +
        +	/*
        +	 * Free internal session cache. However: the remove_cb() may reference
        +	 * the ex_data of SSL_CTX, thus the ex_data store can only be removed
        +	 * after the sessions were flushed.
        +	 * As the ex_data handling routines might also touch the session cache,
        +	 * the most secure solution seems to be: empty (flush) the cache, then
        +	 * free ex_data, then finally free the cache.
        +	 * (See ticket [openssl.org #212].)
        +	 */
        +	if (a->sessions != NULL)
        +		SSL_CTX_flush_sessions(a,0);
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
        +
        +	if (a->sessions != NULL)
        +		lh_SSL_SESSION_free(a->sessions);
        +
        +	if (a->cert_store != NULL)
        +		X509_STORE_free(a->cert_store);
        +	if (a->cipher_list != NULL)
        +		sk_SSL_CIPHER_free(a->cipher_list);
        +	if (a->cipher_list_by_id != NULL)
        +		sk_SSL_CIPHER_free(a->cipher_list_by_id);
        +	if (a->cert != NULL)
        +		ssl_cert_free(a->cert);
        +	if (a->client_CA != NULL)
        +		sk_X509_NAME_pop_free(a->client_CA,X509_NAME_free);
        +	if (a->extra_certs != NULL)
        +		sk_X509_pop_free(a->extra_certs,X509_free);
        +#if 0 /* This should never be done, since it removes a global database */
        +	if (a->comp_methods != NULL)
        +		sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free);
        +#else
        +	a->comp_methods = NULL;
        +#endif
        +
        +#ifndef OPENSSL_NO_SRTP
        +        if (a->srtp_profiles)
        +                sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +	if (a->psk_identity_hint)
        +		OPENSSL_free(a->psk_identity_hint);
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	SSL_CTX_SRP_CTX_free(a);
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +	if (a->client_cert_engine)
        +		ENGINE_finish(a->client_cert_engine);
        +#endif
        +
        +#ifndef OPENSSL_NO_BUF_FREELISTS
        +	if (a->wbuf_freelist)
        +		ssl_buf_freelist_free(a->wbuf_freelist);
        +	if (a->rbuf_freelist)
        +		ssl_buf_freelist_free(a->rbuf_freelist);
        +#endif
        +
        +	OPENSSL_free(a);
        +	}
        +
        +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
        +	{
        +	ctx->default_passwd_callback=cb;
        +	}
        +
        +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,void *u)
        +	{
        +	ctx->default_passwd_callback_userdata=u;
        +	}
        +
        +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg)
        +	{
        +	ctx->app_verify_callback=cb;
        +	ctx->app_verify_arg=arg;
        +	}
        +
        +void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*cb)(int, X509_STORE_CTX *))
        +	{
        +	ctx->verify_mode=mode;
        +	ctx->default_verify_callback=cb;
        +	}
        +
        +void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth)
        +	{
        +	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
        +	}
        +
        +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
        +	{
        +	CERT_PKEY *cpk;
        +	int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
        +	int rsa_enc_export,dh_rsa_export,dh_dsa_export;
        +	int rsa_tmp_export,dh_tmp_export,kl;
        +	unsigned long mask_k,mask_a,emask_k,emask_a;
        +	int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size;
        +#ifndef OPENSSL_NO_ECDH
        +	int have_ecdh_tmp;
        +#endif
        +	X509 *x = NULL;
        +	EVP_PKEY *ecc_pkey = NULL;
        +	int signature_nid = 0, pk_nid = 0, md_nid = 0;
        +
        +	if (c == NULL) return;
        +
        +	kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
        +
        +#ifndef OPENSSL_NO_RSA
        +	rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
        +	rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
        +		(rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
        +#else
        +	rsa_tmp=rsa_tmp_export=0;
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
        +	dh_tmp_export=(c->dh_tmp_cb != NULL ||
        +		(dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
        +#else
        +	dh_tmp=dh_tmp_export=0;
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL);
        +#endif
        +	cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]);
        +	rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL);
        +	rsa_enc_export=(rsa_enc && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
        +	cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]);
        +	rsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
        +	cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]);
        +	dsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
        +	cpk= &(c->pkeys[SSL_PKEY_DH_RSA]);
        +	dh_rsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);
        +	dh_rsa_export=(dh_rsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
        +	cpk= &(c->pkeys[SSL_PKEY_DH_DSA]);
        +/* FIX THIS EAY EAY EAY */
        +	dh_dsa=  (cpk->x509 != NULL && cpk->privatekey != NULL);
        +	dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
        +	cpk= &(c->pkeys[SSL_PKEY_ECC]);
        +	have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL);
        +	mask_k=0;
        +	mask_a=0;
        +	emask_k=0;
        +	emask_a=0;
        +
        +	
        +
        +#ifdef CIPHER_DEBUG
        +	printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
        +	        rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
        +		rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
        +#endif
        +	
        +	cpk = &(c->pkeys[SSL_PKEY_GOST01]);
        +	if (cpk->x509 != NULL && cpk->privatekey !=NULL) {
        +		mask_k |= SSL_kGOST;
        +		mask_a |= SSL_aGOST01;
        +	}
        +	cpk = &(c->pkeys[SSL_PKEY_GOST94]);
        +	if (cpk->x509 != NULL && cpk->privatekey !=NULL) {
        +		mask_k |= SSL_kGOST;
        +		mask_a |= SSL_aGOST94;
        +	}
        +
        +	if (rsa_enc || (rsa_tmp && rsa_sign))
        +		mask_k|=SSL_kRSA;
        +	if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
        +		emask_k|=SSL_kRSA;
        +
        +#if 0
        +	/* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
        +	if (	(dh_tmp || dh_rsa || dh_dsa) &&
        +		(rsa_enc || rsa_sign || dsa_sign))
        +		mask_k|=SSL_kEDH;
        +	if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
        +		(rsa_enc || rsa_sign || dsa_sign))
        +		emask_k|=SSL_kEDH;
        +#endif
        +
        +	if (dh_tmp_export)
        +		emask_k|=SSL_kEDH;
        +
        +	if (dh_tmp)
        +		mask_k|=SSL_kEDH;
        +
        +	if (dh_rsa) mask_k|=SSL_kDHr;
        +	if (dh_rsa_export) emask_k|=SSL_kDHr;
        +
        +	if (dh_dsa) mask_k|=SSL_kDHd;
        +	if (dh_dsa_export) emask_k|=SSL_kDHd;
        +
        +	if (rsa_enc || rsa_sign)
        +		{
        +		mask_a|=SSL_aRSA;
        +		emask_a|=SSL_aRSA;
        +		}
        +
        +	if (dsa_sign)
        +		{
        +		mask_a|=SSL_aDSS;
        +		emask_a|=SSL_aDSS;
        +		}
        +
        +	mask_a|=SSL_aNULL;
        +	emask_a|=SSL_aNULL;
        +
        +#ifndef OPENSSL_NO_KRB5
        +	mask_k|=SSL_kKRB5;
        +	mask_a|=SSL_aKRB5;
        +	emask_k|=SSL_kKRB5;
        +	emask_a|=SSL_aKRB5;
        +#endif
        +
        +	/* An ECC certificate may be usable for ECDH and/or
        +	 * ECDSA cipher suites depending on the key usage extension.
        +	 */
        +	if (have_ecc_cert)
        +		{
        +		/* This call populates extension flags (ex_flags) */
        +		x = (c->pkeys[SSL_PKEY_ECC]).x509;
        +		X509_check_purpose(x, -1, 0);
        +		ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
        +		    (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
        +		ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
        +		    (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
        +		ecc_pkey = X509_get_pubkey(x);
        +		ecc_pkey_size = (ecc_pkey != NULL) ?
        +		    EVP_PKEY_bits(ecc_pkey) : 0;
        +		EVP_PKEY_free(ecc_pkey);
        +		if ((x->sig_alg) && (x->sig_alg->algorithm))
        +			{
        +			signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
        +			OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
        +			}
        +#ifndef OPENSSL_NO_ECDH
        +		if (ecdh_ok)
        +			{
        +
        +			if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa)
        +				{
        +				mask_k|=SSL_kECDHr;
        +				mask_a|=SSL_aECDH;
        +				if (ecc_pkey_size <= 163)
        +					{
        +					emask_k|=SSL_kECDHr;
        +					emask_a|=SSL_aECDH;
        +					}
        +				}
        +
        +			if (pk_nid == NID_X9_62_id_ecPublicKey)
        +				{
        +				mask_k|=SSL_kECDHe;
        +				mask_a|=SSL_aECDH;
        +				if (ecc_pkey_size <= 163)
        +					{
        +					emask_k|=SSL_kECDHe;
        +					emask_a|=SSL_aECDH;
        +					}
        +				}
        +			}
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +		if (ecdsa_ok)
        +			{
        +			mask_a|=SSL_aECDSA;
        +			emask_a|=SSL_aECDSA;
        +			}
        +#endif
        +		}
        +
        +#ifndef OPENSSL_NO_ECDH
        +	if (have_ecdh_tmp)
        +		{
        +		mask_k|=SSL_kEECDH;
        +		emask_k|=SSL_kEECDH;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +	mask_k |= SSL_kPSK;
        +	mask_a |= SSL_aPSK;
        +	emask_k |= SSL_kPSK;
        +	emask_a |= SSL_aPSK;
        +#endif
        +
        +	c->mask_k=mask_k;
        +	c->mask_a=mask_a;
        +	c->export_mask_k=emask_k;
        +	c->export_mask_a=emask_a;
        +	c->valid=1;
        +	}
        +
        +/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
        +#define ku_reject(x, usage) \
        +	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
        +
        +#ifndef OPENSSL_NO_EC
        +
        +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
        +	{
        +	unsigned long alg_k, alg_a;
        +	EVP_PKEY *pkey = NULL;
        +	int keysize = 0;
        +	int signature_nid = 0, md_nid = 0, pk_nid = 0;
        +	const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
        +
        +	alg_k = cs->algorithm_mkey;
        +	alg_a = cs->algorithm_auth;
        +
        +	if (SSL_C_IS_EXPORT(cs))
        +		{
        +		/* ECDH key length in export ciphers must be <= 163 bits */
        +		pkey = X509_get_pubkey(x);
        +		if (pkey == NULL) return 0;
        +		keysize = EVP_PKEY_bits(pkey);
        +		EVP_PKEY_free(pkey);
        +		if (keysize > 163) return 0;
        +		}
        +
        +	/* This call populates the ex_flags field correctly */
        +	X509_check_purpose(x, -1, 0);
        +	if ((x->sig_alg) && (x->sig_alg->algorithm))
        +		{
        +		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
        +		OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
        +		}
        +	if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr)
        +		{
        +		/* key usage, if present, must allow key agreement */
        +		if (ku_reject(x, X509v3_KU_KEY_AGREEMENT))
        +			{
        +			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
        +			return 0;
        +			}
        +		if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION)
        +			{
        +			/* signature alg must be ECDSA */
        +			if (pk_nid != NID_X9_62_id_ecPublicKey)
        +				{
        +				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
        +				return 0;
        +				}
        +			}
        +		if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION)
        +			{
        +			/* signature alg must be RSA */
        +
        +			if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa)
        +				{
        +				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
        +				return 0;
        +				}
        +			}
        +		}
        +	if (alg_a & SSL_aECDSA)
        +		{
        +		/* key usage, if present, must allow signing */
        +		if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
        +			{
        +			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
        +			return 0;
        +			}
        +		}
        +
        +	return 1;  /* all checks are ok */
        +	}
        +
        +#endif
        +
        +/* THIS NEEDS CLEANING UP */
        +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
        +	{
        +	unsigned long alg_k,alg_a;
        +	CERT *c;
        +	int i;
        +
        +	c=s->cert;
        +	ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
        +	
        +	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
        +	alg_a = s->s3->tmp.new_cipher->algorithm_auth;
        +
        +	if (alg_k & (SSL_kECDHr|SSL_kECDHe))
        +		{
        +		/* we don't need to look at SSL_kEECDH
        +		 * since no certificate is needed for
        +		 * anon ECDH and for authenticated
        +		 * EECDH, the check for the auth
        +		 * algorithm will set i correctly
        +		 * NOTE: For ECDH-RSA, we need an ECC
        +		 * not an RSA cert but for EECDH-RSA
        +		 * we need an RSA cert. Placing the
        +		 * checks for SSL_kECDH before RSA
        +		 * checks ensures the correct cert is chosen.
        +		 */
        +		i=SSL_PKEY_ECC;
        +		}
        +	else if (alg_a & SSL_aECDSA)
        +		{
        +		i=SSL_PKEY_ECC;
        +		}
        +	else if (alg_k & SSL_kDHr)
        +		i=SSL_PKEY_DH_RSA;
        +	else if (alg_k & SSL_kDHd)
        +		i=SSL_PKEY_DH_DSA;
        +	else if (alg_a & SSL_aDSS)
        +		i=SSL_PKEY_DSA_SIGN;
        +	else if (alg_a & SSL_aRSA)
        +		{
        +		if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)
        +			i=SSL_PKEY_RSA_SIGN;
        +		else
        +			i=SSL_PKEY_RSA_ENC;
        +		}
        +	else if (alg_a & SSL_aKRB5)
        +		{
        +		/* VRS something else here? */
        +		return(NULL);
        +		}
        +	else if (alg_a & SSL_aGOST94) 
        +		i=SSL_PKEY_GOST94;
        +	else if (alg_a & SSL_aGOST01)
        +		i=SSL_PKEY_GOST01;
        +	else /* if (alg_a & SSL_aNULL) */
        +		{
        +		SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR);
        +		return(NULL);
        +		}
        +
        +	return c->pkeys + i;
        +	}
        +
        +X509 *ssl_get_server_send_cert(const SSL *s)
        +	{
        +	CERT_PKEY *cpk;
        +	cpk = ssl_get_server_send_pkey(s);
        +	if (!cpk)
        +		return NULL;
        +	return cpk->x509;
        +	}
        +
        +EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
        +	{
        +	unsigned long alg_a;
        +	CERT *c;
        +	int idx = -1;
        +
        +	alg_a = cipher->algorithm_auth;
        +	c=s->cert;
        +
        +	if ((alg_a & SSL_aDSS) &&
        +		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
        +		idx = SSL_PKEY_DSA_SIGN;
        +	else if (alg_a & SSL_aRSA)
        +		{
        +		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
        +			idx = SSL_PKEY_RSA_SIGN;
        +		else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
        +			idx = SSL_PKEY_RSA_ENC;
        +		}
        +	else if ((alg_a & SSL_aECDSA) &&
        +	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
        +		idx = SSL_PKEY_ECC;
        +	if (idx == -1)
        +		{
        +		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
        +		return(NULL);
        +		}
        +	if (pmd)
        +		*pmd = c->pkeys[idx].digest;
        +	return c->pkeys[idx].privatekey;
        +	}
        +
        +void ssl_update_cache(SSL *s,int mode)
        +	{
        +	int i;
        +
        +	/* If the session_id_length is 0, we are not supposed to cache it,
        +	 * and it would be rather hard to do anyway :-) */
        +	if (s->session->session_id_length == 0) return;
        +
        +	i=s->session_ctx->session_cache_mode;
        +	if ((i & mode) && (!s->hit)
        +		&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
        +		    || SSL_CTX_add_session(s->session_ctx,s->session))
        +		&& (s->session_ctx->new_session_cb != NULL))
        +		{
        +		CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
        +		if (!s->session_ctx->new_session_cb(s,s->session))
        +			SSL_SESSION_free(s->session);
        +		}
        +
        +	/* auto flush every 255 connections */
        +	if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) &&
        +		((i & mode) == mode))
        +		{
        +		if (  (((mode & SSL_SESS_CACHE_CLIENT)
        +			?s->session_ctx->stats.sess_connect_good
        +			:s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff)
        +			{
        +			SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL));
        +			}
        +		}
        +	}
        +
        +const SSL_METHOD *SSL_get_ssl_method(SSL *s)
        +	{
        +	return(s->method);
        +	}
        +
        +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
        +	{
        +	int conn= -1;
        +	int ret=1;
        +
        +	if (s->method != meth)
        +		{
        +		if (s->handshake_func != NULL)
        +			conn=(s->handshake_func == s->method->ssl_connect);
        +
        +		if (s->method->version == meth->version)
        +			s->method=meth;
        +		else
        +			{
        +			s->method->ssl_free(s);
        +			s->method=meth;
        +			ret=s->method->ssl_new(s);
        +			}
        +
        +		if (conn == 1)
        +			s->handshake_func=meth->ssl_connect;
        +		else if (conn == 0)
        +			s->handshake_func=meth->ssl_accept;
        +		}
        +	return(ret);
        +	}
        +
        +int SSL_get_error(const SSL *s,int i)
        +	{
        +	int reason;
        +	unsigned long l;
        +	BIO *bio;
        +
        +	if (i > 0) return(SSL_ERROR_NONE);
        +
        +	/* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake
        +	 * etc, where we do encode the error */
        +	if ((l=ERR_peek_error()) != 0)
        +		{
        +		if (ERR_GET_LIB(l) == ERR_LIB_SYS)
        +			return(SSL_ERROR_SYSCALL);
        +		else
        +			return(SSL_ERROR_SSL);
        +		}
        +
        +	if ((i < 0) && SSL_want_read(s))
        +		{
        +		bio=SSL_get_rbio(s);
        +		if (BIO_should_read(bio))
        +			return(SSL_ERROR_WANT_READ);
        +		else if (BIO_should_write(bio))
        +			/* This one doesn't make too much sense ... We never try
        +			 * to write to the rbio, and an application program where
        +			 * rbio and wbio are separate couldn't even know what it
        +			 * should wait for.
        +			 * However if we ever set s->rwstate incorrectly
        +			 * (so that we have SSL_want_read(s) instead of
        +			 * SSL_want_write(s)) and rbio and wbio *are* the same,
        +			 * this test works around that bug; so it might be safer
        +			 * to keep it. */
        +			return(SSL_ERROR_WANT_WRITE);
        +		else if (BIO_should_io_special(bio))
        +			{
        +			reason=BIO_get_retry_reason(bio);
        +			if (reason == BIO_RR_CONNECT)
        +				return(SSL_ERROR_WANT_CONNECT);
        +			else if (reason == BIO_RR_ACCEPT)
        +				return(SSL_ERROR_WANT_ACCEPT);
        +			else
        +				return(SSL_ERROR_SYSCALL); /* unknown */
        +			}
        +		}
        +
        +	if ((i < 0) && SSL_want_write(s))
        +		{
        +		bio=SSL_get_wbio(s);
        +		if (BIO_should_write(bio))
        +			return(SSL_ERROR_WANT_WRITE);
        +		else if (BIO_should_read(bio))
        +			/* See above (SSL_want_read(s) with BIO_should_write(bio)) */
        +			return(SSL_ERROR_WANT_READ);
        +		else if (BIO_should_io_special(bio))
        +			{
        +			reason=BIO_get_retry_reason(bio);
        +			if (reason == BIO_RR_CONNECT)
        +				return(SSL_ERROR_WANT_CONNECT);
        +			else if (reason == BIO_RR_ACCEPT)
        +				return(SSL_ERROR_WANT_ACCEPT);
        +			else
        +				return(SSL_ERROR_SYSCALL);
        +			}
        +		}
        +	if ((i < 0) && SSL_want_x509_lookup(s))
        +		{
        +		return(SSL_ERROR_WANT_X509_LOOKUP);
        +		}
        +
        +	if (i == 0)
        +		{
        +		if (s->version == SSL2_VERSION)
        +			{
        +			/* assume it is the socket being closed */
        +			return(SSL_ERROR_ZERO_RETURN);
        +			}
        +		else
        +			{
        +			if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
        +				(s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))
        +				return(SSL_ERROR_ZERO_RETURN);
        +			}
        +		}
        +	return(SSL_ERROR_SYSCALL);
        +	}
        +
        +int SSL_do_handshake(SSL *s)
        +	{
        +	int ret=1;
        +
        +	if (s->handshake_func == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_DO_HANDSHAKE,SSL_R_CONNECTION_TYPE_NOT_SET);
        +		return(-1);
        +		}
        +
        +	s->method->ssl_renegotiate_check(s);
        +
        +	if (SSL_in_init(s) || SSL_in_before(s))
        +		{
        +		ret=s->handshake_func(s);
        +		}
        +	return(ret);
        +	}
        +
        +/* For the next 2 functions, SSL_clear() sets shutdown and so
        + * one of these calls will reset it */
        +void SSL_set_accept_state(SSL *s)
        +	{
        +	s->server=1;
        +	s->shutdown=0;
        +	s->state=SSL_ST_ACCEPT|SSL_ST_BEFORE;
        +	s->handshake_func=s->method->ssl_accept;
        +	/* clear the current cipher */
        +	ssl_clear_cipher_ctx(s);
        +	ssl_clear_hash_ctx(&s->read_hash);
        +	ssl_clear_hash_ctx(&s->write_hash);
        +	}
        +
        +void SSL_set_connect_state(SSL *s)
        +	{
        +	s->server=0;
        +	s->shutdown=0;
        +	s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;
        +	s->handshake_func=s->method->ssl_connect;
        +	/* clear the current cipher */
        +	ssl_clear_cipher_ctx(s);
        +	ssl_clear_hash_ctx(&s->read_hash);
        +	ssl_clear_hash_ctx(&s->write_hash);
        +	}
        +
        +int ssl_undefined_function(SSL *s)
        +	{
        +	SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(0);
        +	}
        +
        +int ssl_undefined_void_function(void)
        +	{
        +	SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(0);
        +	}
        +
        +int ssl_undefined_const_function(const SSL *s)
        +	{
        +	SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(0);
        +	}
        +
        +SSL_METHOD *ssl_bad_method(int ver)
        +	{
        +	SSLerr(SSL_F_SSL_BAD_METHOD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        +	return(NULL);
        +	}
        +
        +const char *SSL_get_version(const SSL *s)
        +	{
        +	if (s->version == TLS1_2_VERSION)
        +		return("TLSv1.2");
        +	else if (s->version == TLS1_1_VERSION)
        +		return("TLSv1.1");
        +	else if (s->version == TLS1_VERSION)
        +		return("TLSv1");
        +	else if (s->version == SSL3_VERSION)
        +		return("SSLv3");
        +	else if (s->version == SSL2_VERSION)
        +		return("SSLv2");
        +	else
        +		return("unknown");
        +	}
        +
        +SSL *SSL_dup(SSL *s)
        +	{
        +	STACK_OF(X509_NAME) *sk;
        +	X509_NAME *xn;
        +	SSL *ret;
        +	int i;
        +	
        +	if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL)
        +	    return(NULL);
        +
        +	ret->version = s->version;
        +	ret->type = s->type;
        +	ret->method = s->method;
        +
        +	if (s->session != NULL)
        +		{
        +		/* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
        +		SSL_copy_session_id(ret,s);
        +		}
        +	else
        +		{
        +		/* No session has been established yet, so we have to expect
        +		 * that s->cert or ret->cert will be changed later --
        +		 * they should not both point to the same object,
        +		 * and thus we can't use SSL_copy_session_id. */
        +
        +		ret->method->ssl_free(ret);
        +		ret->method = s->method;
        +		ret->method->ssl_new(ret);
        +
        +		if (s->cert != NULL)
        +			{
        +			if (ret->cert != NULL)
        +				{
        +				ssl_cert_free(ret->cert);
        +				}
        +			ret->cert = ssl_cert_dup(s->cert);
        +			if (ret->cert == NULL)
        +				goto err;
        +			}
        +				
        +		SSL_set_session_id_context(ret,
        +			s->sid_ctx, s->sid_ctx_length);
        +		}
        +
        +	ret->options=s->options;
        +	ret->mode=s->mode;
        +	SSL_set_max_cert_list(ret,SSL_get_max_cert_list(s));
        +	SSL_set_read_ahead(ret,SSL_get_read_ahead(s));
        +	ret->msg_callback = s->msg_callback;
        +	ret->msg_callback_arg = s->msg_callback_arg;
        +	SSL_set_verify(ret,SSL_get_verify_mode(s),
        +		SSL_get_verify_callback(s));
        +	SSL_set_verify_depth(ret,SSL_get_verify_depth(s));
        +	ret->generate_session_id = s->generate_session_id;
        +
        +	SSL_set_info_callback(ret,SSL_get_info_callback(s));
        +	
        +	ret->debug=s->debug;
        +
        +	/* copy app data, a little dangerous perhaps */
        +	if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
        +		goto err;
        +
        +	/* setup rbio, and wbio */
        +	if (s->rbio != NULL)
        +		{
        +		if (!BIO_dup_state(s->rbio,(char *)&ret->rbio))
        +			goto err;
        +		}
        +	if (s->wbio != NULL)
        +		{
        +		if (s->wbio != s->rbio)
        +			{
        +			if (!BIO_dup_state(s->wbio,(char *)&ret->wbio))
        +				goto err;
        +			}
        +		else
        +			ret->wbio=ret->rbio;
        +		}
        +	ret->rwstate = s->rwstate;
        +	ret->in_handshake = s->in_handshake;
        +	ret->handshake_func = s->handshake_func;
        +	ret->server = s->server;
        +	ret->renegotiate = s->renegotiate;
        +	ret->new_session = s->new_session;
        +	ret->quiet_shutdown = s->quiet_shutdown;
        +	ret->shutdown=s->shutdown;
        +	ret->state=s->state; /* SSL_dup does not really work at any state, though */
        +	ret->rstate=s->rstate;
        +	ret->init_num = 0; /* would have to copy ret->init_buf, ret->init_msg, ret->init_num, ret->init_off */
        +	ret->hit=s->hit;
        +
        +	X509_VERIFY_PARAM_inherit(ret->param, s->param);
        +
        +	/* dup the cipher_list and cipher_list_by_id stacks */
        +	if (s->cipher_list != NULL)
        +		{
        +		if ((ret->cipher_list=sk_SSL_CIPHER_dup(s->cipher_list)) == NULL)
        +			goto err;
        +		}
        +	if (s->cipher_list_by_id != NULL)
        +		if ((ret->cipher_list_by_id=sk_SSL_CIPHER_dup(s->cipher_list_by_id))
        +			== NULL)
        +			goto err;
        +
        +	/* Dup the client_CA list */
        +	if (s->client_CA != NULL)
        +		{
        +		if ((sk=sk_X509_NAME_dup(s->client_CA)) == NULL) goto err;
        +		ret->client_CA=sk;
        +		for (i=0; i<sk_X509_NAME_num(sk); i++)
        +			{
        +			xn=sk_X509_NAME_value(sk,i);
        +			if (sk_X509_NAME_set(sk,i,X509_NAME_dup(xn)) == NULL)
        +				{
        +				X509_NAME_free(xn);
        +				goto err;
        +				}
        +			}
        +		}
        +
        +	if (0)
        +		{
        +err:
        +		if (ret != NULL) SSL_free(ret);
        +		ret=NULL;
        +		}
        +	return(ret);
        +	}
        +
        +void ssl_clear_cipher_ctx(SSL *s)
        +	{
        +	if (s->enc_read_ctx != NULL)
        +		{
        +		EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
        +		OPENSSL_free(s->enc_read_ctx);
        +		s->enc_read_ctx=NULL;
        +		}
        +	if (s->enc_write_ctx != NULL)
        +		{
        +		EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
        +		OPENSSL_free(s->enc_write_ctx);
        +		s->enc_write_ctx=NULL;
        +		}
        +#ifndef OPENSSL_NO_COMP
        +	if (s->expand != NULL)
        +		{
        +		COMP_CTX_free(s->expand);
        +		s->expand=NULL;
        +		}
        +	if (s->compress != NULL)
        +		{
        +		COMP_CTX_free(s->compress);
        +		s->compress=NULL;
        +		}
        +#endif
        +	}
        +
        +/* Fix this function so that it takes an optional type parameter */
        +X509 *SSL_get_certificate(const SSL *s)
        +	{
        +	if (s->server)
        +		return(ssl_get_server_send_cert(s));
        +	else if (s->cert != NULL)
        +		return(s->cert->key->x509);
        +	else
        +		return(NULL);
        +	}
        +
        +/* Fix this function so that it takes an optional type parameter */
        +EVP_PKEY *SSL_get_privatekey(SSL *s)
        +	{
        +	if (s->cert != NULL)
        +		return(s->cert->key->privatekey);
        +	else
        +		return(NULL);
        +	}
        +
        +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
        +	{
        +	if ((s->session != NULL) && (s->session->cipher != NULL))
        +		return(s->session->cipher);
        +	return(NULL);
        +	}
        +#ifdef OPENSSL_NO_COMP
        +const void *SSL_get_current_compression(SSL *s)
        +	{
        +	return NULL;
        +	}
        +const void *SSL_get_current_expansion(SSL *s)
        +	{
        +	return NULL;
        +	}
        +#else
        +
        +const COMP_METHOD *SSL_get_current_compression(SSL *s)
        +	{
        +	if (s->compress != NULL)
        +		return(s->compress->meth);
        +	return(NULL);
        +	}
        +
        +const COMP_METHOD *SSL_get_current_expansion(SSL *s)
        +	{
        +	if (s->expand != NULL)
        +		return(s->expand->meth);
        +	return(NULL);
        +	}
        +#endif
        +
        +int ssl_init_wbio_buffer(SSL *s,int push)
        +	{
        +	BIO *bbio;
        +
        +	if (s->bbio == NULL)
        +		{
        +		bbio=BIO_new(BIO_f_buffer());
        +		if (bbio == NULL) return(0);
        +		s->bbio=bbio;
        +		}
        +	else
        +		{
        +		bbio=s->bbio;
        +		if (s->bbio == s->wbio)
        +			s->wbio=BIO_pop(s->wbio);
        +		}
        +	(void)BIO_reset(bbio);
        +/*	if (!BIO_set_write_buffer_size(bbio,16*1024)) */
        +	if (!BIO_set_read_buffer_size(bbio,1))
        +		{
        +		SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	if (push)
        +		{
        +		if (s->wbio != bbio)
        +			s->wbio=BIO_push(bbio,s->wbio);
        +		}
        +	else
        +		{
        +		if (s->wbio == bbio)
        +			s->wbio=BIO_pop(bbio);
        +		}
        +	return(1);
        +	}
        +
        +void ssl_free_wbio_buffer(SSL *s)
        +	{
        +	if (s->bbio == NULL) return;
        +
        +	if (s->bbio == s->wbio)
        +		{
        +		/* remove buffering */
        +		s->wbio=BIO_pop(s->wbio);
        +#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */
        +		assert(s->wbio != NULL);
        +#endif
        +	}
        +	BIO_free(s->bbio);
        +	s->bbio=NULL;
        +	}
        +	
        +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode)
        +	{
        +	ctx->quiet_shutdown=mode;
        +	}
        +
        +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx)
        +	{
        +	return(ctx->quiet_shutdown);
        +	}
        +
        +void SSL_set_quiet_shutdown(SSL *s,int mode)
        +	{
        +	s->quiet_shutdown=mode;
        +	}
        +
        +int SSL_get_quiet_shutdown(const SSL *s)
        +	{
        +	return(s->quiet_shutdown);
        +	}
        +
        +void SSL_set_shutdown(SSL *s,int mode)
        +	{
        +	s->shutdown=mode;
        +	}
        +
        +int SSL_get_shutdown(const SSL *s)
        +	{
        +	return(s->shutdown);
        +	}
        +
        +int SSL_version(const SSL *s)
        +	{
        +	return(s->version);
        +	}
        +
        +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
        +	{
        +	return(ssl->ctx);
        +	}
        +
        +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
        +	{
        +	if (ssl->ctx == ctx)
        +		return ssl->ctx;
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (ctx == NULL)
        +		ctx = ssl->initial_ctx;
        +#endif
        +	if (ssl->cert != NULL)
        +		ssl_cert_free(ssl->cert);
        +	ssl->cert = ssl_cert_dup(ctx->cert);
        +	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
        +	if (ssl->ctx != NULL)
        +		SSL_CTX_free(ssl->ctx); /* decrement reference count */
        +	ssl->ctx = ctx;
        +	return(ssl->ctx);
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
        +	{
        +	return(X509_STORE_set_default_paths(ctx->cert_store));
        +	}
        +
        +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
        +		const char *CApath)
        +	{
        +	return(X509_STORE_load_locations(ctx->cert_store,CAfile,CApath));
        +	}
        +#endif
        +
        +void SSL_set_info_callback(SSL *ssl,
        +	void (*cb)(const SSL *ssl,int type,int val))
        +	{
        +	ssl->info_callback=cb;
        +	}
        +
        +/* One compiler (Diab DCC) doesn't like argument names in returned
        +   function pointer.  */
        +void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/)
        +	{
        +	return ssl->info_callback;
        +	}
        +
        +int SSL_state(const SSL *ssl)
        +	{
        +	return(ssl->state);
        +	}
        +
        +void SSL_set_state(SSL *ssl, int state)
        +	{
        +	ssl->state = state;
        +	}
        +
        +void SSL_set_verify_result(SSL *ssl,long arg)
        +	{
        +	ssl->verify_result=arg;
        +	}
        +
        +long SSL_get_verify_result(const SSL *ssl)
        +	{
        +	return(ssl->verify_result);
        +	}
        +
        +int SSL_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
        +			 CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
        +	{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp,
        +				new_func, dup_func, free_func);
        +	}
        +
        +int SSL_set_ex_data(SSL *s,int idx,void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
        +	}
        +
        +void *SSL_get_ex_data(const SSL *s,int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&s->ex_data,idx));
        +	}
        +
        +int SSL_CTX_get_ex_new_index(long argl,void *argp,CRYPTO_EX_new *new_func,
        +			     CRYPTO_EX_dup *dup_func,CRYPTO_EX_free *free_func)
        +	{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp,
        +				new_func, dup_func, free_func);
        +	}
        +
        +int SSL_CTX_set_ex_data(SSL_CTX *s,int idx,void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
        +	}
        +
        +void *SSL_CTX_get_ex_data(const SSL_CTX *s,int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&s->ex_data,idx));
        +	}
        +
        +int ssl_ok(SSL *s)
        +	{
        +	return(1);
        +	}
        +
        +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
        +	{
        +	return(ctx->cert_store);
        +	}
        +
        +void SSL_CTX_set_cert_store(SSL_CTX *ctx,X509_STORE *store)
        +	{
        +	if (ctx->cert_store != NULL)
        +		X509_STORE_free(ctx->cert_store);
        +	ctx->cert_store=store;
        +	}
        +
        +int SSL_want(const SSL *s)
        +	{
        +	return(s->rwstate);
        +	}
        +
        +/*!
        + * \brief Set the callback for generating temporary RSA keys.
        + * \param ctx the SSL context.
        + * \param cb the callback
        + */
        +
        +#ifndef OPENSSL_NO_RSA
        +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
        +							  int is_export,
        +							  int keylength))
        +    {
        +    SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb);
        +    }
        +
        +void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,
        +						  int is_export,
        +						  int keylength))
        +    {
        +    SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb);
        +    }
        +#endif
        +
        +#ifdef DOXYGEN
        +/*!
        + * \brief The RSA temporary key callback function.
        + * \param ssl the SSL session.
        + * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite.
        + * \param keylength if \c is_export is \c TRUE, then \c keylength is the size
        + * of the required key in bits.
        + * \return the temporary RSA key.
        + * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback
        + */
        +
        +RSA *cb(SSL *ssl,int is_export,int keylength)
        +    {}
        +#endif
        +
        +/*!
        + * \brief Set the callback for generating temporary DH keys.
        + * \param ctx the SSL context.
        + * \param dh the callback
        + */
        +
        +#ifndef OPENSSL_NO_DH
        +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
        +                                                        int keylength))
        +	{
        +	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
        +	}
        +
        +void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
        +                                                int keylength))
        +	{
        +	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
        +                                                                int keylength))
        +	{
        +	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
        +	}
        +
        +void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
        +                                                        int keylength))
        +	{
        +	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
        +	{
        +	if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
        +		return 0;
        +		}
        +	if (ctx->psk_identity_hint != NULL)
        +		OPENSSL_free(ctx->psk_identity_hint);
        +	if (identity_hint != NULL)
        +		{
        +		ctx->psk_identity_hint = BUF_strdup(identity_hint);
        +		if (ctx->psk_identity_hint == NULL)
        +			return 0;
        +		}
        +	else
        +		ctx->psk_identity_hint = NULL;
        +	return 1;
        +	}
        +
        +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
        +	{
        +	if (s == NULL)
        +		return 0;
        +
        +	if (s->session == NULL)
        +		return 1; /* session not created yet, ignored */
        +
        +	if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN)
        +		{
        +		SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
        +		return 0;
        +		}
        +	if (s->session->psk_identity_hint != NULL)
        +		OPENSSL_free(s->session->psk_identity_hint);
        +	if (identity_hint != NULL)
        +		{
        +		s->session->psk_identity_hint = BUF_strdup(identity_hint);
        +		if (s->session->psk_identity_hint == NULL)
        +			return 0;
        +		}
        +	else
        +		s->session->psk_identity_hint = NULL;
        +	return 1;
        +	}
        +
        +const char *SSL_get_psk_identity_hint(const SSL *s)
        +	{
        +	if (s == NULL || s->session == NULL)
        +		return NULL;
        +	return(s->session->psk_identity_hint);
        +	}
        +
        +const char *SSL_get_psk_identity(const SSL *s)
        +	{
        +	if (s == NULL || s->session == NULL)
        +		return NULL;
        +	return(s->session->psk_identity);
        +	}
        +
        +void SSL_set_psk_client_callback(SSL *s,
        +    unsigned int (*cb)(SSL *ssl, const char *hint,
        +                       char *identity, unsigned int max_identity_len, unsigned char *psk,
        +                       unsigned int max_psk_len))
        +	{
        +	s->psk_client_callback = cb;
        +	}
        +
        +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
        +    unsigned int (*cb)(SSL *ssl, const char *hint,
        +                       char *identity, unsigned int max_identity_len, unsigned char *psk,
        +                       unsigned int max_psk_len))
        +	{
        +	ctx->psk_client_callback = cb;
        +	}
        +
        +void SSL_set_psk_server_callback(SSL *s,
        +    unsigned int (*cb)(SSL *ssl, const char *identity,
        +                       unsigned char *psk, unsigned int max_psk_len))
        +	{
        +	s->psk_server_callback = cb;
        +	}
        +
        +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
        +    unsigned int (*cb)(SSL *ssl, const char *identity,
        +                       unsigned char *psk, unsigned int max_psk_len))
        +	{
        +	ctx->psk_server_callback = cb;
        +	}
        +#endif
        +
        +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
        +	{
        +	SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
        +	}
        +void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
        +	{
        +	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
        +	}
        +
        +/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
        + * vairable, freeing  EVP_MD_CTX previously stored in that variable, if
        + * any. If EVP_MD pointer is passed, initializes ctx with this md
        + * Returns newly allocated ctx;
        + */
        +
        +EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) 
        +{
        +	ssl_clear_hash_ctx(hash);
        +	*hash = EVP_MD_CTX_create();
        +	if (md) EVP_DigestInit_ex(*hash,md,NULL);
        +	return *hash;
        +}
        +void ssl_clear_hash_ctx(EVP_MD_CTX **hash) 
        +{
        +
        +	if (*hash) EVP_MD_CTX_destroy(*hash);
        +	*hash=NULL;
        +}
        +
        +void SSL_set_debug(SSL *s, int debug)
        +	{
        +	s->debug = debug;
        +	}
        +
        +int SSL_cache_hit(SSL *s)
        +	{
        +	return s->hit;
        +	}
        +
        +#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
        +#include "../crypto/bio/bss_file.c"
        +#endif
        +
        +IMPLEMENT_STACK_OF(SSL_CIPHER)
        +IMPLEMENT_STACK_OF(SSL_COMP)
        +IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
        +				    ssl_cipher_id);
        diff --git a/vendor/openssl/openssl/ssl/ssl_locl.h b/vendor/openssl/openssl/ssl/ssl_locl.h
        new file mode 100644
        index 000000000..1b98947e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_locl.h
        @@ -0,0 +1,1174 @@
        +/* ssl/ssl_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.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#ifndef HEADER_SSL_LOCL_H
        +#define HEADER_SSL_LOCL_H
        +#include <stdlib.h>
        +#include <time.h>
        +#include <string.h>
        +#include <errno.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/buffer.h>
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#include <openssl/bio.h>
        +#include <openssl/stack.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/ssl.h>
        +#include <openssl/symhacks.h>
        +
        +#ifdef OPENSSL_BUILD_SHLIBSSL
        +# undef OPENSSL_EXTERN
        +# define OPENSSL_EXTERN OPENSSL_EXPORT
        +#endif
        +
        +#undef PKCS1_CHECK
        +
        +#define c2l(c,l)	(l = ((unsigned long)(*((c)++)))     , \
        +			 l|=(((unsigned long)(*((c)++)))<< 8), \
        +			 l|=(((unsigned long)(*((c)++)))<<16), \
        +			 l|=(((unsigned long)(*((c)++)))<<24))
        +
        +/* NOTE - c is not incremented as per c2l */
        +#define c2ln(c,l1,l2,n)	{ \
        +			c+=n; \
        +			l1=l2=0; \
        +			switch (n) { \
        +			case 8: l2 =((unsigned long)(*(--(c))))<<24; \
        +			case 7: l2|=((unsigned long)(*(--(c))))<<16; \
        +			case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
        +			case 5: l2|=((unsigned long)(*(--(c))));     \
        +			case 4: l1 =((unsigned long)(*(--(c))))<<24; \
        +			case 3: l1|=((unsigned long)(*(--(c))))<<16; \
        +			case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
        +			case 1: l1|=((unsigned long)(*(--(c))));     \
        +				} \
        +			}
        +
        +#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
        +
        +#define n2l(c,l)	(l =((unsigned long)(*((c)++)))<<24, \
        +			 l|=((unsigned long)(*((c)++)))<<16, \
        +			 l|=((unsigned long)(*((c)++)))<< 8, \
        +			 l|=((unsigned long)(*((c)++))))
        +
        +#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)    )&0xff))
        +
        +#define l2n6(l,c)	(*((c)++)=(unsigned char)(((l)>>40)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>32)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)    )&0xff))
        +
        +#define l2n8(l,c)	(*((c)++)=(unsigned char)(((l)>>56)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>48)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>40)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>32)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>24)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
        +			 *((c)++)=(unsigned char)(((l)    )&0xff))
        +
        +#define n2l6(c,l)	(l =((BN_ULLONG)(*((c)++)))<<40, \
        +			 l|=((BN_ULLONG)(*((c)++)))<<32, \
        +			 l|=((BN_ULLONG)(*((c)++)))<<24, \
        +			 l|=((BN_ULLONG)(*((c)++)))<<16, \
        +			 l|=((BN_ULLONG)(*((c)++)))<< 8, \
        +			 l|=((BN_ULLONG)(*((c)++))))
        +
        +/* NOTE - c is not incremented as per l2c */
        +#define l2cn(l1,l2,c,n)	{ \
        +			c+=n; \
        +			switch (n) { \
        +			case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
        +			case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
        +			case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
        +			case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
        +			case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
        +			case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
        +			case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
        +			case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
        +				} \
        +			}
        +
        +#define n2s(c,s)	((s=(((unsigned int)(c[0]))<< 8)| \
        +			    (((unsigned int)(c[1]))    )),c+=2)
        +#define s2n(s,c)	((c[0]=(unsigned char)(((s)>> 8)&0xff), \
        +			  c[1]=(unsigned char)(((s)    )&0xff)),c+=2)
        +
        +#define n2l3(c,l)	((l =(((unsigned long)(c[0]))<<16)| \
        +			     (((unsigned long)(c[1]))<< 8)| \
        +			     (((unsigned long)(c[2]))    )),c+=3)
        +
        +#define l2n3(l,c)	((c[0]=(unsigned char)(((l)>>16)&0xff), \
        +			  c[1]=(unsigned char)(((l)>> 8)&0xff), \
        +			  c[2]=(unsigned char)(((l)    )&0xff)),c+=3)
        +
        +/* LOCAL STUFF */
        +
        +#define SSL_DECRYPT	0
        +#define SSL_ENCRYPT	1
        +
        +#define TWO_BYTE_BIT	0x80
        +#define SEC_ESC_BIT	0x40
        +#define TWO_BYTE_MASK	0x7fff
        +#define THREE_BYTE_MASK	0x3fff
        +
        +#define INC32(a)	((a)=((a)+1)&0xffffffffL)
        +#define DEC32(a)	((a)=((a)-1)&0xffffffffL)
        +#define MAX_MAC_SIZE	20 /* up from 16 for SSLv3 */
        +
        +/*
        + * Define the Bitmasks for SSL_CIPHER.algorithms.
        + * This bits are used packed as dense as possible. If new methods/ciphers
        + * etc will be added, the bits a likely to change, so this information
        + * is for internal library use only, even though SSL_CIPHER.algorithms
        + * can be publicly accessed.
        + * Use the according functions for cipher management instead.
        + *
        + * The bit mask handling in the selection and sorting scheme in
        + * ssl_create_cipher_list() has only limited capabilities, reflecting
        + * that the different entities within are mutually exclusive:
        + * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
        + */
        +
        +/* Bits for algorithm_mkey (key exchange algorithm) */
        +#define SSL_kRSA		0x00000001L /* RSA key exchange */
        +#define SSL_kDHr		0x00000002L /* DH cert, RSA CA cert */ /* no such ciphersuites supported! */
        +#define SSL_kDHd		0x00000004L /* DH cert, DSA CA cert */ /* no such ciphersuite supported! */
        +#define SSL_kEDH		0x00000008L /* tmp DH key no DH cert */
        +#define SSL_kKRB5		0x00000010L /* Kerberos5 key exchange */
        +#define SSL_kECDHr		0x00000020L /* ECDH cert, RSA CA cert */
        +#define SSL_kECDHe		0x00000040L /* ECDH cert, ECDSA CA cert */
        +#define SSL_kEECDH		0x00000080L /* ephemeral ECDH */
        +#define SSL_kPSK		0x00000100L /* PSK */
        +#define SSL_kGOST       0x00000200L /* GOST key exchange */
        +#define SSL_kSRP        0x00000400L /* SRP */
        +
        +/* Bits for algorithm_auth (server authentication) */
        +#define SSL_aRSA		0x00000001L /* RSA auth */
        +#define SSL_aDSS 		0x00000002L /* DSS auth */
        +#define SSL_aNULL 		0x00000004L /* no auth (i.e. use ADH or AECDH) */
        +#define SSL_aDH 		0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no such ciphersuites supported! */
        +#define SSL_aECDH 		0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */
        +#define SSL_aKRB5               0x00000020L /* KRB5 auth */
        +#define SSL_aECDSA              0x00000040L /* ECDSA auth*/
        +#define SSL_aPSK                0x00000080L /* PSK auth */
        +#define SSL_aGOST94				0x00000100L /* GOST R 34.10-94 signature auth */
        +#define SSL_aGOST01 			0x00000200L /* GOST R 34.10-2001 signature auth */
        +
        +
        +/* Bits for algorithm_enc (symmetric encryption) */
        +#define SSL_DES			0x00000001L
        +#define SSL_3DES		0x00000002L
        +#define SSL_RC4			0x00000004L
        +#define SSL_RC2			0x00000008L
        +#define SSL_IDEA		0x00000010L
        +#define SSL_eNULL		0x00000020L
        +#define SSL_AES128		0x00000040L
        +#define SSL_AES256		0x00000080L
        +#define SSL_CAMELLIA128		0x00000100L
        +#define SSL_CAMELLIA256		0x00000200L
        +#define SSL_eGOST2814789CNT	0x00000400L
        +#define SSL_SEED		0x00000800L
        +#define SSL_AES128GCM		0x00001000L
        +#define SSL_AES256GCM		0x00002000L
        +
        +#define SSL_AES        		(SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
        +#define SSL_CAMELLIA		(SSL_CAMELLIA128|SSL_CAMELLIA256)
        +
        +
        +/* Bits for algorithm_mac (symmetric authentication) */
        +
        +#define SSL_MD5			0x00000001L
        +#define SSL_SHA1		0x00000002L
        +#define SSL_GOST94      0x00000004L
        +#define SSL_GOST89MAC   0x00000008L
        +#define SSL_SHA256		0x00000010L
        +#define SSL_SHA384		0x00000020L
        +/* Not a real MAC, just an indication it is part of cipher */
        +#define SSL_AEAD		0x00000040L
        +
        +/* Bits for algorithm_ssl (protocol version) */
        +#define SSL_SSLV2		0x00000001L
        +#define SSL_SSLV3		0x00000002L
        +#define SSL_TLSV1		SSL_SSLV3	/* for now */
        +#define SSL_TLSV1_2		0x00000004L
        +
        +
        +/* Bits for algorithm2 (handshake digests and other extra flags) */
        +
        +#define SSL_HANDSHAKE_MAC_MD5 0x10
        +#define SSL_HANDSHAKE_MAC_SHA 0x20
        +#define SSL_HANDSHAKE_MAC_GOST94 0x40
        +#define SSL_HANDSHAKE_MAC_SHA256 0x80
        +#define SSL_HANDSHAKE_MAC_SHA384 0x100
        +#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
        +
        +/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
        + * make sure to update this constant too */
        +#define SSL_MAX_DIGEST 6
        +
        +#define TLS1_PRF_DGST_MASK	(0xff << TLS1_PRF_DGST_SHIFT)
        +
        +#define TLS1_PRF_DGST_SHIFT 10
        +#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
        +#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
        +#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
        +#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
        +#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT)
        +#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
        +
        +/* Stream MAC for GOST ciphersuites from cryptopro draft
        + * (currently this also goes into algorithm2) */
        +#define TLS1_STREAM_MAC 0x04
        +
        +
        +
        +/*
        + * Export and cipher strength information. For each cipher we have to decide
        + * whether it is exportable or not. This information is likely to change
        + * over time, since the export control rules are no static technical issue.
        + *
        + * Independent of the export flag the cipher strength is sorted into classes.
        + * SSL_EXP40 was denoting the 40bit US export limit of past times, which now
        + * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change
        + * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more,
        + * since SSL_EXP64 could be similar to SSL_LOW.
        + * For this reason SSL_MICRO and SSL_MINI macros are included to widen the
        + * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed
        + * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would
        + * be possible.
        + */
        +#define SSL_EXP_MASK		0x00000003L
        +#define SSL_STRONG_MASK		0x000001fcL
        +
        +#define SSL_NOT_EXP		0x00000001L
        +#define SSL_EXPORT		0x00000002L
        +
        +#define SSL_STRONG_NONE		0x00000004L
        +#define SSL_EXP40		0x00000008L
        +#define SSL_MICRO		(SSL_EXP40)
        +#define SSL_EXP56		0x00000010L
        +#define SSL_MINI		(SSL_EXP56)
        +#define SSL_LOW			0x00000020L
        +#define SSL_MEDIUM		0x00000040L
        +#define SSL_HIGH		0x00000080L
        +#define SSL_FIPS		0x00000100L
        +
        +/* we have used 000001ff - 23 bits left to go */
        +
        +/*
        + * Macros to check the export status and cipher strength for export ciphers.
        + * Even though the macros for EXPORT and EXPORT40/56 have similar names,
        + * their meaning is different:
        + * *_EXPORT macros check the 'exportable' status.
        + * *_EXPORT40/56 macros are used to check whether a certain cipher strength
        + *          is given.
        + * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct
        + * algorithm structure element to be passed (algorithms, algo_strength) and no
        + * typechecking can be done as they are all of type unsigned long, their
        + * direct usage is discouraged.
        + * Use the SSL_C_* macros instead.
        + */
        +#define SSL_IS_EXPORT(a)	((a)&SSL_EXPORT)
        +#define SSL_IS_EXPORT56(a)	((a)&SSL_EXP56)
        +#define SSL_IS_EXPORT40(a)	((a)&SSL_EXP40)
        +#define SSL_C_IS_EXPORT(c)	SSL_IS_EXPORT((c)->algo_strength)
        +#define SSL_C_IS_EXPORT56(c)	SSL_IS_EXPORT56((c)->algo_strength)
        +#define SSL_C_IS_EXPORT40(c)	SSL_IS_EXPORT40((c)->algo_strength)
        +
        +#define SSL_EXPORT_KEYLENGTH(a,s)	(SSL_IS_EXPORT40(s) ? 5 : \
        +				 (a) == SSL_DES ? 8 : 7)
        +#define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024)
        +#define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \
        +				(c)->algo_strength)
        +#define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algo_strength)
        +
        +
        +
        +
        +/* Mostly for SSLv3 */
        +#define SSL_PKEY_RSA_ENC	0
        +#define SSL_PKEY_RSA_SIGN	1
        +#define SSL_PKEY_DSA_SIGN	2
        +#define SSL_PKEY_DH_RSA		3
        +#define SSL_PKEY_DH_DSA		4
        +#define SSL_PKEY_ECC            5
        +#define SSL_PKEY_GOST94		6
        +#define SSL_PKEY_GOST01		7
        +#define SSL_PKEY_NUM		8
        +
        +/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) |
        + * 	    <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN)
        + * SSL_kDH  <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
        + * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN
        + * SSL_aRSA <- RSA_ENC | RSA_SIGN
        + * SSL_aDSS <- DSA_SIGN
        + */
        +
        +/*
        +#define CERT_INVALID		0
        +#define CERT_PUBLIC_KEY		1
        +#define CERT_PRIVATE_KEY	2
        +*/
        +
        +#ifndef OPENSSL_NO_EC
        +/* From ECC-TLS draft, used in encoding the curve type in 
        + * ECParameters
        + */
        +#define EXPLICIT_PRIME_CURVE_TYPE  1   
        +#define EXPLICIT_CHAR2_CURVE_TYPE  2
        +#define NAMED_CURVE_TYPE           3
        +#endif  /* OPENSSL_NO_EC */
        +
        +typedef struct cert_pkey_st
        +	{
        +	X509 *x509;
        +	EVP_PKEY *privatekey;
        +	/* Digest to use when signing */
        +	const EVP_MD *digest;
        +	} CERT_PKEY;
        +
        +typedef struct cert_st
        +	{
        +	/* Current active set */
        +	CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array
        +			 * Probably it would make more sense to store
        +			 * an index, not a pointer. */
        + 
        +	/* The following masks are for the key and auth
        +	 * algorithms that are supported by the certs below */
        +	int valid;
        +	unsigned long mask_k;
        +	unsigned long mask_a;
        +	unsigned long export_mask_k;
        +	unsigned long export_mask_a;
        +#ifndef OPENSSL_NO_RSA
        +	RSA *rsa_tmp;
        +	RSA *(*rsa_tmp_cb)(SSL *ssl,int is_export,int keysize);
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	DH *dh_tmp;
        +	DH *(*dh_tmp_cb)(SSL *ssl,int is_export,int keysize);
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh_tmp;
        +	/* Callback for generating ephemeral ECDH keys */
        +	EC_KEY *(*ecdh_tmp_cb)(SSL *ssl,int is_export,int keysize);
        +#endif
        +
        +	CERT_PKEY pkeys[SSL_PKEY_NUM];
        +
        +	int references; /* >1 only if SSL_copy_session_id is used */
        +	} CERT;
        +
        +
        +typedef struct sess_cert_st
        +	{
        +	STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */
        +
        +	/* The 'peer_...' members are used only by clients. */
        +	int peer_cert_type;
        +
        +	CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never NULL!) */
        +	CERT_PKEY peer_pkeys[SSL_PKEY_NUM];
        +	/* Obviously we don't have the private keys of these,
        +	 * so maybe we shouldn't even use the CERT_PKEY type here. */
        +
        +#ifndef OPENSSL_NO_RSA
        +	RSA *peer_rsa_tmp; /* not used for SSL 2 */
        +#endif
        +#ifndef OPENSSL_NO_DH
        +	DH *peer_dh_tmp; /* not used for SSL 2 */
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *peer_ecdh_tmp;
        +#endif
        +
        +	int references; /* actually always 1 at the moment */
        +	} SESS_CERT;
        +
        +
        +/*#define MAC_DEBUG	*/
        +
        +/*#define ERR_DEBUG	*/
        +/*#define ABORT_DEBUG	*/
        +/*#define PKT_DEBUG 1   */
        +/*#define DES_DEBUG	*/
        +/*#define DES_OFB_DEBUG	*/
        +/*#define SSL_DEBUG	*/
        +/*#define RSA_DEBUG	*/ 
        +/*#define IDEA_DEBUG	*/ 
        +
        +#define FP_ICC  (int (*)(const void *,const void *))
        +#define ssl_put_cipher_by_char(ssl,ciph,ptr) \
        +		((ssl)->method->put_cipher_by_char((ciph),(ptr)))
        +#define ssl_get_cipher_by_char(ssl,ptr) \
        +		((ssl)->method->get_cipher_by_char(ptr))
        +
        +/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff
        + * It is a bit of a mess of functions, but hell, think of it as
        + * an opaque structure :-) */
        +typedef struct ssl3_enc_method
        +	{
        +	int (*enc)(SSL *, int);
        +	int (*mac)(SSL *, unsigned char *, int);
        +	int (*setup_key_block)(SSL *);
        +	int (*generate_master_secret)(SSL *, unsigned char *, unsigned char *, int);
        +	int (*change_cipher_state)(SSL *, int);
        +	int (*final_finish_mac)(SSL *,  const char *, int, unsigned char *);
        +	int finish_mac_length;
        +	int (*cert_verify_mac)(SSL *, int, unsigned char *);
        +	const char *client_finished_label;
        +	int client_finished_label_len;
        +	const char *server_finished_label;
        +	int server_finished_label_len;
        +	int (*alert_value)(int);
        +	int (*export_keying_material)(SSL *, unsigned char *, size_t,
        +				      const char *, size_t,
        +				      const unsigned char *, size_t,
        +				      int use_context);
        +	} SSL3_ENC_METHOD;
        +
        +#ifndef OPENSSL_NO_COMP
        +/* Used for holding the relevant compression methods loaded into SSL_CTX */
        +typedef struct ssl3_comp_st
        +	{
        +	int comp_id;	/* The identifier byte for this compression type */
        +	char *name;	/* Text name used for the compression type */
        +	COMP_METHOD *method; /* The method :-) */
        +	} SSL3_COMP;
        +#endif
        +
        +#ifndef OPENSSL_NO_BUF_FREELISTS
        +typedef struct ssl3_buf_freelist_st
        +	{
        +	size_t chunklen;
        +	unsigned int len;
        +	struct ssl3_buf_freelist_entry_st *head;
        +	} SSL3_BUF_FREELIST;
        +
        +typedef struct ssl3_buf_freelist_entry_st
        +	{
        +	struct ssl3_buf_freelist_entry_st *next;
        +	} SSL3_BUF_FREELIST_ENTRY;
        +#endif
        +
        +extern SSL3_ENC_METHOD ssl3_undef_enc_method;
        +OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[];
        +OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[];
        +
        +
        +SSL_METHOD *ssl_bad_method(int ver);
        +
        +extern SSL3_ENC_METHOD TLSv1_enc_data;
        +extern SSL3_ENC_METHOD SSLv3_enc_data;
        +extern SSL3_ENC_METHOD DTLSv1_enc_data;
        +
        +#define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \
        +				s_get_meth) \
        +const SSL_METHOD *func_name(void)  \
        +	{ \
        +	static const SSL_METHOD func_name##_data= { \
        +		version, \
        +		tls1_new, \
        +		tls1_clear, \
        +		tls1_free, \
        +		s_accept, \
        +		s_connect, \
        +		ssl3_read, \
        +		ssl3_peek, \
        +		ssl3_write, \
        +		ssl3_shutdown, \
        +		ssl3_renegotiate, \
        +		ssl3_renegotiate_check, \
        +		ssl3_get_message, \
        +		ssl3_read_bytes, \
        +		ssl3_write_bytes, \
        +		ssl3_dispatch_alert, \
        +		ssl3_ctrl, \
        +		ssl3_ctx_ctrl, \
        +		ssl3_get_cipher_by_char, \
        +		ssl3_put_cipher_by_char, \
        +		ssl3_pending, \
        +		ssl3_num_ciphers, \
        +		ssl3_get_cipher, \
        +		s_get_meth, \
        +		tls1_default_timeout, \
        +		&TLSv1_enc_data, \
        +		ssl_undefined_void_function, \
        +		ssl3_callback_ctrl, \
        +		ssl3_ctx_callback_ctrl, \
        +	}; \
        +	return &func_name##_data; \
        +	}
        +
        +#define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \
        +const SSL_METHOD *func_name(void)  \
        +	{ \
        +	static const SSL_METHOD func_name##_data= { \
        +		SSL3_VERSION, \
        +		ssl3_new, \
        +		ssl3_clear, \
        +		ssl3_free, \
        +		s_accept, \
        +		s_connect, \
        +		ssl3_read, \
        +		ssl3_peek, \
        +		ssl3_write, \
        +		ssl3_shutdown, \
        +		ssl3_renegotiate, \
        +		ssl3_renegotiate_check, \
        +		ssl3_get_message, \
        +		ssl3_read_bytes, \
        +		ssl3_write_bytes, \
        +		ssl3_dispatch_alert, \
        +		ssl3_ctrl, \
        +		ssl3_ctx_ctrl, \
        +		ssl3_get_cipher_by_char, \
        +		ssl3_put_cipher_by_char, \
        +		ssl3_pending, \
        +		ssl3_num_ciphers, \
        +		ssl3_get_cipher, \
        +		s_get_meth, \
        +		ssl3_default_timeout, \
        +		&SSLv3_enc_data, \
        +		ssl_undefined_void_function, \
        +		ssl3_callback_ctrl, \
        +		ssl3_ctx_callback_ctrl, \
        +	}; \
        +	return &func_name##_data; \
        +	}
        +
        +#define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
        +const SSL_METHOD *func_name(void)  \
        +	{ \
        +	static const SSL_METHOD func_name##_data= { \
        +	TLS1_2_VERSION, \
        +	tls1_new, \
        +	tls1_clear, \
        +	tls1_free, \
        +	s_accept, \
        +	s_connect, \
        +	ssl23_read, \
        +	ssl23_peek, \
        +	ssl23_write, \
        +	ssl_undefined_function, \
        +	ssl_undefined_function, \
        +	ssl_ok, \
        +	ssl3_get_message, \
        +	ssl3_read_bytes, \
        +	ssl3_write_bytes, \
        +	ssl3_dispatch_alert, \
        +	ssl3_ctrl, \
        +	ssl3_ctx_ctrl, \
        +	ssl23_get_cipher_by_char, \
        +	ssl23_put_cipher_by_char, \
        +	ssl_undefined_const_function, \
        +	ssl23_num_ciphers, \
        +	ssl23_get_cipher, \
        +	s_get_meth, \
        +	ssl23_default_timeout, \
        +	&ssl3_undef_enc_method, \
        +	ssl_undefined_void_function, \
        +	ssl3_callback_ctrl, \
        +	ssl3_ctx_callback_ctrl, \
        +	}; \
        +	return &func_name##_data; \
        +	}
        +
        +#define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \
        +const SSL_METHOD *func_name(void)  \
        +	{ \
        +	static const SSL_METHOD func_name##_data= { \
        +		SSL2_VERSION, \
        +		ssl2_new,	/* local */ \
        +		ssl2_clear,	/* local */ \
        +		ssl2_free,	/* local */ \
        +		s_accept, \
        +		s_connect, \
        +		ssl2_read, \
        +		ssl2_peek, \
        +		ssl2_write, \
        +		ssl2_shutdown, \
        +		ssl_ok,	/* NULL - renegotiate */ \
        +		ssl_ok,	/* NULL - check renegotiate */ \
        +		NULL, /* NULL - ssl_get_message */ \
        +		NULL, /* NULL - ssl_get_record */ \
        +		NULL, /* NULL - ssl_write_bytes */ \
        +		NULL, /* NULL - dispatch_alert */ \
        +		ssl2_ctrl,	/* local */ \
        +		ssl2_ctx_ctrl,	/* local */ \
        +		ssl2_get_cipher_by_char, \
        +		ssl2_put_cipher_by_char, \
        +		ssl2_pending, \
        +		ssl2_num_ciphers, \
        +		ssl2_get_cipher, \
        +		s_get_meth, \
        +		ssl2_default_timeout, \
        +		&ssl3_undef_enc_method, \
        +		ssl_undefined_void_function, \
        +		ssl2_callback_ctrl,	/* local */ \
        +		ssl2_ctx_callback_ctrl,	/* local */ \
        +	}; \
        +	return &func_name##_data; \
        +	}
        +
        +#define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
        +const SSL_METHOD *func_name(void)  \
        +	{ \
        +	static const SSL_METHOD func_name##_data= { \
        +		DTLS1_VERSION, \
        +		dtls1_new, \
        +		dtls1_clear, \
        +		dtls1_free, \
        +		s_accept, \
        +		s_connect, \
        +		ssl3_read, \
        +		ssl3_peek, \
        +		ssl3_write, \
        +		dtls1_shutdown, \
        +		ssl3_renegotiate, \
        +		ssl3_renegotiate_check, \
        +		dtls1_get_message, \
        +		dtls1_read_bytes, \
        +		dtls1_write_app_data_bytes, \
        +		dtls1_dispatch_alert, \
        +		dtls1_ctrl, \
        +		ssl3_ctx_ctrl, \
        +		ssl3_get_cipher_by_char, \
        +		ssl3_put_cipher_by_char, \
        +		ssl3_pending, \
        +		ssl3_num_ciphers, \
        +		dtls1_get_cipher, \
        +		s_get_meth, \
        +		dtls1_default_timeout, \
        +		&DTLSv1_enc_data, \
        +		ssl_undefined_void_function, \
        +		ssl3_callback_ctrl, \
        +		ssl3_ctx_callback_ctrl, \
        +	}; \
        +	return &func_name##_data; \
        +	}
        +
        +void ssl_clear_cipher_ctx(SSL *s);
        +int ssl_clear_bad_session(SSL *s);
        +CERT *ssl_cert_new(void);
        +CERT *ssl_cert_dup(CERT *cert);
        +int ssl_cert_inst(CERT **o);
        +void ssl_cert_free(CERT *c);
        +SESS_CERT *ssl_sess_cert_new(void);
        +void ssl_sess_cert_free(SESS_CERT *sc);
        +int ssl_set_peer_cert_type(SESS_CERT *c, int type);
        +int ssl_get_new_session(SSL *s, int session);
        +int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
        +int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
        +DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
        +				  ssl_cipher_id);
        +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
        +			const SSL_CIPHER * const *bp);
        +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
        +					       STACK_OF(SSL_CIPHER) **skp);
        +int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
        +                             int (*put_cb)(const SSL_CIPHER *, unsigned char *));
        +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
        +					     STACK_OF(SSL_CIPHER) **pref,
        +					     STACK_OF(SSL_CIPHER) **sorted,
        +					     const char *rule_str);
        +void ssl_update_cache(SSL *s, int mode);
        +int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
        +		       const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
        +int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);			   
        +int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
        +int ssl_undefined_function(SSL *s);
        +int ssl_undefined_void_function(void);
        +int ssl_undefined_const_function(const SSL *s);
        +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
        +X509 *ssl_get_server_send_cert(const SSL *);
        +EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd);
        +int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
        +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
        +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
        +int ssl_verify_alarm_type(long type);
        +void ssl_load_ciphers(void);
        +
        +int ssl2_enc_init(SSL *s, int client);
        +int ssl2_generate_key_material(SSL *s);
        +void ssl2_enc(SSL *s,int send_data);
        +void ssl2_mac(SSL *s,unsigned char *mac,int send_data);
        +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
        +int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
        +int ssl2_part_read(SSL *s, unsigned long f, int i);
        +int ssl2_do_write(SSL *s);
        +int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data);
        +void ssl2_return_error(SSL *s,int reason);
        +void ssl2_write_error(SSL *s);
        +int ssl2_num_ciphers(void);
        +const SSL_CIPHER *ssl2_get_cipher(unsigned int u);
        +int	ssl2_new(SSL *s);
        +void	ssl2_free(SSL *s);
        +int	ssl2_accept(SSL *s);
        +int	ssl2_connect(SSL *s);
        +int	ssl2_read(SSL *s, void *buf, int len);
        +int	ssl2_peek(SSL *s, void *buf, int len);
        +int	ssl2_write(SSL *s, const void *buf, int len);
        +int	ssl2_shutdown(SSL *s);
        +void	ssl2_clear(SSL *s);
        +long	ssl2_ctrl(SSL *s,int cmd, long larg, void *parg);
        +long	ssl2_ctx_ctrl(SSL_CTX *s,int cmd, long larg, void *parg);
        +long	ssl2_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
        +long	ssl2_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)(void));
        +int	ssl2_pending(const SSL *s);
        +long	ssl2_default_timeout(void );
        +
        +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
        +int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
        +void ssl3_init_finished_mac(SSL *s);
        +int ssl3_send_server_certificate(SSL *s);
        +int ssl3_send_newsession_ticket(SSL *s);
        +int ssl3_send_cert_status(SSL *s);
        +int ssl3_get_finished(SSL *s,int state_a,int state_b);
        +int ssl3_setup_key_block(SSL *s);
        +int ssl3_send_change_cipher_spec(SSL *s,int state_a,int state_b);
        +int ssl3_change_cipher_state(SSL *s,int which);
        +void ssl3_cleanup_key_block(SSL *s);
        +int ssl3_do_write(SSL *s,int type);
        +int ssl3_send_alert(SSL *s,int level, int desc);
        +int ssl3_generate_master_secret(SSL *s, unsigned char *out,
        +	unsigned char *p, int len);
        +int ssl3_get_req_cert_type(SSL *s,unsigned char *p);
        +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
        +int ssl3_send_finished(SSL *s, int a, int b, const char *sender,int slen);
        +int ssl3_num_ciphers(void);
        +const SSL_CIPHER *ssl3_get_cipher(unsigned int u);
        +int ssl3_renegotiate(SSL *ssl); 
        +int ssl3_renegotiate_check(SSL *ssl); 
        +int ssl3_dispatch_alert(SSL *s);
        +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
        +int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
        +int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,unsigned char *p);
        +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
        +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len);
        +int ssl3_enc(SSL *s, int send_data);
        +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
        +void ssl3_free_digest_list(SSL *s);
        +unsigned long ssl3_output_cert_chain(SSL *s, X509 *x);
        +SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,STACK_OF(SSL_CIPHER) *clnt,
        +			       STACK_OF(SSL_CIPHER) *srvr);
        +int	ssl3_setup_buffers(SSL *s);
        +int	ssl3_setup_read_buffer(SSL *s);
        +int	ssl3_setup_write_buffer(SSL *s);
        +int	ssl3_release_read_buffer(SSL *s);
        +int	ssl3_release_write_buffer(SSL *s);
        +int	ssl3_digest_cached_records(SSL *s);
        +int	ssl3_new(SSL *s);
        +void	ssl3_free(SSL *s);
        +int	ssl3_accept(SSL *s);
        +int	ssl3_connect(SSL *s);
        +int	ssl3_read(SSL *s, void *buf, int len);
        +int	ssl3_peek(SSL *s, void *buf, int len);
        +int	ssl3_write(SSL *s, const void *buf, int len);
        +int	ssl3_shutdown(SSL *s);
        +void	ssl3_clear(SSL *s);
        +long	ssl3_ctrl(SSL *s,int cmd, long larg, void *parg);
        +long	ssl3_ctx_ctrl(SSL_CTX *s,int cmd, long larg, void *parg);
        +long	ssl3_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
        +long	ssl3_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)(void));
        +int	ssl3_pending(const SSL *s);
        +
        +void ssl3_record_sequence_update(unsigned char *seq);
        +int ssl3_do_change_cipher_spec(SSL *ssl);
        +long ssl3_default_timeout(void );
        +
        +int ssl23_num_ciphers(void );
        +const SSL_CIPHER *ssl23_get_cipher(unsigned int u);
        +int ssl23_read(SSL *s, void *buf, int len);
        +int ssl23_peek(SSL *s, void *buf, int len);
        +int ssl23_write(SSL *s, const void *buf, int len);
        +int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
        +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p);
        +long ssl23_default_timeout(void );
        +
        +long tls1_default_timeout(void);
        +int dtls1_do_write(SSL *s,int type);
        +int ssl3_read_n(SSL *s, int n, int max, int extend);
        +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
        +int ssl3_do_compress(SSL *ssl);
        +int ssl3_do_uncompress(SSL *ssl);
        +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
        +	unsigned int len);
        +unsigned char *dtls1_set_message_header(SSL *s, 
        +	unsigned char *p, unsigned char mt,	unsigned long len, 
        +	unsigned long frag_off, unsigned long frag_len);
        +
        +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
        +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
        +
        +int dtls1_send_change_cipher_spec(SSL *s, int a, int b);
        +int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen);
        +unsigned long dtls1_output_cert_chain(SSL *s, X509 *x);
        +int dtls1_read_failed(SSL *s, int code);
        +int dtls1_buffer_message(SSL *s, int ccs);
        +int dtls1_retransmit_message(SSL *s, unsigned short seq, 
        +	unsigned long frag_off, int *found);
        +int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
        +int dtls1_retransmit_buffered_messages(SSL *s);
        +void dtls1_clear_record_buffer(SSL *s);
        +void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr);
        +void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
        +void dtls1_reset_seq_numbers(SSL *s, int rw);
        +long dtls1_default_timeout(void);
        +struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
        +int dtls1_check_timeout_num(SSL *s);
        +int dtls1_handle_timeout(SSL *s);
        +const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
        +void dtls1_start_timer(SSL *s);
        +void dtls1_stop_timer(SSL *s);
        +int dtls1_is_timer_expired(SSL *s);
        +void dtls1_double_timeout(SSL *s);
        +int dtls1_send_newsession_ticket(SSL *s);
        +unsigned int dtls1_min_mtu(void);
        +
        +/* some client-only functions */
        +int ssl3_client_hello(SSL *s);
        +int ssl3_get_server_hello(SSL *s);
        +int ssl3_get_certificate_request(SSL *s);
        +int ssl3_get_new_session_ticket(SSL *s);
        +int ssl3_get_cert_status(SSL *s);
        +int ssl3_get_server_done(SSL *s);
        +int ssl3_send_client_verify(SSL *s);
        +int ssl3_send_client_certificate(SSL *s);
        +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
        +int ssl3_send_client_key_exchange(SSL *s);
        +int ssl3_get_key_exchange(SSL *s);
        +int ssl3_get_server_certificate(SSL *s);
        +int ssl3_check_cert_and_algorithm(SSL *s);
        +#ifndef OPENSSL_NO_TLSEXT
        +int ssl3_check_finished(SSL *s);
        +# ifndef OPENSSL_NO_NEXTPROTONEG
        +int ssl3_send_next_proto(SSL *s);
        +# endif
        +#endif
        +
        +int dtls1_client_hello(SSL *s);
        +int dtls1_send_client_certificate(SSL *s);
        +int dtls1_send_client_key_exchange(SSL *s);
        +int dtls1_send_client_verify(SSL *s);
        +
        +/* some server-only functions */
        +int ssl3_get_client_hello(SSL *s);
        +int ssl3_send_server_hello(SSL *s);
        +int ssl3_send_hello_request(SSL *s);
        +int ssl3_send_server_key_exchange(SSL *s);
        +int ssl3_send_certificate_request(SSL *s);
        +int ssl3_send_server_done(SSL *s);
        +int ssl3_check_client_hello(SSL *s);
        +int ssl3_get_client_certificate(SSL *s);
        +int ssl3_get_client_key_exchange(SSL *s);
        +int ssl3_get_cert_verify(SSL *s);
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +int ssl3_get_next_proto(SSL *s);
        +#endif
        +
        +int dtls1_send_hello_request(SSL *s);
        +int dtls1_send_server_hello(SSL *s);
        +int dtls1_send_server_certificate(SSL *s);
        +int dtls1_send_server_key_exchange(SSL *s);
        +int dtls1_send_certificate_request(SSL *s);
        +int dtls1_send_server_done(SSL *s);
        +
        +
        +
        +int ssl23_accept(SSL *s);
        +int ssl23_connect(SSL *s);
        +int ssl23_read_bytes(SSL *s, int n);
        +int ssl23_write_bytes(SSL *s);
        +
        +int tls1_new(SSL *s);
        +void tls1_free(SSL *s);
        +void tls1_clear(SSL *s);
        +long tls1_ctrl(SSL *s,int cmd, long larg, void *parg);
        +long tls1_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
        +
        +int dtls1_new(SSL *s);
        +int	dtls1_accept(SSL *s);
        +int	dtls1_connect(SSL *s);
        +void dtls1_free(SSL *s);
        +void dtls1_clear(SSL *s);
        +long dtls1_ctrl(SSL *s,int cmd, long larg, void *parg);
        +int dtls1_shutdown(SSL *s);
        +
        +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
        +int dtls1_get_record(SSL *s);
        +int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
        +	unsigned int len, int create_empty_fragement);
        +int dtls1_dispatch_alert(SSL *s);
        +int dtls1_enc(SSL *s, int snd);
        +
        +int ssl_init_wbio_buffer(SSL *s, int push);
        +void ssl_free_wbio_buffer(SSL *s);
        +
        +int tls1_change_cipher_state(SSL *s, int which);
        +int tls1_setup_key_block(SSL *s);
        +int tls1_enc(SSL *s, int snd);
        +int tls1_final_finish_mac(SSL *s,
        +	const char *str, int slen, unsigned char *p);
        +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
        +int tls1_mac(SSL *ssl, unsigned char *md, int snd);
        +int tls1_generate_master_secret(SSL *s, unsigned char *out,
        +	unsigned char *p, int len);
        +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
        +	const char *label, size_t llen,
        +	const unsigned char *p, size_t plen, int use_context);
        +int tls1_alert_code(int code);
        +int ssl3_alert_code(int code);
        +int ssl_ok(SSL *s);
        +
        +#ifndef OPENSSL_NO_ECDH
        +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
        +#endif
        +
        +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
        +
        +#ifndef OPENSSL_NO_EC
        +int tls1_ec_curve_id2nid(int curve_id);
        +int tls1_ec_nid2curve_id(int nid);
        +#endif /* OPENSSL_NO_EC */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
        +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
        +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
        +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
        +int ssl_prepare_clienthello_tlsext(SSL *s);
        +int ssl_prepare_serverhello_tlsext(SSL *s);
        +int ssl_check_clienthello_tlsext_early(SSL *s);
        +int ssl_check_clienthello_tlsext_late(SSL *s);
        +int ssl_check_serverhello_tlsext(SSL *s);
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +int tls1_heartbeat(SSL *s);
        +int dtls1_heartbeat(SSL *s);
        +int tls1_process_heartbeat(SSL *s);
        +int dtls1_process_heartbeat(SSL *s);
        +#endif
        +
        +#ifdef OPENSSL_NO_SHA256
        +#define tlsext_tick_md	EVP_sha1
        +#else
        +#define tlsext_tick_md	EVP_sha256
        +#endif
        +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
        +				const unsigned char *limit, SSL_SESSION **ret);
        +
        +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
        +				const EVP_MD *md);
        +int tls12_get_sigid(const EVP_PKEY *pk);
        +const EVP_MD *tls12_get_hash(unsigned char hash_alg);
        +
        +#endif
        +EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
        +void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
        +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
        +					int maxlen);
        +int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
        +					  int *al);
        +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
        +					int maxlen);
        +int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
        +					  int *al);
        +long ssl_get_algorithm2(SSL *s);
        +int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
        +int tls12_get_req_sig_algs(SSL *s, unsigned char *p);
        +
        +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
        +int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
        +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
        +int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
        +
        +/* s3_cbc.c */
        +void ssl3_cbc_copy_mac(unsigned char* out,
        +		       const SSL3_RECORD *rec,
        +		       unsigned md_size,unsigned orig_len);
        +int ssl3_cbc_remove_padding(const SSL* s,
        +			    SSL3_RECORD *rec,
        +			    unsigned block_size,
        +			    unsigned mac_size);
        +int tls1_cbc_remove_padding(const SSL* s,
        +			    SSL3_RECORD *rec,
        +			    unsigned block_size,
        +			    unsigned mac_size);
        +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
        +void ssl3_cbc_digest_record(
        +	const EVP_MD_CTX *ctx,
        +	unsigned char* md_out,
        +	size_t* md_out_size,
        +	const unsigned char header[13],
        +	const unsigned char *data,
        +	size_t data_plus_mac_size,
        +	size_t data_plus_mac_plus_padding_size,
        +	const unsigned char *mac_secret,
        +	unsigned mac_secret_length,
        +	char is_sslv3);
        +
        +void tls_fips_digest_extra(
        +	const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
        +	const unsigned char *data, size_t data_len, size_t orig_len);
        +
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/ssl_rsa.c b/vendor/openssl/openssl/ssl/ssl_rsa.c
        new file mode 100644
        index 000000000..60e7b6685
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_rsa.c
        @@ -0,0 +1,783 @@
        +/* ssl/ssl_rsa.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/bio.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/pem.h>
        +
        +static int ssl_set_cert(CERT *c, X509 *x509);
        +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
        +int SSL_use_certificate(SSL *ssl, X509 *x)
        +	{
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (!ssl_cert_inst(&ssl->cert))
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	return(ssl_set_cert(ssl->cert,x));
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
        +	{
        +	int j;
        +	BIO *in;
        +	int ret=0;
        +	X509 *x=NULL;
        +
        +	in=BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +	if (type == SSL_FILETYPE_ASN1)
        +		{
        +		j=ERR_R_ASN1_LIB;
        +		x=d2i_X509_bio(in,NULL);
        +		}
        +	else if (type == SSL_FILETYPE_PEM)
        +		{
        +		j=ERR_R_PEM_LIB;
        +		x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
        +		goto end;
        +		}
        +
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,j);
        +		goto end;
        +		}
        +
        +	ret=SSL_use_certificate(ssl,x);
        +end:
        +	if (x != NULL) X509_free(x);
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
        +	{
        +	X509 *x;
        +	int ret;
        +
        +	x=d2i_X509(NULL,&d,(long)len);
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB);
        +		return(0);
        +		}
        +
        +	ret=SSL_use_certificate(ssl,x);
        +	X509_free(x);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
        +	{
        +	EVP_PKEY *pkey;
        +	int ret;
        +
        +	if (rsa == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (!ssl_cert_inst(&ssl->cert))
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	if ((pkey=EVP_PKEY_new()) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB);
        +		return(0);
        +		}
        +
        +	RSA_up_ref(rsa);
        +	EVP_PKEY_assign_RSA(pkey,rsa);
        +
        +	ret=ssl_set_pkey(ssl->cert,pkey);
        +	EVP_PKEY_free(pkey);
        +	return(ret);
        +	}
        +#endif
        +
        +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
        +	{
        +	int i;
        +
        +	i=ssl_cert_type(NULL,pkey);
        +	if (i < 0)
        +		{
        +		SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
        +		return(0);
        +		}
        +
        +	if (c->pkeys[i].x509 != NULL)
        +		{
        +		EVP_PKEY *pktmp;
        +		pktmp =	X509_get_pubkey(c->pkeys[i].x509);
        +		EVP_PKEY_copy_parameters(pktmp,pkey);
        +		EVP_PKEY_free(pktmp);
        +		ERR_clear_error();
        +
        +#ifndef OPENSSL_NO_RSA
        +		/* Don't check the public/private key, this is mostly
        +		 * for smart cards. */
        +		if ((pkey->type == EVP_PKEY_RSA) &&
        +			(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
        +			;
        +		else
        +#endif
        +		if (!X509_check_private_key(c->pkeys[i].x509,pkey))
        +			{
        +			X509_free(c->pkeys[i].x509);
        +			c->pkeys[i].x509 = NULL;
        +			return 0;
        +			}
        +		}
        +
        +	if (c->pkeys[i].privatekey != NULL)
        +		EVP_PKEY_free(c->pkeys[i].privatekey);
        +	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        +	c->pkeys[i].privatekey=pkey;
        +	c->key= &(c->pkeys[i]);
        +
        +	c->valid=0;
        +	return(1);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
        +	{
        +	int j,ret=0;
        +	BIO *in;
        +	RSA *rsa=NULL;
        +
        +	in=BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +	if	(type == SSL_FILETYPE_ASN1)
        +		{
        +		j=ERR_R_ASN1_LIB;
        +		rsa=d2i_RSAPrivateKey_bio(in,NULL);
        +		}
        +	else if (type == SSL_FILETYPE_PEM)
        +		{
        +		j=ERR_R_PEM_LIB;
        +		rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
        +			ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
        +		goto end;
        +		}
        +	if (rsa == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,j);
        +		goto end;
        +		}
        +	ret=SSL_use_RSAPrivateKey(ssl,rsa);
        +	RSA_free(rsa);
        +end:
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len)
        +	{
        +	int ret;
        +	const unsigned char *p;
        +	RSA *rsa;
        +
        +	p=d;
        +	if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
        +		return(0);
        +		}
        +
        +	ret=SSL_use_RSAPrivateKey(ssl,rsa);
        +	RSA_free(rsa);
        +	return(ret);
        +	}
        +#endif /* !OPENSSL_NO_RSA */
        +
        +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
        +	{
        +	int ret;
        +
        +	if (pkey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (!ssl_cert_inst(&ssl->cert))
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	ret=ssl_set_pkey(ssl->cert,pkey);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
        +	{
        +	int j,ret=0;
        +	BIO *in;
        +	EVP_PKEY *pkey=NULL;
        +
        +	in=BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +	if (type == SSL_FILETYPE_PEM)
        +		{
        +		j=ERR_R_PEM_LIB;
        +		pkey=PEM_read_bio_PrivateKey(in,NULL,
        +			ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
        +		}
        +	else if (type == SSL_FILETYPE_ASN1)
        +		{
        +		j = ERR_R_ASN1_LIB;
        +		pkey = d2i_PrivateKey_bio(in,NULL);
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
        +		goto end;
        +		}
        +	if (pkey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,j);
        +		goto end;
        +		}
        +	ret=SSL_use_PrivateKey(ssl,pkey);
        +	EVP_PKEY_free(pkey);
        +end:
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
        +	{
        +	int ret;
        +	const unsigned char *p;
        +	EVP_PKEY *pkey;
        +
        +	p=d;
        +	if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
        +		return(0);
        +		}
        +
        +	ret=SSL_use_PrivateKey(ssl,pkey);
        +	EVP_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
        +	{
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (!ssl_cert_inst(&ctx->cert))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	return(ssl_set_cert(ctx->cert, x));
        +	}
        +
        +static int ssl_set_cert(CERT *c, X509 *x)
        +	{
        +	EVP_PKEY *pkey;
        +	int i;
        +
        +	pkey=X509_get_pubkey(x);
        +	if (pkey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB);
        +		return(0);
        +		}
        +
        +	i=ssl_cert_type(x,pkey);
        +	if (i < 0)
        +		{
        +		SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
        +		EVP_PKEY_free(pkey);
        +		return(0);
        +		}
        +
        +	if (c->pkeys[i].privatekey != NULL)
        +		{
        +		EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey);
        +		ERR_clear_error();
        +
        +#ifndef OPENSSL_NO_RSA
        +		/* Don't check the public/private key, this is mostly
        +		 * for smart cards. */
        +		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
        +			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
        +			 RSA_METHOD_FLAG_NO_CHECK))
        +			 ;
        +		else
        +#endif /* OPENSSL_NO_RSA */
        +		if (!X509_check_private_key(x,c->pkeys[i].privatekey))
        +			{
        +			/* don't fail for a cert/key mismatch, just free
        +			 * current private key (when switching to a different
        +			 * cert & key, first this function should be used,
        +			 * then ssl_set_pkey */
        +			EVP_PKEY_free(c->pkeys[i].privatekey);
        +			c->pkeys[i].privatekey=NULL;
        +			/* clear error queue */
        +			ERR_clear_error();
        +			}
        +		}
        +
        +	EVP_PKEY_free(pkey);
        +
        +	if (c->pkeys[i].x509 != NULL)
        +		X509_free(c->pkeys[i].x509);
        +	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
        +	c->pkeys[i].x509=x;
        +	c->key= &(c->pkeys[i]);
        +
        +	c->valid=0;
        +	return(1);
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
        +	{
        +	int j;
        +	BIO *in;
        +	int ret=0;
        +	X509 *x=NULL;
        +
        +	in=BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +	if (type == SSL_FILETYPE_ASN1)
        +		{
        +		j=ERR_R_ASN1_LIB;
        +		x=d2i_X509_bio(in,NULL);
        +		}
        +	else if (type == SSL_FILETYPE_PEM)
        +		{
        +		j=ERR_R_PEM_LIB;
        +		x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
        +		goto end;
        +		}
        +
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j);
        +		goto end;
        +		}
        +
        +	ret=SSL_CTX_use_certificate(ctx,x);
        +end:
        +	if (x != NULL) X509_free(x);
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
        +	{
        +	X509 *x;
        +	int ret;
        +
        +	x=d2i_X509(NULL,&d,(long)len);
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1,ERR_R_ASN1_LIB);
        +		return(0);
        +		}
        +
        +	ret=SSL_CTX_use_certificate(ctx,x);
        +	X509_free(x);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
        +	{
        +	int ret;
        +	EVP_PKEY *pkey;
        +
        +	if (rsa == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (!ssl_cert_inst(&ctx->cert))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	if ((pkey=EVP_PKEY_new()) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB);
        +		return(0);
        +		}
        +
        +	RSA_up_ref(rsa);
        +	EVP_PKEY_assign_RSA(pkey,rsa);
        +
        +	ret=ssl_set_pkey(ctx->cert, pkey);
        +	EVP_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
        +	{
        +	int j,ret=0;
        +	BIO *in;
        +	RSA *rsa=NULL;
        +
        +	in=BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +	if	(type == SSL_FILETYPE_ASN1)
        +		{
        +		j=ERR_R_ASN1_LIB;
        +		rsa=d2i_RSAPrivateKey_bio(in,NULL);
        +		}
        +	else if (type == SSL_FILETYPE_PEM)
        +		{
        +		j=ERR_R_PEM_LIB;
        +		rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
        +			ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
        +		goto end;
        +		}
        +	if (rsa == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,j);
        +		goto end;
        +		}
        +	ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
        +	RSA_free(rsa);
        +end:
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
        +	{
        +	int ret;
        +	const unsigned char *p;
        +	RSA *rsa;
        +
        +	p=d;
        +	if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
        +		return(0);
        +		}
        +
        +	ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
        +	RSA_free(rsa);
        +	return(ret);
        +	}
        +#endif /* !OPENSSL_NO_RSA */
        +
        +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
        +	{
        +	if (pkey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER);
        +		return(0);
        +		}
        +	if (!ssl_cert_inst(&ctx->cert))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	return(ssl_set_pkey(ctx->cert,pkey));
        +	}
        +
        +#ifndef OPENSSL_NO_STDIO
        +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
        +	{
        +	int j,ret=0;
        +	BIO *in;
        +	EVP_PKEY *pkey=NULL;
        +
        +	in=BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +	if (type == SSL_FILETYPE_PEM)
        +		{
        +		j=ERR_R_PEM_LIB;
        +		pkey=PEM_read_bio_PrivateKey(in,NULL,
        +			ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
        +		}
        +	else if (type == SSL_FILETYPE_ASN1)
        +		{
        +		j = ERR_R_ASN1_LIB;
        +		pkey = d2i_PrivateKey_bio(in,NULL);
        +		}
        +	else
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
        +		goto end;
        +		}
        +	if (pkey == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,j);
        +		goto end;
        +		}
        +	ret=SSL_CTX_use_PrivateKey(ctx,pkey);
        +	EVP_PKEY_free(pkey);
        +end:
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
        +	     long len)
        +	{
        +	int ret;
        +	const unsigned char *p;
        +	EVP_PKEY *pkey;
        +
        +	p=d;
        +	if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1,ERR_R_ASN1_LIB);
        +		return(0);
        +		}
        +
        +	ret=SSL_CTX_use_PrivateKey(ctx,pkey);
        +	EVP_PKEY_free(pkey);
        +	return(ret);
        +	}
        +
        +
        +#ifndef OPENSSL_NO_STDIO
        +/* Read a file that contains our certificate in "PEM" format,
        + * possibly followed by a sequence of CA certificates that should be
        + * sent to the peer in the Certificate message.
        + */
        +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
        +	{
        +	BIO *in;
        +	int ret=0;
        +	X509 *x=NULL;
        +
        +	ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
        +
        +	in = BIO_new(BIO_s_file_internal());
        +	if (in == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB);
        +		goto end;
        +		}
        +
        +	if (BIO_read_filename(in,file) <= 0)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_SYS_LIB);
        +		goto end;
        +		}
        +
        +	x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,
        +				ctx->default_passwd_callback_userdata);
        +	if (x == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
        +		goto end;
        +		}
        +
        +	ret = SSL_CTX_use_certificate(ctx, x);
        +
        +	if (ERR_peek_error() != 0)
        +		ret = 0;  /* Key/certificate mismatch doesn't imply ret==0 ... */
        +	if (ret)
        +		{
        +		/* If we could set up our certificate, now proceed to
        +		 * the CA certificates.
        +		 */
        +		X509 *ca;
        +		int r;
        +		unsigned long err;
        +		
        +		if (ctx->extra_certs != NULL)
        +			{
        +			sk_X509_pop_free(ctx->extra_certs, X509_free);
        +			ctx->extra_certs = NULL;
        +			}
        +
        +		while ((ca = PEM_read_bio_X509(in, NULL,
        +					ctx->default_passwd_callback,
        +					ctx->default_passwd_callback_userdata))
        +			!= NULL)
        +			{
        +			r = SSL_CTX_add_extra_chain_cert(ctx, ca);
        +			if (!r) 
        +				{
        +				X509_free(ca);
        +				ret = 0;
        +				goto end;
        +				}
        +			/* Note that we must not free r if it was successfully
        +			 * added to the chain (while we must free the main
        +			 * certificate, since its reference count is increased
        +			 * by SSL_CTX_use_certificate). */
        +			}
        +		/* When the while loop ends, it's usually just EOF. */
        +		err = ERR_peek_last_error();
        +		if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
        +			ERR_clear_error();
        +		else 
        +			ret = 0; /* some real error */
        +		}
        +
        +end:
        +	if (x != NULL) X509_free(x);
        +	if (in != NULL) BIO_free(in);
        +	return(ret);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/ssl_sess.c b/vendor/openssl/openssl/ssl/ssl_sess.c
        new file mode 100644
        index 000000000..ad40fadd0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_sess.c
        @@ -0,0 +1,1159 @@
        +/* ssl/ssl_sess.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-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include <openssl/lhash.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include "ssl_locl.h"
        +
        +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
        +static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
        +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
        +
        +SSL_SESSION *SSL_get_session(const SSL *ssl)
        +/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
        +	{
        +	return(ssl->session);
        +	}
        +
        +SSL_SESSION *SSL_get1_session(SSL *ssl)
        +/* variant of SSL_get_session: caller really gets something */
        +	{
        +	SSL_SESSION *sess;
        +	/* Need to lock this all up rather than just use CRYPTO_add so that
        +	 * somebody doesn't free ssl->session between when we check it's
        +	 * non-null and when we up the reference count. */
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION);
        +	sess = ssl->session;
        +	if(sess)
        +		sess->references++;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION);
        +	return(sess);
        +	}
        +
        +int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
        +	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        +	{
        +	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
        +			new_func, dup_func, free_func);
        +	}
        +
        +int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
        +	{
        +	return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
        +	}
        +
        +void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
        +	{
        +	return(CRYPTO_get_ex_data(&s->ex_data,idx));
        +	}
        +
        +SSL_SESSION *SSL_SESSION_new(void)
        +	{
        +	SSL_SESSION *ss;
        +
        +	ss=(SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
        +	if (ss == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_SESSION_NEW,ERR_R_MALLOC_FAILURE);
        +		return(0);
        +		}
        +	memset(ss,0,sizeof(SSL_SESSION));
        +
        +	ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
        +	ss->references=1;
        +	ss->timeout=60*5+4; /* 5 minute timeout by default */
        +	ss->time=(unsigned long)time(NULL);
        +	ss->prev=NULL;
        +	ss->next=NULL;
        +	ss->compress_meth=0;
        +#ifndef OPENSSL_NO_TLSEXT
        +	ss->tlsext_hostname = NULL; 
        +#ifndef OPENSSL_NO_EC
        +	ss->tlsext_ecpointformatlist_length = 0;
        +	ss->tlsext_ecpointformatlist = NULL;
        +	ss->tlsext_ellipticcurvelist_length = 0;
        +	ss->tlsext_ellipticcurvelist = NULL;
        +#endif
        +#endif
        +	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
        +#ifndef OPENSSL_NO_PSK
        +	ss->psk_identity_hint=NULL;
        +	ss->psk_identity=NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	ss->srp_username=NULL;
        +#endif
        +	return(ss);
        +	}
        +
        +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
        +	{
        +	if(len)
        +		*len = s->session_id_length;
        +	return s->session_id;
        +	}
        +
        +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
        +	{
        +	return s->compress_meth;
        +	}
        +
        +/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
        + * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
        + * until we have no conflict is going to complete in one iteration pretty much
        + * "most" of the time (btw: understatement). So, if it takes us 10 iterations
        + * and we still can't avoid a conflict - well that's a reasonable point to call
        + * it quits. Either the RAND code is broken or someone is trying to open roughly
        + * very close to 2^128 (or 2^256) SSL sessions to our server. How you might
        + * store that many sessions is perhaps a more interesting question ... */
        +
        +#define MAX_SESS_ID_ATTEMPTS 10
        +static int def_generate_session_id(const SSL *ssl, unsigned char *id,
        +				unsigned int *id_len)
        +{
        +	unsigned int retry = 0;
        +	do
        +		if (RAND_pseudo_bytes(id, *id_len) <= 0)
        +			return 0;
        +	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
        +		(++retry < MAX_SESS_ID_ATTEMPTS));
        +	if(retry < MAX_SESS_ID_ATTEMPTS)
        +		return 1;
        +	/* else - woops a session_id match */
        +	/* XXX We should also check the external cache --
        +	 * but the probability of a collision is negligible, and
        +	 * we could not prevent the concurrent creation of sessions
        +	 * with identical IDs since we currently don't have means
        +	 * to atomically check whether a session ID already exists
        +	 * and make a reservation for it if it does not
        +	 * (this problem applies to the internal cache as well).
        +	 */
        +	return 0;
        +}
        +
        +int ssl_get_new_session(SSL *s, int session)
        +	{
        +	/* This gets used by clients and servers. */
        +
        +	unsigned int tmp;
        +	SSL_SESSION *ss=NULL;
        +	GEN_SESSION_CB cb = def_generate_session_id;
        +
        +	if ((ss=SSL_SESSION_new()) == NULL) return(0);
        +
        +	/* If the context has a default timeout, use it */
        +	if (s->session_ctx->session_timeout == 0)
        +		ss->timeout=SSL_get_default_timeout(s);
        +	else
        +		ss->timeout=s->session_ctx->session_timeout;
        +
        +	if (s->session != NULL)
        +		{
        +		SSL_SESSION_free(s->session);
        +		s->session=NULL;
        +		}
        +
        +	if (session)
        +		{
        +		if (s->version == SSL2_VERSION)
        +			{
        +			ss->ssl_version=SSL2_VERSION;
        +			ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
        +			}
        +		else if (s->version == SSL3_VERSION)
        +			{
        +			ss->ssl_version=SSL3_VERSION;
        +			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
        +			}
        +		else if (s->version == TLS1_VERSION)
        +			{
        +			ss->ssl_version=TLS1_VERSION;
        +			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
        +			}
        +		else if (s->version == TLS1_1_VERSION)
        +			{
        +			ss->ssl_version=TLS1_1_VERSION;
        +			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
        +			}
        +		else if (s->version == TLS1_2_VERSION)
        +			{
        +			ss->ssl_version=TLS1_2_VERSION;
        +			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
        +			}
        +		else if (s->version == DTLS1_BAD_VER)
        +			{
        +			ss->ssl_version=DTLS1_BAD_VER;
        +			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
        +			}
        +		else if (s->version == DTLS1_VERSION)
        +			{
        +			ss->ssl_version=DTLS1_VERSION;
        +			ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
        +			}
        +		else
        +			{
        +			SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
        +			SSL_SESSION_free(ss);
        +			return(0);
        +			}
        +#ifndef OPENSSL_NO_TLSEXT
        +		/* If RFC4507 ticket use empty session ID */
        +		if (s->tlsext_ticket_expected)
        +			{
        +			ss->session_id_length = 0;
        +			goto sess_id_done;
        +			}
        +#endif
        +		/* Choose which callback will set the session ID */
        +		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
        +		if(s->generate_session_id)
        +			cb = s->generate_session_id;
        +		else if(s->session_ctx->generate_session_id)
        +			cb = s->session_ctx->generate_session_id;
        +		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
        +		/* Choose a session ID */
        +		tmp = ss->session_id_length;
        +		if(!cb(s, ss->session_id, &tmp))
        +			{
        +			/* The callback failed */
        +			SSLerr(SSL_F_SSL_GET_NEW_SESSION,
        +				SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
        +			SSL_SESSION_free(ss);
        +			return(0);
        +			}
        +		/* Don't allow the callback to set the session length to zero.
        +		 * nor set it higher than it was. */
        +		if(!tmp || (tmp > ss->session_id_length))
        +			{
        +			/* The callback set an illegal length */
        +			SSLerr(SSL_F_SSL_GET_NEW_SESSION,
        +				SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
        +			SSL_SESSION_free(ss);
        +			return(0);
        +			}
        +		/* If the session length was shrunk and we're SSLv2, pad it */
        +		if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
        +			memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
        +		else
        +			ss->session_id_length = tmp;
        +		/* Finally, check for a conflict */
        +		if(SSL_has_matching_session_id(s, ss->session_id,
        +						ss->session_id_length))
        +			{
        +			SSLerr(SSL_F_SSL_GET_NEW_SESSION,
        +				SSL_R_SSL_SESSION_ID_CONFLICT);
        +			SSL_SESSION_free(ss);
        +			return(0);
        +			}
        +#ifndef OPENSSL_NO_TLSEXT
        +		sess_id_done:
        +		if (s->tlsext_hostname) {
        +			ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
        +			if (ss->tlsext_hostname == NULL) {
        +				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
        +				SSL_SESSION_free(ss);
        +				return 0;
        +				}
        +			}
        +#ifndef OPENSSL_NO_EC
        +		if (s->tlsext_ecpointformatlist)
        +			{
        +			if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
        +			if ((ss->tlsext_ecpointformatlist = OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
        +				SSL_SESSION_free(ss);
        +				return 0;
        +				}
        +			ss->tlsext_ecpointformatlist_length = s->tlsext_ecpointformatlist_length;
        +			memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
        +			}
        +		if (s->tlsext_ellipticcurvelist)
        +			{
        +			if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
        +			if ((ss->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
        +				{
        +				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
        +				SSL_SESSION_free(ss);
        +				return 0;
        +				}
        +			ss->tlsext_ellipticcurvelist_length = s->tlsext_ellipticcurvelist_length;
        +			memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
        +			}
        +#endif
        +#endif
        +		}
        +	else
        +		{
        +		ss->session_id_length=0;
        +		}
        +
        +	if (s->sid_ctx_length > sizeof ss->sid_ctx)
        +		{
        +		SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
        +		SSL_SESSION_free(ss);
        +		return 0;
        +		}
        +	memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length);
        +	ss->sid_ctx_length=s->sid_ctx_length;
        +	s->session=ss;
        +	ss->ssl_version=s->version;
        +	ss->verify_result = X509_V_OK;
        +
        +	return(1);
        +	}
        +
        +/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
        + * connection. It is only called by servers.
        + *
        + *   session_id: points at the session ID in the ClientHello. This code will
        + *       read past the end of this in order to parse out the session ticket
        + *       extension, if any.
        + *   len: the length of the session ID.
        + *   limit: a pointer to the first byte after the ClientHello.
        + *
        + * Returns:
        + *   -1: error
        + *    0: a session may have been found.
        + *
        + * Side effects:
        + *   - If a session is found then s->session is pointed at it (after freeing an
        + *     existing session if need be) and s->verify_result is set from the session.
        + *   - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
        + *     if the server should issue a new session ticket (to 0 otherwise).
        + */
        +int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
        +			const unsigned char *limit)
        +	{
        +	/* This is used only by servers. */
        +
        +	SSL_SESSION *ret=NULL;
        +	int fatal = 0;
        +	int try_session_cache = 1;
        +#ifndef OPENSSL_NO_TLSEXT
        +	int r;
        +#endif
        +
        +	if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
        +		goto err;
        +
        +	if (len == 0)
        +		try_session_cache = 0;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +	r = tls1_process_ticket(s, session_id, len, limit, &ret); /* sets s->tlsext_ticket_expected */
        +	switch (r)
        +		{
        +	case -1: /* Error during processing */
        +		fatal = 1;
        +		goto err;
        +	case 0: /* No ticket found */
        +	case 1: /* Zero length ticket found */
        +		break; /* Ok to carry on processing session id. */
        +	case 2: /* Ticket found but not decrypted. */
        +	case 3: /* Ticket decrypted, *ret has been set. */
        +		try_session_cache = 0;
        +		break;
        +	default:
        +		abort();
        +		}
        +#endif
        +
        +	if (try_session_cache &&
        +	    ret == NULL &&
        +	    !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
        +		{
        +		SSL_SESSION data;
        +		data.ssl_version=s->version;
        +		data.session_id_length=len;
        +		if (len == 0)
        +			return 0;
        +		memcpy(data.session_id,session_id,len);
        +		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
        +		ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
        +		if (ret != NULL)
        +			{
        +			/* don't allow other threads to steal it: */
        +			CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
        +			}
        +		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
        +		if (ret == NULL)
        +			s->session_ctx->stats.sess_miss++;
        +		}
        +
        +	if (try_session_cache &&
        +	    ret == NULL &&
        +	    s->session_ctx->get_session_cb != NULL)
        +		{
        +		int copy=1;
        +	
        +		if ((ret=s->session_ctx->get_session_cb(s,session_id,len,&copy)))
        +			{
        +			s->session_ctx->stats.sess_cb_hit++;
        +
        +			/* Increment reference count now if the session callback
        +			 * asks us to do so (note that if the session structures
        +			 * returned by the callback are shared between threads,
        +			 * it must handle the reference count itself [i.e. copy == 0],
        +			 * or things won't be thread-safe). */
        +			if (copy)
        +				CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
        +
        +			/* Add the externally cached session to the internal
        +			 * cache as well if and only if we are supposed to. */
        +			if(!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
        +				/* The following should not return 1, otherwise,
        +				 * things are very strange */
        +				SSL_CTX_add_session(s->session_ctx,ret);
        +			}
        +		}
        +
        +	if (ret == NULL)
        +		goto err;
        +
        +	/* Now ret is non-NULL and we own one of its reference counts. */
        +
        +	if (ret->sid_ctx_length != s->sid_ctx_length
        +	    || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
        +		{
        +		/* We have the session requested by the client, but we don't
        +		 * want to use it in this context. */
        +		goto err; /* treat like cache miss */
        +		}
        +	
        +	if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
        +		{
        +		/* We can't be sure if this session is being used out of
        +		 * context, which is especially important for SSL_VERIFY_PEER.
        +		 * The application should have used SSL[_CTX]_set_session_id_context.
        +		 *
        +		 * For this error case, we generate an error instead of treating
        +		 * the event like a cache miss (otherwise it would be easy for
        +		 * applications to effectively disable the session cache by
        +		 * accident without anyone noticing).
        +		 */
        +		
        +		SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
        +		fatal = 1;
        +		goto err;
        +		}
        +
        +	if (ret->cipher == NULL)
        +		{
        +		unsigned char buf[5],*p;
        +		unsigned long l;
        +
        +		p=buf;
        +		l=ret->cipher_id;
        +		l2n(l,p);
        +		if ((ret->ssl_version>>8) >= SSL3_VERSION_MAJOR)
        +			ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
        +		else 
        +			ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
        +		if (ret->cipher == NULL)
        +			goto err;
        +		}
        +
        +	if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
        +		{
        +		s->session_ctx->stats.sess_timeout++;
        +		if (try_session_cache)
        +			{
        +			/* session was from the cache, so remove it */
        +			SSL_CTX_remove_session(s->session_ctx,ret);
        +			}
        +		goto err;
        +		}
        +
        +	s->session_ctx->stats.sess_hit++;
        +
        +	if (s->session != NULL)
        +		SSL_SESSION_free(s->session);
        +	s->session=ret;
        +	s->verify_result = s->session->verify_result;
        +	return 1;
        +
        + err:
        +	if (ret != NULL)
        +		{
        +		SSL_SESSION_free(ret);
        +#ifndef OPENSSL_NO_TLSEXT
        +		if (!try_session_cache)
        +			{
        +			/* The session was from a ticket, so we should
        +			 * issue a ticket for the new session */
        +			s->tlsext_ticket_expected = 1;
        +			}
        +#endif
        +		}
        +	if (fatal)
        +		return -1;
        +	else
        +		return 0;
        +	}
        +
        +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
        +	{
        +	int ret=0;
        +	SSL_SESSION *s;
        +
        +	/* add just 1 reference count for the SSL_CTX's session cache
        +	 * even though it has two ways of access: each session is in a
        +	 * doubly linked list and an lhash */
        +	CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
        +	/* if session c is in already in cache, we take back the increment later */
        +
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +	s=lh_SSL_SESSION_insert(ctx->sessions,c);
        +	
        +	/* s != NULL iff we already had a session with the given PID.
        +	 * In this case, s == c should hold (then we did not really modify
        +	 * ctx->sessions), or we're in trouble. */
        +	if (s != NULL && s != c)
        +		{
        +		/* We *are* in trouble ... */
        +		SSL_SESSION_list_remove(ctx,s);
        +		SSL_SESSION_free(s);
        +		/* ... so pretend the other session did not exist in cache
        +		 * (we cannot handle two SSL_SESSION structures with identical
        +		 * session ID in the same cache, which could happen e.g. when
        +		 * two threads concurrently obtain the same session from an external
        +		 * cache) */
        +		s = NULL;
        +		}
        +
        + 	/* Put at the head of the queue unless it is already in the cache */
        +	if (s == NULL)
        +		SSL_SESSION_list_add(ctx,c);
        +
        +	if (s != NULL)
        +		{
        +		/* existing cache entry -- decrement previously incremented reference
        +		 * count because it already takes into account the cache */
        +
        +		SSL_SESSION_free(s); /* s == c */
        +		ret=0;
        +		}
        +	else
        +		{
        +		/* new cache entry -- remove old ones if cache has become too large */
        +		
        +		ret=1;
        +
        +		if (SSL_CTX_sess_get_cache_size(ctx) > 0)
        +			{
        +			while (SSL_CTX_sess_number(ctx) >
        +				SSL_CTX_sess_get_cache_size(ctx))
        +				{
        +				if (!remove_session_lock(ctx,
        +					ctx->session_cache_tail, 0))
        +					break;
        +				else
        +					ctx->stats.sess_cache_full++;
        +				}
        +			}
        +		}
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +	return(ret);
        +	}
        +
        +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
        +{
        +	return remove_session_lock(ctx, c, 1);
        +}
        +
        +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
        +	{
        +	SSL_SESSION *r;
        +	int ret=0;
        +
        +	if ((c != NULL) && (c->session_id_length != 0))
        +		{
        +		if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +		if ((r = lh_SSL_SESSION_retrieve(ctx->sessions,c)) == c)
        +			{
        +			ret=1;
        +			r=lh_SSL_SESSION_delete(ctx->sessions,c);
        +			SSL_SESSION_list_remove(ctx,c);
        +			}
        +
        +		if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +
        +		if (ret)
        +			{
        +			r->not_resumable=1;
        +			if (ctx->remove_session_cb != NULL)
        +				ctx->remove_session_cb(ctx,r);
        +			SSL_SESSION_free(r);
        +			}
        +		}
        +	else
        +		ret=0;
        +	return(ret);
        +	}
        +
        +void SSL_SESSION_free(SSL_SESSION *ss)
        +	{
        +	int i;
        +
        +	if(ss == NULL)
        +	    return;
        +
        +	i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);
        +#ifdef REF_PRINT
        +	REF_PRINT("SSL_SESSION",ss);
        +#endif
        +	if (i > 0) return;
        +#ifdef REF_CHECK
        +	if (i < 0)
        +		{
        +		fprintf(stderr,"SSL_SESSION_free, bad reference count\n");
        +		abort(); /* ok */
        +		}
        +#endif
        +
        +	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
        +
        +	OPENSSL_cleanse(ss->key_arg,sizeof ss->key_arg);
        +	OPENSSL_cleanse(ss->master_key,sizeof ss->master_key);
        +	OPENSSL_cleanse(ss->session_id,sizeof ss->session_id);
        +	if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
        +	if (ss->peer != NULL) X509_free(ss->peer);
        +	if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
        +	if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
        +#ifndef OPENSSL_NO_EC
        +	ss->tlsext_ecpointformatlist_length = 0;
        +	if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
        +	ss->tlsext_ellipticcurvelist_length = 0;
        +	if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
        +#endif /* OPENSSL_NO_EC */
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +	if (ss->psk_identity_hint != NULL)
        +		OPENSSL_free(ss->psk_identity_hint);
        +	if (ss->psk_identity != NULL)
        +		OPENSSL_free(ss->psk_identity);
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	if (ss->srp_username != NULL)
        +		OPENSSL_free(ss->srp_username);
        +#endif
        +	OPENSSL_cleanse(ss,sizeof(*ss));
        +	OPENSSL_free(ss);
        +	}
        +
        +int SSL_set_session(SSL *s, SSL_SESSION *session)
        +	{
        +	int ret=0;
        +	const SSL_METHOD *meth;
        +
        +	if (session != NULL)
        +		{
        +		meth=s->ctx->method->get_ssl_method(session->ssl_version);
        +		if (meth == NULL)
        +			meth=s->method->get_ssl_method(session->ssl_version);
        +		if (meth == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);
        +			return(0);
        +			}
        +
        +		if (meth != s->method)
        +			{
        +			if (!SSL_set_ssl_method(s,meth))
        +				return(0);
        +			}
        +
        +#ifndef OPENSSL_NO_KRB5
        +                if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
        +                    session->krb5_client_princ_len > 0)
        +                {
        +                    s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
        +                    memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
        +                            session->krb5_client_princ_len);
        +                    s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
        +                }
        +#endif /* OPENSSL_NO_KRB5 */
        +
        +		/* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
        +		CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
        +		if (s->session != NULL)
        +			SSL_SESSION_free(s->session);
        +		s->session=session;
        +		s->verify_result = s->session->verify_result;
        +		/* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
        +		ret=1;
        +		}
        +	else
        +		{
        +		if (s->session != NULL)
        +			{
        +			SSL_SESSION_free(s->session);
        +			s->session=NULL;
        +			}
        +
        +		meth=s->ctx->method;
        +		if (meth != s->method)
        +			{
        +			if (!SSL_set_ssl_method(s,meth))
        +				return(0);
        +			}
        +		ret=1;
        +		}
        +	return(ret);
        +	}
        +
        +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
        +	{
        +	if (s == NULL) return(0);
        +	s->timeout=t;
        +	return(1);
        +	}
        +
        +long SSL_SESSION_get_timeout(const SSL_SESSION *s)
        +	{
        +	if (s == NULL) return(0);
        +	return(s->timeout);
        +	}
        +
        +long SSL_SESSION_get_time(const SSL_SESSION *s)
        +	{
        +	if (s == NULL) return(0);
        +	return(s->time);
        +	}
        +
        +long SSL_SESSION_set_time(SSL_SESSION *s, long t)
        +	{
        +	if (s == NULL) return(0);
        +	s->time=t;
        +	return(t);
        +	}
        +
        +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
        +	{
        +	return s->peer;
        +	}
        +
        +int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
        +			       unsigned int sid_ctx_len)
        +	{
        +	if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
        +		{
        +		SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
        +		return 0;
        +		}
        +	s->sid_ctx_length=sid_ctx_len;
        +	memcpy(s->sid_ctx,sid_ctx,sid_ctx_len);
        +
        +	return 1;
        +	}
        +
        +long SSL_CTX_set_timeout(SSL_CTX *s, long t)
        +	{
        +	long l;
        +	if (s == NULL) return(0);
        +	l=s->session_timeout;
        +	s->session_timeout=t;
        +	return(l);
        +	}
        +
        +long SSL_CTX_get_timeout(const SSL_CTX *s)
        +	{
        +	if (s == NULL) return(0);
        +	return(s->session_timeout);
        +	}
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
        +	STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
        +	{
        +	if (s == NULL) return(0);
        +	s->tls_session_secret_cb = tls_session_secret_cb;
        +	s->tls_session_secret_cb_arg = arg;
        +	return(1);
        +	}
        +
        +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
        +				  void *arg)
        +	{
        +	if (s == NULL) return(0);
        +	s->tls_session_ticket_ext_cb = cb;
        +	s->tls_session_ticket_ext_cb_arg = arg;
        +	return(1);
        +	}
        +
        +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
        +	{
        +	if (s->version >= TLS1_VERSION)
        +		{
        +		if (s->tlsext_session_ticket)
        +			{
        +			OPENSSL_free(s->tlsext_session_ticket);
        +			s->tlsext_session_ticket = NULL;
        +			}
        +
        +		s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
        +		if (!s->tlsext_session_ticket)
        +			{
        +			SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
        +			return 0;
        +			}
        +
        +		if (ext_data)
        +			{
        +			s->tlsext_session_ticket->length = ext_len;
        +			s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
        +			memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
        +			}
        +		else
        +			{
        +			s->tlsext_session_ticket->length = 0;
        +			s->tlsext_session_ticket->data = NULL;
        +			}
        +
        +		return 1;
        +		}
        +
        +	return 0;
        +	}
        +#endif /* OPENSSL_NO_TLSEXT */
        +
        +typedef struct timeout_param_st
        +	{
        +	SSL_CTX *ctx;
        +	long time;
        +	LHASH_OF(SSL_SESSION) *cache;
        +	} TIMEOUT_PARAM;
        +
        +static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p)
        +	{
        +	if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
        +		{
        +		/* The reason we don't call SSL_CTX_remove_session() is to
        +		 * save on locking overhead */
        +		(void)lh_SSL_SESSION_delete(p->cache,s);
        +		SSL_SESSION_list_remove(p->ctx,s);
        +		s->not_resumable=1;
        +		if (p->ctx->remove_session_cb != NULL)
        +			p->ctx->remove_session_cb(p->ctx,s);
        +		SSL_SESSION_free(s);
        +		}
        +	}
        +
        +static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM)
        +
        +void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
        +	{
        +	unsigned long i;
        +	TIMEOUT_PARAM tp;
        +
        +	tp.ctx=s;
        +	tp.cache=s->sessions;
        +	if (tp.cache == NULL) return;
        +	tp.time=t;
        +	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +	i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load;
        +	CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0;
        +	lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout),
        +				 TIMEOUT_PARAM, &tp);
        +	CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i;
        +	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +	}
        +
        +int ssl_clear_bad_session(SSL *s)
        +	{
        +	if (	(s->session != NULL) &&
        +		!(s->shutdown & SSL_SENT_SHUTDOWN) &&
        +		!(SSL_in_init(s) || SSL_in_before(s)))
        +		{
        +		SSL_CTX_remove_session(s->ctx,s->session);
        +		return(1);
        +		}
        +	else
        +		return(0);
        +	}
        +
        +/* locked by SSL_CTX in the calling function */
        +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
        +	{
        +	if ((s->next == NULL) || (s->prev == NULL)) return;
        +
        +	if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))
        +		{ /* last element in list */
        +		if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
        +			{ /* only one element in list */
        +			ctx->session_cache_head=NULL;
        +			ctx->session_cache_tail=NULL;
        +			}
        +		else
        +			{
        +			ctx->session_cache_tail=s->prev;
        +			s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);
        +			}
        +		}
        +	else
        +		{
        +		if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
        +			{ /* first element in list */
        +			ctx->session_cache_head=s->next;
        +			s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);
        +			}
        +		else
        +			{ /* middle of list */
        +			s->next->prev=s->prev;
        +			s->prev->next=s->next;
        +			}
        +		}
        +	s->prev=s->next=NULL;
        +	}
        +
        +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
        +	{
        +	if ((s->next != NULL) && (s->prev != NULL))
        +		SSL_SESSION_list_remove(ctx,s);
        +
        +	if (ctx->session_cache_head == NULL)
        +		{
        +		ctx->session_cache_head=s;
        +		ctx->session_cache_tail=s;
        +		s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
        +		s->next=(SSL_SESSION *)&(ctx->session_cache_tail);
        +		}
        +	else
        +		{
        +		s->next=ctx->session_cache_head;
        +		s->next->prev=s;
        +		s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
        +		ctx->session_cache_head=s;
        +		}
        +	}
        +
        +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
        +	int (*cb)(struct ssl_st *ssl,SSL_SESSION *sess))
        +	{
        +	ctx->new_session_cb=cb;
        +	}
        +
        +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess)
        +	{
        +	return ctx->new_session_cb;
        +	}
        +
        +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
        +	void (*cb)(SSL_CTX *ctx,SSL_SESSION *sess))
        +	{
        +	ctx->remove_session_cb=cb;
        +	}
        +
        +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx,SSL_SESSION *sess)
        +	{
        +	return ctx->remove_session_cb;
        +	}
        +
        +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
        +	SSL_SESSION *(*cb)(struct ssl_st *ssl,
        +	         unsigned char *data,int len,int *copy))
        +	{
        +	ctx->get_session_cb=cb;
        +	}
        +
        +SSL_SESSION * (*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl,
        +	         unsigned char *data,int len,int *copy)
        +	{
        +	return ctx->get_session_cb;
        +	}
        +
        +void SSL_CTX_set_info_callback(SSL_CTX *ctx, 
        +	void (*cb)(const SSL *ssl,int type,int val))
        +	{
        +	ctx->info_callback=cb;
        +	}
        +
        +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val)
        +	{
        +	return ctx->info_callback;
        +	}
        +
        +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
        +	int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey))
        +	{
        +	ctx->client_cert_cb=cb;
        +	}
        +
        +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PKEY **pkey)
        +	{
        +	return ctx->client_cert_cb;
        +	}
        +
        +#ifndef OPENSSL_NO_ENGINE
        +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
        +	{
        +	if (!ENGINE_init(e))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
        +		return 0;
        +		}
        +	if(!ENGINE_get_ssl_client_cert_function(e))
        +		{
        +		SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD);
        +		ENGINE_finish(e);
        +		return 0;
        +		}
        +	ctx->client_cert_engine = e;
        +	return 1;
        +	}
        +#endif
        +
        +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
        +	int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
        +	{
        +	ctx->app_gen_cookie_cb=cb;
        +	}
        +
        +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
        +	int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len))
        +	{
        +	ctx->app_verify_cookie_cb=cb;
        +	}
        +
        +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
        diff --git a/vendor/openssl/openssl/ssl/ssl_stat.c b/vendor/openssl/openssl/ssl/ssl_stat.c
        new file mode 100644
        index 000000000..144b81e55
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_stat.c
        @@ -0,0 +1,567 @@
        +/* ssl/ssl_stat.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 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +
        +const char *SSL_state_string_long(const SSL *s)
        +	{
        +	const char *str;
        +
        +	switch (s->state)
        +		{
        +case SSL_ST_BEFORE: str="before SSL initialization"; break;
        +case SSL_ST_ACCEPT: str="before accept initialization"; break;
        +case SSL_ST_CONNECT: str="before connect initialization"; break;
        +case SSL_ST_OK: str="SSL negotiation finished successfully"; break;
        +case SSL_ST_RENEGOTIATE:	str="SSL renegotiate ciphers"; break;
        +case SSL_ST_BEFORE|SSL_ST_CONNECT: str="before/connect initialization"; break;
        +case SSL_ST_OK|SSL_ST_CONNECT: str="ok/connect SSL initialization"; break;
        +case SSL_ST_BEFORE|SSL_ST_ACCEPT: str="before/accept initialization"; break;
        +case SSL_ST_OK|SSL_ST_ACCEPT: str="ok/accept SSL initialization"; break;
        +#ifndef OPENSSL_NO_SSL2
        +case SSL2_ST_CLIENT_START_ENCRYPTION: str="SSLv2 client start encryption"; break;
        +case SSL2_ST_SERVER_START_ENCRYPTION: str="SSLv2 server start encryption"; break;
        +case SSL2_ST_SEND_CLIENT_HELLO_A: str="SSLv2 write client hello A"; break;
        +case SSL2_ST_SEND_CLIENT_HELLO_B: str="SSLv2 write client hello B"; break;
        +case SSL2_ST_GET_SERVER_HELLO_A: str="SSLv2 read server hello A"; break;
        +case SSL2_ST_GET_SERVER_HELLO_B: str="SSLv2 read server hello B"; break;
        +case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: str="SSLv2 write client master key A"; break;
        +case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: str="SSLv2 write client master key B"; break;
        +case SSL2_ST_SEND_CLIENT_FINISHED_A: str="SSLv2 write client finished A"; break;
        +case SSL2_ST_SEND_CLIENT_FINISHED_B: str="SSLv2 write client finished B"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: str="SSLv2 write client certificate A"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: str="SSLv2 write client certificate B"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: str="SSLv2 write client certificate C"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: str="SSLv2 write client certificate D"; break;
        +case SSL2_ST_GET_SERVER_VERIFY_A: str="SSLv2 read server verify A"; break;
        +case SSL2_ST_GET_SERVER_VERIFY_B: str="SSLv2 read server verify B"; break;
        +case SSL2_ST_GET_SERVER_FINISHED_A: str="SSLv2 read server finished A"; break;
        +case SSL2_ST_GET_SERVER_FINISHED_B: str="SSLv2 read server finished B"; break;
        +case SSL2_ST_GET_CLIENT_HELLO_A: str="SSLv2 read client hello A"; break;
        +case SSL2_ST_GET_CLIENT_HELLO_B: str="SSLv2 read client hello B"; break;
        +case SSL2_ST_GET_CLIENT_HELLO_C: str="SSLv2 read client hello C"; break;
        +case SSL2_ST_SEND_SERVER_HELLO_A: str="SSLv2 write server hello A"; break;
        +case SSL2_ST_SEND_SERVER_HELLO_B: str="SSLv2 write server hello B"; break;
        +case SSL2_ST_GET_CLIENT_MASTER_KEY_A: str="SSLv2 read client master key A"; break;
        +case SSL2_ST_GET_CLIENT_MASTER_KEY_B: str="SSLv2 read client master key B"; break;
        +case SSL2_ST_SEND_SERVER_VERIFY_A: str="SSLv2 write server verify A"; break;
        +case SSL2_ST_SEND_SERVER_VERIFY_B: str="SSLv2 write server verify B"; break;
        +case SSL2_ST_SEND_SERVER_VERIFY_C: str="SSLv2 write server verify C"; break;
        +case SSL2_ST_GET_CLIENT_FINISHED_A: str="SSLv2 read client finished A"; break;
        +case SSL2_ST_GET_CLIENT_FINISHED_B: str="SSLv2 read client finished B"; break;
        +case SSL2_ST_SEND_SERVER_FINISHED_A: str="SSLv2 write server finished A"; break;
        +case SSL2_ST_SEND_SERVER_FINISHED_B: str="SSLv2 write server finished B"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: str="SSLv2 write request certificate A"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: str="SSLv2 write request certificate B"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: str="SSLv2 write request certificate C"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: str="SSLv2 write request certificate D"; break;
        +case SSL2_ST_X509_GET_SERVER_CERTIFICATE: str="SSLv2 X509 read server certificate"; break;
        +case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: str="SSLv2 X509 read client certificate"; break;
        +#endif
        +
        +#ifndef OPENSSL_NO_SSL3
        +/* SSLv3 additions */
        +case SSL3_ST_CW_CLNT_HELLO_A:	str="SSLv3 write client hello A"; break;
        +case SSL3_ST_CW_CLNT_HELLO_B:	str="SSLv3 write client hello B"; break;
        +case SSL3_ST_CR_SRVR_HELLO_A:	str="SSLv3 read server hello A"; break;
        +case SSL3_ST_CR_SRVR_HELLO_B:	str="SSLv3 read server hello B"; break;
        +case SSL3_ST_CR_CERT_A:		str="SSLv3 read server certificate A"; break;
        +case SSL3_ST_CR_CERT_B:		str="SSLv3 read server certificate B"; break;
        +case SSL3_ST_CR_KEY_EXCH_A:	str="SSLv3 read server key exchange A"; break;
        +case SSL3_ST_CR_KEY_EXCH_B:	str="SSLv3 read server key exchange B"; break;
        +case SSL3_ST_CR_CERT_REQ_A:	str="SSLv3 read server certificate request A"; break;
        +case SSL3_ST_CR_CERT_REQ_B:	str="SSLv3 read server certificate request B"; break;
        +case SSL3_ST_CR_SESSION_TICKET_A: str="SSLv3 read server session ticket A";break;
        +case SSL3_ST_CR_SESSION_TICKET_B: str="SSLv3 read server session ticket B";break;
        +case SSL3_ST_CR_SRVR_DONE_A:	str="SSLv3 read server done A"; break;
        +case SSL3_ST_CR_SRVR_DONE_B:	str="SSLv3 read server done B"; break;
        +case SSL3_ST_CW_CERT_A:		str="SSLv3 write client certificate A"; break;
        +case SSL3_ST_CW_CERT_B:		str="SSLv3 write client certificate B"; break;
        +case SSL3_ST_CW_CERT_C:		str="SSLv3 write client certificate C"; break;
        +case SSL3_ST_CW_CERT_D:		str="SSLv3 write client certificate D"; break;
        +case SSL3_ST_CW_KEY_EXCH_A:	str="SSLv3 write client key exchange A"; break;
        +case SSL3_ST_CW_KEY_EXCH_B:	str="SSLv3 write client key exchange B"; break;
        +case SSL3_ST_CW_CERT_VRFY_A:	str="SSLv3 write certificate verify A"; break;
        +case SSL3_ST_CW_CERT_VRFY_B:	str="SSLv3 write certificate verify B"; break;
        +
        +case SSL3_ST_CW_CHANGE_A:
        +case SSL3_ST_SW_CHANGE_A:	str="SSLv3 write change cipher spec A"; break;
        +case SSL3_ST_CW_CHANGE_B:	
        +case SSL3_ST_SW_CHANGE_B:	str="SSLv3 write change cipher spec B"; break;
        +case SSL3_ST_CW_FINISHED_A:	
        +case SSL3_ST_SW_FINISHED_A:	str="SSLv3 write finished A"; break;
        +case SSL3_ST_CW_FINISHED_B:	
        +case SSL3_ST_SW_FINISHED_B:	str="SSLv3 write finished B"; break;
        +case SSL3_ST_CR_CHANGE_A:	
        +case SSL3_ST_SR_CHANGE_A:	str="SSLv3 read change cipher spec A"; break;
        +case SSL3_ST_CR_CHANGE_B:	
        +case SSL3_ST_SR_CHANGE_B:	str="SSLv3 read change cipher spec B"; break;
        +case SSL3_ST_CR_FINISHED_A:	
        +case SSL3_ST_SR_FINISHED_A:	str="SSLv3 read finished A"; break;
        +case SSL3_ST_CR_FINISHED_B:	
        +case SSL3_ST_SR_FINISHED_B:	str="SSLv3 read finished B"; break;
        +
        +case SSL3_ST_CW_FLUSH:
        +case SSL3_ST_SW_FLUSH:		str="SSLv3 flush data"; break;
        +
        +case SSL3_ST_SR_CLNT_HELLO_A:	str="SSLv3 read client hello A"; break;
        +case SSL3_ST_SR_CLNT_HELLO_B:	str="SSLv3 read client hello B"; break;
        +case SSL3_ST_SR_CLNT_HELLO_C:	str="SSLv3 read client hello C"; break;
        +case SSL3_ST_SW_HELLO_REQ_A:	str="SSLv3 write hello request A"; break;
        +case SSL3_ST_SW_HELLO_REQ_B:	str="SSLv3 write hello request B"; break;
        +case SSL3_ST_SW_HELLO_REQ_C:	str="SSLv3 write hello request C"; break;
        +case SSL3_ST_SW_SRVR_HELLO_A:	str="SSLv3 write server hello A"; break;
        +case SSL3_ST_SW_SRVR_HELLO_B:	str="SSLv3 write server hello B"; break;
        +case SSL3_ST_SW_CERT_A:		str="SSLv3 write certificate A"; break;
        +case SSL3_ST_SW_CERT_B:		str="SSLv3 write certificate B"; break;
        +case SSL3_ST_SW_KEY_EXCH_A:	str="SSLv3 write key exchange A"; break;
        +case SSL3_ST_SW_KEY_EXCH_B:	str="SSLv3 write key exchange B"; break;
        +case SSL3_ST_SW_CERT_REQ_A:	str="SSLv3 write certificate request A"; break;
        +case SSL3_ST_SW_CERT_REQ_B:	str="SSLv3 write certificate request B"; break;
        +case SSL3_ST_SW_SESSION_TICKET_A: str="SSLv3 write session ticket A"; break;
        +case SSL3_ST_SW_SESSION_TICKET_B: str="SSLv3 write session ticket B"; break;
        +case SSL3_ST_SW_SRVR_DONE_A:	str="SSLv3 write server done A"; break;
        +case SSL3_ST_SW_SRVR_DONE_B:	str="SSLv3 write server done B"; break;
        +case SSL3_ST_SR_CERT_A:		str="SSLv3 read client certificate A"; break;
        +case SSL3_ST_SR_CERT_B:		str="SSLv3 read client certificate B"; break;
        +case SSL3_ST_SR_KEY_EXCH_A:	str="SSLv3 read client key exchange A"; break;
        +case SSL3_ST_SR_KEY_EXCH_B:	str="SSLv3 read client key exchange B"; break;
        +case SSL3_ST_SR_CERT_VRFY_A:	str="SSLv3 read certificate verify A"; break;
        +case SSL3_ST_SR_CERT_VRFY_B:	str="SSLv3 read certificate verify B"; break;
        +#endif
        +
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +/* SSLv2/v3 compatibility states */
        +/* client */
        +case SSL23_ST_CW_CLNT_HELLO_A:	str="SSLv2/v3 write client hello A"; break;
        +case SSL23_ST_CW_CLNT_HELLO_B:	str="SSLv2/v3 write client hello B"; break;
        +case SSL23_ST_CR_SRVR_HELLO_A:	str="SSLv2/v3 read server hello A"; break;
        +case SSL23_ST_CR_SRVR_HELLO_B:	str="SSLv2/v3 read server hello B"; break;
        +/* server */
        +case SSL23_ST_SR_CLNT_HELLO_A:	str="SSLv2/v3 read client hello A"; break;
        +case SSL23_ST_SR_CLNT_HELLO_B:	str="SSLv2/v3 read client hello B"; break;
        +#endif
        +
        +/* DTLS */
        +case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DTLS1 read hello verify request A"; break;
        +case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DTLS1 read hello verify request B"; break;
        +case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: str="DTLS1 write hello verify request A"; break;
        +case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: str="DTLS1 write hello verify request B"; break;
        +
        +default:	str="unknown state"; break;
        +		}
        +	return(str);
        +	}
        +
        +const char *SSL_rstate_string_long(const SSL *s)
        +	{
        +	const char *str;
        +
        +	switch (s->rstate)
        +		{
        +	case SSL_ST_READ_HEADER: str="read header"; break;
        +	case SSL_ST_READ_BODY: str="read body"; break;
        +	case SSL_ST_READ_DONE: str="read done"; break;
        +	default: str="unknown"; break;
        +		}
        +	return(str);
        +	}
        +
        +const char *SSL_state_string(const SSL *s)
        +	{
        +	const char *str;
        +
        +	switch (s->state)
        +		{
        +case SSL_ST_BEFORE:				str="PINIT "; break;
        +case SSL_ST_ACCEPT:				str="AINIT "; break;
        +case SSL_ST_CONNECT:				str="CINIT "; break;
        +case SSL_ST_OK:			 		str="SSLOK "; break;
        +#ifndef OPENSSL_NO_SSL2
        +case SSL2_ST_CLIENT_START_ENCRYPTION:		str="2CSENC"; break;
        +case SSL2_ST_SERVER_START_ENCRYPTION:		str="2SSENC"; break;
        +case SSL2_ST_SEND_CLIENT_HELLO_A:		str="2SCH_A"; break;
        +case SSL2_ST_SEND_CLIENT_HELLO_B:		str="2SCH_B"; break;
        +case SSL2_ST_GET_SERVER_HELLO_A:		str="2GSH_A"; break;
        +case SSL2_ST_GET_SERVER_HELLO_B:		str="2GSH_B"; break;
        +case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:		str="2SCMKA"; break;
        +case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:		str="2SCMKB"; break;
        +case SSL2_ST_SEND_CLIENT_FINISHED_A:		str="2SCF_A"; break;
        +case SSL2_ST_SEND_CLIENT_FINISHED_B:		str="2SCF_B"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:		str="2SCC_A"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:		str="2SCC_B"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:		str="2SCC_C"; break;
        +case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:		str="2SCC_D"; break;
        +case SSL2_ST_GET_SERVER_VERIFY_A:		str="2GSV_A"; break;
        +case SSL2_ST_GET_SERVER_VERIFY_B:		str="2GSV_B"; break;
        +case SSL2_ST_GET_SERVER_FINISHED_A:		str="2GSF_A"; break;
        +case SSL2_ST_GET_SERVER_FINISHED_B:		str="2GSF_B"; break;
        +case SSL2_ST_GET_CLIENT_HELLO_A:		str="2GCH_A"; break;
        +case SSL2_ST_GET_CLIENT_HELLO_B:		str="2GCH_B"; break;
        +case SSL2_ST_GET_CLIENT_HELLO_C:		str="2GCH_C"; break;
        +case SSL2_ST_SEND_SERVER_HELLO_A:		str="2SSH_A"; break;
        +case SSL2_ST_SEND_SERVER_HELLO_B:		str="2SSH_B"; break;
        +case SSL2_ST_GET_CLIENT_MASTER_KEY_A:		str="2GCMKA"; break;
        +case SSL2_ST_GET_CLIENT_MASTER_KEY_B:		str="2GCMKA"; break;
        +case SSL2_ST_SEND_SERVER_VERIFY_A:		str="2SSV_A"; break;
        +case SSL2_ST_SEND_SERVER_VERIFY_B:		str="2SSV_B"; break;
        +case SSL2_ST_SEND_SERVER_VERIFY_C:		str="2SSV_C"; break;
        +case SSL2_ST_GET_CLIENT_FINISHED_A:		str="2GCF_A"; break;
        +case SSL2_ST_GET_CLIENT_FINISHED_B:		str="2GCF_B"; break;
        +case SSL2_ST_SEND_SERVER_FINISHED_A:		str="2SSF_A"; break;
        +case SSL2_ST_SEND_SERVER_FINISHED_B:		str="2SSF_B"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:	str="2SRC_A"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:	str="2SRC_B"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:	str="2SRC_C"; break;
        +case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:	str="2SRC_D"; break;
        +case SSL2_ST_X509_GET_SERVER_CERTIFICATE:	str="2X9GSC"; break;
        +case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:	str="2X9GCC"; break;
        +#endif
        +
        +#ifndef OPENSSL_NO_SSL3
        +/* SSLv3 additions */
        +case SSL3_ST_SW_FLUSH:
        +case SSL3_ST_CW_FLUSH:				str="3FLUSH"; break;
        +case SSL3_ST_CW_CLNT_HELLO_A:			str="3WCH_A"; break;
        +case SSL3_ST_CW_CLNT_HELLO_B:			str="3WCH_B"; break;
        +case SSL3_ST_CR_SRVR_HELLO_A:			str="3RSH_A"; break;
        +case SSL3_ST_CR_SRVR_HELLO_B:			str="3RSH_B"; break;
        +case SSL3_ST_CR_CERT_A:				str="3RSC_A"; break;
        +case SSL3_ST_CR_CERT_B:				str="3RSC_B"; break;
        +case SSL3_ST_CR_KEY_EXCH_A:			str="3RSKEA"; break;
        +case SSL3_ST_CR_KEY_EXCH_B:			str="3RSKEB"; break;
        +case SSL3_ST_CR_CERT_REQ_A:			str="3RCR_A"; break;
        +case SSL3_ST_CR_CERT_REQ_B:			str="3RCR_B"; break;
        +case SSL3_ST_CR_SRVR_DONE_A:			str="3RSD_A"; break;
        +case SSL3_ST_CR_SRVR_DONE_B:			str="3RSD_B"; break;
        +case SSL3_ST_CW_CERT_A:				str="3WCC_A"; break;
        +case SSL3_ST_CW_CERT_B:				str="3WCC_B"; break;
        +case SSL3_ST_CW_CERT_C:				str="3WCC_C"; break;
        +case SSL3_ST_CW_CERT_D:				str="3WCC_D"; break;
        +case SSL3_ST_CW_KEY_EXCH_A:			str="3WCKEA"; break;
        +case SSL3_ST_CW_KEY_EXCH_B:			str="3WCKEB"; break;
        +case SSL3_ST_CW_CERT_VRFY_A:			str="3WCV_A"; break;
        +case SSL3_ST_CW_CERT_VRFY_B:			str="3WCV_B"; break;
        +
        +case SSL3_ST_SW_CHANGE_A:
        +case SSL3_ST_CW_CHANGE_A:			str="3WCCSA"; break;
        +case SSL3_ST_SW_CHANGE_B:
        +case SSL3_ST_CW_CHANGE_B:			str="3WCCSB"; break;
        +case SSL3_ST_SW_FINISHED_A:
        +case SSL3_ST_CW_FINISHED_A:			str="3WFINA"; break;
        +case SSL3_ST_SW_FINISHED_B:
        +case SSL3_ST_CW_FINISHED_B:			str="3WFINB"; break;
        +case SSL3_ST_SR_CHANGE_A:
        +case SSL3_ST_CR_CHANGE_A:			str="3RCCSA"; break;
        +case SSL3_ST_SR_CHANGE_B:
        +case SSL3_ST_CR_CHANGE_B:			str="3RCCSB"; break;
        +case SSL3_ST_SR_FINISHED_A:
        +case SSL3_ST_CR_FINISHED_A:			str="3RFINA"; break;
        +case SSL3_ST_SR_FINISHED_B:
        +case SSL3_ST_CR_FINISHED_B:			str="3RFINB"; break;
        +
        +case SSL3_ST_SW_HELLO_REQ_A:			str="3WHR_A"; break;
        +case SSL3_ST_SW_HELLO_REQ_B:			str="3WHR_B"; break;
        +case SSL3_ST_SW_HELLO_REQ_C:			str="3WHR_C"; break;
        +case SSL3_ST_SR_CLNT_HELLO_A:			str="3RCH_A"; break;
        +case SSL3_ST_SR_CLNT_HELLO_B:			str="3RCH_B"; break;
        +case SSL3_ST_SR_CLNT_HELLO_C:			str="3RCH_C"; break;
        +case SSL3_ST_SW_SRVR_HELLO_A:			str="3WSH_A"; break;
        +case SSL3_ST_SW_SRVR_HELLO_B:			str="3WSH_B"; break;
        +case SSL3_ST_SW_CERT_A:				str="3WSC_A"; break;
        +case SSL3_ST_SW_CERT_B:				str="3WSC_B"; break;
        +case SSL3_ST_SW_KEY_EXCH_A:			str="3WSKEA"; break;
        +case SSL3_ST_SW_KEY_EXCH_B:			str="3WSKEB"; break;
        +case SSL3_ST_SW_CERT_REQ_A:			str="3WCR_A"; break;
        +case SSL3_ST_SW_CERT_REQ_B:			str="3WCR_B"; break;
        +case SSL3_ST_SW_SRVR_DONE_A:			str="3WSD_A"; break;
        +case SSL3_ST_SW_SRVR_DONE_B:			str="3WSD_B"; break;
        +case SSL3_ST_SR_CERT_A:				str="3RCC_A"; break;
        +case SSL3_ST_SR_CERT_B:				str="3RCC_B"; break;
        +case SSL3_ST_SR_KEY_EXCH_A:			str="3RCKEA"; break;
        +case SSL3_ST_SR_KEY_EXCH_B:			str="3RCKEB"; break;
        +case SSL3_ST_SR_CERT_VRFY_A:			str="3RCV_A"; break;
        +case SSL3_ST_SR_CERT_VRFY_B:			str="3RCV_B"; break;
        +#endif
        +
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +/* SSLv2/v3 compatibility states */
        +/* client */
        +case SSL23_ST_CW_CLNT_HELLO_A:			str="23WCHA"; break;
        +case SSL23_ST_CW_CLNT_HELLO_B:			str="23WCHB"; break;
        +case SSL23_ST_CR_SRVR_HELLO_A:			str="23RSHA"; break;
        +case SSL23_ST_CR_SRVR_HELLO_B:			str="23RSHA"; break;
        +/* server */
        +case SSL23_ST_SR_CLNT_HELLO_A:			str="23RCHA"; break;
        +case SSL23_ST_SR_CLNT_HELLO_B:			str="23RCHB"; break;
        +#endif
        +/* DTLS */
        +case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: str="DRCHVA"; break;
        +case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: str="DRCHVB"; break;
        +case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: str="DWCHVA"; break;
        +case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: str="DWCHVB"; break;
        +
        +default:					str="UNKWN "; break;
        +		}
        +	return(str);
        +	}
        +
        +const char *SSL_alert_type_string_long(int value)
        +	{
        +	value>>=8;
        +	if (value == SSL3_AL_WARNING)
        +		return("warning");
        +	else if (value == SSL3_AL_FATAL)
        +		return("fatal");
        +	else
        +		return("unknown");
        +	}
        +
        +const char *SSL_alert_type_string(int value)
        +	{
        +	value>>=8;
        +	if (value == SSL3_AL_WARNING)
        +		return("W");
        +	else if (value == SSL3_AL_FATAL)
        +		return("F");
        +	else
        +		return("U");
        +	}
        +
        +const char *SSL_alert_desc_string(int value)
        +	{
        +	const char *str;
        +
        +	switch (value & 0xff)
        +		{
        +	case SSL3_AD_CLOSE_NOTIFY:		str="CN"; break;
        +	case SSL3_AD_UNEXPECTED_MESSAGE:	str="UM"; break;
        +	case SSL3_AD_BAD_RECORD_MAC:		str="BM"; break;
        +	case SSL3_AD_DECOMPRESSION_FAILURE:	str="DF"; break;
        +	case SSL3_AD_HANDSHAKE_FAILURE:		str="HF"; break;
        +	case SSL3_AD_NO_CERTIFICATE:		str="NC"; break;
        +	case SSL3_AD_BAD_CERTIFICATE:		str="BC"; break;
        +	case SSL3_AD_UNSUPPORTED_CERTIFICATE:	str="UC"; break;
        +	case SSL3_AD_CERTIFICATE_REVOKED:	str="CR"; break;
        +	case SSL3_AD_CERTIFICATE_EXPIRED:	str="CE"; break;
        +	case SSL3_AD_CERTIFICATE_UNKNOWN:	str="CU"; break;
        +	case SSL3_AD_ILLEGAL_PARAMETER:		str="IP"; break;
        +	case TLS1_AD_DECRYPTION_FAILED:		str="DC"; break;
        +	case TLS1_AD_RECORD_OVERFLOW:		str="RO"; break;
        +	case TLS1_AD_UNKNOWN_CA:		str="CA"; break;
        +	case TLS1_AD_ACCESS_DENIED:		str="AD"; break;
        +	case TLS1_AD_DECODE_ERROR:		str="DE"; break;
        +	case TLS1_AD_DECRYPT_ERROR:		str="CY"; break;
        +	case TLS1_AD_EXPORT_RESTRICTION:	str="ER"; break;
        +	case TLS1_AD_PROTOCOL_VERSION:		str="PV"; break;
        +	case TLS1_AD_INSUFFICIENT_SECURITY:	str="IS"; break;
        +	case TLS1_AD_INTERNAL_ERROR:		str="IE"; break;
        +	case TLS1_AD_USER_CANCELLED:		str="US"; break;
        +	case TLS1_AD_NO_RENEGOTIATION:		str="NR"; break;
        +	case TLS1_AD_UNSUPPORTED_EXTENSION:	str="UE"; break;
        +	case TLS1_AD_CERTIFICATE_UNOBTAINABLE:	str="CO"; break;
        +	case TLS1_AD_UNRECOGNIZED_NAME:		str="UN"; break;
        +	case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: str="BR"; break;
        +	case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: str="BH"; break;
        +	case TLS1_AD_UNKNOWN_PSK_IDENTITY:	str="UP"; break;
        +	default:				str="UK"; break;
        +		}
        +	return(str);
        +	}
        +
        +const char *SSL_alert_desc_string_long(int value)
        +	{
        +	const char *str;
        +
        +	switch (value & 0xff)
        +		{
        +	case SSL3_AD_CLOSE_NOTIFY:
        +		str="close notify";
        +		break;
        +	case SSL3_AD_UNEXPECTED_MESSAGE:
        +		str="unexpected_message";
        +		break;
        +	case SSL3_AD_BAD_RECORD_MAC:
        +		str="bad record mac";
        +		break;
        +	case SSL3_AD_DECOMPRESSION_FAILURE:
        +		str="decompression failure";
        +		break;
        +	case SSL3_AD_HANDSHAKE_FAILURE:
        +		str="handshake failure";
        +		break;
        +	case SSL3_AD_NO_CERTIFICATE:
        +		str="no certificate";
        +		break;
        +	case SSL3_AD_BAD_CERTIFICATE:
        +		str="bad certificate";
        +		break;
        +	case SSL3_AD_UNSUPPORTED_CERTIFICATE:
        +		str="unsupported certificate";
        +		break;
        +	case SSL3_AD_CERTIFICATE_REVOKED:
        +		str="certificate revoked";
        +		break;
        +	case SSL3_AD_CERTIFICATE_EXPIRED:
        +		str="certificate expired";
        +		break;
        +	case SSL3_AD_CERTIFICATE_UNKNOWN:
        +		str="certificate unknown";
        +		break;
        +	case SSL3_AD_ILLEGAL_PARAMETER:
        +		str="illegal parameter";
        +		break;
        +	case TLS1_AD_DECRYPTION_FAILED:
        +		str="decryption failed";
        +		break;
        +	case TLS1_AD_RECORD_OVERFLOW:
        +		str="record overflow";
        +		break;
        +	case TLS1_AD_UNKNOWN_CA:
        +		str="unknown CA";
        +		break;
        +	case TLS1_AD_ACCESS_DENIED:
        +		str="access denied";
        +		break;
        +	case TLS1_AD_DECODE_ERROR:
        +		str="decode error";
        +		break;
        +	case TLS1_AD_DECRYPT_ERROR:
        +		str="decrypt error";
        +		break;
        +	case TLS1_AD_EXPORT_RESTRICTION:
        +		str="export restriction";
        +		break;
        +	case TLS1_AD_PROTOCOL_VERSION:
        +		str="protocol version";
        +		break;
        +	case TLS1_AD_INSUFFICIENT_SECURITY:
        +		str="insufficient security";
        +		break;
        +	case TLS1_AD_INTERNAL_ERROR:
        +		str="internal error";
        +		break;
        +	case TLS1_AD_USER_CANCELLED:
        +		str="user canceled";
        +		break;
        +	case TLS1_AD_NO_RENEGOTIATION:
        +		str="no renegotiation";
        +		break;
        +	case TLS1_AD_UNSUPPORTED_EXTENSION:
        +		str="unsupported extension";
        +		break;
        +	case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
        +		str="certificate unobtainable";
        +		break;
        +	case TLS1_AD_UNRECOGNIZED_NAME:
        +		str="unrecognized name";
        +		break;
        +	case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
        +		str="bad certificate status response";
        +		break;
        +	case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
        +		str="bad certificate hash value";
        +		break;
        +	case TLS1_AD_UNKNOWN_PSK_IDENTITY:
        +		str="unknown PSK identity";
        +		break;
        +	default: str="unknown"; break;
        +		}
        +	return(str);
        +	}
        +
        +const char *SSL_rstate_string(const SSL *s)
        +	{
        +	const char *str;
        +
        +	switch (s->rstate)
        +		{
        +	case SSL_ST_READ_HEADER:str="RH"; break;
        +	case SSL_ST_READ_BODY:	str="RB"; break;
        +	case SSL_ST_READ_DONE:	str="RD"; break;
        +	default: str="unknown"; break;
        +		}
        +	return(str);
        +	}
        diff --git a/vendor/openssl/openssl/ssl/ssl_task.c b/vendor/openssl/openssl/ssl/ssl_task.c
        new file mode 100644
        index 000000000..b5ce44b47
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_task.c
        @@ -0,0 +1,369 @@
        +/* ssl/ssl_task.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.]
        + */
        +
        +/* VMS */
        +/*
        + * DECnet object for servicing SSL.  We accept the inbound and speak a
        + * simple protocol for multiplexing the 2 data streams (application and
        + * ssl data) over this logical link.
        + *
        + * Logical names:
        + *    SSL_CIPHER	Defines a list of cipher specifications the server
        + *			will support in order of preference.
        + *    SSL_SERVER_CERTIFICATE
        + *			Points to PEM (privacy enhanced mail) file that
        + *			contains the server certificate and private password.
        + *    SYS$NET		Logical created by netserver.exe as hook for completing
        + *			DECnet logical link.
        + *
        + * Each NSP message sent over the DECnet link has the following structure:
        + *    struct rpc_msg { 
        + *      char channel;
        + *      char function;
        + *      short length;
        + *      char data[MAX_DATA];
        + *    } msg;
        + *
        + * The channel field designates the virtual data stream this message applies
        + * to and is one of:
        + *   A - Application data (payload).
        + *   R - Remote client connection that initiated the SSL connection.  Encrypted
        + *       data is sent over this connection.
        + *   G - General data, reserved for future use.
        + *
        + * The data streams are half-duplex read/write and have following functions:
        + *   G - Get, requests that up to msg.length bytes of data be returned.  The
        + *       data is returned in the next 'C' function response that matches the
        + *       requesting channel.
        + *   P - Put, requests that the first msg.length bytes of msg.data be appended
        + *       to the designated stream.
        + *   C - Confirms a get or put.  Every get and put will get a confirm response,
        + *       you cannot initiate another function on a channel until the previous
        + *       operation has been confirmed.
        + *
        + *  The 2 channels may interleave their operations, for example:
        + *        Server msg           Client msg
        + *         A, Get, 4092          ---->
        + *                               <----  R, get, 4092
        + *         R, Confirm, {hello}   ---->
        + *                               <----  R, put, {srv hello}
        + *         R, Confirm, 0         ---->
        + *                               .		(SSL handshake completed)
        + *                               .              (read first app data).
        + *                               <----  A, confirm, {http data}
        + *         A, Put, {http data}   ---->
        + *                               <----  A, confirm, 0
        + *
        + *  The length field is not permitted to be larger that 4092 bytes.
        + *
        + * Author: Dave Jones
        + * Date:   22-JUL-1996
        + */
        +#include <stdlib.h>
        +#include <stdio.h>
        +#include <iodef.h>		/* VMS IO$_ definitions */
        +#include <descrip.h>		/* VMS string descriptors */
        +extern int SYS$QIOW(), SYS$ASSIGN();
        +int LIB$INIT_TIMER(), LIB$SHOW_TIMER();
        +
        +#include <string.h>		/* from ssltest.c */
        +#include <errno.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/buffer.h>
        +#include <openssl/x509.h>
        +#include <openssl/ssl.h>
        +#include <openssl/err.h>
        +
        +int MS_CALLBACK verify_callback(int ok, X509 *xs, X509 *xi, int depth,
        +	int error);
        +BIO *bio_err=NULL;
        +BIO *bio_stdout=NULL;
        +BIO_METHOD *BIO_s_rtcp();
        +
        +static char *cipher=NULL;
        +int verbose=1;
        +#ifdef FIONBIO
        +static int s_nbio=0;
        +#endif
        +#define TEST_SERVER_CERT "SSL_SERVER_CERTIFICATE"
        +/*************************************************************************/
        +struct rpc_msg {		/* Should have member alignment inhibited */
        +   char channel;		/* 'A'-app data. 'R'-remote client 'G'-global */
        +   char function;		/* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */
        +   unsigned short int length;	/* Amount of data returned or max to return */
        +   char data[4092];		/* variable data */
        +};
        +#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092)
        +
        +static $DESCRIPTOR(sysnet, "SYS$NET");
        +typedef unsigned short io_channel;
        +
        +struct io_status {
        +    unsigned short status;
        +    unsigned short count;
        +    unsigned long stsval;
        +};
        +int doit(io_channel chan, SSL_CTX *s_ctx );
        +/*****************************************************************************/
        +/* Decnet I/O routines.
        + */
        +static int get ( io_channel chan, char *buffer, int maxlen, int *length )
        +{
        +    int status;
        +    struct io_status iosb;
        +    status = SYS$QIOW ( 0, chan, IO$_READVBLK, &iosb, 0, 0,
        +	buffer, maxlen, 0, 0, 0, 0 );
        +    if ( (status&1) == 1 ) status = iosb.status;
        +    if ( (status&1) == 1 ) *length = iosb.count;
        +    return status;
        +}
        +
        +static int put ( io_channel chan, char *buffer, int length )
        +{
        +    int status;
        +    struct io_status iosb;
        +    status = SYS$QIOW ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0,
        +	buffer, length, 0, 0, 0, 0 );
        +    if ( (status&1) == 1 ) status = iosb.status;
        +    return status;
        +}
        +/***************************************************************************/
        +/* Handle operations on the 'G' channel.
        + */
        +static int general_request ( io_channel chan, struct rpc_msg *msg, int length )
        +{
        +    return 48;
        +}
        +/***************************************************************************/
        +int main ( int argc, char **argv )
        +{
        +    int status, length;
        +    io_channel chan;
        +    struct rpc_msg msg;
        +
        +	char *CApath=NULL,*CAfile=NULL;
        +	int badop=0;
        +	int ret=1;
        +	int client_auth=0;
        +	int server_auth=0;
        +	SSL_CTX *s_ctx=NULL;
        +    /*
        +     * Confirm logical link with initiating client.
        +     */
        +    LIB$INIT_TIMER();
        +    status = SYS$ASSIGN ( &sysnet, &chan, 0, 0, 0 );
        +    printf("status of assign to SYS$NET: %d\n", status );
        +    /*
        +     * Initialize standard out and error files.
        +     */
        +	if (bio_err == NULL)
        +		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
        +	if (bio_stdout == NULL)
        +		if ((bio_stdout=BIO_new(BIO_s_file())) != NULL)
        +			BIO_set_fp(bio_stdout,stdout,BIO_NOCLOSE);
        +    /*
        +     * get the preferred cipher list and other initialization
        +     */
        +	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
        +	printf("cipher list: %s\n", cipher ? cipher : "{undefined}" );
        +
        +	SSL_load_error_strings();
        +	OpenSSL_add_all_algorithms();
        +
        +/* DRM, this was the original, but there is no such thing as SSLv2()
        +	s_ctx=SSL_CTX_new(SSLv2());
        +*/
        +	s_ctx=SSL_CTX_new(SSLv2_server_method());
        +
        +	if (s_ctx == NULL) goto end;
        +
        +	SSL_CTX_use_certificate_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM);
        +	SSL_CTX_use_RSAPrivateKey_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM);
        +	printf("Loaded server certificate: '%s'\n", TEST_SERVER_CERT );
        +
        +    /*
        +     * Take commands from client until bad status.
        +     */
        +    LIB$SHOW_TIMER();
        +    status = doit ( chan, s_ctx );
        +    LIB$SHOW_TIMER();
        +    /*
        +     * do final cleanup and exit.
        +     */
        +end:
        +	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
        +    LIB$SHOW_TIMER();
        +    return 1;
        +}
        +
        +int doit(io_channel chan, SSL_CTX *s_ctx )
        +{
        +    int status, length, link_state;
        +     struct rpc_msg msg;
        +
        +	SSL *s_ssl=NULL;
        +	BIO *c_to_s=NULL;
        +	BIO *s_to_c=NULL;
        +	BIO *c_bio=NULL;
        +	BIO *s_bio=NULL;
        +	int i;
        +	int done=0;
        +
        +	s_ssl=SSL_new(s_ctx);
        +	if (s_ssl == NULL) goto err;
        +
        +	c_to_s=BIO_new(BIO_s_rtcp());
        +	s_to_c=BIO_new(BIO_s_rtcp());
        +	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
        +/* original, DRM 24-SEP-1997
        +	BIO_set_fd ( c_to_s, "", chan );
        +	BIO_set_fd ( s_to_c, "", chan );
        +*/
        +	BIO_set_fd ( c_to_s, 0, chan );
        +	BIO_set_fd ( s_to_c, 0, chan );
        +
        +	c_bio=BIO_new(BIO_f_ssl());
        +	s_bio=BIO_new(BIO_f_ssl());
        +	if ((c_bio == NULL) || (s_bio == NULL)) goto err;
        +
        +	SSL_set_accept_state(s_ssl);
        +	SSL_set_bio(s_ssl,c_to_s,s_to_c);
        +	BIO_set_ssl(s_bio,s_ssl,BIO_CLOSE);
        +
        +	/* We can always do writes */
        +	printf("Begin doit main loop\n");
        +	/*
        +	 * Link states: 0-idle, 1-read pending, 2-write pending, 3-closed.
        +	 */
        +	for (link_state = 0; link_state < 3; ) {
        +	    /*
        +	     * Wait for remote end to request data action on A channel.
        +	     */
        +	    while ( link_state == 0 ) {
        +		status = get ( chan, (char *) &msg, sizeof(msg), &length );
        +		if ( (status&1) == 0 ) {
        +		    printf("Error in main loop get: %d\n", status );
        +		    link_state = 3;
        +		    break;
        +		}
        +	   	if ( length < RPC_HDR_SIZE ) {
        +		    printf("Error in main loop get size: %d\n", length );
        +		    break;
        +		    link_state = 3;
        +		}
        +	   	if ( msg.channel != 'A' ) {
        +		    printf("Error in main loop, unexpected channel: %c\n", 
        +			msg.channel );
        +		    break;
        +		    link_state = 3;
        +		}
        +		if ( msg.function == 'G' ) {
        +		    link_state = 1;
        +		} else if ( msg.function == 'P' ) {
        +		    link_state = 2;	/* write pending */
        +		} else if ( msg.function == 'X' ) {
        +		    link_state = 3;
        +		} else {
        +		    link_state = 3;
        +		}
        +	    }
        +	    if ( link_state == 1 ) {
        +		i = BIO_read ( s_bio, msg.data, msg.length );
        +		if ( i < 0 ) link_state = 3;
        +		else {
        +		    msg.channel = 'A';
        +		    msg.function = 'C';		/* confirm */
        +		    msg.length = i;
        +		    status = put ( chan, (char *) &msg, i+RPC_HDR_SIZE );
        +		    if ( (status&1) == 0 ) break;
        +		    link_state = 0;
        +		}
        +	    } else if ( link_state == 2 ) {
        +		i = BIO_write ( s_bio, msg.data, msg.length );
        +		if ( i < 0 ) link_state = 3;
        +		else {
        +		    msg.channel = 'A';
        +		    msg.function = 'C';		/* confirm */
        +		    msg.length = 0;
        +		    status = put ( chan, (char *) &msg, RPC_HDR_SIZE );
        +		    if ( (status&1) == 0 ) break;
        +		    link_state = 0;
        +		}
        +	    }
        +	}
        +	fprintf(stdout,"DONE\n");
        +err:
        +	/* We have to set the BIO's to NULL otherwise they will be
        +	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
        +	 * again when c_ssl is SSL_free()ed.
        +	 * This is a hack required because s_ssl and c_ssl are sharing the same
        +	 * BIO structure and SSL_set_bio() and SSL_free() automatically
        +	 * BIO_free non NULL entries.
        +	 * You should not normally do this or be required to do this */
        +	s_ssl->rbio=NULL;
        +	s_ssl->wbio=NULL;
        +
        +	if (c_to_s != NULL) BIO_free(c_to_s);
        +	if (s_to_c != NULL) BIO_free(s_to_c);
        +	if (c_bio != NULL) BIO_free(c_bio);
        +	if (s_bio != NULL) BIO_free(s_bio);
        +	return(0);
        +}
        diff --git a/vendor/openssl/openssl/ssl/ssl_txt.c b/vendor/openssl/openssl/ssl/ssl_txt.c
        new file mode 100644
        index 000000000..6479d52c0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssl_txt.c
        @@ -0,0 +1,248 @@
        +/* ssl/ssl_txt.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 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include <openssl/buffer.h>
        +#include "ssl_locl.h"
        +
        +#ifndef OPENSSL_NO_FP_API
        +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
        +	{
        +	BIO *b;
        +	int ret;
        +
        +	if ((b=BIO_new(BIO_s_file_internal())) == NULL)
        +		{
        +		SSLerr(SSL_F_SSL_SESSION_PRINT_FP,ERR_R_BUF_LIB);
        +		return(0);
        +		}
        +	BIO_set_fp(b,fp,BIO_NOCLOSE);
        +	ret=SSL_SESSION_print(b,x);
        +	BIO_free(b);
        +	return(ret);
        +	}
        +#endif
        +
        +int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
        +	{
        +	unsigned int i;
        +	const char *s;
        +
        +	if (x == NULL) goto err;
        +	if (BIO_puts(bp,"SSL-Session:\n") <= 0) goto err;
        +	if (x->ssl_version == SSL2_VERSION)
        +		s="SSLv2";
        +	else if (x->ssl_version == SSL3_VERSION)
        +		s="SSLv3";
        +	else if (x->ssl_version == TLS1_2_VERSION)
        +		s="TLSv1.2";
        +	else if (x->ssl_version == TLS1_1_VERSION)
        +		s="TLSv1.1";
        +	else if (x->ssl_version == TLS1_VERSION)
        +		s="TLSv1";
        +	else if (x->ssl_version == DTLS1_VERSION)
        +		s="DTLSv1";
        +	else if (x->ssl_version == DTLS1_BAD_VER)
        +		s="DTLSv1-bad";
        +	else
        +		s="unknown";
        +	if (BIO_printf(bp,"    Protocol  : %s\n",s) <= 0) goto err;
        +
        +	if (x->cipher == NULL)
        +		{
        +		if (((x->cipher_id) & 0xff000000) == 0x02000000)
        +			{
        +			if (BIO_printf(bp,"    Cipher    : %06lX\n",x->cipher_id&0xffffff) <= 0)
        +				goto err;
        +			}
        +		else
        +			{
        +			if (BIO_printf(bp,"    Cipher    : %04lX\n",x->cipher_id&0xffff) <= 0)
        +				goto err;
        +			}
        +		}
        +	else
        +		{
        +		if (BIO_printf(bp,"    Cipher    : %s\n",((x->cipher == NULL)?"unknown":x->cipher->name)) <= 0)
        +			goto err;
        +		}
        +	if (BIO_puts(bp,"    Session-ID: ") <= 0) goto err;
        +	for (i=0; i<x->session_id_length; i++)
        +		{
        +		if (BIO_printf(bp,"%02X",x->session_id[i]) <= 0) goto err;
        +		}
        +	if (BIO_puts(bp,"\n    Session-ID-ctx: ") <= 0) goto err;
        +	for (i=0; i<x->sid_ctx_length; i++)
        +		{
        +		if (BIO_printf(bp,"%02X",x->sid_ctx[i]) <= 0)
        +			goto err;
        +		}
        +	if (BIO_puts(bp,"\n    Master-Key: ") <= 0) goto err;
        +	for (i=0; i<(unsigned int)x->master_key_length; i++)
        +		{
        +		if (BIO_printf(bp,"%02X",x->master_key[i]) <= 0) goto err;
        +		}
        +	if (BIO_puts(bp,"\n    Key-Arg   : ") <= 0) goto err;
        +	if (x->key_arg_length == 0)
        +		{
        +		if (BIO_puts(bp,"None") <= 0) goto err;
        +		}
        +	else
        +		for (i=0; i<x->key_arg_length; i++)
        +			{
        +			if (BIO_printf(bp,"%02X",x->key_arg[i]) <= 0) goto err;
        +			}
        +#ifndef OPENSSL_NO_KRB5
        +       if (BIO_puts(bp,"\n    Krb5 Principal: ") <= 0) goto err;
        +            if (x->krb5_client_princ_len == 0)
        +            {
        +		if (BIO_puts(bp,"None") <= 0) goto err;
        +		}
        +	else
        +		for (i=0; i<x->krb5_client_princ_len; i++)
        +			{
        +			if (BIO_printf(bp,"%02X",x->krb5_client_princ[i]) <= 0) goto err;
        +			}
        +#endif /* OPENSSL_NO_KRB5 */
        +#ifndef OPENSSL_NO_PSK
        +	if (BIO_puts(bp,"\n    PSK identity: ") <= 0) goto err;
        +	if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) goto err;
        +	if (BIO_puts(bp,"\n    PSK identity hint: ") <= 0) goto err;
        +	if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	if (BIO_puts(bp,"\n    SRP username: ") <= 0) goto err;
        +	if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) goto err;
        +#endif
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (x->tlsext_tick_lifetime_hint)
        +		{
        +		if (BIO_printf(bp,
        +			"\n    TLS session ticket lifetime hint: %ld (seconds)",
        +			x->tlsext_tick_lifetime_hint) <=0)
        +			goto err;
        +		}
        +	if (x->tlsext_tick)
        +		{
        +		if (BIO_puts(bp, "\n    TLS session ticket:\n") <= 0) goto err;
        +		if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) <= 0)
        +			goto err;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_COMP
        +	if (x->compress_meth != 0)
        +		{
        +		SSL_COMP *comp = NULL;
        +
        +		ssl_cipher_get_evp(x,NULL,NULL,NULL,NULL,&comp);
        +		if (comp == NULL)
        +			{
        +			if (BIO_printf(bp,"\n    Compression: %d",x->compress_meth) <= 0) goto err;
        +			}
        +		else
        +			{
        +			if (BIO_printf(bp,"\n    Compression: %d (%s)", comp->id,comp->method->name) <= 0) goto err;
        +			}
        +		}	
        +#endif
        +	if (x->time != 0L)
        +		{
        +		if (BIO_printf(bp, "\n    Start Time: %ld",x->time) <= 0) goto err;
        +		}
        +	if (x->timeout != 0L)
        +		{
        +		if (BIO_printf(bp, "\n    Timeout   : %ld (sec)",x->timeout) <= 0) goto err;
        +		}
        +	if (BIO_puts(bp,"\n") <= 0) goto err;
        +
        +	if (BIO_puts(bp, "    Verify return code: ") <= 0) goto err;
        +	if (BIO_printf(bp, "%ld (%s)\n", x->verify_result,
        +		X509_verify_cert_error_string(x->verify_result)) <= 0) goto err;
        +		
        +	return(1);
        +err:
        +	return(0);
        +	}
        +
        diff --git a/vendor/openssl/openssl/ssl/ssltest.c b/vendor/openssl/openssl/ssl/ssltest.c
        new file mode 100644
        index 000000000..316bbb0c9
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/ssltest.c
        @@ -0,0 +1,2577 @@
        +/* ssl/ssltest.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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#define _BSD_SOURCE 1		/* Or gethostname won't be declared properly
        +				   on Linux and GNU platforms. */
        +
        +#include <assert.h>
        +#include <errno.h>
        +#include <limits.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +
        +#define USE_SOCKETS
        +#include "e_os.h"
        +
        +#ifdef OPENSSL_SYS_VMS
        +#define _XOPEN_SOURCE 500	/* Or isascii won't be declared properly on
        +				   VMS (at least with DECompHP C).  */
        +#endif
        +
        +#include <ctype.h>
        +
        +#include <openssl/bio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ssl.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +#include <openssl/srp.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#define _XOPEN_SOURCE_EXTENDED	1 /* Or gethostname won't be declared properly
        +				     on Compaq platforms (at least with DEC C).
        +				     Do not try to put it earlier, or IPv6 includes
        +				     get screwed...
        +				  */
        +
        +#ifdef OPENSSL_SYS_WINDOWS
        +#include <winsock.h>
        +#else
        +#include OPENSSL_UNISTD
        +#endif
        +
        +#ifdef OPENSSL_SYS_VMS
        +#  define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
        +#  define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
        +#elif defined(OPENSSL_SYS_WINCE)
        +#  define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
        +#  define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
        +#elif defined(OPENSSL_SYS_NETWARE)
        +#  define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
        +#  define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem"
        +#else
        +#  define TEST_SERVER_CERT "../apps/server.pem"
        +#  define TEST_CLIENT_CERT "../apps/client.pem"
        +#endif
        +
        +/* There is really no standard for this, so let's assign some tentative
        +   numbers.  In any case, these numbers are only for this test */
        +#define COMP_RLE	255
        +#define COMP_ZLIB	1
        +
        +static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
        +#ifndef OPENSSL_NO_RSA
        +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
        +static void free_tmp_rsa(void);
        +#endif
        +static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
        +#define APP_CALLBACK_STRING "Test Callback Argument"
        +struct app_verify_arg
        +	{
        +	char *string;
        +	int app_verify;
        +	int allow_proxy_certs;
        +	char *proxy_auth;
        +	char *proxy_cond;
        +	};
        +
        +#ifndef OPENSSL_NO_DH
        +static DH *get_dh512(void);
        +static DH *get_dh1024(void);
        +static DH *get_dh1024dsa(void);
        +#endif
        +
        +
        +static char *psk_key=NULL; /* by default PSK is not used */
        +#ifndef OPENSSL_NO_PSK
        +static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
        +	unsigned int max_identity_len, unsigned char *psk,
        +	unsigned int max_psk_len);
        +static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
        +	unsigned int max_psk_len);
        +#endif
        +
        +#ifndef OPENSSL_NO_SRP
        +/* SRP client */
        +/* This is a context that we pass to all callbacks */
        +typedef struct srp_client_arg_st
        +	{
        +	char *srppassin;
        +	char *srplogin;
        +	} SRP_CLIENT_ARG;
        +
        +#define PWD_STRLEN 1024
        +
        +static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
        +	{
        +	SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
        +	return BUF_strdup((char *)srp_client_arg->srppassin);
        +	}
        +
        +/* SRP server */
        +/* This is a context that we pass to SRP server callbacks */
        +typedef struct srp_server_arg_st
        +	{
        +	char *expected_user;
        +	char *pass;
        +	} SRP_SERVER_ARG;
        +
        +static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
        +	{
        +	SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
        +
        +	if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
        +		{
        +		fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
        +		return SSL3_AL_FATAL;
        +		}
        +	if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
        +		{
        +		*ad = SSL_AD_INTERNAL_ERROR;
        +		return SSL3_AL_FATAL;
        +		}
        +	return SSL_ERROR_NONE;
        +	}
        +#endif
        +
        +static BIO *bio_err=NULL;
        +static BIO *bio_stdout=NULL;
        +
        +static char *cipher=NULL;
        +static int verbose=0;
        +static int debug=0;
        +#if 0
        +/* Not used yet. */
        +#ifdef FIONBIO
        +static int s_nbio=0;
        +#endif
        +#endif
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time);
        +int doit(SSL *s_ssl,SSL *c_ssl,long bytes);
        +static int do_test_cipherlist(void);
        +static void sv_usage(void)
        +	{
        +	fprintf(stderr,"usage: ssltest [args ...]\n");
        +	fprintf(stderr,"\n");
        +#ifdef OPENSSL_FIPS
        +	fprintf(stderr,"-F             - run test in FIPS mode\n");
        +#endif
        +	fprintf(stderr," -server_auth  - check server certificate\n");
        +	fprintf(stderr," -client_auth  - do client authentication\n");
        +	fprintf(stderr," -proxy        - allow proxy certificates\n");
        +	fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
        +	fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
        +	fprintf(stderr," -v            - more output\n");
        +	fprintf(stderr," -d            - debug output\n");
        +	fprintf(stderr," -reuse        - use session-id reuse\n");
        +	fprintf(stderr," -num <val>    - number of connections to perform\n");
        +	fprintf(stderr," -bytes <val>  - number of bytes to swap between client/server\n");
        +#ifndef OPENSSL_NO_DH
        +	fprintf(stderr," -dhe1024      - use 1024 bit key (safe prime) for DHE\n");
        +	fprintf(stderr," -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
        +	fprintf(stderr," -no_dhe       - disable DHE\n");
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	fprintf(stderr," -no_ecdhe     - disable ECDHE\n");
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +	fprintf(stderr," -psk arg      - PSK in hex (without 0x)\n");
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	fprintf(stderr," -srpuser user  - SRP username to use\n");
        +	fprintf(stderr," -srppass arg   - password for 'user'\n");
        +#endif
        +#ifndef OPENSSL_NO_SSL2
        +	fprintf(stderr," -ssl2         - use SSLv2\n");
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +	fprintf(stderr," -ssl3         - use SSLv3\n");
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +	fprintf(stderr," -tls1         - use TLSv1\n");
        +#endif
        +	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
        +	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
        +	fprintf(stderr," -cert arg     - Server certificate file\n");
        +	fprintf(stderr," -key arg      - Server key file (default: same as -cert)\n");
        +	fprintf(stderr," -c_cert arg   - Client certificate file\n");
        +	fprintf(stderr," -c_key arg    - Client key file (default: same as -c_cert)\n");
        +	fprintf(stderr," -cipher arg   - The cipher list\n");
        +	fprintf(stderr," -bio_pair     - Use BIO pairs\n");
        +	fprintf(stderr," -f            - Test even cases that can't work\n");
        +	fprintf(stderr," -time         - measure processor time used by client and server\n");
        +	fprintf(stderr," -zlib         - use zlib compression\n");
        +	fprintf(stderr," -rle          - use rle compression\n");
        +#ifndef OPENSSL_NO_ECDH
        +	fprintf(stderr," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
        +	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
        +	               "                 (default is sect163r2).\n");
        +#endif
        +	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
        +	}
        +
        +static void print_details(SSL *c_ssl, const char *prefix)
        +	{
        +	const SSL_CIPHER *ciph;
        +	X509 *cert;
        +		
        +	ciph=SSL_get_current_cipher(c_ssl);
        +	BIO_printf(bio_stdout,"%s%s, cipher %s %s",
        +		prefix,
        +		SSL_get_version(c_ssl),
        +		SSL_CIPHER_get_version(ciph),
        +		SSL_CIPHER_get_name(ciph));
        +	cert=SSL_get_peer_certificate(c_ssl);
        +	if (cert != NULL)
        +		{
        +		EVP_PKEY *pkey = X509_get_pubkey(cert);
        +		if (pkey != NULL)
        +			{
        +			if (0) 
        +				;
        +#ifndef OPENSSL_NO_RSA
        +			else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
        +				&& pkey->pkey.rsa->n != NULL)
        +				{
        +				BIO_printf(bio_stdout, ", %d bit RSA",
        +					BN_num_bits(pkey->pkey.rsa->n));
        +				}
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
        +				&& pkey->pkey.dsa->p != NULL)
        +				{
        +				BIO_printf(bio_stdout, ", %d bit DSA",
        +					BN_num_bits(pkey->pkey.dsa->p));
        +				}
        +#endif
        +			EVP_PKEY_free(pkey);
        +			}
        +		X509_free(cert);
        +		}
        +	/* The SSL API does not allow us to look at temporary RSA/DH keys,
        +	 * otherwise we should print their lengths too */
        +	BIO_printf(bio_stdout,"\n");
        +	}
        +
        +static void lock_dbg_cb(int mode, int type, const char *file, int line)
        +	{
        +	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
        +	const char *errstr = NULL;
        +	int rw;
        +	
        +	rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
        +	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
        +		{
        +		errstr = "invalid mode";
        +		goto err;
        +		}
        +
        +	if (type < 0 || type >= CRYPTO_NUM_LOCKS)
        +		{
        +		errstr = "type out of bounds";
        +		goto err;
        +		}
        +
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		if (modes[type])
        +			{
        +			errstr = "already locked";
        +			/* must not happen in a single-threaded program
        +			 * (would deadlock) */
        +			goto err;
        +			}
        +
        +		modes[type] = rw;
        +		}
        +	else if (mode & CRYPTO_UNLOCK)
        +		{
        +		if (!modes[type])
        +			{
        +			errstr = "not locked";
        +			goto err;
        +			}
        +		
        +		if (modes[type] != rw)
        +			{
        +			errstr = (rw == CRYPTO_READ) ?
        +				"CRYPTO_r_unlock on write lock" :
        +				"CRYPTO_w_unlock on read lock";
        +			}
        +
        +		modes[type] = 0;
        +		}
        +	else
        +		{
        +		errstr = "invalid mode";
        +		goto err;
        +		}
        +
        + err:
        +	if (errstr)
        +		{
        +		/* we cannot use bio_err here */
        +		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
        +			errstr, mode, type, file, line);
        +		}
        +	}
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +struct cb_info_st { void *input; size_t len; int ret; };
        +struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */
        +struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */
        +struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */
        +struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */
        +
        +int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
        +	{
        +	struct cb_info_st *arg = arg_;
        +
        +	if (arg == NULL)
        +		return 1;
        +	
        +	if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len))
        +		return 0;
        +	return arg->ret;
        +	}
        +#endif
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *CApath=NULL,*CAfile=NULL;
        +	int badop=0;
        +	int bio_pair=0;
        +	int force=0;
        +	int tls1=0,ssl2=0,ssl3=0,ret=1;
        +	int client_auth=0;
        +	int server_auth=0,i;
        +	struct app_verify_arg app_verify_arg =
        +		{ APP_CALLBACK_STRING, 0, 0, NULL, NULL };
        +	char *server_cert=TEST_SERVER_CERT;
        +	char *server_key=NULL;
        +	char *client_cert=TEST_CLIENT_CERT;
        +	char *client_key=NULL;
        +#ifndef OPENSSL_NO_ECDH
        +	char *named_curve = NULL;
        +#endif
        +	SSL_CTX *s_ctx=NULL;
        +	SSL_CTX *c_ctx=NULL;
        +	const SSL_METHOD *meth=NULL;
        +	SSL *c_ssl,*s_ssl;
        +	int number=1,reuse=0;
        +	long bytes=256L;
        +#ifndef OPENSSL_NO_DH
        +	DH *dh;
        +	int dhe1024 = 0, dhe1024dsa = 0;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh = NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	/* client */
        +	SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
        +	/* server */
        +	SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
        +#endif
        +	int no_dhe = 0;
        +	int no_ecdhe = 0;
        +	int no_psk = 0;
        +	int print_time = 0;
        +	clock_t s_time = 0, c_time = 0;
        +	int comp = 0;
        +#ifndef OPENSSL_NO_COMP
        +	COMP_METHOD *cm = NULL;
        +	STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
        +#endif
        +	int test_cipherlist = 0;
        +#ifdef OPENSSL_FIPS
        +	int fips_mode=0;
        +#endif
        +
        +	verbose = 0;
        +	debug = 0;
        +	cipher = 0;
        +
        +	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);	
        +
        +	CRYPTO_set_locking_callback(lock_dbg_cb);
        +
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	argc--;
        +	argv++;
        +
        +	while (argc >= 1)
        +		{
        +		if(!strcmp(*argv,"-F"))
        +			{
        +#ifdef OPENSSL_FIPS
        +			fips_mode=1;
        +#else
        +			fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
        +			EXIT(0);
        +#endif
        +			}
        +		else if (strcmp(*argv,"-server_auth") == 0)
        +			server_auth=1;
        +		else if	(strcmp(*argv,"-client_auth") == 0)
        +			client_auth=1;
        +		else if (strcmp(*argv,"-proxy_auth") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			app_verify_arg.proxy_auth= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-proxy_cond") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			app_verify_arg.proxy_cond= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-v") == 0)
        +			verbose=1;
        +		else if	(strcmp(*argv,"-d") == 0)
        +			debug=1;
        +		else if	(strcmp(*argv,"-reuse") == 0)
        +			reuse=1;
        +		else if	(strcmp(*argv,"-dhe1024") == 0)
        +			{
        +#ifndef OPENSSL_NO_DH
        +			dhe1024=1;
        +#else
        +			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
        +#endif
        +			}
        +		else if	(strcmp(*argv,"-dhe1024dsa") == 0)
        +			{
        +#ifndef OPENSSL_NO_DH
        +			dhe1024dsa=1;
        +#else
        +			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
        +#endif
        +			}
        +		else if	(strcmp(*argv,"-no_dhe") == 0)
        +			no_dhe=1;
        +		else if	(strcmp(*argv,"-no_ecdhe") == 0)
        +			no_ecdhe=1;
        +		else if (strcmp(*argv,"-psk") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			psk_key=*(++argv);
        +#ifndef OPENSSL_NO_PSK
        +			if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key))
        +				{
        +				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
        +				goto bad;
        +				}
        +#else
        +			no_psk=1;
        +#endif
        +			}
        +#ifndef OPENSSL_NO_SRP
        +		else if (strcmp(*argv,"-srpuser") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
        +			tls1=1;
        +			}
        +		else if (strcmp(*argv,"-srppass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
        +			tls1=1;
        +			}
        +#endif
        +		else if	(strcmp(*argv,"-ssl2") == 0)
        +			ssl2=1;
        +		else if	(strcmp(*argv,"-tls1") == 0)
        +			tls1=1;
        +		else if	(strcmp(*argv,"-ssl3") == 0)
        +			ssl3=1;
        +		else if	(strncmp(*argv,"-num",4) == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			number= atoi(*(++argv));
        +			if (number == 0) number=1;
        +			}
        +		else if	(strcmp(*argv,"-bytes") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			bytes= atol(*(++argv));
        +			if (bytes == 0L) bytes=1L;
        +			i=strlen(argv[0]);
        +			if (argv[0][i-1] == 'k') bytes*=1024L;
        +			if (argv[0][i-1] == 'm') bytes*=1024L*1024L;
        +			}
        +		else if	(strcmp(*argv,"-cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_cert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-s_cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_cert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_key= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-s_key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_key= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-c_cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			client_cert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-c_key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			client_key= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-cipher") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			cipher= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CApath") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CApath= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CAfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-bio_pair") == 0)
        +			{
        +			bio_pair = 1;
        +			}
        +		else if	(strcmp(*argv,"-f") == 0)
        +			{
        +			force = 1;
        +			}
        +		else if	(strcmp(*argv,"-time") == 0)
        +			{
        +			print_time = 1;
        +			}
        +		else if	(strcmp(*argv,"-zlib") == 0)
        +			{
        +			comp = COMP_ZLIB;
        +			}
        +		else if	(strcmp(*argv,"-rle") == 0)
        +			{
        +			comp = COMP_RLE;
        +			}
        +		else if	(strcmp(*argv,"-named_curve") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +#ifndef OPENSSL_NO_ECDH		
        +			named_curve = *(++argv);
        +#else
        +			fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
        +			++argv;
        +#endif
        +			}
        +		else if	(strcmp(*argv,"-app_verify") == 0)
        +			{
        +			app_verify_arg.app_verify = 1;
        +			}
        +		else if	(strcmp(*argv,"-proxy") == 0)
        +			{
        +			app_verify_arg.allow_proxy_certs = 1;
        +			}
        +		else if (strcmp(*argv,"-test_cipherlist") == 0)
        +			{
        +			test_cipherlist = 1;
        +			}
        +		else
        +			{
        +			fprintf(stderr,"unknown option %s\n",*argv);
        +			badop=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +	if (badop)
        +		{
        +bad:
        +		sv_usage();
        +		goto end;
        +		}
        +
        +	if (test_cipherlist == 1)
        +		{
        +		/* ensure that the cipher list are correctly sorted and exit */
        +		if (do_test_cipherlist() == 0)
        +			EXIT(1);
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
        +		{
        +		fprintf(stderr, "This case cannot work.  Use -f to perform "
        +			"the test anyway (and\n-d to see what happens), "
        +			"or add one of -ssl2, -ssl3, -tls1, -reuse\n"
        +			"to avoid protocol mismatch.\n");
        +		EXIT(1);
        +		}
        +
        +#ifdef OPENSSL_FIPS
        +	if(fips_mode)
        +		{
        +		if(!FIPS_mode_set(1))
        +			{
        +			ERR_load_crypto_strings();
        +			ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
        +			EXIT(1);
        +			}
        +		else
        +			fprintf(stderr,"*** IN FIPS MODE ***\n");
        +		}
        +#endif
        +
        +	if (print_time)
        +		{
        +		if (!bio_pair)
        +			{
        +			fprintf(stderr, "Using BIO pair (-bio_pair)\n");
        +			bio_pair = 1;
        +			}
        +		if (number < 50 && !force)
        +			fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
        +		}
        +
        +/*	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
        +
        +	SSL_library_init();
        +	SSL_load_error_strings();
        +
        +#ifndef OPENSSL_NO_COMP
        +	if (comp == COMP_ZLIB) cm = COMP_zlib();
        +	if (comp == COMP_RLE) cm = COMP_rle();
        +	if (cm != NULL)
        +		{
        +		if (cm->type != NID_undef)
        +			{
        +			if (SSL_COMP_add_compression_method(comp, cm) != 0)
        +				{
        +				fprintf(stderr,
        +					"Failed to add compression method\n");
        +				ERR_print_errors_fp(stderr);
        +				}
        +			}
        +		else
        +			{
        +			fprintf(stderr,
        +				"Warning: %s compression not supported\n",
        +				(comp == COMP_RLE ? "rle" :
        +					(comp == COMP_ZLIB ? "zlib" :
        +						"unknown")));
        +			ERR_print_errors_fp(stderr);
        +			}
        +		}
        +	ssl_comp_methods = SSL_COMP_get_compression_methods();
        +	fprintf(stderr, "Available compression methods:\n");
        +	{
        +	int j, n = sk_SSL_COMP_num(ssl_comp_methods);
        +	if (n == 0)
        +		fprintf(stderr, "  NONE\n");
        +	else
        +		for (j = 0; j < n; j++)
        +			{
        +			SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
        +			fprintf(stderr, "  %d: %s\n", c->id, c->name);
        +			}
        +	}
        +#endif
        +
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +	if (ssl2)
        +		meth=SSLv2_method();
        +	else 
        +	if (tls1)
        +		meth=TLSv1_method();
        +	else
        +	if (ssl3)
        +		meth=SSLv3_method();
        +	else
        +		meth=SSLv23_method();
        +#else
        +#ifdef OPENSSL_NO_SSL2
        +	meth=SSLv3_method();
        +#else
        +	meth=SSLv2_method();
        +#endif
        +#endif
        +
        +	c_ctx=SSL_CTX_new(meth);
        +	s_ctx=SSL_CTX_new(meth);
        +	if ((c_ctx == NULL) || (s_ctx == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (cipher != NULL)
        +		{
        +		SSL_CTX_set_cipher_list(c_ctx,cipher);
        +		SSL_CTX_set_cipher_list(s_ctx,cipher);
        +		}
        +
        +#ifndef OPENSSL_NO_DH
        +	if (!no_dhe)
        +		{
        +		if (dhe1024dsa)
        +			{
        +			/* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
        +			SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
        +			dh=get_dh1024dsa();
        +			}
        +		else if (dhe1024)
        +			dh=get_dh1024();
        +		else
        +			dh=get_dh512();
        +		SSL_CTX_set_tmp_dh(s_ctx,dh);
        +		DH_free(dh);
        +		}
        +#else
        +	(void)no_dhe;
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	if (!no_ecdhe)
        +		{
        +		int nid;
        +
        +		if (named_curve != NULL)
        +			{
        +			nid = OBJ_sn2nid(named_curve);
        +			if (nid == 0)
        +			{
        +				BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
        +				goto end;
        +				}
        +			}
        +		else
        +#ifdef OPENSSL_NO_EC2M
        +			nid = NID_X9_62_prime256v1;
        +#else
        +			nid = NID_sect163r2;
        +#endif
        +
        +		ecdh = EC_KEY_new_by_curve_name(nid);
        +		if (ecdh == NULL)
        +			{
        +			BIO_printf(bio_err, "unable to create curve\n");
        +			goto end;
        +			}
        +
        +		SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
        +		SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
        +		EC_KEY_free(ecdh);
        +		}
        +#else
        +	(void)no_ecdhe;
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +	SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
        +#endif
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb);
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb);
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &co2 or NULL */
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); /* or &so2 or NULL */
        +#endif
        +
        +	if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
        +		{
        +		ERR_print_errors(bio_err);
        +		}
        +	else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
        +		(server_key?server_key:server_cert), SSL_FILETYPE_PEM))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (client_auth)
        +		{
        +		SSL_CTX_use_certificate_file(c_ctx,client_cert,
        +			SSL_FILETYPE_PEM);
        +		SSL_CTX_use_PrivateKey_file(c_ctx,
        +			(client_key?client_key:client_cert),
        +			SSL_FILETYPE_PEM);
        +		}
        +
        +	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
        +		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(c_ctx)))
        +		{
        +		/* fprintf(stderr,"SSL_load_verify_locations\n"); */
        +		ERR_print_errors(bio_err);
        +		/* goto end; */
        +		}
        +
        +	if (client_auth)
        +		{
        +		BIO_printf(bio_err,"client authentication\n");
        +		SSL_CTX_set_verify(s_ctx,
        +			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
        +			verify_callback);
        +		SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
        +		}
        +	if (server_auth)
        +		{
        +		BIO_printf(bio_err,"server authentication\n");
        +		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
        +			verify_callback);
        +		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
        +		}
        +	
        +	{
        +		int session_id_context = 0;
        +		SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context);
        +	}
        +
        +	/* Use PSK only if PSK key is given */
        +	if (psk_key != NULL)
        +		{
        +		/* no_psk is used to avoid putting psk command to openssl tool */
        +		if (no_psk)
        +			{
        +			/* if PSK is not compiled in and psk key is
        +			 * given, do nothing and exit successfully */
        +			ret=0;
        +			goto end;
        +			}
        +#ifndef OPENSSL_NO_PSK
        +		SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback);
        +		SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback);
        +		if (debug)
        +			BIO_printf(bio_err,"setting PSK identity hint to s_ctx\n");
        +		if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint"))
        +			{
        +			BIO_printf(bio_err,"error setting PSK identity hint to s_ctx\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +#endif
        +		}
        +#ifndef OPENSSL_NO_SRP
        +        if (srp_client_arg.srplogin)
        +		{
        +		if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
        +			{
        +			BIO_printf(bio_err,"Unable to set SRP username\n");
        +			goto end;
        +			}
        +		SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
        +		SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
        +		/*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
        +		}
        +
        +	if (srp_server_arg.expected_user != NULL)
        +		{
        +		SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
        +		SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
        +		SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
        +		}
        +#endif
        +
        +	c_ssl=SSL_new(c_ctx);
        +	s_ssl=SSL_new(s_ctx);
        +
        +#ifndef OPENSSL_NO_KRB5
        +	if (c_ssl  &&  c_ssl->kssl_ctx)
        +                {
        +                char	localhost[MAXHOSTNAMELEN+2];
        +
        +		if (gethostname(localhost, sizeof localhost-1) == 0)
        +                        {
        +			localhost[sizeof localhost-1]='\0';
        +			if(strlen(localhost) == sizeof localhost-1)
        +				{
        +				BIO_printf(bio_err,"localhost name too long\n");
        +				goto end;
        +				}
        +			kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
        +                                localhost);
        +			}
        +		}
        +#endif    /* OPENSSL_NO_KRB5  */
        +
        +	for (i=0; i<number; i++)
        +		{
        +		if (!reuse) SSL_set_session(c_ssl,NULL);
        +		if (bio_pair)
        +			ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time);
        +		else
        +			ret=doit(s_ssl,c_ssl,bytes);
        +		}
        +
        +	if (!verbose)
        +		{
        +		print_details(c_ssl, "");
        +		}
        +	if ((number > 1) || (bytes > 1L))
        +		BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes);
        +	if (print_time)
        +		{
        +#ifdef CLOCKS_PER_SEC
        +		/* "To determine the time in seconds, the value returned
        +		 * by the clock function should be divided by the value
        +		 * of the macro CLOCKS_PER_SEC."
        +		 *                                       -- ISO/IEC 9899 */
        +		BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n"
        +			"Approximate total client time: %6.2f s\n",
        +			(double)s_time/CLOCKS_PER_SEC,
        +			(double)c_time/CLOCKS_PER_SEC);
        +#else
        +		/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
        +		 *                            -- cc on NeXTstep/OpenStep */
        +		BIO_printf(bio_stdout,
        +			"Approximate total server time: %6.2f units\n"
        +			"Approximate total client time: %6.2f units\n",
        +			(double)s_time,
        +			(double)c_time);
        +#endif
        +		}
        +
        +	SSL_free(s_ssl);
        +	SSL_free(c_ssl);
        +
        +end:
        +	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
        +	if (c_ctx != NULL) SSL_CTX_free(c_ctx);
        +
        +	if (bio_stdout != NULL) BIO_free(bio_stdout);
        +
        +#ifndef OPENSSL_NO_RSA
        +	free_tmp_rsa();
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_cleanup();
        +#endif
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_free_strings();
        +	ERR_remove_thread_state(NULL);
        +	EVP_cleanup();
        +	CRYPTO_mem_leaks(bio_err);
        +	if (bio_err != NULL) BIO_free(bio_err);
        +	EXIT(ret);
        +	return ret;
        +	}
        +
        +int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
        +	clock_t *s_time, clock_t *c_time)
        +	{
        +	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
        +	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
        +	BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
        +	int ret = 1;
        +	
        +	size_t bufsiz = 256; /* small buffer for testing */
        +
        +	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
        +		goto err;
        +	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
        +		goto err;
        +	
        +	s_ssl_bio = BIO_new(BIO_f_ssl());
        +	if (!s_ssl_bio)
        +		goto err;
        +
        +	c_ssl_bio = BIO_new(BIO_f_ssl());
        +	if (!c_ssl_bio)
        +		goto err;
        +
        +	SSL_set_connect_state(c_ssl);
        +	SSL_set_bio(c_ssl, client, client);
        +	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
        +
        +	SSL_set_accept_state(s_ssl);
        +	SSL_set_bio(s_ssl, server, server);
        +	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
        +
        +	do
        +		{
        +		/* c_ssl_bio:          SSL filter BIO
        +		 *
        +		 * client:             pseudo-I/O for SSL library
        +		 *
        +		 * client_io:          client's SSL communication; usually to be
        +		 *                     relayed over some I/O facility, but in this
        +		 *                     test program, we're the server, too:
        +		 *
        +		 * server_io:          server's SSL communication
        +		 *
        +		 * server:             pseudo-I/O for SSL library
        +		 *
        +		 * s_ssl_bio:          SSL filter BIO
        +		 *
        +		 * The client and the server each employ a "BIO pair":
        +		 * client + client_io, server + server_io.
        +		 * BIO pairs are symmetric.  A BIO pair behaves similar
        +		 * to a non-blocking socketpair (but both endpoints must
        +		 * be handled by the same thread).
        +		 * [Here we could connect client and server to the ends
        +		 * of a single BIO pair, but then this code would be less
        +		 * suitable as an example for BIO pairs in general.]
        +		 *
        +		 * Useful functions for querying the state of BIO pair endpoints:
        +		 *
        +		 * BIO_ctrl_pending(bio)              number of bytes we can read now
        +		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
        +		 *                                      other side's read attempt
        +		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
        +		 *
        +		 * ..._read_request is never more than ..._write_guarantee;
        +		 * it depends on the application which one you should use.
        +		 */
        +
        +		/* We have non-blocking behaviour throughout this test program, but
        +		 * can be sure that there is *some* progress in each iteration; so
        +		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
        +		 * -- we just try everything in each iteration
        +		 */
        +
        +			{
        +			/* CLIENT */
        +		
        +			MS_STATIC char cbuf[1024*8];
        +			int i, r;
        +			clock_t c_clock = clock();
        +
        +			memset(cbuf, 0, sizeof(cbuf));
        +
        +			if (debug)
        +				if (SSL_in_init(c_ssl))
        +					printf("client waiting in SSL_connect - %s\n",
        +						SSL_state_string_long(c_ssl));
        +
        +			if (cw_num > 0)
        +				{
        +				/* Write to server. */
        +				
        +				if (cw_num > (long)sizeof cbuf)
        +					i = sizeof cbuf;
        +				else
        +					i = (int)cw_num;
        +				r = BIO_write(c_ssl_bio, cbuf, i);
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(c_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						goto err;
        +						}
        +					/* BIO_should_retry(...) can just be ignored here.
        +					 * The library expects us to call BIO_write with
        +					 * the same arguments again, and that's what we will
        +					 * do in the next iteration. */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client wrote %d\n", r);
        +					cw_num -= r;				
        +					}
        +				}
        +
        +			if (cr_num > 0)
        +				{
        +				/* Read from server. */
        +
        +				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(c_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						goto err;
        +						}
        +					/* Again, "BIO_should_retry" can be ignored. */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client read %d\n", r);
        +					cr_num -= r;
        +					}
        +				}
        +
        +			/* c_time and s_time increments will typically be very small
        +			 * (depending on machine speed and clock tick intervals),
        +			 * but sampling over a large number of connections should
        +			 * result in fairly accurate figures.  We cannot guarantee
        +			 * a lot, however -- if each connection lasts for exactly
        +			 * one clock tick, it will be counted only for the client
        +			 * or only for the server or even not at all.
        +			 */
        +			*c_time += (clock() - c_clock);
        +			}
        +
        +			{
        +			/* SERVER */
        +		
        +			MS_STATIC char sbuf[1024*8];
        +			int i, r;
        +			clock_t s_clock = clock();
        +
        +			memset(sbuf, 0, sizeof(sbuf));
        +
        +			if (debug)
        +				if (SSL_in_init(s_ssl))
        +					printf("server waiting in SSL_accept - %s\n",
        +						SSL_state_string_long(s_ssl));
        +
        +			if (sw_num > 0)
        +				{
        +				/* Write to client. */
        +				
        +				if (sw_num > (long)sizeof sbuf)
        +					i = sizeof sbuf;
        +				else
        +					i = (int)sw_num;
        +				r = BIO_write(s_ssl_bio, sbuf, i);
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(s_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						goto err;
        +						}
        +					/* Ignore "BIO_should_retry". */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server wrote %d\n", r);
        +					sw_num -= r;				
        +					}
        +				}
        +
        +			if (sr_num > 0)
        +				{
        +				/* Read from client. */
        +
        +				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(s_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						goto err;
        +						}
        +					/* blah, blah */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server read %d\n", r);
        +					sr_num -= r;
        +					}
        +				}
        +
        +			*s_time += (clock() - s_clock);
        +			}
        +			
        +			{
        +			/* "I/O" BETWEEN CLIENT AND SERVER. */
        +
        +			size_t r1, r2;
        +			BIO *io1 = server_io, *io2 = client_io;
        +			/* we use the non-copying interface for io1
        +			 * and the standard BIO_write/BIO_read interface for io2
        +			 */
        +			
        +			static int prev_progress = 1;
        +			int progress = 0;
        +			
        +			/* io1 to io2 */
        +			do
        +				{
        +				size_t num;
        +				int r;
        +
        +				r1 = BIO_ctrl_pending(io1);
        +				r2 = BIO_ctrl_get_write_guarantee(io2);
        +
        +				num = r1;
        +				if (r2 < num)
        +					num = r2;
        +				if (num)
        +					{
        +					char *dataptr;
        +
        +					if (INT_MAX < num) /* yeah, right */
        +						num = INT_MAX;
        +					
        +					r = BIO_nread(io1, &dataptr, (int)num);
        +					assert(r > 0);
        +					assert(r <= (int)num);
        +					/* possibly r < num (non-contiguous data) */
        +					num = r;
        +					r = BIO_write(io2, dataptr, (int)num);
        +					if (r != (int)num) /* can't happen */
        +						{
        +						fprintf(stderr, "ERROR: BIO_write could not write "
        +							"BIO_ctrl_get_write_guarantee() bytes");
        +						goto err;
        +						}
        +					progress = 1;
        +
        +					if (debug)
        +						printf((io1 == client_io) ?
        +							"C->S relaying: %d bytes\n" :
        +							"S->C relaying: %d bytes\n",
        +							(int)num);
        +					}
        +				}
        +			while (r1 && r2);
        +
        +			/* io2 to io1 */
        +			{
        +				size_t num;
        +				int r;
        +
        +				r1 = BIO_ctrl_pending(io2);
        +				r2 = BIO_ctrl_get_read_request(io1);
        +				/* here we could use ..._get_write_guarantee instead of
        +				 * ..._get_read_request, but by using the latter
        +				 * we test restartability of the SSL implementation
        +				 * more thoroughly */
        +				num = r1;
        +				if (r2 < num)
        +					num = r2;
        +				if (num)
        +					{
        +					char *dataptr;
        +					
        +					if (INT_MAX < num)
        +						num = INT_MAX;
        +
        +					if (num > 1)
        +						--num; /* test restartability even more thoroughly */
        +					
        +					r = BIO_nwrite0(io1, &dataptr);
        +					assert(r > 0);
        +					if (r < (int)num)
        +						num = r;
        +					r = BIO_read(io2, dataptr, (int)num);
        +					if (r != (int)num) /* can't happen */
        +						{
        +						fprintf(stderr, "ERROR: BIO_read could not read "
        +							"BIO_ctrl_pending() bytes");
        +						goto err;
        +						}
        +					progress = 1;
        +					r = BIO_nwrite(io1, &dataptr, (int)num);
        +					if (r != (int)num) /* can't happen */
        +						{
        +						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
        +							"BIO_nwrite0() bytes");
        +						goto err;
        +						}
        +					
        +					if (debug)
        +						printf((io2 == client_io) ?
        +							"C->S relaying: %d bytes\n" :
        +							"S->C relaying: %d bytes\n",
        +							(int)num);
        +					}
        +			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
        +
        +			if (!progress && !prev_progress)
        +				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
        +					{
        +					fprintf(stderr, "ERROR: got stuck\n");
        +					if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)
        +						{
        +						fprintf(stderr, "This can happen for SSL2 because "
        +							"CLIENT-FINISHED and SERVER-VERIFY are written \n"
        +							"concurrently ...");
        +						if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
        +							&& strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)
        +							{
        +							fprintf(stderr, " ok.\n");
        +							goto end;
        +							}
        +						}
        +					fprintf(stderr, " ERROR.\n");
        +					goto err;
        +					}
        +			prev_progress = progress;
        +			}
        +		}
        +	while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
        +
        +	if (verbose)
        +		print_details(c_ssl, "DONE via BIO pair: ");
        +end:
        +	ret = 0;
        +
        + err:
        +	ERR_print_errors(bio_err);
        +	
        +	if (server)
        +		BIO_free(server);
        +	if (server_io)
        +		BIO_free(server_io);
        +	if (client)
        +		BIO_free(client);
        +	if (client_io)
        +		BIO_free(client_io);
        +	if (s_ssl_bio)
        +		BIO_free(s_ssl_bio);
        +	if (c_ssl_bio)
        +		BIO_free(c_ssl_bio);
        +
        +	return ret;
        +	}
        +
        +
        +#define W_READ	1
        +#define W_WRITE	2
        +#define C_DONE	1
        +#define S_DONE	2
        +
        +int doit(SSL *s_ssl, SSL *c_ssl, long count)
        +	{
        +	MS_STATIC char cbuf[1024*8],sbuf[1024*8];
        +	long cw_num=count,cr_num=count;
        +	long sw_num=count,sr_num=count;
        +	int ret=1;
        +	BIO *c_to_s=NULL;
        +	BIO *s_to_c=NULL;
        +	BIO *c_bio=NULL;
        +	BIO *s_bio=NULL;
        +	int c_r,c_w,s_r,s_w;
        +	int i,j;
        +	int done=0;
        +	int c_write,s_write;
        +	int do_server=0,do_client=0;
        +
        +	memset(cbuf,0,sizeof(cbuf));
        +	memset(sbuf,0,sizeof(sbuf));
        +
        +	c_to_s=BIO_new(BIO_s_mem());
        +	s_to_c=BIO_new(BIO_s_mem());
        +	if ((s_to_c == NULL) || (c_to_s == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	c_bio=BIO_new(BIO_f_ssl());
        +	s_bio=BIO_new(BIO_f_ssl());
        +	if ((c_bio == NULL) || (s_bio == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	SSL_set_connect_state(c_ssl);
        +	SSL_set_bio(c_ssl,s_to_c,c_to_s);
        +	BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
        +
        +	SSL_set_accept_state(s_ssl);
        +	SSL_set_bio(s_ssl,c_to_s,s_to_c);
        +	BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
        +
        +	c_r=0; s_r=1;
        +	c_w=1; s_w=0;
        +	c_write=1,s_write=0;
        +
        +	/* We can always do writes */
        +	for (;;)
        +		{
        +		do_server=0;
        +		do_client=0;
        +
        +		i=(int)BIO_pending(s_bio);
        +		if ((i && s_r) || s_w) do_server=1;
        +
        +		i=(int)BIO_pending(c_bio);
        +		if ((i && c_r) || c_w) do_client=1;
        +
        +		if (do_server && debug)
        +			{
        +			if (SSL_in_init(s_ssl))
        +				printf("server waiting in SSL_accept - %s\n",
        +					SSL_state_string_long(s_ssl));
        +/*			else if (s_write)
        +				printf("server:SSL_write()\n");
        +			else
        +				printf("server:SSL_read()\n"); */
        +			}
        +
        +		if (do_client && debug)
        +			{
        +			if (SSL_in_init(c_ssl))
        +				printf("client waiting in SSL_connect - %s\n",
        +					SSL_state_string_long(c_ssl));
        +/*			else if (c_write)
        +				printf("client:SSL_write()\n");
        +			else
        +				printf("client:SSL_read()\n"); */
        +			}
        +
        +		if (!do_client && !do_server)
        +			{
        +			fprintf(stdout,"ERROR IN STARTUP\n");
        +			ERR_print_errors(bio_err);
        +			break;
        +			}
        +		if (do_client && !(done & C_DONE))
        +			{
        +			if (c_write)
        +				{
        +				j = (cw_num > (long)sizeof(cbuf)) ?
        +					(int)sizeof(cbuf) : (int)cw_num;
        +				i=BIO_write(c_bio,cbuf,j);
        +				if (i < 0)
        +					{
        +					c_r=0;
        +					c_w=0;
        +					if (BIO_should_retry(c_bio))
        +						{
        +						if (BIO_should_read(c_bio))
        +							c_r=1;
        +						if (BIO_should_write(c_bio))
        +							c_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client wrote %d\n",i);
        +					/* ok */
        +					s_r=1;
        +					c_write=0;
        +					cw_num-=i;
        +					}
        +				}
        +			else
        +				{
        +				i=BIO_read(c_bio,cbuf,sizeof(cbuf));
        +				if (i < 0)
        +					{
        +					c_r=0;
        +					c_w=0;
        +					if (BIO_should_retry(c_bio))
        +						{
        +						if (BIO_should_read(c_bio))
        +							c_r=1;
        +						if (BIO_should_write(c_bio))
        +							c_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client read %d\n",i);
        +					cr_num-=i;
        +					if (sw_num > 0)
        +						{
        +						s_write=1;
        +						s_w=1;
        +						}
        +					if (cr_num <= 0)
        +						{
        +						s_write=1;
        +						s_w=1;
        +						done=S_DONE|C_DONE;
        +						}
        +					}
        +				}
        +			}
        +
        +		if (do_server && !(done & S_DONE))
        +			{
        +			if (!s_write)
        +				{
        +				i=BIO_read(s_bio,sbuf,sizeof(cbuf));
        +				if (i < 0)
        +					{
        +					s_r=0;
        +					s_w=0;
        +					if (BIO_should_retry(s_bio))
        +						{
        +						if (BIO_should_read(s_bio))
        +							s_r=1;
        +						if (BIO_should_write(s_bio))
        +							s_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					ERR_print_errors(bio_err);
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server read %d\n",i);
        +					sr_num-=i;
        +					if (cw_num > 0)
        +						{
        +						c_write=1;
        +						c_w=1;
        +						}
        +					if (sr_num <= 0)
        +						{
        +						s_write=1;
        +						s_w=1;
        +						c_write=0;
        +						}
        +					}
        +				}
        +			else
        +				{
        +				j = (sw_num > (long)sizeof(sbuf)) ?
        +					(int)sizeof(sbuf) : (int)sw_num;
        +				i=BIO_write(s_bio,sbuf,j);
        +				if (i < 0)
        +					{
        +					s_r=0;
        +					s_w=0;
        +					if (BIO_should_retry(s_bio))
        +						{
        +						if (BIO_should_read(s_bio))
        +							s_r=1;
        +						if (BIO_should_write(s_bio))
        +							s_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					ERR_print_errors(bio_err);
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server wrote %d\n",i);
        +					sw_num-=i;
        +					s_write=0;
        +					c_r=1;
        +					if (sw_num <= 0)
        +						done|=S_DONE;
        +					}
        +				}
        +			}
        +
        +		if ((done & S_DONE) && (done & C_DONE)) break;
        +		}
        +
        +	if (verbose)
        +		print_details(c_ssl, "DONE: ");
        +	ret=0;
        +err:
        +	/* We have to set the BIO's to NULL otherwise they will be
        +	 * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and
        +	 * again when c_ssl is SSL_free()ed.
        +	 * This is a hack required because s_ssl and c_ssl are sharing the same
        +	 * BIO structure and SSL_set_bio() and SSL_free() automatically
        +	 * BIO_free non NULL entries.
        +	 * You should not normally do this or be required to do this */
        +	if (s_ssl != NULL)
        +		{
        +		s_ssl->rbio=NULL;
        +		s_ssl->wbio=NULL;
        +		}
        +	if (c_ssl != NULL)
        +		{
        +		c_ssl->rbio=NULL;
        +		c_ssl->wbio=NULL;
        +		}
        +
        +	if (c_to_s != NULL) BIO_free(c_to_s);
        +	if (s_to_c != NULL) BIO_free(s_to_c);
        +	if (c_bio != NULL) BIO_free_all(c_bio);
        +	if (s_bio != NULL) BIO_free_all(s_bio);
        +	return(ret);
        +	}
        +
        +static int get_proxy_auth_ex_data_idx(void)
        +	{
        +	static volatile int idx = -1;
        +	if (idx < 0)
        +		{
        +		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +		if (idx < 0)
        +			{
        +			idx = X509_STORE_CTX_get_ex_new_index(0,
        +				"SSLtest for verify callback", NULL,NULL,NULL);
        +			}
        +		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +		}
        +	return idx;
        +	}
        +
        +static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	char *s,buf[256];
        +
        +	s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
        +			    sizeof buf);
        +	if (s != NULL)
        +		{
        +		if (ok)
        +			fprintf(stderr,"depth=%d %s\n",
        +				ctx->error_depth,buf);
        +		else
        +			{
        +			fprintf(stderr,"depth=%d error=%d %s\n",
        +				ctx->error_depth,ctx->error,buf);
        +			}
        +		}
        +
        +	if (ok == 0)
        +		{
        +		fprintf(stderr,"Error string: %s\n",
        +			X509_verify_cert_error_string(ctx->error));
        +		switch (ctx->error)
        +			{
        +		case X509_V_ERR_CERT_NOT_YET_VALID:
        +		case X509_V_ERR_CERT_HAS_EXPIRED:
        +		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        +			fprintf(stderr,"  ... ignored.\n");
        +			ok=1;
        +			}
        +		}
        +
        +	if (ok == 1)
        +		{
        +		X509 *xs = ctx->current_cert;
        +#if 0
        +		X509 *xi = ctx->current_issuer;
        +#endif
        +
        +		if (xs->ex_flags & EXFLAG_PROXY)
        +			{
        +			unsigned int *letters =
        +				X509_STORE_CTX_get_ex_data(ctx,
        +					get_proxy_auth_ex_data_idx());
        +
        +			if (letters)
        +				{
        +				int found_any = 0;
        +				int i;
        +				PROXY_CERT_INFO_EXTENSION *pci =
        +					X509_get_ext_d2i(xs, NID_proxyCertInfo,
        +						NULL, NULL);
        +
        +				switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
        +					{
        +				case NID_Independent:
        +					/* Completely meaningless in this
        +					   program, as there's no way to
        +					   grant explicit rights to a
        +					   specific PrC.  Basically, using
        +					   id-ppl-Independent is the perfect
        +					   way to grant no rights at all. */
        +					fprintf(stderr, "  Independent proxy certificate");
        +					for (i = 0; i < 26; i++)
        +						letters[i] = 0;
        +					break;
        +				case NID_id_ppl_inheritAll:
        +					/* This is basically a NOP, we
        +					   simply let the current rights
        +					   stand as they are. */
        +					fprintf(stderr, "  Proxy certificate inherits all");
        +					break;
        +				default:
        +					s = (char *)
        +						pci->proxyPolicy->policy->data;
        +					i = pci->proxyPolicy->policy->length;
        +
        +					/* The algorithm works as follows:
        +					   it is assumed that previous
        +					   iterations or the initial granted
        +					   rights has already set some elements
        +					   of `letters'.  What we need to do is
        +					   to clear those that weren't granted
        +					   by the current PrC as well.  The
        +					   easiest way to do this is to add 1
        +					   to all the elements whose letters
        +					   are given with the current policy.
        +					   That way, all elements that are set
        +					   by the current policy and were
        +					   already set by earlier policies and
        +					   through the original grant of rights
        +					   will get the value 2 or higher.
        +					   The last thing to do is to sweep
        +					   through `letters' and keep the
        +					   elements having the value 2 as set,
        +					   and clear all the others. */
        +
        +					fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
        +					while(i-- > 0)
        +						{
        +						int c = *s++;
        +						if (isascii(c) && isalpha(c))
        +							{
        +							if (islower(c))
        +								c = toupper(c);
        +							letters[c - 'A']++;
        +							}
        +						}
        +					for (i = 0; i < 26; i++)
        +						if (letters[i] < 2)
        +							letters[i] = 0;
        +						else
        +							letters[i] = 1;
        +					}
        +
        +				found_any = 0;
        +				fprintf(stderr,
        +					", resulting proxy rights = ");
        +				for(i = 0; i < 26; i++)
        +					if (letters[i])
        +						{
        +						fprintf(stderr, "%c", i + 'A');
        +						found_any = 1;
        +						}
        +				if (!found_any)
        +					fprintf(stderr, "none");
        +				fprintf(stderr, "\n");
        +
        +				PROXY_CERT_INFO_EXTENSION_free(pci);
        +				}
        +			}
        +		}
        +
        +	return(ok);
        +	}
        +
        +static void process_proxy_debug(int indent, const char *format, ...)
        +	{
        +	static const char indentation[] =
        +		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
        +		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
        +	char my_format[256];
        +	va_list args;
        +
        +	BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
        +		indent, indent, indentation, format);
        +
        +	va_start(args, format);
        +	vfprintf(stderr, my_format, args);
        +	va_end(args);
        +	}
        +/* Priority levels:
        +   0	[!]var, ()
        +   1	& ^
        +   2	|
        +*/
        +static int process_proxy_cond_adders(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent);
        +static int process_proxy_cond_val(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent)
        +	{
        +	int c;
        +	int ok = 1;
        +	int negate = 0;
        +
        +	while(isspace((int)*cond))
        +		{
        +		cond++; (*pos)++;
        +		}
        +	c = *cond;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"Start process_proxy_cond_val at position %d: %s\n",
        +			*pos, cond);
        +
        +	while(c == '!')
        +		{
        +		negate = !negate;
        +		cond++; (*pos)++;
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +		}
        +
        +	if (c == '(')
        +		{
        +		cond++; (*pos)++;
        +		ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
        +			indent + 1);
        +		cond = *cond_end;
        +		if (ok < 0)
        +			goto end;
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +		if (c != ')')
        +			{
        +			fprintf(stderr,
        +				"Weird condition character in position %d: "
        +				"%c\n", *pos, c);
        +			ok = -1;
        +			goto end;
        +			}
        +		cond++; (*pos)++;
        +		}
        +	else if (isascii(c) && isalpha(c))
        +		{
        +		if (islower(c))
        +			c = toupper(c);
        +		ok = letters[c - 'A'];
        +		cond++; (*pos)++;
        +		}
        +	else
        +		{
        +		fprintf(stderr,
        +			"Weird condition character in position %d: "
        +			"%c\n", *pos, c);
        +		ok = -1;
        +		goto end;
        +		}
        + end:
        +	*cond_end = cond;
        +	if (ok >= 0 && negate)
        +		ok = !ok;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"End process_proxy_cond_val at position %d: %s, returning %d\n",
        +			*pos, cond, ok);
        +
        +	return ok;
        +	}
        +static int process_proxy_cond_multipliers(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent)
        +	{
        +	int ok;
        +	char c;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"Start process_proxy_cond_multipliers at position %d: %s\n",
        +			*pos, cond);
        +
        +	ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
        +	cond = *cond_end;
        +	if (ok < 0)
        +		goto end;
        +
        +	while(ok >= 0)
        +		{
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +
        +		switch(c)
        +			{
        +		case '&':
        +		case '^':
        +			{
        +			int save_ok = ok;
        +
        +			cond++; (*pos)++;
        +			ok = process_proxy_cond_val(letters,
        +				cond, cond_end, pos, indent + 1);
        +			cond = *cond_end;
        +			if (ok < 0)
        +				break;
        +
        +			switch(c)
        +				{
        +			case '&':
        +				ok &= save_ok;
        +				break;
        +			case '^':
        +				ok ^= save_ok;
        +				break;
        +			default:
        +				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
        +					" STOPPING\n");
        +				EXIT(1);
        +				}
        +			}
        +			break;
        +		default:
        +			goto end;
        +			}
        +		}
        + end:
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
        +			*pos, cond, ok);
        +
        +	*cond_end = cond;
        +	return ok;
        +	}
        +static int process_proxy_cond_adders(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent)
        +	{
        +	int ok;
        +	char c;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"Start process_proxy_cond_adders at position %d: %s\n",
        +			*pos, cond);
        +
        +	ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
        +		indent + 1);
        +	cond = *cond_end;
        +	if (ok < 0)
        +		goto end;
        +
        +	while(ok >= 0)
        +		{
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +
        +		switch(c)
        +			{
        +		case '|':
        +			{
        +			int save_ok = ok;
        +
        +			cond++; (*pos)++;
        +			ok = process_proxy_cond_multipliers(letters,
        +				cond, cond_end, pos, indent + 1);
        +			cond = *cond_end;
        +			if (ok < 0)
        +				break;
        +
        +			switch(c)
        +				{
        +			case '|':
        +				ok |= save_ok;
        +				break;
        +			default:
        +				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
        +					" STOPPING\n");
        +				EXIT(1);
        +				}
        +			}
        +			break;
        +		default:
        +			goto end;
        +			}
        +		}
        + end:
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"End process_proxy_cond_adders at position %d: %s, returning %d\n",
        +			*pos, cond, ok);
        +
        +	*cond_end = cond;
        +	return ok;
        +	}
        +
        +static int process_proxy_cond(unsigned int letters[26],
        +	const char *cond, const char **cond_end)
        +	{
        +	int pos = 1;
        +	return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
        +	}
        +
        +static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
        +	{
        +	int ok=1;
        +	struct app_verify_arg *cb_arg = arg;
        +	unsigned int letters[26]; /* only used with proxy_auth */
        +
        +	if (cb_arg->app_verify)
        +		{
        +		char *s = NULL,buf[256];
        +
        +		fprintf(stderr, "In app_verify_callback, allowing cert. ");
        +		fprintf(stderr, "Arg is: %s\n", cb_arg->string);
        +		fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
        +			(void *)ctx, (void *)ctx->cert);
        +		if (ctx->cert)
        +			s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
        +		if (s != NULL)
        +			{
        +			fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
        +			}
        +		return(1);
        +		}
        +	if (cb_arg->proxy_auth)
        +		{
        +		int found_any = 0, i;
        +		char *sp;
        +
        +		for(i = 0; i < 26; i++)
        +			letters[i] = 0;
        +		for(sp = cb_arg->proxy_auth; *sp; sp++)
        +			{
        +			int c = *sp;
        +			if (isascii(c) && isalpha(c))
        +				{
        +				if (islower(c))
        +					c = toupper(c);
        +				letters[c - 'A'] = 1;
        +				}
        +			}
        +
        +		fprintf(stderr,
        +			"  Initial proxy rights = ");
        +		for(i = 0; i < 26; i++)
        +			if (letters[i])
        +				{
        +				fprintf(stderr, "%c", i + 'A');
        +				found_any = 1;
        +				}
        +		if (!found_any)
        +			fprintf(stderr, "none");
        +		fprintf(stderr, "\n");
        +
        +		X509_STORE_CTX_set_ex_data(ctx,
        +			get_proxy_auth_ex_data_idx(),letters);
        +		}
        +	if (cb_arg->allow_proxy_certs)
        +		{
        +		X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
        +		}
        +
        +#ifndef OPENSSL_NO_X509_VERIFY
        +	ok = X509_verify_cert(ctx);
        +#endif
        +
        +	if (cb_arg->proxy_auth)
        +		{
        +		if (ok > 0)
        +			{
        +			const char *cond_end = NULL;
        +
        +			ok = process_proxy_cond(letters,
        +				cb_arg->proxy_cond, &cond_end);
        +
        +			if (ok < 0)
        +				EXIT(3);
        +			if (*cond_end)
        +				{
        +				fprintf(stderr, "Stopped processing condition before it's end.\n");
        +				ok = 0;
        +				}
        +			if (!ok)
        +				fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
        +					cb_arg->proxy_cond);
        +			else
        +				fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
        +					cb_arg->proxy_cond);
        +			}
        +		}
        +	return(ok);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA *rsa_tmp=NULL;
        +
        +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
        +	{
        +	BIGNUM *bn = NULL;
        +	if (rsa_tmp == NULL)
        +		{
        +		bn = BN_new();
        +		rsa_tmp = RSA_new();
        +		if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
        +			{
        +			BIO_printf(bio_err, "Memory error...");
        +			goto end;
        +			}
        +		BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
        +		(void)BIO_flush(bio_err);
        +		if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
        +			{
        +			BIO_printf(bio_err, "Error generating key.");
        +			RSA_free(rsa_tmp);
        +			rsa_tmp = NULL;
        +			}
        +end:
        +		BIO_printf(bio_err,"\n");
        +		(void)BIO_flush(bio_err);
        +		}
        +	if(bn) BN_free(bn);
        +	return(rsa_tmp);
        +	}
        +
        +static void free_tmp_rsa(void)
        +	{
        +	if (rsa_tmp != NULL)
        +		{
        +		RSA_free(rsa_tmp);
        +		rsa_tmp = NULL;
        +		}
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* These DH parameters have been generated as follows:
        + *    $ openssl dhparam -C -noout 512
        + *    $ openssl dhparam -C -noout 1024
        + *    $ openssl dhparam -C -noout -dsaparam 1024
        + * (The third function has been renamed to avoid name conflicts.)
        + */
        +static DH *get_dh512()
        +	{
        +	static unsigned char dh512_p[]={
        +		0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
        +		0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
        +		0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
        +		0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
        +		0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
        +		0x02,0xC5,0xAE,0x23,
        +		};
        +	static unsigned char dh512_g[]={
        +		0x02,
        +		};
        +	DH *dh;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
        +	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		{ DH_free(dh); return(NULL); }
        +	return(dh);
        +	}
        +
        +static DH *get_dh1024()
        +	{
        +	static unsigned char dh1024_p[]={
        +		0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
        +		0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
        +		0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
        +		0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
        +		0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
        +		0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
        +		0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
        +		0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
        +		0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
        +		0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
        +		0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
        +		};
        +	static unsigned char dh1024_g[]={
        +		0x02,
        +		};
        +	DH *dh;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
        +	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		{ DH_free(dh); return(NULL); }
        +	return(dh);
        +	}
        +
        +static DH *get_dh1024dsa()
        +	{
        +	static unsigned char dh1024_p[]={
        +		0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
        +		0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
        +		0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
        +		0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
        +		0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
        +		0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
        +		0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
        +		0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
        +		0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
        +		0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
        +		0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
        +		};
        +	static unsigned char dh1024_g[]={
        +		0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
        +		0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
        +		0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
        +		0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
        +		0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
        +		0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
        +		0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
        +		0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
        +		0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
        +		0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
        +		0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
        +		};
        +	DH *dh;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
        +	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		{ DH_free(dh); return(NULL); }
        +	dh->length = 160;
        +	return(dh);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +/* convert the PSK key (psk_key) in ascii to binary (psk) */
        +static int psk_key2bn(const char *pskkey, unsigned char *psk,
        +	unsigned int max_psk_len)
        +	{
        +	int ret;
        +	BIGNUM *bn = NULL;
        +
        +	ret = BN_hex2bn(&bn, pskkey);
        +	if (!ret)
        +		{
        +		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", pskkey); 
        +		if (bn)
        +			BN_free(bn);
        +		return 0;
        +		}
        +	if (BN_num_bytes(bn) > (int)max_psk_len)
        +		{
        +		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
        +			max_psk_len, BN_num_bytes(bn));
        +		BN_free(bn);
        +		return 0;
        +		}
        +	ret = BN_bn2bin(bn, psk);
        +	BN_free(bn);
        +	return ret;
        +	}
        +
        +static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
        +	unsigned int max_identity_len, unsigned char *psk,
        +	unsigned int max_psk_len)
        +	{
        +	int ret;
        +	unsigned int psk_len = 0;
        +
        +	ret = BIO_snprintf(identity, max_identity_len, "Client_identity");
        +	if (ret < 0)
        +		goto out_err;
        +	if (debug)
        +		fprintf(stderr, "client: created identity '%s' len=%d\n", identity, ret);
        +	ret = psk_key2bn(psk_key, psk, max_psk_len);
        +	if (ret < 0)
        +		goto out_err;
        +	psk_len = ret;
        +out_err:
        +	return psk_len;
        +	}
        +
        +static unsigned int psk_server_callback(SSL *ssl, const char *identity,
        +	unsigned char *psk, unsigned int max_psk_len)
        +	{
        +	unsigned int psk_len=0;
        +
        +	if (strcmp(identity, "Client_identity") != 0)
        +		{
        +		BIO_printf(bio_err, "server: PSK error: client identity not found\n");
        +		return 0;
        +		}
        +	psk_len=psk_key2bn(psk_key, psk, max_psk_len);
        +	return psk_len;
        +	}
        +#endif
        +
        +static int do_test_cipherlist(void)
        +	{
        +	int i = 0;
        +	const SSL_METHOD *meth;
        +	const SSL_CIPHER *ci, *tci = NULL;
        +
        +#ifndef OPENSSL_NO_SSL2
        +	fprintf(stderr, "testing SSLv2 cipher list order: ");
        +	meth = SSLv2_method();
        +	while ((ci = meth->get_cipher(i++)) != NULL)
        +		{
        +		if (tci != NULL)
        +			if (ci->id >= tci->id)
        +				{
        +				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
        +				return 0;
        +				}
        +		tci = ci;
        +		}
        +	fprintf(stderr, "ok\n");
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +	fprintf(stderr, "testing SSLv3 cipher list order: ");
        +	meth = SSLv3_method();
        +	tci = NULL;
        +	while ((ci = meth->get_cipher(i++)) != NULL)
        +		{
        +		if (tci != NULL)
        +			if (ci->id >= tci->id)
        +				{
        +				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
        +				return 0;
        +				}
        +		tci = ci;
        +		}
        +	fprintf(stderr, "ok\n");
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +	fprintf(stderr, "testing TLSv1 cipher list order: ");
        +	meth = TLSv1_method();
        +	tci = NULL;
        +	while ((ci = meth->get_cipher(i++)) != NULL)
        +		{
        +		if (tci != NULL)
        +			if (ci->id >= tci->id)
        +				{
        +				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
        +				return 0;
        +				}
        +		tci = ci;
        +		}
        +	fprintf(stderr, "ok\n");
        +#endif
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/ssl/t1_clnt.c b/vendor/openssl/openssl/ssl/t1_clnt.c
        new file mode 100644
        index 000000000..578617ed8
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/t1_clnt.c
        @@ -0,0 +1,92 @@
        +/* ssl/t1_clnt.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +
        +static const SSL_METHOD *tls1_get_client_method(int ver);
        +static const SSL_METHOD *tls1_get_client_method(int ver)
        +	{
        +	if (ver == TLS1_2_VERSION)
        +		return TLSv1_2_client_method();
        +	if (ver == TLS1_1_VERSION)
        +		return TLSv1_1_client_method();
        +	if (ver == TLS1_VERSION)
        +		return TLSv1_client_method();
        +	return NULL;
        +	}
        +
        +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method,
        +			ssl_undefined_function,
        +			ssl3_connect,
        +			tls1_get_client_method)
        +
        +IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method,
        +			ssl_undefined_function,
        +			ssl3_connect,
        +			tls1_get_client_method)
        +
        +IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method,
        +			ssl_undefined_function,
        +			ssl3_connect,
        +			tls1_get_client_method)
        +
        diff --git a/vendor/openssl/openssl/ssl/t1_enc.c b/vendor/openssl/openssl/ssl/t1_enc.c
        new file mode 100644
        index 000000000..809ad2ee1
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/t1_enc.c
        @@ -0,0 +1,1247 @@
        +/* ssl/t1_enc.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#ifndef OPENSSL_NO_COMP
        +#include <openssl/comp.h>
        +#endif
        +#include <openssl/evp.h>
        +#include <openssl/hmac.h>
        +#include <openssl/md5.h>
        +#include <openssl/rand.h>
        +#ifdef KSSL_DEBUG
        +#include <openssl/des.h>
        +#endif
        +
        +/* seed1 through seed5 are virtually concatenated */
        +static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
        +			int sec_len,
        +			const void *seed1, int seed1_len,
        +			const void *seed2, int seed2_len,
        +			const void *seed3, int seed3_len,
        +			const void *seed4, int seed4_len,
        +			const void *seed5, int seed5_len,
        +			unsigned char *out, int olen)
        +	{
        +	int chunk;
        +	size_t j;
        +	EVP_MD_CTX ctx, ctx_tmp;
        +	EVP_PKEY *mac_key;
        +	unsigned char A1[EVP_MAX_MD_SIZE];
        +	size_t A1_len;
        +	int ret = 0;
        +	
        +	chunk=EVP_MD_size(md);
        +	OPENSSL_assert(chunk >= 0);
        +
        +	EVP_MD_CTX_init(&ctx);
        +	EVP_MD_CTX_init(&ctx_tmp);
        +	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +	EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        +	mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
        +	if (!mac_key)
        +		goto err;
        +	if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
        +		goto err;
        +	if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
        +		goto err;
        +	if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
        +		goto err;
        +	if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
        +		goto err;
        +	if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
        +		goto err;
        +	if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
        +		goto err;
        +	if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
        +		goto err;
        +	if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
        +		goto err;
        +
        +	for (;;)
        +		{
        +		/* Reinit mac contexts */
        +		if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
        +			goto err;
        +		if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
        +			goto err;
        +		if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
        +			goto err;
        +		if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
        +			goto err;
        +		if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
        +			goto err;
        +		if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
        +			goto err;
        +		if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
        +			goto err;
        +		if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
        +			goto err;
        +		if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
        +			goto err;
        +
        +		if (olen > chunk)
        +			{
        +			if (!EVP_DigestSignFinal(&ctx,out,&j))
        +				goto err;
        +			out+=j;
        +			olen-=j;
        +			/* calc the next A1 value */
        +			if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len))
        +				goto err;
        +			}
        +		else	/* last one */
        +			{
        +			if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
        +				goto err;
        +			memcpy(out,A1,olen);
        +			break;
        +			}
        +		}
        +	ret = 1;
        +err:
        +	EVP_PKEY_free(mac_key);
        +	EVP_MD_CTX_cleanup(&ctx);
        +	EVP_MD_CTX_cleanup(&ctx_tmp);
        +	OPENSSL_cleanse(A1,sizeof(A1));
        +	return ret;
        +	}
        +
        +/* seed1 through seed5 are virtually concatenated */
        +static int tls1_PRF(long digest_mask,
        +		     const void *seed1, int seed1_len,
        +		     const void *seed2, int seed2_len,
        +		     const void *seed3, int seed3_len,
        +		     const void *seed4, int seed4_len,
        +		     const void *seed5, int seed5_len,
        +		     const unsigned char *sec, int slen,
        +		     unsigned char *out1,
        +		     unsigned char *out2, int olen)
        +	{
        +	int len,i,idx,count;
        +	const unsigned char *S1;
        +	long m;
        +	const EVP_MD *md;
        +	int ret = 0;
        +
        +	/* Count number of digests and partition sec evenly */
        +	count=0;
        +	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
        +		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
        +	}	
        +	len=slen/count;
        +	if (count == 1)
        +		slen = 0;
        +	S1=sec;
        +	memset(out1,0,olen);
        +	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
        +		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) {
        +			if (!md) {
        +				SSLerr(SSL_F_TLS1_PRF,
        +				SSL_R_UNSUPPORTED_DIGEST_TYPE);
        +				goto err;				
        +			}
        +			if (!tls1_P_hash(md ,S1,len+(slen&1),
        +					seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len,
        +					out2,olen))
        +				goto err;
        +			S1+=len;
        +			for (i=0; i<olen; i++)
        +			{
        +				out1[i]^=out2[i];
        +			}
        +		}
        +	}
        +	ret = 1;
        +err:
        +	return ret;
        +}
        +static int tls1_generate_key_block(SSL *s, unsigned char *km,
        +	     unsigned char *tmp, int num)
        +	{
        +	int ret;
        +	ret = tls1_PRF(ssl_get_algorithm2(s),
        +		 TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
        +		 s->s3->server_random,SSL3_RANDOM_SIZE,
        +		 s->s3->client_random,SSL3_RANDOM_SIZE,
        +		 NULL,0,NULL,0,
        +		 s->session->master_key,s->session->master_key_length,
        +		 km,tmp,num);
        +#ifdef KSSL_DEBUG
        +	printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
        +                s->session->master_key_length);
        +	{
        +        int i;
        +        for (i=0; i < s->session->master_key_length; i++)
        +                {
        +                printf("%02X", s->session->master_key[i]);
        +                }
        +        printf("\n");  }
        +#endif    /* KSSL_DEBUG */
        +	return ret;
        +	}
        +
        +int tls1_change_cipher_state(SSL *s, int which)
        +	{
        +	static const unsigned char empty[]="";
        +	unsigned char *p,*mac_secret;
        +	unsigned char *exp_label;
        +	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
        +	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
        +	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
        +	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
        +	unsigned char *ms,*key,*iv;
        +	int client_write;
        +	EVP_CIPHER_CTX *dd;
        +	const EVP_CIPHER *c;
        +#ifndef OPENSSL_NO_COMP
        +	const SSL_COMP *comp;
        +#endif
        +	const EVP_MD *m;
        +	int mac_type;
        +	int *mac_secret_size;
        +	EVP_MD_CTX *mac_ctx;
        +	EVP_PKEY *mac_key;
        +	int is_export,n,i,j,k,exp_label_len,cl;
        +	int reuse_dd = 0;
        +
        +	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
        +	c=s->s3->tmp.new_sym_enc;
        +	m=s->s3->tmp.new_hash;
        +	mac_type = s->s3->tmp.new_mac_pkey_type;
        +#ifndef OPENSSL_NO_COMP
        +	comp=s->s3->tmp.new_compression;
        +#endif
        +
        +#ifdef KSSL_DEBUG
        +	printf("tls1_change_cipher_state(which= %d) w/\n", which);
        +	printf("\talg= %ld/%ld, comp= %p\n",
        +	       s->s3->tmp.new_cipher->algorithm_mkey,
        +	       s->s3->tmp.new_cipher->algorithm_auth,
        +	       comp);
        +	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
        +	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
        +                c->nid,c->block_size,c->key_len,c->iv_len);
        +	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
        +	{
        +        int i;
        +        for (i=0; i<s->s3->tmp.key_block_length; i++)
        +		printf("%02x", s->s3->tmp.key_block[i]);  printf("\n");
        +        }
        +#endif	/* KSSL_DEBUG */
        +
        +	if (which & SSL3_CC_READ)
        +		{
        +		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
        +			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
        +		else
        +			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
        +
        +		if (s->enc_read_ctx != NULL)
        +			reuse_dd = 1;
        +		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
        +			goto err;
        +		else
        +			/* make sure it's intialized in case we exit later with an error */
        +			EVP_CIPHER_CTX_init(s->enc_read_ctx);
        +		dd= s->enc_read_ctx;
        +		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
        +#ifndef OPENSSL_NO_COMP
        +		if (s->expand != NULL)
        +			{
        +			COMP_CTX_free(s->expand);
        +			s->expand=NULL;
        +			}
        +		if (comp != NULL)
        +			{
        +			s->expand=COMP_CTX_new(comp->method);
        +			if (s->expand == NULL)
        +				{
        +				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
        +				goto err2;
        +				}
        +			if (s->s3->rrec.comp == NULL)
        +				s->s3->rrec.comp=(unsigned char *)
        +					OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
        +			if (s->s3->rrec.comp == NULL)
        +				goto err;
        +			}
        +#endif
        +		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
        + 		if (s->version != DTLS1_VERSION)
        +			memset(&(s->s3->read_sequence[0]),0,8);
        +		mac_secret= &(s->s3->read_mac_secret[0]);
        +		mac_secret_size=&(s->s3->read_mac_secret_size);
        +		}
        +	else
        +		{
        +		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
        +			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
        +			else
        +			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
        +		if (s->enc_write_ctx != NULL)
        +			reuse_dd = 1;
        +		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
        +			goto err;
        +		else
        +			/* make sure it's intialized in case we exit later with an error */
        +			EVP_CIPHER_CTX_init(s->enc_write_ctx);
        +		dd= s->enc_write_ctx;
        +		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
        +#ifndef OPENSSL_NO_COMP
        +		if (s->compress != NULL)
        +			{
        +			COMP_CTX_free(s->compress);
        +			s->compress=NULL;
        +			}
        +		if (comp != NULL)
        +			{
        +			s->compress=COMP_CTX_new(comp->method);
        +			if (s->compress == NULL)
        +				{
        +				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
        +				goto err2;
        +				}
        +			}
        +#endif
        +		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
        + 		if (s->version != DTLS1_VERSION)
        +			memset(&(s->s3->write_sequence[0]),0,8);
        +		mac_secret= &(s->s3->write_mac_secret[0]);
        +		mac_secret_size = &(s->s3->write_mac_secret_size);
        +		}
        +
        +	if (reuse_dd)
        +		EVP_CIPHER_CTX_cleanup(dd);
        +
        +	p=s->s3->tmp.key_block;
        +	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
        +
        +	cl=EVP_CIPHER_key_length(c);
        +	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
        +	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
        +	/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
        +	/* If GCM mode only part of IV comes from PRF */
        +	if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
        +		k = EVP_GCM_TLS_FIXED_IV_LEN;
        +	else
        +		k=EVP_CIPHER_iv_length(c);
        +	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
        +		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
        +		{
        +		ms=  &(p[ 0]); n=i+i;
        +		key= &(p[ n]); n+=j+j;
        +		iv=  &(p[ n]); n+=k+k;
        +		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
        +		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
        +		client_write=1;
        +		}
        +	else
        +		{
        +		n=i;
        +		ms=  &(p[ n]); n+=i+j;
        +		key= &(p[ n]); n+=j+k;
        +		iv=  &(p[ n]); n+=k;
        +		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
        +		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
        +		client_write=0;
        +		}
        +
        +	if (n > s->s3->tmp.key_block_length)
        +		{
        +		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
        +		goto err2;
        +		}
        +
        +	memcpy(mac_secret,ms,i);
        +
        +	if (!(EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER))
        +		{
        +		mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
        +				mac_secret,*mac_secret_size);
        +		EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
        +		EVP_PKEY_free(mac_key);
        +		}
        +#ifdef TLS_DEBUG
        +printf("which = %04X\nmac key=",which);
        +{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
        +#endif
        +	if (is_export)
        +		{
        +		/* In here I set both the read and write key/iv to the
        +		 * same value since only the correct one will be used :-).
        +		 */
        +		if (!tls1_PRF(ssl_get_algorithm2(s),
        +				exp_label,exp_label_len,
        +				s->s3->client_random,SSL3_RANDOM_SIZE,
        +				s->s3->server_random,SSL3_RANDOM_SIZE,
        +				NULL,0,NULL,0,
        +				key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
        +			goto err2;
        +		key=tmp1;
        +
        +		if (k > 0)
        +			{
        +			if (!tls1_PRF(ssl_get_algorithm2(s),
        +					TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
        +					s->s3->client_random,SSL3_RANDOM_SIZE,
        +					s->s3->server_random,SSL3_RANDOM_SIZE,
        +					NULL,0,NULL,0,
        +					empty,0,iv1,iv2,k*2))
        +				goto err2;
        +			if (client_write)
        +				iv=iv1;
        +			else
        +				iv= &(iv1[k]);
        +			}
        +		}
        +
        +	s->session->key_arg_length=0;
        +#ifdef KSSL_DEBUG
        +	{
        +        int i;
        +	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
        +	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
        +	printf("\n");
        +	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
        +	printf("\n");
        +	}
        +#endif	/* KSSL_DEBUG */
        +
        +	if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
        +		{
        +		EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE));
        +		EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
        +		}
        +	else	
        +		EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
        +
        +	/* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
        +	if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
        +		EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY,
        +				*mac_secret_size,mac_secret);
        +
        +#ifdef TLS_DEBUG
        +printf("which = %04X\nkey=",which);
        +{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
        +printf("\niv=");
        +{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
        +printf("\n");
        +#endif
        +
        +	OPENSSL_cleanse(tmp1,sizeof(tmp1));
        +	OPENSSL_cleanse(tmp2,sizeof(tmp1));
        +	OPENSSL_cleanse(iv1,sizeof(iv1));
        +	OPENSSL_cleanse(iv2,sizeof(iv2));
        +	return(1);
        +err:
        +	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
        +err2:
        +	return(0);
        +	}
        +
        +int tls1_setup_key_block(SSL *s)
        +	{
        +	unsigned char *p1,*p2=NULL;
        +	const EVP_CIPHER *c;
        +	const EVP_MD *hash;
        +	int num;
        +	SSL_COMP *comp;
        +	int mac_type= NID_undef,mac_secret_size=0;
        +	int ret=0;
        +
        +#ifdef KSSL_DEBUG
        +	printf ("tls1_setup_key_block()\n");
        +#endif	/* KSSL_DEBUG */
        +
        +	if (s->s3->tmp.key_block_length != 0)
        +		return(1);
        +
        +	if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
        +		{
        +		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
        +		return(0);
        +		}
        +
        +	s->s3->tmp.new_sym_enc=c;
        +	s->s3->tmp.new_hash=hash;
        +	s->s3->tmp.new_mac_pkey_type = mac_type;
        +	s->s3->tmp.new_mac_secret_size = mac_secret_size;
        +	num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
        +	num*=2;
        +
        +	ssl3_cleanup_key_block(s);
        +
        +	if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL)
        +		{
        +		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +	s->s3->tmp.key_block_length=num;
        +	s->s3->tmp.key_block=p1;
        +
        +	if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL)
        +		{
        +		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
        +		goto err;
        +		}
        +
        +#ifdef TLS_DEBUG
        +printf("client random\n");
        +{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); }
        +printf("server random\n");
        +{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); }
        +printf("pre-master\n");
        +{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
        +#endif
        +	if (!tls1_generate_key_block(s,p1,p2,num))
        +		goto err;
        +#ifdef TLS_DEBUG
        +printf("\nkey block\n");
        +{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
        +#endif
        +
        +	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
        +		&& s->method->version <= TLS1_VERSION)
        +		{
        +		/* enable vulnerability countermeasure for CBC ciphers with
        +		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
        +		 */
        +		s->s3->need_empty_fragments = 1;
        +
        +		if (s->session->cipher != NULL)
        +			{
        +			if (s->session->cipher->algorithm_enc == SSL_eNULL)
        +				s->s3->need_empty_fragments = 0;
        +			
        +#ifndef OPENSSL_NO_RC4
        +			if (s->session->cipher->algorithm_enc == SSL_RC4)
        +				s->s3->need_empty_fragments = 0;
        +#endif
        +			}
        +		}
        +		
        +	ret = 1;
        +err:
        +	if (p2)
        +		{
        +		OPENSSL_cleanse(p2,num);
        +		OPENSSL_free(p2);
        +		}
        +	return(ret);
        +	}
        +
        +/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
        + *
        + * Returns:
        + *   0: (in non-constant time) if the record is publically invalid (i.e. too
        + *       short etc).
        + *   1: if the record's padding is valid / the encryption was successful.
        + *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
        + *       an internal error occured.
        + */
        +int tls1_enc(SSL *s, int send)
        +	{
        +	SSL3_RECORD *rec;
        +	EVP_CIPHER_CTX *ds;
        +	unsigned long l;
        +	int bs,i,j,k,pad=0,ret,mac_size=0;
        +	const EVP_CIPHER *enc;
        +
        +	if (send)
        +		{
        +		if (EVP_MD_CTX_md(s->write_hash))
        +			{
        +			int n=EVP_MD_CTX_size(s->write_hash);
        +			OPENSSL_assert(n >= 0);
        +			}
        +		ds=s->enc_write_ctx;
        +		rec= &(s->s3->wrec);
        +		if (s->enc_write_ctx == NULL)
        +			enc=NULL;
        +		else
        +			{
        +			int ivlen;
        +			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
        +			/* For TLSv1.1 and later explicit IV */
        +			if (s->version >= TLS1_1_VERSION
        +				&& EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
        +				ivlen = EVP_CIPHER_iv_length(enc);
        +			else
        +				ivlen = 0;
        +			if (ivlen > 1)
        +				{
        +				if ( rec->data != rec->input)
        +					/* we can't write into the input stream:
        +					 * Can this ever happen?? (steve)
        +					 */
        +					fprintf(stderr,
        +						"%s:%d: rec->data != rec->input\n",
        +						__FILE__, __LINE__);
        +				else if (RAND_bytes(rec->input, ivlen) <= 0)
        +					return -1;
        +				}
        +			}
        +		}
        +	else
        +		{
        +		if (EVP_MD_CTX_md(s->read_hash))
        +			{
        +			int n=EVP_MD_CTX_size(s->read_hash);
        +			OPENSSL_assert(n >= 0);
        +			}
        +		ds=s->enc_read_ctx;
        +		rec= &(s->s3->rrec);
        +		if (s->enc_read_ctx == NULL)
        +			enc=NULL;
        +		else
        +			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
        +		}
        +
        +#ifdef KSSL_DEBUG
        +	printf("tls1_enc(%d)\n", send);
        +#endif    /* KSSL_DEBUG */
        +
        +	if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
        +		{
        +		memmove(rec->data,rec->input,rec->length);
        +		rec->input=rec->data;
        +		ret = 1;
        +		}
        +	else
        +		{
        +		l=rec->length;
        +		bs=EVP_CIPHER_block_size(ds->cipher);
        +
        +		if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
        +			{
        +			unsigned char buf[13],*seq;
        +
        +			seq = send?s->s3->write_sequence:s->s3->read_sequence;
        +
        +			if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
        +				{
        +				unsigned char dtlsseq[9],*p=dtlsseq;
        +
        +				s2n(send?s->d1->w_epoch:s->d1->r_epoch,p);
        +				memcpy(p,&seq[2],6);
        +				memcpy(buf,dtlsseq,8);
        +				}
        +			else
        +				{
        +				memcpy(buf,seq,8);
        +				for (i=7; i>=0; i--)	/* increment */
        +					{
        +					++seq[i];
        +					if (seq[i] != 0) break; 
        +					}
        +				}
        +
        +			buf[8]=rec->type;
        +			buf[9]=(unsigned char)(s->version>>8);
        +			buf[10]=(unsigned char)(s->version);
        +			buf[11]=rec->length>>8;
        +			buf[12]=rec->length&0xff;
        +			pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf);
        +			if (send)
        +				{
        +				l+=pad;
        +				rec->length+=pad;
        +				}
        +			}
        +		else if ((bs != 1) && send)
        +			{
        +			i=bs-((int)l%bs);
        +
        +			/* Add weird padding of upto 256 bytes */
        +
        +			/* we need to add 'i' padding bytes of value j */
        +			j=i-1;
        +			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
        +				{
        +				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
        +					j++;
        +				}
        +			for (k=(int)l; k<(int)(l+i); k++)
        +				rec->input[k]=j;
        +			l+=i;
        +			rec->length+=i;
        +			}
        +
        +#ifdef KSSL_DEBUG
        +		{
        +		unsigned long ui;
        +		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
        +			ds,rec->data,rec->input,l);
        +		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
        +			ds->buf_len, ds->cipher->key_len,
        +			DES_KEY_SZ, DES_SCHEDULE_SZ,
        +			ds->cipher->iv_len);
        +		printf("\t\tIV: ");
        +		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
        +		printf("\n");
        +		printf("\trec->input=");
        +		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
        +		printf("\n");
        +		}
        +#endif	/* KSSL_DEBUG */
        +
        +		if (!send)
        +			{
        +			if (l == 0 || l%bs != 0)
        +				return 0;
        +			}
        +		
        +		i = EVP_Cipher(ds,rec->data,rec->input,l);
        +		if ((EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_CUSTOM_CIPHER)
        +						?(i<0)
        +						:(i==0))
        +			return -1;	/* AEAD can fail to verify MAC */
        +		if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send)
        +			{
        +			rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +			rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +			rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
        +			}
        +
        +#ifdef KSSL_DEBUG
        +		{
        +		unsigned long i;
        +		printf("\trec->data=");
        +		for (i=0; i<l; i++)
        +			printf(" %02x", rec->data[i]);  printf("\n");
        +		}
        +#endif	/* KSSL_DEBUG */
        +
        +		ret = 1;
        +		if (EVP_MD_CTX_md(s->read_hash) != NULL)
        +			mac_size = EVP_MD_CTX_size(s->read_hash);
        +		if ((bs != 1) && !send)
        +			ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
        +		if (pad && !send)
        +			rec->length -= pad;
        +		}
        +	return ret;
        +	}
        +
        +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
        +	{
        +	unsigned int ret;
        +	EVP_MD_CTX ctx, *d=NULL;
        +	int i;
        +
        +	if (s->s3->handshake_buffer) 
        +		if (!ssl3_digest_cached_records(s))
        +			return 0;
        +
        +	for (i=0;i<SSL_MAX_DIGEST;i++) 
        +		{
        +		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) 
        +		  	{
        +		  	d=s->s3->handshake_dgst[i];
        +			break;
        +			}
        +		}
        +	if (!d) {
        +		SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC,SSL_R_NO_REQUIRED_DIGEST);
        +		return 0;
        +	}	
        +
        +	EVP_MD_CTX_init(&ctx);
        +	EVP_MD_CTX_copy_ex(&ctx,d);
        +	EVP_DigestFinal_ex(&ctx,out,&ret);
        +	EVP_MD_CTX_cleanup(&ctx);
        +	return((int)ret);
        +	}
        +
        +int tls1_final_finish_mac(SSL *s,
        +	     const char *str, int slen, unsigned char *out)
        +	{
        +	unsigned int i;
        +	EVP_MD_CTX ctx;
        +	unsigned char buf[2*EVP_MAX_MD_SIZE];
        +	unsigned char *q,buf2[12];
        +	int idx;
        +	long mask;
        +	int err=0;
        +	const EVP_MD *md; 
        +
        +	q=buf;
        +
        +	if (s->s3->handshake_buffer) 
        +		if (!ssl3_digest_cached_records(s))
        +			return 0;
        +
        +	EVP_MD_CTX_init(&ctx);
        +
        +	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
        +		{
        +		if (mask & ssl_get_algorithm2(s))
        +			{
        +			int hashsize = EVP_MD_size(md);
        +			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
        +				{
        +				/* internal error: 'buf' is too small for this cipersuite! */
        +				err = 1;
        +				}
        +			else
        +				{
        +				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
        +				EVP_DigestFinal_ex(&ctx,q,&i);
        +				if (i != (unsigned int)hashsize) /* can't really happen */
        +					err = 1;
        +				q+=i;
        +				}
        +			}
        +		}
        +		
        +	if (!tls1_PRF(ssl_get_algorithm2(s),
        +			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
        +			s->session->master_key,s->session->master_key_length,
        +			out,buf2,sizeof buf2))
        +		err = 1;
        +	EVP_MD_CTX_cleanup(&ctx);
        +
        +	if (err)
        +		return 0;
        +	else
        +		return sizeof buf2;
        +	}
        +
        +int tls1_mac(SSL *ssl, unsigned char *md, int send)
        +	{
        +	SSL3_RECORD *rec;
        +	unsigned char *seq;
        +	EVP_MD_CTX *hash;
        +	size_t md_size, orig_len;
        +	int i;
        +	EVP_MD_CTX hmac, *mac_ctx;
        +	unsigned char header[13];
        +	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
        +	int t;
        +
        +	if (send)
        +		{
        +		rec= &(ssl->s3->wrec);
        +		seq= &(ssl->s3->write_sequence[0]);
        +		hash=ssl->write_hash;
        +		}
        +	else
        +		{
        +		rec= &(ssl->s3->rrec);
        +		seq= &(ssl->s3->read_sequence[0]);
        +		hash=ssl->read_hash;
        +		}
        +
        +	t=EVP_MD_CTX_size(hash);
        +	OPENSSL_assert(t >= 0);
        +	md_size=t;
        +
        +	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
        +	if (stream_mac) 
        +		{
        +			mac_ctx = hash;
        +		}
        +		else
        +		{
        +			EVP_MD_CTX_copy(&hmac,hash);
        +			mac_ctx = &hmac;
        +		}
        +
        +	if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER)
        +		{
        +		unsigned char dtlsseq[8],*p=dtlsseq;
        +
        +		s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
        +		memcpy (p,&seq[2],6);
        +
        +		memcpy(header, dtlsseq, 8);
        +		}
        +	else
        +		memcpy(header, seq, 8);
        +
        +	/* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
        +	orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
        +	rec->type &= 0xff;
        +
        +	header[8]=rec->type;
        +	header[9]=(unsigned char)(ssl->version>>8);
        +	header[10]=(unsigned char)(ssl->version);
        +	header[11]=(rec->length)>>8;
        +	header[12]=(rec->length)&0xff;
        +
        +	if (!send &&
        +	    EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
        +	    ssl3_cbc_record_digest_supported(mac_ctx))
        +		{
        +		/* This is a CBC-encrypted record. We must avoid leaking any
        +		 * timing-side channel information about how many blocks of
        +		 * data we are hashing because that gives an attacker a
        +		 * timing-oracle. */
        +		ssl3_cbc_digest_record(
        +			mac_ctx,
        +			md, &md_size,
        +			header, rec->input,
        +			rec->length + md_size, orig_len,
        +			ssl->s3->read_mac_secret,
        +			ssl->s3->read_mac_secret_size,
        +			0 /* not SSLv3 */);
        +		}
        +	else
        +		{
        +		EVP_DigestSignUpdate(mac_ctx,header,sizeof(header));
        +		EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
        +		t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
        +		OPENSSL_assert(t > 0);
        +#ifdef OPENSSL_FIPS
        +		if (!send && FIPS_mode())
        +			tls_fips_digest_extra(
        +	    				ssl->enc_read_ctx,
        +					mac_ctx, rec->input,
        +					rec->length, orig_len);
        +#endif
        +		}
        +		
        +	if (!stream_mac)
        +		EVP_MD_CTX_cleanup(&hmac);
        +#ifdef TLS_DEBUG
        +printf("sec=");
        +{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
        +printf("seq=");
        +{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
        +printf("buf=");
        +{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
        +printf("rec=");
        +{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
        +#endif
        +
        +	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
        +		{
        +		for (i=7; i>=0; i--)
        +			{
        +			++seq[i];
        +			if (seq[i] != 0) break; 
        +			}
        +		}
        +
        +#ifdef TLS_DEBUG
        +{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
        +#endif
        +	return(md_size);
        +	}
        +
        +int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
        +	     int len)
        +	{
        +	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
        +	const void *co = NULL, *so = NULL;
        +	int col = 0, sol = 0;
        +
        +
        +#ifdef KSSL_DEBUG
        +	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
        +#endif	/* KSSL_DEBUG */
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	if (s->s3->client_opaque_prf_input != NULL && s->s3->server_opaque_prf_input != NULL &&
        +	    s->s3->client_opaque_prf_input_len > 0 &&
        +	    s->s3->client_opaque_prf_input_len == s->s3->server_opaque_prf_input_len)
        +		{
        +		co = s->s3->client_opaque_prf_input;
        +		col = s->s3->server_opaque_prf_input_len;
        +		so = s->s3->server_opaque_prf_input;
        +		sol = s->s3->client_opaque_prf_input_len; /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */
        +		}
        +#endif
        +
        +	tls1_PRF(ssl_get_algorithm2(s),
        +		TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
        +		s->s3->client_random,SSL3_RANDOM_SIZE,
        +		co, col,
        +		s->s3->server_random,SSL3_RANDOM_SIZE,
        +		so, sol,
        +		p,len,
        +		s->session->master_key,buff,sizeof buff);
        +#ifdef SSL_DEBUG
        +	fprintf(stderr, "Premaster Secret:\n");
        +	BIO_dump_fp(stderr, (char *)p, len);
        +	fprintf(stderr, "Client Random:\n");
        +	BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE);
        +	fprintf(stderr, "Server Random:\n");
        +	BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE);
        +	fprintf(stderr, "Master Secret:\n");
        +	BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
        +#endif
        +
        +#ifdef KSSL_DEBUG
        +	printf ("tls1_generate_master_secret() complete\n");
        +#endif	/* KSSL_DEBUG */
        +	return(SSL3_MASTER_SECRET_SIZE);
        +	}
        +
        +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
        +	 const char *label, size_t llen, const unsigned char *context,
        +	 size_t contextlen, int use_context)
        +	{
        +	unsigned char *buff;
        +	unsigned char *val = NULL;
        +	size_t vallen, currentvalpos;
        +	int rv;
        +
        +#ifdef KSSL_DEBUG
        +	printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
        +#endif	/* KSSL_DEBUG */
        +
        +	buff = OPENSSL_malloc(olen);
        +	if (buff == NULL) goto err2;
        +
        +	/* construct PRF arguments
        +	 * we construct the PRF argument ourself rather than passing separate
        +	 * values into the TLS PRF to ensure that the concatenation of values
        +	 * does not create a prohibited label.
        +	 */
        +	vallen = llen + SSL3_RANDOM_SIZE * 2;
        +	if (use_context)
        +		{
        +		vallen += 2 + contextlen;
        +		}
        +
        +	val = OPENSSL_malloc(vallen);
        +	if (val == NULL) goto err2;
        +	currentvalpos = 0;
        +	memcpy(val + currentvalpos, (unsigned char *) label, llen);
        +	currentvalpos += llen;
        +	memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
        +	currentvalpos += SSL3_RANDOM_SIZE;
        +	memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
        +	currentvalpos += SSL3_RANDOM_SIZE;
        +
        +	if (use_context)
        +		{
        +		val[currentvalpos] = (contextlen >> 8) & 0xff;
        +		currentvalpos++;
        +		val[currentvalpos] = contextlen & 0xff;
        +		currentvalpos++;
        +		if ((contextlen > 0) || (context != NULL))
        +			{
        +			memcpy(val + currentvalpos, context, contextlen);
        +			}
        +		}
        +
        +	/* disallow prohibited labels
        +	 * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
        +	 * 15, so size of val > max(prohibited label len) = 15 and the
        +	 * comparisons won't have buffer overflow
        +	 */
        +	if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
        +		 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
        +	if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
        +		 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
        +	if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
        +		 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
        +	if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
        +		 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
        +
        +	rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
        +		      val, vallen,
        +		      NULL, 0,
        +		      NULL, 0,
        +		      NULL, 0,
        +		      NULL, 0,
        +		      s->session->master_key,s->session->master_key_length,
        +		      out,buff,olen);
        +
        +#ifdef KSSL_DEBUG
        +	printf ("tls1_export_keying_material() complete\n");
        +#endif	/* KSSL_DEBUG */
        +	goto ret;
        +err1:
        +	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
        +	rv = 0;
        +	goto ret;
        +err2:
        +	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
        +	rv = 0;
        +ret:
        +	if (buff != NULL) OPENSSL_free(buff);
        +	if (val != NULL) OPENSSL_free(val);
        +	return(rv);
        +	}
        +
        +int tls1_alert_code(int code)
        +	{
        +	switch (code)
        +		{
        +	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
        +	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
        +	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
        +	case SSL_AD_DECRYPTION_FAILED:	return(TLS1_AD_DECRYPTION_FAILED);
        +	case SSL_AD_RECORD_OVERFLOW:	return(TLS1_AD_RECORD_OVERFLOW);
        +	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
        +	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
        +	case SSL_AD_NO_CERTIFICATE:	return(-1);
        +	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
        +	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
        +	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
        +	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
        +	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
        +	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
        +	case SSL_AD_UNKNOWN_CA:		return(TLS1_AD_UNKNOWN_CA);
        +	case SSL_AD_ACCESS_DENIED:	return(TLS1_AD_ACCESS_DENIED);
        +	case SSL_AD_DECODE_ERROR:	return(TLS1_AD_DECODE_ERROR);
        +	case SSL_AD_DECRYPT_ERROR:	return(TLS1_AD_DECRYPT_ERROR);
        +	case SSL_AD_EXPORT_RESTRICTION:	return(TLS1_AD_EXPORT_RESTRICTION);
        +	case SSL_AD_PROTOCOL_VERSION:	return(TLS1_AD_PROTOCOL_VERSION);
        +	case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY);
        +	case SSL_AD_INTERNAL_ERROR:	return(TLS1_AD_INTERNAL_ERROR);
        +	case SSL_AD_USER_CANCELLED:	return(TLS1_AD_USER_CANCELLED);
        +	case SSL_AD_NO_RENEGOTIATION:	return(TLS1_AD_NO_RENEGOTIATION);
        +	case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
        +	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
        +	case SSL_AD_UNRECOGNIZED_NAME:	return(TLS1_AD_UNRECOGNIZED_NAME);
        +	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
        +	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
        +	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
        +#if 0 /* not appropriate for TLS, not used for DTLS */
        +	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
        +					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
        +#endif
        +	default:			return(-1);
        +		}
        +	}
        diff --git a/vendor/openssl/openssl/ssl/t1_lib.c b/vendor/openssl/openssl/ssl/t1_lib.c
        new file mode 100644
        index 000000000..e08088c57
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/t1_lib.c
        @@ -0,0 +1,2623 @@
        +/* ssl/t1_lib.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2007 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 <stdio.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/hmac.h>
        +#include <openssl/ocsp.h>
        +#include <openssl/rand.h>
        +#include "ssl_locl.h"
        +
        +const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
        +				const unsigned char *sess_id, int sesslen,
        +				SSL_SESSION **psess);
        +#endif
        +
        +SSL3_ENC_METHOD TLSv1_enc_data={
        +	tls1_enc,
        +	tls1_mac,
        +	tls1_setup_key_block,
        +	tls1_generate_master_secret,
        +	tls1_change_cipher_state,
        +	tls1_final_finish_mac,
        +	TLS1_FINISH_MAC_LENGTH,
        +	tls1_cert_verify_mac,
        +	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
        +	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
        +	tls1_alert_code,
        +	tls1_export_keying_material,
        +	};
        +
        +long tls1_default_timeout(void)
        +	{
        +	/* 2 hours, the 24 hours mentioned in the TLSv1 spec
        +	 * is way too long for http, the cache would over fill */
        +	return(60*60*2);
        +	}
        +
        +int tls1_new(SSL *s)
        +	{
        +	if (!ssl3_new(s)) return(0);
        +	s->method->ssl_clear(s);
        +	return(1);
        +	}
        +
        +void tls1_free(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_TLSEXT
        +	if (s->tlsext_session_ticket)
        +		{
        +		OPENSSL_free(s->tlsext_session_ticket);
        +		}
        +#endif /* OPENSSL_NO_TLSEXT */
        +	ssl3_free(s);
        +	}
        +
        +void tls1_clear(SSL *s)
        +	{
        +	ssl3_clear(s);
        +	s->version = s->method->version;
        +	}
        +
        +#ifndef OPENSSL_NO_EC
        +
        +static int nid_list[] =
        +	{
        +		NID_sect163k1, /* sect163k1 (1) */
        +		NID_sect163r1, /* sect163r1 (2) */
        +		NID_sect163r2, /* sect163r2 (3) */
        +		NID_sect193r1, /* sect193r1 (4) */ 
        +		NID_sect193r2, /* sect193r2 (5) */ 
        +		NID_sect233k1, /* sect233k1 (6) */
        +		NID_sect233r1, /* sect233r1 (7) */ 
        +		NID_sect239k1, /* sect239k1 (8) */ 
        +		NID_sect283k1, /* sect283k1 (9) */
        +		NID_sect283r1, /* sect283r1 (10) */ 
        +		NID_sect409k1, /* sect409k1 (11) */ 
        +		NID_sect409r1, /* sect409r1 (12) */
        +		NID_sect571k1, /* sect571k1 (13) */ 
        +		NID_sect571r1, /* sect571r1 (14) */ 
        +		NID_secp160k1, /* secp160k1 (15) */
        +		NID_secp160r1, /* secp160r1 (16) */ 
        +		NID_secp160r2, /* secp160r2 (17) */ 
        +		NID_secp192k1, /* secp192k1 (18) */
        +		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
        +		NID_secp224k1, /* secp224k1 (20) */ 
        +		NID_secp224r1, /* secp224r1 (21) */
        +		NID_secp256k1, /* secp256k1 (22) */ 
        +		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
        +		NID_secp384r1, /* secp384r1 (24) */
        +		NID_secp521r1  /* secp521r1 (25) */	
        +	};
        +
        +static int pref_list[] =
        +	{
        +		NID_sect571r1, /* sect571r1 (14) */ 
        +		NID_sect571k1, /* sect571k1 (13) */ 
        +		NID_secp521r1, /* secp521r1 (25) */	
        +		NID_sect409k1, /* sect409k1 (11) */ 
        +		NID_sect409r1, /* sect409r1 (12) */
        +		NID_secp384r1, /* secp384r1 (24) */
        +		NID_sect283k1, /* sect283k1 (9) */
        +		NID_sect283r1, /* sect283r1 (10) */ 
        +		NID_secp256k1, /* secp256k1 (22) */ 
        +		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
        +		NID_sect239k1, /* sect239k1 (8) */ 
        +		NID_sect233k1, /* sect233k1 (6) */
        +		NID_sect233r1, /* sect233r1 (7) */ 
        +		NID_secp224k1, /* secp224k1 (20) */ 
        +		NID_secp224r1, /* secp224r1 (21) */
        +		NID_sect193r1, /* sect193r1 (4) */ 
        +		NID_sect193r2, /* sect193r2 (5) */ 
        +		NID_secp192k1, /* secp192k1 (18) */
        +		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
        +		NID_sect163k1, /* sect163k1 (1) */
        +		NID_sect163r1, /* sect163r1 (2) */
        +		NID_sect163r2, /* sect163r2 (3) */
        +		NID_secp160k1, /* secp160k1 (15) */
        +		NID_secp160r1, /* secp160r1 (16) */ 
        +		NID_secp160r2, /* secp160r2 (17) */ 
        +	};
        +
        +int tls1_ec_curve_id2nid(int curve_id)
        +	{
        +	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
        +	if ((curve_id < 1) || ((unsigned int)curve_id >
        +				sizeof(nid_list)/sizeof(nid_list[0])))
        +		return 0;
        +	return nid_list[curve_id-1];
        +	}
        +
        +int tls1_ec_nid2curve_id(int nid)
        +	{
        +	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
        +	switch (nid)
        +		{
        +	case NID_sect163k1: /* sect163k1 (1) */
        +		return 1;
        +	case NID_sect163r1: /* sect163r1 (2) */
        +		return 2;
        +	case NID_sect163r2: /* sect163r2 (3) */
        +		return 3;
        +	case NID_sect193r1: /* sect193r1 (4) */ 
        +		return 4;
        +	case NID_sect193r2: /* sect193r2 (5) */ 
        +		return 5;
        +	case NID_sect233k1: /* sect233k1 (6) */
        +		return 6;
        +	case NID_sect233r1: /* sect233r1 (7) */ 
        +		return 7;
        +	case NID_sect239k1: /* sect239k1 (8) */ 
        +		return 8;
        +	case NID_sect283k1: /* sect283k1 (9) */
        +		return 9;
        +	case NID_sect283r1: /* sect283r1 (10) */ 
        +		return 10;
        +	case NID_sect409k1: /* sect409k1 (11) */ 
        +		return 11;
        +	case NID_sect409r1: /* sect409r1 (12) */
        +		return 12;
        +	case NID_sect571k1: /* sect571k1 (13) */ 
        +		return 13;
        +	case NID_sect571r1: /* sect571r1 (14) */ 
        +		return 14;
        +	case NID_secp160k1: /* secp160k1 (15) */
        +		return 15;
        +	case NID_secp160r1: /* secp160r1 (16) */ 
        +		return 16;
        +	case NID_secp160r2: /* secp160r2 (17) */ 
        +		return 17;
        +	case NID_secp192k1: /* secp192k1 (18) */
        +		return 18;
        +	case NID_X9_62_prime192v1: /* secp192r1 (19) */ 
        +		return 19;
        +	case NID_secp224k1: /* secp224k1 (20) */ 
        +		return 20;
        +	case NID_secp224r1: /* secp224r1 (21) */
        +		return 21;
        +	case NID_secp256k1: /* secp256k1 (22) */ 
        +		return 22;
        +	case NID_X9_62_prime256v1: /* secp256r1 (23) */ 
        +		return 23;
        +	case NID_secp384r1: /* secp384r1 (24) */
        +		return 24;
        +	case NID_secp521r1:  /* secp521r1 (25) */	
        +		return 25;
        +	default:
        +		return 0;
        +		}
        +	}
        +#endif /* OPENSSL_NO_EC */
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +
        +/* List of supported signature algorithms and hashes. Should make this
        + * customisable at some point, for now include everything we support.
        + */
        +
        +#ifdef OPENSSL_NO_RSA
        +#define tlsext_sigalg_rsa(md) /* */
        +#else
        +#define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
        +#endif
        +
        +#ifdef OPENSSL_NO_DSA
        +#define tlsext_sigalg_dsa(md) /* */
        +#else
        +#define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
        +#endif
        +
        +#ifdef OPENSSL_NO_ECDSA
        +#define tlsext_sigalg_ecdsa(md) /* */
        +#else
        +#define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
        +#endif
        +
        +#define tlsext_sigalg(md) \
        +		tlsext_sigalg_rsa(md) \
        +		tlsext_sigalg_dsa(md) \
        +		tlsext_sigalg_ecdsa(md)
        +
        +static unsigned char tls12_sigalgs[] = {
        +#ifndef OPENSSL_NO_SHA512
        +	tlsext_sigalg(TLSEXT_hash_sha512)
        +	tlsext_sigalg(TLSEXT_hash_sha384)
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +	tlsext_sigalg(TLSEXT_hash_sha256)
        +	tlsext_sigalg(TLSEXT_hash_sha224)
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	tlsext_sigalg(TLSEXT_hash_sha1)
        +#endif
        +#ifndef OPENSSL_NO_MD5
        +	tlsext_sigalg_rsa(TLSEXT_hash_md5)
        +#endif
        +};
        +
        +int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
        +	{
        +	size_t slen = sizeof(tls12_sigalgs);
        +#ifdef OPENSSL_FIPS
        +	/* If FIPS mode don't include MD5 which is last */
        +	if (FIPS_mode())
        +		slen -= 2;
        +#endif
        +	if (p)
        +		memcpy(p, tls12_sigalgs, slen);
        +	return (int)slen;
        +	}
        +
        +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
        +	{
        +	int extdatalen=0;
        +	unsigned char *ret = p;
        +
        +	/* don't add extensions for SSLv3 unless doing secure renegotiation */
        +	if (s->client_version == SSL3_VERSION
        +					&& !s->s3->send_connection_binding)
        +		return p;
        +
        +	ret+=2;
        +
        +	if (ret>=limit) return NULL; /* this really never occurs, but ... */
        +
        + 	if (s->tlsext_hostname != NULL)
        +		{ 
        +		/* Add TLS extension servername to the Client Hello message */
        +		unsigned long size_str;
        +		long lenmax; 
        +
        +		/* check for enough space.
        +		   4 for the servername type and entension length
        +		   2 for servernamelist length
        +		   1 for the hostname type
        +		   2 for hostname length
        +		   + hostname length 
        +		*/
        +		   
        +		if ((lenmax = limit - ret - 9) < 0 
        +		    || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
        +			return NULL;
        +			
        +		/* extension type and length */
        +		s2n(TLSEXT_TYPE_server_name,ret); 
        +		s2n(size_str+5,ret);
        +		
        +		/* length of servername list */
        +		s2n(size_str+3,ret);
        +	
        +		/* hostname type, length and hostname */
        +		*(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
        +		s2n(size_str,ret);
        +		memcpy(ret, s->tlsext_hostname, size_str);
        +		ret+=size_str;
        +		}
        +
        +        /* Add RI if renegotiating */
        +        if (s->renegotiate)
        +          {
        +          int el;
        +          
        +          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
        +              {
        +              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +              return NULL;
        +              }
        +
        +          if((limit - p - 4 - el) < 0) return NULL;
        +          
        +          s2n(TLSEXT_TYPE_renegotiate,ret);
        +          s2n(el,ret);
        +
        +          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
        +              {
        +              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +              return NULL;
        +              }
        +
        +          ret += el;
        +        }
        +
        +#ifndef OPENSSL_NO_SRP
        +	/* Add SRP username if there is one */
        +	if (s->srp_ctx.login != NULL)
        +		{ /* Add TLS extension SRP username to the Client Hello message */
        +
        +		int login_len = strlen(s->srp_ctx.login);	
        +		if (login_len > 255 || login_len == 0)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			} 
        +
        +		/* check for enough space.
        +		   4 for the srp type type and entension length
        +		   1 for the srp user identity
        +		   + srp user identity length 
        +		*/
        +		if ((limit - ret - 5 - login_len) < 0) return NULL; 
        +
        +		/* fill in the extension */
        +		s2n(TLSEXT_TYPE_srp,ret);
        +		s2n(login_len+1,ret);
        +		(*ret++) = (unsigned char) login_len;
        +		memcpy(ret, s->srp_ctx.login, login_len);
        +		ret+=login_len;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +	if (s->tlsext_ecpointformatlist != NULL &&
        +	    s->version != DTLS1_VERSION)
        +		{
        +		/* Add TLS extension ECPointFormats to the ClientHello message */
        +		long lenmax; 
        +
        +		if ((lenmax = limit - ret - 5) < 0) return NULL; 
        +		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
        +		if (s->tlsext_ecpointformatlist_length > 255)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			}
        +		
        +		s2n(TLSEXT_TYPE_ec_point_formats,ret);
        +		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
        +		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
        +		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
        +		ret+=s->tlsext_ecpointformatlist_length;
        +		}
        +	if (s->tlsext_ellipticcurvelist != NULL &&
        +	    s->version != DTLS1_VERSION)
        +		{
        +		/* Add TLS extension EllipticCurves to the ClientHello message */
        +		long lenmax; 
        +
        +		if ((lenmax = limit - ret - 6) < 0) return NULL; 
        +		if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
        +		if (s->tlsext_ellipticcurvelist_length > 65532)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			}
        +		
        +		s2n(TLSEXT_TYPE_elliptic_curves,ret);
        +		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
        +
        +		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
        +		 * elliptic_curve_list, but the examples use two bytes.
        +		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
        +		 * resolves this to two bytes.
        +		 */
        +		s2n(s->tlsext_ellipticcurvelist_length, ret);
        +		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
        +		ret+=s->tlsext_ellipticcurvelist_length;
        +		}
        +#endif /* OPENSSL_NO_EC */
        +
        +	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
        +		{
        +		int ticklen;
        +		if (!s->new_session && s->session && s->session->tlsext_tick)
        +			ticklen = s->session->tlsext_ticklen;
        +		else if (s->session && s->tlsext_session_ticket &&
        +			 s->tlsext_session_ticket->data)
        +			{
        +			ticklen = s->tlsext_session_ticket->length;
        +			s->session->tlsext_tick = OPENSSL_malloc(ticklen);
        +			if (!s->session->tlsext_tick)
        +				return NULL;
        +			memcpy(s->session->tlsext_tick,
        +			       s->tlsext_session_ticket->data,
        +			       ticklen);
        +			s->session->tlsext_ticklen = ticklen;
        +			}
        +		else
        +			ticklen = 0;
        +		if (ticklen == 0 && s->tlsext_session_ticket &&
        +		    s->tlsext_session_ticket->data == NULL)
        +			goto skip_ext;
        +		/* Check for enough room 2 for extension type, 2 for len
        + 		 * rest for ticket
        +  		 */
        +		if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
        +		s2n(TLSEXT_TYPE_session_ticket,ret); 
        +		s2n(ticklen,ret);
        +		if (ticklen)
        +			{
        +			memcpy(ret, s->session->tlsext_tick, ticklen);
        +			ret += ticklen;
        +			}
        +		}
        +		skip_ext:
        +
        +	if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
        +		{
        +		if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6)
        +			return NULL; 
        +		s2n(TLSEXT_TYPE_signature_algorithms,ret);
        +		s2n(sizeof(tls12_sigalgs) + 2, ret);
        +		s2n(sizeof(tls12_sigalgs), ret);
        +		memcpy(ret, tls12_sigalgs, sizeof(tls12_sigalgs));
        +		ret += sizeof(tls12_sigalgs);
        +		}
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	if (s->s3->client_opaque_prf_input != NULL &&
        +	    s->version != DTLS1_VERSION)
        +		{
        +		size_t col = s->s3->client_opaque_prf_input_len;
        +		
        +		if ((long)(limit - ret - 6 - col < 0))
        +			return NULL;
        +		if (col > 0xFFFD) /* can't happen */
        +			return NULL;
        +
        +		s2n(TLSEXT_TYPE_opaque_prf_input, ret); 
        +		s2n(col + 2, ret);
        +		s2n(col, ret);
        +		memcpy(ret, s->s3->client_opaque_prf_input, col);
        +		ret += col;
        +		}
        +#endif
        +
        +	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
        +	    s->version != DTLS1_VERSION)
        +		{
        +		int i;
        +		long extlen, idlen, itmp;
        +		OCSP_RESPID *id;
        +
        +		idlen = 0;
        +		for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
        +			{
        +			id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
        +			itmp = i2d_OCSP_RESPID(id, NULL);
        +			if (itmp <= 0)
        +				return NULL;
        +			idlen += itmp + 2;
        +			}
        +
        +		if (s->tlsext_ocsp_exts)
        +			{
        +			extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
        +			if (extlen < 0)
        +				return NULL;
        +			}
        +		else
        +			extlen = 0;
        +			
        +		if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
        +		s2n(TLSEXT_TYPE_status_request, ret);
        +		if (extlen + idlen > 0xFFF0)
        +			return NULL;
        +		s2n(extlen + idlen + 5, ret);
        +		*(ret++) = TLSEXT_STATUSTYPE_ocsp;
        +		s2n(idlen, ret);
        +		for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
        +			{
        +			/* save position of id len */
        +			unsigned char *q = ret;
        +			id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
        +			/* skip over id len */
        +			ret += 2;
        +			itmp = i2d_OCSP_RESPID(id, &ret);
        +			/* write id len */
        +			s2n(itmp, q);
        +			}
        +		s2n(extlen, ret);
        +		if (extlen > 0)
        +			i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
        +		}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	/* Add Heartbeat extension */
        +	s2n(TLSEXT_TYPE_heartbeat,ret);
        +	s2n(1,ret);
        +	/* Set mode:
        +	 * 1: peer may send requests
        +	 * 2: peer not allowed to send requests
        +	 */
        +	if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
        +		*(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
        +	else
        +		*(ret++) = SSL_TLSEXT_HB_ENABLED;
        +#endif
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
        +		{
        +		/* The client advertises an emtpy extension to indicate its
        +		 * support for Next Protocol Negotiation */
        +		if (limit - ret - 4 < 0)
        +			return NULL;
        +		s2n(TLSEXT_TYPE_next_proto_neg,ret);
        +		s2n(0,ret);
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_SRTP
        +        if(SSL_get_srtp_profiles(s))
        +                {
        +                int el;
        +
        +                ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
        +                
        +                if((limit - p - 4 - el) < 0) return NULL;
        +
        +                s2n(TLSEXT_TYPE_use_srtp,ret);
        +                s2n(el,ret);
        +
        +                if(ssl_add_clienthello_use_srtp_ext(s, ret, &el, el))
        +			{
        +			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			}
        +                ret += el;
        +                }
        +#endif
        +
        +	if ((extdatalen = ret-p-2)== 0) 
        +		return p;
        +
        +	s2n(extdatalen,p);
        +	return ret;
        +	}
        +
        +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
        +	{
        +	int extdatalen=0;
        +	unsigned char *ret = p;
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	int next_proto_neg_seen;
        +#endif
        +
        +	/* don't add extensions for SSLv3, unless doing secure renegotiation */
        +	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
        +		return p;
        +	
        +	ret+=2;
        +	if (ret>=limit) return NULL; /* this really never occurs, but ... */
        +
        +	if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
        +		{ 
        +		if ((long)(limit - ret - 4) < 0) return NULL; 
        +
        +		s2n(TLSEXT_TYPE_server_name,ret);
        +		s2n(0,ret);
        +		}
        +
        +	if(s->s3->send_connection_binding)
        +        {
        +          int el;
        +          
        +          if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
        +              {
        +              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +              return NULL;
        +              }
        +
        +          if((limit - p - 4 - el) < 0) return NULL;
        +          
        +          s2n(TLSEXT_TYPE_renegotiate,ret);
        +          s2n(el,ret);
        +
        +          if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
        +              {
        +              SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +              return NULL;
        +              }
        +
        +          ret += el;
        +        }
        +
        +#ifndef OPENSSL_NO_EC
        +	if (s->tlsext_ecpointformatlist != NULL &&
        +	    s->version != DTLS1_VERSION)
        +		{
        +		/* Add TLS extension ECPointFormats to the ServerHello message */
        +		long lenmax; 
        +
        +		if ((lenmax = limit - ret - 5) < 0) return NULL; 
        +		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
        +		if (s->tlsext_ecpointformatlist_length > 255)
        +			{
        +			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			}
        +		
        +		s2n(TLSEXT_TYPE_ec_point_formats,ret);
        +		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
        +		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
        +		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
        +		ret+=s->tlsext_ecpointformatlist_length;
        +
        +		}
        +	/* Currently the server should not respond with a SupportedCurves extension */
        +#endif /* OPENSSL_NO_EC */
        +
        +	if (s->tlsext_ticket_expected
        +		&& !(SSL_get_options(s) & SSL_OP_NO_TICKET)) 
        +		{ 
        +		if ((long)(limit - ret - 4) < 0) return NULL; 
        +		s2n(TLSEXT_TYPE_session_ticket,ret);
        +		s2n(0,ret);
        +		}
        +
        +	if (s->tlsext_status_expected)
        +		{ 
        +		if ((long)(limit - ret - 4) < 0) return NULL; 
        +		s2n(TLSEXT_TYPE_status_request,ret);
        +		s2n(0,ret);
        +		}
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	if (s->s3->server_opaque_prf_input != NULL &&
        +	    s->version != DTLS1_VERSION)
        +		{
        +		size_t sol = s->s3->server_opaque_prf_input_len;
        +		
        +		if ((long)(limit - ret - 6 - sol) < 0)
        +			return NULL;
        +		if (sol > 0xFFFD) /* can't happen */
        +			return NULL;
        +
        +		s2n(TLSEXT_TYPE_opaque_prf_input, ret); 
        +		s2n(sol + 2, ret);
        +		s2n(sol, ret);
        +		memcpy(ret, s->s3->server_opaque_prf_input, sol);
        +		ret += sol;
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_SRTP
        +        if(s->srtp_profile)
        +                {
        +                int el;
        +
        +                ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
        +                
        +                if((limit - p - 4 - el) < 0) return NULL;
        +
        +                s2n(TLSEXT_TYPE_use_srtp,ret);
        +                s2n(el,ret);
        +
        +                if(ssl_add_serverhello_use_srtp_ext(s, ret, &el, el))
        +			{
        +			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
        +			return NULL;
        +			}
        +                ret+=el;
        +                }
        +#endif
        +
        +	if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) 
        +		&& (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
        +		{ const unsigned char cryptopro_ext[36] = {
        +			0xfd, 0xe8, /*65000*/
        +			0x00, 0x20, /*32 bytes length*/
        +			0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, 
        +			0x03,   0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, 
        +			0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, 
        +			0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17};
        +			if (limit-ret<36) return NULL;
        +			memcpy(ret,cryptopro_ext,36);
        +			ret+=36;
        +
        +		}
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	/* Add Heartbeat extension if we've received one */
        +	if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
        +		{
        +		s2n(TLSEXT_TYPE_heartbeat,ret);
        +		s2n(1,ret);
        +		/* Set mode:
        +		 * 1: peer may send requests
        +		 * 2: peer not allowed to send requests
        +		 */
        +		if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
        +			*(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
        +		else
        +			*(ret++) = SSL_TLSEXT_HB_ENABLED;
        +
        +		}
        +#endif
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	next_proto_neg_seen = s->s3->next_proto_neg_seen;
        +	s->s3->next_proto_neg_seen = 0;
        +	if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb)
        +		{
        +		const unsigned char *npa;
        +		unsigned int npalen;
        +		int r;
        +
        +		r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
        +		if (r == SSL_TLSEXT_ERR_OK)
        +			{
        +			if ((long)(limit - ret - 4 - npalen) < 0) return NULL;
        +			s2n(TLSEXT_TYPE_next_proto_neg,ret);
        +			s2n(npalen,ret);
        +			memcpy(ret, npa, npalen);
        +			ret += npalen;
        +			s->s3->next_proto_neg_seen = 1;
        +			}
        +		}
        +#endif
        +
        +	if ((extdatalen = ret-p-2)== 0) 
        +		return p;
        +
        +	s2n(extdatalen,p);
        +	return ret;
        +	}
        +
        +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
        +	{
        +	unsigned short type;
        +	unsigned short size;
        +	unsigned short len;
        +	unsigned char *data = *p;
        +	int renegotiate_seen = 0;
        +	int sigalg_seen = 0;
        +
        +	s->servername_done = 0;
        +	s->tlsext_status_type = -1;
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	s->s3->next_proto_neg_seen = 0;
        +#endif
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
        +	                       SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
        +#endif
        +
        +	if (data >= (d+n-2))
        +		goto ri_check;
        +	n2s(data,len);
        +
        +	if (data > (d+n-len)) 
        +		goto ri_check;
        +
        +	while (data <= (d+n-4))
        +		{
        +		n2s(data,type);
        +		n2s(data,size);
        +
        +		if (data+size > (d+n))
        +	   		goto ri_check;
        +#if 0
        +		fprintf(stderr,"Received extension type %d size %d\n",type,size);
        +#endif
        +		if (s->tlsext_debug_cb)
        +			s->tlsext_debug_cb(s, 0, type, data, size,
        +						s->tlsext_debug_arg);
        +/* The servername extension is treated as follows:
        +
        +   - Only the hostname type is supported with a maximum length of 255.
        +   - The servername is rejected if too long or if it contains zeros,
        +     in which case an fatal alert is generated.
        +   - The servername field is maintained together with the session cache.
        +   - When a session is resumed, the servername call back invoked in order
        +     to allow the application to position itself to the right context. 
        +   - The servername is acknowledged if it is new for a session or when 
        +     it is identical to a previously used for the same session. 
        +     Applications can control the behaviour.  They can at any time
        +     set a 'desirable' servername for a new SSL object. This can be the
        +     case for example with HTTPS when a Host: header field is received and
        +     a renegotiation is requested. In this case, a possible servername
        +     presented in the new client hello is only acknowledged if it matches
        +     the value of the Host: field. 
        +   - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
        +     if they provide for changing an explicit servername context for the session,
        +     i.e. when the session has been established with a servername extension. 
        +   - On session reconnect, the servername extension may be absent. 
        +
        +*/      
        +
        +		if (type == TLSEXT_TYPE_server_name)
        +			{
        +			unsigned char *sdata;
        +			int servname_type;
        +			int dsize; 
        +		
        +			if (size < 2) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			n2s(data,dsize);  
        +			size -= 2;
        +			if (dsize > size  ) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				} 
        +
        +			sdata = data;
        +			while (dsize > 3) 
        +				{
        +	 			servname_type = *(sdata++); 
        +				n2s(sdata,len);
        +				dsize -= 3;
        +
        +				if (len > dsize) 
        +					{
        +					*al = SSL_AD_DECODE_ERROR;
        +					return 0;
        +					}
        +				if (s->servername_done == 0)
        +				switch (servname_type)
        +					{
        +				case TLSEXT_NAMETYPE_host_name:
        +					if (!s->hit)
        +						{
        +						if(s->session->tlsext_hostname)
        +							{
        +							*al = SSL_AD_DECODE_ERROR;
        +							return 0;
        +							}
        +						if (len > TLSEXT_MAXLEN_host_name)
        +							{
        +							*al = TLS1_AD_UNRECOGNIZED_NAME;
        +							return 0;
        +							}
        +						if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)
        +							{
        +							*al = TLS1_AD_INTERNAL_ERROR;
        +							return 0;
        +							}
        +						memcpy(s->session->tlsext_hostname, sdata, len);
        +						s->session->tlsext_hostname[len]='\0';
        +						if (strlen(s->session->tlsext_hostname) != len) {
        +							OPENSSL_free(s->session->tlsext_hostname);
        +							s->session->tlsext_hostname = NULL;
        +							*al = TLS1_AD_UNRECOGNIZED_NAME;
        +							return 0;
        +						}
        +						s->servername_done = 1; 
        +
        +						}
        +					else 
        +						s->servername_done = s->session->tlsext_hostname
        +							&& strlen(s->session->tlsext_hostname) == len 
        +							&& strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
        +					
        +					break;
        +
        +				default:
        +					break;
        +					}
        +				 
        +				dsize -= len;
        +				}
        +			if (dsize != 0) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +
        +			}
        +#ifndef OPENSSL_NO_SRP
        +		else if (type == TLSEXT_TYPE_srp)
        +			{
        +			if (size <= 0 || ((len = data[0])) != (size -1))
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			if (s->srp_ctx.login != NULL)
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL)
        +				return -1;
        +			memcpy(s->srp_ctx.login, &data[1], len);
        +			s->srp_ctx.login[len]='\0';
        +  
        +			if (strlen(s->srp_ctx.login) != len) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			}
        +#endif
        +
        +#ifndef OPENSSL_NO_EC
        +		else if (type == TLSEXT_TYPE_ec_point_formats &&
        +	             s->version != DTLS1_VERSION)
        +			{
        +			unsigned char *sdata = data;
        +			int ecpointformatlist_length = *(sdata++);
        +
        +			if (ecpointformatlist_length != size - 1)
        +				{
        +				*al = TLS1_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			if (!s->hit)
        +				{
        +				if(s->session->tlsext_ecpointformatlist)
        +					{
        +					OPENSSL_free(s->session->tlsext_ecpointformatlist);
        +					s->session->tlsext_ecpointformatlist = NULL;
        +					}
        +				s->session->tlsext_ecpointformatlist_length = 0;
        +				if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
        +					{
        +					*al = TLS1_AD_INTERNAL_ERROR;
        +					return 0;
        +					}
        +				s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
        +				memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
        +				}
        +#if 0
        +			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
        +			sdata = s->session->tlsext_ecpointformatlist;
        +			for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
        +				fprintf(stderr,"%i ",*(sdata++));
        +			fprintf(stderr,"\n");
        +#endif
        +			}
        +		else if (type == TLSEXT_TYPE_elliptic_curves &&
        +	             s->version != DTLS1_VERSION)
        +			{
        +			unsigned char *sdata = data;
        +			int ellipticcurvelist_length = (*(sdata++) << 8);
        +			ellipticcurvelist_length += (*(sdata++));
        +
        +			if (ellipticcurvelist_length != size - 2 ||
        +				ellipticcurvelist_length < 1)
        +				{
        +				*al = TLS1_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			if (!s->hit)
        +				{
        +				if(s->session->tlsext_ellipticcurvelist)
        +					{
        +					*al = TLS1_AD_DECODE_ERROR;
        +					return 0;
        +					}
        +				s->session->tlsext_ellipticcurvelist_length = 0;
        +				if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
        +					{
        +					*al = TLS1_AD_INTERNAL_ERROR;
        +					return 0;
        +					}
        +				s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
        +				memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
        +				}
        +#if 0
        +			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
        +			sdata = s->session->tlsext_ellipticcurvelist;
        +			for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
        +				fprintf(stderr,"%i ",*(sdata++));
        +			fprintf(stderr,"\n");
        +#endif
        +			}
        +#endif /* OPENSSL_NO_EC */
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +		else if (type == TLSEXT_TYPE_opaque_prf_input &&
        +	             s->version != DTLS1_VERSION)
        +			{
        +			unsigned char *sdata = data;
        +
        +			if (size < 2)
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			n2s(sdata, s->s3->client_opaque_prf_input_len);
        +			if (s->s3->client_opaque_prf_input_len != size - 2)
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +
        +			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
        +				OPENSSL_free(s->s3->client_opaque_prf_input);
        +			if (s->s3->client_opaque_prf_input_len == 0)
        +				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
        +			else
        +				s->s3->client_opaque_prf_input = BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
        +			if (s->s3->client_opaque_prf_input == NULL)
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			}
        +#endif
        +		else if (type == TLSEXT_TYPE_session_ticket)
        +			{
        +			if (s->tls_session_ticket_ext_cb &&
        +			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			}
        +		else if (type == TLSEXT_TYPE_renegotiate)
        +			{
        +			if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
        +				return 0;
        +			renegotiate_seen = 1;
        +			}
        +		else if (type == TLSEXT_TYPE_signature_algorithms)
        +			{
        +			int dsize;
        +			if (sigalg_seen || size < 2) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			sigalg_seen = 1;
        +			n2s(data,dsize);
        +			size -= 2;
        +			if (dsize != size || dsize & 1) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			if (!tls1_process_sigalgs(s, data, dsize))
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			}
        +		else if (type == TLSEXT_TYPE_status_request &&
        +		         s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
        +			{
        +		
        +			if (size < 5) 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +
        +			s->tlsext_status_type = *data++;
        +			size--;
        +			if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
        +				{
        +				const unsigned char *sdata;
        +				int dsize;
        +				/* Read in responder_id_list */
        +				n2s(data,dsize);
        +				size -= 2;
        +				if (dsize > size  ) 
        +					{
        +					*al = SSL_AD_DECODE_ERROR;
        +					return 0;
        +					}
        +				while (dsize > 0)
        +					{
        +					OCSP_RESPID *id;
        +					int idsize;
        +					if (dsize < 4)
        +						{
        +						*al = SSL_AD_DECODE_ERROR;
        +						return 0;
        +						}
        +					n2s(data, idsize);
        +					dsize -= 2 + idsize;
        +					size -= 2 + idsize;
        +					if (dsize < 0)
        +						{
        +						*al = SSL_AD_DECODE_ERROR;
        +						return 0;
        +						}
        +					sdata = data;
        +					data += idsize;
        +					id = d2i_OCSP_RESPID(NULL,
        +								&sdata, idsize);
        +					if (!id)
        +						{
        +						*al = SSL_AD_DECODE_ERROR;
        +						return 0;
        +						}
        +					if (data != sdata)
        +						{
        +						OCSP_RESPID_free(id);
        +						*al = SSL_AD_DECODE_ERROR;
        +						return 0;
        +						}
        +					if (!s->tlsext_ocsp_ids
        +						&& !(s->tlsext_ocsp_ids =
        +						sk_OCSP_RESPID_new_null()))
        +						{
        +						OCSP_RESPID_free(id);
        +						*al = SSL_AD_INTERNAL_ERROR;
        +						return 0;
        +						}
        +					if (!sk_OCSP_RESPID_push(
        +							s->tlsext_ocsp_ids, id))
        +						{
        +						OCSP_RESPID_free(id);
        +						*al = SSL_AD_INTERNAL_ERROR;
        +						return 0;
        +						}
        +					}
        +
        +				/* Read in request_extensions */
        +				if (size < 2)
        +					{
        +					*al = SSL_AD_DECODE_ERROR;
        +					return 0;
        +					}
        +				n2s(data,dsize);
        +				size -= 2;
        +				if (dsize != size)
        +					{
        +					*al = SSL_AD_DECODE_ERROR;
        +					return 0;
        +					}
        +				sdata = data;
        +				if (dsize > 0)
        +					{
        +					if (s->tlsext_ocsp_exts)
        +						{
        +						sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
        +									   X509_EXTENSION_free);
        +						}
        +
        +					s->tlsext_ocsp_exts =
        +						d2i_X509_EXTENSIONS(NULL,
        +							&sdata, dsize);
        +					if (!s->tlsext_ocsp_exts
        +						|| (data + dsize != sdata))
        +						{
        +						*al = SSL_AD_DECODE_ERROR;
        +						return 0;
        +						}
        +					}
        +				}
        +				/* We don't know what to do with any other type
        + 			 	* so ignore it.
        + 			 	*/
        +				else
        +					s->tlsext_status_type = -1;
        +			}
        +#ifndef OPENSSL_NO_HEARTBEATS
        +		else if (type == TLSEXT_TYPE_heartbeat)
        +			{
        +			switch(data[0])
        +				{
        +				case 0x01:	/* Client allows us to send HB requests */
        +							s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
        +							break;
        +				case 0x02:	/* Client doesn't accept HB requests */
        +							s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
        +							s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
        +							break;
        +				default:	*al = SSL_AD_ILLEGAL_PARAMETER;
        +							return 0;
        +				}
        +			}
        +#endif
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +		else if (type == TLSEXT_TYPE_next_proto_neg &&
        +			 s->s3->tmp.finish_md_len == 0)
        +			{
        +			/* We shouldn't accept this extension on a
        +			 * renegotiation.
        +			 *
        +			 * s->new_session will be set on renegotiation, but we
        +			 * probably shouldn't rely that it couldn't be set on
        +			 * the initial renegotation too in certain cases (when
        +			 * there's some other reason to disallow resuming an
        +			 * earlier session -- the current code won't be doing
        +			 * anything like that, but this might change).
        +
        +			 * A valid sign that there's been a previous handshake
        +			 * in this connection is if s->s3->tmp.finish_md_len >
        +			 * 0.  (We are talking about a check that will happen
        +			 * in the Hello protocol round, well before a new
        +			 * Finished message could have been computed.) */
        +			s->s3->next_proto_neg_seen = 1;
        +			}
        +#endif
        +
        +		/* session ticket processed earlier */
        +#ifndef OPENSSL_NO_SRTP
        +		else if (type == TLSEXT_TYPE_use_srtp)
        +			{
        +			if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
        +							      al))
        +				return 0;
        +			}
        +#endif
        +
        +		data+=size;
        +		}
        +				
        +	*p = data;
        +
        +	ri_check:
        +
        +	/* Need RI if renegotiating */
        +
        +	if (!renegotiate_seen && s->renegotiate &&
        +		!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
        +		{
        +		*al = SSL_AD_HANDSHAKE_FAILURE;
        +	 	SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
        +				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
        + * elements of zero length are allowed and the set of elements must exactly fill
        + * the length of the block. */
        +static char ssl_next_proto_validate(unsigned char *d, unsigned len)
        +	{
        +	unsigned int off = 0;
        +
        +	while (off < len)
        +		{
        +		if (d[off] == 0)
        +			return 0;
        +		off += d[off];
        +		off++;
        +		}
        +
        +	return off == len;
        +	}
        +#endif
        +
        +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
        +	{
        +	unsigned short length;
        +	unsigned short type;
        +	unsigned short size;
        +	unsigned char *data = *p;
        +	int tlsext_servername = 0;
        +	int renegotiate_seen = 0;
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +	s->s3->next_proto_neg_seen = 0;
        +#endif
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +	s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
        +	                       SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
        +#endif
        +
        +	if (data >= (d+n-2))
        +		goto ri_check;
        +
        +	n2s(data,length);
        +	if (data+length != d+n)
        +		{
        +		*al = SSL_AD_DECODE_ERROR;
        +		return 0;
        +		}
        +
        +	while(data <= (d+n-4))
        +		{
        +		n2s(data,type);
        +		n2s(data,size);
        +
        +		if (data+size > (d+n))
        +	   		goto ri_check;
        +
        +		if (s->tlsext_debug_cb)
        +			s->tlsext_debug_cb(s, 1, type, data, size,
        +						s->tlsext_debug_arg);
        +
        +		if (type == TLSEXT_TYPE_server_name)
        +			{
        +			if (s->tlsext_hostname == NULL || size > 0)
        +				{
        +				*al = TLS1_AD_UNRECOGNIZED_NAME;
        +				return 0;
        +				}
        +			tlsext_servername = 1;   
        +			}
        +
        +#ifndef OPENSSL_NO_EC
        +		else if (type == TLSEXT_TYPE_ec_point_formats &&
        +	             s->version != DTLS1_VERSION)
        +			{
        +			unsigned char *sdata = data;
        +			int ecpointformatlist_length = *(sdata++);
        +
        +			if (ecpointformatlist_length != size - 1 || 
        +				ecpointformatlist_length < 1)
        +				{
        +				*al = TLS1_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			s->session->tlsext_ecpointformatlist_length = 0;
        +			if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
        +			if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
        +			memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
        +#if 0
        +			fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
        +			sdata = s->session->tlsext_ecpointformatlist;
        +			for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
        +				fprintf(stderr,"%i ",*(sdata++));
        +			fprintf(stderr,"\n");
        +#endif
        +			}
        +#endif /* OPENSSL_NO_EC */
        +
        +		else if (type == TLSEXT_TYPE_session_ticket)
        +			{
        +			if (s->tls_session_ticket_ext_cb &&
        +			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
        +				|| (size > 0))
        +				{
        +				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
        +				return 0;
        +				}
        +			s->tlsext_ticket_expected = 1;
        +			}
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +		else if (type == TLSEXT_TYPE_opaque_prf_input &&
        +	             s->version != DTLS1_VERSION)
        +			{
        +			unsigned char *sdata = data;
        +
        +			if (size < 2)
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			n2s(sdata, s->s3->server_opaque_prf_input_len);
        +			if (s->s3->server_opaque_prf_input_len != size - 2)
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			
        +			if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
        +				OPENSSL_free(s->s3->server_opaque_prf_input);
        +			if (s->s3->server_opaque_prf_input_len == 0)
        +				s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
        +			else
        +				s->s3->server_opaque_prf_input = BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
        +
        +			if (s->s3->server_opaque_prf_input == NULL)
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			}
        +#endif
        +		else if (type == TLSEXT_TYPE_status_request &&
        +		         s->version != DTLS1_VERSION)
        +			{
        +			/* MUST be empty and only sent if we've requested
        +			 * a status request message.
        +			 */ 
        +			if ((s->tlsext_status_type == -1) || (size > 0))
        +				{
        +				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
        +				return 0;
        +				}
        +			/* Set flag to expect CertificateStatus message */
        +			s->tlsext_status_expected = 1;
        +			}
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +		else if (type == TLSEXT_TYPE_next_proto_neg &&
        +			 s->s3->tmp.finish_md_len == 0)
        +			{
        +			unsigned char *selected;
        +			unsigned char selected_len;
        +
        +			/* We must have requested it. */
        +			if (s->ctx->next_proto_select_cb == NULL)
        +				{
        +				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
        +				return 0;
        +				}
        +			/* The data must be valid */
        +			if (!ssl_next_proto_validate(data, size))
        +				{
        +				*al = TLS1_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data, size, s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK)
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			s->next_proto_negotiated = OPENSSL_malloc(selected_len);
        +			if (!s->next_proto_negotiated)
        +				{
        +				*al = TLS1_AD_INTERNAL_ERROR;
        +				return 0;
        +				}
        +			memcpy(s->next_proto_negotiated, selected, selected_len);
        +			s->next_proto_negotiated_len = selected_len;
        +			s->s3->next_proto_neg_seen = 1;
        +			}
        +#endif
        +		else if (type == TLSEXT_TYPE_renegotiate)
        +			{
        +			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
        +				return 0;
        +			renegotiate_seen = 1;
        +			}
        +#ifndef OPENSSL_NO_HEARTBEATS
        +		else if (type == TLSEXT_TYPE_heartbeat)
        +			{
        +			switch(data[0])
        +				{
        +				case 0x01:	/* Server allows us to send HB requests */
        +							s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
        +							break;
        +				case 0x02:	/* Server doesn't accept HB requests */
        +							s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
        +							s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
        +							break;
        +				default:	*al = SSL_AD_ILLEGAL_PARAMETER;
        +							return 0;
        +				}
        +			}
        +#endif
        +#ifndef OPENSSL_NO_SRTP
        +		else if (type == TLSEXT_TYPE_use_srtp)
        +			{
        +                        if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
        +							      al))
        +                                return 0;
        +			}
        +#endif
        +
        +		data+=size;		
        +		}
        +
        +	if (data != d+n)
        +		{
        +		*al = SSL_AD_DECODE_ERROR;
        +		return 0;
        +		}
        +
        +	if (!s->hit && tlsext_servername == 1)
        +		{
        + 		if (s->tlsext_hostname)
        +			{
        +			if (s->session->tlsext_hostname == NULL)
        +				{
        +				s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);	
        +				if (!s->session->tlsext_hostname)
        +					{
        +					*al = SSL_AD_UNRECOGNIZED_NAME;
        +					return 0;
        +					}
        +				}
        +			else 
        +				{
        +				*al = SSL_AD_DECODE_ERROR;
        +				return 0;
        +				}
        +			}
        +		}
        +
        +	*p = data;
        +
        +	ri_check:
        +
        +	/* Determine if we need to see RI. Strictly speaking if we want to
        +	 * avoid an attack we should *always* see RI even on initial server
        +	 * hello because the client doesn't see any renegotiation during an
        +	 * attack. However this would mean we could not connect to any server
        +	 * which doesn't support RI so for the immediate future tolerate RI
        +	 * absence on initial connect only.
        +	 */
        +	if (!renegotiate_seen
        +		&& !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
        +		&& !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
        +		{
        +		*al = SSL_AD_HANDSHAKE_FAILURE;
        +		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
        +				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
        +		return 0;
        +		}
        +
        +	return 1;
        +	}
        +
        +
        +int ssl_prepare_clienthello_tlsext(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_EC
        +	/* If we are client and using an elliptic curve cryptography cipher suite, send the point formats 
        +	 * and elliptic curves we support.
        +	 */
        +	int using_ecc = 0;
        +	int i;
        +	unsigned char *j;
        +	unsigned long alg_k, alg_a;
        +	STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
        +
        +	for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
        +		{
        +		SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
        +
        +		alg_k = c->algorithm_mkey;
        +		alg_a = c->algorithm_auth;
        +		if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA)))
        +			{
        +			using_ecc = 1;
        +			break;
        +			}
        +		}
        +	using_ecc = using_ecc && (s->version >= TLS1_VERSION);
        +	if (using_ecc)
        +		{
        +		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
        +		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		s->tlsext_ecpointformatlist_length = 3;
        +		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
        +		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
        +		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
        +
        +		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
        +		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
        +		s->tlsext_ellipticcurvelist_length = sizeof(pref_list)/sizeof(pref_list[0]) * 2;
        +		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
        +			{
        +			s->tlsext_ellipticcurvelist_length = 0;
        +			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i <
        +				sizeof(pref_list)/sizeof(pref_list[0]); i++)
        +			{
        +			int id = tls1_ec_nid2curve_id(pref_list[i]);
        +			s2n(id,j);
        +			}
        +		}
        +#endif /* OPENSSL_NO_EC */
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        + 	{
        +		int r = 1;
        +	
        +		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
        +			{
        +			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
        +			if (!r)
        +				return -1;
        +			}
        +
        +		if (s->tlsext_opaque_prf_input != NULL)
        +			{
        +			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
        +				OPENSSL_free(s->s3->client_opaque_prf_input);
        +
        +			if (s->tlsext_opaque_prf_input_len == 0)
        +				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
        +			else
        +				s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
        +			if (s->s3->client_opaque_prf_input == NULL)
        +				{
        +				SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
        +				return -1;
        +				}
        +			s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
        +			}
        +
        +		if (r == 2)
        +			/* at callback's request, insist on receiving an appropriate server opaque PRF input */
        +			s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
        +	}
        +#endif
        +
        +	return 1;
        +	}
        +
        +int ssl_prepare_serverhello_tlsext(SSL *s)
        +	{
        +#ifndef OPENSSL_NO_EC
        +	/* If we are server and using an ECC cipher suite, send the point formats we support 
        +	 * if the client sent us an ECPointsFormat extension.  Note that the server is not
        +	 * supposed to send an EllipticCurves extension.
        +	 */
        +
        +	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
        +	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
        +	int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
        +	using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
        +	
        +	if (using_ecc)
        +		{
        +		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
        +		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
        +			{
        +			SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
        +			return -1;
        +			}
        +		s->tlsext_ecpointformatlist_length = 3;
        +		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
        +		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
        +		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
        +		}
        +#endif /* OPENSSL_NO_EC */
        +
        +	return 1;
        +	}
        +
        +int ssl_check_clienthello_tlsext_early(SSL *s)
        +	{
        +	int ret=SSL_TLSEXT_ERR_NOACK;
        +	int al = SSL_AD_UNRECOGNIZED_NAME;
        +
        +#ifndef OPENSSL_NO_EC
        +	/* The handling of the ECPointFormats extension is done elsewhere, namely in 
        +	 * ssl3_choose_cipher in s3_lib.c.
        +	 */
        +	/* The handling of the EllipticCurves extension is done elsewhere, namely in 
        +	 * ssl3_choose_cipher in s3_lib.c.
        +	 */
        +#endif
        +
        +	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
        +		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
        +	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
        +		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        + 	{
        +		/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
        +		 * but we might be sending an alert in response to the client hello,
        +		 * so this has to happen here in
        +		 * ssl_check_clienthello_tlsext_early(). */
        +
        +		int r = 1;
        +	
        +		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
        +			{
        +			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
        +			if (!r)
        +				{
        +				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +				al = SSL_AD_INTERNAL_ERROR;
        +				goto err;
        +				}
        +			}
        +
        +		if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
        +			OPENSSL_free(s->s3->server_opaque_prf_input);
        +		s->s3->server_opaque_prf_input = NULL;
        +
        +		if (s->tlsext_opaque_prf_input != NULL)
        +			{
        +			if (s->s3->client_opaque_prf_input != NULL &&
        +				s->s3->client_opaque_prf_input_len == s->tlsext_opaque_prf_input_len)
        +				{
        +				/* can only use this extension if we have a server opaque PRF input
        +				 * of the same length as the client opaque PRF input! */
        +
        +				if (s->tlsext_opaque_prf_input_len == 0)
        +					s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
        +				else
        +					s->s3->server_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
        +				if (s->s3->server_opaque_prf_input == NULL)
        +					{
        +					ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +					al = SSL_AD_INTERNAL_ERROR;
        +					goto err;
        +					}
        +				s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
        +				}
        +			}
        +
        +		if (r == 2 && s->s3->server_opaque_prf_input == NULL)
        +			{
        +			/* The callback wants to enforce use of the extension,
        +			 * but we can't do that with the client opaque PRF input;
        +			 * abort the handshake.
        +			 */
        +			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +			al = SSL_AD_HANDSHAKE_FAILURE;
        +			}
        +	}
        +
        + err:
        +#endif
        +	switch (ret)
        +		{
        +		case SSL_TLSEXT_ERR_ALERT_FATAL:
        +			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
        +			return -1;
        +
        +		case SSL_TLSEXT_ERR_ALERT_WARNING:
        +			ssl3_send_alert(s,SSL3_AL_WARNING,al);
        +			return 1; 
        +					
        +		case SSL_TLSEXT_ERR_NOACK:
        +			s->servername_done=0;
        +			default:
        +		return 1;
        +		}
        +	}
        +
        +int ssl_check_clienthello_tlsext_late(SSL *s)
        +	{
        +	int ret = SSL_TLSEXT_ERR_OK;
        +	int al;
        +
        +	/* If status request then ask callback what to do.
        + 	 * Note: this must be called after servername callbacks in case 
        + 	 * the certificate has changed, and must be called after the cipher
        +	 * has been chosen because this may influence which certificate is sent
        + 	 */
        +	if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
        +		{
        +		int r;
        +		CERT_PKEY *certpkey;
        +		certpkey = ssl_get_server_send_pkey(s);
        +		/* If no certificate can't return certificate status */
        +		if (certpkey == NULL)
        +			{
        +			s->tlsext_status_expected = 0;
        +			return 1;
        +			}
        +		/* Set current certificate to one we will use so
        +		 * SSL_get_certificate et al can pick it up.
        +		 */
        +		s->cert->key = certpkey;
        +		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
        +		switch (r)
        +			{
        +			/* We don't want to send a status request response */
        +			case SSL_TLSEXT_ERR_NOACK:
        +				s->tlsext_status_expected = 0;
        +				break;
        +			/* status request response should be sent */
        +			case SSL_TLSEXT_ERR_OK:
        +				if (s->tlsext_ocsp_resp)
        +					s->tlsext_status_expected = 1;
        +				else
        +					s->tlsext_status_expected = 0;
        +				break;
        +			/* something bad happened */
        +			case SSL_TLSEXT_ERR_ALERT_FATAL:
        +				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +				al = SSL_AD_INTERNAL_ERROR;
        +				goto err;
        +			}
        +		}
        +	else
        +		s->tlsext_status_expected = 0;
        +
        + err:
        +	switch (ret)
        +		{
        +		case SSL_TLSEXT_ERR_ALERT_FATAL:
        +			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
        +			return -1;
        +
        +		case SSL_TLSEXT_ERR_ALERT_WARNING:
        +			ssl3_send_alert(s,SSL3_AL_WARNING,al);
        +			return 1; 
        +
        +		default:
        +			return 1;
        +		}
        +	}
        +
        +int ssl_check_serverhello_tlsext(SSL *s)
        +	{
        +	int ret=SSL_TLSEXT_ERR_NOACK;
        +	int al = SSL_AD_UNRECOGNIZED_NAME;
        +
        +#ifndef OPENSSL_NO_EC
        +	/* If we are client and using an elliptic curve cryptography cipher
        +	 * suite, then if server returns an EC point formats lists extension
        +	 * it must contain uncompressed.
        +	 */
        +	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
        +	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
        +	if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) && 
        +	    (s->session->tlsext_ecpointformatlist != NULL) && (s->session->tlsext_ecpointformatlist_length > 0) && 
        +	    ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA)))
        +		{
        +		/* we are using an ECC cipher */
        +		size_t i;
        +		unsigned char *list;
        +		int found_uncompressed = 0;
        +		list = s->session->tlsext_ecpointformatlist;
        +		for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
        +			{
        +			if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed)
        +				{
        +				found_uncompressed = 1;
        +				break;
        +				}
        +			}
        +		if (!found_uncompressed)
        +			{
        +			SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
        +			return -1;
        +			}
        +		}
        +	ret = SSL_TLSEXT_ERR_OK;
        +#endif /* OPENSSL_NO_EC */
        +
        +	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
        +		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
        +	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
        +		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	if (s->s3->server_opaque_prf_input_len > 0)
        +		{
        +		/* This case may indicate that we, as a client, want to insist on using opaque PRF inputs.
        +		 * So first verify that we really have a value from the server too. */
        +
        +		if (s->s3->server_opaque_prf_input == NULL)
        +			{
        +			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +			al = SSL_AD_HANDSHAKE_FAILURE;
        +			}
        +		
        +		/* Anytime the server *has* sent an opaque PRF input, we need to check
        +		 * that we have a client opaque PRF input of the same size. */
        +		if (s->s3->client_opaque_prf_input == NULL ||
        +		    s->s3->client_opaque_prf_input_len != s->s3->server_opaque_prf_input_len)
        +			{
        +			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +			al = SSL_AD_ILLEGAL_PARAMETER;
        +			}
        +		}
        +#endif
        +
        +	/* If we've requested certificate status and we wont get one
        + 	 * tell the callback
        + 	 */
        +	if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
        +			&& s->ctx && s->ctx->tlsext_status_cb)
        +		{
        +		int r;
        +		/* Set resp to NULL, resplen to -1 so callback knows
        + 		 * there is no response.
        + 		 */
        +		if (s->tlsext_ocsp_resp)
        +			{
        +			OPENSSL_free(s->tlsext_ocsp_resp);
        +			s->tlsext_ocsp_resp = NULL;
        +			}
        +		s->tlsext_ocsp_resplen = -1;
        +		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
        +		if (r == 0)
        +			{
        +			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
        +			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +			}
        +		if (r < 0)
        +			{
        +			al = SSL_AD_INTERNAL_ERROR;
        +			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
        +			}
        +		}
        +
        +	switch (ret)
        +		{
        +		case SSL_TLSEXT_ERR_ALERT_FATAL:
        +			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
        +			return -1;
        +
        +		case SSL_TLSEXT_ERR_ALERT_WARNING:
        +			ssl3_send_alert(s,SSL3_AL_WARNING,al);
        +			return 1; 
        +					
        +		case SSL_TLSEXT_ERR_NOACK:
        +			s->servername_done=0;
        +			default:
        +		return 1;
        +		}
        +	}
        +
        +/* Since the server cache lookup is done early on in the processing of the
        + * ClientHello, and other operations depend on the result, we need to handle
        + * any TLS session ticket extension at the same time.
        + *
        + *   session_id: points at the session ID in the ClientHello. This code will
        + *       read past the end of this in order to parse out the session ticket
        + *       extension, if any.
        + *   len: the length of the session ID.
        + *   limit: a pointer to the first byte after the ClientHello.
        + *   ret: (output) on return, if a ticket was decrypted, then this is set to
        + *       point to the resulting session.
        + *
        + * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
        + * ciphersuite, in which case we have no use for session tickets and one will
        + * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
        + *
        + * Returns:
        + *   -1: fatal error, either from parsing or decrypting the ticket.
        + *    0: no ticket was found (or was ignored, based on settings).
        + *    1: a zero length extension was found, indicating that the client supports
        + *       session tickets but doesn't currently have one to offer.
        + *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
        + *       couldn't be decrypted because of a non-fatal error.
        + *    3: a ticket was successfully decrypted and *ret was set.
        + *
        + * Side effects:
        + *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
        + *   a new session ticket to the client because the client indicated support
        + *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
        + *   a session ticket or we couldn't use the one it gave us, or if
        + *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
        + *   Otherwise, s->tlsext_ticket_expected is set to 0.
        + */
        +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
        +			const unsigned char *limit, SSL_SESSION **ret)
        +	{
        +	/* Point after session ID in client hello */
        +	const unsigned char *p = session_id + len;
        +	unsigned short i;
        +
        +	*ret = NULL;
        +	s->tlsext_ticket_expected = 0;
        +
        +	/* If tickets disabled behave as if no ticket present
        +	 * to permit stateful resumption.
        +	 */
        +	if (SSL_get_options(s) & SSL_OP_NO_TICKET)
        +		return 0;
        +	if ((s->version <= SSL3_VERSION) || !limit)
        +		return 0;
        +	if (p >= limit)
        +		return -1;
        +	/* Skip past DTLS cookie */
        +	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
        +		{
        +		i = *(p++);
        +		p+= i;
        +		if (p >= limit)
        +			return -1;
        +		}
        +	/* Skip past cipher list */
        +	n2s(p, i);
        +	p+= i;
        +	if (p >= limit)
        +		return -1;
        +	/* Skip past compression algorithm list */
        +	i = *(p++);
        +	p += i;
        +	if (p > limit)
        +		return -1;
        +	/* Now at start of extensions */
        +	if ((p + 2) >= limit)
        +		return 0;
        +	n2s(p, i);
        +	while ((p + 4) <= limit)
        +		{
        +		unsigned short type, size;
        +		n2s(p, type);
        +		n2s(p, size);
        +		if (p + size > limit)
        +			return 0;
        +		if (type == TLSEXT_TYPE_session_ticket)
        +			{
        +			int r;
        +			if (size == 0)
        +				{
        +				/* The client will accept a ticket but doesn't
        +				 * currently have one. */
        +				s->tlsext_ticket_expected = 1;
        +				return 1;
        +				}
        +			if (s->tls_session_secret_cb)
        +				{
        +				/* Indicate that the ticket couldn't be
        +				 * decrypted rather than generating the session
        +				 * from ticket now, trigger abbreviated
        +				 * handshake based on external mechanism to
        +				 * calculate the master secret later. */
        +				return 2;
        +				}
        +			r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
        +			switch (r)
        +				{
        +				case 2: /* ticket couldn't be decrypted */
        +					s->tlsext_ticket_expected = 1;
        +					return 2;
        +				case 3: /* ticket was decrypted */
        +					return r;
        +				case 4: /* ticket decrypted but need to renew */
        +					s->tlsext_ticket_expected = 1;
        +					return 3;
        +				default: /* fatal error */
        +					return -1;
        +				}
        +			}
        +		p += size;
        +		}
        +	return 0;
        +	}
        +
        +/* tls_decrypt_ticket attempts to decrypt a session ticket.
        + *
        + *   etick: points to the body of the session ticket extension.
        + *   eticklen: the length of the session tickets extenion.
        + *   sess_id: points at the session ID.
        + *   sesslen: the length of the session ID.
        + *   psess: (output) on return, if a ticket was decrypted, then this is set to
        + *       point to the resulting session.
        + *
        + * Returns:
        + *   -1: fatal error, either from parsing or decrypting the ticket.
        + *    2: the ticket couldn't be decrypted.
        + *    3: a ticket was successfully decrypted and *psess was set.
        + *    4: same as 3, but the ticket needs to be renewed.
        + */
        +static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
        +				const unsigned char *sess_id, int sesslen,
        +				SSL_SESSION **psess)
        +	{
        +	SSL_SESSION *sess;
        +	unsigned char *sdec;
        +	const unsigned char *p;
        +	int slen, mlen, renew_ticket = 0;
        +	unsigned char tick_hmac[EVP_MAX_MD_SIZE];
        +	HMAC_CTX hctx;
        +	EVP_CIPHER_CTX ctx;
        +	SSL_CTX *tctx = s->initial_ctx;
        +	/* Need at least keyname + iv + some encrypted data */
        +	if (eticklen < 48)
        +		return 2;
        +	/* Initialize session ticket encryption and HMAC contexts */
        +	HMAC_CTX_init(&hctx);
        +	EVP_CIPHER_CTX_init(&ctx);
        +	if (tctx->tlsext_ticket_key_cb)
        +		{
        +		unsigned char *nctick = (unsigned char *)etick;
        +		int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
        +							&ctx, &hctx, 0);
        +		if (rv < 0)
        +			return -1;
        +		if (rv == 0)
        +			return 2;
        +		if (rv == 2)
        +			renew_ticket = 1;
        +		}
        +	else
        +		{
        +		/* Check key name matches */
        +		if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
        +			return 2;
        +		HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
        +					tlsext_tick_md(), NULL);
        +		EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
        +				tctx->tlsext_tick_aes_key, etick + 16);
        +		}
        +	/* Attempt to process session ticket, first conduct sanity and
        +	 * integrity checks on ticket.
        +	 */
        +	mlen = HMAC_size(&hctx);
        +	if (mlen < 0)
        +		{
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +		return -1;
        +		}
        +	eticklen -= mlen;
        +	/* Check HMAC of encrypted ticket */
        +	HMAC_Update(&hctx, etick, eticklen);
        +	HMAC_Final(&hctx, tick_hmac, NULL);
        +	HMAC_CTX_cleanup(&hctx);
        +	if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
        +		return 2;
        +	/* Attempt to decrypt session data */
        +	/* Move p after IV to start of encrypted ticket, update length */
        +	p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
        +	eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
        +	sdec = OPENSSL_malloc(eticklen);
        +	if (!sdec)
        +		{
        +		EVP_CIPHER_CTX_cleanup(&ctx);
        +		return -1;
        +		}
        +	EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
        +	if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
        +		return 2;
        +	slen += mlen;
        +	EVP_CIPHER_CTX_cleanup(&ctx);
        +	p = sdec;
        +
        +	sess = d2i_SSL_SESSION(NULL, &p, slen);
        +	OPENSSL_free(sdec);
        +	if (sess)
        +		{
        +		/* The session ID, if non-empty, is used by some clients to
        +		 * detect that the ticket has been accepted. So we copy it to
        +		 * the session structure. If it is empty set length to zero
        +		 * as required by standard.
        +		 */
        +		if (sesslen)
        +			memcpy(sess->session_id, sess_id, sesslen);
        +		sess->session_id_length = sesslen;
        +		*psess = sess;
        +		if (renew_ticket)
        +			return 4;
        +		else
        +			return 3;
        +		}
        +        ERR_clear_error();
        +	/* For session parse failure, indicate that we need to send a new
        +	 * ticket. */
        +	return 2;
        +	}
        +
        +/* Tables to translate from NIDs to TLS v1.2 ids */
        +
        +typedef struct 
        +	{
        +	int nid;
        +	int id;
        +	} tls12_lookup;
        +
        +static tls12_lookup tls12_md[] = {
        +#ifndef OPENSSL_NO_MD5
        +	{NID_md5, TLSEXT_hash_md5},
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +	{NID_sha1, TLSEXT_hash_sha1},
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +	{NID_sha224, TLSEXT_hash_sha224},
        +	{NID_sha256, TLSEXT_hash_sha256},
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +	{NID_sha384, TLSEXT_hash_sha384},
        +	{NID_sha512, TLSEXT_hash_sha512}
        +#endif
        +};
        +
        +static tls12_lookup tls12_sig[] = {
        +#ifndef OPENSSL_NO_RSA
        +	{EVP_PKEY_RSA, TLSEXT_signature_rsa},
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +	{EVP_PKEY_DSA, TLSEXT_signature_dsa},
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	{EVP_PKEY_EC, TLSEXT_signature_ecdsa}
        +#endif
        +};
        +
        +static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
        +	{
        +	size_t i;
        +	for (i = 0; i < tlen; i++)
        +		{
        +		if (table[i].nid == nid)
        +			return table[i].id;
        +		}
        +	return -1;
        +	}
        +#if 0
        +static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
        +	{
        +	size_t i;
        +	for (i = 0; i < tlen; i++)
        +		{
        +		if (table[i].id == id)
        +			return table[i].nid;
        +		}
        +	return -1;
        +	}
        +#endif
        +
        +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md)
        +	{
        +	int sig_id, md_id;
        +	if (!md)
        +		return 0;
        +	md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
        +				sizeof(tls12_md)/sizeof(tls12_lookup));
        +	if (md_id == -1)
        +		return 0;
        +	sig_id = tls12_get_sigid(pk);
        +	if (sig_id == -1)
        +		return 0;
        +	p[0] = (unsigned char)md_id;
        +	p[1] = (unsigned char)sig_id;
        +	return 1;
        +	}
        +
        +int tls12_get_sigid(const EVP_PKEY *pk)
        +	{
        +	return tls12_find_id(pk->type, tls12_sig,
        +				sizeof(tls12_sig)/sizeof(tls12_lookup));
        +	}
        +
        +const EVP_MD *tls12_get_hash(unsigned char hash_alg)
        +	{
        +	switch(hash_alg)
        +		{
        +#ifndef OPENSSL_NO_MD5
        +		case TLSEXT_hash_md5:
        +#ifdef OPENSSL_FIPS
        +		if (FIPS_mode())
        +			return NULL;
        +#endif
        +		return EVP_md5();
        +#endif
        +#ifndef OPENSSL_NO_SHA
        +		case TLSEXT_hash_sha1:
        +		return EVP_sha1();
        +#endif
        +#ifndef OPENSSL_NO_SHA256
        +		case TLSEXT_hash_sha224:
        +		return EVP_sha224();
        +
        +		case TLSEXT_hash_sha256:
        +		return EVP_sha256();
        +#endif
        +#ifndef OPENSSL_NO_SHA512
        +		case TLSEXT_hash_sha384:
        +		return EVP_sha384();
        +
        +		case TLSEXT_hash_sha512:
        +		return EVP_sha512();
        +#endif
        +		default:
        +		return NULL;
        +
        +		}
        +	}
        +
        +/* Set preferred digest for each key type */
        +
        +int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
        +	{
        +	int i, idx;
        +	const EVP_MD *md;
        +	CERT *c = s->cert;
        +	/* Extension ignored for TLS versions below 1.2 */
        +	if (TLS1_get_version(s) < TLS1_2_VERSION)
        +		return 1;
        +	/* Should never happen */
        +	if (!c)
        +		return 0;
        +
        +	c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
        +	c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL;
        +	c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL;
        +	c->pkeys[SSL_PKEY_ECC].digest = NULL;
        +
        +	for (i = 0; i < dsize; i += 2)
        +		{
        +		unsigned char hash_alg = data[i], sig_alg = data[i+1];
        +
        +		switch(sig_alg)
        +			{
        +#ifndef OPENSSL_NO_RSA
        +			case TLSEXT_signature_rsa:
        +			idx = SSL_PKEY_RSA_SIGN;
        +			break;
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			case TLSEXT_signature_dsa:
        +			idx = SSL_PKEY_DSA_SIGN;
        +			break;
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +			case TLSEXT_signature_ecdsa:
        +			idx = SSL_PKEY_ECC;
        +			break;
        +#endif
        +			default:
        +			continue;
        +			}
        +
        +		if (c->pkeys[idx].digest == NULL)
        +			{
        +			md = tls12_get_hash(hash_alg);
        +			if (md)
        +				{
        +				c->pkeys[idx].digest = md;
        +				if (idx == SSL_PKEY_RSA_SIGN)
        +					c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
        +				}
        +			}
        +
        +		}
        +
        +
        +	/* Set any remaining keys to default values. NOTE: if alg is not
        +	 * supported it stays as NULL.
        +	 */
        +#ifndef OPENSSL_NO_DSA
        +	if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
        +		c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
        +#endif
        +#ifndef OPENSSL_NO_RSA
        +	if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest)
        +		{
        +		c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
        +		c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
        +		}
        +#endif
        +#ifndef OPENSSL_NO_ECDSA
        +	if (!c->pkeys[SSL_PKEY_ECC].digest)
        +		c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
        +#endif
        +	return 1;
        +	}
        +
        +#endif
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +int
        +tls1_process_heartbeat(SSL *s)
        +	{
        +	unsigned char *p = &s->s3->rrec.data[0], *pl;
        +	unsigned short hbtype;
        +	unsigned int payload;
        +	unsigned int padding = 16; /* Use minimum padding */
        +
        +	/* Read type and payload length first */
        +	hbtype = *p++;
        +	n2s(p, payload);
        +	pl = p;
        +
        +	if (s->msg_callback)
        +		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
        +			&s->s3->rrec.data[0], s->s3->rrec.length,
        +			s, s->msg_callback_arg);
        +
        +	if (hbtype == TLS1_HB_REQUEST)
        +		{
        +		unsigned char *buffer, *bp;
        +		int r;
        +
        +		/* Allocate memory for the response, size is 1 bytes
        +		 * message type, plus 2 bytes payload length, plus
        +		 * payload, plus padding
        +		 */
        +		buffer = OPENSSL_malloc(1 + 2 + payload + padding);
        +		bp = buffer;
        +		
        +		/* Enter response type, length and copy payload */
        +		*bp++ = TLS1_HB_RESPONSE;
        +		s2n(payload, bp);
        +		memcpy(bp, pl, payload);
        +		bp += payload;
        +		/* Random padding */
        +		RAND_pseudo_bytes(bp, padding);
        +
        +		r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
        +
        +		if (r >= 0 && s->msg_callback)
        +			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
        +				buffer, 3 + payload + padding,
        +				s, s->msg_callback_arg);
        +
        +		OPENSSL_free(buffer);
        +
        +		if (r < 0)
        +			return r;
        +		}
        +	else if (hbtype == TLS1_HB_RESPONSE)
        +		{
        +		unsigned int seq;
        +		
        +		/* We only send sequence numbers (2 bytes unsigned int),
        +		 * and 16 random bytes, so we just try to read the
        +		 * sequence number */
        +		n2s(pl, seq);
        +		
        +		if (payload == 18 && seq == s->tlsext_hb_seq)
        +			{
        +			s->tlsext_hb_seq++;
        +			s->tlsext_hb_pending = 0;
        +			}
        +		}
        +
        +	return 0;
        +	}
        +
        +int
        +tls1_heartbeat(SSL *s)
        +	{
        +	unsigned char *buf, *p;
        +	int ret;
        +	unsigned int payload = 18; /* Sequence number + random bytes */
        +	unsigned int padding = 16; /* Use minimum padding */
        +
        +	/* Only send if peer supports and accepts HB requests... */
        +	if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
        +	    s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
        +		{
        +		SSLerr(SSL_F_TLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
        +		return -1;
        +		}
        +
        +	/* ...and there is none in flight yet... */
        +	if (s->tlsext_hb_pending)
        +		{
        +		SSLerr(SSL_F_TLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
        +		return -1;
        +		}
        +		
        +	/* ...and no handshake in progress. */
        +	if (SSL_in_init(s) || s->in_handshake)
        +		{
        +		SSLerr(SSL_F_TLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
        +		return -1;
        +		}
        +		
        +	/* Check if padding is too long, payload and padding
        +	 * must not exceed 2^14 - 3 = 16381 bytes in total.
        +	 */
        +	OPENSSL_assert(payload + padding <= 16381);
        +
        +	/* Create HeartBeat message, we just use a sequence number
        +	 * as payload to distuingish different messages and add
        +	 * some random stuff.
        +	 *  - Message Type, 1 byte
        +	 *  - Payload Length, 2 bytes (unsigned int)
        +	 *  - Payload, the sequence number (2 bytes uint)
        +	 *  - Payload, random bytes (16 bytes uint)
        +	 *  - Padding
        +	 */
        +	buf = OPENSSL_malloc(1 + 2 + payload + padding);
        +	p = buf;
        +	/* Message Type */
        +	*p++ = TLS1_HB_REQUEST;
        +	/* Payload length (18 bytes here) */
        +	s2n(payload, p);
        +	/* Sequence number */
        +	s2n(s->tlsext_hb_seq, p);
        +	/* 16 random bytes */
        +	RAND_pseudo_bytes(p, 16);
        +	p += 16;
        +	/* Random padding */
        +	RAND_pseudo_bytes(p, padding);
        +
        +	ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
        +	if (ret >= 0)
        +		{
        +		if (s->msg_callback)
        +			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
        +				buf, 3 + payload + padding,
        +				s, s->msg_callback_arg);
        +
        +		s->tlsext_hb_pending = 1;
        +		}
        +		
        +	OPENSSL_free(buf);
        +
        +	return ret;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/t1_meth.c b/vendor/openssl/openssl/ssl/t1_meth.c
        new file mode 100644
        index 000000000..53c807de2
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/t1_meth.c
        @@ -0,0 +1,88 @@
        +/* ssl/t1_meth.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +static const SSL_METHOD *tls1_get_method(int ver)
        +	{
        +	if (ver == TLS1_2_VERSION)
        +		return TLSv1_2_method();
        +	if (ver == TLS1_1_VERSION)
        +		return TLSv1_1_method();
        +	if (ver == TLS1_VERSION)
        +		return TLSv1_method();
        +	return NULL;
        +	}
        +
        +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method,
        +			ssl3_accept,
        +			ssl3_connect,
        +			tls1_get_method)
        +
        +IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
        +			ssl3_accept,
        +			ssl3_connect,
        +			tls1_get_method)
        +
        +IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method,
        +			ssl3_accept,
        +			ssl3_connect,
        +			tls1_get_method)
        +
        diff --git a/vendor/openssl/openssl/ssl/t1_reneg.c b/vendor/openssl/openssl/ssl/t1_reneg.c
        new file mode 100644
        index 000000000..9c2cc3c71
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/t1_reneg.c
        @@ -0,0 +1,292 @@
        +/* ssl/t1_reneg.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-2009 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 <stdio.h>
        +#include <openssl/objects.h>
        +#include "ssl_locl.h"
        +
        +/* Add the client's renegotiation binding */
        +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
        +					int maxlen)
        +    {
        +    if(p)
        +        {
        +	if((s->s3->previous_client_finished_len+1) > maxlen)
        +            {
        +            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
        +            return 0;
        +            }
        +            
        +        /* Length byte */
        +	*p = s->s3->previous_client_finished_len;
        +        p++;
        +
        +        memcpy(p, s->s3->previous_client_finished,
        +	       s->s3->previous_client_finished_len);
        +#ifdef OPENSSL_RI_DEBUG
        +    fprintf(stderr, "%s RI extension sent by client\n",
        +		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
        +#endif
        +        }
        +    
        +    *len=s->s3->previous_client_finished_len + 1;
        +
        + 
        +    return 1;
        +    }
        +
        +/* Parse the client's renegotiation binding and abort if it's not
        +   right */
        +int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
        +					  int *al)
        +    {
        +    int ilen;
        +
        +    /* Parse the length byte */
        +    if(len < 1)
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
        +        *al=SSL_AD_ILLEGAL_PARAMETER;
        +        return 0;
        +        }
        +    ilen = *d;
        +    d++;
        +
        +    /* Consistency check */
        +    if((ilen+1) != len)
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
        +        *al=SSL_AD_ILLEGAL_PARAMETER;
        +        return 0;
        +        }
        +
        +    /* Check that the extension matches */
        +    if(ilen != s->s3->previous_client_finished_len)
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
        +        *al=SSL_AD_HANDSHAKE_FAILURE;
        +        return 0;
        +        }
        +    
        +    if(memcmp(d, s->s3->previous_client_finished,
        +	      s->s3->previous_client_finished_len))
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
        +        *al=SSL_AD_HANDSHAKE_FAILURE;
        +        return 0;
        +        }
        +#ifdef OPENSSL_RI_DEBUG
        +    fprintf(stderr, "%s RI extension received by server\n",
        +				ilen ? "Non-empty" : "Empty");
        +#endif
        +
        +    s->s3->send_connection_binding=1;
        +
        +    return 1;
        +    }
        +
        +/* Add the server's renegotiation binding */
        +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
        +					int maxlen)
        +    {
        +    if(p)
        +        {
        +        if((s->s3->previous_client_finished_len +
        +            s->s3->previous_server_finished_len + 1) > maxlen)
        +            {
        +            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
        +            return 0;
        +            }
        +        
        +        /* Length byte */
        +        *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
        +        p++;
        +
        +        memcpy(p, s->s3->previous_client_finished,
        +	       s->s3->previous_client_finished_len);
        +        p += s->s3->previous_client_finished_len;
        +
        +        memcpy(p, s->s3->previous_server_finished,
        +	       s->s3->previous_server_finished_len);
        +#ifdef OPENSSL_RI_DEBUG
        +    fprintf(stderr, "%s RI extension sent by server\n",
        +    		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
        +#endif
        +        }
        +    
        +    *len=s->s3->previous_client_finished_len
        +	+ s->s3->previous_server_finished_len + 1;
        +    
        +    return 1;
        +    }
        +
        +/* Parse the server's renegotiation binding and abort if it's not
        +   right */
        +int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
        +					  int *al)
        +    {
        +    int expected_len=s->s3->previous_client_finished_len
        +	+ s->s3->previous_server_finished_len;
        +    int ilen;
        +
        +    /* Check for logic errors */
        +    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
        +    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
        +    
        +    /* Parse the length byte */
        +    if(len < 1)
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
        +        *al=SSL_AD_ILLEGAL_PARAMETER;
        +        return 0;
        +        }
        +    ilen = *d;
        +    d++;
        +
        +    /* Consistency check */
        +    if(ilen+1 != len)
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
        +        *al=SSL_AD_ILLEGAL_PARAMETER;
        +        return 0;
        +        }
        +    
        +    /* Check that the extension matches */
        +    if(ilen != expected_len)
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
        +        *al=SSL_AD_HANDSHAKE_FAILURE;
        +        return 0;
        +        }
        +
        +    if(memcmp(d, s->s3->previous_client_finished,
        +	      s->s3->previous_client_finished_len))
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
        +        *al=SSL_AD_HANDSHAKE_FAILURE;
        +        return 0;
        +        }
        +    d += s->s3->previous_client_finished_len;
        +
        +    if(memcmp(d, s->s3->previous_server_finished,
        +	      s->s3->previous_server_finished_len))
        +        {
        +        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
        +        *al=SSL_AD_ILLEGAL_PARAMETER;
        +        return 0;
        +        }
        +#ifdef OPENSSL_RI_DEBUG
        +    fprintf(stderr, "%s RI extension received by client\n",
        +				ilen ? "Non-empty" : "Empty");
        +#endif
        +    s->s3->send_connection_binding=1;
        +
        +    return 1;
        +    }
        diff --git a/vendor/openssl/openssl/ssl/t1_srvr.c b/vendor/openssl/openssl/ssl/t1_srvr.c
        new file mode 100644
        index 000000000..f1d156576
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/t1_srvr.c
        @@ -0,0 +1,93 @@
        +/* ssl/t1_srvr.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include "ssl_locl.h"
        +#include <openssl/buffer.h>
        +#include <openssl/rand.h>
        +#include <openssl/objects.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +
        +static const SSL_METHOD *tls1_get_server_method(int ver);
        +static const SSL_METHOD *tls1_get_server_method(int ver)
        +	{
        +	if (ver == TLS1_2_VERSION)
        +		return TLSv1_2_server_method();
        +	if (ver == TLS1_1_VERSION)
        +		return TLSv1_1_server_method();
        +	if (ver == TLS1_VERSION)
        +		return TLSv1_server_method();
        +	return NULL;
        +	}
        +
        +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method,
        +			ssl3_accept,
        +			ssl_undefined_function,
        +			tls1_get_server_method)
        +
        +IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
        +			ssl3_accept,
        +			ssl_undefined_function,
        +			tls1_get_server_method)
        +
        +IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method,
        +			ssl3_accept,
        +			ssl_undefined_function,
        +			tls1_get_server_method)
        +
        diff --git a/vendor/openssl/openssl/ssl/tls1.h b/vendor/openssl/openssl/ssl/tls1.h
        new file mode 100644
        index 000000000..c39c267f0
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/tls1.h
        @@ -0,0 +1,735 @@
        +/* ssl/tls1.h */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * ECC cipher suite support in OpenSSL originally written by
        + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#ifndef HEADER_TLS1_H 
        +#define HEADER_TLS1_H 
        +
        +#include <openssl/buffer.h>
        +
        +#ifdef  __cplusplus
        +extern "C" {
        +#endif
        +
        +#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	0
        +
        +#define TLS1_2_VERSION			0x0303
        +#define TLS1_2_VERSION_MAJOR		0x03
        +#define TLS1_2_VERSION_MINOR		0x03
        +
        +#define TLS1_1_VERSION			0x0302
        +#define TLS1_1_VERSION_MAJOR		0x03
        +#define TLS1_1_VERSION_MINOR		0x02
        +
        +#define TLS1_VERSION			0x0301
        +#define TLS1_VERSION_MAJOR		0x03
        +#define TLS1_VERSION_MINOR		0x01
        +
        +#define TLS1_get_version(s) \
        +		((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
        +
        +#define TLS1_get_client_version(s) \
        +		((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0)
        +
        +#define TLS1_AD_DECRYPTION_FAILED	21
        +#define TLS1_AD_RECORD_OVERFLOW		22
        +#define TLS1_AD_UNKNOWN_CA		48	/* fatal */
        +#define TLS1_AD_ACCESS_DENIED		49	/* fatal */
        +#define TLS1_AD_DECODE_ERROR		50	/* fatal */
        +#define TLS1_AD_DECRYPT_ERROR		51
        +#define TLS1_AD_EXPORT_RESTRICTION	60	/* fatal */
        +#define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
        +#define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
        +#define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
        +#define TLS1_AD_USER_CANCELLED		90
        +#define TLS1_AD_NO_RENEGOTIATION	100
        +/* codes 110-114 are from RFC3546 */
        +#define TLS1_AD_UNSUPPORTED_EXTENSION	110
        +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
        +#define TLS1_AD_UNRECOGNIZED_NAME 	112
        +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
        +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
        +#define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
        +
        +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */
        +#define TLSEXT_TYPE_server_name			0
        +#define TLSEXT_TYPE_max_fragment_length		1
        +#define TLSEXT_TYPE_client_certificate_url	2
        +#define TLSEXT_TYPE_trusted_ca_keys		3
        +#define TLSEXT_TYPE_truncated_hmac		4
        +#define TLSEXT_TYPE_status_request		5
        +/* ExtensionType values from RFC4681 */
        +#define TLSEXT_TYPE_user_mapping		6
        +
        +/* ExtensionType values from RFC5878 */
        +#define TLSEXT_TYPE_client_authz		7
        +#define TLSEXT_TYPE_server_authz		8
        +
        +/* ExtensionType values from RFC6091 */
        +#define TLSEXT_TYPE_cert_type		9
        +
        +/* ExtensionType values from RFC4492 */
        +#define TLSEXT_TYPE_elliptic_curves		10
        +#define TLSEXT_TYPE_ec_point_formats		11
        +
        +/* ExtensionType value from RFC5054 */
        +#define TLSEXT_TYPE_srp				12
        +
        +/* ExtensionType values from RFC5246 */
        +#define TLSEXT_TYPE_signature_algorithms	13
        +
        +/* ExtensionType value from RFC5764 */
        +#define TLSEXT_TYPE_use_srtp	14
        +
        +/* ExtensionType value from RFC5620 */
        +#define TLSEXT_TYPE_heartbeat	15
        +
        +/* ExtensionType value from RFC4507 */
        +#define TLSEXT_TYPE_session_ticket		35
        +
        +/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
        +#if 0 /* will have to be provided externally for now ,
        +       * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
        +       * using whatever extension number you'd like to try */
        +# define TLSEXT_TYPE_opaque_prf_input		?? */
        +#endif
        +
        +/* Temporary extension type */
        +#define TLSEXT_TYPE_renegotiate                 0xff01
        +
        +#ifndef OPENSSL_NO_NEXTPROTONEG
        +/* This is not an IANA defined extension number */
        +#define TLSEXT_TYPE_next_proto_neg		13172
        +#endif
        +
        +/* NameType value from RFC 3546 */
        +#define TLSEXT_NAMETYPE_host_name 0
        +/* status request value from RFC 3546 */
        +#define TLSEXT_STATUSTYPE_ocsp 1
        +
        +/* ECPointFormat values from draft-ietf-tls-ecc-12 */
        +#define TLSEXT_ECPOINTFORMAT_first			0
        +#define TLSEXT_ECPOINTFORMAT_uncompressed		0
        +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime	1
        +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2	2
        +#define TLSEXT_ECPOINTFORMAT_last			2
        +
        +/* Signature and hash algorithms from RFC 5246 */
        +
        +#define TLSEXT_signature_anonymous			0
        +#define TLSEXT_signature_rsa				1
        +#define TLSEXT_signature_dsa				2
        +#define TLSEXT_signature_ecdsa				3
        +
        +#define TLSEXT_hash_none				0
        +#define TLSEXT_hash_md5					1
        +#define TLSEXT_hash_sha1				2
        +#define TLSEXT_hash_sha224				3
        +#define TLSEXT_hash_sha256				4
        +#define TLSEXT_hash_sha384				5
        +#define TLSEXT_hash_sha512				6
        +
        +#ifndef OPENSSL_NO_TLSEXT
        +
        +#define TLSEXT_MAXLEN_host_name 255
        +
        +const char *SSL_get_servername(const SSL *s, const int type);
        +int SSL_get_servername_type(const SSL *s);
        +/* SSL_export_keying_material exports a value derived from the master secret,
        + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
        + * optional context. (Since a zero length context is allowed, the |use_context|
        + * flag controls whether a context is included.)
        + *
        + * It returns 1 on success and zero otherwise.
        + */
        +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
        +	const char *label, size_t llen, const unsigned char *p, size_t plen,
        +	int use_context);
        +
        +#define SSL_set_tlsext_host_name(s,name) \
        +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
        +
        +#define SSL_set_tlsext_debug_callback(ssl, cb) \
        +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
        +
        +#define SSL_set_tlsext_debug_arg(ssl, arg) \
        +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
        +
        +#define SSL_set_tlsext_status_type(ssl, type) \
        +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)
        +
        +#define SSL_get_tlsext_status_exts(ssl, arg) \
        +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
        +
        +#define SSL_set_tlsext_status_exts(ssl, arg) \
        +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
        +
        +#define SSL_get_tlsext_status_ids(ssl, arg) \
        +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
        +
        +#define SSL_set_tlsext_status_ids(ssl, arg) \
        +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
        +
        +#define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
        +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)
        +
        +#define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
        +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)
        +
        +#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
        +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
        +
        +#define SSL_TLSEXT_ERR_OK 0
        +#define SSL_TLSEXT_ERR_ALERT_WARNING 1
        +#define SSL_TLSEXT_ERR_ALERT_FATAL 2
        +#define SSL_TLSEXT_ERR_NOACK 3
        +
        +#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
        +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
        +
        +#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
        +#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
        +	SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))
        +
        +#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
        +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
        +
        +#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
        +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
        +
        +#define SSL_set_tlsext_opaque_prf_input(s, src, len) \
        +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
        +#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
        +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
        +#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
        +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
        +
        +#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
        +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
        +
        +#ifndef OPENSSL_NO_HEARTBEATS
        +#define SSL_TLSEXT_HB_ENABLED				0x01
        +#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS	0x02
        +#define SSL_TLSEXT_HB_DONT_RECV_REQUESTS	0x04
        +
        +#define SSL_get_tlsext_heartbeat_pending(ssl) \
        +        SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL)
        +#define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
        +        SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
        +#endif
        +#endif
        +
        +/* PSK ciphersuites from 4279 */
        +#define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
        +#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
        +#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
        +#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
        +
        +/* Additional TLS ciphersuites from expired Internet Draft
        + * draft-ietf-tls-56-bit-ciphersuites-01.txt
        + * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
        + * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
        + * shouldn't.  Note that the first two are actually not in the IDs. */
        +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060 /* not in ID */
        +#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061 /* not in ID */
        +#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA		0x03000062
        +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	0x03000063
        +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA		0x03000064
        +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	0x03000065
        +#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA		0x03000066
        +
        +/* AES ciphersuites from RFC3268 */
        +
        +#define TLS1_CK_RSA_WITH_AES_128_SHA			0x0300002F
        +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA			0x03000030
        +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA			0x03000031
        +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA		0x03000032
        +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA		0x03000033
        +#define TLS1_CK_ADH_WITH_AES_128_SHA			0x03000034
        +
        +#define TLS1_CK_RSA_WITH_AES_256_SHA			0x03000035
        +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA			0x03000036
        +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA			0x03000037
        +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA		0x03000038
        +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA		0x03000039
        +#define TLS1_CK_ADH_WITH_AES_256_SHA			0x0300003A
        +
        +/* TLS v1.2 ciphersuites */
        +#define TLS1_CK_RSA_WITH_NULL_SHA256			0x0300003B
        +#define TLS1_CK_RSA_WITH_AES_128_SHA256			0x0300003C
        +#define TLS1_CK_RSA_WITH_AES_256_SHA256			0x0300003D
        +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256		0x0300003E
        +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256		0x0300003F
        +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256		0x03000040
        +
        +/* Camellia ciphersuites from RFC4132 */
        +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA		0x03000041
        +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	0x03000042
        +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA	0x03000043
        +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA	0x03000044
        +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA	0x03000045
        +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA		0x03000046
        +
        +/* TLS v1.2 ciphersuites */
        +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256		0x03000067
        +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256		0x03000068
        +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256		0x03000069
        +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256		0x0300006A
        +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256		0x0300006B
        +#define TLS1_CK_ADH_WITH_AES_128_SHA256			0x0300006C
        +#define TLS1_CK_ADH_WITH_AES_256_SHA256			0x0300006D
        +
        +/* Camellia ciphersuites from RFC4132 */
        +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA		0x03000084
        +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA	0x03000085
        +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA	0x03000086
        +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA	0x03000087
        +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA	0x03000088
        +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA		0x03000089
        +
        +/* SEED ciphersuites from RFC4162 */
        +#define TLS1_CK_RSA_WITH_SEED_SHA                       0x03000096
        +#define TLS1_CK_DH_DSS_WITH_SEED_SHA                    0x03000097
        +#define TLS1_CK_DH_RSA_WITH_SEED_SHA                    0x03000098
        +#define TLS1_CK_DHE_DSS_WITH_SEED_SHA                   0x03000099
        +#define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
        +#define TLS1_CK_ADH_WITH_SEED_SHA                	0x0300009B
        +
        +/* TLS v1.2 GCM ciphersuites from RFC5288 */
        +#define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256		0x0300009C
        +#define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384		0x0300009D
        +#define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256		0x0300009E
        +#define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384		0x0300009F
        +#define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256		0x030000A0
        +#define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384		0x030000A1
        +#define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256		0x030000A2
        +#define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384		0x030000A3
        +#define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256		0x030000A4
        +#define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384		0x030000A5
        +#define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256		0x030000A6
        +#define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384		0x030000A7
        +
        +/* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */
        +#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
        +#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
        +#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
        +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
        +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005
        +
        +#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
        +#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
        +#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
        +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
        +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A
        +
        +#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
        +#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
        +#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
        +#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
        +#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F
        +
        +#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
        +#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
        +#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
        +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
        +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014
        +
        +#define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
        +#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
        +#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
        +#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
        +#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
        +
        +/* SRP ciphersuites from RFC 5054 */
        +#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA		0x0300C01A
        +#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA	0x0300C01B
        +#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA	0x0300C01C
        +#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA		0x0300C01D
        +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA	0x0300C01E
        +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA	0x0300C01F
        +#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA		0x0300C020
        +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA	0x0300C021
        +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA	0x0300C022
        +
        +/* ECDH HMAC based ciphersuites from RFC5289 */
        +
        +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256         0x0300C023
        +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384         0x0300C024
        +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256          0x0300C025
        +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384          0x0300C026
        +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256           0x0300C027
        +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384           0x0300C028
        +#define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256            0x0300C029
        +#define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384            0x0300C02A
        +
        +/* ECDH GCM based ciphersuites from RFC5289 */
        +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256	0x0300C02B
        +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384	0x0300C02C
        +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256      0x0300C02D
        +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384      0x0300C02E
        +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256       0x0300C02F
        +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384       0x0300C030
        +#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
        +#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032
        +
        +/* XXX
        + * Inconsistency alert:
        + * The OpenSSL names of ciphers with ephemeral DH here include the string
        + * "DHE", while elsewhere it has always been "EDH".
        + * (The alias for the list of all such ciphers also is "EDH".)
        + * The specifications speak of "EDH"; maybe we should allow both forms
        + * for everything. */
        +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5		"EXP1024-RC4-MD5"
        +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	"EXP1024-RC2-CBC-MD5"
        +#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DES-CBC-SHA"
        +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DHE-DSS-DES-CBC-SHA"
        +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA		"EXP1024-RC4-SHA"
        +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	"EXP1024-DHE-DSS-RC4-SHA"
        +#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA		"DHE-DSS-RC4-SHA"
        +
        +/* AES ciphersuites from RFC3268 */
        +#define TLS1_TXT_RSA_WITH_AES_128_SHA			"AES128-SHA"
        +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA		"DH-DSS-AES128-SHA"
        +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA		"DH-RSA-AES128-SHA"
        +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA		"DHE-DSS-AES128-SHA"
        +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA		"DHE-RSA-AES128-SHA"
        +#define TLS1_TXT_ADH_WITH_AES_128_SHA			"ADH-AES128-SHA"
        +
        +#define TLS1_TXT_RSA_WITH_AES_256_SHA			"AES256-SHA"
        +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA		"DH-DSS-AES256-SHA"
        +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA		"DH-RSA-AES256-SHA"
        +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA		"DHE-DSS-AES256-SHA"
        +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA		"DHE-RSA-AES256-SHA"
        +#define TLS1_TXT_ADH_WITH_AES_256_SHA			"ADH-AES256-SHA"
        +
        +/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */
        +#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
        +
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"
        +
        +#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
        +#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
        +#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
        +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
        +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
        +
        +#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
        +#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
        +#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
        +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
        +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"
        +
        +#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
        +#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
        +#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
        +#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
        +#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
        +
        +/* PSK ciphersuites from RFC 4279 */
        +#define TLS1_TXT_PSK_WITH_RC4_128_SHA			"PSK-RC4-SHA"
        +#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA		"PSK-3DES-EDE-CBC-SHA"
        +#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA		"PSK-AES128-CBC-SHA"
        +#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA		"PSK-AES256-CBC-SHA"
        +
        +/* SRP ciphersuite from RFC 5054 */
        +#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA		"SRP-3DES-EDE-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA	"SRP-RSA-3DES-EDE-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA	"SRP-DSS-3DES-EDE-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA		"SRP-AES-128-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA	"SRP-RSA-AES-128-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA	"SRP-DSS-AES-128-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA		"SRP-AES-256-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA	"SRP-RSA-AES-256-CBC-SHA"
        +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA	"SRP-DSS-AES-256-CBC-SHA"
        +
        +/* Camellia ciphersuites from RFC4132 */
        +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA		"CAMELLIA128-SHA"
        +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	"DH-DSS-CAMELLIA128-SHA"
        +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA	"DH-RSA-CAMELLIA128-SHA"
        +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA	"DHE-DSS-CAMELLIA128-SHA"
        +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA	"DHE-RSA-CAMELLIA128-SHA"
        +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA		"ADH-CAMELLIA128-SHA"
        +
        +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA		"CAMELLIA256-SHA"
        +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA	"DH-DSS-CAMELLIA256-SHA"
        +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA	"DH-RSA-CAMELLIA256-SHA"
        +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA	"DHE-DSS-CAMELLIA256-SHA"
        +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA	"DHE-RSA-CAMELLIA256-SHA"
        +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA		"ADH-CAMELLIA256-SHA"
        +
        +/* SEED ciphersuites from RFC4162 */
        +#define TLS1_TXT_RSA_WITH_SEED_SHA                      "SEED-SHA"
        +#define TLS1_TXT_DH_DSS_WITH_SEED_SHA                   "DH-DSS-SEED-SHA"
        +#define TLS1_TXT_DH_RSA_WITH_SEED_SHA                   "DH-RSA-SEED-SHA"
        +#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA                  "DHE-DSS-SEED-SHA"
        +#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
        +#define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
        +
        +/* TLS v1.2 ciphersuites */
        +#define TLS1_TXT_RSA_WITH_NULL_SHA256			"NULL-SHA256"
        +#define TLS1_TXT_RSA_WITH_AES_128_SHA256		"AES128-SHA256"
        +#define TLS1_TXT_RSA_WITH_AES_256_SHA256		"AES256-SHA256"
        +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256		"DH-DSS-AES128-SHA256"
        +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256		"DH-RSA-AES128-SHA256"
        +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256		"DHE-DSS-AES128-SHA256"
        +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256		"DHE-RSA-AES128-SHA256"
        +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256		"DH-DSS-AES256-SHA256"
        +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256		"DH-RSA-AES256-SHA256"
        +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256		"DHE-DSS-AES256-SHA256"
        +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256		"DHE-RSA-AES256-SHA256"
        +#define TLS1_TXT_ADH_WITH_AES_128_SHA256		"ADH-AES128-SHA256"
        +#define TLS1_TXT_ADH_WITH_AES_256_SHA256		"ADH-AES256-SHA256"
        +
        +/* TLS v1.2 GCM ciphersuites from RFC5288 */
        +#define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256		"AES128-GCM-SHA256"
        +#define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384		"AES256-GCM-SHA384"
        +#define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256	"DHE-RSA-AES128-GCM-SHA256"
        +#define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384	"DHE-RSA-AES256-GCM-SHA384"
        +#define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256		"DH-RSA-AES128-GCM-SHA256"
        +#define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384		"DH-RSA-AES256-GCM-SHA384"
        +#define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256	"DHE-DSS-AES128-GCM-SHA256"
        +#define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384	"DHE-DSS-AES256-GCM-SHA384"
        +#define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256		"DH-DSS-AES128-GCM-SHA256"
        +#define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384		"DH-DSS-AES256-GCM-SHA384"
        +#define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256		"ADH-AES128-GCM-SHA256"
        +#define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384		"ADH-AES256-GCM-SHA384"
        +
        +/* ECDH HMAC based ciphersuites from RFC5289 */
        +
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256    "ECDHE-ECDSA-AES128-SHA256"
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384    "ECDHE-ECDSA-AES256-SHA384"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256     "ECDH-ECDSA-AES128-SHA256"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384     "ECDH-ECDSA-AES256-SHA384"
        +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256      "ECDHE-RSA-AES128-SHA256"
        +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384      "ECDHE-RSA-AES256-SHA384"
        +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256       "ECDH-RSA-AES128-SHA256"
        +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384       "ECDH-RSA-AES256-SHA384"
        +
        +/* ECDH GCM based ciphersuites from RFC5289 */
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    "ECDHE-ECDSA-AES128-GCM-SHA256"
        +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    "ECDHE-ECDSA-AES256-GCM-SHA384"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256     "ECDH-ECDSA-AES128-GCM-SHA256"
        +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384     "ECDH-ECDSA-AES256-GCM-SHA384"
        +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256      "ECDHE-RSA-AES128-GCM-SHA256"
        +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384      "ECDHE-RSA-AES256-GCM-SHA384"
        +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
        +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"
        +
        +#define TLS_CT_RSA_SIGN			1
        +#define TLS_CT_DSS_SIGN			2
        +#define TLS_CT_RSA_FIXED_DH		3
        +#define TLS_CT_DSS_FIXED_DH		4
        +#define TLS_CT_ECDSA_SIGN		64
        +#define TLS_CT_RSA_FIXED_ECDH		65
        +#define TLS_CT_ECDSA_FIXED_ECDH 	66
        +#define TLS_CT_GOST94_SIGN		21
        +#define TLS_CT_GOST01_SIGN		22
        +/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
        + * comment there) */
        +#define TLS_CT_NUMBER			9
        +
        +#define TLS1_FINISH_MAC_LENGTH		12
        +
        +#define TLS_MD_MAX_CONST_SIZE			20
        +#define TLS_MD_CLIENT_FINISH_CONST		"client finished"
        +#define TLS_MD_CLIENT_FINISH_CONST_SIZE		15
        +#define TLS_MD_SERVER_FINISH_CONST		"server finished"
        +#define TLS_MD_SERVER_FINISH_CONST_SIZE		15
        +#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
        +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
        +#define TLS_MD_KEY_EXPANSION_CONST		"key expansion"
        +#define TLS_MD_KEY_EXPANSION_CONST_SIZE		13
        +#define TLS_MD_CLIENT_WRITE_KEY_CONST		"client write key"
        +#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE	16
        +#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
        +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
        +#define TLS_MD_IV_BLOCK_CONST			"IV block"
        +#define TLS_MD_IV_BLOCK_CONST_SIZE		8
        +#define TLS_MD_MASTER_SECRET_CONST		"master secret"
        +#define TLS_MD_MASTER_SECRET_CONST_SIZE		13
        +
        +#ifdef CHARSET_EBCDIC
        +#undef TLS_MD_CLIENT_FINISH_CONST
        +#define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*client finished*/
        +#undef TLS_MD_SERVER_FINISH_CONST
        +#define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*server finished*/
        +#undef TLS_MD_SERVER_WRITE_KEY_CONST
        +#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
        +#undef TLS_MD_KEY_EXPANSION_CONST
        +#define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"  /*key expansion*/
        +#undef TLS_MD_CLIENT_WRITE_KEY_CONST
        +#define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*client write key*/
        +#undef TLS_MD_SERVER_WRITE_KEY_CONST
        +#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
        +#undef TLS_MD_IV_BLOCK_CONST
        +#define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"  /*IV block*/
        +#undef TLS_MD_MASTER_SECRET_CONST
        +#define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
        +#endif
        +
        +/* TLS Session Ticket extension struct */
        +struct tls_session_ticket_ext_st
        +	{
        +	unsigned short length;
        +	void *data;
        +	};
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/ssl/tls_srp.c b/vendor/openssl/openssl/ssl/tls_srp.c
        new file mode 100644
        index 000000000..2315a7c0a
        --- /dev/null
        +++ b/vendor/openssl/openssl/ssl/tls_srp.c
        @@ -0,0 +1,507 @@
        +/* ssl/tls_srp.c */
        +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
        + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
        + * for the EdelKey project and contributed to the OpenSSL project 2004.
        + */
        +/* ====================================================================
        + * Copyright (c) 2004-2011 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 "ssl_locl.h"
        +#ifndef OPENSSL_NO_SRP
        +
        +#include <openssl/rand.h>
        +#include <openssl/srp.h>
        +#include <openssl/err.h>
        +
        +int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
        +	{
        +	if (ctx == NULL)
        +		return 0;
        +	OPENSSL_free(ctx->srp_ctx.login);
        +	BN_free(ctx->srp_ctx.N);
        +	BN_free(ctx->srp_ctx.g);
        +	BN_free(ctx->srp_ctx.s);
        +	BN_free(ctx->srp_ctx.B);
        +	BN_free(ctx->srp_ctx.A);
        +	BN_free(ctx->srp_ctx.a);
        +	BN_free(ctx->srp_ctx.b);
        +	BN_free(ctx->srp_ctx.v);
        +	ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
        +	ctx->srp_ctx.SRP_cb_arg = NULL;
        +	ctx->srp_ctx.SRP_verify_param_callback = NULL;
        +	ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
        +	ctx->srp_ctx.N = NULL;
        +	ctx->srp_ctx.g = NULL;
        +	ctx->srp_ctx.s = NULL;
        +	ctx->srp_ctx.B = NULL;
        +	ctx->srp_ctx.A = NULL;
        +	ctx->srp_ctx.a = NULL;
        +	ctx->srp_ctx.b = NULL;
        +	ctx->srp_ctx.v = NULL;
        +	ctx->srp_ctx.login = NULL;
        +	ctx->srp_ctx.info = NULL;
        +	ctx->srp_ctx.strength = SRP_MINIMAL_N;
        +	ctx->srp_ctx.srp_Mask = 0;
        +	return (1);
        +	}
        +
        +int SSL_SRP_CTX_free(struct ssl_st *s)
        +	{
        +	if (s == NULL)
        +		return 0;
        +	OPENSSL_free(s->srp_ctx.login);
        +	BN_free(s->srp_ctx.N);
        +	BN_free(s->srp_ctx.g);
        +	BN_free(s->srp_ctx.s);
        +	BN_free(s->srp_ctx.B);
        +	BN_free(s->srp_ctx.A);
        +	BN_free(s->srp_ctx.a);
        +	BN_free(s->srp_ctx.b);
        +	BN_free(s->srp_ctx.v);
        +	s->srp_ctx.TLS_ext_srp_username_callback = NULL;
        +	s->srp_ctx.SRP_cb_arg = NULL;
        +	s->srp_ctx.SRP_verify_param_callback = NULL;
        +	s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
        +	s->srp_ctx.N = NULL;
        +	s->srp_ctx.g = NULL;
        +	s->srp_ctx.s = NULL;
        +	s->srp_ctx.B = NULL;
        +	s->srp_ctx.A = NULL;
        +	s->srp_ctx.a = NULL;
        +	s->srp_ctx.b = NULL;
        +	s->srp_ctx.v = NULL;
        +	s->srp_ctx.login = NULL;
        +	s->srp_ctx.info = NULL;
        +	s->srp_ctx.strength = SRP_MINIMAL_N;
        +	s->srp_ctx.srp_Mask = 0;
        +	return (1);
        +	}
        +
        +int SSL_SRP_CTX_init(struct ssl_st *s)
        +	{
        +	SSL_CTX *ctx;
        +
        +	if ((s == NULL) || ((ctx = s->ctx) == NULL))
        +		return 0;
        +	s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
        +	/* set client Hello login callback */
        +	s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
        +	/* set SRP N/g param callback for verification */
        +	s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
        +	/* set SRP client passwd callback */
        +	s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
        +
        +	s->srp_ctx.N = NULL;
        +	s->srp_ctx.g = NULL;
        +	s->srp_ctx.s = NULL;
        +	s->srp_ctx.B = NULL;
        +	s->srp_ctx.A = NULL;
        +	s->srp_ctx.a = NULL;
        +	s->srp_ctx.b = NULL;
        +	s->srp_ctx.v = NULL;
        +	s->srp_ctx.login = NULL;
        +	s->srp_ctx.info = ctx->srp_ctx.info;
        +	s->srp_ctx.strength = ctx->srp_ctx.strength;
        +
        +	if (((ctx->srp_ctx.N != NULL) &&
        +		 ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
        +		((ctx->srp_ctx.g != NULL) &&
        +		 ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
        +		((ctx->srp_ctx.s != NULL) &&
        +		 ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
        +		((ctx->srp_ctx.B != NULL) &&
        +		 ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
        +		((ctx->srp_ctx.A != NULL) &&
        +		 ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
        +		((ctx->srp_ctx.a != NULL) &&
        +		 ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
        +		((ctx->srp_ctx.v != NULL) &&
        +		 ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
        +		((ctx->srp_ctx.b != NULL) &&
        +		 ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
        +		{
        +		SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
        +		goto err;
        +		}
        +	if ((ctx->srp_ctx.login != NULL) && 
        +		((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
        +		{
        +		SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
        +		goto err;
        +		}
        +	s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
        +
        +	return (1);
        +err:
        +	OPENSSL_free(s->srp_ctx.login);
        +	BN_free(s->srp_ctx.N);
        +	BN_free(s->srp_ctx.g);
        +	BN_free(s->srp_ctx.s);
        +	BN_free(s->srp_ctx.B);
        +	BN_free(s->srp_ctx.A);
        +	BN_free(s->srp_ctx.a);
        +	BN_free(s->srp_ctx.b);
        +	BN_free(s->srp_ctx.v);
        +	return (0);
        +	}
        +
        +int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
        +	{
        +	if (ctx == NULL)
        +		return 0;
        +
        +	ctx->srp_ctx.SRP_cb_arg = NULL;
        +	/* set client Hello login callback */
        +	ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
        +	/* set SRP N/g param callback for verification */
        +	ctx->srp_ctx.SRP_verify_param_callback = NULL;
        +	/* set SRP client passwd callback */
        +	ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
        +
        +	ctx->srp_ctx.N = NULL;
        +	ctx->srp_ctx.g = NULL;
        +	ctx->srp_ctx.s = NULL;
        +	ctx->srp_ctx.B = NULL;
        +	ctx->srp_ctx.A = NULL;
        +	ctx->srp_ctx.a = NULL;
        +	ctx->srp_ctx.b = NULL;
        +	ctx->srp_ctx.v = NULL;
        +	ctx->srp_ctx.login = NULL;
        +	ctx->srp_ctx.srp_Mask = 0;
        +	ctx->srp_ctx.info = NULL;
        +	ctx->srp_ctx.strength = SRP_MINIMAL_N;
        +
        +	return (1);
        +	}
        +
        +/* server side */
        +int SSL_srp_server_param_with_username(SSL *s, int *ad)
        +	{
        +	unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
        +	int al;
        +
        +	*ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
        +	if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
        +		((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
        +			return al;
        +
        +	*ad = SSL_AD_INTERNAL_ERROR;
        +	if ((s->srp_ctx.N == NULL) ||
        +		(s->srp_ctx.g == NULL) ||
        +		(s->srp_ctx.s == NULL) ||
        +		(s->srp_ctx.v == NULL))
        +		return SSL3_AL_FATAL;
        +
        +	if (RAND_bytes(b, sizeof(b)) <= 0)
        +		return SSL3_AL_FATAL;
        +	s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
        +	OPENSSL_cleanse(b,sizeof(b));
        +
        +	/* Calculate:  B = (kv + g^b) % N  */
        +
        +	return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
        +			SSL_ERROR_NONE:SSL3_AL_FATAL;
        +	}
        +
        +/* If the server just has the raw password, make up a verifier entry on the fly */
        +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
        +	{
        +	SRP_gN *GN = SRP_get_default_gN(grp);
        +	if(GN == NULL) return -1;
        +	s->srp_ctx.N = BN_dup(GN->N);
        +	s->srp_ctx.g = BN_dup(GN->g);
        +	if(s->srp_ctx.v != NULL)
        +		{
        +		BN_clear_free(s->srp_ctx.v);
        +		s->srp_ctx.v = NULL;
        +		}
        +	if(s->srp_ctx.s != NULL)
        +		{
        +		BN_clear_free(s->srp_ctx.s);
        +		s->srp_ctx.s = NULL;
        +		}
        +	if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;
        +
        +	return 1;
        +	}
        +
        +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
        +			     BIGNUM *sa, BIGNUM *v, char *info)
        +	{
        +	if (N!= NULL)
        +		{
        +		if (s->srp_ctx.N != NULL)
        +			{
        +			if (!BN_copy(s->srp_ctx.N,N))
        +				{
        +				BN_free(s->srp_ctx.N);
        +				s->srp_ctx.N = NULL;
        +				}
        +			}
        +		else
        +			s->srp_ctx.N = BN_dup(N);
        +		}
        +	if (g!= NULL)
        +		{
        +		if (s->srp_ctx.g != NULL)
        +			{
        +			if (!BN_copy(s->srp_ctx.g,g))
        +				{
        +				BN_free(s->srp_ctx.g);
        +				s->srp_ctx.g = NULL;
        +				}
        +			}
        +		else
        +			s->srp_ctx.g = BN_dup(g);
        +		}
        +	if (sa!= NULL)
        +		{
        +		if (s->srp_ctx.s != NULL)
        +			{
        +			if (!BN_copy(s->srp_ctx.s,sa))
        +				{
        +				BN_free(s->srp_ctx.s);
        +				s->srp_ctx.s = NULL;
        +				}
        +			}
        +		else
        +			s->srp_ctx.s = BN_dup(sa);
        +		}
        +	if (v!= NULL)
        +		{
        +		if (s->srp_ctx.v != NULL)
        +			{
        +			if (!BN_copy(s->srp_ctx.v,v))
        +				{
        +				BN_free(s->srp_ctx.v);
        +				s->srp_ctx.v = NULL;
        +				}
        +			}
        +		else
        +			s->srp_ctx.v = BN_dup(v);
        +		}
        +	s->srp_ctx.info = info;
        +
        +	if (!(s->srp_ctx.N) ||
        +		!(s->srp_ctx.g) ||
        +		!(s->srp_ctx.s) ||
        +		!(s->srp_ctx.v))
        +		return -1;
        +
        +	return 1;
        +	}
        +
        +int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
        +	{
        +	BIGNUM *K = NULL, *u = NULL;
        +	int ret = -1, tmp_len;
        +	unsigned char *tmp = NULL;
        +
        +	if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
        +		goto err;
        +	if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
        +		goto err;
        +	if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
        +		goto err;
        +
        +	tmp_len = BN_num_bytes(K);
        +	if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
        +		goto err;
        +	BN_bn2bin(K, tmp);
        +	ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
        +err:
        +	if (tmp)
        +		{
        +		OPENSSL_cleanse(tmp,tmp_len) ;
        +		OPENSSL_free(tmp);
        +		}
        +	BN_clear_free(K);
        +	BN_clear_free(u);
        +	return ret;
        +	}
        +
        +/* client side */
        +int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
        +	{
        +	BIGNUM *x = NULL, *u = NULL, *K = NULL;
        +	int ret = -1, tmp_len;
        +	char *passwd = NULL;
        +	unsigned char *tmp = NULL;
        +
        +	/* Checks if b % n == 0
        +	 */
        +	if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
        +	if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
        +	if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
        +	if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
        +	if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
        +	if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;
        +
        +	tmp_len = BN_num_bytes(K);
        +	if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
        +	BN_bn2bin(K, tmp);
        +	ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
        +err:
        +	if (tmp)
        +		{
        +		OPENSSL_cleanse(tmp,tmp_len) ;
        +		OPENSSL_free(tmp);
        +		}
        +	BN_clear_free(K);
        +	BN_clear_free(x);
        +	if (passwd)
        +		{
        +		OPENSSL_cleanse(passwd,strlen(passwd)) ;
        +		OPENSSL_free(passwd);
        +		}
        +	BN_clear_free(u);
        +	return ret;
        +	}
        +
        +int SRP_Calc_A_param(SSL *s)
        +	{
        +	unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
        +
        +	if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
        +		return -1;
        +
        +	if (s->srp_ctx.SRP_verify_param_callback ==NULL && 
        +		!SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
        +		return -1 ;
        +
        +	RAND_bytes(rnd, sizeof(rnd));
        +	s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
        +	OPENSSL_cleanse(rnd, sizeof(rnd));
        +
        +	if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
        +		return -1;
        +
        +	/* We can have a callback to verify SRP param!! */
        +	if (s->srp_ctx.SRP_verify_param_callback !=NULL) 
        +		return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);
        +
        +	return 1;
        +	}
        +
        +BIGNUM *SSL_get_srp_g(SSL *s)
        +	{
        +	if (s->srp_ctx.g != NULL)
        +		return s->srp_ctx.g;
        +	return s->ctx->srp_ctx.g;
        +	}
        +
        +BIGNUM *SSL_get_srp_N(SSL *s)
        +	{
        +	if (s->srp_ctx.N != NULL)
        +		return s->srp_ctx.N;
        +	return s->ctx->srp_ctx.N;
        +	}
        +
        +char *SSL_get_srp_username(SSL *s)
        +	{
        +	if (s->srp_ctx.login != NULL)
        +		return s->srp_ctx.login;
        +	return s->ctx->srp_ctx.login;
        +	}
        +
        +char *SSL_get_srp_userinfo(SSL *s)
        +	{
        +	if (s->srp_ctx.info != NULL)
        +		return s->srp_ctx.info;
        +	return s->ctx->srp_ctx.info;
        +	}
        +
        +#define tls1_ctx_ctrl ssl3_ctx_ctrl
        +#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
        +
        +int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name)
        +	{
        +	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME,0,name);
        +	}
        +
        +int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password)
        +	{
        +	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD,0,password);
        +	}
        +
        +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
        +	{
        +	return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
        +			     NULL);
        +	}
        +
        +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
        +	{
        +	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
        +				      (void (*)(void))cb);
        +	}
        +
        +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
        +	{
        +	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
        +	}
        +
        +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
        +				      int (*cb)(SSL *,int *,void *))
        +	{
        +	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
        +				      (void (*)(void))cb);
        +	}
        +
        +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
        +	{
        +	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
        +				      (void (*)(void))cb);
        +	}
        +
        +#endif
        diff --git a/vendor/openssl/openssl/test/CAss.cnf b/vendor/openssl/openssl/test/CAss.cnf
        new file mode 100644
        index 000000000..109bc8c10
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/CAss.cnf
        @@ -0,0 +1,76 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +RANDFILE		= ./.rnd
        +
        +####################################################################
        +[ req ]
        +default_bits		= 2048
        +default_keyfile 	= keySS.pem
        +distinguished_name	= req_distinguished_name
        +encrypt_rsa_key		= no
        +default_md		= sha1
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_value		= AU
        +
        +organizationName		= Organization Name (eg, company)
        +organizationName_value		= Dodgy Brothers
        +
        +commonName			= Common Name (eg, YOUR name)
        +commonName_value		= Dodgy CA
        +
        +####################################################################
        +[ ca ]
        +default_ca	= CA_default		# The default ca section
        +
        +####################################################################
        +[ CA_default ]
        +
        +dir		= ./demoCA		# Where everything is kept
        +certs		= $dir/certs		# Where the issued certs are kept
        +crl_dir		= $dir/crl		# Where the issued crl are kept
        +database	= $dir/index.txt	# database index file.
        +#unique_subject	= no			# Set to 'no' to allow creation of
        +					# several ctificates with same subject.
        +new_certs_dir	= $dir/newcerts		# default place for new certs.
        +
        +certificate	= $dir/cacert.pem 	# The CA certificate
        +serial		= $dir/serial 		# The current serial number
        +crl		= $dir/crl.pem 		# The current CRL
        +private_key	= $dir/private/cakey.pem# The private key
        +RANDFILE	= $dir/private/.rand	# private random number file
        +
        +x509_extensions	= v3_ca			# The extentions to add to the cert
        +
        +name_opt 	= ca_default		# Subject Name options
        +cert_opt 	= ca_default		# Certificate field options
        +
        +default_days	= 365			# how long to certify for
        +default_crl_days= 30			# how long before next CRL
        +default_md	= md5			# which md to use.
        +preserve	= no			# keep passed DN ordering
        +
        +policy		= policy_anything
        +
        +[ policy_anything ]
        +countryName		= optional
        +stateOrProvinceName	= optional
        +localityName		= optional
        +organizationName	= optional
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +
        +
        +[ v3_ca ]
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid:always,issuer:always
        +basicConstraints = CA:true,pathlen:1
        +keyUsage = cRLSign, keyCertSign
        +issuerAltName=issuer:copy
        diff --git a/vendor/openssl/openssl/test/CAssdh.cnf b/vendor/openssl/openssl/test/CAssdh.cnf
        new file mode 100644
        index 000000000..4e0a90867
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/CAssdh.cnf
        @@ -0,0 +1,24 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +# hacked by iang to do DH certs - CA
        +
        +RANDFILE              = ./.rnd
        +
        +####################################################################
        +[ req ]
        +distinguished_name    = req_distinguished_name
        +encrypt_rsa_key               = no
        +
        +[ req_distinguished_name ]
        +countryName                   = Country Name (2 letter code)
        +countryName_default           = CU
        +countryName_value             = CU
        +
        +organizationName              = Organization Name (eg, company)
        +organizationName_value                = La Junta de la Revolucion
        +
        +commonName                    = Common Name (eg, YOUR name)
        +commonName_value              = Junta
        +
        diff --git a/vendor/openssl/openssl/test/CAssdsa.cnf b/vendor/openssl/openssl/test/CAssdsa.cnf
        new file mode 100644
        index 000000000..a6b4d1810
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/CAssdsa.cnf
        @@ -0,0 +1,23 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +# hacked by iang to do DSA certs - CA
        +
        +RANDFILE              = ./.rnd
        +
        +####################################################################
        +[ req ]
        +distinguished_name    = req_distinguished_name
        +encrypt_rsa_key               = no
        +
        +[ req_distinguished_name ]
        +countryName                   = Country Name (2 letter code)
        +countryName_default           = ES
        +countryName_value             = ES
        +
        +organizationName              = Organization Name (eg, company)
        +organizationName_value                = Hermanos Locos
        +
        +commonName                    = Common Name (eg, YOUR name)
        +commonName_value              = Hermanos Locos CA
        diff --git a/vendor/openssl/openssl/test/CAssrsa.cnf b/vendor/openssl/openssl/test/CAssrsa.cnf
        new file mode 100644
        index 000000000..eb24a6dfc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/CAssrsa.cnf
        @@ -0,0 +1,24 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +# create RSA certs - CA
        +
        +RANDFILE              = ./.rnd
        +
        +####################################################################
        +[ req ]
        +distinguished_name    = req_distinguished_name
        +encrypt_key           = no
        +
        +[ req_distinguished_name ]
        +countryName                   = Country Name (2 letter code)
        +countryName_default           = ES
        +countryName_value             = ES
        +
        +organizationName              = Organization Name (eg, company)
        +organizationName_value                = Hermanos Locos
        +
        +commonName                    = Common Name (eg, YOUR name)
        +commonName_value              = Hermanos Locos CA
        +
        diff --git a/vendor/openssl/openssl/test/CAtsa.cnf b/vendor/openssl/openssl/test/CAtsa.cnf
        new file mode 100644
        index 000000000..f5a275bfc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/CAtsa.cnf
        @@ -0,0 +1,163 @@
        +
        +#
        +# This config is used by the Time Stamp Authority tests.
        +#
        +
        +RANDFILE		= ./.rnd
        +
        +# Extra OBJECT IDENTIFIER info:
        +oid_section		= new_oids
        +
        +TSDNSECT		= ts_cert_dn
        +INDEX			= 1
        +
        +[ new_oids ]
        +
        +# Policies used by the TSA tests.
        +tsa_policy1 = 1.2.3.4.1
        +tsa_policy2 = 1.2.3.4.5.6
        +tsa_policy3 = 1.2.3.4.5.7
        +
        +#----------------------------------------------------------------------
        +[ ca ]
        +default_ca	= CA_default		# The default ca section
        +
        +[ CA_default ]
        +
        +dir		= ./demoCA
        +certs		= $dir/certs		# Where the issued certs are kept
        +database	= $dir/index.txt	# database index file.
        +new_certs_dir	= $dir/newcerts		# default place for new certs.
        +
        +certificate	= $dir/cacert.pem 	# The CA certificate
        +serial		= $dir/serial 		# The current serial number
        +private_key	= $dir/private/cakey.pem# The private key
        +RANDFILE	= $dir/private/.rand	# private random number file
        +
        +default_days	= 365			# how long to certify for
        +default_md	= sha1			# which md to use.
        +preserve	= no			# keep passed DN ordering
        +
        +policy		= policy_match
        +
        +# For the CA policy
        +[ policy_match ]
        +countryName		= supplied
        +stateOrProvinceName	= supplied
        +organizationName	= supplied
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +#----------------------------------------------------------------------
        +[ req ]
        +default_bits		= 1024
        +default_md		= sha1
        +distinguished_name	= $ENV::TSDNSECT
        +encrypt_rsa_key		= no
        +prompt 			= no
        +# attributes		= req_attributes
        +x509_extensions	= v3_ca	# The extentions to add to the self signed cert
        +
        +string_mask = nombstr
        +
        +[ ts_ca_dn ]
        +countryName			= HU
        +stateOrProvinceName		= Budapest
        +localityName			= Budapest
        +organizationName		= Gov-CA Ltd.
        +commonName			= ca1
        +
        +[ ts_cert_dn ]
        +countryName			= HU
        +stateOrProvinceName		= Budapest
        +localityName			= Buda
        +organizationName		= Hun-TSA Ltd.
        +commonName			= tsa$ENV::INDEX
        +
        +[ tsa_cert ]
        +
        +# TSA server cert is not a CA cert.
        +basicConstraints=CA:FALSE
        +
        +# The following key usage flags are needed for TSA server certificates.
        +keyUsage = nonRepudiation, digitalSignature
        +extendedKeyUsage = critical,timeStamping
        +
        +# PKIX recommendations harmless if included in all certificates.
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer:always
        +
        +[ non_tsa_cert ]
        +
        +# This is not a CA cert and not a TSA cert, either (timeStamping usage missing)
        +basicConstraints=CA:FALSE
        +
        +# The following key usage flags are needed for TSA server certificates.
        +keyUsage = nonRepudiation, digitalSignature
        +# timeStamping is not supported by this certificate
        +# extendedKeyUsage = critical,timeStamping
        +
        +# PKIX recommendations harmless if included in all certificates.
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer:always
        +
        +[ v3_req ]
        +
        +# Extensions to add to a certificate request
        +basicConstraints = CA:FALSE
        +keyUsage = nonRepudiation, digitalSignature
        +
        +[ v3_ca ]
        +
        +# Extensions for a typical CA
        +
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid:always,issuer:always
        +basicConstraints = critical,CA:true
        +keyUsage = cRLSign, keyCertSign
        +
        +#----------------------------------------------------------------------
        +[ tsa ]
        +
        +default_tsa = tsa_config1	# the default TSA section
        +
        +[ tsa_config1 ]
        +
        +# These are used by the TSA reply generation only.
        +dir		= .			# TSA root directory
        +serial		= $dir/tsa_serial	# The current serial number (mandatory)
        +signer_cert	= $dir/tsa_cert1.pem 	# The TSA signing certificate
        +					# (optional)
        +certs		= $dir/tsaca.pem	# Certificate chain to include in reply
        +					# (optional)
        +signer_key	= $dir/tsa_key1.pem	# The TSA private key (optional)
        +
        +default_policy	= tsa_policy1		# Policy if request did not specify it
        +					# (optional)
        +other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
        +digests		= md5, sha1		# Acceptable message digests (mandatory)
        +accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
        +ordering		= yes	# Is ordering defined for timestamps?
        +				# (optional, default: no)
        +tsa_name		= yes	# Must the TSA name be included in the reply?
        +				# (optional, default: no)
        +ess_cert_id_chain	= yes	# Must the ESS cert id chain be included?
        +				# (optional, default: no)
        +
        +[ tsa_config2 ]
        +
        +# This configuration uses a certificate which doesn't have timeStamping usage.
        +# These are used by the TSA reply generation only.
        +dir		= .			# TSA root directory
        +serial		= $dir/tsa_serial	# The current serial number (mandatory)
        +signer_cert	= $dir/tsa_cert2.pem 	# The TSA signing certificate
        +					# (optional)
        +certs		= $dir/demoCA/cacert.pem# Certificate chain to include in reply
        +					# (optional)
        +signer_key	= $dir/tsa_key2.pem	# The TSA private key (optional)
        +
        +default_policy	= tsa_policy1		# Policy if request did not specify it
        +					# (optional)
        +other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
        +digests		= md5, sha1		# Acceptable message digests (mandatory)
        diff --git a/vendor/openssl/openssl/test/Makefile b/vendor/openssl/openssl/test/Makefile
        new file mode 100644
        index 000000000..4c9eabcc2
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/Makefile
        @@ -0,0 +1,729 @@
        +#
        +# test/Makefile
        +#
        +
        +DIR=		test
        +TOP=		..
        +CC=		cc
        +INCLUDES=	-I$(TOP) -I../include $(KRB5_INCLUDES)
        +CFLAG=		-g
        +MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
        +PERL=		perl
        +# KRB5 stuff
        +KRB5_INCLUDES=
        +LIBKRB5=
        +
        +PEX_LIBS=
        +EX_LIBS= #-lnsl -lsocket
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile maketests.com \
        +	tests.com testenc.com tx509.com trsa.com tcrl.com tsid.com treq.com \
        +	tpkcs7.com tpkcs7d.com tverify.com testgen.com testss.com testssl.com \
        +	testca.com VMSca-response.1 VMSca-response.2
        +
        +DLIBCRYPTO= ../libcrypto.a
        +DLIBSSL= ../libssl.a
        +LIBCRYPTO= -L.. -lcrypto
        +LIBSSL= -L.. -lssl
        +
        +BNTEST=		bntest
        +ECTEST=		ectest
        +ECDSATEST=	ecdsatest
        +ECDHTEST=	ecdhtest
        +EXPTEST=	exptest
        +IDEATEST=	ideatest
        +SHATEST=	shatest
        +SHA1TEST=	sha1test
        +SHA256TEST=	sha256t
        +SHA512TEST=	sha512t
        +MDC2TEST=	mdc2test
        +RMDTEST=	rmdtest
        +MD2TEST=	md2test
        +MD4TEST=	md4test
        +MD5TEST=	md5test
        +HMACTEST=	hmactest
        +WPTEST=		wp_test
        +RC2TEST=	rc2test
        +RC4TEST=	rc4test
        +RC5TEST=	rc5test
        +BFTEST=		bftest
        +CASTTEST=	casttest
        +DESTEST=	destest
        +RANDTEST=	randtest
        +DHTEST=		dhtest
        +DSATEST=	dsatest
        +METHTEST=	methtest
        +SSLTEST=	ssltest
        +RSATEST=	rsa_test
        +ENGINETEST=	enginetest
        +EVPTEST=	evp_test
        +IGETEST=	igetest
        +JPAKETEST=	jpaketest
        +SRPTEST=	srptest
        +ASN1TEST=	asn1test
        +
        +TESTS=		alltests
        +
        +EXE=	$(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_EXT)  $(ECDSATEST)$(EXE_EXT) $(ECDHTEST)$(EXE_EXT) $(IDEATEST)$(EXE_EXT) \
        +	$(MD2TEST)$(EXE_EXT)  $(MD4TEST)$(EXE_EXT) $(MD5TEST)$(EXE_EXT) $(HMACTEST)$(EXE_EXT) $(WPTEST)$(EXE_EXT) \
        +	$(RC2TEST)$(EXE_EXT) $(RC4TEST)$(EXE_EXT) $(RC5TEST)$(EXE_EXT) \
        +	$(DESTEST)$(EXE_EXT) $(SHATEST)$(EXE_EXT) $(SHA1TEST)$(EXE_EXT) $(SHA256TEST)$(EXE_EXT) $(SHA512TEST)$(EXE_EXT) \
        +	$(MDC2TEST)$(EXE_EXT) $(RMDTEST)$(EXE_EXT) \
        +	$(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \
        +	$(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
        +	$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT) \
        +	$(ASN1TEST)$(EXE_EXT)
        +
        +# $(METHTEST)$(EXE_EXT)
        +
        +OBJ=	$(BNTEST).o $(ECTEST).o  $(ECDSATEST).o $(ECDHTEST).o $(IDEATEST).o \
        +	$(MD2TEST).o $(MD4TEST).o $(MD5TEST).o \
        +	$(HMACTEST).o $(WPTEST).o \
        +	$(RC2TEST).o $(RC4TEST).o $(RC5TEST).o \
        +	$(DESTEST).o $(SHATEST).o $(SHA1TEST).o $(SHA256TEST).o $(SHA512TEST).o \
        +	$(MDC2TEST).o $(RMDTEST).o \
        +	$(RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \
        +	$(BFTEST).o  $(SSLTEST).o  $(DSATEST).o  $(EXPTEST).o $(RSATEST).o \
        +	$(EVPTEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o
        +SRC=	$(BNTEST).c $(ECTEST).c  $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
        +	$(MD2TEST).c  $(MD4TEST).c $(MD5TEST).c \
        +	$(HMACTEST).c $(WPTEST).c \
        +	$(RC2TEST).c $(RC4TEST).c $(RC5TEST).c \
        +	$(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \
        +	$(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
        +	$(BFTEST).c  $(SSLTEST).c $(DSATEST).c   $(EXPTEST).c $(RSATEST).c \
        +	$(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c
        +
        +EXHEADER= 
        +HEADER=	$(EXHEADER)
        +
        +ALL=    $(GENERAL) $(SRC) $(HEADER)
        +
        +top:
        +	(cd ..; $(MAKE) DIRS=$(DIR) TESTS=$(TESTS) all)
        +
        +all:	exe
        +
        +exe:	$(EXE) dummytest$(EXE_EXT)
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +
        +generate: $(SRC)
        +$(SRC):
        +	@sh $(TOP)/util/point.sh dummytest.c $@
        +
        +errors:
        +
        +install:
        +
        +tags:
        +	ctags $(SRC)
        +
        +tests:	exe apps $(TESTS)
        +
        +apps:
        +	@(cd ..; $(MAKE) DIRS=apps all)
        +
        +alltests: \
        +	test_des test_idea test_sha test_md4 test_md5 test_hmac \
        +	test_md2 test_mdc2 test_wp \
        +	test_rmd test_rc2 test_rc4 test_rc5 test_bf test_cast test_aes \
        +	test_rand test_bn test_ec test_ecdsa test_ecdh \
        +	test_enc test_x509 test_rsa test_crl test_sid \
        +	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
        +	test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \
        +	test_jpake test_srp test_cms
        +
        +test_evp:
        +	../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
        +
        +test_des:
        +	../util/shlib_wrap.sh ./$(DESTEST)
        +
        +test_idea:
        +	../util/shlib_wrap.sh ./$(IDEATEST)
        +
        +test_sha:
        +	../util/shlib_wrap.sh ./$(SHATEST)
        +	../util/shlib_wrap.sh ./$(SHA1TEST)
        +	../util/shlib_wrap.sh ./$(SHA256TEST)
        +	../util/shlib_wrap.sh ./$(SHA512TEST)
        +
        +test_mdc2:
        +	../util/shlib_wrap.sh ./$(MDC2TEST)
        +
        +test_md5:
        +	../util/shlib_wrap.sh ./$(MD5TEST)
        +
        +test_md4:
        +	../util/shlib_wrap.sh ./$(MD4TEST)
        +
        +test_hmac:
        +	../util/shlib_wrap.sh ./$(HMACTEST)
        +
        +test_wp:
        +	../util/shlib_wrap.sh ./$(WPTEST)
        +
        +test_md2:
        +	../util/shlib_wrap.sh ./$(MD2TEST)
        +
        +test_rmd:
        +	../util/shlib_wrap.sh ./$(RMDTEST)
        +
        +test_bf:
        +	../util/shlib_wrap.sh ./$(BFTEST)
        +
        +test_cast:
        +	../util/shlib_wrap.sh ./$(CASTTEST)
        +
        +test_rc2:
        +	../util/shlib_wrap.sh ./$(RC2TEST)
        +
        +test_rc4:
        +	../util/shlib_wrap.sh ./$(RC4TEST)
        +
        +test_rc5:
        +	../util/shlib_wrap.sh ./$(RC5TEST)
        +
        +test_rand:
        +	../util/shlib_wrap.sh ./$(RANDTEST)
        +
        +test_enc:
        +	@sh ./testenc
        +
        +test_x509:
        +	echo test normal x509v1 certificate
        +	sh ./tx509 2>/dev/null
        +	echo test first x509v3 certificate
        +	sh ./tx509 v3-cert1.pem 2>/dev/null
        +	echo test second x509v3 certificate
        +	sh ./tx509 v3-cert2.pem 2>/dev/null
        +
        +test_rsa: $(RSATEST)$(EXE_EXT)
        +	@sh ./trsa 2>/dev/null
        +	../util/shlib_wrap.sh ./$(RSATEST)
        +
        +test_crl:
        +	@sh ./tcrl 2>/dev/null
        +
        +test_sid:
        +	@sh ./tsid 2>/dev/null
        +
        +test_req:
        +	@sh ./treq 2>/dev/null
        +	@sh ./treq testreq2.pem 2>/dev/null
        +
        +test_pkcs7:
        +	@sh ./tpkcs7 2>/dev/null
        +	@sh ./tpkcs7d 2>/dev/null
        +
        +test_bn:
        +	@echo starting big number library test, could take a while...
        +	@../util/shlib_wrap.sh ./$(BNTEST) >tmp.bntest
        +	@echo quit >>tmp.bntest
        +	@echo "running bc"
        +	@<tmp.bntest sh -c "`sh ./bctest ignore`" | $(PERL) -e '$$i=0; while (<STDIN>) {if (/^test (.*)/) {print STDERR "\nverify $$1";} elsif (!/^0$$/) {die "\nFailed! bc: $$_";} else {print STDERR "."; $$i++;}} print STDERR "\n$$i tests passed\n"'
        +	@echo 'test a^b%c implementations'
        +	../util/shlib_wrap.sh ./$(EXPTEST)
        +
        +test_ec:
        +	@echo 'test elliptic curves'
        +	../util/shlib_wrap.sh ./$(ECTEST)
        +
        +test_ecdsa:
        +	@echo 'test ecdsa'
        +	../util/shlib_wrap.sh ./$(ECDSATEST)
        +
        +test_ecdh:
        +	@echo 'test ecdh'
        +	../util/shlib_wrap.sh ./$(ECDHTEST)
        +
        +test_verify:
        +	@echo "The following command should have some OK's and some failures"
        +	@echo "There are definitly a few expired certificates"
        +	../util/shlib_wrap.sh ../apps/openssl verify -CApath ../certs/demo ../certs/demo/*.pem
        +
        +test_dh:
        +	@echo "Generate a set of DH parameters"
        +	../util/shlib_wrap.sh ./$(DHTEST)
        +
        +test_dsa:
        +	@echo "Generate a set of DSA parameters"
        +	../util/shlib_wrap.sh ./$(DSATEST)
        +	../util/shlib_wrap.sh ./$(DSATEST) -app2_1
        +
        +test_gen:
        +	@echo "Generate and verify a certificate request"
        +	@sh ./testgen
        +
        +test_ss keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
        +		intP1.ss intP2.ss: testss
        +	@echo "Generate and certify a test certificate"
        +	@sh ./testss
        +	@cat certCA.ss certU.ss > intP1.ss
        +	@cat certCA.ss certU.ss certP1.ss > intP2.ss
        +
        +test_engine: 
        +	@echo "Manipulate the ENGINE structures"
        +	../util/shlib_wrap.sh ./$(ENGINETEST)
        +
        +test_ssl: keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \
        +		intP1.ss intP2.ss
        +	@echo "test SSL protocol"
        +	@if [ -n "$(FIPSCANLIB)" ]; then \
        +	  sh ./testfipsssl keyU.ss certU.ss certCA.ss; \
        +	fi
        +	../util/shlib_wrap.sh ./$(SSLTEST) -test_cipherlist
        +	@sh ./testssl keyU.ss certU.ss certCA.ss
        +	@sh ./testsslproxy keyP1.ss certP1.ss intP1.ss
        +	@sh ./testsslproxy keyP2.ss certP2.ss intP2.ss
        +
        +test_ca:
        +	@if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
        +	  echo "skipping CA.sh test -- requires RSA"; \
        +	else \
        +	  echo "Generate and certify a test certificate via the 'ca' program"; \
        +	  sh ./testca; \
        +	fi
        +
        +test_aes: #$(AESTEST)
        +#	@echo "test Rijndael"
        +#	../util/shlib_wrap.sh ./$(AESTEST)
        +
        +test_tsa:
        +	@if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then \
        +	  echo "skipping testtsa test -- requires RSA"; \
        +	else \
        +	  sh ./testtsa; \
        +	fi
        +
        +test_ige: $(IGETEST)$(EXE_EXT)
        +	@echo "Test IGE mode"
        +	../util/shlib_wrap.sh ./$(IGETEST)
        +
        +test_jpake: $(JPAKETEST)$(EXE_EXT)
        +	@echo "Test JPAKE"
        +	../util/shlib_wrap.sh ./$(JPAKETEST)
        +
        +test_cms:
        +	@echo "CMS consistency test"
        +	$(PERL) cms-test.pl
        +
        +test_srp: $(SRPTEST)$(EXE_EXT)
        +	@echo "Test SRP"
        +	../util/shlib_wrap.sh ./srptest
        +
        +lint:
        +	lint -DLINT $(INCLUDES) $(SRC)>fluff
        +
        +depend:
        +	@if [ -z "$(THIS)" ]; then \
        +	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
        +	else \
        +	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
        +	fi
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +	rm -f $(SRC) $(SHA256TEST).c $(SHA512TEST).c evptests.txt newkey.pem testkey.pem \
        +			testreq.pem
        +
        +clean:
        +	rm -f .rnd tmp.bntest tmp.bctest *.o *.obj *.dll lib tags core .pure .nfs* *.old *.bak fluff $(EXE) *.ss *.srl log dummytest
        +
        +$(DLIBSSL):
        +	(cd ..; $(MAKE) DIRS=ssl all)
        +
        +$(DLIBCRYPTO):
        +	(cd ..; $(MAKE) DIRS=crypto all)
        +
        +BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
        +		shlib_target="$(SHLIB_TARGET)"; \
        +	fi; \
        +	LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
        +	$(MAKE) -f $(TOP)/Makefile.shared -e \
        +		CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
        +		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
        +		link_app.$${shlib_target}
        +
        +FIPS_BUILD_CMD=shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
        +		shlib_target="$(SHLIB_TARGET)"; \
        +	fi; \
        +	LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
        +	if [ -z "$(SHARED_LIBS)" -a -n "$(FIPSCANLIB)" ] ; then \
        +		FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; export CC FIPSLD_CC; \
        +	fi; \
        +	$(MAKE) -f $(TOP)/Makefile.shared -e \
        +		CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
        +		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
        +		link_app.$${shlib_target}
        +
        +$(RSATEST)$(EXE_EXT): $(RSATEST).o $(DLIBCRYPTO)
        +	@target=$(RSATEST); $(BUILD_CMD)
        +
        +$(BNTEST)$(EXE_EXT): $(BNTEST).o $(DLIBCRYPTO)
        +	@target=$(BNTEST); $(BUILD_CMD)
        +
        +$(ECTEST)$(EXE_EXT): $(ECTEST).o $(DLIBCRYPTO)
        +	@target=$(ECTEST); $(BUILD_CMD)
        +
        +$(EXPTEST)$(EXE_EXT): $(EXPTEST).o $(DLIBCRYPTO)
        +	@target=$(EXPTEST); $(BUILD_CMD)
        +
        +$(IDEATEST)$(EXE_EXT): $(IDEATEST).o $(DLIBCRYPTO)
        +	@target=$(IDEATEST); $(BUILD_CMD)
        +
        +$(MD2TEST)$(EXE_EXT): $(MD2TEST).o $(DLIBCRYPTO)
        +	@target=$(MD2TEST); $(BUILD_CMD)
        +
        +$(SHATEST)$(EXE_EXT): $(SHATEST).o $(DLIBCRYPTO)
        +	@target=$(SHATEST); $(BUILD_CMD)
        +
        +$(SHA1TEST)$(EXE_EXT): $(SHA1TEST).o $(DLIBCRYPTO)
        +	@target=$(SHA1TEST); $(BUILD_CMD)
        +
        +$(SHA256TEST)$(EXE_EXT): $(SHA256TEST).o $(DLIBCRYPTO)
        +	@target=$(SHA256TEST); $(BUILD_CMD)
        +
        +$(SHA512TEST)$(EXE_EXT): $(SHA512TEST).o $(DLIBCRYPTO)
        +	@target=$(SHA512TEST); $(BUILD_CMD)
        +
        +$(RMDTEST)$(EXE_EXT): $(RMDTEST).o $(DLIBCRYPTO)
        +	@target=$(RMDTEST); $(BUILD_CMD)
        +
        +$(MDC2TEST)$(EXE_EXT): $(MDC2TEST).o $(DLIBCRYPTO)
        +	@target=$(MDC2TEST); $(BUILD_CMD)
        +
        +$(MD4TEST)$(EXE_EXT): $(MD4TEST).o $(DLIBCRYPTO)
        +	@target=$(MD4TEST); $(BUILD_CMD)
        +
        +$(MD5TEST)$(EXE_EXT): $(MD5TEST).o $(DLIBCRYPTO)
        +	@target=$(MD5TEST); $(BUILD_CMD)
        +
        +$(HMACTEST)$(EXE_EXT): $(HMACTEST).o $(DLIBCRYPTO)
        +	@target=$(HMACTEST); $(BUILD_CMD)
        +
        +$(WPTEST)$(EXE_EXT): $(WPTEST).o $(DLIBCRYPTO)
        +	@target=$(WPTEST); $(BUILD_CMD)
        +
        +$(RC2TEST)$(EXE_EXT): $(RC2TEST).o $(DLIBCRYPTO)
        +	@target=$(RC2TEST); $(BUILD_CMD)
        +
        +$(BFTEST)$(EXE_EXT): $(BFTEST).o $(DLIBCRYPTO)
        +	@target=$(BFTEST); $(BUILD_CMD)
        +
        +$(CASTTEST)$(EXE_EXT): $(CASTTEST).o $(DLIBCRYPTO)
        +	@target=$(CASTTEST); $(BUILD_CMD)
        +
        +$(RC4TEST)$(EXE_EXT): $(RC4TEST).o $(DLIBCRYPTO)
        +	@target=$(RC4TEST); $(BUILD_CMD)
        +
        +$(RC5TEST)$(EXE_EXT): $(RC5TEST).o $(DLIBCRYPTO)
        +	@target=$(RC5TEST); $(BUILD_CMD)
        +
        +$(DESTEST)$(EXE_EXT): $(DESTEST).o $(DLIBCRYPTO)
        +	@target=$(DESTEST); $(BUILD_CMD)
        +
        +$(RANDTEST)$(EXE_EXT): $(RANDTEST).o $(DLIBCRYPTO)
        +	@target=$(RANDTEST); $(BUILD_CMD)
        +
        +$(DHTEST)$(EXE_EXT): $(DHTEST).o $(DLIBCRYPTO)
        +	@target=$(DHTEST); $(BUILD_CMD)
        +
        +$(DSATEST)$(EXE_EXT): $(DSATEST).o $(DLIBCRYPTO)
        +	@target=$(DSATEST); $(BUILD_CMD)
        +
        +$(METHTEST)$(EXE_EXT): $(METHTEST).o $(DLIBCRYPTO)
        +	@target=$(METHTEST); $(BUILD_CMD)
        +
        +$(SSLTEST)$(EXE_EXT): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO)
        +	@target=$(SSLTEST); $(FIPS_BUILD_CMD)
        +
        +$(ENGINETEST)$(EXE_EXT): $(ENGINETEST).o $(DLIBCRYPTO)
        +	@target=$(ENGINETEST); $(BUILD_CMD)
        +
        +$(EVPTEST)$(EXE_EXT): $(EVPTEST).o $(DLIBCRYPTO)
        +	@target=$(EVPTEST); $(BUILD_CMD)
        +
        +$(ECDSATEST)$(EXE_EXT): $(ECDSATEST).o $(DLIBCRYPTO)
        +	@target=$(ECDSATEST); $(BUILD_CMD)
        +
        +$(ECDHTEST)$(EXE_EXT): $(ECDHTEST).o $(DLIBCRYPTO)
        +	@target=$(ECDHTEST); $(BUILD_CMD)
        +
        +$(IGETEST)$(EXE_EXT): $(IGETEST).o $(DLIBCRYPTO)
        +	@target=$(IGETEST); $(BUILD_CMD)
        +
        +$(JPAKETEST)$(EXE_EXT): $(JPAKETEST).o $(DLIBCRYPTO)
        +	@target=$(JPAKETEST); $(BUILD_CMD)
        +
        +$(ASN1TEST)$(EXE_EXT): $(ASN1TEST).o $(DLIBCRYPTO)
        +	@target=$(ASN1TEST); $(BUILD_CMD)
        +
        +$(SRPTEST)$(EXE_EXT): $(SRPTEST).o $(DLIBCRYPTO)
        +	@target=$(SRPTEST); $(BUILD_CMD)
        +
        +#$(AESTEST).o: $(AESTEST).c
        +#	$(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
        +
        +#$(AESTEST)$(EXE_EXT): $(AESTEST).o $(DLIBCRYPTO)
        +#	if [ "$(SHLIB_TARGET)" = "hpux-shared" -o "$(SHLIB_TARGET)" = "darwin-shared" ] ; then \
        +#	  $(CC) -o $(AESTEST)$(EXE_EXT) $(CFLAGS) $(AESTEST).o $(PEX_LIBS) $(DLIBCRYPTO) $(EX_LIBS) ; \
        +#	else \
        +#	  $(CC) -o $(AESTEST)$(EXE_EXT) $(CFLAGS) $(AESTEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS) ; \
        +#	fi
        +
        +dummytest$(EXE_EXT): dummytest.o $(DLIBCRYPTO)
        +	@target=dummytest; $(BUILD_CMD)
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        +
        +asn1test.o: ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
        +asn1test.o: ../include/openssl/bio.h ../include/openssl/buffer.h
        +asn1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +asn1test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +asn1test.o: ../include/openssl/ecdsa.h ../include/openssl/evp.h
        +asn1test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +asn1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +asn1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +asn1test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +asn1test.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +asn1test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +asn1test.o: ../include/openssl/x509_vfy.h asn1test.c
        +bftest.o: ../e_os.h ../include/openssl/blowfish.h ../include/openssl/e_os2.h
        +bftest.o: ../include/openssl/opensslconf.h bftest.c
        +bntest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +bntest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +bntest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +bntest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
        +bntest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +bntest.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
        +bntest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +bntest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +bntest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +bntest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +bntest.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +bntest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +bntest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +bntest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bntest.c
        +casttest.o: ../e_os.h ../include/openssl/cast.h ../include/openssl/e_os2.h
        +casttest.o: ../include/openssl/opensslconf.h casttest.c
        +destest.o: ../include/openssl/des.h ../include/openssl/des_old.h
        +destest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
        +destest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +destest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +destest.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h destest.c
        +dhtest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
        +dhtest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +dhtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
        +dhtest.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
        +dhtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +dhtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
        +dhtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h dhtest.c
        +dsatest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
        +dsatest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +dsatest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
        +dsatest.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +dsatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +dsatest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
        +dsatest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +dsatest.o: ../include/openssl/symhacks.h dsatest.c
        +ecdhtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ecdhtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
        +ecdhtest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ecdhtest.o: ../include/openssl/ecdh.h ../include/openssl/err.h
        +ecdhtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ecdhtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ecdhtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ecdhtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
        +ecdhtest.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +ecdhtest.o: ../include/openssl/symhacks.h ecdhtest.c
        +ecdsatest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +ecdsatest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ecdsatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +ecdsatest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ecdsatest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ecdsatest.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ecdsatest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ecdsatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ecdsatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ecdsatest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +ecdsatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ecdsatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ecdsatest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +ecdsatest.o: ecdsatest.c
        +ectest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ectest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ectest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +ectest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +ectest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +ectest.o: ../include/openssl/err.h ../include/openssl/evp.h
        +ectest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +ectest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +ectest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +ectest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
        +ectest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +ectest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +ectest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ectest.c
        +enginetest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
        +enginetest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
        +enginetest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +enginetest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +enginetest.o: ../include/openssl/engine.h ../include/openssl/err.h
        +enginetest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
        +enginetest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +enginetest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +enginetest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
        +enginetest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +enginetest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +enginetest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +enginetest.o: enginetest.c
        +evp_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +evp_test.o: ../include/openssl/buffer.h ../include/openssl/conf.h
        +evp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +evp_test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
        +evp_test.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
        +evp_test.o: ../include/openssl/err.h ../include/openssl/evp.h
        +evp_test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
        +evp_test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +evp_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +evp_test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
        +evp_test.o: ../include/openssl/sha.h ../include/openssl/stack.h
        +evp_test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
        +evp_test.o: ../include/openssl/x509_vfy.h evp_test.c
        +exptest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
        +exptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +exptest.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +exptest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +exptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
        +exptest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +exptest.o: ../include/openssl/symhacks.h exptest.c
        +hmactest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +hmactest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +hmactest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +hmactest.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
        +hmactest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +hmactest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +hmactest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +hmactest.o: ../include/openssl/symhacks.h hmactest.c
        +ideatest.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/idea.h
        +ideatest.o: ../include/openssl/opensslconf.h ideatest.c
        +igetest.o: ../include/openssl/aes.h ../include/openssl/e_os2.h
        +igetest.o: ../include/openssl/opensslconf.h ../include/openssl/ossl_typ.h
        +igetest.o: ../include/openssl/rand.h igetest.c
        +jpaketest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
        +jpaketest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
        +jpaketest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +jpaketest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +jpaketest.o: ../include/openssl/symhacks.h jpaketest.c
        +md2test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
        +md2test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
        +md2test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +md2test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +md2test.o: ../include/openssl/symhacks.h md2test.c
        +md4test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +md4test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +md4test.o: ../include/openssl/evp.h ../include/openssl/md4.h
        +md4test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +md4test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +md4test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +md4test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md4test.c
        +md5test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +md5test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +md5test.o: ../include/openssl/evp.h ../include/openssl/md5.h
        +md5test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +md5test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +md5test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +md5test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md5test.c
        +mdc2test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +mdc2test.o: ../include/openssl/crypto.h ../include/openssl/des.h
        +mdc2test.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
        +mdc2test.o: ../include/openssl/evp.h ../include/openssl/mdc2.h
        +mdc2test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +mdc2test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +mdc2test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +mdc2test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +mdc2test.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h mdc2test.c
        +randtest.o: ../e_os.h ../include/openssl/e_os2.h
        +randtest.o: ../include/openssl/opensslconf.h ../include/openssl/ossl_typ.h
        +randtest.o: ../include/openssl/rand.h randtest.c
        +rc2test.o: ../e_os.h ../include/openssl/e_os2.h
        +rc2test.o: ../include/openssl/opensslconf.h ../include/openssl/rc2.h rc2test.c
        +rc4test.o: ../e_os.h ../include/openssl/e_os2.h
        +rc4test.o: ../include/openssl/opensslconf.h ../include/openssl/rc4.h
        +rc4test.o: ../include/openssl/sha.h rc4test.c
        +rc5test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
        +rc5test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
        +rc5test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +rc5test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +rc5test.o: ../include/openssl/symhacks.h rc5test.c
        +rmdtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +rmdtest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +rmdtest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
        +rmdtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +rmdtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +rmdtest.o: ../include/openssl/ripemd.h ../include/openssl/safestack.h
        +rmdtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h rmdtest.c
        +rsa_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +rsa_test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
        +rsa_test.o: ../include/openssl/e_os2.h ../include/openssl/err.h
        +rsa_test.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
        +rsa_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +rsa_test.o: ../include/openssl/rand.h ../include/openssl/rsa.h
        +rsa_test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
        +rsa_test.o: ../include/openssl/symhacks.h rsa_test.c
        +sha1test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +sha1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +sha1test.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
        +sha1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +sha1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +sha1test.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +sha1test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h sha1test.c
        +shatest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +shatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +shatest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
        +shatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
        +shatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
        +shatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
        +shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h shatest.c
        +srptest.o: ../include/openssl/bio.h ../include/openssl/bn.h
        +srptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +srptest.o: ../include/openssl/err.h ../include/openssl/lhash.h
        +srptest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +srptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
        +srptest.o: ../include/openssl/safestack.h ../include/openssl/srp.h
        +srptest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h srptest.c
        +ssltest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
        +ssltest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
        +ssltest.o: ../include/openssl/comp.h ../include/openssl/conf.h
        +ssltest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
        +ssltest.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
        +ssltest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
        +ssltest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
        +ssltest.o: ../include/openssl/engine.h ../include/openssl/err.h
        +ssltest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
        +ssltest.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
        +ssltest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
        +ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +ssltest.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
        +ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
        +ssltest.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
        +ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
        +ssltest.o: ../include/openssl/sha.h ../include/openssl/srp.h
        +ssltest.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
        +ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
        +ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
        +ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
        +ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
        +ssltest.o: ../include/openssl/x509v3.h ssltest.c
        +wp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
        +wp_test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
        +wp_test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
        +wp_test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
        +wp_test.o: ../include/openssl/whrlpool.h wp_test.c
        diff --git a/vendor/openssl/openssl/test/P1ss.cnf b/vendor/openssl/openssl/test/P1ss.cnf
        new file mode 100644
        index 000000000..326cce2ba
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/P1ss.cnf
        @@ -0,0 +1,37 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +RANDFILE		= ./.rnd
        +
        +####################################################################
        +[ req ]
        +default_bits		= 1024
        +default_keyfile 	= keySS.pem
        +distinguished_name	= req_distinguished_name
        +encrypt_rsa_key		= no
        +default_md		= md2
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_value		= AU
        +
        +organizationName                = Organization Name (eg, company)
        +organizationName_value          = Dodgy Brothers
        +
        +0.commonName			= Common Name (eg, YOUR name)
        +0.commonName_value		= Brother 1
        +
        +1.commonName			= Common Name (eg, YOUR name)
        +1.commonName_value		= Brother 2
        +
        +2.commonName			= Common Name (eg, YOUR name)
        +2.commonName_value		= Proxy 1
        +
        +[ v3_proxy ]
        +basicConstraints=CA:FALSE
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer:always
        +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
        diff --git a/vendor/openssl/openssl/test/P2ss.cnf b/vendor/openssl/openssl/test/P2ss.cnf
        new file mode 100644
        index 000000000..8b502321b
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/P2ss.cnf
        @@ -0,0 +1,45 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +RANDFILE		= ./.rnd
        +
        +####################################################################
        +[ req ]
        +default_bits		= 1024
        +default_keyfile 	= keySS.pem
        +distinguished_name	= req_distinguished_name
        +encrypt_rsa_key		= no
        +default_md		= md2
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_value		= AU
        +
        +organizationName                = Organization Name (eg, company)
        +organizationName_value          = Dodgy Brothers
        +
        +0.commonName			= Common Name (eg, YOUR name)
        +0.commonName_value		= Brother 1
        +
        +1.commonName			= Common Name (eg, YOUR name)
        +1.commonName_value		= Brother 2
        +
        +2.commonName			= Common Name (eg, YOUR name)
        +2.commonName_value		= Proxy 1
        +
        +3.commonName			= Common Name (eg, YOUR name)
        +3.commonName_value		= Proxy 2
        +
        +[ v3_proxy ]
        +basicConstraints=CA:FALSE
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer:always
        +proxyCertInfo=critical,@proxy_ext
        +
        +[ proxy_ext ]
        +language=id-ppl-anyLanguage
        +pathlen=0
        +policy=text:BC
        diff --git a/vendor/openssl/openssl/test/Sssdsa.cnf b/vendor/openssl/openssl/test/Sssdsa.cnf
        new file mode 100644
        index 000000000..8e170a28e
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/Sssdsa.cnf
        @@ -0,0 +1,27 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +# hacked by iang to do DSA certs - Server
        +
        +RANDFILE              = ./.rnd
        +
        +####################################################################
        +[ req ]
        +distinguished_name    = req_distinguished_name
        +encrypt_rsa_key               = no
        +
        +[ req_distinguished_name ]
        +countryName                   = Country Name (2 letter code)
        +countryName_default           = ES
        +countryName_value             = ES
        +
        +organizationName                = Organization Name (eg, company)
        +organizationName_value          = Tortilleras S.A.
        +
        +0.commonName                  = Common Name (eg, YOUR name)
        +0.commonName_value            = Torti
        +
        +1.commonName                  = Common Name (eg, YOUR name)
        +1.commonName_value            = Gordita
        +
        diff --git a/vendor/openssl/openssl/test/Sssrsa.cnf b/vendor/openssl/openssl/test/Sssrsa.cnf
        new file mode 100644
        index 000000000..8c79a03fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/Sssrsa.cnf
        @@ -0,0 +1,26 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +# create RSA certs - Server
        +
        +RANDFILE              = ./.rnd
        +
        +####################################################################
        +[ req ]
        +distinguished_name    = req_distinguished_name
        +encrypt_key           = no
        +
        +[ req_distinguished_name ]
        +countryName                   = Country Name (2 letter code)
        +countryName_default           = ES
        +countryName_value             = ES
        +
        +organizationName                = Organization Name (eg, company)
        +organizationName_value          = Tortilleras S.A.
        +
        +0.commonName                  = Common Name (eg, YOUR name)
        +0.commonName_value            = Torti
        +
        +1.commonName                  = Common Name (eg, YOUR name)
        +1.commonName_value            = Gordita
        diff --git a/vendor/openssl/openssl/test/Uss.cnf b/vendor/openssl/openssl/test/Uss.cnf
        new file mode 100644
        index 000000000..58ac0ca54
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/Uss.cnf
        @@ -0,0 +1,36 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +RANDFILE		= ./.rnd
        +
        +####################################################################
        +[ req ]
        +default_bits		= 2048
        +default_keyfile 	= keySS.pem
        +distinguished_name	= req_distinguished_name
        +encrypt_rsa_key		= no
        +default_md		= sha256
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_value		= AU
        +
        +organizationName                = Organization Name (eg, company)
        +organizationName_value          = Dodgy Brothers
        +
        +0.commonName			= Common Name (eg, YOUR name)
        +0.commonName_value		= Brother 1
        +
        +1.commonName			= Common Name (eg, YOUR name)
        +1.commonName_value		= Brother 2
        +
        +[ v3_ee ]
        +subjectKeyIdentifier=hash
        +authorityKeyIdentifier=keyid,issuer:always
        +basicConstraints = CA:false
        +keyUsage = nonRepudiation, digitalSignature, keyEncipherment
        +issuerAltName=issuer:copy
        +
        diff --git a/vendor/openssl/openssl/test/VMSca-response.1 b/vendor/openssl/openssl/test/VMSca-response.1
        new file mode 100644
        index 000000000..8b1378917
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/VMSca-response.1
        @@ -0,0 +1 @@
        +
        diff --git a/vendor/openssl/openssl/test/VMSca-response.2 b/vendor/openssl/openssl/test/VMSca-response.2
        new file mode 100644
        index 000000000..9b48ee4cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/VMSca-response.2
        @@ -0,0 +1,2 @@
        +y
        +y
        diff --git a/vendor/openssl/openssl/test/asn1test.c b/vendor/openssl/openssl/test/asn1test.c
        new file mode 100644
        index 000000000..9f53d8034
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/asn1test.c
        @@ -0,0 +1,22 @@
        +#include <openssl/x509.h>
        +#include <openssl/asn1_mac.h>
        +
        +typedef struct X
        +    {
        +    STACK_OF(X509_EXTENSION) *ext;
        +    } X;
        +
        +/* This isn't meant to run particularly, it's just to test type checking */
        +int main(int argc, char **argv)
        +    {
        +    X *x = NULL;
        +    unsigned char **pp = NULL;
        +
        +    M_ASN1_I2D_vars(x);
        +    M_ASN1_I2D_len_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
        +				     i2d_X509_EXTENSION);
        +    M_ASN1_I2D_seq_total();
        +    M_ASN1_I2D_put_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
        +				     i2d_X509_EXTENSION);
        +    M_ASN1_I2D_finish();
        +    }
        diff --git a/vendor/openssl/openssl/test/bctest b/vendor/openssl/openssl/test/bctest
        new file mode 100644
        index 000000000..bdb3218f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/bctest
        @@ -0,0 +1,111 @@
        +#!/bin/sh
        +
        +# This script is used by test/Makefile.ssl to check whether a sane 'bc'
        +# is installed.
        +# ('make test_bn' should not try to run 'bc' if it does not exist or if
        +# it is a broken 'bc' version that is known to cause trouble.)
        +#
        +# If 'bc' works, we also test if it knows the 'print' command.
        +#
        +# In any case, output an appropriate command line for running (or not
        +# running) bc.
        +
        +
        +IFS=:
        +try_without_dir=true
        +# First we try "bc", then "$dir/bc" for each item in $PATH.
        +for dir in dummy:$PATH; do
        +    if [ "$try_without_dir" = true ]; then
        +      # first iteration
        +      bc=bc
        +      try_without_dir=false
        +    else
        +      # second and later iterations
        +      bc="$dir/bc"
        +      if [ ! -f "$bc" ]; then  # '-x' is not available on Ultrix
        +        bc=''
        +      fi
        +    fi
        +
        +    if [ ! "$bc" = '' ]; then
        +        failure=none
        +
        +
        +        # Test for SunOS 5.[78] bc bug
        +        "$bc" >tmp.bctest <<\EOF
        +obase=16
        +ibase=16
        +a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\
        +CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\
        +10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\
        +C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\
        +3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\
        +4FC3CADF855448B24A9D7640BCF473E
        +b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\
        +9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\
        +8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\
        +3ED0E2017D60A68775B75481449
        +(a/b)*b + (a%b) - a
        +EOF
        +        if [ 0 != "`cat tmp.bctest`" ]; then
        +            failure=SunOStest
        +        fi
        +
        +
        +        if [ "$failure" = none ]; then
        +            # Test for SCO bc bug.
        +            "$bc" >tmp.bctest <<\EOF
        +obase=16
        +ibase=16
        +-FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\
        +9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\
        +11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\
        +1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\
        +AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\
        +F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\
        +B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\
        +02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\
        +85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\
        +A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\
        +E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\
        +8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\
        +04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\
        +89C8D71
        +AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\
        +928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\
        +8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\
        +37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\
        +E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\
        +F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\
        +9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\
        +D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\
        +5296964
        +EOF
        +            if [ "0
        +0" != "`cat tmp.bctest`" ]; then
        +                failure=SCOtest
        +            fi
        +        fi
        +
        +
        +        if [ "$failure" = none ]; then
        +            # bc works; now check if it knows the 'print' command.
        +            if [ "OK" = "`echo 'print \"OK\"' | $bc 2>/dev/null`" ]
        +            then
        +                echo "$bc"
        +            else
        +                echo "sed 's/print.*//' | $bc"
        +            fi
        +            exit 0
        +        fi
        +
        +        echo "$bc does not work properly ('$failure' failed).  Looking for another bc ..." >&2
        +    fi
        +done
        +
        +echo "No working bc found.  Consider installing GNU bc." >&2
        +if [ "$1" = ignore ]; then
        +  echo "cat >/dev/null"
        +  exit 0
        +fi
        +exit 1
        diff --git a/vendor/openssl/openssl/test/bctest.com b/vendor/openssl/openssl/test/bctest.com
        new file mode 100644
        index 000000000..d7e5ec139
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/bctest.com
        @@ -0,0 +1,152 @@
        +$!
        +$! Check operation of "bc".
        +$!
        +$! 2010-04-05 SMS.  New.  Based (loosely) on "bctest".
        +$!
        +$!
        +$ tmp_file_name = "tmp.bctest"
        +$ failure = ""
        +$!
        +$! Basic command test.
        +$!
        +$ on warning then goto bc_fail
        +$ bc
        +$ on error then exit
        +$!
        +$! Test for SunOS 5.[78] bc bug.
        +$!
        +$ if (failure .eqs. "")
        +$ then
        +$!
        +$     define /user_mode sys$output 'tmp_file_name'
        +$     bc
        +obase=16
        +ibase=16
        +a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\
        +CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\
        +10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\
        +C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\
        +3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\
        +4FC3CADF855448B24A9D7640BCF473E
        +b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\
        +9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\
        +8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\
        +3ED0E2017D60A68775B75481449
        +(a/b)*b + (a%b) - a
        +$     status = $status
        +$     output_expected = "0"
        +$     gosub check_output
        +$     if (output .ne. 1)
        +$     then
        +$         failure = "SunOStest"
        +$     else
        +$         delete 'f$parse( tmp_file_name)'
        +$     endif
        +$ endif
        +$!
        +$! Test for SCO bc bug.
        +$!
        +$ if (failure .eqs. "")
        +$ then
        +$!
        +$     define /user_mode sys$output 'tmp_file_name'
        +$     bc
        +obase=16
        +ibase=16
        +-FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\
        +9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\
        +11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\
        +1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\
        +AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\
        +F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\
        +B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\
        +02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\
        +85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\
        +A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\
        +E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\
        +8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\
        +04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\
        +89C8D71
        +AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\
        +928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\
        +8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\
        +37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\
        +E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\
        +F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\
        +9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\
        +D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\
        +5296964
        +$     status = $status
        +$     output_expected = "0\0"
        +$     gosub check_output
        +$     if (output .ne. 1)
        +$     then
        +$         failure = "SCOtest"
        +$     else
        +$         delete 'f$parse( tmp_file_name)'
        +$     endif
        +$ endif
        +$!
        +$! Test for working 'print' command.
        +$!
        +$ if (failure .eqs. "")
        +$ then
        +$!
        +$     define /user_mode sys$output 'tmp_file_name'
        +$     bc
        +print "OK"
        +$     status = $status
        +$     output_expected = "OK"
        +$     gosub check_output
        +$     if (output .ne. 1)
        +$     then
        +$         failure = "printtest"
        +$     else
        +$         delete 'f$parse( tmp_file_name)'
        +$     endif
        +$ endif
        +$!
        +$ if (failure .nes. "")
        +$ then
        +$     write sys$output -
        +       "No working bc found.  Consider installing GNU bc."
        +$     exit %X00030000 ! %DCL-W-NORMAL
        +$ endif
        +$!
        +$ exit
        +$!
        +$!
        +$! Complete "bc" command failure.
        +$!
        +$ bc_fail:
        +$ write sys$output -
        +   "No ""bc"" program/symbol found.  Consider installing GNU bc."
        +$ exit %X00030000 ! %DCL-W-NORMAL
        +$!
        +$!
        +$! Output check subroutine.
        +$!
        +$ check_output:
        +$     eof = 0
        +$     line_nr = 0
        +$     open /read tmp_file 'tmp_file_name'
        +$     c_o_loop:
        +$         read /error = error_read tmp_file line
        +$         goto ok_read
        +$         error_read:
        +$         eof = 1
        +$         ok_read:
        +$         line_expected = f$element( line_nr, "\", output_expected)
        +$         line_nr = line_nr+ 1
        +$     if ((line_expected .nes. "\") .and. (.not. eof) .and. -
        +       (line_expected .eqs. line)) then goto c_o_loop
        +$!
        +$     if ((line_expected .eqs. "\") .and. eof)
        +$     then
        +$         output = 1
        +$     else
        +$         output = 0
        +$     endif
        +$     close tmp_file
        +$ return
        +$!
        diff --git a/vendor/openssl/openssl/test/bftest.c b/vendor/openssl/openssl/test/bftest.c
        new file mode 100644
        index 000000000..97e6634d3
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/bftest.c
        @@ -0,0 +1,540 @@
        +/* crypto/bf/bftest.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.]
        + */
        +
        +/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
        + * RC2 modes, more of the code will be uncommented. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_BF is defined */
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_BF
        +int main(int argc, char *argv[])
        +{
        +    printf("No BF support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/blowfish.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static char *bf_key[2]={
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"Who is John Galt?"
        +	};
        +
        +/* big endian */
        +static BF_LONG bf_plain[2][2]={
        +	{0x424c4f57L,0x46495348L},
        +	{0xfedcba98L,0x76543210L}
        +	};
        +
        +static BF_LONG bf_cipher[2][2]={
        +	{0x324ed0feL,0xf413a203L},
        +	{0xcc91732bL,0x8022f684L}
        +	};
        +/************/
        +
        +/* Lets use the DES test vectors :-) */
        +#define NUM_TESTS 34
        +static unsigned char ecb_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
        +	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
        +	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
        +	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
        +	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
        +	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
        +	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
        +	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
        +	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
        +	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
        +	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
        +	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
        +	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
        +	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
        +	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
        +	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
        +	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
        +	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
        +	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
        +	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
        +	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
        +	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
        +	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
        +
        +static unsigned char plain_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
        +	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
        +	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
        +	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
        +	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
        +	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
        +	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
        +	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
        +	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
        +	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
        +	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
        +	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
        +	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
        +	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
        +	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
        +	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
        +	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
        +	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
        +	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
        +
        +static unsigned char cipher_data[NUM_TESTS][8]={
        +	{0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
        +	{0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A},
        +	{0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2},
        +	{0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D},
        +	{0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96},
        +	{0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7},
        +	{0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78},
        +	{0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D},
        +	{0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B},
        +	{0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0},
        +	{0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4},
        +	{0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB},
        +	{0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A},
        +	{0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18},
        +	{0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98},
        +	{0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5},
        +	{0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79},
        +	{0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3},
        +	{0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69},
        +	{0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B},
        +	{0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E},
        +	{0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD},
        +	{0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19},
        +	{0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3},
        +	{0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5},
        +	{0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78},
        +	{0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01},
        +	{0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2},
        +	{0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE},
        +	{0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D},
        +	{0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4},
        +	{0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC},
        +	{0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A},
        +	{0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A},
        +	};
        +
        +static unsigned char cbc_key [16]={
        +	0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        +	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
        +static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
        +static char cbc_data[40]="7654321 Now is the time for ";
        +static unsigned char cbc_ok[32]={
        +	0x6B,0x77,0xB4,0xD6,0x30,0x06,0xDE,0xE6,
        +	0x05,0xB1,0x56,0xE2,0x74,0x03,0x97,0x93,
        +	0x58,0xDE,0xB9,0xE7,0x15,0x46,0x16,0xD9,
        +	0x59,0xF1,0x65,0x2B,0xD5,0xFF,0x92,0xCC};
        +
        +static unsigned char cfb64_ok[]={
        +	0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
        +	0xF2,0x6E,0xCF,0x6D,0x2E,0xB9,0xE7,0x6E,
        +	0x3D,0xA3,0xDE,0x04,0xD1,0x51,0x72,0x00,
        +	0x51,0x9D,0x57,0xA6,0xC3};
        +
        +static unsigned char ofb64_ok[]={
        +	0xE7,0x32,0x14,0xA2,0x82,0x21,0x39,0xCA,
        +	0x62,0xB3,0x43,0xCC,0x5B,0x65,0x58,0x73,
        +	0x10,0xDD,0x90,0x8D,0x0C,0x24,0x1B,0x22,
        +	0x63,0xC2,0xCF,0x80,0xDA};
        +
        +#define KEY_TEST_NUM	25
        +static unsigned char key_test[KEY_TEST_NUM]={
        +	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87,
        +	0x78,0x69,0x5a,0x4b,0x3c,0x2d,0x1e,0x0f,
        +	0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
        +	0x88};
        +
        +static unsigned char key_data[8]=
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10};
        +
        +static unsigned char key_out[KEY_TEST_NUM][8]={
        +	{0xF9,0xAD,0x59,0x7C,0x49,0xDB,0x00,0x5E},
        +	{0xE9,0x1D,0x21,0xC1,0xD9,0x61,0xA6,0xD6},
        +	{0xE9,0xC2,0xB7,0x0A,0x1B,0xC6,0x5C,0xF3},
        +	{0xBE,0x1E,0x63,0x94,0x08,0x64,0x0F,0x05},
        +	{0xB3,0x9E,0x44,0x48,0x1B,0xDB,0x1E,0x6E},
        +	{0x94,0x57,0xAA,0x83,0xB1,0x92,0x8C,0x0D},
        +	{0x8B,0xB7,0x70,0x32,0xF9,0x60,0x62,0x9D},
        +	{0xE8,0x7A,0x24,0x4E,0x2C,0xC8,0x5E,0x82},
        +	{0x15,0x75,0x0E,0x7A,0x4F,0x4E,0xC5,0x77},
        +	{0x12,0x2B,0xA7,0x0B,0x3A,0xB6,0x4A,0xE0},
        +	{0x3A,0x83,0x3C,0x9A,0xFF,0xC5,0x37,0xF6},
        +	{0x94,0x09,0xDA,0x87,0xA9,0x0F,0x6B,0xF2},
        +	{0x88,0x4F,0x80,0x62,0x50,0x60,0xB8,0xB4},
        +	{0x1F,0x85,0x03,0x1C,0x19,0xE1,0x19,0x68},
        +	{0x79,0xD9,0x37,0x3A,0x71,0x4C,0xA3,0x4F},
        +	{0x93,0x14,0x28,0x87,0xEE,0x3B,0xE1,0x5C},
        +	{0x03,0x42,0x9E,0x83,0x8C,0xE2,0xD1,0x4B},
        +	{0xA4,0x29,0x9E,0x27,0x46,0x9F,0xF6,0x7B},
        +	{0xAF,0xD5,0xAE,0xD1,0xC1,0xBC,0x96,0xA8},
        +	{0x10,0x85,0x1C,0x0E,0x38,0x58,0xDA,0x9F},
        +	{0xE6,0xF5,0x1E,0xD7,0x9B,0x9D,0xB2,0x1F},
        +	{0x64,0xA6,0xE1,0x4A,0xFD,0x36,0xB4,0x6F},
        +	{0x80,0xC7,0xD7,0xD4,0x5A,0x54,0x79,0xAD},
        +	{0x05,0x04,0x4B,0x62,0xFA,0x52,0xD0,0x80},
        +	};
        +
        +static int test(void );
        +static int print_test_data(void );
        +int main(int argc, char *argv[])
        +	{
        +	int ret;
        +
        +	if (argc > 1)
        +		ret=print_test_data();
        +	else
        +		ret=test();
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (ret) printf("ERROR: %d\n", ret);
        +#endif
        +	EXIT(ret);
        +	return(0);
        +	}
        +
        +static int print_test_data(void)
        +	{
        +	unsigned int i,j;
        +
        +	printf("ecb test data\n");
        +	printf("key bytes\t\tclear bytes\t\tcipher bytes\n");
        +	for (i=0; i<NUM_TESTS; i++)
        +		{
        +		for (j=0; j<8; j++)
        +			printf("%02X",ecb_data[i][j]);
        +		printf("\t");
        +		for (j=0; j<8; j++)
        +			printf("%02X",plain_data[i][j]);
        +		printf("\t");
        +		for (j=0; j<8; j++)
        +			printf("%02X",cipher_data[i][j]);
        +		printf("\n");
        +		}
        +
        +	printf("set_key test data\n");
        +	printf("data[8]= ");
        +	for (j=0; j<8; j++)
        +		printf("%02X",key_data[j]);
        +	printf("\n");
        +	for (i=0; i<KEY_TEST_NUM-1; i++)
        +		{
        +		printf("c=");
        +		for (j=0; j<8; j++)
        +			printf("%02X",key_out[i][j]);
        +		printf(" k[%2u]=",i+1);
        +		for (j=0; j<i+1; j++)
        +			printf("%02X",key_test[j]);
        +		printf("\n");
        +		}
        +
        +	printf("\nchaining mode test data\n");
        +	printf("key[16]   = ");
        +	for (j=0; j<16; j++)
        +		printf("%02X",cbc_key[j]);
        +	printf("\niv[8]     = ");
        +	for (j=0; j<8; j++)
        +		printf("%02X",cbc_iv[j]);
        +	printf("\ndata[%d]  = '%s'",(int)strlen(cbc_data)+1,cbc_data);
        +	printf("\ndata[%d]  = ",(int)strlen(cbc_data)+1);
        +	for (j=0; j<strlen(cbc_data)+1; j++)
        +		printf("%02X",cbc_data[j]);
        +	printf("\n");
        +	printf("cbc cipher text\n");
        +	printf("cipher[%d]= ",32);
        +	for (j=0; j<32; j++)
        +		printf("%02X",cbc_ok[j]);
        +	printf("\n");
        +
        +	printf("cfb64 cipher text\n");
        +	printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
        +	for (j=0; j<strlen(cbc_data)+1; j++)
        +		printf("%02X",cfb64_ok[j]);
        +	printf("\n");
        +
        +	printf("ofb64 cipher text\n");
        +	printf("cipher[%d]= ",(int)strlen(cbc_data)+1);
        +	for (j=0; j<strlen(cbc_data)+1; j++)
        +		printf("%02X",ofb64_ok[j]);
        +	printf("\n");
        +	return(0);
        +	}
        +
        +static int test(void)
        +	{
        +	unsigned char cbc_in[40],cbc_out[40],iv[8];
        +	int i,n,err=0;
        +	BF_KEY key;
        +	BF_LONG data[2]; 
        +	unsigned char out[8]; 
        +	BF_LONG len;
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(cbc_data, cbc_data, strlen(cbc_data));
        +#endif
        +
        +	printf("testing blowfish in raw ecb mode\n");
        +	for (n=0; n<2; n++)
        +		{
        +#ifdef CHARSET_EBCDIC
        +		ebcdic2ascii(bf_key[n], bf_key[n], strlen(bf_key[n]));
        +#endif
        +		BF_set_key(&key,strlen(bf_key[n]),(unsigned char *)bf_key[n]);
        +
        +		data[0]=bf_plain[n][0];
        +		data[1]=bf_plain[n][1];
        +		BF_encrypt(data,&key);
        +		if (memcmp(&(bf_cipher[n][0]),&(data[0]),8) != 0)
        +			{
        +			printf("BF_encrypt error encrypting\n");
        +			printf("got     :");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)data[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)bf_cipher[n][i]);
        +			err=1;
        +			printf("\n");
        +			}
        +
        +		BF_decrypt(&(data[0]),&key);
        +		if (memcmp(&(bf_plain[n][0]),&(data[0]),8) != 0)
        +			{
        +			printf("BF_encrypt error decrypting\n");
        +			printf("got     :");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)data[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<2; i++)
        +				printf("%08lX ",(unsigned long)bf_plain[n][i]);
        +			printf("\n");
        +			err=1;
        +			}
        +		}
        +
        +	printf("testing blowfish in ecb mode\n");
        +
        +	for (n=0; n<NUM_TESTS; n++)
        +		{
        +		BF_set_key(&key,8,ecb_data[n]);
        +
        +		BF_ecb_encrypt(&(plain_data[n][0]),out,&key,BF_ENCRYPT);
        +		if (memcmp(&(cipher_data[n][0]),out,8) != 0)
        +			{
        +			printf("BF_ecb_encrypt blowfish error encrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",out[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",cipher_data[n][i]);
        +			err=1;
        +			printf("\n");
        +			}
        +
        +		BF_ecb_encrypt(out,out,&key,BF_DECRYPT);
        +		if (memcmp(&(plain_data[n][0]),out,8) != 0)
        +			{
        +			printf("BF_ecb_encrypt error decrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",out[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",plain_data[n][i]);
        +			printf("\n");
        +			err=1;
        +			}
        +		}
        +
        +	printf("testing blowfish set_key\n");
        +	for (n=1; n<KEY_TEST_NUM; n++)
        +		{
        +		BF_set_key(&key,n,key_test);
        +		BF_ecb_encrypt(key_data,out,&key,BF_ENCRYPT);
        +		/* mips-sgi-irix6.5-gcc  vv  -mabi=64 bug workaround */
        +		if (memcmp(out,&(key_out[i=n-1][0]),8) != 0)
        +			{
        +			printf("blowfish setkey error\n");
        +			err=1;
        +			}
        +		}
        +
        +	printf("testing blowfish in cbc mode\n");
        +	len=strlen(cbc_data)+1;
        +
        +	BF_set_key(&key,16,cbc_key);
        +	memset(cbc_in,0,sizeof cbc_in);
        +	memset(cbc_out,0,sizeof cbc_out);
        +	memcpy(iv,cbc_iv,sizeof iv);
        +	BF_cbc_encrypt((unsigned char *)cbc_data,cbc_out,len,
        +		&key,iv,BF_ENCRYPT);
        +	if (memcmp(cbc_out,cbc_ok,32) != 0)
        +		{
        +		err=1;
        +		printf("BF_cbc_encrypt encrypt error\n");
        +		for (i=0; i<32; i++) printf("0x%02X,",cbc_out[i]);
        +		}
        +	memcpy(iv,cbc_iv,8);
        +	BF_cbc_encrypt(cbc_out,cbc_in,len,
        +		&key,iv,BF_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
        +		{
        +		printf("BF_cbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("testing blowfish in cfb64 mode\n");
        +
        +	BF_set_key(&key,16,cbc_key);
        +	memset(cbc_in,0,40);
        +	memset(cbc_out,0,40);
        +	memcpy(iv,cbc_iv,8);
        +	n=0;
        +	BF_cfb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,
        +		&key,iv,&n,BF_ENCRYPT);
        +	BF_cfb64_encrypt((unsigned char *)&(cbc_data[13]),&(cbc_out[13]),len-13,
        +		&key,iv,&n,BF_ENCRYPT);
        +	if (memcmp(cbc_out,cfb64_ok,(int)len) != 0)
        +		{
        +		err=1;
        +		printf("BF_cfb64_encrypt encrypt error\n");
        +		for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
        +		}
        +	n=0;
        +	memcpy(iv,cbc_iv,8);
        +	BF_cfb64_encrypt(cbc_out,cbc_in,17,
        +		&key,iv,&n,BF_DECRYPT);
        +	BF_cfb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,
        +		&key,iv,&n,BF_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,(int)len) != 0)
        +		{
        +		printf("BF_cfb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("testing blowfish in ofb64\n");
        +
        +	BF_set_key(&key,16,cbc_key);
        +	memset(cbc_in,0,40);
        +	memset(cbc_out,0,40);
        +	memcpy(iv,cbc_iv,8);
        +	n=0;
        +	BF_ofb64_encrypt((unsigned char *)cbc_data,cbc_out,(long)13,&key,iv,&n);
        +	BF_ofb64_encrypt((unsigned char *)&(cbc_data[13]),
        +		&(cbc_out[13]),len-13,&key,iv,&n);
        +	if (memcmp(cbc_out,ofb64_ok,(int)len) != 0)
        +		{
        +		err=1;
        +		printf("BF_ofb64_encrypt encrypt error\n");
        +		for (i=0; i<(int)len; i++) printf("0x%02X,",cbc_out[i]);
        +		}
        +	n=0;
        +	memcpy(iv,cbc_iv,8);
        +	BF_ofb64_encrypt(cbc_out,cbc_in,17,&key,iv,&n);
        +	BF_ofb64_encrypt(&(cbc_out[17]),&(cbc_in[17]),len-17,&key,iv,&n);
        +	if (memcmp(cbc_in,cbc_data,(int)len) != 0)
        +		{
        +		printf("BF_ofb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	return(err);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/bntest.c b/vendor/openssl/openssl/test/bntest.c
        new file mode 100644
        index 000000000..06f5954ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/bntest.c
        @@ -0,0 +1,2013 @@
        +/* crypto/bn/bntest.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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the Eric Young open source
        + * license provided above.
        + *
        + * The binary polynomial arithmetic software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/x509.h>
        +#include <openssl/err.h>
        +
        +const int num0 = 100; /* number of tests */
        +const int num1 = 50;  /* additional tests for some functions */
        +const int num2 = 5;   /* number of tests for slow functions */
        +
        +int test_add(BIO *bp);
        +int test_sub(BIO *bp);
        +int test_lshift1(BIO *bp);
        +int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
        +int test_rshift1(BIO *bp);
        +int test_rshift(BIO *bp,BN_CTX *ctx);
        +int test_div(BIO *bp,BN_CTX *ctx);
        +int test_div_word(BIO *bp);
        +int test_div_recp(BIO *bp,BN_CTX *ctx);
        +int test_mul(BIO *bp);
        +int test_sqr(BIO *bp,BN_CTX *ctx);
        +int test_mont(BIO *bp,BN_CTX *ctx);
        +int test_mod(BIO *bp,BN_CTX *ctx);
        +int test_mod_mul(BIO *bp,BN_CTX *ctx);
        +int test_mod_exp(BIO *bp,BN_CTX *ctx);
        +int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
        +int test_exp(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_add(BIO *bp);
        +int test_gf2m_mod(BIO *bp);
        +int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
        +int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
        +int test_kron(BIO *bp,BN_CTX *ctx);
        +int test_sqrt(BIO *bp,BN_CTX *ctx);
        +int rand_neg(void);
        +static int results=0;
        +
        +static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
        +"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +static void message(BIO *out, char *m)
        +	{
        +	fprintf(stderr, "test %s\n", m);
        +	BIO_puts(out, "print \"test ");
        +	BIO_puts(out, m);
        +	BIO_puts(out, "\\n\"\n");
        +	}
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_CTX *ctx;
        +	BIO *out;
        +	char *outfile=NULL;
        +
        +	results = 0;
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
        +
        +	argc--;
        +	argv++;
        +	while (argc >= 1)
        +		{
        +		if (strcmp(*argv,"-results") == 0)
        +			results=1;
        +		else if (strcmp(*argv,"-out") == 0)
        +			{
        +			if (--argc < 1) break;
        +			outfile= *(++argv);
        +			}
        +		argc--;
        +		argv++;
        +		}
        +
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) EXIT(1);
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) EXIT(1);
        +	if (outfile == NULL)
        +		{
        +		BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +		}
        +	else
        +		{
        +		if (!BIO_write_filename(out,outfile))
        +			{
        +			perror(outfile);
        +			EXIT(1);
        +			}
        +		}
        +
        +	if (!results)
        +		BIO_puts(out,"obase=16\nibase=16\n");
        +
        +	message(out,"BN_add");
        +	if (!test_add(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_sub");
        +	if (!test_sub(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_lshift1");
        +	if (!test_lshift1(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_lshift (fixed)");
        +	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
        +	    goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_lshift");
        +	if (!test_lshift(out,ctx,NULL)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_rshift1");
        +	if (!test_rshift1(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_rshift");
        +	if (!test_rshift(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_sqr");
        +	if (!test_sqr(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mul");
        +	if (!test_mul(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_div");
        +	if (!test_div(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_div_word");
        +	if (!test_div_word(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_div_recp");
        +	if (!test_div_recp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod");
        +	if (!test_mod(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_mul");
        +	if (!test_mod_mul(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mont");
        +	if (!test_mont(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_exp");
        +	if (!test_mod_exp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_exp_mont_consttime");
        +	if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_exp");
        +	if (!test_exp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_kronecker");
        +	if (!test_kron(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_mod_sqrt");
        +	if (!test_sqrt(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +#ifndef OPENSSL_NO_EC2M
        +	message(out,"BN_GF2m_add");
        +	if (!test_gf2m_add(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod");
        +	if (!test_gf2m_mod(out)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_mul");
        +	if (!test_gf2m_mod_mul(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_sqr");
        +	if (!test_gf2m_mod_sqr(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_inv");
        +	if (!test_gf2m_mod_inv(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_div");
        +	if (!test_gf2m_mod_div(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_exp");
        +	if (!test_gf2m_mod_exp(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_sqrt");
        +	if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +
        +	message(out,"BN_GF2m_mod_solve_quad");
        +	if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
        +	(void)BIO_flush(out);
        +#endif
        +	BN_CTX_free(ctx);
        +	BIO_free(out);
        +
        +/**/
        +	EXIT(0);
        +err:
        +	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
        +	                      * the failure, see test_bn in test/Makefile.ssl*/
        +	(void)BIO_flush(out);
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	EXIT(1);
        +	return(1);
        +	}
        +
        +int test_add(BIO *bp)
        +	{
        +	BIGNUM a,b,c;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	BN_bntest_rand(&a,512,0,0);
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(&b,450+i,0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_add(&c,&a,&b);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," + ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		a.neg=!a.neg;
        +		b.neg=!b.neg;
        +		BN_add(&c,&c,&b);
        +		BN_add(&c,&c,&a);
        +		if(!BN_is_zero(&c))
        +		    {
        +		    fprintf(stderr,"Add test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	return(1);
        +	}
        +
        +int test_sub(BIO *bp)
        +	{
        +	BIGNUM a,b,c;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i < num1)
        +			{
        +			BN_bntest_rand(&a,512,0,0);
        +			BN_copy(&b,&a);
        +			if (BN_set_bit(&a,i)==0) return(0);
        +			BN_add_word(&b,i);
        +			}
        +		else
        +			{
        +			BN_bntest_rand(&b,400+i-num1,0,0);
        +			a.neg=rand_neg();
        +			b.neg=rand_neg();
        +			}
        +		BN_sub(&c,&a,&b);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," - ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_add(&c,&c,&b);
        +		BN_sub(&c,&c,&a);
        +		if(!BN_is_zero(&c))
        +		    {
        +		    fprintf(stderr,"Subtract test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	return(1);
        +	}
        +
        +int test_div(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,b,c,d,e;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i < num1)
        +			{
        +			BN_bntest_rand(&a,400,0,0);
        +			BN_copy(&b,&a);
        +			BN_lshift(&a,&a,i);
        +			BN_add_word(&a,i);
        +			}
        +		else
        +			BN_bntest_rand(&b,50+3*(i-num1),0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_div(&d,&c,&a,&b,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," / ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&d);
        +			BIO_puts(bp,"\n");
        +
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(&e,&d,&b,ctx);
        +		BN_add(&d,&e,&c);
        +		BN_sub(&d,&d,&a);
        +		if(!BN_is_zero(&d))
        +		    {
        +		    fprintf(stderr,"Division test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	return(1);
        +	}
        +
        +static void print_word(BIO *bp,BN_ULONG w)
        +	{
        +#ifdef SIXTY_FOUR_BIT
        +	if (sizeof(w) > sizeof(unsigned long))
        +		{
        +		unsigned long	h=(unsigned long)(w>>32),
        +				l=(unsigned long)(w);
        +
        +		if (h)	BIO_printf(bp,"%lX%08lX",h,l);
        +		else	BIO_printf(bp,"%lX",l);
        +		return;
        +		}
        +#endif
        +	BIO_printf(bp,BN_HEX_FMT1,w);
        +	}
        +
        +int test_div_word(BIO *bp)
        +	{
        +	BIGNUM   a,b;
        +	BN_ULONG r,s;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		do {
        +			BN_bntest_rand(&a,512,-1,0);
        +			BN_bntest_rand(&b,BN_BITS2,-1,0);
        +			s = b.d[0];
        +		} while (!s);
        +
        +		BN_copy(&b, &a);
        +		r = BN_div_word(&b, s);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," / ");
        +				print_word(bp,s);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&b);
        +			BIO_puts(bp,"\n");
        +
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," % ");
        +				print_word(bp,s);
        +				BIO_puts(bp," - ");
        +				}
        +			print_word(bp,r);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul_word(&b,s);
        +		BN_add_word(&b,r);
        +		BN_sub(&b,&a,&b);
        +		if(!BN_is_zero(&b))
        +		    {
        +		    fprintf(stderr,"Division (word) test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	return(1);
        +	}
        +
        +int test_div_recp(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,b,c,d,e;
        +	BN_RECP_CTX recp;
        +	int i;
        +
        +	BN_RECP_CTX_init(&recp);
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i < num1)
        +			{
        +			BN_bntest_rand(&a,400,0,0);
        +			BN_copy(&b,&a);
        +			BN_lshift(&a,&a,i);
        +			BN_add_word(&a,i);
        +			}
        +		else
        +			BN_bntest_rand(&b,50+3*(i-num1),0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_RECP_CTX_set(&recp,&b,ctx);
        +		BN_div_recp(&d,&c,&a,&recp,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," / ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&d);
        +			BIO_puts(bp,"\n");
        +
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(&e,&d,&b,ctx);
        +		BN_add(&d,&e,&c);
        +		BN_sub(&d,&d,&a);
        +		if(!BN_is_zero(&d))
        +		    {
        +		    fprintf(stderr,"Reciprocal division test failed!\n");
        +		    fprintf(stderr,"a=");
        +		    BN_print_fp(stderr,&a);
        +		    fprintf(stderr,"\nb=");
        +		    BN_print_fp(stderr,&b);
        +		    fprintf(stderr,"\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	BN_RECP_CTX_free(&recp);
        +	return(1);
        +	}
        +
        +int test_mul(BIO *bp)
        +	{
        +	BIGNUM a,b,c,d,e;
        +	int i;
        +	BN_CTX *ctx;
        +
        +	ctx = BN_CTX_new();
        +	if (ctx == NULL) EXIT(1);
        +	
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0+num1; i++)
        +		{
        +		if (i <= num1)
        +			{
        +			BN_bntest_rand(&a,100,0,0);
        +			BN_bntest_rand(&b,100,0,0);
        +			}
        +		else
        +			BN_bntest_rand(&b,i-num1,0,0);
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_mul(&c,&a,&b,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(&d,&e,&c,&a,ctx);
        +		BN_sub(&d,&d,&b);
        +		if(!BN_is_zero(&d) || !BN_is_zero(&e))
        +		    {
        +		    fprintf(stderr,"Multiplication test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	BN_CTX_free(ctx);
        +	return(1);
        +	}
        +
        +int test_sqr(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,c,d,e;
        +	int i;
        +
        +	BN_init(&a);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&e);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(&a,40+i*10,0,0);
        +		a.neg=rand_neg();
        +		BN_sqr(&c,&a,ctx);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,&a);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(&d,&e,&c,&a,ctx);
        +		BN_sub(&d,&d,&a);
        +		if(!BN_is_zero(&d) || !BN_is_zero(&e))
        +		    {
        +		    fprintf(stderr,"Square test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(&a);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&e);
        +	return(1);
        +	}
        +
        +int test_mont(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM a,b,c,d,A,B;
        +	BIGNUM n;
        +	int i;
        +	BN_MONT_CTX *mont;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +	BN_init(&d);
        +	BN_init(&A);
        +	BN_init(&B);
        +	BN_init(&n);
        +
        +	mont=BN_MONT_CTX_new();
        +	if (mont == NULL)
        +		return 0;
        +
        +	BN_bntest_rand(&a,100,0,0); /**/
        +	BN_bntest_rand(&b,100,0,0); /**/
        +	for (i=0; i<num2; i++)
        +		{
        +		int bits = (200*(i+1))/num2;
        +
        +		if (bits == 0)
        +			continue;
        +		BN_bntest_rand(&n,bits,0,1);
        +		BN_MONT_CTX_set(mont,&n,ctx);
        +
        +		BN_nnmod(&a,&a,&n,ctx);
        +		BN_nnmod(&b,&b,&n,ctx);
        +
        +		BN_to_montgomery(&A,&a,mont,ctx);
        +		BN_to_montgomery(&B,&b,mont,ctx);
        +
        +		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
        +		BN_from_montgomery(&A,&c,mont,ctx);/**/
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +#ifdef undef
        +fprintf(stderr,"%d * %d %% %d\n",
        +BN_num_bits(&a),
        +BN_num_bits(&b),
        +BN_num_bits(mont->N));
        +#endif
        +				BN_print(bp,&a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,&(mont->N));
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,&A);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mod_mul(&d,&a,&b,&n,ctx);
        +		BN_sub(&d,&d,&A);
        +		if(!BN_is_zero(&d))
        +		    {
        +		    fprintf(stderr,"Montgomery multiplication test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_MONT_CTX_free(mont);
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	BN_free(&d);
        +	BN_free(&A);
        +	BN_free(&B);
        +	BN_free(&n);
        +	return(1);
        +	}
        +
        +int test_mod(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_bntest_rand(a,1024,0,0); /**/
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(b,450+i*10,0,0); /**/
        +		a->neg=rand_neg();
        +		b->neg=rand_neg();
        +		BN_mod(c,a,b,ctx);/**/
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,c);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(d,e,a,b,ctx);
        +		BN_sub(e,e,c);
        +		if(!BN_is_zero(e))
        +		    {
        +		    fprintf(stderr,"Modulo test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_mod_mul(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i,j;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	for (j=0; j<3; j++) {
        +	BN_bntest_rand(c,1024,0,0); /**/
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a,475+i*10,0,0); /**/
        +		BN_bntest_rand(b,425+i*11,0,0); /**/
        +		a->neg=rand_neg();
        +		b->neg=rand_neg();
        +		if (!BN_mod_mul(e,a,b,c,ctx))
        +			{
        +			unsigned long l;
        +
        +			while ((l=ERR_get_error()))
        +				fprintf(stderr,"ERROR:%s\n",
        +					ERR_error_string(l,NULL));
        +			EXIT(1);
        +			}
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,c);
        +				if ((a->neg ^ b->neg) && !BN_is_zero(e))
        +					{
        +					/* If  (a*b) % c  is negative,  c  must be added
        +					 * in order to obtain the normalized remainder
        +					 * (new with OpenSSL 0.9.7, previous versions of
        +					 * BN_mod_mul could generate negative results)
        +					 */
        +					BIO_puts(bp," + ");
        +					BN_print(bp,c);
        +					}
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,e);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(d,a,b,ctx);
        +		BN_sub(d,d,e);
        +		BN_div(a,b,d,c,ctx);
        +		if(!BN_is_zero(b))
        +		    {
        +		    fprintf(stderr,"Modulo multiply test failed!\n");
        +		    ERR_print_errors_fp(stderr);
        +		    return 0;
        +		    }
        +		}
        +	}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_mod_exp(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
        +	for (i=0; i<num2; i++)
        +		{
        +		BN_bntest_rand(a,20+i*5,0,0); /**/
        +		BN_bntest_rand(b,2+i,0,0); /**/
        +
        +		if (!BN_mod_exp(d,a,b,c,ctx))
        +			return(0);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,d);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_exp(e,a,b,ctx);
        +		BN_sub(e,e,d);
        +		BN_div(a,b,e,c,ctx);
        +		if(!BN_is_zero(b))
        +		    {
        +		    fprintf(stderr,"Modulo exponentiation test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
        +	for (i=0; i<num2; i++)
        +		{
        +		BN_bntest_rand(a,20+i*5,0,0); /**/
        +		BN_bntest_rand(b,2+i,0,0); /**/
        +
        +		if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
        +			return(00);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," % ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,d);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_exp(e,a,b,ctx);
        +		BN_sub(e,e,d);
        +		BN_div(a,b,e,c,ctx);
        +		if(!BN_is_zero(b))
        +		    {
        +		    fprintf(stderr,"Modulo exponentiation test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_exp(BIO *bp, BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*d,*e,*one;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	one=BN_new();
        +	BN_one(one);
        +
        +	for (i=0; i<num2; i++)
        +		{
        +		BN_bntest_rand(a,20+i*5,0,0); /**/
        +		BN_bntest_rand(b,2+i,0,0); /**/
        +
        +		if (BN_exp(d,a,b,ctx) <= 0)
        +			return(0);
        +
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,b);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,d);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_one(e);
        +		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
        +		    BN_mul(e,e,a,ctx);
        +		BN_sub(e,e,d);
        +		if(!BN_is_zero(e))
        +		    {
        +		    fprintf(stderr,"Exponentiation test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(one);
        +	return(1);
        +	}
        +#ifndef OPENSSL_NO_EC2M
        +int test_gf2m_add(BIO *bp)
        +	{
        +	BIGNUM a,b,c;
        +	int i, ret = 0;
        +
        +	BN_init(&a);
        +	BN_init(&b);
        +	BN_init(&c);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_rand(&a,512,0,0);
        +		BN_copy(&b, BN_value_one());
        +		a.neg=rand_neg();
        +		b.neg=rand_neg();
        +		BN_GF2m_add(&c,&a,&b);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,&a);
        +				BIO_puts(bp," ^ ");
        +				BN_print(bp,&b);
        +				BIO_puts(bp," = ");
        +				}
        +			BN_print(bp,&c);
        +			BIO_puts(bp,"\n");
        +			}
        +#endif
        +		/* Test that two added values have the correct parity. */
        +		if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
        +			{
        +		    fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
        +			goto err;
        +			}
        +		BN_GF2m_add(&c,&c,&c);
        +		/* Test that c + c = 0. */
        +		if(!BN_is_zero(&c))
        +		    {
        +		    fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
        +			goto err;
        +		    }
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(&a);
        +	BN_free(&b);
        +	BN_free(&c);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod(BIO *bp)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 1024, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod(c, a, b[j]);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp," % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp," - ");
        +					BN_print(bp,c);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(d, a, c);
        +			BN_GF2m_mod(e, d, b[j]);
        +			/* Test that a + (a mod p) mod p == 0. */
        +			if(!BN_is_zero(e))
        +				{
        +				fprintf(stderr,"GF(2^m) modulo test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +	g=BN_new();
        +	h=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 1024, 0, 0);
        +		BN_bntest_rand(c, 1024, 0, 0);
        +		BN_bntest_rand(d, 1024, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_mul(e, a, c, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp," * ");
        +					BN_print(bp,c);
        +					BIO_puts(bp," % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp," - ");
        +					BN_print(bp,e);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(f, a, d);
        +			BN_GF2m_mod_mul(g, f, c, b[j], ctx);
        +			BN_GF2m_mod_mul(h, d, c, b[j], ctx);
        +			BN_GF2m_add(f, e, g);
        +			BN_GF2m_add(f, f, h);
        +			/* Test that (a+d)*c = a*c + d*c. */
        +			if(!BN_is_zero(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	BN_free(g);
        +	BN_free(h);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 1024, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_sqr(c, a, b[j], ctx);
        +			BN_copy(d, a);
        +			BN_GF2m_mod_mul(d, a, d, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp," ^ 2 % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp, " = ");
        +					BN_print(bp,c);
        +					BIO_puts(bp,"; a * a = ");
        +					BN_print(bp,d);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(d, c, d);
        +			/* Test that a*a = a^2. */
        +			if(!BN_is_zero(d))
        +				{
        +				fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0); 
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_inv(c, a, b[j], ctx);
        +			BN_GF2m_mod_mul(d, a, c, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp, " * ");
        +					BN_print(bp,c);
        +					BIO_puts(bp," - 1 % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			/* Test that ((1/a)*a) = 1. */
        +			if(!BN_is_one(d))
        +				{
        +				fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0); 
        +		BN_bntest_rand(c, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_div(d, a, c, b[j], ctx);
        +			BN_GF2m_mod_mul(e, d, c, b[j], ctx);
        +			BN_GF2m_mod_div(f, a, e, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp, " = ");
        +					BN_print(bp,c);
        +					BIO_puts(bp," * ");
        +					BN_print(bp,d);
        +					BIO_puts(bp, " % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			/* Test that ((a/c)*c)/a = 1. */
        +			if(!BN_is_one(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular division test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0);
        +		BN_bntest_rand(c, 512, 0, 0);
        +		BN_bntest_rand(d, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod_exp(e, a, c, b[j], ctx);
        +			BN_GF2m_mod_exp(f, a, d, b[j], ctx);
        +			BN_GF2m_mod_mul(e, e, f, b[j], ctx);
        +			BN_add(f, c, d);
        +			BN_GF2m_mod_exp(f, a, f, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,a);
        +					BIO_puts(bp, " ^ (");
        +					BN_print(bp,c);
        +					BIO_puts(bp," + ");
        +					BN_print(bp,d);
        +					BIO_puts(bp, ") = ");
        +					BN_print(bp,e);
        +					BIO_puts(bp, "; - ");
        +					BN_print(bp,f);
        +					BIO_puts(bp, " % ");
        +					BN_print(bp,b[j]);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(f, e, f);
        +			/* Test that a^(c+d)=a^c*a^d. */
        +			if(!BN_is_zero(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e,*f;
        +	int i, j, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	f=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			BN_GF2m_mod(c, a, b[j]);
        +			BN_GF2m_mod_sqrt(d, a, b[j], ctx);
        +			BN_GF2m_mod_sqr(e, d, b[j], ctx);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +			if (bp != NULL)
        +				{
        +				if (!results)
        +					{
        +					BN_print(bp,d);
        +					BIO_puts(bp, " ^ 2 - ");
        +					BN_print(bp,a);
        +					BIO_puts(bp,"\n");
        +					}
        +				}
        +#endif
        +			BN_GF2m_add(f, c, e);
        +			/* Test that d^2 = a, where d = sqrt(a). */
        +			if(!BN_is_zero(f))
        +				{
        +				fprintf(stderr,"GF(2^m) modular square root test failed!\n");
        +				goto err;
        +				}
        +			}
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	BN_free(f);
        +	return ret;
        +	}
        +
        +int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b[2],*c,*d,*e;
        +	int i, j, s = 0, t, ret = 0;
        +	int p0[] = {163,7,6,3,0,-1};
        +	int p1[] = {193,15,0,-1};
        +
        +	a=BN_new();
        +	b[0]=BN_new();
        +	b[1]=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +
        +	BN_GF2m_arr2poly(p0, b[0]);
        +	BN_GF2m_arr2poly(p1, b[1]);
        +
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_bntest_rand(a, 512, 0, 0);
        +		for (j=0; j < 2; j++)
        +			{
        +			t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
        +			if (t)
        +				{
        +				s++;
        +				BN_GF2m_mod_sqr(d, c, b[j], ctx);
        +				BN_GF2m_add(d, c, d);
        +				BN_GF2m_mod(e, a, b[j]);
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +				if (bp != NULL)
        +					{
        +					if (!results)
        +						{
        +						BN_print(bp,c);
        +						BIO_puts(bp, " is root of z^2 + z = ");
        +						BN_print(bp,a);
        +						BIO_puts(bp, " % ");
        +						BN_print(bp,b[j]);
        +						BIO_puts(bp, "\n");
        +						}
        +					}
        +#endif
        +				BN_GF2m_add(e, e, d);
        +				/* Test that solution of quadratic c satisfies c^2 + c = a. */
        +				if(!BN_is_zero(e))
        +					{
        +					fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
        +					goto err;
        +					}
        +
        +				}
        +			else 
        +				{
        +#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
        +				if (bp != NULL)
        +					{
        +					if (!results)
        +						{
        +						BIO_puts(bp, "There are no roots of z^2 + z = ");
        +						BN_print(bp,a);
        +						BIO_puts(bp, " % ");
        +						BN_print(bp,b[j]);
        +						BIO_puts(bp, "\n");
        +						}
        +					}
        +#endif
        +				}
        +			}
        +		}
        +	if (s == 0)
        +		{	
        +		fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
        +		fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
        +		goto err;
        +		}
        +	ret = 1;
        +  err:
        +	BN_free(a);
        +	BN_free(b[0]);
        +	BN_free(b[1]);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return ret;
        +	}
        +#endif
        +static int genprime_cb(int p, int n, BN_GENCB *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	putc(c, stderr);
        +	fflush(stderr);
        +	return 1;
        +	}
        +
        +int test_kron(BIO *bp, BN_CTX *ctx)
        +	{
        +	BN_GENCB cb;
        +	BIGNUM *a,*b,*r,*t;
        +	int i;
        +	int legendre, kronecker;
        +	int ret = 0;
        +
        +	a = BN_new();
        +	b = BN_new();
        +	r = BN_new();
        +	t = BN_new();
        +	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
        +
        +	BN_GENCB_set(&cb, genprime_cb, NULL);
        +	
        +	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
        +	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
        +	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
        +	 * So we generate a random prime  b  and compare these values
        +	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
        +	 * primality test to confirm that  b  is prime, except that we
        +	 * don't want to test whether  b  is prime but whether BN_kronecker
        +	 * works.) */
        +
        +	if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
        +	b->neg = rand_neg();
        +	putc('\n', stderr);
        +
        +	for (i = 0; i < num0; i++)
        +		{
        +		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
        +		a->neg = rand_neg();
        +
        +		/* t := (|b|-1)/2  (note that b is odd) */
        +		if (!BN_copy(t, b)) goto err;
        +		t->neg = 0;
        +		if (!BN_sub_word(t, 1)) goto err;
        +		if (!BN_rshift1(t, t)) goto err;
        +		/* r := a^t mod b */
        +		b->neg=0;
        +		
        +		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
        +		b->neg=1;
        +
        +		if (BN_is_word(r, 1))
        +			legendre = 1;
        +		else if (BN_is_zero(r))
        +			legendre = 0;
        +		else
        +			{
        +			if (!BN_add_word(r, 1)) goto err;
        +			if (0 != BN_ucmp(r, b))
        +				{
        +				fprintf(stderr, "Legendre symbol computation failed\n");
        +				goto err;
        +				}
        +			legendre = -1;
        +			}
        +		
        +		kronecker = BN_kronecker(a, b, ctx);
        +		if (kronecker < -1) goto err;
        +		/* we actually need BN_kronecker(a, |b|) */
        +		if (a->neg && b->neg)
        +			kronecker = -kronecker;
        +		
        +		if (legendre != kronecker)
        +			{
        +			fprintf(stderr, "legendre != kronecker; a = ");
        +			BN_print_fp(stderr, a);
        +			fprintf(stderr, ", b = ");
        +			BN_print_fp(stderr, b);
        +			fprintf(stderr, "\n");
        +			goto err;
        +			}
        +
        +		putc('.', stderr);
        +		fflush(stderr);
        +		}
        +
        +	putc('\n', stderr);
        +	fflush(stderr);
        +	ret = 1;
        + err:
        +	if (a != NULL) BN_free(a);
        +	if (b != NULL) BN_free(b);
        +	if (r != NULL) BN_free(r);
        +	if (t != NULL) BN_free(t);
        +	return ret;
        +	}
        +
        +int test_sqrt(BIO *bp, BN_CTX *ctx)
        +	{
        +	BN_GENCB cb;
        +	BIGNUM *a,*p,*r;
        +	int i, j;
        +	int ret = 0;
        +
        +	a = BN_new();
        +	p = BN_new();
        +	r = BN_new();
        +	if (a == NULL || p == NULL || r == NULL) goto err;
        +
        +	BN_GENCB_set(&cb, genprime_cb, NULL);
        +
        +	for (i = 0; i < 16; i++)
        +		{
        +		if (i < 8)
        +			{
        +			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
        +			
        +			if (!BN_set_word(p, primes[i])) goto err;
        +			}
        +		else
        +			{
        +			if (!BN_set_word(a, 32)) goto err;
        +			if (!BN_set_word(r, 2*i + 1)) goto err;
        +		
        +			if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
        +			putc('\n', stderr);
        +			}
        +		p->neg = rand_neg();
        +
        +		for (j = 0; j < num2; j++)
        +			{
        +			/* construct 'a' such that it is a square modulo p,
        +			 * but in general not a proper square and not reduced modulo p */
        +			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
        +			if (!BN_nnmod(r, r, p, ctx)) goto err;
        +			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
        +			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
        +			if (!BN_nnmod(a, a, p, ctx)) goto err;
        +			if (!BN_mod_sqr(a, a, p, ctx)) goto err;
        +			if (!BN_mul(a, a, r, ctx)) goto err;
        +			if (rand_neg())
        +				if (!BN_sub(a, a, p)) goto err;
        +
        +			if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
        +			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
        +
        +			if (!BN_nnmod(a, a, p, ctx)) goto err;
        +
        +			if (BN_cmp(a, r) != 0)
        +				{
        +				fprintf(stderr, "BN_mod_sqrt failed: a = ");
        +				BN_print_fp(stderr, a);
        +				fprintf(stderr, ", r = ");
        +				BN_print_fp(stderr, r);
        +				fprintf(stderr, ", p = ");
        +				BN_print_fp(stderr, p);
        +				fprintf(stderr, "\n");
        +				goto err;
        +				}
        +
        +			putc('.', stderr);
        +			fflush(stderr);
        +			}
        +		
        +		putc('\n', stderr);
        +		fflush(stderr);
        +		}
        +	ret = 1;
        + err:
        +	if (a != NULL) BN_free(a);
        +	if (p != NULL) BN_free(p);
        +	if (r != NULL) BN_free(r);
        +	return ret;
        +	}
        +
        +int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
        +	{
        +	BIGNUM *a,*b,*c,*d;
        +	int i;
        +
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	BN_one(c);
        +
        +	if(a_)
        +	    a=a_;
        +	else
        +	    {
        +	    a=BN_new();
        +	    BN_bntest_rand(a,200,0,0); /**/
        +	    a->neg=rand_neg();
        +	    }
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_lshift(b,a,i+1);
        +		BN_add(c,c,c);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," * ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_mul(d,a,c,ctx);
        +		BN_sub(d,d,b);
        +		if(!BN_is_zero(d))
        +		    {
        +		    fprintf(stderr,"Left shift test failed!\n");
        +		    fprintf(stderr,"a=");
        +		    BN_print_fp(stderr,a);
        +		    fprintf(stderr,"\nb=");
        +		    BN_print_fp(stderr,b);
        +		    fprintf(stderr,"\nc=");
        +		    BN_print_fp(stderr,c);
        +		    fprintf(stderr,"\nd=");
        +		    BN_print_fp(stderr,d);
        +		    fprintf(stderr,"\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	return(1);
        +	}
        +
        +int test_lshift1(BIO *bp)
        +	{
        +	BIGNUM *a,*b,*c;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +
        +	BN_bntest_rand(a,200,0,0); /**/
        +	a->neg=rand_neg();
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_lshift1(b,a);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," * 2");
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_add(c,a,a);
        +		BN_sub(a,b,c);
        +		if(!BN_is_zero(a))
        +		    {
        +		    fprintf(stderr,"Left shift one test failed!\n");
        +		    return 0;
        +		    }
        +		
        +		BN_copy(a,b);
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	return(1);
        +	}
        +
        +int test_rshift(BIO *bp,BN_CTX *ctx)
        +	{
        +	BIGNUM *a,*b,*c,*d,*e;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +	d=BN_new();
        +	e=BN_new();
        +	BN_one(c);
        +
        +	BN_bntest_rand(a,200,0,0); /**/
        +	a->neg=rand_neg();
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_rshift(b,a,i+1);
        +		BN_add(c,c,c);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," / ");
        +				BN_print(bp,c);
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_div(d,e,a,c,ctx);
        +		BN_sub(d,d,b);
        +		if(!BN_is_zero(d))
        +		    {
        +		    fprintf(stderr,"Right shift test failed!\n");
        +		    return 0;
        +		    }
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	BN_free(d);
        +	BN_free(e);
        +	return(1);
        +	}
        +
        +int test_rshift1(BIO *bp)
        +	{
        +	BIGNUM *a,*b,*c;
        +	int i;
        +
        +	a=BN_new();
        +	b=BN_new();
        +	c=BN_new();
        +
        +	BN_bntest_rand(a,200,0,0); /**/
        +	a->neg=rand_neg();
        +	for (i=0; i<num0; i++)
        +		{
        +		BN_rshift1(b,a);
        +		if (bp != NULL)
        +			{
        +			if (!results)
        +				{
        +				BN_print(bp,a);
        +				BIO_puts(bp," / 2");
        +				BIO_puts(bp," - ");
        +				}
        +			BN_print(bp,b);
        +			BIO_puts(bp,"\n");
        +			}
        +		BN_sub(c,a,b);
        +		BN_sub(c,c,b);
        +		if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
        +		    {
        +		    fprintf(stderr,"Right shift one test failed!\n");
        +		    return 0;
        +		    }
        +		BN_copy(a,b);
        +		}
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(c);
        +	return(1);
        +	}
        +
        +int rand_neg(void)
        +	{
        +	static unsigned int neg=0;
        +	static int sign[8]={0,0,0,1,1,0,1,1};
        +
        +	return(sign[(neg++)%8]);
        +	}
        diff --git a/vendor/openssl/openssl/test/bntest.com b/vendor/openssl/openssl/test/bntest.com
        new file mode 100644
        index 000000000..6545d2e5a
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/bntest.com
        @@ -0,0 +1,76 @@
        +$!
        +$! Analyze bntest output file.
        +$!
        +$! Exit status = 1 (success) if all tests passed,
        +$!               0 (warning) if any test failed.
        +$!
        +$! 2011-02-20 SMS.  Added code to skip "#" comments in the input file.
        +$!
        +$! 2010-04-05 SMS.  New.  Based (loosely) on perl code in bntest-vms.sh.
        +$!
        +$!                  Expect data like:
        +$!                        test test_name1
        +$!                        0
        +$!                        [...]
        +$!                        test test_name2
        +$!                        0
        +$!                        [...]
        +$!                        [...]
        +$!
        +$!                  Some tests have no following "0" lines.
        +$!
        +$ result_file_name = f$edit( p1, "TRIM")
        +$ if (result_file_name .eqs. "")
        +$ then
        +$     result_file_name = "bntest-vms.out"
        +$ endif
        +$!
        +$ fail = 0
        +$ passed = 0
        +$ tests = 0
        +$!
        +$ on control_c then goto tidy
        +$ on error then goto tidy
        +$!
        +$ open /read result_file 'result_file_name'
        +$!
        +$ read_loop:
        +$     read /end = read_loop_end /error = tidy result_file line
        +$     t1 = f$element( 0, " ", line)
        +$!
        +$!    Skip "#" comment lines.
        +$     if (f$extract( 0, 1, f$edit( line, "TRIM")) .eqs. "#") then -
        +       goto read_loop
        +$!
        +$     if (t1 .eqs. "test")
        +$     then
        +$         passed = passed+ 1
        +$         tests = tests+ 1
        +$         fail = 1
        +$         t2 = f$extract( 5, 1000, line)
        +$         write sys$output "verify ''t2'"
        +$     else
        +$         if (t1 .nes. "0")
        +$         then
        +$             write sys$output "Failed! bc: ''line'"
        +$             passed = passed- fail
        +$             fail = 0
        +$         endif
        +$     endif
        +$ goto read_loop
        +$ read_loop_end:
        +$ write sys$output "''passed'/''tests' tests passed"
        +$!
        +$ tidy:
        +$ if f$trnlnm( "result_file", "LNM$PROCESS_TABLE", , "SUPERVISOR", , "CONFINE")
        +$ then
        +$     close result_file
        +$ endif
        +$!
        +$ if ((tests .gt. 0) .and. (tests .eq. passed))
        +$ then
        +$    exit 1
        +$ else
        +$    exit 0
        +$ endif
        +$!
        diff --git a/vendor/openssl/openssl/test/casttest.c b/vendor/openssl/openssl/test/casttest.c
        new file mode 100644
        index 000000000..0d020d697
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/casttest.c
        @@ -0,0 +1,233 @@
        +/* crypto/cast/casttest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_CAST is defined */
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_CAST
        +int main(int argc, char *argv[])
        +{
        +    printf("No CAST support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/cast.h>
        +
        +#define FULL_TEST
        +
        +static unsigned char k[16]={
        +	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
        +	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A
        +	};
        +
        +static unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
        +
        +static int k_len[3]={16,10,5};
        +static unsigned char c[3][8]={
        +	{0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2},
        +	{0xEB,0x6A,0x71,0x1A,0x2C,0x02,0x27,0x1B},
        +	{0x7A,0xC8,0x16,0xD1,0x6E,0x9B,0x30,0x2E},
        +	};
        +static unsigned char out[80];
        +
        +static unsigned char in_a[16]={
        +	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
        +	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
        +static unsigned char in_b[16]={
        +	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
        +	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
        +
        +static unsigned char c_a[16]={
        +	0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
        +	0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92};
        +static unsigned char c_b[16]={
        +	0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
        +	0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E};
        +
        +#if 0
        +char *text="Hello to all people out there";
        +
        +static unsigned char cfb_key[16]={
        +	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
        +	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
        +	};
        +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +#define CFB_TEST_SIZE 24
        +static unsigned char plain[CFB_TEST_SIZE]=
        +        {
        +        0x4e,0x6f,0x77,0x20,0x69,0x73,
        +        0x20,0x74,0x68,0x65,0x20,0x74,
        +        0x69,0x6d,0x65,0x20,0x66,0x6f,
        +        0x72,0x20,0x61,0x6c,0x6c,0x20
        +        };
        +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
        +	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
        +	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
        +	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
        +
        +/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
        +	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
        +	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
        +	}; 
        +#endif
        +
        +int main(int argc, char *argv[])
        +    {
        +#ifdef FULL_TEST
        +    long l;
        +    CAST_KEY key_b;
        +#endif
        +    int i,z,err=0;
        +    CAST_KEY key;
        +
        +    for (z=0; z<3; z++)
        +	{
        +	CAST_set_key(&key,k_len[z],k);
        +
        +	CAST_ecb_encrypt(in,out,&key,CAST_ENCRYPT);
        +	if (memcmp(out,&(c[z][0]),8) != 0)
        +	    {
        +	    printf("ecb cast error encrypting for keysize %d\n",k_len[z]*8);
        +	    printf("got     :");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",out[i]);
        +	    printf("\n");
        +	    printf("expected:");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",c[z][i]);
        +	    err=20;
        +	    printf("\n");
        +	    }
        +
        +	CAST_ecb_encrypt(out,out,&key,CAST_DECRYPT);
        +	if (memcmp(out,in,8) != 0)
        +	    {
        +	    printf("ecb cast error decrypting for keysize %d\n",k_len[z]*8);
        +	    printf("got     :");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",out[i]);
        +	    printf("\n");
        +	    printf("expected:");
        +	    for (i=0; i<8; i++)
        +		printf("%02X ",in[i]);
        +	    printf("\n");
        +	    err=3;
        +	    }
        +	}
        +    if (err == 0)
        +	printf("ecb cast5 ok\n");
        +
        +#ifdef FULL_TEST
        +      {
        +      unsigned char out_a[16],out_b[16];
        +      static char *hex="0123456789ABCDEF";
        +      
        +      printf("This test will take some time....");
        +      fflush(stdout);
        +      memcpy(out_a,in_a,sizeof(in_a));
        +      memcpy(out_b,in_b,sizeof(in_b));
        +      i=1;
        +
        +      for (l=0; l<1000000L; l++)
        +	  {
        +	  CAST_set_key(&key_b,16,out_b);
        +	  CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT);
        +	  CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT);
        +	  CAST_set_key(&key,16,out_a);
        +	  CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT);
        +	  CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT);
        +	  if ((l & 0xffff) == 0xffff)
        +	      {
        +	      printf("%c",hex[i&0x0f]);
        +	      fflush(stdout);
        +	      i++;
        +	      }
        +	  }
        +
        +      if (	(memcmp(out_a,c_a,sizeof(c_a)) != 0) ||
        +		(memcmp(out_b,c_b,sizeof(c_b)) != 0))
        +	  {
        +	  printf("\n");
        +	  printf("Error\n");
        +
        +	  printf("A out =");
        +	  for (i=0; i<16; i++) printf("%02X ",out_a[i]);
        +	  printf("\nactual=");
        +	  for (i=0; i<16; i++) printf("%02X ",c_a[i]);
        +	  printf("\n");
        +
        +	  printf("B out =");
        +	  for (i=0; i<16; i++) printf("%02X ",out_b[i]);
        +	  printf("\nactual=");
        +	  for (i=0; i<16; i++) printf("%02X ",c_b[i]);
        +	  printf("\n");
        +	  }
        +      else
        +	  printf(" ok\n");
        +      }
        +#endif
        +
        +    EXIT(err);
        +    return(err);
        +    }
        +#endif
        diff --git a/vendor/openssl/openssl/test/clean_test.com b/vendor/openssl/openssl/test/clean_test.com
        new file mode 100644
        index 000000000..7df633fbe
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/clean_test.com
        @@ -0,0 +1,35 @@
        +$!
        +$! Delete various test results files.
        +$!
        +$ def_orig = f$environment( "default")
        +$ proc = f$environment( "procedure")
        +$ proc_dev_dir = f$parse( "A.;", proc) - "A.;"
        +$!
        +$ on control_c then goto tidy
        +$ on error then goto tidy
        +$!
        +$ set default 'proc_dev_dir'
        +$!
        +$ files := *.cms;*, *.srl;*, *.ss;*, -
        +   cms.err;*, cms.out;*, newreq.pem;*, -
        +   p.txt-zlib-cipher;*, -
        +   smtst.txt;*, testkey.pem;*, testreq.pem;*, -
        +   test_*.err;*, test_*.out;*, -
        +   .rnd;*
        +$!
        +$ delim = ","
        +$ i = 0
        +$ loop:
        +$    file = f$edit( f$element( i, delim, files), "trim")
        +$    if (file .eqs. delim) then goto loop_end
        +$    if (f$search( file) .nes. "") then -
        +      delete 'p1' 'file'
        +$    i = i+ 1
        +$ goto loop
        +$ loop_end:
        +$!
        +$ tidy:
        +$ 
        +$ if (f$type( def_orig) .nes. "") then -
        +   set default 'def_orig'
        +$!
        diff --git a/vendor/openssl/openssl/test/cms-examples.pl b/vendor/openssl/openssl/test/cms-examples.pl
        new file mode 100644
        index 000000000..2e95b48ba
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/cms-examples.pl
        @@ -0,0 +1,409 @@
        +# test/cms-examples.pl
        +# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        +# project.
        +#
        +# ====================================================================
        +# Copyright (c) 2008 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.
        +# ====================================================================
        +
        +# Perl script to run tests against S/MIME examples in RFC4134
        +# Assumes RFC is in current directory and called "rfc4134.txt"
        +
        +use MIME::Base64;
        +
        +my $badttest = 0;
        +my $verbose  = 1;
        +
        +my $cmscmd;
        +my $exdir  = "./";
        +my $exfile = "./rfc4134.txt";
        +
        +if (-f "../apps/openssl")
        +	{
        +	$cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
        +	}
        +elsif (-f "..\\out32dll\\openssl.exe")
        +	{
        +	$cmscmd = "..\\out32dll\\openssl.exe cms";
        +	}
        +elsif (-f "..\\out32\\openssl.exe")
        +	{
        +	$cmscmd = "..\\out32\\openssl.exe cms";
        +	}
        +
        +my @test_list = (
        +    [ "3.1.bin"  => "dataout" ],
        +    [ "3.2.bin"  => "encode, dataout" ],
        +    [ "4.1.bin"  => "encode, verifyder, cont, dss" ],
        +    [ "4.2.bin"  => "encode, verifyder, cont, rsa" ],
        +    [ "4.3.bin"  => "encode, verifyder, cont_extern, dss" ],
        +    [ "4.4.bin"  => "encode, verifyder, cont, dss" ],
        +    [ "4.5.bin"  => "verifyder, cont, rsa" ],
        +    [ "4.6.bin"  => "encode, verifyder, cont, dss" ],
        +    [ "4.7.bin"  => "encode, verifyder, cont, dss" ],
        +    [ "4.8.eml"  => "verifymime, dss" ],
        +    [ "4.9.eml"  => "verifymime, dss" ],
        +    [ "4.10.bin" => "encode, verifyder, cont, dss" ],
        +    [ "4.11.bin" => "encode, certsout" ],
        +    [ "5.1.bin"  => "encode, envelopeder, cont" ],
        +    [ "5.2.bin"  => "encode, envelopeder, cont" ],
        +    [ "5.3.eml"  => "envelopemime, cont" ],
        +    [ "6.0.bin"  => "encode, digest, cont" ],
        +    [ "7.1.bin"  => "encode, encrypted, cont" ],
        +    [ "7.2.bin"  => "encode, encrypted, cont" ]
        +);
        +
        +# Extract examples from RFC4134 text.
        +# Base64 decode all examples, certificates and
        +# private keys are converted to PEM format.
        +
        +my ( $filename, $data );
        +
        +my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
        +
        +$data = "";
        +
        +open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
        +
        +while (<IN>) {
        +    next unless (/^\|/);
        +    s/^\|//;
        +    next if (/^\*/);
        +    if (/^>(.*)$/) {
        +        $filename = $1;
        +        next;
        +    }
        +    if (/^</) {
        +        $filename = "$exdir/$filename";
        +        if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
        +            $data = decode_base64($data);
        +            open OUT, ">$filename";
        +            binmode OUT;
        +            print OUT $data;
        +            close OUT;
        +            push @cleanup, $filename;
        +        }
        +        elsif ( $filename =~ /\.cer$/ ) {
        +            write_pem( $filename, "CERTIFICATE", $data );
        +        }
        +        elsif ( $filename =~ /\.pri$/ ) {
        +            write_pem( $filename, "PRIVATE KEY", $data );
        +        }
        +        $data     = "";
        +        $filename = "";
        +    }
        +    else {
        +        $data .= $_;
        +    }
        +
        +}
        +
        +my $secretkey =
        +  "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
        +
        +foreach (@test_list) {
        +    my ( $file, $tlist ) = @$_;
        +    print "Example file $file:\n";
        +    if ( $tlist =~ /encode/ ) {
        +        run_reencode_test( $exdir, $file );
        +    }
        +    if ( $tlist =~ /certsout/ ) {
        +        run_certsout_test( $exdir, $file );
        +    }
        +    if ( $tlist =~ /dataout/ ) {
        +        run_dataout_test( $exdir, $file );
        +    }
        +    if ( $tlist =~ /verify/ ) {
        +        run_verify_test( $exdir, $tlist, $file );
        +    }
        +    if ( $tlist =~ /digest/ ) {
        +        run_digest_test( $exdir, $tlist, $file );
        +    }
        +    if ( $tlist =~ /encrypted/ ) {
        +        run_encrypted_test( $exdir, $tlist, $file, $secretkey );
        +    }
        +    if ( $tlist =~ /envelope/ ) {
        +        run_envelope_test( $exdir, $tlist, $file );
        +    }
        +
        +}
        +
        +foreach (@cleanup) {
        +    unlink $_;
        +}
        +
        +if ($badtest) {
        +    print "\n$badtest TESTS FAILED!!\n";
        +}
        +else {
        +    print "\n***All tests successful***\n";
        +}
        +
        +sub write_pem {
        +    my ( $filename, $str, $data ) = @_;
        +
        +    $filename =~ s/\.[^.]*$/.pem/;
        +
        +    push @cleanup, $filename;
        +
        +    open OUT, ">$filename";
        +
        +    print OUT "-----BEGIN $str-----\n";
        +    print OUT $data;
        +    print OUT "-----END $str-----\n";
        +
        +    close OUT;
        +}
        +
        +sub run_reencode_test {
        +    my ( $cmsdir, $tfile ) = @_;
        +    unlink "tmp.der";
        +
        +    system( "$cmscmd -cmsout -inform DER -outform DER"
        +          . " -in $cmsdir/$tfile -out tmp.der" );
        +
        +    if ($?) {
        +        print "\tReencode command FAILED!!\n";
        +        $badtest++;
        +    }
        +    elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
        +        print "\tReencode FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tReencode passed\n" if $verbose;
        +    }
        +}
        +
        +sub run_certsout_test {
        +    my ( $cmsdir, $tfile ) = @_;
        +    unlink "tmp.der";
        +    unlink "tmp.pem";
        +
        +    system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
        +          . " -in $cmsdir/$tfile -out tmp.der" );
        +
        +    if ($?) {
        +        print "\tCertificate output command FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tCertificate output passed\n" if $verbose;
        +    }
        +}
        +
        +sub run_dataout_test {
        +    my ( $cmsdir, $tfile ) = @_;
        +    unlink "tmp.txt";
        +
        +    system(
        +        "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
        +
        +    if ($?) {
        +        print "\tDataout command FAILED!!\n";
        +        $badtest++;
        +    }
        +    elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
        +        print "\tDataout compare FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tDataout passed\n" if $verbose;
        +    }
        +}
        +
        +sub run_verify_test {
        +    my ( $cmsdir, $tlist, $tfile ) = @_;
        +    unlink "tmp.txt";
        +
        +    $form   = "DER"                     if $tlist =~ /verifyder/;
        +    $form   = "SMIME"                   if $tlist =~ /verifymime/;
        +    $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
        +    $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
        +
        +    $cmd =
        +        "$cmscmd -verify -inform $form"
        +      . " -CAfile $cafile"
        +      . " -in $cmsdir/$tfile -out tmp.txt";
        +
        +    $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
        +
        +    system("$cmd 2>cms.err 1>cms.out");
        +
        +    if ($?) {
        +        print "\tVerify command FAILED!!\n";
        +        $badtest++;
        +    }
        +    elsif ( $tlist =~ /cont/
        +        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
        +    {
        +        print "\tVerify content compare FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tVerify passed\n" if $verbose;
        +    }
        +}
        +
        +sub run_envelope_test {
        +    my ( $cmsdir, $tlist, $tfile ) = @_;
        +    unlink "tmp.txt";
        +
        +    $form = "DER"   if $tlist =~ /envelopeder/;
        +    $form = "SMIME" if $tlist =~ /envelopemime/;
        +
        +    $cmd =
        +        "$cmscmd -decrypt -inform $form"
        +      . " -recip $cmsdir/BobRSASignByCarl.pem"
        +      . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
        +      . " -in $cmsdir/$tfile -out tmp.txt";
        +
        +    system("$cmd 2>cms.err 1>cms.out");
        +
        +    if ($?) {
        +        print "\tDecrypt command FAILED!!\n";
        +        $badtest++;
        +    }
        +    elsif ( $tlist =~ /cont/
        +        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
        +    {
        +        print "\tDecrypt content compare FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tDecrypt passed\n" if $verbose;
        +    }
        +}
        +
        +sub run_digest_test {
        +    my ( $cmsdir, $tlist, $tfile ) = @_;
        +    unlink "tmp.txt";
        +
        +    my $cmd =
        +      "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
        +
        +    system("$cmd 2>cms.err 1>cms.out");
        +
        +    if ($?) {
        +        print "\tDigest verify command FAILED!!\n";
        +        $badtest++;
        +    }
        +    elsif ( $tlist =~ /cont/
        +        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
        +    {
        +        print "\tDigest verify content compare FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tDigest verify passed\n" if $verbose;
        +    }
        +}
        +
        +sub run_encrypted_test {
        +    my ( $cmsdir, $tlist, $tfile, $key ) = @_;
        +    unlink "tmp.txt";
        +
        +    system( "$cmscmd -EncryptedData_decrypt -inform DER"
        +          . " -secretkey $key"
        +          . " -in $cmsdir/$tfile -out tmp.txt" );
        +
        +    if ($?) {
        +        print "\tEncrypted Data command FAILED!!\n";
        +        $badtest++;
        +    }
        +    elsif ( $tlist =~ /cont/
        +        && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
        +    {
        +        print "\tEncrypted Data content compare FAILED!!\n";
        +        $badtest++;
        +    }
        +    else {
        +        print "\tEncryptedData verify passed\n" if $verbose;
        +    }
        +}
        +
        +sub cmp_files {
        +    my ( $f1, $f2 ) = @_;
        +    my ( $fp1, $fp2 );
        +
        +    my ( $rd1, $rd2 );
        +
        +    if ( !open( $fp1, "<$f1" ) ) {
        +        print STDERR "Can't Open file $f1\n";
        +        return 0;
        +    }
        +
        +    if ( !open( $fp2, "<$f2" ) ) {
        +        print STDERR "Can't Open file $f2\n";
        +        return 0;
        +    }
        +
        +    binmode $fp1;
        +    binmode $fp2;
        +
        +    my $ret = 0;
        +
        +    for ( ; ; ) {
        +        $n1 = sysread $fp1, $rd1, 4096;
        +        $n2 = sysread $fp2, $rd2, 4096;
        +        last if ( $n1 != $n2 );
        +        last if ( $rd1 ne $rd2 );
        +
        +        if ( $n1 == 0 ) {
        +            $ret = 1;
        +            last;
        +        }
        +
        +    }
        +
        +    close $fp1;
        +    close $fp2;
        +
        +    return $ret;
        +
        +}
        +
        diff --git a/vendor/openssl/openssl/test/cms-test.pl b/vendor/openssl/openssl/test/cms-test.pl
        new file mode 100644
        index 000000000..c938bcf00
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/cms-test.pl
        @@ -0,0 +1,457 @@
        +# test/cms-test.pl
        +# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        +# project.
        +#
        +# ====================================================================
        +# Copyright (c) 2008 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.
        +# ====================================================================
        +
        +# CMS, PKCS7 consistency test script. Run extensive tests on
        +# OpenSSL PKCS#7 and CMS implementations.
        +
        +my $ossl_path;
        +my $redir = " 2> cms.err > cms.out";
        +# Make VMS work
        +if ( $^O eq "VMS" && -f "OSSLX:openssl.exe" ) {
        +    $ossl_path = "pipe mcr OSSLX:openssl";
        +}
        +# Make MSYS work
        +elsif ( $^O eq "MSWin32" && -f "../apps/openssl.exe" ) {
        +    $ossl_path = "cmd /c ..\\apps\\openssl";
        +}
        +elsif ( -f "../apps/openssl$ENV{EXE_EXT}" ) {
        +    $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
        +}
        +elsif ( -f "..\\out32dll\\openssl.exe" ) {
        +    $ossl_path = "..\\out32dll\\openssl.exe";
        +}
        +elsif ( -f "..\\out32\\openssl.exe" ) {
        +    $ossl_path = "..\\out32\\openssl.exe";
        +}
        +else {
        +    die "Can't find OpenSSL executable";
        +}
        +
        +my $pk7cmd   = "$ossl_path smime ";
        +my $cmscmd   = "$ossl_path cms ";
        +my $smdir    = "smime-certs";
        +my $halt_err = 1;
        +
        +my $badcmd = 0;
        +my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/;
        +
        +my @smime_pkcs7_tests = (
        +
        +    [
        +        "signed content DER format, RSA key",
        +        "-sign -in smcont.txt -outform \"DER\" -nodetach"
        +          . " -certfile $smdir/smroot.pem"
        +          . " -signer $smdir/smrsa1.pem -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed detached content DER format, RSA key",
        +        "-sign -in smcont.txt -outform \"DER\""
        +          . " -signer $smdir/smrsa1.pem -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
        +    ],
        +
        +    [
        +        "signed content test streaming BER format, RSA",
        +        "-sign -in smcont.txt -outform \"DER\" -nodetach"
        +          . " -stream -signer $smdir/smrsa1.pem -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed content DER format, DSA key",
        +        "-sign -in smcont.txt -outform \"DER\" -nodetach"
        +          . " -signer $smdir/smdsa1.pem -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed detached content DER format, DSA key",
        +        "-sign -in smcont.txt -outform \"DER\""
        +          . " -signer $smdir/smdsa1.pem -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
        +    ],
        +
        +    [
        +        "signed detached content DER format, add RSA signer",
        +        "-resign -inform \"DER\" -in test.cms -outform \"DER\""
        +          . " -signer $smdir/smrsa1.pem -out test2.cms",
        +        "-verify -in test2.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt -content smcont.txt"
        +    ],
        +
        +    [
        +        "signed content test streaming BER format, DSA key",
        +        "-sign -in smcont.txt -outform \"DER\" -nodetach"
        +          . " -stream -signer $smdir/smdsa1.pem -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed content test streaming BER format, 2 DSA and 2 RSA keys",
        +        "-sign -in smcont.txt -outform \"DER\" -nodetach"
        +          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
        +          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
        +          . " -stream -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +"signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
        +        "-sign -in smcont.txt -outform \"DER\" -noattr -nodetach"
        +          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
        +          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
        +          . " -stream -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
        +        "-sign -in smcont.txt -nodetach"
        +          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
        +          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
        +          . " -stream -out test.cms",
        +        "-verify -in test.cms " . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +"signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
        +        "-sign -in smcont.txt"
        +          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
        +          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
        +          . " -stream -out test.cms",
        +        "-verify -in test.cms " . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "enveloped content test streaming S/MIME format, 3 recipients",
        +        "-encrypt -in smcont.txt"
        +          . " -stream -out test.cms"
        +          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
        +        "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
        +    ],
        +
        +    [
        +"enveloped content test streaming S/MIME format, 3 recipients, 3rd used",
        +        "-encrypt -in smcont.txt"
        +          . " -stream -out test.cms"
        +          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
        +        "-decrypt -recip $smdir/smrsa3.pem -in test.cms -out smtst.txt"
        +    ],
        +
        +    [
        +"enveloped content test streaming S/MIME format, 3 recipients, key only used",
        +        "-encrypt -in smcont.txt"
        +          . " -stream -out test.cms"
        +          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
        +        "-decrypt -inkey $smdir/smrsa3.pem -in test.cms -out smtst.txt"
        +    ],
        +
        +    [
        +"enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
        +        "-encrypt -in smcont.txt"
        +          . " -aes256 -stream -out test.cms"
        +          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
        +        "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
        +    ],
        +
        +);
        +
        +my @smime_cms_tests = (
        +
        +    [
        +        "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
        +        "-sign -in smcont.txt -outform \"DER\" -nodetach -keyid"
        +          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
        +          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
        +          . " -stream -out test.cms",
        +        "-verify -in test.cms -inform \"DER\" "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
        +        "-sign -in smcont.txt -outform PEM -nodetach"
        +          . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
        +          . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
        +          . " -stream -out test.cms",
        +        "-verify -in test.cms -inform PEM "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed content MIME format, RSA key, signed receipt request",
        +        "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
        +          . " -receipt_request_to test\@openssl.org -receipt_request_all"
        +          . " -out test.cms",
        +        "-verify -in test.cms "
        +          . " \"-CAfile\" $smdir/smroot.pem -out smtst.txt"
        +    ],
        +
        +    [
        +        "signed receipt MIME format, RSA key",
        +        "-sign_receipt -in test.cms"
        +          . " -signer $smdir/smrsa2.pem"
        +          . " -out test2.cms",
        +        "-verify_receipt test2.cms -in test.cms"
        +          . " \"-CAfile\" $smdir/smroot.pem"
        +    ],
        +
        +    [
        +        "enveloped content test streaming S/MIME format, 3 recipients, keyid",
        +        "-encrypt -in smcont.txt"
        +          . " -stream -out test.cms -keyid"
        +          . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
        +        "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
        +    ],
        +
        +    [
        +        "enveloped content test streaming PEM format, KEK",
        +        "-encrypt -in smcont.txt -outform PEM -aes128"
        +          . " -stream -out test.cms "
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F "
        +          . " -secretkeyid C0FEE0",
        +        "-decrypt -in test.cms -out smtst.txt -inform PEM"
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F "
        +          . " -secretkeyid C0FEE0"
        +    ],
        +
        +    [
        +        "enveloped content test streaming PEM format, KEK, key only",
        +        "-encrypt -in smcont.txt -outform PEM -aes128"
        +          . " -stream -out test.cms "
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F "
        +          . " -secretkeyid C0FEE0",
        +        "-decrypt -in test.cms -out smtst.txt -inform PEM"
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F "
        +    ],
        +
        +    [
        +        "data content test streaming PEM format",
        +        "-data_create -in smcont.txt -outform PEM -nodetach"
        +          . " -stream -out test.cms",
        +        "-data_out -in test.cms -inform PEM -out smtst.txt"
        +    ],
        +
        +    [
        +        "encrypted content test streaming PEM format, 128 bit RC2 key",
        +        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
        +          . " -rc2 -secretkey 000102030405060708090A0B0C0D0E0F"
        +          . " -stream -out test.cms",
        +        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
        +    ],
        +
        +    [
        +        "encrypted content test streaming PEM format, 40 bit RC2 key",
        +        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
        +          . " -rc2 -secretkey 0001020304"
        +          . " -stream -out test.cms",
        +        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
        +          . " -secretkey 0001020304 -out smtst.txt"
        +    ],
        +
        +    [
        +        "encrypted content test streaming PEM format, triple DES key",
        +        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
        +          . " -des3 -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
        +          . " -stream -out test.cms",
        +        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
        +          . " -out smtst.txt"
        +    ],
        +
        +    [
        +        "encrypted content test streaming PEM format, 128 bit AES key",
        +        "\"-EncryptedData_encrypt\" -in smcont.txt -outform PEM"
        +          . " -aes128 -secretkey 000102030405060708090A0B0C0D0E0F"
        +          . " -stream -out test.cms",
        +        "\"-EncryptedData_decrypt\" -in test.cms -inform PEM "
        +          . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
        +    ],
        +
        +);
        +
        +my @smime_cms_comp_tests = (
        +
        +    [
        +        "compressed content test streaming PEM format",
        +        "-compress -in smcont.txt -outform PEM -nodetach"
        +          . " -stream -out test.cms",
        +        "-uncompress -in test.cms -inform PEM -out smtst.txt"
        +    ]
        +
        +);
        +
        +print "CMS => PKCS#7 compatibility tests\n";
        +
        +run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
        +
        +print "CMS <= PKCS#7 compatibility tests\n";
        +
        +run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd );
        +
        +print "CMS <=> CMS consistency tests\n";
        +
        +run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd );
        +run_smime_tests( \$badcmd, \@smime_cms_tests,   $cmscmd, $cmscmd );
        +
        +if ( `$ossl_path version -f` =~ /ZLIB/ ) {
        +    run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd );
        +}
        +else {
        +    print "Zlib not supported: compression tests skipped\n";
        +}
        +
        +print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8);
        +
        +if ($badcmd) {
        +    print "$badcmd TESTS FAILED!!\n";
        +}
        +else {
        +    print "ALL TESTS SUCCESSFUL.\n";
        +}
        +
        +unlink "test.cms";
        +unlink "test2.cms";
        +unlink "smtst.txt";
        +unlink "cms.out";
        +unlink "cms.err";
        +
        +sub run_smime_tests {
        +    my ( $rv, $aref, $scmd, $vcmd ) = @_;
        +
        +    foreach $smtst (@$aref) {
        +        my ( $tnam, $rscmd, $rvcmd ) = @$smtst;
        +	if ($ossl8)
        +		{
        +		# Skip smime resign: 0.9.8 smime doesn't support -resign	
        +		next if ($scmd =~ /smime/ && $rscmd =~ /-resign/);
        +		# Disable streaming: option not supported in 0.9.8
        +		$tnam =~ s/streaming//;	
        +		$rscmd =~ s/-stream//;	
        +		$rvcmd =~ s/-stream//;
        +		}
        +        system("$scmd$rscmd$redir");
        +        if ($?) {
        +            print "$tnam: generation error\n";
        +            $$rv++;
        +            exit 1 if $halt_err;
        +            next;
        +        }
        +        system("$vcmd$rvcmd$redir");
        +        if ($?) {
        +            print "$tnam: verify error\n";
        +            $$rv++;
        +            exit 1 if $halt_err;
        +            next;
        +        }
        +	if (!cmp_files("smtst.txt", "smcont.txt")) {
        +            print "$tnam: content verify error\n";
        +            $$rv++;
        +            exit 1 if $halt_err;
        +            next;
        +	}
        +        print "$tnam: OK\n";
        +    }
        +}
        +
        +sub cmp_files {
        +    my ( $f1, $f2 ) = @_;
        +    my ( $fp1, $fp2 );
        +
        +    my ( $rd1, $rd2 );
        +
        +    if ( !open( $fp1, "<$f1" ) ) {
        +        print STDERR "Can't Open file $f1\n";
        +        return 0;
        +    }
        +
        +    if ( !open( $fp2, "<$f2" ) ) {
        +        print STDERR "Can't Open file $f2\n";
        +        return 0;
        +    }
        +
        +    binmode $fp1;
        +    binmode $fp2;
        +
        +    my $ret = 0;
        +
        +    for ( ; ; ) {
        +        $n1 = sysread $fp1, $rd1, 4096;
        +        $n2 = sysread $fp2, $rd2, 4096;
        +        last if ( $n1 != $n2 );
        +        last if ( $rd1 ne $rd2 );
        +
        +        if ( $n1 == 0 ) {
        +            $ret = 1;
        +            last;
        +        }
        +
        +    }
        +
        +    close $fp1;
        +    close $fp2;
        +
        +    return $ret;
        +
        +}
        +
        diff --git a/vendor/openssl/openssl/test/destest.c b/vendor/openssl/openssl/test/destest.c
        new file mode 100644
        index 000000000..64b92a34f
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/destest.c
        @@ -0,0 +1,952 @@
        +/* crypto/des/destest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +
        +#include <openssl/e_os2.h>
        +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_WINDOWS)
        +#ifndef OPENSSL_SYS_MSDOS
        +#define OPENSSL_SYS_MSDOS
        +#endif
        +#endif
        +
        +#ifndef OPENSSL_SYS_MSDOS
        +#if !defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VMS_DECC)
        +#include OPENSSL_UNISTD
        +#endif
        +#else
        +#include <io.h>
        +#endif
        +#include <string.h>
        +
        +#ifdef OPENSSL_NO_DES
        +int main(int argc, char *argv[])
        +{
        +    printf("No DES support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/des.h>
        +
        +#define crypt(c,s) (DES_crypt((c),(s)))
        +
        +/* tisk tisk - the test keys don't all have odd parity :-( */
        +/* test data */
        +#define NUM_TESTS 34
        +static unsigned char key_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
        +	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
        +	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
        +	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
        +	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
        +	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
        +	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
        +	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
        +	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
        +	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
        +	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
        +	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
        +	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
        +	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
        +	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
        +	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
        +	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
        +	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
        +	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
        +	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
        +	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
        +	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
        +	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
        +
        +static unsigned char plain_data[NUM_TESTS][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
        +	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
        +	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
        +	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
        +	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
        +	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
        +	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
        +	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
        +	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
        +	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
        +	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
        +	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
        +	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
        +	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
        +	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
        +	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
        +	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
        +	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
        +	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
        +
        +static unsigned char cipher_data[NUM_TESTS][8]={
        +	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
        +	{0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
        +	{0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
        +	{0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
        +	{0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
        +	{0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
        +	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
        +	{0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
        +	{0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
        +	{0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
        +	{0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
        +	{0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
        +	{0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
        +	{0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
        +	{0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
        +	{0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
        +	{0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
        +	{0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
        +	{0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
        +	{0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
        +	{0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
        +	{0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
        +	{0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
        +	{0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
        +	{0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
        +	{0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
        +	{0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
        +	{0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
        +	{0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
        +	{0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
        +	{0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
        +	{0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
        +	{0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
        +	{0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
        +
        +static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
        +	{0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
        +	{0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
        +	{0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
        +	{0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
        +	{0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
        +	{0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
        +	{0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
        +	{0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
        +	{0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
        +	{0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
        +	{0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
        +	{0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
        +	{0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
        +	{0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
        +	{0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
        +	{0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
        +	{0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
        +	{0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
        +	{0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
        +	{0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
        +	{0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
        +	{0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
        +	{0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
        +	{0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
        +	{0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
        +	{0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
        +	{0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
        +	{0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
        +	{0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
        +	{0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
        +	{0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
        +	{0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
        +	{0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
        +
        +static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
        +static unsigned char cbc2_key[8]={0xf1,0xe0,0xd3,0xc2,0xb5,0xa4,0x97,0x86};
        +static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
        +static unsigned char cbc_iv  [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
        +/* Changed the following text constant to binary so it will work on ebcdic
        + * machines :-) */
        +/* static char cbc_data[40]="7654321 Now is the time for \0001"; */
        +static unsigned char cbc_data[40]={
        +	0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x20,
        +	0x4E,0x6F,0x77,0x20,0x69,0x73,0x20,0x74,
        +	0x68,0x65,0x20,0x74,0x69,0x6D,0x65,0x20,
        +	0x66,0x6F,0x72,0x20,0x00,0x31,0x00,0x00,
        +	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	};
        +
        +static unsigned char cbc_ok[32]={
        +	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
        +	0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
        +	0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
        +	0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
        +
        +#ifdef SCREW_THE_PARITY
        +#error "SCREW_THE_PARITY is not ment to be defined."
        +#error "Original vectors are preserved for reference only."
        +static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
        +static unsigned char xcbc_ok[32]={
        +	0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
        +	0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
        +	0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
        +	0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
        +	};
        +#else
        +static unsigned char xcbc_ok[32]={
        +	0x84,0x6B,0x29,0x14,0x85,0x1E,0x9A,0x29,
        +	0x54,0x73,0x2F,0x8A,0xA0,0xA6,0x11,0xC1,
        +	0x15,0xCD,0xC2,0xD7,0x95,0x1B,0x10,0x53,
        +	0xA6,0x3C,0x5E,0x03,0xB2,0x1A,0xA3,0xC4,
        +	};
        +#endif
        +
        +static unsigned char cbc3_ok[32]={
        +	0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
        +	0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
        +	0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
        +	0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
        +
        +static unsigned char pcbc_ok[32]={
        +	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
        +	0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
        +	0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
        +	0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
        +
        +static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
        +static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +static unsigned char plain[24]=
        +	{
        +	0x4e,0x6f,0x77,0x20,0x69,0x73,
        +	0x20,0x74,0x68,0x65,0x20,0x74,
        +	0x69,0x6d,0x65,0x20,0x66,0x6f,
        +	0x72,0x20,0x61,0x6c,0x6c,0x20
        +	};
        +static unsigned char cfb_cipher8[24]= {
        +	0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
        +	0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
        +static unsigned char cfb_cipher16[24]={
        +	0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
        +	0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
        +static unsigned char cfb_cipher32[24]={
        +	0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
        +	0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
        +static unsigned char cfb_cipher48[24]={
        +	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
        +	0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
        +static unsigned char cfb_cipher64[24]={
        +	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
        +	0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
        +
        +static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
        +static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
        +static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
        +static unsigned char ofb_cipher[24]=
        +	{
        +	0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
        +	0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
        +	0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
        +	};
        +
        +#if 0
        +static DES_LONG cbc_cksum_ret=0xB462FEF7L;
        +#else
        +static DES_LONG cbc_cksum_ret=0xF7FE62B4L;
        +#endif
        +static unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
        +
        +static char *pt(unsigned char *p);
        +static int cfb_test(int bits, unsigned char *cfb_cipher);
        +static int cfb64_test(unsigned char *cfb_cipher);
        +static int ede_cfb64_test(unsigned char *cfb_cipher);
        +int main(int argc, char *argv[])
        +	{
        +	int j,err=0;
        +	unsigned int i;
        +	des_cblock in,out,outin,iv3,iv2;
        +	des_key_schedule ks,ks2,ks3;
        +	unsigned char cbc_in[40];
        +	unsigned char cbc_out[40];
        +	DES_LONG cs;
        +	unsigned char cret[8];
        +#ifdef _CRAY
        +        struct {
        +            int a:32;
        +            int b:32;
        +        } lqret[2];
        +#else
        +        DES_LONG lqret[4];
        +#endif
        +	int num;
        +	char *str;
        +
        +#ifndef OPENSSL_NO_DESCBCM
        +	printf("Doing cbcm\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	i=strlen((char *)cbc_data)+1;
        +	/* i=((i+7)/8)*8; */
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	memset(iv2,'\0',sizeof iv2);
        +
        +	DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2,
        +			      DES_ENCRYPT);
        +	DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3,
        +			      &iv3,&iv2,DES_ENCRYPT);
        +	/*	if (memcmp(cbc_out,cbc3_ok,
        +		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
        +		{
        +		printf("des_ede3_cbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	*/
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	memset(iv2,'\0',sizeof iv2);
        +	DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		unsigned int n;
        +
        +		printf("des_ede3_cbcm_encrypt decrypt error\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_data[n]);
        +		printf("\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_in[n]);
        +		printf("\n");
        +		err=1;
        +		}
        +#endif
        +
        +	printf("Doing ecb\n");
        +	for (i=0; i<NUM_TESTS; i++)
        +		{
        +		DES_set_key_unchecked(&key_data[i],&ks);
        +		memcpy(in,plain_data[i],8);
        +		memset(out,0,8);
        +		memset(outin,0,8);
        +		des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
        +		des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);
        +
        +		if (memcmp(out,cipher_data[i],8) != 0)
        +			{
        +			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
        +				pt(out));
        +			err=1;
        +			}
        +		if (memcmp(in,outin,8) != 0)
        +			{
        +			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
        +			err=1;
        +			}
        +		}
        +
        +#ifndef LIBDES_LIT
        +	printf("Doing ede ecb\n");
        +	for (i=0; i<(NUM_TESTS-2); i++)
        +		{
        +		DES_set_key_unchecked(&key_data[i],&ks);
        +		DES_set_key_unchecked(&key_data[i+1],&ks2);
        +		DES_set_key_unchecked(&key_data[i+2],&ks3);
        +		memcpy(in,plain_data[i],8);
        +		memset(out,0,8);
        +		memset(outin,0,8);
        +		des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
        +		des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);
        +
        +		if (memcmp(out,cipher_ecb2[i],8) != 0)
        +			{
        +			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
        +				pt(out));
        +			err=1;
        +			}
        +		if (memcmp(in,outin,8) != 0)
        +			{
        +			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
        +				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
        +			err=1;
        +			}
        +		}
        +#endif
        +
        +	printf("Doing cbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_ncbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,DES_ENCRYPT);
        +	if (memcmp(cbc_out,cbc_ok,32) != 0)
        +		{
        +		printf("cbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_ncbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
        +		{
        +		printf("cbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +#ifndef LIBDES_LIT
        +	printf("Doing desx cbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_xcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
        +	if (memcmp(cbc_out,xcbc_ok,32) != 0)
        +		{
        +		printf("des_xcbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_xcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
        +			 &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		printf("des_xcbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +#endif
        +
        +	printf("Doing ede cbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	i=strlen((char *)cbc_data)+1;
        +	/* i=((i+7)/8)*8; */
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +
        +	des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,
        +			     DES_ENCRYPT);
        +	des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3,
        +			     &iv3,DES_ENCRYPT);
        +	if (memcmp(cbc_out,cbc3_ok,
        +		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
        +		{
        +		unsigned int n;
        +
        +		printf("des_ede3_cbc_encrypt encrypt error\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_out[n]);
        +		printf("\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc3_ok[n]);
        +		printf("\n");
        +		err=1;
        +		}
        +
        +	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
        +	des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		unsigned int n;
        +
        +		printf("des_ede3_cbc_encrypt decrypt error\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_data[n]);
        +		printf("\n");
        +		for(n=0 ; n < i ; ++n)
        +		    printf(" %02x",cbc_in[n]);
        +		printf("\n");
        +		err=1;
        +		}
        +
        +#ifndef LIBDES_LIT
        +	printf("Doing pcbc\n");
        +	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
        +		{
        +		printf("Key error %d\n",j);
        +		err=1;
        +		}
        +	memset(cbc_out,0,40);
        +	memset(cbc_in,0,40);
        +	des_pcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
        +			 &cbc_iv,DES_ENCRYPT);
        +	if (memcmp(cbc_out,pcbc_ok,32) != 0)
        +		{
        +		printf("pcbc_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	des_pcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,&cbc_iv,
        +			 DES_DECRYPT);
        +	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
        +		{
        +		printf("pcbc_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("Doing ");
        +	printf("cfb8 ");
        +	err+=cfb_test(8,cfb_cipher8);
        +	printf("cfb16 ");
        +	err+=cfb_test(16,cfb_cipher16);
        +	printf("cfb32 ");
        +	err+=cfb_test(32,cfb_cipher32);
        +	printf("cfb48 ");
        +	err+=cfb_test(48,cfb_cipher48);
        +	printf("cfb64 ");
        +	err+=cfb_test(64,cfb_cipher64);
        +
        +	printf("cfb64() ");
        +	err+=cfb64_test(cfb_cipher64);
        +
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	for (i=0; i<sizeof(plain); i++)
        +		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
        +			8,1,ks,&cfb_tmp,DES_ENCRYPT);
        +	if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		printf("cfb_encrypt small encrypt error\n");
        +		err=1;
        +		}
        +
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	for (i=0; i<sizeof(plain); i++)
        +		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
        +			8,1,ks,&cfb_tmp,DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		printf("cfb_encrypt small decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("ede_cfb64() ");
        +	err+=ede_cfb64_test(cfb_cipher64);
        +
        +	printf("done\n");
        +
        +	printf("Doing ofb\n");
        +	DES_set_key_checked(&ofb_key,&ks);
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp);
        +	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
        +		{
        +		printf("ofb_encrypt encrypt error\n");
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
        +ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
        +ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
        +		err=1;
        +		}
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp);
        +	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
        +		{
        +		printf("ofb_encrypt decrypt error\n");
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
        +ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
        +printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
        +plain[8+0], plain[8+1], plain[8+2], plain[8+3],
        +plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
        +		err=1;
        +		}
        +
        +	printf("Doing ofb64\n");
        +	DES_set_key_checked(&ofb_key,&ks);
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	memset(ofb_buf1,0,sizeof(ofb_buf1));
        +	memset(ofb_buf2,0,sizeof(ofb_buf1));
        +	num=0;
        +	for (i=0; i<sizeof(plain); i++)
        +		{
        +		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,&ofb_tmp,
        +				  &num);
        +		}
        +	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
        +		{
        +		printf("ofb64_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	num=0;
        +	des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp,
        +			  &num);
        +	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
        +		{
        +		printf("ofb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("Doing ede_ofb64\n");
        +	DES_set_key_checked(&ofb_key,&ks);
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	memset(ofb_buf1,0,sizeof(ofb_buf1));
        +	memset(ofb_buf2,0,sizeof(ofb_buf1));
        +	num=0;
        +	for (i=0; i<sizeof(plain); i++)
        +		{
        +		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,
        +				       ks,&ofb_tmp,&num);
        +		}
        +	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
        +		{
        +		printf("ede_ofb64_encrypt encrypt error\n");
        +		err=1;
        +		}
        +	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
        +	num=0;
        +	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,ks,ks,
        +			       &ofb_tmp,&num);
        +	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
        +		{
        +		printf("ede_ofb64_encrypt decrypt error\n");
        +		err=1;
        +		}
        +
        +	printf("Doing cbc_cksum\n");
        +	DES_set_key_checked(&cbc_key,&ks);
        +	cs=des_cbc_cksum(cbc_data,&cret,strlen((char *)cbc_data),ks,&cbc_iv);
        +	if (cs != cbc_cksum_ret)
        +		{
        +		printf("bad return value (%08lX), should be %08lX\n",
        +			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
        +		err=1;
        +		}
        +	if (memcmp(cret,cbc_cksum_data,8) != 0)
        +		{
        +		printf("bad cbc_cksum block returned\n");
        +		err=1;
        +		}
        +
        +	printf("Doing quad_cksum\n");
        +	cs=des_quad_cksum(cbc_data,(des_cblock *)lqret,
        +		(long)strlen((char *)cbc_data),2,(des_cblock *)cbc_iv);
        +	if (cs != 0x70d7a63aL)
        +		{
        +		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
        +			(unsigned long)cs);
        +		err=1;
        +		}
        +#ifdef _CRAY
        +	if (lqret[0].a != 0x327eba8dL)
        +		{
        +		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
        +			(unsigned long)lqret[0].a,0x327eba8dUL);
        +		err=1;
        +		}
        +	if (lqret[0].b != 0x201a49ccL)
        +		{
        +		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
        +			(unsigned long)lqret[0].b,0x201a49ccUL);
        +		err=1;
        +		}
        +	if (lqret[1].a != 0x70d7a63aL)
        +		{
        +		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
        +			(unsigned long)lqret[1].a,0x70d7a63aUL);
        +		err=1;
        +		}
        +	if (lqret[1].b != 0x501c2c26L)
        +		{
        +		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
        +			(unsigned long)lqret[1].b,0x501c2c26UL);
        +		err=1;
        +		}
        +#else
        +	if (lqret[0] != 0x327eba8dL)
        +		{
        +		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
        +			(unsigned long)lqret[0],0x327eba8dUL);
        +		err=1;
        +		}
        +	if (lqret[1] != 0x201a49ccL)
        +		{
        +		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
        +			(unsigned long)lqret[1],0x201a49ccUL);
        +		err=1;
        +		}
        +	if (lqret[2] != 0x70d7a63aL)
        +		{
        +		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
        +			(unsigned long)lqret[2],0x70d7a63aUL);
        +		err=1;
        +		}
        +	if (lqret[3] != 0x501c2c26L)
        +		{
        +		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
        +			(unsigned long)lqret[3],0x501c2c26UL);
        +		err=1;
        +		}
        +#endif
        +#endif
        +
        +	printf("input word alignment test");
        +	for (i=0; i<4; i++)
        +		{
        +		printf(" %d",i);
        +		des_ncbc_encrypt(&(cbc_out[i]),cbc_in,
        +				 strlen((char *)cbc_data)+1,ks,
        +				 &cbc_iv,DES_ENCRYPT);
        +		}
        +	printf("\noutput word alignment test");
        +	for (i=0; i<4; i++)
        +		{
        +		printf(" %d",i);
        +		des_ncbc_encrypt(cbc_out,&(cbc_in[i]),
        +				 strlen((char *)cbc_data)+1,ks,
        +				 &cbc_iv,DES_ENCRYPT);
        +		}
        +	printf("\n");
        +	printf("fast crypt test ");
        +	str=crypt("testing","ef");
        +	if (strcmp("efGnQx2725bI2",str) != 0)
        +		{
        +		printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
        +		err=1;
        +		}
        +	str=crypt("bca76;23","yA");
        +	if (strcmp("yA1Rp/1hZXIJk",str) != 0)
        +		{
        +		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
        +		err=1;
        +		}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	printf("\n");
        +	return(err);
        +	}
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +
        +#ifndef LIBDES_LIT
        +
        +static int cfb_test(int bits, unsigned char *cfb_cipher)
        +	{
        +	des_key_schedule ks;
        +	int i,err=0;
        +
        +	DES_set_key_checked(&cfb_key,&ks);
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	des_cfb_encrypt(plain,cfb_buf1,bits,sizeof(plain),ks,&cfb_tmp,
        +			DES_ENCRYPT);
        +	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt encrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,sizeof(plain),ks,&cfb_tmp,
        +			DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt decrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	return(err);
        +	}
        +
        +static int cfb64_test(unsigned char *cfb_cipher)
        +	{
        +	des_key_schedule ks;
        +	int err=0,i,n;
        +
        +	DES_set_key_checked(&cfb_key,&ks);
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_cfb64_encrypt(plain,cfb_buf1,12,ks,&cfb_tmp,&n,DES_ENCRYPT);
        +	des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),sizeof(plain)-12,ks,
        +			  &cfb_tmp,&n,DES_ENCRYPT);
        +	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt encrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_cfb64_encrypt(cfb_buf1,cfb_buf2,17,ks,&cfb_tmp,&n,DES_DECRYPT);
        +	des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +			  sizeof(plain)-17,ks,&cfb_tmp,&n,DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("cfb_encrypt decrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf2[i])));
        +		}
        +	return(err);
        +	}
        +
        +static int ede_cfb64_test(unsigned char *cfb_cipher)
        +	{
        +	des_key_schedule ks;
        +	int err=0,i,n;
        +
        +	DES_set_key_checked(&cfb_key,&ks);
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_ede3_cfb64_encrypt(plain,cfb_buf1,12,ks,ks,ks,&cfb_tmp,&n,
        +			       DES_ENCRYPT);
        +	des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +			       sizeof(plain)-12,ks,ks,ks,
        +			       &cfb_tmp,&n,DES_ENCRYPT);
        +	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("ede_cfb_encrypt encrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf1[i])));
        +		}
        +	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
        +	n=0;
        +	des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
        +			       &cfb_tmp,&n,DES_DECRYPT);
        +	des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +			       sizeof(plain)-17,ks,ks,ks,
        +			       &cfb_tmp,&n,DES_DECRYPT);
        +	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
        +		{
        +		err=1;
        +		printf("ede_cfb_encrypt decrypt error\n");
        +		for (i=0; i<24; i+=8)
        +			printf("%s\n",pt(&(cfb_buf2[i])));
        +		}
        +	return(err);
        +	}
        +
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/test/dhtest.c b/vendor/openssl/openssl/test/dhtest.c
        new file mode 100644
        index 000000000..882f5c310
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/dhtest.c
        @@ -0,0 +1,226 @@
        +/* crypto/dh/dhtest.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.]
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +#ifdef OPENSSL_NO_DH
        +int main(int argc, char *argv[])
        +{
        +    printf("No DH support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/dh.h>
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define MS_CALLBACK	_far _loadds
        +#else
        +#define MS_CALLBACK
        +#endif
        +
        +static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg);
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_GENCB _cb;
        +	DH *a;
        +	DH *b=NULL;
        +	char buf[12];
        +	unsigned char *abuf=NULL,*bbuf=NULL;
        +	int i,alen,blen,aout,bout,ret=1;
        +	BIO *out;
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +#ifdef OPENSSL_SYS_WIN32
        +	CRYPTO_malloc_init();
        +#endif
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) EXIT(1);
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +
        +	BN_GENCB_set(&_cb, &cb, out);
        +	if(((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64,
        +				DH_GENERATOR_5, &_cb))
        +		goto err;
        +
        +	if (!DH_check(a, &i)) goto err;
        +	if (i & DH_CHECK_P_NOT_PRIME)
        +		BIO_puts(out, "p value is not prime\n");
        +	if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        +		BIO_puts(out, "p value is not a safe prime\n");
        +	if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        +		BIO_puts(out, "unable to check the generator value\n");
        +	if (i & DH_NOT_SUITABLE_GENERATOR)
        +		BIO_puts(out, "the g value is not a generator\n");
        +
        +	BIO_puts(out,"\np    =");
        +	BN_print(out,a->p);
        +	BIO_puts(out,"\ng    =");
        +	BN_print(out,a->g);
        +	BIO_puts(out,"\n");
        +
        +	b=DH_new();
        +	if (b == NULL) goto err;
        +
        +	b->p=BN_dup(a->p);
        +	b->g=BN_dup(a->g);
        +	if ((b->p == NULL) || (b->g == NULL)) goto err;
        +
        +	/* Set a to run with normal modexp and b to use constant time */
        +	a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
        +	b->flags |= DH_FLAG_NO_EXP_CONSTTIME;
        +
        +	if (!DH_generate_key(a)) goto err;
        +	BIO_puts(out,"pri 1=");
        +	BN_print(out,a->priv_key);
        +	BIO_puts(out,"\npub 1=");
        +	BN_print(out,a->pub_key);
        +	BIO_puts(out,"\n");
        +
        +	if (!DH_generate_key(b)) goto err;
        +	BIO_puts(out,"pri 2=");
        +	BN_print(out,b->priv_key);
        +	BIO_puts(out,"\npub 2=");
        +	BN_print(out,b->pub_key);
        +	BIO_puts(out,"\n");
        +
        +	alen=DH_size(a);
        +	abuf=(unsigned char *)OPENSSL_malloc(alen);
        +	aout=DH_compute_key(abuf,b->pub_key,a);
        +
        +	BIO_puts(out,"key1 =");
        +	for (i=0; i<aout; i++)
        +		{
        +		sprintf(buf,"%02X",abuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +
        +	blen=DH_size(b);
        +	bbuf=(unsigned char *)OPENSSL_malloc(blen);
        +	bout=DH_compute_key(bbuf,a->pub_key,b);
        +
        +	BIO_puts(out,"key2 =");
        +	for (i=0; i<bout; i++)
        +		{
        +		sprintf(buf,"%02X",bbuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
        +		{
        +		fprintf(stderr,"Error in DH routines\n");
        +		ret=1;
        +		}
        +	else
        +		ret=0;
        +err:
        +	ERR_print_errors_fp(stderr);
        +
        +	if (abuf != NULL) OPENSSL_free(abuf);
        +	if (bbuf != NULL) OPENSSL_free(bbuf);
        +	if(b != NULL) DH_free(b);
        +	if(a != NULL) DH_free(a);
        +	BIO_free(out);
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (ret) printf("ERROR: %d\n", ret);
        +#endif
        +	EXIT(ret);
        +	return(ret);
        +	}
        +
        +static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write(arg->arg,&c,1);
        +	(void)BIO_flush(arg->arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/dsatest.c b/vendor/openssl/openssl/test/dsatest.c
        new file mode 100644
        index 000000000..edffd24e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/dsatest.c
        @@ -0,0 +1,259 @@
        +/* crypto/dsa/dsatest.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.]
        + */
        +
        +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
        + * deprecated functions for openssl-internal code */
        +#ifdef OPENSSL_NO_DEPRECATED
        +#undef OPENSSL_NO_DEPRECATED
        +#endif
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <sys/types.h>
        +#include <sys/stat.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/rand.h>
        +#include <openssl/bio.h>
        +#include <openssl/err.h>
        +#include <openssl/bn.h>
        +
        +#ifdef OPENSSL_NO_DSA
        +int main(int argc, char *argv[])
        +{
        +    printf("No DSA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/dsa.h>
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define MS_CALLBACK     _far _loadds
        +#else
        +#define MS_CALLBACK
        +#endif
        +
        +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg);
        +
        +/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
        + * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
        +static unsigned char seed[20]={
        +	0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
        +	0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
        +	};
        +
        +static unsigned char out_p[]={
        +	0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
        +	0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
        +	0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
        +	0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
        +	0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
        +	0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
        +	0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
        +	0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
        +	};
        +
        +static unsigned char out_q[]={
        +	0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
        +	0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
        +	0xda,0xce,0x91,0x5f,
        +	};
        +
        +static unsigned char out_g[]={
        +	0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
        +	0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
        +	0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
        +	0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
        +	0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
        +	0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
        +	0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
        +	0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
        +	};
        +
        +static const unsigned char str1[]="12345678901234567890";
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +static BIO *bio_err=NULL;
        +
        +int main(int argc, char **argv)
        +	{
        +	BN_GENCB cb;
        +	DSA *dsa=NULL;
        +	int counter,ret=0,i,j;
        +	unsigned char buf[256];
        +	unsigned long h;
        +	unsigned char sig[256];
        +	unsigned int siglen;
        +
        +	if (bio_err == NULL)
        +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	ERR_load_crypto_strings();
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	BIO_printf(bio_err,"test generation of DSA parameters\n");
        +
        +	BN_GENCB_set(&cb, dsa_cb, bio_err);
        +	if(((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
        +				seed, 20, &counter, &h, &cb))
        +		goto end;
        +
        +	BIO_printf(bio_err,"seed\n");
        +	for (i=0; i<20; i+=4)
        +		{
        +		BIO_printf(bio_err,"%02X%02X%02X%02X ",
        +			seed[i],seed[i+1],seed[i+2],seed[i+3]);
        +		}
        +	BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h);
        +		
        +	DSA_print(bio_err,dsa,0);
        +	if (counter != 105) 
        +		{
        +		BIO_printf(bio_err,"counter should be 105\n");
        +		goto end;
        +		}
        +	if (h != 2)
        +		{
        +		BIO_printf(bio_err,"h should be 2\n");
        +		goto end;
        +		}
        +
        +	i=BN_bn2bin(dsa->q,buf);
        +	j=sizeof(out_q);
        +	if ((i != j) || (memcmp(buf,out_q,i) != 0))
        +		{
        +		BIO_printf(bio_err,"q value is wrong\n");
        +		goto end;
        +		}
        +
        +	i=BN_bn2bin(dsa->p,buf);
        +	j=sizeof(out_p);
        +	if ((i != j) || (memcmp(buf,out_p,i) != 0))
        +		{
        +		BIO_printf(bio_err,"p value is wrong\n");
        +		goto end;
        +		}
        +
        +	i=BN_bn2bin(dsa->g,buf);
        +	j=sizeof(out_g);
        +	if ((i != j) || (memcmp(buf,out_g,i) != 0))
        +		{
        +		BIO_printf(bio_err,"g value is wrong\n");
        +		goto end;
        +		}
        +
        +	dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
        +	DSA_generate_key(dsa);
        +	DSA_sign(0, str1, 20, sig, &siglen, dsa);
        +	if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
        +		ret=1;
        +
        +	dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
        +	DSA_generate_key(dsa);
        +	DSA_sign(0, str1, 20, sig, &siglen, dsa);
        +	if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
        +		ret=1;
        +
        +end:
        +	if (!ret)
        +		ERR_print_errors(bio_err);
        +	if (dsa != NULL) DSA_free(dsa);
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	ERR_free_strings();
        +	CRYPTO_mem_leaks(bio_err);
        +	if (bio_err != NULL)
        +		{
        +		BIO_free(bio_err);
        +		bio_err = NULL;
        +		}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (!ret) printf("ERROR\n");
        +#endif
        +	EXIT(!ret);
        +	return(0);
        +	}
        +
        +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg)
        +	{
        +	char c='*';
        +	static int ok=0,num=0;
        +
        +	if (p == 0) { c='.'; num++; };
        +	if (p == 1) c='+';
        +	if (p == 2) { c='*'; ok++; }
        +	if (p == 3) c='\n';
        +	BIO_write(arg->arg,&c,1);
        +	(void)BIO_flush(arg->arg);
        +
        +	if (!ok && (p == 0) && (num > 1))
        +		{
        +		BIO_printf((BIO *)arg,"error in dsatest\n");
        +		return 0;
        +		}
        +	return 1;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/dummytest.c b/vendor/openssl/openssl/test/dummytest.c
        new file mode 100644
        index 000000000..5b4467e04
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/dummytest.c
        @@ -0,0 +1,48 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/buffer.h>
        +#include <openssl/crypto.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *p, *q = 0, *program;
        +
        +	p = strrchr(argv[0], '/');
        +	if (!p) p = strrchr(argv[0], '\\');
        +#ifdef OPENSSL_SYS_VMS
        +	if (!p) p = strrchr(argv[0], ']');
        +	if (p) q = strrchr(p, '>');
        +	if (q) p = q;
        +	if (!p) p = strrchr(argv[0], ':');
        +	q = 0;
        +#endif
        +	if (p) p++;
        +	if (!p) p = argv[0];
        +	if (p) q = strchr(p, '.');
        +	if (p && !q) q = p + strlen(p);
        +
        +	if (!p)
        +		program = BUF_strdup("(unknown)");
        +	else
        +		{
        +		program = OPENSSL_malloc((q - p) + 1);
        +		strncpy(program, p, q - p);
        +		program[q - p] = '\0';
        +		}
        +
        +	for(p = program; *p; p++)
        +		if (islower((unsigned char)(*p)))
        +			*p = toupper((unsigned char)(*p));
        +
        +	q = strstr(program, "TEST");
        +	if (q > p && q[-1] == '_') q--;
        +	*q = '\0';
        +
        +	printf("No %s support\n", program);
        +
        +	OPENSSL_free(program);
        +	return(0);
        +	}
        diff --git a/vendor/openssl/openssl/test/ecdhtest.c b/vendor/openssl/openssl/test/ecdhtest.c
        new file mode 100644
        index 000000000..823d7baa6
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/ecdhtest.c
        @@ -0,0 +1,374 @@
        +/* crypto/ecdh/ecdhtest.c */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
        + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
        + * to the OpenSSL project.
        + *
        + * The ECC Code is licensed pursuant to the OpenSSL open source
        + * license provided below.
        + *
        + * The ECDH software is originally written by Douglas Stebila of
        + * Sun Microsystems Laboratories.
        + *
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/opensslconf.h>	/* for OPENSSL_NO_ECDH */
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/sha.h>
        +#include <openssl/err.h>
        +
        +#ifdef OPENSSL_NO_ECDH
        +int main(int argc, char *argv[])
        +{
        +    printf("No ECDH support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/ec.h>
        +#include <openssl/ecdh.h>
        +
        +#ifdef OPENSSL_SYS_WIN16
        +#define MS_CALLBACK	_far _loadds
        +#else
        +#define MS_CALLBACK
        +#endif
        +
        +#if 0
        +static void MS_CALLBACK cb(int p, int n, void *arg);
        +#endif
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +
        +static const int KDF1_SHA1_len = 20;
        +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
        +	{
        +#ifndef OPENSSL_NO_SHA
        +	if (*outlen < SHA_DIGEST_LENGTH)
        +		return NULL;
        +	else
        +		*outlen = SHA_DIGEST_LENGTH;
        +	return SHA1(in, inlen, out);
        +#else
        +	return NULL;
        +#endif
        +	}
        +
        +
        +static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
        +	{
        +	EC_KEY *a=NULL;
        +	EC_KEY *b=NULL;
        +	BIGNUM *x_a=NULL, *y_a=NULL,
        +	       *x_b=NULL, *y_b=NULL;
        +	char buf[12];
        +	unsigned char *abuf=NULL,*bbuf=NULL;
        +	int i,alen,blen,aout,bout,ret=0;
        +	const EC_GROUP *group;
        +
        +	a = EC_KEY_new_by_curve_name(nid);
        +	b = EC_KEY_new_by_curve_name(nid);
        +	if (a == NULL || b == NULL)
        +		goto err;
        +
        +	group = EC_KEY_get0_group(a);
        +
        +	if ((x_a=BN_new()) == NULL) goto err;
        +	if ((y_a=BN_new()) == NULL) goto err;
        +	if ((x_b=BN_new()) == NULL) goto err;
        +	if ((y_b=BN_new()) == NULL) goto err;
        +
        +	BIO_puts(out,"Testing key generation with ");
        +	BIO_puts(out,text);
        +#ifdef NOISY
        +	BIO_puts(out,"\n");
        +#else
        +	(void)BIO_flush(out);
        +#endif
        +
        +	if (!EC_KEY_generate_key(a)) goto err;
        +	
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group,
        +			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group,
        +			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
        +		}
        +#endif
        +#ifdef NOISY
        +	BIO_puts(out,"  pri 1=");
        +	BN_print(out,a->priv_key);
        +	BIO_puts(out,"\n  pub 1=");
        +	BN_print(out,x_a);
        +	BIO_puts(out,",");
        +	BN_print(out,y_a);
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out," .");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	if (!EC_KEY_generate_key(b)) goto err;
        +
        +	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group, 
        +			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
        +		}
        +#ifndef OPENSSL_NO_EC2M
        +	else
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, 
        +			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
        +		}
        +#endif
        +
        +#ifdef NOISY
        +	BIO_puts(out,"  pri 2=");
        +	BN_print(out,b->priv_key);
        +	BIO_puts(out,"\n  pub 2=");
        +	BN_print(out,x_b);
        +	BIO_puts(out,",");
        +	BN_print(out,y_b);
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out,".");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	alen=KDF1_SHA1_len;
        +	abuf=(unsigned char *)OPENSSL_malloc(alen);
        +	aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);
        +
        +#ifdef NOISY
        +	BIO_puts(out,"  key1 =");
        +	for (i=0; i<aout; i++)
        +		{
        +		sprintf(buf,"%02X",abuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out,".");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	blen=KDF1_SHA1_len;
        +	bbuf=(unsigned char *)OPENSSL_malloc(blen);
        +	bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);
        +
        +#ifdef NOISY
        +	BIO_puts(out,"  key2 =");
        +	for (i=0; i<bout; i++)
        +		{
        +		sprintf(buf,"%02X",bbuf[i]);
        +		BIO_puts(out,buf);
        +		}
        +	BIO_puts(out,"\n");
        +#else
        +	BIO_printf(out,".");
        +	(void)BIO_flush(out);
        +#endif
        +
        +	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
        +		{
        +#ifndef NOISY
        +		BIO_printf(out, " failed\n\n");
        +		BIO_printf(out, "key a:\n");
        +		BIO_printf(out, "private key: ");
        +		BN_print(out, EC_KEY_get0_private_key(a));
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "public key (x,y): ");
        +		BN_print(out, x_a);
        +		BIO_printf(out, ",");
        +		BN_print(out, y_a);
        +		BIO_printf(out, "\nkey b:\n");
        +		BIO_printf(out, "private key: ");
        +		BN_print(out, EC_KEY_get0_private_key(b));
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "public key (x,y): ");
        +		BN_print(out, x_b);
        +		BIO_printf(out, ",");
        +		BN_print(out, y_b);
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "generated key a: ");
        +		for (i=0; i<bout; i++)
        +			{
        +			sprintf(buf, "%02X", bbuf[i]);
        +			BIO_puts(out, buf);
        +			}
        +		BIO_printf(out, "\n");
        +		BIO_printf(out, "generated key b: ");
        +		for (i=0; i<aout; i++)
        +			{
        +			sprintf(buf, "%02X", abuf[i]);
        +			BIO_puts(out,buf);
        +			}
        +		BIO_printf(out, "\n");
        +#endif
        +		fprintf(stderr,"Error in ECDH routines\n");
        +		ret=0;
        +		}
        +	else
        +		{
        +#ifndef NOISY
        +		BIO_printf(out, " ok\n");
        +#endif
        +		ret=1;
        +		}
        +err:
        +	ERR_print_errors_fp(stderr);
        +
        +	if (abuf != NULL) OPENSSL_free(abuf);
        +	if (bbuf != NULL) OPENSSL_free(bbuf);
        +	if (x_a) BN_free(x_a);
        +	if (y_a) BN_free(y_a);
        +	if (x_b) BN_free(x_b);
        +	if (y_b) BN_free(y_b);
        +	if (b) EC_KEY_free(b);
        +	if (a) EC_KEY_free(a);
        +	return(ret);
        +	}
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_CTX *ctx=NULL;
        +	int ret=1;
        +	BIO *out;
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +#ifdef OPENSSL_SYS_WIN32
        +	CRYPTO_malloc_init();
        +#endif
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	out=BIO_new(BIO_s_file());
        +	if (out == NULL) EXIT(1);
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +
        +	if ((ctx=BN_CTX_new()) == NULL) goto err;
        +
        +	/* NIST PRIME CURVES TESTS */
        +	if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
        +#ifndef OPENSSL_NO_EC2M
        +	/* NIST BINARY CURVES TESTS */
        +	if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
        +	if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
        +#endif
        +
        +	ret = 0;
        +
        +err:
        +	ERR_print_errors_fp(stderr);
        +	if (ctx) BN_CTX_free(ctx);
        +	BIO_free(out);
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks_fp(stderr);
        +	EXIT(ret);
        +	return(ret);
        +	}
        +
        +#if 0
        +static void MS_CALLBACK cb(int p, int n, void *arg)
        +	{
        +	char c='*';
        +
        +	if (p == 0) c='.';
        +	if (p == 1) c='+';
        +	if (p == 2) c='*';
        +	if (p == 3) c='\n';
        +	BIO_write((BIO *)arg,&c,1);
        +	(void)BIO_flush((BIO *)arg);
        +#ifdef LINT
        +	p=n;
        +#endif
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/test/ecdsatest.c b/vendor/openssl/openssl/test/ecdsatest.c
        new file mode 100644
        index 000000000..537bb3036
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/ecdsatest.c
        @@ -0,0 +1,572 @@
        +/* crypto/ecdsa/ecdsatest.c */
        +/*
        + * Written by Nils Larsch for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 2000-2005 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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */
        +
        +#ifdef OPENSSL_NO_ECDSA
        +int main(int argc, char * argv[])
        +	{
        +	puts("Elliptic curves are disabled.");
        +	return 0;
        +	}
        +#else
        +
        +#include <openssl/crypto.h>
        +#include <openssl/bio.h>
        +#include <openssl/evp.h>
        +#include <openssl/bn.h>
        +#include <openssl/ecdsa.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +
        +static const char rnd_seed[] = "string to make the random number generator "
        +	"think it has entropy";
        +
        +/* declaration of the test functions */
        +int x9_62_tests(BIO *);
        +int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s);
        +int test_builtin(BIO *);
        +
        +/* functions to change the RAND_METHOD */
        +int change_rand(void);
        +int restore_rand(void);
        +int fbytes(unsigned char *buf, int num);
        +
        +RAND_METHOD	fake_rand;
        +const RAND_METHOD *old_rand;
        +
        +int change_rand(void)
        +	{
        +	/* save old rand method */
        +	if ((old_rand = RAND_get_rand_method()) == NULL)
        +		return 0;
        +
        +	fake_rand.seed    = old_rand->seed;
        +	fake_rand.cleanup = old_rand->cleanup;
        +	fake_rand.add     = old_rand->add;
        +	fake_rand.status  = old_rand->status;
        +	/* use own random function */
        +	fake_rand.bytes      = fbytes;
        +	fake_rand.pseudorand = old_rand->bytes;
        +	/* set new RAND_METHOD */
        +	if (!RAND_set_rand_method(&fake_rand))
        +		return 0;
        +	return 1;
        +	}
        +
        +int restore_rand(void)
        +	{
        +	if (!RAND_set_rand_method(old_rand))
        +		return 0;
        +	else
        +		return 1;
        +	}
        +
        +static int fbytes_counter = 0;
        +static const char *numbers[8] = {
        +	"651056770906015076056810763456358567190100156695615665659",
        +	"6140507067065001063065065565667405560006161556565665656654",
        +	"8763001015071075675010661307616710783570106710677817767166"
        +	"71676178726717",
        +	"7000000175690566466555057817571571075705015757757057795755"
        +	"55657156756655",
        +	"1275552191113212300012030439187146164646146646466749494799",
        +	"1542725565216523985789236956265265265235675811949404040041",
        +	"1456427555219115346513212300075341203043918714616464614664"
        +	"64667494947990",
        +	"1712787255652165239672857892369562652652652356758119494040"
        +	"40041670216363"};
        +
        +int fbytes(unsigned char *buf, int num)
        +	{
        +	int	ret;
        +	BIGNUM	*tmp = NULL;
        +
        +	if (fbytes_counter >= 8)
        +		return 0;
        +	tmp = BN_new();
        +	if (!tmp)
        +		return 0;
        +	if (!BN_dec2bn(&tmp, numbers[fbytes_counter]))
        +		{
        +		BN_free(tmp);
        +		return 0;
        +		}
        +	fbytes_counter ++;
        +	if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
        +		ret = 0;
        +	else 
        +		ret = 1;
        +	if (tmp)
        +		BN_free(tmp);
        +	return ret;
        +	}
        +
        +/* some tests from the X9.62 draft */
        +int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
        +	{
        +	int	ret = 0;
        +	const char message[] = "abc";
        +	unsigned char digest[20];
        +	unsigned int  dgst_len = 0;
        +	EVP_MD_CTX md_ctx;
        +	EC_KEY    *key = NULL;
        +	ECDSA_SIG *signature = NULL;
        +	BIGNUM    *r = NULL, *s = NULL;
        +
        +	EVP_MD_CTX_init(&md_ctx);
        +	/* get the message digest */
        +	EVP_DigestInit(&md_ctx, EVP_ecdsa());
        +	EVP_DigestUpdate(&md_ctx, (const void*)message, 3);
        +	EVP_DigestFinal(&md_ctx, digest, &dgst_len);
        +
        +	BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
        +	/* create the key */
        +	if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
        +		goto x962_int_err;
        +	if (!EC_KEY_generate_key(key))
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +	/* create the signature */
        +	signature = ECDSA_do_sign(digest, 20, key);
        +	if (signature == NULL)
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +	/* compare the created signature with the expected signature */
        +	if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
        +		goto x962_int_err;
        +	if (!BN_dec2bn(&r, r_in) ||
        +	    !BN_dec2bn(&s, s_in))
        +		goto x962_int_err;
        +	if (BN_cmp(signature->r ,r) || BN_cmp(signature->s, s))
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +	/* verify the signature */
        +	if (ECDSA_do_verify(digest, 20, signature, key) != 1)
        +		goto x962_int_err;
        +	BIO_printf(out, ".");
        +	(void)BIO_flush(out);
        +
        +	BIO_printf(out, " ok\n");
        +	ret = 1;
        +x962_int_err:
        +	if (!ret)
        +		BIO_printf(out, " failed\n");
        +	if (key)
        +		EC_KEY_free(key);
        +	if (signature)
        +		ECDSA_SIG_free(signature);
        +	if (r)
        +		BN_free(r);
        +	if (s)
        +		BN_free(s);
        +	EVP_MD_CTX_cleanup(&md_ctx);
        +	return ret;
        +	}
        +
        +int x9_62_tests(BIO *out)
        +	{
        +	int ret = 0;
        +
        +	BIO_printf(out, "some tests from X9.62:\n");
        +
        +	/* set own rand method */
        +	if (!change_rand())
        +		goto x962_err;
        +
        +	if (!x9_62_test_internal(out, NID_X9_62_prime192v1,
        +		"3342403536405981729393488334694600415596881826869351677613",
        +		"5735822328888155254683894997897571951568553642892029982342"))
        +		goto x962_err;
        +	if (!x9_62_test_internal(out, NID_X9_62_prime239v1,
        +		"3086361431751678114926225473006680188549593787585317781474"
        +		"62058306432176",
        +		"3238135532097973577080787768312505059318910517550078427819"
        +		"78505179448783"))
        +		goto x962_err;
        +#ifndef OPENSSL_NO_EC2M
        +	if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
        +		"87194383164871543355722284926904419997237591535066528048",
        +		"308992691965804947361541664549085895292153777025772063598"))
        +		goto x962_err;
        +	if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1,
        +		"2159633321041961198501834003903461262881815148684178964245"
        +		"5876922391552",
        +		"1970303740007316867383349976549972270528498040721988191026"
        +		"49413465737174"))
        +		goto x962_err;
        +#endif
        +	ret = 1;
        +x962_err:
        +	if (!restore_rand())
        +		ret = 0;
        +	return ret;
        +	}
        +
        +int test_builtin(BIO *out)
        +	{
        +	EC_builtin_curve *curves = NULL;
        +	size_t		crv_len = 0, n = 0;
        +	EC_KEY		*eckey = NULL, *wrong_eckey = NULL;
        +	EC_GROUP	*group;
        +	ECDSA_SIG	*ecdsa_sig = NULL;
        +	unsigned char	digest[20], wrong_digest[20];
        +	unsigned char	*signature = NULL;
        +	const unsigned char	*sig_ptr;
        +	unsigned char	*sig_ptr2;
        +	unsigned char	*raw_buf = NULL;
        +	unsigned int	sig_len, degree, r_len, s_len, bn_len, buf_len;
        +	int		nid, ret =  0;
        +	
        +	/* fill digest values with some random data */
        +	if (!RAND_pseudo_bytes(digest, 20) ||
        +	    !RAND_pseudo_bytes(wrong_digest, 20))
        +		{
        +		BIO_printf(out, "ERROR: unable to get random data\n");
        +		goto builtin_err;
        +		}
        +
        +	/* create and verify a ecdsa signature with every availble curve
        +	 * (with ) */
        +	BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
        +		"with some internal curves:\n");
        +
        +	/* get a list of all internal curves */
        +	crv_len = EC_get_builtin_curves(NULL, 0);
        +
        +	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
        +
        +	if (curves == NULL)
        +		{
        +		BIO_printf(out, "malloc error\n");
        +		goto builtin_err;
        +		}
        +	
        +	if (!EC_get_builtin_curves(curves, crv_len))
        +		{
        +		BIO_printf(out, "unable to get internal curves\n");
        +		goto builtin_err;
        +		}
        +
        +	/* now create and verify a signature for every curve */
        +	for (n = 0; n < crv_len; n++)
        +		{
        +		unsigned char dirt, offset;
        +
        +		nid = curves[n].nid;
        +		if (nid == NID_ipsec4)
        +			continue;
        +		/* create new ecdsa key (== EC_KEY) */
        +		if ((eckey = EC_KEY_new()) == NULL)
        +			goto builtin_err;
        +		group = EC_GROUP_new_by_curve_name(nid);
        +		if (group == NULL)
        +			goto builtin_err;
        +		if (EC_KEY_set_group(eckey, group) == 0)
        +			goto builtin_err;
        +		EC_GROUP_free(group);
        +		degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
        +		if (degree < 160)
        +			/* drop the curve */ 
        +			{
        +			EC_KEY_free(eckey);
        +			eckey = NULL;
        +			continue;
        +			}
        +		BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
        +		/* create key */
        +		if (!EC_KEY_generate_key(eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		/* create second key */
        +		if ((wrong_eckey = EC_KEY_new()) == NULL)
        +			goto builtin_err;
        +		group = EC_GROUP_new_by_curve_name(nid);
        +		if (group == NULL)
        +			goto builtin_err;
        +		if (EC_KEY_set_group(wrong_eckey, group) == 0)
        +			goto builtin_err;
        +		EC_GROUP_free(group);
        +		if (!EC_KEY_generate_key(wrong_eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* check key */
        +		if (!EC_KEY_check_key(eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* create signature */
        +		sig_len = ECDSA_size(eckey);
        +		if ((signature = OPENSSL_malloc(sig_len)) == NULL)
        +			goto builtin_err;
        +                if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* verify signature */
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* verify signature with the wrong key */
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, 
        +			wrong_eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* wrong digest */
        +		if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
        +			eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		/* wrong length */
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
        +			eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +
        +		/* Modify a single byte of the signature: to ensure we don't
        +		 * garble the ASN1 structure, we read the raw signature and
        +		 * modify a byte in one of the bignums directly. */
        +		sig_ptr = signature;
        +		if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +
        +		/* Store the two BIGNUMs in raw_buf. */
        +		r_len = BN_num_bytes(ecdsa_sig->r);
        +		s_len = BN_num_bytes(ecdsa_sig->s);
        +		bn_len = (degree + 7) / 8;
        +		if ((r_len > bn_len) || (s_len > bn_len))
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		buf_len = 2 * bn_len;
        +		if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
        +			goto builtin_err;
        +		/* Pad the bignums with leading zeroes. */
        +		memset(raw_buf, 0, buf_len);
        +		BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
        +		BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
        +
        +		/* Modify a single byte in the buffer. */
        +		offset = raw_buf[10] % buf_len;
        +		dirt   = raw_buf[11] ? raw_buf[11] : 1;
        +		raw_buf[offset] ^= dirt;
        +		/* Now read the BIGNUMs back in from raw_buf. */
        +		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
        +			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
        +			goto builtin_err;
        +
        +		sig_ptr2 = signature;
        +		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		/* Sanity check: undo the modification and verify signature. */
        +		raw_buf[offset] ^= dirt;
        +		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
        +			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
        +			goto builtin_err;
        +
        +		sig_ptr2 = signature;
        +		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
        +		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
        +			{
        +			BIO_printf(out, " failed\n");
        +			goto builtin_err;
        +			}
        +		BIO_printf(out, ".");
        +		(void)BIO_flush(out);
        +		
        +		BIO_printf(out, " ok\n");
        +		/* cleanup */
        +		/* clean bogus errors */
        +		ERR_clear_error();
        +		OPENSSL_free(signature);
        +		signature = NULL;
        +		EC_KEY_free(eckey);
        +		eckey = NULL;
        +		EC_KEY_free(wrong_eckey);
        +		wrong_eckey = NULL;
        +		ECDSA_SIG_free(ecdsa_sig);
        +		ecdsa_sig = NULL;
        +		OPENSSL_free(raw_buf);
        +		raw_buf = NULL;
        +		}
        +
        +	ret = 1;	
        +builtin_err:
        +	if (eckey)
        +		EC_KEY_free(eckey);
        +	if (wrong_eckey)
        +		EC_KEY_free(wrong_eckey);
        +	if (ecdsa_sig)
        +		ECDSA_SIG_free(ecdsa_sig);
        +	if (signature)
        +		OPENSSL_free(signature);
        +	if (raw_buf)
        +		OPENSSL_free(raw_buf);
        +	if (curves)
        +		OPENSSL_free(curves);
        +
        +	return ret;
        +	}
        +
        +int main(void)
        +	{
        +	int 	ret = 1;
        +	BIO	*out;
        +
        +	out = BIO_new_fp(stdout, BIO_NOCLOSE);
        +	
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && 
        +		(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	ERR_load_crypto_strings();
        +
        +	/* initialize the prng */
        +	RAND_seed(rnd_seed, sizeof(rnd_seed));
        +
        +	/* the tests */
        +	if (!x9_62_tests(out))  goto err;
        +	if (!test_builtin(out)) goto err;
        +	
        +	ret = 0;
        +err:	
        +	if (ret) 	
        +		BIO_printf(out, "\nECDSA test failed\n");
        +	else 
        +		BIO_printf(out, "\nECDSA test passed\n");
        +	if (ret)
        +		ERR_print_errors(out);
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	ERR_free_strings();
        +	CRYPTO_mem_leaks(out);
        +	if (out != NULL)
        +		BIO_free(out);
        +	return ret;
        +	}	
        +#endif
        diff --git a/vendor/openssl/openssl/test/ectest.c b/vendor/openssl/openssl/test/ectest.c
        new file mode 100644
        index 000000000..102eaa9b2
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/ectest.c
        @@ -0,0 +1,1489 @@
        +/* crypto/ec/ectest.c */
        +/*
        + * Originally written by Bodo Moeller for the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + * ====================================================================
        + *
        + * This product includes cryptographic software written by Eric Young
        + * (eay@cryptsoft.com).  This product includes software written by Tim
        + * Hudson (tjh@cryptsoft.com).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + *
        + * Portions of the attached software ("Contribution") are developed by 
        + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
        + *
        + * The Contribution is licensed pursuant to the OpenSSL open source
        + * license provided above.
        + *
        + * The elliptic curve binary polynomial software is originally written by 
        + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
        + *
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#ifdef FLAT_INC
        +#include "e_os.h"
        +#else
        +#include "../e_os.h"
        +#endif
        +#include <string.h>
        +#include <time.h>
        +
        +
        +#ifdef OPENSSL_NO_EC
        +int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
        +#else
        +
        +
        +#include <openssl/ec.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/obj_mac.h>
        +#include <openssl/objects.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +#include <openssl/opensslconf.h>
        +
        +#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
        +/* suppress "too big too optimize" warning */
        +#pragma warning(disable:4959)
        +#endif
        +
        +#define ABORT do { \
        +	fflush(stdout); \
        +	fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
        +	ERR_print_errors_fp(stderr); \
        +	EXIT(1); \
        +} while (0)
        +
        +#define TIMING_BASE_PT 0
        +#define TIMING_RAND_PT 1
        +#define TIMING_SIMUL 2
        +
        +#if 0
        +static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
        +	{
        +	clock_t clck;
        +	int i, j;
        +	BIGNUM *s;
        +	BIGNUM *r[10], *r0[10];
        +	EC_POINT *P;
        +		
        +	s = BN_new();
        +	if (s == NULL) ABORT;
        +
        +	fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
        +	if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
        +	fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
        +	fflush(stdout);
        +
        +	P = EC_POINT_new(group);
        +	if (P == NULL) ABORT;
        +	EC_POINT_copy(P, EC_GROUP_get0_generator(group));
        +
        +	for (i = 0; i < 10; i++)
        +		{
        +		if ((r[i] = BN_new()) == NULL) ABORT;
        +		if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
        +		if (type != TIMING_BASE_PT)
        +			{
        +			if ((r0[i] = BN_new()) == NULL) ABORT;
        +			if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
        +			}
        +		}
        +
        +	clck = clock();
        +	for (i = 0; i < 10; i++)
        +		{
        +		for (j = 0; j < 10; j++)
        +			{
        +			if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, 
        +				(type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
        +			}
        +		}
        +	clck = clock() - clck;
        +
        +	fprintf(stdout, "\n");
        +
        +#ifdef CLOCKS_PER_SEC
        +	/* "To determine the time in seconds, the value returned
        +	 * by the clock function should be divided by the value
        +	 * of the macro CLOCKS_PER_SEC."
        +	 *                                       -- ISO/IEC 9899 */
        +#	define UNIT "s"
        +#else
        +	/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
        +	 *                            -- cc on NeXTstep/OpenStep */
        +#	define UNIT "units"
        +#	define CLOCKS_PER_SEC 1
        +#endif
        +
        +	if (type == TIMING_BASE_PT) {
        +		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
        +			"base point multiplications", (double)clck/CLOCKS_PER_SEC);
        +	} else if (type == TIMING_RAND_PT) {
        +		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
        +			"random point multiplications", (double)clck/CLOCKS_PER_SEC);
        +	} else if (type == TIMING_SIMUL) {
        +		fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
        +			"s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
        +	}
        +	fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
        +
        +	EC_POINT_free(P);
        +	BN_free(s);
        +	for (i = 0; i < 10; i++)
        +		{
        +		BN_free(r[i]);
        +		if (type != TIMING_BASE_PT) BN_free(r0[i]);
        +		}
        +	}
        +#endif
        +
        +/* test multiplication with group order, long and negative scalars */
        +static void group_order_tests(EC_GROUP *group)
        +	{
        +	BIGNUM *n1, *n2, *order;
        +	EC_POINT *P = EC_POINT_new(group);
        +	EC_POINT *Q = EC_POINT_new(group);
        +	BN_CTX *ctx = BN_CTX_new();
        +
        +	n1 = BN_new(); n2 = BN_new(); order = BN_new();
        +	fprintf(stdout, "verify group order ...");
        +	fflush(stdout);
        +	if (!EC_GROUP_get_order(group, order, ctx)) ABORT;
        +	if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	fprintf(stdout, ".");
        +	fflush(stdout);
        +	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
        +	if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	fprintf(stdout, " ok\n");
        +	fprintf(stdout, "long/negative scalar tests ... ");
        +	if (!BN_one(n1)) ABORT;
        +	/* n1 = 1 - order */
        +	if (!BN_sub(n1, n1, order)) ABORT;
        +	if(!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
        +	/* n2 = 1 + order */
        +	if (!BN_add(n2, order, BN_value_one())) ABORT;
        +	if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
        +	/* n2 = (1 - order) * (1 + order) */
        +	if (!BN_mul(n2, n1, n2, ctx)) ABORT;
        +	if(!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, Q, P, ctx)) ABORT;
        +	fprintf(stdout, "ok\n");
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	BN_free(n1);
        +	BN_free(n2);
        +	BN_free(order);
        +	BN_CTX_free(ctx);
        +	}
        +
        +static void prime_field_tests(void)
        +	{
        +	BN_CTX *ctx = NULL;
        +	BIGNUM *p, *a, *b;
        +	EC_GROUP *group;
        +	EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
        +	EC_POINT *P, *Q, *R;
        +	BIGNUM *x, *y, *z;
        +	unsigned char buf[100];
        +	size_t i, len;
        +	int k;
        +	
        +#if 1 /* optional */
        +	ctx = BN_CTX_new();
        +	if (!ctx) ABORT;
        +#endif
        +
        +	p = BN_new();
        +	a = BN_new();
        +	b = BN_new();
        +	if (!p || !a || !b) ABORT;
        +
        +	if (!BN_hex2bn(&p, "17")) ABORT;
        +	if (!BN_hex2bn(&a, "1")) ABORT;
        +	if (!BN_hex2bn(&b, "1")) ABORT;
        +	
        +	group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
        +	                                             * so that the library gets to choose the EC_METHOD */
        +	if (!group) ABORT;
        +
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	{
        +		EC_GROUP *tmp;
        +		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
        +		if (!tmp) ABORT;
        +		if (!EC_GROUP_copy(tmp, group)) ABORT;
        +		EC_GROUP_free(group);
        +		group = tmp;
        +	}
        +	
        +	if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
        +	BN_print_fp(stdout, p);
        +	fprintf(stdout, ")\n     a = 0x");
        +	BN_print_fp(stdout, a);
        +	fprintf(stdout, "\n     b = 0x");
        +	BN_print_fp(stdout, b);
        +	fprintf(stdout, "\n");
        +
        +	P = EC_POINT_new(group);
        +	Q = EC_POINT_new(group);
        +	R = EC_POINT_new(group);
        +	if (!P || !Q || !R) ABORT;
        +	
        +	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	buf[0] = 0;
        +	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
        +
        +	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	x = BN_new();
        +	y = BN_new();
        +	z = BN_new();
        +	if (!x || !y || !z) ABORT;
        +
        +	if (!BN_hex2bn(&x, "D")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, Q, ctx))
        +		{
        +		if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
        +		fprintf(stderr, "Point is not on curve: x = 0x");
        +		BN_print_fp(stderr, x);
        +		fprintf(stderr, ", y = 0x");
        +		BN_print_fp(stderr, y);
        +		fprintf(stderr, "\n");
        +		ABORT;
        +		}
        +
        +	fprintf(stdout, "A cyclic subgroup:\n");
        +	k = 100;
        +	do
        +		{
        +		if (k-- == 0) ABORT;
        +
        +		if (EC_POINT_is_at_infinity(group, P))
        +			fprintf(stdout, "     point at infinity\n");
        +		else
        +			{
        +			if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +
        +			fprintf(stdout, "     x = 0x");
        +			BN_print_fp(stdout, x);
        +			fprintf(stdout, ", y = 0x");
        +			BN_print_fp(stdout, y);
        +			fprintf(stdout, "\n");
        +			}
        +		
        +		if (!EC_POINT_copy(R, P)) ABORT;
        +		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +
        +#if 0 /* optional */
        +		{
        +			EC_POINT *points[3];
        +		
        +			points[0] = R;
        +			points[1] = Q;
        +			points[2] = P;
        +			if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
        +		}
        +#endif
        +
        +		}
        +	while (!EC_POINT_is_at_infinity(group, P));
        +
        +	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +	if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
        +	fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, ", Y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, ", Z = 0x");
        +	BN_print_fp(stdout, z);
        +	fprintf(stdout, "\n");
        +
        +	if (!EC_POINT_invert(group, P, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +
        +
        +	/* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
        +	 * -- not a NIST curve, but commonly used */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
        +	if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
        +	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 160) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_160, group)) ABORT;
        +
        +
        +	/* Curve P-192 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 192) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_192, group)) ABORT;
        +
        +
        +	/* Curve P-224 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
        +	if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 224) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_224, group)) ABORT;
        +
        +
        +	/* Curve P-256 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
        +		"84F3B9CAC2FC632551")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 256) ABORT;
        +	fprintf(stdout, " ok\n");
        +	
        +	group_order_tests(group);
        +
        +	if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_256, group)) ABORT;
        +
        +
        +	/* Curve P-384 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
        +		"120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
        +		"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
        +		"7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 384) ABORT;
        +	fprintf(stdout, " ok\n");
        +
        +	group_order_tests(group);
        +
        +	if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_384, group)) ABORT;
        +
        +
        +	/* Curve P-521 (FIPS PUB 186-2, App. 6) */
        +	
        +	if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
        +	if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
        +		"315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
        +		"DF883D2C34F1EF451FD46B503F00")) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
        +
        +	if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
        +		"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
        +		"3C1856A429BF97E7E31C2E5BD66")) ABORT;
        +	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        +		"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
        +		"C9B8899C47AEBB6FB71E91386409")) ABORT;
        +	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
        +
        +	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
        +	fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
        +	BN_print_fp(stdout, x);
        +	fprintf(stdout, "\n     y = 0x");
        +	BN_print_fp(stdout, y);
        +	fprintf(stdout, "\n");
        +	/* G_y value taken from the standard: */
        +	if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
        +		"B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
        +		"7086A272C24088BE94769FD16650")) ABORT;
        +	if (0 != BN_cmp(y, z)) ABORT;
        +	
        +	fprintf(stdout, "verify degree ...");
        +	if (EC_GROUP_get_degree(group) != 521) ABORT;
        +	fprintf(stdout, " ok\n");
        +
        + 	group_order_tests(group);
        +
        +	if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
        +	if (!EC_GROUP_copy(P_521, group)) ABORT;
        +
        +
        +	/* more tests using the last curve */
        +
        +	if (!EC_POINT_copy(Q, P)) ABORT;
        +	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
        +
        +	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
        +
        +	{
        +		const EC_POINT *points[4];
        +		const BIGNUM *scalars[4];
        +		BIGNUM scalar3;
        +	
        +		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +		points[0] = Q;
        +		points[1] = Q;
        +		points[2] = Q;
        +		points[3] = Q;
        +
        +		if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
        +		if (!BN_add(y, z, BN_value_one())) ABORT;
        +		if (BN_is_odd(y)) ABORT;
        +		if (!BN_rshift1(y, y)) ABORT;
        +		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
        +		scalars[1] = y;
        +
        +		fprintf(stdout, "combined multiplication ...");
        +		fflush(stdout);
        +
        +		/* z is still the group order */
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
        +		if (!BN_add(z, z, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = y;
        +		scalars[1] = z; /* z = -(order + y) */
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
        +		if (!BN_add(z, x, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = x;
        +		scalars[1] = y;
        +		scalars[2] = z; /* z = -(x+y) */
        +
        +		BN_init(&scalar3);
        +		BN_zero(&scalar3);
        +		scalars[3] = &scalar3;
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, " ok\n\n");
        +
        +		BN_free(&scalar3);
        +	}
        +
        +
        +#if 0
        +	timings(P_160, TIMING_BASE_PT, ctx);
        +	timings(P_160, TIMING_RAND_PT, ctx);
        +	timings(P_160, TIMING_SIMUL, ctx);
        +	timings(P_192, TIMING_BASE_PT, ctx);
        +	timings(P_192, TIMING_RAND_PT, ctx);
        +	timings(P_192, TIMING_SIMUL, ctx);
        +	timings(P_224, TIMING_BASE_PT, ctx);
        +	timings(P_224, TIMING_RAND_PT, ctx);
        +	timings(P_224, TIMING_SIMUL, ctx);
        +	timings(P_256, TIMING_BASE_PT, ctx);
        +	timings(P_256, TIMING_RAND_PT, ctx);
        +	timings(P_256, TIMING_SIMUL, ctx);
        +	timings(P_384, TIMING_BASE_PT, ctx);
        +	timings(P_384, TIMING_RAND_PT, ctx);
        +	timings(P_384, TIMING_SIMUL, ctx);
        +	timings(P_521, TIMING_BASE_PT, ctx);
        +	timings(P_521, TIMING_RAND_PT, ctx);
        +	timings(P_521, TIMING_SIMUL, ctx);
        +#endif
        +
        +
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	BN_free(p); BN_free(a);	BN_free(b);
        +	EC_GROUP_free(group);
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	EC_POINT_free(R);
        +	BN_free(x); BN_free(y); BN_free(z);
        +
        +	if (P_160) EC_GROUP_free(P_160);
        +	if (P_192) EC_GROUP_free(P_192);
        +	if (P_224) EC_GROUP_free(P_224);
        +	if (P_256) EC_GROUP_free(P_256);
        +	if (P_384) EC_GROUP_free(P_384);
        +	if (P_521) EC_GROUP_free(P_521);
        +
        +	}
        +
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	if (!BN_hex2bn(&x, _x)) ABORT; \
        +	if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
        +	if (!BN_hex2bn(&z, _order)) ABORT; \
        +	if (!BN_hex2bn(&cof, _cof)) ABORT; \
        +	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
        +	if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
        +	fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
        +	BN_print_fp(stdout, x); \
        +	fprintf(stdout, "\n     y = 0x"); \
        +	BN_print_fp(stdout, y); \
        +	fprintf(stdout, "\n"); \
        +	/* G_y value taken from the standard: */ \
        +	if (!BN_hex2bn(&z, _y)) ABORT; \
        +	if (0 != BN_cmp(y, z)) ABORT;
        +#else 
        +#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	if (!BN_hex2bn(&x, _x)) ABORT; \
        +	if (!BN_hex2bn(&y, _y)) ABORT; \
        +	if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
        +	if (!BN_hex2bn(&z, _order)) ABORT; \
        +	if (!BN_hex2bn(&cof, _cof)) ABORT; \
        +	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
        +	fprintf(stdout, "\n%s -- Generator:\n     x = 0x", _name); \
        +	BN_print_fp(stdout, x); \
        +	fprintf(stdout, "\n     y = 0x"); \
        +	BN_print_fp(stdout, y); \
        +	fprintf(stdout, "\n");
        +#endif
        +
        +#define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	if (!BN_hex2bn(&p, _p)) ABORT; \
        +	if (!BN_hex2bn(&a, _a)) ABORT; \
        +	if (!BN_hex2bn(&b, _b)) ABORT; \
        +	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
        +	CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
        +	fprintf(stdout, "verify degree ..."); \
        +	if (EC_GROUP_get_degree(group) != _degree) ABORT; \
        +	fprintf(stdout, " ok\n"); \
        +	group_order_tests(group); \
        +	if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
        +	if (!EC_GROUP_copy(_variable, group)) ABORT; \
        +
        +#ifndef OPENSSL_NO_EC2M
        +
        +static void char2_field_tests(void)
        +	{
        +	BN_CTX *ctx = NULL;
        +	BIGNUM *p, *a, *b;
        +	EC_GROUP *group;
        +	EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
        +	EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
        +	EC_POINT *P, *Q, *R;
        +	BIGNUM *x, *y, *z, *cof;
        +	unsigned char buf[100];
        +	size_t i, len;
        +	int k;
        +	
        +#if 1 /* optional */
        +	ctx = BN_CTX_new();
        +	if (!ctx) ABORT;
        +#endif
        +
        +	p = BN_new();
        +	a = BN_new();
        +	b = BN_new();
        +	if (!p || !a || !b) ABORT;
        +
        +	if (!BN_hex2bn(&p, "13")) ABORT;
        +	if (!BN_hex2bn(&a, "3")) ABORT;
        +	if (!BN_hex2bn(&b, "1")) ABORT;
        +	
        +	group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
        +	                                                * so that the library gets to choose the EC_METHOD */
        +	if (!group) ABORT;
        +	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;
        +
        +	{
        +		EC_GROUP *tmp;
        +		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
        +		if (!tmp) ABORT;
        +		if (!EC_GROUP_copy(tmp, group)) ABORT;
        +		EC_GROUP_free(group);
        +		group = tmp;
        +	}
        +	
        +	if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;
        +
        +	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
        +	BN_print_fp(stdout, p);
        +	fprintf(stdout, ")\n     a = 0x");
        +	BN_print_fp(stdout, a);
        +	fprintf(stdout, "\n     b = 0x");
        +	BN_print_fp(stdout, b);
        +	fprintf(stdout, "\n(0x... means binary polynomial)\n");
        +
        +	P = EC_POINT_new(group);
        +	Q = EC_POINT_new(group);
        +	R = EC_POINT_new(group);
        +	if (!P || !Q || !R) ABORT;
        +	
        +	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	buf[0] = 0;
        +	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
        +
        +	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +	x = BN_new();
        +	y = BN_new();
        +	z = BN_new();
        +	cof = BN_new();
        +	if (!x || !y || !z || !cof) ABORT;
        +
        +	if (!BN_hex2bn(&x, "6")) ABORT;
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +	if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
        +#else
        +	if (!BN_hex2bn(&y, "8")) ABORT;
        +	if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
        +#endif
        +	if (!EC_POINT_is_on_curve(group, Q, ctx))
        +		{
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +		if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
        +#endif
        +		fprintf(stderr, "Point is not on curve: x = 0x");
        +		BN_print_fp(stderr, x);
        +		fprintf(stderr, ", y = 0x");
        +		BN_print_fp(stderr, y);
        +		fprintf(stderr, "\n");
        +		ABORT;
        +		}
        +
        +	fprintf(stdout, "A cyclic subgroup:\n");
        +	k = 100;
        +	do
        +		{
        +		if (k-- == 0) ABORT;
        +
        +		if (EC_POINT_is_at_infinity(group, P))
        +			fprintf(stdout, "     point at infinity\n");
        +		else
        +			{
        +			if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;
        +
        +			fprintf(stdout, "     x = 0x");
        +			BN_print_fp(stdout, x);
        +			fprintf(stdout, ", y = 0x");
        +			BN_print_fp(stdout, y);
        +			fprintf(stdout, "\n");
        +			}
        +		
        +		if (!EC_POINT_copy(R, P)) ABORT;
        +		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
        +		}
        +	while (!EC_POINT_is_at_infinity(group, P));
        +
        +	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +#endif
        +	
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +	
        +/* Change test based on whether binary point compression is enabled or not. */
        +#ifdef OPENSSL_EC_BIN_PT_COMP
        +	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
        +	if (len == 0) ABORT;
        +	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
        +	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
        +	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
        +#endif
        +
        +	fprintf(stdout, "\n");
        +	
        +	if (!EC_POINT_invert(group, P, ctx)) ABORT;
        +	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +
        +
        +	/* Curve K-163 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-163",
        +		"0800000000000000000000000000000000000000C9",
        +		"1",
        +		"1",
        +		"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
        +		"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
        +		1,
        +		"04000000000000000000020108A2E0CC0D99F8A5EF",
        +		"2",
        +		163,
        +		C2_K163
        +		);
        +
        +	/* Curve B-163 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-163",
        +		"0800000000000000000000000000000000000000C9",
        +		"1",
        +		"020A601907B8C953CA1481EB10512F78744A3205FD",
        +		"03F0EBA16286A2D57EA0991168D4994637E8343E36",
        +		"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
        +		1,
        +		"040000000000000000000292FE77E70C12A4234C33",
        +		"2",
        +		163,
        +		C2_B163
        +		);
        +
        +	/* Curve K-233 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-233",
        +		"020000000000000000000000000000000000000004000000000000000001",
        +		"0",
        +		"1",
        +		"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
        +		"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
        +		0,
        +		"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
        +		"4",
        +		233,
        +		C2_K233
        +		);
        +
        +	/* Curve B-233 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-233",
        +		"020000000000000000000000000000000000000004000000000000000001",
        +		"000000000000000000000000000000000000000000000000000000000001",
        +		"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
        +		"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
        +		"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
        +		1,
        +		"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
        +		"2",
        +		233,
        +		C2_B233
        +		);
        +
        +	/* Curve K-283 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-283",
        +		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
        +		"0",
        +		"1",
        +		"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
        +		"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
        +		0,
        +		"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
        +		"4",
        +		283,
        +		C2_K283
        +		);
        +
        +	/* Curve B-283 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-283",
        +		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
        +		"000000000000000000000000000000000000000000000000000000000000000000000001",
        +		"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
        +		"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
        +		"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
        +		1,
        +		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
        +		"2",
        +		283,
        +		C2_B283
        +		);
        +
        +	/* Curve K-409 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-409",
        +		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
        +		"0",
        +		"1",
        +		"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
        +		"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
        +		1,
        +		"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
        +		"4",
        +		409,
        +		C2_K409
        +		);
        +
        +	/* Curve B-409 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-409",
        +		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
        +		"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
        +		"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
        +		"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
        +		"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
        +		1,
        +		"010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
        +		"2",
        +		409,
        +		C2_B409
        +		);
        +
        +	/* Curve K-571 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve K-571",
        +		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
        +		"0",
        +		"1",
        +		"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
        +		"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
        +		0,
        +		"020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
        +		"4",
        +		571,
        +		C2_K571
        +		);
        +
        +	/* Curve B-571 (FIPS PUB 186-2, App. 6) */
        +	CHAR2_CURVE_TEST
        +		(
        +		"NIST curve B-571",
        +		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
        +		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
        +		"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
        +		"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
        +		"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
        +		1,
        +		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
        +		"2",
        +		571,
        +		C2_B571
        +		);
        +
        +	/* more tests using the last curve */
        +
        +	if (!EC_POINT_copy(Q, P)) ABORT;
        +	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
        +	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
        +	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
        +
        +	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
        +	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
        +	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
        +
        +	{
        +		const EC_POINT *points[3];
        +		const BIGNUM *scalars[3];
        +	
        +		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
        +		points[0] = Q;
        +		points[1] = Q;
        +		points[2] = Q;
        +
        +		if (!BN_add(y, z, BN_value_one())) ABORT;
        +		if (BN_is_odd(y)) ABORT;
        +		if (!BN_rshift1(y, y)) ABORT;
        +		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
        +		scalars[1] = y;
        +
        +		fprintf(stdout, "combined multiplication ...");
        +		fflush(stdout);
        +
        +		/* z is still the group order */
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
        +		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
        +		if (!BN_add(z, z, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = y;
        +		scalars[1] = z; /* z = -(order + y) */
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +
        +		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
        +		if (!BN_add(z, x, y)) ABORT;
        +		BN_set_negative(z, 1);
        +		scalars[0] = x;
        +		scalars[1] = y;
        +		scalars[2] = z; /* z = -(x+y) */
        +
        +		if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
        +		if (!EC_POINT_is_at_infinity(group, P)) ABORT;
        +
        +		fprintf(stdout, " ok\n\n");
        +	}
        +
        +
        +#if 0
        +	timings(C2_K163, TIMING_BASE_PT, ctx);
        +	timings(C2_K163, TIMING_RAND_PT, ctx);
        +	timings(C2_K163, TIMING_SIMUL, ctx);
        +	timings(C2_B163, TIMING_BASE_PT, ctx);
        +	timings(C2_B163, TIMING_RAND_PT, ctx);
        +	timings(C2_B163, TIMING_SIMUL, ctx);
        +	timings(C2_K233, TIMING_BASE_PT, ctx);
        +	timings(C2_K233, TIMING_RAND_PT, ctx);
        +	timings(C2_K233, TIMING_SIMUL, ctx);
        +	timings(C2_B233, TIMING_BASE_PT, ctx);
        +	timings(C2_B233, TIMING_RAND_PT, ctx);
        +	timings(C2_B233, TIMING_SIMUL, ctx);
        +	timings(C2_K283, TIMING_BASE_PT, ctx);
        +	timings(C2_K283, TIMING_RAND_PT, ctx);
        +	timings(C2_K283, TIMING_SIMUL, ctx);
        +	timings(C2_B283, TIMING_BASE_PT, ctx);
        +	timings(C2_B283, TIMING_RAND_PT, ctx);
        +	timings(C2_B283, TIMING_SIMUL, ctx);
        +	timings(C2_K409, TIMING_BASE_PT, ctx);
        +	timings(C2_K409, TIMING_RAND_PT, ctx);
        +	timings(C2_K409, TIMING_SIMUL, ctx);
        +	timings(C2_B409, TIMING_BASE_PT, ctx);
        +	timings(C2_B409, TIMING_RAND_PT, ctx);
        +	timings(C2_B409, TIMING_SIMUL, ctx);
        +	timings(C2_K571, TIMING_BASE_PT, ctx);
        +	timings(C2_K571, TIMING_RAND_PT, ctx);
        +	timings(C2_K571, TIMING_SIMUL, ctx);
        +	timings(C2_B571, TIMING_BASE_PT, ctx);
        +	timings(C2_B571, TIMING_RAND_PT, ctx);
        +	timings(C2_B571, TIMING_SIMUL, ctx);
        +#endif
        +
        +
        +	if (ctx)
        +		BN_CTX_free(ctx);
        +	BN_free(p); BN_free(a);	BN_free(b);
        +	EC_GROUP_free(group);
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	EC_POINT_free(R);
        +	BN_free(x); BN_free(y); BN_free(z); BN_free(cof);
        +
        +	if (C2_K163) EC_GROUP_free(C2_K163);
        +	if (C2_B163) EC_GROUP_free(C2_B163);
        +	if (C2_K233) EC_GROUP_free(C2_K233);
        +	if (C2_B233) EC_GROUP_free(C2_B233);
        +	if (C2_K283) EC_GROUP_free(C2_K283);
        +	if (C2_B283) EC_GROUP_free(C2_B283);
        +	if (C2_K409) EC_GROUP_free(C2_K409);
        +	if (C2_B409) EC_GROUP_free(C2_B409);
        +	if (C2_K571) EC_GROUP_free(C2_K571);
        +	if (C2_B571) EC_GROUP_free(C2_B571);
        +
        +	}
        +#endif
        +
        +static void internal_curve_test(void)
        +	{
        +	EC_builtin_curve *curves = NULL;
        +	size_t crv_len = 0, n = 0;
        +	int    ok = 1;
        +
        +	crv_len = EC_get_builtin_curves(NULL, 0);
        +
        +	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
        +
        +	if (curves == NULL)
        +		return;
        +
        +	if (!EC_get_builtin_curves(curves, crv_len))
        +		{
        +		OPENSSL_free(curves);
        +		return;
        +		}
        +
        +	fprintf(stdout, "testing internal curves: ");
        +		
        +	for (n = 0; n < crv_len; n++)
        +		{
        +		EC_GROUP *group = NULL;
        +		int nid = curves[n].nid;
        +		if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
        +			{
        +			ok = 0;
        +			fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
        +				" curve %s\n", OBJ_nid2sn(nid));
        +			/* try next curve */
        +			continue;
        +			}
        +		if (!EC_GROUP_check(group, NULL))
        +			{
        +			ok = 0;
        +			fprintf(stdout, "\nEC_GROUP_check() failed with"
        +				" curve %s\n", OBJ_nid2sn(nid));
        +			EC_GROUP_free(group);
        +			/* try the next curve */
        +			continue;
        +			}
        +		fprintf(stdout, ".");
        +		fflush(stdout);
        +		EC_GROUP_free(group);
        +		}
        +	if (ok)
        +		fprintf(stdout, " ok\n\n");
        +	else
        +		{
        +		fprintf(stdout, " failed\n\n");
        +		ABORT;
        +		}
        +	OPENSSL_free(curves);
        +	return;
        +	}
        +
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +/* nistp_test_params contains magic numbers for testing our optimized
        + * implementations of several NIST curves with characteristic > 3. */
        +struct nistp_test_params
        +	{
        +	const EC_METHOD* (*meth) ();
        +	int degree;
        +	/* Qx, Qy and D are taken from
        +	 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
        +	 * Otherwise, values are standard curve parameters from FIPS 180-3 */
        +	const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
        +	};
        +
        +static const struct nistp_test_params nistp_tests_params[] =
        +	{
        +		{
        +		/* P-224 */
        +		EC_GFp_nistp224_method,
        +		224,
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* p */
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* a */
        +		"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* b */
        +		"E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", /* Qx */
        +		"4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", /* Qy */
        +		"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
        +		"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
        +		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
        +		"3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", /* d */
        +		},
        +		{
        +		/* P-256 */
        +		EC_GFp_nistp256_method,
        +		256,
        +		"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", /* p */
        +		"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", /* a */
        +		"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", /* b */
        +		"b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", /* Qx */
        +		"3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", /* Qy */
        +		"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", /* Gx */
        +		"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", /* Gy */
        +		"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", /* order */
        +		"c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", /* d */
        +		},
        +		{
        +		/* P-521 */
        +		EC_GFp_nistp521_method,
        +		521,
        +		"1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", /* p */
        +		"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", /* a */
        +		"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", /* b */
        +		"0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", /* Qx */
        +		"0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", /* Qy */
        +		"c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", /* Gx */
        +		"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", /* Gy */
        +		"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", /* order */
        +		"0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", /* d */
        +		},
        +	};
        +
        +void nistp_single_test(const struct nistp_test_params *test)
        +	{
        +	BN_CTX *ctx;
        +	BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
        +	EC_GROUP *NISTP;
        +	EC_POINT *G, *P, *Q, *Q_CHECK;
        +
        +	fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree);
        +	ctx = BN_CTX_new();
        +	p = BN_new();
        +	a = BN_new();
        +	b = BN_new();
        +	x = BN_new(); y = BN_new();
        +	m = BN_new(); n = BN_new(); order = BN_new();
        +
        +	NISTP = EC_GROUP_new(test->meth());
        +	if(!NISTP) ABORT;
        +	if (!BN_hex2bn(&p, test->p)) ABORT;
        +	if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
        +	if (!BN_hex2bn(&a, test->a)) ABORT;
        +	if (!BN_hex2bn(&b, test->b)) ABORT;
        +	if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) ABORT;
        +	G = EC_POINT_new(NISTP);
        +	P = EC_POINT_new(NISTP);
        +	Q = EC_POINT_new(NISTP);
        +	Q_CHECK = EC_POINT_new(NISTP);
        +	if(!BN_hex2bn(&x, test->Qx)) ABORT;
        +	if(!BN_hex2bn(&y, test->Qy)) ABORT;
        +	if(!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) ABORT;
        +	if (!BN_hex2bn(&x, test->Gx)) ABORT;
        +	if (!BN_hex2bn(&y, test->Gy)) ABORT;
        +	if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) ABORT;
        +	if (!BN_hex2bn(&order, test->order)) ABORT;
        +	if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
        +
        +	fprintf(stdout, "verify degree ... ");
        +	if (EC_GROUP_get_degree(NISTP) != test->degree) ABORT;
        +	fprintf(stdout, "ok\n");
        +
        +	fprintf(stdout, "NIST test vectors ... ");
        +	if (!BN_hex2bn(&n, test->d)) ABORT;
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	/* set generator to P = 2*G, where G is the standard generator */
        +	if (!EC_POINT_dbl(NISTP, P, G, ctx)) ABORT;
        +	if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) ABORT;
        +	/* set the scalar to m=n/2, where n is the NIST test scalar */
        +	if (!BN_rshift(m, n, 1)) ABORT;
        +
        +	/* test the non-standard generator */
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	/* now repeat all tests with precomputation */
        +	if (!EC_GROUP_precompute_mult(NISTP, ctx)) ABORT;
        +
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	/* reset generator */
        +	if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) ABORT;
        +	/* fixed point multiplication */
        +	EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +	/* random point multiplication */
        +	EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
        +	if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) ABORT;
        +
        +	fprintf(stdout, "ok\n");
        +	group_order_tests(NISTP);
        +#if 0
        +	timings(NISTP, TIMING_BASE_PT, ctx);
        +	timings(NISTP, TIMING_RAND_PT, ctx);
        +#endif
        +	EC_GROUP_free(NISTP);
        +	EC_POINT_free(G);
        +	EC_POINT_free(P);
        +	EC_POINT_free(Q);
        +	EC_POINT_free(Q_CHECK);
        +	BN_free(n);
        +	BN_free(m);
        +	BN_free(p);
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(x);
        +	BN_free(y);
        +	BN_free(order);
        +	BN_CTX_free(ctx);
        +	}
        +
        +void nistp_tests()
        +	{
        +	unsigned i;
        +
        +	for (i = 0; i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); i++)
        +		{
        +		nistp_single_test(&nistp_tests_params[i]);
        +		}
        +	}
        +#endif
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +	{	
        +	
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +	ERR_load_crypto_strings();
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
        +
        +	prime_field_tests();
        +	puts("");
        +#ifndef OPENSSL_NO_EC2M
        +	char2_field_tests();
        +#endif
        +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
        +	nistp_tests();
        +#endif
        +	/* test the internal curves */
        +	internal_curve_test();
        +
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_cleanup();
        +#endif
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_free_strings();
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks_fp(stderr);
        +	
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/enginetest.c b/vendor/openssl/openssl/test/enginetest.c
        new file mode 100644
        index 000000000..f4d70e7e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/enginetest.c
        @@ -0,0 +1,283 @@
        +/* crypto/engine/enginetest.c */
        +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
        + * project 2000.
        + */
        +/* ====================================================================
        + * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    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 <stdio.h>
        +#include <string.h>
        +#include <openssl/e_os2.h>
        +
        +#ifdef OPENSSL_NO_ENGINE
        +int main(int argc, char *argv[])
        +{
        +    printf("No ENGINE support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/buffer.h>
        +#include <openssl/crypto.h>
        +#include <openssl/engine.h>
        +#include <openssl/err.h>
        +
        +static void display_engine_list(void)
        +	{
        +	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");
        +	/* ENGINE_get_first() increases the struct_ref counter, so we 
        +           must call ENGINE_free() to decrease it again */
        +	ENGINE_free(h);
        +	}
        +
        +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;
        +
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +	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;
        +		}
        +	if (ptr)
        +		ENGINE_free(ptr);
        +	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");
        +	ERR_clear_error();
        +	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");
        +	if (ptr)
        +		ENGINE_free(ptr);
        +	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 = BUF_strdup(buf);
        +		sprintf(buf, "Fake engine type %i", loop);
        +		name = BUF_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;
        +			}
        +		ENGINE_free(ptr);
        +		printf("."); fflush(stdout);
        +		}
        +	for(loop = 0; loop < 512; loop++)
        +		{
        +		OPENSSL_free((void *)ENGINE_get_id(block[loop]));
        +		OPENSSL_free((void *)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]);
        +	ENGINE_cleanup();
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_free_strings();
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks_fp(stderr);
        +	return to_return;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/evp_test.c b/vendor/openssl/openssl/test/evp_test.c
        new file mode 100644
        index 000000000..55c7cdfdc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/evp_test.c
        @@ -0,0 +1,450 @@
        +/* Written by Ben Laurie, 2001 */
        +/*
        + * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
        + *
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + *
        + * 1. Redistributions of source code must retain the above copyright
        + *    notice, this list of conditions and the following disclaimer. 
        + *
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in
        + *    the documentation and/or other materials provided with the
        + *    distribution.
        + *
        + * 3. All advertising materials mentioning features or use of this
        + *    software must display the following acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
        + *
        + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
        + *    endorse or promote products derived from this software without
        + *    prior written permission. For written permission, please contact
        + *    openssl-core@openssl.org.
        + *
        + * 5. Products derived from this software may not be called "OpenSSL"
        + *    nor may "OpenSSL" appear in their names without prior written
        + *    permission of the OpenSSL Project.
        + *
        + * 6. Redistributions of any form whatsoever must retain the following
        + *    acknowledgment:
        + *    "This product includes software developed by the OpenSSL Project
        + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
        + *
        + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
        + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
        + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
        + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
        + * OF THE POSSIBILITY OF SUCH DAMAGE.
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/opensslconf.h>
        +#include <openssl/evp.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/conf.h>
        +
        +static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
        +    {
        +    int n=0;
        +
        +    fprintf(f,"%s",title);
        +    for( ; n < l ; ++n)
        +	{
        +	if((n%16) == 0)
        +	    fprintf(f,"\n%04x",n);
        +	fprintf(f," %02x",s[n]);
        +	}
        +    fprintf(f,"\n");
        +    }
        +
        +static int convert(unsigned char *s)
        +    {
        +    unsigned char *d;
        +
        +    for(d=s ; *s ; s+=2,++d)
        +	{
        +	unsigned int n;
        +
        +	if(!s[1])
        +	    {
        +	    fprintf(stderr,"Odd number of hex digits!");
        +	    EXIT(4);
        +	    }
        +	sscanf((char *)s,"%2x",&n);
        +	*d=(unsigned char)n;
        +	}
        +    return s-d;
        +    }
        +
        +static char *sstrsep(char **string, const char *delim)
        +    {
        +    char isdelim[256];
        +    char *token = *string;
        +
        +    if (**string == 0)
        +        return NULL;
        +
        +    memset(isdelim, 0, 256);
        +    isdelim[0] = 1;
        +
        +    while (*delim)
        +        {
        +        isdelim[(unsigned char)(*delim)] = 1;
        +        delim++;
        +        }
        +
        +    while (!isdelim[(unsigned char)(**string)])
        +        {
        +        (*string)++;
        +        }
        +
        +    if (**string)
        +        {
        +        **string = 0;
        +        (*string)++;
        +        }
        +
        +    return token;
        +    }
        +
        +static unsigned char *ustrsep(char **p,const char *sep)
        +    { return (unsigned char *)sstrsep(p,sep); }
        +
        +static int test1_exit(int ec)
        +	{
        +	EXIT(ec);
        +	return(0);		/* To keep some compilers quiet */
        +	}
        +
        +static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
        +		  const unsigned char *iv,int in,
        +		  const unsigned char *plaintext,int pn,
        +		  const unsigned char *ciphertext,int cn,
        +		  int encdec)
        +    {
        +    EVP_CIPHER_CTX ctx;
        +    unsigned char out[4096];
        +    int outl,outl2;
        +
        +    printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
        +	   (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
        +    hexdump(stdout,"Key",key,kn);
        +    if(in)
        +	hexdump(stdout,"IV",iv,in);
        +    hexdump(stdout,"Plaintext",plaintext,pn);
        +    hexdump(stdout,"Ciphertext",ciphertext,cn);
        +    
        +    if(kn != c->key_len)
        +	{
        +	fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn,
        +		(unsigned long)c->key_len);
        +	test1_exit(5);
        +	}
        +    EVP_CIPHER_CTX_init(&ctx);
        +    if (encdec != 0)
        +        {
        +	if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
        +	    {
        +	    fprintf(stderr,"EncryptInit failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(10);
        +	    }
        +	EVP_CIPHER_CTX_set_padding(&ctx,0);
        +
        +	if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
        +	    {
        +	    fprintf(stderr,"Encrypt failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(6);
        +	    }
        +	if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
        +	    {
        +	    fprintf(stderr,"EncryptFinal failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(7);
        +	    }
        +
        +	if(outl+outl2 != cn)
        +	    {
        +	    fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
        +		    outl+outl2,cn);
        +	    test1_exit(8);
        +	    }
        +
        +	if(memcmp(out,ciphertext,cn))
        +	    {
        +	    fprintf(stderr,"Ciphertext mismatch\n");
        +	    hexdump(stderr,"Got",out,cn);
        +	    hexdump(stderr,"Expected",ciphertext,cn);
        +	    test1_exit(9);
        +	    }
        +	}
        +
        +    if (encdec <= 0)
        +        {
        +	if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
        +	    {
        +	    fprintf(stderr,"DecryptInit failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(11);
        +	    }
        +	EVP_CIPHER_CTX_set_padding(&ctx,0);
        +
        +	if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
        +	    {
        +	    fprintf(stderr,"Decrypt failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(6);
        +	    }
        +	if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
        +	    {
        +	    fprintf(stderr,"DecryptFinal failed\n");
        +	    ERR_print_errors_fp(stderr);
        +	    test1_exit(7);
        +	    }
        +
        +	if(outl+outl2 != pn)
        +	    {
        +	    fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
        +		    outl+outl2,pn);
        +	    test1_exit(8);
        +	    }
        +
        +	if(memcmp(out,plaintext,pn))
        +	    {
        +	    fprintf(stderr,"Plaintext mismatch\n");
        +	    hexdump(stderr,"Got",out,pn);
        +	    hexdump(stderr,"Expected",plaintext,pn);
        +	    test1_exit(9);
        +	    }
        +	}
        +
        +    EVP_CIPHER_CTX_cleanup(&ctx);
        +
        +    printf("\n");
        +    }
        +
        +static int test_cipher(const char *cipher,const unsigned char *key,int kn,
        +		       const unsigned char *iv,int in,
        +		       const unsigned char *plaintext,int pn,
        +		       const unsigned char *ciphertext,int cn,
        +		       int encdec)
        +    {
        +    const EVP_CIPHER *c;
        +
        +    c=EVP_get_cipherbyname(cipher);
        +    if(!c)
        +	return 0;
        +
        +    test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec);
        +
        +    return 1;
        +    }
        +
        +static int test_digest(const char *digest,
        +		       const unsigned char *plaintext,int pn,
        +		       const unsigned char *ciphertext, unsigned int cn)
        +    {
        +    const EVP_MD *d;
        +    EVP_MD_CTX ctx;
        +    unsigned char md[EVP_MAX_MD_SIZE];
        +    unsigned int mdn;
        +
        +    d=EVP_get_digestbyname(digest);
        +    if(!d)
        +	return 0;
        +
        +    printf("Testing digest %s\n",EVP_MD_name(d));
        +    hexdump(stdout,"Plaintext",plaintext,pn);
        +    hexdump(stdout,"Digest",ciphertext,cn);
        +
        +    EVP_MD_CTX_init(&ctx);
        +    if(!EVP_DigestInit_ex(&ctx,d, NULL))
        +	{
        +	fprintf(stderr,"DigestInit failed\n");
        +	ERR_print_errors_fp(stderr);
        +	EXIT(100);
        +	}
        +    if(!EVP_DigestUpdate(&ctx,plaintext,pn))
        +	{
        +	fprintf(stderr,"DigestUpdate failed\n");
        +	ERR_print_errors_fp(stderr);
        +	EXIT(101);
        +	}
        +    if(!EVP_DigestFinal_ex(&ctx,md,&mdn))
        +	{
        +	fprintf(stderr,"DigestFinal failed\n");
        +	ERR_print_errors_fp(stderr);
        +	EXIT(101);
        +	}
        +    EVP_MD_CTX_cleanup(&ctx);
        +
        +    if(mdn != cn)
        +	{
        +	fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn);
        +	EXIT(102);
        +	}
        +
        +    if(memcmp(md,ciphertext,cn))
        +	{
        +	fprintf(stderr,"Digest mismatch\n");
        +	hexdump(stderr,"Got",md,cn);
        +	hexdump(stderr,"Expected",ciphertext,cn);
        +	EXIT(103);
        +	}
        +
        +    printf("\n");
        +
        +    EVP_MD_CTX_cleanup(&ctx);
        +
        +    return 1;
        +    }
        +
        +int main(int argc,char **argv)
        +    {
        +    const char *szTestFile;
        +    FILE *f;
        +
        +    if(argc != 2)
        +	{
        +	fprintf(stderr,"%s <test file>\n",argv[0]);
        +	EXIT(1);
        +	}
        +    CRYPTO_malloc_debug_init();
        +    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +    szTestFile=argv[1];
        +
        +    f=fopen(szTestFile,"r");
        +    if(!f)
        +	{
        +	perror(szTestFile);
        +	EXIT(2);
        +	}
        +
        +    /* Load up the software EVP_CIPHER and EVP_MD definitions */
        +    OpenSSL_add_all_ciphers();
        +    OpenSSL_add_all_digests();
        +#ifndef OPENSSL_NO_ENGINE
        +    /* Load all compiled-in ENGINEs */
        +    ENGINE_load_builtin_engines();
        +#endif
        +#if 0
        +    OPENSSL_config();
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +    /* Register all available ENGINE implementations of ciphers and digests.
        +     * This could perhaps be changed to "ENGINE_register_all_complete()"? */
        +    ENGINE_register_all_ciphers();
        +    ENGINE_register_all_digests();
        +    /* If we add command-line options, this statement should be switchable.
        +     * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
        +     * they weren't already initialised. */
        +    /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
        +#endif
        +
        +    for( ; ; )
        +	{
        +	char line[4096];
        +	char *p;
        +	char *cipher;
        +	unsigned char *iv,*key,*plaintext,*ciphertext;
        +	int encdec;
        +	int kn,in,pn,cn;
        +
        +	if(!fgets((char *)line,sizeof line,f))
        +	    break;
        +	if(line[0] == '#' || line[0] == '\n')
        +	    continue;
        +	p=line;
        +	cipher=sstrsep(&p,":");	
        +	key=ustrsep(&p,":");
        +	iv=ustrsep(&p,":");
        +	plaintext=ustrsep(&p,":");
        +	ciphertext=ustrsep(&p,":");
        +	if (p[-1] == '\n') {
        +	    p[-1] = '\0';
        +	    encdec = -1;
        +	} else {
        +	    encdec = atoi(sstrsep(&p,"\n"));
        +	}
        +	      
        +
        +	kn=convert(key);
        +	in=convert(iv);
        +	pn=convert(plaintext);
        +	cn=convert(ciphertext);
        +
        +	if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
        +	   && !test_digest(cipher,plaintext,pn,ciphertext,cn))
        +	    {
        +#ifdef OPENSSL_NO_AES
        +	    if (strstr(cipher, "AES") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_DES
        +	    if (strstr(cipher, "DES") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_RC4
        +	    if (strstr(cipher, "RC4") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_CAMELLIA
        +	    if (strstr(cipher, "CAMELLIA") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +#ifdef OPENSSL_NO_SEED
        +	    if (strstr(cipher, "SEED") == cipher)
        +		{
        +		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
        +		continue;
        +		}
        +#endif
        +	    fprintf(stderr,"Can't find %s\n",cipher);
        +	    EXIT(3);
        +	    }
        +	}
        +	fclose(f);
        +
        +#ifndef OPENSSL_NO_ENGINE
        +    ENGINE_cleanup();
        +#endif
        +    EVP_cleanup();
        +    CRYPTO_cleanup_all_ex_data();
        +    ERR_remove_thread_state(NULL);
        +    ERR_free_strings();
        +    CRYPTO_mem_leaks_fp(stderr);
        +
        +    return 0;
        +    }
        diff --git a/vendor/openssl/openssl/test/evptests.txt b/vendor/openssl/openssl/test/evptests.txt
        new file mode 100644
        index 000000000..c273707c1
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/evptests.txt
        @@ -0,0 +1,334 @@
        +#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt)
        +#digest:::input:output
        +
        +# SHA(1) tests (from shatest.c)
        +SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d
        +
        +# MD5 tests (from md5test.c)
        +MD5::::d41d8cd98f00b204e9800998ecf8427e
        +MD5:::61:0cc175b9c0f1b6a831c399e269772661
        +MD5:::616263:900150983cd24fb0d6963f7d28e17f72
        +MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0
        +MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b
        +MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f
        +MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a
        +
        +# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
        +
        +AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
        +
        +# AES 192 ECB tests (from FIPS-197 test vectors, encrypt)
        +
        +AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
        +
        +# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
        +
        +AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
        +
        +# AES 128 ECB tests (from NIST test vectors, encrypt)
        +
        +#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1
        +
        +# AES 128 ECB tests (from NIST test vectors, decrypt)
        +
        +#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0
        +
        +# AES 192 ECB tests (from NIST test vectors, decrypt)
        +
        +#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0
        +
        +# AES 256 ECB tests (from NIST test vectors, decrypt)
        +
        +#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0
        +
        +# AES 128 CBC tests (from NIST test vectors, encrypt)
        +
        +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1
        +
        +# AES 192 CBC tests (from NIST test vectors, encrypt)
        +
        +#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1
        +
        +# AES 256 CBC tests (from NIST test vectors, encrypt)
        +
        +#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1
        +
        +# AES 128 CBC tests (from NIST test vectors, decrypt)
        +
        +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0
        +
        +# AES tests from NIST document SP800-38A
        +# For all ECB encrypts and decrypts, the transformed sequence is
        +#   AES-bits-ECB:key::plaintext:ciphertext:encdec
        +# ECB-AES128.Encrypt and ECB-AES128.Decrypt
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
        +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
        +# ECB-AES192.Encrypt and ECB-AES192.Decrypt 
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
        +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
        +# ECB-AES256.Encrypt and ECB-AES256.Decrypt 
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
        +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
        +# For all CBC encrypts and decrypts, the transformed sequence is
        +#   AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CBC-AES128.Encrypt and CBC-AES128.Decrypt 
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
        +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
        +# CBC-AES192.Encrypt and CBC-AES192.Decrypt 
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
        +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
        +# CBC-AES256.Encrypt and CBC-AES256.Decrypt 
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
        +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
        +# We don't support CFB{1,8}-AESxxx.{En,De}crypt
        +# For all CFB128 encrypts and decrypts, the transformed sequence is
        +#   AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CFB128-AES128.Encrypt 
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
        +# CFB128-AES128.Decrypt 
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
        +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0
        +# CFB128-AES192.Encrypt
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1
        +# CFB128-AES192.Decrypt
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
        +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
        +# CFB128-AES256.Encrypt 
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
        +# CFB128-AES256.Decrypt 
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
        +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
        +# For all OFB encrypts and decrypts, the transformed sequence is
        +#   AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
        +# OFB-AES128.Encrypt 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 
        +# OFB-AES128.Decrypt 
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
        +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
        +# OFB-AES192.Encrypt 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 
        +# OFB-AES192.Decrypt 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 
        +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 
        +# OFB-AES256.Encrypt 
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
        +# OFB-AES256.Decrypt 
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
        +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
        +
        +# AES Counter test vectors from RFC3686
        +aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
        +aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
        +aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
        +
        +aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1
        +aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1
        +aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1
        +
        +aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
        +aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
        +aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
        +
        +# DES ECB tests (from destest)
        +
        +DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
        +DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58
        +DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B
        +DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533
        +DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D
        +DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD
        +DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4
        +
        +# DESX-CBC tests (from destest)
        +DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4
        +
        +# DES EDE3 CBC tests (from destest)
        +DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
        +
        +# RC4 tests (from rc4test)
        +RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
        +RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
        +RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
        +RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
        +RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
        +RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
        +
        +
        +# Camellia tests from RFC3713
        +# For all ECB encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec
        +CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43
        +CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9
        +CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509
        +
        +# ECB-CAMELLIA128.Encrypt
        +CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1
        +CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
        +CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
        +
        +# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt 
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
        +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
        +
        +# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt 
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
        +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
        +
        +# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt 
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
        +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B
        +
        +# For all CBC encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt 
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
        +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
        +
        +# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt 
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
        +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
        +
        +# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt 
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
        +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F
        +
        +# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
        +# For all CFB128 encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
        +# CFB128-CAMELLIA128.Encrypt 
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
        +
        +# CFB128-CAMELLIA128.Decrypt 
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
        +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0
        +
        +# CFB128-CAMELLIA192.Encrypt
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1
        +
        +# CFB128-CAMELLIA192.Decrypt
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
        +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
        +
        +# CFB128-CAMELLIA256.Encrypt 
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
        +
        +# CFB128-CAMELLIA256.Decrypt 
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
        +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0
        +
        +# For all OFB encrypts and decrypts, the transformed sequence is
        +#   CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
        +# OFB-CAMELLIA128.Encrypt 
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
        +
        +# OFB-CAMELLIA128.Decrypt 
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
        +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
        +
        +# OFB-CAMELLIA192.Encrypt 
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
        +
        +# OFB-CAMELLIA192.Decrypt 
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
        +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
        +
        +# OFB-CAMELLIA256.Encrypt 
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
        +
        +# OFB-CAMELLIA256.Decrypt 
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
        +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0
        +
        +# SEED test vectors from RFC4269
        +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0
        +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0
        +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0
        +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0
        +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1
        +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1
        +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1
        +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1
        diff --git a/vendor/openssl/openssl/test/exptest.c b/vendor/openssl/openssl/test/exptest.c
        new file mode 100644
        index 000000000..074a8e882
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/exptest.c
        @@ -0,0 +1,204 @@
        +/* crypto/bn/exptest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#include <openssl/bio.h>
        +#include <openssl/bn.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +#define NUM_BITS	(BN_BITS*2)
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +	{
        +	BN_CTX *ctx;
        +	BIO *out=NULL;
        +	int i,ret;
        +	unsigned char c;
        +	BIGNUM *r_mont,*r_mont_const,*r_recp,*r_simple,*a,*b,*m;
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
        +	                                       * even check its return value
        +	                                       * (which we should) */
        +
        +	ERR_load_BN_strings();
        +
        +	ctx=BN_CTX_new();
        +	if (ctx == NULL) EXIT(1);
        +	r_mont=BN_new();
        +	r_mont_const=BN_new();
        +	r_recp=BN_new();
        +	r_simple=BN_new();
        +	a=BN_new();
        +	b=BN_new();
        +	m=BN_new();
        +	if (	(r_mont == NULL) || (r_recp == NULL) ||
        +		(a == NULL) || (b == NULL))
        +		goto err;
        +
        +	out=BIO_new(BIO_s_file());
        +
        +	if (out == NULL) EXIT(1);
        +	BIO_set_fp(out,stdout,BIO_NOCLOSE);
        +
        +	for (i=0; i<200; i++)
        +		{
        +		RAND_bytes(&c,1);
        +		c=(c%BN_BITS)-BN_BITS2;
        +		BN_rand(a,NUM_BITS+c,0,0);
        +
        +		RAND_bytes(&c,1);
        +		c=(c%BN_BITS)-BN_BITS2;
        +		BN_rand(b,NUM_BITS+c,0,0);
        +
        +		RAND_bytes(&c,1);
        +		c=(c%BN_BITS)-BN_BITS2;
        +		BN_rand(m,NUM_BITS+c,0,1);
        +
        +		BN_mod(a,a,m,ctx);
        +		BN_mod(b,b,m,ctx);
        +
        +		ret=BN_mod_exp_mont(r_mont,a,b,m,ctx,NULL);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_mont() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		ret=BN_mod_exp_recp(r_recp,a,b,m,ctx);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_recp() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		ret=BN_mod_exp_simple(r_simple,a,b,m,ctx);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_simple() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		ret=BN_mod_exp_mont_consttime(r_mont_const,a,b,m,ctx,NULL);
        +		if (ret <= 0)
        +			{
        +			printf("BN_mod_exp_mont_consttime() problems\n");
        +			ERR_print_errors(out);
        +			EXIT(1);
        +			}
        +
        +		if (BN_cmp(r_simple, r_mont) == 0
        +		    && BN_cmp(r_simple,r_recp) == 0
        +			&& BN_cmp(r_simple,r_mont_const) == 0)
        +			{
        +			printf(".");
        +			fflush(stdout);
        +			}
        +		else
        +		  	{
        +			if (BN_cmp(r_simple,r_mont) != 0)
        +				printf("\nsimple and mont results differ\n");
        +			if (BN_cmp(r_simple,r_mont_const) != 0)
        +				printf("\nsimple and mont const time results differ\n");
        +			if (BN_cmp(r_simple,r_recp) != 0)
        +				printf("\nsimple and recp results differ\n");
        +
        +			printf("a (%3d) = ",BN_num_bits(a));   BN_print(out,a);
        +			printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b);
        +			printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m);
        +			printf("\nsimple   =");	BN_print(out,r_simple);
        +			printf("\nrecp     =");	BN_print(out,r_recp);
        +			printf("\nmont     ="); BN_print(out,r_mont);
        +			printf("\nmont_ct  ="); BN_print(out,r_mont_const);
        +			printf("\n");
        +			EXIT(1);
        +			}
        +		}
        +	BN_free(r_mont);
        +	BN_free(r_mont_const);
        +	BN_free(r_recp);
        +	BN_free(r_simple);
        +	BN_free(a);
        +	BN_free(b);
        +	BN_free(m);
        +	BN_CTX_free(ctx);
        +	ERR_remove_thread_state(NULL);
        +	CRYPTO_mem_leaks(out);
        +	BIO_free(out);
        +	printf(" done\n");
        +	EXIT(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors(out);
        +#ifdef OPENSSL_SYS_NETWARE
        +    printf("ERROR\n");
        +#endif
        +	EXIT(1);
        +	return(1);
        +	}
        +
        diff --git a/vendor/openssl/openssl/test/hmactest.c b/vendor/openssl/openssl/test/hmactest.c
        new file mode 100644
        index 000000000..1b906b81a
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/hmactest.c
        @@ -0,0 +1,175 @@
        +/* crypto/hmac/hmactest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_HMAC
        +int main(int argc, char *argv[])
        +{
        +    printf("No HMAC support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/hmac.h>
        +#ifndef OPENSSL_NO_MD5
        +#include <openssl/md5.h>
        +#endif
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +#ifndef OPENSSL_NO_MD5
        +static struct test_st
        +	{
        +	unsigned char key[16];
        +	int key_len;
        +	unsigned char data[64];
        +	int data_len;
        +	unsigned char *digest;
        +	} test[4]={
        +	{	"",
        +		0,
        +		"More text test vectors to stuff up EBCDIC machines :-)",
        +		54,
        +		(unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
        +	},{	{0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
        +		 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
        +		16,
        +		"Hi There",
        +		8,
        +		(unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
        +	},{	"Jefe",
        +		4,
        +		"what do ya want for nothing?",
        +		28,
        +		(unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
        +	},{
        +		{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
        +		 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
        +		16,
        +		{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
        +		 0xdd,0xdd},
        +		50,
        +		(unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
        +	},
        +	};
        +#endif
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +#ifndef OPENSSL_NO_MD5
        +	int i;
        +	char *p;
        +#endif
        +	int err=0;
        +
        +#ifdef OPENSSL_NO_MD5
        +	printf("test skipped: MD5 disabled\n");
        +#else
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
        +	ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
        +	ebcdic2ascii(test[2].key,  test[2].key,  test[2].key_len);
        +	ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
        +#endif
        +
        +	for (i=0; i<4; i++)
        +		{
        +		p=pt(HMAC(EVP_md5(),
        +			test[i].key, test[i].key_len,
        +			test[i].data, test[i].data_len,
        +			NULL,NULL));
        +
        +		if (strcmp(p,(char *)test[i].digest) != 0)
        +			{
        +			printf("error calculating HMAC on %d entry'\n",i);
        +			printf("got %s instead of %s\n",p,test[i].digest);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		}
        +#endif /* OPENSSL_NO_MD5 */
        +	EXIT(err);
        +	return(0);
        +	}
        +
        +#ifndef OPENSSL_NO_MD5
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<MD5_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/test/ideatest.c b/vendor/openssl/openssl/test/ideatest.c
        new file mode 100644
        index 000000000..e6ffc7025
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/ideatest.c
        @@ -0,0 +1,235 @@
        +/* crypto/idea/ideatest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_IDEA
        +int main(int argc, char *argv[])
        +{
        +    printf("No IDEA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/idea.h>
        +
        +unsigned char k[16]={
        +	0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
        +	0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
        +
        +unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
        +unsigned char  c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
        +unsigned char out[80];
        +
        +char *text="Hello to all people out there";
        +
        +static unsigned char cfb_key[16]={
        +	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
        +	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
        +	};
        +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +#define CFB_TEST_SIZE 24
        +static unsigned char plain[CFB_TEST_SIZE]=
        +        {
        +        0x4e,0x6f,0x77,0x20,0x69,0x73,
        +        0x20,0x74,0x68,0x65,0x20,0x74,
        +        0x69,0x6d,0x65,0x20,0x66,0x6f,
        +        0x72,0x20,0x61,0x6c,0x6c,0x20
        +        };
        +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
        +	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
        +	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
        +	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
        +
        +/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
        +	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
        +	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
        +	}; 
        +
        +static int cfb64_test(unsigned char *cfb_cipher);
        +static char *pt(unsigned char *p);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	IDEA_KEY_SCHEDULE key,dkey; 
        +	unsigned char iv[8];
        +
        +	idea_set_encrypt_key(k,&key);
        +	idea_ecb_encrypt(in,out,&key);
        +	if (memcmp(out,c,8) != 0)
        +		{
        +		printf("ecb idea error encrypting\n");
        +		printf("got     :");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",out[i]);
        +		printf("\n");
        +		printf("expected:");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",c[i]);
        +		err=20;
        +		printf("\n");
        +		}
        +
        +	idea_set_decrypt_key(&key,&dkey);
        +	idea_ecb_encrypt(c,out,&dkey);
        +	if (memcmp(out,in,8) != 0)
        +		{
        +		printf("ecb idea error decrypting\n");
        +		printf("got     :");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",out[i]);
        +		printf("\n");
        +		printf("expected:");
        +		for (i=0; i<8; i++)
        +			printf("%02X ",in[i]);
        +		printf("\n");
        +		err=3;
        +		}
        +
        +	if (err == 0) printf("ecb idea ok\n");
        +
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt(out,out,8,&dkey,iv,0);
        +	idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
        +	if (memcmp(text,out,strlen(text)+1) != 0)
        +		{
        +		printf("cbc idea bad\n");
        +		err=4;
        +		}
        +	else
        +		printf("cbc idea ok\n");
        +
        +	printf("cfb64 idea ");
        +	if (cfb64_test(cfb_cipher64))
        +		{
        +		printf("bad\n");
        +		err=5;
        +		}
        +	else
        +		printf("ok\n");
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(err);
        +	}
        +
        +static int cfb64_test(unsigned char *cfb_cipher)
        +        {
        +        IDEA_KEY_SCHEDULE eks,dks;
        +        int err=0,i,n;
        +
        +        idea_set_encrypt_key(cfb_key,&eks);
        +        idea_set_decrypt_key(&eks,&dks);
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +                (long)CFB_TEST_SIZE-12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb64_encrypt encrypt error\n");
        +                for (i=0; i<CFB_TEST_SIZE; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf1[i])));
        +                }
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +                (long)CFB_TEST_SIZE-17,&dks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb_encrypt decrypt error\n");
        +                for (i=0; i<24; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf2[i])));
        +                }
        +        return(err);
        +        }
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/igetest.c b/vendor/openssl/openssl/test/igetest.c
        new file mode 100644
        index 000000000..1ba900244
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/igetest.c
        @@ -0,0 +1,503 @@
        +/* test/igetest.c -*- mode:C; c-file-style: "eay" -*- */
        +/* ====================================================================
        + * Copyright (c) 2006 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.
        + * ====================================================================
        + *
        + */
        +
        +#include <openssl/aes.h>
        +#include <openssl/rand.h>
        +#include <stdio.h>
        +#include <string.h>
        +#include <assert.h>
        +
        +#define TEST_SIZE	128
        +#define BIG_TEST_SIZE 10240
        +
        +static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
        +    {
        +    int n=0;
        +
        +    fprintf(f,"%s",title);
        +    for( ; n < l ; ++n)
        +		{
        +		if((n%16) == 0)
        +			fprintf(f,"\n%04x",n);
        +		fprintf(f," %02x",s[n]);
        +		}
        +    fprintf(f,"\n");
        +    }
        +
        +#define MAX_VECTOR_SIZE	64
        +
        +struct ige_test
        +	{
        +	const unsigned char key[16];
        +	const unsigned char iv[32];
        +	const unsigned char in[MAX_VECTOR_SIZE];
        +	const unsigned char out[MAX_VECTOR_SIZE];
        +	const size_t length;
        +	const int encrypt;
        +	};
        +
        +static struct ige_test const ige_test_vectors[] = {
        +{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key */
        +  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
        +    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        +    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* iv */
        +  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* in */
        +  { 0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
        +    0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
        +    0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
        +    0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb }, /* out */
        +  32, AES_ENCRYPT }, /* test vector 0 */
        +
        +{ { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
        +    0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65 }, /* key */
        +  { 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
        +    0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
        +    0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
        +    0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53 }, /* iv */
        +  { 0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
        +    0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
        +    0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
        +    0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a }, /* in */
        +  { 0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
        +    0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
        +    0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
        +    0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b }, /* out */
        +  32, AES_DECRYPT }, /* test vector 1 */
        +};
        +
        +struct bi_ige_test
        +	{
        +	const unsigned char key1[32];
        +	const unsigned char key2[32];
        +	const unsigned char iv[64];
        +	const unsigned char in[MAX_VECTOR_SIZE];
        +	const unsigned char out[MAX_VECTOR_SIZE];
        +	const size_t keysize;
        +	const size_t length;
        +	const int encrypt;
        +	};
        +
        +static struct bi_ige_test const bi_ige_test_vectors[] = {
        +{ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* key1 */
        +  { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        +    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* key2 */
        +  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        +    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
        +    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        +    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
        +    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
        +    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
        +    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        +    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f }, /* iv */
        +  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* in */
        +  { 0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
        +	0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
        +	0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
        +	0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12 }, /* out */
        +  16, 32, AES_ENCRYPT }, /* test vector 0 */
        +{ { 0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
        +	0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
        +	0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
        +	0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37 }, /* key1 */
        +  { 0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
        +	0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
        +	0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
        +	0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4 }, /* key2 */
        +  { 0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
        +	0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
        +	0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
        +	0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
        +	0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
        +	0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
        +	0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
        +	0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3 }, /* iv */
        +  { 0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
        +	0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
        +	0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
        +	0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
        +	0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
        +	0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
        +	0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
        +	0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
        +  { 0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
        +	0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
        +	0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
        +	0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
        +	0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
        +	0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
        +	0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
        +	0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
        +  32, 64, AES_ENCRYPT }, /* test vector 1 */
        +
        +};
        +
        +static int run_test_vectors(void)
        +	{
        +	unsigned int n;
        +	int errs = 0;
        +
        +	for(n=0 ; n < sizeof(ige_test_vectors)/sizeof(ige_test_vectors[0]) ; ++n)
        +		{
        +		const struct ige_test * const v = &ige_test_vectors[n];
        +		AES_KEY key;
        +		unsigned char buf[MAX_VECTOR_SIZE];
        +		unsigned char iv[AES_BLOCK_SIZE*2];
        +
        +		assert(v->length <= MAX_VECTOR_SIZE);
        +
        +		if(v->encrypt == AES_ENCRYPT)
        +			AES_set_encrypt_key(v->key, 8*sizeof v->key, &key);
        +		else
        +			AES_set_decrypt_key(v->key, 8*sizeof v->key, &key);
        +		memcpy(iv, v->iv, sizeof iv);
        +		AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
        +
        +		if(memcmp(v->out, buf, v->length))
        +			{
        +			printf("IGE test vector %d failed\n", n);
        +			hexdump(stdout, "key", v->key, sizeof v->key);
        +			hexdump(stdout, "iv", v->iv, sizeof v->iv);
        +			hexdump(stdout, "in", v->in, v->length);
        +			hexdump(stdout, "expected", v->out, v->length);
        +			hexdump(stdout, "got", buf, v->length);
        +
        +			++errs;
        +			}
        +
        +                /* try with in == out */
        +		memcpy(iv, v->iv, sizeof iv);
        +                memcpy(buf, v->in, v->length);
        +		AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
        +
        +		if(memcmp(v->out, buf, v->length))
        +			{
        +			printf("IGE test vector %d failed (with in == out)\n", n);
        +			hexdump(stdout, "key", v->key, sizeof v->key);
        +			hexdump(stdout, "iv", v->iv, sizeof v->iv);
        +			hexdump(stdout, "in", v->in, v->length);
        +			hexdump(stdout, "expected", v->out, v->length);
        +			hexdump(stdout, "got", buf, v->length);
        +
        +			++errs;
        +			}
        +		}
        +
        +	for(n=0 ; n < sizeof(bi_ige_test_vectors)/sizeof(bi_ige_test_vectors[0])
        +			; ++n)
        +		{
        +		const struct bi_ige_test * const v = &bi_ige_test_vectors[n];
        +		AES_KEY key1;
        +		AES_KEY key2;
        +		unsigned char buf[MAX_VECTOR_SIZE];
        +
        +		assert(v->length <= MAX_VECTOR_SIZE);
        +
        +		if(v->encrypt == AES_ENCRYPT)
        +			{
        +			AES_set_encrypt_key(v->key1, 8*v->keysize, &key1);
        +			AES_set_encrypt_key(v->key2, 8*v->keysize, &key2);
        +			}
        +		else
        +			{
        +			AES_set_decrypt_key(v->key1, 8*v->keysize, &key1);
        +			AES_set_decrypt_key(v->key2, 8*v->keysize, &key2);
        +			}
        +
        +		AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
        +						   v->encrypt);
        +
        +		if(memcmp(v->out, buf, v->length))
        +			{
        +			printf("Bidirectional IGE test vector %d failed\n", n);
        +			hexdump(stdout, "key 1", v->key1, sizeof v->key1);
        +			hexdump(stdout, "key 2", v->key2, sizeof v->key2);
        +			hexdump(stdout, "iv", v->iv, sizeof v->iv);
        +			hexdump(stdout, "in", v->in, v->length);
        +			hexdump(stdout, "expected", v->out, v->length);
        +			hexdump(stdout, "got", buf, v->length);
        +
        +			++errs;
        +			}
        +		}
        +
        +	return errs;
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	unsigned char rkey[16];
        +	unsigned char rkey2[16];
        +	AES_KEY key;
        +	AES_KEY key2;
        +	unsigned char plaintext[BIG_TEST_SIZE];
        +	unsigned char ciphertext[BIG_TEST_SIZE];
        +	unsigned char checktext[BIG_TEST_SIZE];
        +	unsigned char iv[AES_BLOCK_SIZE*4];
        +	unsigned char saved_iv[AES_BLOCK_SIZE*4];
        +	int err = 0;
        +	unsigned int n;
        +	unsigned matches;
        +
        +	assert(BIG_TEST_SIZE >= TEST_SIZE);
        +
        +	RAND_pseudo_bytes(rkey, sizeof rkey);
        +	RAND_pseudo_bytes(plaintext, sizeof plaintext);
        +	RAND_pseudo_bytes(iv, sizeof iv);
        +	memcpy(saved_iv, iv, sizeof saved_iv);
        +
        +	/* Forward IGE only... */
        +
        +	/* Straight encrypt/decrypt */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv,
        +					AES_ENCRYPT);
        +
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv,
        +					AES_DECRYPT);
        +
        +	if(memcmp(checktext, plaintext, TEST_SIZE))
        +		{
        +		printf("Encrypt+decrypt doesn't match\n");
        +		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
        +		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
        +		++err;
        +		}
        +
        +	/* Now check encrypt chaining works */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv,
        +					AES_ENCRYPT);
        +	AES_ige_encrypt(plaintext+TEST_SIZE/2,
        +					ciphertext+TEST_SIZE/2, TEST_SIZE/2,
        +					&key, iv, AES_ENCRYPT);
        +
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv,
        +					AES_DECRYPT);
        +
        +	if(memcmp(checktext, plaintext, TEST_SIZE))
        +		{
        +		printf("Chained encrypt+decrypt doesn't match\n");
        +		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
        +		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
        +		++err;
        +		}
        +
        +	/* And check decrypt chaining */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE/2, &key, iv,
        +					AES_ENCRYPT);
        +	AES_ige_encrypt(plaintext+TEST_SIZE/2,
        +					ciphertext+TEST_SIZE/2, TEST_SIZE/2,
        +					&key, iv, AES_ENCRYPT);
        +
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(ciphertext, checktext, TEST_SIZE/2, &key, iv,
        +					AES_DECRYPT);
        +	AES_ige_encrypt(ciphertext+TEST_SIZE/2,
        +					checktext+TEST_SIZE/2, TEST_SIZE/2, &key, iv,
        +					AES_DECRYPT);
        +
        +	if(memcmp(checktext, plaintext, TEST_SIZE))
        +		{
        +		printf("Chained encrypt+chained decrypt doesn't match\n");
        +		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
        +		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
        +		++err;
        +		}
        +
        +	/* make sure garble extends forwards only */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
        +					AES_ENCRYPT);
        +
        +	/* corrupt halfway through */
        +	++ciphertext[sizeof ciphertext/2];
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	memcpy(iv, saved_iv, sizeof iv);
        +	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
        +					AES_DECRYPT);
        +
        +	matches=0;
        +	for(n=0 ; n < sizeof checktext ; ++n)
        +		if(checktext[n] == plaintext[n])
        +			++matches;
        +
        +	if(matches > sizeof checktext/2+sizeof checktext/100)
        +		{
        +		printf("More than 51%% matches after garbling\n");
        +		++err;
        +		}
        +
        +	if(matches < sizeof checktext/2)
        +		{
        +		printf("Garble extends backwards!\n");
        +		++err;
        +		}
        +
        +	/* Bi-directional IGE */
        +
        +	/* Note that we don't have to recover the IV, because chaining isn't */
        +	/* possible with biIGE, so the IV is not updated. */
        +
        +	RAND_pseudo_bytes(rkey2, sizeof rkey2);
        +
        +	/* Straight encrypt/decrypt */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
        +					   AES_ENCRYPT);
        +
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
        +					   AES_DECRYPT);
        +
        +	if(memcmp(checktext, plaintext, TEST_SIZE))
        +		{
        +		printf("Encrypt+decrypt doesn't match\n");
        +		hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
        +		hexdump(stdout, "Checktext", checktext, TEST_SIZE);
        +		++err;
        +		}
        +
        +	/* make sure garble extends both ways */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
        +					AES_ENCRYPT);
        +
        +	/* corrupt halfway through */
        +	++ciphertext[sizeof ciphertext/2];
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
        +					AES_DECRYPT);
        +
        +	matches=0;
        +	for(n=0 ; n < sizeof checktext ; ++n)
        +		if(checktext[n] == plaintext[n])
        +			++matches;
        +
        +	if(matches > sizeof checktext/100)
        +		{
        +		printf("More than 1%% matches after bidirectional garbling\n");
        +		++err;
        +		}
        +
        +	/* make sure garble extends both ways (2) */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
        +					AES_ENCRYPT);
        +
        +	/* corrupt right at the end */
        +	++ciphertext[sizeof ciphertext-1];
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
        +					AES_DECRYPT);
        +
        +	matches=0;
        +	for(n=0 ; n < sizeof checktext ; ++n)
        +		if(checktext[n] == plaintext[n])
        +			++matches;
        +
        +	if(matches > sizeof checktext/100)
        +		{
        +		printf("More than 1%% matches after bidirectional garbling (2)\n");
        +		++err;
        +		}
        +
        +	/* make sure garble extends both ways (3) */
        +	AES_set_encrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_encrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
        +					AES_ENCRYPT);
        +
        +	/* corrupt right at the start */
        +	++ciphertext[0];
        +	AES_set_decrypt_key(rkey, 8*sizeof rkey, &key);
        +	AES_set_decrypt_key(rkey2, 8*sizeof rkey2, &key2);
        +	AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
        +					AES_DECRYPT);
        +
        +	matches=0;
        +	for(n=0 ; n < sizeof checktext ; ++n)
        +		if(checktext[n] == plaintext[n])
        +			++matches;
        +
        +	if(matches > sizeof checktext/100)
        +		{
        +		printf("More than 1%% matches after bidirectional garbling (3)\n");
        +		++err;
        +		}
        +
        +	err += run_test_vectors();
        +
        +	return err;
        +	}
        diff --git a/vendor/openssl/openssl/test/jpaketest.c b/vendor/openssl/openssl/test/jpaketest.c
        new file mode 100644
        index 000000000..5b4467e04
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/jpaketest.c
        @@ -0,0 +1,48 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/buffer.h>
        +#include <openssl/crypto.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *p, *q = 0, *program;
        +
        +	p = strrchr(argv[0], '/');
        +	if (!p) p = strrchr(argv[0], '\\');
        +#ifdef OPENSSL_SYS_VMS
        +	if (!p) p = strrchr(argv[0], ']');
        +	if (p) q = strrchr(p, '>');
        +	if (q) p = q;
        +	if (!p) p = strrchr(argv[0], ':');
        +	q = 0;
        +#endif
        +	if (p) p++;
        +	if (!p) p = argv[0];
        +	if (p) q = strchr(p, '.');
        +	if (p && !q) q = p + strlen(p);
        +
        +	if (!p)
        +		program = BUF_strdup("(unknown)");
        +	else
        +		{
        +		program = OPENSSL_malloc((q - p) + 1);
        +		strncpy(program, p, q - p);
        +		program[q - p] = '\0';
        +		}
        +
        +	for(p = program; *p; p++)
        +		if (islower((unsigned char)(*p)))
        +			*p = toupper((unsigned char)(*p));
        +
        +	q = strstr(program, "TEST");
        +	if (q > p && q[-1] == '_') q--;
        +	*q = '\0';
        +
        +	printf("No %s support\n", program);
        +
        +	OPENSSL_free(program);
        +	return(0);
        +	}
        diff --git a/vendor/openssl/openssl/test/maketests.com b/vendor/openssl/openssl/test/maketests.com
        new file mode 100644
        index 000000000..9b64cba23
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/maketests.com
        @@ -0,0 +1,1087 @@
        +$!
        +$!  MAKETESTS.COM
        +$!  Written By:  Robert Byer
        +$!               Vice-President
        +$!               A-Com Computing, Inc.
        +$!               byer@mail.all-net.net
        +$!
        +$!  Changes by Richard Levitte <richard@levitte.org>
        +$!
        +$!  This command files compiles and creates all the various different
        +$!  "test" programs for the different types of encryption for OpenSSL.
        +$!  It was written so it would try to determine what "C" compiler to
        +$!  use or you can specify which "C" compiler to use.
        +$!
        +$!  The test "executables" will be placed in a directory called
        +$!  [.xxx.EXE.TEST] where "xxx" denotes ALPHA, IA64, or VAX, depending
        +$!  on your machine architecture.
        +$!
        +$!  Specify DEBUG or NODEBUG P1 to compile with or without debugger
        +$!  information.
        +$!
        +$!  Specify which compiler at P2 to try to compile under.
        +$!
        +$!	   VAXC	 For VAX C.
        +$!	   DECC	 For DEC C.
        +$!	   GNUC	 For GNU C.
        +$!
        +$!  If you don't specify a compiler, it will try to determine which
        +$!  "C" compiler to use.
        +$!
        +$!  P3, if defined, sets a TCP/IP library to use, through one of the following
        +$!  keywords:
        +$!
        +$!	UCX		for UCX
        +$!	SOCKETSHR	for SOCKETSHR+NETLIB
        +$!
        +$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
        +$!
        +$!
        +$!  P5, if defined, specifies the C pointer size.  Ignored on VAX.
        +$!      ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
        +$!      Supported values are:
        +$!
        +$!      ""       Compile with default (/NOPOINTER_SIZE)
        +$!      32       Compile with /POINTER_SIZE=32 (SHORT)
        +$!      64       Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
        +$!               (Automatically select ARGV if compiler supports it.)
        +$!      64=      Compile with /POINTER_SIZE=64 (LONG).
        +$!      64=ARGV  Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
        +$!
        +$!  P6, if defined, specifies a directory where ZLIB files (zlib.h,
        +$!  libz.olb) may be found.  Optionally, a non-default object library
        +$!  name may be included ("dev:[dir]libz_64.olb", for example).
        +$!
        +$!
        +$! Announce/identify.
        +$!
        +$ proc = f$environment( "procedure")
        +$ write sys$output "@@@ "+ -
        +   f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$! Define A TCP/IP Library That We Will Need To Link To.
        +$! (That is, If We Need To Link To One.)
        +$!
        +$ TCPIP_LIB = ""
        +$ ZLIB_LIB = ""
        +$!
        +$! Check Which Architecture We Are Using.
        +$!
        +$ if (f$getsyi( "cpu") .lt. 128)
        +$ then
        +$    ARCH = "VAX"
        +$ else
        +$    ARCH = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$    if (ARCH .eqs. "") then ARCH = "UNK"
        +$ endif
        +$!
        +$ ARCHD = ARCH
        +$ LIB32 = "32"
        +$ OPT_FILE = ""
        +$ POINTER_SIZE = ""
        +$!
        +$! Check To Make Sure We Have Valid Command Line Parameters.
        +$!
        +$ GOSUB CHECK_OPTIONS
        +$!
        +$! Define The OBJ and EXE Directories.
        +$!
        +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.TEST]
        +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.TEST]
        +$!
        +$! Specify the destination directory in any /MAP option.
        +$!
        +$ if (LINKMAP .eqs. "MAP")
        +$ then
        +$   LINKMAP = LINKMAP+ "=''EXE_DIR'"
        +$ endif
        +$!
        +$! Add the location prefix to the linker options file name.
        +$!
        +$ if (OPT_FILE .nes. "")
        +$ then
        +$   OPT_FILE = EXE_DIR+ OPT_FILE
        +$ endif
        +$!
        +$! Initialise logical names and such
        +$!
        +$ GOSUB INITIALISE
        +$!
        +$! Tell The User What Kind of Machine We Run On.
        +$!
        +$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
        +$!
        +$! Define The CRYPTO-LIB We Are To Use.
        +$!
        +$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
        +$!
        +$! Define The SSL We Are To Use.
        +$!
        +$ SSL_LIB := SYS$DISK:[-.'ARCHD'.EXE.SSL]SSL_LIBSSL'LIB32'.OLB
        +$!
        +$! Create the OBJ and EXE Directories, if needed.
        +$!
        +$ IF (F$PARSE(OBJ_DIR).EQS."") THEN -
        +   CREATE /DIRECTORY 'OBJ_DIR'
        +$ IF (F$PARSE(EXE_DIR).EQS."") THEN -
        +   CREATE /DIRECTORY 'EXE_DIR'
        +$!
        +$! Check To See If We Have The Proper Libraries.
        +$!
        +$ GOSUB LIB_CHECK
        +$!
        +$! Check To See If We Have A Linker Option File.
        +$!
        +$ GOSUB CHECK_OPT_FILE
        +$!
        +$! Define The TEST Files.
        +$! NOTE: Some might think this list ugly.  However, it's made this way to
        +$! reflect the EXE variable in Makefile as closely as possible,
        +$! thereby making it fairly easy to verify that the lists are the same.
        +$!
        +$ TEST_FILES = "BNTEST,ECTEST,ECDSATEST,ECDHTEST,IDEATEST,"+ -
        +	       "MD2TEST,MD4TEST,MD5TEST,HMACTEST,WP_TEST,"+ -
        +	       "RC2TEST,RC4TEST,RC5TEST,"+ -
        +	       "DESTEST,SHATEST,SHA1TEST,SHA256T,SHA512T,"+ -
        +	       "MDC2TEST,RMDTEST,"+ -
        +	       "RANDTEST,DHTEST,ENGINETEST,"+ -
        +	       "BFTEST,CASTTEST,SSLTEST,EXPTEST,DSATEST,RSA_TEST,"+ -
        +	       "EVP_TEST,IGETEST,JPAKETEST,SRPTEST,"+ -
        +	       "ASN1TEST"
        +$! Should we add MTTEST,PQ_TEST,LH_TEST,DIVTEST,TABTEST as well?
        +$!
        +$! Additional directory information.
        +$ T_D_BNTEST     := [-.crypto.bn]
        +$ T_D_ECTEST     := [-.crypto.ec]
        +$ T_D_ECDSATEST  := [-.crypto.ecdsa]
        +$ T_D_ECDHTEST   := [-.crypto.ecdh]
        +$ T_D_IDEATEST   := [-.crypto.idea]
        +$ T_D_MD2TEST    := [-.crypto.md2]
        +$ T_D_MD4TEST    := [-.crypto.md4]
        +$ T_D_MD5TEST    := [-.crypto.md5]
        +$ T_D_HMACTEST   := [-.crypto.hmac]
        +$ T_D_WP_TEST    := [-.crypto.whrlpool]
        +$ T_D_RC2TEST    := [-.crypto.rc2]
        +$ T_D_RC4TEST    := [-.crypto.rc4]
        +$ T_D_RC5TEST    := [-.crypto.rc5]
        +$ T_D_DESTEST    := [-.crypto.des]
        +$ T_D_SHATEST    := [-.crypto.sha]
        +$ T_D_SHA1TEST   := [-.crypto.sha]
        +$ T_D_SHA256T    := [-.crypto.sha]
        +$ T_D_SHA512T    := [-.crypto.sha]
        +$ T_D_MDC2TEST   := [-.crypto.mdc2]
        +$ T_D_RMDTEST    := [-.crypto.ripemd]
        +$ T_D_RANDTEST   := [-.crypto.rand]
        +$ T_D_DHTEST     := [-.crypto.dh]
        +$ T_D_ENGINETEST := [-.crypto.engine]
        +$ T_D_BFTEST     := [-.crypto.bf]
        +$ T_D_CASTTEST   := [-.crypto.cast]
        +$ T_D_SSLTEST    := [-.ssl]
        +$ T_D_EXPTEST    := [-.crypto.bn]
        +$ T_D_DSATEST    := [-.crypto.dsa]
        +$ T_D_RSA_TEST   := [-.crypto.rsa]
        +$ T_D_EVP_TEST   := [-.crypto.evp]
        +$ T_D_IGETEST    := [-.test]
        +$ T_D_JPAKETEST  := [-.crypto.jpake]
        +$ T_D_SRPTEST    := [-.crypto.srp]
        +$ T_D_ASN1TEST   := [-.test]
        +$!
        +$ TCPIP_PROGRAMS = ",,"
        +$ IF COMPILER .EQS. "VAXC" THEN -
        +     TCPIP_PROGRAMS = ",SSLTEST,"
        +$!
        +$! Define A File Counter And Set It To "0".
        +$!
        +$ FILE_COUNTER = 0
        +$!
        +$! Top Of The File Loop.
        +$!
        +$ NEXT_FILE:
        +$!
        +$! O.K, Extract The File Name From The File List.
        +$!
        +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",TEST_FILES)
        +$!
        +$! Check To See If We Are At The End Of The File List.
        +$!
        +$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
        +$!
        +$! Increment The Counter.
        +$!
        +$ FILE_COUNTER = FILE_COUNTER + 1
        +$!
        +$! Create The Source File Name.
        +$!
        +$ SOURCE_FILE = "SYS$DISK:" + T_D_'FILE_NAME' + FILE_NAME + ".C"
        +$!
        +$! Create The Object File Name.
        +$!
        +$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
        +$!
        +$! Create The Executable File Name.
        +$!
        +$ EXE_FILE = EXE_DIR + FILE_NAME + ".EXE"
        +$ ON WARNING THEN GOTO NEXT_FILE
        +$!
        +$! Check To See If The File We Want To Compile Actually Exists.
        +$!
        +$ IF (F$SEARCH(SOURCE_FILE).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User That The File Dosen't Exist.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Exit The Build.
        +$!
        +$   GOTO EXIT
        +$ ENDIF
        +$!
        +$! Tell The User What We Are Building.
        +$!
        +$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Test Program."
        +$!
        +$! Compile The File.
        +$!
        +$ ON ERROR THEN GOTO NEXT_FILE
        +$ CC /OBJECT='OBJECT_FILE' 'SOURCE_FILE'
        +$ ON WARNING THEN GOTO NEXT_FILE
        +$!
        +$! Check If What We Are About To Compile Works Without A TCP/IP Library.
        +$!
        +$ IF ((TCPIP_LIB.EQS."").AND.((TCPIP_PROGRAMS-FILE_NAME).NES.TCPIP_PROGRAMS))
        +$ THEN
        +$!
        +$!  Inform The User That A TCP/IP Library Is Needed To Compile This Program.
        +$!
        +$   WRITE SYS$OUTPUT -
        +	  FILE_NAME," Needs A TCP/IP Library.  Can't Link.  Skipping..."
        +$   GOTO NEXT_FILE
        +$!
        +$! End The TCP/IP Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Link The Program, Check To See If We Need To Link With RSAREF Or Not.
        +$! Check To See If We Are To Link With A Specific TCP/IP Library.
        +$!
        +$!  Don't Link With The RSAREF Routines And TCP/IP Library.
        +$!
        +$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXECTABLE = 'EXE_FILE' -
        +   'OBJECT_FILE', -
        +   'SSL_LIB' /LIBRARY, -
        +   'CRYPTO_LIB' /LIBRARY -
        +   'TCPIP_LIB' -
        +   'ZLIB_LIB' -
        +   ,'OPT_FILE' /OPTIONS
        +$!
        +$! Go Back And Do It Again.
        +$!
        +$ GOTO NEXT_FILE
        +$!
        +$! All Done With This Library Part.
        +$!
        +$ FILE_DONE:
        +$!
        +$! All Done, Time To Exit.
        +$!
        +$ EXIT:
        +$ GOSUB CLEANUP
        +$ EXIT
        +$!
        +$! Check For The Link Option FIle.
        +$!
        +$ CHECK_OPT_FILE:
        +$!
        +$! Check To See If We Need To Make A VAX C Option File.
        +$!
        +$ IF (COMPILER.EQS."VAXC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A VAX C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A VAX C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable VAX C Runtime Library.
        +!
        +SYS$SHARE:VAXCRTL.EXE /SHAREABLE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The VAXC Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A GNU C Option File.
        +$!
        +$ IF (COMPILER.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A GNU C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    We Need A GNU C Linker Option File.
        +$!
        +$     CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +GNU_CC:[000000]GCCLIB.OLB /LIBRARY
        +SYS$SHARE:VAXCRTL.EXE /SHAREABLE
        +$EOD
        +$!
        +$!  End The Option File Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The GNU C Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Need A DEC C Option File.
        +$!
        +$ IF (COMPILER.EQS."DECC")
        +$ THEN
        +$!
        +$!  Check To See If We Already Have A DEC C Linker Option File.
        +$!
        +$   IF (F$SEARCH(OPT_FILE).EQS."")
        +$   THEN
        +$!
        +$!    Figure Out If We Need A non-VAX Or A VAX Linker Option File.
        +$!
        +$     IF (ARCH.EQS."VAX")
        +$     THEN
        +$!
        +$!      We Need A DEC C Linker Option File For VAX.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File To Link Against 
        +! The Sharable DEC C Runtime Library.
        +!
        +SYS$SHARE:DECC$SHR.EXE /SHAREABLE
        +$EOD
        +$!
        +$!    Else...
        +$!
        +$     ELSE
        +$!
        +$!      Create The non-VAX Linker Option File.
        +$!
        +$       CREATE 'OPT_FILE'
        +$DECK
        +!
        +! Default System Options File For non-VAX To Link Against 
        +! The Sharable C Runtime Library.
        +!
        +SYS$SHARE:CMA$OPEN_LIB_SHR.EXE /SHAREABLE
        +SYS$SHARE:CMA$OPEN_RTL.EXE /SHAREABLE
        +$EOD
        +$!
        +$!    End The DEC C Option File Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The Option File Search.
        +$!
        +$   ENDIF
        +$!
        +$! End The DEC C Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Tell The User What Linker Option File We Are Using.
        +$!
        +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
        +$!
        +$! Time To RETURN.
        +$!
        +$ RETURN
        +$!
        +$! Check To See If We Have The Appropiate Libraries.
        +$!
        +$ LIB_CHECK:
        +$!
        +$! Look For The Library LIBCRYPTO.OLB.
        +$!
        +$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
        +$   WRITE SYS$OUTPUT "We Can't Link Without It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$!
        +$! End The Crypto Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Look For The Library LIBSSL.OLB.
        +$!
        +$ IF (F$SEARCH(SSL_LIB).EQS."")
        +$ THEN
        +$!
        +$!  Tell The User We Can't Find The LIBSSL.OLB Library.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
        +$   WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Since We Can't Link Without It, Exit.
        +$!
        +$   EXIT
        +$!
        +$! End The SSL Library Check.
        +$!
        +$ ENDIF
        +$!
        +$! Time To Return.
        +$!
        +$ RETURN
        +$!
        +$! Check The User's Options.
        +$!
        +$ CHECK_OPTIONS:
        +$!
        +$! Set basic C compiler /INCLUDE directories.
        +$!
        +$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
        +$!
        +$! Check To See If P1 Is Blank.
        +$!
        +$ IF (P1.EQS."NODEBUG")
        +$ THEN
        +$!
        +$!  P1 Is NODEBUG, So Compile Without Debugger Information.
        +$!
        +$   DEBUGGER  = "NODEBUG"
        +$   LINKMAP = "NOMAP"
        +$   TRACEBACK = "NOTRACEBACK" 
        +$   GCC_OPTIMIZE = "OPTIMIZE"
        +$   CC_OPTIMIZE = "OPTIMIZE"
        +$   WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
        +$   WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
        +$!
        +$! Else...
        +$!
        +$ ELSE
        +$!
        +$!  Check To See If We Are To Compile With Debugger Information.
        +$!
        +$   IF (P1.EQS."DEBUG")
        +$   THEN
        +$!
        +$!    Compile With Debugger Information.
        +$!
        +$     DEBUGGER  = "DEBUG"
        +$     LINKMAP = "MAP"
        +$     TRACEBACK = "TRACEBACK"
        +$     GCC_OPTIMIZE = "NOOPTIMIZE"
        +$     CC_OPTIMIZE = "NOOPTIMIZE"
        +$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
        +$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
        +$!
        +$!  Else...
        +$!
        +$   ELSE
        +$!
        +$!    Tell The User Entered An Invalid Option.
        +$!
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
        +$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
        +$     WRITE SYS$OUTPUT ""
        +$!
        +$!    Time To EXIT.
        +$!
        +$     EXIT
        +$!
        +$!  End The Valid Argument Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P1 Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check P5 (POINTER_SIZE).
        +$!
        +$ IF (P5 .NES. "") .AND. (ARCH .NES. "VAX")
        +$ THEN
        +$!
        +$   IF (P5 .EQS. "32")
        +$   THEN
        +$     POINTER_SIZE = " /POINTER_SIZE=32"
        +$   ELSE
        +$     POINTER_SIZE = F$EDIT( P5, "COLLAPSE, UPCASE")
        +$     IF ((POINTER_SIZE .EQS. "64") .OR. -
        +       (POINTER_SIZE .EQS. "64=") .OR. -
        +       (POINTER_SIZE .EQS. "64=ARGV"))
        +$     THEN
        +$       ARCHD = ARCH+ "_64"
        +$       LIB32 = ""
        +$       IF (F$EXTRACT( 2, 1, POINTER_SIZE) .EQS. "=")
        +$       THEN
        +$!        Explicit user choice: "64" or "64=ARGV".
        +$         IF (POINTER_SIZE .EQS. "64=") THEN POINTER_SIZE = "64"
        +$       ELSE
        +$         SET NOON
        +$         DEFINE /USER_MODE SYS$OUTPUT NL:
        +$         DEFINE /USER_MODE SYS$ERROR NL:
        +$         CC /NOLIST /NOOBJECT /POINTER_SIZE=64=ARGV NL:
        +$         IF ($STATUS .AND. %X0FFF0000) .EQ. %X00030000
        +$         THEN
        +$           ! If we got here, it means DCL complained like this:
        +$           ! %DCL-W-NOVALU, value not allowed - remove value specification
        +$           !  \64=\
        +$           !
        +$           ! If the compiler was run, logicals defined in /USER would
        +$           ! have been deassigned automatically.  However, when DCL
        +$           ! complains, they aren't, so we do it here (it might be
        +$           ! unnecessary, but just in case there will be another error
        +$           ! message further on that we don't want to miss)
        +$           DEASSIGN /USER_MODE SYS$ERROR
        +$           DEASSIGN /USER_MODE SYS$OUTPUT
        +$         ELSE
        +$           POINTER_SIZE = POINTER_SIZE + "=ARGV"
        +$         ENDIF
        +$         SET ON
        +$       ENDIF
        +$       POINTER_SIZE = " /POINTER_SIZE=''POINTER_SIZE'"
        +$     ELSE
        +$!
        +$!      Tell The User Entered An Invalid Option.
        +$!
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", P5, -
        +         " Is Invalid.  The Valid Options Are:"
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT -
        +         "    """"  :  Compile with default (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    32  :  Compile with 32-bit (short) pointers."
        +$       WRITE SYS$OUTPUT -
        +         "    64       :  Compile with 64-bit (long) pointers (auto ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=      :  Compile with 64-bit (long) pointers (no ARGV)."
        +$       WRITE SYS$OUTPUT -
        +         "    64=ARGV  :  Compile with 64-bit (long) pointers (ARGV)."
        +$       WRITE SYS$OUTPUT ""
        +$! 
        +$!      Time To EXIT.
        +$!
        +$       EXIT
        +$!
        +$     ENDIF
        +$!
        +$   ENDIF
        +$!
        +$! End The P5 (POINTER_SIZE) Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If P2 Is Blank.
        +$!
        +$ IF (P2.EQS."")
        +$ THEN
        +$!
        +$!  O.K., The User Didn't Specify A Compiler, Let's Try To
        +$!  Find Out Which One To Use.
        +$!
        +$!  Check To See If We Have GNU C.
        +$!
        +$   IF (F$TRNLNM("GNU_CC").NES."")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     P2 = "GNUC"
        +$!
        +$!  End The GNU C Compiler Check.
        +$!
        +$   ELSE
        +$!
        +$!  Check To See If We Have VAXC Or DECC.
        +$!
        +$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
        +$     THEN 
        +$!
        +$!      Looks Like DECC, Set To Use DECC.
        +$!
        +$       P2 = "DECC"
        +$!
        +$!      Else...
        +$!
        +$     ELSE
        +$!
        +$!      Looks Like VAXC, Set To Use VAXC.
        +$!
        +$       P2 = "VAXC"
        +$!
        +$!    End The VAXC Compiler Check.
        +$!
        +$     ENDIF
        +$!
        +$!  End The DECC & VAXC Compiler Check.
        +$!
        +$   ENDIF
        +$!
        +$!  End The Compiler Check.
        +$!
        +$ ENDIF
        +$!
        +$! Check To See If We Have A Option For P3.
        +$!
        +$ IF (P3.EQS."")
        +$ THEN
        +$!
        +$!  Find out what socket library we have available
        +$!
        +$   IF F$PARSE("SOCKETSHR:") .NES. ""
        +$   THEN
        +$!
        +$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
        +$!
        +$     P3 = "SOCKETSHR"
        +$!
        +$!    Tell the user
        +$!
        +$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
        +$!
        +$!    Else, let's look for something else
        +$!
        +$   ELSE
        +$!
        +$!    Like UCX (the reason to do this before Multinet is that the UCX
        +$!    emulation is easier to use...)
        +$!
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
        +	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
        +	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
        +$     THEN
        +$!
        +$!	Last resort: a UCX or UCX-compatible library
        +$!
        +$	P3 = "UCX"
        +$!
        +$!      Tell the user
        +$!
        +$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
        +$!
        +$!	That was all...
        +$!
        +$     ENDIF
        +$   ENDIF
        +$ ENDIF
        +$!
        +$! Set Up Initial CC Definitions, Possibly With User Ones
        +$!
        +$ CCDEFS = "TCPIP_TYPE_''P3'"
        +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
        +$ CCEXTRAFLAGS = ""
        +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
        +$ CCDISABLEWARNINGS = "" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
        +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
        +	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
        +$!
        +$! Check To See If We Have A ZLIB Option.
        +$!
        +$ ZLIB = P6
        +$ IF (ZLIB .NES. "")
        +$ THEN
        +$!
        +$!  Check for expected ZLIB files.
        +$!
        +$   err = 0
        +$   file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
        +$   if (f$search( file1) .eqs. "")
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$     WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     WRITE SYS$OUTPUT "    Can't find header: ''file1'"
        +$     err = 1
        +$   endif
        +$   file1 = f$parse( "A.;", ZLIB)- "A.;"
        +$!
        +$   file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
        +$   if (f$search( file2) .eqs. "")
        +$   then
        +$     if (err .eq. 0)
        +$     then
        +$       WRITE SYS$OUTPUT ""
        +$       WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
        +$     endif
        +$     WRITE SYS$OUTPUT "    Can't find library: ''file2'"
        +$     WRITE SYS$OUTPUT ""
        +$     err = err+ 2
        +$   endif
        +$   if (err .eq. 1)
        +$   then
        +$     WRITE SYS$OUTPUT ""
        +$   endif
        +$!
        +$   if (err .ne. 0)
        +$   then
        +$     GOTO EXIT
        +$   endif
        +$!
        +$   CCDEFS = """ZLIB=1"", "+ CCDEFS
        +$   CC_INCLUDES = CC_INCLUDES+ ", "+ file1
        +$   ZLIB_LIB = ", ''file2' /library"
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "ZLIB library spec: ", file2
        +$!
        +$! End The P8 Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Check To See If The User Entered A Valid Parameter.
        +$!
        +$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
        +$ THEN
        +$!
        +$!  Check To See If The User Wanted DECC.
        +$!
        +$   IF (P2.EQS."DECC")
        +$   THEN
        +$!
        +$!    Looks Like DECC, Set To Use DECC.
        +$!
        +$     COMPILER = "DECC"
        +$!
        +$!    Tell The User We Are Using DECC.
        +$!
        +$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
        +$!
        +$!    Use DECC...
        +$!
        +$     CC = "CC"
        +$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
        +	 THEN CC = "CC /DECC"
        +$     CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
        +       "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
        +       " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_DECC_OPTIONS.OPT"
        +$!
        +$!  End DECC Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use VAXC.
        +$!
        +$   IF (P2.EQS."VAXC")
        +$   THEN
        +$!
        +$!    Looks Like VAXC, Set To Use VAXC.
        +$!
        +$     COMPILER = "VAXC"
        +$!
        +$!    Tell The User We Are Using VAX C.
        +$!
        +$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
        +$!
        +$!    Compile Using VAXC.
        +$!
        +$     CC = "CC"
        +$     IF ARCH.NES."VAX"
        +$     THEN
        +$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
        +$	EXIT
        +$     ENDIF
        +$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC /VAXC"
        +$     CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
        +$     CCDEFS = CCDEFS + ",""VAXC"""
        +$!
        +$!    Define <sys> As SYS$COMMON:[SYSLIB]
        +$!
        +$     DEFINE /NOLOG SYS SYS$COMMON:[SYSLIB]
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
        +$!
        +$!  End VAXC Check
        +$!
        +$   ENDIF
        +$!
        +$!  Check To See If We Are To Use GNU C.
        +$!
        +$   IF (P2.EQS."GNUC")
        +$   THEN
        +$!
        +$!    Looks Like GNUC, Set To Use GNUC.
        +$!
        +$     COMPILER = "GNUC"
        +$!
        +$!    Tell The User We Are Using GNUC.
        +$!
        +$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
        +$!
        +$!    Use GNU C...
        +$!
        +$     CC = "GCC /NOCASE_HACK /''GCC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
        +	   "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
        +$!
        +$!    Define The Linker Options File Name.
        +$!
        +$     OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
        +$!
        +$!  End The GNU C Check.
        +$!
        +$   ENDIF
        +$!
        +$!  Set up default defines
        +$!
        +$   CCDEFS = """FLAT_INC=1""," + CCDEFS
        +$!
        +$!  Finish up the definition of CC.
        +$!
        +$   IF COMPILER .EQS. "DECC"
        +$   THEN
        +$     IF CCDISABLEWARNINGS .EQS. ""
        +$     THEN
        +$       CC4DISABLEWARNINGS = "DOLLARID"
        +$     ELSE
        +$       CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
        +$       CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
        +$     ENDIF
        +$     CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
        +$   ELSE
        +$     CCDISABLEWARNINGS = ""
        +$     CC4DISABLEWARNINGS = ""
        +$   ENDIF
        +$   CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
        +$!
        +$!  Show user the result
        +$!
        +$   WRITE /SYMBOL SYS$OUTPUT "Main Compiling Command: ", CC
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
        +$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
        +$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$ ENDIF
        +$!
        +$! Time to check the contents, and to make sure we get the correct library.
        +$!
        +$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
        +     .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
        +$ THEN
        +$!
        +$!  Check to see if SOCKETSHR was chosen
        +$!
        +$   IF P3.EQS."SOCKETSHR"
        +$   THEN
        +$!
        +$!    Set the library to use SOCKETSHR
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
        +$!
        +$!    Done with SOCKETSHR
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if MULTINET was chosen
        +$!
        +$   IF P3.EQS."MULTINET"
        +$   THEN
        +$!
        +$!    Set the library to use UCX emulation.
        +$!
        +$     P3 = "UCX"
        +$!
        +$!    Done with MULTINET
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if UCX was chosen
        +$!
        +$   IF P3.EQS."UCX"
        +$   THEN
        +$!
        +$!    Set the library to use UCX.
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
        +$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
        +$     THEN
        +$       TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
        +$     ELSE
        +$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
        +	  TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
        +$     ENDIF
        +$!
        +$!    Done with UCX
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if TCPIP was chosen
        +$!
        +$   IF P3.EQS."TCPIP"
        +$   THEN
        +$!
        +$!    Set the library to use TCPIP (post UCX).
        +$!
        +$     TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
        +$!
        +$!    Done with TCPIP
        +$!
        +$   ENDIF
        +$!
        +$!  Check to see if NONE was chosen
        +$!
        +$   IF P3.EQS."NONE"
        +$   THEN
        +$!
        +$!    Do not use a TCPIP library.
        +$!
        +$     TCPIP_LIB = ""
        +$!
        +$!    Done with NONE
        +$!
        +$   ENDIF
        +$!
        +$!  Print info
        +$!
        +$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
        +$!
        +$!  Else The User Entered An Invalid Argument.
        +$!
        +$ ELSE
        +$!
        +$!  Tell The User We Don't Know What They Want.
        +$!
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
        +$   WRITE SYS$OUTPUT ""
        +$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
        +$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
        +$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
        +$   WRITE SYS$OUTPUT ""
        +$!
        +$!  Time To EXIT.
        +$!
        +$   EXIT
        +$!
        +$!  Done with TCP/IP libraries
        +$!
        +$ ENDIF
        +$!
        +$! Special Threads For OpenVMS v7.1 Or Later
        +$!
        +$! Written By:  Richard Levitte
        +$!              richard@levitte.org
        +$!
        +$!
        +$! Check To See If We Have A Option For P4.
        +$!
        +$ IF (P4.EQS."")
        +$ THEN
        +$!
        +$!  Get The Version Of VMS We Are Using.
        +$!
        +$   ISSEVEN :=
        +$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
        +$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
        +$!
        +$!  Check To See If The VMS Version Is v7.1 Or Later.
        +$!
        +$   IF (TMP.GE.71)
        +$   THEN
        +$!
        +$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
        +$!
        +$     ISSEVEN := ,PTHREAD_USE_D4
        +$!
        +$!  End The VMS Version Check.
        +$!
        +$   ENDIF
        +$!
        +$! End The P4 Check.
        +$!
        +$ ENDIF
        +$!
        +$!  Time To RETURN...
        +$!
        +$ RETURN
        +$!
        +$ INITIALISE:
        +$!
        +$! Save old value of the logical name OPENSSL
        +$!
        +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
        +$!
        +$! Save directory information
        +$!
        +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
        +$ __HERE = F$EDIT(__HERE,"UPCASE")
        +$ __TOP = __HERE - "TEST]"
        +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
        +$!
        +$! Set up the logical name OPENSSL to point at the include directory
        +$!
        +$ DEFINE OPENSSL /NOLOG '__INCLUDE'
        +$!
        +$! Done
        +$!
        +$ RETURN
        +$!
        +$ CLEANUP:
        +$!
        +$! Restore the logical name OPENSSL if it had a value
        +$!
        +$ IF __SAVE_OPENSSL .EQS. ""
        +$ THEN
        +$   DEASSIGN OPENSSL
        +$ ELSE
        +$   DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
        +$ ENDIF
        +$!
        +$! Done
        +$!
        +$ RETURN
        diff --git a/vendor/openssl/openssl/test/md2test.c b/vendor/openssl/openssl/test/md2test.c
        new file mode 100644
        index 000000000..5b4467e04
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/md2test.c
        @@ -0,0 +1,48 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/buffer.h>
        +#include <openssl/crypto.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *p, *q = 0, *program;
        +
        +	p = strrchr(argv[0], '/');
        +	if (!p) p = strrchr(argv[0], '\\');
        +#ifdef OPENSSL_SYS_VMS
        +	if (!p) p = strrchr(argv[0], ']');
        +	if (p) q = strrchr(p, '>');
        +	if (q) p = q;
        +	if (!p) p = strrchr(argv[0], ':');
        +	q = 0;
        +#endif
        +	if (p) p++;
        +	if (!p) p = argv[0];
        +	if (p) q = strchr(p, '.');
        +	if (p && !q) q = p + strlen(p);
        +
        +	if (!p)
        +		program = BUF_strdup("(unknown)");
        +	else
        +		{
        +		program = OPENSSL_malloc((q - p) + 1);
        +		strncpy(program, p, q - p);
        +		program[q - p] = '\0';
        +		}
        +
        +	for(p = program; *p; p++)
        +		if (islower((unsigned char)(*p)))
        +			*p = toupper((unsigned char)(*p));
        +
        +	q = strstr(program, "TEST");
        +	if (q > p && q[-1] == '_') q--;
        +	*q = '\0';
        +
        +	printf("No %s support\n", program);
        +
        +	OPENSSL_free(program);
        +	return(0);
        +	}
        diff --git a/vendor/openssl/openssl/test/md4test.c b/vendor/openssl/openssl/test/md4test.c
        new file mode 100644
        index 000000000..56591728a
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/md4test.c
        @@ -0,0 +1,136 @@
        +/* 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 <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_MD4
        +int main(int argc, char *argv[])
        +{
        +    printf("No MD4 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/md4.h>
        +
        +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;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[MD4_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md4(), NULL);
        +		p=pt(md);
        +		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<MD4_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/md5test.c b/vendor/openssl/openssl/test/md5test.c
        new file mode 100644
        index 000000000..2b37190e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/md5test.c
        @@ -0,0 +1,140 @@
        +/* crypto/md5/md5test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_MD5
        +int main(int argc, char *argv[])
        +{
        +    printf("No MD5 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/md5.h>
        +
        +static char *test[]={
        +	"",
        +	"a",
        +	"abc",
        +	"message digest",
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        +	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
        +	NULL,
        +	};
        +
        +static char *ret[]={
        +	"d41d8cd98f00b204e9800998ecf8427e",
        +	"0cc175b9c0f1b6a831c399e269772661",
        +	"900150983cd24fb0d6963f7d28e17f72",
        +	"f96b697d7cb7938d525a2f31aaf161d0",
        +	"c3fcd3d76192e4007dfb496cca67e13b",
        +	"d174ab98d277d9f5a5611c2c9f419d9f",
        +	"57edf4a22be3c955ac49da2e2107b67a",
        +	};
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[MD5_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_md5(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,(char *)*R) != 0)
        +			{
        +			printf("error calculating MD5 on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(0);
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<MD5_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/mdc2test.c b/vendor/openssl/openssl/test/mdc2test.c
        new file mode 100644
        index 000000000..017b31add
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/mdc2test.c
        @@ -0,0 +1,149 @@
        +/* crypto/mdc2/mdc2test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#if defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_MDC2)
        +#define OPENSSL_NO_MDC2
        +#endif
        +
        +#ifdef OPENSSL_NO_MDC2
        +int main(int argc, char *argv[])
        +{
        +    printf("No MDC2 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/mdc2.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static unsigned char pad1[16]={
        +	0x42,0xE5,0x0C,0xD2,0x24,0xBA,0xCE,0xBA,
        +	0x76,0x0B,0xDD,0x2B,0xD4,0x09,0x28,0x1A
        +	};
        +
        +static unsigned char pad2[16]={
        +	0x2E,0x46,0x79,0xB5,0xAD,0xD9,0xCA,0x75,
        +	0x35,0xD8,0x7A,0xFE,0xAB,0x33,0xBE,0xE2
        +	};
        +
        +int main(int argc, char *argv[])
        +	{
        +	int ret=0;
        +	unsigned char md[MDC2_DIGEST_LENGTH];
        +	int i;
        +	EVP_MD_CTX c;
        +	static char *text="Now is the time for all ";
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(text,text,strlen(text));
        +#endif
        +
        +	EVP_MD_CTX_init(&c);
        +	EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
        +	EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
        +	EVP_DigestFinal_ex(&c,&(md[0]),NULL);
        +
        +	if (memcmp(md,pad1,MDC2_DIGEST_LENGTH) != 0)
        +		{
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",md[i]);
        +		printf(" <- generated\n");
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",pad1[i]);
        +		printf(" <- correct\n");
        +		ret=1;
        +		}
        +	else
        +		printf("pad1 - ok\n");
        +
        +	EVP_DigestInit_ex(&c,EVP_mdc2(), NULL);
        +	/* FIXME: use a ctl function? */
        +	((MDC2_CTX *)c.md_data)->pad_type=2;
        +	EVP_DigestUpdate(&c,(unsigned char *)text,strlen(text));
        +	EVP_DigestFinal_ex(&c,&(md[0]),NULL);
        +
        +	if (memcmp(md,pad2,MDC2_DIGEST_LENGTH) != 0)
        +		{
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",md[i]);
        +		printf(" <- generated\n");
        +		for (i=0; i<MDC2_DIGEST_LENGTH; i++)
        +			printf("%02X",pad2[i]);
        +		printf(" <- correct\n");
        +		ret=1;
        +		}
        +	else
        +		printf("pad2 - ok\n");
        +
        +	EVP_MD_CTX_cleanup(&c);
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (ret) printf("ERROR: %d\n", ret);
        +#endif
        +	EXIT(ret);
        +	return(ret);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/methtest.c b/vendor/openssl/openssl/test/methtest.c
        new file mode 100644
        index 000000000..005c2f482
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/methtest.c
        @@ -0,0 +1,105 @@
        +/* test/methtest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/rsa.h>
        +#include <openssl/x509.h>
        +#include "meth.h"
        +#include <openssl/err.h>
        +
        +int main(argc,argv)
        +int argc;
        +char *argv[];
        +	{
        +	METHOD_CTX *top,*tmp1,*tmp2;
        +
        +	top=METH_new(x509_lookup()); /* get a top level context */
        +	if (top == NULL) goto err;
        +
        +	tmp1=METH_new(x509_by_file());
        +	if (top == NULL) goto err;
        +	METH_arg(tmp1,METH_TYPE_FILE,"cafile1");
        +	METH_arg(tmp1,METH_TYPE_FILE,"cafile2");
        +	METH_push(top,METH_X509_CA_BY_SUBJECT,tmp1);
        +
        +	tmp2=METH_new(x509_by_dir());
        +	METH_arg(tmp2,METH_TYPE_DIR,"/home/eay/.CAcerts");
        +	METH_arg(tmp2,METH_TYPE_DIR,"/home/eay/SSLeay/certs");
        +	METH_arg(tmp2,METH_TYPE_DIR,"/usr/local/ssl/certs");
        +	METH_push(top,METH_X509_CA_BY_SUBJECT,tmp2);
        +
        +/*	tmp=METH_new(x509_by_issuer_dir);
        +	METH_arg(tmp,METH_TYPE_DIR,"/home/eay/.mycerts");
        +	METH_push(top,METH_X509_BY_ISSUER,tmp);
        +
        +	tmp=METH_new(x509_by_issuer_primary);
        +	METH_arg(tmp,METH_TYPE_FILE,"/home/eay/.mycerts/primary.pem");
        +	METH_push(top,METH_X509_BY_ISSUER,tmp);
        +*/
        +
        +	METH_init(top);
        +	METH_control(tmp1,METH_CONTROL_DUMP,stdout);
        +	METH_control(tmp2,METH_CONTROL_DUMP,stdout);
        +	EXIT(0);
        +err:
        +	ERR_load_crypto_strings();
        +	ERR_print_errors_fp(stderr);
        +	EXIT(1);
        +	return(0);
        +	}
        diff --git a/vendor/openssl/openssl/test/pkcs7-1.pem b/vendor/openssl/openssl/test/pkcs7-1.pem
        new file mode 100644
        index 000000000..c47b27af8
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/pkcs7-1.pem
        @@ -0,0 +1,15 @@
        +-----BEGIN PKCS7-----
        +MIICUAYJKoZIhvcNAQcCoIICQTCCAj0CAQExDjAMBggqhkiG9w0CAgUAMCgGCSqG
        +SIb3DQEHAaAbBBlFdmVyeW9uZSBnZXRzIEZyaWRheSBvZmYuoIIBXjCCAVowggEE
        +AgQUAAApMA0GCSqGSIb3DQEBAgUAMCwxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRF
        +eGFtcGxlIE9yZ2FuaXphdGlvbjAeFw05MjA5MDkyMjE4MDZaFw05NDA5MDkyMjE4
        +MDVaMEIxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRFeGFtcGxlIE9yZ2FuaXphdGlv
        +bjEUMBIGA1UEAxMLVGVzdCBVc2VyIDEwWzANBgkqhkiG9w0BAQEFAANKADBHAkAK
        +ZnkdxpiBaN56t3QZu3+wwAHGJxAnAHUUKULhmo2MUdBTs+N4Kh3l3Fr06+mUaBcB
        +FKHf5nzcmpr1XWVWILurAgMBAAEwDQYJKoZIhvcNAQECBQADQQBFGqHhqncgSl/N
        +9XYGnQL3MsJvNnsNV4puZPOakR9Hld8JlDQFEaDR30ogsmp3TMrvdfxpLlTCoZN8
        +BxEmnZsWMYGbMIGYAgEBMDQwLDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFEV4YW1w
        +bGUgT3JnYW5pemF0aW9uAgQUAAApMAwGCCqGSIb3DQICBQAwDQYJKoZIhvcNAQEB
        +BQAEQAX6aoEvx9+L9PJUJQngPoRuEbnGIL4gCe+0QO+8xmkhaZSsBPNBtX0FIC1C
        +j7Kie1x339mxW/w9VZNTUDQQweHh
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/test/pkcs7.pem b/vendor/openssl/openssl/test/pkcs7.pem
        new file mode 100644
        index 000000000..d55c60b94
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/pkcs7.pem
        @@ -0,0 +1,54 @@
        +     MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCAMIIE+DCCBGGg
        +     AwIBAgIQaGSF/JpbS1C223+yrc+N1DANBgkqhkiG9w0BAQQFADBiMREwDwYDVQQH
        +     EwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNVBAsTK1Zl
        +     cmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXIwHhcNOTYw
        +     ODEyMDAwMDAwWhcNOTYwODE3MjM1OTU5WjCCASAxETAPBgNVBAcTCEludGVybmV0
        +     MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh
        +     c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjE3MDUGA1UECxMuRGlnaXRh
        +     bCBJRCBDbGFzcyAxIC0gU01JTUUgVmVyaVNpZ24sIEluYy4gVEVTVDFGMEQGA1UE
        +     CxM9d3d3LnZlcmlzaWduLmNvbS9yZXBvc2l0b3J5L0NQUyBJbmNvcnAuIGJ5IFJl
        +     Zi4sTElBQi5MVEQoYyk5NjEZMBcGA1UEAxMQQWxleGFuZHJlIERlYWNvbjEgMB4G
        +     CSqGSIb3DQEJARYRYWxleEB2ZXJpc2lnbi5jb20wWzANBgkqhkiG9w0BAQEFAANK
        +     ADBHAkAOy7xxCAIkOfuIA2LyRpxgKlDORl8htdXYhF5iBGUx1GYaK6KF+bK/CCI0
        +     l4j2OfWGFBUrwGoWqxTNcWgTfMzRAgMBAAGjggIyMIICLjAJBgNVHRMEAjAAMIIC
        +     HwYDVR0DBIICFjCCAhIwggIOMIICCgYLYIZIAYb4RQEHAQEwggH5FoIBp1RoaXMg
        +     Y2VydGlmaWNhdGUgaW5jb3Jwb3JhdGVzIGJ5IHJlZmVyZW5jZSwgYW5kIGl0cyB1
        +     c2UgaXMgc3RyaWN0bHkgc3ViamVjdCB0bywgdGhlIFZlcmlTaWduIENlcnRpZmlj
        +     YXRpb24gUHJhY3RpY2UgU3RhdGVtZW50IChDUFMpLCBhdmFpbGFibGUgYXQ6IGh0
        +     dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9DUFM7IGJ5IEUtbWFpbCBhdCBDUFMtcmVx
        +     dWVzdHNAdmVyaXNpZ24uY29tOyBvciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMu
        +     LCAyNTkzIENvYXN0IEF2ZS4sIE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBU
        +     ZWwuICsxICg0MTUpIDk2MS04ODMwIENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2ln
        +     biwgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVT
        +     IERJU0NMQUlNRUQgYW5kIExJQUJJTElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcB
        +     AQGhDgYMYIZIAYb4RQEHAQECMCwwKhYoaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t
        +     L3JlcG9zaXRvcnkvQ1BTIDANBgkqhkiG9w0BAQQFAAOBgQAimWMGQwwwxk+b3KAL
        +     HlSWXtU7LWHe29CEG8XeVNTvrqs6SBqT7OoENOkGxpfdpVgZ3Qw2SKjxDvbvpfSF
        +     slsqcxWSgB/hWuaVuZCkvTw/dYGGOxkTJGxvDCfl1PZjX4dKbatslsi9Z9HpGWT7
        +     ttItRwKqcBKgmCJvKi1pGWED0zCCAnkwggHioAMCAQICEDURpVKQb+fQKaRAGdQR
        +     /D4wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlT
        +     aWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRp
        +     ZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDYyNzAwMDAwMFoXDTk3MDYyNzIzNTk1
        +     OVowYjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMu
        +     MTQwMgYDVQQLEytWZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJz
        +     Y3JpYmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2FKbPTdAFDdjKI9Bv
        +     qrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7jW80GqLd5HUQq7XPy
        +     sVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cariQPJUObwW7s987Lrb
        +     P2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABozMwMTAPBgNVHRMECDAGAQH/AgEBMAsG
        +     A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcNAQECBQADgYEA
        +     KeXHoBmnbxRCgk0jM9e9mDppdxpsipIna/J8DOHEUuD4nONAr4+xOg73SBl026n7
        +     Bk55A2wvAMGo7+kKTZ+rHaFDDcmq4O+rzFri2RIOeGAncj1IcGptAQhvXoIhFMG4
        +     Jlzg1KlHZHqy7D3jex78zcSU7kKOu8f5tAX1jC3+sToAAKGAMIIBJzCBkTANBgkq
        +     hkiG9w0BAQIFADBiMREwDwYDVQQHEwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNp
        +     Z24sIEluYy4xNDAyBgNVBAsTK1ZlcmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlk
        +     dWFsIFN1YnNjcmliZXIXDTk2MDcwMTE3MzA0MFoXDTk3MDcwMTAwMDAwMFowDQYJ
        +     KoZIhvcNAQECBQADgYEAGLuQ6PX8A7AiqBEtWzYtl6lZNSDI0bR5YUo+D2Jzkw30
        +     dxQnJSbKXEc6XYuzAW5HvrzATXu5c19WWPT4cRDwmjH71i9QcDysWwf/wE0qGTiW
        +     I3tQT0I5VGh7jIJD07nlBw3R4Xl8dH9kr85JsWinqDH5YKpIo9o8knY5n7+qjOow
        +     ggEkMIGOMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5W
        +     ZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBD
        +     ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eRcNOTYwNzE2MjMxMTI5WhcNOTYwODE1MDAw
        +     MDAwWjANBgkqhkiG9w0BAQIFAAOBgQAXsLE4vnsY6sY67QrmWec7iaU2ehzxanEK
        +     /9wKHZNuhlNzk+qGZZw2evxfUe2OaRbYpl8zuZvhK9BHD3ad14OSe9/zx5hOPgP/
        +     DQXt6R4R8Q/1JheBrolrgbavjvI2wKS8/Psp2prBrkF4T48+AKRmS8Zzh1guxgvP
        +     b+xSu/jH0gAAMYAAAAAAAAAAAA==
        diff --git a/vendor/openssl/openssl/test/pkits-test.pl b/vendor/openssl/openssl/test/pkits-test.pl
        new file mode 100644
        index 000000000..5c6b89fcd
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/pkits-test.pl
        @@ -0,0 +1,949 @@
        +# test/pkits-test.pl
        +# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
        +# project.
        +#
        +# ====================================================================
        +# Copyright (c) 2008 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.
        +# ====================================================================
        +
        +# Perl utility to run PKITS tests for RFC3280 compliance. 
        +
        +my $ossl_path;
        +
        +if ( -f "../apps/openssl" ) {
        +    $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
        +}
        +elsif ( -f "..\\out32dll\\openssl.exe" ) {
        +    $ossl_path = "..\\out32dll\\openssl.exe";
        +}
        +elsif ( -f "..\\out32\\openssl.exe" ) {
        +    $ossl_path = "..\\out32\\openssl.exe";
        +}
        +else {
        +    die "Can't find OpenSSL executable";
        +}
        +
        +my $pkitsdir = "pkits/smime";
        +my $pkitsta = "pkits/certs/TrustAnchorRootCertificate.crt";
        +
        +die "Can't find PKITS test data" if !-d $pkitsdir;
        +
        +my $nist1 = "2.16.840.1.101.3.2.1.48.1";
        +my $nist2 = "2.16.840.1.101.3.2.1.48.2";
        +my $nist3 = "2.16.840.1.101.3.2.1.48.3";
        +my $nist4 = "2.16.840.1.101.3.2.1.48.4";
        +my $nist5 = "2.16.840.1.101.3.2.1.48.5";
        +my $nist6 = "2.16.840.1.101.3.2.1.48.6";
        +
        +my $apolicy = "X509v3 Any Policy";
        +
        +# This table contains the chapter headings of the accompanying PKITS
        +# document. They provide useful informational output and their names
        +# can be converted into the filename to test.
        +
        +my @testlists = (
        +    [ "4.1", "Signature Verification" ],
        +    [ "4.1.1", "Valid Signatures Test1",                        0 ],
        +    [ "4.1.2", "Invalid CA Signature Test2",                    7 ],
        +    [ "4.1.3", "Invalid EE Signature Test3",                    7 ],
        +    [ "4.1.4", "Valid DSA Signatures Test4",                    0 ],
        +    [ "4.1.5", "Valid DSA Parameter Inheritance Test5",         0 ],
        +    [ "4.1.6", "Invalid DSA Signature Test6",                   7 ],
        +    [ "4.2",   "Validity Periods" ],
        +    [ "4.2.1", "Invalid CA notBefore Date Test1",               9 ],
        +    [ "4.2.2", "Invalid EE notBefore Date Test2",               9 ],
        +    [ "4.2.3", "Valid pre2000 UTC notBefore Date Test3",        0 ],
        +    [ "4.2.4", "Valid GeneralizedTime notBefore Date Test4",    0 ],
        +    [ "4.2.5", "Invalid CA notAfter Date Test5",                10 ],
        +    [ "4.2.6", "Invalid EE notAfter Date Test6",                10 ],
        +    [ "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7",    10 ],
        +    [ "4.2.8", "Valid GeneralizedTime notAfter Date Test8",     0 ],
        +    [ "4.3",   "Verifying Name Chaining" ],
        +    [ "4.3.1", "Invalid Name Chaining EE Test1",                20 ],
        +    [ "4.3.2", "Invalid Name Chaining Order Test2",             20 ],
        +    [ "4.3.3", "Valid Name Chaining Whitespace Test3",          0 ],
        +    [ "4.3.4", "Valid Name Chaining Whitespace Test4",          0 ],
        +    [ "4.3.5", "Valid Name Chaining Capitalization Test5",      0 ],
        +    [ "4.3.6", "Valid Name Chaining UIDs Test6",                0 ],
        +    [ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7", 0 ],
        +    [ "4.3.8", "Valid RFC3280 Optional Attribute Types Test8",  0 ],
        +    [ "4.3.9", "Valid UTF8String Encoded Names Test9",          0 ],
        +    [ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10", 0 ],
        +    [ "4.3.11", "Valid UTF8String Case Insensitive Match Test11",           0 ],
        +    [ "4.4",    "Basic Certificate Revocation Tests" ],
        +    [ "4.4.1",  "Missing CRL Test1",                                        3 ],
        +    [ "4.4.2", "Invalid Revoked CA Test2",          23 ],
        +    [ "4.4.3", "Invalid Revoked EE Test3",          23 ],
        +    [ "4.4.4", "Invalid Bad CRL Signature Test4",   8 ],
        +    [ "4.4.5", "Invalid Bad CRL Issuer Name Test5", 3 ],
        +    [ "4.4.6", "Invalid Wrong CRL Test6",           3 ],
        +    [ "4.4.7", "Valid Two CRLs Test7",              0 ],
        +
        +    # The test document suggests these should return certificate revoked...
        +    # Subsquent discussion has concluded they should not due to unhandle
        +    # critical CRL extensions.
        +    [ "4.4.8", "Invalid Unknown CRL Entry Extension Test8", 36 ],
        +    [ "4.4.9", "Invalid Unknown CRL Extension Test9",       36 ],
        +
        +    [ "4.4.10", "Invalid Unknown CRL Extension Test10",             36 ],
        +    [ "4.4.11", "Invalid Old CRL nextUpdate Test11",                12 ],
        +    [ "4.4.12", "Invalid pre2000 CRL nextUpdate Test12",            12 ],
        +    [ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13",      0 ],
        +    [ "4.4.14", "Valid Negative Serial Number Test14",              0 ],
        +    [ "4.4.15", "Invalid Negative Serial Number Test15",            23 ],
        +    [ "4.4.16", "Valid Long Serial Number Test16",                  0 ],
        +    [ "4.4.17", "Valid Long Serial Number Test17",                  0 ],
        +    [ "4.4.18", "Invalid Long Serial Number Test18",                23 ],
        +    [ "4.4.19", "Valid Separate Certificate and CRL Keys Test19",   0 ],
        +    [ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20", 23 ],
        +
        +    # CRL path is revoked so get a CRL path validation error
        +    [ "4.4.21", "Invalid Separate Certificate and CRL Keys Test21",      54 ],
        +    [ "4.5",    "Verifying Paths with Self-Issued Certificates" ],
        +    [ "4.5.1",  "Valid Basic Self-Issued Old With New Test1",            0 ],
        +    [ "4.5.2",  "Invalid Basic Self-Issued Old With New Test2",          23 ],
        +    [ "4.5.3",  "Valid Basic Self-Issued New With Old Test3",            0 ],
        +    [ "4.5.4",  "Valid Basic Self-Issued New With Old Test4",            0 ],
        +    [ "4.5.5",  "Invalid Basic Self-Issued New With Old Test5",          23 ],
        +    [ "4.5.6",  "Valid Basic Self-Issued CRL Signing Key Test6",         0 ],
        +    [ "4.5.7",  "Invalid Basic Self-Issued CRL Signing Key Test7",       23 ],
        +    [ "4.5.8",  "Invalid Basic Self-Issued CRL Signing Key Test8",       20 ],
        +    [ "4.6",    "Verifying Basic Constraints" ],
        +    [ "4.6.1",  "Invalid Missing basicConstraints Test1",                24 ],
        +    [ "4.6.2",  "Invalid cA False Test2",                                24 ],
        +    [ "4.6.3",  "Invalid cA False Test3",                                24 ],
        +    [ "4.6.4",  "Valid basicConstraints Not Critical Test4",             0 ],
        +    [ "4.6.5",  "Invalid pathLenConstraint Test5",                       25 ],
        +    [ "4.6.6",  "Invalid pathLenConstraint Test6",                       25 ],
        +    [ "4.6.7",  "Valid pathLenConstraint Test7",                         0 ],
        +    [ "4.6.8",  "Valid pathLenConstraint Test8",                         0 ],
        +    [ "4.6.9",  "Invalid pathLenConstraint Test9",                       25 ],
        +    [ "4.6.10", "Invalid pathLenConstraint Test10",                      25 ],
        +    [ "4.6.11", "Invalid pathLenConstraint Test11",                      25 ],
        +    [ "4.6.12", "Invalid pathLenConstraint Test12",                      25 ],
        +    [ "4.6.13", "Valid pathLenConstraint Test13",                        0 ],
        +    [ "4.6.14", "Valid pathLenConstraint Test14",                        0 ],
        +    [ "4.6.15", "Valid Self-Issued pathLenConstraint Test15",            0 ],
        +    [ "4.6.16", "Invalid Self-Issued pathLenConstraint Test16",          25 ],
        +    [ "4.6.17", "Valid Self-Issued pathLenConstraint Test17",            0 ],
        +    [ "4.7",    "Key Usage" ],
        +    [ "4.7.1",  "Invalid keyUsage Critical keyCertSign False Test1",     20 ],
        +    [ "4.7.2",  "Invalid keyUsage Not Critical keyCertSign False Test2", 20 ],
        +    [ "4.7.3",  "Valid keyUsage Not Critical Test3",                     0 ],
        +    [ "4.7.4",  "Invalid keyUsage Critical cRLSign False Test4",         35 ],
        +    [ "4.7.5",  "Invalid keyUsage Not Critical cRLSign False Test5",     35 ],
        +
        +    # Certificate policy tests need special handling. They can have several
        +    # sub tests and we need to check the outputs are correct.
        +
        +    [ "4.8", "Certificate Policies" ],
        +    [
        +        "4.8.1.1",
        +        "All Certificates Same Policy Test1",
        +        "-policy anyPolicy -explicit_policy",
        +        "True", $nist1, $nist1, 0
        +    ],
        +    [
        +        "4.8.1.2",
        +        "All Certificates Same Policy Test1",
        +        "-policy $nist1 -explicit_policy",
        +        "True", $nist1, $nist1, 0
        +    ],
        +    [
        +        "4.8.1.3",
        +        "All Certificates Same Policy Test1",
        +        "-policy $nist2 -explicit_policy",
        +        "True", $nist1, "<empty>", 43
        +    ],
        +    [
        +        "4.8.1.4",
        +        "All Certificates Same Policy Test1",
        +        "-policy $nist1 -policy $nist2 -explicit_policy",
        +        "True", $nist1, $nist1, 0
        +    ],
        +    [
        +        "4.8.2.1",
        +        "All Certificates No Policies Test2",
        +        "-policy anyPolicy",
        +        "False", "<empty>", "<empty>", 0
        +    ],
        +    [
        +        "4.8.2.2",
        +        "All Certificates No Policies Test2",
        +        "-policy anyPolicy -explicit_policy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.3.1",
        +        "Different Policies Test3",
        +        "-policy anyPolicy",
        +        "False", "<empty>", "<empty>", 0
        +    ],
        +    [
        +        "4.8.3.2",
        +        "Different Policies Test3",
        +        "-policy anyPolicy -explicit_policy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.3.3",
        +        "Different Policies Test3",
        +        "-policy $nist1 -policy $nist2 -explicit_policy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +
        +    [
        +        "4.8.4",
        +        "Different Policies Test4",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.5",
        +        "Different Policies Test5",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.6.1",
        +        "Overlapping Policies Test6",
        +        "-policy anyPolicy",
        +        "True", $nist1, $nist1, 0
        +    ],
        +    [
        +        "4.8.6.2",
        +        "Overlapping Policies Test6",
        +        "-policy $nist1",
        +        "True", $nist1, $nist1, 0
        +    ],
        +    [
        +        "4.8.6.3",
        +        "Overlapping Policies Test6",
        +        "-policy $nist2",
        +        "True", $nist1, "<empty>", 43
        +    ],
        +    [
        +        "4.8.7",
        +        "Different Policies Test7",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.8",
        +        "Different Policies Test8",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.9",
        +        "Different Policies Test9",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.10.1",
        +        "All Certificates Same Policies Test10",
        +        "-policy $nist1",
        +        "True", "$nist1:$nist2", "$nist1", 0
        +    ],
        +    [
        +        "4.8.10.2",
        +        "All Certificates Same Policies Test10",
        +        "-policy $nist2",
        +        "True", "$nist1:$nist2", "$nist2", 0
        +    ],
        +    [
        +        "4.8.10.3",
        +        "All Certificates Same Policies Test10",
        +        "-policy anyPolicy",
        +        "True", "$nist1:$nist2", "$nist1:$nist2", 0
        +    ],
        +    [
        +        "4.8.11.1",
        +        "All Certificates AnyPolicy Test11",
        +        "-policy anyPolicy",
        +        "True", "$apolicy", "$apolicy", 0
        +    ],
        +    [
        +        "4.8.11.2",
        +        "All Certificates AnyPolicy Test11",
        +        "-policy $nist1",
        +        "True", "$apolicy", "$nist1", 0
        +    ],
        +    [
        +        "4.8.12",
        +        "Different Policies Test12",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.8.13.1",
        +        "All Certificates Same Policies Test13",
        +        "-policy $nist1",
        +        "True", "$nist1:$nist2:$nist3", "$nist1", 0
        +    ],
        +    [
        +        "4.8.13.2",
        +        "All Certificates Same Policies Test13",
        +        "-policy $nist2",
        +        "True", "$nist1:$nist2:$nist3", "$nist2", 0
        +    ],
        +    [
        +        "4.8.13.3",
        +        "All Certificates Same Policies Test13",
        +        "-policy $nist3",
        +        "True", "$nist1:$nist2:$nist3", "$nist3", 0
        +    ],
        +    [
        +        "4.8.14.1",       "AnyPolicy Test14",
        +        "-policy $nist1", "True",
        +        "$nist1",         "$nist1",
        +        0
        +    ],
        +    [
        +        "4.8.14.2",       "AnyPolicy Test14",
        +        "-policy $nist2", "True",
        +        "$nist1",         "<empty>",
        +        43
        +    ],
        +    [
        +        "4.8.15",
        +        "User Notice Qualifier Test15",
        +        "-policy anyPolicy",
        +        "False", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.8.16",
        +        "User Notice Qualifier Test16",
        +        "-policy anyPolicy",
        +        "False", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.8.17",
        +        "User Notice Qualifier Test17",
        +        "-policy anyPolicy",
        +        "False", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.8.18.1",
        +        "User Notice Qualifier Test18",
        +        "-policy $nist1",
        +        "True", "$nist1:$nist2", "$nist1", 0
        +    ],
        +    [
        +        "4.8.18.2",
        +        "User Notice Qualifier Test18",
        +        "-policy $nist2",
        +        "True", "$nist1:$nist2", "$nist2", 0
        +    ],
        +    [
        +        "4.8.19",
        +        "User Notice Qualifier Test19",
        +        "-policy anyPolicy",
        +        "False", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.8.20",
        +        "CPS Pointer Qualifier Test20",
        +        "-policy anyPolicy -explicit_policy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [ "4.9", "Require Explicit Policy" ],
        +    [
        +        "4.9.1",
        +        "Valid RequireExplicitPolicy Test1",
        +        "-policy anyPolicy",
        +        "False", "<empty>", "<empty>", 0
        +    ],
        +    [
        +        "4.9.2",
        +        "Valid RequireExplicitPolicy Test2",
        +        "-policy anyPolicy",
        +        "False", "<empty>", "<empty>", 0
        +    ],
        +    [
        +        "4.9.3",
        +        "Invalid RequireExplicitPolicy Test3",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.9.4",
        +        "Valid RequireExplicitPolicy Test4",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.9.5",
        +        "Invalid RequireExplicitPolicy Test5",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.9.6",
        +        "Valid Self-Issued requireExplicitPolicy Test6",
        +        "-policy anyPolicy",
        +        "False", "<empty>", "<empty>", 0
        +    ],
        +    [
        +        "4.9.7",
        +        "Invalid Self-Issued requireExplicitPolicy Test7",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.9.8",
        +        "Invalid Self-Issued requireExplicitPolicy Test8",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [ "4.10", "Policy Mappings" ],
        +    [
        +        "4.10.1.1",
        +        "Valid Policy Mapping Test1",
        +        "-policy $nist1",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.10.1.2",
        +        "Valid Policy Mapping Test1",
        +        "-policy $nist2",
        +        "True", "$nist1", "<empty>", 43
        +    ],
        +    [
        +        "4.10.1.3",
        +        "Valid Policy Mapping Test1",
        +        "-policy anyPolicy -inhibit_map",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.10.2.1",
        +        "Invalid Policy Mapping Test2",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.10.2.2",
        +        "Invalid Policy Mapping Test2",
        +        "-policy anyPolicy -inhibit_map",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.10.3.1",
        +        "Valid Policy Mapping Test3",
        +        "-policy $nist1",
        +        "True", "$nist2", "<empty>", 43
        +    ],
        +    [
        +        "4.10.3.2",
        +        "Valid Policy Mapping Test3",
        +        "-policy $nist2",
        +        "True", "$nist2", "$nist2", 0
        +    ],
        +    [
        +        "4.10.4",
        +        "Invalid Policy Mapping Test4",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.10.5.1",
        +        "Valid Policy Mapping Test5",
        +        "-policy $nist1",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.10.5.2",
        +        "Valid Policy Mapping Test5",
        +        "-policy $nist6",
        +        "True", "$nist1", "<empty>", 43
        +    ],
        +    [
        +        "4.10.6.1",
        +        "Valid Policy Mapping Test6",
        +        "-policy $nist1",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.10.6.2",
        +        "Valid Policy Mapping Test6",
        +        "-policy $nist6",
        +        "True", "$nist1", "<empty>", 43
        +    ],
        +    [ "4.10.7", "Invalid Mapping From anyPolicy Test7", 42 ],
        +    [ "4.10.8", "Invalid Mapping To anyPolicy Test8",   42 ],
        +    [
        +        "4.10.9",
        +        "Valid Policy Mapping Test9",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.10.10",
        +        "Invalid Policy Mapping Test10",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.10.11",
        +        "Valid Policy Mapping Test11",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +
        +    # TODO: check notice display
        +    [
        +        "4.10.12.1",
        +        "Valid Policy Mapping Test12",
        +        "-policy $nist1",
        +        "True", "$nist1:$nist2", "$nist1", 0
        +    ],
        +
        +    # TODO: check notice display
        +    [
        +        "4.10.12.2",
        +        "Valid Policy Mapping Test12",
        +        "-policy $nist2",
        +        "True", "$nist1:$nist2", "$nist2", 0
        +    ],
        +    [
        +        "4.10.13",
        +        "Valid Policy Mapping Test13",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +
        +    # TODO: check notice display
        +    [
        +        "4.10.14",
        +        "Valid Policy Mapping Test14",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [ "4.11", "Inhibit Policy Mapping" ],
        +    [
        +        "4.11.1",
        +        "Invalid inhibitPolicyMapping Test1",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.2",
        +        "Valid inhibitPolicyMapping Test2",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.11.3",
        +        "Invalid inhibitPolicyMapping Test3",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.4",
        +        "Valid inhibitPolicyMapping Test4",
        +        "-policy anyPolicy",
        +        "True", "$nist2", "$nist2", 0
        +    ],
        +    [
        +        "4.11.5",
        +        "Invalid inhibitPolicyMapping Test5",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.6",
        +        "Invalid inhibitPolicyMapping Test6",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.7",
        +        "Valid Self-Issued inhibitPolicyMapping Test7",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.11.8",
        +        "Invalid Self-Issued inhibitPolicyMapping Test8",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.9",
        +        "Invalid Self-Issued inhibitPolicyMapping Test9",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.10",
        +        "Invalid Self-Issued inhibitPolicyMapping Test10",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.11.11",
        +        "Invalid Self-Issued inhibitPolicyMapping Test11",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [ "4.12", "Inhibit Any Policy" ],
        +    [
        +        "4.12.1",
        +        "Invalid inhibitAnyPolicy Test1",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.12.2",
        +        "Valid inhibitAnyPolicy Test2",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.12.3.1",
        +        "inhibitAnyPolicy Test3",
        +        "-policy anyPolicy",
        +        "True", "$nist1", "$nist1", 0
        +    ],
        +    [
        +        "4.12.3.2",
        +        "inhibitAnyPolicy Test3",
        +        "-policy anyPolicy -inhibit_any",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.12.4",
        +        "Invalid inhibitAnyPolicy Test4",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.12.5",
        +        "Invalid inhibitAnyPolicy Test5",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [
        +        "4.12.6",
        +        "Invalid inhibitAnyPolicy Test6",
        +        "-policy anyPolicy",
        +        "True", "<empty>", "<empty>", 43
        +    ],
        +    [ "4.12.7",  "Valid Self-Issued inhibitAnyPolicy Test7",      0 ],
        +    [ "4.12.8",  "Invalid Self-Issued inhibitAnyPolicy Test8",    43 ],
        +    [ "4.12.9",  "Valid Self-Issued inhibitAnyPolicy Test9",      0 ],
        +    [ "4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10",   43 ],
        +    [ "4.13",    "Name Constraints" ],
        +    [ "4.13.1",  "Valid DN nameConstraints Test1",                0 ],
        +    [ "4.13.2",  "Invalid DN nameConstraints Test2",              47 ],
        +    [ "4.13.3",  "Invalid DN nameConstraints Test3",              47 ],
        +    [ "4.13.4",  "Valid DN nameConstraints Test4",                0 ],
        +    [ "4.13.5",  "Valid DN nameConstraints Test5",                0 ],
        +    [ "4.13.6",  "Valid DN nameConstraints Test6",                0 ],
        +    [ "4.13.7",  "Invalid DN nameConstraints Test7",              48 ],
        +    [ "4.13.8",  "Invalid DN nameConstraints Test8",              48 ],
        +    [ "4.13.9",  "Invalid DN nameConstraints Test9",              48 ],
        +    [ "4.13.10", "Invalid DN nameConstraints Test10",             48 ],
        +    [ "4.13.11", "Valid DN nameConstraints Test11",               0 ],
        +    [ "4.13.12", "Invalid DN nameConstraints Test12",             47 ],
        +    [ "4.13.13", "Invalid DN nameConstraints Test13",             47 ],
        +    [ "4.13.14", "Valid DN nameConstraints Test14",               0 ],
        +    [ "4.13.15", "Invalid DN nameConstraints Test15",             48 ],
        +    [ "4.13.16", "Invalid DN nameConstraints Test16",             48 ],
        +    [ "4.13.17", "Invalid DN nameConstraints Test17",             48 ],
        +    [ "4.13.18", "Valid DN nameConstraints Test18",               0 ],
        +    [ "4.13.19", "Valid Self-Issued DN nameConstraints Test19",   0 ],
        +    [ "4.13.20", "Invalid Self-Issued DN nameConstraints Test20", 47 ],
        +    [ "4.13.21", "Valid RFC822 nameConstraints Test21",           0 ],
        +    [ "4.13.22", "Invalid RFC822 nameConstraints Test22",         47 ],
        +    [ "4.13.23", "Valid RFC822 nameConstraints Test23",           0 ],
        +    [ "4.13.24", "Invalid RFC822 nameConstraints Test24",         47 ],
        +    [ "4.13.25", "Valid RFC822 nameConstraints Test25",           0 ],
        +    [ "4.13.26", "Invalid RFC822 nameConstraints Test26",         48 ],
        +    [ "4.13.27", "Valid DN and RFC822 nameConstraints Test27",    0 ],
        +    [ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28",  47 ],
        +    [ "4.13.29", "Invalid DN and RFC822 nameConstraints Test29",  47 ],
        +    [ "4.13.30", "Valid DNS nameConstraints Test30",              0 ],
        +    [ "4.13.31", "Invalid DNS nameConstraints Test31",            47 ],
        +    [ "4.13.32", "Valid DNS nameConstraints Test32",              0 ],
        +    [ "4.13.33", "Invalid DNS nameConstraints Test33",            48 ],
        +    [ "4.13.34", "Valid URI nameConstraints Test34",              0 ],
        +    [ "4.13.35", "Invalid URI nameConstraints Test35",            47 ],
        +    [ "4.13.36", "Valid URI nameConstraints Test36",              0 ],
        +    [ "4.13.37", "Invalid URI nameConstraints Test37",            48 ],
        +    [ "4.13.38", "Invalid DNS nameConstraints Test38",            47 ],
        +    [ "4.14",    "Distribution Points" ],
        +    [ "4.14.1",  "Valid distributionPoint Test1",                 0 ],
        +    [ "4.14.2",  "Invalid distributionPoint Test2",               23 ],
        +    [ "4.14.3",  "Invalid distributionPoint Test3",               44 ],
        +    [ "4.14.4",  "Valid distributionPoint Test4",                 0 ],
        +    [ "4.14.5",  "Valid distributionPoint Test5",                 0 ],
        +    [ "4.14.6",  "Invalid distributionPoint Test6",               23 ],
        +    [ "4.14.7",  "Valid distributionPoint Test7",                 0 ],
        +    [ "4.14.8",  "Invalid distributionPoint Test8",               44 ],
        +    [ "4.14.9",  "Invalid distributionPoint Test9",               44 ],
        +    [ "4.14.10", "Valid No issuingDistributionPoint Test10",      0 ],
        +    [ "4.14.11", "Invalid onlyContainsUserCerts CRL Test11",      44 ],
        +    [ "4.14.12", "Invalid onlyContainsCACerts CRL Test12",        44 ],
        +    [ "4.14.13", "Valid onlyContainsCACerts CRL Test13",          0 ],
        +    [ "4.14.14", "Invalid onlyContainsAttributeCerts Test14",     44 ],
        +    [ "4.14.15", "Invalid onlySomeReasons Test15",                23 ],
        +    [ "4.14.16", "Invalid onlySomeReasons Test16",                23 ],
        +    [ "4.14.17", "Invalid onlySomeReasons Test17",                3 ],
        +    [ "4.14.18", "Valid onlySomeReasons Test18",                  0 ],
        +    [ "4.14.19", "Valid onlySomeReasons Test19",                  0 ],
        +    [ "4.14.20", "Invalid onlySomeReasons Test20",                23 ],
        +    [ "4.14.21", "Invalid onlySomeReasons Test21",                23 ],
        +    [ "4.14.22", "Valid IDP with indirectCRL Test22",             0 ],
        +    [ "4.14.23", "Invalid IDP with indirectCRL Test23",           23 ],
        +    [ "4.14.24", "Valid IDP with indirectCRL Test24",             0 ],
        +    [ "4.14.25", "Valid IDP with indirectCRL Test25",             0 ],
        +    [ "4.14.26", "Invalid IDP with indirectCRL Test26",           44 ],
        +    [ "4.14.27", "Invalid cRLIssuer Test27",                      3 ],
        +    [ "4.14.28", "Valid cRLIssuer Test28",                        0 ],
        +    [ "4.14.29", "Valid cRLIssuer Test29",                        0 ],
        +
        +    # Although this test is valid it has a circular dependency. As a result
        +    # an attempt is made to reursively checks a CRL path and rejected due to
        +    # a CRL path validation error. PKITS notes suggest this test does not
        +    # need to be run due to this issue.
        +    [ "4.14.30", "Valid cRLIssuer Test30",                                 54 ],
        +    [ "4.14.31", "Invalid cRLIssuer Test31",                               23 ],
        +    [ "4.14.32", "Invalid cRLIssuer Test32",                               23 ],
        +    [ "4.14.33", "Valid cRLIssuer Test33",                                 0 ],
        +    [ "4.14.34", "Invalid cRLIssuer Test34",                               23 ],
        +    [ "4.14.35", "Invalid cRLIssuer Test35",                               44 ],
        +    [ "4.15",    "Delta-CRLs" ],
        +    [ "4.15.1",  "Invalid deltaCRLIndicator No Base Test1",                3 ],
        +    [ "4.15.2",  "Valid delta-CRL Test2",                                  0 ],
        +    [ "4.15.3",  "Invalid delta-CRL Test3",                                23 ],
        +    [ "4.15.4",  "Invalid delta-CRL Test4",                                23 ],
        +    [ "4.15.5",  "Valid delta-CRL Test5",                                  0 ],
        +    [ "4.15.6",  "Invalid delta-CRL Test6",                                23 ],
        +    [ "4.15.7",  "Valid delta-CRL Test7",                                  0 ],
        +    [ "4.15.8",  "Valid delta-CRL Test8",                                  0 ],
        +    [ "4.15.9",  "Invalid delta-CRL Test9",                                23 ],
        +    [ "4.15.10", "Invalid delta-CRL Test10",                               12 ],
        +    [ "4.16",    "Private Certificate Extensions" ],
        +    [ "4.16.1",  "Valid Unknown Not Critical Certificate Extension Test1", 0 ],
        +    [ "4.16.2",  "Invalid Unknown Critical Certificate Extension Test2",   34 ],
        +);
        +
        +
        +my $verbose = 1;
        +
        +my $numtest = 0;
        +my $numfail = 0;
        +
        +my $ossl = "ossl/apps/openssl";
        +
        +my $ossl_cmd = "$ossl_path cms -verify -verify_retcode ";
        +$ossl_cmd .= "-CAfile pkitsta.pem -crl_check_all -x509_strict ";
        +
        +# Check for expiry of trust anchor
        +system "$ossl_path x509 -inform DER -in $pkitsta -checkend 0";
        +if ($? == 256)
        +	{
        +	print STDERR "WARNING: using older expired data\n";
        +	$ossl_cmd .= "-attime 1291940972 ";
        +	}
        +
        +$ossl_cmd .= "-policy_check -extended_crl -use_deltas -out /dev/null 2>&1 ";
        +
        +system "$ossl_path x509 -inform DER -in $pkitsta -out pkitsta.pem";
        +
        +die "Can't create trust anchor file" if $?;
        +
        +print "Running PKITS tests:\n" if $verbose;
        +
        +foreach (@testlists) {
        +    my $argnum = @$_;
        +    if ( $argnum == 2 ) {
        +        my ( $tnum, $title ) = @$_;
        +        print "$tnum $title\n" if $verbose;
        +    }
        +    elsif ( $argnum == 3 ) {
        +        my ( $tnum, $title, $exp_ret ) = @$_;
        +        my $filename = $title;
        +        $exp_ret += 32 if $exp_ret;
        +        $filename =~ tr/ -//d;
        +        $filename = "Signed${filename}.eml";
        +        if ( !-f "$pkitsdir/$filename" ) {
        +            print "\"$filename\" not found\n";
        +        }
        +        else {
        +            my $ret;
        +            my $test_fail = 0;
        +            my $errmsg    = "";
        +            my $cmd       = $ossl_cmd;
        +            $cmd .= "-in $pkitsdir/$filename -policy anyPolicy";
        +            my $cmdout = `$cmd`;
        +            $ret = $? >> 8;
        +            if ( $? & 0xff ) {
        +                $errmsg .= "Abnormal OpenSSL termination\n";
        +                $test_fail = 1;
        +            }
        +            if ( $exp_ret != $ret ) {
        +                $errmsg .= "Return code:$ret, ";
        +                $errmsg .= "expected $exp_ret\n";
        +                $test_fail = 1;
        +            }
        +            if ($test_fail) {
        +                print "$tnum $title : Failed!\n";
        +                print "Filename: $pkitsdir/$filename\n";
        +                print $errmsg;
        +                print "Command output:\n$cmdout\n";
        +                $numfail++;
        +            }
        +            $numtest++;
        +        }
        +    }
        +    elsif ( $argnum == 7 ) {
        +        my ( $tnum, $title, $exargs, $exp_epol, $exp_aset, $exp_uset, $exp_ret )
        +          = @$_;
        +        my $filename = $title;
        +        $exp_ret += 32 if $exp_ret;
        +        $filename =~ tr/ -//d;
        +        $filename = "Signed${filename}.eml";
        +        if ( !-f "$pkitsdir/$filename" ) {
        +            print "\"$filename\" not found\n";
        +        }
        +        else {
        +            my $ret;
        +            my $cmdout    = "";
        +            my $errmsg    = "";
        +            my $epol      = "";
        +            my $aset      = "";
        +            my $uset      = "";
        +            my $pol       = -1;
        +            my $test_fail = 0;
        +            my $cmd       = $ossl_cmd;
        +            $cmd .= "-in $pkitsdir/$filename $exargs -policy_print";
        +            @oparr = `$cmd`;
        +            $ret   = $? >> 8;
        +
        +            if ( $? & 0xff ) {
        +                $errmsg .= "Abnormal OpenSSL termination\n";
        +                $test_fail = 1;
        +            }
        +            foreach (@oparr) {
        +                my $test_failed = 0;
        +                $cmdout .= $_;
        +                if (/^Require explicit Policy: (.*)$/) {
        +                    $epol = $1;
        +                }
        +                if (/^Authority Policies/) {
        +                    if (/empty/) {
        +                        $aset = "<empty>";
        +                    }
        +                    else {
        +                        $pol = 1;
        +                    }
        +                }
        +                $test_fail = 1 if (/leak/i);
        +                if (/^User Policies/) {
        +                    if (/empty/) {
        +                        $uset = "<empty>";
        +                    }
        +                    else {
        +                        $pol = 2;
        +                    }
        +                }
        +                if (/\s+Policy: (.*)$/) {
        +                    if ( $pol == 1 ) {
        +                        $aset .= ":" if $aset ne "";
        +                        $aset .= $1;
        +                    }
        +                    elsif ( $pol == 2 ) {
        +                        $uset .= ":" if $uset ne "";
        +                        $uset .= $1;
        +                    }
        +                }
        +            }
        +
        +            if ( $epol ne $exp_epol ) {
        +                $errmsg .= "Explicit policy:$epol, ";
        +                $errmsg .= "expected $exp_epol\n";
        +                $test_fail = 1;
        +            }
        +            if ( $aset ne $exp_aset ) {
        +                $errmsg .= "Authority policy set :$aset, ";
        +                $errmsg .= "expected $exp_aset\n";
        +                $test_fail = 1;
        +            }
        +            if ( $uset ne $exp_uset ) {
        +                $errmsg .= "User policy set :$uset, ";
        +                $errmsg .= "expected $exp_uset\n";
        +                $test_fail = 1;
        +            }
        +
        +            if ( $exp_ret != $ret ) {
        +                print "Return code:$ret, expected $exp_ret\n";
        +                $test_fail = 1;
        +            }
        +
        +            if ($test_fail) {
        +                print "$tnum $title : Failed!\n";
        +                print "Filename: $pkitsdir/$filename\n";
        +                print "Command output:\n$cmdout\n";
        +                $numfail++;
        +            }
        +            $numtest++;
        +        }
        +    }
        +}
        +
        +if ($numfail) {
        +    print "$numfail tests failed out of $numtest\n";
        +}
        +else {
        +    print "All Tests Successful.\n";
        +}
        +
        +unlink "pkitsta.pem";
        +
        diff --git a/vendor/openssl/openssl/test/r160test.c b/vendor/openssl/openssl/test/r160test.c
        new file mode 100644
        index 000000000..a172e393c
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/r160test.c
        @@ -0,0 +1,57 @@
        +/* test/r160test.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.]
        + */
        diff --git a/vendor/openssl/openssl/test/randtest.c b/vendor/openssl/openssl/test/randtest.c
        new file mode 100644
        index 000000000..9e92a70b0
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/randtest.c
        @@ -0,0 +1,219 @@
        +/* crypto/rand/randtest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/rand.h>
        +
        +#include "../e_os.h"
        +
        +/* some FIPS 140-1 random number test */
        +/* some simple tests */
        +
        +int main(int argc,char **argv)
        +	{
        +	unsigned char buf[2500];
        +	int i,j,k,s,sign,nsign,err=0;
        +	unsigned long n1;
        +	unsigned long n2[16];
        +	unsigned long runs[2][34];
        +	/*double d; */
        +	long d;
        +
        +	i = RAND_pseudo_bytes(buf,2500);
        +	if (i < 0)
        +		{
        +		printf ("init failed, the rand method is not properly installed\n");
        +		err++;
        +		goto err;
        +		}
        +
        +	n1=0;
        +	for (i=0; i<16; i++) n2[i]=0;
        +	for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
        +
        +	/* test 1 and 2 */
        +	sign=0;
        +	nsign=0;
        +	for (i=0; i<2500; i++)
        +		{
        +		j=buf[i];
        +
        +		n2[j&0x0f]++;
        +		n2[(j>>4)&0x0f]++;
        +
        +		for (k=0; k<8; k++)
        +			{
        +			s=(j&0x01);
        +			if (s == sign)
        +				nsign++;
        +			else
        +				{
        +				if (nsign > 34) nsign=34;
        +				if (nsign != 0)
        +					{
        +					runs[sign][nsign-1]++;
        +					if (nsign > 6)
        +						runs[sign][5]++;
        +					}
        +				sign=s;
        +				nsign=1;
        +				}
        +
        +			if (s) n1++;
        +			j>>=1;
        +			}
        +		}
        +		if (nsign > 34) nsign=34;
        +		if (nsign != 0) runs[sign][nsign-1]++;
        +
        +	/* test 1 */
        +	if (!((9654 < n1) && (n1 < 10346)))
        +		{
        +		printf("test 1 failed, X=%lu\n",n1);
        +		err++;
        +		}
        +	printf("test 1 done\n");
        +
        +	/* test 2 */
        +#ifdef undef
        +	d=0;
        +	for (i=0; i<16; i++)
        +		d+=n2[i]*n2[i];
        +	d=d*16.0/5000.0-5000.0;
        +	if (!((1.03 < d) && (d < 57.4)))
        +		{
        +		printf("test 2 failed, X=%.2f\n",d);
        +		err++;
        +		}
        +#endif
        +	d=0;
        +	for (i=0; i<16; i++)
        +		d+=n2[i]*n2[i];
        +	d=(d*8)/25-500000;
        +	if (!((103 < d) && (d < 5740)))
        +		{
        +		printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
        +		err++;
        +		}
        +	printf("test 2 done\n");
        +
        +	/* test 3 */
        +	for (i=0; i<2; i++)
        +		{
        +		if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,1,runs[i][0]);
        +			err++;
        +			}
        +		if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,2,runs[i][1]);
        +			err++;
        +			}
        +		if (!(( 502 < runs[i][2]) && (runs[i][2] <  748)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,3,runs[i][2]);
        +			err++;
        +			}
        +		if (!(( 223 < runs[i][3]) && (runs[i][3] <  402)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,4,runs[i][3]);
        +			err++;
        +			}
        +		if (!((  90 < runs[i][4]) && (runs[i][4] <  223)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,5,runs[i][4]);
        +			err++;
        +			}
        +		if (!((  90 < runs[i][5]) && (runs[i][5] <  223)))
        +			{
        +			printf("test 3 failed, bit=%d run=%d num=%lu\n",
        +				i,6,runs[i][5]);
        +			err++;
        +			}
        +		}
        +	printf("test 3 done\n");
        +	
        +	/* test 4 */
        +	if (runs[0][33] != 0)
        +		{
        +		printf("test 4 failed, bit=%d run=%d num=%lu\n",
        +			0,34,runs[0][33]);
        +		err++;
        +		}
        +	if (runs[1][33] != 0)
        +		{
        +		printf("test 4 failed, bit=%d run=%d num=%lu\n",
        +			1,34,runs[1][33]);
        +		err++;
        +		}
        +	printf("test 4 done\n");
        + err:
        +	err=((err)?1:0);
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(err);
        +	}
        diff --git a/vendor/openssl/openssl/test/rc2test.c b/vendor/openssl/openssl/test/rc2test.c
        new file mode 100644
        index 000000000..0e117436b
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/rc2test.c
        @@ -0,0 +1,274 @@
        +/* crypto/rc2/rc2test.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.]
        + */
        +
        +/* This has been a quickly hacked 'ideatest.c'.  When I add tests for other
        + * RC2 modes, more of the code will be uncommented. */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RC2
        +int main(int argc, char *argv[])
        +{
        +    printf("No RC2 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rc2.h>
        +
        +static unsigned char RC2key[4][16]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
        +	 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
        +	};
        +
        +static unsigned char RC2plain[4][8]={
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	};
        +
        +static unsigned char RC2cipher[4][8]={
        +	{0x1C,0x19,0x8A,0x83,0x8D,0xF0,0x28,0xB7},
        +	{0x21,0x82,0x9C,0x78,0xA9,0xF9,0xC0,0x74},
        +	{0x13,0xDB,0x35,0x17,0xD3,0x21,0x86,0x9E},
        +	{0x50,0xDC,0x01,0x62,0xBD,0x75,0x7F,0x31},
        +	};
        +/************/
        +#ifdef undef
        +unsigned char k[16]={
        +	0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,
        +	0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08};
        +
        +unsigned char in[8]={0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03};
        +unsigned char  c[8]={0x11,0xFB,0xED,0x2B,0x01,0x98,0x6D,0xE5};
        +unsigned char out[80];
        +
        +char *text="Hello to all people out there";
        +
        +static unsigned char cfb_key[16]={
        +	0xe1,0xf0,0xc3,0xd2,0xa5,0xb4,0x87,0x96,
        +	0x69,0x78,0x4b,0x5a,0x2d,0x3c,0x0f,0x1e,
        +	};
        +static unsigned char cfb_iv[80]={0x34,0x12,0x78,0x56,0xab,0x90,0xef,0xcd};
        +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
        +#define CFB_TEST_SIZE 24
        +static unsigned char plain[CFB_TEST_SIZE]=
        +        {
        +        0x4e,0x6f,0x77,0x20,0x69,0x73,
        +        0x20,0x74,0x68,0x65,0x20,0x74,
        +        0x69,0x6d,0x65,0x20,0x66,0x6f,
        +        0x72,0x20,0x61,0x6c,0x6c,0x20
        +        };
        +static unsigned char cfb_cipher64[CFB_TEST_SIZE]={
        +	0x59,0xD8,0xE2,0x65,0x00,0x58,0x6C,0x3F,
        +	0x2C,0x17,0x25,0xD0,0x1A,0x38,0xB7,0x2A,
        +	0x39,0x61,0x37,0xDC,0x79,0xFB,0x9F,0x45
        +
        +/*	0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38,
        +	0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9,
        +	0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/
        +	}; 
        +
        +
        +/*static int cfb64_test(unsigned char *cfb_cipher);*/
        +static char *pt(unsigned char *p);
        +#endif
        +
        +int main(int argc, char *argv[])
        +	{
        +	int i,n,err=0;
        +	RC2_KEY key; 
        +	unsigned char buf[8],buf2[8];
        +
        +	for (n=0; n<4; n++)
        +		{
        +		RC2_set_key(&key,16,&(RC2key[n][0]),0 /* or 1024 */);
        +
        +		RC2_ecb_encrypt(&(RC2plain[n][0]),buf,&key,RC2_ENCRYPT);
        +		if (memcmp(&(RC2cipher[n][0]),buf,8) != 0)
        +			{
        +			printf("ecb rc2 error encrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",RC2cipher[n][i]);
        +			err=20;
        +			printf("\n");
        +			}
        +
        +		RC2_ecb_encrypt(buf,buf2,&key,RC2_DECRYPT);
        +		if (memcmp(&(RC2plain[n][0]),buf2,8) != 0)
        +			{
        +			printf("ecb RC2 error decrypting\n");
        +			printf("got     :");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",buf[i]);
        +			printf("\n");
        +			printf("expected:");
        +			for (i=0; i<8; i++)
        +				printf("%02X ",RC2plain[n][i]);
        +			printf("\n");
        +			err=3;
        +			}
        +		}
        +
        +	if (err == 0) printf("ecb RC2 ok\n");
        +#ifdef undef
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt((unsigned char *)text,out,strlen(text)+1,&key,iv,1);
        +	memcpy(iv,k,8);
        +	idea_cbc_encrypt(out,out,8,&dkey,iv,0);
        +	idea_cbc_encrypt(&(out[8]),&(out[8]),strlen(text)+1-8,&dkey,iv,0);
        +	if (memcmp(text,out,strlen(text)+1) != 0)
        +		{
        +		printf("cbc idea bad\n");
        +		err=4;
        +		}
        +	else
        +		printf("cbc idea ok\n");
        +
        +	printf("cfb64 idea ");
        +	if (cfb64_test(cfb_cipher64))
        +		{
        +		printf("bad\n");
        +		err=5;
        +		}
        +	else
        +		printf("ok\n");
        +#endif
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(err);
        +	}
        +
        +#ifdef undef
        +static int cfb64_test(unsigned char *cfb_cipher)
        +        {
        +        IDEA_KEY_SCHEDULE eks,dks;
        +        int err=0,i,n;
        +
        +        idea_set_encrypt_key(cfb_key,&eks);
        +        idea_set_decrypt_key(&eks,&dks);
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(plain,cfb_buf1,(long)12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        idea_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
        +                (long)CFB_TEST_SIZE-12,&eks,
        +                cfb_tmp,&n,IDEA_ENCRYPT);
        +        if (memcmp(cfb_cipher,cfb_buf1,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb64_encrypt encrypt error\n");
        +                for (i=0; i<CFB_TEST_SIZE; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf1[i])));
        +                }
        +        memcpy(cfb_tmp,cfb_iv,8);
        +        n=0;
        +        idea_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,&eks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        idea_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
        +                (long)CFB_TEST_SIZE-17,&dks,
        +                cfb_tmp,&n,IDEA_DECRYPT);
        +        if (memcmp(plain,cfb_buf2,CFB_TEST_SIZE) != 0)
        +                {
        +                err=1;
        +                printf("idea_cfb_encrypt decrypt error\n");
        +                for (i=0; i<24; i+=8)
        +                        printf("%s\n",pt(&(cfb_buf2[i])));
        +                }
        +        return(err);
        +        }
        +
        +static char *pt(unsigned char *p)
        +	{
        +	static char bufs[10][20];
        +	static int bnum=0;
        +	char *ret;
        +	int i;
        +	static char *f="0123456789ABCDEF";
        +
        +	ret= &(bufs[bnum++][0]);
        +	bnum%=10;
        +	for (i=0; i<8; i++)
        +		{
        +		ret[i*2]=f[(p[i]>>4)&0xf];
        +		ret[i*2+1]=f[p[i]&0xf];
        +		}
        +	ret[16]='\0';
        +	return(ret);
        +	}
        +	
        +#endif
        +#endif
        diff --git a/vendor/openssl/openssl/test/rc4test.c b/vendor/openssl/openssl/test/rc4test.c
        new file mode 100644
        index 000000000..4312605cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/rc4test.c
        @@ -0,0 +1,242 @@
        +/* crypto/rc4/rc4test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RC4
        +int main(int argc, char *argv[])
        +{
        +    printf("No RC4 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rc4.h>
        +#include <openssl/sha.h>
        +
        +static unsigned char keys[7][30]={
        +	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
        +	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
        +	{8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        +	{4,0xef,0x01,0x23,0x45},
        +	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
        +	{4,0xef,0x01,0x23,0x45},
        +	};
        +
        +static unsigned char data_len[7]={8,8,8,20,28,10};
        +static unsigned char data[7][30]={
        +	{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        +	   0x00,0x00,0x00,0x00,0xff},
        +	{0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
        +	   0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
        +	   0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0,
        +	   0x12,0x34,0x56,0x78,0xff},
        +	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
        +	{0},
        +	};
        +
        +static unsigned char output[7][30]={
        +	{0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
        +	{0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
        +	{0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
        +	{0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,
        +	 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba,
        +	 0x36,0xb6,0x78,0x58,0x00},
        +	{0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89,
        +	 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c,
        +	 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87,
        +	 0x40,0x01,0x1e,0xcf,0x00},
        +	{0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00},
        +	{0},
        +	};
        +
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	int j;
        +	unsigned char *p;
        +	RC4_KEY key;
        +	unsigned char obuf[512];
        +
        +#if !defined(OPENSSL_PIC)
        +	void OPENSSL_cpuid_setup(void);
        +
        +	OPENSSL_cpuid_setup();
        +#endif
        +
        +	for (i=0; i<6; i++)
        +		{
        +		RC4_set_key(&key,keys[i][0],&(keys[i][1]));
        +		memset(obuf,0x00,sizeof(obuf));
        +		RC4(&key,data_len[i],&(data[i][0]),obuf);
        +		if (memcmp(obuf,output[i],data_len[i]+1) != 0)
        +			{
        +			printf("error calculating RC4\n");
        +			printf("output:");
        +			for (j=0; j<data_len[i]+1; j++)
        +				printf(" %02x",obuf[j]);
        +			printf("\n");
        +			printf("expect:");
        +			p= &(output[i][0]);
        +			for (j=0; j<data_len[i]+1; j++)
        +				printf(" %02x",*(p++));
        +			printf("\n");
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		}
        +	printf("test end processing ");
        +	for (i=0; i<data_len[3]; i++)
        +		{
        +		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
        +		memset(obuf,0x00,sizeof(obuf));
        +		RC4(&key,i,&(data[3][0]),obuf);
        +		if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0))
        +			{
        +			printf("error in RC4 length processing\n");
        +			printf("output:");
        +			for (j=0; j<i+1; j++)
        +				printf(" %02x",obuf[j]);
        +			printf("\n");
        +			printf("expect:");
        +			p= &(output[3][0]);
        +			for (j=0; j<i; j++)
        +				printf(" %02x",*(p++));
        +			printf(" 00\n");
        +			err++;
        +			}
        +		else
        +			{
        +			printf(".");
        +			fflush(stdout);
        +			}
        +		}
        +	printf("done\n");
        +	printf("test multi-call ");
        +	for (i=0; i<data_len[3]; i++)
        +		{
        +		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
        +		memset(obuf,0x00,sizeof(obuf));
        +		RC4(&key,i,&(data[3][0]),obuf);
        +		RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i]));
        +		if (memcmp(obuf,output[3],data_len[3]+1) != 0)
        +			{
        +			printf("error in RC4 multi-call processing\n");
        +			printf("output:");
        +			for (j=0; j<data_len[3]+1; j++)
        +				printf(" %02x",obuf[j]);
        +			printf("\n");
        +			printf("expect:");
        +			p= &(output[3][0]);
        +			for (j=0; j<data_len[3]+1; j++)
        +				printf(" %02x",*(p++));
        +			err++;
        +			}
        +		else
        +			{
        +			printf(".");
        +			fflush(stdout);
        +			}
        +		}
        +	printf("done\n");
        +	printf("bulk test ");
        +	{   unsigned char buf[513];
        +	    SHA_CTX c;
        +	    unsigned char md[SHA_DIGEST_LENGTH];
        +	    static unsigned char expected[]={
        +		0xa4,0x7b,0xcc,0x00,0x3d,0xd0,0xbd,0xe1,0xac,0x5f,
        +		0x12,0x1e,0x45,0xbc,0xfb,0x1a,0xa1,0xf2,0x7f,0xc5 };
        +
        +		RC4_set_key(&key,keys[0][0],&(keys[3][1]));
        +		memset(buf,'\0',sizeof(buf));
        +		SHA1_Init(&c);
        +		for (i=0;i<2571;i++) {
        +			RC4(&key,sizeof(buf),buf,buf);
        +			SHA1_Update(&c,buf,sizeof(buf));
        +		}
        +		SHA1_Final(md,&c);
        +
        +		if (memcmp(md,expected,sizeof(md))) {
        +			printf("error in RC4 bulk test\n");
        +			printf("output:");
        +			for (j=0; j<(int)sizeof(md); j++)
        +				printf(" %02x",md[j]);
        +			printf("\n");
        +			printf("expect:");
        +			for (j=0; j<(int)sizeof(md); j++)
        +				printf(" %02x",expected[j]);
        +			printf("\n");
        +			err++;
        +		}
        +		else	printf("ok\n");
        +	}
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	return(0);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/rc5test.c b/vendor/openssl/openssl/test/rc5test.c
        new file mode 100644
        index 000000000..5b4467e04
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/rc5test.c
        @@ -0,0 +1,48 @@
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <ctype.h>
        +#include <openssl/e_os2.h>
        +#include <openssl/buffer.h>
        +#include <openssl/crypto.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *p, *q = 0, *program;
        +
        +	p = strrchr(argv[0], '/');
        +	if (!p) p = strrchr(argv[0], '\\');
        +#ifdef OPENSSL_SYS_VMS
        +	if (!p) p = strrchr(argv[0], ']');
        +	if (p) q = strrchr(p, '>');
        +	if (q) p = q;
        +	if (!p) p = strrchr(argv[0], ':');
        +	q = 0;
        +#endif
        +	if (p) p++;
        +	if (!p) p = argv[0];
        +	if (p) q = strchr(p, '.');
        +	if (p && !q) q = p + strlen(p);
        +
        +	if (!p)
        +		program = BUF_strdup("(unknown)");
        +	else
        +		{
        +		program = OPENSSL_malloc((q - p) + 1);
        +		strncpy(program, p, q - p);
        +		program[q - p] = '\0';
        +		}
        +
        +	for(p = program; *p; p++)
        +		if (islower((unsigned char)(*p)))
        +			*p = toupper((unsigned char)(*p));
        +
        +	q = strstr(program, "TEST");
        +	if (q > p && q[-1] == '_') q--;
        +	*q = '\0';
        +
        +	printf("No %s support\n", program);
        +
        +	OPENSSL_free(program);
        +	return(0);
        +	}
        diff --git a/vendor/openssl/openssl/test/rmdtest.c b/vendor/openssl/openssl/test/rmdtest.c
        new file mode 100644
        index 000000000..fb34e0e83
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/rmdtest.c
        @@ -0,0 +1,145 @@
        +/* crypto/ripemd/rmdtest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_RIPEMD
        +int main(int argc, char *argv[])
        +{
        +    printf("No ripemd support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/ripemd.h>
        +#include <openssl/evp.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +static char *test[]={
        +	"",
        +	"a",
        +	"abc",
        +	"message digest",
        +	"abcdefghijklmnopqrstuvwxyz",
        +	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
        +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        +	"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
        +	NULL,
        +	};
        +
        +static char *ret[]={
        +	"9c1185a5c5e9fc54612808977ee8f548b2258d31",
        +	"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe",
        +	"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
        +	"5d0689ef49d2fae572b881b123a85ffa21595f36",
        +	"f71c27109c692c1b56bbdceb5b9d2865b3708dbc",
        +	"12a053384a9c0c88e405a06c27dcf49ada62eb2b",
        +	"b0e20b6e3116640286ed3a87a5713079b21f5189",
        +	"9b752e45573d4b39f4dbd3323cab82bf63326bfb",
        +	};
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	char *p;
        +	unsigned char md[RIPEMD160_DIGEST_LENGTH];
        +
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +#ifdef CHARSET_EBCDIC
        +		ebcdic2ascii((char *)*P, (char *)*P, strlen((char *)*P));
        +#endif
        +		EVP_Digest(&(P[0][0]),strlen((char *)*P),md,NULL,EVP_ripemd160(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,(char *)*R) != 0)
        +			{
        +			printf("error calculating RIPEMD160 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<RIPEMD160_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/rsa_test.c b/vendor/openssl/openssl/test/rsa_test.c
        new file mode 100644
        index 000000000..c8705a0f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/rsa_test.c
        @@ -0,0 +1,340 @@
        +/* test vectors from p1ovect1.txt */
        +
        +#include <stdio.h>
        +#include <string.h>
        +
        +#include "e_os.h"
        +
        +#include <openssl/crypto.h>
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +#include <openssl/bn.h>
        +#ifdef OPENSSL_NO_RSA
        +int main(int argc, char *argv[])
        +{
        +    printf("No RSA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/rsa.h>
        +
        +#define SetKey \
        +  key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
        +  key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
        +  key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
        +  key->p = BN_bin2bn(p, sizeof(p)-1, key->p); \
        +  key->q = BN_bin2bn(q, sizeof(q)-1, key->q); \
        +  key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); \
        +  key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); \
        +  key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); \
        +  memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \
        +  return (sizeof(ctext_ex) - 1);
        +
        +static int key1(RSA *key, unsigned char *c)
        +    {
        +    static unsigned char n[] =
        +"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
        +"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
        +"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
        +"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
        +"\xF5";
        +
        +    static unsigned char e[] = "\x11";
        +
        +    static unsigned char d[] =
        +"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
        +"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
        +"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
        +"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
        +
        +    static unsigned char p[] =
        +"\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
        +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
        +"\x0D";
        +    
        +    static unsigned char q[] =
        +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
        +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
        +"\x89";
        +
        +    static unsigned char dmp1[] =
        +"\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
        +"\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
        +
        +    static unsigned char dmq1[] =
        +"\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
        +"\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
        +"\x51";
        +
        +    static unsigned char iqmp[] =
        +"\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
        +"\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
        +
        +    static unsigned char ctext_ex[] =
        +"\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89"
        +"\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52"
        +"\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44"
        +"\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
        +
        +    SetKey;
        +    }
        +
        +static int key2(RSA *key, unsigned char *c)
        +    {
        +    static unsigned char n[] =
        +"\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8"
        +"\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26"
        +"\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8"
        +"\x34\x77\xCF";
        +
        +    static unsigned char e[] = "\x3";
        +
        +    static unsigned char d[] =
        +"\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2"
        +"\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41"
        +"\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21"
        +"\xE5\xEB";
        +
        +    static unsigned char p[] =
        +"\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92"
        +"\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91";
        +
        +    static unsigned char q[] =
        +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
        +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F";
        +    
        +    static unsigned char dmp1[] =
        +"\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61"
        +"\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B";
        +
        +    static unsigned char dmq1[] =
        +"\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90"
        +"\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F";
        +
        +    static unsigned char iqmp[] =
        +"\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13"
        +"\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D";
        +
        +    static unsigned char ctext_ex[] =
        +"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
        +"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
        +"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
        +"\x62\x51";
        +
        +    SetKey;
        +    }
        +
        +static int key3(RSA *key, unsigned char *c)
        +    {
        +    static unsigned char n[] =
        +"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
        +"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
        +"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
        +"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
        +"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
        +"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
        +"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
        +"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
        +"\xCB";
        +
        +    static unsigned char e[] = "\x11";
        +
        +    static unsigned char d[] =
        +"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
        +"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
        +"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
        +"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
        +"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
        +"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
        +"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
        +"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
        +"\xC1";
        +
        +    static unsigned char p[] =
        +"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
        +"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
        +"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
        +"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
        +"\x99";
        +
        +    static unsigned char q[] =
        +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
        +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
        +"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
        +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
        +"\x03";
        +
        +    static unsigned char dmp1[] =
        +"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
        +"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
        +"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
        +"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
        +
        +    static unsigned char dmq1[] =
        +"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
        +"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
        +"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
        +"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
        +    
        +    static unsigned char iqmp[] =
        +"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
        +"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
        +"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
        +"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
        +"\xF7";
        +
        +    static unsigned char ctext_ex[] =
        +"\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7"
        +"\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce"
        +"\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3"
        +"\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06"
        +"\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86"
        +"\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4"
        +"\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a"
        +"\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1";
        +
        +    SetKey;
        +    }
        +
        +static int pad_unknown(void)
        +{
        +    unsigned long l;
        +    while ((l = ERR_get_error()) != 0)
        +      if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE)
        +	return(1);
        +    return(0);
        +}
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int main(int argc, char *argv[])
        +    {
        +    int err=0;
        +    int v;
        +    RSA *key;
        +    unsigned char ptext[256];
        +    unsigned char ctext[256];
        +    static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
        +    unsigned char ctext_ex[256];
        +    int plen;
        +    int clen = 0;
        +    int num;
        +    int n;
        +
        +    CRYPTO_malloc_debug_init();
        +    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +    RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */
        +
        +    plen = sizeof(ptext_ex) - 1;
        +
        +    for (v = 0; v < 6; v++)
        +	{
        +	key = RSA_new();
        +	switch (v%3) {
        +    case 0:
        +	clen = key1(key, ctext_ex);
        +	break;
        +    case 1:
        +	clen = key2(key, ctext_ex);
        +	break;
        +    case 2:
        +	clen = key3(key, ctext_ex);
        +	break;
        +	}
        +	if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
        +
        +	num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
        +				 RSA_PKCS1_PADDING);
        +	if (num != clen)
        +	    {
        +	    printf("PKCS#1 v1.5 encryption failed!\n");
        +	    err=1;
        +	    goto oaep;
        +	    }
        +  
        +	num = RSA_private_decrypt(num, ctext, ptext, key,
        +				  RSA_PKCS1_PADDING);
        +	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
        +	    {
        +	    printf("PKCS#1 v1.5 decryption failed!\n");
        +	    err=1;
        +	    }
        +	else
        +	    printf("PKCS #1 v1.5 encryption/decryption ok\n");
        +
        +    oaep:
        +	ERR_clear_error();
        +	num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
        +				 RSA_PKCS1_OAEP_PADDING);
        +	if (num == -1 && pad_unknown())
        +	    {
        +	    printf("No OAEP support\n");
        +	    goto next;
        +	    }
        +	if (num != clen)
        +	    {
        +	    printf("OAEP encryption failed!\n");
        +	    err=1;
        +	    goto next;
        +	    }
        +
        +	num = RSA_private_decrypt(num, ctext, ptext, key,
        +				  RSA_PKCS1_OAEP_PADDING);
        +	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
        +	    {
        +	    printf("OAEP decryption (encrypted data) failed!\n");
        +	    err=1;
        +	    }
        +	else if (memcmp(ctext, ctext_ex, num) == 0)
        +	    printf("OAEP test vector %d passed!\n", v);
        +    
        +	/* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
        +	   Try decrypting ctext_ex */
        +
        +	num = RSA_private_decrypt(clen, ctext_ex, ptext, key,
        +				  RSA_PKCS1_OAEP_PADDING);
        +
        +	if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
        +	    {
        +	    printf("OAEP decryption (test vector data) failed!\n");
        +	    err=1;
        +	    }
        +	else
        +	    printf("OAEP encryption/decryption ok\n");
        +
        +	/* Try decrypting corrupted ciphertexts */
        +	for(n = 0 ; n < clen ; ++n)
        +	    {
        +	    int b;
        +	    unsigned char saved = ctext[n];
        +	    for(b = 0 ; b < 256 ; ++b)
        +		{
        +		if(b == saved)
        +		    continue;
        +		ctext[n] = b;
        +		num = RSA_private_decrypt(num, ctext, ptext, key,
        +					  RSA_PKCS1_OAEP_PADDING);
        +		if(num > 0)
        +		    {
        +		    printf("Corrupt data decrypted!\n");
        +		    err = 1;
        +		    }
        +		}
        +	    }
        +    next:
        +	RSA_free(key);
        +	}
        +
        +    CRYPTO_cleanup_all_ex_data();
        +    ERR_remove_thread_state(NULL);
        +
        +    CRYPTO_mem_leaks_fp(stderr);
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +    return err;
        +    }
        +#endif
        diff --git a/vendor/openssl/openssl/test/sha1test.c b/vendor/openssl/openssl/test/sha1test.c
        new file mode 100644
        index 000000000..6feb3964c
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/sha1test.c
        @@ -0,0 +1,178 @@
        +/* crypto/sha/sha1test.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#ifdef OPENSSL_NO_SHA
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/sha.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +#undef SHA_0 /* FIPS 180 */
        +#define  SHA_1 /* FIPS 180-1 */
        +
        +static char *test[]={
        +	"abc",
        +	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
        +	NULL,
        +	};
        +
        +#ifdef SHA_0
        +static char *ret[]={
        +	"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
        +	"d2516ee1acfa5baf33dfc1c471e438449ef134c8",
        +	};
        +static char *bigret=
        +	"3232affa48628a26653b5aaa44541fd90d690603";
        +#endif
        +#ifdef SHA_1
        +static char *ret[]={
        +	"a9993e364706816aba3e25717850c26c9cd0d89d",
        +	"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
        +	};
        +static char *bigret=
        +	"34aa973cd4c4daa4f61eeb2bdbad27316534016f";
        +#endif
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	static unsigned char buf[1000];
        +	char *p,*r;
        +	EVP_MD_CTX c;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(test[0], test[0], strlen(test[0]));
        +	ebcdic2ascii(test[1], test[1], strlen(test[1]));
        +#endif
        +
        +	EVP_MD_CTX_init(&c);
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha1(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,(char *)*R) != 0)
        +			{
        +			printf("error calculating SHA1 on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +
        +	memset(buf,'a',1000);
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(buf, buf, 1000);
        +#endif /*CHARSET_EBCDIC*/
        +	EVP_DigestInit_ex(&c,EVP_sha1(), NULL);
        +	for (i=0; i<1000; i++)
        +		EVP_DigestUpdate(&c,buf,1000);
        +	EVP_DigestFinal_ex(&c,md,NULL);
        +	p=pt(md);
        +
        +	r=bigret;
        +	if (strcmp(p,r) != 0)
        +		{
        +		printf("error calculating SHA1 on 'a' * 1000\n");
        +		printf("got %s instead of %s\n",p,r);
        +		err++;
        +		}
        +	else
        +		printf("test 3 ok\n");
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EXIT(err);
        +	EVP_MD_CTX_cleanup(&c);
        +	return(0);
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<SHA_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/sha256t.c b/vendor/openssl/openssl/test/sha256t.c
        new file mode 100644
        index 000000000..6b4a3bd00
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/sha256t.c
        @@ -0,0 +1,147 @@
        +/* crypto/sha/sha256t.c */
        +/* ====================================================================
        + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
        + * ====================================================================
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include <openssl/sha.h>
        +#include <openssl/evp.h>
        +
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256)
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA256 support\n");
        +    return(0);
        +}
        +#else
        +
        +unsigned char app_b1[SHA256_DIGEST_LENGTH] = {
        +	0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,
        +	0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,
        +	0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,
        +	0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad	};
        +
        +unsigned char app_b2[SHA256_DIGEST_LENGTH] = {
        +	0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,
        +	0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,
        +	0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,
        +	0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1	};
        +
        +unsigned char app_b3[SHA256_DIGEST_LENGTH] = {
        +	0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,
        +	0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67,
        +	0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,
        +	0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0	};
        +
        +unsigned char addenum_1[SHA224_DIGEST_LENGTH] = {
        +	0x23,0x09,0x7d,0x22,0x34,0x05,0xd8,0x22,
        +	0x86,0x42,0xa4,0x77,0xbd,0xa2,0x55,0xb3,
        +	0x2a,0xad,0xbc,0xe4,0xbd,0xa0,0xb3,0xf7,
        +	0xe3,0x6c,0x9d,0xa7 };
        +
        +unsigned char addenum_2[SHA224_DIGEST_LENGTH] = {
        +	0x75,0x38,0x8b,0x16,0x51,0x27,0x76,0xcc,
        +	0x5d,0xba,0x5d,0xa1,0xfd,0x89,0x01,0x50,
        +	0xb0,0xc6,0x45,0x5c,0xb4,0xf5,0x8b,0x19,
        +	0x52,0x52,0x25,0x25 };
        +
        +unsigned char addenum_3[SHA224_DIGEST_LENGTH] = {
        +	0x20,0x79,0x46,0x55,0x98,0x0c,0x91,0xd8,
        +	0xbb,0xb4,0xc1,0xea,0x97,0x61,0x8a,0x4b,
        +	0xf0,0x3f,0x42,0x58,0x19,0x48,0xb2,0xee,
        +	0x4e,0xe7,0xad,0x67 };
        +
        +int main (int argc,char **argv)
        +{ unsigned char md[SHA256_DIGEST_LENGTH];
        +  int		i;
        +  EVP_MD_CTX	evp;
        +
        +    fprintf(stdout,"Testing SHA-256 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha256(),NULL);
        +    if (memcmp(md,app_b1,sizeof(app_b1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
        +		"ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha256(),NULL);
        +    if (memcmp(md,app_b2,sizeof(app_b2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha256(),NULL);
        +    for (i=0;i<1000000;i+=160)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<160?1000000-i:160);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,app_b3,sizeof(app_b3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +    fprintf(stdout,"Testing SHA-224 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha224(),NULL);
        +    if (memcmp(md,addenum_1,sizeof(addenum_1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk"
        +		"ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha224(),NULL);
        +    if (memcmp(md,addenum_2,sizeof(addenum_2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha224(),NULL);
        +    for (i=0;i<1000000;i+=64)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<64?1000000-i:64);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,addenum_3,sizeof(addenum_3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +  return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/test/sha512t.c b/vendor/openssl/openssl/test/sha512t.c
        new file mode 100644
        index 000000000..210041d43
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/sha512t.c
        @@ -0,0 +1,184 @@
        +/* crypto/sha/sha512t.c */
        +/* ====================================================================
        + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
        + * ====================================================================
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include <openssl/sha.h>
        +#include <openssl/evp.h>
        +#include <openssl/crypto.h>
        +
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512)
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA512 support\n");
        +    return(0);
        +}
        +#else
        +
        +unsigned char app_c1[SHA512_DIGEST_LENGTH] = {
        +	0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,
        +	0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,
        +	0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,
        +	0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,
        +	0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,
        +	0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,
        +	0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,
        +	0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f };
        +
        +unsigned char app_c2[SHA512_DIGEST_LENGTH] = {
        +	0x8e,0x95,0x9b,0x75,0xda,0xe3,0x13,0xda,
        +	0x8c,0xf4,0xf7,0x28,0x14,0xfc,0x14,0x3f,
        +	0x8f,0x77,0x79,0xc6,0xeb,0x9f,0x7f,0xa1,
        +	0x72,0x99,0xae,0xad,0xb6,0x88,0x90,0x18,
        +	0x50,0x1d,0x28,0x9e,0x49,0x00,0xf7,0xe4,
        +	0x33,0x1b,0x99,0xde,0xc4,0xb5,0x43,0x3a,
        +	0xc7,0xd3,0x29,0xee,0xb6,0xdd,0x26,0x54,
        +	0x5e,0x96,0xe5,0x5b,0x87,0x4b,0xe9,0x09 };
        +
        +unsigned char app_c3[SHA512_DIGEST_LENGTH] = {
        +	0xe7,0x18,0x48,0x3d,0x0c,0xe7,0x69,0x64,
        +	0x4e,0x2e,0x42,0xc7,0xbc,0x15,0xb4,0x63,
        +	0x8e,0x1f,0x98,0xb1,0x3b,0x20,0x44,0x28,
        +	0x56,0x32,0xa8,0x03,0xaf,0xa9,0x73,0xeb,
        +	0xde,0x0f,0xf2,0x44,0x87,0x7e,0xa6,0x0a,
        +	0x4c,0xb0,0x43,0x2c,0xe5,0x77,0xc3,0x1b,
        +	0xeb,0x00,0x9c,0x5c,0x2c,0x49,0xaa,0x2e,
        +	0x4e,0xad,0xb2,0x17,0xad,0x8c,0xc0,0x9b };
        +
        +unsigned char app_d1[SHA384_DIGEST_LENGTH] = {
        +	0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b,
        +	0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07,
        +	0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63,
        +	0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed,
        +	0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23,
        +	0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7 };
        +
        +unsigned char app_d2[SHA384_DIGEST_LENGTH] = {
        +	0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8,
        +	0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47,
        +	0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2,
        +	0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12,
        +	0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9,
        +	0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39 };
        +
        +unsigned char app_d3[SHA384_DIGEST_LENGTH] = {
        +	0x9d,0x0e,0x18,0x09,0x71,0x64,0x74,0xcb,
        +	0x08,0x6e,0x83,0x4e,0x31,0x0a,0x4a,0x1c,
        +	0xed,0x14,0x9e,0x9c,0x00,0xf2,0x48,0x52,
        +	0x79,0x72,0xce,0xc5,0x70,0x4c,0x2a,0x5b,
        +	0x07,0xb8,0xb3,0xdc,0x38,0xec,0xc4,0xeb,
        +	0xae,0x97,0xdd,0xd8,0x7f,0x3d,0x89,0x85 };
        +
        +int main (int argc,char **argv)
        +{ unsigned char md[SHA512_DIGEST_LENGTH];
        +  int		i;
        +  EVP_MD_CTX	evp;
        +
        +#ifdef OPENSSL_IA32_SSE2
        +    /* Alternative to this is to call OpenSSL_add_all_algorithms...
        +     * The below code is retained exclusively for debugging purposes. */
        +    { char      *env;
        +
        +	if ((env=getenv("OPENSSL_ia32cap")))
        +	    OPENSSL_ia32cap = strtoul (env,NULL,0);
        +    }
        +#endif
        +
        +    fprintf(stdout,"Testing SHA-512 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha512(),NULL);
        +    if (memcmp(md,app_c1,sizeof(app_c1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
        +		"efghijkl""fghijklm""ghijklmn""hijklmno"
        +		"ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
        +		"mnopqrst""nopqrstu",112,md,NULL,EVP_sha512(),NULL);
        +    if (memcmp(md,app_c2,sizeof(app_c2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha512(),NULL);
        +    for (i=0;i<1000000;i+=288)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<288?1000000-i:288);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,app_c3,sizeof(app_c3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +    fprintf(stdout,"Testing SHA-384 ");
        +
        +    EVP_Digest ("abc",3,md,NULL,EVP_sha384(),NULL);
        +    if (memcmp(md,app_d1,sizeof(app_d1)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk"
        +		"efghijkl""fghijklm""ghijklmn""hijklmno"
        +		"ijklmnop""jklmnopq""klmnopqr""lmnopqrs"
        +		"mnopqrst""nopqrstu",112,md,NULL,EVP_sha384(),NULL);
        +    if (memcmp(md,app_d2,sizeof(app_d2)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    EVP_MD_CTX_init (&evp);
        +    EVP_DigestInit_ex (&evp,EVP_sha384(),NULL);
        +    for (i=0;i<1000000;i+=64)
        +	EVP_DigestUpdate (&evp,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<64?1000000-i:64);
        +    EVP_DigestFinal_ex (&evp,md,NULL);
        +    EVP_MD_CTX_cleanup (&evp);
        +
        +    if (memcmp(md,app_d3,sizeof(app_d3)))
        +    {	fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 3 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +  return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/test/shatest.c b/vendor/openssl/openssl/test/shatest.c
        new file mode 100644
        index 000000000..27614646d
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/shatest.c
        @@ -0,0 +1,178 @@
        +/* crypto/sha/shatest.c */
        +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
        + * All rights reserved.
        + *
        + * This package is an SSL implementation written
        + * by Eric Young (eay@cryptsoft.com).
        + * The implementation was written so as to conform with Netscapes SSL.
        + * 
        + * This library is free for commercial and non-commercial use as long as
        + * the following conditions are aheared to.  The following conditions
        + * apply to all code found in this distribution, be it the RC4, RSA,
        + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
        + * included with this distribution is covered by the same copyright terms
        + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
        + * 
        + * Copyright remains Eric Young's, and as such any Copyright notices in
        + * the code are not to be removed.
        + * If this package is used in a product, Eric Young should be given attribution
        + * as the author of the parts of the library used.
        + * This can be in the form of a textual message at program startup or
        + * in documentation (online or textual) provided with the package.
        + * 
        + * Redistribution and use in source and binary forms, with or without
        + * modification, are permitted provided that the following conditions
        + * are met:
        + * 1. Redistributions of source code must retain the copyright
        + *    notice, this list of conditions and the following disclaimer.
        + * 2. Redistributions in binary form must reproduce the above copyright
        + *    notice, this list of conditions and the following disclaimer in the
        + *    documentation and/or other materials provided with the distribution.
        + * 3. All advertising materials mentioning features or use of this software
        + *    must display the following acknowledgement:
        + *    "This product includes cryptographic software written by
        + *     Eric Young (eay@cryptsoft.com)"
        + *    The word 'cryptographic' can be left out if the rouines from the library
        + *    being used are not cryptographic related :-).
        + * 4. If you include any Windows specific code (or a derivative thereof) from 
        + *    the apps directory (application code) you must include an acknowledgement:
        + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        + * 
        + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        + * SUCH DAMAGE.
        + * 
        + * The licence and distribution terms for any publically available version or
        + * derivative of this code cannot be changed.  i.e. this code cannot simply be
        + * copied and put under another distribution licence
        + * [including the GNU Public Licence.]
        + */
        +
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include "../e_os.h"
        +
        +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0)
        +int main(int argc, char *argv[])
        +{
        +    printf("No SHA0 support\n");
        +    return(0);
        +}
        +#else
        +#include <openssl/evp.h>
        +#include <openssl/sha.h>
        +
        +#ifdef CHARSET_EBCDIC
        +#include <openssl/ebcdic.h>
        +#endif
        +
        +#define SHA_0 /* FIPS 180 */
        +#undef  SHA_1 /* FIPS 180-1 */
        +
        +static char *test[]={
        +	"abc",
        +	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
        +	NULL,
        +	};
        +
        +#ifdef SHA_0
        +static char *ret[]={
        +	"0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
        +	"d2516ee1acfa5baf33dfc1c471e438449ef134c8",
        +	};
        +static char *bigret=
        +	"3232affa48628a26653b5aaa44541fd90d690603";
        +#endif
        +#ifdef SHA_1
        +static char *ret[]={
        +	"a9993e364706816aba3e25717850c26c9cd0d89d",
        +	"84983e441c3bd26ebaae4aa1f95129e5e54670f1",
        +	};
        +static char *bigret=
        +	"34aa973cd4c4daa4f61eeb2bdbad27316534016f";
        +#endif
        +
        +static char *pt(unsigned char *md);
        +int main(int argc, char *argv[])
        +	{
        +	int i,err=0;
        +	char **P,**R;
        +	static unsigned char buf[1000];
        +	char *p,*r;
        +	EVP_MD_CTX c;
        +	unsigned char md[SHA_DIGEST_LENGTH];
        +
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(test[0], test[0], strlen(test[0]));
        +	ebcdic2ascii(test[1], test[1], strlen(test[1]));
        +#endif
        +
        +	EVP_MD_CTX_init(&c);
        +	P=test;
        +	R=ret;
        +	i=1;
        +	while (*P != NULL)
        +		{
        +		EVP_Digest(*P,strlen(*P),md,NULL,EVP_sha(), NULL);
        +		p=pt(md);
        +		if (strcmp(p,*R) != 0)
        +			{
        +			printf("error calculating SHA on '%s'\n",*P);
        +			printf("got %s instead of %s\n",p,*R);
        +			err++;
        +			}
        +		else
        +			printf("test %d ok\n",i);
        +		i++;
        +		R++;
        +		P++;
        +		}
        +
        +	memset(buf,'a',1000);
        +#ifdef CHARSET_EBCDIC
        +	ebcdic2ascii(buf, buf, 1000);
        +#endif /*CHARSET_EBCDIC*/
        +	EVP_DigestInit_ex(&c,EVP_sha(), NULL);
        +	for (i=0; i<1000; i++)
        +		EVP_DigestUpdate(&c,buf,1000);
        +	EVP_DigestFinal_ex(&c,md,NULL);
        +	p=pt(md);
        +
        +	r=bigret;
        +	if (strcmp(p,r) != 0)
        +		{
        +		printf("error calculating SHA on '%s'\n",p);
        +		printf("got %s instead of %s\n",p,r);
        +		err++;
        +		}
        +	else
        +		printf("test 3 ok\n");
        +
        +#ifdef OPENSSL_SYS_NETWARE
        +    if (err) printf("ERROR: %d\n", err);
        +#endif
        +	EVP_MD_CTX_cleanup(&c);
        +	EXIT(err);
        +	return(0);
        +	}
        +
        +static char *pt(unsigned char *md)
        +	{
        +	int i;
        +	static char buf[80];
        +
        +	for (i=0; i<SHA_DIGEST_LENGTH; i++)
        +		sprintf(&(buf[i*2]),"%02x",md[i]);
        +	return(buf);
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/smcont.txt b/vendor/openssl/openssl/test/smcont.txt
        new file mode 100644
        index 000000000..e837c0b75
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smcont.txt
        @@ -0,0 +1 @@
        +Some test content for OpenSSL CMS
        \ No newline at end of file
        diff --git a/vendor/openssl/openssl/test/smime-certs/smdsa1.pem b/vendor/openssl/openssl/test/smime-certs/smdsa1.pem
        new file mode 100644
        index 000000000..d5677dbfb
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smdsa1.pem
        @@ -0,0 +1,34 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
        +OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
        +GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
        +jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
        +wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
        ++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
        +SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd
        +YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9
        +C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx
        +9fMUZq1v0ePD4Wo0Xkxo
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
        +ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
        +CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
        +mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
        +jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
        +CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
        +kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
        +xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN
        +CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M
        +7WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG
        +h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU
        +4Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
        +aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
        +c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO
        +kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8
        +phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n
        +hRJ79W9FaiJRvaAOX+TkyTukJrxAWRyv
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smdsa2.pem b/vendor/openssl/openssl/test/smime-certs/smdsa2.pem
        new file mode 100644
        index 000000000..ef86c115d
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smdsa2.pem
        @@ -0,0 +1,34 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
        +OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
        +GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
        +jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
        +wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
        ++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
        +SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v
        +It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ
        +VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2
        +Nf8SimTZYB0/CKje6M5ufA==
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
        +ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
        +CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
        +mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
        +jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
        +CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
        +kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
        +xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA
        +g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm
        +6WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs
        +j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE
        +FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab
        +rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB
        +FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF
        +FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l
        +6Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0
        +jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smdsa3.pem b/vendor/openssl/openssl/test/smime-certs/smdsa3.pem
        new file mode 100644
        index 000000000..eeb848dab
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smdsa3.pem
        @@ -0,0 +1,34 @@
        +-----BEGIN DSA PRIVATE KEY-----
        +MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
        +OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
        +GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
        +jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
        +wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
        ++FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
        +SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7
        +GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju
        +TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g
        +Y+XZd0Sv69CatDIRYWvaIA==
        +-----END DSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
        +ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
        +CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
        +mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
        +jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
        +CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
        +kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
        +xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj
        +M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz
        +aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/
        +pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU
        +VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
        +aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
        +c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m
        +k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu
        +rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25
        +OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smdsap.pem b/vendor/openssl/openssl/test/smime-certs/smdsap.pem
        new file mode 100644
        index 000000000..249706c8c
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smdsap.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN DSA PARAMETERS-----
        +MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG
        +Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA
        +gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d
        +qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv
        +Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO
        +GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB
        +Qw5z
        +-----END DSA PARAMETERS-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smroot.pem b/vendor/openssl/openssl/test/smime-certs/smroot.pem
        new file mode 100644
        index 000000000..a59eb2684
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smroot.pem
        @@ -0,0 +1,30 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki
        +9Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ
        +speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB
        +AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY
        +JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0
        +xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ
        +U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS
        +Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO
        +1tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3
        +3Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a
        +3ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN
        +U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8
        +0J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc=
        +-----END RSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU
        +ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
        +wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF
        +9HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk
        +81XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O
        +BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX
        +dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
        +SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS
        +l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp
        +r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/OVQLa2lGN9Dr2mQsD8ijctatG
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smrsa1.pem b/vendor/openssl/openssl/test/smime-certs/smrsa1.pem
        new file mode 100644
        index 000000000..2cf3148e3
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smrsa1.pem
        @@ -0,0 +1,31 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E
        +ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7
        +JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB
        +AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i
        +KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl
        +JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn
        +xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf
        +KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY
        +Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW
        +h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg
        +oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f
        +QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1
        +SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA==
        +-----END RSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
        +ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
        +ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl
        +ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ
        +yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD
        +VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z
        +OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
        +EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi
        +O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj
        +9cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC
        +I/+wvHHENYIK5+T/79M9LaZ2Qk4F9MNE1VMljdz9Qw==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smrsa2.pem b/vendor/openssl/openssl/test/smime-certs/smrsa2.pem
        new file mode 100644
        index 000000000..d41f69c82
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smrsa2.pem
        @@ -0,0 +1,31 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe
        +59i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT
        +WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB
        +AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551
        ++rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q
        +dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx
        +bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6
        +QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS
        +M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY
        +iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex
        +A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07
        +jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG
        +6rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA==
        +-----END RSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
        +ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
        +ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ
        +eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5
        +00obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD
        +VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z
        +OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
        +EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2
        +rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe
        +ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2
        +YNdR/aNOug+5sXygHmTSKqiCpQjOIClzXoPVVeEVHw==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/smime-certs/smrsa3.pem b/vendor/openssl/openssl/test/smime-certs/smrsa3.pem
        new file mode 100644
        index 000000000..c8cbe5515
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/smime-certs/smrsa3.pem
        @@ -0,0 +1,31 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy
        +ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM
        +h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB
        +AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi
        +iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT
        +/1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p
        +ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC
        +hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs
        +OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj
        +RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T
        +9XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5
        +GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd
        +VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc=
        +-----END RSA PRIVATE KEY-----
        +-----BEGIN CERTIFICATE-----
        +MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
        +BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
        +TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
        +CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
        +ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
        +ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z
        +Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H
        +Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD
        +VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z
        +OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
        +EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE
        +tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq
        +jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ
        +PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA==
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/srptest.c b/vendor/openssl/openssl/test/srptest.c
        new file mode 100644
        index 000000000..04b66b454
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/srptest.c
        @@ -0,0 +1,162 @@
        +#include <openssl/opensslconf.h>
        +#ifdef OPENSSL_NO_SRP
        +
        +#include <stdio.h>
        +
        +int main(int argc, char *argv[])
        +	{
        +	printf("No SRP support\n");
        +	return(0);
        +	}
        +
        +#else
        +
        +#include <openssl/srp.h>
        +#include <openssl/rand.h>
        +#include <openssl/err.h>
        +
        +static void showbn(const char *name, const BIGNUM *bn)
        +	{
        +	fputs(name, stdout);
        +	fputs(" = ", stdout);
        +	BN_print_fp(stdout, bn);
        +	putc('\n', stdout);
        +	}
        +
        +#define RANDOM_SIZE 32	/* use 256 bits on each side */
        +
        +static int run_srp(const char *username, const char *client_pass, const char *server_pass)
        +	{
        +	int ret=-1;
        +	BIGNUM *s = NULL;
        +	BIGNUM *v = NULL;
        +	BIGNUM *a = NULL;
        +	BIGNUM *b = NULL;
        +	BIGNUM *u = NULL;
        +	BIGNUM *x = NULL;
        +	BIGNUM *Apub = NULL;
        +	BIGNUM *Bpub = NULL;
        +	BIGNUM *Kclient = NULL;
        +	BIGNUM *Kserver = NULL;
        +	unsigned char rand_tmp[RANDOM_SIZE];
        +	/* use builtin 1024-bit params */
        +	SRP_gN *GN = SRP_get_default_gN("1024");
        +
        +	if(GN == NULL)
        +		{
        +		fprintf(stderr, "Failed to get SRP parameters\n");
        +		return -1;
        +		}
        +	/* Set up server's password entry */
        +	if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
        +		{
        +		fprintf(stderr, "Failed to create SRP verifier\n");
        +		return -1;
        +		}
        +
        +	showbn("N", GN->N);
        +	showbn("g", GN->g);
        +	showbn("Salt", s);
        +	showbn("Verifier", v);
        +
        +	/* Server random */
        +	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
        +	b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
        +	/* TODO - check b != 0 */
        +	showbn("b", b);
        +
        +	/* Server's first message */
        +	Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
        +	showbn("B", Bpub);
        +
        +	if(!SRP_Verify_B_mod_N(Bpub, GN->N))
        +		{
        +		fprintf(stderr, "Invalid B\n");
        +		return -1;
        +		}
        +
        +	/* Client random */
        +	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
        +	a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
        +	/* TODO - check a != 0 */
        +	showbn("a", a);
        +
        +	/* Client's response */
        +	Apub = SRP_Calc_A(a, GN->N, GN->g);
        +	showbn("A", Apub);
        +
        +	if(!SRP_Verify_A_mod_N(Apub, GN->N))
        +		{
        +		fprintf(stderr, "Invalid A\n");
        +		return -1;
        +		}
        +
        +	/* Both sides calculate u */
        +	u = SRP_Calc_u(Apub, Bpub, GN->N);
        +
        +	/* Client's key */
        +	x = SRP_Calc_x(s, username, client_pass);
        +	Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
        +	showbn("Client's key", Kclient);
        +
        +	/* Server's key */
        +	Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
        +	showbn("Server's key", Kserver);
        +
        +	if(BN_cmp(Kclient, Kserver) == 0)
        +		{
        +		ret = 0;
        +		}
        +	else
        +		{
        +		fprintf(stderr, "Keys mismatch\n");
        +		ret = 1;
        +		}
        +
        +	BN_clear_free(Kclient);
        +	BN_clear_free(Kserver);
        +	BN_clear_free(x);
        +	BN_free(u);
        +	BN_free(Apub);
        +	BN_clear_free(a);
        +	BN_free(Bpub);
        +	BN_clear_free(b);
        +	BN_free(s);
        +	BN_clear_free(v);
        +
        +	return ret;
        +	}
        +
        +int main(int argc, char **argv)
        +	{
        +	BIO *bio_err;
        +	bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
        +
        +	CRYPTO_malloc_debug_init();
        +	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	ERR_load_crypto_strings();
        +
        +	/* "Negative" test, expect a mismatch */
        +	if(run_srp("alice", "password1", "password2") == 0)
        +		{
        +		fprintf(stderr, "Mismatched SRP run failed\n");
        +		return 1;
        +		}
        +
        +	/* "Positive" test, should pass */
        +	if(run_srp("alice", "password", "password") != 0)
        +		{
        +		fprintf(stderr, "Plain SRP run failed\n");
        +		return 1;
        +		}
        +
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_remove_thread_state(NULL);
        +	ERR_free_strings();
        +	CRYPTO_mem_leaks(bio_err);
        +
        +	return 0;
        +	}
        +#endif
        diff --git a/vendor/openssl/openssl/test/ssltest.c b/vendor/openssl/openssl/test/ssltest.c
        new file mode 100644
        index 000000000..316bbb0c9
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/ssltest.c
        @@ -0,0 +1,2577 @@
        +/* ssl/ssltest.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).
        + *
        + */
        +/* ====================================================================
        + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
        + * ECC cipher suite support in OpenSSL originally developed by 
        + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
        + */
        +/* ====================================================================
        + * Copyright 2005 Nokia. All rights reserved.
        + *
        + * The portions of the attached software ("Contribution") is developed by
        + * Nokia Corporation and is licensed pursuant to the OpenSSL open source
        + * license.
        + *
        + * The Contribution, originally written by Mika Kousa and Pasi Eronen of
        + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
        + * support (see RFC 4279) to OpenSSL.
        + *
        + * No patent licenses or other rights except those expressly stated in
        + * the OpenSSL open source license shall be deemed granted or received
        + * expressly, by implication, estoppel, or otherwise.
        + *
        + * No assurances are provided by Nokia that the Contribution does not
        + * infringe the patent or other intellectual property rights of any third
        + * party or that the license provides you with all the necessary rights
        + * to make use of the Contribution.
        + *
        + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
        + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
        + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
        + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
        + * OTHERWISE.
        + */
        +
        +#define _BSD_SOURCE 1		/* Or gethostname won't be declared properly
        +				   on Linux and GNU platforms. */
        +
        +#include <assert.h>
        +#include <errno.h>
        +#include <limits.h>
        +#include <stdio.h>
        +#include <stdlib.h>
        +#include <string.h>
        +#include <time.h>
        +
        +#define USE_SOCKETS
        +#include "e_os.h"
        +
        +#ifdef OPENSSL_SYS_VMS
        +#define _XOPEN_SOURCE 500	/* Or isascii won't be declared properly on
        +				   VMS (at least with DECompHP C).  */
        +#endif
        +
        +#include <ctype.h>
        +
        +#include <openssl/bio.h>
        +#include <openssl/crypto.h>
        +#include <openssl/evp.h>
        +#include <openssl/x509.h>
        +#include <openssl/x509v3.h>
        +#include <openssl/ssl.h>
        +#ifndef OPENSSL_NO_ENGINE
        +#include <openssl/engine.h>
        +#endif
        +#include <openssl/err.h>
        +#include <openssl/rand.h>
        +#ifndef OPENSSL_NO_RSA
        +#include <openssl/rsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +#include <openssl/dsa.h>
        +#endif
        +#ifndef OPENSSL_NO_DH
        +#include <openssl/dh.h>
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +#include <openssl/srp.h>
        +#endif
        +#include <openssl/bn.h>
        +
        +#define _XOPEN_SOURCE_EXTENDED	1 /* Or gethostname won't be declared properly
        +				     on Compaq platforms (at least with DEC C).
        +				     Do not try to put it earlier, or IPv6 includes
        +				     get screwed...
        +				  */
        +
        +#ifdef OPENSSL_SYS_WINDOWS
        +#include <winsock.h>
        +#else
        +#include OPENSSL_UNISTD
        +#endif
        +
        +#ifdef OPENSSL_SYS_VMS
        +#  define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
        +#  define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
        +#elif defined(OPENSSL_SYS_WINCE)
        +#  define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
        +#  define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
        +#elif defined(OPENSSL_SYS_NETWARE)
        +#  define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
        +#  define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem"
        +#else
        +#  define TEST_SERVER_CERT "../apps/server.pem"
        +#  define TEST_CLIENT_CERT "../apps/client.pem"
        +#endif
        +
        +/* There is really no standard for this, so let's assign some tentative
        +   numbers.  In any case, these numbers are only for this test */
        +#define COMP_RLE	255
        +#define COMP_ZLIB	1
        +
        +static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
        +#ifndef OPENSSL_NO_RSA
        +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
        +static void free_tmp_rsa(void);
        +#endif
        +static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
        +#define APP_CALLBACK_STRING "Test Callback Argument"
        +struct app_verify_arg
        +	{
        +	char *string;
        +	int app_verify;
        +	int allow_proxy_certs;
        +	char *proxy_auth;
        +	char *proxy_cond;
        +	};
        +
        +#ifndef OPENSSL_NO_DH
        +static DH *get_dh512(void);
        +static DH *get_dh1024(void);
        +static DH *get_dh1024dsa(void);
        +#endif
        +
        +
        +static char *psk_key=NULL; /* by default PSK is not used */
        +#ifndef OPENSSL_NO_PSK
        +static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
        +	unsigned int max_identity_len, unsigned char *psk,
        +	unsigned int max_psk_len);
        +static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
        +	unsigned int max_psk_len);
        +#endif
        +
        +#ifndef OPENSSL_NO_SRP
        +/* SRP client */
        +/* This is a context that we pass to all callbacks */
        +typedef struct srp_client_arg_st
        +	{
        +	char *srppassin;
        +	char *srplogin;
        +	} SRP_CLIENT_ARG;
        +
        +#define PWD_STRLEN 1024
        +
        +static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
        +	{
        +	SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
        +	return BUF_strdup((char *)srp_client_arg->srppassin);
        +	}
        +
        +/* SRP server */
        +/* This is a context that we pass to SRP server callbacks */
        +typedef struct srp_server_arg_st
        +	{
        +	char *expected_user;
        +	char *pass;
        +	} SRP_SERVER_ARG;
        +
        +static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
        +	{
        +	SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
        +
        +	if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
        +		{
        +		fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
        +		return SSL3_AL_FATAL;
        +		}
        +	if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
        +		{
        +		*ad = SSL_AD_INTERNAL_ERROR;
        +		return SSL3_AL_FATAL;
        +		}
        +	return SSL_ERROR_NONE;
        +	}
        +#endif
        +
        +static BIO *bio_err=NULL;
        +static BIO *bio_stdout=NULL;
        +
        +static char *cipher=NULL;
        +static int verbose=0;
        +static int debug=0;
        +#if 0
        +/* Not used yet. */
        +#ifdef FIONBIO
        +static int s_nbio=0;
        +#endif
        +#endif
        +
        +static const char rnd_seed[] = "string to make the random number generator think it has entropy";
        +
        +int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time);
        +int doit(SSL *s_ssl,SSL *c_ssl,long bytes);
        +static int do_test_cipherlist(void);
        +static void sv_usage(void)
        +	{
        +	fprintf(stderr,"usage: ssltest [args ...]\n");
        +	fprintf(stderr,"\n");
        +#ifdef OPENSSL_FIPS
        +	fprintf(stderr,"-F             - run test in FIPS mode\n");
        +#endif
        +	fprintf(stderr," -server_auth  - check server certificate\n");
        +	fprintf(stderr," -client_auth  - do client authentication\n");
        +	fprintf(stderr," -proxy        - allow proxy certificates\n");
        +	fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
        +	fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
        +	fprintf(stderr," -v            - more output\n");
        +	fprintf(stderr," -d            - debug output\n");
        +	fprintf(stderr," -reuse        - use session-id reuse\n");
        +	fprintf(stderr," -num <val>    - number of connections to perform\n");
        +	fprintf(stderr," -bytes <val>  - number of bytes to swap between client/server\n");
        +#ifndef OPENSSL_NO_DH
        +	fprintf(stderr," -dhe1024      - use 1024 bit key (safe prime) for DHE\n");
        +	fprintf(stderr," -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
        +	fprintf(stderr," -no_dhe       - disable DHE\n");
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	fprintf(stderr," -no_ecdhe     - disable ECDHE\n");
        +#endif
        +#ifndef OPENSSL_NO_PSK
        +	fprintf(stderr," -psk arg      - PSK in hex (without 0x)\n");
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	fprintf(stderr," -srpuser user  - SRP username to use\n");
        +	fprintf(stderr," -srppass arg   - password for 'user'\n");
        +#endif
        +#ifndef OPENSSL_NO_SSL2
        +	fprintf(stderr," -ssl2         - use SSLv2\n");
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +	fprintf(stderr," -ssl3         - use SSLv3\n");
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +	fprintf(stderr," -tls1         - use TLSv1\n");
        +#endif
        +	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
        +	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
        +	fprintf(stderr," -cert arg     - Server certificate file\n");
        +	fprintf(stderr," -key arg      - Server key file (default: same as -cert)\n");
        +	fprintf(stderr," -c_cert arg   - Client certificate file\n");
        +	fprintf(stderr," -c_key arg    - Client key file (default: same as -c_cert)\n");
        +	fprintf(stderr," -cipher arg   - The cipher list\n");
        +	fprintf(stderr," -bio_pair     - Use BIO pairs\n");
        +	fprintf(stderr," -f            - Test even cases that can't work\n");
        +	fprintf(stderr," -time         - measure processor time used by client and server\n");
        +	fprintf(stderr," -zlib         - use zlib compression\n");
        +	fprintf(stderr," -rle          - use rle compression\n");
        +#ifndef OPENSSL_NO_ECDH
        +	fprintf(stderr," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
        +	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
        +	               "                 (default is sect163r2).\n");
        +#endif
        +	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
        +	}
        +
        +static void print_details(SSL *c_ssl, const char *prefix)
        +	{
        +	const SSL_CIPHER *ciph;
        +	X509 *cert;
        +		
        +	ciph=SSL_get_current_cipher(c_ssl);
        +	BIO_printf(bio_stdout,"%s%s, cipher %s %s",
        +		prefix,
        +		SSL_get_version(c_ssl),
        +		SSL_CIPHER_get_version(ciph),
        +		SSL_CIPHER_get_name(ciph));
        +	cert=SSL_get_peer_certificate(c_ssl);
        +	if (cert != NULL)
        +		{
        +		EVP_PKEY *pkey = X509_get_pubkey(cert);
        +		if (pkey != NULL)
        +			{
        +			if (0) 
        +				;
        +#ifndef OPENSSL_NO_RSA
        +			else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
        +				&& pkey->pkey.rsa->n != NULL)
        +				{
        +				BIO_printf(bio_stdout, ", %d bit RSA",
        +					BN_num_bits(pkey->pkey.rsa->n));
        +				}
        +#endif
        +#ifndef OPENSSL_NO_DSA
        +			else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
        +				&& pkey->pkey.dsa->p != NULL)
        +				{
        +				BIO_printf(bio_stdout, ", %d bit DSA",
        +					BN_num_bits(pkey->pkey.dsa->p));
        +				}
        +#endif
        +			EVP_PKEY_free(pkey);
        +			}
        +		X509_free(cert);
        +		}
        +	/* The SSL API does not allow us to look at temporary RSA/DH keys,
        +	 * otherwise we should print their lengths too */
        +	BIO_printf(bio_stdout,"\n");
        +	}
        +
        +static void lock_dbg_cb(int mode, int type, const char *file, int line)
        +	{
        +	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
        +	const char *errstr = NULL;
        +	int rw;
        +	
        +	rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
        +	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
        +		{
        +		errstr = "invalid mode";
        +		goto err;
        +		}
        +
        +	if (type < 0 || type >= CRYPTO_NUM_LOCKS)
        +		{
        +		errstr = "type out of bounds";
        +		goto err;
        +		}
        +
        +	if (mode & CRYPTO_LOCK)
        +		{
        +		if (modes[type])
        +			{
        +			errstr = "already locked";
        +			/* must not happen in a single-threaded program
        +			 * (would deadlock) */
        +			goto err;
        +			}
        +
        +		modes[type] = rw;
        +		}
        +	else if (mode & CRYPTO_UNLOCK)
        +		{
        +		if (!modes[type])
        +			{
        +			errstr = "not locked";
        +			goto err;
        +			}
        +		
        +		if (modes[type] != rw)
        +			{
        +			errstr = (rw == CRYPTO_READ) ?
        +				"CRYPTO_r_unlock on write lock" :
        +				"CRYPTO_w_unlock on read lock";
        +			}
        +
        +		modes[type] = 0;
        +		}
        +	else
        +		{
        +		errstr = "invalid mode";
        +		goto err;
        +		}
        +
        + err:
        +	if (errstr)
        +		{
        +		/* we cannot use bio_err here */
        +		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
        +			errstr, mode, type, file, line);
        +		}
        +	}
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +struct cb_info_st { void *input; size_t len; int ret; };
        +struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */
        +struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */
        +struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */
        +struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */
        +
        +int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
        +	{
        +	struct cb_info_st *arg = arg_;
        +
        +	if (arg == NULL)
        +		return 1;
        +	
        +	if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len))
        +		return 0;
        +	return arg->ret;
        +	}
        +#endif
        +
        +int main(int argc, char *argv[])
        +	{
        +	char *CApath=NULL,*CAfile=NULL;
        +	int badop=0;
        +	int bio_pair=0;
        +	int force=0;
        +	int tls1=0,ssl2=0,ssl3=0,ret=1;
        +	int client_auth=0;
        +	int server_auth=0,i;
        +	struct app_verify_arg app_verify_arg =
        +		{ APP_CALLBACK_STRING, 0, 0, NULL, NULL };
        +	char *server_cert=TEST_SERVER_CERT;
        +	char *server_key=NULL;
        +	char *client_cert=TEST_CLIENT_CERT;
        +	char *client_key=NULL;
        +#ifndef OPENSSL_NO_ECDH
        +	char *named_curve = NULL;
        +#endif
        +	SSL_CTX *s_ctx=NULL;
        +	SSL_CTX *c_ctx=NULL;
        +	const SSL_METHOD *meth=NULL;
        +	SSL *c_ssl,*s_ssl;
        +	int number=1,reuse=0;
        +	long bytes=256L;
        +#ifndef OPENSSL_NO_DH
        +	DH *dh;
        +	int dhe1024 = 0, dhe1024dsa = 0;
        +#endif
        +#ifndef OPENSSL_NO_ECDH
        +	EC_KEY *ecdh = NULL;
        +#endif
        +#ifndef OPENSSL_NO_SRP
        +	/* client */
        +	SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
        +	/* server */
        +	SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
        +#endif
        +	int no_dhe = 0;
        +	int no_ecdhe = 0;
        +	int no_psk = 0;
        +	int print_time = 0;
        +	clock_t s_time = 0, c_time = 0;
        +	int comp = 0;
        +#ifndef OPENSSL_NO_COMP
        +	COMP_METHOD *cm = NULL;
        +	STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
        +#endif
        +	int test_cipherlist = 0;
        +#ifdef OPENSSL_FIPS
        +	int fips_mode=0;
        +#endif
        +
        +	verbose = 0;
        +	debug = 0;
        +	cipher = 0;
        +
        +	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);	
        +
        +	CRYPTO_set_locking_callback(lock_dbg_cb);
        +
        +	/* enable memory leak checking unless explicitly disabled */
        +	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
        +		{
        +		CRYPTO_malloc_debug_init();
        +		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        +		}
        +	else
        +		{
        +		/* OPENSSL_DEBUG_MEMORY=off */
        +		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        +		}
        +	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
        +
        +	RAND_seed(rnd_seed, sizeof rnd_seed);
        +
        +	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
        +
        +	argc--;
        +	argv++;
        +
        +	while (argc >= 1)
        +		{
        +		if(!strcmp(*argv,"-F"))
        +			{
        +#ifdef OPENSSL_FIPS
        +			fips_mode=1;
        +#else
        +			fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
        +			EXIT(0);
        +#endif
        +			}
        +		else if (strcmp(*argv,"-server_auth") == 0)
        +			server_auth=1;
        +		else if	(strcmp(*argv,"-client_auth") == 0)
        +			client_auth=1;
        +		else if (strcmp(*argv,"-proxy_auth") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			app_verify_arg.proxy_auth= *(++argv);
        +			}
        +		else if (strcmp(*argv,"-proxy_cond") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			app_verify_arg.proxy_cond= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-v") == 0)
        +			verbose=1;
        +		else if	(strcmp(*argv,"-d") == 0)
        +			debug=1;
        +		else if	(strcmp(*argv,"-reuse") == 0)
        +			reuse=1;
        +		else if	(strcmp(*argv,"-dhe1024") == 0)
        +			{
        +#ifndef OPENSSL_NO_DH
        +			dhe1024=1;
        +#else
        +			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
        +#endif
        +			}
        +		else if	(strcmp(*argv,"-dhe1024dsa") == 0)
        +			{
        +#ifndef OPENSSL_NO_DH
        +			dhe1024dsa=1;
        +#else
        +			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
        +#endif
        +			}
        +		else if	(strcmp(*argv,"-no_dhe") == 0)
        +			no_dhe=1;
        +		else if	(strcmp(*argv,"-no_ecdhe") == 0)
        +			no_ecdhe=1;
        +		else if (strcmp(*argv,"-psk") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			psk_key=*(++argv);
        +#ifndef OPENSSL_NO_PSK
        +			if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key))
        +				{
        +				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
        +				goto bad;
        +				}
        +#else
        +			no_psk=1;
        +#endif
        +			}
        +#ifndef OPENSSL_NO_SRP
        +		else if (strcmp(*argv,"-srpuser") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
        +			tls1=1;
        +			}
        +		else if (strcmp(*argv,"-srppass") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
        +			tls1=1;
        +			}
        +#endif
        +		else if	(strcmp(*argv,"-ssl2") == 0)
        +			ssl2=1;
        +		else if	(strcmp(*argv,"-tls1") == 0)
        +			tls1=1;
        +		else if	(strcmp(*argv,"-ssl3") == 0)
        +			ssl3=1;
        +		else if	(strncmp(*argv,"-num",4) == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			number= atoi(*(++argv));
        +			if (number == 0) number=1;
        +			}
        +		else if	(strcmp(*argv,"-bytes") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			bytes= atol(*(++argv));
        +			if (bytes == 0L) bytes=1L;
        +			i=strlen(argv[0]);
        +			if (argv[0][i-1] == 'k') bytes*=1024L;
        +			if (argv[0][i-1] == 'm') bytes*=1024L*1024L;
        +			}
        +		else if	(strcmp(*argv,"-cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_cert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-s_cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_cert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_key= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-s_key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			server_key= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-c_cert") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			client_cert= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-c_key") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			client_key= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-cipher") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			cipher= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CApath") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CApath= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-CAfile") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +			CAfile= *(++argv);
        +			}
        +		else if	(strcmp(*argv,"-bio_pair") == 0)
        +			{
        +			bio_pair = 1;
        +			}
        +		else if	(strcmp(*argv,"-f") == 0)
        +			{
        +			force = 1;
        +			}
        +		else if	(strcmp(*argv,"-time") == 0)
        +			{
        +			print_time = 1;
        +			}
        +		else if	(strcmp(*argv,"-zlib") == 0)
        +			{
        +			comp = COMP_ZLIB;
        +			}
        +		else if	(strcmp(*argv,"-rle") == 0)
        +			{
        +			comp = COMP_RLE;
        +			}
        +		else if	(strcmp(*argv,"-named_curve") == 0)
        +			{
        +			if (--argc < 1) goto bad;
        +#ifndef OPENSSL_NO_ECDH		
        +			named_curve = *(++argv);
        +#else
        +			fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
        +			++argv;
        +#endif
        +			}
        +		else if	(strcmp(*argv,"-app_verify") == 0)
        +			{
        +			app_verify_arg.app_verify = 1;
        +			}
        +		else if	(strcmp(*argv,"-proxy") == 0)
        +			{
        +			app_verify_arg.allow_proxy_certs = 1;
        +			}
        +		else if (strcmp(*argv,"-test_cipherlist") == 0)
        +			{
        +			test_cipherlist = 1;
        +			}
        +		else
        +			{
        +			fprintf(stderr,"unknown option %s\n",*argv);
        +			badop=1;
        +			break;
        +			}
        +		argc--;
        +		argv++;
        +		}
        +	if (badop)
        +		{
        +bad:
        +		sv_usage();
        +		goto end;
        +		}
        +
        +	if (test_cipherlist == 1)
        +		{
        +		/* ensure that the cipher list are correctly sorted and exit */
        +		if (do_test_cipherlist() == 0)
        +			EXIT(1);
        +		ret = 0;
        +		goto end;
        +		}
        +
        +	if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
        +		{
        +		fprintf(stderr, "This case cannot work.  Use -f to perform "
        +			"the test anyway (and\n-d to see what happens), "
        +			"or add one of -ssl2, -ssl3, -tls1, -reuse\n"
        +			"to avoid protocol mismatch.\n");
        +		EXIT(1);
        +		}
        +
        +#ifdef OPENSSL_FIPS
        +	if(fips_mode)
        +		{
        +		if(!FIPS_mode_set(1))
        +			{
        +			ERR_load_crypto_strings();
        +			ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
        +			EXIT(1);
        +			}
        +		else
        +			fprintf(stderr,"*** IN FIPS MODE ***\n");
        +		}
        +#endif
        +
        +	if (print_time)
        +		{
        +		if (!bio_pair)
        +			{
        +			fprintf(stderr, "Using BIO pair (-bio_pair)\n");
        +			bio_pair = 1;
        +			}
        +		if (number < 50 && !force)
        +			fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
        +		}
        +
        +/*	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
        +
        +	SSL_library_init();
        +	SSL_load_error_strings();
        +
        +#ifndef OPENSSL_NO_COMP
        +	if (comp == COMP_ZLIB) cm = COMP_zlib();
        +	if (comp == COMP_RLE) cm = COMP_rle();
        +	if (cm != NULL)
        +		{
        +		if (cm->type != NID_undef)
        +			{
        +			if (SSL_COMP_add_compression_method(comp, cm) != 0)
        +				{
        +				fprintf(stderr,
        +					"Failed to add compression method\n");
        +				ERR_print_errors_fp(stderr);
        +				}
        +			}
        +		else
        +			{
        +			fprintf(stderr,
        +				"Warning: %s compression not supported\n",
        +				(comp == COMP_RLE ? "rle" :
        +					(comp == COMP_ZLIB ? "zlib" :
        +						"unknown")));
        +			ERR_print_errors_fp(stderr);
        +			}
        +		}
        +	ssl_comp_methods = SSL_COMP_get_compression_methods();
        +	fprintf(stderr, "Available compression methods:\n");
        +	{
        +	int j, n = sk_SSL_COMP_num(ssl_comp_methods);
        +	if (n == 0)
        +		fprintf(stderr, "  NONE\n");
        +	else
        +		for (j = 0; j < n; j++)
        +			{
        +			SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
        +			fprintf(stderr, "  %d: %s\n", c->id, c->name);
        +			}
        +	}
        +#endif
        +
        +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        +	if (ssl2)
        +		meth=SSLv2_method();
        +	else 
        +	if (tls1)
        +		meth=TLSv1_method();
        +	else
        +	if (ssl3)
        +		meth=SSLv3_method();
        +	else
        +		meth=SSLv23_method();
        +#else
        +#ifdef OPENSSL_NO_SSL2
        +	meth=SSLv3_method();
        +#else
        +	meth=SSLv2_method();
        +#endif
        +#endif
        +
        +	c_ctx=SSL_CTX_new(meth);
        +	s_ctx=SSL_CTX_new(meth);
        +	if ((c_ctx == NULL) || (s_ctx == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (cipher != NULL)
        +		{
        +		SSL_CTX_set_cipher_list(c_ctx,cipher);
        +		SSL_CTX_set_cipher_list(s_ctx,cipher);
        +		}
        +
        +#ifndef OPENSSL_NO_DH
        +	if (!no_dhe)
        +		{
        +		if (dhe1024dsa)
        +			{
        +			/* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
        +			SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
        +			dh=get_dh1024dsa();
        +			}
        +		else if (dhe1024)
        +			dh=get_dh1024();
        +		else
        +			dh=get_dh512();
        +		SSL_CTX_set_tmp_dh(s_ctx,dh);
        +		DH_free(dh);
        +		}
        +#else
        +	(void)no_dhe;
        +#endif
        +
        +#ifndef OPENSSL_NO_ECDH
        +	if (!no_ecdhe)
        +		{
        +		int nid;
        +
        +		if (named_curve != NULL)
        +			{
        +			nid = OBJ_sn2nid(named_curve);
        +			if (nid == 0)
        +			{
        +				BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
        +				goto end;
        +				}
        +			}
        +		else
        +#ifdef OPENSSL_NO_EC2M
        +			nid = NID_X9_62_prime256v1;
        +#else
        +			nid = NID_sect163r2;
        +#endif
        +
        +		ecdh = EC_KEY_new_by_curve_name(nid);
        +		if (ecdh == NULL)
        +			{
        +			BIO_printf(bio_err, "unable to create curve\n");
        +			goto end;
        +			}
        +
        +		SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
        +		SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
        +		EC_KEY_free(ecdh);
        +		}
        +#else
        +	(void)no_ecdhe;
        +#endif
        +
        +#ifndef OPENSSL_NO_RSA
        +	SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
        +#endif
        +
        +#ifdef TLSEXT_TYPE_opaque_prf_input
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb);
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb);
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &co2 or NULL */
        +	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); /* or &so2 or NULL */
        +#endif
        +
        +	if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
        +		{
        +		ERR_print_errors(bio_err);
        +		}
        +	else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
        +		(server_key?server_key:server_cert), SSL_FILETYPE_PEM))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto end;
        +		}
        +
        +	if (client_auth)
        +		{
        +		SSL_CTX_use_certificate_file(c_ctx,client_cert,
        +			SSL_FILETYPE_PEM);
        +		SSL_CTX_use_PrivateKey_file(c_ctx,
        +			(client_key?client_key:client_cert),
        +			SSL_FILETYPE_PEM);
        +		}
        +
        +	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
        +		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
        +		(!SSL_CTX_set_default_verify_paths(c_ctx)))
        +		{
        +		/* fprintf(stderr,"SSL_load_verify_locations\n"); */
        +		ERR_print_errors(bio_err);
        +		/* goto end; */
        +		}
        +
        +	if (client_auth)
        +		{
        +		BIO_printf(bio_err,"client authentication\n");
        +		SSL_CTX_set_verify(s_ctx,
        +			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
        +			verify_callback);
        +		SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
        +		}
        +	if (server_auth)
        +		{
        +		BIO_printf(bio_err,"server authentication\n");
        +		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
        +			verify_callback);
        +		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
        +		}
        +	
        +	{
        +		int session_id_context = 0;
        +		SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context);
        +	}
        +
        +	/* Use PSK only if PSK key is given */
        +	if (psk_key != NULL)
        +		{
        +		/* no_psk is used to avoid putting psk command to openssl tool */
        +		if (no_psk)
        +			{
        +			/* if PSK is not compiled in and psk key is
        +			 * given, do nothing and exit successfully */
        +			ret=0;
        +			goto end;
        +			}
        +#ifndef OPENSSL_NO_PSK
        +		SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback);
        +		SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback);
        +		if (debug)
        +			BIO_printf(bio_err,"setting PSK identity hint to s_ctx\n");
        +		if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint"))
        +			{
        +			BIO_printf(bio_err,"error setting PSK identity hint to s_ctx\n");
        +			ERR_print_errors(bio_err);
        +			goto end;
        +			}
        +#endif
        +		}
        +#ifndef OPENSSL_NO_SRP
        +        if (srp_client_arg.srplogin)
        +		{
        +		if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
        +			{
        +			BIO_printf(bio_err,"Unable to set SRP username\n");
        +			goto end;
        +			}
        +		SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
        +		SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
        +		/*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
        +		}
        +
        +	if (srp_server_arg.expected_user != NULL)
        +		{
        +		SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
        +		SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
        +		SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
        +		}
        +#endif
        +
        +	c_ssl=SSL_new(c_ctx);
        +	s_ssl=SSL_new(s_ctx);
        +
        +#ifndef OPENSSL_NO_KRB5
        +	if (c_ssl  &&  c_ssl->kssl_ctx)
        +                {
        +                char	localhost[MAXHOSTNAMELEN+2];
        +
        +		if (gethostname(localhost, sizeof localhost-1) == 0)
        +                        {
        +			localhost[sizeof localhost-1]='\0';
        +			if(strlen(localhost) == sizeof localhost-1)
        +				{
        +				BIO_printf(bio_err,"localhost name too long\n");
        +				goto end;
        +				}
        +			kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
        +                                localhost);
        +			}
        +		}
        +#endif    /* OPENSSL_NO_KRB5  */
        +
        +	for (i=0; i<number; i++)
        +		{
        +		if (!reuse) SSL_set_session(c_ssl,NULL);
        +		if (bio_pair)
        +			ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time);
        +		else
        +			ret=doit(s_ssl,c_ssl,bytes);
        +		}
        +
        +	if (!verbose)
        +		{
        +		print_details(c_ssl, "");
        +		}
        +	if ((number > 1) || (bytes > 1L))
        +		BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes);
        +	if (print_time)
        +		{
        +#ifdef CLOCKS_PER_SEC
        +		/* "To determine the time in seconds, the value returned
        +		 * by the clock function should be divided by the value
        +		 * of the macro CLOCKS_PER_SEC."
        +		 *                                       -- ISO/IEC 9899 */
        +		BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n"
        +			"Approximate total client time: %6.2f s\n",
        +			(double)s_time/CLOCKS_PER_SEC,
        +			(double)c_time/CLOCKS_PER_SEC);
        +#else
        +		/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
        +		 *                            -- cc on NeXTstep/OpenStep */
        +		BIO_printf(bio_stdout,
        +			"Approximate total server time: %6.2f units\n"
        +			"Approximate total client time: %6.2f units\n",
        +			(double)s_time,
        +			(double)c_time);
        +#endif
        +		}
        +
        +	SSL_free(s_ssl);
        +	SSL_free(c_ssl);
        +
        +end:
        +	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
        +	if (c_ctx != NULL) SSL_CTX_free(c_ctx);
        +
        +	if (bio_stdout != NULL) BIO_free(bio_stdout);
        +
        +#ifndef OPENSSL_NO_RSA
        +	free_tmp_rsa();
        +#endif
        +#ifndef OPENSSL_NO_ENGINE
        +	ENGINE_cleanup();
        +#endif
        +	CRYPTO_cleanup_all_ex_data();
        +	ERR_free_strings();
        +	ERR_remove_thread_state(NULL);
        +	EVP_cleanup();
        +	CRYPTO_mem_leaks(bio_err);
        +	if (bio_err != NULL) BIO_free(bio_err);
        +	EXIT(ret);
        +	return ret;
        +	}
        +
        +int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
        +	clock_t *s_time, clock_t *c_time)
        +	{
        +	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
        +	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
        +	BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
        +	int ret = 1;
        +	
        +	size_t bufsiz = 256; /* small buffer for testing */
        +
        +	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
        +		goto err;
        +	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
        +		goto err;
        +	
        +	s_ssl_bio = BIO_new(BIO_f_ssl());
        +	if (!s_ssl_bio)
        +		goto err;
        +
        +	c_ssl_bio = BIO_new(BIO_f_ssl());
        +	if (!c_ssl_bio)
        +		goto err;
        +
        +	SSL_set_connect_state(c_ssl);
        +	SSL_set_bio(c_ssl, client, client);
        +	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
        +
        +	SSL_set_accept_state(s_ssl);
        +	SSL_set_bio(s_ssl, server, server);
        +	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
        +
        +	do
        +		{
        +		/* c_ssl_bio:          SSL filter BIO
        +		 *
        +		 * client:             pseudo-I/O for SSL library
        +		 *
        +		 * client_io:          client's SSL communication; usually to be
        +		 *                     relayed over some I/O facility, but in this
        +		 *                     test program, we're the server, too:
        +		 *
        +		 * server_io:          server's SSL communication
        +		 *
        +		 * server:             pseudo-I/O for SSL library
        +		 *
        +		 * s_ssl_bio:          SSL filter BIO
        +		 *
        +		 * The client and the server each employ a "BIO pair":
        +		 * client + client_io, server + server_io.
        +		 * BIO pairs are symmetric.  A BIO pair behaves similar
        +		 * to a non-blocking socketpair (but both endpoints must
        +		 * be handled by the same thread).
        +		 * [Here we could connect client and server to the ends
        +		 * of a single BIO pair, but then this code would be less
        +		 * suitable as an example for BIO pairs in general.]
        +		 *
        +		 * Useful functions for querying the state of BIO pair endpoints:
        +		 *
        +		 * BIO_ctrl_pending(bio)              number of bytes we can read now
        +		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
        +		 *                                      other side's read attempt
        +		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
        +		 *
        +		 * ..._read_request is never more than ..._write_guarantee;
        +		 * it depends on the application which one you should use.
        +		 */
        +
        +		/* We have non-blocking behaviour throughout this test program, but
        +		 * can be sure that there is *some* progress in each iteration; so
        +		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
        +		 * -- we just try everything in each iteration
        +		 */
        +
        +			{
        +			/* CLIENT */
        +		
        +			MS_STATIC char cbuf[1024*8];
        +			int i, r;
        +			clock_t c_clock = clock();
        +
        +			memset(cbuf, 0, sizeof(cbuf));
        +
        +			if (debug)
        +				if (SSL_in_init(c_ssl))
        +					printf("client waiting in SSL_connect - %s\n",
        +						SSL_state_string_long(c_ssl));
        +
        +			if (cw_num > 0)
        +				{
        +				/* Write to server. */
        +				
        +				if (cw_num > (long)sizeof cbuf)
        +					i = sizeof cbuf;
        +				else
        +					i = (int)cw_num;
        +				r = BIO_write(c_ssl_bio, cbuf, i);
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(c_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						goto err;
        +						}
        +					/* BIO_should_retry(...) can just be ignored here.
        +					 * The library expects us to call BIO_write with
        +					 * the same arguments again, and that's what we will
        +					 * do in the next iteration. */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client wrote %d\n", r);
        +					cw_num -= r;				
        +					}
        +				}
        +
        +			if (cr_num > 0)
        +				{
        +				/* Read from server. */
        +
        +				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(c_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						goto err;
        +						}
        +					/* Again, "BIO_should_retry" can be ignored. */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client read %d\n", r);
        +					cr_num -= r;
        +					}
        +				}
        +
        +			/* c_time and s_time increments will typically be very small
        +			 * (depending on machine speed and clock tick intervals),
        +			 * but sampling over a large number of connections should
        +			 * result in fairly accurate figures.  We cannot guarantee
        +			 * a lot, however -- if each connection lasts for exactly
        +			 * one clock tick, it will be counted only for the client
        +			 * or only for the server or even not at all.
        +			 */
        +			*c_time += (clock() - c_clock);
        +			}
        +
        +			{
        +			/* SERVER */
        +		
        +			MS_STATIC char sbuf[1024*8];
        +			int i, r;
        +			clock_t s_clock = clock();
        +
        +			memset(sbuf, 0, sizeof(sbuf));
        +
        +			if (debug)
        +				if (SSL_in_init(s_ssl))
        +					printf("server waiting in SSL_accept - %s\n",
        +						SSL_state_string_long(s_ssl));
        +
        +			if (sw_num > 0)
        +				{
        +				/* Write to client. */
        +				
        +				if (sw_num > (long)sizeof sbuf)
        +					i = sizeof sbuf;
        +				else
        +					i = (int)sw_num;
        +				r = BIO_write(s_ssl_bio, sbuf, i);
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(s_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						goto err;
        +						}
        +					/* Ignore "BIO_should_retry". */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server wrote %d\n", r);
        +					sw_num -= r;				
        +					}
        +				}
        +
        +			if (sr_num > 0)
        +				{
        +				/* Read from client. */
        +
        +				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
        +				if (r < 0)
        +					{
        +					if (!BIO_should_retry(s_ssl_bio))
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						goto err;
        +						}
        +					/* blah, blah */
        +					}
        +				else if (r == 0)
        +					{
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server read %d\n", r);
        +					sr_num -= r;
        +					}
        +				}
        +
        +			*s_time += (clock() - s_clock);
        +			}
        +			
        +			{
        +			/* "I/O" BETWEEN CLIENT AND SERVER. */
        +
        +			size_t r1, r2;
        +			BIO *io1 = server_io, *io2 = client_io;
        +			/* we use the non-copying interface for io1
        +			 * and the standard BIO_write/BIO_read interface for io2
        +			 */
        +			
        +			static int prev_progress = 1;
        +			int progress = 0;
        +			
        +			/* io1 to io2 */
        +			do
        +				{
        +				size_t num;
        +				int r;
        +
        +				r1 = BIO_ctrl_pending(io1);
        +				r2 = BIO_ctrl_get_write_guarantee(io2);
        +
        +				num = r1;
        +				if (r2 < num)
        +					num = r2;
        +				if (num)
        +					{
        +					char *dataptr;
        +
        +					if (INT_MAX < num) /* yeah, right */
        +						num = INT_MAX;
        +					
        +					r = BIO_nread(io1, &dataptr, (int)num);
        +					assert(r > 0);
        +					assert(r <= (int)num);
        +					/* possibly r < num (non-contiguous data) */
        +					num = r;
        +					r = BIO_write(io2, dataptr, (int)num);
        +					if (r != (int)num) /* can't happen */
        +						{
        +						fprintf(stderr, "ERROR: BIO_write could not write "
        +							"BIO_ctrl_get_write_guarantee() bytes");
        +						goto err;
        +						}
        +					progress = 1;
        +
        +					if (debug)
        +						printf((io1 == client_io) ?
        +							"C->S relaying: %d bytes\n" :
        +							"S->C relaying: %d bytes\n",
        +							(int)num);
        +					}
        +				}
        +			while (r1 && r2);
        +
        +			/* io2 to io1 */
        +			{
        +				size_t num;
        +				int r;
        +
        +				r1 = BIO_ctrl_pending(io2);
        +				r2 = BIO_ctrl_get_read_request(io1);
        +				/* here we could use ..._get_write_guarantee instead of
        +				 * ..._get_read_request, but by using the latter
        +				 * we test restartability of the SSL implementation
        +				 * more thoroughly */
        +				num = r1;
        +				if (r2 < num)
        +					num = r2;
        +				if (num)
        +					{
        +					char *dataptr;
        +					
        +					if (INT_MAX < num)
        +						num = INT_MAX;
        +
        +					if (num > 1)
        +						--num; /* test restartability even more thoroughly */
        +					
        +					r = BIO_nwrite0(io1, &dataptr);
        +					assert(r > 0);
        +					if (r < (int)num)
        +						num = r;
        +					r = BIO_read(io2, dataptr, (int)num);
        +					if (r != (int)num) /* can't happen */
        +						{
        +						fprintf(stderr, "ERROR: BIO_read could not read "
        +							"BIO_ctrl_pending() bytes");
        +						goto err;
        +						}
        +					progress = 1;
        +					r = BIO_nwrite(io1, &dataptr, (int)num);
        +					if (r != (int)num) /* can't happen */
        +						{
        +						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
        +							"BIO_nwrite0() bytes");
        +						goto err;
        +						}
        +					
        +					if (debug)
        +						printf((io2 == client_io) ?
        +							"C->S relaying: %d bytes\n" :
        +							"S->C relaying: %d bytes\n",
        +							(int)num);
        +					}
        +			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
        +
        +			if (!progress && !prev_progress)
        +				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
        +					{
        +					fprintf(stderr, "ERROR: got stuck\n");
        +					if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)
        +						{
        +						fprintf(stderr, "This can happen for SSL2 because "
        +							"CLIENT-FINISHED and SERVER-VERIFY are written \n"
        +							"concurrently ...");
        +						if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
        +							&& strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)
        +							{
        +							fprintf(stderr, " ok.\n");
        +							goto end;
        +							}
        +						}
        +					fprintf(stderr, " ERROR.\n");
        +					goto err;
        +					}
        +			prev_progress = progress;
        +			}
        +		}
        +	while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
        +
        +	if (verbose)
        +		print_details(c_ssl, "DONE via BIO pair: ");
        +end:
        +	ret = 0;
        +
        + err:
        +	ERR_print_errors(bio_err);
        +	
        +	if (server)
        +		BIO_free(server);
        +	if (server_io)
        +		BIO_free(server_io);
        +	if (client)
        +		BIO_free(client);
        +	if (client_io)
        +		BIO_free(client_io);
        +	if (s_ssl_bio)
        +		BIO_free(s_ssl_bio);
        +	if (c_ssl_bio)
        +		BIO_free(c_ssl_bio);
        +
        +	return ret;
        +	}
        +
        +
        +#define W_READ	1
        +#define W_WRITE	2
        +#define C_DONE	1
        +#define S_DONE	2
        +
        +int doit(SSL *s_ssl, SSL *c_ssl, long count)
        +	{
        +	MS_STATIC char cbuf[1024*8],sbuf[1024*8];
        +	long cw_num=count,cr_num=count;
        +	long sw_num=count,sr_num=count;
        +	int ret=1;
        +	BIO *c_to_s=NULL;
        +	BIO *s_to_c=NULL;
        +	BIO *c_bio=NULL;
        +	BIO *s_bio=NULL;
        +	int c_r,c_w,s_r,s_w;
        +	int i,j;
        +	int done=0;
        +	int c_write,s_write;
        +	int do_server=0,do_client=0;
        +
        +	memset(cbuf,0,sizeof(cbuf));
        +	memset(sbuf,0,sizeof(sbuf));
        +
        +	c_to_s=BIO_new(BIO_s_mem());
        +	s_to_c=BIO_new(BIO_s_mem());
        +	if ((s_to_c == NULL) || (c_to_s == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	c_bio=BIO_new(BIO_f_ssl());
        +	s_bio=BIO_new(BIO_f_ssl());
        +	if ((c_bio == NULL) || (s_bio == NULL))
        +		{
        +		ERR_print_errors(bio_err);
        +		goto err;
        +		}
        +
        +	SSL_set_connect_state(c_ssl);
        +	SSL_set_bio(c_ssl,s_to_c,c_to_s);
        +	BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
        +
        +	SSL_set_accept_state(s_ssl);
        +	SSL_set_bio(s_ssl,c_to_s,s_to_c);
        +	BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
        +
        +	c_r=0; s_r=1;
        +	c_w=1; s_w=0;
        +	c_write=1,s_write=0;
        +
        +	/* We can always do writes */
        +	for (;;)
        +		{
        +		do_server=0;
        +		do_client=0;
        +
        +		i=(int)BIO_pending(s_bio);
        +		if ((i && s_r) || s_w) do_server=1;
        +
        +		i=(int)BIO_pending(c_bio);
        +		if ((i && c_r) || c_w) do_client=1;
        +
        +		if (do_server && debug)
        +			{
        +			if (SSL_in_init(s_ssl))
        +				printf("server waiting in SSL_accept - %s\n",
        +					SSL_state_string_long(s_ssl));
        +/*			else if (s_write)
        +				printf("server:SSL_write()\n");
        +			else
        +				printf("server:SSL_read()\n"); */
        +			}
        +
        +		if (do_client && debug)
        +			{
        +			if (SSL_in_init(c_ssl))
        +				printf("client waiting in SSL_connect - %s\n",
        +					SSL_state_string_long(c_ssl));
        +/*			else if (c_write)
        +				printf("client:SSL_write()\n");
        +			else
        +				printf("client:SSL_read()\n"); */
        +			}
        +
        +		if (!do_client && !do_server)
        +			{
        +			fprintf(stdout,"ERROR IN STARTUP\n");
        +			ERR_print_errors(bio_err);
        +			break;
        +			}
        +		if (do_client && !(done & C_DONE))
        +			{
        +			if (c_write)
        +				{
        +				j = (cw_num > (long)sizeof(cbuf)) ?
        +					(int)sizeof(cbuf) : (int)cw_num;
        +				i=BIO_write(c_bio,cbuf,j);
        +				if (i < 0)
        +					{
        +					c_r=0;
        +					c_w=0;
        +					if (BIO_should_retry(c_bio))
        +						{
        +						if (BIO_should_read(c_bio))
        +							c_r=1;
        +						if (BIO_should_write(c_bio))
        +							c_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client wrote %d\n",i);
        +					/* ok */
        +					s_r=1;
        +					c_write=0;
        +					cw_num-=i;
        +					}
        +				}
        +			else
        +				{
        +				i=BIO_read(c_bio,cbuf,sizeof(cbuf));
        +				if (i < 0)
        +					{
        +					c_r=0;
        +					c_w=0;
        +					if (BIO_should_retry(c_bio))
        +						{
        +						if (BIO_should_read(c_bio))
        +							c_r=1;
        +						if (BIO_should_write(c_bio))
        +							c_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in CLIENT\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("client read %d\n",i);
        +					cr_num-=i;
        +					if (sw_num > 0)
        +						{
        +						s_write=1;
        +						s_w=1;
        +						}
        +					if (cr_num <= 0)
        +						{
        +						s_write=1;
        +						s_w=1;
        +						done=S_DONE|C_DONE;
        +						}
        +					}
        +				}
        +			}
        +
        +		if (do_server && !(done & S_DONE))
        +			{
        +			if (!s_write)
        +				{
        +				i=BIO_read(s_bio,sbuf,sizeof(cbuf));
        +				if (i < 0)
        +					{
        +					s_r=0;
        +					s_w=0;
        +					if (BIO_should_retry(s_bio))
        +						{
        +						if (BIO_should_read(s_bio))
        +							s_r=1;
        +						if (BIO_should_write(s_bio))
        +							s_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					ERR_print_errors(bio_err);
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server read %d\n",i);
        +					sr_num-=i;
        +					if (cw_num > 0)
        +						{
        +						c_write=1;
        +						c_w=1;
        +						}
        +					if (sr_num <= 0)
        +						{
        +						s_write=1;
        +						s_w=1;
        +						c_write=0;
        +						}
        +					}
        +				}
        +			else
        +				{
        +				j = (sw_num > (long)sizeof(sbuf)) ?
        +					(int)sizeof(sbuf) : (int)sw_num;
        +				i=BIO_write(s_bio,sbuf,j);
        +				if (i < 0)
        +					{
        +					s_r=0;
        +					s_w=0;
        +					if (BIO_should_retry(s_bio))
        +						{
        +						if (BIO_should_read(s_bio))
        +							s_r=1;
        +						if (BIO_should_write(s_bio))
        +							s_w=1;
        +						}
        +					else
        +						{
        +						fprintf(stderr,"ERROR in SERVER\n");
        +						ERR_print_errors(bio_err);
        +						goto err;
        +						}
        +					}
        +				else if (i == 0)
        +					{
        +					ERR_print_errors(bio_err);
        +					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
        +					goto err;
        +					}
        +				else
        +					{
        +					if (debug)
        +						printf("server wrote %d\n",i);
        +					sw_num-=i;
        +					s_write=0;
        +					c_r=1;
        +					if (sw_num <= 0)
        +						done|=S_DONE;
        +					}
        +				}
        +			}
        +
        +		if ((done & S_DONE) && (done & C_DONE)) break;
        +		}
        +
        +	if (verbose)
        +		print_details(c_ssl, "DONE: ");
        +	ret=0;
        +err:
        +	/* We have to set the BIO's to NULL otherwise they will be
        +	 * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and
        +	 * again when c_ssl is SSL_free()ed.
        +	 * This is a hack required because s_ssl and c_ssl are sharing the same
        +	 * BIO structure and SSL_set_bio() and SSL_free() automatically
        +	 * BIO_free non NULL entries.
        +	 * You should not normally do this or be required to do this */
        +	if (s_ssl != NULL)
        +		{
        +		s_ssl->rbio=NULL;
        +		s_ssl->wbio=NULL;
        +		}
        +	if (c_ssl != NULL)
        +		{
        +		c_ssl->rbio=NULL;
        +		c_ssl->wbio=NULL;
        +		}
        +
        +	if (c_to_s != NULL) BIO_free(c_to_s);
        +	if (s_to_c != NULL) BIO_free(s_to_c);
        +	if (c_bio != NULL) BIO_free_all(c_bio);
        +	if (s_bio != NULL) BIO_free_all(s_bio);
        +	return(ret);
        +	}
        +
        +static int get_proxy_auth_ex_data_idx(void)
        +	{
        +	static volatile int idx = -1;
        +	if (idx < 0)
        +		{
        +		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
        +		if (idx < 0)
        +			{
        +			idx = X509_STORE_CTX_get_ex_new_index(0,
        +				"SSLtest for verify callback", NULL,NULL,NULL);
        +			}
        +		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
        +		}
        +	return idx;
        +	}
        +
        +static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        +	{
        +	char *s,buf[256];
        +
        +	s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
        +			    sizeof buf);
        +	if (s != NULL)
        +		{
        +		if (ok)
        +			fprintf(stderr,"depth=%d %s\n",
        +				ctx->error_depth,buf);
        +		else
        +			{
        +			fprintf(stderr,"depth=%d error=%d %s\n",
        +				ctx->error_depth,ctx->error,buf);
        +			}
        +		}
        +
        +	if (ok == 0)
        +		{
        +		fprintf(stderr,"Error string: %s\n",
        +			X509_verify_cert_error_string(ctx->error));
        +		switch (ctx->error)
        +			{
        +		case X509_V_ERR_CERT_NOT_YET_VALID:
        +		case X509_V_ERR_CERT_HAS_EXPIRED:
        +		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
        +			fprintf(stderr,"  ... ignored.\n");
        +			ok=1;
        +			}
        +		}
        +
        +	if (ok == 1)
        +		{
        +		X509 *xs = ctx->current_cert;
        +#if 0
        +		X509 *xi = ctx->current_issuer;
        +#endif
        +
        +		if (xs->ex_flags & EXFLAG_PROXY)
        +			{
        +			unsigned int *letters =
        +				X509_STORE_CTX_get_ex_data(ctx,
        +					get_proxy_auth_ex_data_idx());
        +
        +			if (letters)
        +				{
        +				int found_any = 0;
        +				int i;
        +				PROXY_CERT_INFO_EXTENSION *pci =
        +					X509_get_ext_d2i(xs, NID_proxyCertInfo,
        +						NULL, NULL);
        +
        +				switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
        +					{
        +				case NID_Independent:
        +					/* Completely meaningless in this
        +					   program, as there's no way to
        +					   grant explicit rights to a
        +					   specific PrC.  Basically, using
        +					   id-ppl-Independent is the perfect
        +					   way to grant no rights at all. */
        +					fprintf(stderr, "  Independent proxy certificate");
        +					for (i = 0; i < 26; i++)
        +						letters[i] = 0;
        +					break;
        +				case NID_id_ppl_inheritAll:
        +					/* This is basically a NOP, we
        +					   simply let the current rights
        +					   stand as they are. */
        +					fprintf(stderr, "  Proxy certificate inherits all");
        +					break;
        +				default:
        +					s = (char *)
        +						pci->proxyPolicy->policy->data;
        +					i = pci->proxyPolicy->policy->length;
        +
        +					/* The algorithm works as follows:
        +					   it is assumed that previous
        +					   iterations or the initial granted
        +					   rights has already set some elements
        +					   of `letters'.  What we need to do is
        +					   to clear those that weren't granted
        +					   by the current PrC as well.  The
        +					   easiest way to do this is to add 1
        +					   to all the elements whose letters
        +					   are given with the current policy.
        +					   That way, all elements that are set
        +					   by the current policy and were
        +					   already set by earlier policies and
        +					   through the original grant of rights
        +					   will get the value 2 or higher.
        +					   The last thing to do is to sweep
        +					   through `letters' and keep the
        +					   elements having the value 2 as set,
        +					   and clear all the others. */
        +
        +					fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
        +					while(i-- > 0)
        +						{
        +						int c = *s++;
        +						if (isascii(c) && isalpha(c))
        +							{
        +							if (islower(c))
        +								c = toupper(c);
        +							letters[c - 'A']++;
        +							}
        +						}
        +					for (i = 0; i < 26; i++)
        +						if (letters[i] < 2)
        +							letters[i] = 0;
        +						else
        +							letters[i] = 1;
        +					}
        +
        +				found_any = 0;
        +				fprintf(stderr,
        +					", resulting proxy rights = ");
        +				for(i = 0; i < 26; i++)
        +					if (letters[i])
        +						{
        +						fprintf(stderr, "%c", i + 'A');
        +						found_any = 1;
        +						}
        +				if (!found_any)
        +					fprintf(stderr, "none");
        +				fprintf(stderr, "\n");
        +
        +				PROXY_CERT_INFO_EXTENSION_free(pci);
        +				}
        +			}
        +		}
        +
        +	return(ok);
        +	}
        +
        +static void process_proxy_debug(int indent, const char *format, ...)
        +	{
        +	static const char indentation[] =
        +		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
        +		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
        +	char my_format[256];
        +	va_list args;
        +
        +	BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
        +		indent, indent, indentation, format);
        +
        +	va_start(args, format);
        +	vfprintf(stderr, my_format, args);
        +	va_end(args);
        +	}
        +/* Priority levels:
        +   0	[!]var, ()
        +   1	& ^
        +   2	|
        +*/
        +static int process_proxy_cond_adders(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent);
        +static int process_proxy_cond_val(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent)
        +	{
        +	int c;
        +	int ok = 1;
        +	int negate = 0;
        +
        +	while(isspace((int)*cond))
        +		{
        +		cond++; (*pos)++;
        +		}
        +	c = *cond;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"Start process_proxy_cond_val at position %d: %s\n",
        +			*pos, cond);
        +
        +	while(c == '!')
        +		{
        +		negate = !negate;
        +		cond++; (*pos)++;
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +		}
        +
        +	if (c == '(')
        +		{
        +		cond++; (*pos)++;
        +		ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
        +			indent + 1);
        +		cond = *cond_end;
        +		if (ok < 0)
        +			goto end;
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +		if (c != ')')
        +			{
        +			fprintf(stderr,
        +				"Weird condition character in position %d: "
        +				"%c\n", *pos, c);
        +			ok = -1;
        +			goto end;
        +			}
        +		cond++; (*pos)++;
        +		}
        +	else if (isascii(c) && isalpha(c))
        +		{
        +		if (islower(c))
        +			c = toupper(c);
        +		ok = letters[c - 'A'];
        +		cond++; (*pos)++;
        +		}
        +	else
        +		{
        +		fprintf(stderr,
        +			"Weird condition character in position %d: "
        +			"%c\n", *pos, c);
        +		ok = -1;
        +		goto end;
        +		}
        + end:
        +	*cond_end = cond;
        +	if (ok >= 0 && negate)
        +		ok = !ok;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"End process_proxy_cond_val at position %d: %s, returning %d\n",
        +			*pos, cond, ok);
        +
        +	return ok;
        +	}
        +static int process_proxy_cond_multipliers(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent)
        +	{
        +	int ok;
        +	char c;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"Start process_proxy_cond_multipliers at position %d: %s\n",
        +			*pos, cond);
        +
        +	ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
        +	cond = *cond_end;
        +	if (ok < 0)
        +		goto end;
        +
        +	while(ok >= 0)
        +		{
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +
        +		switch(c)
        +			{
        +		case '&':
        +		case '^':
        +			{
        +			int save_ok = ok;
        +
        +			cond++; (*pos)++;
        +			ok = process_proxy_cond_val(letters,
        +				cond, cond_end, pos, indent + 1);
        +			cond = *cond_end;
        +			if (ok < 0)
        +				break;
        +
        +			switch(c)
        +				{
        +			case '&':
        +				ok &= save_ok;
        +				break;
        +			case '^':
        +				ok ^= save_ok;
        +				break;
        +			default:
        +				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
        +					" STOPPING\n");
        +				EXIT(1);
        +				}
        +			}
        +			break;
        +		default:
        +			goto end;
        +			}
        +		}
        + end:
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
        +			*pos, cond, ok);
        +
        +	*cond_end = cond;
        +	return ok;
        +	}
        +static int process_proxy_cond_adders(unsigned int letters[26],
        +	const char *cond, const char **cond_end, int *pos, int indent)
        +	{
        +	int ok;
        +	char c;
        +
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"Start process_proxy_cond_adders at position %d: %s\n",
        +			*pos, cond);
        +
        +	ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
        +		indent + 1);
        +	cond = *cond_end;
        +	if (ok < 0)
        +		goto end;
        +
        +	while(ok >= 0)
        +		{
        +		while(isspace((int)*cond))
        +			{
        +			cond++; (*pos)++;
        +			}
        +		c = *cond;
        +
        +		switch(c)
        +			{
        +		case '|':
        +			{
        +			int save_ok = ok;
        +
        +			cond++; (*pos)++;
        +			ok = process_proxy_cond_multipliers(letters,
        +				cond, cond_end, pos, indent + 1);
        +			cond = *cond_end;
        +			if (ok < 0)
        +				break;
        +
        +			switch(c)
        +				{
        +			case '|':
        +				ok |= save_ok;
        +				break;
        +			default:
        +				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
        +					" STOPPING\n");
        +				EXIT(1);
        +				}
        +			}
        +			break;
        +		default:
        +			goto end;
        +			}
        +		}
        + end:
        +	if (debug)
        +		process_proxy_debug(indent,
        +			"End process_proxy_cond_adders at position %d: %s, returning %d\n",
        +			*pos, cond, ok);
        +
        +	*cond_end = cond;
        +	return ok;
        +	}
        +
        +static int process_proxy_cond(unsigned int letters[26],
        +	const char *cond, const char **cond_end)
        +	{
        +	int pos = 1;
        +	return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
        +	}
        +
        +static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
        +	{
        +	int ok=1;
        +	struct app_verify_arg *cb_arg = arg;
        +	unsigned int letters[26]; /* only used with proxy_auth */
        +
        +	if (cb_arg->app_verify)
        +		{
        +		char *s = NULL,buf[256];
        +
        +		fprintf(stderr, "In app_verify_callback, allowing cert. ");
        +		fprintf(stderr, "Arg is: %s\n", cb_arg->string);
        +		fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
        +			(void *)ctx, (void *)ctx->cert);
        +		if (ctx->cert)
        +			s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
        +		if (s != NULL)
        +			{
        +			fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
        +			}
        +		return(1);
        +		}
        +	if (cb_arg->proxy_auth)
        +		{
        +		int found_any = 0, i;
        +		char *sp;
        +
        +		for(i = 0; i < 26; i++)
        +			letters[i] = 0;
        +		for(sp = cb_arg->proxy_auth; *sp; sp++)
        +			{
        +			int c = *sp;
        +			if (isascii(c) && isalpha(c))
        +				{
        +				if (islower(c))
        +					c = toupper(c);
        +				letters[c - 'A'] = 1;
        +				}
        +			}
        +
        +		fprintf(stderr,
        +			"  Initial proxy rights = ");
        +		for(i = 0; i < 26; i++)
        +			if (letters[i])
        +				{
        +				fprintf(stderr, "%c", i + 'A');
        +				found_any = 1;
        +				}
        +		if (!found_any)
        +			fprintf(stderr, "none");
        +		fprintf(stderr, "\n");
        +
        +		X509_STORE_CTX_set_ex_data(ctx,
        +			get_proxy_auth_ex_data_idx(),letters);
        +		}
        +	if (cb_arg->allow_proxy_certs)
        +		{
        +		X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
        +		}
        +
        +#ifndef OPENSSL_NO_X509_VERIFY
        +	ok = X509_verify_cert(ctx);
        +#endif
        +
        +	if (cb_arg->proxy_auth)
        +		{
        +		if (ok > 0)
        +			{
        +			const char *cond_end = NULL;
        +
        +			ok = process_proxy_cond(letters,
        +				cb_arg->proxy_cond, &cond_end);
        +
        +			if (ok < 0)
        +				EXIT(3);
        +			if (*cond_end)
        +				{
        +				fprintf(stderr, "Stopped processing condition before it's end.\n");
        +				ok = 0;
        +				}
        +			if (!ok)
        +				fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
        +					cb_arg->proxy_cond);
        +			else
        +				fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
        +					cb_arg->proxy_cond);
        +			}
        +		}
        +	return(ok);
        +	}
        +
        +#ifndef OPENSSL_NO_RSA
        +static RSA *rsa_tmp=NULL;
        +
        +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
        +	{
        +	BIGNUM *bn = NULL;
        +	if (rsa_tmp == NULL)
        +		{
        +		bn = BN_new();
        +		rsa_tmp = RSA_new();
        +		if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
        +			{
        +			BIO_printf(bio_err, "Memory error...");
        +			goto end;
        +			}
        +		BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
        +		(void)BIO_flush(bio_err);
        +		if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
        +			{
        +			BIO_printf(bio_err, "Error generating key.");
        +			RSA_free(rsa_tmp);
        +			rsa_tmp = NULL;
        +			}
        +end:
        +		BIO_printf(bio_err,"\n");
        +		(void)BIO_flush(bio_err);
        +		}
        +	if(bn) BN_free(bn);
        +	return(rsa_tmp);
        +	}
        +
        +static void free_tmp_rsa(void)
        +	{
        +	if (rsa_tmp != NULL)
        +		{
        +		RSA_free(rsa_tmp);
        +		rsa_tmp = NULL;
        +		}
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_DH
        +/* These DH parameters have been generated as follows:
        + *    $ openssl dhparam -C -noout 512
        + *    $ openssl dhparam -C -noout 1024
        + *    $ openssl dhparam -C -noout -dsaparam 1024
        + * (The third function has been renamed to avoid name conflicts.)
        + */
        +static DH *get_dh512()
        +	{
        +	static unsigned char dh512_p[]={
        +		0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
        +		0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
        +		0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
        +		0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
        +		0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
        +		0x02,0xC5,0xAE,0x23,
        +		};
        +	static unsigned char dh512_g[]={
        +		0x02,
        +		};
        +	DH *dh;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
        +	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		{ DH_free(dh); return(NULL); }
        +	return(dh);
        +	}
        +
        +static DH *get_dh1024()
        +	{
        +	static unsigned char dh1024_p[]={
        +		0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
        +		0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
        +		0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
        +		0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
        +		0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
        +		0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
        +		0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
        +		0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
        +		0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
        +		0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
        +		0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
        +		};
        +	static unsigned char dh1024_g[]={
        +		0x02,
        +		};
        +	DH *dh;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
        +	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		{ DH_free(dh); return(NULL); }
        +	return(dh);
        +	}
        +
        +static DH *get_dh1024dsa()
        +	{
        +	static unsigned char dh1024_p[]={
        +		0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
        +		0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
        +		0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
        +		0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
        +		0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
        +		0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
        +		0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
        +		0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
        +		0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
        +		0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
        +		0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
        +		};
        +	static unsigned char dh1024_g[]={
        +		0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
        +		0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
        +		0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
        +		0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
        +		0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
        +		0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
        +		0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
        +		0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
        +		0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
        +		0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
        +		0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
        +		};
        +	DH *dh;
        +
        +	if ((dh=DH_new()) == NULL) return(NULL);
        +	dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
        +	dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
        +	if ((dh->p == NULL) || (dh->g == NULL))
        +		{ DH_free(dh); return(NULL); }
        +	dh->length = 160;
        +	return(dh);
        +	}
        +#endif
        +
        +#ifndef OPENSSL_NO_PSK
        +/* convert the PSK key (psk_key) in ascii to binary (psk) */
        +static int psk_key2bn(const char *pskkey, unsigned char *psk,
        +	unsigned int max_psk_len)
        +	{
        +	int ret;
        +	BIGNUM *bn = NULL;
        +
        +	ret = BN_hex2bn(&bn, pskkey);
        +	if (!ret)
        +		{
        +		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", pskkey); 
        +		if (bn)
        +			BN_free(bn);
        +		return 0;
        +		}
        +	if (BN_num_bytes(bn) > (int)max_psk_len)
        +		{
        +		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
        +			max_psk_len, BN_num_bytes(bn));
        +		BN_free(bn);
        +		return 0;
        +		}
        +	ret = BN_bn2bin(bn, psk);
        +	BN_free(bn);
        +	return ret;
        +	}
        +
        +static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
        +	unsigned int max_identity_len, unsigned char *psk,
        +	unsigned int max_psk_len)
        +	{
        +	int ret;
        +	unsigned int psk_len = 0;
        +
        +	ret = BIO_snprintf(identity, max_identity_len, "Client_identity");
        +	if (ret < 0)
        +		goto out_err;
        +	if (debug)
        +		fprintf(stderr, "client: created identity '%s' len=%d\n", identity, ret);
        +	ret = psk_key2bn(psk_key, psk, max_psk_len);
        +	if (ret < 0)
        +		goto out_err;
        +	psk_len = ret;
        +out_err:
        +	return psk_len;
        +	}
        +
        +static unsigned int psk_server_callback(SSL *ssl, const char *identity,
        +	unsigned char *psk, unsigned int max_psk_len)
        +	{
        +	unsigned int psk_len=0;
        +
        +	if (strcmp(identity, "Client_identity") != 0)
        +		{
        +		BIO_printf(bio_err, "server: PSK error: client identity not found\n");
        +		return 0;
        +		}
        +	psk_len=psk_key2bn(psk_key, psk, max_psk_len);
        +	return psk_len;
        +	}
        +#endif
        +
        +static int do_test_cipherlist(void)
        +	{
        +	int i = 0;
        +	const SSL_METHOD *meth;
        +	const SSL_CIPHER *ci, *tci = NULL;
        +
        +#ifndef OPENSSL_NO_SSL2
        +	fprintf(stderr, "testing SSLv2 cipher list order: ");
        +	meth = SSLv2_method();
        +	while ((ci = meth->get_cipher(i++)) != NULL)
        +		{
        +		if (tci != NULL)
        +			if (ci->id >= tci->id)
        +				{
        +				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
        +				return 0;
        +				}
        +		tci = ci;
        +		}
        +	fprintf(stderr, "ok\n");
        +#endif
        +#ifndef OPENSSL_NO_SSL3
        +	fprintf(stderr, "testing SSLv3 cipher list order: ");
        +	meth = SSLv3_method();
        +	tci = NULL;
        +	while ((ci = meth->get_cipher(i++)) != NULL)
        +		{
        +		if (tci != NULL)
        +			if (ci->id >= tci->id)
        +				{
        +				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
        +				return 0;
        +				}
        +		tci = ci;
        +		}
        +	fprintf(stderr, "ok\n");
        +#endif
        +#ifndef OPENSSL_NO_TLS1
        +	fprintf(stderr, "testing TLSv1 cipher list order: ");
        +	meth = TLSv1_method();
        +	tci = NULL;
        +	while ((ci = meth->get_cipher(i++)) != NULL)
        +		{
        +		if (tci != NULL)
        +			if (ci->id >= tci->id)
        +				{
        +				fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
        +				return 0;
        +				}
        +		tci = ci;
        +		}
        +	fprintf(stderr, "ok\n");
        +#endif
        +
        +	return 1;
        +	}
        diff --git a/vendor/openssl/openssl/test/tcrl b/vendor/openssl/openssl/test/tcrl
        new file mode 100644
        index 000000000..055269eab
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tcrl
        @@ -0,0 +1,78 @@
        +#!/bin/sh
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl crl'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=testcrl.pem
        +fi
        +
        +echo testing crl conversions
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in fff.p -inform p -outform t >f.t
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> d"
        +#$cmd -in f.t -inform t -outform d >ff.d2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#echo "d -> t"
        +#$cmd -in f.d -inform d -outform t >ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> t"
        +#$cmd -in f.t -inform t -outform t >ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in f.p -inform p -outform t >ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> p"
        +#$cmd -in f.t -inform t -outform p >ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp fff.p f.p
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp fff.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#cmp f.t ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp f.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/tcrl.com b/vendor/openssl/openssl/test/tcrl.com
        new file mode 100644
        index 000000000..dd96a2b6d
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tcrl.com
        @@ -0,0 +1,88 @@
        +$! TCRL.COM  --  Tests crl keys
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	cmd = "mcr ''exe_dir'openssl crl"
        +$
        +$	t = "testcrl.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing CRL conversions"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in fff.p -inform p -outform t -out f.t
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> d"
        +$!	'cmd' -in f.t -inform t -outform d -out ff.d2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	write sys$output "d -> t"
        +$!	'cmd' -in f.d -inform d -outform t -out ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> t"
        +$!	'cmd' -in f.t -inform t -outform t -out ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in f.p -inform p -outform t -out ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> p"
        +$!	'cmd' -in f.t -inform t -outform p -out ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare fff.p f.p
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare fff.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	backup/compare f.t ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/test.cnf b/vendor/openssl/openssl/test/test.cnf
        new file mode 100644
        index 000000000..10834442a
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/test.cnf
        @@ -0,0 +1,88 @@
        +#
        +# SSLeay example configuration file.
        +# This is mostly being used for generation of certificate requests.
        +#
        +
        +RANDFILE		= ./.rnd
        +
        +####################################################################
        +[ ca ]
        +default_ca	= CA_default		# The default ca section
        +
        +####################################################################
        +[ CA_default ]
        +
        +dir		= ./demoCA		# Where everything is kept
        +certs		= $dir/certs		# Where the issued certs are kept
        +crl_dir		= $dir/crl		# Where the issued crl are kept
        +database	= $dir/index.txt	# database index file.
        +new_certs_dir	= $dir/new_certs	# default place for new certs.
        +
        +certificate	= $dir/CAcert.pem 	# The CA certificate
        +serial		= $dir/serial 		# The current serial number
        +crl		= $dir/crl.pem 		# The current CRL
        +private_key	= $dir/private/CAkey.pem# The private key
        +RANDFILE	= $dir/private/.rand	# private random number file
        +
        +default_days	= 365			# how long to certify for
        +default_crl_days= 30			# how long before next CRL
        +default_md	= md5			# which md to use.
        +
        +# A few difference way of specifying how similar the request should look
        +# For type CA, the listed attributes must be the same, and the optional
        +# and supplied fields are just that :-)
        +policy		= policy_match
        +
        +# For the CA policy
        +[ policy_match ]
        +countryName		= match
        +stateOrProvinceName	= match
        +organizationName	= match
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +# For the 'anything' policy
        +# At this point in time, you must list all acceptable 'object'
        +# types.
        +[ policy_anything ]
        +countryName		= optional
        +stateOrProvinceName	= optional
        +localityName		= optional
        +organizationName	= optional
        +organizationalUnitName	= optional
        +commonName		= supplied
        +emailAddress		= optional
        +
        +####################################################################
        +[ req ]
        +default_bits		= 1024
        +default_keyfile 	= testkey.pem
        +distinguished_name	= req_distinguished_name
        +encrypt_rsa_key		= no
        +
        +[ req_distinguished_name ]
        +countryName			= Country Name (2 letter code)
        +countryName_default		= AU
        +countryName_value		= AU
        +
        +stateOrProvinceName		= State or Province Name (full name)
        +stateOrProvinceName_default	= Queensland
        +stateOrProvinceName_value	=
        +
        +localityName			= Locality Name (eg, city)
        +localityName_value		= Brisbane
        +
        +organizationName		= Organization Name (eg, company)
        +organizationName_default	= 
        +organizationName_value		= CryptSoft Pty Ltd
        +
        +organizationalUnitName		= Organizational Unit Name (eg, section)
        +organizationalUnitName_default	=
        +organizationalUnitName_value	= .
        +
        +commonName			= Common Name (eg, YOUR name)
        +commonName_value		= Eric Young
        +
        +emailAddress			= Email Address
        +emailAddress_value		= eay@mincom.oz.au
        diff --git a/vendor/openssl/openssl/test/test_padlock b/vendor/openssl/openssl/test/test_padlock
        new file mode 100644
        index 000000000..5c0f21043
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/test_padlock
        @@ -0,0 +1,64 @@
        +#!/bin/sh
        +
        +PROG=$1
        +
        +if [ -x $PROG ]; then
        +    if expr "x`$PROG version`" : "xOpenSSL" > /dev/null; then
        +	:
        +    else
        +	echo "$PROG is not OpenSSL executable"
        +	exit 1
        +    fi
        +else
        +    echo "$PROG is not executable"
        +    exit 1;
        +fi
        +
        +if $PROG engine padlock | grep -v no-ACE; then
        +
        +    HASH=`cat $PROG | $PROG dgst -hex`
        +
        +    ACE_ALGS="	aes-128-ecb aes-192-ecb aes-256-ecb \
        +		aes-128-cbc aes-192-cbc aes-256-cbc \
        +		aes-128-cfb aes-192-cfb aes-256-cfb \
        +		aes-128-ofb aes-192-ofb aes-256-ofb"
        +
        +    nerr=0
        +
        +    for alg in $ACE_ALGS; do
        +	echo $alg
        +	TEST=`(	cat $PROG | \
        +		$PROG enc -e -k "$HASH" -$alg -bufsize 999 -engine padlock | \
        +		$PROG enc -d -k "$HASH" -$alg | \
        +		$PROG dgst -hex ) 2>/dev/null`
        +	if [ "$TEST" != "$HASH" ]; then
        +		echo "-$alg encrypt test failed"
        +		nerr=`expr $nerr + 1`
        +	fi
        +	TEST=`(	cat $PROG | \
        +		$PROG enc -e -k "$HASH" -$alg | \
        +		$PROG enc -d -k "$HASH" -$alg -bufsize 999 -engine padlock | \
        +		$PROG dgst -hex ) 2>/dev/null`
        +	if [ "$TEST" != "$HASH" ]; then
        +		echo "-$alg decrypt test failed"
        +		nerr=`expr $nerr + 1`
        +	fi
        +	TEST=`(	cat $PROG | \
        +		$PROG enc -e -k "$HASH" -$alg -engine padlock | \
        +		$PROG enc -d -k "$HASH" -$alg -engine padlock | \
        +		$PROG dgst -hex ) 2>/dev/null`
        +	if [ "$TEST" != "$HASH" ]; then
        +		echo "-$alg en/decrypt test failed"
        +		nerr=`expr $nerr + 1`
        +	fi
        +    done
        +
        +    if [ $nerr -gt 0 ]; then
        +	echo "PadLock ACE test failed."
        +	exit 1;
        +    fi
        +else
        +    echo "PadLock ACE is not available"
        +fi
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/test/testca b/vendor/openssl/openssl/test/testca
        new file mode 100644
        index 000000000..b109cfe27
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testca
        @@ -0,0 +1,51 @@
        +#!/bin/sh
        +
        +SH="/bin/sh"
        +if test "$OSTYPE" = msdosdjgpp; then
        +    PATH="../apps\;$PATH"
        +else
        +    PATH="../apps:$PATH"
        +fi
        +export SH PATH
        +
        +SSLEAY_CONFIG="-config CAss.cnf"
        +export SSLEAY_CONFIG
        +
        +OPENSSL="`pwd`/../util/opensslwrap.sh"
        +export OPENSSL
        +
        +/bin/rm -fr demoCA
        +$SH ../apps/CA.sh -newca <<EOF
        +EOF
        +
        +if [ $? != 0 ]; then
        +	exit 1;
        +fi
        +
        +SSLEAY_CONFIG="-config Uss.cnf"
        +export SSLEAY_CONFIG
        +$SH ../apps/CA.sh -newreq
        +if [ $? != 0 ]; then
        +	exit 1;
        +fi
        +
        +
        +SSLEAY_CONFIG="-config ../apps/openssl.cnf"
        +export SSLEAY_CONFIG
        +$SH ../apps/CA.sh -sign  <<EOF
        +y
        +y
        +EOF
        +if [ $? != 0 ]; then
        +	exit 1;
        +fi
        +
        +
        +$SH ../apps/CA.sh -verify newcert.pem
        +if [ $? != 0 ]; then
        +	exit 1;
        +fi
        +
        +/bin/rm -fr demoCA newcert.pem newreq.pem
        +#usage: CA -newcert|-newreq|-newca|-sign|-verify
        +
        diff --git a/vendor/openssl/openssl/test/testca.com b/vendor/openssl/openssl/test/testca.com
        new file mode 100644
        index 000000000..78cda9ec5
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testca.com
        @@ -0,0 +1,52 @@
        +$! TESTCA.COM
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$       if (p1 .eqs. "64") then __arch = __arch+ "_64"
        +$
        +$	openssl = "mcr ''exe_dir'openssl"
        +$
        +$	SSLEAY_CONFIG="-config ""CAss.cnf"""
        +$
        +$	set noon
        +$	if f$search("demoCA.dir") .nes. ""
        +$	then
        +$	    @[-.util]deltree [.demoCA]*.*
        +$	    set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) demoCA.dir;*
        +$	    delete demoCA.dir;*
        +$	endif
        +$	set on
        +$	open/read sys$ca_input VMSca-response.1
        +$	@[-.apps]CA.com -input sys$ca_input -newca
        +$	close sys$ca_input
        +$	if $severity .ne. 1 then exit 3
        +$
        +$
        +$	SSLEAY_CONFIG="-config ""Uss.cnf"""
        +$	@[-.apps]CA.com -newreq
        +$	if $severity .ne. 1 then exit 3
        +$
        +$
        +$	SSLEAY_CONFIG="-config [-.apps]openssl-vms.cnf"
        +$	open/read sys$ca_input VMSca-response.2
        +$	@[-.apps]CA.com -input sys$ca_input -sign
        +$	close sys$ca_input
        +$	if $severity .ne. 1 then exit 3
        +$
        +$
        +$	@[-.apps]CA.com -verify newcert.pem
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	set noon
        +$	@[-.util]deltree [.demoCA]*.*
        +$	set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) demoCA.dir;*
        +$	delete demoCA.dir;*
        +$	if f$search("newcert.pem") .nes. "" then delete newcert.pem;*
        +$	if f$search("newcert.pem") .nes. "" then delete newreq.pem;*
        +$	set on
        +$!	#usage: CA -newcert|-newreq|-newca|-sign|-verify
        +$
        +$	exit
        diff --git a/vendor/openssl/openssl/test/testcrl.pem b/vendor/openssl/openssl/test/testcrl.pem
        new file mode 100644
        index 000000000..098978835
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testcrl.pem
        @@ -0,0 +1,16 @@
        +-----BEGIN X509 CRL-----
        +MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT
        +F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy
        +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw
        +MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw
        +MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw
        +MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw
        +MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw
        +MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw
        +MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw
        +NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw
        +NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF
        +AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ
        +wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt
        +JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v
        +-----END X509 CRL-----
        diff --git a/vendor/openssl/openssl/test/testenc b/vendor/openssl/openssl/test/testenc
        new file mode 100644
        index 000000000..f5ce7c0c4
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testenc
        @@ -0,0 +1,54 @@
        +#!/bin/sh
        +
        +testsrc=Makefile
        +test=./p
        +cmd="../util/shlib_wrap.sh ../apps/openssl"
        +
        +cat $testsrc >$test;
        +
        +echo cat
        +$cmd enc < $test > $test.cipher
        +$cmd enc < $test.cipher >$test.clear
        +cmp $test $test.clear
        +if [ $? != 0 ]
        +then
        +	exit 1
        +else
        +	/bin/rm $test.cipher $test.clear
        +fi
        +echo base64
        +$cmd enc -a -e < $test > $test.cipher
        +$cmd enc -a -d < $test.cipher >$test.clear
        +cmp $test $test.clear
        +if [ $? != 0 ]
        +then
        +	exit 1
        +else
        +	/bin/rm $test.cipher $test.clear
        +fi
        +
        +for i in `$cmd list-cipher-commands`
        +do
        +	echo $i
        +	$cmd $i -bufsize 113 -e -k test < $test > $test.$i.cipher
        +	$cmd $i -bufsize 157 -d -k test < $test.$i.cipher >$test.$i.clear
        +	cmp $test $test.$i.clear
        +	if [ $? != 0 ]
        +	then
        +		exit 1
        +	else
        +		/bin/rm $test.$i.cipher $test.$i.clear
        +	fi
        +
        +	echo $i base64
        +	$cmd $i -bufsize 113 -a -e -k test < $test > $test.$i.cipher
        +	$cmd $i -bufsize 157 -a -d -k test < $test.$i.cipher >$test.$i.clear
        +	cmp $test $test.$i.clear
        +	if [ $? != 0 ]
        +	then
        +		exit 1
        +	else
        +		/bin/rm $test.$i.cipher $test.$i.clear
        +	fi
        +done
        +rm -f $test
        diff --git a/vendor/openssl/openssl/test/testenc.com b/vendor/openssl/openssl/test/testenc.com
        new file mode 100644
        index 000000000..75acd6f07
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testenc.com
        @@ -0,0 +1,66 @@
        +$! TESTENC.COM  --  Test encoding and decoding
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p1 .eqs. 64) then __arch = __arch+ "_64"
        +$
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$	testsrc = "makefile."
        +$	test = "p.txt"
        +$	cmd = "mcr ''exe_dir'openssl"
        +$
        +$	if f$search(test) .nes. "" then delete 'test';*
        +$	convert/fdl=sys$input: 'testsrc' 'test'
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	if f$search(test+"-cipher") .nes. "" then delete 'test'-cipher;*
        +$	if f$search(test+"-clear") .nes. "" then delete 'test'-clear;*
        +$
        +$	write sys$output "cat"
        +$	'cmd' enc -in 'test' -out 'test'-cipher
        +$	'cmd' enc -in 'test'-cipher -out 'test'-clear
        +$	backup/compare 'test' 'test'-clear
        +$	if $severity .ne. 1 then exit 3
        +$	delete 'test'-cipher;*,'test'-clear;*
        +$
        +$	write sys$output "base64"
        +$	'cmd' enc -a -e -in 'test' -out 'test'-cipher
        +$	'cmd' enc -a -d -in 'test'-cipher -out 'test'-clear
        +$	backup/compare 'test' 'test'-clear
        +$	if $severity .ne. 1 then exit 3
        +$	delete 'test'-cipher;*,'test'-clear;*
        +$
        +$	define/user sys$output 'test'-cipher-commands
        +$	'cmd' list-cipher-commands
        +$	open/read f 'test'-cipher-commands
        +$ loop_cipher_commands:
        +$	read/end=loop_cipher_commands_end f i
        +$	write sys$output i
        +$
        +$	if f$search(test+"-"+i+"-cipher") .nes. "" then -
        +		delete 'test'-'i'-cipher;*
        +$	if f$search(test+"-"+i+"-clear") .nes. "" then -
        +		delete 'test'-'i'-clear;*
        +$
        +$	'cmd' 'i' -bufsize 113 -e -k test -in 'test' -out 'test'-'i'-cipher
        +$	'cmd' 'i' -bufsize 157 -d -k test -in 'test'-'i'-cipher -out 'test'-'i'-clear
        +$	backup/compare 'test' 'test'-'i'-clear
        +$	if $severity .ne. 1 then exit 3
        +$	delete 'test'-'i'-cipher;*,'test'-'i'-clear;*
        +$
        +$	write sys$output i," base64"
        +$	'cmd' 'i' -bufsize 113 -a -e -k test -in 'test' -out 'test'-'i'-cipher
        +$	'cmd' 'i' -bufsize 157 -a -d -k test -in 'test'-'i'-cipher -out 'test'-'i'-clear
        +$	backup/compare 'test' 'test'-'i'-clear
        +$	if $severity .ne. 1 then exit 3
        +$	delete 'test'-'i'-cipher;*,'test'-'i'-clear;*
        +$
        +$	goto loop_cipher_commands
        +$ loop_cipher_commands_end:
        +$	close f
        +$	delete 'test'-cipher-commands;*
        +$	delete 'test';*
        diff --git a/vendor/openssl/openssl/test/testfipsssl b/vendor/openssl/openssl/test/testfipsssl
        new file mode 100644
        index 000000000..c4836edc2
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testfipsssl
        @@ -0,0 +1,113 @@
        +#!/bin/sh
        +
        +if [ "$1" = "" ]; then
        +  key=../apps/server.pem
        +else
        +  key="$1"
        +fi
        +if [ "$2" = "" ]; then
        +  cert=../apps/server.pem
        +else
        +  cert="$2"
        +fi
        +
        +ciphers="DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA"
        +
        +ssltest="../util/shlib_wrap.sh ./ssltest -F -key $key -cert $cert -c_key $key -c_cert $cert -cipher $ciphers"
        +
        +if ../util/shlib_wrap.sh ../apps/openssl x509 -in $cert -text -noout | fgrep 'DSA Public Key' >/dev/null; then
        +  dsa_cert=YES
        +else
        +  dsa_cert=NO
        +fi
        +
        +if [ "$3" = "" ]; then
        +  CA="-CApath ../certs"
        +else
        +  CA="-CAfile $3"
        +fi
        +
        +if [ "$4" = "" ]; then
        +  extra=""
        +else
        +  extra="$4"
        +fi
        +
        +#############################################################################
        +
        +echo test ssl3 is forbidden in FIPS mode
        +$ssltest -ssl3 $extra && exit 1
        +
        +echo test ssl2 is forbidden in FIPS mode
        +$ssltest -ssl2 $extra && exit 1
        +
        +echo test tls1
        +$ssltest -tls1 $extra || exit 1
        +
        +echo test tls1 with server authentication
        +$ssltest -tls1 -server_auth $CA $extra || exit 1
        +
        +echo test tls1 with client authentication
        +$ssltest -tls1 -client_auth $CA $extra || exit 1
        +
        +echo test tls1 with both client and server authentication
        +$ssltest -tls1 -server_auth -client_auth $CA $extra || exit 1
        +
        +echo test tls1 via BIO pair
        +$ssltest -bio_pair -tls1 $extra || exit 1
        +
        +echo test tls1 with server authentication via BIO pair
        +$ssltest -bio_pair -tls1 -server_auth $CA $extra || exit 1
        +
        +echo test tls1 with client authentication via BIO pair
        +$ssltest -bio_pair -tls1 -client_auth $CA $extra || exit 1
        +
        +echo test tls1 with both client and server authentication via BIO pair
        +$ssltest -bio_pair -tls1 -server_auth -client_auth $CA $extra || exit 1
        +
        +# note that all the below actually choose TLS...
        +
        +if [ $dsa_cert = NO ]; then
        +  echo test sslv2/sslv3 w/o DHE via BIO pair
        +  $ssltest -bio_pair -no_dhe $extra || exit 1
        +fi
        +
        +echo test sslv2/sslv3 with 1024bit DHE via BIO pair
        +$ssltest -bio_pair -dhe1024dsa -v $extra || exit 1
        +
        +echo test sslv2/sslv3 with server authentication
        +$ssltest -bio_pair -server_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with client authentication via BIO pair
        +$ssltest -bio_pair -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with both client and server authentication via BIO pair
        +$ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify
        +$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
        +
        +#############################################################################
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
        +  echo skipping anonymous DH tests
        +else
        +  echo test tls1 with 1024bit anonymous DH, multiple handshakes
        +  $ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1
        +fi
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
        +  echo skipping RSA tests
        +else
        +  echo test tls1 with 1024bit RSA, no DHE, multiple handshakes
        +  ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -num 10 -f -time $extra || exit 1
        +
        +  if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
        +    echo skipping RSA+DHE tests
        +  else
        +    echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes
        +    ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1
        +  fi
        +fi
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/test/testgen b/vendor/openssl/openssl/test/testgen
        new file mode 100644
        index 000000000..524c0d134
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testgen
        @@ -0,0 +1,44 @@
        +#!/bin/sh
        +
        +T=testcert
        +KEY=512
        +CA=../certs/testca.pem
        +
        +/bin/rm -f $T.1 $T.2 $T.key
        +
        +if test "$OSTYPE" = msdosdjgpp; then
        +    PATH=../apps\;$PATH;
        +else
        +    PATH=../apps:$PATH;
        +fi
        +export PATH
        +
        +echo "generating certificate request"
        +
        +echo "string to make the random number generator think it has entropy" >> ./.rnd
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
        +  req_new='-newkey dsa:../apps/dsa512.pem'
        +else
        +  req_new='-new'
        +  echo "There should be a 2 sequences of .'s and some +'s."
        +  echo "There should not be more that at most 80 per line"
        +fi
        +
        +echo "This could take some time."
        +
        +rm -f testkey.pem testreq.pem
        +
        +../util/shlib_wrap.sh ../apps/openssl req -config test.cnf $req_new -out testreq.pem
        +if [ $? != 0 ]; then
        +echo problems creating request
        +exit 1
        +fi
        +
        +../util/shlib_wrap.sh ../apps/openssl req -config test.cnf -verify -in testreq.pem -noout
        +if [ $? != 0 ]; then
        +echo signature on req is wrong
        +exit 1
        +fi
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/test/testgen.com b/vendor/openssl/openssl/test/testgen.com
        new file mode 100644
        index 000000000..e076da2f3
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testgen.com
        @@ -0,0 +1,58 @@
        +$! TESTGEN.COM
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$	if (p1 .eqs. 64) then __arch = __arch+ "_64"
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	T = "testcert"
        +$	KEY = 512
        +$	CA = "[-.certs]testca.pem"
        +$
        +$	set noon
        +$	if f$search(T+".1;*") .nes. "" then delete 'T'.1;*
        +$	if f$search(T+".2;*") .nes. "" then delete 'T'.2;*
        +$	if f$search(T+".key;*") .nes. "" then delete 'T'.key;*
        +$	set on
        +$
        +$	write sys$output "generating certificate request"
        +$
        +$	append/new nl: .rnd
        +$	open/append random_file .rnd
        +$	write random_file -
        +	 "string to make the random number generator think it has entropy"
        +$	close random_file
        +$
        +$	set noon
        +$	define/user sys$output nla0:
        +$	mcr 'exe_dir'openssl no-rsa
        +$	save_severity=$SEVERITY
        +$	set on
        +$	if save_severity
        +$	then
        +$	    req_new="-newkey dsa:[-.apps]dsa512.pem"
        +$	else
        +$	    req_new="-new"
        +$	    write sys$output -
        +	     "There should be a 2 sequences of .'s and some +'s."
        +$	    write sys$output -
        +	     "There should not be more that at most 80 per line"
        +$	endif
        +$
        +$	write sys$output "This could take some time."
        +$
        +$	mcr 'exe_dir'openssl req -config test.cnf 'req_new' -out testreq.pem
        +$	if $severity .ne. 1
        +$	then
        +$	    write sys$output "problems creating request"
        +$	    exit 3
        +$	endif
        +$
        +$	mcr 'exe_dir'openssl req -config test.cnf -verify -in testreq.pem -noout
        +$	if $severity .ne. 1
        +$	then
        +$	    write sys$output "signature on req is wrong"
        +$	    exit 3
        +$	endif
        diff --git a/vendor/openssl/openssl/test/testp7.pem b/vendor/openssl/openssl/test/testp7.pem
        new file mode 100644
        index 000000000..e5b7866c3
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testp7.pem
        @@ -0,0 +1,46 @@
        +-----BEGIN PKCS7-----
        +MIIIGAYJKoZIhvcNAQcCoIIICTCCCAUCAQExADALBgkqhkiG9w0BBwGgggY8MIIE
        +cjCCBBygAwIBAgIQeS+OJfWJUZAx6cX0eAiMjzANBgkqhkiG9w0BAQQFADBiMREw
        +DwYDVQQHEwhJbnRlcm5ldDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNDAyBgNV
        +BAsTK1ZlcmlTaWduIENsYXNzIDEgQ0EgLSBJbmRpdmlkdWFsIFN1YnNjcmliZXIw
        +HhcNOTYwNzE5MDAwMDAwWhcNOTcwMzMwMjM1OTU5WjCB1TERMA8GA1UEBxMISW50
        +ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJpU2ln
        +biBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMSgwJgYDVQQLEx9E
        +aWdpdGFsIElEIENsYXNzIDEgLSBTTUlNRSBUZXN0MUcwRQYDVQQLEz53d3cudmVy
        +aXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMCBJbmMuIGJ5IFJlZi4sTElBQi5M
        +VEQoYyk5NjBbMA0GCSqGSIb3DQEBAQUAA0oAMEcCQA7LvHEIAiQ5+4gDYvJGnGAq
        +UM5GXyG11diEXmIEZTHUZhorooX5sr8IIjSXiPY59YYUFSvAaharFM1xaBN8zNEC
        +AwEAAaOCAjkwggI1MAkGA1UdEwQCMAAwggImBgNVHQMEggIdMIICGTCCAhUwggIR
        +BgtghkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0
        +ZXMgYnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0
        +IHRvLCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1l
        +bnQgKENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29t
        +L0NQUy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29t
        +OyBvciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4s
        +IE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04
        +ODMwIENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0
        +cyBSZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJ
        +QUJJTElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQEC
        +MC8wLRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEu
        +AzANBgkqhkiG9w0BAQQFAANBAMCYDuSb/eIlYSxY31nZZTaCZkCSfHjlacMofExr
        +cF+A2yHoEuT+eCQkqM0pMNHXddUeoQ9RjV+VuMBNmm63DUYwggHCMIIBbKADAgEC
        +AhB8CYTq1bkRFJBYOd67cp9JMA0GCSqGSIb3DQEBAgUAMD4xCzAJBgNVBAYTAlVT
        +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEWMBQGA1UECxMNVEVTVCBSb290IFBD
        +QTAeFw05NjA3MTcwMDAwMDBaFw05NzA3MTcyMzU5NTlaMGIxETAPBgNVBAcTCElu
        +dGVybmV0MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNp
        +Z24gQ2xhc3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjBcMA0GCSqGSIb3
        +DQEBAQUAA0sAMEgCQQDsVzrNgnDhbAJZrWeLd9g1vMZJA2W67D33TTbga6yMt+ES
        +TWEywhS6RNP+fzLGg7utinjH4tL60cXa0G27GDsLAgMBAAGjIjAgMAsGA1UdDwQE
        +AwIBBjARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcNAQECBQADQQAUp6bRwkaD
        +2d1MBs/mjUcgTI2fXVmW8tTm/Ud6OzUwpC3vYgybiOOA4f6mOC5dbyUHrLOsrihU
        +47ZQ0Jo1DUfboYIBrTCBwTBtMA0GCSqGSIb3DQEBAgUAMD4xCzAJBgNVBAYTAlVT
        +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEWMBQGA1UECxMNVEVTVCBSb290IFBD
        +QRcNOTYwNzE3MTc0NDA5WhcNOTgwNzE3MDAwMDAwWjANBgkqhkiG9w0BAQIFAANB
        +AHitA0/xAukCjHzeh1AMT/l2oC68N+yFb+aJPHBBMxc6gG2MaKjBNwb5hcXUllMl
        +ExONA3ju10f7owIq3s3wx10wgeYwgZEwDQYJKoZIhvcNAQECBQAwYjERMA8GA1UE
        +BxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytW
        +ZXJpU2lnbiBDbGFzcyAxIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyFw05NjA3
        +MTcxNzU5MjlaFw05NzA3MTgwMDAwMDBaMA0GCSqGSIb3DQEBAgUAA0EAubVWYTsW
        +sQmste9f+UgMw8BkjDlM25fwQLrCfmmnLxjewey10kSROypUaJLb+r4oRALc0fG9
        +XfZsaiiIgotQHjEA
        +-----END PKCS7-----
        diff --git a/vendor/openssl/openssl/test/testreq2.pem b/vendor/openssl/openssl/test/testreq2.pem
        new file mode 100644
        index 000000000..c3cdcffcb
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testreq2.pem
        @@ -0,0 +1,7 @@
        +-----BEGIN CERTIFICATE REQUEST-----
        +MIHaMIGFAgEAMA4xDDAKBgNVBAMTA2NuNDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
        +QQCQsnkyUGDY2R3mYoeTprFJKgWuJ3f1jUjlIuW5+wfAUoeMt35c4vcFZ2mIBpEG
        +DtzkNQN1kr2O9ldm9zYnYhyhAgMBAAGgEjAQBgorBgEEAYI3AgEOMQIwADANBgkq
        +hkiG9w0BAQQFAANBAAb2szZgVIxg3vK6kYLjGSBISyuzcXJ6IvuPW6M+yzi1Qgoi
        +gQhazHTJp91T8ItZEzUJGZSZl2e5iXlnffWB+/U=
        +-----END CERTIFICATE REQUEST-----
        diff --git a/vendor/openssl/openssl/test/testrsa.pem b/vendor/openssl/openssl/test/testrsa.pem
        new file mode 100644
        index 000000000..aad21067a
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testrsa.pem
        @@ -0,0 +1,9 @@
        +-----BEGIN RSA PRIVATE KEY-----
        +MIIBPAIBAAJBAKrbeqkuRk8VcRmWFmtP+LviMB3+6dizWW3DwaffznyHGAFwUJ/I
        +Tv0XtbsCyl3QoyKGhrOAy3RvPK5M38iuXT0CAwEAAQJAZ3cnzaHXM/bxGaR5CR1R
        +rD1qFBAVfoQFiOH9uPJgMaoAuoQEisPHVcZDKcOv4wEg6/TInAIXBnEigtqvRzuy
        +oQIhAPcgZzUq3yVooAaoov8UbXPxqHlwo6GBMqnv20xzkf6ZAiEAsP4BnIaQTM8S
        +mvcpHZwQJdmdHHkGKAs37Dfxi67HbkUCIQCeZGliHXFa071Fp06ZeWlR2ADonTZz
        +rJBhdTe0v5pCeQIhAIZfkiGgGBX4cIuuckzEm43g9WMUjxP/0GlK39vIyihxAiEA
        +mymehFRT0MvqW5xAKAx7Pgkt8HVKwVhc2LwGKHE0DZM=
        +-----END RSA PRIVATE KEY-----
        diff --git a/vendor/openssl/openssl/test/tests.com b/vendor/openssl/openssl/test/tests.com
        new file mode 100644
        index 000000000..a840d5078
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tests.com
        @@ -0,0 +1,375 @@
        +$! TESTS.COM  --  Performs the necessary tests
        +$!
        +$! P1	tests to be performed.  Empty means all.
        +$! P2	Pointer size: "", "32", or "64".
        +$!
        +$! Announce/identify.
        +$!
        +$	proc = f$environment( "procedure")
        +$	write sys$output "@@@ "+ -
        +	 f$parse( proc, , , "name")+ f$parse( proc, , , "type")
        +$!
        +$	__proc = f$element(0,";",f$environment("procedure"))
        +$	__here = f$parse(f$parse("A.;",__proc) - "A.;","[]A.;") - "A.;"
        +$	__save_default = f$environment("default")
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	__archd = __arch
        +$       pointer_size = ""
        +$	if (p2 .eq. "64")
        +$	then
        +$	  pointer_size = "64"
        +$	  __archd = __arch+ "_64"
        +$	endif
        +$!
        +$	texe_dir := sys$disk:[-.'__archd'.exe.test]
        +$	exe_dir := sys$disk:[-.'__archd'.exe.apps]
        +$
        +$	set default '__here'
        +$
        +$       ROOT = F$PARSE("sys$disk:[-]A.;0",,,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
        +$       ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
        +$       ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
        +                   - ".][000000" - "[000000." - "][" - "[" - "]"
        +$       ROOT = ROOT_DEV + "[" + ROOT_DIR
        +$       DEFINE/NOLOG SSLROOT 'ROOT'.APPS.] /TRANS=CONC
        +$	openssl_conf := sslroot:[000000]openssl-vms.cnf
        +$
        +$	on control_y then goto exit
        +$	on error then goto exit
        +$
        +$	if p1 .nes. ""
        +$	then
        +$	    tests = p1
        +$	else
        +$! NOTE: This list reflects the list of dependencies following the
        +$! "alltests" target in Makefile.  This should make it easy to see
        +$! if there's a difference that needs to be taken care of.
        +$	    tests := -
        +	test_des,test_idea,test_sha,test_md4,test_md5,test_hmac,-
        +	test_md2,test_mdc2,test_wp,-
        +	test_rmd,test_rc2,test_rc4,test_rc5,test_bf,test_cast,test_aes,-
        +	test_rand,test_bn,test_ec,test_ecdsa,test_ecdh,-
        +	test_enc,test_x509,test_rsa,test_crl,test_sid,-
        +	test_gen,test_req,test_pkcs7,test_verify,test_dh,test_dsa,-
        +	test_ss,test_ca,test_engine,test_evp,test_ssl,test_tsa,test_ige,-
        +	test_jpake,test_srp,test_cms
        +$	endif
        +$	tests = f$edit(tests,"COLLAPSE")
        +$
        +$	BNTEST :=	bntest
        +$	ECTEST :=	ectest
        +$	ECDSATEST :=	ecdsatest
        +$	ECDHTEST :=	ecdhtest
        +$	EXPTEST :=	exptest
        +$	IDEATEST :=	ideatest
        +$	SHATEST :=	shatest
        +$	SHA1TEST :=	sha1test
        +$	SHA256TEST :=	sha256t
        +$	SHA512TEST :=	sha512t
        +$	MDC2TEST :=	mdc2test
        +$	RMDTEST :=	rmdtest
        +$	MD2TEST :=	md2test
        +$	MD4TEST :=	md4test
        +$	MD5TEST :=	md5test
        +$	HMACTEST :=	hmactest
        +$	WPTEST :=	wp_test
        +$	RC2TEST :=	rc2test
        +$	RC4TEST :=	rc4test
        +$	RC5TEST :=	rc5test
        +$	BFTEST :=	bftest
        +$	CASTTEST :=	casttest
        +$	DESTEST :=	destest
        +$	RANDTEST :=	randtest
        +$	DHTEST :=	dhtest
        +$	DSATEST :=	dsatest
        +$	METHTEST :=	methtest
        +$	SSLTEST :=	ssltest
        +$	RSATEST :=	rsa_test
        +$	ENGINETEST :=	enginetest
        +$	EVPTEST :=	evp_test
        +$	IGETEST :=	igetest
        +$	JPAKETEST :=	jpaketest
        +$	SRPTEST :=	srptest
        +$	ASN1TEST :=	asn1test
        +$!
        +$	tests_i = 0
        +$ loop_tests:
        +$	tests_e = f$element(tests_i,",",tests)
        +$	tests_i = tests_i + 1
        +$	if tests_e .eqs. "," then goto exit
        +$	write sys$output "---> ''tests_e'"
        +$	gosub 'tests_e'
        +$	goto loop_tests
        +$
        +$ test_evp:
        +$	mcr 'texe_dir''evptest' 'ROOT'.CRYPTO.EVP]evptests.txt
        +$	return
        +$ test_des:
        +$	mcr 'texe_dir''destest'
        +$	return
        +$ test_idea:
        +$	mcr 'texe_dir''ideatest'
        +$	return
        +$ test_sha:
        +$	mcr 'texe_dir''shatest'
        +$	mcr 'texe_dir''sha1test'
        +$	mcr 'texe_dir''sha256test'
        +$	mcr 'texe_dir''sha512test'
        +$	return
        +$ test_mdc2:
        +$	mcr 'texe_dir''mdc2test'
        +$	return
        +$ test_md5:
        +$	mcr 'texe_dir''md5test'
        +$	return
        +$ test_md4:
        +$	mcr 'texe_dir''md4test'
        +$	return
        +$ test_hmac:
        +$	mcr 'texe_dir''hmactest'
        +$	return
        +$ test_wp:
        +$	mcr 'texe_dir''wptest'
        +$	return
        +$ test_md2:
        +$	mcr 'texe_dir''md2test'
        +$	return
        +$ test_rmd:
        +$	mcr 'texe_dir''rmdtest'
        +$	return
        +$ test_bf:
        +$	mcr 'texe_dir''bftest'
        +$	return
        +$ test_cast:
        +$	mcr 'texe_dir''casttest'
        +$	return
        +$ test_rc2:
        +$	mcr 'texe_dir''rc2test'
        +$	return
        +$ test_rc4:
        +$	mcr 'texe_dir''rc4test'
        +$	return
        +$ test_rc5:
        +$	mcr 'texe_dir''rc5test'
        +$	return
        +$ test_rand:
        +$	mcr 'texe_dir''randtest'
        +$	return
        +$ test_enc:
        +$	@testenc.com 'pointer_size'
        +$	return
        +$ test_x509:
        +$	set noon
        +$	define sys$error test_x509.err
        +$	write sys$output "test normal x509v1 certificate"
        +$	@tx509.com "" 'pointer_size'
        +$	write sys$output "test first x509v3 certificate"
        +$	@tx509.com v3-cert1.pem 'pointer_size'
        +$	write sys$output "test second x509v3 certificate"
        +$	@tx509.com v3-cert2.pem 'pointer_size'
        +$	deassign sys$error
        +$	set on
        +$	return
        +$ test_rsa:
        +$	set noon
        +$	define sys$error test_rsa.err
        +$	@trsa.com "" 'pointer_size'
        +$	deassign sys$error
        +$	mcr 'texe_dir''rsatest'
        +$	set on
        +$	return
        +$ test_crl:
        +$	set noon
        +$	define sys$error test_crl.err
        +$	@tcrl.com "" 'pointer_size'
        +$	deassign sys$error
        +$	set on
        +$	return
        +$ test_sid:
        +$	set noon
        +$	define sys$error test_sid.err
        +$	@tsid.com "" 'pointer_size'
        +$	deassign sys$error
        +$	set on
        +$	return
        +$ test_req:
        +$	set noon
        +$	define sys$error test_req.err
        +$	@treq.com "" 'pointer_size'
        +$	@treq.com testreq2.pem 'pointer_size'
        +$	deassign sys$error
        +$	set on
        +$	return
        +$ test_pkcs7:
        +$	set noon
        +$	define sys$error test_pkcs7.err
        +$	@tpkcs7.com "" 'pointer_size'
        +$	@tpkcs7d.com "" 'pointer_size'
        +$	deassign sys$error
        +$	set on
        +$	return
        +$ test_bn:
        +$	write sys$output -
        +	      "starting big number library test, could take a while..."
        +$	set noon
        +$	define sys$error test_bn.err
        +$	define sys$output test_bn.out
        +$	@ bctest.com
        +$	status = $status
        +$	deassign sys$error
        +$	deassign sys$output
        +$	set on
        +$	if (status)
        +$	then
        +$	    create /fdl = sys$input bntest-vms.tmp
        +FILE
        +	ORGANIZATION	sequential
        +RECORD
        +	FORMAT		stream_lf
        +$	    define /user_mode sys$output bntest-vms.tmp
        +$	    mcr 'texe_dir''bntest'
        +$	    define /user_mode sys$input bntest-vms.tmp
        +$	    define /user_mode sys$output bntest-vms.out
        +$	    bc
        +$	    @ bntest.com bntest-vms.out
        +$	    status = $status
        +$	    if (status)
        +$	    then
        +$		delete bntest-vms.out;*
        +$		delete bntest-vms.tmp;*
        +$	    endif
        +$	else
        +$	    create /fdl = sys$input bntest-vms.sh
        +FILE
        +	ORGANIZATION	sequential
        +RECORD
        +	FORMAT		stream_lf
        +$	    open /append bntest_file bntest-vms.sh
        +$	    type /output = bntest_file sys$input:
        +<< __FOO__ sh -c "`sh ./bctest`" | perl -e '$i=0; while (<STDIN>) {if (/^test (.*)/) {print STDERR "\nverify $1";} elsif (!/^0$/) {die "\nFailed! bc: $_";} else {print STDERR "."; $i++;}} print STDERR "\n$i tests passed\n"'
        +$	    define /user_mode sys$output bntest-vms.tmp
        +$	    mcr 'texe_dir''bntest'
        +$	    copy bntest-vms.tmp bntest_file
        +$	    delete bntest-vms.tmp;*
        +$	    type /output = bntest_file sys$input:
        +__FOO__
        +$	    close bntest_file
        +$	    write sys$output "-- copy the [.test]bntest-vms.sh and [.test]bctest files to a Unix system and"
        +$	    write sys$output "-- run bntest-vms.sh through sh or bash to verify that the bignum operations"
        +$	    write sys$output "-- went well."
        +$	    write sys$output ""
        +$	endif
        +$	write sys$output "test a^b%c implementations"
        +$	mcr 'texe_dir''exptest'
        +$	return
        +$ test_ec:
        +$	write sys$output "test elliptic curves"
        +$	mcr 'texe_dir''ectest'
        +$	return
        +$ test_ecdsa:
        +$	write sys$output "test ecdsa"
        +$	mcr 'texe_dir''ecdsatest'
        +$	return
        +$ test_ecdh:
        +$	write sys$output "test ecdh"
        +$	mcr 'texe_dir''ecdhtest'
        +$	return
        +$ test_verify:
        +$	write sys$output "The following command should have some OK's and some failures"
        +$	write sys$output "There are definitly a few expired certificates"
        +$	@tverify.com 'pointer_size'
        +$	return
        +$ test_dh:
        +$	write sys$output "Generate a set of DH parameters"
        +$	mcr 'texe_dir''dhtest'
        +$	return
        +$ test_dsa:
        +$	write sys$output "Generate a set of DSA parameters"
        +$	mcr 'texe_dir''dsatest'
        +$	return
        +$ test_gen:
        +$	write sys$output "Generate and verify a certificate request"
        +$	@testgen.com 'pointer_size'
        +$	return
        +$ maybe_test_ss:
        +$	testss_RDT = f$cvtime(f$file_attributes("testss.com","RDT"))
        +$	if f$cvtime(f$file_attributes("keyU.ss","RDT")) .les. testss_RDT then -
        +		goto test_ss
        +$	if f$cvtime(f$file_attributes("certU.ss","RDT")) .les. testss_RDT then -
        +		goto test_ss
        +$	if f$cvtime(f$file_attributes("certCA.ss","RDT")) .les. testss_RDT then -
        +		goto test_ss
        +$	return
        +$ test_ss:
        +$	write sys$output "Generate and certify a test certificate"
        +$	@testss.com 'pointer_size'
        +$	return
        +$ test_engine: 
        +$	write sys$output "Manipulate the ENGINE structures"
        +$	mcr 'texe_dir''enginetest'
        +$	return
        +$ test_ssl:
        +$	write sys$output "test SSL protocol"
        +$	gosub maybe_test_ss
        +$	@testssl.com keyU.ss certU.ss certCA.ss 'pointer_size'
        +$	return
        +$ test_ca:
        +$	set noon
        +$	define /user_mode sys$output test_ca.out
        +$	mcr 'exe_dir'openssl no-rsa
        +$	save_severity=$SEVERITY
        +$	set on
        +$	if save_severity
        +$	then
        +$	    write sys$output "skipping CA.com test -- requires RSA"
        +$	else
        +$	    write sys$output "Generate and certify a test certificate via the 'ca' program"
        +$	    @testca.com 'pointer_size'
        +$	endif
        +$	return
        +$ test_aes: 
        +$!	write sys$output "test AES"
        +$!	!mcr 'texe_dir''aestest'
        +$	return
        +$ test_tsa:
        +$	set noon
        +$	define /user_mode sys$output nla0:
        +$	mcr 'exe_dir'openssl no-rsa
        +$	save_severity=$SEVERITY
        +$	set on
        +$	if save_severity
        +$	then
        +$	    write sys$output "skipping testtsa.com test -- requires RSA"
        +$	else
        +$	    @testtsa.com "" "" "" 'pointer_size'
        +$	endif
        +$	return
        +$ test_ige: 
        +$	write sys$output "Test IGE mode"
        +$	mcr 'texe_dir''igetest'
        +$	return
        +$ test_jpake: 
        +$	write sys$output "Test JPAKE"
        +$	mcr 'texe_dir''jpaketest'
        +$	return
        +$ test_cms:
        +$	write sys$output "CMS consistency test"
        +$	! Define the logical name used to find openssl.exe in the perl script.
        +$	define /user_mode osslx 'exe_dir'
        +$	perl CMS-TEST.PL
        +$	return
        +$ test_srp: 
        +$	write sys$output "Test SRP"
        +$	mcr 'texe_dir''srptest'
        +$	return
        +$
        +$
        +$ exit:
        +$	mcr 'exe_dir'openssl version -a
        +$	set default '__save_default'
        +$	deassign sslroot
        +$	exit
        diff --git a/vendor/openssl/openssl/test/testsid.pem b/vendor/openssl/openssl/test/testsid.pem
        new file mode 100644
        index 000000000..7ffd008f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testsid.pem
        @@ -0,0 +1,12 @@
        +-----BEGIN SSL SESSION PARAMETERS-----
        +MIIB1gIBAQIBAgQDAQCABBCi11xa5qkOP8xrr02K/NQCBBBkIYQZM0Bt95W0EHNV
        +bA58oQYCBDIBr7WiBAICASyjggGGMIIBgjCCASwCAQMwDQYJKoZIhvcNAQEEBQAw
        +ODELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3Jz
        +YSB0ZXN0IENBMB4XDTk1MTAwOTIzMzEzNFoXDTk4MDcwNTIzMzEzNFowYDELMAkG
        +A1UEBhMCQVUxDDAKBgNVBAgTA1FMRDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRk
        +LjELMAkGA1UECxMCQ1MxGzAZBgNVBAMTElNTTGVheSBkZW1vIGNsaWVudDBcMA0G
        +CSqGSIb3DQEBAQUAA0sAMEgCQQC4pcXEL1lgVA+B5Q3TcuW/O3LZHoA73IYm8oFD
        +TezgCDhL2RTMn+seKWF36UtJKRIOBU9jZHCVVd0Me5ls6BEjAgMBAAEwDQYJKoZI
        +hvcNAQEEBQADQQBoIpOcwUY1qlVF7j3ROSGvUsbvByOBFmYWkIBgsCqR+9qo1A7L
        +CrWF5i8LWt/vLwAHaxWNx2YuBJMFyuK81fTvpA0EC3Rlc3Rjb250ZXh0
        +-----END SSL SESSION PARAMETERS-----
        diff --git a/vendor/openssl/openssl/test/testss b/vendor/openssl/openssl/test/testss
        new file mode 100644
        index 000000000..1a426857d
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testss
        @@ -0,0 +1,163 @@
        +#!/bin/sh
        +
        +digest='-sha1'
        +reqcmd="../util/shlib_wrap.sh ../apps/openssl req"
        +x509cmd="../util/shlib_wrap.sh ../apps/openssl x509 $digest"
        +verifycmd="../util/shlib_wrap.sh ../apps/openssl verify"
        +dummycnf="../apps/openssl.cnf"
        +
        +CAkey="keyCA.ss"
        +CAcert="certCA.ss"
        +CAreq="reqCA.ss"
        +CAconf="CAss.cnf"
        +CAreq2="req2CA.ss"	# temp
        +
        +Uconf="Uss.cnf"
        +Ukey="keyU.ss"
        +Ureq="reqU.ss"
        +Ucert="certU.ss"
        +
        +P1conf="P1ss.cnf"
        +P1key="keyP1.ss"
        +P1req="reqP1.ss"
        +P1cert="certP1.ss"
        +P1intermediate="tmp_intP1.ss"
        +
        +P2conf="P2ss.cnf"
        +P2key="keyP2.ss"
        +P2req="reqP2.ss"
        +P2cert="certP2.ss"
        +P2intermediate="tmp_intP2.ss"
        +
        +echo
        +echo "make a certificate request using 'req'"
        +
        +echo "string to make the random number generator think it has entropy" >> ./.rnd
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
        +  req_new='-newkey dsa:../apps/dsa512.pem'
        +else
        +  req_new='-new'
        +fi
        +
        +$reqcmd -config $CAconf -out $CAreq -keyout $CAkey $req_new #>err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'req' to generate a certificate request"
        +	exit 1
        +fi
        +echo
        +echo "convert the certificate request into a self signed certificate using 'x509'"
        +$x509cmd -CAcreateserial -in $CAreq -days 30 -req -out $CAcert -signkey $CAkey -extfile $CAconf -extensions v3_ca >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'x509' to self sign a certificate request"
        +	exit 1
        +fi
        +
        +echo
        +echo "convert a certificate into a certificate request using 'x509'"
        +$x509cmd -in $CAcert -x509toreq -signkey $CAkey -out $CAreq2 >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'x509' convert a certificate to a certificate request"
        +	exit 1
        +fi
        +
        +$reqcmd -config $dummycnf -verify -in $CAreq -noout
        +if [ $? != 0 ]; then
        +	echo first generated request is invalid
        +	exit 1
        +fi
        +
        +$reqcmd -config $dummycnf -verify -in $CAreq2 -noout
        +if [ $? != 0 ]; then
        +	echo second generated request is invalid
        +	exit 1
        +fi
        +
        +$verifycmd -CAfile $CAcert $CAcert
        +if [ $? != 0 ]; then
        +	echo first generated cert is invalid
        +	exit 1
        +fi
        +
        +echo
        +echo "make a user certificate request using 'req'"
        +$reqcmd -config $Uconf -out $Ureq -keyout $Ukey $req_new >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'req' to generate a user certificate request"
        +	exit 1
        +fi
        +
        +echo
        +echo "sign user certificate request with the just created CA via 'x509'"
        +$x509cmd -CAcreateserial -in $Ureq -days 30 -req -out $Ucert -CA $CAcert -CAkey $CAkey -extfile $Uconf -extensions v3_ee >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'x509' to sign a user certificate request"
        +	exit 1
        +fi
        +
        +$verifycmd -CAfile $CAcert $Ucert
        +echo
        +echo "Certificate details"
        +$x509cmd -subject -issuer -startdate -enddate -noout -in $Ucert
        +
        +echo
        +echo "make a proxy certificate request using 'req'"
        +$reqcmd -config $P1conf -out $P1req -keyout $P1key $req_new >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'req' to generate a proxy certificate request"
        +	exit 1
        +fi
        +
        +echo
        +echo "sign proxy certificate request with the just created user certificate via 'x509'"
        +$x509cmd -CAcreateserial -in $P1req -days 30 -req -out $P1cert -CA $Ucert -CAkey $Ukey -extfile $P1conf -extensions v3_proxy >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'x509' to sign a proxy certificate request"
        +	exit 1
        +fi
        +
        +cat $Ucert > $P1intermediate
        +$verifycmd -CAfile $CAcert -untrusted $P1intermediate $P1cert
        +echo
        +echo "Certificate details"
        +$x509cmd -subject -issuer -startdate -enddate -noout -in $P1cert
        +
        +echo
        +echo "make another proxy certificate request using 'req'"
        +$reqcmd -config $P2conf -out $P2req -keyout $P2key $req_new >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'req' to generate another proxy certificate request"
        +	exit 1
        +fi
        +
        +echo
        +echo "sign second proxy certificate request with the first proxy certificate via 'x509'"
        +$x509cmd -CAcreateserial -in $P2req -days 30 -req -out $P2cert -CA $P1cert -CAkey $P1key -extfile $P2conf -extensions v3_proxy >err.ss
        +if [ $? != 0 ]; then
        +	echo "error using 'x509' to sign a second proxy certificate request"
        +	exit 1
        +fi
        +
        +cat $Ucert $P1cert > $P2intermediate
        +$verifycmd -CAfile $CAcert -untrusted $P2intermediate $P2cert
        +echo
        +echo "Certificate details"
        +$x509cmd -subject -issuer -startdate -enddate -noout -in $P2cert
        +
        +echo
        +echo The generated CA certificate is $CAcert
        +echo The generated CA private key is $CAkey
        +
        +echo The generated user certificate is $Ucert
        +echo The generated user private key is $Ukey
        +
        +echo The first generated proxy certificate is $P1cert
        +echo The first generated proxy private key is $P1key
        +
        +echo The second generated proxy certificate is $P2cert
        +echo The second generated proxy private key is $P2key
        +
        +/bin/rm err.ss
        +#/bin/rm $P1intermediate
        +#/bin/rm $P2intermediate
        +exit 0
        diff --git a/vendor/openssl/openssl/test/testss.com b/vendor/openssl/openssl/test/testss.com
        new file mode 100644
        index 000000000..32a74d0fc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testss.com
        @@ -0,0 +1,123 @@
        +$! TESTSS.COM
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p1 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	digest="-md5"
        +$	reqcmd = "mcr ''exe_dir'openssl req"
        +$	x509cmd = "mcr ''exe_dir'openssl x509 ''digest'"
        +$	verifycmd = "mcr ''exe_dir'openssl verify"
        +$	dummycnf = "sys$disk:[-.apps]openssl-vms.cnf"
        +$
        +$	CAkey="""keyCA.ss"""
        +$	CAcert="""certCA.ss"""
        +$	CAreq="""reqCA.ss"""
        +$	CAconf="""CAss.cnf"""
        +$	CAreq2="""req2CA.ss"""	! temp
        +$
        +$	Uconf="""Uss.cnf"""
        +$	Ukey="""keyU.ss"""
        +$	Ureq="""reqU.ss"""
        +$	Ucert="""certU.ss"""
        +$
        +$	write sys$output ""
        +$	write sys$output "make a certificate request using 'req'"
        +$
        +$	set noon
        +$	define/user sys$output nla0:
        +$	mcr 'exe_dir'openssl no-rsa
        +$	save_severity=$SEVERITY
        +$	set on
        +$	if save_severity
        +$	then
        +$	    req_new="-newkey dsa:[-.apps]dsa512.pem"
        +$	else
        +$	    req_new="-new"
        +$	endif
        +$
        +$	'reqcmd' -config 'CAconf' -out 'CAreq' -keyout 'CAkey' 'req_new' ! -out err.ss
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "error using 'req' to generate a certificate request"
        +$		exit 3
        +$	endif
        +$	write sys$output ""
        +$	write sys$output "convert the certificate request into a self signed certificate using 'x509'"
        +$	define /user sys$output err.ss
        +$	'x509cmd' "-CAcreateserial" -in 'CAreq' -days 30 -req -out 'CAcert' -signkey 'CAkey'
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "error using 'x509' to self sign a certificate request"
        +$		exit 3
        +$	endif
        +$
        +$	write sys$output ""
        +$	write sys$output "convert a certificate into a certificate request using 'x509'"
        +$	define /user sys$output err.ss
        +$	'x509cmd' -in 'CAcert' -x509toreq -signkey 'CAkey' -out 'CAreq2'
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "error using 'x509' convert a certificate to a certificate request"
        +$		exit 3
        +$	endif
        +$
        +$	'reqcmd' -config 'dummycnf' -verify -in 'CAreq' -noout
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "first generated request is invalid"
        +$		exit 3
        +$	endif
        +$
        +$	'reqcmd' -config 'dummycnf' -verify -in 'CAreq2' -noout
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "second generated request is invalid"
        +$		exit 3
        +$	endif
        +$
        +$	'verifycmd' "-CAfile" 'CAcert' 'CAcert'
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "first generated cert is invalid"
        +$		exit 3
        +$	endif
        +$
        +$	write sys$output ""
        +$	write sys$output "make another certificate request using 'req'"
        +$	define /user sys$output err.ss
        +$	'reqcmd' -config 'Uconf' -out 'Ureq' -keyout 'Ukey' 'req_new'
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "error using 'req' to generate a certificate request"
        +$		exit 3
        +$	endif
        +$
        +$	write sys$output ""
        +$	write sys$output "sign certificate request with the just created CA via 'x509'"
        +$	define /user sys$output err.ss
        +$	'x509cmd' "-CAcreateserial" -in 'Ureq' -days 30 -req -out 'Ucert' "-CA" 'CAcert' "-CAkey" 'CAkey'
        +$	if $severity .ne. 1
        +$	then
        +$		write sys$output "error using 'x509' to sign a certificate request"
        +$		exit 3
        +$	endif
        +$
        +$	'verifycmd' "-CAfile" 'CAcert' 'Ucert'
        +$	write sys$output ""
        +$	write sys$output "Certificate details"
        +$	'x509cmd' -subject -issuer -startdate -enddate -noout -in 'Ucert'
        +$
        +$	write sys$output ""
        +$	write sys$output "The generated CA certificate is ",CAcert
        +$	write sys$output "The generated CA private key is ",CAkey
        +$
        +$	write sys$output "The generated user certificate is ",Ucert
        +$	write sys$output "The generated user private key is ",Ukey
        +$
        +$	if f$search("err.ss;*") .nes. "" then delete err.ss;*
        diff --git a/vendor/openssl/openssl/test/testssl b/vendor/openssl/openssl/test/testssl
        new file mode 100644
        index 000000000..4e8542b55
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testssl
        @@ -0,0 +1,178 @@
        +#!/bin/sh
        +
        +if [ "$1" = "" ]; then
        +  key=../apps/server.pem
        +else
        +  key="$1"
        +fi
        +if [ "$2" = "" ]; then
        +  cert=../apps/server.pem
        +else
        +  cert="$2"
        +fi
        +ssltest="../util/shlib_wrap.sh ./ssltest -key $key -cert $cert -c_key $key -c_cert $cert"
        +
        +if ../util/shlib_wrap.sh ../apps/openssl x509 -in $cert -text -noout | fgrep 'DSA Public Key' >/dev/null; then
        +  dsa_cert=YES
        +else
        +  dsa_cert=NO
        +fi
        +
        +if [ "$3" = "" ]; then
        +  CA="-CApath ../certs"
        +else
        +  CA="-CAfile $3"
        +fi
        +
        +if [ "$4" = "" ]; then
        +  extra=""
        +else
        +  extra="$4"
        +fi
        +
        +#############################################################################
        +
        +echo test sslv2
        +$ssltest -ssl2 $extra || exit 1
        +
        +echo test sslv2 with server authentication
        +$ssltest -ssl2 -server_auth $CA $extra || exit 1
        +
        +if [ $dsa_cert = NO ]; then
        +  echo test sslv2 with client authentication
        +  $ssltest -ssl2 -client_auth $CA $extra || exit 1
        +
        +  echo test sslv2 with both client and server authentication
        +  $ssltest -ssl2 -server_auth -client_auth $CA $extra || exit 1
        +fi
        +
        +echo test sslv3
        +$ssltest -ssl3 $extra || exit 1
        +
        +echo test sslv3 with server authentication
        +$ssltest -ssl3 -server_auth $CA $extra || exit 1
        +
        +echo test sslv3 with client authentication
        +$ssltest -ssl3 -client_auth $CA $extra || exit 1
        +
        +echo test sslv3 with both client and server authentication
        +$ssltest -ssl3 -server_auth -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3
        +$ssltest $extra || exit 1
        +
        +echo test sslv2/sslv3 with server authentication
        +$ssltest -server_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with client authentication
        +$ssltest -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with both client and server authentication
        +$ssltest -server_auth -client_auth $CA $extra || exit 1
        +
        +echo test sslv2 via BIO pair
        +$ssltest -bio_pair -ssl2 $extra || exit 1
        +
        +echo test sslv2 with server authentication via BIO pair
        +$ssltest -bio_pair -ssl2 -server_auth $CA $extra || exit 1
        +
        +if [ $dsa_cert = NO ]; then
        +  echo test sslv2 with client authentication via BIO pair
        +  $ssltest -bio_pair -ssl2 -client_auth $CA $extra || exit 1
        +
        +  echo test sslv2 with both client and server authentication via BIO pair
        +  $ssltest -bio_pair -ssl2 -server_auth -client_auth $CA $extra || exit 1
        +fi
        +
        +echo test sslv3 via BIO pair
        +$ssltest -bio_pair -ssl3 $extra || exit 1
        +
        +echo test sslv3 with server authentication via BIO pair
        +$ssltest -bio_pair -ssl3 -server_auth $CA $extra || exit 1
        +
        +echo test sslv3 with client authentication via BIO pair
        +$ssltest -bio_pair -ssl3 -client_auth $CA $extra || exit 1
        +
        +echo test sslv3 with both client and server authentication via BIO pair
        +$ssltest -bio_pair -ssl3 -server_auth -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 via BIO pair
        +$ssltest $extra || exit 1
        +
        +if [ $dsa_cert = NO ]; then
        +  echo 'test sslv2/sslv3 w/o (EC)DHE via BIO pair'
        +  $ssltest -bio_pair -no_dhe -no_ecdhe $extra || exit 1
        +fi
        +
        +echo test sslv2/sslv3 with 1024bit DHE via BIO pair
        +$ssltest -bio_pair -dhe1024dsa -v $extra || exit 1
        +
        +echo test sslv2/sslv3 with server authentication
        +$ssltest -bio_pair -server_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with client authentication via BIO pair
        +$ssltest -bio_pair -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with both client and server authentication via BIO pair
        +$ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
        +
        +echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify
        +$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
        +
        +echo "Testing ciphersuites"
        +for protocol in TLSv1.2 SSLv3; do
        +  echo "Testing ciphersuites for $protocol"
        +  for cipher in `../util/shlib_wrap.sh ../apps/openssl ciphers "RSA+$protocol" | tr ':' ' '`; do
        +    echo "Testing $cipher"
        +    prot=""
        +    if [ $protocol = "SSLv3" ] ; then
        +      prot="-ssl3"
        +    fi
        +    $ssltest -cipher $cipher $prot
        +    if [ $? -ne 0 ] ; then
        +	  echo "Failed $cipher"
        +	  exit 1
        +    fi
        +  done
        +done
        +
        +#############################################################################
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
        +  echo skipping anonymous DH tests
        +else
        +  echo test tls1 with 1024bit anonymous DH, multiple handshakes
        +  $ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1
        +fi
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
        +  echo skipping RSA tests
        +else
        +  echo 'test tls1 with 1024bit RSA, no (EC)DHE, multiple handshakes'
        +  ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -no_ecdhe -num 10 -f -time $extra || exit 1
        +
        +  if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
        +    echo skipping RSA+DHE tests
        +  else
        +    echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes
        +    ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1
        +  fi
        +fi
        +
        +echo test tls1 with PSK
        +$ssltest -tls1 -cipher PSK -psk abc123 $extra || exit 1
        +
        +echo test tls1 with PSK via BIO pair
        +$ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-srp; then
        +  echo skipping SRP tests
        +else
        +  echo test tls1 with SRP
        +  $ssltest -tls1 -cipher SRP -srpuser test -srppass abc123
        +
        +  echo test tls1 with SRP via BIO pair
        +  $ssltest -bio_pair -tls1 -cipher SRP -srpuser test -srppass abc123
        +fi
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/test/testssl.com b/vendor/openssl/openssl/test/testssl.com
        new file mode 100644
        index 000000000..f19edc471
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testssl.com
        @@ -0,0 +1,208 @@
        +$! TESTSSL.COM
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p4 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	texe_dir = "sys$disk:[-.''__arch'.exe.test]"
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	if p1 .eqs. ""
        +$	then
        +$	    key="[-.apps]server.pem"
        +$	else
        +$	    key=p1
        +$	endif
        +$	if p2 .eqs. ""
        +$	then
        +$	    cert="[-.apps]server.pem"
        +$	else
        +$	    cert=p2
        +$	endif
        +$	ssltest = "mcr ''texe_dir'ssltest -key ''key'"+ -
        +	 " -cert ''cert' -c_key ''key' -c_cert ''cert'"
        +$!
        +$	set noon
        +$	define/user sys$output testssl-x509-output.
        +$	define/user sys$error nla0:
        +$	mcr 'exe_dir'openssl x509 -in 'cert' -text -noout
        +$	define/user sys$error nla0:
        +$	search/output=nla0: testssl-x509-output. "DSA Public Key"/exact
        +$	if $severity .eq. 1
        +$	then
        +$	    dsa_cert = "YES"
        +$	else
        +$	    dsa_cert = "NO"
        +$	endif
        +$	delete testssl-x509-output.;*
        +$
        +$	if p3 .eqs. ""
        +$	then
        +$	    copy/concatenate [-.certs]*.pem certs.tmp
        +$	    CA = """-CAfile"" certs.tmp"
        +$	else
        +$	    CA = """-CAfile"" "+p3
        +$	endif
        +$
        +$!###########################################################################
        +$
        +$	write sys$output "test sslv2"
        +$	'ssltest' -ssl2
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2 with server authentication"
        +$	'ssltest' -ssl2 -server_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	if .not. dsa_cert
        +$	then
        +$	    write sys$output "test sslv2 with client authentication"
        +$	    'ssltest' -ssl2 -client_auth 'CA'
        +$	    if $severity .ne. 1 then goto exit3
        +$
        +$	    write sys$output "test sslv2 with both client and server authentication"
        +$	    'ssltest' -ssl2 -server_auth -client_auth 'CA'
        +$	    if $severity .ne. 1 then goto exit3
        +$	endif
        +$
        +$	write sys$output "test sslv3"
        +$	'ssltest' -ssl3
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv3 with server authentication"
        +$	'ssltest' -ssl3 -server_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv3 with client authentication"
        +$	'ssltest' -ssl3 -client_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv3 with both client and server authentication"
        +$	'ssltest' -ssl3 -server_auth -client_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3"
        +$	'ssltest'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 with server authentication"
        +$	'ssltest' -server_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 with client authentication"
        +$	'ssltest' -client_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 with both client and server authentication"
        +$	'ssltest' -server_auth -client_auth 'CA'
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2 via BIO pair"
        +$	'ssltest' -bio_pair -ssl2 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2 with server authentication via BIO pair"
        +$	'ssltest' -bio_pair -ssl2 -server_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	if .not. dsa_cert
        +$	then
        +$	    write sys$output "test sslv2 with client authentication via BIO pair"
        +$	    'ssltest' -bio_pair -ssl2 -client_auth 'CA' 
        +$	    if $severity .ne. 1 then goto exit3
        +$
        +$	    write sys$output "test sslv2 with both client and server authentication via BIO pair"
        +$	    'ssltest' -bio_pair -ssl2 -server_auth -client_auth 'CA' 
        +$	    if $severity .ne. 1 then goto exit3
        +$	endif
        +$
        +$	write sys$output "test sslv3 via BIO pair"
        +$	'ssltest' -bio_pair -ssl3 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv3 with server authentication via BIO pair"
        +$	'ssltest' -bio_pair -ssl3 -server_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv3 with client authentication via BIO pair"
        +$	'ssltest' -bio_pair -ssl3 -client_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        + 
        +$	write sys$output "test sslv3 with both client and server authentication via BIO pair"
        +$	'ssltest' -bio_pair -ssl3 -server_auth -client_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 via BIO pair"
        +$	'ssltest' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	if .not. dsa_cert
        +$	then
        +$	    write sys$output "test sslv2/sslv3 w/o DHE via BIO pair"
        +$	    'ssltest' -bio_pair -no_dhe
        +$	    if $severity .ne. 1 then goto exit3
        +$	endif
        +$
        +$	write sys$output "test sslv2/sslv3 with 1024 bit DHE via BIO pair"
        +$	'ssltest' -bio_pair -dhe1024dsa -v
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 with server authentication"
        +$	'ssltest' -bio_pair -server_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 with client authentication via BIO pair"
        +$	'ssltest' -bio_pair -client_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$	write sys$output "test sslv2/sslv3 with both client and server authentication via BIO pair"
        +$	'ssltest' -bio_pair -server_auth -client_auth 'CA' 
        +$	if $severity .ne. 1 then goto exit3
        +$
        +$!###########################################################################
        +$
        +$	define/user sys$output nla0:
        +$	mcr 'exe_dir'openssl no-rsa
        +$	no_rsa=$SEVERITY
        +$	define/user sys$output nla0:
        +$	mcr 'exe_dir'openssl no-dh
        +$	no_dh=$SEVERITY
        +$
        +$	if no_dh
        +$	then
        +$	    write sys$output "skipping anonymous DH tests"
        +$	else
        +$	    write sys$output "test tls1 with 1024bit anonymous DH, multiple handshakes"
        +$	    'ssltest' -v -bio_pair -tls1 -cipher "ADH" -dhe1024dsa -num 10 -f -time
        +$	    if $severity .ne. 1 then goto exit3
        +$	endif
        +$
        +$	if no_rsa
        +$	then
        +$	    write sys$output "skipping RSA tests"
        +$	else
        +$	    write sys$output "test tls1 with 1024bit RSA, no DHE, multiple handshakes"
        +$	    mcr 'texe_dir'ssltest -v -bio_pair -tls1 -cert [-.apps]server2.pem -no_dhe -num 10 -f -time
        +$	    if $severity .ne. 1 then goto exit3
        +$
        +$	    if no_dh
        +$	    then
        +$		write sys$output "skipping RSA+DHE tests"
        +$	    else
        +$		write sys$output "test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes"
        +$		mcr 'texe_dir'ssltest -v -bio_pair -tls1 -cert [-.apps]server2.pem -dhe1024dsa -num 10 -f -time
        +$		if $severity .ne. 1 then goto exit3
        +$	    endif
        +$	endif
        +$
        +$	RET = 1
        +$	goto exit
        +$ exit3:
        +$	RET = 3
        +$ exit:
        +$	if p3 .eqs. "" then delete certs.tmp;*
        +$	set on
        +$	exit 'RET'
        diff --git a/vendor/openssl/openssl/test/testsslproxy b/vendor/openssl/openssl/test/testsslproxy
        new file mode 100644
        index 000000000..58bbda8ab
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testsslproxy
        @@ -0,0 +1,10 @@
        +#! /bin/sh
        +
        +echo 'Testing a lot of proxy conditions.'
        +echo 'Some of them may turn out being invalid, which is fine.'
        +for auth in A B C BC; do
        +    for cond in A B C 'A|B&!C'; do
        +	sh ./testssl $1 $2 $3 "-proxy -proxy_auth $auth -proxy_cond $cond"
        +	if [ $? = 3 ]; then exit 1; fi
        +    done
        +done
        diff --git a/vendor/openssl/openssl/test/testtsa b/vendor/openssl/openssl/test/testtsa
        new file mode 100644
        index 000000000..bb653b5f7
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testtsa
        @@ -0,0 +1,238 @@
        +#!/bin/sh
        +
        +#
        +# A few very basic tests for the 'ts' time stamping authority command.
        +#
        +
        +SH="/bin/sh"
        +if test "$OSTYPE" = msdosdjgpp; then
        +    PATH="../apps\;$PATH"
        +else
        +    PATH="../apps:$PATH"
        +fi
        +export SH PATH
        +
        +OPENSSL_CONF="../CAtsa.cnf"
        +export OPENSSL_CONF
        +# Because that's what ../apps/CA.sh really looks at
        +SSLEAY_CONFIG="-config $OPENSSL_CONF"
        +export SSLEAY_CONFIG
        +
        +OPENSSL="`pwd`/../util/opensslwrap.sh"
        +export OPENSSL
        +
        +error () {
        +
        +    echo "TSA test failed!" >&2
        +    exit 1
        +}
        +
        +setup_dir () {
        +
        +    rm -rf tsa 2>/dev/null
        +    mkdir tsa
        +    cd ./tsa
        +}
        +
        +clean_up_dir () {
        +
        +    cd ..
        +    rm -rf tsa
        +}
        +
        +create_ca () {
        +
        +    echo "Creating a new CA for the TSA tests..."
        +    TSDNSECT=ts_ca_dn
        +    export TSDNSECT   
        +    ../../util/shlib_wrap.sh ../../apps/openssl req -new -x509 -nodes \
        +	-out tsaca.pem -keyout tsacakey.pem
        +    test $? != 0 && error
        +}
        +
        +create_tsa_cert () {
        +
        +    INDEX=$1
        +    export INDEX
        +    EXT=$2
        +    TSDNSECT=ts_cert_dn
        +    export TSDNSECT   
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl req -new \
        +	-out tsa_req${INDEX}.pem -keyout tsa_key${INDEX}.pem
        +    test $? != 0 && error
        +echo Using extension $EXT
        +    ../../util/shlib_wrap.sh ../../apps/openssl x509 -req \
        +	-in tsa_req${INDEX}.pem -out tsa_cert${INDEX}.pem \
        +	-CA tsaca.pem -CAkey tsacakey.pem -CAcreateserial \
        +	-extfile $OPENSSL_CONF -extensions $EXT
        +    test $? != 0 && error
        +}
        +
        +print_request () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -in $1 -text
        +}
        +
        +create_time_stamp_request1 () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy1 -cert -out req1.tsq
        +    test $? != 0 && error
        +}
        +
        +create_time_stamp_request2 () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy2 -no_nonce \
        +	-out req2.tsq
        +    test $? != 0 && error
        +}
        +
        +create_time_stamp_request3 () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../CAtsa.cnf -no_nonce -out req3.tsq
        +    test $? != 0 && error
        +}
        +
        +print_response () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $1 -text
        +    test $? != 0 && error
        +}
        +
        +create_time_stamp_response () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -section $3 -queryfile $1 -out $2
        +    test $? != 0 && error
        +}
        +
        +time_stamp_response_token_test () {
        +
        +    RESPONSE2=$2.copy.tsr
        +    TOKEN_DER=$2.token.der
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $TOKEN_DER -token_out
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -out $RESPONSE2
        +    test $? != 0 && error
        +    cmp $RESPONSE2 $2
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -text -token_out
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -text -token_out
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -queryfile $1 -text -token_out
        +    test $? != 0 && error
        +}
        +
        +verify_time_stamp_response () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
        +	-untrusted tsa_cert1.pem
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2 -CAfile tsaca.pem \
        +	-untrusted tsa_cert1.pem
        +    test $? != 0 && error
        +}
        +
        +verify_time_stamp_token () {
        +
        +    # create the token from the response first
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $2.token -token_out
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2.token -token_in \
        +	-CAfile tsaca.pem -untrusted tsa_cert1.pem
        +    test $? != 0 && error
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2.token -token_in \
        +	-CAfile tsaca.pem -untrusted tsa_cert1.pem
        +    test $? != 0 && error
        +}
        +
        +verify_time_stamp_response_fail () {
        +
        +    ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
        +	-untrusted tsa_cert1.pem
        +    # Checks if the verification failed, as it should have.
        +    test $? = 0 && error
        +    echo Ok
        +}
        +
        +# main functions
        +
        +echo "Setting up TSA test directory..."
        +setup_dir
        +
        +echo "Creating CA for TSA tests..."
        +create_ca
        +
        +echo "Creating tsa_cert1.pem TSA server cert..."
        +create_tsa_cert 1 tsa_cert
        +
        +echo "Creating tsa_cert2.pem non-TSA server cert..."
        +create_tsa_cert 2 non_tsa_cert
        +
        +echo "Creating req1.req time stamp request for file testtsa..."
        +create_time_stamp_request1
        +
        +echo "Printing req1.req..."
        +print_request req1.tsq
        +
        +echo "Generating valid response for req1.req..."
        +create_time_stamp_response req1.tsq resp1.tsr tsa_config1
        +
        +echo "Printing response..."
        +print_response resp1.tsr
        +
        +echo "Verifying valid response..."
        +verify_time_stamp_response req1.tsq resp1.tsr ../testtsa
        +
        +echo "Verifying valid token..."
        +verify_time_stamp_token req1.tsq resp1.tsr ../testtsa
        +
        +# The tests below are commented out, because invalid signer certificates
        +# can no longer be specified in the config file.
        +
        +# echo "Generating _invalid_ response for req1.req..."
        +# create_time_stamp_response req1.tsq resp1_bad.tsr tsa_config2
        +
        +# echo "Printing response..."
        +# print_response resp1_bad.tsr
        +
        +# echo "Verifying invalid response, it should fail..."
        +# verify_time_stamp_response_fail req1.tsq resp1_bad.tsr
        +
        +echo "Creating req2.req time stamp request for file testtsa..."
        +create_time_stamp_request2
        +
        +echo "Printing req2.req..."
        +print_request req2.tsq
        +
        +echo "Generating valid response for req2.req..."
        +create_time_stamp_response req2.tsq resp2.tsr tsa_config1
        +
        +echo "Checking '-token_in' and '-token_out' options with '-reply'..."
        +time_stamp_response_token_test req2.tsq resp2.tsr
        +
        +echo "Printing response..."
        +print_response resp2.tsr
        +
        +echo "Verifying valid response..."
        +verify_time_stamp_response req2.tsq resp2.tsr ../testtsa
        +
        +echo "Verifying response against wrong request, it should fail..."
        +verify_time_stamp_response_fail req1.tsq resp2.tsr
        +
        +echo "Verifying response against wrong request, it should fail..."
        +verify_time_stamp_response_fail req2.tsq resp1.tsr
        +
        +echo "Creating req3.req time stamp request for file CAtsa.cnf..."
        +create_time_stamp_request3
        +
        +echo "Printing req3.req..."
        +print_request req3.tsq
        +
        +echo "Verifying response against wrong request, it should fail..."
        +verify_time_stamp_response_fail req3.tsq resp1.tsr
        +
        +echo "Cleaning up..."
        +clean_up_dir
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/test/testtsa.com b/vendor/openssl/openssl/test/testtsa.com
        new file mode 100644
        index 000000000..29fb1d0e6
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testtsa.com
        @@ -0,0 +1,255 @@
        +$!
        +$! A few very basic tests for the 'ts' time stamping authority command.
        +$!
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p4 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	openssl = "mcr ''f$parse(exe_dir+"openssl.exe")'"
        +$	OPENSSL_CONF = "[-]CAtsa.cnf"
        +$	! Because that's what ../apps/CA.sh really looks at
        +$	SSLEAY_CONFIG = "-config " + OPENSSL_CONF
        +$
        +$ error:
        +$	subroutine
        +$		write sys$error "TSA test failed!"
        +$		exit 3
        +$	endsubroutine
        +$
        +$ setup_dir:
        +$	subroutine
        +$
        +$		if f$search("tsa.dir") .nes ""
        +$		then
        +$			@[-.util]deltree [.tsa]*.*
        +$ 			set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) tsa.dir;*
        +$ 			delete tsa.dir;*
        +$		endif
        +$
        +$		create/dir [.tsa]
        +$		set default [.tsa]
        +$	endsubroutine
        +$
        +$ clean_up_dir:
        +$	subroutine
        +$
        +$		set default [-]
        +$		@[-.util]deltree [.tsa]*.*
        +$ 		set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) tsa.dir;*
        +$ 		delete tsa.dir;*
        +$	endsubroutine
        +$
        +$ create_ca:
        +$	subroutine
        +$
        +$		write sys$output "Creating a new CA for the TSA tests..."
        +$		TSDNSECT = "ts_ca_dn"
        +$		openssl req -new -x509 -nodes -
        +			-out tsaca.pem -keyout tsacakey.pem
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ create_tsa_cert:
        +$	subroutine
        +$
        +$		INDEX=p1
        +$		EXT=p2
        +$		TSDNSECT = "ts_cert_dn"
        +$
        +$		openssl req -new -
        +			-out tsa_req'INDEX'.pem -keyout tsa_key'INDEX'.pem
        +$		if $severity .ne. 1 then call error
        +$
        +$		write sys$output "Using extension ''EXT'"
        +$		openssl x509 -req -
        +			-in tsa_req'INDEX'.pem -out tsa_cert'INDEX'.pem -
        +			"-CA" tsaca.pem "-CAkey" tsacakey.pem "-CAcreateserial" -
        +			-extfile 'OPENSSL_CONF' -extensions "''EXT'"
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ print_request:
        +$	subroutine
        +$
        +$		openssl ts -query -in 'p1' -text
        +$	endsubroutine
        +$
        +$ create_time_stamp_request1: subroutine
        +$
        +$		openssl ts -query -data [-]testtsa.com -policy tsa_policy1 -
        +			-cert -out req1.tsq
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ create_time_stamp_request2: subroutine
        +$
        +$		openssl ts -query -data [-]testtsa.com -policy tsa_policy2 -
        +			-no_nonce -out req2.tsq
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ create_time_stamp_request3: subroutine
        +$
        +$		openssl ts -query -data [-]CAtsa.cnf -no_nonce -out req3.tsq
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ print_response:
        +$	subroutine
        +$
        +$		openssl ts -reply -in 'p1' -text
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ create_time_stamp_response:
        +$	subroutine
        +$
        +$		openssl ts -reply -section 'p3' -queryfile 'p1' -out 'p2'
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ time_stamp_response_token_test:
        +$	subroutine
        +$
        +$		RESPONSE2 = p2+ "-copy_tsr"
        +$		TOKEN_DER = p2+ "-token_der"
        +$		openssl ts -reply -in 'p2' -out 'TOKEN_DER' -token_out
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -reply -in 'TOKEN_DER' -token_in -out 'RESPONSE2'
        +$		if $severity .ne. 1 then call error
        +$		backup/compare 'RESPONSE2' 'p2'
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -reply -in 'p2' -text -token_out
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -reply -in 'TOKEN_DER' -token_in -text -token_out
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -reply -queryfile 'p1' -text -token_out
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ verify_time_stamp_response:
        +$	subroutine
        +$
        +$		openssl ts -verify -queryfile 'p1' -in 'p2' -
        +			"-CAfile" tsaca.pem -untrusted tsa_cert1.pem
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -verify -data 'p3' -in 'p2' -
        +			"-CAfile" tsaca.pem -untrusted tsa_cert1.pem
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ verify_time_stamp_token:
        +$	subroutine
        +$
        +$		! create the token from the response first
        +$		openssl ts -reply -in "''p2'" -out "''p2'-token" -token_out
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -verify -queryfile "''p1'" -in "''p2'-token" -
        +		 -token_in "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
        +$		if $severity .ne. 1 then call error
        +$		openssl ts -verify -data "''p3'" -in "''p2'-token" -
        +		 -token_in "-CAfile" tsaca.pem -untrusted tsa_cert1.pem
        +$		if $severity .ne. 1 then call error
        +$	endsubroutine
        +$
        +$ verify_time_stamp_response_fail:
        +$	subroutine
        +$
        +$		openssl ts -verify -queryfile 'p1' -in 'p2' -
        +			"-CAfile" tsaca.pem -untrusted tsa_cert1.pem
        +$		! Checks if the verification failed, as it should have.
        +$		if $severity .eq. 1 then call error
        +$		write sys$output "Ok"
        +$	endsubroutine
        +$
        +$	! Main body ----------------------------------------------------------
        +$
        +$	set noon
        +$
        +$	write sys$output "Setting up TSA test directory..."
        +$	call setup_dir
        +$
        +$	write sys$output "Creating CA for TSA tests..."
        +$	call create_ca
        +$
        +$	write sys$output "Creating tsa_cert1.pem TSA server cert..."
        +$	call create_tsa_cert 1 "tsa_cert"
        +$
        +$	write sys$output "Creating tsa_cert2.pem non-TSA server cert..."
        +$	call create_tsa_cert 2 "non_tsa_cert"
        +$
        +$	write sys$output "Creating req1.req time stamp request for file testtsa..."
        +$	call create_time_stamp_request1
        +$
        +$	write sys$output "Printing req1.req..."
        +$	call print_request "req1.tsq"
        +$
        +$	write sys$output "Generating valid response for req1.req..."
        +$	call create_time_stamp_response "req1.tsq" "resp1.tsr" "tsa_config1"
        +$
        +$	write sys$output "Printing response..."
        +$	call print_response "resp1.tsr"
        +$
        +$	write sys$output "Verifying valid response..."
        +$	call verify_time_stamp_response "req1.tsq" "resp1.tsr" "[-]testtsa.com"
        +$
        +$	write sys$output "Verifying valid token..."
        +$	call verify_time_stamp_token "req1.tsq" "resp1.tsr" "[-]testtsa.com"
        +$
        +$	! The tests below are commented out, because invalid signer certificates
        +$	! can no longer be specified in the config file.
        +$
        +$	! write sys$output "Generating _invalid_ response for req1.req..."
        +$	! call create_time_stamp_response "req1.tsq" "resp1_bad.tsr" "tsa_config2"
        +$
        +$	! write sys$output "Printing response..."
        +$	! call print_response "resp1_bad.tsr"
        +$
        +$	! write sys$output "Verifying invalid response, it should fail..."
        +$	! call verify_time_stamp_response_fail "req1.tsq" "resp1_bad.tsr"
        +$
        +$	write sys$output "Creating req2.req time stamp request for file testtsa..."
        +$	call create_time_stamp_request2
        +$
        +$	write sys$output "Printing req2.req..."
        +$	call print_request "req2.tsq"
        +$
        +$	write sys$output "Generating valid response for req2.req..."
        +$	call create_time_stamp_response "req2.tsq" "resp2.tsr" "tsa_config1"
        +$
        +$	write sys$output "Checking '-token_in' and '-token_out' options with '-reply'..."
        +$	call time_stamp_response_token_test "req2.tsq" "resp2.tsr"
        +$
        +$	write sys$output "Printing response..."
        +$	call print_response "resp2.tsr"
        +$
        +$	write sys$output "Verifying valid response..."
        +$	call verify_time_stamp_response "req2.tsq" "resp2.tsr" "[-]testtsa.com"
        +$
        +$	write sys$output "Verifying response against wrong request, it should fail..."
        +$	call verify_time_stamp_response_fail "req1.tsq" "resp2.tsr"
        +$
        +$	write sys$output "Verifying response against wrong request, it should fail..."
        +$	call verify_time_stamp_response_fail "req2.tsq" "resp1.tsr"
        +$
        +$	write sys$output "Creating req3.req time stamp request for file CAtsa.cnf..."
        +$	call create_time_stamp_request3
        +$
        +$	write sys$output "Printing req3.req..."
        +$	call print_request "req3.tsq"
        +$
        +$	write sys$output "Verifying response against wrong request, it should fail..."
        +$	call verify_time_stamp_response_fail "req3.tsq" "resp1.tsr"
        +$
        +$	write sys$output "Cleaning up..."
        +$	call clean_up_dir
        +$
        +$	set on
        +$
        +$	exit
        diff --git a/vendor/openssl/openssl/test/testx509.pem b/vendor/openssl/openssl/test/testx509.pem
        new file mode 100644
        index 000000000..8a85d1496
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/testx509.pem
        @@ -0,0 +1,10 @@
        +-----BEGIN CERTIFICATE-----
        +MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
        +BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz
        +MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
        +RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF
        +AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO
        +/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE
        +Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ
        +zl9HYIMxATFyqSiD9jsx
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/times b/vendor/openssl/openssl/test/times
        new file mode 100644
        index 000000000..6b66eb342
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/times
        @@ -0,0 +1,113 @@
        +
        +More number for the questions about SSL overheads....
        +
        +The following numbers were generated on a Pentium pro 200, running Linux.
        +They give an indication of the SSL protocol and encryption overheads.
        +
        +The program that generated them is an unreleased version of ssl/ssltest.c
        +which is the SSLeay ssl protocol testing program.  It is a single process that
        +talks both sides of the SSL protocol via a non-blocking memory buffer
        +interface.
        +
        +How do I read this?  The protocol and cipher are reasonable obvious.
        +The next number is the number of connections being made.  The next is the
        +number of bytes exchanged between the client and server side of the protocol.
        +This is the number of bytes that the client sends to the server, and then
        +the server sends back.  Because this is all happening in one process,
        +the data is being encrypted, decrypted, encrypted and then decrypted again.
        +It is a round trip of that many bytes.  Because the one process performs
        +both the client and server sides of the protocol and it sends this many bytes
        +each direction, multiply this number by 4 to generate the number
        +of bytes encrypted/decrypted/MACed.  The first time value is how many seconds
        +elapsed doing a full SSL handshake, the second is the cost of one
        +full handshake and the rest being session-id reuse.
        +
        +SSLv2 RC4-MD5      1000 x      1   12.83s   0.70s
        +SSLv3 NULL-MD5     1000 x      1   14.35s   1.47s
        +SSLv3 RC4-MD5      1000 x      1   14.46s   1.56s
        +SSLv3 RC4-MD5      1000 x      1   51.93s   1.62s 1024bit RSA
        +SSLv3 RC4-SHA      1000 x      1   14.61s   1.83s
        +SSLv3 DES-CBC-SHA  1000 x      1   14.70s   1.89s
        +SSLv3 DES-CBC3-SHA 1000 x      1   15.16s   2.16s
        +
        +SSLv2 RC4-MD5      1000 x   1024   13.72s   1.27s
        +SSLv3 NULL-MD5     1000 x   1024   14.79s   1.92s
        +SSLv3 RC4-MD5      1000 x   1024   52.58s   2.29s 1024bit RSA
        +SSLv3 RC4-SHA      1000 x   1024   15.39s   2.67s
        +SSLv3 DES-CBC-SHA  1000 x   1024   16.45s   3.55s
        +SSLv3 DES-CBC3-SHA 1000 x   1024   18.21s   5.38s
        +
        +SSLv2 RC4-MD5      1000 x  10240   18.97s   6.52s
        +SSLv3 NULL-MD5     1000 x  10240   17.79s   5.11s
        +SSLv3 RC4-MD5      1000 x  10240   20.25s   7.90s
        +SSLv3 RC4-MD5      1000 x  10240   58.26s   8.08s 1024bit RSA
        +SSLv3 RC4-SHA      1000 x  10240   22.96s  11.44s
        +SSLv3 DES-CBC-SHA  1000 x  10240   30.65s  18.41s
        +SSLv3 DES-CBC3-SHA 1000 x  10240   47.04s  34.53s
        +
        +SSLv2 RC4-MD5      1000 x 102400   70.22s  57.74s
        +SSLv3 NULL-MD5     1000 x 102400   43.73s  31.03s
        +SSLv3 RC4-MD5      1000 x 102400   71.32s  58.83s
        +SSLv3 RC4-MD5      1000 x 102400  109.66s  59.20s 1024bit RSA
        +SSLv3 RC4-SHA      1000 x 102400   95.88s  82.21s
        +SSLv3 DES-CBC-SHA  1000 x 102400  173.22s 160.55s
        +SSLv3 DES-CBC3-SHA 1000 x 102400  336.61s 323.82s
        +
        +What does this all mean?  Well for a server, with no session-id reuse, with
        +a transfer size of 10240 bytes, using RC4-MD5 and a 512bit server key,
        +a Pentium pro 200 running Linux can handle the SSLv3 protocol overheads of
        +about 49 connections a second.  Reality will be quite different :-).
        +
        +Remember the first number is 1000 full ssl handshakes, the second is
        +1 full and 999 with session-id reuse.  The RSA overheads for each exchange
        +would be one public and one private operation, but the protocol/MAC/cipher
        +cost would be quite similar in both the client and server.
        +
        +eric (adding numbers to speculation)
        +
        +--- Appendix ---
        +- The time measured is user time but these number a very rough.
        +- Remember this is the cost of both client and server sides of the protocol.
        +- The TCP/kernel overhead of connection establishment is normally the
        +  killer in SSL.  Often delays in the TCP protocol will make session-id
        +  reuse look slower that new sessions, but this would not be the case on
        +  a loaded server.
        +- The TCP round trip latencies, while slowing individual connections,
        +  would have minimal impact on throughput.
        +- Instead of sending one 102400 byte buffer, one 8k buffer is sent until
        +- the required number of bytes are processed.
        +- The SSLv3 connections were actually SSLv2 compatible SSLv3 headers.
        +- A 512bit server key was being used except where noted.
        +- No server key verification was being performed on the client side of the
        +  protocol.  This would slow things down very little.
        +- The library being used is SSLeay 0.8.x.
        +- The normal measuring system was commands of the form
        +  time ./ssltest -num 1000 -bytes 102400 -cipher DES-CBC-SHA -reuse
        +  This modified version of ssltest should be in the next public release of
        +  SSLeay.
        +
        +The general cipher performance number for this platform are
        +
        +SSLeay 0.8.2a 04-Sep-1997
        +built on Fri Sep  5 17:37:05 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
        +C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized 
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               131.02k      368.41k      500.57k      549.21k      566.09k
        +mdc2              535.60k      589.10k      595.88k      595.97k      594.54k
        +md5              1801.53k     9674.77k    17484.03k    21849.43k    23592.96k
        +sha              1261.63k     5533.25k     9285.63k    11187.88k    11913.90k
        +sha1             1103.13k     4782.53k     7933.78k     9472.34k    10070.70k
        +rc4             10722.53k    14443.93k    15215.79k    15299.24k    15219.59k
        +des cbc          3286.57k     3827.73k     3913.39k     3931.82k     3926.70k
        +des ede3         1443.50k     1549.08k     1561.17k     1566.38k     1564.67k
        +idea cbc         2203.64k     2508.16k     2538.33k     2543.62k     2547.71k
        +rc2 cbc          1430.94k     1511.59k     1524.82k     1527.13k     1523.33k
        +blowfish cbc     4716.07k     5965.82k     6190.17k     6243.67k     6234.11k
        +                  sign    verify
        +rsa  512 bits   0.0100s   0.0011s
        +rsa 1024 bits   0.0451s   0.0012s
        +rsa 2048 bits   0.2605s   0.0086s
        +rsa 4096 bits   1.6883s   0.0302s
        +
        diff --git a/vendor/openssl/openssl/test/tpkcs7 b/vendor/openssl/openssl/test/tpkcs7
        new file mode 100644
        index 000000000..3e435ffbf
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tpkcs7
        @@ -0,0 +1,48 @@
        +#!/bin/sh
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl pkcs7'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=testp7.pem
        +fi
        +
        +echo testing pkcs7 conversions
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp fff.p f.p
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/tpkcs7.com b/vendor/openssl/openssl/test/tpkcs7.com
        new file mode 100644
        index 000000000..3fc4982bb
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tpkcs7.com
        @@ -0,0 +1,59 @@
        +$! TPKCS7.COM  --  Tests pkcs7 keys
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	cmd = "mcr ''exe_dir'openssl pkcs7"
        +$
        +$	t = "testp7.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing PKCS7 conversions"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare fff.p f.p
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/tpkcs7d b/vendor/openssl/openssl/test/tpkcs7d
        new file mode 100644
        index 000000000..64fc28e88
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tpkcs7d
        @@ -0,0 +1,41 @@
        +#!/bin/sh
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl pkcs7'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=pkcs7-1.pem
        +fi
        +
        +echo "testing pkcs7 conversions (2)"
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/tpkcs7d.com b/vendor/openssl/openssl/test/tpkcs7d.com
        new file mode 100644
        index 000000000..eea8c888e
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tpkcs7d.com
        @@ -0,0 +1,52 @@
        +$! TPKCS7.COM  --  Tests pkcs7 keys
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	cmd = "mcr ''exe_dir'openssl pkcs7"
        +$
        +$	t = "pkcs7-1.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing PKCS7 conversions (2)"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/treq b/vendor/openssl/openssl/test/treq
        new file mode 100644
        index 000000000..77f37dcf3
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/treq
        @@ -0,0 +1,83 @@
        +#!/bin/sh
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl req -config ../apps/openssl.cnf'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=testreq.pem
        +fi
        +
        +if $cmd -in $t -inform p -noout -text 2>&1 | fgrep -i 'Unknown Public Key'; then
        +  echo "skipping req conversion test for $t"
        +  exit 0
        +fi
        +
        +echo testing req conversions
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in fff.p -inform p -outform t >f.t
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -verify -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> d"
        +#$cmd -in f.t -inform t -outform d >ff.d2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -verify -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#echo "d -> t"
        +#$cmd -in f.d -inform d -outform t >ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> t"
        +#$cmd -in f.t -inform t -outform t >ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in f.p -inform p -outform t >ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> p"
        +#$cmd -in f.t -inform t -outform p >ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp fff.p f.p
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp fff.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#cmp f.t ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp f.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/treq.com b/vendor/openssl/openssl/test/treq.com
        new file mode 100644
        index 000000000..acf08b79e
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/treq.com
        @@ -0,0 +1,88 @@
        +$! TREQ.COM  --  Tests req keys
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	cmd = "mcr ''exe_dir'openssl req -config [-.apps]openssl-vms.cnf"
        +$
        +$	t = "testreq.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing req conversions"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in fff.p -inform p -outform t -out f.t
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -verify -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> d"
        +$!	'cmd' -verify -in f.t -inform t -outform d -out ff.d2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -verify -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	write sys$output "d -> t"
        +$!	'cmd' -in f.d -inform d -outform t -out ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> t"
        +$!	'cmd' -in f.t -inform t -outform t -out ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in f.p -inform p -outform t -out ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> p"
        +$!	'cmd' -in f.t -inform t -outform p -out ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare fff.p f.p
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare fff.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	backup/compare f.t ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/trsa b/vendor/openssl/openssl/test/trsa
        new file mode 100644
        index 000000000..249ac1ddc
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/trsa
        @@ -0,0 +1,83 @@
        +#!/bin/sh
        +
        +if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
        +  echo skipping rsa conversion test
        +  exit 0
        +fi
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl rsa'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=testrsa.pem
        +fi
        +
        +echo testing rsa conversions
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in fff.p -inform p -outform t >f.t
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> d"
        +#$cmd -in f.t -inform t -outform d >ff.d2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#echo "d -> t"
        +#$cmd -in f.d -inform d -outform t >ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> t"
        +#$cmd -in f.t -inform t -outform t >ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in f.p -inform p -outform t >ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> p"
        +#$cmd -in f.t -inform t -outform p >ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp fff.p f.p
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp fff.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#cmp f.t ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp f.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/trsa.com b/vendor/openssl/openssl/test/trsa.com
        new file mode 100644
        index 000000000..54180843e
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/trsa.com
        @@ -0,0 +1,99 @@
        +$! TRSA.COM  --  Tests rsa keys
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	set noon
        +$	define/user sys$output nla0:
        +$	mcr 'exe_dir'openssl no-rsa
        +$	save_severity=$SEVERITY
        +$	set on
        +$	if save_severity
        +$	then
        +$	    write sys$output "skipping RSA conversion test"
        +$	    exit
        +$	endif
        +$
        +$	cmd = "mcr ''exe_dir'openssl rsa"
        +$
        +$	t = "testrsa.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing RSA conversions"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in fff.p -inform p -outform t -out f.t
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> d"
        +$!	'cmd' -in f.t -inform t -outform d -out ff.d2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	write sys$output "d -> t"
        +$!	'cmd' -in f.d -inform d -outform t -out ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> t"
        +$!	'cmd' -in f.t -inform t -outform t -out ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in f.p -inform p -outform t -out ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> p"
        +$!	'cmd' -in f.t -inform t -outform p -out ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare fff.p f.p
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare fff.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	backup/compare f.t ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/tsid b/vendor/openssl/openssl/test/tsid
        new file mode 100644
        index 000000000..6adbd531c
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tsid
        @@ -0,0 +1,78 @@
        +#!/bin/sh
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl sess_id'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=testsid.pem
        +fi
        +
        +echo testing session-id conversions
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in fff.p -inform p -outform t >f.t
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> d"
        +#$cmd -in f.t -inform t -outform d >ff.d2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#echo "d -> t"
        +#$cmd -in f.d -inform d -outform t >ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> t"
        +#$cmd -in f.t -inform t -outform t >ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#echo "p -> t"
        +#$cmd -in f.p -inform p -outform t >ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#echo "t -> p"
        +#$cmd -in f.t -inform t -outform p >ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp fff.p f.p
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp fff.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +#cmp f.t ff.t1
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t2
        +#if [ $? != 0 ]; then exit 1; fi
        +#cmp f.t ff.t3
        +#if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +#cmp f.p ff.p2
        +#if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/tsid.com b/vendor/openssl/openssl/test/tsid.com
        new file mode 100644
        index 000000000..b6c4e4947
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tsid.com
        @@ -0,0 +1,88 @@
        +$! TSID.COM  --  Tests sid keys
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	cmd = "mcr ''exe_dir'openssl sess_id"
        +$
        +$	t = "testsid.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing session-id conversions"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in fff.p -inform p -outform t -out f.t
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> d"
        +$!	'cmd' -in f.t -inform t -outform d -out ff.d2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	write sys$output "d -> t"
        +$!	'cmd' -in f.d -inform d -outform t -out ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> t"
        +$!	'cmd' -in f.t -inform t -outform t -out ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	write sys$output "p -> t"
        +$!	'cmd' -in f.p -inform p -outform t -out ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	write sys$output "t -> p"
        +$!	'cmd' -in f.t -inform t -outform p -out ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare fff.p f.p
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare fff.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$!	backup/compare f.t ff.t1
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t2
        +$!	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.t ff.t3
        +$!	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$!	backup/compare f.p ff.p2
        +$!	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/tverify.com b/vendor/openssl/openssl/test/tverify.com
        new file mode 100644
        index 000000000..d88834463
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tverify.com
        @@ -0,0 +1,65 @@
        +$! TVERIFY.COM
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p1 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	line_max = 255 ! Could be longer on modern non-VAX.
        +$	temp_file_name = "certs_"+ f$getjpi( "", "PID")+ ".tmp"
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$	cmd = "mcr ''exe_dir'openssl verify ""-CAfile"" ''temp_file_name'"
        +$	cmd_len = f$length( cmd)
        +$	pems = "[-.certs...]*.pem"
        +$!
        +$!	Concatenate all the certificate files.
        +$!
        +$	copy /concatenate 'pems' 'temp_file_name'
        +$!
        +$!	Loop through all the certificate files.
        +$!
        +$	args = ""
        +$	old_f = ""
        +$ loop_file: 
        +$	    f = f$search( pems)
        +$	    if ((f .nes. "") .and. (f .nes. old_f))
        +$	    then
        +$	      old_f = f
        +$!
        +$!	      If this file name would over-extend the command line, then
        +$!	      run the command now.
        +$!
        +$	      if (cmd_len+ f$length( args)+ 1+ f$length( f) .gt. line_max)
        +$	      then
        +$	         if (args .eqs. "") then goto disaster
        +$	         'cmd''args'
        +$	         args = ""
        +$	      endif
        +$!	      Add the next file to the argument list.
        +$	      args = args+ " "+ f
        +$	   else
        +$!            No more files in the list
        +$	      goto loop_file_end
        +$	   endif
        +$	goto loop_file
        +$	loop_file_end:
        +$!
        +$!	Run the command for any left-over arguments.
        +$!
        +$	if (args .nes. "")
        +$	then
        +$	   'cmd''args'
        +$	endif
        +$!
        +$!	Delete the temporary file.
        +$!
        +$	if (f$search( "''temp_file_name';*") .nes. "") then -
        +	 delete 'temp_file_name';*
        +$!
        +$	exit
        +$!
        +$	disaster:
        +$	write sys$output "   Command line too long.  Doomed."
        +$!
        diff --git a/vendor/openssl/openssl/test/tx509 b/vendor/openssl/openssl/test/tx509
        new file mode 100644
        index 000000000..4a15b98d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tx509
        @@ -0,0 +1,78 @@
        +#!/bin/sh
        +
        +cmd='../util/shlib_wrap.sh ../apps/openssl x509'
        +
        +if [ "$1"x != "x" ]; then
        +	t=$1
        +else
        +	t=testx509.pem
        +fi
        +
        +echo testing X509 conversions
        +cp $t fff.p
        +
        +echo "p -> d"
        +$cmd -in fff.p -inform p -outform d >f.d
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> n"
        +$cmd -in fff.p -inform p -outform n >f.n
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in fff.p -inform p -outform p >f.p
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> d"
        +$cmd -in f.d -inform d -outform d >ff.d1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "n -> d"
        +$cmd -in f.n -inform n -outform d >ff.d2
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> d"
        +$cmd -in f.p -inform p -outform d >ff.d3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> n"
        +$cmd -in f.d -inform d -outform n >ff.n1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "n -> n"
        +$cmd -in f.n -inform n -outform n >ff.n2
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> n"
        +$cmd -in f.p -inform p -outform n >ff.n3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +echo "d -> p"
        +$cmd -in f.d -inform d -outform p >ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +echo "n -> p"
        +$cmd -in f.n -inform n -outform p >ff.p2
        +if [ $? != 0 ]; then exit 1; fi
        +echo "p -> p"
        +$cmd -in f.p -inform p -outform p >ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp fff.p f.p
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p2
        +if [ $? != 0 ]; then exit 1; fi
        +cmp fff.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.n ff.n1
        +if [ $? != 0 ]; then exit 1; fi
        +cmp f.n ff.n2
        +if [ $? != 0 ]; then exit 1; fi
        +cmp f.n ff.n3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +cmp f.p ff.p1
        +if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p2
        +if [ $? != 0 ]; then exit 1; fi
        +cmp f.p ff.p3
        +if [ $? != 0 ]; then exit 1; fi
        +
        +/bin/rm -f f.* ff.* fff.*
        +exit 0
        diff --git a/vendor/openssl/openssl/test/tx509.com b/vendor/openssl/openssl/test/tx509.com
        new file mode 100644
        index 000000000..93ce988b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/tx509.com
        @@ -0,0 +1,88 @@
        +$! TX509.COM  --  Tests x509 certificates
        +$
        +$	__arch = "VAX"
        +$	if f$getsyi("cpu") .ge. 128 then -
        +	   __arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
        +$	if __arch .eqs. "" then __arch = "UNK"
        +$!
        +$	if (p2 .eqs. "64") then __arch = __arch+ "_64"
        +$!
        +$	exe_dir = "sys$disk:[-.''__arch'.exe.apps]"
        +$
        +$	cmd = "mcr ''exe_dir'openssl x509"
        +$
        +$	t = "testx509.pem"
        +$	if p1 .nes. "" then t = p1
        +$
        +$	write sys$output "testing X509 conversions"
        +$	if f$search("fff.*") .nes "" then delete fff.*;*
        +$	if f$search("ff.*") .nes "" then delete ff.*;*
        +$	if f$search("f.*") .nes "" then delete f.*;*
        +$	convert/fdl=sys$input: 't' fff.p
        +RECORD
        +	FORMAT STREAM_LF
        +$
        +$	write sys$output "p -> d"
        +$	'cmd' -in fff.p -inform p -outform d -out f.d
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> n"
        +$	'cmd' -in fff.p -inform p -outform n -out f.n
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in fff.p -inform p -outform p -out f.p
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> d"
        +$	'cmd' -in f.d -inform d -outform d -out ff.d1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "n -> d"
        +$	'cmd' -in f.n -inform n -outform d -out ff.d2
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> d"
        +$	'cmd' -in f.p -inform p -outform d -out ff.d3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> n"
        +$	'cmd' -in f.d -inform d -outform n -out ff.n1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "n -> n"
        +$	'cmd' -in f.n -inform n -outform n -out ff.n2
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> n"
        +$	'cmd' -in f.p -inform p -outform n -out ff.n3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	write sys$output "d -> p"
        +$	'cmd' -in f.d -inform d -outform p -out ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "n -> p"
        +$	'cmd' -in f.n -inform n -outform p -out ff.p2
        +$	if $severity .ne. 1 then exit 3
        +$	write sys$output "p -> p"
        +$	'cmd' -in f.p -inform p -outform p -out ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare fff.p f.p
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p2
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare fff.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.n ff.n1
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare f.n ff.n2
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare f.n ff.n3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	backup/compare f.p ff.p1
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p2
        +$	if $severity .ne. 1 then exit 3
        +$	backup/compare f.p ff.p3
        +$	if $severity .ne. 1 then exit 3
        +$
        +$	delete f.*;*,ff.*;*,fff.*;*
        diff --git a/vendor/openssl/openssl/test/v3-cert1.pem b/vendor/openssl/openssl/test/v3-cert1.pem
        new file mode 100644
        index 000000000..0da253d5c
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/v3-cert1.pem
        @@ -0,0 +1,16 @@
        +-----BEGIN CERTIFICATE-----
        +MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx
        +NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz
        +dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw
        +ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu
        +ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2
        +ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp
        +miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C
        +AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
        +Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
        +DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR
        +MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB
        +AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21
        +X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3
        +WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/v3-cert2.pem b/vendor/openssl/openssl/test/v3-cert2.pem
        new file mode 100644
        index 000000000..de0723ff8
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/v3-cert2.pem
        @@ -0,0 +1,16 @@
        +-----BEGIN CERTIFICATE-----
        +MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD
        +YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0
        +ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu
        +dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1
        +WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV
        +BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx
        +FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
        +6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT
        +G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ
        +YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm
        +b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc
        +F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz
        +lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap
        +jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=
        +-----END CERTIFICATE-----
        diff --git a/vendor/openssl/openssl/test/wp_test.c b/vendor/openssl/openssl/test/wp_test.c
        new file mode 100644
        index 000000000..c68c2c62c
        --- /dev/null
        +++ b/vendor/openssl/openssl/test/wp_test.c
        @@ -0,0 +1,228 @@
        +/* ====================================================================
        + * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
        + * ====================================================================
        + */
        +#include <stdio.h>
        +#include <string.h>
        +#include <stdlib.h>
        +
        +#include <openssl/whrlpool.h>
        +#include <openssl/crypto.h>
        +
        +#if defined(OPENSSL_NO_WHIRLPOOL)
        +int main(int argc, char *argv[])
        +{
        +    printf("No Whirlpool support\n");
        +    return(0);
        +}
        +#else
        +
        +/* ISO/IEC 10118-3 test vector set */
        +unsigned char iso_test_1[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x19,0xFA,0x61,0xD7,0x55,0x22,0xA4,0x66,
        +	0x9B,0x44,0xE3,0x9C,0x1D,0x2E,0x17,0x26,
        +	0xC5,0x30,0x23,0x21,0x30,0xD4,0x07,0xF8,
        +	0x9A,0xFE,0xE0,0x96,0x49,0x97,0xF7,0xA7,
        +	0x3E,0x83,0xBE,0x69,0x8B,0x28,0x8F,0xEB,
        +	0xCF,0x88,0xE3,0xE0,0x3C,0x4F,0x07,0x57,
        +	0xEA,0x89,0x64,0xE5,0x9B,0x63,0xD9,0x37,
        +	0x08,0xB1,0x38,0xCC,0x42,0xA6,0x6E,0xB3 };
        +
        +unsigned char iso_test_2[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x8A,0xCA,0x26,0x02,0x79,0x2A,0xEC,0x6F,
        +	0x11,0xA6,0x72,0x06,0x53,0x1F,0xB7,0xD7,
        +	0xF0,0xDF,0xF5,0x94,0x13,0x14,0x5E,0x69,
        +	0x73,0xC4,0x50,0x01,0xD0,0x08,0x7B,0x42,
        +	0xD1,0x1B,0xC6,0x45,0x41,0x3A,0xEF,0xF6,
        +	0x3A,0x42,0x39,0x1A,0x39,0x14,0x5A,0x59,
        +	0x1A,0x92,0x20,0x0D,0x56,0x01,0x95,0xE5,
        +	0x3B,0x47,0x85,0x84,0xFD,0xAE,0x23,0x1A };
        +
        +unsigned char iso_test_3[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x4E,0x24,0x48,0xA4,0xC6,0xF4,0x86,0xBB,
        +	0x16,0xB6,0x56,0x2C,0x73,0xB4,0x02,0x0B,
        +	0xF3,0x04,0x3E,0x3A,0x73,0x1B,0xCE,0x72,
        +	0x1A,0xE1,0xB3,0x03,0xD9,0x7E,0x6D,0x4C,
        +	0x71,0x81,0xEE,0xBD,0xB6,0xC5,0x7E,0x27,
        +	0x7D,0x0E,0x34,0x95,0x71,0x14,0xCB,0xD6,
        +	0xC7,0x97,0xFC,0x9D,0x95,0xD8,0xB5,0x82,
        +	0xD2,0x25,0x29,0x20,0x76,0xD4,0xEE,0xF5 };
        +
        +unsigned char iso_test_4[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x37,0x8C,0x84,0xA4,0x12,0x6E,0x2D,0xC6,
        +	0xE5,0x6D,0xCC,0x74,0x58,0x37,0x7A,0xAC,
        +	0x83,0x8D,0x00,0x03,0x22,0x30,0xF5,0x3C,
        +	0xE1,0xF5,0x70,0x0C,0x0F,0xFB,0x4D,0x3B,
        +	0x84,0x21,0x55,0x76,0x59,0xEF,0x55,0xC1,
        +	0x06,0xB4,0xB5,0x2A,0xC5,0xA4,0xAA,0xA6,
        +	0x92,0xED,0x92,0x00,0x52,0x83,0x8F,0x33,
        +	0x62,0xE8,0x6D,0xBD,0x37,0xA8,0x90,0x3E };
        +
        +unsigned char iso_test_5[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0xF1,0xD7,0x54,0x66,0x26,0x36,0xFF,0xE9,
        +	0x2C,0x82,0xEB,0xB9,0x21,0x2A,0x48,0x4A,
        +	0x8D,0x38,0x63,0x1E,0xAD,0x42,0x38,0xF5,
        +	0x44,0x2E,0xE1,0x3B,0x80,0x54,0xE4,0x1B,
        +	0x08,0xBF,0x2A,0x92,0x51,0xC3,0x0B,0x6A,
        +	0x0B,0x8A,0xAE,0x86,0x17,0x7A,0xB4,0xA6,
        +	0xF6,0x8F,0x67,0x3E,0x72,0x07,0x86,0x5D,
        +	0x5D,0x98,0x19,0xA3,0xDB,0xA4,0xEB,0x3B };
        +
        +unsigned char iso_test_6[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0xDC,0x37,0xE0,0x08,0xCF,0x9E,0xE6,0x9B,
        +	0xF1,0x1F,0x00,0xED,0x9A,0xBA,0x26,0x90,
        +	0x1D,0xD7,0xC2,0x8C,0xDE,0xC0,0x66,0xCC,
        +	0x6A,0xF4,0x2E,0x40,0xF8,0x2F,0x3A,0x1E,
        +	0x08,0xEB,0xA2,0x66,0x29,0x12,0x9D,0x8F,
        +	0xB7,0xCB,0x57,0x21,0x1B,0x92,0x81,0xA6,
        +	0x55,0x17,0xCC,0x87,0x9D,0x7B,0x96,0x21,
        +	0x42,0xC6,0x5F,0x5A,0x7A,0xF0,0x14,0x67 };
        +
        +unsigned char iso_test_7[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x46,0x6E,0xF1,0x8B,0xAB,0xB0,0x15,0x4D,
        +	0x25,0xB9,0xD3,0x8A,0x64,0x14,0xF5,0xC0,
        +	0x87,0x84,0x37,0x2B,0xCC,0xB2,0x04,0xD6,
        +	0x54,0x9C,0x4A,0xFA,0xDB,0x60,0x14,0x29,
        +	0x4D,0x5B,0xD8,0xDF,0x2A,0x6C,0x44,0xE5,
        +	0x38,0xCD,0x04,0x7B,0x26,0x81,0xA5,0x1A,
        +	0x2C,0x60,0x48,0x1E,0x88,0xC5,0xA2,0x0B,
        +	0x2C,0x2A,0x80,0xCF,0x3A,0x9A,0x08,0x3B };
        +
        +unsigned char iso_test_8[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x2A,0x98,0x7E,0xA4,0x0F,0x91,0x70,0x61,
        +	0xF5,0xD6,0xF0,0xA0,0xE4,0x64,0x4F,0x48,
        +	0x8A,0x7A,0x5A,0x52,0xDE,0xEE,0x65,0x62,
        +	0x07,0xC5,0x62,0xF9,0x88,0xE9,0x5C,0x69,
        +	0x16,0xBD,0xC8,0x03,0x1B,0xC5,0xBE,0x1B,
        +	0x7B,0x94,0x76,0x39,0xFE,0x05,0x0B,0x56,
        +	0x93,0x9B,0xAA,0xA0,0xAD,0xFF,0x9A,0xE6,
        +	0x74,0x5B,0x7B,0x18,0x1C,0x3B,0xE3,0xFD };
        +
        +unsigned char iso_test_9[WHIRLPOOL_DIGEST_LENGTH] = {
        +	0x0C,0x99,0x00,0x5B,0xEB,0x57,0xEF,0xF5,
        +	0x0A,0x7C,0xF0,0x05,0x56,0x0D,0xDF,0x5D,
        +	0x29,0x05,0x7F,0xD8,0x6B,0x20,0xBF,0xD6,
        +	0x2D,0xEC,0xA0,0xF1,0xCC,0xEA,0x4A,0xF5,
        +	0x1F,0xC1,0x54,0x90,0xED,0xDC,0x47,0xAF,
        +	0x32,0xBB,0x2B,0x66,0xC3,0x4F,0xF9,0xAD,
        +	0x8C,0x60,0x08,0xAD,0x67,0x7F,0x77,0x12,
        +	0x69,0x53,0xB2,0x26,0xE4,0xED,0x8B,0x01 };
        +
        +int main (int argc,char *argv[])
        +{ unsigned char md[WHIRLPOOL_DIGEST_LENGTH];
        +  int		i;
        +  WHIRLPOOL_CTX	ctx;
        +
        +#ifdef OPENSSL_IA32_SSE2
        +    /* Alternative to this is to call OpenSSL_add_all_algorithms...
        +     * The below code is retained exclusively for debugging purposes. */
        +    { char      *env;
        +
        +	if ((env=getenv("OPENSSL_ia32cap")))
        +	    OPENSSL_ia32cap = strtoul (env,NULL,0);
        +    }
        +#endif
        +
        +    fprintf(stdout,"Testing Whirlpool ");
        +
        +    WHIRLPOOL("",0,md);
        +    if (memcmp(md,iso_test_1,sizeof(iso_test_1)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 1 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("a",1,md);
        +    if (memcmp(md,iso_test_2,sizeof(iso_test_2)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 2 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("abc",3,md);
        +    if (memcmp(md,iso_test_3,sizeof(iso_test_3)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 3 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("message digest",14,md);
        +    if (memcmp(md,iso_test_4,sizeof(iso_test_4)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 4 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("abcdefghijklmnopqrstuvwxyz",26,md);
        +    if (memcmp(md,iso_test_5,sizeof(iso_test_5)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 5 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL(	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        +		"abcdefghijklmnopqrstuvwxyz"
        +		"0123456789",62,md);
        +    if (memcmp(md,iso_test_6,sizeof(iso_test_6)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 6 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL(	"1234567890""1234567890""1234567890""1234567890"
        +		"1234567890""1234567890""1234567890""1234567890",80,md);
        +    if (memcmp(md,iso_test_7,sizeof(iso_test_7)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 7 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    WHIRLPOOL("abcdbcdecdefdefgefghfghighijhijk",32,md);
        +    if (memcmp(md,iso_test_8,sizeof(iso_test_8)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 8 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        + 
        +    WHIRLPOOL_Init (&ctx);
        +    for (i=0;i<1000000;i+=288)
        +	WHIRLPOOL_Update (&ctx,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
        +				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
        +				(1000000-i)<288?1000000-i:288);
        +    WHIRLPOOL_Final (md,&ctx);
        +    if (memcmp(md,iso_test_9,sizeof(iso_test_9)))
        +    {   fflush(stdout);
        +	fprintf(stderr,"\nTEST 9 of 9 failed.\n");
        +	return 1;
        +    }
        +    else
        +	fprintf(stdout,"."); fflush(stdout);
        +
        +    fprintf(stdout," passed.\n"); fflush(stdout);
        +
        +  return 0;
        +}
        +#endif
        diff --git a/vendor/openssl/openssl/times/090/586-100.nt b/vendor/openssl/openssl/times/090/586-100.nt
        new file mode 100644
        index 000000000..297ec3e7f
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/090/586-100.nt
        @@ -0,0 +1,32 @@
        +SSLeay 0.9.0 08-Apr-1998
        +built on Wed Apr  8 12:47:17 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(
        +ptr2)
        +C flags:cl /MD /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN
        +-DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 92.25k      256.80k      347.01k      380.40k      390.31k
        +mdc2               240.72k      251.10k      252.00k      250.80k      251.40k
        +md5               1013.61k     5651.94k    11831.61k    16294.89k    17901.43k
        +hmac(md5)          419.50k     2828.07k     7770.11k    13824.34k    17091.70k
        +sha1               524.31k     2721.45k     5216.15k     6766.10k     7308.42k
        +rmd160             462.09k     2288.59k     4260.77k     5446.44k     5841.65k
        +rc4               7895.90k    10326.73k    10555.43k    10728.22k    10429.44k
        +des cbc           2036.86k     2208.92k     2237.68k     2237.20k     2181.35k
        +des ede3           649.92k      739.42k      749.07k      748.86k      738.27k
        +idea cbc           823.19k      885.10k      894.92k      896.45k      891.87k
        +rc2 cbc            792.63k      859.00k      867.45k      868.96k      865.30k
        +rc5-32/12 cbc     3502.26k     4026.79k     4107.23k     4121.76k     4073.72k
        +blowfish cbc      3752.96k     4026.79k     4075.31k     3965.87k     3892.26k
        +cast cbc          2566.27k     2807.43k     2821.79k     2792.48k     2719.34k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0179s   0.0020s     56.0    501.7
        +rsa 1024 bits   0.0950s   0.0060s     10.5    166.6
        +rsa 2048 bits   0.6299s   0.0209s      1.6     47.8
        +rsa 4096 bits   4.5870s   0.0787s      0.2     12.7
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0180s   0.0339s     55.6     29.5
        +dsa 1024 bits   0.0555s   0.1076s     18.0      9.3
        +dsa 2048 bits   0.1971s   0.3918s      5.1      2.6
        +
        diff --git a/vendor/openssl/openssl/times/091/486-50.nt b/vendor/openssl/openssl/times/091/486-50.nt
        new file mode 100644
        index 000000000..84820d9c6
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/486-50.nt
        @@ -0,0 +1,30 @@
        +486-50 NT 4.0
        +
        +SSLeay 0.9.1a 06-Jul-1998
        +built on Sat Jul 18 18:03:20 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
        +C flags:cl /MD /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM /Fdout32
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 28.77k       80.30k      108.50k      118.98k      122.47k
        +mdc2                51.52k       54.06k       54.54k       54.65k       54.62k
        +md5                304.39k     1565.04k     3061.54k     3996.10k     4240.10k
        +hmac(md5)          119.53k      793.23k     2061.29k     3454.95k     4121.76k
        +sha1               127.51k      596.93k     1055.54k     1313.84k     1413.18k
        +rmd160             128.50k      572.49k     1001.03k     1248.01k     1323.63k
        +rc4               1224.40k     1545.11k     1590.29k     1600.20k     1576.90k
        +des cbc            448.19k      503.45k      512.30k      513.30k      508.23k
        +des ede3           148.66k      162.48k      163.68k      163.94k      164.24k
        +idea cbc           194.18k      211.10k      212.99k      213.18k      212.64k
        +rc2 cbc            245.78k      271.01k      274.12k      274.38k      273.52k
        +rc5-32/12 cbc     1252.48k     1625.20k     1700.03k     1711.12k     1677.18k
        +blowfish cbc       725.16k      828.26k      850.01k      846.99k      833.79k
        +cast cbc           643.30k      717.22k      739.48k      741.57k      735.33k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0904s   0.0104s     11.1     96.2
        +rsa 1024 bits   0.5968s   0.0352s      1.7     28.4
        +rsa 2048 bits   3.8860s   0.1017s      0.3      9.8
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.1006s   0.1249s      9.9      8.0
        +dsa 1024 bits   0.3306s   0.4093s      3.0      2.4
        +dsa 2048 bits   0.9454s   1.1707s      1.1      0.9
        diff --git a/vendor/openssl/openssl/times/091/586-100.lnx b/vendor/openssl/openssl/times/091/586-100.lnx
        new file mode 100644
        index 000000000..92892a672
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/586-100.lnx
        @@ -0,0 +1,32 @@
        +Pentium 100mhz, linux
        +
        +SSLeay 0.9.0a 14-Apr-1998
        +built on Fri Apr 17 08:47:07 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 56.65k      153.88k      208.47k      229.03k      237.57k
        +mdc2               189.59k      204.95k      206.93k      208.90k      209.56k
        +md5               1019.48k     5882.41k    12085.42k    16376.49k    18295.47k
        +hmac(md5)          415.86k     2887.85k     7891.29k    13894.66k    17446.23k
        +sha1               540.68k     2791.96k     5289.30k     6813.01k     7432.87k
        +rmd160             298.37k     1846.87k     3869.10k     5273.94k     5892.78k
        +rc4               7870.87k    10438.10k    10857.13k    10729.47k    10788.86k
        +des cbc           1960.60k     2226.37k     2241.88k     2054.83k     2181.80k
        +des ede3           734.44k      739.69k      779.43k      750.25k      772.78k
        +idea cbc           654.07k      711.00k      716.89k      718.51k      720.90k
        +rc2 cbc            648.83k      701.91k      708.61k      708.95k      709.97k
        +rc5-32/12 cbc     3504.71k     4054.76k     4131.41k     4105.56k     4134.23k
        +blowfish cbc      3762.25k     4313.79k     4460.54k     4356.78k     4317.18k
        +cast cbc          2755.01k     3038.91k     3076.44k     3027.63k     2998.27k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0195s   0.0019s     51.4    519.9
        +rsa 1024 bits   0.1000s   0.0059s     10.0    168.2
        +rsa 2048 bits   0.6406s   0.0209s      1.6     47.8
        +rsa 4096 bits   4.6100s   0.0787s      0.2     12.7
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0188s   0.0360s     53.1     27.8
        +dsa 1024 bits   0.0570s   0.1126s     17.5      8.9
        +dsa 2048 bits   0.1990s   0.3954s      5.0      2.5
        +
        diff --git a/vendor/openssl/openssl/times/091/68000.bsd b/vendor/openssl/openssl/times/091/68000.bsd
        new file mode 100644
        index 000000000..a3a14e808
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/68000.bsd
        @@ -0,0 +1,32 @@
        +Motorolla 68020 20mhz, NetBSD
        +
        +SSLeay 0.9.0t 29-May-1998
        +built on Fri Jun  5 12:42:23 EST 1998
        +options:bn(64,32) md2(char) rc4(idx,int) des(idx,cisc,16,long) idea(int) blowfish(idx) 
        +C flags:gcc -DTERMIOS -O3 -fomit-frame-pointer -Wall -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               2176.00      5994.67      8079.73      8845.18      9077.01 
        +mdc2              5730.67      6122.67      6167.66      6176.51      6174.87 
        +md5                 29.10k      127.31k      209.66k      250.50k      263.99k
        +hmac(md5)           12.33k       73.02k      160.17k      228.04k      261.15k
        +sha1                11.27k       49.37k       84.31k      102.40k      109.23k
        +rmd160              11.69k       48.62k       78.76k       93.15k       98.41k
        +rc4                117.96k      148.94k      152.57k      153.09k      152.92k
        +des cbc             27.13k       30.06k       30.38k       30.38k       30.53k
        +des ede3            10.51k       10.94k       11.01k       11.01k       11.01k
        +idea cbc            26.74k       29.23k       29.45k       29.60k       29.74k
        +rc2 cbc             34.27k       39.39k       40.03k       40.07k       40.16k
        +rc5-32/12 cbc       64.31k       83.18k       85.70k       86.70k       87.09k
        +blowfish cbc        48.86k       59.18k       60.07k       60.42k       60.78k
        +cast cbc            42.67k       50.01k       50.86k       51.20k       51.37k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.7738s   0.0774s      1.3     12.9
        +rsa 1024 bits   4.3967s   0.2615s      0.2      3.8
        +rsa 2048 bits  29.5200s   0.9664s      0.0      1.0
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.7862s   0.9709s      1.3      1.0
        +dsa 1024 bits   2.5375s   3.1625s      0.4      0.3
        +dsa 2048 bits   9.2150s  11.8200s      0.1      0.1
        +
        +
        diff --git a/vendor/openssl/openssl/times/091/686-200.lnx b/vendor/openssl/openssl/times/091/686-200.lnx
        new file mode 100644
        index 000000000..bb857d48d
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/686-200.lnx
        @@ -0,0 +1,32 @@
        +Pentium Pro 200mhz, linux
        +
        +SSLeay 0.9.0d 26-Apr-1998
        +built on Sun Apr 26 10:25:33 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                130.58k      364.54k      499.24k      545.79k      561.66k
        +mdc2               526.68k      579.72k      588.37k      588.80k      589.82k
        +md5               1917.71k    11434.69k    22512.21k    29495.30k    32677.89k
        +hmac(md5)          749.18k     5264.83k    14227.20k    25018.71k    31760.38k
        +sha1              1343.83k     6436.29k    11702.78k    14664.70k    15829.67k
        +rmd160            1038.05k     5138.77k     8985.51k    10985.13k    11799.21k
        +rc4              14891.04k    21334.06k    22376.79k    22579.54k    22574.42k
        +des cbc           4131.97k     4568.31k     4645.29k     4631.21k     4572.73k
        +des ede3          1567.17k     1631.13k     1657.32k     1653.08k     1643.86k
        +idea cbc          2427.23k     2671.21k     2716.67k     2723.84k     2733.40k
        +rc2 cbc           1629.90k     1767.38k     1788.50k     1797.12k     1799.51k
        +rc5-32/12 cbc    10290.55k    13161.60k    13744.55k    14011.73k    14123.01k
        +blowfish cbc      5896.42k     6920.77k     7122.01k     7151.62k     7146.15k
        +cast cbc          6037.71k     6935.19k     7101.35k     7145.81k     7116.12k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0070s   0.0007s    142.6   1502.9
        +rsa 1024 bits   0.0340s   0.0019s     29.4    513.3
        +rsa 2048 bits   0.2087s   0.0066s      4.8    151.3
        +rsa 4096 bits   1.4700s   0.0242s      0.7     41.2
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0064s   0.0121s    156.1     82.9
        +dsa 1024 bits   0.0184s   0.0363s     54.4     27.5
        +dsa 2048 bits   0.0629s   0.1250s     15.9      8.0
        +
        diff --git a/vendor/openssl/openssl/times/091/alpha064.osf b/vendor/openssl/openssl/times/091/alpha064.osf
        new file mode 100644
        index 000000000..a8e7fdfd6
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/alpha064.osf
        @@ -0,0 +1,32 @@
        +Alpha EV4.5 (21064) 275mhz, OSF1 V4.0
        +SSLeay 0.9.0g 01-May-1998
        +built on Mon May  4 17:26:09 CST 1998
        +options:bn(64,64) md2(int) rc4(ptr,int) des(idx,cisc,4,long) idea(int) blowfish(idx) 
        +C flags:cc -tune host -O4 -readonly_strings
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                119.58k      327.48k      443.28k      480.09k      495.16k
        +mdc2               436.67k      456.35k      465.42k      466.57k      469.01k
        +md5               1459.34k     6566.46k    11111.91k    13375.30k    14072.60k
        +hmac(md5)          597.90k     3595.45k     8180.88k    12099.49k    13884.46k
        +sha1               707.01k     3253.09k     6131.73k     7798.23k     8439.67k
        +rmd160             618.57k     2729.07k     4711.33k     5825.16k     6119.23k
        +rc4               8796.43k     9393.62k     9548.88k     9378.77k     9472.57k
        +des cbc           2165.97k     2514.90k     2586.27k     2572.93k     2639.08k
        +des ede3           945.44k     1004.03k     1005.96k     1017.33k     1020.85k
        +idea cbc          1498.81k     1629.11k     1637.28k     1625.50k     1641.11k
        +rc2 cbc           1866.00k     2044.92k     2067.12k     2064.00k     2068.96k
        +rc5-32/12 cbc     4366.97k     5521.32k     5687.50k     5729.16k     5736.96k
        +blowfish cbc      3997.31k     4790.60k     4937.84k     4954.56k     5024.85k
        +cast cbc          2900.19k     3673.30k     3803.73k     3823.93k     3890.25k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0069s   0.0006s    144.2   1545.8
        +rsa 1024 bits   0.0304s   0.0018s     32.9    552.6
        +rsa 2048 bits   0.1887s   0.0062s      5.3    161.4
        +rsa 4096 bits   1.3667s   0.0233s      0.7     42.9
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0067s   0.0123s    149.6     81.1
        +dsa 1024 bits   0.0177s   0.0332s     56.6     30.1
        +dsa 2048 bits   0.0590s   0.1162s     16.9      8.6
        +
        +
        diff --git a/vendor/openssl/openssl/times/091/alpha164.lnx b/vendor/openssl/openssl/times/091/alpha164.lnx
        new file mode 100644
        index 000000000..c99466269
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/alpha164.lnx
        @@ -0,0 +1,32 @@
        +Alpha EV5.6 (21164A) 533mhz, Linux 2.0.32
        +
        +SSLeay 0.9.0p 22-May-1998
        +built on Sun May 27 14:23:38 GMT 2018
        +options:bn(64,64) md2(int) rc4(ptr,int) des(idx,risc1,16,long) idea(int) blowfish(idx) 
        +C flags:gcc -O3
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                295.78k      825.34k     1116.42k     1225.10k     1262.65k
        +mdc2               918.16k     1017.55k     1032.18k     1034.24k     1035.60k
        +md5               3574.93k    15517.05k    25482.67k    30434.31k    32210.51k
        +hmac(md5)         1261.54k     7757.15k    18025.46k    27081.21k    31653.27k
        +sha1              2251.89k    10056.84k    16990.19k    20651.04k    21973.29k
        +rmd160            1615.49k     7017.13k    11601.11k    13875.62k    14690.31k
        +rc4              22435.16k    24476.40k    24349.95k    23042.36k    24581.53k
        +des cbc           5198.38k     6559.04k     6775.43k     6827.87k     6875.82k
        +des ede3          2257.73k     2602.18k     2645.60k     2657.12k     2670.59k
        +idea cbc          3694.42k     4125.61k     4180.74k     4193.28k     4192.94k
        +rc2 cbc           4642.47k     5323.85k     5415.42k     5435.86k     5434.03k
        +rc5-32/12 cbc     9705.26k    13277.79k    13843.46k    13989.66k    13987.57k
        +blowfish cbc      7861.28k    10852.34k    11447.98k    11616.97k    11667.54k
        +cast cbc          6718.13k     8599.98k     8967.17k     9070.81k     9099.28k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0018s   0.0002s    555.9   6299.5
        +rsa 1024 bits   0.0081s   0.0005s    123.3   2208.7
        +rsa 2048 bits   0.0489s   0.0015s     20.4    648.5
        +rsa 4096 bits   0.3402s   0.0057s      2.9    174.7
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0019s   0.0032s    529.0    310.2
        +dsa 1024 bits   0.0047s   0.0086s    214.1    115.7
        +dsa 2048 bits   0.0150s   0.0289s     66.7     34.6
        +
        diff --git a/vendor/openssl/openssl/times/091/alpha164.osf b/vendor/openssl/openssl/times/091/alpha164.osf
        new file mode 100644
        index 000000000..df712c689
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/alpha164.osf
        @@ -0,0 +1,31 @@
        +Alpha EV5.6 (21164A) 400mhz, OSF1 V4.0
        +
        +SSLeay 0.9.0 10-Apr-1998
        +built on Sun Apr 19 07:54:37 EST 1998
        +options:bn(64,64) md2(int) rc4(ptr,int) des(ptr,risc2,4,int) idea(int) blowfish(idx) 
        +C flags:cc -O4 -tune host -fast
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                276.30k      762.07k     1034.35k     1134.07k     1160.53k
        +mdc2               814.99k      845.83k      849.09k      850.33k      849.24k
        +md5               2468.43k    10945.27k    17963.48k    21430.89k    22544.38k
        +hmac(md5)         1002.48k     6023.98k    13430.99k    19344.17k    22351.80k
        +sha1              1984.93k     8882.47k    14856.47k    17878.70k    18955.10k
        +rmd160            1286.96k     5595.52k     9167.00k    10957.74k    11582.30k
        +rc4              15948.15k    16710.29k    16793.20k    17929.50k    18474.56k
        +des cbc           3416.04k     4149.37k     4296.25k     4328.89k     4327.57k
        +des ede3          1540.14k     1683.36k     1691.14k     1705.90k     1705.22k
        +idea cbc          2795.87k     3192.93k     3238.13k     3238.17k     3256.66k
        +rc2 cbc           3529.00k     4069.93k     4135.79k     4135.25k     4160.07k
        +rc5-32/12 cbc     7212.35k     9849.71k    10260.91k    10423.38k    10439.99k
        +blowfish cbc      6061.75k     8363.50k     8706.80k     8779.40k     8784.55k
        +cast cbc          5401.75k     6433.31k     6638.18k     6662.40k     6702.80k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0022s   0.0002s    449.6   4916.2
        +rsa 1024 bits   0.0105s   0.0006s     95.3   1661.2
        +rsa 2048 bits   0.0637s   0.0020s     15.7    495.6
        +rsa 4096 bits   0.4457s   0.0075s      2.2    132.7
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0028s   0.0048s    362.2    210.4
        +dsa 1024 bits   0.0064s   0.0123s    155.2     81.6
        +dsa 2048 bits   0.0201s   0.0394s     49.7     25.4
        diff --git a/vendor/openssl/openssl/times/091/mips-rel.pl b/vendor/openssl/openssl/times/091/mips-rel.pl
        new file mode 100644
        index 000000000..4b2509315
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/mips-rel.pl
        @@ -0,0 +1,21 @@
        +#!/usr/local/bin/perl
        +
        +&doit(100,"Pentium   100 32",0.0195,0.1000,0.6406,4.6100);	# pentium-100
        +&doit(200,"PPro      200 32",0.0070,0.0340,0.2087,1.4700);	# pentium-100
        +&doit( 25,"R3000      25 32",0.0860,0.4825,3.2417,23.8833);	# R3000-25
        +&doit(200,"R4400     200 32",0.0137,0.0717,0.4730,3.4367);	# R4400 32bit
        +&doit(180,"R10000    180 32",0.0061,0.0311,0.1955,1.3871);	# R10000 32bit
        +&doit(180,"R10000    180 64",0.0034,0.0149,0.0880,0.5933);	# R10000 64bit
        +&doit(400,"DEC 21164 400 64",0.0022,0.0105,0.0637,0.4457);	# R10000 64bit
        +
        +sub doit
        +	{
        +	local($mhz,$label,@data)=@_;
        +
        +	for ($i=0; $i <= $#data; $i++)
        +		{
        +		$data[$i]=1/$data[$i]*200/$mhz;
        +		}
        +	printf("%s %6.1f %6.1f %6.1f %6.1f\n",$label,@data);
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/091/r10000.irx b/vendor/openssl/openssl/times/091/r10000.irx
        new file mode 100644
        index 000000000..237ee5d19
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/r10000.irx
        @@ -0,0 +1,37 @@
        +MIPS R10000 32kI+32kD 180mhz, IRIX 6.4
        +
        +Using crypto/bn/mips3.s
        +
        +This is built for n32, which is faster for all benchmarks than the n64
        +compilation model
        +
        +SSLeay 0.9.0b 19-Apr-1998
        +built on Sat Apr 25 12:43:14 EST 1998
        +options:bn(64,64) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int) blowfish(ptr) 
        +C flags:cc -use_readonly_const -O2 -DTERMIOS -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                126.38k      349.38k      472.67k      517.01k      529.81k
        +mdc2               501.64k      545.87k      551.80k      553.64k      554.41k
        +md5               1825.77k     7623.64k    12630.47k    15111.74k    16012.09k
        +hmac(md5)          780.81k     4472.86k     9667.22k    13802.67k    15777.89k
        +sha1              1375.52k     6213.91k    11037.30k    13682.01k    14714.09k
        +rmd160             856.72k     3454.40k     5598.33k     6689.94k     7073.48k
        +rc4              11260.93k    13311.50k    13360.05k    13322.17k    13364.39k
        +des cbc           2770.78k     3055.42k     3095.18k     3092.48k     3103.03k
        +des ede3          1023.22k     1060.58k     1063.81k     1070.37k     1064.54k
        +idea cbc          3029.09k     3334.30k     3375.29k     3375.65k     3380.64k
        +rc2 cbc           2307.45k     2470.72k     2501.25k     2500.68k     2500.55k
        +rc5-32/12 cbc     6770.91k     8629.89k     8909.58k     9009.64k     9044.95k
        +blowfish cbc      4796.53k     5598.20k     5717.14k     5755.11k     5749.86k
        +cast cbc          3986.20k     4426.17k     4465.04k     4476.84k     4475.08k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0034s   0.0003s    296.1   3225.4
        +rsa 1024 bits   0.0139s   0.0008s     71.8   1221.8
        +rsa 2048 bits   0.0815s   0.0026s     12.3    380.3
        +rsa 4096 bits   0.5656s   0.0096s      1.8    103.7
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0034s   0.0061s    290.8    164.9
        +dsa 1024 bits   0.0084s   0.0161s    119.1     62.3
        +dsa 2048 bits   0.0260s   0.0515s     38.5     19.4
        +
        diff --git a/vendor/openssl/openssl/times/091/r3000.ult b/vendor/openssl/openssl/times/091/r3000.ult
        new file mode 100644
        index 000000000..ecd33908b
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/r3000.ult
        @@ -0,0 +1,32 @@
        +MIPS R3000 64kI+64kD 25mhz, ultrix 4.3
        +
        +SSLeay 0.9.0b 19-Apr-1998
        +built on Thu Apr 23 07:22:31 EST 1998
        +options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int) blowfish(idx) 
        +C flags:cc -O2 -DL_ENDIAN -DNOPROTO -DNOCONST
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 14.63k       40.65k       54.70k       60.07k       61.78k
        +mdc2                29.43k       37.27k       38.23k       38.57k       38.60k
        +md5                140.04k      676.59k     1283.84k     1654.10k     1802.24k
        +hmac(md5)           60.51k      378.90k      937.82k     1470.46k     1766.74k
        +sha1                60.77k      296.79k      525.40k      649.90k      699.05k
        +rmd160              48.82k      227.16k      417.19k      530.31k      572.05k
        +rc4                904.76k      996.20k     1007.53k     1015.65k     1010.35k
        +des cbc            178.87k      209.39k      213.42k      215.55k      214.53k
        +des ede3            74.25k       79.30k       80.40k       80.21k       80.14k
        +idea cbc           181.02k      209.37k      214.44k      214.36k      213.83k
        +rc2 cbc            161.52k      184.98k      187.99k      188.76k      189.05k
        +rc5-32/12 cbc      398.99k      582.91k      614.66k      626.07k      621.87k
        +blowfish cbc       296.38k      387.69k      405.50k      412.57k      410.05k
        +cast cbc           214.76k      260.63k      266.92k      268.63k      258.26k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0870s   0.0089s     11.5    112.4
        +rsa 1024 bits   0.4881s   0.0295s      2.0     33.9
        +rsa 2048 bits   3.2750s   0.1072s      0.3      9.3
        +rsa 4096 bits  23.9833s   0.4093s      0.0      2.4
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0898s   0.1706s     11.1      5.9
        +dsa 1024 bits   0.2847s   0.5565s      3.5      1.8
        +dsa 2048 bits   1.0267s   2.0433s      1.0      0.5
        +
        diff --git a/vendor/openssl/openssl/times/091/r4400.irx b/vendor/openssl/openssl/times/091/r4400.irx
        new file mode 100644
        index 000000000..9b96ca110
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/091/r4400.irx
        @@ -0,0 +1,32 @@
        +R4400 16kI+16kD 200mhz, Irix 5.3
        +
        +SSLeay 0.9.0e 27-Apr-1998
        +built on Sun Apr 26 07:26:05 PDT 1998
        +options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int) blowfish(ptr) 
        +C flags:cc -O2 -use_readonly_const -DTERMIOS -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 79.80k      220.59k      298.01k      327.06k      338.60k
        +mdc2               262.74k      285.30k      289.16k      288.36k      288.49k
        +md5                930.35k     4167.13k     7167.91k     8678.23k     9235.86k
        +hmac(md5)          399.44k     2367.57k     5370.74k     7884.28k     9076.98k
        +sha1               550.96k     2488.17k     4342.76k     5362.50k     5745.40k
        +rmd160             424.58k     1752.83k     2909.67k     3486.08k     3702.89k
        +rc4               6687.79k     7834.63k     7962.61k     8035.65k     7915.28k
        +des cbc           1544.20k     1725.94k     1748.35k     1758.17k     1745.61k
        +des ede3           587.29k      637.75k      645.93k      643.17k      646.01k
        +idea cbc          1575.52k     1719.75k     1732.41k     1736.69k     1740.11k
        +rc2 cbc           1496.21k     1629.90k     1643.19k     1652.14k     1646.62k
        +rc5-32/12 cbc     3452.48k     4276.47k     4390.74k     4405.25k     4400.12k
        +blowfish cbc      2354.58k     3242.36k     3401.11k     3433.65k     3383.65k
        +cast cbc          1942.22k     2152.28k     2187.51k     2185.67k     2177.20k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0130s   0.0014s     76.9    729.8
        +rsa 1024 bits   0.0697s   0.0043s     14.4    233.9
        +rsa 2048 bits   0.4664s   0.0156s      2.1     64.0
        +rsa 4096 bits   3.4067s   0.0586s      0.3     17.1
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0140s   0.0261s     71.4     38.4
        +dsa 1024 bits   0.0417s   0.0794s     24.0     12.6
        +dsa 2048 bits   0.1478s   0.2929s      6.8      3.4
        +
        diff --git a/vendor/openssl/openssl/times/100.lnx b/vendor/openssl/openssl/times/100.lnx
        new file mode 100644
        index 000000000..d0f45371d
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/100.lnx
        @@ -0,0 +1,32 @@
        +SSLeay 0.8.4c 03-Aug-1999
        +built on Tue Nov  4 02:52:29 EST 1997
        +options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                53.27k      155.95k      201.30k      216.41k      236.78k
        +mdc2              192.98k      207.98k      206.76k      206.17k      208.87k
        +md5               993.15k     5748.27k    11944.70k    16477.53k    18287.27k
        +hmac(md5)         404.97k     2787.58k     7690.07k    13744.43k    17601.88k
        +sha1              563.24k     2851.67k     5363.71k     6879.23k     7441.07k
        +rc4              7876.70k    10400.85k    10825.90k    10943.49k    10745.17k
        +des cbc          2047.39k     2188.25k     2188.29k     2239.49k     2233.69k
        +des ede3          660.55k      764.01k      773.55k      779.21k      780.97k
        +idea cbc          653.93k      708.48k      715.43k      719.87k      720.90k
        +rc2 cbc           648.08k      702.23k      708.78k      711.00k      709.97k
        +blowfish cbc     3764.39k     4288.66k     4375.04k     4497.07k     4423.68k
        +cast cbc         2757.14k     2993.75k     3035.31k     3078.90k     3055.62k
        +
        +blowfish cbc     3258.81k     3673.47k     3767.30k     3774.12k     3719.17k
        +cast cbc         2677.05k     3164.78k     3273.05k     3287.38k     3244.03k
        +
        +
        +                  sign    verify
        +rsa  512 bits   0.0213s   0.0020s
        +rsa 1024 bits   0.1073s   0.0063s
        +rsa 2048 bits   0.6873s   0.0224s
        +rsa 4096 bits   4.9333s   0.0845s
        +                  sign    verify
        +dsa  512 bits   0.0201s   0.0385s
        +dsa 1024 bits   0.0604s   0.1190s
        +dsa 2048 bits   0.2121s   0.4229s
        diff --git a/vendor/openssl/openssl/times/100.nt b/vendor/openssl/openssl/times/100.nt
        new file mode 100644
        index 000000000..0dd7cfc47
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/100.nt
        @@ -0,0 +1,29 @@
        +SSLeay 0.8.4c 03-Aug-1999
        +built on Tue Aug  3 09:49:58 EST 1999
        +options:bn(64,32) md2(int) rc4(ptr,int) des(idx,cisc,4,long) idea(int) blowfish(
        +ptr2)
        +C flags:cl /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN -DBN
        +_ASM -DMD5_ASM -DSHA1_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                93.07k      258.38k      349.03k      382.83k      392.87k
        +mdc2              245.80k      259.02k      259.34k      259.16k      260.14k
        +md5              1103.42k     6017.65k    12210.49k    16552.11k    18291.77k
        +hmac(md5)         520.15k     3394.00k     8761.86k    14593.96k    17742.40k
        +sha1              538.06k     2726.76k     5242.22k     6821.12k     7426.18k
        +rc4              8283.90k    10513.09k    10886.38k    10929.50k    10816.75k
        +des cbc          2073.10k     2232.91k     2251.61k     2256.46k     2232.44k
        +des ede3          758.85k      782.46k      786.14k      786.08k      781.24k
        +idea cbc          831.02k      892.63k      901.07k      903.48k      901.85k
        +rc2 cbc           799.89k      866.09k      873.96k      876.22k      874.03k
        +blowfish cbc     3835.32k     4418.78k     4511.94k     4494.54k     4416.92k
        +cast cbc         2974.68k     3272.71k     3313.04k     3335.17k     3261.51k
        +                  sign    verify
        +rsa  512 bits   0.0202s   0.0019s
        +rsa 1024 bits   0.1029s   0.0062s
        +rsa 2048 bits   0.6770s   0.0220s
        +rsa 4096 bits   4.8770s   0.0838s
        +                  sign    verify
        +dsa  512 bits   0.0191s   0.0364s
        +dsa 1024 bits   0.0590s   0.1141s
        +dsa 2048 bits   0.2088s   0.4171s
        diff --git a/vendor/openssl/openssl/times/200.lnx b/vendor/openssl/openssl/times/200.lnx
        new file mode 100644
        index 000000000..fd7e7f4e9
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/200.lnx
        @@ -0,0 +1,30 @@
        +This machine was slightly loaded :-(
        +
        +SSLeay 0.8.4c 03-Aug-1999
        +built on Tue Nov  4 02:52:29 EST 1997
        +options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               130.86k      365.31k      499.60k      547.75k      561.41k
        +mdc2              526.03k      581.38k      587.12k      586.31k      589.60k
        +md5              1919.49k    11173.23k    22387.60k    29553.47k    32587.21k
        +hmac(md5)         747.09k     5248.35k    14275.44k    24713.26k    31737.13k
        +sha1             1336.63k     6400.50k    11668.67k    14648.83k    15700.85k
        +rc4             15002.32k    21327.21k    22301.63k    22503.78k    22549.26k
        +des cbc          4115.16k     4521.08k     4632.37k     4607.28k     4570.57k
        +des ede3         1540.29k     1609.76k     1623.64k     1620.76k     1624.18k
        +idea cbc         2405.08k     2664.78k     2704.22k     2713.95k     2716.29k
        +rc2 cbc          1634.07k     1764.30k     1780.23k     1790.27k     1788.12k
        +blowfish cbc     5993.98k     6927.27k     7083.61k     7088.40k     7123.72k
        +cast cbc         5981.52k     6900.44k     7079.70k     7110.40k     7057.72k
        +                  sign    verify
        +rsa  512 bits   0.0085s   0.0007s
        +rsa 1024 bits   0.0377s   0.0020s
        +rsa 2048 bits   0.2176s   0.0067s
        +rsa 4096 bits   1.4800s   0.0242s
        +sign    verify
        +dsa  512 bits   0.0071s   0.0132s
        +dsa 1024 bits   0.0192s   0.0376s
        +dsa 2048 bits   0.0638s   0.1280s
        +
        diff --git a/vendor/openssl/openssl/times/486-66.dos b/vendor/openssl/openssl/times/486-66.dos
        new file mode 100644
        index 000000000..1644bf802
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/486-66.dos
        @@ -0,0 +1,22 @@
        +MS-dos static libs, 16bit C build, 16bit assember
        +
        +SSLeay 0.6.1
        +options:bn(32,16) md2(char) rc4(idx,int) des(ptr,long) idea(short)
        +C flags:cl /ALw /Gx- /Gf /f- /Ocgnotb2 /G2 /W3 /WX -DL_ENDIAN /nologo -DMSDOS -D
        +NO_SOCK
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             18.62k       55.54k       76.88k       85.39k       86.52k
        +md5             94.03k      442.06k      794.38k      974.51k     1061.31k
        +sha             38.37k      166.23k      272.78k      331.41k      353.77k
        +sha1            34.38k      147.77k      244.77k      292.57k      312.08k
        +rc4            641.25k      795.34k      817.16k      829.57k      817.16k
        +des cfb        111.46k      118.08k      120.69k      119.16k      119.37k
        +des cbc        122.96k      135.69k      137.10k      135.69k      135.40k
        +des ede3        48.01k       50.92k       50.32k       50.96k       50.96k
        +idea cfb        97.09k      100.21k      100.36k      101.14k      100.98k
        +idea cbc       102.08k      109.41k      111.46k      111.65k      110.52k
        +rc2 cfb        120.47k      125.55k      125.79k      125.55k      125.55k
        +rc2 cbc        129.77k      140.33k      143.72k      142.16k      141.85k
        +rsa  512 bits   0.264s
        +rsa 1024 bits   1.494s
        diff --git a/vendor/openssl/openssl/times/486-66.nt b/vendor/openssl/openssl/times/486-66.nt
        new file mode 100644
        index 000000000..b26a9005d
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/486-66.nt
        @@ -0,0 +1,22 @@
        +SSLeay 0.6.1 02-Jul-1996
        +built on Fri Jul 10 09:53:15 EST 1996
        +options:bn(64,32) md2(int) rc4(idx,int) des(idx,long) idea(int)
        +C flags:cl /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /nologo -DWIN32 -DL_ENDIAN /MD
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             38.27k      107.28k      145.43k      159.60k      164.15k
        +md5            399.00k     1946.13k     3610.80k     4511.94k     4477.27k
        +sha            182.04k      851.26k     1470.65k     1799.20k     1876.48k
        +sha1           151.83k      756.55k     1289.76k     1567.38k     1625.70k
        +rc4           1853.92k     2196.25k     2232.91k     2241.31k     2152.96k
        +des cfb        360.58k      382.69k      384.94k      386.07k      377.19k
        +des cbc        376.10k      431.87k      436.32k      437.78k      430.45k
        +des ede3       152.55k      160.38k      161.51k      161.33k      159.98k
        +idea cfb       245.59k      255.60k      256.65k      257.16k      254.61k
        +idea cbc       257.16k      276.12k      279.05k      279.11k      276.70k
        +rc2 cfb        280.25k      293.49k      294.74k      294.15k      291.47k
        +rc2 cbc        295.47k      321.57k      324.76k      324.76k      320.00k
        +rsa  512 bits   0.084s
        +rsa 1024 bits   0.495s
        +rsa 2048 bits   3.435s
        +
        diff --git a/vendor/openssl/openssl/times/486-66.w31 b/vendor/openssl/openssl/times/486-66.w31
        new file mode 100644
        index 000000000..381f149b3
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/486-66.w31
        @@ -0,0 +1,23 @@
        +Windows 3.1 DLL's, 16 bit C with 32bit assember
        +
        +SSLeay 0.6.1 02-Jul-1996
        +built on Wed Jul 10 09:53:15 EST 1996
        +options:bn(32,32) md2(char) rc4(idx,int) des(ptr,long) idea(short)
        +C flags:cl /ALw /Gx- /Gf /G2 /f- /Ocgnotb2 /W3 /WX -DL_ENDIAN /nologo -DWIN16
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             18.94k       54.27k       73.43k       80.91k       83.75k
        +md5             78.96k      391.26k      734.30k      919.80k      992.97k
        +sha             39.01k      168.04k      280.67k      336.08k      359.10k
        +sha1            35.20k      150.14k      247.31k      294.54k      313.94k
        +rc4            509.61k      655.36k      678.43k      677.02k      670.10k
        +des cfb         97.09k      104.69k      106.56k      105.70k      106.56k
        +des cbc        116.82k      129.77k      131.07k      131.07k      131.07k
        +des ede3        44.22k       47.90k       48.53k       48.47k       47.86k
        +idea cfb        83.49k       87.03k       87.03k       87.15k       87.73k
        +idea cbc        89.04k       96.23k       96.95k       97.81k       97.09k
        +rc2 cfb        108.32k      113.58k      113.78k      114.57k      114.77k
        +rc2 cbc        118.08k      131.07k      134.02k      134.02k      132.66k
        +rsa  512 bits   0.181s
        +rsa 1024 bits   0.846s
        +
        diff --git a/vendor/openssl/openssl/times/5.lnx b/vendor/openssl/openssl/times/5.lnx
        new file mode 100644
        index 000000000..1c1e392a2
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/5.lnx
        @@ -0,0 +1,29 @@
        +SSLeay 0.8.5g 24-Jan-1998
        +built on Tue Jan 27 08:11:42 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 56.55k      156.69k      211.63k      231.77k      238.71k
        +mdc2               192.26k      208.09k      210.09k      209.58k      210.26k
        +md5                991.04k     5745.51k    11932.67k    16465.24k    18306.39k
        +hmac(md5)          333.99k     2383.89k     6890.67k    13133.82k    17397.08k
        +sha1               571.68k     2883.88k     5379.07k     6880.26k     7443.80k
        +rmd160             409.41k     2212.91k     4225.45k     5456.55k     5928.28k
        +rc4               6847.57k     8596.22k     8901.80k     8912.90k     8850.09k
        +des cbc           2046.29k     2229.78k     2254.76k     2259.97k     2233.69k
        +des ede3           751.11k      779.95k      783.96k      784.38k      780.97k
        +idea cbc           653.40k      708.29k      718.42k      720.21k      720.90k
        +rc2 cbc            647.19k      702.46k      709.21k      710.66k      709.97k
        +rc5-32/12 cbc     3498.18k     4054.12k     4133.46k     4151.64k     4139.69k
        +blowfish cbc      3763.95k     4437.74k     4532.74k     4515.50k     4448.26k
        +cast cbc          2754.22k     3020.67k     3079.08k     3069.95k     3036.50k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0207s   0.0020s     48.3    511.3
        +rsa 1024 bits   0.1018s   0.0059s      9.8    169.6
        +rsa 2048 bits   0.6438s   0.0208s      1.6     48.0
        +rsa 4096 bits   4.6033s   0.0793s      0.2     12.6
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0190s   0.0359s     52.6     27.8
        +dsa 1024 bits   0.0566s   0.1109s     17.7      9.0
        +dsa 2048 bits   0.1988s   0.3915s      5.0      2.6
        diff --git a/vendor/openssl/openssl/times/586-085i.nt b/vendor/openssl/openssl/times/586-085i.nt
        new file mode 100644
        index 000000000..8a5797526
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-085i.nt
        @@ -0,0 +1,29 @@
        +SSLeay 0.8.5i 28-Jan-1998
        +built on Wed Jan 28 18:00:07 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
        +C flags:cl /MT /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                 92.74k      257.59k      348.16k      381.79k      392.14k
        +mdc2               227.65k      247.82k      249.90k      250.65k      250.20k
        +md5               1089.54k     5966.29k    12104.77k    16493.53k    18204.44k
        +hmac(md5)          513.53k     3361.36k     8725.41k    14543.36k    17593.56k
        +sha1               580.74k     2880.51k     5376.62k     6865.78k     7413.05k
        +rmd160             508.06k     2427.96k     4385.51k     5510.84k     5915.80k
        +rc4               8004.40k    10408.74k    10794.48k    10884.12k    10728.22k
        +des cbc           2057.24k     2222.97k     2246.79k     2209.39k     2223.44k
        +des ede3           739.42k      761.99k      765.48k      760.26k      760.97k
        +idea cbc           827.08k      889.60k      898.83k      901.15k      897.98k
        +rc2 cbc            795.64k      861.04k      871.13k      872.58k      871.13k
        +rc5-32/12 cbc     3597.17k     4139.66k     4204.39k     4223.02k     4204.39k
        +blowfish cbc      3807.47k     3996.10k     4156.07k     4204.39k     4105.62k
        +cast cbc          2777.68k     2814.21k     2892.62k     2916.76k     2868.88k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0178s   0.0018s     56.3    541.6
        +rsa 1024 bits   0.0945s   0.0059s     10.6    168.3
        +rsa 2048 bits   0.6269s   0.0208s      1.6     48.0
        +rsa 4096 bits   4.5560s   0.0784s      0.2     12.8
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0178s   0.0340s     56.2     29.4
        +dsa 1024 bits   0.0552s   0.1077s     18.1      9.3
        +dsa 2048 bits   0.1963s   0.3811s      5.1      2.6
        diff --git a/vendor/openssl/openssl/times/586-100.LN3 b/vendor/openssl/openssl/times/586-100.LN3
        new file mode 100644
        index 000000000..a6fa818f4
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.LN3
        @@ -0,0 +1,26 @@
        +SSLeay 0.8.3v 15-Oct-1997
        +built on Wed Oct 15 10:05:00 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DX86_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                56.27k      156.76k      211.46k      231.77k      238.71k
        +mdc2              188.74k      206.12k      207.70k      207.87k      208.18k
        +md5               991.56k     5718.31k    11748.61k    16090.79k    17850.37k
        +hmac(md5)         387.56k     2636.01k     7327.83k    13340.33k    17091.24k
        +sha1              463.55k     2274.18k     4071.17k     5072.90k     5447.68k
        +rc4              3673.94k     4314.52k     4402.26k     4427.09k     4407.30k
        +des cbc          2023.79k     2209.77k     2233.34k     2220.71k     2222.76k
        +des ede3          747.17k      778.54k      781.57k      778.24k      778.24k
        +idea cbc          614.64k      678.04k      683.52k      685.06k      685.40k
        +rc2 cbc           536.83k      574.10k      578.05k      579.24k      578.90k
        +blowfish cbc     3673.39k     4354.58k     4450.22k     4429.48k     4377.26k
        +                  sign    verify
        +rsa  512 bits   0.0217s   0.0021s
        +rsa 1024 bits   0.1083s   0.0064s
        +rsa 2048 bits   0.6867s   0.0223s
        +rsa 4096 bits   4.9400s   0.0846s
        +                  sign    verify
        +dsa  512 bits   0.0203s   0.0387s
        +dsa 1024 bits   0.0599s   0.1170s
        +dsa 2048 bits   0.2115s   0.4242s
        diff --git a/vendor/openssl/openssl/times/586-100.NT2 b/vendor/openssl/openssl/times/586-100.NT2
        new file mode 100644
        index 000000000..7f8c167b4
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.NT2
        @@ -0,0 +1,26 @@
        +SSLeay 0.8.3e 30-Sep-1997
        +built on Tue Sep 30 14:52:58 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
        +C flags:cl /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN -DX86_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                92.99k      257.59k      348.16k      381.47k      392.14k
        +mdc2              223.77k      235.30k      237.15k      236.77k      237.29k
        +md5               862.53k     4222.17k     7842.75k     9925.00k    10392.23k
        +sha               491.34k     2338.61k     4062.28k     4986.10k     5307.90k
        +sha1              494.38k     2234.94k     3838.83k     4679.58k     4980.18k
        +rc4              6338.10k     7489.83k     7676.25k     7698.80k     7631.56k
        +des cbc          1654.17k     1917.66k     1961.05k     1968.05k     1960.69k
        +des ede3          691.17k      739.42k      744.13k      745.82k      741.40k
        +idea cbc          788.46k      870.33k      879.16k      881.38k      879.90k
        +rc2 cbc           794.44k      859.63k      868.24k      869.68k      867.45k
        +blowfish cbc     2379.88k     3017.48k     3116.12k     3134.76k     3070.50k
        +                  sign    verify
        +rsa  512 bits   0.0204s   0.0027s
        +rsa 1024 bits   0.1074s   0.0032s
        +rsa 2048 bits   0.6890s   0.0246s
        +rsa 4096 bits   5.0180s   0.0911s
        +                  sign    verify
        +dsa  512 bits   0.0201s   0.0376s
        +dsa 1024 bits   0.0608s   0.1193s
        +dsa 2048 bits   0.2133s   0.4294s
        diff --git a/vendor/openssl/openssl/times/586-100.dos b/vendor/openssl/openssl/times/586-100.dos
        new file mode 100644
        index 000000000..3085c256b
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.dos
        @@ -0,0 +1,24 @@
        +ms-dos static libs, 16 bit C and 16 bit assmber 
        +
        +SSLeay 0.6.1 02-Jul-1996
        +built on Tue Jul  9 22:52:54 EST 1996
        +options:bn(32,16) md2(char) rc4(idx,int) des(ptr,long) idea(short)
        +C flags:cl /ALw /Gx- /Gf /G2 /f- /Ocgnotb2 /W3 /WX -DL_ENDIAN /nologo -DMSDOS -DNO_SOCK
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             45.99k      130.75k      176.53k      199.35k      203.21k
        +md5            236.17k     1072.16k     1839.61k     2221.56k     2383.13k
        +sha            107.97k      459.10k      757.64k      908.64k      954.99k
        +sha1            96.95k      409.92k      672.16k      788.40k      844.26k
        +rc4           1659.14k     1956.30k     2022.72k     2022.72k     2022.72k
        +des cfb        313.57k      326.86k      326.86k      331.83k      326.86k
        +des cbc        345.84k      378.82k      378.82k      384.38k      378.82k
        +des ede3       139.59k      144.66k      144.61k      144.45k      143.29k
        +idea cfb       262.67k      274.21k      274.21k      274.21k      274.21k
        +idea cbc       284.32k      318.14k      318.14k      318.14k      318.14k
        +rc2 cfb        265.33k      274.21k      277.69k      277.11k      277.69k
        +rc2 cbc        283.71k      310.60k      309.86k      313.57k      314.32k
        +rsa  512 bits   0.104s
        +rsa 1024 bits   0.566s
        +rsa 2048 bits   3.680s
        +rsa 4096 bits  26.740s
        diff --git a/vendor/openssl/openssl/times/586-100.ln4 b/vendor/openssl/openssl/times/586-100.ln4
        new file mode 100644
        index 000000000..14a9db912
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.ln4
        @@ -0,0 +1,26 @@
        +SSLeay 0.8.3aa 24-Oct-1997
        +built on Mon Oct 27 10:16:25 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                56.78k      156.71k      211.46k      231.77k      238.71k
        +mdc2              187.45k      200.49k      201.64k      202.75k      202.77k
        +md5              1002.51k     5798.66k    11967.15k    16449.19k    18251.78k
        +hmac(md5)         468.71k     3173.46k     8386.99k    14305.56k    17607.34k
        +sha1              586.98k     2934.87k     5393.58k     6863.19k     7408.30k
        +rc4              3675.10k     4314.15k     4402.77k     4427.78k     4404.57k
        +des cbc          1902.96k     2202.01k     2242.30k     2252.46k     2236.42k
        +des ede3          700.15k      774.23k      783.70k      781.62k      783.70k
        +idea cbc          618.46k      677.93k      683.61k      685.40k      685.40k
        +rc2 cbc           536.97k      573.87k      577.96k      579.24k      578.90k
        +blowfish cbc     3672.66k     4271.89k     4428.80k     4469.76k     4374.53k
        +                  sign    verify
        +rsa  512 bits   0.0213s   0.0021s
        +rsa 1024 bits   0.1075s   0.0063s
        +rsa 2048 bits   0.6853s   0.0224s
        +rsa 4096 bits   4.9400s   0.0845s
        +                  sign    verify
        +dsa  512 bits   0.0203s   0.0380s
        +dsa 1024 bits   0.0600s   0.1189s
        +dsa 2048 bits   0.2110s   0.4250s
        diff --git a/vendor/openssl/openssl/times/586-100.lnx b/vendor/openssl/openssl/times/586-100.lnx
        new file mode 100644
        index 000000000..0c051738c
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.lnx
        @@ -0,0 +1,23 @@
        +SSLeay 0.7.3 30-Apr-1997
        +built on Mon May 12 04:13:55 EST 1997
        +options:bn(64,32) md2(char) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
        +C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                72.95k      202.77k      274.01k      300.37k      309.23k
        +md5               770.57k     4094.02k     7409.41k     9302.36k     9986.05k
        +sha               363.05k     1571.07k     2613.85k     3134.81k     3320.49k
        +sha1              340.94k     1462.85k     2419.20k     2892.12k     3042.35k
        +rc4              3676.91k     4314.94k     4407.47k     4430.51k     4412.76k
        +des cbc          1489.95k     1799.08k     1841.66k     1851.73k     1848.66k
        +des ede3          621.93k      711.19k      726.10k      729.77k      729.09k
        +idea cbc          618.16k      676.99k      683.09k      684.37k      683.59k
        +rc2 cbc           537.59k      573.93k      578.56k      579.58k      579.70k
        +blowfish cbc     2077.57k     2682.20k     2827.18k     2840.92k     2842.62k
        +rsa  512 bits   0.024s   0.003
        +rsa 1024 bits   0.120s   0.003
        +rsa 2048 bits   0.751s   0.026
        +rsa 4096 bits   5.320s   0.096
        +dsa  512 bits   0.022s   0.042
        +dsa 1024 bits   0.065s   0.126
        +dsa 2048 bits   0.227s   0.449
        diff --git a/vendor/openssl/openssl/times/586-100.nt b/vendor/openssl/openssl/times/586-100.nt
        new file mode 100644
        index 000000000..9adcac310
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.nt
        @@ -0,0 +1,23 @@
        +SSLeay 0.7.3 30-Apr-1997
        +built on Mon May 19 10:47:38 EST 1997
        +options:bn(64,32) md2(char) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
        +C flags not available
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                89.57k      245.94k      331.59k      362.95k      373.29k
        +md5               858.93k     4175.51k     7700.21k     9715.78k    10369.11k
        +sha               466.18k     2103.67k     3607.69k     4399.31k     4669.16k
        +sha1              449.59k     2041.02k     3496.13k     4256.45k     4512.92k
        +rc4              5862.55k     7447.27k     7698.80k     7768.38k     7653.84k
        +des cbc          1562.71k     1879.84k     1928.24k     1938.93k     1911.02k
        +des ede3          680.27k      707.97k      728.62k      733.15k      725.98k
        +idea cbc          797.46k      885.85k      895.68k      898.06k      896.45k
        +rc2 cbc           609.46k      648.75k      654.01k      654.42k      653.60k
        +blowfish cbc     2357.94k     3000.22k     3106.89k     3134.76k     3080.42k
        +rsa  512 bits   0.022s   0.003
        +rsa 1024 bits   0.112s   0.003
        +rsa 2048 bits   0.726s   0.026
        +rsa 4096 bits   5.268s   0.095
        +dsa  512 bits   0.021s   0.039
        +dsa 1024 bits   0.063s   0.127
        +dsa 2048 bits   0.224s   0.451
        diff --git a/vendor/openssl/openssl/times/586-100.ntx b/vendor/openssl/openssl/times/586-100.ntx
        new file mode 100644
        index 000000000..35166a5e9
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.ntx
        @@ -0,0 +1,30 @@
        +SSLeay 0.8.5f 22-Jan-1998
        +built on Wed Jan 21 17:11:53 EST 1998
        +options:bn(64,32) md2(int) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(
        +ptr2)
        +C flags:cl /MT /W3 /WX /G5 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo -DWIN32 -DL_ENDIAN
        +-DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                92.99k      257.43k      347.84k      381.82k      392.14k
        +mdc2              232.19k      253.68k      257.57k      258.70k      258.70k
        +md5              1094.09k     5974.79k    12139.81k    16487.04k    18291.77k
        +hmac(md5)         375.70k     2590.04k     7309.70k    13469.18k    17447.19k
        +sha1              613.78k     2982.93k     5446.44k     6889.46k     7424.86k
        +rmd160            501.23k     2405.68k     4367.25k     5503.61k     5915.80k
        +rc4              8167.75k    10429.44k    10839.12k    10929.50k    10772.30k
        +des cbc          2057.24k     2218.27k     2237.20k     2227.69k     2213.59k
        +des ede3          719.63k      727.11k      728.77k      719.56k      722.97k
        +idea cbc          827.67k      888.85k      898.06k      900.30k      898.75k
        +rc2 cbc           797.46k      862.53k      870.33k      872.58k      870.40k
        +blowfish cbc     3835.32k     4435.60k     4513.89k     4513.89k     4416.92k
        +cast cbc         2785.06k     3052.62k     3088.59k     3034.95k     3034.95k
        +                  sign    verify    sign/s verify/s
        +rsa  512 bits   0.0202s   0.0020s     49.4    500.2
        +rsa 1024 bits   0.1030s   0.0063s      9.7    159.4
        +rsa 2048 bits   0.6740s   0.0223s      1.5     44.9
        +rsa 4096 bits   4.8970s   0.0844s      0.2     11.8
        +                  sign    verify    sign/s verify/s
        +dsa  512 bits   0.0191s   0.0361s     52.4     27.7
        +dsa 1024 bits   0.0587s   0.1167s     17.0      8.6
        +dsa 2048 bits   0.2091s   0.4123s      4.8      2.4
        diff --git a/vendor/openssl/openssl/times/586-100.w31 b/vendor/openssl/openssl/times/586-100.w31
        new file mode 100644
        index 000000000..d5b1c1024
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-100.w31
        @@ -0,0 +1,27 @@
        +Pentium 100, Windows 3.1 DLL's, 16 bit C, 32bit assember.
        +
        +Running under Windows NT 4.0 Beta 2
        +
        +SSLeay 0.6.4 20-Aug-1996
        +built on Thu Aug 22 08:44:21 EST 1996
        +options:bn(32,32) md2(char) rc4(idx,int) des(ptr,long) idea(short)
        +C flags:cl /ALw /Gx- /Gf /G2 /f- /Ocgnotb2 /W3 /WX -DL_ENDIAN /nologo -DWIN16
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             45.83k      128.82k      180.17k      194.90k      198.59k
        +md5            224.82k     1038.19k     1801.68k     2175.47k     2330.17k
        +sha            105.11k      448.11k      739.48k      884.13k      944.66k
        +sha1            94.71k      402.99k      667.88k      795.58k      844.26k
        +rc4           1614.19k     1956.30k     2022.72k     2022.72k     2022.72k
        +des cfb        291.27k      318.14k      318.14k      318.14k      322.84k
        +des cbc        326.86k      356.17k      362.08k      362.08k      367.15k
        +des ede3       132.40k      139.57k      139.53k      139.37k      140.97k
        +idea cfb       265.33k      280.67k      280.67k      277.69k      281.27k
        +idea cbc       274.21k      302.01k      306.24k      306.24k      305.53k
        +rc2 cfb        264.79k      274.21k      274.78k      274.21k      274.21k
        +rc2 cbc        281.27k      306.24k      309.86k      305.53k      309.86k
        +rsa  512 bits   0.058s
        +rsa 1024 bits   0.280s
        +rsa 2048 bits   1.430s
        +rsa 4096 bits  10.600s
        +
        diff --git a/vendor/openssl/openssl/times/586-1002.lnx b/vendor/openssl/openssl/times/586-1002.lnx
        new file mode 100644
        index 000000000..d830bcea4
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586-1002.lnx
        @@ -0,0 +1,26 @@
        +SSLeay 0.8.3e 30-Sep-1997
        +built on Wed Oct  1 03:01:44 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DX86_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                56.21k      156.57k      211.29k      231.77k      237.92k
        +mdc2              170.99k      191.70k      193.90k      195.58k      195.95k
        +md5               770.50k     3961.96k     7291.22k     9250.82k     9942.36k
        +sha               344.93k     1520.77k     2569.81k     3108.52k     3295.91k
        +sha1              326.20k     1423.74k     2385.15k     2870.95k     3041.96k
        +rc4              3672.88k     4309.65k     4374.41k     4408.66k     4355.41k
        +des cbc          1349.73k     1689.05k     1735.34k     1748.99k     1739.43k
        +des ede3          638.70k      704.00k      711.85k      714.41k      712.70k
        +idea cbc          619.55k      677.33k      683.26k      685.06k      685.40k
        +rc2 cbc           521.18k      571.20k      573.46k      578.90k      578.90k
        +blowfish cbc     2079.67k     2592.49k     2702.34k     2730.33k     2695.17k
        +                  sign    verify
        +rsa  512 bits   0.0213s   0.0026s
        +rsa 1024 bits   0.1099s   0.0031s
        +rsa 2048 bits   0.7007s   0.0248s
        +rsa 4096 bits   5.0500s   0.0921s
        +                  sign    verify
        +dsa  512 bits   0.0203s   0.0389s
        +dsa 1024 bits   0.0614s   0.1222s
        +dsa 2048 bits   0.2149s   0.4283s
        diff --git a/vendor/openssl/openssl/times/586p-100.lnx b/vendor/openssl/openssl/times/586p-100.lnx
        new file mode 100644
        index 000000000..561eb3114
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/586p-100.lnx
        @@ -0,0 +1,26 @@
        +Pentium 100 - Linux 1.2.13 - gcc 2.7.2p
        +This is the pentium specific version of gcc
        +
        +SSLeay 0.6.4 20-Aug-1996
        +built on Thu Aug 22 08:27:58 EST 1996
        +options:bn(64,32) md2(char) rc4(idx,int) des(idx,long) idea(int)
        +C flags:gcc -DL_ENDIAN -DTERMIO -O6 -fomit-frame-pointer -mpentium -Wall
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             74.90k      208.43k      282.11k      309.59k      318.43k
        +md5            807.08k     4205.67k     7801.51k     9958.06k    10810.71k
        +sha            405.98k     1821.55k     3119.10k     3799.04k     4052.31k
        +sha1           389.13k     1699.50k     2852.78k     3437.57k     3656.36k
        +rc4           3621.15k     4130.07k     4212.74k     4228.44k     4213.42k
        +des cfb        794.39k      828.37k      831.74k      832.51k      832.85k
        +des cbc        817.68k      886.17k      894.72k      896.00k      892.93k
        +des ede3       308.83k      323.29k      324.61k      324.95k      324.95k
        +idea cfb       690.41k      715.39k      718.51k      719.19k      718.17k
        +idea cbc       696.80k      760.60k      767.32k      768.68k      770.05k
        +rc2 cfb        619.91k      639.74k      642.30k      642.73k      641.71k
        +rc2 cbc        631.99k      671.42k      676.35k      676.18k      677.21k
        +rsa  512 bits   0.025s
        +rsa 1024 bits   0.123s
        +rsa 2048 bits   0.756s
        +rsa 4096 bits   5.365s
        +
        diff --git a/vendor/openssl/openssl/times/686-200.bsd b/vendor/openssl/openssl/times/686-200.bsd
        new file mode 100644
        index 000000000..f23c580e0
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/686-200.bsd
        @@ -0,0 +1,25 @@
        +Pentium Pro 200mhz
        +FreeBSD 2.1.5
        +gcc 2.7.2.2
        +
        +SSLeay 0.7.0 30-Jan-1997
        +built on Tue Apr 22 12:14:36 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
        +C flags:gcc -DTERMIOS -D_ANSI_SOURCE -fomit-frame-pointer -O3 -m486 -Wall
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               130.99k      367.68k      499.09k      547.04k      566.50k
        +md5              1924.98k     8293.50k    13464.41k    16010.39k    16820.68k
        +sha              1250.75k     5330.43k     8636.88k    10227.36k    10779.14k
        +sha1             1071.55k     4572.50k     7459.98k     8791.96k     9341.61k
        +rc4             10724.22k    14546.25k    15240.18k    15259.50k    15265.63k
        +des cbc          3309.11k     3883.01k     3968.25k     3971.86k     3979.14k
        +des ede3         1442.98k     1548.33k     1562.48k     1562.00k     1563.33k
        +idea cbc         2195.69k     2506.39k     2529.59k     2545.66k     2546.54k
        +rc2 cbc           806.00k      833.52k      837.58k      838.52k      836.69k
        +blowfish cbc     4687.34k     5949.97k     6182.43k     6248.11k     6226.09k
        +rsa  512 bits   0.010s
        +rsa 1024 bits   0.045s
        +rsa 2048 bits   0.260s
        +rsa 4096 bits   1.690s
        +
        diff --git a/vendor/openssl/openssl/times/686-200.lnx b/vendor/openssl/openssl/times/686-200.lnx
        new file mode 100644
        index 000000000..a10cc2fd0
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/686-200.lnx
        @@ -0,0 +1,26 @@
        +SSLeay 0.8.2a 04-Sep-1997
        +built on Fri Sep  5 17:37:05 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               131.02k      368.41k      500.57k      549.21k      566.09k
        +mdc2              535.60k      589.10k      595.88k      595.97k      594.54k
        +md5              1801.53k     9674.77k    17484.03k    21849.43k    23592.96k
        +sha              1261.63k     5533.25k     9285.63k    11187.88k    11913.90k
        +sha1             1103.13k     4782.53k     7933.78k     9472.34k    10070.70k
        +rc4             10722.53k    14443.93k    15215.79k    15299.24k    15219.59k
        +des cbc          3286.57k     3827.73k     3913.39k     3931.82k     3926.70k
        +des ede3         1443.50k     1549.08k     1561.17k     1566.38k     1564.67k
        +idea cbc         2203.64k     2508.16k     2538.33k     2543.62k     2547.71k
        +rc2 cbc          1430.94k     1511.59k     1524.82k     1527.13k     1523.33k
        +blowfish cbc     4716.07k     5965.82k     6190.17k     6243.67k     6234.11k
        +                  sign    verify
        +rsa  512 bits   0.0100s   0.0011s
        +rsa 1024 bits   0.0451s   0.0012s
        +rsa 2048 bits   0.2605s   0.0086s
        +rsa 4096 bits   1.6883s   0.0302s
        +                  sign    verify
        +dsa  512 bits   0.0083s   0.0156s
        +dsa 1024 bits   0.0228s   0.0454s
        +dsa 2048 bits   0.0719s   0.1446s
        +
        diff --git a/vendor/openssl/openssl/times/686-200.nt b/vendor/openssl/openssl/times/686-200.nt
        new file mode 100644
        index 000000000..c8cbaa04e
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/686-200.nt
        @@ -0,0 +1,24 @@
        +built on Tue May 13 08:24:51 EST 1997
        +options:bn(64,32) md2(char) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfi
        +sh(ptr2)
        +C flags not available
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               156.39k      427.99k      576.14k      628.36k      647.27k
        +md5              2120.48k    10255.02k    18396.07k    22795.13k    24244.53k
        +sha              1468.59k     6388.89k    10686.12k    12826.62k    13640.01k
        +sha1             1393.46k     6013.34k     9974.56k    11932.59k    12633.45k
        +rc4             13833.46k    19275.29k    20321.24k    20281.93k    20520.08k
        +des cbc          3382.50k     4104.02k     4152.78k     4194.30k     4194.30k
        +des ede3         1465.51k     1533.00k     1549.96k     1553.29k     1570.29k
        +idea cbc         2579.52k     3079.52k     3130.08k     3153.61k     3106.89k
        +rc2 cbc          1204.57k     1276.42k     1285.81k     1289.76k     1285.81k
        +blowfish cbc     5229.81k     6374.32k     6574.14k     6574.14k     6594.82k
        +rsa  512 bits   0.008s   0.001
        +rsa 1024 bits   0.038s   0.001
        +rsa 2048 bits   0.231s   0.008
        +rsa 4096 bits   1.540s   0.027
        +dsa  512 bits   0.007s   0.013
        +dsa 1024 bits   0.021s   0.040
        +dsa 2048 bits   0.066s   0.130
        +
        diff --git a/vendor/openssl/openssl/times/L1 b/vendor/openssl/openssl/times/L1
        new file mode 100644
        index 000000000..09253d727
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/L1
        @@ -0,0 +1,27 @@
        +SSLeay 0.8.3ad 27-Oct-1997
        +built on Wed Oct 29 00:36:17 EST 1997
        +options:bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2) 
        +C flags:gcc -DL_ENDIAN -DTERMIO -DBN_ASM -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized -DMD5_ASM -DSHA1_ASM
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                56.16k      156.50k      211.46k      231.77k      238.71k
        +mdc2              183.37k      205.21k      205.57k      209.92k      207.53k
        +md5              1003.65k     5605.56k    11628.54k    15887.70k    17522.69k
        +hmac(md5)         411.24k     2803.46k     7616.94k    13475.84k    16864.60k
        +sha1              542.66k     2843.50k     5320.53k     6833.49k     7389.18k
        +rc4              3677.15k     4313.73k     4407.89k     4429.82k     4404.57k
        +des cbc          1787.94k     2174.51k     2236.76k     2249.73k     2230.95k
        +des ede3          719.46k      777.26k      784.81k      780.29k      783.70k
        +idea cbc          619.56k      677.89k      684.12k      685.40k      685.40k
        +rc2 cbc           537.51k      573.93k      578.47k      579.24k      578.90k
        +blowfish cbc     3226.76k     4221.65k     4424.19k     4468.39k     4377.26k
        +cast cbc         2866.13k     3165.35k     3263.15k     3287.04k     3233.11k
        +                  sign    verify
        +rsa  512 bits   0.0212s   0.0021s
        +rsa 1024 bits   0.1072s   0.0064s
        +rsa 2048 bits   0.6853s   0.0222s
        +rsa 4096 bits   4.9300s   0.0848s
        +                  sign    verify
        +dsa  512 bits   0.0200s   0.0380s
        +dsa 1024 bits   0.0600s   0.1180s
        +dsa 2048 bits   0.2110s   0.4221s
        diff --git a/vendor/openssl/openssl/times/R10000.t b/vendor/openssl/openssl/times/R10000.t
        new file mode 100644
        index 000000000..6b3874c86
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/R10000.t
        @@ -0,0 +1,24 @@
        +IRIX 6.2 - R10000 195mhz
        +SLeay 0.6.5a 06-Dec-1996
        +built on Tue Dec 24 03:51:45 EST 1996
        +options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int)
        +C flags:cc -O2 -DTERMIOS -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2            156.34k      424.03k      571.88k      628.88k      646.01k
        +md5           1885.02k     8181.72k    13440.53k    16020.60k    16947.54k
        +sha           1587.12k     7022.05k    11951.24k    14440.12k    15462.74k
        +sha1          1413.13k     6215.86k    10571.16k    12736.22k    13628.51k
        +rc4          10556.28k    11974.08k    12077.10k    12111.38k    12103.20k
        +des cfb       2977.71k     3252.27k     3284.36k     3302.66k     3290.54k
        +des cbc       3298.31k     3704.96k     3771.30k     3730.73k     3778.80k
        +des ede3      1278.28k     1328.82k     1342.66k     1339.82k     1343.27k
        +idea cfb      2843.34k     3138.04k     3180.95k     3176.46k     3188.54k
        +idea cbc      3115.21k     3558.03k     3590.61k     3591.24k     3601.18k
        +rc2 cfb       2006.66k     2133.33k     2149.03k     2159.36k     2149.71k
        +rc2 cbc       2167.07k     2315.30k     2338.05k     2329.34k     2333.90k
        +rsa  512 bits   0.008s
        +rsa 1024 bits   0.043s
        +rsa 2048 bits   0.280s
        +rsa 4096 bits   2.064s
        +
        diff --git a/vendor/openssl/openssl/times/R4400.t b/vendor/openssl/openssl/times/R4400.t
        new file mode 100644
        index 000000000..af8848ffe
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/R4400.t
        @@ -0,0 +1,26 @@
        +IRIX 5.3
        +R4400 200mhz
        +cc -O2
        +SSLeay 0.6.5a 06-Dec-1996
        +built on Mon Dec 23 11:51:11 EST 1996
        +options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc2,16,long) idea(int)
        +C flags:cc -O2 -DTERMIOS -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2            100.62k      280.25k      380.15k      416.02k      428.82k
        +md5            828.62k     3525.05k     6311.98k     7742.51k     8328.04k
        +sha            580.04k     2513.74k     4251.73k     5101.04k     5394.80k
        +sha1           520.23k     2382.94k     4107.82k     5024.62k     5362.56k
        +rc4           5871.53k     6323.08k     6357.49k     6392.04k     6305.45k
        +des cfb       1016.76k     1156.72k     1176.59k     1180.55k     1181.65k
        +des cbc       1016.38k     1303.81k     1349.10k     1359.41k     1356.62k
        +des ede3       607.39k      650.74k      655.11k      657.52k      654.18k
        +idea cfb      1296.10k     1348.66k     1353.80k     1358.75k     1355.40k
        +idea cbc      1453.90k     1554.68k     1567.84k     1569.89k     1573.57k
        +rc2 cfb       1199.86k     1251.69k     1253.57k     1259.56k     1251.31k
        +rc2 cbc       1334.60k     1428.55k     1441.89k     1445.42k     1441.45k
        +rsa  512 bits   0.024s
        +rsa 1024 bits   0.125s
        +rsa 2048 bits   0.806s
        +rsa 4096 bits   5.800s
        +
        diff --git a/vendor/openssl/openssl/times/aix.t b/vendor/openssl/openssl/times/aix.t
        new file mode 100644
        index 000000000..4f24e3980
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/aix.t
        @@ -0,0 +1,34 @@
        +from Paco Garcia <pgarcia@ctv.es>
        +This machine is a Bull Estrella  Minitower Model MT604-100
        +Processor        : PPC604 
        +P.Speed          : 100Mhz 
        +Data/Instr Cache :    16 K
        +L2 Cache         :   256 K
        +PCI BUS Speed    :    33 Mhz
        +TransfRate PCI   :   132 MB/s
        +Memory           :    96 MB
        +
        +AIX 4.1.4
        +
        +SSLeay 0.6.6 14-Jan-1997
        +built on Mon Jan 13 21:36:03 CUT 1997
        +options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,4,long) idea(int) blowfish
        +(idx)
        +C flags:cc -O -DAIX -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                53.83k      147.46k      197.63k      215.72k     221.70k
        +md5              1278.13k     5354.77k     8679.60k    10195.09k   10780.56k
        +sha              1055.34k     4600.37k     7721.30k     9298.94k    9868.63k
        +sha1              276.90k     1270.25k     2187.95k     2666.84k    2850.82k
        +rc4              4660.57k     5268.93k     5332.48k     5362.47k    5346.65k
        +des cbc          1774.16k     1981.10k     1979.56k     2032.71k    1972.25k
        +des ede3          748.81k      781.42k      785.66k      785.75k     780.84k
        +idea cbc         2066.19k     2329.58k     2378.91k     2379.86k    2380.89k
        +rc2 cbc          1278.53k     1379.69k     1389.99k     1393.66k    1389.91k
        +blowfish cbc     2812.91k     3307.90k     3364.91k     3386.37k    3374.32k
        +rsa  512 bits   0.019s
        +rsa 1024 bits   0.096s
        +rsa 2048 bits   0.614s
        +rsa 4096 bits   4.433s
        +
        diff --git a/vendor/openssl/openssl/times/aixold.t b/vendor/openssl/openssl/times/aixold.t
        new file mode 100644
        index 000000000..0b51412cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/aixold.t
        @@ -0,0 +1,23 @@
        +SSLeay 0.7.3r 20-May-1997
        +built on Mon Jun  2 04:06:32 EST 1997
        +options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,4,long) idea(int) blowfish(idx)
        +C flags:cc -O -DAIX -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                19.09k       52.47k       71.23k       77.49k       78.93k
        +md5               214.56k      941.21k     1585.43k     1883.12k     1988.70k
        +sha               118.35k      521.65k      860.28k     1042.27k     1100.46k
        +sha1              109.52k      478.98k      825.90k      995.48k     1049.69k
        +rc4              1263.63k     1494.24k     1545.70k     1521.66k     1518.99k
        +des cbc           259.62k      286.55k      287.15k      288.15k      289.45k
        +des ede3          104.92k      107.88k      109.27k      109.25k      109.96k
        +idea cbc          291.63k      320.07k      319.40k      320.51k      318.27k
        +rc2 cbc           220.04k      237.76k      241.44k      245.90k      244.08k
        +blowfish cbc      407.95k      474.83k      480.99k      485.71k      481.07k
        +rsa  512 bits   0.157s   0.019
        +rsa 1024 bits   0.908s   0.023
        +rsa 2048 bits   6.225s   0.218
        +rsa 4096 bits  46.500s   0.830
        +dsa  512 bits   0.159s   0.312
        +dsa 1024 bits   0.536s   1.057
        +dsa 2048 bits   1.970s   3.977
        diff --git a/vendor/openssl/openssl/times/alpha.t b/vendor/openssl/openssl/times/alpha.t
        new file mode 100644
        index 000000000..3a7c6c498
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/alpha.t
        @@ -0,0 +1,81 @@
        +SSLeay-051 Alpha gcc -O3 64Bit (assember bn_mul)
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             44.40k      121.56k      162.73k      179.20k      185.01k
        +md5            780.85k     3278.53k     5281.52k     6327.98k     6684.67k
        +sha            501.40k     2249.19k     3855.27k     4801.19k     5160.96k
        +sha-1          384.99k     1759.72k     3113.64k     3946.92k     4229.80k
        +rc4           3505.05k     3724.54k     3723.78k     3555.33k     3694.68k
        +des cfb        946.96k     1015.27k     1021.87k     1033.56k     1037.65k
        +des cbc       1001.24k     1220.20k     1243.31k     1272.73k     1265.87k
        +des ede3       445.34k      491.65k      500.53k      502.10k      502.44k
        +idea cfb       643.53k      667.49k      663.81k      666.28k      664.51k
        +idea cbc       650.42k      735.41k      733.27k      742.74k      745.47k
        +rsa  512 bits   0.031s
        +rsa 1024 bits   0.141s
        +rsa 2048 bits   0.844s
        +rsa 4096 bits   6.033s
        +
        +SSLeay-051 Alpha cc -O2 64bit (assember bn_mul)
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             45.37k      122.86k      165.97k      182.95k      188.42k
        +md5            842.42k     3629.93k     5916.76k     7039.17k     7364.61k
        +sha            498.93k     2197.23k     3895.60k     4756.48k     5132.13k
        +sha-1          382.02k     1757.21k     3112.53k     3865.23k     4128.77k
        +rc4           2975.25k     3049.33k     3180.97k     3214.68k     3424.26k
        +des cfb        901.55k      990.83k     1006.08k     1011.19k     1004.89k
        +des cbc        947.84k     1127.84k     1163.67k     1162.24k     1157.80k
        +des ede3       435.62k      485.57k      493.67k      491.52k      491.52k
        +idea cfb       629.31k      648.66k      647.77k      648.53k      649.90k
        +idea cbc       565.15k      608.00k      613.46k      613.38k      617.13k
        +rsa  512 bits   0.030s
        +rsa 1024 bits   0.141s
        +rsa 2048 bits   0.854s
        +rsa 4096 bits   6.067s
        +
        +des cfb        718.28k      822.64k      833.11k      836.27k      841.05k
        +des cbc        806.10k      951.42k      975.83k      983.73k      991.23k
        +des ede3       329.50k      379.11k      387.95k      387.41k      388.33k
        +
        +des cfb        871.62k      948.65k      951.81k      953.00k      955.58k
        +des cbc        953.60k     1174.27k     1206.70k     1216.10k     1216.44k
        +des ede3       349.34k      418.05k      427.26k      429.74k      431.45k
        +
        +
        +
        +
        +SSLeay-045c Alpha gcc -O3 64Bit
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             44.95k      122.22k      164.27k      180.62k      184.66k
        +md5            808.71k     3371.95k     5415.68k     6385.66k     6684.67k
        +sha            493.68k     2162.05k     3725.82k     4552.02k     4838.74k
        +rc4           3317.32k     3649.09k     3728.30k     3744.09k     3691.86k
        +cfb des        996.45k     1050.77k     1058.30k     1059.16k     1064.96k
        +cbc des       1096.52k     1255.49k     1282.13k     1289.90k     1299.80k
        +ede3 des       482.14k      513.51k      518.66k      520.19k      521.39k
        +cfb idea       519.90k      533.40k      535.21k      535.55k      535.21k
        +cbc idea       619.34k      682.21k      688.04k      689.15k      690.86k
        +rsa  512 bits   0.050s
        +rsa 1024 bits   0.279s
        +rsa 2048 bits   1.908s
        +rsa 4096 bits  14.750s
        +
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             37.31k      102.77k      137.64k      151.55k      155.78k
        +md5            516.65k     2535.21k     4655.72k     5859.66k     6343.34k
        +rc4           3519.61k     3707.01k     3746.86k     3755.39k     3675.48k
        +cfb des        780.27k      894.68k      913.10k      921.26k      922.97k
        +cbc des        867.54k     1040.13k     1074.17k     1075.54k     1084.07k
        +ede3 des       357.19k      397.36k      398.08k      402.28k      401.41k
        +cbc idea       646.53k      686.44k      694.03k      691.20k      693.59k
        +rsa  512 bits   0.046s
        +rsa 1024 bits   0.270s
        +rsa 2048 bits   1.858s
        +rsa 4096 bits  14.350s
        +
        +md2      C      37.83k      103.17k      137.90k      150.87k      155.37k
        +md2      L      37.30k      102.04k      139.01k      152.74k      155.78k
        +rc4       I   3532.24k     3718.08k     3750.83k     3768.78k     3694.59k
        +rc4      CI   2662.97k     2873.26k     2907.22k     2920.63k     2886.31k
        +rc4      LI   3514.63k     3738.72k     3747.41k     3752.96k     3708.49k
        +cbc idea S     619.01k      658.68k      661.50k      662.53k      663.55k
        +cbc idea  L    645.69k      684.22k      694.55k      692.57k      690.86k
        diff --git a/vendor/openssl/openssl/times/alpha400.t b/vendor/openssl/openssl/times/alpha400.t
        new file mode 100644
        index 000000000..079e0d187
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/alpha400.t
        @@ -0,0 +1,25 @@
        +Alpha EV5.6 (21164A) 400mhz
        +
        +SSLeay 0.7.3r 20-May-1997
        +built on Mon Jun  2 03:39:58 EST 1997
        +options:bn(64,64) md2(int) rc4(ptr,int) des(idx,cisc,4,long) idea(int) blowfish(idx)
        +C flags:cc -arch host -tune host -fast -std -O4 -inline speed
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               274.98k      760.96k     1034.27k     1124.69k     1148.69k
        +md5              2524.46k    11602.60k    19838.81k    24075.26k    25745.10k
        +sha              1848.46k     8335.66k    14232.49k    17247.91k    18530.30k
        +sha1             1639.67k     7336.53k    12371.80k    14807.72k    15870.63k
        +rc4             17950.93k    19390.66k    19652.44k    19700.39k    19412.31k
        +des cbc          4018.59k     4872.06k     4988.76k     5003.26k     4995.73k
        +des ede3         1809.11k     1965.67k     1984.26k     1986.90k     1982.46k
        +idea cbc         2848.82k     3204.33k     3250.26k     3257.34k     3260.42k
        +rc2 cbc          3766.08k     4349.50k     4432.21k     4448.94k     4448.26k
        +blowfish cbc     6694.88k     9042.35k     9486.93k     9598.98k     9624.91k
        +rsa  512 bits   0.003s   0.000
        +rsa 1024 bits   0.013s   0.000
        +rsa 2048 bits   0.081s   0.003
        +rsa 4096 bits   0.577s   0.011
        +dsa  512 bits   0.003s   0.005
        +dsa 1024 bits   0.007s   0.014
        +dsa 2048 bits   0.025s   0.050
        diff --git a/vendor/openssl/openssl/times/cyrix100.lnx b/vendor/openssl/openssl/times/cyrix100.lnx
        new file mode 100644
        index 000000000..010a2216b
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/cyrix100.lnx
        @@ -0,0 +1,22 @@
        +SSLeay 0.6.6 06-Dec-1996
        +built on Fri Dec  6 10:05:20 GMT 1996
        +options:bn(64,32) md2(char) rc4(idx,int) des(idx,risc,16,long) idea(int)
        +C flags:gcc -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -Wuninitialized
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             36.77k      102.48k      138.00k      151.57k      155.78k
        +md5            513.59k     2577.22k     4623.51k     5768.99k     6214.53k
        +sha            259.89k     1105.45k     1814.97k     2156.16k     2292.13k
        +sha1           242.43k     1040.95k     1719.44k     2049.74k     2164.64k
        +rc4           1984.48k     2303.41k     2109.37k     2071.47k     1985.61k
        +des cfb        712.08k      758.29k      753.17k      752.06k      748.67k
        +des cbc        787.37k      937.64k      956.77k      961.61k      957.54k
        +des ede3       353.97k      377.28k      379.99k      379.34k      379.11k
        +idea cfb       403.80k      418.50k      416.60k      415.78k      415.03k
        +idea cbc       426.54k      466.40k      471.31k      472.67k      473.14k
        +rc2 cfb        405.15k      420.05k      418.16k      416.72k      416.36k
        +rc2 cbc        428.21k      468.43k      473.09k      472.59k      474.70k
        +rsa  512 bits   0.040s
        +rsa 1024 bits   0.195s
        +rsa 2048 bits   1.201s
        +rsa 4096 bits   8.700s
        diff --git a/vendor/openssl/openssl/times/dgux-x86.t b/vendor/openssl/openssl/times/dgux-x86.t
        new file mode 100644
        index 000000000..70635c536
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/dgux-x86.t
        @@ -0,0 +1,23 @@
        +version:SSLeay 0.5.2c 15-May-1996
        +built Fri Jun 14 19:47:04 EST 1996
        +options:bn(LLONG,thirty_two) md2(CHAR) rc4(IDX,int) des(ary,long) idea(int)
        +C flags:gcc -O3 -fomit-frame-pointer -DL_ENDIAN
        +
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2            113.86k      316.48k      428.36k      467.63k      481.56k
        +md5           1001.99k     5037.99k     9545.94k    12036.95k    11800.38k
        +sha            628.77k     2743.48k     5113.42k     6206.99k     6165.42k
        +sha1           583.83k     2638.66k     4538.85k     5532.09k     5917.04k
        +rc4           5493.27k     6369.39k     6511.30k     6577.83k     6486.73k
        +des cfb       1219.01k     1286.06k     1299.33k     1288.87k     1381.72k
        +des cbc       1360.58k     1469.04k     1456.96k     1454.08k     1513.57k
        +des ede3       544.45k      567.84k      568.99k      570.37k      566.09k
        +idea cfb      1012.39k     1056.30k     1063.52k      989.17k      863.24k
        +idea cbc       985.36k     1090.44k     1105.92k     1108.65k     1090.17k
        +rc2 cfb        963.86k      979.06k      995.30k      937.35k      827.39k
        +rc2 cbc        951.72k     1042.11k     1049.60k     1047.21k     1059.11k
        +rsa  512 bits   0.032s
        +rsa 1024 bits   0.159s
        +rsa 2048 bits   1.025s
        +rsa 4096 bits   7.270s
        +
        diff --git a/vendor/openssl/openssl/times/dgux.t b/vendor/openssl/openssl/times/dgux.t
        new file mode 100644
        index 000000000..c7f7564e8
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/dgux.t
        @@ -0,0 +1,17 @@
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             38.54k      106.28k      144.00k      157.46k      161.72k
        +md5            323.23k     1471.62k     2546.11k     3100.20k     3309.57k
        +rc4        I  1902.74k     2055.20k     2080.42k     2077.88k     2065.46k
        +cfb des        456.23k      475.22k      481.79k      488.42k      487.17k
        +cbc des        484.30k      537.50k      553.09k      558.08k      558.67k
        +ede3 des       199.97k      209.05k      211.03k      211.85k      212.78k
        +cbc idea       478.50k      519.33k      523.42k      525.09k      526.44k
        +rsa  512 bits   0.159s !RSA_LLONG
        +rsa 1024 bits   1.053s
        +rsa 2048 bits   7.600s
        +rsa 4096 bits  59.760s
        +
        +md2       C     30.53k       83.58k      112.84k      123.22k      126.24k
        +rc4           1844.56k     1975.50k     1997.73k     1994.95k     1984.88k
        +rc4       C   1800.09k     1968.85k     1995.20k     1992.36k     1996.80k
        +rc4       CI  1830.81k     2035.75k     2067.28k     2070.23k     2062.77k
        diff --git a/vendor/openssl/openssl/times/hpux-acc.t b/vendor/openssl/openssl/times/hpux-acc.t
        new file mode 100644
        index 000000000..0c0e936d1
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/hpux-acc.t
        @@ -0,0 +1,25 @@
        +HPUX 887
        +
        +SSLeay 0.7.3r 20-May-1997
        +built on Mon Jun  2 02:59:45 EST 1997
        +options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) blowfish(idx)
        +C flags:cc -DB_ENDIAN -D_HPUX_SOURCE -Aa -Ae +ESlit +O4 -Wl,-a,archive
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                58.99k      166.85k      225.07k      247.21k      253.76k
        +md5               639.22k     2726.98k     4477.25k     5312.69k     5605.20k
        +sha               381.08k     1661.49k     2793.84k     3368.86k     3581.23k
        +sha1              349.54k     1514.56k     2536.63k     3042.59k     3224.39k
        +rc4              2891.10k     4238.01k     4464.11k     4532.49k     4545.87k
        +des cbc           717.05k      808.76k      820.14k      821.97k      821.96k
        +des ede3          288.21k      303.50k      303.69k      305.82k      305.14k
        +idea cbc          325.83k      334.36k      335.89k      336.61k      333.43k
        +rc2 cbc           793.00k      915.81k      926.69k      933.28k      929.53k
        +blowfish cbc     1561.91k     2051.97k     2122.65k     2139.40k     2145.92k
        +rsa  512 bits   0.031s   0.004
        +rsa 1024 bits   0.164s   0.004
        +rsa 2048 bits   1.055s   0.037
        +rsa 4096 bits   7.600s   0.137
        +dsa  512 bits   0.029s   0.057
        +dsa 1024 bits   0.092s   0.177
        +dsa 2048 bits   0.325s   0.646
        diff --git a/vendor/openssl/openssl/times/hpux-kr.t b/vendor/openssl/openssl/times/hpux-kr.t
        new file mode 100644
        index 000000000..ad4a0adc1
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/hpux-kr.t
        @@ -0,0 +1,23 @@
        +SSLeay 0.7.3r 20-May-1997
        +built on Mon Jun  2 02:17:35 EST 1997
        +options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,cisc,16,long) idea(int) blowfish(idx)
        +C flags:cc -DB_ENDIAN -DNOCONST -DNOPROTO -D_HPUX_SOURCE
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                35.30k       98.36k      133.41k      146.34k      150.69k
        +md5               391.20k     1737.31k     2796.65k     3313.75k     3503.74k
        +sha               189.55k      848.14k     1436.72k     1735.87k     1848.03k
        +sha1              175.30k      781.14k     1310.32k     1575.61k     1675.81k
        +rc4              2070.55k     2501.47k     2556.65k     2578.34k     2584.91k
        +des cbc           465.13k      536.85k      545.87k      547.86k      548.89k
        +des ede3          190.05k      200.99k      202.31k      202.22k      202.75k
        +idea cbc          263.44k      277.77k      282.13k      281.51k      283.15k
        +rc2 cbc           448.37k      511.39k      519.54k      522.00k      521.31k
        +blowfish cbc      839.98k     1097.70k     1131.16k     1145.64k     1144.67k
        +rsa  512 bits   0.048s   0.005
        +rsa 1024 bits   0.222s   0.006
        +rsa 2048 bits   1.272s   0.042
        +rsa 4096 bits   8.445s   0.149
        +dsa  512 bits   0.041s   0.077
        +dsa 1024 bits   0.111s   0.220
        +dsa 2048 bits   0.363s   0.726
        diff --git a/vendor/openssl/openssl/times/hpux.t b/vendor/openssl/openssl/times/hpux.t
        new file mode 100644
        index 000000000..dcf7615ed
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/hpux.t
        @@ -0,0 +1,86 @@
        +HP-UX A.09.05 9000/712
        +
        +SSLeay 0.6.6 14-Jan-1997
        +built on Tue Jan 14 16:36:31 WET 1997
        +options:bn(32,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) 
        +blowfish(idx)
        +C flags:cc -DB_ENDIAN -D_HPUX_SOURCE -Aa +ESlit +O2 -Wl,-a,archive
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                66.56k      184.92k      251.82k      259.86k      282.62k
        +md5               615.54k     2805.92k     4764.30k     5724.21k     6084.39k
        +sha               358.23k     1616.46k     2781.50k     3325.72k     3640.89k
        +sha1              327.50k     1497.98k     2619.44k     3220.26k     3460.85k
        +rc4              3500.47k     3890.99k     3943.81k     3883.74k     3900.02k
        +des cbc           742.65k      871.66k      887.15k      891.21k      895.40k
        +des ede3          302.42k      322.50k      324.46k      326.66k      326.05k
        +idea cbc          664.41k      755.87k      765.61k      772.70k      773.69k
        +rc2 cbc           798.78k      931.04k      947.69k      950.31k      952.04k
        +blowfish cbc     1353.32k     1932.29k     2021.93k     2047.02k     2053.66k
        +rsa  512 bits   0.059s
        +rsa 1024 bits   0.372s
        +rsa 2048 bits   2.697s
        +rsa 4096 bits  20.790s
        +
        +SSLeay 0.6.6 14-Jan-1997
        +built on Tue Jan 14 15:37:30 WET 1997
        +options:bn(64,32) md2(int) rc4(ptr,int) des(ptr,risc1,16,long) idea(int) 
        +blowfish(idx)
        +C flags:gcc -DB_ENDIAN -O3
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                44.91k      122.57k      167.71k      183.89k      190.24k
        +md5               532.50k     2316.27k     3965.72k     4740.11k     5055.06k
        +sha               363.76k     1684.09k     2978.53k     3730.86k     3972.72k
        +sha1              385.76k     1743.53k     2997.69k     3650.74k     3899.08k
        +rc4              3178.84k     3621.31k     3672.71k     3684.01k     3571.54k
        +des cbc           733.00k      844.70k      863.28k      863.72k      868.73k
        +des ede3          289.99k      308.94k      310.11k      309.64k      312.08k
        +idea cbc          624.07k      713.91k      724.76k      723.35k      725.13k
        +rc2 cbc           704.34k      793.39k      804.25k      805.99k      782.63k
        +blowfish cbc     1371.24k     1823.66k     1890.05k     1915.51k     1920.12k
        +rsa  512 bits   0.030s
        +rsa 1024 bits   0.156s
        +rsa 2048 bits   1.113s
        +rsa 4096 bits   7.480s
        +
        +
        +HPUX B.10.01 V 9000/887 - HP92453-01 A.10.11 HP C Compiler
        +SSLeay 0.5.2 - -Aa +ESlit +Oall +O4 -Wl,-a,archive
        +
        +HPUX A.09.04 B 9000/887
        +
        +ssleay 0.5.1 gcc v 2.7.0 -O3 -mpa-risc-1-1
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             53.00k      166.81k      205.66k      241.95k      242.20k
        +md5            743.22k     3128.44k     6031.85k     6142.07k     7025.26k
        +sha            481.30k     2008.24k     3361.31k     3985.07k     4180.74k
        +sha-1          463.60k     1916.15k     3139.24k     3786.27k     3997.70k
        +rc4           3708.61k     4125.16k     4547.53k     4206.21k     4390.07k
        +des cfb        665.91k      705.97k      698.48k      694.25k      666.08k
        +des cbc        679.80k      741.90k      769.85k      747.62k      719.47k
        +des ede3       264.31k      270.22k      265.63k      273.07k      273.07k
        +idea cfb       635.91k      673.40k      605.60k      699.53k      672.36k
        +idea cbc       705.85k      774.63k      750.60k      715.83k      721.50k
        +rsa  512 bits   0.066s
        +rsa 1024 bits   0.372s
        +rsa 2048 bits   2.177s
        +rsa 4096 bits  16.230s
        +
        +HP92453-01 A.09.61 HP C Compiler
        +ssleay 0.5.1 cc -Ae +ESlit +Oall -Wl,-a,archive
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             58.69k      163.30k      213.57k      230.40k      254.23k
        +md5            608.60k     2596.82k     3871.43k     4684.10k     4763.88k
        +sha            343.26k     1482.43k     2316.80k     2766.27k     2860.26k
        +sha-1          319.15k     1324.13k     2106.03k     2527.82k     2747.95k
        +rc4           2467.47k     3374.41k     3265.49k     3354.39k     3368.55k
        +des cfb        812.05k      814.90k      851.20k      819.20k      854.56k
        +des cbc        836.35k      994.06k      916.02k     1020.01k      988.14k
        +des ede3       369.78k      389.15k      401.01k      382.94k      408.03k
        +idea cfb       290.40k      298.06k      286.11k      296.92k      299.46k
        +idea cbc       301.30k      297.72k      304.34k      300.10k      309.70k
        +rsa  512 bits   0.350s
        +rsa 1024 bits   2.635s
        +rsa 2048 bits  19.930s
        +
        diff --git a/vendor/openssl/openssl/times/p2.w95 b/vendor/openssl/openssl/times/p2.w95
        new file mode 100644
        index 000000000..82d1e5515
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/p2.w95
        @@ -0,0 +1,22 @@
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               235.90k      652.30k      893.36k      985.74k      985.74k
        +mdc2              779.61k      816.81k      825.65k      816.01k      825.65k
        +md5              2788.77k    13508.23k    24672.38k    30504.03k    33156.55k
        +sha              1938.22k     8397.01k    14122.24k    16980.99k    18196.55k
        +sha1             1817.29k     7832.50k    13168.93k    15738.48k    16810.84k
        +rc4             15887.52k    21709.65k    22745.68k    22995.09k    22995.09k
        +des cbc          4599.02k     5377.31k     5377.31k     5533.38k     5533.38k
        +des ede3         1899.59k     2086.71k     2086.67k     2086.51k     2085.90k
        +idea cbc         3350.08k     3934.62k     3979.42k     4017.53k     4017.53k
        +rc2 cbc          1534.13k     1630.76k     1625.70k     1644.83k     1653.91k
        +blowfish cbc     6678.83k     8490.49k     8701.88k     8848.74k     8886.24k
        +                  sign    verify
        +rsa  512 bits   0.0062s   0.0008s
        +rsa 1024 bits   0.0287s   0.0009s
        +rsa 2048 bits   0.1785s   0.0059s
        +rsa 4096 bits   1.1300s   0.0205s
        +                  sign    verify
        +dsa  512 bits   0.0055s   0.0100s
        +dsa 1024 bits   0.0154s   0.0299s
        +dsa 2048 bits   0.0502s   0.0996s
        diff --git a/vendor/openssl/openssl/times/pent2.t b/vendor/openssl/openssl/times/pent2.t
        new file mode 100644
        index 000000000..b6dc26915
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/pent2.t
        @@ -0,0 +1,24 @@
        +pentium 2, 266mhz, Visual C++ 5.0, Windows 95
        +
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               235.90k      652.30k      893.36k      985.74k      985.74k
        +mdc2              779.61k      816.81k      825.65k      816.01k      825.65k
        +md5              2788.77k    13508.23k    24672.38k    30504.03k    33156.55k
        +sha              1938.22k     8397.01k    14122.24k    16980.99k    18196.55k
        +sha1             1817.29k     7832.50k    13168.93k    15738.48k    16810.84k
        +rc4             15887.52k    21709.65k    22745.68k    22995.09k    22995.09k
        +des cbc          4599.02k     5377.31k     5377.31k     5533.38k     5533.38k
        +des ede3         1899.59k     2086.71k     2086.67k     2086.51k     2085.90k
        +idea cbc         3350.08k     3934.62k     3979.42k     4017.53k     4017.53k
        +rc2 cbc          1534.13k     1630.76k     1625.70k     1644.83k     1653.91k
        +blowfish cbc     6678.83k     8490.49k     8701.88k     8848.74k     8886.24k
        +                  sign    verify
        +rsa  512 bits   0.0062s   0.0008s
        +rsa 1024 bits   0.0287s   0.0009s
        +rsa 2048 bits   0.1785s   0.0059s
        +rsa 4096 bits   1.1300s   0.0205s
        +                  sign    verify
        +dsa  512 bits   0.0055s   0.0100s
        +dsa 1024 bits   0.0154s   0.0299s
        +dsa 2048 bits   0.0502s   0.0996s
        diff --git a/vendor/openssl/openssl/times/readme b/vendor/openssl/openssl/times/readme
        new file mode 100644
        index 000000000..7074f5815
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/readme
        @@ -0,0 +1,11 @@
        +The 'times' in this directory are not all for the most recent version of
        +the library and it should be noted that on some CPUs (specifically sparc
        +and Alpha), the locations of files in the application after linking can
        +make upto a %10 speed difference when running benchmarks on things like
        +cbc mode DES.  To put it mildly this can be very anoying.
        +
        +About the only way to get around this would be to compile the library as one
        +object file, or to 'include' the source files in a specific order.
        +
        +The best way to get an idea of the 'raw' DES speed is to build the 
        +'speed' program in crypto/des.
        diff --git a/vendor/openssl/openssl/times/s586-100.lnx b/vendor/openssl/openssl/times/s586-100.lnx
        new file mode 100644
        index 000000000..cbc3e3c4f
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/s586-100.lnx
        @@ -0,0 +1,25 @@
        +Shared library build
        +
        +SSLeay 0.7.3 30-Apr-1997
        +built on Tue May 13 03:43:56 EST 1997
        +options:bn(64,32) md2(char) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(ptr2)
        +C flags:-DTERMIO -O3 -DL_ENDIAN -fomit-frame-pointer -m486 -Wall
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                68.95k      191.40k      258.22k      283.31k      291.21k
        +md5               627.37k     3064.75k     5370.15k     6765.91k     7255.38k
        +sha               323.35k     1431.32k     2417.07k     2916.69k     3102.04k
        +sha1              298.08k     1318.34k     2228.82k     2694.83k     2864.47k
        +rc4              3404.13k     4026.33k     4107.43k     4136.28k     4117.85k
        +des cbc          1414.60k     1782.53k     1824.24k     1847.64k     1840.47k
        +des ede3          588.36k      688.19k      700.33k      702.46k      704.51k
        +idea cbc          582.96k      636.71k      641.54k      642.39k      642.30k
        +rc2 cbc           569.34k      612.37k      617.64k      617.47k      619.86k
        +blowfish cbc     2015.77k     2534.49k     2609.65k     2607.10k     2615.98k
        +rsa  512 bits   0.027s   0.003
        +rsa 1024 bits   0.128s   0.003
        +rsa 2048 bits   0.779s   0.027
        +rsa 4096 bits   5.450s   0.098
        +dsa  512 bits   0.024s   0.045
        +dsa 1024 bits   0.068s   0.132
        +dsa 2048 bits   0.231s   0.469
        diff --git a/vendor/openssl/openssl/times/s586-100.nt b/vendor/openssl/openssl/times/s586-100.nt
        new file mode 100644
        index 000000000..8e3baf6d5
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/s586-100.nt
        @@ -0,0 +1,23 @@
        +SSLeay 0.7.3 30-Apr-1997
        +built on Mon May 19 10:47:38 EST 1997
        +options:bn(64,32) md2(char) rc4(idx,int) des(idx,cisc,4,long) idea(int) blowfish(ptr2)
        +C flags not available
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                90.26k      248.57k      335.06k      366.09k      376.64k
        +md5               863.95k     4205.24k     7628.78k     9582.60k    10290.25k
        +sha               463.93k     2102.51k     3623.28k     4417.85k     4695.29k
        +sha1              458.23k     2005.88k     3385.78k     4094.00k     4340.13k
        +rc4              5843.60k     7543.71k     7790.31k     7836.89k     7791.47k
        +des cbc          1583.95k     1910.67k     1960.69k     1972.12k     1946.13k
        +des ede3          654.79k      722.60k      740.97k      745.82k      738.27k
        +idea cbc          792.04k      876.96k      887.35k      892.63k      890.36k
        +rc2 cbc           603.50k      652.38k      661.85k      662.69k      661.44k
        +blowfish cbc     2379.88k     3043.76k     3153.61k     3153.61k     3134.76k
        +rsa  512 bits   0.022s   0.003
        +rsa 1024 bits   0.111s   0.003
        +rsa 2048 bits   0.716s   0.025
        +rsa 4096 bits   5.188s   0.094
        +dsa  512 bits   0.020s   0.039
        +dsa 1024 bits   0.062s   0.124
        +dsa 2048 bits   0.221s   0.441
        diff --git a/vendor/openssl/openssl/times/sgi.t b/vendor/openssl/openssl/times/sgi.t
        new file mode 100644
        index 000000000..796361015
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/sgi.t
        @@ -0,0 +1,29 @@
        +SGI Challenge R4400 200mhz IRIX 5.3 - gcc (2.6.3)
        +SSLeay 0.6.1 02-Jul-1996
        +built on Tue Jul  2 16:25:30 EST 1996
        +options:bn(64,32) md2(char) rc4(idx,char) des(idx,long) idea(int)
        +C flags:gcc -O2 -mips2 -DTERMIOS -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type           8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2             96.53k      266.70k      360.09k      393.70k      405.07k
        +md5            971.15k     4382.56k     7406.90k     8979.99k     9559.18k
        +sha            596.86k     2832.26k     4997.30k     6277.75k     6712.89k
        +sha1           578.34k     2630.16k     4632.05k     5684.34k     6083.37k
        +rc4           5641.12k     6821.76k     6996.13k     7052.61k     6913.32k
        +des cfb       1354.86k     1422.11k     1434.58k     1433.24k     1432.89k
        +des cbc       1467.13k     1618.92k     1630.08k     1637.00k     1629.62k
        +des ede3       566.13k      591.91k      596.86k      596.18k      592.54k
        +idea cfb      1190.60k     1264.49k     1270.38k     1267.84k     1272.37k
        +idea cbc      1271.45k     1410.37k     1422.49k     1426.46k     1421.73k
        +rc2 cfb       1285.73k     1371.40k     1380.92k     1383.13k     1379.23k
        +rc2 cbc       1386.61k     1542.10k     1562.49k     1572.45k     1567.93k
        +rsa  512 bits   0.018s
        +rsa 1024 bits   0.106s
        +rsa 2048 bits   0.738s
        +rsa 4096 bits   5.535s
        +
        +version:SSLeay 0.5.2c 15-May-1996
        +rsa  512 bits   0.035s
        +rsa 1024 bits   0.204s
        +rsa 2048 bits   1.423s
        +rsa 4096 bits  10.800s
        diff --git a/vendor/openssl/openssl/times/sparc.t b/vendor/openssl/openssl/times/sparc.t
        new file mode 100644
        index 000000000..1611f7657
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/sparc.t
        @@ -0,0 +1,26 @@
        +gcc 2.7.2
        +Sparc 10 - Solaris 2.3 - 50mhz
        +SSLeay 0.7.3r 20-May-1997
        +built on Mon Jun  2 00:55:51 EST 1997
        +options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,16,long) idea(int) blowfish(ptr)
        +C flags:gcc -O3 -fomit-frame-pointer -mv8 -Wall
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                54.88k      154.52k      210.35k      231.08k      237.21k
        +md5               550.75k     2460.49k     4116.01k     4988.74k     5159.86k
        +sha               340.28k     1461.76k     2430.10k     2879.87k     2999.15k
        +sha1              307.27k     1298.41k     2136.26k     2540.07k     2658.28k
        +rc4              2652.21k     2805.24k     3301.63k     4003.98k     4071.18k
        +des cbc           811.78k      903.93k      914.19k      921.60k      932.29k
        +des ede3          328.21k      344.93k      349.64k      351.48k      345.07k
        +idea cbc          685.06k      727.42k      734.41k      730.11k      739.21k
        +rc2 cbc           718.59k      777.02k      781.96k      784.38k      782.60k
        +blowfish cbc     1268.85k     1520.64k     1568.88k     1587.54k     1591.98k
        +rsa  512 bits   0.037s   0.005
        +rsa 1024 bits   0.213s   0.006
        +rsa 2048 bits   1.471s   0.053
        +rsa 4096 bits  11.100s   0.202
        +dsa  512 bits   0.038s   0.074
        +dsa 1024 bits   0.128s   0.248
        +dsa 2048 bits   0.473s   0.959
        +
        diff --git a/vendor/openssl/openssl/times/sparc2 b/vendor/openssl/openssl/times/sparc2
        new file mode 100644
        index 000000000..4b0dd805e
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/sparc2
        @@ -0,0 +1,21 @@
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                14.56k       40.25k       54.95k       60.13k       62.18k
        +mdc2               53.59k       57.45k       58.11k       58.21k       58.51k
        +md5               176.95k      764.75k     1270.36k     1520.14k     1608.36k
        +hmac(md5)          55.88k      369.70k      881.15k     1337.05k     1567.40k
        +sha1               92.69k      419.75k      723.63k      878.82k      939.35k
        +rc4              1247.28k     1414.09k     1434.30k     1434.34k     1441.13k
        +des cbc           284.41k      318.58k      323.07k      324.09k      323.87k
        +des ede3          109.99k      119.99k      121.60k      121.87k      121.66k
        +idea cbc           43.06k       43.68k       43.84k       43.64k       44.07k
        +rc2 cbc           278.85k      311.44k      316.50k      316.57k      317.37k
        +blowfish cbc      468.89k      569.35k      581.61k      568.34k      559.54k
        +cast cbc          285.84k      338.79k      345.71k      346.19k      341.09k
        +                  sign    verify
        +rsa  512 bits   0.4175s   0.0519s
        +rsa 1024 bits   2.9325s   0.1948s
        +rsa 2048 bits  22.3600s   0.7669s
        +		  sign    verify
        +dsa  512 bits   0.5178s   1.0300s
        +dsa 1024 bits   1.8780s   3.7167s
        +dsa 2048 bits   7.3500s  14.4800s
        diff --git a/vendor/openssl/openssl/times/sparcLX.t b/vendor/openssl/openssl/times/sparcLX.t
        new file mode 100644
        index 000000000..2fdaed7cc
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/sparcLX.t
        @@ -0,0 +1,22 @@
        +Sparc Station LX
        +SSLeay 0.7.3 30-Apr-1997
        +built on Thu May  1 10:44:02 EST 1997
        +options:bn(64,32) md2(int) rc4(ptr,char) des(idx,cisc,16,long) idea(int) blowfish(ptr)
        +C flags:gcc -O3 -fomit-frame-pointer -mv8 -Wall
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2                17.60k       48.72k       66.47k       72.70k       74.72k
        +md5               226.24k     1082.21k     1982.72k     2594.02k     2717.01k
        +sha                71.38k      320.71k      551.08k      677.76k      720.90k
        +sha1               63.08k      280.79k      473.86k      576.94k      608.94k
        +rc4              1138.30k     1257.67k     1304.49k     1377.78k     1364.42k
        +des cbc           265.34k      308.85k      314.28k      315.39k      317.20k
        +des ede3           83.23k       93.13k       94.04k       94.50k       94.63k
        +idea cbc          254.48k      274.26k      275.88k      274.68k      275.80k
        +rc2 cbc           328.27k      375.39k      381.43k      381.61k      380.83k
        +blowfish cbc      487.00k      498.02k      510.12k      515.41k      516.10k
        +rsa  512 bits   0.093s
        +rsa 1024 bits   0.537s
        +rsa 2048 bits   3.823s
        +rsa 4096 bits  28.650s
        +
        diff --git a/vendor/openssl/openssl/times/usparc.t b/vendor/openssl/openssl/times/usparc.t
        new file mode 100644
        index 000000000..2215624f9
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/usparc.t
        @@ -0,0 +1,25 @@
        +Sparc 2000? - Solaris 2.5.1 - 167mhz Ultra sparc
        +
        +SSLeay 0.7.3r 20-May-1997
        +built on Mon Jun  2 02:25:48 EST 1997
        +options:bn(64,32) md2(int) rc4(ptr,char) des(ptr,risc1,16,long) idea(int) blowfish(ptr)
        +C flags:cc cc -xtarget=ultra -xarch=v8plus -Xa -xO5 -Xa -DB_ENDIAN
        +The 'numbers' are in 1000s of bytes per second processed.
        +type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
        +md2               135.23k      389.87k      536.66k      591.87k      603.48k
        +md5              1534.38k     6160.41k     9842.69k    11446.95k    11993.09k
        +sha              1178.30k     5020.74k     8532.22k    10275.50k    11010.05k
        +sha1             1114.22k     4703.94k     7703.81k     9236.14k     9756.67k
        +rc4             10818.03k    13327.57k    13711.10k    13810.69k    13836.29k
        +des cbc          3052.44k     3320.02k     3356.25k     3369.98k     3295.91k
        +des ede3         1310.32k     1359.98k     1367.47k     1362.94k     1362.60k
        +idea cbc         1749.52k     1833.13k     1844.74k     1848.32k     1848.66k
        +rc2 cbc          1950.25k     2053.23k     2064.21k     2072.58k     2072.58k
        +blowfish cbc     4927.16k     5659.75k     5762.73k     5797.55k     5805.40k
        +rsa  512 bits   0.021s   0.003
        +rsa 1024 bits   0.126s   0.003
        +rsa 2048 bits   0.888s   0.032
        +rsa 4096 bits   6.770s   0.122
        +dsa  512 bits   0.022s   0.043
        +dsa 1024 bits   0.076s   0.151
        +dsa 2048 bits   0.286s   0.574
        diff --git a/vendor/openssl/openssl/times/x86/bfs.cpp b/vendor/openssl/openssl/times/x86/bfs.cpp
        new file mode 100644
        index 000000000..d74c45776
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/bfs.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/blowfish.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	BF_KEY key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			BF_encrypt(&data[0],&key);
        +			GetTSC(s1);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			BF_encrypt(&data[0],&key);
        +			GetTSC(e2);
        +			BF_encrypt(&data[0],&key);
        +			}
        +
        +		printf("blowfish %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/x86/casts.cpp b/vendor/openssl/openssl/times/x86/casts.cpp
        new file mode 100644
        index 000000000..7661191ac
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/casts.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/cast.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	CAST_KEY key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			CAST_encrypt(&data[0],&key);
        +			GetTSC(s1);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			CAST_encrypt(&data[0],&key);
        +			GetTSC(e2);
        +			CAST_encrypt(&data[0],&key);
        +			}
        +
        +		printf("cast %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/x86/des3s.cpp b/vendor/openssl/openssl/times/x86/des3s.cpp
        new file mode 100644
        index 000000000..cd2b1126f
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/des3s.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/des.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	des_key_schedule key1,key2,key3;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			GetTSC(s1);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			GetTSC(e2);
        +			des_encrypt3(&data[0],key1,key2,key3);
        +			}
        +
        +		printf("des3 %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/x86/dess.cpp b/vendor/openssl/openssl/times/x86/dess.cpp
        new file mode 100644
        index 000000000..753e67ad9
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/dess.cpp
        @@ -0,0 +1,67 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/des.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	des_key_schedule key;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned long data[2];
        +	int i,j;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<1000; i++) /**/
        +			{
        +			des_encrypt(&data[0],key,1);
        +			GetTSC(s1);
        +			des_encrypt(&data[0],key,1);
        +			des_encrypt(&data[0],key,1);
        +			des_encrypt(&data[0],key,1);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			des_encrypt(&data[0],key,1);
        +			des_encrypt(&data[0],key,1);
        +			des_encrypt(&data[0],key,1);
        +			des_encrypt(&data[0],key,1);
        +			GetTSC(e2);
        +			des_encrypt(&data[0],key,1);
        +			}
        +
        +		printf("des %d %d (%d)\n",
        +			e1-s1,e2-s2,((e2-s2)-(e1-s1)));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/x86/md4s.cpp b/vendor/openssl/openssl/times/x86/md4s.cpp
        new file mode 100644
        index 000000000..c0ec97fc9
        --- /dev/null
        +++ b/vendor/openssl/openssl/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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md4.h>
        +
        +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/vendor/openssl/openssl/times/x86/md5s.cpp b/vendor/openssl/openssl/times/x86/md5s.cpp
        new file mode 100644
        index 000000000..dd343fd4e
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/md5s.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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/md5.h>
        +
        +extern "C" {
        +void md5_block_x86(MD5_CTX *ctx, unsigned char *buffer,int num);
        +}
        +
        +void main(int argc,char *argv[])
        +	{
        +	unsigned char buffer[64*256];
        +	MD5_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++) /**/
        +			{
        +			md5_block_x86(&ctx,buffer,numm);
        +			GetTSC(s1);
        +			md5_block_x86(&ctx,buffer,numm);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			md5_block_x86(&ctx,buffer,num);
        +			GetTSC(e2);
        +			md5_block_x86(&ctx,buffer,num);
        +			}
        +		printf("md5 (%d bytes) %d %d (%.2f)\n",num,
        +			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/x86/rc4s.cpp b/vendor/openssl/openssl/times/x86/rc4s.cpp
        new file mode 100644
        index 000000000..3814fde99
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/rc4s.cpp
        @@ -0,0 +1,73 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/rc4.h>
        +
        +void main(int argc,char *argv[])
        +	{
        +	unsigned char buffer[1024];
        +	RC4_KEY ctx;
        +	unsigned long s1,s2,e1,e2;
        +	unsigned char k[16];
        +	unsigned long data[2];
        +	unsigned char iv[8];
        +	int i,num=64,numm;
        +	int j=0;
        +
        +	if (argc >= 2)
        +		num=atoi(argv[1]);
        +
        +	if (num == 0) num=256;
        +	if (num > 1024-16) num=1024-16;
        +	numm=num+8;
        +
        +	for (j=0; j<6; j++)
        +		{
        +		for (i=0; i<10; i++) /**/
        +			{
        +			RC4(&ctx,numm,buffer,buffer);
        +			GetTSC(s1);
        +			RC4(&ctx,numm,buffer,buffer);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			RC4(&ctx,num,buffer,buffer);
        +			GetTSC(e2);
        +			RC4(&ctx,num,buffer,buffer);
        +			}
        +
        +		printf("RC4 (%d bytes) %d %d (%d) - 8 bytes\n",num,
        +			e1-s1,e2-s2,(e1-s1)-(e2-s2));
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/times/x86/sha1s.cpp b/vendor/openssl/openssl/times/x86/sha1s.cpp
        new file mode 100644
        index 000000000..3103e1871
        --- /dev/null
        +++ b/vendor/openssl/openssl/times/x86/sha1s.cpp
        @@ -0,0 +1,79 @@
        +//
        +// 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 <stdio.h>
        +#include <stdlib.h>
        +#include <openssl/sha.h>
        +
        +extern "C" {
        +void sha1_block_x86(SHA_CTX *ctx, unsigned char *buffer,int num);
        +}
        +
        +void main(int argc,char *argv[])
        +	{
        +	unsigned char buffer[64*256];
        +	SHA_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++) /**/
        +			{
        +			sha1_block_x86(&ctx,buffer,numm);
        +			GetTSC(s1);
        +			sha1_block_x86(&ctx,buffer,numm);
        +			GetTSC(e1);
        +			GetTSC(s2);
        +			sha1_block_x86(&ctx,buffer,num);
        +			GetTSC(e2);
        +			sha1_block_x86(&ctx,buffer,num);
        +			}
        +
        +		printf("sha1 (%d bytes) %d %d (%.2f)\n",num,
        +			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
        +		}
        +	}
        +
        diff --git a/vendor/openssl/openssl/tools/Makefile b/vendor/openssl/openssl/tools/Makefile
        new file mode 100644
        index 000000000..bb6fb71f3
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/Makefile
        @@ -0,0 +1,59 @@
        +#
        +# OpenSSL/tools/Makefile
        +#
        +
        +DIR=	tools
        +TOP=	..
        +CC=	cc
        +INCLUDES= -I$(TOP) -I../../include
        +CFLAG=-g
        +MAKEFILE=	Makefile
        +
        +CFLAGS= $(INCLUDES) $(CFLAG)
        +
        +GENERAL=Makefile
        +TEST=
        +APPS= c_rehash
        +MISC_APPS= c_hash c_info c_issuer c_name
        +
        +all:
        +
        +install:
        +	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
        +	@for i in $(APPS) ; \
        +	do  \
        +	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
        +	mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
        +	done;
        +	@for i in $(MISC_APPS) ; \
        +	do  \
        +	(cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
        +	chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
        +	mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
        +	done;
        +
        +files:
        +	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
        +
        +links:
        +
        +lint:
        +
        +tags:
        +
        +errors:
        +
        +depend:
        +
        +dclean:
        +	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
        +	mv -f Makefile.new $(MAKEFILE)
        +	rm -f c_rehash
        +
        +clean:
        +	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
        +
        +errors:
        +
        +# DO NOT DELETE THIS LINE -- make depend depends on it.
        diff --git a/vendor/openssl/openssl/tools/c89.sh b/vendor/openssl/openssl/tools/c89.sh
        new file mode 100644
        index 000000000..b25c9fda2
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c89.sh
        @@ -0,0 +1,15 @@
        +#!/bin/sh -k
        +#
        +# Re-order arguments so that -L comes first
        +#
        +opts=""
        +lopts=""
        +        
        +for arg in $* ; do
        +  case $arg in
        +    -L*) lopts="$lopts $arg" ;;
        +    *) opts="$opts $arg" ;;
        +  esac
        +done
        +
        +c89 $lopts $opts
        diff --git a/vendor/openssl/openssl/tools/c_hash b/vendor/openssl/openssl/tools/c_hash
        new file mode 100644
        index 000000000..5e0a90817
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c_hash
        @@ -0,0 +1,9 @@
        +#!/bin/sh
        +# print out the hash values 
        +#
        +
        +for i in $*
        +do
        +	h=`openssl x509 -hash -noout -in $i`
        +	echo "$h.0 => $i"
        +done
        diff --git a/vendor/openssl/openssl/tools/c_info b/vendor/openssl/openssl/tools/c_info
        new file mode 100644
        index 000000000..0e1e633b6
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c_info
        @@ -0,0 +1,12 @@
        +#!/bin/sh
        +#
        +# print the subject
        +#
        +
        +for i in $*
        +do
        +	n=`openssl x509 -subject -issuer -enddate -noout -in $i`
        +	echo "$i"
        +	echo "$n"
        +	echo "--------"
        +done
        diff --git a/vendor/openssl/openssl/tools/c_issuer b/vendor/openssl/openssl/tools/c_issuer
        new file mode 100644
        index 000000000..55821ab74
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c_issuer
        @@ -0,0 +1,10 @@
        +#!/bin/sh
        +#
        +# print out the issuer
        +#
        +
        +for i in $*
        +do
        +	n=`openssl x509 -issuer -noout -in $i`
        +	echo "$i	$n"
        +done
        diff --git a/vendor/openssl/openssl/tools/c_name b/vendor/openssl/openssl/tools/c_name
        new file mode 100644
        index 000000000..28800c0b3
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c_name
        @@ -0,0 +1,10 @@
        +#!/bin/sh
        +#
        +# print the subject
        +#
        +
        +for i in $*
        +do
        +	n=`openssl x509 -subject -noout -in $i`
        +	echo "$i	$n"
        +done
        diff --git a/vendor/openssl/openssl/tools/c_rehash b/vendor/openssl/openssl/tools/c_rehash
        new file mode 100644
        index 000000000..6a20011a4
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c_rehash
        @@ -0,0 +1,180 @@
        +#!/usr/bin/perl
        +
        +
        +# Perl c_rehash script, scan all files in a directory
        +# and add symbolic links to their hash values.
        +
        +my $openssl;
        +
        +my $dir = "/usr/local/ssl";
        +my $prefix = "/usr/local/ssl";
        +
        +if(defined $ENV{OPENSSL}) {
        +	$openssl = $ENV{OPENSSL};
        +} else {
        +	$openssl = "openssl";
        +	$ENV{OPENSSL} = $openssl;
        +}
        +
        +my $pwd;
        +eval "require Cwd";
        +if (defined(&Cwd::getcwd)) {
        +	$pwd=Cwd::getcwd();
        +} else {
        +	$pwd=`pwd`; chomp($pwd);
        +}
        +my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; # DOS/Win32 or Unix delimiter?
        +
        +$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); # prefix our path
        +
        +if(! -x $openssl) {
        +	my $found = 0;
        +	foreach (split /$path_delim/, $ENV{PATH}) {
        +		if(-x "$_/$openssl") {
        +			$found = 1;
        +			$openssl = "$_/$openssl";
        +			last;
        +		}	
        +	}
        +	if($found == 0) {
        +		print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
        +		exit 0;
        +	}
        +}
        +
        +if(@ARGV) {
        +	@dirlist = @ARGV;
        +} elsif($ENV{SSL_CERT_DIR}) {
        +	@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
        +} else {
        +	$dirlist[0] = "$dir/certs";
        +}
        +
        +if (-d $dirlist[0]) {
        +	chdir $dirlist[0];
        +	$openssl="$pwd/$openssl" if (!-x $openssl);
        +	chdir $pwd;
        +}
        +
        +foreach (@dirlist) {
        +	if(-d $_ and -w $_) {
        +		hash_dir($_);
        +	}
        +}
        +
        +sub hash_dir {
        +	my %hashlist;
        +	print "Doing $_[0]\n";
        +	chdir $_[0];
        +	opendir(DIR, ".");
        +	my @flist = readdir(DIR);
        +	# Delete any existing symbolic links
        +	foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
        +		if(-l $_) {
        +			unlink $_;
        +		}
        +	}
        +	closedir DIR;
        +	FILE: foreach $fname (grep {/\.pem$/} @flist) {
        +		# Check to see if certificates and/or CRLs present.
        +		my ($cert, $crl) = check_file($fname);
        +		if(!$cert && !$crl) {
        +			print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
        +			next;
        +		}
        +		link_hash_cert($fname) if($cert);
        +		link_hash_crl($fname) if($crl);
        +	}
        +}
        +
        +sub check_file {
        +	my ($is_cert, $is_crl) = (0,0);
        +	my $fname = $_[0];
        +	open IN, $fname;
        +	while(<IN>) {
        +		if(/^-----BEGIN (.*)-----/) {
        +			my $hdr = $1;
        +			if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
        +				$is_cert = 1;
        +				last if($is_crl);
        +			} elsif($hdr eq "X509 CRL") {
        +				$is_crl = 1;
        +				last if($is_cert);
        +			}
        +		}
        +	}
        +	close IN;
        +	return ($is_cert, $is_crl);
        +}
        +
        +
        +# Link a certificate to its subject name hash value, each hash is of
        +# the form <hash>.<n> where n is an integer. If the hash value already exists
        +# then we need to up the value of n, unless its a duplicate in which
        +# case we skip the link. We check for duplicates by comparing the
        +# certificate fingerprints
        +
        +sub link_hash_cert {
        +		my $fname = $_[0];
        +		$fname =~ s/'/'\\''/g;
        +		my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in "$fname"`;
        +		chomp $hash;
        +		chomp $fprint;
        +		$fprint =~ s/^.*=//;
        +		$fprint =~ tr/://d;
        +		my $suffix = 0;
        +		# Search for an unused hash filename
        +		while(exists $hashlist{"$hash.$suffix"}) {
        +			# Hash matches: if fingerprint matches its a duplicate cert
        +			if($hashlist{"$hash.$suffix"} eq $fprint) {
        +				print STDERR "WARNING: Skipping duplicate certificate $fname\n";
        +				return;
        +			}
        +			$suffix++;
        +		}
        +		$hash .= ".$suffix";
        +		print "$fname => $hash\n";
        +		$symlink_exists=eval {symlink("",""); 1};
        +		if ($symlink_exists) {
        +			symlink $fname, $hash;
        +		} else {
        +			open IN,"<$fname" or die "can't open $fname for read";
        +			open OUT,">$hash" or die "can't open $hash for write";
        +			print OUT <IN>;	# does the job for small text files
        +			close OUT;
        +			close IN;
        +		}
        +		$hashlist{$hash} = $fprint;
        +}
        +
        +# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
        +
        +sub link_hash_crl {
        +		my $fname = $_[0];
        +		$fname =~ s/'/'\\''/g;
        +		my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
        +		chomp $hash;
        +		chomp $fprint;
        +		$fprint =~ s/^.*=//;
        +		$fprint =~ tr/://d;
        +		my $suffix = 0;
        +		# Search for an unused hash filename
        +		while(exists $hashlist{"$hash.r$suffix"}) {
        +			# Hash matches: if fingerprint matches its a duplicate cert
        +			if($hashlist{"$hash.r$suffix"} eq $fprint) {
        +				print STDERR "WARNING: Skipping duplicate CRL $fname\n";
        +				return;
        +			}
        +			$suffix++;
        +		}
        +		$hash .= ".r$suffix";
        +		print "$fname => $hash\n";
        +		$symlink_exists=eval {symlink("",""); 1};
        +		if ($symlink_exists) {
        +			symlink $fname, $hash;
        +		} else {
        +			system ("cp", $fname, $hash);
        +		}
        +		$hashlist{$hash} = $fprint;
        +}
        +
        diff --git a/vendor/openssl/openssl/tools/c_rehash.in b/vendor/openssl/openssl/tools/c_rehash.in
        new file mode 100644
        index 000000000..bfc4a69ed
        --- /dev/null
        +++ b/vendor/openssl/openssl/tools/c_rehash.in
        @@ -0,0 +1,180 @@
        +#!/usr/local/bin/perl
        +
        +
        +# Perl c_rehash script, scan all files in a directory
        +# and add symbolic links to their hash values.
        +
        +my $openssl;
        +
        +my $dir;
        +my $prefix;
        +
        +if(defined $ENV{OPENSSL}) {
        +	$openssl = $ENV{OPENSSL};
        +} else {
        +	$openssl = "openssl";
        +	$ENV{OPENSSL} = $openssl;
        +}
        +
        +my $pwd;
        +eval "require Cwd";
        +if (defined(&Cwd::getcwd)) {
        +	$pwd=Cwd::getcwd();
        +} else {
        +	$pwd=`pwd`; chomp($pwd);
        +}
        +my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; # DOS/Win32 or Unix delimiter?
        +
        +$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); # prefix our path
        +
        +if(! -x $openssl) {
        +	my $found = 0;
        +	foreach (split /$path_delim/, $ENV{PATH}) {
        +		if(-x "$_/$openssl") {
        +			$found = 1;
        +			$openssl = "$_/$openssl";
        +			last;
        +		}	
        +	}
        +	if($found == 0) {
        +		print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
        +		exit 0;
        +	}
        +}
        +
        +if(@ARGV) {
        +	@dirlist = @ARGV;
        +} elsif($ENV{SSL_CERT_DIR}) {
        +	@dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR};
        +} else {
        +	$dirlist[0] = "$dir/certs";
        +}
        +
        +if (-d $dirlist[0]) {
        +	chdir $dirlist[0];
        +	$openssl="$pwd/$openssl" if (!-x $openssl);
        +	chdir $pwd;
        +}
        +
        +foreach (@dirlist) {
        +	if(-d $_ and -w $_) {
        +		hash_dir($_);
        +	}
        +}
        +
        +sub hash_dir {
        +	my %hashlist;
        +	print "Doing $_[0]\n";
        +	chdir $_[0];
        +	opendir(DIR, ".");
        +	my @flist = readdir(DIR);
        +	# Delete any existing symbolic links
        +	foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
        +		if(-l $_) {
        +			unlink $_;
        +		}
        +	}
        +	closedir DIR;
        +	FILE: foreach $fname (grep {/\.pem$/} @flist) {
        +		# Check to see if certificates and/or CRLs present.
        +		my ($cert, $crl) = check_file($fname);
        +		if(!$cert && !$crl) {
        +			print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
        +			next;
        +		}
        +		link_hash_cert($fname) if($cert);
        +		link_hash_crl($fname) if($crl);
        +	}
        +}
        +
        +sub check_file {
        +	my ($is_cert, $is_crl) = (0,0);
        +	my $fname = $_[0];
        +	open IN, $fname;
        +	while(<IN>) {
        +		if(/^-----BEGIN (.*)-----/) {
        +			my $hdr = $1;
        +			if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
        +				$is_cert = 1;
        +				last if($is_crl);
        +			} elsif($hdr eq "X509 CRL") {
        +				$is_crl = 1;
        +				last if($is_cert);
        +			}
        +		}
        +	}
        +	close IN;
        +	return ($is_cert, $is_crl);
        +}
        +
        +
        +# Link a certificate to its subject name hash value, each hash is of
        +# the form <hash>.<n> where n is an integer. If the hash value already exists
        +# then we need to up the value of n, unless its a duplicate in which
        +# case we skip the link. We check for duplicates by comparing the
        +# certificate fingerprints
        +
        +sub link_hash_cert {
        +		my $fname = $_[0];
        +		$fname =~ s/'/'\\''/g;
        +		my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in "$fname"`;
        +		chomp $hash;
        +		chomp $fprint;
        +		$fprint =~ s/^.*=//;
        +		$fprint =~ tr/://d;
        +		my $suffix = 0;
        +		# Search for an unused hash filename
        +		while(exists $hashlist{"$hash.$suffix"}) {
        +			# Hash matches: if fingerprint matches its a duplicate cert
        +			if($hashlist{"$hash.$suffix"} eq $fprint) {
        +				print STDERR "WARNING: Skipping duplicate certificate $fname\n";
        +				return;
        +			}
        +			$suffix++;
        +		}
        +		$hash .= ".$suffix";
        +		print "$fname => $hash\n";
        +		$symlink_exists=eval {symlink("",""); 1};
        +		if ($symlink_exists) {
        +			symlink $fname, $hash;
        +		} else {
        +			open IN,"<$fname" or die "can't open $fname for read";
        +			open OUT,">$hash" or die "can't open $hash for write";
        +			print OUT <IN>;	# does the job for small text files
        +			close OUT;
        +			close IN;
        +		}
        +		$hashlist{$hash} = $fprint;
        +}
        +
        +# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
        +
        +sub link_hash_crl {
        +		my $fname = $_[0];
        +		$fname =~ s/'/'\\''/g;
        +		my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
        +		chomp $hash;
        +		chomp $fprint;
        +		$fprint =~ s/^.*=//;
        +		$fprint =~ tr/://d;
        +		my $suffix = 0;
        +		# Search for an unused hash filename
        +		while(exists $hashlist{"$hash.r$suffix"}) {
        +			# Hash matches: if fingerprint matches its a duplicate cert
        +			if($hashlist{"$hash.r$suffix"} eq $fprint) {
        +				print STDERR "WARNING: Skipping duplicate CRL $fname\n";
        +				return;
        +			}
        +			$suffix++;
        +		}
        +		$hash .= ".r$suffix";
        +		print "$fname => $hash\n";
        +		$symlink_exists=eval {symlink("",""); 1};
        +		if ($symlink_exists) {
        +			symlink $fname, $hash;
        +		} else {
        +			system ("cp", $fname, $hash);
        +		}
        +		$hashlist{$hash} = $fprint;
        +}
        +
        diff --git a/vendor/openssl/openssl/util/FreeBSD.sh b/vendor/openssl/openssl/util/FreeBSD.sh
        new file mode 100644
        index 000000000..db8edfc6a
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/FreeBSD.sh
        @@ -0,0 +1,6 @@
        +#!/bin/sh
        +
        +perl util/perlpath.pl /usr/bin
        +perl util/ssldir.pl /usr/local  
        +perl util/mk1mf.pl FreeBSD >Makefile.FreeBSD
        +perl Configure FreeBSD
        diff --git a/vendor/openssl/openssl/util/add_cr.pl b/vendor/openssl/openssl/util/add_cr.pl
        new file mode 100644
        index 000000000..c7b62c11e
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/add_cr.pl
        @@ -0,0 +1,123 @@
        +#!/usr/local/bin/perl
        +#
        +# This adds a copyright message to a souce code file.
        +# It also gets the file name correct.
        +#
        +# perl util/add_cr.pl *.[ch] */*.[ch] */*/*.[ch]
        +#
        +
        +foreach (@ARGV)
        +	{
        +	&dofile($_);
        +	}
        +
        +sub dofile
        +	{
        +	local($file)=@_;
        +
        +	open(IN,"<$file") || die "unable to open $file:$!\n";
        +
        +	print STDERR "doing $file\n";
        +	@in=<IN>;
        +
        +	return(1) if ($in[0] =~ / NOCW /);
        +
        +	@out=();
        +	open(OUT,">$file.out") || die "unable to open $file.$$:$!\n";
        +	push(@out,"/* $file */\n");
        +	if (($in[1] !~ /^\/\* Copyright \(C\) [0-9-]+ Eric Young \(eay\@cryptsoft.com\)/))
        +		{
        +		push(@out,&Copyright);
        +		$i=2;
        +		@a=grep(/ Copyright \(C\) /,@in);
        +		if ($#a >= 0)
        +			{
        +			while (($i <= $#in) && ($in[$i] ne " */\n"))
        +				{ $i++; }
        +			$i++ if ($in[$i] eq " */\n");
        +
        +			while (($i <= $#in) && ($in[$i] =~ /^\s*$/))
        +				{ $i++; }
        +
        +			push(@out,"\n");
        +			for ( ; $i <= $#in; $i++)
        +				{ push(@out,$in[$i]); }
        +			}
        +		else
        +			{ push(@out,@in); }
        +		}
        +	else
        +		{
        +		shift(@in);
        +		push(@out,@in);
        +		}
        +	print OUT @out;
        +	close(IN);
        +	close(OUT);
        +	rename("$file","$file.orig") || die "unable to rename $file:$!\n";
        +	rename("$file.out",$file) || die "unable to rename $file.out:$!\n";
        +	}
        +
        +
        +
        +sub Copyright
        +	{
        +	return <<'EOF';
        +/* 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.]
        + */
        +EOF
        +	}
        diff --git a/vendor/openssl/openssl/util/bat.sh b/vendor/openssl/openssl/util/bat.sh
        new file mode 100644
        index 000000000..4d9a8287d
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/bat.sh
        @@ -0,0 +1,134 @@
        +#!/usr/local/bin/perl
        +
        +$infile="/home/eay/ssl/SSLeay/MINFO";
        +
        +open(IN,"<$infile") || die "unable to open $infile:$!\n";
        +$_=<IN>;
        +for (;;)
        +	{
        +	chop;
        +
        +	($key,$val)=/^([^=]+)=(.*)/;
        +	if ($key eq "RELATIVE_DIRECTORY")
        +		{
        +		if ($lib ne "")
        +			{
        +			$uc=$lib;
        +			$uc =~ s/^lib(.*)\.a/$1/;
        +			$uc =~ tr/a-z/A-Z/;
        +			$lib_nam{$uc}=$uc;
        +			$lib_obj{$uc}.=$libobj." ";
        +			}
        +		last if ($val eq "FINISHED");
        +		$lib="";
        +		$libobj="";
        +		$dir=$val;
        +		}
        +
        +	if ($key eq "TEST")
        +		{ $test.=&var_add($dir,$val); }
        +
        +	if (($key eq "PROGS") || ($key eq "E_OBJ"))
        +		{ $e_exe.=&var_add($dir,$val); }
        +
        +	if ($key eq "LIB")
        +		{
        +		$lib=$val;
        +		$lib =~ s/^.*\/([^\/]+)$/$1/;
        +		}
        +
        +	if ($key eq "EXHEADER")
        +		{ $exheader.=&var_add($dir,$val); }
        +
        +	if ($key eq "HEADER")
        +		{ $header.=&var_add($dir,$val); }
        +
        +	if ($key eq "LIBSRC")
        +		{ $libsrc.=&var_add($dir,$val); }
        +
        +	if (!($_=<IN>))
        +		{ $_="RELATIVE_DIRECTORY=FINISHED\n"; }
        +	}
        +close(IN);
        +
        +@a=split(/\s+/,$libsrc);
        +foreach (@a)
        +	{
        +	print "${_}.c\n";
        +	}
        +
        +sub var_add
        +	{
        +	local($dir,$val)=@_;
        +	local(@a,$_,$ret);
        +
        +	return("") if $no_engine && $dir =~ /\/engine/;
        +	return("") if $no_idea && $dir =~ /\/idea/;
        +	return("") if $no_rc2  && $dir =~ /\/rc2/;
        +	return("") if $no_rc4  && $dir =~ /\/rc4/;
        +	return("") if $no_rsa  && $dir =~ /\/rsa/;
        +	return("") if $no_rsa  && $dir =~ /^rsaref/;
        +	return("") if $no_dsa  && $dir =~ /\/dsa/;
        +	return("") if $no_dh   && $dir =~ /\/dh/;
        +	if ($no_des && $dir =~ /\/des/)
        +		{
        +		if ($val =~ /read_pwd/)
        +			{ return("$dir/read_pwd "); }
        +		else
        +			{ return(""); }
        +		}
        +	return("") if $no_mdc2 && $dir =~ /\/mdc2/;
        +	return("") if $no_sock && $dir =~ /\/proxy/;
        +	return("") if $no_bf   && $dir =~ /\/bf/;
        +	return("") if $no_cast && $dir =~ /\/cast/;
        +
        +	$val =~ s/^\s*(.*)\s*$/$1/;
        +	@a=split(/\s+/,$val);
        +	grep(s/\.[och]$//,@a);
        +
        +	@a=grep(!/^e_.*_3d$/,@a) if $no_des;
        +	@a=grep(!/^e_.*_d$/,@a) if $no_des;
        +	@a=grep(!/^e_.*_i$/,@a) if $no_idea;
        +	@a=grep(!/^e_.*_r2$/,@a) if $no_rc2;
        +	@a=grep(!/^e_.*_bf$/,@a) if $no_bf;
        +	@a=grep(!/^e_.*_c$/,@a) if $no_cast;
        +	@a=grep(!/^e_rc4$/,@a) if $no_rc4;
        +
        +	@a=grep(!/(^s2_)|(^s23_)/,@a) if $no_ssl2;
        +	@a=grep(!/(^s3_)|(^s23_)/,@a) if $no_ssl3;
        +
        +	@a=grep(!/(_sock$)|(_acpt$)|(_conn$)|(^pxy_)/,@a) if $no_sock;
        +
        +	@a=grep(!/(^md2)|(_md2$)/,@a) if $no_md2;
        +	@a=grep(!/(^md5)|(_md5$)/,@a) if $no_md5;
        +
        +	@a=grep(!/(^d2i_r_)|(^i2d_r_)/,@a) if $no_rsa;
        +	@a=grep(!/(^p_open$)|(^p_seal$)/,@a) if $no_rsa;
        +	@a=grep(!/(^pem_seal$)/,@a) if $no_rsa;
        +
        +	@a=grep(!/(m_dss$)|(m_dss1$)/,@a) if $no_dsa;
        +	@a=grep(!/(^d2i_s_)|(^i2d_s_)|(_dsap$)/,@a) if $no_dsa;
        +
        +	@a=grep(!/^n_pkey$/,@a) if $no_rsa || $no_rc4;
        +
        +	@a=grep(!/_dhp$/,@a) if $no_dh;
        +
        +	@a=grep(!/(^sha[^1])|(_sha$)|(m_dss$)/,@a) if $no_sha;
        +	@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
        +	@a=grep(!/_mdc2$/,@a) if $no_mdc2;
        +
        +	@a=grep(!/^engine$/,@a) if $no_engine;
        +	@a=grep(!/(^rsa$)|(^genrsa$)|(^req$)|(^ca$)/,@a) if $no_rsa;
        +	@a=grep(!/(^dsa$)|(^gendsa$)|(^dsaparam$)/,@a) if $no_dsa;
        +	@a=grep(!/^gendsa$/,@a) if $no_sha1;
        +	@a=grep(!/(^dh$)|(^gendh$)/,@a) if $no_dh;
        +
        +	@a=grep(!/(^dh)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
        +
        +	grep($_="$dir/$_",@a);
        +	@a=grep(!/(^|\/)s_/,@a) if $no_sock;
        +	@a=grep(!/(^|\/)bio_sock/,@a) if $no_sock;
        +	$ret=join(' ',@a)." ";
        +	return($ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/util/ck_errf.pl b/vendor/openssl/openssl/util/ck_errf.pl
        new file mode 100644
        index 000000000..f13af5c50
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/ck_errf.pl
        @@ -0,0 +1,64 @@
        +#!/usr/local/bin/perl
        +#
        +# This is just a quick script to scan for cases where the 'error'
        +# function name in a XXXerr() macro is wrong.
        +# 
        +# Run in the top level by going
        +# perl util/ck_errf.pl */*.c */*/*.c
        +#
        +
        +my $err_strict = 0;
        +my $bad = 0;
        +
        +foreach $file (@ARGV)
        +	{
        +	if ($file eq "-strict")
        +		{
        +		$err_strict = 1;
        +		next;
        +		}
        +	open(IN,"<$file") || die "unable to open $file\n";
        +	$func="";
        +	while (<IN>)
        +		{
        +		if (!/;$/ && /^([a-zA-Z].*[\s*])?([A-Za-z_0-9]+)\(.*[),]/)
        +			{
        +			/^([^()]*(\([^()]*\)[^()]*)*)\(/;
        +			$1 =~ /([A-Za-z_0-9]*)$/;
        +			$func = $1;
        +			$func =~ tr/A-Z/a-z/;
        +			}
        +		if (/([A-Z0-9]+)err\(([^,]+)/ && ! /ckerr_ignore/)
        +			{
        +			$errlib=$1;
        +			$n=$2;
        +
        +			if ($func eq "")
        +				{ print "$file:$.:???:$n\n"; $bad = 1; next; }
        +
        +			if ($n !~ /([^_]+)_F_(.+)$/)
        +				{
        +		#		print "check -$file:$.:$func:$n\n";
        +				next;
        +				}
        +			$lib=$1;
        +			$n=$2;
        +
        +			if ($lib ne $errlib)
        +				{ print "$file:$.:$func:$n [${errlib}err]\n"; $bad = 1; next; }
        +
        +			$n =~ tr/A-Z/a-z/;
        +			if (($n ne $func) && ($errlib ne "SYS"))
        +				{ print "$file:$.:$func:$n\n"; $bad = 1; next; }
        +	#		print "$func:$1\n";
        +			}
        +		}
        +	close(IN);
        +        }
        +
        +if ($bad && $err_strict)
        +	{
        +	print STDERR "FATAL: error discrepancy\n";
        +	exit 1;
        +	}
        +
        diff --git a/vendor/openssl/openssl/util/clean-depend.pl b/vendor/openssl/openssl/util/clean-depend.pl
        new file mode 100644
        index 000000000..d3525b0ed
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/clean-depend.pl
        @@ -0,0 +1,58 @@
        +#!/usr/local/bin/perl -w
        +# Clean the dependency list in a makefile of standard includes...
        +# Written by Ben Laurie <ben@algroup.co.uk> 19 Jan 1999
        +
        +use strict;
        +
        +while(<STDIN>) {
        +    print;
        +    last if /^# DO NOT DELETE THIS LINE/;
        +}
        +
        +my %files;
        +
        +my $thisfile="";
        +while(<STDIN>) {
        +    my ($dummy, $file,$deps)=/^((.*):)? (.*)$/;
        +    my $origfile="";
        +    $thisfile=$file if defined $file;
        +    next if !defined $deps;
        +    $origfile=$thisfile;
        +    $origfile=~s/\.o$/.c/;
        +    my @deps=split ' ',$deps;
        +    @deps=grep(!/^\//,@deps);
        +    @deps=grep(!/^\\$/,@deps);
        +    @deps=grep(!/^$origfile$/,@deps);
        +# pull out the kludged kerberos header (if present).
        +    @deps=grep(!/^[.\/]+\/krb5.h/,@deps);
        +    push @{$files{$thisfile}},@deps;
        +}
        +
        +my $file;
        +foreach $file (sort keys %files) {
        +    my $len=0;
        +    my $dep;
        +    my $origfile=$file;
        +    $origfile=~s/\.o$/.c/;
        +    $file=~s/^\.\///;
        +    push @{$files{$file}},$origfile;
        +    my $prevdep="";
        +
        +    # Remove leading ./ before sorting
        +    my @deps = map { $_ =~ s/^\.\///; $_ } @{$files{$file}};
        +
        +    foreach $dep (sort @deps) {
        +	$dep=~s/^\.\///;
        +	next if $prevdep eq $dep; # to exterminate duplicates...
        +	$prevdep = $dep;
        +	$len=0 if $len+length($dep)+1 >= 80;
        +	if($len == 0) {
        +	    print "\n$file:";
        +	    $len=length($file)+1;
        +	}
        +	print " $dep";
        +	$len+=length($dep)+1;
        +    }
        +}
        +
        +print "\n";
        diff --git a/vendor/openssl/openssl/util/copy.pl b/vendor/openssl/openssl/util/copy.pl
        new file mode 100644
        index 000000000..eba6d5815
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/copy.pl
        @@ -0,0 +1,70 @@
        +#!/usr/local/bin/perl
        +
        +use Fcntl;
        +
        +
        +# copy.pl
        +
        +# Perl script 'copy' comment. On Windows the built in "copy" command also
        +# copies timestamps: this messes up Makefile dependencies.
        +
        +my $stripcr = 0;
        +
        +my $arg;
        +
        +foreach $arg (@ARGV) {
        +	if ($arg eq "-stripcr")
        +		{
        +		$stripcr = 1;
        +		next;
        +		}
        +	$arg =~ s|\\|/|g;	# compensate for bug/feature in cygwin glob...
        +	foreach (glob $arg)
        +		{
        +		push @filelist, $_;
        +		}
        +}
        +
        +$fnum = @filelist;
        +
        +if ($fnum <= 1)
        +	{
        +	die "Need at least two filenames";
        +	}
        +
        +$dest = pop @filelist;
        +	
        +if ($fnum > 2 && ! -d $dest)
        +	{
        +	die "Destination must be a directory";
        +	}
        +
        +foreach (@filelist)
        +	{
        +	if (-d $dest)
        +		{
        +		$dfile = $_;
        +		$dfile =~ s|^.*[/\\]([^/\\]*)$|$1|;
        +		$dfile = "$dest/$dfile";
        +		}
        +	else
        +		{
        +		$dfile = $dest;
        +		}
        +	sysopen(IN, $_, O_RDONLY|O_BINARY) || die "Can't Open $_";
        +	sysopen(OUT, $dfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY)
        +					|| die "Can't Open $dfile";
        +	while (sysread IN, $buf, 10240)
        +		{
        +		if ($stripcr)
        +			{
        +			$buf =~ tr/\015//d;
        +			}
        +		syswrite(OUT, $buf, length($buf));
        +		}
        +	close(IN);
        +	close(OUT);
        +	print "Copying: $_ to $dfile\n";
        +	}
        +		
        +
        diff --git a/vendor/openssl/openssl/util/cygwin.sh b/vendor/openssl/openssl/util/cygwin.sh
        new file mode 100644
        index 000000000..cfdb04d2a
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/cygwin.sh
        @@ -0,0 +1,154 @@
        +#!/bin/bash
        +#
        +# This script configures, builds and packs the binary package for
        +# the Cygwin net distribution version of OpenSSL
        +#
        +
        +# Uncomment when debugging
        +#set -x
        +
        +CONFIG_OPTIONS="--prefix=/usr shared zlib no-idea no-rc5"
        +INSTALL_PREFIX=/tmp/install/INSTALL
        +
        +VERSION=
        +SHLIB_VERSION_NUMBER=
        +SUBVERSION=$1
        +
        +function cleanup()
        +{
        +  rm -rf ${INSTALL_PREFIX}/etc
        +  rm -rf ${INSTALL_PREFIX}/usr
        +}
        +
        +function get_openssl_version()
        +{
        +  eval `grep '^VERSION=' Makefile`
        +  if [ -z "${VERSION}" ]
        +  then
        +    echo "Error: Couldn't retrieve OpenSSL version from Makefile."
        +    echo "       Check value of variable VERSION in Makefile."
        +    exit 1
        +  fi
        +  eval `grep '^SHLIB_VERSION_NUMBER=' Makefile`
        +  if [ -z "${SHLIB_VERSION_NUMBER}" ]
        +  then
        +    echo "Error: Couldn't retrieve OpenSSL shared lib version from Makefile."
        +    echo " Check value of variable SHLIB_VERSION_NUMBER in Makefile."
        +    exit 1
        +  fi
        +}
        +
        +function base_install()
        +{
        +  mkdir -p ${INSTALL_PREFIX}
        +  cleanup
        +  make install INSTALL_PREFIX="${INSTALL_PREFIX}"
        +}
        +
        +function doc_install()
        +{
        +  DOC_DIR=${INSTALL_PREFIX}/usr/share/doc/openssl
        +
        +  mkdir -p ${DOC_DIR}
        +  cp CHANGES CHANGES.SSLeay INSTALL LICENSE NEWS README ${DOC_DIR}
        +
        +  create_cygwin_readme
        +}
        +
        +function certs_install()
        +{
        +  CERTS_DIR=${INSTALL_PREFIX}/usr/ssl/certs
        +
        +  mkdir -p ${CERTS_DIR}
        +  cp -rp certs/* ${CERTS_DIR}
        +}
        +
        +function create_cygwin_readme()
        +{
        +  README_DIR=${INSTALL_PREFIX}/usr/share/doc/Cygwin
        +  README_FILE=${README_DIR}/openssl-${VERSION}.README
        +
        +  mkdir -p ${README_DIR}
        +  cat > ${README_FILE} <<- EOF
        +	The Cygwin version has been built using the following configure:
        +
        +	  ./config ${CONFIG_OPTIONS}
        +
        +	The IDEA and RC5 algorithms are disabled due to patent and/or
        +	licensing issues.
        +	EOF
        +}
        +
        +function create_profile_files()
        +{
        +  PROFILE_DIR=${INSTALL_PREFIX}/etc/profile.d
        +
        +  mkdir -p $PROFILE_DIR
        +  cat > ${PROFILE_DIR}/openssl.sh <<- "EOF"
        +	export MANPATH="${MANPATH}:/usr/ssl/man"
        +	EOF
        +  cat > ${PROFILE_DIR}/openssl.csh <<- "EOF"
        +	if ( $?MANPATH ) then
        +	  setenv MANPATH "${MANPATH}:/usr/ssl/man"
        +	else
        +	  setenv MANPATH ":/usr/ssl/man"
        +	endif
        +	EOF
        +}
        +
        +if [ -z "${SUBVERSION}" ]
        +then
        +  echo "Usage: $0 subversion"
        +  exit 1
        +fi
        +
        +if [ ! -f config ]
        +then
        +  echo "You must start this script in the OpenSSL toplevel source dir."
        +  exit 1
        +fi
        +
        +./config ${CONFIG_OPTIONS}
        +
        +get_openssl_version
        +
        +make depend || exit 1
        +
        +make || exit 1
        +
        +base_install
        +
        +doc_install
        +
        +certs_install
        +
        +create_cygwin_readme
        +
        +create_profile_files
        +
        +cd ${INSTALL_PREFIX}
        +chmod u+w usr/lib/engines/*.so
        +strip usr/bin/*.exe usr/bin/*.dll usr/lib/engines/*.so
        +chmod u-w usr/lib/engines/*.so
        +
        +# Runtime package
        +tar cjf libopenssl${SHLIB_VERSION_NUMBER//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2 \
        +     usr/bin/cyg*dll
        +# Base package
        +find etc usr/bin/openssl.exe usr/bin/c_rehash usr/lib/engines usr/share/doc \
        +     usr/ssl/certs usr/ssl/man/man[157] usr/ssl/misc usr/ssl/openssl.cnf \
        +     usr/ssl/private \
        +     -empty -o \! -type d |
        +tar cjfT openssl-${VERSION}-${SUBVERSION}.tar.bz2 -
        +# Development package
        +find usr/include usr/lib/*.a usr/lib/pkgconfig usr/ssl/man/man3 \
        +     -empty -o \! -type d |
        +tar cjfT openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2 -
        +
        +ls -l openssl-${VERSION}-${SUBVERSION}.tar.bz2
        +ls -l openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2
        +ls -l libopenssl${SHLIB_VERSION_NUMBER//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2
        +
        +cleanup
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/util/deleof.pl b/vendor/openssl/openssl/util/deleof.pl
        new file mode 100644
        index 000000000..155acd88f
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/deleof.pl
        @@ -0,0 +1,7 @@
        +#!/usr/local/bin/perl
        +
        +while (<>)
        +	{
        +	print
        +	last if (/^# DO NOT DELETE THIS LINE/);
        +	}
        diff --git a/vendor/openssl/openssl/util/deltree.com b/vendor/openssl/openssl/util/deltree.com
        new file mode 100644
        index 000000000..9f36b1a5e
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/deltree.com
        @@ -0,0 +1,34 @@
        +$! DELTREE.COM
        +$
        +$ call deltree 'p1'
        +$ exit $status
        +$
        +$ deltree: subroutine ! P1 is a name of a directory
        +$	on control_y then goto dt_STOP
        +$	on warning then goto dt_exit
        +$	_dt_def = f$trnlnm("SYS$DISK")+f$directory()
        +$	if f$parse(p1) .eqs. "" then exit
        +$	set default 'f$parse(p1,,,"DEVICE")''f$parse(p1,,,"DIRECTORY")'
        +$	p1 = f$parse(p1,,,"NAME") + f$parse(p1,,,"TYPE")
        +$	_fp = f$parse(".DIR",p1)
        +$ dt_loop:
        +$	_f = f$search(_fp)
        +$	if _f .eqs. "" then goto dt_loopend
        +$	call deltree [.'f$parse(_f,,,"NAME")']*.*
        +$	goto dt_loop
        +$ dt_loopend:
        +$	_fp = f$parse(p1,".;*")
        +$	if f$search(_fp) .eqs. "" then goto dt_exit
        +$	set noon
        +$	set file/prot=(S:RWED,O:RWED,G:RWED,W:RWED) '_fp'
        +$	set on
        +$	delete/nolog '_fp'
        +$ dt_exit:
        +$	set default '_dt_def'
        +$	goto dt_end
        +$ dt_STOP:
        +$	set default '_dt_def'
        +$	stop/id=""
        +$	exit
        +$ dt_end:
        +$	endsubroutine
        diff --git a/vendor/openssl/openssl/util/dirname.pl b/vendor/openssl/openssl/util/dirname.pl
        new file mode 100644
        index 000000000..d7a66d96a
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/dirname.pl
        @@ -0,0 +1,18 @@
        +#!/usr/local/bin/perl
        +
        +if ($#ARGV < 0) {
        +    die "dirname.pl: too few arguments\n";
        +} elsif ($#ARGV > 0) {
        +    die "dirname.pl: too many arguments\n";
        +}
        +
        +my $d = $ARGV[0];
        +
        +if ($d =~ m|.*/.*|) {
        +    $d =~ s|/[^/]*$||;
        +} else {
        +    $d = ".";
        +}
        +
        +print $d,"\n";
        +exit(0);
        diff --git a/vendor/openssl/openssl/util/do_ms.sh b/vendor/openssl/openssl/util/do_ms.sh
        new file mode 100644
        index 000000000..515b074cf
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/do_ms.sh
        @@ -0,0 +1,19 @@
        +#!/bin/sh
        +#
        +# generate the Microsoft makefiles and .def files
        +#
        +
        +PATH=util:../util:$PATH
        +
        +# perl util/mk1mf.pl no-sock VC-MSDOS >ms/msdos.mak
        +# perl util/mk1mf.pl VC-W31-32 >ms/w31.mak
        +perl util/mk1mf.pl dll VC-WIN16 >ms/w31dll.mak
        +# perl util/mk1mf.pl VC-WIN32 >ms/nt.mak
        +perl util/mk1mf.pl dll VC-WIN32 >ms/ntdll.mak
        +perl util/mk1mf.pl Mingw32 >ms/mingw32.mak
        +perl util/mk1mf.pl Mingw32-files >ms/mingw32f.mak
        +
        +perl util/mkdef.pl 16 libeay > ms/libeay16.def
        +perl util/mkdef.pl 32 libeay > ms/libeay32.def
        +perl util/mkdef.pl 16 ssleay > ms/ssleay16.def
        +perl util/mkdef.pl 32 ssleay > ms/ssleay32.def
        diff --git a/vendor/openssl/openssl/util/domd b/vendor/openssl/openssl/util/domd
        new file mode 100644
        index 000000000..bab48cb7a
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/domd
        @@ -0,0 +1,38 @@
        +#!/bin/sh
        +# Do a makedepend, only leave out the standard headers
        +# Written by Ben Laurie <ben@algroup.co.uk> 19 Jan 1999
        +
        +TOP=$1
        +shift
        +if [ "$1" = "-MD" ]; then
        +    shift
        +    MAKEDEPEND=$1
        +    shift
        +fi
        +if [ "$MAKEDEPEND" = "" ]; then MAKEDEPEND=makedepend; fi
        +
        +cp Makefile Makefile.save
        +# fake the presence of Kerberos
        +touch $TOP/krb5.h
        +if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then
        +    args=""
        +    while [ $# -gt 0 ]; do
        +	if [ "$1" != "--" ]; then args="$args $1"; fi
        +	shift
        +    done
        +    sed -e '/^# DO NOT DELETE.*/,$d' < Makefile > Makefile.tmp
        +    echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile.tmp
        +    ${MAKEDEPEND} -Werror -D OPENSSL_DOING_MAKEDEPEND -M $args >> Makefile.tmp || exit 1
        +    ${PERL} $TOP/util/clean-depend.pl < Makefile.tmp > Makefile.new
        +    RC=$?
        +    rm -f Makefile.tmp
        +else
        +    ${MAKEDEPEND} -D OPENSSL_DOING_MAKEDEPEND $@ && \
        +    ${PERL} $TOP/util/clean-depend.pl < Makefile > Makefile.new
        +    RC=$?
        +fi
        +mv Makefile.new Makefile
        +# unfake the presence of Kerberos
        +rm $TOP/krb5.h
        +
        +exit $RC
        diff --git a/vendor/openssl/openssl/util/err-ins.pl b/vendor/openssl/openssl/util/err-ins.pl
        new file mode 100644
        index 000000000..31b70df8d
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/err-ins.pl
        @@ -0,0 +1,33 @@
        +#!/usr/local/bin/perl
        +#
        +# tack error codes onto the end of a file
        +#
        +
        +open(ERR,$ARGV[0]) || die "unable to open error file '$ARGV[0]':$!\n";
        +@err=<ERR>;
        +close(ERR);
        +
        +open(IN,$ARGV[1]) || die "unable to open header file '$ARGV[1]':$!\n";
        +
        +@out="";
        +while (<IN>)
        +	{
        +	push(@out,$_);
        +	last if /BEGIN ERROR CODES/;
        +	}
        +close(IN);
        +
        +open(OUT,">$ARGV[1]") || die "unable to open header file '$ARGV[1]':$1\n";
        +print OUT @out;
        +print OUT @err;
        +print OUT <<"EOF";
        + 
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +
        +EOF
        +close(OUT);
        +
        +
        diff --git a/vendor/openssl/openssl/util/extract-names.pl b/vendor/openssl/openssl/util/extract-names.pl
        new file mode 100644
        index 000000000..35bd6ed84
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/extract-names.pl
        @@ -0,0 +1,26 @@
        +#!/usr/bin/perl
        +
        +$/ = "";			# Eat a paragraph at once.
        +while(<STDIN>) {
        +    chop;
        +    s/\n/ /gm;
        +    if (/^=head1 /) {
        +	$name = 0;
        +    } elsif ($name) {
        +	if (/ - /) {
        +	    s/ - .*//;
        +	    s/,\s+/,/g;
        +	    s/\s+,/,/g;
        +	    s/^\s+//g;
        +	    s/\s+$//g;
        +	    s/\s/_/g;
        +	    push @words, split ',';
        +	}
        +    }
        +    if (/^=head1 *NAME *$/) {
        +	$name = 1;
        +    }
        +}
        +
        +print join("\n", @words),"\n";
        +
        diff --git a/vendor/openssl/openssl/util/extract-section.pl b/vendor/openssl/openssl/util/extract-section.pl
        new file mode 100644
        index 000000000..7a0ba4f69
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/extract-section.pl
        @@ -0,0 +1,12 @@
        +#!/usr/bin/perl
        +
        +while(<STDIN>) {
        +	if (/=for\s+comment\s+openssl_manual_section:(\S+)/)
        +		{
        +		print "$1\n";
        +		exit 0;
        +		}
        +}
        +
        +print "$ARGV[0]\n";
        +
        diff --git a/vendor/openssl/openssl/util/files.pl b/vendor/openssl/openssl/util/files.pl
        new file mode 100644
        index 000000000..41f033e3b
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/files.pl
        @@ -0,0 +1,61 @@
        +#!/usr/local/bin/perl
        +#
        +# used to generate the file MINFO for use by util/mk1mf.pl
        +# It is basically a list of all variables from the passed makefile
        +#
        +
        +$s="";
        +while (<>)
        +	{
        +	chop;
        +	s/#.*//;
        +	if (/^(\S+)\s*=\s*(.*)$/)
        +		{
        +		$o="";
        +		($s,$b)=($1,$2);
        +		for (;;)
        +			{
        +			if ($b =~ /\\$/)
        +				{
        +				chop($b);
        +				$o.=$b." ";
        +				$b=<>;
        +				chop($b);
        +				}
        +			else
        +				{
        +				$o.=$b." ";
        +				last;
        +				}
        +			}
        +		$o =~ s/^\s+//;
        +		$o =~ s/\s+$//;
        +		$o =~ s/\s+/ /g;
        +
        +		$o =~ s/\$[({]([^)}]+)[)}]/$sym{$1}/g;
        +		$sym{$s}=$o;
        +		}
        +	}
        +
        +$pwd=`pwd`; chop($pwd);
        +
        +if ($sym{'TOP'} eq ".")
        +	{
        +	$n=0;
        +	$dir=".";
        +	}
        +else	{
        +	$n=split(/\//,$sym{'TOP'});
        +	@_=split(/\//,$pwd);
        +	$z=$#_-$n+1;
        +	foreach $i ($z .. $#_) { $dir.=$_[$i]."/"; }
        +	chop($dir);
        +	}
        +
        +print "RELATIVE_DIRECTORY=$dir\n";
        +
        +foreach (sort keys %sym)
        +	{
        +	print "$_=$sym{$_}\n";
        +	}
        +print "RELATIVE_DIRECTORY=\n";
        diff --git a/vendor/openssl/openssl/util/fixNT.sh b/vendor/openssl/openssl/util/fixNT.sh
        new file mode 100644
        index 000000000..ab9e766b8
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/fixNT.sh
        @@ -0,0 +1,14 @@
        +#!/bin/sh
        +#
        +# clean up the mess that NT makes of my source tree
        +#
        +
        +if [ -f makefile -a ! -f Makefile ]; then
        +	/bin/mv makefile Makefile
        +fi
        +chmod +x Configure util/*
        +echo cleaning
        +/bin/rm -f `find . -name '*.$$$' -print` 2>/dev/null >/dev/null
        +echo 'removing those damn ^M'
        +perl -pi -e 's/\015//' `find . -type 'f' -print |grep -v '.obj$' |grep -v '.der$' |grep -v '.gz'`
        +make -f Makefile links
        diff --git a/vendor/openssl/openssl/util/install.sh b/vendor/openssl/openssl/util/install.sh
        new file mode 100644
        index 000000000..e1d0c982d
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/install.sh
        @@ -0,0 +1,108 @@
        +#!/bin/sh
        +#
        +# install - install a program, script, or datafile
        +# This comes from X11R5; it is not part of GNU.
        +#
        +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
        +#
        +# This script is compatible with the BSD install script, but was written
        +# from scratch.
        +#
        +
        +
        +# set DOITPROG to echo to test this script
        +
        +doit="${DOITPROG:-}"
        +
        +
        +# put in absolute paths if you don't have them in your path; or use env. vars.
        +
        +mvprog="${MVPROG:-mv}"
        +cpprog="${CPPROG:-cp}"
        +chmodprog="${CHMODPROG:-chmod}"
        +chownprog="${CHOWNPROG:-chown}"
        +chgrpprog="${CHGRPPROG:-chgrp}"
        +stripprog="${STRIPPROG:-strip}"
        +rmprog="${RMPROG:-rm}"
        +
        +instcmd="$mvprog"
        +chmodcmd=""
        +chowncmd=""
        +chgrpcmd=""
        +stripcmd=""
        +rmcmd="$rmprog -f"
        +src=""
        +dst=""
        +
        +while [ x"$1" != x ]; do
        +    case $1 in
        +	-c) instcmd="$cpprog"
        +	    shift
        +	    continue;;
        +
        +	-m) chmodcmd="$chmodprog $2"
        +	    shift
        +	    shift
        +	    continue;;
        +
        +	-o) chowncmd="$chownprog $2"
        +	    shift
        +	    shift
        +	    continue;;
        +
        +	-g) chgrpcmd="$chgrpprog $2"
        +	    shift
        +	    shift
        +	    continue;;
        +
        +	-s) stripcmd="$stripprog"
        +	    shift
        +	    continue;;
        +
        +	*)  if [ x"$src" = x ]
        +	    then
        +		src=$1
        +	    else
        +		dst=$1
        +	    fi
        +	    shift
        +	    continue;;
        +    esac
        +done
        +
        +if [ x"$src" = x ]
        +then
        +	echo "install:  no input file specified"
        +	exit 1
        +fi
        +
        +if [ x"$dst" = x ]
        +then
        +	echo "install:  no destination specified"
        +	exit 1
        +fi
        +
        +
        +# if destination is a directory, append the input filename; if your system
        +# does not like double slashes in filenames, you may need to add some logic
        +
        +if [ -d $dst ]
        +then
        +	dst="$dst"/`basename $src`
        +fi
        +
        +
        +# get rid of the old one and mode the new one in
        +
        +$doit $rmcmd $dst
        +$doit $instcmd $src $dst
        +
        +
        +# and set any options; do chmod last to preserve setuid bits
        +
        +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; fi
        +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; fi
        +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; fi
        +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; fi
        +
        +exit 0
        diff --git a/vendor/openssl/openssl/util/libeay.num b/vendor/openssl/openssl/util/libeay.num
        new file mode 100644
        index 000000000..6debdb60a
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/libeay.num
        @@ -0,0 +1,4313 @@
        +SSLeay                                  1	EXIST::FUNCTION:
        +SSLeay_version                          2	EXIST::FUNCTION:
        +ASN1_BIT_STRING_asn1_meth               3	NOEXIST::FUNCTION:
        +ASN1_HEADER_free                        4	NOEXIST::FUNCTION:
        +ASN1_HEADER_new                         5	NOEXIST::FUNCTION:
        +ASN1_IA5STRING_asn1_meth                6	NOEXIST::FUNCTION:
        +ASN1_INTEGER_get                        7	EXIST::FUNCTION:
        +ASN1_INTEGER_set                        8	EXIST::FUNCTION:
        +ASN1_INTEGER_to_BN                      9	EXIST::FUNCTION:
        +ASN1_OBJECT_create                      10	EXIST::FUNCTION:
        +ASN1_OBJECT_free                        11	EXIST::FUNCTION:
        +ASN1_OBJECT_new                         12	EXIST::FUNCTION:
        +ASN1_PRINTABLE_type                     13	EXIST::FUNCTION:
        +ASN1_STRING_cmp                         14	EXIST::FUNCTION:
        +ASN1_STRING_dup                         15	EXIST::FUNCTION:
        +ASN1_STRING_free                        16	EXIST::FUNCTION:
        +ASN1_STRING_new                         17	EXIST::FUNCTION:
        +ASN1_STRING_print                       18	EXIST::FUNCTION:BIO
        +ASN1_STRING_set                         19	EXIST::FUNCTION:
        +ASN1_STRING_type_new                    20	EXIST::FUNCTION:
        +ASN1_TYPE_free                          21	EXIST::FUNCTION:
        +ASN1_TYPE_new                           22	EXIST::FUNCTION:
        +ASN1_UNIVERSALSTRING_to_string          23	EXIST::FUNCTION:
        +ASN1_UTCTIME_check                      24	EXIST::FUNCTION:
        +ASN1_UTCTIME_print                      25	EXIST::FUNCTION:BIO
        +ASN1_UTCTIME_set                        26	EXIST::FUNCTION:
        +ASN1_check_infinite_end                 27	EXIST::FUNCTION:
        +ASN1_d2i_bio                            28	EXIST::FUNCTION:BIO
        +ASN1_d2i_fp                             29	EXIST::FUNCTION:FP_API
        +ASN1_digest                             30	EXIST::FUNCTION:EVP
        +ASN1_dup                                31	EXIST::FUNCTION:
        +ASN1_get_object                         32	EXIST::FUNCTION:
        +ASN1_i2d_bio                            33	EXIST::FUNCTION:BIO
        +ASN1_i2d_fp                             34	EXIST::FUNCTION:FP_API
        +ASN1_object_size                        35	EXIST::FUNCTION:
        +ASN1_parse                              36	EXIST::FUNCTION:BIO
        +ASN1_put_object                         37	EXIST::FUNCTION:
        +ASN1_sign                               38	EXIST::FUNCTION:EVP
        +ASN1_verify                             39	EXIST::FUNCTION:EVP
        +BF_cbc_encrypt                          40	EXIST::FUNCTION:BF
        +BF_cfb64_encrypt                        41	EXIST::FUNCTION:BF
        +BF_ecb_encrypt                          42	EXIST::FUNCTION:BF
        +BF_encrypt                              43	EXIST::FUNCTION:BF
        +BF_ofb64_encrypt                        44	EXIST::FUNCTION:BF
        +BF_options                              45	EXIST::FUNCTION:BF
        +BF_set_key                              46	EXIST::FUNCTION:BF
        +BIO_CONNECT_free                        47	NOEXIST::FUNCTION:
        +BIO_CONNECT_new                         48	NOEXIST::FUNCTION:
        +BIO_accept                              51	EXIST::FUNCTION:
        +BIO_ctrl                                52	EXIST::FUNCTION:
        +BIO_int_ctrl                            53	EXIST::FUNCTION:
        +BIO_debug_callback                      54	EXIST::FUNCTION:
        +BIO_dump                                55	EXIST::FUNCTION:
        +BIO_dup_chain                           56	EXIST::FUNCTION:
        +BIO_f_base64                            57	EXIST::FUNCTION:BIO
        +BIO_f_buffer                            58	EXIST::FUNCTION:
        +BIO_f_cipher                            59	EXIST::FUNCTION:BIO
        +BIO_f_md                                60	EXIST::FUNCTION:BIO
        +BIO_f_null                              61	EXIST::FUNCTION:
        +BIO_f_proxy_server                      62	NOEXIST::FUNCTION:
        +BIO_fd_non_fatal_error                  63	EXIST::FUNCTION:
        +BIO_fd_should_retry                     64	EXIST::FUNCTION:
        +BIO_find_type                           65	EXIST::FUNCTION:
        +BIO_free                                66	EXIST::FUNCTION:
        +BIO_free_all                            67	EXIST::FUNCTION:
        +BIO_get_accept_socket                   69	EXIST::FUNCTION:
        +BIO_get_filter_bio                      70	NOEXIST::FUNCTION:
        +BIO_get_host_ip                         71	EXIST::FUNCTION:
        +BIO_get_port                            72	EXIST::FUNCTION:
        +BIO_get_retry_BIO                       73	EXIST::FUNCTION:
        +BIO_get_retry_reason                    74	EXIST::FUNCTION:
        +BIO_gethostbyname                       75	EXIST::FUNCTION:
        +BIO_gets                                76	EXIST::FUNCTION:
        +BIO_new                                 78	EXIST::FUNCTION:
        +BIO_new_accept                          79	EXIST::FUNCTION:
        +BIO_new_connect                         80	EXIST::FUNCTION:
        +BIO_new_fd                              81	EXIST::FUNCTION:
        +BIO_new_file                            82	EXIST::FUNCTION:FP_API
        +BIO_new_fp                              83	EXIST::FUNCTION:FP_API
        +BIO_new_socket                          84	EXIST::FUNCTION:
        +BIO_pop                                 85	EXIST::FUNCTION:
        +BIO_printf                              86	EXIST::FUNCTION:
        +BIO_push                                87	EXIST::FUNCTION:
        +BIO_puts                                88	EXIST::FUNCTION:
        +BIO_read                                89	EXIST::FUNCTION:
        +BIO_s_accept                            90	EXIST::FUNCTION:
        +BIO_s_connect                           91	EXIST::FUNCTION:
        +BIO_s_fd                                92	EXIST::FUNCTION:
        +BIO_s_file                              93	EXIST::FUNCTION:FP_API
        +BIO_s_mem                               95	EXIST::FUNCTION:
        +BIO_s_null                              96	EXIST::FUNCTION:
        +BIO_s_proxy_client                      97	NOEXIST::FUNCTION:
        +BIO_s_socket                            98	EXIST::FUNCTION:
        +BIO_set                                 100	EXIST::FUNCTION:
        +BIO_set_cipher                          101	EXIST::FUNCTION:BIO
        +BIO_set_tcp_ndelay                      102	EXIST::FUNCTION:
        +BIO_sock_cleanup                        103	EXIST::FUNCTION:
        +BIO_sock_error                          104	EXIST::FUNCTION:
        +BIO_sock_init                           105	EXIST::FUNCTION:
        +BIO_sock_non_fatal_error                106	EXIST::FUNCTION:
        +BIO_sock_should_retry                   107	EXIST::FUNCTION:
        +BIO_socket_ioctl                        108	EXIST::FUNCTION:
        +BIO_write                               109	EXIST::FUNCTION:
        +BN_CTX_free                             110	EXIST::FUNCTION:
        +BN_CTX_new                              111	EXIST::FUNCTION:
        +BN_MONT_CTX_free                        112	EXIST::FUNCTION:
        +BN_MONT_CTX_new                         113	EXIST::FUNCTION:
        +BN_MONT_CTX_set                         114	EXIST::FUNCTION:
        +BN_add                                  115	EXIST::FUNCTION:
        +BN_add_word                             116	EXIST::FUNCTION:
        +BN_hex2bn                               117	EXIST::FUNCTION:
        +BN_bin2bn                               118	EXIST::FUNCTION:
        +BN_bn2hex                               119	EXIST::FUNCTION:
        +BN_bn2bin                               120	EXIST::FUNCTION:
        +BN_clear                                121	EXIST::FUNCTION:
        +BN_clear_bit                            122	EXIST::FUNCTION:
        +BN_clear_free                           123	EXIST::FUNCTION:
        +BN_cmp                                  124	EXIST::FUNCTION:
        +BN_copy                                 125	EXIST::FUNCTION:
        +BN_div                                  126	EXIST::FUNCTION:
        +BN_div_word                             127	EXIST::FUNCTION:
        +BN_dup                                  128	EXIST::FUNCTION:
        +BN_free                                 129	EXIST::FUNCTION:
        +BN_from_montgomery                      130	EXIST::FUNCTION:
        +BN_gcd                                  131	EXIST::FUNCTION:
        +BN_generate_prime                       132	EXIST::FUNCTION:DEPRECATED
        +BN_get_word                             133	EXIST::FUNCTION:
        +BN_is_bit_set                           134	EXIST::FUNCTION:
        +BN_is_prime                             135	EXIST::FUNCTION:DEPRECATED
        +BN_lshift                               136	EXIST::FUNCTION:
        +BN_lshift1                              137	EXIST::FUNCTION:
        +BN_mask_bits                            138	EXIST::FUNCTION:
        +BN_mod                                  139	NOEXIST::FUNCTION:
        +BN_mod_exp                              140	EXIST::FUNCTION:
        +BN_mod_exp_mont                         141	EXIST::FUNCTION:
        +BN_mod_exp_simple                       143	EXIST::FUNCTION:
        +BN_mod_inverse                          144	EXIST::FUNCTION:
        +BN_mod_mul                              145	EXIST::FUNCTION:
        +BN_mod_mul_montgomery                   146	EXIST::FUNCTION:
        +BN_mod_word                             148	EXIST::FUNCTION:
        +BN_mul                                  149	EXIST::FUNCTION:
        +BN_new                                  150	EXIST::FUNCTION:
        +BN_num_bits                             151	EXIST::FUNCTION:
        +BN_num_bits_word                        152	EXIST::FUNCTION:
        +BN_options                              153	EXIST::FUNCTION:
        +BN_print                                154	EXIST::FUNCTION:
        +BN_print_fp                             155	EXIST::FUNCTION:FP_API
        +BN_rand                                 156	EXIST::FUNCTION:
        +BN_reciprocal                           157	EXIST::FUNCTION:
        +BN_rshift                               158	EXIST::FUNCTION:
        +BN_rshift1                              159	EXIST::FUNCTION:
        +BN_set_bit                              160	EXIST::FUNCTION:
        +BN_set_word                             161	EXIST::FUNCTION:
        +BN_sqr                                  162	EXIST::FUNCTION:
        +BN_sub                                  163	EXIST::FUNCTION:
        +BN_to_ASN1_INTEGER                      164	EXIST::FUNCTION:
        +BN_ucmp                                 165	EXIST::FUNCTION:
        +BN_value_one                            166	EXIST::FUNCTION:
        +BUF_MEM_free                            167	EXIST::FUNCTION:
        +BUF_MEM_grow                            168	EXIST::FUNCTION:
        +BUF_MEM_new                             169	EXIST::FUNCTION:
        +BUF_strdup                              170	EXIST::FUNCTION:
        +CONF_free                               171	EXIST::FUNCTION:
        +CONF_get_number                         172	EXIST::FUNCTION:
        +CONF_get_section                        173	EXIST::FUNCTION:
        +CONF_get_string                         174	EXIST::FUNCTION:
        +CONF_load                               175	EXIST::FUNCTION:
        +CRYPTO_add_lock                         176	EXIST::FUNCTION:
        +CRYPTO_dbg_free                         177	EXIST::FUNCTION:
        +CRYPTO_dbg_malloc                       178	EXIST::FUNCTION:
        +CRYPTO_dbg_realloc                      179	EXIST::FUNCTION:
        +CRYPTO_dbg_remalloc                     180	NOEXIST::FUNCTION:
        +CRYPTO_free                             181	EXIST::FUNCTION:
        +CRYPTO_get_add_lock_callback            182	EXIST::FUNCTION:
        +CRYPTO_get_id_callback                  183	EXIST::FUNCTION:DEPRECATED
        +CRYPTO_get_lock_name                    184	EXIST::FUNCTION:
        +CRYPTO_get_locking_callback             185	EXIST::FUNCTION:
        +CRYPTO_get_mem_functions                186	EXIST::FUNCTION:
        +CRYPTO_lock                             187	EXIST::FUNCTION:
        +CRYPTO_malloc                           188	EXIST::FUNCTION:
        +CRYPTO_mem_ctrl                         189	EXIST::FUNCTION:
        +CRYPTO_mem_leaks                        190	EXIST::FUNCTION:
        +CRYPTO_mem_leaks_cb                     191	EXIST::FUNCTION:
        +CRYPTO_mem_leaks_fp                     192	EXIST::FUNCTION:FP_API
        +CRYPTO_realloc                          193	EXIST::FUNCTION:
        +CRYPTO_remalloc                         194	EXIST::FUNCTION:
        +CRYPTO_set_add_lock_callback            195	EXIST::FUNCTION:
        +CRYPTO_set_id_callback                  196	EXIST::FUNCTION:DEPRECATED
        +CRYPTO_set_locking_callback             197	EXIST::FUNCTION:
        +CRYPTO_set_mem_functions                198	EXIST::FUNCTION:
        +CRYPTO_thread_id                        199	EXIST::FUNCTION:DEPRECATED
        +DH_check                                200	EXIST::FUNCTION:DH
        +DH_compute_key                          201	EXIST::FUNCTION:DH
        +DH_free                                 202	EXIST::FUNCTION:DH
        +DH_generate_key                         203	EXIST::FUNCTION:DH
        +DH_generate_parameters                  204	EXIST::FUNCTION:DEPRECATED,DH
        +DH_new                                  205	EXIST::FUNCTION:DH
        +DH_size                                 206	EXIST::FUNCTION:DH
        +DHparams_print                          207	EXIST::FUNCTION:BIO,DH
        +DHparams_print_fp                       208	EXIST::FUNCTION:DH,FP_API
        +DSA_free                                209	EXIST::FUNCTION:DSA
        +DSA_generate_key                        210	EXIST::FUNCTION:DSA
        +DSA_generate_parameters                 211	EXIST::FUNCTION:DEPRECATED,DSA
        +DSA_is_prime                            212	NOEXIST::FUNCTION:
        +DSA_new                                 213	EXIST::FUNCTION:DSA
        +DSA_print                               214	EXIST::FUNCTION:BIO,DSA
        +DSA_print_fp                            215	EXIST::FUNCTION:DSA,FP_API
        +DSA_sign                                216	EXIST::FUNCTION:DSA
        +DSA_sign_setup                          217	EXIST::FUNCTION:DSA
        +DSA_size                                218	EXIST::FUNCTION:DSA
        +DSA_verify                              219	EXIST::FUNCTION:DSA
        +DSAparams_print                         220	EXIST::FUNCTION:BIO,DSA
        +DSAparams_print_fp                      221	EXIST::FUNCTION:DSA,FP_API
        +ERR_clear_error                         222	EXIST::FUNCTION:
        +ERR_error_string                        223	EXIST::FUNCTION:
        +ERR_free_strings                        224	EXIST::FUNCTION:
        +ERR_func_error_string                   225	EXIST::FUNCTION:
        +ERR_get_err_state_table                 226	EXIST::FUNCTION:LHASH
        +ERR_get_error                           227	EXIST::FUNCTION:
        +ERR_get_error_line                      228	EXIST::FUNCTION:
        +ERR_get_state                           229	EXIST::FUNCTION:
        +ERR_get_string_table                    230	EXIST::FUNCTION:LHASH
        +ERR_lib_error_string                    231	EXIST::FUNCTION:
        +ERR_load_ASN1_strings                   232	EXIST::FUNCTION:
        +ERR_load_BIO_strings                    233	EXIST::FUNCTION:
        +ERR_load_BN_strings                     234	EXIST::FUNCTION:
        +ERR_load_BUF_strings                    235	EXIST::FUNCTION:
        +ERR_load_CONF_strings                   236	EXIST::FUNCTION:
        +ERR_load_DH_strings                     237	EXIST::FUNCTION:DH
        +ERR_load_DSA_strings                    238	EXIST::FUNCTION:DSA
        +ERR_load_ERR_strings                    239	EXIST::FUNCTION:
        +ERR_load_EVP_strings                    240	EXIST::FUNCTION:
        +ERR_load_OBJ_strings                    241	EXIST::FUNCTION:
        +ERR_load_PEM_strings                    242	EXIST::FUNCTION:
        +ERR_load_PROXY_strings                  243	NOEXIST::FUNCTION:
        +ERR_load_RSA_strings                    244	EXIST::FUNCTION:RSA
        +ERR_load_X509_strings                   245	EXIST::FUNCTION:
        +ERR_load_crypto_strings                 246	EXIST::FUNCTION:
        +ERR_load_strings                        247	EXIST::FUNCTION:
        +ERR_peek_error                          248	EXIST::FUNCTION:
        +ERR_peek_error_line                     249	EXIST::FUNCTION:
        +ERR_print_errors                        250	EXIST::FUNCTION:BIO
        +ERR_print_errors_fp                     251	EXIST::FUNCTION:FP_API
        +ERR_put_error                           252	EXIST::FUNCTION:
        +ERR_reason_error_string                 253	EXIST::FUNCTION:
        +ERR_remove_state                        254	EXIST::FUNCTION:DEPRECATED
        +EVP_BytesToKey                          255	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_cleanup                  256	EXIST::FUNCTION:
        +EVP_CipherFinal                         257	EXIST::FUNCTION:
        +EVP_CipherInit                          258	EXIST::FUNCTION:
        +EVP_CipherUpdate                        259	EXIST::FUNCTION:
        +EVP_DecodeBlock                         260	EXIST::FUNCTION:
        +EVP_DecodeFinal                         261	EXIST::FUNCTION:
        +EVP_DecodeInit                          262	EXIST::FUNCTION:
        +EVP_DecodeUpdate                        263	EXIST::FUNCTION:
        +EVP_DecryptFinal                        264	EXIST::FUNCTION:
        +EVP_DecryptInit                         265	EXIST::FUNCTION:
        +EVP_DecryptUpdate                       266	EXIST::FUNCTION:
        +EVP_DigestFinal                         267	EXIST::FUNCTION:
        +EVP_DigestInit                          268	EXIST::FUNCTION:
        +EVP_DigestUpdate                        269	EXIST::FUNCTION:
        +EVP_EncodeBlock                         270	EXIST::FUNCTION:
        +EVP_EncodeFinal                         271	EXIST::FUNCTION:
        +EVP_EncodeInit                          272	EXIST::FUNCTION:
        +EVP_EncodeUpdate                        273	EXIST::FUNCTION:
        +EVP_EncryptFinal                        274	EXIST::FUNCTION:
        +EVP_EncryptInit                         275	EXIST::FUNCTION:
        +EVP_EncryptUpdate                       276	EXIST::FUNCTION:
        +EVP_OpenFinal                           277	EXIST::FUNCTION:RSA
        +EVP_OpenInit                            278	EXIST::FUNCTION:RSA
        +EVP_PKEY_assign                         279	EXIST::FUNCTION:
        +EVP_PKEY_copy_parameters                280	EXIST::FUNCTION:
        +EVP_PKEY_free                           281	EXIST::FUNCTION:
        +EVP_PKEY_missing_parameters             282	EXIST::FUNCTION:
        +EVP_PKEY_new                            283	EXIST::FUNCTION:
        +EVP_PKEY_save_parameters                284	EXIST::FUNCTION:
        +EVP_PKEY_size                           285	EXIST::FUNCTION:
        +EVP_PKEY_type                           286	EXIST::FUNCTION:
        +EVP_SealFinal                           287	EXIST::FUNCTION:RSA
        +EVP_SealInit                            288	EXIST::FUNCTION:RSA
        +EVP_SignFinal                           289	EXIST::FUNCTION:
        +EVP_VerifyFinal                         290	EXIST::FUNCTION:
        +EVP_add_alias                           291	NOEXIST::FUNCTION:
        +EVP_add_cipher                          292	EXIST::FUNCTION:
        +EVP_add_digest                          293	EXIST::FUNCTION:
        +EVP_bf_cbc                              294	EXIST::FUNCTION:BF
        +EVP_bf_cfb64                            295	EXIST::FUNCTION:BF
        +EVP_bf_ecb                              296	EXIST::FUNCTION:BF
        +EVP_bf_ofb                              297	EXIST::FUNCTION:BF
        +EVP_cleanup                             298	EXIST::FUNCTION:
        +EVP_des_cbc                             299	EXIST::FUNCTION:DES
        +EVP_des_cfb64                           300	EXIST::FUNCTION:DES
        +EVP_des_ecb                             301	EXIST::FUNCTION:DES
        +EVP_des_ede                             302	EXIST::FUNCTION:DES
        +EVP_des_ede3                            303	EXIST::FUNCTION:DES
        +EVP_des_ede3_cbc                        304	EXIST::FUNCTION:DES
        +EVP_des_ede3_cfb64                      305	EXIST::FUNCTION:DES
        +EVP_des_ede3_ofb                        306	EXIST::FUNCTION:DES
        +EVP_des_ede_cbc                         307	EXIST::FUNCTION:DES
        +EVP_des_ede_cfb64                       308	EXIST::FUNCTION:DES
        +EVP_des_ede_ofb                         309	EXIST::FUNCTION:DES
        +EVP_des_ofb                             310	EXIST::FUNCTION:DES
        +EVP_desx_cbc                            311	EXIST::FUNCTION:DES
        +EVP_dss                                 312	EXIST::FUNCTION:DSA,SHA
        +EVP_dss1                                313	EXIST::FUNCTION:DSA,SHA
        +EVP_enc_null                            314	EXIST::FUNCTION:
        +EVP_get_cipherbyname                    315	EXIST::FUNCTION:
        +EVP_get_digestbyname                    316	EXIST::FUNCTION:
        +EVP_get_pw_prompt                       317	EXIST::FUNCTION:
        +EVP_idea_cbc                            318	EXIST::FUNCTION:IDEA
        +EVP_idea_cfb64                          319	EXIST::FUNCTION:IDEA
        +EVP_idea_ecb                            320	EXIST::FUNCTION:IDEA
        +EVP_idea_ofb                            321	EXIST::FUNCTION:IDEA
        +EVP_md2                                 322	EXIST::FUNCTION:MD2
        +EVP_md5                                 323	EXIST::FUNCTION:MD5
        +EVP_md_null                             324	EXIST::FUNCTION:
        +EVP_rc2_cbc                             325	EXIST::FUNCTION:RC2
        +EVP_rc2_cfb64                           326	EXIST::FUNCTION:RC2
        +EVP_rc2_ecb                             327	EXIST::FUNCTION:RC2
        +EVP_rc2_ofb                             328	EXIST::FUNCTION:RC2
        +EVP_rc4                                 329	EXIST::FUNCTION:RC4
        +EVP_read_pw_string                      330	EXIST::FUNCTION:
        +EVP_set_pw_prompt                       331	EXIST::FUNCTION:
        +EVP_sha                                 332	EXIST::FUNCTION:SHA
        +EVP_sha1                                333	EXIST::FUNCTION:SHA
        +MD2                                     334	EXIST::FUNCTION:MD2
        +MD2_Final                               335	EXIST::FUNCTION:MD2
        +MD2_Init                                336	EXIST::FUNCTION:MD2
        +MD2_Update                              337	EXIST::FUNCTION:MD2
        +MD2_options                             338	EXIST::FUNCTION:MD2
        +MD5                                     339	EXIST::FUNCTION:MD5
        +MD5_Final                               340	EXIST::FUNCTION:MD5
        +MD5_Init                                341	EXIST::FUNCTION:MD5
        +MD5_Update                              342	EXIST::FUNCTION:MD5
        +MDC2                                    343	EXIST::FUNCTION:MDC2
        +MDC2_Final                              344	EXIST::FUNCTION:MDC2
        +MDC2_Init                               345	EXIST::FUNCTION:MDC2
        +MDC2_Update                             346	EXIST::FUNCTION:MDC2
        +NETSCAPE_SPKAC_free                     347	EXIST::FUNCTION:
        +NETSCAPE_SPKAC_new                      348	EXIST::FUNCTION:
        +NETSCAPE_SPKI_free                      349	EXIST::FUNCTION:
        +NETSCAPE_SPKI_new                       350	EXIST::FUNCTION:
        +NETSCAPE_SPKI_sign                      351	EXIST::FUNCTION:EVP
        +NETSCAPE_SPKI_verify                    352	EXIST::FUNCTION:EVP
        +OBJ_add_object                          353	EXIST::FUNCTION:
        +OBJ_bsearch                             354	NOEXIST::FUNCTION:
        +OBJ_cleanup                             355	EXIST::FUNCTION:
        +OBJ_cmp                                 356	EXIST::FUNCTION:
        +OBJ_create                              357	EXIST::FUNCTION:
        +OBJ_dup                                 358	EXIST::FUNCTION:
        +OBJ_ln2nid                              359	EXIST::FUNCTION:
        +OBJ_new_nid                             360	EXIST::FUNCTION:
        +OBJ_nid2ln                              361	EXIST::FUNCTION:
        +OBJ_nid2obj                             362	EXIST::FUNCTION:
        +OBJ_nid2sn                              363	EXIST::FUNCTION:
        +OBJ_obj2nid                             364	EXIST::FUNCTION:
        +OBJ_sn2nid                              365	EXIST::FUNCTION:
        +OBJ_txt2nid                             366	EXIST::FUNCTION:
        +PEM_ASN1_read                           367	EXIST::FUNCTION:
        +PEM_ASN1_read_bio                       368	EXIST::FUNCTION:BIO
        +PEM_ASN1_write                          369	EXIST::FUNCTION:
        +PEM_ASN1_write_bio                      370	EXIST::FUNCTION:BIO
        +PEM_SealFinal                           371	EXIST::FUNCTION:RSA
        +PEM_SealInit                            372	EXIST::FUNCTION:RSA
        +PEM_SealUpdate                          373	EXIST::FUNCTION:RSA
        +PEM_SignFinal                           374	EXIST::FUNCTION:
        +PEM_SignInit                            375	EXIST::FUNCTION:
        +PEM_SignUpdate                          376	EXIST::FUNCTION:
        +PEM_X509_INFO_read                      377	EXIST::FUNCTION:
        +PEM_X509_INFO_read_bio                  378	EXIST::FUNCTION:BIO
        +PEM_X509_INFO_write_bio                 379	EXIST::FUNCTION:BIO
        +PEM_dek_info                            380	EXIST::FUNCTION:
        +PEM_do_header                           381	EXIST::FUNCTION:
        +PEM_get_EVP_CIPHER_INFO                 382	EXIST::FUNCTION:
        +PEM_proc_type                           383	EXIST::FUNCTION:
        +PEM_read                                384	EXIST::FUNCTION:
        +PEM_read_DHparams                       385	EXIST:!WIN16:FUNCTION:DH
        +PEM_read_DSAPrivateKey                  386	EXIST:!WIN16:FUNCTION:DSA
        +PEM_read_DSAparams                      387	EXIST:!WIN16:FUNCTION:DSA
        +PEM_read_PKCS7                          388	EXIST:!WIN16:FUNCTION:
        +PEM_read_PrivateKey                     389	EXIST:!WIN16:FUNCTION:
        +PEM_read_RSAPrivateKey                  390	EXIST:!WIN16:FUNCTION:RSA
        +PEM_read_X509                           391	EXIST:!WIN16:FUNCTION:
        +PEM_read_X509_CRL                       392	EXIST:!WIN16:FUNCTION:
        +PEM_read_X509_REQ                       393	EXIST:!WIN16:FUNCTION:
        +PEM_read_bio                            394	EXIST::FUNCTION:BIO
        +PEM_read_bio_DHparams                   395	EXIST::FUNCTION:DH
        +PEM_read_bio_DSAPrivateKey              396	EXIST::FUNCTION:DSA
        +PEM_read_bio_DSAparams                  397	EXIST::FUNCTION:DSA
        +PEM_read_bio_PKCS7                      398	EXIST::FUNCTION:
        +PEM_read_bio_PrivateKey                 399	EXIST::FUNCTION:
        +PEM_read_bio_RSAPrivateKey              400	EXIST::FUNCTION:RSA
        +PEM_read_bio_X509                       401	EXIST::FUNCTION:
        +PEM_read_bio_X509_CRL                   402	EXIST::FUNCTION:
        +PEM_read_bio_X509_REQ                   403	EXIST::FUNCTION:
        +PEM_write                               404	EXIST::FUNCTION:
        +PEM_write_DHparams                      405	EXIST:!WIN16:FUNCTION:DH
        +PEM_write_DSAPrivateKey                 406	EXIST:!WIN16:FUNCTION:DSA
        +PEM_write_DSAparams                     407	EXIST:!WIN16:FUNCTION:DSA
        +PEM_write_PKCS7                         408	EXIST:!WIN16:FUNCTION:
        +PEM_write_PrivateKey                    409	EXIST:!WIN16:FUNCTION:
        +PEM_write_RSAPrivateKey                 410	EXIST:!WIN16:FUNCTION:RSA
        +PEM_write_X509                          411	EXIST:!WIN16:FUNCTION:
        +PEM_write_X509_CRL                      412	EXIST:!WIN16:FUNCTION:
        +PEM_write_X509_REQ                      413	EXIST:!WIN16:FUNCTION:
        +PEM_write_bio                           414	EXIST::FUNCTION:BIO
        +PEM_write_bio_DHparams                  415	EXIST::FUNCTION:DH
        +PEM_write_bio_DSAPrivateKey             416	EXIST::FUNCTION:DSA
        +PEM_write_bio_DSAparams                 417	EXIST::FUNCTION:DSA
        +PEM_write_bio_PKCS7                     418	EXIST::FUNCTION:
        +PEM_write_bio_PrivateKey                419	EXIST::FUNCTION:
        +PEM_write_bio_RSAPrivateKey             420	EXIST::FUNCTION:RSA
        +PEM_write_bio_X509                      421	EXIST::FUNCTION:
        +PEM_write_bio_X509_CRL                  422	EXIST::FUNCTION:
        +PEM_write_bio_X509_REQ                  423	EXIST::FUNCTION:
        +PKCS7_DIGEST_free                       424	EXIST::FUNCTION:
        +PKCS7_DIGEST_new                        425	EXIST::FUNCTION:
        +PKCS7_ENCRYPT_free                      426	EXIST::FUNCTION:
        +PKCS7_ENCRYPT_new                       427	EXIST::FUNCTION:
        +PKCS7_ENC_CONTENT_free                  428	EXIST::FUNCTION:
        +PKCS7_ENC_CONTENT_new                   429	EXIST::FUNCTION:
        +PKCS7_ENVELOPE_free                     430	EXIST::FUNCTION:
        +PKCS7_ENVELOPE_new                      431	EXIST::FUNCTION:
        +PKCS7_ISSUER_AND_SERIAL_digest          432	EXIST::FUNCTION:
        +PKCS7_ISSUER_AND_SERIAL_free            433	EXIST::FUNCTION:
        +PKCS7_ISSUER_AND_SERIAL_new             434	EXIST::FUNCTION:
        +PKCS7_RECIP_INFO_free                   435	EXIST::FUNCTION:
        +PKCS7_RECIP_INFO_new                    436	EXIST::FUNCTION:
        +PKCS7_SIGNED_free                       437	EXIST::FUNCTION:
        +PKCS7_SIGNED_new                        438	EXIST::FUNCTION:
        +PKCS7_SIGNER_INFO_free                  439	EXIST::FUNCTION:
        +PKCS7_SIGNER_INFO_new                   440	EXIST::FUNCTION:
        +PKCS7_SIGN_ENVELOPE_free                441	EXIST::FUNCTION:
        +PKCS7_SIGN_ENVELOPE_new                 442	EXIST::FUNCTION:
        +PKCS7_dup                               443	EXIST::FUNCTION:
        +PKCS7_free                              444	EXIST::FUNCTION:
        +PKCS7_new                               445	EXIST::FUNCTION:
        +PROXY_ENTRY_add_noproxy                 446	NOEXIST::FUNCTION:
        +PROXY_ENTRY_clear_noproxy               447	NOEXIST::FUNCTION:
        +PROXY_ENTRY_free                        448	NOEXIST::FUNCTION:
        +PROXY_ENTRY_get_noproxy                 449	NOEXIST::FUNCTION:
        +PROXY_ENTRY_new                         450	NOEXIST::FUNCTION:
        +PROXY_ENTRY_set_server                  451	NOEXIST::FUNCTION:
        +PROXY_add_noproxy                       452	NOEXIST::FUNCTION:
        +PROXY_add_server                        453	NOEXIST::FUNCTION:
        +PROXY_check_by_host                     454	NOEXIST::FUNCTION:
        +PROXY_check_url                         455	NOEXIST::FUNCTION:
        +PROXY_clear_noproxy                     456	NOEXIST::FUNCTION:
        +PROXY_free                              457	NOEXIST::FUNCTION:
        +PROXY_get_noproxy                       458	NOEXIST::FUNCTION:
        +PROXY_get_proxies                       459	NOEXIST::FUNCTION:
        +PROXY_get_proxy_entry                   460	NOEXIST::FUNCTION:
        +PROXY_load_conf                         461	NOEXIST::FUNCTION:
        +PROXY_new                               462	NOEXIST::FUNCTION:
        +PROXY_print                             463	NOEXIST::FUNCTION:
        +RAND_bytes                              464	EXIST::FUNCTION:
        +RAND_cleanup                            465	EXIST::FUNCTION:
        +RAND_file_name                          466	EXIST::FUNCTION:
        +RAND_load_file                          467	EXIST::FUNCTION:
        +RAND_screen                             468	EXIST:WIN32:FUNCTION:
        +RAND_seed                               469	EXIST::FUNCTION:
        +RAND_write_file                         470	EXIST::FUNCTION:
        +RC2_cbc_encrypt                         471	EXIST::FUNCTION:RC2
        +RC2_cfb64_encrypt                       472	EXIST::FUNCTION:RC2
        +RC2_ecb_encrypt                         473	EXIST::FUNCTION:RC2
        +RC2_encrypt                             474	EXIST::FUNCTION:RC2
        +RC2_ofb64_encrypt                       475	EXIST::FUNCTION:RC2
        +RC2_set_key                             476	EXIST::FUNCTION:RC2
        +RC4                                     477	EXIST::FUNCTION:RC4
        +RC4_options                             478	EXIST::FUNCTION:RC4
        +RC4_set_key                             479	EXIST::FUNCTION:RC4
        +RSAPrivateKey_asn1_meth                 480	NOEXIST::FUNCTION:
        +RSAPrivateKey_dup                       481	EXIST::FUNCTION:RSA
        +RSAPublicKey_dup                        482	EXIST::FUNCTION:RSA
        +RSA_PKCS1_SSLeay                        483	EXIST::FUNCTION:RSA
        +RSA_free                                484	EXIST::FUNCTION:RSA
        +RSA_generate_key                        485	EXIST::FUNCTION:DEPRECATED,RSA
        +RSA_new                                 486	EXIST::FUNCTION:RSA
        +RSA_new_method                          487	EXIST::FUNCTION:RSA
        +RSA_print                               488	EXIST::FUNCTION:BIO,RSA
        +RSA_print_fp                            489	EXIST::FUNCTION:FP_API,RSA
        +RSA_private_decrypt                     490	EXIST::FUNCTION:RSA
        +RSA_private_encrypt                     491	EXIST::FUNCTION:RSA
        +RSA_public_decrypt                      492	EXIST::FUNCTION:RSA
        +RSA_public_encrypt                      493	EXIST::FUNCTION:RSA
        +RSA_set_default_method                  494	EXIST::FUNCTION:RSA
        +RSA_sign                                495	EXIST::FUNCTION:RSA
        +RSA_sign_ASN1_OCTET_STRING              496	EXIST::FUNCTION:RSA
        +RSA_size                                497	EXIST::FUNCTION:RSA
        +RSA_verify                              498	EXIST::FUNCTION:RSA
        +RSA_verify_ASN1_OCTET_STRING            499	EXIST::FUNCTION:RSA
        +SHA                                     500	EXIST::FUNCTION:SHA,SHA0
        +SHA1                                    501	EXIST::FUNCTION:SHA,SHA1
        +SHA1_Final                              502	EXIST::FUNCTION:SHA,SHA1
        +SHA1_Init                               503	EXIST::FUNCTION:SHA,SHA1
        +SHA1_Update                             504	EXIST::FUNCTION:SHA,SHA1
        +SHA_Final                               505	EXIST::FUNCTION:SHA,SHA0
        +SHA_Init                                506	EXIST::FUNCTION:SHA,SHA0
        +SHA_Update                              507	EXIST::FUNCTION:SHA,SHA0
        +OpenSSL_add_all_algorithms              508	NOEXIST::FUNCTION:
        +OpenSSL_add_all_ciphers                 509	EXIST::FUNCTION:
        +OpenSSL_add_all_digests                 510	EXIST::FUNCTION:
        +TXT_DB_create_index                     511	EXIST::FUNCTION:
        +TXT_DB_free                             512	EXIST::FUNCTION:
        +TXT_DB_get_by_index                     513	EXIST::FUNCTION:
        +TXT_DB_insert                           514	EXIST::FUNCTION:
        +TXT_DB_read                             515	EXIST::FUNCTION:BIO
        +TXT_DB_write                            516	EXIST::FUNCTION:BIO
        +X509_ALGOR_free                         517	EXIST::FUNCTION:
        +X509_ALGOR_new                          518	EXIST::FUNCTION:
        +X509_ATTRIBUTE_free                     519	EXIST::FUNCTION:
        +X509_ATTRIBUTE_new                      520	EXIST::FUNCTION:
        +X509_CINF_free                          521	EXIST::FUNCTION:
        +X509_CINF_new                           522	EXIST::FUNCTION:
        +X509_CRL_INFO_free                      523	EXIST::FUNCTION:
        +X509_CRL_INFO_new                       524	EXIST::FUNCTION:
        +X509_CRL_add_ext                        525	EXIST::FUNCTION:
        +X509_CRL_cmp                            526	EXIST::FUNCTION:
        +X509_CRL_delete_ext                     527	EXIST::FUNCTION:
        +X509_CRL_dup                            528	EXIST::FUNCTION:
        +X509_CRL_free                           529	EXIST::FUNCTION:
        +X509_CRL_get_ext                        530	EXIST::FUNCTION:
        +X509_CRL_get_ext_by_NID                 531	EXIST::FUNCTION:
        +X509_CRL_get_ext_by_OBJ                 532	EXIST::FUNCTION:
        +X509_CRL_get_ext_by_critical            533	EXIST::FUNCTION:
        +X509_CRL_get_ext_count                  534	EXIST::FUNCTION:
        +X509_CRL_new                            535	EXIST::FUNCTION:
        +X509_CRL_sign                           536	EXIST::FUNCTION:EVP
        +X509_CRL_verify                         537	EXIST::FUNCTION:EVP
        +X509_EXTENSION_create_by_NID            538	EXIST::FUNCTION:
        +X509_EXTENSION_create_by_OBJ            539	EXIST::FUNCTION:
        +X509_EXTENSION_dup                      540	EXIST::FUNCTION:
        +X509_EXTENSION_free                     541	EXIST::FUNCTION:
        +X509_EXTENSION_get_critical             542	EXIST::FUNCTION:
        +X509_EXTENSION_get_data                 543	EXIST::FUNCTION:
        +X509_EXTENSION_get_object               544	EXIST::FUNCTION:
        +X509_EXTENSION_new                      545	EXIST::FUNCTION:
        +X509_EXTENSION_set_critical             546	EXIST::FUNCTION:
        +X509_EXTENSION_set_data                 547	EXIST::FUNCTION:
        +X509_EXTENSION_set_object               548	EXIST::FUNCTION:
        +X509_INFO_free                          549	EXIST::FUNCTION:EVP
        +X509_INFO_new                           550	EXIST::FUNCTION:EVP
        +X509_LOOKUP_by_alias                    551	EXIST::FUNCTION:
        +X509_LOOKUP_by_fingerprint              552	EXIST::FUNCTION:
        +X509_LOOKUP_by_issuer_serial            553	EXIST::FUNCTION:
        +X509_LOOKUP_by_subject                  554	EXIST::FUNCTION:
        +X509_LOOKUP_ctrl                        555	EXIST::FUNCTION:
        +X509_LOOKUP_file                        556	EXIST::FUNCTION:
        +X509_LOOKUP_free                        557	EXIST::FUNCTION:
        +X509_LOOKUP_hash_dir                    558	EXIST::FUNCTION:
        +X509_LOOKUP_init                        559	EXIST::FUNCTION:
        +X509_LOOKUP_new                         560	EXIST::FUNCTION:
        +X509_LOOKUP_shutdown                    561	EXIST::FUNCTION:
        +X509_NAME_ENTRY_create_by_NID           562	EXIST::FUNCTION:
        +X509_NAME_ENTRY_create_by_OBJ           563	EXIST::FUNCTION:
        +X509_NAME_ENTRY_dup                     564	EXIST::FUNCTION:
        +X509_NAME_ENTRY_free                    565	EXIST::FUNCTION:
        +X509_NAME_ENTRY_get_data                566	EXIST::FUNCTION:
        +X509_NAME_ENTRY_get_object              567	EXIST::FUNCTION:
        +X509_NAME_ENTRY_new                     568	EXIST::FUNCTION:
        +X509_NAME_ENTRY_set_data                569	EXIST::FUNCTION:
        +X509_NAME_ENTRY_set_object              570	EXIST::FUNCTION:
        +X509_NAME_add_entry                     571	EXIST::FUNCTION:
        +X509_NAME_cmp                           572	EXIST::FUNCTION:
        +X509_NAME_delete_entry                  573	EXIST::FUNCTION:
        +X509_NAME_digest                        574	EXIST::FUNCTION:EVP
        +X509_NAME_dup                           575	EXIST::FUNCTION:
        +X509_NAME_entry_count                   576	EXIST::FUNCTION:
        +X509_NAME_free                          577	EXIST::FUNCTION:
        +X509_NAME_get_entry                     578	EXIST::FUNCTION:
        +X509_NAME_get_index_by_NID              579	EXIST::FUNCTION:
        +X509_NAME_get_index_by_OBJ              580	EXIST::FUNCTION:
        +X509_NAME_get_text_by_NID               581	EXIST::FUNCTION:
        +X509_NAME_get_text_by_OBJ               582	EXIST::FUNCTION:
        +X509_NAME_hash                          583	EXIST::FUNCTION:
        +X509_NAME_new                           584	EXIST::FUNCTION:
        +X509_NAME_oneline                       585	EXIST::FUNCTION:EVP
        +X509_NAME_print                         586	EXIST::FUNCTION:BIO
        +X509_NAME_set                           587	EXIST::FUNCTION:
        +X509_OBJECT_free_contents               588	EXIST::FUNCTION:
        +X509_OBJECT_retrieve_by_subject         589	EXIST::FUNCTION:
        +X509_OBJECT_up_ref_count                590	EXIST::FUNCTION:
        +X509_PKEY_free                          591	EXIST::FUNCTION:
        +X509_PKEY_new                           592	EXIST::FUNCTION:
        +X509_PUBKEY_free                        593	EXIST::FUNCTION:
        +X509_PUBKEY_get                         594	EXIST::FUNCTION:
        +X509_PUBKEY_new                         595	EXIST::FUNCTION:
        +X509_PUBKEY_set                         596	EXIST::FUNCTION:
        +X509_REQ_INFO_free                      597	EXIST::FUNCTION:
        +X509_REQ_INFO_new                       598	EXIST::FUNCTION:
        +X509_REQ_dup                            599	EXIST::FUNCTION:
        +X509_REQ_free                           600	EXIST::FUNCTION:
        +X509_REQ_get_pubkey                     601	EXIST::FUNCTION:
        +X509_REQ_new                            602	EXIST::FUNCTION:
        +X509_REQ_print                          603	EXIST::FUNCTION:BIO
        +X509_REQ_print_fp                       604	EXIST::FUNCTION:FP_API
        +X509_REQ_set_pubkey                     605	EXIST::FUNCTION:
        +X509_REQ_set_subject_name               606	EXIST::FUNCTION:
        +X509_REQ_set_version                    607	EXIST::FUNCTION:
        +X509_REQ_sign                           608	EXIST::FUNCTION:EVP
        +X509_REQ_to_X509                        609	EXIST::FUNCTION:
        +X509_REQ_verify                         610	EXIST::FUNCTION:EVP
        +X509_REVOKED_add_ext                    611	EXIST::FUNCTION:
        +X509_REVOKED_delete_ext                 612	EXIST::FUNCTION:
        +X509_REVOKED_free                       613	EXIST::FUNCTION:
        +X509_REVOKED_get_ext                    614	EXIST::FUNCTION:
        +X509_REVOKED_get_ext_by_NID             615	EXIST::FUNCTION:
        +X509_REVOKED_get_ext_by_OBJ             616	EXIST::FUNCTION:
        +X509_REVOKED_get_ext_by_critical        617	EXIST:!VMS:FUNCTION:
        +X509_REVOKED_get_ext_by_critic          617	EXIST:VMS:FUNCTION:
        +X509_REVOKED_get_ext_count              618	EXIST::FUNCTION:
        +X509_REVOKED_new                        619	EXIST::FUNCTION:
        +X509_SIG_free                           620	EXIST::FUNCTION:
        +X509_SIG_new                            621	EXIST::FUNCTION:
        +X509_STORE_CTX_cleanup                  622	EXIST::FUNCTION:
        +X509_STORE_CTX_init                     623	EXIST::FUNCTION:
        +X509_STORE_add_cert                     624	EXIST::FUNCTION:
        +X509_STORE_add_lookup                   625	EXIST::FUNCTION:
        +X509_STORE_free                         626	EXIST::FUNCTION:
        +X509_STORE_get_by_subject               627	EXIST::FUNCTION:
        +X509_STORE_load_locations               628	EXIST::FUNCTION:STDIO
        +X509_STORE_new                          629	EXIST::FUNCTION:
        +X509_STORE_set_default_paths            630	EXIST::FUNCTION:STDIO
        +X509_VAL_free                           631	EXIST::FUNCTION:
        +X509_VAL_new                            632	EXIST::FUNCTION:
        +X509_add_ext                            633	EXIST::FUNCTION:
        +X509_asn1_meth                          634	NOEXIST::FUNCTION:
        +X509_certificate_type                   635	EXIST::FUNCTION:
        +X509_check_private_key                  636	EXIST::FUNCTION:
        +X509_cmp_current_time                   637	EXIST::FUNCTION:
        +X509_delete_ext                         638	EXIST::FUNCTION:
        +X509_digest                             639	EXIST::FUNCTION:EVP
        +X509_dup                                640	EXIST::FUNCTION:
        +X509_free                               641	EXIST::FUNCTION:
        +X509_get_default_cert_area              642	EXIST::FUNCTION:
        +X509_get_default_cert_dir               643	EXIST::FUNCTION:
        +X509_get_default_cert_dir_env           644	EXIST::FUNCTION:
        +X509_get_default_cert_file              645	EXIST::FUNCTION:
        +X509_get_default_cert_file_env          646	EXIST::FUNCTION:
        +X509_get_default_private_dir            647	EXIST::FUNCTION:
        +X509_get_ext                            648	EXIST::FUNCTION:
        +X509_get_ext_by_NID                     649	EXIST::FUNCTION:
        +X509_get_ext_by_OBJ                     650	EXIST::FUNCTION:
        +X509_get_ext_by_critical                651	EXIST::FUNCTION:
        +X509_get_ext_count                      652	EXIST::FUNCTION:
        +X509_get_issuer_name                    653	EXIST::FUNCTION:
        +X509_get_pubkey                         654	EXIST::FUNCTION:
        +X509_get_pubkey_parameters              655	EXIST::FUNCTION:
        +X509_get_serialNumber                   656	EXIST::FUNCTION:
        +X509_get_subject_name                   657	EXIST::FUNCTION:
        +X509_gmtime_adj                         658	EXIST::FUNCTION:
        +X509_issuer_and_serial_cmp              659	EXIST::FUNCTION:
        +X509_issuer_and_serial_hash             660	EXIST::FUNCTION:
        +X509_issuer_name_cmp                    661	EXIST::FUNCTION:
        +X509_issuer_name_hash                   662	EXIST::FUNCTION:
        +X509_load_cert_file                     663	EXIST::FUNCTION:STDIO
        +X509_new                                664	EXIST::FUNCTION:
        +X509_print                              665	EXIST::FUNCTION:BIO
        +X509_print_fp                           666	EXIST::FUNCTION:FP_API
        +X509_set_issuer_name                    667	EXIST::FUNCTION:
        +X509_set_notAfter                       668	EXIST::FUNCTION:
        +X509_set_notBefore                      669	EXIST::FUNCTION:
        +X509_set_pubkey                         670	EXIST::FUNCTION:
        +X509_set_serialNumber                   671	EXIST::FUNCTION:
        +X509_set_subject_name                   672	EXIST::FUNCTION:
        +X509_set_version                        673	EXIST::FUNCTION:
        +X509_sign                               674	EXIST::FUNCTION:EVP
        +X509_subject_name_cmp                   675	EXIST::FUNCTION:
        +X509_subject_name_hash                  676	EXIST::FUNCTION:
        +X509_to_X509_REQ                        677	EXIST::FUNCTION:
        +X509_verify                             678	EXIST::FUNCTION:EVP
        +X509_verify_cert                        679	EXIST::FUNCTION:
        +X509_verify_cert_error_string           680	EXIST::FUNCTION:
        +X509v3_add_ext                          681	EXIST::FUNCTION:
        +X509v3_add_extension                    682	NOEXIST::FUNCTION:
        +X509v3_add_netscape_extensions          683	NOEXIST::FUNCTION:
        +X509v3_add_standard_extensions          684	NOEXIST::FUNCTION:
        +X509v3_cleanup_extensions               685	NOEXIST::FUNCTION:
        +X509v3_data_type_by_NID                 686	NOEXIST::FUNCTION:
        +X509v3_data_type_by_OBJ                 687	NOEXIST::FUNCTION:
        +X509v3_delete_ext                       688	EXIST::FUNCTION:
        +X509v3_get_ext                          689	EXIST::FUNCTION:
        +X509v3_get_ext_by_NID                   690	EXIST::FUNCTION:
        +X509v3_get_ext_by_OBJ                   691	EXIST::FUNCTION:
        +X509v3_get_ext_by_critical              692	EXIST::FUNCTION:
        +X509v3_get_ext_count                    693	EXIST::FUNCTION:
        +X509v3_pack_string                      694	NOEXIST::FUNCTION:
        +X509v3_pack_type_by_NID                 695	NOEXIST::FUNCTION:
        +X509v3_pack_type_by_OBJ                 696	NOEXIST::FUNCTION:
        +X509v3_unpack_string                    697	NOEXIST::FUNCTION:
        +_des_crypt                              698	NOEXIST::FUNCTION:
        +a2d_ASN1_OBJECT                         699	EXIST::FUNCTION:
        +a2i_ASN1_INTEGER                        700	EXIST::FUNCTION:BIO
        +a2i_ASN1_STRING                         701	EXIST::FUNCTION:BIO
        +asn1_Finish                             702	EXIST::FUNCTION:
        +asn1_GetSequence                        703	EXIST::FUNCTION:
        +bn_div_words                            704	EXIST::FUNCTION:
        +bn_expand2                              705	EXIST::FUNCTION:
        +bn_mul_add_words                        706	EXIST::FUNCTION:
        +bn_mul_words                            707	EXIST::FUNCTION:
        +BN_uadd                                 708	EXIST::FUNCTION:
        +BN_usub                                 709	EXIST::FUNCTION:
        +bn_sqr_words                            710	EXIST::FUNCTION:
        +_ossl_old_crypt                         711	EXIST:!NeXT,!PERL5:FUNCTION:DES
        +d2i_ASN1_BIT_STRING                     712	EXIST::FUNCTION:
        +d2i_ASN1_BOOLEAN                        713	EXIST::FUNCTION:
        +d2i_ASN1_HEADER                         714	NOEXIST::FUNCTION:
        +d2i_ASN1_IA5STRING                      715	EXIST::FUNCTION:
        +d2i_ASN1_INTEGER                        716	EXIST::FUNCTION:
        +d2i_ASN1_OBJECT                         717	EXIST::FUNCTION:
        +d2i_ASN1_OCTET_STRING                   718	EXIST::FUNCTION:
        +d2i_ASN1_PRINTABLE                      719	EXIST::FUNCTION:
        +d2i_ASN1_PRINTABLESTRING                720	EXIST::FUNCTION:
        +d2i_ASN1_SET                            721	EXIST::FUNCTION:
        +d2i_ASN1_T61STRING                      722	EXIST::FUNCTION:
        +d2i_ASN1_TYPE                           723	EXIST::FUNCTION:
        +d2i_ASN1_UTCTIME                        724	EXIST::FUNCTION:
        +d2i_ASN1_bytes                          725	EXIST::FUNCTION:
        +d2i_ASN1_type_bytes                     726	EXIST::FUNCTION:
        +d2i_DHparams                            727	EXIST::FUNCTION:DH
        +d2i_DSAPrivateKey                       728	EXIST::FUNCTION:DSA
        +d2i_DSAPrivateKey_bio                   729	EXIST::FUNCTION:BIO,DSA
        +d2i_DSAPrivateKey_fp                    730	EXIST::FUNCTION:DSA,FP_API
        +d2i_DSAPublicKey                        731	EXIST::FUNCTION:DSA
        +d2i_DSAparams                           732	EXIST::FUNCTION:DSA
        +d2i_NETSCAPE_SPKAC                      733	EXIST::FUNCTION:
        +d2i_NETSCAPE_SPKI                       734	EXIST::FUNCTION:
        +d2i_Netscape_RSA                        735	EXIST::FUNCTION:RC4,RSA
        +d2i_PKCS7                               736	EXIST::FUNCTION:
        +d2i_PKCS7_DIGEST                        737	EXIST::FUNCTION:
        +d2i_PKCS7_ENCRYPT                       738	EXIST::FUNCTION:
        +d2i_PKCS7_ENC_CONTENT                   739	EXIST::FUNCTION:
        +d2i_PKCS7_ENVELOPE                      740	EXIST::FUNCTION:
        +d2i_PKCS7_ISSUER_AND_SERIAL             741	EXIST::FUNCTION:
        +d2i_PKCS7_RECIP_INFO                    742	EXIST::FUNCTION:
        +d2i_PKCS7_SIGNED                        743	EXIST::FUNCTION:
        +d2i_PKCS7_SIGNER_INFO                   744	EXIST::FUNCTION:
        +d2i_PKCS7_SIGN_ENVELOPE                 745	EXIST::FUNCTION:
        +d2i_PKCS7_bio                           746	EXIST::FUNCTION:
        +d2i_PKCS7_fp                            747	EXIST::FUNCTION:FP_API
        +d2i_PrivateKey                          748	EXIST::FUNCTION:
        +d2i_PublicKey                           749	EXIST::FUNCTION:
        +d2i_RSAPrivateKey                       750	EXIST::FUNCTION:RSA
        +d2i_RSAPrivateKey_bio                   751	EXIST::FUNCTION:BIO,RSA
        +d2i_RSAPrivateKey_fp                    752	EXIST::FUNCTION:FP_API,RSA
        +d2i_RSAPublicKey                        753	EXIST::FUNCTION:RSA
        +d2i_X509                                754	EXIST::FUNCTION:
        +d2i_X509_ALGOR                          755	EXIST::FUNCTION:
        +d2i_X509_ATTRIBUTE                      756	EXIST::FUNCTION:
        +d2i_X509_CINF                           757	EXIST::FUNCTION:
        +d2i_X509_CRL                            758	EXIST::FUNCTION:
        +d2i_X509_CRL_INFO                       759	EXIST::FUNCTION:
        +d2i_X509_CRL_bio                        760	EXIST::FUNCTION:BIO
        +d2i_X509_CRL_fp                         761	EXIST::FUNCTION:FP_API
        +d2i_X509_EXTENSION                      762	EXIST::FUNCTION:
        +d2i_X509_NAME                           763	EXIST::FUNCTION:
        +d2i_X509_NAME_ENTRY                     764	EXIST::FUNCTION:
        +d2i_X509_PKEY                           765	EXIST::FUNCTION:
        +d2i_X509_PUBKEY                         766	EXIST::FUNCTION:
        +d2i_X509_REQ                            767	EXIST::FUNCTION:
        +d2i_X509_REQ_INFO                       768	EXIST::FUNCTION:
        +d2i_X509_REQ_bio                        769	EXIST::FUNCTION:BIO
        +d2i_X509_REQ_fp                         770	EXIST::FUNCTION:FP_API
        +d2i_X509_REVOKED                        771	EXIST::FUNCTION:
        +d2i_X509_SIG                            772	EXIST::FUNCTION:
        +d2i_X509_VAL                            773	EXIST::FUNCTION:
        +d2i_X509_bio                            774	EXIST::FUNCTION:BIO
        +d2i_X509_fp                             775	EXIST::FUNCTION:FP_API
        +DES_cbc_cksum                           777	EXIST::FUNCTION:DES
        +DES_cbc_encrypt                         778	EXIST::FUNCTION:DES
        +DES_cblock_print_file                   779	NOEXIST::FUNCTION:
        +DES_cfb64_encrypt                       780	EXIST::FUNCTION:DES
        +DES_cfb_encrypt                         781	EXIST::FUNCTION:DES
        +DES_decrypt3                            782	EXIST::FUNCTION:DES
        +DES_ecb3_encrypt                        783	EXIST::FUNCTION:DES
        +DES_ecb_encrypt                         784	EXIST::FUNCTION:DES
        +DES_ede3_cbc_encrypt                    785	EXIST::FUNCTION:DES
        +DES_ede3_cfb64_encrypt                  786	EXIST::FUNCTION:DES
        +DES_ede3_ofb64_encrypt                  787	EXIST::FUNCTION:DES
        +DES_enc_read                            788	EXIST::FUNCTION:DES
        +DES_enc_write                           789	EXIST::FUNCTION:DES
        +DES_encrypt1                            790	EXIST::FUNCTION:DES
        +DES_encrypt2                            791	EXIST::FUNCTION:DES
        +DES_encrypt3                            792	EXIST::FUNCTION:DES
        +DES_fcrypt                              793	EXIST::FUNCTION:DES
        +DES_is_weak_key                         794	EXIST::FUNCTION:DES
        +DES_key_sched                           795	EXIST::FUNCTION:DES
        +DES_ncbc_encrypt                        796	EXIST::FUNCTION:DES
        +DES_ofb64_encrypt                       797	EXIST::FUNCTION:DES
        +DES_ofb_encrypt                         798	EXIST::FUNCTION:DES
        +DES_options                             799	EXIST::FUNCTION:DES
        +DES_pcbc_encrypt                        800	EXIST::FUNCTION:DES
        +DES_quad_cksum                          801	EXIST::FUNCTION:DES
        +DES_random_key                          802	EXIST::FUNCTION:DES
        +_ossl_old_des_random_seed               803	EXIST::FUNCTION:DES
        +_ossl_old_des_read_2passwords           804	EXIST::FUNCTION:DES
        +_ossl_old_des_read_password             805	EXIST::FUNCTION:DES
        +_ossl_old_des_read_pw                   806	EXIST::FUNCTION:
        +_ossl_old_des_read_pw_string            807	EXIST::FUNCTION:
        +DES_set_key                             808	EXIST::FUNCTION:DES
        +DES_set_odd_parity                      809	EXIST::FUNCTION:DES
        +DES_string_to_2keys                     810	EXIST::FUNCTION:DES
        +DES_string_to_key                       811	EXIST::FUNCTION:DES
        +DES_xcbc_encrypt                        812	EXIST::FUNCTION:DES
        +DES_xwhite_in2out                       813	NOEXIST::FUNCTION:
        +fcrypt_body                             814	NOEXIST::FUNCTION:
        +i2a_ASN1_INTEGER                        815	EXIST::FUNCTION:BIO
        +i2a_ASN1_OBJECT                         816	EXIST::FUNCTION:BIO
        +i2a_ASN1_STRING                         817	EXIST::FUNCTION:BIO
        +i2d_ASN1_BIT_STRING                     818	EXIST::FUNCTION:
        +i2d_ASN1_BOOLEAN                        819	EXIST::FUNCTION:
        +i2d_ASN1_HEADER                         820	NOEXIST::FUNCTION:
        +i2d_ASN1_IA5STRING                      821	EXIST::FUNCTION:
        +i2d_ASN1_INTEGER                        822	EXIST::FUNCTION:
        +i2d_ASN1_OBJECT                         823	EXIST::FUNCTION:
        +i2d_ASN1_OCTET_STRING                   824	EXIST::FUNCTION:
        +i2d_ASN1_PRINTABLE                      825	EXIST::FUNCTION:
        +i2d_ASN1_SET                            826	EXIST::FUNCTION:
        +i2d_ASN1_TYPE                           827	EXIST::FUNCTION:
        +i2d_ASN1_UTCTIME                        828	EXIST::FUNCTION:
        +i2d_ASN1_bytes                          829	EXIST::FUNCTION:
        +i2d_DHparams                            830	EXIST::FUNCTION:DH
        +i2d_DSAPrivateKey                       831	EXIST::FUNCTION:DSA
        +i2d_DSAPrivateKey_bio                   832	EXIST::FUNCTION:BIO,DSA
        +i2d_DSAPrivateKey_fp                    833	EXIST::FUNCTION:DSA,FP_API
        +i2d_DSAPublicKey                        834	EXIST::FUNCTION:DSA
        +i2d_DSAparams                           835	EXIST::FUNCTION:DSA
        +i2d_NETSCAPE_SPKAC                      836	EXIST::FUNCTION:
        +i2d_NETSCAPE_SPKI                       837	EXIST::FUNCTION:
        +i2d_Netscape_RSA                        838	EXIST::FUNCTION:RC4,RSA
        +i2d_PKCS7                               839	EXIST::FUNCTION:
        +i2d_PKCS7_DIGEST                        840	EXIST::FUNCTION:
        +i2d_PKCS7_ENCRYPT                       841	EXIST::FUNCTION:
        +i2d_PKCS7_ENC_CONTENT                   842	EXIST::FUNCTION:
        +i2d_PKCS7_ENVELOPE                      843	EXIST::FUNCTION:
        +i2d_PKCS7_ISSUER_AND_SERIAL             844	EXIST::FUNCTION:
        +i2d_PKCS7_RECIP_INFO                    845	EXIST::FUNCTION:
        +i2d_PKCS7_SIGNED                        846	EXIST::FUNCTION:
        +i2d_PKCS7_SIGNER_INFO                   847	EXIST::FUNCTION:
        +i2d_PKCS7_SIGN_ENVELOPE                 848	EXIST::FUNCTION:
        +i2d_PKCS7_bio                           849	EXIST::FUNCTION:
        +i2d_PKCS7_fp                            850	EXIST::FUNCTION:FP_API
        +i2d_PrivateKey                          851	EXIST::FUNCTION:
        +i2d_PublicKey                           852	EXIST::FUNCTION:
        +i2d_RSAPrivateKey                       853	EXIST::FUNCTION:RSA
        +i2d_RSAPrivateKey_bio                   854	EXIST::FUNCTION:BIO,RSA
        +i2d_RSAPrivateKey_fp                    855	EXIST::FUNCTION:FP_API,RSA
        +i2d_RSAPublicKey                        856	EXIST::FUNCTION:RSA
        +i2d_X509                                857	EXIST::FUNCTION:
        +i2d_X509_ALGOR                          858	EXIST::FUNCTION:
        +i2d_X509_ATTRIBUTE                      859	EXIST::FUNCTION:
        +i2d_X509_CINF                           860	EXIST::FUNCTION:
        +i2d_X509_CRL                            861	EXIST::FUNCTION:
        +i2d_X509_CRL_INFO                       862	EXIST::FUNCTION:
        +i2d_X509_CRL_bio                        863	EXIST::FUNCTION:BIO
        +i2d_X509_CRL_fp                         864	EXIST::FUNCTION:FP_API
        +i2d_X509_EXTENSION                      865	EXIST::FUNCTION:
        +i2d_X509_NAME                           866	EXIST::FUNCTION:
        +i2d_X509_NAME_ENTRY                     867	EXIST::FUNCTION:
        +i2d_X509_PKEY                           868	EXIST::FUNCTION:
        +i2d_X509_PUBKEY                         869	EXIST::FUNCTION:
        +i2d_X509_REQ                            870	EXIST::FUNCTION:
        +i2d_X509_REQ_INFO                       871	EXIST::FUNCTION:
        +i2d_X509_REQ_bio                        872	EXIST::FUNCTION:BIO
        +i2d_X509_REQ_fp                         873	EXIST::FUNCTION:FP_API
        +i2d_X509_REVOKED                        874	EXIST::FUNCTION:
        +i2d_X509_SIG                            875	EXIST::FUNCTION:
        +i2d_X509_VAL                            876	EXIST::FUNCTION:
        +i2d_X509_bio                            877	EXIST::FUNCTION:BIO
        +i2d_X509_fp                             878	EXIST::FUNCTION:FP_API
        +idea_cbc_encrypt                        879	EXIST::FUNCTION:IDEA
        +idea_cfb64_encrypt                      880	EXIST::FUNCTION:IDEA
        +idea_ecb_encrypt                        881	EXIST::FUNCTION:IDEA
        +idea_encrypt                            882	EXIST::FUNCTION:IDEA
        +idea_ofb64_encrypt                      883	EXIST::FUNCTION:IDEA
        +idea_options                            884	EXIST::FUNCTION:IDEA
        +idea_set_decrypt_key                    885	EXIST::FUNCTION:IDEA
        +idea_set_encrypt_key                    886	EXIST::FUNCTION:IDEA
        +lh_delete                               887	EXIST::FUNCTION:
        +lh_doall                                888	EXIST::FUNCTION:
        +lh_doall_arg                            889	EXIST::FUNCTION:
        +lh_free                                 890	EXIST::FUNCTION:
        +lh_insert                               891	EXIST::FUNCTION:
        +lh_new                                  892	EXIST::FUNCTION:
        +lh_node_stats                           893	EXIST::FUNCTION:FP_API
        +lh_node_stats_bio                       894	EXIST::FUNCTION:BIO
        +lh_node_usage_stats                     895	EXIST::FUNCTION:FP_API
        +lh_node_usage_stats_bio                 896	EXIST::FUNCTION:BIO
        +lh_retrieve                             897	EXIST::FUNCTION:
        +lh_stats                                898	EXIST::FUNCTION:FP_API
        +lh_stats_bio                            899	EXIST::FUNCTION:BIO
        +lh_strhash                              900	EXIST::FUNCTION:
        +sk_delete                               901	EXIST::FUNCTION:
        +sk_delete_ptr                           902	EXIST::FUNCTION:
        +sk_dup                                  903	EXIST::FUNCTION:
        +sk_find                                 904	EXIST::FUNCTION:
        +sk_free                                 905	EXIST::FUNCTION:
        +sk_insert                               906	EXIST::FUNCTION:
        +sk_new                                  907	EXIST::FUNCTION:
        +sk_pop                                  908	EXIST::FUNCTION:
        +sk_pop_free                             909	EXIST::FUNCTION:
        +sk_push                                 910	EXIST::FUNCTION:
        +sk_set_cmp_func                         911	EXIST::FUNCTION:
        +sk_shift                                912	EXIST::FUNCTION:
        +sk_unshift                              913	EXIST::FUNCTION:
        +sk_zero                                 914	EXIST::FUNCTION:
        +BIO_f_nbio_test                         915	EXIST::FUNCTION:
        +ASN1_TYPE_get                           916	EXIST::FUNCTION:
        +ASN1_TYPE_set                           917	EXIST::FUNCTION:
        +PKCS7_content_free                      918	NOEXIST::FUNCTION:
        +ERR_load_PKCS7_strings                  919	EXIST::FUNCTION:
        +X509_find_by_issuer_and_serial          920	EXIST::FUNCTION:
        +X509_find_by_subject                    921	EXIST::FUNCTION:
        +PKCS7_ctrl                              927	EXIST::FUNCTION:
        +PKCS7_set_type                          928	EXIST::FUNCTION:
        +PKCS7_set_content                       929	EXIST::FUNCTION:
        +PKCS7_SIGNER_INFO_set                   930	EXIST::FUNCTION:
        +PKCS7_add_signer                        931	EXIST::FUNCTION:
        +PKCS7_add_certificate                   932	EXIST::FUNCTION:
        +PKCS7_add_crl                           933	EXIST::FUNCTION:
        +PKCS7_content_new                       934	EXIST::FUNCTION:
        +PKCS7_dataSign                          935	NOEXIST::FUNCTION:
        +PKCS7_dataVerify                        936	EXIST::FUNCTION:
        +PKCS7_dataInit                          937	EXIST::FUNCTION:
        +PKCS7_add_signature                     938	EXIST::FUNCTION:
        +PKCS7_cert_from_signer_info             939	EXIST::FUNCTION:
        +PKCS7_get_signer_info                   940	EXIST::FUNCTION:
        +EVP_delete_alias                        941	NOEXIST::FUNCTION:
        +EVP_mdc2                                942	EXIST::FUNCTION:MDC2
        +PEM_read_bio_RSAPublicKey               943	EXIST::FUNCTION:RSA
        +PEM_write_bio_RSAPublicKey              944	EXIST::FUNCTION:RSA
        +d2i_RSAPublicKey_bio                    945	EXIST::FUNCTION:BIO,RSA
        +i2d_RSAPublicKey_bio                    946	EXIST::FUNCTION:BIO,RSA
        +PEM_read_RSAPublicKey                   947	EXIST:!WIN16:FUNCTION:RSA
        +PEM_write_RSAPublicKey                  949	EXIST:!WIN16:FUNCTION:RSA
        +d2i_RSAPublicKey_fp                     952	EXIST::FUNCTION:FP_API,RSA
        +i2d_RSAPublicKey_fp                     954	EXIST::FUNCTION:FP_API,RSA
        +BIO_copy_next_retry                     955	EXIST::FUNCTION:
        +RSA_flags                               956	EXIST::FUNCTION:RSA
        +X509_STORE_add_crl                      957	EXIST::FUNCTION:
        +X509_load_crl_file                      958	EXIST::FUNCTION:STDIO
        +EVP_rc2_40_cbc                          959	EXIST::FUNCTION:RC2
        +EVP_rc4_40                              960	EXIST::FUNCTION:RC4
        +EVP_CIPHER_CTX_init                     961	EXIST::FUNCTION:
        +HMAC                                    962	EXIST::FUNCTION:HMAC
        +HMAC_Init                               963	EXIST::FUNCTION:HMAC
        +HMAC_Update                             964	EXIST::FUNCTION:HMAC
        +HMAC_Final                              965	EXIST::FUNCTION:HMAC
        +ERR_get_next_error_library              966	EXIST::FUNCTION:
        +EVP_PKEY_cmp_parameters                 967	EXIST::FUNCTION:
        +HMAC_cleanup                            968	NOEXIST::FUNCTION:
        +BIO_ptr_ctrl                            969	EXIST::FUNCTION:
        +BIO_new_file_internal                   970	NOEXIST::FUNCTION:
        +BIO_new_fp_internal                     971	NOEXIST::FUNCTION:
        +BIO_s_file_internal                     972	NOEXIST::FUNCTION:
        +BN_BLINDING_convert                     973	EXIST::FUNCTION:
        +BN_BLINDING_invert                      974	EXIST::FUNCTION:
        +BN_BLINDING_update                      975	EXIST::FUNCTION:
        +RSA_blinding_on                         977	EXIST::FUNCTION:RSA
        +RSA_blinding_off                        978	EXIST::FUNCTION:RSA
        +i2t_ASN1_OBJECT                         979	EXIST::FUNCTION:
        +BN_BLINDING_new                         980	EXIST::FUNCTION:
        +BN_BLINDING_free                        981	EXIST::FUNCTION:
        +EVP_cast5_cbc                           983	EXIST::FUNCTION:CAST
        +EVP_cast5_cfb64                         984	EXIST::FUNCTION:CAST
        +EVP_cast5_ecb                           985	EXIST::FUNCTION:CAST
        +EVP_cast5_ofb                           986	EXIST::FUNCTION:CAST
        +BF_decrypt                              987	EXIST::FUNCTION:BF
        +CAST_set_key                            988	EXIST::FUNCTION:CAST
        +CAST_encrypt                            989	EXIST::FUNCTION:CAST
        +CAST_decrypt                            990	EXIST::FUNCTION:CAST
        +CAST_ecb_encrypt                        991	EXIST::FUNCTION:CAST
        +CAST_cbc_encrypt                        992	EXIST::FUNCTION:CAST
        +CAST_cfb64_encrypt                      993	EXIST::FUNCTION:CAST
        +CAST_ofb64_encrypt                      994	EXIST::FUNCTION:CAST
        +RC2_decrypt                             995	EXIST::FUNCTION:RC2
        +OBJ_create_objects                      997	EXIST::FUNCTION:
        +BN_exp                                  998	EXIST::FUNCTION:
        +BN_mul_word                             999	EXIST::FUNCTION:
        +BN_sub_word                             1000	EXIST::FUNCTION:
        +BN_dec2bn                               1001	EXIST::FUNCTION:
        +BN_bn2dec                               1002	EXIST::FUNCTION:
        +BIO_ghbn_ctrl                           1003	NOEXIST::FUNCTION:
        +CRYPTO_free_ex_data                     1004	EXIST::FUNCTION:
        +CRYPTO_get_ex_data                      1005	EXIST::FUNCTION:
        +CRYPTO_set_ex_data                      1007	EXIST::FUNCTION:
        +ERR_load_CRYPTO_strings                 1009	EXIST:!OS2,!VMS:FUNCTION:
        +ERR_load_CRYPTOlib_strings              1009	EXIST:OS2,VMS:FUNCTION:
        +EVP_PKEY_bits                           1010	EXIST::FUNCTION:
        +MD5_Transform                           1011	EXIST::FUNCTION:MD5
        +SHA1_Transform                          1012	EXIST::FUNCTION:SHA,SHA1
        +SHA_Transform                           1013	EXIST::FUNCTION:SHA,SHA0
        +X509_STORE_CTX_get_chain                1014	EXIST::FUNCTION:
        +X509_STORE_CTX_get_current_cert         1015	EXIST::FUNCTION:
        +X509_STORE_CTX_get_error                1016	EXIST::FUNCTION:
        +X509_STORE_CTX_get_error_depth          1017	EXIST::FUNCTION:
        +X509_STORE_CTX_get_ex_data              1018	EXIST::FUNCTION:
        +X509_STORE_CTX_set_cert                 1020	EXIST::FUNCTION:
        +X509_STORE_CTX_set_chain                1021	EXIST::FUNCTION:
        +X509_STORE_CTX_set_error                1022	EXIST::FUNCTION:
        +X509_STORE_CTX_set_ex_data              1023	EXIST::FUNCTION:
        +CRYPTO_dup_ex_data                      1025	EXIST::FUNCTION:
        +CRYPTO_get_new_lockid                   1026	EXIST::FUNCTION:
        +CRYPTO_new_ex_data                      1027	EXIST::FUNCTION:
        +RSA_set_ex_data                         1028	EXIST::FUNCTION:RSA
        +RSA_get_ex_data                         1029	EXIST::FUNCTION:RSA
        +RSA_get_ex_new_index                    1030	EXIST::FUNCTION:RSA
        +RSA_padding_add_PKCS1_type_1            1031	EXIST::FUNCTION:RSA
        +RSA_padding_add_PKCS1_type_2            1032	EXIST::FUNCTION:RSA
        +RSA_padding_add_SSLv23                  1033	EXIST::FUNCTION:RSA
        +RSA_padding_add_none                    1034	EXIST::FUNCTION:RSA
        +RSA_padding_check_PKCS1_type_1          1035	EXIST::FUNCTION:RSA
        +RSA_padding_check_PKCS1_type_2          1036	EXIST::FUNCTION:RSA
        +RSA_padding_check_SSLv23                1037	EXIST::FUNCTION:RSA
        +RSA_padding_check_none                  1038	EXIST::FUNCTION:RSA
        +bn_add_words                            1039	EXIST::FUNCTION:
        +d2i_Netscape_RSA_2                      1040	NOEXIST::FUNCTION:
        +CRYPTO_get_ex_new_index                 1041	EXIST::FUNCTION:
        +RIPEMD160_Init                          1042	EXIST::FUNCTION:RIPEMD
        +RIPEMD160_Update                        1043	EXIST::FUNCTION:RIPEMD
        +RIPEMD160_Final                         1044	EXIST::FUNCTION:RIPEMD
        +RIPEMD160                               1045	EXIST::FUNCTION:RIPEMD
        +RIPEMD160_Transform                     1046	EXIST::FUNCTION:RIPEMD
        +RC5_32_set_key                          1047	EXIST::FUNCTION:RC5
        +RC5_32_ecb_encrypt                      1048	EXIST::FUNCTION:RC5
        +RC5_32_encrypt                          1049	EXIST::FUNCTION:RC5
        +RC5_32_decrypt                          1050	EXIST::FUNCTION:RC5
        +RC5_32_cbc_encrypt                      1051	EXIST::FUNCTION:RC5
        +RC5_32_cfb64_encrypt                    1052	EXIST::FUNCTION:RC5
        +RC5_32_ofb64_encrypt                    1053	EXIST::FUNCTION:RC5
        +BN_bn2mpi                               1058	EXIST::FUNCTION:
        +BN_mpi2bn                               1059	EXIST::FUNCTION:
        +ASN1_BIT_STRING_get_bit                 1060	EXIST::FUNCTION:
        +ASN1_BIT_STRING_set_bit                 1061	EXIST::FUNCTION:
        +BIO_get_ex_data                         1062	EXIST::FUNCTION:
        +BIO_get_ex_new_index                    1063	EXIST::FUNCTION:
        +BIO_set_ex_data                         1064	EXIST::FUNCTION:
        +X509v3_get_key_usage                    1066	NOEXIST::FUNCTION:
        +X509v3_set_key_usage                    1067	NOEXIST::FUNCTION:
        +a2i_X509v3_key_usage                    1068	NOEXIST::FUNCTION:
        +i2a_X509v3_key_usage                    1069	NOEXIST::FUNCTION:
        +EVP_PKEY_decrypt                        1070	EXIST::FUNCTION:
        +EVP_PKEY_encrypt                        1071	EXIST::FUNCTION:
        +PKCS7_RECIP_INFO_set                    1072	EXIST::FUNCTION:
        +PKCS7_add_recipient                     1073	EXIST::FUNCTION:
        +PKCS7_add_recipient_info                1074	EXIST::FUNCTION:
        +PKCS7_set_cipher                        1075	EXIST::FUNCTION:
        +ASN1_TYPE_get_int_octetstring           1076	EXIST::FUNCTION:
        +ASN1_TYPE_get_octetstring               1077	EXIST::FUNCTION:
        +ASN1_TYPE_set_int_octetstring           1078	EXIST::FUNCTION:
        +ASN1_TYPE_set_octetstring               1079	EXIST::FUNCTION:
        +ASN1_UTCTIME_set_string                 1080	EXIST::FUNCTION:
        +ERR_add_error_data                      1081	EXIST::FUNCTION:
        +ERR_set_error_data                      1082	EXIST::FUNCTION:
        +EVP_CIPHER_asn1_to_param                1083	EXIST::FUNCTION:
        +EVP_CIPHER_param_to_asn1                1084	EXIST::FUNCTION:
        +EVP_CIPHER_get_asn1_iv                  1085	EXIST::FUNCTION:
        +EVP_CIPHER_set_asn1_iv                  1086	EXIST::FUNCTION:
        +EVP_rc5_32_12_16_cbc                    1087	EXIST::FUNCTION:RC5
        +EVP_rc5_32_12_16_cfb64                  1088	EXIST::FUNCTION:RC5
        +EVP_rc5_32_12_16_ecb                    1089	EXIST::FUNCTION:RC5
        +EVP_rc5_32_12_16_ofb                    1090	EXIST::FUNCTION:RC5
        +asn1_add_error                          1091	EXIST::FUNCTION:
        +d2i_ASN1_BMPSTRING                      1092	EXIST::FUNCTION:
        +i2d_ASN1_BMPSTRING                      1093	EXIST::FUNCTION:
        +BIO_f_ber                               1094	NOEXIST::FUNCTION:
        +BN_init                                 1095	EXIST::FUNCTION:
        +COMP_CTX_new                            1096	EXIST::FUNCTION:
        +COMP_CTX_free                           1097	EXIST::FUNCTION:
        +COMP_CTX_compress_block                 1098	NOEXIST::FUNCTION:
        +COMP_CTX_expand_block                   1099	NOEXIST::FUNCTION:
        +X509_STORE_CTX_get_ex_new_index         1100	EXIST::FUNCTION:
        +OBJ_NAME_add                            1101	EXIST::FUNCTION:
        +BIO_socket_nbio                         1102	EXIST::FUNCTION:
        +EVP_rc2_64_cbc                          1103	EXIST::FUNCTION:RC2
        +OBJ_NAME_cleanup                        1104	EXIST::FUNCTION:
        +OBJ_NAME_get                            1105	EXIST::FUNCTION:
        +OBJ_NAME_init                           1106	EXIST::FUNCTION:
        +OBJ_NAME_new_index                      1107	EXIST::FUNCTION:
        +OBJ_NAME_remove                         1108	EXIST::FUNCTION:
        +BN_MONT_CTX_copy                        1109	EXIST::FUNCTION:
        +BIO_new_socks4a_connect                 1110	NOEXIST::FUNCTION:
        +BIO_s_socks4a_connect                   1111	NOEXIST::FUNCTION:
        +PROXY_set_connect_mode                  1112	NOEXIST::FUNCTION:
        +RAND_SSLeay                             1113	EXIST::FUNCTION:
        +RAND_set_rand_method                    1114	EXIST::FUNCTION:
        +RSA_memory_lock                         1115	EXIST::FUNCTION:RSA
        +bn_sub_words                            1116	EXIST::FUNCTION:
        +bn_mul_normal                           1117	NOEXIST::FUNCTION:
        +bn_mul_comba8                           1118	NOEXIST::FUNCTION:
        +bn_mul_comba4                           1119	NOEXIST::FUNCTION:
        +bn_sqr_normal                           1120	NOEXIST::FUNCTION:
        +bn_sqr_comba8                           1121	NOEXIST::FUNCTION:
        +bn_sqr_comba4                           1122	NOEXIST::FUNCTION:
        +bn_cmp_words                            1123	NOEXIST::FUNCTION:
        +bn_mul_recursive                        1124	NOEXIST::FUNCTION:
        +bn_mul_part_recursive                   1125	NOEXIST::FUNCTION:
        +bn_sqr_recursive                        1126	NOEXIST::FUNCTION:
        +bn_mul_low_normal                       1127	NOEXIST::FUNCTION:
        +BN_RECP_CTX_init                        1128	EXIST::FUNCTION:
        +BN_RECP_CTX_new                         1129	EXIST::FUNCTION:
        +BN_RECP_CTX_free                        1130	EXIST::FUNCTION:
        +BN_RECP_CTX_set                         1131	EXIST::FUNCTION:
        +BN_mod_mul_reciprocal                   1132	EXIST::FUNCTION:
        +BN_mod_exp_recp                         1133	EXIST::FUNCTION:
        +BN_div_recp                             1134	EXIST::FUNCTION:
        +BN_CTX_init                             1135	EXIST::FUNCTION:DEPRECATED
        +BN_MONT_CTX_init                        1136	EXIST::FUNCTION:
        +RAND_get_rand_method                    1137	EXIST::FUNCTION:
        +PKCS7_add_attribute                     1138	EXIST::FUNCTION:
        +PKCS7_add_signed_attribute              1139	EXIST::FUNCTION:
        +PKCS7_digest_from_attributes            1140	EXIST::FUNCTION:
        +PKCS7_get_attribute                     1141	EXIST::FUNCTION:
        +PKCS7_get_issuer_and_serial             1142	EXIST::FUNCTION:
        +PKCS7_get_signed_attribute              1143	EXIST::FUNCTION:
        +COMP_compress_block                     1144	EXIST::FUNCTION:
        +COMP_expand_block                       1145	EXIST::FUNCTION:
        +COMP_rle                                1146	EXIST::FUNCTION:
        +COMP_zlib                               1147	EXIST::FUNCTION:
        +ms_time_diff                            1148	NOEXIST::FUNCTION:
        +ms_time_new                             1149	NOEXIST::FUNCTION:
        +ms_time_free                            1150	NOEXIST::FUNCTION:
        +ms_time_cmp                             1151	NOEXIST::FUNCTION:
        +ms_time_get                             1152	NOEXIST::FUNCTION:
        +PKCS7_set_attributes                    1153	EXIST::FUNCTION:
        +PKCS7_set_signed_attributes             1154	EXIST::FUNCTION:
        +X509_ATTRIBUTE_create                   1155	EXIST::FUNCTION:
        +X509_ATTRIBUTE_dup                      1156	EXIST::FUNCTION:
        +ASN1_GENERALIZEDTIME_check              1157	EXIST::FUNCTION:
        +ASN1_GENERALIZEDTIME_print              1158	EXIST::FUNCTION:BIO
        +ASN1_GENERALIZEDTIME_set                1159	EXIST::FUNCTION:
        +ASN1_GENERALIZEDTIME_set_string         1160	EXIST::FUNCTION:
        +ASN1_TIME_print                         1161	EXIST::FUNCTION:BIO
        +BASIC_CONSTRAINTS_free                  1162	EXIST::FUNCTION:
        +BASIC_CONSTRAINTS_new                   1163	EXIST::FUNCTION:
        +ERR_load_X509V3_strings                 1164	EXIST::FUNCTION:
        +NETSCAPE_CERT_SEQUENCE_free             1165	EXIST::FUNCTION:
        +NETSCAPE_CERT_SEQUENCE_new              1166	EXIST::FUNCTION:
        +OBJ_txt2obj                             1167	EXIST::FUNCTION:
        +PEM_read_NETSCAPE_CERT_SEQUENCE         1168	EXIST:!VMS,!WIN16:FUNCTION:
        +PEM_read_NS_CERT_SEQ                    1168	EXIST:VMS:FUNCTION:
        +PEM_read_bio_NETSCAPE_CERT_SEQUENCE     1169	EXIST:!VMS:FUNCTION:
        +PEM_read_bio_NS_CERT_SEQ                1169	EXIST:VMS:FUNCTION:
        +PEM_write_NETSCAPE_CERT_SEQUENCE        1170	EXIST:!VMS,!WIN16:FUNCTION:
        +PEM_write_NS_CERT_SEQ                   1170	EXIST:VMS:FUNCTION:
        +PEM_write_bio_NETSCAPE_CERT_SEQUENCE    1171	EXIST:!VMS:FUNCTION:
        +PEM_write_bio_NS_CERT_SEQ               1171	EXIST:VMS:FUNCTION:
        +X509V3_EXT_add                          1172	EXIST::FUNCTION:
        +X509V3_EXT_add_alias                    1173	EXIST::FUNCTION:
        +X509V3_EXT_add_conf                     1174	EXIST::FUNCTION:
        +X509V3_EXT_cleanup                      1175	EXIST::FUNCTION:
        +X509V3_EXT_conf                         1176	EXIST::FUNCTION:
        +X509V3_EXT_conf_nid                     1177	EXIST::FUNCTION:
        +X509V3_EXT_get                          1178	EXIST::FUNCTION:
        +X509V3_EXT_get_nid                      1179	EXIST::FUNCTION:
        +X509V3_EXT_print                        1180	EXIST::FUNCTION:
        +X509V3_EXT_print_fp                     1181	EXIST::FUNCTION:
        +X509V3_add_standard_extensions          1182	EXIST::FUNCTION:
        +X509V3_add_value                        1183	EXIST::FUNCTION:
        +X509V3_add_value_bool                   1184	EXIST::FUNCTION:
        +X509V3_add_value_int                    1185	EXIST::FUNCTION:
        +X509V3_conf_free                        1186	EXIST::FUNCTION:
        +X509V3_get_value_bool                   1187	EXIST::FUNCTION:
        +X509V3_get_value_int                    1188	EXIST::FUNCTION:
        +X509V3_parse_list                       1189	EXIST::FUNCTION:
        +d2i_ASN1_GENERALIZEDTIME                1190	EXIST::FUNCTION:
        +d2i_ASN1_TIME                           1191	EXIST::FUNCTION:
        +d2i_BASIC_CONSTRAINTS                   1192	EXIST::FUNCTION:
        +d2i_NETSCAPE_CERT_SEQUENCE              1193	EXIST::FUNCTION:
        +d2i_ext_ku                              1194	NOEXIST::FUNCTION:
        +ext_ku_free                             1195	NOEXIST::FUNCTION:
        +ext_ku_new                              1196	NOEXIST::FUNCTION:
        +i2d_ASN1_GENERALIZEDTIME                1197	EXIST::FUNCTION:
        +i2d_ASN1_TIME                           1198	EXIST::FUNCTION:
        +i2d_BASIC_CONSTRAINTS                   1199	EXIST::FUNCTION:
        +i2d_NETSCAPE_CERT_SEQUENCE              1200	EXIST::FUNCTION:
        +i2d_ext_ku                              1201	NOEXIST::FUNCTION:
        +EVP_MD_CTX_copy                         1202	EXIST::FUNCTION:
        +i2d_ASN1_ENUMERATED                     1203	EXIST::FUNCTION:
        +d2i_ASN1_ENUMERATED                     1204	EXIST::FUNCTION:
        +ASN1_ENUMERATED_set                     1205	EXIST::FUNCTION:
        +ASN1_ENUMERATED_get                     1206	EXIST::FUNCTION:
        +BN_to_ASN1_ENUMERATED                   1207	EXIST::FUNCTION:
        +ASN1_ENUMERATED_to_BN                   1208	EXIST::FUNCTION:
        +i2a_ASN1_ENUMERATED                     1209	EXIST::FUNCTION:BIO
        +a2i_ASN1_ENUMERATED                     1210	EXIST::FUNCTION:BIO
        +i2d_GENERAL_NAME                        1211	EXIST::FUNCTION:
        +d2i_GENERAL_NAME                        1212	EXIST::FUNCTION:
        +GENERAL_NAME_new                        1213	EXIST::FUNCTION:
        +GENERAL_NAME_free                       1214	EXIST::FUNCTION:
        +GENERAL_NAMES_new                       1215	EXIST::FUNCTION:
        +GENERAL_NAMES_free                      1216	EXIST::FUNCTION:
        +d2i_GENERAL_NAMES                       1217	EXIST::FUNCTION:
        +i2d_GENERAL_NAMES                       1218	EXIST::FUNCTION:
        +i2v_GENERAL_NAMES                       1219	EXIST::FUNCTION:
        +i2s_ASN1_OCTET_STRING                   1220	EXIST::FUNCTION:
        +s2i_ASN1_OCTET_STRING                   1221	EXIST::FUNCTION:
        +X509V3_EXT_check_conf                   1222	NOEXIST::FUNCTION:
        +hex_to_string                           1223	EXIST::FUNCTION:
        +string_to_hex                           1224	EXIST::FUNCTION:
        +DES_ede3_cbcm_encrypt                   1225	EXIST::FUNCTION:DES
        +RSA_padding_add_PKCS1_OAEP              1226	EXIST::FUNCTION:RSA
        +RSA_padding_check_PKCS1_OAEP            1227	EXIST::FUNCTION:RSA
        +X509_CRL_print_fp                       1228	EXIST::FUNCTION:FP_API
        +X509_CRL_print                          1229	EXIST::FUNCTION:BIO
        +i2v_GENERAL_NAME                        1230	EXIST::FUNCTION:
        +v2i_GENERAL_NAME                        1231	EXIST::FUNCTION:
        +i2d_PKEY_USAGE_PERIOD                   1232	EXIST::FUNCTION:
        +d2i_PKEY_USAGE_PERIOD                   1233	EXIST::FUNCTION:
        +PKEY_USAGE_PERIOD_new                   1234	EXIST::FUNCTION:
        +PKEY_USAGE_PERIOD_free                  1235	EXIST::FUNCTION:
        +v2i_GENERAL_NAMES                       1236	EXIST::FUNCTION:
        +i2s_ASN1_INTEGER                        1237	EXIST::FUNCTION:
        +X509V3_EXT_d2i                          1238	EXIST::FUNCTION:
        +name_cmp                                1239	EXIST::FUNCTION:
        +str_dup                                 1240	NOEXIST::FUNCTION:
        +i2s_ASN1_ENUMERATED                     1241	EXIST::FUNCTION:
        +i2s_ASN1_ENUMERATED_TABLE               1242	EXIST::FUNCTION:
        +BIO_s_log                               1243	EXIST:!OS2,!WIN16,!WIN32,!macintosh:FUNCTION:
        +BIO_f_reliable                          1244	EXIST::FUNCTION:BIO
        +PKCS7_dataFinal                         1245	EXIST::FUNCTION:
        +PKCS7_dataDecode                        1246	EXIST::FUNCTION:
        +X509V3_EXT_CRL_add_conf                 1247	EXIST::FUNCTION:
        +BN_set_params                           1248	EXIST::FUNCTION:DEPRECATED
        +BN_get_params                           1249	EXIST::FUNCTION:DEPRECATED
        +BIO_get_ex_num                          1250	NOEXIST::FUNCTION:
        +BIO_set_ex_free_func                    1251	NOEXIST::FUNCTION:
        +EVP_ripemd160                           1252	EXIST::FUNCTION:RIPEMD
        +ASN1_TIME_set                           1253	EXIST::FUNCTION:
        +i2d_AUTHORITY_KEYID                     1254	EXIST::FUNCTION:
        +d2i_AUTHORITY_KEYID                     1255	EXIST::FUNCTION:
        +AUTHORITY_KEYID_new                     1256	EXIST::FUNCTION:
        +AUTHORITY_KEYID_free                    1257	EXIST::FUNCTION:
        +ASN1_seq_unpack                         1258	EXIST::FUNCTION:
        +ASN1_seq_pack                           1259	EXIST::FUNCTION:
        +ASN1_unpack_string                      1260	EXIST::FUNCTION:
        +ASN1_pack_string                        1261	EXIST::FUNCTION:
        +PKCS12_pack_safebag                     1262	NOEXIST::FUNCTION:
        +PKCS12_MAKE_KEYBAG                      1263	EXIST::FUNCTION:
        +PKCS8_encrypt                           1264	EXIST::FUNCTION:
        +PKCS12_MAKE_SHKEYBAG                    1265	EXIST::FUNCTION:
        +PKCS12_pack_p7data                      1266	EXIST::FUNCTION:
        +PKCS12_pack_p7encdata                   1267	EXIST::FUNCTION:
        +PKCS12_add_localkeyid                   1268	EXIST::FUNCTION:
        +PKCS12_add_friendlyname_asc             1269	EXIST::FUNCTION:
        +PKCS12_add_friendlyname_uni             1270	EXIST::FUNCTION:
        +PKCS12_get_friendlyname                 1271	EXIST::FUNCTION:
        +PKCS12_pbe_crypt                        1272	EXIST::FUNCTION:
        +PKCS12_decrypt_d2i                      1273	NOEXIST::FUNCTION:
        +PKCS12_i2d_encrypt                      1274	NOEXIST::FUNCTION:
        +PKCS12_init                             1275	EXIST::FUNCTION:
        +PKCS12_key_gen_asc                      1276	EXIST::FUNCTION:
        +PKCS12_key_gen_uni                      1277	EXIST::FUNCTION:
        +PKCS12_gen_mac                          1278	EXIST::FUNCTION:
        +PKCS12_verify_mac                       1279	EXIST::FUNCTION:
        +PKCS12_set_mac                          1280	EXIST::FUNCTION:
        +PKCS12_setup_mac                        1281	EXIST::FUNCTION:
        +OPENSSL_asc2uni                         1282	EXIST::FUNCTION:
        +OPENSSL_uni2asc                         1283	EXIST::FUNCTION:
        +i2d_PKCS12_BAGS                         1284	EXIST::FUNCTION:
        +PKCS12_BAGS_new                         1285	EXIST::FUNCTION:
        +d2i_PKCS12_BAGS                         1286	EXIST::FUNCTION:
        +PKCS12_BAGS_free                        1287	EXIST::FUNCTION:
        +i2d_PKCS12                              1288	EXIST::FUNCTION:
        +d2i_PKCS12                              1289	EXIST::FUNCTION:
        +PKCS12_new                              1290	EXIST::FUNCTION:
        +PKCS12_free                             1291	EXIST::FUNCTION:
        +i2d_PKCS12_MAC_DATA                     1292	EXIST::FUNCTION:
        +PKCS12_MAC_DATA_new                     1293	EXIST::FUNCTION:
        +d2i_PKCS12_MAC_DATA                     1294	EXIST::FUNCTION:
        +PKCS12_MAC_DATA_free                    1295	EXIST::FUNCTION:
        +i2d_PKCS12_SAFEBAG                      1296	EXIST::FUNCTION:
        +PKCS12_SAFEBAG_new                      1297	EXIST::FUNCTION:
        +d2i_PKCS12_SAFEBAG                      1298	EXIST::FUNCTION:
        +PKCS12_SAFEBAG_free                     1299	EXIST::FUNCTION:
        +ERR_load_PKCS12_strings                 1300	EXIST::FUNCTION:
        +PKCS12_PBE_add                          1301	EXIST::FUNCTION:
        +PKCS8_add_keyusage                      1302	EXIST::FUNCTION:
        +PKCS12_get_attr_gen                     1303	EXIST::FUNCTION:
        +PKCS12_parse                            1304	EXIST::FUNCTION:
        +PKCS12_create                           1305	EXIST::FUNCTION:
        +i2d_PKCS12_bio                          1306	EXIST::FUNCTION:
        +i2d_PKCS12_fp                           1307	EXIST::FUNCTION:
        +d2i_PKCS12_bio                          1308	EXIST::FUNCTION:
        +d2i_PKCS12_fp                           1309	EXIST::FUNCTION:
        +i2d_PBEPARAM                            1310	EXIST::FUNCTION:
        +PBEPARAM_new                            1311	EXIST::FUNCTION:
        +d2i_PBEPARAM                            1312	EXIST::FUNCTION:
        +PBEPARAM_free                           1313	EXIST::FUNCTION:
        +i2d_PKCS8_PRIV_KEY_INFO                 1314	EXIST::FUNCTION:
        +PKCS8_PRIV_KEY_INFO_new                 1315	EXIST::FUNCTION:
        +d2i_PKCS8_PRIV_KEY_INFO                 1316	EXIST::FUNCTION:
        +PKCS8_PRIV_KEY_INFO_free                1317	EXIST::FUNCTION:
        +EVP_PKCS82PKEY                          1318	EXIST::FUNCTION:
        +EVP_PKEY2PKCS8                          1319	EXIST::FUNCTION:
        +PKCS8_set_broken                        1320	EXIST::FUNCTION:
        +EVP_PBE_ALGOR_CipherInit                1321	NOEXIST::FUNCTION:
        +EVP_PBE_alg_add                         1322	EXIST::FUNCTION:
        +PKCS5_pbe_set                           1323	EXIST::FUNCTION:
        +EVP_PBE_cleanup                         1324	EXIST::FUNCTION:
        +i2d_SXNET                               1325	EXIST::FUNCTION:
        +d2i_SXNET                               1326	EXIST::FUNCTION:
        +SXNET_new                               1327	EXIST::FUNCTION:
        +SXNET_free                              1328	EXIST::FUNCTION:
        +i2d_SXNETID                             1329	EXIST::FUNCTION:
        +d2i_SXNETID                             1330	EXIST::FUNCTION:
        +SXNETID_new                             1331	EXIST::FUNCTION:
        +SXNETID_free                            1332	EXIST::FUNCTION:
        +DSA_SIG_new                             1333	EXIST::FUNCTION:DSA
        +DSA_SIG_free                            1334	EXIST::FUNCTION:DSA
        +DSA_do_sign                             1335	EXIST::FUNCTION:DSA
        +DSA_do_verify                           1336	EXIST::FUNCTION:DSA
        +d2i_DSA_SIG                             1337	EXIST::FUNCTION:DSA
        +i2d_DSA_SIG                             1338	EXIST::FUNCTION:DSA
        +i2d_ASN1_VISIBLESTRING                  1339	EXIST::FUNCTION:
        +d2i_ASN1_VISIBLESTRING                  1340	EXIST::FUNCTION:
        +i2d_ASN1_UTF8STRING                     1341	EXIST::FUNCTION:
        +d2i_ASN1_UTF8STRING                     1342	EXIST::FUNCTION:
        +i2d_DIRECTORYSTRING                     1343	EXIST::FUNCTION:
        +d2i_DIRECTORYSTRING                     1344	EXIST::FUNCTION:
        +i2d_DISPLAYTEXT                         1345	EXIST::FUNCTION:
        +d2i_DISPLAYTEXT                         1346	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509                    1379	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509                    1380	NOEXIST::FUNCTION:
        +i2d_PBKDF2PARAM                         1397	EXIST::FUNCTION:
        +PBKDF2PARAM_new                         1398	EXIST::FUNCTION:
        +d2i_PBKDF2PARAM                         1399	EXIST::FUNCTION:
        +PBKDF2PARAM_free                        1400	EXIST::FUNCTION:
        +i2d_PBE2PARAM                           1401	EXIST::FUNCTION:
        +PBE2PARAM_new                           1402	EXIST::FUNCTION:
        +d2i_PBE2PARAM                           1403	EXIST::FUNCTION:
        +PBE2PARAM_free                          1404	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_GENERAL_NAME            1421	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_GENERAL_NAME            1422	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_SXNETID                 1439	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_SXNETID                 1440	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_POLICYQUALINFO          1457	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_POLICYQUALINFO          1458	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_POLICYINFO              1475	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_POLICYINFO              1476	NOEXIST::FUNCTION:
        +SXNET_add_id_asc                        1477	EXIST::FUNCTION:
        +SXNET_add_id_ulong                      1478	EXIST::FUNCTION:
        +SXNET_add_id_INTEGER                    1479	EXIST::FUNCTION:
        +SXNET_get_id_asc                        1480	EXIST::FUNCTION:
        +SXNET_get_id_ulong                      1481	EXIST::FUNCTION:
        +SXNET_get_id_INTEGER                    1482	EXIST::FUNCTION:
        +X509V3_set_conf_lhash                   1483	EXIST::FUNCTION:
        +i2d_CERTIFICATEPOLICIES                 1484	EXIST::FUNCTION:
        +CERTIFICATEPOLICIES_new                 1485	EXIST::FUNCTION:
        +CERTIFICATEPOLICIES_free                1486	EXIST::FUNCTION:
        +d2i_CERTIFICATEPOLICIES                 1487	EXIST::FUNCTION:
        +i2d_POLICYINFO                          1488	EXIST::FUNCTION:
        +POLICYINFO_new                          1489	EXIST::FUNCTION:
        +d2i_POLICYINFO                          1490	EXIST::FUNCTION:
        +POLICYINFO_free                         1491	EXIST::FUNCTION:
        +i2d_POLICYQUALINFO                      1492	EXIST::FUNCTION:
        +POLICYQUALINFO_new                      1493	EXIST::FUNCTION:
        +d2i_POLICYQUALINFO                      1494	EXIST::FUNCTION:
        +POLICYQUALINFO_free                     1495	EXIST::FUNCTION:
        +i2d_USERNOTICE                          1496	EXIST::FUNCTION:
        +USERNOTICE_new                          1497	EXIST::FUNCTION:
        +d2i_USERNOTICE                          1498	EXIST::FUNCTION:
        +USERNOTICE_free                         1499	EXIST::FUNCTION:
        +i2d_NOTICEREF                           1500	EXIST::FUNCTION:
        +NOTICEREF_new                           1501	EXIST::FUNCTION:
        +d2i_NOTICEREF                           1502	EXIST::FUNCTION:
        +NOTICEREF_free                          1503	EXIST::FUNCTION:
        +X509V3_get_string                       1504	EXIST::FUNCTION:
        +X509V3_get_section                      1505	EXIST::FUNCTION:
        +X509V3_string_free                      1506	EXIST::FUNCTION:
        +X509V3_section_free                     1507	EXIST::FUNCTION:
        +X509V3_set_ctx                          1508	EXIST::FUNCTION:
        +s2i_ASN1_INTEGER                        1509	EXIST::FUNCTION:
        +CRYPTO_set_locked_mem_functions         1510	EXIST::FUNCTION:
        +CRYPTO_get_locked_mem_functions         1511	EXIST::FUNCTION:
        +CRYPTO_malloc_locked                    1512	EXIST::FUNCTION:
        +CRYPTO_free_locked                      1513	EXIST::FUNCTION:
        +BN_mod_exp2_mont                        1514	EXIST::FUNCTION:
        +ERR_get_error_line_data                 1515	EXIST::FUNCTION:
        +ERR_peek_error_line_data                1516	EXIST::FUNCTION:
        +PKCS12_PBE_keyivgen                     1517	EXIST::FUNCTION:
        +X509_ALGOR_dup                          1518	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_DIST_POINT              1535	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_DIST_POINT              1536	NOEXIST::FUNCTION:
        +i2d_CRL_DIST_POINTS                     1537	EXIST::FUNCTION:
        +CRL_DIST_POINTS_new                     1538	EXIST::FUNCTION:
        +CRL_DIST_POINTS_free                    1539	EXIST::FUNCTION:
        +d2i_CRL_DIST_POINTS                     1540	EXIST::FUNCTION:
        +i2d_DIST_POINT                          1541	EXIST::FUNCTION:
        +DIST_POINT_new                          1542	EXIST::FUNCTION:
        +d2i_DIST_POINT                          1543	EXIST::FUNCTION:
        +DIST_POINT_free                         1544	EXIST::FUNCTION:
        +i2d_DIST_POINT_NAME                     1545	EXIST::FUNCTION:
        +DIST_POINT_NAME_new                     1546	EXIST::FUNCTION:
        +DIST_POINT_NAME_free                    1547	EXIST::FUNCTION:
        +d2i_DIST_POINT_NAME                     1548	EXIST::FUNCTION:
        +X509V3_add_value_uchar                  1549	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509_ATTRIBUTE          1555	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_ASN1_TYPE               1560	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509_EXTENSION          1567	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509_NAME_ENTRY         1574	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_ASN1_TYPE               1589	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509_ATTRIBUTE          1615	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509_EXTENSION          1624	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509_NAME_ENTRY         1633	NOEXIST::FUNCTION:
        +X509V3_EXT_i2d                          1646	EXIST::FUNCTION:
        +X509V3_EXT_val_prn                      1647	EXIST::FUNCTION:
        +X509V3_EXT_add_list                     1648	EXIST::FUNCTION:
        +EVP_CIPHER_type                         1649	EXIST::FUNCTION:
        +EVP_PBE_CipherInit                      1650	EXIST::FUNCTION:
        +X509V3_add_value_bool_nf                1651	EXIST::FUNCTION:
        +d2i_ASN1_UINTEGER                       1652	EXIST::FUNCTION:
        +sk_value                                1653	EXIST::FUNCTION:
        +sk_num                                  1654	EXIST::FUNCTION:
        +sk_set                                  1655	EXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509_REVOKED            1661	NOEXIST::FUNCTION:
        +sk_sort                                 1671	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509_REVOKED            1674	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509_ALGOR              1682	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_X509_CRL                1685	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509_ALGOR              1696	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_X509_CRL                1702	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO       1723	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_PKCS7_RECIP_INFO        1738	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO       1748	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_PKCS7_RECIP_INFO        1753	NOEXIST::FUNCTION:
        +PKCS5_PBE_add                           1775	EXIST::FUNCTION:
        +PEM_write_bio_PKCS8                     1776	EXIST::FUNCTION:
        +i2d_PKCS8_fp                            1777	EXIST::FUNCTION:FP_API
        +PEM_read_bio_PKCS8_PRIV_KEY_INFO        1778	EXIST:!VMS:FUNCTION:
        +PEM_read_bio_P8_PRIV_KEY_INFO           1778	EXIST:VMS:FUNCTION:
        +d2i_PKCS8_bio                           1779	EXIST::FUNCTION:BIO
        +d2i_PKCS8_PRIV_KEY_INFO_fp              1780	EXIST::FUNCTION:FP_API
        +PEM_write_bio_PKCS8_PRIV_KEY_INFO       1781	EXIST:!VMS:FUNCTION:
        +PEM_write_bio_P8_PRIV_KEY_INFO          1781	EXIST:VMS:FUNCTION:
        +PEM_read_PKCS8                          1782	EXIST:!WIN16:FUNCTION:
        +d2i_PKCS8_PRIV_KEY_INFO_bio             1783	EXIST::FUNCTION:BIO
        +d2i_PKCS8_fp                            1784	EXIST::FUNCTION:FP_API
        +PEM_write_PKCS8                         1785	EXIST:!WIN16:FUNCTION:
        +PEM_read_PKCS8_PRIV_KEY_INFO            1786	EXIST:!VMS,!WIN16:FUNCTION:
        +PEM_read_P8_PRIV_KEY_INFO               1786	EXIST:VMS:FUNCTION:
        +PEM_read_bio_PKCS8                      1787	EXIST::FUNCTION:
        +PEM_write_PKCS8_PRIV_KEY_INFO           1788	EXIST:!VMS,!WIN16:FUNCTION:
        +PEM_write_P8_PRIV_KEY_INFO              1788	EXIST:VMS:FUNCTION:
        +PKCS5_PBE_keyivgen                      1789	EXIST::FUNCTION:
        +i2d_PKCS8_bio                           1790	EXIST::FUNCTION:BIO
        +i2d_PKCS8_PRIV_KEY_INFO_fp              1791	EXIST::FUNCTION:FP_API
        +i2d_PKCS8_PRIV_KEY_INFO_bio             1792	EXIST::FUNCTION:BIO
        +BIO_s_bio                               1793	EXIST::FUNCTION:
        +PKCS5_pbe2_set                          1794	EXIST::FUNCTION:
        +PKCS5_PBKDF2_HMAC_SHA1                  1795	EXIST::FUNCTION:
        +PKCS5_v2_PBE_keyivgen                   1796	EXIST::FUNCTION:
        +PEM_write_bio_PKCS8PrivateKey           1797	EXIST::FUNCTION:
        +PEM_write_PKCS8PrivateKey               1798	EXIST::FUNCTION:
        +BIO_ctrl_get_read_request               1799	EXIST::FUNCTION:
        +BIO_ctrl_pending                        1800	EXIST::FUNCTION:
        +BIO_ctrl_wpending                       1801	EXIST::FUNCTION:
        +BIO_new_bio_pair                        1802	EXIST::FUNCTION:
        +BIO_ctrl_get_write_guarantee            1803	EXIST::FUNCTION:
        +CRYPTO_num_locks                        1804	EXIST::FUNCTION:
        +CONF_load_bio                           1805	EXIST::FUNCTION:
        +CONF_load_fp                            1806	EXIST::FUNCTION:FP_API
        +i2d_ASN1_SET_OF_ASN1_OBJECT             1837	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_ASN1_OBJECT             1844	NOEXIST::FUNCTION:
        +PKCS7_signatureVerify                   1845	EXIST::FUNCTION:
        +RSA_set_method                          1846	EXIST::FUNCTION:RSA
        +RSA_get_method                          1847	EXIST::FUNCTION:RSA
        +RSA_get_default_method                  1848	EXIST::FUNCTION:RSA
        +RSA_check_key                           1869	EXIST::FUNCTION:RSA
        +OBJ_obj2txt                             1870	EXIST::FUNCTION:
        +DSA_dup_DH                              1871	EXIST::FUNCTION:DH,DSA
        +X509_REQ_get_extensions                 1872	EXIST::FUNCTION:
        +X509_REQ_set_extension_nids             1873	EXIST::FUNCTION:
        +BIO_nwrite                              1874	EXIST::FUNCTION:
        +X509_REQ_extension_nid                  1875	EXIST::FUNCTION:
        +BIO_nread                               1876	EXIST::FUNCTION:
        +X509_REQ_get_extension_nids             1877	EXIST::FUNCTION:
        +BIO_nwrite0                             1878	EXIST::FUNCTION:
        +X509_REQ_add_extensions_nid             1879	EXIST::FUNCTION:
        +BIO_nread0                              1880	EXIST::FUNCTION:
        +X509_REQ_add_extensions                 1881	EXIST::FUNCTION:
        +BIO_new_mem_buf                         1882	EXIST::FUNCTION:
        +DH_set_ex_data                          1883	EXIST::FUNCTION:DH
        +DH_set_method                           1884	EXIST::FUNCTION:DH
        +DSA_OpenSSL                             1885	EXIST::FUNCTION:DSA
        +DH_get_ex_data                          1886	EXIST::FUNCTION:DH
        +DH_get_ex_new_index                     1887	EXIST::FUNCTION:DH
        +DSA_new_method                          1888	EXIST::FUNCTION:DSA
        +DH_new_method                           1889	EXIST::FUNCTION:DH
        +DH_OpenSSL                              1890	EXIST::FUNCTION:DH
        +DSA_get_ex_new_index                    1891	EXIST::FUNCTION:DSA
        +DH_get_default_method                   1892	EXIST::FUNCTION:DH
        +DSA_set_ex_data                         1893	EXIST::FUNCTION:DSA
        +DH_set_default_method                   1894	EXIST::FUNCTION:DH
        +DSA_get_ex_data                         1895	EXIST::FUNCTION:DSA
        +X509V3_EXT_REQ_add_conf                 1896	EXIST::FUNCTION:
        +NETSCAPE_SPKI_print                     1897	EXIST::FUNCTION:EVP
        +NETSCAPE_SPKI_set_pubkey                1898	EXIST::FUNCTION:EVP
        +NETSCAPE_SPKI_b64_encode                1899	EXIST::FUNCTION:EVP
        +NETSCAPE_SPKI_get_pubkey                1900	EXIST::FUNCTION:EVP
        +NETSCAPE_SPKI_b64_decode                1901	EXIST::FUNCTION:EVP
        +UTF8_putc                               1902	EXIST::FUNCTION:
        +UTF8_getc                               1903	EXIST::FUNCTION:
        +RSA_null_method                         1904	EXIST::FUNCTION:RSA
        +ASN1_tag2str                            1905	EXIST::FUNCTION:
        +BIO_ctrl_reset_read_request             1906	EXIST::FUNCTION:
        +DISPLAYTEXT_new                         1907	EXIST::FUNCTION:
        +ASN1_GENERALIZEDTIME_free               1908	EXIST::FUNCTION:
        +X509_REVOKED_get_ext_d2i                1909	EXIST::FUNCTION:
        +X509_set_ex_data                        1910	EXIST::FUNCTION:
        +X509_reject_set_bit_asc                 1911	NOEXIST::FUNCTION:
        +X509_NAME_add_entry_by_txt              1912	EXIST::FUNCTION:
        +X509_NAME_add_entry_by_NID              1914	EXIST::FUNCTION:
        +X509_PURPOSE_get0                       1915	EXIST::FUNCTION:
        +PEM_read_X509_AUX                       1917	EXIST:!WIN16:FUNCTION:
        +d2i_AUTHORITY_INFO_ACCESS               1918	EXIST::FUNCTION:
        +PEM_write_PUBKEY                        1921	EXIST:!WIN16:FUNCTION:
        +ACCESS_DESCRIPTION_new                  1925	EXIST::FUNCTION:
        +X509_CERT_AUX_free                      1926	EXIST::FUNCTION:
        +d2i_ACCESS_DESCRIPTION                  1927	EXIST::FUNCTION:
        +X509_trust_clear                        1928	EXIST::FUNCTION:
        +X509_TRUST_add                          1931	EXIST::FUNCTION:
        +ASN1_VISIBLESTRING_new                  1932	EXIST::FUNCTION:
        +X509_alias_set1                         1933	EXIST::FUNCTION:
        +ASN1_PRINTABLESTRING_free               1934	EXIST::FUNCTION:
        +EVP_PKEY_get1_DSA                       1935	EXIST::FUNCTION:DSA
        +ASN1_BMPSTRING_new                      1936	EXIST::FUNCTION:
        +ASN1_mbstring_copy                      1937	EXIST::FUNCTION:
        +ASN1_UTF8STRING_new                     1938	EXIST::FUNCTION:
        +DSA_get_default_method                  1941	EXIST::FUNCTION:DSA
        +i2d_ASN1_SET_OF_ACCESS_DESCRIPTION      1945	NOEXIST::FUNCTION:
        +ASN1_T61STRING_free                     1946	EXIST::FUNCTION:
        +DSA_set_method                          1949	EXIST::FUNCTION:DSA
        +X509_get_ex_data                        1950	EXIST::FUNCTION:
        +ASN1_STRING_type                        1951	EXIST::FUNCTION:
        +X509_PURPOSE_get_by_sname               1952	EXIST::FUNCTION:
        +ASN1_TIME_free                          1954	EXIST::FUNCTION:
        +ASN1_OCTET_STRING_cmp                   1955	EXIST::FUNCTION:
        +ASN1_BIT_STRING_new                     1957	EXIST::FUNCTION:
        +X509_get_ext_d2i                        1958	EXIST::FUNCTION:
        +PEM_read_bio_X509_AUX                   1959	EXIST::FUNCTION:
        +ASN1_STRING_set_default_mask_asc        1960	EXIST:!VMS:FUNCTION:
        +ASN1_STRING_set_def_mask_asc            1960	EXIST:VMS:FUNCTION:
        +PEM_write_bio_RSA_PUBKEY                1961	EXIST::FUNCTION:RSA
        +ASN1_INTEGER_cmp                        1963	EXIST::FUNCTION:
        +d2i_RSA_PUBKEY_fp                       1964	EXIST::FUNCTION:FP_API,RSA
        +X509_trust_set_bit_asc                  1967	NOEXIST::FUNCTION:
        +PEM_write_bio_DSA_PUBKEY                1968	EXIST::FUNCTION:DSA
        +X509_STORE_CTX_free                     1969	EXIST::FUNCTION:
        +EVP_PKEY_set1_DSA                       1970	EXIST::FUNCTION:DSA
        +i2d_DSA_PUBKEY_fp                       1971	EXIST::FUNCTION:DSA,FP_API
        +X509_load_cert_crl_file                 1972	EXIST::FUNCTION:STDIO
        +ASN1_TIME_new                           1973	EXIST::FUNCTION:
        +i2d_RSA_PUBKEY                          1974	EXIST::FUNCTION:RSA
        +X509_STORE_CTX_purpose_inherit          1976	EXIST::FUNCTION:
        +PEM_read_RSA_PUBKEY                     1977	EXIST:!WIN16:FUNCTION:RSA
        +d2i_X509_AUX                            1980	EXIST::FUNCTION:
        +i2d_DSA_PUBKEY                          1981	EXIST::FUNCTION:DSA
        +X509_CERT_AUX_print                     1982	EXIST::FUNCTION:BIO
        +PEM_read_DSA_PUBKEY                     1984	EXIST:!WIN16:FUNCTION:DSA
        +i2d_RSA_PUBKEY_bio                      1985	EXIST::FUNCTION:BIO,RSA
        +ASN1_BIT_STRING_num_asc                 1986	EXIST::FUNCTION:
        +i2d_PUBKEY                              1987	EXIST::FUNCTION:
        +ASN1_UTCTIME_free                       1988	EXIST::FUNCTION:
        +DSA_set_default_method                  1989	EXIST::FUNCTION:DSA
        +X509_PURPOSE_get_by_id                  1990	EXIST::FUNCTION:
        +ACCESS_DESCRIPTION_free                 1994	EXIST::FUNCTION:
        +PEM_read_bio_PUBKEY                     1995	EXIST::FUNCTION:
        +ASN1_STRING_set_by_NID                  1996	EXIST::FUNCTION:
        +X509_PURPOSE_get_id                     1997	EXIST::FUNCTION:
        +DISPLAYTEXT_free                        1998	EXIST::FUNCTION:
        +OTHERNAME_new                           1999	EXIST::FUNCTION:
        +X509_CERT_AUX_new                       2001	EXIST::FUNCTION:
        +X509_TRUST_cleanup                      2007	EXIST::FUNCTION:
        +X509_NAME_add_entry_by_OBJ              2008	EXIST::FUNCTION:
        +X509_CRL_get_ext_d2i                    2009	EXIST::FUNCTION:
        +X509_PURPOSE_get0_name                  2011	EXIST::FUNCTION:
        +PEM_read_PUBKEY                         2012	EXIST:!WIN16:FUNCTION:
        +i2d_DSA_PUBKEY_bio                      2014	EXIST::FUNCTION:BIO,DSA
        +i2d_OTHERNAME                           2015	EXIST::FUNCTION:
        +ASN1_OCTET_STRING_free                  2016	EXIST::FUNCTION:
        +ASN1_BIT_STRING_set_asc                 2017	EXIST::FUNCTION:
        +X509_get_ex_new_index                   2019	EXIST::FUNCTION:
        +ASN1_STRING_TABLE_cleanup               2020	EXIST::FUNCTION:
        +X509_TRUST_get_by_id                    2021	EXIST::FUNCTION:
        +X509_PURPOSE_get_trust                  2022	EXIST::FUNCTION:
        +ASN1_STRING_length                      2023	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_ACCESS_DESCRIPTION      2024	NOEXIST::FUNCTION:
        +ASN1_PRINTABLESTRING_new                2025	EXIST::FUNCTION:
        +X509V3_get_d2i                          2026	EXIST::FUNCTION:
        +ASN1_ENUMERATED_free                    2027	EXIST::FUNCTION:
        +i2d_X509_CERT_AUX                       2028	EXIST::FUNCTION:
        +X509_STORE_CTX_set_trust                2030	EXIST::FUNCTION:
        +ASN1_STRING_set_default_mask            2032	EXIST::FUNCTION:
        +X509_STORE_CTX_new                      2033	EXIST::FUNCTION:
        +EVP_PKEY_get1_RSA                       2034	EXIST::FUNCTION:RSA
        +DIRECTORYSTRING_free                    2038	EXIST::FUNCTION:
        +PEM_write_X509_AUX                      2039	EXIST:!WIN16:FUNCTION:
        +ASN1_OCTET_STRING_set                   2040	EXIST::FUNCTION:
        +d2i_DSA_PUBKEY_fp                       2041	EXIST::FUNCTION:DSA,FP_API
        +d2i_RSA_PUBKEY                          2044	EXIST::FUNCTION:RSA
        +X509_TRUST_get0_name                    2046	EXIST::FUNCTION:
        +X509_TRUST_get0                         2047	EXIST::FUNCTION:
        +AUTHORITY_INFO_ACCESS_free              2048	EXIST::FUNCTION:
        +ASN1_IA5STRING_new                      2049	EXIST::FUNCTION:
        +d2i_DSA_PUBKEY                          2050	EXIST::FUNCTION:DSA
        +X509_check_purpose                      2051	EXIST::FUNCTION:
        +ASN1_ENUMERATED_new                     2052	EXIST::FUNCTION:
        +d2i_RSA_PUBKEY_bio                      2053	EXIST::FUNCTION:BIO,RSA
        +d2i_PUBKEY                              2054	EXIST::FUNCTION:
        +X509_TRUST_get_trust                    2055	EXIST::FUNCTION:
        +X509_TRUST_get_flags                    2056	EXIST::FUNCTION:
        +ASN1_BMPSTRING_free                     2057	EXIST::FUNCTION:
        +ASN1_T61STRING_new                      2058	EXIST::FUNCTION:
        +ASN1_UTCTIME_new                        2060	EXIST::FUNCTION:
        +i2d_AUTHORITY_INFO_ACCESS               2062	EXIST::FUNCTION:
        +EVP_PKEY_set1_RSA                       2063	EXIST::FUNCTION:RSA
        +X509_STORE_CTX_set_purpose              2064	EXIST::FUNCTION:
        +ASN1_IA5STRING_free                     2065	EXIST::FUNCTION:
        +PEM_write_bio_X509_AUX                  2066	EXIST::FUNCTION:
        +X509_PURPOSE_get_count                  2067	EXIST::FUNCTION:
        +CRYPTO_add_info                         2068	NOEXIST::FUNCTION:
        +X509_NAME_ENTRY_create_by_txt           2071	EXIST::FUNCTION:
        +ASN1_STRING_get_default_mask            2072	EXIST::FUNCTION:
        +X509_alias_get0                         2074	EXIST::FUNCTION:
        +ASN1_STRING_data                        2075	EXIST::FUNCTION:
        +i2d_ACCESS_DESCRIPTION                  2077	EXIST::FUNCTION:
        +X509_trust_set_bit                      2078	NOEXIST::FUNCTION:
        +ASN1_BIT_STRING_free                    2080	EXIST::FUNCTION:
        +PEM_read_bio_RSA_PUBKEY                 2081	EXIST::FUNCTION:RSA
        +X509_add1_reject_object                 2082	EXIST::FUNCTION:
        +X509_check_trust                        2083	EXIST::FUNCTION:
        +PEM_read_bio_DSA_PUBKEY                 2088	EXIST::FUNCTION:DSA
        +X509_PURPOSE_add                        2090	EXIST::FUNCTION:
        +ASN1_STRING_TABLE_get                   2091	EXIST::FUNCTION:
        +ASN1_UTF8STRING_free                    2092	EXIST::FUNCTION:
        +d2i_DSA_PUBKEY_bio                      2093	EXIST::FUNCTION:BIO,DSA
        +PEM_write_RSA_PUBKEY                    2095	EXIST:!WIN16:FUNCTION:RSA
        +d2i_OTHERNAME                           2096	EXIST::FUNCTION:
        +X509_reject_set_bit                     2098	NOEXIST::FUNCTION:
        +PEM_write_DSA_PUBKEY                    2101	EXIST:!WIN16:FUNCTION:DSA
        +X509_PURPOSE_get0_sname                 2105	EXIST::FUNCTION:
        +EVP_PKEY_set1_DH                        2107	EXIST::FUNCTION:DH
        +ASN1_OCTET_STRING_dup                   2108	EXIST::FUNCTION:
        +ASN1_BIT_STRING_set                     2109	EXIST::FUNCTION:
        +X509_TRUST_get_count                    2110	EXIST::FUNCTION:
        +ASN1_INTEGER_free                       2111	EXIST::FUNCTION:
        +OTHERNAME_free                          2112	EXIST::FUNCTION:
        +i2d_RSA_PUBKEY_fp                       2113	EXIST::FUNCTION:FP_API,RSA
        +ASN1_INTEGER_dup                        2114	EXIST::FUNCTION:
        +d2i_X509_CERT_AUX                       2115	EXIST::FUNCTION:
        +PEM_write_bio_PUBKEY                    2117	EXIST::FUNCTION:
        +ASN1_VISIBLESTRING_free                 2118	EXIST::FUNCTION:
        +X509_PURPOSE_cleanup                    2119	EXIST::FUNCTION:
        +ASN1_mbstring_ncopy                     2123	EXIST::FUNCTION:
        +ASN1_GENERALIZEDTIME_new                2126	EXIST::FUNCTION:
        +EVP_PKEY_get1_DH                        2128	EXIST::FUNCTION:DH
        +ASN1_OCTET_STRING_new                   2130	EXIST::FUNCTION:
        +ASN1_INTEGER_new                        2131	EXIST::FUNCTION:
        +i2d_X509_AUX                            2132	EXIST::FUNCTION:
        +ASN1_BIT_STRING_name_print              2134	EXIST::FUNCTION:BIO
        +X509_cmp                                2135	EXIST::FUNCTION:
        +ASN1_STRING_length_set                  2136	EXIST::FUNCTION:
        +DIRECTORYSTRING_new                     2137	EXIST::FUNCTION:
        +X509_add1_trust_object                  2140	EXIST::FUNCTION:
        +PKCS12_newpass                          2141	EXIST::FUNCTION:
        +SMIME_write_PKCS7                       2142	EXIST::FUNCTION:
        +SMIME_read_PKCS7                        2143	EXIST::FUNCTION:
        +DES_set_key_checked                     2144	EXIST::FUNCTION:DES
        +PKCS7_verify                            2145	EXIST::FUNCTION:
        +PKCS7_encrypt                           2146	EXIST::FUNCTION:
        +DES_set_key_unchecked                   2147	EXIST::FUNCTION:DES
        +SMIME_crlf_copy                         2148	EXIST::FUNCTION:
        +i2d_ASN1_PRINTABLESTRING                2149	EXIST::FUNCTION:
        +PKCS7_get0_signers                      2150	EXIST::FUNCTION:
        +PKCS7_decrypt                           2151	EXIST::FUNCTION:
        +SMIME_text                              2152	EXIST::FUNCTION:
        +PKCS7_simple_smimecap                   2153	EXIST::FUNCTION:
        +PKCS7_get_smimecap                      2154	EXIST::FUNCTION:
        +PKCS7_sign                              2155	EXIST::FUNCTION:
        +PKCS7_add_attrib_smimecap               2156	EXIST::FUNCTION:
        +CRYPTO_dbg_set_options                  2157	EXIST::FUNCTION:
        +CRYPTO_remove_all_info                  2158	EXIST::FUNCTION:
        +CRYPTO_get_mem_debug_functions          2159	EXIST::FUNCTION:
        +CRYPTO_is_mem_check_on                  2160	EXIST::FUNCTION:
        +CRYPTO_set_mem_debug_functions          2161	EXIST::FUNCTION:
        +CRYPTO_pop_info                         2162	EXIST::FUNCTION:
        +CRYPTO_push_info_                       2163	EXIST::FUNCTION:
        +CRYPTO_set_mem_debug_options            2164	EXIST::FUNCTION:
        +PEM_write_PKCS8PrivateKey_nid           2165	EXIST::FUNCTION:
        +PEM_write_bio_PKCS8PrivateKey_nid       2166	EXIST:!VMS:FUNCTION:
        +PEM_write_bio_PKCS8PrivKey_nid          2166	EXIST:VMS:FUNCTION:
        +d2i_PKCS8PrivateKey_bio                 2167	EXIST::FUNCTION:
        +ASN1_NULL_free                          2168	EXIST::FUNCTION:
        +d2i_ASN1_NULL                           2169	EXIST::FUNCTION:
        +ASN1_NULL_new                           2170	EXIST::FUNCTION:
        +i2d_PKCS8PrivateKey_bio                 2171	EXIST::FUNCTION:
        +i2d_PKCS8PrivateKey_fp                  2172	EXIST::FUNCTION:
        +i2d_ASN1_NULL                           2173	EXIST::FUNCTION:
        +i2d_PKCS8PrivateKey_nid_fp              2174	EXIST::FUNCTION:
        +d2i_PKCS8PrivateKey_fp                  2175	EXIST::FUNCTION:
        +i2d_PKCS8PrivateKey_nid_bio             2176	EXIST::FUNCTION:
        +i2d_PKCS8PrivateKeyInfo_fp              2177	EXIST::FUNCTION:FP_API
        +i2d_PKCS8PrivateKeyInfo_bio             2178	EXIST::FUNCTION:BIO
        +PEM_cb                                  2179	NOEXIST::FUNCTION:
        +i2d_PrivateKey_fp                       2180	EXIST::FUNCTION:FP_API
        +d2i_PrivateKey_bio                      2181	EXIST::FUNCTION:BIO
        +d2i_PrivateKey_fp                       2182	EXIST::FUNCTION:FP_API
        +i2d_PrivateKey_bio                      2183	EXIST::FUNCTION:BIO
        +X509_reject_clear                       2184	EXIST::FUNCTION:
        +X509_TRUST_set_default                  2185	EXIST::FUNCTION:
        +d2i_AutoPrivateKey                      2186	EXIST::FUNCTION:
        +X509_ATTRIBUTE_get0_type                2187	EXIST::FUNCTION:
        +X509_ATTRIBUTE_set1_data                2188	EXIST::FUNCTION:
        +X509at_get_attr                         2189	EXIST::FUNCTION:
        +X509at_get_attr_count                   2190	EXIST::FUNCTION:
        +X509_ATTRIBUTE_create_by_NID            2191	EXIST::FUNCTION:
        +X509_ATTRIBUTE_set1_object              2192	EXIST::FUNCTION:
        +X509_ATTRIBUTE_count                    2193	EXIST::FUNCTION:
        +X509_ATTRIBUTE_create_by_OBJ            2194	EXIST::FUNCTION:
        +X509_ATTRIBUTE_get0_object              2195	EXIST::FUNCTION:
        +X509at_get_attr_by_NID                  2196	EXIST::FUNCTION:
        +X509at_add1_attr                        2197	EXIST::FUNCTION:
        +X509_ATTRIBUTE_get0_data                2198	EXIST::FUNCTION:
        +X509at_delete_attr                      2199	EXIST::FUNCTION:
        +X509at_get_attr_by_OBJ                  2200	EXIST::FUNCTION:
        +RAND_add                                2201	EXIST::FUNCTION:
        +BIO_number_written                      2202	EXIST::FUNCTION:
        +BIO_number_read                         2203	EXIST::FUNCTION:
        +X509_STORE_CTX_get1_chain               2204	EXIST::FUNCTION:
        +ERR_load_RAND_strings                   2205	EXIST::FUNCTION:
        +RAND_pseudo_bytes                       2206	EXIST::FUNCTION:
        +X509_REQ_get_attr_by_NID                2207	EXIST::FUNCTION:
        +X509_REQ_get_attr                       2208	EXIST::FUNCTION:
        +X509_REQ_add1_attr_by_NID               2209	EXIST::FUNCTION:
        +X509_REQ_get_attr_by_OBJ                2210	EXIST::FUNCTION:
        +X509at_add1_attr_by_NID                 2211	EXIST::FUNCTION:
        +X509_REQ_add1_attr_by_OBJ               2212	EXIST::FUNCTION:
        +X509_REQ_get_attr_count                 2213	EXIST::FUNCTION:
        +X509_REQ_add1_attr                      2214	EXIST::FUNCTION:
        +X509_REQ_delete_attr                    2215	EXIST::FUNCTION:
        +X509at_add1_attr_by_OBJ                 2216	EXIST::FUNCTION:
        +X509_REQ_add1_attr_by_txt               2217	EXIST::FUNCTION:
        +X509_ATTRIBUTE_create_by_txt            2218	EXIST::FUNCTION:
        +X509at_add1_attr_by_txt                 2219	EXIST::FUNCTION:
        +BN_pseudo_rand                          2239	EXIST::FUNCTION:
        +BN_is_prime_fasttest                    2240	EXIST::FUNCTION:DEPRECATED
        +BN_CTX_end                              2241	EXIST::FUNCTION:
        +BN_CTX_start                            2242	EXIST::FUNCTION:
        +BN_CTX_get                              2243	EXIST::FUNCTION:
        +EVP_PKEY2PKCS8_broken                   2244	EXIST::FUNCTION:
        +ASN1_STRING_TABLE_add                   2245	EXIST::FUNCTION:
        +CRYPTO_dbg_get_options                  2246	EXIST::FUNCTION:
        +AUTHORITY_INFO_ACCESS_new               2247	EXIST::FUNCTION:
        +CRYPTO_get_mem_debug_options            2248	EXIST::FUNCTION:
        +DES_crypt                               2249	EXIST::FUNCTION:DES
        +PEM_write_bio_X509_REQ_NEW              2250	EXIST::FUNCTION:
        +PEM_write_X509_REQ_NEW                  2251	EXIST:!WIN16:FUNCTION:
        +BIO_callback_ctrl                       2252	EXIST::FUNCTION:
        +RAND_egd                                2253	EXIST::FUNCTION:
        +RAND_status                             2254	EXIST::FUNCTION:
        +bn_dump1                                2255	NOEXIST::FUNCTION:
        +DES_check_key_parity                    2256	EXIST::FUNCTION:DES
        +lh_num_items                            2257	EXIST::FUNCTION:
        +RAND_event                              2258	EXIST:WIN32:FUNCTION:
        +DSO_new                                 2259	EXIST::FUNCTION:
        +DSO_new_method                          2260	EXIST::FUNCTION:
        +DSO_free                                2261	EXIST::FUNCTION:
        +DSO_flags                               2262	EXIST::FUNCTION:
        +DSO_up                                  2263	NOEXIST::FUNCTION:
        +DSO_set_default_method                  2264	EXIST::FUNCTION:
        +DSO_get_default_method                  2265	EXIST::FUNCTION:
        +DSO_get_method                          2266	EXIST::FUNCTION:
        +DSO_set_method                          2267	EXIST::FUNCTION:
        +DSO_load                                2268	EXIST::FUNCTION:
        +DSO_bind_var                            2269	EXIST::FUNCTION:
        +DSO_METHOD_null                         2270	EXIST::FUNCTION:
        +DSO_METHOD_openssl                      2271	EXIST::FUNCTION:
        +DSO_METHOD_dlfcn                        2272	EXIST::FUNCTION:
        +DSO_METHOD_win32                        2273	EXIST::FUNCTION:
        +ERR_load_DSO_strings                    2274	EXIST::FUNCTION:
        +DSO_METHOD_dl                           2275	EXIST::FUNCTION:
        +NCONF_load                              2276	EXIST::FUNCTION:
        +NCONF_load_fp                           2278	EXIST::FUNCTION:FP_API
        +NCONF_new                               2279	EXIST::FUNCTION:
        +NCONF_get_string                        2280	EXIST::FUNCTION:
        +NCONF_free                              2281	EXIST::FUNCTION:
        +NCONF_get_number                        2282	NOEXIST::FUNCTION:
        +CONF_dump_fp                            2283	EXIST::FUNCTION:
        +NCONF_load_bio                          2284	EXIST::FUNCTION:
        +NCONF_dump_fp                           2285	EXIST::FUNCTION:
        +NCONF_get_section                       2286	EXIST::FUNCTION:
        +NCONF_dump_bio                          2287	EXIST::FUNCTION:
        +CONF_dump_bio                           2288	EXIST::FUNCTION:
        +NCONF_free_data                         2289	EXIST::FUNCTION:
        +CONF_set_default_method                 2290	EXIST::FUNCTION:
        +ERR_error_string_n                      2291	EXIST::FUNCTION:
        +BIO_snprintf                            2292	EXIST::FUNCTION:
        +DSO_ctrl                                2293	EXIST::FUNCTION:
        +i2d_ASN1_SET_OF_ASN1_INTEGER            2317	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_PKCS12_SAFEBAG          2320	NOEXIST::FUNCTION:
        +i2d_ASN1_SET_OF_PKCS7                   2328	NOEXIST::FUNCTION:
        +BIO_vfree                               2334	EXIST::FUNCTION:
        +d2i_ASN1_SET_OF_ASN1_INTEGER            2339	NOEXIST::FUNCTION:
        +d2i_ASN1_SET_OF_PKCS12_SAFEBAG          2341	NOEXIST::FUNCTION:
        +ASN1_UTCTIME_get                        2350	NOEXIST::FUNCTION:
        +X509_REQ_digest                         2362	EXIST::FUNCTION:EVP
        +X509_CRL_digest                         2391	EXIST::FUNCTION:EVP
        +d2i_ASN1_SET_OF_PKCS7                   2397	NOEXIST::FUNCTION:
        +EVP_CIPHER_CTX_set_key_length           2399	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_ctrl                     2400	EXIST::FUNCTION:
        +BN_mod_exp_mont_word                    2401	EXIST::FUNCTION:
        +RAND_egd_bytes                          2402	EXIST::FUNCTION:
        +X509_REQ_get1_email                     2403	EXIST::FUNCTION:
        +X509_get1_email                         2404	EXIST::FUNCTION:
        +X509_email_free                         2405	EXIST::FUNCTION:
        +i2d_RSA_NET                             2406	EXIST::FUNCTION:RC4,RSA
        +d2i_RSA_NET_2                           2407	NOEXIST::FUNCTION:
        +d2i_RSA_NET                             2408	EXIST::FUNCTION:RC4,RSA
        +DSO_bind_func                           2409	EXIST::FUNCTION:
        +CRYPTO_get_new_dynlockid                2410	EXIST::FUNCTION:
        +sk_new_null                             2411	EXIST::FUNCTION:
        +CRYPTO_set_dynlock_destroy_callback     2412	EXIST:!VMS:FUNCTION:
        +CRYPTO_set_dynlock_destroy_cb           2412	EXIST:VMS:FUNCTION:
        +CRYPTO_destroy_dynlockid                2413	EXIST::FUNCTION:
        +CRYPTO_set_dynlock_size                 2414	NOEXIST::FUNCTION:
        +CRYPTO_set_dynlock_create_callback      2415	EXIST:!VMS:FUNCTION:
        +CRYPTO_set_dynlock_create_cb            2415	EXIST:VMS:FUNCTION:
        +CRYPTO_set_dynlock_lock_callback        2416	EXIST:!VMS:FUNCTION:
        +CRYPTO_set_dynlock_lock_cb              2416	EXIST:VMS:FUNCTION:
        +CRYPTO_get_dynlock_lock_callback        2417	EXIST:!VMS:FUNCTION:
        +CRYPTO_get_dynlock_lock_cb              2417	EXIST:VMS:FUNCTION:
        +CRYPTO_get_dynlock_destroy_callback     2418	EXIST:!VMS:FUNCTION:
        +CRYPTO_get_dynlock_destroy_cb           2418	EXIST:VMS:FUNCTION:
        +CRYPTO_get_dynlock_value                2419	EXIST::FUNCTION:
        +CRYPTO_get_dynlock_create_callback      2420	EXIST:!VMS:FUNCTION:
        +CRYPTO_get_dynlock_create_cb            2420	EXIST:VMS:FUNCTION:
        +c2i_ASN1_BIT_STRING                     2421	EXIST::FUNCTION:
        +i2c_ASN1_BIT_STRING                     2422	EXIST::FUNCTION:
        +RAND_poll                               2423	EXIST::FUNCTION:
        +c2i_ASN1_INTEGER                        2424	EXIST::FUNCTION:
        +i2c_ASN1_INTEGER                        2425	EXIST::FUNCTION:
        +BIO_dump_indent                         2426	EXIST::FUNCTION:
        +ASN1_parse_dump                         2427	EXIST::FUNCTION:BIO
        +c2i_ASN1_OBJECT                         2428	EXIST::FUNCTION:
        +X509_NAME_print_ex_fp                   2429	EXIST::FUNCTION:FP_API
        +ASN1_STRING_print_ex_fp                 2430	EXIST::FUNCTION:FP_API
        +X509_NAME_print_ex                      2431	EXIST::FUNCTION:BIO
        +ASN1_STRING_print_ex                    2432	EXIST::FUNCTION:BIO
        +MD4                                     2433	EXIST::FUNCTION:MD4
        +MD4_Transform                           2434	EXIST::FUNCTION:MD4
        +MD4_Final                               2435	EXIST::FUNCTION:MD4
        +MD4_Update                              2436	EXIST::FUNCTION:MD4
        +MD4_Init                                2437	EXIST::FUNCTION:MD4
        +EVP_md4                                 2438	EXIST::FUNCTION:MD4
        +i2d_PUBKEY_bio                          2439	EXIST::FUNCTION:BIO
        +i2d_PUBKEY_fp                           2440	EXIST::FUNCTION:FP_API
        +d2i_PUBKEY_bio                          2441	EXIST::FUNCTION:BIO
        +ASN1_STRING_to_UTF8                     2442	EXIST::FUNCTION:
        +BIO_vprintf                             2443	EXIST::FUNCTION:
        +BIO_vsnprintf                           2444	EXIST::FUNCTION:
        +d2i_PUBKEY_fp                           2445	EXIST::FUNCTION:FP_API
        +X509_cmp_time                           2446	EXIST::FUNCTION:
        +X509_STORE_CTX_set_time                 2447	EXIST::FUNCTION:
        +X509_STORE_CTX_get1_issuer              2448	EXIST::FUNCTION:
        +X509_OBJECT_retrieve_match              2449	EXIST::FUNCTION:
        +X509_OBJECT_idx_by_subject              2450	EXIST::FUNCTION:
        +X509_STORE_CTX_set_flags                2451	EXIST::FUNCTION:
        +X509_STORE_CTX_trusted_stack            2452	EXIST::FUNCTION:
        +X509_time_adj                           2453	EXIST::FUNCTION:
        +X509_check_issued                       2454	EXIST::FUNCTION:
        +ASN1_UTCTIME_cmp_time_t                 2455	EXIST::FUNCTION:
        +DES_set_weak_key_flag                   2456	NOEXIST::FUNCTION:
        +DES_check_key                           2457	NOEXIST::FUNCTION:
        +DES_rw_mode                             2458	NOEXIST::FUNCTION:
        +RSA_PKCS1_RSAref                        2459	NOEXIST::FUNCTION:
        +X509_keyid_set1                         2460	EXIST::FUNCTION:
        +BIO_next                                2461	EXIST::FUNCTION:
        +DSO_METHOD_vms                          2462	EXIST::FUNCTION:
        +BIO_f_linebuffer                        2463	EXIST:VMS:FUNCTION:
        +BN_bntest_rand                          2464	EXIST::FUNCTION:
        +OPENSSL_issetugid                       2465	EXIST::FUNCTION:
        +BN_rand_range                           2466	EXIST::FUNCTION:
        +ERR_load_ENGINE_strings                 2467	EXIST::FUNCTION:ENGINE
        +ENGINE_set_DSA                          2468	EXIST::FUNCTION:ENGINE
        +ENGINE_get_finish_function              2469	EXIST::FUNCTION:ENGINE
        +ENGINE_get_default_RSA                  2470	EXIST::FUNCTION:ENGINE
        +ENGINE_get_BN_mod_exp                   2471	NOEXIST::FUNCTION:
        +DSA_get_default_openssl_method          2472	NOEXIST::FUNCTION:
        +ENGINE_set_DH                           2473	EXIST::FUNCTION:ENGINE
        +ENGINE_set_def_BN_mod_exp_crt           2474	NOEXIST::FUNCTION:
        +ENGINE_set_default_BN_mod_exp_crt       2474	NOEXIST::FUNCTION:
        +ENGINE_init                             2475	EXIST::FUNCTION:ENGINE
        +DH_get_default_openssl_method           2476	NOEXIST::FUNCTION:
        +RSA_set_default_openssl_method          2477	NOEXIST::FUNCTION:
        +ENGINE_finish                           2478	EXIST::FUNCTION:ENGINE
        +ENGINE_load_public_key                  2479	EXIST::FUNCTION:ENGINE
        +ENGINE_get_DH                           2480	EXIST::FUNCTION:ENGINE
        +ENGINE_ctrl                             2481	EXIST::FUNCTION:ENGINE
        +ENGINE_get_init_function                2482	EXIST::FUNCTION:ENGINE
        +ENGINE_set_init_function                2483	EXIST::FUNCTION:ENGINE
        +ENGINE_set_default_DSA                  2484	EXIST::FUNCTION:ENGINE
        +ENGINE_get_name                         2485	EXIST::FUNCTION:ENGINE
        +ENGINE_get_last                         2486	EXIST::FUNCTION:ENGINE
        +ENGINE_get_prev                         2487	EXIST::FUNCTION:ENGINE
        +ENGINE_get_default_DH                   2488	EXIST::FUNCTION:ENGINE
        +ENGINE_get_RSA                          2489	EXIST::FUNCTION:ENGINE
        +ENGINE_set_default                      2490	EXIST::FUNCTION:ENGINE
        +ENGINE_get_RAND                         2491	EXIST::FUNCTION:ENGINE
        +ENGINE_get_first                        2492	EXIST::FUNCTION:ENGINE
        +ENGINE_by_id                            2493	EXIST::FUNCTION:ENGINE
        +ENGINE_set_finish_function              2494	EXIST::FUNCTION:ENGINE
        +ENGINE_get_def_BN_mod_exp_crt           2495	NOEXIST::FUNCTION:
        +ENGINE_get_default_BN_mod_exp_crt       2495	NOEXIST::FUNCTION:
        +RSA_get_default_openssl_method          2496	NOEXIST::FUNCTION:
        +ENGINE_set_RSA                          2497	EXIST::FUNCTION:ENGINE
        +ENGINE_load_private_key                 2498	EXIST::FUNCTION:ENGINE
        +ENGINE_set_default_RAND                 2499	EXIST::FUNCTION:ENGINE
        +ENGINE_set_BN_mod_exp                   2500	NOEXIST::FUNCTION:
        +ENGINE_remove                           2501	EXIST::FUNCTION:ENGINE
        +ENGINE_free                             2502	EXIST::FUNCTION:ENGINE
        +ENGINE_get_BN_mod_exp_crt               2503	NOEXIST::FUNCTION:
        +ENGINE_get_next                         2504	EXIST::FUNCTION:ENGINE
        +ENGINE_set_name                         2505	EXIST::FUNCTION:ENGINE
        +ENGINE_get_default_DSA                  2506	EXIST::FUNCTION:ENGINE
        +ENGINE_set_default_BN_mod_exp           2507	NOEXIST::FUNCTION:
        +ENGINE_set_default_RSA                  2508	EXIST::FUNCTION:ENGINE
        +ENGINE_get_default_RAND                 2509	EXIST::FUNCTION:ENGINE
        +ENGINE_get_default_BN_mod_exp           2510	NOEXIST::FUNCTION:
        +ENGINE_set_RAND                         2511	EXIST::FUNCTION:ENGINE
        +ENGINE_set_id                           2512	EXIST::FUNCTION:ENGINE
        +ENGINE_set_BN_mod_exp_crt               2513	NOEXIST::FUNCTION:
        +ENGINE_set_default_DH                   2514	EXIST::FUNCTION:ENGINE
        +ENGINE_new                              2515	EXIST::FUNCTION:ENGINE
        +ENGINE_get_id                           2516	EXIST::FUNCTION:ENGINE
        +DSA_set_default_openssl_method          2517	NOEXIST::FUNCTION:
        +ENGINE_add                              2518	EXIST::FUNCTION:ENGINE
        +DH_set_default_openssl_method           2519	NOEXIST::FUNCTION:
        +ENGINE_get_DSA                          2520	EXIST::FUNCTION:ENGINE
        +ENGINE_get_ctrl_function                2521	EXIST::FUNCTION:ENGINE
        +ENGINE_set_ctrl_function                2522	EXIST::FUNCTION:ENGINE
        +BN_pseudo_rand_range                    2523	EXIST::FUNCTION:
        +X509_STORE_CTX_set_verify_cb            2524	EXIST::FUNCTION:
        +ERR_load_COMP_strings                   2525	EXIST::FUNCTION:
        +PKCS12_item_decrypt_d2i                 2526	EXIST::FUNCTION:
        +ASN1_UTF8STRING_it                      2527	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_UTF8STRING_it                      2527	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_unregister_ciphers               2528	EXIST::FUNCTION:ENGINE
        +ENGINE_get_ciphers                      2529	EXIST::FUNCTION:ENGINE
        +d2i_OCSP_BASICRESP                      2530	EXIST::FUNCTION:
        +KRB5_CHECKSUM_it                        2531	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_CHECKSUM_it                        2531	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_POINT_add                            2532	EXIST::FUNCTION:EC
        +ASN1_item_ex_i2d                        2533	EXIST::FUNCTION:
        +OCSP_CERTID_it                          2534	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_CERTID_it                          2534	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_OCSP_RESPBYTES                      2535	EXIST::FUNCTION:
        +X509V3_add1_i2d                         2536	EXIST::FUNCTION:
        +PKCS7_ENVELOPE_it                       2537	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_ENVELOPE_it                       2537	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_add_input_boolean                    2538	EXIST::FUNCTION:
        +ENGINE_unregister_RSA                   2539	EXIST::FUNCTION:ENGINE
        +X509V3_EXT_nconf                        2540	EXIST::FUNCTION:
        +ASN1_GENERALSTRING_free                 2541	EXIST::FUNCTION:
        +d2i_OCSP_CERTSTATUS                     2542	EXIST::FUNCTION:
        +X509_REVOKED_set_serialNumber           2543	EXIST::FUNCTION:
        +X509_print_ex                           2544	EXIST::FUNCTION:BIO
        +OCSP_ONEREQ_get1_ext_d2i                2545	EXIST::FUNCTION:
        +ENGINE_register_all_RAND                2546	EXIST::FUNCTION:ENGINE
        +ENGINE_load_dynamic                     2547	EXIST::FUNCTION:ENGINE
        +PBKDF2PARAM_it                          2548	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PBKDF2PARAM_it                          2548	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EXTENDED_KEY_USAGE_new                  2549	EXIST::FUNCTION:
        +EC_GROUP_clear_free                     2550	EXIST::FUNCTION:EC
        +OCSP_sendreq_bio                        2551	EXIST::FUNCTION:
        +ASN1_item_digest                        2552	EXIST::FUNCTION:EVP
        +OCSP_BASICRESP_delete_ext               2553	EXIST::FUNCTION:
        +OCSP_SIGNATURE_it                       2554	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_SIGNATURE_it                       2554	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_CRL_it                             2555	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_CRL_it                             2555	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_BASICRESP_add_ext                  2556	EXIST::FUNCTION:
        +KRB5_ENCKEY_it                          2557	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_ENCKEY_it                          2557	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_method_set_closer                    2558	EXIST::FUNCTION:
        +X509_STORE_set_purpose                  2559	EXIST::FUNCTION:
        +i2d_ASN1_GENERALSTRING                  2560	EXIST::FUNCTION:
        +OCSP_response_status                    2561	EXIST::FUNCTION:
        +i2d_OCSP_SERVICELOC                     2562	EXIST::FUNCTION:
        +ENGINE_get_digest_engine                2563	EXIST::FUNCTION:ENGINE
        +EC_GROUP_set_curve_GFp                  2564	EXIST::FUNCTION:EC
        +OCSP_REQUEST_get_ext_by_OBJ             2565	EXIST::FUNCTION:
        +_ossl_old_des_random_key                2566	EXIST::FUNCTION:DES
        +ASN1_T61STRING_it                       2567	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_T61STRING_it                       2567	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_GROUP_method_of                      2568	EXIST::FUNCTION:EC
        +i2d_KRB5_APREQ                          2569	EXIST::FUNCTION:
        +_ossl_old_des_encrypt                   2570	EXIST::FUNCTION:DES
        +ASN1_PRINTABLE_new                      2571	EXIST::FUNCTION:
        +HMAC_Init_ex                            2572	EXIST::FUNCTION:HMAC
        +d2i_KRB5_AUTHENT                        2573	EXIST::FUNCTION:
        +OCSP_archive_cutoff_new                 2574	EXIST::FUNCTION:
        +EC_POINT_set_Jprojective_coordinates_GFp 2575	EXIST:!VMS:FUNCTION:EC
        +EC_POINT_set_Jproj_coords_GFp           2575	EXIST:VMS:FUNCTION:EC
        +_ossl_old_des_is_weak_key               2576	EXIST::FUNCTION:DES
        +OCSP_BASICRESP_get_ext_by_OBJ           2577	EXIST::FUNCTION:
        +EC_POINT_oct2point                      2578	EXIST::FUNCTION:EC
        +OCSP_SINGLERESP_get_ext_count           2579	EXIST::FUNCTION:
        +UI_ctrl                                 2580	EXIST::FUNCTION:
        +_shadow_DES_rw_mode                     2581	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:DES
        +_shadow_DES_rw_mode                     2581	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:DES
        +asn1_do_adb                             2582	EXIST::FUNCTION:
        +ASN1_template_i2d                       2583	EXIST::FUNCTION:
        +ENGINE_register_DH                      2584	EXIST::FUNCTION:ENGINE
        +UI_construct_prompt                     2585	EXIST::FUNCTION:
        +X509_STORE_set_trust                    2586	EXIST::FUNCTION:
        +UI_dup_input_string                     2587	EXIST::FUNCTION:
        +d2i_KRB5_APREQ                          2588	EXIST::FUNCTION:
        +EVP_MD_CTX_copy_ex                      2589	EXIST::FUNCTION:
        +OCSP_request_is_signed                  2590	EXIST::FUNCTION:
        +i2d_OCSP_REQINFO                        2591	EXIST::FUNCTION:
        +KRB5_ENCKEY_free                        2592	EXIST::FUNCTION:
        +OCSP_resp_get0                          2593	EXIST::FUNCTION:
        +GENERAL_NAME_it                         2594	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +GENERAL_NAME_it                         2594	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_GENERALIZEDTIME_it                 2595	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_GENERALIZEDTIME_it                 2595	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_STORE_set_flags                    2596	EXIST::FUNCTION:
        +EC_POINT_set_compressed_coordinates_GFp 2597	EXIST:!VMS:FUNCTION:EC
        +EC_POINT_set_compr_coords_GFp           2597	EXIST:VMS:FUNCTION:EC
        +OCSP_response_status_str                2598	EXIST::FUNCTION:
        +d2i_OCSP_REVOKEDINFO                    2599	EXIST::FUNCTION:
        +OCSP_basic_add1_cert                    2600	EXIST::FUNCTION:
        +ERR_get_implementation                  2601	EXIST::FUNCTION:
        +EVP_CipherFinal_ex                      2602	EXIST::FUNCTION:
        +OCSP_CERTSTATUS_new                     2603	EXIST::FUNCTION:
        +CRYPTO_cleanup_all_ex_data              2604	EXIST::FUNCTION:
        +OCSP_resp_find                          2605	EXIST::FUNCTION:
        +BN_nnmod                                2606	EXIST::FUNCTION:
        +X509_CRL_sort                           2607	EXIST::FUNCTION:
        +X509_REVOKED_set_revocationDate         2608	EXIST::FUNCTION:
        +ENGINE_register_RAND                    2609	EXIST::FUNCTION:ENGINE
        +OCSP_SERVICELOC_new                     2610	EXIST::FUNCTION:
        +EC_POINT_set_affine_coordinates_GFp     2611	EXIST:!VMS:FUNCTION:EC
        +EC_POINT_set_affine_coords_GFp          2611	EXIST:VMS:FUNCTION:EC
        +_ossl_old_des_options                   2612	EXIST::FUNCTION:DES
        +SXNET_it                                2613	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +SXNET_it                                2613	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_dup_input_boolean                    2614	EXIST::FUNCTION:
        +PKCS12_add_CSPName_asc                  2615	EXIST::FUNCTION:
        +EC_POINT_is_at_infinity                 2616	EXIST::FUNCTION:EC
        +ENGINE_load_cryptodev                   2617	EXIST::FUNCTION:ENGINE
        +DSO_convert_filename                    2618	EXIST::FUNCTION:
        +POLICYQUALINFO_it                       2619	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +POLICYQUALINFO_it                       2619	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_register_ciphers                 2620	EXIST::FUNCTION:ENGINE
        +BN_mod_lshift_quick                     2621	EXIST::FUNCTION:
        +DSO_set_filename                        2622	EXIST::FUNCTION:
        +ASN1_item_free                          2623	EXIST::FUNCTION:
        +KRB5_TKTBODY_free                       2624	EXIST::FUNCTION:
        +AUTHORITY_KEYID_it                      2625	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +AUTHORITY_KEYID_it                      2625	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +KRB5_APREQBODY_new                      2626	EXIST::FUNCTION:
        +X509V3_EXT_REQ_add_nconf                2627	EXIST::FUNCTION:
        +ENGINE_ctrl_cmd_string                  2628	EXIST::FUNCTION:ENGINE
        +i2d_OCSP_RESPDATA                       2629	EXIST::FUNCTION:
        +EVP_MD_CTX_init                         2630	EXIST::FUNCTION:
        +EXTENDED_KEY_USAGE_free                 2631	EXIST::FUNCTION:
        +PKCS7_ATTR_SIGN_it                      2632	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_ATTR_SIGN_it                      2632	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_add_error_string                     2633	EXIST::FUNCTION:
        +KRB5_CHECKSUM_free                      2634	EXIST::FUNCTION:
        +OCSP_REQUEST_get_ext                    2635	EXIST::FUNCTION:
        +ENGINE_load_ubsec                       2636	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +ENGINE_register_all_digests             2637	EXIST::FUNCTION:ENGINE
        +PKEY_USAGE_PERIOD_it                    2638	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKEY_USAGE_PERIOD_it                    2638	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PKCS12_unpack_authsafes                 2639	EXIST::FUNCTION:
        +ASN1_item_unpack                        2640	EXIST::FUNCTION:
        +NETSCAPE_SPKAC_it                       2641	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +NETSCAPE_SPKAC_it                       2641	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_REVOKED_it                         2642	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_REVOKED_it                         2642	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_STRING_encode                      2643	NOEXIST::FUNCTION:
        +EVP_aes_128_ecb                         2644	EXIST::FUNCTION:AES
        +KRB5_AUTHENT_free                       2645	EXIST::FUNCTION:
        +OCSP_BASICRESP_get_ext_by_critical      2646	EXIST:!VMS:FUNCTION:
        +OCSP_BASICRESP_get_ext_by_crit          2646	EXIST:VMS:FUNCTION:
        +OCSP_cert_status_str                    2647	EXIST::FUNCTION:
        +d2i_OCSP_REQUEST                        2648	EXIST::FUNCTION:
        +UI_dup_info_string                      2649	EXIST::FUNCTION:
        +_ossl_old_des_xwhite_in2out             2650	NOEXIST::FUNCTION:
        +PKCS12_it                               2651	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS12_it                               2651	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_SINGLERESP_get_ext_by_critical     2652	EXIST:!VMS:FUNCTION:
        +OCSP_SINGLERESP_get_ext_by_crit         2652	EXIST:VMS:FUNCTION:
        +OCSP_CERTSTATUS_free                    2653	EXIST::FUNCTION:
        +_ossl_old_des_crypt                     2654	EXIST::FUNCTION:DES
        +ASN1_item_i2d                           2655	EXIST::FUNCTION:
        +EVP_DecryptFinal_ex                     2656	EXIST::FUNCTION:
        +ENGINE_load_openssl                     2657	EXIST::FUNCTION:ENGINE
        +ENGINE_get_cmd_defns                    2658	EXIST::FUNCTION:ENGINE
        +ENGINE_set_load_privkey_function        2659	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_set_load_privkey_fn              2659	EXIST:VMS:FUNCTION:ENGINE
        +EVP_EncryptFinal_ex                     2660	EXIST::FUNCTION:
        +ENGINE_set_default_digests              2661	EXIST::FUNCTION:ENGINE
        +X509_get0_pubkey_bitstr                 2662	EXIST::FUNCTION:
        +asn1_ex_i2c                             2663	EXIST::FUNCTION:
        +ENGINE_register_RSA                     2664	EXIST::FUNCTION:ENGINE
        +ENGINE_unregister_DSA                   2665	EXIST::FUNCTION:ENGINE
        +_ossl_old_des_key_sched                 2666	EXIST::FUNCTION:DES
        +X509_EXTENSION_it                       2667	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_EXTENSION_it                       2667	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +i2d_KRB5_AUTHENT                        2668	EXIST::FUNCTION:
        +SXNETID_it                              2669	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +SXNETID_it                              2669	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_OCSP_SINGLERESP                     2670	EXIST::FUNCTION:
        +EDIPARTYNAME_new                        2671	EXIST::FUNCTION:
        +PKCS12_certbag2x509                     2672	EXIST::FUNCTION:
        +_ossl_old_des_ofb64_encrypt             2673	EXIST::FUNCTION:DES
        +d2i_EXTENDED_KEY_USAGE                  2674	EXIST::FUNCTION:
        +ERR_print_errors_cb                     2675	EXIST::FUNCTION:
        +ENGINE_set_ciphers                      2676	EXIST::FUNCTION:ENGINE
        +d2i_KRB5_APREQBODY                      2677	EXIST::FUNCTION:
        +UI_method_get_flusher                   2678	EXIST::FUNCTION:
        +X509_PUBKEY_it                          2679	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_PUBKEY_it                          2679	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +_ossl_old_des_enc_read                  2680	EXIST::FUNCTION:DES
        +PKCS7_ENCRYPT_it                        2681	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_ENCRYPT_it                        2681	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +i2d_OCSP_RESPONSE                       2682	EXIST::FUNCTION:
        +EC_GROUP_get_cofactor                   2683	EXIST::FUNCTION:EC
        +PKCS12_unpack_p7data                    2684	EXIST::FUNCTION:
        +d2i_KRB5_AUTHDATA                       2685	EXIST::FUNCTION:
        +OCSP_copy_nonce                         2686	EXIST::FUNCTION:
        +KRB5_AUTHDATA_new                       2687	EXIST::FUNCTION:
        +OCSP_RESPDATA_new                       2688	EXIST::FUNCTION:
        +EC_GFp_mont_method                      2689	EXIST::FUNCTION:EC
        +OCSP_REVOKEDINFO_free                   2690	EXIST::FUNCTION:
        +UI_get_ex_data                          2691	EXIST::FUNCTION:
        +KRB5_APREQBODY_free                     2692	EXIST::FUNCTION:
        +EC_GROUP_get0_generator                 2693	EXIST::FUNCTION:EC
        +UI_get_default_method                   2694	EXIST::FUNCTION:
        +X509V3_set_nconf                        2695	EXIST::FUNCTION:
        +PKCS12_item_i2d_encrypt                 2696	EXIST::FUNCTION:
        +X509_add1_ext_i2d                       2697	EXIST::FUNCTION:
        +PKCS7_SIGNER_INFO_it                    2698	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_SIGNER_INFO_it                    2698	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +KRB5_PRINCNAME_new                      2699	EXIST::FUNCTION:
        +PKCS12_SAFEBAG_it                       2700	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS12_SAFEBAG_it                       2700	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_GROUP_get_order                      2701	EXIST::FUNCTION:EC
        +d2i_OCSP_RESPID                         2702	EXIST::FUNCTION:
        +OCSP_request_verify                     2703	EXIST::FUNCTION:
        +NCONF_get_number_e                      2704	EXIST::FUNCTION:
        +_ossl_old_des_decrypt3                  2705	EXIST::FUNCTION:DES
        +X509_signature_print                    2706	EXIST::FUNCTION:EVP
        +OCSP_SINGLERESP_free                    2707	EXIST::FUNCTION:
        +ENGINE_load_builtin_engines             2708	EXIST::FUNCTION:ENGINE
        +i2d_OCSP_ONEREQ                         2709	EXIST::FUNCTION:
        +OCSP_REQUEST_add_ext                    2710	EXIST::FUNCTION:
        +OCSP_RESPBYTES_new                      2711	EXIST::FUNCTION:
        +EVP_MD_CTX_create                       2712	EXIST::FUNCTION:
        +OCSP_resp_find_status                   2713	EXIST::FUNCTION:
        +X509_ALGOR_it                           2714	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_ALGOR_it                           2714	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_TIME_it                            2715	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_TIME_it                            2715	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_request_set1_name                  2716	EXIST::FUNCTION:
        +OCSP_ONEREQ_get_ext_count               2717	EXIST::FUNCTION:
        +UI_get0_result                          2718	EXIST::FUNCTION:
        +PKCS12_AUTHSAFES_it                     2719	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS12_AUTHSAFES_it                     2719	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_aes_256_ecb                         2720	EXIST::FUNCTION:AES
        +PKCS12_pack_authsafes                   2721	EXIST::FUNCTION:
        +ASN1_IA5STRING_it                       2722	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_IA5STRING_it                       2722	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_get_input_flags                      2723	EXIST::FUNCTION:
        +EC_GROUP_set_generator                  2724	EXIST::FUNCTION:EC
        +_ossl_old_des_string_to_2keys           2725	EXIST::FUNCTION:DES
        +OCSP_CERTID_free                        2726	EXIST::FUNCTION:
        +X509_CERT_AUX_it                        2727	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_CERT_AUX_it                        2727	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +CERTIFICATEPOLICIES_it                  2728	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +CERTIFICATEPOLICIES_it                  2728	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +_ossl_old_des_ede3_cbc_encrypt          2729	EXIST::FUNCTION:DES
        +RAND_set_rand_engine                    2730	EXIST::FUNCTION:ENGINE
        +DSO_get_loaded_filename                 2731	EXIST::FUNCTION:
        +X509_ATTRIBUTE_it                       2732	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_ATTRIBUTE_it                       2732	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_ONEREQ_get_ext_by_NID              2733	EXIST::FUNCTION:
        +PKCS12_decrypt_skey                     2734	EXIST::FUNCTION:
        +KRB5_AUTHENT_it                         2735	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_AUTHENT_it                         2735	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_dup_error_string                     2736	EXIST::FUNCTION:
        +RSAPublicKey_it                         2737	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA
        +RSAPublicKey_it                         2737	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RSA
        +i2d_OCSP_REQUEST                        2738	EXIST::FUNCTION:
        +PKCS12_x509crl2certbag                  2739	EXIST::FUNCTION:
        +OCSP_SERVICELOC_it                      2740	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_SERVICELOC_it                      2740	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_item_sign                          2741	EXIST::FUNCTION:EVP
        +X509_CRL_set_issuer_name                2742	EXIST::FUNCTION:
        +OBJ_NAME_do_all_sorted                  2743	EXIST::FUNCTION:
        +i2d_OCSP_BASICRESP                      2744	EXIST::FUNCTION:
        +i2d_OCSP_RESPBYTES                      2745	EXIST::FUNCTION:
        +PKCS12_unpack_p7encdata                 2746	EXIST::FUNCTION:
        +HMAC_CTX_init                           2747	EXIST::FUNCTION:HMAC
        +ENGINE_get_digest                       2748	EXIST::FUNCTION:ENGINE
        +OCSP_RESPONSE_print                     2749	EXIST::FUNCTION:
        +KRB5_TKTBODY_it                         2750	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_TKTBODY_it                         2750	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ACCESS_DESCRIPTION_it                   2751	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ACCESS_DESCRIPTION_it                   2751	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PKCS7_ISSUER_AND_SERIAL_it              2752	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_ISSUER_AND_SERIAL_it              2752	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PBE2PARAM_it                            2753	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PBE2PARAM_it                            2753	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PKCS12_certbag2x509crl                  2754	EXIST::FUNCTION:
        +PKCS7_SIGNED_it                         2755	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_SIGNED_it                         2755	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_get_cipher                       2756	EXIST::FUNCTION:ENGINE
        +i2d_OCSP_CRLID                          2757	EXIST::FUNCTION:
        +OCSP_SINGLERESP_new                     2758	EXIST::FUNCTION:
        +ENGINE_cmd_is_executable                2759	EXIST::FUNCTION:ENGINE
        +RSA_up_ref                              2760	EXIST::FUNCTION:RSA
        +ASN1_GENERALSTRING_it                   2761	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_GENERALSTRING_it                   2761	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_register_DSA                     2762	EXIST::FUNCTION:ENGINE
        +X509V3_EXT_add_nconf_sk                 2763	EXIST::FUNCTION:
        +ENGINE_set_load_pubkey_function         2764	EXIST::FUNCTION:ENGINE
        +PKCS8_decrypt                           2765	EXIST::FUNCTION:
        +PEM_bytes_read_bio                      2766	EXIST::FUNCTION:BIO
        +DIRECTORYSTRING_it                      2767	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +DIRECTORYSTRING_it                      2767	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_OCSP_CRLID                          2768	EXIST::FUNCTION:
        +EC_POINT_is_on_curve                    2769	EXIST::FUNCTION:EC
        +CRYPTO_set_locked_mem_ex_functions      2770	EXIST:!VMS:FUNCTION:
        +CRYPTO_set_locked_mem_ex_funcs          2770	EXIST:VMS:FUNCTION:
        +d2i_KRB5_CHECKSUM                       2771	EXIST::FUNCTION:
        +ASN1_item_dup                           2772	EXIST::FUNCTION:
        +X509_it                                 2773	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_it                                 2773	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +BN_mod_add                              2774	EXIST::FUNCTION:
        +KRB5_AUTHDATA_free                      2775	EXIST::FUNCTION:
        +_ossl_old_des_cbc_cksum                 2776	EXIST::FUNCTION:DES
        +ASN1_item_verify                        2777	EXIST::FUNCTION:EVP
        +CRYPTO_set_mem_ex_functions             2778	EXIST::FUNCTION:
        +EC_POINT_get_Jprojective_coordinates_GFp 2779	EXIST:!VMS:FUNCTION:EC
        +EC_POINT_get_Jproj_coords_GFp           2779	EXIST:VMS:FUNCTION:EC
        +ZLONG_it                                2780	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ZLONG_it                                2780	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +CRYPTO_get_locked_mem_ex_functions      2781	EXIST:!VMS:FUNCTION:
        +CRYPTO_get_locked_mem_ex_funcs          2781	EXIST:VMS:FUNCTION:
        +ASN1_TIME_check                         2782	EXIST::FUNCTION:
        +UI_get0_user_data                       2783	EXIST::FUNCTION:
        +HMAC_CTX_cleanup                        2784	EXIST::FUNCTION:HMAC
        +DSA_up_ref                              2785	EXIST::FUNCTION:DSA
        +_ossl_old_des_ede3_cfb64_encrypt        2786	EXIST:!VMS:FUNCTION:DES
        +_ossl_odes_ede3_cfb64_encrypt           2786	EXIST:VMS:FUNCTION:DES
        +ASN1_BMPSTRING_it                       2787	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_BMPSTRING_it                       2787	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_tag2bit                            2788	EXIST::FUNCTION:
        +UI_method_set_flusher                   2789	EXIST::FUNCTION:
        +X509_ocspid_print                       2790	EXIST::FUNCTION:BIO
        +KRB5_ENCDATA_it                         2791	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_ENCDATA_it                         2791	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_get_load_pubkey_function         2792	EXIST::FUNCTION:ENGINE
        +UI_add_user_data                        2793	EXIST::FUNCTION:
        +OCSP_REQUEST_delete_ext                 2794	EXIST::FUNCTION:
        +UI_get_method                           2795	EXIST::FUNCTION:
        +OCSP_ONEREQ_free                        2796	EXIST::FUNCTION:
        +ASN1_PRINTABLESTRING_it                 2797	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_PRINTABLESTRING_it                 2797	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_CRL_set_nextUpdate                 2798	EXIST::FUNCTION:
        +OCSP_REQUEST_it                         2799	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_REQUEST_it                         2799	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_BASICRESP_it                       2800	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_BASICRESP_it                       2800	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +AES_ecb_encrypt                         2801	EXIST::FUNCTION:AES
        +BN_mod_sqr                              2802	EXIST::FUNCTION:
        +NETSCAPE_CERT_SEQUENCE_it               2803	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +NETSCAPE_CERT_SEQUENCE_it               2803	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +GENERAL_NAMES_it                        2804	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +GENERAL_NAMES_it                        2804	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +AUTHORITY_INFO_ACCESS_it                2805	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +AUTHORITY_INFO_ACCESS_it                2805	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_FBOOLEAN_it                        2806	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_FBOOLEAN_it                        2806	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_set_ex_data                          2807	EXIST::FUNCTION:
        +_ossl_old_des_string_to_key             2808	EXIST::FUNCTION:DES
        +ENGINE_register_all_RSA                 2809	EXIST::FUNCTION:ENGINE
        +d2i_KRB5_PRINCNAME                      2810	EXIST::FUNCTION:
        +OCSP_RESPBYTES_it                       2811	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_RESPBYTES_it                       2811	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_CINF_it                            2812	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_CINF_it                            2812	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_unregister_digests               2813	EXIST::FUNCTION:ENGINE
        +d2i_EDIPARTYNAME                        2814	EXIST::FUNCTION:
        +d2i_OCSP_SERVICELOC                     2815	EXIST::FUNCTION:
        +ENGINE_get_digests                      2816	EXIST::FUNCTION:ENGINE
        +_ossl_old_des_set_odd_parity            2817	EXIST::FUNCTION:DES
        +OCSP_RESPDATA_free                      2818	EXIST::FUNCTION:
        +d2i_KRB5_TICKET                         2819	EXIST::FUNCTION:
        +OTHERNAME_it                            2820	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OTHERNAME_it                            2820	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_MD_CTX_cleanup                      2821	EXIST::FUNCTION:
        +d2i_ASN1_GENERALSTRING                  2822	EXIST::FUNCTION:
        +X509_CRL_set_version                    2823	EXIST::FUNCTION:
        +BN_mod_sub                              2824	EXIST::FUNCTION:
        +OCSP_SINGLERESP_get_ext_by_NID          2825	EXIST::FUNCTION:
        +ENGINE_get_ex_new_index                 2826	EXIST::FUNCTION:ENGINE
        +OCSP_REQUEST_free                       2827	EXIST::FUNCTION:
        +OCSP_REQUEST_add1_ext_i2d               2828	EXIST::FUNCTION:
        +X509_VAL_it                             2829	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_VAL_it                             2829	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_POINTs_make_affine                   2830	EXIST::FUNCTION:EC
        +EC_POINT_mul                            2831	EXIST::FUNCTION:EC
        +X509V3_EXT_add_nconf                    2832	EXIST::FUNCTION:
        +X509_TRUST_set                          2833	EXIST::FUNCTION:
        +X509_CRL_add1_ext_i2d                   2834	EXIST::FUNCTION:
        +_ossl_old_des_fcrypt                    2835	EXIST::FUNCTION:DES
        +DISPLAYTEXT_it                          2836	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +DISPLAYTEXT_it                          2836	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_CRL_set_lastUpdate                 2837	EXIST::FUNCTION:
        +OCSP_BASICRESP_free                     2838	EXIST::FUNCTION:
        +OCSP_BASICRESP_add1_ext_i2d             2839	EXIST::FUNCTION:
        +d2i_KRB5_AUTHENTBODY                    2840	EXIST::FUNCTION:
        +CRYPTO_set_ex_data_implementation       2841	EXIST:!VMS:FUNCTION:
        +CRYPTO_set_ex_data_impl                 2841	EXIST:VMS:FUNCTION:
        +KRB5_ENCDATA_new                        2842	EXIST::FUNCTION:
        +DSO_up_ref                              2843	EXIST::FUNCTION:
        +OCSP_crl_reason_str                     2844	EXIST::FUNCTION:
        +UI_get0_result_string                   2845	EXIST::FUNCTION:
        +ASN1_GENERALSTRING_new                  2846	EXIST::FUNCTION:
        +X509_SIG_it                             2847	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_SIG_it                             2847	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ERR_set_implementation                  2848	EXIST::FUNCTION:
        +ERR_load_EC_strings                     2849	EXIST::FUNCTION:EC
        +UI_get0_action_string                   2850	EXIST::FUNCTION:
        +OCSP_ONEREQ_get_ext                     2851	EXIST::FUNCTION:
        +EC_POINT_method_of                      2852	EXIST::FUNCTION:EC
        +i2d_KRB5_APREQBODY                      2853	EXIST::FUNCTION:
        +_ossl_old_des_ecb3_encrypt              2854	EXIST::FUNCTION:DES
        +CRYPTO_get_mem_ex_functions             2855	EXIST::FUNCTION:
        +ENGINE_get_ex_data                      2856	EXIST::FUNCTION:ENGINE
        +UI_destroy_method                       2857	EXIST::FUNCTION:
        +ASN1_item_i2d_bio                       2858	EXIST::FUNCTION:BIO
        +OCSP_ONEREQ_get_ext_by_OBJ              2859	EXIST::FUNCTION:
        +ASN1_primitive_new                      2860	EXIST::FUNCTION:
        +ASN1_PRINTABLE_it                       2861	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_PRINTABLE_it                       2861	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_aes_192_ecb                         2862	EXIST::FUNCTION:AES
        +OCSP_SIGNATURE_new                      2863	EXIST::FUNCTION:
        +LONG_it                                 2864	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +LONG_it                                 2864	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_VISIBLESTRING_it                   2865	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_VISIBLESTRING_it                   2865	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_SINGLERESP_add1_ext_i2d            2866	EXIST::FUNCTION:
        +d2i_OCSP_CERTID                         2867	EXIST::FUNCTION:
        +ASN1_item_d2i_fp                        2868	EXIST::FUNCTION:FP_API
        +CRL_DIST_POINTS_it                      2869	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +CRL_DIST_POINTS_it                      2869	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +GENERAL_NAME_print                      2870	EXIST::FUNCTION:
        +OCSP_SINGLERESP_delete_ext              2871	EXIST::FUNCTION:
        +PKCS12_SAFEBAGS_it                      2872	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS12_SAFEBAGS_it                      2872	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_OCSP_SIGNATURE                      2873	EXIST::FUNCTION:
        +OCSP_request_add1_nonce                 2874	EXIST::FUNCTION:
        +ENGINE_set_cmd_defns                    2875	EXIST::FUNCTION:ENGINE
        +OCSP_SERVICELOC_free                    2876	EXIST::FUNCTION:
        +EC_GROUP_free                           2877	EXIST::FUNCTION:EC
        +ASN1_BIT_STRING_it                      2878	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_BIT_STRING_it                      2878	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_REQ_it                             2879	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_REQ_it                             2879	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +_ossl_old_des_cbc_encrypt               2880	EXIST::FUNCTION:DES
        +ERR_unload_strings                      2881	EXIST::FUNCTION:
        +PKCS7_SIGN_ENVELOPE_it                  2882	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_SIGN_ENVELOPE_it                  2882	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EDIPARTYNAME_free                       2883	EXIST::FUNCTION:
        +OCSP_REQINFO_free                       2884	EXIST::FUNCTION:
        +EC_GROUP_new_curve_GFp                  2885	EXIST::FUNCTION:EC
        +OCSP_REQUEST_get1_ext_d2i               2886	EXIST::FUNCTION:
        +PKCS12_item_pack_safebag                2887	EXIST::FUNCTION:
        +asn1_ex_c2i                             2888	EXIST::FUNCTION:
        +ENGINE_register_digests                 2889	EXIST::FUNCTION:ENGINE
        +i2d_OCSP_REVOKEDINFO                    2890	EXIST::FUNCTION:
        +asn1_enc_restore                        2891	EXIST::FUNCTION:
        +UI_free                                 2892	EXIST::FUNCTION:
        +UI_new_method                           2893	EXIST::FUNCTION:
        +EVP_EncryptInit_ex                      2894	EXIST::FUNCTION:
        +X509_pubkey_digest                      2895	EXIST::FUNCTION:EVP
        +EC_POINT_invert                         2896	EXIST::FUNCTION:EC
        +OCSP_basic_sign                         2897	EXIST::FUNCTION:
        +i2d_OCSP_RESPID                         2898	EXIST::FUNCTION:
        +OCSP_check_nonce                        2899	EXIST::FUNCTION:
        +ENGINE_ctrl_cmd                         2900	EXIST::FUNCTION:ENGINE
        +d2i_KRB5_ENCKEY                         2901	EXIST::FUNCTION:
        +OCSP_parse_url                          2902	EXIST::FUNCTION:
        +OCSP_SINGLERESP_get_ext                 2903	EXIST::FUNCTION:
        +OCSP_CRLID_free                         2904	EXIST::FUNCTION:
        +OCSP_BASICRESP_get1_ext_d2i             2905	EXIST::FUNCTION:
        +RSAPrivateKey_it                        2906	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA
        +RSAPrivateKey_it                        2906	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RSA
        +ENGINE_register_all_DH                  2907	EXIST::FUNCTION:ENGINE
        +i2d_EDIPARTYNAME                        2908	EXIST::FUNCTION:
        +EC_POINT_get_affine_coordinates_GFp     2909	EXIST:!VMS:FUNCTION:EC
        +EC_POINT_get_affine_coords_GFp          2909	EXIST:VMS:FUNCTION:EC
        +OCSP_CRLID_new                          2910	EXIST::FUNCTION:
        +ENGINE_get_flags                        2911	EXIST::FUNCTION:ENGINE
        +OCSP_ONEREQ_it                          2912	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_ONEREQ_it                          2912	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_process                              2913	EXIST::FUNCTION:
        +ASN1_INTEGER_it                         2914	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_INTEGER_it                         2914	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_CipherInit_ex                       2915	EXIST::FUNCTION:
        +UI_get_string_type                      2916	EXIST::FUNCTION:
        +ENGINE_unregister_DH                    2917	EXIST::FUNCTION:ENGINE
        +ENGINE_register_all_DSA                 2918	EXIST::FUNCTION:ENGINE
        +OCSP_ONEREQ_get_ext_by_critical         2919	EXIST::FUNCTION:
        +bn_dup_expand                           2920	EXIST::FUNCTION:DEPRECATED
        +OCSP_cert_id_new                        2921	EXIST::FUNCTION:
        +BASIC_CONSTRAINTS_it                    2922	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +BASIC_CONSTRAINTS_it                    2922	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +BN_mod_add_quick                        2923	EXIST::FUNCTION:
        +EC_POINT_new                            2924	EXIST::FUNCTION:EC
        +EVP_MD_CTX_destroy                      2925	EXIST::FUNCTION:
        +OCSP_RESPBYTES_free                     2926	EXIST::FUNCTION:
        +EVP_aes_128_cbc                         2927	EXIST::FUNCTION:AES
        +OCSP_SINGLERESP_get1_ext_d2i            2928	EXIST::FUNCTION:
        +EC_POINT_free                           2929	EXIST::FUNCTION:EC
        +DH_up_ref                               2930	EXIST::FUNCTION:DH
        +X509_NAME_ENTRY_it                      2931	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_NAME_ENTRY_it                      2931	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_get_ex_new_index                     2932	EXIST::FUNCTION:
        +BN_mod_sub_quick                        2933	EXIST::FUNCTION:
        +OCSP_ONEREQ_add_ext                     2934	EXIST::FUNCTION:
        +OCSP_request_sign                       2935	EXIST::FUNCTION:
        +EVP_DigestFinal_ex                      2936	EXIST::FUNCTION:
        +ENGINE_set_digests                      2937	EXIST::FUNCTION:ENGINE
        +OCSP_id_issuer_cmp                      2938	EXIST::FUNCTION:
        +OBJ_NAME_do_all                         2939	EXIST::FUNCTION:
        +EC_POINTs_mul                           2940	EXIST::FUNCTION:EC
        +ENGINE_register_complete                2941	EXIST::FUNCTION:ENGINE
        +X509V3_EXT_nconf_nid                    2942	EXIST::FUNCTION:
        +ASN1_SEQUENCE_it                        2943	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_SEQUENCE_it                        2943	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_set_default_method                   2944	EXIST::FUNCTION:
        +RAND_query_egd_bytes                    2945	EXIST::FUNCTION:
        +UI_method_get_writer                    2946	EXIST::FUNCTION:
        +UI_OpenSSL                              2947	EXIST::FUNCTION:
        +PEM_def_callback                        2948	EXIST::FUNCTION:
        +ENGINE_cleanup                          2949	EXIST::FUNCTION:ENGINE
        +DIST_POINT_it                           2950	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +DIST_POINT_it                           2950	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_SINGLERESP_it                      2951	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_SINGLERESP_it                      2951	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_KRB5_TKTBODY                        2952	EXIST::FUNCTION:
        +EC_POINT_cmp                            2953	EXIST::FUNCTION:EC
        +OCSP_REVOKEDINFO_new                    2954	EXIST::FUNCTION:
        +i2d_OCSP_CERTSTATUS                     2955	EXIST::FUNCTION:
        +OCSP_basic_add1_nonce                   2956	EXIST::FUNCTION:
        +ASN1_item_ex_d2i                        2957	EXIST::FUNCTION:
        +BN_mod_lshift1_quick                    2958	EXIST::FUNCTION:
        +UI_set_method                           2959	EXIST::FUNCTION:
        +OCSP_id_get0_info                       2960	EXIST::FUNCTION:
        +BN_mod_sqrt                             2961	EXIST::FUNCTION:
        +EC_GROUP_copy                           2962	EXIST::FUNCTION:EC
        +KRB5_ENCDATA_free                       2963	EXIST::FUNCTION:
        +_ossl_old_des_cfb_encrypt               2964	EXIST::FUNCTION:DES
        +OCSP_SINGLERESP_get_ext_by_OBJ          2965	EXIST::FUNCTION:
        +OCSP_cert_to_id                         2966	EXIST::FUNCTION:
        +OCSP_RESPID_new                         2967	EXIST::FUNCTION:
        +OCSP_RESPDATA_it                        2968	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_RESPDATA_it                        2968	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_OCSP_RESPDATA                       2969	EXIST::FUNCTION:
        +ENGINE_register_all_complete            2970	EXIST::FUNCTION:ENGINE
        +OCSP_check_validity                     2971	EXIST::FUNCTION:
        +PKCS12_BAGS_it                          2972	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS12_BAGS_it                          2972	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_url_svcloc_new                     2973	EXIST::FUNCTION:
        +ASN1_template_free                      2974	EXIST::FUNCTION:
        +OCSP_SINGLERESP_add_ext                 2975	EXIST::FUNCTION:
        +KRB5_AUTHENTBODY_it                     2976	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_AUTHENTBODY_it                     2976	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_supported_extension                2977	EXIST::FUNCTION:
        +i2d_KRB5_AUTHDATA                       2978	EXIST::FUNCTION:
        +UI_method_get_opener                    2979	EXIST::FUNCTION:
        +ENGINE_set_ex_data                      2980	EXIST::FUNCTION:ENGINE
        +OCSP_REQUEST_print                      2981	EXIST::FUNCTION:
        +CBIGNUM_it                              2982	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +CBIGNUM_it                              2982	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +KRB5_TICKET_new                         2983	EXIST::FUNCTION:
        +KRB5_APREQ_new                          2984	EXIST::FUNCTION:
        +EC_GROUP_get_curve_GFp                  2985	EXIST::FUNCTION:EC
        +KRB5_ENCKEY_new                         2986	EXIST::FUNCTION:
        +ASN1_template_d2i                       2987	EXIST::FUNCTION:
        +_ossl_old_des_quad_cksum                2988	EXIST::FUNCTION:DES
        +OCSP_single_get0_status                 2989	EXIST::FUNCTION:
        +BN_swap                                 2990	EXIST::FUNCTION:
        +POLICYINFO_it                           2991	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +POLICYINFO_it                           2991	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_set_destroy_function             2992	EXIST::FUNCTION:ENGINE
        +asn1_enc_free                           2993	EXIST::FUNCTION:
        +OCSP_RESPID_it                          2994	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_RESPID_it                          2994	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_GROUP_new                            2995	EXIST::FUNCTION:EC
        +EVP_aes_256_cbc                         2996	EXIST::FUNCTION:AES
        +i2d_KRB5_PRINCNAME                      2997	EXIST::FUNCTION:
        +_ossl_old_des_encrypt2                  2998	EXIST::FUNCTION:DES
        +_ossl_old_des_encrypt3                  2999	EXIST::FUNCTION:DES
        +PKCS8_PRIV_KEY_INFO_it                  3000	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS8_PRIV_KEY_INFO_it                  3000	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_REQINFO_it                         3001	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_REQINFO_it                         3001	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PBEPARAM_it                             3002	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PBEPARAM_it                             3002	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +KRB5_AUTHENTBODY_new                    3003	EXIST::FUNCTION:
        +X509_CRL_add0_revoked                   3004	EXIST::FUNCTION:
        +EDIPARTYNAME_it                         3005	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +EDIPARTYNAME_it                         3005	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +NETSCAPE_SPKI_it                        3006	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +NETSCAPE_SPKI_it                        3006	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_get0_test_string                     3007	EXIST::FUNCTION:
        +ENGINE_get_cipher_engine                3008	EXIST::FUNCTION:ENGINE
        +ENGINE_register_all_ciphers             3009	EXIST::FUNCTION:ENGINE
        +EC_POINT_copy                           3010	EXIST::FUNCTION:EC
        +BN_kronecker                            3011	EXIST::FUNCTION:
        +_ossl_old_des_ede3_ofb64_encrypt        3012	EXIST:!VMS:FUNCTION:DES
        +_ossl_odes_ede3_ofb64_encrypt           3012	EXIST:VMS:FUNCTION:DES
        +UI_method_get_reader                    3013	EXIST::FUNCTION:
        +OCSP_BASICRESP_get_ext_count            3014	EXIST::FUNCTION:
        +ASN1_ENUMERATED_it                      3015	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_ENUMERATED_it                      3015	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_set_result                           3016	EXIST::FUNCTION:
        +i2d_KRB5_TICKET                         3017	EXIST::FUNCTION:
        +X509_print_ex_fp                        3018	EXIST::FUNCTION:FP_API
        +EVP_CIPHER_CTX_set_padding              3019	EXIST::FUNCTION:
        +d2i_OCSP_RESPONSE                       3020	EXIST::FUNCTION:
        +ASN1_UTCTIME_it                         3021	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_UTCTIME_it                         3021	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +_ossl_old_des_enc_write                 3022	EXIST::FUNCTION:DES
        +OCSP_RESPONSE_new                       3023	EXIST::FUNCTION:
        +AES_set_encrypt_key                     3024	EXIST::FUNCTION:AES
        +OCSP_resp_count                         3025	EXIST::FUNCTION:
        +KRB5_CHECKSUM_new                       3026	EXIST::FUNCTION:
        +ENGINE_load_cswift                      3027	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +OCSP_onereq_get0_id                     3028	EXIST::FUNCTION:
        +ENGINE_set_default_ciphers              3029	EXIST::FUNCTION:ENGINE
        +NOTICEREF_it                            3030	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +NOTICEREF_it                            3030	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509V3_EXT_CRL_add_nconf                3031	EXIST::FUNCTION:
        +OCSP_REVOKEDINFO_it                     3032	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_REVOKEDINFO_it                     3032	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +AES_encrypt                             3033	EXIST::FUNCTION:AES
        +OCSP_REQUEST_new                        3034	EXIST::FUNCTION:
        +ASN1_ANY_it                             3035	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_ANY_it                             3035	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +CRYPTO_ex_data_new_class                3036	EXIST::FUNCTION:
        +_ossl_old_des_ncbc_encrypt              3037	EXIST::FUNCTION:DES
        +i2d_KRB5_TKTBODY                        3038	EXIST::FUNCTION:
        +EC_POINT_clear_free                     3039	EXIST::FUNCTION:EC
        +AES_decrypt                             3040	EXIST::FUNCTION:AES
        +asn1_enc_init                           3041	EXIST::FUNCTION:
        +UI_get_result_maxsize                   3042	EXIST::FUNCTION:
        +OCSP_CERTID_new                         3043	EXIST::FUNCTION:
        +ENGINE_unregister_RAND                  3044	EXIST::FUNCTION:ENGINE
        +UI_method_get_closer                    3045	EXIST::FUNCTION:
        +d2i_KRB5_ENCDATA                        3046	EXIST::FUNCTION:
        +OCSP_request_onereq_count               3047	EXIST::FUNCTION:
        +OCSP_basic_verify                       3048	EXIST::FUNCTION:
        +KRB5_AUTHENTBODY_free                   3049	EXIST::FUNCTION:
        +ASN1_item_d2i                           3050	EXIST::FUNCTION:
        +ASN1_primitive_free                     3051	EXIST::FUNCTION:
        +i2d_EXTENDED_KEY_USAGE                  3052	EXIST::FUNCTION:
        +i2d_OCSP_SIGNATURE                      3053	EXIST::FUNCTION:
        +asn1_enc_save                           3054	EXIST::FUNCTION:
        +ENGINE_load_nuron                       3055	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +_ossl_old_des_pcbc_encrypt              3056	EXIST::FUNCTION:DES
        +PKCS12_MAC_DATA_it                      3057	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS12_MAC_DATA_it                      3057	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_accept_responses_new               3058	EXIST::FUNCTION:
        +asn1_do_lock                            3059	EXIST::FUNCTION:
        +PKCS7_ATTR_VERIFY_it                    3060	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_ATTR_VERIFY_it                    3060	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +KRB5_APREQBODY_it                       3061	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_APREQBODY_it                       3061	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +i2d_OCSP_SINGLERESP                     3062	EXIST::FUNCTION:
        +ASN1_item_ex_new                        3063	EXIST::FUNCTION:
        +UI_add_verify_string                    3064	EXIST::FUNCTION:
        +_ossl_old_des_set_key                   3065	EXIST::FUNCTION:DES
        +KRB5_PRINCNAME_it                       3066	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_PRINCNAME_it                       3066	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_DecryptInit_ex                      3067	EXIST::FUNCTION:
        +i2d_OCSP_CERTID                         3068	EXIST::FUNCTION:
        +ASN1_item_d2i_bio                       3069	EXIST::FUNCTION:BIO
        +EC_POINT_dbl                            3070	EXIST::FUNCTION:EC
        +asn1_get_choice_selector                3071	EXIST::FUNCTION:
        +i2d_KRB5_CHECKSUM                       3072	EXIST::FUNCTION:
        +ENGINE_set_table_flags                  3073	EXIST::FUNCTION:ENGINE
        +AES_options                             3074	EXIST::FUNCTION:AES
        +ENGINE_load_chil                        3075	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +OCSP_id_cmp                             3076	EXIST::FUNCTION:
        +OCSP_BASICRESP_new                      3077	EXIST::FUNCTION:
        +OCSP_REQUEST_get_ext_by_NID             3078	EXIST::FUNCTION:
        +KRB5_APREQ_it                           3079	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_APREQ_it                           3079	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_get_destroy_function             3080	EXIST::FUNCTION:ENGINE
        +CONF_set_nconf                          3081	EXIST::FUNCTION:
        +ASN1_PRINTABLE_free                     3082	EXIST::FUNCTION:
        +OCSP_BASICRESP_get_ext_by_NID           3083	EXIST::FUNCTION:
        +DIST_POINT_NAME_it                      3084	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +DIST_POINT_NAME_it                      3084	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509V3_extensions_print                 3085	EXIST::FUNCTION:
        +_ossl_old_des_cfb64_encrypt             3086	EXIST::FUNCTION:DES
        +X509_REVOKED_add1_ext_i2d               3087	EXIST::FUNCTION:
        +_ossl_old_des_ofb_encrypt               3088	EXIST::FUNCTION:DES
        +KRB5_TKTBODY_new                        3089	EXIST::FUNCTION:
        +ASN1_OCTET_STRING_it                    3090	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_OCTET_STRING_it                    3090	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ERR_load_UI_strings                     3091	EXIST::FUNCTION:
        +i2d_KRB5_ENCKEY                         3092	EXIST::FUNCTION:
        +ASN1_template_new                       3093	EXIST::FUNCTION:
        +OCSP_SIGNATURE_free                     3094	EXIST::FUNCTION:
        +ASN1_item_i2d_fp                        3095	EXIST::FUNCTION:FP_API
        +KRB5_PRINCNAME_free                     3096	EXIST::FUNCTION:
        +PKCS7_RECIP_INFO_it                     3097	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_RECIP_INFO_it                     3097	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EXTENDED_KEY_USAGE_it                   3098	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +EXTENDED_KEY_USAGE_it                   3098	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_GFp_simple_method                    3099	EXIST::FUNCTION:EC
        +EC_GROUP_precompute_mult                3100	EXIST::FUNCTION:EC
        +OCSP_request_onereq_get0                3101	EXIST::FUNCTION:
        +UI_method_set_writer                    3102	EXIST::FUNCTION:
        +KRB5_AUTHENT_new                        3103	EXIST::FUNCTION:
        +X509_CRL_INFO_it                        3104	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_CRL_INFO_it                        3104	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +DSO_set_name_converter                  3105	EXIST::FUNCTION:
        +AES_set_decrypt_key                     3106	EXIST::FUNCTION:AES
        +PKCS7_DIGEST_it                         3107	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_DIGEST_it                         3107	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PKCS12_x5092certbag                     3108	EXIST::FUNCTION:
        +EVP_DigestInit_ex                       3109	EXIST::FUNCTION:
        +i2a_ACCESS_DESCRIPTION                  3110	EXIST::FUNCTION:
        +OCSP_RESPONSE_it                        3111	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_RESPONSE_it                        3111	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PKCS7_ENC_CONTENT_it                    3112	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_ENC_CONTENT_it                    3112	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_request_add0_id                    3113	EXIST::FUNCTION:
        +EC_POINT_make_affine                    3114	EXIST::FUNCTION:EC
        +DSO_get_filename                        3115	EXIST::FUNCTION:
        +OCSP_CERTSTATUS_it                      3116	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_CERTSTATUS_it                      3116	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_request_add1_cert                  3117	EXIST::FUNCTION:
        +UI_get0_output_string                   3118	EXIST::FUNCTION:
        +UI_dup_verify_string                    3119	EXIST::FUNCTION:
        +BN_mod_lshift                           3120	EXIST::FUNCTION:
        +KRB5_AUTHDATA_it                        3121	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_AUTHDATA_it                        3121	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +asn1_set_choice_selector                3122	EXIST::FUNCTION:
        +OCSP_basic_add1_status                  3123	EXIST::FUNCTION:
        +OCSP_RESPID_free                        3124	EXIST::FUNCTION:
        +asn1_get_field_ptr                      3125	EXIST::FUNCTION:
        +UI_add_input_string                     3126	EXIST::FUNCTION:
        +OCSP_CRLID_it                           3127	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +OCSP_CRLID_it                           3127	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +i2d_KRB5_AUTHENTBODY                    3128	EXIST::FUNCTION:
        +OCSP_REQUEST_get_ext_count              3129	EXIST::FUNCTION:
        +ENGINE_load_atalla                      3130	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +X509_NAME_it                            3131	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_NAME_it                            3131	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +USERNOTICE_it                           3132	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +USERNOTICE_it                           3132	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_REQINFO_new                        3133	EXIST::FUNCTION:
        +OCSP_BASICRESP_get_ext                  3134	EXIST::FUNCTION:
        +CRYPTO_get_ex_data_implementation       3135	EXIST:!VMS:FUNCTION:
        +CRYPTO_get_ex_data_impl                 3135	EXIST:VMS:FUNCTION:
        +ASN1_item_pack                          3136	EXIST::FUNCTION:
        +i2d_KRB5_ENCDATA                        3137	EXIST::FUNCTION:
        +X509_PURPOSE_set                        3138	EXIST::FUNCTION:
        +X509_REQ_INFO_it                        3139	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_REQ_INFO_it                        3139	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +UI_method_set_opener                    3140	EXIST::FUNCTION:
        +ASN1_item_ex_free                       3141	EXIST::FUNCTION:
        +ASN1_BOOLEAN_it                         3142	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_BOOLEAN_it                         3142	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ENGINE_get_table_flags                  3143	EXIST::FUNCTION:ENGINE
        +UI_create_method                        3144	EXIST::FUNCTION:
        +OCSP_ONEREQ_add1_ext_i2d                3145	EXIST::FUNCTION:
        +_shadow_DES_check_key                   3146	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:DES
        +_shadow_DES_check_key                   3146	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:DES
        +d2i_OCSP_REQINFO                        3147	EXIST::FUNCTION:
        +UI_add_info_string                      3148	EXIST::FUNCTION:
        +UI_get_result_minsize                   3149	EXIST::FUNCTION:
        +ASN1_NULL_it                            3150	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_NULL_it                            3150	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +BN_mod_lshift1                          3151	EXIST::FUNCTION:
        +d2i_OCSP_ONEREQ                         3152	EXIST::FUNCTION:
        +OCSP_ONEREQ_new                         3153	EXIST::FUNCTION:
        +KRB5_TICKET_it                          3154	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +KRB5_TICKET_it                          3154	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_aes_192_cbc                         3155	EXIST::FUNCTION:AES
        +KRB5_TICKET_free                        3156	EXIST::FUNCTION:
        +UI_new                                  3157	EXIST::FUNCTION:
        +OCSP_response_create                    3158	EXIST::FUNCTION:
        +_ossl_old_des_xcbc_encrypt              3159	EXIST::FUNCTION:DES
        +PKCS7_it                                3160	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PKCS7_it                                3160	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_REQUEST_get_ext_by_critical        3161	EXIST:!VMS:FUNCTION:
        +OCSP_REQUEST_get_ext_by_crit            3161	EXIST:VMS:FUNCTION:
        +ENGINE_set_flags                        3162	EXIST::FUNCTION:ENGINE
        +_ossl_old_des_ecb_encrypt               3163	EXIST::FUNCTION:DES
        +OCSP_response_get1_basic                3164	EXIST::FUNCTION:
        +EVP_Digest                              3165	EXIST::FUNCTION:
        +OCSP_ONEREQ_delete_ext                  3166	EXIST::FUNCTION:
        +ASN1_TBOOLEAN_it                        3167	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_TBOOLEAN_it                        3167	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ASN1_item_new                           3168	EXIST::FUNCTION:
        +ASN1_TIME_to_generalizedtime            3169	EXIST::FUNCTION:
        +BIGNUM_it                               3170	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +BIGNUM_it                               3170	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +AES_cbc_encrypt                         3171	EXIST::FUNCTION:AES
        +ENGINE_get_load_privkey_function        3172	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_get_load_privkey_fn              3172	EXIST:VMS:FUNCTION:ENGINE
        +OCSP_RESPONSE_free                      3173	EXIST::FUNCTION:
        +UI_method_set_reader                    3174	EXIST::FUNCTION:
        +i2d_ASN1_T61STRING                      3175	EXIST::FUNCTION:
        +EC_POINT_set_to_infinity                3176	EXIST::FUNCTION:EC
        +ERR_load_OCSP_strings                   3177	EXIST::FUNCTION:
        +EC_POINT_point2oct                      3178	EXIST::FUNCTION:EC
        +KRB5_APREQ_free                         3179	EXIST::FUNCTION:
        +ASN1_OBJECT_it                          3180	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_OBJECT_it                          3180	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +OCSP_crlID_new                          3181	EXIST:!OS2,!VMS:FUNCTION:
        +OCSP_crlID2_new                         3181	EXIST:OS2,VMS:FUNCTION:
        +CONF_modules_load_file                  3182	EXIST::FUNCTION:
        +CONF_imodule_set_usr_data               3183	EXIST::FUNCTION:
        +ENGINE_set_default_string               3184	EXIST::FUNCTION:ENGINE
        +CONF_module_get_usr_data                3185	EXIST::FUNCTION:
        +ASN1_add_oid_module                     3186	EXIST::FUNCTION:
        +CONF_modules_finish                     3187	EXIST::FUNCTION:
        +OPENSSL_config                          3188	EXIST::FUNCTION:
        +CONF_modules_unload                     3189	EXIST::FUNCTION:
        +CONF_imodule_get_value                  3190	EXIST::FUNCTION:
        +CONF_module_set_usr_data                3191	EXIST::FUNCTION:
        +CONF_parse_list                         3192	EXIST::FUNCTION:
        +CONF_module_add                         3193	EXIST::FUNCTION:
        +CONF_get1_default_config_file           3194	EXIST::FUNCTION:
        +CONF_imodule_get_flags                  3195	EXIST::FUNCTION:
        +CONF_imodule_get_module                 3196	EXIST::FUNCTION:
        +CONF_modules_load                       3197	EXIST::FUNCTION:
        +CONF_imodule_get_name                   3198	EXIST::FUNCTION:
        +ERR_peek_top_error                      3199	NOEXIST::FUNCTION:
        +CONF_imodule_get_usr_data               3200	EXIST::FUNCTION:
        +CONF_imodule_set_flags                  3201	EXIST::FUNCTION:
        +ENGINE_add_conf_module                  3202	EXIST::FUNCTION:ENGINE
        +ERR_peek_last_error_line                3203	EXIST::FUNCTION:
        +ERR_peek_last_error_line_data           3204	EXIST::FUNCTION:
        +ERR_peek_last_error                     3205	EXIST::FUNCTION:
        +DES_read_2passwords                     3206	EXIST::FUNCTION:DES
        +DES_read_password                       3207	EXIST::FUNCTION:DES
        +UI_UTIL_read_pw                         3208	EXIST::FUNCTION:
        +UI_UTIL_read_pw_string                  3209	EXIST::FUNCTION:
        +ENGINE_load_aep                         3210	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +ENGINE_load_sureware                    3211	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +OPENSSL_add_all_algorithms_noconf       3212	EXIST:!VMS:FUNCTION:
        +OPENSSL_add_all_algo_noconf             3212	EXIST:VMS:FUNCTION:
        +OPENSSL_add_all_algorithms_conf         3213	EXIST:!VMS:FUNCTION:
        +OPENSSL_add_all_algo_conf               3213	EXIST:VMS:FUNCTION:
        +OPENSSL_load_builtin_modules            3214	EXIST::FUNCTION:
        +AES_ofb128_encrypt                      3215	EXIST::FUNCTION:AES
        +AES_ctr128_encrypt                      3216	EXIST::FUNCTION:AES
        +AES_cfb128_encrypt                      3217	EXIST::FUNCTION:AES
        +ENGINE_load_4758cca                     3218	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +_ossl_096_des_random_seed               3219	EXIST::FUNCTION:DES
        +EVP_aes_256_ofb                         3220	EXIST::FUNCTION:AES
        +EVP_aes_192_ofb                         3221	EXIST::FUNCTION:AES
        +EVP_aes_128_cfb128                      3222	EXIST::FUNCTION:AES
        +EVP_aes_256_cfb128                      3223	EXIST::FUNCTION:AES
        +EVP_aes_128_ofb                         3224	EXIST::FUNCTION:AES
        +EVP_aes_192_cfb128                      3225	EXIST::FUNCTION:AES
        +CONF_modules_free                       3226	EXIST::FUNCTION:
        +NCONF_default                           3227	EXIST::FUNCTION:
        +OPENSSL_no_config                       3228	EXIST::FUNCTION:
        +NCONF_WIN32                             3229	EXIST::FUNCTION:
        +ASN1_UNIVERSALSTRING_new                3230	EXIST::FUNCTION:
        +EVP_des_ede_ecb                         3231	EXIST::FUNCTION:DES
        +i2d_ASN1_UNIVERSALSTRING                3232	EXIST::FUNCTION:
        +ASN1_UNIVERSALSTRING_free               3233	EXIST::FUNCTION:
        +ASN1_UNIVERSALSTRING_it                 3234	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_UNIVERSALSTRING_it                 3234	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_ASN1_UNIVERSALSTRING                3235	EXIST::FUNCTION:
        +EVP_des_ede3_ecb                        3236	EXIST::FUNCTION:DES
        +X509_REQ_print_ex                       3237	EXIST::FUNCTION:BIO
        +ENGINE_up_ref                           3238	EXIST::FUNCTION:ENGINE
        +BUF_MEM_grow_clean                      3239	EXIST::FUNCTION:
        +CRYPTO_realloc_clean                    3240	EXIST::FUNCTION:
        +BUF_strlcat                             3241	EXIST::FUNCTION:
        +BIO_indent                              3242	EXIST::FUNCTION:
        +BUF_strlcpy                             3243	EXIST::FUNCTION:
        +OpenSSLDie                              3244	EXIST::FUNCTION:
        +OPENSSL_cleanse                         3245	EXIST::FUNCTION:
        +ENGINE_setup_bsd_cryptodev              3246	EXIST:__FreeBSD__:FUNCTION:ENGINE
        +ERR_release_err_state_table             3247	EXIST::FUNCTION:LHASH
        +EVP_aes_128_cfb8                        3248	EXIST::FUNCTION:AES
        +FIPS_corrupt_rsa                        3249	NOEXIST::FUNCTION:
        +FIPS_selftest_des                       3250	NOEXIST::FUNCTION:
        +EVP_aes_128_cfb1                        3251	EXIST::FUNCTION:AES
        +EVP_aes_192_cfb8                        3252	EXIST::FUNCTION:AES
        +FIPS_mode_set                           3253	EXIST::FUNCTION:
        +FIPS_selftest_dsa                       3254	NOEXIST::FUNCTION:
        +EVP_aes_256_cfb8                        3255	EXIST::FUNCTION:AES
        +FIPS_allow_md5                          3256	NOEXIST::FUNCTION:
        +DES_ede3_cfb_encrypt                    3257	EXIST::FUNCTION:DES
        +EVP_des_ede3_cfb8                       3258	EXIST::FUNCTION:DES
        +FIPS_rand_seeded                        3259	NOEXIST::FUNCTION:
        +AES_cfbr_encrypt_block                  3260	NOEXIST::FUNCTION:
        +AES_cfb8_encrypt                        3261	EXIST::FUNCTION:AES
        +FIPS_rand_seed                          3262	NOEXIST::FUNCTION:
        +FIPS_corrupt_des                        3263	NOEXIST::FUNCTION:
        +EVP_aes_192_cfb1                        3264	EXIST::FUNCTION:AES
        +FIPS_selftest_aes                       3265	NOEXIST::FUNCTION:
        +FIPS_set_prng_key                       3266	NOEXIST::FUNCTION:
        +EVP_des_cfb8                            3267	EXIST::FUNCTION:DES
        +FIPS_corrupt_dsa                        3268	NOEXIST::FUNCTION:
        +FIPS_test_mode                          3269	NOEXIST::FUNCTION:
        +FIPS_rand_method                        3270	NOEXIST::FUNCTION:
        +EVP_aes_256_cfb1                        3271	EXIST::FUNCTION:AES
        +ERR_load_FIPS_strings                   3272	NOEXIST::FUNCTION:
        +FIPS_corrupt_aes                        3273	NOEXIST::FUNCTION:
        +FIPS_selftest_sha1                      3274	NOEXIST::FUNCTION:
        +FIPS_selftest_rsa                       3275	NOEXIST::FUNCTION:
        +FIPS_corrupt_sha1                       3276	NOEXIST::FUNCTION:
        +EVP_des_cfb1                            3277	EXIST::FUNCTION:DES
        +FIPS_dsa_check                          3278	NOEXIST::FUNCTION:
        +AES_cfb1_encrypt                        3279	EXIST::FUNCTION:AES
        +EVP_des_ede3_cfb1                       3280	EXIST::FUNCTION:DES
        +FIPS_rand_check                         3281	NOEXIST::FUNCTION:
        +FIPS_md5_allowed                        3282	NOEXIST::FUNCTION:
        +FIPS_mode                               3283	EXIST::FUNCTION:
        +FIPS_selftest_failed                    3284	NOEXIST::FUNCTION:
        +sk_is_sorted                            3285	EXIST::FUNCTION:
        +X509_check_ca                           3286	EXIST::FUNCTION:
        +private_idea_set_encrypt_key            3287	EXIST:OPENSSL_FIPS:FUNCTION:IDEA
        +HMAC_CTX_set_flags                      3288	EXIST::FUNCTION:HMAC
        +private_SHA_Init                        3289	EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA0
        +private_CAST_set_key                    3290	EXIST:OPENSSL_FIPS:FUNCTION:CAST
        +private_RIPEMD160_Init                  3291	EXIST:OPENSSL_FIPS:FUNCTION:RIPEMD
        +private_RC5_32_set_key                  3292	NOEXIST::FUNCTION:
        +private_MD5_Init                        3293	EXIST:OPENSSL_FIPS:FUNCTION:MD5
        +private_RC4_set_key                     3294	EXIST::FUNCTION:RC4
        +private_MDC2_Init                       3295	EXIST:OPENSSL_FIPS:FUNCTION:MDC2
        +private_RC2_set_key                     3296	EXIST:OPENSSL_FIPS:FUNCTION:RC2
        +private_MD4_Init                        3297	EXIST:OPENSSL_FIPS:FUNCTION:MD4
        +private_BF_set_key                      3298	EXIST:OPENSSL_FIPS:FUNCTION:BF
        +private_MD2_Init                        3299	EXIST:OPENSSL_FIPS:FUNCTION:MD2
        +d2i_PROXY_CERT_INFO_EXTENSION           3300	EXIST::FUNCTION:
        +PROXY_POLICY_it                         3301	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PROXY_POLICY_it                         3301	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +i2d_PROXY_POLICY                        3302	EXIST::FUNCTION:
        +i2d_PROXY_CERT_INFO_EXTENSION           3303	EXIST::FUNCTION:
        +d2i_PROXY_POLICY                        3304	EXIST::FUNCTION:
        +PROXY_CERT_INFO_EXTENSION_new           3305	EXIST::FUNCTION:
        +PROXY_CERT_INFO_EXTENSION_free          3306	EXIST::FUNCTION:
        +PROXY_CERT_INFO_EXTENSION_it            3307	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +PROXY_CERT_INFO_EXTENSION_it            3307	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +PROXY_POLICY_free                       3308	EXIST::FUNCTION:
        +PROXY_POLICY_new                        3309	EXIST::FUNCTION:
        +BN_MONT_CTX_set_locked                  3310	EXIST::FUNCTION:
        +FIPS_selftest_rng                       3311	NOEXIST::FUNCTION:
        +EVP_sha384                              3312	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +EVP_sha512                              3313	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +EVP_sha224                              3314	EXIST::FUNCTION:SHA,SHA256
        +EVP_sha256                              3315	EXIST::FUNCTION:SHA,SHA256
        +FIPS_selftest_hmac                      3316	NOEXIST::FUNCTION:
        +FIPS_corrupt_rng                        3317	NOEXIST::FUNCTION:
        +BN_mod_exp_mont_consttime               3318	EXIST::FUNCTION:
        +RSA_X931_hash_id                        3319	EXIST::FUNCTION:RSA
        +RSA_padding_check_X931                  3320	EXIST::FUNCTION:RSA
        +RSA_verify_PKCS1_PSS                    3321	EXIST::FUNCTION:RSA
        +RSA_padding_add_X931                    3322	EXIST::FUNCTION:RSA
        +RSA_padding_add_PKCS1_PSS               3323	EXIST::FUNCTION:RSA
        +PKCS1_MGF1                              3324	EXIST::FUNCTION:RSA
        +BN_X931_generate_Xpq                    3325	EXIST::FUNCTION:
        +RSA_X931_generate_key                   3326	NOEXIST::FUNCTION:
        +BN_X931_derive_prime                    3327	NOEXIST::FUNCTION:
        +BN_X931_generate_prime                  3328	NOEXIST::FUNCTION:
        +RSA_X931_derive                         3329	NOEXIST::FUNCTION:
        +BIO_new_dgram                           3330	EXIST::FUNCTION:
        +BN_get0_nist_prime_384                  3331	EXIST::FUNCTION:
        +ERR_set_mark                            3332	EXIST::FUNCTION:
        +X509_STORE_CTX_set0_crls                3333	EXIST::FUNCTION:
        +ENGINE_set_STORE                        3334	EXIST::FUNCTION:ENGINE
        +ENGINE_register_ECDSA                   3335	EXIST::FUNCTION:ENGINE
        +STORE_meth_set_list_start_fn            3336	NOEXIST::FUNCTION:
        +STORE_method_set_list_start_function    3336	NOEXIST::FUNCTION:
        +BN_BLINDING_invert_ex                   3337	EXIST::FUNCTION:
        +NAME_CONSTRAINTS_free                   3338	EXIST::FUNCTION:
        +STORE_ATTR_INFO_set_number              3339	NOEXIST::FUNCTION:
        +BN_BLINDING_get_thread_id               3340	EXIST::FUNCTION:DEPRECATED
        +X509_STORE_CTX_set0_param               3341	EXIST::FUNCTION:
        +POLICY_MAPPING_it                       3342	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +POLICY_MAPPING_it                       3342	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +STORE_parse_attrs_start                 3343	NOEXIST::FUNCTION:
        +POLICY_CONSTRAINTS_free                 3344	EXIST::FUNCTION:
        +EVP_PKEY_add1_attr_by_NID               3345	EXIST::FUNCTION:
        +BN_nist_mod_192                         3346	EXIST::FUNCTION:
        +EC_GROUP_get_trinomial_basis            3347	EXIST::FUNCTION:EC,EC2M
        +STORE_set_method                        3348	NOEXIST::FUNCTION:
        +GENERAL_SUBTREE_free                    3349	EXIST::FUNCTION:
        +NAME_CONSTRAINTS_it                     3350	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +NAME_CONSTRAINTS_it                     3350	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +ECDH_get_default_method                 3351	EXIST::FUNCTION:ECDH
        +PKCS12_add_safe                         3352	EXIST::FUNCTION:
        +EC_KEY_new_by_curve_name                3353	EXIST::FUNCTION:EC
        +STORE_meth_get_update_store_fn          3354	NOEXIST::FUNCTION:
        +STORE_method_get_update_store_function  3354	NOEXIST::FUNCTION:
        +ENGINE_register_ECDH                    3355	EXIST::FUNCTION:ENGINE
        +SHA512_Update                           3356	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +i2d_ECPrivateKey                        3357	EXIST::FUNCTION:EC
        +BN_get0_nist_prime_192                  3358	EXIST::FUNCTION:
        +STORE_modify_certificate                3359	NOEXIST::FUNCTION:
        +EC_POINT_set_affine_coordinates_GF2m    3360	EXIST:!VMS:FUNCTION:EC,EC2M
        +EC_POINT_set_affine_coords_GF2m         3360	EXIST:VMS:FUNCTION:EC,EC2M
        +BN_GF2m_mod_exp_arr                     3361	EXIST::FUNCTION:EC2M
        +STORE_ATTR_INFO_modify_number           3362	NOEXIST::FUNCTION:
        +X509_keyid_get0                         3363	EXIST::FUNCTION:
        +ENGINE_load_gmp                         3364	EXIST::FUNCTION:ENGINE,GMP,STATIC_ENGINE
        +pitem_new                               3365	EXIST::FUNCTION:
        +BN_GF2m_mod_mul_arr                     3366	EXIST::FUNCTION:EC2M
        +STORE_list_public_key_endp              3367	NOEXIST::FUNCTION:
        +o2i_ECPublicKey                         3368	EXIST::FUNCTION:EC
        +EC_KEY_copy                             3369	EXIST::FUNCTION:EC
        +BIO_dump_fp                             3370	EXIST::FUNCTION:FP_API
        +X509_policy_node_get0_parent            3371	EXIST::FUNCTION:
        +EC_GROUP_check_discriminant             3372	EXIST::FUNCTION:EC
        +i2o_ECPublicKey                         3373	EXIST::FUNCTION:EC
        +EC_KEY_precompute_mult                  3374	EXIST::FUNCTION:EC
        +a2i_IPADDRESS                           3375	EXIST::FUNCTION:
        +STORE_meth_set_initialise_fn            3376	NOEXIST::FUNCTION:
        +STORE_method_set_initialise_function    3376	NOEXIST::FUNCTION:
        +X509_STORE_CTX_set_depth                3377	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_inherit               3378	EXIST::FUNCTION:
        +EC_POINT_point2bn                       3379	EXIST::FUNCTION:EC
        +STORE_ATTR_INFO_set_dn                  3380	NOEXIST::FUNCTION:
        +X509_policy_tree_get0_policies          3381	EXIST::FUNCTION:
        +EC_GROUP_new_curve_GF2m                 3382	EXIST::FUNCTION:EC,EC2M
        +STORE_destroy_method                    3383	NOEXIST::FUNCTION:
        +ENGINE_unregister_STORE                 3384	EXIST::FUNCTION:ENGINE
        +EVP_PKEY_get1_EC_KEY                    3385	EXIST::FUNCTION:EC
        +STORE_ATTR_INFO_get0_number             3386	NOEXIST::FUNCTION:
        +ENGINE_get_default_ECDH                 3387	EXIST::FUNCTION:ENGINE
        +EC_KEY_get_conv_form                    3388	EXIST::FUNCTION:EC
        +ASN1_OCTET_STRING_NDEF_it               3389	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_OCTET_STRING_NDEF_it               3389	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +STORE_delete_public_key                 3390	NOEXIST::FUNCTION:
        +STORE_get_public_key                    3391	NOEXIST::FUNCTION:
        +STORE_modify_arbitrary                  3392	NOEXIST::FUNCTION:
        +ENGINE_get_static_state                 3393	EXIST::FUNCTION:ENGINE
        +pqueue_iterator                         3394	EXIST::FUNCTION:
        +ECDSA_SIG_new                           3395	EXIST::FUNCTION:ECDSA
        +OPENSSL_DIR_end                         3396	EXIST::FUNCTION:
        +BN_GF2m_mod_sqr                         3397	EXIST::FUNCTION:EC2M
        +EC_POINT_bn2point                       3398	EXIST::FUNCTION:EC
        +X509_VERIFY_PARAM_set_depth             3399	EXIST::FUNCTION:
        +EC_KEY_set_asn1_flag                    3400	EXIST::FUNCTION:EC
        +STORE_get_method                        3401	NOEXIST::FUNCTION:
        +EC_KEY_get_key_method_data              3402	EXIST::FUNCTION:EC
        +ECDSA_sign_ex                           3403	EXIST::FUNCTION:ECDSA
        +STORE_parse_attrs_end                   3404	NOEXIST::FUNCTION:
        +EC_GROUP_get_point_conversion_form      3405	EXIST:!VMS:FUNCTION:EC
        +EC_GROUP_get_point_conv_form            3405	EXIST:VMS:FUNCTION:EC
        +STORE_method_set_store_function         3406	NOEXIST::FUNCTION:
        +STORE_ATTR_INFO_in                      3407	NOEXIST::FUNCTION:
        +PEM_read_bio_ECPKParameters             3408	EXIST::FUNCTION:EC
        +EC_GROUP_get_pentanomial_basis          3409	EXIST::FUNCTION:EC,EC2M
        +EVP_PKEY_add1_attr_by_txt               3410	EXIST::FUNCTION:
        +BN_BLINDING_set_flags                   3411	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_set1_policies         3412	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_set1_name             3413	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_set_purpose           3414	EXIST::FUNCTION:
        +STORE_get_number                        3415	NOEXIST::FUNCTION:
        +ECDSA_sign_setup                        3416	EXIST::FUNCTION:ECDSA
        +BN_GF2m_mod_solve_quad_arr              3417	EXIST::FUNCTION:EC2M
        +EC_KEY_up_ref                           3418	EXIST::FUNCTION:EC
        +POLICY_MAPPING_free                     3419	EXIST::FUNCTION:
        +BN_GF2m_mod_div                         3420	EXIST::FUNCTION:EC2M
        +X509_VERIFY_PARAM_set_flags             3421	EXIST::FUNCTION:
        +EC_KEY_free                             3422	EXIST::FUNCTION:EC
        +STORE_meth_set_list_next_fn             3423	NOEXIST::FUNCTION:
        +STORE_method_set_list_next_function     3423	NOEXIST::FUNCTION:
        +PEM_write_bio_ECPrivateKey              3424	EXIST::FUNCTION:EC
        +d2i_EC_PUBKEY                           3425	EXIST::FUNCTION:EC
        +STORE_meth_get_generate_fn              3426	NOEXIST::FUNCTION:
        +STORE_method_get_generate_function      3426	NOEXIST::FUNCTION:
        +STORE_meth_set_list_end_fn              3427	NOEXIST::FUNCTION:
        +STORE_method_set_list_end_function      3427	NOEXIST::FUNCTION:
        +pqueue_print                            3428	EXIST::FUNCTION:
        +EC_GROUP_have_precompute_mult           3429	EXIST::FUNCTION:EC
        +EC_KEY_print_fp                         3430	EXIST::FUNCTION:EC,FP_API
        +BN_GF2m_mod_arr                         3431	EXIST::FUNCTION:EC2M
        +PEM_write_bio_X509_CERT_PAIR            3432	EXIST::FUNCTION:
        +EVP_PKEY_cmp                            3433	EXIST::FUNCTION:
        +X509_policy_level_node_count            3434	EXIST::FUNCTION:
        +STORE_new_engine                        3435	NOEXIST::FUNCTION:
        +STORE_list_public_key_start             3436	NOEXIST::FUNCTION:
        +X509_VERIFY_PARAM_new                   3437	EXIST::FUNCTION:
        +ECDH_get_ex_data                        3438	EXIST::FUNCTION:ECDH
        +EVP_PKEY_get_attr                       3439	EXIST::FUNCTION:
        +ECDSA_do_sign                           3440	EXIST::FUNCTION:ECDSA
        +ENGINE_unregister_ECDH                  3441	EXIST::FUNCTION:ENGINE
        +ECDH_OpenSSL                            3442	EXIST::FUNCTION:ECDH
        +EC_KEY_set_conv_form                    3443	EXIST::FUNCTION:EC
        +EC_POINT_dup                            3444	EXIST::FUNCTION:EC
        +GENERAL_SUBTREE_new                     3445	EXIST::FUNCTION:
        +STORE_list_crl_endp                     3446	NOEXIST::FUNCTION:
        +EC_get_builtin_curves                   3447	EXIST::FUNCTION:EC
        +X509_policy_node_get0_qualifiers        3448	EXIST:!VMS:FUNCTION:
        +X509_pcy_node_get0_qualifiers           3448	EXIST:VMS:FUNCTION:
        +STORE_list_crl_end                      3449	NOEXIST::FUNCTION:
        +EVP_PKEY_set1_EC_KEY                    3450	EXIST::FUNCTION:EC
        +BN_GF2m_mod_sqrt_arr                    3451	EXIST::FUNCTION:EC2M
        +i2d_ECPrivateKey_bio                    3452	EXIST::FUNCTION:BIO,EC
        +ECPKParameters_print_fp                 3453	EXIST::FUNCTION:EC,FP_API
        +pqueue_find                             3454	EXIST::FUNCTION:
        +ECDSA_SIG_free                          3455	EXIST::FUNCTION:ECDSA
        +PEM_write_bio_ECPKParameters            3456	EXIST::FUNCTION:EC
        +STORE_method_set_ctrl_function          3457	NOEXIST::FUNCTION:
        +STORE_list_public_key_end               3458	NOEXIST::FUNCTION:
        +EC_KEY_set_private_key                  3459	EXIST::FUNCTION:EC
        +pqueue_peek                             3460	EXIST::FUNCTION:
        +STORE_get_arbitrary                     3461	NOEXIST::FUNCTION:
        +STORE_store_crl                         3462	NOEXIST::FUNCTION:
        +X509_policy_node_get0_policy            3463	EXIST::FUNCTION:
        +PKCS12_add_safes                        3464	EXIST::FUNCTION:
        +BN_BLINDING_convert_ex                  3465	EXIST::FUNCTION:
        +X509_policy_tree_free                   3466	EXIST::FUNCTION:
        +OPENSSL_ia32cap_loc                     3467	EXIST::FUNCTION:
        +BN_GF2m_poly2arr                        3468	EXIST::FUNCTION:EC2M
        +STORE_ctrl                              3469	NOEXIST::FUNCTION:
        +STORE_ATTR_INFO_compare                 3470	NOEXIST::FUNCTION:
        +BN_get0_nist_prime_224                  3471	EXIST::FUNCTION:
        +i2d_ECParameters                        3472	EXIST::FUNCTION:EC
        +i2d_ECPKParameters                      3473	EXIST::FUNCTION:EC
        +BN_GENCB_call                           3474	EXIST::FUNCTION:
        +d2i_ECPKParameters                      3475	EXIST::FUNCTION:EC
        +STORE_meth_set_generate_fn              3476	NOEXIST::FUNCTION:
        +STORE_method_set_generate_function      3476	NOEXIST::FUNCTION:
        +ENGINE_set_ECDH                         3477	EXIST::FUNCTION:ENGINE
        +NAME_CONSTRAINTS_new                    3478	EXIST::FUNCTION:
        +SHA256_Init                             3479	EXIST::FUNCTION:SHA,SHA256
        +EC_KEY_get0_public_key                  3480	EXIST::FUNCTION:EC
        +PEM_write_bio_EC_PUBKEY                 3481	EXIST::FUNCTION:EC
        +STORE_ATTR_INFO_set_cstr                3482	NOEXIST::FUNCTION:
        +STORE_list_crl_next                     3483	NOEXIST::FUNCTION:
        +STORE_ATTR_INFO_in_range                3484	NOEXIST::FUNCTION:
        +ECParameters_print                      3485	EXIST::FUNCTION:BIO,EC
        +STORE_meth_set_delete_fn                3486	NOEXIST::FUNCTION:
        +STORE_method_set_delete_function        3486	NOEXIST::FUNCTION:
        +STORE_list_certificate_next             3487	NOEXIST::FUNCTION:
        +ASN1_generate_nconf                     3488	EXIST::FUNCTION:
        +BUF_memdup                              3489	EXIST::FUNCTION:
        +BN_GF2m_mod_mul                         3490	EXIST::FUNCTION:EC2M
        +STORE_meth_get_list_next_fn             3491	NOEXIST::FUNCTION:
        +STORE_method_get_list_next_function     3491	NOEXIST::FUNCTION:
        +STORE_ATTR_INFO_get0_dn                 3492	NOEXIST::FUNCTION:
        +STORE_list_private_key_next             3493	NOEXIST::FUNCTION:
        +EC_GROUP_set_seed                       3494	EXIST::FUNCTION:EC
        +X509_VERIFY_PARAM_set_trust             3495	EXIST::FUNCTION:
        +STORE_ATTR_INFO_free                    3496	NOEXIST::FUNCTION:
        +STORE_get_private_key                   3497	NOEXIST::FUNCTION:
        +EVP_PKEY_get_attr_count                 3498	EXIST::FUNCTION:
        +STORE_ATTR_INFO_new                     3499	NOEXIST::FUNCTION:
        +EC_GROUP_get_curve_GF2m                 3500	EXIST::FUNCTION:EC,EC2M
        +STORE_meth_set_revoke_fn                3501	NOEXIST::FUNCTION:
        +STORE_method_set_revoke_function        3501	NOEXIST::FUNCTION:
        +STORE_store_number                      3502	NOEXIST::FUNCTION:
        +BN_is_prime_ex                          3503	EXIST::FUNCTION:
        +STORE_revoke_public_key                 3504	NOEXIST::FUNCTION:
        +X509_STORE_CTX_get0_param               3505	EXIST::FUNCTION:
        +STORE_delete_arbitrary                  3506	NOEXIST::FUNCTION:
        +PEM_read_X509_CERT_PAIR                 3507	EXIST:!WIN16:FUNCTION:
        +X509_STORE_set_depth                    3508	EXIST::FUNCTION:
        +ECDSA_get_ex_data                       3509	EXIST::FUNCTION:ECDSA
        +SHA224                                  3510	EXIST::FUNCTION:SHA,SHA256
        +BIO_dump_indent_fp                      3511	EXIST::FUNCTION:FP_API
        +EC_KEY_set_group                        3512	EXIST::FUNCTION:EC
        +BUF_strndup                             3513	EXIST::FUNCTION:
        +STORE_list_certificate_start            3514	NOEXIST::FUNCTION:
        +BN_GF2m_mod                             3515	EXIST::FUNCTION:EC2M
        +X509_REQ_check_private_key              3516	EXIST::FUNCTION:
        +EC_GROUP_get_seed_len                   3517	EXIST::FUNCTION:EC
        +ERR_load_STORE_strings                  3518	NOEXIST::FUNCTION:
        +PEM_read_bio_EC_PUBKEY                  3519	EXIST::FUNCTION:EC
        +STORE_list_private_key_end              3520	NOEXIST::FUNCTION:
        +i2d_EC_PUBKEY                           3521	EXIST::FUNCTION:EC
        +ECDSA_get_default_method                3522	EXIST::FUNCTION:ECDSA
        +ASN1_put_eoc                            3523	EXIST::FUNCTION:
        +X509_STORE_CTX_get_explicit_policy      3524	EXIST:!VMS:FUNCTION:
        +X509_STORE_CTX_get_expl_policy          3524	EXIST:VMS:FUNCTION:
        +X509_VERIFY_PARAM_table_cleanup         3525	EXIST::FUNCTION:
        +STORE_modify_private_key                3526	NOEXIST::FUNCTION:
        +X509_VERIFY_PARAM_free                  3527	EXIST::FUNCTION:
        +EC_METHOD_get_field_type                3528	EXIST::FUNCTION:EC
        +EC_GFp_nist_method                      3529	EXIST::FUNCTION:EC
        +STORE_meth_set_modify_fn                3530	NOEXIST::FUNCTION:
        +STORE_method_set_modify_function        3530	NOEXIST::FUNCTION:
        +STORE_parse_attrs_next                  3531	NOEXIST::FUNCTION:
        +ENGINE_load_padlock                     3532	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +EC_GROUP_set_curve_name                 3533	EXIST::FUNCTION:EC
        +X509_CERT_PAIR_it                       3534	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_CERT_PAIR_it                       3534	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +STORE_meth_get_revoke_fn                3535	NOEXIST::FUNCTION:
        +STORE_method_get_revoke_function        3535	NOEXIST::FUNCTION:
        +STORE_method_set_get_function           3536	NOEXIST::FUNCTION:
        +STORE_modify_number                     3537	NOEXIST::FUNCTION:
        +STORE_method_get_store_function         3538	NOEXIST::FUNCTION:
        +STORE_store_private_key                 3539	NOEXIST::FUNCTION:
        +BN_GF2m_mod_sqr_arr                     3540	EXIST::FUNCTION:EC2M
        +RSA_setup_blinding                      3541	EXIST::FUNCTION:RSA
        +BIO_s_datagram                          3542	EXIST::FUNCTION:DGRAM
        +STORE_Memory                            3543	NOEXIST::FUNCTION:
        +sk_find_ex                              3544	EXIST::FUNCTION:
        +EC_GROUP_set_curve_GF2m                 3545	EXIST::FUNCTION:EC,EC2M
        +ENGINE_set_default_ECDSA                3546	EXIST::FUNCTION:ENGINE
        +POLICY_CONSTRAINTS_new                  3547	EXIST::FUNCTION:
        +BN_GF2m_mod_sqrt                        3548	EXIST::FUNCTION:EC2M
        +ECDH_set_default_method                 3549	EXIST::FUNCTION:ECDH
        +EC_KEY_generate_key                     3550	EXIST::FUNCTION:EC
        +SHA384_Update                           3551	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +BN_GF2m_arr2poly                        3552	EXIST::FUNCTION:EC2M
        +STORE_method_get_get_function           3553	NOEXIST::FUNCTION:
        +STORE_meth_set_cleanup_fn               3554	NOEXIST::FUNCTION:
        +STORE_method_set_cleanup_function       3554	NOEXIST::FUNCTION:
        +EC_GROUP_check                          3555	EXIST::FUNCTION:EC
        +d2i_ECPrivateKey_bio                    3556	EXIST::FUNCTION:BIO,EC
        +EC_KEY_insert_key_method_data           3557	EXIST::FUNCTION:EC
        +STORE_meth_get_lock_store_fn            3558	NOEXIST::FUNCTION:
        +STORE_method_get_lock_store_function    3558	NOEXIST::FUNCTION:
        +X509_VERIFY_PARAM_get_depth             3559	EXIST::FUNCTION:
        +SHA224_Final                            3560	EXIST::FUNCTION:SHA,SHA256
        +STORE_meth_set_update_store_fn          3561	NOEXIST::FUNCTION:
        +STORE_method_set_update_store_function  3561	NOEXIST::FUNCTION:
        +SHA224_Update                           3562	EXIST::FUNCTION:SHA,SHA256
        +d2i_ECPrivateKey                        3563	EXIST::FUNCTION:EC
        +ASN1_item_ndef_i2d                      3564	EXIST::FUNCTION:
        +STORE_delete_private_key                3565	NOEXIST::FUNCTION:
        +ERR_pop_to_mark                         3566	EXIST::FUNCTION:
        +ENGINE_register_all_STORE               3567	EXIST::FUNCTION:ENGINE
        +X509_policy_level_get0_node             3568	EXIST::FUNCTION:
        +i2d_PKCS7_NDEF                          3569	EXIST::FUNCTION:
        +EC_GROUP_get_degree                     3570	EXIST::FUNCTION:EC
        +ASN1_generate_v3                        3571	EXIST::FUNCTION:
        +STORE_ATTR_INFO_modify_cstr             3572	NOEXIST::FUNCTION:
        +X509_policy_tree_level_count            3573	EXIST::FUNCTION:
        +BN_GF2m_add                             3574	EXIST::FUNCTION:EC2M
        +EC_KEY_get0_group                       3575	EXIST::FUNCTION:EC
        +STORE_generate_crl                      3576	NOEXIST::FUNCTION:
        +STORE_store_public_key                  3577	NOEXIST::FUNCTION:
        +X509_CERT_PAIR_free                     3578	EXIST::FUNCTION:
        +STORE_revoke_private_key                3579	NOEXIST::FUNCTION:
        +BN_nist_mod_224                         3580	EXIST::FUNCTION:
        +SHA512_Final                            3581	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +STORE_ATTR_INFO_modify_dn               3582	NOEXIST::FUNCTION:
        +STORE_meth_get_initialise_fn            3583	NOEXIST::FUNCTION:
        +STORE_method_get_initialise_function    3583	NOEXIST::FUNCTION:
        +STORE_delete_number                     3584	NOEXIST::FUNCTION:
        +i2d_EC_PUBKEY_bio                       3585	EXIST::FUNCTION:BIO,EC
        +BIO_dgram_non_fatal_error               3586	EXIST::FUNCTION:
        +EC_GROUP_get_asn1_flag                  3587	EXIST::FUNCTION:EC
        +STORE_ATTR_INFO_in_ex                   3588	NOEXIST::FUNCTION:
        +STORE_list_crl_start                    3589	NOEXIST::FUNCTION:
        +ECDH_get_ex_new_index                   3590	EXIST::FUNCTION:ECDH
        +STORE_meth_get_modify_fn                3591	NOEXIST::FUNCTION:
        +STORE_method_get_modify_function        3591	NOEXIST::FUNCTION:
        +v2i_ASN1_BIT_STRING                     3592	EXIST::FUNCTION:
        +STORE_store_certificate                 3593	NOEXIST::FUNCTION:
        +OBJ_bsearch_ex                          3594	NOEXIST::FUNCTION:
        +X509_STORE_CTX_set_default              3595	EXIST::FUNCTION:
        +STORE_ATTR_INFO_set_sha1str             3596	NOEXIST::FUNCTION:
        +BN_GF2m_mod_inv                         3597	EXIST::FUNCTION:EC2M
        +BN_GF2m_mod_exp                         3598	EXIST::FUNCTION:EC2M
        +STORE_modify_public_key                 3599	NOEXIST::FUNCTION:
        +STORE_meth_get_list_start_fn            3600	NOEXIST::FUNCTION:
        +STORE_method_get_list_start_function    3600	NOEXIST::FUNCTION:
        +EC_GROUP_get0_seed                      3601	EXIST::FUNCTION:EC
        +STORE_store_arbitrary                   3602	NOEXIST::FUNCTION:
        +STORE_meth_set_unlock_store_fn          3603	NOEXIST::FUNCTION:
        +STORE_method_set_unlock_store_function  3603	NOEXIST::FUNCTION:
        +BN_GF2m_mod_div_arr                     3604	EXIST::FUNCTION:EC2M
        +ENGINE_set_ECDSA                        3605	EXIST::FUNCTION:ENGINE
        +STORE_create_method                     3606	NOEXIST::FUNCTION:
        +ECPKParameters_print                    3607	EXIST::FUNCTION:BIO,EC
        +EC_KEY_get0_private_key                 3608	EXIST::FUNCTION:EC
        +PEM_write_EC_PUBKEY                     3609	EXIST:!WIN16:FUNCTION:EC
        +X509_VERIFY_PARAM_set1                  3610	EXIST::FUNCTION:
        +ECDH_set_method                         3611	EXIST::FUNCTION:ECDH
        +v2i_GENERAL_NAME_ex                     3612	EXIST::FUNCTION:
        +ECDH_set_ex_data                        3613	EXIST::FUNCTION:ECDH
        +STORE_generate_key                      3614	NOEXIST::FUNCTION:
        +BN_nist_mod_521                         3615	EXIST::FUNCTION:
        +X509_policy_tree_get0_level             3616	EXIST::FUNCTION:
        +EC_GROUP_set_point_conversion_form      3617	EXIST:!VMS:FUNCTION:EC
        +EC_GROUP_set_point_conv_form            3617	EXIST:VMS:FUNCTION:EC
        +PEM_read_EC_PUBKEY                      3618	EXIST:!WIN16:FUNCTION:EC
        +i2d_ECDSA_SIG                           3619	EXIST::FUNCTION:ECDSA
        +ECDSA_OpenSSL                           3620	EXIST::FUNCTION:ECDSA
        +STORE_delete_crl                        3621	NOEXIST::FUNCTION:
        +EC_KEY_get_enc_flags                    3622	EXIST::FUNCTION:EC
        +ASN1_const_check_infinite_end           3623	EXIST::FUNCTION:
        +EVP_PKEY_delete_attr                    3624	EXIST::FUNCTION:
        +ECDSA_set_default_method                3625	EXIST::FUNCTION:ECDSA
        +EC_POINT_set_compressed_coordinates_GF2m 3626	EXIST:!VMS:FUNCTION:EC,EC2M
        +EC_POINT_set_compr_coords_GF2m          3626	EXIST:VMS:FUNCTION:EC,EC2M
        +EC_GROUP_cmp                            3627	EXIST::FUNCTION:EC
        +STORE_revoke_certificate                3628	NOEXIST::FUNCTION:
        +BN_get0_nist_prime_256                  3629	EXIST::FUNCTION:
        +STORE_meth_get_delete_fn                3630	NOEXIST::FUNCTION:
        +STORE_method_get_delete_function        3630	NOEXIST::FUNCTION:
        +SHA224_Init                             3631	EXIST::FUNCTION:SHA,SHA256
        +PEM_read_ECPrivateKey                   3632	EXIST:!WIN16:FUNCTION:EC
        +SHA512_Init                             3633	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +STORE_parse_attrs_endp                  3634	NOEXIST::FUNCTION:
        +BN_set_negative                         3635	EXIST::FUNCTION:
        +ERR_load_ECDSA_strings                  3636	EXIST::FUNCTION:ECDSA
        +EC_GROUP_get_basis_type                 3637	EXIST::FUNCTION:EC
        +STORE_list_public_key_next              3638	NOEXIST::FUNCTION:
        +i2v_ASN1_BIT_STRING                     3639	EXIST::FUNCTION:
        +STORE_OBJECT_free                       3640	NOEXIST::FUNCTION:
        +BN_nist_mod_384                         3641	EXIST::FUNCTION:
        +i2d_X509_CERT_PAIR                      3642	EXIST::FUNCTION:
        +PEM_write_ECPKParameters                3643	EXIST:!WIN16:FUNCTION:EC
        +ECDH_compute_key                        3644	EXIST::FUNCTION:ECDH
        +STORE_ATTR_INFO_get0_sha1str            3645	NOEXIST::FUNCTION:
        +ENGINE_register_all_ECDH                3646	EXIST::FUNCTION:ENGINE
        +pqueue_pop                              3647	EXIST::FUNCTION:
        +STORE_ATTR_INFO_get0_cstr               3648	NOEXIST::FUNCTION:
        +POLICY_CONSTRAINTS_it                   3649	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +POLICY_CONSTRAINTS_it                   3649	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +STORE_get_ex_new_index                  3650	NOEXIST::FUNCTION:
        +EVP_PKEY_get_attr_by_OBJ                3651	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_add0_policy           3652	EXIST::FUNCTION:
        +BN_GF2m_mod_solve_quad                  3653	EXIST::FUNCTION:EC2M
        +SHA256                                  3654	EXIST::FUNCTION:SHA,SHA256
        +i2d_ECPrivateKey_fp                     3655	EXIST::FUNCTION:EC,FP_API
        +X509_policy_tree_get0_user_policies     3656	EXIST:!VMS:FUNCTION:
        +X509_pcy_tree_get0_usr_policies         3656	EXIST:VMS:FUNCTION:
        +OPENSSL_DIR_read                        3657	EXIST::FUNCTION:
        +ENGINE_register_all_ECDSA               3658	EXIST::FUNCTION:ENGINE
        +X509_VERIFY_PARAM_lookup                3659	EXIST::FUNCTION:
        +EC_POINT_get_affine_coordinates_GF2m    3660	EXIST:!VMS:FUNCTION:EC,EC2M
        +EC_POINT_get_affine_coords_GF2m         3660	EXIST:VMS:FUNCTION:EC,EC2M
        +EC_GROUP_dup                            3661	EXIST::FUNCTION:EC
        +ENGINE_get_default_ECDSA                3662	EXIST::FUNCTION:ENGINE
        +EC_KEY_new                              3663	EXIST::FUNCTION:EC
        +SHA256_Transform                        3664	EXIST::FUNCTION:SHA,SHA256
        +EC_KEY_set_enc_flags                    3665	EXIST::FUNCTION:EC
        +ECDSA_verify                            3666	EXIST::FUNCTION:ECDSA
        +EC_POINT_point2hex                      3667	EXIST::FUNCTION:EC
        +ENGINE_get_STORE                        3668	EXIST::FUNCTION:ENGINE
        +SHA512                                  3669	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +STORE_get_certificate                   3670	NOEXIST::FUNCTION:
        +ECDSA_do_sign_ex                        3671	EXIST::FUNCTION:ECDSA
        +ECDSA_do_verify                         3672	EXIST::FUNCTION:ECDSA
        +d2i_ECPrivateKey_fp                     3673	EXIST::FUNCTION:EC,FP_API
        +STORE_delete_certificate                3674	NOEXIST::FUNCTION:
        +SHA512_Transform                        3675	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +X509_STORE_set1_param                   3676	EXIST::FUNCTION:
        +STORE_method_get_ctrl_function          3677	NOEXIST::FUNCTION:
        +STORE_free                              3678	NOEXIST::FUNCTION:
        +PEM_write_ECPrivateKey                  3679	EXIST:!WIN16:FUNCTION:EC
        +STORE_meth_get_unlock_store_fn          3680	NOEXIST::FUNCTION:
        +STORE_method_get_unlock_store_function  3680	NOEXIST::FUNCTION:
        +STORE_get_ex_data                       3681	NOEXIST::FUNCTION:
        +EC_KEY_set_public_key                   3682	EXIST::FUNCTION:EC
        +PEM_read_ECPKParameters                 3683	EXIST:!WIN16:FUNCTION:EC
        +X509_CERT_PAIR_new                      3684	EXIST::FUNCTION:
        +ENGINE_register_STORE                   3685	EXIST::FUNCTION:ENGINE
        +RSA_generate_key_ex                     3686	EXIST::FUNCTION:RSA
        +DSA_generate_parameters_ex              3687	EXIST::FUNCTION:DSA
        +ECParameters_print_fp                   3688	EXIST::FUNCTION:EC,FP_API
        +X509V3_NAME_from_section                3689	EXIST::FUNCTION:
        +EVP_PKEY_add1_attr                      3690	EXIST::FUNCTION:
        +STORE_modify_crl                        3691	NOEXIST::FUNCTION:
        +STORE_list_private_key_start            3692	NOEXIST::FUNCTION:
        +POLICY_MAPPINGS_it                      3693	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +POLICY_MAPPINGS_it                      3693	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +GENERAL_SUBTREE_it                      3694	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +GENERAL_SUBTREE_it                      3694	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EC_GROUP_get_curve_name                 3695	EXIST::FUNCTION:EC
        +PEM_write_X509_CERT_PAIR                3696	EXIST:!WIN16:FUNCTION:
        +BIO_dump_indent_cb                      3697	EXIST::FUNCTION:
        +d2i_X509_CERT_PAIR                      3698	EXIST::FUNCTION:
        +STORE_list_private_key_endp             3699	NOEXIST::FUNCTION:
        +asn1_const_Finish                       3700	EXIST::FUNCTION:
        +i2d_EC_PUBKEY_fp                        3701	EXIST::FUNCTION:EC,FP_API
        +BN_nist_mod_256                         3702	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_add0_table            3703	EXIST::FUNCTION:
        +pqueue_free                             3704	EXIST::FUNCTION:
        +BN_BLINDING_create_param                3705	EXIST::FUNCTION:
        +ECDSA_size                              3706	EXIST::FUNCTION:ECDSA
        +d2i_EC_PUBKEY_bio                       3707	EXIST::FUNCTION:BIO,EC
        +BN_get0_nist_prime_521                  3708	EXIST::FUNCTION:
        +STORE_ATTR_INFO_modify_sha1str          3709	NOEXIST::FUNCTION:
        +BN_generate_prime_ex                    3710	EXIST::FUNCTION:
        +EC_GROUP_new_by_curve_name              3711	EXIST::FUNCTION:EC
        +SHA256_Final                            3712	EXIST::FUNCTION:SHA,SHA256
        +DH_generate_parameters_ex               3713	EXIST::FUNCTION:DH
        +PEM_read_bio_ECPrivateKey               3714	EXIST::FUNCTION:EC
        +STORE_meth_get_cleanup_fn               3715	NOEXIST::FUNCTION:
        +STORE_method_get_cleanup_function       3715	NOEXIST::FUNCTION:
        +ENGINE_get_ECDH                         3716	EXIST::FUNCTION:ENGINE
        +d2i_ECDSA_SIG                           3717	EXIST::FUNCTION:ECDSA
        +BN_is_prime_fasttest_ex                 3718	EXIST::FUNCTION:
        +ECDSA_sign                              3719	EXIST::FUNCTION:ECDSA
        +X509_policy_check                       3720	EXIST::FUNCTION:
        +EVP_PKEY_get_attr_by_NID                3721	EXIST::FUNCTION:
        +STORE_set_ex_data                       3722	NOEXIST::FUNCTION:
        +ENGINE_get_ECDSA                        3723	EXIST::FUNCTION:ENGINE
        +EVP_ecdsa                               3724	EXIST::FUNCTION:SHA
        +BN_BLINDING_get_flags                   3725	EXIST::FUNCTION:
        +PKCS12_add_cert                         3726	EXIST::FUNCTION:
        +STORE_OBJECT_new                        3727	NOEXIST::FUNCTION:
        +ERR_load_ECDH_strings                   3728	EXIST::FUNCTION:ECDH
        +EC_KEY_dup                              3729	EXIST::FUNCTION:EC
        +EVP_CIPHER_CTX_rand_key                 3730	EXIST::FUNCTION:
        +ECDSA_set_method                        3731	EXIST::FUNCTION:ECDSA
        +a2i_IPADDRESS_NC                        3732	EXIST::FUNCTION:
        +d2i_ECParameters                        3733	EXIST::FUNCTION:EC
        +STORE_list_certificate_end              3734	NOEXIST::FUNCTION:
        +STORE_get_crl                           3735	NOEXIST::FUNCTION:
        +X509_POLICY_NODE_print                  3736	EXIST::FUNCTION:
        +SHA384_Init                             3737	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +EC_GF2m_simple_method                   3738	EXIST::FUNCTION:EC,EC2M
        +ECDSA_set_ex_data                       3739	EXIST::FUNCTION:ECDSA
        +SHA384_Final                            3740	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +PKCS7_set_digest                        3741	EXIST::FUNCTION:
        +EC_KEY_print                            3742	EXIST::FUNCTION:BIO,EC
        +STORE_meth_set_lock_store_fn            3743	NOEXIST::FUNCTION:
        +STORE_method_set_lock_store_function    3743	NOEXIST::FUNCTION:
        +ECDSA_get_ex_new_index                  3744	EXIST::FUNCTION:ECDSA
        +SHA384                                  3745	EXIST:!VMSVAX:FUNCTION:SHA,SHA512
        +POLICY_MAPPING_new                      3746	EXIST::FUNCTION:
        +STORE_list_certificate_endp             3747	NOEXIST::FUNCTION:
        +X509_STORE_CTX_get0_policy_tree         3748	EXIST::FUNCTION:
        +EC_GROUP_set_asn1_flag                  3749	EXIST::FUNCTION:EC
        +EC_KEY_check_key                        3750	EXIST::FUNCTION:EC
        +d2i_EC_PUBKEY_fp                        3751	EXIST::FUNCTION:EC,FP_API
        +PKCS7_set0_type_other                   3752	EXIST::FUNCTION:
        +PEM_read_bio_X509_CERT_PAIR             3753	EXIST::FUNCTION:
        +pqueue_next                             3754	EXIST::FUNCTION:
        +STORE_meth_get_list_end_fn              3755	NOEXIST::FUNCTION:
        +STORE_method_get_list_end_function      3755	NOEXIST::FUNCTION:
        +EVP_PKEY_add1_attr_by_OBJ               3756	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_set_time              3757	EXIST::FUNCTION:
        +pqueue_new                              3758	EXIST::FUNCTION:
        +ENGINE_set_default_ECDH                 3759	EXIST::FUNCTION:ENGINE
        +STORE_new_method                        3760	NOEXIST::FUNCTION:
        +PKCS12_add_key                          3761	EXIST::FUNCTION:
        +DSO_merge                               3762	EXIST::FUNCTION:
        +EC_POINT_hex2point                      3763	EXIST::FUNCTION:EC
        +BIO_dump_cb                             3764	EXIST::FUNCTION:
        +SHA256_Update                           3765	EXIST::FUNCTION:SHA,SHA256
        +pqueue_insert                           3766	EXIST::FUNCTION:
        +pitem_free                              3767	EXIST::FUNCTION:
        +BN_GF2m_mod_inv_arr                     3768	EXIST::FUNCTION:EC2M
        +ENGINE_unregister_ECDSA                 3769	EXIST::FUNCTION:ENGINE
        +BN_BLINDING_set_thread_id               3770	EXIST::FUNCTION:DEPRECATED
        +get_rfc3526_prime_8192                  3771	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_clear_flags           3772	EXIST::FUNCTION:
        +get_rfc2409_prime_1024                  3773	EXIST::FUNCTION:
        +DH_check_pub_key                        3774	EXIST::FUNCTION:DH
        +get_rfc3526_prime_2048                  3775	EXIST::FUNCTION:
        +get_rfc3526_prime_6144                  3776	EXIST::FUNCTION:
        +get_rfc3526_prime_1536                  3777	EXIST::FUNCTION:
        +get_rfc3526_prime_3072                  3778	EXIST::FUNCTION:
        +get_rfc3526_prime_4096                  3779	EXIST::FUNCTION:
        +get_rfc2409_prime_768                   3780	EXIST::FUNCTION:
        +X509_VERIFY_PARAM_get_flags             3781	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_new                      3782	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_free                     3783	EXIST::FUNCTION:
        +Camellia_cbc_encrypt                    3784	EXIST::FUNCTION:CAMELLIA
        +Camellia_cfb128_encrypt                 3785	EXIST::FUNCTION:CAMELLIA
        +Camellia_cfb1_encrypt                   3786	EXIST::FUNCTION:CAMELLIA
        +Camellia_cfb8_encrypt                   3787	EXIST::FUNCTION:CAMELLIA
        +Camellia_ctr128_encrypt                 3788	EXIST::FUNCTION:CAMELLIA
        +Camellia_cfbr_encrypt_block             3789	NOEXIST::FUNCTION:
        +Camellia_decrypt                        3790	EXIST::FUNCTION:CAMELLIA
        +Camellia_ecb_encrypt                    3791	EXIST::FUNCTION:CAMELLIA
        +Camellia_encrypt                        3792	EXIST::FUNCTION:CAMELLIA
        +Camellia_ofb128_encrypt                 3793	EXIST::FUNCTION:CAMELLIA
        +Camellia_set_key                        3794	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_128_cbc                    3795	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_128_cfb128                 3796	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_128_cfb1                   3797	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_128_cfb8                   3798	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_128_ecb                    3799	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_128_ofb                    3800	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_192_cbc                    3801	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_192_cfb128                 3802	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_192_cfb1                   3803	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_192_cfb8                   3804	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_192_ecb                    3805	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_192_ofb                    3806	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_256_cbc                    3807	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_256_cfb128                 3808	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_256_cfb1                   3809	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_256_cfb8                   3810	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_256_ecb                    3811	EXIST::FUNCTION:CAMELLIA
        +EVP_camellia_256_ofb                    3812	EXIST::FUNCTION:CAMELLIA
        +a2i_ipadd                               3813	EXIST::FUNCTION:
        +ASIdentifiers_free                      3814	EXIST::FUNCTION:RFC3779
        +i2d_ASIdOrRange                         3815	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_block_size                   3816	EXIST::FUNCTION:
        +v3_asid_is_canonical                    3817	EXIST::FUNCTION:RFC3779
        +IPAddressChoice_free                    3818	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_CTX_set_app_data             3819	EXIST::FUNCTION:
        +BIO_set_callback_arg                    3820	EXIST::FUNCTION:
        +v3_addr_add_prefix                      3821	EXIST::FUNCTION:RFC3779
        +IPAddressOrRange_it                     3822	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +IPAddressOrRange_it                     3822	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +BIO_set_flags                           3823	EXIST::FUNCTION:
        +ASIdentifiers_it                        3824	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +ASIdentifiers_it                        3824	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +v3_addr_get_range                       3825	EXIST::FUNCTION:RFC3779
        +BIO_method_type                         3826	EXIST::FUNCTION:
        +v3_addr_inherits                        3827	EXIST::FUNCTION:RFC3779
        +IPAddressChoice_it                      3828	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +IPAddressChoice_it                      3828	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +AES_ige_encrypt                         3829	EXIST::FUNCTION:AES
        +v3_addr_add_range                       3830	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_CTX_nid                      3831	EXIST::FUNCTION:
        +d2i_ASRange                             3832	EXIST::FUNCTION:RFC3779
        +v3_addr_add_inherit                     3833	EXIST::FUNCTION:RFC3779
        +v3_asid_add_id_or_range                 3834	EXIST::FUNCTION:RFC3779
        +v3_addr_validate_resource_set           3835	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_iv_length                    3836	EXIST::FUNCTION:
        +EVP_MD_type                             3837	EXIST::FUNCTION:
        +v3_asid_canonize                        3838	EXIST::FUNCTION:RFC3779
        +IPAddressRange_free                     3839	EXIST::FUNCTION:RFC3779
        +v3_asid_add_inherit                     3840	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_CTX_key_length               3841	EXIST::FUNCTION:
        +IPAddressRange_new                      3842	EXIST::FUNCTION:RFC3779
        +ASIdOrRange_new                         3843	EXIST::FUNCTION:RFC3779
        +EVP_MD_size                             3844	EXIST::FUNCTION:
        +EVP_MD_CTX_test_flags                   3845	EXIST::FUNCTION:
        +BIO_clear_flags                         3846	EXIST::FUNCTION:
        +i2d_ASRange                             3847	EXIST::FUNCTION:RFC3779
        +IPAddressRange_it                       3848	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +IPAddressRange_it                       3848	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +IPAddressChoice_new                     3849	EXIST::FUNCTION:RFC3779
        +ASIdentifierChoice_new                  3850	EXIST::FUNCTION:RFC3779
        +ASRange_free                            3851	EXIST::FUNCTION:RFC3779
        +EVP_MD_pkey_type                        3852	EXIST::FUNCTION:
        +EVP_MD_CTX_clear_flags                  3853	EXIST::FUNCTION:
        +IPAddressFamily_free                    3854	EXIST::FUNCTION:RFC3779
        +i2d_IPAddressFamily                     3855	EXIST::FUNCTION:RFC3779
        +IPAddressOrRange_new                    3856	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_flags                        3857	EXIST::FUNCTION:
        +v3_asid_validate_resource_set           3858	EXIST::FUNCTION:RFC3779
        +d2i_IPAddressRange                      3859	EXIST::FUNCTION:RFC3779
        +AES_bi_ige_encrypt                      3860	EXIST::FUNCTION:AES
        +BIO_get_callback                        3861	EXIST::FUNCTION:
        +IPAddressOrRange_free                   3862	EXIST::FUNCTION:RFC3779
        +v3_addr_subset                          3863	EXIST::FUNCTION:RFC3779
        +d2i_IPAddressFamily                     3864	EXIST::FUNCTION:RFC3779
        +v3_asid_subset                          3865	EXIST::FUNCTION:RFC3779
        +BIO_test_flags                          3866	EXIST::FUNCTION:
        +i2d_ASIdentifierChoice                  3867	EXIST::FUNCTION:RFC3779
        +ASRange_it                              3868	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +ASRange_it                              3868	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +d2i_ASIdentifiers                       3869	EXIST::FUNCTION:RFC3779
        +ASRange_new                             3870	EXIST::FUNCTION:RFC3779
        +d2i_IPAddressChoice                     3871	EXIST::FUNCTION:RFC3779
        +v3_addr_get_afi                         3872	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_key_length                   3873	EXIST::FUNCTION:
        +EVP_Cipher                              3874	EXIST::FUNCTION:
        +i2d_IPAddressOrRange                    3875	EXIST::FUNCTION:RFC3779
        +ASIdOrRange_it                          3876	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +ASIdOrRange_it                          3876	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +EVP_CIPHER_nid                          3877	EXIST::FUNCTION:
        +i2d_IPAddressChoice                     3878	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_CTX_block_size               3879	EXIST::FUNCTION:
        +ASIdentifiers_new                       3880	EXIST::FUNCTION:RFC3779
        +v3_addr_validate_path                   3881	EXIST::FUNCTION:RFC3779
        +IPAddressFamily_new                     3882	EXIST::FUNCTION:RFC3779
        +EVP_MD_CTX_set_flags                    3883	EXIST::FUNCTION:
        +v3_addr_is_canonical                    3884	EXIST::FUNCTION:RFC3779
        +i2d_IPAddressRange                      3885	EXIST::FUNCTION:RFC3779
        +IPAddressFamily_it                      3886	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +IPAddressFamily_it                      3886	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +v3_asid_inherits                        3887	EXIST::FUNCTION:RFC3779
        +EVP_CIPHER_CTX_cipher                   3888	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_get_app_data             3889	EXIST::FUNCTION:
        +EVP_MD_block_size                       3890	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_flags                    3891	EXIST::FUNCTION:
        +v3_asid_validate_path                   3892	EXIST::FUNCTION:RFC3779
        +d2i_IPAddressOrRange                    3893	EXIST::FUNCTION:RFC3779
        +v3_addr_canonize                        3894	EXIST::FUNCTION:RFC3779
        +ASIdentifierChoice_it                   3895	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RFC3779
        +ASIdentifierChoice_it                   3895	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RFC3779
        +EVP_MD_CTX_md                           3896	EXIST::FUNCTION:
        +d2i_ASIdentifierChoice                  3897	EXIST::FUNCTION:RFC3779
        +BIO_method_name                         3898	EXIST::FUNCTION:
        +EVP_CIPHER_CTX_iv_length                3899	EXIST::FUNCTION:
        +ASIdOrRange_free                        3900	EXIST::FUNCTION:RFC3779
        +ASIdentifierChoice_free                 3901	EXIST::FUNCTION:RFC3779
        +BIO_get_callback_arg                    3902	EXIST::FUNCTION:
        +BIO_set_callback                        3903	EXIST::FUNCTION:
        +d2i_ASIdOrRange                         3904	EXIST::FUNCTION:RFC3779
        +i2d_ASIdentifiers                       3905	EXIST::FUNCTION:RFC3779
        +CRYPTO_memcmp                           3906	EXIST::FUNCTION:
        +SEED_decrypt                            3908	EXIST::FUNCTION:SEED
        +SEED_encrypt                            3909	EXIST::FUNCTION:SEED
        +SEED_cbc_encrypt                        3910	EXIST::FUNCTION:SEED
        +EVP_seed_ofb                            3911	EXIST::FUNCTION:SEED
        +SEED_cfb128_encrypt                     3912	EXIST::FUNCTION:SEED
        +SEED_ofb128_encrypt                     3913	EXIST::FUNCTION:SEED
        +EVP_seed_cbc                            3914	EXIST::FUNCTION:SEED
        +SEED_ecb_encrypt                        3915	EXIST::FUNCTION:SEED
        +EVP_seed_ecb                            3916	EXIST::FUNCTION:SEED
        +SEED_set_key                            3917	EXIST::FUNCTION:SEED
        +EVP_seed_cfb128                         3918	EXIST::FUNCTION:SEED
        +X509_EXTENSIONS_it                      3919	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_EXTENSIONS_it                      3919	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_get1_ocsp                          3920	EXIST::FUNCTION:
        +OCSP_REQ_CTX_free                       3921	EXIST::FUNCTION:
        +i2d_X509_EXTENSIONS                     3922	EXIST::FUNCTION:
        +OCSP_sendreq_nbio                       3923	EXIST::FUNCTION:
        +OCSP_sendreq_new                        3924	EXIST::FUNCTION:
        +d2i_X509_EXTENSIONS                     3925	EXIST::FUNCTION:
        +X509_ALGORS_it                          3926	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +X509_ALGORS_it                          3926	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +X509_ALGOR_get0                         3927	EXIST::FUNCTION:
        +X509_ALGOR_set0                         3928	EXIST::FUNCTION:
        +AES_unwrap_key                          3929	EXIST::FUNCTION:AES
        +AES_wrap_key                            3930	EXIST::FUNCTION:AES
        +X509at_get0_data_by_OBJ                 3931	EXIST::FUNCTION:
        +ASN1_TYPE_set1                          3932	EXIST::FUNCTION:
        +ASN1_STRING_set0                        3933	EXIST::FUNCTION:
        +i2d_X509_ALGORS                         3934	EXIST::FUNCTION:
        +BIO_f_zlib                              3935	EXIST:ZLIB:FUNCTION:
        +COMP_zlib_cleanup                       3936	EXIST::FUNCTION:
        +d2i_X509_ALGORS                         3937	EXIST::FUNCTION:
        +CMS_ReceiptRequest_free                 3938	EXIST::FUNCTION:CMS
        +PEM_write_CMS                           3939	EXIST:!WIN16:FUNCTION:CMS
        +CMS_add0_CertificateChoices             3940	EXIST::FUNCTION:CMS
        +CMS_unsigned_add1_attr_by_OBJ           3941	EXIST::FUNCTION:CMS
        +ERR_load_CMS_strings                    3942	EXIST::FUNCTION:CMS
        +CMS_sign_receipt                        3943	EXIST::FUNCTION:CMS
        +i2d_CMS_ContentInfo                     3944	EXIST::FUNCTION:CMS
        +CMS_signed_delete_attr                  3945	EXIST::FUNCTION:CMS
        +d2i_CMS_bio                             3946	EXIST::FUNCTION:CMS
        +CMS_unsigned_get_attr_by_NID            3947	EXIST::FUNCTION:CMS
        +CMS_verify                              3948	EXIST::FUNCTION:CMS
        +SMIME_read_CMS                          3949	EXIST::FUNCTION:CMS
        +CMS_decrypt_set1_key                    3950	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_get0_algs                3951	EXIST::FUNCTION:CMS
        +CMS_add1_cert                           3952	EXIST::FUNCTION:CMS
        +CMS_set_detached                        3953	EXIST::FUNCTION:CMS
        +CMS_encrypt                             3954	EXIST::FUNCTION:CMS
        +CMS_EnvelopedData_create                3955	EXIST::FUNCTION:CMS
        +CMS_uncompress                          3956	EXIST::FUNCTION:CMS
        +CMS_add0_crl                            3957	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_verify_content           3958	EXIST::FUNCTION:CMS
        +CMS_unsigned_get0_data_by_OBJ           3959	EXIST::FUNCTION:CMS
        +PEM_write_bio_CMS                       3960	EXIST::FUNCTION:CMS
        +CMS_unsigned_get_attr                   3961	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_ktri_cert_cmp         3962	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_ktri_get0_algs        3963	EXIST:!VMS:FUNCTION:CMS
        +CMS_RecipInfo_ktri_get0_algs            3963	EXIST:VMS:FUNCTION:CMS
        +CMS_ContentInfo_free                    3964	EXIST::FUNCTION:CMS
        +CMS_final                               3965	EXIST::FUNCTION:CMS
        +CMS_add_simple_smimecap                 3966	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_verify                   3967	EXIST::FUNCTION:CMS
        +CMS_data                                3968	EXIST::FUNCTION:CMS
        +CMS_ContentInfo_it                      3969	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:CMS
        +CMS_ContentInfo_it                      3969	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:CMS
        +d2i_CMS_ReceiptRequest                  3970	EXIST::FUNCTION:CMS
        +CMS_compress                            3971	EXIST::FUNCTION:CMS
        +CMS_digest_create                       3972	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_cert_cmp                 3973	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_sign                     3974	EXIST::FUNCTION:CMS
        +CMS_data_create                         3975	EXIST::FUNCTION:CMS
        +i2d_CMS_bio                             3976	EXIST::FUNCTION:CMS
        +CMS_EncryptedData_set1_key              3977	EXIST::FUNCTION:CMS
        +CMS_decrypt                             3978	EXIST::FUNCTION:CMS
        +int_smime_write_ASN1                    3979	NOEXIST::FUNCTION:
        +CMS_unsigned_delete_attr                3980	EXIST::FUNCTION:CMS
        +CMS_unsigned_get_attr_count             3981	EXIST::FUNCTION:CMS
        +CMS_add_smimecap                        3982	EXIST::FUNCTION:CMS
        +PEM_read_CMS                            3983	EXIST:!WIN16:FUNCTION:CMS
        +CMS_signed_get_attr_by_OBJ              3984	EXIST::FUNCTION:CMS
        +d2i_CMS_ContentInfo                     3985	EXIST::FUNCTION:CMS
        +CMS_add_standard_smimecap               3986	EXIST::FUNCTION:CMS
        +CMS_ContentInfo_new                     3987	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_type                  3988	EXIST::FUNCTION:CMS
        +CMS_get0_type                           3989	EXIST::FUNCTION:CMS
        +CMS_is_detached                         3990	EXIST::FUNCTION:CMS
        +CMS_sign                                3991	EXIST::FUNCTION:CMS
        +CMS_signed_add1_attr                    3992	EXIST::FUNCTION:CMS
        +CMS_unsigned_get_attr_by_OBJ            3993	EXIST::FUNCTION:CMS
        +SMIME_write_CMS                         3994	EXIST::FUNCTION:CMS
        +CMS_EncryptedData_decrypt               3995	EXIST::FUNCTION:CMS
        +CMS_get0_RecipientInfos                 3996	EXIST::FUNCTION:CMS
        +CMS_add0_RevocationInfoChoice           3997	EXIST::FUNCTION:CMS
        +CMS_decrypt_set1_pkey                   3998	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_set1_signer_cert         3999	EXIST::FUNCTION:CMS
        +CMS_get0_signers                        4000	EXIST::FUNCTION:CMS
        +CMS_ReceiptRequest_get0_values          4001	EXIST::FUNCTION:CMS
        +CMS_signed_get0_data_by_OBJ             4002	EXIST::FUNCTION:CMS
        +CMS_get0_SignerInfos                    4003	EXIST::FUNCTION:CMS
        +CMS_add0_cert                           4004	EXIST::FUNCTION:CMS
        +CMS_EncryptedData_encrypt               4005	EXIST::FUNCTION:CMS
        +CMS_digest_verify                       4006	EXIST::FUNCTION:CMS
        +CMS_set1_signers_certs                  4007	EXIST::FUNCTION:CMS
        +CMS_signed_get_attr                     4008	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_set0_key              4009	EXIST::FUNCTION:CMS
        +CMS_SignedData_init                     4010	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_kekri_get0_id         4011	EXIST::FUNCTION:CMS
        +CMS_verify_receipt                      4012	EXIST::FUNCTION:CMS
        +CMS_ReceiptRequest_it                   4013	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:CMS
        +CMS_ReceiptRequest_it                   4013	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:CMS
        +PEM_read_bio_CMS                        4014	EXIST::FUNCTION:CMS
        +CMS_get1_crls                           4015	EXIST::FUNCTION:CMS
        +CMS_add0_recipient_key                  4016	EXIST::FUNCTION:CMS
        +SMIME_read_ASN1                         4017	EXIST::FUNCTION:
        +CMS_ReceiptRequest_new                  4018	EXIST::FUNCTION:CMS
        +CMS_get0_content                        4019	EXIST::FUNCTION:CMS
        +CMS_get1_ReceiptRequest                 4020	EXIST::FUNCTION:CMS
        +CMS_signed_add1_attr_by_OBJ             4021	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_kekri_id_cmp          4022	EXIST::FUNCTION:CMS
        +CMS_add1_ReceiptRequest                 4023	EXIST::FUNCTION:CMS
        +CMS_SignerInfo_get0_signer_id           4024	EXIST::FUNCTION:CMS
        +CMS_unsigned_add1_attr_by_NID           4025	EXIST::FUNCTION:CMS
        +CMS_unsigned_add1_attr                  4026	EXIST::FUNCTION:CMS
        +CMS_signed_get_attr_by_NID              4027	EXIST::FUNCTION:CMS
        +CMS_get1_certs                          4028	EXIST::FUNCTION:CMS
        +CMS_signed_add1_attr_by_NID             4029	EXIST::FUNCTION:CMS
        +CMS_unsigned_add1_attr_by_txt           4030	EXIST::FUNCTION:CMS
        +CMS_dataFinal                           4031	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_ktri_get0_signer_id   4032	EXIST:!VMS:FUNCTION:CMS
        +CMS_RecipInfo_ktri_get0_sigr_id         4032	EXIST:VMS:FUNCTION:CMS
        +i2d_CMS_ReceiptRequest                  4033	EXIST::FUNCTION:CMS
        +CMS_add1_recipient_cert                 4034	EXIST::FUNCTION:CMS
        +CMS_dataInit                            4035	EXIST::FUNCTION:CMS
        +CMS_signed_add1_attr_by_txt             4036	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_decrypt               4037	EXIST::FUNCTION:CMS
        +CMS_signed_get_attr_count               4038	EXIST::FUNCTION:CMS
        +CMS_get0_eContentType                   4039	EXIST::FUNCTION:CMS
        +CMS_set1_eContentType                   4040	EXIST::FUNCTION:CMS
        +CMS_ReceiptRequest_create0              4041	EXIST::FUNCTION:CMS
        +CMS_add1_signer                         4042	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_set0_pkey             4043	EXIST::FUNCTION:CMS
        +ENGINE_set_load_ssl_client_cert_function 4044	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_set_ld_ssl_clnt_cert_fn          4044	EXIST:VMS:FUNCTION:ENGINE
        +ENGINE_get_ssl_client_cert_function     4045	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_get_ssl_client_cert_fn           4045	EXIST:VMS:FUNCTION:ENGINE
        +ENGINE_load_ssl_client_cert             4046	EXIST::FUNCTION:ENGINE
        +ENGINE_load_capi                        4047	EXIST::FUNCTION:ENGINE,STATIC_ENGINE
        +OPENSSL_isservice                       4048	EXIST::FUNCTION:
        +FIPS_dsa_sig_decode                     4049	NOEXIST::FUNCTION:
        +EVP_CIPHER_CTX_clear_flags              4050	EXIST::FUNCTION:
        +FIPS_rand_status                        4051	NOEXIST::FUNCTION:
        +FIPS_rand_set_key                       4052	NOEXIST::FUNCTION:
        +CRYPTO_set_mem_info_functions           4053	NOEXIST::FUNCTION:
        +RSA_X931_generate_key_ex                4054	NOEXIST::FUNCTION:
        +int_ERR_set_state_func                  4055	NOEXIST::FUNCTION:
        +int_EVP_MD_set_engine_callbacks         4056	NOEXIST::FUNCTION:
        +int_CRYPTO_set_do_dynlock_callback      4057	NOEXIST::FUNCTION:
        +FIPS_rng_stick                          4058	NOEXIST::FUNCTION:
        +EVP_CIPHER_CTX_set_flags                4059	EXIST::FUNCTION:
        +BN_X931_generate_prime_ex               4060	EXIST::FUNCTION:
        +FIPS_selftest_check                     4061	NOEXIST::FUNCTION:
        +FIPS_rand_set_dt                        4062	NOEXIST::FUNCTION:
        +CRYPTO_dbg_pop_info                     4063	NOEXIST::FUNCTION:
        +FIPS_dsa_free                           4064	NOEXIST::FUNCTION:
        +RSA_X931_derive_ex                      4065	NOEXIST::FUNCTION:
        +FIPS_rsa_new                            4066	NOEXIST::FUNCTION:
        +FIPS_rand_bytes                         4067	NOEXIST::FUNCTION:
        +fips_cipher_test                        4068	NOEXIST::FUNCTION:
        +EVP_CIPHER_CTX_test_flags               4069	EXIST::FUNCTION:
        +CRYPTO_malloc_debug_init                4070	NOEXIST::FUNCTION:
        +CRYPTO_dbg_push_info                    4071	NOEXIST::FUNCTION:
        +FIPS_corrupt_rsa_keygen                 4072	NOEXIST::FUNCTION:
        +FIPS_dh_new                             4073	NOEXIST::FUNCTION:
        +FIPS_corrupt_dsa_keygen                 4074	NOEXIST::FUNCTION:
        +FIPS_dh_free                            4075	NOEXIST::FUNCTION:
        +fips_pkey_signature_test                4076	NOEXIST::FUNCTION:
        +EVP_add_alg_module                      4077	EXIST::FUNCTION:
        +int_RAND_init_engine_callbacks          4078	NOEXIST::FUNCTION:
        +int_EVP_CIPHER_set_engine_callbacks     4079	NOEXIST::FUNCTION:
        +int_EVP_MD_init_engine_callbacks        4080	NOEXIST::FUNCTION:
        +FIPS_rand_test_mode                     4081	NOEXIST::FUNCTION:
        +FIPS_rand_reset                         4082	NOEXIST::FUNCTION:
        +FIPS_dsa_new                            4083	NOEXIST::FUNCTION:
        +int_RAND_set_callbacks                  4084	NOEXIST::FUNCTION:
        +BN_X931_derive_prime_ex                 4085	EXIST::FUNCTION:
        +int_ERR_lib_init                        4086	NOEXIST::FUNCTION:
        +int_EVP_CIPHER_init_engine_callbacks    4087	NOEXIST::FUNCTION:
        +FIPS_rsa_free                           4088	NOEXIST::FUNCTION:
        +FIPS_dsa_sig_encode                     4089	NOEXIST::FUNCTION:
        +CRYPTO_dbg_remove_all_info              4090	NOEXIST::FUNCTION:
        +OPENSSL_init                            4091	EXIST::FUNCTION:
        +private_Camellia_set_key                4092	EXIST:OPENSSL_FIPS:FUNCTION:CAMELLIA
        +CRYPTO_strdup                           4093	EXIST::FUNCTION:
        +JPAKE_STEP3A_process                    4094	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP1_release                     4095	EXIST::FUNCTION:JPAKE
        +JPAKE_get_shared_key                    4096	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3B_init                       4097	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP1_generate                    4098	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP1_init                        4099	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3B_process                    4100	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP2_generate                    4101	EXIST::FUNCTION:JPAKE
        +JPAKE_CTX_new                           4102	EXIST::FUNCTION:JPAKE
        +JPAKE_CTX_free                          4103	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3B_release                    4104	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3A_release                    4105	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP2_process                     4106	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3B_generate                   4107	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP1_process                     4108	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3A_generate                   4109	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP2_release                     4110	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP3A_init                       4111	EXIST::FUNCTION:JPAKE
        +ERR_load_JPAKE_strings                  4112	EXIST::FUNCTION:JPAKE
        +JPAKE_STEP2_init                        4113	EXIST::FUNCTION:JPAKE
        +pqueue_size                             4114	EXIST::FUNCTION:
        +i2d_TS_ACCURACY                         4115	EXIST::FUNCTION:
        +i2d_TS_MSG_IMPRINT_fp                   4116	EXIST::FUNCTION:
        +i2d_TS_MSG_IMPRINT                      4117	EXIST::FUNCTION:
        +EVP_PKEY_print_public                   4118	EXIST::FUNCTION:
        +EVP_PKEY_CTX_new                        4119	EXIST::FUNCTION:
        +i2d_TS_TST_INFO                         4120	EXIST::FUNCTION:
        +EVP_PKEY_asn1_find                      4121	EXIST::FUNCTION:
        +DSO_METHOD_beos                         4122	EXIST::FUNCTION:
        +TS_CONF_load_cert                       4123	EXIST::FUNCTION:
        +TS_REQ_get_ext                          4124	EXIST::FUNCTION:
        +EVP_PKEY_sign_init                      4125	EXIST::FUNCTION:
        +ASN1_item_print                         4126	EXIST::FUNCTION:
        +TS_TST_INFO_set_nonce                   4127	EXIST::FUNCTION:
        +TS_RESP_dup                             4128	EXIST::FUNCTION:
        +ENGINE_register_pkey_meths              4129	EXIST::FUNCTION:ENGINE
        +EVP_PKEY_asn1_add0                      4130	EXIST::FUNCTION:
        +PKCS7_add0_attrib_signing_time          4131	EXIST::FUNCTION:
        +i2d_TS_TST_INFO_fp                      4132	EXIST::FUNCTION:
        +BIO_asn1_get_prefix                     4133	EXIST::FUNCTION:
        +TS_TST_INFO_set_time                    4134	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_decrypt               4135	EXIST::FUNCTION:
        +EVP_PKEY_set_type_str                   4136	EXIST::FUNCTION:
        +EVP_PKEY_CTX_get_keygen_info            4137	EXIST::FUNCTION:
        +TS_REQ_set_policy_id                    4138	EXIST::FUNCTION:
        +d2i_TS_RESP_fp                          4139	EXIST::FUNCTION:
        +ENGINE_get_pkey_asn1_meth_engine        4140	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_get_pkey_asn1_meth_eng           4140	EXIST:VMS:FUNCTION:ENGINE
        +WHIRLPOOL_Init                          4141	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
        +TS_RESP_set_status_info                 4142	EXIST::FUNCTION:
        +EVP_PKEY_keygen                         4143	EXIST::FUNCTION:
        +EVP_DigestSignInit                      4144	EXIST::FUNCTION:
        +TS_ACCURACY_set_millis                  4145	EXIST::FUNCTION:
        +TS_REQ_dup                              4146	EXIST::FUNCTION:
        +GENERAL_NAME_dup                        4147	EXIST::FUNCTION:
        +ASN1_SEQUENCE_ANY_it                    4148	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_SEQUENCE_ANY_it                    4148	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +WHIRLPOOL                               4149	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
        +X509_STORE_get1_crls                    4150	EXIST::FUNCTION:
        +ENGINE_get_pkey_asn1_meth               4151	EXIST::FUNCTION:ENGINE
        +EVP_PKEY_asn1_new                       4152	EXIST::FUNCTION:
        +BIO_new_NDEF                            4153	EXIST::FUNCTION:
        +ENGINE_get_pkey_meth                    4154	EXIST::FUNCTION:ENGINE
        +TS_MSG_IMPRINT_set_algo                 4155	EXIST::FUNCTION:
        +i2d_TS_TST_INFO_bio                     4156	EXIST::FUNCTION:
        +TS_TST_INFO_set_ordering                4157	EXIST::FUNCTION:
        +TS_TST_INFO_get_ext_by_OBJ              4158	EXIST::FUNCTION:
        +CRYPTO_THREADID_set_pointer             4159	EXIST::FUNCTION:
        +TS_CONF_get_tsa_section                 4160	EXIST::FUNCTION:
        +SMIME_write_ASN1                        4161	EXIST::FUNCTION:
        +TS_RESP_CTX_set_signer_key              4162	EXIST::FUNCTION:
        +EVP_PKEY_encrypt_old                    4163	EXIST::FUNCTION:
        +EVP_PKEY_encrypt_init                   4164	EXIST::FUNCTION:
        +CRYPTO_THREADID_cpy                     4165	EXIST::FUNCTION:
        +ASN1_PCTX_get_cert_flags                4166	EXIST::FUNCTION:
        +i2d_ESS_SIGNING_CERT                    4167	EXIST::FUNCTION:
        +TS_CONF_load_key                        4168	EXIST::FUNCTION:
        +i2d_ASN1_SEQUENCE_ANY                   4169	EXIST::FUNCTION:
        +d2i_TS_MSG_IMPRINT_bio                  4170	EXIST::FUNCTION:
        +EVP_PKEY_asn1_set_public                4171	EXIST::FUNCTION:
        +b2i_PublicKey_bio                       4172	EXIST::FUNCTION:
        +BIO_asn1_set_prefix                     4173	EXIST::FUNCTION:
        +EVP_PKEY_new_mac_key                    4174	EXIST::FUNCTION:
        +BIO_new_CMS                             4175	EXIST::FUNCTION:CMS
        +CRYPTO_THREADID_cmp                     4176	EXIST::FUNCTION:
        +TS_REQ_ext_free                         4177	EXIST::FUNCTION:
        +EVP_PKEY_asn1_set_free                  4178	EXIST::FUNCTION:
        +EVP_PKEY_get0_asn1                      4179	EXIST::FUNCTION:
        +d2i_NETSCAPE_X509                       4180	EXIST::FUNCTION:
        +EVP_PKEY_verify_recover_init            4181	EXIST::FUNCTION:
        +EVP_PKEY_CTX_set_data                   4182	EXIST::FUNCTION:
        +EVP_PKEY_keygen_init                    4183	EXIST::FUNCTION:
        +TS_RESP_CTX_set_status_info             4184	EXIST::FUNCTION:
        +TS_MSG_IMPRINT_get_algo                 4185	EXIST::FUNCTION:
        +TS_REQ_print_bio                        4186	EXIST::FUNCTION:
        +EVP_PKEY_CTX_ctrl_str                   4187	EXIST::FUNCTION:
        +EVP_PKEY_get_default_digest_nid         4188	EXIST::FUNCTION:
        +PEM_write_bio_PKCS7_stream              4189	EXIST::FUNCTION:
        +TS_MSG_IMPRINT_print_bio                4190	EXIST::FUNCTION:
        +BN_asc2bn                               4191	EXIST::FUNCTION:
        +TS_REQ_get_policy_id                    4192	EXIST::FUNCTION:
        +ENGINE_set_default_pkey_asn1_meths      4193	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_set_def_pkey_asn1_meths          4193	EXIST:VMS:FUNCTION:ENGINE
        +d2i_TS_ACCURACY                         4194	EXIST::FUNCTION:
        +DSO_global_lookup                       4195	EXIST::FUNCTION:
        +TS_CONF_set_tsa_name                    4196	EXIST::FUNCTION:
        +i2d_ASN1_SET_ANY                        4197	EXIST::FUNCTION:
        +ENGINE_load_gost                        4198	EXIST::FUNCTION:ENGINE,GOST,STATIC_ENGINE
        +WHIRLPOOL_BitUpdate                     4199	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
        +ASN1_PCTX_get_flags                     4200	EXIST::FUNCTION:
        +TS_TST_INFO_get_ext_by_NID              4201	EXIST::FUNCTION:
        +TS_RESP_new                             4202	EXIST::FUNCTION:
        +ESS_CERT_ID_dup                         4203	EXIST::FUNCTION:
        +TS_STATUS_INFO_dup                      4204	EXIST::FUNCTION:
        +TS_REQ_delete_ext                       4205	EXIST::FUNCTION:
        +EVP_DigestVerifyFinal                   4206	EXIST::FUNCTION:
        +EVP_PKEY_print_params                   4207	EXIST::FUNCTION:
        +i2d_CMS_bio_stream                      4208	EXIST::FUNCTION:CMS
        +TS_REQ_get_msg_imprint                  4209	EXIST::FUNCTION:
        +OBJ_find_sigid_by_algs                  4210	EXIST::FUNCTION:
        +TS_TST_INFO_get_serial                  4211	EXIST::FUNCTION:
        +TS_REQ_get_nonce                        4212	EXIST::FUNCTION:
        +X509_PUBKEY_set0_param                  4213	EXIST::FUNCTION:
        +EVP_PKEY_CTX_set0_keygen_info           4214	EXIST::FUNCTION:
        +DIST_POINT_set_dpname                   4215	EXIST::FUNCTION:
        +i2d_ISSUING_DIST_POINT                  4216	EXIST::FUNCTION:
        +ASN1_SET_ANY_it                         4217	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ASN1_SET_ANY_it                         4217	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +EVP_PKEY_CTX_get_data                   4218	EXIST::FUNCTION:
        +TS_STATUS_INFO_print_bio                4219	EXIST::FUNCTION:
        +EVP_PKEY_derive_init                    4220	EXIST::FUNCTION:
        +d2i_TS_TST_INFO                         4221	EXIST::FUNCTION:
        +EVP_PKEY_asn1_add_alias                 4222	EXIST::FUNCTION:
        +d2i_TS_RESP_bio                         4223	EXIST::FUNCTION:
        +OTHERNAME_cmp                           4224	EXIST::FUNCTION:
        +GENERAL_NAME_set0_value                 4225	EXIST::FUNCTION:
        +PKCS7_RECIP_INFO_get0_alg               4226	EXIST::FUNCTION:
        +TS_RESP_CTX_new                         4227	EXIST::FUNCTION:
        +TS_RESP_set_tst_info                    4228	EXIST::FUNCTION:
        +PKCS7_final                             4229	EXIST::FUNCTION:
        +EVP_PKEY_base_id                        4230	EXIST::FUNCTION:
        +TS_RESP_CTX_set_signer_cert             4231	EXIST::FUNCTION:
        +TS_REQ_set_msg_imprint                  4232	EXIST::FUNCTION:
        +EVP_PKEY_CTX_ctrl                       4233	EXIST::FUNCTION:
        +TS_CONF_set_digests                     4234	EXIST::FUNCTION:
        +d2i_TS_MSG_IMPRINT                      4235	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_ctrl                  4236	EXIST::FUNCTION:
        +TS_REQ_get_ext_by_NID                   4237	EXIST::FUNCTION:
        +PKCS5_pbe_set0_algor                    4238	EXIST::FUNCTION:
        +BN_BLINDING_thread_id                   4239	EXIST::FUNCTION:
        +TS_ACCURACY_new                         4240	EXIST::FUNCTION:
        +X509_CRL_METHOD_free                    4241	EXIST::FUNCTION:
        +ASN1_PCTX_get_nm_flags                  4242	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_sign                  4243	EXIST::FUNCTION:
        +CRYPTO_THREADID_current                 4244	EXIST::FUNCTION:
        +EVP_PKEY_decrypt_init                   4245	EXIST::FUNCTION:
        +NETSCAPE_X509_free                      4246	EXIST::FUNCTION:
        +i2b_PVK_bio                             4247	EXIST::FUNCTION:RC4
        +EVP_PKEY_print_private                  4248	EXIST::FUNCTION:
        +GENERAL_NAME_get0_value                 4249	EXIST::FUNCTION:
        +b2i_PVK_bio                             4250	EXIST::FUNCTION:RC4
        +ASN1_UTCTIME_adj                        4251	EXIST::FUNCTION:
        +TS_TST_INFO_new                         4252	EXIST::FUNCTION:
        +EVP_MD_do_all_sorted                    4253	EXIST::FUNCTION:
        +TS_CONF_set_default_engine              4254	EXIST::FUNCTION:
        +TS_ACCURACY_set_seconds                 4255	EXIST::FUNCTION:
        +TS_TST_INFO_get_time                    4256	EXIST::FUNCTION:
        +PKCS8_pkey_get0                         4257	EXIST::FUNCTION:
        +EVP_PKEY_asn1_get0                      4258	EXIST::FUNCTION:
        +OBJ_add_sigid                           4259	EXIST::FUNCTION:
        +PKCS7_SIGNER_INFO_sign                  4260	EXIST::FUNCTION:
        +EVP_PKEY_paramgen_init                  4261	EXIST::FUNCTION:
        +EVP_PKEY_sign                           4262	EXIST::FUNCTION:
        +OBJ_sigid_free                          4263	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_init                  4264	EXIST::FUNCTION:
        +d2i_ESS_ISSUER_SERIAL                   4265	EXIST::FUNCTION:
        +ISSUING_DIST_POINT_new                  4266	EXIST::FUNCTION:
        +ASN1_TIME_adj                           4267	EXIST::FUNCTION:
        +TS_OBJ_print_bio                        4268	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_verify_recover        4269	EXIST:!VMS:FUNCTION:
        +EVP_PKEY_meth_set_vrfy_recover          4269	EXIST:VMS:FUNCTION:
        +TS_RESP_get_status_info                 4270	EXIST::FUNCTION:
        +CMS_stream                              4271	EXIST::FUNCTION:CMS
        +EVP_PKEY_CTX_set_cb                     4272	EXIST::FUNCTION:
        +PKCS7_to_TS_TST_INFO                    4273	EXIST::FUNCTION:
        +ASN1_PCTX_get_oid_flags                 4274	EXIST::FUNCTION:
        +TS_TST_INFO_add_ext                     4275	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_derive                4276	EXIST::FUNCTION:
        +i2d_TS_RESP_fp                          4277	EXIST::FUNCTION:
        +i2d_TS_MSG_IMPRINT_bio                  4278	EXIST::FUNCTION:
        +TS_RESP_CTX_set_accuracy                4279	EXIST::FUNCTION:
        +TS_REQ_set_nonce                        4280	EXIST::FUNCTION:
        +ESS_CERT_ID_new                         4281	EXIST::FUNCTION:
        +ENGINE_pkey_asn1_find_str               4282	EXIST::FUNCTION:ENGINE
        +TS_REQ_get_ext_count                    4283	EXIST::FUNCTION:
        +BUF_reverse                             4284	EXIST::FUNCTION:
        +TS_TST_INFO_print_bio                   4285	EXIST::FUNCTION:
        +d2i_ISSUING_DIST_POINT                  4286	EXIST::FUNCTION:
        +ENGINE_get_pkey_meths                   4287	EXIST::FUNCTION:ENGINE
        +i2b_PrivateKey_bio                      4288	EXIST::FUNCTION:
        +i2d_TS_RESP                             4289	EXIST::FUNCTION:
        +b2i_PublicKey                           4290	EXIST::FUNCTION:
        +TS_VERIFY_CTX_cleanup                   4291	EXIST::FUNCTION:
        +TS_STATUS_INFO_free                     4292	EXIST::FUNCTION:
        +TS_RESP_verify_token                    4293	EXIST::FUNCTION:
        +OBJ_bsearch_ex_                         4294	EXIST::FUNCTION:
        +ASN1_bn_print                           4295	EXIST::FUNCTION:BIO
        +EVP_PKEY_asn1_get_count                 4296	EXIST::FUNCTION:
        +ENGINE_register_pkey_asn1_meths         4297	EXIST::FUNCTION:ENGINE
        +ASN1_PCTX_set_nm_flags                  4298	EXIST::FUNCTION:
        +EVP_DigestVerifyInit                    4299	EXIST::FUNCTION:
        +ENGINE_set_default_pkey_meths           4300	EXIST::FUNCTION:ENGINE
        +TS_TST_INFO_get_policy_id               4301	EXIST::FUNCTION:
        +TS_REQ_get_cert_req                     4302	EXIST::FUNCTION:
        +X509_CRL_set_meth_data                  4303	EXIST::FUNCTION:
        +PKCS8_pkey_set0                         4304	EXIST::FUNCTION:
        +ASN1_STRING_copy                        4305	EXIST::FUNCTION:
        +d2i_TS_TST_INFO_fp                      4306	EXIST::FUNCTION:
        +X509_CRL_match                          4307	EXIST::FUNCTION:
        +EVP_PKEY_asn1_set_private               4308	EXIST::FUNCTION:
        +TS_TST_INFO_get_ext_d2i                 4309	EXIST::FUNCTION:
        +TS_RESP_CTX_add_policy                  4310	EXIST::FUNCTION:
        +d2i_TS_RESP                             4311	EXIST::FUNCTION:
        +TS_CONF_load_certs                      4312	EXIST::FUNCTION:
        +TS_TST_INFO_get_msg_imprint             4313	EXIST::FUNCTION:
        +ERR_load_TS_strings                     4314	EXIST::FUNCTION:
        +TS_TST_INFO_get_version                 4315	EXIST::FUNCTION:
        +EVP_PKEY_CTX_dup                        4316	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_verify                4317	EXIST::FUNCTION:
        +i2b_PublicKey_bio                       4318	EXIST::FUNCTION:
        +TS_CONF_set_certs                       4319	EXIST::FUNCTION:
        +EVP_PKEY_asn1_get0_info                 4320	EXIST::FUNCTION:
        +TS_VERIFY_CTX_free                      4321	EXIST::FUNCTION:
        +TS_REQ_get_ext_by_critical              4322	EXIST::FUNCTION:
        +TS_RESP_CTX_set_serial_cb               4323	EXIST::FUNCTION:
        +X509_CRL_get_meth_data                  4324	EXIST::FUNCTION:
        +TS_RESP_CTX_set_time_cb                 4325	EXIST::FUNCTION:
        +TS_MSG_IMPRINT_get_msg                  4326	EXIST::FUNCTION:
        +TS_TST_INFO_ext_free                    4327	EXIST::FUNCTION:
        +TS_REQ_get_version                      4328	EXIST::FUNCTION:
        +TS_REQ_add_ext                          4329	EXIST::FUNCTION:
        +EVP_PKEY_CTX_set_app_data               4330	EXIST::FUNCTION:
        +OBJ_bsearch_                            4331	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_verifyctx             4332	EXIST::FUNCTION:
        +i2d_PKCS7_bio_stream                    4333	EXIST::FUNCTION:
        +CRYPTO_THREADID_set_numeric             4334	EXIST::FUNCTION:
        +PKCS7_sign_add_signer                   4335	EXIST::FUNCTION:
        +d2i_TS_TST_INFO_bio                     4336	EXIST::FUNCTION:
        +TS_TST_INFO_get_ordering                4337	EXIST::FUNCTION:
        +TS_RESP_print_bio                       4338	EXIST::FUNCTION:
        +TS_TST_INFO_get_exts                    4339	EXIST::FUNCTION:
        +HMAC_CTX_copy                           4340	EXIST::FUNCTION:HMAC
        +PKCS5_pbe2_set_iv                       4341	EXIST::FUNCTION:
        +ENGINE_get_pkey_asn1_meths              4342	EXIST::FUNCTION:ENGINE
        +b2i_PrivateKey                          4343	EXIST::FUNCTION:
        +EVP_PKEY_CTX_get_app_data               4344	EXIST::FUNCTION:
        +TS_REQ_set_cert_req                     4345	EXIST::FUNCTION:
        +CRYPTO_THREADID_set_callback            4346	EXIST::FUNCTION:
        +TS_CONF_set_serial                      4347	EXIST::FUNCTION:
        +TS_TST_INFO_free                        4348	EXIST::FUNCTION:
        +d2i_TS_REQ_fp                           4349	EXIST::FUNCTION:
        +TS_RESP_verify_response                 4350	EXIST::FUNCTION:
        +i2d_ESS_ISSUER_SERIAL                   4351	EXIST::FUNCTION:
        +TS_ACCURACY_get_seconds                 4352	EXIST::FUNCTION:
        +EVP_CIPHER_do_all                       4353	EXIST::FUNCTION:
        +b2i_PrivateKey_bio                      4354	EXIST::FUNCTION:
        +OCSP_CERTID_dup                         4355	EXIST::FUNCTION:
        +X509_PUBKEY_get0_param                  4356	EXIST::FUNCTION:
        +TS_MSG_IMPRINT_dup                      4357	EXIST::FUNCTION:
        +PKCS7_print_ctx                         4358	EXIST::FUNCTION:
        +i2d_TS_REQ_bio                          4359	EXIST::FUNCTION:
        +EVP_whirlpool                           4360	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
        +EVP_PKEY_asn1_set_param                 4361	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_encrypt               4362	EXIST::FUNCTION:
        +ASN1_PCTX_set_flags                     4363	EXIST::FUNCTION:
        +i2d_ESS_CERT_ID                         4364	EXIST::FUNCTION:
        +TS_VERIFY_CTX_new                       4365	EXIST::FUNCTION:
        +TS_RESP_CTX_set_extension_cb            4366	EXIST::FUNCTION:
        +ENGINE_register_all_pkey_meths          4367	EXIST::FUNCTION:ENGINE
        +TS_RESP_CTX_set_status_info_cond        4368	EXIST:!VMS:FUNCTION:
        +TS_RESP_CTX_set_stat_info_cond          4368	EXIST:VMS:FUNCTION:
        +EVP_PKEY_verify                         4369	EXIST::FUNCTION:
        +WHIRLPOOL_Final                         4370	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
        +X509_CRL_METHOD_new                     4371	EXIST::FUNCTION:
        +EVP_DigestSignFinal                     4372	EXIST::FUNCTION:
        +TS_RESP_CTX_set_def_policy              4373	EXIST::FUNCTION:
        +NETSCAPE_X509_it                        4374	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +NETSCAPE_X509_it                        4374	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +TS_RESP_create_response                 4375	EXIST::FUNCTION:
        +PKCS7_SIGNER_INFO_get0_algs             4376	EXIST::FUNCTION:
        +TS_TST_INFO_get_nonce                   4377	EXIST::FUNCTION:
        +EVP_PKEY_decrypt_old                    4378	EXIST::FUNCTION:
        +TS_TST_INFO_set_policy_id               4379	EXIST::FUNCTION:
        +TS_CONF_set_ess_cert_id_chain           4380	EXIST::FUNCTION:
        +EVP_PKEY_CTX_get0_pkey                  4381	EXIST::FUNCTION:
        +d2i_TS_REQ                              4382	EXIST::FUNCTION:
        +EVP_PKEY_asn1_find_str                  4383	EXIST::FUNCTION:
        +BIO_f_asn1                              4384	EXIST::FUNCTION:
        +ESS_SIGNING_CERT_new                    4385	EXIST::FUNCTION:
        +EVP_PBE_find                            4386	EXIST::FUNCTION:
        +X509_CRL_get0_by_cert                   4387	EXIST::FUNCTION:
        +EVP_PKEY_derive                         4388	EXIST::FUNCTION:
        +i2d_TS_REQ                              4389	EXIST::FUNCTION:
        +TS_TST_INFO_delete_ext                  4390	EXIST::FUNCTION:
        +ESS_ISSUER_SERIAL_free                  4391	EXIST::FUNCTION:
        +ASN1_PCTX_set_str_flags                 4392	EXIST::FUNCTION:
        +ENGINE_get_pkey_asn1_meth_str           4393	EXIST::FUNCTION:ENGINE
        +TS_CONF_set_signer_key                  4394	EXIST::FUNCTION:
        +TS_ACCURACY_get_millis                  4395	EXIST::FUNCTION:
        +TS_RESP_get_token                       4396	EXIST::FUNCTION:
        +TS_ACCURACY_dup                         4397	EXIST::FUNCTION:
        +ENGINE_register_all_pkey_asn1_meths     4398	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_reg_all_pkey_asn1_meths          4398	EXIST:VMS:FUNCTION:ENGINE
        +X509_CRL_set_default_method             4399	EXIST::FUNCTION:
        +CRYPTO_THREADID_hash                    4400	EXIST::FUNCTION:
        +CMS_ContentInfo_print_ctx               4401	EXIST::FUNCTION:CMS
        +TS_RESP_free                            4402	EXIST::FUNCTION:
        +ISSUING_DIST_POINT_free                 4403	EXIST::FUNCTION:
        +ESS_ISSUER_SERIAL_new                   4404	EXIST::FUNCTION:
        +CMS_add1_crl                            4405	EXIST::FUNCTION:CMS
        +PKCS7_add1_attrib_digest                4406	EXIST::FUNCTION:
        +TS_RESP_CTX_add_md                      4407	EXIST::FUNCTION:
        +TS_TST_INFO_dup                         4408	EXIST::FUNCTION:
        +ENGINE_set_pkey_asn1_meths              4409	EXIST::FUNCTION:ENGINE
        +PEM_write_bio_Parameters                4410	EXIST::FUNCTION:
        +TS_TST_INFO_get_accuracy                4411	EXIST::FUNCTION:
        +X509_CRL_get0_by_serial                 4412	EXIST::FUNCTION:
        +TS_TST_INFO_set_version                 4413	EXIST::FUNCTION:
        +TS_RESP_CTX_get_tst_info                4414	EXIST::FUNCTION:
        +TS_RESP_verify_signature                4415	EXIST::FUNCTION:
        +CRYPTO_THREADID_get_callback            4416	EXIST::FUNCTION:
        +TS_TST_INFO_get_tsa                     4417	EXIST::FUNCTION:
        +TS_STATUS_INFO_new                      4418	EXIST::FUNCTION:
        +EVP_PKEY_CTX_get_cb                     4419	EXIST::FUNCTION:
        +TS_REQ_get_ext_d2i                      4420	EXIST::FUNCTION:
        +GENERAL_NAME_set0_othername             4421	EXIST::FUNCTION:
        +TS_TST_INFO_get_ext_count               4422	EXIST::FUNCTION:
        +TS_RESP_CTX_get_request                 4423	EXIST::FUNCTION:
        +i2d_NETSCAPE_X509                       4424	EXIST::FUNCTION:
        +ENGINE_get_pkey_meth_engine             4425	EXIST::FUNCTION:ENGINE
        +EVP_PKEY_meth_set_signctx               4426	EXIST::FUNCTION:
        +EVP_PKEY_asn1_copy                      4427	EXIST::FUNCTION:
        +ASN1_TYPE_cmp                           4428	EXIST::FUNCTION:
        +EVP_CIPHER_do_all_sorted                4429	EXIST::FUNCTION:
        +EVP_PKEY_CTX_free                       4430	EXIST::FUNCTION:
        +ISSUING_DIST_POINT_it                   4431	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:
        +ISSUING_DIST_POINT_it                   4431	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:
        +d2i_TS_MSG_IMPRINT_fp                   4432	EXIST::FUNCTION:
        +X509_STORE_get1_certs                   4433	EXIST::FUNCTION:
        +EVP_PKEY_CTX_get_operation              4434	EXIST::FUNCTION:
        +d2i_ESS_SIGNING_CERT                    4435	EXIST::FUNCTION:
        +TS_CONF_set_ordering                    4436	EXIST::FUNCTION:
        +EVP_PBE_alg_add_type                    4437	EXIST::FUNCTION:
        +TS_REQ_set_version                      4438	EXIST::FUNCTION:
        +EVP_PKEY_get0                           4439	EXIST::FUNCTION:
        +BIO_asn1_set_suffix                     4440	EXIST::FUNCTION:
        +i2d_TS_STATUS_INFO                      4441	EXIST::FUNCTION:
        +EVP_MD_do_all                           4442	EXIST::FUNCTION:
        +TS_TST_INFO_set_accuracy                4443	EXIST::FUNCTION:
        +PKCS7_add_attrib_content_type           4444	EXIST::FUNCTION:
        +ERR_remove_thread_state                 4445	EXIST::FUNCTION:
        +EVP_PKEY_meth_add0                      4446	EXIST::FUNCTION:
        +TS_TST_INFO_set_tsa                     4447	EXIST::FUNCTION:
        +EVP_PKEY_meth_new                       4448	EXIST::FUNCTION:
        +WHIRLPOOL_Update                        4449	EXIST:!VMSVAX:FUNCTION:WHIRLPOOL
        +TS_CONF_set_accuracy                    4450	EXIST::FUNCTION:
        +ASN1_PCTX_set_oid_flags                 4451	EXIST::FUNCTION:
        +ESS_SIGNING_CERT_dup                    4452	EXIST::FUNCTION:
        +d2i_TS_REQ_bio                          4453	EXIST::FUNCTION:
        +X509_time_adj_ex                        4454	EXIST::FUNCTION:
        +TS_RESP_CTX_add_flags                   4455	EXIST::FUNCTION:
        +d2i_TS_STATUS_INFO                      4456	EXIST::FUNCTION:
        +TS_MSG_IMPRINT_set_msg                  4457	EXIST::FUNCTION:
        +BIO_asn1_get_suffix                     4458	EXIST::FUNCTION:
        +TS_REQ_free                             4459	EXIST::FUNCTION:
        +EVP_PKEY_meth_free                      4460	EXIST::FUNCTION:
        +TS_REQ_get_exts                         4461	EXIST::FUNCTION:
        +TS_RESP_CTX_set_clock_precision_digits  4462	EXIST:!VMS:FUNCTION:
        +TS_RESP_CTX_set_clk_prec_digits         4462	EXIST:VMS:FUNCTION:
        +TS_RESP_CTX_add_failure_info            4463	EXIST::FUNCTION:
        +i2d_TS_RESP_bio                         4464	EXIST::FUNCTION:
        +EVP_PKEY_CTX_get0_peerkey               4465	EXIST::FUNCTION:
        +PEM_write_bio_CMS_stream                4466	EXIST::FUNCTION:CMS
        +TS_REQ_new                              4467	EXIST::FUNCTION:
        +TS_MSG_IMPRINT_new                      4468	EXIST::FUNCTION:
        +EVP_PKEY_meth_find                      4469	EXIST::FUNCTION:
        +EVP_PKEY_id                             4470	EXIST::FUNCTION:
        +TS_TST_INFO_set_serial                  4471	EXIST::FUNCTION:
        +a2i_GENERAL_NAME                        4472	EXIST::FUNCTION:
        +TS_CONF_set_crypto_device               4473	EXIST::FUNCTION:
        +EVP_PKEY_verify_init                    4474	EXIST::FUNCTION:
        +TS_CONF_set_policies                    4475	EXIST::FUNCTION:
        +ASN1_PCTX_new                           4476	EXIST::FUNCTION:
        +ESS_CERT_ID_free                        4477	EXIST::FUNCTION:
        +ENGINE_unregister_pkey_meths            4478	EXIST::FUNCTION:ENGINE
        +TS_MSG_IMPRINT_free                     4479	EXIST::FUNCTION:
        +TS_VERIFY_CTX_init                      4480	EXIST::FUNCTION:
        +PKCS7_stream                            4481	EXIST::FUNCTION:
        +TS_RESP_CTX_set_certs                   4482	EXIST::FUNCTION:
        +TS_CONF_set_def_policy                  4483	EXIST::FUNCTION:
        +ASN1_GENERALIZEDTIME_adj                4484	EXIST::FUNCTION:
        +NETSCAPE_X509_new                       4485	EXIST::FUNCTION:
        +TS_ACCURACY_free                        4486	EXIST::FUNCTION:
        +TS_RESP_get_tst_info                    4487	EXIST::FUNCTION:
        +EVP_PKEY_derive_set_peer                4488	EXIST::FUNCTION:
        +PEM_read_bio_Parameters                 4489	EXIST::FUNCTION:
        +TS_CONF_set_clock_precision_digits      4490	EXIST:!VMS:FUNCTION:
        +TS_CONF_set_clk_prec_digits             4490	EXIST:VMS:FUNCTION:
        +ESS_ISSUER_SERIAL_dup                   4491	EXIST::FUNCTION:
        +TS_ACCURACY_get_micros                  4492	EXIST::FUNCTION:
        +ASN1_PCTX_get_str_flags                 4493	EXIST::FUNCTION:
        +NAME_CONSTRAINTS_check                  4494	EXIST::FUNCTION:
        +ASN1_BIT_STRING_check                   4495	EXIST::FUNCTION:
        +X509_check_akid                         4496	EXIST::FUNCTION:
        +ENGINE_unregister_pkey_asn1_meths       4497	EXIST:!VMS:FUNCTION:ENGINE
        +ENGINE_unreg_pkey_asn1_meths            4497	EXIST:VMS:FUNCTION:ENGINE
        +ASN1_PCTX_free                          4498	EXIST::FUNCTION:
        +PEM_write_bio_ASN1_stream               4499	EXIST::FUNCTION:
        +i2d_ASN1_bio_stream                     4500	EXIST::FUNCTION:
        +TS_X509_ALGOR_print_bio                 4501	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_cleanup               4502	EXIST::FUNCTION:
        +EVP_PKEY_asn1_free                      4503	EXIST::FUNCTION:
        +ESS_SIGNING_CERT_free                   4504	EXIST::FUNCTION:
        +TS_TST_INFO_set_msg_imprint             4505	EXIST::FUNCTION:
        +GENERAL_NAME_cmp                        4506	EXIST::FUNCTION:
        +d2i_ASN1_SET_ANY                        4507	EXIST::FUNCTION:
        +ENGINE_set_pkey_meths                   4508	EXIST::FUNCTION:ENGINE
        +i2d_TS_REQ_fp                           4509	EXIST::FUNCTION:
        +d2i_ASN1_SEQUENCE_ANY                   4510	EXIST::FUNCTION:
        +GENERAL_NAME_get0_otherName             4511	EXIST::FUNCTION:
        +d2i_ESS_CERT_ID                         4512	EXIST::FUNCTION:
        +OBJ_find_sigid_algs                     4513	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_keygen                4514	EXIST::FUNCTION:
        +PKCS5_PBKDF2_HMAC                       4515	EXIST::FUNCTION:
        +EVP_PKEY_paramgen                       4516	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_paramgen              4517	EXIST::FUNCTION:
        +BIO_new_PKCS7                           4518	EXIST::FUNCTION:
        +EVP_PKEY_verify_recover                 4519	EXIST::FUNCTION:
        +TS_ext_print_bio                        4520	EXIST::FUNCTION:
        +TS_ASN1_INTEGER_print_bio               4521	EXIST::FUNCTION:
        +check_defer                             4522	EXIST::FUNCTION:
        +DSO_pathbyaddr                          4523	EXIST::FUNCTION:
        +EVP_PKEY_set_type                       4524	EXIST::FUNCTION:
        +TS_ACCURACY_set_micros                  4525	EXIST::FUNCTION:
        +TS_REQ_to_TS_VERIFY_CTX                 4526	EXIST::FUNCTION:
        +EVP_PKEY_meth_set_copy                  4527	EXIST::FUNCTION:
        +ASN1_PCTX_set_cert_flags                4528	EXIST::FUNCTION:
        +TS_TST_INFO_get_ext                     4529	EXIST::FUNCTION:
        +EVP_PKEY_asn1_set_ctrl                  4530	EXIST::FUNCTION:
        +TS_TST_INFO_get_ext_by_critical         4531	EXIST::FUNCTION:
        +EVP_PKEY_CTX_new_id                     4532	EXIST::FUNCTION:
        +TS_REQ_get_ext_by_OBJ                   4533	EXIST::FUNCTION:
        +TS_CONF_set_signer_cert                 4534	EXIST::FUNCTION:
        +X509_NAME_hash_old                      4535	EXIST::FUNCTION:
        +ASN1_TIME_set_string                    4536	EXIST::FUNCTION:
        +EVP_MD_flags                            4537	EXIST::FUNCTION:
        +TS_RESP_CTX_free                        4538	EXIST::FUNCTION:
        +DSAparams_dup                           4539	EXIST::FUNCTION:DSA
        +DHparams_dup                            4540	EXIST::FUNCTION:DH
        +OCSP_REQ_CTX_add1_header                4541	EXIST::FUNCTION:
        +OCSP_REQ_CTX_set1_req                   4542	EXIST::FUNCTION:
        +X509_STORE_set_verify_cb                4543	EXIST::FUNCTION:
        +X509_STORE_CTX_get0_current_crl         4544	EXIST::FUNCTION:
        +X509_STORE_CTX_get0_parent_ctx          4545	EXIST::FUNCTION:
        +X509_STORE_CTX_get0_current_issuer      4546	EXIST:!VMS:FUNCTION:
        +X509_STORE_CTX_get0_cur_issuer          4546	EXIST:VMS:FUNCTION:
        +X509_issuer_name_hash_old               4547	EXIST::FUNCTION:MD5
        +X509_subject_name_hash_old              4548	EXIST::FUNCTION:MD5
        +EVP_CIPHER_CTX_copy                     4549	EXIST::FUNCTION:
        +UI_method_get_prompt_constructor        4550	EXIST:!VMS:FUNCTION:
        +UI_method_get_prompt_constructr         4550	EXIST:VMS:FUNCTION:
        +UI_method_set_prompt_constructor        4551	EXIST:!VMS:FUNCTION:
        +UI_method_set_prompt_constructr         4551	EXIST:VMS:FUNCTION:
        +EVP_read_pw_string_min                  4552	EXIST::FUNCTION:
        +CRYPTO_cts128_encrypt                   4553	EXIST::FUNCTION:
        +CRYPTO_cts128_decrypt_block             4554	EXIST::FUNCTION:
        +CRYPTO_cfb128_1_encrypt                 4555	EXIST::FUNCTION:
        +CRYPTO_cbc128_encrypt                   4556	EXIST::FUNCTION:
        +CRYPTO_ctr128_encrypt                   4557	EXIST::FUNCTION:
        +CRYPTO_ofb128_encrypt                   4558	EXIST::FUNCTION:
        +CRYPTO_cts128_decrypt                   4559	EXIST::FUNCTION:
        +CRYPTO_cts128_encrypt_block             4560	EXIST::FUNCTION:
        +CRYPTO_cbc128_decrypt                   4561	EXIST::FUNCTION:
        +CRYPTO_cfb128_encrypt                   4562	EXIST::FUNCTION:
        +CRYPTO_cfb128_8_encrypt                 4563	EXIST::FUNCTION:
        +OPENSSL_strcasecmp                      4564	EXIST::FUNCTION:
        +OPENSSL_memcmp                          4565	EXIST::FUNCTION:
        +OPENSSL_strncasecmp                     4566	EXIST::FUNCTION:
        +OPENSSL_gmtime                          4567	EXIST::FUNCTION:
        +OPENSSL_gmtime_adj                      4568	EXIST::FUNCTION:
        +SRP_VBASE_get_by_user                   4569	EXIST::FUNCTION:SRP
        +SRP_Calc_server_key                     4570	EXIST::FUNCTION:SRP
        +SRP_create_verifier                     4571	EXIST::FUNCTION:SRP
        +SRP_create_verifier_BN                  4572	EXIST::FUNCTION:SRP
        +SRP_Calc_u                              4573	EXIST::FUNCTION:SRP
        +SRP_VBASE_free                          4574	EXIST::FUNCTION:SRP
        +SRP_Calc_client_key                     4575	EXIST::FUNCTION:SRP
        +SRP_get_default_gN                      4576	EXIST::FUNCTION:SRP
        +SRP_Calc_x                              4577	EXIST::FUNCTION:SRP
        +SRP_Calc_B                              4578	EXIST::FUNCTION:SRP
        +SRP_VBASE_new                           4579	EXIST::FUNCTION:SRP
        +SRP_check_known_gN_param                4580	EXIST::FUNCTION:SRP
        +SRP_Calc_A                              4581	EXIST::FUNCTION:SRP
        +SRP_Verify_A_mod_N                      4582	EXIST::FUNCTION:SRP
        +SRP_VBASE_init                          4583	EXIST::FUNCTION:SRP
        +SRP_Verify_B_mod_N                      4584	EXIST::FUNCTION:SRP
        +EC_KEY_set_public_key_affine_coordinates 4585	EXIST:!VMS:FUNCTION:EC
        +EC_KEY_set_pub_key_aff_coords           4585	EXIST:VMS:FUNCTION:EC
        +EVP_aes_192_ctr                         4586	EXIST::FUNCTION:AES
        +EVP_PKEY_meth_get0_info                 4587	EXIST::FUNCTION:
        +EVP_PKEY_meth_copy                      4588	EXIST::FUNCTION:
        +ERR_add_error_vdata                     4589	EXIST::FUNCTION:
        +EVP_aes_128_ctr                         4590	EXIST::FUNCTION:AES
        +EVP_aes_256_ctr                         4591	EXIST::FUNCTION:AES
        +EC_GFp_nistp224_method                  4592	EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128
        +EC_KEY_get_flags                        4593	EXIST::FUNCTION:EC
        +RSA_padding_add_PKCS1_PSS_mgf1          4594	EXIST::FUNCTION:RSA
        +EVP_aes_128_xts                         4595	EXIST::FUNCTION:AES
        +private_SHA224_Init                     4596	EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA256
        +private_AES_set_decrypt_key             4597	EXIST::FUNCTION:AES
        +private_WHIRLPOOL_Init                  4598	EXIST:OPENSSL_FIPS:FUNCTION:WHIRLPOOL
        +EVP_aes_256_xts                         4599	EXIST::FUNCTION:AES
        +private_SHA512_Init                     4600	EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA512
        +EVP_aes_128_gcm                         4601	EXIST::FUNCTION:AES
        +EC_KEY_clear_flags                      4602	EXIST::FUNCTION:EC
        +EC_KEY_set_flags                        4603	EXIST::FUNCTION:EC
        +private_DES_set_key_unchecked           4604	EXIST:OPENSSL_FIPS:FUNCTION:DES
        +EVP_aes_256_ccm                         4605	EXIST::FUNCTION:AES
        +private_AES_set_encrypt_key             4606	EXIST::FUNCTION:AES
        +RSA_verify_PKCS1_PSS_mgf1               4607	EXIST::FUNCTION:RSA
        +private_SHA1_Init                       4608	EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA1
        +EVP_aes_128_ccm                         4609	EXIST::FUNCTION:AES
        +private_SEED_set_key                    4610	EXIST:OPENSSL_FIPS:FUNCTION:SEED
        +EVP_aes_192_gcm                         4611	EXIST::FUNCTION:AES
        +X509_ALGOR_set_md                       4612	EXIST::FUNCTION:
        +private_SHA256_Init                     4613	EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA256
        +RAND_init_fips                          4614	EXIST:OPENSSL_FIPS:FUNCTION:
        +EVP_aes_256_gcm                         4615	EXIST::FUNCTION:AES
        +private_SHA384_Init                     4616	EXIST:OPENSSL_FIPS:FUNCTION:SHA,SHA512
        +EVP_aes_192_ccm                         4617	EXIST::FUNCTION:AES
        +CMAC_CTX_copy                           4618	EXIST::FUNCTION:
        +CMAC_CTX_free                           4619	EXIST::FUNCTION:
        +CMAC_CTX_get0_cipher_ctx                4620	EXIST::FUNCTION:
        +CMAC_CTX_cleanup                        4621	EXIST::FUNCTION:
        +CMAC_Init                               4622	EXIST::FUNCTION:
        +CMAC_Update                             4623	EXIST::FUNCTION:
        +CMAC_resume                             4624	EXIST::FUNCTION:
        +CMAC_CTX_new                            4625	EXIST::FUNCTION:
        +CMAC_Final                              4626	EXIST::FUNCTION:
        +CRYPTO_ctr128_encrypt_ctr32             4627	EXIST::FUNCTION:
        +CRYPTO_gcm128_release                   4628	EXIST::FUNCTION:
        +CRYPTO_ccm128_decrypt_ccm64             4629	EXIST::FUNCTION:
        +CRYPTO_ccm128_encrypt                   4630	EXIST::FUNCTION:
        +CRYPTO_gcm128_encrypt                   4631	EXIST::FUNCTION:
        +CRYPTO_xts128_encrypt                   4632	EXIST::FUNCTION:
        +EVP_rc4_hmac_md5                        4633	EXIST::FUNCTION:MD5,RC4
        +CRYPTO_nistcts128_decrypt_block         4634	EXIST::FUNCTION:
        +CRYPTO_gcm128_setiv                     4635	EXIST::FUNCTION:
        +CRYPTO_nistcts128_encrypt               4636	EXIST::FUNCTION:
        +EVP_aes_128_cbc_hmac_sha1               4637	EXIST::FUNCTION:AES,SHA,SHA1
        +CRYPTO_gcm128_tag                       4638	EXIST::FUNCTION:
        +CRYPTO_ccm128_encrypt_ccm64             4639	EXIST::FUNCTION:
        +ENGINE_load_rdrand                      4640	EXIST::FUNCTION:ENGINE
        +CRYPTO_ccm128_setiv                     4641	EXIST::FUNCTION:
        +CRYPTO_nistcts128_encrypt_block         4642	EXIST::FUNCTION:
        +CRYPTO_gcm128_aad                       4643	EXIST::FUNCTION:
        +CRYPTO_ccm128_init                      4644	EXIST::FUNCTION:
        +CRYPTO_nistcts128_decrypt               4645	EXIST::FUNCTION:
        +CRYPTO_gcm128_new                       4646	EXIST::FUNCTION:
        +CRYPTO_ccm128_tag                       4647	EXIST::FUNCTION:
        +CRYPTO_ccm128_decrypt                   4648	EXIST::FUNCTION:
        +CRYPTO_ccm128_aad                       4649	EXIST::FUNCTION:
        +CRYPTO_gcm128_init                      4650	EXIST::FUNCTION:
        +CRYPTO_gcm128_decrypt                   4651	EXIST::FUNCTION:
        +ENGINE_load_rsax                        4652	EXIST::FUNCTION:ENGINE
        +CRYPTO_gcm128_decrypt_ctr32             4653	EXIST::FUNCTION:
        +CRYPTO_gcm128_encrypt_ctr32             4654	EXIST::FUNCTION:
        +CRYPTO_gcm128_finish                    4655	EXIST::FUNCTION:
        +EVP_aes_256_cbc_hmac_sha1               4656	EXIST::FUNCTION:AES,SHA,SHA1
        +PKCS5_pbkdf2_set                        4657	EXIST::FUNCTION:
        +CMS_add0_recipient_password             4658	EXIST::FUNCTION:CMS
        +CMS_decrypt_set1_password               4659	EXIST::FUNCTION:CMS
        +CMS_RecipientInfo_set0_password         4660	EXIST::FUNCTION:CMS
        +RAND_set_fips_drbg_type                 4661	EXIST:OPENSSL_FIPS:FUNCTION:
        +X509_REQ_sign_ctx                       4662	EXIST::FUNCTION:EVP
        +RSA_PSS_PARAMS_new                      4663	EXIST::FUNCTION:RSA
        +X509_CRL_sign_ctx                       4664	EXIST::FUNCTION:EVP
        +X509_signature_dump                     4665	EXIST::FUNCTION:EVP
        +d2i_RSA_PSS_PARAMS                      4666	EXIST::FUNCTION:RSA
        +RSA_PSS_PARAMS_it                       4667	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA
        +RSA_PSS_PARAMS_it                       4667	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:RSA
        +RSA_PSS_PARAMS_free                     4668	EXIST::FUNCTION:RSA
        +X509_sign_ctx                           4669	EXIST::FUNCTION:EVP
        +i2d_RSA_PSS_PARAMS                      4670	EXIST::FUNCTION:RSA
        +ASN1_item_sign_ctx                      4671	EXIST::FUNCTION:EVP
        +EC_GFp_nistp521_method                  4672	EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128
        +EC_GFp_nistp256_method                  4673	EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128
        +OPENSSL_stderr                          4674	EXIST::FUNCTION:
        +OPENSSL_cpuid_setup                     4675	EXIST::FUNCTION:
        +OPENSSL_showfatal                       4676	EXIST::FUNCTION:
        +BIO_new_dgram_sctp                      4677	EXIST::FUNCTION:SCTP
        +BIO_dgram_sctp_msg_waiting              4678	EXIST::FUNCTION:SCTP
        +BIO_dgram_sctp_wait_for_dry             4679	EXIST::FUNCTION:SCTP
        +BIO_s_datagram_sctp                     4680	EXIST::FUNCTION:DGRAM,SCTP
        +BIO_dgram_is_sctp                       4681	EXIST::FUNCTION:SCTP
        +BIO_dgram_sctp_notification_cb          4682	EXIST::FUNCTION:SCTP
        diff --git a/vendor/openssl/openssl/util/mk1mf.pl b/vendor/openssl/openssl/util/mk1mf.pl
        new file mode 100644
        index 000000000..72fa089f6
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mk1mf.pl
        @@ -0,0 +1,1231 @@
        +#!/usr/local/bin/perl
        +# A bit of an evil hack but it post processes the file ../MINFO which
        +# is generated by `make files` in the top directory.
        +# This script outputs one mega makefile that has no shell stuff or any
        +# funny stuff
        +#
        +
        +$INSTALLTOP="/usr/local/ssl";
        +$OPENSSLDIR="/usr/local/ssl";
        +$OPTIONS="";
        +$ssl_version="";
        +$banner="\t\@echo Building OpenSSL";
        +
        +my $no_static_engine = 1;
        +my $engines = "";
        +my $otherlibs = "";
        +local $zlib_opt = 0;	# 0 = no zlib, 1 = static, 2 = dynamic
        +local $zlib_lib = "";
        +local $perl_asm = 0;	# 1 to autobuild asm files from perl scripts
        +
        +my $ex_l_libs = "";
        +
        +# Options to import from top level Makefile
        +
        +my %mf_import = (
        +	VERSION	       => \$ssl_version,
        +	OPTIONS        => \$OPTIONS,
        +	INSTALLTOP     => \$INSTALLTOP,
        +	OPENSSLDIR     => \$OPENSSLDIR,
        +	PLATFORM       => \$mf_platform,
        +	CFLAG	       => \$mf_cflag,
        +	DEPFLAG	       => \$mf_depflag,
        +	CPUID_OBJ      => \$mf_cpuid_asm,
        +	BN_ASM	       => \$mf_bn_asm,
        +	DES_ENC	       => \$mf_des_asm,
        +	AES_ENC        => \$mf_aes_asm,
        +	BF_ENC	       => \$mf_bf_asm,
        +	CAST_ENC       => \$mf_cast_asm,
        +	RC4_ENC	       => \$mf_rc4_asm,
        +	RC5_ENC        => \$mf_rc5_asm,
        +	MD5_ASM_OBJ    => \$mf_md5_asm,
        +	SHA1_ASM_OBJ   => \$mf_sha_asm,
        +	RMD160_ASM_OBJ => \$mf_rmd_asm,
        +	WP_ASM_OBJ     => \$mf_wp_asm,
        +	CMLL_ENC       => \$mf_cm_asm,
        +	BASEADDR       => \$baseaddr,
        +	FIPSDIR        => \$fipsdir,
        +);
        +
        +
        +open(IN,"<Makefile") || die "unable to open Makefile!\n";
        +while(<IN>) {
        +    my ($mf_opt, $mf_ref);
        +    while (($mf_opt, $mf_ref) = each %mf_import) {
        +    	if (/^$mf_opt\s*=\s*(.*)$/) {
        +	   $$mf_ref = $1;
        +	}
        +    }
        +}
        +close(IN);
        +
        +$debug = 1 if $mf_platform =~ /^debug-/;
        +
        +die "Makefile is not the toplevel Makefile!\n" if $ssl_version eq "";
        +
        +$infile="MINFO";
        +
        +%ops=(
        +	"VC-WIN32",   "Microsoft Visual C++ [4-6] - Windows NT or 9X",
        +	"VC-WIN64I",  "Microsoft C/C++ - Win64/IA-64",
        +	"VC-WIN64A",  "Microsoft C/C++ - Win64/x64",
        +	"VC-CE",   "Microsoft eMbedded Visual C++ 3.0 - Windows CE ONLY",
        +	"VC-NT",   "Microsoft Visual C++ [4-6] - Windows NT ONLY",
        +	"Mingw32", "GNU C++ - Windows NT or 9x",
        +	"Mingw32-files", "Create files with DOS copy ...",
        +	"BC-NT",   "Borland C++ 4.5 - Windows NT",
        +	"linux-elf","Linux elf",
        +	"ultrix-mips","DEC mips ultrix",
        +	"FreeBSD","FreeBSD distribution",
        +	"OS2-EMX", "EMX GCC OS/2",
        +	"netware-clib", "CodeWarrior for NetWare - CLib - with WinSock Sockets",
        +	"netware-clib-bsdsock", "CodeWarrior for NetWare - CLib - with BSD Sockets",
        +	"netware-libc", "CodeWarrior for NetWare - LibC - with WinSock Sockets",
        +	"netware-libc-bsdsock", "CodeWarrior for NetWare - LibC - with BSD Sockets",
        +	"default","cc under unix",
        +	"auto", "auto detect from top level Makefile"
        +	);
        +
        +$platform="";
        +my $xcflags="";
        +foreach (@ARGV)
        +	{
        +	if (!&read_options && !defined($ops{$_}))
        +		{
        +		print STDERR "unknown option - $_\n";
        +		print STDERR "usage: perl mk1mf.pl [options] [system]\n";
        +		print STDERR "\nwhere [system] can be one of the following\n";
        +		foreach $i (sort keys %ops)
        +		{ printf STDERR "\t%-10s\t%s\n",$i,$ops{$i}; }
        +		print STDERR <<"EOF";
        +and [options] can be one of
        +	no-md2 no-md4 no-md5 no-sha no-mdc2	- Skip this digest
        +	no-ripemd
        +	no-rc2 no-rc4 no-rc5 no-idea no-des     - Skip this symetric cipher
        +	no-bf no-cast no-aes no-camellia no-seed
        +	no-rsa no-dsa no-dh			- Skip this public key cipher
        +	no-ssl2 no-ssl3				- Skip this version of SSL
        +	just-ssl				- remove all non-ssl keys/digest
        +	no-asm 					- No x86 asm
        +	no-krb5					- No KRB5
        +	no-srp					- No SRP
        +	no-ec					- No EC
        +	no-ecdsa				- No ECDSA
        +	no-ecdh					- No ECDH
        +	no-engine				- No engine
        +	no-hw					- No hw
        +	nasm 					- Use NASM for x86 asm
        +	nw-nasm					- Use NASM x86 asm for NetWare
        +	nw-mwasm				- Use Metrowerks x86 asm for NetWare
        +	gaswin					- Use GNU as with Mingw32
        +	no-socks				- No socket code
        +	no-err					- No error strings
        +	dll/shlib				- Build shared libraries (MS)
        +	debug					- Debug build
        +        profile                                 - Profiling build
        +	gcc					- Use Gcc (unix)
        +
        +Values that can be set
        +TMP=tmpdir OUT=outdir SRC=srcdir BIN=binpath INC=header-outdir CC=C-compiler
        +
        +-L<ex_lib_path> -l<ex_lib>			- extra library flags (unix)
        +-<ex_cc_flags>					- extra 'cc' flags,
        +						  added (MS), or replace (unix)
        +EOF
        +		exit(1);
        +		}
        +	$platform=$_;
        +	}
        +foreach (grep(!/^$/, split(/ /, $OPTIONS)))
        +	{
        +	print STDERR "unknown option - $_\n" if !&read_options;
        +	}
        +
        +$no_static_engine = 0 if (!$shlib);
        +
        +$no_mdc2=1 if ($no_des);
        +
        +$no_ssl3=1 if ($no_md5 || $no_sha);
        +$no_ssl3=1 if ($no_rsa && $no_dh);
        +
        +$no_ssl2=1 if ($no_md5);
        +$no_ssl2=1 if ($no_rsa);
        +
        +$out_def="out";
        +$inc_def="outinc";
        +$tmp_def="tmp";
        +
        +$perl="perl" unless defined $perl;
        +$mkdir="-mkdir" unless defined $mkdir;
        +
        +($ssl,$crypto)=("ssl","crypto");
        +$ranlib="echo ranlib";
        +
        +$cc=(defined($VARS{'CC'}))?$VARS{'CC'}:'cc';
        +$src_dir=(defined($VARS{'SRC'}))?$VARS{'SRC'}:'.';
        +$bin_dir=(defined($VARS{'BIN'}))?$VARS{'BIN'}:'';
        +
        +# $bin_dir.=$o causes a core dump on my sparc :-(
        +
        +
        +$NT=0;
        +
        +push(@INC,"util/pl","pl");
        +
        +if ($platform eq "auto") {
        +	$platform = $mf_platform;
        +	print STDERR "Imported platform $mf_platform\n";
        +}
        +
        +if (($platform =~ /VC-(.+)/))
        +	{
        +	$FLAVOR=$1;
        +	$NT = 1 if $1 eq "NT";
        +	require 'VC-32.pl';
        +	}
        +elsif ($platform eq "Mingw32")
        +	{
        +	require 'Mingw32.pl';
        +	}
        +elsif ($platform eq "Mingw32-files")
        +	{
        +	require 'Mingw32f.pl';
        +	}
        +elsif ($platform eq "BC-NT")
        +	{
        +	$bc=1;
        +	require 'BC-32.pl';
        +	}
        +elsif ($platform eq "FreeBSD")
        +	{
        +	require 'unix.pl';
        +	$cflags='-DTERMIO -D_ANSI_SOURCE -O2 -fomit-frame-pointer';
        +	}
        +elsif ($platform eq "linux-elf")
        +	{
        +	require "unix.pl";
        +	require "linux.pl";
        +	$unix=1;
        +	}
        +elsif ($platform eq "ultrix-mips")
        +	{
        +	require "unix.pl";
        +	require "ultrix.pl";
        +	$unix=1;
        +	}
        +elsif ($platform eq "OS2-EMX")
        +	{
        +	$wc=1;
        +	require 'OS2-EMX.pl';
        +	}
        +elsif (($platform eq "netware-clib") || ($platform eq "netware-libc") ||
        +       ($platform eq "netware-clib-bsdsock") || ($platform eq "netware-libc-bsdsock"))
        +	{
        +	$LIBC=1 if $platform eq "netware-libc" || $platform eq "netware-libc-bsdsock";
        +	$BSDSOCK=1 if ($platform eq "netware-libc-bsdsock") || ($platform eq "netware-clib-bsdsock");
        +	require 'netware.pl';
        +	}
        +else
        +	{
        +	require "unix.pl";
        +
        +	$unix=1;
        +	$cflags.=' -DTERMIO';
        +	}
        +
        +$fipsdir =~ s/\//${o}/g;
        +
        +$out_dir=(defined($VARS{'OUT'}))?$VARS{'OUT'}:$out_def.($debug?".dbg":"");
        +$tmp_dir=(defined($VARS{'TMP'}))?$VARS{'TMP'}:$tmp_def.($debug?".dbg":"");
        +$inc_dir=(defined($VARS{'INC'}))?$VARS{'INC'}:$inc_def;
        +
        +$bin_dir=$bin_dir.$o unless ((substr($bin_dir,-1,1) eq $o) || ($bin_dir eq ''));
        +
        +$cflags= "$xcflags$cflags" if $xcflags ne "";
        +
        +$cflags.=" -DOPENSSL_NO_IDEA" if $no_idea;
        +$cflags.=" -DOPENSSL_NO_AES"  if $no_aes;
        +$cflags.=" -DOPENSSL_NO_CAMELLIA"  if $no_camellia;
        +$cflags.=" -DOPENSSL_NO_SEED" if $no_seed;
        +$cflags.=" -DOPENSSL_NO_RC2"  if $no_rc2;
        +$cflags.=" -DOPENSSL_NO_RC4"  if $no_rc4;
        +$cflags.=" -DOPENSSL_NO_RC5"  if $no_rc5;
        +$cflags.=" -DOPENSSL_NO_MD2"  if $no_md2;
        +$cflags.=" -DOPENSSL_NO_MD4"  if $no_md4;
        +$cflags.=" -DOPENSSL_NO_MD5"  if $no_md5;
        +$cflags.=" -DOPENSSL_NO_SHA"  if $no_sha;
        +$cflags.=" -DOPENSSL_NO_SHA1" if $no_sha1;
        +$cflags.=" -DOPENSSL_NO_RIPEMD" if $no_ripemd;
        +$cflags.=" -DOPENSSL_NO_MDC2" if $no_mdc2;
        +$cflags.=" -DOPENSSL_NO_BF"  if $no_bf;
        +$cflags.=" -DOPENSSL_NO_CAST" if $no_cast;
        +$cflags.=" -DOPENSSL_NO_DES"  if $no_des;
        +$cflags.=" -DOPENSSL_NO_RSA"  if $no_rsa;
        +$cflags.=" -DOPENSSL_NO_DSA"  if $no_dsa;
        +$cflags.=" -DOPENSSL_NO_DH"   if $no_dh;
        +$cflags.=" -DOPENSSL_NO_WHIRLPOOL"   if $no_whirlpool;
        +$cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
        +$cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
        +$cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
        +$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
        +$cflags.=" -DOPENSSL_NO_SRP" if $no_srp;
        +$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
        +$cflags.=" -DOPENSSL_NO_ERR"  if $no_err;
        +$cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
        +$cflags.=" -DOPENSSL_NO_EC"   if $no_ec;
        +$cflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
        +$cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
        +$cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
        +$cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
        +$cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
        +$cflags.=" -DOPENSSL_FIPS"    if $fips;
        +$cflags.=" -DOPENSSL_NO_JPAKE"    if $no_jpake;
        +$cflags.=" -DOPENSSL_NO_EC2M"    if $no_ec2m;
        +$cflags.= " -DZLIB" if $zlib_opt;
        +$cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
        +
        +if ($no_static_engine)
        +	{
        +	$cflags .= " -DOPENSSL_NO_STATIC_ENGINE";
        +	}
        +else
        +	{
        +	$cflags .= " -DOPENSSL_NO_DYNAMIC_ENGINE";
        +	}
        +
        +#$cflags.=" -DRSAref"  if $rsaref ne "";
        +
        +## if ($unix)
        +##	{ $cflags="$c_flags" if ($c_flags ne ""); }
        +##else
        +	{ $cflags="$c_flags$cflags" if ($c_flags ne ""); }
        +
        +$ex_libs="$l_flags$ex_libs" if ($l_flags ne "");
        +
        +
        +%shlib_ex_cflags=("SSL" => " -DOPENSSL_BUILD_SHLIBSSL",
        +		  "CRYPTO" => " -DOPENSSL_BUILD_SHLIBCRYPTO");
        +
        +if ($msdos)
        +	{
        +	$banner ="\t\@echo Make sure you have run 'perl Configure $platform' in the\n";
        +	$banner.="\t\@echo top level directory, if you don't have perl, you will\n";
        +	$banner.="\t\@echo need to probably edit crypto/bn/bn.h, check the\n";
        +	$banner.="\t\@echo documentation for details.\n";
        +	}
        +
        +# have to do this to allow $(CC) under unix
        +$link="$bin_dir$link" if ($link !~ /^\$/);
        +
        +$INSTALLTOP =~ s|/|$o|g;
        +$OPENSSLDIR =~ s|/|$o|g;
        +
        +#############################################
        +# We parse in input file and 'store' info for later printing.
        +open(IN,"<$infile") || die "unable to open $infile:$!\n";
        +$_=<IN>;
        +for (;;)
        +	{
        +	chop;
        +
        +	($key,$val)=/^([^=]+)=(.*)/;
        +	if ($key eq "RELATIVE_DIRECTORY")
        +		{
        +		if ($lib ne "")
        +			{
        +			$uc=$lib;
        +			$uc =~ s/^lib(.*)\.a/$1/;
        +			$uc =~ tr/a-z/A-Z/;
        +			$lib_nam{$uc}=$uc;
        +			$lib_obj{$uc}.=$libobj." ";
        +			}
        +		last if ($val eq "FINISHED");
        +		$lib="";
        +		$libobj="";
        +		$dir=$val;
        +		}
        +
        +	if ($key eq "KRB5_INCLUDES")
        +		{ $cflags .= " $val";}
        +
        +	if ($key eq "ZLIB_INCLUDE")
        +		{ $cflags .= " $val" if $val ne "";}
        +
        +	if ($key eq "LIBZLIB")
        +		{ $zlib_lib = "$val" if $val ne "";}
        +
        +	if ($key eq "LIBKRB5")
        +		{ $ex_libs .= " $val" if $val ne "";}
        +
        +	if ($key eq "TEST")
        +		{ $test.=&var_add($dir,$val, 0); }
        +
        +	if (($key eq "PROGS") || ($key eq "E_OBJ"))
        +		{ $e_exe.=&var_add($dir,$val, 0); }
        +
        +	if ($key eq "LIB")
        +		{
        +		$lib=$val;
        +		$lib =~ s/^.*\/([^\/]+)$/$1/;
        +		}
        +	if ($key eq "LIBNAME" && $no_static_engine)
        +		{
        +		$lib=$val;
        +		$lib =~ s/^.*\/([^\/]+)$/$1/;
        +		$otherlibs .= " $lib";
        +		}
        +
        +	if ($key eq "EXHEADER")
        +		{ $exheader.=&var_add($dir,$val, 1); }
        +
        +	if ($key eq "HEADER")
        +		{ $header.=&var_add($dir,$val, 1); }
        +
        +	if ($key eq "LIBOBJ" && ($dir ne "engines" || !$no_static_engine))
        +		{ $libobj=&var_add($dir,$val, 0); }
        +	if ($key eq "LIBNAMES" && $dir eq "engines" && $no_static_engine)
        + 		{ $engines.=$val }
        +
        +	if (!($_=<IN>))
        +		{ $_="RELATIVE_DIRECTORY=FINISHED\n"; }
        +	}
        +close(IN);
        +
        +if ($shlib)
        +	{
        +	$extra_install= <<"EOF";
        +	\$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}bin\"
        +	\$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}bin\"
        +	\$(CP) \"\$(L_SSL)\" \"\$(INSTALLTOP)${o}lib\"
        +	\$(CP) \"\$(L_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
        +EOF
        +	if ($no_static_engine)
        +		{
        +		$extra_install .= <<"EOF"
        +	\$(MKDIR) \"\$(INSTALLTOP)${o}lib${o}engines\"
        +	\$(CP) \"\$(E_SHLIB)\" \"\$(INSTALLTOP)${o}lib${o}engines\"
        +EOF
        +		}
        +	}
        +else
        +	{
        +	$extra_install= <<"EOF";
        +	\$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}lib\"
        +	\$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
        +EOF
        +	$ex_libs .= " $zlib_lib" if $zlib_opt == 1;
        +	if ($fips)
        +		{
        +		$build_targets .= " \$(LIB_D)$o$crypto_compat \$(PREMAIN_DSO_EXE)";
        +		$ex_l_libs .= " \$(O_FIPSCANISTER)";
        +		}
        +	}
        +
        +$defs= <<"EOF";
        +# This makefile has been automatically generated from the OpenSSL distribution.
        +# This single makefile will build the complete OpenSSL distribution and
        +# by default leave the 'intertesting' output files in .${o}out and the stuff
        +# that needs deleting in .${o}tmp.
        +# The file was generated by running 'make makefile.one', which
        +# does a 'make files', which writes all the environment variables from all
        +# the makefiles to the file call MINFO.  This file is used by
        +# util${o}mk1mf.pl to generate makefile.one.
        +# The 'makefile per directory' system suites me when developing this
        +# library and also so I can 'distribute' indervidual library sections.
        +# The one monster makefile better suits building in non-unix
        +# environments.
        +
        +EOF
        +
        +$defs .= $preamble if defined $preamble;
        +
        +$defs.= <<"EOF";
        +INSTALLTOP=$INSTALLTOP
        +OPENSSLDIR=$OPENSSLDIR
        +
        +# Set your compiler options
        +PLATFORM=$platform
        +CC=$bin_dir${cc}
        +CFLAG=$cflags
        +APP_CFLAG=$app_cflag
        +LIB_CFLAG=$lib_cflag
        +SHLIB_CFLAG=$shl_cflag
        +APP_EX_OBJ=$app_ex_obj
        +SHLIB_EX_OBJ=$shlib_ex_obj
        +# add extra libraries to this define, for solaris -lsocket -lnsl would
        +# be added
        +EX_LIBS=$ex_libs
        +
        +# The OpenSSL directory
        +SRC_D=$src_dir
        +
        +LINK=$link
        +LFLAGS=$lflags
        +RSC=$rsc
        +
        +# The output directory for everything intersting
        +OUT_D=$out_dir
        +# The output directory for all the temporary muck
        +TMP_D=$tmp_dir
        +# The output directory for the header files
        +INC_D=$inc_dir
        +INCO_D=$inc_dir${o}openssl
        +
        +PERL=$perl
        +CP=$cp
        +RM=$rm
        +RANLIB=$ranlib
        +MKDIR=$mkdir
        +MKLIB=$bin_dir$mklib
        +MLFLAGS=$mlflags
        +ASM=$bin_dir$asm
        +
        +# FIPS validated module and support file locations
        +
        +FIPSDIR=$fipsdir
        +BASEADDR=$baseaddr
        +FIPSLIB_D=\$(FIPSDIR)${o}lib
        +FIPS_PREMAIN_SRC=\$(FIPSLIB_D)${o}fips_premain.c
        +O_FIPSCANISTER=\$(FIPSLIB_D)${o}fipscanister.lib
        +FIPS_SHA1_EXE=\$(FIPSDIR)${o}bin${o}fips_standalone_sha1${exep}
        +E_PREMAIN_DSO=fips_premain_dso
        +PREMAIN_DSO_EXE=\$(BIN_D)${o}fips_premain_dso$exep
        +FIPSLINK=\$(PERL) \$(FIPSDIR)${o}bin${o}fipslink.pl
        +
        +######################################################
        +# You should not need to touch anything below this point
        +######################################################
        +
        +E_EXE=openssl
        +SSL=$ssl
        +CRYPTO=$crypto
        +
        +# BIN_D  - Binary output directory
        +# TEST_D - Binary test file output directory
        +# LIB_D  - library output directory
        +# ENG_D  - dynamic engine output directory
        +# Note: if you change these point to different directories then uncomment out
        +# the lines around the 'NB' comment below.
        +# 
        +BIN_D=\$(OUT_D)
        +TEST_D=\$(OUT_D)
        +LIB_D=\$(OUT_D)
        +ENG_D=\$(OUT_D)
        +
        +# INCL_D - local library directory
        +# OBJ_D  - temp object file directory
        +OBJ_D=\$(TMP_D)
        +INCL_D=\$(TMP_D)
        +
        +O_SSL=     \$(LIB_D)$o$plib\$(SSL)$shlibp
        +O_CRYPTO=  \$(LIB_D)$o$plib\$(CRYPTO)$shlibp
        +SO_SSL=    $plib\$(SSL)$so_shlibp
        +SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp
        +L_SSL=     \$(LIB_D)$o$plib\$(SSL)$libp
        +L_CRYPTO=  \$(LIB_D)$o$plib\$(CRYPTO)$libp
        +
        +L_LIBS= \$(L_SSL) \$(L_CRYPTO) $ex_l_libs
        +
        +######################################################
        +# Don't touch anything below this point
        +######################################################
        +
        +INC=-I\$(INC_D) -I\$(INCL_D)
        +APP_CFLAGS=\$(INC) \$(CFLAG) \$(APP_CFLAG)
        +LIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG)
        +SHLIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG) \$(SHLIB_CFLAG)
        +LIBS_DEP=\$(O_CRYPTO) \$(O_SSL)
        +
        +#############################################
        +EOF
        +
        +$rules=<<"EOF";
        +all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe $build_targets
        +
        +banner:
        +$banner
        +
        +\$(TMP_D):
        +	\$(MKDIR) \"\$(TMP_D)\"
        +# NB: uncomment out these lines if BIN_D, TEST_D and LIB_D are different
        +#\$(BIN_D):
        +#	\$(MKDIR) \$(BIN_D)
        +#
        +#\$(TEST_D):
        +#	\$(MKDIR) \$(TEST_D)
        +
        +\$(LIB_D):
        +	\$(MKDIR) \"\$(LIB_D)\"
        +
        +\$(INCO_D): \$(INC_D)
        +	\$(MKDIR) \"\$(INCO_D)\"
        +
        +\$(INC_D):
        +	\$(MKDIR) \"\$(INC_D)\"
        +
        +headers: \$(HEADER) \$(EXHEADER)
        +	@
        +
        +lib: \$(LIBS_DEP) \$(E_SHLIB)
        +
        +exe: \$(T_EXE) \$(BIN_D)$o\$(E_EXE)$exep
        +
        +install: all
        +	\$(MKDIR) \"\$(INSTALLTOP)\"
        +	\$(MKDIR) \"\$(INSTALLTOP)${o}bin\"
        +	\$(MKDIR) \"\$(INSTALLTOP)${o}include\"
        +	\$(MKDIR) \"\$(INSTALLTOP)${o}include${o}openssl\"
        +	\$(MKDIR) \"\$(INSTALLTOP)${o}lib\"
        +	\$(CP) \"\$(INCO_D)${o}*.\[ch\]\" \"\$(INSTALLTOP)${o}include${o}openssl\"
        +	\$(CP) \"\$(BIN_D)$o\$(E_EXE)$exep \$(INSTALLTOP)${o}bin\"
        +	\$(MKDIR) \"\$(OPENSSLDIR)\"
        +	\$(CP) apps${o}openssl.cnf \"\$(OPENSSLDIR)\"
        +$extra_install
        +
        +
        +test: \$(T_EXE)
        +	cd \$(BIN_D)
        +	..${o}ms${o}test
        +
        +clean:
        +	\$(RM) \$(TMP_D)$o*.*
        +
        +vclean:
        +	\$(RM) \$(TMP_D)$o*.*
        +	\$(RM) \$(OUT_D)$o*.*
        +
        +EOF
        +    
        +my $platform_cpp_symbol = "MK1MF_PLATFORM_$platform";
        +$platform_cpp_symbol =~ s/-/_/g;
        +if (open(IN,"crypto/buildinf.h"))
        +	{
        +	# Remove entry for this platform in existing file buildinf.h.
        +
        +	my $old_buildinf_h = "";
        +	while (<IN>)
        +		{
        +		if (/^\#ifdef $platform_cpp_symbol$/)
        +			{
        +			while (<IN>) { last if (/^\#endif/); }
        +			}
        +		else
        +			{
        +			$old_buildinf_h .= $_;
        +			}
        +		}
        +	close(IN);
        +
        +	open(OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
        +	print OUT $old_buildinf_h;
        +	close(OUT);
        +	}
        +
        +open (OUT,">>crypto/buildinf.h") || die "Can't open buildinf.h";
        +printf OUT <<EOF;
        +#ifdef $platform_cpp_symbol
        +  /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
        +  #define CFLAGS "$cc $cflags"
        +  #define PLATFORM "$platform"
        +EOF
        +printf OUT "  #define DATE \"%s\"\n", scalar gmtime();
        +printf OUT "#endif\n";
        +close(OUT);
        +
        +# Strip of trailing ' '
        +foreach (keys %lib_obj) { $lib_obj{$_}=&clean_up_ws($lib_obj{$_}); }
        +$test=&clean_up_ws($test);
        +$e_exe=&clean_up_ws($e_exe);
        +$exheader=&clean_up_ws($exheader);
        +$header=&clean_up_ws($header);
        +
        +# First we strip the exheaders from the headers list
        +foreach (split(/\s+/,$exheader)){ $h{$_}=1; }
        +foreach (split(/\s+/,$header))	{ $h.=$_." " unless $h{$_}; }
        +chop($h); $header=$h;
        +
        +$defs.=&do_defs("HEADER",$header,"\$(INCL_D)","");
        +$rules.=&do_copy_rule("\$(INCL_D)",$header,"");
        +
        +$defs.=&do_defs("EXHEADER",$exheader,"\$(INCO_D)","");
        +$rules.=&do_copy_rule("\$(INCO_D)",$exheader,"");
        +
        +$defs.=&do_defs("T_OBJ",$test,"\$(OBJ_D)",$obj);
        +$rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)");
        +
        +$defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj);
        +$rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)');
        +
        +# Special case rule for fips_premain_dso
        +
        +if ($fips)
        +	{
        +	$rules.=&cc_compile_target("\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj",
        +		"\$(FIPS_PREMAIN_SRC)",
        +		"-DFINGERPRINT_PREMAIN_DSO_LOAD \$(SHLIB_CFLAGS)", "");
        +	$rules.=&do_link_rule("\$(PREMAIN_DSO_EXE)","\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj \$(CRYPTOOBJ) \$(O_FIPSCANISTER)","","\$(EX_LIBS)", 1);
        +	}
        +
        +foreach (values %lib_nam)
        +	{
        +	$lib_obj=$lib_obj{$_};
        +	local($slib)=$shlib;
        +
        +	if (($_ eq "SSL") && $no_ssl2 && $no_ssl3)
        +		{
        +		$rules.="\$(O_SSL):\n\n"; 
        +		next;
        +		}
        +
        +	$defs.=&do_defs(${_}."OBJ",$lib_obj,"\$(OBJ_D)",$obj);
        +	$lib=($slib)?" \$(SHLIB_CFLAGS)".$shlib_ex_cflags{$_}:" \$(LIB_CFLAGS)";
        +	$rules.=&do_compile_rule("\$(OBJ_D)",$lib_obj{$_},$lib);
        +	}
        +
        +# hack to add version info on MSVC
        +if (($platform eq "VC-WIN32") || ($platform eq "VC-WIN64A")
        +	|| ($platform eq "VC-WIN64I") || ($platform eq "VC-NT")) {
        +    $rules.= <<"EOF";
        +\$(OBJ_D)\\\$(CRYPTO).res: ms\\version32.rc
        +	\$(RSC) /fo"\$(OBJ_D)\\\$(CRYPTO).res" /d CRYPTO ms\\version32.rc
        +
        +\$(OBJ_D)\\\$(SSL).res: ms\\version32.rc
        +	\$(RSC) /fo"\$(OBJ_D)\\\$(SSL).res" /d SSL ms\\version32.rc
        +
        +EOF
        +}
        +
        +$defs.=&do_defs("T_EXE",$test,"\$(TEST_D)",$exep);
        +foreach (split(/\s+/,$test))
        +	{
        +	$t=&bname($_);
        +	$tt="\$(OBJ_D)${o}$t${obj}";
        +	$rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
        +	}
        +
        +$defs.=&do_defs("E_SHLIB",$engines . $otherlibs,"\$(ENG_D)",$shlibp);
        +
        +foreach (split(/\s+/,$engines))
        +	{
        +	$rules.=&do_compile_rule("\$(OBJ_D)","engines${o}e_$_",$lib);
        +	$rules.= &do_lib_rule("\$(OBJ_D)${o}e_${_}.obj","\$(ENG_D)$o$_$shlibp","",$shlib,"");
        +	}
        +
        +
        +
        +$rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)");
        +
        +if ($fips)
        +	{
        +	if ($shlib)
        +		{
        +		$rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)",
        +				"\$(O_CRYPTO)", "$crypto",
        +				$shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)");
        +		}
        +	else
        +		{
        +		$rules.= &do_lib_rule("\$(CRYPTOOBJ)",
        +			"\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)", "");
        +		$rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)",
        +			"\$(LIB_D)$o$crypto_compat",$crypto,$shlib,"\$(SO_CRYPTO)", "");
        +		}
        +	}
        +	else
        +	{
        +	$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,
        +							"\$(SO_CRYPTO)");
        +	}
        +
        +foreach (split(" ",$otherlibs))
        +	{
        +	my $uc = $_;
        +	$uc =~ tr /a-z/A-Z/;	
        +	$rules.= &do_lib_rule("\$(${uc}OBJ)","\$(ENG_D)$o$_$shlibp", "", $shlib, "");
        +
        +	}
        +
        +$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)", ($fips && !$shlib) ? 2 : 0);
        +
        +print $defs;
        +
        +if ($platform eq "linux-elf") {
        +    print <<"EOF";
        +# Generate perlasm output files
        +%.cpp:
        +	(cd \$(\@D)/..; PERL=perl make -f Makefile asm/\$(\@F))
        +EOF
        +}
        +print "###################################################################\n";
        +print $rules;
        +
        +###############################################
        +# strip off any trailing .[och] and append the relative directory
        +# also remembering to do nothing if we are in one of the dropped
        +# directories
        +sub var_add
        +	{
        +	local($dir,$val,$keepext)=@_;
        +	local(@a,$_,$ret);
        +
        +	return("") if $no_engine && $dir =~ /\/engine/;
        +	return("") if $no_hw   && $dir =~ /\/hw/;
        +	return("") if $no_idea && $dir =~ /\/idea/;
        +	return("") if $no_aes  && $dir =~ /\/aes/;
        +	return("") if $no_camellia  && $dir =~ /\/camellia/;
        +	return("") if $no_seed && $dir =~ /\/seed/;
        +	return("") if $no_rc2  && $dir =~ /\/rc2/;
        +	return("") if $no_rc4  && $dir =~ /\/rc4/;
        +	return("") if $no_rc5  && $dir =~ /\/rc5/;
        +	return("") if $no_rsa  && $dir =~ /\/rsa/;
        +	return("") if $no_rsa  && $dir =~ /^rsaref/;
        +	return("") if $no_dsa  && $dir =~ /\/dsa/;
        +	return("") if $no_dh   && $dir =~ /\/dh/;
        +	return("") if $no_ec   && $dir =~ /\/ec/;
        +	return("") if $no_gost   && $dir =~ /\/ccgost/;
        +	return("") if $no_cms  && $dir =~ /\/cms/;
        +	return("") if $no_jpake  && $dir =~ /\/jpake/;
        +	if ($no_des && $dir =~ /\/des/)
        +		{
        +		if ($val =~ /read_pwd/)
        +			{ return("$dir/read_pwd "); }
        +		else
        +			{ return(""); }
        +		}
        +	return("") if $no_mdc2 && $dir =~ /\/mdc2/;
        +	return("") if $no_sock && $dir =~ /\/proxy/;
        +	return("") if $no_bf   && $dir =~ /\/bf/;
        +	return("") if $no_cast && $dir =~ /\/cast/;
        +	return("") if $no_whirlpool && $dir =~ /\/whrlpool/;
        +
        +	$val =~ s/^\s*(.*)\s*$/$1/;
        +	@a=split(/\s+/,$val);
        +	grep(s/\.[och]$//,@a) unless $keepext;
        +
        +	@a=grep(!/^e_.*_3d$/,@a) if $no_des;
        +	@a=grep(!/^e_.*_d$/,@a) if $no_des;
        +	@a=grep(!/^e_.*_ae$/,@a) if $no_idea;
        +	@a=grep(!/^e_.*_i$/,@a) if $no_aes;
        +	@a=grep(!/^e_.*_r2$/,@a) if $no_rc2;
        +	@a=grep(!/^e_.*_r5$/,@a) if $no_rc5;
        +	@a=grep(!/^e_.*_bf$/,@a) if $no_bf;
        +	@a=grep(!/^e_.*_c$/,@a) if $no_cast;
        +	@a=grep(!/^e_rc4$/,@a) if $no_rc4;
        +	@a=grep(!/^e_camellia$/,@a) if $no_camellia;
        +	@a=grep(!/^e_seed$/,@a) if $no_seed;
        +
        +	#@a=grep(!/(^s2_)|(^s23_)/,@a) if $no_ssl2;
        +	#@a=grep(!/(^s3_)|(^s23_)/,@a) if $no_ssl3;
        +
        +	@a=grep(!/(_sock$)|(_acpt$)|(_conn$)|(^pxy_)/,@a) if $no_sock;
        +
        +	@a=grep(!/(^md2)|(_md2$)/,@a) if $no_md2;
        +	@a=grep(!/(^md4)|(_md4$)/,@a) if $no_md4;
        +	@a=grep(!/(^md5)|(_md5$)/,@a) if $no_md5;
        +	@a=grep(!/(rmd)|(ripemd)/,@a) if $no_ripemd;
        +
        +	@a=grep(!/(^d2i_r_)|(^i2d_r_)/,@a) if $no_rsa;
        +	@a=grep(!/(^p_open$)|(^p_seal$)/,@a) if $no_rsa;
        +	@a=grep(!/(^pem_seal$)/,@a) if $no_rsa;
        +
        +	@a=grep(!/(m_dss$)|(m_dss1$)/,@a) if $no_dsa;
        +	@a=grep(!/(^d2i_s_)|(^i2d_s_)|(_dsap$)/,@a) if $no_dsa;
        +
        +	@a=grep(!/^n_pkey$/,@a) if $no_rsa || $no_rc4;
        +
        +	@a=grep(!/_dhp$/,@a) if $no_dh;
        +
        +	@a=grep(!/(^sha[^1])|(_sha$)|(m_dss$)/,@a) if $no_sha;
        +	@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
        +	@a=grep(!/_mdc2$/,@a) if $no_mdc2;
        +
        +	@a=grep(!/(srp)/,@a) if $no_srp;
        +
        +	@a=grep(!/^engine$/,@a) if $no_engine;
        +	@a=grep(!/^hw$/,@a) if $no_hw;
        +	@a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
        +	@a=grep(!/(^dsa$)|(^gendsa$)|(^dsaparam$)/,@a) if $no_dsa;
        +	@a=grep(!/^gendsa$/,@a) if $no_sha1;
        +	@a=grep(!/(^dh$)|(^gendh$)/,@a) if $no_dh;
        +
        +	@a=grep(!/(^dh)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
        +
        +	grep($_="$dir/$_",@a);
        +	@a=grep(!/(^|\/)s_/,@a) if $no_sock;
        +	@a=grep(!/(^|\/)bio_sock/,@a) if $no_sock;
        +	$ret=join(' ',@a)." ";
        +	return($ret);
        +	}
        +
        +# change things so that each 'token' is only separated by one space
        +sub clean_up_ws
        +	{
        +	local($w)=@_;
        +
        +	$w =~ s/^\s*(.*)\s*$/$1/;
        +	$w =~ s/\s+/ /g;
        +	return($w);
        +	}
        +
        +sub do_defs
        +	{
        +	local($var,$files,$location,$postfix)=@_;
        +	local($_,$ret,$pf);
        +	local(*OUT,$tmp,$t);
        +
        +	$files =~ s/\//$o/g if $o ne '/';
        +	$ret="$var="; 
        +	$n=1;
        +	$Vars{$var}.="";
        +	foreach (split(/ /,$files))
        +		{
        +		$orig=$_;
        +		$_=&bname($_) unless /^\$/;
        +		if ($n++ == 2)
        +			{
        +			$n=0;
        +			$ret.="\\\n\t";
        +			}
        +		if (($_ =~ /bss_file/) && ($postfix eq ".h"))
        +			{ $pf=".c"; }
        +		else	{ $pf=$postfix; }
        +		if ($_ =~ /BN_ASM/)	{ $t="$_ "; }
        +		elsif ($_ =~ /BNCO_ASM/){ $t="$_ "; }
        +		elsif ($_ =~ /AES_ASM/){ $t="$_ "; }
        +		elsif ($_ =~ /DES_ENC/)	{ $t="$_ "; }
        +		elsif ($_ =~ /BF_ENC/)	{ $t="$_ "; }
        +		elsif ($_ =~ /CAST_ENC/){ $t="$_ "; }
        +		elsif ($_ =~ /RC4_ENC/)	{ $t="$_ "; }
        +		elsif ($_ =~ /RC5_ENC/)	{ $t="$_ "; }
        +		elsif ($_ =~ /MD5_ASM/)	{ $t="$_ "; }
        +		elsif ($_ =~ /SHA1_ASM/){ $t="$_ "; }
        +		elsif ($_ =~ /RMD160_ASM/){ $t="$_ "; }
        +		elsif ($_ =~ /WHIRLPOOL_ASM/){ $t="$_ "; }
        +		elsif ($_ =~ /CPUID_ASM/){ $t="$_ "; }
        +		else	{ $t="$location${o}$_$pf "; }
        +
        +		$Vars{$var}.="$t ";
        +		$ret.=$t;
        +		}
        +	# hack to add version info on MSVC
        +	if ($shlib && (($platform eq "VC-WIN32") || ($platfrom eq "VC-WIN64I") || ($platform eq "VC-WIN64A") || ($platform eq "VC-NT")))
        +		{
        +		if ($var eq "CRYPTOOBJ")
        +			{ $ret.="\$(OBJ_D)\\\$(CRYPTO).res "; }
        +		elsif ($var eq "SSLOBJ")
        +			{ $ret.="\$(OBJ_D)\\\$(SSL).res "; }
        +		}
        +	chomp($ret);
        +	$ret.="\n\n";
        +	return($ret);
        +	}
        +
        +# return the name with the leading path removed
        +sub bname
        +	{
        +	local($ret)=@_;
        +	$ret =~ s/^.*[\\\/]([^\\\/]+)$/$1/;
        +	return($ret);
        +	}
        +
        +# return the leading path
        +sub dname
        +	{
        +	my $ret=shift;
        +	$ret =~ s/(^.*)[\\\/][^\\\/]+$/$1/;
        +	return($ret);
        +	}
        +
        +##############################################################
        +# do a rule for each file that says 'compile' to new direcory
        +# compile the files in '$files' into $to
        +sub do_compile_rule
        +	{
        +	local($to,$files,$ex)=@_;
        +	local($ret,$_,$n,$d,$s);
        +
        +	$files =~ s/\//$o/g if $o ne '/';
        +	foreach (split(/\s+/,$files))
        +		{
        +		$n=&bname($_);
        +		$d=&dname($_);
        +		if (-f "${_}.c")
        +			{
        +			$ret.=&cc_compile_target("$to${o}$n$obj","${_}.c",$ex)
        +			}
        +		elsif (-f ($s="${d}${o}asm${o}${n}.pl") or
        +		       ($s=~s/sha256/sha512/ and -f $s) or
        +		       -f ($s="${d}${o}${n}.pl"))
        +			{
        +			$ret.=&perlasm_compile_target("$to${o}$n$obj",$s,$n);
        +			}
        +		elsif (-f ($s="${d}${o}asm${o}${n}.S") or
        +		       -f ($s="${d}${o}${n}.S"))
        +			{
        +			$ret.=&Sasm_compile_target("$to${o}$n$obj",$s,$n);
        +			}
        +		else	{ die "no rule for $_"; }
        +		}
        +	return($ret);
        +	}
        +
        +##############################################################
        +# do a rule for each file that says 'compile' to new direcory
        +sub perlasm_compile_target
        +	{
        +	my($target,$source,$bname)=@_;
        +	my($ret);
        +
        +	$bname =~ s/(.*)\.[^\.]$/$1/;
        +	$ret ="\$(TMP_D)$o$bname.asm: $source\n";
        +	$ret.="\t\$(PERL) $source $asmtype \$(CFLAG) >\$\@\n\n";
        +	$ret.="$target: \$(TMP_D)$o$bname.asm\n";
        +	$ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
        +	return($ret);
        +	}
        +
        +sub Sasm_compile_target
        +	{
        +	my($target,$source,$bname)=@_;
        +	my($ret);
        +
        +	$bname =~ s/(.*)\.[^\.]$/$1/;
        +	$ret ="\$(TMP_D)$o$bname.asm: $source\n";
        +	$ret.="\t\$(CC) -E \$(CFLAG) $source >\$\@\n\n";
        +	$ret.="$target: \$(TMP_D)$o$bname.asm\n";
        +	$ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
        +	return($ret);
        +	}
        +
        +sub cc_compile_target
        +	{
        +	local($target,$source,$ex_flags, $srcd)=@_;
        +	local($ret);
        +	
        +	$ex_flags.=" -DMK1MF_BUILD -D$platform_cpp_symbol" if ($source =~ /cversion/);
        +	$target =~ s/\//$o/g if $o ne "/";
        +	$source =~ s/\//$o/g if $o ne "/";
        +	$srcd = "\$(SRC_D)$o" unless defined $srcd;
        +	$ret ="$target: $srcd$source\n\t";
        +	$ret.="\$(CC) ${ofile}$target $ex_flags -c $srcd$source\n\n";
        +	return($ret);
        +	}
        +
        +##############################################################
        +sub do_asm_rule
        +	{
        +	local($target,$src)=@_;
        +	local($ret,@s,@t,$i);
        +
        +	$target =~ s/\//$o/g if $o ne "/";
        +	$src =~ s/\//$o/g if $o ne "/";
        +
        +	@t=split(/\s+/,$target);
        +	@s=split(/\s+/,$src);
        +
        +
        +	for ($i=0; $i<=$#s; $i++)
        +		{
        +		my $objfile = $t[$i];
        +		my $srcfile = $s[$i];
        +
        +		if ($perl_asm == 1)
        +			{
        +			my $plasm = $objfile;
        +			$plasm =~ s/${obj}/.pl/;
        +			$ret.="$srcfile: $plasm\n";
        +			$ret.="\t\$(PERL) $plasm $asmtype \$(CFLAG) >$srcfile\n\n";
        +			}
        +
        +		$ret.="$objfile: $srcfile\n";
        +		$ret.="\t\$(ASM) $afile$objfile \$(SRC_D)$o$srcfile\n\n";
        +		}
        +	return($ret);
        +	}
        +
        +sub do_shlib_rule
        +	{
        +	local($n,$def)=@_;
        +	local($ret,$nn);
        +	local($t);
        +
        +	($nn=$n) =~ tr/a-z/A-Z/;
        +	$ret.="$n.dll: \$(${nn}OBJ)\n";
        +	if ($vc && $w32)
        +		{
        +		$ret.="\t\$(MKSHLIB) $efile$n.dll $def @<<\n  \$(${nn}OBJ_F)\n<<\n";
        +		}
        +	$ret.="\n";
        +	return($ret);
        +	}
        +
        +# do a rule for each file that says 'copy' to new direcory on change
        +sub do_copy_rule
        +	{
        +	local($to,$files,$p)=@_;
        +	local($ret,$_,$n,$pp);
        +	
        +	$files =~ s/\//$o/g if $o ne '/';
        +	foreach (split(/\s+/,$files))
        +		{
        +		$n=&bname($_);
        +		if ($n =~ /bss_file/)
        +			{ $pp=".c"; }
        +		else	{ $pp=$p; }
        +		$ret.="$to${o}$n$pp: \$(SRC_D)$o$_$pp\n\t\$(CP) \"\$(SRC_D)$o$_$pp\" \"$to${o}$n$pp\"\n\n";
        +		}
        +	return($ret);
        +	}
        +
        +sub read_options
        +	{
        +	# Many options are handled in a similar way. In particular
        +	# no-xxx sets zero or more scalars to 1.
        +	# Process these using a hash containing the option name and
        +	# reference to the scalars to set.
        +
        +	my %valid_options = (
        +		"no-rc2" => \$no_rc2,
        +		"no-rc4" => \$no_rc4,
        +		"no-rc5" => \$no_rc5,
        +		"no-idea" => \$no_idea,
        +		"no-aes" => \$no_aes,
        +		"no-camellia" => \$no_camellia,
        +		"no-seed" => \$no_seed,
        +		"no-des" => \$no_des,
        +		"no-bf" => \$no_bf,
        +		"no-cast" => \$no_cast,
        +		"no-md2" => \$no_md2,
        +		"no-md4" => \$no_md4,
        +		"no-md5" => \$no_md5,
        +		"no-sha" => \$no_sha,
        +		"no-sha1" => \$no_sha1,
        +		"no-ripemd" => \$no_ripemd,
        +		"no-mdc2" => \$no_mdc2,
        +		"no-whirlpool" => \$no_whirlpool,
        +		"no-patents" => 
        +			[\$no_rc2, \$no_rc4, \$no_rc5, \$no_idea, \$no_rsa],
        +		"no-rsa" => \$no_rsa,
        +		"no-dsa" => \$no_dsa,
        +		"no-dh" => \$no_dh,
        +		"no-hmac" => \$no_hmac,
        +		"no-asm" => \$no_asm,
        +		"nasm" => \$nasm,
        +		"nw-nasm" => \$nw_nasm,
        +		"nw-mwasm" => \$nw_mwasm,
        +		"gaswin" => \$gaswin,
        +		"no-ssl2" => \$no_ssl2,
        +		"no-ssl3" => \$no_ssl3,
        +		"no-tlsext" => \$no_tlsext,
        +		"no-srp" => \$no_srp,
        +		"no-cms" => \$no_cms,
        +		"no-ec2m" => \$no_ec2m,
        +		"no-jpake" => \$no_jpake,
        +		"no-ec_nistp_64_gcc_128" => 0,
        +		"no-err" => \$no_err,
        +		"no-sock" => \$no_sock,
        +		"no-krb5" => \$no_krb5,
        +		"no-ec" => \$no_ec,
        +		"no-ecdsa" => \$no_ecdsa,
        +		"no-ecdh" => \$no_ecdh,
        +		"no-gost" => \$no_gost,
        +		"no-engine" => \$no_engine,
        +		"no-hw" => \$no_hw,
        +		"no-rsax" => 0,
        +		"just-ssl" =>
        +			[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
        +			  \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
        +			  \$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
        +			  \$no_aes, \$no_camellia, \$no_seed, \$no_srp],
        +		"rsaref" => 0,
        +		"gcc" => \$gcc,
        +		"debug" => \$debug,
        +		"profile" => \$profile,
        +		"shlib" => \$shlib,
        +		"dll" => \$shlib,
        +		"shared" => 0,
        +		"no-sctp" => 0,
        +		"no-gmp" => 0,
        +		"no-rfc3779" => 0,
        +		"no-montasm" => 0,
        +		"no-shared" => 0,
        +		"no-store" => 0,
        +		"no-zlib" => 0,
        +		"no-zlib-dynamic" => 0,
        +		"fips" => \$fips
        +		);
        +
        +	if (exists $valid_options{$_})
        +		{
        +		my $r = $valid_options{$_};
        +		if ( ref $r eq "SCALAR")
        +			{ $$r = 1;}
        +		elsif ( ref $r eq "ARRAY")
        +			{
        +			my $r2;
        +			foreach $r2 (@$r)
        +				{
        +				$$r2 = 1;
        +				}
        +			}
        +		}
        +	elsif (/^no-comp$/) { $xcflags = "-DOPENSSL_NO_COMP $xcflags"; }
        +	elsif (/^enable-zlib$/) { $zlib_opt = 1 if $zlib_opt == 0 }
        +	elsif (/^enable-zlib-dynamic$/)
        +		{
        +		$zlib_opt = 2;
        +		}
        +	elsif (/^no-static-engine/)
        +		{
        +		$no_static_engine = 1;
        +		}
        +	elsif (/^enable-static-engine/)
        +		{
        +		$no_static_engine = 0;
        +		}
        +	# There are also enable-xxx options which correspond to
        +	# the no-xxx. Since the scalars are enabled by default
        +	# these can be ignored.
        +	elsif (/^enable-/)
        +		{
        +		my $t = $_;
        +		$t =~ s/^enable/no/;
        +		if (exists $valid_options{$t})
        +			{return 1;}
        +		return 0;
        +		}
        +	# experimental-xxx is mostly like enable-xxx, but opensslconf.v
        +	# will still set OPENSSL_NO_xxx unless we set OPENSSL_EXPERIMENTAL_xxx.
        +	# (No need to fail if we don't know the algorithm -- this is for adventurous users only.)
        +	elsif (/^experimental-/)
        +		{
        +		my $algo, $ALGO;
        +		($algo = $_) =~ s/^experimental-//;
        +		($ALGO = $algo) =~ tr/[a-z]/[A-Z]/;
        +
        +		$xcflags="-DOPENSSL_EXPERIMENTAL_$ALGO $xcflags";
        +		
        +		}
        +	elsif (/^--with-krb5-flavor=(.*)$/)
        +		{
        +		my $krb5_flavor = $1;
        +		if ($krb5_flavor =~ /^force-[Hh]eimdal$/)
        +			{
        +			$xcflags="-DKRB5_HEIMDAL $xcflags";
        +			}
        +		elsif ($krb5_flavor =~ /^MIT/i)
        +			{
        +			$xcflags="-DKRB5_MIT $xcflags";
        +		 	if ($krb5_flavor =~ /^MIT[._-]*1[._-]*[01]/i)
        +				{
        +				$xcflags="-DKRB5_MIT_OLD11 $xcflags"
        +				}
        +			}
        +		}
        +	elsif (/^([^=]*)=(.*)$/){ $VARS{$1}=$2; }
        +	elsif (/^-[lL].*$/)	{ $l_flags.="$_ "; }
        +	elsif ((!/^-help/) && (!/^-h/) && (!/^-\?/) && /^-.*$/)
        +		{ $c_flags.="$_ "; }
        +	else { return(0); }
        +	return(1);
        +	}
        diff --git a/vendor/openssl/openssl/util/mkcerts.sh b/vendor/openssl/openssl/util/mkcerts.sh
        new file mode 100644
        index 000000000..0184fcb70
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkcerts.sh
        @@ -0,0 +1,220 @@
        +#!/bin/sh
        +
        +# This script will re-make all the required certs.
        +# cd apps
        +# sh ../util/mkcerts.sh
        +# mv ca-cert.pem pca-cert.pem ../certs
        +# cd ..
        +# cat certs/*.pem >>apps/server.pem
        +# cat certs/*.pem >>apps/server2.pem
        +# SSLEAY=`pwd`/apps/ssleay; export SSLEAY
        +# sh tools/c_rehash certs
        +#
        + 
        +CAbits=1024
        +SSLEAY="../apps/openssl"
        +CONF="-config ../apps/openssl.cnf"
        +
        +# create pca request.
        +echo creating $CAbits bit PCA cert request
        +$SSLEAY req $CONF \
        +	-new -md5 -newkey $CAbits \
        +	-keyout pca-key.pem \
        +	-out pca-req.pem -nodes >/dev/null <<EOF
        +AU
        +Queensland
        +.
        +CryptSoft Pty Ltd
        +.
        +Test PCA (1024 bit)
        +
        +
        +
        +EOF
        +
        +if [ $? != 0 ]; then
        +	echo problems generating PCA request
        +	exit 1
        +fi
        +
        +#sign it.
        +echo
        +echo self signing PCA
        +$SSLEAY x509 -md5 -days 1461 \
        +	-req -signkey pca-key.pem \
        +	-CAcreateserial -CAserial pca-cert.srl \
        +	-in pca-req.pem -out pca-cert.pem
        +
        +if [ $? != 0 ]; then
        +	echo problems self signing PCA cert
        +	exit 1
        +fi
        +echo
        +
        +# create ca request.
        +echo creating $CAbits bit CA cert request
        +$SSLEAY req $CONF \
        +	-new -md5 -newkey $CAbits \
        +	-keyout ca-key.pem \
        +	-out ca-req.pem -nodes >/dev/null <<EOF
        +AU
        +Queensland
        +.
        +CryptSoft Pty Ltd
        +.
        +Test CA (1024 bit)
        +
        +
        +
        +EOF
        +
        +if [ $? != 0 ]; then
        +	echo problems generating CA request
        +	exit 1
        +fi
        +
        +#sign it.
        +echo
        +echo signing CA
        +$SSLEAY x509 -md5 -days 1461 \
        +	-req \
        +	-CAcreateserial -CAserial pca-cert.srl \
        +	-CA pca-cert.pem -CAkey pca-key.pem \
        +	-in ca-req.pem -out ca-cert.pem
        +
        +if [ $? != 0 ]; then
        +	echo problems signing CA cert
        +	exit 1
        +fi
        +echo
        +
        +# create server request.
        +echo creating 512 bit server cert request
        +$SSLEAY req $CONF \
        +	-new -md5 -newkey 512 \
        +	-keyout s512-key.pem \
        +	-out s512-req.pem -nodes >/dev/null <<EOF
        +AU
        +Queensland
        +.
        +CryptSoft Pty Ltd
        +.
        +Server test cert (512 bit)
        +
        +
        +
        +EOF
        +
        +if [ $? != 0 ]; then
        +	echo problems generating 512 bit server cert request
        +	exit 1
        +fi
        +
        +#sign it.
        +echo
        +echo signing 512 bit server cert
        +$SSLEAY x509 -md5 -days 365 \
        +	-req \
        +	-CAcreateserial -CAserial ca-cert.srl \
        +	-CA ca-cert.pem -CAkey ca-key.pem \
        +	-in s512-req.pem -out server.pem
        +
        +if [ $? != 0 ]; then
        +	echo problems signing 512 bit server cert
        +	exit 1
        +fi
        +echo
        +
        +# create 1024 bit server request.
        +echo creating 1024 bit server cert request
        +$SSLEAY req $CONF \
        +	-new -md5 -newkey 1024 \
        +	-keyout s1024key.pem \
        +	-out s1024req.pem -nodes >/dev/null <<EOF
        +AU
        +Queensland
        +.
        +CryptSoft Pty Ltd
        +.
        +Server test cert (1024 bit)
        +
        +
        +
        +EOF
        +
        +if [ $? != 0 ]; then
        +	echo problems generating 1024 bit server cert request
        +	exit 1
        +fi
        +
        +#sign it.
        +echo
        +echo signing 1024 bit server cert
        +$SSLEAY x509 -md5 -days 365 \
        +	-req \
        +	-CAcreateserial -CAserial ca-cert.srl \
        +	-CA ca-cert.pem -CAkey ca-key.pem \
        +	-in s1024req.pem -out server2.pem
        +
        +if [ $? != 0 ]; then
        +	echo problems signing 1024 bit server cert
        +	exit 1
        +fi
        +echo
        +
        +# create 512 bit client request.
        +echo creating 512 bit client cert request
        +$SSLEAY req $CONF \
        +	-new -md5 -newkey 512 \
        +	-keyout c512-key.pem \
        +	-out c512-req.pem -nodes >/dev/null <<EOF
        +AU
        +Queensland
        +.
        +CryptSoft Pty Ltd
        +.
        +Client test cert (512 bit)
        +
        +
        +
        +EOF
        +
        +if [ $? != 0 ]; then
        +	echo problems generating 512 bit client cert request
        +	exit 1
        +fi
        +
        +#sign it.
        +echo
        +echo signing 512 bit client cert
        +$SSLEAY x509 -md5 -days 365 \
        +	-req \
        +	-CAcreateserial -CAserial ca-cert.srl \
        +	-CA ca-cert.pem -CAkey ca-key.pem \
        +	-in c512-req.pem -out client.pem
        +
        +if [ $? != 0 ]; then
        +	echo problems signing 512 bit client cert
        +	exit 1
        +fi
        +
        +echo cleanup
        +
        +cat pca-key.pem  >> pca-cert.pem
        +cat ca-key.pem   >> ca-cert.pem
        +cat s512-key.pem >> server.pem
        +cat s1024key.pem >> server2.pem
        +cat c512-key.pem >> client.pem
        +
        +for i in pca-cert.pem ca-cert.pem server.pem server2.pem client.pem
        +do
        +$SSLEAY x509 -issuer -subject -in $i -noout >$$
        +cat $$
        +/bin/cat $i >>$$
        +/bin/mv $$ $i
        +done
        +
        +#/bin/rm -f *key.pem *req.pem *.srl
        +
        +echo Finished
        +
        diff --git a/vendor/openssl/openssl/util/mkdef.pl b/vendor/openssl/openssl/util/mkdef.pl
        new file mode 100644
        index 000000000..9a8c7b87d
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkdef.pl
        @@ -0,0 +1,1539 @@
        +#!/usr/local/bin/perl -w
        +#
        +# generate a .def file
        +#
        +# It does this by parsing the header files and looking for the
        +# prototyped functions: it then prunes the output.
        +#
        +# Intermediary files are created, call libeay.num and ssleay.num,...
        +# Previously, they had the following format:
        +#
        +#	routine-name	nnnn
        +#
        +# But that isn't enough for a number of reasons, the first on being that
        +# this format is (needlessly) very Win32-centric, and even then...
        +# One of the biggest problems is that there's no information about what
        +# routines should actually be used, which varies with what crypto algorithms
        +# are disabled.  Also, some operating systems (for example VMS with VAX C)
        +# need to keep track of the global variables as well as the functions.
        +#
        +# So, a remake of this script is done so as to include information on the
        +# kind of symbol it is (function or variable) and what algorithms they're
        +# part of.  This will allow easy translating to .def files or the corresponding
        +# file in other operating systems (a .opt file for VMS, possibly with a .mar
        +# file).
        +#
        +# The format now becomes:
        +#
        +#	routine-name	nnnn	info
        +#
        +# and the "info" part is actually a colon-separated string of fields with
        +# the following meaning:
        +#
        +#	existence:platform:kind:algorithms
        +#
        +# - "existence" can be "EXIST" or "NOEXIST" depending on if the symbol is
        +#   found somewhere in the source, 
        +# - "platforms" is empty if it exists on all platforms, otherwise it contains
        +#   comma-separated list of the platform, just as they are if the symbol exists
        +#   for those platforms, or prepended with a "!" if not.  This helps resolve
        +#   symbol name variants for platforms where the names are too long for the
        +#   compiler or linker, or if the systems is case insensitive and there is a
        +#   clash, or the symbol is implemented differently (see
        +#   EXPORT_VAR_AS_FUNCTION).  This script assumes renaming of symbols is found
        +#   in the file crypto/symhacks.h.
        +#   The semantics for the platforms is that every item is checked against the
        +#   environment.  For the negative items ("!FOO"), if any of them is false
        +#   (i.e. "FOO" is true) in the environment, the corresponding symbol can't be
        +#   used.  For the positive itms, if all of them are false in the environment,
        +#   the corresponding symbol can't be used.  Any combination of positive and
        +#   negative items are possible, and of course leave room for some redundancy.
        +# - "kind" is "FUNCTION" or "VARIABLE".  The meaning of that is obvious.
        +# - "algorithms" is a comma-separated list of algorithm names.  This helps
        +#   exclude symbols that are part of an algorithm that some user wants to
        +#   exclude.
        +#
        +
        +my $debug=0;
        +
        +my $crypto_num= "util/libeay.num";
        +my $ssl_num=    "util/ssleay.num";
        +my $libname;
        +
        +my $do_update = 0;
        +my $do_rewrite = 1;
        +my $do_crypto = 0;
        +my $do_ssl = 0;
        +my $do_ctest = 0;
        +my $do_ctestall = 0;
        +my $do_checkexist = 0;
        +
        +my $VMSVAX=0;
        +my $VMSNonVAX=0;
        +my $VMS=0;
        +my $W32=0;
        +my $W16=0;
        +my $NT=0;
        +my $OS2=0;
        +# Set this to make typesafe STACK definitions appear in DEF
        +my $safe_stack_def = 0;
        +
        +my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
        +			"EXPORT_VAR_AS_FUNCTION", "ZLIB", "OPENSSL_FIPS" );
        +my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
        +my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
        +			 "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
        +			 "SHA256", "SHA512", "RIPEMD",
        +			 "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M",
        +			 "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
        +			 # EC_NISTP_64_GCC_128
        +			 "EC_NISTP_64_GCC_128",
        +			 # Envelope "algorithms"
        +			 "EVP", "X509", "ASN1_TYPEDEFS",
        +			 # Helper "algorithms"
        +			 "BIO", "COMP", "BUFFER", "LHASH", "STACK", "ERR",
        +			 "LOCKING",
        +			 # External "algorithms"
        +			 "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
        +			 # Engines
        +			 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
        +			 # RFC3779
        +			 "RFC3779",
        +			 # TLS
        +			 "TLSEXT", "PSK", "SRP", "HEARTBEATS",
        +			 # CMS
        +			 "CMS",
        +			 # CryptoAPI Engine
        +			 "CAPIENG",
        +			 # SSL v2
        +			 "SSL2",
        +			 # JPAKE
        +			 "JPAKE",
        +			 # NEXTPROTONEG
        +			 "NEXTPROTONEG",
        +			 # Deprecated functions
        +			 "DEPRECATED",
        +			 # Hide SSL internals
        +			 "SSL_INTERN",
        +			 # SCTP
        +			 "SCTP");
        +
        +my $options="";
        +open(IN,"<Makefile") || die "unable to open Makefile!\n";
        +while(<IN>) {
        +    $options=$1 if (/^OPTIONS=(.*)$/);
        +}
        +close(IN);
        +
        +# The following ciphers may be excluded (by Configure). This means functions
        +# defined with ifndef(NO_XXX) are not included in the .def file, and everything
        +# in directory xxx is ignored.
        +my $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
        +my $no_cast; my $no_whirlpool; my $no_camellia; my $no_seed;
        +my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
        +my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
        +my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
        +my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
        +my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
        +my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc; 
        +my $no_nextprotoneg; my $no_sctp;
        +
        +my $fips;
        +
        +my $zlib;
        +
        +
        +foreach (@ARGV, split(/ /, $options))
        +	{
        +	$debug=1 if $_ eq "debug";
        +	$W32=1 if $_ eq "32";
        +	$W16=1 if $_ eq "16";
        +	if($_ eq "NT") {
        +		$W32 = 1;
        +		$NT = 1;
        +	}
        +	if ($_ eq "VMS-VAX") {
        +		$VMS=1;
        +		$VMSVAX=1;
        +	}
        +	if ($_ eq "VMS-NonVAX") {
        +		$VMS=1;
        +		$VMSNonVAX=1;
        +	}
        +	$VMS=1 if $_ eq "VMS";
        +	$OS2=1 if $_ eq "OS2";
        +	$fips=1 if /^fips/;
        +	if ($_ eq "zlib" || $_ eq "enable-zlib" || $_ eq "zlib-dynamic"
        +			 || $_ eq "enable-zlib-dynamic") {
        +		$zlib = 1;
        +	}
        +
        +	$do_ssl=1 if $_ eq "ssleay";
        +	if ($_ eq "ssl") {
        +		$do_ssl=1; 
        +		$libname=$_
        +	}
        +	$do_crypto=1 if $_ eq "libeay";
        +	if ($_ eq "crypto") {
        +		$do_crypto=1;
        +		$libname=$_;
        +	}
        +	$no_static_engine=1 if $_ eq "no-static-engine";
        +	$no_static_engine=0 if $_ eq "enable-static-engine";
        +	$do_update=1 if $_ eq "update";
        +	$do_rewrite=1 if $_ eq "rewrite";
        +	$do_ctest=1 if $_ eq "ctest";
        +	$do_ctestall=1 if $_ eq "ctestall";
        +	$do_checkexist=1 if $_ eq "exist";
        +	#$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK";
        +
        +	if    (/^no-rc2$/)      { $no_rc2=1; }
        +	elsif (/^no-rc4$/)      { $no_rc4=1; }
        +	elsif (/^no-rc5$/)      { $no_rc5=1; }
        +	elsif (/^no-idea$/)     { $no_idea=1; }
        +	elsif (/^no-des$/)      { $no_des=1; $no_mdc2=1; }
        +	elsif (/^no-bf$/)       { $no_bf=1; }
        +	elsif (/^no-cast$/)     { $no_cast=1; }
        +	elsif (/^no-whirlpool$/)     { $no_whirlpool=1; }
        +	elsif (/^no-md2$/)      { $no_md2=1; }
        +	elsif (/^no-md4$/)      { $no_md4=1; }
        +	elsif (/^no-md5$/)      { $no_md5=1; }
        +	elsif (/^no-sha$/)      { $no_sha=1; }
        +	elsif (/^no-ripemd$/)   { $no_ripemd=1; }
        +	elsif (/^no-mdc2$/)     { $no_mdc2=1; }
        +	elsif (/^no-rsa$/)      { $no_rsa=1; }
        +	elsif (/^no-dsa$/)      { $no_dsa=1; }
        +	elsif (/^no-dh$/)       { $no_dh=1; }
        +	elsif (/^no-ec$/)       { $no_ec=1; }
        +	elsif (/^no-ecdsa$/)	{ $no_ecdsa=1; }
        +	elsif (/^no-ecdh$/) 	{ $no_ecdh=1; }
        +	elsif (/^no-hmac$/)	{ $no_hmac=1; }
        +	elsif (/^no-aes$/)	{ $no_aes=1; }
        +	elsif (/^no-camellia$/)	{ $no_camellia=1; }
        +	elsif (/^no-seed$/)     { $no_seed=1; }
        +	elsif (/^no-evp$/)	{ $no_evp=1; }
        +	elsif (/^no-lhash$/)	{ $no_lhash=1; }
        +	elsif (/^no-stack$/)	{ $no_stack=1; }
        +	elsif (/^no-err$/)	{ $no_err=1; }
        +	elsif (/^no-buffer$/)	{ $no_buffer=1; }
        +	elsif (/^no-bio$/)	{ $no_bio=1; }
        +	#elsif (/^no-locking$/)	{ $no_locking=1; }
        +	elsif (/^no-comp$/)	{ $no_comp=1; }
        +	elsif (/^no-dso$/)	{ $no_dso=1; }
        +	elsif (/^no-krb5$/)	{ $no_krb5=1; }
        +	elsif (/^no-engine$/)	{ $no_engine=1; }
        +	elsif (/^no-hw$/)	{ $no_hw=1; }
        +	elsif (/^no-gmp$/)	{ $no_gmp=1; }
        +	elsif (/^no-rfc3779$/)	{ $no_rfc3779=1; }
        +	elsif (/^no-tlsext$/)	{ $no_tlsext=1; }
        +	elsif (/^no-cms$/)	{ $no_cms=1; }
        +	elsif (/^no-ec2m$/)	{ $no_ec2m=1; }
        +	elsif (/^no-ec_nistp_64_gcc_128$/)	{ $no_nistp_gcc=1; }
        +	elsif (/^no-nextprotoneg$/)	{ $no_nextprotoneg=1; }
        +	elsif (/^no-ssl2$/)	{ $no_ssl2=1; }
        +	elsif (/^no-capieng$/)	{ $no_capieng=1; }
        +	elsif (/^no-jpake$/)	{ $no_jpake=1; }
        +	elsif (/^no-srp$/)	{ $no_srp=1; }
        +	elsif (/^no-sctp$/)	{ $no_sctp=1; }
        +	}
        +
        +
        +if (!$libname) { 
        +	if ($do_ssl) {
        +		$libname="SSLEAY";
        +	}
        +	if ($do_crypto) {
        +		$libname="LIBEAY";
        +	}
        +}
        +
        +# If no platform is given, assume WIN32
        +if ($W32 + $W16 + $VMS + $OS2 == 0) {
        +	$W32 = 1;
        +}
        +
        +# Add extra knowledge
        +if ($W16) {
        +	$no_fp_api=1;
        +}
        +
        +if (!$do_ssl && !$do_crypto)
        +	{
        +	print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT | OS2 ]\n";
        +	exit(1);
        +	}
        +
        +%ssl_list=&load_numbers($ssl_num);
        +$max_ssl = $max_num;
        +%crypto_list=&load_numbers($crypto_num);
        +$max_crypto = $max_num;
        +
        +my $ssl="ssl/ssl.h";
        +$ssl.=" ssl/kssl.h";
        +$ssl.=" ssl/tls1.h";
        +$ssl.=" ssl/srtp.h";
        +
        +my $crypto ="crypto/crypto.h";
        +$crypto.=" crypto/cryptlib.h";
        +$crypto.=" crypto/o_dir.h";
        +$crypto.=" crypto/o_str.h";
        +$crypto.=" crypto/o_time.h";
        +$crypto.=" crypto/des/des.h crypto/des/des_old.h" ; # unless $no_des;
        +$crypto.=" crypto/idea/idea.h" ; # unless $no_idea;
        +$crypto.=" crypto/rc4/rc4.h" ; # unless $no_rc4;
        +$crypto.=" crypto/rc5/rc5.h" ; # unless $no_rc5;
        +$crypto.=" crypto/rc2/rc2.h" ; # unless $no_rc2;
        +$crypto.=" crypto/bf/blowfish.h" ; # unless $no_bf;
        +$crypto.=" crypto/cast/cast.h" ; # unless $no_cast;
        +$crypto.=" crypto/whrlpool/whrlpool.h" ;
        +$crypto.=" crypto/md2/md2.h" ; # unless $no_md2;
        +$crypto.=" crypto/md4/md4.h" ; # unless $no_md4;
        +$crypto.=" crypto/md5/md5.h" ; # unless $no_md5;
        +$crypto.=" crypto/mdc2/mdc2.h" ; # unless $no_mdc2;
        +$crypto.=" crypto/sha/sha.h" ; # unless $no_sha;
        +$crypto.=" crypto/ripemd/ripemd.h" ; # unless $no_ripemd;
        +$crypto.=" crypto/aes/aes.h" ; # unless $no_aes;
        +$crypto.=" crypto/camellia/camellia.h" ; # unless $no_camellia;
        +$crypto.=" crypto/seed/seed.h"; # unless $no_seed;
        +
        +$crypto.=" crypto/bn/bn.h";
        +$crypto.=" crypto/rsa/rsa.h" ; # unless $no_rsa;
        +$crypto.=" crypto/dsa/dsa.h" ; # unless $no_dsa;
        +$crypto.=" crypto/dh/dh.h" ; # unless $no_dh;
        +$crypto.=" crypto/ec/ec.h" ; # unless $no_ec;
        +$crypto.=" crypto/ecdsa/ecdsa.h" ; # unless $no_ecdsa;
        +$crypto.=" crypto/ecdh/ecdh.h" ; # unless $no_ecdh;
        +$crypto.=" crypto/hmac/hmac.h" ; # unless $no_hmac;
        +$crypto.=" crypto/cmac/cmac.h" ; # unless $no_hmac;
        +
        +$crypto.=" crypto/engine/engine.h"; # unless $no_engine;
        +$crypto.=" crypto/stack/stack.h" ; # unless $no_stack;
        +$crypto.=" crypto/buffer/buffer.h" ; # unless $no_buffer;
        +$crypto.=" crypto/bio/bio.h" ; # unless $no_bio;
        +$crypto.=" crypto/dso/dso.h" ; # unless $no_dso;
        +$crypto.=" crypto/lhash/lhash.h" ; # unless $no_lhash;
        +$crypto.=" crypto/conf/conf.h";
        +$crypto.=" crypto/txt_db/txt_db.h";
        +
        +$crypto.=" crypto/evp/evp.h" ; # unless $no_evp;
        +$crypto.=" crypto/objects/objects.h";
        +$crypto.=" crypto/pem/pem.h";
        +#$crypto.=" crypto/meth/meth.h";
        +$crypto.=" crypto/asn1/asn1.h";
        +$crypto.=" crypto/asn1/asn1t.h";
        +$crypto.=" crypto/asn1/asn1_mac.h";
        +$crypto.=" crypto/err/err.h" ; # unless $no_err;
        +$crypto.=" crypto/pkcs7/pkcs7.h";
        +$crypto.=" crypto/pkcs12/pkcs12.h";
        +$crypto.=" crypto/x509/x509.h";
        +$crypto.=" crypto/x509/x509_vfy.h";
        +$crypto.=" crypto/x509v3/x509v3.h";
        +$crypto.=" crypto/ts/ts.h";
        +$crypto.=" crypto/rand/rand.h";
        +$crypto.=" crypto/comp/comp.h" ; # unless $no_comp;
        +$crypto.=" crypto/ocsp/ocsp.h";
        +$crypto.=" crypto/ui/ui.h crypto/ui/ui_compat.h";
        +$crypto.=" crypto/krb5/krb5_asn.h";
        +#$crypto.=" crypto/store/store.h";
        +$crypto.=" crypto/pqueue/pqueue.h";
        +$crypto.=" crypto/cms/cms.h";
        +$crypto.=" crypto/jpake/jpake.h";
        +$crypto.=" crypto/modes/modes.h";
        +$crypto.=" crypto/srp/srp.h";
        +
        +my $symhacks="crypto/symhacks.h";
        +
        +my @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks);
        +my @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks);
        +
        +if ($do_update) {
        +
        +if ($do_ssl == 1) {
        +
        +	&maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols);
        +	if ($do_rewrite == 1) {
        +		open(OUT, ">$ssl_num");
        +		&rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols);
        +	} else {
        +		open(OUT, ">>$ssl_num");
        +	}
        +	&update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols);
        +	close OUT;
        +}
        +
        +if($do_crypto == 1) {
        +
        +	&maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols);
        +	if ($do_rewrite == 1) {
        +		open(OUT, ">$crypto_num");
        +		&rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols);
        +	} else {
        +		open(OUT, ">>$crypto_num");
        +	}
        +	&update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols);
        +	close OUT;
        +} 
        +
        +} elsif ($do_checkexist) {
        +	&check_existing(*ssl_list, @ssl_symbols)
        +		if $do_ssl == 1;
        +	&check_existing(*crypto_list, @crypto_symbols)
        +		if $do_crypto == 1;
        +} elsif ($do_ctest || $do_ctestall) {
        +
        +	print <<"EOF";
        +
        +/* Test file to check all DEF file symbols are present by trying
        + * to link to all of them. This is *not* intended to be run!
        + */
        +
        +int main()
        +{
        +EOF
        +	&print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols)
        +		if $do_ssl == 1;
        +
        +	&print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols)
        +		if $do_crypto == 1;
        +
        +	print "}\n";
        +
        +} else {
        +
        +	&print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
        +		if $do_ssl == 1;
        +
        +	&print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
        +		if $do_crypto == 1;
        +
        +}
        +
        +
        +sub do_defs
        +{
        +	my($name,$files,$symhacksfile)=@_;
        +	my $file;
        +	my @ret;
        +	my %syms;
        +	my %platform;		# For anything undefined, we assume ""
        +	my %kind;		# For anything undefined, we assume "FUNCTION"
        +	my %algorithm;		# For anything undefined, we assume ""
        +	my %variant;
        +	my %variant_cnt;	# To be able to allocate "name{n}" if "name"
        +				# is the same name as the original.
        +	my $cpp;
        +	my %unknown_algorithms = ();
        +
        +	foreach $file (split(/\s+/,$symhacksfile." ".$files))
        +		{
        +		print STDERR "DEBUG: starting on $file:\n" if $debug;
        +		open(IN,"<$file") || die "unable to open $file:$!\n";
        +		my $line = "", my $def= "";
        +		my %tag = (
        +			(map { $_ => 0 } @known_platforms),
        +			(map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
        +			(map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
        +			NOPROTO		=> 0,
        +			PERL5		=> 0,
        +			_WINDLL		=> 0,
        +			CONST_STRICT	=> 0,
        +			TRUE		=> 1,
        +		);
        +		my $symhacking = $file eq $symhacksfile;
        +		my @current_platforms = ();
        +		my @current_algorithms = ();
        +
        +		# params: symbol, alias, platforms, kind
        +		# The reason to put this subroutine in a variable is that
        +		# it will otherwise create it's own, unshared, version of
        +		# %tag and %variant...
        +		my $make_variant = sub
        +		{
        +			my ($s, $a, $p, $k) = @_;
        +			my ($a1, $a2);
        +
        +			print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
        +			if (defined($p))
        +			{
        +				$a1 = join(",",$p,
        +					   grep(!/^$/,
        +						map { $tag{$_} == 1 ? $_ : "" }
        +						@known_platforms));
        +			}
        +			else
        +			{
        +				$a1 = join(",",
        +					   grep(!/^$/,
        +						map { $tag{$_} == 1 ? $_ : "" }
        +						@known_platforms));
        +			}
        +			$a2 = join(",",
        +				   grep(!/^$/,
        +					map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
        +					@known_ossl_platforms));
        +			print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
        +			if ($a1 eq "") { $a1 = $a2; }
        +			elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
        +			if ($a eq $s)
        +			{
        +				if (!defined($variant_cnt{$s}))
        +				{
        +					$variant_cnt{$s} = 0;
        +				}
        +				$variant_cnt{$s}++;
        +				$a .= "{$variant_cnt{$s}}";
        +			}
        +			my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
        +			my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
        +			if (!grep(/^$togrep$/,
        +				  split(/;/, defined($variant{$s})?$variant{$s}:""))) {
        +				if (defined($variant{$s})) { $variant{$s} .= ";"; }
        +				$variant{$s} .= $toadd;
        +			}
        +			print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
        +		};
        +
        +		print STDERR "DEBUG: parsing ----------\n" if $debug;
        +		while(<IN>) {
        +			if (/\/\* Error codes for the \w+ functions\. \*\//)
        +				{
        +				undef @tag;
        +				last;
        +				}
        +			if ($line ne '') {
        +				$_ = $line . $_;
        +				$line = '';
        +			}
        +
        +			if (/\\$/) {
        +				chomp; # remove eol
        +				chop; # remove ending backslash
        +				$line = $_;
        +				next;
        +			}
        +
        +			if(/\/\*/) {
        +				if (not /\*\//) {	# multiline comment...
        +					$line = $_;	# ... just accumulate
        +					next;
        +				} else {
        +					s/\/\*.*?\*\///gs;# wipe it
        +				}
        +			}
        +
        +			if ($cpp) {
        +				$cpp++ if /^#\s*if/;
        +				$cpp-- if /^#\s*endif/;
        +				next;
        +	    		}
        +			$cpp = 1 if /^#.*ifdef.*cplusplus/;
        +
        +			s/{[^{}]*}//gs;                      # ignore {} blocks
        +			print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
        +			print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
        +			if (/^\#\s*ifndef\s+(.*)/) {
        +				push(@tag,"-");
        +				push(@tag,$1);
        +				$tag{$1}=-1;
        +				print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
        +			} elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
        +				push(@tag,"-");
        +				if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
        +					my $tmp_1 = $1;
        +					my $tmp_;
        +					foreach $tmp_ (split '\&\&',$tmp_1) {
        +						$tmp_ =~ /!defined\(([^\)]+)\)/;
        +						print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
        +						push(@tag,$1);
        +						$tag{$1}=-1;
        +					}
        +				} else {
        +					print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
        +					print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
        +					push(@tag,$1);
        +					$tag{$1}=-1;
        +				}
        +			} elsif (/^\#\s*ifdef\s+(\S*)/) {
        +				push(@tag,"-");
        +				push(@tag,$1);
        +				$tag{$1}=1;
        +				print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
        +			} elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
        +				push(@tag,"-");
        +				if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
        +					my $tmp_1 = $1;
        +					my $tmp_;
        +					foreach $tmp_ (split '\|\|',$tmp_1) {
        +						$tmp_ =~ /defined\(([^\)]+)\)/;
        +						print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
        +						push(@tag,$1);
        +						$tag{$1}=1;
        +					}
        +				} else {
        +					print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
        +					print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
        +					push(@tag,$1);
        +					$tag{$1}=1;
        +				}
        +			} elsif (/^\#\s*error\s+(\w+) is disabled\./) {
        +				my $tag_i = $#tag;
        +				while($tag[$tag_i] ne "-") {
        +					if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
        +						$tag{$tag[$tag_i]}=2;
        +						print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
        +					}
        +					$tag_i--;
        +				}
        +			} elsif (/^\#\s*endif/) {
        +				my $tag_i = $#tag;
        +				while($tag_i > 0 && $tag[$tag_i] ne "-") {
        +					my $t=$tag[$tag_i];
        +					print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
        +					if ($tag{$t}==2) {
        +						$tag{$t}=-1;
        +					} else {
        +						$tag{$t}=0;
        +					}
        +					print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
        +					pop(@tag);
        +					if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
        +						$t=$1;
        +					} else {
        +						$t="";
        +					}
        +					if ($t ne ""
        +					    && !grep(/^$t$/, @known_algorithms)) {
        +						$unknown_algorithms{$t} = 1;
        +						#print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
        +					}
        +					$tag_i--;
        +				}
        +				pop(@tag);
        +			} elsif (/^\#\s*else/) {
        +				my $tag_i = $#tag;
        +				while($tag[$tag_i] ne "-") {
        +					my $t=$tag[$tag_i];
        +					$tag{$t}= -$tag{$t};
        +					print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
        +					$tag_i--;
        +				}
        +			} elsif (/^\#\s*if\s+1/) {
        +				push(@tag,"-");
        +				# Dummy tag
        +				push(@tag,"TRUE");
        +				$tag{"TRUE"}=1;
        +				print STDERR "DEBUG: $file: found 1\n" if $debug;
        +			} elsif (/^\#\s*if\s+0/) {
        +				push(@tag,"-");
        +				# Dummy tag
        +				push(@tag,"TRUE");
        +				$tag{"TRUE"}=-1;
        +				print STDERR "DEBUG: $file: found 0\n" if $debug;
        +			} elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
        +				 && $symhacking && $tag{'TRUE'} != -1) {
        +				# This is for aliasing.  When we find an alias,
        +				# we have to invert
        +				&$make_variant($1,$2);
        +				print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
        +			}
        +			if (/^\#/) {
        +				@current_platforms =
        +				    grep(!/^$/,
        +					 map { $tag{$_} == 1 ? $_ :
        +						   $tag{$_} == -1 ? "!".$_  : "" }
        +					 @known_platforms);
        +				push @current_platforms
        +				    , grep(!/^$/,
        +					   map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
        +						     $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_  : "" }
        +					   @known_ossl_platforms);
        +				@current_algorithms =
        +				    grep(!/^$/,
        +					 map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
        +					 @known_algorithms);
        +				$def .=
        +				    "#INFO:"
        +					.join(',',@current_platforms).":"
        +					    .join(',',@current_algorithms).";";
        +				next;
        +			}
        +			if ($tag{'TRUE'} != -1) {
        +				if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
        +					$def .= "int d2i_$3(void);";
        +					$def .= "int i2d_$3(void);";
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int $2_it;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("$2_it","$2_it",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
        +					$def .= "int d2i_$3(void);";
        +					$def .= "int i2d_$3(void);";
        +					$def .= "int $3_free(void);";
        +					$def .= "int $3_new(void);";
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int $2_it;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("$2_it","$2_it",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
        +					 /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
        +					$def .= "int d2i_$1(void);";
        +					$def .= "int i2d_$1(void);";
        +					$def .= "int $1_free(void);";
        +					$def .= "int $1_new(void);";
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int $1_it;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("$1_it","$1_it",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
        +					$def .= "int d2i_$2(void);";
        +					$def .= "int i2d_$2(void);";
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int $2_it;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("$2_it","$2_it",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
        +					$def .= "int $1_free(void);";
        +					$def .= "int $1_new(void);";
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
        +					$def .= "int d2i_$2(void);";
        +					$def .= "int i2d_$2(void);";
        +					$def .= "int $2_free(void);";
        +					$def .= "int $2_new(void);";
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int $2_it;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("$2_it","$2_it",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_ITEM\s*\(\s*(\w*)\s*\)/) {
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int $1_it;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("$1_it","$1_it",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_NDEF_FUNCTION\s*\(\s*(\w*)\s*\)/) {
        +					$def .= "int i2d_$1_NDEF(void);";
        +				} elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION\s*\(\s*(\w*)\s*\)/) {
        +					$def .= "int $1_print_ctx(void);";
        +					next;
        +				} elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
        +					$def .= "int $2_print_ctx(void);";
        +					next;
        +				} elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) {
        +					next;
        +				} elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
        +					 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ||
        +					 /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) {
        +					# Things not in Win16
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!WIN16",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "int PEM_read_$1(void);";
        +					$def .= "int PEM_write_$1(void);";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Things that are everywhere
        +					$def .= "int PEM_read_bio_$1(void);";
        +					$def .= "int PEM_write_bio_$1(void);";
        +					next;
        +				} elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
        +					 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
        +					# Things not in Win16
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!WIN16",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "int PEM_write_$1(void);";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Things that are everywhere
        +					$def .= "int PEM_write_bio_$1(void);";
        +					next;
        +				} elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
        +					 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
        +					# Things not in Win16
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!WIN16",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "int PEM_read_$1(void);";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Things that are everywhere
        +					$def .= "int PEM_read_bio_$1(void);";
        +					next;
        +				} elsif (/^OPENSSL_DECLARE_GLOBAL\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
        +					# Variant for platforms that do not
        +					# have to access globale variables
        +					# in shared libraries through functions
        +					$def .=
        +					    "#INFO:"
        +						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					$def .= "OPENSSL_EXTERN int _shadow_$2;";
        +					$def .=
        +					    "#INFO:"
        +						.join(',',@current_platforms).":"
        +						    .join(',',@current_algorithms).";";
        +					# Variant for platforms that have to
        +					# access globale variables in shared
        +					# libraries through functions
        +					&$make_variant("_shadow_$2","_shadow_$2",
        +						      "EXPORT_VAR_AS_FUNCTION",
        +						      "FUNCTION");
        +				} elsif ($tag{'CONST_STRICT'} != 1) {
        +					if (/\{|\/\*|\([^\)]*$/) {
        +						$line = $_;
        +					} else {
        +						$def .= $_;
        +					}
        +				}
        +			}
        +		}
        +		close(IN);
        +
        +		my $algs;
        +		my $plays;
        +
        +		print STDERR "DEBUG: postprocessing ----------\n" if $debug;
        +		foreach (split /;/, $def) {
        +			my $s; my $k = "FUNCTION"; my $p; my $a;
        +			s/^[\n\s]*//g;
        +			s/[\n\s]*$//g;
        +			next if(/\#undef/);
        +			next if(/typedef\W/);
        +			next if(/\#define/);
        +
        +			# Reduce argument lists to empty ()
        +			# fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
        +			while(/\(.*\)/s) {
        +				s/\([^\(\)]+\)/\{\}/gs;
        +				s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs;	#(*f{}) -> f
        +			}
        +			# pretend as we didn't use curly braces: {} -> ()
        +			s/\{\}/\(\)/gs;
        +
        +			s/STACK_OF\(\)/void/gs;
        +			s/LHASH_OF\(\)/void/gs;
        +
        +			print STDERR "DEBUG: \$_ = \"$_\"\n" if $debug;
        +			if (/^\#INFO:([^:]*):(.*)$/) {
        +				$plats = $1;
        +				$algs = $2;
        +				print STDERR "DEBUG: found info on platforms ($plats) and algorithms ($algs)\n" if $debug;
        +				next;
        +			} elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+(\{[0-9]+\})?)(\[[0-9]*\])*\s*$/) {
        +				$s = $1;
        +				$k = "VARIABLE";
        +				print STDERR "DEBUG: found external variable $s\n" if $debug;
        +			} elsif (/TYPEDEF_\w+_OF/s) {
        +				next;
        +			} elsif (/(\w+)\s*\(\).*/s) {	# first token prior [first] () is
        +				$s = $1;		# a function name!
        +				print STDERR "DEBUG: found function $s\n" if $debug;
        +			} elsif (/\(/ and not (/=/)) {
        +				print STDERR "File $file: cannot parse: $_;\n";
        +				next;
        +			} else {
        +				next;
        +			}
        +
        +			$syms{$s} = 1;
        +			$kind{$s} = $k;
        +
        +			$p = $plats;
        +			$a = $algs;
        +			$a .= ",BF" if($s =~ /EVP_bf/);
        +			$a .= ",CAST" if($s =~ /EVP_cast/);
        +			$a .= ",DES" if($s =~ /EVP_des/);
        +			$a .= ",DSA" if($s =~ /EVP_dss/);
        +			$a .= ",IDEA" if($s =~ /EVP_idea/);
        +			$a .= ",MD2" if($s =~ /EVP_md2/);
        +			$a .= ",MD4" if($s =~ /EVP_md4/);
        +			$a .= ",MD5" if($s =~ /EVP_md5/);
        +			$a .= ",RC2" if($s =~ /EVP_rc2/);
        +			$a .= ",RC4" if($s =~ /EVP_rc4/);
        +			$a .= ",RC5" if($s =~ /EVP_rc5/);
        +			$a .= ",RIPEMD" if($s =~ /EVP_ripemd/);
        +			$a .= ",SHA" if($s =~ /EVP_sha/);
        +			$a .= ",RSA" if($s =~ /EVP_(Open|Seal)(Final|Init)/);
        +			$a .= ",RSA" if($s =~ /PEM_Seal(Final|Init|Update)/);
        +			$a .= ",RSA" if($s =~ /RSAPrivateKey/);
        +			$a .= ",RSA" if($s =~ /SSLv23?_((client|server)_)?method/);
        +
        +			$platform{$s} =
        +			    &reduce_platforms((defined($platform{$s})?$platform{$s}.',':"").$p);
        +			$algorithm{$s} .= ','.$a;
        +
        +			if (defined($variant{$s})) {
        +				foreach $v (split /;/,$variant{$s}) {
        +					(my $r, my $p, my $k) = split(/:/,$v);
        +					my $ip = join ',',map({ /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p);
        +					$syms{$r} = 1;
        +					if (!defined($k)) { $k = $kind{$s}; }
        +					$kind{$r} = $k."(".$s.")";
        +					$algorithm{$r} = $algorithm{$s};
        +					$platform{$r} = &reduce_platforms($platform{$s}.",".$p.",".$p);
        +					$platform{$s} = &reduce_platforms($platform{$s}.','.$ip.','.$ip);
        +					print STDERR "DEBUG: \$variant{\"$s\"} = ",$v,"; \$r = $r; \$p = ",$platform{$r},"; \$a = ",$algorithm{$r},"; \$kind = ",$kind{$r},"\n" if $debug;
        +				}
        +			}
        +			print STDERR "DEBUG: \$s = $s; \$p = ",$platform{$s},"; \$a = ",$algorithm{$s},"; \$kind = ",$kind{$s},"\n" if $debug;
        +		}
        +	}
        +
        +	# Prune the returned symbols
        +
        +        delete $syms{"bn_dump1"};
        +	$platform{"BIO_s_log"} .= ",!WIN32,!WIN16,!macintosh";
        +
        +	$platform{"PEM_read_NS_CERT_SEQ"} = "VMS";
        +	$platform{"PEM_write_NS_CERT_SEQ"} = "VMS";
        +	$platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
        +	$platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
        +	$platform{"EVP_sha384"} = "!VMSVAX";
        +	$platform{"EVP_sha512"} = "!VMSVAX";
        +	$platform{"SHA384_Init"} = "!VMSVAX";
        +	$platform{"SHA384_Transform"} = "!VMSVAX";
        +	$platform{"SHA384_Update"} = "!VMSVAX";
        +	$platform{"SHA384_Final"} = "!VMSVAX";
        +	$platform{"SHA384"} = "!VMSVAX";
        +	$platform{"SHA512_Init"} = "!VMSVAX";
        +	$platform{"SHA512_Transform"} = "!VMSVAX";
        +	$platform{"SHA512_Update"} = "!VMSVAX";
        +	$platform{"SHA512_Final"} = "!VMSVAX";
        +	$platform{"SHA512"} = "!VMSVAX";
        +	$platform{"WHIRLPOOL_Init"} = "!VMSVAX";
        +	$platform{"WHIRLPOOL"} = "!VMSVAX";
        +	$platform{"WHIRLPOOL_BitUpdate"} = "!VMSVAX";
        +	$platform{"EVP_whirlpool"} = "!VMSVAX";
        +	$platform{"WHIRLPOOL_Final"} = "!VMSVAX";
        +	$platform{"WHIRLPOOL_Update"} = "!VMSVAX";
        +
        +
        +	# Info we know about
        +
        +	push @ret, map { $_."\\".&info_string($_,"EXIST",
        +					      $platform{$_},
        +					      $kind{$_},
        +					      $algorithm{$_}) } keys %syms;
        +
        +	if (keys %unknown_algorithms) {
        +		print STDERR "WARNING: mkdef.pl doesn't know the following algorithms:\n";
        +		print STDERR "\t",join("\n\t",keys %unknown_algorithms),"\n";
        +	}
        +	return(@ret);
        +}
        +
        +# Param: string of comma-separated platform-specs.
        +sub reduce_platforms
        +{
        +	my ($platforms) = @_;
        +	my $pl = defined($platforms) ? $platforms : "";
        +	my %p = map { $_ => 0 } split /,/, $pl;
        +	my $ret;
        +
        +	print STDERR "DEBUG: Entered reduce_platforms with \"$platforms\"\n"
        +	    if $debug;
        +	# We do this, because if there's code like the following, it really
        +	# means the function exists in all cases and should therefore be
        +	# everywhere.  By increasing and decreasing, we may attain 0:
        +	#
        +	# ifndef WIN16
        +	#    int foo();
        +	# else
        +	#    int _fat foo();
        +	# endif
        +	foreach $platform (split /,/, $pl) {
        +		if ($platform =~ /^!(.*)$/) {
        +			$p{$1}--;
        +		} else {
        +			$p{$platform}++;
        +		}
        +	}
        +	foreach $platform (keys %p) {
        +		if ($p{$platform} == 0) { delete $p{$platform}; }
        +	}
        +
        +	delete $p{""};
        +
        +	$ret = join(',',sort(map { $p{$_} < 0 ? "!".$_ : $_ } keys %p));
        +	print STDERR "DEBUG: Exiting reduce_platforms with \"$ret\"\n"
        +	    if $debug;
        +	return $ret;
        +}
        +
        +sub info_string {
        +	(my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_;
        +
        +	my %a = defined($algorithms) ?
        +	    map { $_ => 1 } split /,/, $algorithms : ();
        +	my $k = defined($kind) ? $kind : "FUNCTION";
        +	my $ret;
        +	my $p = &reduce_platforms($platforms);
        +
        +	delete $a{""};
        +
        +	$ret = $exist;
        +	$ret .= ":".$p;
        +	$ret .= ":".$k;
        +	$ret .= ":".join(',',sort keys %a);
        +	return $ret;
        +}
        +
        +sub maybe_add_info {
        +	(my $name, *nums, my @symbols) = @_;
        +	my $sym;
        +	my $new_info = 0;
        +	my %syms=();
        +
        +	print STDERR "Updating $name info\n";
        +	foreach $sym (@symbols) {
        +		(my $s, my $i) = split /\\/, $sym;
        +		if (defined($nums{$s})) {
        +			$i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/;
        +			(my $n, my $dummy) = split /\\/, $nums{$s};
        +			if (!defined($dummy) || $i ne $dummy) {
        +				$nums{$s} = $n."\\".$i;
        +				$new_info++;
        +				print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n" if $debug;
        +			}
        +		}
        +		$syms{$s} = 1;
        +	}
        +
        +	my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums;
        +	foreach $sym (@s) {
        +		(my $n, my $i) = split /\\/, $nums{$sym};
        +		if (!defined($syms{$sym}) && $i !~ /^NOEXIST:/) {
        +			$new_info++;
        +			print STDERR "DEBUG: maybe_add_info for $sym: -> undefined\n" if $debug;
        +		}
        +	}
        +	if ($new_info) {
        +		print STDERR "$new_info old symbols got an info update\n";
        +		if (!$do_rewrite) {
        +			print STDERR "You should do a rewrite to fix this.\n";
        +		}
        +	} else {
        +		print STDERR "No old symbols needed info update\n";
        +	}
        +}
        +
        +# Param: string of comma-separated keywords, each possibly prefixed with a "!"
        +sub is_valid
        +{
        +	my ($keywords_txt,$platforms) = @_;
        +	my (@keywords) = split /,/,$keywords_txt;
        +	my ($falsesum, $truesum) = (0, 1);
        +
        +	# Param: one keyword
        +	sub recognise
        +	{
        +		my ($keyword,$platforms) = @_;
        +
        +		if ($platforms) {
        +			# platforms
        +			if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
        +			if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
        +			if ($keyword eq "VMS" && $VMS) { return 1; }
        +			if ($keyword eq "WIN32" && $W32) { return 1; }
        +			if ($keyword eq "WIN16" && $W16) { return 1; }
        +			if ($keyword eq "WINNT" && $NT) { return 1; }
        +			if ($keyword eq "OS2" && $OS2) { return 1; }
        +			# Special platforms:
        +			# EXPORT_VAR_AS_FUNCTION means that global variables
        +			# will be represented as functions.  This currently
        +			# only happens on VMS-VAX.
        +			if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32 || $W16)) {
        +				return 1;
        +			}
        +			if ($keyword eq "OPENSSL_FIPS" && $fips) {
        +				return 1;
        +			}
        +			if ($keyword eq "ZLIB" && $zlib) { return 1; }
        +			return 0;
        +		} else {
        +			# algorithms
        +			if ($keyword eq "RC2" && $no_rc2) { return 0; }
        +			if ($keyword eq "RC4" && $no_rc4) { return 0; }
        +			if ($keyword eq "RC5" && $no_rc5) { return 0; }
        +			if ($keyword eq "IDEA" && $no_idea) { return 0; }
        +			if ($keyword eq "DES" && $no_des) { return 0; }
        +			if ($keyword eq "BF" && $no_bf) { return 0; }
        +			if ($keyword eq "CAST" && $no_cast) { return 0; }
        +			if ($keyword eq "MD2" && $no_md2) { return 0; }
        +			if ($keyword eq "MD4" && $no_md4) { return 0; }
        +			if ($keyword eq "MD5" && $no_md5) { return 0; }
        +			if ($keyword eq "SHA" && $no_sha) { return 0; }
        +			if ($keyword eq "RIPEMD" && $no_ripemd) { return 0; }
        +			if ($keyword eq "MDC2" && $no_mdc2) { return 0; }
        +			if ($keyword eq "WHIRLPOOL" && $no_whirlpool) { return 0; }
        +			if ($keyword eq "RSA" && $no_rsa) { return 0; }
        +			if ($keyword eq "DSA" && $no_dsa) { return 0; }
        +			if ($keyword eq "DH" && $no_dh) { return 0; }
        +			if ($keyword eq "EC" && $no_ec) { return 0; }
        +			if ($keyword eq "ECDSA" && $no_ecdsa) { return 0; }
        +			if ($keyword eq "ECDH" && $no_ecdh) { return 0; }
        +			if ($keyword eq "HMAC" && $no_hmac) { return 0; }
        +			if ($keyword eq "AES" && $no_aes) { return 0; }
        +			if ($keyword eq "CAMELLIA" && $no_camellia) { return 0; }
        +			if ($keyword eq "SEED" && $no_seed) { return 0; }
        +			if ($keyword eq "EVP" && $no_evp) { return 0; }
        +			if ($keyword eq "LHASH" && $no_lhash) { return 0; }
        +			if ($keyword eq "STACK" && $no_stack) { return 0; }
        +			if ($keyword eq "ERR" && $no_err) { return 0; }
        +			if ($keyword eq "BUFFER" && $no_buffer) { return 0; }
        +			if ($keyword eq "BIO" && $no_bio) { return 0; }
        +			if ($keyword eq "COMP" && $no_comp) { return 0; }
        +			if ($keyword eq "DSO" && $no_dso) { return 0; }
        +			if ($keyword eq "KRB5" && $no_krb5) { return 0; }
        +			if ($keyword eq "ENGINE" && $no_engine) { return 0; }
        +			if ($keyword eq "HW" && $no_hw) { return 0; }
        +			if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
        +			if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
        +			if ($keyword eq "GMP" && $no_gmp) { return 0; }
        +			if ($keyword eq "RFC3779" && $no_rfc3779) { return 0; }
        +			if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; }
        +			if ($keyword eq "PSK" && $no_psk) { return 0; }
        +			if ($keyword eq "CMS" && $no_cms) { return 0; }
        +			if ($keyword eq "EC2M" && $no_ec2m) { return 0; }
        +			if ($keyword eq "NEXTPROTONEG" && $no_nextprotoneg) { return 0; }
        +			if ($keyword eq "EC_NISTP_64_GCC_128" && $no_nistp_gcc)
        +					{ return 0; }
        +			if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
        +			if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
        +			if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
        +			if ($keyword eq "SRP" && $no_srp) { return 0; }
        +			if ($keyword eq "SCTP" && $no_sctp) { return 0; }
        +			if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
        +
        +			# Nothing recognise as true
        +			return 1;
        +		}
        +	}
        +
        +	foreach $k (@keywords) {
        +		if ($k =~ /^!(.*)$/) {
        +			$falsesum += &recognise($1,$platforms);
        +		} else {
        +			$truesum *= &recognise($k,$platforms);
        +		}
        +	}
        +	print STDERR "DEBUG: [",$#keywords,",",$#keywords < 0,"] is_valid($keywords_txt) => (\!$falsesum) && $truesum = ",(!$falsesum) && $truesum,"\n" if $debug;
        +	return (!$falsesum) && $truesum;
        +}
        +
        +sub print_test_file
        +{
        +	(*OUT,my $name,*nums,my $testall,my @symbols)=@_;
        +	my $n = 1; my @e; my @r;
        +	my $sym; my $prev = ""; my $prefSSLeay;
        +
        +	(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
        +	(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:.*/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
        +	@symbols=((sort @e),(sort @r));
        +
        +	foreach $sym (@symbols) {
        +		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
        +		my $v = 0;
        +		$v = 1 if $i=~ /^.*?:.*?:VARIABLE/;
        +		my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
        +		my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
        +		if (!defined($nums{$s})) {
        +			print STDERR "Warning: $s does not have a number assigned\n"
        +			    if(!$do_update);
        +		} elsif (is_valid($p,1) && is_valid($a,0)) {
        +			my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
        +			if ($prev eq $s2) {
        +				print OUT "\t/* The following has already appeared previously */\n";
        +				print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
        +			}
        +			$prev = $s2;	# To warn about duplicates...
        +
        +			($nn,$ni)=($nums{$s2} =~ /^(.*?)\\(.*)$/);
        +			if ($v) {
        +				print OUT "\textern int $s2; /* type unknown */ /* $nn $ni */\n";
        +			} else {
        +				print OUT "\textern int $s2(); /* type unknown */ /* $nn $ni */\n";
        +			}
        +		}
        +	}
        +}
        +
        +sub get_version {
        +   local *MF;
        +   my $v = '?';
        +   open MF, 'Makefile' or return $v;
        +   while (<MF>) {
        +     $v = $1, last if /^VERSION=(.*?)\s*$/;
        +   }
        +   close MF;
        +   return $v;
        +}
        +
        +sub print_def_file
        +{
        +	(*OUT,my $name,*nums,my @symbols)=@_;
        +	my $n = 1; my @e; my @r; my @v; my $prev="";
        +	my $liboptions="";
        +	my $libname = $name;
        +	my $http_vendor = 'www.openssl.org/';
        +	my $version = get_version();
        +	my $what = "OpenSSL: implementation of Secure Socket Layer";
        +	my $description = "$what $version, $name - http://$http_vendor";
        +
        +	if ($W32)
        +		{ $libname.="32"; }
        +	elsif ($W16)
        +		{ $libname.="16"; }
        +	elsif ($OS2)
        +		{ # DLL names should not clash on the whole system.
        +		  # However, they should not have any particular relationship
        +		  # to the name of the static library.  Chose descriptive names
        +		  # (must be at most 8 chars).
        +		  my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
        +		  $libname = $translate{$name} || $name;
        +		  $liboptions = <<EOO;
        +INITINSTANCE
        +DATA MULTIPLE NONSHARED
        +EOO
        +		  # Vendor field can't contain colon, drat; so we omit http://
        +		  $description = "\@#$http_vendor:$version#\@$what; DLL for library $name.  Build for EMX -Zmtd";
        +		}
        +
        +	print OUT <<"EOF";
        +;
        +; Definition file for the DLL version of the $name library from OpenSSL
        +;
        +
        +LIBRARY         $libname	$liboptions
        +
        +EOF
        +
        +	if ($W16) {
        +		print <<"EOF";
        +CODE            PRELOAD MOVEABLE
        +DATA            PRELOAD MOVEABLE SINGLE
        +
        +EXETYPE		WINDOWS
        +
        +HEAPSIZE	4096
        +STACKSIZE	8192
        +
        +EOF
        +	}
        +
        +	print "EXPORTS\n";
        +
        +	(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
        +	(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
        +	(@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
        +	@symbols=((sort @e),(sort @r), (sort @v));
        +
        +
        +	foreach $sym (@symbols) {
        +		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
        +		my $v = 0;
        +		$v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
        +		if (!defined($nums{$s})) {
        +			printf STDERR "Warning: $s does not have a number assigned\n"
        +			    if(!$do_update);
        +		} else {
        +			(my $n, my $dummy) = split /\\/, $nums{$s};
        +			my %pf = ();
        +			my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
        +			my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
        +			if (is_valid($p,1) && is_valid($a,0)) {
        +				my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
        +				if ($prev eq $s2) {
        +					print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
        +				}
        +				$prev = $s2;	# To warn about duplicates...
        +				if($v && !$OS2) {
        +					printf OUT "    %s%-39s @%-8d DATA\n",($W32)?"":"_",$s2,$n;
        +				} else {
        +					printf OUT "    %s%-39s @%d\n",($W32||$OS2)?"":"_",$s2,$n;
        +				}
        +			}
        +		}
        +	}
        +	printf OUT "\n";
        +}
        +
        +sub load_numbers
        +{
        +	my($name)=@_;
        +	my(@a,%ret);
        +
        +	$max_num = 0;
        +	$num_noinfo = 0;
        +	$prev = "";
        +	$prev_cnt = 0;
        +
        +	open(IN,"<$name") || die "unable to open $name:$!\n";
        +	while (<IN>) {
        +		chop;
        +		s/#.*$//;
        +		next if /^\s*$/;
        +		@a=split;
        +		if (defined $ret{$a[0]}) {
        +			# This is actually perfectly OK
        +			#print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n";
        +		}
        +		if ($max_num > $a[1]) {
        +			print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n";
        +		}
        +		elsif ($max_num == $a[1]) {
        +			# This is actually perfectly OK
        +			#print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n";
        +			if ($a[0] eq $prev) {
        +				$prev_cnt++;
        +				$a[0] .= "{$prev_cnt}";
        +			}
        +		}
        +		else {
        +			$prev_cnt = 0;
        +		}
        +		if ($#a < 2) {
        +			# Existence will be proven later, in do_defs
        +			$ret{$a[0]}=$a[1];
        +			$num_noinfo++;
        +		} else {
        +			$ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker
        +		}
        +		$max_num = $a[1] if $a[1] > $max_num;
        +		$prev=$a[0];
        +	}
        +	if ($num_noinfo) {
        +		print STDERR "Warning: $num_noinfo symbols were without info.";
        +		if ($do_rewrite) {
        +			printf STDERR "  The rewrite will fix this.\n";
        +		} else {
        +			printf STDERR "  You should do a rewrite to fix this.\n";
        +		}
        +	}
        +	close(IN);
        +	return(%ret);
        +}
        +
        +sub parse_number
        +{
        +	(my $str, my $what) = @_;
        +	(my $n, my $i) = split(/\\/,$str);
        +	if ($what eq "n") {
        +		return $n;
        +	} else {
        +		return $i;
        +	}
        +}
        +
        +sub rewrite_numbers
        +{
        +	(*OUT,$name,*nums,@symbols)=@_;
        +	my $thing;
        +
        +	print STDERR "Rewriting $name\n";
        +
        +	my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
        +	my $r; my %r; my %rsyms;
        +	foreach $r (@r) {
        +		(my $s, my $i) = split /\\/, $r;
        +		my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
        +		$i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
        +		$r{$a} = $s."\\".$i;
        +		$rsyms{$s} = 1;
        +	}
        +
        +	my %syms = ();
        +	foreach $_ (@symbols) {
        +		(my $n, my $i) = split /\\/;
        +		$syms{$n} = 1;
        +	}
        +
        +	my @s=sort {
        +	    &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n")
        +	    || $a cmp $b
        +	} keys %nums;
        +	foreach $sym (@s) {
        +		(my $n, my $i) = split /\\/, $nums{$sym};
        +		next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/;
        +		next if defined($rsyms{$sym});
        +		print STDERR "DEBUG: rewrite_numbers for sym = ",$sym,": i = ",$i,", n = ",$n,", rsym{sym} = ",$rsyms{$sym},"syms{sym} = ",$syms{$sym},"\n" if $debug;
        +		$i="NOEXIST::FUNCTION:"
        +			if !defined($i) || $i eq "" || !defined($syms{$sym});
        +		my $s2 = $sym;
        +		$s2 =~ s/\{[0-9]+\}$//;
        +		printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
        +		if (exists $r{$sym}) {
        +			(my $s, $i) = split /\\/,$r{$sym};
        +			my $s2 = $s;
        +			$s2 =~ s/\{[0-9]+\}$//;
        +			printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
        +		}
        +	}
        +}
        +
        +sub update_numbers
        +{
        +	(*OUT,$name,*nums,my $start_num, my @symbols)=@_;
        +	my $new_syms = 0;
        +
        +	print STDERR "Updating $name numbers\n";
        +
        +	my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
        +	my $r; my %r; my %rsyms;
        +	foreach $r (@r) {
        +		(my $s, my $i) = split /\\/, $r;
        +		my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
        +		$i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
        +		$r{$a} = $s."\\".$i;
        +		$rsyms{$s} = 1;
        +	}
        +
        +	foreach $sym (@symbols) {
        +		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
        +		next if $i =~ /^.*?:.*?:\w+\(\w+\)/;
        +		next if defined($rsyms{$sym});
        +		die "ERROR: Symbol $sym had no info attached to it."
        +		    if $i eq "";
        +		if (!exists $nums{$s}) {
        +			$new_syms++;
        +			my $s2 = $s;
        +			$s2 =~ s/\{[0-9]+\}$//;
        +			printf OUT "%s%-39s %d\t%s\n","",$s2, ++$start_num,$i;
        +			if (exists $r{$s}) {
        +				($s, $i) = split /\\/,$r{$s};
        +				$s =~ s/\{[0-9]+\}$//;
        +				printf OUT "%s%-39s %d\t%s\n","",$s, $start_num,$i;
        +			}
        +		}
        +	}
        +	if($new_syms) {
        +		print STDERR "$new_syms New symbols added\n";
        +	} else {
        +		print STDERR "No New symbols Added\n";
        +	}
        +}
        +
        +sub check_existing
        +{
        +	(*nums, my @symbols)=@_;
        +	my %existing; my @remaining;
        +	@remaining=();
        +	foreach $sym (@symbols) {
        +		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
        +		$existing{$s}=1;
        +	}
        +	foreach $sym (keys %nums) {
        +		if (!exists $existing{$sym}) {
        +			push @remaining, $sym;
        +		}
        +	}
        +	if(@remaining) {
        +		print STDERR "The following symbols do not seem to exist:\n";
        +		foreach $sym (@remaining) {
        +			print STDERR "\t",$sym,"\n";
        +		}
        +	}
        +}
        +
        diff --git a/vendor/openssl/openssl/util/mkdir-p.pl b/vendor/openssl/openssl/util/mkdir-p.pl
        new file mode 100644
        index 000000000..e73d02b07
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkdir-p.pl
        @@ -0,0 +1,34 @@
        +#!/usr/local/bin/perl
        +
        +# mkdir-p.pl
        +
        +# On some systems, the -p option to mkdir (= also create any missing parent
        +# directories) is not available.
        +
        +my $arg;
        +
        +foreach $arg (@ARGV) {
        +  $arg =~ tr|\\|/|;
        +  &do_mkdir_p($arg);
        +}
        +
        +
        +sub do_mkdir_p {
        +  local($dir) = @_;
        +
        +  $dir =~ s|/*\Z(?!\n)||s;
        +
        +  if (-d $dir) {
        +    return;
        +  }
        +
        +  if ($dir =~ m|[^/]/|s) {
        +    local($parent) = $dir;
        +    $parent =~ s|[^/]*\Z(?!\n)||s;
        +
        +    do_mkdir_p($parent);
        +  }
        +
        +  mkdir($dir, 0777) || die "Cannot create directory $dir: $!\n";
        +  print "created directory `$dir'\n";
        +}
        diff --git a/vendor/openssl/openssl/util/mkerr.pl b/vendor/openssl/openssl/util/mkerr.pl
        new file mode 100644
        index 000000000..aec401c77
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkerr.pl
        @@ -0,0 +1,810 @@
        +#!/usr/local/bin/perl -w
        +
        +my $config = "crypto/err/openssl.ec";
        +my $hprefix = "openssl/";
        +my $debug = 0;
        +my $rebuild = 0;
        +my $static = 1;
        +my $recurse = 0;
        +my $reindex = 0;
        +my $dowrite = 0;
        +my $staticloader = "";
        +
        +my $pack_errcode;
        +my $load_errcode;
        +
        +my $errcount;
        +
        +while (@ARGV) {
        +	my $arg = $ARGV[0];
        +	if($arg eq "-conf") {
        +		shift @ARGV;
        +		$config = shift @ARGV;
        +	} elsif($arg eq "-hprefix") {
        +		shift @ARGV;
        +		$hprefix = shift @ARGV;
        +	} elsif($arg eq "-debug") {
        +		$debug = 1;
        +		shift @ARGV;
        +	} elsif($arg eq "-rebuild") {
        +		$rebuild = 1;
        +		shift @ARGV;
        +	} elsif($arg eq "-recurse") {
        +		$recurse = 1;
        +		shift @ARGV;
        +	} elsif($arg eq "-reindex") {
        +		$reindex = 1;
        +		shift @ARGV;
        +	} elsif($arg eq "-nostatic") {
        +		$static = 0;
        +		shift @ARGV;
        +	} elsif($arg eq "-staticloader") {
        +		$staticloader = "static ";
        +		shift @ARGV;
        +	} elsif($arg eq "-write") {
        +		$dowrite = 1;
        +		shift @ARGV;
        +	} elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") {
        +		print STDERR <<"EOF";
        +mkerr.pl [options] ...
        +
        +Options:
        +
        +  -conf F       Use the config file F instead of the default one:
        +                  crypto/err/openssl.ec
        +
        +  -hprefix P    Prepend the filenames in generated #include <header>
        +                statements with prefix P. Default: 'openssl/' (without
        +                the quotes, naturally)
        +
        +  -debug        Turn on debugging verbose output on stderr.
        +
        +  -rebuild      Rebuild all header and C source files, irrespective of the
        +                fact if any error or function codes have been added/removed.
        +                Default: only update files for libraries which saw change
        +                         (of course, this requires '-write' as well, or no
        +                          files will be touched!)
        +
        +  -recurse      scan a preconfigured set of directories / files for error and
        +                function codes:
        +                  (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>)
        +                When this option is NOT specified, the filelist is taken from
        +                the commandline instead. Here, wildcards may be embedded. (Be
        +                sure to escape those to prevent the shell from expanding them
        +                for you when you wish mkerr.pl to do so instead.)
        +                Default: take file list to scan from the command line.
        +
        +  -reindex      Discard the numeric values previously assigned to the error
        +                and function codes as extracted from the scanned header files;
        +                instead renumber all of them starting from 100. (Note that
        +                the numbers assigned through 'R' records in the config file
        +                remain intact.)
        +                Default: keep previously assigned numbers. (You are warned
        +                         when collisions are detected.)
        +
        +  -nostatic     Generates a different source code, where these additional 
        +                functions are generated for each library specified in the
        +                config file:
        +                  void ERR_load_<LIB>_strings(void);
        +                  void ERR_unload_<LIB>_strings(void);
        +                  void ERR_<LIB>_error(int f, int r, char *fn, int ln);
        +                  #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__)
        +                while the code facilitates the use of these in an environment
        +                where the error support routines are dynamically loaded at 
        +                runtime.
        +                Default: 'static' code generation.
        +
        +  -staticloader Prefix generated functions with the 'static' scope modifier.
        +                Default: don't write any scope modifier prefix.
        +
        +  -write        Actually (over)write the generated code to the header and C 
        +                source files as assigned to each library through the config 
        +                file.
        +                Default: don't write.
        +
        +  -help / -h / -? / --help            Show this help text.
        +
        +  ...           Additional arguments are added to the file list to scan,
        +                assuming '-recurse' was NOT specified on the command line.
        +
        +EOF
        +		exit 1;
        +	} else {
        +		last;
        +	}
        +}
        +
        +if($recurse) {
        +	@source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>);
        +} else {
        +	@source = @ARGV;
        +}
        +
        +# Read in the config file
        +
        +open(IN, "<$config") || die "Can't open config file $config";
        +
        +# Parse config file
        +
        +while(<IN>)
        +{
        +	if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
        +		$hinc{$1} = $2;
        +		$libinc{$2} = $1;
        +		$cskip{$3} = $1;
        +		if($3 ne "NONE") {
        +			$csrc{$1} = $3;
        +			$fmax{$1} = 100;
        +			$rmax{$1} = 100;
        +			$fassigned{$1} = ":";
        +			$rassigned{$1} = ":";
        +			$fnew{$1} = 0;
        +			$rnew{$1} = 0;
        +		}
        +	} elsif (/^F\s+(\S+)/) {
        +	# Add extra function with $1
        +	} elsif (/^R\s+(\S+)\s+(\S+)/) {
        +		$rextra{$1} = $2;
        +		$rcodes{$1} = $2;
        +	}
        +}
        +
        +close IN;
        +
        +# Scan each header file in turn and make a list of error codes
        +# and function names
        +
        +while (($hdr, $lib) = each %libinc)
        +{
        +	next if($hdr eq "NONE");
        +	print STDERR "Scanning header file $hdr\n" if $debug; 
        +	my $line = "", $def= "", $linenr = 0, $gotfile = 0;
        +	if (open(IN, "<$hdr")) {
        +	    $gotfile = 1;
        +	    while(<IN>) {
        +		$linenr++;
        +		print STDERR "line: $linenr\r" if $debug;
        +
        +		last if(/BEGIN\s+ERROR\s+CODES/);
        +		if ($line ne '') {
        +		    $_ = $line . $_;
        +		    $line = '';
        +		}
        +
        +		if (/\\$/) {
        +		    $line = $_;
        +		    next;
        +		}
        +
        +		if(/\/\*/) {
        +		    if (not /\*\//) {		# multiline comment...
        +			$line = $_;		# ... just accumulate
        +			next; 
        +		    } else {
        +			s/\/\*.*?\*\///gs;	# wipe it
        +		    }
        +		}
        +
        +		if ($cpp) {
        +		    $cpp++ if /^#\s*if/;
        +		    $cpp-- if /^#\s*endif/;
        +		    next;
        +		}
        +		$cpp = 1 if /^#.*ifdef.*cplusplus/;  # skip "C" declaration
        +
        +		next if (/^\#/);                      # skip preprocessor directives
        +
        +		s/{[^{}]*}//gs;                      # ignore {} blocks
        +
        +		if (/\{|\/\*/) { # Add a } so editor works...
        +		    $line = $_;
        +		} else {
        +		    $def .= $_;
        +		}
        +	    }
        +	}
        +
        +	print STDERR "                                  \r" if $debug;
        +        $defnr = 0;
        +	# Delete any DECLARE_ macros
        +	$def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
        +	foreach (split /;/, $def) {
        +	    $defnr++;
        +	    print STDERR "def: $defnr\r" if $debug;
        +
        +	    # The goal is to collect function names from function declarations.
        +
        +	    s/^[\n\s]*//g;
        +	    s/[\n\s]*$//g;
        +
        +	    # Skip over recognized non-function declarations
        +	    next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
        +
        +	    # Remove STACK_OF(foo)
        +	    s/STACK_OF\(\w+\)/void/;
        +
        +	    # Reduce argument lists to empty ()
        +	    # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
        +	    while(/\(.*\)/s) {
        +		s/\([^\(\)]+\)/\{\}/gs;
        +		s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs;	#(*f{}) -> f
        +	    }
        +	    # pretend as we didn't use curly braces: {} -> ()
        +	    s/\{\}/\(\)/gs;
        +
        +	    if (/(\w+)\s*\(\).*/s) {	# first token prior [first] () is
        +		my $name = $1;		# a function name!
        +		$name =~ tr/[a-z]/[A-Z]/;
        +		$ftrans{$name} = $1;
        +	    } elsif (/[\(\)]/ and not (/=/)) {
        +		print STDERR "Header $hdr: cannot parse: $_;\n";
        +	    }
        +	}
        +
        +	print STDERR "                                  \r" if $debug;
        +
        +	next if $reindex;
        +
        +	# Scan function and reason codes and store them: keep a note of the
        +	# maximum code used.
        +
        +	if ($gotfile) {
        +	  while(<IN>) {
        +		if(/^\#define\s+(\S+)\s+(\S+)/) {
        +			$name = $1;
        +			$code = $2;
        +			next if $name =~ /^${lib}err/;
        +			unless($name =~ /^${lib}_([RF])_(\w+)$/) {
        +				print STDERR "Invalid error code $name\n";
        +				next;
        +			}
        +			if($1 eq "R") {
        +				$rcodes{$name} = $code;
        +				if ($rassigned{$lib} =~ /:$code:/) {
        +					print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
        +					++$errcount;
        +				}
        +				$rassigned{$lib} .= "$code:";
        +				if(!(exists $rextra{$name}) &&
        +					 ($code > $rmax{$lib}) ) {
        +					$rmax{$lib} = $code;
        +				}
        +			} else {
        +				if ($fassigned{$lib} =~ /:$code:/) {
        +					print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
        +					++$errcount;
        +				}
        +				$fassigned{$lib} .= "$code:";
        +				if($code > $fmax{$lib}) {
        +					$fmax{$lib} = $code;
        +				}
        +				$fcodes{$name} = $code;
        +			}
        +		}
        +	  }
        +	}
        +
        +	if ($debug) {
        +		if (defined($fmax{$lib})) {
        +			print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
        +			$fassigned{$lib} =~ m/^:(.*):$/;
        +			@fassigned = sort {$a <=> $b} split(":", $1);
        +			print STDERR "  @fassigned\n";
        +		}
        +		if (defined($rmax{$lib})) {
        +			print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
        +			$rassigned{$lib} =~ m/^:(.*):$/;
        +			@rassigned = sort {$a <=> $b} split(":", $1);
        +			print STDERR "  @rassigned\n";
        +		}
        +	}
        +
        +	if ($lib eq "SSL") {
        +		if ($rmax{$lib} >= 1000) {
        +			print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
        +			print STDERR "!!        Any new alerts must be added to $config.\n";
        +			++$errcount;
        +			print STDERR "\n";
        +		}
        +	}
        +	close IN;
        +}
        +
        +# Scan each C source file and look for function and reason codes
        +# This is done by looking for strings that "look like" function or
        +# reason codes: basically anything consisting of all upper case and
        +# numerics which has _F_ or _R_ in it and which has the name of an
        +# error library at the start. This seems to work fine except for the
        +# oddly named structure BIO_F_CTX which needs to be ignored.
        +# If a code doesn't exist in list compiled from headers then mark it
        +# with the value "X" as a place holder to give it a value later.
        +# Store all function and reason codes found in %ufcodes and %urcodes
        +# so all those unreferenced can be printed out.
        +
        +
        +foreach $file (@source) {
        +	# Don't parse the error source file.
        +	next if exists $cskip{$file};
        +	print STDERR "File loaded: ".$file."\r" if $debug;
        +	open(IN, "<$file") || die "Can't open source file $file\n";
        +	while(<IN>) {
        +		# skip obsoleted source files entirely!
        +		last if(/^#error\s+obsolete/);
        +
        +		if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
        +			next unless exists $csrc{$2};
        +			next if($1 eq "BIO_F_BUFFER_CTX");
        +			$ufcodes{$1} = 1;
        +			if(!exists $fcodes{$1}) {
        +				$fcodes{$1} = "X";
        +				$fnew{$2}++;
        +			}
        +			$notrans{$1} = 1 unless exists $ftrans{$3};
        +			print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug; 
        +		}
        +		if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
        +			next unless exists $csrc{$2};
        +			$urcodes{$1} = 1;
        +			if(!exists $rcodes{$1}) {
        +				$rcodes{$1} = "X";
        +				$rnew{$2}++;
        +			}
        +			print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug; 
        +		} 
        +	}
        +	close IN;
        +}
        +print STDERR "                                  \n" if $debug;
        +
        +# Now process each library in turn.
        +
        +foreach $lib (keys %csrc)
        +{
        +	my $hfile = $hinc{$lib};
        +	my $cfile = $csrc{$lib};
        +	if(!$fnew{$lib} && !$rnew{$lib}) {
        +		print STDERR "$lib:\t\tNo new error codes\n";
        +		next unless $rebuild;
        +	} else {
        +		print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
        +		print STDERR " $rnew{$lib} New Reasons.\n";
        +		next unless $dowrite;
        +	}
        +
        +	# If we get here then we have some new error codes so we
        +	# need to rebuild the header file and C file.
        +
        +	# Make a sorted list of error and reason codes for later use.
        +
        +	my @function = sort grep(/^${lib}_/,keys %fcodes);
        +	my @reasons = sort grep(/^${lib}_/,keys %rcodes);
        +
        +	# Rewrite the header file
        +
        +	if (open(IN, "<$hfile")) {
        +	    # Copy across the old file
        +	    while(<IN>) {
        +		push @out, $_;
        +		last if (/BEGIN ERROR CODES/);
        +	    }
        +	    close IN;
        +	} else {
        +	    push @out,
        +"/* ====================================================================\n",
        +" * Copyright (c) 2001-2011 The OpenSSL Project.  All rights reserved.\n",
        +" *\n",
        +" * Redistribution and use in source and binary forms, with or without\n",
        +" * modification, are permitted provided that the following conditions\n",
        +" * are met:\n",
        +" *\n",
        +" * 1. Redistributions of source code must retain the above copyright\n",
        +" *    notice, this list of conditions and the following disclaimer. \n",
        +" *\n",
        +" * 2. Redistributions in binary form must reproduce the above copyright\n",
        +" *    notice, this list of conditions and the following disclaimer in\n",
        +" *    the documentation and/or other materials provided with the\n",
        +" *    distribution.\n",
        +" *\n",
        +" * 3. All advertising materials mentioning features or use of this\n",
        +" *    software must display the following acknowledgment:\n",
        +" *    \"This product includes software developed by the OpenSSL Project\n",
        +" *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
        +" *\n",
        +" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
        +" *    endorse or promote products derived from this software without\n",
        +" *    prior written permission. For written permission, please contact\n",
        +" *    openssl-core\@openssl.org.\n",
        +" *\n",
        +" * 5. Products derived from this software may not be called \"OpenSSL\"\n",
        +" *    nor may \"OpenSSL\" appear in their names without prior written\n",
        +" *    permission of the OpenSSL Project.\n",
        +" *\n",
        +" * 6. Redistributions of any form whatsoever must retain the following\n",
        +" *    acknowledgment:\n",
        +" *    \"This product includes software developed by the OpenSSL Project\n",
        +" *    for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
        +" *\n",
        +" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
        +" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
        +" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
        +" * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
        +" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
        +" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
        +" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
        +" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
        +" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
        +" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
        +" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
        +" * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
        +" * ====================================================================\n",
        +" *\n",
        +" * This product includes cryptographic software written by Eric Young\n",
        +" * (eay\@cryptsoft.com).  This product includes software written by Tim\n",
        +" * Hudson (tjh\@cryptsoft.com).\n",
        +" *\n",
        +" */\n",
        +"\n",
        +"#ifndef HEADER_${lib}_ERR_H\n",
        +"#define HEADER_${lib}_ERR_H\n",
        +"\n",
        +"#ifdef  __cplusplus\n",
        +"extern \"C\" {\n",
        +"#endif\n",
        +"\n",
        +"/* BEGIN ERROR CODES */\n";
        +	}
        +	open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
        +
        +	print OUT @out;
        +	undef @out;
        +	print OUT <<"EOF";
        +/* 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.
        + */
        +EOF
        +	if($static) {
        +		print OUT <<"EOF";
        +${staticloader}void ERR_load_${lib}_strings(void);
        +
        +EOF
        +	} else {
        +		print OUT <<"EOF";
        +${staticloader}void ERR_load_${lib}_strings(void);
        +${staticloader}void ERR_unload_${lib}_strings(void);
        +${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
        +#define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
        +
        +EOF
        +	}
        +	print OUT <<"EOF";
        +/* Error codes for the $lib functions. */
        +
        +/* Function codes. */
        +EOF
        +
        +	foreach $i (@function) {
        +		$z=6-int(length($i)/8);
        +		if($fcodes{$i} eq "X") {
        +			$fassigned{$lib} =~ m/^:([^:]*):/;
        +			$findcode = $1;
        +			if (!defined($findcode)) {
        +				$findcode = $fmax{$lib};
        +			}
        +			while ($fassigned{$lib} =~ m/:$findcode:/) {
        +				$findcode++;
        +			}
        +			$fcodes{$i} = $findcode;
        +			$fassigned{$lib} .= "$findcode:";
        +			print STDERR "New Function code $i\n" if $debug;
        +		}
        +		printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z;
        +	}
        +
        +	print OUT "\n/* Reason codes. */\n";
        +
        +	foreach $i (@reasons) {
        +		$z=6-int(length($i)/8);
        +		if($rcodes{$i} eq "X") {
        +			$rassigned{$lib} =~ m/^:([^:]*):/;
        +			$findcode = $1;
        +			if (!defined($findcode)) {
        +				$findcode = $rmax{$lib};
        +			}
        +			while ($rassigned{$lib} =~ m/:$findcode:/) {
        +				$findcode++;
        +			}
        +			$rcodes{$i} = $findcode;
        +			$rassigned{$lib} .= "$findcode:";
        +			print STDERR "New Reason code   $i\n" if $debug;
        +		}
        +		printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z;
        +	}
        +	print OUT <<"EOF";
        +
        +#ifdef  __cplusplus
        +}
        +#endif
        +#endif
        +EOF
        +	close OUT;
        +
        +	# Rewrite the C source file containing the error details.
        +
        +	# First, read any existing reason string definitions:
        +	my %err_reason_strings;
        +	if (open(IN,"<$cfile")) {
        +		while (<IN>) {
        +			if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
        +				$err_reason_strings{$1} = $2;
        +			}
        +			if (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
        +				if (!exists $ftrans{$1} && ($1 ne $2)) {
        +					print STDERR "WARNING: Mismatched function string $2\n";
        +					$ftrans{$1} = $2;
        +				}
        +			}
        +		}
        +		close(IN);
        +	}
        +
        +
        +	my $hincf;
        +	if($static) {
        +		$hfile =~ /([^\/]+)$/;
        +		$hincf = "<${hprefix}$1>";
        +	} else {
        +		$hincf = "\"$hfile\"";
        +	}
        +
        +	# If static we know the error code at compile time so use it
        +	# in error definitions.
        +
        +	if ($static)
        +		{
        +		$pack_errcode = "ERR_LIB_${lib}";
        +		$load_errcode = "0";
        +		}
        +	else
        +		{
        +		$pack_errcode = "0";
        +		$load_errcode = "ERR_LIB_${lib}";
        +		}
        +
        +
        +	open (OUT,">$cfile") || die "Can't open $cfile for writing";
        +
        +	print OUT <<"EOF";
        +/* $cfile */
        +/* ====================================================================
        + * Copyright (c) 1999-2011 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 <stdio.h>
        +#include <openssl/err.h>
        +#include $hincf
        +
        +/* BEGIN ERROR CODES */
        +#ifndef OPENSSL_NO_ERR
        +
        +#define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
        +#define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
        +
        +static ERR_STRING_DATA ${lib}_str_functs[]=
        +	{
        +EOF
        +	# Add each function code: if a function name is found then use it.
        +	foreach $i (@function) {
        +		my $fn;
        +		$i =~ /^${lib}_F_(\S+)$/;
        +		$fn = $1;
        +		if(exists $ftrans{$fn}) {
        +			$fn = $ftrans{$fn};
        +		}
        +#		print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
        +		print OUT "{ERR_FUNC($i),\t\"$fn\"},\n";
        +	}
        +	print OUT <<"EOF";
        +{0,NULL}
        +	};
        +
        +static ERR_STRING_DATA ${lib}_str_reasons[]=
        +	{
        +EOF
        +	# Add each reason code.
        +	foreach $i (@reasons) {
        +		my $rn;
        +		my $rstr = "ERR_REASON($i)";
        +		my $nspc = 0;
        +		if (exists $err_reason_strings{$i}) {
        +			$rn = $err_reason_strings{$i};
        +		} else {
        +			$i =~ /^${lib}_R_(\S+)$/;
        +			$rn = $1;
        +			$rn =~ tr/_[A-Z]/ [a-z]/;
        +		}
        +		$nspc = 40 - length($rstr) unless length($rstr) > 40;
        +		$nspc = " " x $nspc;
        +		print OUT "{${rstr}${nspc},\"$rn\"},\n";
        +	}
        +if($static) {
        +	print OUT <<"EOF";
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +${staticloader}void ERR_load_${lib}_strings(void)
        +	{
        +#ifndef OPENSSL_NO_ERR
        +
        +	if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL)
        +		{
        +		ERR_load_strings($load_errcode,${lib}_str_functs);
        +		ERR_load_strings($load_errcode,${lib}_str_reasons);
        +		}
        +#endif
        +	}
        +EOF
        +} else {
        +	print OUT <<"EOF";
        +{0,NULL}
        +	};
        +
        +#endif
        +
        +#ifdef ${lib}_LIB_NAME
        +static ERR_STRING_DATA ${lib}_lib_name[]=
        +        {
        +{0	,${lib}_LIB_NAME},
        +{0,NULL}
        +	};
        +#endif
        +
        +
        +static int ${lib}_lib_error_code=0;
        +static int ${lib}_error_init=1;
        +
        +${staticloader}void ERR_load_${lib}_strings(void)
        +	{
        +	if (${lib}_lib_error_code == 0)
        +		${lib}_lib_error_code=ERR_get_next_error_library();
        +
        +	if (${lib}_error_init)
        +		{
        +		${lib}_error_init=0;
        +#ifndef OPENSSL_NO_ERR
        +		ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs);
        +		ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons);
        +#endif
        +
        +#ifdef ${lib}_LIB_NAME
        +		${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0);
        +		ERR_load_strings(0,${lib}_lib_name);
        +#endif
        +		}
        +	}
        +
        +${staticloader}void ERR_unload_${lib}_strings(void)
        +	{
        +	if (${lib}_error_init == 0)
        +		{
        +#ifndef OPENSSL_NO_ERR
        +		ERR_unload_strings(${lib}_lib_error_code,${lib}_str_functs);
        +		ERR_unload_strings(${lib}_lib_error_code,${lib}_str_reasons);
        +#endif
        +
        +#ifdef ${lib}_LIB_NAME
        +		ERR_unload_strings(0,${lib}_lib_name);
        +#endif
        +		${lib}_error_init=1;
        +		}
        +	}
        +
        +${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
        +	{
        +	if (${lib}_lib_error_code == 0)
        +		${lib}_lib_error_code=ERR_get_next_error_library();
        +	ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line);
        +	}
        +EOF
        +
        +}
        +
        +	close OUT;
        +	undef %err_reason_strings;
        +}
        +
        +if($debug && %notrans) {
        +	print STDERR "The following function codes were not translated:\n";
        +	foreach(sort keys %notrans)
        +	{
        +		print STDERR "$_\n";
        +	}
        +}
        +
        +# Make a list of unreferenced function and reason codes
        +
        +foreach (keys %fcodes) {
        +	push (@funref, $_) unless exists $ufcodes{$_};
        +}
        +
        +foreach (keys %rcodes) {
        +	push (@runref, $_) unless exists $urcodes{$_};
        +}
        +
        +if($debug && defined(@funref) ) {
        +	print STDERR "The following function codes were not referenced:\n";
        +	foreach(sort @funref)
        +	{
        +		print STDERR "$_\n";
        +	}
        +}
        +
        +if($debug && defined(@runref) ) {
        +	print STDERR "The following reason codes were not referenced:\n";
        +	foreach(sort @runref)
        +	{
        +		print STDERR "$_\n";
        +	}
        +}
        +
        +if($errcount) {
        +	print STDERR "There were errors, failing...\n\n";
        +	exit $errcount;
        +}
        +
        diff --git a/vendor/openssl/openssl/util/mkfiles.pl b/vendor/openssl/openssl/util/mkfiles.pl
        new file mode 100644
        index 000000000..7d9a9d5e5
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkfiles.pl
        @@ -0,0 +1,143 @@
        +#!/usr/local/bin/perl
        +#
        +# This is a hacked version of files.pl for systems that can't do a 'make files'.
        +# Do a perl util/mkminfo.pl >MINFO to build MINFO
        +# Written by Steve Henson 1999.
        +
        +# List of directories to process
        +
        +my @dirs = (
        +".",
        +"crypto",
        +"crypto/md2",
        +"crypto/md4",
        +"crypto/md5",
        +"crypto/sha",
        +"crypto/mdc2",
        +"crypto/hmac",
        +"crypto/cmac",
        +"crypto/ripemd",
        +"crypto/des",
        +"crypto/rc2",
        +"crypto/rc4",
        +"crypto/rc5",
        +"crypto/idea",
        +"crypto/bf",
        +"crypto/cast",
        +"crypto/aes",
        +"crypto/camellia",
        +"crypto/seed",
        +"crypto/modes",
        +"crypto/bn",
        +"crypto/rsa",
        +"crypto/dsa",
        +"crypto/dso",
        +"crypto/dh",
        +"crypto/ec",
        +"crypto/ecdh",
        +"crypto/ecdsa",
        +"crypto/buffer",
        +"crypto/bio",
        +"crypto/stack",
        +"crypto/lhash",
        +"crypto/rand",
        +"crypto/err",
        +"crypto/objects",
        +"crypto/evp",
        +"crypto/asn1",
        +"crypto/pem",
        +"crypto/x509",
        +"crypto/x509v3",
        +"crypto/cms",
        +"crypto/conf",
        +"crypto/jpake",
        +"crypto/txt_db",
        +"crypto/pkcs7",
        +"crypto/pkcs12",
        +"crypto/comp",
        +"crypto/engine",
        +"crypto/ocsp",
        +"crypto/ui",
        +"crypto/krb5",
        +#"crypto/store",
        +"crypto/pqueue",
        +"crypto/whrlpool",
        +"crypto/ts",
        +"crypto/srp",
        +"ssl",
        +"apps",
        +"engines",
        +"engines/ccgost",
        +"test",
        +"tools"
        +);
        +
        +%top;
        +
        +foreach (@dirs) {
        +	&files_dir ($_, "Makefile");
        +}
        +
        +exit(0);
        +
        +sub files_dir
        +{
        +my ($dir, $makefile) = @_;
        +
        +my %sym;
        +
        +open (IN, "$dir/$makefile") || die "Can't open $dir/$makefile";
        +
        +my $s="";
        +
        +while (<IN>)
        +	{
        +	chop;
        +	s/#.*//;
        +	if (/^(\S+)\s*=\s*(.*)$/)
        +		{
        +		$o="";
        +		($s,$b)=($1,$2);
        +		for (;;)
        +			{
        +			if ($b =~ /\\$/)
        +				{
        +				chop($b);
        +				$o.=$b." ";
        +				$b=<IN>;
        +				chop($b);
        +				}
        +			else
        +				{
        +				$o.=$b." ";
        +				last;
        +				}
        +			}
        +		$o =~ s/^\s+//;
        +		$o =~ s/\s+$//;
        +		$o =~ s/\s+/ /g;
        +
        +		$o =~ s/\$[({]([^)}]+)[)}]/$top{$1} or $sym{$1}/ge;
        +		$sym{$s}=($top{$s} or $o);
        +		}
        +	}
        +
        +print "RELATIVE_DIRECTORY=$dir\n";
        +
        +foreach (sort keys %sym)
        +	{
        +	print "$_=$sym{$_}\n";
        +	}
        +if ($dir eq "." && defined($sym{"BUILDENV"}))
        +	{
        +	foreach (split(' ',$sym{"BUILDENV"}))
        +		{
        +		/^(.+)=/;
        +		$top{$1}=$sym{$1};
        +		}
        +	}
        +
        +print "RELATIVE_DIRECTORY=\n";
        +
        +close (IN);
        +}
        diff --git a/vendor/openssl/openssl/util/mklink.pl b/vendor/openssl/openssl/util/mklink.pl
        new file mode 100644
        index 000000000..61db12c68
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mklink.pl
        @@ -0,0 +1,73 @@
        +#!/usr/local/bin/perl
        +
        +# mklink.pl
        +
        +# The first command line argument is a non-empty relative path
        +# specifying the "from" directory.
        +# Each other argument is a file name not containing / and
        +# names a file in the current directory.
        +#
        +# For each of these files, we create in the "from" directory a link
        +# of the same name pointing to the local file.
        +#
        +# We assume that the directory structure is a tree, i.e. that it does
        +# not contain symbolic links and that the parent of / is never referenced.
        +# Apart from this, this script should be able to handle even the most
        +# pathological cases.
        +
        +use Cwd;
        +
        +my $from = shift;
        +my @files = @ARGV;
        +
        +my @from_path = split(/[\\\/]/, $from);
        +my $pwd = getcwd();
        +chomp($pwd);
        +my @pwd_path = split(/[\\\/]/, $pwd);
        +
        +my @to_path = ();
        +
        +my $dirname;
        +foreach $dirname (@from_path) {
        +
        +    # In this loop, @to_path always is a relative path from
        +    # @pwd_path (interpreted is an absolute path) to the original pwd.
        +
        +    # At the end, @from_path (as a relative path from the original pwd)
        +    # designates the same directory as the absolute path @pwd_path,
        +    # which means that @to_path then is a path from there to the original pwd.
        +
        +    next if ($dirname eq "" || $dirname eq ".");
        +
        +    if ($dirname eq "..") {
        +	@to_path = (pop(@pwd_path), @to_path);
        +    } else {
        +	@to_path = ("..", @to_path);
        +	push(@pwd_path, $dirname);
        +    }
        +}
        +
        +my $to = join('/', @to_path);
        +
        +my $file;
        +$symlink_exists=eval {symlink("",""); 1};
        +if ($^O eq "msys") { $symlink_exists=0 };
        +foreach $file (@files) {
        +    my $err = "";
        +    if ($symlink_exists) {
        +	unlink "$from/$file";
        +	symlink("$to/$file", "$from/$file") or $err = " [$!]";
        +    } else {
        +	unlink "$from/$file"; 
        +	open (OLD, "<$file") or die "Can't open $file: $!";
        +	open (NEW, ">$from/$file") or die "Can't open $from/$file: $!";
        +	binmode(OLD);
        +	binmode(NEW);
        +	while (<OLD>) {
        +	    print NEW $_;
        +	}
        +	close (OLD) or die "Can't close $file: $!";
        +	close (NEW) or die "Can't close $from/$file: $!";
        +    }
        +    print $file . " => $from/$file$err\n";
        +}
        diff --git a/vendor/openssl/openssl/util/mkrc.pl b/vendor/openssl/openssl/util/mkrc.pl
        new file mode 100644
        index 000000000..0ceadcf8d
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkrc.pl
        @@ -0,0 +1,71 @@
        +#!/bin/env perl
        +#
        +open FD,"crypto/opensslv.h";
        +while(<FD>) {
        +    if (/OPENSSL_VERSION_NUMBER\s+(0x[0-9a-f]+)/i) {
        +	$ver = hex($1);
        +	$v1 = ($ver>>28);
        +	$v2 = ($ver>>20)&0xff;
        +	$v3 = ($ver>>12)&0xff;
        +	$v4 = ($ver>> 4)&0xff;
        +	$beta = $ver&0xf;
        +	$version = "$v1.$v2.$v3";
        +	if ($beta==0xf)	{ $version .= chr(ord('a')+$v4-1) if ($v4);	}
        +	elsif ($beta==0){ $version .= "-dev";				}
        +	else		{ $version .= "-beta$beta";			}
        +	last;
        +    }
        +}
        +close(FD);
        +
        +$filename = $ARGV[0]; $filename =~ /(.*)\.([^.]+)$/;
        +$basename = $1;
        +$extname  = $2;
        +
        +if ($extname =~ /dll/i)	{ $description = "OpenSSL shared library"; }
        +else			{ $description = "OpenSSL application";    }
        +
        +print <<___;
        +#include <winver.h>
        +
        +LANGUAGE 0x09,0x01
        +
        +1 VERSIONINFO
        +  FILEVERSION $v1,$v2,$v3,$v4
        +  PRODUCTVERSION $v1,$v2,$v3,$v4
        +  FILEFLAGSMASK 0x3fL
        +#ifdef _DEBUG
        +  FILEFLAGS 0x01L
        +#else
        +  FILEFLAGS 0x00L
        +#endif
        +  FILEOS VOS__WINDOWS32
        +  FILETYPE VFT_DLL
        +  FILESUBTYPE 0x0L
        +BEGIN
        +    BLOCK "StringFileInfo"
        +    BEGIN
        +        BLOCK "040904b0"
        +        BEGIN
        +            // Required:
        +            VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
        +            VALUE "FileDescription", "$description\\0"
        +            VALUE "FileVersion", "$version\\0"
        +            VALUE "InternalName", "$basename\\0"
        +            VALUE "OriginalFilename", "$filename\\0"
        +            VALUE "ProductName", "The OpenSSL Toolkit\\0"
        +            VALUE "ProductVersion", "$version\\0"
        +            // Optional:
        +            //VALUE "Comments", "\\0"
        +            VALUE "LegalCopyright", "Copyright © 1998-2006 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
        +            //VALUE "LegalTrademarks", "\\0"
        +            //VALUE "PrivateBuild", "\\0"
        +            //VALUE "SpecialBuild", "\\0"
        +        END
        +    END
        +    BLOCK "VarFileInfo"
        +    BEGIN
        +        VALUE "Translation", 0x409, 0x4b0
        +    END
        +END
        +___
        diff --git a/vendor/openssl/openssl/util/mkstack.pl b/vendor/openssl/openssl/util/mkstack.pl
        new file mode 100644
        index 000000000..f708610a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/mkstack.pl
        @@ -0,0 +1,192 @@
        +#!/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 = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <ssl/*.[ch]>, <apps/*.[ch]>);
        +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(<IN>) {
        +		if (/^DECLARE_STACK_OF\(([^)]+)\)/) {
        +			push @stacklst, $1;
        +		}
        +	        if (/^DECLARE_SPECIAL_STACK_OF\(([^,\s]+)\s*,\s*([^>\s]+)\)/) {
        +		    	push @sstacklst, [$1, $2];
        +		}
        +		if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) {
        +			push @asn1setlst, $1;
        +		}
        +		if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) {
        +			push @p12stklst, $1;
        +		}
        +		if (/^DECLARE_LHASH_OF\(([^)]+)\)/) {
        +			push @lhashlst, $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(<IN>) {
        +	$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 .= <<EOF;
        +
        +#define sk_${type_thing}_new(cmp) SKM_sk_new($type_thing, (cmp))
        +#define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing)
        +#define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st))
        +#define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st))
        +#define sk_${type_thing}_value(st, i) SKM_sk_value($type_thing, (st), (i))
        +#define sk_${type_thing}_set(st, i, val) SKM_sk_set($type_thing, (st), (i), (val))
        +#define sk_${type_thing}_zero(st) SKM_sk_zero($type_thing, (st))
        +#define sk_${type_thing}_push(st, val) SKM_sk_push($type_thing, (st), (val))
        +#define sk_${type_thing}_unshift(st, val) SKM_sk_unshift($type_thing, (st), (val))
        +#define sk_${type_thing}_find(st, val) SKM_sk_find($type_thing, (st), (val))
        +#define sk_${type_thing}_find_ex(st, val) SKM_sk_find_ex($type_thing, (st), (val))
        +#define sk_${type_thing}_delete(st, i) SKM_sk_delete($type_thing, (st), (i))
        +#define sk_${type_thing}_delete_ptr(st, ptr) SKM_sk_delete_ptr($type_thing, (st), (ptr))
        +#define sk_${type_thing}_insert(st, val, i) SKM_sk_insert($type_thing, (st), (val), (i))
        +#define sk_${type_thing}_set_cmp_func(st, cmp) SKM_sk_set_cmp_func($type_thing, (st), (cmp))
        +#define sk_${type_thing}_dup(st) SKM_sk_dup($type_thing, st)
        +#define sk_${type_thing}_pop_free(st, free_func) SKM_sk_pop_free($type_thing, (st), (free_func))
        +#define sk_${type_thing}_shift(st) SKM_sk_shift($type_thing, (st))
        +#define sk_${type_thing}_pop(st) SKM_sk_pop($type_thing, (st))
        +#define sk_${type_thing}_sort(st) SKM_sk_sort($type_thing, (st))
        +#define sk_${type_thing}_is_sorted(st) SKM_sk_is_sorted($type_thing, (st))
        +EOF
        +	}
        +
        +	foreach $type_thing (sort @sstacklst) {
        +	    my $t1 = $type_thing->[0];
        +	    my $t2 = $type_thing->[1];
        +	    $new_stackfile .= <<EOF;
        +
        +#define sk_${t1}_new(cmp) ((STACK_OF($t1) *)sk_new(CHECKED_SK_CMP_FUNC($t2, cmp)))
        +#define sk_${t1}_new_null() ((STACK_OF($t1) *)sk_new_null())
        +#define sk_${t1}_push(st, val) sk_push(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
        +#define sk_${t1}_find(st, val) sk_find(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
        +#define sk_${t1}_value(st, i) (($t1)sk_value(CHECKED_STACK_OF($t1, st), i))
        +#define sk_${t1}_num(st) SKM_sk_num($t1, st)
        +#define sk_${t1}_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF($t1, st), CHECKED_SK_FREE_FUNC2($t1, free_func))
        +#define sk_${t1}_insert(st, val, i) sk_insert(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val), i)
        +#define sk_${t1}_free(st) SKM_sk_free(${t1}, st)
        +#define sk_${t1}_set(st, i, val) sk_set(CHECKED_STACK_OF($t1, st), i, CHECKED_PTR_OF($t2, val))
        +#define sk_${t1}_zero(st) SKM_sk_zero($t1, (st))
        +#define sk_${t1}_unshift(st, val) sk_unshift(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
        +#define sk_${t1}_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF($t1), st), CHECKED_CONST_PTR_OF($t2, val))
        +#define sk_${t1}_delete(st, i) SKM_sk_delete($t1, (st), (i))
        +#define sk_${t1}_delete_ptr(st, ptr) ($t1 *)sk_delete_ptr(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, ptr))
        +#define sk_${t1}_set_cmp_func(st, cmp)  \\
        +	((int (*)(const $t2 * const *,const $t2 * const *)) \\
        +	sk_set_cmp_func(CHECKED_STACK_OF($t1, st), CHECKED_SK_CMP_FUNC($t2, cmp)))
        +#define sk_${t1}_dup(st) SKM_sk_dup($t1, st)
        +#define sk_${t1}_shift(st) SKM_sk_shift($t1, (st))
        +#define sk_${t1}_pop(st) ($t2 *)sk_pop(CHECKED_STACK_OF($t1, st))
        +#define sk_${t1}_sort(st) SKM_sk_sort($t1, (st))
        +#define sk_${t1}_is_sorted(st) SKM_sk_is_sorted($t1, (st))
        +
        +EOF
        +	}
        +
        +	foreach $type_thing (sort @asn1setlst) {
        +		$new_stackfile .= <<EOF;
        +
        +#define d2i_ASN1_SET_OF_${type_thing}(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \\
        +	SKM_ASN1_SET_OF_d2i($type_thing, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
        +#define i2d_ASN1_SET_OF_${type_thing}(st, pp, i2d_func, ex_tag, ex_class, is_set) \\
        +	SKM_ASN1_SET_OF_i2d($type_thing, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
        +#define ASN1_seq_pack_${type_thing}(st, i2d_func, buf, len) \\
        +	SKM_ASN1_seq_pack($type_thing, (st), (i2d_func), (buf), (len))
        +#define ASN1_seq_unpack_${type_thing}(buf, len, d2i_func, free_func) \\
        +	SKM_ASN1_seq_unpack($type_thing, (buf), (len), (d2i_func), (free_func))
        +EOF
        +	}
        +	foreach $type_thing (sort @p12stklst) {
        +		$new_stackfile .= <<EOF;
        +
        +#define PKCS12_decrypt_d2i_${type_thing}(algor, d2i_func, free_func, pass, passlen, oct, seq) \\
        +	SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
        +EOF
        +	}
        +
        +	foreach $type_thing (sort @lhashlst) {
        +		my $lc_tt = lc $type_thing;
        +		$new_stackfile .= <<EOF;
        +
        +#define lh_${type_thing}_new() LHM_lh_new(${type_thing},${lc_tt})
        +#define lh_${type_thing}_insert(lh,inst) LHM_lh_insert(${type_thing},lh,inst)
        +#define lh_${type_thing}_retrieve(lh,inst) LHM_lh_retrieve(${type_thing},lh,inst)
        +#define lh_${type_thing}_delete(lh,inst) LHM_lh_delete(${type_thing},lh,inst)
        +#define lh_${type_thing}_doall(lh,fn) LHM_lh_doall(${type_thing},lh,fn)
        +#define lh_${type_thing}_doall_arg(lh,fn,arg_type,arg) \\
        +  LHM_lh_doall_arg(${type_thing},lh,fn,arg_type,arg)
        +#define lh_${type_thing}_error(lh) LHM_lh_error(${type_thing},lh)
        +#define lh_${type_thing}_num_items(lh) LHM_lh_num_items(${type_thing},lh)
        +#define lh_${type_thing}_down_load(lh) LHM_lh_down_load(${type_thing},lh)
        +#define lh_${type_thing}_node_stats_bio(lh,out) \\
        +  LHM_lh_node_stats_bio(${type_thing},lh,out)
        +#define lh_${type_thing}_node_usage_stats_bio(lh,out) \\
        +  LHM_lh_node_usage_stats_bio(${type_thing},lh,out)
        +#define lh_${type_thing}_stats_bio(lh,out) \\
        +  LHM_lh_stats_bio(${type_thing},lh,out)
        +#define lh_${type_thing}_free(lh) LHM_lh_free(${type_thing},lh)
        +EOF
        +	}
        +
        +	$new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n";
        +	$inside_block = 2;
        +}
        +
        +
        +if ($new_stackfile eq $old_stackfile) {
        +	print "No changes to $safestack.h.\n";
        +	exit 0; # avoid unnecessary rebuild
        +}
        +
        +if ($do_write) {
        +	print "Writing new $safestack.h.\n";
        +	open OUT, ">$safestack.h" || die "Can't open output file";
        +	print OUT $new_stackfile;
        +	close OUT;
        +}
        diff --git a/vendor/openssl/openssl/util/opensslwrap.sh b/vendor/openssl/openssl/util/opensslwrap.sh
        new file mode 100644
        index 000000000..b27cbb897
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/opensslwrap.sh
        @@ -0,0 +1,26 @@
        +#!/bin/sh
        +
        +HERE="`echo $0 | sed -e 's|[^/]*$||'`"
        +OPENSSL="${HERE}../apps/openssl"
        +
        +if [ -d "${HERE}../engines" -a "x$OPENSSL_ENGINES" = "x" ]; then
        +	OPENSSL_ENGINES="${HERE}../engines"; export OPENSSL_ENGINES
        +fi
        +
        +if [ -x "${OPENSSL}.exe" ]; then
        +	# The original reason for this script existence is to work around
        +	# certain caveats in run-time linker behaviour. On Windows platforms
        +	# adjusting $PATH used to be sufficient, but with introduction of
        +	# SafeDllSearchMode in XP/2003 the only way to get it right in
        +	# *all* possible situations is to copy newly built .DLLs to apps/
        +	# and test/, which is now done elsewhere... The $PATH is adjusted
        +	# for backward compatibility (and nostagical reasons:-).
        +	if [ "$OSTYPE" != msdosdjgpp ]; then
        +		PATH="${HERE}..:$PATH"; export PATH
        +	fi
        +	exec "${OPENSSL}.exe" "$@"
        +elif [ -x "${OPENSSL}" -a -x "${HERE}shlib_wrap.sh" ]; then
        +	exec "${HERE}shlib_wrap.sh" "${OPENSSL}" "$@"
        +else
        +	exec "${OPENSSL}" "$@"	# hope for the best...
        +fi
        diff --git a/vendor/openssl/openssl/util/perlpath.pl b/vendor/openssl/openssl/util/perlpath.pl
        new file mode 100644
        index 000000000..a1f236bd9
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/perlpath.pl
        @@ -0,0 +1,35 @@
        +#!/usr/local/bin/perl
        +#
        +# modify the '#!/usr/local/bin/perl'
        +# line in all scripts that rely on perl.
        +#
        +
        +require "find.pl";
        +
        +$#ARGV == 0 || print STDERR "usage: perlpath newpath  (eg /usr/bin)\n";
        +&find(".");
        +
        +sub wanted
        +	{
        +	return unless /\.pl$/ || /^[Cc]onfigur/;
        +
        +	open(IN,"<$_") || die "unable to open $dir/$_:$!\n";
        +	@a=<IN>;
        +	close(IN);
        +
        +	if (-d $ARGV[0]) {
        +		$a[0]="#!$ARGV[0]/perl\n";
        +	}
        +	else {
        +		$a[0]="#!$ARGV[0]\n";
        +	}
        +
        +	# Playing it safe...
        +	$new="$_.new";
        +	open(OUT,">$new") || die "unable to open $dir/$new:$!\n";
        +	print OUT @a;
        +	close(OUT);
        +
        +	rename($new,$_) || die "unable to rename $dir/$new:$!\n";
        +	chmod(0755,$_) || die "unable to chmod $dir/$new:$!\n";
        +	}
        diff --git a/vendor/openssl/openssl/util/pl/BC-32.pl b/vendor/openssl/openssl/util/pl/BC-32.pl
        new file mode 100644
        index 000000000..1f1e13fb4
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/BC-32.pl
        @@ -0,0 +1,139 @@
        +#!/usr/local/bin/perl
        +# Borland C++ builder 3 and 4 -- Janez Jere <jj@void.si>
        +#
        +
        +$ssl=	"ssleay32";
        +$crypto="libeay32";
        +
        +$o='\\';
        +$cp='copy';
        +$rm='del';
        +
        +# C compiler stuff
        +$cc='bcc32';
        +$lflags="-ap -Tpe -x -Gn ";
        +$mlflags='';
        +
        +$out_def="out32";
        +$tmp_def="tmp32";
        +$inc_def="inc32";
        +#enable max error messages, disable most common warnings
        +$cflags="-DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp ";
        +if ($debug)
        +{
        +    $cflags.="-Od -y -v -vi- -D_DEBUG";
        +    $mlflags.=' ';
        +}
        +else
        +{
        +    $cflags.="-O2 -ff -fp";
        +}
        +
        +$obj='.obj';
        +$ofile="-o";
        +
        +# EXE linking stuff
        +$link="ilink32";
        +$efile="";
        +$exep='.exe';
        +if ($no_sock)
        +	{ $ex_libs=""; }
        +else	{ $ex_libs="cw32mt.lib import32.lib"; }
        +
        +# static library stuff
        +$mklib='tlib /P64';
        +$ranlib='';
        +$plib="";
        +$libp=".lib";
        +$shlibp=($shlib)?".dll":".lib";
        +$lfile='';
        +
        +$shlib_ex_obj="";
        +$app_ex_obj="c0x32.obj"; 
        +
        +$asm='nasmw -f obj -d__omf__';
        +$asm.=" /Zi" if $debug;
        +$afile='-o';
        +
        +$bn_mulw_obj='';
        +$bn_mulw_src='';
        +$des_enc_obj='';
        +$des_enc_src='';
        +$bf_enc_obj='';
        +$bf_enc_src='';
        +
        +if (!$no_asm)
        +	{
        +	$bn_mulw_obj='crypto\bn\asm\bn_win32.obj';
        +	$bn_mulw_src='crypto\bn\asm\bn_win32.asm';
        +	$des_enc_obj='crypto\des\asm\d_win32.obj crypto\des\asm\y_win32.obj';
        +	$des_enc_src='crypto\des\asm\d_win32.asm crypto\des\asm\y_win32.asm';
        +	$bf_enc_obj='crypto\bf\asm\b_win32.obj';
        +	$bf_enc_src='crypto\bf\asm\b_win32.asm';
        +	$cast_enc_obj='crypto\cast\asm\c_win32.obj';
        +	$cast_enc_src='crypto\cast\asm\c_win32.asm';
        +	$rc4_enc_obj='crypto\rc4\asm\r4_win32.obj';
        +	$rc4_enc_src='crypto\rc4\asm\r4_win32.asm';
        +	$rc5_enc_obj='crypto\rc5\asm\r5_win32.obj';
        +	$rc5_enc_src='crypto\rc5\asm\r5_win32.asm';
        +	$md5_asm_obj='crypto\md5\asm\m5_win32.obj';
        +	$md5_asm_src='crypto\md5\asm\m5_win32.asm';
        +	$sha1_asm_obj='crypto\sha\asm\s1_win32.obj';
        +	$sha1_asm_src='crypto\sha\asm\s1_win32.asm';
        +	$rmd160_asm_obj='crypto\ripemd\asm\rm_win32.obj';
        +	$rmd160_asm_src='crypto\ripemd\asm\rm_win32.asm';
        +	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM";
        +	}
        +
        +if ($shlib)
        +	{
        +	$mlflags.=" $lflags /dll";
        +#	$cflags =~ s| /MD| /MT|;
        +	$lib_cflag=" /GD -D_WINDLL -D_DLL";
        +	$out_def="out32dll";
        +	$tmp_def="tmp32dll";
        +	}
        +
        +sub do_lib_rule
        +	{
        +	local($objs,$target,$name,$shlib)=@_;
        +	local($ret,$Name);
        +
        +	$taget =~ s/\//$o/g if $o ne '/';
        +	($Name=$name) =~ tr/a-z/A-Z/;
        +
        +#	$target="\$(LIB_D)$o$target";
        +	$ret.="$target: $objs\n";
        +	if (!$shlib)
        +		{
        +		$ret.=<<___;
        +	-\$(RM) $lfile$target
        +	\$(MKLIB) $lfile$target \@&&!
        ++\$(**: = &^
        ++)
        +!
        +___
        +		}
        +	else
        +		{
        +		local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':'';
        +		$ex.=' ws2_32.lib gdi32.lib';
        +		$ret.="\t\$(LINK) \$(MLFLAGS) $efile$target /def:ms/${Name}.def @<<\n  \$(SHLIB_EX_OBJ) $objs $ex\n<<\n";
        +		}
        +	$ret.="\n";
        +	return($ret);
        +	}
        +
        +sub do_link_rule
        +	{
        +	local($target,$files,$dep_libs,$libs)=@_;
        +	local($ret,$_);
        +	
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($targer);
        +	$ret.="$target: $files $dep_libs\n";
        +	$ret.="\t\$(LINK) \$(LFLAGS) $files \$(APP_EX_OBJ), $target,, $libs\n\n";
        +	return($ret);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/Mingw32.pl b/vendor/openssl/openssl/util/pl/Mingw32.pl
        new file mode 100644
        index 000000000..fe3fb27a7
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/Mingw32.pl
        @@ -0,0 +1,104 @@
        +#!/usr/local/bin/perl
        +#
        +# Mingw32.pl -- Mingw
        +#
        +
        +$o='/';
        +$cp='cp';
        +$rm='rm -f';
        +$mkdir='gmkdir';
        +
        +$o='\\';
        +$cp='copy';
        +$rm='del';
        +$mkdir='mkdir';
        +
        +# C compiler stuff
        +
        +$cc='gcc';
        +if ($debug)
        +	{ $cflags="-DL_ENDIAN -DDSO_WIN32 -g2 -ggdb"; }
        +else
        +	{ $cflags="-DL_ENDIAN -DDSO_WIN32 -fomit-frame-pointer -O3 -mcpu=i486 -Wall"; }
        +
        +if ($gaswin and !$no_asm)
        +	{
        +        $bn_asm_obj='$(OBJ_D)\bn-win32.o';
        +        $bn_asm_src='crypto/bn/asm/bn-win32.s';
        +        $bnco_asm_obj='$(OBJ_D)\co-win32.o';
        +        $bnco_asm_src='crypto/bn/asm/co-win32.s';
        +        $des_enc_obj='$(OBJ_D)\d-win32.o $(OBJ_D)\y-win32.o';
        +        $des_enc_src='crypto/des/asm/d-win32.s crypto/des/asm/y-win32.s';
        +        $bf_enc_obj='$(OBJ_D)\b-win32.o';
        +        $bf_enc_src='crypto/bf/asm/b-win32.s';
        +#       $cast_enc_obj='$(OBJ_D)\c-win32.o';
        +#       $cast_enc_src='crypto/cast/asm/c-win32.s';
        +        $rc4_enc_obj='$(OBJ_D)\r4-win32.o';
        +        $rc4_enc_src='crypto/rc4/asm/r4-win32.s';
        +        $rc5_enc_obj='$(OBJ_D)\r5-win32.o';
        +        $rc5_enc_src='crypto/rc5/asm/r5-win32.s';
        +        $md5_asm_obj='$(OBJ_D)\m5-win32.o';
        +        $md5_asm_src='crypto/md5/asm/m5-win32.s';
        +        $rmd160_asm_obj='$(OBJ_D)\rm-win32.o';
        +        $rmd160_asm_src='crypto/ripemd/asm/rm-win32.s';
        +        $sha1_asm_obj='$(OBJ_D)\s1-win32.o';
        +        $sha1_asm_src='crypto/sha/asm/s1-win32.s';
        +	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_BN_ASM_PART_WORDS";
        +	}
        +
        +
        +$obj='.o';
        +$ofile='-o ';
        +
        +# EXE linking stuff
        +$link='${CC}';
        +$lflags='${CFLAGS}';
        +$efile='-o ';
        +$exep='';
        +$ex_libs="-lws2_32 -lgdi32";
        +
        +# static library stuff
        +$mklib='ar r';
        +$mlflags='';
        +$ranlib='ranlib';
        +$plib='lib';
        +$libp=".a";
        +$shlibp=".a";
        +$lfile='';
        +
        +$asm='as';
        +$afile='-o ';
        +#$bn_asm_obj="";
        +#$bn_asm_src="";
        +#$des_enc_obj="";
        +#$des_enc_src="";
        +#$bf_enc_obj="";
        +#$bf_enc_src="";
        +
        +sub do_lib_rule
        +	{
        +	local($obj,$target,$name,$shlib)=@_;
        +	local($ret,$_,$Name);
        +
        +	$target =~ s/\//$o/g if $o ne '/';
        +	$target="$target";
        +	($Name=$name) =~ tr/a-z/A-Z/;
        +
        +	$ret.="$target: \$(${Name}OBJ)\n";
        +	$ret.="\tif exist $target \$(RM) $target\n";
        +	$ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
        +	$ret.="\t\$(RANLIB) $target\n\n";
        +	}
        +
        +sub do_link_rule
        +	{
        +	local($target,$files,$dep_libs,$libs)=@_;
        +	local($ret,$_);
        +	
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($target);
        +	$ret.="$target: $files $dep_libs\n";
        +	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
        +	return($ret);
        +	}
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/OS2-EMX.pl b/vendor/openssl/openssl/util/pl/OS2-EMX.pl
        new file mode 100644
        index 000000000..28cd11690
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/OS2-EMX.pl
        @@ -0,0 +1,120 @@
        +#!/usr/local/bin/perl
        +#
        +# OS2-EMX.pl - for EMX GCC on OS/2
        +#
        +
        +$o='/';
        +$cp='cp';
        +$rm='rm -f';
        +
        +$preamble = "SHELL=sh\n";
        +
        +# C compiler stuff
        +
        +$cc='gcc';
        +$cflags="-DL_ENDIAN -O3 -fomit-frame-pointer -m486 -Zmtd -Wall ";
        +$cflags.="-Zomf " if $shlib;
        +$shl_cflag="-Zdll";
        +
        +if ($debug) { 
        +	$cflags.="-g "; 
        +}
        +
        +$obj=$shlib ? '.obj' : '.o';
        +$ofile='-o ';
        +
        +# EXE linking stuff
        +$link='${CC}';
        +$lflags='${CFLAGS} -Zbsd-signals -s';
        +$efile='-o ';
        +$exep='.exe';
        +$ex_libs="-lsocket";
        +
        +# static library stuff
        +$mklib='ar r';
        +$mlflags='';
        +$ranlib="ar s";
        +$plib='';
        +$libp=$shlib ? ".lib" : ".a";
        +$shlibp=$shlib ? ".dll" : ".a";
        +$lfile='';
        +
        +$asm=$shlib ? 'as -Zomf' : 'as';
        +$afile='-o ';
        +$bn_asm_obj="";
        +$bn_asm_src="";
        +$des_enc_obj="";
        +$des_enc_src="";
        +$bf_enc_obj="";
        +$bf_enc_src="";
        +
        +if (!$no_asm)
        +	{
        +	$bn_asm_obj="crypto/bn/asm/bn-os2$obj crypto/bn/asm/co-os2$obj";
        +	$bn_asm_src="crypto/bn/asm/bn-os2.asm crypto/bn/asm/co-os2.asm";
        +	$des_enc_obj="crypto/des/asm/d-os2$obj crypto/des/asm/y-os2$obj";
        +	$des_enc_src="crypto/des/asm/d-os2.asm crypto/des/asm/y-os2.asm";
        +	$bf_enc_obj="crypto/bf/asm/b-os2$obj";
        +	$bf_enc_src="crypto/bf/asm/b-os2.asm";
        +	$cast_enc_obj="crypto/cast/asm/c-os2$obj";
        +	$cast_enc_src="crypto/cast/asm/c-os2.asm";
        +	$rc4_enc_obj="crypto/rc4/asm/r4-os2$obj";
        +	$rc4_enc_src="crypto/rc4/asm/r4-os2.asm";
        +	$rc5_enc_obj="crypto/rc5/asm/r5-os2$obj";
        +	$rc5_enc_src="crypto/rc5/asm/r5-os2.asm";
        +	$md5_asm_obj="crypto/md5/asm/m5-os2$obj";
        +	$md5_asm_src="crypto/md5/asm/m5-os2.asm";
        +	$sha1_asm_obj="crypto/sha/asm/s1-os2$obj";
        +	$sha1_asm_src="crypto/sha/asm/s1-os2.asm";
        +	$rmd160_asm_obj="crypto/ripemd/asm/rm-os2$obj";
        +	$rmd160_asm_src="crypto/ripemd/asm/rm-os2.asm";
        +	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_BN_ASM_PART_WORDS";
        +	}
        +
        +if ($shlib)
        +	{
        +	$mlflags.=" $lflags -Zdll";
        +	$lib_cflag=" -D_DLL";
        +	$out_def="out_dll";
        +	$tmp_def="tmp_dll";
        +	}
        +
        +sub do_lib_rule
        +	{
        +	local($obj,$target,$name,$shlib)=@_;
        +	local($ret,$_,$Name);
        +
        +	$target =~ s/\//$o/g if $o ne '/';
        +	$target="$target";
        +	($Name=$name) =~ tr/a-z/A-Z/;
        +
        +	$ret.="$target: \$(${Name}OBJ)\n";
        +	if (!$shlib) 
        +		{
        +		$ret.="\t\$(RM) $target\n";
        +		$ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
        +		$ret.="\t\$(RANLIB) $target\n\n";
        +		}
        +	else
        +		{
        +		local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':'';
        +		$ex.=' -lsocket';
        +		$ret.="\t\$(LINK) \$(SHLIB_CFLAGS) \$(MLFLAGS) $efile$target \$(SHLIB_EX_OBJ) \$(${Name}OBJ) $ex os2/${Name}.def\n";
        +		$ret.="\temximp -o $out_def/$name.a os2/${Name}.def\n";
        +		$ret.="\temximp -o $out_def/$name.lib os2/${Name}.def\n\n";
        +		}
        +	}
        +
        +sub do_link_rule
        +	{
        +	local($target,$files,$dep_libs,$libs)=@_;
        +	local($ret,$_);
        +	
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($target);
        +	$ret.="$target: $files $dep_libs\n";
        +	$ret.="\t\$(LINK) ${efile}$target \$(CFLAG) \$(LFLAGS) $files $libs\n\n";
        +	return($ret);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/VC-32.pl b/vendor/openssl/openssl/util/pl/VC-32.pl
        new file mode 100644
        index 000000000..6c550f54a
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/VC-32.pl
        @@ -0,0 +1,397 @@
        +#!/usr/local/bin/perl
        +# VC-32.pl - unified script for Microsoft Visual C++, covering Win32,
        +# Win64 and WinCE [follow $FLAVOR variable to trace the differences].
        +#
        +
        +$ssl=	"ssleay32";
        +$crypto="libeay32";
        +
        +if ($fips && !$shlib)
        +	{
        +	$crypto="libeayfips32";
        +	$crypto_compat = "libeaycompat32.lib";
        +	}
        +else
        +	{
        +	$crypto="libeay32";
        +	}
        +
        +$o='\\';
        +$cp='$(PERL) util/copy.pl';
        +$mkdir='$(PERL) util/mkdir-p.pl';
        +$rm='del /Q';
        +
        +$zlib_lib="zlib1.lib";
        +
        +# Santize -L options for ms link
        +$l_flags =~ s/-L("\[^"]+")/\/libpath:$1/g;
        +$l_flags =~ s/-L(\S+)/\/libpath:$1/g;
        +
        +# C compiler stuff
        +$cc='cl';
        +if ($FLAVOR =~ /WIN64/)
        +    {
        +    # Note that we currently don't have /WX on Win64! There is a lot of
        +    # warnings, but only of two types:
        +    #
        +    # C4344: conversion from '__int64' to 'int/long', possible loss of data
        +    # C4267: conversion from 'size_t' to 'int/long', possible loss of data
        +    #
        +    # Amount of latter type is minimized by aliasing strlen to function of
        +    # own desing and limiting its return value to 2GB-1 (see e_os.h). As
        +    # per 0.9.8 release remaining warnings were explicitly examined and
        +    # considered safe to ignore.
        +    # 
        +    $base_cflags= " $mf_cflag";
        +    my $f = $shlib || $fips ?' /MD':' /MT';
        +    $lib_cflag='/Zl' if (!$shlib);	# remove /DEFAULTLIBs from static lib
        +    $opt_cflags=$f.' /Ox';
        +    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
        +    $lflags="/nologo /subsystem:console /opt:ref";
        +
        +    *::perlasm_compile_target = sub {
        +	my ($target,$source,$bname)=@_;
        +	my $ret;
        +
        +	$bname =~ s/(.*)\.[^\.]$/$1/;
        +	$ret=<<___;
        +\$(TMP_D)$o$bname.asm: $source
        +	set ASM=\$(ASM)
        +	\$(PERL) $source \$\@
        +
        +$target: \$(TMP_D)$o$bname.asm
        +	\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm
        +
        +___
        +	}
        +    }
        +elsif ($FLAVOR =~ /CE/)
        +    {
        +    # sanity check
        +    die '%OSVERSION% is not defined'	if (!defined($ENV{'OSVERSION'}));
        +    die '%PLATFORM% is not defined'	if (!defined($ENV{'PLATFORM'}));
        +    die '%TARGETCPU% is not defined'	if (!defined($ENV{'TARGETCPU'}));
        +
        +    #
        +    # Idea behind this is to mimic flags set by eVC++ IDE...
        +    #
        +    $wcevers = $ENV{'OSVERSION'};			# WCENNN
        +    die '%OSVERSION% value is insane'	if ($wcevers !~ /^WCE([1-9])([0-9]{2})$/);
        +    $wcecdefs = "-D_WIN32_WCE=$1$2 -DUNDER_CE=$1$2";	# -D_WIN32_WCE=NNN
        +    $wcelflag = "/subsystem:windowsce,$1.$2";		# ...,N.NN
        +
        +    $wceplatf =  $ENV{'PLATFORM'};
        +    $wceplatf =~ tr/a-z0-9 /A-Z0-9_/d;
        +    $wcecdefs .= " -DWCE_PLATFORM_$wceplatf";
        +
        +    $wcetgt = $ENV{'TARGETCPU'};	# just shorter name...
        +    SWITCH: for($wcetgt) {
        +	/^X86/		&& do {	$wcecdefs.=" -Dx86 -D_X86_ -D_i386_ -Di_386_";
        +				$wcelflag.=" /machine:IX86";	last; };
        +	/^ARMV4[IT]/	&& do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
        +				$wcecdefs.=" -DTHUMB -D_THUMB_" if($wcetgt=~/T$/);
        +				$wcecdefs.=" -QRarch4T -QRinterwork-return";
        +				$wcelflag.=" /machine:THUMB";	last; };
        +	/^ARM/		&& do {	$wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
        +				$wcelflag.=" /machine:ARM";	last; };
        +	/^MIPSIV/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
        +				$wcecdefs.=" -D_MIPS64 -QMmips4 -QMn32";
        +				$wcelflag.=" /machine:MIPSFPU";	last; };
        +	/^MIPS16/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
        +				$wcecdefs.=" -DMIPSII -QMmips16";
        +				$wcelflag.=" /machine:MIPS16";	last; };
        +	/^MIPSII/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
        +				$wcecdefs.=" -QMmips2";
        +				$wcelflag.=" /machine:MIPS";	last; };
        +	/^R4[0-9]{3}/	&& do {	$wcecdefs.=" -DMIPS -D_MIPS_ -DR4000";
        +				$wcelflag.=" /machine:MIPS";	last; };
        +	/^SH[0-9]/	&& do {	$wcecdefs.=" -D$wcetgt -D_$wcetgt_ -DSHx";
        +				$wcecdefs.=" -Qsh4" if ($wcetgt =~ /^SH4/);
        +				$wcelflag.=" /machine:$wcetgt";	last; };
        +	{ $wcecdefs.=" -D$wcetgt -D_$wcetgt_";
        +	  $wcelflag.=" /machine:$wcetgt";			last; };
        +    }
        +
        +    $cc='$(CC)';
        +    $base_cflags=' /W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT';
        +    $base_cflags.=" $wcecdefs";
        +    $base_cflags.=' -I$(WCECOMPAT)/include'		if (defined($ENV{'WCECOMPAT'}));
        +    $base_cflags.=' -I$(PORTSDK_LIBPATH)/../../include'	if (defined($ENV{'PORTSDK_LIBPATH'}));
        +    $opt_cflags=' /MC /O1i';	# optimize for space, but with intrinsics...
        +    $dbg_cflags=' /MC /Od -DDEBUG -D_DEBUG';
        +    $lflags="/nologo /opt:ref $wcelflag";
        +    }
        +else	# Win32
        +    {
        +    $base_cflags= " $mf_cflag";
        +    my $f = $shlib || $fips ?' /MD':' /MT';
        +    $lib_cflag='/Zl' if (!$shlib);	# remove /DEFAULTLIBs from static lib
        +    $opt_cflags=$f.' /Ox /O2 /Ob2';
        +    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
        +    $lflags="/nologo /subsystem:console /opt:ref";
        +    }
        +$mlflags='';
        +
        +$out_def ="out32";	$out_def.="dll"			if ($shlib);
        +			$out_def.='_$(TARGETCPU)'	if ($FLAVOR =~ /CE/);
        +$tmp_def ="tmp32";	$tmp_def.="dll"			if ($shlib);
        +			$tmp_def.='_$(TARGETCPU)'	if ($FLAVOR =~ /CE/);
        +$inc_def="inc32";
        +
        +if ($debug)
        +	{
        +	$cflags=$dbg_cflags.$base_cflags;
        +	}
        +else
        +	{
        +	$cflags=$opt_cflags.$base_cflags;
        +	}
        +
        +# generate symbols.pdb unconditionally
        +$app_cflag.=" /Zi /Fd\$(TMP_D)/app";
        +$lib_cflag.=" /Zi /Fd\$(TMP_D)/lib";
        +$lflags.=" /debug";
        +
        +$obj='.obj';
        +$asm_suffix='.asm';
        +$ofile="/Fo";
        +
        +# EXE linking stuff
        +$link="link";
        +$rsc="rc";
        +$efile="/out:";
        +$exep='.exe';
        +if ($no_sock)		{ $ex_libs=''; }
        +elsif ($FLAVOR =~ /CE/)	{ $ex_libs='winsock.lib'; }
        +else			{ $ex_libs='ws2_32.lib'; }
        +
        +if ($FLAVOR =~ /CE/)
        +	{
        +	$ex_libs.=' $(WCECOMPAT)/lib/wcecompatex.lib'	if (defined($ENV{'WCECOMPAT'}));
        +	$ex_libs.=' $(PORTSDK_LIBPATH)/portlib.lib'	if (defined($ENV{'PORTSDK_LIBPATH'}));
        +	$ex_libs.=' /nodefaultlib:oldnames.lib coredll.lib corelibc.lib' if ($ENV{'TARGETCPU'} eq "X86");
        +	}
        +else
        +	{
        +	$ex_libs.=' gdi32.lib advapi32.lib crypt32.lib user32.lib';
        +	$ex_libs.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/ and `cl 2>&1` =~ /14\.00\.4[0-9]{4}\./);
        +	# WIN32 UNICODE build gets linked with unicows.lib for
        +	# backward compatibility with Win9x.
        +	$ex_libs="unicows.lib $ex_libs" if ($FLAVOR =~ /WIN32/ and $cflags =~ /\-DUNICODE/);
        +	}
        +
        +# static library stuff
        +$mklib='lib /nologo';
        +$ranlib='';
        +$plib="";
        +$libp=".lib";
        +$shlibp=($shlib)?".dll":".lib";
        +$lfile='/out:';
        +
        +$shlib_ex_obj="";
        +$app_ex_obj="setargv.obj" if ($FLAVOR !~ /CE/);
        +if ($FLAVOR =~ /WIN64A/) {
        +	if (`nasm -v 2>NUL` =~ /NASM version ([0-9]+\.[0-9]+)/ && $1 >= 2.0) {
        +		$asm='nasm -f win64 -DNEAR -Ox -g';
        +		$afile='-o ';
        +	} else {
        +		$asm='ml64 /c /Cp /Cx /Zi';
        +		$afile='/Fo';
        +	}
        +} elsif ($FLAVOR =~ /WIN64I/) {
        +	$asm='ias -d debug';
        +	$afile="-o ";
        +} elsif ($nasm) {
        +	my $ver=`nasm -v 2>NUL`;
        +	my $vew=`nasmw -v 2>NUL`;
        +	# pick newest version
        +	$asm=($ver ge $vew?"nasm":"nasmw")." -f win32";
        +	$asmtype="win32n";
        +	$afile='-o ';
        +} else {
        +	$asm='ml /nologo /Cp /coff /c /Cx /Zi';
        +	$afile='/Fo';
        +	$asmtype="win32";
        +}
        +
        +$bn_asm_obj='';
        +$bn_asm_src='';
        +$des_enc_obj='';
        +$des_enc_src='';
        +$bf_enc_obj='';
        +$bf_enc_src='';
        +
        +if (!$no_asm)
        +	{
        +	win32_import_asm($mf_bn_asm, "bn", \$bn_asm_obj, \$bn_asm_src);
        +	win32_import_asm($mf_aes_asm, "aes", \$aes_asm_obj, \$aes_asm_src);
        +	win32_import_asm($mf_des_asm, "des", \$des_enc_obj, \$des_enc_src);
        +	win32_import_asm($mf_bf_asm, "bf", \$bf_enc_obj, \$bf_enc_src);
        +	win32_import_asm($mf_cast_asm, "cast", \$cast_enc_obj, \$cast_enc_src);
        +	win32_import_asm($mf_rc4_asm, "rc4", \$rc4_enc_obj, \$rc4_enc_src);
        +	win32_import_asm($mf_rc5_asm, "rc5", \$rc5_enc_obj, \$rc5_enc_src);
        +	win32_import_asm($mf_md5_asm, "md5", \$md5_asm_obj, \$md5_asm_src);
        +	win32_import_asm($mf_sha_asm, "sha", \$sha1_asm_obj, \$sha1_asm_src);
        +	win32_import_asm($mf_rmd_asm, "ripemd", \$rmd160_asm_obj, \$rmd160_asm_src);
        +	win32_import_asm($mf_wp_asm, "whrlpool", \$whirlpool_asm_obj, \$whirlpool_asm_src);
        +	win32_import_asm($mf_cpuid_asm, "", \$cpuid_asm_obj, \$cpuid_asm_src);
        +	$perl_asm = 1;
        +	}
        +
        +if ($shlib && $FLAVOR !~ /CE/)
        +	{
        +	$mlflags.=" $lflags /dll";
        +	$lib_cflag.=" -D_WINDLL";
        +	#
        +	# Engage Applink...
        +	#
        +	$app_ex_obj.=" \$(OBJ_D)\\applink.obj /implib:\$(TMP_D)\\junk.lib";
        +	$cflags.=" -DOPENSSL_USE_APPLINK -I.";
        +	# I'm open for better suggestions than overriding $banner...
        +	$banner=<<'___';
        +	@echo Building OpenSSL
        +
        +$(OBJ_D)\applink.obj:	ms\applink.c
        +	$(CC) /Fo$(OBJ_D)\applink.obj $(APP_CFLAGS) -c ms\applink.c
        +$(OBJ_D)\uplink.obj:	ms\uplink.c ms\applink.c
        +	$(CC) /Fo$(OBJ_D)\uplink.obj $(SHLIB_CFLAGS) -c ms\uplink.c
        +$(INCO_D)\applink.c:	ms\applink.c
        +	$(CP) ms\applink.c $(INCO_D)\applink.c
        +
        +EXHEADER= $(EXHEADER) $(INCO_D)\applink.c
        +
        +LIBS_DEP=$(LIBS_DEP) $(OBJ_D)\applink.obj
        +CRYPTOOBJ=$(OBJ_D)\uplink.obj $(CRYPTOOBJ)
        +___
        +	$banner.=<<'___' if ($FLAVOR =~ /WIN64/);
        +CRYPTOOBJ=ms\uptable.obj $(CRYPTOOBJ)
        +___
        +	}
        +elsif ($shlib && $FLAVOR =~ /CE/)
        +	{
        +	$mlflags.=" $lflags /dll";
        +	$lflags.=' /entry:mainCRTstartup' if(defined($ENV{'PORTSDK_LIBPATH'}));
        +	$lib_cflag.=" -D_WINDLL -D_DLL";
        +	}
        +
        +sub do_lib_rule
        +	{
        +	my($objs,$target,$name,$shlib,$ign,$base_addr) = @_;
        +	local($ret);
        +
        +	$taget =~ s/\//$o/g if $o ne '/';
        +	my $base_arg;
        +	if ($base_addr ne "")
        +		{
        +		$base_arg= " /base:$base_addr";
        +		}
        +	else
        +		{
        +		$base_arg = "";
        +		}
        +	if ($name ne "")
        +		{
        +		$name =~ tr/a-z/A-Z/;
        +		$name = "/def:ms/${name}.def";
        +		}
        +
        +#	$target="\$(LIB_D)$o$target";
        +#	$ret.="$target: $objs\n";
        +	if (!$shlib)
        +		{
        +#		$ret.="\t\$(RM) \$(O_$Name)\n";
        +		$ret.="$target: $objs\n";
        +		$ret.="\t\$(MKLIB) $lfile$target @<<\n  $objs\n<<\n";
        +		}
        +	else
        +		{
        +		local($ex)=($target =~ /O_CRYPTO/)?'':' $(L_CRYPTO)';
        +		$ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
        +
        + 		if ($fips && $target =~ /O_CRYPTO/)
        +			{
        +			$ret.="$target: $objs \$(PREMAIN_DSO_EXE)";
        +			$ret.="\n\tSET FIPS_LINK=\$(LINK)\n";
        +			$ret.="\tSET FIPS_CC=\$(CC)\n";
        +			$ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\n";
        +			$ret.="\tSET PREMAIN_DSO_EXE=\$(PREMAIN_DSO_EXE)\n";
        +			$ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
        +			$ret.="\tSET FIPS_TARGET=$target\n";
        +			$ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n";
        +			$ret.="\t\$(FIPSLINK) \$(MLFLAGS) /map $base_arg $efile$target ";
        +			$ret.="$name @<<\n  \$(SHLIB_EX_OBJ) $objs \$(EX_LIBS) ";
        +			$ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n<<\n";
        +			}
        +		else
        +			{
        +			$ret.="$target: $objs";
        +			$ret.="\n\t\$(LINK) \$(MLFLAGS) $efile$target $name @<<\n  \$(SHLIB_EX_OBJ) $objs $ex \$(EX_LIBS)\n<<\n";
        +			}
        +		$ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;2\n\n";
        +		}
        +	$ret.="\n";
        +	return($ret);
        +	}
        +
        +sub do_link_rule
        +	{
        +	my($target,$files,$dep_libs,$libs,$standalone)=@_;
        +	local($ret,$_);
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($targer);
        +	$ret.="$target: $files $dep_libs\n";
        +	if ($standalone == 1)
        +		{
        +		$ret.="  \$(LINK) \$(LFLAGS) $efile$target @<<\n\t";
        +		$ret.= "\$(EX_LIBS) " if ($files =~ /O_FIPSCANISTER/ && !$fipscanisterbuild);
        +		$ret.="$files $libs\n<<\n";
        +		}
        +	elsif ($standalone == 2)
        +		{
        +		$ret.="\tSET FIPS_LINK=\$(LINK)\n";
        +		$ret.="\tSET FIPS_CC=\$(CC)\n";
        +		$ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\n";
        +		$ret.="\tSET PREMAIN_DSO_EXE=\n";
        +		$ret.="\tSET FIPS_TARGET=$target\n";
        +		$ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
        +		$ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n";
        +		$ret.="\t\$(FIPSLINK) \$(LFLAGS) /map $efile$target @<<\n";
        +		$ret.="\t\$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n<<\n";
        +		}
        +	else
        +		{
        +		$ret.="\t\$(LINK) \$(LFLAGS) $efile$target @<<\n";
        +		$ret.="\t\$(APP_EX_OBJ) $files $libs\n<<\n";
        +		}
        +    	$ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;1\n\n";
        +	return($ret);
        +	}
        +
        +sub win32_import_asm
        +	{
        +	my ($mf_var, $asm_name, $oref, $sref) = @_;
        +	my $asm_dir;
        +	if ($asm_name eq "")
        +		{
        +		$asm_dir = "crypto\\";
        +		}
        +	else
        +		{
        +		$asm_dir = "crypto\\$asm_name\\asm\\";
        +		}
        +
        +	$$oref = "";
        +	$mf_var =~ s/\.o$/.obj/g;
        +
        +	foreach (split(/ /, $mf_var))
        +		{
        +		$$oref .= $asm_dir . $_ . " ";
        +		}
        +	$$oref =~ s/ $//;
        +	$$sref = $$oref;
        +	$$sref =~ s/\.obj/.asm/g;
        +
        +	}
        +
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/linux.pl b/vendor/openssl/openssl/util/pl/linux.pl
        new file mode 100644
        index 000000000..d24f7b729
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/linux.pl
        @@ -0,0 +1,104 @@
        +#!/usr/local/bin/perl
        +#
        +# linux.pl - the standard unix makefile stuff.
        +#
        +
        +$o='/';
        +$cp='/bin/cp';
        +$rm='/bin/rm -f';
        +
        +# C compiler stuff
        +
        +$cc='gcc';
        +if ($debug)
        +	{ $cflags="-g2 -ggdb -DREF_CHECK -DCRYPTO_MDEBUG"; }
        +elsif ($profile)
        +	{ $cflags="-pg -O3"; }
        +else
        +	{ $cflags="-O3 -fomit-frame-pointer"; }
        +
        +if (!$no_asm)
        +	{
        +	$bn_asm_obj='$(OBJ_D)/bn86-elf.o';
        +	$bn_asm_src='crypto/bn/asm/bn86unix.cpp';
        +	$bnco_asm_obj='$(OBJ_D)/co86-elf.o';
        +	$bnco_asm_src='crypto/bn/asm/co86unix.cpp';
        +	$des_enc_obj='$(OBJ_D)/dx86-elf.o $(OBJ_D)/yx86-elf.o';
        +	$des_enc_src='crypto/des/asm/dx86unix.cpp crypto/des/asm/yx86unix.cpp';
        +	$bf_enc_obj='$(OBJ_D)/bx86-elf.o';
        +	$bf_enc_src='crypto/bf/asm/bx86unix.cpp';
        +	$cast_enc_obj='$(OBJ_D)/cx86-elf.o';
        +	$cast_enc_src='crypto/cast/asm/cx86unix.cpp';
        +	$rc4_enc_obj='$(OBJ_D)/rx86-elf.o';
        +	$rc4_enc_src='crypto/rc4/asm/rx86unix.cpp';
        +	$rc5_enc_obj='$(OBJ_D)/r586-elf.o';
        +	$rc5_enc_src='crypto/rc5/asm/r586unix.cpp';
        +	$md5_asm_obj='$(OBJ_D)/mx86-elf.o';
        +	$md5_asm_src='crypto/md5/asm/mx86unix.cpp';
        +	$rmd160_asm_obj='$(OBJ_D)/rm86-elf.o';
        +	$rmd160_asm_src='crypto/ripemd/asm/rm86unix.cpp';
        +	$sha1_asm_obj='$(OBJ_D)/sx86-elf.o';
        +	$sha1_asm_src='crypto/sha/asm/sx86unix.cpp';
        +	$cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_BN_ASM_PART_WORDS";
        +	}
        +
        +$cflags.=" -DTERMIO -DL_ENDIAN -m486 -Wall";
        +
        +if ($shlib)
        +	{
        +	$shl_cflag=" -DPIC -fpic";
        +	$shlibp=".so.$ssl_version";
        +	$so_shlibp=".so";
        +	}
        +
        +sub do_shlib_rule
        +	{
        +	local($obj,$target,$name,$shlib,$so_name)=@_;
        +	local($ret,$_,$Name);
        +
        +	$target =~ s/\//$o/g if $o ne '/';
        +	($Name=$name) =~ tr/a-z/A-Z/;
        +
        +	$ret.="$target: \$(${Name}OBJ)\n";
        +	$ret.="\t\$(RM) target\n";
        +	$ret.="\tgcc \${CFLAGS} -shared -Wl,-soname,$target -o $target \$(${Name}OBJ)\n";
        +	($t=$target) =~ s/(^.*)\/[^\/]*$/$1/;
        +	if ($so_name ne "")
        +		{
        +		$ret.="\t\$(RM) \$(LIB_D)$o$so_name\n";
        +		$ret.="\tln -s $target \$(LIB_D)$o$so_name\n\n";
        +		}
        +	}
        +
        +sub do_link_rule
        +	{
        +	local($target,$files,$dep_libs,$libs)=@_;
        +	local($ret,$_);
        +	
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($target);
        +	$ret.="$target: $files $dep_libs\n";
        +	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
        +	return($ret);
        +	}
        +
        +sub do_asm_rule
        +	{
        +	local($target,$src)=@_;
        +	local($ret,@s,@t,$i);
        +
        +	$target =~ s/\//$o/g if $o ne "/";
        +	$src =~ s/\//$o/g if $o ne "/";
        +
        +	@s=split(/\s+/,$src);
        +	@t=split(/\s+/,$target);
        +
        +	for ($i=0; $i<=$#s; $i++)
        +		{
        +		$ret.="$t[$i]: $s[$i]\n";
        +		$ret.="\tgcc -E -DELF \$(SRC_D)$o$s[$i]|\$(AS) $afile$t[$i]\n\n";
        +		}
        +	return($ret);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/netware.pl b/vendor/openssl/openssl/util/pl/netware.pl
        new file mode 100644
        index 000000000..c78bcfc87
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/netware.pl
        @@ -0,0 +1,532 @@
        +# Metrowerks Codewarrior or gcc / nlmconv for NetWare
        +#
        +
        +$version_header = "crypto/opensslv.h";
        +open(IN, "$version_header") or die "Couldn't open $version_header: $!";
        +while (<IN>) {
        +  if (/^#define[\s\t]+OPENSSL_VERSION_NUMBER[\s\t]+0x(\d)(\d{2})(\d{2})(\d{2})/)
        +  {
        +    # die "OpenSSL version detected: $1.$2.$3.$4\n";
        +    #$nlmvernum = "$1,$2,$3";
        +    $nlmvernum = "$1,".($2*10+$3).",".($4*1);
        +    #$nlmverstr = "$1.".($2*1).".".($3*1).($4?(chr(96+$4)):"");
        +    break;
        +  }
        +}
        +close(IN) or die "Couldn't close $version_header: $!";
        +
        +$readme_file = "README";
        +open(IN, $readme_file) or die "Couldn't open $readme_file: $!";
        +while (<IN>) {
        +  if (/^[\s\t]+OpenSSL[\s\t]+(\d)\.(\d{1,2})\.(\d{1,2})([a-z])(.*)/)
        +  {
        +    #$nlmvernum = "$1,$2,$3";
        +    #$nlmvernum = "$1,".($2*10+$3).",".($4*1);
        +    $nlmverstr = "$1.$2.$3$4$5";
        +  }
        +  elsif (/^[\s\t]+(Copyright \(c\) \d{4}\-\d{4} The OpenSSL Project)$/)
        +  {
        +    $nlmcpystr = $1;
        +  }
        +  break if ($nlmvernum && $nlmcpystr);
        +}
        +close(IN) or die "Couldn't close $readme_file: $!";
        +
        +# Define stacksize here
        +$nlmstack = "32768";
        +
        +# some default settings here in case we failed to find them in README
        +$nlmvernum = "1,0,0" if (!$nlmvernum);
        +$nlmverstr = "OpenSSL" if (!$nlmverstr);
        +$nlmcpystr = "Copyright (c) 1998-now The OpenSSL Project" if (!$nlmcpystr);
        +
        +# die "OpenSSL copyright: $nlmcpystr\nOpenSSL verstring: $nlmverstr\nOpenSSL vernumber: $nlmvernum\n";
        +
        +# The import files and other misc imports needed to link
        +@misc_imports = ("GetProcessSwitchCount", "RunningProcess",
        +                 "GetSuperHighResolutionTimer");
        +if ($LIBC)
        +{
        +   @import_files = ("libc.imp");
        +   @module_files = ("libc");
        +   $libarch = "LIBC";
        +}
        +else
        +{
        +   # clib build
        +   @import_files = ("clib.imp");
        +   push(@import_files, "socklib.imp") if ($BSDSOCK);
        +   @module_files = ("clib");
        +   # push(@misc_imports, "_rt_modu64%16", "_rt_divu64%16");
        +   $libarch = "CLIB";
        +}
        +if ($BSDSOCK)
        +{
        +   $libarch .= "-BSD";
        +}
        +else
        +{
        +   $libarch .= "-WS2";
        +   push(@import_files, "ws2nlm.imp");
        +}
        +
        +# The "IMPORTS" environment variable must be set and point to the location
        +# where import files (*.imp) can be found.
        +# Example:  set IMPORTS=c:\ndk\nwsdk\imports
        +$import_path = $ENV{"IMPORTS"} || die ("IMPORTS environment variable not set\n");
        +
        +
        +# The "PRELUDE" environment variable must be set and point to the location
        +# and name of the prelude source to link with ( nwpre.obj is recommended ).
        +# Example: set PRELUDE=c:\codewar\novell support\metrowerks support\libraries\runtime\nwpre.obj
        +$prelude = $ENV{"PRELUDE"} || die ("PRELUDE environment variable not set\n");
        +
        +# The "INCLUDES" environment variable must be set and point to the location
        +# where import files (*.imp) can be found.
        +$include_path = $ENV{"INCLUDE"} || die ("INCLUDES environment variable not set\n");
        +$include_path =~ s/\\/\//g;
        +$include_path = join(" -I", split(/;/, $include_path));
        +
        +# check for gcc compiler
        +$gnuc = $ENV{"GNUC"};
        +
        +#$ssl=   "ssleay32";
        +#$crypto="libeay32";
        +
        +if ($gnuc)
        +{
        +   # C compiler
        +   $cc='gcc';
        +   # Linker
        +   $link='nlmconv';
        +   # librarian
        +   $mklib='ar';
        +   $o='/';
        +   # cp command
        +   $cp='cp -af';
        +   # rm command
        +   $rm='rm -f';
        +   # mv command
        +   $mv='mv -f';
        +   # mkdir command
        +   $mkdir='gmkdir';
        +   #$ranlib='ranlib';
        +}
        +else
        +{
        +   # C compiler
        +   $cc='mwccnlm';
        +   # Linker
        +   $link='mwldnlm';
        +   # librarian
        +   $mklib='mwldnlm';
        +   # Path separator
        +   $o='\\';
        +   # cp command
        +   $cp='copy >nul:';
        +   # rm command
        +   $rm='del /f /q';
        +}
        +
        +# assembler
        +if ($nw_nasm)
        +{
        +   $asm=(`nasm -v 2>NUL` gt `nasmw -v 2>NUL`?"nasm":"nasmw");
        +   if ($gnuc)
        +   {
        +      $asm.=" -s -f elf";
        +   }
        +   else
        +   {
        +      $asm.=" -s -f coff -d __coff__";
        +   }
        +   $afile="-o ";
        +   $asm.=" -g" if $debug;
        +}
        +elsif ($nw_mwasm)
        +{
        +   $asm="mwasmnlm -maxerrors 20";
        +   $afile="-o ";
        +   $asm.=" -g" if $debug;
        +}
        +elsif ($nw_masm)
        +{
        +# masm assembly settings - it should be possible to use masm but haven't
        +# got it working.
        +# $asm='ml /Cp /coff /c /Cx';
        +# $asm.=" /Zi" if $debug;
        +# $afile='/Fo';
        +   die("Support for masm assembler not yet functional\n");
        +}
        +else
        +{
        +   $asm="";
        +   $afile="";
        +}
        +
        +
        +
        +if ($gnuc)
        +{
        +   # compile flags for GNUC
        +   # additional flags based upon debug | non-debug
        +   if ($debug)
        +   {
        +      $cflags="-g -DDEBUG";
        +   }
        +   else
        +   {
        +      $cflags="-O2";
        +   }
        +   $cflags.=" -nostdinc -I$include_path \\
        +         -fno-builtin -fpcc-struct-return -fno-strict-aliasing \\
        +         -funsigned-char -Wall -Wno-unused -Wno-uninitialized";
        +
        +   # link flags
        +   $lflags="-T";
        +}
        +else
        +{
        +   # compile flags for CodeWarrior
        +   # additional flags based upon debug | non-debug
        +   if ($debug)
        +   {
        +      $cflags="-opt off -g -sym internal -DDEBUG";
        +   }
        +   else
        +   {
        +   # CodeWarrior compiler has a problem with optimizations for floating
        +   # points - no optimizations until further investigation
        +   #      $cflags="-opt all";
        +   }
        +
        +   # NOTES: Several c files in the crypto subdirectory include headers from
        +   #        their local directories.  Metrowerks wouldn't find these h files
        +   #        without adding individual include directives as compile flags
        +   #        or modifying the c files.  Instead of adding individual include
        +   #        paths for each subdirectory a recursive include directive
        +   #        is used ( -ir crypto ).
        +   #
        +   #        A similar issue exists for the engines and apps subdirectories.
        +   #
        +   #        Turned off the "possible" warnings ( -w nopossible ).  Metrowerks
        +   #        complained a lot about various stuff.  May want to turn back
        +   #        on for further development.
        +   $cflags.=" -nostdinc -ir crypto -ir engines -ir apps -I$include_path \\
        +         -msgstyle gcc -align 4 -processor pentium -char unsigned \\
        +         -w on -w nolargeargs -w nopossible -w nounusedarg -w nounusedexpr \\
        +         -w noimplicitconv -relax_pointers -nosyspath -maxerrors 20";
        +
        +   # link flags
        +   $lflags="-msgstyle gcc -zerobss -nostdlib -sym internal -commandfile";
        +}
        +
        +# common defines
        +$cflags.=" -DL_ENDIAN -DOPENSSL_SYSNAME_NETWARE -U_WIN32";
        +
        +# If LibC build add in NKS_LIBC define and set the entry/exit
        +# routines - The default entry/exit routines are for CLib and don't exist
        +# in LibC
        +if ($LIBC)
        +{
        +   $cflags.=" -DNETWARE_LIBC";
        +   $nlmstart = "_LibCPrelude";
        +   $nlmexit = "_LibCPostlude";
        +   @nlm_flags = ("pseudopreemption", "flag_on 64");
        +}
        +else
        +{
        +   $cflags.=" -DNETWARE_CLIB";
        +   $nlmstart = "_Prelude";
        +   $nlmexit = "_Stop";
        +}
        +
        +# If BSD Socket support is requested, set a define for the compiler
        +if ($BSDSOCK)
        +{
        +   $cflags.=" -DNETWARE_BSDSOCK";
        +   if (!$LIBC)
        +   {
        +      $cflags.=" -DNETDB_USE_INTERNET";
        +   }
        +}
        +
        +
        +# linking stuff
        +# for the output directories use the mk1mf.pl values with "_nw" appended
        +if ($shlib)
        +{
        +   if ($LIBC)
        +   {
        +      $out_def.="_nw_libc_nlm";
        +      $tmp_def.="_nw_libc_nlm";
        +      $inc_def.="_nw_libc_nlm";
        +   }
        +   else  # NETWARE_CLIB
        +   {
        +      $out_def.="_nw_clib_nlm";
        +      $tmp_def.="_nw_clib_nlm";
        +      $inc_def.="_nw_clib_nlm";
        +   }
        +}
        +else
        +{
        +   if ($gnuc) # GNUC Tools
        +   {
        +      $libp=".a";
        +      $shlibp=".a";
        +      $lib_flags="-cr";
        +   }
        +   else       # CodeWarrior
        +   {
        +      $libp=".lib";
        +      $shlibp=".lib";
        +      $lib_flags="-nodefaults -type library -o";
        +   }
        +   if ($LIBC)
        +   {
        +      $out_def.="_nw_libc";
        +      $tmp_def.="_nw_libc";
        +      $inc_def.="_nw_libc";
        +   }
        +   else  # NETWARE_CLIB
        +   {
        +      $out_def.="_nw_clib";
        +      $tmp_def.="_nw_clib";
        +      $inc_def.="_nw_clib";
        +   }
        +}
        +
        +# used by mk1mf.pl
        +$obj='.o';
        +$ofile='-o ';
        +$efile='';
        +$exep='.nlm';
        +$ex_libs='';
        +
        +if (!$no_asm)
        +{
        +   $bn_asm_obj="\$(OBJ_D)${o}bn-nw${obj}";
        +   $bn_asm_src="crypto${o}bn${o}asm${o}bn-nw.asm";
        +   $bnco_asm_obj="\$(OBJ_D)${o}co-nw${obj}";
        +   $bnco_asm_src="crypto${o}bn${o}asm${o}co-nw.asm";
        +   $aes_asm_obj="\$(OBJ_D)${o}a-nw${obj}";
        +   $aes_asm_src="crypto${o}aes${o}asm${o}a-nw.asm";
        +   $des_enc_obj="\$(OBJ_D)${o}d-nw${obj} \$(OBJ_D)${o}y-nw${obj}";
        +   $des_enc_src="crypto${o}des${o}asm${o}d-nw.asm crypto${o}des${o}asm${o}y-nw.asm";
        +   $bf_enc_obj="\$(OBJ_D)${o}b-nw${obj}";
        +   $bf_enc_src="crypto${o}bf${o}asm${o}b-nw.asm";
        +   $cast_enc_obj="\$(OBJ_D)${o}c-nw${obj}";
        +   $cast_enc_src="crypto${o}cast${o}asm${o}c-nw.asm";
        +   $rc4_enc_obj="\$(OBJ_D)${o}r4-nw${obj}";
        +   $rc4_enc_src="crypto${o}rc4${o}asm${o}r4-nw.asm";
        +   $rc5_enc_obj="\$(OBJ_D)${o}r5-nw${obj}";
        +   $rc5_enc_src="crypto${o}rc5${o}asm${o}r5-nw.asm";
        +   $md5_asm_obj="\$(OBJ_D)${o}m5-nw${obj}";
        +   $md5_asm_src="crypto${o}md5${o}asm${o}m5-nw.asm";
        +   $sha1_asm_obj="\$(OBJ_D)${o}s1-nw${obj} \$(OBJ_D)${o}sha256-nw${obj} \$(OBJ_D)${o}sha512-nw${obj}";
        +   $sha1_asm_src="crypto${o}sha${o}asm${o}s1-nw.asm crypto${o}sha${o}asm${o}sha256-nw.asm crypto${o}sha${o}asm${o}sha512-nw.asm";
        +   $rmd160_asm_obj="\$(OBJ_D)${o}rm-nw${obj}";
        +   $rmd160_asm_src="crypto${o}ripemd${o}asm${o}rm-nw.asm";
        +   $whirlpool_asm_obj="\$(OBJ_D)${o}wp-nw${obj}";
        +   $whirlpool_asm_src="crypto${o}whrlpool${o}asm${o}wp-nw.asm";
        +   $cpuid_asm_obj="\$(OBJ_D)${o}x86cpuid-nw${obj}";
        +   $cpuid_asm_src="crypto${o}x86cpuid-nw.asm";
        +   $cflags.=" -DOPENSSL_CPUID_OBJ -DBN_ASM -DOPENSSL_BN_ASM_PART_WORDS -DMD5_ASM -DWHIRLPOOL_ASM";
        +   $cflags.=" -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM";
        +   $cflags.=" -DAES_ASM -DRMD160_ASM";
        +}
        +else
        +{
        +   $bn_asm_obj='';
        +   $bn_asm_src='';
        +   $bnco_asm_obj='';
        +   $bnco_asm_src='';
        +   $aes_asm_obj='';
        +   $aes_asm_src='';
        +   $des_enc_obj='';
        +   $des_enc_src='';
        +   $bf_enc_obj='';
        +   $bf_enc_src='';
        +   $cast_enc_obj='';
        +   $cast_enc_src='';
        +   $rc4_enc_obj='';
        +   $rc4_enc_src='';
        +   $rc5_enc_obj='';
        +   $rc5_enc_src='';
        +   $md5_asm_obj='';
        +   $md5_asm_src='';
        +   $sha1_asm_obj='';
        +   $sha1_asm_src='';
        +   $rmd160_asm_obj='';
        +   $rmd160_asm_src='';
        +   $whirlpool_asm_obj='';
        +   $whirlpool_asm_src='';
        +   $cpuid_asm_obj='';
        +   $cpuid_asm_src='';
        +}
        +
        +# create the *.def linker command files in \openssl\netware\ directory
        +sub do_def_file
        +{
        +   # strip off the leading path
        +   my($target) = bname(shift);
        +   my($i);
        +
        +   if ($target =~ /(.*).nlm/)
        +   {
        +      $target = $1;
        +   }
        +
        +   # special case for openssl - the mk1mf.pl defines E_EXE = openssl
        +   if ($target =~ /E_EXE/)
        +   {
        +      $target =~ s/\$\(E_EXE\)/openssl/;
        +   }
        +
        +   # Note: originally tried to use full path ( \openssl\netware\$target.def )
        +   # Metrowerks linker choked on this with an assertion failure. bug???
        +   #
        +   my($def_file) = "netware${o}$target.def";
        +
        +   open(DEF_OUT, ">$def_file") || die("unable to open file $def_file\n");
        +
        +   print( DEF_OUT "# command file generated by netware.pl for NLM target.\n" );
        +   print( DEF_OUT "# do not edit this file - all your changes will be lost!!\n" );
        +   print( DEF_OUT "#\n");
        +   print( DEF_OUT "DESCRIPTION \"$target ($libarch) - OpenSSL $nlmverstr\"\n");
        +   print( DEF_OUT "COPYRIGHT \"$nlmcpystr\"\n");
        +   print( DEF_OUT "VERSION $nlmvernum\n");
        +   print( DEF_OUT "STACK $nlmstack\n");
        +   print( DEF_OUT "START $nlmstart\n");
        +   print( DEF_OUT "EXIT $nlmexit\n");
        +
        +   # special case for openssl
        +   if ($target eq "openssl")
        +   {
        +      print( DEF_OUT "SCREENNAME \"OpenSSL $nlmverstr\"\n");
        +   }
        +   else
        +   {
        +      print( DEF_OUT "SCREENNAME \"DEFAULT\"\n");
        +   }
        +
        +   foreach $i (@misc_imports)
        +   {
        +      print( DEF_OUT "IMPORT $i\n");
        +   }
        +
        +   foreach $i (@import_files)
        +   {
        +      print( DEF_OUT "IMPORT \@$import_path${o}$i\n");
        +   }
        +
        +   foreach $i (@module_files)
        +   {
        +      print( DEF_OUT "MODULE $i\n");
        +   }
        +
        +   foreach $i (@nlm_flags)
        +   {
        +      print( DEF_OUT "$i\n");
        +   }
        +
        +   if ($gnuc)
        +   {
        +      if ($target =~ /openssl/)
        +      {
        +         print( DEF_OUT "INPUT ${tmp_def}${o}openssl${obj}\n");
        +         print( DEF_OUT "INPUT ${tmp_def}${o}openssl${libp}\n");
        +      }
        +      else
        +      {
        +         print( DEF_OUT "INPUT ${tmp_def}${o}${target}${obj}\n");
        +      }
        +      print( DEF_OUT "INPUT $prelude\n");
        +      print( DEF_OUT "INPUT ${out_def}${o}${ssl}${libp} ${out_def}${o}${crypto}${libp}\n");
        +      print( DEF_OUT "OUTPUT $target.nlm\n");
        +   }
        +
        +   close(DEF_OUT);
        +   return($def_file);
        +}
        +
        +sub do_lib_rule
        +{
        +   my($objs,$target,$name,$shlib)=@_;
        +   my($ret);
        +
        +   $ret.="$target: $objs\n";
        +   if (!$shlib)
        +   {
        +      $ret.="\t\@echo Building Lib: $name\n";
        +      $ret.="\t\$(MKLIB) $lib_flags $target $objs\n";
        +      $ret.="\t\@echo .\n"
        +   }
        +   else
        +   {
        +      die( "Building as NLM not currently supported!" );
        +   }
        +
        +   $ret.="\n";
        +   return($ret);
        +}
        +
        +sub do_link_rule
        +{
        +   my($target,$files,$dep_libs,$libs)=@_;
        +   my($ret);
        +   my($def_file) = do_def_file($target);
        +
        +   $ret.="$target: $files $dep_libs\n";
        +
        +   # NOTE:  When building the test nlms no screen name is given
        +   #  which causes the console screen to be used.  By using the console
        +   #  screen there is no "<press any key to continue>" message which
        +   #  requires user interaction.  The test script ( do_tests.pl ) needs
        +   #  to be able to run the tests without requiring user interaction.
        +   #
        +   #  However, the sample program "openssl.nlm" is used by the tests and is
        +   #  a interactive sample so a screen is desired when not be run by the
        +   #  tests.  To solve the problem, two versions of the program are built:
        +   #    openssl2 - no screen used by tests
        +   #    openssl - default screen - use for normal interactive modes
        +   #
        +
        +   # special case for openssl - the mk1mf.pl defines E_EXE = openssl
        +   if ($target =~ /E_EXE/)
        +   {
        +      my($target2) = $target;
        +
        +      $target2 =~ s/\(E_EXE\)/\(E_EXE\)2/;
        +
        +      # openssl2
        +      my($def_file2) = do_def_file($target2);
        +
        +      if ($gnuc)
        +      {
        +         $ret.="\t\$(MKLIB) $lib_flags \$(TMP_D)${o}\$(E_EXE).a \$(filter-out \$(TMP_D)${o}\$(E_EXE)${obj},$files)\n";
        +         $ret.="\t\$(LINK) \$(LFLAGS) $def_file2\n";
        +         $ret.="\t\@$mv \$(E_EXE)2.nlm \$(TEST_D)\n";
        +      }
        +      else
        +      {
        +         $ret.="\t\$(LINK) \$(LFLAGS) $def_file2 $files \"$prelude\" $libs -o $target2\n";
        +      }
        +   }
        +   if ($gnuc)
        +   {
        +      $ret.="\t\$(LINK) \$(LFLAGS) $def_file\n";
        +      $ret.="\t\@$mv \$(\@F) \$(TEST_D)\n";
        +   }
        +   else
        +   {
        +      $ret.="\t\$(LINK) \$(LFLAGS) $def_file $files \"$prelude\" $libs -o $target\n";
        +   }
        +
        +   $ret.="\n";
        +   return($ret);
        +
        +}
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/ultrix.pl b/vendor/openssl/openssl/util/pl/ultrix.pl
        new file mode 100644
        index 000000000..ea370c71f
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/ultrix.pl
        @@ -0,0 +1,38 @@
        +#!/usr/local/bin/perl
        +#
        +# linux.pl - the standard unix makefile stuff.
        +#
        +
        +$o='/';
        +$cp='/bin/cp';
        +$rm='/bin/rm -f';
        +
        +# C compiler stuff
        +
        +$cc='cc';
        +if ($debug)
        +	{ $cflags="-g -DREF_CHECK -DCRYPTO_MDEBUG"; }
        +else
        +	{ $cflags="-O2"; }
        +
        +$cflags.=" -std1 -DL_ENDIAN";
        +
        +if (!$no_asm)
        +	{
        +	$bn_asm_obj='$(OBJ_D)/mips1.o';
        +	$bn_asm_src='crypto/bn/asm/mips1.s';
        +	}
        +
        +sub do_link_rule
        +	{
        +	local($target,$files,$dep_libs,$libs)=@_;
        +	local($ret,$_);
        +	
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($target);
        +	$ret.="$target: $files $dep_libs\n";
        +	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
        +	return($ret);
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pl/unix.pl b/vendor/openssl/openssl/util/pl/unix.pl
        new file mode 100644
        index 000000000..146611ad9
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pl/unix.pl
        @@ -0,0 +1,96 @@
        +#!/usr/local/bin/perl
        +#
        +# unix.pl - the standard unix makefile stuff.
        +#
        +
        +$o='/';
        +$cp='/bin/cp';
        +$rm='/bin/rm -f';
        +
        +# C compiler stuff
        +
        +if ($gcc)
        +	{
        +	$cc='gcc';
        +	if ($debug)
        +		{ $cflags="-g2 -ggdb"; }
        +	else
        +		{ $cflags="-O3 -fomit-frame-pointer"; }
        +	}
        +else
        +	{
        +	$cc='cc';
        +	if ($debug)
        +		{ $cflags="-g"; }
        +	else
        +		{ $cflags="-O"; }
        +	}
        +$obj='.o';
        +$ofile='-o ';
        +
        +# EXE linking stuff
        +$link='${CC}';
        +$lflags='${CFLAGS}';
        +$efile='-o ';
        +$exep='';
        +$ex_libs="";
        +
        +# static library stuff
        +$mklib='ar r';
        +$mlflags='';
        +$ranlib=&which("ranlib") or $ranlib="true";
        +$plib='lib';
        +$libp=".a";
        +$shlibp=".a";
        +$lfile='';
        +
        +$asm='as';
        +$afile='-o ';
        +$bn_asm_obj="";
        +$bn_asm_src="";
        +$des_enc_obj="";
        +$des_enc_src="";
        +$bf_enc_obj="";
        +$bf_enc_src="";
        +
        +sub do_lib_rule
        +	{
        +	local($obj,$target,$name,$shlib)=@_;
        +	local($ret,$_,$Name);
        +
        +	$target =~ s/\//$o/g if $o ne '/';
        +	$target="$target";
        +	($Name=$name) =~ tr/a-z/A-Z/;
        +
        +	$ret.="$target: \$(${Name}OBJ)\n";
        +	$ret.="\t\$(RM) $target\n";
        +	$ret.="\t\$(MKLIB) $target \$(${Name}OBJ)\n";
        +	$ret.="\t\$(RANLIB) $target\n\n";
        +	}
        +
        +sub do_link_rule
        +	{
        +	local($target,$files,$dep_libs,$libs)=@_;
        +	local($ret,$_);
        +	
        +	$file =~ s/\//$o/g if $o ne '/';
        +	$n=&bname($target);
        +	$ret.="$target: $files $dep_libs\n";
        +	$ret.="\t\$(LINK) ${efile}$target \$(LFLAGS) $files $libs\n\n";
        +	return($ret);
        +	}
        +
        +sub which
        +	{
        +	my ($name)=@_;
        +	my $path;
        +	foreach $path (split /:/, $ENV{PATH})
        +		{
        +		if (-x "$path/$name")
        +			{
        +			return "$path/$name";
        +			}
        +		}
        +	}
        +
        +1;
        diff --git a/vendor/openssl/openssl/util/pod2man.pl b/vendor/openssl/openssl/util/pod2man.pl
        new file mode 100644
        index 000000000..025d914f2
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pod2man.pl
        @@ -0,0 +1,1184 @@
        +: #!/usr/bin/perl-5.005
        +    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
        +	if $running_under_some_shell;
        +
        +$DEF_PM_SECTION = '3pm' || '3';
        +
        +=head1 NAME
        +
        +pod2man - translate embedded Perl pod directives into man pages
        +
        +=head1 SYNOPSIS
        +
        +B<pod2man>
        +[ B<--section=>I<manext> ]
        +[ B<--release=>I<relpatch> ]
        +[ B<--center=>I<string> ]
        +[ B<--date=>I<string> ]
        +[ B<--fixed=>I<font> ]
        +[ B<--official> ]
        +[ B<--lax> ]
        +I<inputfile>
        +
        +=head1 DESCRIPTION
        +
        +B<pod2man> converts its input file containing embedded pod directives (see
        +L<perlpod>) into nroff source suitable for viewing with nroff(1) or
        +troff(1) using the man(7) macro set.
        +
        +Besides the obvious pod conversions, B<pod2man> also takes care of
        +func(), func(n), and simple variable references like $foo or @bar so
        +you don't have to use code escapes for them; complex expressions like
        +C<$fred{'stuff'}> will still need to be escaped, though.  Other nagging
        +little roffish things that it catches include translating the minus in
        +something like foo-bar, making a long dash--like this--into a real em
        +dash, fixing up "paired quotes", putting a little space after the
        +parens in something like func(), making C++ and PI look right, making
        +double underbars have a little tiny space between them, making ALLCAPS
        +a teeny bit smaller in troff(1), and escaping backslashes so you don't
        +have to.
        +
        +=head1 OPTIONS
        +
        +=over 8
        +
        +=item center
        +
        +Set the centered header to a specific string.  The default is
        +"User Contributed Perl Documentation", unless the C<--official> flag is
        +given, in which case the default is "Perl Programmers Reference Guide".
        +
        +=item date
        +
        +Set the left-hand footer string to this value.  By default,
        +the modification date of the input file will be used.
        +
        +=item fixed
        +
        +The fixed font to use for code refs.  Defaults to CW.
        +
        +=item official
        +
        +Set the default header to indicate that this page is of
        +the standard release in case C<--center> is not given.
        +
        +=item release
        +
        +Set the centered footer.  By default, this is the current
        +perl release.
        +
        +=item section
        +
        +Set the section for the C<.TH> macro.  The standard conventions on
        +sections are to use 1 for user commands,  2 for system calls, 3 for
        +functions, 4 for devices, 5 for file formats, 6 for games, 7 for
        +miscellaneous information, and 8 for administrator commands.  This works
        +best if you put your Perl man pages in a separate tree, like
        +F</usr/local/perl/man/>.  By default, section 1 will be used
        +unless the file ends in F<.pm> in which case section 3 will be selected.
        +
        +=item lax
        +
        +Don't complain when required sections aren't present.
        +
        +=back
        +
        +=head1 Anatomy of a Proper Man Page
        +
        +For those not sure of the proper layout of a man page, here's
        +an example of the skeleton of a proper man page.  Head of the
        +major headers should be setout as a C<=head1> directive, and
        +are historically written in the rather startling ALL UPPER CASE
        +format, although this is not mandatory.
        +Minor headers may be included using C<=head2>, and are
        +typically in mixed case.
        +
        +=over 10
        +
        +=item NAME
        +
        +Mandatory section; should be a comma-separated list of programs or
        +functions documented by this podpage, such as:
        +
        +    foo, bar - programs to do something
        +
        +=item SYNOPSIS
        +
        +A short usage summary for programs and functions, which
        +may someday be deemed mandatory.
        +
        +=item DESCRIPTION
        +
        +Long drawn out discussion of the program.  It's a good idea to break this
        +up into subsections using the C<=head2> directives, like
        +
        +    =head2 A Sample Subection
        +
        +    =head2 Yet Another Sample Subection
        +
        +=item OPTIONS
        +
        +Some people make this separate from the description.
        +
        +=item RETURN VALUE
        +
        +What the program or function returns if successful.
        +
        +=item ERRORS
        +
        +Exceptions, return codes, exit stati, and errno settings.
        +
        +=item EXAMPLES
        +
        +Give some example uses of the program.
        +
        +=item ENVIRONMENT
        +
        +Envariables this program might care about.
        +
        +=item FILES
        +
        +All files used by the program.  You should probably use the FE<lt>E<gt>
        +for these.
        +
        +=item SEE ALSO
        +
        +Other man pages to check out, like man(1), man(7), makewhatis(8), or catman(8).
        +
        +=item NOTES
        +
        +Miscellaneous commentary.
        +
        +=item CAVEATS
        +
        +Things to take special care with; sometimes called WARNINGS.
        +
        +=item DIAGNOSTICS
        +
        +All possible messages the program can print out--and
        +what they mean.
        +
        +=item BUGS
        +
        +Things that are broken or just don't work quite right.
        +
        +=item RESTRICTIONS
        +
        +Bugs you don't plan to fix :-)
        +
        +=item AUTHOR
        +
        +Who wrote it (or AUTHORS if multiple).
        +
        +=item HISTORY
        +
        +Programs derived from other sources sometimes have this, or
        +you might keep a modification log here.
        +
        +=back
        +
        +=head1 EXAMPLES
        +
        +    pod2man program > program.1
        +    pod2man some_module.pm > /usr/perl/man/man3/some_module.3
        +    pod2man --section=7 note.pod > note.7
        +
        +=head1 DIAGNOSTICS
        +
        +The following diagnostics are generated by B<pod2man>.  Items
        +marked "(W)" are non-fatal, whereas the "(F)" errors will cause
        +B<pod2man> to immediately exit with a non-zero status.
        +
        +=over 4
        +
        +=item bad option in paragraph %d of %s: ``%s'' should be [%s]<%s>
        +
        +(W) If you start include an option, you should set it off
        +as bold, italic, or code.
        +
        +=item can't open %s: %s
        +
        +(F) The input file wasn't available for the given reason.
        +
        +=item Improper man page - no dash in NAME header in paragraph %d of %s
        +
        +(W) The NAME header did not have an isolated dash in it.  This is
        +considered important.
        +
        +=item Invalid man page - no NAME line in %s
        +
        +(F) You did not include a NAME header, which is essential.
        +
        +=item roff font should be 1 or 2 chars, not `%s'  (F)
        +
        +(F) The font specified with the C<--fixed> option was not
        +a one- or two-digit roff font.
        +
        +=item %s is missing required section: %s
        +
        +(W) Required sections include NAME, DESCRIPTION, and if you're
        +using a section starting with a 3, also a SYNOPSIS.  Actually,
        +not having a NAME is a fatal.
        +
        +=item Unknown escape: %s in %s
        +
        +(W) An unknown HTML entity (probably for an 8-bit character) was given via
        +a C<EE<lt>E<gt>> directive.  Besides amp, lt, gt, and quot, recognized
        +entities are Aacute, aacute, Acirc, acirc, AElig, aelig, Agrave, agrave,
        +Aring, aring, Atilde, atilde, Auml, auml, Ccedil, ccedil, Eacute, eacute,
        +Ecirc, ecirc, Egrave, egrave, ETH, eth, Euml, euml, Iacute, iacute, Icirc,
        +icirc, Igrave, igrave, Iuml, iuml, Ntilde, ntilde, Oacute, oacute, Ocirc,
        +ocirc, Ograve, ograve, Oslash, oslash, Otilde, otilde, Ouml, ouml, szlig,
        +THORN, thorn, Uacute, uacute, Ucirc, ucirc, Ugrave, ugrave, Uuml, uuml,
        +Yacute, yacute, and yuml.
        +
        +=item Unmatched =back
        +
        +(W) You have a C<=back> without a corresponding C<=over>.
        +
        +=item Unrecognized pod directive: %s
        +
        +(W) You specified a pod directive that isn't in the known list of
        +C<=head1>, C<=head2>, C<=item>, C<=over>, C<=back>, or C<=cut>.
        +
        +
        +=back
        +
        +=head1 NOTES
        +
        +If you would like to print out a lot of man page continuously, you
        +probably want to set the C and D registers to set contiguous page
        +numbering and even/odd paging, at least on some versions of man(7).
        +Settting the F register will get you some additional experimental
        +indexing:
        +
        +    troff -man -rC1 -rD1 -rF1 perl.1 perldata.1 perlsyn.1 ...
        +
        +The indexing merely outputs messages via C<.tm> for each
        +major page, section, subsection, item, and any C<XE<lt>E<gt>>
        +directives.
        +
        +
        +=head1 RESTRICTIONS
        +
        +None at this time.
        +
        +=head1 BUGS
        +
        +The =over and =back directives don't really work right.  They
        +take absolute positions instead of offsets, don't nest well, and
        +making people count is suboptimal in any event.
        +
        +=head1 AUTHORS
        +
        +Original prototype by Larry Wall, but so massively hacked over by
        +Tom Christiansen such that Larry probably doesn't recognize it anymore.
        +
        +=cut
        +
        +$/ = "";
        +$cutting = 1;
        +@Indices = ();
        +
        +# We try first to get the version number from a local binary, in case we're
        +# running an installed version of Perl to produce documentation from an
        +# uninstalled newer version's pod files.
        +if ($^O ne 'plan9' and $^O ne 'dos' and $^O ne 'os2' and $^O ne 'MSWin32') {
        +  my $perl = (-x './perl' && -f './perl' ) ?
        +                 './perl' :
        +                 ((-x '../perl' && -f '../perl') ?
        +                      '../perl' :
        +                      '');
        +  ($version,$patch) = `$perl -e 'print $]'` =~ /^(\d\.\d{3})(\d{2})?/ if $perl;
        +}
        +# No luck; we'll just go with the running Perl's version
        +($version,$patch) = $] =~ /^(.{5})(\d{2})?/ unless $version;
        +$DEF_RELEASE  = "perl $version";
        +$DEF_RELEASE .= ", patch $patch" if $patch;
        +
        +
        +sub makedate {
        +    my $secs = shift;
        +    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($secs);
        +    my $mname = (qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec})[$mon];
        +    $year += 1900;
        +    return "$mday/$mname/$year";
        +}
        +
        +use Getopt::Long;
        +
        +$DEF_SECTION = 1;
        +$DEF_CENTER = "User Contributed Perl Documentation";
        +$STD_CENTER = "Perl Programmers Reference Guide";
        +$DEF_FIXED = 'CW';
        +$DEF_LAX = 0;
        +
        +sub usage {
        +    warn "$0: @_\n" if @_;
        +    die <<EOF;
        +usage: $0 [options] podpage
        +Options are:
        +	--section=manext      (default "$DEF_SECTION")
        +	--release=relpatch    (default "$DEF_RELEASE")
        +	--center=string       (default "$DEF_CENTER")
        +	--date=string         (default "$DEF_DATE")
        +	--fixed=font	      (default "$DEF_FIXED")
        +	--official	      (default NOT)
        +	--lax                 (default NOT)
        +EOF
        +}
        +
        +$uok = GetOptions( qw(
        +	section=s
        +	release=s
        +	center=s
        +	date=s
        +	fixed=s
        +	official
        +	lax
        +	help));
        +
        +$DEF_DATE = makedate((stat($ARGV[0]))[9] || time());
        +
        +usage("Usage error!") unless $uok;
        +usage() if $opt_help;
        +usage("Need one and only one podpage argument") unless @ARGV == 1;
        +
        +$section = $opt_section || ($ARGV[0] =~ /\.pm$/
        +				? $DEF_PM_SECTION : $DEF_SECTION);
        +$RP = $opt_release || $DEF_RELEASE;
        +$center = $opt_center || ($opt_official ? $STD_CENTER : $DEF_CENTER);
        +$lax = $opt_lax || $DEF_LAX;
        +
        +$CFont = $opt_fixed || $DEF_FIXED;
        +
        +if (length($CFont) == 2) {
        +    $CFont_embed = "\\f($CFont";
        +}
        +elsif (length($CFont) == 1) {
        +    $CFont_embed = "\\f$CFont";
        +}
        +else {
        +    die "roff font should be 1 or 2 chars, not `$CFont_embed'";
        +}
        +
        +$date = $opt_date || $DEF_DATE;
        +
        +for (qw{NAME DESCRIPTION}) {
        +# for (qw{NAME DESCRIPTION AUTHOR}) {
        +    $wanna_see{$_}++;
        +}
        +$wanna_see{SYNOPSIS}++ if $section =~ /^3/;
        +
        +
        +$name = @ARGV ? $ARGV[0] : "<STDIN>";
        +$Filename = $name;
        +if ($section =~ /^1/) {
        +    require File::Basename;
        +    $name = uc File::Basename::basename($name);
        +}
        +$name =~ s/\.(pod|p[lm])$//i;
        +
        +# Lose everything up to the first of
        +#     */lib/*perl*	standard or site_perl module
        +#     */*perl*/lib	from -D prefix=/opt/perl
        +#     */*perl*/		random module hierarchy
        +# which works.
        +$name =~ s-//+-/-g;
        +if ($name =~ s-^.*?/lib/[^/]*perl[^/]*/--i
        +	or $name =~ s-^.*?/[^/]*perl[^/]*/lib/--i
        +	or $name =~ s-^.*?/[^/]*perl[^/]*/--i) {
        +    # Lose ^site(_perl)?/.
        +    $name =~ s-^site(_perl)?/--;
        +    # Lose ^arch/.	(XXX should we use Config? Just for archname?)
        +    $name =~ s~^(.*-$^O|$^O-.*)/~~o;
        +    # Lose ^version/.
        +    $name =~ s-^\d+\.\d+/--;
        +}
        +
        +# Translate Getopt/Long to Getopt::Long, etc.
        +$name =~ s(/)(::)g;
        +
        +if ($name ne 'something') {
        +    FCHECK: {
        +	open(F, "< $ARGV[0]") || die "can't open $ARGV[0]: $!";
        +	while (<F>) {
        +	    next unless /^=\b/;
        +	    if (/^=head1\s+NAME\s*$/) {  # an /m would forgive mistakes
        +		$_ = <F>;
        +		unless (/\s*-+\s+/) {
        +		    $oops++;
        +		    warn "$0: Improper man page - no dash in NAME header in paragraph $. of $ARGV[0]\n"
        +                } else {
        +		    my @n = split /\s+-+\s+/;
        +		    if (@n != 2) {
        +			$oops++;
        +			warn "$0: Improper man page - malformed NAME header in paragraph $. of $ARGV[0]\n"
        +		    }
        +		    else {
        +			$n[0] =~ s/\n/ /g;
        +			$n[1] =~ s/\n/ /g;
        +			%namedesc = @n;
        +		    }
        +		}
        +		last FCHECK;
        +	    }
        +	    next if /^=cut\b/;	# DB_File and Net::Ping have =cut before NAME
        +	    next if /^=pod\b/;  # It is OK to have =pod before NAME
        +	    next if /^=(for|begin|end)\s+comment\b/;  # It is OK to have =for =begin or =end comment before NAME
        +	    die "$0: Invalid man page - 1st pod line is not NAME in $ARGV[0]\n" unless $lax;
        +	}
        +	die "$0: Invalid man page - no documentation in $ARGV[0]\n" unless $lax;
        +    }
        +    close F;
        +}
        +
        +print <<"END";
        +.rn '' }`
        +''' \$RCSfile\$\$Revision\$\$Date\$
        +'''
        +''' \$Log\$
        +'''
        +.de Sh
        +.br
        +.if t .Sp
        +.ne 5
        +.PP
        +\\fB\\\\\$1\\fR
        +.PP
        +..
        +.de Sp
        +.if t .sp .5v
        +.if n .sp
        +..
        +.de Ip
        +.br
        +.ie \\\\n(.\$>=3 .ne \\\\\$3
        +.el .ne 3
        +.IP "\\\\\$1" \\\\\$2
        +..
        +.de Vb
        +.ft $CFont
        +.nf
        +.ne \\\\\$1
        +..
        +.de Ve
        +.ft R
        +
        +.fi
        +..
        +'''
        +'''
        +'''     Set up \\*(-- to give an unbreakable dash;
        +'''     string Tr holds user defined translation string.
        +'''     Bell System Logo is used as a dummy character.
        +'''
        +.tr \\(*W-|\\(bv\\*(Tr
        +.ie n \\{\\
        +.ds -- \\(*W-
        +.ds PI pi
        +.if (\\n(.H=4u)&(1m=24u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-12u'-\\" diablo 10 pitch
        +.if (\\n(.H=4u)&(1m=20u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-8u'-\\" diablo 12 pitch
        +.ds L" ""
        +.ds R" ""
        +'''   \\*(M", \\*(S", \\*(N" and \\*(T" are the equivalent of
        +'''   \\*(L" and \\*(R", except that they are used on ".xx" lines,
        +'''   such as .IP and .SH, which do another additional levels of
        +'''   double-quote interpretation
        +.ds M" """
        +.ds S" """
        +.ds N" """""
        +.ds T" """""
        +.ds L' '
        +.ds R' '
        +.ds M' '
        +.ds S' '
        +.ds N' '
        +.ds T' '
        +'br\\}
        +.el\\{\\
        +.ds -- \\(em\\|
        +.tr \\*(Tr
        +.ds L" ``
        +.ds R" ''
        +.ds M" ``
        +.ds S" ''
        +.ds N" ``
        +.ds T" ''
        +.ds L' `
        +.ds R' '
        +.ds M' `
        +.ds S' '
        +.ds N' `
        +.ds T' '
        +.ds PI \\(*p
        +'br\\}
        +END
        +
        +print <<'END';
        +.\"	If the F register is turned on, we'll generate
        +.\"	index entries out stderr for the following things:
        +.\"		TH	Title 
        +.\"		SH	Header
        +.\"		Sh	Subsection 
        +.\"		Ip	Item
        +.\"		X<>	Xref  (embedded
        +.\"	Of course, you have to process the output yourself
        +.\"	in some meaninful fashion.
        +.if \nF \{
        +.de IX
        +.tm Index:\\$1\t\\n%\t"\\$2"
        +..
        +.nr % 0
        +.rr F
        +.\}
        +END
        +
        +print <<"END";
        +.TH $name $section "$RP" "$date" "$center"
        +.UC
        +END
        +
        +push(@Indices, qq{.IX Title "$name $section"});
        +
        +while (($name, $desc) = each %namedesc) {
        +    for ($name, $desc) { s/^\s+//; s/\s+$//; }
        +    push(@Indices, qq(.IX Name "$name - $desc"\n));
        +}
        +
        +print <<'END';
        +.if n .hy 0
        +.if n .na
        +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
        +.de CQ          \" put $1 in typewriter font
        +END
        +print ".ft $CFont\n";
        +print <<'END';
        +'if n "\c
        +'if t \\&\\$1\c
        +'if n \\&\\$1\c
        +'if n \&"
        +\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
        +'.ft R
        +..
        +.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
        +.	\" AM - accent mark definitions
        +.bd B 3
        +.	\" fudge factors for nroff and troff
        +.if n \{\
        +.	ds #H 0
        +.	ds #V .8m
        +.	ds #F .3m
        +.	ds #[ \f1
        +.	ds #] \fP
        +.\}
        +.if t \{\
        +.	ds #H ((1u-(\\\\n(.fu%2u))*.13m)
        +.	ds #V .6m
        +.	ds #F 0
        +.	ds #[ \&
        +.	ds #] \&
        +.\}
        +.	\" simple accents for nroff and troff
        +.if n \{\
        +.	ds ' \&
        +.	ds ` \&
        +.	ds ^ \&
        +.	ds , \&
        +.	ds ~ ~
        +.	ds ? ?
        +.	ds ! !
        +.	ds /
        +.	ds q
        +.\}
        +.if t \{\
        +.	ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
        +.	ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
        +.	ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
        +.	ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
        +.	ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
        +.	ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
        +.	ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
        +.	ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
        +.	ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
        +.\}
        +.	\" troff and (daisy-wheel) nroff accents
        +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
        +.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
        +.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
        +.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
        +.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
        +.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
        +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
        +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
        +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
        +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
        +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
        +.ds ae a\h'-(\w'a'u*4/10)'e
        +.ds Ae A\h'-(\w'A'u*4/10)'E
        +.ds oe o\h'-(\w'o'u*4/10)'e
        +.ds Oe O\h'-(\w'O'u*4/10)'E
        +.	\" corrections for vroff
        +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
        +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
        +.	\" for low resolution devices (crt and lpr)
        +.if \n(.H>23 .if \n(.V>19 \
        +\{\
        +.	ds : e
        +.	ds 8 ss
        +.	ds v \h'-1'\o'\(aa\(ga'
        +.	ds _ \h'-1'^
        +.	ds . \h'-1'.
        +.	ds 3 3
        +.	ds o a
        +.	ds d- d\h'-1'\(ga
        +.	ds D- D\h'-1'\(hy
        +.	ds th \o'bp'
        +.	ds Th \o'LP'
        +.	ds ae ae
        +.	ds Ae AE
        +.	ds oe oe
        +.	ds Oe OE
        +.\}
        +.rm #[ #] #H #V #F C
        +END
        +
        +$indent = 0;
        +
        +$begun = "";
        +
        +# Unrolling [^A-Z>]|[A-Z](?!<) gives:    // MRE pp 165.
        +my $nonest = '(?:[^A-Z>]*(?:[A-Z](?!<)[^A-Z>]*)*)';
        +
        +while (<>) {
        +    if ($cutting) {
        +	next unless /^=/;
        +	$cutting = 0;
        +    }
        +    if ($begun) {
        +	if (/^=end\s+$begun/) {
        +            $begun = "";
        +	}
        +	elsif ($begun =~ /^(roff|man)$/) {
        +	    print STDOUT $_;
        +        }
        +	next;
        +    }
        +    chomp;
        +
        +    # Translate verbatim paragraph
        +
        +    if (/^\s/) {
        +	@lines = split(/\n/);
        +	for (@lines) {
        +	    1 while s
        +		{^( [^\t]* ) \t ( \t* ) }
        +		{ $1 . ' ' x (8 - (length($1)%8) + 8 * (length($2))) }ex;
        +	    s/\\/\\e/g;
        +	    s/\A/\\&/s;
        +	}
        +	$lines = @lines;
        +	makespace() unless $verbatim++;
        +	print ".Vb $lines\n";
        +	print join("\n", @lines), "\n";
        +	print ".Ve\n";
        +	$needspace = 0;
        +	next;
        +    }
        +
        +    $verbatim = 0;
        +
        +    if (/^=for\s+(\S+)\s*/s) {
        +	if ($1 eq "man" or $1 eq "roff") {
        +	    print STDOUT $',"\n\n";
        +	} else {
        +	    # ignore unknown for
        +	}
        +	next;
        +    }
        +    elsif (/^=begin\s+(\S+)\s*/s) {
        +	$begun = $1;
        +	if ($1 eq "man" or $1 eq "roff") {
        +	    print STDOUT $'."\n\n";
        +	}
        +	next;
        +    }
        +
        +    # check for things that'll hosed our noremap scheme; affects $_
        +    init_noremap();
        +
        +    if (!/^=item/) {
        +
        +	# trofficate backslashes; must do it before what happens below
        +	s/\\/noremap('\\e')/ge;
        +
        +	# protect leading periods and quotes against *roff
        +	# mistaking them for directives
        +	s/^(?:[A-Z]<)?[.']/\\&$&/gm;
        +
        +	# first hide the escapes in case we need to
        +	# intuit something and get it wrong due to fmting
        +
        +	1 while s/([A-Z]<$nonest>)/noremap($1)/ge;
        +
        +	# func() is a reference to a perl function
        +	s{
        +	    \b
        +	    (
        +		[:\w]+ \(\)
        +	    )
        +	} {I<$1>}gx;
        +
        +	# func(n) is a reference to a perl function or a man page
        +	s{
        +	    ([:\w]+)
        +	    (
        +		\( [^\051]+ \)
        +	    )
        +	} {I<$1>\\|$2}gx;
        +
        +	# convert simple variable references
        +	s/(\s+)([\$\@%][\w:]+)(?!\()/${1}C<$2>/g;
        +
        +	if (m{ (
        +		    [\-\w]+
        +		    \(
        +			[^\051]*?
        +			[\@\$,]
        +			[^\051]*?
        +		    \)
        +		)
        +	    }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/)
        +	{
        +	    warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [LCI]<$1>\n";
        +	    $oops++;
        +	}
        +
        +	while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) {
        +	    warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [CB]<$1>\n";
        +	    $oops++;
        +	}
        +
        +	# put it back so we get the <> processed again;
        +	clear_noremap(0); # 0 means leave the E's
        +
        +    } else {
        +	# trofficate backslashes
        +	s/\\/noremap('\\e')/ge;
        +
        +    }
        +
        +    # need to hide E<> first; they're processed in clear_noremap
        +    s/(E<[^<>]+>)/noremap($1)/ge;
        +
        +
        +    $maxnest = 10;
        +    while ($maxnest-- && /[A-Z]</) {
        +
        +	# can't do C font here
        +	s/([BI])<($nonest)>/font($1) . $2 . font('R')/eg;
        +
        +	# files and filelike refs in italics
        +	s/F<($nonest)>/I<$1>/g;
        +
        +	# no break -- usually we want C<> for this
        +	s/S<($nonest)>/nobreak($1)/eg;
        +
        +	# LREF: a la HREF L<show this text|man/section>
        +	s:L<([^|>]+)\|[^>]+>:$1:g;
        +
        +	# LREF: a manpage(3f)
        +	s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g;
        +
        +	# LREF: an =item on another manpage
        +	s{
        +	    L<
        +		([^/]+)
        +		/
        +		(
        +		    [:\w]+
        +		    (\(\))?
        +		)
        +	    >
        +	} {the C<$2> entry in the I<$1> manpage}gx;
        +
        +	# LREF: an =item on this manpage
        +	s{
        +	   ((?:
        +	    L<
        +		/
        +		(
        +		    [:\w]+
        +		    (\(\))?
        +		)
        +	    >
        +	    (,?\s+(and\s+)?)?
        +	  )+)
        +	} { internal_lrefs($1) }gex;
        +
        +	# LREF: a =head2 (head1?), maybe on a manpage, maybe right here
        +	# the "func" can disambiguate
        +	s{
        +	    L<
        +		(?:
        +		    ([a-zA-Z]\S+?) /
        +		)?
        +		"?(.*?)"?
        +	    >
        +	}{
        +	    do {
        +		$1 	# if no $1, assume it means on this page.
        +		    ?  "the section on I<$2> in the I<$1> manpage"
        +		    :  "the section on I<$2>"
        +	    }
        +	}gesx; # s in case it goes over multiple lines, so . matches \n
        +
        +	s/Z<>/\\&/g;
        +
        +	# comes last because not subject to reprocessing
        +	s/C<($nonest)>/noremap("${CFont_embed}${1}\\fR")/eg;
        +    }
        +
        +    if (s/^=//) {
        +	$needspace = 0;		# Assume this.
        +
        +	s/\n/ /g;
        +
        +	($Cmd, $_) = split(' ', $_, 2);
        +
        +	$dotlevel = 1;
        +	if ($Cmd eq 'head1') {
        +	   $dotlevel = 1;
        +	}
        +	elsif ($Cmd eq 'head2') {
        +	   $dotlevel = 1;
        +	}
        +	elsif ($Cmd eq 'item') {
        +	   $dotlevel = 2;
        +	}
        +
        +	if (defined $_) {
        +	    &escapes($dotlevel);
        +	    s/"/""/g;
        +	}
        +
        +	clear_noremap(1);
        +
        +	if ($Cmd eq 'cut') {
        +	    $cutting = 1;
        +	}
        +	elsif ($Cmd eq 'head1') {
        +	    s/\s+$//;
        +	    delete $wanna_see{$_} if exists $wanna_see{$_};
        +	    print qq{.SH "$_"\n};
        +      push(@Indices, qq{.IX Header "$_"\n});
        +	}
        +	elsif ($Cmd eq 'head2') {
        +	    print qq{.Sh "$_"\n};
        +      push(@Indices, qq{.IX Subsection "$_"\n});
        +	}
        +	elsif ($Cmd eq 'over') {
        +	    push(@indent,$indent);
        +	    $indent += ($_ + 0) || 5;
        +	}
        +	elsif ($Cmd eq 'back') {
        +	    $indent = pop(@indent);
        +	    warn "$0: Unmatched =back in paragraph $. of $ARGV\n" unless defined $indent;
        +	    $needspace = 1;
        +	}
        +	elsif ($Cmd eq 'item') {
        +	    s/^\*( |$)/\\(bu$1/g;
        +	    # if you know how to get ":s please do
        +	    s/\\\*\(L"([^"]+?)\\\*\(R"/'$1'/g;
        +	    s/\\\*\(L"([^"]+?)""/'$1'/g;
        +	    s/[^"]""([^"]+?)""[^"]/'$1'/g;
        +	    # here do something about the $" in perlvar?
        +	    print STDOUT qq{.Ip "$_" $indent\n};
        +      push(@Indices, qq{.IX Item "$_"\n});
        +	}
        +	elsif ($Cmd eq 'pod') {
        +	    # this is just a comment
        +	} 
        +	else {
        +	    warn "$0: Unrecognized pod directive in paragraph $. of $ARGV: $Cmd\n";
        +	}
        +    }
        +    else {
        +	if ($needspace) {
        +	    &makespace;
        +	}
        +	&escapes(0);
        +	clear_noremap(1);
        +	print $_, "\n";
        +	$needspace = 1;
        +    }
        +}
        +
        +print <<"END";
        +
        +.rn }` ''
        +END
        +
        +if (%wanna_see && !$lax) {
        +    @missing = keys %wanna_see;
        +    warn "$0: $Filename is missing required section"
        +	.  (@missing > 1 && "s")
        +	.  ": @missing\n";
        +    $oops++;
        +}
        +
        +foreach (@Indices) { print "$_\n"; }
        +
        +exit;
        +#exit ($oops != 0);
        +
        +#########################################################################
        +
        +sub nobreak {
        +    my $string = shift;
        +    $string =~ s/ /\\ /g;
        +    $string;
        +}
        +
        +sub escapes {
        +    my $indot = shift;
        +
        +    s/X<(.*?)>/mkindex($1)/ge;
        +
        +    # translate the minus in foo-bar into foo\-bar for roff
        +    s/([^0-9a-z-])-([^-])/$1\\-$2/g;
        +
        +    # make -- into the string version \*(-- (defined above)
        +    s/\b--\b/\\*(--/g;
        +    s/"--([^"])/"\\*(--$1/g;  # should be a better way
        +    s/([^"])--"/$1\\*(--"/g;
        +
        +    # fix up quotes; this is somewhat tricky
        +    my $dotmacroL = 'L';
        +    my $dotmacroR = 'R';
        +    if ( $indot == 1 ) {
        +	$dotmacroL = 'M';
        +	$dotmacroR = 'S';
        +    }  
        +    elsif ( $indot >= 2 ) {
        +	$dotmacroL = 'N';
        +	$dotmacroR = 'T';
        +    }  
        +    if (!/""/) {
        +	s/(^|\s)(['"])/noremap("$1\\*($dotmacroL$2")/ge;
        +	s/(['"])($|[\-\s,;\\!?.])/noremap("\\*($dotmacroR$1$2")/ge;
        +    }
        +
        +    #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g;
        +    #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g;
        +
        +
        +    # make sure that func() keeps a bit a space tween the parens
        +    ### s/\b\(\)/\\|()/g;
        +    ### s/\b\(\)/(\\|)/g;
        +
        +    # make C++ into \*C+, which is a squinched version (defined above)
        +    s/\bC\+\+/\\*(C+/g;
        +
        +    # make double underbars have a little tiny space between them
        +    s/__/_\\|_/g;
        +
        +    # PI goes to \*(PI (defined above)
        +    s/\bPI\b/noremap('\\*(PI')/ge;
        +
        +    # make all caps a teeny bit smaller, but don't muck with embedded code literals
        +    my $hidCFont = font('C');
        +    if ($Cmd !~ /^head1/) { # SH already makes smaller
        +	# /g isn't enough; 1 while or we'll be off
        +
        +#	1 while s{
        +#	    (?!$hidCFont)(..|^.|^)
        +#	    \b
        +#	    (
        +#		[A-Z][\/A-Z+:\-\d_$.]+
        +#	    )
        +#	    (s?) 		
        +#	    \b
        +#	} {$1\\s-1$2\\s0}gmox;
        +
        +	1 while s{
        +	    (?!$hidCFont)(..|^.|^)
        +	    (
        +		\b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b
        +	    )
        +	} {
        +	    $1 . noremap( '\\s-1' .  $2 . '\\s0' )
        +	}egmox;
        +
        +    }
        +}
        +
        +# make troff just be normal, but make small nroff get quoted
        +# decided to just put the quotes in the text; sigh;
        +sub ccvt {
        +    local($_,$prev) = @_;
        +    noremap(qq{.CQ "$_" \n\\&});
        +}
        +
        +sub makespace {
        +    if ($indent) {
        +	print ".Sp\n";
        +    }
        +    else {
        +	print ".PP\n";
        +    }
        +}
        +
        +sub mkindex {
        +    my ($entry) = @_;
        +    my @entries = split m:\s*/\s*:, $entry;
        +    push @Indices, ".IX Xref " . join ' ', map {qq("$_")} @entries;
        +    return '';
        +}
        +
        +sub font {
        +    local($font) = shift;
        +    return '\\f' . noremap($font);
        +}
        +
        +sub noremap {
        +    local($thing_to_hide) = shift;
        +    $thing_to_hide =~ tr/\000-\177/\200-\377/;
        +    return $thing_to_hide;
        +}
        +
        +sub init_noremap {
        +	# escape high bit characters in input stream
        +	s/([\200-\377])/"E<".ord($1).">"/ge;
        +}
        +
        +sub clear_noremap {
        +    my $ready_to_print = $_[0];
        +
        +    tr/\200-\377/\000-\177/;
        +
        +    # trofficate backslashes
        +    # s/(?!\\e)(?:..|^.|^)\\/\\e/g;
        +
        +    # now for the E<>s, which have been hidden until now
        +    # otherwise the interative \w<> processing would have
        +    # been hosed by the E<gt>
        +    s {
        +	    E<
        +	    (
        +	        ( \d + ) 
        +	        | ( [A-Za-z]+ )	
        +	    )
        +	    >	
        +    } {
        +	 do {
        +	     defined $2
        +		? chr($2)
        +		:	
        +	     exists $HTML_Escapes{$3}
        +		? do { $HTML_Escapes{$3} }
        +		: do {
        +		    warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n";
        +		    "E<$1>";
        +		}
        +	 }
        +    }egx if $ready_to_print;
        +}
        +
        +sub internal_lrefs {
        +    local($_) = shift;
        +    local $trailing_and = s/and\s+$// ? "and " : "";
        +
        +    s{L</([^>]+)>}{$1}g;
        +    my(@items) = split( /(?:,?\s+(?:and\s+)?)/ );
        +    my $retstr = "the ";
        +    my $i;
        +    for ($i = 0; $i <= $#items; $i++) {
        +	$retstr .= "C<$items[$i]>";
        +	$retstr .= ", " if @items > 2 && $i != $#items;
        +	$retstr .= " and " if $i+2 == @items;
        +    }
        +
        +    $retstr .= " entr" . ( @items > 1  ? "ies" : "y" )
        +	    .  " elsewhere in this document";
        +    # terminal space to avoid words running together (pattern used
        +    # strips terminal spaces)
        +    $retstr .= " " if length $trailing_and;
        +    $retstr .=  $trailing_and;
        +
        +    return $retstr;
        +
        +}
        +
        +BEGIN {
        +%HTML_Escapes = (
        +    'amp'	=>	'&',	#   ampersand
        +    'lt'	=>	'<',	#   left chevron, less-than
        +    'gt'	=>	'>',	#   right chevron, greater-than
        +    'quot'	=>	'"',	#   double quote
        +
        +    "Aacute"	=>	"A\\*'",	#   capital A, acute accent
        +    "aacute"	=>	"a\\*'",	#   small a, acute accent
        +    "Acirc"	=>	"A\\*^",	#   capital A, circumflex accent
        +    "acirc"	=>	"a\\*^",	#   small a, circumflex accent
        +    "AElig"	=>	'\*(AE',	#   capital AE diphthong (ligature)
        +    "aelig"	=>	'\*(ae',	#   small ae diphthong (ligature)
        +    "Agrave"	=>	"A\\*`",	#   capital A, grave accent
        +    "agrave"	=>	"A\\*`",	#   small a, grave accent
        +    "Aring"	=>	'A\\*o',	#   capital A, ring
        +    "aring"	=>	'a\\*o',	#   small a, ring
        +    "Atilde"	=>	'A\\*~',	#   capital A, tilde
        +    "atilde"	=>	'a\\*~',	#   small a, tilde
        +    "Auml"	=>	'A\\*:',	#   capital A, dieresis or umlaut mark
        +    "auml"	=>	'a\\*:',	#   small a, dieresis or umlaut mark
        +    "Ccedil"	=>	'C\\*,',	#   capital C, cedilla
        +    "ccedil"	=>	'c\\*,',	#   small c, cedilla
        +    "Eacute"	=>	"E\\*'",	#   capital E, acute accent
        +    "eacute"	=>	"e\\*'",	#   small e, acute accent
        +    "Ecirc"	=>	"E\\*^",	#   capital E, circumflex accent
        +    "ecirc"	=>	"e\\*^",	#   small e, circumflex accent
        +    "Egrave"	=>	"E\\*`",	#   capital E, grave accent
        +    "egrave"	=>	"e\\*`",	#   small e, grave accent
        +    "ETH"	=>	'\\*(D-',	#   capital Eth, Icelandic
        +    "eth"	=>	'\\*(d-',	#   small eth, Icelandic
        +    "Euml"	=>	"E\\*:",	#   capital E, dieresis or umlaut mark
        +    "euml"	=>	"e\\*:",	#   small e, dieresis or umlaut mark
        +    "Iacute"	=>	"I\\*'",	#   capital I, acute accent
        +    "iacute"	=>	"i\\*'",	#   small i, acute accent
        +    "Icirc"	=>	"I\\*^",	#   capital I, circumflex accent
        +    "icirc"	=>	"i\\*^",	#   small i, circumflex accent
        +    "Igrave"	=>	"I\\*`",	#   capital I, grave accent
        +    "igrave"	=>	"i\\*`",	#   small i, grave accent
        +    "Iuml"	=>	"I\\*:",	#   capital I, dieresis or umlaut mark
        +    "iuml"	=>	"i\\*:",	#   small i, dieresis or umlaut mark
        +    "Ntilde"	=>	'N\*~',		#   capital N, tilde
        +    "ntilde"	=>	'n\*~',		#   small n, tilde
        +    "Oacute"	=>	"O\\*'",	#   capital O, acute accent
        +    "oacute"	=>	"o\\*'",	#   small o, acute accent
        +    "Ocirc"	=>	"O\\*^",	#   capital O, circumflex accent
        +    "ocirc"	=>	"o\\*^",	#   small o, circumflex accent
        +    "Ograve"	=>	"O\\*`",	#   capital O, grave accent
        +    "ograve"	=>	"o\\*`",	#   small o, grave accent
        +    "Oslash"	=>	"O\\*/",	#   capital O, slash
        +    "oslash"	=>	"o\\*/",	#   small o, slash
        +    "Otilde"	=>	"O\\*~",	#   capital O, tilde
        +    "otilde"	=>	"o\\*~",	#   small o, tilde
        +    "Ouml"	=>	"O\\*:",	#   capital O, dieresis or umlaut mark
        +    "ouml"	=>	"o\\*:",	#   small o, dieresis or umlaut mark
        +    "szlig"	=>	'\*8',		#   small sharp s, German (sz ligature)
        +    "THORN"	=>	'\\*(Th',	#   capital THORN, Icelandic
        +    "thorn"	=>	'\\*(th',,	#   small thorn, Icelandic
        +    "Uacute"	=>	"U\\*'",	#   capital U, acute accent
        +    "uacute"	=>	"u\\*'",	#   small u, acute accent
        +    "Ucirc"	=>	"U\\*^",	#   capital U, circumflex accent
        +    "ucirc"	=>	"u\\*^",	#   small u, circumflex accent
        +    "Ugrave"	=>	"U\\*`",	#   capital U, grave accent
        +    "ugrave"	=>	"u\\*`",	#   small u, grave accent
        +    "Uuml"	=>	"U\\*:",	#   capital U, dieresis or umlaut mark
        +    "uuml"	=>	"u\\*:",	#   small u, dieresis or umlaut mark
        +    "Yacute"	=>	"Y\\*'",	#   capital Y, acute accent
        +    "yacute"	=>	"y\\*'",	#   small y, acute accent
        +    "yuml"	=>	"y\\*:",	#   small y, dieresis or umlaut mark
        +);
        +}
        +
        diff --git a/vendor/openssl/openssl/util/pod2mantest b/vendor/openssl/openssl/util/pod2mantest
        new file mode 100644
        index 000000000..384e683df
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pod2mantest
        @@ -0,0 +1,58 @@
        +#!/bin/sh
        +
        +# This script is used by test/Makefile to check whether a sane 'pod2man'
        +# is installed.
        +# ('make install' should not try to run 'pod2man' if it does not exist or if
        +# it is a broken 'pod2man' version that is known to cause trouble. if we find
        +# the system 'pod2man' to be broken, we use our own copy instead)
        +#
        +# In any case, output an appropriate command line for running (or not
        +# running) pod2man.
        +
        +
        +IFS=:
        +if test "$OSTYPE" = "msdosdjgpp"; then IFS=";"; fi
        +
        +try_without_dir=true
        +# First we try "pod2man", then "$dir/pod2man" for each item in $PATH.
        +for dir in dummy${IFS}$PATH; do
        +    if [ "$try_without_dir" = true ]; then
        +      # first iteration
        +      pod2man=pod2man
        +      try_without_dir=false
        +    else
        +      # second and later iterations
        +      pod2man="$dir/pod2man"
        +      if [ ! -f "$pod2man" ]; then  # '-x' is not available on Ultrix
        +        pod2man=''
        +      fi
        +    fi
        +
        +    if [ ! "$pod2man" = '' ]; then
        +        failure=none
        +
        +	if "$pod2man" --section=1 --center=OpenSSL --release=dev pod2mantest.pod | fgrep OpenSSL >/dev/null; then
        +	    :
        +	else
        +	    failure=BasicTest
        +	fi
        +
        +	if [ "$failure" = none ]; then
        +	    if "$pod2man" --section=1 --center=OpenSSL --release=dev pod2mantest.pod | grep '^MARKER - ' >/dev/null; then
        +	        failure=MultilineTest
        +	    fi
        +	fi
        +
        +
        +        if [ "$failure" = none ]; then
        +            echo "$pod2man"
        +            exit 0
        +        fi
        +
        +        echo "$pod2man does not work properly ('$failure' failed).  Looking for another pod2man ..." >&2
        +    fi
        +done
        +
        +echo "No working pod2man found.  Consider installing a new version." >&2
        +echo "As a workaround, we'll use a bundled old copy of pod2man.pl." >&2
        +echo "$1 ../../util/pod2man.pl"
        diff --git a/vendor/openssl/openssl/util/pod2mantest.pod b/vendor/openssl/openssl/util/pod2mantest.pod
        new file mode 100644
        index 000000000..5d2539a17
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/pod2mantest.pod
        @@ -0,0 +1,15 @@
        +=pod
        +
        +=head1 NAME
        +
        +foo, bar,
        +MARKER - test of multiline name section
        +
        +=head1 DESCRIPTION
        +
        +This is a test .pod file to see if we have a buggy pod2man or not.
        +If we have a buggy implementation, we will get a line matching the
        +regular expression "^ +MARKER - test of multiline name section *$"
        +at the end of the resulting document.
        +
        +=cut
        diff --git a/vendor/openssl/openssl/util/point.sh b/vendor/openssl/openssl/util/point.sh
        new file mode 100644
        index 000000000..da39899cb
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/point.sh
        @@ -0,0 +1,10 @@
        +#!/bin/sh
        +
        +rm -f "$2"
        +if test "$OSTYPE" = msdosdjgpp || test "x$PLATFORM" = xmingw ; then
        +    cp "$1" "$2"
        +else
        +    ln -s "$1" "$2"
        +fi
        +echo "$2 => $1"
        +
        diff --git a/vendor/openssl/openssl/util/selftest.pl b/vendor/openssl/openssl/util/selftest.pl
        new file mode 100644
        index 000000000..7b32e9f4f
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/selftest.pl
        @@ -0,0 +1,201 @@
        +#!/usr/local/bin/perl -w
        +#
        +# Run the test suite and generate a report
        +#
        +
        +if (! -f "Configure") {
        +    print "Please run perl util/selftest.pl in the OpenSSL directory.\n";
        +    exit 1;
        +}
        +
        +my $report="testlog";
        +my $os="??";
        +my $version="??";
        +my $platform0="??";
        +my $platform="??";
        +my $options="??";
        +my $last="??";
        +my $ok=0;
        +my $cc="cc";
        +my $cversion="??";
        +my $sep="-----------------------------------------------------------------------------\n";
        +my $not_our_fault="\nPlease ask your system administrator/vendor for more information.\n[Problems with your operating system setup should not be reported\nto the OpenSSL project.]\n";
        +
        +open(OUT,">$report") or die;
        +
        +print OUT "OpenSSL self-test report:\n\n";
        +
        +$uname=`uname -a`;
        +$uname="??\n" if $uname eq "";
        +
        +$c=`sh config -t`;
        +foreach $_ (split("\n",$c)) {
        +    $os=$1 if (/Operating system: (.*)$/);
        +    $platform0=$1 if (/Configuring for (.*)$/);
        +}
        +
        +system "sh config" if (! -f "Makefile");
        +
        +if (open(IN,"<Makefile")) {
        +    while (<IN>) {
        +	$version=$1 if (/^VERSION=(.*)$/);
        +	$platform=$1 if (/^PLATFORM=(.*)$/);
        +	$options=$1 if (/^OPTIONS=(.*)$/);
        +	$cc=$1 if (/^CC= *(.*)$/);
        +    }
        +    close(IN);
        +} else {
        +    print OUT "Error running config!\n";
        +}
        +
        +$cversion=`$cc -v 2>&1`;
        +$cversion=`$cc -V 2>&1` if $cversion =~ "[Uu]sage";
        +$cversion=`$cc -V |head -1` if $cversion =~ "Error";
        +$cversion=`$cc --version` if $cversion eq "";
        +$cversion =~ s/Reading specs.*\n//;
        +$cversion =~ s/usage.*\n//;
        +chomp $cversion;
        +
        +if (open(IN,"<CHANGES")) {
        +    while(<IN>) {
        +	if (/\*\) (.{0,55})/ && !/applies to/) {
        +	    $last=$1;
        +	    last;
        +	}
        +    }
        +    close(IN);
        +}
        +
        +print OUT "OpenSSL version:  $version\n";
        +print OUT "Last change:      $last...\n";
        +print OUT "Options:          $options\n" if $options ne "";
        +print OUT "OS (uname):       $uname";
        +print OUT "OS (config):      $os\n";
        +print OUT "Target (default): $platform0\n";
        +print OUT "Target:           $platform\n";
        +print OUT "Compiler:         $cversion\n";
        +print OUT "\n";
        +
        +print "Checking compiler...\n";
        +if (open(TEST,">cctest.c")) {
        +    print TEST "#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\nmain(){printf(\"Hello world\\n\");}\n";
        +    close(TEST);
        +    system("$cc -o cctest cctest.c");
        +    if (`./cctest` !~ /Hello world/) {
        +	print OUT "Compiler doesn't work.\n";
        +	print OUT $not_our_fault;
        +	goto err;
        +    }
        +    system("ar r cctest.a /dev/null");
        +    if (not -f "cctest.a") {
        +	print OUT "Check your archive tool (ar).\n";
        +	print OUT $not_our_fault;
        +	goto err;
        +    }
        +} else {
        +    print OUT "Can't create cctest.c\n";
        +}
        +if (open(TEST,">cctest.c")) {
        +    print TEST "#include <stdio.h>\n#include <stdlib.h>\n#include <openssl/opensslv.h>\nmain(){printf(OPENSSL_VERSION_TEXT);}\n";
        +    close(TEST);
        +    system("$cc -o cctest -Iinclude cctest.c");
        +    $cctest = `./cctest`;
        +    if ($cctest !~ /OpenSSL $version/) {
        +	if ($cctest =~ /OpenSSL/) {
        +	    print OUT "#include uses headers from different OpenSSL version!\n";
        +	} else {
        +	    print OUT "Can't compile test program!\n";
        +	}
        +	print OUT $not_our_fault;
        +	goto err;
        +    }
        +} else {
        +    print OUT "Can't create cctest.c\n";
        +}
        +
        +print "Running make...\n";
        +if (system("make 2>&1 | tee make.log") > 255) {
        +
        +    print OUT "make failed!\n";
        +    if (open(IN,"<make.log")) {
        +	print OUT $sep;
        +	while (<IN>) {
        +	    print OUT;
        +	}
        +	close(IN);
        +	print OUT $sep;
        +    } else {
        +	print OUT "make.log not found!\n";
        +    }
        +    goto err;
        +}
        +
        +# Not sure why this is here.  The tests themselves can detect if their
        +# particular feature isn't included, and should therefore skip themselves.
        +# To skip *all* tests just because one algorithm isn't included is like
        +# shooting mosquito with an elephant gun...
        +#                   -- Richard Levitte, inspired by problem report 1089
        +#
        +#$_=$options;
        +#s/no-asm//;
        +#s/no-shared//;
        +#s/no-krb5//;
        +#if (/no-/)
        +#{
        +#    print OUT "Test skipped.\n";
        +#    goto err;
        +#}
        +
        +print "Running make test...\n";
        +if (system("make test 2>&1 | tee maketest.log") > 255)
        + {
        +    print OUT "make test failed!\n";
        +} else {
        +    $ok=1;
        +}
        +
        +if ($ok and open(IN,"<maketest.log")) {
        +    while (<IN>) {
        +	$ok=2 if /^platform: $platform/;
        +    }
        +    close(IN);
        +}
        +
        +if ($ok != 2) {
        +    print OUT "Failure!\n";
        +    if (open(IN,"<make.log")) {
        +	print OUT $sep;
        +	while (<IN>) {
        +	    print OUT;
        +	}
        +	close(IN);
        +	print OUT $sep;
        +    } else {
        +	print OUT "make.log not found!\n";
        +    }
        +    if (open(IN,"<maketest.log")) {
        +	while (<IN>) {
        +	    print OUT;
        +	}
        +	close(IN);
        +	print OUT $sep;
        +    } else {
        +	print OUT "maketest.log not found!\n";
        +    }
        +} else {
        +    print OUT "Test passed.\n";
        +}
        +err:
        +close(OUT);
        +
        +print "\n";
        +open(IN,"<$report") or die;
        +while (<IN>) {
        +    if (/$sep/) {
        +	print "[...]\n";
        +	last;
        +    }
        +    print;
        +}
        +print "\nTest report in file $report\n";
        +
        diff --git a/vendor/openssl/openssl/util/shlib_wrap.sh b/vendor/openssl/openssl/util/shlib_wrap.sh
        new file mode 100644
        index 000000000..9416d593d
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/shlib_wrap.sh
        @@ -0,0 +1,93 @@
        +#!/bin/sh
        +
        +[ $# -ne 0 ] || set -x		# debug mode without arguments:-)
        +
        +THERE="`echo $0 | sed -e 's|[^/]*$||' 2>/dev/null`.."
        +[ -d "${THERE}" ] || exec "$@"	# should never happen...
        +
        +# Alternative to this is to parse ${THERE}/Makefile...
        +LIBCRYPTOSO="${THERE}/libcrypto.so"
        +if [ -f "$LIBCRYPTOSO" ]; then
        +    while [ -h "$LIBCRYPTOSO" ]; do
        +	LIBCRYPTOSO="${THERE}/`ls -l "$LIBCRYPTOSO" | sed -e 's|.*\-> ||'`"
        +    done
        +    SOSUFFIX=`echo ${LIBCRYPTOSO} | sed -e 's|.*\.so||' 2>/dev/null`
        +    LIBSSLSO="${THERE}/libssl.so${SOSUFFIX}"
        +fi
        +
        +SYSNAME=`(uname -s) 2>/dev/null`;
        +case "$SYSNAME" in
        +SunOS|IRIX*)
        +	# SunOS and IRIX run-time linkers evaluate alternative
        +	# variables depending on target ABI...
        +	rld_var=LD_LIBRARY_PATH
        +	case "`(/usr/bin/file "$LIBCRYPTOSO") 2>/dev/null`" in
        +	*ELF\ 64*SPARC*|*ELF\ 64*AMD64*)
        +		[ -n "$LD_LIBRARY_PATH_64" ] && rld_var=LD_LIBRARY_PATH_64
        +		LD_PRELOAD_64="$LIBCRYPTOSO $LIBSSLSO"; export LD_PRELOAD_64
        +		preload_var=LD_PRELOAD_64
        +		;;
        +	# Why are newly built .so's preloaded anyway? Because run-time
        +	# .so lookup path embedded into application takes precedence
        +	# over LD_LIBRARY_PATH and as result application ends up linking
        +	# to previously installed .so's. On IRIX instead of preloading
        +	# newly built .so's we trick run-time linker to fail to find
        +	# the installed .so by setting _RLD_ROOT variable.
        +	*ELF\ 32*MIPS*)
        +		#_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD_LIST
        +		_RLD_ROOT=/no/such/dir; export _RLD_ROOT
        +		eval $rld_var=\"/usr/lib'${'$rld_var':+:$'$rld_var'}'\"
        +		preload_var=_RLD_LIST
        +		;;
        +	*ELF\ N32*MIPS*)
        +		[ -n "$LD_LIBRARYN32_PATH" ] && rld_var=LD_LIBRARYN32_PATH
        +		#_RLDN32_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLDN32_LIST
        +		_RLDN32_ROOT=/no/such/dir; export _RLDN32_ROOT
        +		eval $rld_var=\"/usr/lib32'${'$rld_var':+:$'$rld_var'}'\"
        +		preload_var=_RLDN32_LIST
        +		;;
        +	*ELF\ 64*MIPS*)
        +		[ -n "$LD_LIBRARY64_PATH"  ] && rld_var=LD_LIBRARY64_PATH
        +		#_RLD64_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD64_LIST
        +		_RLD64_ROOT=/no/such/dir; export _RLD64_ROOT
        +		eval $rld_var=\"/usr/lib64'${'$rld_var':+:$'$rld_var'}'\"
        +		preload_var=_RLD64_LIST
        +		;;
        +	esac
        +	eval $rld_var=\"${THERE}'${'$rld_var':+:$'$rld_var'}'\"; export $rld_var
        +	unset rld_var
        +	;;
        +*)	LD_LIBRARY_PATH="${THERE}:$LD_LIBRARY_PATH"	# Linux, ELF HP-UX
        +	DYLD_LIBRARY_PATH="${THERE}:$DYLD_LIBRARY_PATH"	# MacOS X
        +	SHLIB_PATH="${THERE}:$SHLIB_PATH"		# legacy HP-UX
        +	LIBPATH="${THERE}:$LIBPATH"			# AIX, OS/2
        +	export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH
        +	# Even though $PATH is adjusted [for Windows sake], it doesn't
        +	# necessarily does the trick. Trouble is that with introduction
        +	# of SafeDllSearchMode in XP/2003 it's more appropriate to copy
        +	# .DLLs in vicinity of executable, which is done elsewhere...
        +	if [ "$OSTYPE" != msdosdjgpp ]; then
        +		PATH="${THERE}:$PATH"; export PATH
        +	fi
        +	;;
        +esac
        +
        +if [ -f "$LIBCRYPTOSO" -a -z "$preload_var" ]; then
        +	# Following three lines are major excuse for isolating them into
        +	# this wrapper script. Original reason for setting LD_PRELOAD
        +	# was to make it possible to pass 'make test' when user linked
        +	# with -rpath pointing to previous version installation. Wrapping
        +	# it into a script makes it possible to do so on multi-ABI
        +	# platforms.
        +	case "$SYSNAME" in
        +	*BSD|QNX)	LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;;	# *BSD, QNX
        +	*)	LD_PRELOAD="$LIBCRYPTOSO $LIBSSLSO" ;;	# SunOS, Linux, ELF HP-UX
        +	esac
        +	_RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"	# Tru64, o32 IRIX
        +	DYLD_INSERT_LIBRARIES="$LIBCRYPTOSO:$LIBSSLSO"	# MacOS X
        +	export LD_PRELOAD _RLD_LIST DYLD_INSERT_LIBRARIES
        +fi
        +
        +cmd="$1${EXE_EXT}"
        +shift
        +exec "$cmd" "$@"
        diff --git a/vendor/openssl/openssl/util/sp-diff.pl b/vendor/openssl/openssl/util/sp-diff.pl
        new file mode 100644
        index 000000000..9d6c60387
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/sp-diff.pl
        @@ -0,0 +1,80 @@
        +#!/usr/local/bin/perl
        +#
        +# This file takes as input, the files that have been output from
        +# ssleay speed.
        +# It prints a table of the relative differences with %100 being 'no difference'
        +#
        +
        +($#ARGV == 1) || die "$0 speedout1 speedout2\n";
        +
        +%one=&loadfile($ARGV[0]);
        +%two=&loadfile($ARGV[1]);
        +
        +$line=0;
        +foreach $a ("md2","md4","md5","sha","sha1","rc4","des cfb","des cbc","des ede3",
        +	"idea cfb","idea cbc","rc2 cfb","rc2 cbc","blowfish cbc","cast cbc")
        +	{
        +	if (defined($one{$a,8}) && defined($two{$a,8}))
        +		{
        +		print "type              8 byte%    64 byte%   256 byte%  1024 byte%  8192 byte%\n"
        +			unless $line;
        +		$line++;
        +		printf "%-12s ",$a;
        +		foreach $b (8,64,256,1024,8192)
        +			{
        +			$r=$two{$a,$b}/$one{$a,$b}*100;
        +			printf "%12.2f",$r;
        +			}
        +		print "\n";
        +		}
        +	}
        +
        +foreach $a	(
        +		"rsa  512","rsa 1024","rsa 2048","rsa 4096",
        +		"dsa  512","dsa 1024","dsa 2048",
        +		)
        +	{
        +	if (defined($one{$a,1}) && defined($two{$a,1}))
        +		{
        +		$r1=($one{$a,1}/$two{$a,1})*100;
        +		$r2=($one{$a,2}/$two{$a,2})*100;
        +		printf "$a bits %%    %6.2f %%    %6.2f\n",$r1,$r2;
        +		}
        +	}
        +
        +sub loadfile
        +	{
        +	local($file)=@_;
        +	local($_,%ret);
        +
        +	open(IN,"<$file") || die "unable to open '$file' for input\n";
        +	$header=1;
        +	while (<IN>)
        +		{
        +		$header=0 if /^[dr]sa/;
        +		if (/^type/) { $header=0; next; }
        +		next if $header;
        +		chop;
        +		@a=split;
        +		if ($a[0] =~ /^[dr]sa$/)
        +			{
        +			($n,$t1,$t2)=($_ =~ /^([dr]sa\s+\d+)\s+bits\s+([.\d]+)s\s+([.\d]+)/);
        +			$ret{$n,1}=$t1;
        +			$ret{$n,2}=$t2;
        +			}
        +		else
        +			{
        +			$n=join(' ',grep(/[^k]$/,@a));
        +			@k=grep(s/k$//,@a);
        +			
        +			$ret{$n,   8}=$k[0];
        +			$ret{$n,  64}=$k[1];
        +			$ret{$n, 256}=$k[2];
        +			$ret{$n,1024}=$k[3];
        +			$ret{$n,8192}=$k[4];
        +			}
        +		}
        +	close(IN);
        +	return(%ret);
        +	}
        +
        diff --git a/vendor/openssl/openssl/util/speed.sh b/vendor/openssl/openssl/util/speed.sh
        new file mode 100644
        index 000000000..f48970619
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/speed.sh
        @@ -0,0 +1,39 @@
        +#!/bin/sh
        +
        +#
        +# This is a ugly script use, in conjuction with editing the 'b'
        +# configuration in the $(TOP)/Configure script which will
        +# output when finished a file called speed.log which is the
        +# timings of SSLeay with various options turned on or off.
        +#
        +# from the $(TOP) directory
        +# Edit Configure, modifying things to do with the b/bl-4c-2c etc
        +# configurations.
        +#
        +
        +make clean
        +perl Configure b
        +make
        +apps/ssleay version -v -b -f >speed.1
        +apps/ssleay speed >speed.1l
        +
        +perl Configure bl-4c-2c
        +/bin/rm -f crypto/rc4/*.o crypto/bn/bn*.o crypto/md2/md2_dgst.o
        +make
        +apps/ssleay speed rc4 rsa md2 >speed.2l
        +
        +perl Configure bl-4c-ri
        +/bin/rm -f crypto/rc4/rc4*.o
        +make
        +apps/ssleay speed rc4 >speed.3l
        +
        +perl Configure b2-is-ri-dp
        +/bin/rm -f crypto/idea/i_*.o crypto/rc4/*.o crypto/des/ecb_enc.o crypto/bn/bn*.o
        +apps/ssleay speed rsa rc4 idea des >speed.4l
        +
        +cat speed.1 >speed.log
        +cat speed.1l >>speed.log
        +perl util/sp-diff.pl speed.1l speed.2l >>speed.log
        +perl util/sp-diff.pl speed.1l speed.3l >>speed.log
        +perl util/sp-diff.pl speed.1l speed.4l >>speed.log
        +
        diff --git a/vendor/openssl/openssl/util/src-dep.pl b/vendor/openssl/openssl/util/src-dep.pl
        new file mode 100644
        index 000000000..ad997e474
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/src-dep.pl
        @@ -0,0 +1,147 @@
        +#!/usr/local/bin/perl
        +
        +# we make up an array of
        +# $file{function_name}=filename;
        +# $unres{filename}="func1 func2 ...."
        +$debug=1;
        +#$nm_func="parse_linux";
        +$nm_func="parse_solaris";
        +
        +foreach (@ARGV)
        +	{
        +	&$nm_func($_);
        +	}
        +
        +foreach $file (sort keys %unres)
        +	{
        +	@a=split(/\s+/,$unres{$file});
        +	%ff=();
        +	foreach $func (@a)
        +		{
        +		$f=$file{$func};
        +		$ff{$f}=1 if $f ne "";
        +		}
        +
        +	foreach $a (keys %ff)
        +		{ $we_need{$file}.="$a "; }
        +	}
        +
        +foreach $file (sort keys %we_need)
        +	{
        +#	print "	$file $we_need{$file}\n";
        +	foreach $bit (split(/\s+/,$we_need{$file}))
        +		{ push(@final,&walk($bit)); }
        +
        +	foreach (@final) { $fin{$_}=1; }
        +	@final="";
        +	foreach (sort keys %fin)
        +		{ push(@final,$_); }
        +
        +	print "$file: @final\n";
        +	}
        +
        +sub walk
        +	{
        +	local($f)=@_;
        +	local(@a,%seen,@ret,$r);
        +
        +	@ret="";
        +	$f =~ s/^\s+//;
        +	$f =~ s/\s+$//;
        +	return "" if ($f =~ "^\s*$");
        +
        +	return(split(/\s/,$done{$f})) if defined ($done{$f});
        +
        +	return if $in{$f} > 0;
        +	$in{$f}++;
        +	push(@ret,$f);
        +	foreach $r (split(/\s+/,$we_need{$f}))
        +		{
        +		push(@ret,&walk($r));
        +		}
        +	$in{$f}--;
        +	$done{$f}=join(" ",@ret);
        +	return(@ret);
        +	}
        +
        +sub parse_linux
        +	{
        +	local($name)=@_;
        +
        +	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
        +	while (<IN>)
        +		{
        +		chop;
        +		next if /^\s*$/;
        +		if (/^[^[](.*):$/)
        +			{
        +			$file=$1;
        +			$file="$1.c" if /\[(.*).o\]/;
        +			print STDERR "$file\n";
        +			$we_need{$file}=" ";
        +			next;
        +			}
        +
        +		@a=split(/\s*\|\s*/);
        +		next unless $#a == 7;
        +		next unless $a[4] eq "GLOB";
        +		if ($a[6] eq "UNDEF")
        +			{
        +			$unres{$file}.=$a[7]." ";
        +			}
        +		else
        +			{
        +			if ($file{$a[7]} ne "")
        +				{
        +				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
        +				}
        +			else
        +				{
        +				$file{$a[7]}=$file;
        +				}
        +			}
        +		}
        +	close(IN);
        +	}
        +
        +sub parse_solaris
        +	{
        +	local($name)=@_;
        +
        +	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
        +	while (<IN>)
        +		{
        +		chop;
        +		next if /^\s*$/;
        +		if (/^(\S+):$/)
        +			{
        +			$file=$1;
        +			#$file="$1.c" if $file =~ /^(.*).o$/;
        +			print STDERR "$file\n";
        +			$we_need{$file}=" ";
        +			next;
        +			}
        +		@a=split(/\s*\|\s*/);
        +		next unless $#a == 7;
        +		next unless $a[4] eq "GLOB";
        +		if ($a[6] eq "UNDEF")
        +			{
        +			$unres{$file}.=$a[7]." ";
        +			print STDERR "$file needs $a[7]\n" if $debug;
        +			}
        +		else
        +			{
        +			if ($file{$a[7]} ne "")
        +				{
        +				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
        +				}
        +			else
        +				{
        +				$file{$a[7]}=$file;
        +				print STDERR "$file has $a[7]\n" if $debug;
        +				}
        +			}
        +		}
        +	close(IN);
        +	}
        +
        diff --git a/vendor/openssl/openssl/util/ssleay.num b/vendor/openssl/openssl/util/ssleay.num
        new file mode 100644
        index 000000000..37655bc40
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/ssleay.num
        @@ -0,0 +1,322 @@
        +ERR_load_SSL_strings                    1	EXIST::FUNCTION:
        +SSL_CIPHER_description                  2	EXIST::FUNCTION:
        +SSL_CTX_add_client_CA                   3	EXIST::FUNCTION:
        +SSL_CTX_add_session                     4	EXIST::FUNCTION:
        +SSL_CTX_check_private_key               5	EXIST::FUNCTION:
        +SSL_CTX_ctrl                            6	EXIST::FUNCTION:
        +SSL_CTX_flush_sessions                  7	EXIST::FUNCTION:
        +SSL_CTX_free                            8	EXIST::FUNCTION:
        +SSL_CTX_get_client_CA_list              9	EXIST::FUNCTION:
        +SSL_CTX_get_verify_callback             10	EXIST::FUNCTION:
        +SSL_CTX_get_verify_mode                 11	EXIST::FUNCTION:
        +SSL_CTX_new                             12	EXIST::FUNCTION:
        +SSL_CTX_remove_session                  13	EXIST::FUNCTION:
        +SSL_CTX_set_cipher_list                 15	EXIST::FUNCTION:
        +SSL_CTX_set_client_CA_list              16	EXIST::FUNCTION:
        +SSL_CTX_set_default_passwd_cb           17	EXIST::FUNCTION:
        +SSL_CTX_set_ssl_version                 19	EXIST::FUNCTION:
        +SSL_CTX_set_verify                      21	EXIST::FUNCTION:
        +SSL_CTX_use_PrivateKey                  22	EXIST::FUNCTION:
        +SSL_CTX_use_PrivateKey_ASN1             23	EXIST::FUNCTION:
        +SSL_CTX_use_PrivateKey_file             24	EXIST::FUNCTION:STDIO
        +SSL_CTX_use_RSAPrivateKey               25	EXIST::FUNCTION:RSA
        +SSL_CTX_use_RSAPrivateKey_ASN1          26	EXIST::FUNCTION:RSA
        +SSL_CTX_use_RSAPrivateKey_file          27	EXIST::FUNCTION:RSA,STDIO
        +SSL_CTX_use_certificate                 28	EXIST::FUNCTION:
        +SSL_CTX_use_certificate_ASN1            29	EXIST::FUNCTION:
        +SSL_CTX_use_certificate_file            30	EXIST::FUNCTION:STDIO
        +SSL_SESSION_free                        31	EXIST::FUNCTION:
        +SSL_SESSION_new                         32	EXIST::FUNCTION:
        +SSL_SESSION_print                       33	EXIST::FUNCTION:BIO
        +SSL_SESSION_print_fp                    34	EXIST::FUNCTION:FP_API
        +SSL_accept                              35	EXIST::FUNCTION:
        +SSL_add_client_CA                       36	EXIST::FUNCTION:
        +SSL_alert_desc_string                   37	EXIST::FUNCTION:
        +SSL_alert_desc_string_long              38	EXIST::FUNCTION:
        +SSL_alert_type_string                   39	EXIST::FUNCTION:
        +SSL_alert_type_string_long              40	EXIST::FUNCTION:
        +SSL_check_private_key                   41	EXIST::FUNCTION:
        +SSL_clear                               42	EXIST::FUNCTION:
        +SSL_connect                             43	EXIST::FUNCTION:
        +SSL_copy_session_id                     44	EXIST::FUNCTION:
        +SSL_ctrl                                45	EXIST::FUNCTION:
        +SSL_dup                                 46	EXIST::FUNCTION:
        +SSL_dup_CA_list                         47	EXIST::FUNCTION:
        +SSL_free                                48	EXIST::FUNCTION:
        +SSL_get_certificate                     49	EXIST::FUNCTION:
        +SSL_get_cipher_list                     52	EXIST::FUNCTION:
        +SSL_get_ciphers                         55	EXIST::FUNCTION:
        +SSL_get_client_CA_list                  56	EXIST::FUNCTION:
        +SSL_get_default_timeout                 57	EXIST::FUNCTION:
        +SSL_get_error                           58	EXIST::FUNCTION:
        +SSL_get_fd                              59	EXIST::FUNCTION:
        +SSL_get_peer_cert_chain                 60	EXIST::FUNCTION:
        +SSL_get_peer_certificate                61	EXIST::FUNCTION:
        +SSL_get_rbio                            63	EXIST::FUNCTION:BIO
        +SSL_get_read_ahead                      64	EXIST::FUNCTION:
        +SSL_get_shared_ciphers                  65	EXIST::FUNCTION:
        +SSL_get_ssl_method                      66	EXIST::FUNCTION:
        +SSL_get_verify_callback                 69	EXIST::FUNCTION:
        +SSL_get_verify_mode                     70	EXIST::FUNCTION:
        +SSL_get_version                         71	EXIST::FUNCTION:
        +SSL_get_wbio                            72	EXIST::FUNCTION:BIO
        +SSL_load_client_CA_file                 73	EXIST::FUNCTION:STDIO
        +SSL_load_error_strings                  74	EXIST::FUNCTION:
        +SSL_new                                 75	EXIST::FUNCTION:
        +SSL_peek                                76	EXIST::FUNCTION:
        +SSL_pending                             77	EXIST::FUNCTION:
        +SSL_read                                78	EXIST::FUNCTION:
        +SSL_renegotiate                         79	EXIST::FUNCTION:
        +SSL_rstate_string                       80	EXIST::FUNCTION:
        +SSL_rstate_string_long                  81	EXIST::FUNCTION:
        +SSL_set_accept_state                    82	EXIST::FUNCTION:
        +SSL_set_bio                             83	EXIST::FUNCTION:BIO
        +SSL_set_cipher_list                     84	EXIST::FUNCTION:
        +SSL_set_client_CA_list                  85	EXIST::FUNCTION:
        +SSL_set_connect_state                   86	EXIST::FUNCTION:
        +SSL_set_fd                              87	EXIST::FUNCTION:SOCK
        +SSL_set_read_ahead                      88	EXIST::FUNCTION:
        +SSL_set_rfd                             89	EXIST::FUNCTION:SOCK
        +SSL_set_session                         90	EXIST::FUNCTION:
        +SSL_set_ssl_method                      91	EXIST::FUNCTION:
        +SSL_set_verify                          94	EXIST::FUNCTION:
        +SSL_set_wfd                             95	EXIST::FUNCTION:SOCK
        +SSL_shutdown                            96	EXIST::FUNCTION:
        +SSL_state_string                        97	EXIST::FUNCTION:
        +SSL_state_string_long                   98	EXIST::FUNCTION:
        +SSL_use_PrivateKey                      99	EXIST::FUNCTION:
        +SSL_use_PrivateKey_ASN1                 100	EXIST::FUNCTION:
        +SSL_use_PrivateKey_file                 101	EXIST::FUNCTION:STDIO
        +SSL_use_RSAPrivateKey                   102	EXIST::FUNCTION:RSA
        +SSL_use_RSAPrivateKey_ASN1              103	EXIST::FUNCTION:RSA
        +SSL_use_RSAPrivateKey_file              104	EXIST::FUNCTION:RSA,STDIO
        +SSL_use_certificate                     105	EXIST::FUNCTION:
        +SSL_use_certificate_ASN1                106	EXIST::FUNCTION:
        +SSL_use_certificate_file                107	EXIST::FUNCTION:STDIO
        +SSL_write                               108	EXIST::FUNCTION:
        +SSLeay_add_ssl_algorithms               109	NOEXIST::FUNCTION:
        +SSLv23_client_method                    110	EXIST::FUNCTION:RSA
        +SSLv23_method                           111	EXIST::FUNCTION:RSA
        +SSLv23_server_method                    112	EXIST::FUNCTION:RSA
        +SSLv2_client_method                     113	EXIST::FUNCTION:RSA,SSL2
        +SSLv2_method                            114	EXIST::FUNCTION:RSA,SSL2
        +SSLv2_server_method                     115	EXIST::FUNCTION:RSA,SSL2
        +SSLv3_client_method                     116	EXIST::FUNCTION:
        +SSLv3_method                            117	EXIST::FUNCTION:
        +SSLv3_server_method                     118	EXIST::FUNCTION:
        +d2i_SSL_SESSION                         119	EXIST::FUNCTION:
        +i2d_SSL_SESSION                         120	EXIST::FUNCTION:
        +BIO_f_ssl                               121	EXIST::FUNCTION:BIO
        +BIO_new_ssl                             122	EXIST::FUNCTION:BIO
        +BIO_proxy_ssl_copy_session_id           123	NOEXIST::FUNCTION:
        +BIO_ssl_copy_session_id                 124	EXIST::FUNCTION:BIO
        +SSL_do_handshake                        125	EXIST::FUNCTION:
        +SSL_get_privatekey                      126	EXIST::FUNCTION:
        +SSL_get_current_cipher                  127	EXIST::FUNCTION:
        +SSL_CIPHER_get_bits                     128	EXIST::FUNCTION:
        +SSL_CIPHER_get_version                  129	EXIST::FUNCTION:
        +SSL_CIPHER_get_name                     130	EXIST::FUNCTION:
        +BIO_ssl_shutdown                        131	EXIST::FUNCTION:BIO
        +SSL_SESSION_cmp                         132	NOEXIST::FUNCTION:
        +SSL_SESSION_hash                        133	NOEXIST::FUNCTION:
        +SSL_SESSION_get_time                    134	EXIST::FUNCTION:
        +SSL_SESSION_set_time                    135	EXIST::FUNCTION:
        +SSL_SESSION_get_timeout                 136	EXIST::FUNCTION:
        +SSL_SESSION_set_timeout                 137	EXIST::FUNCTION:
        +SSL_CTX_get_ex_data                     138	EXIST::FUNCTION:
        +SSL_CTX_get_quiet_shutdown              140	EXIST::FUNCTION:
        +SSL_CTX_load_verify_locations           141	EXIST::FUNCTION:
        +SSL_CTX_set_default_verify_paths        142	EXIST:!VMS:FUNCTION:
        +SSL_CTX_set_def_verify_paths            142	EXIST:VMS:FUNCTION:
        +SSL_CTX_set_ex_data                     143	EXIST::FUNCTION:
        +SSL_CTX_set_quiet_shutdown              145	EXIST::FUNCTION:
        +SSL_SESSION_get_ex_data                 146	EXIST::FUNCTION:
        +SSL_SESSION_set_ex_data                 148	EXIST::FUNCTION:
        +SSL_get_SSL_CTX                         150	EXIST::FUNCTION:
        +SSL_get_ex_data                         151	EXIST::FUNCTION:
        +SSL_get_quiet_shutdown                  153	EXIST::FUNCTION:
        +SSL_get_session                         154	EXIST::FUNCTION:
        +SSL_get_shutdown                        155	EXIST::FUNCTION:
        +SSL_get_verify_result                   157	EXIST::FUNCTION:
        +SSL_set_ex_data                         158	EXIST::FUNCTION:
        +SSL_set_info_callback                   160	EXIST::FUNCTION:
        +SSL_set_quiet_shutdown                  161	EXIST::FUNCTION:
        +SSL_set_shutdown                        162	EXIST::FUNCTION:
        +SSL_set_verify_result                   163	EXIST::FUNCTION:
        +SSL_version                             164	EXIST::FUNCTION:
        +SSL_get_info_callback                   165	EXIST::FUNCTION:
        +SSL_state                               166	EXIST::FUNCTION:
        +SSL_CTX_get_ex_new_index                167	EXIST::FUNCTION:
        +SSL_SESSION_get_ex_new_index            168	EXIST::FUNCTION:
        +SSL_get_ex_new_index                    169	EXIST::FUNCTION:
        +TLSv1_method                            170	EXIST::FUNCTION:
        +TLSv1_server_method                     171	EXIST::FUNCTION:
        +TLSv1_client_method                     172	EXIST::FUNCTION:
        +BIO_new_buffer_ssl_connect              173	EXIST::FUNCTION:BIO
        +BIO_new_ssl_connect                     174	EXIST::FUNCTION:BIO
        +SSL_get_ex_data_X509_STORE_CTX_idx      175	EXIST:!VMS:FUNCTION:
        +SSL_get_ex_d_X509_STORE_CTX_idx         175	EXIST:VMS:FUNCTION:
        +SSL_CTX_set_tmp_dh_callback             176	EXIST::FUNCTION:DH
        +SSL_CTX_set_tmp_rsa_callback            177	EXIST::FUNCTION:RSA
        +SSL_CTX_set_timeout                     178	EXIST::FUNCTION:
        +SSL_CTX_get_timeout                     179	EXIST::FUNCTION:
        +SSL_CTX_get_cert_store                  180	EXIST::FUNCTION:
        +SSL_CTX_set_cert_store                  181	EXIST::FUNCTION:
        +SSL_want                                182	EXIST::FUNCTION:
        +SSL_library_init                        183	EXIST::FUNCTION:
        +SSL_COMP_add_compression_method         184	EXIST::FUNCTION:COMP
        +SSL_add_file_cert_subjects_to_stack     185	EXIST:!VMS:FUNCTION:STDIO
        +SSL_add_file_cert_subjs_to_stk          185	EXIST:VMS:FUNCTION:STDIO
        +SSL_set_tmp_rsa_callback                186	EXIST::FUNCTION:RSA
        +SSL_set_tmp_dh_callback                 187	EXIST::FUNCTION:DH
        +SSL_add_dir_cert_subjects_to_stack      188	EXIST:!VMS:FUNCTION:STDIO
        +SSL_add_dir_cert_subjs_to_stk           188	EXIST:VMS:FUNCTION:STDIO
        +SSL_set_session_id_context              189	EXIST::FUNCTION:
        +SSL_CTX_use_certificate_chain_file      222	EXIST:!VMS:FUNCTION:STDIO
        +SSL_CTX_use_cert_chain_file             222	EXIST:VMS:FUNCTION:STDIO
        +SSL_CTX_set_verify_depth                225	EXIST::FUNCTION:
        +SSL_set_verify_depth                    226	EXIST::FUNCTION:
        +SSL_CTX_get_verify_depth                228	EXIST::FUNCTION:
        +SSL_get_verify_depth                    229	EXIST::FUNCTION:
        +SSL_CTX_set_session_id_context          231	EXIST::FUNCTION:
        +SSL_CTX_set_cert_verify_callback        232	EXIST:!VMS:FUNCTION:
        +SSL_CTX_set_cert_verify_cb              232	EXIST:VMS:FUNCTION:
        +SSL_CTX_set_default_passwd_cb_userdata  235	EXIST:!VMS:FUNCTION:
        +SSL_CTX_set_def_passwd_cb_ud            235	EXIST:VMS:FUNCTION:
        +SSL_set_purpose                         236	EXIST::FUNCTION:
        +SSL_CTX_set_trust                       237	EXIST::FUNCTION:
        +SSL_CTX_set_purpose                     238	EXIST::FUNCTION:
        +SSL_set_trust                           239	EXIST::FUNCTION:
        +SSL_get_finished                        240	EXIST::FUNCTION:
        +SSL_get_peer_finished                   241	EXIST::FUNCTION:
        +SSL_get1_session                        242	EXIST::FUNCTION:
        +SSL_CTX_callback_ctrl                   243	EXIST::FUNCTION:
        +SSL_callback_ctrl                       244	EXIST::FUNCTION:
        +SSL_CTX_sessions                        245	EXIST::FUNCTION:
        +SSL_get_rfd                             246	EXIST::FUNCTION:
        +SSL_get_wfd                             247	EXIST::FUNCTION:
        +kssl_cget_tkt                           248	EXIST::FUNCTION:KRB5
        +SSL_has_matching_session_id             249	EXIST::FUNCTION:
        +kssl_err_set                            250	EXIST::FUNCTION:KRB5
        +kssl_ctx_show                           251	EXIST::FUNCTION:KRB5
        +kssl_validate_times                     252	EXIST::FUNCTION:KRB5
        +kssl_check_authent                      253	EXIST::FUNCTION:KRB5
        +kssl_ctx_new                            254	EXIST::FUNCTION:KRB5
        +kssl_build_principal_2                  255	EXIST::FUNCTION:KRB5
        +kssl_skip_confound                      256	EXIST::FUNCTION:KRB5
        +kssl_sget_tkt                           257	EXIST::FUNCTION:KRB5
        +SSL_set_generate_session_id             258	EXIST::FUNCTION:
        +kssl_ctx_setkey                         259	EXIST::FUNCTION:KRB5
        +kssl_ctx_setprinc                       260	EXIST::FUNCTION:KRB5
        +kssl_ctx_free                           261	EXIST::FUNCTION:KRB5
        +kssl_krb5_free_data_contents            262	EXIST::FUNCTION:KRB5
        +kssl_ctx_setstring                      263	EXIST::FUNCTION:KRB5
        +SSL_CTX_set_generate_session_id         264	EXIST::FUNCTION:
        +SSL_renegotiate_pending                 265	EXIST::FUNCTION:
        +SSL_CTX_set_msg_callback                266	EXIST::FUNCTION:
        +SSL_set_msg_callback                    267	EXIST::FUNCTION:
        +DTLSv1_client_method                    268	EXIST::FUNCTION:
        +SSL_CTX_set_tmp_ecdh_callback           269	EXIST::FUNCTION:ECDH
        +SSL_set_tmp_ecdh_callback               270	EXIST::FUNCTION:ECDH
        +SSL_COMP_get_name                       271	EXIST::FUNCTION:COMP
        +SSL_get_current_compression             272	EXIST::FUNCTION:COMP
        +DTLSv1_method                           273	EXIST::FUNCTION:
        +SSL_get_current_expansion               274	EXIST::FUNCTION:COMP
        +DTLSv1_server_method                    275	EXIST::FUNCTION:
        +SSL_COMP_get_compression_methods        276	EXIST:!VMS:FUNCTION:COMP
        +SSL_COMP_get_compress_methods           276	EXIST:VMS:FUNCTION:COMP
        +SSL_SESSION_get_id                      277	EXIST::FUNCTION:
        +SSL_CTX_sess_set_new_cb                 278	EXIST::FUNCTION:
        +SSL_CTX_sess_get_get_cb                 279	EXIST::FUNCTION:
        +SSL_CTX_sess_set_get_cb                 280	EXIST::FUNCTION:
        +SSL_CTX_set_cookie_verify_cb            281	EXIST::FUNCTION:
        +SSL_CTX_get_info_callback               282	EXIST::FUNCTION:
        +SSL_CTX_set_cookie_generate_cb          283	EXIST::FUNCTION:
        +SSL_CTX_set_client_cert_cb              284	EXIST::FUNCTION:
        +SSL_CTX_sess_set_remove_cb              285	EXIST::FUNCTION:
        +SSL_CTX_set_info_callback               286	EXIST::FUNCTION:
        +SSL_CTX_sess_get_new_cb                 287	EXIST::FUNCTION:
        +SSL_CTX_get_client_cert_cb              288	EXIST::FUNCTION:
        +SSL_CTX_sess_get_remove_cb              289	EXIST::FUNCTION:
        +SSL_set_SSL_CTX                         290	EXIST::FUNCTION:
        +SSL_get_servername                      291	EXIST::FUNCTION:TLSEXT
        +SSL_get_servername_type                 292	EXIST::FUNCTION:TLSEXT
        +SSL_CTX_set_client_cert_engine          293	EXIST::FUNCTION:ENGINE
        +SSL_CTX_use_psk_identity_hint           294	EXIST::FUNCTION:PSK
        +SSL_CTX_set_psk_client_callback         295	EXIST::FUNCTION:PSK
        +PEM_write_bio_SSL_SESSION               296	EXIST::FUNCTION:
        +SSL_get_psk_identity_hint               297	EXIST::FUNCTION:PSK
        +SSL_set_psk_server_callback             298	EXIST::FUNCTION:PSK
        +SSL_use_psk_identity_hint               299	EXIST::FUNCTION:PSK
        +SSL_set_psk_client_callback             300	EXIST::FUNCTION:PSK
        +PEM_read_SSL_SESSION                    301	EXIST:!WIN16:FUNCTION:
        +PEM_read_bio_SSL_SESSION                302	EXIST::FUNCTION:
        +SSL_CTX_set_psk_server_callback         303	EXIST::FUNCTION:PSK
        +SSL_get_psk_identity                    304	EXIST::FUNCTION:PSK
        +PEM_write_SSL_SESSION                   305	EXIST:!WIN16:FUNCTION:
        +SSL_set_session_ticket_ext              306	EXIST::FUNCTION:
        +SSL_set_session_secret_cb               307	EXIST::FUNCTION:
        +SSL_set_session_ticket_ext_cb           308	EXIST::FUNCTION:
        +SSL_set1_param                          309	EXIST::FUNCTION:
        +SSL_CTX_set1_param                      310	EXIST::FUNCTION:
        +SSL_tls1_key_exporter                   311	NOEXIST::FUNCTION:
        +SSL_renegotiate_abbreviated             312	EXIST::FUNCTION:
        +TLSv1_1_method                          313	EXIST::FUNCTION:
        +TLSv1_1_client_method                   314	EXIST::FUNCTION:
        +TLSv1_1_server_method                   315	EXIST::FUNCTION:
        +SSL_CTX_set_srp_client_pwd_callback     316	EXIST:!VMS:FUNCTION:SRP
        +SSL_CTX_set_srp_client_pwd_cb           316	EXIST:VMS:FUNCTION:SRP
        +SSL_get_srp_g                           317	EXIST::FUNCTION:SRP
        +SSL_CTX_set_srp_username_callback       318	EXIST:!VMS:FUNCTION:SRP
        +SSL_CTX_set_srp_un_cb                   318	EXIST:VMS:FUNCTION:SRP
        +SSL_get_srp_userinfo                    319	EXIST::FUNCTION:SRP
        +SSL_set_srp_server_param                320	EXIST::FUNCTION:SRP
        +SSL_set_srp_server_param_pw             321	EXIST::FUNCTION:SRP
        +SSL_get_srp_N                           322	EXIST::FUNCTION:SRP
        +SSL_get_srp_username                    323	EXIST::FUNCTION:SRP
        +SSL_CTX_set_srp_password                324	EXIST::FUNCTION:SRP
        +SSL_CTX_set_srp_strength                325	EXIST::FUNCTION:SRP
        +SSL_CTX_set_srp_verify_param_callback   326	EXIST:!VMS:FUNCTION:SRP
        +SSL_CTX_set_srp_vfy_param_cb            326	EXIST:VMS:FUNCTION:SRP
        +SSL_CTX_set_srp_miss_srp_un_cb          327	NOEXIST::FUNCTION:
        +SSL_CTX_set_srp_missing_srp_username_callback 327	NOEXIST::FUNCTION:
        +SSL_CTX_set_srp_cb_arg                  328	EXIST::FUNCTION:SRP
        +SSL_CTX_set_srp_username                329	EXIST::FUNCTION:SRP
        +SSL_CTX_SRP_CTX_init                    330	EXIST::FUNCTION:SRP
        +SSL_SRP_CTX_init                        331	EXIST::FUNCTION:SRP
        +SRP_Calc_A_param                        332	EXIST::FUNCTION:SRP
        +SRP_generate_server_master_secret       333	EXIST:!VMS:FUNCTION:SRP
        +SRP_gen_server_master_secret            333	EXIST:VMS:FUNCTION:SRP
        +SSL_CTX_SRP_CTX_free                    334	EXIST::FUNCTION:SRP
        +SRP_generate_client_master_secret       335	EXIST:!VMS:FUNCTION:SRP
        +SRP_gen_client_master_secret            335	EXIST:VMS:FUNCTION:SRP
        +SSL_srp_server_param_with_username      336	EXIST:!VMS:FUNCTION:SRP
        +SSL_srp_server_param_with_un            336	EXIST:VMS:FUNCTION:SRP
        +SRP_have_to_put_srp_username            337	NOEXIST::FUNCTION:
        +SSL_SRP_CTX_free                        338	EXIST::FUNCTION:SRP
        +SSL_set_debug                           339	EXIST::FUNCTION:
        +SSL_SESSION_get0_peer                   340	EXIST::FUNCTION:
        +TLSv1_2_client_method                   341	EXIST::FUNCTION:
        +SSL_SESSION_set1_id_context             342	EXIST::FUNCTION:
        +TLSv1_2_server_method                   343	EXIST::FUNCTION:
        +SSL_cache_hit                           344	EXIST::FUNCTION:
        +SSL_get0_kssl_ctx                       345	EXIST::FUNCTION:KRB5
        +SSL_set0_kssl_ctx                       346	EXIST::FUNCTION:KRB5
        +SSL_SESSION_get0_id                     347	NOEXIST::FUNCTION:
        +SSL_set_state                           348	EXIST::FUNCTION:
        +SSL_CIPHER_get_id                       349	EXIST::FUNCTION:
        +TLSv1_2_method                          350	EXIST::FUNCTION:
        +SSL_SESSION_get_id_len                  351	NOEXIST::FUNCTION:
        +kssl_ctx_get0_client_princ              352	EXIST::FUNCTION:KRB5
        +SSL_export_keying_material              353	EXIST::FUNCTION:TLSEXT
        +SSL_set_tlsext_use_srtp                 354	EXIST::FUNCTION:
        +SSL_CTX_set_next_protos_advertised_cb   355	EXIST:!VMS:FUNCTION:NEXTPROTONEG
        +SSL_CTX_set_next_protos_adv_cb          355	EXIST:VMS:FUNCTION:NEXTPROTONEG
        +SSL_get0_next_proto_negotiated          356	EXIST::FUNCTION:NEXTPROTONEG
        +SSL_get_selected_srtp_profile           357	EXIST::FUNCTION:
        +SSL_CTX_set_tlsext_use_srtp             358	EXIST::FUNCTION:
        +SSL_select_next_proto                   359	EXIST::FUNCTION:NEXTPROTONEG
        +SSL_get_srtp_profiles                   360	EXIST::FUNCTION:
        +SSL_CTX_set_next_proto_select_cb        361	EXIST:!VMS:FUNCTION:NEXTPROTONEG
        +SSL_CTX_set_next_proto_sel_cb           361	EXIST:VMS:FUNCTION:NEXTPROTONEG
        +SSL_SESSION_get_compress_id             362	EXIST::FUNCTION:
        diff --git a/vendor/openssl/openssl/util/tab_num.pl b/vendor/openssl/openssl/util/tab_num.pl
        new file mode 100644
        index 000000000..a81ed0edc
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/tab_num.pl
        @@ -0,0 +1,17 @@
        +#!/usr/local/bin/perl
        +
        +$num=1;
        +$width=40;
        +
        +while (<>)
        +	{
        +	chop;
        +
        +	$i=length($_);
        +
        +	$n=$width-$i;
        +	$i=int(($n+7)/8);
        +	print $_.("\t" x $i).$num."\n";
        +	$num++;
        +	}
        +
        diff --git a/vendor/openssl/openssl/util/x86asm.sh b/vendor/openssl/openssl/util/x86asm.sh
        new file mode 100644
        index 000000000..d2090a984
        --- /dev/null
        +++ b/vendor/openssl/openssl/util/x86asm.sh
        @@ -0,0 +1,42 @@
        +#!/bin/sh
        +
        +echo Generating x86 assember
        +echo Bignum
        +(cd crypto/bn/asm; perl x86.pl cpp > bn86unix.cpp)
        +(cd crypto/bn/asm; perl x86.pl win32 > bn-win32.asm)
        +
        +echo DES
        +(cd crypto/des/asm; perl des-586.pl cpp > dx86unix.cpp)
        +(cd crypto/des/asm; perl des-586.pl win32 > d-win32.asm)
        +
        +echo "crypt(3)"
        +(cd crypto/des/asm; perl crypt586.pl cpp > yx86unix.cpp)
        +(cd crypto/des/asm; perl crypt586.pl win32 > y-win32.asm)
        +
        +echo Blowfish
        +(cd crypto/bf/asm; perl bf-586.pl cpp > bx86unix.cpp)
        +(cd crypto/bf/asm; perl bf-586.pl win32 > b-win32.asm)
        +
        +echo CAST5
        +(cd crypto/cast/asm; perl cast-586.pl cpp > cx86unix.cpp)
        +(cd crypto/cast/asm; perl cast-586.pl win32 > c-win32.asm)
        +
        +echo RC4
        +(cd crypto/rc4/asm; perl rc4-586.pl cpp > rx86unix.cpp)
        +(cd crypto/rc4/asm; perl rc4-586.pl win32 > r4-win32.asm)
        +
        +echo MD5
        +(cd crypto/md5/asm; perl md5-586.pl cpp > mx86unix.cpp)
        +(cd crypto/md5/asm; perl md5-586.pl win32 > m5-win32.asm)
        +
        +echo SHA1
        +(cd crypto/sha/asm; perl sha1-586.pl cpp > sx86unix.cpp)
        +(cd crypto/sha/asm; perl sha1-586.pl win32 > s1-win32.asm)
        +
        +echo RIPEMD160
        +(cd crypto/ripemd/asm; perl rmd-586.pl cpp > rm86unix.cpp)
        +(cd crypto/ripemd/asm; perl rmd-586.pl win32 > rm-win32.asm)
        +
        +echo RC5/32
        +(cd crypto/rc5/asm; perl rc5-586.pl cpp > r586unix.cpp)
        +(cd crypto/rc5/asm; perl rc5-586.pl win32 > r5-win32.asm)
        diff --git a/vendor/pageant.exe b/vendor/pageant.exe
        new file mode 100644
        index 000000000..f11c37800
        Binary files /dev/null and b/vendor/pageant.exe differ
        diff --git a/vendor/plink.exe b/vendor/plink.exe
        new file mode 100644
        index 000000000..ed861e2b1
        Binary files /dev/null and b/vendor/plink.exe differ
        diff --git a/vendor/private.ppk b/vendor/private.ppk
        new file mode 100644
        index 000000000..e69837aaa
        --- /dev/null
        +++ b/vendor/private.ppk
        @@ -0,0 +1,26 @@
        +PuTTY-User-Key-File-2: ssh-rsa
        +Encryption: none
        +Comment: rsa-key-20141021
        +Public-Lines: 6
        +AAAAB3NzaC1yc2EAAAABJQAAAQEAkr6tlPb0QODfJJRhwsSsN88TSB6pgk/6x1KM
        +yVuDE6SeKz5sB4iaQfPleLSaWxuQEKkoa4sLAROy18lSk0PMioQHM6tgXbOcpTbS
        +Yf6uf1wtAMeFTO7vP0ZuIXbYmBmsK4DK1GWQq3Db5+Q/xbDp20dlCvCPMdokhYFr
        +N2B9G0C4AKgXRMS+loEXwOeQiupfYcUXfZiCOoviArCcLgRsUNZTeTbP03skLBDr
        +2xMdpaGx8QgSylz+yGeXRNjXaxE2mnwwVkBnNYsInZhw4/OdxddyilDealpcwp7x
        +enAwWsoLd9NlpskNCEQsznPMAe66/PKvRGl22+8tpNBzDbnZsw==
        +Private-Lines: 14
        +AAABABPUk/9fpHd4VYF71dwMvVOmXI00k3J5gsD9UUuklSwrAJ4PWrTo8kBDjbZd
        +mFGAQ+aTZlO41/k6A2lEuCG9Dc2HdphHl2abuzjru5CztrdDzrrqh6Kc1Dj7rgSF
        +rpEYOdxdgzF1gkCuYuf8P/ge035/RQF6dDcrUQsfU62JlF2gwQpVbQZ97DC9uGtt
        +ktYY0pSVU36xty4uQ148mOC8TXWFOxaGPOFq14sxmBUFVhHsmHnytQULIkibRCze
        +bfkpJNAizNKTNCfupd3aub205kzG48blZ3eWxYtK3mreiSDvhdWNWiyVhTajkXGQ
        +r3a+AqE/8e5Qks7ekzbpKk388a0AAACBAOftyBzFLENp3ccimF7ctlS44H2hfas4
        +2PQVbDpCKrY1u0XC+vn/GqgAVq/hcHeK6DrkaEK23Q30phNN7+8BDzR1VxO27TLg
        +UdwFE0z/0jnTuwkJcusO7bCb3dGGUX4ENSyRpNJVyu4X4iKuz03+ccPD3utkTIMI
        +zCskK5VQT0MBAAAAgQCh+ZsG6SfakMD76b3zF3xaw8bJmPe+q/YumlDDbM6sG9q+
        +3Fp5trBBJbGjXhTCyUkOuWiUh8cmVBFYRHrtz9GLVCOXVd6yYOzHlTKSNRnu7Slt
        +jdX1s0QphmPlQ6/uyUIAhrIrOkVFKNrV10Kex/7jwwdfL8i1cecng+dxfE4AswAA
        +AIEAiWClSrfWJTIKa3CZtIxlbHFHNLAVEuDjGeyKIMZ96qDEM7jDQ4vUzAagw60D
        +qUsJQMyx9RFfSLDYE3TZaXGrGdSXcFBz9f9xLcWLe/2LH7NUmjpUf5GnlMSs7+Br
        +ET2wiPd6NDf1kka+4+zMOgFqJF44xgDuNLnM3ty4EFlfzlY=
        +Private-MAC: 6e0ff7c94a3253c5e45b3e06951e04d2b06e6262